diff --git a/org.eclipse.jdt.core/.classpath b/org.eclipse.jdt.core/.classpath
new file mode 100644
index 0000000..3a38cd7
--- /dev/null
+++ b/org.eclipse.jdt.core/.classpath
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry output="antbin" kind="src" path="antadapter"/>
+	<classpathentry kind="src" path="batch"/>
+	<classpathentry kind="src" path="codeassist"/>
+	<classpathentry kind="src" path="compiler"/>
+	<classpathentry kind="src" path="dom"/>
+	<classpathentry kind="src" path="eval"/>
+	<classpathentry kind="src" path="formatter"/>
+	<classpathentry kind="src" path="model"/>
+	<classpathentry kind="src" path="search"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jdt.core/.options b/org.eclipse.jdt.core/.options
new file mode 100644
index 0000000..3a2a221
--- /dev/null
+++ b/org.eclipse.jdt.core/.options
@@ -0,0 +1,93 @@
+# Turn on debug tracing for org.eclipse.jdt.core plugin
+org.eclipse.jdt.core/debug=true
+
+# Reports buffer manager activity
+org.eclipse.jdt.core/debug/buffermanager=false
+
+# Reports java  builder activity : nature of build, built state reading, indictment process
+org.eclipse.jdt.core/debug/builder=false
+
+# Reports java builder stats
+org.eclipse.jdt.core/debug/builder/stats=false
+
+# Reports compiler activity
+org.eclipse.jdt.core/debug/compiler=false
+
+# Reports codeassist completion activity : recovered unit, inferred completions
+org.eclipse.jdt.core/debug/completion=false
+
+# Reports classpath variable initialization, and classpath container resolution
+org.eclipse.jdt.core/debug/cpresolution=false
+
+# Reports internals of classpath variable initialization, and classpath container resolution (to be used on the JDT/Core team request only)
+org.eclipse.jdt.core/debug/cpresolution/advanced=false
+
+# Reports failures during classpath variable initialization, and classpath container resolution
+org.eclipse.jdt.core/debug/cpresolution/failure=false
+
+# Reports bad node nesting in DOM AST
+org.eclipse.jdt.core/debug/dom/ast=false
+
+# Throws an exception in case of bad node nesting in DOM AST
+org.eclipse.jdt.core/debug/dom/ast/throw=false
+
+# Reports type errors when using ASTRewrite
+org.eclipse.jdt.core/debug/dom/rewrite=false
+
+# Report type hierarchy connections, refreshes and deltas
+org.eclipse.jdt.core/debug/hierarchy=false
+
+# Reports background indexer activity: indexing, saving index file, index queries
+org.eclipse.jdt.core/debug/indexmanager=false
+
+# Reports internals of indexer activity (to be used on the JDT/Core team request only)
+org.eclipse.jdt.core/debug/indexmanager/advanced=false
+
+# Print notified Java element deltas
+org.eclipse.jdt.core/debug/javadelta=false
+org.eclipse.jdt.core/debug/javadelta/verbose=false
+
+# Reports various Java model activities
+org.eclipse.jdt.core/debug/javamodel=false
+
+# Reports Java model elements opening/closing
+org.eclipse.jdt.core/debug/javamodel/cache=false
+
+# Reports post actions addition/run
+org.eclipse.jdt.core/debug/postaction=false
+
+# Reports name resolution activity
+org.eclipse.jdt.core/debug/resolution=false
+
+# Reports java search activity
+org.eclipse.jdt.core/debug/search=false
+
+# Reports source mapper activity
+org.eclipse.jdt.core/debug/sourcemapper=false
+
+# Reports code formatter activity
+org.eclipse.jdt.core/debug/formatter=false
+
+# Reports open on selection activity : recovered unit, inferred selection
+org.eclipse.jdt.core/debug/selection=false
+
+# Reports access to zip and jar files through the Java model
+org.eclipse.jdt.core/debug/zipaccess=false
+
+# Reports the time to perform code completion.
+org.eclipse.jdt.core/perf/completion=300
+
+# Reports the time to perform code selection.
+org.eclipse.jdt.core/perf/selection=300
+
+# Reports the time to process a java element delta.
+org.eclipse.jdt.core/perf/javadeltalistener=500
+
+# Reports the time to perform an initialization of a classpath variable.
+org.eclipse.jdt.core/perf/variableinitializer=5000
+
+# Reports the time to perform an initialization of a classpath container.
+org.eclipse.jdt.core/perf/containerinitializer=5000
+
+# Reports the time to perform a reconcile operation.
+org.eclipse.jdt.core/perf/reconcile=1000
diff --git a/org.eclipse.jdt.core/.project b/org.eclipse.jdt.core/.project
new file mode 100644
index 0000000..63121f2
--- /dev/null
+++ b/org.eclipse.jdt.core/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.jdt.core</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
new file mode 100644
index 0000000..fdfa23c
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?><component id="org.eclipse.jdt.core" version="2">
+    <resource path="model/org/eclipse/jdt/core/IAccessRule.java" type="org.eclipse.jdt.core.IAccessRule">
+        <filter id="403853384">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.IAccessRule"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="model/org/eclipse/jdt/core/IAnnotatable.java" type="org.eclipse.jdt.core.IAnnotatable">
+        <filter id="403853384">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.IAnnotatable"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="model/org/eclipse/jdt/core/IAnnotation.java" type="org.eclipse.jdt.core.IAnnotation">
+        <filter id="403853384">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.IAnnotation"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..465e861
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,355 @@
+#Wed Feb 02 11:25:08 EST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=warning
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs
new file mode 100644
index 0000000..2dcd706
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs
@@ -0,0 +1,3 @@
+#Wed Feb 02 11:25:08 EST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=error
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..020f0ab
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,105 @@
+#Tue Jan 05 12:29:35 EST 2010
+cleanup.add_default_serial_version_id=true
+cleanup.add_generated_serial_version_id=false
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_serial_version_id=false
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=true
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.format_comment=false
+cleanup.format_javadoc=true
+cleanup.format_multi_line_comment=true
+cleanup.format_single_line_comment=true
+cleanup.format_source_code=false
+cleanup.make_local_variable_final=true
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_variable_declarations_final=false
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=false
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=false
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.use_blocks=false
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_parentheses_in_expressions=false
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup_profile=_Numbat
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Jdtcore [built-in + Indent switch body + LineWidth\:120]
+formatter_settings_version=11
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=false
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.update_ibm_copyright_to_current_year=true
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..6f7536a
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,94 @@
+#Fri May 21 10:24:07 EDT 2010
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_JAVADOC_TAG=Warning
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Warning
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..35bb407
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,35 @@
+#Fri May 21 10:24:08 EDT 2010
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=2
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=2
+compilers.p.build.source.library=2
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-bundle-classpath-entries=2
+compilers.p.missing-packages=2
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b372bf2
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -0,0 +1,63 @@
+Manifest-Version: 1.0
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
+Bundle-Version: 3.9.0.qualifier
+Bundle-Activator: org.eclipse.jdt.core.JavaCore
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jdt.core,
+ org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.core.compiler.batch,
+ org.eclipse.jdt.core.dom,
+ org.eclipse.jdt.core.dom.rewrite,
+ org.eclipse.jdt.core.eval,
+ org.eclipse.jdt.core.formatter,
+ org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.search,
+ org.eclipse.jdt.core.util,
+ org.eclipse.jdt.core.index,
+ org.eclipse.jdt.internal.codeassist;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.complete;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.impl;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.select;x-internal:=true,
+ org.eclipse.jdt.internal.compiler;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.ast;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.batch;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.classfmt;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.compiler.codegen;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.compiler.env;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.flow;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.impl;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.lookup;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.parser.diagnose;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.problem;x-friends:="org.eclipse.jdt.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
+ org.eclipse.jdt.internal.compiler.util;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.jdt.compiler.tool,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.core.builder;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.core.dom;x-internal:=true,
+ org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
+ org.eclipse.jdt.internal.core.eval;x-internal:=true,
+ org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
+ org.eclipse.jdt.internal.core.index;x-internal:=true,
+ org.eclipse.jdt.internal.core.jdom;x-internal:=true,
+ org.eclipse.jdt.internal.core.search;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.indexing;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.matching;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.processing;x-internal:=true,
+ org.eclipse.jdt.internal.core.util;x-friends:="org.eclipse.jdt.apt.pluggable.core,org.eclipse.pde.api.tools",
+ org.eclipse.jdt.internal.eval;x-internal:=true,
+ org.eclipse.jdt.internal.formatter;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.align;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.comment;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.old;x-internal:=true
+Require-Bundle: org.eclipse.core.resources;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.filesystem;bundle-version="[1.0.0,2.0.0)",
+ org.eclipse.text;bundle-version="[3.1.0,4.0.0)",
+ org.eclipse.team.core;bundle-version="[3.1.0,4.0.0)";resolution:=optional
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Eclipse-ExtensibleAPI: true
+Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.core/META-INF/eclipse.inf b/org.eclipse.jdt.core/META-INF/eclipse.inf
new file mode 100644
index 0000000..43380da
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/eclipse.inf
@@ -0,0 +1,2 @@
+jarprocessor.exclude.children=true
+jarprocessor.exclude.pack=true
diff --git a/org.eclipse.jdt.core/_buildnotes_jdt-core.html b/org.eclipse.jdt.core/_buildnotes_jdt-core.html
new file mode 100644
index 0000000..c1798d2
--- /dev/null
+++ b/org.eclipse.jdt.core/_buildnotes_jdt-core.html
@@ -0,0 +1,2020 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes 3.8</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.8 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/"><b>HEAD</b></a> branch.
+	  For more information on 3.8 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.8/plan.php">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.8/plan.php#current-milestone">milestone plan</a>,
+	  the overall <a href="http://www.eclipse.org/projects/project-plan.php?planurl=http://www.eclipse.org/eclipse/development/plans/eclipse_project_plan_3_7.xml">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.7 (also see a summary of <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/plain/org.eclipse.jdt.core/notes/API_changes.html">API changes</a>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_7_maintenance">R3.7.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_6_maintenance">R3.6.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_5_maintenance">R3.5.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_4_maintenance">R3.4.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_3_maintenance">R3.3.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=R2_0_1">R2.0.x</a>,
+		  <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/log/?h=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+<a name="v_C58"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 31, 2012
+<br>Project org.eclipse.jdt.core v_C58
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_C58">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=380927">380927</a>
+VerifyError issue with inconsistent stack map frames with do..while and nested switch statements.
+
+<a name="v_C57"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 29, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=380750">380750</a>
+[compiler] local incorrectly flagged as uninitialized due to fix for bug 359495
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=380313">380313</a>
+Inconsistent stack error when using Java 1.7
+
+<a name="v_C56"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 23, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112">380112</a>
+[1.7][compiler] Incorrect unreachable catch block detection in try-with-resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=379726">379726</a>
+Include Eclipse-BundleShape in test plugin MANIFEST.MF
+
+<a name="v_C55"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 21, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=379793">379793</a>
+formatter hangs
+
+<a name="v_C54"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 16, 2012 - 3.8.0 RC1
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=379630">379630</a>
+Regression: NPE during reconcile/build
+
+<a name="v_C53"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 14, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=375971">375971</a>
+[search] Not finding method references with generics
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376550">376550</a>
+&quot;Method can be static&quot; warning on method that accesses instance field in inner class
+
+<a name="v_C52"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 11, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=373409">373409</a>
+[code assist] Bad relevance for constructor proposals (new Thread())
+
+<a name="v_C51"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - May 8, 2012 - 3.8.0 RC1
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=378390">378390</a>
+[search] regression caused by the fix for bug 357547
+
+<a name="v_C50"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 30, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376930">376930</a>
+FUP of bug 24804: Organize imports does not work when folding imports into on-demand import
+
+<a name="v_C49"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 30, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=374176">374176</a>
+Sticky default nullness diagnostics.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=371832">371832</a>
+The preference &quot;Suppress optional errors with '@SuppressWarnings'&quot; ends up silencing warnings it shouldn't
+
+<a name="v_C48"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 27, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=377806">377806</a>
+ExternalFoldersManager standalone regression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322977">322977</a>
+Documentation about use of &quot;SearchPattern.R_REGEXP_MATCH&quot; is wrong
+
+<a name="v_C47"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 26, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376724">376724</a>
+ExternalFoldersManager still has synchronization gaps
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=374129">374129</a>
+more tests for bug 372011
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365710">365710</a>
+FUP of bug 363293: Fix the incorrect added resource close
+
+<a name="v_C46"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 24, 2012 - April 10, 2012
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>New/changed options in JavaCore to control warnings relating to incomplete switch statements:
+<pre>
+	/**
+	 * Compiler option ID: Reporting Incomplete Enum Switch.
+	 * When enabled, the compiler will issue an error or a warning
+	 * 		regarding each enum constant for which a corresponding case label is lacking.
+	 * 		Reporting is further controlled by the option {@link #COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT}.
+	 *
+	 * Option id:"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"
+	 * Possible values:{ "error", "warning", "ignore" }
+	 * Default:"warning"
+	 * 
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INCOMPLETE_ENUM_SWITCH = PLUGIN_ID + ".compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Enum Case In Switch Despite An Existing Default Case.
+	 * This option further controls the option {@link #COMPILER_PB_INCOMPLETE_ENUM_SWITCH}:
+	 * 	
+	 *  - If enabled the compiler will report problems about missing enum constants even if a default case exists
+	 * 		in the same switch statement.
+	 *  - If disabled existence of a default case is considered as sufficient to make a switch statement complete.
+	 * 
+	 *  This option has no effect if {@link #COMPILER_PB_INCOMPLETE_ENUM_SWITCH} is set to "ignore".
+	 *
+	 * Option id:"org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault"
+	 * Possible values:{ "enabled", "disabled" }
+	 * Default:"disabled"
+	 *
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT = PLUGIN_ID + ".compiler.problem.missingEnumCaseDespiteDefault"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Default Case In Switch.
+	 * When enabled, the compiler will issue an error or a warning 
+	 * 		against each switch statement that lacks a default case.
+	 * 
+	 * Option id:"org.eclipse.jdt.core.compiler.problem.missingDefaultCase"
+	 * Possible values:{ "error", "warning", "ignore" }
+	 * Default:"ignore"
+	 *
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SWITCH_MISSING_DEFAULT_CASE = PLUGIN_ID + ".compiler.problem.missingDefaultCase"; //$NON-NLS-1$
+</pre>
+</li>
+<li> New IProblems relating to incomplete switch statements.
+<pre>
+	/** @since 3.8 */
+	int MissingEnumDefaultCase = Internal + 766;
+	/** @since 3.8 */
+	int MissingDefaultCase = Internal + 767;
+	/** @since 3.8 */
+	int MissingEnumConstantCaseDespiteDefault = FieldRelated + 768;
+	/** @since 3.8 */
+	int UninitializedLocalVariableHintMissingDefault = Internal + 769;
+	/** @since 3.8 */
+	int UninitializedBlankFinalFieldHintMissingDefault = FieldRelated + 770;
+	/** @since 3.8 */
+	int ShouldReturnValueHintMissingDefault = MethodRelated + 771;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=377401">377401</a>
+FuP of bug 372418: &quot;The type ... cannot be resolved&quot; error when there is a $ in the class name.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376429">376429</a>
+AIOOBE when trying to create AST for invalid annotation declaration
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376673">376673</a>
+DBCS4.2 Can not rename the class names when DBCS (Surrogate e.g. U+20B9F) is in it
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=374605">374605</a>
+Unreasonable warning for enum-based switch statements
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372694">372694</a>
+Adjust parser generator tools
+
+<a name="v_C45"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 17, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=326610">326610</a>
+[content assist] code assist for package-info.java
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376465">376465</a>
+Mixed line delimiters in org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(int)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=376837">376837</a>
+[warning] Resource leak warning in FileManagerTest
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=375394">375394</a>
+Incorrect type checking for parameterized types
+
+<a name="v_C44"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351697">351697</a>
+ClassCastException while copying a .class file to wrong source package
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=375326">375326</a>
+try-with-resources assignment in statement produces stack map exception
+
+<a name="v_C43"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - April 3, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=375568">375568</a>
+@PolymorphicSignature methods in MethodHandle have wrong annotation on parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687">372687</a>
+org.eclipse.jdt.core.LRUCache.get(Object key) returns an empty list from a class that has methods
+
+<a name="v_C42"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 27, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=374538">374538</a>
+[local] localFile service tries to set modified time on virtual files
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=375248">375248</a>
+AIOOBE inside twr with finally block
+
+<a name="v_C41"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 20, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372319">372319</a>
+Unexpected 'The local variable i may not have been initialized' compile error
+
+<a name="v_C40"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 13, 2012 - 3.8.0 M6
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=374063">374063</a>
+[builder][regression] bug 372012 causes regular problems to be reported against the package
+
+<a name="v_C39"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 13, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=373953">373953</a>
+FUP of bug 127575: java.eclipse.core.runtime.Assert  is being recognized as org.eclipse.core.runtime.Assert
+
+<a name="v_C38"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 12, 2012
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li> New IProblems for distinguishing null warnings based on flow analysis vs. null annotations.
+<pre>
+	/** @since 3.8 */
+	int RedundantNullCheckOnSpecdNonNullLocalVariable = Internal + 931;
+
+	/** @since 3.8 */
+	int SpecdNonNullLocalVariableComparisonYieldsFalse = Internal + 932;
+
+	/** @since 3.8 */
+	int RequiredNonNullButProvidedSpecdNullable = Internal + 933;
+</pre>
+</li>
+<li> New IProblems for reporting missing NonNullByDefault annotation on package/type.
+<pre>
+	/** @since 3.8 */
+	int MissingNonNullByDefaultAnnotationOnPackage = Internal + 913;
+	
+	/** @since 3.8 */
+	int MissingNonNullByDefaultAnnotationOnType = Internal + 930;
+</pre>
+</li>
+<li>Added new option in JavaCore to control warning for missing default nullness annotation:
+<pre>
+	/**
+	 * Compiler option ID: Reporting missing default nullness annotation.
+	 * 
+	 * When enabled, the compiler will issue an error or a warning in the following cases:
+	 * 
+	 * 1. When a package does not contain a default nullness annotation, as a result of missing package-info.java 
+	 * or missing default nullness annotation in package-info.java.
+	 * 2. When a type inside a default package does not contain a default nullness annotation.
+	 * 
+	 * This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+	 * 
+	 * Option id:"org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation"
+	 * Possible values:{ "error", "warning", "ignore" }
+	 * Default:"ignore"
+	 * 
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION = PLUGIN_ID + ".compiler.annotation.missingNonNullByDefaultAnnotation"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365859">365859</a>
+[compiler][null] distinguish warnings based on flow analysis vs. null annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=373571">373571</a>
+[null][regression] Incorrect application of null annotations to primitive types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367836">367836</a>
+Inconsistent source range for error from build and reconciler (declared package does not match expected)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368646">368646</a>
+[rename] rejects LocalVariable with initializer
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012">372012</a>
+[compiler][null] Warn when defaults not specified
+
+<a name="v_C37"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - March 6, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<ul>
+<li> New IProblems for reporting if an enum switch lacks a default cause (recommended by the JLS).
+<pre>
+	/** @since 3.8 */
+	int MissingEnumDefaultCase = Internal + 766;
+</pre>
+</li>
+<li>Adjusted the specification of the corresponding constant in JavaCore:
+<pre>
+	/**
+	 * Compiler option ID: Reporting Incomplete Enum Switch.
+	 *    
+	 * When enabled, the compiler will issue an error or a warning whenever
+	 * an enum switch statement lacks a default case.
+	 * If no default case is given, additionally one error or warning is issued
+	 * regarding each enum constant for which a corresponding case label is lacking.
+	 * 
+	 * Option id: "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"
+	 * Possible values: { "error", "warning", "ignore" }
+	 * Default: "warning"
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INCOMPLETE_ENUM_SWITCH = PLUGIN_ID + ".compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
+</pre>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=371732">371732</a>
+Deprecate AST.JLS3
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372909">372909</a>
+message verbiage for instanceof erasure
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347386">347386</a>
+Cannot delete package from java project (two source and output folders)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372011">372011</a>
+[compiler][null] Restore behaviour of null defaults for binary types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=127575">127575</a>
+Null reference checks don't handle Assert
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=265744">265744</a>
+Enum switch should warn about missing default
+
+<a name="v_C36"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - February 28, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372377">372377</a>
+ASTParser#createASTs(..) should not ignore optional compile problems
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=372351">372351</a>
+Illegal implementation of 'org.eclipse.jdt.internal.compiler.env.ICompilationUnit' in Tomcat Jasper
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=220928">220928</a>
+[buildpath] Should be able to ignore warnings from certain source folders
+
+<a name="v_C35"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - February 21, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365499">365499</a>
+Add a system property to control for JavaModelManager's jar type cache size
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368152">368152</a>
+ConcurrentModificationException on startup in ExternalFoldersManager.createPendingFolders
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544">244544</a>
+codeSelect fails on constant declaration in anonymous and local classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040">291040</a>
+codeSelect(..) does not work for a deeply nested method invocation in nested and anonymous class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370930">370930</a>
+NonNull annotation not considered for enhanced for loops
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366063">366063</a>
+Compiler should not add synthetic @NonNull annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365531">365531</a>
+[compiler][null] investigate alternative strategy for internally encoding nullness defaults
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=370639">370639</a>
+[compiler][resource] restore the default for resource leak warnings
+
+<a name="v_C34"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - February 14, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836">123836</a>
+[1.5][search] for references to overriding method with bound type variable is not polymorphic
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368546">368546</a>
+[compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364254">364254</a>
+Reduce console output during JDT/Core junits execution.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362633">362633</a>
+NPE while trying to rename a class
+
+<a name="v_C33"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 25, 2012 - 3.8.0 M5
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=369595">369595</a>
+Javadoc fixes for IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING
+
+<a name="v_C32"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 24, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a>
+Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method
+
+<a name="v_C31"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 22, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=369251">369251</a>
+Starved worker threads
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365208">365208</a>
+[compiler][batch] command line options for annotation based null analysis
+
+<a name="v_C30"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 20, 2012
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>New constant for the name of the encoding to be used for source attachments in IClasspathAttribute (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361356">361356</a> for details)
+<pre>
+	/**
+	 * Constant for the name of the encoding to be used for source attachments.
+	 *
+	 * &lt;p&gt;The value of this attribute has to be a string representation of a valid encoding. The encoding
+	 * for a source attachment is determined in the following order:  &lt;/p&gt;
+	 *
+	 * &lt;ul&gt;
+	 * &lt;li&gt; Encoding explicitly set on the source file (java or zip), i.e. <code>org.eclipse.core.resources.IFile#getCharset(false)</code> &lt;/li&gt;
+	 * &lt;li&gt; Encoding set on the corresponding classpath entry &lt;/li&gt;
+	 * &lt;li&gt; If the source attachment is a member of the project, then the project's default charSet&lt;/li&gt;
+	 * &lt;li&gt; Workspace default charSet &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 *
+	 * @since 3.8
+	 */
+	String SOURCE_ATTACHMENT_ENCODING = "source_encoding";
+</pre>
+</li>
+<li> New IProblems for messages relating to contradictory or redundant null annotations
+<pre>
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotation = Internal + 925;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationPackage = Internal + 926;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationType = Internal + 927;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationMethod = Internal + 928;
+	/** @since 3.8 */
+	int ContradictoryNullAnnotations = Internal + 929;
+</pre>
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361356">361356</a>
+Allow to specify encoding for source attachments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365582">365582</a>
+FUP of bug 361938: Other error code pattern
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365662">365662</a>
+[compiler][null] warn on contradictory and redundant null annotations
+
+<a name="v_C29"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 17, 2012
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368842">368842</a>
+test failure because test case refers to java.util.Objects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368709">368709</a>
+Endless loop in FakedTrackingVariable.markPassedToOutside
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361407">361407</a>
+Resource leak warning when resource is assigned to a field outside of constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362331">362331</a>
+Resource leak not detected when closeable not assigned to variable
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362332">362332</a>
+Only report potential leak when closeable not created in the local scope
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360908">360908</a>
+Avoid resource leak warning when the underlying/chained resource is closed explicitly
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361073">361073</a>
+Avoid resource leak warning when the top level resource is closed explicitly
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358903">358903</a>
+Filter practically unimportant resource leak warnings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365387">365387</a>
+[compiler][null] bug 186342: Issues to follow up post review and verification.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365519">365519</a>
+editorial cleanup after bug 186342 and bug 365387
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=368435">368435</a>
+[compiler] NPE while compile a method with unused local
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361963">361963</a>
+Stack overflow when trying to code complete a generic list
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365437">365437</a>
+Private methods tagged with @Inject should not be flagged with unused warning
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131">366131</a>
+[1.5][compiler] New generics compile error in Indigo SR1 for code that compiles in earlier Eclipse and javac
+
+<a name="v_C28"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 10, 2012
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023">367023</a>
+Error in JDT Core during AST creation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229">354229</a>
+[compiler][1.7] Name clash error not being reported by ecj.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367879">367879</a>
+Incorrect &quot;Potential null pointer access&quot; warning on statement after try-with-resources within try-finally
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366999">366999</a>
+VerifyError: Inconsistent stackmap frames
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346175">346175</a>
+@SuppressWarnings should clear all errors including fatal optional errors
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366544">366544</a>
+[index] Test testUseIndexInternalJarAfterRestart failed on Mac and Linux
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302850">302850</a>
+13 failures in JavaModel tests for the N20100214-2000 Mac OS X - Cocoa test machine
+
+<a name="v_C27"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - January 3, 2012 - 3.8.0 M5
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566">367566</a>
+In try-with-resources statement close() method of resource is not called
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364890">364890</a>
+BinaryTypeBinding should use char constants from Util
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365992">365992</a>
+[builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367203">367203</a>
+[compiler][null] detect assigning null to nonnull argument
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367154">367154</a>
+[compiler][null]  Problem in propagating null defaults.
+
+<a name="v_C26"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - December 20, 2011
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362711">362711</a>
+possibly incorrect JDT POST_CHANGE event fired when a file is replaced
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365835">365835</a>
+[compiler][null] inconsistent error reporting.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365836">365836</a>
+[compiler][null] Incomplete propagation of null defaults.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365983">365983</a>
+[compiler][null] AIOOB with null annotation analysis and varargs
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366003">366003</a>
+CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a>
+Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450">364450</a>
+Dubious class path error triggers a full rebuild
+
+<a name="v_C25"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - December 13, 2011
+<h2>What's new in this drop</h2>
+<ul>
+<li>New constant for the name of index location class path attribute in IClasspathAttribute(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356620">356620</a> for details)
+<pre>
+   /**
+     * Constant for the name of the index location attribute.
+     * 
+     * The value for this attribute has to be the string representation of a URL.
+     * It should point to an existing index file in a folder or a jar. The URL can also be of platform protocol.
+     * 
+     * @since 3.8
+     */
+     String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; 
+</pre>
+</li>
+<li>New API org.eclipse.jdt.core.index.JavaIndexer.generateIndexForJar to generate the index file for a given jar
+<pre>
+   /**
+     * Generates the index file for the specified jar.
+     *
+     * @param pathToJar The full path to the jar that needs to be indexed
+     * @param pathToIndexFile The full path to the index file that needs to be generated
+     * @throws IOException if the jar is not found or could not write into the index file
+     * @since 3.8
+     */
+     public static void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException;
+</pre>
+</li>
+<li> New application org.eclipse.jdt.core.JavaIndexer to generate index file for the given jar
+</li>
+<li> New ant task eclipse.buildJarIndex to generate the index file for the given jar </li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356620">356620</a>
+Make it possible to provide indexes for defined libraries
+
+<a name="v_C24"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - December 5, 2011 - 3.8.1 M4
+
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365566">365566</a>
+set resource leak diagnostic to &quot;ignore&quot; until bug 358903 is fixed
+
+<a name="v_C23"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Annotation-based Null Analysis.
+     * 
+     * This option controls whether the compiler will use null annotations for
+     * improved analysis of (potential) null references.
+     * 
+     * When enabled, the compiler will interpret the annotation types defined using
+     * {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME}
+     * as specifying whether or not a given type includes the value <code>null</code>.
+     * 
+     * The effect of these analyses is further controlled by the options
+     * {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+     * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and
+     * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nullanalysis"</code>
+     * Possible values: <code>{ "disabled", "enabled" }</code>
+     * Default: <code>"disabled"</code>
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_ANNOTATION_NULL_ANALYSIS = PLUGIN_ID + ".compiler.annotation.nullanalysis";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Name of Annotation Type for Nullable Types.
+     * 
+     * This option defines a fully qualified Java type name that the compiler may use
+     * to perform special null analysis.
+     * 
+     * If the annotation specified by this option is applied to a type in a method
+     * signature or variable declaration, this will be interpreted as a specification
+     * that <code>null</code> is a legal value in that position. Currently supported
+     * positions are: method parameters, method return type and local variables.
+     * 
+     * If a value whose type
+     * is annotated with this annotation is dereferenced without checking for null,
+     * the compiler will trigger a diagnostic as further controlled by
+     * {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}.
+     * 
+     * The compiler may furthermore check adherence to the null specification as
+     * further controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+     * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and
+     * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nullable"</code>
+     * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type.
+     * Default: <code>"org.eclipse.jdt.annotation.Nullable"</code>
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_NULLABLE_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nullable";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Name of Annotation Type for Non-Null Types.
+     * 
+     * This option defines a fully qualified Java type name that the compiler may use
+     * to perform special null analysis.
+     * 
+     * If the annotation specified by this option is applied to a type in a method
+     * signature or variable declaration, this will be interpreted as a specification
+     * that <code>null</code> is <b>not</b> a legal value in that position. Currently
+     * supported positions are: method parameters, method return type and local variables.
+     * 
+     * For values declared with this annotation, the compiler will never trigger a null
+     * reference diagnostic (as controlled by {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}
+     * and {@link #COMPILER_PB_NULL_REFERENCE}), because the assumption is made that null
+     * will never occur at runtime in these positions.
+     * 
+     * The compiler may furthermore check adherence to the null specification as further
+     * controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+     * {@link #COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION} and
+     * {@link #COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO}.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnull"</code>
+     * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type.
+     * Default: <code>"org.eclipse.jdt.annotation.NonNull"</code>
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_NONNULL_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnull";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Name of Annotation Type to specify a nullness default for unannotated types.
+     * 
+     * This option defines a fully qualified Java type name that the compiler may use
+     * to perform special null analysis.
+     * 
+     * If the annotation is applied without an argument, all unannotated types in method signatures
+     * within the annotated element will be treated as if they were specified with the non-null annotation
+     * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}).
+     * 
+     * If the annotation is applied with the constant <code>false</code> as its argument
+     * all corresponding defaults at outer scopes will be canceled for the annotated element.
+     * This includes defaults specified using this annotation type or a default defined using
+     * the compiler option {@link #COMPILER_NONNULL_IS_DEFAULT}.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"</code>
+     * Possible values: any legal, fully qualified Java type name; must resolve to an annotation type.
+     *     That annotation type should have exactly one boolean parameter.
+     * Default: <code>"org.eclipse.jdt.annotation.NonNullByDefault"</code>
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnullbydefault";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_NONNULL_IS_DEFAULT (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Globally specify non-null as the assumed default for unannotated types.
+     * 
+     * When enabled this option globally achieves the same effect 
+     * as specifying {@link #COMPILER_NONNULL_ANNOTATION_NAME} does for individual elements.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     *
+     * Option id: <code>"org.eclipse.jdt.core.compiler.annotation.nonnullisdefault"</code>
+     * Possible values: <code>{ "disabled", "enabled" }</code>.
+     * Default: <code>"disabled"</code>
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_NONNULL_IS_DEFAULT = PLUGIN_ID + ".compiler.annotation.nonnullisdefault";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Reporting Violations of Null Specifications.
+     * 
+     * Depending on this option, the compiler will issue either an error or a warning
+     * whenever one of the following situations is detected:
+     * 
+     * 1. A method declared with a nonnull annotation returns an expression that is
+     *    statically known to evaluate to a null value.
+     * 2. An expression that is statically known to evaluate to a null value is passed
+     *    as an argument in a method call where the corresponding parameter of the called
+     *    method is declared with a nonnull annotation.
+     * 3. An expression that is statically known to evaluate to a null value is assigned
+     *    to a local variable that is declared with a nonnull annotation.
+     * 4. A method that overrides an inherited method declared with a nonnull annotation
+     *    tries to relax that contract by specifying a nullable annotation
+     *    (prohibition of contravariant return).
+     * 5. A method that overrides an inherited method which has a nullable declaration
+     *    for at least one of its parameters, tries to tighten that null contract by
+     *    specifying a nonnull annotation for its corresponding parameter
+     *    (prohibition of covariant parameters).
+     * 
+     * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+     * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+     * shall interpret as nonnull or nullable annotations, respectively.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     *
+     * Option id: <code>"org.eclipse.jdt.core.compiler.problem.nullSpecViolation"</code>
+     * Possible values: <code>{ "error", "warning" }</code>
+     * Default: <code>"error"</code>
+     * 
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_PB_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.nullSpecViolation";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Reporting Violations of Null Specifications with Potential Null Value.
+     * 
+     * When enabled, the compiler will issue an error or a warning whenever one of the
+     * following situations is detected:
+     *
+     * 1. A method declared with a nonnull annotation returns an expression that is
+     *    statically known to evaluate to a null value on some flow.
+     * 2. An expression that is statically known to evaluate to a null value on some flow
+     *    is passed as an argument in a method call where the corresponding parameter of
+     *    the called method is declared with a nonnull annotation.
+     * 3. An expression that is statically known to evaluate to a null value on some flow
+     *    is assigned to a local variable that is declared with a nonnull annotation.
+     * 
+     * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+     * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+     * shall interpret as nonnull or nullable annotations, respectively.
+     * 
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     *
+     * Option id: <code>"org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation"</code>
+     * Possible values: <code>{ "error", "warning", "ignore" }</code>
+     * Default: <code>"error"</code>
+     * 
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.potentialNullSpecViolation";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Reporting Insufficient Information for Analysing Adherence to Null Specifications.
+     * 
+     * When enabled, the compiler will issue an error or a warning whenever one of the
+     * following situations is detected:
+     *
+     * 1. A method declared with a nonnull annotation returns an expression for which
+     *    insufficient nullness information is available for statically proving that no
+     *    flow will pass a null value at runtime.
+     * 2. An expression for which insufficient nullness information is available for
+     *    statically proving that it will never evaluate to a null value at runtime
+     *    is passed as an argument in a method call where the corresponding parameter of
+     *    the called method is declared with a nonnull annotation.
+     * 3. An expression for which insufficient nullness information is available for
+     *    statically proving that it will never evaluate to a null value at runtime
+     *    is assigned to a local variable that is declared with a nonnull annotation.
+     *
+     * Insufficient nullness information is usually a consequence of using other unannotated
+     * variables or methods.
+     * 
+     * The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+     * {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+     * shall interpret as nonnull or nullable annotations, respectively.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo"</code>
+     * Possible values: <code>{ "error", "warning", "ignore" }</code>
+     * Default: <code>"warning"</code>
+     * 
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO = PLUGIN_ID + ".compiler.problem.nullSpecInsufficientInfo";
+</pre></li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a> for details):
+<pre>
+    /**
+     * Compiler option ID: Reporting Redundant Null Annotations.
+     * 
+     * When enabled, the compiler will issue an error or a warning when a non-null annotation
+     * (see {@link #COMPILER_NONNULL_ANNOTATION_NAME})
+     * is applied although the same effect is already achieved by a default applicable at the
+     * current location. Such a default may be effective by enabling the option
+     * {@link #COMPILER_NONNULL_IS_DEFAULT} or by using the annotation specified by the option
+     * {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}.
+     * 
+     * This option only has an effect if the the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.
+     * 
+     * Option id: <code>"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation"</code>
+     * Possible values: <code>{ "error", "warning", "ignore" }</code>
+     * Default: <code>"warning"</code>
+     * 
+     * @since 3.8
+     * @category CompilerOptionID
+     */
+    public static final String COMPILER_PB_REDUNDANT_NULL_ANNOTATION = PLUGIN_ID + ".compiler.problem.redundantNullAnnotation";
+</pre>
+</li>
+<li>New API added to org.eclipse.jdt.core.compiler.IProblem to signal null-related issues:
+	<ul>
+	<li> int RequiredNonNullButProvidedNull</li>
+	<li> int RequiredNonNullButProvidedPotentialNull</li>
+	<li> int RequiredNonNullButProvidedUnknown</li>
+	<li> int MissingNullAnnotationType</li>
+	<li> int IllegalReturnNullityRedefinition</li>
+	<li> int IllegalRedefinitionToNonNullParameter</li>
+	<li> int IllegalDefinitionToNonNullParameter</li>
+	<li> int ParameterLackingNonNullAnnotation</li>
+	<li> int ParameterLackingNullableAnnotation</li>
+	<li> int PotentialNullMessageSendReference</li>
+	<li> int RedundantNullCheckOnNonNullMessageSend</li>
+	<li> int CannotImplementIncompatibleNullness</li>
+	<li> int RedundantNullAnnotation</li>
+	<li> int IllegalAnnotationForBaseType</li>
+	</ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=363858">363858</a>
+[dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331647">331647</a>
+[compiler][null] support flexible default mechanism for null-annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334457">334457</a>
+[compiler][null] check compatibility of inherited null contracts
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186342">186342</a>
+[compiler][null] Using annotations for null checking
+
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - November 29, 2011
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340945">340945</a>
+Extension Request of JavaContentAssistInvocationContext
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364672">364672</a>
+[compiler] ecj fails to compile valid calls to varargs method
+
+<a name="v_C21"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - November 22, 2011
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350738">350738</a>
+&quot;The method is never used locally&quot; is not shown for parameterized recursive methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053">361053</a>
+java.lang.VerifyError on try-with-resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038">346038</a>
+[1.5][compiler] ecj vs. javac differ for methods using vararg parameters of different primitive types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346039">346039</a>
+[1.5][compiler] ecj vs. javac differ for varargs overloading
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362279">362279</a>
+ecj vs. javac differ for automatic boxing of implicitly converted types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362591">362591</a>
+VerifyError: Inconsistent stackmap frames
+
+<a name="v_C20"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - November 15, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361327">361327</a>
+Static import resolution does not record all static elements being imported
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042">346042</a>
+[1.5][compiler] ecj compiles code rejected by javac for varargs parameters of inaccessible type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361938">361938</a>
+Formerly working JLS3 parser not working -- Scanner reports com.sun.jdi.InvocationException occurred invoking method.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359284">359284</a>
+Unnecessary checkast from null
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361441">361441</a>
+Error in JDT Core during AST creation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=363293">363293</a>
+resource leaks in org.eclipse.jdt.compiler.tool.tests
+
+<a name="v_C19"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - November 8, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=361922">361922</a>
+Fup of 357425: ensure all reported regressions are witnessed by tests
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766">354766</a>
+Javadoc content does not appear in content assist info window for non-static inner class constructors
+
+<a name="v_C18"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 25, 2011 - 3.8.0 M3
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_C17"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 20, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a> for details):
+<pre>
+/**
+ * Status constant indicating that the default or specific output folder is overlapping
+ * with another source location.
+ * @since 3.8 
+ */
+public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013;
+</pre>
+</li>
+
+<li>Added a new option CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE to report an output location overlapping another source location(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a> for details):
+<pre>
+/**
+ * Core option ID: Reporting an output location overlapping another source location.
+ * Indicate the severity of the problem reported when a source entry's output location overlaps another
+ * source entry.
+ * 
+ * Option id:"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"
+ * Possible values:{ "error", "warning", "ignore" }
+ * Default:"error"
+ * 
+ * @since 3.8
+ */
+public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource";
+</pre>
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164">287164</a>
+Report build path error if source folder has other source folder as output folder
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359721">359721</a>
+[options] add command line option for new warning token &quot;resource&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343480">343480</a>
+[compiler] Incorrect/confusing error message on inner class static field declaration
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401">318401</a>
+FUP of 317858: Clarify eclipse compiler behavior on imports &amp; shadowing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317">360317</a>
+[compiler] report switch over enum in 1.4- mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164">360164</a>
+Compile error in XSDImpl
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359727">359727</a>
+[1.7][doc] Update doc for new resource leak warnings
+
+<a name="v_C16"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 18, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API IBootstrapMethodsEntry to describe the bootstrap method table entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Description of a bootstrap method table entry as specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IBootstrapMethodsEntry;
+</pre>
+</li>
+
+<li>Added a new API IBootstrapMethodsAttribute to describe the bootstrap method attribute(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Description of a bootstrap methods attribute as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IBootstrapMethodsAttribute
+</pre>
+</li>
+
+<li>Added a new API in IBootstrapMethodsAttribute to obtain the number of bootstrap methods of this entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Answer back the number of bootstrap methods of this entry as specified in
+ * the JVM specifications.
+ *
+ * @return the number of bootstrap methods of this entry as specified in
+ * the JVM specifications
+ */
+int getBootstrapMethodsLength();
+</pre>
+</li>
+
+<li>Added a new API in IBootstrapMethodsAttribute to obtain the bootstrap methods table of this entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Answer back the bootstrap methods table of this entry as specified in
+ * the JVM specifications. Answer an empty array if none.
+ *
+ * @return the bootstrap methods table of this entry as specified in
+ * the JVM specifications. Answer an empty array if none
+ */
+IBootstrapMethodsEntry[] getBootstrapMethods();
+</pre>
+</li>
+
+<li>Added IConstantPoolEntry2 to describe the new constant pool entry from Java 7 onwards(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Description of the new constant pool entry as described in the JVM specifications
+ * added for Java 7 support.
+ * Its contents is initialized according to its kind.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IConstantPoolEntry2
+</pre>
+</li>
+
+<li>Added new API in IConstantPoolEntry2 to return the descriptor index for MethodType entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Returns the descriptor index. This value is set only when decoding a MethodType entry.
+ * The value is unspecified otherwise. The corresponding UTF8 value can be retrieved by using
+ * {@link #getMethodDescriptor()}.
+ *
+ * @return the descriptor index. This value is set only when decoding a MethodType entry.
+ * @see IConstantPoolConstant#CONSTANT_MethodType
+ */
+int getDescriptorIndex();
+</pre>
+</li>
+
+<li>Added new API in IConstantPoolEntry2 to return the reference kind for MethodHandle entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Returns the reference kind. This value is set only when decoding a MethodHandle entry.
+ * The value is unspecified otherwise.
+ *
+ * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+ * @see IConstantPoolConstant#CONSTANT_MethodHandle
+ */
+int getReferenceKind();
+</pre>
+</li>
+
+<li>Added new API in IConstantPoolEntry2 to return the reference index for MethodHandle entry(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Returns the reference index. This value is set only when decoding a MethodHandle entry.
+ * The value is unspecified otherwise.
+ *
+ * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+ * @see IConstantPoolConstant#CONSTANT_MethodHandle
+ */
+int getReferenceIndex();
+</pre>
+</li>
+
+<li>Added new API in IConstantPoolEntry2 to return the bootstrap method attribute index(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+/**
+ * Returns the bootstrap method attribute index. This value is set only when decoding a InvokeDynamic entry.
+ * The value is unspecified otherwise.
+ *
+ * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+ * @see IConstantPoolConstant#CONSTANT_InvokeDynamic
+ */
+int getBootstrapMethodAttributeIndex();
+</pre>
+</li>
+
+<li>Added new API in IByteCodeVisitor(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a> for details):
+<pre>
+	/**
+	 * @since 3.8
+	 */
+	void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry invokeDynamic);
+</pre>
+<p>
+This has been added in place of the deprecated API
+<pre>
+	void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry nameEntry,
+			IConstantPoolEntry descriptorEntry);
+</pre>
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359943">359943</a>
+invokedynamic in generated class file is not correctly recognized by the eclipse compiler
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360644">360644</a>
+Scope.isDefinedInSameUnit(ReferenceBinding) fails for a ParameterizedTypeBinding
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358762">358762</a>
+NPE in JDT compiler
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=360328">360328</a>
+[compiler][null] detect null problems in nested code (local class inside a loop)
+
+<a name="v_C15"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 11, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285">350285</a>
+ASTRewrite destroys formatting on CatchClause#setBody(copyTarget)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353474">353474</a>
+type converters should include more annotations
+
+<a name="v_C14"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 5, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354181">354181</a>
+migrate jdt.core to git
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359831">359831</a>
+Fix messages for &quot;new warning for missing try-with-resources&quot;
+
+<a name="v_C13"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - October 3, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE to raise a warning or error
+  when a resource of type Closeable or AutoCloseable is not closed locally.  
+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting a resource that is not closed properly.
+	 *
+	 * When enabled, the compiler will issue an error or a warning if
+	 * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance&gt;=1.7) 
+	 * or a value of type <code>java.io.Closeable</code> (compliance&lt;=1.6) and if
+	 * flow analysis shows that the method <code>close()</code> is not invoked locally on that value.
+	 * 
+	 * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code>
+	 * Possible values: <code>{ "error", "warning", "ignore" }</code>
+	 * Default: <code>"warning"</code>
+	 *
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
+</pre>
+</li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE to raise a warning or error
+  when a resource of type Closeable or AutoCloseable is not definitely closed locally.
+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting a resource that may not be closed properly.
+	 * 
+	 * When enabled, the compiler will issue an error or a warning if
+	 * a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance&gt;=1.7) 
+	 * or a value of type <code>java.io.Closeable</code> (compliance&lt;=1.6) and if
+	 * flow analysis shows that the method <code>close()</code> is 
+	 * not invoked locally on that value for all execution paths.
+	 * 
+	 * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code>
+	 * Possible values: <code>{ "error", "warning", "ignore" }</code>
+	 * Default: <code>"ignore"</code>
+	 * 
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
+</pre>
+</li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE to raise a warning or error
+  when a resource of type AutoCloseable is closed explicitly rather than using a try-with-resources block.
+(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
+	 * 
+	 * When enabled, the compiler will issue an error or a warning if a local variable 
+	 * holds a value of type <code>java.lang.AutoCloseable</code>, and if the method
+	 * <code>close()</code> is explicitly invoked on that resource, but the resource is
+	 * not managed by a try-with-resources block.
+	 * 
+	 * Option id: <code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code>
+	 * Possible values: <code>{ "error", "warning", "ignore" }</code>
+	 * Default: <code>"ignore"</code>
+	 * 
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495">359495</a>
+[1.7][compiler] VerifyError in try-finally block with lock encompassing for-each block and unlock in finally clause
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=161129">161129</a>
+[batch][compiler] Add -warn:all to report all warnings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359646">359646</a>
+Formatter fails silently if Java source contains 0x8000000000000000L
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796">256796</a>
+[compiler] dead code detection: &quot;if (DEBUG) return;&quot; should also be trivial IF stmt
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359334">359334</a>
+Analysis for resource leak warnings does not consider exceptions as method exit points
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=359362">359362</a>
+FUP of bug 349326: Resource leak on non-Closeable resource.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348186">348186</a>
+[compiler] Improve wording for the warning for masked/hidden catch block
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=355838">355838</a>
+[compiler] ecj compiles the code that javac6 rejects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349326">349326</a>
+[1.7] new warning for missing try-with-resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354502">354502</a>
+Incorrect Compiler Warning: &quot;Method can be declared as static&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241834">241834</a>
+[search] ClassCastException during move class refactoring
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=358827">358827</a>
+[1.7] exception analysis for t-w-r spoils null analysis
+
+<a name="v_C12"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - September 23, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>Tagging to prepare for the git migration</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_C11"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - September 20, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357110">357110</a>
+Problem with inner classes referenced from jars or class folders: &quot;The type ... cannot be resolved&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357471">357471</a>
+ASTParser cannot resolve binding of PackageDeclaration if class name is equal to the first segment of the package name
+
+<a name="v_C10"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - September 13, 2011 - 3.8.0 M2
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=357259">357259</a>
+[dom] AST#newArrayType(Type, int) should allow array type as argument
+
+<a name="v_C09"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - September 9, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332">354332</a>
+DeltaProcessor exhibits O(N^2) behavior
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=355605">355605</a>
+NPE in HierarchyResolver
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347396">347396</a>
+ASTParser returns empty or partial AST if we parse the the body contains empty for loop
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356746">356746</a>
+ECJ accepts illegal unicode escape sequences
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337935">337935</a>
+Test failures when run as an IDE (org.eclipse.sdk.ide)
+
+<a name="v_C08"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - September 6, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356325">356325</a>
+[select] Open declaration on a constructor of a local class with type parameters doesn't work
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=24804">24804</a>
+Organize imports wipes comments between statements [code manipulation]
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356363">356363</a>
+Many links to java.sun.com are broken
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346529">346529</a>
+Don't show &quot;The method * from the type * is never used locally&quot; warning for private methods annotated with standard annotations like @PostConstruct
+
+<a name="v_C07"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - August 30, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356002">356002</a>
+VerifyError &quot;Inconsistent stackmap frames&quot; for switch-string statement with nested for-loop
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350095">350095</a>
+The 2000th (0-based) enum constant is null
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=234074">234074</a>
+Compliance_1_5#test088 fails when launched with JRE 6 and -Dcompliance=1.5
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612">350612</a>
+OutOfMemoryError while &quot;Initializing Java Tooling&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348024">348024</a>
+Empty AST for class with static inner class in a package with package-info.java
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346010">346010</a>
+[model] strange initialization dependency in OptionTests
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353640">353640</a>
+AIOOBE in ParameterizedTypeBinding.substitute
+
+<a name="v_C06"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - August 23, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348507">348507</a>
+[search] Hyperlinks from the Java Stack Trace console should search the workspace in CLASSPATH order
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345949">345949</a>
+[compiler] Inconsistent name clash behavior vis-a-vis javac7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354766">354766</a>
+Javadoc content does not appear in content assist info window for non-static inner class constructors
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353535">353535</a>
+Eclipse compiler generates wrong bytecode for nested try-with-resources statements
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354579">354579</a>
+Fup of bug 289247: Investigate validity of the fix vis-a-vis JLS.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354078">354078</a>
+[dom] ASTConverter.removeTrailingCommentFromExpressionEndingWithAParen() ??
+
+<a name="v_C05"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - August 16, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354554">354554</a>
+[null] conditional with redundant condition yields weak error message
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354536">354536</a>
+compiling package-info.java still depends on the order of compilation units
+<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=352412">352412</a>
+Switching on strings in 1.6- modes produces misleading message
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719">317719</a>
+Method incorrectly flagged as having same erasure output when return type differs
+
+<a name="v_C04"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - August 9, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API in BindingKey to return it's declaring type(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351165">351165</a> for details):
+<pre>
+/**
+ * Returns the binding key of the declaring type of the element represented by this binding key. If the binding key
+ * does not represent a member or if the member doesn't have a declaring type, returns <code>null</code>.
+ * 
+ * Note that only binding keys for references to methods and fields
+ * are fully supported. The binding keys for declarations will not have type parameters.
+ * 
+ * @return the type binding key or <code>null</code>
+ * @since 3.7.1
+ */
+public BindingKey getDeclaringType();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=354052">354052</a>
+[1.7] NPE in org.eclipse.jdt.internal.compiler.ClassFile.traverse(ClassFile.java:4507)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346741">346741</a>
+[1.7][doc] Update doc when java 1.7 support is done
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353238">353238</a>
+[1.7] update unusedTypeArgs option description for the batch compiler
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353089">353089</a>
+[1.7][compiler] Incorrect name clash error with ecj
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351165">351165</a>
+[1.7] API to get the type arguments of the declaring type for constructor invocations
+
+<a name="v_C03"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - August 3, 2011 - 3.8.0 M1
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353553">353553</a>
+Rename readableNames.properties to avoid translation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353085">353085</a>
+[1.7] Cannot cast from Object to boolean
+
+<a name="v_C02"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - July 28, 2011
+<br>
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353250">353250</a>
+[1.7] merging Java 7 work to HEAD
+
+<a name="v_C01"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - July 27, 2011
+<br>
+<h2>What's new in this drop</h2>
+<ul>
+<li>Bundle version has been incremented to 3.8.0.qualifier</li>
+<li>Added a new API in CompletionProposal to tell whether it diamond operator can be used (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351444">351444</a> for details):
+<pre>
+/** 
+ * Returns whether it is safe to use the '&lt;&gt;' (diamond) operator in place of explicitly specifying
+ * type arguments for this proposal. 
+ * 
+ * This is only relevant for source level 1.7 or greater.
+ * 
+ * @param coreContext the completion context associated with the proposal
+ * @since 3.7.1
+ * @return <code>true</code> if it is safe to use the diamond operator for the constructor invocation, 
+ * <code>false</code> otherwise. Also returns <code>false</code> for source levels below 1.7
+ */
+public boolean canUseDiamond(CompletionContext coreContext);
+</pre>
+</li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS added to raise warning or error for redundant
+usage of type arguments when diamond operator can be used instead. (see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340747">340747</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting redundant specification of type arguments in class instance creation expressions.
+	 * When enabled, the compiler will issue an error or a warning if type arguments are used in a class instance creation,
+	 * when the '&lt;&gt;' operator can be used instead.
+	 *
+	 * This option only has an effect if the compiler compliance is 1.7 or greater.
+	 * 
+	 * Option id:<code>"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"</code>
+	 * Possible values:<code>{ "error", "warning", "ignore" }</code>
+	 * Default:<code>"ignore"</code>
+	 * 
+	 * @since 3.7.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS = PLUGIN_ID + ".compiler.problem.redundantSpecificationOfTypeArguments";
+	</pre>
+</li>
+<li>Added a new API in ClassInstanceCreation to tell whether the resolved type is inferred from the assignment context:
+<br>(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350897">350897</a> for details):
+<pre>
+	/**
+	 * Returns <code>true</code> if the resolved class type has been inferred
+	 * from the assignment context (JLS4 15.12.2.8), <code>false</code> otherwise.
+	 *
+	 * This information is available only when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if the resolved class type has been inferred
+	 * 	from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise
+	 * @since 3.7.1
+	 */
+	public boolean isResolvedTypeInferredFromExpectedType();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342936">342936</a>
+NPEs and inconsistencies when running jdt.compiler.tool.tests against Java 7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351426">351426</a>
+[1.7][code assist] CompletionContext.getExpectedTypesKeys() returns wrong type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353137">353137</a>
+[1.7] Make sure TagBits.AnnotationSafeVarargs and AnnotationPolymorphicSignature are handled everywhere
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353093">353093</a>
+IMethod#getAnnotations() doesn't return @SafeVarargs of java.util.Arrays#asList(T...)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352464">352464</a>
+[1.7] Incorrect Javadoc shown for reference of invokeExact
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351498">351498</a>
+[model]java.util.ConcurrentModificationException upon startup
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352699">352699</a>
+[1.7][compiler] Improve error range for redundant type parameter warning
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352665">352665</a>
+[1.6][compiler] Internal compiler Error: ArrayIndexOutOfBoundsException when compiling certain classes with outer access error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352553">352553</a>
+[1.7] 'char a\u200b' is being accepted in 1.6 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352496">352496</a>
+tests using wrong version of JCL
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300576">300576</a>
+NPE Computing type hierarchy when compliance doesn't match libraries
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352145">352145</a>
+[1.7][compiler] VerifyError with aload0 being involved into ConditionalExpression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965">351965</a>
+[1.7] CCE when using diamond in 1.4
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351444">351444</a>
+[1.7][content assist] Need to know whether I can use diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352014">352014</a>
+\u1369 no longer accepted as a valid java identifier part
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351653">351653</a>
+[1.7][compiler]: VerifyError in try statement with finally and return statements
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340747">340747</a>
+[1.7][compiler] compiler option to warn when diamond can be used, but type args are used instead.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350895">350895</a>
+[1.7][formatter] New option to wrap before/after '|' in multi-catch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350652">350652</a>
+[1.7][assist] Completion issues with multicatch (FUP of 343637)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347503">347503</a>
+[DOM] ASTParser.setEnvironment() ignores includeRunningVMBootclasspath parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350897">350897</a>
+[1.7][api] ClassInstanceCreation#isResolvedTypeInferredFromExpectedType()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351170">351170</a>
+[1.7] ASTRewrite issues in Try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348493">348493</a>
+[1.7] Improve error msg for Diamond operator in 1.5 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350885">350885</a>
+[Search] The pull up refactoring throws an NPE when pulling up a member that already exists in the superclass
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350611">350611</a>
+[1.7] Inconsistent error msg and error location for illegal diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350579">350579</a>
+[1.7][compiler] VerifyError running example from bug 338402 comment 5
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350767">350767</a>
+[1.7][assist] CCE while invoking assist on a multi-catch block
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349312">349312</a>
+[1.7][compiler] improved problem messages
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350003">350003</a>
+[1.7] [compiler] AnnotationPolymorphicSignature tag is not being set to invokeExact while compiling MethodHandle source file
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350496">350496</a>
+[1.7] @PolymorphicSignature IMethods are missing the annotation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349314">349314</a>
+[1.7][formatter] Line wrapping for multi-catch arguments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350039">350039</a>
+[1.7] ASTParser#createASTs(..) doesn't resolve IMethodBinding for @PolymorphicSignature method reference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349396">349396</a>
+[1.7][formatter] Line wrapping and indentation options for try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350361">350361</a>
+[1.7] Unhandled exception type Exception
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349488">349488</a>
+[1.7] IMethodBinding#getMethodDeclaration() should return the declaration of @PolymorphicSignature methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349487">349487</a>
+[1.7] IMethodBinding#getJavaElement() returns inexistent element for @PolymorphicSignature methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862">349862</a>
+[1.7] NPE when trying to use UnionType as TryStatement resource
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349864">349864</a>
+[1.7][compiler] Error message considers AutoCloseable as class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348956">348956</a>
+[1.7] ITypeBinding#isAssignmentCompatible(ITypeBinding) returns different result
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349312">349312</a>
+[1.7][compiler] improved problem messages
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349008">349008</a>
+[1.7] Ugly formatting for try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349072">349072</a>
+[1.7] &quot;Cannot infer elided type(s)&quot; sounds too elite
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705">348705</a>
+[1.7][compiler] Improve error message for unhandled IOException generated due to compiler-generated close()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348050">348050</a>
+[1.7] Error in JDT Core during AST creation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348406">348406</a>
+[1.7] Incorrect error msg on try with resources in 1.5 mode 
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348492">348492</a>
+[1.7] Improve error msg on strings in switch in 1.5 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348491">348491</a>
+[1.7] Rename IProblem.IllegalBinaryLiteral to BinaryLiteralNotBelow17 and IProblem.IllegalUsageOfUnderscore to UnderscoreInLiteralsNotBelow17
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348369">348369</a>
+[1.7] Missing error &quot;No exception of type Exception[] can be thrown&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348379">348379</a>
+[1.7][compiler] Null pointer access warning for strings in switch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346415">346415</a>
+[1.7][assist] No proposal inside catch statement from 3rd catch block onwards
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454">346454</a>
+[1.7][content assist]Getting NegativeArraySizeException while trying content assist after diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347600">347600</a>
+[1.7][compiler] Suspect bounds check failure after inference.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347746">347746</a>
+[1.7][compiler] Bounds check failure during method inference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283353">283353</a>
+[1.5][compiler] Eclipse compiler shows error on javac-valid construct: Bound mismatch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347145">347145</a>
+[1.7][compiler] Bounds check issue with raw types in method inference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347426">347426</a>
+[1.7][compiler] ecj behavior differs from javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344522">344522</a>
+[1.7] Incorrect source range for ParameterizedType in case of Diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341795">341795</a>
+[1.7][compiler] Cannot assign a generic method with multiple bounds return value to any variable
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159">242159</a>
+[1.7][compiler] type inference with unbounded wildcard in result type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343693">343693</a>
+[1.7] Adjust subclasses of AllocationExpression for &lt;&gt; support
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343637">343637</a>
+[1.7] Already used exception offered again in a Mulicatch block
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968">345968</a>
+[1.7][compiler] NPE while using diamond for inner class allocation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334313">334313</a>
+[1.5][compiler] Bug in the way eclipse handles overriding of generic abstract method by a non-abstract method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346029">346029</a>
+[1.7][compiler] Eclipse compiles code rejected by JDK7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345628">345628</a>
+[1.7] Rename disjunctive type to union type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345559">345559</a>
+[1.7][compiler] Type inference for generic allocation can be avoided for invalid constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342819">342819</a>
+Code rejected by javac with name clash error compiles under eclipse.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334306">334306</a>
+[1.7][compiler] name clash reported in javac 1.7 and not in javac 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345579">345579</a>
+[1.7][compiler] Weird error message in rethrow site
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345522">345522</a>
+[1.7][compiler] Compilers fails to compute precisely rethrown types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344824">344824</a>
+[1.7][compiler] Incorrect error range for unreachable catch block error in multi-catch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340486">340486</a>
+[1.7][compiler] Missing error in multi catch scenario
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359">345359</a>
+[1.7][compiler] AIOOB on diamond construct with argument error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345239">345239</a>
+[1.7][compiler] Compiler should issue better diagnostics for use of &lt;&gt; with anonymous classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344655">344655</a>
+[1.7][compiler] Prohibit use of &lt;&gt; with explicit type arguments to generic constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328575">328575</a>
+Inheritance of annotation fails with generic classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785">343785</a>
+[1.7] Incorrect line numbers in stack trace with try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343687">343687</a>
+[1.7] IAE in NumberLiteral#setToken(String) for binary tokens and tokens with underscore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339478">339478</a>
+[1.7][compiler] support for diamond case
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476">343476</a>
+[1.7][assist] propose String variables and fields inside catch expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087">292087</a>
+anonymous class in array member initializer confuses content assist
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343475">343475</a>
+[1.7] Compiler warning for invalid type inside switch needs to be improved
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342416">342416</a>
+[1.7] Signature#createIntersectionTypeSignature(..) should take array of signatures
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340059">340059</a>
+[1.7] IAE when dealing with Signature of disjunctive type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338789">338789</a>
+[1.7][assist] No proposal inside a multi catch statement after '|'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341333">341333</a>
+[1.7][compiler] DisjunctiveTypeReference#resolveType(..) does not set the value for DisjunctiveTypeReference$resolvedType
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340634">340634</a>
+[1.7][compiler][multicatch] Compiler accepts type variables as catch parameter type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340626">340626</a>
+[1.7][compiler] Inconsistent source pinpointing in multi-catch blocks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340513">340513</a>
+[1.7][compiler] Unicode 6.0 characters work at compiler compliance level 1.5 and 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340445">340445</a>
+[1.7] ASTRewriteAnalyzer and ASTRewriteFlattener need updates
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340372">340372</a>
+[1.7] NaiveASTFlattener needs to support the new AST nodes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340365">340365</a>
+[1.7] Problems in new APIs (TryStatementWithResources, DisjunctiveType)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340375">340375</a>
+[1.7] Merge TryStatementWithResources into TryStatement
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340022">340022</a>
+[1.7][compiler] Support for precise rethrow
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339837">339837</a>
+[1.7][compiler] Multicatch syntax not rejected at 1.6-
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339864">339864</a>
+[1.7] Add recovery in ASTConverter for all new constructs in JLS3 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402">338402</a>
+[1.7][compiler][enh] Open issues in try with resources implementation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795">337795</a>
+[1.7][compiler] Missing unchecked warning at varargs method/ctor declaration site
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337802">337802</a>
+[1.7][compiler] Usage of 0x0ffffffff is being reported as out of range.
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799">337799</a>
+[1.7][compiler][varargs] Eclipse fails to report error on incorrect SafeVarargs usage
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337738">337738</a>
+[1.7][content assist]Test CompletionParserTest#testEA_1 fails
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336782">336782</a>
+[1.7][recovery]Extra error tokens with invalid unary operator
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336322">336322</a>
+[1.7][search]CCE while searching for a type reference in multiple catch parameters
+
+<hr>
+<p>For earlier build notes, also see <a href="http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/plain/org.eclipse.jdt.core/notes/R37_buildnotes_jdt-core.html">build notes up to Release 3.7</a>.</p>
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/about.html b/org.eclipse.jdt.core/about.html
new file mode 100644
index 0000000..c5eab07
--- /dev/null
+++ b/org.eclipse.jdt.core/about.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>March 17, 2011</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+<h3>Disassembler</h3>
+<p>This plug-in contains a bytecode disassembler (&quot;Disassembler&quot;) that can produce a listing of the Java assembler mnemonics (&quot;Assembler Mnemonics&quot;) for a Java method.  If you 
+use the Disassembler to view the Assembler Mnemonics for a method, you should ensure that doing so will not violate the terms of any licenses that apply to your use of that method, as
+such licenses may not permit you to reverse engineer, decompile, or disassemble method bytecodes.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf b/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf
new file mode 100644
index 0000000..125dc30
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/META-INF/eclipse.inf
@@ -0,0 +1,3 @@
+jarprocessor.exclude.sign=true
+jarprocessor.exclude.children=true
+jarprocessor.exclude.pack=true
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java
new file mode 100644
index 0000000..cd7238a
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/BuildJarIndex.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.eclipse.jdt.core.index.JavaIndexer;
+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
+
+/**
+ * <p>
+ * An Ant task to generate the index file for the given jar path.
+ * </p>
+ * <p>
+ * <code>&lt;eclipse.buildJarIndex jarPath="Test.jar" indexPath="Test.index"/&gt;</code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ * <p>
+ * This is not intended to be subclassed by users.
+ * </p>
+ * @since 3.8
+ */
+public class BuildJarIndex extends Task {
+
+	private String jarPath;
+	private String indexPath;
+
+	public void execute() throws BuildException {
+		if (this.jarPath == null) {
+			throw new BuildException(AntAdapterMessages.getString("buildJarIndex.jarFile.cannot.be.null")); //$NON-NLS-1$
+		}
+		if (this.indexPath == null) {
+			throw new BuildException(AntAdapterMessages.getString("buildJarIndex.indexFile.cannot.be.null")); //$NON-NLS-1$
+		}
+
+		try {
+			JavaIndexer.generateIndexForJar(this.jarPath, this.indexPath);
+		} catch (IOException e) {
+			throw new BuildException(AntAdapterMessages.getString("buildJarIndex.ioexception.occured", e.getLocalizedMessage())); //$NON-NLS-1$
+		}
+	}
+
+	public void setJarPath(String path) {
+		this.jarPath = path;
+	}
+
+	public void setIndexPath(String path) {
+		this.indexPath = path;
+	}
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
new file mode 100644
index 0000000..85db071
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
+
+/**
+ * <p>An Ant task to find out if a class file or a jar contains debug attributes. If this is the case,
+ * the property contains the value "has debug" after the call.
+ * </p>
+ * <p>
+ * <code>&lt;eclipse.checkDebugAttributes property="hasDebug" file="${basedir}/bin/p/A.class"/&gt;</code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ *
+ * This is not intended to be subclassed by users.
+ * @since 2.0
+ */
+public final class CheckDebugAttributes extends Task {
+
+	private String file;
+	private String property;
+
+	public void execute() throws BuildException {
+		if (this.file == null) {
+			throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.file.argument.cannot.be.null")); //$NON-NLS-1$
+		}
+		if (this.property == null) {
+			throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.property.argument.cannot.be.null")); //$NON-NLS-1$
+		}
+		try {
+			boolean hasDebugAttributes = false;
+			if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(this.file)) {
+				IClassFileReader classFileReader = ToolFactory.createDefaultClassFileReader(this.file, IClassFileReader.ALL);
+				hasDebugAttributes = checkClassFile(classFileReader);
+			} else {
+				ZipFile jarFile = null;
+				try {
+					jarFile = new ZipFile(this.file);
+				} catch (ZipException e) {
+					throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile")); //$NON-NLS-1$
+				}
+				for (Enumeration entries = jarFile.entries(); !hasDebugAttributes && entries.hasMoreElements(); ) {
+					ZipEntry entry = (ZipEntry) entries.nextElement();
+					if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(entry.getName())) {
+						IClassFileReader classFileReader = ToolFactory.createDefaultClassFileReader(this.file, entry.getName(), IClassFileReader.ALL);
+						hasDebugAttributes = checkClassFile(classFileReader);
+					}
+				}
+			}
+			if (hasDebugAttributes) {
+				getProject().setUserProperty(this.property, "has debug"); //$NON-NLS-1$
+			}
+		} catch (IOException e) {
+			throw new BuildException(AntAdapterMessages.getString("checkDebugAttributes.ioexception.occured") + this.file); //$NON-NLS-1$
+		}
+	}
+
+	private boolean checkClassFile(IClassFileReader classFileReader) {
+		IMethodInfo[] methodInfos = classFileReader.getMethodInfos();
+		for (int i = 0, max = methodInfos.length; i < max; i++) {
+			ICodeAttribute codeAttribute = methodInfos[i].getCodeAttribute();
+			if (codeAttribute != null && codeAttribute.getLineNumberAttribute() != null) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void setFile(String value) {
+		this.file = value;
+	}
+
+	public void setProperty(String value) {
+		this.property = value;
+	}
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
new file mode 100644
index 0000000..966e175
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
@@ -0,0 +1,576 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Commandline.Argument;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Ant 1.5 compiler adapter for the Eclipse Java compiler. This adapter permits the
+ * Eclipse Java compiler to be used with the <code>javac</code> task in Ant scripts. In order
+ * to use it, just set the property <code>build.compiler</code> as follows:
+ * <p>
+ * <code>&lt;property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/&gt;</code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ *
+ * @since 2.0
+ */
+public class JDTCompilerAdapter extends DefaultCompilerAdapter {
+	private static final char[] SEPARATOR_CHARS = new char[] { '/', '\\' };
+	private static final char[] ADAPTER_PREFIX = "#ADAPTER#".toCharArray(); //$NON-NLS-1$
+	private static final char[] ADAPTER_ENCODING = "ENCODING#".toCharArray(); //$NON-NLS-1$
+	private static final char[] ADAPTER_ACCESS = "ACCESS#".toCharArray(); //$NON-NLS-1$
+	private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; //$NON-NLS-1$
+	String logFileName;
+	Map customDefaultOptions;
+	private Map fileEncodings = null;
+	private Map dirEncodings = null;
+	private List accessRules = null;
+
+	/**
+	 * Performs a compile using the JDT batch compiler
+	 * @throws BuildException if anything wrong happen during the compilation
+	 * @return boolean true if the compilation is ok, false otherwise
+	 */
+	public boolean execute() throws BuildException {
+		this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); //$NON-NLS-1$
+		Commandline cmd = setupJavacCommand();
+
+		try {
+			Class c = Class.forName(compilerClass);
+			Constructor batchCompilerConstructor = c.getConstructor(new Class[] { PrintWriter.class, PrintWriter.class, Boolean.TYPE, Map.class});
+			Object batchCompilerInstance = batchCompilerConstructor.newInstance(new Object[] {new PrintWriter(System.out), new PrintWriter(System.err), Boolean.TRUE, this.customDefaultOptions});
+			Method compile = c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$
+			Object result = compile.invoke(batchCompilerInstance, new Object[] { cmd.getArguments()});
+			final boolean resultValue = ((Boolean) result).booleanValue();
+			if (!resultValue && this.logFileName != null) {
+				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$
+			}
+			return resultValue;
+		} catch (ClassNotFoundException cnfe) {
+			throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler")); //$NON-NLS-1$
+		} catch (Exception ex) {
+			throw new BuildException(ex);
+		}
+	}
+
+
+	protected Commandline setupJavacCommand() throws BuildException {
+		Commandline cmd = new Commandline();
+		this.customDefaultOptions = new CompilerOptions().getMap();
+
+		Class javacClass = Javac.class;
+
+		/*
+		 * Read in the compiler arguments first since we might need to modify
+		 * the classpath if any access rules were specified
+		 */
+		String [] compilerArgs = processCompilerArguments(javacClass);
+
+		/*
+		 * This option is used to never exit at the end of the ant task.
+		 */
+		cmd.createArgument().setValue("-noExit"); //$NON-NLS-1$
+
+		if (this.bootclasspath != null) {
+			cmd.createArgument().setValue("-bootclasspath"); //$NON-NLS-1$
+			if (this.bootclasspath.size() != 0) {
+				/*
+				 * Set the bootclasspath for the Eclipse compiler.
+				 */
+				cmd.createArgument().setPath(this.bootclasspath);
+			} else {
+				cmd.createArgument().setValue(Util.EMPTY_STRING);
+			}
+		}
+
+		/*
+		 * Eclipse compiler doesn't support -extdirs.
+		 * It is emulated using the classpath. We add extdirs entries after the
+		 * bootclasspath.
+		 */
+		if (this.extdirs != null) {
+			cmd.createArgument().setValue("-extdirs"); //$NON-NLS-1$
+			cmd.createArgument().setPath(this.extdirs);
+		}
+
+		Path classpath = new Path(this.project);
+		/*
+		 * The java runtime is already handled, so we simply want to retrieve the
+		 * ant runtime and the compile classpath.
+		 */
+		classpath.append(getCompileClasspath());
+		/*
+		 * Set the classpath for the Eclipse compiler.
+		 */
+		cmd.createArgument().setValue("-classpath"); //$NON-NLS-1$
+		createClasspathArgument(cmd, classpath);
+
+		// For -sourcepath, use the "sourcepath" value if present.
+		// Otherwise default to the "srcdir" value.
+		Path sourcepath = null;
+
+		// retrieve the method getSourcepath() using reflect
+		// This is done to improve the compatibility to ant 1.5
+		Method getSourcepathMethod = null;
+		try {
+			getSourcepathMethod = javacClass.getMethod("getSourcepath", null); //$NON-NLS-1$
+		} catch(NoSuchMethodException e) {
+			// if not found, then we cannot use this method (ant 1.5)
+		}
+		Path compileSourcePath = null;
+		if (getSourcepathMethod != null) {
+			try {
+				compileSourcePath = (Path) getSourcepathMethod.invoke(this.attributes, null);
+			} catch (IllegalAccessException e) {
+				// should never happen
+			} catch (InvocationTargetException e) {
+				// should never happen
+			}
+		}
+		if (compileSourcePath != null) {
+			sourcepath = compileSourcePath;
+		} else {
+			sourcepath = this.src;
+		}
+		cmd.createArgument().setValue("-sourcepath"); //$NON-NLS-1$
+		createClasspathArgument(cmd, sourcepath);
+
+		final String javaVersion = JavaEnvUtils.getJavaVersion();
+		String memoryParameterPrefix = javaVersion.equals(JavaEnvUtils.JAVA_1_1) ? "-J-" : "-J-X";//$NON-NLS-1$//$NON-NLS-2$
+		if (this.memoryInitialSize != null) {
+			if (!this.attributes.isForkedJavac()) {
+				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryInitialSize"), Project.MSG_WARN); //$NON-NLS-1$
+			} else {
+				cmd.createArgument().setValue(memoryParameterPrefix
+						+ "ms" + this.memoryInitialSize); //$NON-NLS-1$
+			}
+		}
+
+		if (this.memoryMaximumSize != null) {
+			if (!this.attributes.isForkedJavac()) {
+				this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.ignoringMemoryMaximumSize"), Project.MSG_WARN); //$NON-NLS-1$
+			} else {
+				cmd.createArgument().setValue(memoryParameterPrefix
+						+ "mx" + this.memoryMaximumSize); //$NON-NLS-1$
+			}
+		}
+
+		if (this.debug) {
+			// retrieve the method getSourcepath() using reflect
+			// This is done to improve the compatibility to ant 1.5
+			Method getDebugLevelMethod = null;
+			try {
+				getDebugLevelMethod = javacClass.getMethod("getDebugLevel", null); //$NON-NLS-1$
+			} catch(NoSuchMethodException e) {
+				// if not found, then we cannot use this method (ant 1.5)
+				// debug level is only available with ant 1.5.x
+			}
+			String debugLevel = null;
+			if (getDebugLevelMethod != null) {
+				try {
+					debugLevel = (String) getDebugLevelMethod.invoke(this.attributes, null);
+				} catch (IllegalAccessException e) {
+					// should never happen
+				} catch (InvocationTargetException e) {
+					// should never happen
+				}
+			}
+			if (debugLevel != null) {
+				this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
+				if (debugLevel.length() != 0) {
+					if (debugLevel.indexOf("vars") != -1) {//$NON-NLS-1$
+						this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+					}
+					if (debugLevel.indexOf("lines") != -1) {//$NON-NLS-1$
+						this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
+					}
+					if (debugLevel.indexOf("source") != -1) {//$NON-NLS-1$
+						this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
+					}
+				}
+			} else {
+				this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.GENERATE);
+			}
+		} else {
+			this.customDefaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_SourceFileAttribute , CompilerOptions.DO_NOT_GENERATE);
+		}
+
+		/*
+		 * Handle the nowarn option. If none, then we generate all warnings.
+		 */
+		if (this.attributes.getNowarn()) {
+			// disable all warnings
+			Object[] entries = this.customDefaultOptions.entrySet().toArray();
+			for (int i = 0, max = entries.length; i < max; i++) {
+				Map.Entry entry = (Map.Entry) entries[i];
+				if (!(entry.getKey() instanceof String))
+					continue;
+				if (!(entry.getValue() instanceof String))
+					continue;
+				if (((String) entry.getValue()).equals(CompilerOptions.WARNING)) {
+					this.customDefaultOptions.put(entry.getKey(), CompilerOptions.IGNORE);
+				}
+			}
+			this.customDefaultOptions.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
+			if (this.deprecation) {
+				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
+				this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
+			}
+		} else if (this.deprecation) {
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
+		} else {
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
+			this.customDefaultOptions.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
+		}
+
+		/*
+		 * destDir option.
+		 */
+		if (this.destDir != null) {
+			cmd.createArgument().setValue("-d"); //$NON-NLS-1$
+			cmd.createArgument().setFile(this.destDir.getAbsoluteFile());
+		}
+
+		/*
+		 * verbose option
+		 */
+		if (this.verbose) {
+			cmd.createArgument().setValue("-verbose"); //$NON-NLS-1$
+		}
+
+		/*
+		 * failnoerror option
+		 */
+		if (!this.attributes.getFailonerror()) {
+			cmd.createArgument().setValue("-proceedOnError"); //$NON-NLS-1$
+		}
+
+		/*
+		 * target option.
+		 */
+		if (this.target != null) {
+			this.customDefaultOptions.put(CompilerOptions.OPTION_TargetPlatform, this.target);
+		}
+
+		/*
+		 * source option
+		 */
+		String source = this.attributes.getSource();
+		if (source != null) {
+			this.customDefaultOptions.put(CompilerOptions.OPTION_Source, source);
+		}
+
+		if (compilerArgs != null) {
+			/*
+			 * Add extra argument on the command line
+			 */
+			final int length = compilerArgs.length;
+			if (length != 0) {
+				for (int i = 0, max = length; i < max; i++) {
+					String arg = compilerArgs[i];
+					if (this.logFileName == null && "-log".equals(arg) && ((i + 1) < max)) { //$NON-NLS-1$
+						this.logFileName = compilerArgs[i + 1];
+					}
+					cmd.createArgument().setValue(arg);
+				}
+			}
+		}
+		/*
+		 * encoding option. javac task encoding property must be the last encoding on the command
+		 * line as compiler arg might also specify an encoding.
+		 */
+		if (this.encoding != null) {
+			cmd.createArgument().setValue("-encoding"); //$NON-NLS-1$
+			cmd.createArgument().setValue(this.encoding);
+		}
+
+		/*
+		 * Eclipse compiler doesn't have a -sourcepath option. This is
+		 * handled through the javac task that collects all source files in
+		 * srcdir option.
+		 */
+		logAndAddFilesToCompile(cmd);
+		return cmd;
+	}
+
+	/**
+	 * Get the compiler arguments
+	 * @param javacClass
+	 * @return String[] the array of arguments
+	 */
+	private String[] processCompilerArguments(Class javacClass) {
+		// retrieve the method getCurrentCompilerArgs() using reflect
+		// This is done to improve the compatibility to ant 1.5
+		Method getCurrentCompilerArgsMethod = null;
+		try {
+			getCurrentCompilerArgsMethod = javacClass.getMethod("getCurrentCompilerArgs", null); //$NON-NLS-1$
+		} catch (NoSuchMethodException e) {
+			// if not found, then we cannot use this method (ant 1.5)
+			// debug level is only available with ant 1.5.x
+		}
+		String[] compilerArgs = null;
+		if (getCurrentCompilerArgsMethod != null) {
+			try {
+				compilerArgs = (String[]) getCurrentCompilerArgsMethod.invoke(this.attributes, null);
+			} catch (IllegalAccessException e) {
+				// should never happen
+			} catch (InvocationTargetException e) {
+				// should never happen
+			}
+		}
+		//check the compiler arguments for anything requiring extra processing
+		if (compilerArgs != null) checkCompilerArgs(compilerArgs);
+		return compilerArgs;
+	}
+	/**
+	 * check the compiler arguments.
+	 * Extract from files specified using @, lines marked with ADAPTER_PREFIX
+	 * These lines specify information that needs to be interpreted by us.
+	 * @param args compiler arguments to process
+	 */
+	private void checkCompilerArgs(String[] args) {
+		for (int i = 0; i < args.length; i++) {
+			if (args[i].charAt(0) == '@') {
+				try {
+					char[] content = Util.getFileCharContent(new File(args[i].substring(1)), null);
+					int offset = 0;
+					int prefixLength = ADAPTER_PREFIX.length;
+					while ((offset = CharOperation.indexOf(ADAPTER_PREFIX, content, true, offset)) > -1) {
+						int start = offset + prefixLength;
+						int end = CharOperation.indexOf('\n', content, start);
+						if (end == -1)
+							end = content.length;
+						while (CharOperation.isWhitespace(content[end])) {
+							end--;
+						}
+
+						// end is inclusive, but in the API end is exclusive
+						if (CharOperation.equals(ADAPTER_ENCODING, content, start, start + ADAPTER_ENCODING.length)) {
+							CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, end + 1);
+							// file or folder level custom encoding
+							start += ADAPTER_ENCODING.length;
+							int encodeStart = CharOperation.lastIndexOf('[', content, start, end);
+							if (start < encodeStart && encodeStart < end) {
+								boolean isFile = CharOperation.equals(SuffixConstants.SUFFIX_java, content, encodeStart - 5, encodeStart, false);
+
+								String str = String.valueOf(content, start, encodeStart - start);
+								String enc = String.valueOf(content, encodeStart, end - encodeStart + 1);
+								if (isFile) {
+									if (this.fileEncodings == null)
+										this.fileEncodings = new HashMap();
+									//use File to translate the string into a path with the correct File.seperator
+									this.fileEncodings.put(str, enc);
+								} else {
+									if (this.dirEncodings == null)
+										this.dirEncodings = new HashMap();
+									this.dirEncodings.put(str, enc);
+								}
+							}
+						} else if (CharOperation.equals(ADAPTER_ACCESS, content, start, start + ADAPTER_ACCESS.length)) {
+							// access rules for the classpath
+							start += ADAPTER_ACCESS.length;
+							int accessStart = CharOperation.indexOf('[', content, start, end);
+							CharOperation.replace(content, SEPARATOR_CHARS, File.separatorChar, start, accessStart);
+							if (start < accessStart && accessStart < end) {
+								String path = String.valueOf(content, start, accessStart - start);
+								String access = String.valueOf(content, accessStart, end - accessStart + 1);
+								if (this.accessRules == null)
+									this.accessRules = new ArrayList();
+								this.accessRules.add(path);
+								this.accessRules.add(access);
+							}
+						}
+						offset = end;
+					}
+				} catch (IOException e) {
+					//ignore
+				}
+			}
+		}
+
+	}
+
+	/**
+	 * Copy the classpath to the command line with access rules included.
+	 * @param cmd the given command line
+	 * @param classpath the given classpath entry
+	 */
+	private void createClasspathArgument(Commandline cmd, Path classpath) {
+		Argument arg = cmd.createArgument();
+		final String[] pathElements = classpath.list();
+
+		// empty path return empty string
+		if (pathElements.length == 0) {
+			arg.setValue(Util.EMPTY_STRING);
+			return;
+		}
+
+		// no access rules, can set the path directly
+		if (this.accessRules == null) {
+			arg.setPath(classpath);
+			return;
+		}
+
+		int rulesLength = this.accessRules.size();
+		String[] rules = (String[]) this.accessRules.toArray(new String[rulesLength]);
+		int nextRule = 0;
+		final StringBuffer result = new StringBuffer();
+
+		//access rules are expected in the same order as the classpath, but there could
+		//be elements in the classpath not in the access rules or access rules not in the classpath
+		for (int i = 0, max = pathElements.length; i < max; i++) {
+			if (i > 0)
+				result.append(File.pathSeparatorChar);
+			String pathElement = pathElements[i];
+			result.append(pathElement);
+			//the rules list is [path, rule, path, rule, ...]
+			for (int j = nextRule; j < rulesLength; j += 2) {
+				String rule = rules[j];
+				if (pathElement.endsWith(rule)) {
+					result.append(rules[j + 1]);
+					nextRule = j + 2;
+					break;
+				}
+				// if the path doesn't match, it could be due to a trailing file separatorChar in the rule
+				if (rule.endsWith(File.separator)) {
+					// rule ends with the File.separator, but pathElement might not
+					// otherwise it would match on the first endsWith
+					int ruleLength = rule.length();
+					if (pathElement.regionMatches(false, pathElement.length() - ruleLength + 1, rule, 0, ruleLength - 1)) {
+						result.append(rules[j + 1]);
+						nextRule = j + 2;
+						break;
+					}
+				} else if (pathElement.endsWith(File.separator)) {
+					// rule doesn't end with the File.separator, but pathElement might
+					int ruleLength = rule.length();
+					if (pathElement.regionMatches(false, pathElement.length() - ruleLength - 1, rule, 0, ruleLength)) {
+						result.append(rules[j + 1]);
+						nextRule = j + 2;
+						break;
+					}
+				}
+			}
+		}
+
+		arg.setValue(result.toString());
+	}
+	/**
+	 * Modified from base class, Logs the compilation parameters, adds the files
+	 * to compile and logs the &quot;niceSourceList&quot;
+	 * Appends encoding information at the end of arguments
+	 *
+	 * @param cmd the given command line
+	 */
+	protected void logAndAddFilesToCompile(Commandline cmd) {
+		this.attributes.log("Compilation " + cmd.describeArguments(), //$NON-NLS-1$
+				Project.MSG_VERBOSE);
+
+		StringBuffer niceSourceList = new StringBuffer("File"); //$NON-NLS-1$
+		if (this.compileList.length != 1) {
+			niceSourceList.append("s"); //$NON-NLS-1$
+		}
+		niceSourceList.append(" to be compiled:"); //$NON-NLS-1$
+		niceSourceList.append(lSep);
+
+		String[] encodedFiles = null, encodedDirs = null;
+		int encodedFilesLength = 0, encodedDirsLength = 0;
+		if (this.fileEncodings != null) {
+			encodedFilesLength = this.fileEncodings.size();
+			encodedFiles = new String[encodedFilesLength];
+			this.fileEncodings.keySet().toArray(encodedFiles);
+		}
+		if (this.dirEncodings != null) {
+			encodedDirsLength = this.dirEncodings.size();
+			encodedDirs = new String[encodedDirsLength];
+			this.dirEncodings.keySet().toArray(encodedDirs);
+			//we need the directories sorted, longest first,since sub directories can
+			//override encodings for their parent directories
+			Comparator comparator = new Comparator() {
+				public int compare(Object o1, Object o2) {
+					return ((String) o2).length() - ((String) o1).length();
+				}
+			};
+			Arrays.sort(encodedDirs, comparator);
+		}
+
+		for (int i = 0; i < this.compileList.length; i++) {
+			String arg = this.compileList[i].getAbsolutePath();
+			boolean encoded = false;
+			if (encodedFiles != null) {
+				//check for file level custom encoding
+				for (int j = 0; j < encodedFilesLength; j++) {
+					if (arg.endsWith(encodedFiles[j])) {
+						//found encoding, remove it from the list to speed things up next time around
+						arg = arg + (String) this.fileEncodings.get(encodedFiles[j]);
+						if (j < encodedFilesLength - 1) {
+							System.arraycopy(encodedFiles, j + 1, encodedFiles, j, encodedFilesLength - j - 1);
+						}
+						encodedFiles[--encodedFilesLength] = null;
+						encoded = true;
+						break;
+					}
+				}
+			}
+			if (!encoded && encodedDirs != null) {
+				//check folder level custom encoding
+				for (int j = 0; j < encodedDirsLength; j++) {
+					if (arg.lastIndexOf(encodedDirs[j]) != -1) {
+						arg = arg + (String) this.dirEncodings.get(encodedDirs[j]);
+						break;
+					}
+				}
+			}
+			cmd.createArgument().setValue(arg);
+			niceSourceList.append("    " + arg + lSep); //$NON-NLS-1$
+		}
+
+		this.attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+	}
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
new file mode 100644
index 0000000..bad9d07
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.antadapter;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class AntAdapterMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.antadapter.messages"; //$NON-NLS-1$
+
+	private static ResourceBundle RESOURCE_BUNDLE;
+
+	static {
+		try {
+		RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.getDefault());
+		} catch(MissingResourceException e) {
+			System.out.println("Missing resource : " + BUNDLE_NAME.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
+			throw e;
+		}
+	}
+
+	private AntAdapterMessages() {
+		// cannot be instantiated
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+
+	public static String getString(String key, String argument) {
+		try {
+			String message = RESOURCE_BUNDLE.getString(key);
+			MessageFormat messageFormat = new MessageFormat(message);
+			return messageFormat.format(new String[] { argument } );
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
new file mode 100644
index 0000000..9cb9be2
--- /dev/null
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2000, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+### ant tasks messages.
+ant.jdtadapter.info.usingJDTCompiler=Using JDT compiler
+ant.jdtadapter.error.compilationFailed=Compilation failed. Compiler errors are available in {0}
+ant.jdtadapter.error.cannotFindJDTCompiler=Cannot find the JDT compiler
+ant.jdtadapter.info.ignoringMemoryInitialSize=Since fork is false, ignoring memoryInitialSize setting
+ant.jdtadapter.info.ignoringMemoryMaximumSize=Since fork is false, ignoring memoryMaximumSize setting
+
+checkDebugAttributes.file.argument.cannot.be.null=The file argument cannot be null
+checkDebugAttributes.property.argument.cannot.be.null=The property argument cannot be null
+checkDebugAttributes.ioexception.occured=IOException occurred while reading 
+checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile=The file argument must be a .class or a .jar file
+
+buildJarIndex.jarFile.cannot.be.null=The jar file argument cannot be null
+buildJarIndex.indexFile.cannot.be.null=The index file argument cannot be null
+buildJarIndex.ioexception.occured=IOException - {0}
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
new file mode 100644
index 0000000..09d02cb
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler.batch;
+
+import java.io.PrintWriter;
+
+import org.eclipse.jdt.core.compiler.CompilationProgress;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+
+/**
+ * A public API for invoking the Eclipse Compiler for Java. E.g.
+ * <pre>
+ * BatchCompiler.compile("C:\\mySources\\X.java -d C:\\myOutput", new PrintWriter(System.out), new PrintWriter(System.err), null);
+ * </pre>
+ *
+ * @since 3.4
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class BatchCompiler {
+
+	/**
+	 * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
+	 * to print messages, and reporting progress to the given compilation progress. Returns whether
+	 * the compilation completed successfully.
+	 * <p>
+	 * Reasons for a compilation failing to complete successfully include:</p>
+	 * <ul>
+	 * <li>an error was reported</li>
+	 * <li>a runtime exception occurred</li>
+	 * <li>the compilation was canceled using the compilation progress</li>
+	 * </ul>
+	 * <p>
+	 * The specification of the command line arguments is defined by running the batch compiler's help
+	 * <pre>BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);</pre>
+	 * </p>
+	 *
+	 * @param commandLine the command line arguments passed to the compiler
+	 * @param outWriter the writer used to print standard messages
+	 * @param errWriter the writer used to print error messages
+	 * @param progress the object to report progress to and to provide cancellation, or <code>null</code> if no progress is needed
+	 * @return whether the compilation completed successfully
+	 */
+	public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+		return compile(Main.tokenize(commandLine), outWriter, errWriter, progress);
+	}
+
+	/**
+	 * Invokes the Eclipse Compiler for Java with the given command line arguments, using the given writers
+	 * to print messages, and reporting progress to the given compilation progress. Returns whether
+	 * the compilation completed successfully.
+	 * <p>
+	 * Reasons for a compilation failing to complete successfully include:</p>
+	 * <ul>
+	 * <li>an error was reported</li>
+	 * <li>a runtime exception occurred</li>
+	 * <li>the compilation was canceled using the compilation progress</li>
+	 * </ul>
+	 * <p>
+	 * The specification of the command line arguments is defined by running the batch compiler's help
+	 * <pre>BatchCompiler.compile("-help", new PrintWriter(System.out), new PrintWriter(System.err), null);</pre>
+	 * </p>
+	 * Note that a <code>true</code> returned value indicates that no errors were reported, no runtime exceptions
+	 * occurred and that the compilation was not canceled.
+	 *
+	 * @param commandLineArguments the command line arguments passed to the compiler
+	 * @param outWriter the writer used to print standard messages
+	 * @param errWriter the writer used to print error messages
+	 * @param progress the object to report progress to and to provide cancellation, or <code>null</code> if no progress is needed
+	 * @return whether the compilation completed successfully
+	 */
+	public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+		return Main.compile(commandLineArguments, outWriter, errWriter, progress);
+	}
+
+	private BatchCompiler() {
+		// prevent instantiation
+	}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html
new file mode 100644
index 0000000..cf3bc8a
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/package.html
@@ -0,0 +1,16 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+This package contains the batch compiler API.
+<h2>
+Package Specification</h2>
+
+<p><br>This package contains the batch compiler API.
+</body>
+</html>
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
new file mode 100644
index 0000000..b7b368f
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathDirectory extends ClasspathLocation {
+
+private Hashtable directoryCache;
+private String[] missingPackageHolder = new String[1];
+private int mode; // ability to only consider one kind of files (source vs. binaries), by default use both
+private String encoding; // only useful if referenced in the source path
+
+ClasspathDirectory(File directory, String encoding, int mode,
+		AccessRuleSet accessRuleSet, String destinationPath) {
+	super(accessRuleSet, destinationPath);
+	this.mode = mode;
+	try {
+		this.path = directory.getCanonicalPath();
+	} catch (IOException e) {
+		// should not happen as we know that the file exists
+		this.path = directory.getAbsolutePath();
+	}
+	if (!this.path.endsWith(File.separator))
+		this.path += File.separator;
+	this.directoryCache = new Hashtable(11);
+	this.encoding = encoding;
+}
+String[] directoryList(String qualifiedPackageName) {
+	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
+	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
+	if (dirList != null) return dirList;
+
+	File dir = new File(this.path + qualifiedPackageName);
+	notFound : if (dir.isDirectory()) {
+		// must protect against a case insensitive File call
+		// walk the qualifiedPackageName backwards looking for an uppercase character before the '/'
+		int index = qualifiedPackageName.length();
+		int last = qualifiedPackageName.lastIndexOf(File.separatorChar);
+		while (--index > last && !ScannerHelper.isUpperCase(qualifiedPackageName.charAt(index))){/*empty*/}
+		if (index > last) {
+			if (last == -1) {
+				if (!doesFileExist(qualifiedPackageName, Util.EMPTY_STRING))
+					break notFound;
+			} else {
+				String packageName = qualifiedPackageName.substring(last + 1);
+				String parentPackage = qualifiedPackageName.substring(0, last);
+				if (!doesFileExist(packageName, parentPackage))
+					break notFound;
+			}
+		}
+		if ((dirList = dir.list()) == null)
+			dirList = CharOperation.NO_STRINGS;
+		this.directoryCache.put(qualifiedPackageName, dirList);
+		return dirList;
+	}
+	this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
+	return null;
+}
+boolean doesFileExist(String fileName, String qualifiedPackageName) {
+	String[] dirList = directoryList(qualifiedPackageName);
+	if (dirList == null) return false; // most common case
+
+	for (int i = dirList.length; --i >= 0;)
+		if (fileName.equals(dirList[i]))
+			return true;
+	return false;
+}
+public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
+	return null;
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+	if (!isPackage(qualifiedPackageName)) return null; // most common case
+
+	String fileName = new String(typeName);
+	boolean binaryExists = ((this.mode & BINARY) != 0) && doesFileExist(fileName + SUFFIX_STRING_class, qualifiedPackageName);
+	boolean sourceExists = ((this.mode & SOURCE) != 0) && doesFileExist(fileName + SUFFIX_STRING_java, qualifiedPackageName);
+	if (sourceExists && !asBinaryOnly) {
+		String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6)  + SUFFIX_STRING_java;
+		if (!binaryExists)
+			return new NameEnvironmentAnswer(new CompilationUnit(null,
+					fullSourcePath, this.encoding, this.destinationPath),
+					fetchAccessRestriction(qualifiedBinaryFileName));
+		String fullBinaryPath = this.path + qualifiedBinaryFileName;
+		long binaryModified = new File(fullBinaryPath).lastModified();
+		long sourceModified = new File(fullSourcePath).lastModified();
+		if (sourceModified > binaryModified)
+			return new NameEnvironmentAnswer(new CompilationUnit(null,
+					fullSourcePath, this.encoding, this.destinationPath),
+					fetchAccessRestriction(qualifiedBinaryFileName));
+	}
+	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,
+						fetchAccessRestriction(qualifiedBinaryFileName));
+		} catch (IOException e) {
+			// treat as if file is missing
+		} catch (ClassFormatException e) {
+			// treat as if file is missing
+		}
+	}
+	return null;
+}
+public char[][][] findTypeNames(String qualifiedPackageName) {
+	if (!isPackage(qualifiedPackageName)) {
+		return null; // most common case
+	}
+	File dir = new File(this.path + qualifiedPackageName);
+	if (!dir.exists() || !dir.isDirectory()) {
+		return null;
+	}
+	String[] listFiles = dir.list(new FilenameFilter() {
+		public boolean accept(File directory, String name) {
+			String fileName = name.toLowerCase();
+			return fileName.endsWith(".class") || fileName.endsWith(".java"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	});
+	int length;
+	if (listFiles == null || (length = listFiles.length) == 0) {
+		return null;
+	}
+	char[][][] result = new char[length][][];
+	char[][] packageName = CharOperation.splitOn(File.separatorChar, qualifiedPackageName.toCharArray());
+	for (int i = 0; i < length; i++) {
+		String fileName = listFiles[i];
+		int indexOfLastDot = fileName.indexOf('.');
+		result[i] = CharOperation.arrayConcat(packageName, fileName.substring(0, indexOfLastDot).toCharArray());
+	}
+	return result;
+}
+public void initialize() throws IOException {
+	// nothing to do
+}
+public boolean isPackage(String qualifiedPackageName) {
+	return directoryList(qualifiedPackageName) != null;
+}
+public void reset() {
+	this.directoryCache = new Hashtable(11);
+}
+public String toString() {
+	return "ClasspathDirectory " + this.path; //$NON-NLS-1$
+}
+public char[] normalizedPath() {
+	if (this.normalizedPath == null) {
+		this.normalizedPath = this.path.toCharArray();
+		if (File.separatorChar == '\\') {
+			CharOperation.replace(this.normalizedPath, '\\', '/');
+		}
+	}
+	return this.normalizedPath;
+}
+public String getPath() {
+	return this.path;
+}
+public int getMode() {
+	return this.mode;
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
new file mode 100644
index 0000000..332ccce
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathJar extends ClasspathLocation {
+
+protected File file;
+protected ZipFile zipFile;
+protected boolean closeZipFileAtEnd;
+protected Hashtable packageCache;
+
+public ClasspathJar(File file, boolean closeZipFileAtEnd,
+		AccessRuleSet accessRuleSet, String destinationPath) {
+	super(accessRuleSet, destinationPath);
+	this.file = file;
+	this.closeZipFileAtEnd = closeZipFileAtEnd;
+}
+
+public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
+	// expected to be called once only - if multiple calls desired, consider
+	// using a cache
+	InputStream inputStream = null;
+	try {
+		initialize();
+		ArrayList result = new ArrayList();
+		ZipEntry manifest = this.zipFile.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
+		if (manifest != null) { // non-null implies regular file
+			inputStream = this.zipFile.getInputStream(manifest);
+			ManifestAnalyzer analyzer = new ManifestAnalyzer();
+			boolean success = analyzer.analyzeManifestContents(inputStream);
+			List calledFileNames = analyzer.getCalledFileNames();
+			if (problemReporter != null) {
+				if (!success || analyzer.getClasspathSectionsCount() == 1 &&  calledFileNames == null) {
+					problemReporter.invalidClasspathSection(getPath());
+				} else if (analyzer.getClasspathSectionsCount() > 1) {
+					problemReporter.multipleClasspathSections(getPath());
+				}
+			}
+			if (calledFileNames != null) {
+				Iterator calledFilesIterator = calledFileNames.iterator();
+				String directoryPath = getPath();
+				int lastSeparator = directoryPath.lastIndexOf(File.separatorChar);
+				directoryPath = directoryPath.substring(0, lastSeparator + 1); // potentially empty (see bug 214731)
+				while (calledFilesIterator.hasNext()) {
+					result.add(new ClasspathJar(new File(directoryPath + (String) calledFilesIterator.next()), this.closeZipFileAtEnd, this.accessRuleSet, this.destinationPath));
+				}
+			}
+		}
+		return result;
+	} catch (IOException e) {
+		return null;
+	} finally {
+		if (inputStream != null) {
+			try {
+				inputStream.close();
+			} catch (IOException e) {
+				// best effort
+			}
+		}
+	}
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+}
+public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+	if (!isPackage(qualifiedPackageName))
+		return null; // most common case
+
+	try {
+		ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
+		if (reader != null)
+			return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName));
+	} catch(ClassFormatException e) {
+		// treat as if class file is missing
+	} catch (IOException e) {
+		// treat as if class file is missing
+	}
+	return null;
+}
+public char[][][] findTypeNames(String qualifiedPackageName) {
+	if (!isPackage(qualifiedPackageName))
+		return null; // most common case
+
+	ArrayList answers = new ArrayList();
+	nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
+		String fileName = ((ZipEntry) e.nextElement()).getName();
+
+		// add the package name & all of its parent packages
+		int last = fileName.lastIndexOf('/');
+		while (last > 0) {
+			// extract the package name
+			String packageName = fileName.substring(0, last);
+			if (!qualifiedPackageName.equals(packageName))
+				continue nextEntry;
+			int indexOfDot = fileName.lastIndexOf('.');
+			if (indexOfDot != -1) {
+				String typeName = fileName.substring(last + 1, indexOfDot);
+				char[] packageArray = packageName.toCharArray();
+				answers.add(
+					CharOperation.arrayConcat(
+						CharOperation.splitOn('/', packageArray),
+						typeName.toCharArray()));
+			}
+		}
+	}
+	int size = answers.size();
+	if (size != 0) {
+		char[][][] result = new char[size][][];
+		answers.toArray(result);
+		return null;
+	}
+	return null;
+}
+public void initialize() throws IOException {
+	if (this.zipFile == null) {
+		this.zipFile = new ZipFile(this.file);
+	}
+}
+public boolean isPackage(String qualifiedPackageName) {
+	if (this.packageCache != null)
+		return this.packageCache.containsKey(qualifiedPackageName);
+
+	this.packageCache = new Hashtable(41);
+	this.packageCache.put(Util.EMPTY_STRING, Util.EMPTY_STRING);
+
+	nextEntry : for (Enumeration e = this.zipFile.entries(); e.hasMoreElements(); ) {
+		String fileName = ((ZipEntry) e.nextElement()).getName();
+
+		// add the package name & all of its parent packages
+		int last = fileName.lastIndexOf('/');
+		while (last > 0) {
+			// extract the package name
+			String packageName = fileName.substring(0, last);
+			if (this.packageCache.containsKey(packageName))
+				continue nextEntry;
+			this.packageCache.put(packageName, packageName);
+			last = packageName.lastIndexOf('/');
+		}
+	}
+	return this.packageCache.containsKey(qualifiedPackageName);
+}
+public void reset() {
+	if (this.zipFile != null && this.closeZipFileAtEnd) {
+		try {
+			this.zipFile.close();
+		} catch(IOException e) {
+			// ignore
+		}
+		this.zipFile = null;
+	}
+	this.packageCache = null;
+}
+public String toString() {
+	return "Classpath for jar file " + this.file.getPath(); //$NON-NLS-1$
+}
+public char[] normalizedPath() {
+	if (this.normalizedPath == null) {
+		String path2 = this.getPath();
+		char[] rawName = path2.toCharArray();
+		if (File.separatorChar == '\\') {
+			CharOperation.replace(rawName, '\\', '/');
+		}
+		this.normalizedPath = CharOperation.subarray(rawName, 0, CharOperation.lastIndexOf('.', rawName));
+	}
+	return this.normalizedPath;
+}
+public String getPath() {
+	if (this.path == null) {
+		try {
+			this.path = this.file.getCanonicalPath();
+		} catch (IOException e) {
+			// in case of error, simply return the absolute path
+			this.path = this.file.getAbsolutePath();
+		}
+	}
+	return this.path;
+}
+public int getMode() {
+	return BINARY;
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
new file mode 100644
index 0000000..f0c5c07
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+
+public abstract class ClasspathLocation implements FileSystem.Classpath,
+		SuffixConstants {
+
+	public static final int SOURCE = 1;
+	public static final int BINARY = 2;
+
+	String path;
+	char[] normalizedPath;
+	public AccessRuleSet accessRuleSet;
+
+	public String destinationPath;
+		// destination path for compilation units that are reached through this
+		// classpath location; the coding is consistent with the one of
+		// Main.destinationPath:
+		// == null: unspecified, use whatever value is set by the enclosing
+		//          context, id est Main;
+		// == Main.NONE: absorbent element, do not output class files;
+		// else: use as the path of the directory into which class files must
+		//       be written.
+		// potentially carried by any entry that contains to be compiled files
+
+	protected ClasspathLocation(AccessRuleSet accessRuleSet,
+			String destinationPath) {
+		this.accessRuleSet = accessRuleSet;
+		this.destinationPath = destinationPath;
+	}
+
+	/**
+	 * Return the first access rule which is violated when accessing a given
+	 * type, or null if no 'non accessible' access rule applies.
+	 *
+	 * @param qualifiedBinaryFileName
+	 *            tested type specification, formed as:
+	 *            "org/eclipse/jdt/core/JavaCore.class"; on systems that
+	 *            use \ as File.separator, the
+	 *            "org\eclipse\jdt\core\JavaCore.class" is accepted as well
+	 * @return the first access rule which is violated when accessing a given
+	 *         type, or null if none applies
+	 */
+	protected AccessRestriction fetchAccessRestriction(String qualifiedBinaryFileName) {
+		if (this.accessRuleSet == null)
+			return null;
+		char [] qualifiedTypeName = qualifiedBinaryFileName.
+			substring(0, qualifiedBinaryFileName.length() - SUFFIX_CLASS.length)
+			.toCharArray();
+		if (File.separatorChar == '\\') {
+			CharOperation.replace(qualifiedTypeName, File.separatorChar, '/');
+		}
+		return this.accessRuleSet.getViolatedRestriction(qualifiedTypeName);
+	}
+	
+	public int getMode() {
+		return SOURCE | BINARY;
+	}
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + this.getMode();
+		result = prime * result + ((this.path == null) ? 0 : this.path.hashCode());
+		return result;
+	}
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ClasspathLocation other = (ClasspathLocation) obj;
+		String localPath = this.getPath();
+		String otherPath = other.getPath();
+		if (localPath == null) {
+			if (otherPath != null)
+				return false;
+		} else if (!localPath.equals(otherPath))
+			return false;
+		if (this.getMode() != other.getMode())
+			return false;
+		return true;
+	}
+	public String getPath() {
+		return this.path;
+	}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java
new file mode 100644
index 0000000..fc94aa1
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathSourceJar extends ClasspathJar {
+	private String encoding;
+
+	public ClasspathSourceJar(File file, boolean closeZipFileAtEnd,
+			AccessRuleSet accessRuleSet, String encoding,
+			String destinationPath) {
+		super(file, closeZipFileAtEnd, accessRuleSet, destinationPath);
+		this.encoding = encoding;
+	}
+
+	public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+		if (!isPackage(qualifiedPackageName))
+			return null; // most common case
+
+		ZipEntry sourceEntry = this.zipFile.getEntry(qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6)  + SUFFIX_STRING_java);
+		if (sourceEntry != null) {
+			try {
+				InputStream stream = null;
+				char[] contents = null; 
+				try {
+					stream = this.zipFile.getInputStream(sourceEntry);
+					contents = Util.getInputStreamAsCharArray(stream, -1, this.encoding);
+				} finally {
+					if (stream != null)
+						stream.close();
+				}
+				return new NameEnvironmentAnswer(
+					new CompilationUnit(
+						contents,
+						qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java,
+						this.encoding,
+						this.destinationPath),
+					fetchAccessRestriction(qualifiedBinaryFileName));
+			} catch (IOException e) {
+				// treat as if source file is missing
+			}
+		}
+		return null;
+	}
+	public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+		return findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, false);
+	}
+	public int getMode() {
+		return SOURCE;
+	}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
new file mode 100644
index 0000000..64d3d89
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CompilationUnit implements ICompilationUnit {
+	public char[] contents;
+	public char[] fileName;
+	public char[] mainTypeName;
+	String encoding;
+	public String destinationPath;
+		// a specific destination path for this compilation unit; coding is
+		// aligned with Main.destinationPath:
+		// == null: unspecified, use whatever value is set by the enclosing
+		//          context, id est Main;
+		// == Main.NONE: absorbent element, do not output class files;
+		// else: use as the path of the directory into which class files must
+		//       be written.
+	private boolean ignoreOptionalProblems;
+
+public CompilationUnit(char[] contents, String fileName, String encoding) {
+	this(contents, fileName, encoding, null);
+}
+public CompilationUnit(char[] contents, String fileName, String encoding,
+		String destinationPath) {
+	this(contents, fileName, encoding, destinationPath, false);
+}
+public CompilationUnit(char[] contents, String fileName, String encoding,
+		String destinationPath, boolean ignoreOptionalProblems) {
+	this.contents = contents;
+	char[] fileNameCharArray = fileName.toCharArray();
+	switch(File.separatorChar) {
+		case '/' :
+			if (CharOperation.indexOf('\\', fileNameCharArray) != -1) {
+				CharOperation.replace(fileNameCharArray, '\\', '/');
+			}
+			break;
+		case '\\' :
+			if (CharOperation.indexOf('/', fileNameCharArray) != -1) {
+				CharOperation.replace(fileNameCharArray, '/', '\\');
+			}
+	}
+	this.fileName = fileNameCharArray;
+	int start = CharOperation.lastIndexOf(File.separatorChar, fileNameCharArray) + 1;
+
+	int end = CharOperation.lastIndexOf('.', fileNameCharArray);
+	if (end == -1) {
+		end = fileNameCharArray.length;
+	}
+
+	this.mainTypeName = CharOperation.subarray(fileNameCharArray, start, end);
+	this.encoding = encoding;
+	this.destinationPath = destinationPath;
+	this.ignoreOptionalProblems = ignoreOptionalProblems;
+}
+public char[] getContents() {
+	if (this.contents != null)
+		return this.contents;   // answer the cached source
+
+	// otherwise retrieve it
+	try {
+		return Util.getFileCharContent(new File(new String(this.fileName)), this.encoding);
+	} catch (IOException e) {
+		this.contents = CharOperation.NO_CHAR; // assume no source if asked again
+		throw new AbortCompilationUnit(null, e, this.encoding);
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.fileName;
+}
+public char[] getMainTypeName() {
+	return this.mainTypeName;
+}
+public char[][] getPackageName() {
+	return null;
+}
+public boolean ignoreOptionalProblems() {
+	return this.ignoreOptionalProblems;
+}
+public String toString() {
+	return "CompilationUnit[" + new String(this.fileName) + "]";  //$NON-NLS-2$ //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
new file mode 100644
index 0000000..0fb7a88
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class FileFinder {
+
+public static String[] find(File f, String pattern) {
+	ArrayList files = new ArrayList();
+	find0(f, pattern, files);
+	String[] result = new String[files.size()];
+	files.toArray(result);
+	return result;
+}
+private static void find0(File f, String pattern, ArrayList collector) {
+	if (f.isDirectory()) {
+		String[] files = f.list();
+		if (files == null) return;
+		for (int i = 0, max = files.length; i < max; i++) {
+			File current = new File(f, files[i]);
+			if (current.isDirectory()) {
+				find0(current, pattern, collector);
+			} else {
+				if (current.getName().toUpperCase().endsWith(pattern)) {
+					collector.add(current.getAbsolutePath());
+				}
+			}
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
new file mode 100644
index 0000000..af1b7e9
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class FileSystem implements INameEnvironment, SuffixConstants {
+	public interface Classpath {
+		char[][][] findTypeNames(String qualifiedPackageName);
+		NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName);
+		NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName, boolean asBinaryOnly);
+		boolean isPackage(String qualifiedPackageName);
+		/**
+		 * Return a list of the jar file names defined in the Class-Path section
+		 * of the jar file manifest if any, null else. Only ClasspathJar (and
+		 * extending classes) instances may return a non-null result.
+		 * @param  problemReporter problem reporter with which potential
+		 *         misconfiguration issues are raised
+		 * @return a list of the jar file names defined in the Class-Path
+		 *         section of the jar file manifest if any
+		 */
+		List fetchLinkedJars(ClasspathSectionProblemReporter problemReporter);
+		/**
+		 * This method resets the environment. The resulting state is equivalent to
+		 * a new name environment without creating a new object.
+		 */
+		void reset();
+		/**
+		 * Return a normalized path for file based classpath entries. This is an
+		 * absolute path in which file separators are transformed to the
+		 * platform-agnostic '/', ending with a '/' for directories. This is an
+		 * absolute path in which file separators are transformed to the
+		 * platform-agnostic '/', deprived from the '.jar' (resp. '.zip')
+		 * extension for jar (resp. zip) files.
+		 * @return a normalized path for file based classpath entries
+		 */
+		char[] normalizedPath();
+		/**
+		 * Return the path for file based classpath entries. This is an absolute path
+		 * ending with a file separator for directories, an absolute path including the '.jar'
+		 * (resp. '.zip') extension for jar (resp. zip) files.
+		 * @return the path for file based classpath entries
+		 */
+		String getPath();
+		/**
+		 * Initialize the entry
+		 */
+		void initialize() throws IOException;
+	}
+	public interface ClasspathSectionProblemReporter {
+		void invalidClasspathSection(String jarFilePath);
+		void multipleClasspathSections(String jarFilePath);
+	}
+
+	/**
+	 * This class is defined how to normalize the classpath entries.
+	 * It removes duplicate entries.
+	 */
+	public static class ClasspathNormalizer {
+		/**
+		 * Returns the normalized classpath entries (no duplicate).
+		 * <p>The given classpath entries are FileSystem.Classpath. We check the getPath() in order to find
+		 * duplicate entries.</p>
+		 *
+		 * @param classpaths the given classpath entries
+		 * @return the normalized classpath entries
+		 */
+		public static ArrayList normalize(ArrayList classpaths) {
+			ArrayList normalizedClasspath = new ArrayList();
+			HashSet cache = new HashSet();
+			for (Iterator iterator = classpaths.iterator(); iterator.hasNext(); ) {
+				FileSystem.Classpath classpath = (FileSystem.Classpath) iterator.next();
+				if (!cache.contains(classpath)) {
+					normalizedClasspath.add(classpath);
+					cache.add(classpath);
+				}
+			}
+			return normalizedClasspath;
+		}
+	}
+
+	protected Classpath[] classpaths;
+	Set knownFileNames;
+
+/*
+	classPathNames is a collection is Strings representing the full path of each class path
+	initialFileNames is a collection is Strings, the trailing '.java' will be removed if its not already.
+*/
+public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding) {
+	final int classpathSize = classpathNames.length;
+	this.classpaths = new Classpath[classpathSize];
+	int counter = 0;
+	for (int i = 0; i < classpathSize; i++) {
+		Classpath classpath = getClasspath(classpathNames[i], encoding, null);
+		try {
+			classpath.initialize();
+			this.classpaths[counter++] = classpath;
+		} catch (IOException e) {
+			// ignore
+		}
+	}
+	if (counter != classpathSize) {
+		System.arraycopy(this.classpaths, 0, (this.classpaths = new Classpath[counter]), 0, counter);
+	}
+	initializeKnownFileNames(initialFileNames);
+}
+protected FileSystem(Classpath[] paths, String[] initialFileNames) {
+	final int length = paths.length;
+	int counter = 0;
+	this.classpaths = new FileSystem.Classpath[length];
+	for (int i = 0; i < length; i++) {
+		final Classpath classpath = paths[i];
+		try {
+			classpath.initialize();
+			this.classpaths[counter++] = classpath;
+		} catch(IOException exception) {
+			// ignore
+		}
+	}
+	if (counter != length) {
+		// should not happen
+		System.arraycopy(this.classpaths, 0, (this.classpaths = new FileSystem.Classpath[counter]), 0, counter);
+	}
+	initializeKnownFileNames(initialFileNames);
+}
+public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) {
+	return getClasspath(classpathName, encoding, false, accessRuleSet, null);
+}
+public static Classpath getClasspath(String classpathName, String encoding,
+		boolean isSourceOnly, AccessRuleSet accessRuleSet,
+		String destinationPath) {
+	Classpath result = null;
+	File file = new File(convertPathSeparators(classpathName));
+	if (file.isDirectory()) {
+		if (file.exists()) {
+			result = new ClasspathDirectory(file, encoding,
+					isSourceOnly ? ClasspathLocation.SOURCE :
+						ClasspathLocation.SOURCE | ClasspathLocation.BINARY,
+					accessRuleSet,
+					destinationPath == null || destinationPath == Main.NONE ?
+						destinationPath : // keep == comparison valid
+						convertPathSeparators(destinationPath));
+		}
+	} else {
+		if (Util.isPotentialZipArchive(classpathName)) {
+			if (isSourceOnly) {
+				// source only mode
+				result = new ClasspathSourceJar(file, true, accessRuleSet,
+					encoding,
+					destinationPath == null || destinationPath == Main.NONE ?
+						destinationPath : // keep == comparison valid
+						convertPathSeparators(destinationPath));
+			} else if (destinationPath == null) {
+				// class file only mode
+				result = new ClasspathJar(file, true, accessRuleSet, null);
+			}
+		}
+	}
+	return result;
+}
+private void initializeKnownFileNames(String[] initialFileNames) {
+	if (initialFileNames == null) {
+		this.knownFileNames = new HashSet(0);
+		return;
+	}
+	this.knownFileNames = new HashSet(initialFileNames.length * 2);
+	for (int i = initialFileNames.length; --i >= 0;) {
+		File compilationUnitFile = new File(initialFileNames[i]);
+		char[] fileName = null;
+		try {
+			fileName = compilationUnitFile.getCanonicalPath().toCharArray();
+		} catch (IOException e) {
+			// this should not happen as the file exists
+			continue;
+		}
+		char[] matchingPathName = null;
+		final int lastIndexOf = CharOperation.lastIndexOf('.', fileName);
+		if (lastIndexOf != -1) {
+			fileName = CharOperation.subarray(fileName, 0, lastIndexOf);
+		}
+		CharOperation.replace(fileName, '\\', '/');
+		boolean globalPathMatches = false;
+		// the most nested path should be the selected one
+		for (int j = 0, max = this.classpaths.length; j < max; j++) {
+			char[] matchCandidate = this.classpaths[j].normalizedPath();
+			boolean currentPathMatch = false;
+			if (this.classpaths[j] instanceof ClasspathDirectory
+					&& CharOperation.prefixEquals(matchCandidate, fileName)) {
+				currentPathMatch = true;
+				if (matchingPathName == null) {
+					matchingPathName = matchCandidate;
+				} else {
+					if (currentPathMatch) {
+						// we have a second source folder that matches the path of the source file
+						if (matchCandidate.length > matchingPathName.length) {
+							// we want to preserve the shortest possible path
+							matchingPathName = matchCandidate;
+						}
+					} else {
+						// we want to preserve the shortest possible path
+						if (!globalPathMatches && matchCandidate.length < matchingPathName.length) {
+							matchingPathName = matchCandidate;
+						}
+					}
+				}
+				if (currentPathMatch) {
+					globalPathMatches = true;
+				}
+			}
+		}
+		if (matchingPathName == null) {
+			this.knownFileNames.add(new String(fileName)); // leave as is...
+		} else {
+			this.knownFileNames.add(new String(CharOperation.subarray(fileName, matchingPathName.length, fileName.length)));
+		}
+		matchingPathName = null;
+	}
+}
+public void cleanup() {
+	for (int i = 0, max = this.classpaths.length; i < max; i++)
+		this.classpaths[i].reset();
+}
+private static String convertPathSeparators(String path) {
+	return File.separatorChar == '/'
+		? path.replace('\\', '/')
+		 : path.replace('/', '\\');
+}
+private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly){
+	if (this.knownFileNames.contains(qualifiedTypeName)) return null; // looking for a file which we know was provided at the beginning of the compilation
+
+	String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+	String qualifiedPackageName =
+		qualifiedTypeName.length() == typeName.length
+			? Util.EMPTY_STRING
+			: qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1);
+	String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+	NameEnvironmentAnswer suggestedAnswer = null;
+	if (qualifiedPackageName == qp2) {
+		for (int i = 0, length = this.classpaths.length; i < length; i++) {
+			NameEnvironmentAnswer answer = this.classpaths[i].findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly);
+			if (answer != null) {
+				if (!answer.ignoreIfBetter()) {
+					if (answer.isBetter(suggestedAnswer))
+						return answer;
+				} else if (answer.isBetter(suggestedAnswer))
+					// remember suggestion and keep looking
+					suggestedAnswer = answer;
+			}
+		}
+	} else {
+		String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar);
+		for (int i = 0, length = this.classpaths.length; i < length; i++) {
+			Classpath p = this.classpaths[i];
+			NameEnvironmentAnswer answer = (p instanceof ClasspathJar)
+				? p.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly)
+				: p.findClass(typeName, qp2, qb2, asBinaryOnly);
+			if (answer != null) {
+				if (!answer.ignoreIfBetter()) {
+					if (answer.isBetter(suggestedAnswer))
+						return answer;
+				} else if (answer.isBetter(suggestedAnswer))
+					// remember suggestion and keep looking
+					suggestedAnswer = answer;
+			}
+		}
+	}
+	if (suggestedAnswer != null)
+		// no better answer was found
+		return suggestedAnswer;
+	return null;
+}
+public NameEnvironmentAnswer findType(char[][] compoundName) {
+	if (compoundName != null)
+		return findClass(
+			new String(CharOperation.concatWith(compoundName, '/')),
+			compoundName[compoundName.length - 1],
+			false);
+	return null;
+}
+public char[][][] findTypeNames(char[][] packageName) {
+	char[][][] result = null;
+	if (packageName != null) {
+		String qualifiedPackageName = new String(CharOperation.concatWith(packageName, '/'));
+		String qualifiedPackageName2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+		if (qualifiedPackageName == qualifiedPackageName2) {
+			for (int i = 0, length = this.classpaths.length; i < length; i++) {
+				char[][][] answers = this.classpaths[i].findTypeNames(qualifiedPackageName);
+				if (answers != null) {
+					// concat with previous answers
+					if (result == null) {
+						result = answers;
+					} else {
+						int resultLength = result.length;
+						int answersLength = answers.length;
+						System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
+						System.arraycopy(answers, 0, result, resultLength, answersLength);
+					}
+				}
+			}
+		} else {
+			for (int i = 0, length = this.classpaths.length; i < length; i++) {
+				Classpath p = this.classpaths[i];
+				char[][][] answers = (p instanceof ClasspathJar)
+					? p.findTypeNames(qualifiedPackageName)
+					: p.findTypeNames(qualifiedPackageName2);
+				if (answers != null) {
+					// concat with previous answers
+					if (result == null) {
+						result = answers;
+					} else {
+						int resultLength = result.length;
+						int answersLength = answers.length;
+						System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
+						System.arraycopy(answers, 0, result, resultLength, answersLength);
+					}
+				}
+			}
+		}
+	}
+	return result;
+}
+public NameEnvironmentAnswer findType(char[][] compoundName, boolean asBinaryOnly) {
+	if (compoundName != null)
+		return findClass(
+			new String(CharOperation.concatWith(compoundName, '/')),
+			compoundName[compoundName.length - 1],
+			asBinaryOnly);
+	return null;
+}
+public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+	if (typeName != null)
+		return findClass(
+			new String(CharOperation.concatWith(packageName, typeName, '/')),
+			typeName,
+			false);
+	return null;
+}
+public boolean isPackage(char[][] compoundName, char[] packageName) {
+	String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
+	String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
+	if (qualifiedPackageName == qp2) {
+		for (int i = 0, length = this.classpaths.length; i < length; i++)
+			if (this.classpaths[i].isPackage(qualifiedPackageName))
+				return true;
+	} else {
+		for (int i = 0, length = this.classpaths.length; i < length; i++) {
+			Classpath p = this.classpaths[i];
+			if ((p instanceof ClasspathJar) ? p.isPackage(qualifiedPackageName) : p.isPackage(qp2))
+				return true;
+		}
+	}
+	return false;
+}
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
new file mode 100644
index 0000000..35ae5b1
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -0,0 +1,4750 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Tom Tromey - Contribution for bug 125961
+ *     Tom Tromey - Contribution for bug 159641
+ *     Benjamin Muskalla - Contribution for bug 239066
+ *     Stephan Herrmann  - Contributions for 
+ *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ *     							bug 295551 - Add option to automatically promote all warnings to errors
+ *     							bug 359721 - [options] add command line option for new warning token "resource"
+ *								bug 365208 - [compiler][batch] command line options for annotation based null analysis
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.CompilationProgress;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
+import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.CompilerStats;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class Main implements ProblemSeverities, SuffixConstants {
+	public static class Logger {
+		private PrintWriter err;
+		private PrintWriter log;
+		private Main main;
+		private PrintWriter out;
+		private HashMap parameters;
+		int tagBits;
+		private static final String CLASS = "class"; //$NON-NLS-1$
+		private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$
+		private static final String CLASSPATH = "classpath"; //$NON-NLS-1$
+		private static final String CLASSPATH_FILE = "FILE"; //$NON-NLS-1$
+		private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
+		private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$
+		private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
+		private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$
+		private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
+		private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
+		private static final String COMPILER = "compiler"; //$NON-NLS-1$
+		private static final String COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$
+		private static final String COMPILER_NAME = "name"; //$NON-NLS-1$
+		private static final String COMPILER_VERSION = "version"; //$NON-NLS-1$
+		public static final int EMACS = 2;
+		private static final String ERROR = "ERROR"; //$NON-NLS-1$
+		private static final String ERROR_TAG = "error"; //$NON-NLS-1$
+		private static final String WARNING_TAG = "warning"; //$NON-NLS-1$
+		private static final String EXCEPTION = "exception"; //$NON-NLS-1$
+		private static final String EXTRA_PROBLEM_TAG = "extra_problem"; //$NON-NLS-1$
+		private static final String EXTRA_PROBLEMS = "extra_problems"; //$NON-NLS-1$
+		private static final HashtableOfInt FIELD_TABLE = new HashtableOfInt();
+		private static final String KEY = "key"; //$NON-NLS-1$
+		private static final String MESSAGE = "message"; //$NON-NLS-1$
+		private static final String NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$
+		private static final String NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$
+		private static final String NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$
+		private static final String NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$
+		private static final String NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$
+		private static final String NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$
+		private static final String OPTION = "option"; //$NON-NLS-1$
+		private static final String OPTIONS = "options"; //$NON-NLS-1$
+		private static final String OUTPUT = "output"; //$NON-NLS-1$
+		private static final String PACKAGE = "package"; //$NON-NLS-1$
+		private static final String PATH = "path"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$
+		private static final String PROBLEM_CATEGORY_ID = "categoryID"; //$NON-NLS-1$
+		private static final String ID = "id"; //$NON-NLS-1$
+		private static final String PROBLEM_ID = "problemID"; //$NON-NLS-1$
+		private static final String PROBLEM_LINE = "line"; //$NON-NLS-1$
+		private static final String PROBLEM_OPTION_KEY = "optionKey"; //$NON-NLS-1$
+		private static final String PROBLEM_MESSAGE = "message"; //$NON-NLS-1$
+		private static final String PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$
+		private static final String PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$
+		private static final String PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$
+		private static final String PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$
+		private static final String PROBLEM_TAG = "problem"; //$NON-NLS-1$
+		private static final String PROBLEMS = "problems"; //$NON-NLS-1$
+		private static final String SOURCE = "source"; //$NON-NLS-1$
+		private static final String SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$
+		private static final String SOURCE_END = "sourceEnd"; //$NON-NLS-1$
+		private static final String SOURCE_START = "sourceStart"; //$NON-NLS-1$
+		private static final String SOURCES = "sources"; //$NON-NLS-1$
+
+		private static final String STATS = "stats"; //$NON-NLS-1$
+
+		private static final String TASK = "task"; //$NON-NLS-1$
+		private static final String TASKS = "tasks"; //$NON-NLS-1$
+		private static final String TIME = "time"; //$NON-NLS-1$
+		private static final String VALUE = "value"; //$NON-NLS-1$
+		private static final String WARNING = "WARNING"; //$NON-NLS-1$
+		public static final int XML = 1;
+		private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.004 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_004.dtd\">"; //$NON-NLS-1$
+		static {
+			try {
+				Class c = IProblem.class;
+				Field[] fields = c.getFields();
+				for (int i = 0, max = fields.length; i < max; i++) {
+					Field field = fields[i];
+					if (field.getType().equals(Integer.TYPE)) {
+						Integer value = (Integer) field.get(null);
+						int key2 = value.intValue() & IProblem.IgnoreCategoriesMask;
+						if (key2 == 0) {
+							key2 = Integer.MAX_VALUE;
+						}
+						Logger.FIELD_TABLE.put(key2, field.getName());
+					}
+				}
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		public Logger(Main main, PrintWriter out, PrintWriter err) {
+			this.out = out;
+			this.err = err;
+			this.parameters = new HashMap();
+			this.main = main;
+		}
+
+		public String buildFileName(
+			String outputPath,
+			String relativeFileName) {
+			char fileSeparatorChar = File.separatorChar;
+			String fileSeparator = File.separator;
+
+			outputPath = outputPath.replace('/', fileSeparatorChar);
+			// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+			StringBuffer outDir = new StringBuffer(outputPath);
+			if (!outputPath.endsWith(fileSeparator)) {
+				outDir.append(fileSeparator);
+			}
+			StringTokenizer tokenizer =
+				new StringTokenizer(relativeFileName, fileSeparator);
+			String token = tokenizer.nextToken();
+			while (tokenizer.hasMoreTokens()) {
+				outDir.append(token).append(fileSeparator);
+				token = tokenizer.nextToken();
+			}
+			// token contains the last one
+			return outDir.append(token).toString();
+		}
+
+		public void close() {
+			if (this.log != null) {
+				if ((this.tagBits & Logger.XML) != 0) {
+					endTag(Logger.COMPILER);
+					flush();
+				}
+				this.log.close();
+			}
+		}
+
+		/**
+		 *
+		 */
+		public void compiling() {
+			printlnOut(this.main.bind("progress.compiling")); //$NON-NLS-1$
+		}
+		private void endLoggingExtraProblems() {
+			endTag(Logger.EXTRA_PROBLEMS);
+		}
+		/**
+		 * Used to stop logging problems.
+		 * Only use in xml mode.
+		 */
+		private void endLoggingProblems() {
+			endTag(Logger.PROBLEMS);
+		}
+		public void endLoggingSource() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				endTag(Logger.SOURCE);
+			}
+		}
+
+		public void endLoggingSources() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				endTag(Logger.SOURCES);
+			}
+		}
+
+		public void endLoggingTasks() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				endTag(Logger.TASKS);
+			}
+		}
+		private void endTag(String name) {
+			if (this.log != null) {
+				((GenericXMLWriter) this.log).endTag(name, true, true);
+			}
+		}
+		private String errorReportSource(CategorizedProblem problem, char[] unitSource, int bits) {
+			//extra from the source the innacurate     token
+			//and "highlight" it using some underneath ^^^^^
+			//put some context around too.
+
+			//this code assumes that the font used in the console is fixed size
+
+			//sanity .....
+			int startPosition = problem.getSourceStart();
+			int endPosition = problem.getSourceEnd();
+			if (unitSource == null) {
+				if (problem.getOriginatingFileName() != null) {
+					try {
+						unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
+					} catch (IOException e) {
+						// ignore;
+					}
+				}
+			}
+			int length;
+			if ((startPosition > endPosition)
+				|| ((startPosition < 0) && (endPosition < 0))
+				|| (unitSource == null)
+				|| (length = unitSource.length) == 0)
+				return Messages.problem_noSourceInformation;
+
+			StringBuffer errorBuffer = new StringBuffer();
+			if ((bits & Main.Logger.EMACS) == 0) {
+				errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(problem.getSourceLineNumber())));
+				errorBuffer.append(Util.LINE_SEPARATOR);
+			}
+			errorBuffer.append('\t');
+
+			char c;
+			final char SPACE = '\u0020';
+			final char MARK = '^';
+			final char TAB = '\t';
+			//the next code tries to underline the token.....
+			//it assumes (for a good display) that token source does not
+			//contain any \r \n. This is false on statements !
+			//(the code still works but the display is not optimal !)
+
+			// expand to line limits
+			int begin;
+			int end;
+			for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+				if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+			}
+			for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+				if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+			}
+
+			// trim left and right spaces/tabs
+			while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+			//while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated
+
+			// copy source
+			errorBuffer.append(unitSource, begin, end-begin+1);
+			errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
+
+			// compute underline
+			for (int i = begin; i <startPosition; i++) {
+				errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
+			}
+			for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) {
+				errorBuffer.append(MARK);
+			}
+			return errorBuffer.toString();
+		}
+
+		private void extractContext(CategorizedProblem problem, char[] unitSource) {
+			//sanity .....
+			int startPosition = problem.getSourceStart();
+			int endPosition = problem.getSourceEnd();
+			if (unitSource == null) {
+				if (problem.getOriginatingFileName() != null) {
+					try {
+						unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
+					} catch(IOException e) {
+						// ignore
+					}
+				}
+			}
+			int length;
+			if ((startPosition > endPosition)
+					|| ((startPosition < 0) && (endPosition < 0))
+					|| (unitSource == null)
+					|| ((length = unitSource.length) <= 0)
+					|| (endPosition > length)) {
+				this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
+				this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
+				this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
+				printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+				return;
+			}
+
+			char c;
+			//the next code tries to underline the token.....
+			//it assumes (for a good display) that token source does not
+			//contain any \r \n. This is false on statements !
+			//(the code still works but the display is not optimal !)
+
+			// expand to line limits
+			int begin, end;
+			for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+				if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+			}
+			for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+				if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+			}
+
+			// trim left and right spaces/tabs
+			while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+			while ((c = unitSource[end]) == ' ' || c == '\t') end--;
+
+			// copy source
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(unitSource, begin, end - begin + 1);
+
+			this.parameters.put(Logger.VALUE, String.valueOf(buffer));
+			this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
+			this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
+			printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
+		}
+		public void flush() {
+			this.out.flush();
+			this.err.flush();
+			if (this.log != null) {
+				this.log.flush();
+			}
+		}
+
+		private String getFieldName(int id) {
+			int key2 = id & IProblem.IgnoreCategoriesMask;
+			if (key2 == 0) {
+				key2 = Integer.MAX_VALUE;
+			}
+			return (String) Logger.FIELD_TABLE.get(key2);
+		}
+
+		// find out an option name controlling a given problemID
+		private String getProblemOptionKey(int problemID) {
+			int irritant = ProblemReporter.getIrritant(problemID);
+			return CompilerOptions.optionKeyFromIrritant(irritant);
+		}
+
+		public void logAverage() {
+			Arrays.sort(this.main.compilerStats);
+			long lineCount = this.main.compilerStats[0].lineCount;
+			final int length = this.main.maxRepetition;
+			long sum = 0;
+			long parseSum = 0, resolveSum = 0, analyzeSum = 0, generateSum = 0;
+			for (int i = 1, max = length - 1; i < max; i++) {
+				CompilerStats stats = this.main.compilerStats[i];
+				sum += stats.elapsedTime();
+				parseSum += stats.parseTime;
+				resolveSum += stats.resolveTime;
+				analyzeSum += stats.analyzeTime;
+				generateSum += stats.generateTime;
+			}
+			long time = sum / (length - 2);
+			long parseTime = parseSum/(length - 2);
+			long resolveTime = resolveSum/(length - 2);
+			long analyzeTime = analyzeSum/(length - 2);
+			long generateTime = generateSum/(length - 2);
+			printlnOut(this.main.bind(
+				"compile.averageTime", //$NON-NLS-1$
+				new String[] {
+					String.valueOf(lineCount),
+					String.valueOf(time),
+					String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
+				}));
+			if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
+				printlnOut(
+						this.main.bind("compile.detailedTime", //$NON-NLS-1$
+							new String[] {
+								String.valueOf(parseTime),
+								String.valueOf(((int) (parseTime * 1000.0 / time)) / 10.0),
+								String.valueOf(resolveTime),
+								String.valueOf(((int) (resolveTime * 1000.0 / time)) / 10.0),
+								String.valueOf(analyzeTime),
+								String.valueOf(((int) (analyzeTime * 1000.0 / time)) / 10.0),
+								String.valueOf(generateTime),
+								String.valueOf(((int) (generateTime * 1000.0 / time)) / 10.0),
+							}));
+			}
+		}
+		public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				String fileName = null;
+				if (generatePackagesStructure) {
+					fileName = buildFileName(outputPath, relativeFileName);
+				} else {
+					char fileSeparatorChar = File.separatorChar;
+					String fileSeparator = File.separator;
+					// First we ensure that the outputPath exists
+					outputPath = outputPath.replace('/', fileSeparatorChar);
+					// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+					int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
+					if (indexOfPackageSeparator == -1) {
+						if (outputPath.endsWith(fileSeparator)) {
+							fileName = outputPath + relativeFileName;
+						} else {
+							fileName = outputPath + fileSeparator + relativeFileName;
+						}
+					} else {
+						int length = relativeFileName.length();
+						if (outputPath.endsWith(fileSeparator)) {
+							fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+						} else {
+							fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+						}
+					}
+				}
+				File f = new File(fileName);
+				try {
+					this.parameters.put(Logger.PATH, f.getCanonicalPath());
+					printTag(Logger.CLASS_FILE, this.parameters, true, true);
+				} catch (IOException e) {
+					logNoClassFileCreated(outputPath, relativeFileName, e);
+				}
+			}
+		}
+		public void logClasspath(FileSystem.Classpath[] classpaths) {
+			if (classpaths == null) return;
+			if ((this.tagBits & Logger.XML) != 0) {
+				final int length = classpaths.length;
+				if (length != 0) {
+					// generate xml output
+					printTag(Logger.CLASSPATHS, null, true, false);
+					for (int i = 0; i < length; i++) {
+						String classpath = classpaths[i].getPath();
+						this.parameters.put(Logger.PATH, classpath);
+						File f = new File(classpath);
+						String id = null;
+						if (f.isFile()) {
+							if (Util.isPotentialZipArchive(classpath)) {
+								id = Logger.CLASSPATH_JAR;
+							} else {
+								id = Logger.CLASSPATH_FILE;
+							}
+						} else if (f.isDirectory()) {
+							id = Logger.CLASSPATH_FOLDER;
+						}
+						if (id != null) {
+							this.parameters.put(Logger.CLASSPATH_ID, id);
+							printTag(Logger.CLASSPATH, this.parameters, true, true);
+						}
+					}
+					endTag(Logger.CLASSPATHS);
+				}
+			}
+
+		}
+
+		public void logCommandLineArguments(String[] commandLineArguments) {
+			if (commandLineArguments == null) return;
+			if ((this.tagBits & Logger.XML) != 0) {
+				final int length = commandLineArguments.length;
+				if (length != 0) {
+					// generate xml output
+					printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false);
+					for (int i = 0; i < length; i++) {
+						this.parameters.put(Logger.VALUE, commandLineArguments[i]);
+						printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true);
+					}
+					endTag(Logger.COMMAND_LINE_ARGUMENTS);
+				}
+			}
+		}
+
+		/**
+		 * @param e the given exception to log
+		 */
+		public void logException(Exception e) {
+			StringWriter writer = new StringWriter();
+			PrintWriter printWriter = new PrintWriter(writer);
+			e.printStackTrace(printWriter);
+			printWriter.flush();
+			printWriter.close();
+			final String stackTrace = writer.toString();
+			if ((this.tagBits & Logger.XML) != 0) {
+				LineNumberReader reader = new LineNumberReader(new StringReader(stackTrace));
+				String line;
+				int i = 0;
+				StringBuffer buffer = new StringBuffer();
+				String message = e.getMessage();
+				if (message != null) {
+					buffer.append(message).append(Util.LINE_SEPARATOR);
+				}
+				try {
+					while ((line = reader.readLine()) != null && i < 4) {
+						buffer.append(line).append(Util.LINE_SEPARATOR);
+						i++;
+					}
+					reader.close();
+				} catch (IOException e1) {
+					// ignore
+				}
+				message = buffer.toString();
+				this.parameters.put(Logger.MESSAGE, message);
+				this.parameters.put(Logger.CLASS, e.getClass());
+				printTag(Logger.EXCEPTION, this.parameters, true, true);
+			}
+			String message = e.getMessage();
+			if (message == null) {
+				this.printlnErr(stackTrace);
+			} else {
+				this.printlnErr(message);
+			}
+		}
+
+		private void logExtraProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount) {
+			char[] originatingFileName = problem.getOriginatingFileName();
+			if (originatingFileName == null) {
+				// simplified message output
+				if (problem.isError()) {
+					printErr(this.main.bind(
+								"requestor.extraerror", //$NON-NLS-1$
+								Integer.toString(globalErrorCount)));
+				} else {
+					// warning / mandatory warning / other
+					printErr(this.main.bind(
+							"requestor.extrawarning", //$NON-NLS-1$
+							Integer.toString(globalErrorCount)));
+				}
+				printErr(" "); //$NON-NLS-1$
+				this.printlnErr(problem.getMessage());
+			} else {
+				String fileName = new String(originatingFileName);
+				if ((this.tagBits & Logger.EMACS) != 0) {
+					String result = fileName
+							+ ":" //$NON-NLS-1$
+							+ problem.getSourceLineNumber()
+							+ ": " //$NON-NLS-1$
+							+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
+							+ ": " //$NON-NLS-1$
+							+ problem.getMessage();
+					this.printlnErr(result);
+					final String errorReportSource = errorReportSource(problem, null, this.tagBits);
+					this.printlnErr(errorReportSource);
+				} else {
+					if (localErrorCount == 0) {
+						this.printlnErr("----------"); //$NON-NLS-1$
+					}
+					printErr(problem.isError() ?
+							this.main.bind(
+									"requestor.error", //$NON-NLS-1$
+									Integer.toString(globalErrorCount),
+									new String(fileName))
+									: this.main.bind(
+											"requestor.warning", //$NON-NLS-1$
+											Integer.toString(globalErrorCount),
+											new String(fileName)));
+					final String errorReportSource = errorReportSource(problem, null, 0);
+					this.printlnErr(errorReportSource);
+					this.printlnErr(problem.getMessage());
+					this.printlnErr("----------"); //$NON-NLS-1$
+				}
+			}
+		}
+
+		public void loggingExtraProblems(Main currentMain) {
+			ArrayList problems = currentMain.extraProblems;
+			final int count = problems.size();
+			int localProblemCount = 0;
+			if (count != 0) {
+				int errors = 0;
+				int warnings = 0;
+				for (int i = 0; i < count; i++) {
+					CategorizedProblem problem = (CategorizedProblem) problems.get(i);
+					if (problem != null) {
+						currentMain.globalProblemsCount++;
+						logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
+						localProblemCount++;
+						if (problem.isError()) {
+							errors++;
+							currentMain.globalErrorsCount++;
+						} else if (problem.isWarning()) {
+							currentMain.globalWarningsCount++;
+							warnings++;
+						}
+					}
+				}
+				if ((this.tagBits & Logger.XML) != 0) {
+					if ((errors + warnings) != 0) {
+						startLoggingExtraProblems(count);
+						for (int i = 0; i < count; i++) {
+							CategorizedProblem problem = (CategorizedProblem) problems.get(i);
+							if (problem!= null) {
+								if (problem.getID() != IProblem.Task) {
+									logXmlExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
+								}
+							}
+						}
+						endLoggingExtraProblems();
+					}
+				}
+			}
+		}
+
+		public void logIncorrectVMVersionForAnnotationProcessing() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
+				printTag(Logger.ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
+		}
+
+		/**
+		 *
+		 */
+		public void logNoClassFileCreated(String outputDir, String relativeFileName, IOException e) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
+					new String[] {
+						outputDir,
+						relativeFileName,
+						e.getMessage()
+					}));
+				printTag(Logger.ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
+				new String[] {
+					outputDir,
+					relativeFileName,
+					e.getMessage()
+				}));
+		}
+
+		/**
+		 * @param exportedClassFilesCounter
+		 */
+		public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.VALUE, new Integer(exportedClassFilesCounter));
+				printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true);
+			}
+			if (exportedClassFilesCounter == 1) {
+				printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
+			} else {
+				printlnOut(this.main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$
+					String.valueOf(exportedClassFilesCounter)));
+			}
+		}
+
+		/**
+		 * @param options the given compiler options
+		 */
+		public void logOptions(Map options) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				printTag(Logger.OPTIONS, null, true, false);
+				final Set entriesSet = options.entrySet();
+				Object[] entries = entriesSet.toArray();
+				Arrays.sort(entries, new Comparator() {
+					public int compare(Object o1, Object o2) {
+						Map.Entry entry1 = (Map.Entry) o1;
+						Map.Entry entry2 = (Map.Entry) o2;
+						return ((String) entry1.getKey()).compareTo((String) entry2.getKey());
+					}
+				});
+				for (int i = 0, max = entries.length; i < max; i++) {
+					Map.Entry entry = (Map.Entry) entries[i];
+					String key = (String) entry.getKey();
+					this.parameters.put(Logger.KEY, key);
+					this.parameters.put(Logger.VALUE, entry.getValue());
+					printTag(Logger.OPTION, this.parameters, true, true);
+				}
+				endTag(Logger.OPTIONS);
+			}
+		}
+
+		/**
+		 * @param error the given error
+		 */
+		public void logPendingError(String error) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.MESSAGE, error);
+				printTag(Logger.ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(error);
+		}
+
+		/**
+		 * @param message the given message
+		 */
+		public void logWarning(String message) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.MESSAGE, message);
+				printTag(Logger.WARNING_TAG, this.parameters, true, true);
+			}
+			this.printlnOut(message);
+		}
+
+		private void logProblem(CategorizedProblem problem, int localErrorCount,
+			int globalErrorCount, char[] unitSource) {
+			if ((this.tagBits & Logger.EMACS) != 0) {
+				String result = (new String(problem.getOriginatingFileName())
+						+ ":" //$NON-NLS-1$
+						+ problem.getSourceLineNumber()
+						+ ": " //$NON-NLS-1$
+						+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
+						+ ": " //$NON-NLS-1$
+						+ problem.getMessage());
+				this.printlnErr(result);
+				final String errorReportSource = errorReportSource(problem, unitSource, this.tagBits);
+				if (errorReportSource.length() != 0) this.printlnErr(errorReportSource);
+			} else {
+				if (localErrorCount == 0) {
+					this.printlnErr("----------"); //$NON-NLS-1$
+				}
+				printErr(problem.isError() ?
+						this.main.bind(
+								"requestor.error", //$NON-NLS-1$
+								Integer.toString(globalErrorCount),
+								new String(problem.getOriginatingFileName()))
+								: this.main.bind(
+										"requestor.warning", //$NON-NLS-1$
+										Integer.toString(globalErrorCount),
+										new String(problem.getOriginatingFileName())));
+				try {
+					final String errorReportSource = errorReportSource(problem, unitSource, 0);
+					this.printlnErr(errorReportSource);
+					this.printlnErr(problem.getMessage());
+				} catch (Exception e) {
+					this.printlnErr(this.main.bind(
+						"requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$
+				}
+				this.printlnErr("----------"); //$NON-NLS-1$
+			}
+		}
+
+		public int logProblems(CategorizedProblem[] problems, char[] unitSource, Main currentMain) {
+			final int count = problems.length;
+			int localErrorCount = 0;
+			int localProblemCount = 0;
+			if (count != 0) {
+				int errors = 0;
+				int warnings = 0;
+				int tasks = 0;
+				for (int i = 0; i < count; i++) {
+					CategorizedProblem problem = problems[i];
+					if (problem != null) {
+						currentMain.globalProblemsCount++;
+						logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource);
+						localProblemCount++;
+						if (problem.isError()) {
+							localErrorCount++;
+							errors++;
+							currentMain.globalErrorsCount++;
+						} else if (problem.getID() == IProblem.Task) {
+							currentMain.globalTasksCount++;
+							tasks++;
+						} else {
+							currentMain.globalWarningsCount++;
+							warnings++;
+						}
+					}
+				}
+				if ((this.tagBits & Logger.XML) != 0) {
+					if ((errors + warnings) != 0) {
+						startLoggingProblems(errors, warnings);
+						for (int i = 0; i < count; i++) {
+							CategorizedProblem problem = problems[i];
+							if (problem!= null) {
+								if (problem.getID() != IProblem.Task) {
+									logXmlProblem(problem, unitSource);
+								}
+							}
+						}
+						endLoggingProblems();
+					}
+					if (tasks != 0) {
+						startLoggingTasks(tasks);
+						for (int i = 0; i < count; i++) {
+							CategorizedProblem problem = problems[i];
+							if (problem!= null) {
+								if (problem.getID() == IProblem.Task) {
+									logXmlTask(problem, unitSource);
+								}
+							}
+						}
+						endLoggingTasks();
+					}
+				}
+			}
+			return localErrorCount;
+		}
+
+		/**
+		 * @param globalProblemsCount
+		 * @param globalErrorsCount
+		 * @param globalWarningsCount
+		 */
+		public void logProblemsSummary(int globalProblemsCount,
+			int globalErrorsCount, int globalWarningsCount, int globalTasksCount) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				// generate xml
+				this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(globalProblemsCount));
+				this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer(globalErrorsCount));
+				this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer(globalWarningsCount));
+				this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer(globalTasksCount));
+				printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true);
+			}
+			if (globalProblemsCount == 1) {
+				String message = null;
+				if (globalErrorsCount == 1) {
+					message = this.main.bind("compile.oneError"); //$NON-NLS-1$
+				} else {
+					message = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
+				}
+				printErr(this.main.bind("compile.oneProblem", message)); //$NON-NLS-1$
+			} else {
+				String errorMessage = null;
+				String warningMessage = null;
+				if (globalErrorsCount > 0) {
+					if (globalErrorsCount == 1) {
+						errorMessage = this.main.bind("compile.oneError"); //$NON-NLS-1$
+					} else {
+						errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
+					}
+				}
+				int warningsNumber = globalWarningsCount + globalTasksCount;
+				if (warningsNumber > 0) {
+					if (warningsNumber == 1) {
+						warningMessage = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
+					} else {
+						warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
+					}
+				}
+				if (errorMessage == null || warningMessage == null) {
+					if (errorMessage == null) {
+						printErr(this.main.bind(
+							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+							String.valueOf(globalProblemsCount),
+							warningMessage));
+					} else {
+						printErr(this.main.bind(
+							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+							String.valueOf(globalProblemsCount),
+							errorMessage));
+					}
+				} else {
+					printErr(this.main.bind(
+						"compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
+						new String[] {
+							String.valueOf(globalProblemsCount),
+							errorMessage,
+							warningMessage
+						}));
+				}
+			}
+			if ((this.tagBits & Logger.EMACS) != 0) {
+				this.printlnErr();
+			}
+		}
+
+		/**
+		 *
+		 */
+		public void logProgress() {
+			printOut('.');
+		}
+
+		/**
+		 * @param i
+		 *            the current repetition number
+		 * @param repetitions
+		 *            the given number of repetitions
+		 */
+		public void logRepetition(int i, int repetitions) {
+			printlnOut(this.main.bind("compile.repetition", //$NON-NLS-1$
+				String.valueOf(i + 1), String.valueOf(repetitions)));
+		}
+		/**
+		 * @param compilerStats
+		 */
+		public void logTiming(CompilerStats compilerStats) {
+			long time = compilerStats.elapsedTime();
+			long lineCount = compilerStats.lineCount;
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.VALUE, new Long(time));
+				printTag(Logger.TIME, this.parameters, true, true);
+				this.parameters.put(Logger.VALUE, new Long(lineCount));
+				printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true);
+			}
+			if (lineCount != 0) {
+				printlnOut(
+					this.main.bind("compile.instantTime", //$NON-NLS-1$
+						new String[] {
+							String.valueOf(lineCount),
+							String.valueOf(time),
+							String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
+						}));
+			} else {
+				printlnOut(
+					this.main.bind("compile.totalTime", //$NON-NLS-1$
+						new String[] {
+							String.valueOf(time),
+						}));
+			}
+			if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
+				printlnOut(
+						this.main.bind("compile.detailedTime", //$NON-NLS-1$
+							new String[] {
+								String.valueOf(compilerStats.parseTime),
+								String.valueOf(((int) (compilerStats.parseTime * 1000.0 / time)) / 10.0),
+								String.valueOf(compilerStats.resolveTime),
+								String.valueOf(((int) (compilerStats.resolveTime * 1000.0 / time)) / 10.0),
+								String.valueOf(compilerStats.analyzeTime),
+								String.valueOf(((int) (compilerStats.analyzeTime * 1000.0 / time)) / 10.0),
+								String.valueOf(compilerStats.generateTime),
+								String.valueOf(((int) (compilerStats.generateTime * 1000.0 / time)) / 10.0),
+							}));
+			}
+		}
+
+		/**
+		 * Print the usage of the compiler
+		 * @param usage
+		 */
+		public void logUsage(String usage) {
+			printlnOut(usage);
+		}
+
+		/**
+		 * Print the version of the compiler in the log and/or the out field
+		 */
+		public void logVersion(final boolean printToOut) {
+			if (this.log != null && (this.tagBits & Logger.XML) == 0) {
+				final String version = this.main.bind("misc.version", //$NON-NLS-1$
+					new String[] {
+						this.main.bind("compiler.name"), //$NON-NLS-1$
+						this.main.bind("compiler.version"), //$NON-NLS-1$
+						this.main.bind("compiler.copyright") //$NON-NLS-1$
+					}
+				);
+				this.log.println("# " + version); //$NON-NLS-1$
+				if (printToOut) {
+					this.out.println(version);
+					this.out.flush();
+				}
+			} else if (printToOut) {
+				final String version = this.main.bind("misc.version", //$NON-NLS-1$
+					new String[] {
+						this.main.bind("compiler.name"), //$NON-NLS-1$
+						this.main.bind("compiler.version"), //$NON-NLS-1$
+						this.main.bind("compiler.copyright") //$NON-NLS-1$
+					}
+				);
+				this.out.println(version);
+				this.out.flush();
+			}
+		}
+
+		/**
+		 * Print the usage of wrong JDK
+		 */
+		public void logWrongJDK() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+				printTag(Logger.ERROR, this.parameters, true, true);
+			}
+			this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+		}
+
+		private void logXmlExtraProblem(CategorizedProblem problem, int globalErrorCount, int localErrorCount) {
+			final int sourceStart = problem.getSourceStart();
+			final int sourceEnd = problem.getSourceEnd();
+			boolean isError = problem.isError();
+			this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
+			this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+			this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(sourceStart));
+			this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(sourceEnd));
+			printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false);
+			this.parameters.put(Logger.VALUE, problem.getMessage());
+			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+			extractContext(problem, null);
+			endTag(Logger.EXTRA_PROBLEM_TAG);
+		}
+		/**
+		 * @param problem
+		 *            the given problem to log
+		 * @param unitSource
+		 *            the given unit source
+		 */
+		private void logXmlProblem(CategorizedProblem problem, char[] unitSource) {
+			final int sourceStart = problem.getSourceStart();
+			final int sourceEnd = problem.getSourceEnd();
+			final int id = problem.getID();
+			this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name
+			this.parameters.put(Logger.PROBLEM_ID, new Integer(id)); // ID as numeric value
+			boolean isError = problem.isError();
+			int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning;
+			this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : Logger.WARNING);
+			this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+			this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(sourceStart));
+			this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(sourceEnd));
+			String problemOptionKey = getProblemOptionKey(id);
+			if (problemOptionKey != null) {
+				this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+			}
+			int categoryID = ProblemReporter.getProblemCategory(severity, id);
+			this.parameters.put(Logger.PROBLEM_CATEGORY_ID, new Integer(categoryID));
+			printTag(Logger.PROBLEM_TAG, this.parameters, true, false);
+			this.parameters.put(Logger.VALUE, problem.getMessage());
+			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+			extractContext(problem, unitSource);
+			String[] arguments = problem.getArguments();
+			final int length = arguments.length;
+			if (length != 0) {
+				printTag(Logger.PROBLEM_ARGUMENTS, null, true, false);
+				for (int i = 0; i < length; i++) {
+					this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
+					printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true);
+				}
+				endTag(Logger.PROBLEM_ARGUMENTS);
+			}
+			endTag(Logger.PROBLEM_TAG);
+		}
+		/**
+		 * @param problem
+		 *            the given problem to log
+		 * @param unitSource
+		 *            the given unit source
+		 */
+		private void logXmlTask(CategorizedProblem problem, char[] unitSource) {
+			this.parameters.put(Logger.PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+			this.parameters.put(Logger.PROBLEM_SOURCE_START, new Integer(problem.getSourceStart()));
+			this.parameters.put(Logger.PROBLEM_SOURCE_END, new Integer(problem.getSourceEnd()));
+			String problemOptionKey = getProblemOptionKey(problem.getID());
+			if (problemOptionKey != null) {
+				this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
+			}
+			printTag(Logger.TASK, this.parameters, true, false);
+			this.parameters.put(Logger.VALUE, problem.getMessage());
+			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
+			extractContext(problem, unitSource);
+			endTag(Logger.TASK);
+		}
+
+		private void printErr(String s) {
+			this.err.print(s);
+			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+				this.log.print(s);
+			}
+		}
+
+		private void printlnErr() {
+			this.err.println();
+			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+				this.log.println();
+			}
+		}
+
+		private void printlnErr(String s) {
+			this.err.println(s);
+			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+				this.log.println(s);
+			}
+		}
+
+		private void printlnOut(String s) {
+			this.out.println(s);
+			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
+				this.log.println(s);
+			}
+		}
+
+		/**
+		 *
+		 */
+		public void printNewLine() {
+			this.out.println();
+		}
+
+		private void printOut(char c) {
+			this.out.print(c);
+		}
+
+		public void printStats() {
+			final boolean isTimed = (this.main.timing & TIMING_ENABLED) != 0;
+			if ((this.tagBits & Logger.XML) != 0) {
+				printTag(Logger.STATS, null, true, false);
+			}
+			if (isTimed) {
+				CompilerStats compilerStats = this.main.batchCompiler.stats;
+				compilerStats.startTime = this.main.startTime; // also include batch initialization times
+				compilerStats.endTime = System.currentTimeMillis(); // also include batch output times
+				logTiming(compilerStats);
+			}
+			if (this.main.globalProblemsCount > 0) {
+				logProblemsSummary(this.main.globalProblemsCount, this.main.globalErrorsCount, this.main.globalWarningsCount, this.main.globalTasksCount);
+			}
+			if (this.main.exportedClassFilesCounter != 0
+					&& (this.main.showProgress || isTimed || this.main.verbose)) {
+				logNumberOfClassFilesGenerated(this.main.exportedClassFilesCounter);
+			}
+			if ((this.tagBits & Logger.XML) != 0) {
+				endTag(Logger.STATS);
+			}
+		}
+
+		private void printTag(String name, HashMap params, boolean insertNewLine, boolean closeTag) {
+			if (this.log != null) {
+				((GenericXMLWriter) this.log).printTag(name, this.parameters, true, insertNewLine, closeTag);
+			}
+			this.parameters.clear();
+		}
+
+		public void setEmacs() {
+			this.tagBits |= Logger.EMACS;
+		}
+		public void setLog(String logFileName) {
+			final Date date = new Date();
+			final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault());
+			try {
+				int index = logFileName.lastIndexOf('.');
+				if (index != -1) {
+					if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
+						this.log = new GenericXMLWriter(new OutputStreamWriter(new FileOutputStream(logFileName, false), Util.UTF_8), Util.LINE_SEPARATOR, true);
+						this.tagBits |= Logger.XML;
+						// insert time stamp as comment
+						this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$
+						this.log.println(Logger.XML_DTD_DECLARATION);
+						this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
+						this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
+						this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
+						printTag(Logger.COMPILER, this.parameters, true, false);
+					} else {
+						this.log = new PrintWriter(new FileOutputStream(logFileName, false));
+						this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
+					}
+				} else {
+					this.log = new PrintWriter(new FileOutputStream(logFileName, false));
+					this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
+				}
+			} catch (FileNotFoundException e) {
+				throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLog", logFileName)); //$NON-NLS-1$
+			} catch (UnsupportedEncodingException e) {
+				throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLogInvalidEncoding", logFileName)); //$NON-NLS-1$
+			}
+		}
+		private void startLoggingExtraProblems(int count) {
+			this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(count));
+			printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false);
+		}
+
+		/**
+		 * Used to start logging problems.
+		 * Only use in xml mode.
+		 */
+		private void startLoggingProblems(int errors, int warnings) {
+			this.parameters.put(Logger.NUMBER_OF_PROBLEMS, new Integer(errors + warnings));
+			this.parameters.put(Logger.NUMBER_OF_ERRORS, new Integer(errors));
+			this.parameters.put(Logger.NUMBER_OF_WARNINGS, new Integer(warnings));
+			printTag(Logger.PROBLEMS, this.parameters, true, false);
+		}
+
+		public void startLoggingSource(CompilationResult compilationResult) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				ICompilationUnit compilationUnit = compilationResult.compilationUnit;
+				if (compilationUnit != null) {
+    				char[] fileName = compilationUnit.getFileName();
+    				File f = new File(new String(fileName));
+    				if (fileName != null) {
+    					this.parameters.put(Logger.PATH, f.getAbsolutePath());
+    				}
+    				char[][] packageName = compilationResult.packageName;
+    				if (packageName != null) {
+    					this.parameters.put(
+    							Logger.PACKAGE,
+    							new String(CharOperation.concatWith(packageName, File.separatorChar)));
+    				}
+    				CompilationUnit unit = (CompilationUnit) compilationUnit;
+    				String destinationPath = unit.destinationPath;
+					if (destinationPath == null) {
+						destinationPath = this.main.destinationPath;
+					}
+					if (destinationPath != null && destinationPath != NONE) {
+						if (File.separatorChar == '/') {
+							this.parameters.put(Logger.OUTPUT, destinationPath);
+						} else {
+							this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
+						}
+					}
+				}
+				printTag(Logger.SOURCE, this.parameters, true, false);
+			}
+		}
+
+		public void startLoggingSources() {
+			if ((this.tagBits & Logger.XML) != 0) {
+				printTag(Logger.SOURCES, null, true, false);
+			}
+		}
+
+		public void startLoggingTasks(int tasks) {
+			if ((this.tagBits & Logger.XML) != 0) {
+				this.parameters.put(Logger.NUMBER_OF_TASKS, new Integer(tasks));
+				printTag(Logger.TASKS, this.parameters, true, false);
+			}
+		}
+	}
+
+	/**
+	 * Resource bundle factory to share bundles for the same locale
+	 */
+	public static class ResourceBundleFactory {
+		private static HashMap Cache = new HashMap();
+		public static synchronized ResourceBundle getBundle(Locale locale) {
+			ResourceBundle bundle = (ResourceBundle) Cache.get(locale);
+			if (bundle == null) {
+				bundle = ResourceBundle.getBundle(Main.bundleName, locale);
+				Cache.put(locale, bundle);
+			}
+			return bundle;
+		}
+	}
+	// javadoc analysis tuning
+	boolean enableJavadocOn;
+
+	boolean warnJavadocOn;
+	boolean warnAllJavadocOn;
+
+	public Compiler batchCompiler;
+	/* Bundle containing messages */
+	public ResourceBundle bundle;
+	protected FileSystem.Classpath[] checkedClasspaths;
+
+	public Locale compilerLocale;
+	public CompilerOptions compilerOptions; // read-only
+	public CompilationProgress progress;
+	public String destinationPath;
+	public String[] destinationPaths;
+	// destination path for compilation units that get no more specific
+	// one (through directory arguments or various classpath options);
+	// coding is:
+	// == null: unspecified, write class files close to their respective
+	//          source files;
+	// == Main.NONE: absorbent element, do not output class files;
+	// else: use as the path of the directory into which class files must
+	//       be written.
+	private boolean didSpecifySource;
+	private boolean didSpecifyTarget;
+	public String[] encodings;
+	public int exportedClassFilesCounter;
+	public String[] filenames;
+	public String[] classNames;
+	// overrides of destinationPath on a directory argument basis
+	public int globalErrorsCount;
+	public int globalProblemsCount;
+	public int globalTasksCount;
+	public int globalWarningsCount;
+
+	private File javaHomeCache;
+
+	private boolean javaHomeChecked = false;
+	public long lineCount0;
+
+	public String log;
+
+	public Logger logger;
+	public int maxProblems;
+	public Map options;
+	public char[][] ignoreOptionalProblemsFromFolders;
+	protected PrintWriter out;
+	public boolean proceed = true;
+	public boolean proceedOnError = false;
+	public boolean produceRefInfo = false;
+	public int currentRepetition, maxRepetition;
+	public boolean showProgress = false;
+	public long startTime;
+	public ArrayList pendingErrors;
+	public boolean systemExitWhenFinished = true;
+
+	public static final int TIMING_DISABLED = 0;
+	public static final int TIMING_ENABLED = 1;
+	public static final int TIMING_DETAILED = 2;
+
+	public int timing = TIMING_DISABLED;
+	public CompilerStats[] compilerStats;
+	public boolean verbose = false;
+	private String[] expandedCommandLine;
+
+	private PrintWriter err;
+
+	protected ArrayList extraProblems;
+	public final static String bundleName = "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$
+	// two uses: recognize 'none' in options; code the singleton none
+	// for the '-d none' option (wherever it may be found)
+	public static final int DEFAULT_SIZE_CLASSPATH = 4;
+
+	public static final String NONE = "none"; //$NON-NLS-1$
+
+/**
+ * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
+ * 						  e.g. BatchCompiler.compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err), null);
+ */
+public static boolean compile(String commandLine) {
+	return new Main(new PrintWriter(System.out), new PrintWriter(System.err), false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
+}
+
+/**
+ * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
+ *                       e.g. BatchCompiler.compile(commandLine, outWriter, errWriter, null);
+ */
+public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter) {
+	return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
+}
+
+/*
+ * Internal API for public API BatchCompiler#compile(String[], PrintWriter, PrintWriter, CompilationProgress)
+ */
+public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
+	return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, progress).compile(commandLineArguments);
+}
+public static File[][] getLibrariesFiles(File[] files) {
+	FilenameFilter filter = new FilenameFilter() {
+		public boolean accept(File dir, String name) {
+			return Util.isPotentialZipArchive(name);
+		}
+	};
+	final int filesLength = files.length;
+	File[][] result = new File[filesLength][];
+	for (int i = 0; i < filesLength; i++) {
+		File currentFile = files[i];
+		if (currentFile.exists() && currentFile.isDirectory()) {
+			result[i] = currentFile.listFiles(filter);
+		}
+	}
+	return result;
+}
+
+public static void main(String[] argv) {
+	new Main(new PrintWriter(System.out), new PrintWriter(System.err), true/*systemExit*/, null/*options*/, null/*progress*/).compile(argv);
+}
+
+public static String[] tokenize(String commandLine) {
+
+	int count = 0;
+	String[] arguments = new String[10];
+	StringTokenizer tokenizer = new StringTokenizer(commandLine, " \"", true); //$NON-NLS-1$
+	String token = Util.EMPTY_STRING;
+	boolean insideQuotes = false;
+	boolean startNewToken = true;
+
+	// take care to quotes on the command line
+	// 'xxx "aaa bbb";ccc yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
+	// 'xxx "aaa bbb;ccc" yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
+	// 'xxx "aaa bbb";"ccc" yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
+	// 'xxx/"aaa bbb";"ccc" yyy' --->  {"xxx/aaa bbb;ccc", "yyy" }
+	while (tokenizer.hasMoreTokens()) {
+		token = tokenizer.nextToken();
+
+		if (token.equals(" ")) { //$NON-NLS-1$
+			if (insideQuotes) {
+				arguments[count - 1] += token;
+				startNewToken = false;
+			} else {
+				startNewToken = true;
+			}
+		} else if (token.equals("\"")) { //$NON-NLS-1$
+			if (!insideQuotes && startNewToken) {
+				if (count == arguments.length)
+					System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
+				arguments[count++] = Util.EMPTY_STRING;
+			}
+			insideQuotes = !insideQuotes;
+			startNewToken = false;
+		} else {
+			if (insideQuotes) {
+				arguments[count - 1] += token;
+			} else {
+				if (token.length() > 0 && !startNewToken) {
+					arguments[count - 1] += token;
+				} else {
+					if (count == arguments.length)
+						System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
+					String trimmedToken = token.trim();
+					if (trimmedToken.length() != 0) {
+						arguments[count++] = trimmedToken;
+					}
+				}
+			}
+			startNewToken = false;
+		}
+	}
+	System.arraycopy(arguments, 0, arguments = new String[count], 0, count);
+	return arguments;
+}
+
+/**
+ * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ *                       e.g. Main(outWriter, errWriter, systemExitWhenFinished, null, null)
+ */
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) {
+	this(outWriter, errWriter, systemExitWhenFinished, null /* options */, null /* progress */);
+}
+
+/**
+ * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ *                       e.g. Main(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null)
+ */
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions) {
+	this(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null /* progress */);
+}
+
+public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map customDefaultOptions, CompilationProgress compilationProgress) {
+	this.initialize(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, compilationProgress);
+	this.relocalize();
+}
+
+public void addExtraProblems(CategorizedProblem problem) {
+	if (this.extraProblems == null) {
+		this.extraProblems = new ArrayList();
+	}
+	this.extraProblems.add(problem);
+}
+protected void addNewEntry(ArrayList paths, String currentClasspathName,
+		ArrayList currentRuleSpecs, String customEncoding,
+		String destPath, boolean isSourceOnly,
+		boolean rejectDestinationPathOnJars) {
+
+	int rulesSpecsSize = currentRuleSpecs.size();
+	AccessRuleSet accessRuleSet = null;
+	if (rulesSpecsSize != 0) {
+		AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
+		boolean rulesOK = true;
+		Iterator i = currentRuleSpecs.iterator();
+		int j = 0;
+		while (i.hasNext()) {
+			String ruleSpec = (String) i.next();
+			char key = ruleSpec.charAt(0);
+			String pattern = ruleSpec.substring(1);
+			if (pattern.length() > 0) {
+				switch (key) {
+					case '+':
+						accessRules[j++] = new AccessRule(pattern
+								.toCharArray(), 0);
+						break;
+					case '~':
+						accessRules[j++] = new AccessRule(pattern
+								.toCharArray(),
+								IProblem.DiscouragedReference);
+						break;
+					case '-':
+						accessRules[j++] = new AccessRule(pattern
+								.toCharArray(),
+								IProblem.ForbiddenReference);
+						break;
+					case '?':
+						accessRules[j++] = new AccessRule(pattern
+								.toCharArray(),
+								IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
+						break;
+					default:
+						rulesOK = false;
+				}
+			} else {
+				rulesOK = false;
+			}
+		}
+		if (rulesOK) {
+    		accessRuleSet = new AccessRuleSet(accessRules, AccessRestriction.COMMAND_LINE, currentClasspathName);
+		} else {
+			if (currentClasspathName.length() != 0) {
+				// we go on anyway
+				addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
+			}
+			return;
+		}
+	}
+	if (NONE.equals(destPath)) {
+		destPath = NONE; // keep == comparison valid
+	}
+	if (rejectDestinationPathOnJars && destPath != null &&
+			Util.isPotentialZipArchive(currentClasspathName)) {
+		throw new IllegalArgumentException(
+			this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
+						currentClasspathName));
+	}
+	FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
+			currentClasspathName,
+			customEncoding,
+			isSourceOnly,
+			accessRuleSet,
+			destPath);
+	if (currentClasspath != null) {
+		paths.add(currentClasspath);
+	} else if (currentClasspathName.length() != 0) {
+		// we go on anyway
+		addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
+	}
+}
+void addPendingErrors(String message) {
+	if (this.pendingErrors == null) {
+		this.pendingErrors = new ArrayList();
+	}
+	this.pendingErrors.add(message);
+}
+/*
+ * Lookup the message with the given ID in this catalog
+ */
+public String bind(String id) {
+	return bind(id, (String[]) null);
+}
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string.
+ */
+public String bind(String id, String binding) {
+	return bind(id, new String[] { binding });
+}
+
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given strings.
+ */
+public String bind(String id, String binding1, String binding2) {
+	return bind(id, new String[] { binding1, binding2 });
+}
+
+/*
+ * Lookup the message with the given ID in this catalog and bind its
+ * substitution locations with the given string values.
+ */
+public String bind(String id, String[] arguments) {
+	if (id == null)
+		return "No message available"; //$NON-NLS-1$
+	String message = null;
+	try {
+		message = this.bundle.getString(id);
+	} catch (MissingResourceException e) {
+		// If we got an exception looking for the message, fail gracefully by just returning
+		// the id we were looking for.  In most cases this is semi-informative so is not too bad.
+		return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
+	}
+	return MessageFormat.format(message, arguments);
+}
+/**
+ * Return true if and only if the running VM supports the given minimal version.
+ *
+ * <p>This only checks the major version, since the minor version is always 0 (at least for the useful cases).</p>
+ * <p>The given minimalSupportedVersion is one of the constants:</p>
+ * <ul>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6</code></li>
+ * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_7</code></li>
+ * </ul>
+ * @param minimalSupportedVersion the given minimal version
+ * @return true if and only if the running VM supports the given minimal version, false otherwise
+ */
+private boolean checkVMVersion(long minimalSupportedVersion) {
+	// the format of this property is supposed to be xx.x where x are digits.
+	String classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$
+	if (classFileVersion == null) {
+		// by default we don't support a class file version we cannot recognize
+		return false;
+	}
+	int index = classFileVersion.indexOf('.');
+	if (index == -1) {
+		// by default we don't support a class file version we cannot recognize
+		return false;
+	}
+	int majorVersion;
+	try {
+		majorVersion = Integer.parseInt(classFileVersion.substring(0, index));
+	} catch (NumberFormatException e) {
+		// by default we don't support a class file version we cannot recognize
+		return false;
+	}
+	switch(majorVersion) {
+		case ClassFileConstants.MAJOR_VERSION_1_1 : // 1.0 and 1.1
+			return ClassFileConstants.JDK1_1 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_2 : // 1.2
+			return ClassFileConstants.JDK1_2 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_3 : // 1.3
+			return ClassFileConstants.JDK1_3 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_4 : // 1.4
+			return ClassFileConstants.JDK1_4 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_5 : // 1.5
+			return ClassFileConstants.JDK1_5 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_6 : // 1.6
+			return ClassFileConstants.JDK1_6 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_7 : // 1.7
+			return ClassFileConstants.JDK1_7 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_1_8: // 1.8
+			return ClassFileConstants.JDK1_8 >= minimalSupportedVersion;
+	}
+	// unknown version
+	return false;
+}
+/*
+ *  Low-level API performing the actual compilation
+ */
+public boolean compile(String[] argv) {
+
+	// decode command line arguments
+	try {
+		configure(argv);
+		if (this.progress != null)
+			this.progress.begin(this.filenames == null ? 0 : this.filenames.length * this.maxRepetition);
+		if (this.proceed) {
+//				if (this.verbose) {
+//					System.out.println(new CompilerOptions(this.options));
+//				}
+			if (this.showProgress) this.logger.compiling();
+			for (this.currentRepetition = 0; this.currentRepetition < this.maxRepetition; this.currentRepetition++) {
+				this.globalProblemsCount = 0;
+				this.globalErrorsCount = 0;
+				this.globalWarningsCount = 0;
+				this.globalTasksCount = 0;
+				this.exportedClassFilesCounter = 0;
+
+				if (this.maxRepetition > 1) {
+					this.logger.flush();
+					this.logger.logRepetition(this.currentRepetition, this.maxRepetition);
+				}
+				// request compilation
+				performCompilation();
+			}
+			if (this.compilerStats != null) {
+				this.logger.logAverage();
+			}
+			if (this.showProgress) this.logger.printNewLine();
+		}
+		if (this.systemExitWhenFinished) {
+			this.logger.flush();
+			this.logger.close();
+			System.exit(this.globalErrorsCount > 0 ? -1 : 0);
+		}
+	} catch (IllegalArgumentException e) {
+		this.logger.logException(e);
+		if (this.systemExitWhenFinished) {
+			this.logger.flush();
+			this.logger.close();
+			System.exit(-1);
+		}
+		return false;
+	} catch (RuntimeException e) { // internal compiler failure
+		this.logger.logException(e);
+		if (this.systemExitWhenFinished) {
+			this.logger.flush();
+			this.logger.close();
+			System.exit(-1);
+		}
+		return false;
+	} finally {
+		this.logger.flush();
+		this.logger.close();
+		if (this.progress != null)
+			this.progress.done();
+	}
+	if (this.globalErrorsCount == 0 && (this.progress == null || !this.progress.isCanceled()))
+		return true;
+	return false;
+}
+
+/*
+Decode the command line arguments
+ */
+public void configure(String[] argv) {
+
+	if ((argv == null) || (argv.length == 0)) {
+		printUsage();
+		return;
+	}
+
+	final int INSIDE_CLASSPATH_start = 1;
+	final int INSIDE_DESTINATION_PATH = 3;
+	final int INSIDE_TARGET = 4;
+	final int INSIDE_LOG = 5;
+	final int INSIDE_REPETITION = 6;
+	final int INSIDE_SOURCE = 7;
+	final int INSIDE_DEFAULT_ENCODING = 8;
+	final int INSIDE_BOOTCLASSPATH_start = 9;
+	final int INSIDE_MAX_PROBLEMS = 11;
+	final int INSIDE_EXT_DIRS = 12;
+	final int INSIDE_SOURCE_PATH_start = 13;
+	final int INSIDE_ENDORSED_DIRS = 15;
+	final int INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH = 16;
+	final int INSIDE_PROCESSOR_PATH_start = 17;
+	final int INSIDE_PROCESSOR_start = 18;
+	final int INSIDE_S_start = 19;
+	final int INSIDE_CLASS_NAMES = 20;
+	final int INSIDE_WARNINGS_PROPERTIES = 21;
+
+	final int DEFAULT = 0;
+	ArrayList bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+	String sourcepathClasspathArg = null;
+	ArrayList sourcepathClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+	ArrayList classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+	ArrayList extdirsClasspaths = null;
+	ArrayList endorsedDirClasspaths = null;
+
+	int index = -1;
+	int filesCount = 0;
+	int classCount = 0;
+	int argCount = argv.length;
+	int mode = DEFAULT;
+	this.maxRepetition = 0;
+	boolean printUsageRequired = false;
+	String usageSection = null;
+	boolean printVersionRequired = false;
+
+	boolean didSpecifyDeprecation = false;
+	boolean didSpecifyCompliance = false;
+	boolean didSpecifyDisabledAnnotationProcessing = false;
+
+	String customEncoding = null;
+	String customDestinationPath = null;
+	String currentSourceDirectory = null;
+	String currentArg = Util.EMPTY_STRING;
+	
+	Set specifiedEncodings = null;
+
+	// expand the command line if necessary
+	boolean needExpansion = false;
+	loop: for (int i = 0; i < argCount; i++) {
+			if (argv[i].startsWith("@")) { //$NON-NLS-1$
+				needExpansion = true;
+				break loop;
+			}
+	}
+
+	String[] newCommandLineArgs = null;
+	if (needExpansion) {
+		newCommandLineArgs = new String[argCount];
+		index = 0;
+		for (int i = 0; i < argCount; i++) {
+			String[] newArgs = null;
+			String arg = argv[i].trim();
+			if (arg.startsWith("@")) { //$NON-NLS-1$
+				try {
+					LineNumberReader reader = new LineNumberReader(new StringReader(new String(Util.getFileCharContent(new File(arg.substring(1)), null))));
+					StringBuffer buffer = new StringBuffer();
+					String line;
+					while((line = reader.readLine()) != null) {
+						line = line.trim();
+						if (!line.startsWith("#")) { //$NON-NLS-1$
+							buffer.append(line).append(" "); //$NON-NLS-1$
+						}
+					}
+					newArgs = tokenize(buffer.toString());
+				} catch(IOException e) {
+					throw new IllegalArgumentException(
+						this.bind("configure.invalidexpansionargumentname", arg)); //$NON-NLS-1$
+				}
+			}
+			if (newArgs != null) {
+				int newCommandLineArgsLength = newCommandLineArgs.length;
+				int newArgsLength = newArgs.length;
+				System.arraycopy(newCommandLineArgs, 0, (newCommandLineArgs = new String[newCommandLineArgsLength + newArgsLength - 1]), 0, index);
+				System.arraycopy(newArgs, 0, newCommandLineArgs, index, newArgsLength);
+				index += newArgsLength;
+			} else {
+				newCommandLineArgs[index++] = arg;
+			}
+		}
+		index = -1;
+	} else {
+		newCommandLineArgs = argv;
+		for (int i = 0; i < argCount; i++) {
+			newCommandLineArgs[i] = newCommandLineArgs[i].trim();
+		}
+	}
+	argCount = newCommandLineArgs.length;
+	this.expandedCommandLine = newCommandLineArgs;
+	while (++index < argCount) {
+
+		if (customEncoding != null) {
+			throw new IllegalArgumentException(
+				this.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$
+		}
+
+		currentArg = newCommandLineArgs[index];
+
+		switch(mode) {
+			case DEFAULT :
+				if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$
+					switch (currentArg.length()) {
+						case 7:
+							disableAll(ProblemSeverities.Warning);
+							break;
+						case 8:
+							throw new IllegalArgumentException(this.bind(
+									"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
+						default:
+							int foldersStart = currentArg.indexOf('[') + 1;
+							int foldersEnd = currentArg.lastIndexOf(']');
+							if (foldersStart <= 8 || foldersEnd == -1 || foldersStart > foldersEnd
+									|| foldersEnd < currentArg.length() - 1) {
+								throw new IllegalArgumentException(this.bind(
+										"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
+							}
+							String folders = currentArg.substring(foldersStart, foldersEnd);
+							if (folders.length() > 0) {
+								char[][] currentFolders = decodeIgnoreOptionalProblemsFromFolders(folders);
+								if (this.ignoreOptionalProblemsFromFolders != null) {
+									int length = this.ignoreOptionalProblemsFromFolders.length + currentFolders.length;
+									char[][] tempFolders = new char[length][];
+									System.arraycopy(this.ignoreOptionalProblemsFromFolders, 0, tempFolders, 0, this.ignoreOptionalProblemsFromFolders.length);
+									System.arraycopy(currentFolders, 0, tempFolders, this.ignoreOptionalProblemsFromFolders.length, currentFolders.length);
+									this.ignoreOptionalProblemsFromFolders = tempFolders;
+								} else {
+									this.ignoreOptionalProblemsFromFolders = currentFolders;
+								}
+							} else {
+								throw new IllegalArgumentException(this.bind(
+										"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
+							}
+					}
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.startsWith("[")) { //$NON-NLS-1$
+					throw new IllegalArgumentException(
+						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+									currentArg));
+				}
+
+				if (currentArg.endsWith("]")) { //$NON-NLS-1$
+					// look for encoding specification
+					int encodingStart = currentArg.indexOf('[') + 1;
+					if (encodingStart <= 1) {
+						throw new IllegalArgumentException(
+								this.bind("configure.unexpectedBracket", currentArg)); //$NON-NLS-1$
+					}
+					int encodingEnd = currentArg.length() - 1;
+					if (encodingStart >= 1) {
+						if (encodingStart < encodingEnd) {
+							customEncoding = currentArg.substring(encodingStart, encodingEnd);
+							try { // ensure encoding is supported
+								new InputStreamReader(new ByteArrayInputStream(new byte[0]), customEncoding);
+							} catch (UnsupportedEncodingException e) {
+								throw new IllegalArgumentException(
+									this.bind("configure.unsupportedEncoding", customEncoding)); //$NON-NLS-1$
+							}
+						}
+						currentArg = currentArg.substring(0, encodingStart - 1);
+					}
+				}
+
+				if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) {
+					if (this.filenames == null) {
+						this.filenames = new String[argCount - index];
+						this.encodings = new String[argCount - index];
+						this.destinationPaths = new String[argCount - index];
+					} else if (filesCount == this.filenames.length) {
+						int length = this.filenames.length;
+						System.arraycopy(
+							this.filenames,
+							0,
+							(this.filenames = new String[length + argCount - index]),
+							0,
+							length);
+						System.arraycopy(
+							this.encodings,
+							0,
+							(this.encodings = new String[length + argCount - index]),
+							0,
+							length);
+						System.arraycopy(
+							this.destinationPaths,
+							0,
+							(this.destinationPaths = new String[length + argCount - index]),
+							0,
+							length);
+					}
+					this.filenames[filesCount] = currentArg;
+					this.encodings[filesCount++] = customEncoding;
+					// destination path cannot be specified upon an individual file
+					customEncoding = null;
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-log")) { //$NON-NLS-1$
+					if (this.log != null)
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$
+					mode = INSIDE_LOG;
+					continue;
+				}
+				if (currentArg.equals("-repeat")) { //$NON-NLS-1$
+					if (this.maxRepetition > 0)
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$
+					mode = INSIDE_REPETITION;
+					continue;
+				}
+				if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$
+					if (this.maxProblems > 0)
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$
+					mode = INSIDE_MAX_PROBLEMS;
+					continue;
+				}
+				if (currentArg.equals("-source")) { //$NON-NLS-1$
+					mode = INSIDE_SOURCE;
+					continue;
+				}
+				if (currentArg.equals("-encoding")) { //$NON-NLS-1$
+					mode = INSIDE_DEFAULT_ENCODING;
+					continue;
+				}
+				if (currentArg.equals("-1.3")) { //$NON-NLS-1$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-1.4")) { //$NON-NLS-1$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-1.6") || currentArg.equals("-6") || currentArg.equals("-6.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-1.7") || currentArg.equals("-7") || currentArg.equals("-7.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-1.8") || currentArg.equals("-8") || currentArg.equals("-8.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-d")) { //$NON-NLS-1$
+					if (this.destinationPath != null) {
+						StringBuffer errorMessage = new StringBuffer();
+						errorMessage.append(currentArg);
+						if ((index + 1) < argCount) {
+							errorMessage.append(' ');
+							errorMessage.append(newCommandLineArgs[index + 1]);
+						}
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$
+					}
+					mode = INSIDE_DESTINATION_PATH;
+					continue;
+				}
+				if (currentArg.equals("-classpath") //$NON-NLS-1$
+					|| currentArg.equals("-cp")) { //$NON-NLS-1$
+					mode = INSIDE_CLASSPATH_start;
+					continue;
+				}
+				if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$
+					if (bootclasspaths.size() > 0) {
+						StringBuffer errorMessage = new StringBuffer();
+						errorMessage.append(currentArg);
+						if ((index + 1) < argCount) {
+							errorMessage.append(' ');
+							errorMessage.append(newCommandLineArgs[index + 1]);
+						}
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateBootClasspath", errorMessage.toString())); //$NON-NLS-1$
+					}
+					mode = INSIDE_BOOTCLASSPATH_start;
+					continue;
+				}
+				if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
+					if (sourcepathClasspathArg != null) {
+						StringBuffer errorMessage = new StringBuffer();
+						errorMessage.append(currentArg);
+						if ((index + 1) < argCount) {
+							errorMessage.append(' ');
+							errorMessage.append(newCommandLineArgs[index + 1]);
+						}
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateSourcepath", errorMessage.toString())); //$NON-NLS-1$
+					}
+					mode = INSIDE_SOURCE_PATH_start;
+					continue;
+				}
+				if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
+					if (extdirsClasspaths != null) {
+						StringBuffer errorMessage = new StringBuffer();
+						errorMessage.append(currentArg);
+						if ((index + 1) < argCount) {
+							errorMessage.append(' ');
+							errorMessage.append(newCommandLineArgs[index + 1]);
+						}
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateExtDirs", errorMessage.toString())); //$NON-NLS-1$
+					}
+					mode = INSIDE_EXT_DIRS;
+					continue;
+				}
+				if (currentArg.equals("-endorseddirs")) { //$NON-NLS-1$
+					if (endorsedDirClasspaths != null) {
+						StringBuffer errorMessage = new StringBuffer();
+						errorMessage.append(currentArg);
+						if ((index + 1) < argCount) {
+							errorMessage.append(' ');
+							errorMessage.append(newCommandLineArgs[index + 1]);
+						}
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateEndorsedDirs", errorMessage.toString())); //$NON-NLS-1$
+					}
+					mode = INSIDE_ENDORSED_DIRS;
+					continue;
+				}
+				if (currentArg.equals("-progress")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					this.showProgress = true;
+					continue;
+				}
+				if (currentArg.startsWith("-proceedOnError")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					int length = currentArg.length();
+					if (length > 15) {
+						if (currentArg.equals("-proceedOnError:Fatal")) { //$NON-NLS-1$
+							this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.ENABLED);
+						} else {
+							throw new IllegalArgumentException(
+									this.bind("configure.invalidWarningConfiguration", currentArg)); //$NON-NLS-1$
+						}
+					} else {
+						this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.DISABLED);
+					}
+					this.proceedOnError = true;
+					continue;
+				}
+				if (currentArg.equals("-time")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					this.timing = TIMING_ENABLED;
+					continue;
+				}
+				if (currentArg.equals("-time:detail")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					this.timing = TIMING_ENABLED|TIMING_DETAILED;
+					continue;
+				}
+				if (currentArg.equals("-version") //$NON-NLS-1$
+						|| currentArg.equals("-v")) { //$NON-NLS-1$
+					this.logger.logVersion(true);
+					this.proceed = false;
+					return;
+				}
+				if (currentArg.equals("-showversion")) { //$NON-NLS-1$
+					printVersionRequired = true;
+					mode = DEFAULT;
+					continue;
+				}
+				if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$
+					didSpecifyDeprecation = true;
+					this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$
+					printUsageRequired = true;
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-help:warn") || //$NON-NLS-1$
+						currentArg.equals("-?:warn")) { //$NON-NLS-1$
+					printUsageRequired = true;
+					usageSection = "misc.usage.warn"; //$NON-NLS-1$
+					continue;
+				}
+				if (currentArg.equals("-noExit")) { //$NON-NLS-1$
+					this.systemExitWhenFinished = false;
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-verbose")) { //$NON-NLS-1$
+					this.verbose = true;
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$
+					this.produceRefInfo = true;
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					this.options.put(
+							CompilerOptions.OPTION_InlineJsr,
+							CompilerOptions.ENABLED);
+					continue;
+				}
+				if (currentArg.startsWith("-g")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					String debugOption = currentArg;
+					int length = currentArg.length();
+					if (length == 2) {
+						this.options.put(
+							CompilerOptions.OPTION_LocalVariableAttribute,
+							CompilerOptions.GENERATE);
+						this.options.put(
+							CompilerOptions.OPTION_LineNumberAttribute,
+							CompilerOptions.GENERATE);
+						this.options.put(
+							CompilerOptions.OPTION_SourceFileAttribute,
+							CompilerOptions.GENERATE);
+						continue;
+					}
+					if (length > 3) {
+						this.options.put(
+							CompilerOptions.OPTION_LocalVariableAttribute,
+							CompilerOptions.DO_NOT_GENERATE);
+						this.options.put(
+							CompilerOptions.OPTION_LineNumberAttribute,
+							CompilerOptions.DO_NOT_GENERATE);
+						this.options.put(
+							CompilerOptions.OPTION_SourceFileAttribute,
+							CompilerOptions.DO_NOT_GENERATE);
+						if (length == 7 && debugOption.equals("-g:" + NONE)) //$NON-NLS-1$
+							continue;
+						StringTokenizer tokenizer =
+							new StringTokenizer(debugOption.substring(3, debugOption.length()), ","); //$NON-NLS-1$
+						while (tokenizer.hasMoreTokens()) {
+							String token = tokenizer.nextToken();
+							if (token.equals("vars")) { //$NON-NLS-1$
+								this.options.put(
+									CompilerOptions.OPTION_LocalVariableAttribute,
+									CompilerOptions.GENERATE);
+							} else if (token.equals("lines")) { //$NON-NLS-1$
+								this.options.put(
+									CompilerOptions.OPTION_LineNumberAttribute,
+									CompilerOptions.GENERATE);
+							} else if (token.equals("source")) { //$NON-NLS-1$
+								this.options.put(
+									CompilerOptions.OPTION_SourceFileAttribute,
+									CompilerOptions.GENERATE);
+							} else {
+								throw new IllegalArgumentException(
+									this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
+							}
+						}
+						continue;
+					}
+					throw new IllegalArgumentException(
+						this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
+				}
+				if (currentArg.startsWith("-warn")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					String warningOption = currentArg;
+					int length = currentArg.length();
+					if (length == 10 && warningOption.equals("-warn:" + NONE)) { //$NON-NLS-1$
+						disableAll(ProblemSeverities.Warning);
+						continue;
+					}
+					if (length <= 6) {
+						throw new IllegalArgumentException(
+							this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$
+					}
+					int warnTokenStart;
+					boolean isEnabling;
+					switch (warningOption.charAt(6)) {
+						case '+' :
+							warnTokenStart = 7;
+							isEnabling = true;
+							break;
+						case '-' :
+							warnTokenStart = 7;
+							isEnabling = false; // specified warnings are disabled
+							break;
+						default:
+							disableAll(ProblemSeverities.Warning);
+							warnTokenStart = 6;
+							isEnabling = true;
+					}
+
+					StringTokenizer tokenizer =
+						new StringTokenizer(warningOption.substring(warnTokenStart, warningOption.length()), ","); //$NON-NLS-1$
+					int tokenCounter = 0;
+
+					if (didSpecifyDeprecation) {  // deprecation could have also been set through -deprecation option
+						this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
+					}
+
+					while (tokenizer.hasMoreTokens()) {
+						String token = tokenizer.nextToken();
+						tokenCounter++;
+						switch(token.charAt(0)) {
+							case '+' :
+								isEnabling = true;
+								token = token.substring(1);
+								break;
+							case '-' :
+								isEnabling = false;
+								token = token.substring(1);
+						}
+						handleWarningToken(token, isEnabling);
+					}
+					if (tokenCounter == 0) {
+						throw new IllegalArgumentException(
+							this.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$
+					}
+					continue;
+				}
+				if (currentArg.startsWith("-err")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					String errorOption = currentArg;
+					int length = currentArg.length();
+					if (length <= 5) {
+						throw new IllegalArgumentException(
+							this.bind("configure.invalidErrorConfiguration", errorOption)); //$NON-NLS-1$
+					}
+					int errorTokenStart;
+					boolean isEnabling;
+					switch (errorOption.charAt(5)) {
+						case '+' :
+							errorTokenStart = 6;
+							isEnabling = true;
+							break;
+						case '-' :
+							errorTokenStart = 6;
+							isEnabling = false; // specified errors are disabled
+							break;
+						default:
+							disableAll(ProblemSeverities.Error);
+							errorTokenStart = 5;
+							isEnabling = true;
+					}
+
+					StringTokenizer tokenizer =
+						new StringTokenizer(errorOption.substring(errorTokenStart, errorOption.length()), ","); //$NON-NLS-1$
+					int tokenCounter = 0;
+
+					while (tokenizer.hasMoreTokens()) {
+						String token = tokenizer.nextToken();
+						tokenCounter++;
+						switch(token.charAt(0)) {
+							case '+' :
+								isEnabling = true;
+								token = token.substring(1);
+								break;
+							case '-' :
+								isEnabling = false;
+								token = token.substring(1);
+								break;
+						}
+						handleErrorToken(token, isEnabling);
+					}
+					if (tokenCounter == 0) {
+						throw new IllegalArgumentException(
+							this.bind("configure.invalidErrorOption", currentArg)); //$NON-NLS-1$
+					}
+					continue;
+				}
+				if (currentArg.equals("-target")) { //$NON-NLS-1$
+					mode = INSIDE_TARGET;
+					continue;
+				}
+				if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$
+					this.options.put(
+						CompilerOptions.OPTION_PreserveUnusedLocal,
+						CompilerOptions.PRESERVE);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$
+					mode = DEFAULT;
+					this.enableJavadocOn = true;
+					continue;
+				}
+				if (currentArg.equals("-Xemacs")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					this.logger.setEmacs();
+					continue;
+				}
+				// annotation processing
+				if (currentArg.startsWith("-A")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-processorpath")) { //$NON-NLS-1$
+					mode = INSIDE_PROCESSOR_PATH_start;
+					continue;
+				}
+				if (currentArg.equals("-processor")) { //$NON-NLS-1$
+					mode = INSIDE_PROCESSOR_start;
+					continue;
+				}
+				if (currentArg.equals("-proc:only")) { //$NON-NLS-1$
+					this.options.put(
+						CompilerOptions.OPTION_GenerateClassFiles,
+						CompilerOptions.DISABLED);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-proc:none")) { //$NON-NLS-1$
+					didSpecifyDisabledAnnotationProcessing = true;
+					this.options.put(
+						CompilerOptions.OPTION_Process_Annotations,
+						CompilerOptions.DISABLED);
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-s")) { //$NON-NLS-1$
+					mode = INSIDE_S_start;
+					continue;
+				}
+				if (currentArg.equals("-XprintProcessorInfo") //$NON-NLS-1$
+						|| currentArg.equals("-XprintRounds")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					continue;
+				}
+				// tolerated javac options - quietly filtered out
+				if (currentArg.startsWith("-X")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.startsWith("-J")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-O")) { //$NON-NLS-1$
+					mode = DEFAULT;
+					continue;
+				}
+				if (currentArg.equals("-classNames")) { //$NON-NLS-1$
+					mode = INSIDE_CLASS_NAMES;
+					continue;
+				}
+				if (currentArg.equals("-properties")) { //$NON-NLS-1$
+					mode = INSIDE_WARNINGS_PROPERTIES;
+					continue;
+				}
+				if (currentArg.equals("-missingNullDefault")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_ReportMissingNonNullByDefaultAnnotation, CompilerOptions.WARNING);
+					continue;
+				}
+				break;
+			case INSIDE_TARGET :
+				if (this.didSpecifyTarget) {
+					throw new IllegalArgumentException(
+						this.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$
+				}
+				this.didSpecifyTarget = true;
+				if (currentArg.equals("1.1")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
+				} else if (currentArg.equals("1.2")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+				} else if (currentArg.equals("1.3")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
+				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+				} else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+				} else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+				} else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
+				}
+				else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
+				} else if (currentArg.equals("cldc1.1")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_CLDC1_1);
+					this.options.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.ENABLED);
+				}else {
+					throw new IllegalArgumentException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
+				}
+				mode = DEFAULT;
+				continue;
+			case INSIDE_LOG :
+				this.log = currentArg;
+				mode = DEFAULT;
+				continue;
+			case INSIDE_REPETITION :
+				try {
+					this.maxRepetition = Integer.parseInt(currentArg);
+					if (this.maxRepetition <= 0) {
+						throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
+					}
+				} catch (NumberFormatException e) {
+					throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
+				}
+				mode = DEFAULT;
+				continue;
+			case INSIDE_MAX_PROBLEMS :
+				try {
+					this.maxProblems = Integer.parseInt(currentArg);
+					if (this.maxProblems <= 0) {
+						throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
+					}
+					this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg);
+				} catch (NumberFormatException e) {
+					throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
+				}
+				mode = DEFAULT;
+				continue;
+			case INSIDE_SOURCE :
+				if (this.didSpecifySource) {
+					throw new IllegalArgumentException(
+						this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$
+				}
+				this.didSpecifySource = true;
+				if (currentArg.equals("1.3")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
+				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+				} else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
+				} else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
+				} else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
+				} else {
+					throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
+				}
+				mode = DEFAULT;
+				continue;
+			case INSIDE_DEFAULT_ENCODING :
+				if (specifiedEncodings != null) {
+					// check already defined encoding
+					if (!specifiedEncodings.contains(currentArg)) {
+						if (specifiedEncodings.size() > 1) {
+							this.logger.logWarning(
+									this.bind("configure.differentencodings", //$NON-NLS-1$
+									currentArg,
+									getAllEncodings(specifiedEncodings)));
+						} else {
+							this.logger.logWarning(
+									this.bind("configure.differentencoding", //$NON-NLS-1$
+									currentArg,
+									getAllEncodings(specifiedEncodings)));
+						}
+					}
+				} else {
+					specifiedEncodings = new HashSet();
+				}
+				try { // ensure encoding is supported
+					new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg);
+				} catch (UnsupportedEncodingException e) {
+					throw new IllegalArgumentException(
+						this.bind("configure.unsupportedEncoding", currentArg)); //$NON-NLS-1$
+				}
+				specifiedEncodings.add(currentArg);
+				this.options.put(CompilerOptions.OPTION_Encoding, currentArg);
+				mode = DEFAULT;
+				continue;
+			case INSIDE_DESTINATION_PATH :
+				setDestinationPath(currentArg.equals(NONE) ? NONE : currentArg);
+				mode = DEFAULT;
+				continue;
+			case INSIDE_CLASSPATH_start:
+				mode = DEFAULT;
+				index += processPaths(newCommandLineArgs, index, currentArg, classpaths);
+				continue;
+			case INSIDE_BOOTCLASSPATH_start:
+				mode = DEFAULT;
+				index += processPaths(newCommandLineArgs, index, currentArg, bootclasspaths);
+				continue;
+			case INSIDE_SOURCE_PATH_start:
+				mode = DEFAULT;
+				String[] sourcePaths = new String[1];
+				index += processPaths(newCommandLineArgs, index, currentArg, sourcePaths);
+				sourcepathClasspathArg = sourcePaths[0];
+				continue;
+			case INSIDE_EXT_DIRS:
+				if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
+					throw new IllegalArgumentException(
+						this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
+							"-extdir")); //$NON-NLS-1$
+				}
+				StringTokenizer tokenizer = new StringTokenizer(currentArg,	File.pathSeparator, false);
+				extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+				while (tokenizer.hasMoreTokens())
+					extdirsClasspaths.add(tokenizer.nextToken());
+				mode = DEFAULT;
+				continue;
+			case INSIDE_ENDORSED_DIRS:
+				if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
+					throw new IllegalArgumentException(
+						this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
+							"-endorseddirs")); //$NON-NLS-1$
+				}				tokenizer = new StringTokenizer(currentArg,	File.pathSeparator, false);
+				endorsedDirClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+				while (tokenizer.hasMoreTokens())
+					endorsedDirClasspaths.add(tokenizer.nextToken());
+				mode = DEFAULT;
+				continue;
+			case INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH:
+				if (currentArg.endsWith("]")) { //$NON-NLS-1$
+					customDestinationPath = currentArg.substring(0,
+						currentArg.length() - 1);
+				} else {
+					throw new IllegalArgumentException(
+						this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+							"[-d " + currentArg)); //$NON-NLS-1$
+				}
+				break;
+			case INSIDE_PROCESSOR_PATH_start :
+				// nothing to do here. This is consumed again by the AnnotationProcessorManager
+				mode = DEFAULT;
+				continue;
+			case INSIDE_PROCESSOR_start :
+				// nothing to do here. This is consumed again by the AnnotationProcessorManager
+				mode = DEFAULT;
+				continue;
+			case INSIDE_S_start :
+				// nothing to do here. This is consumed again by the AnnotationProcessorManager
+				mode = DEFAULT;
+				continue;
+			case INSIDE_CLASS_NAMES :
+				tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$
+				if (this.classNames == null) {
+					this.classNames = new String[DEFAULT_SIZE_CLASSPATH];
+				}
+				while (tokenizer.hasMoreTokens()) {
+					if (this.classNames.length == classCount) {
+						// resize
+						System.arraycopy(
+							this.classNames,
+							0,
+							(this.classNames = new String[classCount * 2]),
+							0,
+							classCount);
+					}
+					this.classNames[classCount++] = tokenizer.nextToken();
+				}
+				mode = DEFAULT;
+				continue;
+			case INSIDE_WARNINGS_PROPERTIES :
+				initializeWarnings(currentArg);
+				mode = DEFAULT;
+				continue;
+		}
+
+		// default is input directory, if no custom destination path exists
+		if (customDestinationPath == null) {
+			if (File.separatorChar != '/') {
+				currentArg = currentArg.replace('/', File.separatorChar);
+			}
+			if (currentArg.endsWith("[-d")) { //$NON-NLS-1$
+				currentSourceDirectory = currentArg.substring(0,
+					currentArg.length() - 3);
+				mode = INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH;
+				continue;
+			}
+			currentSourceDirectory = currentArg;
+		}
+		File dir = new File(currentSourceDirectory);
+		if (!dir.isDirectory()) {
+			throw new IllegalArgumentException(
+				this.bind("configure.unrecognizedOption", currentSourceDirectory)); //$NON-NLS-1$
+		}
+		String[] result = FileFinder.find(dir, SuffixConstants.SUFFIX_STRING_JAVA);
+		if (NONE.equals(customDestinationPath)) {
+			customDestinationPath = NONE; // ensure == comparison
+		}
+		if (this.filenames != null) {
+			// some source files were specified explicitly
+			int length = result.length;
+			System.arraycopy(
+				this.filenames,
+				0,
+				(this.filenames = new String[length + filesCount]),
+				0,
+				filesCount);
+			System.arraycopy(
+				this.encodings,
+				0,
+				(this.encodings = new String[length + filesCount]),
+				0,
+				filesCount);
+			System.arraycopy(
+				this.destinationPaths,
+				0,
+				(this.destinationPaths = new String[length + filesCount]),
+				0,
+				filesCount);
+			System.arraycopy(result, 0, this.filenames, filesCount, length);
+			for (int i = 0; i < length; i++) {
+				this.encodings[filesCount + i] = customEncoding;
+				this.destinationPaths[filesCount + i] = customDestinationPath;
+			}
+			filesCount += length;
+			customEncoding = null;
+			customDestinationPath = null;
+			currentSourceDirectory = null;
+		} else {
+			this.filenames = result;
+			filesCount = this.filenames.length;
+			this.encodings = new String[filesCount];
+			this.destinationPaths = new String[filesCount];
+			for (int i = 0; i < filesCount; i++) {
+				this.encodings[i] = customEncoding;
+				this.destinationPaths[i] = customDestinationPath;
+			}
+			customEncoding = null;
+			customDestinationPath = null;
+			currentSourceDirectory = null;
+		}
+		mode = DEFAULT;
+		continue;
+	}
+
+	// set DocCommentSupport, with appropriate side effects on defaults if
+	// javadoc is not enabled
+	if (this.enableJavadocOn) {
+		this.options.put(
+			CompilerOptions.OPTION_DocCommentSupport,
+			CompilerOptions.ENABLED);
+	} else if (this.warnJavadocOn || this.warnAllJavadocOn) {
+		this.options.put(
+			CompilerOptions.OPTION_DocCommentSupport,
+			CompilerOptions.ENABLED);
+		// override defaults: references that are embedded in javadoc are ignored
+		// from the perspective of parameters and thrown exceptions usage
+		this.options.put(
+			CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
+			CompilerOptions.DISABLED);
+		this.options.put(
+			CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
+			CompilerOptions.DISABLED);
+	}
+	// configure warnings for javadoc contents
+	if (this.warnJavadocOn) {
+		this.options.put(
+			CompilerOptions.OPTION_ReportInvalidJavadocTags,
+			CompilerOptions.ENABLED);
+		this.options.put(
+			CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
+			CompilerOptions.ENABLED);
+		this.options.put(
+			CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
+			CompilerOptions.ENABLED);
+		this.options.put(
+			CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
+			CompilerOptions.PRIVATE);
+	}
+
+	if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
+		if (usageSection ==  null) {
+			printUsage(); // default
+		} else {
+			printUsage(usageSection);
+		}
+		this.proceed = false;
+		return;
+	}
+
+	if (this.log != null) {
+		this.logger.setLog(this.log);
+	} else {
+		this.showProgress = false;
+	}
+	this.logger.logVersion(printVersionRequired);
+
+	validateOptions(didSpecifyCompliance);
+
+	// Enable annotation processing by default in batch mode when compliance is at least 1.6
+	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=185768
+	if (!didSpecifyDisabledAnnotationProcessing
+			&& CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) >= ClassFileConstants.JDK1_6) {
+		this.options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED);
+	}
+
+	this.logger.logCommandLineArguments(newCommandLineArgs);
+	this.logger.logOptions(this.options);
+
+	if (this.maxRepetition == 0) {
+		this.maxRepetition = 1;
+	}
+	if (this.maxRepetition >= 3 && (this.timing & TIMING_ENABLED) != 0) {
+		this.compilerStats = new CompilerStats[this.maxRepetition];
+	}
+
+	if (filesCount != 0) {
+		System.arraycopy(
+			this.filenames,
+			0,
+			(this.filenames = new String[filesCount]),
+			0,
+			filesCount);
+	}
+
+	if (classCount != 0) {
+		System.arraycopy(
+			this.classNames,
+			0,
+			(this.classNames = new String[classCount]),
+			0,
+			classCount);
+	}
+
+	setPaths(bootclasspaths,
+			sourcepathClasspathArg,
+			sourcepathClasspaths,
+			classpaths,
+			extdirsClasspaths,
+			endorsedDirClasspaths,
+			customEncoding);
+
+	if (specifiedEncodings != null && specifiedEncodings.size() > 1) {
+		this.logger.logWarning(this.bind("configure.multipleencodings", //$NON-NLS-1$
+				(String) this.options.get(CompilerOptions.OPTION_Encoding),
+				getAllEncodings(specifiedEncodings)));
+	}
+	if (this.pendingErrors != null) {
+		for (Iterator iterator = this.pendingErrors.iterator(); iterator.hasNext(); ) {
+			String message = (String) iterator.next();
+			this.logger.logPendingError(message);
+		}
+		this.pendingErrors = null;
+	}
+}
+
+private static char[][] decodeIgnoreOptionalProblemsFromFolders(String folders) {
+	StringTokenizer tokenizer = new StringTokenizer(folders, File.pathSeparator);
+	char[][] result = new char[tokenizer.countTokens()][];
+	int count = 0;
+	while (tokenizer.hasMoreTokens()) {
+		String fileName = tokenizer.nextToken();
+		// relative folder names are created relative to the current user dir
+		File file = new File(fileName);
+		if (file.exists()) {
+			// if the file exists, we should try to use its canonical path
+			try {
+				result[count++] = file.getCanonicalPath().toCharArray();
+			} catch (IOException e) {
+				// if we got exception during canonicalization, fall back to the name that was specified
+				result[count++] = fileName.toCharArray();
+			}
+		} else {
+			// if the file does not exist, use the name that was specified
+			result[count++] = fileName.toCharArray();
+		}
+	}
+	return result;
+}
+
+private static String getAllEncodings(Set encodings) {
+	int size = encodings.size();
+	String[] allEncodings = new String[size];
+	encodings.toArray(allEncodings);
+	Arrays.sort(allEncodings);
+	StringBuffer buffer = new StringBuffer();
+	for (int i = 0; i < size; i++) {
+		if (i > 0) {
+			buffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(allEncodings[i]);
+	}
+	return String.valueOf(buffer);
+}
+
+private void initializeWarnings(String propertiesFile) {
+	File file = new File(propertiesFile);
+	if (!file.exists()) {
+		throw new IllegalArgumentException(this.bind("configure.missingwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$
+	}
+	BufferedInputStream stream = null;
+	Properties properties = null;
+	try {
+		stream = new BufferedInputStream(new FileInputStream(propertiesFile));
+		properties = new Properties();
+		properties.load(stream);
+	} catch(IOException e) {
+		e.printStackTrace();
+		throw new IllegalArgumentException(this.bind("configure.ioexceptionwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$
+	} finally {
+		if (stream != null) {
+			try {
+				stream.close();
+			} catch(IOException e) {
+				// ignore
+			}
+		}
+	}
+	for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext(); ) {
+		Map.Entry entry = (Map.Entry) iterator.next();
+		final String key = (String) entry.getKey();
+		if (key.startsWith("org.eclipse.jdt.core.compiler.")) { //$NON-NLS-1$
+			this.options.put(key, entry.getValue());
+		}
+	}
+	// when using a properties file mimic relevant defaults from JavaCorePreferenceInitializer:
+	if (!properties.containsKey(CompilerOptions.OPTION_LocalVariableAttribute)) {
+		this.options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+	}
+	if (!properties.containsKey(CompilerOptions.OPTION_PreserveUnusedLocal)) {
+		this.options.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
+	}
+	if (!properties.containsKey(CompilerOptions.OPTION_DocCommentSupport)) {
+		this.options.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED);
+	}
+	if (!properties.containsKey(CompilerOptions.OPTION_ReportForbiddenReference)) {
+		this.options.put(CompilerOptions.OPTION_ReportForbiddenReference, CompilerOptions.ERROR);
+	}
+}
+protected void enableAll(int severity) {
+	String newValue = null;
+	switch(severity) {
+		case ProblemSeverities.Error :
+			newValue = CompilerOptions.ERROR;
+			break;
+		case ProblemSeverities.Warning :
+			newValue = CompilerOptions.WARNING;
+			break;
+	}
+	Object[] entries = this.options.entrySet().toArray();
+	for (int i = 0, max = entries.length; i < max; i++) {
+		Map.Entry entry = (Map.Entry) entries[i];
+		if (!(entry.getKey() instanceof String))
+			continue;
+		if (!(entry.getValue() instanceof String))
+			continue;
+		if (((String) entry.getValue()).equals(CompilerOptions.IGNORE)) {
+			this.options.put(entry.getKey(), newValue);
+		}
+	}
+	this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
+}
+protected void disableAll(int severity) {
+	String checkedValue = null;
+	switch(severity) {
+		case ProblemSeverities.Error :
+			checkedValue = CompilerOptions.ERROR;
+			break;
+		case ProblemSeverities.Warning :
+			checkedValue = CompilerOptions.WARNING;
+			break;
+	}
+	Object[] entries = this.options.entrySet().toArray();
+	for (int i = 0, max = entries.length; i < max; i++) {
+		Map.Entry entry = (Map.Entry) entries[i];
+		if (!(entry.getKey() instanceof String))
+			continue;
+		if (!(entry.getValue() instanceof String))
+			continue;
+		if (((String) entry.getValue()).equals(checkedValue)) {
+			this.options.put(entry.getKey(), CompilerOptions.IGNORE);
+		}
+	}
+}
+public String extractDestinationPathFromSourceFile(CompilationResult result) {
+	ICompilationUnit compilationUnit = result.compilationUnit;
+	if (compilationUnit != null) {
+		char[] fileName = compilationUnit.getFileName();
+		int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName);
+		if (lastIndex != -1) {
+			final String outputPathName = new String(fileName, 0, lastIndex);
+			final File output = new File(outputPathName);
+			if (output.exists() && output.isDirectory()) {
+				return outputPathName;
+			}
+		}
+	}
+	return System.getProperty("user.dir"); //$NON-NLS-1$
+}
+/*
+ * Answer the component to which will be handed back compilation results from the compiler
+ */
+public ICompilerRequestor getBatchRequestor() {
+	return new ICompilerRequestor() {
+		int lineDelta = 0;
+		public void acceptResult(CompilationResult compilationResult) {
+			if (compilationResult.lineSeparatorPositions != null) {
+				int unitLineCount = compilationResult.lineSeparatorPositions.length;
+				this.lineDelta += unitLineCount;
+				if (Main.this.showProgress && this.lineDelta > 2000) {
+					// in -log mode, dump a dot every 2000 lines compiled
+					Main.this.logger.logProgress();
+					this.lineDelta = 0;
+				}
+			}
+			Main.this.logger.startLoggingSource(compilationResult);
+			if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
+				Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this);
+			}
+			outputClassFiles(compilationResult);
+			Main.this.logger.endLoggingSource();
+		}
+	};
+}
+/*
+ *  Build the set of compilation source units
+ */
+public CompilationUnit[] getCompilationUnits() {
+	int fileCount = this.filenames.length;
+	CompilationUnit[] units = new CompilationUnit[fileCount];
+	HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);
+
+	String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding);
+	if (Util.EMPTY_STRING.equals(defaultEncoding))
+		defaultEncoding = null;
+
+	for (int i = 0; i < fileCount; i++) {
+		char[] charName = this.filenames[i].toCharArray();
+		if (knownFileNames.get(charName) != null)
+			throw new IllegalArgumentException(this.bind("unit.more", this.filenames[i])); //$NON-NLS-1$
+		knownFileNames.put(charName, charName);
+		File file = new File(this.filenames[i]);
+		if (!file.exists())
+			throw new IllegalArgumentException(this.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$
+		String encoding = this.encodings[i];
+		if (encoding == null)
+			encoding = defaultEncoding;
+		String fileName;
+		try {
+			fileName = file.getCanonicalPath();
+		} catch (IOException e) {
+			// if we got exception during canonicalization, fall back to the name that was specified
+			fileName = this.filenames[i];
+		}
+		units[i] = new CompilationUnit(null, fileName, encoding, this.destinationPaths[i],
+				shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()));
+	}
+	return units;
+}
+
+/*
+ *  Low-level API performing the actual compilation
+ */
+public IErrorHandlingPolicy getHandlingPolicy() {
+
+	// passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
+	return new IErrorHandlingPolicy() {
+		public boolean proceedOnErrors() {
+			return Main.this.proceedOnError; // stop if there are some errors
+		}
+		public boolean stopOnFirstError() {
+			return false;
+		}
+		public boolean ignoreAllErrors() {
+			return false;
+		}
+	};
+}
+
+/*
+ * External API
+ */
+public File getJavaHome() {
+	if (!this.javaHomeChecked) {
+		this.javaHomeChecked = true;
+		this.javaHomeCache = Util.getJavaHome();
+	}
+	return this.javaHomeCache;
+}
+
+public FileSystem getLibraryAccess() {
+	return new FileSystem(this.checkedClasspaths, this.filenames);
+}
+
+/*
+ *  Low-level API performing the actual compilation
+ */
+public IProblemFactory getProblemFactory() {
+	return new DefaultProblemFactory(this.compilerLocale);
+}
+
+/*
+ * External API
+ */
+protected ArrayList handleBootclasspath(ArrayList bootclasspaths, String customEncoding) {
+ 	final int bootclasspathsSize;
+	if ((bootclasspaths != null)
+		&& ((bootclasspathsSize = bootclasspaths.size()) != 0))
+	{
+		String[] paths = new String[bootclasspathsSize];
+		bootclasspaths.toArray(paths);
+		bootclasspaths.clear();
+		for (int i = 0; i < bootclasspathsSize; i++) {
+			processPathEntries(DEFAULT_SIZE_CLASSPATH, bootclasspaths,
+				paths[i], customEncoding, false, true);
+		}
+	} else {
+		bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+		try {
+			Util.collectRunningVMBootclasspath(bootclasspaths);
+		} catch(IllegalStateException e) {
+			this.logger.logWrongJDK();
+			this.proceed = false;
+			return null;
+		}
+	}
+	return bootclasspaths;
+}
+
+/*
+ * External API
+ */
+protected ArrayList handleClasspath(ArrayList classpaths, String customEncoding) {
+	final int classpathsSize;
+	if ((classpaths != null)
+		&& ((classpathsSize = classpaths.size()) != 0))
+	{
+		String[] paths = new String[classpathsSize];
+		classpaths.toArray(paths);
+		classpaths.clear();
+		for (int i = 0; i < classpathsSize; i++) {
+			processPathEntries(DEFAULT_SIZE_CLASSPATH, classpaths, paths[i],
+					customEncoding, false, true);
+		}
+	} else {
+		// no user classpath specified.
+		classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+		String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
+		if ((classProp == null) || (classProp.length() == 0)) {
+			addPendingErrors(this.bind("configure.noClasspath")); //$NON-NLS-1$
+			final Classpath classpath = FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, null);//$NON-NLS-1$
+			if (classpath != null) {
+				classpaths.add(classpath);
+			}
+		} else {
+			StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
+			String token;
+			while (tokenizer.hasMoreTokens()) {
+				token = tokenizer.nextToken();
+				FileSystem.Classpath currentClasspath = FileSystem
+						.getClasspath(token, customEncoding, null);
+				if (currentClasspath != null) {
+					classpaths.add(currentClasspath);
+				} else if (token.length() != 0) {
+					addPendingErrors(this.bind("configure.incorrectClasspath", token));//$NON-NLS-1$
+				}
+			}
+		}
+	}
+	ArrayList result = new ArrayList();
+	HashMap knownNames = new HashMap();
+	FileSystem.ClasspathSectionProblemReporter problemReporter =
+		new FileSystem.ClasspathSectionProblemReporter() {
+			public void invalidClasspathSection(String jarFilePath) {
+				addPendingErrors(bind("configure.invalidClasspathSection", jarFilePath)); //$NON-NLS-1$
+			}
+			public void multipleClasspathSections(String jarFilePath) {
+				addPendingErrors(bind("configure.multipleClasspathSections", jarFilePath)); //$NON-NLS-1$
+			}
+		};
+	while (! classpaths.isEmpty()) {
+		Classpath current = (Classpath) classpaths.remove(0);
+		String currentPath = current.getPath();
+		if (knownNames.get(currentPath) == null) {
+			knownNames.put(currentPath, current);
+			result.add(current);
+			List linkedJars = current.fetchLinkedJars(problemReporter);
+			if (linkedJars != null) {
+				classpaths.addAll(0, linkedJars);
+			}
+		}
+	}
+	return result;
+}
+/*
+ * External API
+ */
+protected ArrayList handleEndorseddirs(ArrayList endorsedDirClasspaths) {
+ 	final File javaHome = getJavaHome();
+	/*
+	 * Feed endorsedDirClasspath according to:
+	 * - -endorseddirs first if present;
+	 * - else java.endorsed.dirs if defined;
+	 * - else default extensions directory for the platform. (/lib/endorsed)
+	 */
+	if (endorsedDirClasspaths == null) {
+		endorsedDirClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+		String endorsedDirsStr = System.getProperty("java.endorsed.dirs"); //$NON-NLS-1$
+		if (endorsedDirsStr == null) {
+			if (javaHome != null) {
+				endorsedDirClasspaths.add(javaHome.getAbsolutePath() + "/lib/endorsed"); //$NON-NLS-1$
+			}
+		} else {
+			StringTokenizer tokenizer = new StringTokenizer(endorsedDirsStr, File.pathSeparator);
+			while (tokenizer.hasMoreTokens()) {
+				endorsedDirClasspaths.add(tokenizer.nextToken());
+			}
+		}
+	}
+
+	/*
+	 * Feed extdirsClasspath with the entries found into the directories listed by
+	 * extdirsNames.
+	 */
+	if (endorsedDirClasspaths.size() != 0) {
+		File[] directoriesToCheck = new File[endorsedDirClasspaths.size()];
+		for (int i = 0; i < directoriesToCheck.length; i++)
+			directoriesToCheck[i] = new File((String) endorsedDirClasspaths.get(i));
+		endorsedDirClasspaths.clear();
+		File[][] endorsedDirsJars = getLibrariesFiles(directoriesToCheck);
+		if (endorsedDirsJars != null) {
+			for (int i = 0, max = endorsedDirsJars.length; i < max; i++) {
+				File[] current = endorsedDirsJars[i];
+				if (current != null) {
+					for (int j = 0, max2 = current.length; j < max2; j++) {
+						FileSystem.Classpath classpath =
+							FileSystem.getClasspath(
+									current[j].getAbsolutePath(),
+									null, null);
+						if (classpath != null) {
+							endorsedDirClasspaths.add(classpath);
+						}
+					}
+				} else if (directoriesToCheck[i].isFile()) {
+					addPendingErrors(
+						this.bind(
+							"configure.incorrectEndorsedDirsEntry", //$NON-NLS-1$
+							directoriesToCheck[i].getAbsolutePath()));
+				}
+			}
+		}
+	}
+	return endorsedDirClasspaths;
+}
+
+/*
+ * External API
+ * Handle extdirs processing
+ */
+protected ArrayList handleExtdirs(ArrayList extdirsClasspaths) {
+ 	final File javaHome = getJavaHome();
+
+	/*
+	 * Feed extDirClasspath according to:
+	 * - -extdirs first if present;
+	 * - else java.ext.dirs if defined;
+	 * - else default extensions directory for the platform.
+	 */
+	if (extdirsClasspaths == null) {
+		extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+		String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$
+		if (extdirsStr == null) {
+			extdirsClasspaths.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$
+		} else {
+			StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator);
+			while (tokenizer.hasMoreTokens())
+				extdirsClasspaths.add(tokenizer.nextToken());
+		}
+	}
+
+	/*
+	 * Feed extdirsClasspath with the entries found into the directories listed by
+	 * extdirsNames.
+	 */
+	if (extdirsClasspaths.size() != 0) {
+		File[] directoriesToCheck = new File[extdirsClasspaths.size()];
+		for (int i = 0; i < directoriesToCheck.length; i++)
+			directoriesToCheck[i] = new File((String) extdirsClasspaths.get(i));
+		extdirsClasspaths.clear();
+		File[][] extdirsJars = getLibrariesFiles(directoriesToCheck);
+		if (extdirsJars != null) {
+			for (int i = 0, max = extdirsJars.length; i < max; i++) {
+				File[] current = extdirsJars[i];
+				if (current != null) {
+					for (int j = 0, max2 = current.length; j < max2; j++) {
+						FileSystem.Classpath classpath =
+							FileSystem.getClasspath(
+									current[j].getAbsolutePath(),
+									null, null);
+						if (classpath != null) {
+							extdirsClasspaths.add(classpath);
+						}
+					}
+				} else if (directoriesToCheck[i].isFile()) {
+					addPendingErrors(this.bind(
+							"configure.incorrectExtDirsEntry", //$NON-NLS-1$
+							directoriesToCheck[i].getAbsolutePath()));
+				}
+			}
+		}
+	}
+
+	return extdirsClasspaths;
+}
+
+/*
+ * External API
+ * Handle a single warning token.
+*/
+protected void handleWarningToken(String token, boolean isEnabling) {
+	handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Warning);
+}
+protected void handleErrorToken(String token, boolean isEnabling) {
+	handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Error);
+}
+private void setSeverity(String compilerOptions, int severity, boolean isEnabling) {
+	if (isEnabling) {
+		switch(severity) {
+			case ProblemSeverities.Error :
+				this.options.put(compilerOptions, CompilerOptions.ERROR);
+				break;
+			case ProblemSeverities.Warning :
+				this.options.put(compilerOptions, CompilerOptions.WARNING);
+				break;
+			default:
+				this.options.put(compilerOptions, CompilerOptions.IGNORE);
+		}
+	} else {
+		switch(severity) {
+			case ProblemSeverities.Error :
+				String currentValue = (String) this.options.get(compilerOptions);
+				if (CompilerOptions.ERROR.equals(currentValue)) {
+					this.options.put(compilerOptions, CompilerOptions.IGNORE);
+				}
+				break;
+			case ProblemSeverities.Warning :
+				currentValue = (String) this.options.get(compilerOptions);
+				if (CompilerOptions.WARNING.equals(currentValue)) {
+					this.options.put(compilerOptions, CompilerOptions.IGNORE);
+				}
+				break;
+			default:
+				this.options.put(compilerOptions, CompilerOptions.IGNORE);
+		}
+	}
+}
+private void handleErrorOrWarningToken(String token, boolean isEnabling, int severity) {
+	if (token.length() == 0) return;
+	switch(token.charAt(0)) {
+		case 'a' :
+			if (token.equals("allDeprecation")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("allJavadoc")) { //$NON-NLS-1$
+				this.warnAllJavadocOn = this.warnJavadocOn = isEnabling;
+				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
+				return;
+			} else if (token.equals("assertIdentifier")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportAssertIdentifier, severity, isEnabling);
+				return;
+			} else if (token.equals("allDeadCode")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("allOver-ann")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("all-static-method")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, severity, isEnabling);
+				return;
+			} else if (token.equals("all")) { //$NON-NLS-1$
+				if (isEnabling) {
+					enableAll(severity);
+				} else {
+					disableAll(severity);
+				}
+				return;
+			}
+			break;
+		case 'b' :
+			if (token.equals("boxing")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportAutoboxing, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'c' :
+			if (token.equals("constructorName")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMethodWithConstructorName, severity, isEnabling);
+				return;
+			} else if (token.equals("conditionAssign")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, severity, isEnabling);
+				return;
+			} else if (token.equals("compareIdentical")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportComparingIdentical, severity, isEnabling);
+				return;
+			} else if (token.equals("charConcat") /*|| token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'd' :
+			if (token.equals("deprecation")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
+					CompilerOptions.DISABLED);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
+					CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("dep-ann")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation, severity, isEnabling);
+				return;
+			} else if (token.equals("discouraged")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportDiscouragedReference, severity, isEnabling);
+				return;
+			} else if (token.equals("deadCode")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
+					CompilerOptions.DISABLED);
+				return;
+			}
+			break;
+		case 'e' :
+			if (token.equals("enumSwitch")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
+				return;
+			} else if (token.equals("enumSwitchPedantic")) { //$NON-NLS-1$
+				if (isEnabling) {
+					switch (severity) {
+						case ProblemSeverities.Error:
+							setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
+							break;
+						case ProblemSeverities.Warning:
+							if (CompilerOptions.IGNORE.equals(this.options.get(CompilerOptions.OPTION_ReportIncompleteEnumSwitch))) {
+								setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
+							}
+							break;
+						default: // no severity update
+					}
+				}
+				this.options.put(CompilerOptions.OPTION_ReportMissingEnumCaseDespiteDefault, 
+								 isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("emptyBlock")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, severity, isEnabling);
+				return;
+			} else if (token.equals("enumIdentifier")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportEnumIdentifier, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'f' :
+			if (token.equals("fieldHiding")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
+				return;
+			} else if (token.equals("finalBound")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportFinalParameterBound, severity, isEnabling);
+				return;
+			} else if (token.equals("finally")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, severity, isEnabling);
+				return;
+			} else if (token.equals("forbidden")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportForbiddenReference, severity, isEnabling);
+				return;
+			} else if (token.equals("fallthrough")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportFallthroughCase, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'h' :
+			if (token.equals("hiding")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
+				return;
+			} else if (token.equals("hashCode")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingHashCodeMethod, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'i' :
+			if (token.equals("indirectStatic")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
+				return;
+			} else if (token.equals("inheritNullAnnot")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_InheritNullAnnotations,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, severity, isEnabling);
+				return;
+			} else if (token.equals("intfAnnotation")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportAnnotationSuperInterface, severity, isEnabling);
+				return;
+			} else if (token.equals("intfRedundant") /*|| token.equals("redundantSuperinterface")*/) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
+				return;
+			} else if (token.equals("includeAssertNull")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_IncludeNullInfoFromAsserts,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("invalidJavadoc")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportInvalidJavadocTags,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				this.options.put(
+					CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				this.options.put(
+					CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				if (isEnabling) {
+					this.options.put(
+							CompilerOptions.OPTION_DocCommentSupport,
+							CompilerOptions.ENABLED);
+					this.options.put(
+						CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
+						CompilerOptions.PRIVATE);
+				}
+				return;
+			} else if (token.equals("invalidJavadocTag")) { //$NON-NLS-1$
+				this.options.put(
+					CompilerOptions.OPTION_ReportInvalidJavadocTags,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("invalidJavadocTagDep")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("invalidJavadocTagNotVisible")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.startsWith("invalidJavadocTagVisibility")) { //$NON-NLS-1$
+				int start = token.indexOf('(');
+				int end = token.indexOf(')');
+				String visibility = null;
+				if (isEnabling && start >= 0 && end >= 0 && start < end){
+					visibility = token.substring(start+1, end).trim();
+				}
+				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
+						|| visibility.equals(CompilerOptions.PRIVATE)
+						|| visibility.equals(CompilerOptions.PROTECTED)
+						|| visibility.equals(CompilerOptions.DEFAULT)) {
+					this.options.put(
+							CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
+							visibility);
+					return;
+				} else {
+					throw new IllegalArgumentException(this.bind("configure.invalidJavadocTagVisibility", token)); //$NON-NLS-1$
+				}
+			}
+			break;
+		case 'j' :
+			if (token.equals("javadoc")) {//$NON-NLS-1$
+				this.warnJavadocOn = isEnabling;
+				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'l' :
+			if (token.equals("localHiding")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'm' :
+			if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
+				return;
+			} else if (token.equals("missingJavadocTags")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				if (isEnabling) {
+					this.options.put(
+							CompilerOptions.OPTION_DocCommentSupport,
+							CompilerOptions.ENABLED);
+					this.options.put(
+						CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
+						CompilerOptions.PRIVATE);
+				}
+				return;
+			} else if (token.equals("missingJavadocTagsOverriding")) { //$NON-NLS-1$
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("missingJavadocTagsMethod")) { //$NON-NLS-1$
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.startsWith("missingJavadocTagsVisibility")) { //$NON-NLS-1$
+				int start = token.indexOf('(');
+				int end = token.indexOf(')');
+				String visibility = null;
+				if (isEnabling && start >= 0 && end >= 0 && start < end){
+					visibility = token.substring(start+1, end).trim();
+				}
+				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
+						|| visibility.equals(CompilerOptions.PRIVATE)
+						|| visibility.equals(CompilerOptions.PROTECTED)
+						|| visibility.equals(CompilerOptions.DEFAULT)) {
+					this.options.put(
+							CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
+							visibility);
+					return;
+				} else {
+					throw new IllegalArgumentException(this.bind("configure.missingJavadocTagsVisibility", token)); //$NON-NLS-1$
+				}
+			} else if (token.equals("missingJavadocComments")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				if (isEnabling) {
+					this.options.put(
+							CompilerOptions.OPTION_DocCommentSupport,
+							CompilerOptions.ENABLED);
+					this.options.put(
+						CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility,
+						CompilerOptions.PRIVATE);
+				}
+				return;
+			} else if (token.equals("missingJavadocCommentsOverriding")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.startsWith("missingJavadocCommentsVisibility")) { //$NON-NLS-1$
+				int start = token.indexOf('(');
+				int end = token.indexOf(')');
+				String visibility = null;
+				if (isEnabling && start >= 0 && end >= 0 && start < end){
+					visibility = token.substring(start+1, end).trim();
+				}
+				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
+						|| visibility.equals(CompilerOptions.PRIVATE)
+						|| visibility.equals(CompilerOptions.PROTECTED)
+						|| visibility.equals(CompilerOptions.DEFAULT)) {
+					this.options.put(
+							CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility,
+							visibility);
+					return;
+				} else {
+					throw new IllegalArgumentException(this.bind("configure.missingJavadocCommentsVisibility", token)); //$NON-NLS-1$
+				}
+			}
+			break;
+		case 'n' :
+			if (token.equals("nls")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, severity, isEnabling);
+				return;
+			} else if (token.equals("noEffectAssign")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNoEffectAssignment, severity, isEnabling);
+				return;
+			} else if (/*token.equals("charConcat") ||*/ token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
+				return;
+			} else if (token.equals("null")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, severity, isEnabling);
+				return;
+			} else if (token.equals("nullDereference")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
+				if (!isEnabling) {
+					setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, ProblemSeverities.Ignore, isEnabling);
+					setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling);
+				}
+				return;
+			}else if (token.equals("nullAnnotConflict")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling);
+				return;
+			} else if (token.equals("nullAnnotRedundant")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling);
+				return;
+			} else if (token.startsWith("nullAnnot")) { //$NON-NLS-1$
+				String annotationNames = Util.EMPTY_STRING;
+				int start = token.indexOf('(');
+				int end = token.indexOf(')');
+				String nonNullAnnotName = null, nullableAnnotName = null, nonNullByDefaultAnnotName = null;
+				if (isEnabling && start >= 0 && end >= 0 && start < end){
+					annotationNames = token.substring(start+1, end).trim();
+					int separator1 = annotationNames.indexOf('|');
+					if (separator1 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
+					nullableAnnotName = annotationNames.substring(0, separator1).trim();
+					if (nullableAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
+					int separator2 = annotationNames.indexOf('|', separator1 + 1);
+					if (separator2 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
+					nonNullAnnotName = annotationNames.substring(separator1 + 1, separator2).trim();
+					if (nonNullAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
+					nonNullByDefaultAnnotName = annotationNames.substring(separator2 + 1).trim();
+					if (nonNullByDefaultAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
+					this.options.put(CompilerOptions.OPTION_NullableAnnotationName, nullableAnnotName);
+					this.options.put(CompilerOptions.OPTION_NonNullAnnotationName, nonNullAnnotName);
+					this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationName, nonNullByDefaultAnnotName);
+				}
+				this.options.put(
+						CompilerOptions.OPTION_AnnotationBasedNullAnalysis,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				setSeverity(CompilerOptions.OPTION_ReportNullSpecViolation, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling);
+				return;
+			} else if (token.equals("nullUncheckedConversion")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling);
+				return;
+			} else if (token.equals("nonnullNotRepeated")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNonnullParameterAnnotationDropped, severity, isEnabling);
+				return;
+			}
+			
+			break;
+		case 'o' :
+			if (token.equals("over-sync") /*|| token.equals("syncOverride")*/) { //$NON-NLS-1$ 
+				setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
+				return;
+			} else if (token.equals("over-ann")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
+				this.options.put(
+					CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
+					CompilerOptions.DISABLED);
+				return;
+			}
+			break;
+		case 'p' :
+			if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, severity, isEnabling);
+				return;
+			} else if (token.equals("paramAssign")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportParameterAssignment, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'r' :
+			if (token.equals("raw")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportRawTypeReference, severity, isEnabling);
+				return;
+			} else if (/*token.equals("intfRedundant") ||*/ token.equals("redundantSuperinterface")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
+				return;
+			} else if (token.equals("resource")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnclosedCloseable, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, severity, isEnabling);
+				return;
+			}
+			break;
+		case 's' :
+			if (token.equals("specialParamHiding")) { //$NON-NLS-1$
+				this.options.put(
+					CompilerOptions.OPTION_ReportSpecialParameterHidingField,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("syntheticAccess") || token.equals("synthetic-access")) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, severity, isEnabling);
+				return;
+			} else if (token.equals("staticReceiver")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
+				return;
+			} else 	if (/*token.equals("over-sync") ||*/ token.equals("syncOverride")) { //$NON-NLS-1$ 
+				setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
+				return;
+			} else if (token.equals("semicolon")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportEmptyStatement, severity, isEnabling);
+				return;
+			} else if (token.equals("serial")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingSerialVersion, severity, isEnabling);
+				return;
+			} else if (token.equals("suppress")) {//$NON-NLS-1$
+				switch(severity) {
+					case ProblemSeverities.Warning :
+						this.options.put(
+								CompilerOptions.OPTION_SuppressWarnings,
+								isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+						this.options.put(
+								CompilerOptions.OPTION_SuppressOptionalErrors,
+								CompilerOptions.DISABLED);
+						break;
+					case ProblemSeverities.Error :
+						this.options.put(
+								CompilerOptions.OPTION_SuppressWarnings,
+								isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+						this.options.put(
+							CompilerOptions.OPTION_SuppressOptionalErrors,
+							isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				}
+				return;
+			} else if (token.equals("static-access")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
+				return;
+			} else if (token.equals("super")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, severity, isEnabling);
+				return;
+			} else if (token.equals("static-method")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling);
+				return;
+			} else if (token.equals("switchDefault")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportMissingDefaultCase, severity, isEnabling);
+				return;
+			}
+			break;
+		case 't' :
+			if (token.startsWith("tasks")) { //$NON-NLS-1$
+				String taskTags = Util.EMPTY_STRING;
+				int start = token.indexOf('(');
+				int end = token.indexOf(')');
+				if (start >= 0 && end >= 0 && start < end){
+					taskTags = token.substring(start+1, end).trim();
+					taskTags = taskTags.replace('|',',');
+				}
+				if (taskTags.length() == 0){
+					throw new IllegalArgumentException(this.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$
+				}
+				this.options.put(
+					CompilerOptions.OPTION_TaskTags,
+					isEnabling ? taskTags : Util.EMPTY_STRING);
+				
+				setSeverity(CompilerOptions.OPTION_ReportTasks, severity, isEnabling);
+				return;
+			} else if (token.equals("typeHiding")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'u' :
+			if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedAllocation")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedPrivate")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedLabel")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
+				return;
+			} else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, severity, isEnabling);
+				return;
+			} else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportUncheckedTypeOperation, severity, isEnabling);
+				return;
+			} else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnnecessaryElse, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedThrown")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedThrownWhenOverriding")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("unusedThrownIncludeDocComment")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("unusedThrownExemptExceptionThrowable")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("unqualifiedField") || token.equals("unqualified-field-access")) { //$NON-NLS-1$ //$NON-NLS-2$
+				setSeverity(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, severity, isEnabling);
+				return;
+			} else if (token.equals("unused")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity,isEnabling);
+				return;
+			} else if (token.equals("unusedParam")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedTypeParameter")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity, isEnabling);
+				return;
+			} else if (token.equals("unusedParamIncludeDoc")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("unusedParamOverriding")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			} else if (token.equals("unusedParamImplementing")) { //$NON-NLS-1$
+				this.options.put(
+						CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract,
+						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			}  else if (token.equals("unusedTypeArgs")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
+				return;
+			} else if (token.equals("unavoidableGenericProblems")) { //$NON-NLS-1$
+				this.options.put(
+					CompilerOptions.OPTION_ReportUnavoidableGenericTypeProblems,
+					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+				return;
+			}
+			break;
+		case 'v' :
+			if (token.equals("varargsCast")) { //$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportVarargsArgumentNeedCast, severity, isEnabling);
+				return;
+			}
+			break;
+		case 'w' :
+			if (token.equals("warningToken")) {//$NON-NLS-1$
+				setSeverity(CompilerOptions.OPTION_ReportUnhandledWarningToken, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportUnusedWarningToken, severity, isEnabling);
+				return;
+			}
+			break;
+	}
+	String message = null;
+	switch(severity) {
+		case ProblemSeverities.Warning :
+			message = this.bind("configure.invalidWarning", token); //$NON-NLS-1$
+			break;
+		case ProblemSeverities.Error :
+			message = this.bind("configure.invalidError", token); //$NON-NLS-1$
+	}
+	addPendingErrors(message);
+}
+/**
+ * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ *                       e.g. initialize(outWriter, errWriter, systemExit, null, null)
+ */
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit) {
+	this.initialize(outWriter, errWriter, systemExit, null /* options */, null /* progress */);
+}
+/**
+ * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
+ *                       e.g. initialize(outWriter, errWriter, systemExit, customDefaultOptions, null)
+ */
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions) {
+	this.initialize(outWriter, errWriter, systemExit, customDefaultOptions, null /* progress */);
+}
+protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map customDefaultOptions, CompilationProgress compilationProgress) {
+	this.logger = new Logger(this, outWriter, errWriter);
+	this.proceed = true;
+	this.out = outWriter;
+	this.err = errWriter;
+	this.systemExitWhenFinished = systemExit;
+	this.options = new CompilerOptions().getMap();
+	this.ignoreOptionalProblemsFromFolders = null;
+
+	this.progress = compilationProgress;
+	if (customDefaultOptions != null) {
+		this.didSpecifySource = customDefaultOptions.get(CompilerOptions.OPTION_Source) != null;
+		this.didSpecifyTarget = customDefaultOptions.get(CompilerOptions.OPTION_TargetPlatform) != null;
+		for (Iterator iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			this.options.put(entry.getKey(), entry.getValue());
+		}
+	} else {
+		this.didSpecifySource = false;
+		this.didSpecifyTarget = false;
+	}
+	this.classNames = null;
+}
+protected void initializeAnnotationProcessorManager() {
+	try {
+		Class c = Class.forName("org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"); //$NON-NLS-1$
+		AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance();
+		annotationManager.configure(this, this.expandedCommandLine);
+		annotationManager.setErr(this.err);
+		annotationManager.setOut(this.out);
+		this.batchCompiler.annotationProcessorManager = annotationManager;
+	} catch (ClassNotFoundException e) {
+		// ignore
+	} catch (InstantiationException e) {
+		// should not happen
+		throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
+	} catch (IllegalAccessException e) {
+		// should not happen
+		throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
+	} catch(UnsupportedClassVersionError e) {
+		// report a warning
+		this.logger.logIncorrectVMVersionForAnnotationProcessing();
+	}
+}
+private static boolean isParentOf(char[] folderName, char[] fileName) {
+	if (folderName.length >= fileName.length) {
+		return false;
+	}
+	if (fileName[folderName.length] != '\\' && fileName[folderName.length] != '/') {
+		return false;
+	}
+	for (int i = folderName.length - 1; i >= 0; i--) {
+		if (folderName[i] != fileName[i]) {
+			return false;
+		}
+	}
+	return true;
+}
+// Dump classfiles onto disk for all compilation units that where successful
+// and do not carry a -d none spec, either directly or inherited from Main.
+public void outputClassFiles(CompilationResult unitResult) {
+	if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
+		ClassFile[] classFiles = unitResult.getClassFiles();
+		String currentDestinationPath = null;
+		boolean generateClasspathStructure = false;
+		CompilationUnit compilationUnit =
+			(CompilationUnit) unitResult.compilationUnit;
+		if (compilationUnit.destinationPath == null) {
+			if (this.destinationPath == null) {
+				currentDestinationPath =
+					extractDestinationPathFromSourceFile(unitResult);
+			} else if (this.destinationPath != NONE) {
+				currentDestinationPath = this.destinationPath;
+				generateClasspathStructure = true;
+			} // else leave currentDestinationPath null
+		} else if (compilationUnit.destinationPath != NONE) {
+			currentDestinationPath = compilationUnit.destinationPath;
+			generateClasspathStructure = true;
+		} // else leave currentDestinationPath null
+		if (currentDestinationPath != null) {
+			for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
+				// retrieve the key and the corresponding classfile
+				ClassFile classFile = classFiles[i];
+				char[] filename = classFile.fileName();
+				int length = filename.length;
+				char[] relativeName = new char[length + 6];
+				System.arraycopy(filename, 0, relativeName, 0, length);
+				System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
+				CharOperation.replace(relativeName, '/', File.separatorChar);
+				String relativeStringName = new String(relativeName);
+				try {
+					if (this.compilerOptions.verbose)
+						this.out.println(
+							Messages.bind(
+								Messages.compilation_write,
+								new String[] {
+									String.valueOf(this.exportedClassFilesCounter+1),
+									relativeStringName
+								}));
+					Util.writeToDisk(
+						generateClasspathStructure,
+						currentDestinationPath,
+						relativeStringName,
+						classFile);
+					this.logger.logClassFile(
+						generateClasspathStructure,
+						currentDestinationPath,
+						relativeStringName);
+					this.exportedClassFilesCounter++;
+				} catch (IOException e) {
+					this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
+				}
+			}
+			this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles);
+		}
+	}
+}
+/*
+ *  Low-level API performing the actual compilation
+ */
+public void performCompilation() {
+
+	this.startTime = System.currentTimeMillis();
+
+	FileSystem environment = getLibraryAccess();
+	this.compilerOptions = new CompilerOptions(this.options);
+	this.compilerOptions.performMethodsFullRecovery = false;
+	this.compilerOptions.performStatementsRecovery = false;
+	this.batchCompiler =
+		new Compiler(
+			environment,
+			getHandlingPolicy(),
+			this.compilerOptions,
+			getBatchRequestor(),
+			getProblemFactory(),
+			this.out,
+			this.progress);
+	this.batchCompiler.remainingIterations = this.maxRepetition-this.currentRepetition/*remaining iterations including this one*/;
+	// temporary code to allow the compiler to revert to a single thread
+	String setting = System.getProperty("jdt.compiler.useSingleThread"); //$NON-NLS-1$
+	this.batchCompiler.useSingleThread = setting != null && setting.equals("true"); //$NON-NLS-1$
+
+	if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
+			&& this.compilerOptions.processAnnotations) {
+		if (checkVMVersion(ClassFileConstants.JDK1_6)) {
+			initializeAnnotationProcessorManager();
+			if (this.classNames != null) {
+				this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
+			}
+		} else {
+			// report a warning
+			this.logger.logIncorrectVMVersionForAnnotationProcessing();
+		}
+	}
+
+	// set the non-externally configurable options.
+	this.compilerOptions.verbose = this.verbose;
+	this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
+	try {
+		this.logger.startLoggingSources();
+		this.batchCompiler.compile(getCompilationUnits());
+	} finally {
+		this.logger.endLoggingSources();
+	}
+
+	if (this.extraProblems != null) {
+		loggingExtraProblems();
+		this.extraProblems = null;
+	}
+	if (this.compilerStats != null) {
+		this.compilerStats[this.currentRepetition] = this.batchCompiler.stats;
+	}
+	this.logger.printStats();
+
+	// cleanup
+	environment.cleanup();
+}
+protected void loggingExtraProblems() {
+	this.logger.loggingExtraProblems(this);
+}
+public void printUsage() {
+	printUsage("misc.usage"); //$NON-NLS-1$
+}
+private void printUsage(String sectionID) {
+	this.logger.logUsage(
+		this.bind(
+			sectionID,
+			new String[] {
+				System.getProperty("path.separator"), //$NON-NLS-1$
+				this.bind("compiler.name"), //$NON-NLS-1$
+				this.bind("compiler.version"), //$NON-NLS-1$
+				this.bind("compiler.copyright") //$NON-NLS-1$
+			}));
+	this.logger.flush();
+}
+private ReferenceBinding[] processClassNames(LookupEnvironment environment) {
+	// check for .class file presence in case of apt processing
+	int length = this.classNames.length;
+	ReferenceBinding[] referenceBindings = new ReferenceBinding[length];
+	for (int i = 0; i < length; i++) {
+		String currentName = this.classNames[i];
+		char[][] compoundName = null;
+		if (currentName.indexOf('.') != -1) {
+			// consider names with '.' as fully qualified names
+			char[] typeName = currentName.toCharArray();
+			compoundName = CharOperation.splitOn('.', typeName);
+		} else {
+			compoundName = new char[][] { currentName.toCharArray() };
+		}
+		ReferenceBinding type = environment.getType(compoundName);
+		if (type != null && type.isValidBinding()) {
+			if (type.isBinaryBinding()) {
+				referenceBindings[i] = type;
+			}
+		} else {
+			throw new IllegalArgumentException(
+					this.bind("configure.invalidClassName", currentName));//$NON-NLS-1$
+		}
+	}
+	return referenceBindings;
+}
+/*
+ * External API
+ */
+public void processPathEntries(final int defaultSize, final ArrayList paths,
+			final String currentPath, String customEncoding, boolean isSourceOnly,
+			boolean rejectDestinationPathOnJars) {
+	String currentClasspathName = null;
+	String currentDestinationPath = null;
+	ArrayList currentRuleSpecs = new ArrayList(defaultSize);
+	StringTokenizer tokenizer = new StringTokenizer(currentPath,
+			File.pathSeparator + "[]", true); //$NON-NLS-1$
+	ArrayList tokens = new ArrayList();
+	while (tokenizer.hasMoreTokens()) {
+		tokens.add(tokenizer.nextToken());
+	}
+	// state machine
+	final int start = 0;
+	final int readyToClose = 1;
+	// 'path' 'path1[rule];path2'
+	final int readyToCloseEndingWithRules = 2;
+	// 'path[rule]' 'path1;path2[rule]'
+	final int readyToCloseOrOtherEntry = 3;
+	// 'path[rule];' 'path;' 'path1;path2;'
+	final int rulesNeedAnotherRule = 4;
+	// 'path[rule1;'
+	final int rulesStart = 5;
+	// 'path[' 'path1;path2['
+	final int rulesReadyToClose = 6;
+	// 'path[rule' 'path[rule1;rule2'
+	final int destinationPathReadyToClose = 7;
+	// 'path[-d bin'
+	final int readyToCloseEndingWithDestinationPath = 8;
+	// 'path[-d bin]' 'path[rule][-d bin]'
+	final int destinationPathStart = 9;
+	// 'path[rule]['
+	final int bracketOpened = 10;
+	// '.*[.*'
+	final int bracketClosed = 11;
+	// '.*([.*])+'
+
+	final int error = 99;
+	int state = start;
+	String token = null;
+	int cursor = 0, tokensNb = tokens.size(), bracket = -1;
+	while (cursor < tokensNb && state != error) {
+		token = (String) tokens.get(cursor++);
+		if (token.equals(File.pathSeparator)) {
+			switch (state) {
+			case start:
+			case readyToCloseOrOtherEntry:
+			case bracketOpened:
+				break;
+			case readyToClose:
+			case readyToCloseEndingWithRules:
+			case readyToCloseEndingWithDestinationPath:
+				state = readyToCloseOrOtherEntry;
+				addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+						customEncoding, currentDestinationPath, isSourceOnly,
+						rejectDestinationPathOnJars);
+				currentRuleSpecs.clear();
+				break;
+			case rulesReadyToClose:
+				state = rulesNeedAnotherRule;
+				break;
+			case destinationPathReadyToClose:
+				throw new IllegalArgumentException(
+					this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
+						currentPath));
+			case bracketClosed:
+				cursor = bracket + 1;
+				state = rulesStart;
+				break;
+			default:
+				state = error;
+			}
+		} else if (token.equals("[")) { //$NON-NLS-1$
+			switch (state) {
+			case start:
+				currentClasspathName = ""; //$NON-NLS-1$
+				//$FALL-THROUGH$
+				case readyToClose:
+				bracket = cursor - 1;
+				//$FALL-THROUGH$
+				case bracketClosed:
+				state = bracketOpened;
+				break;
+			case readyToCloseEndingWithRules:
+				state = destinationPathStart;
+				break;
+			case readyToCloseEndingWithDestinationPath:
+				state = rulesStart;
+				break;
+			case bracketOpened:
+			default:
+				state = error;
+			}
+		} else if (token.equals("]")) { //$NON-NLS-1$
+			switch (state) {
+			case rulesReadyToClose:
+				state = readyToCloseEndingWithRules;
+				break;
+			case destinationPathReadyToClose:
+				state = readyToCloseEndingWithDestinationPath;
+				break;
+			case bracketOpened:
+				state = bracketClosed;
+				break;
+			case bracketClosed:
+			default:
+				state = error;
+			}
+		} else {
+			// regular word
+			switch (state) {
+			case start:
+			case readyToCloseOrOtherEntry:
+				state = readyToClose;
+				currentClasspathName = token;
+				break;
+			case rulesStart:
+				if (token.startsWith("-d ")) { //$NON-NLS-1$
+					if (currentDestinationPath != null) {
+						throw new IllegalArgumentException(
+								this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
+										currentPath));
+					}
+					currentDestinationPath = token.substring(3).trim();
+					state = destinationPathReadyToClose;
+					break;
+				} // else we proceed with a rule
+				//$FALL-THROUGH$
+			case rulesNeedAnotherRule:
+				if (currentDestinationPath != null) {
+					throw new IllegalArgumentException(
+							this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
+								currentPath));
+				}
+				state = rulesReadyToClose;
+				currentRuleSpecs.add(token);
+				break;
+			case destinationPathStart:
+				if (!token.startsWith("-d ")) { //$NON-NLS-1$
+					state = error;
+				} else {
+					currentDestinationPath = token.substring(3).trim();
+					state = destinationPathReadyToClose;
+				}
+				break;
+			case bracketClosed:
+				for (int i = bracket; i < cursor ; i++) {
+					currentClasspathName += (String) tokens.get(i);
+				}
+				state = readyToClose;
+				break;
+			case bracketOpened:
+				break;
+			default:
+				state = error;
+			}
+		}
+		if (state == bracketClosed && cursor == tokensNb) {
+			cursor = bracket + 1;
+			state = rulesStart;
+		}
+	}
+	switch(state) {
+		case readyToCloseOrOtherEntry:
+			break;
+		case readyToClose:
+		case readyToCloseEndingWithRules:
+		case readyToCloseEndingWithDestinationPath:
+			addNewEntry(paths, currentClasspathName, currentRuleSpecs,
+				customEncoding, currentDestinationPath, isSourceOnly,
+				rejectDestinationPathOnJars);
+			break;
+		case bracketOpened:
+		case bracketClosed:
+		default :
+			// we go on anyway
+			if (currentPath.length() != 0) {
+				addPendingErrors(this.bind("configure.incorrectClasspath", currentPath));//$NON-NLS-1$
+			}
+	}
+}
+
+private int processPaths(String[] args, int index, String currentArg, ArrayList paths) {
+	int localIndex = index;
+	int count = 0;
+	for (int i = 0, max = currentArg.length(); i < max; i++) {
+		switch(currentArg.charAt(i)) {
+			case '[' :
+				count++;
+				break;
+			case ']' :
+				count--;
+				break;
+		}
+	}
+	if (count == 0) {
+		paths.add(currentArg);
+	} else if (count > 1) {
+		throw new IllegalArgumentException(
+				this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+							currentArg));
+	} else {
+		StringBuffer currentPath = new StringBuffer(currentArg);
+		while (true) {
+			if (localIndex >= args.length) {
+				throw new IllegalArgumentException(
+						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+								currentArg));
+			}
+			localIndex++;
+			String nextArg = args[localIndex];
+			for (int i = 0, max = nextArg.length(); i < max; i++) {
+				switch(nextArg.charAt(i)) {
+					case '[' :
+						if (count > 1) {
+							throw new IllegalArgumentException(
+									this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+											nextArg));
+						}
+						count++;
+						break;
+					case ']' :
+						count--;
+						break;
+				}
+			}
+			if (count == 0) {
+				currentPath.append(' ');
+				currentPath.append(nextArg);
+				paths.add(currentPath.toString());
+				return localIndex - index;
+			} else if (count < 0) {
+				throw new IllegalArgumentException(
+						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+									nextArg));
+			} else {
+				currentPath.append(' ');
+				currentPath.append(nextArg);
+			}
+		}
+
+	}
+	return localIndex - index;
+}
+private int processPaths(String[] args, int index, String currentArg, String[] paths) {
+	int localIndex = index;
+	int count = 0;
+	for (int i = 0, max = currentArg.length(); i < max; i++) {
+		switch(currentArg.charAt(i)) {
+			case '[' :
+				count++;
+				break;
+			case ']' :
+				count--;
+				break;
+		}
+	}
+	if (count == 0) {
+		paths[0] = currentArg;
+	} else {
+		StringBuffer currentPath = new StringBuffer(currentArg);
+		while (true) {
+			localIndex++;
+			if (localIndex >= args.length) {
+				throw new IllegalArgumentException(
+						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+								currentArg));
+			}
+			String nextArg = args[localIndex];
+			for (int i = 0, max = nextArg.length(); i < max; i++) {
+				switch(nextArg.charAt(i)) {
+					case '[' :
+						if (count > 1) {
+							throw new IllegalArgumentException(
+									this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+											currentArg));
+						}
+						count++;
+						break;
+					case ']' :
+						count--;
+						break;
+				}
+			}
+			if (count == 0) {
+				currentPath.append(' ');
+				currentPath.append(nextArg);
+				paths[0] = currentPath.toString();
+				return localIndex - index;
+			} else if (count < 0) {
+				throw new IllegalArgumentException(
+						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
+									currentArg));
+			} else {
+				currentPath.append(' ');
+				currentPath.append(nextArg);
+			}
+		}
+
+	}
+	return localIndex - index;
+}
+/**
+ * Creates a NLS catalog for the given locale.
+ */
+public void relocalize() {
+	relocalize(Locale.getDefault());
+}
+
+private void relocalize(Locale locale) {
+	this.compilerLocale = locale;
+	try {
+		this.bundle = ResourceBundleFactory.getBundle(locale);
+	} catch(MissingResourceException e) {
+		System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
+		throw e;
+	}
+}
+/*
+ * External API
+ */
+public void setDestinationPath(String dest) {
+	this.destinationPath = dest;
+}
+/*
+ * External API
+ */
+public void setLocale(Locale locale) {
+	relocalize(locale);
+}
+/*
+ * External API
+ */
+protected void setPaths(ArrayList bootclasspaths,
+		String sourcepathClasspathArg,
+		ArrayList sourcepathClasspaths,
+		ArrayList classpaths,
+		ArrayList extdirsClasspaths,
+		ArrayList endorsedDirClasspaths,
+		String customEncoding) {
+
+	// process bootclasspath, classpath and sourcepaths
+ 	bootclasspaths = handleBootclasspath(bootclasspaths, customEncoding);
+
+	classpaths = handleClasspath(classpaths, customEncoding);
+
+	if (sourcepathClasspathArg != null) {
+		processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepathClasspaths,
+			sourcepathClasspathArg, customEncoding, true, false);
+	}
+
+	/*
+	 * Feed endorsedDirClasspath according to:
+	 * - -extdirs first if present;
+	 * - else java.ext.dirs if defined;
+	 * - else default extensions directory for the platform.
+	 */
+	extdirsClasspaths = handleExtdirs(extdirsClasspaths);
+
+	endorsedDirClasspaths = handleEndorseddirs(endorsedDirClasspaths);
+
+	/*
+	 * Concatenate classpath entries
+	 * We put the bootclasspath at the beginning of the classpath
+	 * entries, followed by the extension libraries, followed by
+	 * the sourcepath followed by the classpath.  All classpath
+	 * entries are searched for both sources and binaries except
+	 * the sourcepath entries which are searched for sources only.
+	 */
+	bootclasspaths.addAll(endorsedDirClasspaths);
+	bootclasspaths.addAll(extdirsClasspaths);
+	bootclasspaths.addAll(sourcepathClasspaths);
+	bootclasspaths.addAll(classpaths);
+	classpaths = bootclasspaths;
+	classpaths = FileSystem.ClasspathNormalizer.normalize(classpaths);
+	this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()];
+	classpaths.toArray(this.checkedClasspaths);
+	this.logger.logClasspath(this.checkedClasspaths);
+}
+private static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) {
+	if (folderNames == null || fileName == null) {
+		return false;
+	}
+	for (int i = 0, max = folderNames.length; i < max; i++) {
+		char[] folderName = folderNames[i];
+		if (isParentOf(folderName, fileName)) {
+			return true;
+		}
+	}
+	return false;
+}
+protected void validateOptions(boolean didSpecifyCompliance) {
+	if (didSpecifyCompliance) {
+		Object version = this.options.get(CompilerOptions.OPTION_Compliance);
+		if (CompilerOptions.VERSION_1_3.equals(version)) {
+			if (!this.didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
+		} else if (CompilerOptions.VERSION_1_4.equals(version)) {
+			if (this.didSpecifySource) {
+				Object source = this.options.get(CompilerOptions.OPTION_Source);
+				if (CompilerOptions.VERSION_1_3.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+				} else if (CompilerOptions.VERSION_1_4.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				}
+			} else {
+				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+			}
+		} else if (CompilerOptions.VERSION_1_5.equals(version)) {
+			if (this.didSpecifySource) {
+				Object source = this.options.get(CompilerOptions.OPTION_Source);
+				if (CompilerOptions.VERSION_1_3.equals(source)
+						|| CompilerOptions.VERSION_1_4.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				} else if (CompilerOptions.VERSION_1_5.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+				}
+			} else {
+				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+			}
+		} else if (CompilerOptions.VERSION_1_6.equals(version)) {
+			if (this.didSpecifySource) {
+				Object source = this.options.get(CompilerOptions.OPTION_Source);
+				if (CompilerOptions.VERSION_1_3.equals(source)
+						|| CompilerOptions.VERSION_1_4.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				} else if (CompilerOptions.VERSION_1_5.equals(source)
+						|| CompilerOptions.VERSION_1_6.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+				}
+			} else {
+				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
+				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+			}
+		} else if (CompilerOptions.VERSION_1_7.equals(version)) {
+			if (this.didSpecifySource) {
+				Object source = this.options.get(CompilerOptions.OPTION_Source);
+				if (CompilerOptions.VERSION_1_3.equals(source)
+						|| CompilerOptions.VERSION_1_4.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				} else if (CompilerOptions.VERSION_1_5.equals(source)
+						|| CompilerOptions.VERSION_1_6.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+				}
+			} else {
+				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
+				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+			}
+		} else if (CompilerOptions.VERSION_1_8.equals(version)) {
+			if (this.didSpecifySource) {
+				Object source = this.options.get(CompilerOptions.OPTION_Source);
+				if (CompilerOptions.VERSION_1_3.equals(source)
+						|| CompilerOptions.VERSION_1_4.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				} else if (CompilerOptions.VERSION_1_5.equals(source)
+						|| CompilerOptions.VERSION_1_6.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+				} else if (CompilerOptions.VERSION_1_8.equals(source)) {
+					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
+				}
+			} else {
+				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
+				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
+			}
+		}
+	} else if (this.didSpecifySource) {
+		Object version = this.options.get(CompilerOptions.OPTION_Source);
+		// default is source 1.3 target 1.2 and compliance 1.4
+		if (CompilerOptions.VERSION_1_4.equals(version)) {
+			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+		} else if (CompilerOptions.VERSION_1_5.equals(version)) {
+			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+		} else if (CompilerOptions.VERSION_1_6.equals(version)) {
+			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
+		} else if (CompilerOptions.VERSION_1_7.equals(version)) {
+			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
+		} else if (CompilerOptions.VERSION_1_8.equals(version)) {
+			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
+			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
+		}
+	}
+
+	final Object sourceVersion = this.options.get(CompilerOptions.OPTION_Source);
+	final Object compliance = this.options.get(CompilerOptions.OPTION_Compliance);
+	if (sourceVersion.equals(CompilerOptions.VERSION_1_8)
+			&& CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_8) {
+		// compliance must be 1.8 if source is 1.8
+		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_8)); //$NON-NLS-1$
+	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_7)
+			&& CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_7) {
+		// compliance must be 1.7 if source is 1.7
+		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
+	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_6)
+			&& CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_6) {
+		// compliance must be 1.6 if source is 1.6
+		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
+	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)
+			&& CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_5) {
+		// compliance must be 1.5 if source is 1.5
+		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
+	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)
+			&& CompilerOptions.versionToJdkLevel(compliance) < ClassFileConstants.JDK1_4) {
+		// compliance must be 1.4 if source is 1.4
+		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
+	}
+
+	// check and set compliance/source/target compatibilities
+	if (this.didSpecifyTarget) {
+		final Object targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform);
+		// tolerate jsr14 target
+		if (CompilerOptions.VERSION_JSR14.equals(targetVersion)) {
+			// expecting source >= 1.5
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) < ClassFileConstants.JDK1_5) {
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForGenericSource", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+			}
+		} else if (CompilerOptions.VERSION_CLDC1_1.equals(targetVersion)) {
+			if (this.didSpecifySource && CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4) {
+				throw new IllegalArgumentException(this.bind("configure.incompatibleSourceForCldcTarget", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+			}
+			if (CompilerOptions.versionToJdkLevel(compliance) >= ClassFileConstants.JDK1_5) {
+				throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForCldcTarget", (String) targetVersion, (String) sourceVersion)); //$NON-NLS-1$
+			}
+		} else {
+			// target must be 1.8 if source is 1.8
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_8
+					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_8){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_8)); //$NON-NLS-1$
+			}
+			// target must be 1.7 if source is 1.7
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_7
+					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_7){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
+			}
+			// target must be 1.6 if source is 1.6
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6
+					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
+			}
+			// target must be 1.5 if source is 1.5
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_5
+					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_5){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
+			}
+			// target must be 1.4 if source is 1.4
+			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4
+					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_4){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", (String) targetVersion, CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
+			}
+			// target cannot be greater than compliance level
+			if (CompilerOptions.versionToJdkLevel(compliance) < CompilerOptions.versionToJdkLevel(targetVersion)){
+				throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), (String) targetVersion)); //$NON-NLS-1$
+			}
+		}
+	}
+}
+}
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
new file mode 100644
index 0000000..803f5e8
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -0,0 +1,408 @@
+###############################################################################
+# Copyright (c) 2000, 2013 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+#		Benjamin Muskalla - Contribution for bug 239066
+#		Stephan Herrmann - Contributions for
+#								bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+#								bug 295551 - Add option to automatically promote all warnings to errors
+#								bug 359721 - [options] add command line option for new warning token "resource"
+#								bug 365208 - [compiler][batch] command line options for annotation based null analysis
+#								bug 374605 - Unreasonable warning for enum-based switch statements
+#								bug 388281 - [compiler][null] inheritance of null annotations as an option
+#		Alan Moraes <alan@kelon.org> - Contribution for bug 383644
+###############################################################################
+### JavaBatchCompiler messages.
+
+### compiler
+#Format: compiler.name = word1 word2 word3
+compiler.name = Eclipse Compiler for Java(TM)
+#Format: compiler.version = (The placeholder 'bundle_qualifier' will be automatically filled. Do not remove or alter it)
+compiler.version = bundle_qualifier, 3.9.0
+compiler.copyright = Copyright IBM Corp 2000, 2013. All rights reserved.
+
+### progress
+progress.compiling = Compiling
+
+### compile
+compile.repetition = [repetition {0}/{1}]
+compile.instantTime = [compiled {0} lines in {1} ms: {2} lines/s]
+compile.detailedTime = [parse: {0} ms ({1}%), resolve: {2} ms ({3}%), analyze: {4} ms ({5}%), generate: {6} ms ({7}%) ]
+compile.ioTime = [i/o: read: {0} ms ({1}%), write: {2} ms ({3}%)]
+compile.averageTime = [average, excluding min-max {0} lines in {1} ms: {2} lines/s]
+compile.totalTime = [total compilation time: {0}]
+compile.oneProblem = 1 problem ({0})
+compile.severalProblemsErrorsOrWarnings = {0} problems ({1})
+compile.severalProblemsErrorsAndWarnings = {0} problems ({1}, {2})
+compile.oneError = 1 error
+compile.severalErrors = {0} errors
+compile.oneWarning = 1 warning
+compile.severalWarnings = {0} warnings
+compile.oneClassFileGenerated = [1 .class file generated]
+compile.severalClassFilesGenerated = [{0} .class files generated]
+
+### configure
+configure.requiresJDK1.2orAbove = Need to use a JVM >= 1.2
+configure.duplicateLog = duplicate log specification: {0}
+configure.duplicateRepeat = duplicate repeat specification: {0}
+configure.duplicateMaxProblems = duplicate max problems specification: {0}
+configure.duplicateCompliance = duplicate compliance setting specification: {0}
+configure.duplicateSource = duplicate source compliance setting specification: {0}
+configure.duplicateTarget = duplicate target compliance setting specification: {0}
+configure.source = source level should be comprised in between ''1.3'' and ''1.8'' (or ''5'', ''5.0'', ..., ''8'' or ''8.0''): {0}
+configure.duplicateOutputPath = duplicate output path specification: {0}
+configure.duplicateBootClasspath = duplicate bootclasspath specification: {0}
+configure.duplicateExtDirs = duplicate extdirs specification: {0}
+configure.duplicateSourcepath = duplicate sourcepath specification: {0}
+configure.invalidDebugOption = invalid debug option: {0}
+configure.invalidWarningConfiguration = invalid warning configuration: ''{0}''
+configure.invalidWarning = invalid warning token: ''{0}''. Ignoring warning and compiling
+configure.invalidWarningOption = invalid warning option: ''{0}''. Must specify a warning token
+configure.targetJDK = target level should be comprised in between ''1.1'' and ''1.8'' (or ''5'', ''5.0'', ..., ''8'' or ''8.0'') or cldc1.1: {0}
+configure.incompatibleTargetForSource = Target level ''{0}'' is incompatible with source level ''{1}''. A target level ''{1}'' or better is required
+configure.incompatibleTargetForGenericSource = Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.5'' or better is required
+configure.incompatibleComplianceForSource = Compliance level ''{0}'' is incompatible with source level ''{1}''. A compliance level ''{1}'' or better is required
+configure.incompatibleComplianceForTarget = Compliance level ''{0}'' is incompatible with target level ''{1}''. A compliance level ''{1}'' or better is required
+configure.repetition = repetition must be a positive integer: {0}
+configure.maxProblems = max problems must be a positive integer: {0}
+configure.invalidNowarnOption = invalid syntax for nowarn option: {0}
+
+configure.invalidErrorConfiguration = invalid error configuration: ''{0}''
+configure.invalidError = invalid error token: ''{0}''. Ignoring this error token and compiling
+configure.invalidErrorOption = invalid error option: ''{0}''. Must specify an error token
+
+## configure.directoryNotExist = directory does not exist: {0}
+configure.unrecognizedOption = Unrecognized option : {0}
+configure.noClasspath = no classpath defined, using default directory instead
+configure.incorrectClasspath = incorrect classpath: {0}
+configure.invalidexpansionargumentname = expansion argument file {0} does not exist or cannot be read
+configure.cannotOpenLog = cannot open .log file: {0}
+configure.cannotOpenLogInvalidEncoding = cannot open .log file: {0}; because UTF-8 is not supported
+configure.unexpectedCustomEncoding = unexpected custom encoding specification: {0}[{1}]
+configure.unsupportedEncoding = unsupported encoding format: {0}
+configure.duplicateDefaultEncoding = duplicate default encoding format specification: {0}
+configure.invalidTaskTag ={0} is an invalid task tag
+configure.incorrectExtDirsEntry = incorrect ext dir entry; {0} must be a directory
+configure.incorrectEndorsedDirsEntry = incorrect endorsed dir entry; {0} must be a directory
+configure.duplicateEndorsedDirs = duplicate endorseddirs specification: {0}
+configure.incorrectDestinationPathEntry = incorrect destination path entry: {0}
+configure.unexpectedBracket = unexpected bracket: {0}
+configure.unexpectedDestinationPathEntry = unexpected destination path entry in {0} option
+configure.unexpectedDestinationPathEntryFile = unexpected destination path entry for file: {0}
+configure.accessRuleAfterDestinationPath = access rules cannot follow destination path entries: {0}
+configure.duplicateDestinationPathEntry = duplicate destination path entry in {0} option
+configure.invalidClassName = invalid class name: {0}
+configure.incorrectVMVersionforAPT = Annotation processing got disabled, since it requires a 1.6 compliant JVM
+configure.incompatibleSourceForCldcTarget=Target level ''{0}'' is incompatible with source level ''{1}''. A source level ''1.3'' or lower is required
+configure.incompatibleComplianceForCldcTarget=Target level ''{0}'' is incompatible with compliance level ''{1}''. A compliance level ''1.4''or lower is required
+configure.invalidClasspathSection = invalid Class-Path header in manifest of jar file: {0}
+configure.multipleClasspathSections = multiple Class-Path headers in manifest of jar file: {0}
+configure.missingwarningspropertiesfile=properties file {0} does not exist
+configure.ioexceptionwarningspropertiesfile=An IOException occurred while reading the properties file {0}
+configure.multipleencodings=Multiple encoding specified: {1}. The default encoding has been set to {0}
+configure.differentencodings=Found encoding {0}. Different encodings were specified: {1}
+configure.differentencoding=Found encoding {0}. A different encoding was specified: {1}
+
+### null annotations
+configure.invalidNullAnnot = Token {0} is not in the expected format "nullAnnot(<non null annotation name> | <nullable annotation name> | <non-null by default annotation name>)"
+
+### requestor
+requestor.error = {0}. ERROR in {1}
+requestor.warning = {0}. WARNING in {1}
+requestor.extraerror = {0}. ERROR:
+requestor.extrawarning = {0}. WARNING:
+requestor.notRetrieveErrorMessage = Cannot retrieve the error message for {0}
+requestor.noFileNameSpecified = (original file name is not available)
+
+### EMACS STYLE
+output.emacs.error=error
+output.emacs.warning=warning
+
+### unit
+unit.more = File {0} is specified more than once
+unit.missing = File {0} is missing
+
+### output
+output.noClassFileCreated = No .class file created for file {1} in {0} because of an IOException: {2}
+
+### miscellaneous
+misc.version = {0} {1}, {2}
+misc.usage = {1} {2}\n\
+{3}\n\
+\ \n\
+\ Usage: <options> <source files | directories>\n\
+\ If directories are specified, then their source contents are compiled.\n\
+\ Possible options are listed below. Options enabled by default are prefixed\n\
+\ with ''+''.\n\
+\ \n\
+\ Classpath options:\n\
+\    -cp -classpath <directories and ZIP archives separated by {0}>\n\
+\                       specify location for application classes and sources.\n\
+\                       Each directory or file can specify access rules for\n\
+\                       types between ''['' and '']'' (e.g. [-X] to forbid\n\
+\                       access to type X, [~X] to discourage access to type X,\n\
+\                       [+p/X{0}-p/*] to forbid access to all types in package p\n\
+\                       but allow access to p/X)\n\
+\    -bootclasspath <directories and ZIP archives separated by {0}>\n\
+\                       specify location for system classes. Each directory or\n\
+\                       file can specify access rules for types between ''[''\n\
+\                       and '']''\n\
+\    -sourcepath <directories and ZIP archives separated by {0}>\n\
+\                       specify location for application sources. Each directory\n\
+\                       or file can specify access rules for types between ''[''\n\
+\                       and '']''. Each directory can further specify a specific\n\
+\                       destination directory using a ''-d'' option between ''[''\n\
+\                       and '']''; this overrides the general ''-d'' option.\n\
+\                       .class files created from source files contained in a\n\
+\                       jar file are put in the user.dir folder in case no\n\
+\                       general ''-d'' option is specified. ZIP archives cannot\n\
+\                       override the general ''-d'' option\n\
+\    -extdirs <directories separated by {0}>\n\
+\                       specify location for extension ZIP archives\n\
+\    -endorseddirs <directories separated by {0}>\n\
+\                       specify location for endorsed ZIP archives\n\
+\    -d <dir>           destination directory (if omitted, no directory is\n\
+\                       created); this option can be overridden per source\n\
+\                       directory\n\
+\    -d none            generate no .class files\n\
+\    -encoding <enc>    specify default encoding for all source files. Each\n\
+\                       file/directory can override it when suffixed with\n\
+\                       ''[''<enc>'']'' (e.g. X.java[utf8]).\n\
+\                       If multiple default encodings are specified, the last\n\
+\                       one will be used.\n\
+\ \n\
+\ Compliance options:\n\
+\    -1.3               use 1.3 compliance (-source 1.3 -target 1.1)\n\
+\    -1.4             + use 1.4 compliance (-source 1.3 -target 1.2)\n\
+\    -1.5 -5 -5.0       use 1.5 compliance (-source 1.5 -target 1.5)\n\
+\    -1.6 -6 -6.0       use 1.6 compliance (-source 1.6 -target 1.6)\n\
+\    -1.7 -7 -7.0       use 1.7 compliance (-source 1.7 -target 1.7)\n\
+\    -1.8 -8 -8.0       use 1.8 compliance (-source 1.8 -target 1.8)\n\
+\    -source <version>  set source level: 1.3 to 1.8 (or 5, 5.0, etc)\n\
+\    -target <version>  set classfile target: 1.1 to 1.8 (or 5, 5.0, etc)\n\
+\                       cldc1.1 can also be used to generate the StackMap\n\
+\                       attribute\n\
+\ \n\
+\ Warning options:\n\
+\    -deprecation     + deprecation outside deprecated code (equivalent to\n\
+\                       -warn:+deprecation)\n\
+\    -nowarn -warn:none disable all warnings\n\
+\    -nowarn:[<directories separated by {0}>]\n\
+\                       specify directories from which optional problems should\n\
+\                       be ignored\n\
+\    -?:warn -help:warn display advanced warning options\n\
+\ \n\
+\ Error options:\n\
+\    -err:<warnings separated by ,>    convert exactly the listed warnings\n\
+\                                      to be reported as errors\n\
+\    -err:+<warnings separated by ,>   enable additional warnings to be\n\
+\                                      reported as errors\n\
+\    -err:-<warnings separated by ,>   disable specific warnings to be\n\
+\                                      reported as errors\n\
+\ \n\
+\ Setting warning or error options using properties file:\n\
+\    -properties <file>   set warnings/errors option based on the properties\n\
+\                          file contents. This option can be used with -nowarn,\n\
+\                          -err:.. or -warn:.. options, but the last one on the\n\
+\                          command line sets the options to be used.\n\
+\ \n\
+\ Debug options:\n\
+\    -g[:lines,vars,source] custom debug info\n\
+\    -g:lines,source  + both lines table and source debug info\n\
+\    -g                 all debug info\n\
+\    -g:none            no debug info\n\
+\    -preserveAllLocals preserve unused local vars for debug purpose\n\
+\ \n\
+\ Annotation processing options:\n\
+\   These options are meaningful only in a 1.6 environment.\n\
+\    -Akey[=value]        options that are passed to annotation processors\n\
+\    -processorpath <directories and ZIP archives separated by {0}>\n\
+\                         specify locations where to find annotation processors.\n\
+\                         If this option is not used, the classpath will be\n\
+\                         searched for processors\n\
+\    -processor <class1[,class2,...]>\n\
+\                         qualified names of the annotation processors to run.\n\
+\                         This bypasses the default annotation discovery process\n\
+\    -proc:only           run annotation processors, but do not compile\n\
+\    -proc:none           perform compilation but do not run annotation\n\
+\                         processors\n\
+\    -s <dir>             destination directory for generated source files\n\
+\    -XprintProcessorInfo print information about which annotations and elements\n\
+\                         a processor is asked to process\n\
+\    -XprintRounds        print information about annotation processing rounds\n\
+\    -classNames <className1[,className2,...]>\n\
+\                         qualified names of binary classes to process\n\
+\ \n\
+\ Advanced options:\n\
+\    @<file>            read command line arguments from file\n\
+\    -maxProblems <n>   max number of problems per compilation unit (100 by\n\
+\                       default)\n\
+\    -log <file>        log to a file. If the file extension is ''.xml'', then\n\
+\                       the log will be a xml file.\n\
+\    -proceedOnError[:Fatal]\n\
+\                       do not stop at first error, dumping class files with\n\
+\                       problem methods\n\
+\                       With ":Fatal", all optional errors are treated as fatal\n\
+\    -verbose           enable verbose output\n\
+\    -referenceInfo     compute reference info\n\
+\    -progress          show progress (only in -log mode)\n\
+\    -time              display speed information \n\
+\    -noExit            do not call System.exit(n) at end of compilation (n==0\n\
+\                       if no error)\n\
+\    -repeat <n>        repeat compilation process <n> times for perf analysis\n\
+\    -inlineJSR         inline JSR bytecode (implicit if target >= 1.5)\n\
+\    -enableJavadoc     consider references in javadoc\n\
+\    -Xemacs            used to enable emacs-style output in the console.\n\
+\                       It does not affect the xml log output\n\
+\    -missingNullDefault  report missing default nullness annotation\n\
+\ \n\
+\    -? -help           print this help message\n\
+\    -v -version        print compiler version\n\
+\    -showversion       print compiler version and continue\n\
+\ \n\
+\ Ignored options:\n\
+\    -J<option>         pass option to virtual machine (ignored)\n\
+\    -X<option>         specify non-standard option (ignored\n\
+\                       except for listed -X options)\n\
+\    -X                 print non-standard options and exit (ignored)\n\
+\    -O                 optimize for execution time (ignored)\n
+misc.usage.warn = {1} {2}\n\
+{3}\n\
+\ \n\
+\ Warning options:\n\
+\    -deprecation         + deprecation outside deprecated code\n\
+\    -nowarn -warn:none disable all warnings\n\
+\    -nowarn:[<directories separated by {0}>]\n\
+\                       specify directories from which optional problems should\n\
+\                       be ignored\n\
+\    -warn:<warnings separated by ,>    enable exactly the listed warnings\n\
+\    -warn:+<warnings separated by ,>   enable additional warnings\n\
+\    -warn:-<warnings separated by ,>   disable specific warnings\n\
+\      all                  enable all warnings\n\
+\      allDeadCode          dead code including trivial if(DEBUG) check\n\
+\      allDeprecation       deprecation including inside deprecated code\n\
+\      allJavadoc           invalid or missing javadoc\n\
+\      allOver-ann          all missing @Override annotations\n\
+\      all-static-method    all method can be declared as static warnings\n\
+\      assertIdentifier   + ''assert'' used as identifier\n\
+\      boxing               autoboxing conversion\n\
+\      charConcat         + char[] in String concat\n\
+\      compareIdentical   + comparing identical expressions\n\
+\      conditionAssign      possible accidental boolean assignment\n\
+\      constructorName    + method with constructor name\n\
+\      deadCode           + dead code excluding trivial if (DEBUG) check\n\
+\      dep-ann              missing @Deprecated annotation\n\
+\      deprecation        + deprecation outside deprecated code\n\
+\      discouraged        + use of types matching a discouraged access rule\n\
+\      emptyBlock           undocumented empty block\n\
+\      enumIdentifier       ''enum'' used as identifier\n\
+\      enumSwitch           incomplete enum switch\n\
+\      enumSwitchPedantic + report missing enum switch cases even\n\
+\                           in the presence of a default case\n\
+\      fallthrough          possible fall-through case\n\
+\      fieldHiding          field hiding another variable\n\
+\      finalBound           type parameter with final bound\n\
+\      finally            + finally block not completing normally\n\
+\      forbidden          + use of types matching a forbidden access rule\n\
+\      hashCode              missing hashCode() method when overriding equals()\n\
+\      hiding               macro for fieldHiding, localHiding, typeHiding and\n\
+\                           maskedCatchBlock\n\
+\      includeAssertNull    raise null warnings for variables\n\
+\                           that got tainted in an assert expression\n\
+\      indirectStatic       indirect reference to static member\n\
+\      inheritNullAnnot     inherit null annotations\n\
+\      intfAnnotation     + annotation type used as super interface\n\
+\      intfNonInherited   + interface non-inherited method compatibility\n\
+\      intfRedundant        find redundant superinterfaces\n\
+\      invalidJavadoc       all warnings for malformed javadoc tags\n\
+\      invalidJavadocTag    validate javadoc tag arguments\n\
+\      invalidJavadocTagDep validate deprecated references in javadoc tag args\n\
+\      invalidJavadocTagNotVisible  validate non-visible references in javadoc\n\
+\							tag args\n\
+\      invalidJavadocVisibility(<visibility>)  specify visibility modifier\n\
+\							for malformed javadoc tag warnings\n\
+\      javadoc              invalid javadoc\n\
+\      localHiding          local variable hiding another variable\n\
+\      maskedCatchBlock   + hidden catch block\n\
+\      missingJavadocTags   missing Javadoc tags\n\
+\      missingJavadocTagsOverriding missing Javadoc tags in overriding methods\n\
+\      missingJavadocTagsMethod missing Javadoc tags for method type parameter\n\
+\      missingJavadocTagsVisibility(<visibility>)  specify visibility modifier\n\
+\							for missing javadoc tags warnings\n\
+\      missingJavadocComments   missing Javadoc comments\n\
+\      missingJavadocCommentsOverriding   missing Javadoc tags in overriding\n\
+\							methods\n\
+\      missingJavadocCommentsVisibility(<visibility>)  specify visibility\n\
+\							modifier for missing javadoc comments warnings\n\
+\      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n\
+\      noEffectAssign     + assignment without effect\n\
+\      null                 potential missing or redundant null check\n\
+\      nullAnnot(<annot. names separated by |>)   annotation based null analysis,\n\
+\                           nullable|nonnull|nonnullbydefault annotation types\n\
+\                           optionally specified using fully qualified names.\n\
+\							Enabling this option enables all null-annotation\n\
+\							related sub-options. These can be individually\n\
+\							controlled using options listed below.\n\
+\      nullAnnotConflict    conflict between null annotation specified\n\
+\							and nullness inferred. Is effective only with\n\
+\							nullAnnot option enabled.\n\
+\      nullAnnotRedundant   redundant specification of null annotation. Is\n\
+\							effective only with nullAnnot option enabled.\n\
+\      nullDereference    + missing null check\n\
+\	   nullUncheckedConversion unchecked conversion from non-annotated type\n\
+\							to @NonNull type. Is effective only with\n\
+\							nullAnnot option enabled.\n\
+\      over-ann             missing @Override annotation (superclass)\n\
+\      paramAssign          assignment to a parameter\n\
+\      pkgDefaultMethod   + attempt to override package-default method\n\
+\      raw                + usage of raw type\n\
+\      resource           + (pot.) unsafe usage of resource of type Closeable\n\
+\      semicolon            unnecessary semicolon, empty statement\n\
+\      serial             + missing serialVersionUID\n\
+\      specialParamHiding   constructor or setter parameter hiding a field\n\
+\      static-method        method can be declared as static\n\
+\      static-access        macro for indirectStatic and staticReceiver\n\
+\      staticReceiver     + non-static reference to static member\n\
+\      super                overriding a method without making a super invocation\n\
+\      suppress           + enable @SuppressWarnings\n\
+\                           When used with -err:, it can also silent optional\n\
+\                           errors and warnings\n\
+\      switchDefault      + switch statement lacking a default case\n\
+\      syncOverride         missing synchronized in synchr. method override\n\
+\      syntheticAccess      synthetic access for innerclass\n\
+\      tasks(<tags separated by |>) tasks identified by tags inside comments\n\
+\      typeHiding         + type parameter hiding another type\n\
+\      unavoidableGenericProblems + ignore unavoidable type safety problems\n\
+\                                   due to raw APIs\n\
+\      unchecked          + unchecked type operation\n\
+\      unnecessaryElse      unnecessary else clause\n\
+\      unqualifiedField     unqualified reference to field\n\
+\      unused               macro for unusedAllocation, unusedArgument,\n\
+\                               unusedImport, unusedLabel, unusedLocal,\n\
+\                               unusedPrivate, unusedThrown, and unusedTypeArgs\n\
+\      unusedAllocation     allocating an object that is not used\n\
+\      unusedArgument       unread method parameter\n\
+\      unusedImport       + unused import declaration\n\
+\      unusedLabel        + unused label\n\
+\      unusedLocal        + unread local variable\n\
+\      unusedParam		    unused parameter\n\
+\      unusedParamOverriding unused parameter for overriding method\n\
+\      unusedParamImplementing unused parameter for implementing method\n\
+\      unusedParamIncludeDoc unused parameter documented in comment tag\n\
+\      unusedPrivate      + unused private member declaration\n\
+\      unusedThrown         unused declared thrown exception\n\
+\      unusedThrownWhenOverriding unused declared thrown exception in \n\
+\							overriding method\n\
+\      unusedThrownIncludeDocComment     unused declared thrown exception,\n\
+\							documented in a comment tag\n\
+\      unusedThrownExemptExceptionThrowable  unused declared thrown exception,\n\
+\							exempt Exception and Throwable\n\
+\      unusedTypeArgs     + unused type arguments for method and constructor\n\
+\      uselessTypeCheck     unnecessary cast/instanceof operation\n\
+\      varargsCast        + varargs argument need explicit cast\n\
+\      warningToken       + unsupported or unnecessary @SuppressWarnings\n
diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties
new file mode 100644
index 0000000..8e3f678
--- /dev/null
+++ b/org.eclipse.jdt.core/build.properties
@@ -0,0 +1,44 @@
+###############################################################################
+# Copyright (c) 2000, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+customBuildCallbacks=customBuildCallbacks.xml
+customBuildCallbacks.inheritall=true
+bin.includes = plugin.xml,\
+               plugin.properties,\
+               about.html,\
+               .,\
+               jdtCompilerAdapter.jar,\
+               .options,\
+               META-INF/
+javadoc.packages = org.eclipse.jdt.core.*,\
+                   org.eclipse.jdt.core.formatter.*,\
+                   org.eclipse.jdt.core.compiler.*,\
+                   org.eclipse.jdt.core.eval.*,\
+                   org.eclipse.jdt.core.jdom.*,\
+                   org.eclipse.jdt.core.dom.*,\
+                   org.eclipse.jdt.core.dom.rewrite.*,\
+                   org.eclipse.jdt.core.search.*,\
+                   org.eclipse.jdt.core.index.*
+source.. =   batch/,\
+	         codeassist/,\
+	         compiler/,\
+	         eval/,\
+	         formatter/,\
+	         dom/,\
+	         search/,\
+	         model/
+output.. = bin/
+output.jdtCompilerAdapter.jar = antbin/
+source.jdtCompilerAdapter.jar = antadapter/
+jars.compile.order=.,jdtCompilerAdapter.jar
+jars.extra.classpath=platform:/plugin/org.apache.ant/lib/ant.jar
+src.includes = about.html,\
+               schema/
+generateSourceReferences=true
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java
new file mode 100644
index 0000000..99427f5
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionElementNotifier.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnAnnotationOfType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnArgumentName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnImportReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword2;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodReturnType;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodTypeParameter;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnPackageReference;
+import org.eclipse.jdt.internal.compiler.SourceElementNotifier;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+
+public class CompletionElementNotifier extends SourceElementNotifier {
+
+	private ASTNode assistNode;
+
+	public CompletionElementNotifier(
+			CompletionUnitStructureRequestor requestor,
+			boolean reportLocalDeclarations,
+			ASTNode assistNode) {
+		super(requestor, reportLocalDeclarations);
+		this.assistNode = assistNode;
+	}
+
+	protected char[][][] getArguments(Argument[] arguments) {
+		int argumentLength = arguments.length;
+		char[][] argumentTypes = new char[argumentLength][];
+		char[][] argumentNames = new char[argumentLength][];
+		int argumentCount = 0;
+		next : for (int i = 0; i < argumentLength; i++) {
+			Argument argument = arguments[i];
+
+			if (argument instanceof CompletionOnArgumentName && argument.name.length == 0) continue next;
+
+			argumentTypes[argumentCount] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.');
+			argumentNames[argumentCount++] = argument.name;
+		}
+
+		if (argumentCount < argumentLength) {
+			System.arraycopy(argumentTypes, 0, argumentTypes = new char[argumentCount][], 0, argumentCount);
+			System.arraycopy(argumentNames, 0, argumentNames = new char[argumentCount][], 0, argumentCount);
+		}
+
+		return new char[][][] {argumentTypes, argumentNames};
+	}
+
+	protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) {
+		char[][] interfaceNames = null;
+		int superInterfacesLength = 0;
+		TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			superInterfacesLength = superInterfaces.length;
+			interfaceNames = new char[superInterfacesLength][];
+		} else {
+			if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+				// see PR 3442
+				QualifiedAllocationExpression alloc = typeDeclaration.allocation;
+				if (alloc != null && alloc.type != null) {
+					superInterfaces = new TypeReference[] { alloc.type};
+					superInterfacesLength = 1;
+					interfaceNames = new char[1][];
+				}
+			}
+		}
+		if (superInterfaces != null) {
+			int superInterfaceCount = 0;
+			next: for (int i = 0; i < superInterfacesLength; i++) {
+				TypeReference superInterface = superInterfaces[i];
+
+				if (superInterface instanceof CompletionOnKeyword) continue next;
+				if (CompletionUnitStructureRequestor.hasEmptyName(superInterface, this.assistNode)) continue next;
+
+				interfaceNames[superInterfaceCount++] = CharOperation.concatWith(superInterface.getParameterizedTypeName(), '.');
+			}
+
+			if (superInterfaceCount == 0) return null;
+			if (superInterfaceCount < superInterfacesLength) {
+				System.arraycopy(interfaceNames, 0, interfaceNames = new char[superInterfaceCount][], 0, superInterfaceCount);
+			}
+		}
+		return interfaceNames;
+	}
+
+	protected char[] getSuperclassName(TypeDeclaration typeDeclaration) {
+		TypeReference superclass = typeDeclaration.superclass;
+
+		if (superclass instanceof CompletionOnKeyword) return null;
+		if (CompletionUnitStructureRequestor.hasEmptyName(superclass, this.assistNode)) return null;
+
+		return superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null;
+	}
+
+	protected char[][] getThrownExceptions(AbstractMethodDeclaration methodDeclaration) {
+		char[][] thrownExceptionTypes = null;
+		TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+		if (thrownExceptions != null) {
+			int thrownExceptionLength = thrownExceptions.length;
+			int thrownExceptionCount = 0;
+			thrownExceptionTypes = new char[thrownExceptionLength][];
+			next : for (int i = 0; i < thrownExceptionLength; i++) {
+				TypeReference thrownException = thrownExceptions[i];
+
+				if (thrownException instanceof CompletionOnKeyword) continue next;
+				if (CompletionUnitStructureRequestor.hasEmptyName(thrownException, this.assistNode)) continue next;
+
+				thrownExceptionTypes[thrownExceptionCount++] =
+					CharOperation.concatWith(thrownException.getParameterizedTypeName(), '.');
+			}
+
+			if (thrownExceptionCount == 0) return null;
+			if (thrownExceptionCount < thrownExceptionLength) {
+				System.arraycopy(thrownExceptionTypes, 0, thrownExceptionTypes = new char[thrownExceptionCount][], 0, thrownExceptionCount);
+			}
+		}
+		return thrownExceptionTypes;
+	}
+
+	protected char[][] getTypeParameterBounds(TypeParameter typeParameter) {
+		TypeReference firstBound = typeParameter.type;
+		TypeReference[] otherBounds = typeParameter.bounds;
+		char[][] typeParameterBounds = null;
+		if (firstBound != null) {
+			if (otherBounds != null) {
+				int otherBoundsLength = otherBounds.length;
+				char[][] boundNames = new char[otherBoundsLength+1][];
+				int boundCount = 0;
+				if (!CompletionUnitStructureRequestor.hasEmptyName(firstBound, this.assistNode)) {
+					boundNames[boundCount++] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.');
+				}
+				for (int j = 0; j < otherBoundsLength; j++) {
+					TypeReference otherBound = otherBounds[j];
+					if (!CompletionUnitStructureRequestor.hasEmptyName(otherBound, this.assistNode)) {
+						boundNames[boundCount++] =
+							CharOperation.concatWith(otherBound.getParameterizedTypeName(), '.');
+					}
+				}
+
+				if (boundCount == 0) {
+					boundNames = CharOperation.NO_CHAR_CHAR;
+				} else if (boundCount < otherBoundsLength + 1){
+					System.arraycopy(boundNames, 0, boundNames = new char[boundCount][], 0, boundCount);
+				}
+				typeParameterBounds = boundNames;
+			} else {
+				if (!CompletionUnitStructureRequestor.hasEmptyName(firstBound, this.assistNode)) {
+					typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')};
+				} else {
+					typeParameterBounds = CharOperation.NO_CHAR_CHAR;
+				}
+			}
+		} else {
+			typeParameterBounds = CharOperation.NO_CHAR_CHAR;
+		}
+
+		return typeParameterBounds;
+	}
+
+	protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {
+		if (methodDeclaration instanceof CompletionOnMethodReturnType) return;
+		if (methodDeclaration instanceof CompletionOnMethodTypeParameter) return;
+		if (methodDeclaration instanceof CompletionOnMethodName) return;
+		super.notifySourceElementRequestor(methodDeclaration, declaringType, currentPackage);
+	}
+
+	public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit, int sourceStart, int sourceEnd, boolean reportReference, HashtableOfObjectToInt sourceEndsMap, Map nodesToCategoriesMap) {
+		super.notifySourceElementRequestor(parsedUnit, sourceStart, sourceEnd, reportReference, sourceEndsMap, nodesToCategoriesMap);
+	}
+
+	protected void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) {
+		if (fieldDeclaration instanceof CompletionOnFieldType) return;
+		if (fieldDeclaration instanceof CompletionOnFieldName) return;
+		super.notifySourceElementRequestor(fieldDeclaration, declaringType);
+	}
+
+	protected void notifySourceElementRequestor(ImportReference importReference, boolean isPackage) {
+		if (importReference instanceof CompletionOnKeyword2) return;
+		if (importReference instanceof CompletionOnImportReference ||
+				importReference instanceof CompletionOnPackageReference) {
+			if (importReference.tokens[importReference.tokens.length - 1].length == 0) return;
+		}
+
+		super.notifySourceElementRequestor(importReference, isPackage);
+	}
+
+	protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {
+		if (typeDeclaration instanceof CompletionOnAnnotationOfType) return;
+		super.notifySourceElementRequestor(typeDeclaration, notifyTypePresence, declaringType, currentPackage);
+	}
+}
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
new file mode 100644
index 0000000..96a93bc
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -0,0 +1,12883 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionFlags;
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.codeassist.complete.*;
+import org.eclipse.jdt.internal.codeassist.impl.AssistParser;
+import org.eclipse.jdt.internal.codeassist.impl.Engine;
+import org.eclipse.jdt.internal.codeassist.impl.Keywords;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.core.BasicCompilationUnit;
+import org.eclipse.jdt.internal.core.INamingRequestor;
+import org.eclipse.jdt.internal.core.InternalNamingConventions;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.SourceMethod;
+import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
+import org.eclipse.jdt.internal.core.SourceType;
+import org.eclipse.jdt.internal.core.BinaryTypeConverter;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This class is the entry point for source completions.
+ * It contains two public APIs used to call CodeAssist on a given source with
+ * a given environment, assisting position and storage (and possibly options).
+ */
+public final class CompletionEngine
+	extends Engine
+	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
+	
+	private static class AcceptedConstructor {
+		public int modifiers;
+		public char[] simpleTypeName;
+		public int parameterCount;
+		public char[] signature;
+		public char[][] parameterTypes;
+		public char[][] parameterNames;
+		public int typeModifiers;
+		public char[] packageName;
+		public int extraFlags;
+		public int accessibility;
+		public boolean proposeType = false;
+		public boolean proposeConstructor = false;
+		public char[] fullyQualifiedName = null;
+		
+		public boolean mustBeQualified = false;
+		
+		public AcceptedConstructor(
+				int modifiers,
+				char[] simpleTypeName,
+				int parameterCount,
+				char[] signature,
+				char[][] parameterTypes,
+				char[][] parameterNames,
+				int typeModifiers,
+				char[] packageName,
+				int extraFlags,
+				int accessibility) {
+			this.modifiers = modifiers;
+			this.simpleTypeName = simpleTypeName;
+			this.parameterCount = parameterCount;
+			this.signature = signature;
+			this.parameterTypes = parameterTypes;
+			this.parameterNames = parameterNames;
+			this.typeModifiers = typeModifiers;
+			this.packageName = packageName;
+			this.extraFlags = extraFlags;
+			this.accessibility = accessibility;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('{');
+			buffer.append(this.packageName);
+			buffer.append(',');
+			buffer.append(this.simpleTypeName);
+			buffer.append('}');
+			return buffer.toString();
+		}
+	}
+	
+	private static class AcceptedType {
+		public char[] packageName;
+		public char[] simpleTypeName;
+		public char[][] enclosingTypeNames;
+		public int modifiers;
+		public int accessibility;
+		public boolean mustBeQualified = false;
+
+		public char[] fullyQualifiedName = null;
+		public char[] qualifiedTypeName = null;
+		public AcceptedType(
+			char[] packageName,
+			char[] simpleTypeName,
+			char[][] enclosingTypeNames,
+			int modifiers,
+			int accessibility) {
+			this.packageName = packageName;
+			this.simpleTypeName = simpleTypeName;
+			this.enclosingTypeNames = enclosingTypeNames;
+			this.modifiers = modifiers;
+			this.accessibility = accessibility;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('{');
+			buffer.append(this.packageName);
+			buffer.append(',');
+			buffer.append(this.simpleTypeName);
+			buffer.append(',');
+			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
+			buffer.append('}');
+			return buffer.toString();
+		}
+	}
+	
+	public class CompletionProblemFactory extends DefaultProblemFactory {
+		private int lastErrorStart;
+
+		private boolean checkProblems = false;
+		public boolean hasForbiddenProblems = false;
+		public boolean hasAllowedProblems = false;
+
+		public CompletionProblemFactory(Locale loc) {
+			super(loc);
+		}
+
+		private CategorizedProblem checkProblem(CategorizedProblem pb,
+			char[] originatingFileName,	int severity, int start) {
+			int id = pb.getID();
+			if (CompletionEngine.this.actualCompletionPosition > start
+				&& this.lastErrorStart < start
+				&& pb.isError()
+				&& (id & IProblem.Syntax) == 0
+				&& (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) {
+
+				CompletionEngine.this.problem = pb;
+				this.lastErrorStart = start;
+			}
+			if (this.checkProblems && !this.hasForbiddenProblems) {
+				switch (id) {
+					case IProblem.UsingDeprecatedType:
+						this.hasForbiddenProblems =
+							CompletionEngine.this.options.checkDeprecation;
+						break;
+					case IProblem.NotVisibleType:
+						this.hasForbiddenProblems =
+							CompletionEngine.this.options.checkVisibility;
+						break;
+					case IProblem.ForbiddenReference:
+						this.hasForbiddenProblems =
+							CompletionEngine.this.options.checkForbiddenReference;
+						break;
+					case IProblem.DiscouragedReference:
+						this.hasForbiddenProblems =
+							CompletionEngine.this.options.checkDiscouragedReference;
+						break;
+					default:
+						if ((severity & ProblemSeverities.Optional) != 0) {
+							this.hasAllowedProblems = true;
+						} else {
+							this.hasForbiddenProblems = true;
+						}
+
+						break;
+				}
+			}
+
+			return pb;
+		}
+
+		public CategorizedProblem createProblem(
+				char[] originatingFileName,
+				int problemId,
+				String[] problemArguments,
+				int elaborationId,
+				String[] messageArguments,
+				int severity,
+				int start,
+				int end,
+				int lineNumber,
+				int columnNumber) {
+				return checkProblem(
+					super.createProblem(
+						originatingFileName,
+						problemId,
+						problemArguments,
+						elaborationId,
+						messageArguments,
+						severity,
+						start,
+						end,
+						lineNumber,
+						columnNumber), originatingFileName, severity, start);
+		}
+
+		public CategorizedProblem createProblem(
+				char[] originatingFileName,
+				int problemId,
+				String[] problemArguments,
+				String[] messageArguments,
+				int severity,
+				int start,
+				int end,
+				int lineNumber,
+				int columnNumber) {
+				return checkProblem(
+					super.createProblem(
+						originatingFileName,
+						problemId,
+						problemArguments,
+						messageArguments,
+						severity,
+						start,
+						end,
+						lineNumber,
+						columnNumber), originatingFileName, severity, start);
+		}
+
+		public void startCheckingProblems() {
+			this.checkProblems = true;
+			this.hasForbiddenProblems = false;
+			this.hasAllowedProblems = false;
+		}
+
+		public void stopCheckingProblems() {
+			this.checkProblems = false;
+		}
+	}
+	
+	public static char[] createBindingKey(char[] packageName, char[] typeName) {
+		char[] signature = createTypeSignature(packageName, typeName);
+		CharOperation.replace(signature, '.', '/');
+		return signature;
+	}
+
+	public static char[][] createDefaultParameterNames(int length) {
+		char[][] parameters;
+		switch (length) {
+			case 0 :
+				parameters = new char[length][];
+				break;
+			case 1 :
+				parameters = ARGS1;
+				break;
+			case 2 :
+				parameters = ARGS2;
+				break;
+			case 3 :
+				parameters = ARGS3;
+				break;
+			case 4 :
+				parameters = ARGS4;
+				break;
+			default :
+				parameters = new char[length][];
+				for (int i = 0; i < length; i++) {
+					parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
+				}
+				break;
+		}
+		return parameters;
+	}
+	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
+		char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
+		for (int i = 0; i < parameterTypeSignature.length; i++) {
+			parameterTypeSignature[i] =
+				Signature.createCharArrayTypeSignature(
+						CharOperation.concat(
+								parameterPackageNames[i],
+								CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
+		}
+
+		return Signature.createMethodSignature(
+				parameterTypeSignature,
+				returnTypeSignature);
+	}
+
+	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
+		char[] returnTypeSignature =
+			returnTypeName == null || returnTypeName.length == 0
+			? Signature.createCharArrayTypeSignature(VOID, true)
+			: Signature.createCharArrayTypeSignature(
+					CharOperation.concat(
+							returnPackagename,
+							CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
+
+		return createMethodSignature(
+				parameterPackageNames,
+				parameterTypeNames,
+				returnTypeSignature);
+	}
+	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+		return Signature.createCharArrayTypeSignature(
+				CharOperation.concat(
+						qualifiedPackageName,
+						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
+	}
+
+	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+		char[] name = new char[qualifiedTypeName.length];
+		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
+
+		int depth = 0;
+		int length = name.length;
+		for (int i = length -1; i >= 0; i--) {
+			switch (name[i]) {
+				case '.':
+					if (depth == 0 && name[i - 1] != '>') {
+						name[i] = '$';
+					}
+					break;
+				case '<':
+					depth--;
+					break;
+				case '>':
+					depth++;
+					break;
+			}
+		}
+		return Signature.createCharArrayTypeSignature(
+				CharOperation.concat(
+						qualifiedPackageName,
+						name, '.'), true);
+	}
+
+	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
+		char[] result = null;
+		StringBuffer sig = new StringBuffer(10);
+
+		sig.append(typeBinding.signature());
+
+		int sigLength = sig.length();
+		result = new char[sigLength];
+		sig.getChars(0, sigLength, result, 0);
+		result = CharOperation.replaceOnCopy(result, '/', '.');
+		return result;
+	}
+	
+	private static char[] getTypeName(TypeReference typeReference) {
+		char[] typeName = CharOperation.concatWith(typeReference.getTypeName(), '.');
+		int dims = typeReference.dimensions();
+		if (dims > 0) {
+			int length = typeName.length;
+			int newLength = length + (dims*2);
+			System.arraycopy(typeName, 0, typeName = new char[newLength], 0, length);
+			for (int k = length; k < newLength; k += 2) {
+				typeName[k] = '[';
+				typeName[k+1] = ']';
+			}
+		}
+		
+		return typeName;
+	}
+	
+	private static boolean hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope) {
+		ReferenceBinding[] memberTypes = typeBinding.memberTypes();
+		int length = memberTypes == null ? 0 : memberTypes.length;
+		next : for (int i = 0; i < length; i++) {
+			ReferenceBinding memberType = memberTypes[i];
+			if (invocationType != null && !memberType.canBeSeenBy(typeBinding, invocationType)) {
+				continue next;
+			} else if(invocationType == null && !memberType.canBeSeenBy(unitScope.fPackage)) {
+				continue next;
+			}
+			
+			if ((memberType.modifiers & ClassFileConstants.AccStatic) != 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private static boolean hasMemberTypesInEnclosingScope(SourceTypeBinding typeBinding, Scope scope) {
+		ReferenceBinding[] memberTypes = typeBinding.memberTypes();
+		int length = memberTypes == null ? 0 : memberTypes.length;
+		
+		if (length > 0) {
+			MethodScope methodScope = scope.methodScope();
+			if (methodScope != null && !methodScope.isStatic) {
+				ClassScope classScope = typeBinding.scope;
+				Scope currentScope = scope;
+				while (currentScope != null) {
+					if (currentScope == classScope) {
+						return true;
+					}
+					currentScope = currentScope.parent;
+				}
+			}
+		}
+		return false;
+	}
+	
+	public HashtableOfObject typeCache;
+	public int openedBinaryTypes; // used during InternalCompletionProposal#findConstructorParameterNames()
+	
+	public static boolean DEBUG = false;
+	public static boolean PERF = false;
+	
+	private static final char[] KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS = new char[]{};
+	private static final char[] KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS = new char[]{};
+	
+	private static final char[] ARG = "arg".toCharArray();  //$NON-NLS-1$
+	private static final char[] ARG0 = "arg0".toCharArray();  //$NON-NLS-1$
+	private static final char[] ARG1 = "arg1".toCharArray();  //$NON-NLS-1$
+	private static final char[] ARG2 = "arg2".toCharArray();  //$NON-NLS-1$
+	private static final char[] ARG3 = "arg3".toCharArray();  //$NON-NLS-1$
+	private static final char[][] ARGS1 = new char[][]{ARG0};
+	private static final char[][] ARGS2 = new char[][]{ARG0, ARG1};
+	private static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2};
+	private static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3};
+	
+	private final static int CHECK_CANCEL_FREQUENCY = 50;
+	
+	// temporary constants to quickly disabled polish features if necessary
+	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
+	
+	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
+	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
+	private final static char[] SEMICOLON = new char[] { ';' };
+
+	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
+	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
+	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
+	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
+	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
+	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
+	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
+	private final static char[] DEFAULT_CONSTRUCTOR_SIGNATURE = "()V".toCharArray();  //$NON-NLS-1$
+	
+	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
+
+	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
+	
+	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
+	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
+	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
+	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$
+
+	private final static char[] JAVA_LANG_OBJECT_SIGNATURE =
+		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
+	private final static char[] JAVA_LANG_NAME =
+		CharOperation.concatWith(JAVA_LANG, '.');
+	
+	private final static int NONE = 0;
+	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;
+	boolean hasJavaLangObjectAsExpectedType = false;
+	boolean hasExpectedArrayTypes = false;
+	boolean hasComputedExpectedArrayTypes = false;
+	int uninterestingBindingsPtr = -1;
+	Binding[] uninterestingBindings = new Binding[1];
+	int forbbidenBindingsPtr = -1;
+	Binding[] forbbidenBindings = new Binding[1];
+	int uninterestingBindingsFilter;     // only set when completing on an exception type
+	
+	ImportBinding[] favoriteReferenceBindings;
+	
+	boolean assistNodeIsClass;
+	boolean assistNodeIsEnum;
+	boolean assistNodeIsException;
+	boolean assistNodeIsInterface;
+	boolean assistNodeIsAnnotation;
+	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
+	boolean assistNodeIsString = false;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476
+	
+	long targetedElement;
+	
+	WorkingCopyOwner owner;
+	IProgressMonitor monitor;
+	IJavaProject javaProject;
+	ITypeRoot typeRoot;
+	CompletionParser parser;
+	CompletionRequestor requestor;
+	CompletionProblemFactory problemFactory;
+	ProblemReporter problemReporter;
+	private JavaSearchNameEnvironment noCacheNameEnvironment;
+	char[] source;
+	char[] completionToken;
+	char[] qualifiedCompletionToken;
+	boolean resolvingImports = false;
+	boolean resolvingStaticImports = false;
+	boolean insideQualifiedReference = false;
+	boolean noProposal = true;
+	CategorizedProblem problem = null;
+	char[] fileName = null;
+	int startPosition, actualCompletionPosition, endPosition, offset;
+	int tokenStart, tokenEnd;
+	int javadocTagPosition; // Position of previous tag while completing in javadoc
+	HashtableOfObject knownPkgs = new HashtableOfObject(10);
+	HashtableOfObject knownTypes = new HashtableOfObject(10);
+	
+ 	/*
+		static final char[][] mainDeclarations =
+			new char[][] {
+				"package".toCharArray(),
+				"import".toCharArray(),
+				"abstract".toCharArray(),
+				"final".toCharArray(),
+				"public".toCharArray(),
+				"class".toCharArray(),
+				"interface".toCharArray()};
+
+		static final char[][] modifiers = // may want field, method, type & member type modifiers
+			new char[][] {
+				"abstract".toCharArray(),
+				"final".toCharArray(),
+				"native".toCharArray(),
+				"public".toCharArray(),
+				"protected".toCharArray(),
+				"private".toCharArray(),
+				"static".toCharArray(),
+				"strictfp".toCharArray(),
+				"synchronized".toCharArray(),
+				"transient".toCharArray(),
+				"volatile".toCharArray()};
+	*/
+	static final BaseTypeBinding[] BASE_TYPES = {
+		TypeBinding.BOOLEAN,
+		TypeBinding.BYTE,
+		TypeBinding.CHAR,
+		TypeBinding.DOUBLE,
+		TypeBinding.FLOAT,
+		TypeBinding.INT,
+		TypeBinding.LONG,
+		TypeBinding.SHORT,
+		TypeBinding.VOID
+	};
+	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
+	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
+	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
+	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
+	static {
+ 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
+ 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
+ 		}
+		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
+			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
+		}
+ 	}
+	
+	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
+	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
+	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
+	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
+	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$
+
+	static InvocationSite FakeInvocationSite = new InvocationSite(){
+		public TypeBinding[] genericTypeArguments() { return null; }
+		public boolean isSuperAccess(){ return false; }
+		public boolean isTypeAccess(){ return false; }
+		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
+		public void setDepth(int depth){/* empty */}
+		public void setFieldIndex(int depth){/* empty */}
+		public int sourceEnd() { return 0; 	}
+		public int sourceStart() { return 0; 	}
+		public TypeBinding expectedType() { return null; }
+		public boolean receiverIsImplicitThis() { return false;}
+	};
+
+	private int foundTypesCount;
+	private ObjectVector acceptedTypes;
+	
+	private int foundConstructorsCount;
+	private ObjectVector acceptedConstructors;
+
+	/**
+	 * The CompletionEngine is responsible for computing source completions.
+	 *
+	 * It requires a searchable name environment, which supports some
+	 * specific search APIs, and a requestor to feed back the results to a UI.
+	 *
+	 *  @param nameEnvironment org.eclipse.jdt.internal.codeassist.ISearchableNameEnvironment
+	 *      used to resolve type/package references and search for types/packages
+	 *      based on partial names.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.codeassist.ICompletionRequestor
+	 *      since the engine might produce answers of various forms, the engine
+	 *      is associated with a requestor able to accept all possible completions.
+	 *
+	 *  @param settings java.util.Map
+	 *		set of options used to configure the code assist engine.
+	 */
+	public CompletionEngine(
+			SearchableEnvironment nameEnvironment,
+			CompletionRequestor requestor,
+			Map settings,
+			IJavaProject javaProject,
+			WorkingCopyOwner owner,
+			IProgressMonitor monitor) {
+		super(settings);
+		this.javaProject = javaProject;
+		this.requestor = requestor;
+		this.nameEnvironment = nameEnvironment;
+		this.typeCache = new HashtableOfObject(5);
+		this.openedBinaryTypes = 0;
+
+		this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
+		this.problemReporter = new ProblemReporter(
+				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+				this.compilerOptions,
+				this.problemFactory);
+		this.lookupEnvironment =
+			new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment);
+		this.parser =
+			new CompletionParser(this.problemReporter, this.requestor.isExtendedContextRequired());
+		this.owner = owner;
+		this.monitor = monitor;
+	}
+	
+	public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+		if (!CharOperation.equals(sourceUnit.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
+			// do not accept package-info.java as a type for completion engine
+			// because it contains no extra info that will help in completion
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343865
+			// Required after the fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=337868
+			// because now we get a type corresponding to the package-info.java from the java model.
+			super.accept(sourceUnit, accessRestriction);
+		}
+	}
+	
+	public void acceptConstructor(
+			int modifiers,
+			char[] simpleTypeName,
+			int parameterCount,
+			char[] signature,
+			char[][] parameterTypes,
+			char[][] parameterNames,
+			int typeModifiers,
+			char[] packageName,
+			int extraFlags,
+			String path,
+			AccessRestriction accessRestriction) {
+		
+		// does not check cancellation for every types to avoid performance loss
+		if ((this.foundConstructorsCount % (CHECK_CANCEL_FREQUENCY)) == 0) checkCancel();
+		this.foundConstructorsCount++;
+		
+		if ((typeModifiers & ClassFileConstants.AccEnum) != 0) return;
+		
+		if (this.options.checkDeprecation && (typeModifiers & ClassFileConstants.AccDeprecated) != 0) return;
+
+		if (this.options.checkVisibility) {
+			if((typeModifiers & ClassFileConstants.AccPublic) == 0) {
+				if((typeModifiers & ClassFileConstants.AccPrivate) != 0) return;
+
+				if (this.currentPackageName == null) {
+					initializePackageCache();
+				}
+				
+				if(!CharOperation.equals(packageName, this.currentPackageName)) return;
+			}
+		}
+
+		int accessibility = IAccessRule.K_ACCESSIBLE;
+		if(accessRestriction != null) {
+			switch (accessRestriction.getProblemId()) {
+				case IProblem.ForbiddenReference:
+					if (this.options.checkForbiddenReference) {
+						return;
+					}
+					accessibility = IAccessRule.K_NON_ACCESSIBLE;
+					break;
+				case IProblem.DiscouragedReference:
+					if (this.options.checkDiscouragedReference) {
+						return;
+					}
+					accessibility = IAccessRule.K_DISCOURAGED;
+					break;
+			}
+		}
+		
+		if(this.acceptedConstructors == null) {
+			this.acceptedConstructors = new ObjectVector();
+		}
+		this.acceptedConstructors.add(
+				new AcceptedConstructor(
+						modifiers,
+						simpleTypeName,
+						parameterCount,
+						signature,
+						parameterTypes,
+						parameterNames,
+						typeModifiers,
+						packageName,
+						extraFlags,
+						accessibility));
+	}
+	
+	private void acceptConstructors(Scope scope) {
+		final boolean DEFER_QUALIFIED_PROPOSALS = false;
+		
+		this.checkCancel();
+		
+		if(this.acceptedConstructors == null) return;
+
+		int length = this.acceptedConstructors.size();
+
+		if(length == 0) return;
+		
+		HashtableOfObject onDemandFound = new HashtableOfObject();
+		
+		ArrayList deferredProposals = null;
+		if (DEFER_QUALIFIED_PROPOSALS) {
+			deferredProposals = new ArrayList();
+		}
+		
+		try {
+			next : for (int i = 0; i < length; i++) {
+				
+				// does not check cancellation for every types to avoid performance loss
+				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+				
+				AcceptedConstructor acceptedConstructor = (AcceptedConstructor)this.acceptedConstructors.elementAt(i);
+				final int typeModifiers = acceptedConstructor.typeModifiers;
+				final char[] packageName = acceptedConstructor.packageName;
+				final char[] simpleTypeName = acceptedConstructor.simpleTypeName;
+				final int modifiers = acceptedConstructor.modifiers;
+				final int parameterCount = acceptedConstructor.parameterCount;
+				final char[] signature = acceptedConstructor.signature;
+				final char[][] parameterTypes = acceptedConstructor.parameterTypes;
+				final char[][] parameterNames = acceptedConstructor.parameterNames;
+				final int extraFlags = acceptedConstructor.extraFlags;
+				final int accessibility = acceptedConstructor.accessibility;
+				
+				boolean proposeType = hasArrayTypeAsExpectedSuperTypes() || (extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0;
+				
+				char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.');
+						
+				Object knownTypeKind = this.knownTypes.get(fullyQualifiedName);
+				if (knownTypeKind != null) {
+					if (knownTypeKind == KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS) {
+						// the type and its constructors are already accepted
+						continue next;
+					}
+					// this type is already accepted
+					proposeType = false;
+				} else {
+					this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
+				}
+				
+				boolean proposeConstructor = true;
+					
+				if (this.options.checkVisibility) {
+					if((modifiers & ClassFileConstants.AccPublic) == 0) {
+						if((modifiers & ClassFileConstants.AccPrivate) != 0) {
+							if (!proposeType) continue next;
+							proposeConstructor = false;
+						} else {
+							if (this.currentPackageName == null) {
+								initializePackageCache();
+							}
+							
+							if(!CharOperation.equals(packageName, this.currentPackageName)) {
+								
+								if((typeModifiers & ClassFileConstants.AccAbstract) == 0 ||
+										(modifiers & ClassFileConstants.AccProtected) == 0) {
+									if (!proposeType) continue next;
+									proposeConstructor = false;
+								}
+							}
+						}
+					}
+				}
+				
+				acceptedConstructor.fullyQualifiedName = fullyQualifiedName;
+				acceptedConstructor.proposeType = proposeType;
+				acceptedConstructor.proposeConstructor = proposeConstructor;
+				
+				
+				if(!this.importCachesInitialized) {
+					initializeImportCaches();
+				}
+				
+				for (int j = 0; j < this.importCacheCount; j++) {
+					char[][] importName = this.importsCache[j];
+					if(CharOperation.equals(simpleTypeName, importName[0])) {
+						if (proposeType) {
+							proposeType(
+									packageName,
+									simpleTypeName,
+									typeModifiers,
+									accessibility,
+									simpleTypeName,
+									fullyQualifiedName,
+									!CharOperation.equals(fullyQualifiedName, importName[1]),
+									scope);
+						}
+						
+						if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+							boolean isQualified = !CharOperation.equals(fullyQualifiedName, importName[1]);
+							if (!isQualified) {
+								proposeConstructor(
+										simpleTypeName,
+										parameterCount,
+										signature,
+										parameterTypes,
+										parameterNames,
+										modifiers,
+										packageName,
+										typeModifiers,
+										accessibility,
+										simpleTypeName,
+										fullyQualifiedName,
+										isQualified,
+										scope,
+										extraFlags);
+							} else {
+								acceptedConstructor.mustBeQualified = true;
+								if (DEFER_QUALIFIED_PROPOSALS) {
+									deferredProposals.add(acceptedConstructor);
+								} else {
+									proposeConstructor(acceptedConstructor, scope);
+								}
+							}
+						}
+						continue next;
+					}
+				}
+
+
+				if (CharOperation.equals(this.currentPackageName, packageName)) {
+					if (proposeType) {
+						proposeType(
+								packageName,
+								simpleTypeName,
+								typeModifiers,
+								accessibility,
+								simpleTypeName,
+								fullyQualifiedName,
+								false,
+								scope);
+					}
+					
+					if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+						proposeConstructor(
+								simpleTypeName,
+								parameterCount,
+								signature,
+								parameterTypes,
+								parameterNames,
+								modifiers,
+								packageName,
+								typeModifiers,
+								accessibility,
+								simpleTypeName,
+								fullyQualifiedName,
+								false,
+								scope,
+								extraFlags);
+					}
+					continue next;
+				} else {
+					char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+					AcceptedConstructor foundConstructor = null;
+					if((foundConstructor = (AcceptedConstructor)onDemandFound.get(simpleTypeName)) == null) {
+						for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+							ImportBinding importBinding = this.onDemandImportsCache[j];
+
+							char[][] importName = importBinding.compoundName;
+							char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+								fullyQualifiedEnclosingTypeOrPackageName = packageName;
+							}
+							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+								if(importBinding.isStatic()) {
+									if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+										onDemandFound.put(
+												simpleTypeName,
+												acceptedConstructor);
+										continue next;
+									}
+								} else {
+									onDemandFound.put(
+											simpleTypeName,
+											acceptedConstructor);
+									continue next;
+								}
+							}
+						}
+					} else if(!foundConstructor.mustBeQualified){
+						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+							ImportBinding importBinding = this.onDemandImportsCache[j];
+
+							char[][] importName = importBinding.compoundName;
+							char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+								fullyQualifiedEnclosingTypeOrPackageName = packageName;
+							}
+							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+								if(importBinding.isStatic()) {
+									if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
+										foundConstructor.mustBeQualified = true;
+										break done;
+									}
+								} else {
+									foundConstructor.mustBeQualified = true;
+									break done;
+								}
+							}
+						}
+					}
+					if (proposeType) {
+						proposeType(
+								packageName,
+								simpleTypeName,
+								typeModifiers,
+								accessibility,
+								simpleTypeName,
+								fullyQualifiedName,
+								true,
+								scope);
+					}
+					
+					if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
+						acceptedConstructor.mustBeQualified = true;
+						if (DEFER_QUALIFIED_PROPOSALS) {
+							deferredProposals.add(acceptedConstructor);
+						} else {
+							proposeConstructor(acceptedConstructor, scope);
+						}
+					}
+				}
+			}
+		
+			char[][] keys = onDemandFound.keyTable;
+			Object[] values = onDemandFound.valueTable;
+			int max = keys.length;
+			for (int i = 0; i < max; i++) {
+				
+				// does not check cancellation for every types to avoid performance loss
+				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+				
+				if(keys[i] != null) {
+					AcceptedConstructor value = (AcceptedConstructor) values[i];
+					if(value != null) {
+						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+							ImportBinding importBinding = this.onDemandImportsCache[j];
+
+							char[][] importName = importBinding.compoundName;
+							char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+								fullyQualifiedEnclosingTypeOrPackageName = value.packageName;
+							}
+							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+								if(importBinding.isStatic()) {
+									if((value.modifiers & ClassFileConstants.AccStatic) != 0) {
+										value.mustBeQualified = true;
+										break done;
+									}
+								} else {
+									value.mustBeQualified = true;
+									break done;
+								}
+							}
+						}
+						if (value.proposeType) {
+							proposeType(
+									value.packageName,
+									value.simpleTypeName,
+									value.typeModifiers,
+									value.accessibility,
+									value.simpleTypeName,
+									value.fullyQualifiedName,
+									value.mustBeQualified,
+									scope);
+						}
+						
+						if (value.proposeConstructor && !Flags.isEnum(value.modifiers)) {
+							if (!value.mustBeQualified) {
+								proposeConstructor(
+										value.simpleTypeName,
+										value.parameterCount,
+										value.signature,
+										value.parameterTypes,
+										value.parameterNames,
+										value.modifiers,
+										value.packageName,
+										value.typeModifiers,
+										value.accessibility,
+										value.simpleTypeName,
+										value.fullyQualifiedName,
+										value.mustBeQualified,
+										scope,
+										value.extraFlags);
+							} else {
+								if (DEFER_QUALIFIED_PROPOSALS) {
+									deferredProposals.add(value);
+								} else {
+									proposeConstructor(value, scope);
+								}
+							}
+						}
+					}
+				}
+			}
+			
+			if (DEFER_QUALIFIED_PROPOSALS) {
+				int size = deferredProposals.size();
+				for (int i = 0; i < size; i++) {
+					
+					// does not check cancellation for every types to avoid performance loss
+					if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+				
+					AcceptedConstructor deferredProposal = (AcceptedConstructor)deferredProposals.get(i);
+					
+					if (deferredProposal.proposeConstructor) {
+						proposeConstructor(
+								deferredProposal.simpleTypeName,
+								deferredProposal.parameterCount,
+								deferredProposal.signature,
+								deferredProposal.parameterTypes,
+								deferredProposal.parameterNames,
+								deferredProposal.modifiers,
+								deferredProposal.packageName,
+								deferredProposal.typeModifiers,
+								deferredProposal.accessibility,
+								deferredProposal.simpleTypeName,
+								deferredProposal.fullyQualifiedName,
+								deferredProposal.mustBeQualified,
+								scope,
+								deferredProposal.extraFlags);
+					}
+				}
+			}
+		} finally {
+			this.acceptedTypes = null; // reset
+		}
+	}
+
+	/**
+	 * One result of the search consists of a new package.
+	 *
+	 * NOTE - All package names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    The default package is represented by an empty array.
+	 */
+	public void acceptPackage(char[] packageName) {
+
+		if (this.knownPkgs.containsKey(packageName)) return;
+
+		this.knownPkgs.put(packageName, this);
+
+		char[] completion;
+		if(this.resolvingImports) {
+			if(this.resolvingStaticImports) {
+				completion = CharOperation.concat(packageName, new char[] { '.' });
+			} else {
+				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
+			}
+		} else {
+			completion = packageName;
+		}
+
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
+		if(!this.resolvingImports) {
+			relevance += computeRelevanceForQualification(true);
+		}
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+		this.noProposal = false;
+		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
+			proposal.setDeclarationSignature(packageName);
+			proposal.setPackageName(packageName);
+			proposal.setCompletion(completion);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+	}
+
+	/**
+	 * One result of the search consists of a new type.
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.I".
+	 *    The default package is represented by an empty array.
+	 */
+	public void acceptType(
+		char[] packageName,
+		char[] simpleTypeName,
+		char[][] enclosingTypeNames,
+		int modifiers,
+		AccessRestriction accessRestriction) {
+		
+		// does not check cancellation for every types to avoid performance loss
+		if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+		this.foundTypesCount++;
+		
+		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
+		if (this.assistNodeIsExtendedType && (modifiers & ClassFileConstants.AccFinal) != 0) return;
+
+		if (this.options.checkVisibility) {
+			if((modifiers & ClassFileConstants.AccPublic) == 0) {
+				if((modifiers & ClassFileConstants.AccPrivate) != 0) return;
+
+				char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
+				if(!CharOperation.equals(packageName, currentPackage)) return;
+			}
+		}
+
+		int accessibility = IAccessRule.K_ACCESSIBLE;
+		if(accessRestriction != null) {
+			switch (accessRestriction.getProblemId()) {
+				case IProblem.ForbiddenReference:
+					if (this.options.checkForbiddenReference) {
+						return;
+					}
+					accessibility = IAccessRule.K_NON_ACCESSIBLE;
+					break;
+				case IProblem.DiscouragedReference:
+					if (this.options.checkDiscouragedReference) {
+						return;
+					}
+					accessibility = IAccessRule.K_DISCOURAGED;
+					break;
+			}
+		}
+		
+		if (isForbiddenType(packageName, simpleTypeName, enclosingTypeNames)) {
+			return;
+		}
+
+		if(this.acceptedTypes == null) {
+			this.acceptedTypes = new ObjectVector();
+		}
+		this.acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility));
+	}
+
+	private void acceptTypes(Scope scope) {
+		this.checkCancel();
+		
+		if(this.acceptedTypes == null) return;
+
+		int length = this.acceptedTypes.size();
+
+		if(length == 0) return;
+
+		HashtableOfObject onDemandFound = new HashtableOfObject();
+		
+		try {
+			next : for (int i = 0; i < length; i++) {
+				
+				// does not check cancellation for every types to avoid performance loss
+				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+				
+				AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
+				char[] packageName = acceptedType.packageName;
+				char[] simpleTypeName = acceptedType.simpleTypeName;
+				char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
+				int modifiers = acceptedType.modifiers;
+				int accessibility = acceptedType.accessibility;
+	
+				char[] typeName;
+				char[] flatEnclosingTypeNames;
+				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+					flatEnclosingTypeNames = null;
+					typeName = simpleTypeName;
+				} else {
+					flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
+					typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
+				}
+				char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+	
+				if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
+	
+				this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
+	
+				if (this.resolvingImports) {
+					if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
+						continue next; // import of default package is forbidden when compliance is 1.4 or higher
+					}
+	
+					char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
+	
+					if(this.resolvingStaticImports) {
+						if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+							completionName = CharOperation.concat(completionName, new char[] { '.' });
+						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
+							continue next;
+						} else {
+							completionName = CharOperation.concat(completionName, new char[] { ';' });
+						}
+					} else {
+						completionName = CharOperation.concat(completionName, new char[] { ';' });
+					}
+	
+					int relevance = computeBaseRelevance();
+					relevance += computeRelevanceForResolution();
+					relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName);
+					relevance += computeRelevanceForRestrictions(accessibility);
+					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+	
+					this.noProposal = false;
+					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+						createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
+					}
+				} else {
+					if(!this.importCachesInitialized) {
+						initializeImportCaches();
+					}
+	
+					for (int j = 0; j < this.importCacheCount; j++) {
+						char[][] importName = this.importsCache[j];
+						if(CharOperation.equals(typeName, importName[0])) {
+							proposeType(
+									packageName,
+									simpleTypeName,
+									modifiers,
+									accessibility,
+									typeName,
+									fullyQualifiedName,
+									!CharOperation.equals(fullyQualifiedName, importName[1]),
+									scope);
+							continue next;
+						}
+					}
+	
+	
+					if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
+						proposeType(
+								packageName,
+								simpleTypeName,
+								modifiers,
+								accessibility,
+								typeName,
+								fullyQualifiedName,
+								false,
+								scope);
+						continue next;
+					} else {
+						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+	
+						AcceptedType foundType = null;
+						if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
+							for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+								ImportBinding importBinding = this.onDemandImportsCache[j];
+	
+								char[][] importName = importBinding.compoundName;
+								char[] importFlatName = CharOperation.concatWith(importName, '.');
+	
+								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+										fullyQualifiedEnclosingTypeOrPackageName =
+											CharOperation.concat(
+													packageName,
+													flatEnclosingTypeNames,
+													'.');
+									} else {
+										fullyQualifiedEnclosingTypeOrPackageName =
+											packageName;
+									}
+								}
+								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+									if(importBinding.isStatic()) {
+										if((modifiers & ClassFileConstants.AccStatic) != 0) {
+											acceptedType.qualifiedTypeName = typeName;
+											acceptedType.fullyQualifiedName = fullyQualifiedName;
+											onDemandFound.put(
+													simpleTypeName,
+													acceptedType);
+											continue next;
+										}
+									} else {
+										acceptedType.qualifiedTypeName = typeName;
+										acceptedType.fullyQualifiedName = fullyQualifiedName;
+										onDemandFound.put(
+												simpleTypeName,
+												acceptedType);
+										continue next;
+									}
+								}
+							}
+						} else if(!foundType.mustBeQualified){
+							done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+								ImportBinding importBinding = this.onDemandImportsCache[j];
+	
+								char[][] importName = importBinding.compoundName;
+								char[] importFlatName = CharOperation.concatWith(importName, '.');
+	
+								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+										fullyQualifiedEnclosingTypeOrPackageName =
+											CharOperation.concat(
+													packageName,
+													flatEnclosingTypeNames,
+													'.');
+									} else {
+										fullyQualifiedEnclosingTypeOrPackageName =
+											packageName;
+									}
+								}
+								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+									if(importBinding.isStatic()) {
+										if((modifiers & ClassFileConstants.AccStatic) != 0) {
+											foundType.mustBeQualified = true;
+											break done;
+										}
+									} else {
+										foundType.mustBeQualified = true;
+										break done;
+									}
+								}
+							}
+						}
+						proposeType(
+								packageName,
+								simpleTypeName,
+								modifiers,
+								accessibility,
+								typeName,
+								fullyQualifiedName,
+								true,
+								scope);
+					}
+				}
+			}
+		
+			char[][] keys = onDemandFound.keyTable;
+			Object[] values = onDemandFound.valueTable;
+			int max = keys.length;
+			for (int i = 0; i < max; i++) {
+				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
+				if(keys[i] != null) {
+					AcceptedType value = (AcceptedType) values[i];
+					if(value != null) {
+						proposeType(
+								value.packageName,
+								value.simpleTypeName,
+								value.modifiers,
+								value.accessibility,
+								value.qualifiedTypeName,
+								value.fullyQualifiedName,
+								value.mustBeQualified,
+								scope);
+					}
+				}
+			}
+		} finally {
+			this.acceptedTypes = null; // reset
+		}
+	}
+	
+	public void acceptUnresolvedName(char[] name) {
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution(false);
+		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForCaseMatching(this.completionToken, name);
+		relevance += computeRelevanceForQualification(false);
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
+		CompletionEngine.this.noProposal = false;
+		if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+			InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition);
+			proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE);
+			proposal.setPackageName(JAVA_LANG_NAME);
+			proposal.setTypeName(OBJECT);
+			proposal.setName(name);
+			proposal.setCompletion(name);
+			proposal.setFlags(Flags.AccDefault);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			CompletionEngine.this.requestor.accept(proposal);
+			if(DEBUG) {
+				CompletionEngine.this.printDebug(proposal);
+			}
+		}
+	}
+	private void addExpectedType(TypeBinding type, Scope scope){
+		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
+
+		// do not add twice the same type
+		for (int i = 0; i <= this.expectedTypesPtr; i++) {
+			if (this.expectedTypes[i] == type) return;
+		}
+
+		int length = this.expectedTypes.length;
+		if (++this.expectedTypesPtr >= length)
+			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
+		this.expectedTypes[this.expectedTypesPtr] = type;
+
+		if(type == scope.getJavaLangObject()) {
+			this.hasJavaLangObjectAsExpectedType = true;
+		}
+	}
+
+	private void addForbiddenBindings(Binding binding){
+		if (binding == null) return;
+
+		int length = this.forbbidenBindings.length;
+		if (++this.forbbidenBindingsPtr >= length)
+			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
+		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
+	}
+
+	private void addUninterestingBindings(Binding binding){
+		if (binding == null) return;
+
+		int length = this.uninterestingBindings.length;
+		if (++this.uninterestingBindingsPtr >= length)
+			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
+		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
+	}
+
+	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
+	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
+		int paramLength = parameters.length;
+		int argLength = arguments.length;
+		int lastIndex = argLength;
+		if (isVarargs) {
+			lastIndex = paramLength - 1;
+			if (paramLength == argLength) { // accept X[] but not X or X[][]
+				TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition
+				TypeBinding lastArgument = arguments[lastIndex];
+				if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
+					return false;
+			} else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
+				TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType();
+				for (int i = lastIndex; i < argLength; i++)
+					if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
+						return false;
+			} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
+				return false;
+			}
+			// now compare standard arguments from 0 to lastIndex
+		} else {
+			if(paramLength != argLength)
+				return false;
+		}
+		for (int i = 0; i < lastIndex; i++)
+			if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i]))
+				return false;
+		return true;
+	}
+
+	private void buildContext(
+			ASTNode astNode,
+			ASTNode astNodeParent,
+			CompilationUnitDeclaration compilationUnitDeclaration,
+			Binding qualifiedBinding,
+			Scope scope) {
+		InternalCompletionContext context = new InternalCompletionContext();
+		if (this.requestor.isExtendedContextRequired()) {
+			context.setExtendedData(
+					this.typeRoot,
+					compilationUnitDeclaration,
+					this.lookupEnvironment,
+					scope,
+					astNode,
+					astNodeParent,
+					this.owner,
+					this.parser);
+		}
+
+		// build expected types context
+		if (this.expectedTypesPtr > -1) {
+			int length = this.expectedTypesPtr + 1;
+			char[][] expTypes = new char[length][];
+			char[][] expKeys = new char[length][];
+			for (int i = 0; i < length; i++) {
+				expTypes[i] = getSignature(this.expectedTypes[i]);
+				expKeys[i] = this.expectedTypes[i].computeUniqueKey();
+			}
+			context.setExpectedTypesSignatures(expTypes);
+			context.setExpectedTypesKeys(expKeys);
+		}
+
+		context.setOffset(this.actualCompletionPosition + 1 - this.offset);
+
+		// Set javadoc info
+		if (astNode instanceof CompletionOnJavadoc) {
+			this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
+			context.setJavadoc(this.assistNodeInJavadoc);
+		}
+
+		if (!(astNode instanceof CompletionOnJavadoc)) {
+			CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
+			context.setToken(scanner.completionIdentifier);
+			context.setTokenRange(
+					scanner.completedIdentifierStart - this.offset,
+					scanner.completedIdentifierEnd - this.offset,
+					scanner.endOfEmptyToken - this.offset);
+		} else if(astNode instanceof CompletionOnJavadocTag) {
+			CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+			context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
+			context.setTokenRange(
+					javadocTag.tagSourceStart - this.offset,
+					javadocTag.tagSourceEnd - this.offset,
+					((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
+		} else {
+			CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
+			context.setToken(scanner.completionIdentifier);
+			context.setTokenRange(
+					scanner.completedIdentifierStart - this.offset,
+					scanner.completedIdentifierEnd - this.offset,
+					scanner.endOfEmptyToken - this.offset);
+		}
+
+		if(astNode instanceof CompletionOnStringLiteral) {
+			context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
+		} else {
+			context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
+		}
+
+		buildTokenLocationContext(context, scope, astNode, astNodeParent);
+
+		if(DEBUG) {
+			System.out.println(context.toString());
+		}
+		this.requestor.acceptContext(context);
+	}
+
+	private void buildTokenLocationContext(InternalCompletionContext context, Scope scope, ASTNode astNode, ASTNode astNodeParent) {
+		if (scope == null || context.isInJavadoc()) return;
+
+		if (astNode instanceof CompletionOnFieldType) {
+			CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+			if (!field.isLocalVariable &&
+					field.modifiers == ClassFileConstants.AccDefault &&
+					(field.annotations == null || field.annotations.length == 0)) {
+				context.setTokenLocation(CompletionContext.TL_MEMBER_START);
+			}
+		} else if (astNode instanceof CompletionOnMethodReturnType) {
+			CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+			if (method.modifiers == ClassFileConstants.AccDefault &&
+					(method.annotations == null || method.annotations.length == 0)) {
+				context.setTokenLocation(CompletionContext.TL_MEMBER_START);
+			}
+		} else if (astNode instanceof CompletionOnSingleTypeReference) {
+			CompletionOnSingleTypeReference completionOnSingleTypeReference = (CompletionOnSingleTypeReference) astNode;
+			if (completionOnSingleTypeReference.isConstructorType) {
+						context.setTokenLocation(CompletionContext.TL_CONSTRUCTOR_START);
+			}
+		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+			CompletionOnQualifiedTypeReference completionOnQualifiedTypeReference = (CompletionOnQualifiedTypeReference) astNode;
+			if (completionOnQualifiedTypeReference.isConstructorType){
+						context.setTokenLocation(CompletionContext.TL_CONSTRUCTOR_START);
+			}
+		} else {
+			ReferenceContext referenceContext = scope.referenceContext();
+			if (referenceContext instanceof AbstractMethodDeclaration) {
+				AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration)referenceContext;
+				if (methodDeclaration.bodyStart <= astNode.sourceStart &&
+						astNode.sourceEnd <= methodDeclaration.bodyEnd) {
+					// completion is inside a method body
+					if (astNodeParent == null &&
+							astNode instanceof CompletionOnSingleNameReference &&
+							!((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
+						context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
+					}
+				}
+			} else if (referenceContext instanceof TypeDeclaration) {
+				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+				FieldDeclaration[] fields = typeDeclaration.fields;
+				if (fields != null) {
+					done : for (int i = 0; i < fields.length; i++) {
+						if (fields[i] instanceof Initializer) {
+							Initializer initializer = (Initializer) fields[i];
+							if (initializer.block.sourceStart <= astNode.sourceStart &&
+									astNode.sourceStart < initializer.bodyEnd) {
+								// completion is inside an initializer
+								if (astNodeParent == null &&
+										astNode instanceof CompletionOnSingleNameReference &&
+										!((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
+									context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
+								}
+								break done;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	void checkCancel() {
+		if (this.monitor != null && this.monitor.isCanceled()) {
+			throw new OperationCanceledException();
+		}
+	}
+
+	private boolean complete(
+			ASTNode astNode,
+			ASTNode astNodeParent,
+			ASTNode enclosingNode,
+			CompilationUnitDeclaration compilationUnitDeclaration,
+			Binding qualifiedBinding,
+			Scope scope,
+			boolean insideTypeAnnotation) {
+
+		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd);
+
+		scope = computeForbiddenBindings(astNode, astNodeParent, scope);
+		computeUninterestingBindings(astNode, astNodeParent, scope);
+		if(astNodeParent != null) {
+			if(!isValidParent(astNodeParent, astNode, scope)) return false;
+			computeExpectedTypes(astNodeParent, astNode, scope);
+		}
+
+		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
+
+		if (astNode instanceof CompletionOnFieldType) {
+			completionOnFieldType(astNode, scope);
+		} else if (astNode instanceof CompletionOnMethodReturnType) {
+			completionOnMethodReturnType(astNode, scope);
+		} else if (astNode instanceof CompletionOnSingleNameReference) {
+			completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
+		} else if (astNode instanceof CompletionOnSingleTypeReference) {
+			completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
+			completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+			completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnMemberAccess) {
+			completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+		} else if (astNode instanceof CompletionOnMessageSend) {
+			completionOnMessageSend(astNode, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
+			completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
+			completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
+			completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnMethodName) {
+			completionOnMethodName(astNode, scope);
+		} else if (astNode instanceof CompletionOnFieldName) {
+			completionOnFieldName(astNode, scope);
+		} else if (astNode instanceof CompletionOnLocalName) {
+			completionOnLocalOrArgumentName(astNode, scope);
+		} else if (astNode instanceof CompletionOnArgumentName) {
+			completionOnLocalOrArgumentName(astNode, scope);
+		} else if (astNode instanceof CompletionOnKeyword) {
+			completionOnKeyword(astNode);
+		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+			completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
+			completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
+		} else if (astNode instanceof CompletionOnMemberValueName) {
+			completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
+		} else if(astNode instanceof CompletionOnBranchStatementLabel) {
+			completionOnBranchStatementLabel(astNode);
+		} else if(astNode instanceof CompletionOnMessageSendName) {
+			completionOnMessageSendName(astNode, qualifiedBinding, scope);
+		// Completion on Javadoc nodes
+		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
+			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
+				completionOnJavadocSingleTypeReference(astNode, scope);
+			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+				completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
+			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
+				completionOnJavadocFieldReference(astNode, scope);
+			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
+				completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
+			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
+				completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
+			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
+				completionOnJavadocParamNameReference(astNode);
+			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
+				completionOnJavadocTypeParamReference(astNode);
+			} else if (astNode instanceof CompletionOnJavadocTag) {
+				completionOnJavadocTag(astNode);
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Ask the engine to compute a completion at the specified position
+	 * of the given compilation unit.
+	 *
+	 *  No return
+	 *      completion results are answered through a requestor.
+	 *
+	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
+	 *      the source of the current compilation unit.
+	 *
+	 *  @param completionPosition int
+	 *      a position in the source where the completion is taking place.
+	 *      This position is relative to the source provided.
+	 */
+	public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
+
+		if(DEBUG) {
+			System.out.print("COMPLETION IN "); //$NON-NLS-1$
+			System.out.print(sourceUnit.getFileName());
+			System.out.print(" AT POSITION "); //$NON-NLS-1$
+			System.out.println(completionPosition);
+			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
+			System.out.println(sourceUnit.getContents());
+		}
+		if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
+		this.requestor.beginReporting();
+		boolean contextAccepted = false;
+		try {
+			this.fileName = sourceUnit.getFileName();
+			this.actualCompletionPosition = completionPosition - 1;
+			this.offset = pos;
+			this.typeRoot = root;
+			
+			this.checkCancel();
+			
+			// for now until we can change the UI.
+			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
+
+			//		boolean completionNodeFound = false;
+			if (parsedUnit != null) {
+				if(DEBUG) {
+					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
+					System.out.println(parsedUnit.toString());
+				}
+
+				// scan the package & import statements first
+				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
+					contextAccepted = true;
+					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
+					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
+					}
+					if(this.noProposal && this.problem != null) {
+						this.requestor.completionFailure(this.problem);
+						if(DEBUG) {
+							this.printDebug(this.problem);
+						}
+					}
+					return;
+				}
+
+				ImportReference[] imports = parsedUnit.imports;
+				if (imports != null) {
+					for (int i = 0, length = imports.length; i < length; i++) {
+						ImportReference importReference = imports[i];
+						if (importReference instanceof CompletionOnImportReference) {
+							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+							if ((this.unitScope = parsedUnit.scope) != null) {
+								contextAccepted = true;
+								buildContext(importReference, null, parsedUnit, null, null);
+
+								long positions = importReference.sourcePositions[importReference.tokens.length - 1];
+								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
+
+								char[][] oldTokens = importReference.tokens;
+								int tokenCount = oldTokens.length;
+								if (tokenCount == 1) {
+									findImports((CompletionOnImportReference)importReference, true);
+								} else if(tokenCount > 1){
+									this.insideQualifiedReference = true;
+
+									char[] lastToken = oldTokens[tokenCount - 1];
+									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
+
+									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
+									if(binding != null) {
+										if(binding instanceof PackageBinding) {
+											findImports((CompletionOnImportReference)importReference, false);
+										} else {
+											ReferenceBinding ref = (ReferenceBinding) binding;
+
+											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
+											}
+											if(importReference.isStatic()) {
+
+												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+													findImportsOfStaticFields(lastToken, ref);
+												}
+												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+													findImportsOfStaticMethods(lastToken, ref);
+												}
+											}
+										}
+									}
+								}
+
+								if(this.noProposal && this.problem != null) {
+									this.requestor.completionFailure(this.problem);
+									if(DEBUG) {
+										this.printDebug(this.problem);
+									}
+								}
+							}
+							return;
+						} else if(importReference instanceof CompletionOnKeyword) {
+							contextAccepted = true;
+							buildContext(importReference, null, parsedUnit, null, null);
+							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
+								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
+								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, parsedUnit.currentPackage != null);
+							}
+							if(this.noProposal && this.problem != null) {
+								this.requestor.completionFailure(this.problem);
+								if(DEBUG) {
+									this.printDebug(this.problem);
+								}
+							}
+							return;
+						}
+					}
+				}
+
+				if (parsedUnit.types != null) {
+					try {
+						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+
+						if ((this.unitScope = parsedUnit.scope) != null) {
+							this.source = sourceUnit.getContents();
+							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+							parsedUnit.scope.faultInTypes();
+							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
+							if(DEBUG) {
+								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
+								System.out.println(parsedUnit.toString());
+							}
+							parsedUnit.resolve();
+						}
+					} catch (CompletionNodeFound e) {
+						//					completionNodeFound = true;
+						if (e.astNode != null) {
+							// if null then we found a problem in the completion node
+							if(DEBUG) {
+								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
+								System.out.println(e.astNode.toString());
+								if(this.parser.assistNodeParent != null) {
+									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
+									System.out.println(this.parser.assistNodeParent);
+								}
+							}
+							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
+							contextAccepted =
+								complete(
+									e.astNode,
+									this.parser.assistNodeParent,
+									this.parser.enclosingNode,
+									parsedUnit,
+									e.qualifiedBinding,
+									e.scope,
+									e.insideTypeAnnotation);
+						}
+					}
+				}
+			}
+
+			if(this.noProposal && this.problem != null) {
+				if(!contextAccepted) {
+					contextAccepted = true;
+					InternalCompletionContext context = new InternalCompletionContext();
+					context.setOffset(completionPosition - this.offset);
+					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+					if (this.requestor.isExtendedContextRequired()) context.setExtended();
+					this.requestor.acceptContext(context);
+				}
+				this.requestor.completionFailure(this.problem);
+				if(DEBUG) {
+					this.printDebug(this.problem);
+				}
+			}
+			/* Ignore package, import, class & interface keywords for now...
+					if (!completionNodeFound) {
+						if (parsedUnit == null || parsedUnit.types == null) {
+							// this is not good enough... can still be trying to define a second type
+							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
+							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
+							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
+						}
+						// currently have no way to know if extends/implements are possible keywords
+					}
+			*/
+		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} finally {
+			if(!contextAccepted) {
+				contextAccepted = true;
+				InternalCompletionContext context = new InternalCompletionContext();
+				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+				context.setOffset(completionPosition - this.offset);
+				if (this.requestor.isExtendedContextRequired()) context.setExtended();
+				this.requestor.acceptContext(context);
+			}
+			this.requestor.endReporting();
+			if (this.monitor != null) this.monitor.done();
+			reset();
+		}
+	}
+
+	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
+		if(this.requestor != null){
+			this.requestor.beginReporting();
+		}
+		boolean contextAccepted = false;
+		IType topLevelType = type;
+		while(topLevelType.getDeclaringType() != null) {
+			topLevelType = topLevelType.getDeclaringType();
+		}
+
+		this.fileName = topLevelType.getParent().getElementName().toCharArray();
+		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+
+		CompilationUnitDeclaration compilationUnit = null;
+
+		try {
+			// TypeConverter is used instead of SourceTypeConverter because the type
+			// to convert can be a binary type or a source type
+			TypeDeclaration typeDeclaration = null;
+			if (type instanceof SourceType) {
+				SourceType sourceType = (SourceType) type;
+				ISourceType info = (ISourceType) sourceType.getElementInfo();
+				compilationUnit = SourceTypeConverter.buildCompilationUnit(
+					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
+					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+					| SourceTypeConverter.MEMBER_TYPE, // need member types
+					// no need for field initialization
+					this.problemReporter,
+					compilationResult);
+				if (compilationUnit.types != null)
+					typeDeclaration = compilationUnit.types[0];
+			} else {
+				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
+				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
+			}
+
+			if(typeDeclaration != null) {
+				// build AST from snippet
+				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+
+				// merge AST
+				FieldDeclaration[] oldFields = typeDeclaration.fields;
+				FieldDeclaration[] newFields = null;
+				if (oldFields != null) {
+					newFields = new FieldDeclaration[oldFields.length + 1];
+					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
+					newFields[oldFields.length] = fakeInitializer;
+				} else {
+					newFields = new FieldDeclaration[] {fakeInitializer};
+				}
+				typeDeclaration.fields = newFields;
+
+				if(DEBUG) {
+					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
+					System.out.println(compilationUnit.toString());
+				}
+
+				if (compilationUnit.types != null) {
+					try {
+						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
+
+						if ((this.unitScope = compilationUnit.scope) != null) {
+							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
+							compilationUnit.scope.faultInTypes();
+							compilationUnit.resolve();
+						}
+					} catch (CompletionNodeFound e) {
+						//					completionNodeFound = true;
+						if (e.astNode != null) {
+							// if null then we found a problem in the completion node
+							contextAccepted =
+								complete(
+									e.astNode,
+									this.parser.assistNodeParent,
+									this.parser.enclosingNode,
+									compilationUnit,
+									e.qualifiedBinding,
+									e.scope,
+									e.insideTypeAnnotation);
+						}
+					}
+				}
+				if(this.noProposal && this.problem != null) {
+					if(!contextAccepted) {
+						contextAccepted = true;
+						InternalCompletionContext context = new InternalCompletionContext();
+						if (this.requestor.isExtendedContextRequired()) context.setExtended();
+						this.requestor.acceptContext(context);
+					}
+					this.requestor.completionFailure(this.problem);
+					if(DEBUG) {
+						this.printDebug(this.problem);
+					}
+				}
+			}
+		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
+			if(DEBUG) {
+				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch(JavaModelException e) {
+			// Do nothing
+		}
+		if(!contextAccepted) {
+			contextAccepted = true;
+			InternalCompletionContext context = new InternalCompletionContext();
+			if (this.requestor.isExtendedContextRequired()) context.setExtended();
+			this.requestor.acceptContext(context);
+		}
+		if(this.requestor != null){
+			this.requestor.endReporting();
+		}
+	}
+	
+	private void completionOnBranchStatementLabel(ASTNode astNode) {
+		if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
+			CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
+			this.completionToken = label.label;
+			findLabels(this.completionToken, label.possibleLabels);
+		}
+	}
+	
+	private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+			CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
+			setSourceAndTokenRange(access.classStart, access.sourceEnd);
+			this.completionToken = access.completionIdentifier;
+			findClassField(
+					this.completionToken,
+					(TypeBinding) qualifiedBinding,
+					scope,
+					null,
+					null,
+					null,
+					false);
+		}
+	}
+	
+	private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+			CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
+			TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
+			findConstructors(
+				(ReferenceBinding) qualifiedBinding,
+				argTypes,
+				scope,
+				constructorCall,
+				false,
+				null,
+				null,
+				null,
+				false);
+		}
+	}
+	
+	private void completionOnFieldName(ASTNode astNode, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+			CompletionOnFieldName field = (CompletionOnFieldName) astNode;
+
+			FieldBinding[] fields = scope.enclosingSourceType().fields();
+			char[][] excludeNames = new char[fields.length][];
+			for(int i = 0 ; i < fields.length ; i++){
+				excludeNames[i] = fields[i].name;
+			}
+
+			this.completionToken = field.realName;
+
+			
+			int kind =
+				 (field.modifiers & ClassFileConstants.AccStatic) == 0 ? 
+						InternalNamingConventions.VK_INSTANCE_FIELD :
+							(field.modifiers & ClassFileConstants.AccFinal) == 0 ? 
+									InternalNamingConventions.VK_STATIC_FIELD :
+										InternalNamingConventions.VK_STATIC_FINAL_FIELD;
+			
+			findVariableNames(field.realName, field.type, excludeNames, null, kind);
+		}
+	}
+	
+	private void completionOnFieldType(ASTNode astNode, Scope scope) {
+		CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+		CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
+		this.completionToken = type.token;
+		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+
+		findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
+		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+			findKeywordsForMember(this.completionToken, field.modifiers, astNode);
+		}
+
+		if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
+			SourceTypeBinding enclosingType = scope.enclosingSourceType();
+			if (!enclosingType.isAnnotationType()) {
+				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+					findMethodDeclarations(
+							this.completionToken,
+							enclosingType,
+							scope,
+							new ObjectVector(),
+							null,
+							null,
+							null,
+							false);
+				}
+				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+					proposeNewMethod(this.completionToken, enclosingType);
+				}
+			}
+		}
+	}
+	//TODO
+	private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
+		
+		CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
+		this.javadocTagPosition = allocExpression.tagSourceStart;
+		int rangeStart = astNode.sourceStart;
+		if (allocExpression.type.isThis()) {
+			if (allocExpression.completeInText()) {
+				rangeStart = allocExpression.separatorPosition;
+			}
+		} else if (allocExpression.completeInText()) {
+			rangeStart = allocExpression.type.sourceStart;
+		}
+		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
+
+		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
+			findConstructors(ref, argTypes, scope, allocExpression, false, null, null, null, false);
+		}
+	}
+	//TODO
+	private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
+		this.insideQualifiedReference = true;
+		CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
+		this.completionToken = fieldRef.token;
+		long completionPosition = fieldRef.nameSourcePosition;
+		this.javadocTagPosition = fieldRef.tagSourceStart;
+
+		if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
+				ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
+			int rangeStart = (int) (completionPosition >>> 32);
+			if (fieldRef.receiver.isThis()) {
+				if (fieldRef.completeInText()) {
+					rangeStart = fieldRef.separatorPosition;
+				}
+			} else if (fieldRef.completeInText()) {
+				rangeStart = fieldRef.receiver.sourceStart;
+			}
+			setSourceAndTokenRange(rangeStart, (int) completionPosition);
+
+			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
+					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
+				findFields(this.completionToken,
+					receiverType,
+					scope,
+					new ObjectVector(),
+					new ObjectVector(),
+					false, /*not only static */
+					fieldRef,
+					scope,
+					false,
+					true,
+					null,
+					null,
+					null,
+					false,
+					null,
+					-1,
+					-1);
+			}
+
+			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+				findMethods(
+					this.completionToken,
+					null,
+					null,
+					receiverType,
+					scope,
+					new ObjectVector(),
+					false, /*not only static */
+					false,
+					fieldRef,
+					scope,
+					false,
+					false,
+					true,
+					null,
+					null,
+					null,
+					false,
+					null,
+					-1,
+					-1);
+				if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
+					ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
+					if (this.completionToken == null
+							|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
+							|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
+						findConstructors(refBinding, null, scope, fieldRef, false, null, null, null, false);
+					}
+				}
+			}
+		}
+	}
+	//TODO
+	private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
+		TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
+		this.completionToken = messageSend.selector;
+		this.javadocTagPosition = messageSend.tagSourceStart;
+
+		// Set source range
+		int rangeStart = astNode.sourceStart;
+		if (messageSend.receiver.isThis()) {
+			if (messageSend.completeInText()) {
+				rangeStart = messageSend.separatorPosition;
+			}
+		} else if (messageSend.completeInText()) {
+			rangeStart = messageSend.receiver.sourceStart;
+		}
+		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+
+		if (qualifiedBinding == null) {
+			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
+			}
+		} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+			findMethods(
+				this.completionToken,
+				null,
+				argTypes,
+				(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+				scope,
+				new ObjectVector(),
+				false,
+				false/* prefix match */,
+				messageSend,
+				scope,
+				false,
+				messageSend.receiver instanceof SuperReference,
+				true,
+				null,
+				null,
+				null,
+				false,
+				null,
+				-1,
+				-1);
+		}
+	}
+	//TODO
+	private void completionOnJavadocParamNameReference(ASTNode astNode) {
+		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+			CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
+			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+			findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
+			findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
+		}
+	}
+	//TODO
+	private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		this.insideQualifiedReference = true;
+
+		CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
+		this.completionToken = typeRef.completionIdentifier;
+		long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
+		this.javadocTagPosition = typeRef.tagSourceStart;
+
+		// get the source positions of the completion identifier
+		if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+					((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
+				int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+				setSourceAndTokenRange(rangeStart, (int) completionPosition);
+				findMemberTypes(
+					this.completionToken,
+					(ReferenceBinding) qualifiedBinding,
+					scope,
+					scope.enclosingSourceType(),
+					false,
+					false,
+					new ObjectVector(),
+					null,
+					null,
+					null,
+					false);
+			}
+		} else if (qualifiedBinding instanceof PackageBinding) {
+
+			setSourceRange(astNode.sourceStart, (int) completionPosition);
+			int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+			setTokenRange(rangeStart, (int) completionPosition);
+			// replace to the end of the completion identifier
+			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+		}
+	}
+	//TODO
+	private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
+		CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
+		this.completionToken = typeRef.token;
+		this.javadocTagPosition = typeRef.tagSourceStart;
+		setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
+		findTypesAndPackages(
+				this.completionToken,
+				scope,
+				(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
+				false,
+				new ObjectVector());
+	}
+	//TODO
+	private void completionOnJavadocTag(ASTNode astNode) {
+		CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+		setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
+		findJavadocBlockTags(javadocTag);
+		findJavadocInlineTags(javadocTag);
+	}
+	//TODO
+	private void completionOnJavadocTypeParamReference(ASTNode astNode) {
+		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+			CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
+			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+			findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
+		}
+	}
+	
+	private void completionOnKeyword(ASTNode astNode) {
+		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+			CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
+			findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
+		}
+	}
+	
+	private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+			LocalDeclaration variable = (LocalDeclaration) astNode;
+
+			int kind;
+			if (variable instanceof CompletionOnLocalName){
+				this.completionToken = ((CompletionOnLocalName) variable).realName;
+				kind = InternalNamingConventions.VK_LOCAL;
+			} else {
+				CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
+				this.completionToken = arg.realName;
+				kind = arg.isCatchArgument ? InternalNamingConventions.VK_LOCAL : InternalNamingConventions.VK_PARAMETER;
+			}
+
+			char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
+
+			char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
+
+			LocalVariableBinding[] locals = ((BlockScope)scope).locals;
+			char[][] discouragedNames = new char[locals.length][];
+			int localCount = 0;
+			for(int i = 0 ; i < locals.length ; i++){
+				if (locals[i] != null) {
+					discouragedNames[localCount++] = locals[i].name;
+				}
+			}
+
+			System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
+
+			findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind);
+		}
+	}
+	
+	private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
+
+		CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
+		if (fakeType.annotations[0] == annot) {
+			// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
+			// So 'targetedElement' is not computed in this case.
+			if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
+				this.targetedElement = computeTargetedElement(fakeType);
+			}
+
+		}
+
+		this.assistNodeIsAnnotation = true;
+		if (annot.type instanceof CompletionOnSingleTypeReference) {
+			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
+			this.completionToken = type.token;
+			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+
+			if (scope.parent.parent != null &&
+					!(scope.parent.parent instanceof MethodScope) &&
+					!fakeType.isParameter) {
+
+				if (this.completionToken.length <= Keywords.INTERFACE.length
+					&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
+				)){
+					int relevance = computeBaseRelevance();
+					relevance += computeRelevanceForResolution();
+					relevance += computeRelevanceForInterestingProposal();
+					relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+					relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
+
+					this.noProposal = false;
+					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+						CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+						proposal.setName(Keywords.INTERFACE);
+						proposal.setCompletion(Keywords.INTERFACE);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+			}
+
+			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+		} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
+			this.insideQualifiedReference = true;
+
+			CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
+			this.completionToken = type.completionIdentifier;
+			long completionPosition = type.sourcePositions[type.tokens.length];
+			if (qualifiedBinding instanceof PackageBinding) {
+
+				setSourceRange(astNode.sourceStart, (int) completionPosition);
+				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+				// replace to the end of the completion identifier
+				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+			} else {
+				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+				findMemberTypes(
+					this.completionToken,
+					(ReferenceBinding) qualifiedBinding,
+					scope,
+					scope.enclosingSourceType(),
+					false,
+					false,
+					new ObjectVector(),
+					null,
+					null,
+					null,
+					false);
+			}
+		}
+	}
+	
+	private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+			Scope scope, boolean insideTypeAnnotation) {
+		this.insideQualifiedReference = true;
+		CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
+		long completionPosition = access.nameSourcePosition;
+		setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+		this.completionToken = access.token;
+
+		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+			// complete method members with missing return type
+			// class X {
+			//   Missing f() {return null;}
+			//   void foo() {
+			//     f().|
+			//   }
+			// }
+			if (this.assistNodeInJavadoc == 0 &&
+					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+				ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
+				findFieldsAndMethodsFromMissingReturnType(
+						problemMethodBinding.selector,
+						problemMethodBinding.parameters,
+						scope,
+						access,
+						insideTypeAnnotation);
+			}
+		} else {
+			if (!access.isInsideAnnotation) {
+				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD) && !access.isSuperAccess()) {
+					findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
+				}
+
+				ObjectVector fieldsFound = new ObjectVector();
+				ObjectVector methodsFound = new ObjectVector();
+
+				boolean superCall = access.receiver instanceof SuperReference;
+
+				findFieldsAndMethods(
+					this.completionToken,
+					((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
+					scope,
+					fieldsFound,
+					methodsFound,
+					access,
+					scope,
+					false,
+					superCall,
+					null,
+					null,
+					null,
+					false,
+					null,
+					-1,
+					-1);
+
+				if (!superCall) {
+					
+					checkCancel();
+					
+					findFieldsAndMethodsFromCastedReceiver(
+							enclosingNode,
+							qualifiedBinding,
+							scope,
+							fieldsFound,
+							methodsFound,
+							access,
+							scope,
+							access.receiver);
+				}
+			}
+		}
+	}
+	
+	private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+			boolean insideTypeAnnotation) {
+		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
+		Annotation annotation = (Annotation) astNodeParent;
+
+		this.completionToken = memberValuePair.name;
+
+		ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
+
+		if (annotationType != null && annotationType.isAnnotationType()) {
+			if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+				findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
+			}
+			if (this.assistNodeCanBeSingleMemberAnnotation) {
+				if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+				} else {
+					if (this.expectedTypesPtr > -1) {
+						this.assistNodeIsEnum = true;
+						done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+							if (!this.expectedTypes[i].isEnum()) {
+								this.assistNodeIsEnum = false;
+								break done;
+							}
+						}
+
+					}
+					if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+						char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
+
+						findUnresolvedReference(
+								memberValuePair.sourceStart,
+								memberValuePair.sourceEnd,
+								(BlockScope)scope,
+								alreadyDefinedName);
+					}
+					findVariablesAndMethods(
+						this.completionToken,
+						scope,
+						FakeInvocationSite,
+						scope,
+						insideTypeAnnotation,
+						true);
+					// can be the start of a qualified type name
+					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+				}
+			}
+		}
+	}
+	
+	private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+		CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
+		TypeBinding[] argTypes = computeTypes(messageSend.arguments);
+		this.completionToken = messageSend.selector;
+		if (qualifiedBinding == null) {
+			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+				ObjectVector methodsFound = new ObjectVector();
+
+				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
+				
+				checkCancel();
+				
+				findLocalMethodsFromStaticImports(
+						this.completionToken,
+						scope,
+						messageSend,
+						scope,
+						true,
+						methodsFound,
+						true);
+			}
+		} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+			findMethods(
+				this.completionToken,
+				null,
+				argTypes,
+				(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+				scope,
+				new ObjectVector(),
+				false,
+				true,
+				messageSend,
+				scope,
+				false,
+				messageSend.receiver instanceof SuperReference,
+				false,
+				null,
+				null,
+				null,
+				false,
+				null,
+				-1,
+				-1);
+		}
+	}
+	
+	private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+			CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
+
+			this.insideQualifiedReference = true;
+			this.completionToken = messageSend.selector;
+			boolean onlyStatic = false;
+			if (messageSend.receiver instanceof NameReference) {
+				onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
+			} else if (!(messageSend.receiver instanceof MessageSend) &&
+					!(messageSend.receiver instanceof FieldReference) &&
+					!(messageSend.receiver.isThis())) {
+				onlyStatic = true;
+			}
+
+			TypeBinding receiverType = (TypeBinding)qualifiedBinding;
+
+			if(receiverType != null && receiverType instanceof ReferenceBinding) {
+				TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
+				if(typeArgTypes != null) {
+					findMethods(
+							this.completionToken,
+							typeArgTypes,
+							null,
+							(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
+							scope,
+							new ObjectVector(),
+							onlyStatic,
+							false,
+							messageSend,
+							scope,
+							false,
+							false,
+							false,
+							null,
+							null,
+							null,
+							false,
+							null,
+							-1,
+							-1);
+				}
+			}
+		}
+	}
+	
+	private void completionOnMethodName(ASTNode astNode, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+			CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+
+			setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
+
+			FieldBinding[] fields = scope.enclosingSourceType().fields();
+			char[][] excludeNames = new char[fields.length][];
+			for(int i = 0 ; i < fields.length ; i++){
+				excludeNames[i] = fields[i].name;
+			}
+
+			this.completionToken = method.selector;
+
+			
+			int kind =
+				 (method.modifiers & ClassFileConstants.AccStatic) == 0 ? 
+						InternalNamingConventions.VK_INSTANCE_FIELD :
+							(method.modifiers & ClassFileConstants.AccFinal) == 0 ? 
+									InternalNamingConventions.VK_STATIC_FIELD :
+										InternalNamingConventions.VK_STATIC_FINAL_FIELD;
+						
+			findVariableNames(this.completionToken, method.returnType, excludeNames, null, kind);
+		}
+	}
+	
+	private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
+		CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+		SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
+		this.completionToken = type.token;
+		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+		findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
+		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+			findKeywordsForMember(this.completionToken, method.modifiers, null);
+		}
+
+		if (method.modifiers == ClassFileConstants.AccDefault) {
+			SourceTypeBinding enclosingType = scope.enclosingSourceType();
+			if (!enclosingType.isAnnotationType()) {
+				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+					findMethodDeclarations(
+							this.completionToken,
+							scope.enclosingSourceType(),
+							scope,
+							new ObjectVector(),
+							null,
+							null,
+							null,
+							false);
+				}
+				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+				}
+			}
+		}
+	}
+	
+	private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
+
+			this.insideQualifiedReference = true;
+
+			this.assistNodeIsClass = ref.isClass();
+			this.assistNodeIsException = ref.isException();
+			this.assistNodeIsInterface = ref.isInterface();
+			this.assistNodeIsSuperType = ref.isSuperType();
+			this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+			this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
+
+			this.completionToken = ref.completionIdentifier;
+			long completionPosition = ref.sourcePositions[ref.tokens.length];
+			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+			if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
+					(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
+				if (this.assistNodeInJavadoc == 0 &&
+						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+					if(ref.tokens.length == 1) {
+						findMemberTypesFromMissingType(
+								ref,
+								ref.sourcePositions[0],
+								scope);
+					}
+				}
+			} else {
+				ObjectVector typesFound = new ObjectVector();
+				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+					findExceptionFromTryStatement(
+							this.completionToken,
+							(ReferenceBinding)qualifiedBinding,
+							scope.enclosingSourceType(),
+							(BlockScope)scope,
+							typesFound);
+				}
+				
+				checkCancel();
+				
+				findMemberTypes(
+					this.completionToken,
+					(ReferenceBinding) qualifiedBinding,
+					scope,
+					scope.enclosingSourceType(),
+					false,
+					false,
+					typesFound,
+					null,
+					null,
+					null,
+					false);
+			}
+		}
+	}
+
+	private boolean assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399, don't propose final types for extension.
+		if (astNodeParent == null)
+			return false;
+		if (astNodeParent instanceof TypeDeclaration) {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent;
+			return (typeDeclaration.superclass == astNode);	
+		} else if (astNodeParent instanceof TypeParameter) {
+			TypeParameter typeParameter = (TypeParameter) astNodeParent;
+			return (typeParameter.type == astNode);
+		} else if (astNodeParent instanceof Wildcard) {
+			Wildcard wildcard = (Wildcard) astNodeParent;
+			return (wildcard.bound == astNode && wildcard.kind == Wildcard.EXTENDS);
+		}
+		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);
+
+		CompletionOnQualifiedAllocationExpression allocExpression =
+			(CompletionOnQualifiedAllocationExpression) astNode;
+		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
+
+		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+		
+		if (ref.problemId() == ProblemReasons.NotFound) {
+			findConstructorsFromMissingType(
+					allocExpression.type,
+					argTypes,
+					scope,
+					allocExpression);
+		} else {
+			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+					&& ref.isClass()
+					&& !ref.isAbstract()) {
+					findConstructors(
+						ref,
+						argTypes,
+						scope,
+						allocExpression,
+						false,
+						null,
+						null,
+						null,
+						false);
+			}
+			
+			checkCancel();
+			
+			if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
+					&& !ref.isFinal()
+					&& !ref.isEnum()){
+				findAnonymousType(
+					ref,
+					argTypes,
+					scope,
+					allocExpression,
+					null,
+					null,
+					null,
+					false);
+			}
+		}
+	}
+	
+	private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+			Scope scope, boolean insideTypeAnnotation) {
+		this.insideQualifiedReference = true;
+		CompletionOnQualifiedNameReference ref =
+			(CompletionOnQualifiedNameReference) astNode;
+		this.completionToken = ref.completionIdentifier;
+		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
+		
+		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+			// complete field members with missing fields type
+			// class X {
+			//   Missing f;
+			//   void foo() {
+			//     f.|
+			//   }
+			// }
+			if (this.assistNodeInJavadoc == 0 &&
+					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
+							this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+				if(ref.tokens.length == 1) {
+					boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+
+					if (!foundSomeFields) {
+						
+						checkCancel();
+						
+						findMembersFromMissingType(
+								ref.tokens[0],
+								ref.sourcePositions[0],
+								null,
+								scope,
+								ref,
+								ref.isInsideAnnotationAttribute);
+					}
+				}
+			}
+		} else if (qualifiedBinding instanceof VariableBinding) {
+			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+			TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
+			if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
+				ObjectVector fieldsFound = new ObjectVector();
+				ObjectVector methodsFound = new ObjectVector();
+
+				findFieldsAndMethods(
+						this.completionToken,
+						receiverType.capture(scope, ref.sourceEnd),
+						scope,
+						fieldsFound,
+						methodsFound,
+						ref,
+						scope,
+						false,
+						false,
+						null,
+						null,
+						null,
+						false,
+						null,
+						-1,
+						-1);
+				
+				checkCancel();
+
+				findFieldsAndMethodsFromCastedReceiver(
+						enclosingNode,
+						qualifiedBinding,
+						scope,
+						fieldsFound,
+						methodsFound,
+						ref,
+						scope,
+						ref);
+
+			} else if (this.assistNodeInJavadoc == 0 &&
+					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+				boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+				boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+				if (proposeField || proposeMethod) {
+					if(ref.tokens.length == 1) {
+						if (qualifiedBinding instanceof LocalVariableBinding) {
+							// complete local variable members with missing variables type
+							// class X {
+							//   void foo() {
+							//     Missing f;
+							//     f.|
+							//   }
+							// }
+							LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
+							findFieldsAndMethodsFromMissingType(
+									localVariableBinding.declaration.type,
+									localVariableBinding.declaringScope,
+									ref,
+									scope);
+						} else {
+							// complete field members with missing fields type
+							// class X {
+							//   Missing f;
+							//   void foo() {
+							//     f.|
+							//   }
+							// }
+							findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+						}
+
+					}
+				}
+			}
+
+		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+			boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
+			ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
+			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+			findMembers(
+					this.completionToken,
+					receiverType,
+					scope,
+					ref,
+					isInsideAnnotationAttribute,
+					null,
+					null,
+					null,
+					false);
+
+		} else if (qualifiedBinding instanceof PackageBinding) {
+
+			setSourceRange(astNode.sourceStart, (int) completionPosition);
+			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+			// replace to the end of the completion identifier
+			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+		}
+	}
+	
+	private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
+			Scope scope) {
+		this.insideQualifiedReference = true;
+
+		CompletionOnQualifiedTypeReference ref =
+			(CompletionOnQualifiedTypeReference) astNode;
+
+		this.assistNodeIsClass = ref.isClass();
+		this.assistNodeIsException = ref.isException();
+		this.assistNodeIsInterface = ref.isInterface();
+		this.assistNodeIsConstructor = ref.isConstructorType;
+		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];
+
+		// get the source positions of the completion identifier
+		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+			if (this.assistNodeInJavadoc == 0 &&
+					(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+				if(ref.tokens.length == 1) {
+					findMemberTypesFromMissingType(
+							ref.tokens[0],
+							ref.sourcePositions[0],
+							scope);
+				}
+			}
+		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+				ObjectVector typesFound = new ObjectVector();
+
+				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+					findExceptionFromTryStatement(
+							this.completionToken,
+							(ReferenceBinding)qualifiedBinding,
+							scope.enclosingSourceType(),
+							(BlockScope)scope,
+							typesFound);
+				}
+				
+				checkCancel();
+
+				findMemberTypes(
+					this.completionToken,
+					(ReferenceBinding) qualifiedBinding,
+					scope,
+					scope.enclosingSourceType(),
+					false,
+					false,
+					typesFound,
+					null,
+					null,
+					null,
+					false);
+			}
+		} else if (qualifiedBinding instanceof PackageBinding) {
+
+			setSourceRange(astNode.sourceStart, (int) completionPosition);
+			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+			// replace to the end of the completion identifier
+			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+		}
+	}
+	
+	private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+			boolean insideTypeAnnotation) {
+		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
+		this.completionToken = singleNameReference.token;
+		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
+		if (switchStatement != null
+				&& switchStatement.expression.resolvedType != null
+				&& switchStatement.expression.resolvedType.isEnum()) {
+			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+				this.assistNodeIsEnum = true;
+				findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
+			}
+		} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+		} else {
+			if (this.expectedTypesPtr > -1) {
+				this.assistNodeIsEnum = true;
+				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+					if (!this.expectedTypes[i].isEnum()) {
+						this.assistNodeIsEnum = false;
+						break done;
+					}
+				}
+
+			}
+			if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
+
+				findUnresolvedReference(
+						singleNameReference.sourceStart,
+						singleNameReference.sourceEnd,
+						(BlockScope)scope,
+						alreadyDefinedName);
+			}
+			
+			checkCancel();
+			
+			findVariablesAndMethods(
+				this.completionToken,
+				scope,
+				singleNameReference,
+				scope,
+				insideTypeAnnotation,
+				singleNameReference.isInsideAnnotationAttribute);
+			
+			checkCancel();
+			
+			// can be the start of a qualified type name
+			findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
+			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+				if (this.completionToken != null && this.completionToken.length != 0) {
+					findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
+				} else {
+					findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
+				}
+			}
+			if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
+				if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
+					ReferenceBinding ref = scope.enclosingSourceType();
+					findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
+				} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
+					ReferenceBinding ref = scope.enclosingSourceType();
+					findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
+				}
+			}
+		}
+	}
+	
+	private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+		CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
+
+		this.completionToken = singleRef.token;
+
+		this.assistNodeIsClass = singleRef.isClass();
+		this.assistNodeIsException = singleRef.isException();
+		this.assistNodeIsInterface = singleRef.isInterface();
+		this.assistNodeIsConstructor = singleRef.isConstructorType;
+		this.assistNodeIsSuperType = singleRef.isSuperType();
+		this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+		this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
+		
+		// can be the start of a qualified type name
+		if (qualifiedBinding == null) {
+			if (this.completionToken.length == 0 &&
+					(astNodeParent instanceof ParameterizedSingleTypeReference ||
+							astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
+				this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
+
+				findParameterizedType((TypeReference)astNodeParent, scope);
+			} else {
+				ObjectVector typesFound = new ObjectVector();
+				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+					findExceptionFromTryStatement(
+							this.completionToken,
+							null,
+							scope.enclosingSourceType(),
+							(BlockScope)scope,
+							typesFound);
+				}
+				
+				checkCancel();
+				
+				findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
+			}
+		} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			findMemberTypes(
+				this.completionToken,
+				(ReferenceBinding) qualifiedBinding,
+				scope,
+				scope.enclosingSourceType(),
+				false,
+				false,
+				false,
+				false,
+				!this.assistNodeIsConstructor,
+				null,
+				new ObjectVector(),
+				null,
+				null,
+				null,
+				false);
+		}
+	}
+
+	private char[][] computeAlreadyDefinedName(
+			BlockScope scope,
+			InvocationSite invocationSite) {
+		ArrayList result = new ArrayList();
+
+		boolean staticsOnly = false;
+
+		Scope currentScope = scope;
+
+		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (currentScope.kind) {
+
+				case Scope.METHOD_SCOPE :
+					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+					MethodScope methodScope = (MethodScope) currentScope;
+					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+
+				//$FALL-THROUGH$
+				case Scope.BLOCK_SCOPE :
+					BlockScope blockScope = (BlockScope) currentScope;
+
+					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+						LocalVariableBinding local = blockScope.locals[i];
+
+						if (local == null)
+							break next;
+
+						if (local.isSecret())
+							continue next;
+
+						result.add(local.name);
+					}
+					break;
+
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) currentScope;
+					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+					computeAlreadyDefinedName(
+							enclosingType,
+							classScope,
+							staticsOnly,
+							invocationSite,
+							result);
+					staticsOnly |= enclosingType.isStatic();
+					break;
+
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done1;
+			}
+			currentScope = currentScope.parent;
+		}
+
+		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
+
+		return (char[][])result.toArray(new char[result.size()][]);
+	}
+
+	private void computeAlreadyDefinedName(
+			FieldBinding[] fields,
+			Scope scope,
+			boolean onlyStaticFields,
+			ReferenceBinding receiverType,
+			InvocationSite invocationSite,
+			ArrayList result) {
+
+		next : for (int f = fields.length; --f >= 0;) {
+			FieldBinding field = fields[f];
+
+			if (field.isSynthetic()) continue next;
+
+			if (onlyStaticFields && !field.isStatic()) continue next;
+
+			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			result.add(field.name);
+		}
+	}
+
+	private void computeAlreadyDefinedName(
+			SourceTypeBinding receiverType,
+			ClassScope scope,
+			boolean onlyStaticFields,
+			InvocationSite invocationSite,
+			ArrayList result) {
+
+		ReferenceBinding currentType = receiverType;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		do {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+
+			FieldBinding[] fields = currentType.availableFields();
+			if(fields != null && fields.length > 0) {
+				computeAlreadyDefinedName(
+					fields,
+					scope,
+					onlyStaticFields,
+					receiverType,
+					invocationSite,
+					result);
+			}
+			currentType = currentType.superclass();
+		} while ( currentType != null);
+
+		if (interfacesToVisit != null) {
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				FieldBinding[] fields = anInterface.availableFields();
+				if(fields !=  null) {
+					computeAlreadyDefinedName(
+						fields,
+						scope,
+						onlyStaticFields,
+						receiverType,
+						invocationSite,
+						result);
+				}
+
+				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	int computeBaseRelevance(){
+		return R_DEFAULT;
+	}
+
+	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
+
+		// default filter
+		this.expectedTypesFilter = SUBTYPE;
+		this.hasJavaLangObjectAsExpectedType = false;
+
+		// find types from parent
+		if(parent instanceof AbstractVariableDeclaration && !(parent instanceof TypeParameter)) {
+			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
+			TypeBinding binding = variable.type.resolvedType;
+			if(binding != null) {
+				if(!(variable.initialization instanceof ArrayInitializer)) {
+					addExpectedType(binding, scope);
+				} else { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310747
+					// If the variable is of type X[], and we're in the initializer
+					// we should have X as the expected type for the variable initializers.
+					binding = binding.leafComponentType();
+					addExpectedType(binding, scope);
+				}
+			}
+		} else if(parent instanceof Assignment) {
+			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
+			if(binding != null) {
+				addExpectedType(binding, scope);
+			}
+		} else if(parent instanceof ReturnStatement) {
+			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
+				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
+				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
+				if(binding != null) {
+					addExpectedType(binding, scope);
+				}
+			}
+		} else if(parent instanceof CastExpression) {
+			TypeReference e = ((CastExpression)parent).type;
+			TypeBinding binding = e.resolvedType;
+			if(binding != null){
+				addExpectedType(binding, scope);
+				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+			}
+		} else if(parent instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) parent;
+
+			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
+				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
+				boolean isStatic = messageSend.receiver.isTypeReference();
+
+				while(binding != null) {
+					computeExpectedTypesForMessageSend(
+						binding,
+						messageSend.selector,
+						messageSend.arguments,
+						(ReferenceBinding)messageSend.actualReceiverType,
+						scope,
+						messageSend,
+						isStatic);
+					computeExpectedTypesForMessageSendForInterface(
+						binding,
+						messageSend.selector,
+						messageSend.arguments,
+						(ReferenceBinding)messageSend.actualReceiverType,
+						scope,
+						messageSend,
+						isStatic);
+					binding = binding.superclass();
+				}
+			}
+		} else if(parent instanceof AllocationExpression) {
+			AllocationExpression allocationExpression = (AllocationExpression) parent;
+
+			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
+
+			if(binding != null) {
+				computeExpectedTypesForAllocationExpression(
+					binding,
+					allocationExpression.arguments,
+					scope,
+					allocationExpression);
+			}
+		} else if(parent instanceof OperatorExpression) {
+			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+			if(parent instanceof ConditionalExpression) {
+				// for future use
+			} else if(parent instanceof InstanceOfExpression) {
+				InstanceOfExpression e = (InstanceOfExpression) parent;
+				TypeBinding binding = e.expression.resolvedType;
+				if(binding != null){
+					addExpectedType(binding, scope);
+					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+				}
+			} else if(parent instanceof BinaryExpression) {
+				BinaryExpression binaryExpression = (BinaryExpression) parent;
+				switch(operator) {
+					case OperatorIds.EQUAL_EQUAL :
+						// expected type is not relevant in this case
+						TypeBinding binding = binaryExpression.left.resolvedType;
+						if (binding != null) {
+							addExpectedType(binding, scope);
+							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+						}
+						break;
+					case OperatorIds.PLUS :
+						addExpectedType(TypeBinding.SHORT, scope);
+						addExpectedType(TypeBinding.INT, scope);
+						addExpectedType(TypeBinding.LONG, scope);
+						addExpectedType(TypeBinding.FLOAT, scope);
+						addExpectedType(TypeBinding.DOUBLE, scope);
+						addExpectedType(TypeBinding.CHAR, scope);
+						addExpectedType(TypeBinding.BYTE, scope);
+						addExpectedType(scope.getJavaLangString(), scope);
+						break;
+					case OperatorIds.AND_AND :
+					case OperatorIds.OR_OR :
+					case OperatorIds.XOR :
+						addExpectedType(TypeBinding.BOOLEAN, scope);
+						break;
+					default :
+						addExpectedType(TypeBinding.SHORT, scope);
+						addExpectedType(TypeBinding.INT, scope);
+						addExpectedType(TypeBinding.LONG, scope);
+						addExpectedType(TypeBinding.FLOAT, scope);
+						addExpectedType(TypeBinding.DOUBLE, scope);
+						addExpectedType(TypeBinding.CHAR, scope);
+						addExpectedType(TypeBinding.BYTE, scope);
+						break;
+				}
+				if(operator == OperatorIds.LESS) {
+					if(binaryExpression.left instanceof SingleNameReference){
+						SingleNameReference name = (SingleNameReference) binaryExpression.left;
+						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
+						if(b instanceof ReferenceBinding) {
+							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
+							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
+								addExpectedType(typeVariableBindings[0].firstBound, scope);
+							}
+
+						}
+					}
+				}
+			} else if(parent instanceof UnaryExpression) {
+				switch(operator) {
+					case OperatorIds.NOT :
+						addExpectedType(TypeBinding.BOOLEAN, scope);
+						break;
+					case OperatorIds.TWIDDLE :
+						addExpectedType(TypeBinding.SHORT, scope);
+						addExpectedType(TypeBinding.INT, scope);
+						addExpectedType(TypeBinding.LONG, scope);
+						addExpectedType(TypeBinding.CHAR, scope);
+						addExpectedType(TypeBinding.BYTE, scope);
+						break;
+					case OperatorIds.PLUS :
+					case OperatorIds.MINUS :
+					case OperatorIds.PLUS_PLUS :
+					case OperatorIds.MINUS_MINUS :
+						addExpectedType(TypeBinding.SHORT, scope);
+						addExpectedType(TypeBinding.INT, scope);
+						addExpectedType(TypeBinding.LONG, scope);
+						addExpectedType(TypeBinding.FLOAT, scope);
+						addExpectedType(TypeBinding.DOUBLE, scope);
+						addExpectedType(TypeBinding.CHAR, scope);
+						addExpectedType(TypeBinding.BYTE, scope);
+						break;
+				}
+			}
+		} else if(parent instanceof ArrayReference) {
+			addExpectedType(TypeBinding.SHORT, scope);
+			addExpectedType(TypeBinding.INT, scope);
+			addExpectedType(TypeBinding.LONG, scope);
+		} else if(parent instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
+			TypeBinding expected = null;
+			if (this.parser.enclosingNode instanceof AbstractVariableDeclaration ||
+					this.parser.enclosingNode instanceof ReturnStatement) {
+				// completing inside the diamond
+				if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) {
+					AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode;
+					expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null;					
+				} else {
+					ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode;
+					if (returnStatement.expression != null) {
+						expected = returnStatement.expression.expectedType();
+					}
+				}	
+				addExpectedType(expected, scope);
+			} else {
+				TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+				int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
+				if(typeVariables != null && typeVariables.length >= length) {
+					int index = length - 1;
+					while(index > -1 && ref.typeArguments[index] != node) index--;
+	
+					TypeBinding bound = typeVariables[index].firstBound;
+					addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+				}
+			}
+		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
+			TypeReference[][] arguments = ref.typeArguments;
+			TypeBinding expected = null;
+			if (this.parser.enclosingNode instanceof AbstractVariableDeclaration ||
+					this.parser.enclosingNode instanceof ReturnStatement) {
+				// completing inside the diamond
+				if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) {
+					AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode;
+					expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null;
+				} else {
+					ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode;
+					if (returnStatement.expression != null) {
+						expected = returnStatement.expression.expectedType();
+					}
+				}
+				addExpectedType(expected, scope);
+			} else {
+				TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+				if(typeVariables != null) {
+					int iLength = arguments == null ? 0 : arguments.length;
+					done: for (int i = 0; i < iLength; i++) {
+						int jLength = arguments[i] == null ? 0 : arguments[i].length;
+						for (int j = 0; j < jLength; j++) {
+							if(arguments[i][j] == node && typeVariables.length > j) {
+								TypeBinding bound = typeVariables[j].firstBound;
+								addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+								break done;
+							}
+						}
+					}
+				}
+			}
+		} else if(parent instanceof MemberValuePair) {
+			MemberValuePair memberValuePair = (MemberValuePair) parent;
+			if(memberValuePair.binding != null) {
+				addExpectedType(memberValuePair.binding.returnType, scope);
+			}
+		} else if (parent instanceof NormalAnnotation) {
+			NormalAnnotation annotation = (NormalAnnotation) parent;
+			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+			if(memberValuePairs == null || memberValuePairs.length == 0) {
+				if(annotation.resolvedType instanceof ReferenceBinding) {
+					MethodBinding[] methodBindings =
+						((ReferenceBinding)annotation.resolvedType).availableMethods();
+					if (methodBindings != null &&
+							methodBindings.length > 0 &&
+							CharOperation.equals(methodBindings[0].selector, VALUE)) {
+						boolean canBeSingleMemberAnnotation = true;
+						done : for (int i = 1; i < methodBindings.length; i++) {
+							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
+								canBeSingleMemberAnnotation = false;
+								break done;
+							}
+						}
+						if (canBeSingleMemberAnnotation) {
+							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
+							addExpectedType(methodBindings[0].returnType, scope);
+						}
+					}
+				}
+			}
+		} else if (parent instanceof TryStatement) {
+			boolean isException = false;
+			if (node instanceof CompletionOnSingleTypeReference) {
+				isException = ((CompletionOnSingleTypeReference)node).isException();
+			} else if (node instanceof CompletionOnQualifiedTypeReference) {
+				isException = ((CompletionOnQualifiedTypeReference)node).isException();
+			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
+				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
+			}
+			if (isException) {
+				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
+				thrownExceptionFinder.processThrownExceptions((TryStatement) parent, (BlockScope)scope);
+				ReferenceBinding[] bindings = thrownExceptionFinder.getThrownUncaughtExceptions();
+				ReferenceBinding[] alreadyCaughtExceptions = thrownExceptionFinder.getAlreadyCaughtExceptions();
+				ReferenceBinding[] discouragedExceptions = thrownExceptionFinder.getDiscouragedExceptions();
+				if (bindings != null && bindings.length > 0) {
+					for (int i = 0; i < bindings.length; i++) {
+						addExpectedType(bindings[i], scope);
+					}
+					this.expectedTypesFilter = SUPERTYPE;
+				}
+				if (alreadyCaughtExceptions != null && alreadyCaughtExceptions.length > 0) {
+					for (int i = 0; i < alreadyCaughtExceptions.length; i++) {
+						addForbiddenBindings(alreadyCaughtExceptions[i]);
+						this.knownTypes.put(CharOperation.concat(alreadyCaughtExceptions[i].qualifiedPackageName(), alreadyCaughtExceptions[i].qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+					}
+				}
+				if (discouragedExceptions != null && discouragedExceptions.length > 0) {
+					for (int i = 0; i < discouragedExceptions.length; i++) {
+						addUninterestingBindings(discouragedExceptions[i]);
+						// do not insert into known types. We do need these types to come from
+						// searchAllTypes(..) albeit with lower relevance
+					}
+				}
+			}
+		} else if (parent instanceof SwitchStatement) {
+			SwitchStatement switchStatement = (SwitchStatement) parent;
+			this.assistNodeIsInsideCase = assistNodeIsInsideCase(node, parent);
+			if (switchStatement.expression != null &&
+					switchStatement.expression.resolvedType != null) {
+				if (this.assistNodeIsInsideCase &&
+						switchStatement.expression.resolvedType.id == TypeIds.T_JavaLangString &&
+						this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_7) {
+					// set the field to true even though the expected types array will contain String as
+					// expected type to avoid traversing the array in every case later on.
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476
+					this.assistNodeIsString = true;
+				}
+				addExpectedType(switchStatement.expression.resolvedType, scope);
+			}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008, flag boolean as the expected
+		// type if we are completing inside if(), for (; ;), while() and do while()
+		} else if (parent instanceof WhileStatement) {  // covers both while and do-while loops
+			addExpectedType(TypeBinding.BOOLEAN, scope);
+		} else if (parent instanceof IfStatement) {  
+			addExpectedType(TypeBinding.BOOLEAN, scope);
+		} else if (parent instanceof AssertStatement) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466
+			// If the assertExpression is same as the node , then the assistNode is the conditional part of the assert statement
+			AssertStatement assertStatement = (AssertStatement) parent;
+			if (assertStatement.assertExpression == node) {
+				addExpectedType(TypeBinding.BOOLEAN, scope);
+			}
+		} else if (parent instanceof ForStatement) {   // astNodeParent set to ForStatement only for the condition  
+			addExpectedType(TypeBinding.BOOLEAN, scope);
+
+		// Expected types for javadoc
+		} else if (parent instanceof Javadoc) {
+			if (scope.kind == Scope.METHOD_SCOPE) {
+				MethodScope methodScope = (MethodScope) scope;
+				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
+				if (methodDecl != null && methodDecl.binding != null) {
+					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
+					if (exceptions != null) {
+						for (int i = 0; i < exceptions.length; i++) {
+							addExpectedType(exceptions[i], scope);
+						}
+					}
+				}
+			}
+		}
+
+		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
+			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
+		}
+	}
+
+	private void computeExpectedTypesForAllocationExpression(
+		ReferenceBinding binding,
+		Expression[] arguments,
+		Scope scope,
+		InvocationSite invocationSite) {
+
+		MethodBinding[] methods = binding.availableMethods();
+		nextMethod : for (int i = 0; i < methods.length; i++) {
+			MethodBinding method = methods[i];
+
+			if (!method.isConstructor()) continue nextMethod;
+
+			if (method.isSynthetic()) continue nextMethod;
+
+			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
+
+			TypeBinding[] parameters = method.parameters;
+			if(parameters.length < arguments.length)
+				continue nextMethod;
+
+			int length = arguments.length - 1;
+
+			for (int j = 0; j < length; j++) {
+				Expression argument = arguments[j];
+				TypeBinding argType = argument.resolvedType;
+				if(argType != null && !argType.isCompatibleWith(parameters[j]))
+					continue nextMethod;
+			}
+
+			TypeBinding expectedType = method.parameters[arguments.length - 1];
+			if(expectedType != null) {
+				addExpectedType(expectedType, scope);
+			}
+		}
+	}
+	private void computeExpectedTypesForMessageSend(
+		ReferenceBinding binding,
+		char[] selector,
+		Expression[] arguments,
+		ReferenceBinding receiverType,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean isStatic) {
+
+		MethodBinding[] methods = binding.availableMethods();
+		nextMethod : for (int i = 0; i < methods.length; i++) {
+			MethodBinding method = methods[i];
+
+			if (method.isSynthetic()) continue nextMethod;
+
+			if (method.isDefaultAbstract())	continue nextMethod;
+
+			if (method.isConstructor()) continue nextMethod;
+
+			if (isStatic && !method.isStatic()) continue nextMethod;
+
+			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
+
+			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
+
+			TypeBinding[] parameters = method.parameters;
+			if(parameters.length < arguments.length)
+				continue nextMethod;
+
+			int length = arguments.length - 1;
+
+			for (int j = 0; j < length; j++) {
+				Expression argument = arguments[j];
+				TypeBinding argType = argument.resolvedType;
+				if(argType != null && !argType.isCompatibleWith(parameters[j]))
+					continue nextMethod;
+			}
+
+			TypeBinding expectedType = method.parameters[arguments.length - 1];
+			if(expectedType != null) {
+				addExpectedType(expectedType, scope);
+			}
+		}
+	}
+	private void computeExpectedTypesForMessageSendForInterface(
+		ReferenceBinding binding,
+		char[] selector,
+		Expression[] arguments,
+		ReferenceBinding receiverType,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean isStatic) {
+
+		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding currentType = interfacesToVisit[i];
+				computeExpectedTypesForMessageSend(
+					currentType,
+					selector,
+					arguments,
+					receiverType,
+					scope,
+					invocationSite,
+					isStatic);
+
+				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
+		if(scope instanceof ClassScope) {
+			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
+			if(typeDeclaration.superclass == astNode) {
+				addForbiddenBindings(typeDeclaration.binding);
+				addForbiddenBindingsForMemberTypes(typeDeclaration);
+				return scope.parent;
+			}
+			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+			int length = superInterfaces == null ? 0 : superInterfaces.length;
+			int astNodeIndex = -1;
+			for (int i = 0; i < length; i++) {
+				if(superInterfaces[i] == astNode) {
+					addForbiddenBindings(typeDeclaration.binding);
+					addForbiddenBindingsForMemberTypes(typeDeclaration);
+					astNodeIndex = i;
+					break;
+				}
+			}
+			if (astNodeIndex >= 0) {
+				// Need to loop only up to astNodeIndex as the rest will be undefined.
+				for (int i = 0; i < astNodeIndex; i++) {
+					addForbiddenBindings(superInterfaces[i].resolvedType);
+				}
+				return scope.parent;
+			}
+		}
+//		else if(scope instanceof MethodScope) {
+//			MethodScope methodScope = (MethodScope) scope;
+//			if(methodScope.insideTypeAnnotation) {
+//				return methodScope.parent.parent;
+//			}
+//		}
+		return scope;
+	}
+
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437
+	private void addForbiddenBindingsForMemberTypes(TypeDeclaration typeDeclaration) {
+		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+		int memberTypesLen = memberTypes == null ? 0 : memberTypes.length;
+		for (int i = 0; i < memberTypesLen; i++) {
+			addForbiddenBindings(memberTypes[i].binding);
+			addForbiddenBindingsForMemberTypes(memberTypes[i]);
+		}
+	}
+
+	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
+
+		StringBuffer completion = new StringBuffer(10);
+
+		if (isStatic) {
+			completion.append(declarationType.sourceName());
+
+		} else if (declarationType == invocationType) {
+			completion.append(THIS);
+
+		} else {
+
+			if (!declarationType.isNestedType()) {
+
+				completion.append(declarationType.sourceName());
+				completion.append('.');
+				completion.append(THIS);
+
+			} else if (!declarationType.isAnonymousType()) {
+
+				completion.append(declarationType.sourceName());
+				completion.append('.');
+				completion.append(THIS);
+
+			}
+		}
+
+		return completion.toString().toCharArray();
+	}
+
+	private int computeRelevanceForAnnotation(){
+		if(this.assistNodeIsAnnotation) {
+			return R_ANNOTATION;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
+		if (this.assistNodeIsAnnotation &&
+				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
+			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+			if(target == 0 || (target & this.targetedElement) != 0) {
+				return R_TARGET;
+			}
+		}
+		return 0;
+	}
+	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
+		if (this.options.camelCaseMatch) {
+			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+				return R_CASE + R_EXACT_NAME;
+			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+				return R_CASE;
+			} else if (CharOperation.camelCaseMatch(token, proposalName)){
+				return R_CAMEL_CASE;
+			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+				return R_EXACT_NAME;
+			}
+		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+				return R_CASE + R_EXACT_NAME;
+			} else {
+				return R_CASE;
+			}
+		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+			return R_EXACT_NAME;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForClass(){
+		if(this.assistNodeIsClass) {
+			return R_CLASS;
+		}
+		return 0;
+	}
+	
+	private int computeRelevanceForConstructor() {
+		if (this.assistNodeIsConstructor) {
+			return R_CONSTRUCTOR;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForEnum(){
+		if(this.assistNodeIsEnum) {
+			return R_ENUM;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
+		if(this.assistNodeIsEnum &&
+				proposalType != null &&
+				this.expectedTypes != null) {
+			for (int i = 0; i <= this.expectedTypesPtr; i++) {
+				if (proposalType.isEnum() &&
+						proposalType == this.expectedTypes[i]) {
+					return R_ENUM + R_ENUM_CONSTANT;
+				}
+
+			}
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForException(){
+		if (this.assistNodeIsException) {
+			return R_EXCEPTION;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForException(char[] proposalName){
+
+		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
+			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
+			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
+			return R_EXCEPTION;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
+		if(this.expectedTypes != null) {
+			for (int i = 0; i <= this.expectedTypesPtr; i++) {
+				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
+					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
+					return R_EXACT_EXPECTED_TYPE;
+				}
+			}
+			if(this.hasJavaLangObjectAsExpectedType) {
+				return R_EXPECTED_TYPE;
+			}
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForExpectingType(TypeBinding proposalType){
+		if(this.expectedTypes != null && proposalType != null) {
+			int relevance = 0;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296
+			// If there is at least one expected type, then void proposal types attract a degraded relevance.  
+			if (proposalType == TypeBinding.VOID && this.expectedTypesPtr >=0) {
+				return R_VOID;
+			}	
+			for (int i = 0; i <= this.expectedTypesPtr; i++) {
+				if((this.expectedTypesFilter & SUBTYPE) != 0
+						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
+
+					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+						return R_EXACT_EXPECTED_TYPE;
+					}
+
+					relevance = R_EXPECTED_TYPE;
+				}
+				if((this.expectedTypesFilter & SUPERTYPE) != 0
+						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
+
+					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+						return R_EXACT_EXPECTED_TYPE;
+					}
+
+					relevance = R_EXPECTED_TYPE;
+				}
+				// Bug 84720 - [1.5][assist] proposal ranking by return value should consider auto(un)boxing
+				// Just ensuring that the unitScope is not null, even though it's an unlikely case.
+				if (this.unitScope != null && this.unitScope.isBoxingCompatibleWith(proposalType, this.expectedTypes[i])) {
+					relevance = R_EXPECTED_TYPE;
+				}
+			}
+			return relevance;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
+		if (receiverType == declaringClass) return R_NON_INHERITED;
+		return 0;
+	}
+
+	int computeRelevanceForInterestingProposal(){
+		return computeRelevanceForInterestingProposal(null);
+	}
+
+	private int computeRelevanceForInterestingProposal(Binding binding){
+		if(this.uninterestingBindings != null) {
+			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
+				if(this.uninterestingBindings[i] == binding) {
+					return 0;
+				}
+				if((this.uninterestingBindingsFilter & SUBTYPE) != 0) {
+					if (binding instanceof TypeBinding &&
+							this.uninterestingBindings[i] instanceof TypeBinding &&
+							((TypeBinding)binding).isCompatibleWith((TypeBinding)this.uninterestingBindings[i])) {
+						return 0;
+					}
+				}
+				if ((this.uninterestingBindingsFilter & SUPERTYPE) != 0) {
+					if (binding instanceof TypeBinding &&
+							this.uninterestingBindings[i] instanceof TypeBinding &&
+							((TypeBinding)this.uninterestingBindings[i]).isCompatibleWith((TypeBinding)binding)) {
+						return 0;
+					}
+				}
+			}
+		}
+		return R_INTERESTING;
+	}
+	
+	private int computeRelevanceForInterestingProposal(char[] givenPkgName, char[] fullTypeName) {
+		for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
+			if (this.uninterestingBindings[i] instanceof TypeBinding) {
+				TypeBinding typeBinding = (TypeBinding) this.uninterestingBindings[i];
+				char[] currPkgName = typeBinding.qualifiedPackageName();
+				if (CharOperation.equals(givenPkgName, currPkgName))	{
+					char[] currTypeName = typeBinding.qualifiedSourceName();
+					if (CharOperation.equals(fullTypeName, currTypeName)) {
+						return 0;
+					}
+				}
+			}
+		}
+		return R_INTERESTING;
+	}
+
+	private int computeRelevanceForInterface(){
+		if(this.assistNodeIsInterface) {
+			return R_INTERFACE;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForMissingElements(boolean hasProblems) {
+		if (!hasProblems) {
+			return R_NO_PROBLEMS;
+		}
+		return 0;
+	}
+	int computeRelevanceForQualification(boolean prefixRequired) {
+		if(!prefixRequired && !this.insideQualifiedReference) {
+			return R_UNQUALIFIED;
+		}
+
+		if(prefixRequired && this.insideQualifiedReference) {
+			return R_QUALIFIED;
+		}
+		return 0;
+	}
+
+	int computeRelevanceForResolution(){
+		return computeRelevanceForResolution(true);
+	}
+
+	int computeRelevanceForResolution(boolean isResolved){
+		if (isResolved) {
+			return R_RESOLVED;
+		}
+		return 0;
+	}
+
+	int computeRelevanceForRestrictions(int accessRuleKind) {
+		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
+			return R_NON_RESTRICTED;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
+		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
+			return R_NON_STATIC;
+		}
+		return 0;
+	}
+	
+	private int computeRelevanceForFinal(boolean onlyFinal, boolean isFinal) {
+		if (onlyFinal && isFinal) {
+			return R_FINAL;
+		}
+		return 0;
+	}
+
+	private int computeRelevanceForSuper(MethodBinding method, Scope scope, InvocationSite site) {
+		if (site instanceof CompletionOnMemberAccess) {
+			CompletionOnMemberAccess access = (CompletionOnMemberAccess) site;
+			if (access.isSuperAccess() && this.parser.assistNodeParent == null) {
+				ReferenceContext referenceContext = scope.referenceContext();
+				if (referenceContext instanceof AbstractMethodDeclaration) {
+					MethodBinding binding = ((AbstractMethodDeclaration) referenceContext).binding;
+					if (binding != null) {
+						if (CharOperation.equals(binding.selector, method.selector)) {
+							if (binding.areParameterErasuresEqual(method)) {
+								return R_EXACT_NAME + R_METHOD_OVERIDE;
+							}
+							return R_EXACT_NAME;
+						}
+					}
+				}
+			}
+		}
+		return 0;
+	}
+
+	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
+		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
+
+		if (annotatedElement instanceof TypeDeclaration) {
+			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
+			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
+				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
+			}
+			return TagBits.AnnotationForType;
+		} else if (annotatedElement instanceof FieldDeclaration) {
+			if (fakeNode.isParameter) {
+				return TagBits.AnnotationForParameter;
+			}
+			return TagBits.AnnotationForField;
+		} else if (annotatedElement instanceof MethodDeclaration) {
+			return TagBits.AnnotationForMethod;
+		} else if (annotatedElement instanceof Argument) {
+			return TagBits.AnnotationForParameter;
+		} else if (annotatedElement instanceof ConstructorDeclaration) {
+			return TagBits.AnnotationForConstructor;
+		} else if (annotatedElement instanceof LocalDeclaration) {
+			return TagBits.AnnotationForLocalVariable;
+		} else if (annotatedElement instanceof ImportReference) {
+			return TagBits.AnnotationForPackage;
+		}
+		return 0;
+	}
+	private TypeBinding[] computeTypes(Expression[] arguments) {
+		if (arguments == null) return null;
+		int argsLength = arguments.length;
+		TypeBinding[] argTypes = new TypeBinding[argsLength];
+		for (int a = argsLength; --a >= 0;) {
+			argTypes[a] = arguments[a].resolvedType;
+		}
+		return argTypes;
+	}
+
+	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
+		if (arguments == null) return null;
+		int argsLength = arguments.length;
+		TypeBinding[] argTypes = new TypeBinding[argsLength];
+		for (int a = argsLength; --a >= 0;) {
+			TypeBinding typeBinding = arguments[a].resolvedType;
+			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
+			argTypes[a] = typeBinding;
+		}
+		return argTypes;
+	}
+
+	private void computeUninterestingBindings(ASTNode astNode, ASTNode parent, Scope scope){
+		this.uninterestingBindingsFilter = NONE;
+		if(parent instanceof LocalDeclaration) {
+			addUninterestingBindings(((LocalDeclaration)parent).binding);
+		} else if (parent instanceof FieldDeclaration) {
+			addUninterestingBindings(((FieldDeclaration)parent).binding);
+		} else if (parent instanceof TryStatement) {
+			boolean isException = false;
+			if (astNode instanceof CompletionOnSingleTypeReference) {
+				isException = ((CompletionOnSingleTypeReference)astNode).isException();
+			} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+				isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
+			} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+				isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
+			}
+			if (isException) {
+				this.uninterestingBindingsFilter |= SUBTYPE;
+				// super-types also need to be discouraged if we're in a union type (bug 350652)
+				Argument[] args = ((TryStatement)parent).catchArguments;
+				for (int i = 0; i < args.length; i++) {
+					if (args[i].type instanceof UnionTypeReference) {
+						CompletionNodeDetector detector = new CompletionNodeDetector(astNode, args[i]);
+						if (detector.containsCompletionNode()) {
+							this.uninterestingBindingsFilter |= SUPERTYPE;
+							break;
+						}
+					}
+				}
+				
+			}
+		}
+	}
+
+	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
+		char[] result = IMPORT;
+		if (isStatic) {
+			result = CharOperation.concat(result, STATIC, ' ');
+		}
+		result = CharOperation.concat(result, importedElement, ' ');
+		if (onDemand) {
+			result = CharOperation.concat(result, ON_DEMAND);
+		}
+		return CharOperation.concat(result, IMPORT_END);
+	}
+
+	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
+		//// Modifiers
+		// flush uninteresting modifiers
+		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
+		if(insertedModifiers != ClassFileConstants.AccDefault){
+			ASTNode.printModifiers(insertedModifiers, completion);
+		}
+
+		//// Type parameters
+
+		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
+		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
+			completion.append('<');
+			for (int i = 0; i < typeVariableBindings.length; i++) {
+				if(i != 0) {
+					completion.append(',');
+					completion.append(' ');
+				}
+				createTypeVariable(typeVariableBindings[i], scope, completion);
+			}
+			completion.append('>');
+			completion.append(' ');
+		}
+
+		//// Return type
+		createType(method.returnType, scope, completion);
+		completion.append(' ');
+
+		//// Selector
+		completion.append(method.selector);
+
+		completion.append('(');
+
+		////Parameters
+		TypeBinding[] parameterTypes = method.parameters;
+		int length = parameterTypes.length;
+		for (int i = 0; i < length; i++) {
+			if(i != 0) {
+				completion.append(',');
+				completion.append(' ');
+			}
+			createType(parameterTypes[i], scope, completion);
+			completion.append(' ');
+			if(parameterNames != null){
+				completion.append(parameterNames[i]);
+			} else {
+				completion.append('%');
+			}
+		}
+
+		completion.append(')');
+
+		//// Exceptions
+		ReferenceBinding[] exceptions = method.thrownExceptions;
+
+		if (exceptions != null && exceptions.length > 0){
+			completion.append(' ');
+			completion.append(THROWS);
+			completion.append(' ');
+			for(int i = 0; i < exceptions.length ; i++){
+				if(i != 0) {
+					completion.append(' ');
+					completion.append(',');
+				}
+				createType(exceptions[i], scope, completion);
+			}
+		}
+	}
+
+	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
+		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
+		proposal.nameLookup = this.nameEnvironment.nameLookup;
+		proposal.completionEngine = this;
+		return proposal;
+	}
+
+	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
+		InternalCompletionProposal proposal = null;
+		if (binding instanceof ReferenceBinding) {
+			ReferenceBinding typeBinding = (ReferenceBinding) binding;
+
+			char[] packageName = typeBinding.qualifiedPackageName();
+			char[] typeName = typeBinding.qualifiedSourceName();
+			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+
+			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setDeclarationSignature(packageName);
+			proposal.setSignature(getRequiredTypeSignature(typeBinding));
+			proposal.setPackageName(packageName);
+			proposal.setTypeName(typeName);
+			proposal.setCompletion(fullyQualifiedName);
+			proposal.setFlags(typeBinding.modifiers);
+			proposal.setReplaceRange(start - this.offset, end - this.offset);
+			proposal.setTokenRange(start - this.offset, end - this.offset);
+			proposal.setRelevance(relevance);
+		} else if (binding instanceof PackageBinding) {
+			PackageBinding packageBinding = (PackageBinding) binding;
+
+			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
+
+			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
+			proposal.setDeclarationSignature(packageName);
+			proposal.setPackageName(packageName);
+			proposal.setCompletion(packageName);
+			proposal.setReplaceRange(start - this.offset, end - this.offset);
+			proposal.setTokenRange(start - this.offset, end - this.offset);
+			proposal.setRelevance(relevance);
+		}
+		return proposal;
+	}
+
+	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
+		switch (type.kind()) {
+			case Binding.BASE_TYPE :
+				completion.append(type.sourceName());
+				break;
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
+				WildcardBinding wildcardBinding = (WildcardBinding) type;
+				completion.append('?');
+				switch (wildcardBinding.boundKind) {
+					case Wildcard.EXTENDS:
+						completion.append(' ');
+						completion.append(EXTENDS);
+						completion.append(' ');
+						createType(wildcardBinding.bound, scope, completion);
+						if(wildcardBinding.otherBounds != null) {
+
+							int length = wildcardBinding.otherBounds.length;
+							for (int i = 0; i < length; i++) {
+								completion.append(' ');
+								completion.append('&');
+								completion.append(' ');
+								createType(wildcardBinding.otherBounds[i], scope, completion);
+							}
+						}
+						break;
+					case Wildcard.SUPER:
+						completion.append(' ');
+						completion.append(SUPER);
+						completion.append(' ');
+						createType(wildcardBinding.bound, scope, completion);
+						break;
+				}
+				break;
+			case Binding.ARRAY_TYPE :
+				createType(type.leafComponentType(), scope, completion);
+				int dim = type.dimensions();
+				for (int i = 0; i < dim; i++) {
+					completion.append('[');
+					completion.append(']');
+				}
+				break;
+			case Binding.PARAMETERIZED_TYPE :
+				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
+				if (type.isMemberType()) {
+					createType(parameterizedType.enclosingType(), scope, completion);
+					completion.append('.');
+					completion.append(parameterizedType.sourceName);
+				} else {
+					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
+				}
+				if (parameterizedType.arguments != null) {
+					completion.append('<');
+				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
+				        if (i != 0) completion.append(',');
+				        createType(parameterizedType.arguments[i], scope, completion);
+				    }
+				    completion.append('>');
+				}
+				break;
+			default :
+				char[] packageName = type.qualifiedPackageName();
+			char[] typeName = type.qualifiedSourceName();
+			if(mustQualifyType(
+					(ReferenceBinding)type,
+					packageName,
+					scope)) {
+				completion.append(CharOperation.concat(packageName, typeName,'.'));
+			} else {
+				completion.append(type.sourceName());
+			}
+			break;
+		}
+	}
+
+	/*
+	 * Create a completion proposal for a member type.
+	 */
+	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
+		char[] completionName = typeParameter.name;
+
+		// Create standard type proposal
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setSignature(getSignature(typeParameter.binding));
+			proposal.setTypeName(completionName);
+			proposal.setCompletion(completionName);
+			proposal.setFlags(typeParameter.modifiers);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+
+		// Create javadoc text proposal if necessary
+		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setSignature(getSignature(typeParameter.binding));
+			proposal.setTypeName(javadocCompletion);
+			proposal.setCompletion(javadocCompletion);
+			proposal.setFlags(typeParameter.modifiers);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance+R_INLINE_TAG);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+	}
+
+	/*
+	 * Create a completion proposal for a type.
+	 */
+	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
+
+		// Create standard type proposal
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setDeclarationSignature(packageName);
+			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+			proposal.setPackageName(packageName);
+			proposal.setTypeName(typeName);
+			proposal.setCompletion(completionName);
+			proposal.setFlags(modifiers);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			proposal.setAccessibility(accessibility);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+
+		// Create javadoc text proposal if necessary
+		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setDeclarationSignature(packageName);
+			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+			proposal.setPackageName(packageName);
+			proposal.setTypeName(typeName);
+			proposal.setCompletion(javadocCompletion);
+			proposal.setFlags(modifiers);
+			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance+R_INLINE_TAG);
+			proposal.setAccessibility(accessibility);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+	}
+
+	/*
+	 * Create a completion proposal for a member type.
+	 */
+	private void createTypeProposal(
+			ReferenceBinding refBinding,
+			char[] typeName,
+			int accessibility,
+			char[] completionName,
+			int relevance,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds,
+			boolean missingElementsHaveProblems) {
+
+		// Create standard type proposal
+		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
+			proposal.setSignature(getCompletedTypeSignature(refBinding));
+			proposal.setPackageName(refBinding.qualifiedPackageName());
+			proposal.setTypeName(typeName);
+			if (missingElements != null) {
+				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+				for (int i = 0; i < missingElements.length; i++) {
+					subProposals[i] =
+						createRequiredTypeProposal(
+								missingElements[i],
+								missingElementsStarts[i],
+								missingElementsEnds[i],
+								relevance);
+				}
+				proposal.setRequiredProposals(subProposals);
+			}
+			proposal.setCompletion(completionName);
+			proposal.setFlags(refBinding.modifiers);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+
+		// Create javadoc text proposal if necessary
+		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+			proposal.nameLookup = this.nameEnvironment.nameLookup;
+			proposal.completionEngine = this;
+			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
+			proposal.setSignature(getCompletedTypeSignature(refBinding));
+			proposal.setPackageName(refBinding.qualifiedPackageName());
+			proposal.setTypeName(typeName);
+			proposal.setCompletion(javadocCompletion);
+			proposal.setFlags(refBinding.modifiers);
+			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance+R_INLINE_TAG);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+	}
+	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
+		completion.append(typeVariable.sourceName);
+
+		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
+		    completion.append(' ');
+		    completion.append(EXTENDS);
+		    completion.append(' ');
+		    createType(typeVariable.superclass, scope, completion);
+		}
+		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
+		   if (typeVariable.firstBound != typeVariable.superclass) {
+			   completion.append(' ');
+			   completion.append(EXTENDS);
+			   completion.append(' ');
+		   }
+		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
+			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
+				   completion.append(' ');
+				   completion.append(EXTENDS);
+				   completion.append(' ');
+			   }
+			   createType(typeVariable.superInterfaces[i], scope, completion);
+		   }
+		}
+	}
+	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
+		if (type.isArrayType()) {
+			createType(type.leafComponentType(), scope, completion);
+			int dim = type.dimensions() - 1;
+			for (int i = 0; i < dim; i++) {
+				completion.append('[');
+				completion.append(']');
+			}
+			completion.append(VARARGS);
+		} else {
+			createType(type, scope, completion);
+		}
+	}
+	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
+		MethodBinding[] methods = annotation.availableMethods();
+		nextAttribute: for (int i = 0; i < methods.length; i++) {
+			MethodBinding method = methods[i];
+
+			if(!CharOperation.prefixEquals(token, method.selector, false)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
+
+			int length = attributesFound == null ? 0 : attributesFound.length;
+			for (int j = 0; j < length; j++) {
+				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal(method);
+			relevance += computeRelevanceForCaseMatching(token, method.selector);
+			relevance += computeRelevanceForQualification(false);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setSignature(getSignature(method.returnType));
+				proposal.setName(method.selector);
+				proposal.setCompletion(method.selector);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+	void findAnonymousType(
+			ReferenceBinding currentType,
+			TypeBinding[] argTypes,
+			Scope scope,
+			InvocationSite invocationSite,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds,
+			boolean missingElementsHaveProblems) {
+		
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal(currentType);
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+		
+		if (missingElements != null) {
+			relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+		}
+		
+		findAnonymousType(
+				currentType,
+				argTypes,
+				scope,
+				invocationSite,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				true,
+				false,
+				relevance);
+	}
+	private void findAnonymousType(
+		ReferenceBinding currentType,
+		TypeBinding[] argTypes,
+		Scope scope,
+		InvocationSite invocationSite,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		boolean exactMatch,
+		boolean isQualified,
+		int relevance) {
+
+		if (currentType.isInterface()) {
+			char[] completion = CharOperation.NO_CHAR;
+			char[] typeCompletion = null;
+			if (!exactMatch) {
+				typeCompletion = 
+					isQualified ?
+							CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+								currentType.sourceName();
+				if (this.source != null
+							&& this.source.length > this.endPosition
+							&& this.source[this.endPosition] == '(') {
+					completion = CharOperation.NO_CHAR;
+				} else {
+					completion = new char[] { '(', ')' };
+				}
+			}
+
+			this.noProposal = false;
+			if (!exactMatch) {
+				if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+					char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+					char[] typeName = currentType.qualifiedSourceName();
+					
+					InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(currentType));
+					proposal.setDeclarationKey(currentType.computeUniqueKey());
+					proposal.setSignature(
+							createMethodSignature(
+									CharOperation.NO_CHAR_CHAR,
+									CharOperation.NO_CHAR_CHAR,
+									CharOperation.NO_CHAR,
+									CharOperation.NO_CHAR));
+					//proposal.setOriginalSignature(null);
+					//proposal.setUniqueKey(null);
+					proposal.setDeclarationPackageName(packageName);
+					proposal.setDeclarationTypeName(typeName);
+					//proposal.setParameterPackageNames(null);
+					//proposal.setParameterTypeNames(null);
+					//proposal.setPackageName(null);
+					//proposal.setTypeName(null);
+					proposal.setName(currentType.sourceName());
+					
+					InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+					typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+					typeProposal.completionEngine = this;
+					typeProposal.setDeclarationSignature(packageName);
+					typeProposal.setSignature(getRequiredTypeSignature(currentType));
+					typeProposal.setPackageName(packageName);
+					typeProposal.setTypeName(typeName);
+					typeProposal.setCompletion(typeCompletion);
+					typeProposal.setFlags(currentType.modifiers);
+					typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					typeProposal.setRelevance(relevance);
+					proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+								
+					proposal.setCompletion(completion);
+					proposal.setFlags(Flags.AccPublic);
+					proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}  else {
+				if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) {
+					InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(currentType));
+					proposal.setDeclarationKey(currentType.computeUniqueKey());
+					proposal.setSignature(
+							createMethodSignature(
+									CharOperation.NO_CHAR_CHAR,
+									CharOperation.NO_CHAR_CHAR,
+									CharOperation.NO_CHAR,
+									CharOperation.NO_CHAR));
+					//proposal.setOriginalSignature(null);
+					//proposal.setUniqueKey(null);
+					proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+					proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+					//proposal.setParameterPackageNames(null);
+					//proposal.setParameterTypeNames(null);
+					//proposal.setPackageName(null);
+					//proposal.setTypeName(null);
+					if (missingElements != null) {
+						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+						for (int i = 0; i < missingElements.length; i++) {
+							subProposals[i] =
+								createRequiredTypeProposal(
+										missingElements[i],
+										missingElementsStarts[i],
+										missingElementsEnds[i],
+										relevance);
+						}
+						proposal.setRequiredProposals(subProposals);
+					}
+					proposal.setCompletion(completion);
+					proposal.setFlags(Flags.AccPublic);
+					proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		} else {
+			findConstructors(
+				currentType,
+				argTypes,
+				scope,
+				invocationSite,
+				true,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				exactMatch,
+				isQualified,
+				relevance);
+		}
+	}
+	private void findClassField(
+			char[] token,
+			TypeBinding receiverType,
+			Scope scope,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds,
+			boolean missingElementsHaveProblems) {
+
+		if (token == null) return;
+
+		if (token.length <= classField.length
+			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
+		)) {
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(token, classField);
+			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
+			relevance += R_NON_INHERITED;
+
+			if (missingElements != null) {
+				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+			}
+
+			this.noProposal = false;
+			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
+				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+				//proposal.setDeclarationSignature(null);
+				char[] signature =
+					createNonGenericTypeSignature(
+						CharOperation.concatWith(JAVA_LANG, '.'),
+						CLASS);
+				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
+					// add type argument
+					char[] typeArgument = getTypeSignature(receiverType);
+					int oldLength = signature.length;
+					int argumentLength = typeArgument.length;
+					int newLength = oldLength + argumentLength + 2;
+					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
+					signature[oldLength - 1] = '<';
+					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
+					signature[newLength - 2] = '>';
+					signature[newLength - 1] = ';';
+				}
+				proposal.setSignature(signature);
+				//proposal.setDeclarationPackageName(null);
+				//proposal.setDeclarationTypeName(null);
+				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+				proposal.setTypeName(CLASS);
+				proposal.setName(classField);
+				if (missingElements != null) {
+					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+					for (int i = 0; i < missingElements.length; i++) {
+						subProposals[i] =
+							createRequiredTypeProposal(
+									missingElements[i],
+									missingElementsStarts[i],
+									missingElementsEnds[i],
+									relevance);
+					}
+					proposal.setRequiredProposals(subProposals);
+				}
+				proposal.setCompletion(classField);
+				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+	
+	void findConstructors(
+		ReferenceBinding currentType,
+		TypeBinding[] argTypes,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean forAnonymousType,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems) {
+		
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+		
+		if (missingElements != null) {
+			relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+		}
+		
+		findConstructors(
+				currentType,
+				argTypes,
+				scope,
+				invocationSite,
+				forAnonymousType,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				true,
+				false,
+				relevance);
+	}
+	
+	
+	private void findConstructorsFromMissingType(
+			TypeReference typeRef,
+			final TypeBinding[] argTypes,
+			final Scope scope,
+			final InvocationSite invocationSite) {
+		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+			new MissingTypesGuesser.GuessedTypeRequestor() {
+				public void accept(
+						TypeBinding guessedType,
+						Binding[] missingElements,
+						int[] missingElementsStarts,
+						int[] missingElementsEnds,
+						boolean hasProblems) {
+					if (guessedType instanceof ReferenceBinding) {
+						ReferenceBinding ref = (ReferenceBinding) guessedType;
+						if (!isIgnored(CompletionProposal.METHOD_REF, missingElements != null)
+								&& ref.isClass()
+								&& !ref.isAbstract()) {
+								findConstructors(
+									ref,
+									argTypes,
+									scope,
+									invocationSite,
+									false,
+									missingElements,
+									missingElementsStarts,
+									missingElementsEnds,
+									hasProblems);
+						}
+								
+						checkCancel();
+			
+						if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)
+								&& !ref.isFinal()
+								&& !ref.isEnum()){
+							findAnonymousType(
+								ref,
+								argTypes,
+								scope,
+								invocationSite,
+								missingElements,
+								missingElementsStarts,
+								missingElementsEnds,
+								hasProblems);
+						}
+					}
+				}
+			};
+		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+	}
+		
+	private void findConstructors(
+		ReferenceBinding currentType,
+		TypeBinding[] argTypes,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean forAnonymousType,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		boolean exactMatch,
+		boolean isQualified,
+		int relevance) {
+
+		// No visibility checks can be performed without the scope & invocationSite
+		MethodBinding[] methods = null;
+		if (currentType instanceof ParameterizedTypeBinding && invocationSite instanceof CompletionOnQualifiedAllocationExpression) {
+			CompletionOnQualifiedAllocationExpression alloc = (CompletionOnQualifiedAllocationExpression) invocationSite;
+			if ((alloc.bits & ASTNode.IsDiamond) != 0) {
+				// inference failed. So don't substitute type arguments. Just return the unsubstituted methods
+				// and let the user decide what to substitute.
+				ParameterizedTypeBinding binding = (ParameterizedTypeBinding) currentType;
+				ReferenceBinding originalGenericType = binding.genericType();
+				if (originalGenericType != null)
+					methods = originalGenericType.methods();
+			} else {
+				methods = currentType.availableMethods();
+			}
+		} else {
+			methods = currentType.availableMethods();
+		}
+		if(methods != null) {
+			int minArgLength = argTypes == null ? 0 : argTypes.length;
+			next : for (int f = methods.length; --f >= 0;) {
+				MethodBinding constructor = methods[f];
+				if (constructor.isConstructor()) {
+
+					if (constructor.isSynthetic()) continue next;
+
+					if (this.options.checkDeprecation &&
+							constructor.isViewedAsDeprecated() &&
+							!scope.isDefinedInSameUnit(constructor.declaringClass))
+						continue next;
+
+					if (this.options.checkVisibility
+						&& !constructor.canBeSeenBy(invocationSite, scope)) {
+						if(!forAnonymousType || !constructor.isProtected())
+							continue next;
+					}
+
+					TypeBinding[] parameters = constructor.parameters;
+					int paramLength = parameters.length;
+					if (minArgLength > paramLength)
+						continue next;
+					for (int a = minArgLength; --a >= 0;)
+						if (argTypes[a] != null) { // can be null if it could not be resolved properly
+							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
+								continue next;
+						}
+
+					char[][] parameterPackageNames = new char[paramLength][];
+					char[][] parameterTypeNames = new char[paramLength][];
+					for (int i = 0; i < paramLength; i++) {
+						TypeBinding type = parameters[i];
+						parameterPackageNames[i] = type.qualifiedPackageName();
+						parameterTypeNames[i] = type.qualifiedSourceName();
+					}
+					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
+
+					char[] completion = CharOperation.NO_CHAR;
+					
+					if(forAnonymousType){
+						char[] typeCompletion = null;
+						if (!exactMatch) {
+							typeCompletion = 
+								isQualified ?
+										CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+											currentType.sourceName();
+							if (this.source != null
+										&& this.source.length > this.endPosition
+										&& this.source[this.endPosition] == '(') {
+								completion = CharOperation.NO_CHAR;
+							} else {
+								completion = new char[] { '(', ')' };
+							}
+						}
+						
+						this.noProposal = false;
+						if (!exactMatch) {
+							if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+								char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+								char[] typeName = currentType.qualifiedSourceName();
+								
+								InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(getSignature(currentType));
+								proposal.setDeclarationKey(currentType.computeUniqueKey());
+								proposal.setSignature(getSignature(constructor));
+								MethodBinding original = constructor.original();
+								if(original != constructor) {
+									proposal.setOriginalSignature(getSignature(original));
+								}
+								proposal.setKey(constructor.computeUniqueKey());
+								proposal.setDeclarationPackageName(packageName);
+								proposal.setDeclarationTypeName(typeName);
+								proposal.setParameterPackageNames(parameterPackageNames);
+								proposal.setParameterTypeNames(parameterTypeNames);
+								//proposal.setPackageName(null);
+								//proposal.setTypeName(null);
+								proposal.setName(currentType.sourceName());
+								
+								InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+								typeProposal.completionEngine = this;
+								typeProposal.setDeclarationSignature(packageName);
+								typeProposal.setSignature(getRequiredTypeSignature(currentType));
+								typeProposal.setPackageName(packageName);
+								typeProposal.setTypeName(typeName);
+								typeProposal.setCompletion(typeCompletion);
+								typeProposal.setFlags(currentType.modifiers);
+								typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								typeProposal.setRelevance(relevance);
+								proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+								
+								proposal.setCompletion(completion);
+								proposal.setFlags(constructor.modifiers);
+								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								if(parameterNames != null) proposal.setParameterNames(parameterNames);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						} else {
+							if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) {
+								InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(getSignature(currentType));
+								proposal.setDeclarationKey(currentType.computeUniqueKey());
+								proposal.setSignature(getSignature(constructor));
+								MethodBinding original = constructor.original();
+								if(original != constructor) {
+									proposal.setOriginalSignature(getSignature(original));
+								}
+								proposal.setKey(constructor.computeUniqueKey());
+								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+								proposal.setParameterPackageNames(parameterPackageNames);
+								proposal.setParameterTypeNames(parameterTypeNames);
+								//proposal.setPackageName(null);
+								//proposal.setTypeName(null);
+								if (missingElements != null) {
+									CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+									for (int i = 0; i < missingElements.length; i++) {
+										subProposals[i] =
+											createRequiredTypeProposal(
+													missingElements[i],
+													missingElementsStarts[i],
+													missingElementsEnds[i],
+													relevance);
+									}
+									proposal.setRequiredProposals(subProposals);
+								}
+								proposal.setCompletion(completion);
+								proposal.setFlags(constructor.modifiers);
+								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								if(parameterNames != null) proposal.setParameterNames(parameterNames);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						}
+					} else {
+						char[] typeCompletion = null;
+						// Special case for completion in javadoc
+						if (this.assistNodeInJavadoc > 0) {
+							Expression receiver = null;
+							char[] selector = null;
+							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
+								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
+								receiver = alloc.type;
+							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+								receiver = fieldRef.receiver;
+							}
+							if (receiver != null) {
+								StringBuffer javadocCompletion = new StringBuffer();
+								if (receiver.isThis()) {
+									selector = (((JavadocImplicitTypeReference)receiver).token);
+									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+										javadocCompletion.append('#');
+									}
+								} else if (receiver instanceof JavadocSingleTypeReference) {
+									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
+									selector = typeRef.token;
+									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+										javadocCompletion.append(typeRef.token);
+										javadocCompletion.append('#');
+									}
+								} else if (receiver instanceof JavadocQualifiedTypeReference) {
+									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
+									selector = typeRef.tokens[typeRef.tokens.length-1];
+									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
+										javadocCompletion.append('#');
+									}
+								}
+								// Append parameters types
+								javadocCompletion.append(selector);
+								javadocCompletion.append('(');
+								if (constructor.parameters != null) {
+									boolean isVarargs = constructor.isVarargs();
+									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
+										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
+										TypeBinding argTypeBinding = constructor.parameters[p];
+										if (isVarargs && p == ln - 1)  {
+											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
+										} else {
+											createType(argTypeBinding.erasure(), scope, javadocCompletion);
+										}
+									}
+								}
+								javadocCompletion.append(')');
+								completion = javadocCompletion.toString().toCharArray();
+							}
+						} else {
+							if (!exactMatch) {
+								typeCompletion = 
+									isQualified ?
+											CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
+												currentType.sourceName();
+								
+								if (this.source != null
+											&& this.source.length > this.endPosition
+											&& this.source[this.endPosition] == '(') {
+									completion = CharOperation.NO_CHAR;
+								} else {
+									completion = new char[] { '(', ')' };
+								}
+							}
+						}
+
+						// Create standard proposal
+						this.noProposal = false;
+						if (!exactMatch) {
+							if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+								char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
+								char[] typeName = currentType.qualifiedSourceName();
+								int constructorRelevance = relevance + computeRelevanceForConstructor();
+								InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(getSignature(currentType));
+								proposal.setSignature(getSignature(constructor));
+								MethodBinding original = constructor.original();
+								if(original != constructor) {
+									proposal.setOriginalSignature(getSignature(original));
+								}
+								proposal.setDeclarationPackageName(packageName);
+								proposal.setDeclarationTypeName(typeName);
+								proposal.setParameterPackageNames(parameterPackageNames);
+								proposal.setParameterTypeNames(parameterTypeNames);
+								//proposal.setPackageName(null);
+								//proposal.setTypeName(null);
+								proposal.setName(currentType.sourceName());
+					
+								InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+								typeProposal.completionEngine = this;
+								typeProposal.setDeclarationSignature(packageName);
+								typeProposal.setSignature(getRequiredTypeSignature(currentType));
+								typeProposal.setPackageName(packageName);
+								typeProposal.setTypeName(typeName);
+								typeProposal.setCompletion(typeCompletion);
+								typeProposal.setFlags(currentType.modifiers);
+								typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								typeProposal.setRelevance(constructorRelevance);
+								proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
+								
+								proposal.setIsContructor(true);
+								proposal.setCompletion(completion);
+								proposal.setFlags(constructor.modifiers);
+								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(constructorRelevance);
+								if(parameterNames != null) proposal.setParameterNames(parameterNames);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						} else {
+							if(!isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+								InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(getSignature(currentType));
+								proposal.setSignature(getSignature(constructor));
+								MethodBinding original = constructor.original();
+								if(original != constructor) {
+									proposal.setOriginalSignature(getSignature(original));
+								}
+								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+								proposal.setParameterPackageNames(parameterPackageNames);
+								proposal.setParameterTypeNames(parameterTypeNames);
+								//proposal.setPackageName(null);
+								//proposal.setTypeName(null);
+								proposal.setName(currentType.sourceName());
+								if (missingElements != null) {
+									CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+									for (int i = 0; i < missingElements.length; i++) {
+										subProposals[i] =
+											createRequiredTypeProposal(
+													missingElements[i],
+													missingElementsStarts[i],
+													missingElementsEnds[i],
+													relevance);
+									}
+									proposal.setRequiredProposals(subProposals);
+								}
+								proposal.setIsContructor(true);
+								proposal.setCompletion(completion);
+								proposal.setFlags(constructor.modifiers);
+								int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
+								proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								if(parameterNames != null) proposal.setParameterNames(parameterNames);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+							if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+								char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+								InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(getSignature(currentType));
+								proposal.setSignature(getSignature(constructor));
+								MethodBinding original = constructor.original();
+								if(original != constructor) {
+									proposal.setOriginalSignature(getSignature(original));
+								}
+								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+								proposal.setParameterPackageNames(parameterPackageNames);
+								proposal.setParameterTypeNames(parameterTypeNames);
+								//proposal.setPackageName(null);
+								//proposal.setTypeName(null);
+								proposal.setName(currentType.sourceName());
+								proposal.setIsContructor(true);
+								proposal.setCompletion(javadocCompletion);
+								proposal.setFlags(constructor.modifiers);
+								int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+								proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance+R_INLINE_TAG);
+								if(parameterNames != null) proposal.setParameterNames(parameterNames);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	private char[] getResolvedSignature(char[][] parameterTypes, char[] fullyQualifiedTypeName, int parameterCount, Scope scope) {
+		char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);
+
+		TypeReference ref;
+		if (cn.length == 1) {
+			ref = new SingleTypeReference(cn[0], 0);
+		} else {
+			ref = new QualifiedTypeReference(cn,new long[cn.length]);
+		}
+		
+		TypeBinding guessedType = null;
+		INameEnvironment oldNameEnvironment = this.lookupEnvironment.nameEnvironment;
+		this.lookupEnvironment.nameEnvironment = getNoCacheNameEnvironment();
+		try {
+			switch (scope.kind) {
+				case Scope.METHOD_SCOPE :
+				case Scope.BLOCK_SCOPE :
+					guessedType = ref.resolveType((BlockScope)scope);
+					break;
+				case Scope.CLASS_SCOPE :
+					guessedType = ref.resolveType((ClassScope)scope);
+					break;
+			}
+		
+
+			if (guessedType != null && guessedType.isValidBinding()) {
+				// the erasure must be used because guessedType can be a RawTypeBinding (https://bugs.eclipse.org/bugs/show_bug.cgi?id=276890)
+				guessedType = guessedType.erasure();
+				
+				if (guessedType instanceof SourceTypeBinding) {
+					SourceTypeBinding refBinding = (SourceTypeBinding) guessedType;
+					
+					if (refBinding.scope == null || refBinding.scope.referenceContext == null) return null;
+					
+					TypeDeclaration typeDeclaration = refBinding.scope.referenceContext;
+					AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+					
+					next : for (int i = 0; i < methods.length; i++) {
+						AbstractMethodDeclaration method = methods[i];
+						
+						if (!method.isConstructor()) continue next;
+						
+						Argument[] arguments = method.arguments;
+						int argumentsLength = arguments == null ? 0 : arguments.length;
+						
+						if (parameterCount != argumentsLength) continue next;
+						
+						for (int j = 0; j < argumentsLength; j++) {
+							char[] argumentTypeName = getTypeName(arguments[j].type);
+	
+							if (!CharOperation.equals(argumentTypeName, parameterTypes[j])) {
+								continue next;
+							}
+						}
+						
+						refBinding.resolveTypesFor(method.binding); // force resolution
+						if (method.binding == null) continue next;
+						return getSignature(method.binding);
+					}
+				}
+			}
+		} finally {
+			this.lookupEnvironment.nameEnvironment = oldNameEnvironment;
+		}
+		
+		return null;
+	}
+	
+	private void findConstructorsOrAnonymousTypes(
+			ReferenceBinding currentType,
+			Scope scope,
+			InvocationSite invocationSite,
+			boolean isQualified,
+			int relevance) {
+		
+		if (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
+				&& currentType.isClass()
+				&& !currentType.isAbstract()) {
+				findConstructors(
+					currentType,
+					null,
+					scope,
+					invocationSite,
+					false,
+					null,
+					null,
+					null,
+					false,
+					false,
+					isQualified,
+					relevance);
+		}
+		
+		// This code is disabled because there is too much proposals when constructors and anonymous are proposed
+		if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
+				&& !currentType.isFinal()
+				&& (currentType.isInterface() || (currentType.isClass() && currentType.isAbstract()))){
+			findAnonymousType(
+				currentType,
+				null,
+				scope,
+				invocationSite,
+				null,
+				null,
+				null,
+				false,
+				false,
+				isQualified,
+				relevance);
+		}
+	}
+	private char[][] findEnclosingTypeNames(Scope scope){
+		char[][] excludedNames = new char[10][];
+		int excludedNameCount = 0;
+
+		Scope currentScope = scope;
+		while(currentScope != null) {
+			switch (currentScope.kind) {
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) currentScope;
+
+					TypeDeclaration typeDeclaration = classScope.referenceContext;
+
+					if(excludedNameCount == excludedNames.length) {
+						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+					}
+					excludedNames[excludedNameCount++] = typeDeclaration.name;
+
+					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
+					if(classTypeParameters != null) {
+						for (int i = 0; i < classTypeParameters.length; i++) {
+							TypeParameter typeParameter = classTypeParameters[i];
+							if(excludedNameCount == excludedNames.length) {
+								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+							}
+							excludedNames[excludedNameCount++] = typeParameter.name;
+						}
+					}
+					break;
+				case Scope.METHOD_SCOPE :
+					MethodScope methodScope = (MethodScope) currentScope;
+					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
+						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
+						if(methodTypeParameters != null) {
+							for (int i = 0; i < methodTypeParameters.length; i++) {
+								TypeParameter typeParameter = methodTypeParameters[i];
+								if(excludedNameCount == excludedNames.length) {
+									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+								}
+								excludedNames[excludedNameCount++] = typeParameter.name;
+							}
+						}
+					}
+					break;
+			}
+
+			currentScope = currentScope.parent;
+		}
+
+		if(excludedNameCount == 0) {
+			return CharOperation.NO_CHAR_CHAR;
+		}
+		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
+		return excludedNames;
+	}
+	private void findEnumConstants(
+			char[] enumConstantName,
+			ReferenceBinding enumType,
+			Scope invocationScope,
+			ObjectVector fieldsFound,
+			char[][] alreadyUsedConstants,
+			int alreadyUsedConstantCount,
+			boolean needQualification) {
+
+		FieldBinding[] fields = enumType.fields();
+
+		int enumConstantLength = enumConstantName.length;
+		next : for (int f = fields.length; --f >= 0;) {
+			FieldBinding field = fields[f];
+
+			if (field.isSynthetic()) continue next;
+
+			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
+
+			if (enumConstantLength > field.name.length) continue next;
+
+			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
+
+			char[] fieldName = field.name;
+
+			for (int i = 0; i < alreadyUsedConstantCount; i++) {
+				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal(field);
+			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
+			relevance += computeRelevanceForExpectingType(field.type);
+			relevance += computeRelevanceForEnumConstant(field.type);
+			relevance += computeRelevanceForQualification(needQualification);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if (!needQualification) {
+				char[] completion = fieldName;
+
+				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+
+			} else {
+				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
+				boolean needImport = visibleType == null || !visibleType.isValidBinding();
+
+				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
+
+				if (!needImport) {
+					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(field.declaringClass));
+						proposal.setSignature(getSignature(field.type));
+						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+						proposal.setPackageName(field.type.qualifiedPackageName());
+						proposal.setTypeName(field.type.qualifiedSourceName());
+						proposal.setName(field.name);
+						proposal.setCompletion(completion);
+						proposal.setFlags(field.modifiers);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
+						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+						int importStart = cu.types[0].declarationSourceStart;
+						int importEnd = importStart;
+
+						ReferenceBinding fieldType = (ReferenceBinding)field.type;
+
+						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(field.declaringClass));
+						proposal.setSignature(getSignature(field.type));
+						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+						proposal.setPackageName(field.type.qualifiedPackageName());
+						proposal.setTypeName(field.type.qualifiedSourceName());
+						proposal.setName(field.name);
+						proposal.setCompletion(completion);
+						proposal.setFlags(field.modifiers);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+
+						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
+
+						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+						typeImportProposal.completionEngine = this;
+						char[] packageName = fieldType.qualifiedPackageName();
+						typeImportProposal.setDeclarationSignature(packageName);
+						typeImportProposal.setSignature(getSignature(fieldType));
+						typeImportProposal.setPackageName(packageName);
+						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
+						typeImportProposal.setCompletion(typeImportCompletion);
+						typeImportProposal.setFlags(fieldType.modifiers);
+						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+						typeImportProposal.setRelevance(relevance);
+
+						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+			}
+		}
+	}
+	private void findEnumConstantsFromExpectedTypes(
+			char[] token,
+			Scope invocationScope,
+			ObjectVector fieldsFound) {
+		int length = this.expectedTypesPtr + 1;
+		for (int i = 0; i < length; i++) {
+			if (this.expectedTypes[i].isEnum()) {
+				findEnumConstants(
+						token,
+						(ReferenceBinding)this.expectedTypes[i],
+						invocationScope,
+						fieldsFound,
+						CharOperation.NO_CHAR_CHAR,
+						0,
+						true);
+			}
+		}
+
+	}
+	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
+		TypeBinding expressionType = switchStatement.expression.resolvedType;
+		if(expressionType != null && expressionType.isEnum()) {
+			ReferenceBinding enumType = (ReferenceBinding) expressionType;
+
+			CaseStatement[] cases = switchStatement.cases;
+
+			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
+			int alreadyUsedConstantCount = 0;
+			for (int i = 0; i < switchStatement.caseCount; i++) {
+				Expression caseExpression = cases[i].constantExpression;
+				if((caseExpression instanceof SingleNameReference)
+						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
+					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
+				}
+			}
+
+			findEnumConstants(
+					enumConstantName,
+					enumType,
+					null /* doesn't need invocation scope */,
+					new ObjectVector(),
+					alreadyUsedConstants,
+					alreadyUsedConstantCount,
+					false);
+		}
+	}
+	private void findExceptionFromTryStatement(
+			char[] typeName,
+			ReferenceBinding exceptionType,
+			ReferenceBinding receiverType,
+			SourceTypeBinding invocationType,
+			BlockScope scope,
+			ObjectVector typesFound,
+			boolean searchSuperClasses) {
+
+		if (searchSuperClasses) {
+			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
+			if (exceptionType != javaLangThrowable) {
+				ReferenceBinding superClass = exceptionType.superclass();
+				while(superClass != null && superClass != javaLangThrowable) {
+					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
+					superClass = superClass.superclass();
+				}
+			}
+		}
+
+		if (typeName.length > exceptionType.sourceName.length)
+			return;
+
+		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
+				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
+			return;
+
+		if (this.options.checkDeprecation &&
+				exceptionType.isViewedAsDeprecated() &&
+				!scope.isDefinedInSameUnit(exceptionType))
+			return;
+
+		if (this.options.checkVisibility) {
+			if (invocationType != null) {
+				if (receiverType != null) {
+					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
+				} else {
+					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
+				}
+			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
+				return;
+			}
+		}
+		
+		if (isForbidden(exceptionType)) return;
+
+		for (int j = typesFound.size; --j >= 0;) {
+			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+
+			if (exceptionType == otherType)
+				return;
+
+			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
+
+				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
+					return;
+
+				if (otherType.enclosingType().isInterface())
+					if (exceptionType.enclosingType()
+						.implementsInterface(otherType.enclosingType(), true))
+						return;
+
+				if (exceptionType.enclosingType().isInterface())
+					if (otherType.enclosingType()
+						.implementsInterface(exceptionType.enclosingType(), true))
+						return;
+			}
+		}
+
+		typesFound.add(exceptionType);
+
+		char[] completionName = exceptionType.sourceName();
+
+		boolean isQualified = false;
+
+		if(!this.insideQualifiedReference) {
+			isQualified = true;
+
+			char[] memberPackageName = exceptionType.qualifiedPackageName();
+			char[] memberTypeName = exceptionType.sourceName();
+			char[] memberEnclosingTypeNames = null;
+
+			ReferenceBinding enclosingType = exceptionType.enclosingType();
+			if (enclosingType != null) {
+				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
+			}
+
+			Scope currentScope = scope;
+			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+
+				switch (currentScope.kind) {
+
+					case Scope.METHOD_SCOPE :
+					case Scope.BLOCK_SCOPE :
+						BlockScope blockScope = (BlockScope) currentScope;
+
+						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
+
+							if (blockScope.subscopes[j] instanceof ClassScope) {
+								SourceTypeBinding localType =
+									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
+
+								if (localType == exceptionType) {
+									isQualified = false;
+									break done;
+								}
+							}
+						}
+						break;
+
+					case Scope.CLASS_SCOPE :
+						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
+						ReferenceBinding[] memberTypes = type.memberTypes();
+						if (memberTypes != null) {
+							for (int j = 0; j < memberTypes.length; j++) {
+								if (memberTypes[j] == exceptionType) {
+									isQualified = false;
+									break done;
+								}
+							}
+						}
+
+
+						break;
+
+					case Scope.COMPILATION_UNIT_SCOPE :
+						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
+						if (types != null) {
+							for (int j = 0; j < types.length; j++) {
+								if (types[j] == exceptionType) {
+									isQualified = false;
+									break done;
+								}
+							}
+						}
+						break done;
+				}
+				currentScope = currentScope.parent;
+			}
+
+			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
+				if (memberPackageName == null || memberPackageName.length == 0)
+					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+						return; // ignore types from the default package from outside it
+			} else {
+				isQualified = false;
+			}
+
+			if (isQualified) {
+				completionName =
+					CharOperation.concat(
+							memberPackageName,
+							CharOperation.concat(
+									memberEnclosingTypeNames,
+									memberTypeName,
+									'.'),
+							'.');
+			}
+		}
+
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal(exceptionType);
+		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
+		relevance += computeRelevanceForExpectingType(exceptionType);
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+		if(!this.insideQualifiedReference) {
+			relevance += computeRelevanceForQualification(isQualified);
+		}
+		relevance += computeRelevanceForClass();
+		relevance += computeRelevanceForException();
+
+		this.noProposal = false;
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			createTypeProposal(
+					exceptionType,
+					exceptionType.qualifiedSourceName(),
+					IAccessRule.K_ACCESSIBLE,
+					completionName,
+					relevance,
+					null,
+					null,
+					null,
+					false);
+		}
+	}
+	private void findExceptionFromTryStatement(
+			char[] typeName,
+			ReferenceBinding receiverType,
+			SourceTypeBinding invocationType,
+			BlockScope scope,
+			ObjectVector typesFound) {
+
+		for (int i = 0; i <= this.expectedTypesPtr; i++) {
+			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
+
+			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
+		}
+	}
+	private void findExplicitConstructors(
+		char[] name,
+		ReferenceBinding currentType,
+		MethodScope scope,
+		InvocationSite invocationSite) {
+
+		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
+		MethodBinding enclosingConstructor = constructorDeclaration.binding;
+
+		// No visibility checks can be performed without the scope & invocationSite
+		MethodBinding[] methods = currentType.availableMethods();
+		if(methods != null) {
+			next : for (int f = methods.length; --f >= 0;) {
+				MethodBinding constructor = methods[f];
+				if (constructor != enclosingConstructor && constructor.isConstructor()) {
+
+					if (constructor.isSynthetic()) continue next;
+
+					if (this.options.checkDeprecation &&
+							constructor.isViewedAsDeprecated() &&
+							!scope.isDefinedInSameUnit(constructor.declaringClass))
+						continue next;
+
+					if (this.options.checkVisibility
+						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
+
+					TypeBinding[] parameters = constructor.parameters;
+					int paramLength = parameters.length;
+
+					char[][] parameterPackageNames = new char[paramLength][];
+					char[][] parameterTypeNames = new char[paramLength][];
+					for (int i = 0; i < paramLength; i++) {
+						TypeBinding type = parameters[i];
+						parameterPackageNames[i] = type.qualifiedPackageName();
+						parameterTypeNames[i] = type.qualifiedSourceName();
+					}
+					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
+
+					char[] completion = CharOperation.NO_CHAR;
+					if (this.source != null
+						&& this.source.length > this.endPosition
+						&& this.source[this.endPosition] == '(')
+						completion = name;
+					else
+						completion = CharOperation.concat(name, new char[] { '(', ')' });
+
+					int relevance = computeBaseRelevance();
+					relevance += computeRelevanceForResolution();
+					relevance += computeRelevanceForInterestingProposal();
+					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+					this.noProposal = false;
+					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(currentType));
+						proposal.setSignature(getSignature(constructor));
+						MethodBinding original = constructor.original();
+						if(original != constructor) {
+							proposal.setOriginalSignature(getSignature(original));
+						}
+						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+						proposal.setParameterPackageNames(parameterPackageNames);
+						proposal.setParameterTypeNames(parameterTypeNames);
+						//proposal.setPackageName(null);
+						//proposal.setTypeName(null);
+						proposal.setName(name);
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(constructor.modifiers);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						if(parameterNames != null) proposal.setParameterNames(parameterNames);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+			}
+		}
+	}
+	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
+	private void findFields(
+		char[] fieldName,
+		FieldBinding[] fields,
+		Scope scope,
+		ObjectVector fieldsFound,
+		ObjectVector localsFound,
+		boolean onlyStaticFields,
+		ReferenceBinding receiverType,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean canBePrefixed,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		ObjectVector newFieldsFound = new ObjectVector();
+		// if the proposal is being asked inside a field's initialization, we'll record its id
+		int fieldBeingCompletedId = -1;
+		boolean isFieldBeingCompletedStatic = false;
+		for (int f = fields.length; --f >=0;) {
+			FieldBinding field = fields[f];
+			FieldDeclaration fieldDeclaration = field.sourceField();
+			// We maybe asking for a proposal inside this field's initialization. So record its id
+			ASTNode astNode = this.parser.assistNode;
+			if (fieldDeclaration != null && fieldDeclaration.initialization != null && astNode != null) {
+				if (CharOperation.equals(this.fileName, field.declaringClass.getFileName()) && fieldDeclaration.initialization.sourceEnd > 0) {
+					if (fieldDeclaration.initialization.sourceStart <= astNode.sourceStart &&
+						astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) {
+						// completion is inside a field initializer
+						fieldBeingCompletedId = field.id;
+						isFieldBeingCompletedStatic = field.isStatic();
+						break;
+					}
+				} else { // The sourceEnd may not yet be set
+					CompletionNodeDetector detector = new CompletionNodeDetector(astNode, fieldDeclaration.initialization);
+					if (detector.containsCompletionNode()) {  // completion is inside a field initializer
+						fieldBeingCompletedId = field.id;
+						isFieldBeingCompletedStatic = field.isStatic();
+						break;
+					}
+				}
+			}
+		}
+		// Inherited fields which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+
+		int fieldLength = fieldName.length;
+		next : for (int f = fields.length; --f >= 0;) {
+			FieldBinding field = fields[f];
+			
+			// Content assist invoked inside some field's initialization.
+			// bug 310427 and 325481
+			if (fieldBeingCompletedId >= 0 && field.id >= fieldBeingCompletedId) {
+				// Don't propose field which is being declared currently
+				// Don't propose fields declared after the current field declaration statement
+				// Though, if field is static, then it can be still be proposed
+				if (!field.isStatic()) { 
+					continue next;
+				} else if (isFieldBeingCompletedStatic) {
+					// static fields can't be proposed before they are actually declared if the 
+					// field currently being declared is also static
+					continue next;
+				}
+			}
+			
+			if (field.isSynthetic())	continue next;
+
+			if (onlyStaticFields && !field.isStatic()) continue next;
+
+			if (fieldLength > field.name.length) continue next;
+
+			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
+
+			if (this.options.checkDeprecation &&
+					field.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(field.declaringClass))
+				continue next;
+
+			if (this.options.checkVisibility
+				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
+			
+			// don't propose non constant fields or strings (1.6 or below) in case expression
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342
+			if (this.assistNodeIsInsideCase) {
+				if (field.isFinal() && field.isStatic()) {
+					if (this.assistNodeIsString){
+						if (field.type == null || field.type.id != TypeIds.T_JavaLangString)
+							continue next;
+					} else if (!(field.type instanceof BaseTypeBinding))
+						continue next; 
+				} else {
+					continue next; // non-constants not allowed in case.	
+				}
+			}
+
+			boolean prefixRequired = false;
+
+			for (int i = fieldsFound.size; --i >= 0;) {
+				Object[] other = (Object[])fieldsFound.elementAt(i);
+				FieldBinding otherField = (FieldBinding) other[0];
+				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+				if (field == otherField && receiverType == otherReceiverType)
+					continue next;
+				if (CharOperation.equals(field.name, otherField.name, true)) {
+					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
+						continue next;
+					if (otherField.declaringClass.isInterface()) {
+						if (field.declaringClass == scope.getJavaLangObject())
+							continue next;
+						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
+							continue next;
+					}
+					if (field.declaringClass.isInterface())
+						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
+							continue next;
+					if(canBePrefixed) {
+						prefixRequired = true;
+					} else {
+						continue next;
+					}
+				}
+			}
+
+			for (int l = localsFound.size; --l >= 0;) {
+				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
+
+				if (CharOperation.equals(field.name, local.name, true)) {
+					SourceTypeBinding declarationType = scope.enclosingSourceType();
+					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
+						continue next;
+					}
+					if(canBePrefixed) {
+						prefixRequired = true;
+					} else {
+						continue next;
+					}
+					break;
+				}
+			}
+
+			newFieldsFound.add(new Object[]{field, receiverType});
+
+			char[] completion = field.name;
+
+			if(prefixRequired || this.options.forceImplicitQualification){
+				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
+				completion = CharOperation.concat(prefix,completion,'.');
+			}
+
+
+			if (castedReceiver != null) {
+				completion = CharOperation.concat(castedReceiver, completion);
+			}
+
+			// Special case for javadoc completion
+			if (this.assistNodeInJavadoc > 0) {
+				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+					if (fieldRef.receiver.isThis()) {
+						if (fieldRef.completeInText()) {
+							completion = CharOperation.concat(new char[] { '#' }, field.name);
+						}
+					} else if (fieldRef.completeInText()) {
+						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
+							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
+							completion = CharOperation.concat(typeRef.token, field.name, '#');
+						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
+							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
+							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
+						}
+					}
+				}
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal(field);
+			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+			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) {
+				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
+			}
+			if (missingElements != null) {
+				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+			}
+
+			this.noProposal = false;
+			if (castedReceiver == null) {
+				// Standard proposal
+				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					if (missingElements != null) {
+						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+						for (int i = 0; i < missingElements.length; i++) {
+							subProposals[i] =
+								createRequiredTypeProposal(
+										missingElements[i],
+										missingElementsStarts[i],
+										missingElementsEnds[i],
+										relevance);
+						}
+						proposal.setRequiredProposals(subProposals);
+					}
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+
+				// Javadoc completions
+				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
+					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					proposal.setCompletion(javadocCompletion);
+					proposal.setFlags(field.modifiers);
+					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance+R_INLINE_TAG);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+					// Javadoc value completion for static fields
+					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
+						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
+						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
+						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
+						valueProposal.setSignature(getSignature(field.type));
+						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+						valueProposal.setPackageName(field.type.qualifiedPackageName());
+						valueProposal.setTypeName(field.type.qualifiedSourceName());
+						valueProposal.setName(field.name);
+						valueProposal.setCompletion(javadocCompletion);
+						valueProposal.setFlags(field.modifiers);
+						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						valueProposal.setRelevance(relevance+R_VALUE_TAG);
+						this.requestor.accept(valueProposal);
+						if(DEBUG) {
+							this.printDebug(valueProposal);
+						}
+					}
+				}
+			} else {
+				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setReceiverSignature(getSignature(receiverType));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					if (missingElements != null) {
+						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+						for (int i = 0; i < missingElements.length; i++) {
+							subProposals[i] =
+								createRequiredTypeProposal(
+										missingElements[i],
+										missingElementsStarts[i],
+										missingElementsEnds[i],
+										relevance);
+						}
+						proposal.setRequiredProposals(subProposals);
+					}
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+
+		fieldsFound.addAll(newFieldsFound);
+	}
+	private void findFields(
+		char[] fieldName,
+		ReferenceBinding receiverType,
+		Scope scope,
+		ObjectVector fieldsFound,
+		ObjectVector localsFound,
+		boolean onlyStaticFields,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean canBePrefixed,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
+		if (fieldName == null && notInJavadoc)
+			return;
+
+		ReferenceBinding currentType = receiverType;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		do {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+
+			FieldBinding[] fields = currentType.availableFields();
+			if(fields != null && fields.length > 0) {
+				findFields(
+					fieldName,
+					fields,
+					scope,
+					fieldsFound,
+					localsFound,
+					onlyStaticFields,
+					receiverType,
+					invocationSite,
+					invocationScope,
+					implicitCall,
+					canBePrefixed,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems,
+					castedReceiver,
+					receiverStart,
+					receiverEnd);
+			}
+			currentType = currentType.superclass();
+		} while (notInJavadoc && currentType != null);
+
+		if (notInJavadoc && interfacesToVisit != null) {
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				FieldBinding[] fields = anInterface.availableFields();
+				if(fields !=  null) {
+					findFields(
+						fieldName,
+						fields,
+						scope,
+						fieldsFound,
+						localsFound,
+						onlyStaticFields,
+						receiverType,
+						invocationSite,
+						invocationScope,
+						implicitCall,
+						canBePrefixed,
+						missingElements,
+						missingElementsStarts,
+						missingElementsEnds,
+						missingElementsHaveProblems,
+						castedReceiver,
+						receiverStart,
+						receiverEnd);
+				}
+
+				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	protected void findFieldsAndMethods(
+		char[] token,
+		TypeBinding receiverType,
+		Scope scope,
+		ObjectVector fieldsFound,
+		ObjectVector methodsFound,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean superCall,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		if (token == null)
+			return;
+
+		if (receiverType.isBaseType())
+			return; // nothing else is possible with base types
+
+		boolean proposeField =
+			castedReceiver == null ?
+					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
+					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
+		boolean proposeMethod =
+			castedReceiver == null ?
+					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
+					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
+
+		if (receiverType.isArrayType()) {
+			if (proposeField
+				&& token.length <= lengthField.length
+				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
+			)) {
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(token,lengthField);
+				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
+				if (missingElements != null) {
+					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+				}
+				this.noProposal = false;
+				if (castedReceiver == null) {
+					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(receiverType));
+						proposal.setSignature(INT_SIGNATURE);
+						proposal.setTypeName(INT);
+						proposal.setName(lengthField);
+						if (missingElements != null) {
+							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+							for (int i = 0; i < missingElements.length; i++) {
+								subProposals[i] =
+									createRequiredTypeProposal(
+											missingElements[i],
+											missingElementsStarts[i],
+											missingElementsEnds[i],
+											relevance);
+							}
+							proposal.setRequiredProposals(subProposals);
+						}
+						proposal.setCompletion(lengthField);
+						proposal.setFlags(Flags.AccPublic);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					char[] completion = CharOperation.concat(castedReceiver, lengthField);
+
+					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(receiverType));
+						proposal.setSignature(INT_SIGNATURE);
+						proposal.setReceiverSignature(getSignature(receiverType));
+						proposal.setTypeName(INT);
+						proposal.setName(lengthField);
+						if (missingElements != null) {
+							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+							for (int i = 0; i < missingElements.length; i++) {
+								subProposals[i] =
+									createRequiredTypeProposal(
+											missingElements[i],
+											missingElementsStarts[i],
+											missingElementsEnds[i],
+											relevance);
+							}
+							proposal.setRequiredProposals(subProposals);
+						}
+						proposal.setCompletion(completion);
+						proposal.setFlags(Flags.AccPublic);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+			}
+			if (proposeMethod
+				&& token.length <= cloneMethod.length
+				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
+			) {
+				ReferenceBinding objectRef = scope.getJavaLangObject();
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
+				relevance += computeRelevanceForExpectingType(objectRef);
+				relevance += computeRelevanceForStatic(false, false);
+				relevance += computeRelevanceForQualification(false);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
+				if (missingElements != null) {
+					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+				}
+				char[] completion;
+				if (this.source != null
+					&& this.source.length > this.endPosition
+					&& this.source[this.endPosition] == '(') {
+					completion = cloneMethod;
+					} else {
+					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
+				}
+
+				if (castedReceiver != null) {
+					completion = CharOperation.concat(castedReceiver, completion);
+				}
+
+				this.noProposal = false;
+				if (castedReceiver == null) {
+					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(receiverType));
+						proposal.setSignature(
+								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
+										createMethodSignature(
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.NO_CHAR_CHAR,
+												getSignature(receiverType)) :
+										createMethodSignature(
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.concatWith(JAVA_LANG, '.'),
+												OBJECT));
+						//proposal.setOriginalSignature(null);
+						//proposal.setDeclarationPackageName(null);
+						//proposal.setDeclarationTypeName(null);
+						//proposal.setParameterPackageNames(null);
+						//proposal.setParameterTypeNames(null);
+						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+						proposal.setTypeName(OBJECT);
+						proposal.setName(cloneMethod);
+						if (missingElements != null) {
+							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+							for (int i = 0; i < missingElements.length; i++) {
+								subProposals[i] =
+									createRequiredTypeProposal(
+											missingElements[i],
+											missingElementsStarts[i],
+											missingElementsEnds[i],
+											relevance);
+							}
+							proposal.setRequiredProposals(subProposals);
+						}
+						proposal.setCompletion(completion);
+						proposal.setFlags(Flags.AccPublic);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
+				} else {
+					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(receiverType));
+						proposal.setSignature(
+								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
+										createMethodSignature(
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.NO_CHAR_CHAR,
+												getSignature(receiverType)) :
+										createMethodSignature(
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.NO_CHAR_CHAR,
+												CharOperation.concatWith(JAVA_LANG, '.'),
+												OBJECT));
+						proposal.setReceiverSignature(getSignature(receiverType));
+						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+						proposal.setTypeName(OBJECT);
+						proposal.setName(cloneMethod);
+						if (missingElements != null) {
+							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+							for (int i = 0; i < missingElements.length; i++) {
+								subProposals[i] =
+									createRequiredTypeProposal(
+											missingElements[i],
+											missingElementsStarts[i],
+											missingElementsEnds[i],
+											relevance);
+							}
+							proposal.setRequiredProposals(subProposals);
+						}
+						proposal.setCompletion(completion);
+						proposal.setFlags(Flags.AccPublic);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+			}
+
+			receiverType = scope.getJavaLangObject();
+		}
+		
+		checkCancel();
+		
+		if(proposeField) {
+			findFields(
+				token,
+				(ReferenceBinding) receiverType,
+				scope,
+				fieldsFound,
+				new ObjectVector(),
+				false,
+				invocationSite,
+				invocationScope,
+				implicitCall,
+				false,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				castedReceiver,
+				receiverStart,
+				receiverEnd);
+		}
+
+		if(proposeMethod) {
+			findMethods(
+				token,
+				null,
+				null,
+				(ReferenceBinding) receiverType,
+				scope,
+				methodsFound,
+				false,
+				false,
+				invocationSite,
+				invocationScope,
+				implicitCall,
+				superCall,
+				false,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				castedReceiver,
+				receiverStart,
+				receiverEnd);
+		}
+	}
+
+	protected void findFieldsAndMethodsFromAnotherReceiver(
+			char[] token,
+			TypeReference receiverType,
+			Scope scope,
+			ObjectVector fieldsFound,
+			ObjectVector methodsFound,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean implicitCall,
+			boolean superCall,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds,
+			boolean missingElementsHaveProblems,
+			char[][] receiverName,
+			int receiverStart,
+			int receiverEnd) {
+
+		if (receiverType.resolvedType == null) return;
+
+		TypeBinding receiverTypeBinding = receiverType.resolvedType;
+		char[] castedReceiver = null;
+
+		char[] castedTypeChars = CharOperation.concatWith(receiverType.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(
+							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(
+				token,
+				receiverTypeBinding,
+				scope,
+				fieldsFound,
+				methodsFound,
+				invocationSite,
+				invocationScope,
+				implicitCall,
+				superCall,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				castedReceiver,
+				receiverStart,
+				receiverEnd);
+
+		this.startPosition = oldStartPosition;
+	}
+	private void findFieldsAndMethodsFromCastedReceiver(
+			ASTNode enclosingNode,
+			Binding qualifiedBinding,
+			Scope scope,
+			ObjectVector fieldsFound,
+			ObjectVector methodsFound,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			Expression receiver) {
+
+		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
+
+		IfStatement ifStatement = (IfStatement)enclosingNode;
+		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 == 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.|
+					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(
+							CharOperation.concat(
+								'(',
+								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 {
+				break;
+			}
+		}
+	}
+	private void findFieldsAndMethodsFromFavorites(
+			char[] token,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			ObjectVector localsFound,
+			ObjectVector fieldsFound,
+			ObjectVector methodsFound) {
+
+		ObjectVector methodsFoundFromFavorites = new ObjectVector();
+
+		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
+
+		if (favoriteBindings != null && favoriteBindings.length > 0) {
+			for (int i = 0; i < favoriteBindings.length; i++) {
+				ImportBinding favoriteBinding = favoriteBindings[i];
+				switch (favoriteBinding.resolvedImport.kind()) {
+					case Binding.FIELD:
+						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
+						findFieldsFromFavorites(
+								token,
+								new FieldBinding[]{fieldBinding},
+								scope,
+								fieldsFound,
+								localsFound,
+								fieldBinding.declaringClass,
+								invocationSite,
+								invocationScope);
+						break;
+					case Binding.METHOD:
+						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
+						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
+						long range;
+						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
+							int start = (int) range, end = (int) (range >> 32);
+							int length = end - start + 1;
+							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
+						} else {
+							methods = Binding.NO_METHODS;
+						}
+						findLocalMethodsFromFavorites(
+								token,
+								methods,
+								scope,
+								methodsFound,
+								methodsFoundFromFavorites,
+								methodBinding.declaringClass,
+								invocationSite,
+								invocationScope);
+						break;
+					case Binding.TYPE:
+						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
+						if(favoriteBinding.onDemand) {
+							findFieldsFromFavorites(
+									token,
+									referenceBinding.availableFields(),
+									scope,
+									fieldsFound,
+									localsFound,
+									referenceBinding,
+									invocationSite,
+									invocationScope);
+
+							findLocalMethodsFromFavorites(
+									token,
+									referenceBinding.availableMethods(),
+									scope,
+									methodsFound,
+									methodsFoundFromFavorites,
+									referenceBinding,
+									invocationSite,
+									invocationScope);
+						}
+						break;
+				}
+			}
+		}
+
+		methodsFound.addAll(methodsFoundFromFavorites);
+	}
+
+	private boolean findFieldsAndMethodsFromMissingFieldType(
+		char[] token,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean insideTypeAnnotation) {
+
+		boolean foundSomeFields = false;
+
+		Scope currentScope = scope;
+
+		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (currentScope.kind) {
+
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) currentScope;
+					if(!insideTypeAnnotation) {
+
+						FieldDeclaration[] fields = classScope.referenceContext.fields;
+
+						int fieldsCount = fields == null ? 0 : fields.length;
+						for (int i = 0; i < fieldsCount; i++) {
+							FieldDeclaration fieldDeclaration = fields[i];
+							if (CharOperation.equals(fieldDeclaration.name, token)) {
+								FieldBinding fieldBinding = fieldDeclaration.binding;
+								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
+									foundSomeFields = true;
+									findFieldsAndMethodsFromMissingType(
+											fieldDeclaration.type,
+											currentScope,
+											invocationSite,
+											scope);
+								}
+								break done;
+							}
+						}
+					}
+					insideTypeAnnotation = false;
+					break;
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done;
+			}
+			currentScope = currentScope.parent;
+		}
+		return foundSomeFields;
+	}
+
+	private void findFieldsAndMethodsFromMissingReturnType(
+		char[] token,
+		TypeBinding[] arguments,
+		Scope scope,
+		InvocationSite invocationSite,
+		boolean insideTypeAnnotation) {
+
+		Scope currentScope = scope;
+
+		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (currentScope.kind) {
+
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) currentScope;
+					if(!insideTypeAnnotation) {
+
+						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
+
+						int methodsCount = methods == null ? 0 : methods.length;
+						for (int i = 0; i < methodsCount; i++) {
+							AbstractMethodDeclaration methodDeclaration = methods[i];
+							if (methodDeclaration instanceof MethodDeclaration &&
+									CharOperation.equals(methodDeclaration.selector, token)) {
+								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
+								MethodBinding methodBinding = method.binding;
+								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
+									Argument[] parameters = method.arguments;
+									int parametersLength = parameters == null ? 0 : parameters.length;
+									int argumentsLength = arguments == null ? 0 : arguments.length;
+
+									if (parametersLength == 0) {
+										if (argumentsLength == 0) {
+											findFieldsAndMethodsFromMissingType(
+													method.returnType,
+													currentScope,
+													invocationSite,
+													scope);
+											break done;
+										}
+									} else {
+										TypeBinding[] parametersBindings;
+										if (methodBinding == null) { // since no binding, extra types from type references
+											parametersBindings = new TypeBinding[parametersLength];
+											for (int j = 0; j < parametersLength; j++) {
+												TypeBinding parameterType = parameters[j].type.resolvedType;
+												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
+													parameterType = parameterType.closestMatch();
+												}
+												parametersBindings[j] = parameterType;
+											}
+										} else {
+											parametersBindings = methodBinding.parameters;
+										}
+										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
+											findFieldsAndMethodsFromMissingType(
+													method.returnType,
+													currentScope,
+													invocationSite,
+													scope);
+											break done;
+										}
+									}
+								}
+
+							}
+						}
+					}
+					insideTypeAnnotation = false;
+					break;
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done;
+			}
+			currentScope = currentScope.parent;
+		}
+	}
+
+	private void findFieldsAndMethodsFromMissingType(
+			TypeReference typeRef,
+			final Scope scope,
+			final InvocationSite invocationSite,
+			final Scope invocationScope) {
+		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+			new MissingTypesGuesser.GuessedTypeRequestor() {
+				public void accept(
+						TypeBinding guessedType,
+						Binding[] missingElements,
+						int[] missingElementsStarts,
+						int[] missingElementsEnds,
+						boolean hasProblems) {
+					findFieldsAndMethods(
+						CompletionEngine.this.completionToken,
+						guessedType,
+						scope,
+						new ObjectVector(),
+						new ObjectVector(),
+						invocationSite,
+						invocationScope,
+						false,
+						false,
+						missingElements,
+						missingElementsStarts,
+						missingElementsEnds,
+						hasProblems,
+						null,
+						-1,
+						-1);
+
+				}
+			};
+		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+	}
+
+	private void findFieldsAndMethodsFromStaticImports(
+			char[] token,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean exactMatch,
+			boolean insideAnnotationAttribute,
+			ObjectVector localsFound,
+			ObjectVector fieldsFound,
+			ObjectVector methodsFound,
+			boolean proposeField,
+			boolean proposeMethod) {
+		// search in static import
+		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+		for (int i = 0; i < importBindings.length; i++) {
+			ImportBinding importBinding = importBindings[i];
+			if(importBinding.isValidBinding() && importBinding.isStatic()) {
+				Binding binding = importBinding.resolvedImport;
+				if(binding != null && binding.isValidBinding()) {
+					if(importBinding.onDemand) {
+						if((binding.kind() & Binding.TYPE) != 0) {
+							if(proposeField) {
+								findFields(
+									token,
+									(ReferenceBinding)binding,
+									scope,
+									fieldsFound,
+									localsFound,
+									true,
+									invocationSite,
+									invocationScope,
+									true,
+									false,
+									null,
+									null,
+									null,
+									false,
+									null,
+									-1,
+									-1);
+							}
+							if(proposeMethod && !insideAnnotationAttribute) {
+								findMethods(
+									token,
+									null,
+									null,
+									(ReferenceBinding)binding,
+									scope,
+									methodsFound,
+									true,
+									exactMatch,
+									invocationSite,
+									invocationScope,
+									true,
+									false,
+									false,
+									null,
+									null,
+									null,
+									false,
+									null,
+									-1,
+									-1);
+							}
+						}
+					} else {
+						if ((binding.kind() & Binding.FIELD) != 0) {
+							if(proposeField) {
+									findFields(
+											token,
+											new FieldBinding[]{(FieldBinding)binding},
+											scope,
+											fieldsFound,
+											localsFound,
+											true,
+											((FieldBinding)binding).declaringClass,
+											invocationSite,
+											invocationScope,
+											true,
+											false,
+											null,
+											null,
+											null,
+											false,
+											null,
+											-1,
+											-1);
+							}
+						} else if ((binding.kind() & Binding.METHOD) != 0) {
+							if(proposeMethod && !insideAnnotationAttribute) {
+								MethodBinding methodBinding = (MethodBinding)binding;
+								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
+										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector) ||
+										(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, methodBinding.selector))) {
+									findLocalMethodsFromStaticImports(
+											token,
+											methodBinding.declaringClass.getMethods(methodBinding.selector),
+											scope,
+											exactMatch,
+											methodsFound,
+											methodBinding.declaringClass,
+											invocationSite);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void findFieldsFromFavorites(
+			char[] fieldName,
+			FieldBinding[] fields,
+			Scope scope,
+			ObjectVector fieldsFound,
+			ObjectVector localsFound,
+			ReferenceBinding receiverType,
+			InvocationSite invocationSite,
+			Scope invocationScope) {
+
+		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
+
+		int fieldLength = fieldName.length;
+		next : for (int f = fields.length; --f >= 0;) {
+			FieldBinding field = fields[f];
+
+			if (field.isSynthetic())	continue next;
+
+			// only static fields must be proposed
+			if (!field.isStatic()) continue next;
+
+			if (fieldLength > field.name.length) continue next;
+
+			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
+
+			if (this.options.checkDeprecation &&
+					field.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(field.declaringClass))
+				continue next;
+
+			if (this.options.checkVisibility
+				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
+
+			for (int i = fieldsFound.size; --i >= 0;) {
+				Object[] other = (Object[])fieldsFound.elementAt(i);
+				FieldBinding otherField = (FieldBinding) other[0];
+
+				if (field == otherField) continue next;
+			}
+
+			fieldsFound.add(new Object[]{field, receiverType});
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal(field);
+			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+			relevance += computeRelevanceForExpectingType(field.type);
+			relevance += computeRelevanceForEnumConstant(field.type);
+			relevance += computeRelevanceForStatic(true, true);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+			int importStart = cu.types[0].declarationSourceStart;
+			int importEnd = importStart;
+
+			this.noProposal = false;
+
+			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
+					!this.options.suggestStaticImport) {
+				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
+					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
+
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+
+					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
+
+					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+					typeImportProposal.completionEngine = this;
+					char[] packageName = receiverType.qualifiedPackageName();
+					typeImportProposal.setDeclarationSignature(packageName);
+					typeImportProposal.setSignature(getSignature(receiverType));
+					typeImportProposal.setPackageName(packageName);
+					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
+					typeImportProposal.setCompletion(typeImportCompletion);
+					typeImportProposal.setFlags(receiverType.modifiers);
+					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+					typeImportProposal.setRelevance(relevance);
+
+					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			} else {
+				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
+					char[] completion = field.name;
+
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName());
+					proposal.setName(field.name);
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+
+					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
+
+					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
+					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
+					fieldImportProposal.setSignature(getSignature(field.type));
+					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
+					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
+					fieldImportProposal.setName(field.name);
+					fieldImportProposal.setCompletion(fieldImportCompletion);
+					fieldImportProposal.setFlags(field.modifiers);
+					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
+					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+					fieldImportProposal.setRelevance(relevance);
+
+					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
+
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
+	private void findImplicitMessageSends(
+		char[] token,
+		TypeBinding[] argTypes,
+		Scope scope,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		ObjectVector methodsFound) {
+
+		if (token == null)
+			return;
+
+		boolean staticsOnly = false;
+		// need to know if we're in a static context (or inside a constructor)
+
+		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (scope.kind) {
+
+				case Scope.METHOD_SCOPE :
+					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+					MethodScope methodScope = (MethodScope) scope;
+					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+					break;
+
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) scope;
+					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+					findMethods(
+						token,
+						null,
+						argTypes,
+						enclosingType,
+						classScope,
+						methodsFound,
+						staticsOnly,
+						true,
+						invocationSite,
+						invocationScope,
+						true,
+						false,
+						true,
+						null,
+						null,
+						null,
+						false,
+						null,
+						-1,
+						-1);
+					staticsOnly |= enclosingType.isStatic();
+					break;
+
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done;
+			}
+			scope = scope.parent;
+		}
+	}
+	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
+		char[][] tokens = importReference.tokens;
+
+		char[] importName = CharOperation.concatWith(tokens, '.');
+
+		if (importName.length == 0)
+			return;
+
+		char[] lastToken = tokens[tokens.length - 1];
+		if(lastToken != null && lastToken.length == 0)
+			importName = CharOperation.concat(importName, new char[]{'.'});
+
+		this.resolvingImports = true;
+		this.resolvingStaticImports = importReference.isStatic();
+
+		this.completionToken =  lastToken;
+		this.qualifiedCompletionToken = importName;
+
+		// want to replace the existing .*;
+		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+			int oldStart = this.startPosition;
+			int oldEnd = this.endPosition;
+			setSourceRange(
+				importReference.sourceStart,
+				importReference.declarationSourceEnd);
+			this.nameEnvironment.findPackages(importName, this);
+			setSourceRange(
+				oldStart,
+				oldEnd - 1,
+				false);
+		}
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			this.foundTypesCount = 0;
+			this.nameEnvironment.findTypes(
+					importName,
+					findMembers,
+					this.options.camelCaseMatch,
+					IJavaSearchConstants.TYPE,
+					this,
+					this.monitor);
+			acceptTypes(null);
+		}
+	}
+
+	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
+		ReferenceBinding[] memberTypes = ref.memberTypes();
+
+		int typeLength = typeName.length;
+		next : for (int m = memberTypes.length; --m >= 0;) {
+			ReferenceBinding memberType = memberTypes[m];
+			//		if (!wantClasses && memberType.isClass()) continue next;
+			//		if (!wantInterfaces && memberType.isInterface()) continue next;
+
+			if (onlyStatic && !memberType.isStatic())
+				continue next;
+
+			if (typeLength > memberType.sourceName.length)
+				continue next;
+
+			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
+				continue next;
+
+			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
+
+			if (this.options.checkVisibility
+				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
+				continue next;
+
+			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			if (memberType.isClass()) {
+				relevance += computeRelevanceForClass();
+			} else if(memberType.isEnum()) {
+				relevance += computeRelevanceForEnum();
+			} else if (memberType.isInterface()) {
+				relevance += computeRelevanceForInterface();
+			}
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+				createTypeProposal(
+						memberType,
+						memberType.qualifiedSourceName(),
+						IAccessRule.K_ACCESSIBLE,
+						completionName,
+						relevance,
+						null,
+						null,
+						null,
+						false);
+			}
+		}
+	}
+
+	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
+		FieldBinding[] fields = ref.availableFields();
+
+		int fieldLength = fieldName.length;
+		next : for (int m = fields.length; --m >= 0;) {
+			FieldBinding field = fields[m];
+
+			if (fieldLength > field.name.length)
+				continue next;
+
+			if (field.isSynthetic())
+				continue next;
+
+			if (!field.isStatic())
+				continue next;
+
+			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
+				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
+				continue next;
+
+			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
+
+			if (this.options.checkVisibility
+				&& !field.canBeSeenBy(this.unitScope.fPackage))
+				continue next;
+
+			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(field.declaringClass));
+				proposal.setSignature(getSignature(field.type));
+				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+				proposal.setPackageName(field.type.qualifiedPackageName());
+				proposal.setTypeName(field.type.qualifiedSourceName());
+				proposal.setName(field.name);
+				proposal.setCompletion(completionName);
+				proposal.setFlags(field.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+
+	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
+		MethodBinding[] methods = ref.availableMethods();
+
+		int methodLength = methodName.length;
+		next : for (int m = methods.length; --m >= 0;) {
+			MethodBinding method = methods[m];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (!method.isStatic()) continue next;
+
+			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
+
+			if (this.options.checkVisibility
+				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
+
+			if (methodLength > method.selector.length)
+				continue next;
+
+			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
+				continue next;
+
+			int length = method.parameters.length;
+			char[][] parameterPackageNames = new char[length][];
+			char[][] parameterTypeNames = new char[length][];
+
+			for (int i = 0; i < length; i++) {
+				TypeBinding type = method.original().parameters[i];
+				parameterPackageNames[i] = type.qualifiedPackageName();
+				parameterTypeNames[i] = type.qualifiedSourceName();
+			}
+			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setSignature(getSignature(method));
+				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+				proposal.setParameterPackageNames(parameterPackageNames);
+				proposal.setParameterTypeNames(parameterTypeNames);
+				proposal.setPackageName(method.returnType.qualifiedPackageName());
+				proposal.setTypeName(method.returnType.qualifiedSourceName());
+				proposal.setName(method.selector);
+				proposal.setCompletion(completionName);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				if(parameterNames != null) proposal.setParameterNames(parameterNames);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+	
+	private void findInterfacesMethodDeclarations(
+		char[] selector,
+		ReferenceBinding receiverType,
+		ReferenceBinding[] itsInterfaces,
+		Scope scope,
+		ObjectVector methodsFound,
+		Binding[] missingElements,
+		int[] missingElementssStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems) {
+
+		if (selector == null)
+			return;
+
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding currentType = interfacesToVisit[i];
+				MethodBinding[] methods = currentType.availableMethods();
+				if(methods != null) {
+					findLocalMethodDeclarations(
+						selector,
+						methods,
+						scope,
+						methodsFound,
+						false,
+						receiverType);
+				}
+
+				itsInterfaces = currentType.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+	
+	private void findInterfacesMethods(
+		char[] selector,
+		TypeBinding[] typeArgTypes,
+		TypeBinding[] argTypes,
+		ReferenceBinding receiverType,
+		ReferenceBinding[] itsInterfaces,
+		Scope scope,
+		ObjectVector methodsFound,
+		boolean onlyStaticMethods,
+		boolean exactMatch,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean superCall,
+		boolean canBePrefixed,
+		Binding[] missingElements,
+		int[] missingElementssStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		if (selector == null)
+			return;
+
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding currentType = interfacesToVisit[i];
+				MethodBinding[] methods = currentType.availableMethods();
+				if(methods != null) {
+					findLocalMethods(
+						selector,
+						typeArgTypes,
+						argTypes,
+						methods,
+						scope,
+						methodsFound,
+						onlyStaticMethods,
+						exactMatch,
+						receiverType,
+						invocationSite,
+						invocationScope,
+						implicitCall,
+						superCall,
+						canBePrefixed,
+						missingElements,
+						missingElementssStarts,
+						missingElementsEnds,
+						missingElementsHaveProblems,
+						castedReceiver,
+						receiverStart,
+						receiverEnd);
+				}
+
+				itsInterfaces = currentType.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+	/*
+	 * Find javadoc block tags for a given completion javadoc tag node
+	 */
+	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
+		char[][] possibleTags = javadocTag.getPossibleBlockTags();
+		if (possibleTags == null) return;
+		int length = possibleTags.length;
+		for (int i=0; i<length; i++) {
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+
+			this.noProposal = false;
+			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
+				char[] possibleTag = possibleTags[i];
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
+				proposal.setName(possibleTag);
+				int tagLength = possibleTag.length;
+				char[] completion = new char[1+tagLength];
+				completion[0] = '@';
+				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
+				proposal.setCompletion(completion);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if (DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+
+	/*
+	 * Find javadoc inline tags for a given completion javadoc tag node
+	 */
+	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
+		char[][] possibleTags = javadocTag.getPossibleInlineTags();
+		if (possibleTags == null) return;
+		int length = possibleTags.length;
+		for (int i=0; i<length; i++) {
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+
+			this.noProposal = false;
+			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
+				char[] possibleTag = possibleTags[i];
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
+				proposal.setName(possibleTag);
+				int tagLength = possibleTag.length;
+//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
+				char[] completion = new char[2+tagLength+1];
+				completion[0] = '{';
+				completion[1] = '@';
+				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
+				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
+				//completion[tagLength+2] = ' ';
+				completion[tagLength+2] = '}';
+				proposal.setCompletion(completion);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if (DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
+
+	/*
+	 * Find javadoc parameter names.
+	 */
+	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
+
+		if (missingParams == null) return;
+
+		// Get relevance
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
+		if (!isTypeParam) relevance += R_INTERESTING;
+
+		// Propose missing param
+		int length = missingParams.length;
+		relevance += length;
+		for (int i=0; i<length; i++) {
+			char[] argName = missingParams[i];
+			if (token == null || CharOperation.prefixEquals(token, argName)) {
+
+				this.noProposal = false;
+				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
+					proposal.setName(argName);
+					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
+					proposal.setCompletion(completion);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(--relevance);
+					this.requestor.accept(proposal);
+					if (DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
+
+	// what about onDemand types? Ignore them since it does not happen!
+	// import p1.p2.A.*;
+	private void findKeywords(char[] keyword, char[][] choices, boolean staticFieldsAndMethodOnly, boolean ignorePackageKeyword) {
+		if(choices == null || choices.length == 0) return;
+		int length = keyword.length;
+		for (int i = 0; i < choices.length; i++)
+			if (length <= choices[i].length
+			&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
+					)){
+				if (ignorePackageKeyword && CharOperation.equals(choices[i], Keywords.PACKAGE))
+					continue;
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+				if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
+
+				if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
+					relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
+					relevance += computeRelevanceForQualification(false);
+				}
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+					proposal.setName(choices[i]);
+					proposal.setCompletion(choices[i]);
+					proposal.setReplaceRange((this.startPosition < 0) ? 0 : this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange((this.tokenStart < 0) ? 0 : this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+	}
+	private void findKeywordsForMember(char[] token, int modifiers, ASTNode astNode) {
+		char[][] keywords = new char[Keywords.COUNT][];
+		int count = 0;
+
+		// visibility
+		if((modifiers & ClassFileConstants.AccPrivate) == 0
+			&& (modifiers & ClassFileConstants.AccProtected) == 0
+			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
+			keywords[count++] = Keywords.PROTECTED;
+			keywords[count++] = Keywords.PUBLIC;
+			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
+				keywords[count++] = Keywords.PRIVATE;
+			}
+		}
+
+		if (astNode instanceof CompletionOnFieldType && 
+	        this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
+	        FieldBinding astNodeBinding = ((CompletionOnFieldType) astNode).binding;
+	        ReferenceBinding declaringClass = astNodeBinding != null ? astNodeBinding.declaringClass : null;
+	        if (declaringClass != null && declaringClass.isInterface() && !declaringClass.isAnnotationType())
+	            keywords[count++] = Keywords.DEFAULT;
+	    }
+		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
+			// abtract
+			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
+				keywords[count++] = Keywords.ABSTRACT;
+			}
+
+			// final
+			if((modifiers & ClassFileConstants.AccFinal) == 0) {
+				keywords[count++] = Keywords.FINAL;
+			}
+
+			// static
+			if((modifiers & ClassFileConstants.AccStatic) == 0) {
+				keywords[count++] = Keywords.STATIC;
+			}
+
+			boolean canBeField = true;
+			boolean canBeMethod = true;
+			boolean canBeType = true;
+			if((modifiers & ClassFileConstants.AccNative) != 0
+				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
+				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
+				canBeField = false;
+				canBeType = false;
+			}
+
+			if((modifiers & ClassFileConstants.AccTransient) != 0
+				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
+				canBeMethod = false;
+				canBeType = false;
+			}
+
+			if(canBeField) {
+				// transient
+				if((modifiers & ClassFileConstants.AccTransient) == 0) {
+					keywords[count++] = Keywords.TRANSIENT;
+				}
+
+				// volatile
+				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
+					keywords[count++] = Keywords.VOLATILE;
+				}
+			}
+
+			if(canBeMethod) {
+				// native
+				if((modifiers & ClassFileConstants.AccNative) == 0) {
+					keywords[count++] = Keywords.NATIVE;
+				}
+
+				// strictfp
+				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
+					keywords[count++] = Keywords.STRICTFP;
+				}
+
+				// synchronized
+				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
+					keywords[count++] = Keywords.SYNCHRONIZED;
+				}
+			}
+
+			if(canBeType) {
+				keywords[count++] = Keywords.CLASS;
+				keywords[count++] = Keywords.INTERFACE;
+
+				if((modifiers & ClassFileConstants.AccFinal) == 0) {
+					keywords[count++] = Keywords.ENUM;
+				}
+			}
+		} else {
+			// class
+			keywords[count++] = Keywords.CLASS;
+			keywords[count++] = Keywords.INTERFACE;
+		}
+		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
+
+		findKeywords(token, keywords, false, false);
+	}
+	private void findLabels(char[] label, char[][] choices) {
+		if(choices == null || choices.length == 0) return;
+
+		int length = label.length;
+		for (int i = 0; i < choices.length; i++) {
+			if (length <= choices[i].length
+				&& CharOperation.prefixEquals(label, choices[i], false /* ignore case */
+			)){
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(label, choices[i]);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
+					proposal.setName(choices[i]);
+					proposal.setCompletion(choices[i]);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
+
+	// Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
+	private void findLocalMethodDeclarations(
+		char[] methodName,
+		MethodBinding[] methods,
+		Scope scope,
+		ObjectVector methodsFound,
+		//	boolean noVoidReturnType, how do you know?
+		boolean exactMatch,
+		ReferenceBinding receiverType) {
+
+		ObjectVector newMethodsFound =  new ObjectVector();
+		// Inherited methods which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+		int methodLength = methodName.length;
+		next : for (int f = methods.length; --f >= 0;) {
+
+			MethodBinding method = methods[f];
+			if (method.isSynthetic())	continue next;
+
+			if (method.isDefaultAbstract()) continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (method.isFinal()) {
+                newMethodsFound.add(method);
+                continue next;
+            }
+
+			if (this.options.checkDeprecation &&
+					method.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(method.declaringClass))
+				continue next;
+
+			//		if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
+			if(method.isStatic()) continue next;
+
+			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
+
+			if (exactMatch) {
+				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
+					))
+					continue next;
+
+			} else {
+
+				if (methodLength > method.selector.length)
+					continue next;
+
+				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
+						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
+					continue next;
+			}
+
+			for (int i = methodsFound.size; --i >= 0;) {
+				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
+				if (method == otherMethod)
+					continue next;
+
+				if (CharOperation.equals(method.selector, otherMethod.selector, true)
+						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+					continue next;
+				}
+			}
+
+			newMethodsFound.add(method);
+
+			int length = method.parameters.length;
+			char[][] parameterPackageNames = new char[length][];
+			char[][] parameterFullTypeNames = new char[length][];
+
+			for (int i = 0; i < length; i++) {
+				TypeBinding type = method.parameters[i];
+				parameterPackageNames[i] = type.qualifiedPackageName();
+				parameterFullTypeNames[i] = type.qualifiedSourceName();
+			}
+
+			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
+
+			if(method.typeVariables != null && method.typeVariables.length > 0) {
+				char[][] excludedNames = findEnclosingTypeNames(scope);
+				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
+				if(substituedParameterNames != null) {
+					method = new ParameterizedMethodBinding(
+								method.declaringClass,
+								method,
+								substituedParameterNames,
+								scope.environment());
+				}
+			}
+
+			StringBuffer completion = new StringBuffer(10);
+			if (!exactMatch) {
+				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			relevance += R_METHOD_OVERIDE;
+			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
+				proposal.setSignature(getSignature(method));
+				MethodBinding original = method.original();
+				if(original != method) {
+					proposal.setOriginalSignature(getSignature(original));
+				}
+				proposal.setKey(method.computeUniqueKey());
+				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+				proposal.setParameterPackageNames(parameterPackageNames);
+				proposal.setParameterTypeNames(parameterFullTypeNames);
+				proposal.setPackageName(method.returnType.qualifiedPackageName());
+				proposal.setTypeName(method.returnType.qualifiedSourceName());
+				proposal.setCompletion(completion.toString().toCharArray());
+				proposal.setName(method.selector);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				if(parameterNames != null) proposal.setParameterNames(parameterNames);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+		methodsFound.addAll(newMethodsFound);
+	}
+
+	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+	private void findLocalMethods(
+		char[] methodName,
+		TypeBinding[] typeArgTypes,
+		TypeBinding[] argTypes,
+		MethodBinding[] methods,
+		Scope scope,
+		ObjectVector methodsFound,
+		boolean onlyStaticMethods,
+		boolean exactMatch,
+		ReferenceBinding receiverType,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean superCall,
+		boolean canBePrefixed,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		ObjectVector newMethodsFound =  new ObjectVector();
+		// Inherited methods which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+
+		int methodLength = methodName.length;
+		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
+		int minArgLength = argTypes == null ? 0 : argTypes.length;
+
+		next : for (int f = methods.length; --f >= 0;) {
+			MethodBinding method = methods[f];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (this.options.checkDeprecation &&
+					method.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(method.declaringClass))
+				continue next;
+
+			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
+			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
+
+			if (onlyStaticMethods && !method.isStatic()) continue next;
+
+			if (this.options.checkVisibility
+				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			if(superCall && method.isAbstract()) {
+				methodsFound.add(new Object[]{method, receiverType});
+				continue next;
+			}
+
+			if (exactMatch) {
+				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
+					continue next;
+				}
+			} else {
+				if (methodLength > method.selector.length) continue next;
+				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
+						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
+					continue next;
+				}
+			}
+
+			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
+				continue next;
+
+			if (minTypeArgLength != 0) {
+				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
+			}
+
+			if (minArgLength > method.parameters.length)
+				continue next;
+
+			for (int a = minArgLength; --a >= 0;){
+				if (argTypes[a] != null) { // can be null if it could not be resolved properly
+					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
+						continue next;
+					}
+				}
+			}
+
+			boolean prefixRequired = false;
+
+			for (int i = methodsFound.size; --i >= 0;) {
+				Object[] other = (Object[]) methodsFound.elementAt(i);
+				MethodBinding otherMethod = (MethodBinding) other[0];
+				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+				if (method == otherMethod && receiverType == otherReceiverType)
+					continue next;
+
+				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+					if (receiverType == otherReceiverType) {
+						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+							if (!superCall || !otherMethod.declaringClass.isInterface()) {
+								continue next;
+							}
+						}
+					} else {
+						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+							if(receiverType.isAnonymousType()) continue next;
+
+							if(!superCall) {
+								if(!canBePrefixed) continue next;
+
+								prefixRequired = true;
+							}
+						}
+					}
+				}
+			}
+
+			newMethodsFound.add(new Object[]{method, receiverType});
+
+			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
+			if (method.declaringClass != superTypeWithSameErasure) {
+				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
+				for (int i = 0; i < otherMethods.length; i++) {
+					if(otherMethods[i].original() == method.original()) {
+						method = otherMethods[i];
+					}
+				}
+			}
+
+			int length = method.parameters.length;
+			char[][] parameterPackageNames = new char[length][];
+			char[][] parameterTypeNames = new char[length][];
+
+			for (int i = 0; i < length; i++) {
+				TypeBinding type = method.original().parameters[i];
+				parameterPackageNames[i] = type.qualifiedPackageName();
+				parameterTypeNames[i] = type.qualifiedSourceName();
+			}
+			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+			char[] completion = CharOperation.NO_CHAR;
+
+			int previousStartPosition = this.startPosition;
+			int previousTokenStart = this.tokenStart;
+
+			// Special case for completion in javadoc
+			if (this.assistNodeInJavadoc > 0) {
+				Expression receiver = null;
+				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
+					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
+					receiver = msg.receiver;
+				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+					receiver = fieldRef.receiver;
+				}
+				if (receiver != null) {
+					StringBuffer javadocCompletion = new StringBuffer();
+					if (receiver.isThis()) {
+						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+							javadocCompletion.append('#');
+						}
+					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+						if (receiver instanceof JavadocSingleTypeReference) {
+							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
+							javadocCompletion.append(typeRef.token);
+							javadocCompletion.append('#');
+						} else if (receiver instanceof JavadocQualifiedTypeReference) {
+							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
+							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
+							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
+								if (t>0) javadocCompletion.append('.');
+								javadocCompletion.append(typeRef.tokens[t]);
+							}
+							javadocCompletion.append('#');
+						}
+					}
+					javadocCompletion.append(method.selector);
+					// Append parameters types
+					javadocCompletion.append('(');
+					if (method.parameters != null) {
+						boolean isVarargs = method.isVarargs();
+						for (int p=0, ln=method.parameters.length; p<ln; p++) {
+							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
+							TypeBinding argTypeBinding = method.parameters[p];
+							if (isVarargs && p == ln - 1)  {
+								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
+							} else {
+								createType(argTypeBinding.erasure(), scope,javadocCompletion);
+							}
+						}
+					}
+					javadocCompletion.append(')');
+					completion = javadocCompletion.toString().toCharArray();
+				}
+			} else {
+				// nothing to insert - do not want to replace the existing selector & arguments
+				if (!exactMatch) {
+					if (this.source != null
+						&& this.source.length > this.endPosition
+						&& this.source[this.endPosition] == '(')
+						completion = method.selector;
+					else
+						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+
+					if (castedReceiver != null) {
+						completion = CharOperation.concat(castedReceiver, completion);
+					}
+				} else {
+					if(prefixRequired && (this.source != null)) {
+						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
+					} else {
+						this.startPosition = this.endPosition;
+					}
+					this.tokenStart = this.tokenEnd;
+				}
+
+				if(prefixRequired || this.options.forceImplicitQualification){
+					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
+					completion = CharOperation.concat(prefix,completion,'.');
+				}
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			relevance += computeRelevanceForExpectingType(method.returnType);
+			relevance += computeRelevanceForEnumConstant(method.returnType);
+			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
+			relevance += computeRelevanceForQualification(prefixRequired);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+			if (onlyStaticMethods && this.insideQualifiedReference) {
+				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
+			}
+			if (missingElements != null) {
+				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+			}
+			relevance += computeRelevanceForSuper(method, scope, invocationSite);
+			this.noProposal = false;
+
+			if (castedReceiver == null) {
+				// Standard proposal
+				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(method.declaringClass));
+					proposal.setSignature(getSignature(method));
+					MethodBinding original = method.original();
+					if(original != method) {
+						proposal.setOriginalSignature(getSignature(original));
+					}
+					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+					proposal.setParameterPackageNames(parameterPackageNames);
+					proposal.setParameterTypeNames(parameterTypeNames);
+					proposal.setPackageName(method.returnType.qualifiedPackageName());
+					proposal.setTypeName(method.returnType.qualifiedSourceName());
+					proposal.setName(method.selector);
+					if (missingElements != null) {
+						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+						for (int i = 0; i < missingElements.length; i++) {
+							subProposals[i] =
+								createRequiredTypeProposal(
+										missingElements[i],
+										missingElementsStarts[i],
+										missingElementsEnds[i],
+										relevance);
+						}
+						proposal.setRequiredProposals(subProposals);
+					}
+					proposal.setCompletion(completion);
+					proposal.setFlags(method.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					if(parameterNames != null) proposal.setParameterNames(parameterNames);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+
+				// Javadoc proposal
+				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(method.declaringClass));
+					proposal.setSignature(getSignature(method));
+					MethodBinding original = method.original();
+					if(original != method) {
+						proposal.setOriginalSignature(getSignature(original));
+					}
+					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+					proposal.setParameterPackageNames(parameterPackageNames);
+					proposal.setParameterTypeNames(parameterTypeNames);
+					proposal.setPackageName(method.returnType.qualifiedPackageName());
+					proposal.setTypeName(method.returnType.qualifiedSourceName());
+					proposal.setName(method.selector);
+					proposal.setCompletion(javadocCompletion);
+					proposal.setFlags(method.modifiers);
+					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance+R_INLINE_TAG);
+					if(parameterNames != null) proposal.setParameterNames(parameterNames);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			} else {
+				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(method.declaringClass));
+					proposal.setSignature(getSignature(method));
+					MethodBinding original = method.original();
+					if(original != method) {
+						proposal.setOriginalSignature(getSignature(original));
+					}
+					proposal.setReceiverSignature(getSignature(receiverType));
+					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+					proposal.setParameterPackageNames(parameterPackageNames);
+					proposal.setParameterTypeNames(parameterTypeNames);
+					proposal.setPackageName(method.returnType.qualifiedPackageName());
+					proposal.setTypeName(method.returnType.qualifiedSourceName());
+					proposal.setName(method.selector);
+					if (missingElements != null) {
+						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+						for (int i = 0; i < missingElements.length; i++) {
+							subProposals[i] =
+								createRequiredTypeProposal(
+										missingElements[i],
+										missingElementsStarts[i],
+										missingElementsEnds[i],
+										relevance);
+						}
+						proposal.setRequiredProposals(subProposals);
+					}
+					proposal.setCompletion(completion);
+					proposal.setFlags(method.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					if(parameterNames != null) proposal.setParameterNames(parameterNames);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+			this.startPosition = previousStartPosition;
+			this.tokenStart = previousTokenStart;
+		}
+
+		methodsFound.addAll(newMethodsFound);
+	}
+	private void findLocalMethodsFromFavorites(
+			char[] methodName,
+			MethodBinding[] methods,
+			Scope scope,
+			ObjectVector methodsFound,
+			ObjectVector methodsFoundFromFavorites,
+			ReferenceBinding receiverType,
+			InvocationSite invocationSite,
+			Scope invocationScope) {
+
+			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
+
+			int methodLength = methodName.length;
+
+			next : for (int f = methods.length; --f >= 0;) {
+				MethodBinding method = methods[f];
+
+				if (method.isSynthetic()) continue next;
+
+				if (method.isDefaultAbstract())	continue next;
+
+				if (method.isConstructor()) continue next;
+
+				if (this.options.checkDeprecation &&
+						method.isViewedAsDeprecated() &&
+						!scope.isDefinedInSameUnit(method.declaringClass))
+					continue next;
+
+				if (!method.isStatic()) continue next;
+
+				if (this.options.checkVisibility
+					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+				if (methodLength > method.selector.length) continue next;
+
+				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
+						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
+					continue next;
+				}
+
+				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
+					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
+					MethodBinding otherMethod = (MethodBinding) other[0];
+
+					if (method == otherMethod) continue next;
+
+					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+						if (otherMethod.declaringClass == method.declaringClass &&
+								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+							continue next;
+						}
+					}
+				}
+
+				for (int i = methodsFound.size; --i >= 0;) {
+					Object[] other = (Object[]) methodsFound.elementAt(i);
+					MethodBinding otherMethod = (MethodBinding) other[0];
+
+					if (method == otherMethod) continue next;
+
+					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+							continue next;
+						}
+					}
+				}
+
+				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
+					this.options.suggestStaticImport;
+
+				boolean isAlreadyImported = false;
+				if (!proposeStaticImport) {
+					if(!this.importCachesInitialized) {
+						initializeImportCaches();
+					}
+					for (int j = 0; j < this.importCacheCount; j++) {
+						char[][] importName = this.importsCache[j];
+						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
+							if (!CharOperation.equals(typeName, importName[1])) {
+								continue next;
+							} else {
+								isAlreadyImported = true;
+							}
+						}
+					}
+				}
+
+				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
+
+				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
+				if (method.declaringClass != superTypeWithSameErasure) {
+					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
+					for (int i = 0; i < otherMethods.length; i++) {
+						if(otherMethods[i].original() == method.original()) {
+							method = otherMethods[i];
+						}
+					}
+				}
+
+				int length = method.parameters.length;
+				char[][] parameterPackageNames = new char[length][];
+				char[][] parameterTypeNames = new char[length][];
+
+				for (int i = 0; i < length; i++) {
+					TypeBinding type = method.original().parameters[i];
+					parameterPackageNames[i] = type.qualifiedPackageName();
+					parameterTypeNames[i] = type.qualifiedSourceName();
+				}
+				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+				char[] completion = CharOperation.NO_CHAR;
+
+				int previousStartPosition = this.startPosition;
+				int previousTokenStart = this.tokenStart;
+
+				if (this.source != null
+					&& this.source.length > this.endPosition
+					&& this.source[this.endPosition] == '(') {
+					completion = method.selector;
+				} else {
+					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+				}
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+				relevance += computeRelevanceForExpectingType(method.returnType);
+				relevance += computeRelevanceForEnumConstant(method.returnType);
+				relevance += computeRelevanceForStatic(true, method.isStatic());
+				relevance += computeRelevanceForQualification(true);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+				int importStart = cu.types[0].declarationSourceStart;
+				int importEnd = importStart;
+
+				this.noProposal = false;
+
+				if (!proposeStaticImport) {
+					if (isAlreadyImported) {
+						if (!isIgnored(CompletionProposal.METHOD_REF)) {
+							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
+
+							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+							proposal.setDeclarationSignature(getSignature(method.declaringClass));
+							proposal.setSignature(getSignature(method));
+							MethodBinding original = method.original();
+							if(original != method) {
+								proposal.setOriginalSignature(getSignature(original));
+							}
+							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+							proposal.setParameterPackageNames(parameterPackageNames);
+							proposal.setParameterTypeNames(parameterTypeNames);
+							proposal.setPackageName(method.returnType.qualifiedPackageName());
+							proposal.setTypeName(method.returnType.qualifiedSourceName());
+							proposal.setName(method.selector);
+							proposal.setCompletion(completion);
+							proposal.setFlags(method.modifiers);
+							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+							proposal.setRelevance(relevance);
+							if(parameterNames != null) proposal.setParameterNames(parameterNames);
+
+							this.requestor.accept(proposal);
+							if(DEBUG) {
+								this.printDebug(proposal);
+							}
+						}
+					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
+						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
+
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(method.declaringClass));
+						proposal.setSignature(getSignature(method));
+						MethodBinding original = method.original();
+						if(original != method) {
+							proposal.setOriginalSignature(getSignature(original));
+						}
+						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+						proposal.setParameterPackageNames(parameterPackageNames);
+						proposal.setParameterTypeNames(parameterTypeNames);
+						proposal.setPackageName(method.returnType.qualifiedPackageName());
+						proposal.setTypeName(method.returnType.qualifiedSourceName());
+						proposal.setName(method.selector);
+						proposal.setCompletion(completion);
+						proposal.setFlags(method.modifiers);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						if(parameterNames != null) proposal.setParameterNames(parameterNames);
+
+						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
+
+						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+						typeImportProposal.completionEngine = this;
+						char[] packageName = receiverType.qualifiedPackageName();
+						typeImportProposal.setDeclarationSignature(packageName);
+						typeImportProposal.setSignature(getSignature(receiverType));
+						typeImportProposal.setPackageName(packageName);
+						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
+						typeImportProposal.setCompletion(typeImportCompletion);
+						typeImportProposal.setFlags(receiverType.modifiers);
+						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+						typeImportProposal.setRelevance(relevance);
+
+						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(getSignature(method.declaringClass));
+						proposal.setSignature(getSignature(method));
+						MethodBinding original = method.original();
+						if(original != method) {
+							proposal.setOriginalSignature(getSignature(original));
+						}
+						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+						proposal.setParameterPackageNames(parameterPackageNames);
+						proposal.setParameterTypeNames(parameterTypeNames);
+						proposal.setPackageName(method.returnType.qualifiedPackageName());
+						proposal.setTypeName(method.returnType.qualifiedSourceName());
+						proposal.setName(method.selector);
+						proposal.setCompletion(completion);
+						proposal.setFlags(method.modifiers);
+						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						if(parameterNames != null) proposal.setParameterNames(parameterNames);
+
+						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
+
+						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
+						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
+						methodImportProposal.setSignature(getSignature(method));
+						if(original != method) {
+							proposal.setOriginalSignature(getSignature(original));
+						}
+						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+						methodImportProposal.setParameterPackageNames(parameterPackageNames);
+						methodImportProposal.setParameterTypeNames(parameterTypeNames);
+						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
+						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
+						methodImportProposal.setName(method.selector);
+						methodImportProposal.setCompletion(methodImportCompletion);
+						methodImportProposal.setFlags(method.modifiers);
+						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
+						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+						methodImportProposal.setRelevance(relevance);
+						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
+
+						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
+
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+
+				this.startPosition = previousStartPosition;
+				this.tokenStart = previousTokenStart;
+			}
+		}
+
+	/**
+	 * Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+	 * Note that the method doesn't do a comparison of the method names and expects the client to handle the same.
+	 * 
+	 * @methodName method as entered by the user, the one to completed
+	 * @param methods a resultant array of MethodBinding, whose names should match methodName. The calling client must ensure that this check is handled.
+	 */
+	private void findLocalMethodsFromStaticImports(
+		char[] methodName,
+		MethodBinding[] methods,
+		Scope scope,
+		boolean exactMatch,
+		ObjectVector methodsFound,
+		ReferenceBinding receiverType,
+		InvocationSite invocationSite) {
+
+		ObjectVector newMethodsFound =  new ObjectVector();
+
+		next : for (int f = methods.length; --f >= 0;) {
+			MethodBinding method = methods[f];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (!method.isStatic()) continue next;
+
+			if (this.options.checkDeprecation &&
+					method.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(method.declaringClass))
+				continue next;
+
+			if (this.options.checkVisibility
+				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			for (int i = methodsFound.size; --i >= 0;) {
+				Object[] other = (Object[]) methodsFound.elementAt(i);
+				MethodBinding otherMethod = (MethodBinding) other[0];
+				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+				if (method == otherMethod && receiverType == otherReceiverType)
+					continue next;
+
+				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+						continue next;
+					}
+				}
+			}
+
+			newMethodsFound.add(new Object[]{method, receiverType});
+
+			int length = method.parameters.length;
+			char[][] parameterPackageNames = new char[length][];
+			char[][] parameterTypeNames = new char[length][];
+
+			for (int i = 0; i < length; i++) {
+				TypeBinding type = method.original().parameters[i];
+				parameterPackageNames[i] = type.qualifiedPackageName();
+				parameterTypeNames[i] = type.qualifiedSourceName();
+			}
+			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+			char[] completion = CharOperation.NO_CHAR;
+
+			int previousStartPosition = this.startPosition;
+			int previousTokenStart = this.tokenStart;
+
+			if (!exactMatch) {
+				if (this.source != null
+					&& this.source.length > this.endPosition
+					&& this.source[this.endPosition] == '(') {
+					completion = method.selector;
+				} else {
+					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+				}
+			} else {
+				this.startPosition = this.endPosition;
+				this.tokenStart = this.tokenEnd;
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			relevance += computeRelevanceForExpectingType(method.returnType);
+			relevance += computeRelevanceForEnumConstant(method.returnType);
+			relevance += computeRelevanceForStatic(true, method.isStatic());
+			relevance += computeRelevanceForQualification(false);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setSignature(getSignature(method));
+				MethodBinding original = method.original();
+				if(original != method) {
+					proposal.setOriginalSignature(getSignature(original));
+				}
+				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+				proposal.setParameterPackageNames(parameterPackageNames);
+				proposal.setParameterTypeNames(parameterTypeNames);
+				proposal.setPackageName(method.returnType.qualifiedPackageName());
+				proposal.setTypeName(method.returnType.qualifiedSourceName());
+				proposal.setName(method.selector);
+				proposal.setCompletion(completion);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+				proposal.setRelevance(relevance);
+				if(parameterNames != null) proposal.setParameterNames(parameterNames);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+			this.startPosition = previousStartPosition;
+			this.tokenStart = previousTokenStart;
+		}
+
+		methodsFound.addAll(newMethodsFound);
+	}
+
+	private void findLocalMethodsFromStaticImports(
+			char[] token,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean exactMatch,
+			ObjectVector methodsFound,
+			boolean proposeMethod) {
+		findFieldsAndMethodsFromStaticImports(
+				token,
+				scope,
+				invocationSite,
+				invocationScope,
+				exactMatch,
+				false,
+				new ObjectVector(),
+				new ObjectVector(),
+				methodsFound,
+				false,
+				proposeMethod);
+	}
+	protected void findMembers(
+			char[] token,
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			boolean isInsideAnnotationAttribute,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds,
+			boolean missingElementsHaveProblems) {
+
+		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			findMemberTypes(
+					token,
+					receiverType,
+					scope,
+					scope.enclosingSourceType(),
+					false,
+					true,
+					new ObjectVector(),
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems);
+		}
+		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+			findClassField(
+					token,
+					receiverType,
+					scope,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems);
+		}
+
+		MethodScope methodScope = null;
+		if (!isInsideAnnotationAttribute &&
+				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
+				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
+				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
+			if (token.length > 0) {
+				findKeywords(token, new char[][]{Keywords.THIS}, true, false);
+			} else {
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+				relevance += R_NON_INHERITED;
+
+				this.noProposal = false;
+				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+					proposal.setName(Keywords.THIS);
+					proposal.setCompletion(Keywords.THIS);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if (DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+
+		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+			findFields(
+				token,
+				receiverType,
+				scope,
+				new ObjectVector(),
+				new ObjectVector(),
+				true,
+				invocationSite,
+				scope,
+				false,
+				false,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				null,
+				-1,
+				-1);
+		}
+
+		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+			findMethods(
+				token,
+				null,
+				null,
+				receiverType,
+				scope,
+				new ObjectVector(),
+				true,
+				false,
+				invocationSite,
+				scope,
+				false,
+				false,
+				false,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems,
+				null,
+				-1,
+				-1);
+		}
+	}
+
+	private void findMembersFromMissingType(
+			final char[] token,
+			final long pos,
+			TypeBinding resolveType,
+			final Scope scope,
+			final InvocationSite invocationSite,
+			final boolean isInsideAnnotationAttribute) {
+		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+			new MissingTypesGuesser.GuessedTypeRequestor() {
+				public void accept(
+						TypeBinding guessedType,
+						Binding[] missingElements,
+						int[] missingElementsStarts,
+						int[] missingElementsEnds,
+						boolean hasProblems) {
+					if (guessedType instanceof ReferenceBinding) {
+						findMembers(
+								CompletionEngine.this.completionToken,
+								(ReferenceBinding)guessedType,
+								scope,
+								invocationSite,
+								isInsideAnnotationAttribute,
+								missingElements,
+								missingElementsStarts,
+								missingElementsEnds,
+								hasProblems);
+					}
+				}
+			};
+		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
+		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
+		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+	}
+
+	private void findMemberTypes(
+		char[] typeName,
+		ReferenceBinding receiverType,
+		Scope scope,
+		SourceTypeBinding typeInvocation,
+		boolean staticOnly,
+		boolean staticFieldsAndMethodOnly,
+		boolean fromStaticImport,
+		boolean checkQualification,
+		boolean proposeAllMemberTypes,
+		SourceTypeBinding typeToIgnore,
+		ObjectVector typesFound,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems) {
+
+		ReferenceBinding currentType = receiverType;
+		if (typeName == null)
+			return;
+
+		if (this.insideQualifiedReference
+			|| typeName.length == 0) { // do not search up the hierarchy
+
+			findMemberTypes(
+				typeName,
+				currentType.memberTypes(),
+				typesFound,
+				receiverType,
+				typeInvocation,
+				staticOnly,
+				staticFieldsAndMethodOnly,
+				fromStaticImport,
+				checkQualification,
+				scope,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems);
+			return;
+		}
+
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+
+		do {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+
+			findMemberTypes(
+				typeName,
+				currentType.memberTypes(),
+				typesFound,
+				receiverType,
+				typeInvocation,
+				staticOnly,
+				staticFieldsAndMethodOnly,
+				fromStaticImport,
+				checkQualification,
+				scope,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems);
+
+			currentType = currentType.superclass();
+		} while (currentType != null);
+
+		if(proposeAllMemberTypes) {
+			ReferenceBinding[] memberTypes = receiverType.memberTypes();
+			for (int i = 0; i < memberTypes.length; i++) {
+				if(memberTypes[i] != typeToIgnore) {
+					findSubMemberTypes(
+						typeName,
+						memberTypes[i],
+						scope,
+						typeInvocation,
+						staticOnly,
+						staticFieldsAndMethodOnly,
+						fromStaticImport,
+						typesFound);
+				}
+			}
+		}
+
+		if (interfacesToVisit != null) {
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				findMemberTypes(
+					typeName,
+					anInterface.memberTypes(),
+					typesFound,
+					receiverType,
+					typeInvocation,
+					staticOnly,
+					staticFieldsAndMethodOnly,
+					fromStaticImport,
+					checkQualification,
+					scope,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems);
+
+				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	protected void findMemberTypes(
+		char[] typeName,
+		ReferenceBinding receiverType,
+		Scope scope,
+		SourceTypeBinding typeInvocation,
+		boolean staticOnly,
+		boolean staticFieldsAndMethodOnly,
+		ObjectVector typesFound,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems)  {
+		findMemberTypes(
+				typeName,
+				receiverType,
+				scope,
+				typeInvocation,
+				staticOnly,
+				staticFieldsAndMethodOnly,
+				false,
+				false,
+				false,
+				null,
+				typesFound,
+				missingElements,
+				missingElementsStarts,
+				missingElementsEnds,
+				missingElementsHaveProblems);
+	}
+		// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
+	private void findMemberTypes(
+		char[] typeName,
+		ReferenceBinding[] memberTypes,
+		ObjectVector typesFound,
+		ReferenceBinding receiverType,
+		SourceTypeBinding invocationType,
+		boolean staticOnly,
+		boolean staticFieldsAndMethodOnly,
+		boolean fromStaticImport,
+		boolean checkQualification,
+		Scope scope,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems) {
+
+		// Inherited member types which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+		int typeLength = typeName.length;
+		next : for (int m = memberTypes.length; --m >= 0;) {
+			ReferenceBinding memberType = memberTypes[m];
+			//		if (!wantClasses && memberType.isClass()) continue next;
+			//		if (!wantInterfaces && memberType.isInterface()) continue next;
+
+			if (staticOnly && !memberType.isStatic()) continue next;
+
+			if (isForbidden(memberType)) continue next;
+
+			if (typeLength > memberType.sourceName.length)
+				continue next;
+
+			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
+					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
+				continue next;
+
+			if (this.options.checkDeprecation &&
+					memberType.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(memberType))
+				continue next;
+
+			if (this.options.checkVisibility) {
+				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
+					continue next;
+				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
+					continue next;
+				}
+			}
+
+			if (this.insideQualifiedReference &&
+					receiverType.isParameterizedType() &&
+					memberType.isStatic()) {
+				continue next;
+			}
+
+			for (int i = typesFound.size; --i >= 0;) {
+				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
+
+				if (memberType == otherType)
+					continue next;
+
+				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
+
+					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
+						continue next;
+
+					if (otherType.enclosingType().isInterface())
+						if (memberType.enclosingType()
+							.implementsInterface(otherType.enclosingType(), true))
+							continue next;
+
+					if (memberType.enclosingType().isInterface())
+						if (otherType.enclosingType()
+							.implementsInterface(memberType.enclosingType(), true))
+							continue next;
+				}
+			}
+
+			typesFound.add(memberType);
+
+			if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next;
+			if (this.assistNodeIsInterfaceExcludingAnnotation && memberType.isAnnotationType()) continue next;
+			if(!this.insideQualifiedReference) {
+				if(this.assistNodeIsClass || this.assistNodeIsException) {
+					if(!memberType.isClass()) continue next;
+				} else if(this.assistNodeIsInterface) {
+					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
+				} else if (this.assistNodeIsAnnotation) {
+					if(!memberType.isAnnotationType()) continue next;
+				}
+			}
+
+			char[] completionName = memberType.sourceName();
+
+			boolean isQualified = false;
+			if(checkQualification && !fromStaticImport) {
+				char[] memberPackageName = memberType.qualifiedPackageName();
+				char[] memberTypeName = memberType.sourceName();
+				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
+				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
+					if (memberPackageName == null || memberPackageName.length == 0)
+						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+							break next; // ignore types from the default package from outside it
+					isQualified = true;
+					completionName =
+						CharOperation.concat(
+								memberPackageName,
+								CharOperation.concat(
+										memberEnclosingTypeNames,
+										memberTypeName,
+										'.'),
+								'.');
+				}
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal(memberType);
+			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
+			relevance += computeRelevanceForExpectingType(memberType);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+			if(!this.insideQualifiedReference) {
+				relevance += computeRelevanceForQualification(isQualified);
+			}
+			if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; // This criterion doesn't concern types and is added to be balanced with field and method relevance.
+
+			if (memberType.isAnnotationType()) {
+				relevance += computeRelevanceForAnnotation();
+				relevance += computeRelevanceForAnnotationTarget(memberType);
+			} else if (memberType.isClass()) {
+				relevance += computeRelevanceForClass();
+				relevance += computeRelevanceForException(memberType.sourceName);
+			} else if(memberType.isEnum()) {
+				relevance += computeRelevanceForEnum();
+			} else if(memberType.isInterface()) {
+				relevance += computeRelevanceForInterface();
+			}
+
+			if (missingElements != null) {
+				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+			}
+
+			boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+			
+			this.noProposal = false;
+			if (!this.assistNodeIsConstructor ||
+					!allowingLongComputationProposals ||
+					hasStaticMemberTypes(memberType, invocationType, this.unitScope) ||
+					(memberType instanceof SourceTypeBinding && hasMemberTypesInEnclosingScope((SourceTypeBinding)memberType, scope)) ||
+					hasArrayTypeAsExpectedSuperTypes()) {
+				createTypeProposal(
+						memberType,
+						memberType.qualifiedSourceName(),
+						IAccessRule.K_ACCESSIBLE,
+						completionName,
+						relevance,
+						missingElements,
+						missingElementsStarts,
+						missingElementsEnds,
+						missingElementsHaveProblems);
+			}
+			
+			if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
+				findConstructorsOrAnonymousTypes(
+						memberType,
+						scope,
+						FakeInvocationSite,
+						isQualified,
+						relevance);
+			}
+		}
+	}
+	private void findMemberTypesFromMissingType(
+			char[] typeName,
+			final long pos,
+			final Scope scope)  {
+		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+			new MissingTypesGuesser.GuessedTypeRequestor() {
+				public void accept(
+						TypeBinding guessedType,
+						Binding[] missingElements,
+						int[] missingElementsStarts,
+						int[] missingElementsEnds,
+						boolean hasProblems) {
+					if (guessedType instanceof ReferenceBinding) {
+						findMemberTypes(
+								CompletionEngine.this.completionToken,
+								(ReferenceBinding)guessedType,
+								scope,
+								scope.enclosingSourceType(),
+								false,
+								false,
+								new ObjectVector(),
+								missingElements,
+								missingElementsStarts,
+								missingElementsEnds,
+								hasProblems);
+					}
+				}
+			};
+		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
+		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
+		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+	}
+	
+	private void findMemberTypesFromMissingType(
+			TypeReference typeRef,
+			final long pos,
+			final Scope scope)  {
+		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+			new MissingTypesGuesser.GuessedTypeRequestor() {
+				public void accept(
+						TypeBinding guessedType,
+						Binding[] missingElements,
+						int[] missingElementsStarts,
+						int[] missingElementsEnds,
+						boolean hasProblems) {
+					if (guessedType instanceof ReferenceBinding) {
+						findMemberTypes(
+								CompletionEngine.this.completionToken,
+								(ReferenceBinding)guessedType,
+								scope,
+								scope.enclosingSourceType(),
+								false,
+								false,
+								new ObjectVector(),
+								missingElements,
+								missingElementsStarts,
+								missingElementsEnds,
+								hasProblems);
+					}
+				}
+			};
+		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+	}
+
+	private void findMethodDeclarations(
+		char[] selector,
+		ReferenceBinding receiverType,
+		Scope scope,
+		ObjectVector methodsFound,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems) {
+
+		if (selector == null) {
+			return;
+		}
+
+		MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
+		if (receiverTypeMethods != null){
+			for (int i = 0; i < receiverTypeMethods.length; i++) {
+				if(!receiverTypeMethods[i].isDefaultAbstract()) {
+					methodsFound.add(receiverTypeMethods[i]);
+				}
+			}
+		}
+
+		ReferenceBinding currentType = receiverType;
+		
+		findInterfacesMethodDeclarations(
+			selector,
+			receiverType,
+			currentType.superInterfaces(),
+			scope,
+			methodsFound,
+			missingElements,
+			missingElementsStarts,
+			missingElementsEnds,
+			missingElementsHaveProblems);
+		
+		if (receiverType.isInterface()) {
+			currentType = scope.getJavaLangObject();
+		} else {
+			currentType = receiverType.superclass();
+		}
+		
+		boolean hasPotentialDefaultAbstractMethods = true;
+		while (currentType != null) {
+
+			MethodBinding[] methods = currentType.availableMethods();
+			if (methods != null) {
+				findLocalMethodDeclarations(
+					selector,
+					methods,
+					scope,
+					methodsFound,
+					false,
+					receiverType);
+			}
+
+			if (hasPotentialDefaultAbstractMethods &&
+					(currentType.isAbstract() ||
+							currentType.isTypeVariable() ||
+							currentType.isIntersectionType() ||
+							currentType.isEnum())){
+
+				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+
+				findInterfacesMethodDeclarations(
+					selector,
+					receiverType,
+					superInterfaces,
+					scope,
+					methodsFound,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems);
+			} else {
+				hasPotentialDefaultAbstractMethods = false;
+			}
+			currentType = currentType.superclass();
+		}
+	}
+	
+	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
+		TypeBinding erasure =  method.declaringClass.erasure();
+		if(!(erasure instanceof ReferenceBinding)) return null;
+
+		char[][] parameterNames = null;
+
+		int length = parameterTypeNames.length;
+
+		if (length == 0){
+			return CharOperation.NO_CHAR_CHAR;
+		}
+		// look into the corresponding unit if it is available
+		if (erasure instanceof SourceTypeBinding){
+			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
+
+			if (sourceType.scope != null){
+				TypeDeclaration parsedType;
+
+				if ((parsedType = sourceType.scope.referenceContext) != null){
+					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
+
+					if (methodDecl != null){
+						Argument[] arguments = methodDecl.arguments;
+						parameterNames = new char[length][];
+
+						for(int i = 0 ; i < length ; i++){
+							parameterNames[i] = arguments[i].name;
+						}
+					}
+				}
+			}
+		}
+		// look into the model
+		if(parameterNames == null){
+
+			ReferenceBinding bindingType = (ReferenceBinding)erasure;
+
+			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
+			Object type = this.typeCache.get(compoundName);
+
+			ISourceType sourceType = null;
+			if(type != null) {
+				if(type instanceof ISourceType) {
+					sourceType = (ISourceType) type;
+				}
+			} else {
+				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
+				if(answer != null && answer.isSourceType()) {
+					sourceType = answer.getSourceTypes()[0];
+					this.typeCache.put(compoundName, sourceType);
+				}
+			}
+
+			if(sourceType != null) {
+				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
+
+				String[] parameterTypeSignatures = new String[length];
+				for (int i = 0; i < length; i++) {
+					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
+				}
+				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
+				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
+
+				if(foundMethods != null) {
+					int len = foundMethods.length;
+					if(len == 1) {
+						try {
+							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
+							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
+						} catch (JavaModelException e) {
+							// method doesn't exist: ignore
+						}
+					}
+				}
+			}
+		}
+		return parameterNames;
+	}
+
+	private void findMethods(
+		char[] selector,
+		TypeBinding[] typeArgTypes,
+		TypeBinding[] argTypes,
+		ReferenceBinding receiverType,
+		Scope scope,
+		ObjectVector methodsFound,
+		boolean onlyStaticMethods,
+		boolean exactMatch,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean implicitCall,
+		boolean superCall,
+		boolean canBePrefixed,
+		Binding[] missingElements,
+		int[] missingElementsStarts,
+		int[] missingElementsEnds,
+		boolean missingElementsHaveProblems,
+		char[] castedReceiver,
+		int receiverStart,
+		int receiverEnd) {
+
+		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
+		if (selector == null && notInJavadoc) {
+			return;
+		}
+		
+		if (this.assistNodeIsInsideCase)
+			return;		// no methods should be proposed inside case expression
+
+		ReferenceBinding currentType = receiverType;
+		if (notInJavadoc) {
+			if (receiverType.isInterface()) {
+				findInterfacesMethods(
+					selector,
+					typeArgTypes,
+					argTypes,
+					receiverType,
+					new ReferenceBinding[]{currentType},
+					scope,
+					methodsFound,
+					onlyStaticMethods,
+					exactMatch,
+					invocationSite,
+					invocationScope,
+					implicitCall,
+					superCall,
+					canBePrefixed,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems,
+					castedReceiver,
+					receiverStart,
+					receiverEnd);
+
+				currentType = scope.getJavaLangObject();
+			}
+		}
+		boolean hasPotentialDefaultAbstractMethods = true;
+		boolean java8Plus = this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8;
+		while (currentType != null) {
+
+			MethodBinding[] methods = currentType.availableMethods();
+			if (methods != null) {
+				findLocalMethods(
+					selector,
+					typeArgTypes,
+					argTypes,
+					methods,
+					scope,
+					methodsFound,
+					onlyStaticMethods,
+					exactMatch,
+					receiverType,
+					invocationSite,
+					invocationScope,
+					implicitCall,
+					superCall,
+					canBePrefixed,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems,
+					castedReceiver,
+					receiverStart,
+					receiverEnd);
+			}
+
+			/* Searching of superinterfaces for candidate proposal methods can be skipped if current type is concrete, but only for source levels below 1.8.
+			   For 1.8 even a concrete type's superinterfaces should be searched as they could have default methods which are not implemented by the concrete
+			   type.
+			*/
+			if (hasPotentialDefaultAbstractMethods &&
+					(java8Plus || (currentType.isAbstract() || currentType.isTypeVariable() || currentType.isIntersectionType() || currentType.isEnum()))) {
+
+				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+				if (superInterfaces != null && currentType.isIntersectionType()) {
+					for (int i = 0; i < superInterfaces.length; i++) {
+						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
+					}
+				}
+
+				findInterfacesMethods(
+					selector,
+					typeArgTypes,
+					argTypes,
+					receiverType,
+					superInterfaces,
+					scope,
+					methodsFound,
+					onlyStaticMethods,
+					exactMatch,
+					invocationSite,
+					invocationScope,
+					implicitCall,
+					superCall,
+					canBePrefixed,
+					missingElements,
+					missingElementsStarts,
+					missingElementsEnds,
+					missingElementsHaveProblems,
+					castedReceiver,
+					receiverStart,
+					receiverEnd);
+			} else {
+				if (!java8Plus)
+					hasPotentialDefaultAbstractMethods = false;
+			}
+			currentType = currentType.superclass();
+		}
+	}
+
+	private void findNestedTypes(
+		char[] typeName,
+		SourceTypeBinding currentType,
+		Scope scope,
+		boolean proposeAllMemberTypes,
+		ObjectVector typesFound) {
+		
+		if (typeName == null)
+			return;
+
+		int typeLength = typeName.length;
+
+		SourceTypeBinding nextTypeToIgnore = null;
+		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (scope.kind) {
+
+				case Scope.METHOD_SCOPE :
+				case Scope.BLOCK_SCOPE :
+					BlockScope blockScope = (BlockScope) scope;
+
+					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
+
+						if (blockScope.subscopes[i] instanceof ClassScope) {
+							SourceTypeBinding localType =
+								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
+
+							if (!localType.isAnonymousType()) {
+								if (isForbidden(localType))
+									continue next;
+
+								if (typeLength > localType.sourceName.length)
+									continue next;
+								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
+										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
+									continue next;
+
+								for (int j = typesFound.size; --j >= 0;) {
+									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+
+									if (localType == otherType)
+										continue next;
+								}
+
+								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) {
+									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
+								} else if (this.assistNodeIsAnnotation) {
+									if(!localType.isAnnotationType()) continue next;
+								}
+
+								int relevance = computeBaseRelevance();
+								relevance += computeRelevanceForResolution();
+								relevance += computeRelevanceForInterestingProposal(localType);
+								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
+								relevance += computeRelevanceForExpectingType(localType);
+								relevance += computeRelevanceForException(localType.sourceName);
+								relevance += computeRelevanceForClass();
+								relevance += computeRelevanceForQualification(false);
+								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
+								relevance += computeRelevanceForAnnotationTarget(localType);
+
+								boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+								if (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasArrayTypeAsExpectedSuperTypes()) {
+									this.noProposal = false;
+									if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+										createTypeProposal(
+												localType,
+												localType.sourceName,
+												IAccessRule.K_ACCESSIBLE,
+												localType.sourceName,
+												relevance,
+												null,
+												null,
+												null,
+												false);
+									}
+								}
+								
+								if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
+									findConstructorsOrAnonymousTypes(
+											localType,
+											blockScope,
+											FakeInvocationSite,
+											false,
+											relevance);
+								}
+							}
+						}
+					}
+					break;
+
+				case Scope.CLASS_SCOPE :
+					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
+					findMemberTypes(
+							typeName,
+							enclosingSourceType,
+							scope,
+							currentType,
+							false,
+							false,
+							false,
+							false,
+							proposeAllMemberTypes,
+							nextTypeToIgnore,
+							typesFound,
+							null,
+							null,
+							null,
+							false);
+					nextTypeToIgnore = enclosingSourceType;
+					if (typeLength == 0)
+						return; // do not search outside the class scope if no prefix was provided
+					break;
+
+				case Scope.COMPILATION_UNIT_SCOPE :
+					return;
+			}
+			scope = scope.parent;
+		}
+	}
+
+	private void findPackages(CompletionOnPackageReference packageStatement) {
+
+		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
+		if (this.completionToken.length == 0)
+			return;
+
+		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
+		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
+		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
+	}
+
+	private void findParameterizedType(TypeReference ref, Scope scope) {
+		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
+		if(refBinding != null) {
+			if (this.options.checkDeprecation &&
+					refBinding.isViewedAsDeprecated() &&
+					!scope.isDefinedInSameUnit(refBinding))
+				return;
+
+			int accessibility = IAccessRule.K_ACCESSIBLE;
+			if(refBinding.hasRestrictedAccess()) {
+				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
+				if(accessRestriction != null) {
+					switch (accessRestriction.getProblemId()) {
+						case IProblem.ForbiddenReference:
+							if (this.options.checkForbiddenReference) {
+								return;
+							}
+							accessibility = IAccessRule.K_NON_ACCESSIBLE;
+							break;
+						case IProblem.DiscouragedReference:
+							if (this.options.checkDiscouragedReference) {
+								return;
+							}
+							accessibility = IAccessRule.K_DISCOURAGED;
+							break;
+					}
+				}
+			}
+
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
+			relevance += computeRelevanceForExpectingType(refBinding);
+			relevance += computeRelevanceForQualification(false);
+			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
+
+			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+				createTypeProposal(
+						refBinding,
+						refBinding.qualifiedSourceName(),
+						IAccessRule.K_ACCESSIBLE,
+						CharOperation.NO_CHAR,
+						relevance,
+						null,
+						null,
+						null,
+						false);
+			}
+		}
+	}
+
+	private void findSubMemberTypes(
+		char[] typeName,
+		ReferenceBinding receiverType,
+		Scope scope,
+		SourceTypeBinding typeInvocation,
+		boolean staticOnly,
+		boolean staticFieldsAndMethodOnly,
+		boolean fromStaticImport,
+		ObjectVector typesFound) {
+
+		ReferenceBinding currentType = receiverType;
+		if (typeName == null)
+			return;
+
+		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
+
+		findMemberTypes(
+				typeName,
+				currentType.memberTypes(),
+				typesFound,
+				receiverType,
+				typeInvocation,
+				staticOnly,
+				staticFieldsAndMethodOnly,
+				fromStaticImport,
+				true,
+				scope,
+				null,
+				null,
+				null,
+				false);
+
+		ReferenceBinding[] memberTypes = receiverType.memberTypes();
+		next : for (int i = 0; i < memberTypes.length; i++) {
+			if (this.options.checkVisibility) {
+				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
+					continue next;
+				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
+					continue next;
+				}
+			}
+			findSubMemberTypes(
+				typeName,
+				memberTypes[i],
+				scope,
+				typeInvocation,
+				staticOnly,
+				staticFieldsAndMethodOnly,
+				fromStaticImport,
+				typesFound);
+		}
+	}
+
+	private void findTrueOrFalseKeywords(char[][] choices) {
+		if(choices == null || choices.length == 0) return;
+
+		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
+
+		for (int i = 0; i < choices.length; i++) {
+			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
+					CharOperation.equals(choices[i], Keywords.FALSE)
+			){
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
+				relevance += computeRelevanceForQualification(false);
+				relevance += R_TRUE_OR_FALSE;
+
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+					proposal.setName(choices[i]);
+					proposal.setCompletion(choices[i]);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
+
+	private void findTypeParameters(char[] token, Scope scope) {
+		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
+
+		TypeParameter[] typeParameters = null;
+		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+			typeParameters = null;
+			switch (scope.kind) {
+				case Scope.METHOD_SCOPE :
+					MethodScope methodScope = (MethodScope) scope;
+					if(methodScope.referenceContext instanceof MethodDeclaration) {
+						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
+						typeParameters = methodDeclaration.typeParameters;
+					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
+						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
+						typeParameters = methodDeclaration.typeParameters;
+					}
+					break;
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) scope;
+					typeParameters = classScope.referenceContext.typeParameters;
+					break;
+				case Scope.COMPILATION_UNIT_SCOPE :
+					return;
+			}
+			if(typeParameters != null) {
+				for (int i = 0; i < typeParameters.length; i++) {
+					int typeLength = token.length;
+					TypeParameter typeParameter = typeParameters[i];
+
+					if(typeParameter.binding == null) continue;
+
+					if (typeLength > typeParameter.name.length) continue;
+
+					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
+							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
+
+					int relevance = computeBaseRelevance();
+					relevance += computeRelevanceForResolution();
+					relevance += computeRelevanceForInterestingProposal();
+					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
+					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
+					relevance += computeRelevanceForQualification(false);
+					relevance += computeRelevanceForException(typeParameter.name);
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
+
+					this.noProposal = false;
+					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+						createTypeParameterProposal(typeParameter, relevance);
+					}
+				}
+			}
+			scope = scope.parent;
+		}
+	}
+
+	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
+
+		if (token == null)
+			return;
+		
+		boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+		
+		boolean proposeType =
+			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
+
+		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
+		
+		boolean proposeConstructor =
+			allowingLongComputationProposals &&
+			this.assistNodeIsConstructor &&
+			(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
+					!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));
+		
+
+		if ((proposeType || proposeConstructor) && scope.enclosingSourceType() != null) {
+			
+			checkCancel();
+			
+			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
+			if(!this.assistNodeIsInterface &&
+					!this.assistNodeIsConstructor &&
+					!this.assistNodeIsAnnotation &&
+					this.assistNodeInJavadoc == 0) {
+				
+				checkCancel();
+				
+				// don't propose type parameters if the completion is a constructor ('new |')
+				findTypeParameters(token, scope);
+			}
+		}
+
+		boolean isEmptyPrefix = token.length == 0;
+
+		if ((proposeType || proposeConstructor) && this.unitScope != null) {
+			
+			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
+			if(outerInvocationType != null) {
+				ReferenceBinding temp = outerInvocationType.enclosingType();
+				while(temp != null) {
+					outerInvocationType = temp;
+					temp = temp.enclosingType();
+				}
+			}
+
+			int typeLength = token.length;
+			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
+
+			next : for (int i = 0, length = types.length; i < length; i++) {
+				
+				checkCancel();
+				
+				SourceTypeBinding sourceType = types[i];
+
+				if(isForbidden(sourceType)) continue next;
+
+				if(proposeAllMemberTypes &&
+					sourceType != outerInvocationType) {
+					findSubMemberTypes(
+							token,
+							sourceType,
+							scope,
+							scope.enclosingSourceType(),
+							false,
+							false,
+							false,
+							typesFound);
+				}
+
+				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
+				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
+
+				if (typeLength > sourceType.sourceName.length) continue next;
+
+				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
+						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue next;
+
+				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
+					continue next;
+				}
+
+				for (int j = typesFound.size; --j >= 0;) {
+					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+
+					if (sourceType == otherType) continue next;
+				}
+				
+				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) {
+					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
+				} else if (this.assistNodeIsAnnotation) {
+					if(!sourceType.isAnnotationType()) continue next;
+				} else if (this.assistNodeIsException) {
+					 if (!sourceType.isClass()) continue next;
+					 if (isEmptyPrefix) {
+						 if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
+							 continue next;
+					     }
+					  }
+				}
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal(sourceType);
+				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
+				relevance += computeRelevanceForExpectingType(sourceType);
+				relevance += computeRelevanceForQualification(false);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
+
+				if (sourceType.isAnnotationType()) {
+					relevance += computeRelevanceForAnnotation();
+					relevance += computeRelevanceForAnnotationTarget(sourceType);
+				} else if (sourceType.isInterface()) {
+					relevance += computeRelevanceForInterface();
+				} else if(sourceType.isClass()){
+					relevance += computeRelevanceForClass();
+					relevance += computeRelevanceForException(sourceType.sourceName);
+				}
+				
+				
+				this.noProposal = false;
+				if(proposeType &&
+						(!this.assistNodeIsConstructor ||
+								!allowingLongComputationProposals ||
+								hasStaticMemberTypes(sourceType, null, this.unitScope) ||
+								hasMemberTypesInEnclosingScope(sourceType, scope)) ||
+								hasArrayTypeAsExpectedSuperTypes()) {
+					char[] typeName = sourceType.sourceName();
+					createTypeProposal(
+							sourceType,
+							typeName,
+							IAccessRule.K_ACCESSIBLE,
+							typeName,
+							relevance,
+							null,
+							null,
+							null,
+							false);
+				}
+				
+				if (proposeConstructor) {
+					findConstructorsOrAnonymousTypes(
+							sourceType,
+							scope,
+							FakeInvocationSite,
+							false,
+							relevance);
+				}
+			}
+		}
+
+		if (proposeConstructor && !isEmptyPrefix) {
+			
+			checkCancel();
+			
+			findTypesFromImports(token, scope, proposeType, typesFound);
+		} else if(proposeType) {
+			
+			checkCancel();
+			
+			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
+		}
+		
+		if (proposeConstructor) {
+			
+			checkCancel();
+			
+			findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
+		}
+
+		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
+			if (!proposeConstructor) {
+				findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
+			}
+		} else {
+			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
+					if (proposeBaseTypes) {
+						if (proposeVoidType) {
+							findKeywords(token, BASE_TYPE_NAMES, false, false);
+						} else {
+							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
+						}
+					}
+				}
+			}
+			
+			if (proposeConstructor) {
+				int l = typesFound.size();
+				for (int i = 0; i < l; i++) {
+					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
+					char[] fullyQualifiedTypeName =
+						CharOperation.concat(
+								typeFound.qualifiedPackageName(),
+								typeFound.qualifiedSourceName(),
+								'.');
+					this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+				}
+				
+				checkCancel();
+				
+				this.foundConstructorsCount = 0;
+				this.nameEnvironment.findConstructorDeclarations(
+						token,
+						this.options.camelCaseMatch,
+						this,
+						this.monitor);
+				acceptConstructors(scope);
+			} else if (proposeType) {
+				int l = typesFound.size();
+				for (int i = 0; i < l; i++) {
+					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
+					char[] fullyQualifiedTypeName =
+						CharOperation.concat(
+								typeFound.qualifiedPackageName(),
+								typeFound.qualifiedSourceName(),
+								'.');
+					this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+				}
+				int searchFor = IJavaSearchConstants.TYPE;
+				if(this.assistNodeIsClass || this.assistNodeIsException) {
+					searchFor = IJavaSearchConstants.CLASS;
+				} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
+					searchFor = IJavaSearchConstants.INTERFACE;
+				} else if(this.assistNodeIsInterface) {
+					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
+				} else if(this.assistNodeIsEnum) {
+					searchFor = IJavaSearchConstants.ENUM;
+				} else if(this.assistNodeIsAnnotation) {
+					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
+				}
+				
+				checkCancel();
+				
+				this.foundTypesCount = 0;
+				this.nameEnvironment.findTypes(
+						token,
+						proposeAllMemberTypes,
+						this.options.camelCaseMatch,
+						searchFor,
+						this,
+						this.monitor);
+				acceptTypes(scope);
+			}
+			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+				
+				checkCancel();
+				
+				this.nameEnvironment.findPackages(token, this);
+			}
+		}
+	}
+
+	private void findTypesAndSubpackages(
+		char[] token,
+		PackageBinding packageBinding,
+		Scope scope) {
+		
+		boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+
+		boolean proposeType =
+			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
+		
+		boolean proposeConstructor =
+			allowingLongComputationProposals &&
+			this.assistNodeIsConstructor &&
+			(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
+					!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));
+
+		char[] qualifiedName =
+			CharOperation.concatWith(packageBinding.compoundName, token, '.');
+
+		if (token == null || token.length == 0) {
+			int length = qualifiedName.length;
+			System.arraycopy(
+				qualifiedName,
+				0,
+				qualifiedName = new char[length + 1],
+				0,
+				length);
+			qualifiedName[length] = '.';
+		}
+
+		this.qualifiedCompletionToken = qualifiedName;
+
+		if ((proposeType || proposeConstructor) && this.unitScope != null) {
+			int typeLength = qualifiedName.length;
+			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
+
+			for (int i = 0, length = types.length; i < length; i++) {
+				
+				checkCancel();
+				
+				SourceTypeBinding sourceType = types[i];
+				
+				if (isForbidden(sourceType)) continue;
+				if (this.assistNodeIsClass && sourceType.isInterface()) continue;
+				if (this.assistNodeIsInterface && sourceType.isClass()) continue;
+
+				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
+
+				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
+				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
+				if (typeLength > qualifiedSourceTypeName.length) continue;
+				if (!(packageBinding == sourceType.getPackage())) continue;
+
+				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
+						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
+
+				if (this.options.checkDeprecation &&
+						sourceType.isViewedAsDeprecated() &&
+						!scope.isDefinedInSameUnit(sourceType))
+					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);
+					if(accessRestriction != null) {
+						switch (accessRestriction.getProblemId()) {
+							case IProblem.ForbiddenReference:
+								if (this.options.checkForbiddenReference) {
+									continue;
+								}
+								accessibility = IAccessRule.K_NON_ACCESSIBLE;
+								break;
+							case IProblem.DiscouragedReference:
+								if (this.options.checkDiscouragedReference) {
+									continue;
+								}
+								accessibility = IAccessRule.K_DISCOURAGED;
+								break;
+						}
+					}
+				}
+
+				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForResolution();
+				relevance += computeRelevanceForInterestingProposal(sourceType);
+				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
+				relevance += computeRelevanceForExpectingType(sourceType);
+				relevance += computeRelevanceForQualification(false);
+				relevance += computeRelevanceForRestrictions(accessibility);
+
+				if (sourceType.isAnnotationType()) {
+					relevance += computeRelevanceForAnnotation();
+				} else if (sourceType.isInterface()) {
+					relevance += computeRelevanceForInterface();
+				} else if (sourceType.isClass()) {
+					relevance += computeRelevanceForClass();
+					relevance += computeRelevanceForException(sourceType.sourceName);
+				}
+				
+				this.noProposal = false;
+				if(proposeType &&
+						(!this.assistNodeIsConstructor ||
+								!allowingLongComputationProposals ||
+								hasStaticMemberTypes(sourceType, null, this.unitScope) ||
+								hasMemberTypesInEnclosingScope(sourceType, scope)) ||
+								hasArrayTypeAsExpectedSuperTypes()) {
+					char[] typeName = sourceType.sourceName();
+					createTypeProposal(
+							sourceType,
+							typeName,
+							IAccessRule.K_ACCESSIBLE,
+							typeName,
+							relevance,
+							null,
+							null,
+							null,
+							false);
+				}
+				
+				if (proposeConstructor) {
+					findConstructorsOrAnonymousTypes(
+							sourceType,
+							scope,
+							FakeInvocationSite,
+							false,
+							relevance);
+				}
+			}
+		}
+
+		if (proposeConstructor) {
+
+			
+			checkCancel();
+			
+			this.foundConstructorsCount = 0;
+			this.nameEnvironment.findConstructorDeclarations(
+					qualifiedName,
+					this.options.camelCaseMatch,
+					this,
+					this.monitor);
+			acceptConstructors(scope);
+		} if(proposeType) {
+			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) {
+				searchFor = IJavaSearchConstants.ENUM;
+			} else if(this.assistNodeIsAnnotation) {
+				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
+			}
+			
+			checkCancel();
+			
+			this.foundTypesCount = 0;
+			this.nameEnvironment.findTypes(
+					qualifiedName,
+					false,
+					this.options.camelCaseMatch,
+					searchFor,
+					this,
+					this.monitor);
+			acceptTypes(scope);
+		}
+		
+		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+			this.nameEnvironment.findPackages(qualifiedName, this);
+		}
+	}
+	
+	private void findTypesFromExpectedTypes(char[] token, Scope scope, ObjectVector typesFound, boolean proposeType, boolean proposeConstructor) {
+		if(this.expectedTypesPtr > -1) {
+			boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
+			
+			int typeLength = token == null ? 0 : token.length;
+			
+			next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+				
+				checkCancel();
+				
+				if(this.expectedTypes[i] instanceof ReferenceBinding) {
+					ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
+					
+					if (typeLength > 0) {
+						if (typeLength > refBinding.sourceName.length) continue next;
+	
+						if (!CharOperation.prefixEquals(token, refBinding.sourceName, false)
+								&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, refBinding.sourceName))) continue next;
+					}
+
+
+					if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
+						// don't propose type variable if the completion is a constructor ('new |')
+						continue next;
+					}
+					if (this.options.checkDeprecation &&
+							refBinding.isViewedAsDeprecated() &&
+							!scope.isDefinedInSameUnit(refBinding))
+						continue next;
+
+					int accessibility = IAccessRule.K_ACCESSIBLE;
+					if(refBinding.hasRestrictedAccess()) {
+						AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
+						if(accessRestriction != null) {
+							switch (accessRestriction.getProblemId()) {
+								case IProblem.ForbiddenReference:
+									if (this.options.checkForbiddenReference) {
+										continue next;
+									}
+									accessibility = IAccessRule.K_NON_ACCESSIBLE;
+									break;
+								case IProblem.DiscouragedReference:
+									if (this.options.checkDiscouragedReference) {
+										continue next;
+									}
+									accessibility = IAccessRule.K_DISCOURAGED;
+									break;
+							}
+						}
+					}
+					if(isForbidden(refBinding)) continue next;
+
+					for (int j = 0; j < typesFound.size(); j++) {
+						ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
+						if (typeFound == refBinding.erasure()) {
+							continue next;
+						}
+					}
+					
+					typesFound.add(refBinding);
+
+					boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
+
+					// top level types of the current unit are already proposed.
+					if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) {
+						char[] packageName = refBinding.qualifiedPackageName();
+						char[] typeName = refBinding.sourceName();
+						char[] completionName = typeName;
+
+						boolean isQualified = false;
+						if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
+							if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
+								if (packageName == null || packageName.length == 0)
+									if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+										continue next; // ignore types from the default package from outside it
+								completionName = CharOperation.concat(packageName, typeName, '.');
+								isQualified = true;
+							}
+						}
+
+						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) {
+							if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
+						} else if (this.assistNodeIsAnnotation) {
+							if(!refBinding.isAnnotationType()) continue next;
+						}
+
+						int relevance = computeBaseRelevance();
+						relevance += computeRelevanceForResolution();
+						relevance += computeRelevanceForInterestingProposal(refBinding);
+						relevance += computeRelevanceForCaseMatching(token, typeName);
+						relevance += computeRelevanceForExpectingType(refBinding);
+						relevance += computeRelevanceForQualification(isQualified);
+						relevance += computeRelevanceForRestrictions(accessibility);
+
+						if(refBinding.isClass()) {
+							relevance += computeRelevanceForClass();
+							relevance += computeRelevanceForException(typeName);
+						} else if(refBinding.isEnum()) {
+							relevance += computeRelevanceForEnum();
+						} else if(refBinding.isInterface()) {
+							relevance += computeRelevanceForInterface();
+						}
+						
+						if (proposeType &&
+								(!this.assistNodeIsConstructor ||
+										!allowingLongComputationProposals ||
+										hasStaticMemberTypes(refBinding, scope.enclosingSourceType() ,this.unitScope)) ||
+										hasArrayTypeAsExpectedSuperTypes()) {
+							this.noProposal = false;
+							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(packageName);
+								proposal.setSignature(getSignature(refBinding));
+								proposal.setPackageName(packageName);
+								proposal.setTypeName(typeName);
+								proposal.setCompletion(completionName);
+								proposal.setFlags(refBinding.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								proposal.setAccessibility(accessibility);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						}
+						
+						if (proposeConstructor) {
+							findConstructorsOrAnonymousTypes(
+									refBinding,
+									scope,
+									FakeInvocationSite,
+									isQualified,
+									relevance);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void findTypesFromImports(char[] token, Scope scope, boolean proposeType, ObjectVector typesFound) {
+		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+		next : for (int i = 0; i < importBindings.length; i++) {
+			ImportBinding importBinding = importBindings[i];
+			if(importBinding.isValidBinding()) {
+				Binding binding = importBinding.resolvedImport;
+				if(binding != null && binding.isValidBinding()) {
+					if(importBinding.onDemand) {
+						if (importBinding.isStatic()) {
+							if((binding.kind() & Binding.TYPE) != 0) {
+								this.findMemberTypes(
+										token,
+										(ReferenceBinding) binding,
+										scope,
+										scope.enclosingSourceType(),
+										true,
+										false,
+										true,
+										true,
+										false,
+										null,
+										typesFound,
+										null,
+										null,
+										null,
+										false);
+							}
+						}
+					} else {
+						if ((binding.kind() & Binding.TYPE) != 0) {
+							ReferenceBinding typeBinding = (ReferenceBinding) binding;
+							int typeLength = token.length;
+
+							if (!typeBinding.isStatic()) continue next;
+
+							if (typeLength > typeBinding.sourceName.length)	continue next;
+
+							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
+									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue next;
+							
+							int accessibility = IAccessRule.K_ACCESSIBLE;
+							if(typeBinding.hasRestrictedAccess()) {
+								AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(typeBinding);
+								if(accessRestriction != null) {
+									switch (accessRestriction.getProblemId()) {
+										case IProblem.ForbiddenReference:
+											if (this.options.checkForbiddenReference) {
+												continue next;
+											}
+											accessibility = IAccessRule.K_NON_ACCESSIBLE;
+											break;
+										case IProblem.DiscouragedReference:
+											if (this.options.checkDiscouragedReference) {
+												continue next;
+											}
+											accessibility = IAccessRule.K_DISCOURAGED;
+											break;
+									}
+								}
+							}
+							
+							if (typesFound.contains(typeBinding)) continue next;
+							
+							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) {
+								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
+							} else if (this.assistNodeIsAnnotation) {
+								if(!typeBinding.isAnnotationType()) continue;
+							}
+							
+							int relevance = computeBaseRelevance();
+							relevance += computeRelevanceForResolution();
+							relevance += computeRelevanceForInterestingProposal(typeBinding);
+							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
+							relevance += computeRelevanceForExpectingType(typeBinding);
+							relevance += computeRelevanceForQualification(false);
+							relevance += computeRelevanceForRestrictions(accessibility);
+			
+							if (typeBinding.isAnnotationType()) {
+								relevance += computeRelevanceForAnnotation();
+								relevance += computeRelevanceForAnnotationTarget(typeBinding);
+							} else if (typeBinding.isInterface()) {
+								relevance += computeRelevanceForInterface();
+							} else if(typeBinding.isClass()){
+								relevance += computeRelevanceForClass();
+								relevance += computeRelevanceForException(typeBinding.sourceName);
+							}
+							
+							if (proposeType && 
+									(hasStaticMemberTypes(typeBinding, scope.enclosingSourceType(), this.unitScope) || hasArrayTypeAsExpectedSuperTypes())) {
+								this.noProposal = false;
+								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+									InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+									proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
+									proposal.setSignature(getSignature(typeBinding));
+									proposal.setPackageName(typeBinding.qualifiedPackageName());
+									proposal.setTypeName(typeBinding.qualifiedSourceName());
+									proposal.setCompletion(typeBinding.sourceName());
+									proposal.setFlags(typeBinding.modifiers);
+									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+									proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+									proposal.setRelevance(relevance);
+									this.requestor.accept(proposal);
+									if(DEBUG) {
+										this.printDebug(proposal);
+									}
+								}
+							}
+							
+							findConstructorsOrAnonymousTypes(
+									typeBinding,
+									scope,
+									FakeInvocationSite,
+									false,
+									relevance);
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
+		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+		for (int i = 0; i < importBindings.length; i++) {
+			ImportBinding importBinding = importBindings[i];
+			if(importBinding.isValidBinding() && importBinding.isStatic()) {
+				Binding binding = importBinding.resolvedImport;
+				if(binding != null && binding.isValidBinding()) {
+					if(importBinding.onDemand) {
+						if((binding.kind() & Binding.TYPE) != 0) {
+							this.findMemberTypes(
+									token,
+									(ReferenceBinding) binding,
+									scope,
+									scope.enclosingSourceType(),
+									true,
+									false,
+									true,
+									true,
+									proposeAllMemberTypes,
+									null,
+									typesFound,
+									null,
+									null,
+									null,
+									false);
+						}
+					} else {
+						if ((binding.kind() & Binding.TYPE) != 0) {
+							ReferenceBinding typeBinding = (ReferenceBinding) binding;
+							int typeLength = token.length;
+
+							if (!typeBinding.isStatic()) continue;
+
+							if (typeLength > typeBinding.sourceName.length)	continue;
+
+							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
+									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
+
+							if (typesFound.contains(typeBinding))  continue;
+
+							typesFound.add(typeBinding);
+
+							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
+							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
+							if(this.assistNodeIsClass || this.assistNodeIsException) {
+								if(!typeBinding.isClass()) continue;
+							} else if(this.assistNodeIsInterface) {
+								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
+							} else if (this.assistNodeIsAnnotation) {
+								if(!typeBinding.isAnnotationType()) continue;
+							}
+
+							int relevance = computeBaseRelevance();
+							relevance += computeRelevanceForResolution();
+							relevance += computeRelevanceForInterestingProposal(typeBinding);
+							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
+							relevance += computeRelevanceForExpectingType(typeBinding);
+							relevance += computeRelevanceForQualification(false);
+							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+							if (typeBinding.isClass()) {
+								relevance += computeRelevanceForClass();
+								relevance += computeRelevanceForException(typeBinding.sourceName);
+							} else if(typeBinding.isEnum()) {
+								relevance += computeRelevanceForEnum();
+							} else if(typeBinding.isInterface()) {
+								relevance += computeRelevanceForInterface();
+							}
+
+							this.noProposal = false;
+							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
+								proposal.setSignature(getSignature(typeBinding));
+								proposal.setPackageName(typeBinding.qualifiedPackageName());
+								proposal.setTypeName(typeBinding.qualifiedSourceName());
+								proposal.setCompletion(typeBinding.sourceName());
+								proposal.setFlags(typeBinding.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
+		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
+		if (foundNames != null && foundNames.length > 1) {
+			int discouragedNamesLength = discouragedNames.length;
+			int foundNamesLength = foundNames.length;
+			int newLength = discouragedNamesLength + foundNamesLength;
+			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
+			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
+		}
+		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
+	}
+
+	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
+		final ArrayList proposedNames = new ArrayList();
+
+		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+				public void acceptName(char[] name) {
+					CompletionEngine.this.acceptUnresolvedName(name);
+					proposedNames.add(name);
+				}
+			};
+
+		ReferenceContext referenceContext = scope.referenceContext();
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+			nameFinder.findAfter(
+					this.completionToken,
+					md.scope,
+					md.scope.classScope(),
+					from,
+					md.bodyEnd,
+					discouragedNames,
+					nameRequestor);
+		} else if (referenceContext instanceof TypeDeclaration) {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+			FieldDeclaration[] fields = typeDeclaration.fields;
+			if (fields != null) {
+				done : for (int i = 0; i < fields.length; i++) {
+					if (fields[i] instanceof Initializer) {
+						Initializer initializer = (Initializer) fields[i];
+						if (initializer.block.sourceStart <= from &&
+								from < initializer.bodyEnd) {
+							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+							nameFinder.findAfter(
+										this.completionToken,
+										typeDeclaration.scope,
+										typeDeclaration.scope,
+										from,
+										initializer.bodyEnd,
+										discouragedNames,
+										nameRequestor);
+							break done;
+						}
+					}
+				}
+			}
+		}
+
+		int proposedNamesCount = proposedNames.size();
+		if (proposedNamesCount > 0) {
+			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+		}
+
+		return null;
+	}
+
+	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
+		final ArrayList proposedNames = new ArrayList();
+
+		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+				public void acceptName(char[] name) {
+					CompletionEngine.this.acceptUnresolvedName(name);
+					proposedNames.add(name);
+				}
+			};
+
+		BlockScope upperScope = scope;
+		while (upperScope.enclosingMethodScope() != null) {
+			upperScope = upperScope.enclosingMethodScope();
+		}
+
+		ReferenceContext referenceContext = upperScope.referenceContext();
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+			nameFinder.findBefore(
+					this.completionToken,
+					md.scope,
+					md.scope.classScope(),
+					md.bodyStart,
+					recordTo,
+					parseTo,
+					discouragedNames,
+					nameRequestor);
+		} else if (referenceContext instanceof TypeDeclaration) {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+
+
+			done : {
+				FieldDeclaration[] fields = typeDeclaration.fields;
+				if (fields != null) {
+					for (int i = 0; i < fields.length; i++) {
+						if (fields[i] instanceof Initializer) {
+							Initializer initializer = (Initializer) fields[i];
+							if (initializer.block.sourceStart <= recordTo &&
+									recordTo < initializer.bodyEnd) {
+
+								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+								nameFinder.findBefore(
+										this.completionToken,
+										typeDeclaration.scope,
+										typeDeclaration.scope,
+										initializer.block.sourceStart,
+										recordTo,
+										parseTo,
+										discouragedNames,
+										nameRequestor);
+								break done;
+							}
+						}
+					}
+				}
+			}
+		}
+
+		int proposedNamesCount = proposedNames.size();
+		if (proposedNamesCount > 0) {
+			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+		}
+
+		return null;
+	}
+
+	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
+		final TypeReference type = variable.type;
+		if(type != null &&
+				type.resolvedType != null &&
+				type.resolvedType.problemId() == ProblemReasons.NoError){
+
+			final ArrayList proposedNames = new ArrayList();
+
+			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+					public void acceptName(char[] name) {
+						int relevance = computeBaseRelevance();
+						relevance += computeRelevanceForInterestingProposal();
+						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
+						relevance += R_NAME_FIRST_PREFIX;
+						relevance += R_NAME_FIRST_SUFFIX;
+						relevance += R_NAME_LESS_NEW_CHARACTERS;
+						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
+
+						// accept result
+						CompletionEngine.this.noProposal = false;
+						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
+							proposal.setSignature(getSignature(type.resolvedType));
+							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
+							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
+							proposal.setName(name);
+							proposal.setCompletion(name);
+							//proposal.setFlags(Flags.AccDefault);
+							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
+							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
+							proposal.setRelevance(relevance);
+							CompletionEngine.this.requestor.accept(proposal);
+							if(DEBUG) {
+								CompletionEngine.this.printDebug(proposal);
+							}
+						}
+						proposedNames.add(name);
+					}
+				};
+
+			ReferenceContext referenceContext = scope.referenceContext();
+			if (referenceContext instanceof AbstractMethodDeclaration) {
+				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+				nameFinder.find(
+						this.completionToken,
+						md,
+						variable.declarationSourceEnd + 1,
+						discouragedNames,
+						nameRequestor);
+			} else if (referenceContext instanceof TypeDeclaration) {
+				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+				FieldDeclaration[] fields = typeDeclaration.fields;
+				if (fields != null) {
+					done : for (int i = 0; i < fields.length; i++) {
+						if (fields[i] instanceof Initializer) {
+							Initializer initializer = (Initializer) fields[i];
+							if (initializer.bodyStart <= variable.sourceStart &&
+									variable.sourceStart < initializer.bodyEnd) {
+								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+								nameFinder.find(
+										this.completionToken,
+										initializer,
+										typeDeclaration.scope,
+										variable.declarationSourceEnd + 1,
+										discouragedNames,
+										nameRequestor);
+								break done;
+							}
+						}
+					}
+				}
+			}
+
+			int proposedNamesCount = proposedNames.size();
+			if (proposedNamesCount > 0) {
+				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+			}
+		}
+
+		return null;
+	}
+
+	private void findVariableName(
+			char[] token,
+			char[] qualifiedPackageName,
+			char[] qualifiedSourceName,
+			char[] sourceName,
+			final TypeBinding typeBinding,
+			char[][] discouragedNames,
+			final char[][] forbiddenNames,
+			boolean forCollection,
+			int dim,
+			int kind){
+
+		if(sourceName == null || sourceName.length == 0)
+			return;
+
+		// compute variable name for non base type
+		final char[] displayName;
+		if (!forCollection) {
+			if (dim > 0){
+				int l = qualifiedSourceName.length;
+				displayName = new char[l+(2*dim)];
+				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
+				for(int i = 0; i < dim; i++){
+					displayName[l+(i*2)] = '[';
+					displayName[l+(i*2)+1] = ']';
+				}
+			} else {
+				displayName = qualifiedSourceName;
+			}
+		} else {
+			displayName = typeBinding.qualifiedSourceName();
+		}
+
+		final char[] t = token;
+		final char[] q = qualifiedPackageName;
+		INamingRequestor namingRequestor = new INamingRequestor() {
+			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
+				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
+				for (int i = 0; i < l; i++) {
+					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
+				}
+
+				if (CharOperation.prefixEquals(t, name, false)) {
+					int relevance = computeBaseRelevance();
+					relevance += computeRelevanceForInterestingProposal();
+					relevance += computeRelevanceForCaseMatching(t, name);
+					relevance += prefixAndSuffixRelevance;
+					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
+
+					// accept result
+					CompletionEngine.this.noProposal = false;
+					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
+						proposal.setSignature(getSignature(typeBinding));
+						proposal.setPackageName(q);
+						proposal.setTypeName(displayName);
+						proposal.setName(name);
+						proposal.setCompletion(name);
+						//proposal.setFlags(Flags.AccDefault);
+						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
+						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
+						proposal.setRelevance(relevance);
+						CompletionEngine.this.requestor.accept(proposal);
+						if(DEBUG) {
+							CompletionEngine.this.printDebug(proposal);
+						}
+					}
+				}
+			}
+
+			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
+				accept(name, 0, reusedCharacters);
+			}
+
+			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
+				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
+			}
+
+			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
+				accept(
+						name,
+						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
+						reusedCharacters);
+			}
+			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
+				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
+			}
+		};
+
+		InternalNamingConventions.suggestVariableNames(
+				kind,
+				InternalNamingConventions.BK_SIMPLE_TYPE_NAME,
+				qualifiedSourceName,
+				this.javaProject,
+				dim,
+				token,
+				discouragedNames,
+				true,
+				namingRequestor);
+	}
+
+	// Helper method for private void findVariableNames(char[] name, TypeReference type )
+	private void findVariableName(
+			char[] token,
+			char[] qualifiedPackageName,
+			char[] qualifiedSourceName,
+			char[] sourceName,
+			final TypeBinding typeBinding,
+			char[][] discouragedNames,
+			final char[][] forbiddenNames,
+			int dim,
+			int kind){
+		findVariableName(
+				token,
+				qualifiedPackageName,
+				qualifiedSourceName,
+				sourceName,
+				typeBinding,
+				discouragedNames,
+				forbiddenNames,
+				false,
+				dim,
+				kind);
+	}
+	private void findVariableNameForCollection(
+			char[] token,
+			char[] qualifiedPackageName,
+			char[] qualifiedSourceName,
+			char[] sourceName,
+			final TypeBinding typeBinding,
+			char[][] discouragedNames,
+			final char[][] forbiddenNames,
+			int kind){
+
+		findVariableName(
+				token,
+				qualifiedPackageName,
+				qualifiedSourceName,
+				sourceName,
+				typeBinding,
+				discouragedNames,
+				forbiddenNames,
+				false,
+				1,
+				kind);
+	}
+	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind){
+		if(type != null &&
+			type.resolvedType != null) {
+			TypeBinding tb = type.resolvedType;
+
+			if (tb.problemId() == ProblemReasons.NoError &&
+					tb != Scope.getBaseType(VOID)) {
+				findVariableName(
+					name,
+					tb.leafComponentType().qualifiedPackageName(),
+					tb.leafComponentType().qualifiedSourceName(),
+					tb.leafComponentType().sourceName(),
+					tb,
+					discouragedNames,
+					forbiddenNames,
+					type.dimensions(),
+					kind);
+				
+				if (tb.isParameterizedType() &&
+						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
+					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
+					TypeBinding[] arguments = ptb.arguments;
+					if (arguments != null && arguments.length == 1) {
+						TypeBinding argument = arguments[0];
+						findVariableNameForCollection(
+							name,
+							argument.leafComponentType().qualifiedPackageName(),
+							argument.leafComponentType().qualifiedSourceName(),
+							argument.leafComponentType().sourceName(),
+							tb,
+							discouragedNames,
+							forbiddenNames,
+							kind);
+					}
+				}
+			}
+		}
+
+	}
+	private void findVariablesAndMethods(
+		char[] token,
+		Scope scope,
+		InvocationSite invocationSite,
+		Scope invocationScope,
+		boolean insideTypeAnnotation,
+		boolean insideAnnotationAttribute) {
+
+		if (token == null)
+			return;
+
+		// Should local variables hide fields from the receiver type or any of its enclosing types?
+		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
+
+		boolean staticsOnly = false;
+		// need to know if we're in a static context (or inside a constructor)
+		int tokenLength = token.length;
+
+		ObjectVector localsFound = new ObjectVector();
+		ObjectVector fieldsFound = new ObjectVector();
+		ObjectVector methodsFound = new ObjectVector();
+
+		Scope currentScope = scope;
+
+		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+				switch (currentScope.kind) {
+
+					case Scope.METHOD_SCOPE :
+						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+						MethodScope methodScope = (MethodScope) currentScope;
+						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+
+					//$FALL-THROUGH$
+					case Scope.BLOCK_SCOPE :
+						BlockScope blockScope = (BlockScope) currentScope;
+
+						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+							LocalVariableBinding local = blockScope.locals[i];
+
+							if (local == null)
+								break next;
+
+							if (tokenLength > local.name.length)
+								continue next;
+
+							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
+									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
+								continue next;
+
+							if (local.isSecret())
+								continue next;
+							
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328674
+							if (local.declaration.initialization != null) {
+								// proposal being asked inside field's initialization. Don't propose this field.
+								continue next;
+							}
+												
+							// don't propose non constant variables or strings (1.6 or below) in case expression
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342
+							if (this.assistNodeIsInsideCase) {
+								if (local.isFinal()) {
+									if (this.assistNodeIsString){
+										if (local.type == null || local.type.id != TypeIds.T_JavaLangString)
+											continue next;
+									} else if (!(local.type instanceof BaseTypeBinding))
+										continue next; 
+								} else {
+									continue next; // non-constants not allowed in case.	
+								}
+							}
+							
+							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 =
+									(LocalVariableBinding) localsFound.elementAt(f);
+								if (CharOperation.equals(otherLocal.name, local.name, true))
+									continue next;
+							}
+							localsFound.add(local);
+
+							int relevance = computeBaseRelevance();
+							relevance += computeRelevanceForResolution();
+							relevance += computeRelevanceForInterestingProposal(local);
+							relevance += computeRelevanceForCaseMatching(token, local.name);
+							relevance += computeRelevanceForExpectingType(local.type);
+							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);
+								proposal.setSignature(
+									local.type == null
+									? createTypeSignature(
+											CharOperation.NO_CHAR,
+											local.declaration.type.toString().toCharArray())
+									: getSignature(local.type));
+								if(local.type == null) {
+									//proposal.setPackageName(null);
+									proposal.setTypeName(local.declaration.type.toString().toCharArray());
+								} else {
+									proposal.setPackageName(local.type.qualifiedPackageName());
+									proposal.setTypeName(local.type.qualifiedSourceName());
+								}
+								proposal.setName(local.name);
+								proposal.setCompletion(local.name);
+								proposal.setFlags(local.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+								proposal.setRelevance(relevance);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
+							}
+						}
+						break;
+
+					case Scope.COMPILATION_UNIT_SCOPE :
+						break done1;
+				}
+				currentScope = currentScope.parent;
+			}
+		}
+		
+		checkCancel();
+
+		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+
+		staticsOnly = false;
+		currentScope = scope;
+
+		if(proposeField || proposeMethod) {
+			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+				switch (currentScope.kind) {
+					case Scope.METHOD_SCOPE :
+						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+						MethodScope methodScope = (MethodScope) currentScope;
+						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+						break;
+					case Scope.CLASS_SCOPE :
+						ClassScope classScope = (ClassScope) currentScope;
+						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
+											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
+											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
+											break done;
+										} else { */
+						if(!insideTypeAnnotation) {
+							if(proposeField) {
+								findFields(
+									token,
+									enclosingType,
+									classScope,
+									fieldsFound,
+									localsFound,
+									staticsOnly,
+									invocationSite,
+									invocationScope,
+									true,
+									true,
+									null,
+									null,
+									null,
+									false,
+									null,
+									-1,
+									-1);
+							}
+							if(proposeMethod && !insideAnnotationAttribute) {
+								findMethods(
+									token,
+									null,
+									null,
+									enclosingType,
+									classScope,
+									methodsFound,
+									staticsOnly,
+									false,
+									invocationSite,
+									invocationScope,
+									true,
+									false,
+									true,
+									null,
+									null,
+									null,
+									false,
+									null,
+									-1,
+									-1);
+							}
+						}
+						staticsOnly |= enclosingType.isStatic();
+						insideTypeAnnotation = false;
+						//				}
+						break;
+
+					case Scope.COMPILATION_UNIT_SCOPE :
+						break done2;
+				}
+				currentScope = currentScope.parent;
+			}
+			
+			checkCancel();
+			
+			findFieldsAndMethodsFromStaticImports(
+					token,
+					scope,
+					invocationSite,
+					invocationScope,
+					false,
+					insideAnnotationAttribute,
+					localsFound,
+					fieldsFound,
+					methodsFound,
+					proposeField,
+					proposeMethod);
+
+			if (this.assistNodeInJavadoc == 0) {
+				
+				checkCancel();
+				
+				// search in favorites import
+				findFieldsAndMethodsFromFavorites(
+						token,
+						scope,
+						invocationSite,
+						invocationScope,
+						localsFound,
+						fieldsFound,
+						methodsFound);
+			}
+			
+			checkCancel();
+			
+			findEnumConstantsFromExpectedTypes(
+					token,
+					invocationScope,
+					fieldsFound);
+		}
+	}
+
+	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
+		char[] result = null;
+		StringBuffer sig = new StringBuffer(10);
+		if (!referenceBinding.isMemberType()) {
+			char[] typeSig = referenceBinding.genericTypeSignature();
+			sig.append(typeSig, 0, typeSig.length);
+		} else if (!this.insideQualifiedReference) {
+			if (referenceBinding.isStatic()) {
+				char[] typeSig = referenceBinding.signature();
+				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+
+				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+				    sig.append(Signature.C_GENERIC_START);
+				    for (int i = 0, length = typeVariables.length; i < length; i++) {
+				        sig.append(typeVariables[i].genericTypeSignature());
+				    }
+				    sig.append(Signature.C_GENERIC_END);
+				}
+				sig.append(Signature.C_SEMICOLON);
+			} else {
+				char[] typeSig = referenceBinding.genericTypeSignature();
+				sig.append(typeSig, 0, typeSig.length);
+			}
+		} else {
+			ReferenceBinding enclosingType = referenceBinding.enclosingType();
+			if (enclosingType.isParameterizedType()) {
+				char[] typeSig = referenceBinding.genericTypeSignature();
+				sig.append(typeSig, 0, typeSig.length-1);
+
+				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+				    sig.append(Signature.C_GENERIC_START);
+				    for (int i = 0, length = typeVariables.length; i < length; i++) {
+				        sig.append(typeVariables[i].genericTypeSignature());
+				    }
+				    sig.append(Signature.C_GENERIC_END);
+				}
+			} else {
+				char[] typeSig = referenceBinding.signature();
+				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+
+				if (referenceBinding.isStatic()) {
+					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+					    sig.append(Signature.C_GENERIC_START);
+					    for (int i = 0, length = typeVariables.length; i < length; i++) {
+					        sig.append(typeVariables[i].genericTypeSignature());
+					    }
+					    sig.append(Signature.C_GENERIC_END);
+					}
+				}
+			}
+			sig.append(Signature.C_SEMICOLON);
+		}
+		int sigLength = sig.length();
+		result = new char[sigLength];
+		sig.getChars(0, sigLength, result, 0);
+		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
+		return result;
+	}
+
+	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
+		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
+
+		String[] favoriteReferences = this.requestor.getFavoriteReferences();
+
+		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
+
+		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
+
+		int count = 0;
+		next : for (int i = 0; i < favoriteReferences.length; i++) {
+			String favoriteReference = favoriteReferences[i];
+
+			int length;
+			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
+
+			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
+
+			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
+			if (onDemand) {
+				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
+			}
+
+			// remove duplicate and conflicting
+			for (int j = 0; j < count; j++) {
+				ImportReference f = resolvedImports[j].reference;
+
+				if (CharOperation.equals(f.tokens, compoundName)) continue next;
+
+				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
+					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
+						continue next;
+				}
+			}
+
+			boolean isStatic = true;
+
+			ImportReference importReference =
+				new ImportReference(
+						compoundName,
+						new long[compoundName.length],
+						onDemand,
+						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
+
+			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
+
+			if (!importBinding.isValidBinding()) {
+				continue next;
+			}
+
+			if (importBinding instanceof PackageBinding) {
+				continue next;
+			}
+
+			resolvedImports[count++] =
+				new ImportBinding(compoundName, onDemand, importBinding, importReference);
+		}
+
+		if (resolvedImports.length > count)
+			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
+
+		return this.favoriteReferenceBindings = resolvedImports;
+	}
+	
+	private INameEnvironment getNoCacheNameEnvironment() {
+		if (this.noCacheNameEnvironment == null) {
+			JavaModelManager.getJavaModelManager().cacheZipFiles(this);
+			this.noCacheNameEnvironment = new JavaSearchNameEnvironment(this.javaProject, this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
+		}
+		return this.noCacheNameEnvironment;
+	}
+
+	public AssistParser getParser() {
+
+		return this.parser;
+	}
+	protected boolean hasArrayTypeAsExpectedSuperTypes() {
+		if ((this.expectedTypesFilter & ~SUBTYPE) != 0) return false;
+		
+		if (!this.hasComputedExpectedArrayTypes) {
+			if(this.expectedTypes != null) {
+				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+					if(this.expectedTypes[i].isArrayType()) {
+						this.hasExpectedArrayTypes = true;
+						break done;
+					}
+				}
+			}
+			
+			this.hasComputedExpectedArrayTypes = true;
+		}
+		
+		return this.hasExpectedArrayTypes;
+	}
+	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
+		if (this.targetedElement == TagBits.AnnotationForPackage) {
+			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
+				return false;
+			}
+		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
+			if (scope.parent != null &&
+					scope.parent.parent != null &&
+					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
+					scope.parent.parent instanceof CompilationUnitScope) {
+				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
+					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
+						return false;
+					}
+				} else {
+					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
+						return false;
+					}
+				}
+			}
+		}
+		return true;
+	}
+	/**
+	 * Returns completion string inserted inside a specified inline tag.
+	 * @param completionName
+	 * @return char[] Completion text inclunding specified inline tag
+	 */
+	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
+		int tagLength= inlineTag.length;
+		int completionLength = completionName.length;
+		int inlineLength = 2+tagLength+1+completionLength+1;
+		char[] inlineCompletion = new char[inlineLength];
+		inlineCompletion[0] = '{';
+		inlineCompletion[1] = '@';
+		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
+		inlineCompletion[tagLength+2] = ' ';
+		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
+		// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
+		//inlineCompletion[inlineLength-2] = ' ';
+		inlineCompletion[inlineLength-1] = '}';
+		return inlineCompletion;
+	}
+	private boolean isAllowingLongComputationProposals() {
+		return this.monitor != null;
+	}
+	private boolean isForbidden(Binding binding) {
+		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
+			if(this.forbbidenBindings[i] == binding) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean isForbiddenType(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) {
+		// CharOperation.concatWith() handles the cases where input args are null/empty
+		char[] fullTypeName = CharOperation.concatWith(enclosingTypeNames, givenTypeName, '.');
+		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
+			if (this.forbbidenBindings[i] instanceof TypeBinding) {
+				TypeBinding typeBinding = (TypeBinding) this.forbbidenBindings[i];
+				char[] currPkgName = typeBinding.qualifiedPackageName();
+				if (CharOperation.equals(givenPkgName, currPkgName))	{
+					char[] currTypeName = typeBinding.qualifiedSourceName();
+					if (CharOperation.equals(fullTypeName, currTypeName)) {
+						return true;
+					}
+				}
+			}
+		}
+		
+		// filter packages ending with enum for projects above 1.5 
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264
+		if (this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5 &&
+				CharOperation.endsWith(givenPkgName, DOT_ENUM)) { //note: it should be .enum and not just enum
+				return true;
+		}
+		
+		return false;
+	}
+
+	private boolean isIgnored(int kind) {
+		return this.requestor.isIgnored(kind);
+	}
+	boolean isIgnored(int kind, boolean missingTypes) {
+		return this.requestor.isIgnored(kind) ||
+			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
+	}
+
+	private boolean isIgnored(int kind, int requiredProposalKind) {
+		return this.requestor.isIgnored(kind) ||
+			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
+	}
+	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
+
+		if(parent instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
+			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
+			int nodeIndex = -1;
+			for(int i = length - 1 ; i > -1 ; i--) {
+				if(node == ref.typeArguments[i]) {
+					nodeIndex = i;
+					break;
+				}
+			}
+			if(nodeIndex > -1 && (typeVariables == null || typeVariables.length < nodeIndex + 1)) {
+				TypeBinding[] typeBindings = new TypeBinding[nodeIndex + 1];
+				for(int i = 0; i < nodeIndex; i++) {
+					typeBindings[i] = ref.typeArguments[i].resolvedType;
+				}
+				typeBindings[nodeIndex] = scope.getJavaLangObject();
+				if(typeVariables == null || typeVariables.length == 0) {
+					scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings);
+				} else {
+					scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
+				}
+				return false;
+			}
+		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
+			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+			TypeReference[][] arguments = ref.typeArguments;
+			int iLength = arguments == null ? 0 : arguments.length;
+			for (int i = 0; i < iLength; i++) {
+				int jLength = arguments[i] == null ? 0 : arguments[i].length;
+				for (int j = 0; j < jLength; j++) {
+					if(arguments[i][j] == node && (typeVariables == null || typeVariables.length <= j)) {
+						TypeBinding[] typeBindings = new TypeBinding[j + 1];
+						for(int k = 0; k < j; k++) {
+							typeBindings[k] = ref.typeArguments[i][k].resolvedType;
+						}
+						typeBindings[j] = scope.getJavaLangObject();
+						if(typeVariables == null || typeVariables.length == 0) {
+							scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings);
+						} else {
+							scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
+						}
+						return false;
+					}
+				}
+			}
+		}
+		return true;
+	}
+	private boolean mustQualifyType(ReferenceBinding type, char[] packageName, Scope scope) {
+		if(!mustQualifyType(
+				packageName,
+				type.sourceName(),
+				type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null,
+				type.modifiers)) {
+			return false;
+		}
+		ReferenceBinding enclosingType = scope.enclosingSourceType();
+		while (enclosingType != null) {
+			ReferenceBinding currentType = enclosingType;
+			while (currentType != null) {
+				ReferenceBinding[] memberTypes = currentType.memberTypes();
+				if(memberTypes != null) {
+					for (int i = 0; i < memberTypes.length; i++) {
+						if (CharOperation.equals(memberTypes[i].sourceName, type.sourceName()) &&
+								memberTypes[i].canBeSeenBy(scope)) {
+							return memberTypes[i] != type;
+						}
+					}
+				}
+				currentType = currentType.superclass();
+			}
+			enclosingType = enclosingType.enclosingType();
+		}
+		return true;
+	}
+	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
+		StringBuffer prefix = new StringBuffer();
+		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
+		if(isStatic) {
+			prefix.append("static "); //$NON-NLS-1$
+		}
+		prefix.append("{\n"); //$NON-NLS-1$
+		for (int i = 0; i < localVariableTypeNames.length; i++) {
+			ASTNode.printModifiers(localVariableModifiers[i], prefix);
+			prefix.append(' ');
+			prefix.append(localVariableTypeNames[i]);
+			prefix.append(' ');
+			prefix.append(localVariableNames[i]);
+			prefix.append(';');
+		}
+
+		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
+		this.offset = prefix.length();
+
+		String encoding = this.compilerOptions.defaultEncoding;
+		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
+			fakeSource,
+			null,
+			"FakeType.java", //$NON-NLS-1$
+			encoding);
+
+		this.actualCompletionPosition = prefix.length() + position - 1;
+
+		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
+
+		parseBlockStatements(fakeAST, this.actualCompletionPosition);
+
+		return (Initializer)fakeAST.types[0].fields[0];
+	}
+	protected void printDebug(CategorizedProblem error) {
+		if(CompletionEngine.DEBUG) {
+			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
+			System.out.print(error);
+			System.out.println(")"); //$NON-NLS-1$
+		}
+	}
+	protected void printDebug(CompletionProposal proposal){
+		StringBuffer buffer = new StringBuffer();
+		printDebug(proposal, 0, buffer);
+		System.out.println(buffer.toString());
+	}
+
+	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
+		printDebugTab(tab, buffer);
+		buffer.append("COMPLETION - "); //$NON-NLS-1$
+		switch(proposal.getKind()) {
+			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION :
+				buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_REF :
+				buffer.append("FIELD_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER :
+				buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.KEYWORD :
+				buffer.append("KEYWORD"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.LABEL_REF :
+				buffer.append("LABEL_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.LOCAL_VARIABLE_REF :
+				buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_DECLARATION :
+				buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_REF :
+				buffer.append("METHOD_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER :
+				buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.PACKAGE_REF :
+				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.TYPE_REF :
+				buffer.append("TYPE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.VARIABLE_DECLARATION :
+				buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.POTENTIAL_METHOD_DECLARATION :
+				buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_NAME_REFERENCE :
+				buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF :
+				buffer.append("ANNOTATION_ATTRIBUT_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_IMPORT :
+				buffer.append("FIELD_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_IMPORT :
+				buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.TYPE_IMPORT :
+				buffer.append("TYPE_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.CONSTRUCTOR_INVOCATION :
+				buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
+				buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+				break;
+			default :
+				buffer.append("PROPOSAL"); //$NON-NLS-1$
+				break;
+
+		}
+
+		buffer.append("{\n");//$NON-NLS-1$
+		printDebugTab(tab, buffer);
+		buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		printDebugTab(tab, buffer);
+		buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		printDebugTab(tab, buffer);
+		buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		printDebugTab(tab, buffer);
+		buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		printDebugTab(tab, buffer);
+		buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		printDebugTab(tab, buffer);
+		buffer.append("\tName[").append(proposal.getName() == null ? "null".toCharArray() : proposal.getName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+		printDebugTab(tab, buffer);
+		buffer.append("\tFlags[");//$NON-NLS-1$
+		int flags = proposal.getFlags();
+		buffer.append(Flags.toString(flags));
+		if((flags & Flags.AccInterface) != 0) buffer.append("interface ");//$NON-NLS-1$
+		if((flags & Flags.AccEnum) != 0) buffer.append("enum ");//$NON-NLS-1$
+		buffer.append("]\n"); //$NON-NLS-1$
+
+		CompletionProposal[] proposals = proposal.getRequiredProposals();
+		if(proposals != null) {
+			printDebugTab(tab, buffer);
+			buffer.append("\tRequiredProposals[");//$NON-NLS-1$
+			for (int i = 0; i < proposals.length; i++) {
+				buffer.append("\n"); //$NON-NLS-1$
+				printDebug(proposals[i], tab + 2, buffer);
+			}
+			printDebugTab(tab, buffer);
+			buffer.append("\n\t]\n"); //$NON-NLS-1$
+		}
+
+		printDebugTab(tab, buffer);
+		buffer.append("\tCompletionLocation[").append(proposal.getCompletionLocation()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		int start = proposal.getReplaceStart();
+		int end = proposal.getReplaceEnd();
+		printDebugTab(tab, buffer);
+		buffer.append("\tReplaceStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append("-ReplaceEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		start = proposal.getTokenStart();
+		end = proposal.getTokenEnd();
+		printDebugTab(tab, buffer);
+		buffer.append("\tTokenStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append("-TokenEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		if (this.source != null) {
+			printDebugTab(tab, buffer);
+			buffer.append("\tReplacedText[").append(this.source, start, end-start).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		printDebugTab(tab, buffer);
+		buffer.append("\tTokenStart[").append(proposal.getTokenStart()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append("-TokenEnd[").append(proposal.getTokenEnd()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		printDebugTab(tab, buffer);
+		buffer.append("\tRelevance[").append(proposal.getRelevance()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
+
+		printDebugTab(tab, buffer);
+		buffer.append("}\n");//$NON-NLS-1$
+	}
+
+	private void printDebugTab(int tab, StringBuffer buffer) {
+		for (int i = 0; i < tab; i++) {
+			buffer.append('\t');
+		}
+	}
+	
+	private void proposeConstructor(AcceptedConstructor deferredProposal, Scope scope) {
+		if (deferredProposal.proposeConstructor) {
+			proposeConstructor(
+					deferredProposal.simpleTypeName,
+					deferredProposal.parameterCount,
+					deferredProposal.signature,
+					deferredProposal.parameterTypes,
+					deferredProposal.parameterNames,
+					deferredProposal.modifiers,
+					deferredProposal.packageName,
+					deferredProposal.typeModifiers,
+					deferredProposal.accessibility,
+					deferredProposal.simpleTypeName,
+					deferredProposal.fullyQualifiedName,
+					deferredProposal.mustBeQualified,
+					scope,
+					deferredProposal.extraFlags);
+		}
+	}
+	
+	private void proposeConstructor(
+			char[] simpleTypeName,
+			int parameterCount,
+			char[] signature,
+			char[][] parameterTypes,
+			char[][] parameterNames,
+			int modifiers,
+			char[] packageName,
+			int typeModifiers,
+			int accessibility,
+			char[] typeName,
+			char[] fullyQualifiedName,
+			boolean isQualified,
+			Scope scope,
+			int extraFlags) {
+		char[] typeCompletion = fullyQualifiedName;
+		if(isQualified) {
+			if (packageName == null || packageName.length == 0)
+				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+					return; // ignore types from the default package from outside it
+		} else {
+			typeCompletion = simpleTypeName;
+		}
+
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForRestrictions(accessibility);
+		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
+		relevance += computeRelevanceForQualification(isQualified);
+		relevance += computeRelevanceForConstructor();
+
+		boolean isInterface = false;
+		int kind = typeModifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
+		switch (kind) {
+			case ClassFileConstants.AccAnnotation:
+			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
+				relevance += computeRelevanceForAnnotation();
+				relevance += computeRelevanceForInterface();
+				isInterface = true;
+				break;
+			case ClassFileConstants.AccEnum:
+				relevance += computeRelevanceForEnum();
+				break;
+			case ClassFileConstants.AccInterface:
+				relevance += computeRelevanceForInterface();
+				isInterface = true;
+				break;
+			default:
+				relevance += computeRelevanceForClass();
+				relevance += computeRelevanceForException(simpleTypeName);
+				break;
+		}
+		
+		char[] completion;
+		if (this.source != null
+					&& this.source.length > this.endPosition
+					&& this.source[this.endPosition] == '(') {
+			completion = CharOperation.NO_CHAR;
+		} else {
+			completion = new char[] { '(', ')' };
+		}
+		
+		InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+		typeProposal.nameLookup = this.nameEnvironment.nameLookup;
+		typeProposal.completionEngine = this;
+		typeProposal.setDeclarationSignature(packageName);
+		typeProposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+		typeProposal.setPackageName(packageName);
+		typeProposal.setTypeName(typeName);
+		typeProposal.setCompletion(typeCompletion);
+		typeProposal.setFlags(typeModifiers);
+		typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+		typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
+		typeProposal.setRelevance(relevance);
+		
+		switch (parameterCount) {
+			case -1: // default constructor
+				int flags = Flags.AccPublic;
+				if (Flags.isDeprecated(typeModifiers)) {
+					flags |= Flags.AccDeprecated;
+				}
+				
+				if (isInterface || (typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(flags);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(flags);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+				break;
+			case 0: // constructor with no parameter
+				
+				if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(modifiers);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(modifiers);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+				break;
+			default: // constructor with parameter
+				if (signature == null) {
+					// resolve type to found parameter types
+					signature = getResolvedSignature(parameterTypes, fullyQualifiedName, parameterCount, scope);
+					if (signature == null) return;
+				} else {
+					signature = CharOperation.replaceOnCopy(signature, '/', '.');
+				}
+				
+				int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length;
+				if (parameterCount != parameterNamesLength) {
+					parameterNames = null;
+				}
+				
+				if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
+						proposal.setSignature(signature);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						if (parameterNames != null) {
+							proposal.setParameterNames(parameterNames);
+						} else {
+							proposal.setHasNoParameterNamesFromIndex(true);
+						}
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(modifiers);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				} else {
+					this.noProposal = false;
+					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
+						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
+						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
+						proposal.setSignature(signature);
+						proposal.setDeclarationPackageName(packageName);
+						proposal.setDeclarationTypeName(typeName);
+						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
+						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
+						if (parameterNames != null) {
+							proposal.setParameterNames(parameterNames);
+						} else {
+							proposal.setHasNoParameterNamesFromIndex(true);
+						}
+						proposal.setName(simpleTypeName);
+						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
+						proposal.setIsContructor(true);
+						proposal.setCompletion(completion);
+						proposal.setFlags(modifiers);
+						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+						proposal.setRelevance(relevance);
+						
+						this.requestor.accept(proposal);
+						if(DEBUG) {
+							this.printDebug(proposal);
+						}
+					}
+				}
+				break;
+		}
+	}
+
+	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
+		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForResolution();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
+
+			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
+			proposal.setDeclarationSignature(getSignature(reference));
+			proposal.setSignature(
+					createMethodSignature(
+							CharOperation.NO_CHAR_CHAR,
+							CharOperation.NO_CHAR_CHAR,
+							CharOperation.NO_CHAR,
+							VOID));
+			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
+			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
+
+			//proposal.setPackageName(null);
+			proposal.setTypeName(VOID);
+			proposal.setName(token);
+			//proposal.setParameterPackageNames(null);
+			//proposal.setParameterTypeNames(null);
+			//proposal.setPackageName(null);
+			proposal.setCompletion(token);
+			proposal.setFlags(Flags.AccPublic);
+			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+			proposal.setRelevance(relevance);
+			this.requestor.accept(proposal);
+			if(DEBUG) {
+				this.printDebug(proposal);
+			}
+		}
+	}
+
+	private void proposeType(
+			char[] packageName,
+			char[] simpleTypeName,
+			int modifiers,
+			int accessibility,
+			char[] typeName,
+			char[] fullyQualifiedName,
+			boolean isQualified,
+			Scope scope) {
+		char[] completionName = fullyQualifiedName;
+		if(isQualified) {
+			if (packageName == null || packageName.length == 0)
+				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+					return; // ignore types from the default package from outside it
+		} else {
+			completionName = simpleTypeName;
+		}
+
+		TypeBinding guessedType = null;
+		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
+				this.assistNodeIsAnnotation &&
+				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
+			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
+
+			TypeReference ref;
+			if (cn.length == 1) {
+				ref = new SingleTypeReference(simpleTypeName, 0);
+			} else {
+				ref = new QualifiedTypeReference(cn,new long[cn.length]);
+			}
+
+			switch (scope.kind) {
+				case Scope.METHOD_SCOPE :
+				case Scope.BLOCK_SCOPE :
+					guessedType = ref.resolveType((BlockScope)scope);
+					break;
+				case Scope.CLASS_SCOPE :
+					guessedType = ref.resolveType((ClassScope)scope);
+					break;
+			}
+
+			if (guessedType == null || !guessedType.isValidBinding()) return;
+
+			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
+		}
+
+		int relevance = computeBaseRelevance();
+		relevance += computeRelevanceForResolution();
+		relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName);
+		relevance += computeRelevanceForRestrictions(accessibility);
+		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
+		relevance += computeRelevanceForQualification(isQualified);
+
+		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
+		switch (kind) {
+			case ClassFileConstants.AccAnnotation:
+			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
+				relevance += computeRelevanceForAnnotation();
+				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
+				relevance += computeRelevanceForInterface();
+				break;
+			case ClassFileConstants.AccEnum:
+				relevance += computeRelevanceForEnum();
+				break;
+			case ClassFileConstants.AccInterface:
+				relevance += computeRelevanceForInterface();
+				break;
+			default:
+				relevance += computeRelevanceForClass();
+				relevance += computeRelevanceForException(simpleTypeName);
+				break;
+		}
+
+		this.noProposal = false;
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
+		}
+	}
+
+	protected void reset() {
+
+		super.reset(false);
+		this.knownPkgs = new HashtableOfObject(10);
+		this.knownTypes = new HashtableOfObject(10);
+		if (this.noCacheNameEnvironment != null) {
+			this.noCacheNameEnvironment.cleanup();
+			this.noCacheNameEnvironment = null;
+			JavaModelManager.getJavaModelManager().flushZipFiles(this);
+		}
+	}
+
+	private void setSourceAndTokenRange(int start, int end) {
+		this.setSourceAndTokenRange(start, end, true);
+	}
+
+	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
+		this.setSourceRange(start, end, emptyTokenAdjstment);
+		this.setTokenRange(start, end, emptyTokenAdjstment);
+	}
+
+	private void setSourceRange(int start, int end) {
+		this.setSourceRange(start, end, true);
+	}
+
+	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
+		this.startPosition = start;
+		if(emptyTokenAdjstment) {
+			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
+			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
+		} else {
+			this.endPosition = end + 1;
+		}
+	}
+
+	private void setTokenRange(int start, int end) {
+		this.setTokenRange(start, end, true);
+	}
+	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
+		this.tokenStart = start;
+		if(emptyTokenAdjstment) {
+			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
+			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
+		} else {
+			this.tokenEnd = end + 1;
+		}
+	}
+
+	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
+		char name = firstName;
+		next : while (true) {
+			for (int i = 0 ; i < excludedNames.length ; i++){
+				if(excludedNames[i].length == 1 && ScannerHelper.toLowerCase(excludedNames[i][0]) == ScannerHelper.toLowerCase(name)) {
+					name++;
+					if(name > endChar)
+						name = startChar;
+					if(name == firstName)
+						return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
+					continue next;
+				}
+			}
+
+			for (int i = 0; i < otherParameterNames.length; i++) {
+				if(otherParameterNames[i].length == 1 && ScannerHelper.toLowerCase(otherParameterNames[i][0]) == ScannerHelper.toLowerCase(name)) {
+					name++;
+					if(name > endChar)
+						name = startChar;
+					if(name == firstName)
+						return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
+					continue next;
+				}
+			}
+			break next;
+		}
+		return new char[]{name};
+	}
+
+	private char[] substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames) {
+		char[] name = firstName;
+		int count = 2;
+		next : while(true) {
+			for(int k = 0 ; k < excludedNames.length ; k++){
+				if(CharOperation.equals(name, excludedNames[k], false)) {
+					name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
+					continue next;
+				}
+			}
+			for (int i = 0; i < otherParameterNames.length; i++) {
+				if(CharOperation.equals(name, otherParameterNames[i], false)) {
+					name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
+					continue next;
+				}
+			}
+			break next;
+		}
+		return name;
+	}
+
+	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
+		char[][] substituedParameterNames = new char[typeVariables.length][];
+
+		for (int i = 0; i < substituedParameterNames.length; i++) {
+			substituedParameterNames[i] = typeVariables[i].sourceName;
+		}
+
+		boolean foundConflicts = false;
+
+		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariables[i];
+			char[] methodParameterName = typeVariableBinding.sourceName;
+
+			for (int j = 0; j < excludedNames.length; j++) {
+				char[] typeParameterName = excludedNames[j];
+				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
+					char[] substitution;
+					if(methodParameterName.length == 1) {
+						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
+							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
+						} else {
+							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
+						}
+					} else {
+						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
+					}
+					substituedParameterNames[i] = substitution;
+
+					foundConflicts = true;
+					continue nextTypeParameter;
+				}
+			}
+		}
+
+		if(foundConflicts) return substituedParameterNames;
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java
new file mode 100644
index 0000000..62af4a3
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * This CompletionRequetor wrap the old requestor ICOmpletionRequestor
+ * @since 3.1
+ * @deprecated
+ */
+public class CompletionRequestorWrapper extends CompletionRequestor {
+	private static boolean DECODE_SIGNATURE = false;
+
+	private org.eclipse.jdt.core.ICompletionRequestor requestor;
+	public CompletionRequestorWrapper(org.eclipse.jdt.core.ICompletionRequestor requestor) {
+		this.requestor = requestor;
+	}
+
+	public void accept(CompletionProposal proposal) {
+		InternalCompletionProposal internalCompletionProposal = (InternalCompletionProposal) proposal;
+		switch(internalCompletionProposal.getKind()) {
+			case CompletionProposal.KEYWORD:
+				this.requestor.acceptKeyword(
+						internalCompletionProposal.getName(),
+						internalCompletionProposal.getReplaceStart(),
+						internalCompletionProposal.getReplaceEnd(),
+						internalCompletionProposal.getRelevance());
+				break;
+			case CompletionProposal.PACKAGE_REF:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptPackage(
+							internalCompletionProposal.getDeclarationSignature(),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance());
+				} else {
+					this.requestor.acceptPackage(
+							internalCompletionProposal.getPackageName(),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance());
+				}
+				break;
+			case CompletionProposal.TYPE_REF:
+				if((internalCompletionProposal.getFlags() & Flags.AccEnum) != 0) {
+					// does not exist for old requestor
+				} else if((internalCompletionProposal.getFlags() & Flags.AccInterface) != 0) {
+					if(DECODE_SIGNATURE) {
+						this.requestor.acceptInterface(
+								internalCompletionProposal.getDeclarationSignature(),
+								Signature.getSignatureSimpleName(internalCompletionProposal.getSignature()),
+								internalCompletionProposal.getCompletion(),
+								internalCompletionProposal.getFlags() & ~Flags.AccInterface,
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance());
+					} else {
+						this.requestor.acceptInterface(
+								internalCompletionProposal.getPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getPackageName(),
+								internalCompletionProposal.getTypeName(),
+								internalCompletionProposal.getCompletion(),
+								internalCompletionProposal.getFlags() & ~Flags.AccInterface,
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance());
+					}
+				} else {
+					if(DECODE_SIGNATURE) {
+						this.requestor.acceptClass(
+								internalCompletionProposal.getDeclarationSignature(),
+								Signature.getSignatureSimpleName(internalCompletionProposal.getSignature()),
+								internalCompletionProposal.getCompletion(),
+								internalCompletionProposal.getFlags(),
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance());
+					} else {
+						this.requestor.acceptClass(
+								internalCompletionProposal.getPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getPackageName(),
+								internalCompletionProposal.getTypeName(),
+								internalCompletionProposal.getCompletion(),
+								internalCompletionProposal.getFlags(),
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance());
+					}
+				}
+				break;
+			case CompletionProposal.FIELD_REF:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptField(
+							Signature.getSignatureQualifier(internalCompletionProposal.getDeclarationSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getDeclarationSignature()),
+							internalCompletionProposal.getName(),
+							Signature.getSignatureQualifier(internalCompletionProposal.getSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				} else {
+					this.requestor.acceptField(
+							internalCompletionProposal.getDeclarationPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getDeclarationPackageName(),
+							internalCompletionProposal.getDeclarationTypeName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getDeclarationTypeName(),
+							internalCompletionProposal.getName(),
+							internalCompletionProposal.getPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getPackageName(),
+							internalCompletionProposal.getTypeName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getTypeName(),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.METHOD_REF:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptMethod(
+							Signature.getSignatureQualifier(internalCompletionProposal.getDeclarationSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getDeclarationSignature()),
+							internalCompletionProposal.getName(),
+							getParameterPackages(internalCompletionProposal.getSignature()),
+							getParameterTypes(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+							Signature.getSignatureQualifier(Signature.getReturnType(internalCompletionProposal.getSignature())),
+							Signature.getSignatureSimpleName(Signature.getReturnType(internalCompletionProposal.getSignature())),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+						);
+				} else {
+					this.requestor.acceptMethod(
+							internalCompletionProposal.getDeclarationPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getDeclarationPackageName(),
+							internalCompletionProposal.getDeclarationTypeName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getDeclarationTypeName(),
+							internalCompletionProposal.getName(),
+							internalCompletionProposal.getParameterPackageNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterPackageNames(),
+							internalCompletionProposal.getParameterTypeNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterTypeNames(),
+							internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+							internalCompletionProposal.getPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getPackageName(),
+							internalCompletionProposal.getTypeName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getTypeName(),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.METHOD_DECLARATION:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptMethodDeclaration(
+							Signature.getSignatureQualifier(internalCompletionProposal.getDeclarationSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getDeclarationSignature()),
+							internalCompletionProposal.getName(),
+							getParameterPackages(internalCompletionProposal.getSignature()),
+							getParameterTypes(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+							Signature.getSignatureQualifier(Signature.getReturnType(internalCompletionProposal.getSignature())),
+							Signature.getSignatureSimpleName(Signature.getReturnType(internalCompletionProposal.getSignature())),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				} else {
+					this.requestor.acceptMethodDeclaration(
+							internalCompletionProposal.getDeclarationPackageName(),
+							internalCompletionProposal.getDeclarationTypeName(),
+							internalCompletionProposal.getName(),
+							internalCompletionProposal.getParameterPackageNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterPackageNames(),
+							internalCompletionProposal.getParameterTypeNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterTypeNames(),
+							internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+							internalCompletionProposal.getPackageName(),
+							internalCompletionProposal.getTypeName(),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptAnonymousType(
+							Signature.getSignatureQualifier(internalCompletionProposal.getDeclarationSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getDeclarationSignature()),
+							getParameterPackages(internalCompletionProposal.getSignature()),
+							getParameterTypes(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+						);
+				} else {
+					this.requestor.acceptAnonymousType(
+						internalCompletionProposal.getDeclarationPackageName(),
+						internalCompletionProposal.getDeclarationTypeName(),
+						internalCompletionProposal.getParameterPackageNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterPackageNames(),
+						internalCompletionProposal.getParameterTypeNames() == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.getParameterTypeNames(),
+						internalCompletionProposal.findParameterNames(null) == null ? CharOperation.NO_CHAR_CHAR : internalCompletionProposal.findParameterNames(null),
+						internalCompletionProposal.getCompletion(),
+						internalCompletionProposal.getFlags(),
+						internalCompletionProposal.getReplaceStart(),
+						internalCompletionProposal.getReplaceEnd(),
+						internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.LABEL_REF :
+				this.requestor.acceptLabel(
+					internalCompletionProposal.getCompletion(),
+					internalCompletionProposal.getReplaceStart(),
+					internalCompletionProposal.getReplaceEnd(),
+					internalCompletionProposal.getRelevance()
+				);
+				break;
+			case CompletionProposal.LOCAL_VARIABLE_REF:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptLocalVariable(
+							internalCompletionProposal.getCompletion(),
+							Signature.getSignatureQualifier(internalCompletionProposal.getSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				} else {
+					this.requestor.acceptLocalVariable(
+							internalCompletionProposal.getCompletion(),
+							internalCompletionProposal.getPackageName() == null ? CharOperation.NO_CHAR : internalCompletionProposal.getPackageName(),
+							internalCompletionProposal.getTypeName(),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.VARIABLE_DECLARATION:
+				if(DECODE_SIGNATURE) {
+					this.requestor.acceptLocalVariable(
+							internalCompletionProposal.getCompletion(),
+							Signature.getSignatureQualifier(internalCompletionProposal.getSignature()),
+							Signature.getSignatureSimpleName(internalCompletionProposal.getSignature()),
+							internalCompletionProposal.getFlags(),
+							internalCompletionProposal.getReplaceStart(),
+							internalCompletionProposal.getReplaceEnd(),
+							internalCompletionProposal.getRelevance()
+						);
+				} else {
+					this.requestor.acceptLocalVariable(
+						internalCompletionProposal.getCompletion(),
+						internalCompletionProposal.getPackageName(),
+						internalCompletionProposal.getTypeName(),
+						internalCompletionProposal.getFlags(),
+						internalCompletionProposal.getReplaceStart(),
+						internalCompletionProposal.getReplaceEnd(),
+						internalCompletionProposal.getRelevance()
+					);
+				}
+				break;
+			case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
+				if(this.requestor instanceof IExtendedCompletionRequestor) {
+					IExtendedCompletionRequestor r = (IExtendedCompletionRequestor) this.requestor;
+					if(DECODE_SIGNATURE) {
+						r.acceptPotentialMethodDeclaration(
+								Signature.getSignatureQualifier(internalCompletionProposal.getDeclarationSignature()),
+								Signature.getSignatureSimpleName(internalCompletionProposal.getDeclarationSignature()),
+								internalCompletionProposal.getName(),
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance()
+						);
+					} else {
+						r.acceptPotentialMethodDeclaration(
+								internalCompletionProposal.getDeclarationPackageName(),
+								internalCompletionProposal.getDeclarationTypeName(),
+								internalCompletionProposal.getName(),
+								internalCompletionProposal.getReplaceStart(),
+								internalCompletionProposal.getReplaceEnd(),
+								internalCompletionProposal.getRelevance()
+						);
+					}
+				}
+				break;
+
+		}
+	}
+
+	public void completionFailure(IProblem problem) {
+		this.requestor.acceptError(problem);
+	}
+
+	private char[][] getParameterPackages(char[] methodSignature) {
+		char[][] parameterQualifiedTypes = Signature.getParameterTypes(methodSignature);
+		int length = parameterQualifiedTypes == null ? 0 : parameterQualifiedTypes.length;
+		char[][] parameterPackages = new char[length][];
+		for(int i = 0; i < length; i++) {
+			parameterPackages[i] = Signature.getSignatureQualifier(parameterQualifiedTypes[i]);
+		}
+
+		return parameterPackages;
+	}
+
+	private char[][] getParameterTypes(char[] methodSignature) {
+		char[][] parameterQualifiedTypes = Signature.getParameterTypes(methodSignature);
+		int length = parameterQualifiedTypes == null ? 0 : parameterQualifiedTypes.length;
+		char[][] parameterPackages = new char[length][];
+		for(int i = 0; i < length; i++) {
+			parameterPackages[i] = Signature.getSignatureSimpleName(parameterQualifiedTypes[i]);
+		}
+
+		return parameterPackages;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionUnitStructureRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionUnitStructureRequestor.java
new file mode 100644
index 0000000..0d600d3
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionUnitStructureRequestor.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMarkerAnnotationName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMemberValueName;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedNameReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedTypeReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameReference;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleTypeReference;
+import org.eclipse.jdt.internal.codeassist.impl.AssistAnnotation;
+import org.eclipse.jdt.internal.codeassist.impl.AssistImportContainer;
+import org.eclipse.jdt.internal.codeassist.impl.AssistImportDeclaration;
+import org.eclipse.jdt.internal.codeassist.impl.AssistInitializer;
+import org.eclipse.jdt.internal.codeassist.impl.AssistPackageDeclaration;
+import org.eclipse.jdt.internal.codeassist.impl.AssistSourceField;
+import org.eclipse.jdt.internal.codeassist.impl.AssistSourceMethod;
+import org.eclipse.jdt.internal.codeassist.impl.AssistSourceType;
+import org.eclipse.jdt.internal.codeassist.impl.AssistTypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.core.AnnotatableInfo;
+import org.eclipse.jdt.internal.core.Annotation;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.CompilationUnitElementInfo;
+import org.eclipse.jdt.internal.core.CompilationUnitStructureRequestor;
+import org.eclipse.jdt.internal.core.ImportContainer;
+import org.eclipse.jdt.internal.core.ImportDeclaration;
+import org.eclipse.jdt.internal.core.Initializer;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.PackageDeclaration;
+import org.eclipse.jdt.internal.core.SourceField;
+import org.eclipse.jdt.internal.core.SourceMethod;
+import org.eclipse.jdt.internal.core.SourceType;
+import org.eclipse.jdt.internal.core.TypeParameter;
+
+public class CompletionUnitStructureRequestor extends CompilationUnitStructureRequestor {
+	private ASTNode assistNode;
+
+	private Map bindingCache;
+	private Map elementCache;
+	private Map elementWithProblemCache;
+
+	public CompletionUnitStructureRequestor(
+			ICompilationUnit unit,
+			CompilationUnitElementInfo unitInfo,
+			Parser parser,
+			ASTNode assistNode,
+			Map bindingCache,
+			Map elementCache,
+			Map elementWithProblemCache,
+			Map newElements) {
+		super(unit, unitInfo, newElements);
+		this.parser = parser;
+		this.assistNode = assistNode;
+		this.bindingCache = bindingCache;
+		this.elementCache = elementCache;
+		this.elementWithProblemCache = elementWithProblemCache;
+	}
+
+	protected Annotation createAnnotation(JavaElement parent, String name) {
+		return new AssistAnnotation(parent, name, this.newElements);
+	}
+
+	protected SourceField createField(JavaElement parent, FieldInfo fieldInfo) {
+		String fieldName = JavaModelManager.getJavaModelManager().intern(new String(fieldInfo.name));
+		AssistSourceField field = new AssistSourceField(parent, fieldName, this.bindingCache, this.newElements);
+		if (fieldInfo.node.binding != null) {
+			this.bindingCache.put(field, fieldInfo.node.binding);
+			this.elementCache.put(fieldInfo.node.binding, field);
+		} else {
+			this.elementWithProblemCache.put(fieldInfo.node, field);
+		}
+		return field;
+	}
+
+	protected ImportContainer createImportContainer(ICompilationUnit parent) {
+		return new AssistImportContainer((CompilationUnit)parent, this.newElements);
+	}
+
+	protected ImportDeclaration createImportDeclaration(ImportContainer parent, String name, boolean onDemand) {
+		return new AssistImportDeclaration(parent, name, onDemand, this.newElements);
+	}
+
+	protected Initializer createInitializer(JavaElement parent) {
+		return new AssistInitializer(parent, 1, this.bindingCache, this.newElements);
+	}
+
+	protected SourceMethod createMethodHandle(JavaElement parent, MethodInfo methodInfo) {
+		String selector = JavaModelManager.getJavaModelManager().intern(new String(methodInfo.name));
+		String[] parameterTypeSigs = convertTypeNamesToSigs(methodInfo.parameterTypes);
+		AssistSourceMethod method = new AssistSourceMethod(parent, selector, parameterTypeSigs, this.bindingCache, this.newElements);
+		if (methodInfo.node.binding != null) {
+			this.bindingCache.put(method, methodInfo.node.binding);
+			this.elementCache.put(methodInfo.node.binding, method);
+		} else {
+			this.elementWithProblemCache.put(methodInfo.node, method);
+		}
+		return method;
+	}
+
+	protected PackageDeclaration createPackageDeclaration(JavaElement parent, String name) {
+		return new AssistPackageDeclaration((CompilationUnit) parent, name, this.newElements);
+	}
+
+	protected SourceType createTypeHandle(JavaElement parent, TypeInfo typeInfo) {
+		String nameString= new String(typeInfo.name);
+		AssistSourceType type = new AssistSourceType(parent, nameString, this.bindingCache, this.newElements);
+		if (typeInfo.node.binding != null) {
+			this.bindingCache.put(type, typeInfo.node.binding);
+			this.elementCache.put(typeInfo.node.binding, type);
+		} else {
+			this.elementWithProblemCache.put(typeInfo.node, type);
+		}
+		return type;
+	}
+
+	protected TypeParameter createTypeParameter(JavaElement parent, String name) {
+		return new AssistTypeParameter(parent, name, this.newElements);
+	}
+
+	protected IAnnotation acceptAnnotation(
+			org.eclipse.jdt.internal.compiler.ast.Annotation annotation,
+			AnnotatableInfo parentInfo,
+			JavaElement parentHandle) {
+		if (annotation instanceof CompletionOnMarkerAnnotationName) {
+			if (hasEmptyName(annotation.type, this.assistNode)) {
+				super.acceptAnnotation(annotation, null, parentHandle);
+				return null;
+			}
+		}
+		return super.acceptAnnotation(annotation, parentInfo, parentHandle);
+	}
+
+	protected Object getMemberValue(
+			org.eclipse.jdt.internal.core.MemberValuePair memberValuePair,
+			Expression expression) {
+		if (expression instanceof CompletionOnSingleNameReference) {
+			CompletionOnSingleNameReference reference = (CompletionOnSingleNameReference) expression;
+			if (reference.token.length == 0) return null;
+		} else if (expression instanceof CompletionOnQualifiedNameReference) {
+			CompletionOnQualifiedNameReference reference = (CompletionOnQualifiedNameReference) expression;
+			if (reference.tokens[reference.tokens.length - 1].length == 0) return null;
+		}
+		return super.getMemberValue(memberValuePair, expression);
+	}
+	protected IMemberValuePair[] getMemberValuePairs(MemberValuePair[] memberValuePairs) {
+		int membersLength = memberValuePairs.length;
+		int membersCount = 0;
+		IMemberValuePair[] members = new IMemberValuePair[membersLength];
+		next : for (int j = 0; j < membersLength; j++) {
+			if (memberValuePairs[j] instanceof CompletionOnMemberValueName) continue next;
+
+			members[membersCount++] = getMemberValuePair(memberValuePairs[j]);
+		}
+
+		if (membersCount > membersLength) {
+			System.arraycopy(members, 0, members, 0, membersCount);
+		}
+		return members;
+	}
+
+	protected static boolean hasEmptyName(TypeReference reference, ASTNode assistNode) {
+		if (reference == null) return false;
+
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397070
+		if (reference != assistNode &&
+				reference.sourceStart <= assistNode.sourceStart && assistNode.sourceEnd <= reference.sourceEnd) return false;
+
+		if (reference instanceof CompletionOnSingleTypeReference ||
+				reference instanceof CompletionOnQualifiedTypeReference ||
+				reference instanceof CompletionOnParameterizedQualifiedTypeReference) {
+			char[][] typeName = reference.getTypeName();
+			if (typeName[typeName.length - 1].length == 0) return true;
+		}
+		if (reference instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference parameterizedReference = (ParameterizedSingleTypeReference) reference;
+			TypeReference[] typeArguments = parameterizedReference.typeArguments;
+			if (typeArguments != null) {
+				for (int i = 0; i < typeArguments.length; i++) {
+					if (hasEmptyName(typeArguments[i], assistNode)) return true;
+				}
+			}
+		} else if (reference instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference parameterizedReference = (ParameterizedQualifiedTypeReference) reference;
+			TypeReference[][] typeArguments = parameterizedReference.typeArguments;
+			if (typeArguments != null) {
+				for (int i = 0; i < typeArguments.length; i++) {
+					if (typeArguments[i] != null) {
+						for (int j = 0; j < typeArguments[i].length; j++) {
+							if (hasEmptyName(typeArguments[i][j], assistNode)) return true;
+						}
+					}
+				}
+			}
+		}
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java
new file mode 100644
index 0000000..cd8b9be
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+/**
+ * @deprecated Use {@link org.eclipse.jdt.core.CompletionRequestor} instead
+ */
+//TODO remove this class once no more clients
+public interface IExtendedCompletionRequestor extends org.eclipse.jdt.core.ICompletionRequestor {
+	void acceptPotentialMethodDeclaration(
+			char[] declaringTypePackageName,
+			char[] declaringTypeName,
+			char[] selector,
+			int completionStart,
+			int completionEnd,
+			int relevance);
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
new file mode 100644
index 0000000..23beccc
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * This is the internal requestor passed to the searchable name environment
+ * so as to process the multiple search results as they are discovered.
+ *
+ * It is used to allow the code assist engine to add some more information
+ * to the raw name environment results before answering them to the UI.
+ */
+public interface ISearchRequestor {
+	public void acceptConstructor(
+						int modifiers,
+						char[] simpleTypeName,
+						int parameterCount,
+						char[] signature,
+						char[][] parameterTypes,
+						char[][] parameterNames,
+						int typeModifiers,
+						char[] packageName,
+						int extraFlags,
+						String path,
+						AccessRestriction access);
+	/**
+	 * One result of the search consists of a new type.
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.I".
+	 *    The default package is represented by an empty array.
+	 */
+	public void acceptType(char[] packageName, char[] typeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction);
+
+//	/**
+//	 * One result of the search consists of a new annotation.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptAnnotation(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new class.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.M".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptClass(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new enum.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptEnum(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new interface.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptInterface(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+
+	/**
+	 * One result of the search consists of a new package.
+	 *
+	 * NOTE - All package names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    The default package is represented by an empty array.
+	 */
+	public void acceptPackage(char[] packageName);
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
new file mode 100644
index 0000000..cd0b4bb
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+/**
+ * A selection requestor accepts results from the selection engine.
+ */
+public interface ISelectionRequestor {
+	/**
+	 * Code assist notification of a enum selection.
+	 * @param packageName char[]
+	 * 		Declaring package name of the type.
+	 *
+	 * @param annotationName char[]
+	 * 		Name of the type.
+	 *
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected type is a declaration
+	 *
+	 * @param genericTypeSignature
+	 *  	genric type signature of the selected type if it is a
+	 *  	parameterized type
+	 *
+	 * @param start
+	 *  	Start of the selection
+	 *
+	 * @param end
+	 *  	End of the selection
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.M".
+	 *    The default package is represented by an empty array.
+	 */
+	void acceptType(
+		char[] packageName,
+		char[] annotationName,
+		int modifiers,
+		boolean isDeclaration,
+		char[] genericTypeSignature,
+		int start,
+		int end);
+
+	/**
+	 * Code assist notification of a compilation error detected during selection.
+	 *  @param error CategorizedProblem
+	 *      Only problems which are categorized as errors are notified to the requestor,
+	 *		warnings are silently ignored.
+	 *		In case an error got signaled, no other completions might be available,
+	 *		therefore the problem message should be presented to the user.
+	 *		The source positions of the problem are related to the source where it was
+	 *		detected (might be in another compilation unit, if it was indirectly requested
+	 *		during the code assist process).
+	 *      Note: the problem knows its originating file name.
+	 */
+	void acceptError(CategorizedProblem error);
+
+	/**
+	 * Code assist notification of a field selection.
+	 * @param declaringTypePackageName char[]
+	 * 		Name of the package in which the type that contains this field is declared.
+	 *
+	 * @param declaringTypeName char[]
+	 * 		Name of the type declaring this new field.
+	 *
+	 * @param name char[]
+	 * 		Name of the field.
+	 *
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected field is a declaration
+	 *
+	 * @param uniqueKey
+	 *  	unique key of this field
+	 *
+	 * @param start
+	 *  	Start of the selection
+	 *
+	 * @param end
+	 *  	End of the selection
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.M".
+	 *    The default package is represented by an empty array.
+	 */
+	void acceptField(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] name,
+		boolean isDeclaration,
+		char[] uniqueKey,
+		int start,
+		int end);
+
+	/**
+	 * Code assist notification of a method selection.
+	 * @param declaringTypePackageName char[]
+	 * 		Name of the package in which the type that contains this new method is declared.
+	 *
+	 * @param declaringTypeName char[]
+	 * 		Name of the type declaring this new method.
+	 *
+	 * @param enclosingDeclaringTypeSignature String
+	 *  	Type signature of the declaring type of the declaring type or <code>null</code>
+	 *  	if declaring type is a top level type.
+	 *
+	 * @param selector char[]
+	 * 		Name of the new method.
+	 *
+	 * @param parameterPackageNames char[][]
+	 * 		Names of the packages in which the parameter types are declared.
+	 *    	Should contain as many elements as parameterTypeNames.
+	 *
+	 * @param parameterTypeNames char[][]
+	 * 		Names of the parameters types.
+	 *    	Should contain as many elements as parameterPackageNames.
+	 *
+	 * @param parameterSignatures String[]
+	 * 		Signature of the parameters types.
+	 *    	Should contain as many elements as parameterPackageNames.
+	 *
+	 *  @param isConstructor boolean
+	 * 		Answer if the method is a constructor.
+	 *
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected method is a declaration
+	 *
+	 * @param uniqueKey
+	 *  	unique key of the method
+	 *
+	 * @param start
+	 *  	Start of the selection
+	 *
+	 * @param end
+	 *  	End of the selection
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Base types are in the form "int" or "boolean".
+	 *    Array types are in the qualified form "M[]" or "int[]".
+	 *    Nested type names are in the qualified form "A.M".
+	 *    The default package is represented by an empty array.
+	 */
+	// parameters 'isDeclaration', 'start' and 'end' are use to distinguish duplicate methods declarations
+	void acceptMethod(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		String enclosingDeclaringTypeSignature,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		String[] parameterSignatures,
+		char[][] typeParameterNames,
+		char[][][] typeParameterBoundNames,
+		boolean isConstructor,
+		boolean isDeclaration,
+		char[] uniqueKey,
+		int start,
+		int end);
+
+	/**
+	 * Code assist notification of a package selection.
+	 * @param packageName char[]
+	 * 		The package name.
+	 *
+	 * NOTE - All package names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    The default package is represented by an empty array.
+	 */
+	void acceptPackage(char[] packageName);
+	/**
+	 * Code assist notification of a type parameter selection.
+	 *
+	 * @param declaringTypePackageName char[]
+	 * 		Name of the package in which the type that contains this new method is declared.
+	 *
+	 * @param declaringTypeName char[]
+	 * 		Name of the type declaring this new method.
+	 *
+	 * @param typeParameterName char[]
+	 * 		Name of the type parameter.
+	 *
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected type parameter is a declaration
+	 *
+	 * @param start
+	 *  	Start of the selection
+	 *
+	 * @param end
+	 *  	End of the selection
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.M".
+	 *    The default package is represented by an empty array.
+	 */
+	void acceptTypeParameter(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] typeParameterName,
+		boolean isDeclaration,
+		int start,
+		int end);
+
+	/**
+	 * Code assist notification of a type parameter selection.
+	 *
+	 * @param declaringTypePackageName char[]
+	 * 		Name of the package in which the type that contains this new method is declared.
+	 *
+	 * @param declaringTypeName char[]
+	 * 		Name of the type declaring this new method.
+	 *
+	 * @param selector char[]
+	 * 		Name of the declaring method.
+	 *
+	 * @param selectorStart int
+	 * 		Start of the selector.
+	 *
+	 * @param selectorEnd int
+	 * 		End of the selector.
+	 *
+	 * @param typeParameterName char[]
+	 * 		Name of the type parameter.
+	 *
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected type parameter is a declaration
+	 *
+	 * @param start
+	 *  	Start of the selection
+	 *
+	 * @param end
+	 *  	End of the selection
+	 *
+	 * NOTE - All package and type names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    Nested type names are in the qualified form "A.M".
+	 *    The default package is represented by an empty array.
+	 */
+	void acceptMethodTypeParameter(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] selector,
+		int selectorStart,
+		int selectorEnd,
+		char[] typeParameterName,
+		boolean isDeclaration,
+		int start,
+		int end);
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java
new file mode 100644
index 0000000..bba8d78
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java
@@ -0,0 +1,460 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadoc;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionParser;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+
+
+/**
+ * Internal completion context
+ * @since 3.1
+ */
+public class InternalCompletionContext extends CompletionContext {
+	protected char[][] expectedTypesSignatures;
+	protected char[][] expectedTypesKeys;
+	protected int javadoc;
+
+	protected int offset = -1;
+	protected int tokenStart = -1;
+	protected int tokenEnd = -1;
+	protected char[] token = null;
+	protected int tokenKind;
+	protected int tokenLocation;
+
+	protected boolean isExtended;
+	protected InternalExtendedCompletionContext extendedContext;
+
+	protected void setExpectedTypesKeys(char[][] expectedTypesKeys) {
+		this.expectedTypesKeys = expectedTypesKeys;
+	}
+
+	protected void setExpectedTypesSignatures(char[][] expectedTypesSignatures) {
+		this.expectedTypesSignatures = expectedTypesSignatures;
+	}
+
+	protected void setExtended() {
+		this.isExtended = true;
+	}
+
+	protected void setExtendedData(
+			ITypeRoot typeRoot,
+			CompilationUnitDeclaration compilationUnitDeclaration,
+			LookupEnvironment lookupEnvironment,
+			Scope scope,
+			ASTNode astNode,
+			ASTNode astNodeParent,
+			WorkingCopyOwner owner,
+			CompletionParser parser) {
+		this.isExtended = true;
+		this.extendedContext =
+			new InternalExtendedCompletionContext(
+					this,
+					typeRoot,
+					compilationUnitDeclaration,
+					lookupEnvironment,
+					scope,
+					astNode,
+					astNodeParent,
+					owner,
+					parser);
+	}
+
+	protected void setJavadoc(int javadoc) {
+		this.javadoc = javadoc;
+	}
+
+	protected void setOffset(int offset) {
+		this.offset = offset;
+	}
+
+	protected void setToken(char[] token) {
+		this.token = token;
+	}
+
+	protected void setTokenKind(int tokenKind) {
+		this.tokenKind = tokenKind;
+	}
+
+	protected void setTokenLocation(int tokenLocation) {
+		this.tokenLocation = tokenLocation;
+	}
+
+	protected void setTokenRange(int start, int end) {
+		this.setTokenRange(start, end, -1);
+	}
+
+	protected void setTokenRange(int start, int end, int endOfEmptyToken) {
+		this.tokenStart = start;
+		this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken : end;
+
+		// Work around for bug 132558 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558).
+		// completionLocation can be -1 if the completion occur at the start of a file or
+		// the start of a code snippet but this API isn't design to support negative position.
+		if(this.tokenEnd == -1) {
+			this.tokenEnd = 0;
+		}
+	}
+
+	/**
+	 * Returns the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 * The returned Java element and all Java elements in the same compilation unit which can be navigated to from the returned Java element are special Java elements:
+	 * <ul>
+	 * <li>they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation</li>
+	 * <li>they are not updated if the buffer changes.</li>
+	 * <li>they do not contain local types which are not visible from the completion location.</li>
+	 * <li>they do not give information about categories. {@link IMember#getCategories()} will return an empty array</li>
+	 * </ul>
+	 *
+	 * Reasons for returning <code>null</code> include:
+	 * <ul>
+	 * <li>the compilation unit no longer exists</li>
+	 * <li>the completion occurred in a binary type. However this restriction might be relaxed in the future.</li>
+	 * </ul>
+	 *
+	 * @return the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 *
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @since 3.4
+	 */
+	public IJavaElement getEnclosingElement() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getEnclosingElement();
+	}
+
+	/**
+	 * Return keys of expected types of a potential completion proposal at the completion position.
+	 *
+	 * It's not mandatory to a completion proposal to respect this expectation.
+	 *
+	 * @return keys of expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 *
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public char[][] getExpectedTypesKeys() {
+		return this.expectedTypesKeys;
+	}
+
+	/**
+	 * Return signatures of expected types of a potential completion proposal at the completion position.
+	 *
+	 * It's not mandatory to a completion proposal to respect this expectation.
+	 *
+	 * @return signatures expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 *
+	 * @see Signature
+	 */
+	public char[][] getExpectedTypesSignatures() {
+		return this.expectedTypesSignatures;
+	}
+
+	/**
+	 * Returns the offset position in the source file buffer
+	 * after which code assist is requested.
+	 *
+	 * @return offset position in the source file buffer
+	 * @since 3.2
+	 */
+	public int getOffset() {
+		return this.offset;
+	}
+
+	/**
+	 * Returns the completed token.
+	 * This token is either the identifier or Java language keyword
+	 * or the string literal under, immediately preceding,
+	 * the original request offset. If the original request offset
+	 * is not within or immediately after an identifier or keyword or
+	 * a string literal then the returned value is <code>null</code>.
+	 *
+	 * @return completed token or <code>null</code>
+	 * @since 3.2
+	 */
+	public char[] getToken() {
+		return this.token;
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant token. When there is no relevant token, the
+	 * range is empty
+	 * (<code>getTokenEnd() == getTokenStart() - 1</code>).
+	 *
+	 * @return character index of token end position (exclusive)
+	 * @since 3.2
+	 */
+	// TODO (david) https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558
+	public int getTokenEnd() {
+		return this.tokenEnd;
+	}
+
+	/**
+	 * Returns the kind of completion token being proposed.
+	 * <p>
+	 * The set of different kinds of completion token is
+	 * expected to change over time. It is strongly recommended
+	 * that clients do <b>not</b> assume that the kind is one of the
+	 * ones they know about, and code defensively for the
+	 * possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the kind; one of the kind constants declared on
+	 * this class whose name starts with <code>TOKEN_KIND</code>,
+	 * or possibly a kind unknown to the caller
+	 * @since 3.2
+	 */
+	public int getTokenKind() {
+		return this.tokenKind;
+	}
+
+	/**
+	 * Returns the location of completion token being proposed.
+	 * The returned location is a bit mask which can contain some values
+	 * of the constants declared on this class whose name starts with <code>TL</code>,
+	 * or possibly values unknown to the caller.
+	 *
+	 * <p>
+	 * The set of different location values is expected to change over time.
+	 * It is strongly recommended that clients do <b>not</b> assume that
+	 * the location contains only known value, and code defensively for
+	 * the possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the location
+	 *
+	 * @since 3.4
+	 */
+	public int getTokenLocation() {
+		return this.tokenLocation;
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant token being completed. This
+	 * token is either the identifier or Java language keyword
+	 * under, or immediately preceding, the original request
+	 * offset. If the original request offset is not within
+	 * or immediately after an identifier or keyword, then the
+	 * position returned is original request offset and the
+	 * token range is empty.
+	 *
+	 * @return character index of token start position (inclusive)
+	 * @since 3.2
+	 */
+	public int getTokenStart() {
+		return this.tokenStart;
+	}
+
+	/**
+	 * Return the elements which are visible from the completion location and which can be assigned to the given type.
+	 * An element is assignable if its type can be assigned to a variable
+	 * of the given type, as specified in section 5.2 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 * A visible element is either:
+	 * <ul>
+	 * <li>a {@link ILocalVariable} - the element type is {@link ILocalVariable#getTypeSignature()}</li>
+	 * <li>a {@link IField} - the element type is {@link IField#getTypeSignature()}</li>
+	 * <li>a {@link IMethod} - the element type is {@link IMethod#getReturnType()}</li>
+	 * </ul>
+	 *
+	 * Returned elements defined in the completed compilation unit are special Java elements:
+	 * <ul>
+	 * <li>they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation</li>
+	 * <li>they are not updated if the buffer changes.</li>
+	 * <li>they do not contain local types which are not visible from the completion location.</li>
+	 * <li>they do not give information about categories. {@link IMember#getCategories()} will return an empty array</li>
+	 * </ul>
+	 *
+	 * Note the array can be empty if:
+	 * <ul>
+	 * <li>the compilation unit no longer exists</li>
+	 * <li>the completion occurred in a binary type. However this restriction might be relaxed in the future.</li>
+	 * </ul>
+	 *
+	 * @param typeSignature elements which can be assigned to this type are returned.
+	 * 		If <code>null</code> there is no constraint on the type of the returned elements.
+	 *
+	 * @return elements which are visible from the completion location and which can be assigned to the given type.
+	 *
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 *
+	 * @since 3.4
+	 */
+	public IJavaElement[] getVisibleElements(String typeSignature) {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return new IJavaElement[0];
+	
+		return this.extendedContext.getVisibleElements(typeSignature);
+	}
+
+	/**
+	 * Returns whether this completion context is an extended context.
+	 * Some methods of this context can be used only if this context is an extended context but an extended context consumes more memory.
+	 *
+	 * @return <code>true</code> if this completion context is an extended context.
+	 *
+	 * @since 3.4
+	 */
+	public boolean isExtended() {
+		return this.isExtended;
+	}
+
+	/**
+	 * Tell user whether completion takes place in a javadoc comment or not.
+	 *
+	 * @return boolean true if completion takes place in a javadoc comment, false otherwise.
+	 * @since 3.2
+	 */
+	public boolean isInJavadoc() {
+		return this.javadoc != 0;
+	}
+
+	/**
+	 * Tell user whether completion takes place in a formal reference of a javadoc tag or not.
+	 * Tags with formal reference are:
+	 * <ul>
+	 * 	<li>&#64;see</li>
+	 * 	<li>&#64;throws</li>
+	 * 	<li>&#64;exception</li>
+	 * 	<li>{&#64;link Object}</li>
+	 * 	<li>{&#64;linkplain Object}</li>
+	 * 	<li>{&#64;value} when compiler compliance is set at leats to 1.5</li>
+	 * </ul>
+	 *
+	 * @return boolean true if completion takes place in formal reference of a javadoc tag, false otherwise.
+	 * @since 3.2
+	 */
+	public boolean isInJavadocFormalReference() {
+		return (this.javadoc & CompletionOnJavadoc.FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Tell user whether completion takes place in text area of a javadoc comment or not.
+	 *
+	 * @return boolean true if completion takes place in a text area of a javadoc comment, false otherwise.
+	 * @since 3.2
+	 */
+	public boolean isInJavadocText() {
+		return (this.javadoc & CompletionOnJavadoc.TEXT) != 0;
+	}
+	
+	/**
+	 * Return the completion node associated with the current completion.
+	 *
+	 * @return completion AST node, or null if the extendedContext is null.
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 */
+	public ASTNode getCompletionNode() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getCompletionNode();
+	}
+	
+	/**
+	 * Return the parent AST node of the completion node associated with the current completion.
+	 *
+	 * @return completion parent AST node, or null if the extendedContext is null.
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 */
+	public ASTNode getCompletionNodeParent() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getCompletionNodeParent();
+	}
+	
+	/**
+	 * Return the bindings of all visible local variables in the current completion context.
+	 *
+	 * @return bindings of all visible local variables, or null if the extendedContext is null. Returned bindings are instances of
+	 * {@link LocalVariableBinding}
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 */
+	public ObjectVector getVisibleLocalVariables() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getVisibleLocalVariables();
+	}
+	
+	/**
+	 * Return the bindings of all visible fields in the current completion context.
+	 *
+	 * @return bindings of all visible fields, or null if the extendedContext is null. Returned bindings are instances of
+	 * {@link FieldBinding}
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 */
+	public ObjectVector getVisibleFields() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getVisibleFields();
+	}
+	
+	/**
+	 * Return the bindings of all visible methods in the current completion context.
+	 *
+	 * @return bindings of all visible methods, or null if the extendedContext is null. Returned bindings are instances of
+	 * {@link MethodBinding}
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 */
+	public ObjectVector getVisibleMethods() {
+		if (!this.isExtended) throw new UnsupportedOperationException("Operation only supported in extended context"); //$NON-NLS-1$
+	
+		if (this.extendedContext == null) return null;
+	
+		return this.extendedContext.getVisibleMethods();
+	}
+}
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
new file mode 100644
index 0000000..f22ad0b
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
@@ -0,0 +1,1822 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Andreas Magnusson <andreas.ch.magnusson@gmail.com>- contribution for bug 151500
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionFlags;
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.ICodeAssist;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.core.BinaryType;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SourceMapper;
+
+/**
+ * Internal completion proposal
+ * @since 3.1
+ */
+public class InternalCompletionProposal extends CompletionProposal {
+	private static Object NO_ATTACHED_SOURCE = new Object();
+	
+	protected CompletionEngine completionEngine;
+	protected NameLookup nameLookup;
+
+	protected char[] declarationPackageName;
+	protected char[] declarationTypeName;
+	protected char[] packageName;
+	protected char[] typeName;
+	protected char[][] parameterPackageNames;
+	protected char[][] parameterTypeNames;
+
+	protected char[] originalSignature;
+
+	private boolean hasNoParameterNamesFromIndex = false;
+	private boolean updateCompletion = false;
+
+	protected int accessibility = IAccessRule.K_ACCESSIBLE;
+
+	protected boolean isConstructor = false;
+
+	/**
+	 * Kind of completion request.
+	 */
+	private int completionKind;
+
+	/**
+	 * Offset in original buffer where ICodeAssist.codeComplete() was
+	 * requested.
+	 */
+	private int completionLocation;
+
+	/**
+	 * Start position (inclusive) of source range in original buffer
+	 * containing the relevant token
+	 * defaults to empty subrange at [0,0).
+	 */
+	private int tokenStart = 0;
+
+	/**
+	 * End position (exclusive) of source range in original buffer
+	 * containing the relevant token;
+	 * defaults to empty subrange at [0,0).
+	 */
+	private int tokenEnd = 0;
+
+	/**
+	 * Completion string; defaults to empty string.
+	 */
+	private char[] completion = CharOperation.NO_CHAR;
+
+	/**
+	 * Start position (inclusive) of source range in original buffer
+	 * to be replaced by completion string;
+	 * defaults to empty subrange at [0,0).
+	 */
+	private int replaceStart = 0;
+
+	/**
+	 * End position (exclusive) of source range in original buffer
+	 * to be replaced by completion string;
+	 * defaults to empty subrange at [0,0).
+	 */
+	private int replaceEnd = 0;
+
+	/**
+	 * Relevance rating; positive; higher means better;
+	 * defaults to minimum rating.
+	 */
+	private int relevance = 1;
+
+	/**
+	 * Signature of the relevant package or type declaration
+	 * in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] declarationSignature = null;
+
+	/**
+	 * Unique key of the relevant package or type declaration
+	 * in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] declarationKey = null;
+
+	/**
+	 * Simple name of the method, field,
+	 * member, or variable relevant in the context, or
+	 * <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] name = null;
+
+	/**
+	 * Signature of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] signature = null;
+
+	/**
+	 * Unique of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] key = null;
+
+	/**
+	 * Array of required completion proposals, or <code>null</code> if none.
+	 * The proposal can not be applied if the required proposals aren't applied.
+	 * Defaults to <code>null</code>.
+	 */
+	private CompletionProposal[] requiredProposals;
+
+	/**
+	 * Modifier flags relevant in the context, or
+	 * <code>Flags.AccDefault</code> if none.
+	 * Defaults to <code>Flags.AccDefault</code>.
+	 */
+	private int flags = Flags.AccDefault;
+
+	/**
+	 * Completion flags relevant in the context, or
+	 * <code>CompletionFlags.Default</code> if none.
+	 * Defaults to <code>CompletionFlags.Default</code>.
+	 */
+	private int additionalFlags = CompletionFlags.Default;
+
+	/**
+	 * Parameter names (for method completions), or
+	 * <code>null</code> if none. Lazily computed.
+	 * Defaults to <code>null</code>.
+	 */
+	private char[][] parameterNames = null;
+
+	/**
+	 * Indicates whether parameter names have been computed.
+	 */
+	private boolean parameterNamesComputed = false;
+	
+	protected char[][] findConstructorParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){
+		if(paramTypeNames == null || declaringTypeName == null) return null;
+
+		char[][] parameters = null;
+		int length = paramTypeNames.length;
+
+		char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.');
+		Object cachedType = this.completionEngine.typeCache.get(tName);
+
+		IType type = null;
+		if(cachedType != null) {
+			if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) {
+				type = (BinaryType)cachedType;
+			}
+		} else {
+			// TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
+			NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName),
+				new String(declaringTypePackageName),
+				false,
+				NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
+				true/* consider secondary types */,
+				false/* do NOT wait for indexes */,
+				false/*don't check restrictions*/,
+				null);
+			type = answer == null ? null : answer.type;
+			if(type instanceof BinaryType){
+				this.completionEngine.typeCache.put(tName, type);
+			} else {
+				type = null;
+			}
+		}
+
+		if(type != null) {
+			// 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++;
+								IBinaryType info = (IBinaryType) ((BinaryType) type).getElementInfo();
+								char[] source = mapper.findSource(type, info);
+								if (source != null){
+									mapper.mapSource(type, source, info);
+								}
+								paramNames = mapper.getMethodParameterNames(method);
+							}
+
+							if(paramNames != null) {
+								parameters = paramNames;
+							}
+						}
+					}
+				} else {
+					IBinaryMethod info = (IBinaryMethod) ((JavaElement)method).getElementInfo();
+					char[][] argumentNames = info.getArgumentNames();
+					if (argumentNames != null && argumentNames.length == length) {
+						parameters = argumentNames;
+						return parameters;
+					}
+
+					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;
+			}
+		}
+
+		// default parameters name
+		if(parameters == null) {
+			parameters = CompletionEngine.createDefaultParameterNames(length);
+		}
+
+		return parameters;
+	}
+	
+	protected char[][] findMethodParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){
+		if(paramTypeNames == null || declaringTypeName == null) return null;
+
+		char[][] parameters = null;
+		int length = paramTypeNames.length;
+
+		char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.');
+		Object cachedType = this.completionEngine.typeCache.get(tName);
+
+		IType type = null;
+		if(cachedType != null) {
+			if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) {
+				type = (BinaryType)cachedType;
+			}
+		} else {
+			// TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
+			NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName),
+				new String(declaringTypePackageName),
+				false,
+				NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
+				true/* consider secondary types */,
+				false/* do NOT wait for indexes */,
+				false/*don't check restrictions*/,
+				null);
+			type = answer == null ? null : answer.type;
+			if(type instanceof BinaryType){
+				this.completionEngine.typeCache.put(tName, type);
+			} else {
+				type = null;
+			}
+		}
+
+		if(type != null) {
+			// 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++){
+					parameters[i] = params[i].toCharArray();
+				}
+			} catch(JavaModelException e){
+				parameters = null;
+			}
+		}
+
+		// default parameters name
+		if(parameters == null) {
+			parameters = CompletionEngine.createDefaultParameterNames(length);
+		}
+
+		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;
+	}
+
+	protected char[] getDeclarationTypeName() {
+		return this.declarationTypeName;
+	}
+	
+	private int getOpenedBinaryTypesThreshold() {
+		return JavaModelManager.getJavaModelManager().getOpenableCacheSize() / 10;
+	}
+
+	protected char[] getPackageName() {
+		return this.packageName;
+	}
+
+	protected char[] getTypeName() {
+		return this.typeName;
+	}
+
+	protected char[][] getParameterPackageNames() {
+		return this.parameterPackageNames;
+	}
+
+
+	protected char[][] getParameterTypeNames() {
+		return this.parameterTypeNames;
+	}
+
+	protected void setDeclarationPackageName(char[] declarationPackageName) {
+		this.declarationPackageName = declarationPackageName;
+	}
+
+	protected void setDeclarationTypeName(char[] declarationTypeName) {
+		this.declarationTypeName = declarationTypeName;
+	}
+
+	protected void setPackageName(char[] packageName) {
+		this.packageName = packageName;
+	}
+
+	protected void setTypeName(char[] typeName) {
+		this.typeName = typeName;
+	}
+
+	protected void setParameterPackageNames(char[][] parameterPackageNames) {
+		this.parameterPackageNames = parameterPackageNames;
+	}
+
+	protected void setParameterTypeNames(char[][] parameterTypeNames) {
+		this.parameterTypeNames = parameterTypeNames;
+	}
+
+	protected void setAccessibility(int kind) {
+		this.accessibility = kind;
+	}
+
+	protected void setIsContructor(boolean isConstructor) {
+		this.isConstructor = isConstructor;
+	}
+	public void setOriginalSignature(char[] originalSignature) {
+		this.originalSignature = originalSignature;
+	}
+	/**
+	 * Creates a basic completion proposal. All instance
+	 * field have plausible default values unless otherwise noted.
+	 * <p>
+	 * Note that the constructors for this class are internal to the
+	 * Java model implementation. Clients cannot directly create
+	 * CompletionProposal objects.
+	 * </p>
+	 *
+	 * @param kind one of the kind constants declared on this class
+	 * @param completionLocation original offset of code completion request
+	 */
+	public InternalCompletionProposal(int kind, int completionLocation) {
+		if ((kind < FIRST_KIND)
+				|| (kind > LAST_KIND)) {
+			throw new IllegalArgumentException();
+		}
+		if (this.completion == null || completionLocation < 0) {
+			// Work around for bug 132558 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558).
+			// completionLocation can be -1 if the completion occur at the start of a file or
+			// the start of a code snippet but this API isn't design to support negative position.
+			if(this.completion == null || completionLocation != -1) {
+				throw new IllegalArgumentException();
+			}
+			completionLocation = 0;
+		}
+		this.completionKind = kind;
+		this.completionLocation = completionLocation;
+	}
+
+	/**
+	 * Returns the completion flags relevant in the context, or
+	 * <code>CompletionFlags.Default</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>FIELD_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * <li><code>METHOD_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * <li><code>TYPE_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * </ul>
+	 * For other kinds of completion proposals, this method returns
+	 * <code>CompletionFlags.Default</code>.
+	 * </p>
+	 *
+	 * @return the completion flags, or
+	 * <code>CompletionFlags.Default</code> if none
+	 * @see CompletionFlags
+	 *
+	 * @since 3.3
+	 */
+	public int getAdditionalFlags() {
+		return this.additionalFlags;
+	}
+
+	/**
+	 * Sets the completion flags relevant in the context.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param additionalFlags the completion flags, or
+	 * <code>CompletionFlags.Default</code> if none
+	 *
+	 * @since 3.3
+	 */
+	public void setAdditionalFlags(int additionalFlags) {
+		this.additionalFlags = additionalFlags;
+	}
+
+	/**
+	 * Returns the kind of completion being proposed.
+	 * <p>
+	 * The set of different kinds of completion proposals is
+	 * expected to change over time. It is strongly recommended
+	 * that clients do <b>not</b> assume that the kind is one of the
+	 * ones they know about, and code defensively for the
+	 * possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the kind; one of the kind constants
+	 * declared on this class, or possibly a kind unknown
+	 * to the caller
+	 */
+	public int getKind() {
+		return this.completionKind;
+	}
+
+	/**
+	 * Returns the character index in the source file buffer
+	 * where source completion was requested (the
+	 * <code>offset</code> parameter to
+	 * <code>ICodeAssist.codeComplete</code> minus one).
+	 *
+	 * @return character index in source file buffer
+	 * @see ICodeAssist#codeComplete(int,CompletionRequestor)
+	 */
+	// TODO (david) https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558
+	public int getCompletionLocation() {
+		return this.completionLocation;
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant token being completed. This
+	 * token is either the identifier or Java language keyword
+	 * under, or immediately preceding, the original request
+	 * offset. If the original request offset is not within
+	 * or immediately after an identifier or keyword, then the
+	 * position returned is original request offset and the
+	 * token range is empty.
+	 *
+	 * @return character index of token start position (inclusive)
+	 */
+	public int getTokenStart() {
+		return this.tokenStart;
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant token. When there is no relevant token, the
+	 * range is empty
+	 * (<code>getEndToken() == getStartToken()</code>).
+	 *
+	 * @return character index of token end position (exclusive)
+	 */
+	public int getTokenEnd() {
+		return this.tokenEnd;
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer containing the relevant token being
+	 * completed. This token is either the identifier or
+	 * Java language keyword under, or immediately preceding,
+	 * the original request offset. If the original request
+	 * offset is not within or immediately after an identifier
+	 * or keyword, then the source range begins at original
+	 * request offset and is empty.
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 *
+	 * @param startIndex character index of token start position (inclusive)
+	 * @param endIndex character index of token end position (exclusive)
+	 */
+	public void setTokenRange(int startIndex, int endIndex) {
+		if (startIndex < 0 || endIndex < startIndex) {
+			throw new IllegalArgumentException();
+		}
+		this.tokenStart = startIndex;
+		this.tokenEnd = endIndex;
+	}
+
+	/**
+	 * Returns the proposed sequence of characters to insert into the
+	 * source file buffer, replacing the characters at the specified
+	 * source range. The string can be arbitrary; for example, it might
+	 * include not only the name of a method but a set of parentheses.
+	 * <p>
+	 * The client must not modify the array returned.
+	 * </p>
+	 *
+	 * @return the completion string
+	 */
+	public char[] getCompletion() {
+		if(this.completionKind == METHOD_DECLARATION) {
+			findParameterNames(null);
+			if(this.updateCompletion) {
+				this.updateCompletion = false;
+
+				if(this.parameterNames != null) {
+					int length = this.parameterNames.length;
+					StringBuffer completionBuffer = new StringBuffer(this.completion.length);
+
+					int start = 0;
+					int end = CharOperation.indexOf('%', this.completion);
+
+					completionBuffer.append(this.completion, start, end - start);
+
+					for(int i = 0 ; i < length ; i++){
+						completionBuffer.append(this.parameterNames[i]);
+						start = end + 1;
+						end = CharOperation.indexOf('%', this.completion, start);
+						if(end > -1){
+							completionBuffer.append(this.completion, start, end - start);
+						} else {
+							completionBuffer.append(this.completion, start, this.completion.length - start);
+						}
+					}
+					int nameLength = completionBuffer.length();
+					this.completion = new char[nameLength];
+					completionBuffer.getChars(0, nameLength, this.completion, 0);
+				}
+			}
+		}
+		return this.completion;
+	}
+
+	/**
+	 * Sets the proposed sequence of characters to insert into the
+	 * source file buffer, replacing the characters at the specified
+	 * source range. The string can be arbitrary; for example, it might
+	 * include not only the name of a method but a set of parentheses.
+	 * <p>
+	 * If not set, defaults to an empty character array.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param completion the completion string
+	 */
+	public void setCompletion(char[] completion) {
+		this.completion = completion;
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer to be replaced
+	 * by the completion string. If the subrange is empty
+	 * (<code>getReplaceEnd() == getReplaceStart()</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 * <p>
+	 * Note that while the token subrange is precisely
+	 * specified, the replacement range is loosely
+	 * constrained and may not bear any direct relation
+	 * to the original request offset. For example,
+	 * it would be possible for a type completion to
+	 * propose inserting an import declaration at the
+	 * top of the compilation unit; or the completion
+	 * might include trailing parentheses and
+	 * punctuation for a method completion.
+	 * </p>
+	 *
+	 * @return replacement start position (inclusive)
+	 */
+	public int getReplaceStart() {
+		return this.replaceStart;
+	}
+
+	/**
+	 * Returns the character index of the end of the
+	 * subrange in the source file buffer to be replaced
+	 * by the completion string. If the subrange is empty
+	 * (<code>getReplaceEnd() == getReplaceStart()</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 *
+	 * @return replacement end position (exclusive)
+	 */
+	public int getReplaceEnd() {
+		return this.replaceEnd;
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer to be replaced by the completion
+	 * string. If the subrange is empty
+	 * (<code>startIndex == endIndex</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param startIndex character index of replacement start position (inclusive)
+	 * @param endIndex character index of replacement end position (exclusive)
+	 */
+	public void setReplaceRange(int startIndex, int endIndex) {
+		if (startIndex < 0 || endIndex < startIndex) {
+			throw new IllegalArgumentException();
+		}
+		this.replaceStart = startIndex;
+		this.replaceEnd = endIndex;
+	}
+
+	/**
+	 * Returns the relative relevance rating of this proposal.
+	 *
+	 * @return relevance rating of this proposal; ratings are positive; higher means better
+	 */
+	public int getRelevance() {
+		return this.relevance;
+	}
+
+	/**
+	 * Sets the relative relevance rating of this proposal.
+	 * <p>
+	 * If not set, defaults to the lowest possible rating (1).
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param rating relevance rating of this proposal; ratings are positive; higher means better
+	 */
+	public void setRelevance(int rating) {
+		if (rating <= 0) {
+			throw new IllegalArgumentException();
+		}
+		this.relevance = rating;
+	}
+
+	/**
+	 * Returns the type signature or package name of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - type signature
+	 * of the annotation that declares the attribute that is referenced</li>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - type signature
+	 * of the type that is being subclassed or implemented</li>
+	 * 	<li><code>FIELD_IMPORT</code> - type signature
+	 * of the type that declares the field that is imported</li>
+	 *  <li><code>FIELD_REF</code> - type signature
+	 * of the type that declares the field that is referenced</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that declares the field that is referenced</li>
+	 * 	<li><code>METHOD_IMPORT</code> - type signature
+	 * of the type that declares the method that is imported</li>
+	 *  <li><code>METHOD_REF</code> - type signature
+	 * of the type that declares the method that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that declares the method that is referenced</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - type signature
+	 * of the type that declares the method that is being
+	 * implemented or overridden</li>
+	 * 	<li><code>PACKAGE_REF</code> - dot-based package
+	 * name of the package that is referenced</li>
+	 * 	<li><code>TYPE_IMPORT</code> - dot-based package
+	 * name of the package containing the type that is imported</li>
+	 *  <li><code>TYPE_REF</code> - dot-based package
+	 * name of the package containing the type that is referenced</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - type signature
+	 * of the type that declares the method that is being created</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a type signature or a package name (depending
+	 * on the kind of completion), or <code>null</code> if none
+	 * @see Signature
+	 */
+	public char[] getDeclarationSignature() {
+		return this.declarationSignature;
+	}
+
+	/**
+	 * Returns the key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - key
+	 * of the type that is being subclassed or implemented</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - key
+	 * of the type that declares the method that is being
+	 * implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getDeclarationKey() {
+		return this.declarationKey;
+	}
+
+	/**
+	 * Sets the type or package signature of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the type or package signature, or
+	 * <code>null</code> if none
+	 */
+	public void setDeclarationSignature(char[] signature) {
+		this.declarationSignature = signature;
+	}
+
+	/**
+	 * Sets the type or package key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param key the type or package key, or
+	 * <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setDeclarationKey(char[] key) {
+		this.declarationKey = key;
+	}
+
+	/**
+	 * Returns the simple name of the method, field,
+	 * member, or variable relevant in the context, or
+	 * <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - the name of the attribute</li>
+	 * 	<li><code>FIELD_IMPORT</code> - the name of the field</li>
+	 *  <li><code>FIELD_REF</code> - the name of the field</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - the name of the field</li>
+	 * 	<li><code>KEYWORD</code> - the keyword</li>
+	 * 	<li><code>LABEL_REF</code> - the name of the label</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the name of the local variable</li>
+	 * 	<li><code>METHOD_IMPORT</code> - the name of the method</li>
+	 *  <li><code>METHOD_REF</code> - the name of the method (the type simple name for constructor)</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - the name of the method</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - the name of the method (the type simple name for constructor)</li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - the name of the variable</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - the name of the method</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the keyword, field, method, local variable, or member
+	 * name, or <code>null</code> if none
+	 */
+	public char[] getName() {
+		return this.name;
+	}
+
+
+	/**
+	 * Sets the simple name of the method (type simple name for constructor), field,
+	 * member, or variable relevant in the context, or
+	 * <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param name the keyword, field, method, local variable,
+	 * or member name, or <code>null</code> if none
+	 */
+	public void setName(char[] name) {
+		this.name = name;
+	}
+
+	/**
+	 * Returns the signature of the method or type
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - the type signature
+	 * of the referenced attribute's type</li>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method signature
+	 * of the constructor that is being invoked</li>
+	 * 	<li><code>FIELD_IMPORT</code> - the type signature
+	 * of the referenced field's type</li>
+	 *  <li><code>FIELD_REF</code> - the type signature
+	 * of the referenced field's type</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - the type signature
+	 * of the referenced field's type</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the type signature
+	 * of the referenced local variable's type</li>
+	 * 	<li><code>METHOD_IMPORT</code> - method signature
+	 * of the method that is imported</li>
+	 *  <li><code>METHOD_REF</code> - method signature
+	 * of the method that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - method signature
+	 * of the method that is referenced</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - method signature
+	 * of the method that is being implemented or overridden</li>
+	 * 	<li><code>TYPE_IMPORT</code> - type signature
+	 * of the type that is imported</li>
+	 * 	<li><code>TYPE_REF</code> - type signature
+	 * of the type that is referenced</li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - the type signature
+	 * of the type of the variable being declared</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - method signature
+	 * of the method that is being created</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the signature, or <code>null</code> if none
+	 * @see Signature
+	 */
+	public char[] getSignature() {
+		return this.signature;
+	}
+
+	/**
+	 * Returns the key relevant in the context,
+	 * or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method key
+	 * of the constructor that is being invoked, or <code>null</code> if
+	 * the declaring type is an interface</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - method key
+	 * of the method that is being implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getKey() {
+		return this.key;
+	}
+
+//	/**
+//	 * Returns the package name of the relevant
+//	 * declaration in the context, or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - the dot-based package name
+//	 * of the type that is being subclassed or implemented</li>
+//	 * 	<li><code>FIELD_REF</code> - the dot-based package name
+//	 * of the type that declares the field that is referenced</li>
+//	 * 	<li><code>METHOD_REF</code> - the dot-based package name
+//	 * of the type that declares the method that is referenced</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - the dot-based package name
+//	 * of the type that declares the method that is being
+//	 * implemented or overridden</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the dot-based package name, or
+//	 * <code>null</code> if none
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[] getDeclarationPackageName() {
+//		return this.declarationPackageName;
+//	}
+//
+//	/**
+//	 * Returns the type name of the relevant
+//	 * declaration in the context without the package fragment,
+//	 * or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - the dot-based type name
+//	 * of the type that is being subclassed or implemented</li>
+//	 * 	<li><code>FIELD_REF</code> - the dot-based type name
+//	 * of the type that declares the field that is referenced
+//	 * or an anonymous type instantiation ("new X(){}") if it is an anonymous type</li>
+//	 * 	<li><code>METHOD_REF</code> - the dot-based type name
+//	 * of the type that declares the method that is referenced
+//	 * or an anonymous type instantiation ("new X(){}") if it is an anonymous type</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - the dot-based type name
+//	 * of the type that declares the method that is being
+//	 * implemented or overridden</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the dot-based package name, or
+//	 * <code>null</code> if none
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[] getDeclarationTypeName() {
+//		return this.declarationTypeName;
+//	}
+//
+//	/**
+//	 * Returns the package name of the method or type
+//	 * relevant in the context, or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * 	<li><code>FIELD_REF</code> - the dot-based package name
+//	 * of the referenced field's type</li>
+//	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the dot-based package name
+//	 * of the referenced local variable's type</li>
+//	 * 	<li><code>METHOD_REF</code> -  the dot-based package name
+//	 * of the return type of the method that is referenced</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - the dot-based package name
+//	 * of the return type of the method that is being implemented
+//	 * or overridden</li>
+//	 * 	<li><code>PACKAGE_REF</code> - the dot-based package name
+//	 * of the package that is referenced</li>
+//	 * 	<li><code>TYPE_REF</code> - the dot-based package name
+//	 * of the type that is referenced</li>
+//	 * 	<li><code>VARIABLE_DECLARATION</code> - the dot-based package name
+//	 * of the type of the variable being declared</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the package name, or <code>null</code> if none
+//	 *
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[] getPackageName() {
+//		return this.packageName;
+//	}
+//
+//	/**
+//	 * Returns the type name without the package fragment of the method or type
+//	 * relevant in the context, or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * 	<li><code>FIELD_REF</code> - the dot-based type name
+//	 * of the referenced field's type</li>
+//	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the dot-based type name
+//	 * of the referenced local variable's type</li>
+//	 * 	<li><code>METHOD_REF</code> -  the dot-based type name
+//	 * of the return type of the method that is referenced</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - the dot-based type name
+//	 * of the return type of the method that is being implemented
+//	 * or overridden</li>
+//	 * 	<li><code>TYPE_REF</code> - the dot-based type name
+//	 * of the type that is referenced</li>
+//	 * 	<li><code>VARIABLE_DECLARATION</code> - the dot-based package name
+//	 * of the type of the variable being declared</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the package name, or <code>null</code> if none
+//	 *
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[] getTypeName() {
+//		return this.typeName;
+//	}
+//
+//	/**
+//	 * Returns the parameter package names of the method
+//	 * relevant in the context, or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * 	<li><code>ANONYMOUS_CLASS_DECLARATION</code> - parameter package names
+//	 * of the constructor that is being invoked</li>
+//	 * 	<li><code>METHOD_REF</code> - parameter package names
+//	 * of the method that is referenced</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - parameter package names
+//	 * of the method that is being implemented or overridden</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the package name, or <code>null</code> if none
+//	 *
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[][] getParameterPackageNames() {
+//		return this.parameterPackageNames;
+//	}
+//
+//	/**
+//	 * Returns the parameter type names without the package fragment of
+//	 * the method relevant in the context, or <code>null</code> if none.
+//	 * <p>
+//	 * This field is available for the following kinds of
+//	 * completion proposals:
+//	 * <ul>
+//	 * 	<li><code>ANONYMOUS_CLASS_DECLARATION</code> - parameter type names
+//	 * of the constructor that is being invoked</li>
+//	 * 	<li><code>METHOD_REF</code> - parameter type names
+//	 * of the method that is referenced</li>
+//	 * 	<li><code>METHOD_DECLARATION</code> - parameter type names
+//	 * of the method that is being implemented or overridden</li>
+//	 * </ul>
+//	 * For kinds of completion proposals, this method returns
+//	 * <code>null</code>. Clients must not modify the array
+//	 * returned.
+//	 * </p>
+//	 *
+//	 * @return the package name, or <code>null</code> if none
+//	 *
+//	 * @see #getDeclarationSignature()
+//	 * @see #getSignature()
+//	 *
+//	 * @since 3.1
+//	 */
+//	public char[][] getParameterTypeNames() {
+//		return this.parameterTypeNames;
+//	}
+
+	/**
+	 * Sets the signature of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the signature, or <code>null</code> if none
+	 */
+	public void setSignature(char[] signature) {
+		this.signature = signature;
+	}
+
+	/**
+	 * Sets the key of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param key the key, or <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setKey(char[] key) {
+		this.key = key;
+	}
+
+	/**
+	 * Returns the modifier flags relevant in the context, or
+	 * <code>Flags.AccDefault</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - modifier flags
+	 * of the attribute that is referenced;
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - modifier flags
+	 * of the constructor that is referenced</li>
+	 * 	<li><code>FIELD_IMPORT</code> - modifier flags
+	 * of the field that is imported.</li>
+	 *  <li><code>FIELD_REF</code> - modifier flags
+	 * of the field that is referenced;
+	 * <code>Flags.AccEnum</code> can be used to recognize
+	 * references to enum constants
+	 * </li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - modifier flags
+	 * of the field that is referenced.
+	 * </li>
+	 * 	<li><code>KEYWORD</code> - modifier flag
+	 * corresponding to the modifier keyword</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - modifier flags
+	 * of the local variable that is referenced</li>
+	 *  <li><code>METHOD_IMPORT</code> - modifier flags
+	 * of the method that is imported;
+	 *  </li>
+	 * 	<li><code>METHOD_REF</code> - modifier flags
+	 * of the method that is referenced;
+	 * <code>Flags.AccAnnotation</code> can be used to recognize
+	 * references to annotation type members
+	 * </li>
+	 * <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - modifier flags
+	 * of the method that is referenced.
+	 * </li>
+	 * <li><code>METHOD_DECLARATION</code> - modifier flags
+	 * for the method that is being implemented or overridden</li>
+	 * <li><code>TYPE_IMPORT</code> - modifier flags
+	 * of the type that is imported; <code>Flags.AccInterface</code>
+	 * can be used to recognize references to interfaces,
+	 * <code>Flags.AccEnum</code> enum types,
+	 * and <code>Flags.AccAnnotation</code> annotation types</li>
+	 * <li><code>TYPE_REF</code> - modifier flags
+	 * of the type that is referenced; <code>Flags.AccInterface</code>
+	 * can be used to recognize references to interfaces,
+	 * <code>Flags.AccEnum</code> enum types,
+	 * and <code>Flags.AccAnnotation</code> annotation types
+	 * </li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - modifier flags
+	 * for the variable being declared</li>
+	 * 	<li><code>POTENTIAL_METHOD_DECLARATION</code> - modifier flags
+	 * for the method that is being created</li>
+	 * </ul>
+	 * For other kinds of completion proposals, this method returns
+	 * <code>Flags.AccDefault</code>.
+	 * </p>
+	 *
+	 * @return the modifier flags, or
+	 * <code>Flags.AccDefault</code> if none
+	 * @see Flags
+	 */
+	public int getFlags() {
+		return this.flags;
+	}
+
+	/**
+	 * Sets the modifier flags relevant in the context.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param flags the modifier flags, or
+	 * <code>Flags.AccDefault</code> if none
+	 */
+	public void setFlags(int flags) {
+		this.flags = flags;
+	}
+	
+	public void setHasNoParameterNamesFromIndex(boolean hasNoParameterNamesFromIndex) {
+		this.hasNoParameterNamesFromIndex = hasNoParameterNamesFromIndex;
+	}
+
+	/**
+	 * Returns the required completion proposals.
+	 * The proposal can be apply only if these required completion proposals are also applied.
+	 * If the required proposal aren't applied the completion could create completion problems.
+	 *
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * 	<li><code>FIELD_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *    <li><code>TYPE_IMPORT</code></li>
+	 *    <li><code>FIELD_IMPORT</code></li>
+	 *   </ul>
+	 * </li>
+	 * 	<li><code>METHOD_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *    <li><code>TYPE_IMPORT</code></li>
+	 *    <li><code>METHOD_IMPORT</code></li>
+	 *   </ul>
+	 *  </li>
+	 * </li>
+	 * 	<li><code>TYPE_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *   </ul>
+	 *  </li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * Other kinds of required proposals will be returned in the future, therefore clients of this
+	 * API must allow with {@link CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)}
+	 * only kinds which are in this list to avoid unexpected results in the future.
+	 * </p>
+	 * <p>
+	 * A required proposal of a given kind is proposed even if {@link CompletionRequestor#isIgnored(int)}
+	 * return <code>true</code> for that kind.
+	 * </p>
+	 * <p>
+	 * A required completion proposal cannot have required completion proposals.
+	 * </p>
+	 *
+	 * @return the required completion proposals, or <code>null</code> if none.
+	 *
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int,boolean)
+	 *
+	 * @since 3.3
+	 */
+	public CompletionProposal[] getRequiredProposals() {
+		return this.requiredProposals;
+	}
+
+
+	/**
+	 * Sets the list of required completion proposals, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param proposals the list of required completion proposals, or
+	 * <code>null</code> if none
+     * @since 3.3
+	 */
+	public void setRequiredProposals(CompletionProposal[] proposals) {
+		this.requiredProposals = proposals;
+	}
+
+	/**
+	 * Finds the method parameter names.
+	 * This information is relevant to method reference (and
+	 * method declaration proposals). Returns <code>null</code>
+	 * if not available or not relevant.
+	 * <p>
+	 * The client must not modify the array returned.
+	 * </p>
+	 * <p>
+	 * <b>Note that this is an expensive thing to compute, which may require
+	 * parsing Java source files, etc. Use sparingly.</b>
+	 * </p>
+	 *
+	 * @param monitor the progress monitor, or <code>null</code> if none
+	 * @return the parameter names, or <code>null</code> if none
+	 * or not available or not relevant
+	 */
+	public char[][] findParameterNames(IProgressMonitor monitor) {
+		if (!this.parameterNamesComputed) {
+			this.parameterNamesComputed = true;
+
+			switch(this.completionKind) {
+				case ANONYMOUS_CLASS_DECLARATION:
+					try {
+						this.parameterNames = findMethodParameterNames(
+								this.declarationPackageName,
+								this.declarationTypeName,
+								CharOperation.lastSegment(this.declarationTypeName, '.'),
+								Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+					} catch(IllegalArgumentException e) {
+						// protection for invalid signature
+						if(this.parameterTypeNames != null) {
+							this.parameterNames =  CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+						} else {
+							this.parameterNames = null;
+						}
+					}
+					break;
+				case ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION:
+					try {
+						this.parameterNames = findConstructorParameterNames(
+								this.declarationPackageName,
+								this.declarationTypeName,
+								CharOperation.lastSegment(this.declarationTypeName, '.'),
+								Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+					} catch(IllegalArgumentException e) {
+						// protection for invalid signature
+						if(this.parameterTypeNames != null) {
+							this.parameterNames =  CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+						} else {
+							this.parameterNames = null;
+						}
+					}
+					break;
+				case METHOD_REF:
+				case METHOD_REF_WITH_CASTED_RECEIVER:
+					try {
+						this.parameterNames = findMethodParameterNames(
+								this.declarationPackageName,
+								this.declarationTypeName,
+								this.name,
+								Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+					} catch(IllegalArgumentException e) {
+						// protection for invalid signature
+						if(this.parameterTypeNames != null) {
+							this.parameterNames =  CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+						} else {
+							this.parameterNames = null;
+						}
+					}
+					break;
+				case CONSTRUCTOR_INVOCATION:
+					try {
+						this.parameterNames = findConstructorParameterNames(
+								this.declarationPackageName,
+								this.declarationTypeName,
+								this.name,
+								Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+					} catch(IllegalArgumentException e) {
+						// protection for invalid signature
+						if(this.parameterTypeNames != null) {
+							this.parameterNames =  CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+						} else {
+							this.parameterNames = null;
+						}
+					}
+					break;
+				case METHOD_DECLARATION:
+					try {
+						this.parameterNames = findMethodParameterNames(
+								this.declarationPackageName,
+								this.declarationTypeName,
+								this.name,
+								Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+					} catch(IllegalArgumentException e) {
+						// protection for invalid signature
+						if(this.parameterTypeNames != null) {
+							this.parameterNames =  CompletionEngine.createDefaultParameterNames(this.parameterTypeNames.length);
+						} else {
+							this.parameterNames = null;
+						}
+					}
+					if(this.parameterNames != null) {
+						this.updateCompletion = true;
+					}
+					break;
+			}
+		}
+		return this.parameterNames;
+	}
+
+	/**
+	 * Sets the method parameter names.
+	 * This information is relevant to method reference (and
+	 * method declaration proposals).
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param parameterNames the parameter names, or <code>null</code> if none
+	 */
+	public void setParameterNames(char[][] parameterNames) {
+		this.parameterNames = parameterNames;
+		this.parameterNamesComputed = true;
+	}
+
+	/**
+	 * Returns the accessibility of the proposal.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * 	<li><code>TYPE_REF</code> - accessibility of the type</li>
+	 * </ul>
+	 * For these kinds of completion proposals, this method returns
+	 * {@link IAccessRule#K_ACCESSIBLE} or {@link IAccessRule#K_DISCOURAGED}
+	 * or {@link IAccessRule#K_NON_ACCESSIBLE}.
+	 * By default this method return {@link IAccessRule#K_ACCESSIBLE}.
+	 * </p>
+	 *
+	 * @see IAccessRule
+	 *
+	 * @return the accessibility of the proposal
+	 *
+	 * @since 3.1
+	 */
+	public int getAccessibility() {
+		return this.accessibility;
+	}
+
+	/**
+	 * Returns whether this proposal is a constructor.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>METHOD_REF</code> - return <code>true</code>
+	 * if the referenced method is a constructor</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - return <code>true</code>
+	 * if the declared method is a constructor</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>false</code>.
+	 * </p>
+	 *
+	 * @return <code>true</code> if the proposal is a constructor.
+	 * @since 3.1
+	 */
+	public boolean isConstructor() {
+		return this.isConstructor;
+	}
+
+	private int receiverStart;
+	private int receiverEnd;
+	private char[] receiverSignature;
+
+	/**
+	 * Returns the type signature or package name of the relevant
+	 * receiver in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that cast the receiver of the field that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that cast the receiver of the method that is referenced</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a type signature or a package name (depending
+	 * on the kind of completion), or <code>null</code> if none
+	 * @see Signature
+	 *
+	 * @since 3.4
+	 */
+	public char[] getReceiverSignature() {
+		return this.receiverSignature;
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant receiver of the member being completed. This
+	 * receiver is an expression.
+	 *
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code></li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code></li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns <code>0</code>.
+	 * </p>
+	 *
+	 * @return character index of receiver start position (inclusive)
+	 *
+	 * @since 3.4
+	 */
+	public int getReceiverStart() {
+		return this.receiverStart;
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant receiver of the member being completed.
+	 *
+	 * * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code></li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code></li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns <code>0</code>.
+	 * </p>
+	 *
+	 * @return character index of receiver end position (exclusive)
+	 *
+	 * @since 3.4
+	 */
+	public int getReceiverEnd() {
+		return this.receiverEnd;
+	}
+
+	/**
+	 * Sets the type or package signature of the relevant
+	 * receiver in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the type or package signature, or
+	 * <code>null</code> if none
+	 *
+	 * @since 3.4
+	 */
+	public void setReceiverSignature(char[] signature) {
+		this.receiverSignature = signature;
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer containing the relevant receiver
+	 * of the member being completed.
+	 *
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 *
+	 * @param startIndex character index of receiver start position (inclusive)
+	 * @param endIndex character index of receiver end position (exclusive)
+	 *
+	 * @since 3.4
+	 */
+	public void setReceiverRange(int startIndex, int endIndex) {
+		this.receiverStart = startIndex;
+		this.receiverEnd = endIndex;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append('[');
+		switch(this.completionKind) {
+			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION :
+				buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_REF :
+				buffer.append("FIELD_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.KEYWORD :
+				buffer.append("KEYWORD"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.LABEL_REF :
+				buffer.append("LABEL_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.LOCAL_VARIABLE_REF :
+				buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_DECLARATION :
+				buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
+				if(this.isConstructor) {
+					buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
+				}
+				break;
+			case CompletionProposal.METHOD_REF :
+				buffer.append("METHOD_REF"); //$NON-NLS-1$
+				if(this.isConstructor) {
+					buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
+				}
+				break;
+			case CompletionProposal.PACKAGE_REF :
+				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.TYPE_REF :
+				buffer.append("TYPE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.VARIABLE_DECLARATION :
+				buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.POTENTIAL_METHOD_DECLARATION :
+				buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_NAME_REFERENCE :
+				buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF :
+				buffer.append("ANNOTATION_ATTRIBUTE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_BLOCK_TAG :
+				buffer.append("JAVADOC_BLOCK_TAG"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_INLINE_TAG :
+				buffer.append("JAVADOC_INLINE_TAG"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_FIELD_REF:
+				buffer.append("JAVADOC_FIELD_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_METHOD_REF :
+				buffer.append("JAVADOC_METHOD_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_TYPE_REF :
+				buffer.append("JAVADOC_TYPE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_PARAM_REF :
+				buffer.append("JAVADOC_PARAM_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.JAVADOC_VALUE_REF :
+				buffer.append("JAVADOC_VALUE_REF"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_IMPORT :
+				buffer.append("FIELD_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_IMPORT :
+				buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.TYPE_IMPORT :
+				buffer.append("TYPE_IMPORT"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER :
+				buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER :
+				buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.CONSTRUCTOR_INVOCATION :
+				buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
+				buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
+				break;
+			default :
+				buffer.append("PROPOSAL"); //$NON-NLS-1$
+				break;
+
+		}
+		buffer.append("]{completion:"); //$NON-NLS-1$
+		if (this.completion != null) buffer.append(this.completion);
+		buffer.append(", declSign:"); //$NON-NLS-1$
+		if (this.declarationSignature != null) buffer.append(this.declarationSignature);
+		buffer.append(", sign:"); //$NON-NLS-1$
+		if (this.signature != null) buffer.append(this.signature);
+		buffer.append(", declKey:"); //$NON-NLS-1$
+		if (this.declarationKey != null) buffer.append(this.declarationKey);
+		buffer.append(", key:"); //$NON-NLS-1$
+		if (this.key != null) buffer.append(this.key);
+		buffer.append(", name:"); //$NON-NLS-1$
+		if (this.name != null) buffer.append(this.name);
+		buffer.append(", replace:["); //$NON-NLS-1$
+		buffer.append(this.replaceStart);
+		buffer.append(',');
+		buffer.append(this.replaceEnd);
+		buffer.append("], token:["); //$NON-NLS-1$
+		buffer.append(this.tokenStart);
+		buffer.append(',');
+		buffer.append(this.tokenEnd);
+		buffer.append("], relevance:"); //$NON-NLS-1$
+		buffer.append(this.relevance);
+		buffer.append('}');
+		return buffer.toString();
+	}
+
+	public boolean canUseDiamond(CompletionContext coreContext) {
+		if (this.getKind() != CONSTRUCTOR_INVOCATION) return false;
+		if (coreContext instanceof InternalCompletionContext) {
+			InternalCompletionContext internalCompletionContext = (InternalCompletionContext) coreContext;
+			if (internalCompletionContext.extendedContext == null) return false;
+			char[] name1 = this.declarationPackageName;
+			char[] name2 = this.declarationTypeName;
+			char[] declarationType = CharOperation.concat(name1, name2, '.');  // fully qualified name
+			// even if the type arguments used in the method have been substituted,
+			// extract the original type arguments only, since thats what we want to compare with the class
+			// type variables (Substitution might have happened when the constructor is coming from another
+			// CU and not the current one).
+			char[] sign = (this.originalSignature != null)? this.originalSignature : getSignature();
+			if (!(sign == null || sign.length < 2)) {
+				sign = Signature.removeCapture(sign);
+			}
+			char[][] types= Signature.getParameterTypes(sign);
+			String[] paramTypeNames= new String[types.length];
+			for (int i= 0; i < types.length; i++) {
+				paramTypeNames[i]= new String(Signature.toCharArray(types[i]));
+			}
+			return internalCompletionContext.extendedContext.canUseDiamond(paramTypeNames,declarationType);
+		}
+		else {
+			return false;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
new file mode 100644
index 0000000..19f2546
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
@@ -0,0 +1,971 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ITypeRoot;
+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;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SignatureWrapper;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.core.CompilationUnitElementInfo;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.LocalVariable;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class InternalExtendedCompletionContext {
+	private static Util.BindingsToNodesMap EmptyNodeMap = new Util.BindingsToNodesMap() {
+		public ASTNode get(Binding binding) {
+			return null;
+		}
+	};
+
+	private InternalCompletionContext completionContext;
+
+	// static data
+	private ITypeRoot typeRoot;
+	private CompilationUnitDeclaration compilationUnitDeclaration;
+	private LookupEnvironment lookupEnvironment;
+	private Scope assistScope;
+	private ASTNode assistNode;
+	private ASTNode assistNodeParent;
+	private WorkingCopyOwner owner;
+
+	private CompletionParser parser;
+
+	// computed data
+	private boolean hasComputedVisibleElementBindings;
+	private ObjectVector visibleLocalVariables;
+	private ObjectVector visibleFields;
+	private ObjectVector visibleMethods;
+
+	private boolean hasComputedEnclosingJavaElements;
+	private Map bindingsToHandles;
+	private Map nodesWithProblemsToHandles;
+	private ICompilationUnit compilationUnit;
+
+	public InternalExtendedCompletionContext(
+			InternalCompletionContext completionContext,
+			ITypeRoot typeRoot,
+			CompilationUnitDeclaration compilationUnitDeclaration,
+			LookupEnvironment lookupEnvironment,
+			Scope assistScope,
+			ASTNode assistNode,
+			ASTNode assistNodeParent,
+			WorkingCopyOwner owner,
+			CompletionParser parser) {
+		this.completionContext = completionContext;
+		this.typeRoot = typeRoot;
+		this.compilationUnitDeclaration = compilationUnitDeclaration;
+		this.lookupEnvironment = lookupEnvironment;
+		this.assistScope = assistScope;
+		this.assistNode = assistNode;
+		this.assistNodeParent = assistNodeParent;
+		this.owner = owner;
+		this.parser = parser;
+	}
+
+	private void computeEnclosingJavaElements() {
+		this.hasComputedEnclosingJavaElements = true;
+
+		if (this.typeRoot == null) return;
+
+		if (this.typeRoot.getElementType() == IJavaElement.COMPILATION_UNIT) {
+	 		ICompilationUnit original = (org.eclipse.jdt.core.ICompilationUnit)this.typeRoot;
+
+			HashMap handleToBinding = new HashMap();
+			HashMap bindingToHandle = new HashMap();
+			HashMap nodeWithProblemToHandle = new HashMap();
+			HashMap handleToInfo = new HashMap();
+
+			org.eclipse.jdt.core.ICompilationUnit handle = new AssistCompilationUnit(original, this.owner, handleToBinding, handleToInfo);
+			CompilationUnitElementInfo info = new CompilationUnitElementInfo();
+
+			handleToInfo.put(handle, info);
+
+			CompletionUnitStructureRequestor structureRequestor =
+				new CompletionUnitStructureRequestor(
+						handle,
+						info,
+						this.parser,
+						this.assistNode,
+						handleToBinding,
+						bindingToHandle,
+						nodeWithProblemToHandle,
+						handleToInfo);
+
+			CompletionElementNotifier notifier =
+				new CompletionElementNotifier(
+						structureRequestor,
+						true,
+						this.assistNode);
+
+			notifier.notifySourceElementRequestor(
+					this.compilationUnitDeclaration,
+					this.compilationUnitDeclaration.sourceStart,
+					this.compilationUnitDeclaration.sourceEnd,
+					false,
+					this.parser.sourceEnds,
+					new HashMap());
+
+			this.bindingsToHandles = bindingToHandle;
+			this.nodesWithProblemsToHandles = nodeWithProblemToHandle;
+			this.compilationUnit = handle;
+		}
+	}
+
+	private void computeVisibleElementBindings() {
+		CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
+		this.lookupEnvironment.unitBeingCompleted = this.compilationUnitDeclaration;
+		try {
+			this.hasComputedVisibleElementBindings = true;
+	
+			Scope scope = this.assistScope;
+			ASTNode astNode = this.assistNode;
+			boolean notInJavadoc = this.completionContext.javadoc == 0;
+	
+			this.visibleLocalVariables = new ObjectVector();
+			this.visibleFields = new ObjectVector();
+			this.visibleMethods = new ObjectVector();
+	
+			ReferenceContext referenceContext = scope.referenceContext();
+			if (referenceContext instanceof AbstractMethodDeclaration) {
+				// completion is inside a method body
+				searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc);
+			} else if (referenceContext instanceof TypeDeclaration) {
+				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+				FieldDeclaration[] fields = typeDeclaration.fields;
+				if (fields != null) {
+					done : for (int i = 0; i < fields.length; i++) {
+						if (fields[i] instanceof Initializer) {
+							Initializer initializer = (Initializer) fields[i];
+							if (initializer.block.sourceStart <= astNode.sourceStart &&
+									astNode.sourceStart < initializer.bodyEnd) {
+								// completion is inside an initializer
+								searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc);
+								break done;
+							}
+						} else {
+							FieldDeclaration fieldDeclaration = fields[i];							
+							if (fieldDeclaration.initialization != null) {
+								boolean isInsideInitializer = false;
+								if (fieldDeclaration.initialization.sourceEnd > 0) {
+									if (fieldDeclaration.initialization.sourceStart <= astNode.sourceStart &&
+											astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) {
+										// completion is inside a field initializer
+										isInsideInitializer = true;
+									}
+								} else { // The sourceEnd may not yet be set
+									CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, fieldDeclaration.initialization);
+									if (detector.containsCompletionNode()) {
+										// completion is inside a field initializer
+										isInsideInitializer = true;
+									}
+								}
+								if (isInsideInitializer) {
+									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);
+									}
+									int count = 0;
+									while (count < this.visibleFields.size) {
+										FieldBinding visibleField = (FieldBinding)this.visibleFields.elementAt(count);
+										if (visibleField.id > fieldDeclaration.binding.id) {
+											this.visibleFields.remove(visibleField);
+											continue;
+										}
+										count++;
+									}
+									break done;
+								}
+							}
+						}
+					}
+				}
+			}
+		} finally {
+			this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
+		}
+	}
+
+	public IJavaElement getEnclosingElement() {
+		try {
+			if (!this.hasComputedEnclosingJavaElements) {
+				computeEnclosingJavaElements();
+			}
+			if (this.compilationUnit == null) return null;
+			IJavaElement enclosingElement = this.compilationUnit.getElementAt(this.completionContext.offset);
+			return enclosingElement == null ? this.compilationUnit : enclosingElement;
+		} catch (JavaModelException e) {
+			Util.log(e, "Cannot compute enclosing element"); //$NON-NLS-1$
+			return null;
+		}
+	}
+
+	private JavaElement getJavaElement(LocalVariableBinding binding) {
+		LocalDeclaration local = binding.declaration;
+
+		JavaElement parent = null;
+		ReferenceContext referenceContext = binding.declaringScope.referenceContext();
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext;
+			parent = this.getJavaElementOfCompilationUnit(methodDeclaration, methodDeclaration.binding);
+		} else if (referenceContext instanceof TypeDeclaration){
+			// Local variable is declared inside an initializer
+			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+
+			JavaElement type = this.getJavaElementOfCompilationUnit(typeDeclaration, typeDeclaration.binding);
+			parent = Util.getUnresolvedJavaElement(local.sourceStart, local.sourceEnd, type);
+		}
+		if (parent == null) return null;
+
+		return new LocalVariable(
+				parent,
+				new String(local.name),
+				local.declarationSourceStart,
+				local.declarationSourceEnd,
+				local.sourceStart,
+				local.sourceEnd,
+				Util.typeSignature(local.type),
+				binding.declaration.annotations,
+				local.modifiers,
+				local.getKind() == AbstractVariableDeclaration.PARAMETER);
+	}
+
+	private JavaElement getJavaElementOfCompilationUnit(Binding binding) {
+		if (!this.hasComputedEnclosingJavaElements) {
+			computeEnclosingJavaElements();
+		}
+		if (this.bindingsToHandles == null) return null;
+		return (JavaElement)this.bindingsToHandles.get(binding);
+	}
+
+	private JavaElement getJavaElementOfCompilationUnit(ASTNode node, Binding binding) {
+		if (!this.hasComputedEnclosingJavaElements) {
+			computeEnclosingJavaElements();
+		}
+		if (binding != null) {
+			if (this.bindingsToHandles == null) return null;
+			return (JavaElement)this.bindingsToHandles.get(binding);
+		} else {
+			if (this.nodesWithProblemsToHandles == null) return null;
+			return (JavaElement)this.nodesWithProblemsToHandles.get(node);
+		}
+	}
+
+	private TypeBinding getTypeFromSignature(String typeSignature, Scope scope) {
+		TypeBinding assignableTypeBinding = null;
+
+		TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
+		ReferenceContext referenceContext = scope.referenceContext();
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext;
+			TypeParameter[] typeParameters = methodDeclaration.typeParameters();
+			if (typeParameters != null && typeParameters.length > 0) {
+				int length = typeParameters.length;
+				int count = 0;
+				typeVariables = new TypeVariableBinding[length];
+				for (int i = 0; i < length; i++) {
+					if (typeParameters[i].binding != null) {
+						typeVariables[count++] = typeParameters[i].binding;
+					}
+				}
+
+				if (count != length) {
+					System.arraycopy(typeVariables, 0, typeVariables = new TypeVariableBinding[count], 0, count);
+				}
+			}
+		}
+
+		CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
+		this.lookupEnvironment.unitBeingCompleted = this.compilationUnitDeclaration;
+		try {
+
+			SignatureWrapper wrapper = new SignatureWrapper(replacePackagesDot(typeSignature.toCharArray()));
+			assignableTypeBinding = this.lookupEnvironment.getTypeFromTypeSignature(wrapper, typeVariables, this.assistScope.enclosingClassScope().referenceContext.binding, null);
+			assignableTypeBinding = BinaryTypeBinding.resolveType(assignableTypeBinding, this.lookupEnvironment, true);
+		} catch (AbortCompilation e) {
+			assignableTypeBinding = null;
+		} finally {
+			this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
+		}
+		return assignableTypeBinding;
+	}
+
+	private char[] replacePackagesDot(char[] signature) {
+		boolean replace = true;
+		int length = signature.length;
+		for (int i = 0; i < length; i++) {
+			switch (signature[i]) {
+				case '.':
+					if (replace) signature[i] = '/';
+					break;
+				case '<':
+					replace = true;
+					break;
+				case '>':
+					replace = false;
+					break;
+			}
+		}
+		return signature;
+	}
+
+	public IJavaElement[] getVisibleElements(String typeSignature) {
+		if (this.assistScope == null) return new IJavaElement[0];
+
+		if (!this.hasComputedVisibleElementBindings) {
+			computeVisibleElementBindings();
+		}
+
+		TypeBinding assignableTypeBinding = null;
+		if (typeSignature != null) {
+			assignableTypeBinding = getTypeFromSignature(typeSignature, this.assistScope);
+			if (assignableTypeBinding == null) return new IJavaElement[0];
+		}
+
+		int length = this.visibleLocalVariables.size() + this.visibleFields.size() + this.visibleMethods.size();
+		if (length == 0) return new IJavaElement[0];
+
+		IJavaElement[] result = new IJavaElement[length];
+
+		int elementCount = 0;
+
+		int size = this.visibleLocalVariables.size();
+		if (size > 0) {
+			next : for (int i = 0; i < size; i++) {
+				try {
+					LocalVariableBinding binding = (LocalVariableBinding) this.visibleLocalVariables.elementAt(i);
+					if (binding.type == null || (assignableTypeBinding != null && !binding.type.isCompatibleWith(assignableTypeBinding))) continue next;
+					JavaElement localVariable = getJavaElement(binding);
+					if (localVariable != null) result[elementCount++] = localVariable;
+				} catch(AbortCompilation e) {
+					// log the exception and proceed
+					Util.logRepeatedMessage(e.getKey(), e);
+				}
+			}
+
+		}
+		size = this.visibleFields.size();
+		if (size > 0) {
+			next : for (int i = 0; i < size; i++) {
+				try {
+					FieldBinding binding = (FieldBinding) this.visibleFields.elementAt(i);
+					if (assignableTypeBinding != null && !binding.type.isCompatibleWith(assignableTypeBinding)) continue next;
+					if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) {
+						JavaElement field = getJavaElementOfCompilationUnit(binding);
+						if (field != null) result[elementCount++] = field;
+					} else {
+						JavaElement field = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap);
+						if (field != null) result[elementCount++] = field.resolved(binding);
+					}
+				} catch(AbortCompilation e) {
+					// log the exception and proceed
+					Util.logRepeatedMessage(e.getKey(), e);
+				}
+			}
+
+		}
+		size = this.visibleMethods.size();
+		if (size > 0) {
+			next : for (int i = 0; i < size; i++) {
+				try {
+					MethodBinding binding = (MethodBinding) this.visibleMethods.elementAt(i);
+					if (assignableTypeBinding != null && !binding.returnType.isCompatibleWith(assignableTypeBinding)) continue next;
+					if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) {
+						JavaElement method = getJavaElementOfCompilationUnit(binding);
+						if (method != null) result[elementCount++] = method;
+					} else {
+						JavaElement method = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap);
+						if (method != null) result[elementCount++] = method.resolved(binding);
+					}
+				} catch(AbortCompilation e) {
+					// log the exception and proceed
+					Util.logRepeatedMessage(e.getKey(), e);
+				}
+			}
+		}
+
+		if (elementCount != result.length) {
+			System.arraycopy(result, 0, result = new IJavaElement[elementCount], 0, elementCount);
+		}
+
+		return result;
+	}
+
+	private void searchVisibleFields(
+			FieldBinding[] fields,
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean onlyStaticFields,
+			ObjectVector localsFound,
+			ObjectVector fieldsFound) {
+		ObjectVector newFieldsFound = new ObjectVector();
+		// Inherited fields which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+
+		next : for (int f = fields.length; --f >= 0;) {
+			FieldBinding field = fields[f];
+
+			if (field.isSynthetic()) continue next;
+
+			if (onlyStaticFields && !field.isStatic()) continue next;
+
+			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			for (int i = fieldsFound.size; --i >= 0;) {
+				FieldBinding otherField = (FieldBinding) fieldsFound.elementAt(i);
+				if (CharOperation.equals(field.name, otherField.name, true)) {
+					continue next;
+				}
+			}
+
+			for (int l = localsFound.size; --l >= 0;) {
+				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
+
+				if (CharOperation.equals(field.name, local.name, true)) {
+					continue next;
+				}
+			}
+
+			newFieldsFound.add(field);
+		}
+
+		fieldsFound.addAll(newFieldsFound);
+	}
+
+	private void searchVisibleFields(
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean onlyStaticFields,
+			boolean notInJavadoc,
+			ObjectVector localsFound,
+			ObjectVector fieldsFound) {
+
+		ReferenceBinding currentType = receiverType;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		do {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+
+			FieldBinding[] fields = currentType.availableFields();
+			if(fields != null && fields.length > 0) {
+
+				searchVisibleFields(
+						fields,
+						receiverType,
+						scope,
+						invocationSite,
+						invocationScope,
+						onlyStaticFields,
+						localsFound,
+						fieldsFound);
+			}
+			currentType = currentType.superclass();
+		} while (notInJavadoc && currentType != null);
+
+		if (notInJavadoc && interfacesToVisit != null) {
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				FieldBinding[] fields = anInterface.availableFields();
+				if(fields !=  null) {
+					searchVisibleFields(
+							fields,
+							receiverType,
+							scope,
+							invocationSite,
+							invocationScope,
+							onlyStaticFields,
+							localsFound,
+							fieldsFound);
+				}
+
+				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	private void searchVisibleInterfaceMethods(
+			ReferenceBinding[] itsInterfaces,
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean onlyStaticMethods,
+			ObjectVector methodsFound) {
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding currentType = interfacesToVisit[i];
+				MethodBinding[] methods = currentType.availableMethods();
+				if(methods != null) {
+					searchVisibleLocalMethods(
+							methods,
+							receiverType,
+							scope,
+							invocationSite,
+							invocationScope,
+							onlyStaticMethods,
+							methodsFound);
+				}
+
+				itsInterfaces = currentType.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	private void searchVisibleLocalMethods(
+			MethodBinding[] methods,
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean onlyStaticMethods,
+			ObjectVector methodsFound) {
+		ObjectVector newMethodsFound =  new ObjectVector();
+		// Inherited methods which are hidden by subclasses are filtered out
+		// No visibility checks can be performed without the scope & invocationSite
+
+		next : for (int f = methods.length; --f >= 0;) {
+			MethodBinding method = methods[f];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (onlyStaticMethods && !method.isStatic()) continue next;
+
+			if (!method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			for (int i = methodsFound.size; --i >= 0;) {
+				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
+				if (method == otherMethod)
+					continue next;
+
+				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+						continue next;
+					}
+				}
+			}
+
+			newMethodsFound.add(method);
+		}
+
+		methodsFound.addAll(newMethodsFound);
+	}
+
+	private void searchVisibleMethods(
+			ReferenceBinding receiverType,
+			Scope scope,
+			InvocationSite invocationSite,
+			Scope invocationScope,
+			boolean onlyStaticMethods,
+			boolean notInJavadoc,
+			ObjectVector methodsFound) {
+		ReferenceBinding currentType = receiverType;
+		if (notInJavadoc) {
+			if (receiverType.isInterface()) {
+				searchVisibleInterfaceMethods(
+						new ReferenceBinding[]{currentType},
+						receiverType,
+						scope,
+						invocationSite,
+						invocationScope,
+						onlyStaticMethods,
+						methodsFound);
+
+				currentType = scope.getJavaLangObject();
+			}
+		}
+		boolean hasPotentialDefaultAbstractMethods = true;
+		while (currentType != null) {
+
+			MethodBinding[] methods = currentType.availableMethods();
+			if (methods != null) {
+				searchVisibleLocalMethods(
+						methods,
+						receiverType,
+						scope,
+						invocationSite,
+						invocationScope,
+						onlyStaticMethods,
+						methodsFound);
+			}
+
+			if (notInJavadoc &&
+					hasPotentialDefaultAbstractMethods &&
+					(currentType.isAbstract() ||
+							currentType.isTypeVariable() ||
+							currentType.isIntersectionType() ||
+							currentType.isEnum())){
+
+				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+				if (superInterfaces != null && currentType.isIntersectionType()) {
+					for (int i = 0; i < superInterfaces.length; i++) {
+						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
+					}
+				}
+
+				searchVisibleInterfaceMethods(
+						superInterfaces,
+						receiverType,
+						scope,
+						invocationSite,
+						invocationScope,
+						onlyStaticMethods,
+						methodsFound);
+			} else {
+				hasPotentialDefaultAbstractMethods = false;
+			}
+			if(currentType.isParameterizedType()) {
+				currentType = ((ParameterizedTypeBinding)currentType).genericType().superclass();
+			} else {
+				currentType = currentType.superclass();
+			}
+		}
+	}
+	private void searchVisibleVariablesAndMethods(
+			Scope scope,
+			ObjectVector localsFound,
+			ObjectVector fieldsFound,
+			ObjectVector methodsFound,
+			boolean notInJavadoc) {
+
+		InvocationSite invocationSite = CompletionEngine.FakeInvocationSite;
+
+		boolean staticsOnly = false;
+		// need to know if we're in a static context (or inside a constructor)
+
+		Scope currentScope = scope;
+
+		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (currentScope.kind) {
+
+				case Scope.METHOD_SCOPE :
+					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+					MethodScope methodScope = (MethodScope) currentScope;
+					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+					//$FALL-THROUGH$
+				case Scope.BLOCK_SCOPE :
+					BlockScope blockScope = (BlockScope) currentScope;
+
+					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+						LocalVariableBinding local = blockScope.locals[i];
+
+						if (local == null)
+							break next;
+
+						if (local.isSecret())
+							continue next;
+						// If the local variable declaration's initialization statement itself has the completion,
+						// then don't propose the local variable
+						if (local.declaration.initialization != null) {
+							/*(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,
+										local.declaration.initialization);
+								if (detector.containsCompletionNode()) {
+									continue next;
+								}
+							}*/
+							continue next;
+						}
+						for (int f = 0; f < localsFound.size; f++) {
+							LocalVariableBinding otherLocal =
+								(LocalVariableBinding) localsFound.elementAt(f);
+							if (CharOperation.equals(otherLocal.name, local.name, true))
+								continue next;
+						}
+
+						localsFound.add(local);
+					}
+					break;
+
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done1;
+			}
+			currentScope = currentScope.parent;
+		}
+
+		staticsOnly = false;
+		currentScope = scope;
+
+		done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+			switch (currentScope.kind) {
+				case Scope.METHOD_SCOPE :
+					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+					MethodScope methodScope = (MethodScope) currentScope;
+					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+					break;
+				case Scope.CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) currentScope;
+					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+
+					searchVisibleFields(
+							enclosingType,
+							classScope,
+							invocationSite,
+							scope,
+							staticsOnly,
+							notInJavadoc,
+							localsFound,
+							fieldsFound);
+
+					searchVisibleMethods(
+							enclosingType,
+							classScope,
+							invocationSite,
+							scope,
+							staticsOnly,
+							notInJavadoc,
+							methodsFound);
+
+					staticsOnly |= enclosingType.isStatic();
+					break;
+
+				case Scope.COMPILATION_UNIT_SCOPE :
+					break done2;
+			}
+			currentScope = currentScope.parent;
+		}
+
+		// search in static import
+		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+		for (int i = 0; i < importBindings.length; i++) {
+			ImportBinding importBinding = importBindings[i];
+			if(importBinding.isValidBinding() && importBinding.isStatic()) {
+				Binding binding = importBinding.resolvedImport;
+				if(binding != null && binding.isValidBinding()) {
+					if(importBinding.onDemand) {
+						if((binding.kind() & Binding.TYPE) != 0) {
+							searchVisibleFields(
+									(ReferenceBinding)binding,
+									scope,
+									invocationSite,
+									scope,
+									staticsOnly,
+									notInJavadoc,
+									localsFound,
+									fieldsFound);
+
+							searchVisibleMethods(
+									(ReferenceBinding)binding,
+									scope,
+									invocationSite,
+									scope,
+									staticsOnly,
+									notInJavadoc,
+									methodsFound);
+						}
+					} else {
+						if ((binding.kind() & Binding.FIELD) != 0) {
+							searchVisibleFields(
+									new FieldBinding[]{(FieldBinding)binding},
+									((FieldBinding)binding).declaringClass,
+									scope,
+									invocationSite,
+									scope,
+									staticsOnly,
+									localsFound,
+									fieldsFound);
+						} else if ((binding.kind() & Binding.METHOD) != 0) {
+							MethodBinding methodBinding = (MethodBinding)binding;
+
+							searchVisibleLocalMethods(
+									methodBinding.declaringClass.getMethods(methodBinding.selector),
+									methodBinding.declaringClass,
+									scope,
+									invocationSite,
+									scope,
+									true,
+									methodsFound);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	public boolean canUseDiamond(String[] parameterTypes, char[] fullyQualifiedTypeName) {
+		TypeBinding guessedType = null;
+		char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);
+		Scope scope = this.assistScope;
+		if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return false;
+		// If no LHS or return type expected, then we can safely use diamond
+		char[][] expectedTypekeys= this.completionContext.getExpectedTypesKeys();
+		if (expectedTypekeys == null || expectedTypekeys.length == 0)
+			return true;
+		// Next, find out whether any of the constructor parameters are the same as one of the 
+		// class type variables. If yes, diamond cannot be used.
+		TypeReference ref;
+		if (cn.length == 1) {
+			ref = new SingleTypeReference(cn[0], 0);
+		} else {
+			ref = new QualifiedTypeReference(cn,new long[cn.length]);
+		}
+		switch (scope.kind) {
+			case Scope.METHOD_SCOPE :
+			case Scope.BLOCK_SCOPE :
+				guessedType = ref.resolveType((BlockScope)scope);
+				break;
+			case Scope.CLASS_SCOPE :
+				guessedType = ref.resolveType((ClassScope)scope);
+				break;
+		}
+		if (guessedType != null && guessedType.isValidBinding()) {
+			// the erasure must be used because guessedType can be a RawTypeBinding
+			guessedType = guessedType.erasure();
+			TypeVariableBinding[] typeVars = guessedType.typeVariables();
+			for (int i = 0; i < parameterTypes.length; i++) {
+				for (int j = 0; j < typeVars.length; j++) {
+					if (CharOperation.equals(parameterTypes[i].toCharArray(), typeVars[j].sourceName))
+						return false;
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	/**
+	 * @see InternalCompletionContext#getCompletionNode()
+	 */
+	public ASTNode getCompletionNode() {
+		return this.assistNode;
+	}
+	
+	/**
+	 * @see InternalCompletionContext#getCompletionNodeParent()
+	 */
+	public ASTNode getCompletionNodeParent() {
+		// TODO Auto-generated method stub
+		return this.assistNodeParent;
+	}
+	
+	public ObjectVector getVisibleLocalVariables() {
+		if (!this.hasComputedVisibleElementBindings) {
+			computeVisibleElementBindings();
+		}
+		return this.visibleLocalVariables;
+	}
+	
+	public ObjectVector getVisibleFields() {
+		if (!this.hasComputedVisibleElementBindings) {
+			computeVisibleElementBindings();
+		}
+		return this.visibleFields;
+	}
+	
+	public ObjectVector getVisibleMethods() {
+		if (!this.hasComputedVisibleElementBindings) {
+			computeVisibleElementBindings();
+		}
+		return this.visibleMethods;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java
new file mode 100644
index 0000000..07fcf36
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/MissingTypesGuesser.java
@@ -0,0 +1,608 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+
+public class MissingTypesGuesser extends ASTVisitor {
+	public static interface GuessedTypeRequestor {
+		public void accept(
+				TypeBinding guessedType,
+				Binding[] missingElements,
+				int[] missingElementsStarts,
+				int[] missingElementsEnds,
+				boolean hasProblems);
+
+	}
+
+	private static class ResolutionCleaner extends ASTVisitor {
+		private HashtableOfObjectToInt bitsMap = new HashtableOfObjectToInt();
+		private boolean firstCall = true;
+
+		public ResolutionCleaner(){
+			super();
+		}
+
+		private void cleanUp(TypeReference typeReference) {
+			if (this.firstCall) {
+				this.bitsMap.put(typeReference, typeReference.bits);
+			} else {
+				typeReference.bits = this.bitsMap.get(typeReference);
+			}
+			typeReference.resolvedType = null;
+		}
+
+		private void cleanUp(ParameterizedSingleTypeReference typeReference) {
+			this.cleanUp((TypeReference)typeReference);
+			typeReference.bits &= ~ASTNode.DidResolve;
+		}
+
+		private void cleanUp(ParameterizedQualifiedTypeReference typeReference) {
+			this.cleanUp((TypeReference)typeReference);
+			typeReference.bits &= ~ASTNode.DidResolve;
+		}
+
+		public void cleanUp(TypeReference convertedType, BlockScope scope) {
+			convertedType.traverse(this, scope);
+			this.firstCall = false;
+		}
+
+		public void cleanUp(TypeReference convertedType, ClassScope scope) {
+			convertedType.traverse(this, scope);
+			this.firstCall = false;
+		}
+
+		public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) {
+			this.cleanUp(singleTypeReference);
+			return true;
+		}
+
+		public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) {
+			this.cleanUp(singleTypeReference);
+			return true;
+		}
+
+		public boolean visit(Wildcard wildcard, BlockScope scope) {
+			this.cleanUp(wildcard);
+			return true;
+		}
+
+		public boolean visit(Wildcard wildcard, ClassScope scope) {
+			this.cleanUp(wildcard);
+			return true;
+		}
+
+		public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
+			this.cleanUp(arrayTypeReference);
+			return true;
+		}
+
+		public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
+			this.cleanUp(arrayTypeReference);
+			return true;
+		}
+
+		public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
+			this.cleanUp(parameterizedSingleTypeReference);
+			return true;
+		}
+
+		public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
+			this.cleanUp(parameterizedSingleTypeReference);
+			return true;
+		}
+
+		public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope) {
+			this.cleanUp(qualifiedTypeReference);
+			return true;
+		}
+
+		public boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
+			this.cleanUp(qualifiedTypeReference);
+			return true;
+		}
+
+		public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) {
+			this.cleanUp(arrayQualifiedTypeReference);
+			return true;
+		}
+
+		public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) {
+			this.cleanUp(arrayQualifiedTypeReference);
+			return true;
+		}
+
+		public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
+			this.cleanUp(parameterizedQualifiedTypeReference);
+			return true;
+		}
+
+		public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
+			this.cleanUp(parameterizedQualifiedTypeReference);
+			return true;
+		}
+
+	}
+
+	private CompletionEngine.CompletionProblemFactory problemFactory ;
+	private  SearchableEnvironment nameEnvironment;
+
+	private HashMap substituedTypes;
+	private HashMap originalTypes;
+	private int combinationsCount;
+
+	public MissingTypesGuesser(CompletionEngine completionEngine) {
+		this.problemFactory = completionEngine.problemFactory;
+		this.nameEnvironment = completionEngine.nameEnvironment;
+	}
+
+	private boolean computeMissingElements(
+			QualifiedTypeReference[] substituedTypeNodes,
+			char[][][] originalTypeNames,
+			Binding[] missingElements,
+			int[] missingElementsStarts,
+			int[] missingElementsEnds) {
+		int length = substituedTypeNodes.length;
+
+		for (int i = 0; i < length; i++) {
+			TypeReference substituedType = substituedTypeNodes[i];
+			if (substituedType.resolvedType == null) return false;
+			ReferenceBinding erasure = (ReferenceBinding)substituedType.resolvedType.leafComponentType().erasure();
+			Binding missingElement;
+			int depthToRemove = originalTypeNames[i].length - 1 ;
+			if (depthToRemove == 0) {
+				missingElement = erasure;
+			} else {
+				int depth = erasure.depth() + 1;
+
+				if (depth > depthToRemove) {
+					missingElement = erasure.enclosingTypeAt(depthToRemove);
+				} else {
+					return false;
+					///////////////////////////////////////////////////////////
+					//// Uncomment the following code to return missing package
+					///////////////////////////////////////////////////////////
+					//depthToRemove -= depth;
+					//PackageBinding packageBinding = erasure.getPackage();
+					//while(depthToRemove > 0) {
+					//	packageBinding = packageBinding.parent;
+					//	depthToRemove--;
+					//}
+					//missingElement = packageBinding;
+				}
+			}
+
+			missingElements[i] = missingElement;
+			missingElementsStarts[i] = substituedType.sourceStart;
+			missingElementsEnds[i] = substituedType.sourceEnd + 1;
+
+		}
+
+		return true;
+	}
+
+	private TypeReference convert(ArrayQualifiedTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			if (typeRef.resolvedType.isValidBinding()) {
+				ArrayQualifiedTypeReference convertedType =
+					new ArrayQualifiedTypeReference(
+							typeRef.tokens,
+							typeRef.dimensions(),
+							typeRef.sourcePositions);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				// only the first token must be resolved
+				if(((ReferenceBinding)typeRef.resolvedType.leafComponentType()).compoundName.length != 1) return null;
+
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+				ArrayQualifiedTypeReference convertedType =
+					new ArrayQualifiedTypeReference(
+							typeNames[0],
+							typeRef.dimensions(),
+							new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(ArrayTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			if (typeRef.resolvedType.isValidBinding()) {
+				ArrayTypeReference convertedType =
+					new ArrayTypeReference(
+							typeRef.token,
+							typeRef.dimensions,
+							0);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.originalSourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+				ArrayQualifiedTypeReference convertedType =
+					new ArrayQualifiedTypeReference(
+							typeNames[0],
+							typeRef.dimensions,
+							new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.originalSourceEnd;
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(ParameterizedQualifiedTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			TypeReference[][] typeArguments = typeRef.typeArguments;
+			int length = typeArguments.length;
+			TypeReference[][] convertedTypeArguments = new TypeReference[length][];
+			next : for (int i = 0; i < length; i++) {
+				if (typeArguments[i] == null) continue next;
+				int length2 = typeArguments[i].length;
+				convertedTypeArguments[i] = new TypeReference[length2];
+				for (int j = 0; j < length2; j++) {
+					convertedTypeArguments[i][j] = convert(typeArguments[i][j]);
+					if (convertedTypeArguments[i][j] == null) return null;
+				}
+			}
+
+			if (typeRef.resolvedType.isValidBinding()) {
+				ParameterizedQualifiedTypeReference convertedType =
+					new ParameterizedQualifiedTypeReference(
+							typeRef.tokens,
+							convertedTypeArguments,
+							typeRef.dimensions(),
+							new long[typeRef.tokens.length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				// only the first token must be resolved
+				if(((ReferenceBinding)typeRef.resolvedType.leafComponentType()).compoundName.length != 1) return null;
+
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+
+				TypeReference[][] newConvertedTypeArguments = new TypeReference[typeNames[0].length][];
+				for (int k = newConvertedTypeArguments.length - 1, l = convertedTypeArguments.length -1; k > -1 && l > -1;) {
+					newConvertedTypeArguments[k] = convertedTypeArguments[l];
+					k--;
+					l--;
+				}
+
+				ParameterizedQualifiedTypeReference convertedType =
+					new ParameterizedQualifiedTypeReference(
+							typeNames[0],
+							newConvertedTypeArguments,
+							typeRef.dimensions(),
+							new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(ParameterizedSingleTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			TypeReference[] typeArguments = typeRef.typeArguments;
+			int length = typeArguments.length;
+			TypeReference[] convertedTypeArguments = new TypeReference[length];
+			for (int i = 0; i < length; i++) {
+				convertedTypeArguments[i] = convert(typeArguments[i]);
+				if(convertedTypeArguments[i] == null) return null;
+			}
+
+			if (typeRef.resolvedType.isValidBinding()) {
+				ParameterizedSingleTypeReference convertedType =
+					new ParameterizedSingleTypeReference(
+							typeRef.token,
+							convertedTypeArguments,
+							typeRef.dimensions,
+							0);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+
+				TypeReference[][] allConvertedTypeArguments = new TypeReference[typeNames[0].length][];
+				allConvertedTypeArguments[allConvertedTypeArguments.length - 1] = convertedTypeArguments;
+
+				ParameterizedQualifiedTypeReference convertedType =
+					new ParameterizedQualifiedTypeReference(
+							typeNames[0],
+							allConvertedTypeArguments,
+							typeRef.dimensions,
+							new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(QualifiedTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			if (typeRef.resolvedType.isValidBinding()) {
+				QualifiedTypeReference convertedType = new QualifiedTypeReference(typeRef.tokens, typeRef.sourcePositions);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				// only the first token must be resolved
+				if(((ReferenceBinding)typeRef.resolvedType).compoundName.length != 1) return null;
+
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+				QualifiedTypeReference convertedType = new QualifiedTypeReference(typeNames[0], new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = (int)(typeRef.sourcePositions[0] & 0x00000000FFFFFFFFL);
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(SingleTypeReference typeRef) {
+		if (typeRef.resolvedType != null) {
+			if (typeRef.resolvedType.isValidBinding()) {
+				SingleTypeReference convertedType = new SingleTypeReference(typeRef.token, 0);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				return convertedType;
+			} else if((typeRef.resolvedType.problemId() & ProblemReasons.NotFound) != 0) {
+				char[][] typeName = typeRef.getTypeName();
+				char[][][] typeNames = findTypeNames(typeName);
+				if(typeNames == null || typeNames.length == 0) return null;
+				QualifiedTypeReference convertedType = new QualifiedTypeReference(typeNames[0], new long[typeNames[0].length]);
+				convertedType.sourceStart = typeRef.sourceStart;
+				convertedType.sourceEnd = typeRef.sourceEnd;
+				this.substituedTypes.put(convertedType, typeNames);
+				this.originalTypes.put(convertedType, typeName);
+				this.combinationsCount *= typeNames.length;
+				return convertedType;
+			}
+		}
+		return null;
+	}
+
+	private TypeReference convert(TypeReference typeRef) {
+		if (typeRef instanceof ParameterizedSingleTypeReference) {
+			return convert((ParameterizedSingleTypeReference)typeRef);
+		} else if(typeRef instanceof ParameterizedQualifiedTypeReference) {
+			return convert((ParameterizedQualifiedTypeReference)typeRef);
+		} else if (typeRef instanceof ArrayTypeReference) {
+			return convert((ArrayTypeReference)typeRef);
+		} else if(typeRef instanceof ArrayQualifiedTypeReference) {
+			return convert((ArrayQualifiedTypeReference)typeRef);
+		} else if(typeRef instanceof Wildcard) {
+			return convert((Wildcard)typeRef);
+		} else if (typeRef instanceof SingleTypeReference) {
+			return convert((SingleTypeReference)typeRef);
+		} else if (typeRef instanceof QualifiedTypeReference) {
+			return convert((QualifiedTypeReference)typeRef);
+		}
+		return null;
+	}
+
+	private TypeReference convert(Wildcard typeRef) {
+		TypeReference bound = typeRef.bound;
+		TypeReference convertedBound = null;
+		if (bound != null) {
+			convertedBound = convert(bound);
+			if (convertedBound == null) return null;
+		}
+		Wildcard convertedType = new Wildcard(typeRef.kind);
+		convertedType.bound = convertedBound;
+		convertedType.sourceStart = typeRef.sourceStart;
+		convertedType.sourceEnd = typeRef.sourceEnd;
+		return convertedType;
+	}
+
+	private char[][][] findTypeNames(char[][] missingTypeName) {
+		char[] missingSimpleName = missingTypeName[missingTypeName.length - 1];
+		final boolean isQualified = missingTypeName.length > 1;
+		final char[] missingFullyQualifiedName =
+			isQualified ? CharOperation.concatWith(missingTypeName, '.') : null;
+		final ArrayList results = new ArrayList();
+		ISearchRequestor storage = new ISearchRequestor() {
+			public void acceptConstructor(
+					int modifiers,
+					char[] simpleTypeName,
+					int parameterCount,
+					char[] signature,
+					char[][] parameterTypes,
+					char[][] parameterNames,
+					int typeModifiers,
+					char[] packageName,
+					int extraFlags,
+					String path,
+					AccessRestriction access) {
+				// constructors aren't searched
+			}
+			public void acceptPackage(char[] packageName) {
+				// package aren't searched
+			}
+			public void acceptType(
+					char[] packageName,
+					char[] typeName,
+					char[][] enclosingTypeNames,
+					int modifiers,
+					AccessRestriction accessRestriction) {
+				char[] fullyQualifiedName = CharOperation.concat(packageName, CharOperation.concat(CharOperation.concatWith(enclosingTypeNames, '.'), typeName, '.'), '.');
+				if (isQualified && !CharOperation.endsWith(fullyQualifiedName, missingFullyQualifiedName)) return;
+				char[][] compoundName = CharOperation.splitOn('.', fullyQualifiedName);
+				results.add(compoundName);
+			}
+
+		};
+		this.nameEnvironment.findExactTypes(missingSimpleName, true, IJavaSearchConstants.TYPE, storage);
+		if(results.size() == 0) return null;
+		return (char[][][])results.toArray(new char[results.size()][0][0]);
+	}
+
+	private char[][] getOriginal(TypeReference typeRef) {
+		return (char[][])this.originalTypes.get(typeRef);
+	}
+
+	private QualifiedTypeReference[] getSubstituedTypes() {
+		Set types = this.substituedTypes.keySet();
+		return (QualifiedTypeReference[]) types.toArray(new QualifiedTypeReference[types.size()]);
+	}
+
+	private char[][][] getSubstitution(TypeReference typeRef) {
+		return (char[][][])this.substituedTypes.get(typeRef);
+	}
+
+	public void guess(TypeReference typeRef, Scope scope, GuessedTypeRequestor requestor) {
+		this.substituedTypes = new HashMap();
+		this.originalTypes = new HashMap();
+		this.combinationsCount = 1;
+
+		TypeReference convertedType = convert(typeRef);
+
+		if(convertedType == null) return;
+
+		QualifiedTypeReference[] substituedTypeNodes = getSubstituedTypes();
+		int length = substituedTypeNodes.length;
+
+		int[] substitutionsIndexes = new int[substituedTypeNodes.length];
+		char[][][][] subtitutions = new char[substituedTypeNodes.length][][][];
+		char[][][] originalTypeNames = new char[substituedTypeNodes.length][][];
+		for (int i = 0; i < substituedTypeNodes.length; i++) {
+			subtitutions[i] = getSubstitution(substituedTypeNodes[i]);
+			originalTypeNames[i] = getOriginal(substituedTypeNodes[i]);
+		}
+
+		ResolutionCleaner resolutionCleaner = new ResolutionCleaner();
+		for (int i = 0; i < this.combinationsCount; i++) {
+
+			nextSubstitution(substituedTypeNodes, subtitutions, substitutionsIndexes);
+
+
+			this.problemFactory.startCheckingProblems();
+			TypeBinding guessedType = null;
+			switch (scope.kind) {
+				case Scope.METHOD_SCOPE :
+				case Scope.BLOCK_SCOPE :
+					resolutionCleaner.cleanUp(convertedType, (BlockScope)scope);
+					guessedType = convertedType.resolveType((BlockScope)scope);
+					break;
+				case Scope.CLASS_SCOPE :
+					resolutionCleaner.cleanUp(convertedType, (ClassScope)scope);
+					guessedType = convertedType.resolveType((ClassScope)scope);
+					break;
+			}
+			this.problemFactory.stopCheckingProblems();
+			if (!this.problemFactory.hasForbiddenProblems) {
+				if (guessedType != null) {
+					Binding[] missingElements = new Binding[length];
+					int[] missingElementsStarts = new int[length];
+					int[] missingElementsEnds = new int[length];
+
+					if(computeMissingElements(
+							substituedTypeNodes,
+							originalTypeNames,
+							missingElements,
+							missingElementsStarts,
+							missingElementsEnds)) {
+						requestor.accept(
+								guessedType.capture(scope, typeRef.sourceEnd),
+								missingElements,
+								missingElementsStarts,
+								missingElementsEnds,
+								this.problemFactory.hasAllowedProblems);
+					}
+				}
+			}
+		}
+	}
+	private void nextSubstitution(
+			QualifiedTypeReference[] substituedTypeNodes,
+			char[][][][] subtitutions,
+			int[] substitutionsIndexes) {
+		int length = substituedTypeNodes.length;
+
+		done : for (int i = 0; i < length; i++) {
+			if(substitutionsIndexes[i] < subtitutions[i].length - 1) {
+				substitutionsIndexes[i]++;
+				break done;
+			} else {
+				substitutionsIndexes[i] = 0;
+			}
+		}
+
+		for (int i = 0; i < length; i++) {
+			QualifiedTypeReference qualifiedTypeReference = substituedTypeNodes[i];
+			qualifiedTypeReference.tokens = subtitutions[i][substitutionsIndexes[i]];
+			qualifiedTypeReference.sourcePositions = new long[qualifiedTypeReference.tokens.length];
+			if(qualifiedTypeReference instanceof ParameterizedQualifiedTypeReference) {
+				ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference =
+					(ParameterizedQualifiedTypeReference)qualifiedTypeReference;
+				TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
+				TypeReference[][] newTypeArguments = new TypeReference[qualifiedTypeReference.tokens.length][];
+				for (int j = newTypeArguments.length - 1, k = typeArguments.length -1; j > -1 && k > -1;) {
+					newTypeArguments[j] = typeArguments[k];
+					j--;
+					k--;
+				}
+			}
+		}
+	}
+}
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
new file mode 100644
index 0000000..12dbc47
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+public interface RelevanceConstants {
+
+	
+	/*
+	 * Important: The following rules must be strictly adhered to while declaring new relevance constants or modifying the existing:
+	 * 1. One or more relevance constants are used in combination to form a relevance.
+	 * 2. A particular relevance constant can be added only once to form a relevance.
+	 * 3. A resultant relevance (after combining all the applicable relevance constants) must be a positive number.
+	 * 4. The value of R_DEFAULT is maintained at a positive value such that the sum of all the negative relevance constants
+	 *    and R_DEFAULT must not be negative. 
+	 */
+	int R_DEFAULT = 5;
+	int R_INTERESTING = 5;
+	int R_CASE = 10;
+	int R_CAMEL_CASE = 5;
+	int R_EXACT_NAME = 4;
+	int R_VOID = -5;
+	int R_EXPECTED_TYPE = 20;
+	int R_EXACT_EXPECTED_TYPE = 30;
+	int R_INTERFACE = 20;
+	int R_CLASS = 20;
+	int R_ENUM = 20;
+	int R_ANNOTATION = 20;
+	int R_EXCEPTION = 20;
+	int R_ENUM_CONSTANT = 5;
+	int R_ABSTRACT_METHOD = 20;
+	int R_NON_STATIC = 11;
+	int R_UNQUALIFIED = 3;
+	int R_QUALIFIED = 2;
+	int R_NAME_FIRST_PREFIX = 6;
+	int R_NAME_PREFIX = 5;
+	int R_NAME_FIRST_SUFFIX = 4;
+	int R_NAME_SUFFIX = 3;
+	int R_NAME_LESS_NEW_CHARACTERS = 15;
+	int R_METHOD_OVERIDE = 3;
+	int R_NON_RESTRICTED = 3;
+	int R_TRUE_OR_FALSE = 1;
+	int R_INLINE_TAG = 31;
+	int R_VALUE_TAG = 31;
+	int R_NON_INHERITED = 2;
+	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
+	int R_CONSTRUCTOR = 3; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=373409
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
new file mode 100644
index 0000000..d1eec1d
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -0,0 +1,1803 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IOpenable;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.TypeNameMatch;
+import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
+import org.eclipse.jdt.internal.codeassist.impl.*;
+import org.eclipse.jdt.internal.codeassist.select.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.core.BinaryTypeConverter;
+import org.eclipse.jdt.internal.core.ClassFile;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.SelectionRequestor;
+import org.eclipse.jdt.internal.core.SourceType;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.TypeNameMatchRequestorWrapper;
+import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
+import org.eclipse.jdt.internal.core.util.HashSetOfCharArrayArray;
+
+/**
+ * The selection engine is intended to infer the nature of a selected name in some
+ * source code. This name can be qualified.
+ *
+ * Selection is resolving context using a name environment (no need to search), assuming
+ * the source where selection occurred is correct and will not perform any completion
+ * attempt. If this was the desired behavior, a call to the CompletionEngine should be
+ * performed instead.
+ */
+public final class SelectionEngine extends Engine implements ISearchRequestor {
+	
+	private static class SelectionTypeNameMatchRequestorWrapper extends TypeNameMatchRequestorWrapper {
+		
+		class AcceptedType {
+			public int modifiers;
+			public char[] packageName;
+			public char[] simpleTypeName;
+			public String path;
+			public AccessRestriction access;
+			
+			public AcceptedType(int modifiers, char[] packageName, char[] simpleTypeName, String path, AccessRestriction access) {
+				this.modifiers = modifiers;
+				this.packageName = packageName;
+				this.simpleTypeName = simpleTypeName;
+				this.path = path;
+				this.access = access;
+			}
+		}
+		
+		private ImportReference[] importReferences;
+		
+		private boolean importCachesNodeInitialized = false;
+		private ImportReference[] onDemandImportsNodeCache;
+		private int onDemandImportsNodeCacheCount;
+		private char[][][] importsNodeCache;
+		private int importsNodeCacheCount;
+		
+		private HashtableOfObject onDemandFound = new HashtableOfObject();
+		private ObjectVector notImportedFound = new ObjectVector();
+		
+		public SelectionTypeNameMatchRequestorWrapper(TypeNameMatchRequestor requestor, IJavaSearchScope scope, ImportReference[] importReferences) {
+			super(requestor, scope);
+			this.importReferences = importReferences;
+		}
+		
+		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+			if (enclosingTypeNames != null && enclosingTypeNames.length > 0) return;
+			
+			if (!this.importCachesNodeInitialized) initializeImportNodeCaches();
+			
+			char[] fullyQualifiedTypeName = CharOperation.concat(packageName, simpleTypeName, '.');
+			
+			for (int i = 0; i < this.importsNodeCacheCount; i++) {
+				char[][] importName = this.importsNodeCache[i];
+				if (CharOperation.equals(importName[0], simpleTypeName)) {
+					
+					if(CharOperation.equals(importName[1], fullyQualifiedTypeName)) {
+						super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
+					}
+					return;
+				}
+			}
+			
+			for (int i = 0; i < this.onDemandImportsNodeCacheCount; i++) {
+				char[][] importName = this.onDemandImportsNodeCache[i].tokens;
+				char[] importFlatName = CharOperation.concatWith(importName, '.');
+				
+				if (CharOperation.equals(importFlatName, packageName)) {
+					
+					this.onDemandFound.put(simpleTypeName, simpleTypeName);
+					super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
+					return;
+				}
+			}
+			
+			
+			this.notImportedFound.add(new AcceptedType(modifiers, packageName, simpleTypeName, path, access));
+		}
+		
+		public void acceptNotImported() {
+			int size = this.notImportedFound.size();
+			for (int i = 0; i < size; i++) {
+				AcceptedType acceptedType = (AcceptedType)this.notImportedFound.elementAt(i);
+				
+				if (this.onDemandFound.get(acceptedType.simpleTypeName) == null) {
+					super.acceptType(
+							acceptedType.modifiers,
+							acceptedType.packageName,
+							acceptedType.simpleTypeName,
+							null,
+							acceptedType.path,
+							acceptedType.access);
+				}
+			}
+		}
+		
+		public void initializeImportNodeCaches() {
+			int length = this.importReferences == null ? 0 : this.importReferences.length;
+			
+			for (int i = 0; i < length; i++) {
+				ImportReference importReference = this.importReferences[i];
+				if((importReference.bits & ASTNode.OnDemand) != 0) {
+					if(this.onDemandImportsNodeCache == null) {
+						this.onDemandImportsNodeCache = new ImportReference[length - i];
+					}
+					this.onDemandImportsNodeCache[this.onDemandImportsNodeCacheCount++] =
+						importReference;
+				} else {
+					if(this.importsNodeCache == null) {
+						this.importsNodeCache = new char[length - i][][];
+					}
+					
+					
+					this.importsNodeCache[this.importsNodeCacheCount++] = new char[][]{
+							importReference.tokens[importReference.tokens.length - 1],
+							CharOperation.concatWith(importReference.tokens, '.')
+						};
+				}
+			}
+			
+			this.importCachesNodeInitialized = true;
+		}
+	}
+
+	public static boolean DEBUG = false;
+	public static boolean PERF = false;
+
+	SelectionParser parser;
+	ISelectionRequestor requestor;
+	WorkingCopyOwner owner;
+
+	boolean acceptedAnswer;
+
+	private int actualSelectionStart;
+	private int actualSelectionEnd;
+	private char[] selectedIdentifier;
+
+	private char[][][] acceptedClasses;
+	private int[] acceptedClassesModifiers;
+	private char[][][] acceptedInterfaces;
+	private int[] acceptedInterfacesModifiers;
+	private char[][][] acceptedEnums;
+	private int[] acceptedEnumsModifiers;
+	private char[][][] acceptedAnnotations;
+	private int[] acceptedAnnotationsModifiers;
+	int acceptedClassesCount;
+	int acceptedInterfacesCount;
+	int acceptedEnumsCount;
+	int acceptedAnnotationsCount;
+
+	boolean noProposal = true;
+	CategorizedProblem problem = null;
+
+	/**
+	 * The SelectionEngine is responsible for computing the selected object.
+	 *
+	 * It requires a searchable name environment, which supports some
+	 * specific search APIs, and a requestor to feed back the results to a UI.
+	 *
+	 *  @param nameEnvironment org.eclipse.jdt.internal.core.SearchableEnvironment
+	 *      used to resolve type/package references and search for types/packages
+	 *      based on partial names.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.codeassist.ISelectionRequestor
+	 *      since the engine might produce answers of various forms, the engine
+	 *      is associated with a requestor able to accept all possible completions.
+	 *
+	 *  @param settings java.util.Map
+	 *		set of options used to configure the code assist engine.
+	 */
+	public SelectionEngine(
+		SearchableEnvironment nameEnvironment,
+		ISelectionRequestor requestor,
+		Map settings,
+		WorkingCopyOwner owner) {
+
+		super(settings);
+
+		this.requestor = requestor;
+		this.nameEnvironment = nameEnvironment;
+
+		ProblemReporter problemReporter =
+			new ProblemReporter(
+				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+				this.compilerOptions,
+				new DefaultProblemFactory(Locale.getDefault())) {
+
+			public CategorizedProblem createProblem(
+				char[] fileName,
+				int problemId,
+				String[] problemArguments,
+				String[] messageArguments,
+				int severity,
+				int problemStartPosition,
+				int problemEndPosition,
+				int lineNumber,
+				int columnNumber) {
+				CategorizedProblem pb =  super.createProblem(
+					fileName,
+					problemId,
+					problemArguments,
+					messageArguments,
+					severity,
+					problemStartPosition,
+					problemEndPosition,
+					lineNumber,
+					columnNumber);
+					if(SelectionEngine.this.problem == null && pb.isError() && (pb.getID() & IProblem.Syntax) == 0) {
+						SelectionEngine.this.problem = pb;
+					}
+
+					return pb;
+			}
+		};
+		this.lookupEnvironment =
+			new LookupEnvironment(this, this.compilerOptions, problemReporter, nameEnvironment);
+		this.parser = new SelectionParser(problemReporter);
+		this.owner = owner;
+	}
+	
+	public void acceptConstructor(
+			int modifiers,
+			char[] simpleTypeName,
+			int parameterCount,
+			char[] signature,
+			char[][] parameterTypes,
+			char[][] parameterNames,
+			int typeModifiers,
+			char[] packageName,
+			int extraFlags,
+			String path,
+			AccessRestriction access) {
+		// constructors aren't searched
+	}
+
+	public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
+		char[] typeName = enclosingTypeNames == null ?
+				simpleTypeName :
+					CharOperation.concat(
+						CharOperation.concatWith(enclosingTypeNames, '.'),
+						simpleTypeName,
+						'.');
+
+		if (CharOperation.equals(simpleTypeName, this.selectedIdentifier)) {
+			char[] flatEnclosingTypeNames =
+				enclosingTypeNames == null || enclosingTypeNames.length == 0 ?
+						null :
+							CharOperation.concatWith(enclosingTypeNames, '.');
+			if(mustQualifyType(packageName, simpleTypeName, flatEnclosingTypeNames, modifiers)) {
+				int length = 0;
+				int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
+				switch (kind) {
+					case ClassFileConstants.AccAnnotation:
+					case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
+						char[][] acceptedAnnotation = new char[2][];
+						acceptedAnnotation[0] = packageName;
+						acceptedAnnotation[1] = typeName;
+
+						if(this.acceptedAnnotations == null) {
+							this.acceptedAnnotations = new char[10][][];
+							this.acceptedAnnotationsModifiers = new int[10];
+							this.acceptedAnnotationsCount = 0;
+						}
+						length = this.acceptedAnnotations.length;
+						if(length == this.acceptedAnnotationsCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedAnnotations, 0, this.acceptedAnnotations = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedAnnotationsModifiers, 0, this.acceptedAnnotationsModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedAnnotationsModifiers[this.acceptedAnnotationsCount] = modifiers;
+						this.acceptedAnnotations[this.acceptedAnnotationsCount++] = acceptedAnnotation;
+						break;
+					case ClassFileConstants.AccEnum:
+						char[][] acceptedEnum = new char[2][];
+						acceptedEnum[0] = packageName;
+						acceptedEnum[1] = typeName;
+
+						if(this.acceptedEnums == null) {
+							this.acceptedEnums = new char[10][][];
+							this.acceptedEnumsModifiers = new int[10];
+							this.acceptedEnumsCount = 0;
+						}
+						length = this.acceptedEnums.length;
+						if(length == this.acceptedEnumsCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedEnums, 0, this.acceptedEnums = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedEnumsModifiers, 0, this.acceptedEnumsModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedEnumsModifiers[this.acceptedEnumsCount] = modifiers;
+						this.acceptedEnums[this.acceptedEnumsCount++] = acceptedEnum;
+						break;
+					case ClassFileConstants.AccInterface:
+						char[][] acceptedInterface= new char[2][];
+						acceptedInterface[0] = packageName;
+						acceptedInterface[1] = typeName;
+
+						if(this.acceptedInterfaces == null) {
+							this.acceptedInterfaces = new char[10][][];
+							this.acceptedInterfacesModifiers = new int[10];
+							this.acceptedInterfacesCount = 0;
+						}
+						length = this.acceptedInterfaces.length;
+						if(length == this.acceptedInterfacesCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedInterfaces, 0, this.acceptedInterfaces = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedInterfacesModifiers, 0, this.acceptedInterfacesModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedInterfacesModifiers[this.acceptedInterfacesCount] = modifiers;
+						this.acceptedInterfaces[this.acceptedInterfacesCount++] = acceptedInterface;
+						break;
+					default:
+						char[][] acceptedClass = new char[2][];
+						acceptedClass[0] = packageName;
+						acceptedClass[1] = typeName;
+
+						if(this.acceptedClasses == null) {
+							this.acceptedClasses = new char[10][][];
+							this.acceptedClassesModifiers = new int[10];
+							this.acceptedClassesCount = 0;
+						}
+						length = this.acceptedClasses.length;
+						if(length == this.acceptedClassesCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedClasses, 0, this.acceptedClasses = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedClassesModifiers, 0, this.acceptedClassesModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedClassesModifiers[this.acceptedClassesCount] = modifiers;
+						this.acceptedClasses[this.acceptedClassesCount++] = acceptedClass;
+						break;
+				}
+			} else {
+				this.noProposal = false;
+				this.requestor.acceptType(
+					packageName,
+					typeName,
+					modifiers,
+					false,
+					null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+				this.acceptedAnswer = true;
+			}
+		}
+	}
+
+	/**
+	 * One result of the search consists of a new package.
+	 * @param packageName char[]
+	 *
+	 * NOTE - All package names are presented in their readable form:
+	 *    Package names are in the form "a.b.c".
+	 *    The default package is represented by an empty array.
+	 */
+	public void acceptPackage(char[] packageName) {
+		// implementation of interface method
+	}
+
+	private void acceptQualifiedTypes() {
+		if(this.acceptedClasses != null){
+			this.acceptedAnswer = true;
+			for (int i = 0; i < this.acceptedClassesCount; i++) {
+				this.noProposal = false;
+				this.requestor.acceptType(
+					this.acceptedClasses[i][0],
+					this.acceptedClasses[i][1],
+					this.acceptedClassesModifiers[i],
+					false,
+					null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+			}
+			this.acceptedClasses = null;
+			this.acceptedClassesModifiers = null;
+			this.acceptedClassesCount = 0;
+		}
+		if(this.acceptedInterfaces != null){
+			this.acceptedAnswer = true;
+			for (int i = 0; i < this.acceptedInterfacesCount; i++) {
+				this.noProposal = false;
+				this.requestor.acceptType(
+					this.acceptedInterfaces[i][0],
+					this.acceptedInterfaces[i][1],
+					this.acceptedInterfacesModifiers[i],
+					false,
+					null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+			}
+			this.acceptedInterfaces = null;
+			this.acceptedInterfacesModifiers = null;
+			this.acceptedInterfacesCount = 0;
+		}
+		if(this.acceptedAnnotations != null){
+			this.acceptedAnswer = true;
+			for (int i = 0; i < this.acceptedAnnotationsCount; i++) {
+				this.noProposal = false;
+				this.requestor.acceptType(
+					this.acceptedAnnotations[i][0],
+					this.acceptedAnnotations[i][1],
+					this.acceptedAnnotationsModifiers[i],
+					false,
+					null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+			}
+			this.acceptedAnnotations = null;
+			this.acceptedAnnotationsModifiers = null;
+			this.acceptedAnnotationsCount = 0;
+		}
+		if(this.acceptedEnums != null){
+			this.acceptedAnswer = true;
+			for (int i = 0; i < this.acceptedEnumsCount; i++) {
+				this.noProposal = false;
+				this.requestor.acceptType(
+					this.acceptedEnums[i][0],
+					this.acceptedEnums[i][1],
+					this.acceptedEnumsModifiers[i],
+					false,
+					null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+			}
+			this.acceptedEnums = null;
+			this.acceptedEnumsModifiers = null;
+			this.acceptedEnumsCount = 0;
+		}
+	}
+	private boolean checkSelection(
+			char[] source,
+			int selectionStart,
+			int selectionEnd) {
+
+		Scanner scanner =
+			new Scanner(
+				false /*comment*/,
+				false /*whitespace*/,
+				false /*nls*/,
+				this.compilerOptions.sourceLevel,
+				this.compilerOptions.complianceLevel,
+				null/*taskTag*/,
+				null/*taskPriorities*/,
+				true /*taskCaseSensitive*/);
+		scanner.setSource(source);
+
+		int lastIdentifierStart = -1;
+		int lastIdentifierEnd = -1;
+		char[] lastIdentifier = null;
+		int token;
+
+		if(selectionStart > selectionEnd){
+			int end = source.length - 1;
+
+			// compute start position of current line
+			int currentPosition = selectionStart - 1;
+			int nextCharacterPosition = selectionStart;
+			char currentCharacter = ' ';
+			try {
+				lineLoop: while(currentPosition > 0){
+
+					if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') {
+						int pos = currentPosition + 2;
+						int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+						while (source[pos] == 'u') {
+							pos++;
+						}
+
+						int endOfUnicode = pos + 3;
+						if (end < endOfUnicode) {
+							if (endOfUnicode < source.length) {
+								end = endOfUnicode;
+							} else {
+								return false; // not enough characters to decode an unicode
+							}
+						}
+
+						if ((c1 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15
+							|| c1 < 0
+							|| (c2 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15
+							|| c2 < 0
+							|| (c3 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15
+							|| c3 < 0
+							|| (c4 = ScannerHelper.getHexadecimalValue(source[pos++])) > 15
+							|| c4 < 0) {
+							return false;
+						} else {
+							currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+							nextCharacterPosition = pos;
+						}
+					} else {
+						currentCharacter = source[currentPosition];
+						nextCharacterPosition = currentPosition+1;
+					}
+
+					switch(currentCharacter) {
+						case '\r':
+						case '\n':
+						case '/':
+						case '"':
+						case '\'':
+							break lineLoop;
+					}
+					currentPosition--;
+				}
+			} catch (ArrayIndexOutOfBoundsException e) {
+				return false;
+			}
+
+			// compute start and end of the last token
+			scanner.resetTo(nextCharacterPosition, end);
+			isolateLastName: do {
+				try {
+					token = scanner.getNextToken();
+				} catch (InvalidInputException e) {
+					return false;
+				}
+				switch (token) {
+					case TerminalTokens.TokenNamethis:
+					case TerminalTokens.TokenNamesuper:
+					case TerminalTokens.TokenNameIdentifier:
+						if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
+							if (scanner.currentPosition == scanner.eofPosition) {
+								int temp = scanner.eofPosition;
+								scanner.eofPosition = scanner.source.length;
+							 	while(scanner.getNextCharAsJavaIdentifierPart()){/*empty*/}
+							 	scanner.eofPosition = temp;
+							}
+							lastIdentifierStart = scanner.startPosition;
+							lastIdentifierEnd = scanner.currentPosition - 1;
+							lastIdentifier = scanner.getCurrentTokenSource();
+							break isolateLastName;
+						}
+						break;
+				}
+			} while (token != TerminalTokens.TokenNameEOF);
+		} else {
+			scanner.resetTo(selectionStart, selectionEnd);
+
+			boolean expectingIdentifier = true;
+			do {
+				try {
+					token = scanner.getNextToken();
+				} catch (InvalidInputException e) {
+					return false;
+				}
+				switch (token) {
+					case TerminalTokens.TokenNamethis :
+					case TerminalTokens.TokenNamesuper :
+					case TerminalTokens.TokenNameIdentifier :
+						if (!expectingIdentifier)
+							return false;
+						lastIdentifier = scanner.getCurrentTokenSource();
+						lastIdentifierStart = scanner.startPosition;
+						lastIdentifierEnd = scanner.currentPosition - 1;
+						if(lastIdentifierEnd > selectionEnd) {
+							lastIdentifierEnd = selectionEnd;
+							lastIdentifier = CharOperation.subarray(lastIdentifier, 0,lastIdentifierEnd - lastIdentifierStart + 1);
+						}
+						expectingIdentifier = false;
+						break;
+					case TerminalTokens.TokenNameDOT :
+						if (expectingIdentifier)
+							return false;
+						expectingIdentifier = true;
+						break;
+					case TerminalTokens.TokenNameEOF :
+						if (expectingIdentifier)
+							return false;
+						break;
+					case TerminalTokens.TokenNameLESS :
+						if(!checkTypeArgument(scanner))
+							return false;
+						break;
+					case TerminalTokens.TokenNameAT:
+						if(scanner.startPosition != scanner.initialPosition)
+							return false;
+						break;
+					default :
+						return false;
+				}
+			} while (token != TerminalTokens.TokenNameEOF);
+		}
+		if (lastIdentifierStart > 0) {
+			this.actualSelectionStart = lastIdentifierStart;
+			this.actualSelectionEnd = lastIdentifierEnd;
+			this.selectedIdentifier = lastIdentifier;
+			return true;
+		}
+		return false;
+	}
+	private boolean checkTypeArgument(Scanner scanner) {
+		int depth = 1;
+		int token;
+		StringBuffer buffer = new StringBuffer();
+		do {
+			try {
+				token = scanner.getNextToken();
+			} catch (InvalidInputException e) {
+				return false;
+			}
+			switch(token) {
+				case TerminalTokens.TokenNameLESS :
+					depth++;
+					buffer.append(scanner.getCurrentTokenSource());
+					break;
+				case TerminalTokens.TokenNameGREATER :
+					depth--;
+					buffer.append(scanner.getCurrentTokenSource());
+					break;
+				case TerminalTokens.TokenNameRIGHT_SHIFT :
+					depth-=2;
+					buffer.append(scanner.getCurrentTokenSource());
+					break;
+				case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT :
+					depth-=3;
+					buffer.append(scanner.getCurrentTokenSource());
+					break;
+				case TerminalTokens.TokenNameextends :
+				case TerminalTokens.TokenNamesuper :
+					buffer.append(' ');
+					buffer.append(scanner.getCurrentTokenSource());
+					buffer.append(' ');
+					break;
+				case TerminalTokens.TokenNameCOMMA :
+					if(depth == 1) {
+						int length = buffer.length();
+						char[] typeRef = new char[length];
+						buffer.getChars(0, length, typeRef, 0);
+						try {
+							Signature.createTypeSignature(typeRef, true);
+							buffer = new StringBuffer();
+						} catch(IllegalArgumentException e) {
+							return false;
+						}
+					}
+					break;
+				default :
+					buffer.append(scanner.getCurrentTokenSource());
+					break;
+
+			}
+			if(depth < 0) {
+				return false;
+			}
+		} while (depth != 0 && token != TerminalTokens.TokenNameEOF);
+
+		if(depth == 0) {
+			int length = buffer.length() - 1;
+			char[] typeRef = new char[length];
+			buffer.getChars(0, length, typeRef, 0);
+			try {
+				Signature.createTypeSignature(typeRef, true);
+				return true;
+			} catch(IllegalArgumentException e) {
+				return false;
+			}
+		}
+
+		return false;
+	}
+	
+	/*
+	 * find all types outside the project scope
+	 */
+	private void findAllTypes(char[] prefix) {
+		try {
+			IProgressMonitor progressMonitor = new IProgressMonitor() {
+				boolean isCanceled = false;
+				public void beginTask(String name, int totalWork) {
+					// implements interface method
+				}
+				public void done() {
+					// implements interface method
+				}
+				public void internalWorked(double work) {
+					// implements interface method
+				}
+				public boolean isCanceled() {
+					return this.isCanceled;
+				}
+				public void setCanceled(boolean value) {
+					this.isCanceled = value;
+				}
+				public void setTaskName(String name) {
+					// implements interface method
+				}
+				public void subTask(String name) {
+					// implements interface method
+				}
+				public void worked(int work) {
+					// implements interface method
+				}
+			};
+			
+			TypeNameMatchRequestor typeNameMatchRequestor = new TypeNameMatchRequestor() {
+				public void acceptTypeNameMatch(TypeNameMatch match) {
+					if (SelectionEngine.this.requestor instanceof SelectionRequestor) {
+						SelectionEngine.this.noProposal = false;
+						((SelectionRequestor)SelectionEngine.this.requestor).acceptType(match.getType());
+					}
+				}
+			};
+			
+			IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope();
+			
+			SelectionTypeNameMatchRequestorWrapper requestorWrapper =
+				new SelectionTypeNameMatchRequestorWrapper(
+						typeNameMatchRequestor, 
+						scope,
+						this.unitScope == null ? null : this.unitScope.referenceContext.imports);
+			
+			org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/);
+			
+			try {
+				new BasicSearchEngine(workingCopies).searchAllTypeNames(
+					null,
+					SearchPattern.R_EXACT_MATCH,
+					prefix,
+					SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
+					IJavaSearchConstants.TYPE,
+					scope,
+					requestorWrapper,
+					IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
+					progressMonitor);
+			} catch (OperationCanceledException e) {
+				// do nothing
+			}
+			requestorWrapper.acceptNotImported();
+		} catch (JavaModelException e) {
+			// do nothing
+		}
+	}
+
+	public AssistParser getParser() {
+		return this.parser;
+	}
+
+	/*
+	 * Returns whether the given binding is a local/anonymous reference binding, or if its declaring class is
+	 * local.
+	 */
+	private boolean isLocal(ReferenceBinding binding) {
+		if(binding instanceof ParameterizedTypeBinding) {
+			return isLocal(((ParameterizedTypeBinding)binding).genericType());
+		}
+		if (!(binding instanceof SourceTypeBinding)) return false;
+		if (binding instanceof LocalTypeBinding) return true;
+		if (binding instanceof MemberTypeBinding) {
+			return isLocal(((MemberTypeBinding)binding).enclosingType);
+		}
+		return false;
+	}
+
+	/**
+	 * Ask the engine to compute the selection at the specified position
+	 * of the given compilation unit.
+
+	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
+	 *      the source of the current compilation unit.
+	 *
+	 *  @param selectionSourceStart int
+	 *  @param selectionSourceEnd int
+	 *      a range in the source where the selection is.
+	 */
+	public void select(
+		ICompilationUnit sourceUnit,
+		int selectionSourceStart,
+		int selectionSourceEnd) {
+
+		char[] source = sourceUnit.getContents();
+
+		if(DEBUG) {
+			System.out.print("SELECTION IN "); //$NON-NLS-1$
+			System.out.print(sourceUnit.getFileName());
+			System.out.print(" FROM "); //$NON-NLS-1$
+			System.out.print(selectionSourceStart);
+			System.out.print(" TO "); //$NON-NLS-1$
+			System.out.println(selectionSourceEnd);
+			System.out.println("SELECTION - Source :"); //$NON-NLS-1$
+			System.out.println(source);
+		}
+		if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) {
+			return;
+		}
+		if (DEBUG) {
+			System.out.print("SELECTION - Checked : \""); //$NON-NLS-1$
+			System.out.print(new String(source, this.actualSelectionStart, this.actualSelectionEnd-this.actualSelectionStart+1));
+			System.out.println('"');
+		}
+		try {
+			this.acceptedAnswer = false;
+			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+			CompilationUnitDeclaration parsedUnit =
+				this.parser.dietParse(sourceUnit, result, this.actualSelectionStart, this.actualSelectionEnd);
+
+			if (parsedUnit != null) {
+				if(DEBUG) {
+					System.out.println("SELECTION - Diet AST :"); //$NON-NLS-1$
+					System.out.println(parsedUnit.toString());
+				}
+
+				// scan the package & import statements first
+				if (parsedUnit.currentPackage instanceof SelectionOnPackageReference) {
+					char[][] tokens =
+						((SelectionOnPackageReference) parsedUnit.currentPackage).tokens;
+					this.noProposal = false;
+					this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
+					return;
+				}
+				ImportReference[] imports = parsedUnit.imports;
+				if (imports != null) {
+					for (int i = 0, length = imports.length; i < length; i++) {
+						ImportReference importReference = imports[i];
+						if (importReference instanceof SelectionOnImportReference) {
+							char[][] tokens = ((SelectionOnImportReference) importReference).tokens;
+							this.noProposal = false;
+							this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
+							this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), false, false, IJavaSearchConstants.TYPE, this);
+
+							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+							if ((this.unitScope = parsedUnit.scope) != null) {
+								int tokenCount = tokens.length;
+								char[] lastToken = tokens[tokenCount - 1];
+								char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);
+
+								if(qualifierTokens != null && qualifierTokens.length > 0) {
+									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
+									if(binding != null && binding instanceof ReferenceBinding) {
+										ReferenceBinding ref = (ReferenceBinding) binding;
+										selectMemberTypeFromImport(parsedUnit, lastToken, ref, importReference.isStatic());
+										if(importReference.isStatic()) {
+											selectStaticFieldFromStaticImport(parsedUnit, lastToken, ref);
+											selectStaticMethodFromStaticImport(parsedUnit, lastToken, ref);
+										}
+									}
+								}
+							}
+
+							// accept qualified types only if no unqualified type was accepted
+							if(!this.acceptedAnswer) {
+								acceptQualifiedTypes();
+								if (!this.acceptedAnswer) {
+									this.nameEnvironment.findTypes(this.selectedIdentifier, false, false, IJavaSearchConstants.TYPE, this);
+									// try with simple type name
+									if(!this.acceptedAnswer) {
+										acceptQualifiedTypes();
+									}
+								}
+							}
+							if(this.noProposal && this.problem != null) {
+								this.requestor.acceptError(this.problem);
+							}
+							return;
+						}
+					}
+				}
+				if (parsedUnit.types != null || parsedUnit.isPackageInfo()) {
+					if(selectDeclaration(parsedUnit))
+						return;
+					this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+					if ((this.unitScope = parsedUnit.scope)  != null) {
+						try {
+							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+							
+							CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
+							this.lookupEnvironment.unitBeingCompleted = parsedUnit;
+							parsedUnit.scope.faultInTypes();
+							this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
+							ASTNode node = null;
+							if (parsedUnit.types != null)
+								node = parseBlockStatements(parsedUnit, selectionSourceStart);
+							if(DEBUG) {
+								System.out.println("SELECTION - AST :"); //$NON-NLS-1$
+								System.out.println(parsedUnit.toString());
+							}
+							parsedUnit.resolve();
+							if (node != null) {
+								selectLocalDeclaration(node);
+							}
+						} catch (SelectionNodeFound e) {
+							if (e.binding != null) {
+								if(DEBUG) {
+									System.out.println("SELECTION - Selection binding:"); //$NON-NLS-1$
+									System.out.println(e.binding.toString());
+								}
+								// if null then we found a problem in the selection node
+								selectFrom(e.binding, parsedUnit, e.isDeclaration);
+							}
+						}
+					}
+				}
+			}
+			// only reaches here if no selection could be derived from the parsed tree
+			// thus use the selected source and perform a textual type search
+			if (!this.acceptedAnswer) {
+				this.nameEnvironment.findTypes(this.selectedIdentifier, false, false, IJavaSearchConstants.TYPE, this);
+
+				// accept qualified types only if no unqualified type was accepted
+				if(!this.acceptedAnswer) {
+					acceptQualifiedTypes();
+					
+					// accept types from all the workspace only if no type was found in the project scope
+					if (this.noProposal) {
+						findAllTypes(this.selectedIdentifier);
+					}
+				}
+			}
+			if(this.noProposal && this.problem != null) {
+				this.requestor.acceptError(this.problem);
+			}
+		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
+			if(DEBUG) {
+				System.out.println("Exception caught by SelectionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+			if(DEBUG) {
+				System.out.println("Exception caught by SelectionEngine:"); //$NON-NLS-1$
+				e.printStackTrace(System.out);
+			}
+		} finally {
+			reset(true);
+		}
+	}
+
+	private void selectMemberTypeFromImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref, boolean staticOnly) {
+		int fieldLength = lastToken.length;
+		ReferenceBinding[] memberTypes = ref.memberTypes();
+		next : for (int j = 0; j < memberTypes.length; j++) {
+			ReferenceBinding memberType = memberTypes[j];
+
+			if (fieldLength > memberType.sourceName.length)
+				continue next;
+
+			if (staticOnly && !memberType.isStatic())
+				continue next;
+
+			if (!CharOperation.equals(lastToken, memberType.sourceName, true))
+				continue next;
+
+			selectFrom(memberType, parsedUnit, false);
+		}
+	}
+
+	private void selectStaticFieldFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
+		int fieldLength = lastToken.length;
+		FieldBinding[] fields = ref.availableFields();
+		next : for (int j = 0; j < fields.length; j++) {
+			FieldBinding field = fields[j];
+
+			if (fieldLength > field.name.length)
+				continue next;
+
+			if (field.isSynthetic())
+				continue next;
+
+			if (!field.isStatic())
+				continue next;
+
+			if (!CharOperation.equals(lastToken, field.name, true))
+				continue next;
+
+			selectFrom(field, parsedUnit, false);
+		}
+	}
+
+	private void selectStaticMethodFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
+		int methodLength = lastToken.length;
+		MethodBinding[] methods = ref.availableMethods();
+		next : for (int j = 0; j < methods.length; j++) {
+			MethodBinding method = methods[j];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (!method.isStatic()) continue next;
+
+			if (methodLength > method.selector.length)
+				continue next;
+
+			if (!CharOperation.equals(lastToken, method.selector, true))
+				continue next;
+
+			selectFrom(method, parsedUnit, false);
+		}
+	}
+
+	private void selectFrom(Binding binding, CompilationUnitDeclaration parsedUnit, boolean isDeclaration) {
+		if(binding instanceof TypeVariableBinding) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) binding;
+			Binding enclosingElement = typeVariableBinding.declaringElement;
+			this.noProposal = false;
+
+			if(enclosingElement instanceof SourceTypeBinding) {
+				SourceTypeBinding enclosingType = (SourceTypeBinding) enclosingElement;
+				if (isLocal(enclosingType) && this.requestor instanceof SelectionRequestor) {
+					((SelectionRequestor)this.requestor).acceptLocalTypeParameter(typeVariableBinding);
+				} else {
+					this.requestor.acceptTypeParameter(
+						enclosingType.qualifiedPackageName(),
+						enclosingType.qualifiedSourceName(),
+						typeVariableBinding.sourceName(),
+						false,
+						this.actualSelectionStart,
+						this.actualSelectionEnd);
+				}
+			} else if(enclosingElement instanceof MethodBinding) {
+				MethodBinding enclosingMethod = (MethodBinding) enclosingElement;
+				if (isLocal(enclosingMethod.declaringClass) && this.requestor instanceof SelectionRequestor) {
+					((SelectionRequestor)this.requestor).acceptLocalMethodTypeParameter(typeVariableBinding);
+				} else {
+					this.requestor.acceptMethodTypeParameter(
+						enclosingMethod.declaringClass.qualifiedPackageName(),
+						enclosingMethod.declaringClass.qualifiedSourceName(),
+						enclosingMethod.isConstructor()
+								? enclosingMethod.declaringClass.sourceName()
+								: enclosingMethod.selector,
+						enclosingMethod.sourceStart(),
+						enclosingMethod.sourceEnd(),
+						typeVariableBinding.sourceName(),
+						false,
+						this.actualSelectionStart,
+						this.actualSelectionEnd);
+				}
+			}
+			this.acceptedAnswer = true;
+		} else if (binding instanceof ReferenceBinding) {
+			ReferenceBinding typeBinding = (ReferenceBinding) binding;
+			if(typeBinding instanceof ProblemReferenceBinding) {
+				TypeBinding closestMatch = typeBinding.closestMatch();
+				if (closestMatch instanceof ReferenceBinding) {
+					typeBinding = (ReferenceBinding) closestMatch;
+				} else {
+					typeBinding = null;
+				}
+			}
+			if (typeBinding == null) return;
+			if (isLocal(typeBinding) && this.requestor instanceof SelectionRequestor) {
+				this.noProposal = false;
+				((SelectionRequestor)this.requestor).acceptLocalType(typeBinding);
+			} else {
+				this.noProposal = false;
+
+				this.requestor.acceptType(
+					typeBinding.qualifiedPackageName(),
+					typeBinding.qualifiedSourceName(),
+					typeBinding.modifiers,
+					false,
+					typeBinding.computeUniqueKey(),
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+			}
+			this.acceptedAnswer = true;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = getCorrectMethodBinding((MethodBinding) binding);
+			this.noProposal = false;
+
+			boolean isValuesOrValueOf = false;
+			if(binding instanceof SyntheticMethodBinding) {
+				SyntheticMethodBinding syntheticMethodBinding = (SyntheticMethodBinding) binding;
+				if(syntheticMethodBinding.purpose  == SyntheticMethodBinding.EnumValues
+						|| syntheticMethodBinding.purpose  == SyntheticMethodBinding.EnumValueOf) {
+					isValuesOrValueOf =  true;
+				}
+			}
+
+			if(!isValuesOrValueOf && !methodBinding.isSynthetic()) {
+				TypeBinding[] parameterTypes = methodBinding.original().parameters;
+				int length = parameterTypes.length;
+				char[][] parameterPackageNames = new char[length][];
+				char[][] parameterTypeNames = new char[length][];
+				String[] parameterSignatures = new String[length];
+				for (int i = 0; i < length; i++) {
+					parameterPackageNames[i] = parameterTypes[i].qualifiedPackageName();
+					parameterTypeNames[i] = parameterTypes[i].qualifiedSourceName();
+					parameterSignatures[i] = new String(getSignature(parameterTypes[i])).replace('/', '.');
+				}
+
+				TypeVariableBinding[] typeVariables = methodBinding.original().typeVariables;
+				length = typeVariables == null ? 0 : typeVariables.length;
+				char[][] typeParameterNames = new char[length][];
+				char[][][] typeParameterBoundNames = new char[length][][];
+				for (int i = 0; i < length; i++) {
+					TypeVariableBinding typeVariable = typeVariables[i];
+					typeParameterNames[i] = typeVariable.sourceName;
+					if (typeVariable.firstBound == null) {
+						typeParameterBoundNames[i] = new char[0][];
+					} else if (typeVariable.firstBound == typeVariable.superclass) {
+						int boundCount = 1 + (typeVariable.superInterfaces == null ? 0 : typeVariable.superInterfaces.length);
+						typeParameterBoundNames[i] = new char[boundCount][];
+						typeParameterBoundNames[i][0] = typeVariable.superclass.sourceName;
+						for (int j = 1; j < boundCount; j++) {
+							typeParameterBoundNames[i][j] = typeVariables[i].superInterfaces[j - 1].sourceName;
+						}
+					} else {
+						int boundCount = typeVariable.superInterfaces == null ? 0 : typeVariable.superInterfaces.length;
+						typeParameterBoundNames[i] = new char[boundCount][];
+						for (int j = 0; j < boundCount; j++) {
+							typeParameterBoundNames[i][j] = typeVariables[i].superInterfaces[j].sourceName;
+						}
+					}
+				}
+
+				ReferenceBinding declaringClass = methodBinding.declaringClass;
+				if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
+					((SelectionRequestor)this.requestor).acceptLocalMethod(methodBinding);
+				} else {
+					this.requestor.acceptMethod(
+						declaringClass.qualifiedPackageName(),
+						declaringClass.qualifiedSourceName(),
+						declaringClass.enclosingType() == null ? null : new String(getSignature(declaringClass.enclosingType())),
+						methodBinding.isConstructor()
+							? declaringClass.sourceName()
+							: methodBinding.selector,
+						parameterPackageNames,
+						parameterTypeNames,
+						parameterSignatures,
+						typeParameterNames,
+						typeParameterBoundNames,
+						methodBinding.isConstructor(),
+						isDeclaration,
+						methodBinding.computeUniqueKey(),
+						this.actualSelectionStart,
+						this.actualSelectionEnd);
+				}
+			}
+			this.acceptedAnswer = true;
+		} else if (binding instanceof FieldBinding) {
+			FieldBinding fieldBinding = (FieldBinding) binding;
+			ReferenceBinding declaringClass = fieldBinding.declaringClass;
+			if (declaringClass != null) { // arraylength
+				this.noProposal = false;
+				if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
+					((SelectionRequestor)this.requestor).acceptLocalField(fieldBinding);
+				} else {
+					// if the binding is a problem field binding, we want to make sure
+					// we can retrieve the closestMatch if the problem reason is NotVisible
+					FieldBinding currentFieldBinding = fieldBinding;
+					while (currentFieldBinding instanceof ProblemFieldBinding) {
+						ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) currentFieldBinding;
+						if (problemFieldBinding.problemId() == ProblemReasons.NotVisible) {
+							currentFieldBinding = problemFieldBinding.closestMatch;
+						} else {
+							currentFieldBinding = null;
+						}
+					}
+					char[] fieldName = null;
+					char[] key = null;
+					if (currentFieldBinding != null) {
+						fieldName = currentFieldBinding.name;
+						key = currentFieldBinding.computeUniqueKey();
+					} else {
+						fieldName = fieldBinding.name;
+						key = fieldBinding.computeUniqueKey();
+					}
+					this.requestor.acceptField(
+						declaringClass.qualifiedPackageName(),
+						declaringClass.qualifiedSourceName(),
+						fieldName,
+						false,
+						key,
+						this.actualSelectionStart,
+						this.actualSelectionEnd);
+				}
+				this.acceptedAnswer = true;
+			}
+		} else if (binding instanceof LocalVariableBinding) {
+			if (this.requestor instanceof SelectionRequestor) {
+				((SelectionRequestor)this.requestor).acceptLocalVariable((LocalVariableBinding)binding);
+				this.acceptedAnswer = true;
+			} else {
+				// open on the type of the variable
+				selectFrom(((LocalVariableBinding) binding).type, parsedUnit, false);
+			}
+		} else if (binding instanceof ArrayBinding) {
+			selectFrom(((ArrayBinding) binding).leafComponentType, parsedUnit, false);
+			// open on the type of the array
+		} else if (binding instanceof PackageBinding) {
+			PackageBinding packageBinding = (PackageBinding) binding;
+			this.noProposal = false;
+			this.requestor.acceptPackage(packageBinding.readableName());
+			this.acceptedAnswer = true;
+		} else if(binding instanceof BaseTypeBinding) {
+			this.acceptedAnswer = true;
+		}
+	}
+	/*
+	 * Checks if a local declaration got selected in this method/initializer/field.
+	 */
+	private void selectLocalDeclaration(ASTNode node) {
+		// the selected identifier is not identical to the parser one (equals but not identical),
+		// for traversing the parse tree, the parser assist identifier is necessary for identitiy checks
+		final char[] assistIdentifier = getParser().assistIdentifier();
+		if (assistIdentifier == null) return;
+
+		class Visitor extends ASTVisitor {
+			public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+				if (constructorDeclaration.selector == assistIdentifier){
+					if (constructorDeclaration.binding != null) {
+						throw new SelectionNodeFound(constructorDeclaration.binding);
+					} else {
+						if (constructorDeclaration.scope != null) {
+							throw new SelectionNodeFound(new MethodBinding(constructorDeclaration.modifiers, constructorDeclaration.selector, null, null, null, constructorDeclaration.scope.referenceType().binding));
+						}
+					}
+				}
+				return true;
+			}
+			public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+				if (fieldDeclaration.name == assistIdentifier){
+					throw new SelectionNodeFound(fieldDeclaration.binding);
+				}
+				return true;
+			}
+			public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+				if (localTypeDeclaration.name == assistIdentifier) {
+					throw new SelectionNodeFound(localTypeDeclaration.binding);
+				}
+				return true;
+			}
+			public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+				if (memberTypeDeclaration.name == assistIdentifier) {
+					throw new SelectionNodeFound(memberTypeDeclaration.binding);
+				}
+				return true;
+			}
+			public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+				if (methodDeclaration.selector == assistIdentifier){
+					if (methodDeclaration.binding != null) {
+						throw new SelectionNodeFound(methodDeclaration.binding);
+					} else {
+						if (methodDeclaration.scope != null) {
+							throw new SelectionNodeFound(new MethodBinding(methodDeclaration.modifiers, methodDeclaration.selector, null, null, null, methodDeclaration.scope.referenceType().binding));
+						}
+					}
+				}
+				return true;
+			}
+			public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+				if (typeDeclaration.name == assistIdentifier) {
+					throw new SelectionNodeFound(typeDeclaration.binding);
+				}
+				return true;
+			}
+			public boolean visit(TypeParameter typeParameter, BlockScope scope) {
+				if (typeParameter.name == assistIdentifier) {
+					throw new SelectionNodeFound(typeParameter.binding);
+				}
+				return true;
+			}
+			public boolean visit(TypeParameter typeParameter, ClassScope scope) {
+				if (typeParameter.name == assistIdentifier) {
+					throw new SelectionNodeFound(typeParameter.binding);
+				}
+				return true;
+			}
+		}
+
+		if (node instanceof AbstractMethodDeclaration) {
+			((AbstractMethodDeclaration)node).traverse(new Visitor(), (ClassScope)null);
+		} else {
+			((FieldDeclaration)node).traverse(new Visitor(), (MethodScope)null);
+		}
+	}
+
+	/**
+	 * Asks the engine to compute the selection of the given type
+	 * from the given context
+	 *
+	 *  @param typeName char[]
+	 *      a type name which is to be resolved in the context of a compilation unit.
+	 *		NOTE: the type name is supposed to be correctly reduced (no whitespaces, no unicodes left)
+	 *
+	 *  @param context org.eclipse.jdt.core.IType
+	 *      the context in which code assist is invoked.
+	 */
+	public void selectType(char[] typeName, IType context) throws JavaModelException {
+		try {
+			this.acceptedAnswer = false;
+
+			// only the type erasure are returned by IType.resolvedType(...)
+			if (CharOperation.indexOf('<', typeName) != -1) {
+				char[] typeSig = Signature.createCharArrayTypeSignature(typeName, false/*not resolved*/);
+				typeSig = Signature.getTypeErasure(typeSig);
+				typeName = Signature.toCharArray(typeSig);
+			}
+
+			// find the outer most type
+			IType outerType = context;
+			IType parent = context.getDeclaringType();
+			while (parent != null) {
+				outerType = parent;
+				parent = parent.getDeclaringType();
+			}
+
+			// compute parse tree for this most outer type
+			CompilationUnitDeclaration parsedUnit = null;
+			TypeDeclaration typeDeclaration = null;
+			org.eclipse.jdt.core.ICompilationUnit cu = context.getCompilationUnit();
+			if (cu != null) {
+			 	IType[] topLevelTypes = cu.getTypes();
+			 	int length = topLevelTypes.length;
+			 	SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
+			 	for (int i = 0; i < length; i++) {
+					topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
+				}
+				ISourceType outerTypeInfo = (ISourceType) ((SourceType) outerType).getElementInfo();
+				CompilationResult result = new CompilationResult(outerTypeInfo.getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
+				int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;
+				if (context.isAnonymous() || context.isLocal())
+					flags |= SourceTypeConverter.LOCAL_TYPE;
+				parsedUnit =
+					SourceTypeConverter.buildCompilationUnit(
+							topLevelInfos,
+							flags,
+							this.parser.problemReporter(),
+							result);
+				if (parsedUnit != null && parsedUnit.types != null) {
+					if(DEBUG) {
+						System.out.println("SELECTION - Diet AST :"); //$NON-NLS-1$
+						System.out.println(parsedUnit.toString());
+					}
+					// find the type declaration that corresponds to the original source type
+					typeDeclaration = new ASTNodeFinder(parsedUnit).findType(context);
+				}
+			} else { // binary type
+				ClassFile classFile = (ClassFile) context.getClassFile();
+				ClassFileReader reader = (ClassFileReader) classFile.getBinaryTypeInfo((IFile) classFile.resource(), false/*don't fully initialize so as to keep constant pool (used below)*/);
+				CompilationResult result = new CompilationResult(reader.getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
+				parsedUnit = new CompilationUnitDeclaration(this.parser.problemReporter(), result, 0);
+				HashSetOfCharArrayArray typeNames = new HashSetOfCharArrayArray();
+
+				BinaryTypeConverter converter = new BinaryTypeConverter(this.parser.problemReporter(), result, typeNames);
+				typeDeclaration = converter.buildTypeDeclaration(context, parsedUnit);
+				parsedUnit.imports = converter.buildImports(reader);
+			}
+
+			if (typeDeclaration != null) {
+
+				// add fake field with the type we're looking for
+				// note: since we didn't ask for fields above, there is no field defined yet
+				FieldDeclaration field = new FieldDeclaration();
+				int dot;
+				if ((dot = CharOperation.lastIndexOf('.', typeName)) == -1) {
+					this.selectedIdentifier = typeName;
+					field.type = new SelectionOnSingleTypeReference(typeName, -1);
+					// position not used
+				} else {
+					char[][] previousIdentifiers = CharOperation.splitOn('.', typeName, 0, dot);
+					char[] selectionIdentifier =
+						CharOperation.subarray(typeName, dot + 1, typeName.length);
+					this.selectedIdentifier = selectionIdentifier;
+					field.type =
+						new SelectionOnQualifiedTypeReference(
+							previousIdentifiers,
+							selectionIdentifier,
+							new long[previousIdentifiers.length + 1]);
+				}
+				field.name = "<fakeField>".toCharArray(); //$NON-NLS-1$
+				typeDeclaration.fields = new FieldDeclaration[] { field };
+
+				// build bindings
+				this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+				if ((this.unitScope = parsedUnit.scope) != null) {
+					try {
+						// build fields
+						// note: this builds fields only in the parsed unit (the buildFieldsAndMethods flag is not passed along)
+						this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+
+						// resolve
+						parsedUnit.scope.faultInTypes();
+						parsedUnit.resolve();
+					} catch (SelectionNodeFound e) {
+						if (e.binding != null) {
+							if(DEBUG) {
+								System.out.println("SELECTION - Selection binding :"); //$NON-NLS-1$
+								System.out.println(e.binding.toString());
+							}
+							// if null then we found a problem in the selection node
+							selectFrom(e.binding, parsedUnit, e.isDeclaration);
+						}
+					}
+				}
+			}
+			if(this.noProposal && this.problem != null) {
+				this.requestor.acceptError(this.problem);
+			}
+		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+		} finally {
+			reset(true);
+		}
+	}
+
+	// Check if a declaration got selected in this unit
+	private boolean selectDeclaration(CompilationUnitDeclaration compilationUnit){
+
+		// the selected identifier is not identical to the parser one (equals but not identical),
+		// for traversing the parse tree, the parser assist identifier is necessary for identitiy checks
+		char[] assistIdentifier = getParser().assistIdentifier();
+		if (assistIdentifier == null) return false;
+
+		ImportReference currentPackage = compilationUnit.currentPackage;
+		char[] packageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
+		// iterate over the types
+		TypeDeclaration[] types = compilationUnit.types;
+		for (int i = 0, length = types == null ? 0 : types.length; i < length; i++){
+			if(selectDeclaration(types[i], assistIdentifier, packageName))
+				return true;
+		}
+		return false;
+	}
+
+	// Check if a declaration got selected in this type
+	private boolean selectDeclaration(TypeDeclaration typeDeclaration, char[] assistIdentifier, char[] packageName){
+
+		if (typeDeclaration.name == assistIdentifier){
+			char[] qualifiedSourceName = null;
+
+			TypeDeclaration enclosingType = typeDeclaration;
+			while(enclosingType != null) {
+				qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
+				enclosingType = enclosingType.enclosingType;
+			}
+			char[] uniqueKey = typeDeclaration.binding != null ? typeDeclaration.binding.computeUniqueKey() : null;
+
+			this.requestor.acceptType(
+				packageName,
+				qualifiedSourceName,
+				typeDeclaration.modifiers,
+				true,
+				uniqueKey,
+				this.actualSelectionStart,
+				this.actualSelectionEnd);
+
+			this.noProposal = false;
+			return true;
+		}
+		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+		for (int i = 0, length = memberTypes == null ? 0 : memberTypes.length; i < length; i++){
+			if(selectDeclaration(memberTypes[i], assistIdentifier, packageName))
+				return true;
+		}
+		FieldDeclaration[] fields = typeDeclaration.fields;
+		for (int i = 0, length = fields == null ? 0 : fields.length; i < length; i++){
+			if (fields[i].name == assistIdentifier){
+				char[] qualifiedSourceName = null;
+
+				TypeDeclaration enclosingType = typeDeclaration;
+				while(enclosingType != null) {
+					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
+					enclosingType = enclosingType.enclosingType;
+				}
+				FieldDeclaration field = fields[i];
+				this.requestor.acceptField(
+					packageName,
+					qualifiedSourceName,
+					field.name,
+					true,
+					field.binding != null ? field.binding.computeUniqueKey() : null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+
+				this.noProposal = false;
+				return true;
+			}
+		}
+		AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+		for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++){
+			AbstractMethodDeclaration method = methods[i];
+
+			if (method.selector == assistIdentifier){
+				char[] qualifiedSourceName = null;
+
+				TypeDeclaration enclosingType = typeDeclaration;
+				while(enclosingType != null) {
+					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
+					enclosingType = enclosingType.enclosingType;
+				}
+
+				this.requestor.acceptMethod(
+					packageName,
+					qualifiedSourceName,
+					null, // SelectionRequestor does not need of declaring type signature for method declaration
+					method.selector,
+					null, // SelectionRequestor does not need of parameters type for method declaration
+					null, // SelectionRequestor does not need of parameters type for method declaration
+					null, // SelectionRequestor does not need of parameters type for method declaration
+					null, // SelectionRequestor does not need of type parameters name for method declaration
+					null, // SelectionRequestor does not need of type parameters bounds for method declaration
+					method.isConstructor(),
+					true,
+					method.binding != null ? method.binding.computeUniqueKey() : null,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+
+				this.noProposal = false;
+				return true;
+			}
+
+			TypeParameter[] methodTypeParameters = method.typeParameters();
+			for (int j = 0, length2 = methodTypeParameters == null ? 0 : methodTypeParameters.length; j < length2; j++){
+				TypeParameter methodTypeParameter = methodTypeParameters[j];
+
+				if(methodTypeParameter.name == assistIdentifier) {
+					char[] qualifiedSourceName = null;
+
+					TypeDeclaration enclosingType = typeDeclaration;
+					while(enclosingType != null) {
+						qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
+						enclosingType = enclosingType.enclosingType;
+					}
+
+					this.requestor.acceptMethodTypeParameter(
+						packageName,
+						qualifiedSourceName,
+						method.selector,
+						method.sourceStart,
+						method.sourceEnd,
+						methodTypeParameter.name,
+						true,
+						this.actualSelectionStart,
+						this.actualSelectionEnd);
+
+					this.noProposal = false;
+					return true;
+				}
+			}
+		}
+
+		TypeParameter[] typeParameters = typeDeclaration.typeParameters;
+		for (int i = 0, length = typeParameters == null ? 0 : typeParameters.length; i < length; i++){
+			TypeParameter typeParameter = typeParameters[i];
+			if(typeParameter.name == assistIdentifier) {
+				char[] qualifiedSourceName = null;
+
+				TypeDeclaration enclosingType = typeDeclaration;
+				while(enclosingType != null) {
+					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
+					enclosingType = enclosingType.enclosingType;
+				}
+
+				this.requestor.acceptTypeParameter(
+					packageName,
+					qualifiedSourceName,
+					typeParameter.name,
+					true,
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
+
+				this.noProposal = false;
+				return true;
+			}
+		}
+
+		return false;
+	}
+	
+	/*
+	 * Returns the correct method binding according to whether the selection is on the method declaration
+	 * or on the inheritDoc tag in its javadoc.
+	 */
+	private MethodBinding getCorrectMethodBinding(MethodBinding binding) {
+		if (this.parser.javadocParser instanceof SelectionJavadocParser) {
+			if (((SelectionJavadocParser)this.parser.javadocParser).inheritDocTagSelected){
+				try {
+					Object res = findMethodWithAttachedDocInHierarchy(binding);
+					if (res instanceof MethodBinding) {
+						return (MethodBinding) res;
+					}
+				} catch (JavaModelException e) {
+					return null;
+				}
+			}
+		}
+		return binding;
+	}
+	
+	protected MethodBinding findOverriddenMethodInType(ReferenceBinding overriddenType, MethodBinding overriding) throws JavaModelException {
+		if (overriddenType == null)
+			return null;
+		MethodBinding[] overriddenMethods= overriddenType.availableMethods();
+		LookupEnvironment lookupEnv = this.lookupEnvironment;
+		if (lookupEnv != null && overriddenMethods != null) {
+			for (int i= 0; i < overriddenMethods.length; i++) {
+				if (lookupEnv.methodVerifier().isMethodSubsignature(overriding, overriddenMethods[i])) {
+					return overriddenMethods[i];
+				}
+			}
+		}
+		return null;
+	}
+	
+	private Object findMethodWithAttachedDocInHierarchy(final MethodBinding method) throws JavaModelException {
+		ReferenceBinding type= method.declaringClass;
+		final SelectionRequestor requestor1 = (SelectionRequestor) this.requestor;
+		return new InheritDocVisitor() {
+			public Object visit(ReferenceBinding currType) throws JavaModelException {
+				MethodBinding overridden =  findOverriddenMethodInType(currType, method);
+				if (overridden == null)
+					return InheritDocVisitor.CONTINUE;
+				TypeBinding args[] = overridden.parameters;
+				String names[] = new String[args.length];
+				for (int i = 0; i < args.length; i++) {
+					names[i] = Signature.createTypeSignature(args[i].sourceName(), false);
+				}
+				IMember member = (IMember) requestor1.findMethodFromBinding(overridden, names, overridden.declaringClass);
+				if (member == null)
+					return InheritDocVisitor.CONTINUE;
+				if (member.getAttachedJavadoc(null) != null ) {  
+					// for binary methods with attached javadoc and no source attached
+					return overridden;
+				}
+				IOpenable openable = member.getOpenable();
+				if (openable == null)
+					return InheritDocVisitor.CONTINUE;
+				IBuffer buf= openable.getBuffer();
+				if (buf == null) {
+					// no source attachment found. This method maybe the one. Stop.
+					return InheritDocVisitor.STOP_BRANCH;
+				}
+
+				ISourceRange javadocRange= member.getJavadocRange();
+				if (javadocRange == null)
+					return InheritDocVisitor.CONTINUE;	// this method doesn't have javadoc, continue to look.
+				String rawJavadoc= buf.getText(javadocRange.getOffset(), javadocRange.getLength());
+				if (rawJavadoc != null) {
+					return overridden;
+				}
+				return InheritDocVisitor.CONTINUE;
+			}
+		}.visitInheritDoc(type);
+	}
+	
+	/**
+	 * Implements the "Algorithm for Inheriting Method Comments" as specified for
+	 * <a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javadoc.html#inheritingcomments">1.6</a>.
+	 *
+	 * <p>
+	 * Unfortunately, the implementation is broken in Javadoc implementations since 1.5, see
+	 * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6376959">Sun's bug</a>.
+	 * </p>
+	 *
+	 * <p>
+	 * We adhere to the spec.
+	 * </p>
+	 */
+	static abstract class InheritDocVisitor {
+		public static final Object STOP_BRANCH= new Object() {
+			public String toString() { return "STOP_BRANCH"; } //$NON-NLS-1$
+		};
+		public static final Object CONTINUE= new Object() {
+			public String toString() { return "CONTINUE"; } //$NON-NLS-1$
+		};
+
+		/**
+		 * Visits a type and decides how the visitor should proceed.
+		 *
+		 * @param currType the current type
+		 * @return <ul>
+		 *         <li>{@link #STOP_BRANCH} to indicate that no Javadoc has been found and visiting
+		 *         super types should stop here</li>
+		 *         <li>{@link #CONTINUE} to indicate that no Javadoc has been found and visiting
+		 *         super types should continue</li>
+		 *         <li>an {@link Object} or <code>null</code>, to indicate that visiting should be
+		 *         cancelled immediately. The returned value is the result of
+		 *         {@link #visitInheritDoc(ReferenceBinding)}</li>
+		 *         </ul>
+		 * @throws JavaModelException unexpected problem
+		 * @see #visitInheritDoc(ReferenceBinding)
+		 */
+		public abstract Object visit(ReferenceBinding currType) throws JavaModelException;
+
+		/**
+		 * Visits the super types of the given <code>currentType</code>.
+		 *
+		 * @param currentType the starting type
+		 * @return the result from a call to {@link #visit(ReferenceBinding)}, or <code>null</code> if none of
+		 *         the calls returned a result
+		 * @throws JavaModelException unexpected problem
+		 */
+		public Object visitInheritDoc(ReferenceBinding currentType) throws JavaModelException {
+			ArrayList visited= new ArrayList();
+			visited.add(currentType);
+			Object result= visitInheritDocInterfaces(visited, currentType);
+			if (result != InheritDocVisitor.CONTINUE)
+				return result;
+
+			ReferenceBinding superClass= currentType.superclass();
+
+			while (superClass != null && ! visited.contains(superClass)) {
+				result= visit(superClass);
+				if (result == InheritDocVisitor.STOP_BRANCH) {
+					return null;
+				} else if (result == InheritDocVisitor.CONTINUE) {
+					visited.add(superClass);
+					result= visitInheritDocInterfaces(visited, superClass);
+					if (result != InheritDocVisitor.CONTINUE)
+						return result;
+					else
+						superClass= superClass.superclass();
+				} else {
+					return result;
+				}
+			}
+
+			return null;
+		}
+
+		/**
+		 * Visits the super interfaces of the given type in the given hierarchy, thereby skipping already visited types.
+		 * 
+		 * @param visited set of visited types
+		 * @param currentType type whose super interfaces should be visited
+		 * @return the result, or {@link #CONTINUE} if no result has been found
+		 * @throws JavaModelException unexpected problem
+		 */
+		private Object visitInheritDocInterfaces(ArrayList visited, ReferenceBinding currentType) throws JavaModelException {
+			ArrayList toVisitChildren= new ArrayList();
+			ReferenceBinding[] superInterfaces= currentType.superInterfaces();
+			for (int i= 0; i < superInterfaces.length; i++) {
+				ReferenceBinding superInterface= superInterfaces[i];
+				if (visited.contains(superInterface))
+					continue;
+				visited.add(superInterface);
+				Object result= visit(superInterface);
+				if (result == InheritDocVisitor.STOP_BRANCH) {
+					//skip
+				} else if (result == InheritDocVisitor.CONTINUE) {
+					toVisitChildren.add(superInterface);
+				} else {
+					return result;
+				}
+			}
+			for (Iterator iter= toVisitChildren.iterator(); iter.hasNext(); ) {
+				ReferenceBinding child= (ReferenceBinding) iter.next();
+				Object result= visitInheritDocInterfaces(visited, child);
+				if (result != InheritDocVisitor.CONTINUE)
+					return result;
+			}
+			return InheritDocVisitor.CONTINUE;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
new file mode 100644
index 0000000..3f4004e
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import java.util.Stack;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class ThrownExceptionFinder extends ASTVisitor {
+
+	private SimpleSet thrownExceptions;
+	private Stack exceptionsStack;
+	private SimpleSet caughtExceptions;
+	private SimpleSet discouragedExceptions;
+
+	/**
+	 * Finds the thrown exceptions minus the ones that are already caught in previous catch blocks.
+	 * Exception is already caught even if its super type is being caught. Also computes, separately,
+	 * a list comprising of (a)those exceptions that have been caught already and (b)those exceptions that are thrown
+	 * by the method and whose super type has been caught already. 
+	 * @param tryStatement
+	 * @param scope
+	 */
+	public void processThrownExceptions(TryStatement tryStatement, BlockScope scope) {
+		this.thrownExceptions = new SimpleSet();
+		this.exceptionsStack = new Stack();
+		this.caughtExceptions = new SimpleSet();
+		this.discouragedExceptions = new SimpleSet();
+		tryStatement.traverse(this, scope);
+		removeCaughtExceptions(tryStatement, true /*remove unchecked exceptions this time*/);
+	}
+
+	private void acceptException(ReferenceBinding binding) {
+		if (binding != null && binding.isValidBinding()) {
+			this.thrownExceptions.add(binding);
+		}
+	}
+
+	public void endVisit(MessageSend messageSend, BlockScope scope) {
+		if (messageSend.binding != null) {
+			endVisitMethodInvocation(messageSend.binding);
+		}
+		super.endVisit(messageSend, scope);
+	}
+
+	public void endVisit(AllocationExpression allocationExpression, BlockScope scope) {
+		if (allocationExpression.binding != null) {
+			endVisitMethodInvocation(allocationExpression.binding);
+		}
+		super.endVisit(allocationExpression, scope);
+	}
+
+	public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
+		acceptException((ReferenceBinding)throwStatement.exception.resolvedType);
+		super.endVisit(throwStatement, scope);
+	}
+
+
+	private void endVisitMethodInvocation(MethodBinding methodBinding) {
+		ReferenceBinding[] thrownExceptionBindings = methodBinding.thrownExceptions;
+		int length = thrownExceptionBindings == null ? 0 : thrownExceptionBindings.length;
+		for (int i = 0; i < length; i++) {
+			acceptException(thrownExceptionBindings[i]);
+		}
+	}
+
+
+	/**
+	 * Returns all the already caught exceptions in catch blocks, found by the call to
+	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}
+	 * @return Returns an array of those exceptions that have been caught already in previous catch or
+	 * multi-catch blocks of the same try block. (Exceptions caught in inner try-catches are obtained via
+	 * {@link ThrownExceptionFinder#getDiscouragedExceptions()}.
+	 */
+	public ReferenceBinding[] getAlreadyCaughtExceptions() {
+		ReferenceBinding[] allCaughtExceptions = new ReferenceBinding[this.caughtExceptions.elementSize];
+		this.caughtExceptions.asArray(allCaughtExceptions);
+		return allCaughtExceptions;
+	}
+	
+	/**
+	 * Returns all the thrown exceptions minus the ones that are already caught in previous catch blocks
+	 * (of the same try), found by the call to 
+	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}.
+	 * @return Returns an array of thrown exceptions that are still not caught in any catch block.
+	 */
+	public ReferenceBinding[] getThrownUncaughtExceptions() {
+		ReferenceBinding[] result = new ReferenceBinding[this.thrownExceptions.elementSize];
+		this.thrownExceptions.asArray(result);
+		return result;
+	}
+	
+	/**
+	 * Returns all exceptions that are discouraged to use because (a) they are already caught in some inner try-catch, 
+	 * or (b) their super exception has already been caught.
+	 * @return all discouraged exceptions
+	 */
+	public ReferenceBinding[] getDiscouragedExceptions() {
+		ReferenceBinding[] allDiscouragedExceptions = new ReferenceBinding[this.discouragedExceptions.elementSize];
+		this.discouragedExceptions.asArray(allDiscouragedExceptions);
+		return allDiscouragedExceptions;
+	}
+	public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+		return visitType(typeDeclaration);
+	}
+
+	public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+		return visitType(memberTypeDeclaration);
+	}
+
+	public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+		return visitType(localTypeDeclaration);
+	}
+
+	private boolean visitType(TypeDeclaration typeDeclaration) {
+		return false;
+	}
+
+	public boolean visit(TryStatement tryStatement, BlockScope scope) {
+		this.exceptionsStack.push(this.thrownExceptions);
+		SimpleSet exceptionSet = new SimpleSet();
+		this.thrownExceptions = exceptionSet;
+		tryStatement.tryBlock.traverse(this, scope);
+
+		removeCaughtExceptions(tryStatement, false);
+
+		this.thrownExceptions = (SimpleSet)this.exceptionsStack.pop();
+
+		Object[] values = exceptionSet.values;
+		for (int i = 0; i < values.length; i++) {
+			if (values[i] != null) {
+				this.thrownExceptions.add(values[i]);
+			}
+		}
+
+		Block[] catchBlocks = tryStatement.catchBlocks;
+		int length = catchBlocks == null ? 0 : catchBlocks.length;
+		for (int i = 0; i < length; i++) {
+			catchBlocks[i].traverse(this, scope);
+		}
+		return false;
+	}
+	
+	private void removeCaughtExceptions(TryStatement tryStatement, boolean recordUncheckedCaughtExceptions) {
+		Argument[] catchArguments = tryStatement.catchArguments;
+		int length = catchArguments == null ? 0 : catchArguments.length;
+		for (int i = 0; i < length; i++) {
+			if (catchArguments[i].type instanceof UnionTypeReference) {
+				UnionTypeReference unionTypeReference = (UnionTypeReference) catchArguments[i].type;
+				TypeBinding caughtException;
+				for (int j = 0; j < unionTypeReference.typeReferences.length; j++) {
+					caughtException = unionTypeReference.typeReferences[j].resolvedType;
+					if ((caughtException instanceof ReferenceBinding) && caughtException.isValidBinding()) {	// might be null when its the completion node
+						if (recordUncheckedCaughtExceptions) {
+							// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
+							removeCaughtException((ReferenceBinding)caughtException);
+							this.caughtExceptions.add(caughtException);
+						} else {
+							// is in some inner try-catch. Discourage already caught checked exceptions
+							// from being proposed in an outer catch.
+							if (!caughtException.isUncheckedException(true)) {
+								this.discouragedExceptions.add(caughtException);
+							}
+						}
+					}
+				}
+			} else {
+				TypeBinding exception = catchArguments[i].type.resolvedType;
+				if ((exception instanceof ReferenceBinding) && exception.isValidBinding()) {
+					if (recordUncheckedCaughtExceptions) {
+						// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
+						removeCaughtException((ReferenceBinding)exception);
+						this.caughtExceptions.add(exception);
+					} else {
+						// is in some inner try-catch. Discourage already caught checked exceptions
+						// from being proposed in an outer catch
+						if (!exception.isUncheckedException(true)) {
+							this.discouragedExceptions.add(exception);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void removeCaughtException(ReferenceBinding caughtException) {
+		Object[] exceptions = this.thrownExceptions.values;
+		for (int i = 0; i < exceptions.length; i++) {
+			ReferenceBinding exception = (ReferenceBinding)exceptions[i];
+			if (exception != null) {
+				if (exception == caughtException) {
+					this.thrownExceptions.remove(exception);
+				} else if (caughtException.isSuperclassOf(exception)) {
+					// catching the sub-exception when super has been caught already will give an error
+					// so remove it from thrown list and lower the relevance for cases when it is found
+					// from searchAllTypes(..)
+					this.thrownExceptions.remove(exception);
+					this.discouragedExceptions.add(exception);
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java
new file mode 100644
index 0000000..c96ef3e
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/UnresolvedReferenceNameFinder.java
@@ -0,0 +1,552 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionParser;
+import org.eclipse.jdt.internal.codeassist.complete.CompletionScanner;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class UnresolvedReferenceNameFinder extends ASTVisitor {
+	private static final int MAX_LINE_COUNT = 100;
+	private static final int FAKE_BLOCKS_COUNT = 20;
+
+	public static interface UnresolvedReferenceNameRequestor {
+		public void acceptName(char[] name);
+	}
+
+	private UnresolvedReferenceNameRequestor requestor;
+
+	private CompletionEngine completionEngine;
+	private CompletionParser parser;
+	private CompletionScanner completionScanner;
+
+	private int parentsPtr;
+	private ASTNode[] parents;
+
+	private int potentialVariableNamesPtr;
+	private char[][] potentialVariableNames;
+	private int[] potentialVariableNameStarts;
+
+	private SimpleSetOfCharArray acceptedNames = new SimpleSetOfCharArray();
+
+	public UnresolvedReferenceNameFinder(CompletionEngine completionEngine) {
+		this.completionEngine = completionEngine;
+		this.parser = completionEngine.parser;
+		this.completionScanner = (CompletionScanner) this.parser.scanner;
+	}
+
+	private void acceptName(char[] name) {
+		// the null check is added to fix bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=166570
+		if (name == null) return;
+
+		if (!CharOperation.prefixEquals(this.completionEngine.completionToken, name, false /* ignore case */)
+				&& !(this.completionEngine.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionEngine.completionToken, name))) return;
+
+		if (this.acceptedNames.includes(name)) return;
+
+		this.acceptedNames.add(name);
+
+		// accept result
+		this.requestor.acceptName(name);
+	}
+
+	public void find(
+			char[] startWith,
+			Initializer initializer,
+			ClassScope scope,
+			int from,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		MethodDeclaration fakeMethod =
+			this.findAfter(startWith, scope, from, initializer.bodyEnd, MAX_LINE_COUNT, false, discouragedNames, nameRequestor);
+		if (fakeMethod != null) fakeMethod.traverse(this, scope);
+	}
+
+	public void find(
+			char[] startWith,
+			AbstractMethodDeclaration methodDeclaration,
+			int from,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		MethodDeclaration fakeMethod =
+			this.findAfter(startWith, methodDeclaration.scope, from, methodDeclaration.bodyEnd, MAX_LINE_COUNT, false, discouragedNames, nameRequestor);
+		if (fakeMethod != null) fakeMethod.traverse(this, methodDeclaration.scope.classScope());
+	}
+
+	public void findAfter(
+			char[] startWith,
+			Scope scope,
+			ClassScope classScope,
+			int from,
+			int to,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		MethodDeclaration fakeMethod =
+			this.findAfter(startWith, scope, from, to, MAX_LINE_COUNT / 2, true, discouragedNames, nameRequestor);
+		if (fakeMethod != null) fakeMethod.traverse(this, classScope);
+	}
+
+	private MethodDeclaration findAfter(
+			char[] startWith,
+			Scope s,
+			int from,
+			int to,
+			int maxLineCount,
+			boolean outsideEnclosingBlock,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		this.requestor = nameRequestor;
+
+		// reinitialize completion scanner to be usable as a normal scanner
+		this.completionScanner.cursorLocation = 0;
+
+		if (!outsideEnclosingBlock) {
+			// compute location of the end of the current block
+			this.completionScanner.resetTo(from + 1, to);
+			this.completionScanner.jumpOverBlock();
+
+			to = this.completionScanner.startPosition - 1;
+		}
+
+		int maxEnd =
+			this.completionScanner.getLineEnd(
+					Util.getLineNumber(from, this.completionScanner.lineEnds, 0, this.completionScanner.linePtr) + maxLineCount);
+
+		int end;
+		if (maxEnd < 0) {
+			end = to;
+		} else {
+			end = maxEnd < to ? maxEnd : to;
+		}
+
+		this.parser.startRecordingIdentifiers(from, end);
+
+		MethodDeclaration fakeMethod = this.parser.parseSomeStatements(
+				from,
+				end,
+				outsideEnclosingBlock ? FAKE_BLOCKS_COUNT : 0,
+				s.compilationUnitScope().referenceContext);
+
+		this.parser.stopRecordingIdentifiers();
+
+		if(!initPotentialNamesTables(discouragedNames)) return null;
+
+		this.parentsPtr = -1;
+		this.parents = new ASTNode[10];
+
+		return fakeMethod;
+	}
+
+	public void findBefore(
+			char[] startWith,
+			Scope scope,
+			ClassScope classScope,
+			int from,
+			int recordTo,
+			int parseTo,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		MethodDeclaration fakeMethod =
+			this.findBefore(startWith, scope, from, recordTo, parseTo, MAX_LINE_COUNT / 2, discouragedNames, nameRequestor);
+		if (fakeMethod != null) fakeMethod.traverse(this, classScope);
+	}
+
+	private MethodDeclaration findBefore(
+			char[] startWith,
+			Scope s,
+			int from,
+			int recordTo,
+			int parseTo,
+			int maxLineCount,
+			char[][] discouragedNames,
+			UnresolvedReferenceNameRequestor nameRequestor) {
+		this.requestor = nameRequestor;
+
+		// reinitialize completion scanner to be usable as a normal scanner
+		this.completionScanner.cursorLocation = 0;
+
+		int minStart =
+			this.completionScanner.getLineStart(
+					Util.getLineNumber(recordTo, this.completionScanner.lineEnds, 0, this.completionScanner.linePtr) - maxLineCount);
+
+		int start;
+		int fakeBlocksCount;
+		if (minStart <= from) {
+			start = from;
+			fakeBlocksCount = 0;
+		} else {
+			start = minStart;
+			fakeBlocksCount = FAKE_BLOCKS_COUNT;
+		}
+
+		this.parser.startRecordingIdentifiers(start, recordTo);
+
+		MethodDeclaration fakeMethod = this.parser.parseSomeStatements(
+				start,
+				parseTo,
+				fakeBlocksCount,
+				s.compilationUnitScope().referenceContext);
+
+		this.parser.stopRecordingIdentifiers();
+
+		if(!initPotentialNamesTables(discouragedNames)) return null;
+
+		this.parentsPtr = -1;
+		this.parents = new ASTNode[10];
+
+		return fakeMethod;
+	}
+
+	private boolean initPotentialNamesTables(char[][] discouragedNames) {
+		char[][] pvns = this.parser.potentialVariableNames;
+		int[] pvnss = this.parser.potentialVariableNameStarts;
+		int pvnsPtr = this.parser.potentialVariableNamesPtr;
+
+		if (pvnsPtr < 0) return false; // there is no potential names
+
+		// remove null and discouragedNames
+		int discouragedNamesCount = discouragedNames == null ? 0 : discouragedNames.length;
+		int j = -1;
+		next : for (int i = 0; i <= pvnsPtr; i++) {
+			char[] temp = pvns[i];
+
+			if (temp == null) continue next;
+
+			for (int k = 0; k < discouragedNamesCount; k++) {
+				if (CharOperation.equals(temp, discouragedNames[k], false)) {
+					continue next;
+				}
+			}
+
+			pvns[i] = null;
+			pvns[++j] = temp;
+			pvnss[j] = pvnss[i];
+		}
+		pvnsPtr = j;
+
+		if (pvnsPtr < 0) return false; // there is no potential names
+
+		this.potentialVariableNames = pvns;
+		this.potentialVariableNameStarts = pvnss;
+		this.potentialVariableNamesPtr = pvnsPtr;
+
+		return true;
+	}
+
+	private void popParent() {
+		this.parentsPtr--;
+	}
+	private void pushParent(ASTNode parent) {
+		int length = this.parents.length;
+		if (this.parentsPtr >= length - 1) {
+			System.arraycopy(this.parents, 0, this.parents = new ASTNode[length * 2], 0, length);
+		}
+		this.parents[++this.parentsPtr] = parent;
+	}
+
+	private ASTNode getEnclosingDeclaration() {
+		int i = this.parentsPtr;
+		while (i > -1) {
+			ASTNode parent = this.parents[i];
+			if (parent instanceof AbstractMethodDeclaration) {
+				return parent;
+			} else if (parent instanceof Initializer) {
+				return parent;
+			} else if (parent instanceof FieldDeclaration) {
+				return parent;
+			} else if (parent instanceof TypeDeclaration) {
+				return parent;
+			}
+			i--;
+		}
+		return null;
+	}
+
+	public boolean visit(Block block, BlockScope blockScope) {
+		ASTNode enclosingDeclaration = getEnclosingDeclaration();
+		removeLocals(block.statements, enclosingDeclaration.sourceStart, block.sourceEnd);
+		pushParent(block);
+		return true;
+	}
+
+	public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
+		if (((constructorDeclaration.bits & ASTNode.IsDefaultConstructor) == 0) && !constructorDeclaration.isClinit()) {
+			removeLocals(
+					constructorDeclaration.arguments,
+					constructorDeclaration.declarationSourceStart,
+					constructorDeclaration.declarationSourceEnd);
+			removeLocals(
+					constructorDeclaration.statements,
+					constructorDeclaration.declarationSourceStart,
+					constructorDeclaration.declarationSourceEnd);
+		}
+		pushParent(constructorDeclaration);
+		return true;
+	}
+
+	public boolean visit(FieldDeclaration fieldDeclaration, MethodScope methodScope) {
+		pushParent(fieldDeclaration);
+		return true;
+	}
+
+	public boolean visit(Initializer initializer, MethodScope methodScope) {
+		pushParent(initializer);
+		return true;
+	}
+
+	public boolean visit(MethodDeclaration methodDeclaration, ClassScope classScope) {
+		removeLocals(
+				methodDeclaration.arguments,
+				methodDeclaration.declarationSourceStart,
+				methodDeclaration.declarationSourceEnd);
+		removeLocals(
+				methodDeclaration.statements,
+				methodDeclaration.declarationSourceStart,
+				methodDeclaration.declarationSourceEnd);
+		pushParent(methodDeclaration);
+		return true;
+	}
+
+	public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope blockScope) {
+		removeFields(localTypeDeclaration);
+		pushParent(localTypeDeclaration);
+		return true;
+	}
+
+	public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+		removeFields(memberTypeDeclaration);
+		pushParent(memberTypeDeclaration);
+		return true;
+	}
+
+	public void endVisit(Block block, BlockScope blockScope) {
+		popParent();
+	}
+
+	public void endVisit(Argument argument, BlockScope blockScope) {
+		endVisitRemoved(argument.declarationSourceStart, argument.sourceEnd);
+	}
+
+	public void endVisit(Argument argument, ClassScope classScope) {
+		endVisitRemoved(argument.declarationSourceStart, argument.sourceEnd);
+	}
+
+	public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
+		if (((constructorDeclaration.bits & ASTNode.IsDefaultConstructor) == 0) && !constructorDeclaration.isClinit()) {
+			endVisitPreserved(constructorDeclaration.bodyStart, constructorDeclaration.bodyEnd);
+		}
+		popParent();
+	}
+
+	public void endVisit(FieldDeclaration fieldDeclaration, MethodScope methodScope) {
+		endVisitRemoved(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceEnd);
+		endVisitPreserved(fieldDeclaration.sourceEnd, fieldDeclaration.declarationEnd);
+		popParent();
+	}
+
+	public void endVisit(Initializer initializer, MethodScope methodScope) {
+		endVisitPreserved(initializer.bodyStart, initializer.bodyEnd);
+		popParent();
+	}
+
+	public void endVisit(LocalDeclaration localDeclaration, BlockScope blockScope) {
+		endVisitRemoved(localDeclaration.declarationSourceStart, localDeclaration.sourceEnd);
+	}
+
+	public void endVisit(MethodDeclaration methodDeclaration, ClassScope classScope) {
+		endVisitPreserved(
+				methodDeclaration.bodyStart,
+				methodDeclaration.bodyEnd);
+		popParent();
+	}
+
+	public void endVisit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+		endVisitRemoved(typeDeclaration.sourceStart, typeDeclaration.declarationSourceEnd);
+		popParent();
+	}
+
+	public void endVisit(TypeDeclaration typeDeclaration, ClassScope classScope) {
+		endVisitRemoved(typeDeclaration.sourceStart, typeDeclaration.declarationSourceEnd);
+		popParent();
+	}
+
+	private int indexOfFisrtNameAfter(int position) {
+		int left = 0;
+		int right = this.potentialVariableNamesPtr;
+
+		next : while (true) {
+			if (right < left) return -1;
+
+			int mid = left + (right - left) / 2;
+			int midPosition = this.potentialVariableNameStarts[mid];
+			if (midPosition < 0) {
+				int nextMid = indexOfNextName(mid);
+				if (nextMid < 0 || right < nextMid) { // no next index or next index is after 'right'
+					right = mid - 1;
+					continue next;
+				}
+				mid = nextMid;
+				midPosition = this.potentialVariableNameStarts[nextMid];
+
+				if (mid == right) { // mid and right are at the same index, we must move 'left'
+					int leftPosition = this.potentialVariableNameStarts[left];
+					if (leftPosition < 0 || leftPosition < position) { // 'left' is empty or 'left' is before the position
+						int nextLeft = indexOfNextName(left);
+						if (nextLeft < 0) return - 1;
+
+						left = nextLeft;
+						continue next;
+					}
+
+					return left;
+				}
+			}
+
+			if (left != right) {
+				if (midPosition < position) {
+					left = mid + 1;
+				} else {
+					right = mid;
+				}
+			} else {
+				if (midPosition < position) {
+					return -1;
+				}
+				return mid;
+			}
+		}
+	}
+
+	private int indexOfNextName(int index) {
+		int nextIndex = index + 1;
+		while (nextIndex <= this.potentialVariableNamesPtr &&
+				this.potentialVariableNames[nextIndex] == null) {
+			int jumpIndex = -this.potentialVariableNameStarts[nextIndex];
+			if (jumpIndex > 0) {
+				nextIndex = jumpIndex;
+			} else {
+				nextIndex++;
+			}
+		}
+
+		if (this.potentialVariableNamesPtr < nextIndex) {
+			if  (index < this.potentialVariableNamesPtr) {
+				this.potentialVariableNamesPtr = index;
+			}
+			return -1;
+		}
+		if (index + 1 < nextIndex) {
+			this.potentialVariableNameStarts[index + 1] = -nextIndex;
+		}
+		return nextIndex;
+	}
+
+	private void removeNameAt(int index) {
+		this.potentialVariableNames[index] = null;
+		int nextIndex = indexOfNextName(index);
+		if (nextIndex != -1) {
+			this.potentialVariableNameStarts[index] = -nextIndex;
+		} else {
+			this.potentialVariableNamesPtr = index - 1;
+		}
+	}
+
+	private void endVisitPreserved(int start, int end) {
+		int i = indexOfFisrtNameAfter(start);
+		done : while (i != -1) {
+			int nameStart = this.potentialVariableNameStarts[i];
+			if (start < nameStart && nameStart < end) {
+				acceptName(this.potentialVariableNames[i]);
+				removeNameAt(i);
+			}
+
+			if (end < nameStart) break done;
+			i = indexOfNextName(i);
+		}
+	}
+
+	private void endVisitRemoved(int start, int end) {
+		int i = indexOfFisrtNameAfter(start);
+		done : while (i != -1) {
+			int nameStart = this.potentialVariableNameStarts[i];
+			if (start < nameStart && nameStart < end) {
+				removeNameAt(i);
+			}
+
+			if (end < nameStart) break done;
+			i = indexOfNextName(i);
+		}
+	}
+
+	private void removeLocals(Statement[] statements, int start, int end) {
+		if (statements != null) {
+			for (int i = 0; i < statements.length; i++) {
+				if (statements[i] instanceof LocalDeclaration) {
+					LocalDeclaration localDeclaration = (LocalDeclaration) statements[i];
+					int j = indexOfFisrtNameAfter(start);
+					done : while (j != -1) {
+						int nameStart = this.potentialVariableNameStarts[j];
+						if (start <= nameStart && nameStart <= end) {
+							if (CharOperation.equals(this.potentialVariableNames[j], localDeclaration.name, false)) {
+								removeNameAt(j);
+							}
+						}
+
+						if (end < nameStart) break done;
+						j = indexOfNextName(j);
+					}
+				}
+			}
+
+		}
+	}
+
+	private void removeFields(TypeDeclaration typeDeclaration) {
+		int start = typeDeclaration.declarationSourceStart;
+		int end = typeDeclaration.declarationSourceEnd;
+
+		FieldDeclaration[] fieldDeclarations = typeDeclaration.fields;
+		if (fieldDeclarations != null) {
+			for (int i = 0; i < fieldDeclarations.length; i++) {
+				int j = indexOfFisrtNameAfter(start);
+				done : while (j != -1) {
+					int nameStart = this.potentialVariableNameStarts[j];
+					if (start <= nameStart && nameStart <= end) {
+						if (CharOperation.equals(this.potentialVariableNames[j], fieldDeclarations[i].name, false)) {
+							removeNameAt(j);
+						}
+					}
+
+					if (end < nameStart) break done;
+					j = indexOfNextName(j);
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java
new file mode 100644
index 0000000..5e2fa11
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadoc.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Node representing a Javadoc comment including code selection.
+ */
+public class CompletionJavadoc extends Javadoc {
+
+	Expression completionNode;
+
+	public CompletionJavadoc(int sourceStart, int sourceEnd) {
+		super(sourceStart, sourceEnd);
+	}
+
+	/**
+	 * @return Returns the completionNode.
+	 */
+	public Expression getCompletionNode() {
+		return this.completionNode;
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws CompletionNodeFound
+	 */
+	private void internalResolve(Scope scope) {
+		if (this.completionNode != null) {
+			if (this.completionNode instanceof CompletionOnJavadocTag) {
+				((CompletionOnJavadocTag)this.completionNode).filterPossibleTags(scope);
+			} else {
+				boolean resolve = true;
+				if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
+					resolve = ((CompletionOnJavadocParamNameReference)this.completionNode).token != null;
+				} else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
+					resolve = ((CompletionOnJavadocTypeParamReference)this.completionNode).token != null;
+				}
+				if (resolve) {
+					switch (scope.kind) {
+						case Scope.CLASS_SCOPE:
+							this.completionNode.resolveType((ClassScope)scope);
+							break;
+						case Scope.METHOD_SCOPE:
+							this.completionNode.resolveType((MethodScope) scope);
+							break;
+					}
+				}
+				if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
+					CompletionOnJavadocParamNameReference paramNameReference = (CompletionOnJavadocParamNameReference) this.completionNode;
+					if (scope.kind == Scope.METHOD_SCOPE) {
+						paramNameReference.missingParams = missingParamTags(paramNameReference.binding, (MethodScope)scope);
+					}
+					if (paramNameReference.token == null || paramNameReference.token.length == 0) {
+						paramNameReference.missingTypeParams = missingTypeParameterTags(paramNameReference.binding, scope);
+					}
+				} else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
+					CompletionOnJavadocTypeParamReference typeParamReference = (CompletionOnJavadocTypeParamReference) this.completionNode;
+					typeParamReference.missingParams = missingTypeParameterTags(typeParamReference.resolvedType, scope);
+				}
+			}
+			Binding qualifiedBinding = null;
+			if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+				CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
+				if (typeRef.packageBinding == null) {
+					qualifiedBinding = typeRef.resolvedType;
+				} else {
+					qualifiedBinding = typeRef.packageBinding;
+				}
+			} else if (this.completionNode instanceof CompletionOnJavadocMessageSend) {
+				CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) this.completionNode;
+				if (!msg.receiver.isThis()) qualifiedBinding = msg.receiver.resolvedType;
+			} else if (this.completionNode instanceof CompletionOnJavadocAllocationExpression) {
+				CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) this.completionNode;
+				qualifiedBinding = alloc.type.resolvedType;
+			}
+			throw new CompletionNodeFound(this.completionNode, qualifiedBinding, scope);
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer print(int indent, StringBuffer output) {
+		printIndent(indent, output).append("/**\n"); //$NON-NLS-1$
+		boolean nodePrinted = false;
+		if (this.paramReferences != null) {
+			for (int i = 0, length = this.paramReferences.length; i < length; i++) {
+				printIndent(indent, output).append(" * @param "); //$NON-NLS-1$
+				this.paramReferences[i].print(indent, output).append('\n');
+				if (!nodePrinted && this.completionNode != null) {
+					nodePrinted =  this.completionNode == this.paramReferences[i];
+				}
+			}
+		}
+		if (this.paramTypeParameters != null) {
+			for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
+				printIndent(indent, output).append(" * @param <"); //$NON-NLS-1$
+				this.paramTypeParameters[i].print(indent, output).append(">\n"); //$NON-NLS-1$
+				if (!nodePrinted && this.completionNode != null) {
+					nodePrinted =  this.completionNode == this.paramTypeParameters[i];
+				}
+			}
+		}
+		if (this.returnStatement != null) {
+			printIndent(indent, output).append(" * @"); //$NON-NLS-1$
+			this.returnStatement.print(indent, output).append('\n');
+		}
+		if (this.exceptionReferences != null) {
+			for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
+				printIndent(indent, output).append(" * @throws "); //$NON-NLS-1$
+				this.exceptionReferences[i].print(indent, output).append('\n');
+				if (!nodePrinted && this.completionNode != null) {
+					nodePrinted =  this.completionNode == this.exceptionReferences[i];
+				}
+			}
+		}
+		if (this.seeReferences != null) {
+			for (int i = 0, length = this.seeReferences.length; i < length; i++) {
+				printIndent(indent, output).append(" * @see "); //$NON-NLS-1$
+				this.seeReferences[i].print(indent, output).append('\n');
+				if (!nodePrinted && this.completionNode != null) {
+					nodePrinted =  this.completionNode == this.seeReferences[i];
+				}
+			}
+		}
+		if (!nodePrinted && this.completionNode != null) {
+			printIndent(indent, output).append(" * "); //$NON-NLS-1$
+			this.completionNode.print(indent, output).append('\n');
+		}
+		printIndent(indent, output).append(" */\n"); //$NON-NLS-1$
+		return output;
+	}
+
+	/**
+	 * Resolve completion node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws CompletionNodeFound
+	 */
+	public void resolve(ClassScope scope) {
+		super.resolve(scope);
+		internalResolve(scope);
+	}
+
+	/**
+	 * Resolve completion node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws CompletionNodeFound
+	 */
+	public void resolve(CompilationUnitScope scope) {
+		internalResolve(scope);
+	}
+
+	/**
+	 * Resolve completion node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws CompletionNodeFound
+	 */
+	public void resolve(MethodScope scope) {
+		super.resolve(scope);
+		internalResolve(scope);
+	}
+
+	/*
+	 * Look for missing method @param tags
+	 */
+	private char[][] missingParamTags(Binding paramNameRefBinding, MethodScope methScope) {
+
+		// Verify if there's some possible param tag
+		AbstractMethodDeclaration md = methScope.referenceMethod();
+		int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
+		if (md == null) return null;
+		int argumentsSize = md.arguments == null ? 0 : md.arguments.length;
+		if (argumentsSize == 0) return null;
+
+		// Store all method arguments if there's no @param in javadoc
+		if (paramTagsSize == 0) {
+			char[][] missingParams = new char[argumentsSize][];
+			for (int i = 0; i < argumentsSize; i++) {
+				missingParams[i] = md.arguments[i].name;
+			}
+			return missingParams;
+		}
+
+		// Look for missing arguments
+		char[][] missingParams = new char[argumentsSize][];
+		int size = 0;
+		for (int i = 0; i < argumentsSize; i++) {
+			Argument arg = md.arguments[i];
+			boolean found = false;
+			int paramNameRefCount = 0;
+			for (int j = 0; j < paramTagsSize && !found; j++) {
+				JavadocSingleNameReference param = this.paramReferences[j];
+				if (arg.binding == param.binding) {
+					if (param.binding == paramNameRefBinding) { // do not count first occurence of param name reference
+						paramNameRefCount++;
+						found = paramNameRefCount > 1;
+					} else {
+						found = true;
+					}
+				}
+			}
+			if (!found) {
+				missingParams[size++] = arg.name;
+			}
+		}
+		if (size > 0) {
+			if (size != argumentsSize) {
+				System.arraycopy(missingParams, 0, missingParams = new char[size][], 0, size);
+			}
+			return missingParams;
+		}
+		return null;
+	}
+
+	/*
+	 * Look for missing type parameters @param tags
+	 */
+	private char[][] missingTypeParameterTags(Binding paramNameRefBinding, Scope scope) {
+		int paramTypeParamLength = this.paramTypeParameters == null ? 0 : this.paramTypeParameters.length;
+
+		// Verify if there's any type parameter to tag
+		TypeParameter[] parameters =  null;
+		TypeVariableBinding[] typeVariables = null;
+		switch (scope.kind) {
+			case Scope.METHOD_SCOPE:
+				AbstractMethodDeclaration methodDeclaration = ((MethodScope)scope).referenceMethod();
+				if (methodDeclaration == null) return null;
+				parameters = methodDeclaration.typeParameters();
+				typeVariables = methodDeclaration.binding.typeVariables;
+				break;
+			case Scope.CLASS_SCOPE:
+				TypeDeclaration typeDeclaration = ((ClassScope) scope).referenceContext;
+				parameters = typeDeclaration.typeParameters;
+				typeVariables = typeDeclaration.binding.typeVariables;
+				break;
+		}
+		if (typeVariables == null || typeVariables.length == 0) return null;
+
+		// Store all type parameters if there's no @param in javadoc
+		if (parameters != null) {
+			int typeParametersLength = parameters.length;
+			if (paramTypeParamLength == 0) {
+				char[][] missingParams = new char[typeParametersLength][];
+				for (int i = 0; i < typeParametersLength; i++) {
+					missingParams[i] = parameters[i].name;
+				}
+				return missingParams;
+			}
+
+			// Look for missing type parameter
+			char[][] missingParams = new char[typeParametersLength][];
+			int size = 0;
+			for (int i = 0; i < typeParametersLength; i++) {
+				TypeParameter parameter = parameters[i];
+				boolean found = false;
+				int paramNameRefCount = 0;
+				for (int j = 0; j < paramTypeParamLength && !found; j++) {
+					if (parameter.binding == this.paramTypeParameters[j].resolvedType) {
+						if (parameter.binding == paramNameRefBinding) { // do not count first occurence of param nmae reference
+							paramNameRefCount++;
+							found = paramNameRefCount > 1;
+						} else {
+							found = true;
+						}
+					}
+				}
+				if (!found) {
+					missingParams[size++] = parameter.name;
+				}
+			}
+			if (size > 0) {
+				if (size != typeParametersLength) {
+					System.arraycopy(missingParams, 0, missingParams = new char[size][], 0, size);
+				}
+				return missingParams;
+			}
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
new file mode 100644
index 0000000..7ca06c0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
@@ -0,0 +1,921 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Parser specialized for decoding javadoc comments which includes cursor location for code completion.
+ */
+public class CompletionJavadocParser extends JavadocParser {
+
+	// Initialize lengthes for block and inline tags tables
+	public final static int INLINE_ALL_TAGS_LENGTH;
+	public final static int BLOCK_ALL_TAGS_LENGTH;
+	static {
+		int length = 0;
+		for (int i=0; i<INLINE_TAGS_LENGTH; i++) {
+			length += INLINE_TAGS[i].length;
+		}
+		INLINE_ALL_TAGS_LENGTH  = length;
+		length = 0;
+		for (int i=0; i<BLOCK_TAGS_LENGTH; i++) {
+			length += BLOCK_TAGS[i].length;
+		}
+		BLOCK_ALL_TAGS_LENGTH = length;
+	}
+
+	// Level tags are array of inline/block tags depending on compilation source level
+	char[][][] levelTags = new char[2][][];
+	int[] levelTagsLength = new int[2];
+
+	// Completion specific info
+	int cursorLocation;
+	CompletionOnJavadoc completionNode = null;
+	boolean pushText = false;
+	boolean allPossibleTags = false;
+
+	public CompletionJavadocParser(CompletionParser sourceParser) {
+		super(sourceParser);
+		this.scanner = new CompletionScanner(ClassFileConstants.JDK1_3);
+		this.kind = COMPLETION_PARSER | TEXT_PARSE;
+		initLevelTags();
+	}
+
+	/*
+	 * Do not parse comment if completion location is not included.
+	 */
+	public boolean checkDeprecation(int commentPtr) {
+		boolean isDeprecated = false;
+
+		this.cursorLocation = ((CompletionParser)this.sourceParser).cursorLocation;
+		CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+		completionScanner.cursorLocation = this.cursorLocation;
+		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
+		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr];
+		if (this.javadocStart <= this.cursorLocation && this.cursorLocation <= this.javadocEnd) {
+			if (CompletionEngine.DEBUG) {
+				System.out.println("COMPLETION in Javadoc:"); //$NON-NLS-1$
+			}
+			completionScanner.completionIdentifier = null;
+			this.firstTagPosition = 1;
+			super.checkDeprecation(commentPtr);
+		} else {
+			if (this.sourceParser.scanner.commentTagStarts[commentPtr] != 0) {
+				boolean previousValue = this.checkDocComment;
+				this.checkDocComment = false;
+				isDeprecated = super.checkDeprecation(commentPtr);
+				this.checkDocComment = previousValue;
+			}
+			this.docComment = null;
+		}
+		return isDeprecated;
+	}
+
+	/*
+	 * Replace stored Javadoc node with specific completion one.
+	 */
+	protected boolean commentParse() {
+		this.docComment = new CompletionJavadoc(this.javadocStart, this.javadocEnd);
+		return super.commentParse();
+	}
+
+	/*
+	 * Create argument expression. If it includes completion location, create and store completion node.
+	 */
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+		// Create argument as we may need it after
+		char[] argName = name==null ? CharOperation.NO_CHAR : name;
+		Expression expression = (Expression) super.createArgumentReference(argName, dim, isVarargs, typeRef, dimPositions, argNamePos);
+		// See if completion location is in argument
+		int refStart = ((TypeReference)typeRef).sourceStart;
+		int refEnd = ((TypeReference)typeRef).sourceEnd;
+		boolean inCompletion = (refStart <= this.cursorLocation && this.cursorLocation <= refEnd) // completion cursor is between first and last stacked identifiers
+			|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation)); // or it's a completion on empty token
+		if (this.completionNode == null && inCompletion) {
+			JavadocArgumentExpression javadocArgument = (JavadocArgumentExpression) expression;
+			TypeReference expressionType = javadocArgument.argument.type;
+			if (expressionType instanceof JavadocSingleTypeReference) {
+				this.completionNode = new CompletionOnJavadocSingleTypeReference((JavadocSingleTypeReference) expressionType);
+			} else if (expressionType instanceof JavadocQualifiedTypeReference) {
+				this.completionNode = new CompletionOnJavadocQualifiedTypeReference((JavadocQualifiedTypeReference) expressionType);
+			}
+			if (CompletionEngine.DEBUG) {
+				System.out.println("	completion argument="+this.completionNode); //$NON-NLS-1$
+			}
+			return this.completionNode;
+		}
+		return expression;
+	}
+
+	/*
+	 * Create field reference. If it includes completion location, create and store completion node.
+	 */
+	protected Object createFieldReference(Object receiver) throws InvalidInputException {
+		int refStart = (int) (this.identifierPositionStack[0] >>> 32);
+		int refEnd = (int) this.identifierPositionStack[0];
+		boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd) // completion cursor is between first and last stacked identifiers
+			|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation)) // or it's a completion on empty token
+			|| (this.memberStart == this.cursorLocation); // or it's a completion just after the member separator with an identifier after the cursor
+		if (inCompletion) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) super.createFieldReference(receiver);
+			char[] name = this.sourceParser.compilationUnit.getMainTypeName();
+			TypeDeclaration typeDecl = getParsedTypeDeclaration();
+			if (typeDecl != null) {
+				name = typeDecl.name;
+			}
+			this.completionNode = new CompletionOnJavadocFieldReference(fieldRef, this.memberStart, name);
+			if (CompletionEngine.DEBUG) {
+				System.out.println("	completion field="+this.completionNode); //$NON-NLS-1$
+			}
+			return this.completionNode;
+		}
+		return super.createFieldReference(receiver);
+	}
+
+	/*
+	 * Verify if method identifier positions include completion location.
+	 * If so, create method reference and store it.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+		int memberPtr = this.identifierLengthStack[0] - 1; // may be > 0 for inner class constructor reference
+		int refStart = (int) (this.identifierPositionStack[memberPtr] >>> 32);
+		int refEnd = (int) this.identifierPositionStack[memberPtr];
+		boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd) // completion cursor is between first and last stacked identifiers
+			|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation)) // or it's a completion on empty token
+			|| (this.memberStart == this.cursorLocation); // or it's a completion just after the member separator with an identifier after the cursor
+		if (inCompletion) {
+			ASTNode node = (ASTNode) super.createMethodReference(receiver, arguments);
+			if (node instanceof JavadocMessageSend) {
+				JavadocMessageSend messageSend = (JavadocMessageSend) node;
+				int nameStart = (int) (messageSend.nameSourcePosition >>> 32);
+				int nameEnd = (int) messageSend.nameSourcePosition;
+				if ((nameStart <= (this.cursorLocation+1) && this.cursorLocation <= nameEnd)) {
+					this.completionNode = new CompletionOnJavadocFieldReference(messageSend, this.memberStart);
+				} else {
+					this.completionNode = new CompletionOnJavadocMessageSend(messageSend, this.memberStart);
+				}
+			} else if (node instanceof JavadocAllocationExpression) {
+				this.completionNode = new CompletionOnJavadocAllocationExpression((JavadocAllocationExpression)node, this.memberStart);
+			}
+			if (CompletionEngine.DEBUG) {
+				System.out.println("	completion method="+this.completionNode); //$NON-NLS-1$
+			}
+			return this.completionNode;
+		}
+		return super.createMethodReference(receiver, arguments);
+	}
+
+	/*
+	 * Create type reference. If it includes completion location, create and store completion node.
+	 */
+	protected Object createTypeReference(int primitiveToken) {
+		// Need to create type ref in case it was needed by members
+		int nbIdentifiers = this.identifierLengthStack[this.identifierLengthPtr];
+		int startPtr = this.identifierPtr - (nbIdentifiers-1);
+		int refStart = (int) (this.identifierPositionStack[startPtr] >>> 32);
+		int refEnd = (int) this.identifierPositionStack[this.identifierPtr];
+		boolean inCompletion = (refStart <= (this.cursorLocation+1) && this.cursorLocation <= refEnd) // completion cursor is between first and last stacked identifiers
+			|| ((refStart == (refEnd+1) && refEnd == this.cursorLocation)); // or it's a completion on empty token
+		if (!inCompletion) {
+			return super.createTypeReference(primitiveToken);
+		}
+		this.identifierLengthPtr--;
+		if (nbIdentifiers == 1) { // Single Type ref
+			this.completionNode = new CompletionOnJavadocSingleTypeReference(
+						this.identifierStack[this.identifierPtr],
+						this.identifierPositionStack[this.identifierPtr],
+						this.tagSourceStart,
+						this.tagSourceEnd);
+		} else if (nbIdentifiers > 1) { // Qualified Type ref
+			for (int i=startPtr; i<this.identifierPtr; i++) {
+				int start = (int) (this.identifierPositionStack[i] >>> 32);
+				int end = (int) this.identifierPositionStack[i];
+				if (start <= this.cursorLocation && this.cursorLocation <= end) {
+					if (i == startPtr) {
+						this.completionNode = new CompletionOnJavadocSingleTypeReference(
+									this.identifierStack[startPtr],
+									this.identifierPositionStack[startPtr],
+									this.tagSourceStart,
+									this.tagSourceEnd);
+					} else {
+						char[][] tokens = new char[i][];
+						System.arraycopy(this.identifierStack, startPtr, tokens, 0, i);
+						long[] positions = new long[i+1];
+						System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, i+1);
+						this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, this.identifierStack[i], positions, this.tagSourceStart, this.tagSourceEnd);
+					}
+					break;
+				}
+			}
+			if (this.completionNode == null) {
+				char[][] tokens = new char[nbIdentifiers-1][];
+				System.arraycopy(this.identifierStack, startPtr, tokens, 0, nbIdentifiers-1);
+				long[] positions = new long[nbIdentifiers];
+				System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, nbIdentifiers);
+				this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, this.identifierStack[this.identifierPtr], positions, this.tagSourceStart, this.tagSourceEnd);
+			}
+		}
+
+		if (CompletionEngine.DEBUG) {
+			System.out.println("	completion partial qualified type="+this.completionNode); //$NON-NLS-1$
+		}
+		return this.completionNode;
+	}
+
+	/*
+	 * Get possible tags for a given prefix.
+	 */
+	private char[][][] possibleTags(char[] prefix, boolean newLine) {
+		char[][][] possibleTags = new char[2][][];
+		if (newLine) {
+			System.arraycopy(this.levelTags[BLOCK_IDX], 0, possibleTags[BLOCK_IDX] = new char[this.levelTagsLength[BLOCK_IDX]][], 0, this.levelTagsLength[BLOCK_IDX]);
+		} else {
+			possibleTags[BLOCK_IDX] = CharOperation.NO_CHAR_CHAR;
+		}
+		System.arraycopy(this.levelTags[INLINE_IDX], 0, possibleTags[INLINE_IDX] = new char[this.levelTagsLength[INLINE_IDX]][], 0, this.levelTagsLength[INLINE_IDX]);
+		if (prefix == null || prefix.length == 0) return possibleTags;
+		int kinds = this.levelTags.length;
+		for (int k=0; k<kinds; k++) {
+			int length = possibleTags[k].length, size = 0;
+			int indexes[] = new int[length];
+			for (int i=0; i<length; i++) {
+				if (CharOperation.prefixEquals(prefix, possibleTags[k][i], false)) {
+					indexes[size++] = i;
+				}
+			}
+			char[][] tags = new char[size][];
+			for (int i=0; i<size; i++) {
+				tags[i] = possibleTags[k][indexes[i]];
+			}
+			possibleTags[k] = tags;
+		}
+		return possibleTags;
+	}
+
+	private CompletionJavadoc getCompletionJavadoc() {
+		return (CompletionJavadoc)this.docComment;
+	}
+
+	private CompletionParser getCompletionParser() {
+		return (CompletionParser)this.sourceParser;
+	}
+
+	/*
+	 * Init tags arrays for current source level.
+	 */
+	private void initLevelTags() {
+		int level = ((int)(this.complianceLevel >>> 16)) - ClassFileConstants.MAJOR_VERSION_1_1 + 1;
+		// Init block tags
+		this.levelTags[BLOCK_IDX] = new char[BLOCK_ALL_TAGS_LENGTH][];
+		this.levelTagsLength[BLOCK_IDX] = 0;
+		for (int i=0; i<=level; i++) {
+			int length = BLOCK_TAGS[i].length;
+			System.arraycopy(BLOCK_TAGS[i], 0, this.levelTags[BLOCK_IDX], this.levelTagsLength[BLOCK_IDX], length);
+			this.levelTagsLength[BLOCK_IDX] += length;
+		}
+		if (this.levelTagsLength[BLOCK_IDX] < BLOCK_ALL_TAGS_LENGTH) {
+			System.arraycopy(this.levelTags[BLOCK_IDX], 0, this.levelTags[BLOCK_IDX] = new char[this.levelTagsLength[BLOCK_IDX]][], 0, this.levelTagsLength[BLOCK_IDX]);
+		}
+		// Init inline tags
+		this.levelTags[INLINE_IDX] = new char[INLINE_ALL_TAGS_LENGTH][];
+		this.levelTagsLength[INLINE_IDX]= 0;
+		for (int i=0; i<=level; i++) {
+			int length = INLINE_TAGS[i].length;
+			System.arraycopy(INLINE_TAGS[i], 0, this.levelTags[INLINE_IDX], this.levelTagsLength[INLINE_IDX], length);
+			this.levelTagsLength[INLINE_IDX] += length;
+		}
+		if (this.levelTagsLength[INLINE_IDX] < INLINE_ALL_TAGS_LENGTH) {
+			System.arraycopy(this.levelTags[INLINE_IDX], 0, this.levelTags[INLINE_IDX] = new char[this.levelTagsLength[INLINE_IDX]][], 0, this.levelTagsLength[INLINE_IDX]);
+		}
+	}
+	/*
+	 * Parse argument in @see tag method reference
+	 */
+	protected Object parseArguments(Object receiver) throws InvalidInputException {
+
+		if (this.tagSourceStart>this.cursorLocation) {
+			return super.parseArguments(receiver);
+		}
+
+		// Init
+		int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type arg,Type arg,...)
+		int iToken = 0;
+		char[] argName = null;
+		List arguments = new ArrayList(10);
+		Object typeRef = null;
+		int dim = 0;
+		boolean isVarargs = false;
+		long[] dimPositions = new long[20]; // assume that there won't be more than 20 dimensions...
+		char[] name = null;
+		long argNamePos = -1;
+
+		// Parse arguments declaration if method reference
+		nextArg : while (this.index < this.scanner.eofPosition) {
+
+			// Read argument type reference
+			try {
+				typeRef = parseQualifiedName(false);
+				if (this.abort) return null; // May be aborted by specialized parser
+			} catch (InvalidInputException e) {
+				break nextArg;
+			}
+			boolean firstArg = modulo == 0;
+			if (firstArg) { // verify position
+				if (iToken != 0)
+					break nextArg;
+			} else if ((iToken % modulo) != 0) {
+					break nextArg;
+			}
+			if (typeRef == null) {
+				if (firstArg && getCurrentTokenType() == TerminalTokens.TokenNameRPAREN) {
+					this.lineStarted = true;
+					return createMethodReference(receiver, null);
+				}
+				Object methodRef = createMethodReference(receiver, arguments);
+				return syntaxRecoverEmptyArgumentType(methodRef);
+			}
+			if (this.index >= this.scanner.eofPosition) {
+				int argumentStart = ((ASTNode)typeRef).sourceStart;
+				Object argument = createArgumentReference(this.scanner.getCurrentIdentifierSource(), 0, false, typeRef, null, (((long)argumentStart)<<32)+this.tokenPreviousPosition-1);
+				return syntaxRecoverArgumentType(receiver, arguments, argument);
+			}
+			if (this.index >= this.cursorLocation) {
+				if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
+					CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
+					if (singleTypeReference.token == null || singleTypeReference.token.length == 0) {
+						Object methodRef = createMethodReference(receiver, arguments);
+						return syntaxRecoverEmptyArgumentType(methodRef);
+					}
+				}
+				if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+					CompletionOnJavadocQualifiedTypeReference qualifiedTypeReference = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
+					if (qualifiedTypeReference.tokens == null || qualifiedTypeReference.tokens.length < qualifiedTypeReference.sourcePositions.length) {
+						Object methodRef = createMethodReference(receiver, arguments);
+						return syntaxRecoverEmptyArgumentType(methodRef);
+					}
+				}
+			}
+			iToken++;
+
+			// Read possible additional type info
+			dim = 0;
+			isVarargs = false;
+			if (readToken() == TerminalTokens.TokenNameLBRACKET) {
+				// array declaration
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				while (readToken() == TerminalTokens.TokenNameLBRACKET) {
+					consumeToken();
+					if (readToken() != TerminalTokens.TokenNameRBRACKET) {
+						break nextArg;
+					}
+					consumeToken();
+					dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				}
+			} else if (readToken() == TerminalTokens.TokenNameELLIPSIS) {
+				// ellipsis declaration
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				consumeToken();
+				isVarargs = true;
+			}
+
+			// Read argument name
+			argNamePos = -1;
+			if (readToken() == TerminalTokens.TokenNameIdentifier) {
+				consumeToken();
+				if (firstArg) { // verify position
+					if (iToken != 1)
+						break nextArg;
+				} else if ((iToken % modulo) != 1) {
+						break nextArg;
+				}
+				if (argName == null) { // verify that all arguments name are declared
+					if (!firstArg) {
+						break nextArg;
+					}
+				}
+				argName = this.scanner.getCurrentIdentifierSource();
+				argNamePos = (((long)this.scanner.getCurrentTokenStartPosition())<<32)+this.scanner.getCurrentTokenEndPosition();
+				iToken++;
+			} else if (argName != null) { // verify that no argument name is declared
+				break nextArg;
+			}
+
+			// Verify token position
+			if (firstArg) {
+				modulo = iToken + 1;
+			} else {
+				if ((iToken % modulo) != (modulo - 1)) {
+					break nextArg;
+				}
+			}
+
+			// Read separator or end arguments declaration
+			int token = readToken();
+			name = argName == null ? CharOperation.NO_CHAR : argName;
+			if (token == TerminalTokens.TokenNameCOMMA) {
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
+				arguments.add(argument);
+				consumeToken();
+				iToken++;
+			} else if (token == TerminalTokens.TokenNameRPAREN) {
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
+				arguments.add(argument);
+				consumeToken();
+				return createMethodReference(receiver, arguments);
+			} else {
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				return syntaxRecoverArgumentType(receiver, arguments, argument);
+			}
+		}
+
+		// Something wrong happened => Invalid input
+		throw new InvalidInputException();
+	}
+
+		protected boolean parseParam() throws InvalidInputException {
+			int startPosition = this.index;
+			int endPosition = this.index;
+			long namePosition = (((long)startPosition)<<32) + endPosition;
+			this.identifierPtr = -1;
+			boolean valid = super.parseParam();
+			if (this.identifierPtr > 2) return valid;
+			// See if expression is concerned by completion
+			char[] name = null;
+			CompletionScanner completionScanner = (CompletionScanner) this.scanner;
+			boolean isTypeParam = false;
+			if (this.identifierPtr >= 0) {
+				char[] identifier = null;
+				switch (this.identifierPtr) {
+					case 2:
+						if (!valid && completionScanner.completionIdentifier != null && completionScanner.completionIdentifier.length == 0) {
+							valid = pushParamName(true);
+						}
+						// $FALL-THROUGH$ - fall through next case to verify and get identifiers stack contents
+					case 1:
+						isTypeParam = this.identifierStack[0][0] == '<';
+						identifier = this.identifierStack[1];
+						namePosition = this.identifierPositionStack[1];
+						break;
+					case 0:
+						identifier = this.identifierStack[0];
+						namePosition = this.identifierPositionStack[0];
+						isTypeParam = identifier.length > 0 && identifier[0] == '<';
+						break;
+				}
+				if (identifier != null && identifier.length > 0 && ScannerHelper.isJavaIdentifierPart(this.complianceLevel, identifier[0])) {
+					name = identifier;
+				}
+				startPosition = (int)(this.identifierPositionStack[0]>>32);
+				endPosition = (int)this.identifierPositionStack[this.identifierPtr];
+			}
+			boolean inCompletion = (startPosition <= (this.cursorLocation+1) && this.cursorLocation <= endPosition) // completion cursor is between first and last stacked identifiers
+				|| ((startPosition == (endPosition+1) && endPosition == this.cursorLocation)); // or it's a completion on empty token
+			if (inCompletion) {
+				if (this.completionNode == null) {
+					if (isTypeParam) {
+						this.completionNode = new CompletionOnJavadocTypeParamReference(name, namePosition, startPosition, endPosition);
+					} else {
+						this.completionNode = new CompletionOnJavadocParamNameReference(name, namePosition, startPosition, endPosition);
+					}
+					if (CompletionEngine.DEBUG) {
+						System.out.println("	completion param="+this.completionNode); //$NON-NLS-1$
+					}
+				} else if (this.completionNode instanceof CompletionOnJavadocParamNameReference) {
+					CompletionOnJavadocParamNameReference paramNameRef = (CompletionOnJavadocParamNameReference)this.completionNode;
+					int nameStart = (int) (namePosition>>32);
+					paramNameRef.sourceStart = nameStart;
+					int nameEnd = (int) namePosition;
+					if (nameStart<this.cursorLocation && this.cursorLocation<nameEnd) {
+						paramNameRef.sourceEnd = this.cursorLocation + 1;
+					} else {
+						paramNameRef.sourceEnd = nameEnd;
+					}
+					paramNameRef.tagSourceStart = startPosition;
+					paramNameRef.tagSourceEnd = endPosition;
+				} else if (this.completionNode instanceof CompletionOnJavadocTypeParamReference) {
+					CompletionOnJavadocTypeParamReference typeParamRef = (CompletionOnJavadocTypeParamReference)this.completionNode;
+					int nameStart = (int) (namePosition>>32);
+					typeParamRef.sourceStart = nameStart;
+					int nameEnd = (int) namePosition;
+					if (nameStart<this.cursorLocation && this.cursorLocation<nameEnd) {
+						typeParamRef.sourceEnd = this.cursorLocation + 1;
+					} else {
+						typeParamRef.sourceEnd = nameEnd;
+					}
+					typeParamRef.tagSourceStart = startPosition;
+					typeParamRef.tagSourceEnd = endPosition;
+				}
+			}
+			return valid;
+		}
+
+	/* (non-Javadoc)
+		 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseReference()
+		 */
+		protected boolean parseReference() throws InvalidInputException {
+			boolean completed = this.completionNode != null;
+			boolean valid = super.parseReference();
+			if (!completed && this.completionNode != null) {
+				this.completionNode.addCompletionFlags(CompletionOnJavadoc.FORMAL_REFERENCE);
+			}
+			return valid;
+		}
+
+	/*(non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseTag(int)
+	 */
+	protected boolean parseTag(int previousPosition) throws InvalidInputException {
+		int startPosition = this.inlineTagStarted ? this.inlineTagStart : previousPosition;
+		boolean newLine = !this.lineStarted;
+		boolean valid = super.parseTag(previousPosition);
+		boolean inCompletion = (this.tagSourceStart <= (this.cursorLocation+1) && this.cursorLocation <= this.tagSourceEnd) // completion cursor is between first and last stacked identifiers
+			|| ((this.tagSourceStart == (this.tagSourceEnd+1) && this.tagSourceEnd == this.cursorLocation)); // or it's a completion on empty token
+		if (inCompletion) {
+			int end = this.tagSourceEnd;
+			if (this.inlineTagStarted && this.scanner.currentCharacter == '}') {
+				end = this.scanner.currentPosition;
+			}
+			long position = (((long)startPosition)<<32) + end;
+			int length = this.cursorLocation+1-this.tagSourceStart;
+			char[] tag = new char[length];
+			System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
+			char[][][] tags = possibleTags(tag, newLine);
+			if (tags != null) {
+				this.completionNode = new CompletionOnJavadocTag(tag, position, startPosition, end, tags, this.allPossibleTags);
+			}
+		}
+		return valid;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseThrows()
+	 */
+	protected boolean parseThrows() {
+		try {
+			Object typeRef = parseQualifiedName(true);
+			if (this.completionNode != null) {
+				this.completionNode.addCompletionFlags(CompletionOnJavadoc.EXCEPTION);
+			}
+			return pushThrowName(typeRef);
+		} catch (InvalidInputException ex) {
+			// ignore
+		}
+		return false;
+	}
+
+	/*
+	 * Push param name reference. If it includes completion location, create and store completion node.
+	 */
+	protected boolean pushParamName(boolean isTypeParam) {
+		if (super.pushParamName(isTypeParam)) {
+			Expression expression = (Expression) this.astStack[this.astPtr];
+			// See if expression is concerned by completion
+			if (expression.sourceStart <= (this.cursorLocation+1) && this.cursorLocation <= expression.sourceEnd) {
+				if (isTypeParam) {
+					this.completionNode = new CompletionOnJavadocTypeParamReference((JavadocSingleTypeReference)expression);
+				} else {
+					this.completionNode = new CompletionOnJavadocParamNameReference((JavadocSingleNameReference)expression);
+				}
+				if (CompletionEngine.DEBUG) {
+					System.out.println("	completion param="+this.completionNode); //$NON-NLS-1$
+				}
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Push text. If it includes completion location, then rescan line to see if there's a possible
+	 * reference under the cursor location.
+	 *
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
+	 */
+	protected void pushText(int start, int end) {
+		if (start <= this.cursorLocation && this.cursorLocation <= end) {
+			this.scanner.resetTo(start, end);
+			boolean tokenizeWhiteSpace = this.scanner.tokenizeWhiteSpace;
+			this.scanner.tokenizeWhiteSpace = true;
+			try {
+				Object typeRef = null;
+				this.pushText = true;
+
+				// Get reference tokens
+				int previousToken = TerminalTokens.TokenNameWHITESPACE;
+				while (!this.scanner.atEnd() && this.completionNode == null && !this.abort) {
+					int token = readTokenSafely();
+					switch (token) {
+						case TerminalTokens.TokenNameStringLiteral :
+							int strStart = 0, strEnd = 0;
+							if ((strStart=this.scanner.getCurrentTokenStartPosition()+1) <= this.cursorLocation &&
+								this.cursorLocation <= (strEnd=this.scanner.getCurrentTokenEndPosition()-1))
+							{
+								this.scanner.resetTo(strStart, strEnd);
+							}
+							consumeToken();
+							break;
+						case TerminalTokens.TokenNameERROR :
+							consumeToken();
+							if (this.scanner.currentCharacter == '#') { // @see ...#member
+								Object member = null;
+								try {
+									this.scanner.tokenizeWhiteSpace = false;
+									member = parseMember(typeRef);
+								} catch (InvalidInputException e) {
+									consumeToken();
+								}
+								this.scanner.tokenizeWhiteSpace = true;
+								if (this.completionNode != null) {
+									int flags = this.inlineTagStarted ? 0 : CompletionOnJavadoc.TEXT|CompletionOnJavadoc.ONLY_INLINE_TAG;
+									if (member instanceof JavadocMessageSend) {
+										JavadocMessageSend msgSend = (JavadocMessageSend) member;
+										this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart, flags);
+										if (CompletionEngine.DEBUG) {
+											System.out.println("	new completion method="+this.completionNode); //$NON-NLS-1$
+										}
+									} else if (member instanceof JavadocAllocationExpression) {
+										JavadocAllocationExpression alloc = (JavadocAllocationExpression) member;
+										this.completionNode = new CompletionOnJavadocAllocationExpression(alloc, this.memberStart, flags);
+										if (CompletionEngine.DEBUG) {
+											System.out.println("	new completion method="+this.completionNode); //$NON-NLS-1$
+										}
+									} else {
+										this.completionNode.addCompletionFlags(flags);
+									}
+								}
+							}
+							break;
+						case TerminalTokens.TokenNameIdentifier :
+							try {
+								this.scanner.tokenizeWhiteSpace = false;
+								typeRef = parseQualifiedName(true);
+								if (this.completionNode == null) {
+									consumeToken();
+									this.scanner.resetTo(this.tokenPreviousPosition, end);
+									this.index = this.tokenPreviousPosition;
+								}
+							}
+							catch (InvalidInputException e) {
+								consumeToken();
+							}
+							finally {
+								this.scanner.tokenizeWhiteSpace = true;
+							}
+							if (previousToken != TerminalTokens.TokenNameWHITESPACE) {
+								typeRef = null;
+								this.completionNode = null;
+							}
+							break;
+						case TerminalTokens.TokenNameAT:
+							consumeToken();
+							try {
+								this.scanner.tokenizeWhiteSpace = false;
+								int startPosition = this.scanner.getCurrentTokenStartPosition();
+								parseTag(startPosition);
+								if (this.completionNode != null) {
+									if (this.inlineTagStarted) {
+										/* May be to replace invalid @value tag inside text?
+										if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
+											CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
+											singleTypeReference.tagSourceStart = startPosition;
+											switch (this.tagValue) {
+												case TAG_VALUE_VALUE:
+//													singleTypeReference.completionFlags |= ONLY_INLINE_TAG;
+													if (this.sourceLevel < ClassFileConstants.JDK1_5) singleTypeReference.completionFlags |= REPLACE_TAG;
+													break;
+											}
+										} else if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+											CompletionOnJavadocQualifiedTypeReference qualifiedTypeRef = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
+											qualifiedTypeRef.tagSourceStart = startPosition;
+											switch (this.tagValue) {
+												case TAG_VALUE_VALUE:
+													singleTypeReference.completionFlags |= ONLY_INLINE_TAG;
+													if (this.sourceLevel < ClassFileConstants.JDK1_5) qualifiedTypeRef.completionFlags |= REPLACE_TAG;
+													break;
+											}
+										}
+//										*/
+									} else {
+										/* May be to replace non-inline tag inside text?
+										if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
+											CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
+											singleTypeReference.tagSourceStart = startPosition;
+											switch (this.tagValue) {
+												case TAG_LINK_VALUE:
+												case TAG_LINKPLAIN_VALUE:
+													singleTypeReference.completionFlags |= ONLY_INLINE_TAG;
+												case TAG_SEE_VALUE:
+													singleTypeReference.completionFlags |= REPLACE_TAG;
+													break;
+											}
+										} else if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+											CompletionOnJavadocQualifiedTypeReference qualifiedTypeRef = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
+											qualifiedTypeRef.tagSourceStart = startPosition;
+											switch (this.tagValue) {
+												case TAG_LINK_VALUE:
+												case TAG_LINKPLAIN_VALUE:
+													qualifiedTypeRef.completionFlags |= ONLY_INLINE_TAG;
+												case TAG_SEE_VALUE:
+													qualifiedTypeRef.completionFlags |= REPLACE_TAG;
+													break;
+											}
+										}
+//										*/
+									}
+								}
+							} catch (InvalidInputException e) {
+								consumeToken();
+							}
+							this.scanner.tokenizeWhiteSpace = true;
+							break;
+						default :
+							consumeToken();
+							typeRef = null;
+							break;
+					}
+					previousToken = token;
+				}
+			}
+			finally {
+				this.scanner.tokenizeWhiteSpace = tokenizeWhiteSpace;
+				this.pushText = false;
+			}
+
+			// Reset position to avoid missing tokens when new line was encountered
+			this.index = end;
+			this.scanner.currentPosition = end;
+			consumeToken();
+
+			if (this.completionNode != null) {
+				if (this.inlineTagStarted) {
+					this.completionNode.addCompletionFlags(CompletionOnJavadoc.FORMAL_REFERENCE);
+				} else {
+					this.completionNode.addCompletionFlags(CompletionOnJavadoc.TEXT);
+				}
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#readToken()
+	 */
+	protected int readToken() throws InvalidInputException {
+		int token = super.readToken();
+		if (token == TerminalTokens.TokenNameIdentifier && this.scanner.currentPosition == this.scanner.startPosition) {
+			// Scanner is looping on empty token => read it...
+			this.scanner.getCurrentIdentifierSource();
+		}
+		return token;
+	}
+
+	/*
+	 * Recover syntax on invalid qualified name.
+	 */
+	protected Object syntaxRecoverQualifiedName(int primitiveToken) throws InvalidInputException {
+		if (this.cursorLocation == ((int)this.identifierPositionStack[this.identifierPtr])) {
+			// special case of completion just before the dot.
+			return createTypeReference(primitiveToken);
+		}
+		int idLength = this.identifierLengthStack[this.identifierLengthPtr];
+		char[][] tokens = new char[idLength][];
+		int startPtr = this.identifierPtr-idLength+1;
+		System.arraycopy(this.identifierStack, startPtr, tokens, 0, idLength);
+		long[] positions = new long[idLength+1];
+		System.arraycopy(this.identifierPositionStack, startPtr, positions, 0, idLength);
+		positions[idLength] = (((long)this.tokenPreviousPosition)<<32) + this.tokenPreviousPosition;
+		this.completionNode = new CompletionOnJavadocQualifiedTypeReference(tokens, CharOperation.NO_CHAR, positions, this.tagSourceStart, this.tagSourceEnd);
+
+		if (CompletionEngine.DEBUG) {
+			System.out.println("	completion partial qualified type="+this.completionNode); //$NON-NLS-1$
+		}
+		return this.completionNode;
+	}
+
+	/*
+	 * Recover syntax on type argument in invalid method/constructor reference
+	 */
+	protected Object syntaxRecoverArgumentType(Object receiver, List arguments, Object argument) throws InvalidInputException {
+		if (this.completionNode != null && !this.pushText) {
+			this.completionNode.addCompletionFlags(CompletionOnJavadoc.BASE_TYPES);
+			if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
+				char[] token = ((CompletionOnJavadocSingleTypeReference)this.completionNode).token;
+				if (token != null && token.length > 0) {
+					return this.completionNode;
+				}
+			} else {
+				return this.completionNode;
+			}
+		}
+		// Filter empty token
+		if (this.completionNode instanceof CompletionOnJavadocSingleTypeReference) {
+			CompletionOnJavadocSingleTypeReference singleTypeReference = (CompletionOnJavadocSingleTypeReference) this.completionNode;
+			if (singleTypeReference.token != null && singleTypeReference.token.length > 0) {
+				arguments.add(argument);
+			}
+		} else if (this.completionNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+			CompletionOnJavadocQualifiedTypeReference qualifiedTypeReference = (CompletionOnJavadocQualifiedTypeReference) this.completionNode;
+			if (qualifiedTypeReference.tokens != null && qualifiedTypeReference.tokens.length == qualifiedTypeReference.sourcePositions.length) {
+				arguments.add(argument);
+			}
+		} else {
+			arguments.add(argument);
+		}
+		Object methodRef = super.createMethodReference(receiver, arguments);
+		if (methodRef instanceof JavadocMessageSend) {
+			JavadocMessageSend msgSend = (JavadocMessageSend) methodRef;
+			if (this.index > this.cursorLocation) {
+				msgSend.sourceEnd = this.tokenPreviousPosition-1;
+			}
+			int nameStart = (int) (msgSend.nameSourcePosition >>> 32);
+			int nameEnd = (int) msgSend.nameSourcePosition;
+			if ((nameStart <= (this.cursorLocation+1) && this.cursorLocation <= nameEnd)) {
+				this.completionNode = new CompletionOnJavadocFieldReference(msgSend, this.memberStart);
+			} else {
+				this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart);
+			}
+		} else if (methodRef instanceof JavadocAllocationExpression) {
+			JavadocAllocationExpression allocExp = (JavadocAllocationExpression) methodRef;
+			if (this.index > this.cursorLocation) {
+				allocExp.sourceEnd = this.tokenPreviousPosition-1;
+			}
+			this.completionNode = new CompletionOnJavadocAllocationExpression(allocExp, this.memberStart);
+		}
+		if (CompletionEngine.DEBUG) {
+			System.out.println("	completion method="+this.completionNode); //$NON-NLS-1$
+		}
+		return this.completionNode;
+	}
+
+	/*
+	 * Recover syntax on empty type argument in invalid method/constructor reference
+	 */
+	protected Object syntaxRecoverEmptyArgumentType(Object methodRef) throws InvalidInputException {
+		if (methodRef instanceof JavadocMessageSend) {
+			JavadocMessageSend msgSend = (JavadocMessageSend) methodRef;
+			if (this.index > this.cursorLocation) {
+				msgSend.sourceEnd = this.tokenPreviousPosition-1;
+			}
+			this.completionNode = new CompletionOnJavadocMessageSend(msgSend, this.memberStart);
+		} else if (methodRef instanceof JavadocAllocationExpression) {
+			JavadocAllocationExpression allocExp = (JavadocAllocationExpression) methodRef;
+			if (this.index > this.cursorLocation) {
+				allocExp.sourceEnd = this.tokenPreviousPosition-1;
+			}
+			this.completionNode = new CompletionOnJavadocAllocationExpression(allocExp, this.memberStart);
+		}
+		if (CompletionEngine.DEBUG) {
+			System.out.println("	completion method="+this.completionNode); //$NON-NLS-1$
+		}
+		return this.completionNode;
+	}
+
+	/*
+	 * Store completion node into doc comment.
+	 */
+	protected void updateDocComment() {
+		super.updateDocComment();
+		if (this.completionNode instanceof Expression) {
+			getCompletionParser().assistNodeParent = this.docComment;
+			getCompletionParser().assistNode = (ASTNode) this.completionNode;
+			getCompletionJavadoc().completionNode = (Expression) this.completionNode;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#verifySpaceOrEndComment()
+	 */
+	protected boolean verifySpaceOrEndComment() {
+		CompletionScanner completionScanner = (CompletionScanner) this.scanner;
+		if (completionScanner.completionIdentifier != null && completionScanner.completedIdentifierStart <= this.cursorLocation && this.cursorLocation <= completionScanner.completedIdentifierEnd) {
+			// if we're on completion location do not verify end...
+			return true;
+		}
+		return super.verifySpaceOrEndComment();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
new file mode 100644
index 0000000..617ace9
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Detect the presence of a node in expression
+ */
+public class CompletionNodeDetector extends ASTVisitor {
+	private ASTNode searchedNode;
+	private ASTNode parent;
+	private boolean result;
+
+	public CompletionNodeDetector(ASTNode searchedNode, ASTNode visitedAst){
+		this.searchedNode = searchedNode;
+		this.result = false;
+
+		if(searchedNode != null && visitedAst != null) {
+			visitedAst.traverse(this, null);
+		}
+	}
+
+	public boolean containsCompletionNode() {
+		return this.result;
+	}
+
+	public ASTNode getCompletionNodeParent() {
+		return this.parent;
+	}
+	public void endVisit(AllocationExpression allocationExpression, BlockScope scope) {
+		endVisit(allocationExpression);
+	}
+	public void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope) {
+		endVisit(and_and_Expression);
+	}
+	public void endVisit(ArrayAllocationExpression arrayAllocationExpression, BlockScope scope) {
+		endVisit(arrayAllocationExpression);
+	}
+	public void endVisit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		endVisit(arrayInitializer);
+	}
+	public void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) {
+		endVisit(arrayQualifiedTypeReference);
+	}
+	public void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) {
+		endVisit(arrayQualifiedTypeReference);
+	}
+	public void endVisit(ArrayReference arrayReference, BlockScope scope) {
+		endVisit(arrayReference);
+	}
+	public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
+		endVisit(arrayTypeReference);
+	}
+	public void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
+		endVisit(arrayTypeReference);
+	}
+	public void endVisit(Assignment assignment, BlockScope scope) {
+		endVisit(assignment);
+	}
+	public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
+		endVisit(binaryExpression);
+	}
+	public void endVisit(CastExpression castExpression, BlockScope scope) {
+		endVisit(castExpression);
+	}
+	public void endVisit(CompoundAssignment compoundAssignment, BlockScope scope) {
+		endVisit(compoundAssignment);
+	}
+	public void endVisit(ConditionalExpression conditionalExpression, BlockScope scope) {
+		endVisit(conditionalExpression);
+	}
+	public void endVisit(EqualExpression equalExpression, BlockScope scope) {
+		endVisit(equalExpression);
+	}
+	public void endVisit(ExplicitConstructorCall explicitConstructor, BlockScope scope) {
+		endVisit(explicitConstructor);
+	}
+	public void endVisit(FieldReference fieldReference, BlockScope scope) {
+		endVisit(fieldReference);
+	}
+	public void endVisit(InstanceOfExpression instanceOfExpression, BlockScope scope) {
+		endVisit(instanceOfExpression);
+	}
+	public void endVisit(MessageSend messageSend, BlockScope scope) {
+		endVisit(messageSend);
+	}
+	public void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		endVisit(or_or_Expression);
+	}
+	public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
+		endVisit(parameterizedQualifiedTypeReference);
+	}
+	public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
+		endVisit(parameterizedQualifiedTypeReference);
+	}
+	public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
+		endVisit(parameterizedSingleTypeReference);
+	}
+	public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
+		endVisit(parameterizedSingleTypeReference);
+	}
+	public void endVisit(PostfixExpression postfixExpression, BlockScope scope) {
+		endVisit(postfixExpression);
+	}
+	public void endVisit(PrefixExpression prefixExpression, BlockScope scope) {
+		endVisit(prefixExpression);
+	}
+	public void endVisit(QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope) {
+		endVisit(qualifiedAllocationExpression);
+	}
+	public void endVisit(QualifiedNameReference qualifiedNameReference, BlockScope scope) {
+		endVisit(qualifiedNameReference);
+	}
+	public void endVisit(QualifiedSuperReference qualifiedSuperReference, BlockScope scope) {
+		endVisit(qualifiedSuperReference);
+	}
+	public void endVisit(QualifiedThisReference qualifiedThisReference, BlockScope scope) {
+		endVisit(qualifiedThisReference);
+	}
+	public void endVisit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope) {
+		endVisit(qualifiedTypeReference);
+	}
+	public void endVisit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
+		endVisit(qualifiedTypeReference);
+	}
+	public void endVisit(SingleNameReference singleNameReference, BlockScope scope) {
+		endVisit(singleNameReference);
+	}
+	public void endVisit(SingleTypeReference singleTypeReference, BlockScope scope) {
+		endVisit(singleTypeReference);
+	}
+	public void endVisit(SingleTypeReference singleTypeReference, ClassScope scope) {
+		endVisit(singleTypeReference);
+	}
+	public void endVisit(SuperReference superReference, BlockScope scope) {
+		endVisit(superReference);
+	}
+	public void endVisit(ThisReference thisReference, BlockScope scope) {
+		endVisit(thisReference);
+	}
+	public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
+		endVisit(unaryExpression);
+	}
+	public void endVisit(MemberValuePair pair, BlockScope scope) {
+		endVisit(pair);
+	}
+	public void endVisit(MemberValuePair pair, CompilationUnitScope scope) {
+		endVisit(pair);
+	}
+	public boolean visit(AllocationExpression allocationExpression, BlockScope scope) {
+		return this.visit(allocationExpression);
+	}
+	public boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope) {
+		return this.visit(and_and_Expression);
+	}
+	public boolean visit(ArrayAllocationExpression arrayAllocationExpression, BlockScope scope) {
+		return this.visit(arrayAllocationExpression);
+	}
+	public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		return this.visit(arrayInitializer);
+	}
+	public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) {
+		return this.visit(arrayQualifiedTypeReference);
+	}
+	public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) {
+		return this.visit(arrayQualifiedTypeReference);
+	}
+	public boolean visit(ArrayReference arrayReference, BlockScope scope) {
+		return this.visit(arrayReference);
+	}
+	public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
+		return this.visit(arrayTypeReference);
+	}
+	public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
+		return this.visit(arrayTypeReference);
+	}
+	public boolean visit(Assignment assignment, BlockScope scope) {
+		return this.visit(assignment);
+	}
+	public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
+		return this.visit(binaryExpression);
+	}
+	public boolean visit(CastExpression castExpression, BlockScope scope) {
+		return this.visit(castExpression);
+	}
+	public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) {
+		return this.visit(compoundAssignment);
+	}
+	public boolean visit(ConditionalExpression conditionalExpression, BlockScope scope) {
+		return this.visit(conditionalExpression);
+	}
+	public boolean visit(EqualExpression equalExpression, BlockScope scope) {
+		return this.visit(equalExpression);
+	}
+	public boolean visit(ExplicitConstructorCall explicitConstructor, BlockScope scope) {
+		return this.visit(explicitConstructor);
+	}
+	public boolean visit(FieldReference fieldReference, BlockScope scope) {
+		return this.visit(fieldReference);
+	}
+	public boolean visit(InstanceOfExpression instanceOfExpression, BlockScope scope) {
+		return this.visit(instanceOfExpression);
+	}
+	public boolean visit(MessageSend messageSend, BlockScope scope) {
+		return this.visit(messageSend);
+	}
+	public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		return this.visit(or_or_Expression);
+	}
+	public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
+		return this.visit(parameterizedQualifiedTypeReference);
+	}
+	public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
+		return this.visit(parameterizedQualifiedTypeReference);
+	}
+	public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
+		return this.visit(parameterizedSingleTypeReference);
+	}
+	public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
+		return this.visit(parameterizedSingleTypeReference);
+	}
+	public boolean visit(PostfixExpression postfixExpression, BlockScope scope) {
+		return this.visit(postfixExpression);
+	}
+	public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
+		return this.visit(prefixExpression);
+	}
+	public boolean visit(QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope) {
+		return this.visit(qualifiedAllocationExpression);
+	}
+	public boolean visit(QualifiedNameReference qualifiedNameReference, BlockScope scope) {
+		return this.visit(qualifiedNameReference);
+	}
+	public boolean visit(QualifiedSuperReference qualifiedSuperReference, BlockScope scope) {
+		return this.visit(qualifiedSuperReference);
+	}
+	public boolean visit(QualifiedThisReference qualifiedThisReference, BlockScope scope) {
+		return this.visit(qualifiedThisReference);
+	}
+	public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope) {
+		return this.visit(qualifiedTypeReference);
+	}
+	public boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) {
+		return this.visit(qualifiedTypeReference);
+	}
+	public boolean visit(SingleNameReference singleNameReference, BlockScope scope) {
+		return this.visit(singleNameReference);
+	}
+	public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) {
+		return this.visit(singleTypeReference);
+	}
+	public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) {
+		return this.visit(singleTypeReference);
+	}
+	public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
+		return this.visit(stringLiteral);
+	}
+	public boolean visit(SuperReference superReference, BlockScope scope) {
+		return this.visit(superReference);
+	}
+	public boolean visit(ThisReference thisReference, BlockScope scope) {
+		return this.visit(thisReference);
+	}
+	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
+		return this.visit(unaryExpression);
+	}
+	public boolean visit(MemberValuePair pair, BlockScope scope) {
+		return this.visit(pair);
+	}
+	public boolean visit(MemberValuePair pair, CompilationUnitScope scope) {
+		return this.visit(pair);
+	}
+	private void endVisit(ASTNode astNode) {
+		if(this.result && this.parent == null && astNode != this.searchedNode) {
+			if(!(astNode instanceof AllocationExpression && ((AllocationExpression) astNode).type == this.searchedNode)
+				&& !(astNode instanceof ConditionalExpression && ((ConditionalExpression) astNode).valueIfTrue == this.searchedNode)
+				&& !(astNode instanceof ConditionalExpression && ((ConditionalExpression) astNode).valueIfFalse == this.searchedNode)) {
+				this.parent = astNode;
+			}
+		}
+	}
+	private boolean visit(ASTNode astNode) {
+		if(astNode == this.searchedNode) {
+			this.result = true;
+		}
+		return !this.result;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java
new file mode 100644
index 0000000..a0f6521
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+
+public class CompletionNodeFound extends RuntimeException {
+
+	public ASTNode astNode;
+	public Binding qualifiedBinding;
+	public Scope scope;
+	public boolean insideTypeAnnotation = false;
+
+	private static final long serialVersionUID = 6981437684184091462L; // backward compatible
+
+public CompletionNodeFound() {
+	this(null, null, null, false); // we found a problem in the completion node
+}
+public CompletionNodeFound(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+	this(astNode, qualifiedBinding, scope, false);
+}
+public CompletionNodeFound(ASTNode astNode, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
+	this.astNode = astNode;
+	this.qualifiedBinding = qualifiedBinding;
+	this.scope = scope;
+	this.insideTypeAnnotation = insideTypeAnnotation;
+}
+public CompletionNodeFound(ASTNode astNode, Scope scope) {
+	this(astNode, null, scope, false);
+}
+public CompletionNodeFound(ASTNode astNode, Scope scope, boolean insideTypeAnnotation) {
+	this(astNode, null, scope, insideTypeAnnotation);
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java
new file mode 100644
index 0000000..6496eff
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnAnnotationMemberValuePair extends NormalAnnotation {
+	public MemberValuePair completedMemberValuePair;
+	public CompletionOnAnnotationMemberValuePair(TypeReference type, int sourceStart, MemberValuePair[] memberValuePairs, MemberValuePair completedMemberValuePair) {
+		super(type, sourceStart);
+		this.memberValuePairs = memberValuePairs;
+		this.completedMemberValuePair = completedMemberValuePair;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		super.resolveType(scope);
+
+		if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
+			throw new CompletionNodeFound();
+		} else {
+			throw new CompletionNodeFound(this.completedMemberValuePair, scope);
+		}
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append('@');
+		this.type.printExpression(0, output);
+		output.append('(');
+		if (this.memberValuePairs != null) {
+			for (int i = 0, max = this.memberValuePairs.length; i < max; i++) {
+				if (i > 0) {
+					output.append(',');
+				}
+				this.memberValuePairs[i].print(indent, output);
+			}
+			output.append(',');
+		}
+		this.completedMemberValuePair.print(indent, output);
+		output.append(')');
+
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java
new file mode 100644
index 0000000..cfae076
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+
+public class CompletionOnAnnotationOfType extends TypeDeclaration {
+	public ASTNode potentialAnnotatedNode;
+	// During recovery a parameter can be parsed as a FieldDeclaration instead of Argument.
+	// 'isParameter' is set to true in this case.
+	public boolean isParameter;
+
+	public CompletionOnAnnotationOfType(char[] typeName, CompilationResult compilationResult, Annotation annotation){
+		super(compilationResult);
+		this.sourceEnd = annotation.sourceEnd;
+		this.sourceStart = annotation.sourceEnd;
+		this.name = typeName;
+		this.annotations = new Annotation[]{annotation};
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+		return this.annotations[0].print(indent, output);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java
new file mode 100644
index 0000000..4abb8fb
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class CompletionOnArgumentName extends Argument {
+
+	private static final char[] FAKENAMESUFFIX = " ".toCharArray(); //$NON-NLS-1$
+	public char[] realName;
+	public boolean isCatchArgument = false;
+
+	public CompletionOnArgumentName(char[] name , long posNom , TypeReference tr , int modifiers){
+
+		super(CharOperation.concat(name, FAKENAMESUFFIX), posNom, tr, modifiers);
+		this.realName = name;
+	}
+
+	public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) {
+
+		super.bind(scope, typeBinding, used);
+		throw new CompletionNodeFound(this, scope);
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		printIndent(indent, output);
+		output.append("<CompleteOnArgumentName:"); //$NON-NLS-1$
+		if (this.type != null) this.type.print(0, output).append(' ');
+		output.append(this.realName);
+		if (this.initialization != null) {
+			output.append(" = "); //$NON-NLS-1$
+			this.initialization.printExpression(0, output);
+		}
+		return output.append('>');
+	}
+
+	public void resolve(BlockScope scope) {
+
+		super.resolve(scope);
+		throw new CompletionNodeFound(this, scope);
+	}
+}
+
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java
new file mode 100644
index 0000000..1c940d5
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+public class CompletionOnBranchStatementLabel extends BranchStatement {
+	public static final int BREAK = 1;
+	public static final int CONTINUE = 2;
+
+	private int kind;
+	public char[][] possibleLabels;
+
+	public CompletionOnBranchStatementLabel(int kind, char[] l, int s, int e, char[][] possibleLabels) {
+		super(l, s, e);
+		this.kind = kind;
+		this.possibleLabels = possibleLabels;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope,
+			FlowContext flowContext, FlowInfo flowInfo) {
+		// Is never called
+		return null;
+	}
+
+	public void resolve(BlockScope scope) {
+		throw new CompletionNodeFound(this, scope);
+	}
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		printIndent(indent, output);
+		if(this.kind == CONTINUE) {
+			output.append("continue "); //$NON-NLS-1$
+		} else {
+			output.append("break "); //$NON-NLS-1$
+		}
+		output.append("<CompleteOnLabel:"); //$NON-NLS-1$
+		output.append(this.label);
+		return output.append(">;"); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java
new file mode 100644
index 0000000..e7c1266
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an access to the literal 'class' containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      String[].[cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <CompleteOnClassLiteralAccess:String[].>
+ *         }
+ *       }
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnClassLiteralAccess extends ClassLiteralAccess {
+
+	public char[] completionIdentifier;
+	public int classStart;
+
+	public CompletionOnClassLiteralAccess(long pos, TypeReference t) {
+
+		super((int)pos, t);
+		this.classStart = (int) (pos >>> 32);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<CompleteOnClassLiteralAccess:"); //$NON-NLS-1$
+		return this.type.print(0, output).append('.').append(this.completionIdentifier).append('>');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		if (super.resolveType(scope) == null)
+			throw new CompletionNodeFound();
+		else
+			throw new CompletionNodeFound(this, this.targetType, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java
new file mode 100644
index 0000000..f2df9b7
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a explicit constructor call containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    X() {
+ *      this(1, 2, [cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         X() {
+ *           <CompleteOnExplicitConstructorCall:this(1, 2)>
+ *         }
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the constructor call are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnExplicitConstructorCall extends ExplicitConstructorCall {
+
+	public CompletionOnExplicitConstructorCall(int accessMode) {
+		super(accessMode);
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output);
+		output.append("<CompleteOnExplicitConstructorCall:"); //$NON-NLS-1$
+		if (this.qualification != null) this.qualification.printExpression(0, output).append('.');
+		if (this.accessMode == This) {
+			output.append("this("); //$NON-NLS-1$
+		} else {
+			output.append("super("); //$NON-NLS-1$
+		}
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(")>;"); //$NON-NLS-1$
+	}
+
+	public void resolve(BlockScope scope) {
+
+		ReferenceBinding receiverType = scope.enclosingSourceType();
+
+		if (this.arguments != null) {
+			int argsLength = this.arguments.length;
+			for (int a = argsLength; --a >= 0;)
+				this.arguments[a].resolveType(scope);
+		}
+
+		if (this.accessMode != This && receiverType != null) {
+			if (receiverType.isHierarchyInconsistent())
+				throw new CompletionNodeFound();
+			receiverType = receiverType.superclass();
+		}
+		if (receiverType == null)
+			throw new CompletionNodeFound();
+		else
+			throw new CompletionNodeFound(this, receiverType, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java
new file mode 100644
index 0000000..ed687da
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+
+public class CompletionOnFieldName extends FieldDeclaration {
+	private static final char[] FAKENAMESUFFIX = " ".toCharArray(); //$NON-NLS-1$
+	public char[] realName;
+	public CompletionOnFieldName(char[] name, int sourceStart, int sourceEnd) {
+		super(CharOperation.concat(name, FAKENAMESUFFIX), sourceStart, sourceEnd);
+		this.realName = name;
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output).append("<CompleteOnFieldName:"); //$NON-NLS-1$
+		if (this.type != null) this.type.print(0, output).append(' ');
+		output.append(this.realName);
+		if (this.initialization != null) {
+			output.append(" = "); //$NON-NLS-1$
+			this.initialization.printExpression(0, output);
+		}
+		return output.append(">;"); //$NON-NLS-1$
+	}
+
+	public void resolve(MethodScope initializationScope) {
+		super.resolve(initializationScope);
+
+		throw new CompletionNodeFound(this, initializationScope);
+	}
+}
+
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java
new file mode 100644
index 0000000..8111049
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an type reference located as a potential return type for a class
+ * member, containing the cursor location.
+ * This node is only a fake-field wrapper of the actual completion node
+ * which is accessible as the fake-field type.
+ * e.g.
+ *
+ *	class X {
+ *    Obj[cursor]
+ *  }
+ *
+ *	---> class X {
+ *         <CompleteOnType:Obj>;
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the allocation expression are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+
+public class CompletionOnFieldType extends FieldDeclaration {
+	public boolean isLocalVariable;
+
+public CompletionOnFieldType(TypeReference type, boolean isLocalVariable){
+	super();
+	this.sourceStart = type.sourceStart;
+	this.sourceEnd = type.sourceEnd;
+	this.type = type;
+	this.name = CharOperation.NO_CHAR;
+	this.isLocalVariable = isLocalVariable;
+	if (type instanceof CompletionOnSingleTypeReference) {
+	    ((CompletionOnSingleTypeReference) type).fieldTypeCompletionNode = this;
+	}
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	return this.type.print(tab, output).append(';');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java
new file mode 100644
index 0000000..ea94bc0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an import reference containing the cursor location.
+ * e.g.
+ *
+ *  import java.io[cursor];
+ *	class X {
+ *    void foo() {
+ *    }
+ *  }
+ *
+ *	---> <CompleteOnImport:java.io>
+ *		 class X {
+ *         void foo() {
+ *         }
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the allocation expression are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+
+public class CompletionOnImportReference extends ImportReference {
+
+public CompletionOnImportReference(char[][] tokens , long[] positions, int modifiers) {
+	super(tokens, positions, false, modifiers);
+}
+public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) {
+
+	printIndent(indent, output).append("<CompleteOnImport:"); //$NON-NLS-1$
+	for (int i = 0; i < this.tokens.length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadoc.java
new file mode 100644
index 0000000..8cc60b1
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadoc.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+public interface CompletionOnJavadoc {
+
+	// Bit pattern for javadoc completion flags
+	int JAVADOC = 0x0001;
+	int EXCEPTION = 0x0002;
+	int TEXT = 0x0004;
+	int BASE_TYPES = 0x0008;
+	int ONLY_INLINE_TAG = 0x0010;
+	int REPLACE_TAG = 0x0020;
+	int FORMAL_REFERENCE = 0x0040;
+	int ALL_POSSIBLE_TAGS = 0x0080;
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags();
+
+	/**
+	 * @param flags The completionFlags to add.
+	 */
+	public void addCompletionFlags(int flags);
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocAllocationExpression.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocAllocationExpression.java
new file mode 100644
index 0000000..c2c1c4d
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocAllocationExpression.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
+
+public class CompletionOnJavadocAllocationExpression extends JavadocAllocationExpression implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public int separatorPosition;
+
+	public CompletionOnJavadocAllocationExpression(JavadocAllocationExpression allocation, int position) {
+		super(allocation.sourceStart, allocation.sourceEnd);
+		this.arguments = allocation.arguments;
+		this.type = allocation.type;
+		this.tagValue = allocation.tagValue;
+		this.sourceEnd = allocation.sourceEnd;
+		this.separatorPosition = position;
+		this.qualification = allocation.qualification;
+	}
+
+	public CompletionOnJavadocAllocationExpression(JavadocAllocationExpression allocation, int position, int flags) {
+		this(allocation, position);
+		this.completionFlags |= flags;
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	public boolean completeAnException() {
+		return (this.completionFlags & EXCEPTION) != 0;
+	}
+
+	public boolean completeInText() {
+		return (this.completionFlags & TEXT) != 0;
+	}
+
+	public boolean completeBaseTypes() {
+		return (this.completionFlags & BASE_TYPES) != 0;
+	}
+
+	public boolean completeFormalReference() {
+		return (this.completionFlags & FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AllocationExpression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompleteOnJavadocAllocationExpression:"); //$NON-NLS-1$
+		super.printExpression(indent, output);
+		indent++;
+		if (this.completionFlags > 0) {
+			output.append('\n');
+			for (int i=0; i<indent; i++) output.append('\t');
+			output.append("infos:"); //$NON-NLS-1$
+			char separator = 0;
+			if (completeAnException()) {
+				output.append("exception"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeInText()) {
+				if (separator != 0) output.append(separator);
+				output.append("text"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeBaseTypes()) {
+				if (separator != 0) output.append(separator);
+				output.append("base types"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeFormalReference()) {
+				if (separator != 0) output.append(separator);
+				output.append("formal reference"); //$NON-NLS-1$
+				separator = ',';
+			}
+			output.append('\n');
+		}
+		indent--;
+		for (int i=0; i<indent; i++) output.append('\t');
+		return output.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java
new file mode 100644
index 0000000..4576958
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocFieldReference.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnJavadocFieldReference extends JavadocFieldReference implements CompletionOnJavadoc {
+//	public boolean completionInText;
+	public int completionFlags = JAVADOC;
+	public int separatorPosition;
+
+	public CompletionOnJavadocFieldReference(Expression receiver, int tag, int position, int separatorPos, char[] name) {
+		super(null, (((long)position)<<32)+position-1);
+		this.receiver = receiver;
+		this.tagSourceStart = position;
+		this.tagSourceEnd = position;
+		this.tagValue = tag;
+		this.separatorPosition = separatorPos;
+	}
+
+	public CompletionOnJavadocFieldReference(JavadocFieldReference fieldRef, int position, char[] name) {
+		super(fieldRef.token, fieldRef.nameSourcePosition);
+		this.receiver = fieldRef.receiver;
+		this.separatorPosition = position;
+		this.tagSourceStart = fieldRef.tagSourceStart;
+		this.tagSourceEnd = fieldRef.tagSourceEnd;
+		this.tagValue = fieldRef.tagValue;
+	}
+
+	public CompletionOnJavadocFieldReference(JavadocMessageSend msgSend, int position) {
+		super(msgSend.selector, ((msgSend.nameSourcePosition>>32)<<32)+msgSend.sourceEnd);
+		this.receiver = msgSend.receiver;
+		this.separatorPosition = position;
+		this.tagSourceStart = msgSend.tagSourceStart;
+		this.tagSourceEnd = msgSend.tagSourceEnd;
+		this.tagValue = msgSend.tagValue;
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	public boolean completeAnException() {
+		return (this.completionFlags & EXCEPTION) != 0;
+	}
+
+	public boolean completeInText() {
+		return (this.completionFlags & TEXT) != 0;
+	}
+
+	public boolean completeBaseTypes() {
+		return (this.completionFlags & BASE_TYPES) != 0;
+	}
+
+	public boolean completeFormalReference() {
+		return (this.completionFlags & FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference#internalResolveType(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding internalResolveType(Scope scope) {
+
+		if (this.token != null) {
+			return super.internalResolveType(scope);
+		}
+
+		// Resolve only receiver
+		if (this.receiver == null) {
+			this.actualReceiverType = scope.enclosingSourceType();
+		} else if (scope.kind == Scope.CLASS_SCOPE) {
+			this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
+		} else {
+			this.actualReceiverType = this.receiver.resolveType((BlockScope)scope);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompleteOnJavadocFieldReference:"); //$NON-NLS-1$
+		super.printExpression(indent, output);
+		indent++;
+		if (this.completionFlags > 0) {
+			output.append('\n');
+			for (int i=0; i<indent; i++) output.append('\t');
+			output.append("infos:"); //$NON-NLS-1$
+			char separator = 0;
+			if (completeAnException()) {
+				output.append("exception"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeInText()) {
+				if (separator != 0) output.append(separator);
+				output.append("text"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeBaseTypes()) {
+				if (separator != 0) output.append(separator);
+				output.append("base types"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeFormalReference()) {
+				if (separator != 0) output.append(separator);
+				output.append("formal reference"); //$NON-NLS-1$
+				separator = ',';
+			}
+			output.append('\n');
+		}
+		indent--;
+		for (int i=0; i<indent; i++) output.append('\t');
+		return output.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocMessageSend.java
new file mode 100644
index 0000000..133c34b
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocMessageSend.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
+
+public class CompletionOnJavadocMessageSend extends JavadocMessageSend implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public int separatorPosition;
+
+	public CompletionOnJavadocMessageSend(JavadocMessageSend method, int position) {
+		super(method.selector, method.nameSourcePosition);
+		this.arguments = method.arguments;
+		this.receiver = method.receiver;
+		this.sourceEnd = method.sourceEnd;
+		this.tagValue = method.tagValue;
+		this.separatorPosition = position;
+	}
+
+	public CompletionOnJavadocMessageSend(JavadocMessageSend method, int position, int flags) {
+		this(method, position);
+		this.completionFlags |= flags;
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	public boolean completeAnException() {
+		return (this.completionFlags & EXCEPTION) != 0;
+	}
+
+	public boolean completeInText() {
+		return (this.completionFlags & TEXT) != 0;
+	}
+
+	public boolean completeBaseTypes() {
+		return (this.completionFlags & BASE_TYPES) != 0;
+	}
+
+	public boolean completeFormalReference() {
+		return (this.completionFlags & FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompleteOnJavadocMessageSend:"); //$NON-NLS-1$
+		super.printExpression(indent, output);
+		indent++;
+		if (this.completionFlags > 0) {
+			output.append('\n');
+			for (int i=0; i<indent; i++) output.append('\t');
+			output.append("infos:"); //$NON-NLS-1$
+			char separator = 0;
+			if (completeAnException()) {
+				output.append("exception"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeInText()) {
+				if (separator != 0) output.append(separator);
+				output.append("text"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeBaseTypes()) {
+				if (separator != 0) output.append(separator);
+				output.append("base types"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeFormalReference()) {
+				if (separator != 0) output.append(separator);
+				output.append("formal reference"); //$NON-NLS-1$
+				separator = ',';
+			}
+			output.append('\n');
+		}
+		indent--;
+		for (int i=0; i<indent; i++) output.append('\t');
+		return output.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocParamNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocParamNameReference.java
new file mode 100644
index 0000000..d5723ee
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocParamNameReference.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnJavadocParamNameReference extends JavadocSingleNameReference implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public char[][] missingParams;
+	public char[][] missingTypeParams;
+
+	public CompletionOnJavadocParamNameReference(char[] name, long pos, int start, int end) {
+		super(name, pos, start, end);
+	}
+
+	public CompletionOnJavadocParamNameReference(JavadocSingleNameReference nameRef) {
+		super(nameRef.token, (((long)nameRef.sourceStart)<<32)+nameRef.sourceEnd, nameRef.tagSourceStart, nameRef.tagSourceStart);
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AllocationExpression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompletionOnJavadocParamNameReference:"); //$NON-NLS-1$
+		if (this.token != null) super.printExpression(indent, output);
+		return output.append('>');
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.SingleNameReference#reportError(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public TypeBinding reportError(BlockScope scope) {
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocQualifiedTypeReference.java
new file mode 100644
index 0000000..f6e4a31
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocQualifiedTypeReference.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference;
+
+public class CompletionOnJavadocQualifiedTypeReference extends JavadocQualifiedTypeReference implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public char[] completionIdentifier;
+
+	public CompletionOnJavadocQualifiedTypeReference(char[][] sources, char[] identifier, long[] pos, int tagStart, int tagEnd) {
+		super(sources, pos, tagStart, tagEnd);
+		this.completionIdentifier = identifier;
+	}
+
+	public CompletionOnJavadocQualifiedTypeReference(JavadocQualifiedTypeReference typeRef) {
+		super(typeRef.tokens, typeRef.sourcePositions, typeRef.tagSourceStart, typeRef.tagSourceStart);
+		this.completionIdentifier = CharOperation.NO_CHAR;
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	public boolean completeAnException() {
+		return (this.completionFlags & EXCEPTION) != 0;
+	}
+
+	public boolean completeInText() {
+		return (this.completionFlags & TEXT) != 0;
+	}
+
+	public boolean completeBaseTypes() {
+		return (this.completionFlags & BASE_TYPES) != 0;
+	}
+
+	public boolean completeFormalReference() {
+		return (this.completionFlags & FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompletionOnJavadocQualifiedTypeReference:"); //$NON-NLS-1$
+		super.printExpression(indent, output);
+		indent++;
+		if (this.completionFlags > 0) {
+			output.append('\n');
+			for (int i=0; i<indent; i++) output.append('\t');
+			output.append("infos:"); //$NON-NLS-1$
+			char separator = 0;
+			if (completeAnException()) {
+				output.append("exception"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeInText()) {
+				if (separator != 0) output.append(separator);
+				output.append("text"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeBaseTypes()) {
+				if (separator != 0) output.append(separator);
+				output.append("base types"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeFormalReference()) {
+				if (separator != 0) output.append(separator);
+				output.append("formal reference"); //$NON-NLS-1$
+				separator = ',';
+			}
+			output.append('\n');
+		}
+		indent--;
+		for (int i=0; i<indent; i++) output.append('\t');
+		return output.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocSingleTypeReference.java
new file mode 100644
index 0000000..113b419
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocSingleTypeReference.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
+
+public class CompletionOnJavadocSingleTypeReference extends JavadocSingleTypeReference implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+
+	public CompletionOnJavadocSingleTypeReference(char[] source, long pos, int tagStart, int tagEnd) {
+		super(source, pos, tagStart, tagEnd);
+	}
+
+	public CompletionOnJavadocSingleTypeReference(JavadocSingleTypeReference typeRef) {
+		super(typeRef.token, (((long)typeRef.sourceStart)<<32)+typeRef.sourceEnd, typeRef.tagSourceStart, typeRef.tagSourceStart);
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	public boolean completeAnException() {
+		return (this.completionFlags & EXCEPTION) != 0;
+	}
+
+	public boolean completeInText() {
+		return (this.completionFlags & TEXT) != 0;
+	}
+
+	public boolean completeBaseTypes() {
+		return (this.completionFlags & BASE_TYPES) != 0;
+	}
+
+	public boolean completeFormalReference() {
+		return (this.completionFlags & FORMAL_REFERENCE) != 0;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.SingleTypeReference#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompletionOnJavadocSingleTypeReference:"); //$NON-NLS-1$
+		super.printExpression(indent, output);
+		indent++;
+		if (this.completionFlags > 0) {
+			output.append('\n');
+			for (int i=0; i<indent; i++) output.append('\t');
+			output.append("infos:"); //$NON-NLS-1$
+			char separator = 0;
+			if (completeAnException()) {
+				output.append("exception"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeInText()) {
+				if (separator != 0) output.append(separator);
+				output.append("text"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeBaseTypes()) {
+				if (separator != 0) output.append(separator);
+				output.append("base types"); //$NON-NLS-1$
+				separator = ',';
+			}
+			if (completeFormalReference()) {
+				if (separator != 0) output.append(separator);
+				output.append("formal reference"); //$NON-NLS-1$
+				separator = ',';
+			}
+			output.append('\n');
+		}
+		indent--;
+		for (int i=0; i<indent; i++) output.append('\t');
+		return output.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java
new file mode 100644
index 0000000..afaa1d9
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTag.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+
+public class CompletionOnJavadocTag extends JavadocSingleNameReference implements JavadocTagConstants, CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public final static char[][][] NO_CHAR_CHAR_CHAR = new char[0][][];
+	private char[][][] possibleTags = NO_CHAR_CHAR_CHAR;
+
+	public CompletionOnJavadocTag(char[] source, long pos, int tagStart, int tagEnd, char[][][] possibleTags, boolean orphan) {
+		super(source, pos, tagStart, tagEnd);
+		this.possibleTags = possibleTags;
+		if (orphan) this.completionFlags |= ALL_POSSIBLE_TAGS;
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AllocationExpression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompleteOnJavadocTag:"); //$NON-NLS-1$
+		output.append('@');
+		if (this.token != null) super.printExpression(indent, output);
+		// Print block tags
+		char[][] blockTags = this.possibleTags[BLOCK_IDX];
+		if (blockTags != null) {
+			int length=blockTags.length;
+			if (length > 0) {
+				output.append("\npossible block tags:"); //$NON-NLS-1$
+				for (int i=0; i<length; i++) {
+					output.append("\n	- "); //$NON-NLS-1$
+					output.append(blockTags[i]);
+				}
+				output.append('\n');
+			}
+		}
+		// Print inline tags
+		char[][] inlineTags = this.possibleTags[INLINE_IDX];
+		if (inlineTags != null) {
+			int length=inlineTags.length;
+			if (length > 0) {
+				output.append("\npossible inline tags:"); //$NON-NLS-1$
+				for (int i=0; i<length; i++) {
+					output.append("\n	- "); //$NON-NLS-1$
+					output.append(inlineTags[i]);
+				}
+				output.append('\n');
+			}
+		}
+		return output.append('>');
+	}
+
+	public void filterPossibleTags(Scope scope) {
+		if (this.possibleTags == null || this.possibleTags.length == 0 || (this.completionFlags & ALL_POSSIBLE_TAGS) != 0) {
+			return;
+		}
+		int kind = scope.kind;
+		char[][] specifiedTags = null;
+		switch (kind) {
+			case Scope.COMPILATION_UNIT_SCOPE:
+				// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=255752
+				// Check for FAKE_TYPE_NAME to allow proposals (@see CompletionParser#consumeCompilationUnit)
+				CompilationUnitDeclaration compilationUnit = scope.referenceCompilationUnit();
+				if (compilationUnit != null &&
+						(compilationUnit.types.length > 0 && compilationUnit.types[0].name == CompletionParser.FAKE_TYPE_NAME)) {
+					specifiedTags = CLASS_TAGS;
+				} else {
+					specifiedTags = COMPILATION_UNIT_TAGS;
+				}
+				break;
+			case Scope.CLASS_SCOPE:
+				specifiedTags = CLASS_TAGS;
+				break;
+			case Scope.METHOD_SCOPE:
+				MethodScope methodScope = (MethodScope) scope;
+				if (methodScope.referenceMethod() == null) {
+					if (methodScope.initializedField == null) {
+						specifiedTags = PACKAGE_TAGS;
+					} else {
+						specifiedTags = FIELD_TAGS;
+					}
+				} else {
+					specifiedTags = METHOD_TAGS;
+				}
+				break;
+			default:
+				return;
+		}
+		int kinds = this.possibleTags.length;
+		for (int k=0; k<kinds; k++) {
+			int length = this.possibleTags[k].length;
+			int specLenth = specifiedTags.length;
+			char[][] filteredTags = new char[length][];
+			int size = 0;
+			for (int i=0; i<length; i++) {
+				char[] possibleTag = this.possibleTags[k][i];
+				for (int j=0; j<specLenth; j++) {
+					if (possibleTag[0] == specifiedTags[j][0] && CharOperation.equals(possibleTag, specifiedTags[j])) {
+						if (possibleTag == TAG_PARAM) {
+							switch (scope.kind) {
+								case Scope.CLASS_SCOPE:
+									if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+										if (((ClassScope)scope).referenceContext.binding.isGenericType()) {
+											filteredTags[size++] = possibleTag;
+										}
+									}
+									break;
+								case Scope.COMPILATION_UNIT_SCOPE:
+									if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+										filteredTags[size++] = possibleTag;
+									}
+									break;
+								default:
+									filteredTags[size++] = possibleTag;
+									break;
+							}
+						} else {
+							filteredTags[size++] = possibleTag;
+						}
+						break;
+					}
+				}
+			}
+			if (size<length) {
+				System.arraycopy(filteredTags, 0, this.possibleTags[k] = new char[size][], 0, size);
+			}
+		}
+	}
+
+	/**
+	 * Return possible block tags
+	 *
+	 * @return char[][]
+	 */
+	public char[][] getPossibleBlockTags() {
+		return this.possibleTags[BLOCK_IDX];
+	}
+
+	/**
+	 * Return possible inline tags
+	 *
+	 * @return char[][]
+	 */
+	public char[][] getPossibleInlineTags() {
+		return this.possibleTags[INLINE_IDX];
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTypeParamReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTypeParamReference.java
new file mode 100644
index 0000000..2ae2acf
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnJavadocTypeParamReference.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnJavadocTypeParamReference extends JavadocSingleTypeReference implements CompletionOnJavadoc {
+	public int completionFlags = JAVADOC;
+	public char[][] missingParams;
+
+	public CompletionOnJavadocTypeParamReference(char[] name, long pos, int start, int end) {
+		super(name, pos, start, end);
+	}
+
+	public CompletionOnJavadocTypeParamReference(JavadocSingleTypeReference typeRef) {
+		super(typeRef.token, (((long)typeRef.sourceStart)<<32)+typeRef.sourceEnd, typeRef.tagSourceStart, typeRef.tagSourceStart);
+	}
+
+	/**
+	 * @param flags The completionFlags to set.
+	 */
+	public void addCompletionFlags(int flags) {
+		this.completionFlags |= flags;
+	}
+
+	/**
+	 * Get completion node flags.
+	 *
+	 * @return int Flags of the javadoc completion node.
+	 */
+	public int getCompletionFlags() {
+		return this.completionFlags;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AllocationExpression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompletionOnJavadocTypeParamReference:"); //$NON-NLS-1$
+		if (this.token != null) super.printExpression(indent, output);
+		return output.append('>');
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.SingleNameReference#reportError(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public TypeBinding reportError(BlockScope scope) {
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
new file mode 100644
index 0000000..62e927e
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+public interface CompletionOnKeyword {
+
+	char[] getToken();
+	char[][] getPossibleKeywords();
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
new file mode 100644
index 0000000..7bd9125
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnKeyword1 extends SingleTypeReference implements CompletionOnKeyword {
+	private char[][] possibleKeywords;
+
+	public CompletionOnKeyword1(char[] token, long pos, char[] possibleKeyword) {
+		this(token, pos, new char[][]{possibleKeyword});
+	}
+	public CompletionOnKeyword1(char[] token, long pos, char[][] possibleKeywords) {
+		super(token, pos);
+		this.possibleKeywords = possibleKeywords;
+	}
+	public char[] getToken() {
+		return this.token;
+	}
+	public char[][] getPossibleKeywords() {
+		return this.possibleKeywords;
+	}
+	public void aboutToResolve(Scope scope) {
+		getTypeBinding(scope);
+	}
+	protected TypeBinding getTypeBinding(Scope scope) {
+		throw new CompletionNodeFound(this, scope);
+	}
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		return output.append("<CompleteOnKeyword:").append(this.token).append('>');  //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
new file mode 100644
index 0000000..017f200
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class CompletionOnKeyword2 extends ImportReference implements CompletionOnKeyword {
+	private char[] token;
+	private char[][] possibleKeywords;
+	public CompletionOnKeyword2(char[] token, long pos, char[][] possibleKeywords) {
+		super(new char[][]{token}, new long[]{pos}, false, ClassFileConstants.AccDefault);
+		this.token = token;
+		this.possibleKeywords = possibleKeywords;
+	}
+	public char[] getToken() {
+		return this.token;
+	}
+	public char[][] getPossibleKeywords() {
+		return this.possibleKeywords;
+	}
+	public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) {
+
+		return printIndent(indent, output).append("<CompleteOnKeyword:").append(this.token).append('>'); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
new file mode 100644
index 0000000..eea71b5
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnKeyword3 extends SingleNameReference implements CompletionOnKeyword{
+	private char[][] possibleKeywords;
+	public CompletionOnKeyword3(char[] token, long pos, char[] possibleKeyword) {
+		this(token, pos, new char[][]{possibleKeyword});
+	}
+	public CompletionOnKeyword3(char[] token, long pos, char[][] possibleKeywords) {
+		super(token, pos);
+		this.token = token;
+		this.possibleKeywords = possibleKeywords;
+	}
+	public char[] getToken() {
+		return this.token;
+	}
+	public char[][] getPossibleKeywords() {
+		return this.possibleKeywords;
+	}
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		return output.append("<CompleteOnKeyword:").append(this.token).append('>'); //$NON-NLS-1$
+	}
+	public TypeBinding resolveType(BlockScope scope) {
+		throw new CompletionNodeFound(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java
new file mode 100644
index 0000000..f59f03d
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+
+public class CompletionOnLocalName extends LocalDeclaration {
+	private static final char[] FAKENAMESUFFIX = " ".toCharArray(); //$NON-NLS-1$
+	public char[] realName;
+
+	public CompletionOnLocalName(char[] name, int sourceStart, int sourceEnd){
+
+		super(CharOperation.concat(name, FAKENAMESUFFIX), sourceStart, sourceEnd);
+		this.realName = name;
+	}
+
+	public void resolve(BlockScope scope) {
+
+		super.resolve(scope);
+		throw new CompletionNodeFound(this, scope);
+	}
+
+	public StringBuffer printAsExpression(int indent, StringBuffer output) {
+		printIndent(indent, output);
+		output.append("<CompleteOnLocalName:"); //$NON-NLS-1$
+		if (this.type != null)  this.type.print(0, output).append(' ');
+		output.append(this.realName);
+		if (this.initialization != null) {
+			output.append(" = "); //$NON-NLS-1$
+			this.initialization.printExpression(0, output);
+		}
+		return output.append('>');
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		printAsExpression(indent, output);
+		return output.append(';');
+	}
+}
+
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java
new file mode 100644
index 0000000..a802d93
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnMarkerAnnotationName extends MarkerAnnotation {
+	public CompletionOnMarkerAnnotationName(TypeReference type, int sourceStart){
+		super(type, sourceStart);
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		if(this.type instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) this.type;
+			Binding binding = scope.parent.getTypeOrPackage(qualifiedTypeReference.tokens); // step up from the ClassScope
+			if (!binding.isValidBinding()) {
+				scope.problemReporter().invalidType(this, (TypeBinding) binding);
+				throw new CompletionNodeFound();
+			}
+			throw new CompletionNodeFound(this, binding, scope);
+		}
+		throw new CompletionNodeFound(this, null, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
new file mode 100644
index 0000000..73d4fc7
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an access to a member (field reference or message send)
+ * containing the completion identifier.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      bar().fred[cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <CompleteOnMemberAccess:bar().fred>
+ *         }
+ *       }
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnMemberAccess extends FieldReference {
+
+	public boolean isInsideAnnotation;
+
+	public CompletionOnMemberAccess(char[] source, long pos, boolean isInsideAnnotation) {
+
+		super(source, pos);
+		this.isInsideAnnotation = isInsideAnnotation;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<CompleteOnMemberAccess:"); //$NON-NLS-1$
+		return super.printExpression(0, output).append('>');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		this.actualReceiverType = this.receiver.resolveType(scope);
+
+		if ((this.actualReceiverType == null || !this.actualReceiverType.isValidBinding()) && this.receiver instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) this.receiver;
+			if(messageSend.receiver instanceof ThisReference) {
+				Expression[] arguments = messageSend.arguments;
+				int length = arguments == null ? 0 : arguments.length;
+				TypeBinding[] argBindings = new TypeBinding[length];
+				for (int i = 0; i < length; i++) {
+					argBindings[i] = arguments[i].resolvedType;
+					if(argBindings[i] == null || !argBindings[i].isValidBinding()) {
+						throw new CompletionNodeFound();
+					}
+				}
+
+				ProblemMethodBinding problemMethodBinding = new ProblemMethodBinding(messageSend.selector, argBindings, ProblemReasons.NotFound);
+				throw new CompletionNodeFound(this, problemMethodBinding, scope);
+			}
+		}
+
+		if (this.actualReceiverType == null || this.actualReceiverType.isBaseType() || !this.actualReceiverType.isValidBinding())
+			throw new CompletionNodeFound();
+		else
+			throw new CompletionNodeFound(this, this.actualReceiverType, scope);
+		// array types are passed along to find the length field
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java
new file mode 100644
index 0000000..913afd6
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce annotation's attribute name containing the cursor.
+ * e.g.
+ *
+ *	@Annot(attri[cursor]
+ *	class X {
+ *  }
+ *
+ *	---> @Annot(<CompletionOnAttributeName:attri>)
+ *		 class X {
+ *       }
+ */
+public class CompletionOnMemberValueName extends MemberValuePair {
+	public CompletionOnMemberValueName(char[] token, int sourceStart, int sourceEnd) {
+		super(token, sourceStart, sourceEnd, null);
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+		output.append("<CompleteOnAttributeName:"); //$NON-NLS-1$
+		output.append(this.name);
+		output.append('>');
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
new file mode 100644
index 0000000..2a46134
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a message send containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      this.bar(1, 2, [cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <CompleteOnMessageSend:this.bar(1, 2)>
+ *         }
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the message send are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnMessageSend extends MessageSend {
+
+	public TypeBinding resolveType(BlockScope scope) {
+		this.constant = Constant.NotAConstant;
+		if (this.arguments != null) {
+			int argsLength = this.arguments.length;
+			for (int a = argsLength; --a >= 0;)
+				this.arguments[a].resolveType(scope);
+		}
+
+		if (this.receiver.isImplicitThis())
+			throw new CompletionNodeFound(this, null, scope);
+
+		this.actualReceiverType = this.receiver.resolveType(scope);
+		if (this.actualReceiverType == null || this.actualReceiverType.isBaseType())
+			throw new CompletionNodeFound();
+
+		if (this.actualReceiverType.isArrayType())
+			this.actualReceiverType = scope.getJavaLangObject();
+		throw new CompletionNodeFound(this, this.actualReceiverType, scope);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<CompleteOnMessageSend:"); //$NON-NLS-1$
+		if (!this.receiver.isImplicitThis()) this.receiver.printExpression(0, output).append('.');
+		if (this.typeArguments != null) {
+			output.append('<');
+			int max = this.typeArguments.length - 1;
+			for (int j = 0; j < max; j++) {
+				this.typeArguments[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+			output.append('>');
+		}
+		output.append(this.selector).append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(")>"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSendName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSendName.java
new file mode 100644
index 0000000..b90eafb
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSendName.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnMessageSendName extends MessageSend {
+	public CompletionOnMessageSendName(char[] selector, int start, int end) {
+		super();
+		this.selector = selector;
+		this.sourceStart = start;
+		this.sourceEnd = end;
+		this.nameSourcePosition = end;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		this.constant = Constant.NotAConstant;
+		
+		if (this.receiver.isImplicitThis())
+			throw new CompletionNodeFound();
+
+		this.actualReceiverType = this.receiver.resolveType(scope);
+		if (this.actualReceiverType == null || this.actualReceiverType.isBaseType() || this.actualReceiverType.isArrayType())
+			throw new CompletionNodeFound();
+
+		// resolve type arguments
+		if (this.typeArguments != null) {
+			int length = this.typeArguments.length;
+			this.genericTypeArguments = new TypeBinding[length];
+			for (int i = 0; i < length; i++) {
+				this.genericTypeArguments[i] = this.typeArguments[i].resolveType(scope, true /* check bounds*/);
+			}
+		}
+
+		throw new CompletionNodeFound(this, this.actualReceiverType, scope);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<CompleteOnMessageSendName:"); //$NON-NLS-1$
+		if (!this.receiver.isImplicitThis()) this.receiver.printExpression(0, output).append('.');
+		if (this.typeArguments != null) {
+			output.append('<');
+			int max = this.typeArguments.length - 1;
+			for (int j = 0; j < max; j++) {
+				this.typeArguments[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+			output.append('>');
+		}
+		output.append(this.selector).append('(');
+		return output.append(")>"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java
new file mode 100644
index 0000000..43ad896
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+
+public class CompletionOnMethodName extends MethodDeclaration {
+	public int selectorEnd;
+
+	public CompletionOnMethodName(CompilationResult compilationResult){
+		super(compilationResult);
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		printIndent(indent, output);
+		output.append("<CompletionOnMethodName:"); //$NON-NLS-1$
+		printModifiers(this.modifiers, output);
+		printReturnType(0, output);
+		output.append(this.selector).append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].print(0, output);
+			}
+		}
+		output.append(')');
+		if (this.thrownExceptions != null) {
+			output.append(" throws "); //$NON-NLS-1$
+			for (int i = 0; i < this.thrownExceptions.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.thrownExceptions[i].print(0, output);
+			}
+		}
+		return output.append('>');
+	}
+
+	public void resolve(ClassScope upperScope) {
+
+		super.resolve(upperScope);
+		throw new CompletionNodeFound(this, upperScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java
new file mode 100644
index 0000000..9e4509b
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+
+public class CompletionOnMethodReturnType extends MethodDeclaration {
+	public CompletionOnMethodReturnType(TypeReference returnType, CompilationResult compilationResult){
+		super(compilationResult);
+		this.returnType = returnType;
+		this.sourceStart = returnType.sourceStart;
+		this.sourceEnd = returnType.sourceEnd;
+	}
+
+	public void resolveStatements() {
+			throw new CompletionNodeFound(this, this.scope);
+	}
+
+	public StringBuffer print(int tab, StringBuffer output) {
+		return this.returnType.print(tab, output);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java
new file mode 100644
index 0000000..7d0b289
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+
+public class CompletionOnMethodTypeParameter extends MethodDeclaration {
+	public CompletionOnMethodTypeParameter(TypeParameter[] typeParameters, CompilationResult compilationResult){
+		super(compilationResult);
+		this.selector = CharOperation.NO_CHAR;
+		this.typeParameters = typeParameters;
+		this.sourceStart = typeParameters[0].sourceStart;
+		this.sourceEnd = typeParameters[typeParameters.length - 1].sourceEnd;
+	}
+
+	public void resolveStatements() {
+			throw new CompletionNodeFound(this, this.scope);
+	}
+
+	public StringBuffer print(int tab, StringBuffer output) {
+		printIndent(tab, output);
+		output.append('<');
+		int max = this.typeParameters.length - 1;
+		for (int j = 0; j < max; j++) {
+			this.typeParameters[j].print(0, output);
+			output.append(", ");//$NON-NLS-1$
+		}
+		this.typeParameters[max].print(0, output);
+		output.append('>');
+		return output;
+	}
+
+}
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
new file mode 100644
index 0000000..1364ced
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an package statement containing the cursor location.
+ * e.g.
+ *
+ *  package java.io[cursor];
+ *	class X {
+ *    void foo() {
+ *    }
+ *  }
+ *
+ *	---> <CompleteOnPackage:java.io>
+ *		 class X {
+ *         void foo() {
+ *         }
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the allocation expression are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class CompletionOnPackageReference extends ImportReference {
+public CompletionOnPackageReference(char[][] tokens , long[] positions) {
+	super(tokens, positions, false, ClassFileConstants.AccDefault);
+}
+public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) {
+
+	printIndent(indent, output).append("<CompleteOnPackage:"); //$NON-NLS-1$
+	for (int i = 0; i < this.tokens.length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java
new file mode 100644
index 0000000..487813c
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a type reference containing the completion identifier as part
+ * of a parameterized qualified name.
+ * e.g.
+ *
+ *	class X extends Y<Z>.W[cursor]
+ *
+ *	---> class X extends <CompleteOnType:Y<Z>.W>
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class CompletionOnParameterizedQualifiedTypeReference extends ParameterizedQualifiedTypeReference {
+	public static final int K_TYPE = 0;
+	public static final int K_CLASS = 1;
+	public static final int K_INTERFACE = 2;
+	public static final int K_EXCEPTION = 3;
+
+	private int kind = K_TYPE;
+	public char[] completionIdentifier;
+	/**
+	 * @param tokens
+	 * @param typeArguments
+	 * @param positions
+	 */
+	public CompletionOnParameterizedQualifiedTypeReference(char[][] tokens,	TypeReference[][] typeArguments, char[] completionIdentifier, long[] positions) {
+		this(tokens, typeArguments, completionIdentifier, positions, K_TYPE);
+	}
+
+	/**
+	 * @param tokens
+	 * @param typeArguments
+	 * @param positions
+	 * @param kind
+	 */
+	public CompletionOnParameterizedQualifiedTypeReference(char[][] tokens,	TypeReference[][] typeArguments, char[] completionIdentifier, long[] positions, int kind) {
+		super(tokens, typeArguments, 0, positions);
+		this.completionIdentifier = completionIdentifier;
+		this.kind = kind;
+	}
+
+	public boolean isClass(){
+		return this.kind == K_CLASS;
+	}
+
+	public boolean isInterface(){
+		return this.kind == K_INTERFACE;
+	}
+
+	public boolean isException(){
+		return this.kind == K_EXCEPTION;
+	}
+
+	public boolean isSuperType(){
+		return this.kind == K_CLASS || this.kind == K_INTERFACE;
+	}
+
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		super.resolveType(scope, checkBounds);
+		throw new CompletionNodeFound(this, this.resolvedType, scope);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		super.resolveType(scope);
+		throw new CompletionNodeFound(this, this.resolvedType, scope);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		switch (this.kind) {
+			case K_CLASS :
+				output.append("<CompleteOnClass:");//$NON-NLS-1$
+				break;
+			case K_INTERFACE :
+				output.append("<CompleteOnInterface:");//$NON-NLS-1$
+				break;
+			case K_EXCEPTION :
+				output.append("<CompleteOnException:");//$NON-NLS-1$
+				break;
+			default :
+				output.append("<CompleteOnType:");//$NON-NLS-1$
+				break;
+		}
+		int length = this.tokens.length;
+		for (int i = 0; i < length - 1; i++) {
+			output.append(this.tokens[i]);
+			TypeReference[] typeArgument = this.typeArguments[i];
+			if (typeArgument != null) {
+				output.append('<');
+				int max = typeArgument.length - 1;
+				for (int j = 0; j < max; j++) {
+					typeArgument[j].print(0, output);
+					output.append(", ");//$NON-NLS-1$
+				}
+				typeArgument[max].print(0, output);
+				output.append('>');
+			}
+			output.append('.');
+		}
+		output.append(this.tokens[length - 1]);
+		TypeReference[] typeArgument = this.typeArguments[length - 1];
+		if (typeArgument != null) {
+			output.append('<');
+			int max = typeArgument.length - 1;
+			for (int j = 0; j < max; j++) {
+				typeArgument[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			typeArgument[max].print(0, output);
+			output.append('>');
+		}
+		output.append('.').append(this.completionIdentifier).append('>');
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java
new file mode 100644
index 0000000..f159de0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce an allocation expression containing the cursor.
+ * If the allocation expression is not qualified, the enclosingInstance field
+ * is null.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      new Bar(1, 2, [cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <CompleteOnAllocationExpression:new Bar(1, 2)>
+ *         }
+ *       }
+ *
+ * The source range is always of length 0.
+ * The arguments of the allocation expression are all the arguments defined
+ * before the cursor.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnQualifiedAllocationExpression extends QualifiedAllocationExpression {
+public TypeBinding resolveType(BlockScope scope) {
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+	if (this.arguments != null) {
+		int argsLength = this.arguments.length;
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		for (int a = argsLength; --a >= 0;) {
+			argumentTypes[a] = this.arguments[a].resolveType(scope);
+		}
+	}
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+	if (this.enclosingInstance != null) {
+		TypeBinding enclosingType = this.enclosingInstance.resolveType(scope);
+		if (enclosingType == null) {
+			// try to propose something even if enclosing type cannot be resolved.
+			// Eg.: new Test<>().new Test<>(#cursor#
+			if (this.enclosingInstance instanceof AllocationExpression) {
+				TypeReference enclosingInstanceType = ((AllocationExpression) this.enclosingInstance).type;
+				if (enclosingInstanceType != null) {
+					enclosingType = enclosingInstanceType.resolvedType;
+				}
+			}
+		}
+		if (enclosingType == null || !(enclosingType instanceof ReferenceBinding)) {
+			throw new CompletionNodeFound();
+		}
+		this.resolvedType = ((SingleTypeReference) this.type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingType);
+		if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
+			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+			if (inferredTypes != null) {
+				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+			} else {
+				// inference failed. Resolved type will be of the form Test<>
+				this.bits |= ASTNode.IsDiamond;
+			}
+	 	}
+		if (!(this.resolvedType instanceof ReferenceBinding))
+			throw new CompletionNodeFound(); // no need to continue if its an array or base type
+		if (this.resolvedType.isInterface()) // handle the anonymous class definition case
+			this.resolvedType = scope.getJavaLangObject();
+	} else {
+	 	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+	 	if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
+			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+			if (inferredTypes != null) {
+				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+			} else {
+				// inference failed. Resolved type will be of the form Test<>
+				this.bits |= ASTNode.IsDiamond;
+			}
+	 	}
+		if (!(this.resolvedType instanceof ReferenceBinding))
+			throw new CompletionNodeFound(); // no need to continue if its an array or base type
+	}
+
+	throw new CompletionNodeFound(this, this.resolvedType, scope);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	if (this.enclosingInstance == null)
+		output.append("<CompleteOnAllocationExpression:" );  //$NON-NLS-1$
+	else
+		output.append("<CompleteOnQualifiedAllocationExpression:");  //$NON-NLS-1$
+	return super.printExpression(indent, output).append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java
new file mode 100644
index 0000000..9c793bd
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a qualified name reference containing the completion identifier.
+ * e.g.
+ *
+ *	class X {
+ *    Y y;
+ *    void foo() {
+ *      y.fred.ba[cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         Y y;
+ *         void foo() {
+ *           <CompleteOnName:y.fred.ba>
+ *         }
+ *       }
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnQualifiedNameReference extends QualifiedNameReference {
+	public char[] completionIdentifier;
+	public boolean isInsideAnnotationAttribute;
+public CompletionOnQualifiedNameReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions, boolean isInsideAnnotationAttribute) {
+	super(previousIdentifiers, positions, (int) (positions[0] >>> 32), (int) positions[positions.length - 1]);
+	this.completionIdentifier = completionIdentifier;
+	this.isInsideAnnotationAttribute = isInsideAnnotationAttribute;
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+
+	output.append("<CompleteOnName:"); //$NON-NLS-1$
+	for (int i = 0; i < this.tokens.length; i++) {
+		output.append(this.tokens[i]);
+		output.append('.');
+	}
+	output.append(this.completionIdentifier).append('>');
+	return output;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// it can be a package, type, member type, local variable or field
+	this.binding = scope.getBinding(this.tokens, this);
+	if (!this.binding.isValidBinding()) {
+		if (this.binding instanceof ProblemFieldBinding) {
+			scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
+		} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
+			scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
+		} else {
+			scope.problemReporter().unresolvableReference(this, this.binding);
+		}
+
+		if (this.binding.problemId() == ProblemReasons.NotFound) {
+			throw new CompletionNodeFound(this, this.binding, scope);
+		}
+
+		throw new CompletionNodeFound();
+	}
+
+	throw new CompletionNodeFound(this, this.binding, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
new file mode 100644
index 0000000..6861b53
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a type reference containing the completion identifier as part
+ * of a qualified name.
+ * e.g.
+ *
+ *	class X extends java.lang.Obj[cursor]
+ *
+ *	---> class X extends <CompleteOnType:java.lang.Obj>
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnQualifiedTypeReference extends QualifiedTypeReference {
+	public static final int K_TYPE = 0;
+	public static final int K_CLASS = 1;
+	public static final int K_INTERFACE = 2;
+	public static final int K_EXCEPTION = 3;
+
+	private int kind = K_TYPE;
+	public char[] completionIdentifier;
+	
+	public boolean isConstructorType;
+	
+public CompletionOnQualifiedTypeReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions) {
+	this(previousIdentifiers, completionIdentifier, positions, K_TYPE);
+}
+public CompletionOnQualifiedTypeReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions, int kind) {
+	super(previousIdentifiers, positions);
+	this.completionIdentifier = completionIdentifier;
+	this.kind = kind;
+}
+public void aboutToResolve(Scope scope) {
+	getTypeBinding(scope);
+}
+/*
+ * No expansion of the completion reference into an array one
+ */
+public TypeReference copyDims(int dim){
+	return this;
+}
+/*
+ * No expansion of the completion reference into an array one
+ */
+public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions){
+	return this;
+}
+protected TypeBinding getTypeBinding(Scope scope) {
+	// it can be a package, type or member type
+	Binding binding = scope.parent.getTypeOrPackage(this.tokens); // step up from the ClassScope
+	if (!binding.isValidBinding()) {
+		scope.problemReporter().invalidType(this, (TypeBinding) binding);
+
+		if (binding.problemId() == ProblemReasons.NotFound) {
+			throw new CompletionNodeFound(this, binding, scope);
+		}
+
+		throw new CompletionNodeFound();
+	}
+
+	throw new CompletionNodeFound(this, binding, scope);
+}
+public boolean isClass(){
+	return this.kind == K_CLASS;
+}
+
+public boolean isInterface(){
+	return this.kind == K_INTERFACE;
+}
+
+public boolean isException(){
+	return this.kind == K_EXCEPTION;
+}
+
+public boolean isSuperType(){
+	return this.kind == K_CLASS || this.kind == K_INTERFACE;
+}
+public void setKind(int kind) {
+	this.kind = kind;
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	switch (this.kind) {
+		case K_CLASS :
+			output.append("<CompleteOnClass:");//$NON-NLS-1$
+			break;
+		case K_INTERFACE :
+			output.append("<CompleteOnInterface:");//$NON-NLS-1$
+			break;
+		case K_EXCEPTION :
+			output.append("<CompleteOnException:");//$NON-NLS-1$
+			break;
+		default :
+			output.append("<CompleteOnType:");//$NON-NLS-1$
+			break;
+	}
+	for (int i = 0; i < this.tokens.length; i++) {
+		output.append(this.tokens[i]);
+		output.append('.');
+	}
+	output.append(this.completionIdentifier).append('>');
+	return output;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java
new file mode 100644
index 0000000..6ea8e35
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a single name reference containing the completion identifier.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      ba[cursor]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <CompleteOnName:ba>
+ *         }
+ *       }
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnSingleNameReference extends SingleNameReference {
+
+	public char[][] possibleKeywords;
+	public boolean canBeExplicitConstructor;
+	public boolean isInsideAnnotationAttribute;
+	public boolean isPrecededByModifiers;
+
+	public CompletionOnSingleNameReference(char[] source, long pos, boolean isInsideAnnotationAttribute) {
+		this(source, pos, null, false, isInsideAnnotationAttribute);
+	}
+
+	public CompletionOnSingleNameReference(char[] source, long pos, char[][] possibleKeywords, boolean canBeExplicitConstructor, boolean isInsideAnnotationAttribute) {
+		super(source, pos);
+		this.possibleKeywords = possibleKeywords;
+		this.canBeExplicitConstructor = canBeExplicitConstructor;
+		this.isInsideAnnotationAttribute = isInsideAnnotationAttribute;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<CompleteOnName:"); //$NON-NLS-1$
+		return super.printExpression(0, output).append('>');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		if(scope instanceof MethodScope) {
+			throw new CompletionNodeFound(this, scope, ((MethodScope)scope).insideTypeAnnotation);
+		}
+		throw new CompletionNodeFound(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
new file mode 100644
index 0000000..c85bb08
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a type reference containing the completion identifier as a single
+ * name reference.
+ * e.g.
+ *
+ *	class X extends Obj[cursor]
+ *
+ *	---> class X extends <CompleteOnType:Obj>
+ *
+ * The source range of the completion node denotes the source range
+ * which should be replaced by the completion.
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompletionOnSingleTypeReference extends SingleTypeReference {
+public static final int K_TYPE = 0;
+public static final int K_CLASS = 1;
+public static final int K_INTERFACE = 2;
+public static final int K_EXCEPTION = 3;
+
+private int kind = K_TYPE;
+public boolean isCompletionNode;
+public boolean isConstructorType;
+public CompletionOnFieldType fieldTypeCompletionNode;
+
+public CompletionOnSingleTypeReference(char[] source, long pos) {
+	this(source, pos, K_TYPE);
+}
+public CompletionOnSingleTypeReference(char[] source, long pos, int kind) {
+	super(source, pos);
+	this.isCompletionNode = true;
+	this.kind = kind;
+}
+public void aboutToResolve(Scope scope) {
+	getTypeBinding(scope);
+}
+/*
+ * No expansion of the completion reference into an array one
+ */
+public TypeReference copyDims(int dim){
+	return this;
+}
+/*
+ * No expansion of the completion reference into an array one
+ */
+public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions){
+	return this;
+}
+protected TypeBinding getTypeBinding(Scope scope) {
+    if (this.fieldTypeCompletionNode != null) {
+		throw new CompletionNodeFound(this.fieldTypeCompletionNode, scope);
+    }
+	if(this.isCompletionNode) {
+		throw new CompletionNodeFound(this, scope);
+	} else {
+		return super.getTypeBinding(scope);
+	}
+}
+public boolean isClass(){
+	return this.kind == K_CLASS;
+}
+public boolean isInterface(){
+	return this.kind == K_INTERFACE;
+}
+public boolean isException(){
+	return this.kind == K_EXCEPTION;
+}
+public boolean isSuperType(){
+	return this.kind == K_CLASS || this.kind == K_INTERFACE;
+}
+public StringBuffer printExpression(int indent, StringBuffer output){
+	switch (this.kind) {
+		case K_CLASS :
+			output.append("<CompleteOnClass:");//$NON-NLS-1$
+			break;
+		case K_INTERFACE :
+			output.append("<CompleteOnInterface:");//$NON-NLS-1$
+			break;
+		case K_EXCEPTION :
+			output.append("<CompleteOnException:");//$NON-NLS-1$
+			break;
+		default :
+			output.append("<CompleteOnType:");//$NON-NLS-1$
+			break;
+	}
+	return output.append(this.token).append('>');
+}
+public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
+    if (this.fieldTypeCompletionNode != null) {
+		throw new CompletionNodeFound(this.fieldTypeCompletionNode, scope);
+    }
+	if(this.isCompletionNode) {
+		throw new CompletionNodeFound(this, enclosingType, scope);
+	} else {
+		return super.resolveTypeEnclosing(scope, enclosingType);
+	}
+}
+public void setKind(int kind) {
+	this.kind = kind;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnStringLiteral.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnStringLiteral.java
new file mode 100644
index 0000000..4f98b25
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnStringLiteral.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce a string literal.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      String s = "a[cursor]"
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           String s = <CompleteOnStringLiteral:a>
+ *         }
+ *       }
+ */
+
+public class CompletionOnStringLiteral extends StringLiteral {
+	public int contentStart;
+	public int contentEnd;
+	public CompletionOnStringLiteral(char[] token, int s, int e, int cs, int ce, int lineNumber) {
+		super(token, s, e, lineNumber);
+		this.contentStart = cs;
+		this.contentEnd = ce;
+	}
+
+	public CompletionOnStringLiteral(int s, int e, int cs, int ce) {
+		super(s,e);
+		this.contentStart = cs;
+		this.contentEnd = ce;
+	}
+	public TypeBinding resolveType(ClassScope scope) {
+		throw new CompletionNodeFound(this, null, scope);
+	}
+	public TypeBinding resolveType(BlockScope scope) {
+		throw new CompletionNodeFound(this, null, scope);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<CompletionOnString:"); //$NON-NLS-1$
+		output = super.printExpression(indent, output);
+		return output.append('>');
+	}
+}
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
new file mode 100644
index 0000000..a82936b
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -0,0 +1,5164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *		IBM Corporation - initial API and implementation
+ *		Stephan Herrmann - Contribution for
+ *								bug 401035 - [1.8] A few tests have started failing recently
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Parser able to build specific completion parse nodes, given a cursorLocation.
+ *
+ * Cursor location denotes the position of the last character behind which completion
+ * got requested:
+ *  -1 means completion at the very beginning of the source
+ *	0  means completion behind the first character
+ *  n  means completion behind the n-th character
+ */
+
+import java.util.HashSet;
+
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.impl.*;
+
+public class CompletionParser extends AssistParser {
+	// OWNER
+	protected static final int COMPLETION_PARSER = 1024;
+	protected static final int COMPLETION_OR_ASSIST_PARSER = ASSIST_PARSER + COMPLETION_PARSER;
+
+	// KIND : all values known by CompletionParser are between 1025 and 1549
+	protected static final int K_BLOCK_DELIMITER = COMPLETION_PARSER + 1; // whether we are inside a block
+	protected static final int K_SELECTOR_INVOCATION_TYPE = COMPLETION_PARSER + 2; // whether we are inside a message send
+	protected static final int K_SELECTOR_QUALIFIER = COMPLETION_PARSER + 3; // whether we are inside a message send
+	protected static final int K_BETWEEN_CATCH_AND_RIGHT_PAREN = COMPLETION_PARSER + 4; // whether we are between the keyword 'catch' and the following ')'
+	protected static final int K_NEXT_TYPEREF_IS_CLASS = COMPLETION_PARSER + 5; // whether the next type reference is a class
+	protected static final int K_NEXT_TYPEREF_IS_INTERFACE = COMPLETION_PARSER + 6; // whether the next type reference is an interface
+	protected static final int K_NEXT_TYPEREF_IS_EXCEPTION = COMPLETION_PARSER + 7; // whether the next type reference is an exception
+	protected static final int K_BETWEEN_NEW_AND_LEFT_BRACKET = COMPLETION_PARSER + 8; // whether we are between the keyword 'new' and the following left braket, i.e. '[', '(' or '{'
+	protected static final int K_INSIDE_THROW_STATEMENT = COMPLETION_PARSER + 9; // whether we are between the keyword 'throw' and the end of a throw statement
+	protected static final int K_INSIDE_RETURN_STATEMENT = COMPLETION_PARSER + 10; // whether we are between the keyword 'return' and the end of a return statement
+	protected static final int K_CAST_STATEMENT = COMPLETION_PARSER + 11; // whether we are between ')' and the end of a cast statement
+	protected static final int K_LOCAL_INITIALIZER_DELIMITER = COMPLETION_PARSER + 12;
+	protected static final int K_ARRAY_INITIALIZER = COMPLETION_PARSER + 13;
+	protected static final int K_ARRAY_CREATION = COMPLETION_PARSER + 14;
+	protected static final int K_UNARY_OPERATOR = COMPLETION_PARSER + 15;
+	protected static final int K_BINARY_OPERATOR = COMPLETION_PARSER + 16;
+	protected static final int K_ASSISGNMENT_OPERATOR = COMPLETION_PARSER + 17;
+	protected static final int K_CONDITIONAL_OPERATOR = COMPLETION_PARSER + 18;
+	protected static final int K_BETWEEN_IF_AND_RIGHT_PAREN = COMPLETION_PARSER + 19;
+	protected static final int K_BETWEEN_WHILE_AND_RIGHT_PAREN = COMPLETION_PARSER + 20;
+	protected static final int K_BETWEEN_FOR_AND_RIGHT_PAREN = COMPLETION_PARSER + 21;
+	protected static final int K_BETWEEN_SWITCH_AND_RIGHT_PAREN = COMPLETION_PARSER + 22;
+	protected static final int K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN = COMPLETION_PARSER + 23;
+	protected static final int K_INSIDE_ASSERT_STATEMENT = COMPLETION_PARSER + 24;
+	protected static final int K_SWITCH_LABEL= COMPLETION_PARSER + 25;
+	protected static final int K_BETWEEN_CASE_AND_COLON = COMPLETION_PARSER + 26;
+	protected static final int K_BETWEEN_DEFAULT_AND_COLON = COMPLETION_PARSER + 27;
+	protected static final int K_BETWEEN_LEFT_AND_RIGHT_BRACKET = COMPLETION_PARSER + 28;
+	protected static final int K_EXTENDS_KEYWORD = COMPLETION_PARSER + 29;
+	protected static final int K_PARAMETERIZED_METHOD_INVOCATION = COMPLETION_PARSER + 30;
+	protected static final int K_PARAMETERIZED_ALLOCATION = COMPLETION_PARSER + 31;
+	protected static final int K_PARAMETERIZED_CAST = COMPLETION_PARSER + 32;
+	protected static final int K_BETWEEN_ANNOTATION_NAME_AND_RPAREN = COMPLETION_PARSER + 33;
+	protected static final int K_INSIDE_BREAK_STATEMENT = COMPLETION_PARSER + 34;
+	protected static final int K_INSIDE_CONTINUE_STATEMENT = COMPLETION_PARSER + 35;
+	protected static final int K_LABEL = COMPLETION_PARSER + 36;
+	protected static final int K_MEMBER_VALUE_ARRAY_INITIALIZER = COMPLETION_PARSER + 37;
+	protected static final int K_CONTROL_STATEMENT_DELIMITER = COMPLETION_PARSER + 38;
+	protected static final int K_INSIDE_ASSERT_EXCEPTION = COMPLETION_PARSER + 39;
+	protected static final int K_INSIDE_FOR_CONDITIONAL = COMPLETION_PARSER + 40;
+	// added for https://bugs.eclipse.org/bugs/show_bug.cgi?id=261534
+	protected static final int K_BETWEEN_INSTANCEOF_AND_RPAREN = COMPLETION_PARSER + 41;
+	protected static final int K_INSIDE_IMPORT_STATEMENT = COMPLETION_PARSER + 43;
+
+
+	public final static char[] FAKE_TYPE_NAME = new char[]{' '};
+	public final static char[] FAKE_METHOD_NAME = new char[]{' '};
+	public final static char[] FAKE_ARGUMENT_NAME = new char[]{' '};
+	public final static char[] VALUE = new char[]{'v', 'a', 'l', 'u', 'e'};
+
+	/* public fields */
+
+	public int cursorLocation;
+	public ASTNode assistNodeParent; // the parent node of assist node
+	public ASTNode enclosingNode; // an enclosing node used by proposals inference
+
+	/* the following fields are internal flags */
+
+	// block kind
+	static final int IF = 1;
+	static final int TRY = 2;
+	static final int CATCH = 3;
+	static final int WHILE = 4;
+	static final int SWITCH = 5;
+	static final int FOR = 6;
+	static final int DO = 7;
+	static final int SYNCHRONIZED = 8;
+
+	// label kind
+	static final int DEFAULT = 1;
+
+	// invocation type constants
+	static final int EXPLICIT_RECEIVER = 0;
+	static final int NO_RECEIVER = -1;
+	static final int SUPER_RECEIVER = -2;
+	static final int NAME_RECEIVER = -3;
+	static final int ALLOCATION = -4;
+	static final int QUALIFIED_ALLOCATION = -5;
+
+	static final int QUESTION = 1;
+	static final int COLON = 2;
+
+	// K_BETWEEN_ANNOTATION_NAME_AND_RPAREN arguments
+	static final int LPAREN_NOT_CONSUMED = 1;
+	static final int LPAREN_CONSUMED = 2;
+	static final int ANNOTATION_NAME_COMPLETION = 4;
+
+	// K_PARAMETERIZED_METHOD_INVOCATION arguments
+	static final int INSIDE_NAME = 1;
+
+	// the type of the current invocation (one of the invocation type constants)
+	int invocationType;
+
+	// a pointer in the expression stack to the qualifier of a invocation
+	int qualifier;
+
+	// used to find if there is unused modifiers when building completion inside a method or an initializer
+	boolean hasUnusedModifiers;
+
+	// show if the current token can be an explicit constructor
+	int canBeExplicitConstructor = NO;
+	static final int NO = 0;
+	static final int NEXTTOKEN = 1;
+	static final int YES = 2;
+
+	protected static final int LabelStackIncrement = 10;
+	char[][] labelStack = new char[LabelStackIncrement][];
+	int labelPtr = -1;
+
+	boolean isAlreadyAttached;
+
+	public boolean record = false;
+	public boolean skipRecord = false;
+	public int recordFrom;
+	public int recordTo;
+	public int potentialVariableNamesPtr;
+	public char[][] potentialVariableNames;
+	public int[] potentialVariableNameStarts;
+	public int[] potentialVariableNameEnds;
+
+	CompletionOnAnnotationOfType pendingAnnotation;
+
+	private boolean storeSourceEnds;
+	public HashtableOfObjectToInt sourceEnds;
+	private boolean inReferenceExpression;
+
+public CompletionParser(ProblemReporter problemReporter, boolean storeExtraSourceEnds) {
+	super(problemReporter);
+	this.reportSyntaxErrorIsRequired = false;
+	this.javadocParser.checkDocComment = true;
+	this.annotationRecoveryActivated = false;
+	if (storeExtraSourceEnds) {
+		this.storeSourceEnds = true;
+		this.sourceEnds = new HashtableOfObjectToInt();
+	}
+}
+private void addPotentialName(char[] potentialVariableName, int start, int end) {
+	int length = this.potentialVariableNames.length;
+	if (this.potentialVariableNamesPtr >= length - 1) {
+		System.arraycopy(
+				this.potentialVariableNames,
+				0,
+				this.potentialVariableNames = new char[length * 2][],
+				0,
+				length);
+		System.arraycopy(
+				this.potentialVariableNameStarts,
+				0,
+				this.potentialVariableNameStarts = new int[length * 2],
+				0,
+				length);
+		System.arraycopy(
+				this.potentialVariableNameEnds,
+				0,
+				this.potentialVariableNameEnds = new int[length * 2],
+				0,
+				length);
+	}
+	this.potentialVariableNames[++this.potentialVariableNamesPtr] = potentialVariableName;
+	this.potentialVariableNameStarts[this.potentialVariableNamesPtr] = start;
+	this.potentialVariableNameEnds[this.potentialVariableNamesPtr] = end;
+}
+public void startRecordingIdentifiers(int from, int to) {
+	this.record = true;
+	this.skipRecord = false;
+	this.recordFrom = from;
+	this.recordTo = to;
+
+	this.potentialVariableNamesPtr = -1;
+	this.potentialVariableNames = new char[10][];
+	this.potentialVariableNameStarts = new int[10];
+	this.potentialVariableNameEnds = new int[10];
+}
+public void stopRecordingIdentifiers() {
+	this.record = true;
+	this.skipRecord = false;
+}
+public char[] assistIdentifier(){
+	return ((CompletionScanner)this.scanner).completionIdentifier;
+}
+protected void attachOrphanCompletionNode(){
+	if(this.assistNode == null || this.isAlreadyAttached) return;
+
+	this.isAlreadyAttached = true;
+
+	if (this.isOrphanCompletionNode) {
+		ASTNode orphan = this.assistNode;
+		this.isOrphanCompletionNode = false;
+
+		if (this.currentElement instanceof RecoveredUnit){
+			if (orphan instanceof ImportReference){
+				this.currentElement.add((ImportReference)orphan, 0);
+			}
+		}
+
+		/* if in context of a type, then persists the identifier into a fake field return type */
+		if (this.currentElement instanceof RecoveredType){
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			/* filter out cases where scanner is still inside type header */
+			if (recoveredType.foundOpeningBrace) {
+				/* generate a pseudo field with a completion on type reference */
+				if (orphan instanceof TypeReference){
+					TypeReference fieldType;
+
+					int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+					int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+					if(kind == K_BINARY_OPERATOR && info == LESS && this.identifierPtr > -1) {
+						if(this.genericsLengthStack[this.genericsLengthPtr] > 0) {
+							consumeTypeArguments();
+						}
+						pushOnGenericsStack(orphan);
+						consumeTypeArguments();
+						fieldType = getTypeReference(0);
+						this.assistNodeParent = fieldType;
+					} else {
+						fieldType = (TypeReference)orphan;
+					}
+
+					CompletionOnFieldType fieldDeclaration = new CompletionOnFieldType(fieldType, false);
+
+					// retrieve annotations if any
+					int length;
+					if ((length = this.expressionLengthStack[this.expressionLengthPtr]) != 0 &&
+							this.expressionStack[this.expressionPtr] instanceof Annotation) {
+						System.arraycopy(
+							this.expressionStack,
+							this.expressionPtr - length + 1,
+							fieldDeclaration.annotations = new Annotation[length],
+							0,
+							length);
+					}
+
+					// retrieve available modifiers if any
+					if (this.intPtr >= 2 && this.intStack[this.intPtr-1] == this.lastModifiersStart && this.intStack[this.intPtr-2] == this.lastModifiers){
+						fieldDeclaration.modifiersSourceStart = this.intStack[this.intPtr-1];
+						fieldDeclaration.modifiers = this.intStack[this.intPtr-2];
+					}
+
+					this.currentElement = this.currentElement.add(fieldDeclaration, 0);
+					return;
+				}
+			}
+		}
+		/* if in context of a method, persists if inside arguments as a type */
+		if (this.currentElement instanceof RecoveredMethod){
+			RecoveredMethod recoveredMethod = (RecoveredMethod)this.currentElement;
+			/* only consider if inside method header */
+			if (!recoveredMethod.foundOpeningBrace) {
+				//if (rParenPos < lParenPos){ // inside arguments
+				if (orphan instanceof TypeReference){
+					this.currentElement = this.currentElement.parent.add(
+						new CompletionOnFieldType((TypeReference)orphan, true), 0);
+					return;
+				}
+
+				if(orphan instanceof Annotation) {
+					CompletionOnAnnotationOfType fakeType =
+						new CompletionOnAnnotationOfType(
+								FAKE_TYPE_NAME,
+								this.compilationUnit.compilationResult(),
+								(Annotation)orphan);
+					fakeType.isParameter = true;
+					this.currentElement.parent.add(fakeType, 0);
+					this.pendingAnnotation = fakeType;
+					return;
+				}
+			}
+		}
+
+		if(orphan instanceof MemberValuePair) {
+			buildMoreAnnotationCompletionContext((MemberValuePair) orphan);
+			return;
+		}
+
+		if(orphan instanceof Annotation) {
+			popUntilCompletedAnnotationIfNecessary();
+
+			CompletionOnAnnotationOfType fakeType =
+				new CompletionOnAnnotationOfType(
+						FAKE_TYPE_NAME,
+						this.compilationUnit.compilationResult(),
+						(Annotation)orphan);
+			this.currentElement.add(fakeType, 0);
+
+			if (!isInsideAnnotation()) {
+				this.pendingAnnotation = fakeType;
+			}
+
+			return;
+		}
+
+		if ((topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)) {
+			if (this.assistNode instanceof CompletionOnSingleTypeReference &&
+					((CompletionOnSingleTypeReference)this.assistNode).isException()) {
+				buildMoreTryStatementCompletionContext((TypeReference)this.assistNode);
+				return;
+			} else if (this.assistNode instanceof CompletionOnQualifiedTypeReference &&
+					((CompletionOnQualifiedTypeReference)this.assistNode).isException()) {
+				buildMoreTryStatementCompletionContext((TypeReference)this.assistNode);
+				return;
+			} else if (this.assistNode instanceof CompletionOnParameterizedQualifiedTypeReference &&
+					((CompletionOnParameterizedQualifiedTypeReference)this.assistNode).isException()) {
+				buildMoreTryStatementCompletionContext((TypeReference)this.assistNode);
+				return;
+			}
+		}
+
+		// add the completion node to the method declaration or constructor declaration
+		if (orphan instanceof Statement) {
+			/* check for completion at the beginning of method body
+				behind an invalid signature
+			 */
+			RecoveredMethod method = this.currentElement.enclosingMethod();
+			if (method != null){
+				AbstractMethodDeclaration methodDecl = method.methodDeclaration;
+				if ((methodDecl.bodyStart == methodDecl.sourceEnd+1) // was missing opening brace
+					&& (Util.getLineNumber(orphan.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+							== Util.getLineNumber(methodDecl.sourceEnd, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+					return;
+				}
+			}
+			// add the completion node as a statement to the list of block statements
+			this.currentElement = this.currentElement.add((Statement)orphan, 0);
+			return;
+		}
+	}
+
+	if (isInsideAnnotation()) {
+		// push top expression on ast stack if it contains the completion node
+		Expression expression;
+		if (this.expressionPtr > -1) {
+			expression = this.expressionStack[this.expressionPtr];
+			if(expression == this.assistNode) {
+				if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_MEMBER_VALUE_ARRAY_INITIALIZER ) {
+					ArrayInitializer arrayInitializer = new ArrayInitializer();
+					arrayInitializer.expressions = new Expression[]{expression};
+
+					MemberValuePair valuePair =
+							new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, arrayInitializer);
+						buildMoreAnnotationCompletionContext(valuePair);
+				} else if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+					if (expression instanceof SingleNameReference) {
+						SingleNameReference nameReference = (SingleNameReference) expression;
+						CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(nameReference.token, nameReference.sourceStart, nameReference.sourceEnd);
+
+						buildMoreAnnotationCompletionContext(memberValueName);
+						return;
+					} else if (expression instanceof QualifiedNameReference || expression instanceof StringLiteral) {
+						MemberValuePair valuePair =
+							new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+						buildMoreAnnotationCompletionContext(valuePair);
+					}
+				} else {
+					int index;
+					if((index = lastIndexOfElement(K_ATTRIBUTE_VALUE_DELIMITER)) != -1) {
+						int attributeIndentifierPtr = this.elementInfoStack[index];
+						int identLengthPtr = this.identifierLengthPtr;
+						int identPtr = this.identifierPtr;
+						while (attributeIndentifierPtr < identPtr) {
+							identPtr -= this.identifierLengthStack[identLengthPtr--];
+						}
+
+						if(attributeIndentifierPtr != identPtr) return;
+
+						this.identifierLengthPtr = identLengthPtr;
+						this.identifierPtr = identPtr;
+
+						this.identifierLengthPtr--;
+						MemberValuePair memberValuePair = new MemberValuePair(
+								this.identifierStack[this.identifierPtr--],
+								expression.sourceStart,
+								expression.sourceEnd,
+								expression);
+
+						buildMoreAnnotationCompletionContext(memberValuePair);
+						return;
+					}
+				}
+			} else {
+				CompletionNodeDetector detector =  new CompletionNodeDetector(this.assistNode, expression);
+				if(detector.containsCompletionNode()) {
+					MemberValuePair valuePair =
+						new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+					buildMoreAnnotationCompletionContext(valuePair);
+				}
+			}
+		}
+
+		if (this.astPtr > -1) {
+			ASTNode node = this.astStack[this.astPtr];
+			if(node instanceof MemberValuePair) {
+				MemberValuePair memberValuePair = (MemberValuePair) node;
+				CompletionNodeDetector detector =  new CompletionNodeDetector(this.assistNode, memberValuePair);
+				if(detector.containsCompletionNode()) {
+					buildMoreAnnotationCompletionContext(memberValuePair);
+					this.assistNodeParent = detector.getCompletionNodeParent();
+					return;
+				}
+			}
+		}
+	}
+
+	if(this.genericsPtr > -1) {
+		ASTNode node = this.genericsStack[this.genericsPtr];
+		if(node instanceof Wildcard && ((Wildcard)node).bound == this.assistNode){
+			int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+			if (kind == K_BINARY_OPERATOR) {
+				int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+				if (info == LESS) {
+					buildMoreGenericsCompletionContext(node, true);
+					return;
+				}
+			}
+			if(this.identifierLengthPtr > -1 && this.identifierLengthStack[this.identifierLengthPtr]!= 0) {
+				this.pushOnElementStack(K_BINARY_OPERATOR, LESS);
+				buildMoreGenericsCompletionContext(node, false);
+				return;
+			}
+		}
+	}
+
+	if(this.currentElement instanceof RecoveredType || this.currentElement instanceof RecoveredMethod) {
+		if(this.currentElement instanceof RecoveredType) {
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			if(recoveredType.foundOpeningBrace && this.genericsPtr > -1) {
+				if(this.genericsStack[this.genericsPtr] instanceof TypeParameter) {
+					TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+					CompletionNodeDetector detector =  new CompletionNodeDetector(this.assistNode, typeParameter);
+					if(detector.containsCompletionNode()) {
+						this.currentElement.add(new CompletionOnMethodTypeParameter(new TypeParameter[]{typeParameter},this.compilationUnit.compilationResult()), 0);
+					}
+					return;
+				}
+			}
+		}
+
+		if ((!isInsideMethod() && !isInsideFieldInitialization())) {
+			if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsIdentifiersLengthPtr > -1) {
+				int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+				int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+				if(kind == K_BINARY_OPERATOR && info == LESS) {
+					consumeTypeArguments();
+				}
+				int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr];
+				int genPtr = this.genericsPtr;
+				done : for(int i = 0; i <= this.identifierLengthPtr && numberOfIdentifiers > 0; i++){
+					int identifierLength = this.identifierLengthStack[this.identifierLengthPtr - i];
+					int length = this.genericsLengthStack[this.genericsLengthPtr - i];
+					for(int j = 0; j < length; j++) {
+						ASTNode node = this.genericsStack[genPtr - j];
+						CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, node);
+						if(detector.containsCompletionNode()) {
+							if(node == this.assistNode){
+								if(this.identifierLengthPtr > -1 &&	this.identifierLengthStack[this.identifierLengthPtr]!= 0) {
+									TypeReference ref = this.getTypeReference(0);
+									this.assistNodeParent = ref;
+								}
+							} else {
+								this.assistNodeParent = detector.getCompletionNodeParent();
+							}
+							break done;
+						}
+					}
+					genPtr -= length;
+					numberOfIdentifiers -= identifierLength;
+				}
+				if(this.assistNodeParent != null && this.assistNodeParent instanceof TypeReference) {
+					if(this.currentElement instanceof RecoveredType) {
+						this.currentElement = this.currentElement.add(new CompletionOnFieldType((TypeReference)this.assistNodeParent, false), 0);
+					} else {
+						this.currentElement = this.currentElement.add((TypeReference)this.assistNodeParent, 0);
+					}
+				}
+			}
+		}
+	}
+
+	// the following code applies only in methods, constructors or initializers
+	if ((!isInsideMethod() && !isInsideFieldInitialization() && !isInsideAttributeValue())) {
+		return;
+	}
+
+	if(this.genericsPtr > -1) {
+		ASTNode node = this.genericsStack[this.genericsPtr];
+		CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, node);
+		if(detector.containsCompletionNode()) {
+			/* check for completion at the beginning of method body
+				behind an invalid signature
+			 */
+			RecoveredMethod method = this.currentElement.enclosingMethod();
+			if (method != null){
+				AbstractMethodDeclaration methodDecl = method.methodDeclaration;
+				if ((methodDecl.bodyStart == methodDecl.sourceEnd+1) // was missing opening brace
+					&& (Util.getLineNumber(node.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						== Util.getLineNumber(methodDecl.sourceEnd, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+					return;
+				}
+			}
+			if(node == this.assistNode){
+				buildMoreGenericsCompletionContext(node, true);
+			}
+		}
+	}
+
+	// push top expression on ast stack if it contains the completion node
+	Expression expression;
+	if (this.expressionPtr > -1) {
+		expression = this.expressionStack[this.expressionPtr];
+		CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, expression);
+		if(detector.containsCompletionNode()) {
+			/* check for completion at the beginning of method body
+				behind an invalid signature
+			 */
+			RecoveredMethod method = this.currentElement.enclosingMethod();
+			if (method != null){
+				AbstractMethodDeclaration methodDecl = method.methodDeclaration;
+				if ((methodDecl.bodyStart == methodDecl.sourceEnd+1) // was missing opening brace
+					&& (Util.getLineNumber(expression.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						== Util.getLineNumber(methodDecl.sourceEnd, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+					return;
+				}
+			}
+			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 && 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
+						&& (this.elementPtr >= 0 && this.elementObjectInfoStack[this.elementPtr] instanceof InstanceOfExpression))){
+				buildMoreCompletionContext(expression);
+				if (this.assistNodeParent == null
+					&& expression instanceof Assignment) {
+					this.assistNodeParent = detector.getCompletionNodeParent();
+				}
+				return;
+			} else {
+				this.assistNodeParent = detector.getCompletionNodeParent();
+				if(this.assistNodeParent != null) {
+					this.currentElement = this.currentElement.add((Statement)this.assistNodeParent, 0);
+				} else {
+					this.currentElement = this.currentElement.add(expression, 0);
+				}
+				return;
+			}
+		}
+	}
+	if (this.astPtr > -1 && this.astStack[this.astPtr] instanceof LocalDeclaration) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287939
+		// To take care of:  if (a instance of X)  int i = a.|
+		LocalDeclaration local = (LocalDeclaration) this.astStack[this.astPtr];
+		if (local.initialization == this.assistNode) {
+			Statement enclosing = buildMoreCompletionEnclosingContext(local);
+			if (enclosing instanceof IfStatement) {
+				if (this.currentElement instanceof RecoveredBlock) {
+					// RecoveredLocalVariable must be removed from its parent because the IfStatement will be added instead
+					RecoveredBlock recoveredBlock = (RecoveredBlock) this.currentElement;
+					recoveredBlock.statements[--recoveredBlock.statementCount] = null;
+					this.currentElement = this.currentElement.add(enclosing, 0);
+				}
+			}
+		}
+	}
+}
+public Object becomeSimpleParser() {
+	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+	int[] parserState = new int[] {this.cursorLocation, completionScanner.cursorLocation};
+	
+	this.cursorLocation = Integer.MAX_VALUE;
+	completionScanner.cursorLocation = Integer.MAX_VALUE;
+	
+	return parserState;
+}
+private void buildMoreAnnotationCompletionContext(MemberValuePair memberValuePair) {
+	if(this.identifierPtr < 0 || this.identifierLengthPtr < 0 ) return;
+
+	TypeReference typeReference = getAnnotationType();
+
+	int nodesToRemove = this.astPtr > -1 && this.astStack[this.astPtr] == memberValuePair ? 1 : 0;
+
+	NormalAnnotation annotation;
+	if (memberValuePair instanceof CompletionOnMemberValueName) {
+		MemberValuePair[] memberValuePairs = null;
+		int length;
+		if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+			if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+				System.arraycopy(
+					this.astStack,
+					(this.astPtr -= length) + 1,
+					memberValuePairs = new MemberValuePair[length - nodesToRemove],
+					0,
+					length - nodesToRemove);
+			}
+		}
+		annotation =
+			new CompletionOnAnnotationMemberValuePair(
+					typeReference,
+					this.intStack[this.intPtr--],
+					memberValuePairs,
+					memberValuePair);
+
+		this.assistNode = memberValuePair;
+		this.assistNodeParent = annotation;
+
+		if (memberValuePair.sourceEnd >= this.lastCheckPoint) {
+			this.lastCheckPoint = memberValuePair.sourceEnd + 1;
+		}
+	} else {
+		MemberValuePair[] memberValuePairs = null;
+		int length = 0;
+		if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+			if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+				System.arraycopy(
+					this.astStack,
+					(this.astPtr -= length) + 1,
+					memberValuePairs = new MemberValuePair[length - nodesToRemove + 1],
+					0,
+					length - nodesToRemove);
+			}
+			if(memberValuePairs != null) {
+				memberValuePairs[length - nodesToRemove] = memberValuePair;
+			} else {
+				memberValuePairs = new MemberValuePair[]{memberValuePair};
+			}
+		} else {
+			memberValuePairs = new MemberValuePair[]{memberValuePair};
+		}
+
+		annotation =
+			new NormalAnnotation(
+					typeReference,
+					this.intStack[this.intPtr--]);
+		annotation.memberValuePairs = memberValuePairs;
+
+	}
+	CompletionOnAnnotationOfType fakeType =
+		new CompletionOnAnnotationOfType(
+				FAKE_TYPE_NAME,
+				this.compilationUnit.compilationResult(),
+				annotation);
+
+	this.currentElement.add(fakeType, 0);
+	this.pendingAnnotation = fakeType;
+}
+private void buildMoreCompletionContext(Expression expression) {
+	Statement statement = expression;
+	int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+	if(kind != 0) {
+		int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+		nextElement : switch (kind) {
+			case K_SELECTOR_QUALIFIER :
+				int selector = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 2);
+				if(selector == THIS_CONSTRUCTOR || selector == SUPER_CONSTRUCTOR) {
+					ExplicitConstructorCall call = new ExplicitConstructorCall(
+						(selector == THIS_CONSTRUCTOR) ?
+							ExplicitConstructorCall.This :
+							ExplicitConstructorCall.Super
+					);
+					call.arguments = new Expression[] {expression};
+					call.sourceStart = expression.sourceStart;
+					call.sourceEnd = expression.sourceEnd;
+					this.assistNodeParent = call;
+				} else {
+					int invocType = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER,1);
+					int qualifierExprPtr = info;
+
+					// find arguments
+					int length = this.expressionLengthStack[this.expressionLengthPtr];
+
+					// search previous arguments if missing
+					if(this.expressionPtr > 0 && this.expressionLengthPtr > 0 && length == 1) {
+						int start = (int) (this.identifierPositionStack[selector] >>> 32);
+						if(this.expressionStack[this.expressionPtr-1] != null && this.expressionStack[this.expressionPtr-1].sourceStart > start) {
+							length += this.expressionLengthStack[this.expressionLengthPtr-1];
+						}
+
+					}
+
+					Expression[] arguments = null;
+					if (length != 0) {
+						arguments = new Expression[length];
+						this.expressionPtr -= length;
+						System.arraycopy(this.expressionStack, this.expressionPtr + 1, arguments, 0, length-1);
+						arguments[length-1] = expression;
+					}
+
+					if(invocType != ALLOCATION && invocType != QUALIFIED_ALLOCATION) {
+						MessageSend messageSend = new MessageSend();
+						messageSend.selector = this.identifierStack[selector];
+						messageSend.arguments = arguments;
+
+						// find receiver
+						switch (invocType) {
+							case NO_RECEIVER:
+								messageSend.receiver = ThisReference.implicitThis();
+								break;
+							case NAME_RECEIVER:
+								// remove special flags for primitive types
+								while (this.identifierLengthPtr >= 0 && this.identifierLengthStack[this.identifierLengthPtr] < 0) {
+									this.identifierLengthPtr--;
+								}
+
+								// remove selector
+								this.identifierPtr--;
+								if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsLengthStack[this.genericsLengthPtr] > 0) {
+									// is inside a paremeterized method: bar.<X>.foo
+									this.identifierLengthPtr--;
+								} else {
+									this.identifierLengthStack[this.identifierLengthPtr]--;
+									length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--];
+									Annotation [] typeAnnotations;
+									if (length != 0) {
+										System.arraycopy(
+												this.typeAnnotationStack,
+												(this.typeAnnotationPtr -= length) + 1,
+												typeAnnotations = new Annotation[length],
+												0,
+												length);
+										problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]);
+									}
+								}
+								// consume the receiver
+								int identifierLength = this.identifierLengthStack[this.identifierLengthPtr];
+								if(this.identifierPtr > -1 && identifierLength > 0 && this.identifierPtr + 1 >= identifierLength) {
+									messageSend.receiver = getUnspecifiedReference();
+								} else {
+									messageSend = null;
+								}
+								break;
+							case SUPER_RECEIVER:
+								messageSend.receiver = new SuperReference(0, 0);
+								break;
+							case EXPLICIT_RECEIVER:
+								messageSend.receiver = this.expressionStack[qualifierExprPtr];
+								break;
+							default :
+								messageSend.receiver = ThisReference.implicitThis();
+								break;
+						}
+						this.assistNodeParent = messageSend;
+					} else {
+						if(invocType == ALLOCATION) {
+							AllocationExpression allocationExpr = new AllocationExpression();
+							allocationExpr.arguments = arguments;
+							pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+							pushOnGenericsLengthStack(0);
+							allocationExpr.type = getTypeReference(0);
+							this.assistNodeParent = allocationExpr;
+						} else {
+							QualifiedAllocationExpression allocationExpr = new QualifiedAllocationExpression();
+							allocationExpr.enclosingInstance = this.expressionStack[qualifierExprPtr];
+							allocationExpr.arguments = arguments;
+							pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+							pushOnGenericsLengthStack(0);
+
+							allocationExpr.type = getTypeReference(0);
+							this.assistNodeParent = allocationExpr;
+						}
+					}
+				}
+				break nextElement;
+			case K_INSIDE_RETURN_STATEMENT :
+				if(info == this.bracketDepth) {
+					ReturnStatement returnStatement = new ReturnStatement(expression, expression.sourceStart, expression.sourceEnd);
+					this.assistNodeParent = returnStatement;
+				}
+				break nextElement;
+			case K_CAST_STATEMENT :
+				Expression castType;
+				if(this.expressionPtr > 0
+					&& ((castType = this.expressionStack[this.expressionPtr-1]) instanceof TypeReference)) {
+					CastExpression cast = new CastExpression(expression, (TypeReference) castType);
+					cast.sourceStart = castType.sourceStart;
+					cast.sourceEnd= expression.sourceEnd;
+					this.assistNodeParent = cast;
+				}
+				break nextElement;
+			case K_UNARY_OPERATOR :
+				if(this.expressionPtr > -1) {
+					Expression operatorExpression = null;
+					switch (info) {
+						case PLUS_PLUS :
+							operatorExpression = new PrefixExpression(expression,IntLiteral.One, PLUS, expression.sourceStart);
+							break;
+						case MINUS_MINUS :
+							operatorExpression = new PrefixExpression(expression,IntLiteral.One, MINUS, expression.sourceStart);
+							break;
+						default :
+							operatorExpression = new UnaryExpression(expression, info);
+							break;
+					}
+					this.assistNodeParent = operatorExpression;
+				}
+				break nextElement;
+			case K_BINARY_OPERATOR :
+				if(this.expressionPtr > -1) {
+					Expression operatorExpression = null;
+					Expression left = null;
+					if(this.expressionPtr == 0) {
+						// it is  a ***_NotName rule
+						if(this.identifierPtr > -1) {
+							left = getUnspecifiedReferenceOptimized();
+						}
+					} else {
+						left = this.expressionStack[this.expressionPtr-1];
+						// is it a ***_NotName rule ?
+						if(this.identifierPtr > -1) {
+							int start = (int) (this.identifierPositionStack[this.identifierPtr] >>> 32);
+							if(left.sourceStart < start) {
+								left = getUnspecifiedReferenceOptimized();
+							}
+						}
+					}
+
+					if(left != null) {
+						switch (info) {
+							case AND_AND :
+								operatorExpression = new AND_AND_Expression(left, expression, info);
+								break;
+							case OR_OR :
+								operatorExpression = new OR_OR_Expression(left, expression, info);
+								break;
+							case EQUAL_EQUAL :
+							case NOT_EQUAL :
+								operatorExpression = new EqualExpression(left, expression, info);
+								break;
+							default :
+								operatorExpression = new BinaryExpression(left, expression, info);
+								break;
+						}
+					}
+					if(operatorExpression != null) {
+						this.assistNodeParent = operatorExpression;
+					}
+				}
+				break nextElement;
+			case K_ARRAY_INITIALIZER :
+				ArrayInitializer arrayInitializer = new ArrayInitializer();
+				arrayInitializer.expressions = new Expression[]{expression};
+				this.expressionPtr -= this.expressionLengthStack[this.expressionLengthPtr--];
+
+				if(this.expressionLengthPtr > -1
+					&& this.expressionPtr > -1
+					&& this.expressionStack[this.expressionPtr] != null
+					&& this.expressionStack[this.expressionPtr].sourceStart > info) {
+					this.expressionLengthPtr--;
+				}
+
+				if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_ARRAY_CREATION) {
+					ArrayAllocationExpression allocationExpression = new ArrayAllocationExpression();
+					pushOnGenericsLengthStack(0);
+					pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+					allocationExpression.type = getTypeReference(0);
+					allocationExpression.type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
+					int length = this.expressionLengthStack[this.expressionLengthPtr];
+					allocationExpression.dimensions = new Expression[length];
+
+					allocationExpression.initializer = arrayInitializer;
+					this.assistNodeParent = allocationExpression;
+				} else if(this.currentElement instanceof RecoveredField && !(this.currentElement instanceof RecoveredInitializer)) {
+					RecoveredField recoveredField = (RecoveredField) this.currentElement;
+					if(recoveredField.fieldDeclaration.type.dimensions() == 0) {
+						Block block = new Block(0);
+						block.sourceStart = info;
+						this.currentElement = this.currentElement.add(block, 1);
+					} else {
+						statement = arrayInitializer;
+					}
+				} else if(this.currentElement instanceof RecoveredLocalVariable) {
+					RecoveredLocalVariable recoveredLocalVariable = (RecoveredLocalVariable) this.currentElement;
+					if(recoveredLocalVariable.localDeclaration.type.dimensions() == 0) {
+						Block block = new Block(0);
+						block.sourceStart = info;
+						this.currentElement = this.currentElement.add(block, 1);
+					} else {
+						statement = arrayInitializer;
+					}
+				} else {
+					statement = arrayInitializer;
+				}
+				break nextElement;
+			case K_ARRAY_CREATION :
+				ArrayAllocationExpression allocationExpression = new ArrayAllocationExpression();
+				allocationExpression.type = getTypeReference(0);
+				allocationExpression.dimensions = new Expression[]{expression};
+
+				this.assistNodeParent = allocationExpression;
+				break nextElement;
+			case K_ASSISGNMENT_OPERATOR :
+				if(this.expressionPtr > 0 && this.expressionStack[this.expressionPtr - 1] != null) {
+					Assignment assignment;
+					if(info == EQUAL) {
+						assignment = new Assignment(
+							this.expressionStack[this.expressionPtr - 1],
+							expression,
+							expression.sourceEnd
+						);
+					} else {
+						assignment = new CompoundAssignment(
+							this.expressionStack[this.expressionPtr - 1],
+							expression,
+							info,
+							expression.sourceEnd
+						);
+					}
+					this.assistNodeParent = assignment;
+				}
+				break nextElement;
+			case K_CONDITIONAL_OPERATOR :
+				if(info == QUESTION) {
+					if(this.expressionPtr > 0) {
+						this.expressionPtr--;
+						this.expressionLengthPtr--;
+						this.expressionStack[this.expressionPtr] = this.expressionStack[this.expressionPtr+1];
+						popElement(K_CONDITIONAL_OPERATOR);
+						buildMoreCompletionContext(expression);
+						return;
+					}
+				} else {
+					if(this.expressionPtr > 1) {
+						this.expressionPtr = this.expressionPtr - 2;
+						this.expressionLengthPtr = this.expressionLengthPtr - 2;
+						this.expressionStack[this.expressionPtr] = this.expressionStack[this.expressionPtr+2];
+						popElement(K_CONDITIONAL_OPERATOR);
+						buildMoreCompletionContext(expression);
+						return;
+					}
+				}
+				break nextElement;
+			case K_BETWEEN_LEFT_AND_RIGHT_BRACKET :
+				ArrayReference arrayReference;
+				if(this.identifierPtr < 0 && this.expressionPtr > 0 && this.expressionStack[this.expressionPtr] == expression) {
+					arrayReference =
+						new ArrayReference(
+							this.expressionStack[this.expressionPtr-1],
+							expression);
+				} else {
+					arrayReference =
+						new ArrayReference(
+							getUnspecifiedReferenceOptimized(),
+							expression);
+				}
+				this.assistNodeParent = arrayReference;
+				break;
+			case K_BETWEEN_CASE_AND_COLON :
+				if(this.expressionPtr > 0) {
+					SwitchStatement switchStatement = new SwitchStatement();
+					switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
+					if(this.astLengthPtr > -1 && this.astPtr > -1) {
+						int length = this.astLengthStack[this.astLengthPtr];
+						int newAstPtr = this.astPtr - length;
+						ASTNode firstNode = this.astStack[newAstPtr + 1];
+						if(length != 0 && firstNode.sourceStart > switchStatement.expression.sourceEnd) {
+							switchStatement.statements = new Statement[length + 1];
+							System.arraycopy(
+								this.astStack,
+								newAstPtr + 1,
+								switchStatement.statements,
+								0,
+								length);
+						}
+					}
+					CaseStatement caseStatement = new CaseStatement(expression, expression.sourceStart, expression.sourceEnd);
+					if(switchStatement.statements == null) {
+						switchStatement.statements = new Statement[]{caseStatement};
+					} else {
+						switchStatement.statements[switchStatement.statements.length - 1] = caseStatement;
+					}
+					this.assistNodeParent = switchStatement;
+				}
+				break;
+			case K_BETWEEN_IF_AND_RIGHT_PAREN :
+				IfStatement ifStatement = new IfStatement(expression, new EmptyStatement(expression.sourceEnd, expression.sourceEnd), expression.sourceStart, expression.sourceEnd);
+				this.assistNodeParent = ifStatement;
+				break nextElement;
+			case K_BETWEEN_WHILE_AND_RIGHT_PAREN :
+				WhileStatement whileStatement = new WhileStatement(expression, new EmptyStatement(expression.sourceEnd, expression.sourceEnd), expression.sourceStart, expression.sourceEnd);
+				this.assistNodeParent = whileStatement;
+				break nextElement;
+			case K_INSIDE_FOR_CONDITIONAL: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008
+				ForStatement forStatement = new ForStatement(new Statement[0], expression, new Statement[0],
+															 new EmptyStatement(expression.sourceEnd, expression.sourceEnd),
+						                                     false,
+						                                     expression.sourceStart, expression.sourceEnd);
+				this.assistNodeParent = forStatement;
+				break nextElement;
+			case K_BETWEEN_SWITCH_AND_RIGHT_PAREN:
+				SwitchStatement switchStatement = new SwitchStatement();
+				switchStatement.expression = expression;
+				switchStatement.statements = new Statement[0];
+				this.assistNodeParent = switchStatement;
+				break nextElement;
+			case K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN :
+				SynchronizedStatement synchronizedStatement = new SynchronizedStatement(expression, new Block(0), expression.sourceStart, expression.sourceEnd);
+				this.assistNodeParent = synchronizedStatement;
+				break nextElement;
+			case K_INSIDE_THROW_STATEMENT:
+				if(info == this.bracketDepth) {
+					ThrowStatement throwStatement = new ThrowStatement(expression, expression.sourceStart, expression.sourceEnd);
+					this.assistNodeParent = throwStatement;
+				}
+				break nextElement;
+			case K_INSIDE_ASSERT_STATEMENT:
+				if(info == this.bracketDepth) {
+					AssertStatement assertStatement = new AssertStatement(expression, expression.sourceStart);
+					this.assistNodeParent = assertStatement;
+				}
+				break nextElement;
+			case K_INSIDE_ASSERT_EXCEPTION:
+				if(info == this.bracketDepth) {
+					AssertStatement assertStatement = new AssertStatement(expression, new TrueLiteral(expression.sourceStart, expression.sourceStart), expression.sourceStart);
+					this.assistNodeParent = assertStatement;
+				}
+				break nextElement;
+		}
+	}
+	if(this.assistNodeParent != null) {
+		this.currentElement = this.currentElement.add(buildMoreCompletionEnclosingContext((Statement)this.assistNodeParent), 0);
+	} else {
+		if(this.currentElement instanceof RecoveredField && !(this.currentElement instanceof RecoveredInitializer)
+			&& ((RecoveredField) this.currentElement).fieldDeclaration.initialization == null) {
+
+			this.assistNodeParent = ((RecoveredField) this.currentElement).fieldDeclaration;
+			this.currentElement = this.currentElement.add(buildMoreCompletionEnclosingContext(statement), 0);
+		} else if(this.currentElement instanceof RecoveredLocalVariable
+			&& ((RecoveredLocalVariable) this.currentElement).localDeclaration.initialization == null) {
+
+			this.assistNodeParent = ((RecoveredLocalVariable) this.currentElement).localDeclaration;
+			this.currentElement = this.currentElement.add(buildMoreCompletionEnclosingContext(statement), 0);
+		} else {
+			this.currentElement = this.currentElement.add(buildMoreCompletionEnclosingContext(expression), 0);
+		}
+	}
+}
+private Statement buildMoreCompletionEnclosingContext(Statement statement) {
+	IfStatement ifStatement = null;
+	int blockIndex = lastIndexOfElement(K_BLOCK_DELIMITER);
+	int controlIndex = lastIndexOfElement(K_CONTROL_STATEMENT_DELIMITER);
+	int index;
+	if (controlIndex != -1) {
+		index = blockIndex != -1 && controlIndex < blockIndex ? blockIndex : controlIndex;
+	} else {
+		// To handle the case when the completion is requested before enclosing R_PAREN
+		// and an instanceof expression is also present
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=261534
+		int instanceOfIndex = lastIndexOfElement(K_BETWEEN_INSTANCEOF_AND_RPAREN);
+		index = blockIndex != -1 && instanceOfIndex < blockIndex ? blockIndex : instanceOfIndex;
+	}
+	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;
+		}
+		index--;
+	}
+	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);
+	if(kind != 0) {
+		int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+		nextElement : switch (kind) {
+			case K_BINARY_OPERATOR :
+				int prevKind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1);
+				switch (prevKind) {
+					case K_PARAMETERIZED_ALLOCATION :
+						if(this.invocationType == ALLOCATION || this.invocationType == QUALIFIED_ALLOCATION) {
+							this.currentElement = this.currentElement.add((TypeReference)node, 0);
+						}
+						break nextElement;
+					case K_PARAMETERIZED_METHOD_INVOCATION :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 1) == 0) {
+							this.currentElement = this.currentElement.add((TypeReference)node, 0);
+							break nextElement;
+						}
+				}
+				if(info == LESS && node instanceof TypeReference) {
+					if(this.identifierLengthPtr > -1 && this.identifierLengthStack[this.identifierLengthPtr]!= 0) {
+						if (consumeTypeArguments) consumeTypeArguments();
+						TypeReference ref = this.getTypeReference(0);
+						if(prevKind == K_PARAMETERIZED_CAST) {
+							ref = computeQualifiedGenericsFromRightSide(ref, 0, null);
+						}
+						if(this.currentElement instanceof RecoveredType) {
+							this.currentElement = this.currentElement.add(new CompletionOnFieldType(ref, false), 0);
+						} else {							
+							
+							if (prevKind == K_BETWEEN_NEW_AND_LEFT_BRACKET) {
+								
+								AllocationExpression exp;
+								if (this.expressionPtr > -1 && this.expressionStack[this.expressionPtr] instanceof AllocationExpression 
+										&& this.invocationType == QUALIFIED_ALLOCATION) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=361963
+									exp = new QualifiedAllocationExpression();
+									exp.type = ref;
+									((QualifiedAllocationExpression)exp).enclosingInstance = this.expressionStack[this.expressionPtr];
+								} else {
+									exp = new AllocationExpression();
+									exp.type = ref;
+								}
+								if (isInsideReturn()) {
+									ReturnStatement returnStatement = new ReturnStatement(exp, exp.sourceStart, exp.sourceEnd);
+									this.enclosingNode = returnStatement;
+									this.currentElement  = this.currentElement.add(returnStatement,0);
+								} else if (this.currentElement instanceof RecoveredLocalVariable) {
+									if (((RecoveredLocalVariable)this.currentElement).localDeclaration.initialization == null) {
+										this.enclosingNode = ((RecoveredLocalVariable) this.currentElement).localDeclaration;
+										this.currentElement = this.currentElement.add(exp, 0);
+									}
+								} else if (this.currentElement instanceof RecoveredField) {
+									if (((RecoveredField) this.currentElement).fieldDeclaration.initialization == null) {
+										this.enclosingNode = ((RecoveredField) this.currentElement).fieldDeclaration;
+										this.currentElement = this.currentElement.add(exp, 0);
+									}
+								} else {
+									this.currentElement = this.currentElement.add(ref, 0);
+								}
+							} else {
+								this.currentElement = this.currentElement.add(ref, 0);
+							}
+						}
+					} else if (this.currentElement.enclosingMethod() != null &&
+							this.currentElement.enclosingMethod().methodDeclaration.isConstructor()) {
+						this.currentElement = this.currentElement.add((TypeReference)node, 0);
+					}
+				}
+				break;
+		}
+	}
+}
+private void buildMoreTryStatementCompletionContext(TypeReference exceptionRef) {
+	if (this.astLengthPtr > 0 &&
+			this.astPtr > 2 &&
+			this.astStack[this.astPtr -1] instanceof Block &&
+			this.astStack[this.astPtr - 2] instanceof Argument) {
+		TryStatement tryStatement = new TryStatement();
+
+		int newAstPtr = this.astPtr - 1;
+
+		int length = this.astLengthStack[this.astLengthPtr - 1];
+		Block[] bks = (tryStatement.catchBlocks = new Block[length + 1]);
+		Argument[] args = (tryStatement.catchArguments = new Argument[length + 1]);
+		if (length != 0) {
+			while (length-- > 0) {
+				bks[length] = (Block) this.astStack[newAstPtr--];
+				bks[length].statements = null; // statements of catch block won't be used
+				args[length] = (Argument) this.astStack[newAstPtr--];
+			}
+		}
+
+		bks[bks.length - 1] = new Block(0);
+		if (this.astStack[this.astPtr] instanceof UnionTypeReference) {
+			UnionTypeReference unionTypeReference = (UnionTypeReference) this.astStack[this.astPtr];
+			args[args.length - 1] = new Argument(FAKE_ARGUMENT_NAME,0,unionTypeReference,0);
+		} else {
+			args[args.length - 1] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		}
+
+		tryStatement.tryBlock = (Block) this.astStack[newAstPtr--];
+
+		this.assistNodeParent = tryStatement;
+
+		this.currentElement.add(tryStatement, 0);
+	} else if (this.astLengthPtr > -1 &&
+			this.astPtr > 0 &&
+			this.astStack[this.astPtr - 1] instanceof Block) {
+		TryStatement tryStatement = new TryStatement();
+
+		int newAstPtr = this.astPtr - 1;
+
+		Block[] bks = (tryStatement.catchBlocks = new Block[1]);
+		Argument[] args = (tryStatement.catchArguments = new Argument[1]);
+
+		bks[0] = new Block(0);
+		if (this.astStack[this.astPtr] instanceof UnionTypeReference) {
+			UnionTypeReference unionTypeReference = (UnionTypeReference) this.astStack[this.astPtr];
+			args[0] = new Argument(FAKE_ARGUMENT_NAME,0,unionTypeReference,0);
+		} else {
+			args[0] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		}
+
+		tryStatement.tryBlock = (Block) this.astStack[newAstPtr--];
+
+		this.assistNodeParent = tryStatement;
+
+		this.currentElement.add(tryStatement, 0);
+	}else {
+		this.currentElement = this.currentElement.add(exceptionRef, 0);
+	}
+}
+public int bodyEnd(AbstractMethodDeclaration method){
+	return this.cursorLocation;
+}
+public int bodyEnd(Initializer initializer){
+	return this.cursorLocation;
+}
+protected void checkAndSetModifiers(int flag) {
+	super.checkAndSetModifiers(flag);
+
+	if (isInsideMethod()) {
+		this.hasUnusedModifiers = true;
+	}
+}
+protected void consumePushCombineModifiers() {
+	super.consumePushCombineModifiers();
+
+	if (isInsideMethod()) {
+		this.hasUnusedModifiers = true;
+	}
+}
+/**
+ * Checks if the completion is on the type following a 'new'.
+ * Returns whether we found a completion node.
+ */
+private boolean checkClassInstanceCreation() {
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_NEW_AND_LEFT_BRACKET) {
+		int length = this.identifierLengthStack[this.identifierLengthPtr];
+		int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr];
+		if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
+			// no class instance creation with a parameterized type
+			return true;
+		}
+
+		// completion on type inside an allocation expression
+
+		TypeReference type;
+		if (this.invocationType == ALLOCATION) {
+			// non qualified allocation expression
+			AllocationExpression allocExpr = new AllocationExpression();
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_INSIDE_THROW_STATEMENT
+				&& topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 1) == this.bracketDepth) {
+				pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+				type = getTypeReference(0);
+				popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+			} else {
+				type = getTypeReference(0);
+			}
+			if(type instanceof CompletionOnSingleTypeReference) {
+				((CompletionOnSingleTypeReference)type).isConstructorType = true;
+			} else if (type instanceof CompletionOnQualifiedTypeReference) {
+				((CompletionOnQualifiedTypeReference)type).isConstructorType = true;
+			}
+			allocExpr.type = type;
+			allocExpr.sourceStart = type.sourceStart;
+			allocExpr.sourceEnd = type.sourceEnd;
+			pushOnExpressionStack(allocExpr);
+			this.isOrphanCompletionNode = false;
+		} else {
+			// qualified allocation expression
+			QualifiedAllocationExpression allocExpr = new QualifiedAllocationExpression();
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+			pushOnGenericsLengthStack(0);
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_INSIDE_THROW_STATEMENT
+				&& topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 1) == this.bracketDepth) {
+				pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+				type = getTypeReference(0);
+				popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+			} else {
+				type = getTypeReference(0);
+			}
+			if(type instanceof CompletionOnSingleTypeReference) {
+				((CompletionOnSingleTypeReference)type).isConstructorType = true;
+			}
+			allocExpr.type = type;
+			allocExpr.enclosingInstance = this.expressionStack[this.qualifier];
+			allocExpr.sourceStart = this.intStack[this.intPtr--];
+			allocExpr.sourceEnd = type.sourceEnd;
+			this.expressionStack[this.qualifier] = allocExpr; // attach it now (it replaces the qualifier expression)
+			this.isOrphanCompletionNode = false;
+		}
+		this.assistNode = type;
+		this.lastCheckPoint = type.sourceEnd + 1;
+
+		popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
+		return true;
+	}
+	return false;
+}
+/**
+ * Checks if the completion is on the dot following an array type,
+ * a primitive type or an primitive array type.
+ * Returns whether we found a completion node.
+ */
+private boolean checkClassLiteralAccess() {
+	if (this.identifierLengthPtr >= 1 && this.previousToken == TokenNameDOT) { // (NB: the top id length is 1 and it is for the completion identifier)
+		int length;
+		// if the penultimate id length is negative,
+		// the completion is after a primitive type or a primitive array type
+		if ((length = this.identifierLengthStack[this.identifierLengthPtr-1]) < 0) {
+			// build the primitive type node
+			int dim = isAfterArrayType() ? this.intStack[this.intPtr--] : 0;
+			Annotation [][] annotationsOnDimensions = dim == 0 ? null : getAnnotationsOnDimensions(dim);
+			SingleTypeReference typeRef = (SingleTypeReference)TypeReference.baseTypeReference(-length, dim, annotationsOnDimensions);
+			typeRef.sourceStart = this.intStack[this.intPtr--];
+			if (dim == 0) {
+				typeRef.sourceEnd = this.intStack[this.intPtr--];
+			} else {
+				this.intPtr--;
+				typeRef.sourceEnd = this.endPosition;
+			}
+			//typeRef.sourceEnd = typeRef.sourceStart + typeRef.token.length; // NB: It's ok to use the length of the token since it doesn't contain any unicode
+
+			// find the completion identifier and its source positions
+			char[] source = this.identifierStack[this.identifierPtr];
+			long pos = this.identifierPositionStack[this.identifierPtr--];
+			this.identifierLengthPtr--; // it can only be a simple identifier (so its length is one)
+
+			// build the completion on class literal access node
+			CompletionOnClassLiteralAccess access = new CompletionOnClassLiteralAccess(pos, typeRef);
+			access.completionIdentifier = source;
+			this.identifierLengthPtr--; // pop the length that was used to say it is a primitive type
+			this.assistNode = access;
+			this.isOrphanCompletionNode = true;
+			return true;
+		}
+
+		// if the completion is after a regular array type
+		if (isAfterArrayType()) {
+			// find the completion identifier and its source positions
+			char[] source = this.identifierStack[this.identifierPtr];
+			long pos = this.identifierPositionStack[this.identifierPtr--];
+			this.identifierLengthPtr--; // it can only be a simple identifier (so its length is one)
+
+			// get the type reference
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+			pushOnGenericsLengthStack(0);
+
+			TypeReference typeRef = getTypeReference(this.intStack[this.intPtr--]);
+
+			// build the completion on class literal access node
+			CompletionOnClassLiteralAccess access = new CompletionOnClassLiteralAccess(pos, typeRef);
+			access.completionIdentifier = source;
+			this.assistNode = access;
+			this.isOrphanCompletionNode = true;
+			return true;
+		}
+
+	}
+	return false;
+}
+private boolean checkKeyword() {
+	if (this.currentElement instanceof RecoveredUnit) {
+		RecoveredUnit unit = (RecoveredUnit) this.currentElement;
+		int index = -1;
+		if ((index = this.indexOfAssistIdentifier()) > -1) {
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+
+			char[] ident = this.identifierStack[ptr];
+			long pos = this.identifierPositionStack[ptr];
+
+			char[][] keywords = new char[Keywords.COUNT][];
+			int count = 0;
+			if(unit.typeCount == 0
+				&& (!this.compilationUnit.isPackageInfo() || this.compilationUnit.currentPackage != null)
+				&& this.lastModifiers == ClassFileConstants.AccDefault) {
+				keywords[count++] = Keywords.IMPORT;
+			}
+			if(unit.typeCount == 0
+				&& unit.importCount == 0
+				&& this.lastModifiers == ClassFileConstants.AccDefault
+				&& this.compilationUnit.currentPackage == null) {
+				keywords[count++] = Keywords.PACKAGE;
+			}
+			if (!this.compilationUnit.isPackageInfo()) {
+				if((this.lastModifiers & ClassFileConstants.AccPublic) == 0) {
+					boolean hasNoPublicType = true;
+					for (int i = 0; i < unit.typeCount; i++) {
+						if((unit.types[i].typeDeclaration.modifiers & ClassFileConstants.AccPublic) != 0) {
+							hasNoPublicType = false;
+						}
+					}
+					if(hasNoPublicType) {
+						keywords[count++] = Keywords.PUBLIC;
+					}
+				}
+				if((this.lastModifiers & ClassFileConstants.AccAbstract) == 0
+					&& (this.lastModifiers & ClassFileConstants.AccFinal) == 0) {
+					keywords[count++] = Keywords.ABSTRACT;
+				}
+				if((this.lastModifiers & ClassFileConstants.AccAbstract) == 0
+					&& (this.lastModifiers & ClassFileConstants.AccFinal) == 0) {
+					keywords[count++] = Keywords.FINAL;
+				}
+	
+				keywords[count++] = Keywords.CLASS;
+				if (this.options.complianceLevel >= ClassFileConstants.JDK1_5) {
+					keywords[count++] = Keywords.ENUM;
+				}
+	
+				if((this.lastModifiers & ClassFileConstants.AccFinal) == 0) {
+					keywords[count++] = Keywords.INTERFACE;
+				}
+			}
+			if(count != 0) {
+				System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
+
+				this.assistNode = new CompletionOnKeyword2(ident, pos, keywords);
+				this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+private boolean checkInstanceofKeyword() {
+	if(isInsideMethod()) {
+		int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+		int index;
+		if(kind != K_BLOCK_DELIMITER
+			&& (index = indexOfAssistIdentifier()) > -1
+			&& this.expressionPtr > -1
+			&& this.expressionLengthStack[this.expressionPtr] == 1) {
+
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+			if(this.identifierStack[ptr].length > 0 && CharOperation.prefixEquals(this.identifierStack[ptr], Keywords.INSTANCEOF)) {
+				this.assistNode = new CompletionOnKeyword3(
+						this.identifierStack[ptr],
+						this.identifierPositionStack[ptr],
+						Keywords.INSTANCEOF);
+				this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/**
+ * Checks if the completion is inside a method invocation or a constructor invocation.
+ * Returns whether we found a completion node.
+ */
+private boolean checkInvocation() {
+	Expression topExpression = this.expressionPtr >= 0 ?
+		this.expressionStack[this.expressionPtr] :
+		null;
+	boolean isEmptyNameCompletion = false;
+	boolean isEmptyAssistIdentifier = false;
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR_QUALIFIER
+		&& ((isEmptyNameCompletion = topExpression == this.assistNode && isEmptyNameCompletion()) // e.g. it is something like "this.fred([cursor]" but it is not something like "this.fred(1 + [cursor]"
+			|| (isEmptyAssistIdentifier = this.indexOfAssistIdentifier() >= 0 && this.identifierStack[this.identifierPtr].length == 0))) { // e.g. it is something like "this.fred(1 [cursor]"
+
+		// pop empty name completion
+		if (isEmptyNameCompletion) {
+			this.expressionPtr--;
+			this.expressionLengthStack[this.expressionLengthPtr]--;
+		} else if (isEmptyAssistIdentifier) {
+			this.identifierPtr--;
+			this.identifierLengthPtr--;
+		}
+
+		// find receiver and qualifier
+		int invocType = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 1);
+		int qualifierExprPtr = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+
+		// find arguments
+		int numArgs = this.expressionPtr - qualifierExprPtr;
+		int argStart = qualifierExprPtr + 1;
+		Expression[] arguments = null;
+		if (numArgs > 0) {
+			// remember the arguments
+			arguments = new Expression[numArgs];
+			System.arraycopy(this.expressionStack, argStart, arguments, 0, numArgs);
+
+			// consume the expression arguments
+			this.expressionPtr -= numArgs;
+			int count = numArgs;
+			while (count > 0) {
+				count -= this.expressionLengthStack[this.expressionLengthPtr--];
+			}
+		}
+
+		// build ast node
+		if (invocType != ALLOCATION && invocType != QUALIFIED_ALLOCATION) {
+			// creates completion on message send
+			CompletionOnMessageSend messageSend = new CompletionOnMessageSend();
+			messageSend.arguments = arguments;
+			switch (invocType) {
+				case NO_RECEIVER:
+					// implicit this
+					messageSend.receiver = ThisReference.implicitThis();
+					break;
+				case NAME_RECEIVER:
+					// remove special flags for primitive types
+					while (this.identifierLengthPtr >= 0 && this.identifierLengthStack[this.identifierLengthPtr] < 0) {
+						this.identifierLengthPtr--;
+					}
+
+					// remove selector
+					this.identifierPtr--;
+					if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsLengthStack[this.genericsLengthPtr] > 0) {
+						// is inside a paremeterized method: bar.<X>.foo
+						this.identifierLengthPtr--;
+					} else {
+						this.identifierLengthStack[this.identifierLengthPtr]--;
+						int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--];
+						Annotation [] typeAnnotations;
+						if (length != 0) {
+							System.arraycopy(
+									this.typeAnnotationStack,
+									(this.typeAnnotationPtr -= length) + 1,
+									typeAnnotations = new Annotation[length],
+									0,
+									length);
+							problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]);
+						}
+					}
+					// consume the receiver
+					messageSend.receiver = getUnspecifiedReference();
+					break;
+				case SUPER_RECEIVER:
+					messageSend.receiver = new SuperReference(0, 0);
+					break;
+				case EXPLICIT_RECEIVER:
+					messageSend.receiver = this.expressionStack[qualifierExprPtr];
+			}
+
+			// set selector
+			int selectorPtr = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 2);
+			messageSend.selector = this.identifierStack[selectorPtr];
+			// remove selector
+			if (this.identifierLengthPtr >=0 && this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+				this.identifierPtr--;
+				this.identifierLengthPtr--;
+			}
+
+			// the entire message may be replaced in case qualification is needed
+			messageSend.sourceStart = (int)(this.identifierPositionStack[selectorPtr] >> 32); //this.cursorLocation + 1;
+			messageSend.sourceEnd = this.cursorLocation;
+
+			// remember the message send as an orphan completion node
+			this.assistNode = messageSend;
+			this.lastCheckPoint = messageSend.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		} else {
+			int selectorPtr = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 2);
+			if (selectorPtr == THIS_CONSTRUCTOR || selectorPtr == SUPER_CONSTRUCTOR) {
+				// creates an explicit constructor call
+				CompletionOnExplicitConstructorCall call = new CompletionOnExplicitConstructorCall(
+					(selectorPtr == THIS_CONSTRUCTOR) ? ExplicitConstructorCall.This : ExplicitConstructorCall.Super);
+				call.arguments = arguments;
+				if (invocType == QUALIFIED_ALLOCATION) {
+					call.qualification = this.expressionStack[qualifierExprPtr];
+				}
+
+				// no source is going to be replaced
+				call.sourceStart = this.cursorLocation + 1;
+				call.sourceEnd = this.cursorLocation;
+
+				// remember the explicit constructor call as an orphan completion node
+				this.assistNode = call;
+				this.lastCheckPoint = call.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			} else {
+				// creates an allocation expression
+				CompletionOnQualifiedAllocationExpression allocExpr = new CompletionOnQualifiedAllocationExpression();
+				allocExpr.arguments = arguments;
+				if(this.genericsLengthPtr < 0) {
+					pushOnGenericsLengthStack(0);
+					pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+				}
+				allocExpr.type = super.getTypeReference(0); // we don't want a completion node here, so call super
+				if (invocType == QUALIFIED_ALLOCATION) {
+					allocExpr.enclosingInstance = this.expressionStack[qualifierExprPtr];
+				}
+				// no source is going to be replaced
+				allocExpr.sourceStart = this.cursorLocation + 1;
+				allocExpr.sourceEnd = this.cursorLocation;
+
+				// remember the allocation expression as an orphan completion node
+				this.assistNode = allocExpr;
+				this.lastCheckPoint = allocExpr.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+private boolean checkLabelStatement() {
+	if(isInsideMethod() || isInsideFieldInitialization()) {
+
+		int kind = this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+		if(kind != K_INSIDE_BREAK_STATEMENT && kind != K_INSIDE_CONTINUE_STATEMENT) return false;
+
+		if (indexOfAssistIdentifier() != 0) return false;
+
+		char[][] labels = new char[this.labelPtr + 1][];
+		int labelCount = 0;
+
+		int labelKind = kind;
+		int index = 1;
+		while(labelKind != 0 && labelKind != K_METHOD_DELIMITER) {
+			labelKind = this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, index);
+			if(labelKind == K_LABEL) {
+				int ptr = this.topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, index);
+				labels[labelCount++] = this.labelStack[ptr];
+			}
+			index++;
+		}
+		System.arraycopy(labels, 0, labels = new char[labelCount][], 0, labelCount);
+
+		long position = this.identifierPositionStack[this.identifierPtr];
+		CompletionOnBranchStatementLabel statementLabel =
+			new CompletionOnBranchStatementLabel(
+					kind == K_INSIDE_BREAK_STATEMENT ? CompletionOnBranchStatementLabel.BREAK : CompletionOnBranchStatementLabel.CONTINUE,
+					this.identifierStack[this.identifierPtr--],
+					(int) (position >>> 32),
+					(int)position,
+					labels);
+
+		this.assistNode = statementLabel;
+		this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+		this.isOrphanCompletionNode = true;
+		return true;
+	}
+	return false;
+}
+/**
+ * Checks if the completion is on a member access (i.e. in an identifier following a dot).
+ * Returns whether we found a completion node.
+ */
+private boolean checkMemberAccess() {
+	if (this.previousToken == TokenNameDOT && this.qualifier > -1 && this.expressionPtr == this.qualifier) {
+		if (this.identifierLengthPtr > 1 && this.identifierLengthStack[this.identifierLengthPtr - 1] < 0) {
+			// its not a  member access because the receiver is a base type
+			// fix for bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=137623
+			return false;
+		}
+		// the receiver is an expression
+		pushCompletionOnMemberAccessOnExpressionStack(false);
+		return true;
+	}
+	return false;
+}
+/**
+ * Checks if the completion is on a name reference.
+ * Returns whether we found a completion node.
+ */
+private boolean checkNameCompletion() {
+	/*
+		We didn't find any other completion, but the completion identifier is on the identifier stack,
+		so it can only be a completion on name.
+		Note that we allow the completion on a name even if nothing is expected (e.g. foo() b[cursor] would
+		be a completion on 'b'). This policy gives more to the user than he/she would expect, but this
+		simplifies the problem. To fix this, the recovery must be changed to work at a 'statement' granularity
+		instead of at the 'expression' granularity as it does right now.
+	*/
+
+	// NB: at this point the completion identifier is on the identifier stack
+	this.assistNode = getUnspecifiedReferenceOptimized();
+	this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+	this.isOrphanCompletionNode = true;
+	if (this.hasUnusedModifiers &&
+			this.assistNode instanceof CompletionOnSingleNameReference) {
+		((CompletionOnSingleNameReference)this.assistNode).isPrecededByModifiers = true;
+	}
+	return true;
+}
+private boolean checkParemeterizedMethodName() {
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_METHOD_INVOCATION &&
+			topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == INSIDE_NAME) {
+		if(this.identifierLengthPtr > -1 && this.genericsLengthPtr > -1 && this.genericsIdentifiersLengthPtr == -1) {
+			CompletionOnMessageSendName m = null;
+			switch (this.invocationType) {
+				case EXPLICIT_RECEIVER:
+				case NO_RECEIVER: // this case occurs with 'bar().foo'
+					if(this.expressionPtr > -1 && this.expressionLengthStack[this.expressionLengthPtr] == 1) {
+						char[] selector = this.identifierStack[this.identifierPtr];
+						long position = this.identifierPositionStack[this.identifierPtr--];
+						this.identifierLengthPtr--;
+						int end = (int) position;
+						int start = (int) (position >>> 32);
+						m = new CompletionOnMessageSendName(selector, start, end);
+
+						// handle type arguments
+						int length = this.genericsLengthStack[this.genericsLengthPtr--];
+						this.genericsPtr -= length;
+						System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+						this.intPtr--;
+
+						m.receiver = this.expressionStack[this.expressionPtr--];
+						this.expressionLengthPtr--;
+					}
+					break;
+				case NAME_RECEIVER:
+					if(this.identifierPtr > 0) {
+						char[] selector = this.identifierStack[this.identifierPtr];
+						long position = this.identifierPositionStack[this.identifierPtr--];
+						this.identifierLengthPtr--;
+						int end = (int) position;
+						int start = (int) (position >>> 32);
+						m = new CompletionOnMessageSendName(selector, start, end);
+
+						// handle type arguments
+						int length = this.genericsLengthStack[this.genericsLengthPtr--];
+						this.genericsPtr -= length;
+						System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+						this.intPtr--;
+
+						m.receiver = getUnspecifiedReference();
+					}
+					break;
+				case SUPER_RECEIVER:
+					char[] selector = this.identifierStack[this.identifierPtr];
+					long position = this.identifierPositionStack[this.identifierPtr--];
+					this.identifierLengthPtr--;
+					int end = (int) position;
+					int start = (int) (position >>> 32);
+					m = new CompletionOnMessageSendName(selector, start, end);
+
+					// handle type arguments
+					int length = this.genericsLengthStack[this.genericsLengthPtr--];
+					this.genericsPtr -= length;
+					System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+					this.intPtr--;
+
+					m.receiver = new SuperReference(start, end);
+					break;
+			}
+
+			if(m != null) {
+				pushOnExpressionStack(m);
+
+				this.assistNode = m;
+				this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+private boolean checkParemeterizedType() {
+	if(this.identifierLengthPtr > -1 && this.genericsLengthPtr > -1 && this.genericsIdentifiersLengthPtr > -1) {
+		int length = this.identifierLengthStack[this.identifierLengthPtr];
+		int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr];
+		if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
+			this.genericsIdentifiersLengthPtr--;
+			this.identifierLengthPtr--;
+			// generic type
+			this.assistNode = getAssistTypeReferenceForGenericType(0, length, numberOfIdentifiers);
+			this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		} else if(this.genericsPtr > -1 && this.genericsStack[this.genericsPtr] instanceof TypeReference) {
+			// type of a cast expression
+			numberOfIdentifiers++;
+
+			this.genericsIdentifiersLengthPtr--;
+			this.identifierLengthPtr--;
+			// generic type
+			this.assistNode = getAssistTypeReferenceForGenericType(0, length, numberOfIdentifiers);
+			this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		}
+	}
+	return false;
+}
+/**
+ * Checks if the completion is in the context of a method and on the type of one of its arguments
+ * Returns whether we found a completion node.
+ */
+private boolean checkRecoveredMethod() {
+	if (this.currentElement instanceof RecoveredMethod){
+		/* check if current awaiting identifier is the completion identifier */
+		if (this.indexOfAssistIdentifier() < 0) return false;
+
+		/* check if on line with an error already - to avoid completing inside
+			illegal type names e.g.  int[<cursor> */
+		if (this.lastErrorEndPosition <= this.cursorLocation
+			&& Util.getLineNumber(this.lastErrorEndPosition, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(((CompletionScanner)this.scanner).completedIdentifierStart, this.scanner.lineEnds, 0, this.scanner.linePtr)){
+			return false;
+		}
+ 		RecoveredMethod recoveredMethod = (RecoveredMethod)this.currentElement;
+		/* only consider if inside method header */
+		if (!recoveredMethod.foundOpeningBrace
+			&& this.lastIgnoredToken == -1) {
+			//if (rParenPos < lParenPos){ // inside arguments
+			this.assistNode = this.getTypeReference(0);
+			this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		}
+	}
+	return false;
+}
+private boolean checkMemberValueName() {
+	/* check if current awaiting identifier is the completion identifier */
+	if (this.indexOfAssistIdentifier() < 0) return false;
+
+	if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) return false;
+
+	if(this.identifierPtr > -1 && this.identifierLengthPtr > -1 && this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+		char[] simpleName = this.identifierStack[this.identifierPtr];
+		long position = this.identifierPositionStack[this.identifierPtr--];
+		this.identifierLengthPtr--;
+		int end = (int) position;
+		int start = (int) (position >>> 32);
+
+
+		CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+		this.assistNode = memberValueName;
+		this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+		this.isOrphanCompletionNode = true;
+
+		return true;
+	}
+	return false;
+}
+/**
+ * Checks if the completion is in the context of a type and on a type reference in this type.
+ * Persists the identifier into a fake field return type
+ * Returns whether we found a completion node.
+ */
+private boolean checkRecoveredType() {
+	if (this.currentElement instanceof RecoveredType){
+		/* check if current awaiting identifier is the completion identifier */
+		if (this.indexOfAssistIdentifier() < 0) return false;
+
+		/* check if on line with an error already - to avoid completing inside
+			illegal type names e.g.  int[<cursor> */
+		if (this.lastErrorEndPosition <= this.cursorLocation
+			&& ((RecoveredType)this.currentElement).lastMemberEnd() < this.lastErrorEndPosition
+			&& Util.getLineNumber(this.lastErrorEndPosition, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(((CompletionScanner)this.scanner).completedIdentifierStart, this.scanner.lineEnds, 0, this.scanner.linePtr)){
+			return false;
+		}
+		RecoveredType recoveredType = (RecoveredType)this.currentElement;
+		/* filter out cases where scanner is still inside type header */
+		if (recoveredType.foundOpeningBrace) {
+			// complete generics stack if necessary
+			if((this.genericsIdentifiersLengthPtr < 0 && this.identifierPtr > -1)
+					|| (this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] <= this.identifierPtr)) {
+				pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+				pushOnGenericsLengthStack(0); // handle type arguments
+			}
+			this.assistNode = this.getTypeReference(0);
+			this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		} else {
+			if(recoveredType.typeDeclaration.superclass == null &&
+					this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_EXTENDS_KEYWORD) {
+				consumeClassOrInterfaceName();
+				this.pushOnElementStack(K_NEXT_TYPEREF_IS_CLASS);
+				this.assistNode = this.getTypeReference(0);
+				popElement(K_NEXT_TYPEREF_IS_CLASS);
+				this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+				this.isOrphanCompletionNode = true;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+private void classHeaderExtendsOrImplements(boolean isInterface) {
+	if (this.currentElement != null
+			&& this.currentToken == TokenNameIdentifier
+			&& this.cursorLocation+1 >= this.scanner.startPosition
+			&& this.cursorLocation < this.scanner.currentPosition){
+			this.pushIdentifier();
+		int index = -1;
+		/* check if current awaiting identifier is the completion identifier */
+		if ((index = this.indexOfAssistIdentifier()) > -1) {
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			/* filter out cases where scanner is still inside type header */
+			if (!recoveredType.foundOpeningBrace) {
+				TypeDeclaration type = recoveredType.typeDeclaration;
+				if(!isInterface) {
+					char[][] keywords = new char[Keywords.COUNT][];
+					int count = 0;
+
+
+					if(type.superInterfaces == null) {
+						if(type.superclass == null) {
+							keywords[count++] = Keywords.EXTENDS;
+						}
+						keywords[count++] = Keywords.IMPLEMENTS;
+					}
+
+					System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
+
+					if(count > 0) {
+						CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+							this.identifierStack[ptr],
+							this.identifierPositionStack[ptr],
+							keywords);
+						type.superclass = completionOnKeyword;
+						type.superclass.bits |= ASTNode.IsSuperType;
+						this.assistNode = completionOnKeyword;
+						this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+					}
+				} else {
+					if(type.superInterfaces == null) {
+						CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+							this.identifierStack[ptr],
+							this.identifierPositionStack[ptr],
+							Keywords.EXTENDS);
+						type.superInterfaces = new TypeReference[]{completionOnKeyword};
+						type.superInterfaces[0].bits |= ASTNode.IsSuperType;
+						this.assistNode = completionOnKeyword;
+						this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+					}
+				}
+			}
+		}
+	}
+}
+/*
+ * Check whether about to shift beyond the completion token.
+ * If so, depending on the context, a special node might need to be created
+ * and attached to the existing recovered structure so as to be remember in the
+ * resulting parsed structure.
+ */
+public void completionIdentifierCheck(){
+	//if (assistNode != null) return;
+
+	if (checkMemberValueName()) return;
+	if (checkKeyword()) return;
+	if (checkRecoveredType()) return;
+	if (checkRecoveredMethod()) return;
+
+	// if not in a method in non diet mode and if not inside a field initializer, only record references attached to types
+	if (!(isInsideMethod() && !this.diet)
+		&& !isIndirectlyInsideFieldInitialization()
+		&& !isInsideAttributeValue()) return;
+
+	/*
+	 	In some cases, the completion identifier may not have yet been consumed,
+	 	e.g.  int.[cursor]
+	 	This is because the grammar does not allow any (empty) identifier to follow
+	 	a base type. We thus have to manually force the identifier to be consumed
+	 	(that is, pushed).
+	 */
+	if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
+		if (this.cursorLocation < this.scanner.startPosition && this.scanner.currentPosition == this.scanner.startPosition){ // fake empty identifier got issued
+			this.pushIdentifier();
+		} else if (this.cursorLocation+1 >= this.scanner.startPosition && this.cursorLocation < this.scanner.currentPosition){
+			this.pushIdentifier();
+		}
+	}
+
+	// check for different scenarii
+	// no need to go further if we found a non empty completion node
+	// (we still need to store labels though)
+	if (this.assistNode != null) {
+		// however inside an invocation, the completion identifier may already have been consumed into an empty name
+		// completion, so this check should be before we check that we are at the cursor location
+		if (!isEmptyNameCompletion() || checkInvocation()) return;
+	}
+
+	// no need to check further if we are not at the cursor location
+	if (this.indexOfAssistIdentifier() < 0) return;
+
+	if (checkClassInstanceCreation()) return;
+	if (checkMemberAccess()) return;
+	if (checkClassLiteralAccess()) return;
+	if (checkInstanceofKeyword()) return;
+
+	// if the completion was not on an empty name, it can still be inside an invocation (e.g. this.fred("abc"[cursor])
+	// (NB: Put this check before checkNameCompletion() because the selector of the invocation can be on the identifier stack)
+	if (checkInvocation()) return;
+
+	if (checkParemeterizedType()) return;
+	if (checkParemeterizedMethodName()) return;
+	if (checkLabelStatement()) return;
+	if (checkNameCompletion()) return;
+}
+protected void consumeArrayCreationExpressionWithInitializer() {
+	super.consumeArrayCreationExpressionWithInitializer();
+	popElement(K_ARRAY_CREATION);
+}
+protected void consumeArrayCreationExpressionWithoutInitializer() {
+	super.consumeArrayCreationExpressionWithoutInitializer();
+	popElement(K_ARRAY_CREATION);
+}
+protected void consumeArrayCreationHeader() {
+	// nothing to do
+}
+protected void consumeAssignment() {
+	popElement(K_ASSISGNMENT_OPERATOR);
+	super.consumeAssignment();
+}
+protected void consumeAssignmentOperator(int pos) {
+	super.consumeAssignmentOperator(pos);
+	pushOnElementStack(K_ASSISGNMENT_OPERATOR, pos);
+}
+protected void consumeBinaryExpression(int op) {
+	super.consumeBinaryExpression(op);
+	popElement(K_BINARY_OPERATOR);
+
+	if(this.expressionStack[this.expressionPtr] instanceof BinaryExpression) {
+		BinaryExpression exp = (BinaryExpression) this.expressionStack[this.expressionPtr];
+		if(this.assistNode != null && exp.right == this.assistNode) {
+			this.assistNodeParent = exp;
+		}
+	}
+}
+protected void consumeBinaryExpressionWithName(int op) {
+	super.consumeBinaryExpressionWithName(op);
+	popElement(K_BINARY_OPERATOR);
+
+	if(this.expressionStack[this.expressionPtr] instanceof BinaryExpression) {
+		BinaryExpression exp = (BinaryExpression) this.expressionStack[this.expressionPtr];
+		if(this.assistNode != null && exp.right == this.assistNode) {
+			this.assistNodeParent = exp;
+		}
+	}
+}
+protected void consumeCaseLabel() {
+	super.consumeCaseLabel();
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_SWITCH_LABEL) {
+		pushOnElementStack(K_SWITCH_LABEL);
+	}
+}
+protected void consumeCastExpressionWithPrimitiveType() {
+	popElement(K_CAST_STATEMENT);
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr+1], castType = (TypeReference) this.expressionStack[this.expressionPtr]);
+	cast.sourceStart = castType.sourceStart - 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionWithGenericsArray() {
+	popElement(K_CAST_STATEMENT);
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr + 1], castType = (TypeReference) this.expressionStack[this.expressionPtr]);
+	cast.sourceStart = castType.sourceStart - 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+
+protected void consumeCastExpressionWithQualifiedGenericsArray() {
+	popElement(K_CAST_STATEMENT);
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr + 1], castType = (TypeReference) this.expressionStack[this.expressionPtr]);
+	cast.sourceStart = castType.sourceStart - 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionWithNameArray() {
+	// CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+	popElement(K_CAST_STATEMENT);
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr+1], castType = (TypeReference) this.expressionStack[this.expressionPtr]);
+	cast.sourceStart = castType.sourceStart - 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionLL1() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionLL1();
+}
+protected void consumeCatchFormalParameter() {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeCatchFormalParameter();
+		if (this.pendingAnnotation != null) {
+			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+			this.pendingAnnotation = null;
+		}
+	} else {
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		this.intPtr--; // dimension from the variabledeclaratorid
+		TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+		this.intPtr -= 2;
+		CompletionOnArgumentName arg =
+			new CompletionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		arg.bits &= ~ASTNode.IsArgument;
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+		}
+
+		arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN;
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
+protected void consumeClassBodyDeclaration() {
+	popElement(K_BLOCK_DELIMITER);
+	super.consumeClassBodyDeclaration();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeClassBodyopt() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeClassBodyopt();
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#consumeClassDeclaration()
+ */
+protected void consumeClassDeclaration() {
+	if (this.astPtr >= 0) {
+		int length = this.astLengthStack[this.astLengthPtr];
+		TypeDeclaration typeDeclaration = (TypeDeclaration) this.astStack[this.astPtr-length];
+		this.javadoc = null;
+		CompletionJavadocParser completionJavadocParser = (CompletionJavadocParser)this.javadocParser;
+		completionJavadocParser.allPossibleTags = true;
+		checkComment();
+		if (this.javadoc != null && this.cursorLocation > this.javadoc.sourceStart && this.cursorLocation < this.javadoc.sourceEnd) {
+			// completion is in an orphan javadoc comment => replace in last read declaration to allow completion resolution
+			typeDeclaration.javadoc = this.javadoc;
+		}
+		completionJavadocParser.allPossibleTags = false;
+	}
+	super.consumeClassDeclaration();
+}
+protected void consumeClassHeaderName1() {
+	super.consumeClassHeaderName1();
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+	classHeaderExtendsOrImplements(false);
+}
+
+protected void consumeClassHeaderExtends() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_CLASS);
+	super.consumeClassHeaderExtends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+		if (typeDecl != null && typeDecl.superclass == this.assistNode)
+			this.assistNodeParent = typeDecl;
+	}
+	popElement(K_NEXT_TYPEREF_IS_CLASS);
+	popElement(K_EXTENDS_KEYWORD);
+
+	if (this.currentElement != null
+		&& this.currentToken == TokenNameIdentifier
+		&& this.cursorLocation+1 >= this.scanner.startPosition
+		&& this.cursorLocation < this.scanner.currentPosition){
+		this.pushIdentifier();
+
+		int index = -1;
+		/* check if current awaiting identifier is the completion identifier */
+		if ((index = this.indexOfAssistIdentifier()) > -1) {
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			/* filter out cases where scanner is still inside type header */
+			if (!recoveredType.foundOpeningBrace) {
+				TypeDeclaration type = recoveredType.typeDeclaration;
+				if(type.superInterfaces == null) {
+					type.superclass = new CompletionOnKeyword1(
+						this.identifierStack[ptr],
+						this.identifierPositionStack[ptr],
+						Keywords.IMPLEMENTS);
+					type.superclass.bits |= ASTNode.IsSuperType;
+					this.assistNode = type.superclass;
+					this.lastCheckPoint = type.superclass.sourceEnd + 1;
+				}
+			}
+		}
+	}
+}
+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();
+	popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.Parser#consumeCompilationUnit()
+ */
+protected void consumeCompilationUnit() {
+	this.javadoc = null;
+	checkComment();
+	if (this.javadoc != null && this.cursorLocation > this.javadoc.sourceStart && this.cursorLocation < this.javadoc.sourceEnd) {
+		// completion is in an orphan javadoc comment => replace compilation unit one to allow completion resolution
+		this.compilationUnit.javadoc = this.javadoc;
+		// create a fake interface declaration to allow resolution
+		if (this.compilationUnit.types == null) {
+			this.compilationUnit.types = new TypeDeclaration[1];
+			TypeDeclaration declaration = new TypeDeclaration(this.compilationUnit.compilationResult);
+			declaration.name = FAKE_TYPE_NAME;
+			declaration.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccInterface;
+			this.compilationUnit.types[0] = declaration;
+		}
+	}
+	super.consumeCompilationUnit();
+}
+protected void consumeConditionalExpression(int op) {
+	popElement(K_CONDITIONAL_OPERATOR);
+	super.consumeConditionalExpression(op);
+}
+protected void consumeConditionalExpressionWithName(int op) {
+	popElement(K_CONDITIONAL_OPERATOR);
+	super.consumeConditionalExpressionWithName(op);
+}
+protected void consumeConstructorBody() {
+	popElement(K_BLOCK_DELIMITER);
+	super.consumeConstructorBody();
+}
+protected void consumeConstructorHeader() {
+	super.consumeConstructorHeader();
+	pushOnElementStack(K_BLOCK_DELIMITER);
+}
+protected void consumeConstructorHeaderName() {
+
+	/* no need to take action if not inside assist identifiers */
+	if (indexOfAssistIdentifier() < 0) {
+		long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+		int selectorSourceEnd = (int) selectorSourcePositions;
+		int currentAstPtr = this.astPtr;
+		/* recovering - might be an empty message send */
+		if (this.currentElement != null && this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
+			super.consumeConstructorHeaderName();
+		} else {
+			super.consumeConstructorHeaderName();
+			if (this.pendingAnnotation != null) {
+				this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+				this.pendingAnnotation = null;
+			}
+		}
+		if (this.sourceEnds != null && this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+			this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+		}
+		return;
+	}
+
+	/* force to start recovering in order to get fake field behavior */
+	if (this.currentElement == null){
+		this.hasReportedError = true; // do not report any error
+	}
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0); // handle type arguments
+	this.restartRecovery = true;
+}
+protected void consumeConstructorHeaderNameWithTypeParameters() {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	if (this.currentElement != null && this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
+		super.consumeConstructorHeaderNameWithTypeParameters();
+	} else {
+		super.consumeConstructorHeaderNameWithTypeParameters();
+		if (this.pendingAnnotation != null) {
+			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+			this.pendingAnnotation = null;
+		}
+	}
+	if (this.sourceEnds != null && this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+	}
+}
+protected void consumeDefaultLabel() {
+	super.consumeDefaultLabel();
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SWITCH_LABEL) {
+		popElement(K_SWITCH_LABEL);
+	}
+	pushOnElementStack(K_SWITCH_LABEL, DEFAULT);
+}
+protected void consumeDimWithOrWithOutExpr() {
+	// DimWithOrWithOutExpr ::= '[' ']'
+	pushOnExpressionStack(null);
+}
+protected void consumeEnhancedForStatement() {
+	super.consumeEnhancedForStatement();
+
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+		popElement(K_CONTROL_STATEMENT_DELIMITER);
+	}
+}
+protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
+	super.consumeEnhancedForStatementHeaderInit(hasModifiers);
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeEnterAnonymousClassBody(boolean qualified) {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeEnterAnonymousClassBody(qualified);
+}
+protected void consumeEnterVariable() {
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+
+	boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
+	int variableIndex = this.variablesCounter[this.nestedType];
+
+	this.hasUnusedModifiers = false;
+
+	if(isLocalDeclaration || indexOfAssistIdentifier() < 0 || variableIndex != 0) {
+		this.identifierPtr++;
+		this.identifierLengthPtr++;
+
+		if (this.pendingAnnotation != null &&
+				this.assistNode != null &&
+				this.currentElement != null &&
+				this.currentElement instanceof RecoveredMethod &&
+				!this.currentElement.foundOpeningBrace &&
+				((RecoveredMethod)this.currentElement).methodDeclaration.declarationSourceEnd == 0) {
+			// this is a method parameter
+			super.consumeEnterVariable();
+			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+			this.pendingAnnotation.isParameter = true;
+			this.pendingAnnotation = null;
+
+		} else {
+			super.consumeEnterVariable();
+			if (this.pendingAnnotation != null) {
+				this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+				this.pendingAnnotation = null;
+			}
+		}
+	} else {
+		this.restartRecovery = true;
+
+		// recovery
+		if (this.currentElement != null) {
+			if(!checkKeyword() && !(this.currentElement instanceof RecoveredUnit && ((RecoveredUnit)this.currentElement).typeCount == 0)) {
+				int nameSourceStart = (int)(this.identifierPositionStack[this.identifierPtr] >>> 32);
+				this.intPtr--;
+				TypeReference type = getTypeReference(this.intStack[this.intPtr--]);
+				this.intPtr--;
+
+				if (!(this.currentElement instanceof RecoveredType)
+					&& (this.currentToken == TokenNameDOT
+						|| (Util.getLineNumber(type.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+								!= Util.getLineNumber(nameSourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)))){
+					this.lastCheckPoint = nameSourceStart;
+					this.restartRecovery = true;
+					return;
+				}
+
+				FieldDeclaration completionFieldDecl = new CompletionOnFieldType(type, false);
+				// consume annotations
+				int length;
+				if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+					System.arraycopy(
+						this.expressionStack,
+						(this.expressionPtr -= length) + 1,
+						completionFieldDecl.annotations = new Annotation[length],
+						0,
+						length);
+				}
+				completionFieldDecl.modifiers = this.intStack[this.intPtr--];
+				this.assistNode = completionFieldDecl;
+				this.lastCheckPoint = type.sourceEnd + 1;
+				this.currentElement = this.currentElement.add(completionFieldDecl, 0);
+				this.lastIgnoredToken = -1;
+			}
+		}
+	}
+}
+protected void consumeEnumConstantHeaderName() {
+	if (this.currentElement != null) {
+		if (!(this.currentElement instanceof RecoveredType
+					|| (this.currentElement instanceof RecoveredField && ((RecoveredField)this.currentElement).fieldDeclaration.type == null))
+				|| (this.lastIgnoredToken == TokenNameDOT)) {
+			super.consumeEnumConstantHeaderName();
+			return;
+		}
+	}
+	super.consumeEnumConstantHeaderName();
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeEnumConstantNoClassBody() {
+	super.consumeEnumConstantNoClassBody();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		if (this.sourceEnds != null) {
+			this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		}
+	}
+}
+protected void consumeEnumConstantWithClassBody() {
+	super.consumeEnumConstantWithClassBody();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		if (this.sourceEnds != null) {
+			this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		}
+	}
+}
+protected void consumeEnumHeaderName() {
+	super.consumeEnumHeaderName();
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeEnumHeaderNameWithTypeParameters() {
+	super.consumeEnumHeaderNameWithTypeParameters();
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeEqualityExpression(int op) {
+	super.consumeEqualityExpression(op);
+	popElement(K_BINARY_OPERATOR);
+
+	BinaryExpression exp = (BinaryExpression) this.expressionStack[this.expressionPtr];
+	if(this.assistNode != null && exp.right == this.assistNode) {
+		this.assistNodeParent = exp;
+	}
+}
+protected void consumeEqualityExpressionWithName(int op) {
+	super.consumeEqualityExpressionWithName(op);
+	popElement(K_BINARY_OPERATOR);
+
+	BinaryExpression exp = (BinaryExpression) this.expressionStack[this.expressionPtr];
+	if(this.assistNode != null && exp.right == this.assistNode) {
+		this.assistNodeParent = exp;
+	}
+}
+protected void consumeExitVariableWithInitialization() {
+	super.consumeExitVariableWithInitialization();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		if (this.sourceEnds != null) {
+			this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		}
+	}
+
+	// does not keep the initialization if completion is not inside
+	AbstractVariableDeclaration variable = (AbstractVariableDeclaration) this.astStack[this.astPtr];
+	if (this.cursorLocation + 1 < variable.initialization.sourceStart ||
+		this.cursorLocation > variable.initialization.sourceEnd) {
+		variable.initialization = null;
+	} else if (this.assistNode != null && this.assistNode == variable.initialization) {
+		this.assistNodeParent = variable;
+	}
+}
+protected void consumeExitVariableWithoutInitialization() {
+	// ExitVariableWithoutInitialization ::= $empty
+	// do nothing by default
+	super.consumeExitVariableWithoutInitialization();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		if (this.sourceEnds != null) {
+			this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		}
+	}
+}
+protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeExplicitConstructorInvocation(flag, recFlag);
+}
+/*
+ * Copy of code from superclass with the following change:
+ * If the cursor location is on the field access, then create a
+ * CompletionOnMemberAccess instead.
+ */
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	// FieldAccess ::= Primary '.' 'Identifier'
+	// FieldAccess ::= 'super' '.' 'Identifier'
+
+	// potential receiver is being poped, so reset potential receiver
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeFieldAccess(isSuperAccess);
+	} else {
+		pushCompletionOnMemberAccessOnExpressionStack(isSuperAccess);
+	}
+}
+protected void consumeForceNoDiet() {
+	super.consumeForceNoDiet();
+	if (isInsideMethod()) {
+		pushOnElementStack(K_LOCAL_INITIALIZER_DELIMITER);
+	}
+}
+protected void consumeFormalParameter(boolean isVarArgs) {
+	
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+	
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeFormalParameter(isVarArgs);
+		if (this.pendingAnnotation != null) {
+			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+			this.pendingAnnotation = null;
+		}
+	} else {
+		boolean isReceiver = this.intStack[this.intPtr--] == 0;
+	    if (isReceiver) {
+	    	this.expressionPtr--;
+	    	this.expressionLengthPtr --;
+	    }
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		int extendedDimensions = this.intStack[this.intPtr--];
+		Annotation [][] annotationsOnExtendedDimensions = extendedDimensions == 0 ? null : getAnnotationsOnDimensions(extendedDimensions);
+		Annotation [] varArgsAnnotations = null;
+		int length;
+		int endOfEllipsis = 0;
+		if (isVarArgs) {
+			endOfEllipsis = this.intStack[this.intPtr--];
+			if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+				System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					varArgsAnnotations = new Annotation[length],
+					0,
+					length);
+			} 
+		}
+		int firstDimensions = this.intStack[this.intPtr--];
+		TypeReference type = getTypeReference(firstDimensions);
+		
+		final int typeDimensions = firstDimensions + extendedDimensions + (isVarArgs ? 1 : 0);
+		if (typeDimensions != firstDimensions) {
+			// jsr308 type annotations management
+			Annotation [][] annotationsOnFirstDimensions = firstDimensions == 0 ? null : type.getAnnotationsOnDimensions();
+			Annotation [][] annotationsOnAllDimensions = annotationsOnFirstDimensions;
+			if (annotationsOnExtendedDimensions != null) {
+				annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions, annotationsOnFirstDimensions, extendedDimensions, annotationsOnExtendedDimensions);
+			}
+			if (varArgsAnnotations != null) {
+				annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions + extendedDimensions, annotationsOnAllDimensions, 1, new Annotation[][]{varArgsAnnotations});
+			}
+			type = copyDims(type, typeDimensions, annotationsOnAllDimensions);
+			type.sourceEnd = type.isParameterizedTypeReference() ? this.endStatementPosition : this.endPosition;
+		}
+		if (isVarArgs) {
+			if (extendedDimensions == 0) {
+				type.sourceEnd = endOfEllipsis;
+			}
+			type.bits |= ASTNode.IsVarArgs; // set isVarArgs
+		}
+		this.intPtr -= 2;
+		CompletionOnArgumentName arg =
+			new CompletionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		// consume annotations
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+			RecoveredType currentRecoveryType = this.currentRecoveryType();
+			if (currentRecoveryType != null)
+				currentRecoveryType.annotationsConsumed(arg.annotations);
+		}
+
+		arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN;
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
+protected void consumeGenericTypeWithDiamond() {
+	super.consumeGenericTypeWithDiamond();
+	// we need to pop the <> of the diamond from the stack.
+	// This is not required in usual case when the type argument isn't elided
+	// since the < and > get popped while parsing the type argument. 
+	popElement(K_BINARY_OPERATOR); // pop >
+	popElement(K_BINARY_OPERATOR); // pop <
+}
+protected void consumeStatementFor() {
+	super.consumeStatementFor();
+
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+		popElement(K_CONTROL_STATEMENT_DELIMITER);
+	}
+}
+protected void consumeStatementIfNoElse() {
+	super.consumeStatementIfNoElse();
+
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+		popElement(K_CONTROL_STATEMENT_DELIMITER);
+	}
+}
+protected void consumeStatementIfWithElse() {
+	super.consumeStatementIfWithElse();
+
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+		popElement(K_CONTROL_STATEMENT_DELIMITER);
+	}
+}
+protected void consumeInsideCastExpression() {
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+	
+	int end = this.intStack[this.intPtr--];
+	boolean isParameterized =(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST);
+	if(isParameterized) {
+		popElement(K_PARAMETERIZED_CAST);
+
+		if(this.identifierLengthStack[this.identifierLengthPtr] > 0) {
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+		}
+	} else {
+		if(this.identifierLengthStack[this.identifierLengthPtr] > 0) {
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+			pushOnGenericsLengthStack(0);
+		}
+	}
+	Expression castType = getTypeReference(this.intStack[this.intPtr--]);
+	if (additionalBoundsLength > 0) {
+		bounds[0] = getTypeReference(this.intStack[this.intPtr--]);
+		castType = createIntersectionCastTypeReference(bounds); 
+	}
+	if(isParameterized) {
+		this.intPtr--;
+	}
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = this.intStack[this.intPtr--] + 1;
+	pushOnExpressionStack(castType);
+
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionLL1() {
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST) {
+		popElement(K_PARAMETERIZED_CAST);
+	}
+	if (!this.record) {
+		super.consumeInsideCastExpressionLL1();
+	} else {
+		boolean temp = this.skipRecord;
+		try {
+			this.skipRecord = true;
+			super.consumeInsideCastExpressionLL1();
+			if (this.record) {
+				Expression typeReference = this.expressionStack[this.expressionPtr];
+				if (!isAlreadyPotentialName(typeReference.sourceStart)) {
+					addPotentialName(null, typeReference.sourceStart, typeReference.sourceEnd);
+				}
+			}
+		} finally {
+			this.skipRecord = temp;
+		}
+	}
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionLL1WithBounds() {
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST) {
+		popElement(K_PARAMETERIZED_CAST);
+	}
+	if (!this.record) {
+		super.consumeInsideCastExpressionLL1WithBounds();
+	} else {
+		boolean temp = this.skipRecord;
+		try {
+			this.skipRecord = true;
+			super.consumeInsideCastExpressionLL1WithBounds();
+			if (this.record) {
+				Expression typeReference = this.expressionStack[this.expressionPtr];
+				if (!isAlreadyPotentialName(typeReference.sourceStart)) {
+					addPotentialName(null, typeReference.sourceStart, typeReference.sourceEnd);
+				}
+			}
+		} finally {
+			this.skipRecord = temp;
+		}
+	}
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionWithQualifiedGenerics() {
+	popElement(K_PARAMETERIZED_CAST);
+
+	Expression castType;
+	int end = this.intStack[this.intPtr--];
+
+	int dim = this.intStack[this.intPtr--];
+	Annotation[][] annotationsOnDimensions = dim == 0 ? null : getAnnotationsOnDimensions(dim);
+	
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+	
+	TypeReference rightSide = getTypeReference(0);
+
+	castType = computeQualifiedGenericsFromRightSide(rightSide, dim, annotationsOnDimensions);
+	if (additionalBoundsLength > 0) {
+		bounds[0] = (TypeReference) castType;
+		castType = createIntersectionCastTypeReference(bounds); 
+	} 
+	this.intPtr--;
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = this.intStack[this.intPtr--] + 1;
+	pushOnExpressionStack(castType);
+
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInstanceOfExpression() {
+	super.consumeInstanceOfExpression();
+	popElement(K_BINARY_OPERATOR);
+	// to handle https://bugs.eclipse.org/bugs/show_bug.cgi?id=261534
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_IF_AND_RIGHT_PAREN) {
+		pushOnElementStack(K_BETWEEN_INSTANCEOF_AND_RPAREN, IF, this.expressionStack[this.expressionPtr]);
+	}
+
+	InstanceOfExpression exp = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
+	if(this.assistNode != null && exp.type == this.assistNode) {
+		this.assistNodeParent = exp;
+	}
+}
+protected void consumeInstanceOfExpressionWithName() {
+	super.consumeInstanceOfExpressionWithName();
+	popElement(K_BINARY_OPERATOR);
+
+	InstanceOfExpression exp = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
+	if(this.assistNode != null && exp.type == this.assistNode) {
+		this.assistNodeParent = exp;
+	}
+}
+protected void consumeInterfaceHeaderName1() {
+	super.consumeInterfaceHeaderName1();
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+	classHeaderExtendsOrImplements(true);
+}
+protected void consumeInterfaceHeaderExtends() {
+	super.consumeInterfaceHeaderExtends();
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeInterfaceType() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_INTERFACE);
+	super.consumeInterfaceType();
+	popElement(K_NEXT_TYPEREF_IS_INTERFACE);
+}
+protected void consumeMethodInvocationName() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationName();
+}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationNameWithTypeArguments();
+}
+protected void consumeMethodInvocationPrimary() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationPrimary();
+}
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationPrimaryWithTypeArguments();
+}
+protected void consumeMethodInvocationSuper() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationSuper();
+}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	popElement(K_SELECTOR_QUALIFIER);
+	popElement(K_SELECTOR_INVOCATION_TYPE);
+	super.consumeMethodInvocationSuperWithTypeArguments();
+}
+protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
+	if(this.indexOfAssistIdentifier() < 0) {
+		this.identifierPtr--;
+		this.identifierLengthPtr--;
+		if(this.indexOfAssistIdentifier() != 0 ||
+			this.identifierLengthStack[this.identifierLengthPtr] != this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr]) {
+			this.identifierPtr++;
+			this.identifierLengthPtr++;
+			long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+			int selectorSourceEnd = (int) selectorSourcePositions;
+			int currentAstPtr = this.astPtr;
+			super.consumeMethodHeaderName(isAnnotationMethod);
+			if (this.sourceEnds != null && this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+				this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+			}
+			if (this.pendingAnnotation != null) {
+				this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+				this.pendingAnnotation = null;
+			}
+		} else {
+			this.restartRecovery = true;
+
+			// recovery
+			if (this.currentElement != null) {
+				//name
+				char[] selector = this.identifierStack[this.identifierPtr + 1];
+				long selectorSource = this.identifierPositionStack[this.identifierPtr + 1];
+
+				//type
+				TypeReference type = getTypeReference(this.intStack[this.intPtr--]);
+				((CompletionOnSingleTypeReference)type).isCompletionNode = false;
+				//modifiers
+				int declarationSourceStart = this.intStack[this.intPtr--];
+				int mod = this.intStack[this.intPtr--];
+
+				if(Util.getLineNumber(type.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						!= Util.getLineNumber((int) (selectorSource >>> 32), this.scanner.lineEnds, 0, this.scanner.linePtr)) {
+					FieldDeclaration completionFieldDecl = new CompletionOnFieldType(type, false);
+					// consume annotations
+					int length;
+					if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+						System.arraycopy(
+							this.expressionStack,
+							(this.expressionPtr -= length) + 1,
+							completionFieldDecl.annotations = new Annotation[length],
+							0,
+							length);
+					}
+					completionFieldDecl.modifiers = mod;
+					this.assistNode = completionFieldDecl;
+					this.lastCheckPoint = type.sourceEnd + 1;
+					this.currentElement = this.currentElement.add(completionFieldDecl, 0);
+					this.lastIgnoredToken = -1;
+				} else {
+					CompletionOnMethodReturnType md = new CompletionOnMethodReturnType(type, this.compilationUnit.compilationResult);
+					// consume annotations
+					int length;
+					if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+						System.arraycopy(
+							this.expressionStack,
+							(this.expressionPtr -= length) + 1,
+							md.annotations = new Annotation[length],
+							0,
+							length);
+					}
+					md.selector = selector;
+					md.declarationSourceStart = declarationSourceStart;
+					md.modifiers = mod;
+					md.bodyStart = this.lParenPos+1;
+					this.listLength = 0; // initialize listLength before reading parameters/throws
+					this.assistNode = md;
+					this.lastCheckPoint = md.bodyStart;
+					this.currentElement = this.currentElement.add(md, 0);
+					this.lastIgnoredToken = -1;
+					// javadoc
+					md.javadoc = this.javadoc;
+					this.javadoc = null;
+				}
+			}
+		}
+	} else {
+		// MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+		CompletionOnMethodName md = new CompletionOnMethodName(this.compilationUnit.compilationResult);
+
+		//name
+		md.selector = this.identifierStack[this.identifierPtr];
+		long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+		this.identifierLengthPtr--;
+		//type
+		md.returnType = getTypeReference(this.intStack[this.intPtr--]);
+		//modifiers
+		md.declarationSourceStart = this.intStack[this.intPtr--];
+		md.modifiers = this.intStack[this.intPtr--];
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				md.annotations = new Annotation[length],
+				0,
+				length);
+		}
+		// javadoc
+		md.javadoc = this.javadoc;
+		this.javadoc = null;
+
+		//highlight starts at selector start
+		md.sourceStart = (int) (selectorSource >>> 32);
+		md.selectorEnd = (int) selectorSource;
+		pushOnAstStack(md);
+		md.sourceEnd = this.lParenPos;
+		md.bodyStart = this.lParenPos+1;
+		this.listLength = 0; // initialize listLength before reading parameters/throws
+
+		this.assistNode = md;
+		this.lastCheckPoint = md.sourceEnd;
+		// recovery
+		if (this.currentElement != null){
+			if (this.currentElement instanceof RecoveredType
+				//|| md.modifiers != 0
+				|| (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						== Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+				this.lastCheckPoint = md.bodyStart;
+				this.currentElement = this.currentElement.add(md, 0);
+				this.lastIgnoredToken = -1;
+			} else {
+				this.lastCheckPoint = md.sourceStart;
+				this.restartRecovery = true;
+			}
+		}
+	}
+}
+protected void consumeMethodHeaderNameWithTypeParameters( boolean isAnnotationMethod) {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	super.consumeMethodHeaderNameWithTypeParameters(isAnnotationMethod);
+	if (this.sourceEnds != null && this.astPtr > currentAstPtr) {// if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+	}
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeMethodHeaderRightParen() {
+	super.consumeMethodHeaderRightParen();
+
+	if (this.currentElement != null
+		&& this.currentToken == TokenNameIdentifier
+		&& this.cursorLocation+1 >= this.scanner.startPosition
+		&& this.cursorLocation < this.scanner.currentPosition){
+		this.pushIdentifier();
+
+		int index = -1;
+		/* check if current awaiting identifier is the completion identifier */
+		if ((index = this.indexOfAssistIdentifier()) > -1) {
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+			if (this.currentElement instanceof RecoveredMethod){
+				RecoveredMethod recoveredMethod = (RecoveredMethod)this.currentElement;
+				/* filter out cases where scanner is still inside type header */
+				if (!recoveredMethod.foundOpeningBrace) {
+					AbstractMethodDeclaration method = recoveredMethod.methodDeclaration;
+					if(method.thrownExceptions == null) {
+						CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+							this.identifierStack[ptr],
+							this.identifierPositionStack[ptr],
+							Keywords.THROWS);
+						method.thrownExceptions = new TypeReference[]{completionOnKeyword};
+						recoveredMethod.foundOpeningBrace = true;
+						this.assistNode = completionOnKeyword;
+						this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+					}
+				}
+			}
+		}
+	}
+}
+protected void consumeMethodHeaderExtendedDims() {
+	super.consumeMethodHeaderExtendedDims();
+
+	if (this.currentElement != null
+		&& this.currentToken == TokenNameIdentifier
+		&& this.cursorLocation+1 >= this.scanner.startPosition
+		&& this.cursorLocation < this.scanner.currentPosition){
+		this.pushIdentifier();
+
+		int index = -1;
+		/* check if current awaiting identifier is the completion identifier */
+		if ((index = this.indexOfAssistIdentifier()) > -1) {
+			int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+			RecoveredMethod recoveredMethod = (RecoveredMethod)this.currentElement;
+			/* filter out cases where scanner is still inside type header */
+			if (!recoveredMethod.foundOpeningBrace) {
+				AbstractMethodDeclaration method = recoveredMethod.methodDeclaration;
+				if(method.thrownExceptions == null) {
+					CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+						this.identifierStack[ptr],
+						this.identifierPositionStack[ptr],
+						Keywords.THROWS);
+					method.thrownExceptions = new TypeReference[]{completionOnKeyword};
+					recoveredMethod.foundOpeningBrace = true;
+					this.assistNode = completionOnKeyword;
+					this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+				}
+			}
+		}
+	}
+}
+protected void consumeAnnotationAsModifier() {
+	super.consumeAnnotationAsModifier();
+
+	if (isInsideMethod()) {
+		this.hasUnusedModifiers = true;
+	}
+}
+protected void consumeAdditionalBound() {
+	super.consumeAdditionalBound();
+	ASTNode node = this.genericsStack[this.genericsPtr];
+	if (node instanceof CompletionOnSingleTypeReference) {
+		((CompletionOnSingleTypeReference) node).setKind(CompletionOnQualifiedTypeReference.K_INTERFACE);
+	} else if (node instanceof CompletionOnQualifiedTypeReference) {
+		((CompletionOnQualifiedTypeReference) node).setKind(CompletionOnQualifiedTypeReference.K_INTERFACE);
+	}
+}
+protected void consumeAdditionalBound1() {
+	super.consumeAdditionalBound1();
+	ASTNode node = this.genericsStack[this.genericsPtr];
+	if (node instanceof CompletionOnSingleTypeReference) {
+		((CompletionOnSingleTypeReference) node).setKind(CompletionOnQualifiedTypeReference.K_INTERFACE);
+	} else if (node instanceof CompletionOnQualifiedTypeReference) {
+		((CompletionOnQualifiedTypeReference) node).setKind(CompletionOnQualifiedTypeReference.K_INTERFACE);
+	}
+}
+protected void consumeAnnotationName() {
+	int index;
+
+	if ((index = this.indexOfAssistIdentifier()) < 0) {
+		super.consumeAnnotationName();
+		this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_NOT_CONSUMED);
+		return;
+	}
+
+	if (isInImportStatement()) {
+		return;
+	}
+	MarkerAnnotation markerAnnotation = null;
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	TypeReference typeReference;
+
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+
+	char[][] subset = identifierSubSet(index);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist on type reference */
+
+	if (index == 0) {
+		/* assist inside first identifier */
+		typeReference = createSingleAssistTypeReference(
+						assistIdentifier(),
+						positions[0]);
+	} else {
+		/* assist inside subsequent identifier */
+		typeReference =	createQualifiedAssistTypeReference(
+						subset,
+						assistIdentifier(),
+						positions);
+	}
+
+	markerAnnotation = new CompletionOnMarkerAnnotationName(typeReference, typeReference.sourceStart);
+	this.intPtr--;
+	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
+	pushOnExpressionStack(markerAnnotation);
+
+	this.assistNode = markerAnnotation;
+	this.isOrphanCompletionNode = true;
+
+	this.lastCheckPoint = markerAnnotation.sourceEnd + 1;
+
+	this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_NOT_CONSUMED | ANNOTATION_NAME_COMPLETION);
+}
+protected void consumeAnnotationTypeDeclarationHeaderName() {
+	super.consumeAnnotationTypeDeclarationHeaderName();
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() {
+	super.consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters();
+	this.hasUnusedModifiers = false;
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumeLabel() {
+	super.consumeLabel();
+	pushOnLabelStack(this.identifierStack[this.identifierPtr]);
+	this.pushOnElementStack(K_LABEL, this.labelPtr);
+}
+protected void consumeMarkerAnnotation(boolean isTypeAnnotation) {
+	if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+			(this.topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) & ANNOTATION_NAME_COMPLETION) != 0 ) {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		this.restartRecovery = true;
+	} else {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		super.consumeMarkerAnnotation(isTypeAnnotation);
+	}
+}
+protected void consumeMemberValuePair() {
+	/* check if current awaiting identifier is the completion identifier */
+	if (this.indexOfAssistIdentifier() < 0){
+		super.consumeMemberValuePair();
+		MemberValuePair memberValuePair = (MemberValuePair) this.astStack[this.astPtr];
+		if(this.assistNode != null && memberValuePair.value == this.assistNode) {
+			this.assistNodeParent = memberValuePair;
+		}
+		return;
+	}
+
+	char[] simpleName = this.identifierStack[this.identifierPtr];
+	long position = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	int end = (int) position;
+	int start = (int) (position >>> 32);
+
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+
+	CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+	pushOnAstStack(memberValueName);
+	this.assistNode = memberValueName;
+	this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+	this.isOrphanCompletionNode = true;
+
+	this.restartRecovery = true;
+}
+protected void consumeMemberValueAsName() {
+	if ((indexOfAssistIdentifier()) < 0) {
+		super.consumeMemberValueAsName();
+	} else {
+		super.consumeMemberValueAsName();
+		if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+			this.restartRecovery = true;
+		}
+	}
+}
+protected void consumeMethodBody() {
+	popElement(K_BLOCK_DELIMITER);
+	super.consumeMethodBody();
+}
+protected void consumeMethodHeader() {
+	super.consumeMethodHeader();
+	pushOnElementStack(K_BLOCK_DELIMITER);
+}
+protected void consumeMethodDeclaration(boolean isNotAbstract) {
+	if (!isNotAbstract) {
+		popElement(K_BLOCK_DELIMITER);
+	}
+	super.consumeMethodDeclaration(isNotAbstract);
+}
+protected void consumeModifiers() {
+	super.consumeModifiers();
+	// save from stack values
+	this.lastModifiersStart = this.intStack[this.intPtr];
+	this.lastModifiers = 	this.intStack[this.intPtr-1];
+}
+protected void consumeReferenceType() {
+	if (this.identifierLengthStack[this.identifierLengthPtr] > 1) { // reducing a qualified name
+		// potential receiver is being poped, so reset potential receiver
+		this.invocationType = NO_RECEIVER;
+		this.qualifier = -1;
+	}
+	super.consumeReferenceType();
+}
+protected void consumeRestoreDiet() {
+	super.consumeRestoreDiet();
+	if (isInsideMethod()) {
+		popElement(K_LOCAL_INITIALIZER_DELIMITER);
+	}
+}
+protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) {
+	if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+			(this.topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) & ANNOTATION_NAME_COMPLETION) != 0 ) {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		this.restartRecovery = true;
+	} else {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		super.consumeSingleMemberAnnotation(isTypeAnnotation);
+	}
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	super.consumeSingleStaticImportDeclarationName();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeSingleTypeImportDeclarationName() {
+	super.consumeSingleTypeImportDeclarationName();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeStatementBreakWithLabel() {
+	super.consumeStatementBreakWithLabel();
+	if (this.record) {
+		ASTNode breakStatement = this.astStack[this.astPtr];
+		if (!isAlreadyPotentialName(breakStatement.sourceStart)) {
+			addPotentialName(null, breakStatement.sourceStart, breakStatement.sourceEnd);
+		}
+	}
+
+}
+protected void consumeStatementLabel() {
+	popElement(K_LABEL);
+	super.consumeStatementLabel();
+}
+protected void consumeStatementSwitch() {
+	super.consumeStatementSwitch();
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SWITCH_LABEL) {
+		popElement(K_SWITCH_LABEL);
+		popElement(K_BLOCK_DELIMITER);
+	}
+}
+protected void consumeStatementWhile() {
+	super.consumeStatementWhile();
+	if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+		popElement(K_CONTROL_STATEMENT_DELIMITER);
+	}
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	super.consumeStaticImportOnDemandDeclarationName();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeStaticInitializer() {
+	super.consumeStaticInitializer();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeNestedMethod() {
+	super.consumeNestedMethod();
+	if(!(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BLOCK_DELIMITER)) pushOnElementStack(K_BLOCK_DELIMITER);
+}
+protected void consumeNormalAnnotation(boolean isTypeAnnotation) {
+	if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+			(this.topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) & ANNOTATION_NAME_COMPLETION) != 0 ) {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		this.restartRecovery = true;
+	} else {
+		popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+		super.consumeNormalAnnotation(isTypeAnnotation);
+	}
+}
+protected void consumePackageDeclarationName() {
+	super.consumePackageDeclarationName();
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.compilationUnit.currentPackage;
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumePackageDeclarationNameWithModifiers() {
+	super.consumePackageDeclarationNameWithModifiers();
+	if (this.pendingAnnotation != null) {
+		this.pendingAnnotation.potentialAnnotatedNode = this.compilationUnit.currentPackage;
+		this.pendingAnnotation = null;
+	}
+}
+protected void consumePrimaryNoNewArrayName() {
+	// this is class literal access, so reset potential receiver
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+
+	super.consumePrimaryNoNewArrayName();
+}
+protected void consumePrimaryNoNewArrayNameSuper() {
+	// this is class literal access, so reset potential receiver
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+
+	super.consumePrimaryNoNewArrayNameSuper();
+}
+protected void consumePrimaryNoNewArrayNameThis() {
+	// this is class literal access, so reset potential receiver
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+
+	super.consumePrimaryNoNewArrayNameThis();
+}
+protected void consumePushPosition() {
+	super.consumePushPosition();
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BINARY_OPERATOR) {
+		int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+		popElement(K_BINARY_OPERATOR);
+		pushOnElementStack(K_UNARY_OPERATOR, info);
+	}
+}
+protected void consumeToken(int token) {
+	if(this.isFirst) {
+		super.consumeToken(token);
+		return;
+	}
+	if(this.canBeExplicitConstructor == NEXTTOKEN) {
+		this.canBeExplicitConstructor = YES;
+	} else {
+		this.canBeExplicitConstructor = NO;
+	}
+
+	int previous = this.previousToken;
+	int prevIdentifierPtr = this.previousIdentifierPtr;
+
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAnnotation()) {
+		switch(token) {
+			case TokenNameLPAREN:
+				if(previous == TokenNameIdentifier &&
+						topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_METHOD_INVOCATION) {
+					popElement(K_PARAMETERIZED_METHOD_INVOCATION);
+				} else {
+					popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
+				}
+				break;
+			case TokenNameLBRACE:
+				popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
+				break;
+			case TokenNameLBRACKET:
+				if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_NEW_AND_LEFT_BRACKET) {
+					popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
+					pushOnElementStack(K_ARRAY_CREATION);
+				}
+				break;
+			case TokenNameRBRACE:
+				int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+				switch (kind) {
+					case K_BLOCK_DELIMITER:
+						popElement(K_BLOCK_DELIMITER);
+						break;
+					case K_MEMBER_VALUE_ARRAY_INITIALIZER:
+						popElement(K_MEMBER_VALUE_ARRAY_INITIALIZER);
+						break;
+					default:
+						popElement(K_ARRAY_INITIALIZER);
+						break;
+				}
+				break;
+			case TokenNameRBRACKET:
+				if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_LEFT_AND_RIGHT_BRACKET) {
+					popElement(K_BETWEEN_LEFT_AND_RIGHT_BRACKET);
+				}
+				break;
+
+		}
+	}
+	super.consumeToken(token);
+
+	// if in field initializer (directly or not), on the completion identifier and not in recovery mode yet
+	// then position end of file at cursor location (so that we have the same behavior as
+	// in method bodies)
+	if (token == TokenNameIdentifier
+			&& this.identifierStack[this.identifierPtr] == assistIdentifier()
+			&& this.currentElement == null
+			&& isIndirectlyInsideFieldInitialization()) {
+		this.scanner.eofPosition = this.cursorLocation < Integer.MAX_VALUE ? this.cursorLocation+1 : this.cursorLocation;
+	}
+	if (token == TokenNameimport) {
+		pushOnElementStack(K_INSIDE_IMPORT_STATEMENT);
+	}
+
+	// if in a method or if in a field initializer
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue()) {
+		switch (token) {
+			case TokenNameDOT:
+				switch (previous) {
+					case TokenNamethis: // e.g. this[.]fred()
+						this.invocationType = EXPLICIT_RECEIVER;
+						break;
+					case TokenNamesuper: // e.g. super[.]fred()
+						this.invocationType = SUPER_RECEIVER;
+						break;
+					case TokenNameIdentifier: // e.g. bar[.]fred()
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_BETWEEN_NEW_AND_LEFT_BRACKET) {
+							if (this.identifierPtr != prevIdentifierPtr) { // if identifier has been consumed, e.g. this.x[.]fred()
+								this.invocationType = EXPLICIT_RECEIVER;
+							} else {
+								this.invocationType = NAME_RECEIVER;
+							}
+						}
+						break;
+				}
+				break;
+			case TokenNameCOLON_COLON:
+				this.inReferenceExpression = true;
+				break;
+			case TokenNameIdentifier:
+				if (this.inReferenceExpression)
+					break;
+				if (previous == TokenNameDOT) { // e.g. foo().[fred]()
+					if (this.invocationType != SUPER_RECEIVER // e.g. not super.[fred]()
+						&& this.invocationType != NAME_RECEIVER // e.g. not bar.[fred]()
+						&& this.invocationType != ALLOCATION // e.g. not new foo.[Bar]()
+						&& this.invocationType != QUALIFIED_ALLOCATION) { // e.g. not fred().new foo.[Bar]()
+
+						this.invocationType = EXPLICIT_RECEIVER;
+						this.qualifier = this.expressionPtr;
+					}
+				}
+				if (previous == TokenNameGREATER) { // e.g. foo().<X>[fred]()
+					if (this.invocationType != SUPER_RECEIVER // e.g. not super.<X>[fred]()
+						&& this.invocationType != NAME_RECEIVER // e.g. not bar.<X>[fred]()
+						&& this.invocationType != ALLOCATION // e.g. not new foo.<X>[Bar]()
+						&& this.invocationType != QUALIFIED_ALLOCATION) { // e.g. not fred().new foo.<X>[Bar]()
+
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_METHOD_INVOCATION) {
+							this.invocationType = EXPLICIT_RECEIVER;
+							this.qualifier = this.expressionPtr;
+						}
+					}
+				}
+				break;
+			case TokenNamenew:
+				if (this.inReferenceExpression)
+					break;
+				pushOnElementStack(K_BETWEEN_NEW_AND_LEFT_BRACKET);
+				this.qualifier = this.expressionPtr; // NB: even if there is no qualification, set it to the expression ptr so that the number of arguments are correctly computed
+				if (previous == TokenNameDOT) { // e.g. fred().[new] X()
+					this.invocationType = QUALIFIED_ALLOCATION;
+				} else { // e.g. [new] X()
+					this.invocationType = ALLOCATION;
+				}
+				break;
+			case TokenNamethis:
+				if (previous == TokenNameDOT) { // e.g. fred().[this]()
+					this.invocationType = QUALIFIED_ALLOCATION;
+					this.qualifier = this.expressionPtr;
+				}
+				break;
+			case TokenNamesuper:
+				if (previous == TokenNameDOT) { // e.g. fred().[super]()
+					this.invocationType = QUALIFIED_ALLOCATION;
+					this.qualifier = this.expressionPtr;
+				}
+				break;
+			case TokenNamecatch:
+				pushOnElementStack(K_BETWEEN_CATCH_AND_RIGHT_PAREN);
+				break;
+			case TokenNameLPAREN:
+				if (this.invocationType == NO_RECEIVER || this.invocationType == NAME_RECEIVER || this.invocationType == SUPER_RECEIVER) {
+					this.qualifier = this.expressionPtr; // remenber the last expression so that arguments are correctly computed
+				}
+				switch (previous) {
+					case TokenNameIdentifier: // e.g. fred[(]) or foo.fred[(])
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
+							int info = 0;
+							if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER,1) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+									(info=topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER,1) & LPAREN_NOT_CONSUMED) != 0) {
+								popElement(K_SELECTOR);
+								popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+								if ((info & ANNOTATION_NAME_COMPLETION) != 0) {
+									this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_CONSUMED | ANNOTATION_NAME_COMPLETION);
+								} else {
+									this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_CONSUMED);
+								}
+							} else {
+								this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, this.invocationType);
+								this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+							}
+						}
+						this.qualifier = -1;
+						this.invocationType = NO_RECEIVER;
+						break;
+					case TokenNamethis: // explicit constructor invocation, e.g. this[(]1, 2)
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
+							this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, (this.invocationType == QUALIFIED_ALLOCATION) ? QUALIFIED_ALLOCATION : ALLOCATION);
+							this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+						}
+						this.qualifier = -1;
+						this.invocationType = NO_RECEIVER;
+						break;
+					case TokenNamesuper: // explicit constructor invocation, e.g. super[(]1, 2)
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
+							this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, (this.invocationType == QUALIFIED_ALLOCATION) ? QUALIFIED_ALLOCATION : ALLOCATION);
+							this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+						}
+						this.qualifier = -1;
+						this.invocationType = NO_RECEIVER;
+						break;
+					case TokenNameGREATER: // explicit constructor invocation, e.g. Fred<X>[(]1, 2)
+					case TokenNameRIGHT_SHIFT: // or fred<X<X>>[(]1, 2)
+					case TokenNameUNSIGNED_RIGHT_SHIFT: //or Fred<X<X<X>>>[(]1, 2)
+						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
+							int info;
+							if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BINARY_OPERATOR &&
+									((info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER, 1)) == GREATER || info == RIGHT_SHIFT || info == UNSIGNED_RIGHT_SHIFT)) {
+								// it's not a selector invocation
+								popElement(K_SELECTOR);
+							} else {
+								this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, (this.invocationType == QUALIFIED_ALLOCATION) ? QUALIFIED_ALLOCATION : ALLOCATION);
+								this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+							}
+						}
+						this.qualifier = -1;
+						this.invocationType = NO_RECEIVER;
+						break;
+				}
+				break;
+			case TokenNameLBRACE:
+				int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+				if(kind == K_FIELD_INITIALIZER_DELIMITER
+					|| kind == K_LOCAL_INITIALIZER_DELIMITER
+					|| kind == K_ARRAY_CREATION) {
+					pushOnElementStack(K_ARRAY_INITIALIZER, this.endPosition);
+				} else if (kind == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+					pushOnElementStack(K_MEMBER_VALUE_ARRAY_INITIALIZER, this.endPosition);
+				} else {
+					if (kind == K_CONTROL_STATEMENT_DELIMITER) {
+						int info = topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER);
+						popElement(K_CONTROL_STATEMENT_DELIMITER);
+						if (info == IF) {
+							pushOnElementStack(K_BLOCK_DELIMITER, IF, this.expressionStack[this.expressionPtr]);
+						} else {
+							pushOnElementStack(K_BLOCK_DELIMITER, info);
+						}
+					} else {
+						switch(previous) {
+							case TokenNameRPAREN :
+								switch(this.previousKind) {
+									case K_BETWEEN_CATCH_AND_RIGHT_PAREN :
+										pushOnElementStack(K_BLOCK_DELIMITER, CATCH);
+										break;
+									case K_BETWEEN_SWITCH_AND_RIGHT_PAREN :
+										pushOnElementStack(K_BLOCK_DELIMITER, SWITCH);
+										break;
+									case K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN :
+										pushOnElementStack(K_BLOCK_DELIMITER, SYNCHRONIZED);
+										break;
+									default :
+										pushOnElementStack(K_BLOCK_DELIMITER);
+										break;
+								}
+								break;
+							case TokenNametry :
+								pushOnElementStack(K_BLOCK_DELIMITER, TRY);
+								break;
+							case TokenNamedo:
+								pushOnElementStack(K_BLOCK_DELIMITER, DO);
+								break;
+							default :
+								pushOnElementStack(K_BLOCK_DELIMITER);
+								break;
+						}
+					}
+				}
+				break;
+			case TokenNameLBRACKET:
+				if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_ARRAY_CREATION) {
+					pushOnElementStack(K_BETWEEN_LEFT_AND_RIGHT_BRACKET);
+				} else {
+					switch (previous) {
+						case TokenNameIdentifier:
+						case TokenNameboolean:
+						case TokenNamebyte:
+						case TokenNamechar:
+						case TokenNamedouble:
+						case TokenNamefloat:
+						case TokenNameint:
+						case TokenNamelong:
+						case TokenNameshort:
+						case TokenNameGREATER:
+						case TokenNameRIGHT_SHIFT:
+						case TokenNameUNSIGNED_RIGHT_SHIFT:
+							this.invocationType = NO_RECEIVER;
+							this.qualifier = -1;
+							break;
+					}
+				}
+				break;
+			case TokenNameRPAREN:
+				switch(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+					case K_BETWEEN_CATCH_AND_RIGHT_PAREN :
+						popElement(K_BETWEEN_CATCH_AND_RIGHT_PAREN);
+						break;
+					case K_BETWEEN_INSTANCEOF_AND_RPAREN :
+						popElement(K_BETWEEN_INSTANCEOF_AND_RPAREN);
+						//$FALL-THROUGH$
+					case K_BETWEEN_IF_AND_RIGHT_PAREN :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_BETWEEN_IF_AND_RIGHT_PAREN);
+							pushOnElementStack(K_CONTROL_STATEMENT_DELIMITER, IF, this.expressionStack[this.expressionPtr]);
+						}
+						break;
+					case K_BETWEEN_WHILE_AND_RIGHT_PAREN :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_BETWEEN_WHILE_AND_RIGHT_PAREN);
+							pushOnElementStack(K_CONTROL_STATEMENT_DELIMITER, WHILE);
+						}
+						break;
+					case K_BETWEEN_FOR_AND_RIGHT_PAREN :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_BETWEEN_FOR_AND_RIGHT_PAREN);
+							pushOnElementStack(K_CONTROL_STATEMENT_DELIMITER, FOR);
+						}
+						break;
+					case K_BETWEEN_SWITCH_AND_RIGHT_PAREN :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_BETWEEN_SWITCH_AND_RIGHT_PAREN);
+						}
+						break;
+					case K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN);
+						}
+						break;
+				}
+				break;
+			case TokenNamethrow:
+				pushOnElementStack(K_INSIDE_THROW_STATEMENT, this.bracketDepth);
+				break;
+			case TokenNameSEMICOLON:
+				switch(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+					case K_INSIDE_THROW_STATEMENT :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_THROW_STATEMENT);
+						}
+						break;
+					case K_INSIDE_RETURN_STATEMENT :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_RETURN_STATEMENT);
+						}
+						break;
+					case K_INSIDE_ASSERT_STATEMENT :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_ASSERT_STATEMENT);
+						}
+						break;
+					case K_INSIDE_ASSERT_EXCEPTION :
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_ASSERT_EXCEPTION);
+							popElement(K_INSIDE_ASSERT_STATEMENT);
+						}
+						break;
+					case K_INSIDE_BREAK_STATEMENT:
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_BREAK_STATEMENT);
+						}
+						break;
+					case K_INSIDE_CONTINUE_STATEMENT:
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_CONTINUE_STATEMENT);
+						}
+						break;
+					case K_BETWEEN_FOR_AND_RIGHT_PAREN:
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth - 1) {
+							popElement(K_BETWEEN_FOR_AND_RIGHT_PAREN);
+							pushOnElementStack(K_INSIDE_FOR_CONDITIONAL, this.bracketDepth - 1);
+						}
+						break;
+					case K_INSIDE_FOR_CONDITIONAL:
+						if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == this.bracketDepth - 1) {
+							popElement(K_INSIDE_FOR_CONDITIONAL);
+							pushOnElementStack(K_BETWEEN_FOR_AND_RIGHT_PAREN, this.bracketDepth - 1);
+						}
+						break;
+				}
+				break;
+			case TokenNamereturn:
+				pushOnElementStack(K_INSIDE_RETURN_STATEMENT, this.bracketDepth);
+				break;
+			case TokenNameMULTIPLY:
+				pushOnElementStack(K_BINARY_OPERATOR, MULTIPLY);
+				break;
+			case TokenNameDIVIDE:
+				pushOnElementStack(K_BINARY_OPERATOR, DIVIDE);
+				break;
+			case TokenNameREMAINDER:
+				pushOnElementStack(K_BINARY_OPERATOR, REMAINDER);
+				break;
+			case TokenNamePLUS:
+				pushOnElementStack(K_BINARY_OPERATOR, PLUS);
+				break;
+			case TokenNameMINUS:
+				pushOnElementStack(K_BINARY_OPERATOR, MINUS);
+				break;
+			case TokenNameLEFT_SHIFT:
+				pushOnElementStack(K_BINARY_OPERATOR, LEFT_SHIFT);
+				break;
+			case TokenNameRIGHT_SHIFT:
+				pushOnElementStack(K_BINARY_OPERATOR, RIGHT_SHIFT);
+				break;
+			case TokenNameUNSIGNED_RIGHT_SHIFT:
+				pushOnElementStack(K_BINARY_OPERATOR, UNSIGNED_RIGHT_SHIFT);
+				break;
+			case TokenNameLESS:
+				switch(previous) {
+					case TokenNameDOT :
+						pushOnElementStack(K_PARAMETERIZED_METHOD_INVOCATION);
+						break;
+					case TokenNamenew :
+						pushOnElementStack(K_PARAMETERIZED_ALLOCATION);
+						break;
+				}
+				pushOnElementStack(K_BINARY_OPERATOR, LESS);
+				break;
+			case TokenNameGREATER:
+				pushOnElementStack(K_BINARY_OPERATOR, GREATER);
+				break;
+			case TokenNameLESS_EQUAL:
+				pushOnElementStack(K_BINARY_OPERATOR, LESS_EQUAL);
+				break;
+			case TokenNameGREATER_EQUAL:
+				pushOnElementStack(K_BINARY_OPERATOR, GREATER_EQUAL);
+				break;
+			case TokenNameAND:
+				pushOnElementStack(K_BINARY_OPERATOR, AND);
+				break;
+			case TokenNameXOR:
+				pushOnElementStack(K_BINARY_OPERATOR, XOR);
+				break;
+			case TokenNameOR:
+				// Don't push the OR operator used for union types in a catch declaration
+				if (topKnownElementKind(COMPLETION_PARSER) != K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+					pushOnElementStack(K_BINARY_OPERATOR, OR);
+				break;
+			case TokenNameAND_AND:
+				pushOnElementStack(K_BINARY_OPERATOR, AND_AND);
+				break;
+			case TokenNameOR_OR:
+				pushOnElementStack(K_BINARY_OPERATOR, OR_OR);
+				break;
+			case TokenNamePLUS_PLUS:
+				pushOnElementStack(K_UNARY_OPERATOR, PLUS_PLUS);
+				break;
+			case TokenNameMINUS_MINUS:
+				pushOnElementStack(K_UNARY_OPERATOR, MINUS_MINUS);
+				break;
+			case TokenNameTWIDDLE:
+				pushOnElementStack(K_UNARY_OPERATOR, TWIDDLE);
+				break;
+			case TokenNameNOT:
+				pushOnElementStack(K_UNARY_OPERATOR, NOT);
+				break;
+			case TokenNameEQUAL_EQUAL:
+				pushOnElementStack(K_BINARY_OPERATOR, EQUAL_EQUAL);
+				break;
+			case TokenNameNOT_EQUAL:
+				pushOnElementStack(K_BINARY_OPERATOR, NOT_EQUAL);
+				break;
+			case TokenNameinstanceof:
+				pushOnElementStack(K_BINARY_OPERATOR, INSTANCEOF);
+				break;
+			case TokenNameQUESTION:
+				if(previous != TokenNameLESS && previous != TokenNameCOMMA) {
+					pushOnElementStack(K_CONDITIONAL_OPERATOR, QUESTION);
+				}
+				break;
+			case TokenNameCOLON:
+				switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+					case K_CONDITIONAL_OPERATOR:
+						if (topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == QUESTION) {
+							popElement(K_CONDITIONAL_OPERATOR);
+							pushOnElementStack(K_CONDITIONAL_OPERATOR, COLON);
+						}
+						break;
+					case K_BETWEEN_CASE_AND_COLON:
+						popElement(K_BETWEEN_CASE_AND_COLON);
+						break;
+					case K_BETWEEN_DEFAULT_AND_COLON:
+						popElement(K_BETWEEN_DEFAULT_AND_COLON);
+						break;
+					case K_INSIDE_ASSERT_STATEMENT:
+						pushOnElementStack(K_INSIDE_ASSERT_EXCEPTION, this.bracketDepth);
+						break;
+				}
+				break;
+			case TokenNameif:
+				pushOnElementStack(K_BETWEEN_IF_AND_RIGHT_PAREN, this.bracketDepth);
+				break;
+			case TokenNameelse:
+				if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_CONTROL_STATEMENT_DELIMITER) {
+					popElement(K_CONTROL_STATEMENT_DELIMITER);
+				}
+				pushOnElementStack(K_CONTROL_STATEMENT_DELIMITER);
+				break;
+			case TokenNamewhile:
+				pushOnElementStack(K_BETWEEN_WHILE_AND_RIGHT_PAREN, this.bracketDepth);
+				break;
+			case TokenNamefor:
+				pushOnElementStack(K_BETWEEN_FOR_AND_RIGHT_PAREN, this.bracketDepth);
+				break;
+			case TokenNameswitch:
+				pushOnElementStack(K_BETWEEN_SWITCH_AND_RIGHT_PAREN, this.bracketDepth);
+				break;
+			case TokenNamesynchronized:
+				pushOnElementStack(K_BETWEEN_SYNCHRONIZED_AND_RIGHT_PAREN, this.bracketDepth);
+				break;
+			case TokenNameassert:
+				pushOnElementStack(K_INSIDE_ASSERT_STATEMENT, this.bracketDepth);
+				break;
+			case TokenNamecase :
+				pushOnElementStack(K_BETWEEN_CASE_AND_COLON);
+				break;
+			case TokenNamedefault :
+				pushOnElementStack(K_BETWEEN_DEFAULT_AND_COLON);
+				break;
+			case TokenNameextends:
+				pushOnElementStack(K_EXTENDS_KEYWORD);
+				break;
+			case TokenNamebreak:
+				pushOnElementStack(K_INSIDE_BREAK_STATEMENT, this.bracketDepth);
+				break;
+			case TokenNamecontinue:
+				pushOnElementStack(K_INSIDE_CONTINUE_STATEMENT, this.bracketDepth);
+				break;
+		}
+	} else if (isInsideAnnotation()){
+		switch (token) {
+			case TokenNameLBRACE:
+				this.bracketDepth++;
+				int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+				if (kind == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+					pushOnElementStack(K_MEMBER_VALUE_ARRAY_INITIALIZER, this.endPosition);
+				}
+				break;
+		}
+	} else {
+		switch(token) {
+			case TokenNameextends:
+				pushOnElementStack(K_EXTENDS_KEYWORD);
+				break;
+			case TokenNameLESS:
+				pushOnElementStack(K_BINARY_OPERATOR, LESS);
+				break;
+			case TokenNameGREATER:
+				pushOnElementStack(K_BINARY_OPERATOR, GREATER);
+				break;
+			case TokenNameRIGHT_SHIFT:
+				pushOnElementStack(K_BINARY_OPERATOR, RIGHT_SHIFT);
+				break;
+			case TokenNameUNSIGNED_RIGHT_SHIFT:
+				pushOnElementStack(K_BINARY_OPERATOR, UNSIGNED_RIGHT_SHIFT);
+				break;
+
+		}
+	}
+}
+protected void consumeIdentifierOrNew(boolean newForm) {
+	this.inReferenceExpression = false;
+	super.consumeIdentifierOrNew(newForm);
+}
+protected void consumeOnlySynchronized() {
+	super.consumeOnlySynchronized();
+	this.hasUnusedModifiers = false;
+}
+protected void consumeOnlyTypeArguments() {
+	super.consumeOnlyTypeArguments();
+	popElement(K_BINARY_OPERATOR);
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_METHOD_INVOCATION) {
+		popElement(K_PARAMETERIZED_METHOD_INVOCATION);
+		pushOnElementStack(K_PARAMETERIZED_METHOD_INVOCATION, INSIDE_NAME);
+	} else {
+		popElement(K_PARAMETERIZED_ALLOCATION);
+	}
+}
+protected void consumeOnlyTypeArgumentsForCastExpression() {
+	super.consumeOnlyTypeArgumentsForCastExpression();
+	pushOnElementStack(K_PARAMETERIZED_CAST);
+}
+protected void consumeOpenFakeBlock() {
+	super.consumeOpenFakeBlock();
+	pushOnElementStack(K_BLOCK_DELIMITER);
+}
+protected void consumeRightParen() {
+	super.consumeRightParen();
+}
+protected void consumeReferenceType1() {
+	super.consumeReferenceType1();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeReferenceType2() {
+	super.consumeReferenceType2();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeReferenceType3() {
+	super.consumeReferenceType3();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeArgumentReferenceType1() {
+	super.consumeTypeArgumentReferenceType1();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeArgumentReferenceType2() {
+	super.consumeTypeArgumentReferenceType2();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeArguments() {
+	super.consumeTypeArguments();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeHeaderNameWithTypeParameters() {
+	super.consumeTypeHeaderNameWithTypeParameters();
+
+	TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
+	classHeaderExtendsOrImplements((typeDecl.modifiers & ClassFileConstants.AccInterface) != 0);
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	super.consumeTypeImportOnDemandDeclarationName();
+	this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+}
+protected void consumeImportDeclaration() {
+	super.consumeImportDeclaration();
+	popElement(K_INSIDE_IMPORT_STATEMENT);
+}
+protected void consumeTypeParameters() {
+	super.consumeTypeParameters();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeParameterHeader() {
+	super.consumeTypeParameterHeader();
+	TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+	if(typeParameter.type != null || (typeParameter.bounds != null && typeParameter.bounds.length > 0)) return;
+
+	if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
+		if (this.cursorLocation < this.scanner.startPosition && this.scanner.currentPosition == this.scanner.startPosition){ // fake empty identifier got issued
+			this.pushIdentifier();
+		} else if (this.cursorLocation+1 >= this.scanner.startPosition && this.cursorLocation < this.scanner.currentPosition){
+			this.pushIdentifier();
+		} else {
+			return;
+		}
+	} else {
+		return;
+	}
+
+	CompletionOnKeyword1 keyword = new CompletionOnKeyword1(
+		this.identifierStack[this.identifierPtr],
+		this.identifierPositionStack[this.identifierPtr],
+		Keywords.EXTENDS);
+	typeParameter.type = keyword;
+
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+
+	this.assistNode = typeParameter.type;
+	this.lastCheckPoint = typeParameter.type.sourceEnd + 1;
+}
+protected void consumeTypeParameter1() {
+	super.consumeTypeParameter1();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeTypeParameterWithExtends() {
+	super.consumeTypeParameterWithExtends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		if (typeParameter != null && typeParameter.type == this.assistNode)
+			this.assistNodeParent = typeParameter;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeTypeParameterWithExtendsAndBounds() {
+	super.consumeTypeParameterWithExtendsAndBounds();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		if (typeParameter != null && typeParameter.type == this.assistNode)
+			this.assistNodeParent = typeParameter;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeTypeParameter1WithExtends() {
+	super.consumeTypeParameter1WithExtends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		if (typeParameter != null && typeParameter.type == this.assistNode)
+			this.assistNodeParent = typeParameter;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeTypeParameter1WithExtendsAndBounds() {
+	super.consumeTypeParameter1WithExtendsAndBounds();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		if (typeParameter != null && typeParameter.type == this.assistNode)
+			this.assistNodeParent = typeParameter;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeUnionType() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+	super.consumeUnionType();
+	popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+}
+protected void consumeUnionTypeAsClassType() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+	super.consumeUnionTypeAsClassType();
+	popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+}
+protected void consumeWildcard() {
+	super.consumeWildcard();
+	if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
+		if (this.cursorLocation < this.scanner.startPosition && this.scanner.currentPosition == this.scanner.startPosition){ // fake empty identifier got issued
+			this.pushIdentifier();
+		} else if (this.cursorLocation+1 >= this.scanner.startPosition && this.cursorLocation < this.scanner.currentPosition){
+			this.pushIdentifier();
+		} else {
+			return;
+		}
+	} else {
+		return;
+	}
+	Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+	CompletionOnKeyword1 keyword = new CompletionOnKeyword1(
+		this.identifierStack[this.identifierPtr],
+		this.identifierPositionStack[this.identifierPtr],
+		new char[][]{Keywords.EXTENDS, Keywords.SUPER} );
+	wildcard.kind = Wildcard.EXTENDS;
+	wildcard.bound = keyword;
+
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+
+	this.assistNode = wildcard.bound;
+	this.lastCheckPoint = wildcard.bound.sourceEnd + 1;
+}
+protected void consumeWildcard1() {
+	super.consumeWildcard1();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeWildcard2() {
+	super.consumeWildcard2();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeWildcard3() {
+	super.consumeWildcard3();
+	popElement(K_BINARY_OPERATOR);
+}
+protected void consumeWildcardBoundsExtends() {
+	super.consumeWildcardBoundsExtends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		if (wildcard != null && wildcard.bound == this.assistNode)
+			this.assistNodeParent = wildcard;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeWildcardBounds1Extends() {
+	super.consumeWildcardBounds1Extends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		if (wildcard != null && wildcard.bound == this.assistNode)
+			this.assistNodeParent = wildcard;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeWildcardBounds2Extends() {
+	super.consumeWildcardBounds2Extends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		if (wildcard != null && wildcard.bound == this.assistNode)
+			this.assistNodeParent = wildcard;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeWildcardBounds3Extends() {
+	super.consumeWildcardBounds3Extends();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		if (wildcard != null && wildcard.bound == this.assistNode)
+			this.assistNodeParent = wildcard;
+	}
+	popElement(K_EXTENDS_KEYWORD);
+}
+protected void consumeUnaryExpression(int op) {
+	super.consumeUnaryExpression(op);
+	popElement(K_UNARY_OPERATOR);
+
+	if(this.expressionStack[this.expressionPtr] instanceof UnaryExpression) {
+		UnaryExpression exp = (UnaryExpression) this.expressionStack[this.expressionPtr];
+		if(this.assistNode != null && exp.expression == this.assistNode) {
+			this.assistNodeParent = exp;
+		}
+	}
+}
+protected void consumeUnaryExpression(int op, boolean post) {
+	super.consumeUnaryExpression(op, post);
+	popElement(K_UNARY_OPERATOR);
+
+	if(this.expressionStack[this.expressionPtr] instanceof UnaryExpression) {
+		UnaryExpression exp = (UnaryExpression) this.expressionStack[this.expressionPtr];
+		if(this.assistNode != null && exp.expression == this.assistNode) {
+			this.assistNodeParent = exp;
+		}
+	}
+}
+public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
+	MethodDeclaration methodDeclaration = super.convertToMethodDeclaration(c, compilationResult);
+	if (this.sourceEnds != null) {
+		int selectorSourceEnd = this.sourceEnds.removeKey(c);
+		if (selectorSourceEnd != -1)
+			this.sourceEnds.put(methodDeclaration, selectorSourceEnd);
+	}
+	return methodDeclaration;
+}
+public ImportReference createAssistImportReference(char[][] tokens, long[] positions, int mod){
+	return new CompletionOnImportReference(tokens, positions, mod);
+}
+public ImportReference createAssistPackageReference(char[][] tokens, long[] positions){
+	return new CompletionOnPackageReference(tokens, positions);
+}
+public NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
+	return new CompletionOnQualifiedNameReference(
+					previousIdentifiers,
+					assistName,
+					positions,
+					isInsideAttributeValue());
+}
+public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
+	switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+		case K_NEXT_TYPEREF_IS_EXCEPTION :
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+				this.isOrphanCompletionNode = true;
+			return new CompletionOnQualifiedTypeReference(
+					previousIdentifiers,
+					assistName,
+					positions,
+					CompletionOnQualifiedTypeReference.K_EXCEPTION);
+		case K_NEXT_TYPEREF_IS_CLASS :
+			return new CompletionOnQualifiedTypeReference(
+					previousIdentifiers,
+					assistName,
+					positions,
+					CompletionOnQualifiedTypeReference.K_CLASS);
+		case K_NEXT_TYPEREF_IS_INTERFACE :
+			return new CompletionOnQualifiedTypeReference(
+					previousIdentifiers,
+					assistName,
+					positions,
+					CompletionOnQualifiedTypeReference.K_INTERFACE);
+		default :
+			return new CompletionOnQualifiedTypeReference(
+					previousIdentifiers,
+					assistName,
+					positions);
+	}
+}
+public TypeReference createParameterizedQualifiedAssistTypeReference(char[][] previousIdentifiers, TypeReference[][] typeArguments, char[] assistName, TypeReference[] assistTypeArguments, long[] positions) {
+	boolean isParameterized = false;
+	for (int i = 0; i < typeArguments.length; i++) {
+		if(typeArguments[i] != null) {
+			isParameterized = true;
+		}
+	}
+	if(!isParameterized) {
+		return createQualifiedAssistTypeReference(previousIdentifiers, assistName, positions);
+	} else {
+		switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+			case K_NEXT_TYPEREF_IS_EXCEPTION :
+				if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+					this.isOrphanCompletionNode = true;
+				return new CompletionOnParameterizedQualifiedTypeReference(
+					previousIdentifiers,
+					typeArguments,
+					assistName,
+					positions,
+					CompletionOnParameterizedQualifiedTypeReference.K_EXCEPTION);
+			case K_NEXT_TYPEREF_IS_CLASS :
+				return new CompletionOnParameterizedQualifiedTypeReference(
+					previousIdentifiers,
+					typeArguments,
+					assistName,
+					positions,
+					CompletionOnParameterizedQualifiedTypeReference.K_CLASS);
+			case K_NEXT_TYPEREF_IS_INTERFACE :
+				return new CompletionOnParameterizedQualifiedTypeReference(
+					previousIdentifiers,
+					typeArguments,
+					assistName,
+					positions,
+					CompletionOnParameterizedQualifiedTypeReference.K_INTERFACE);
+			default :
+				return new CompletionOnParameterizedQualifiedTypeReference(
+					previousIdentifiers,
+					typeArguments,
+					assistName,
+					positions);
+		}
+	}
+}
+public NameReference createSingleAssistNameReference(char[] assistName, long position) {
+	int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
+	if(!isInsideMethod()) {
+		if (isInsideFieldInitialization()) {
+			return new CompletionOnSingleNameReference(
+					assistName,
+					position,
+					new char[][]{Keywords.FALSE, Keywords.TRUE},
+					false,
+					isInsideAttributeValue());
+		}
+		return new CompletionOnSingleNameReference(assistName, position, isInsideAttributeValue());
+	} else {
+		boolean canBeExplicitConstructorCall = false;
+		if(kind == K_BLOCK_DELIMITER
+			&& this.previousKind == K_BLOCK_DELIMITER
+			&& this.previousInfo == DO) {
+			return new CompletionOnKeyword3(assistName, position, Keywords.WHILE);
+		} else if(kind == K_BLOCK_DELIMITER
+			&& this.previousKind == K_BLOCK_DELIMITER
+			&& this.previousInfo == TRY) {
+			return new CompletionOnKeyword3(assistName, position, new char[][]{Keywords.CATCH, Keywords.FINALLY});
+		} else if(kind == K_BLOCK_DELIMITER
+			&& topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == SWITCH) {
+			return new CompletionOnKeyword3(assistName, position, new char[][]{Keywords.CASE, Keywords.DEFAULT});
+		} else {
+			char[][] keywords = new char[Keywords.COUNT][];
+			int count = 0;
+
+			if((this.lastModifiers & ClassFileConstants.AccStatic) == 0) {
+				keywords[count++]= Keywords.SUPER;
+				keywords[count++]= Keywords.THIS;
+			}
+			keywords[count++]= Keywords.NEW;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=269493: Keywords are not proposed in a for
+			// loop without block. Completion while at K_CONTROL_STATEMENT_DELIMITER case needs to handled
+			// similar to the K_BLOCK_DELIMITER with minor differences.
+			if(kind == K_BLOCK_DELIMITER || kind == K_CONTROL_STATEMENT_DELIMITER) {
+				if(this.canBeExplicitConstructor == YES) {
+					canBeExplicitConstructorCall = true;
+				}
+				if (this.options.complianceLevel >= ClassFileConstants.JDK1_4) {
+					keywords[count++]= Keywords.ASSERT;
+				}
+				keywords[count++]= Keywords.DO;
+				keywords[count++]= Keywords.FOR;
+				keywords[count++]= Keywords.IF;
+				keywords[count++]= Keywords.RETURN;
+				keywords[count++]= Keywords.SWITCH;
+				keywords[count++]= Keywords.SYNCHRONIZED;
+				keywords[count++]= Keywords.THROW;
+				keywords[count++]= Keywords.TRY;
+				keywords[count++]= Keywords.WHILE;
+
+				keywords[count++]= Keywords.FINAL;
+				keywords[count++]= Keywords.CLASS;
+
+				if(this.previousKind == K_BLOCK_DELIMITER) {
+					switch (this.previousInfo) {
+						case IF :
+							keywords[count++]= Keywords.ELSE;
+							break;
+						case CATCH :
+							keywords[count++]= Keywords.CATCH;
+							keywords[count++]= Keywords.FINALLY;
+							break;
+					}
+				} else if(this.previousKind == K_CONTROL_STATEMENT_DELIMITER && this.previousInfo == IF) {
+					keywords[count++]= Keywords.ELSE;
+				}
+				if(isInsideLoop()) {
+					keywords[count++]= Keywords.CONTINUE;
+				}
+				if(isInsideBreakable()) {
+					keywords[count++]= Keywords.BREAK;
+				}
+			} else if(kind != K_BETWEEN_CASE_AND_COLON && kind != K_BETWEEN_DEFAULT_AND_COLON) {
+				keywords[count++]= Keywords.TRUE;
+				keywords[count++]= Keywords.FALSE;
+				keywords[count++]= Keywords.NULL;
+
+				if(kind == K_SWITCH_LABEL) {
+					if(topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) != DEFAULT) {
+						keywords[count++]= Keywords.DEFAULT;
+					}
+					keywords[count++]= Keywords.BREAK;
+					keywords[count++]= Keywords.CASE;
+					if (this.options.complianceLevel >= ClassFileConstants.JDK1_4) {
+						keywords[count++]= Keywords.ASSERT;
+					}
+					keywords[count++]= Keywords.DO;
+					keywords[count++]= Keywords.FOR;
+					keywords[count++]= Keywords.IF;
+					keywords[count++]= Keywords.RETURN;
+					keywords[count++]= Keywords.SWITCH;
+					keywords[count++]= Keywords.SYNCHRONIZED;
+					keywords[count++]= Keywords.THROW;
+					keywords[count++]= Keywords.TRY;
+					keywords[count++]= Keywords.WHILE;
+
+					keywords[count++]= Keywords.FINAL;
+					keywords[count++]= Keywords.CLASS;
+
+					if(isInsideLoop()) {
+						keywords[count++]= Keywords.CONTINUE;
+					}
+				}
+			}
+			System.arraycopy(keywords, 0 , keywords = new char[count][], 0, count);
+
+			return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall, isInsideAttributeValue());
+		}
+	}
+}
+public TypeReference createSingleAssistTypeReference(char[] assistName, long position) {
+	switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+		case K_NEXT_TYPEREF_IS_EXCEPTION :
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+				this.isOrphanCompletionNode = true;
+			return new CompletionOnSingleTypeReference(assistName, position, CompletionOnSingleTypeReference.K_EXCEPTION) ;
+		case K_NEXT_TYPEREF_IS_CLASS :
+			return new CompletionOnSingleTypeReference(assistName, position, CompletionOnSingleTypeReference.K_CLASS);
+		case K_NEXT_TYPEREF_IS_INTERFACE :
+			return new CompletionOnSingleTypeReference(assistName, position, CompletionOnSingleTypeReference.K_INTERFACE);
+		default :
+			return new CompletionOnSingleTypeReference(assistName, position);
+	}
+}
+public TypeReference createParameterizedSingleAssistTypeReference(TypeReference[] typeArguments, char[] assistName, long position) {
+	return createSingleAssistTypeReference(assistName, position);
+}
+protected StringLiteral createStringLiteral(char[] token, int start, int end, int lineNumber) {
+	if (start <= this.cursorLocation && this.cursorLocation <= end){
+		char[] source = this.scanner.source;
+
+		int contentStart = start;
+		int contentEnd = end;
+
+		// " could be as unicode \u0022
+		int pos = contentStart;
+		if(source[pos] == '\"') {
+			contentStart = pos + 1;
+		} else if(source[pos] == '\\' && source[pos+1] == 'u') {
+			pos += 2;
+			while (source[pos] == 'u') {
+				pos++;
+			}
+			if(source[pos] == 0 && source[pos + 1] == 0 && source[pos + 2] == 2 && source[pos + 3] == 2) {
+				contentStart = pos + 4;
+			}
+		}
+
+		pos = contentEnd;
+		if(source[pos] == '\"') {
+			contentEnd = pos - 1;
+		} else if(source.length > 5 && source[pos-4] == 'u') {
+			if(source[pos - 3] == 0 && source[pos - 2] == 0 && source[pos - 1] == 2 && source[pos] == 2) {
+				pos -= 5;
+				while (pos > -1 && source[pos] == 'u') {
+					pos--;
+				}
+				if(pos > -1 && source[pos] == '\\') {
+					contentEnd = pos - 1;
+				}
+			}
+		}
+
+		if(contentEnd < start) {
+			contentEnd = end;
+		}
+
+		if(this.cursorLocation != end || end == contentEnd) {
+			CompletionOnStringLiteral stringLiteral = new CompletionOnStringLiteral(
+					token,
+					start,
+					end,
+					contentStart,
+					contentEnd,
+					lineNumber);
+
+			this.assistNode = stringLiteral;
+			this.restartRecovery = true;
+			this.lastCheckPoint = end;
+
+			return stringLiteral;
+		}
+	}
+	return super.createStringLiteral(token, start, end, lineNumber);
+}
+protected TypeReference copyDims(TypeReference typeRef, int dim) {
+	if (this.assistNode == typeRef) {
+		return typeRef;
+	}
+	TypeReference result = super.copyDims(typeRef, dim);
+	if (this.assistNodeParent == typeRef) {
+		this.assistNodeParent = result;
+	}
+	return result;
+}
+protected TypeReference copyDims(TypeReference typeRef, int dim, Annotation[][] annotationsOnDimensions) {
+	if (this.assistNode == typeRef) {
+		return typeRef;
+	}
+	TypeReference result = super.copyDims(typeRef, dim, annotationsOnDimensions);
+	if (this.assistNodeParent == typeRef) {
+		this.assistNodeParent = result;
+	}
+	return result;
+}
+public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int cursorLoc) {
+
+	this.cursorLocation = cursorLoc;
+	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+	completionScanner.completionIdentifier = null;
+	completionScanner.cursorLocation = cursorLoc;
+	return this.dietParse(sourceUnit, compilationResult);
+}
+/*
+ * Flush parser/scanner state regarding to code assist
+ */
+public void flushAssistState() {
+
+	super.flushAssistState();
+	this.isOrphanCompletionNode = false;
+	this.isAlreadyAttached = false;
+	this.assistNodeParent = null;
+	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+	completionScanner.completedIdentifierStart = 0;
+	completionScanner.completedIdentifierEnd = -1;
+}
+
+protected TypeReference getTypeReferenceForGenericType(int dim,	int identifierLength, int numberOfIdentifiers) {
+	TypeReference ref = super.getTypeReferenceForGenericType(dim, identifierLength, numberOfIdentifiers);
+	// in completion case we might have encountered the assist node before really parsing
+	// the complete class instance creation, and so a separate check for diamond is needed here.
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454
+	checkForDiamond(ref);
+	if(this.assistNode != null) {
+		if (identifierLength == 1 && numberOfIdentifiers == 1) {
+			ParameterizedSingleTypeReference singleRef = (ParameterizedSingleTypeReference) ref;
+			TypeReference[] typeArguments = singleRef.typeArguments;
+			for (int i = 0; i < typeArguments.length; i++) {
+				if(typeArguments[i] == this.assistNode) {
+					this.assistNodeParent = ref;
+					return ref;
+				}
+			}
+		} else {
+			ParameterizedQualifiedTypeReference qualifiedRef = (ParameterizedQualifiedTypeReference) ref;
+			TypeReference[][] typeArguments = qualifiedRef.typeArguments;
+			for (int i = 0; i < typeArguments.length; i++) {
+				if(typeArguments[i] != null) {
+					for (int j = 0; j < typeArguments[i].length; j++) {
+						if(typeArguments[i][j] == this.assistNode) {
+							this.assistNodeParent = ref;
+							return ref;
+						}
+					}
+				}
+			}
+
+		}
+	}
+
+	return ref;
+}
+protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	NameReference nameReference = super.getUnspecifiedReference(rejectTypeAnnotations);
+	if (this.record) {
+		recordReference(nameReference);
+	}
+	return nameReference;
+}
+protected NameReference getUnspecifiedReferenceOptimized() {
+	if (this.identifierLengthStack[this.identifierLengthPtr] > 1) { // reducing a qualified name
+		// potential receiver is being poped, so reset potential receiver
+		this.invocationType = NO_RECEIVER;
+		this.qualifier = -1;
+	}
+	NameReference nameReference = super.getUnspecifiedReferenceOptimized();
+	if (this.record) {
+		recordReference(nameReference);
+	}
+	return nameReference;
+}
+private boolean isAlreadyPotentialName(int identifierStart) {
+	if (this.potentialVariableNamesPtr < 0) return false;
+
+	return identifierStart <= this.potentialVariableNameEnds[this.potentialVariableNamesPtr];
+}
+protected int indexOfAssistIdentifier(boolean useGenericsStack) {
+	if (this.record) return -1; // when names are recorded there is no assist identifier
+	return super.indexOfAssistIdentifier(useGenericsStack);
+}
+public void initialize() {
+	super.initialize();
+	this.labelPtr = -1;
+	initializeForBlockStatements();
+}
+public void initialize(boolean initializeNLS) {
+	super.initialize(initializeNLS);
+	this.labelPtr = -1;
+	initializeForBlockStatements();
+}
+/*
+ * Initializes the state of the parser that is about to go for BlockStatements.
+ */
+private void initializeForBlockStatements() {
+	this.previousToken = -1;
+	this.previousIdentifierPtr = -1;
+	this.invocationType = NO_RECEIVER;
+	this.qualifier = -1;
+	popUntilElement(K_SWITCH_LABEL);
+	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_SWITCH_LABEL) {
+		if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_ARRAY_INITIALIZER) {
+			// if recovery is taking place in an array initializer, we should prevent popping
+			// up to the enclosing block until the array initializer is properly closed
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=249704
+			popUntilElement(K_ARRAY_INITIALIZER);
+		} else {
+			popUntilElement(K_BLOCK_DELIMITER);
+		}
+	}
+}
+public void initializeScanner(){
+	this.scanner = new CompletionScanner(this.options.sourceLevel);
+}
+/**
+ * Returns whether the completion is just after an array type
+ * e.g. String[].[cursor]
+ */
+private boolean isAfterArrayType() {
+	// TBD: The following relies on the fact that array dimensions are small: it says that if the
+	//      top of the intStack is less than 11, then it must be a dimension
+	//      (smallest position of array type in a compilation unit is 11 as in "class X{Y[]")
+	if ((this.intPtr > -1) && (this.intStack[this.intPtr] < 11)) {
+		return true;
+	}
+	return false;
+}
+private boolean isEmptyNameCompletion() {
+	return
+		this.assistNode != null &&
+		this.assistNode instanceof CompletionOnSingleNameReference &&
+		(((CompletionOnSingleNameReference)this.assistNode).token.length == 0);
+}
+protected boolean isInsideAnnotation() {
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN)
+			return true;
+		i--;
+	}
+	return false;
+}
+
+protected boolean isIndirectlyInsideBlock(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == K_BLOCK_DELIMITER)
+			return true;
+		i--;
+	}
+	return false;
+}
+
+protected boolean isInsideBlock(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_BLOCK_DELIMITER : return true;
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideBreakable(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_SWITCH_LABEL : return true;
+			case K_BLOCK_DELIMITER :
+			case K_CONTROL_STATEMENT_DELIMITER:
+				switch(this.elementInfoStack[i]) {
+					case FOR :
+					case DO :
+					case WHILE :
+						return true;
+				}
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideLoop(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_BLOCK_DELIMITER :
+			case K_CONTROL_STATEMENT_DELIMITER:
+				switch(this.elementInfoStack[i]) {
+					case FOR :
+					case DO :
+					case WHILE :
+						return true;
+				}
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideReturn(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_BLOCK_DELIMITER : return false;
+			case K_CONTROL_STATEMENT_DELIMITER: return false; // FWIW
+			case K_INSIDE_RETURN_STATEMENT : return true;
+		}
+		i--;
+	}
+	return false;
+}
+public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int cursorLoc) {
+
+	this.cursorLocation = cursorLoc;
+	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+	completionScanner.completionIdentifier = null;
+	completionScanner.cursorLocation = cursorLoc;
+	return this.parse(sourceUnit, compilationResult);
+}
+public void parseBlockStatements(
+	ConstructorDeclaration cd,
+	CompilationUnitDeclaration unit) {
+	this.canBeExplicitConstructor = 1;
+	super.parseBlockStatements(cd, unit);
+}
+public MethodDeclaration parseSomeStatements(int start, int end, int fakeBlocksCount, CompilationUnitDeclaration unit) {
+	this.methodRecoveryActivated = true;
+
+	initialize();
+
+	// simulate goForMethodBody except that we don't want to balance brackets because they are not going to be balanced
+	goForBlockStatementsopt();
+
+	MethodDeclaration fakeMethod = new MethodDeclaration(unit.compilationResult());
+	fakeMethod.selector = FAKE_METHOD_NAME;
+	fakeMethod.bodyStart = start;
+	fakeMethod.bodyEnd = end;
+	fakeMethod.declarationSourceStart = start;
+	fakeMethod.declarationSourceEnd = end;
+	fakeMethod.sourceStart = start;
+	fakeMethod.sourceEnd = start; //fake method must ignore the method header
+
+	this.referenceContext = fakeMethod;
+	this.compilationUnit = unit;
+
+	this.diet = false;
+	this.restartRecovery = true;
+
+	this.scanner.resetTo(start, end);
+	consumeNestedMethod();
+	for (int i = 0; i < fakeBlocksCount; i++) {
+		consumeOpenFakeBlock();
+	}
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+	if (!this.hasError) {
+		int length;
+		if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.astStack,
+				(this.astPtr -= length) + 1,
+				fakeMethod.statements = new Statement[length],
+				0,
+				length);
+		}
+	}
+
+	return fakeMethod;
+}
+protected void popUntilCompletedAnnotationIfNecessary() {
+	if(this.elementPtr < 0) return;
+
+	int i = this.elementPtr;
+	while(i > -1 &&
+			(this.elementKindStack[i] != K_BETWEEN_ANNOTATION_NAME_AND_RPAREN ||
+					(this.elementInfoStack[i] & ANNOTATION_NAME_COMPLETION) == 0)) {
+		i--;
+	}
+
+	if(i >= 0) {
+		this.previousKind = this.elementKindStack[i];
+		this.previousInfo = this.elementInfoStack[i];
+		this.previousObjectInfo = this.elementObjectInfoStack[i];
+
+		for (int j = i; j <= this.elementPtr; j++) {
+			this.elementObjectInfoStack[j] = null;
+		}
+
+		this.elementPtr = i - 1;
+	}
+}
+/*
+ * Prepares the state of the parser to go for BlockStatements.
+ */
+protected void prepareForBlockStatements() {
+	this.nestedMethod[this.nestedType = 0] = 1;
+	this.variablesCounter[this.nestedType] = 0;
+	this.realBlockStack[this.realBlockPtr = 1] = 0;
+
+	initializeForBlockStatements();
+}
+protected void pushOnLabelStack(char[] label){
+	if (this.labelPtr < -1) return;
+
+	int stackLength = this.labelStack.length;
+	if (++this.labelPtr >= stackLength) {
+		System.arraycopy(
+			this.labelStack, 0,
+			this.labelStack = new char[stackLength + LabelStackIncrement][], 0,
+			stackLength);
+	}
+	this.labelStack[this.labelPtr] = label;
+}
+/**
+ * Creates a completion on member access node and push it
+ * on the expression stack.
+ */
+private void pushCompletionOnMemberAccessOnExpressionStack(boolean isSuperAccess) {
+	char[] source = this.identifierStack[this.identifierPtr];
+	long pos = this.identifierPositionStack[this.identifierPtr--];
+	CompletionOnMemberAccess fr = new CompletionOnMemberAccess(source, pos, isInsideAnnotation());
+	this.assistNode = fr;
+	this.lastCheckPoint = fr.sourceEnd + 1;
+	this.identifierLengthPtr--;
+	if (isSuperAccess) { //considerates the fieldReference beginning at the 'super' ....
+		fr.sourceStart = this.intStack[this.intPtr--];
+		fr.receiver = new SuperReference(fr.sourceStart, this.endPosition);
+		pushOnExpressionStack(fr);
+	} else { //optimize push/pop
+		if ((fr.receiver = this.expressionStack[this.expressionPtr]).isThis()) { //fieldreference begins at the this
+			fr.sourceStart = fr.receiver.sourceStart;
+		}
+		this.expressionStack[this.expressionPtr] = fr;
+	}
+}
+private void recordReference(NameReference nameReference) {
+	if (!this.skipRecord &&
+			this.recordFrom <= nameReference.sourceStart &&
+			nameReference.sourceEnd <= this.recordTo &&
+			!isAlreadyPotentialName(nameReference.sourceStart)) {
+		char[] token;
+		if (nameReference instanceof SingleNameReference) {
+			token = ((SingleNameReference) nameReference).token;
+		} else {
+			token = ((QualifiedNameReference) nameReference).tokens[0];
+		}
+
+		// Most of the time a name which start with an uppercase is a type name.
+		// As we don't want to resolve names to avoid to slow down performances then this name will be ignored
+		if (Character.isUpperCase(token[0])) return;
+
+		addPotentialName(token, nameReference.sourceStart, nameReference.sourceEnd);
+	}
+}
+public void recoveryExitFromVariable() {
+	if(this.currentElement != null && this.currentElement instanceof RecoveredLocalVariable) {
+		RecoveredElement oldElement = this.currentElement;
+		super.recoveryExitFromVariable();
+		if(oldElement != this.currentElement) {
+			popElement(K_LOCAL_INITIALIZER_DELIMITER);
+		}
+	} else if(this.currentElement != null && this.currentElement instanceof RecoveredField) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087
+		// To make sure the array initializer is popped when the focus is shifted to the parent
+		// in case we're restarting recovery inside an array initializer
+		RecoveredElement oldElement = this.currentElement;
+		super.recoveryExitFromVariable();	
+		if(oldElement != this.currentElement) {	
+			if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_ARRAY_INITIALIZER) {	
+				popElement(K_ARRAY_INITIALIZER);	
+				popElement(K_FIELD_INITIALIZER_DELIMITER);	
+			} 	
+		}
+	} else {
+		super.recoveryExitFromVariable();
+	}
+}
+public void recoveryTokenCheck() {
+	RecoveredElement oldElement = this.currentElement;
+	switch (this.currentToken) {
+		case TokenNameLBRACE :
+			if(!this.ignoreNextOpeningBrace) {
+				this.pendingAnnotation = null; // the pending annotation cannot be attached to next nodes
+			}
+			super.recoveryTokenCheck();
+			break;
+		case TokenNameRBRACE :
+			super.recoveryTokenCheck();
+			if(this.currentElement != oldElement && oldElement instanceof RecoveredBlock) {
+				if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_ARRAY_INITIALIZER) {
+					// When inside an array initializer, we should not prematurely pop the enclosing block
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=249704
+					popElement(K_ARRAY_INITIALIZER);
+				} else {
+					popElement(K_BLOCK_DELIMITER);
+				}
+			}
+			break;
+		case TokenNamecase :
+			super.recoveryTokenCheck();
+			if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BLOCK_DELIMITER
+				&& topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == SWITCH) {
+				pushOnElementStack(K_SWITCH_LABEL);
+			}
+			break;
+		case TokenNamedefault :
+			super.recoveryTokenCheck();
+			if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BLOCK_DELIMITER
+				&& topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER) == SWITCH) {
+				pushOnElementStack(K_SWITCH_LABEL, DEFAULT);
+			} else if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SWITCH_LABEL) {
+				popElement(K_SWITCH_LABEL);
+				pushOnElementStack(K_SWITCH_LABEL, DEFAULT);
+			}
+			break;
+		default :
+			super.recoveryTokenCheck();
+			break;
+	}
+}
+/*
+ * Reset internal state after completion is over
+ */
+
+public void reset() {
+	super.reset();
+	this.cursorLocation = 0;
+	if (this.storeSourceEnds) {
+		this.sourceEnds = new HashtableOfObjectToInt();
+	}
+}
+/*
+ * Reset internal state after completion is over
+ */
+
+public void resetAfterCompletion() {
+	this.cursorLocation = 0;
+	flushAssistState();
+}
+public void restoreAssistParser(Object parserState) {
+	int[] state = (int[]) parserState;
+	
+	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
+	
+	this.cursorLocation = state[0];
+	completionScanner.cursorLocation = state[1];
+}
+/*
+ * Reset context so as to resume to regular parse loop
+ * If unable to reset for resuming, answers false.
+ *
+ * Move checkpoint location, reset internal stacks and
+ * decide which grammar goal is activated.
+ */
+protected boolean resumeAfterRecovery() {
+	this.hasUnusedModifiers = false;
+	if (this.assistNode != null) {
+		/* if reached [eof] inside method body, but still inside nested type,
+			or inside a field initializer, should continue in diet mode until
+			the end of the method body or compilation unit */
+		if ((this.scanner.eofPosition == this.cursorLocation+1)
+			&& (!(this.referenceContext instanceof CompilationUnitDeclaration)
+			|| isIndirectlyInsideFieldInitialization()
+			|| this.assistNodeParent instanceof FieldDeclaration && !(this.assistNodeParent instanceof Initializer))) {
+
+			/*	disabled since does not handle possible field/message refs, that is, Obj[ASSIST HERE]ect.registerNatives()
+			// consume extra tokens which were part of the qualified reference
+			//   so that the replaced source comprises them as well
+			if (this.assistNode instanceof NameReference){
+				int oldEof = scanner.eofPosition;
+				scanner.eofPosition = currentElement.topElement().sourceEnd()+1;
+				scanner.currentPosition = this.cursorLocation+1;
+				int token = -1;
+				try {
+					do {
+						// first token might not have to be a dot
+						if (token >= 0 || !this.completionBehindDot){
+							if ((token = scanner.getNextToken()) != TokenNameDOT) break;
+						}
+						if ((token = scanner.getNextToken()) != TokenNameIdentifier) break;
+						this.assistNode.sourceEnd = scanner.currentPosition - 1;
+					} while (token != TokenNameEOF);
+				} catch (InvalidInputException e){
+				} finally {
+					scanner.eofPosition = oldEof;
+				}
+			}
+			*/
+			/* restart in diet mode for finding sibling constructs */
+			if (this.currentElement instanceof RecoveredType
+				|| this.currentElement.enclosingType() != null){
+
+				this.pendingAnnotation = null;
+
+				if(this.lastCheckPoint <= this.assistNode.sourceEnd) {
+					this.lastCheckPoint = this.assistNode.sourceEnd+1;
+				}
+				int end = this.currentElement.topElement().sourceEnd();
+				this.scanner.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+			} else {
+				resetStacks();
+				return false;
+			}
+		}
+	}
+	return super.resumeAfterRecovery();
+}
+public void setAssistIdentifier(char[] assistIdent){
+	((CompletionScanner)this.scanner).completionIdentifier = assistIdent;
+}
+public  String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("elementKindStack : int[] = {"); //$NON-NLS-1$
+	for (int i = 0; i <= this.elementPtr; i++) {
+		buffer.append(String.valueOf(this.elementKindStack[i])).append(',');
+	}
+	buffer.append("}\n"); //$NON-NLS-1$
+	buffer.append("elementInfoStack : int[] = {"); //$NON-NLS-1$
+	for (int i = 0; i <= this.elementPtr; i++) {
+		buffer.append(String.valueOf(this.elementInfoStack[i])).append(',');
+	}
+	buffer.append("}\n"); //$NON-NLS-1$
+	buffer.append(super.toString());
+	return String.valueOf(buffer);
+}
+
+/*
+ * Update recovery state based on current parser/scanner state
+ */
+protected void updateRecoveryState() {
+
+	/* expose parser state to recovery state */
+	this.currentElement.updateFromParserState();
+
+	/* may be able to retrieve completionNode as an orphan, and then attach it */
+	completionIdentifierCheck();
+	attachOrphanCompletionNode();
+
+	// if an assist node has been found and a recovered element exists,
+	// mark enclosing blocks as to be preserved
+	if (this.assistNode != null && this.currentElement != null) {
+		this.currentElement.preserveEnclosingBlocks();
+	}
+
+	/* check and update recovered state based on current token,
+		this action is also performed when shifting token after recovery
+		got activated once.
+	*/
+	recoveryTokenCheck();
+
+	recoveryExitFromVariable();
+}
+
+protected LocalDeclaration createLocalDeclaration(char[] assistName, int sourceStart, int sourceEnd) {
+	if (this.indexOfAssistIdentifier() < 0) {
+		return super.createLocalDeclaration(assistName, sourceStart, sourceEnd);
+	} else {
+		CompletionOnLocalName local = new CompletionOnLocalName(assistName, sourceStart, sourceEnd);
+		this.assistNode = local;
+		this.lastCheckPoint = sourceEnd + 1;
+		return local;
+	}
+}
+
+protected JavadocParser createJavadocParser() {
+	return new CompletionJavadocParser(this);
+}
+
+protected FieldDeclaration createFieldDeclaration(char[] assistName, int sourceStart, int sourceEnd) {
+	if (this.indexOfAssistIdentifier() < 0 || (this.currentElement instanceof RecoveredUnit && ((RecoveredUnit)this.currentElement).typeCount == 0)) {
+		return super.createFieldDeclaration(assistName, sourceStart, sourceEnd);
+	} else {
+		CompletionOnFieldName field = new CompletionOnFieldName(assistName, sourceStart, sourceEnd);
+		this.assistNode = field;
+		this.lastCheckPoint = sourceEnd + 1;
+		return field;
+	}
+}
+
+/*
+ * 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;
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087
+protected boolean isInsideArrayInitializer(){
+	int i = this.elementPtr;
+	if (i > -1 && this.elementKindStack[i] == K_ARRAY_INITIALIZER) {
+		return true;
+	}
+	return false;	
+}
+protected boolean isInImportStatement() {
+	int i = this.elementPtr;
+	while (i > -1) {
+		if (this.elementKindStack[i] == K_INSIDE_IMPORT_STATEMENT) {
+			return true;
+		}
+		i--;
+	}
+	return false;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
new file mode 100644
index 0000000..61a375a
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -0,0 +1,921 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/*
+ * Scanner aware of a cursor location so as to discard trailing portions of identifiers
+ * containing the cursor location.
+ *
+ * Cursor location denotes the position of the last character behind which completion
+ * got requested:
+ *  -1 means completion at the very beginning of the source
+ *	0  means completion behind the first character
+ *  n  means completion behind the n-th character
+ */
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+public class CompletionScanner extends Scanner {
+
+	public char[] completionIdentifier;
+	public int cursorLocation;
+	public int endOfEmptyToken = -1;
+
+	/* Source positions of the completedIdentifier
+	 * if inside actual identifier, end goes to the actual identifier
+	 * end, in other words, beyond cursor location
+	 */
+	public int completedIdentifierStart = 0;
+	public int completedIdentifierEnd = -1;
+	public int unicodeCharSize;
+
+	public static final char[] EmptyCompletionIdentifier = {};
+
+public CompletionScanner(long sourceLevel) {
+	super(
+		false /*comment*/,
+		false /*whitespace*/,
+		false /*nls*/,
+		sourceLevel,
+		null /*taskTags*/,
+		null/*taskPriorities*/,
+		true/*taskCaseSensitive*/);
+}
+/*
+ * Truncate the current identifier if it is containing the cursor location. Since completion is performed
+ * on an identifier prefix.
+ *
+ */
+public char[] getCurrentIdentifierSource() {
+
+	if (this.completionIdentifier == null){
+		if (this.cursorLocation < this.startPosition && this.currentPosition == this.startPosition){ // fake empty identifier got issued
+			// remember actual identifier positions
+			this.completedIdentifierStart = this.startPosition;
+			this.completedIdentifierEnd = this.completedIdentifierStart - 1;
+			return this.completionIdentifier = EmptyCompletionIdentifier;
+		}
+		if (this.cursorLocation+1 >= this.startPosition && this.cursorLocation < this.currentPosition){
+			// remember actual identifier positions
+			this.completedIdentifierStart = this.startPosition;
+			this.completedIdentifierEnd = this.currentPosition - 1;
+			if (this.withoutUnicodePtr != 0){			// check unicode scenario
+				int length = this.cursorLocation + 1 - this.startPosition - this.unicodeCharSize;
+				System.arraycopy(this.withoutUnicodeBuffer, 1, this.completionIdentifier = new char[length], 0, length);
+			} else {
+				// no char[] sharing around completionIdentifier, we want it to be unique so as to use identity checks
+				int length = this.cursorLocation + 1 - this.startPosition;
+				System.arraycopy(this.source, this.startPosition, (this.completionIdentifier = new char[length]), 0, length);
+			}
+			return this.completionIdentifier;
+		}
+	}
+	return super.getCurrentIdentifierSource();
+}
+
+public char[] getCurrentTokenSourceString() {
+	if (this.completionIdentifier == null){
+		if (this.cursorLocation+1 >= this.startPosition && this.cursorLocation < this.currentPosition){
+			// remember actual identifier positions
+			this.completedIdentifierStart = this.startPosition;
+			this.completedIdentifierEnd = this.currentPosition - 1;
+			if (this.withoutUnicodePtr != 0){			// check unicode scenario
+				int length = this.cursorLocation - this.startPosition - this.unicodeCharSize;
+				System.arraycopy(this.withoutUnicodeBuffer, 2, this.completionIdentifier = new char[length], 0, length);
+			} else {
+				// no char[] sharing around completionIdentifier, we want it to be unique so as to use identity checks
+				int length = this.cursorLocation - this.startPosition;
+				System.arraycopy(this.source, this.startPosition + 1, (this.completionIdentifier = new char[length]), 0, length);
+			}
+			return this.completionIdentifier;
+		}
+	}
+	return super.getCurrentTokenSourceString();
+}
+protected int getNextToken0() throws InvalidInputException {
+
+	this.wasAcr = false;
+	this.unicodeCharSize = 0;
+	if (this.diet) {
+		jumpOverMethodBody();
+		this.diet = false;
+		return this.currentPosition > this.eofPosition ? TokenNameEOF : TokenNameRBRACE;
+	}
+	int whiteStart = 0;
+	try {
+		while (true) { //loop for jumping over comments
+			this.withoutUnicodePtr = 0;
+			//start with a new token (even comment written with unicode )
+
+			// ---------Consume white space and handles start position---------
+			whiteStart = this.currentPosition;
+			boolean isWhiteSpace, hasWhiteSpaces = false;
+			int offset = 0;
+			do {
+				this.startPosition = this.currentPosition;
+				boolean checkIfUnicode = false;
+				try {
+					checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+						&& (this.source[this.currentPosition] == 'u');
+				} catch(IndexOutOfBoundsException e) {
+					if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+						// reposition scanner in case we are interested by spaces as tokens
+						this.currentPosition--;
+						this.startPosition = whiteStart;
+						return TokenNameWHITESPACE;
+					}
+					if (this.currentPosition > this.eofPosition) {
+						/* might be completing at eof (e.g. behind a dot) */
+						if (this.completionIdentifier == null &&
+							this.startPosition == this.cursorLocation + 1){
+							this.currentPosition = this.startPosition; // for being detected as empty free identifier
+							return TokenNameIdentifier;
+						}
+						return TokenNameEOF;
+					}
+				}
+				if (checkIfUnicode) {
+					isWhiteSpace = jumpOverUnicodeWhiteSpace();
+					offset = 6;
+				} else {
+					offset = 1;
+					if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+						//checkNonExternalizedString();
+						if (this.recordLineSeparator) {
+							pushLineSeparator();
+						}
+					}
+					isWhiteSpace =
+						(this.currentCharacter == ' ') || CharOperation.isWhitespace(this.currentCharacter);
+				}
+				if (isWhiteSpace) {
+					hasWhiteSpaces = true;
+				}
+				/* completion requesting strictly inside blanks */
+				if ((whiteStart != this.currentPosition)
+					//&& (previousToken == TokenNameDOT)
+					&& (this.completionIdentifier == null)
+					&& (whiteStart <= this.cursorLocation+1)
+					&& (this.cursorLocation < this.startPosition)
+					&& !ScannerHelper.isJavaIdentifierStart(this.complianceLevel, this.currentCharacter)){
+					this.currentPosition = this.startPosition; // for next token read
+					return TokenNameIdentifier;
+				}
+			} while (isWhiteSpace);
+			if (this.tokenizeWhiteSpace && hasWhiteSpaces) {
+				// reposition scanner in case we are interested by spaces as tokens
+				this.currentPosition-=offset;
+				this.startPosition = whiteStart;
+				return TokenNameWHITESPACE;
+			}
+			//little trick to get out in the middle of a source computation
+			if (this.currentPosition > this.eofPosition){
+				/* might be completing at eof (e.g. behind a dot) */
+				if (this.completionIdentifier == null &&
+					this.startPosition == this.cursorLocation + 1){
+					// compute end of empty identifier.
+					// if the empty identifier is at the start of a next token the end of
+					// empty identifier is the end of the next token (e.g. "<empty token>next").
+					int temp = this.eofPosition;
+					this.eofPosition = this.source.length;
+				 	while(getNextCharAsJavaIdentifierPart()){/*empty*/}
+				 	this.eofPosition = temp;
+				 	this.endOfEmptyToken = this.currentPosition - 1;
+					this.currentPosition = this.startPosition; // for being detected as empty free identifier
+					return TokenNameIdentifier;
+				}
+				return TokenNameEOF;
+			}
+
+			// ---------Identify the next token-------------
+
+			switch (this.currentCharacter) {
+				case '@' :
+					return TokenNameAT;
+				case '(' :
+					return TokenNameLPAREN;
+				case ')' :
+					return TokenNameRPAREN;
+				case '{' :
+					return TokenNameLBRACE;
+				case '}' :
+					return TokenNameRBRACE;
+				case '[' :
+					return TokenNameLBRACKET;
+				case ']' :
+					return TokenNameRBRACKET;
+				case ';' :
+					return TokenNameSEMICOLON;
+				case ',' :
+					return TokenNameCOMMA;
+				case '.' :
+					if (this.startPosition <= this.cursorLocation
+							&& this.cursorLocation < this.currentPosition){
+						return TokenNameDOT; // completion inside .<|>12
+					}
+					if (getNextCharAsDigit()) {
+						return scanNumber(true);
+					}
+					int temp = this.currentPosition;
+					if (getNextChar('.')) {
+						if (getNextChar('.')) {
+							return TokenNameELLIPSIS;
+						} else {
+							this.currentPosition = temp;
+							return TokenNameDOT;
+						}
+					} else {
+						this.currentPosition = temp;
+						return TokenNameDOT;
+					}
+				case '+' :
+					{
+						int test;
+						if ((test = getNextChar('+', '=')) == 0)
+							return TokenNamePLUS_PLUS;
+						if (test > 0)
+							return TokenNamePLUS_EQUAL;
+						return TokenNamePLUS;
+					}
+				case '-' :
+					{
+						int test;
+						if ((test = getNextChar('-', '=')) == 0)
+							return TokenNameMINUS_MINUS;
+						if (test > 0)
+							return TokenNameMINUS_EQUAL;
+						if (getNextChar('>'))
+							return TokenNameARROW;
+						return TokenNameMINUS;
+					}
+				case '~' :
+					return TokenNameTWIDDLE;
+				case '!' :
+					if (getNextChar('='))
+						return TokenNameNOT_EQUAL;
+					return TokenNameNOT;
+				case '*' :
+					if (getNextChar('='))
+						return TokenNameMULTIPLY_EQUAL;
+					return TokenNameMULTIPLY;
+				case '%' :
+					if (getNextChar('='))
+						return TokenNameREMAINDER_EQUAL;
+					return TokenNameREMAINDER;
+				case '<' :
+					{
+						int test;
+						if ((test = getNextChar('=', '<')) == 0)
+							return TokenNameLESS_EQUAL;
+						if (test > 0) {
+							if (getNextChar('='))
+								return TokenNameLEFT_SHIFT_EQUAL;
+							return TokenNameLEFT_SHIFT;
+						}
+						return TokenNameLESS;
+					}
+				case '>' :
+					{
+						int test;
+						if (this.returnOnlyGreater) {
+							return TokenNameGREATER;
+						}
+						if ((test = getNextChar('=', '>')) == 0)
+							return TokenNameGREATER_EQUAL;
+						if (test > 0) {
+							if ((test = getNextChar('=', '>')) == 0)
+								return TokenNameRIGHT_SHIFT_EQUAL;
+							if (test > 0) {
+								if (getNextChar('='))
+									return TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL;
+								return TokenNameUNSIGNED_RIGHT_SHIFT;
+							}
+							return TokenNameRIGHT_SHIFT;
+						}
+						return TokenNameGREATER;
+					}
+				case '=' :
+					if (getNextChar('='))
+						return TokenNameEQUAL_EQUAL;
+					return TokenNameEQUAL;
+				case '&' :
+					{
+						int test;
+						if ((test = getNextChar('&', '=')) == 0)
+							return TokenNameAND_AND;
+						if (test > 0)
+							return TokenNameAND_EQUAL;
+						return TokenNameAND;
+					}
+				case '|' :
+					{
+						int test;
+						if ((test = getNextChar('|', '=')) == 0)
+							return TokenNameOR_OR;
+						if (test > 0)
+							return TokenNameOR_EQUAL;
+						return TokenNameOR;
+					}
+				case '^' :
+					if (getNextChar('='))
+						return TokenNameXOR_EQUAL;
+					return TokenNameXOR;
+				case '?' :
+					return TokenNameQUESTION;
+				case ':' :
+					if (getNextChar(':'))
+						return TokenNameCOLON_COLON;
+					return TokenNameCOLON;
+				case '\'' :
+					{
+						int test;
+						if ((test = getNextChar('\n', '\r')) == 0) {
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (test > 0) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\'') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+					}
+					if (getNextChar('\'')) {
+						// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+						for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+							if (this.currentPosition + lookAhead == this.eofPosition)
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\n')
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\'') {
+								this.currentPosition += lookAhead + 1;
+								break;
+							}
+						}
+						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+					}
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
+						scanEscapeCharacter();
+					} else { // consume next character
+						this.unicodeAsBackSlash = false;
+						boolean checkIfUnicode = false;
+						try {
+							checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u');
+						} catch(IndexOutOfBoundsException e) {
+							this.currentPosition--;
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (checkIfUnicode) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+							    unicodeStore();
+							}
+						}
+					}
+					if (getNextChar('\''))
+						return TokenNameCharacterLiteral;
+					// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+					for (int lookAhead = 0; lookAhead < 20; lookAhead++) {
+						if (this.currentPosition + lookAhead == this.eofPosition)
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\n')
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\'') {
+							this.currentPosition += lookAhead + 1;
+							break;
+						}
+					}
+					throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+				case '"' :
+					try {
+						// consume next character
+						this.unicodeAsBackSlash = false;
+						boolean isUnicode = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+							isUnicode = true;
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+							    unicodeStore();
+							}
+						}
+
+						while (this.currentCharacter != '"') {
+							/**** \r and \n are not valid in string literals ****/
+							if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) {
+								if (isUnicode) {
+									int start = this.currentPosition - 5;
+									while(this.source[start] != '\\') {
+										start--;
+									}
+									if(this.startPosition <= this.cursorLocation
+											&& this.cursorLocation <= this.currentPosition-1) {
+										this.currentPosition = start;
+										// complete inside a string literal
+										return TokenNameStringLiteral;
+									}
+									start = this.currentPosition;
+									for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+										if (this.currentPosition >= this.eofPosition) {
+											this.currentPosition = start;
+											break;
+										}
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											isUnicode = true;
+											getNextUnicodeChar();
+										} else {
+											isUnicode = false;
+										}
+										if (!isUnicode && this.currentCharacter == '\n') {
+											this.currentPosition--; // set current position on new line character
+											break;
+										}
+										if (this.currentCharacter == '\"') {
+											throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+										}
+									}
+								} else {
+									this.currentPosition--; // set current position on new line character
+									if(this.startPosition <= this.cursorLocation
+											&& this.cursorLocation <= this.currentPosition-1) {
+										// complete inside a string literal
+										return TokenNameStringLiteral;
+									}
+								}
+								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+							}
+							if (this.currentCharacter == '\\') {
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+										this.withoutUnicodePtr--;
+									} else {
+										isUnicode = false;
+									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+								isUnicode = true;
+							} else {
+								isUnicode = false;
+								if (this.withoutUnicodePtr != 0) {
+								    unicodeStore();
+								}
+							}
+
+						}
+					} catch (IndexOutOfBoundsException e) {
+						this.currentPosition--;
+						if(this.startPosition <= this.cursorLocation
+							&& this.cursorLocation < this.currentPosition) {
+							// complete inside a string literal
+							return TokenNameStringLiteral;
+						}
+						throw new InvalidInputException(UNTERMINATED_STRING);
+					} catch (InvalidInputException e) {
+						if (e.getMessage().equals(INVALID_ESCAPE)) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\"') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+
+						}
+						throw e; // rethrow
+					}
+					return TokenNameStringLiteral;
+				case '/' :
+					{
+						int test;
+						if ((test = getNextChar('/', '*')) == 0) { //line comment
+							this.lastCommentLinePosition = this.currentPosition;
+							try { //get the next char
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									//-------------unicode traitement ------------
+									int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+									this.currentPosition++;
+									while (this.source[this.currentPosition] == 'u') {
+										this.currentPosition++;
+									}
+									if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+										|| c1 < 0
+										|| (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+										|| c2 < 0
+										|| (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+										|| c3 < 0
+										|| (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+										|| c4 < 0) {
+										throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+									} else {
+										this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+									}
+								}
+
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								boolean isUnicode = false;
+								while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
+									this.lastCommentLinePosition = this.currentPosition;
+									//get the next char
+									isUnicode = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+										isUnicode = true;
+										//-------------unicode traitement ------------
+										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+										this.currentPosition++;
+										while (this.source[this.currentPosition] == 'u') {
+											this.currentPosition++;
+										}
+										if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+											|| c1 < 0
+											|| (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+											|| c2 < 0
+											|| (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+											|| c3 < 0
+											|| (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+											|| c4 < 0) {
+											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+										} else {
+											this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+										}
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								/*
+								 * We need to completely consume the line break
+								 */
+								if (this.currentCharacter == '\r'
+								   && this.eofPosition > this.currentPosition) {
+								   	if (this.source[this.currentPosition] == '\n') {
+										this.currentPosition++;
+										this.currentCharacter = '\n';
+								   	} else if ((this.source[this.currentPosition] == '\\')
+										&& (this.source[this.currentPosition + 1] == 'u')) {
+										isUnicode = true;
+										char unicodeChar;
+										int index = this.currentPosition + 1;
+										index++;
+										while (this.source[index] == 'u') {
+											index++;
+										}
+										//-------------unicode traitement ------------
+										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+										if ((c1 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15
+											|| c1 < 0
+											|| (c2 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15
+											|| c2 < 0
+											|| (c3 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15
+											|| c3 < 0
+											|| (c4 = ScannerHelper.getHexadecimalValue(this.source[index++])) > 15
+											|| c4 < 0) {
+											this.currentPosition = index;
+											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+										} else {
+											unicodeChar = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+										}
+										if (unicodeChar == '\n') {
+											this.currentPosition = index;
+											this.currentCharacter = '\n';
+										}
+									}
+							   	}
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.startPosition <= this.cursorLocation && this.cursorLocation < this.currentPosition-1){
+									throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_COMMENT);
+								}
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									//checkNonExternalizedString();
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								} else {
+									this.currentPosition++;
+								}
+							}
+							break;
+						}
+						if (test > 0) { //traditional and javadoc comment
+							try { //get the next char
+								boolean isJavadoc = false, star = false;
+								boolean isUnicode = false;
+								int previous;
+								// consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+									if (this.withoutUnicodePtr != 0) {
+									    unicodeStore();
+									}
+								}
+
+								if (this.currentCharacter == '*') {
+									isJavadoc = true;
+									star = true;
+								}
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									//checkNonExternalizedString();
+									if (this.recordLineSeparator) {
+										if (!isUnicode) {
+											pushLineSeparator();
+										}
+									}
+								}
+								isUnicode = false;
+								previous = this.currentPosition;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									//-------------unicode traitement ------------
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								// empty comment is not a javadoc /**/
+								if (this.currentCharacter == '/') {
+									isJavadoc = false;
+								}
+								//loop until end of comment */
+								int firstTag = 0;
+								while ((this.currentCharacter != '/') || (!star)) {
+									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+										//checkNonExternalizedString();
+										if (this.recordLineSeparator) {
+											if (!isUnicode) {
+												pushLineSeparator();
+											}
+										}
+									}									
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0 && this.isFirstTag()) {
+												firstTag = previous;
+											}
+											//$FALL-THROUGH$ default case to set star to false
+										default:
+											star = false;
+									}
+ 									//get next char
+									previous = this.currentPosition;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+										//-------------unicode traitement ------------
+										getNextUnicodeChar();
+										isUnicode = true;
+									} else {
+										isUnicode = false;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
+								recordComment(token);
+								this.commentTagStarts[this.commentPtr] = firstTag;
+								if (!isJavadoc && this.startPosition <= this.cursorLocation && this.cursorLocation < this.currentPosition-1){
+									throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_COMMENT);
+								}
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.tokenizeComments) {
+									/*
+									if (isJavadoc)
+										return TokenNameCOMMENT_JAVADOC;
+									return TokenNameCOMMENT_BLOCK;
+									*/
+									return token;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								throw new InvalidInputException(UNTERMINATED_COMMENT);
+							}
+							break;
+						}
+						if (getNextChar('='))
+							return TokenNameDIVIDE_EQUAL;
+						return TokenNameDIVIDE;
+					}
+				case '\u001a' :
+					if (atEnd())
+						return TokenNameEOF;
+					//the atEnd may not be <this.currentPosition == this.source.length> if source is only some part of a real (external) stream
+					throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
+
+				default :
+					char c = this.currentCharacter;
+					if (c < ScannerHelper.MAX_OBVIOUS) {
+						if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+							return scanIdentifierOrKeyword();
+						} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
+								return scanNumber(false);
+						} else {
+							return TokenNameERROR;
+						}
+					}
+					boolean isJavaIdStart;
+					if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						// Unicode 4 detection
+						char low = (char) getNextChar();
+						if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+							// illegal low surrogate
+							throw new InvalidInputException(INVALID_LOW_SURROGATE);
+						}
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+					}
+					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+					} else {
+						// optimized case already checked
+						isJavaIdStart = Character.isJavaIdentifierStart(c);
+					}
+					if (isJavaIdStart)
+						return scanIdentifierOrKeyword();
+					if (ScannerHelper.isDigit(this.currentCharacter)) {
+						return scanNumber(false);
+					}
+					return TokenNameERROR;
+			}
+		}
+	} //-----------------end switch while try--------------------
+	catch (IndexOutOfBoundsException e) {
+		if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+			// reposition scanner in case we are interested by spaces as tokens
+			this.currentPosition--;
+			this.startPosition = whiteStart;
+			return TokenNameWHITESPACE;
+		}
+	}
+	/* might be completing at very end of file (e.g. behind a dot) */
+	if (this.completionIdentifier == null &&
+		this.startPosition == this.cursorLocation + 1){
+		this.currentPosition = this.startPosition; // for being detected as empty free identifier
+		return TokenNameIdentifier;
+	}
+	return TokenNameEOF;
+}
+public final void getNextUnicodeChar() throws InvalidInputException {
+	int temp = this.currentPosition; // the \ is already read
+	super.getNextUnicodeChar();
+	if(this.cursorLocation > temp) {
+		this.unicodeCharSize += (this.currentPosition - temp);
+	}
+	if (temp < this.cursorLocation && this.cursorLocation < this.currentPosition-1){
+		throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_UNICODE);
+	}
+}
+protected boolean isFirstTag() {
+	return
+		getNextChar('d') &&
+		getNextChar('e') &&
+		getNextChar('p') &&
+		getNextChar('r') &&
+		getNextChar('e') &&
+		getNextChar('c') &&
+		getNextChar('a') &&
+		getNextChar('t') &&
+		getNextChar('e') &&
+		getNextChar('d');
+}
+public final void jumpOverBlock() {
+	jumpOverMethodBody();
+}
+///*
+// * In case we actually read a keyword, but the cursor is located inside,
+// * we pretend we read an identifier.
+// */
+public int scanIdentifierOrKeyword() {
+
+	int id = super.scanIdentifierOrKeyword();
+
+	if (this.startPosition <= this.cursorLocation+1
+			&& this.cursorLocation < this.currentPosition){
+
+		// extends the end of the completion token even if the end is after eofPosition
+		if (this.cursorLocation+1 == this.eofPosition) {
+			int temp = this.eofPosition;
+			this.eofPosition = this.source.length;
+		 	while(getNextCharAsJavaIdentifierPart()){/*empty*/}
+			this.eofPosition = temp;
+		}
+		// convert completed keyword into an identifier
+		return TokenNameIdentifier;
+	}
+	return id;
+}
+
+public int scanNumber(boolean dotPrefix) throws InvalidInputException {
+
+	int token = super.scanNumber(dotPrefix);
+
+	// consider completion just before a number to be ok, will insert before it
+	if (this.startPosition <= this.cursorLocation && this.cursorLocation < this.currentPosition){
+		throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_NUMBER);
+	}
+	return token;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java
new file mode 100644
index 0000000..6180e2d
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+/**
+ * Thrown whenever cursor location is not inside a consistent token
+ * for example: inside a string, number, unicode, comments etc...
+ */
+public class InvalidCursorLocation extends RuntimeException {
+
+	public String irritant;
+
+	/* Possible irritants */
+	public static final String NO_COMPLETION_INSIDE_UNICODE = "No Completion Inside Unicode"; //$NON-NLS-1$
+	public static final String NO_COMPLETION_INSIDE_COMMENT = "No Completion Inside Comment";      //$NON-NLS-1$
+	public static final String NO_COMPLETION_INSIDE_STRING = "No Completion Inside String";        //$NON-NLS-1$
+	public static final String NO_COMPLETION_INSIDE_NUMBER = "No Completion Inside Number";        //$NON-NLS-1$
+
+	private static final long serialVersionUID = -3443160725735779590L; // backward compatible
+
+public InvalidCursorLocation(String irritant){
+	this.irritant = irritant;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistAnnotation.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistAnnotation.java
new file mode 100644
index 0000000..bf7e0cb
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistAnnotation.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.Annotation;
+import org.eclipse.jdt.internal.core.JavaElement;
+
+public class AssistAnnotation extends Annotation {
+	private Map infoCache;
+	public AssistAnnotation(JavaElement parent, String name, Map infoCache) {
+		super(parent, name);
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistCompilationUnit.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistCompilationUnit.java
new file mode 100644
index 0000000..fbee0b0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistCompilationUnit.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportContainer;
+import org.eclipse.jdt.core.IPackageDeclaration;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.JavaElementInfo;
+import org.eclipse.jdt.internal.core.PackageFragment;
+
+public class AssistCompilationUnit extends CompilationUnit {
+	private Map infoCache;
+	private Map bindingCache;
+	public AssistCompilationUnit(ICompilationUnit compilationUnit, WorkingCopyOwner owner, Map bindingCache, Map infoCache) {
+		super((PackageFragment)compilationUnit.getParent(), compilationUnit.getElementName(), owner);
+		this.bindingCache = bindingCache;
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	public IImportContainer getImportContainer() {
+		return new AssistImportContainer(this, this.infoCache);
+	}
+
+	public IPackageDeclaration getPackageDeclaration(String pkg) {
+		return new AssistPackageDeclaration(this, pkg, this.infoCache);
+	}
+
+	public IType getType(String typeName) {
+		return new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+	}
+
+	public boolean hasChildren() throws JavaModelException {
+		JavaElementInfo info = (JavaElementInfo)this.infoCache.get(this);
+		return info.getChildren().length > 0;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportContainer.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportContainer.java
new file mode 100644
index 0000000..79fc771
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportContainer.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.ImportContainer;
+
+public class AssistImportContainer extends ImportContainer {
+	private Map infoCache;
+	public AssistImportContainer(CompilationUnit parent, Map infoCache) {
+		super(parent);
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	protected IImportDeclaration getImport(String importName, boolean isOnDemand) {
+		return new AssistImportDeclaration(this, importName, isOnDemand, this.infoCache);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportDeclaration.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportDeclaration.java
new file mode 100644
index 0000000..2d7e217
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistImportDeclaration.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.ImportContainer;
+import org.eclipse.jdt.internal.core.ImportDeclaration;
+
+public class AssistImportDeclaration extends ImportDeclaration {
+	private Map infoCache;
+	public AssistImportDeclaration(ImportContainer parent, String name, boolean isOnDemand, Map infoCache) {
+		super(parent, name, isOnDemand);
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistInitializer.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistInitializer.java
new file mode 100644
index 0000000..11e0651
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistInitializer.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.Initializer;
+import org.eclipse.jdt.internal.core.JavaElement;
+
+public class AssistInitializer extends Initializer {
+	private Map bindingCache;
+	private Map infoCache;
+	public AssistInitializer(JavaElement parent, int count, Map bindingCache, Map infoCache) {
+		super(parent, count);
+		this.bindingCache = bindingCache;
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	public IType getType(String typeName, int count) {
+		AssistSourceType type = new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+		type.occurrenceCount = count;
+		return type;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
new file mode 100644
index 0000000..6da6374
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class AssistOptions {
+	/**
+	 * Option IDs
+	 */
+	public static final String OPTION_PerformVisibilityCheck =
+		"org.eclipse.jdt.core.codeComplete.visibilityCheck"; 	//$NON-NLS-1$
+	public static final String OPTION_PerformDeprecationCheck =
+		"org.eclipse.jdt.core.codeComplete.deprecationCheck"; 	//$NON-NLS-1$
+	public static final String OPTION_ForceImplicitQualification =
+		"org.eclipse.jdt.core.codeComplete.forceImplicitQualification"; 	//$NON-NLS-1$
+	public static final String OPTION_FieldPrefixes =
+		"org.eclipse.jdt.core.codeComplete.fieldPrefixes"; 	//$NON-NLS-1$
+	public static final String OPTION_StaticFieldPrefixes =
+		"org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"; 	//$NON-NLS-1$
+	public static final String OPTION_StaticFinalFieldPrefixes =
+		"org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes"; 	//$NON-NLS-1$
+	public static final String OPTION_LocalPrefixes =
+		"org.eclipse.jdt.core.codeComplete.localPrefixes"; 	//$NON-NLS-1$
+	public static final String OPTION_ArgumentPrefixes =
+		"org.eclipse.jdt.core.codeComplete.argumentPrefixes"; 	//$NON-NLS-1$
+	public static final String OPTION_FieldSuffixes =
+		"org.eclipse.jdt.core.codeComplete.fieldSuffixes"; 	//$NON-NLS-1$
+	public static final String OPTION_StaticFieldSuffixes =
+		"org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"; 	//$NON-NLS-1$
+	public static final String OPTION_StaticFinalFieldSuffixes =
+		"org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes"; 	//$NON-NLS-1$
+	public static final String OPTION_LocalSuffixes =
+		"org.eclipse.jdt.core.codeComplete.localSuffixes"; 	//$NON-NLS-1$
+	public static final String OPTION_ArgumentSuffixes =
+		"org.eclipse.jdt.core.codeComplete.argumentSuffixes"; 	//$NON-NLS-1$
+	public static final String OPTION_PerformForbiddenReferenceCheck =
+		"org.eclipse.jdt.core.codeComplete.forbiddenReferenceCheck"; 	//$NON-NLS-1$
+	public static final String OPTION_PerformDiscouragedReferenceCheck =
+		"org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"; 	//$NON-NLS-1$
+	public static final String OPTION_CamelCaseMatch =
+		"org.eclipse.jdt.core.codeComplete.camelCaseMatch"; 	//$NON-NLS-1$
+	public static final String OPTION_SuggestStaticImports =
+		"org.eclipse.jdt.core.codeComplete.suggestStaticImports"; 	//$NON-NLS-1$
+
+	public static final String ENABLED = "enabled"; //$NON-NLS-1$
+	public static final String DISABLED = "disabled"; //$NON-NLS-1$
+
+	public boolean checkVisibility = false;
+	public boolean checkDeprecation = false;
+	public boolean checkForbiddenReference = false;
+	public boolean checkDiscouragedReference = false;
+	public boolean forceImplicitQualification = false;
+	public boolean camelCaseMatch = true;
+	public boolean suggestStaticImport = true;
+	public char[][] fieldPrefixes = null;
+	public char[][] staticFieldPrefixes = null;
+	public char[][] staticFinalFieldPrefixes = null;
+	public char[][] localPrefixes = null;
+	public char[][] argumentPrefixes = null;
+	public char[][] fieldSuffixes = null;
+	public char[][] staticFieldSuffixes = null;
+	public char[][] staticFinalFieldSuffixes = null;
+	public char[][] localSuffixes = null;
+	public char[][] argumentSuffixes = null;
+
+	/**
+	 * Initializing the assist options with default settings
+	 */
+	public AssistOptions() {
+		// Initializing the assist options with default settings
+	}
+
+	/**
+	 * Initializing the assist options with external settings
+	 */
+	public AssistOptions(Map settings) {
+		if (settings == null)
+			return;
+
+		set(settings);
+	}
+	public void set(Map optionsMap) {
+
+		Object optionValue;
+		if ((optionValue = optionsMap.get(OPTION_PerformVisibilityCheck)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.checkVisibility = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.checkVisibility = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ForceImplicitQualification)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.forceImplicitQualification = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.forceImplicitQualification = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_FieldPrefixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.fieldPrefixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.fieldPrefixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_StaticFieldPrefixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.staticFieldPrefixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.staticFieldPrefixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_StaticFinalFieldPrefixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.staticFinalFieldPrefixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.staticFinalFieldPrefixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_LocalPrefixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.localPrefixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.localPrefixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ArgumentPrefixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.argumentPrefixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.argumentPrefixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_FieldSuffixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.fieldSuffixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.fieldSuffixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_StaticFieldSuffixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.staticFieldSuffixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.staticFieldSuffixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_StaticFinalFieldSuffixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.staticFinalFieldSuffixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.staticFinalFieldSuffixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_LocalSuffixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.localSuffixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.localSuffixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ArgumentSuffixes)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					this.argumentSuffixes = splitAndTrimOn(',', stringValue.toCharArray());
+				} else {
+					this.argumentSuffixes = null;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_PerformForbiddenReferenceCheck)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.checkForbiddenReference = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.checkForbiddenReference = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_PerformDiscouragedReferenceCheck)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.checkDiscouragedReference = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.checkDiscouragedReference = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_CamelCaseMatch)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.camelCaseMatch = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.camelCaseMatch = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_PerformDeprecationCheck)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.checkDeprecation = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.checkDeprecation = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_SuggestStaticImports)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.suggestStaticImport = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.suggestStaticImport = false;
+			}
+		}
+	}
+
+	private char[][] splitAndTrimOn(char divider, char[] arrayToSplit) {
+		char[][] result = CharOperation.splitAndTrimOn(',', arrayToSplit);
+
+		int length = result.length;
+
+		int resultCount = 0;
+		for (int i = 0; i < length; i++) {
+			if(result[i].length != 0) {
+				result[resultCount++] = result[i];
+			}
+		}
+		if(resultCount != length) {
+			System.arraycopy(result, 0, result = new char[resultCount][], 0, resultCount);
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistPackageDeclaration.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistPackageDeclaration.java
new file mode 100644
index 0000000..00a4f77
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistPackageDeclaration.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.PackageDeclaration;
+
+public class AssistPackageDeclaration extends PackageDeclaration {
+	private Map infoCache;
+	public AssistPackageDeclaration(CompilationUnit parent, String name, Map infoCache) {
+		super(parent, name);
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	public IAnnotation getAnnotation(String name) {
+		return new AssistAnnotation(this, name, this.infoCache);
+	}
+}
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
new file mode 100644
index 0000000..c2cbaaa
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -0,0 +1,1764 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+/*
+ * Parser extension for code assist task
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredBlock;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredElement;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredField;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredInitializer;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredMethod;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredType;
+import org.eclipse.jdt.internal.compiler.parser.RecoveredUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+public abstract class AssistParser extends Parser {
+	public ASTNode assistNode;
+	public boolean isOrphanCompletionNode;
+	// last modifiers info
+	protected int lastModifiers = ClassFileConstants.AccDefault;
+	protected int lastModifiersStart = -1;
+	/* recovery */
+	int[] blockStarts = new int[30];
+
+	// the previous token read by the scanner
+	protected int previousToken;
+
+	// the index in the identifier stack of the previous identifier
+	protected int previousIdentifierPtr;
+	
+	// depth of '(', '{' and '[]'
+	protected int bracketDepth;
+
+	// element stack
+	protected static final int ElementStackIncrement = 100;
+	protected int elementPtr;
+	protected int[] elementKindStack = new int[ElementStackIncrement];
+	protected int[] elementInfoStack = new int[ElementStackIncrement];
+	protected Object[] elementObjectInfoStack = new Object[ElementStackIncrement];
+	protected int previousKind;
+	protected int previousInfo;
+	protected Object previousObjectInfo;
+
+	// OWNER
+	protected static final int ASSIST_PARSER = 512;
+
+	// KIND : all values known by AssistParser are between 513 and 1023
+	protected static final int K_SELECTOR = ASSIST_PARSER + 1; // whether we are inside a message send
+	protected static final int K_TYPE_DELIMITER = ASSIST_PARSER + 2; // whether we are inside a type declaration
+	protected static final int K_METHOD_DELIMITER = ASSIST_PARSER + 3; // whether we are inside a method declaration
+	protected static final int K_FIELD_INITIALIZER_DELIMITER = ASSIST_PARSER + 4; // whether we are inside a field initializer
+	protected static final int K_ATTRIBUTE_VALUE_DELIMITER = ASSIST_PARSER + 5; // whether we are inside a annotation attribute valuer
+	protected static final int K_ENUM_CONSTANT_DELIMITER = ASSIST_PARSER + 6; // whether we are inside a field initializer
+
+	// selector constants
+	protected static final int THIS_CONSTRUCTOR = -1;
+	protected static final int SUPER_CONSTRUCTOR = -2;
+
+	// enum constant constants
+	protected static final int NO_BODY = 0;
+	protected static final int WITH_BODY = 1;
+
+	protected boolean isFirst = false;
+
+public AssistParser(ProblemReporter problemReporter) {
+	super(problemReporter, true);
+	this.javadocParser.checkDocComment = false;
+
+	setMethodsFullRecovery(false);
+	setStatementsRecovery(false);
+}
+public abstract char[] assistIdentifier();
+
+/**
+ * The parser become a simple parser which behave like a Parser
+ * @return the state of the assist parser to be able to restore the assist parser state
+ */
+public Object becomeSimpleParser() {
+	return null;
+}
+/**
+ * Restore the parser as an assist parser
+ * @param parserState
+ */
+public void restoreAssistParser(Object parserState) {
+	//Do nothing
+}
+public int bodyEnd(AbstractMethodDeclaration method){
+	return method.bodyEnd;
+}
+public int bodyEnd(Initializer initializer){
+	return initializer.declarationSourceEnd;
+}
+/*
+ * Build initial recovery state.
+ * Recovery state is inferred from the current state of the parser (reduced node stack).
+ */
+public RecoveredElement buildInitialRecoveryState(){
+	/* recovery in unit structure */
+	if (this.referenceContext instanceof CompilationUnitDeclaration){
+		RecoveredElement element = super.buildInitialRecoveryState();
+		flushAssistState();
+		flushElementStack();
+		return element;
+	}
+
+	/* recovery in method body */
+	this.lastCheckPoint = 0;
+
+	RecoveredElement element = null;
+	if (this.referenceContext instanceof AbstractMethodDeclaration){
+		element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
+		this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
+	} else {
+		/* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
+		if (this.referenceContext instanceof TypeDeclaration){
+			TypeDeclaration type = (TypeDeclaration) this.referenceContext;
+			FieldDeclaration[] fields = type.fields;
+			int length = fields == null ? 0 : fields.length;
+			for (int i = 0; i < length; i++){
+				FieldDeclaration field = fields[i];
+				if (field != null
+						&& field.getKind() == AbstractVariableDeclaration.INITIALIZER
+						&& field.declarationSourceStart <= this.scanner.initialPosition
+						&& this.scanner.initialPosition <= field.declarationSourceEnd
+						&& this.scanner.eofPosition <= field.declarationSourceEnd+1){
+					element = new RecoveredInitializer(field, null, 1, this);
+					this.lastCheckPoint = field.declarationSourceStart;
+					break;
+				}
+			}
+		}
+	}
+
+	if (element == null) return element;
+
+	/* add initial block */
+	Block block = new Block(0);
+	int lastStart = this.blockStarts[0];
+	block.sourceStart = lastStart;
+	element = element.add(block, 1);
+	int blockIndex = 1;	// ignore first block start, since manually rebuilt here
+
+	for(int i = 0; i <= this.astPtr; i++){
+		ASTNode node = this.astStack[i];
+
+		if(node instanceof ForeachStatement && ((ForeachStatement)node).action == null) {
+			node = ((ForeachStatement)node).elementVariable;
+		}
+
+		/* check for intermediate block creation, so recovery can properly close them afterwards */
+		int nodeStart = node.sourceStart;
+		for (int j = blockIndex; j <= this.realBlockPtr; j++){
+			if (this.blockStarts[j] >= 0) {
+				if (this.blockStarts[j] > nodeStart){
+					blockIndex = j; // shift the index to the new block
+					break;
+				}
+				if (this.blockStarts[j] != lastStart){ // avoid multiple block if at same position
+					block = new Block(0);
+					block.sourceStart = lastStart = this.blockStarts[j];
+					element = element.add(block, 1);
+				}
+			} else {
+				if (-this.blockStarts[j] > nodeStart){
+					blockIndex = j; // shift the index to the new block
+					break;
+				}
+				block = new Block(0);
+				block.sourceStart = lastStart = -this.blockStarts[j];
+				element = element.add(block, 1);
+			}
+			blockIndex = j+1; // shift the index to the new block
+		}
+		if (node instanceof LocalDeclaration){
+			LocalDeclaration local = (LocalDeclaration) node;
+			if (local.declarationSourceEnd == 0){
+				element = element.add(local, 0);
+				if (local.initialization == null){
+					this.lastCheckPoint = local.sourceEnd + 1;
+				} else {
+					this.lastCheckPoint = local.initialization.sourceEnd + 1;
+				}
+			} else {
+				element = element.add(local, 0);
+				this.lastCheckPoint = local.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof AbstractMethodDeclaration){
+			AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
+			if (method.declarationSourceEnd == 0){
+				element = element.add(method, 0);
+				this.lastCheckPoint = method.bodyStart;
+			} else {
+				element = element.add(method, 0);
+				this.lastCheckPoint = method.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof Initializer){
+			Initializer initializer = (Initializer) node;
+			if (initializer.declarationSourceEnd == 0){
+				element = element.add(initializer, 1);
+				this.lastCheckPoint = initializer.sourceStart;
+			} else {
+				element = element.add(initializer, 0);
+				this.lastCheckPoint = initializer.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof FieldDeclaration){
+			FieldDeclaration field = (FieldDeclaration) node;
+			if (field.declarationSourceEnd == 0){
+				element = element.add(field, 0);
+				if (field.initialization == null){
+					this.lastCheckPoint = field.sourceEnd + 1;
+				} else {
+					this.lastCheckPoint = field.initialization.sourceEnd + 1;
+				}
+			} else {
+				element = element.add(field, 0);
+				this.lastCheckPoint = field.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof TypeDeclaration){
+			TypeDeclaration type = (TypeDeclaration) node;
+			if (type.declarationSourceEnd == 0){
+				element = element.add(type, 0);
+				this.lastCheckPoint = type.bodyStart;
+			} else {
+				element = element.add(type, 0);
+				this.lastCheckPoint = type.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof ImportReference){
+			ImportReference importRef = (ImportReference) node;
+			element = element.add(importRef, 0);
+			this.lastCheckPoint = importRef.declarationSourceEnd + 1;
+		}
+	}
+	if (this.currentToken == TokenNameRBRACE) {
+		this.currentToken = 0; // closing brace has already been taken care of
+	}
+
+	/* might need some extra block (after the last reduced node) */
+	int pos = this.assistNode == null ? this.lastCheckPoint : this.assistNode.sourceStart;
+	for (int j = blockIndex; j <= this.realBlockPtr; j++){
+		if (this.blockStarts[j] >= 0) {
+			if ((this.blockStarts[j] < pos) && (this.blockStarts[j] != lastStart)){ // avoid multiple block if at same position
+				block = new Block(0);
+				block.sourceStart = lastStart = this.blockStarts[j];
+				element = element.add(block, 1);
+			}
+		} else {
+			if ((this.blockStarts[j] < pos)){ // avoid multiple block if at same position
+				block = new Block(0);
+				block.sourceStart = lastStart = -this.blockStarts[j];
+				element = element.add(block, 1);
+			}
+		}
+	}
+
+	return element;
+}
+protected void consumeAnnotationTypeDeclarationHeader() {
+	super.consumeAnnotationTypeDeclarationHeader();
+	pushOnElementStack(K_TYPE_DELIMITER);
+}
+protected void consumeClassBodyDeclaration() {
+	popElement(K_METHOD_DELIMITER);
+	super.consumeClassBodyDeclaration();
+}
+protected void consumeClassBodyopt() {
+	super.consumeClassBodyopt();
+	popElement(K_SELECTOR);
+}
+protected void consumeClassHeader() {
+	super.consumeClassHeader();
+	pushOnElementStack(K_TYPE_DELIMITER);
+}
+protected void consumeConstructorBody() {
+	super.consumeConstructorBody();
+	popElement(K_METHOD_DELIMITER);
+}
+protected void consumeConstructorHeader() {
+	super.consumeConstructorHeader();
+	pushOnElementStack(K_METHOD_DELIMITER);
+}
+protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
+	super.consumeEnhancedForStatementHeaderInit(hasModifiers);
+
+	if (this.currentElement != null) {
+		LocalDeclaration localDecl = ((ForeachStatement)this.astStack[this.astPtr]).elementVariable;
+		this.lastCheckPoint = localDecl.sourceEnd + 1;
+		this.currentElement = this.currentElement.add(localDecl, 0);
+	}
+}
+protected void consumeEnterAnonymousClassBody(boolean qualified) {
+	super.consumeEnterAnonymousClassBody(qualified);
+	popElement(K_SELECTOR);
+	pushOnElementStack(K_TYPE_DELIMITER);
+}
+protected void consumeEnterMemberValue() {
+	super.consumeEnterMemberValue();
+	pushOnElementStack(K_ATTRIBUTE_VALUE_DELIMITER, this.identifierPtr);
+}
+protected void consumeEnumConstantHeader() {
+	if(this.currentToken == TokenNameLBRACE) {
+		popElement(K_ENUM_CONSTANT_DELIMITER);
+		pushOnElementStack(K_ENUM_CONSTANT_DELIMITER, WITH_BODY);
+		pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+		pushOnElementStack(K_TYPE_DELIMITER);
+	}
+	super.consumeEnumConstantHeader();
+}
+protected void consumeEnumConstantHeaderName() {
+	super.consumeEnumConstantHeaderName();
+	pushOnElementStack(K_ENUM_CONSTANT_DELIMITER);
+}
+protected void consumeEnumConstantWithClassBody() {
+	popElement(K_TYPE_DELIMITER);
+	popElement(K_FIELD_INITIALIZER_DELIMITER);
+	popElement(K_ENUM_CONSTANT_DELIMITER);
+	super.consumeEnumConstantWithClassBody();
+}
+protected void consumeEnumConstantNoClassBody() {
+	popElement(K_ENUM_CONSTANT_DELIMITER);
+	super.consumeEnumConstantNoClassBody();
+}
+protected void consumeEnumHeader() {
+	super.consumeEnumHeader();
+	pushOnElementStack(K_TYPE_DELIMITER);
+}
+protected void consumeExitMemberValue() {
+	super.consumeExitMemberValue();
+	popElement(K_ATTRIBUTE_VALUE_DELIMITER);
+}
+protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
+	super.consumeExplicitConstructorInvocation(flag, recFlag);
+	popElement(K_SELECTOR);
+}
+protected void consumeForceNoDiet() {
+	super.consumeForceNoDiet();
+	// if we are not in a method (i.e. we are not in a local variable initializer)
+	// then we are entering a field initializer
+	if (!isInsideMethod()) {
+		if(topKnownElementKind(ASSIST_PARSER) != K_ENUM_CONSTANT_DELIMITER) {
+			if(topKnownElementKind(ASSIST_PARSER, 2) != K_ENUM_CONSTANT_DELIMITER) {
+				pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+			}
+		} else {
+			int info = topKnownElementInfo(ASSIST_PARSER);
+			if(info != NO_BODY) {
+				pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+			}
+		}
+
+	}
+}
+protected void consumeInterfaceHeader() {
+	super.consumeInterfaceHeader();
+	pushOnElementStack(K_TYPE_DELIMITER);
+}
+protected void consumeMethodBody() {
+	super.consumeMethodBody();
+	popElement(K_METHOD_DELIMITER);
+}
+protected void consumeMethodDeclaration(boolean isNotAbstract) {
+	if (!isNotAbstract) {
+		popElement(K_METHOD_DELIMITER);
+	}
+	super.consumeMethodDeclaration(isNotAbstract);
+}
+protected void consumeMethodHeader() {
+	super.consumeMethodHeader();
+	pushOnElementStack(K_METHOD_DELIMITER);
+}
+protected void consumeMethodInvocationName() {
+	super.consumeMethodInvocationName();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	super.consumeMethodInvocationNameWithTypeArguments();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeMethodInvocationPrimary() {
+	super.consumeMethodInvocationPrimary();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+	super.consumeMethodInvocationPrimaryWithTypeArguments();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeMethodInvocationSuper() {
+	super.consumeMethodInvocationSuper();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	super.consumeMethodInvocationSuperWithTypeArguments();
+	popElement(K_SELECTOR);
+	MessageSend messageSend = (MessageSend)this.expressionStack[this.expressionPtr];
+	if (messageSend == this.assistNode){
+		this.lastCheckPoint = messageSend.sourceEnd + 1;
+	}
+}
+protected void consumeNestedMethod() {
+	super.consumeNestedMethod();
+	if(!isInsideMethod()) pushOnElementStack(K_METHOD_DELIMITER);
+}
+protected void consumeOpenBlock() {
+	// OpenBlock ::= $empty
+
+	super.consumeOpenBlock();
+	int stackLength = this.blockStarts.length;
+	if (this.realBlockPtr >= stackLength) {
+		System.arraycopy(
+			this.blockStarts, 0,
+			this.blockStarts = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.blockStarts[this.realBlockPtr] = this.scanner.startPosition;
+}
+protected void consumeOpenFakeBlock() {
+	// OpenBlock ::= $empty
+
+	super.consumeOpenBlock();
+	int stackLength = this.blockStarts.length;
+	if (this.realBlockPtr >= stackLength) {
+		System.arraycopy(
+			this.blockStarts, 0,
+			this.blockStarts = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.blockStarts[this.realBlockPtr] = -this.scanner.startPosition;
+}
+protected void consumePackageDeclarationName() {
+	// PackageDeclarationName ::= 'package' Name
+	/* build an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumePackageDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist node on package statement */
+	ImportReference reference = createAssistPackageReference(subset, positions);
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+	this.compilationUnit.currentPackage = reference;
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush comments defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumePackageDeclarationNameWithModifiers() {
+	// PackageDeclarationName ::= Modifiers 'package' PushRealModifiers Name
+	/* build an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumePackageDeclarationNameWithModifiers();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	this.intPtr--; // we don't need the modifiers start
+	this.intPtr--; // we don't need the package modifiers
+	ImportReference reference = createAssistPackageReference(subset, positions);
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			reference.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	/* build specific assist node on package statement */
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+	this.compilationUnit.currentPackage = reference;
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush comments defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeRestoreDiet() {
+	super.consumeRestoreDiet();
+	// if we are not in a method (i.e. we were not in a local variable initializer)
+	// then we are exiting a field initializer
+	if (!isInsideMethod()) {
+		popElement(K_FIELD_INITIALIZER_DELIMITER);
+	}
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' 'static' Name
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeSingleStaticImportDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist node on import statement */
+	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccStatic);
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush annotations defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeSingleTypeImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' Name
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeSingleTypeImportDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist node on import statement */
+	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccDefault);
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush comments defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' 'static' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeStaticImportOnDemandDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* 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;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush annotations defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeStaticInitializer() {
+	super.consumeStaticInitializer();
+	popElement(K_METHOD_DELIMITER);
+}
+protected void consumeStaticOnly() {
+	super.consumeStaticOnly();
+	pushOnElementStack(K_METHOD_DELIMITER);
+}
+protected void consumeToken(int token) {
+	super.consumeToken(token);
+
+	if(this.isFirst) {
+		this.isFirst = false;
+		return;
+	}
+	// register message send selector only if inside a method or if looking at a field initializer
+	// and if the current token is an open parenthesis
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue()) {
+		switch (token) {
+			case TokenNameLPAREN :
+				this.bracketDepth++;
+				switch (this.previousToken) {
+					case TokenNameIdentifier:
+						this.pushOnElementStack(K_SELECTOR, this.identifierPtr);
+						break;
+					case TokenNamethis: // explicit constructor invocation, e.g. this(1, 2)
+						this.pushOnElementStack(K_SELECTOR, THIS_CONSTRUCTOR);
+						break;
+					case TokenNamesuper: // explicit constructor invocation, e.g. super(1, 2)
+						this.pushOnElementStack(K_SELECTOR, SUPER_CONSTRUCTOR);
+						break;
+					case TokenNameGREATER: // explicit constructor invocation, e.g. Fred<X>[(]1, 2)
+					case TokenNameRIGHT_SHIFT: // or fred<X<X>>[(]1, 2)
+					case TokenNameUNSIGNED_RIGHT_SHIFT: //or Fred<X<X<X>>>[(]1, 2)
+						if(this.identifierPtr > -1) {
+							this.pushOnElementStack(K_SELECTOR, this.identifierPtr);
+						}
+						break;
+				}
+				break;
+			case TokenNameLBRACE:
+				this.bracketDepth++;
+				break;
+			case TokenNameLBRACKET:
+				this.bracketDepth++;
+				break;
+			case TokenNameRBRACE:
+				this.bracketDepth--;
+				break;
+			case TokenNameRBRACKET:
+				this.bracketDepth--;
+				break;
+			case TokenNameRPAREN:
+				this.bracketDepth--;
+				break;
+		}
+	} else {
+		switch (token) {
+			case TokenNameRBRACE :
+				if(topKnownElementKind(ASSIST_PARSER) == K_TYPE_DELIMITER) {
+					popElement(K_TYPE_DELIMITER);
+				}
+				break;
+		}
+	}
+	this.previousToken = token;
+	if (token == TokenNameIdentifier) {
+		this.previousIdentifierPtr = this.identifierPtr;
+	}
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeTypeImportOnDemandDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* 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;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush comments defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+public abstract ImportReference createAssistImportReference(char[][] tokens, long[] positions, int mod);
+public abstract ImportReference createAssistPackageReference(char[][] tokens, long[] positions);
+public abstract NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions);
+public abstract TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions);
+public abstract TypeReference createParameterizedQualifiedAssistTypeReference(char[][] previousIdentifiers, TypeReference[][] typeArguments, char[] asistIdentifier, TypeReference[] assistTypeArguments, long[] positions);
+public abstract NameReference createSingleAssistNameReference(char[] assistName, long position);
+public abstract TypeReference createSingleAssistTypeReference(char[] assistName, long position);
+public abstract TypeReference createParameterizedSingleAssistTypeReference(TypeReference[] typeArguments, char[] assistName, long position);
+/*
+ * Flush parser/scanner state regarding to code assist
+ */
+public void flushAssistState(){
+	this.assistNode = null;
+	this.isOrphanCompletionNode = false;
+	setAssistIdentifier(null);
+}
+protected void flushElementStack() {
+	for (int j = 0; j <= this.elementPtr; j++) {
+		this.elementObjectInfoStack[j] = null;
+	}
+
+	this.elementPtr = -1;
+	this.previousKind = 0;
+	this.previousInfo = 0;
+	this.previousObjectInfo = null;
+}
+/*
+ * Build specific type reference nodes in case the cursor is located inside the type reference
+ */
+protected TypeReference getTypeReference(int dim) {
+
+	int index;
+
+	/* no need to take action if not inside completed identifiers */
+	if ((index = indexOfAssistIdentifier(true)) < 0) {
+		return super.getTypeReference(dim);
+	}
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	TypeReference reference;
+	int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--];
+	if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
+		this.identifierLengthPtr--;
+		// generic type
+		reference = getAssistTypeReferenceForGenericType(dim, length, numberOfIdentifiers);
+	} else {
+		/* retrieve identifiers subset and whole positions, the assist node positions
+			should include the entire replaced source. */
+
+		char[][] subset = identifierSubSet(index);
+		this.identifierLengthPtr--;
+		this.identifierPtr -= length;
+		long[] positions = new long[length];
+		System.arraycopy(
+			this.identifierPositionStack,
+			this.identifierPtr + 1,
+			positions,
+			0,
+			length);
+
+		/* build specific assist on type reference */
+
+		if (index == 0) {
+//			genericsIdentifiersLengthPtr--;
+			this.genericsLengthPtr--;
+			/* assist inside first identifier */
+			reference = createSingleAssistTypeReference(
+							assistIdentifier(),
+							positions[0]);
+		} else {
+//			genericsIdentifiersLengthPtr--;
+			this.genericsLengthPtr--;
+			/* assist inside subsequent identifier */
+			reference =	createQualifiedAssistTypeReference(
+							subset,
+							assistIdentifier(),
+							positions);
+		}
+		this.assistNode = reference;
+		this.lastCheckPoint = reference.sourceEnd + 1;
+	}
+	return reference;
+}
+protected TypeReference getAssistTypeReferenceForGenericType(int dim, int identifierLength, int numberOfIdentifiers) {
+	/* no need to take action if not inside completed identifiers */
+	if (/*(indexOfAssistIdentifier()) < 0 ||*/ (identifierLength == 1 && numberOfIdentifiers == 1)) {
+		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+		TypeReference[] typeArguments;
+		if (currentTypeArgumentsLength > -1) {
+			typeArguments = new TypeReference[currentTypeArgumentsLength];
+			this.genericsPtr -= currentTypeArgumentsLength;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength);
+		} else {
+			typeArguments = TypeReference.NO_TYPE_ARGUMENTS;
+		}
+		long[] positions = new long[identifierLength];
+		System.arraycopy(
+			this.identifierPositionStack,
+			this.identifierPtr,
+			positions,
+			0,
+			identifierLength);
+
+		this.identifierPtr--;
+
+		TypeReference reference = createParameterizedSingleAssistTypeReference(
+				typeArguments,
+				assistIdentifier(),
+				positions[0]);
+
+		this.assistNode = reference;
+		this.lastCheckPoint = reference.sourceEnd + 1;
+		return reference;
+	}
+
+	TypeReference[][] typeArguments = new TypeReference[numberOfIdentifiers][];
+	char[][] tokens = new char[numberOfIdentifiers][];
+	long[] positions = new long[numberOfIdentifiers];
+	int index = numberOfIdentifiers;
+	int currentIdentifiersLength = identifierLength;
+	while (index > 0) {
+		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+		if (currentTypeArgumentsLength > 0) {
+			this.genericsPtr -= currentTypeArgumentsLength;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
+		}
+		switch(currentIdentifiersLength) {
+			case 1 :
+				// we are in a case A<B>.C<D> or A<B>.C<D>
+				tokens[index - 1] = this.identifierStack[this.identifierPtr];
+				positions[index - 1] = this.identifierPositionStack[this.identifierPtr--];
+				break;
+			default:
+				// we are in a case A.B.C<B>.C<D> or A.B.C<B>...
+				this.identifierPtr -= currentIdentifiersLength;
+				System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, index - currentIdentifiersLength, currentIdentifiersLength);
+				System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, index - currentIdentifiersLength, currentIdentifiersLength);
+		}
+		index -= currentIdentifiersLength;
+		if (index > 0) {
+			currentIdentifiersLength = this.identifierLengthStack[this.identifierLengthPtr--];
+		}
+	}
+
+	// remove completion token
+	int realLength = numberOfIdentifiers;
+	for (int i = 0; i < numberOfIdentifiers; i++) {
+		if(tokens[i] == assistIdentifier()) {
+			realLength = i;
+		}
+	}
+	TypeReference reference;
+	if(realLength == 0) {
+		if(typeArguments[0] != null && typeArguments[0].length > 0) {
+			reference = createParameterizedSingleAssistTypeReference(typeArguments[0], assistIdentifier(), positions[0]);
+		} else {
+			reference = createSingleAssistTypeReference(assistIdentifier(), positions[0]);
+		}
+	} else {
+		TypeReference[] assistTypeArguments = typeArguments[realLength];
+		System.arraycopy(tokens, 0, tokens = new char[realLength][], 0, realLength);
+		System.arraycopy(typeArguments, 0, typeArguments = new TypeReference[realLength][], 0, realLength);
+
+		boolean isParameterized = false;
+		for (int i = 0; i < typeArguments.length; i++) {
+			if(typeArguments[i] != null) {
+				isParameterized = true;
+			}
+		}
+		if(isParameterized || (assistTypeArguments != null && assistTypeArguments.length > 0)) {
+			reference = createParameterizedQualifiedAssistTypeReference(tokens, typeArguments, assistIdentifier(), assistTypeArguments, positions);
+		} else {
+			reference = createQualifiedAssistTypeReference(tokens, assistIdentifier(), positions);
+		}
+	}
+
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+	return reference;
+}
+/*
+ * Copy of code from superclass with the following change:
+ * In the case of qualified name reference if the cursor location is on the
+ * qualified name reference, then create a CompletionOnQualifiedNameReference
+ * instead.
+ */
+protected NameReference getUnspecifiedReferenceOptimized() {
+
+	int completionIndex;
+
+	/* no need to take action if not inside completed identifiers */
+	if ((completionIndex = indexOfAssistIdentifier()) < 0) {
+		return super.getUnspecifiedReferenceOptimized();
+	}
+
+	consumeNonTypeUseName();
+	
+	/* retrieve identifiers subset and whole positions, the completion node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(completionIndex);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific completion on name reference */
+	NameReference reference;
+	if (completionIndex == 0) {
+		/* completion inside first identifier */
+		reference = createSingleAssistNameReference(assistIdentifier(), positions[0]);
+	} else {
+		/* completion inside subsequent identifier */
+		reference = createQualifiedAssistNameReference(subset, assistIdentifier(), positions);
+	}
+	reference.bits &= ~ASTNode.RestrictiveFlagMASK;
+	reference.bits |= Binding.LOCAL | Binding.FIELD;
+
+	this.assistNode = reference;
+	this.lastCheckPoint = reference.sourceEnd + 1;
+	return reference;
+}
+public void goForBlockStatementsopt() {
+	super.goForBlockStatementsopt();
+	this.isFirst = true;
+}
+public void goForHeaders(){
+	super.goForHeaders();
+	this.isFirst = true;
+}
+public void goForCompilationUnit(){
+	super.goForCompilationUnit();
+	this.isFirst = true;
+}
+public void goForBlockStatementsOrCatchHeader() {
+	super.goForBlockStatementsOrCatchHeader();
+	this.isFirst = true;
+}
+/*
+ * Retrieve a partial subset of a qualified name reference up to the completion point.
+ * It does not pop the actual awaiting identifiers, so as to be able to retrieve position
+ * information afterwards.
+ */
+protected char[][] identifierSubSet(int subsetLength){
+
+	if (subsetLength == 0) return null;
+
+	char[][] subset;
+	System.arraycopy(
+		this.identifierStack,
+		this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + 1,
+		(subset = new char[subsetLength][]),
+		0,
+		subsetLength);
+	return subset;
+}
+
+protected int indexOfAssistIdentifier(){
+	return this.indexOfAssistIdentifier(false);
+}
+/*
+ * Iterate the most recent group of awaiting identifiers (grouped for qualified name reference (e.g. aa.bb.cc)
+ * so as to check whether one of them is the assist identifier.
+ * If so, then answer the index of the assist identifier (0 being the first identifier of the set).
+ *	e.g. aa(0).bb(1).cc(2)
+ * If no assist identifier was found, answers -1.
+ */
+protected int indexOfAssistIdentifier(boolean useGenericsStack){
+
+	if (this.identifierLengthPtr < 0){
+		return -1; // no awaiting identifier
+	}
+
+	char[] assistIdentifier ;
+	if ((assistIdentifier = assistIdentifier()) == null){
+		return -1; // no assist identifier found yet
+	}
+
+	// iterate awaiting identifiers backwards
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	if(useGenericsStack && length > 0 && this.genericsIdentifiersLengthPtr > -1 ) {
+		length = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr];
+	}
+	for (int i = 0; i < length; i++){
+		if (this.identifierStack[this.identifierPtr - i] == assistIdentifier){
+			return length - i - 1;
+		}
+	}
+	// none of the awaiting identifiers is the completion one
+	return -1;
+}
+public void initialize() {
+	super.initialize();
+	flushAssistState();
+	flushElementStack();
+	this.previousIdentifierPtr = -1;
+	this.bracketDepth = 0;
+}
+public void initialize(boolean initializeNLS) {
+	super.initialize(initializeNLS);
+	flushAssistState();
+	flushElementStack();
+	this.previousIdentifierPtr = -1;
+	this.bracketDepth = 0;
+}
+public abstract void initializeScanner();
+protected boolean isIndirectlyInsideFieldInitialization(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == K_FIELD_INITIALIZER_DELIMITER)
+			return true;
+		i--;
+	}
+	return false;
+}
+protected boolean isIndirectlyInsideMethod(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == K_METHOD_DELIMITER)
+			return true;
+		i--;
+	}
+	return false;
+}
+protected boolean isIndirectlyInsideType(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == K_TYPE_DELIMITER)
+			return true;
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideAttributeValue(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_ATTRIBUTE_VALUE_DELIMITER : return true;
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideFieldInitialization(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return true;
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideMethod(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return true;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+		}
+		i--;
+	}
+	return false;
+}
+protected boolean isInsideType(){
+	int i = this.elementPtr;
+	while(i > -1) {
+		switch (this.elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return true;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+		}
+		i--;
+	}
+	return false;
+}
+protected int lastIndexOfElement(int kind) {
+	int i = this.elementPtr;
+	while(i > -1) {
+		if(this.elementKindStack[i] == kind) return i;
+		i--;
+	}
+	return -1;
+}
+/**
+ * Parse the block statements inside the given method declaration and try to complete at the
+ * cursor location.
+ */
+public void parseBlockStatements(AbstractMethodDeclaration md, CompilationUnitDeclaration unit) {
+	if (md instanceof MethodDeclaration) {
+		parseBlockStatements((MethodDeclaration) md, unit);
+	} else if (md instanceof ConstructorDeclaration) {
+		parseBlockStatements((ConstructorDeclaration) md, unit);
+	}
+}
+/**
+ * Parse the block statements inside the given constructor declaration and try to complete at the
+ * cursor location.
+ */
+public void parseBlockStatements(ConstructorDeclaration cd, CompilationUnitDeclaration unit) {
+	//only parse the method body of cd
+	//fill out its statements
+
+	//convert bugs into parse error
+
+	initialize();
+	// set the lastModifiers to reflect the modifiers of the constructor whose
+	// block statements are being parsed
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202634
+	this.lastModifiers = cd.modifiers;
+	this.lastModifiersStart = cd.modifiersSourceStart;
+	// simulate goForConstructorBody except that we don't want to balance brackets because they are not going to be balanced
+	goForBlockStatementsopt();
+
+	this.referenceContext = cd;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(cd.bodyStart, bodyEnd(cd));
+	consumeNestedMethod();
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		cd.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	// attach the statements as we might be searching for a reference to a local type
+	cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+		if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
+			//avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
+			{
+			System.arraycopy(
+				this.astStack,
+				this.astPtr + 2,
+				cd.statements = new Statement[length - 1],
+				0,
+				length - 1);
+			cd.constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
+		} else { //need to add explicitly the super();
+			System.arraycopy(
+				this.astStack,
+				this.astPtr + 1,
+				cd.statements = new Statement[length],
+				0,
+				length);
+			cd.constructorCall = SuperReference.implicitSuperConstructorCall();
+		}
+	} else {
+		cd.constructorCall = SuperReference.implicitSuperConstructorCall();
+		if (!containsComment(cd.bodyStart, cd.bodyEnd)) {
+			cd.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+
+	if (cd.constructorCall.sourceEnd == 0) {
+		cd.constructorCall.sourceEnd = cd.sourceEnd;
+		cd.constructorCall.sourceStart = cd.sourceStart;
+	}
+}
+/**
+ * Parse the block statements inside the given initializer and try to complete at the
+ * cursor location.
+ */
+public void parseBlockStatements(
+	Initializer initializer,
+	TypeDeclaration type,
+	CompilationUnitDeclaration unit) {
+
+	initialize();
+	// set the lastModifiers to reflect the modifiers of the initializer whose
+	// block statements are being parsed
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202634
+	this.lastModifiers = initializer.modifiers;
+	this.lastModifiersStart = initializer.modifiersSourceStart;
+	// simulate goForInitializer except that we don't want to balance brackets because they are not going to be balanced
+	goForBlockStatementsopt();
+
+	this.referenceContext = type;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(initializer.sourceStart, bodyEnd(initializer)); // just after the beginning {
+	consumeNestedMethod();
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		initializer.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	// attach the statements as we might be searching for a reference to a local type
+	initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) > 0) {
+		System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length);
+	} else {
+		// check whether this block at least contains some comment in it
+		if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) {
+			initializer.block.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+
+	// mark initializer with local type if one was found during parsing
+	if ((type.bits & ASTNode.HasLocalType) != 0) {
+		initializer.bits |= ASTNode.HasLocalType;
+	}
+}
+/**
+ * Parse the block statements inside the given method declaration and try to complete at the
+ * cursor location.
+ */
+public void parseBlockStatements(MethodDeclaration md, CompilationUnitDeclaration unit) {
+	//only parse the method body of md
+	//fill out method statements
+
+	//convert bugs into parse error
+
+	if (md.isAbstract())
+		return;
+	if (md.isNative())
+		return;
+	if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
+		return;
+
+	initialize();
+	// set the lastModifiers to reflect the modifiers of the method whose
+	// block statements are being parsed
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=202634
+	this.lastModifiers = md.modifiers;
+	this.lastModifiersStart = md.modifiersSourceStart;
+	// simulate goForMethodBody except that we don't want to balance brackets because they are not going to be balanced
+	goForBlockStatementsopt();
+
+	this.referenceContext = md;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(md.bodyStart, bodyEnd(md)); // reset the scanner to parser from { down to the cursor location
+	consumeNestedMethod();
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		md.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	// attach the statements as we might be searching for a reference to a local type
+	md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.astStack,
+			(this.astPtr -= length) + 1,
+			md.statements = new Statement[length],
+			0,
+			length);
+	} else {
+		if (!containsComment(md.bodyStart, md.bodyEnd)) {
+			md.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+
+}
+protected void popElement(int kind){
+	if(this.elementPtr < 0 || this.elementKindStack[this.elementPtr] != kind) return;
+
+	this.previousKind = this.elementKindStack[this.elementPtr];
+	this.previousInfo = this.elementInfoStack[this.elementPtr];
+	this.previousObjectInfo = this.elementObjectInfoStack[this.elementPtr];
+
+	this.elementObjectInfoStack[this.elementPtr] = null;
+
+	switch (kind) {
+		default :
+			this.elementPtr--;
+			break;
+	}
+}
+protected void popUntilElement(int kind){
+	if(this.elementPtr < 0) return;
+	int i = this.elementPtr;
+	while (i >= 0 && this.elementKindStack[i] != kind) {
+		i--;
+	}
+	if(i >= 0) {
+		if(i < this.elementPtr) {
+			this.previousKind = this.elementKindStack[i+1];
+			this.previousInfo = this.elementInfoStack[i+1];
+			this.previousObjectInfo = this.elementObjectInfoStack[i+1];
+
+			for (int j = i + 1; j <= this.elementPtr; j++) {
+				this.elementObjectInfoStack[j] = null;
+			}
+		}
+		this.elementPtr = i;
+	}
+}
+/*
+ * Prepares the state of the parser to go for BlockStatements.
+ */
+protected void prepareForBlockStatements() {
+	this.nestedMethod[this.nestedType = 0] = 1;
+	this.variablesCounter[this.nestedType] = 0;
+	this.realBlockStack[this.realBlockPtr = 1] = 0;
+
+	// initialize element stack
+	int fieldInitializerIndex = lastIndexOfElement(K_FIELD_INITIALIZER_DELIMITER);
+	int methodIndex = lastIndexOfElement(K_METHOD_DELIMITER);
+	if(methodIndex == fieldInitializerIndex) {
+		// there is no method and no field initializer
+		flushElementStack();
+	} else if(methodIndex > fieldInitializerIndex) {
+		popUntilElement(K_METHOD_DELIMITER);
+	} else {
+		popUntilElement(K_FIELD_INITIALIZER_DELIMITER);
+	}
+}
+/*
+ * Prepares the state of the parser to go for Headers.
+ */
+protected void prepareForHeaders() {
+	this.nestedMethod[this.nestedType = 0] = 0;
+	this.variablesCounter[this.nestedType] = 0;
+	this.realBlockStack[this.realBlockPtr = 0] = 0;
+
+	popUntilElement(K_TYPE_DELIMITER);
+
+	if(this.topKnownElementKind(ASSIST_PARSER) != K_TYPE_DELIMITER) {
+		// is outside a type and inside a compilation unit.
+		// remove all elements.
+		flushElementStack();
+	}
+}
+protected void pushOnElementStack(int kind){
+	this.pushOnElementStack(kind, 0, null);
+}
+protected void pushOnElementStack(int kind, int info){
+	this.pushOnElementStack(kind, info, null);
+}
+protected void pushOnElementStack(int kind, int info, Object objectInfo){
+	if (this.elementPtr < -1) return;
+
+	this.previousKind = 0;
+	this.previousInfo = 0;
+	this.previousObjectInfo = null;
+
+	int stackLength = this.elementKindStack.length;
+	if (++this.elementPtr >= stackLength) {
+		System.arraycopy(
+			this.elementKindStack, 0,
+			this.elementKindStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+		System.arraycopy(
+			this.elementInfoStack, 0,
+			this.elementInfoStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+		System.arraycopy(
+			this.elementObjectInfoStack, 0,
+			this.elementObjectInfoStack = new Object[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.elementKindStack[this.elementPtr] = kind;
+	this.elementInfoStack[this.elementPtr] = info;
+	this.elementObjectInfoStack[this.elementPtr] = objectInfo;
+}
+public void recoveryExitFromVariable() {
+	if(this.currentElement != null && this.currentElement instanceof RecoveredField
+		&& !(this.currentElement instanceof RecoveredInitializer)) {
+		RecoveredElement oldElement = this.currentElement;
+		super.recoveryExitFromVariable();
+		if(oldElement != this.currentElement) {
+			popElement(K_FIELD_INITIALIZER_DELIMITER);
+		}
+	} else {
+		super.recoveryExitFromVariable();
+	}
+}
+public void recoveryTokenCheck() {
+	RecoveredElement oldElement = this.currentElement;
+	switch (this.currentToken) {
+		case TokenNameLBRACE :
+			super.recoveryTokenCheck();
+			if(this.currentElement instanceof RecoveredInitializer) {
+				if(oldElement instanceof RecoveredField) {
+					popUntilElement(K_FIELD_INITIALIZER_DELIMITER);
+					popElement(K_FIELD_INITIALIZER_DELIMITER);
+				}
+				if(this.currentElement != oldElement
+					&& topKnownElementKind(ASSIST_PARSER) != K_METHOD_DELIMITER) {
+					pushOnElementStack(K_METHOD_DELIMITER);
+				}
+			}
+			break;
+		case TokenNameRBRACE :
+			super.recoveryTokenCheck();
+			if(this.currentElement != oldElement && !isInsideAttributeValue()) {
+				if(oldElement instanceof RecoveredInitializer
+					|| oldElement instanceof RecoveredMethod
+					|| (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredInitializer)
+					|| (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredMethod)) {
+					popUntilElement(K_METHOD_DELIMITER);
+					popElement(K_METHOD_DELIMITER);
+				} else if(oldElement instanceof RecoveredType) {
+					popUntilElement(K_TYPE_DELIMITER);
+					if(!(this.referenceContext instanceof CompilationUnitDeclaration)
+							|| isIndirectlyInsideFieldInitialization()
+							|| this.currentElement instanceof RecoveredUnit) {
+						popElement(K_TYPE_DELIMITER);
+					}
+				}
+			}
+			break;
+		default :
+			super.recoveryTokenCheck();
+			break;
+	}
+}
+public void reset(){
+	flushAssistState();
+}
+/*
+ * Reset context so as to resume to regular parse loop
+ * If unable to reset for resuming, answers false.
+ *
+ * Move checkpoint location, reset internal stacks and
+ * decide which grammar goal is activated.
+ */
+protected boolean resumeAfterRecovery() {
+
+	// reset internal stacks
+	this.astPtr = -1;
+	this.astLengthPtr = -1;
+	this.expressionPtr = -1;
+	this.expressionLengthPtr = -1;
+	this.typeAnnotationLengthPtr = -1;
+	this.typeAnnotationPtr = -1;
+	this.identifierPtr = -1;
+	this.identifierLengthPtr	= -1;
+	this.intPtr = -1;
+	this.dimensions = 0 ;
+	this.recoveredStaticInitializerStart = 0;
+
+	this.genericsIdentifiersLengthPtr = -1;
+	this.genericsLengthPtr = -1;
+	this.genericsPtr = -1;
+
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1;
+
+	// if in diet mode, reset the diet counter because we're going to restart outside an initializer.
+	if (this.diet) this.dietInt = 0;
+
+	/* attempt to move checkpoint location */
+	if (!moveRecoveryCheckpoint()) return false;
+
+	// only look for headers
+	if (this.referenceContext instanceof CompilationUnitDeclaration
+		|| this.assistNode != null){
+		if(isInsideMethod() &&
+			isIndirectlyInsideFieldInitialization() &&
+			this.assistNode == null
+			){
+			prepareForBlockStatements();
+			goForBlockStatementsOrCatchHeader();
+		} else if((isInsideArrayInitializer()) &&
+				isIndirectlyInsideFieldInitialization() &&
+				this.assistNode == null){
+			prepareForBlockStatements();
+			goForBlockStatementsopt();
+		} else {
+			prepareForHeaders();
+			goForHeaders();
+			this.diet = true; // passed this point, will not consider method bodies
+		}
+		return true;
+	}
+	if (this.referenceContext instanceof AbstractMethodDeclaration
+		|| this.referenceContext instanceof TypeDeclaration){
+
+		if (this.currentElement instanceof RecoveredType){
+			prepareForHeaders();
+			goForHeaders();
+		} else {
+			prepareForBlockStatements();
+			goForBlockStatementsOrCatchHeader();
+		}
+		return true;
+	}
+	// does not know how to restart
+	return false;
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087
+// To be implemented in children viz. CompletionParser that are aware of array initializers
+protected boolean isInsideArrayInitializer() {
+	return false;
+}
+public abstract void setAssistIdentifier(char[] assistIdent);
+protected int topKnownElementInfo(int owner) {
+	return topKnownElementInfo(owner, 0);
+}
+protected int topKnownElementInfo(int owner, int offSet) {
+	int i = this.elementPtr;
+	while(i > -1) {
+		if((this.elementKindStack[i] & owner) != 0) {
+			if(offSet <= 0) return this.elementInfoStack[i];
+			offSet--;
+		}
+		i--;
+	}
+	return 0;
+}
+protected int topKnownElementKind(int owner) {
+	return topKnownElementKind(owner, 0);
+}
+protected int topKnownElementKind(int owner, int offSet) {
+	int i = this.elementPtr;
+	while(i > -1) {
+		if((this.elementKindStack[i] & owner) != 0) {
+			if(offSet <= 0) return this.elementKindStack[i];
+			offSet--;
+		}
+		i--;
+	}
+	return 0;
+}
+protected Object topKnownElementObjectInfo(int owner, int offSet) {
+	int i = this.elementPtr;
+	while(i > -1) {
+		if((this.elementKindStack[i] & owner) != 0) {
+			if(offSet <= 0) return this.elementObjectInfoStack[i];
+			offSet--;
+		}
+		i--;
+	}
+	return null;
+}
+protected Object topKnownElementObjectInfo(int owner) {
+	return topKnownElementObjectInfo(owner, 0);
+}
+/**
+ * If the given ast node is inside an explicit constructor call
+ * then wrap it with a fake constructor call.
+ * Returns the wrapped completion node or the completion node itself.
+ */
+protected ASTNode wrapWithExplicitConstructorCallIfNeeded(ASTNode ast) {
+	int selector;
+	if (ast != null && topKnownElementKind(ASSIST_PARSER) == K_SELECTOR && ast instanceof Expression &&
+			(((selector = topKnownElementInfo(ASSIST_PARSER)) == THIS_CONSTRUCTOR) ||
+			(selector == SUPER_CONSTRUCTOR))) {
+		ExplicitConstructorCall call = new ExplicitConstructorCall(
+			(selector == THIS_CONSTRUCTOR) ?
+				ExplicitConstructorCall.This :
+				ExplicitConstructorCall.Super
+		);
+		call.arguments = new Expression[] {(Expression)ast};
+		call.sourceStart = ast.sourceStart;
+		call.sourceEnd = ast.sourceEnd;
+		return call;
+	} else {
+		return ast;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceField.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceField.java
new file mode 100644
index 0000000..0ad4a66
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceField.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.ResolvedSourceField;
+
+public class AssistSourceField extends ResolvedSourceField {
+	private Map bindingCache;
+	private Map infoCache;
+
+	private String uniqueKey;
+	private boolean isResolved;
+
+	public AssistSourceField(JavaElement parent, String name, Map bindingCache, Map infoCache) {
+		super(parent, name, null);
+		this.bindingCache = bindingCache;
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceField#getKey()
+	 */
+	public String getKey() {
+		if (this.uniqueKey == null) {
+			Binding binding = (Binding) this.bindingCache.get(this);
+			if (binding != null) {
+				this.isResolved = true;
+				this.uniqueKey = new String(binding.computeUniqueKey());
+			} else {
+				this.isResolved = false;
+				try {
+					this.uniqueKey = getKey(this, false/*don't open*/);
+				} catch (JavaModelException e) {
+					// happen only if force open is true
+					return null;
+				}
+			}
+		}
+		return this.uniqueKey;
+	}
+
+	public boolean isResolved() {
+		getKey();
+		return this.isResolved;
+	}
+
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info,boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo && isResolved());
+	}
+
+	public IAnnotation getAnnotation(String annotationName) {
+		return new AssistAnnotation(this, annotationName, this.infoCache);
+	}
+
+	public IType getType(String typeName, int count) {
+		AssistSourceType type = new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+		type.occurrenceCount = count;
+		return type;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceMethod.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceMethod.java
new file mode 100644
index 0000000..ffff24c
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceMethod.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.ResolvedSourceMethod;
+
+public class AssistSourceMethod extends ResolvedSourceMethod {
+	private Map bindingCache;
+	private Map infoCache;
+
+	private String uniqueKey;
+	private boolean isResolved;
+
+	public AssistSourceMethod(JavaElement parent, String name, String[] parameterTypes, Map bindingCache, Map infoCache) {
+		super(parent, name, parameterTypes, null);
+		this.bindingCache = bindingCache;
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceMethod#getKey()
+	 */
+	public String getKey() {
+		if (this.uniqueKey == null) {
+			Binding binding = (Binding) this.bindingCache.get(this);
+			if (binding != null) {
+				this.isResolved = true;
+				this.uniqueKey = new String(binding.computeUniqueKey());
+			} else {
+				this.isResolved = false;
+				try {
+					this.uniqueKey = getKey(this, false/*don't open*/);
+				} catch (JavaModelException e) {
+					// happen only if force open is true
+					return null;
+				}
+			}
+		}
+		return this.uniqueKey;
+	}
+
+	public boolean isResolved() {
+		getKey();
+		return this.isResolved;
+	}
+
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info,boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo && isResolved());
+	}
+
+	public IAnnotation getAnnotation(String annotationName) {
+		return new AssistAnnotation(this, annotationName, this.infoCache);
+	}
+
+	public IType getType(String typeName, int count) {
+		AssistSourceType type = new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+		type.occurrenceCount = count;
+		return type;
+	}
+
+	public ITypeParameter getTypeParameter(String typeParameterName) {
+		return new AssistTypeParameter(this, typeParameterName, this.infoCache);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceType.java
new file mode 100644
index 0000000..4bc713c
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistSourceType.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.ResolvedSourceType;
+
+public class AssistSourceType extends ResolvedSourceType {
+	private Map bindingCache;
+	private Map infoCache;
+
+	private String uniqueKey;
+	private boolean isResolved;
+
+	public AssistSourceType(JavaElement parent, String name, Map bindingCache, Map infoCache) {
+		super(parent, name, null);
+		this.bindingCache = bindingCache;
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+
+	public String getFullyQualifiedParameterizedName() throws JavaModelException {
+		if (isResolved()) {
+			return getFullyQualifiedParameterizedName(getFullyQualifiedName('.'), this.getKey());
+		}
+		return getFullyQualifiedName('.', true/*show parameters*/);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceType#getKey()
+	 */
+	public String getKey() {
+		if (this.uniqueKey == null) {
+			Binding binding = (Binding) this.bindingCache.get(this);
+			if (binding != null) {
+				this.isResolved = true;
+				this.uniqueKey = new String(binding.computeUniqueKey());
+			} else {
+				this.isResolved = false;
+				try {
+					this.uniqueKey = getKey(this, false/*don't open*/);
+				} catch (JavaModelException e) {
+					// happen only if force open is true
+					return null;
+				}
+			}
+		}
+		return this.uniqueKey;
+	}
+
+	public boolean isResolved() {
+		getKey();
+		return this.isResolved;
+	}
+
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info,boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo && isResolved());
+	}
+
+	public IAnnotation getAnnotation(String annotationName) {
+		return new AssistAnnotation(this, annotationName, this.infoCache);
+	}
+
+	public IField getField(String fieldName) {
+		return new AssistSourceField(this, fieldName, this.bindingCache, this.infoCache);
+	}
+
+	public IInitializer getInitializer(int count) {
+		return new AssistInitializer(this, count, this.bindingCache, this.infoCache);
+	}
+
+	public IMethod getMethod(String selector, String[] parameterTypeSignatures) {
+		return new AssistSourceMethod(this, selector, parameterTypeSignatures, this.bindingCache, this.infoCache);
+	}
+
+	public IType getType(String typeName) {
+		return new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+	}
+
+	public IType getType(String typeName, int count) {
+		AssistSourceType type = new AssistSourceType(this, typeName, this.bindingCache, this.infoCache);
+		type.occurrenceCount = count;
+		return type;
+	}
+
+	public ITypeParameter getTypeParameter(String typeParameterName) {
+		return new AssistTypeParameter(this, typeParameterName, this.infoCache);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistTypeParameter.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistTypeParameter.java
new file mode 100644
index 0000000..068c2f1
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistTypeParameter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.TypeParameter;
+
+public class AssistTypeParameter extends TypeParameter {
+	private Map infoCache;
+	public AssistTypeParameter(JavaElement parent, String name, Map infoCache) {
+		super(parent, name);
+		this.infoCache = infoCache;
+	}
+
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+		return this.infoCache.get(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
new file mode 100644
index 0000000..14f9a01
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+
+public abstract class Engine implements ITypeRequestor {
+
+	public LookupEnvironment lookupEnvironment;
+
+	protected CompilationUnitScope unitScope;
+	public SearchableEnvironment nameEnvironment;
+
+	public AssistOptions options;
+	public CompilerOptions compilerOptions;
+	public boolean forbiddenReferenceIsError;
+	public boolean discouragedReferenceIsError;
+
+	public boolean importCachesInitialized = false;
+	public char[][][] importsCache;
+	public ImportBinding[] onDemandImportsCache;
+	public int importCacheCount = 0;
+	public int onDemandImportCacheCount = 0;
+	public char[] currentPackageName = null;
+
+	public Engine(Map settings){
+		this.options = new AssistOptions(settings);
+		this.compilerOptions = new CompilerOptions(settings);
+		this.forbiddenReferenceIsError =
+			(this.compilerOptions.getSeverity(CompilerOptions.ForbiddenReference) & ProblemSeverities.Error) != 0;
+		this.discouragedReferenceIsError =
+			(this.compilerOptions.getSeverity(CompilerOptions.DiscouragedReference) & ProblemSeverities.Error) != 0;
+	}
+
+	/**
+	 * Add an additional binary type
+	 */
+	public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
+	}
+
+	/**
+	 * Add an additional compilation unit.
+	 */
+	public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+		CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+		
+		AssistParser assistParser = getParser();
+		Object parserState = assistParser.becomeSimpleParser();
+		
+		CompilationUnitDeclaration parsedUnit =
+			assistParser.dietParse(sourceUnit, result);
+		
+		assistParser.restoreAssistParser(parserState);
+
+		this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
+		this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+	}
+
+	/**
+	 * Add additional source types (the first one is the requested type, the rest is formed by the
+	 * secondary types defined in the same compilation unit).
+	 */
+	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		CompilationResult result =
+			new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration unit =
+			SourceTypeConverter.buildCompilationUnit(
+				sourceTypes,//sourceTypes[0] is always toplevel here
+				SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+				| SourceTypeConverter.MEMBER_TYPE, // need member types
+				// no need for field initialization
+				this.lookupEnvironment.problemReporter,
+				result);
+
+		if (unit != null) {
+			this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
+			this.lookupEnvironment.completeTypeBindings(unit, true);
+		}
+	}
+
+	public abstract AssistParser getParser();
+
+	public void initializeImportCaches() {
+		if (this.currentPackageName == null) {
+			initializePackageCache();
+		}
+		
+		ImportBinding[] importBindings = this.unitScope.imports;
+		int length = importBindings == null ? 0 : importBindings.length;
+
+		for (int i = 0; i < length; i++) {
+			ImportBinding importBinding = importBindings[i];
+			if(importBinding.onDemand) {
+				if(this.onDemandImportsCache == null) {
+					this.onDemandImportsCache = new ImportBinding[length - i];
+				}
+				this.onDemandImportsCache[this.onDemandImportCacheCount++] =
+					importBinding;
+			} else {
+				if(!(importBinding.resolvedImport instanceof MethodBinding) ||
+						importBinding instanceof ImportConflictBinding) {
+					if(this.importsCache == null) {
+						this.importsCache = new char[length - i][][];
+					}
+					this.importsCache[this.importCacheCount++] = new char[][]{
+							importBinding.compoundName[importBinding.compoundName.length - 1],
+							CharOperation.concatWith(importBinding.compoundName, '.')
+						};
+				}
+			}
+		}
+
+		this.importCachesInitialized = true;
+	}
+	
+	public void initializePackageCache() {
+		if (this.unitScope.fPackage != null) {
+			this.currentPackageName = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
+		} else if (this.unitScope.referenceContext != null &&
+				this.unitScope.referenceContext.currentPackage != null) {
+			this.currentPackageName = CharOperation.concatWith(this.unitScope.referenceContext.currentPackage.tokens, '.');
+		} else {
+			this.currentPackageName = CharOperation.NO_CHAR;
+		}
+	}
+
+	protected boolean mustQualifyType(
+		char[] packageName,
+		char[] typeName,
+		char[] enclosingTypeNames,
+		int modifiers) {
+
+		// If there are no types defined into the current CU yet.
+		if (this.unitScope == null)
+			return true;
+
+		if(!this.importCachesInitialized) {
+			initializeImportCaches();
+		}
+
+		for (int i = 0; i < this.importCacheCount; i++) {
+			char[][] importName = this.importsCache[i];
+			if(CharOperation.equals(typeName, importName[0])) {
+				char[] fullyQualifiedTypeName =
+					enclosingTypeNames == null || enclosingTypeNames.length == 0
+							? CharOperation.concat(
+									packageName,
+									typeName,
+									'.')
+							: CharOperation.concat(
+									CharOperation.concat(
+										packageName,
+										enclosingTypeNames,
+										'.'),
+									typeName,
+									'.');
+				return !CharOperation.equals(fullyQualifiedTypeName, importName[1]);
+			}
+		}
+
+		if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName))
+			return false;
+
+		char[] fullyQualifiedEnclosingTypeName = null;
+
+		for (int i = 0; i < this.onDemandImportCacheCount; i++) {
+			ImportBinding importBinding = this.onDemandImportsCache[i];
+			Binding resolvedImport = importBinding.resolvedImport;
+
+			char[][] importName = importBinding.compoundName;
+			char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+			boolean isFound = false;
+			// resolvedImport is a ReferenceBindng or a PackageBinding
+			if(resolvedImport instanceof ReferenceBinding) {
+				if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+					if(fullyQualifiedEnclosingTypeName == null) {
+						fullyQualifiedEnclosingTypeName =
+							CharOperation.concat(
+									packageName,
+									enclosingTypeNames,
+									'.');
+					}
+					if(CharOperation.equals(fullyQualifiedEnclosingTypeName, importFlatName)) {
+						if(importBinding.isStatic()) {
+							isFound = (modifiers & ClassFileConstants.AccStatic) != 0;
+						} else {
+							isFound = true;
+						}
+					}
+				}
+			} else {
+				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+					if(CharOperation.equals(packageName, importFlatName)) {
+						if(importBinding.isStatic()) {
+							isFound = (modifiers & ClassFileConstants.AccStatic) != 0;
+						} else {
+							isFound = true;
+						}
+					}
+				}
+			}
+
+			// find potential conflict with another import
+			if(isFound) {
+				for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+					if(i != j) {
+						ImportBinding conflictingImportBinding = this.onDemandImportsCache[j];
+						if(conflictingImportBinding.resolvedImport instanceof ReferenceBinding) {
+							ReferenceBinding refBinding =
+								(ReferenceBinding) conflictingImportBinding.resolvedImport;
+							if (refBinding.getMemberType(typeName) != null) {
+								return true;
+							}
+						} else {
+							char[] conflictingImportName =
+								CharOperation.concatWith(conflictingImportBinding.compoundName, '.');
+
+							if (this.nameEnvironment.nameLookup.findType(
+									String.valueOf(typeName),
+									String.valueOf(conflictingImportName),
+									false,
+									NameLookup.ACCEPT_ALL,
+									false/*don't check restrictions*/) != null) {
+								return true;
+							}
+						}
+					}
+				}
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/*
+	 * Find the node (a field, a method or an initializer) at the given position
+	 * and parse its block statements if it is a method or an initializer.
+	 * Returns the node or null if not found
+	 */
+	protected ASTNode parseBlockStatements(CompilationUnitDeclaration unit, int position) {
+		int length = unit.types.length;
+		for (int i = 0; i < length; i++) {
+			TypeDeclaration type = unit.types[i];
+			if (type.declarationSourceStart < position
+				&& type.declarationSourceEnd >= position) {
+				getParser().scanner.setSource(unit.compilationResult);
+				return parseBlockStatements(type, unit, position);
+			}
+		}
+		return null;
+	}
+
+	private ASTNode parseBlockStatements(
+		TypeDeclaration type,
+		CompilationUnitDeclaration unit,
+		int position) {
+		//members
+		TypeDeclaration[] memberTypes = type.memberTypes;
+		if (memberTypes != null) {
+			int length = memberTypes.length;
+			for (int i = 0; i < length; i++) {
+				TypeDeclaration memberType = memberTypes[i];
+				if (memberType.bodyStart > position)
+					continue;
+				if (memberType.declarationSourceEnd >= position) {
+					return parseBlockStatements(memberType, unit, position);
+				}
+			}
+		}
+		//methods
+		AbstractMethodDeclaration[] methods = type.methods;
+		if (methods != null) {
+			int length = methods.length;
+			for (int i = 0; i < length; i++) {
+				AbstractMethodDeclaration method = methods[i];
+				if (method.bodyStart > position + 1)
+					continue;
+
+				if(method.isDefaultConstructor())
+					continue;
+
+				if (method.declarationSourceEnd >= position) {
+
+					getParser().parseBlockStatements(method, unit);
+					return method;
+				}
+			}
+		}
+		//initializers
+		FieldDeclaration[] fields = type.fields;
+		if (fields != null) {
+			int length = fields.length;
+			for (int i = 0; i < length; i++) {
+				FieldDeclaration field = fields[i];
+				if (field.sourceStart > position)
+					continue;
+				if (field.declarationSourceEnd >= position) {
+					if (field instanceof Initializer) {
+						getParser().parseBlockStatements((Initializer)field, type, unit);
+					}
+					return field;
+				}
+			}
+		}
+		return null;
+	}
+
+	protected void reset(boolean resetLookupEnvironment) {
+		if (resetLookupEnvironment) this.lookupEnvironment.reset();
+	}
+
+	public static char[] getTypeSignature(TypeBinding typeBinding) {
+		char[] result = typeBinding.signature();
+		if (result != null) {
+			result = CharOperation.replaceOnCopy(result, '/', '.');
+		}
+		return result;
+	}
+
+	public static char[] getSignature(MethodBinding methodBinding) {
+		char[] result = null;
+
+		int oldMod = methodBinding.modifiers;
+		//TODO remove the next line when method from binary type will be able to generate generic signature
+		methodBinding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+		result = methodBinding.genericSignature();
+		if(result == null) {
+			result = methodBinding.signature();
+		}
+		methodBinding.modifiers = oldMod;
+
+		if (result != null) {
+			result = CharOperation.replaceOnCopy(result, '/', '.');
+		}
+		return result;
+	}
+
+	public static char[] getSignature(TypeBinding typeBinding) {
+		char[] result = null;
+
+		result = typeBinding.genericTypeSignature();
+
+		if (result != null) {
+			result = CharOperation.replaceOnCopy(result, '/', '.');
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java
new file mode 100644
index 0000000..79c4c7f
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.impl;
+
+public interface Keywords {
+	int COUNT = 41;
+
+	char[] ABSTRACT = "abstract".toCharArray(); //$NON-NLS-1$
+	char[] ASSERT = "assert".toCharArray(); //$NON-NLS-1$
+	char[] BREAK = "break".toCharArray(); //$NON-NLS-1$
+	char[] CASE = "case".toCharArray(); //$NON-NLS-1$
+	char[] CATCH = "catch".toCharArray(); //$NON-NLS-1$
+	char[] CLASS = "class".toCharArray(); //$NON-NLS-1$
+	char[] CONTINUE = "continue".toCharArray(); //$NON-NLS-1$
+	char[] DEFAULT = "default".toCharArray(); //$NON-NLS-1$
+	char[] DO = "do".toCharArray(); //$NON-NLS-1$
+	char[] ELSE = "else".toCharArray(); //$NON-NLS-1$
+	char[] ENUM = "enum".toCharArray(); //$NON-NLS-1$
+	char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
+	char[] FINAL = "final".toCharArray(); //$NON-NLS-1$
+	char[] FINALLY = "finally".toCharArray(); //$NON-NLS-1$
+	char[] FOR = "for".toCharArray(); //$NON-NLS-1$
+	char[] IF = "if".toCharArray(); //$NON-NLS-1$
+	char[] IMPLEMENTS = "implements".toCharArray(); //$NON-NLS-1$
+	char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$
+	char[] INSTANCEOF = "instanceof".toCharArray(); //$NON-NLS-1$
+	char[] INTERFACE = "interface".toCharArray(); //$NON-NLS-1$
+	char[] NATIVE = "native".toCharArray(); //$NON-NLS-1$
+	char[] NEW = "new".toCharArray(); //$NON-NLS-1$
+	char[] PACKAGE = "package".toCharArray(); //$NON-NLS-1$
+	char[] PRIVATE = "private".toCharArray(); //$NON-NLS-1$
+	char[] PROTECTED = "protected".toCharArray(); //$NON-NLS-1$
+	char[] PUBLIC = "public".toCharArray(); //$NON-NLS-1$
+	char[] RETURN = "return".toCharArray(); //$NON-NLS-1$
+	char[] STATIC = "static".toCharArray(); //$NON-NLS-1$
+	char[] STRICTFP = "strictfp".toCharArray(); //$NON-NLS-1$
+	char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+	char[] SWITCH = "switch".toCharArray(); //$NON-NLS-1$
+	char[] SYNCHRONIZED = "synchronized".toCharArray(); //$NON-NLS-1$
+	char[] THIS = "this".toCharArray(); //$NON-NLS-1$
+	char[] THROW = "throw".toCharArray(); //$NON-NLS-1$
+	char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$
+	char[] TRANSIENT = "transient".toCharArray(); //$NON-NLS-1$
+	char[] TRY = "try".toCharArray(); //$NON-NLS-1$
+	char[] VOLATILE = "volatile".toCharArray(); //$NON-NLS-1$
+	char[] WHILE = "while".toCharArray(); //$NON-NLS-1$
+	char[] TRUE = "true".toCharArray(); //$NON-NLS-1$
+	char[] FALSE = "false".toCharArray(); //$NON-NLS-1$
+	char[] NULL = "null".toCharArray(); //$NON-NLS-1$
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
new file mode 100644
index 0000000..211bc1a
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Node representing a Javadoc comment including code selection.
+ */
+public class SelectionJavadoc extends Javadoc {
+
+	Expression selectedNode;
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171019
+	// Flag raised when selection is done on inheritDoc javadoc tag
+	boolean inheritDocSelected;
+
+	public SelectionJavadoc(int sourceStart, int sourceEnd) {
+		super(sourceStart, sourceEnd);
+		this.inheritDocSelected = false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Javadoc#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer print(int indent, StringBuffer output) {
+		super.print(indent, output);
+		if (this.selectedNode != null) {
+			String selectedString = null;
+			if (this.selectedNode instanceof JavadocFieldReference) {
+				JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
+				if (fieldRef.methodBinding != null) {
+					selectedString = "<SelectOnMethod:"; //$NON-NLS-1$
+				} else {
+					selectedString = "<SelectOnField:"; //$NON-NLS-1$
+				}
+			} else if (this.selectedNode instanceof JavadocMessageSend) {
+				selectedString = "<SelectOnMethod:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocAllocationExpression) {
+				selectedString = "<SelectOnConstructor:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocSingleNameReference) {
+				selectedString = "<SelectOnLocalVariable:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					selectedString = "<SelectOnType:"; //$NON-NLS-1$
+				}
+			} else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					selectedString = "<SelectOnType:"; //$NON-NLS-1$
+				}
+			} else {
+				selectedString = "<SelectOnType:"; //$NON-NLS-1$
+			}
+			int pos = output.length()-3;
+			output.replace(pos-2,pos, selectedString+this.selectedNode+'>');
+		}
+		return output;
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws SelectionNodeFound
+	 */
+	private void internalResolve(Scope scope) {
+		if (this.selectedNode != null) {
+			switch (scope.kind) {
+				case Scope.CLASS_SCOPE:
+					this.selectedNode.resolveType((ClassScope)scope);
+					break;
+				case Scope.METHOD_SCOPE:
+					this.selectedNode.resolveType((MethodScope)scope);
+					break;
+			}
+			Binding binding = null;
+			if (this.selectedNode instanceof JavadocFieldReference) {
+				JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
+				binding = fieldRef.binding;
+				if (binding == null && fieldRef.methodBinding != null) {
+					binding = fieldRef.methodBinding;
+				}
+			} else if (this.selectedNode instanceof JavadocMessageSend) {
+				binding = ((JavadocMessageSend) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocAllocationExpression) {
+				binding = ((JavadocAllocationExpression) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleNameReference) {
+				binding = ((JavadocSingleNameReference) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else {
+				binding = this.selectedNode.resolvedType;
+			}
+			throw new SelectionNodeFound(binding);
+		} else if (this.inheritDocSelected) {
+			// no selection node when inheritDoc tag is selected
+			// But we need to detect it to enable code select on inheritDoc
+			ReferenceContext referenceContext = scope.referenceContext();
+			if (referenceContext instanceof MethodDeclaration) {
+				throw new SelectionNodeFound(((MethodDeclaration) referenceContext).binding);
+			}
+		}
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws SelectionNodeFound
+	 */
+	public void resolve(ClassScope scope) {
+		internalResolve(scope);
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 *
+	 * @throws SelectionNodeFound
+	 */
+	public void resolve(MethodScope scope) {
+		internalResolve(scope);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java
new file mode 100644
index 0000000..7c8fb62
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
+
+/**
+ * Parser specialized for decoding javadoc comments which includes code selection.
+ */
+public class SelectionJavadocParser extends JavadocParser {
+
+	int selectionStart;
+	int selectionEnd;
+	ASTNode selectedNode;
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171019
+	public boolean inheritDocTagSelected;
+
+	public SelectionJavadocParser(SelectionParser sourceParser) {
+		super(sourceParser);
+		this.shouldReportProblems = false;
+		this.reportProblems = false;
+		this.kind = SELECTION_PARSER | TEXT_PARSE;
+		this.inheritDocTagSelected = false;
+	}
+
+	/*
+	 * Do not parse comment if selection is not included.
+	 */
+	public boolean checkDeprecation(int commentPtr) {
+		this.selectionStart = ((SelectionParser)this.sourceParser).selectionStart;
+		this.selectionEnd = ((SelectionParser)this.sourceParser).selectionEnd;
+		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
+		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr];
+		if (this.javadocStart <= this.selectionStart && this.selectionEnd <= this.javadocEnd) {
+			if (SelectionEngine.DEBUG) {
+				System.out.println("SELECTION in Javadoc:"); //$NON-NLS-1$
+			}
+			super.checkDeprecation(commentPtr);
+		} else {
+			this.docComment = null;
+		}
+		return false;
+	}
+
+	/*
+	 * Replace stored Javadoc node with specific selection one.
+	 */
+	protected boolean commentParse() {
+		this.docComment = new SelectionJavadoc(this.javadocStart, this.javadocEnd);
+		return super.commentParse();
+	}
+
+	/*
+	 * Create argument expression and store it if it includes selection.
+	 */
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+		// Create argument as we may need it after
+		Expression expression = (Expression) super.createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+		// See if selection is in argument
+		int start = ((TypeReference)typeRef).sourceStart;
+		int end = ((TypeReference)typeRef).sourceEnd;
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			this.selectedNode = expression;
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected argument="+this.selectedNode); //$NON-NLS-1$
+			}
+		}
+		return expression;
+	}
+
+	/*
+	 * Verify if field identifier positions include selection.
+	 * If so, create field reference, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createFieldReference(Object receiver) throws InvalidInputException {
+		int start = (int) (this.identifierPositionStack[0] >>> 32);
+		int end = (int) this.identifierPositionStack[0];
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			this.selectedNode = (ASTNode) super.createFieldReference(receiver);
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected field="+this.selectedNode); //$NON-NLS-1$
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Verify if method identifier positions include selection.
+	 * If so, create field reference, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+		int memberPtr = this.identifierLengthStack[0] - 1;	// may be > 0 for inner class constructor reference
+		int start = (int) (this.identifierPositionStack[memberPtr] >>> 32);
+		int end = (int) this.identifierPositionStack[memberPtr];
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			this.selectedNode = (ASTNode) super.createMethodReference(receiver, arguments);
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected method="+this.selectedNode); //$NON-NLS-1$
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Create type reference and verify if it includes selection.
+	 * If so, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createTypeReference(int primitiveToken) {
+		// Need to create type ref in case it was needed by members
+		TypeReference typeRef = (TypeReference) super.createTypeReference(primitiveToken);
+
+		// See if node is concerned by selection
+		if (typeRef.sourceStart <= this.selectionStart && this.selectionEnd <= typeRef.sourceEnd) {
+			// See if selection is in one of tokens of qualification
+			if (typeRef instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference qualifiedTypeRef = (JavadocQualifiedTypeReference) typeRef;
+				int size = qualifiedTypeRef.tokens.length - 1;
+				for (int i=0; i<size; i++) {
+					int start = (int) (qualifiedTypeRef.sourcePositions[i] >>> 32);
+					int end = (int) qualifiedTypeRef.sourcePositions[i];
+					if (start <= this.selectionStart && this.selectionEnd <= end) {
+						int pos = i + 1;
+						char[][] tokens = new char[pos][];
+						int ptr = this.identifierPtr - size;
+						System.arraycopy(this.identifierStack, ptr, tokens, 0, pos);
+						long[] positions = new long[pos];
+						System.arraycopy(this.identifierPositionStack, ptr, positions, 0, pos);
+						this.selectedNode = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd);
+						this.abort = true; // we got selected node => cancel parse
+						if (SelectionEngine.DEBUG) {
+							System.out.println("	selected partial qualified type="+this.selectedNode); //$NON-NLS-1$
+						}
+						return typeRef;
+					}
+				}
+				// Selection is in last token => we'll store type ref as this
+			}
+			// Store type ref as selected node
+			this.selectedNode = typeRef;
+			this.abort = true; // we got selected node => cancel parse
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected type="+this.selectedNode); //$NON-NLS-1$
+			}
+		}
+		return typeRef;
+	}
+
+	/*
+	 * Push param reference and verify if it includes selection.
+	 * If so, store it and abort comment parse.
+	 */
+	protected boolean pushParamName(boolean isTypeParam) {
+		if (super.pushParamName(isTypeParam)) {
+			Expression expression = (Expression) this.astStack[this.astPtr--];
+			// See if expression is concerned by selection
+			if (expression.sourceStart <= this.selectionStart && this.selectionEnd <= expression.sourceEnd) {
+				this.selectedNode = expression;
+				this.abort = true; // we got selected node => cancel parse
+				if (SelectionEngine.DEBUG) {
+					System.out.println("	selected param="+this.selectedNode); //$NON-NLS-1$
+				}
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * Store selected node into doc comment.
+	 */
+	protected void updateDocComment() {
+		if (this.selectedNode instanceof Expression) {
+			((SelectionJavadoc) this.docComment).selectedNode = (Expression) this.selectedNode;
+		} else if (this.inheritDocTagSelected) {
+			((SelectionJavadoc) this.docComment).inheritDocSelected = true;
+		}
+	}
+	
+	/*
+	 * Sets a flag to denote that selection has taken place on an inheritDoc tag
+	 */
+	protected void parseInheritDocTag() {
+		if (this.tagSourceStart == this.selectionStart && this.tagSourceEnd == this.selectionEnd)
+			this.inheritDocTagSelected = true;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
new file mode 100644
index 0000000..9c94418
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SelectionNodeFound extends RuntimeException {
+
+	public Binding binding;
+	public boolean isDeclaration;
+	private static final long serialVersionUID = -7335444736618092295L; // backward compatible
+
+public SelectionNodeFound() {
+	this(null, false); // we found a problem in the selection node
+}
+public SelectionNodeFound(Binding binding) {
+	this(binding, false);
+}
+public SelectionNodeFound(Binding binding, boolean isDeclaration) {
+	this.binding = binding;
+	this.isDeclaration = isDeclaration;
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java
new file mode 100644
index 0000000..bbbce40
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnArgumentName extends Argument {
+
+	public SelectionOnArgumentName(char[] name , long posNom , TypeReference tr , int modifiers){
+
+		super(name, posNom, tr, modifiers);
+	}
+
+	public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) {
+
+		super.bind(scope, typeBinding, used);
+		throw new SelectionNodeFound(this.binding);
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		printIndent(indent, output);
+		output.append("<SelectionOnArgumentName:"); //$NON-NLS-1$
+		if (this.type != null) this.type.print(0, output).append(' ');
+		output.append(this.name);
+		if (this.initialization != null) {
+			output.append(" = ");//$NON-NLS-1$
+			this.initialization.printExpression(0, output);
+		}
+		return output.append('>');
+	}
+
+	public void resolve(BlockScope scope) {
+
+		super.resolve(scope);
+		throw new SelectionNodeFound(this.binding);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java
new file mode 100644
index 0000000..a8a5740
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce an explicit constructor call containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      Y.[start]super[end](1, 2)
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <SelectOnExplicitConstructorCall:Y.super(1, 2)>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SelectionOnExplicitConstructorCall extends ExplicitConstructorCall {
+
+	public SelectionOnExplicitConstructorCall(int accessMode) {
+
+		super(accessMode);
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output);
+		output.append("<SelectOnExplicitConstructorCall:"); //$NON-NLS-1$
+		if (this.qualification != null) this.qualification.printExpression(0, output).append('.');
+		if (this.accessMode == This) {
+			output.append("this("); //$NON-NLS-1$
+		} else {
+			output.append("super("); //$NON-NLS-1$
+		}
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(")>;"); //$NON-NLS-1$
+	}
+
+	public void resolve(BlockScope scope) {
+
+		super.resolve(scope);
+
+		// tolerate some error cases
+		if (this.binding == null ||
+				!(this.binding.isValidBinding() ||
+					this.binding.problemId() == ProblemReasons.NotVisible))
+			throw new SelectionNodeFound();
+		else
+			throw new SelectionNodeFound(this.binding);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java
new file mode 100644
index 0000000..4e75655
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a field reference containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      bar().[start]fred[end]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <SelectOnFieldReference:bar().fred>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnFieldReference extends FieldReference {
+
+	public SelectionOnFieldReference(char[] source , long pos) {
+
+		super(source, pos);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		output.append("<SelectionOnFieldReference:");  //$NON-NLS-1$
+		return super.printExpression(0, output).append('>');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		super.resolveType(scope);
+		// tolerate some error cases
+		if (this.binding == null ||
+				!(this.binding.isValidBinding() ||
+					this.binding.problemId() == ProblemReasons.NotVisible
+					|| this.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext))
+			throw new SelectionNodeFound();
+		else
+			throw new SelectionNodeFound(this.binding);
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java
new file mode 100644
index 0000000..a4838b0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+
+public class SelectionOnFieldType extends FieldDeclaration {
+	public SelectionOnFieldType(TypeReference type) {
+		super();
+		this.sourceStart = type.sourceStart;
+		this.sourceEnd = type.sourceEnd;
+		this.type = type;
+		this.name = CharOperation.NO_CHAR;
+	}
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+		return this.type.print(tab, output).append(';');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java
new file mode 100644
index 0000000..10dcce3
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce an import reference containing the assist identifier.
+ * e.g.
+ *
+ *  import java.[start]io[end].*;
+ *	class X {
+ *    void foo() {
+ *    }
+ *  }
+ *
+ *	---> <SelectOnImport:java.io>
+ *		 class X {
+ *         void foo() {
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class SelectionOnImportReference extends ImportReference {
+
+public SelectionOnImportReference(char[][] tokens , long[] positions, int modifiers) {
+	super(tokens, positions, false, modifiers);
+}
+public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) {
+
+	printIndent(indent, output).append("<SelectOnImport:"); //$NON-NLS-1$
+	for (int i = 0; i < this.tokens.length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
new file mode 100644
index 0000000..fbf92c4
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+public class SelectionOnLocalName extends LocalDeclaration{
+
+	public SelectionOnLocalName(char[] name,	int sourceStart, int sourceEnd) {
+
+		super(name, sourceStart, sourceEnd);
+	}
+
+	public void resolve(BlockScope scope) {
+
+		super.resolve(scope);
+		throw new SelectionNodeFound(this.binding);
+	}
+
+	public StringBuffer printAsExpression(int indent, StringBuffer output) {
+		printIndent(indent, output);
+		output.append("<SelectionOnLocalName:"); //$NON-NLS-1$
+		printModifiers(this.modifiers, output);
+		 this.type.print(0, output).append(' ').append(this.name);
+		if (this.initialization != null) {
+			output.append(" = "); //$NON-NLS-1$
+			this.initialization.printExpression(0, output);
+		}
+		return output.append('>');
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		printAsExpression(indent, output);
+		return output.append(';');
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
new file mode 100644
index 0000000..2485446
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a message send containing the cursor.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      this.[start]bar[end](1, 2)
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <SelectOnMessageSend:this.bar(1, 2)>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnMessageSend extends MessageSend {
+
+	/*
+	 * Cannot answer default abstract match, iterate in superinterfaces of declaring class
+	 * for a better match (default abstract match came from scope lookups).
+	 */
+	private MethodBinding findNonDefaultAbstractMethod(MethodBinding methodBinding) {
+
+		ReferenceBinding[] itsInterfaces = methodBinding.declaringClass.superInterfaces();
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding currentType = interfacesToVisit[i];
+				MethodBinding[] methods = currentType.getMethods(methodBinding.selector);
+				if(methods != null) {
+					for (int k = 0; k < methods.length; k++) {
+						if(methodBinding.areParametersEqual(methods[k]))
+							return methods[k];
+					}
+				}
+
+				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+		return methodBinding;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append("<SelectOnMessageSend:"); //$NON-NLS-1$
+		if (!this.receiver.isImplicitThis()) this.receiver.printExpression(0, output).append('.');
+		output.append(this.selector).append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(")>"); //$NON-NLS-1$
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		super.resolveType(scope);
+
+		// tolerate some error cases
+		if(this.binding == null ||
+					!(this.binding.isValidBinding() ||
+						this.binding.problemId() == ProblemReasons.NotVisible
+						|| this.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName
+						|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation
+						|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext)) {
+			throw new SelectionNodeFound();
+		} else {
+			if(this.binding.isDefaultAbstract()) {
+				throw new SelectionNodeFound(findNonDefaultAbstractMethod(this.binding)); // 23594
+			} else {
+				throw new SelectionNodeFound(this.binding);
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java
new file mode 100644
index 0000000..b703dc3
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class SelectionOnNameOfMemberValuePair extends MemberValuePair {
+
+	public SelectionOnNameOfMemberValuePair(char[] token, int sourceStart, int sourceEnd, Expression value) {
+		super(token, sourceStart, sourceEnd, value);
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+		output.append("<SelectOnName:"); //$NON-NLS-1$
+		output.append(this.name);
+		output.append(">"); //$NON-NLS-1$
+		return output;
+	}
+
+	public void resolveTypeExpecting(BlockScope scope, TypeBinding requiredType) {
+		super.resolveTypeExpecting(scope, requiredType);
+
+		if(this.binding != null) {
+			throw new SelectionNodeFound(this.binding);
+		}
+		throw new SelectionNodeFound();
+	}
+}
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
new file mode 100644
index 0000000..1457479
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce an package statement containing the assist identifier.
+ * e.g.
+ *
+ *  package java.[start]io[end];
+ *	class X {
+ *    void foo() {
+ *    }
+ *  }
+ *
+ *	---> <SelectOnPackage:java.io>
+ *		 class X {
+ *         void foo() {
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class SelectionOnPackageReference extends ImportReference {
+public SelectionOnPackageReference(char[][] tokens , long[] positions) {
+	super(tokens, positions, false, ClassFileConstants.AccDefault);
+}
+public StringBuffer print(int tab, StringBuffer output, boolean withOnDemand) {
+	printIndent(tab, output).append("<SelectOnPackage:"); //$NON-NLS-1$
+	for (int i = 0; i < this.tokens.length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
new file mode 100644
index 0000000..fa26161
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnParameterizedQualifiedTypeReference extends ParameterizedQualifiedTypeReference {
+	public SelectionOnParameterizedQualifiedTypeReference(char[][] previousIdentifiers, char[] selectionIdentifier, TypeReference[][] typeArguments, TypeReference[] assistTypeArguments, long[] positions) {
+		super(
+			CharOperation.arrayConcat(previousIdentifiers, selectionIdentifier),
+			typeArguments,
+			0,
+			positions);
+		int length =  this.typeArguments.length;
+		System.arraycopy(this.typeArguments, 0, this.typeArguments = new TypeReference[length + 1][], 0, length);
+		this.typeArguments[length] = assistTypeArguments;
+	}
+
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		super.resolveType(scope, checkBounds);
+		//// removed unnecessary code to solve bug 94653
+		//if(this.resolvedType != null && this.resolvedType.isRawType()) {
+		//	ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
+		//	throw new SelectionNodeFound(parameterizedTypeBinding);
+		//}
+		throw new SelectionNodeFound(this.resolvedType);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		super.resolveType(scope);
+		//// removed unnecessary code to solve bug 94653
+		//if(this.resolvedType != null && this.resolvedType.isRawType()) {
+		//	ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
+		//	throw new SelectionNodeFound(parameterizedTypeBinding);
+		//}
+		throw new SelectionNodeFound(this.resolvedType);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("<SelectOnType:");//$NON-NLS-1$
+		int length = this.tokens.length;
+		for (int i = 0; i < length; i++) {
+			if(i != 0) {
+				output.append('.');
+			}
+			output.append(this.tokens[i]);
+			TypeReference[] typeArgument = this.typeArguments[i];
+			if (typeArgument != null) {
+				output.append('<');
+				int max = typeArgument.length - 1;
+				for (int j = 0; j < max; j++) {
+					typeArgument[j].print(0, output);
+					output.append(", ");//$NON-NLS-1$
+				}
+				typeArgument[max].print(0, output);
+				output.append('>');
+			}
+
+		}
+		output.append('>');
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java
new file mode 100644
index 0000000..57f749a
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnParameterizedSingleTypeReference extends ParameterizedSingleTypeReference {
+	public SelectionOnParameterizedSingleTypeReference(char[] name, TypeReference[] typeArguments, long pos){
+		super(name, typeArguments, 0, pos);
+	}
+
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		super.resolveType(scope, checkBounds);
+		throw new SelectionNodeFound(this.resolvedType);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		super.resolveType(scope);
+		throw new SelectionNodeFound(this.resolvedType);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+		output.append("<SelectOnType:");//$NON-NLS-1$
+		output.append(this.token);
+		output.append('<');
+		int max = this.typeArguments.length - 1;
+		for (int i= 0; i < max; i++) {
+			this.typeArguments[i].print(0, output);
+			output.append(", ");//$NON-NLS-1$
+		}
+		this.typeArguments[max].print(0, output);
+		output.append('>');
+		output.append('>');
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java
new file mode 100644
index 0000000..356be94
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce an allocation expression containing the cursor.
+ * If the allocation expression is not qualified, the enclosingInstance field
+ * is null.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      new [start]Bar[end](1, 2)
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <SelectOnAllocationExpression:new Bar(1, 2)>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnQualifiedAllocationExpression extends QualifiedAllocationExpression {
+
+	public SelectionOnQualifiedAllocationExpression() {
+		// constructor without argument
+	}
+
+	public SelectionOnQualifiedAllocationExpression(TypeDeclaration anonymous) {
+		super(anonymous);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		if (this.enclosingInstance == null)
+			output.append("<SelectOnAllocationExpression:");  //$NON-NLS-1$
+		else
+			output.append("<SelectOnQualifiedAllocationExpression:"); //$NON-NLS-1$
+
+		return super.printExpression(indent, output).append('>');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		super.resolveType(scope);
+
+		if (this.binding == null) {
+			throw new SelectionNodeFound();
+		}
+
+		// tolerate some error cases
+		if (!this.binding.isValidBinding()) {
+			switch (this.binding.problemId()) {
+				case ProblemReasons.NotVisible:
+					// visibility is ignored
+					break;
+				case ProblemReasons.NotFound:
+					if (this.resolvedType != null && this.resolvedType.isValidBinding()) {
+						throw new SelectionNodeFound(this.resolvedType);
+					}
+					throw new SelectionNodeFound();
+				default:
+					throw new SelectionNodeFound();
+			}
+		}
+
+		if (this.anonymousType == null)
+			throw new SelectionNodeFound(this.binding);
+
+		// if selecting a type for an anonymous type creation, we have to
+		// find its target super constructor (if extending a class) or its target
+		// super interface (if extending an interface)
+		if (this.anonymousType.binding != null) {
+			LocalTypeBinding localType = (LocalTypeBinding) this.anonymousType.binding;
+			if (localType.superInterfaces == Binding.NO_SUPERINTERFACES) {
+				// find the constructor binding inside the super constructor call
+				ConstructorDeclaration constructor = (ConstructorDeclaration) this.anonymousType.declarationOf(this.binding.original());
+				if (constructor != null) {
+					throw new SelectionNodeFound(constructor.constructorCall.binding);
+				}
+				throw new SelectionNodeFound(this.binding);
+			}
+			// open on the only super interface
+			throw new SelectionNodeFound(localType.superInterfaces[0]);
+		} else {
+			if (this.resolvedType.isInterface()) {
+				throw new SelectionNodeFound(this.resolvedType);
+			}
+			throw new SelectionNodeFound(this.binding);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java
new file mode 100644
index 0000000..931710f
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a qualified name reference containing the assist identifier.
+ * e.g.
+ *
+ *	class X {
+ *    Y y;
+ *    void foo() {
+ *      y.fred.[start]ba[end]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         Y y;
+ *         void foo() {
+ *           <SelectOnName:y.fred.ba>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnQualifiedNameReference extends QualifiedNameReference {
+
+public SelectionOnQualifiedNameReference(char[][] previousIdentifiers, char[] selectionIdentifier, long[] positions) {
+	super(
+		CharOperation.arrayConcat(previousIdentifiers, selectionIdentifier),
+		positions,
+		(int) (positions[0] >>> 32),
+		(int) positions[positions.length - 1]);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+
+	output.append("<SelectOnName:"); //$NON-NLS-1$
+	for (int i = 0, length = this.tokens.length; i < length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// it can be a package, type, member type, local variable or field
+	this.binding = scope.getBinding(this.tokens, this);
+	if (!this.binding.isValidBinding()) {
+		if (this.binding instanceof ProblemFieldBinding) {
+			// tolerate some error cases
+			if (this.binding.problemId() == ProblemReasons.NotVisible
+					|| this.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext) {
+				throw new SelectionNodeFound(this.binding);
+			}
+			scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
+		} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
+			// tolerate some error cases
+			if (this.binding.problemId() == ProblemReasons.NotVisible){
+				throw new SelectionNodeFound(this.binding);
+			}
+			scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
+		} else {
+			scope.problemReporter().unresolvableReference(this, this.binding);
+		}
+		throw new SelectionNodeFound();
+	}
+	throw new SelectionNodeFound(this.binding);
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java
new file mode 100644
index 0000000..e2277ec
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a qualified super reference containing the assist identifier.
+ * e.g.
+ *
+ *	class X extends Z {
+ *    class Y {
+ *    	void foo() {
+ *      	X.[start]super[end].bar();
+ *      }
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *		   class Y {
+ *           void foo() {
+ *             <SelectOnQualifiedSuper:X.super>
+ *           }
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnQualifiedSuperReference extends QualifiedSuperReference {
+public SelectionOnQualifiedSuperReference(TypeReference name, int pos, int sourceEnd) {
+	super(name, pos, sourceEnd);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+
+	output.append("<SelectOnQualifiedSuper:"); //$NON-NLS-1$
+	return super.printExpression(0, output).append('>');
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	TypeBinding binding = super.resolveType(scope);
+
+	if (binding == null || !binding.isValidBinding())
+		throw new SelectionNodeFound();
+	else
+		throw new SelectionNodeFound(binding);
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java
new file mode 100644
index 0000000..75d7a0d
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a type reference containing the completion identifier as part
+ * of a qualified name.
+ * e.g.
+ *
+ *	class X extends java.lang.[start]Object[end]
+ *
+ *	---> class X extends <SelectOnType:java.lang.Object>
+ *
+ */
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnQualifiedTypeReference extends QualifiedTypeReference {
+public SelectionOnQualifiedTypeReference(char[][] previousIdentifiers, char[] selectionIdentifier, long[] positions) {
+	super(
+		CharOperation.arrayConcat(previousIdentifiers, selectionIdentifier),
+		positions);
+}
+public void aboutToResolve(Scope scope) {
+	getTypeBinding(scope.parent); // step up from the ClassScope
+}
+protected TypeBinding getTypeBinding(Scope scope) {
+	// it can be a package, type or member type
+	Binding binding = scope.getTypeOrPackage(this.tokens);
+	if (!binding.isValidBinding()) {
+		// tolerate some error cases
+		if (binding.problemId() == ProblemReasons.NotVisible){
+			throw new SelectionNodeFound(binding);
+		}
+
+		if (binding instanceof TypeBinding) {
+			scope.problemReporter().invalidType(this, (TypeBinding) binding);
+		} else if (binding instanceof PackageBinding) {
+			ProblemReferenceBinding problemBinding = new ProblemReferenceBinding(((PackageBinding)binding).compoundName, null, binding.problemId());
+			scope.problemReporter().invalidType(this, problemBinding);
+		}
+
+		throw new SelectionNodeFound();
+	}
+
+	throw new SelectionNodeFound(binding);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+
+	output.append("<SelectOnType:"); //$NON-NLS-1$
+	for (int i = 0, length = this.tokens.length; i < length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output.append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java
new file mode 100644
index 0000000..369851e
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a single name reference containing the assist identifier.
+ * e.g.
+ *
+ *	class X {
+ *    void foo() {
+ *      [start]ba[end]
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *         void foo() {
+ *           <SelectOnName:ba>
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnSingleNameReference extends SingleNameReference {
+public SelectionOnSingleNameReference(char[] source, long pos) {
+	super(source, pos);
+}
+public TypeBinding resolveType(BlockScope scope) {
+	if (this.actualReceiverType != null) {
+		this.binding = scope.getField(this.actualReceiverType, this.token, this);
+		if (this.binding != null && this.binding.isValidBinding()) {
+			throw new SelectionNodeFound(this.binding);
+		}
+	}
+	// it can be a package, type, member type, local variable or field
+	this.binding = scope.getBinding(this.token, Binding.VARIABLE | Binding.TYPE | Binding.PACKAGE, this, true /*resolve*/);
+	if (!this.binding.isValidBinding()) {
+		if (this.binding instanceof ProblemFieldBinding) {
+			// tolerate some error cases
+			if (this.binding.problemId() == ProblemReasons.NotVisible
+					|| this.binding.problemId() == ProblemReasons.InheritedNameHidesEnclosingName
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInConstructorInvocation
+					|| this.binding.problemId() == ProblemReasons.NonStaticReferenceInStaticContext){
+				throw new SelectionNodeFound(this.binding);
+			}
+			scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
+		} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
+			// tolerate some error cases
+			if (this.binding.problemId() == ProblemReasons.NotVisible){
+				throw new SelectionNodeFound(this.binding);
+			}
+			scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
+		} else {
+			scope.problemReporter().unresolvableReference(this, this.binding);
+		}
+		throw new SelectionNodeFound();
+	}
+
+	throw new SelectionNodeFound(this.binding);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	output.append("<SelectOnName:"); //$NON-NLS-1$
+	return super.printExpression(0, output).append('>');
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java
new file mode 100644
index 0000000..66490a2
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a type reference containing the selection identifier as a single
+ * name reference.
+ * e.g.
+ *
+ *	class X extends [start]Object[end]
+ *
+ *	---> class X extends <SelectOnType:Object>
+ *
+ */
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnSingleTypeReference extends SingleTypeReference {
+public SelectionOnSingleTypeReference(char[] source, long pos) {
+	super(source, pos);
+}
+public void aboutToResolve(Scope scope) {
+	getTypeBinding(scope.parent); // step up from the ClassScope
+}
+protected TypeBinding getTypeBinding(Scope scope) {
+	// it can be a package, type or member type
+	Binding binding = scope.getTypeOrPackage(new char[][] {this.token});
+	if (!binding.isValidBinding()) {
+		if (binding instanceof TypeBinding) {
+			scope.problemReporter().invalidType(this, (TypeBinding) binding);
+		} else if (binding instanceof PackageBinding) {
+			ProblemReferenceBinding problemBinding = new ProblemReferenceBinding(((PackageBinding)binding).compoundName, null, binding.problemId());
+			scope.problemReporter().invalidType(this, problemBinding);
+		}
+		throw new SelectionNodeFound();
+	}
+	throw new SelectionNodeFound(binding);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+
+	return output.append("<SelectOnType:").append(this.token).append('>');//$NON-NLS-1$
+}
+public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
+	super.resolveTypeEnclosing(scope, enclosingType);
+
+		// tolerate some error cases
+		if (this.resolvedType == null ||
+				!(this.resolvedType.isValidBinding() ||
+					this.resolvedType.problemId() == ProblemReasons.NotVisible))
+		throw new SelectionNodeFound();
+	else
+		throw new SelectionNodeFound(this.resolvedType);
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java
new file mode 100644
index 0000000..17a1aec
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Selection node build by the parser in any case it was intending to
+ * reduce a super reference containing the assist identifier.
+ * e.g.
+ *
+ *	class X extends Z {
+ *    class Y {
+ *    	void foo() {
+ *      	[start]super[end].bar();
+ *      }
+ *    }
+ *  }
+ *
+ *	---> class X {
+ *		   class Y {
+ *           void foo() {
+ *             <SelectOnQualifiedSuper:super>
+ *           }
+ *         }
+ *       }
+ *
+ */
+
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SelectionOnSuperReference extends SuperReference {
+
+public SelectionOnSuperReference(int pos, int sourceEnd) {
+	super(pos, sourceEnd);
+}
+public StringBuffer printExpression(int indent, StringBuffer output){
+
+	output.append("<SelectOnSuper:"); //$NON-NLS-1$
+	return super.printExpression(0, output).append('>');
+}
+public TypeBinding resolveType(BlockScope scope) {
+	TypeBinding binding = super.resolveType(scope);
+
+	if (binding == null || !binding.isValidBinding())
+		throw new SelectionNodeFound();
+	else
+		throw new SelectionNodeFound(binding);
+}
+}
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
new file mode 100644
index 0000000..90722bf
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -0,0 +1,1459 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Parser able to build specific completion parse nodes, given a cursorLocation.
+ *
+ * Cursor location denotes the position of the last character behind which completion
+ * got requested:
+ *  -1 means completion at the very beginning of the source
+ *	0  means completion behind the first character
+ *  n  means completion behind the n-th character
+ */
+
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.impl.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class SelectionParser extends AssistParser {
+	// OWNER
+	protected static final int SELECTION_PARSER = 1024;
+	protected static final int SELECTION_OR_ASSIST_PARSER = ASSIST_PARSER + SELECTION_PARSER;
+
+	// KIND : all values known by SelectionParser are between 1025 and 1549
+	protected static final int K_BETWEEN_CASE_AND_COLON = SELECTION_PARSER + 1; // whether we are inside a block
+	protected static final int K_INSIDE_RETURN_STATEMENT = SELECTION_PARSER + 2; // whether we are between the keyword 'return' and the end of a return statement
+	protected static final int K_CAST_STATEMENT = SELECTION_PARSER + 3; // whether we are between ')' and the end of a cast statement
+	
+
+	public ASTNode assistNodeParent; // the parent node of assist node
+
+	/* public fields */
+
+	public int selectionStart, selectionEnd;
+
+	public static final char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+	public static final char[] THIS = "this".toCharArray(); //$NON-NLS-1$
+
+public SelectionParser(ProblemReporter problemReporter) {
+	super(problemReporter);
+	this.javadocParser.checkDocComment = true;
+}
+public char[] assistIdentifier(){
+	return ((SelectionScanner)this.scanner).selectionIdentifier;
+}
+protected void attachOrphanCompletionNode(){
+	if (this.isOrphanCompletionNode){
+		ASTNode orphan = this.assistNode;
+		this.isOrphanCompletionNode = false;
+
+
+		/* if in context of a type, then persists the identifier into a fake field return type */
+		if (this.currentElement instanceof RecoveredType){
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			/* filter out cases where scanner is still inside type header */
+			if (recoveredType.foundOpeningBrace) {
+				/* generate a pseudo field with a completion on type reference */
+				if (orphan instanceof TypeReference){
+					this.currentElement = this.currentElement.add(new SelectionOnFieldType((TypeReference)orphan), 0);
+					return;
+				}
+			}
+		}
+
+		if (orphan instanceof Expression) {
+			buildMoreCompletionContext((Expression)orphan);
+		} else {
+			Statement statement = (Statement) orphan;
+			this.currentElement = this.currentElement.add(statement, 0);
+		}
+		this.currentToken = 0; // given we are not on an eof, we do not want side effects caused by looked-ahead token
+	}
+}
+private void buildMoreCompletionContext(Expression expression) {
+	ASTNode parentNode = null;
+
+	int kind = topKnownElementKind(SELECTION_OR_ASSIST_PARSER);
+	if(kind != 0) {
+		int info = topKnownElementInfo(SELECTION_OR_ASSIST_PARSER);
+		nextElement : switch (kind) {
+			case K_BETWEEN_CASE_AND_COLON :
+				if(this.expressionPtr > 0) {
+					SwitchStatement switchStatement = new SwitchStatement();
+					switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
+					if(this.astLengthPtr > -1 && this.astPtr > -1) {
+						int length = this.astLengthStack[this.astLengthPtr];
+						int newAstPtr = this.astPtr - length;
+						ASTNode firstNode = this.astStack[newAstPtr + 1];
+						if(length != 0 && firstNode.sourceStart > switchStatement.expression.sourceEnd) {
+							switchStatement.statements = new Statement[length + 1];
+							System.arraycopy(
+								this.astStack,
+								newAstPtr + 1,
+								switchStatement.statements,
+								0,
+								length);
+						}
+					}
+					CaseStatement caseStatement = new CaseStatement(expression, expression.sourceStart, expression.sourceEnd);
+					if(switchStatement.statements == null) {
+						switchStatement.statements = new Statement[]{caseStatement};
+					} else {
+						switchStatement.statements[switchStatement.statements.length - 1] = caseStatement;
+					}
+					parentNode = switchStatement;
+					this.assistNodeParent = parentNode;
+				}
+				break nextElement;
+			case K_INSIDE_RETURN_STATEMENT :
+				if(info == this.bracketDepth) {
+					ReturnStatement returnStatement = new ReturnStatement(expression, expression.sourceStart, expression.sourceEnd);
+					parentNode = returnStatement;
+					this.assistNodeParent = parentNode;
+				}
+				break nextElement;
+			case K_CAST_STATEMENT :
+				Expression castType;
+				if(this.expressionPtr > 0
+					&& ((castType = this.expressionStack[this.expressionPtr-1]) instanceof TypeReference)) {
+					CastExpression cast = new CastExpression(expression, (TypeReference) castType);
+					cast.sourceStart = castType.sourceStart;
+					cast.sourceEnd= expression.sourceEnd;
+					parentNode = cast;
+					this.assistNodeParent = parentNode;
+				}
+				break nextElement;
+		}
+	}
+	if(parentNode != null) {
+		this.currentElement = this.currentElement.add((Statement)parentNode, 0);
+	} else {
+		this.currentElement = this.currentElement.add((Statement)wrapWithExplicitConstructorCallIfNeeded(expression), 0);
+		if(this.lastCheckPoint < expression.sourceEnd) {
+			this.lastCheckPoint = expression.sourceEnd + 1;
+		}
+	}
+}
+private boolean checkRecoveredType() {
+	if (this.currentElement instanceof RecoveredType){
+		/* check if current awaiting identifier is the completion identifier */
+		if (this.indexOfAssistIdentifier() < 0) return false;
+
+		if ((this.lastErrorEndPosition >= this.selectionStart)
+			&& (this.lastErrorEndPosition <= this.selectionEnd+1)){
+			return false;
+		}
+		RecoveredType recoveredType = (RecoveredType)this.currentElement;
+		/* filter out cases where scanner is still inside type header */
+		if (recoveredType.foundOpeningBrace) {
+			this.assistNode = this.getTypeReference(0);
+			this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+			this.isOrphanCompletionNode = true;
+			return true;
+		}
+	}
+	return false;
+}
+protected void classInstanceCreation(boolean hasClassBody) {
+
+	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+
+	// ClassBodyopt produces a null item on the astStak if it produces NO class body
+	// An empty class body produces a 0 on the length stack.....
+
+
+	if ((this.astLengthStack[this.astLengthPtr] == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+
+
+		int index;
+		if ((index = this.indexOfAssistIdentifier()) < 0) {
+			super.classInstanceCreation(hasClassBody);
+			return;
+		} else if(this.identifierLengthPtr > -1 &&
+					(this.identifierLengthStack[this.identifierLengthPtr] - 1) != index) {
+			super.classInstanceCreation(hasClassBody);
+			return;
+		}
+		QualifiedAllocationExpression alloc;
+		this.astPtr--;
+		this.astLengthPtr--;
+		alloc = new SelectionOnQualifiedAllocationExpression();
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		// trick to avoid creating a selection on type reference
+		char [] oldIdent = assistIdentifier();
+		setAssistIdentifier(null);
+		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
+
+		setAssistIdentifier(oldIdent);
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+
+		this.assistNode = alloc;
+		this.lastCheckPoint = alloc.sourceEnd + 1;
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	} else {
+		super.classInstanceCreation(hasClassBody);
+	}
+}
+protected void consumeArrayCreationExpressionWithoutInitializer() {
+	// ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
+	// ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
+
+	super.consumeArrayCreationExpressionWithoutInitializer();
+
+	ArrayAllocationExpression alloc = (ArrayAllocationExpression)this.expressionStack[this.expressionPtr];
+	if (alloc.type == this.assistNode){
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	}
+}
+protected void consumeArrayCreationExpressionWithInitializer() {
+	// ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
+
+	super.consumeArrayCreationExpressionWithInitializer();
+
+	ArrayAllocationExpression alloc = (ArrayAllocationExpression)this.expressionStack[this.expressionPtr];
+	if (alloc.type == this.assistNode){
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	}
+}
+protected void consumeCastExpressionLL1() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionLL1();
+}
+protected void consumeCastExpressionLL1WithBounds() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionLL1WithBounds();
+}
+protected void consumeCastExpressionWithGenericsArray() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionWithGenericsArray();
+}
+protected void consumeCastExpressionWithNameArray() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionWithNameArray();
+}
+protected void consumeCastExpressionWithPrimitiveType() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionWithPrimitiveType();
+}
+protected void consumeCastExpressionWithQualifiedGenericsArray() {
+	popElement(K_CAST_STATEMENT);
+	super.consumeCastExpressionWithQualifiedGenericsArray();
+}
+protected void consumeCatchFormalParameter() {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeCatchFormalParameter();
+		if((!this.diet || this.dietInt != 0) && this.astPtr > -1) {
+			Argument argument = (Argument) this.astStack[this.astPtr];
+			if(argument.type == this.assistNode) {
+				this.isOrphanCompletionNode = true;
+				this.restartRecovery	= true;	// force to restart in recovery mode
+				this.lastIgnoredToken = -1;
+			}
+		}
+	} else {
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		this.intPtr--; // dimension from the variabledeclaratorid
+		TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+		int modifierPositions = this.intStack[this.intPtr--];
+		this.intPtr--;
+		Argument arg =
+			new SelectionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		arg.bits &= ~ASTNode.IsArgument;
+		arg.declarationSourceStart = modifierPositions;
+
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+		}
+
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	// ClassInstanceCreationExpression ::= Primary '.' 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
+
+	QualifiedAllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr]) == 1) && (this.astStack[this.astPtr] == null)) {
+
+		if (this.indexOfAssistIdentifier() < 0) {
+			super.consumeClassInstanceCreationExpressionQualifiedWithTypeArguments();
+			return;
+		}
+
+		//NO ClassBody
+		this.astPtr--;
+		this.astLengthPtr--;
+		alloc = new SelectionOnQualifiedAllocationExpression();
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+
+		// trick to avoid creating a selection on type reference
+		char [] oldIdent = assistIdentifier();
+		setAssistIdentifier(null);
+		alloc.type = getTypeReference(0);
+		rejectIllegalLeadingTypeAnnotations(alloc.type);
+		checkForDiamond(alloc.type);
+
+		setAssistIdentifier(oldIdent);
+
+		length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--; // remove the position of the '<'
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+
+		this.assistNode = alloc;
+		this.lastCheckPoint = alloc.sourceEnd + 1;
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	} else {
+		super.consumeClassInstanceCreationExpressionQualifiedWithTypeArguments();
+	}
+
+	this.expressionLengthPtr--;
+	QualifiedAllocationExpression qae =
+		(QualifiedAllocationExpression) this.expressionStack[this.expressionPtr--];
+	qae.enclosingInstance = this.expressionStack[this.expressionPtr];
+	this.expressionStack[this.expressionPtr] = qae;
+	qae.sourceStart = qae.enclosingInstance.sourceStart;
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	// ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt
+	AllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr]) == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+
+		if (this.indexOfAssistIdentifier() < 0) {
+			super.consumeClassInstanceCreationExpressionWithTypeArguments();
+			return;
+		}
+
+		//NO ClassBody
+		this.astPtr--;
+		this.astLengthPtr--;
+		alloc = new SelectionOnQualifiedAllocationExpression();
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+
+		// trick to avoid creating a selection on type reference
+		char [] oldIdent = assistIdentifier();
+		setAssistIdentifier(null);
+		alloc.type = getTypeReference(0);
+		rejectIllegalLeadingTypeAnnotations(alloc.type);
+		checkForDiamond(alloc.type);
+
+		setAssistIdentifier(oldIdent);
+
+		length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--; // remove the position of the '<'
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+
+		this.assistNode = alloc;
+		this.lastCheckPoint = alloc.sourceEnd + 1;
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	} else {
+		super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	}
+}
+protected void consumeEnterAnonymousClassBody(boolean qualified) {
+	// EnterAnonymousClassBody ::= $empty
+
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeEnterAnonymousClassBody(qualified);
+		return;
+	}
+
+	// trick to avoid creating a selection on type reference
+	char [] oldIdent = assistIdentifier();
+	setAssistIdentifier(null);
+	TypeReference typeReference = getTypeReference(0);
+	setAssistIdentifier(oldIdent);
+
+	TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
+	anonymousType.name = CharOperation.NO_CHAR;
+	anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
+	QualifiedAllocationExpression alloc = new SelectionOnQualifiedAllocationExpression(anonymousType);
+	markEnclosingMemberWithLocalType();
+	pushOnAstStack(anonymousType);
+
+	alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
+	int argumentLength;
+	if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= argumentLength;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			alloc.arguments = new Expression[argumentLength],
+			0,
+			argumentLength);
+	}
+	
+	if (qualified) {
+		this.expressionLengthPtr--;
+		alloc.enclosingInstance = this.expressionStack[this.expressionPtr--];
+	}
+
+	alloc.type = typeReference;
+
+	anonymousType.sourceEnd = alloc.sourceEnd;
+	//position at the type while it impacts the anonymous declaration
+	anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
+	alloc.sourceStart = this.intStack[this.intPtr--];
+	pushOnExpressionStack(alloc);
+
+	this.assistNode = alloc;
+	this.lastCheckPoint = alloc.sourceEnd + 1;
+	if (!this.diet){
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+		this.currentToken = 0; // opening brace already taken into account
+		this.hasReportedError = true;
+	}
+
+	anonymousType.bodyStart = this.scanner.currentPosition;
+	this.listLength = 0; // will be updated when reading super-interfaces
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = anonymousType.bodyStart;
+		this.currentElement = this.currentElement.add(anonymousType, 0);
+		this.currentToken = 0; // opening brace already taken into account
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeEnterVariable() {
+	// EnterVariable ::= $empty
+	// do nothing by default
+
+	super.consumeEnterVariable();
+
+	AbstractVariableDeclaration variable = (AbstractVariableDeclaration) this.astStack[this.astPtr];
+	if (variable.type == this.assistNode){
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = false; // already attached inside variable decl
+	}
+}
+
+protected void consumeExitVariableWithInitialization() {
+	super.consumeExitVariableWithInitialization();
+
+	// does not keep the initialization if selection is not inside
+	AbstractVariableDeclaration variable = (AbstractVariableDeclaration) this.astStack[this.astPtr];
+	int start = variable.initialization.sourceStart;
+	int end =  variable.initialization.sourceEnd;
+	if ((this.selectionStart < start) &&  (this.selectionEnd < start) ||
+			(this.selectionStart > end) && (this.selectionEnd > end)) {
+		variable.initialization = null;
+	}
+
+}
+
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	// FieldAccess ::= Primary '.' 'Identifier'
+	// FieldAccess ::= 'super' '.' 'Identifier'
+
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeFieldAccess(isSuperAccess);
+		return;
+	}
+	FieldReference fieldReference =
+		new SelectionOnFieldReference(
+			this.identifierStack[this.identifierPtr],
+			this.identifierPositionStack[this.identifierPtr--]);
+	this.identifierLengthPtr--;
+	if (isSuperAccess) { //considerates the fieldReferenceerence beginning at the 'super' ....
+		fieldReference.sourceStart = this.intStack[this.intPtr--];
+		fieldReference.receiver = new SuperReference(fieldReference.sourceStart, this.endPosition);
+		pushOnExpressionStack(fieldReference);
+	} else { //optimize push/pop
+		if ((fieldReference.receiver = this.expressionStack[this.expressionPtr]).isThis()) { //fieldReferenceerence begins at the this
+			fieldReference.sourceStart = fieldReference.receiver.sourceStart;
+		}
+		this.expressionStack[this.expressionPtr] = fieldReference;
+	}
+	this.assistNode = fieldReference;
+	this.lastCheckPoint = fieldReference.sourceEnd + 1;
+	if (!this.diet){
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	}
+	this.isOrphanCompletionNode = true;
+}
+protected void consumeFormalParameter(boolean isVarArgs) {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeFormalParameter(isVarArgs);
+		if((!this.diet || this.dietInt != 0) && this.astPtr > -1) {
+			Argument argument = (Argument) this.astStack[this.astPtr];
+			if(argument.type == this.assistNode) {
+				this.isOrphanCompletionNode = true;
+				this.restartRecovery	= true;	// force to restart in recovery mode
+				this.lastIgnoredToken = -1;
+			}
+		}
+	} else {
+		boolean isReceiver = this.intStack[this.intPtr--] == 0;
+	    if (isReceiver) {
+	    	this.expressionPtr--;
+	    	this.expressionLengthPtr --;
+	    }
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		int extendedDimensions = this.intStack[this.intPtr--];
+		Annotation [][] annotationsOnExtendedDimensions = extendedDimensions == 0 ? null : getAnnotationsOnDimensions(extendedDimensions);
+		Annotation [] varArgsAnnotations = null;
+		int length;
+		int endOfEllipsis = 0;
+		if (isVarArgs) {
+			endOfEllipsis = this.intStack[this.intPtr--];
+			if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+				System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					varArgsAnnotations = new Annotation[length],
+					0,
+					length);
+			} 
+		}
+		int firstDimensions = this.intStack[this.intPtr--];
+		TypeReference type = getTypeReference(firstDimensions);
+
+		final int typeDimensions = firstDimensions + extendedDimensions + (isVarArgs ? 1 : 0);
+		if (typeDimensions != firstDimensions) {
+			// jsr308 type annotations management
+			Annotation [][] annotationsOnFirstDimensions = firstDimensions == 0 ? null : type.getAnnotationsOnDimensions();
+			Annotation [][] annotationsOnAllDimensions = annotationsOnFirstDimensions;
+			if (annotationsOnExtendedDimensions != null) {
+				annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions, annotationsOnFirstDimensions, extendedDimensions, annotationsOnExtendedDimensions);
+			}
+			if (varArgsAnnotations != null) {
+				annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions + extendedDimensions, annotationsOnAllDimensions, 1, new Annotation[][]{varArgsAnnotations});
+			}
+			type = copyDims(type, typeDimensions, annotationsOnAllDimensions);
+			type.sourceEnd = type.isParameterizedTypeReference() ? this.endStatementPosition : this.endPosition;
+		}
+		if (isVarArgs) {
+			if (extendedDimensions == 0) {
+				type.sourceEnd = endOfEllipsis;
+			}
+			type.bits |= ASTNode.IsVarArgs; // set isVarArgs
+		}
+		int modifierPositions = this.intStack[this.intPtr--];
+		this.intPtr--;
+		Argument arg =
+			new SelectionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		arg.declarationSourceStart = modifierPositions;
+
+		// consume annotations
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+			RecoveredType currentRecoveryType = this.currentRecoveryType();
+			if (currentRecoveryType != null)
+				currentRecoveryType.annotationsConsumed(arg.annotations);
+		}
+
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
+protected void consumeInsideCastExpression() {
+	super.consumeInsideCastExpression();
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionLL1() {
+	super.consumeInsideCastExpressionLL1();
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionLL1WithBounds() {
+	super.consumeInsideCastExpressionLL1WithBounds();
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInsideCastExpressionWithQualifiedGenerics() {
+	super.consumeInsideCastExpressionWithQualifiedGenerics();
+	pushOnElementStack(K_CAST_STATEMENT);
+}
+protected void consumeInstanceOfExpression() {
+	if (indexOfAssistIdentifier() < 0) {
+		super.consumeInstanceOfExpression();
+	} else {
+		getTypeReference(this.intStack[this.intPtr--]);
+		this.isOrphanCompletionNode = true;
+		this.restartRecovery = true;
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeInstanceOfExpressionWithName() {
+	if (indexOfAssistIdentifier() < 0) {
+		super.consumeInstanceOfExpressionWithName();
+	} else {
+		getTypeReference(this.intStack[this.intPtr--]);
+		this.isOrphanCompletionNode = true;
+		this.restartRecovery = true;
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeLocalVariableDeclarationStatement() {
+	super.consumeLocalVariableDeclarationStatement();
+
+	// force to restart in recovery mode if the declaration contains the selection
+	if (!this.diet) {
+		LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
+		if ((this.selectionStart >= localDeclaration.sourceStart)
+				&&  (this.selectionEnd <= localDeclaration.sourceEnd)) {
+			this.restartRecovery	= true;
+			this.lastIgnoredToken = -1;
+		}
+	}
+}
+protected void consumeMarkerAnnotation(boolean isTypeAnnotation) {
+	int index;
+
+	if ((index = this.indexOfAssistIdentifier()) < 0) {
+		super.consumeMarkerAnnotation(isTypeAnnotation);
+		return;
+	}
+
+	MarkerAnnotation markerAnnotation = null;
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	TypeReference typeReference;
+
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+
+	char[][] subset = identifierSubSet(index);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist on type reference */
+
+	if (index == 0) {
+		/* assist inside first identifier */
+		typeReference = createSingleAssistTypeReference(
+						assistIdentifier(),
+						positions[0]);
+	} else {
+		/* assist inside subsequent identifier */
+		typeReference =	createQualifiedAssistTypeReference(
+						subset,
+						assistIdentifier(),
+						positions);
+	}
+	this.assistNode = typeReference;
+	this.lastCheckPoint = typeReference.sourceEnd + 1;
+
+	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
+	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(markerAnnotation);
+	} else {
+		pushOnExpressionStack(markerAnnotation);
+	}
+}
+protected void consumeMemberValuePair() {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeMemberValuePair();
+		return;
+	}
+
+	char[] simpleName = this.identifierStack[this.identifierPtr];
+	long position = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	int end = (int) position;
+	int start = (int) (position >>> 32);
+	Expression value = this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr--;
+	MemberValuePair memberValuePair = new SelectionOnNameOfMemberValuePair(simpleName, start, end, value);
+	pushOnAstStack(memberValuePair);
+
+	this.assistNode = memberValuePair;
+	this.lastCheckPoint = memberValuePair.sourceEnd + 1;
+
+
+}
+protected void consumeMethodInvocationName() {
+	// MethodInvocation ::= Name '(' ArgumentListopt ')'
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+
+	char[] selector = this.identifierStack[this.identifierPtr];
+	int accessMode;
+	if(selector == assistIdentifier()) {
+		if(CharOperation.equals(selector, SUPER)) {
+			accessMode = ExplicitConstructorCall.Super;
+		} else if(CharOperation.equals(selector, THIS)) {
+			accessMode = ExplicitConstructorCall.This;
+		} else {
+			super.consumeMethodInvocationName();
+			return;
+		}
+	} else {
+		super.consumeMethodInvocationName();
+		return;
+	}
+
+	final ExplicitConstructorCall constructorCall = new SelectionOnExplicitConstructorCall(accessMode);
+	constructorCall.sourceEnd = this.rParenPos;
+	constructorCall.sourceStart = (int) (this.identifierPositionStack[this.identifierPtr] >>> 32);
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(this.expressionStack, this.expressionPtr + 1, constructorCall.arguments = new Expression[length], 0, length);
+	}
+
+	if (!this.diet){
+		pushOnAstStack(constructorCall);
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	} else {
+		pushOnExpressionStack(new Expression(){
+			public TypeBinding resolveType(BlockScope scope) {
+				constructorCall.resolve(scope);
+				return null;
+			}
+			public StringBuffer printExpression(int indent, StringBuffer output) {
+				return output;
+			}
+		});
+	}
+	this.assistNode = constructorCall;
+	this.lastCheckPoint = constructorCall.sourceEnd + 1;
+	this.isOrphanCompletionNode = true;
+}
+protected void consumeMethodInvocationPrimary() {
+	//optimize the push/pop
+	//MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
+
+	char[] selector = this.identifierStack[this.identifierPtr];
+	int accessMode;
+	if(selector == assistIdentifier()) {
+		if(CharOperation.equals(selector, SUPER)) {
+			accessMode = ExplicitConstructorCall.Super;
+		} else if(CharOperation.equals(selector, THIS)) {
+			accessMode = ExplicitConstructorCall.This;
+		} else {
+			super.consumeMethodInvocationPrimary();
+			return;
+		}
+	} else {
+		super.consumeMethodInvocationPrimary();
+		return;
+	}
+
+	final ExplicitConstructorCall constructorCall = new SelectionOnExplicitConstructorCall(accessMode);
+	constructorCall.sourceEnd = this.rParenPos;
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(this.expressionStack, this.expressionPtr + 1, constructorCall.arguments = new Expression[length], 0, length);
+	}
+	constructorCall.qualification = this.expressionStack[this.expressionPtr--];
+	constructorCall.sourceStart = constructorCall.qualification.sourceStart;
+
+	if (!this.diet){
+		pushOnAstStack(constructorCall);
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	} else {
+		pushOnExpressionStack(new Expression(){
+			public TypeBinding resolveType(BlockScope scope) {
+				constructorCall.resolve(scope);
+				return null;
+			}
+			public StringBuffer printExpression(int indent, StringBuffer output) {
+				return output;
+			}
+		});
+	}
+
+	this.assistNode = constructorCall;
+	this.lastCheckPoint = constructorCall.sourceEnd + 1;
+	this.isOrphanCompletionNode = true;
+}
+protected void consumeNormalAnnotation(boolean isTypeAnnotation) {
+	int index;
+
+	if ((index = this.indexOfAssistIdentifier()) < 0) {
+		super.consumeNormalAnnotation(isTypeAnnotation);
+		return;
+	}
+
+	NormalAnnotation normalAnnotation = null;
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	TypeReference typeReference;
+
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+
+	char[][] subset = identifierSubSet(index);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist on type reference */
+
+	if (index == 0) {
+		/* assist inside first identifier */
+		typeReference = createSingleAssistTypeReference(
+						assistIdentifier(),
+						positions[0]);
+	} else {
+		/* assist inside subsequent identifier */
+		typeReference =	createQualifiedAssistTypeReference(
+						subset,
+						assistIdentifier(),
+						positions);
+	}
+	this.assistNode = typeReference;
+	this.lastCheckPoint = typeReference.sourceEnd + 1;
+
+	normalAnnotation = new NormalAnnotation(typeReference, this.intStack[this.intPtr--]);
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.astStack,
+			(this.astPtr -= length) + 1,
+			normalAnnotation.memberValuePairs = new MemberValuePair[length],
+			0,
+			length);
+	}
+	normalAnnotation.declarationSourceEnd = this.rParenPos;
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(normalAnnotation);
+	} else {
+		pushOnExpressionStack(normalAnnotation);
+	}
+}
+protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) {
+	int index;
+
+	if ((index = this.indexOfAssistIdentifier()) < 0) {
+		super.consumeSingleMemberAnnotation(isTypeAnnotation);
+		return;
+	}
+
+	SingleMemberAnnotation singleMemberAnnotation = null;
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	TypeReference typeReference;
+
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+
+	char[][] subset = identifierSubSet(index);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* build specific assist on type reference */
+
+	if (index == 0) {
+		/* assist inside first identifier */
+		typeReference = createSingleAssistTypeReference(
+						assistIdentifier(),
+						positions[0]);
+	} else {
+		/* assist inside subsequent identifier */
+		typeReference =	createQualifiedAssistTypeReference(
+						subset,
+						assistIdentifier(),
+						positions);
+	}
+	this.assistNode = typeReference;
+	this.lastCheckPoint = typeReference.sourceEnd + 1;
+
+	singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.intStack[this.intPtr--]);
+	singleMemberAnnotation.memberValue = this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr--;
+	singleMemberAnnotation.declarationSourceEnd = this.rParenPos;
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(singleMemberAnnotation);
+	} else {
+		pushOnExpressionStack(singleMemberAnnotation);
+	}
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' 'static' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeStaticImportOnDemandDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* 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;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush annotations defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeToken(int token) {
+	super.consumeToken(token);
+
+	// if in a method or if in a field initializer
+	if (isInsideMethod() || isInsideFieldInitialization()) {
+		switch (token) {
+			case TokenNamecase :
+				pushOnElementStack(K_BETWEEN_CASE_AND_COLON);
+				break;
+			case TokenNameCOLON:
+				if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLON) {
+					popElement(K_BETWEEN_CASE_AND_COLON);
+				}
+				break;
+			case TokenNamereturn:
+				pushOnElementStack(K_INSIDE_RETURN_STATEMENT, this.bracketDepth);
+				break;
+			case TokenNameSEMICOLON:
+				switch(topKnownElementKind(SELECTION_OR_ASSIST_PARSER)) {
+					case K_INSIDE_RETURN_STATEMENT :
+						if(topKnownElementInfo(SELECTION_OR_ASSIST_PARSER) == this.bracketDepth) {
+							popElement(K_INSIDE_RETURN_STATEMENT);
+						}
+						break;
+				}
+				break;
+		}
+	}
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	int index;
+
+	/* no need to take action if not inside assist identifiers */
+	if ((index = indexOfAssistIdentifier()) < 0) {
+		super.consumeTypeImportOnDemandDeclarationName();
+		return;
+	}
+	/* retrieve identifiers subset and whole positions, the assist node positions
+		should include the entire replaced source. */
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	char[][] subset = identifierSubSet(index+1); // include the assistIdentifier
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+
+	/* 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;
+
+	pushOnAstStack(reference);
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		reference.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		reference.declarationSourceEnd = (int) positions[length-1];
+	}
+	//endPosition is just before the ;
+	reference.declarationSourceStart = this.intStack[this.intPtr--];
+	// flush comments defined prior to import statements
+	reference.declarationSourceEnd = flushCommentsDefinedPriorTo(reference.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = reference.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(reference, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+public ImportReference createAssistImportReference(char[][] tokens, long[] positions, int mod){
+	return new SelectionOnImportReference(tokens, positions, mod);
+}
+public ImportReference createAssistPackageReference(char[][] tokens, long[] positions){
+	return new SelectionOnPackageReference(tokens, positions);
+}
+protected JavadocParser createJavadocParser() {
+	return new SelectionJavadocParser(this);
+}
+protected LocalDeclaration createLocalDeclaration(char[] assistName,int sourceStart,int sourceEnd) {
+	if (this.indexOfAssistIdentifier() < 0) {
+		return super.createLocalDeclaration(assistName, sourceStart, sourceEnd);
+	} else {
+		SelectionOnLocalName local = new SelectionOnLocalName(assistName, sourceStart, sourceEnd);
+		this.assistNode = local;
+		this.lastCheckPoint = sourceEnd + 1;
+		return local;
+	}
+}
+public NameReference createQualifiedAssistNameReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
+	return new SelectionOnQualifiedNameReference(
+					previousIdentifiers,
+					assistName,
+					positions);
+}
+public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
+	return new SelectionOnQualifiedTypeReference(
+					previousIdentifiers,
+					assistName,
+					positions);
+}
+public TypeReference createParameterizedQualifiedAssistTypeReference(
+		char[][] tokens, TypeReference[][] typeArguments, char[] assistname, TypeReference[] assistTypeArguments, long[] positions) {
+	return new SelectionOnParameterizedQualifiedTypeReference(tokens, assistname, typeArguments, assistTypeArguments, positions);
+
+}
+public NameReference createSingleAssistNameReference(char[] assistName, long position) {
+	return new SelectionOnSingleNameReference(assistName, position);
+}
+public TypeReference createSingleAssistTypeReference(char[] assistName, long position) {
+	return new SelectionOnSingleTypeReference(assistName, position);
+}
+public TypeReference createParameterizedSingleAssistTypeReference(TypeReference[] typeArguments, char[] assistName, long position) {
+	return new SelectionOnParameterizedSingleTypeReference(assistName, typeArguments, position);
+}
+public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
+
+	this.selectionStart = start;
+	this.selectionEnd = end;
+	SelectionScanner selectionScanner = (SelectionScanner)this.scanner;
+	selectionScanner.selectionIdentifier = null;
+	selectionScanner.selectionStart = start;
+	selectionScanner.selectionEnd = end;
+	return this.dietParse(sourceUnit, compilationResult);
+}
+protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	/* build a (unspecified) NameReference which may be qualified*/
+
+	int completionIndex;
+
+	/* no need to take action if not inside completed identifiers */
+	if ((completionIndex = indexOfAssistIdentifier()) < 0) {
+		return super.getUnspecifiedReference(rejectTypeAnnotations);
+	}
+
+	if (rejectTypeAnnotations) {
+		consumeNonTypeUseName();
+	}
+	int length = this.identifierLengthStack[this.identifierLengthPtr];
+	if (CharOperation.equals(assistIdentifier(), SUPER)){
+		Reference reference;
+		if (completionIndex > 0){ // qualified super
+			// discard 'super' from identifier stacks
+			// There is some voodoo going on here in combination with SelectionScanne#scanIdentifierOrKeyword, do in Rome as Romans do and leave the stacks at the right depth.
+			this.identifierLengthStack[this.identifierLengthPtr] = completionIndex;
+			int ptr = this.identifierPtr -= (length - completionIndex);
+			pushOnGenericsLengthStack(0);
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+			for (int i = 0; i < completionIndex; i++) {
+				pushOnTypeAnnotationLengthStack(0);
+			}
+			reference =
+				new SelectionOnQualifiedSuperReference(
+					getTypeReference(0),
+					(int)(this.identifierPositionStack[ptr+1] >>> 32),
+					(int) this.identifierPositionStack[ptr+1]);
+		} else { // standard super
+			this.identifierPtr -= length;
+			this.identifierLengthPtr--;
+			reference = new SelectionOnSuperReference((int)(this.identifierPositionStack[this.identifierPtr+1] >>> 32), (int) this.identifierPositionStack[this.identifierPtr+1]);
+		}
+		pushOnAstStack(reference);
+		this.assistNode = reference;
+		this.lastCheckPoint = reference.sourceEnd + 1;
+		if (!this.diet || this.dietInt != 0){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+		return new SingleNameReference(CharOperation.NO_CHAR, 0); // dummy reference
+	}
+	NameReference nameReference;
+	/* retrieve identifiers subset and whole positions, the completion node positions
+		should include the entire replaced source. */
+	char[][] subset = identifierSubSet(completionIndex);
+	this.identifierLengthPtr--;
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr + 1,
+		positions,
+		0,
+		length);
+	/* build specific completion on name reference */
+	if (completionIndex == 0) {
+		/* completion inside first identifier */
+		nameReference = createSingleAssistNameReference(assistIdentifier(), positions[0]);
+	} else {
+		/* completion inside subsequent identifier */
+		nameReference = createQualifiedAssistNameReference(subset, assistIdentifier(), positions);
+	}
+	this.assistNode = nameReference;
+	this.lastCheckPoint = nameReference.sourceEnd + 1;
+	if (!this.diet){
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	}
+	this.isOrphanCompletionNode = true;
+	return nameReference;
+}
+/*
+ * Copy of code from superclass with the following change:
+ * In the case of qualified name reference if the cursor location is on the
+ * qualified name reference, then create a CompletionOnQualifiedNameReference
+ * instead.
+ */
+protected NameReference getUnspecifiedReferenceOptimized() {
+
+	int index = indexOfAssistIdentifier();
+	NameReference reference = super.getUnspecifiedReferenceOptimized();
+
+	if (index >= 0){
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+		this.isOrphanCompletionNode = true;
+	}
+	return reference;
+}
+public void initializeScanner(){
+	this.scanner = new SelectionScanner(this.options.sourceLevel);
+}
+protected MessageSend newMessageSend() {
+	// '(' ArgumentListopt ')'
+	// the arguments are on the expression stack
+
+	char[] selector = this.identifierStack[this.identifierPtr];
+	if (selector != assistIdentifier()){
+		return super.newMessageSend();
+	}
+	MessageSend messageSend = new SelectionOnMessageSend();
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			messageSend.arguments = new Expression[length],
+			0,
+			length);
+	}
+	this.assistNode = messageSend;
+	if (!this.diet){
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	}
+
+	this.isOrphanCompletionNode = true;
+	return messageSend;
+}
+protected MessageSend newMessageSendWithTypeArguments() {
+	char[] selector = this.identifierStack[this.identifierPtr];
+	if (selector != assistIdentifier()){
+		return super.newMessageSendWithTypeArguments();
+	}
+	MessageSend messageSend = new SelectionOnMessageSend();
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			messageSend.arguments = new Expression[length],
+			0,
+			length);
+	}
+	this.assistNode = messageSend;
+	if (!this.diet){
+		this.restartRecovery	= true;	// force to restart in recovery mode
+		this.lastIgnoredToken = -1;
+	}
+
+	this.isOrphanCompletionNode = true;
+	return messageSend;
+}
+public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int start, int end) {
+
+	if (end == -1) return super.parse(sourceUnit, compilationResult, start, end);
+
+	this.selectionStart = start;
+	this.selectionEnd = end;
+	SelectionScanner selectionScanner = (SelectionScanner)this.scanner;
+	selectionScanner.selectionIdentifier = null;
+	selectionScanner.selectionStart = start;
+	selectionScanner.selectionEnd = end;
+	return super.parse(sourceUnit, compilationResult, -1, -1/*parse without reseting the scanner*/);
+}
+/*
+ * Reset context so as to resume to regular parse loop
+ * If unable to reset for resuming, answers false.
+ *
+ * Move checkpoint location, reset internal stacks and
+ * decide which grammar goal is activated.
+ */
+protected boolean resumeAfterRecovery() {
+
+	/* if reached assist node inside method body, but still inside nested type,
+		should continue in diet mode until the end of the method body */
+	if (this.assistNode != null
+		&& !(this.referenceContext instanceof CompilationUnitDeclaration)){
+		this.currentElement.preserveEnclosingBlocks();
+		if (this.currentElement.enclosingType() == null) {
+			if(!(this.currentElement instanceof RecoveredType)) {
+				resetStacks();
+				return false;
+			}
+
+			RecoveredType recoveredType = (RecoveredType)this.currentElement;
+			if(recoveredType.typeDeclaration != null && recoveredType.typeDeclaration.allocation == this.assistNode){
+				resetStacks();
+				return false;
+			}
+		}
+	}
+	return super.resumeAfterRecovery();
+}
+
+public void selectionIdentifierCheck(){
+	if (checkRecoveredType()) return;
+}
+public void setAssistIdentifier(char[] assistIdent){
+	((SelectionScanner)this.scanner).selectionIdentifier = assistIdent;
+}
+/*
+ * Update recovery state based on current parser/scanner state
+ */
+protected void updateRecoveryState() {
+
+	/* expose parser state to recovery state */
+	this.currentElement.updateFromParserState();
+
+	/* may be able to retrieve completionNode as an orphan, and then attach it */
+	selectionIdentifierCheck();
+	attachOrphanCompletionNode();
+
+	// if an assist node has been found and a recovered element exists,
+	// mark enclosing blocks as to be preserved
+	if (this.assistNode != null && this.currentElement != null) {
+		this.currentElement.preserveEnclosingBlocks();
+	}
+
+	/* check and update recovered state based on current token,
+		this action is also performed when shifting token after recovery
+		got activated once.
+	*/
+	recoveryTokenCheck();
+}
+
+public  String toString() {
+	String s = Util.EMPTY_STRING;
+	s = s + "elementKindStack : int[] = {"; //$NON-NLS-1$
+	for (int i = 0; i <= this.elementPtr; i++) {
+		s = s + String.valueOf(this.elementKindStack[i]) + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+	s = s + "elementInfoStack : int[] = {"; //$NON-NLS-1$
+	for (int i = 0; i <= this.elementPtr; i++) {
+		s = s + String.valueOf(this.elementInfoStack[i]) + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+	return s + super.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java
new file mode 100644
index 0000000..0e81cd0
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+/*
+ * Scanner aware of a selection range. If finding an identifier which source range is exactly
+ * the same, then will record it so that the parser can make use of it.
+ *
+ * Source positions are zero-based and inclusive.
+ */
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+
+public class SelectionScanner extends Scanner {
+
+	public char[] selectionIdentifier;
+	public int selectionStart, selectionEnd;
+/*
+ * Truncate the current identifier if it is containing the cursor location. Since completion is performed
+ * on an identifier prefix.
+ *
+ */
+
+public SelectionScanner(long sourceLevel) {
+	super(false /*comment*/, false /*whitespace*/, false /*nls*/, sourceLevel, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+}
+
+public char[] getCurrentIdentifierSource() {
+
+	if (this.selectionIdentifier == null){
+		if (this.selectionStart == this.startPosition && this.selectionEnd == this.currentPosition-1){
+			if (this.withoutUnicodePtr != 0){			// check unicode scenario
+				System.arraycopy(this.withoutUnicodeBuffer, 1, this.selectionIdentifier = new char[this.withoutUnicodePtr], 0, this.withoutUnicodePtr);
+			} else {
+				int length = this.currentPosition - this.startPosition;
+				// no char[] sharing around completionIdentifier, we want it to be unique so as to use identity checks
+				System.arraycopy(this.source, this.startPosition, (this.selectionIdentifier = new char[length]), 0, length);
+			}
+			return this.selectionIdentifier;
+		}
+	}
+	return super.getCurrentIdentifierSource();
+}
+/*
+ * In case we actually read a keyword which corresponds to the selected
+ * range, we pretend we read an identifier.
+ */
+public int scanIdentifierOrKeyword() {
+
+	int id = super.scanIdentifierOrKeyword();
+
+	// convert completed keyword into an identifier
+	if (id != TokenNameIdentifier
+		&& this.startPosition == this.selectionStart
+		&& this.currentPosition == this.selectionEnd+1){
+		return TokenNameIdentifier;
+	}
+	return id;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
new file mode 100644
index 0000000..3fe14ec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
+
+/**
+ * Richer description of a Java problem, as detected by the compiler or some of the underlying
+ * technology reusing the compiler. With the introduction of <code>org.eclipse.jdt.core.compiler.CompilationParticipant</code>,
+ * the simpler problem interface {@link IProblem} did not carry enough information to better
+ * separate and categorize Java problems. In order to minimize impact on existing API, Java problems
+ * are still passed around as {@link IProblem}, though actual implementations should explicitly
+ * extend {@link CategorizedProblem}. Participants can produce their own problem definitions,
+ * and given these are categorized problems, they can be better handled by clients (such as user
+ * interface).
+ * <p>
+ * A categorized problem provides access to:
+ * <ul>
+ * <li> its location (originating source file name, source position, line number), </li>
+ * <li> its message description and a predicate to check its severity (warning or error). </li>
+ * <li> its ID : a number identifying the very nature of this problem. All possible IDs for standard Java
+ * problems are listed as constants on {@link IProblem}, </li>
+ * <li> its marker type : a string identifying the problem creator. It corresponds to the marker type
+ * chosen if this problem was to be persisted. Standard Java problems are associated to marker
+ * type "org.eclipse.jdt.core.problem"), </li>
+ * <li> its category ID : a number identifying the category this problem belongs to. All possible IDs for
+ * standard Java problem categories are listed in this class. </li>
+ * </ul>
+ * <p>
+ * Note: the compiler produces IProblems internally, which are turned into markers by the JavaBuilder
+ * so as to persist problem descriptions. This explains why there is no API allowing to reach IProblem detected
+ * when compiling. However, the Java problem markers carry equivalent information to IProblem, in particular
+ * their ID (attribute "id") is set to one of the IDs defined on this interface.
+ * <p>
+ * Note: Standard Java problems produced by Java default tooling will be subclasses of this class. Technically, most
+ * API methods dealing with problems are referring to {@link IProblem} for backward compatibility reason.
+ * It is intended that {@link CategorizedProblem} will be subclassed for custom problem implementation when
+ * participating in compilation operations, so as to allow participant to contribute their own marker types, and thus
+ * defining their own domain specific problem/category IDs.
+ * <p>
+ * Note: standard Java problems produced by Java default tooling will set the marker
+ * <code> IMarker#SOURCE_ID</code> attribute to
+ * <code> JavaBuilder#SOURCE_ID</code>; compiler
+ * participants may specify the <code> IMarker#SOURCE_ID</code>
+ * attribute of their markers by adding it to the extra marker attributes of the problems they generate;
+ * markers resulting from compiler participants' problems that do not have the
+ * <code> IMarker#SOURCE_ID</code> extra attribute set do not have the
+ * <code> JavaBuilder#SOURCE_ID</code> attribute set either.
+ *
+ * @since 3.2
+ */
+public abstract class CategorizedProblem implements IProblem {
+
+	/**
+	 * List of standard category IDs used by Java problems, more categories will be added
+	 * in the future.
+	 */
+	public static final int CAT_UNSPECIFIED = 0;
+	/** Category for problems related to buildpath */
+	public static final int CAT_BUILDPATH = 10;
+	/** Category for fatal problems related to syntax */
+	public static final int CAT_SYNTAX = 20;
+	/** Category for fatal problems in import statements */
+	public static final int CAT_IMPORT = 30;
+	/** Category for fatal problems related to types, could be addressed by some type change */
+	public static final int CAT_TYPE = 40;
+	/** Category for fatal problems related to type members, could be addressed by some field or method change */
+	public static final int CAT_MEMBER = 50;
+	/** Category for fatal problems which could not be addressed by external changes, but require an edit to be addressed */
+	public static final int CAT_INTERNAL = 60;
+	/** Category for optional problems in Javadoc */
+	public static final int CAT_JAVADOC = 70;
+	/** Category for optional problems related to coding style practices */
+	public static final int CAT_CODE_STYLE = 80;
+	/** Category for optional problems related to potential programming flaws */
+	public static final int CAT_POTENTIAL_PROGRAMMING_PROBLEM = 90;
+	/** Category for optional problems related to naming conflicts */
+	public static final int CAT_NAME_SHADOWING_CONFLICT = 100;
+	/** Category for optional problems related to deprecation */
+	public static final int CAT_DEPRECATION = 110;
+	/** Category for optional problems related to unnecessary code */
+	public static final int CAT_UNNECESSARY_CODE = 120;
+	/** Category for optional problems related to type safety in generics */
+	public static final int CAT_UNCHECKED_RAW = 130;
+	/** Category for optional problems related to internationalization of String literals */
+	public static final int CAT_NLS = 140;
+	/** Category for optional problems related to access restrictions */
+	public static final int CAT_RESTRICTION = 150;
+
+/**
+ * Returns an integer identifying the category of this problem. Categories, like problem IDs are
+ * defined in the context of some marker type. Custom implementations of {@link CategorizedProblem}
+ * may choose arbitrary values for problem/category IDs, as long as they are associated with a different
+ * marker type.
+ * Standard Java problem markers (i.e. marker type is "org.eclipse.jdt.core.problem") carry an
+ * attribute "categoryId" persisting the originating problem category ID as defined by this method).
+ * @return id - an integer identifying the category of this problem
+ */
+public abstract int getCategoryID();
+
+/**
+ * Returns the marker type associated to this problem, if it gets persisted into a marker by the JavaBuilder
+ * Standard Java problems are associated to marker type "org.eclipse.jdt.core.problem").
+ * Note: problem markers are expected to extend "org.eclipse.core.resources.problemmarker" marker type.
+ * @return the type of the marker which would be associated to the problem
+ */
+public abstract String getMarkerType();
+
+/**
+ * Returns the names of the extra marker attributes associated to this problem when persisted into a marker
+ * by the JavaBuilder. Extra attributes are only optional, and are allowing client customization of generated
+ * markers. By default, no EXTRA attributes is persisted, and a categorized problem only persists the following attributes:
+ * <ul>
+ * <li>	<code>IMarker#MESSAGE</code> -&gt; {@link IProblem#getMessage()}</li>
+ * <li>	<code>IMarker#SEVERITY</code> -&gt; <code> IMarker#SEVERITY_ERROR</code> or
+ *         <code>IMarker#SEVERITY_WARNING</code> depending on {@link IProblem#isError()} or {@link IProblem#isWarning()}</li>
+ * <li>	<code>IJavaModelMarker#ID</code> -&gt; {@link IProblem#getID()}</li>
+ * <li>	<code>IMarker#CHAR_START</code>  -&gt; {@link IProblem#getSourceStart()}</li>
+ * <li>	<code>IMarker#CHAR_END</code>  -&gt; {@link IProblem#getSourceEnd()}</li>
+ * <li>	<code>IMarker#LINE_NUMBER</code>  -&gt; {@link IProblem#getSourceLineNumber()}</li>
+ * <li>	<code>IJavaModelMarker#ARGUMENTS</code>  -&gt; some <code>String[]</code> used to compute quickfixes </li>
+ * <li>	<code>IJavaModelMarker#CATEGORY_ID</code> -&gt; {@link CategorizedProblem#getCategoryID()}</li>
+ * </ul>
+ * The names must be eligible for marker creation, as defined by <code>IMarker#setAttributes(String[], Object[])</code>,
+ * and there must be as many names as values according to {@link #getExtraMarkerAttributeValues()}.
+ * Note that extra marker attributes will be inserted after default ones (as described in {@link CategorizedProblem#getMarkerType()},
+ * and thus could be used to override defaults.
+ * @return the names of the corresponding marker attributes
+ */
+public String[] getExtraMarkerAttributeNames() {
+	return CharOperation.NO_STRINGS;
+}
+
+/**
+ * Returns the respective values for the extra marker attributes associated to this problem when persisted into
+ * a marker by the JavaBuilder. Each value must correspond to a matching attribute name, as defined by
+ * {@link #getExtraMarkerAttributeNames()}.
+ * The values must be eligible for marker creation, as defined by <code> IMarker#setAttributes(String[], Object[])}.
+ * @return the values of the corresponding extra marker attributes
+ */
+public Object[] getExtraMarkerAttributeValues() {
+	return DefaultProblem.EMPTY_VALUES;
+}
+}
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
new file mode 100644
index 0000000..72437f4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -0,0 +1,3788 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Luiz-Otavio Zorzella <zorzella at gmail dot com> - Improve CamelCase algorithm
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * This class is a collection of helper methods to manipulate char arrays.
+ *
+ * @since 2.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class CharOperation {
+
+	/**
+	 * Constant for an empty char array
+	 */
+	public static final char[] NO_CHAR = new char[0];
+
+	/**
+	 * Constant for an empty char array with two dimensions.
+	 */
+	public static final char[][] NO_CHAR_CHAR = new char[0][];
+
+	/**
+	 * Constant for an empty String array.
+	 * @since 3.1
+	 */
+	public static final String[] NO_STRINGS = new String[0];
+
+/**
+ * Answers a new array with appending the suffix character at the end of the array.
+ * <br>
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    array = { 'a', 'b' }
+ *    suffix = 'c'
+ *    => result = { 'a', 'b' , 'c' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = null
+ *    suffix = 'c'
+ *    => result = { 'c' }
+ * </pre></li>
+ * </ol>
+ *
+ * @param array the array that is concatenated with the suffix character
+ * @param suffix the suffix character
+ * @return the new array
+ */
+public static final char[] append(char[] array, char suffix) {
+	if (array == null)
+		return new char[] { suffix };
+	int length = array.length;
+	System.arraycopy(array, 0, array = new char[length + 1], 0, length);
+	array[length] = suffix;
+	return array;
+}
+
+/**
+ * Append the given sub-array to the target array starting at the given index in the target array.
+ * The start of the sub-array is inclusive, the end is exclusive.
+ * Answers a new target array if it needs to grow, otherwise answers the same target array.
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    target = { 'a', 'b', '0' }
+ *    index = 2
+ *    array = { 'c', 'd' }
+ *    start = 0
+ *    end = 1
+ *    => result = { 'a', 'b' , 'c' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    target = { 'a', 'b' }
+ *    index = 2
+ *    array = { 'c', 'd' }
+ *    start = 0
+ *    end = 1
+ *    => result = { 'a', 'b' , 'c', '0', '0' , '0' } (new array)
+ * </pre></li>
+ * <li><pre>
+ *    target = { 'a', 'b', 'c' }
+ *    index = 1
+ *    array = { 'c', 'd', 'e', 'f' }
+ *    start = 1
+ *    end = 4
+ *    => result = { 'a', 'd' , 'e', 'f', '0', '0', '0', '0' } (new array)
+ * </pre></li>
+ * </ol>
+ *
+ * @param target the given target
+ * @param index the given index
+ * @param array the given array
+ * @param start the given start index
+ * @param end the given end index
+ *
+ * @return the new array
+ * @throws NullPointerException if the target array is null
+ */
+public static final char[] append(char[] target, int index, char[] array, int start, int end) {
+	int targetLength = target.length;
+	int subLength = end-start;
+	int newTargetLength = subLength+index;
+	if (newTargetLength > targetLength) {
+		System.arraycopy(target, 0, target = new char[newTargetLength*2], 0, index);
+	}
+	System.arraycopy(array, start, target, index, subLength);
+	return target;
+}
+
+/**
+ * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
+ * If the first array is null, then the second array is returned.
+ * If the second array is null, then the first array is returned.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    => result = null
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { ' a' } }
+ *    second = null
+ *    => result = { { ' a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = null
+ *    second = { { ' a' } }
+ *    => result = { { ' a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { ' b' } }
+ *    second = { { ' a' } }
+ *    => result = { { ' b' }, { ' a' } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param second the second array to concatenate
+ * @return the concatenation of the two arrays, or null if the two arrays are null.
+ */
+public static final char[][] arrayConcat(char[][] first, char[][] second) {
+	if (first == null)
+		return second;
+	if (second == null)
+		return first;
+
+	int length1 = first.length;
+	int length2 = second.length;
+	char[][] result = new char[length1 + length2][];
+	System.arraycopy(first, 0, result, 0, length1);
+	System.arraycopy(second, 0, result, length1, length2);
+	return result;
+}
+
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or
+ * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
+ * '*' and '?' and is inherently case sensitive.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Using this method allows matching names to have more parts than the specified
+ * pattern (see {@link #camelCaseMatch(char[], char[], boolean)}).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
+ * 'HatMapper' <b>and also</b> 'HashMapEntry'.
+ * <p>
+ * <pre>
+ * Examples:<ol>
+ * <li> pattern = "NPE".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NPE".toCharArray()
+ * name = "NoPermissionException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * name = "NoPermissionException".toCharArray()
+ * result => false</li>
+ * <li> pattern = "npe".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => false</li>
+ * <li> pattern = "IPL3".toCharArray()
+ * name = "IPerspectiveListener3".toCharArray()
+ * result => true</li>
+ * <li> pattern = "HM".toCharArray()
+ * name = "HashMapEntry".toCharArray()
+ * result => true</li>
+ * </ol></pre>
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.2
+ */
+public static final boolean camelCaseMatch(char[] pattern, char[] name) {
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	if (name == null)
+		return false; // null name cannot match
+
+	return camelCaseMatch(pattern, 0, pattern.length, name, 0, name.length, false/*not the same count of parts*/);
+}
+
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or
+ * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
+ * '*' and '?' and is inherently case sensitive.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ * <p>
+ * <pre>
+ * Examples:<ol>
+ * <li> pattern = "NPE".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NPE".toCharArray()
+ * name = "NoPermissionException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * name = "NoPermissionException".toCharArray()
+ * result => false</li>
+ * <li> pattern = "npe".toCharArray()
+ * name = "NullPointerException".toCharArray()
+ * result => false</li>
+ * <li> pattern = "IPL3".toCharArray()
+ * name = "IPerspectiveListener3".toCharArray()
+ * result => true</li>
+ * <li> pattern = "HM".toCharArray()
+ * name = "HashMapEntry".toCharArray()
+ * result => (samePartCount == false)</li>
+ * </ol></pre>
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.<br>
+ * 	&nbsp;&nbsp;For example:
+ * 	<ul>
+ * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'</li>
+ * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
+ * 	</ul>
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, char[] name, boolean samePartCount) {
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	if (name == null)
+		return false; // null name cannot match
+
+	return camelCaseMatch(pattern, 0, pattern.length, name, 0, name.length, samePartCount);
+}
+
+/**
+ * Answers true if a sub-pattern matches the sub-part of the given name using
+ * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
+ * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
+ * Can match only subset of name/pattern, considering end positions as non-inclusive.
+ * The sub-pattern is defined by the patternStart and patternEnd positions.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Using this method allows matching names to have more parts than the specified
+ * pattern (see {@link #camelCaseMatch(char[], int, int, char[], int, int, boolean)}).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
+ * 'HatMapper' <b>and also</b> 'HashMapEntry'.
+ * <p>
+ * Examples:
+ * <ol>
+ * <li> pattern = "NPE".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => true</li>
+ * <li> pattern = "NPE".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NoPermissionException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * patternStart = 0
+ * patternEnd = 6
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * patternStart = 0
+ * patternEnd = 6
+ * name = "NoPermissionException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => false</li>
+ * <li> pattern = "npe".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => false</li>
+ * <li> pattern = "IPL3".toCharArray()
+ * patternStart = 0
+ * patternEnd = 4
+ * name = "IPerspectiveListener3".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => true</li>
+ * <li> pattern = "HM".toCharArray()
+ * patternStart = 0
+ * patternEnd = 2
+ * name = "HashMapEntry".toCharArray()
+ * nameStart = 0
+ * nameEnd = 12
+ * result => true</li>
+ * </ol>
+ *
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.2
+ */
+public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd) {
+	return camelCaseMatch(pattern, patternStart, patternEnd, name, nameStart, nameEnd, false/*not the same count of parts*/);
+}
+
+/**
+ * Answers true if a sub-pattern matches the sub-part of the given name using
+ * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
+ * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
+ * Can match only subset of name/pattern, considering end positions as
+ * non-inclusive. The sub-pattern is defined by the patternStart and patternEnd
+ * positions.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain
+ * a sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ * <p>
+ * <pre>
+ * Examples:
+ * <ol>
+ * <li> pattern = "NPE".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => true</li>
+ * <li> pattern = "NPE".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NoPermissionException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * patternStart = 0
+ * patternEnd = 6
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => true</li>
+ * <li> pattern = "NuPoEx".toCharArray()
+ * patternStart = 0
+ * patternEnd = 6
+ * name = "NoPermissionException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => false</li>
+ * <li> pattern = "npe".toCharArray()
+ * patternStart = 0
+ * patternEnd = 3
+ * name = "NullPointerException".toCharArray()
+ * nameStart = 0
+ * nameEnd = 20
+ * result => false</li>
+ * <li> pattern = "IPL3".toCharArray()
+ * patternStart = 0
+ * patternEnd = 4
+ * name = "IPerspectiveListener3".toCharArray()
+ * nameStart = 0
+ * nameEnd = 21
+ * result => true</li>
+ * <li> pattern = "HM".toCharArray()
+ * patternStart = 0
+ * patternEnd = 2
+ * name = "HashMapEntry".toCharArray()
+ * nameStart = 0
+ * nameEnd = 12
+ * result => (samePartCount == false)</li>
+ * </ol>
+ * </pre>
+ *
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.<br>
+ * 	&nbsp;&nbsp;For example:
+ * 	<ul>
+ * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'</li>
+ * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
+ * 	</ul>
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd, boolean samePartCount) {
+
+	/* !!!!!!!!!! WARNING !!!!!!!!!!
+	 * The algorithm implemented in this method has been heavily used in
+	 * StringOperation#getCamelCaseMatchingRegions(String, int, int, String, int, int, boolean)
+	 * method.
+	 *
+	 * So, if any change needs to be applied in the current algorithm,
+	 * do NOT forget to also apply the same change in the StringOperation method!
+	 */
+
+	if (name == null)
+		return false; // null name cannot match
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	if (patternEnd < 0) 	patternEnd = pattern.length;
+	if (nameEnd < 0) nameEnd = name.length;
+
+	if (patternEnd <= patternStart) return nameEnd <= nameStart;
+	if (nameEnd <= nameStart) return false;
+	// check first pattern char
+	if (name[nameStart] != pattern[patternStart]) {
+		// first char must strictly match (upper/lower)
+		return false;
+	}
+
+	char patternChar, nameChar;
+	int iPattern = patternStart;
+	int iName = nameStart;
+
+	// Main loop is on pattern characters
+	while (true) {
+
+		iPattern++;
+		iName++;
+
+		if (iPattern == patternEnd) { // we have exhausted pattern...
+			// it's a match if the name can have additional parts (i.e. uppercase characters) or is also exhausted
+			if (!samePartCount || iName == nameEnd) return true;
+
+			// otherwise it's a match only if the name has no more uppercase characters
+			while (true) {
+				if (iName == nameEnd) {
+					// we have exhausted the name, so it's a match
+					return true;
+				}
+				nameChar = name[iName];
+				// test if the name character is uppercase
+				if (nameChar < ScannerHelper.MAX_OBVIOUS) {
+					if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] & ScannerHelper.C_UPPER_LETTER) != 0) {
+						return false;
+					}
+				}
+				else if (!Character.isJavaIdentifierPart(nameChar) || Character.isUpperCase(nameChar)) {
+					return false;
+				}
+				iName++;
+			}
+		}
+
+		if (iName == nameEnd){
+			// We have exhausted the name (and not the pattern), so it's not a match
+			return false;
+		}
+
+		// For as long as we're exactly matching, bring it on (even if it's a lower case character)
+		if ((patternChar = pattern[iPattern]) == name[iName]) {
+			continue;
+		}
+
+		// If characters are not equals, then it's not a match if patternChar is lowercase
+		if (patternChar < ScannerHelper.MAX_OBVIOUS) {
+			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) == 0) {
+				return false;
+			}
+		}
+		else if (Character.isJavaIdentifierPart(patternChar) && !Character.isUpperCase(patternChar) && !Character.isDigit(patternChar)) {
+			return false;
+		}
+
+		// patternChar is uppercase, so let's find the next uppercase in name
+		while (true) {
+			if (iName == nameEnd){
+	            //	We have exhausted name (and not pattern), so it's not a match
+				return false;
+			}
+
+			nameChar = name[iName];
+			if (nameChar < ScannerHelper.MAX_OBVIOUS) {
+				int charNature = ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar];
+				if ((charNature & (ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_SPECIAL)) != 0) {
+					// nameChar is lowercase
+					iName++;
+				} else if ((charNature & ScannerHelper.C_DIGIT) != 0) {
+					// nameChar is digit => break if the digit is current pattern character otherwise consume it
+					if (patternChar == nameChar) break;
+					iName++;
+				// nameChar is uppercase...
+				} else  if (patternChar != nameChar) {
+					//.. and it does not match patternChar, so it's not a match
+					return false;
+				} else {
+					//.. and it matched patternChar. Back to the big loop
+					break;
+				}
+			}
+			// Same tests for non-obvious characters
+			else if (Character.isJavaIdentifierPart(nameChar) && !Character.isUpperCase(nameChar)) {
+				iName++;
+			} else if (Character.isDigit(nameChar)) {
+				if (patternChar == nameChar) break;
+				iName++;
+			} else  if (patternChar != nameChar) {
+				return false;
+			} else {
+				break;
+			}
+		}
+		// At this point, either name has been exhausted, or it is at an uppercase letter.
+		// Since pattern is also at an uppercase letter
+	}
+}
+
+/**
+ * Returns the char arrays as an array of Strings
+ *
+ * @param charArrays the char array to convert
+ * @return the char arrays as an array of Strings or null if the given char arrays is null.
+ * @since 3.0
+ */
+public static String[] charArrayToStringArray(char[][] charArrays) {
+	if (charArrays == null)
+		return null;
+	int length = charArrays.length;
+	if (length == 0)
+		return NO_STRINGS;
+	String[] strings= new String[length];
+	for (int i= 0; i < length; i++)
+		strings[i]= new String(charArrays[i]);
+	return strings;
+}
+
+/**
+ * Returns the char array as a String
+
+ * @param charArray the char array to convert
+ * @return the char array as a String or null if the given char array is null.
+ * @since 3.0
+ */
+public static String charToString(char[] charArray) {
+	if (charArray == null) return null;
+	return new String(charArray);
+}
+
+/**
+ * Answers a new array adding the second array at the end of first array.
+ * It answers null if the first and second are null.
+ * If the first array is null, then a new array char[][] is created with second.
+ * If the second array is null, then the first array is returned.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = { 'a' }
+ *    => result = { { ' a' } }
+ * </pre>
+ * <li><pre>
+ *    first = { { ' a' } }
+ *    second = null
+ *    => result = { { ' a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { ' a' } }
+ *    second = { ' b' }
+ *    => result = { { ' a' } , { ' b' } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param second the array to add at the end of the first array
+ * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
+ */
+public static final char[][] arrayConcat(char[][] first, char[] second) {
+	if (second == null)
+		return first;
+	if (first == null)
+		return new char[][] { second };
+
+	int length = first.length;
+	char[][] result = new char[length + 1][];
+	System.arraycopy(first, 0, result, 0, length);
+	result[length] = second;
+	return result;
+}
+/**
+ * Compares the two char arrays lexicographically.
+ *
+ * Returns a negative integer if array1 lexicographically precedes the array2,
+ * a positive integer if this array1 lexicographically follows the array2, or
+ * zero if both arrays are equal.
+ *
+ * @param array1 the first given array
+ * @param array2 the second given array
+ * @return the returned value of the comparison between array1 and array2
+ * @throws NullPointerException if one of the arrays is null
+ * @since 3.3
+ */
+public static final int compareTo(char[] array1, char[] array2) {
+	int length1 = array1.length;
+	int length2 = array2.length;
+	int min = Math.min(length1, length2);
+	for (int i = 0; i < min; i++) {
+		if (array1[i] != array2[i]) {
+			return array1[i] - array2[i];
+		}
+	}
+	return length1 - length2;
+}
+/**
+ * Compares the two char arrays lexicographically between the given start and end positions.
+ *
+ * Returns a negative integer if array1 lexicographically precedes the array2,
+ * a positive integer if this array1 lexicographically follows the array2, or
+ * zero if both arrays are equal.
+ * <p>The comparison is done between start and end positions.</p>
+ *
+ * @param array1 the first given array
+ * @param array2 the second given array
+ * @param start the starting position to compare (inclusive)
+ * @param end the ending position to compare (exclusive)
+ * 
+ * @return the returned value of the comparison between array1 and array2
+ * @throws NullPointerException if one of the arrays is null
+ * @since 3.7.1
+ */
+public static final int compareTo(char[] array1, char[] array2, int start, int end) {
+	int length1 = array1.length;
+	int length2 = array2.length;
+	int min = Math.min(length1, length2);
+	min = Math.min(min, end);
+	for (int i = start; i < min; i++) {
+		if (array1[i] != array2[i]) {
+			return array1[i] - array2[i];
+		}
+	}
+	return length1 - length2;
+}
+/**
+ * Compares the contents of the two arrays array and prefix. Returns
+ * <ul>
+ * <li>zero if the array starts with the prefix contents</li>
+ * <li>the difference between the first two characters that are not equal </li>
+ * <li>one if array length is lower than the prefix length and that the prefix starts with the
+ * array contents.</li>
+ * </ul>
+ * <p>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = null
+ *    prefix = null
+ *    => result = NullPointerException
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'b', 'c', 'd', 'e' }
+ *    prefix = { 'a', 'b', 'c'}
+ *    => result = 0
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'b', 'c', 'd', 'e' }
+ *    prefix = { 'a', 'B', 'c'}
+ *    => result = 32
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'd', 'b', 'c', 'd', 'e' }
+ *    prefix = { 'a', 'b', 'c'}
+ *    => result = 3
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'b', 'c', 'd', 'e' }
+ *    prefix = { 'd', 'b', 'c'}
+ *    => result = -3
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'a', 'c', 'd', 'e' }
+ *    prefix = { 'a', 'e', 'c'}
+ *    => result = -4
+ * </pre>
+ * </li>
+ * </ol>
+ * </p>
+ *
+ * @param array the given array
+ * @param prefix the given prefix
+ * @return the result of the comparison (>=0 if array>prefix)
+ * @throws NullPointerException if either array or prefix is null
+ */
+public static final int compareWith(char[] array, char[] prefix) {
+	int arrayLength = array.length;
+	int prefixLength = prefix.length;
+	int min = Math.min(arrayLength, prefixLength);
+	int i = 0;
+	while (min-- != 0) {
+		char c1 = array[i];
+		char c2 = prefix[i++];
+		if (c1 != c2)
+			return c1 - c2;
+	}
+	if (prefixLength == i)
+		return 0;
+	return -1;	// array is shorter than prefix (e.g. array:'ab' < prefix:'abc').
+}
+
+/**
+ * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
+ * If the first array is null, then the second array is returned.
+ * If the second array is null, then the first array is returned.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = { 'a' }
+ *    => result = { ' a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { ' a' }
+ *    second = null
+ *    => result = { ' a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { ' a' }
+ *    second = { ' b' }
+ *    => result = { ' a' , ' b' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param second the second array to concatenate
+ * @return the concatenation of the two arrays, or null if the two arrays are null.
+ */
+public static final char[] concat(char[] first, char[] second) {
+	if (first == null)
+		return second;
+	if (second == null)
+		return first;
+
+	int length1 = first.length;
+	int length2 = second.length;
+	char[] result = new char[length1 + length2];
+	System.arraycopy(first, 0, result, 0, length1);
+	System.arraycopy(second, 0, result, length1, length2);
+	return result;
+}
+
+/**
+ * Answers the concatenation of the three arrays. It answers null if the three arrays are null.
+ * If first is null, it answers the concatenation of second and third.
+ * If second is null, it answers the concatenation of first and third.
+ * If third is null, it answers the concatenation of first and second.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = { 'a' }
+ *    third = { 'b' }
+ *    => result = { ' a', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = null
+ *    third = { 'b' }
+ *    => result = { ' a', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'b' }
+ *    third = null
+ *    => result = { ' a', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    third = null
+ *    => result = null
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'b' }
+ *    third = { 'c' }
+ *    => result = { 'a', 'b', 'c' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param second the second array to concatenate
+ * @param third the third array to concatenate
+ *
+ * @return the concatenation of the three arrays, or null if the three arrays are null.
+ */
+public static final char[] concat(
+	char[] first,
+	char[] second,
+	char[] third) {
+	if (first == null)
+		return concat(second, third);
+	if (second == null)
+		return concat(first, third);
+	if (third == null)
+		return concat(first, second);
+
+	int length1 = first.length;
+	int length2 = second.length;
+	int length3 = third.length;
+	char[] result = new char[length1 + length2 + length3];
+	System.arraycopy(first, 0, result, 0, length1);
+	System.arraycopy(second, 0, result, length1, length2);
+	System.arraycopy(third, 0, result, length1 + length2, length3);
+	return result;
+}
+
+/**
+ * Answers the concatenation of the two arrays inserting the separator character between the two arrays.
+ * It answers null if the two arrays are null.
+ * If the first array is null, then the second array is returned.
+ * If the second array is null, then the first array is returned.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = { 'a' }
+ *    separator = '/'
+ *    => result = { ' a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { ' a' }
+ *    second = null
+ *    separator = '/'
+ *    => result = { ' a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { ' a' }
+ *    second = { ' b' }
+ *    separator = '/'
+ *    => result = { ' a' , '/', 'b' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param second the second array to concatenate
+ * @param separator the character to insert
+ * @return the concatenation of the two arrays inserting the separator character
+ * between the two arrays , or null if the two arrays are null.
+ */
+public static final char[] concat(
+	char[] first,
+	char[] second,
+	char separator) {
+	if (first == null)
+		return second;
+	if (second == null)
+		return first;
+
+	int length1 = first.length;
+	if (length1 == 0)
+		return second;
+	int length2 = second.length;
+	if (length2 == 0)
+		return first;
+
+	char[] result = new char[length1 + length2 + 1];
+	System.arraycopy(first, 0, result, 0, length1);
+	result[length1] = separator;
+	System.arraycopy(second, 0, result, length1 + 1, length2);
+	return result;
+}
+
+/**
+ * Answers the concatenation of the three arrays inserting the sep1 character between the
+ * first two arrays and sep2 between the last two.
+ * It answers null if the three arrays are null.
+ * If the first array is null, then it answers the concatenation of second and third inserting
+ * the sep2 character between them.
+ * If the second array is null, then it answers the concatenation of first and third inserting
+ * the sep1 character between them.
+ * If the third array is null, then it answers the concatenation of first and second inserting
+ * the sep1 character between them.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    sep1 = '/'
+ *    second = { 'a' }
+ *    sep2 = ':'
+ *    third = { 'b' }
+ *    => result = { ' a' , ':', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    sep1 = '/'
+ *    second = null
+ *    sep2 = ':'
+ *    third = { 'b' }
+ *    => result = { ' a' , '/', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    sep1 = '/'
+ *    second = { 'b' }
+ *    sep2 = ':'
+ *    third = null
+ *    => result = { ' a' , '/', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    sep1 = '/'
+ *    second = { 'b' }
+ *    sep2 = ':'
+ *    third = { 'c' }
+ *    => result = { ' a' , '/', 'b' , ':', 'c' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array to concatenate
+ * @param sep1 the character to insert
+ * @param second the second array to concatenate
+ * @param sep2 the character to insert
+ * @param third the second array to concatenate
+ * @return the concatenation of the three arrays inserting the sep1 character between the
+ * two arrays and sep2 between the last two.
+ */
+public static final char[] concat(
+	char[] first,
+	char sep1,
+	char[] second,
+	char sep2,
+	char[] third) {
+	if (first == null)
+		return concat(second, third, sep2);
+	if (second == null)
+		return concat(first, third, sep1);
+	if (third == null)
+		return concat(first, second, sep1);
+
+	int length1 = first.length;
+	int length2 = second.length;
+	int length3 = third.length;
+	char[] result = new char[length1 + length2 + length3 + 2];
+	System.arraycopy(first, 0, result, 0, length1);
+	result[length1] = sep1;
+	System.arraycopy(second, 0, result, length1 + 1, length2);
+	result[length1 + length2 + 1] = sep2;
+	System.arraycopy(third, 0, result, length1 + length2 + 2, length3);
+	return result;
+}
+
+/**
+ * Answers a new array with prepending the prefix character and appending the suffix
+ * character at the end of the array. If array is null, it answers a new array containing the
+ * prefix and the suffix characters.
+ * <br>
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    prefix = 'a'
+ *    array = { 'b' }
+ *    suffix = 'c'
+ *    => result = { 'a', 'b' , 'c' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    prefix = 'a'
+ *    array = null
+ *    suffix = 'c'
+ *    => result = { 'a', 'c' }
+ * </pre></li>
+ * </ol>
+ *
+ * @param prefix the prefix character
+ * @param array the array that is concatenated with the prefix and suffix characters
+ * @param suffix the suffix character
+ * @return the new array
+ */
+public static final char[] concat(char prefix, char[] array, char suffix) {
+	if (array == null)
+		return new char[] { prefix, suffix };
+
+	int length = array.length;
+	char[] result = new char[length + 2];
+	result[0] = prefix;
+	System.arraycopy(array, 0, result, 1, length);
+	result[length + 1] = suffix;
+	return result;
+}
+
+/**
+ * Answers the concatenation of the given array parts using the given separator between each
+ * part and prepending the given name at the beginning.
+ * <br>
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    name = { 'c' }
+ *    array = { { 'a' }, { 'b' } }
+ *    separator = '.'
+ *    => result = { 'a', '.', 'b' , '.', 'c' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    name = null
+ *    array = { { 'a' }, { 'b' } }
+ *    separator = '.'
+ *    => result = { 'a', '.', 'b' }
+ * </pre></li>
+ * <li><pre>
+ *    name = { ' c' }
+ *    array = null
+ *    separator = '.'
+ *    => result = { 'c' }
+ * </pre></li>
+ * </ol>
+ *
+ * @param name the given name
+ * @param array the given array
+ * @param separator the given separator
+ * @return the concatenation of the given array parts using the given separator between each
+ * part and prepending the given name at the beginning
+ */
+public static final char[] concatWith(
+	char[] name,
+	char[][] array,
+	char separator) {
+	int nameLength = name == null ? 0 : name.length;
+	if (nameLength == 0)
+		return concatWith(array, separator);
+
+	int length = array == null ? 0 : array.length;
+	if (length == 0)
+		return name;
+
+	int size = nameLength;
+	int index = length;
+	while (--index >= 0)
+		if (array[index].length > 0)
+			size += array[index].length + 1;
+	char[] result = new char[size];
+	index = size;
+	for (int i = length - 1; i >= 0; i--) {
+		int subLength = array[i].length;
+		if (subLength > 0) {
+			index -= subLength;
+			System.arraycopy(array[i], 0, result, index, subLength);
+			result[--index] = separator;
+		}
+	}
+	System.arraycopy(name, 0, result, 0, nameLength);
+	return result;
+}
+
+/**
+ * Answers the concatenation of the given array parts using the given separator between each
+ * part and appending the given name at the end.
+ * <br>
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    name = { 'c' }
+ *    array = { { 'a' }, { 'b' } }
+ *    separator = '.'
+ *    => result = { 'a', '.', 'b' , '.', 'c' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    name = null
+ *    array = { { 'a' }, { 'b' } }
+ *    separator = '.'
+ *    => result = { 'a', '.', 'b' }
+ * </pre></li>
+ * <li><pre>
+ *    name = { ' c' }
+ *    array = null
+ *    separator = '.'
+ *    => result = { 'c' }
+ * </pre></li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param name the given name
+ * @param separator the given separator
+ * @return the concatenation of the given array parts using the given separator between each
+ * part and appending the given name at the end
+ */
+public static final char[] concatWith(
+	char[][] array,
+	char[] name,
+	char separator) {
+	int nameLength = name == null ? 0 : name.length;
+	if (nameLength == 0)
+		return concatWith(array, separator);
+
+	int length = array == null ? 0 : array.length;
+	if (length == 0)
+		return name;
+
+	int size = nameLength;
+	int index = length;
+	while (--index >= 0)
+		if (array[index].length > 0)
+			size += array[index].length + 1;
+	char[] result = new char[size];
+	index = 0;
+	for (int i = 0; i < length; i++) {
+		int subLength = array[i].length;
+		if (subLength > 0) {
+			System.arraycopy(array[i], 0, result, index, subLength);
+			index += subLength;
+			result[index++] = separator;
+		}
+	}
+	System.arraycopy(name, 0, result, index, nameLength);
+	return result;
+}
+
+/**
+ * Answers the concatenation of the given array parts using the given separator between each part.
+ * <br>
+ * <br>
+ * For example:<br>
+ * <ol>
+ * <li><pre>
+ *    array = { { 'a' }, { 'b' } }
+ *    separator = '.'
+ *    => result = { 'a', '.', 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = null
+ *    separator = '.'
+ *    => result = { }
+ * </pre></li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param separator the given separator
+ * @return the concatenation of the given array parts using the given separator between each part
+ */
+public static final char[] concatWith(char[][] array, char separator) {
+	int length = array == null ? 0 : array.length;
+	if (length == 0)
+		return CharOperation.NO_CHAR;
+
+	int size = length - 1;
+	int index = length;
+	while (--index >= 0) {
+		if (array[index].length == 0)
+			size--;
+		else
+			size += array[index].length;
+	}
+	if (size <= 0)
+		return CharOperation.NO_CHAR;
+	char[] result = new char[size];
+	index = length;
+	while (--index >= 0) {
+		length = array[index].length;
+		if (length > 0) {
+			System.arraycopy(
+				array[index],
+				0,
+				result,
+				(size -= length),
+				length);
+			if (--size >= 0)
+				result[size] = separator;
+		}
+	}
+	return result;
+}
+
+/**
+ * Answers true if the array contains an occurrence of character, false otherwise.
+ *
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    character = 'c'
+ *    array = { { ' a' }, { ' b' } }
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    character = 'a'
+ *    array = { { ' a' }, { ' b' } }
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param character the character to search
+ * @param array the array in which the search is done
+ * @return true if the array contains an occurrence of character, false otherwise.
+ * @throws NullPointerException if array is null.
+ */
+public static final boolean contains(char character, char[][] array) {
+	for (int i = array.length; --i >= 0;) {
+		char[] subarray = array[i];
+		for (int j = subarray.length; --j >= 0;)
+			if (subarray[j] == character)
+				return true;
+	}
+	return false;
+}
+
+/**
+ * Answers true if the array contains an occurrence of character, false otherwise.
+ *
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    character = 'c'
+ *    array = { ' b'  }
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    character = 'a'
+ *    array = { ' a' , ' b' }
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param character the character to search
+ * @param array the array in which the search is done
+ * @return true if the array contains an occurrence of character, false otherwise.
+ * @throws NullPointerException if array is null.
+ */
+public static final boolean contains(char character, char[] array) {
+	for (int i = array.length; --i >= 0;)
+		if (array[i] == character)
+			return true;
+	return false;
+}
+
+/**
+ * Answers true if the array contains an occurrence of one of the characters, false otherwise.
+ *
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    characters = { 'c', 'd' }
+ *    array = { 'a', ' b'  }
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    characters = { 'c', 'd' }
+ *    array = { 'a', ' b', 'c'  }
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param characters the characters to search
+ * @param array the array in which the search is done
+ * @return true if the array contains an occurrence of one of the characters, false otherwise.
+ * @throws NullPointerException if array is null.
+ * @since 3.1
+ */
+public static final boolean contains(char[] characters, char[] array) {
+	for (int i = array.length; --i >= 0;)
+		for (int j = characters.length; --j >= 0;)
+			if (array[i] == characters[j])
+				return true;
+	return false;
+}
+
+/**
+ * Answers a deep copy of the toCopy array.
+ *
+ * @param toCopy the array to copy
+ * @return a deep copy of the toCopy array.
+ */
+
+public static final char[][] deepCopy(char[][] toCopy) {
+	int toCopyLength = toCopy.length;
+	char[][] result = new char[toCopyLength][];
+	for (int i = 0; i < toCopyLength; i++) {
+		char[] toElement = toCopy[i];
+		int toElementLength = toElement.length;
+		char[] resultElement = new char[toElementLength];
+		System.arraycopy(toElement, 0, resultElement, 0, toElementLength);
+		result[i] = resultElement;
+	}
+	return result;
+}
+
+/**
+ * Return true if array ends with the sequence of characters contained in toBeFound,
+ * otherwise false.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a', 'b', 'c', 'd' }
+ *    toBeFound = { 'b', 'c' }
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'b', 'c' }
+ *    toBeFound = { 'b', 'c' }
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the array to check
+ * @param toBeFound the array to find
+ * @return true if array ends with the sequence of characters contained in toBeFound,
+ * otherwise false.
+ * @throws NullPointerException if array is null or toBeFound is null
+ */
+public static final boolean endsWith(char[] array, char[] toBeFound) {
+	int i = toBeFound.length;
+	int j = array.length - i;
+
+	if (j < 0)
+		return false;
+	while (--i >= 0)
+		if (toBeFound[i] != array[i + j])
+			return false;
+	return true;
+}
+
+/**
+ * Answers true if the two arrays are identical character by character, otherwise false.
+ * The equality is case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { } }
+ *    second = null
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { 'a' } }
+ *    second = { { 'a' } }
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { 'A' } }
+ *    second = { { 'a' } }
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ * @param first the first array
+ * @param second the second array
+ * @return true if the two arrays are identical character by character, otherwise false
+ */
+public static final boolean equals(char[][] first, char[][] second) {
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != second.length)
+		return false;
+
+	for (int i = first.length; --i >= 0;)
+		if (!equals(first[i], second[i]))
+			return false;
+	return true;
+}
+
+/**
+ * If isCaseSensite is true, answers true if the two arrays are identical character
+ * by character, otherwise false.
+ * If it is false, answers true if the two arrays are identical character by
+ * character without checking the case, otherwise false.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { } }
+ *    second = null
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { 'A' } }
+ *    second = { { 'a' } }
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { { 'A' } }
+ *    second = { { 'a' } }
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array
+ * @param second the second array
+ * @param isCaseSensitive check whether or not the equality should be case sensitive
+ * @return true if the two arrays are identical character by character according to the value
+ * of isCaseSensitive, otherwise false
+ */
+public static final boolean equals(
+	char[][] first,
+	char[][] second,
+	boolean isCaseSensitive) {
+
+	if (isCaseSensitive) {
+		return equals(first, second);
+	}
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != second.length)
+		return false;
+
+	for (int i = first.length; --i >= 0;)
+		if (!equals(first[i], second[i], false))
+			return false;
+	return true;
+}
+
+/**
+ * Answers true if the two arrays are identical character by character, otherwise false.
+ * The equality is case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { }
+ *    second = null
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'a' }
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'A' }
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ * @param first the first array
+ * @param second the second array
+ * @return true if the two arrays are identical character by character, otherwise false
+ */
+public static final boolean equals(char[] first, char[] second) {
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != second.length)
+		return false;
+
+	for (int i = first.length; --i >= 0;)
+		if (first[i] != second[i])
+			return false;
+	return true;
+}
+
+/**
+ * Answers true if the first array is identical character by character to a portion of the second array
+ * delimited from position secondStart (inclusive) to secondEnd(exclusive), otherwise false.
+ * The equality is case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    secondStart = 0
+ *    secondEnd = 0
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { }
+ *    second = null
+ *    secondStart = 0
+ *    secondEnd = 0
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'a' }
+ *    secondStart = 0
+ *    secondEnd = 1
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'A' }
+ *    secondStart = 0
+ *    secondEnd = 1
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ * @param first the first array
+ * @param second the second array
+ * @param secondStart inclusive start position in the second array to compare
+ * @param secondEnd exclusive end position in the second array to compare
+ * @return true if the first array is identical character by character to fragment of second array ranging from secondStart to secondEnd-1, otherwise false
+ * @since 3.0
+ */
+public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd) {
+	return equals(first, second, secondStart, secondEnd, true);
+}
+/**
+ * <p>Answers true if the first array is identical character by character to a portion of the second array
+ * delimited from position secondStart (inclusive) to secondEnd(exclusive), otherwise false. The equality could be either
+ * case sensitive or case insensitive according to the value of the <code>isCaseSensitive</code> parameter.
+ * </p>
+ * <p>For example:</p>
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    secondStart = 0
+ *    secondEnd = 0
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { }
+ *    second = null
+ *    secondStart = 0
+ *    secondEnd = 0
+ *    isCaseSensitive = false
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'a' }
+ *    secondStart = 0
+ *    secondEnd = 1
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'A' }
+ *    secondStart = 0
+ *    secondEnd = 1
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'a' }
+ *    second = { 'A' }
+ *    secondStart = 0
+ *    secondEnd = 1
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ * @param first the first array
+ * @param second the second array
+ * @param secondStart inclusive start position in the second array to compare
+ * @param secondEnd exclusive end position in the second array to compare
+ * @param isCaseSensitive check whether or not the equality should be case sensitive
+ * @return true if the first array is identical character by character to fragment of second array ranging from secondStart to secondEnd-1, otherwise false
+ * @since 3.2
+ */
+public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd, boolean isCaseSensitive) {
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != secondEnd - secondStart)
+		return false;
+	if (isCaseSensitive) {
+		for (int i = first.length; --i >= 0;)
+			if (first[i] != second[i+secondStart])
+				return false;
+	} else {
+		for (int i = first.length; --i >= 0;)
+			if (ScannerHelper.toLowerCase(first[i]) != ScannerHelper.toLowerCase(second[i+secondStart]))
+				return false;
+	}
+	return true;
+}
+
+/**
+ * If isCaseSensite is true, answers true if the two arrays are identical character
+ * by character, otherwise false.
+ * If it is false, answers true if the two arrays are identical character by
+ * character without checking the case, otherwise false.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    first = null
+ *    second = null
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { }
+ *    second = null
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'A' }
+ *    second = { 'a' }
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    first = { 'A' }
+ *    second = { 'a' }
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param first the first array
+ * @param second the second array
+ * @param isCaseSensitive check whether or not the equality should be case sensitive
+ * @return true if the two arrays are identical character by character according to the value
+ * of isCaseSensitive, otherwise false
+ */
+public static final boolean equals(
+	char[] first,
+	char[] second,
+	boolean isCaseSensitive) {
+
+	if (isCaseSensitive) {
+		return equals(first, second);
+	}
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != second.length)
+		return false;
+
+	for (int i = first.length; --i >= 0;)
+		if (ScannerHelper.toLowerCase(first[i])
+			!= ScannerHelper.toLowerCase(second[i]))
+			return false;
+	return true;
+}
+
+/**
+ * If isCaseSensite is true, the equality is case sensitive, otherwise it is case insensitive.
+ *
+ * Answers true if the name contains the fragment at the starting index startIndex, otherwise false.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    fragment = { 'b', 'c' , 'd' }
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    startIndex = 1
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    fragment = { 'b', 'c' , 'd' }
+ *    name = { 'a', 'b', 'C' , 'd' }
+ *    startIndex = 1
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    fragment = { 'b', 'c' , 'd' }
+ *    name = { 'a', 'b', 'C' , 'd' }
+ *    startIndex = 0
+ *    isCaseSensitive = false
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    fragment = { 'b', 'c' , 'd' }
+ *    name = { 'a', 'b'}
+ *    startIndex = 0
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param fragment the fragment to check
+ * @param name the array to check
+ * @param startIndex the starting index
+ * @param isCaseSensitive check whether or not the equality should be case sensitive
+ * @return true if the name contains the fragment at the starting index startIndex according to the
+ * value of isCaseSensitive, otherwise false.
+ * @throws NullPointerException if fragment or name is null.
+ */
+public static final boolean fragmentEquals(
+	char[] fragment,
+	char[] name,
+	int startIndex,
+	boolean isCaseSensitive) {
+
+	int max = fragment.length;
+	if (name.length < max + startIndex)
+		return false;
+	if (isCaseSensitive) {
+		for (int i = max;
+			--i >= 0;
+			) // assumes the prefix is not larger than the name
+			if (fragment[i] != name[i + startIndex])
+				return false;
+		return true;
+	}
+	for (int i = max;
+		--i >= 0;
+		) // assumes the prefix is not larger than the name
+		if (ScannerHelper.toLowerCase(fragment[i])
+			!= ScannerHelper.toLowerCase(name[i + startIndex]))
+			return false;
+	return true;
+}
+
+/**
+ * Answers a hashcode for the array
+ *
+ * @param array the array for which a hashcode is required
+ * @return the hashcode
+ * @throws NullPointerException if array is null
+ */
+public static final int hashCode(char[] array) {
+	int length = array.length;
+	int hash = length == 0 ? 31 : array[0];
+	if (length < 8) {
+		for (int i = length; --i > 0;)
+			hash = (hash * 31) + array[i];
+	} else {
+		// 8 characters is enough to compute a decent hash code, don't waste time examining every character
+		for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
+			hash = (hash * 31) + array[i];
+	}
+	return hash & 0x7FFFFFFF;
+}
+
+/**
+ * Answers true if c is a whitespace according to the JLS (&#92;u0009, &#92;u000a, &#92;u000c, &#92;u000d, &#92;u0020), otherwise false.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    c = ' '
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    c = '&#92;u3000'
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param c the character to check
+ * @return true if c is a whitespace according to the JLS, otherwise false.
+ */
+public static boolean isWhitespace(char c) {
+	return c < ScannerHelper.MAX_OBVIOUS && ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) != 0);
+}
+
+/**
+ * Answers the first index in the array for which the corresponding character is
+ * equal to toBeFound. Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @return the first index in the array for which the corresponding character is
+ * equal to toBeFound, -1 otherwise
+ * @throws NullPointerException if array is null
+ */
+public static final int indexOf(char toBeFound, char[] array) {
+	return indexOf(toBeFound, array, 0);
+}
+
+/**
+ * Answers the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule. Answers -1 if no match is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = { 'c' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = { 'e' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the subarray to search
+ * @param array the array to be searched
+ * @param isCaseSensitive flag to know if the matching should be case sensitive
+ * @return the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule, -1 otherwise
+ * @throws NullPointerException if array is null or toBeFound is null
+ * @since 3.2
+ */
+public static final int indexOf(char[] toBeFound, char[] array, boolean isCaseSensitive) {
+	return indexOf(toBeFound, array, isCaseSensitive, 0);
+}
+
+/**
+ * Answers the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule starting at the index start. Answers -1 if no match is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = { 'c' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = { 'e' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the subarray to search
+ * @param array the array to be searched
+ * @param isCaseSensitive flag to know if the matching should be case sensitive
+ * @param start the starting index
+ * @return the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule starting at the index start, -1 otherwise
+ * @throws NullPointerException if array is null or toBeFound is null
+ * @since 3.2
+ */
+public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start) {
+	return indexOf(toBeFound, array, isCaseSensitive, start, array.length);
+}
+
+/**
+ * Answers the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule starting at the index start. Answers -1 if no match is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = { 'c' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = { 'e' }
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the subarray to search
+ * @param array the array to be searched
+ * @param isCaseSensitive flag to know if the matching should be case sensitive
+ * @param start the starting index (inclusive)
+ * @param end the end index (exclusive)
+ * @return the first index in the array for which the toBeFound array is a matching
+ * subarray following the case rule starting at the index start, -1 otherwise
+ * @throws NullPointerException if array is null or toBeFound is null
+ * @since 3.2
+ */
+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 || start < 0) return -1;
+	if (toBeFoundLength == 0) return 0;
+	if (toBeFoundLength == arrayLength) {
+		if (isCaseSensitive) {
+			for (int i = start; i < arrayLength; i++) {
+				if (array[i] != toBeFound[i]) return -1;
+			}
+			return 0;
+		} else {
+			for (int i = start; i < arrayLength; i++) {
+				if (ScannerHelper.toLowerCase(array[i]) != ScannerHelper.toLowerCase(toBeFound[i])) return -1;
+			}
+			return 0;
+		}
+	}
+	if (isCaseSensitive) {
+		arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
+			if (array[i] == toBeFound[0]) {
+				for (int j = 1; j < toBeFoundLength; j++) {
+					if (array[i + j] != toBeFound[j]) continue arrayLoop;
+				}
+				return i;
+			}
+		}
+	} else {
+		arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
+			if (ScannerHelper.toLowerCase(array[i]) == ScannerHelper.toLowerCase(toBeFound[0])) {
+				for (int j = 1; j < toBeFoundLength; j++) {
+					if (ScannerHelper.toLowerCase(array[i + j]) != ScannerHelper.toLowerCase(toBeFound[j])) continue arrayLoop;
+				}
+				return i;
+			}
+		}
+	}
+	return -1;
+}
+
+/**
+ * Answers the first index in the array for which the corresponding character is
+ * equal to toBeFound starting the search at index start.
+ * Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 2
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 3
+ *    result => -1
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 1
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @param start the starting index
+ * @return the first index in the array for which the corresponding character is
+ * equal to toBeFound, -1 otherwise
+ * @throws NullPointerException if array is null
+ * @throws ArrayIndexOutOfBoundsException if  start is lower than 0
+ */
+public static final int indexOf(char toBeFound, char[] array, int start) {
+	for (int i = start; i < array.length; i++)
+		if (toBeFound == array[i])
+			return i;
+	return -1;
+}
+
+/**
+ * Answers the first index in the array for which the corresponding character is
+ * equal to toBeFound starting the search at index start and before the ending index.
+ * Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 2
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 3
+ *    result => -1
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    start = 1
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @param start the starting index (inclusive)
+ * @param end the ending index (exclusive)
+ * @return the first index in the array for which the corresponding character is
+ * equal to toBeFound, -1 otherwise
+ * @throws NullPointerException if array is null
+ * @throws ArrayIndexOutOfBoundsException if  start is lower than 0 or ending greater than array length
+ * @since 3.2
+ */
+public static final int indexOf(char toBeFound, char[] array, int start, int end) {
+	for (int i = start; i < end; i++)
+		if (toBeFound == array[i])
+			return i;
+	return -1;
+}
+
+/**
+ * Answers the last index in the array for which the corresponding character is
+ * equal to toBeFound starting from the end of the array.
+ * Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
+ *    result => 4
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @return the last index in the array for which the corresponding character is
+ * equal to toBeFound starting from the end of the array, -1 otherwise
+ * @throws NullPointerException if array is null
+ */
+public static final int lastIndexOf(char toBeFound, char[] array) {
+	for (int i = array.length; --i >= 0;)
+		if (toBeFound == array[i])
+			return i;
+	return -1;
+}
+
+/**
+ * Answers the last index in the array for which the corresponding character is
+ * equal to toBeFound stopping at the index startIndex.
+ * Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    startIndex = 2
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd', 'e' }
+ *    startIndex = 3
+ *    result => -1
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    startIndex = 0
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @param startIndex the stopping index
+ * @return the last index in the array for which the corresponding character is
+ * equal to toBeFound stopping at the index startIndex, -1 otherwise
+ * @throws NullPointerException if array is null
+ * @throws ArrayIndexOutOfBoundsException if startIndex is lower than 0
+ */
+public static final int lastIndexOf(
+	char toBeFound,
+	char[] array,
+	int startIndex) {
+	for (int i = array.length; --i >= startIndex;)
+		if (toBeFound == array[i])
+			return i;
+	return -1;
+}
+
+/**
+ * Answers the last index in the array for which the corresponding character is
+ * equal to toBeFound starting from endIndex to startIndex.
+ * Answers -1 if no occurrence of this character is found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    startIndex = 2
+ *    endIndex = 2
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { ' a', 'b', 'c', 'd', 'e' }
+ *    startIndex = 3
+ *    endIndex = 4
+ *    result => -1
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'e'
+ *    array = { ' a', 'b', 'c', 'd' }
+ *    startIndex = 0
+ *    endIndex = 3
+ *    result => -1
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the character to search
+ * @param array the array to be searched
+ * @param startIndex the stopping index
+ * @param endIndex the starting index
+ * @return the last index in the array for which the corresponding character is
+ * equal to toBeFound starting from endIndex to startIndex, -1 otherwise
+ * @throws NullPointerException if array is null
+ * @throws ArrayIndexOutOfBoundsException if endIndex is greater or equals to array length or starting is lower than 0
+ */
+public static final int lastIndexOf(
+	char toBeFound,
+	char[] array,
+	int startIndex,
+	int endIndex) {
+	for (int i = endIndex; --i >= startIndex;)
+		if (toBeFound == array[i])
+			return i;
+	return -1;
+}
+
+/**
+ * Answers the last portion of a name given a separator.
+ * <br>
+ * <br>
+ * For example,
+ * <pre>
+ * 	lastSegment("java.lang.Object".toCharArray(),'.') --> Object
+ * </pre>
+ *
+ * @param array the array
+ * @param separator the given separator
+ * @return the last portion of a name given a separator
+ * @throws NullPointerException if array is null
+ */
+final static public char[] lastSegment(char[] array, char separator) {
+	int pos = lastIndexOf(separator, array);
+	if (pos < 0)
+		return array;
+	return subarray(array, pos + 1, array.length);
+}
+
+/**
+ * <p>Answers true if the pattern matches the given name, false otherwise. This char[] pattern matching
+ * accepts wild-cards '*' and '?'.</p>
+ *
+ * <p>When not case sensitive, the pattern is assumed to already be lowercased, the
+ * name will be lowercased character per character as comparing.<br>
+ * If name is null, the answer is false.<br>
+ * If pattern is null, the answer is true if name is not null.
+ * </p>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    pattern = { '?', 'b', '*' }
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    pattern = { '?', 'b', '?' }
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    pattern = { 'b', '*' }
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @param isCaseSensitive flag to know whether or not the matching should be case sensitive
+ * @return true if the pattern matches the given name, false otherwise
+ */
+public static final boolean match(
+	char[] pattern,
+	char[] name,
+	boolean isCaseSensitive) {
+
+	if (name == null)
+		return false; // null name cannot match
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+
+	return match(
+		pattern,
+		0,
+		pattern.length,
+		name,
+		0,
+		name.length,
+		isCaseSensitive);
+}
+
+/**
+ * Answers true if a sub-pattern matches the subpart of the given name, false otherwise.
+ * char[] pattern matching, accepting wild-cards '*' and '?'. Can match only subset of name/pattern.
+ * end positions are non-inclusive.
+ * The subpattern is defined by the patternStart and pattternEnd positions.
+ * When not case sensitive, the pattern is assumed to already be lowercased, the
+ * name will be lowercased character per character as comparing.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    pattern = { '?', 'b', '*' }
+ *    patternStart = 1
+ *    patternEnd = 3
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    nameStart = 1
+ *    nameEnd = 4
+ *    isCaseSensitive = true
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    pattern = { '?', 'b', '*' }
+ *    patternStart = 1
+ *    patternEnd = 2
+ *    name = { 'a', 'b', 'c' , 'd' }
+ *    nameStart = 1
+ *    nameEnd = 4
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param pattern the given pattern
+ * @param patternStart the given pattern start
+ * @param patternEnd the given pattern end
+ * @param name the given name
+ * @param nameStart the given name start
+ * @param nameEnd the given name end
+ * @param isCaseSensitive flag to know if the matching should be case sensitive
+ * @return true if a sub-pattern matches the subpart of the given name, false otherwise
+ */
+public static final boolean match(
+	char[] pattern,
+	int patternStart,
+	int patternEnd,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	boolean isCaseSensitive) {
+
+	if (name == null)
+		return false; // null name cannot match
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	int iPattern = patternStart;
+	int iName = nameStart;
+
+	if (patternEnd < 0)
+		patternEnd = pattern.length;
+	if (nameEnd < 0)
+		nameEnd = name.length;
+
+	/* check first segment */
+	char patternChar = 0;
+	while (true) {
+		if (iPattern == patternEnd) {
+			if (iName == nameEnd) return true; // the chars match
+			return false; // pattern has ended but not the name, no match
+		} 
+		if ((patternChar = pattern[iPattern]) == '*') {
+			break;
+		}
+		if (iName == nameEnd) {
+			return false; // name has ended but not the pattern
+		}
+		if (patternChar
+			!= (isCaseSensitive
+				? name[iName]
+				: ScannerHelper.toLowerCase(name[iName]))
+			&& patternChar != '?') {
+			return false;
+		}
+		iName++;
+		iPattern++;
+	}
+	/* check sequence of star+segment */
+	int segmentStart;
+	if (patternChar == '*') {
+		segmentStart = ++iPattern; // skip star
+	} else {
+		segmentStart = 0; // force iName check
+	}
+	int prefixStart = iName;
+	checkSegment : while (iName < nameEnd) {
+		if (iPattern == patternEnd) {
+			iPattern = segmentStart; // mismatch - restart current segment
+			iName = ++prefixStart;
+			continue checkSegment;
+		}
+		/* segment is ending */
+		if ((patternChar = pattern[iPattern]) == '*') {
+			segmentStart = ++iPattern; // skip start
+			if (segmentStart == patternEnd) {
+				return true;
+			}
+			prefixStart = iName;
+			continue checkSegment;
+		}
+		/* check current name character */
+		if ((isCaseSensitive ? name[iName] : ScannerHelper.toLowerCase(name[iName]))
+					!= patternChar
+				&& patternChar != '?') {
+			iPattern = segmentStart; // mismatch - restart current segment
+			iName = ++prefixStart;
+			continue checkSegment;
+		}
+		iName++;
+		iPattern++;
+	}
+
+	return (segmentStart == patternEnd)
+		|| (iName == nameEnd && iPattern == patternEnd)
+		|| (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
+}
+
+/**
+ * Answers true if the pattern matches the filepath using the pathSepatator, false otherwise.
+ *
+ * Path char[] pattern matching, accepting wild-cards '**', '*' and '?' (using Ant directory tasks
+ * conventions, also see "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes").
+ * Path pattern matching is enhancing regular pattern matching in supporting extra rule where '**' represent
+ * any folder combination.
+ * Special rule:
+ * - foo\  is equivalent to foo\**
+ * When not case sensitive, the pattern is assumed to already be lowercased, the
+ * name will be lowercased character per character as comparing.
+ *
+ * @param pattern the given pattern
+ * @param filepath the given path
+ * @param isCaseSensitive to find out whether or not the matching should be case sensitive
+ * @param pathSeparator the given path separator
+ * @return true if the pattern matches the filepath using the pathSepatator, false otherwise
+ */
+public static final boolean pathMatch(
+	char[] pattern,
+	char[] filepath,
+	boolean isCaseSensitive,
+	char pathSeparator) {
+
+	if (filepath == null)
+		return false; // null name cannot match
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+
+	// offsets inside pattern
+	int pSegmentStart = pattern[0] == pathSeparator ? 1 : 0;
+	int pLength = pattern.length;
+	int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart+1);
+	if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+	// special case: pattern foo\ is equivalent to foo\**
+	boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator;
+
+	// offsets inside filepath
+	int fSegmentStart, fLength = filepath.length;
+	if (filepath[0] != pathSeparator){
+		fSegmentStart = 0;
+	} else {
+		fSegmentStart = 1;
+	}
+	if (fSegmentStart != pSegmentStart) {
+		return false; // both must start with a separator or none.
+	}
+	int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart+1);
+	if (fSegmentEnd < 0) fSegmentEnd = fLength;
+
+	// first segments
+	while (pSegmentStart < pLength
+		&& !(pSegmentEnd == pLength && freeTrailingDoubleStar
+				|| (pSegmentEnd == pSegmentStart + 2
+						&& pattern[pSegmentStart] == '*'
+						&& pattern[pSegmentStart + 1] == '*'))) {
+
+		if (fSegmentStart >= fLength)
+			return false;
+		if (!CharOperation
+			.match(
+				pattern,
+				pSegmentStart,
+				pSegmentEnd,
+				filepath,
+				fSegmentStart,
+				fSegmentEnd,
+				isCaseSensitive)) {
+			return false;
+		}
+
+		// jump to next segment
+		pSegmentEnd =
+			CharOperation.indexOf(
+				pathSeparator,
+				pattern,
+				pSegmentStart = pSegmentEnd + 1);
+		// skip separator
+		if (pSegmentEnd < 0)
+			pSegmentEnd = pLength;
+
+		fSegmentEnd =
+			CharOperation.indexOf(
+				pathSeparator,
+				filepath,
+				fSegmentStart = fSegmentEnd + 1);
+		// skip separator
+		if (fSegmentEnd < 0) fSegmentEnd = fLength;
+	}
+
+	/* check sequence of doubleStar+segment */
+	int pSegmentRestart;
+	if ((pSegmentStart >= pLength && freeTrailingDoubleStar)
+			|| (pSegmentEnd == pSegmentStart + 2
+				&& pattern[pSegmentStart] == '*'
+				&& pattern[pSegmentStart + 1] == '*')) {
+		pSegmentEnd =
+			CharOperation.indexOf(
+				pathSeparator,
+				pattern,
+				pSegmentStart = pSegmentEnd + 1);
+		// skip separator
+		if (pSegmentEnd < 0) pSegmentEnd = pLength;
+		pSegmentRestart = pSegmentStart;
+	} else {
+		if (pSegmentStart >= pLength) return fSegmentStart >= fLength; // true if filepath is done too.
+		pSegmentRestart = 0; // force fSegmentStart check
+	}
+	int fSegmentRestart = fSegmentStart;
+	checkSegment : while (fSegmentStart < fLength) {
+
+		if (pSegmentStart >= pLength) {
+			if (freeTrailingDoubleStar) return true;
+			// mismatch - restart current path segment
+			pSegmentEnd =
+				CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
+			if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+			fSegmentRestart =
+				CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
+			// skip separator
+			if (fSegmentRestart < 0) {
+				fSegmentRestart = fLength;
+			} else {
+				fSegmentRestart++;
+			}
+			fSegmentEnd =
+				CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
+			if (fSegmentEnd < 0) fSegmentEnd = fLength;
+			continue checkSegment;
+		}
+
+		/* path segment is ending */
+		if (pSegmentEnd == pSegmentStart + 2
+			&& pattern[pSegmentStart] == '*'
+			&& pattern[pSegmentStart + 1] == '*') {
+			pSegmentEnd =
+				CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
+			// skip separator
+			if (pSegmentEnd < 0) pSegmentEnd = pLength;
+			pSegmentRestart = pSegmentStart;
+			fSegmentRestart = fSegmentStart;
+			if (pSegmentStart >= pLength) return true;
+			continue checkSegment;
+		}
+		/* chech current path segment */
+		if (!CharOperation.match(
+							pattern,
+							pSegmentStart,
+							pSegmentEnd,
+							filepath,
+							fSegmentStart,
+							fSegmentEnd,
+							isCaseSensitive)) {
+			// mismatch - restart current path segment
+			pSegmentEnd =
+				CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
+			if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+			fSegmentRestart =
+				CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
+			// skip separator
+			if (fSegmentRestart < 0) {
+				fSegmentRestart = fLength;
+			} else {
+				fSegmentRestart++;
+			}
+			fSegmentEnd =
+				CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
+			if (fSegmentEnd < 0) fSegmentEnd = fLength;
+			continue checkSegment;
+		}
+		// jump to next segment
+		pSegmentEnd =
+			CharOperation.indexOf(
+				pathSeparator,
+				pattern,
+				pSegmentStart = pSegmentEnd + 1);
+		// skip separator
+		if (pSegmentEnd < 0)
+			pSegmentEnd = pLength;
+
+		fSegmentEnd =
+			CharOperation.indexOf(
+				pathSeparator,
+				filepath,
+				fSegmentStart = fSegmentEnd + 1);
+		// skip separator
+		if (fSegmentEnd < 0)
+			fSegmentEnd = fLength;
+	}
+
+	return (pSegmentRestart >= pSegmentEnd)
+		|| (fSegmentStart >= fLength && pSegmentStart >= pLength)
+		|| (pSegmentStart == pLength - 2
+			&& pattern[pSegmentStart] == '*'
+			&& pattern[pSegmentStart + 1] == '*')
+		|| (pSegmentStart == pLength && freeTrailingDoubleStar);
+}
+
+/**
+ * Answers the number of occurrences of the given character in the given array, 0 if any.
+ *
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'b'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => 3
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => 0
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the given character
+ * @param array the given array
+ * @return the number of occurrences of the given character in the given array, 0 if any
+ * @throws NullPointerException if array is null
+ */
+public static final int occurencesOf(char toBeFound, char[] array) {
+	int count = 0;
+	for (int i = 0; i < array.length; i++)
+		if (toBeFound == array[i])
+			count++;
+	return count;
+}
+
+/**
+ * Answers the number of occurrences of the given character in the given array starting
+ * at the given index, 0 if any.
+ *
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    toBeFound = 'b'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    start = 2
+ *    result => 2
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    toBeFound = 'c'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    start = 0
+ *    result => 0
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param toBeFound the given character
+ * @param array the given array
+ * @param start the given index
+ * @return the number of occurrences of the given character in the given array, 0 if any
+ * @throws NullPointerException if array is null
+ * @throws ArrayIndexOutOfBoundsException if start is lower than 0
+ */
+public static final int occurencesOf(
+	char toBeFound,
+	char[] array,
+	int start) {
+	int count = 0;
+	for (int i = start; i < array.length; i++)
+		if (toBeFound == array[i])
+			count++;
+	return count;
+}
+/**
+ * Return the int value represented by the designated subpart of array. The
+ * calculation of the result for single-digit positive integers is optimized in
+ * time.
+ * @param array the array within which the int value is to be parsed
+ * @param start first character of the int value in array
+ * @param length length of the int value in array
+ * @return the int value of a subpart of array
+ * @throws NumberFormatException if the designated subpart of array does not
+ *         parse to an int
+ * @since 3.4
+ */
+public static final int parseInt(char[] array, int start, int length) throws NumberFormatException {
+	if (length == 1) {
+		int result = array[start] - '0';
+		if (result < 0 || result > 9) {
+			throw new NumberFormatException("invalid digit"); //$NON-NLS-1$
+		}
+		return result;
+	} else {
+		return Integer.parseInt(new String(array, start, length));
+	}
+}
+/**
+ * Answers true if the given name starts with the given prefix, false otherwise.
+ * The comparison is case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    prefix = { 'a' , 'b' }
+ *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    prefix = { 'a' , 'c' }
+ *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param prefix the given prefix
+ * @param name the given name
+ * @return true if the given name starts with the given prefix, false otherwise
+ * @throws NullPointerException if the given name is null or if the given prefix is null
+ */
+public static final boolean prefixEquals(char[] prefix, char[] name) {
+
+	int max = prefix.length;
+	if (name.length < max)
+		return false;
+	for (int i = max;
+		--i >= 0;
+		) // assumes the prefix is not larger than the name
+		if (prefix[i] != name[i])
+			return false;
+	return true;
+}
+
+/**
+ * Answers true if the given name starts with the given prefix, false otherwise.
+ * isCaseSensitive is used to find out whether or not the comparison should be case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    prefix = { 'a' , 'B' }
+ *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    prefix = { 'a' , 'B' }
+ *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param prefix the given prefix
+ * @param name the given name
+ * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
+ * @return true if the given name starts with the given prefix, false otherwise
+ * @throws NullPointerException if the given name is null or if the given prefix is null
+ */
+public static final boolean prefixEquals(
+	char[] prefix,
+	char[] name,
+	boolean isCaseSensitive) {
+	return prefixEquals(prefix, name, isCaseSensitive, 0);
+}
+
+/**
+ * Answers true if the given name, starting from the given index, starts with the given prefix,
+ * false otherwise. isCaseSensitive is used to find out whether or not the comparison should be
+ * case sensitive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    prefix = { 'a' , 'B' }
+ *    name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    startIndex = 2
+ *    isCaseSensitive = false
+ *    result => true
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    prefix = { 'a' , 'B' }
+ *    name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    startIndex = 2
+ *    isCaseSensitive = true
+ *    result => false
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param prefix the given prefix
+ * @param name the given name
+ * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
+ * @param startIndex index from which the prefix should be searched in the name
+ * @return true if the given name starts with the given prefix, false otherwise
+ * @throws NullPointerException if the given name is null or if the given prefix is null
+ * @since 3.7
+ */
+public static final boolean prefixEquals(
+	char[] prefix,
+	char[] name,
+	boolean isCaseSensitive,
+	int startIndex) {
+
+	int max = prefix.length;
+	if (name.length - startIndex < max)
+		return false;
+	if (isCaseSensitive) {
+		for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
+			if (prefix[i] != name[startIndex + i])
+				return false;
+		return true;
+	}
+
+	for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
+		if (ScannerHelper.toLowerCase(prefix[i])
+			!= ScannerHelper.toLowerCase(name[startIndex + i]))
+			return false;
+	return true;
+}
+
+/**
+ * Answers a new array removing a given character. Answers the given array if there is
+ * no occurrence of the character to remove.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'c', 'b', 'a' }
+ *    toBeRemoved = 'b'
+ *    return { 'a' , 'c', 'a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeRemoved = 'c'
+ *    return array
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeRemoved the character to be removed
+ * @return a new array removing given character
+ * @since 3.2
+ */
+public static final char[] remove(char[] array, char toBeRemoved) {
+
+	if (array == null) return null;
+	int length = array.length;
+	if (length == 0) return array;
+	char[] result = null;
+	int count = 0;
+	for (int i = 0; i < length; i++) {
+		char c = array[i];
+		if (c == toBeRemoved) {
+			if (result == null) {
+				result = new char[length];
+				System.arraycopy(array, 0, result, 0, i);
+				count = i;
+			}
+		} else if (result != null) {
+			result[count++] = c;
+		}
+	}
+	if (result == null) return array;
+	System.arraycopy(result, 0, result = new char[count], 0, count);
+	return result;
+}
+
+/**
+ * Replace all occurrence of the character to be replaced with the replacement character in the
+ * given array.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = 'b'
+ *    replacementChar = 'a'
+ *    result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = 'c'
+ *    replacementChar = 'a'
+ *    result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeReplaced the character to be replaced
+ * @param replacementChar the replacement character
+ * @throws NullPointerException if the given array is null
+ */
+public static final void replace(
+	char[] array,
+	char toBeReplaced,
+	char replacementChar) {
+	if (toBeReplaced != replacementChar) {
+		for (int i = 0, max = array.length; i < max; i++) {
+			if (array[i] == toBeReplaced)
+				array[i] = replacementChar;
+		}
+	}
+}
+
+/**
+ * Replace all occurrences of characters to be replaced with the replacement character in the
+ * given array.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
+ *    toBeReplaced = { 'b', 'c' }
+ *    replacementChar = 'a'
+ *    result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeReplaced characters to be replaced
+ * @param replacementChar the replacement character
+ * @throws NullPointerException if arrays are null.
+ * @since 3.1
+ */
+public static final void replace(char[] array, char[] toBeReplaced, char replacementChar) {
+	replace(array, toBeReplaced, replacementChar, 0, array.length);
+}
+
+/**
+ * Replace all occurrences of characters to be replaced with the replacement character in the
+ * given array from the start position (inclusive) to the end position (exclusive).
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
+ *    toBeReplaced = { 'b', 'c' }
+ *    replacementChar = 'a'
+ *    start = 4
+ *    end = 8
+ *    result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'c', 'a', 'a', 'a', 'a' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeReplaced characters to be replaced
+ * @param replacementChar the replacement character
+ * @param start the given start position (inclusive)
+ * @param end  the given end position (exclusive)
+ * @throws NullPointerException if arrays are null.
+ * @since 3.2
+ */
+public static final void replace(char[] array, char[] toBeReplaced, char replacementChar, int start, int end) {
+	for (int i = end; --i >= start;)
+		for (int j = toBeReplaced.length; --j >= 0;)
+			if (array[i] == toBeReplaced[j])
+				array[i] = replacementChar;
+}
+/**
+ * Answers a new array of characters with substitutions. No side-effect is operated on the original
+ * array, in case no substitution happened, then the result is the same as the
+ * original one.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = { 'b' }
+ *    replacementChar = { 'a', 'a' }
+ *    result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = { 'c' }
+ *    replacementChar = { 'a' }
+ *    result => { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeReplaced characters to be replaced
+ * @param replacementChars the replacement characters
+ * @return a new array of characters with substitutions or the given array if none
+ * @throws NullPointerException if the given array is null
+ */
+public static final char[] replace(
+	char[] array,
+	char[] toBeReplaced,
+	char[] replacementChars) {
+
+	int max = array.length;
+	int replacedLength = toBeReplaced.length;
+	int replacementLength = replacementChars.length;
+
+	int[] starts = new int[5];
+	int occurrenceCount = 0;
+
+	if (!equals(toBeReplaced, replacementChars)) {
+
+		next : for (int i = 0; i < max;) {
+			int index = indexOf(toBeReplaced, array, true, i);
+			if (index == -1) {
+				i++;
+				continue next;
+			}
+			if (occurrenceCount == starts.length) {
+				System.arraycopy(
+					starts,
+					0,
+					starts = new int[occurrenceCount * 2],
+					0,
+					occurrenceCount);
+			}
+			starts[occurrenceCount++] = index;
+			i = index + replacedLength;
+		}
+	}
+	if (occurrenceCount == 0)
+		return array;
+	char[] result =
+		new char[max
+			+ occurrenceCount * (replacementLength - replacedLength)];
+	int inStart = 0, outStart = 0;
+	for (int i = 0; i < occurrenceCount; i++) {
+		int offset = starts[i] - inStart;
+		System.arraycopy(array, inStart, result, outStart, offset);
+		inStart += offset;
+		outStart += offset;
+		System.arraycopy(
+			replacementChars,
+			0,
+			result,
+			outStart,
+			replacementLength);
+		inStart += replacedLength;
+		outStart += replacementLength;
+	}
+	System.arraycopy(array, inStart, result, outStart, max - inStart);
+	return result;
+}
+
+/**
+ * Replace all occurrence of the character to be replaced with the replacement character
+ * in a copy of the given array. Returns the given array if no occurrences of the character
+ * to be replaced are found.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = 'b'
+ *    replacementChar = 'a'
+ *    result => A new array that is equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    toBeReplaced = 'c'
+ *    replacementChar = 'a'
+ *    result => The original array that remains unchanged.
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param toBeReplaced the character to be replaced
+ * @param replacementChar the replacement character
+ * @throws NullPointerException if the given array is null
+ * @since 3.1
+ */
+public static final char[] replaceOnCopy(
+	char[] array,
+	char toBeReplaced,
+	char replacementChar) {
+
+	char[] result = null;
+	for (int i = 0, length = array.length; i < length; i++) {
+		char c = array[i];
+		if (c == toBeReplaced) {
+			if (result == null) {
+				result = new char[length];
+				System.arraycopy(array, 0, result, 0, i);
+			}
+			result[i] = replacementChar;
+		} else if (result != null) {
+			result[i] = c;
+		}
+	}
+	if (result == null) return array;
+	return result;
+}
+
+/**
+ * Return a new array which is the split of the given array using the given divider and trimming each subarray to remove
+ * whitespaces equals to ' '.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    divider = 'b'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    divider = 'c'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    divider = 'b'
+ *    array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
+ *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    divider = 'c'
+ *    array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
+ *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param divider the given divider
+ * @param array the given array
+ * @return a new array which is the split of the given array using the given divider and trimming each subarray to remove
+ * whitespaces equals to ' '
+ */
+public static final char[][] splitAndTrimOn(char divider, char[] array) {
+	int length = array == null ? 0 : array.length;
+	if (length == 0)
+		return NO_CHAR_CHAR;
+
+	int wordCount = 1;
+	for (int i = 0; i < length; i++)
+		if (array[i] == divider)
+			wordCount++;
+	char[][] split = new char[wordCount][];
+	int last = 0, currentWord = 0;
+	for (int i = 0; i < length; i++) {
+		if (array[i] == divider) {
+			int start = last, end = i - 1;
+			while (start < i && array[start] == ' ')
+				start++;
+			while (end > start && array[end] == ' ')
+				end--;
+			split[currentWord] = new char[end - start + 1];
+			System.arraycopy(
+				array,
+				start,
+				split[currentWord++],
+				0,
+				end - start + 1);
+			last = i + 1;
+		}
+	}
+	int start = last, end = length - 1;
+	while (start < length && array[start] == ' ')
+		start++;
+	while (end > start && array[end] == ' ')
+		end--;
+	split[currentWord] = new char[end - start + 1];
+	System.arraycopy(
+		array,
+		start,
+		split[currentWord++],
+		0,
+		end - start + 1);
+	return split;
+}
+
+/**
+ * Return a new array which is the split of the given array using the given divider.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    divider = 'b'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    divider = 'c'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    divider = 'c'
+ *    array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
+ *    result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param divider the given divider
+ * @param array the given array
+ * @return a new array which is the split of the given array using the given divider
+ */
+public static final char[][] splitOn(char divider, char[] array) {
+	int length = array == null ? 0 : array.length;
+	if (length == 0)
+		return NO_CHAR_CHAR;
+
+	int wordCount = 1;
+	for (int i = 0; i < length; i++)
+		if (array[i] == divider)
+			wordCount++;
+	char[][] split = new char[wordCount][];
+	int last = 0, currentWord = 0;
+	for (int i = 0; i < length; i++) {
+		if (array[i] == divider) {
+			split[currentWord] = new char[i - last];
+			System.arraycopy(
+				array,
+				last,
+				split[currentWord++],
+				0,
+				i - last);
+			last = i + 1;
+		}
+	}
+	split[currentWord] = new char[length - last];
+	System.arraycopy(array, last, split[currentWord], 0, length - last);
+	return split;
+}
+
+/**
+ * Return a new array which is the split of the given array using the given divider. The given end
+ * is exclusive and the given start is inclusive.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    divider = 'b'
+ *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+ *    start = 2
+ *    end = 5
+ *    result => { {  }, { 'a' }, {  } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param divider the given divider
+ * @param array the given array
+ * @param start the given starting index
+ * @param end the given ending index
+ * @return a new array which is the split of the given array using the given divider
+ * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length
+ */
+public static final char[][] splitOn(
+	char divider,
+	char[] array,
+	int start,
+	int end) {
+	int length = array == null ? 0 : array.length;
+	if (length == 0 || start > end)
+		return NO_CHAR_CHAR;
+
+	int wordCount = 1;
+	for (int i = start; i < end; i++)
+		if (array[i] == divider)
+			wordCount++;
+	char[][] split = new char[wordCount][];
+	int last = start, currentWord = 0;
+	for (int i = start; i < end; i++) {
+		if (array[i] == divider) {
+			split[currentWord] = new char[i - last];
+			System.arraycopy(
+				array,
+				last,
+				split[currentWord++],
+				0,
+				i - last);
+			last = i + 1;
+		}
+	}
+	split[currentWord] = new char[end - last];
+	System.arraycopy(array, last, split[currentWord], 0, end - last);
+	return split;
+}
+
+/**
+ * Answers a new array which is a copy of the given array starting at the given start and
+ * ending at the given end. The given start is inclusive and the given end is exclusive.
+ * Answers null if start is greater than end, if start is lower than 0 or if end is greater
+ * than the length of the given array. If end  equals -1, it is converted to the array length.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { { 'a' } , { 'b' } }
+ *    start = 0
+ *    end = 1
+ *    result => { { 'a' } }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { { 'a' } , { 'b' } }
+ *    start = 0
+ *    end = -1
+ *    result => { { 'a' }, { 'b' } }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param start the given starting index
+ * @param end the given ending index
+ * @return a new array which is a copy of the given array starting at the given start and
+ * ending at the given end
+ * @throws NullPointerException if the given array is null
+ */
+public static final char[][] subarray(char[][] array, int start, int end) {
+	if (end == -1)
+		end = array.length;
+	if (start > end)
+		return null;
+	if (start < 0)
+		return null;
+	if (end > array.length)
+		return null;
+
+	char[][] result = new char[end - start][];
+	System.arraycopy(array, start, result, 0, end - start);
+	return result;
+}
+
+/**
+ * Answers a new array which is a copy of the given array starting at the given start and
+ * ending at the given end. The given start is inclusive and the given end is exclusive.
+ * Answers null if start is greater than end, if start is lower than 0 or if end is greater
+ * than the length of the given array. If end  equals -1, it is converted to the array length.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { 'a' , 'b' }
+ *    start = 0
+ *    end = 1
+ *    result => { 'a' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'b' }
+ *    start = 0
+ *    end = -1
+ *    result => { 'a' , 'b' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @param start the given starting index
+ * @param end the given ending index
+ * @return a new array which is a copy of the given array starting at the given start and
+ * ending at the given end
+ * @throws NullPointerException if the given array is null
+ */
+public static final char[] subarray(char[] array, int start, int end) {
+	if (end == -1)
+		end = array.length;
+	if (start > end)
+		return null;
+	if (start < 0)
+		return null;
+	if (end > array.length)
+		return null;
+
+	char[] result = new char[end - start];
+	System.arraycopy(array, start, result, 0, end - start);
+	return result;
+}
+
+/**
+ * Answers the result of a char[] conversion to lowercase. Answers null if the given chars array is null.
+ * <br>
+ * NOTE: If no conversion was necessary, then answers back the argument one.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    chars = { 'a' , 'b' }
+ *    result => { 'a' , 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'A', 'b' }
+ *    result => { 'a' , 'b' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param chars the chars to convert
+ * @return the result of a char[] conversion to lowercase
+ */
+final static public char[] toLowerCase(char[] chars) {
+	if (chars == null)
+		return null;
+	int length = chars.length;
+	char[] lowerChars = null;
+	for (int i = 0; i < length; i++) {
+		char c = chars[i];
+		char lc = ScannerHelper.toLowerCase(c);
+		if ((c != lc) || (lowerChars != null)) {
+			if (lowerChars == null) {
+				System.arraycopy(
+					chars,
+					0,
+					lowerChars = new char[length],
+					0,
+					i);
+			}
+			lowerChars[i] = lc;
+		}
+	}
+	return lowerChars == null ? chars : lowerChars;
+}
+
+/**
+ * Answers the result of a char[] conversion to uppercase. Answers null if the given chars array is null.
+ * <br>
+ * NOTE: If no conversion was necessary, then answers back the argument one.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    chars = { 'A' , 'B' }
+ *    result => { 'A' , 'B' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'a', 'B' }
+ *    result => { 'A' , 'B' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param chars the chars to convert
+ * @return the result of a char[] conversion to uppercase
+ * 
+ * @since 3.5
+ */
+final static public char[] toUpperCase(char[] chars) {
+	if (chars == null)
+		return null;
+	int length = chars.length;
+	char[] upperChars = null;
+	for (int i = 0; i < length; i++) {
+		char c = chars[i];
+		char lc = ScannerHelper.toUpperCase(c);
+		if ((c != lc) || (upperChars != null)) {
+			if (upperChars == null) {
+				System.arraycopy(
+					chars,
+					0,
+					upperChars = new char[length],
+					0,
+					i);
+			}
+			upperChars[i] = lc;
+		}
+	}
+	return upperChars == null ? chars : upperChars;
+}
+
+/**
+ * Answers a new array removing leading and trailing spaces (' '). Answers the given array if there is no
+ * space characters to remove.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    chars = { ' ', 'a' , 'b', ' ',  ' ' }
+ *    result => { 'a' , 'b' }
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { 'A', 'b' }
+ *    result => { 'A' , 'b' }
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param chars the given array
+ * @return a new array removing leading and trailing spaces (' ')
+ */
+final static public char[] trim(char[] chars) {
+
+	if (chars == null)
+		return null;
+
+	int start = 0, length = chars.length, end = length - 1;
+	while (start < length && chars[start] == ' ') {
+		start++;
+	}
+	while (end > start && chars[end] == ' ') {
+		end--;
+	}
+	if (start != 0 || end != length - 1) {
+		return subarray(chars, start, end + 1);
+	}
+	return chars;
+}
+
+/**
+ * Answers a string which is the concatenation of the given array using the '.' as a separator.
+ * <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li><pre>
+ *    array = { { 'a' } , { 'b' } }
+ *    result => "a.b"
+ * </pre>
+ * </li>
+ * <li><pre>
+ *    array = { { ' ',  'a' } , { 'b' } }
+ *    result => " a.b"
+ * </pre>
+ * </li>
+ * </ol>
+ *
+ * @param array the given array
+ * @return a string which is the concatenation of the given array using the '.' as a separator
+ */
+final static public String toString(char[][] array) {
+	char[] result = concatWith(array, '.');
+	return new String(result);
+}
+
+/**
+ * Answers an array of strings from the given array of char array.
+ *
+ * @param array the given array
+ * @return an array of strings
+ * @since 3.0
+ */
+final static public String[] toStrings(char[][] array) {
+	if (array == null) return NO_STRINGS;
+	int length = array.length;
+	if (length == 0) return NO_STRINGS;
+	String[] result = new String[length];
+	for (int i = 0; i < length; i++)
+		result[i] = new String(array[i]);
+	return result;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CompilationProgress.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CompilationProgress.java
new file mode 100644
index 0000000..a16b75c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CompilationProgress.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
+
+/**
+ * A compilation progress is used by the {@link BatchCompiler} to report progress during compilation.
+ * It is also used to request cancellation of the compilation.
+ * Clients of the {@link BatchCompiler} should subclass this class, instantiate the subclass and pass this instance to
+ * {@link BatchCompiler#compile(String, java.io.PrintWriter, java.io.PrintWriter, CompilationProgress)}.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.4
+ */
+
+public abstract class CompilationProgress {
+
+	/**
+	 * Notifies that the compilation is beginning. This is called exactly once per batch compilation.
+	 * An estimated amount of remaining work is given. This amount will change as the compilation
+	 * progresses. The new estimated amount of remaining work is reported using {@link #worked(int, int)}.
+	 * <p>
+	 * Clients should not call this method.
+	 * </p>
+	 *
+	 * @param remainingWork the estimated amount of remaining work.
+	 */
+	public abstract void begin(int remainingWork);
+
+	/**
+	 * Notifies that the work is done; that is, either the compilation is completed
+	 * or a cancellation was requested. This is called exactly once per batch compilation.
+	 * <p>
+	 * Clients should not call this method.
+	 * </p>
+	 */
+	public abstract void done();
+
+	/**
+	 * Returns whether cancellation of the compilation has been requested.
+	 *
+	 * @return <code>true</code> if cancellation has been requested,
+	 *    and <code>false</code> otherwise
+	 */
+	public abstract boolean isCanceled();
+
+	/**
+	 * Reports the name (or description) of the current task.
+	 * <p>
+	 * Clients should not call this method.
+	 * </p>
+	 *
+	 * @param name the name (or description) of the current task
+	 */
+	public abstract void setTaskName(String name);
+
+
+	/**
+	 * Notifies that a given amount of work of the compilation
+	 * has been completed. Note that this amount represents an
+	 * installment, as opposed to a cumulative amount of work done
+	 * to date.
+	 * Also notifies an estimated amount of remaining work. Note that this
+	 * amount of remaining work  may be greater than the previous estimated
+	 * amount as new compilation units are injected in the compile loop.
+	 * <p>
+	 * Clients should not call this method.
+	 * </p>
+	 *
+	 * @param workIncrement a non-negative amount of work just completed
+	 * @param remainingWork  a non-negative amount of estimated remaining work
+	 */
+	public abstract void worked(int workIncrement, int remainingWork);
+
+
+}
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
new file mode 100644
index 0000000..178a636
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -0,0 +1,1727 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added the following constants
+ *								   NonStaticAccessToStaticField
+ *								   NonStaticAccessToStaticMethod
+ *								   Task
+ *								   ExpressionShouldBeAVariable
+ *								   AssignmentHasNoEffect
+ *     IBM Corporation - added the following constants
+ *								   TooManySyntheticArgumentSlots
+ *								   TooManyArrayDimensions
+ *								   TooManyBytesForStringConstant
+ *								   TooManyMethods
+ *								   TooManyFields
+ *								   NonBlankFinalLocalAssignment
+ *								   ObjectCannotHaveSuperTypes
+ *								   MissingSemiColon
+ *								   InvalidParenthesizedExpression
+ *								   EnclosingInstanceInConstructorCall
+ *								   BytecodeExceeds64KLimitForConstructor
+ *								   IncompatibleReturnTypeForNonInheritedInterfaceMethod
+ *								   UnusedPrivateMethod
+ *								   UnusedPrivateConstructor
+ *								   UnusedPrivateType
+ *								   UnusedPrivateField
+ *								   IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod
+ *								   InvalidExplicitConstructorCall
+ *     IBM Corporation - added the following constants
+ *								   PossibleAccidentalBooleanAssignment
+ *								   SuperfluousSemicolon
+ *								   IndirectAccessToStaticField
+ *								   IndirectAccessToStaticMethod
+ *								   IndirectAccessToStaticType
+ *								   BooleanMethodThrowingException
+ *								   UnnecessaryCast
+ *								   UnnecessaryArgumentCast
+ *								   UnnecessaryInstanceof
+ *								   FinallyMustCompleteNormally
+ *								   UnusedMethodDeclaredThrownException
+ *								   UnusedConstructorDeclaredThrownException
+ *								   InvalidCatchBlockSequence
+ *								   UnqualifiedFieldAccess
+ *     IBM Corporation - added the following constants
+ *								   Javadoc
+ *								   JavadocUnexpectedTag
+ *								   JavadocMissingParamTag
+ *								   JavadocMissingParamName
+ *								   JavadocDuplicateParamName
+ *								   JavadocInvalidParamName
+ *								   JavadocMissingReturnTag
+ *								   JavadocDuplicateReturnTag
+ *								   JavadocMissingThrowsTag
+ *								   JavadocMissingThrowsClassName
+ *								   JavadocInvalidThrowsClass
+ *								   JavadocDuplicateThrowsClassName
+ *								   JavadocInvalidThrowsClassName
+ *								   JavadocMissingSeeReference
+ *								   JavadocInvalidSeeReference
+ *								   JavadocInvalidSeeHref
+ *								   JavadocInvalidSeeArgs
+ *								   JavadocMissing
+ *								   JavadocInvalidTag
+ *								   JavadocMessagePrefix
+ *								   EmptyControlFlowStatement
+ *     IBM Corporation - added the following constants
+ *								   IllegalUsageOfQualifiedTypeReference
+ *								   InvalidDigit
+ *     IBM Corporation - added the following constants
+ *								   ParameterAssignment
+ *								   FallthroughCase
+ *     IBM Corporation - added the following constants
+ *                                 UnusedLabel
+ *                                 UnnecessaryNLSTag
+ *                                 LocalVariableMayBeNull
+ *                                 EnumConstantsCannotBeSurroundedByParenthesis
+ *                                 JavadocMissingIdentifier
+ *                                 JavadocNonStaticTypeFromStaticInvocation
+ *                                 RawTypeReference
+ *                                 NoAdditionalBoundAfterTypeVariable
+ *                                 UnsafeGenericArrayForVarargs
+ *                                 IllegalAccessFromTypeVariable
+ *                                 AnnotationValueMustBeArrayInitializer
+ *                                 InvalidEncoding
+ *                                 CannotReadSource
+ *                                 EnumStaticFieldInInInitializerContext
+ *                                 ExternalProblemNotFixable
+ *                                 ExternalProblemFixable
+ *     IBM Corporation - added the following constants
+ *                                 AnnotationValueMustBeAnEnumConstant
+ *                                 OverridingMethodWithoutSuperInvocation
+ *                                 MethodMustOverrideOrImplement
+ *                                 TypeHidingTypeParameterFromType
+ *                                 TypeHidingTypeParameterFromMethod
+ *                                 TypeHidingType
+ *     IBM Corporation - added the following constants
+ *								   NullLocalVariableReference
+ *								   PotentialNullLocalVariableReference
+ *								   RedundantNullCheckOnNullLocalVariable
+ * 								   NullLocalVariableComparisonYieldsFalse
+ * 								   RedundantLocalVariableNullAssignment
+ * 								   NullLocalVariableInstanceofYieldsFalse
+ * 								   RedundantNullCheckOnNonNullLocalVariable
+ * 								   NonNullLocalVariableComparisonYieldsFalse
+ *     IBM Corporation - added the following constants
+ *                                 InvalidUsageOfTypeParametersForAnnotationDeclaration
+ *                                 InvalidUsageOfTypeParametersForEnumDeclaration
+ *     IBM Corporation - added the following constants
+ *								   RedundantSuperinterface
+ *		Benjamin Muskalla - added the following constants
+ *									MissingSynchronizedModifierInInheritedMethod
+ *		Stephan Herrmann  - added the following constants
+ *									UnusedObjectAllocation
+ *									PotentiallyUnclosedCloseable
+ *									PotentiallyUnclosedCloseableAtExit
+ *									UnclosedCloseable
+ *									UnclosedCloseableAtExit
+ *									ExplicitlyClosedAutoCloseable
+ * 								    RequiredNonNullButProvidedNull
+ * 									RequiredNonNullButProvidedPotentialNull
+ * 									RequiredNonNullButProvidedUnknown
+ * 									NullAnnotationNameMustBeQualified
+ * 									IllegalReturnNullityRedefinition
+ * 									IllegalRedefinitionToNonNullParameter
+ * 									IllegalDefinitionToNonNullParameter
+ * 									ParameterLackingNonNullAnnotation
+ * 									ParameterLackingNullableAnnotation
+ * 									PotentialNullMessageSendReference
+ * 									RedundantNullCheckOnNonNullMessageSend
+ * 									CannotImplementIncompatibleNullness
+ * 									RedundantNullAnnotation
+ *									RedundantNullDefaultAnnotation
+ *									RedundantNullDefaultAnnotationPackage
+ *									RedundantNullDefaultAnnotationType
+ *									RedundantNullDefaultAnnotationMethod
+ *									ContradictoryNullAnnotations
+ *									IllegalAnnotationForBaseType
+ *									RedundantNullCheckOnSpecdNonNullLocalVariable
+ *									SpecdNonNullLocalVariableComparisonYieldsFalse
+ *									RequiredNonNullButProvidedSpecdNullable
+ *									MissingDefaultCase
+ *									MissingEnumConstantCaseDespiteDefault
+ *									UninitializedLocalVariableHintMissingDefault
+ *									UninitializedBlankFinalFieldHintMissingDefault
+ *									ShouldReturnValueHintMissingDefault
+ *									IllegalModifierForInterfaceDefaultMethod
+ *									InheritedDefaultMethodConflictsWithOtherInherited
+ *									ConflictingNullAnnotations
+ *									ConflictingInheritedNullAnnotations
+ *									UnsafeElementTypeConversion
+ *									ArrayReferencePotentialNullReference
+ *									DereferencingNullableExpression
+ *									NullityMismatchingTypeAnnotation
+ *									NullityMismatchingTypeAnnotationUnchecked
+ *									NullableFieldReference
+ *									UninitializedNonNullField
+ *									UninitializedNonNullFieldHintMissingDefault
+ *									NonNullMessageSendComparisonYieldsFalse
+ *									RedundantNullCheckOnNonNullSpecdField
+ *									NonNullSpecdFieldComparisonYieldsFalse
+ *									NonNullExpressionComparisonYieldsFalse
+ *									RedundantNullCheckOnNonNullExpression
+ *									ReferenceExpressionParameterMismatchPromisedNullable
+ *									ReferenceExpressionParameterRequiredNonnullUnchecked
+ *									ReferenceExpressionReturnNullRedef
+ *									ReferenceExpressionReturnNullRedefUnchecked
+ *									DuplicateInheritedDefaultMethods
+ *									SuperAccessCannotBypassDirectSuper
+ *									SuperCallCannotBypassOverride
+ *									ConflictingNullAnnotations
+ *									ConflictingInheritedNullAnnotations
+ *									UnsafeElementTypeConversion
+ *									PotentialNullUnboxing
+ *									NullUnboxing
+ *									NullExpressionReference
+ *									PotentialNullExpressionReference
+ *      Jesper S Moller  - added the following constants
+ *									TargetTypeNotAFunctionalInterface
+ *									OuterLocalMustBeEffectivelyFinal
+ *									IllegalModifiersForPackage
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+
+/**
+ * Description of a Java problem, as detected by the compiler or some of the underlying
+ * technology reusing the compiler.
+ * A problem provides access to:
+ * <ul>
+ * <li> its location (originating source file name, source position, line number), </li>
+ * <li> its message description and a predicate to check its severity (warning or error). </li>
+ * <li> its ID : a number identifying the very nature of this problem. All possible IDs are listed
+ * as constants on this interface. </li>
+ * </ul>
+ *
+ * Note: the compiler produces IProblems internally, which are turned into markers by the JavaBuilder
+ * so as to persist problem descriptions. This explains why there is no API allowing to reach IProblem detected
+ * when compiling. However, the Java problem markers carry equivalent information to IProblem, in particular
+ * their ID (attribute "id") is set to one of the IDs defined on this interface.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IProblem {
+
+/**
+ * Answer back the original arguments recorded into the problem.
+ * @return the original arguments recorded into the problem
+ */
+String[] getArguments();
+
+/**
+ * Returns the problem id
+ *
+ * @return the problem id
+ */
+int getID();
+
+/**
+ * Answer a localized, human-readable message string which describes the problem.
+ *
+ * @return a localized, human-readable message string which describes the problem
+ */
+String getMessage();
+
+/**
+ * Answer the file name in which the problem was found.
+ *
+ * @return the file name in which the problem was found
+ */
+char[] getOriginatingFileName();
+
+/**
+ * Answer the end position of the problem (inclusive), or -1 if unknown.
+ *
+ * @return the end position of the problem (inclusive), or -1 if unknown
+ */
+int getSourceEnd();
+
+/**
+ * Answer the line number in source where the problem begins.
+ *
+ * @return the line number in source where the problem begins
+ */
+int getSourceLineNumber();
+
+/**
+ * Answer the start position of the problem (inclusive), or -1 if unknown.
+ *
+ * @return the start position of the problem (inclusive), or -1 if unknown
+ */
+int getSourceStart();
+
+/**
+ * Checks the severity to see if the Error bit is set.
+ *
+ * @return true if the Error bit is set for the severity, false otherwise
+ */
+boolean isError();
+
+/**
+ * Checks the severity to see if the Error bit is not set.
+ *
+ * @return true if the Error bit is not set for the severity, false otherwise
+ */
+boolean isWarning();
+
+/**
+ * Set the end position of the problem (inclusive), or -1 if unknown.
+ * Used for shifting problem positions.
+ *
+ * @param sourceEnd the given end position
+ */
+void setSourceEnd(int sourceEnd);
+
+/**
+ * Set the line number in source where the problem begins.
+ *
+ * @param lineNumber the given line number
+ */
+void setSourceLineNumber(int lineNumber);
+
+/**
+ * Set the start position of the problem (inclusive), or -1 if unknown.
+ * Used for shifting problem positions.
+ *
+ * @param sourceStart the given start position
+ */
+void setSourceStart(int sourceStart);
+
+
+	/**
+	 * Problem Categories
+	 * The high bits of a problem ID contains information about the category of a problem.
+	 * For example, (problemID & TypeRelated) != 0, indicates that this problem is type related.
+	 *
+	 * A problem category can help to implement custom problem filters. Indeed, when numerous problems
+	 * are listed, focusing on import related problems first might be relevant.
+	 *
+	 * When a problem is tagged as Internal, it means that no change other than a local source code change
+	 * can  fix the corresponding problem. A type related problem could be addressed by changing the type
+	 * involved in it.
+	 */
+	int TypeRelated = 0x01000000;
+	int FieldRelated = 0x02000000;
+	int MethodRelated = 0x04000000;
+	int ConstructorRelated = 0x08000000;
+	int ImportRelated = 0x10000000;
+	int Internal = 0x20000000;
+	int Syntax = 0x40000000;
+	/** @since 3.0 */
+	int Javadoc = 0x80000000;
+
+	/**
+	 * Mask to use in order to filter out the category portion of the problem ID.
+	 */
+	int IgnoreCategoriesMask = 0xFFFFFF;
+
+	/**
+	 * Below are listed all available problem IDs. Note that this list could be augmented in the future,
+	 * as new features are added to the Java core implementation.
+	 */
+
+	/**
+	 * ID reserved for referencing an internal error inside the JavaCore implementation which
+	 * may be surfaced as a problem associated with the compilation unit which caused it to occur.
+	 */
+	int Unclassified = 0;
+
+	/**
+	 * General type related problems
+	 */
+	int ObjectHasNoSuperclass = TypeRelated + 1;
+	int UndefinedType = TypeRelated + 2;
+	int NotVisibleType = TypeRelated + 3;
+	int AmbiguousType = TypeRelated + 4;
+	int UsingDeprecatedType = TypeRelated + 5;
+	int InternalTypeNameProvided = TypeRelated + 6;
+	/** @since 2.1 */
+	int UnusedPrivateType = Internal + TypeRelated + 7;
+
+	int IncompatibleTypesInEqualityOperator = TypeRelated + 15;
+	int IncompatibleTypesInConditionalOperator = TypeRelated + 16;
+	int TypeMismatch = TypeRelated + 17;
+	/** @since 3.0 */
+	int IndirectAccessToStaticType = Internal + TypeRelated + 18;
+
+	/**
+	 * Inner types related problems
+	 */
+	int MissingEnclosingInstanceForConstructorCall = TypeRelated + 20;
+	int MissingEnclosingInstance = TypeRelated + 21;
+	int IncorrectEnclosingInstanceReference = TypeRelated + 22;
+	int IllegalEnclosingInstanceSpecification = TypeRelated + 23;
+	int CannotDefineStaticInitializerInLocalType = Internal + 24;
+	int OuterLocalMustBeFinal = Internal + 25;
+	int CannotDefineInterfaceInLocalType = Internal + 26;
+	int IllegalPrimitiveOrArrayTypeForEnclosingInstance = TypeRelated + 27;
+	/** @since 2.1 */
+	int EnclosingInstanceInConstructorCall = Internal + 28;
+	int AnonymousClassCannotExtendFinalClass = TypeRelated + 29;
+	/** @since 3.1 */
+	int CannotDefineAnnotationInLocalType = Internal + 30;
+	/** @since 3.1 */
+	int CannotDefineEnumInLocalType = Internal + 31;
+	/** @since 3.1 */
+	int NonStaticContextForEnumMemberType = Internal + 32;
+	/** @since 3.3 */
+	int TypeHidingType = TypeRelated + 33;
+
+	// variables
+	int UndefinedName = Internal + FieldRelated + 50;
+	int UninitializedLocalVariable = Internal + 51;
+	int VariableTypeCannotBeVoid = Internal + 52;
+	/** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
+	int VariableTypeCannotBeVoidArray = Internal + 53;
+	int CannotAllocateVoidArray = Internal + 54;
+	// local variables
+	int RedefinedLocal = Internal + 55;
+	int RedefinedArgument = Internal + 56;
+	// final local variables
+	int DuplicateFinalLocalInitialization = Internal + 57;
+	/** @since 2.1 */
+	int NonBlankFinalLocalAssignment = Internal + 58;
+	/** @since 3.2 */
+	int ParameterAssignment = Internal + 59;
+	int FinalOuterLocalAssignment = Internal + 60;
+	int LocalVariableIsNeverUsed = Internal + 61;
+	int ArgumentIsNeverUsed = Internal + 62;
+	int BytecodeExceeds64KLimit = Internal + 63;
+	int BytecodeExceeds64KLimitForClinit = Internal + 64;
+	int TooManyArgumentSlots = Internal + 65;
+	int TooManyLocalVariableSlots = Internal + 66;
+	/** @since 2.1 */
+	int TooManySyntheticArgumentSlots = Internal + 67;
+	/** @since 2.1 */
+	int TooManyArrayDimensions = Internal + 68;
+	/** @since 2.1 */
+	int BytecodeExceeds64KLimitForConstructor = Internal + 69;
+
+	// fields
+	int UndefinedField = FieldRelated + 70;
+	int NotVisibleField = FieldRelated + 71;
+	int AmbiguousField = FieldRelated + 72;
+	int UsingDeprecatedField = FieldRelated + 73;
+	int NonStaticFieldFromStaticInvocation = FieldRelated + 74;
+	int ReferenceToForwardField = FieldRelated + Internal + 75;
+	/** @since 2.1 */
+	int NonStaticAccessToStaticField = Internal + FieldRelated + 76;
+	/** @since 2.1 */
+	int UnusedPrivateField = Internal + FieldRelated + 77;
+	/** @since 3.0 */
+	int IndirectAccessToStaticField = Internal + FieldRelated + 78;
+	/** @since 3.0 */
+	int UnqualifiedFieldAccess = Internal + FieldRelated + 79;
+	int FinalFieldAssignment = FieldRelated + 80;
+	int UninitializedBlankFinalField = FieldRelated + 81;
+	int DuplicateBlankFinalFieldInitialization = FieldRelated + 82;
+	/** @since 3.6 */
+	int UnresolvedVariable = FieldRelated + 83;
+	/** @since 3.9 BETA_JAVA8 */
+	int NonStaticOrAlienTypeReceiver = MethodRelated + 84;
+	// variable hiding
+	/** @since 3.0 */
+	int LocalVariableHidingLocalVariable = Internal + 90;
+	/** @since 3.0 */
+	int LocalVariableHidingField = Internal + FieldRelated + 91;
+	/** @since 3.0 */
+	int FieldHidingLocalVariable = Internal + FieldRelated + 92;
+	/** @since 3.0 */
+	int FieldHidingField = Internal + FieldRelated + 93;
+	/** @since 3.0 */
+	int ArgumentHidingLocalVariable = Internal + 94;
+	/** @since 3.0 */
+	int ArgumentHidingField = Internal + 95;
+	/** @since 3.1 */
+	int MissingSerialVersion = Internal + 96;
+	/** @since 3.9 BETA_JAVA8 */
+	int LambdaRedeclaresArgument = Internal + 97;
+	/** @since 3.9 BETA_JAVA8 */
+	int LambdaRedeclaresLocal = Internal + 98;
+	/** @since 3.9 BETA_JAVA8 */
+	int LambdaDescriptorMentionsUnmentionable = 99;
+
+	// methods
+	int UndefinedMethod = MethodRelated + 100;
+	int NotVisibleMethod = MethodRelated + 101;
+	int AmbiguousMethod = MethodRelated + 102;
+	int UsingDeprecatedMethod = MethodRelated + 103;
+	int DirectInvocationOfAbstractMethod = MethodRelated + 104;
+	int VoidMethodReturnsValue = MethodRelated + 105;
+	int MethodReturnsVoid = MethodRelated + 106;
+	int MethodRequiresBody = Internal + MethodRelated + 107;
+	int ShouldReturnValue = Internal + MethodRelated + 108;
+	int MethodButWithConstructorName = MethodRelated + 110;
+	int MissingReturnType = TypeRelated + 111;
+	int BodyForNativeMethod = Internal + MethodRelated + 112;
+	int BodyForAbstractMethod = Internal + MethodRelated + 113;
+	int NoMessageSendOnBaseType = MethodRelated + 114;
+	int ParameterMismatch = MethodRelated + 115;
+	int NoMessageSendOnArrayType = MethodRelated + 116;
+	/** @since 2.1 */
+    int NonStaticAccessToStaticMethod = Internal + MethodRelated + 117;
+	/** @since 2.1 */
+	int UnusedPrivateMethod = Internal + MethodRelated + 118;
+	/** @since 3.0 */
+	int IndirectAccessToStaticMethod = Internal + MethodRelated + 119;
+	/** @since 3.4 */
+	int MissingTypeInMethod = MethodRelated + 120;
+	/** @since 3.7 */
+	int MethodCanBeStatic = Internal + MethodRelated + 121;
+	/** @since 3.7 */
+	int MethodCanBePotentiallyStatic = Internal + MethodRelated + 122;
+	/** @since 3.9 BETA_JAVA8 */
+	int MethodReferenceSwingsBothWays = Internal + MethodRelated + 123;
+	/** @since 3.9 BETA_JAVA8 */
+	int StaticMethodShouldBeAccessedStatically = Internal + MethodRelated + 124;
+	/** @since 3.9 BETA_JAVA8 */
+	int InvalidArrayConstructorReference = Internal + MethodRelated + 125;
+	/** @since 3.9 BETA_JAVA8 */
+	int ConstructedArrayIncompatible = Internal + MethodRelated + 126;
+	/** @since 3.9 BETA_JAVA8 */
+	int DanglingReference = Internal + MethodRelated + 127;
+	/** @since 3.9 BETA_JAVA8 */
+	int IncompatibleMethodReference = Internal + MethodRelated + 128;
+
+	// constructors
+	/** @since 3.4 */
+	int MissingTypeInConstructor = ConstructorRelated + 129;
+	int UndefinedConstructor = ConstructorRelated + 130;
+	int NotVisibleConstructor = ConstructorRelated + 131;
+	int AmbiguousConstructor = ConstructorRelated + 132;
+	int UsingDeprecatedConstructor = ConstructorRelated + 133;
+	/** @since 2.1 */
+	int UnusedPrivateConstructor = Internal + MethodRelated + 134;
+	// explicit constructor calls
+	int InstanceFieldDuringConstructorInvocation = ConstructorRelated + 135;
+	int InstanceMethodDuringConstructorInvocation = ConstructorRelated + 136;
+	int RecursiveConstructorInvocation = ConstructorRelated + 137;
+	int ThisSuperDuringConstructorInvocation = ConstructorRelated + 138;
+	/** @since 3.0 */
+	int InvalidExplicitConstructorCall = ConstructorRelated + Syntax + 139;
+	// implicit constructor calls
+	int UndefinedConstructorInDefaultConstructor = ConstructorRelated + 140;
+	int NotVisibleConstructorInDefaultConstructor = ConstructorRelated + 141;
+	int AmbiguousConstructorInDefaultConstructor = ConstructorRelated + 142;
+	int UndefinedConstructorInImplicitConstructorCall = ConstructorRelated + 143;
+	int NotVisibleConstructorInImplicitConstructorCall = ConstructorRelated + 144;
+	int AmbiguousConstructorInImplicitConstructorCall = ConstructorRelated + 145;
+	int UnhandledExceptionInDefaultConstructor = TypeRelated + 146;
+	int UnhandledExceptionInImplicitConstructorCall = TypeRelated + 147;
+
+	// expressions
+	/** @since 3.6 */
+	int UnusedObjectAllocation = Internal + 148;
+	/** @since 3.5 */
+	int DeadCode = Internal + 149;
+	int ArrayReferenceRequired = Internal + 150;
+	int NoImplicitStringConversionForCharArrayExpression = Internal + 151;
+	// constant expressions
+	int StringConstantIsExceedingUtf8Limit = Internal + 152;
+	int NonConstantExpression = Internal + 153;
+	int NumericValueOutOfRange = Internal + 154;
+	// cast expressions
+	int IllegalCast = TypeRelated + 156;
+	// allocations
+	int InvalidClassInstantiation = TypeRelated + 157;
+	int CannotDefineDimensionExpressionsWithInit = Internal + 158;
+	int MustDefineEitherDimensionExpressionsOrInitializer = Internal + 159;
+	// operators
+	int InvalidOperator = Internal + 160;
+	// statements
+	int CodeCannotBeReached = Internal + 161;
+	int CannotReturnInInitializer = Internal + 162;
+	int InitializerMustCompleteNormally = Internal + 163;
+	// assert
+	int InvalidVoidExpression = Internal + 164;
+	// try
+	int MaskedCatch = TypeRelated + 165;
+	int DuplicateDefaultCase = Internal + 166;
+	int UnreachableCatch = TypeRelated + MethodRelated + 167;
+	int UnhandledException = TypeRelated + 168;
+	// switch
+	int IncorrectSwitchType = TypeRelated + 169;
+	int DuplicateCase = FieldRelated + 170;
+
+	// labelled
+	int DuplicateLabel = Internal + 171;
+	int InvalidBreak = Internal + 172;
+	int InvalidContinue = Internal + 173;
+	int UndefinedLabel = Internal + 174;
+	//synchronized
+	int InvalidTypeToSynchronized = Internal + 175;
+	int InvalidNullToSynchronized = Internal + 176;
+	// throw
+	int CannotThrowNull = Internal + 177;
+	// assignment
+	/** @since 2.1 */
+	int AssignmentHasNoEffect = Internal + 178;
+	/** @since 3.0 */
+	int PossibleAccidentalBooleanAssignment = Internal + 179;
+	/** @since 3.0 */
+	int SuperfluousSemicolon = Internal + 180;
+	/** @since 3.0 */
+	int UnnecessaryCast = Internal + TypeRelated + 181;
+	/** @deprecated - no longer generated, use {@link #UnnecessaryCast} instead
+	 *   @since 3.0 */
+	int UnnecessaryArgumentCast = Internal + TypeRelated + 182;
+	/** @since 3.0 */
+	int UnnecessaryInstanceof = Internal + TypeRelated + 183;
+	/** @since 3.0 */
+	int FinallyMustCompleteNormally = Internal + 184;
+	/** @since 3.0 */
+	int UnusedMethodDeclaredThrownException = Internal + 185;
+	/** @since 3.0 */
+	int UnusedConstructorDeclaredThrownException = Internal + 186;
+	/** @since 3.0 */
+	int InvalidCatchBlockSequence = Internal + TypeRelated + 187;
+	/** @since 3.0 */
+	int EmptyControlFlowStatement = Internal + TypeRelated + 188;
+	/** @since 3.0 */
+	int UnnecessaryElse = Internal + 189;
+
+	// inner emulation
+	int NeedToEmulateFieldReadAccess = FieldRelated + 190;
+	int NeedToEmulateFieldWriteAccess = FieldRelated + 191;
+	int NeedToEmulateMethodAccess = MethodRelated + 192;
+	int NeedToEmulateConstructorAccess = MethodRelated + 193;
+
+	/** @since 3.2 */
+	int FallthroughCase = Internal + 194;
+
+	//inherited name hides enclosing name (sort of ambiguous)
+	int InheritedMethodHidesEnclosingName = MethodRelated + 195;
+	int InheritedFieldHidesEnclosingName = FieldRelated + 196;
+	int InheritedTypeHidesEnclosingName = TypeRelated + 197;
+
+	/** @since 3.1 */
+	int IllegalUsageOfQualifiedTypeReference = Internal + Syntax + 198;
+
+	// miscellaneous
+	/** @since 3.2 */
+	int UnusedLabel = Internal + 199;
+	int ThisInStaticContext = Internal + 200;
+	int StaticMethodRequested = Internal + MethodRelated + 201;
+	int IllegalDimension = Internal + 202;
+	/** @deprecated - problem is no longer generated */
+	int InvalidTypeExpression = Internal + 203;
+	int ParsingError = Syntax + Internal + 204;
+	int ParsingErrorNoSuggestion = Syntax + Internal + 205;
+	int InvalidUnaryExpression = Syntax + Internal + 206;
+
+	// syntax errors
+	int InterfaceCannotHaveConstructors = Syntax + Internal + 207;
+	int ArrayConstantsOnlyInArrayInitializers = Syntax + Internal + 208;
+	int ParsingErrorOnKeyword = Syntax + Internal + 209;
+	int ParsingErrorOnKeywordNoSuggestion = Syntax + Internal + 210;
+
+	/** @since 3.5 */
+	int ComparingIdentical = Internal + 211;
+
+	int UnmatchedBracket = Syntax + Internal + 220;
+	int NoFieldOnBaseType = FieldRelated + 221;
+	int InvalidExpressionAsStatement = Syntax + Internal + 222;
+	/** @since 2.1 */
+	int ExpressionShouldBeAVariable = Syntax + Internal + 223;
+	/** @since 2.1 */
+	int MissingSemiColon = Syntax + Internal + 224;
+	/** @since 2.1 */
+	int InvalidParenthesizedExpression = Syntax + Internal + 225;
+
+	/** @since 3.0 */
+	int ParsingErrorInsertTokenBefore = Syntax + Internal + 230;
+	/** @since 3.0 */
+	int ParsingErrorInsertTokenAfter = Syntax + Internal + 231;
+	/** @since 3.0 */
+    int ParsingErrorDeleteToken = Syntax + Internal + 232;
+    /** @since 3.0 */
+    int ParsingErrorDeleteTokens = Syntax + Internal + 233;
+    /** @since 3.0 */
+    int ParsingErrorMergeTokens = Syntax + Internal + 234;
+    /** @since 3.0 */
+    int ParsingErrorInvalidToken = Syntax + Internal + 235;
+    /** @since 3.0 */
+    int ParsingErrorMisplacedConstruct = Syntax + Internal + 236;
+    /** @since 3.0 */
+    int ParsingErrorReplaceTokens = Syntax + Internal + 237;
+    /** @since 3.0 */
+    int ParsingErrorNoSuggestionForTokens = Syntax + Internal + 238;
+    /** @since 3.0 */
+    int ParsingErrorUnexpectedEOF = Syntax + Internal + 239;
+    /** @since 3.0 */
+    int ParsingErrorInsertToComplete = Syntax + Internal + 240;
+    /** @since 3.0 */
+    int ParsingErrorInsertToCompleteScope = Syntax + Internal + 241;
+    /** @since 3.0 */
+    int ParsingErrorInsertToCompletePhrase = Syntax + Internal + 242;
+
+	// scanner errors
+	int EndOfSource = Syntax + Internal + 250;
+	int InvalidHexa = Syntax + Internal + 251;
+	int InvalidOctal = Syntax + Internal + 252;
+	int InvalidCharacterConstant = Syntax + Internal + 253;
+	int InvalidEscape = Syntax + Internal + 254;
+	int InvalidInput = Syntax + Internal + 255;
+	int InvalidUnicodeEscape = Syntax + Internal + 256;
+	int InvalidFloat = Syntax + Internal + 257;
+	int NullSourceString = Syntax + Internal + 258;
+	int UnterminatedString = Syntax + Internal + 259;
+	int UnterminatedComment = Syntax + Internal + 260;
+	int NonExternalizedStringLiteral = Internal + 261;
+	/** @since 3.1 */
+	int InvalidDigit = Syntax + Internal + 262;
+	/** @since 3.1 */
+	int InvalidLowSurrogate = Syntax + Internal + 263;
+	/** @since 3.1 */
+	int InvalidHighSurrogate = Syntax + Internal + 264;
+	/** @since 3.2 */
+	int UnnecessaryNLSTag = Internal + 265;
+	/** @since 3.7.1 */
+	int InvalidBinary = Syntax + Internal + 266;
+	/** @since 3.7.1 */
+	int BinaryLiteralNotBelow17 = Syntax + Internal + 267;
+	/** @since 3.7.1 */
+	int IllegalUnderscorePosition = Syntax + Internal + 268;
+	/** @since 3.7.1 */
+	int UnderscoresInLiteralsNotBelow17 = Syntax + Internal + 269;
+	/** @since 3.7.1 */
+	int IllegalHexaLiteral = Syntax + Internal + 270;
+
+	// type related problems
+	/** @since 3.1 */
+	int DiscouragedReference = TypeRelated + 280;
+
+	int InterfaceCannotHaveInitializers = TypeRelated + 300;
+	int DuplicateModifierForType = TypeRelated + 301;
+	int IllegalModifierForClass = TypeRelated + 302;
+	int IllegalModifierForInterface = TypeRelated + 303;
+	int IllegalModifierForMemberClass = TypeRelated + 304;
+	int IllegalModifierForMemberInterface = TypeRelated + 305;
+	int IllegalModifierForLocalClass = TypeRelated + 306;
+	/** @since 3.1 */
+	int ForbiddenReference = TypeRelated + 307;
+	int IllegalModifierCombinationFinalAbstractForClass = TypeRelated + 308;
+	int IllegalVisibilityModifierForInterfaceMemberType = TypeRelated + 309;
+	int IllegalVisibilityModifierCombinationForMemberType = TypeRelated + 310;
+	int IllegalStaticModifierForMemberType = TypeRelated + 311;
+	int SuperclassMustBeAClass = TypeRelated + 312;
+	int ClassExtendFinalClass = TypeRelated + 313;
+	int DuplicateSuperInterface = TypeRelated + 314;
+	int SuperInterfaceMustBeAnInterface = TypeRelated + 315;
+	int HierarchyCircularitySelfReference = TypeRelated + 316;
+	int HierarchyCircularity = TypeRelated + 317;
+	int HidingEnclosingType = TypeRelated + 318;
+	int DuplicateNestedType = TypeRelated + 319;
+	int CannotThrowType = TypeRelated + 320;
+	int PackageCollidesWithType = TypeRelated + 321;
+	int TypeCollidesWithPackage = TypeRelated + 322;
+	int DuplicateTypes = TypeRelated + 323;
+	int IsClassPathCorrect = TypeRelated + 324;
+	int PublicClassMustMatchFileName = TypeRelated + 325;
+	/** @deprecated - problem is no longer generated */
+	int MustSpecifyPackage = Internal + 326;
+	int HierarchyHasProblems = TypeRelated + 327;
+	int PackageIsNotExpectedPackage = Internal + 328;
+	/** @since 2.1 */
+	int ObjectCannotHaveSuperTypes = Internal + 329;
+	/** @since 3.1 */
+	int ObjectMustBeClass = Internal + 330;
+	/** @since 3.4 */
+	int RedundantSuperinterface = TypeRelated + 331;
+	/** @since 3.5 */
+	int ShouldImplementHashcode = TypeRelated + 332;
+	/** @since 3.5 */
+	int AbstractMethodsInConcreteClass = TypeRelated + 333;
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int SuperclassNotFound =  TypeRelated + 329 + ProblemReasons.NotFound; // TypeRelated + 330
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int SuperclassNotVisible =  TypeRelated + 329 + ProblemReasons.NotVisible; // TypeRelated + 331
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int SuperclassAmbiguous =  TypeRelated + 329 + ProblemReasons.Ambiguous; // TypeRelated + 332
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int SuperclassInternalNameProvided =  TypeRelated + 329 + ProblemReasons.InternalNameProvided; // TypeRelated + 333
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int SuperclassInheritedNameHidesEnclosingName =  TypeRelated + 329 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 334
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int InterfaceNotFound =  TypeRelated + 334 + ProblemReasons.NotFound; // TypeRelated + 335
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int InterfaceNotVisible =  TypeRelated + 334 + ProblemReasons.NotVisible; // TypeRelated + 336
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int InterfaceAmbiguous =  TypeRelated + 334 + ProblemReasons.Ambiguous; // TypeRelated + 337
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int InterfaceInternalNameProvided =  TypeRelated + 334 + ProblemReasons.InternalNameProvided; // TypeRelated + 338
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int InterfaceInheritedNameHidesEnclosingName =  TypeRelated + 334 + ProblemReasons.InheritedNameHidesEnclosingName; // TypeRelated + 339
+
+	// field related problems
+	int DuplicateField = FieldRelated + 340;
+	int DuplicateModifierForField = FieldRelated + 341;
+	int IllegalModifierForField = FieldRelated + 342;
+	int IllegalModifierForInterfaceField = FieldRelated + 343;
+	int IllegalVisibilityModifierCombinationForField = FieldRelated + 344;
+	int IllegalModifierCombinationFinalVolatileForField = FieldRelated + 345;
+	int UnexpectedStaticModifierForField = FieldRelated + 346;
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int FieldTypeNotFound =  FieldRelated + 349 + ProblemReasons.NotFound; // FieldRelated + 350
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int FieldTypeNotVisible =  FieldRelated + 349 + ProblemReasons.NotVisible; // FieldRelated + 351
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int FieldTypeAmbiguous =  FieldRelated + 349 + ProblemReasons.Ambiguous; // FieldRelated + 352
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int FieldTypeInternalNameProvided =  FieldRelated + 349 + ProblemReasons.InternalNameProvided; // FieldRelated + 353
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int FieldTypeInheritedNameHidesEnclosingName =  FieldRelated + 349 + ProblemReasons.InheritedNameHidesEnclosingName; // FieldRelated + 354
+
+	// method related problems
+	int DuplicateMethod = MethodRelated + 355;
+	int IllegalModifierForArgument = MethodRelated + 356;
+	int DuplicateModifierForMethod = MethodRelated + 357;
+	int IllegalModifierForMethod = MethodRelated + 358;
+	int IllegalModifierForInterfaceMethod = MethodRelated + 359;
+	int IllegalVisibilityModifierCombinationForMethod = MethodRelated + 360;
+	int UnexpectedStaticModifierForMethod = MethodRelated + 361;
+	int IllegalAbstractModifierCombinationForMethod = MethodRelated + 362;
+	int AbstractMethodInAbstractClass = MethodRelated + 363;
+	int ArgumentTypeCannotBeVoid = MethodRelated + 364;
+	/** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
+	int ArgumentTypeCannotBeVoidArray = MethodRelated + 365;
+	/** @deprecated - problem is no longer generated, use {@link #CannotAllocateVoidArray} instead */
+	int ReturnTypeCannotBeVoidArray = MethodRelated + 366;
+	int NativeMethodsCannotBeStrictfp = MethodRelated + 367;
+	int DuplicateModifierForArgument = MethodRelated + 368;
+	/** @since 3.5 */
+	int IllegalModifierForConstructor = MethodRelated + 369;
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int ArgumentTypeNotFound =  MethodRelated + 369 + ProblemReasons.NotFound; // MethodRelated + 370
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int ArgumentTypeNotVisible =  MethodRelated + 369 + ProblemReasons.NotVisible; // MethodRelated + 371
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int ArgumentTypeAmbiguous =  MethodRelated + 369 + ProblemReasons.Ambiguous; // MethodRelated + 372
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int ArgumentTypeInternalNameProvided =  MethodRelated + 369 + ProblemReasons.InternalNameProvided; // MethodRelated + 373
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int ArgumentTypeInheritedNameHidesEnclosingName =  MethodRelated + 369 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 374
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int ExceptionTypeNotFound =  MethodRelated + 374 + ProblemReasons.NotFound; // MethodRelated + 375
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int ExceptionTypeNotVisible =  MethodRelated + 374 + ProblemReasons.NotVisible; // MethodRelated + 376
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int ExceptionTypeAmbiguous =  MethodRelated + 374 + ProblemReasons.Ambiguous; // MethodRelated + 377
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int ExceptionTypeInternalNameProvided =  MethodRelated + 374 + ProblemReasons.InternalNameProvided; // MethodRelated + 378
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int ExceptionTypeInheritedNameHidesEnclosingName =  MethodRelated + 374 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 379
+
+	/** @deprecated - problem is no longer generated, use {@link #UndefinedType} instead */
+	int ReturnTypeNotFound =  MethodRelated + 379 + ProblemReasons.NotFound; // MethodRelated + 380
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int ReturnTypeNotVisible =  MethodRelated + 379 + ProblemReasons.NotVisible; // MethodRelated + 381
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int ReturnTypeAmbiguous =  MethodRelated + 379 + ProblemReasons.Ambiguous; // MethodRelated + 382
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int ReturnTypeInternalNameProvided =  MethodRelated + 379 + ProblemReasons.InternalNameProvided; // MethodRelated + 383
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int ReturnTypeInheritedNameHidesEnclosingName =  MethodRelated + 379 + ProblemReasons.InheritedNameHidesEnclosingName; // MethodRelated + 384
+
+	// import related problems
+	int ConflictingImport = ImportRelated + 385;
+	int DuplicateImport = ImportRelated + 386;
+	int CannotImportPackage = ImportRelated + 387;
+	int UnusedImport = ImportRelated + 388;
+
+	int ImportNotFound =  ImportRelated + 389 + ProblemReasons.NotFound; // ImportRelated + 390
+	/** @deprecated - problem is no longer generated, use {@link #NotVisibleType} instead */
+	int ImportNotVisible =  ImportRelated + 389 + ProblemReasons.NotVisible; // ImportRelated + 391
+	/** @deprecated - problem is no longer generated, use {@link #AmbiguousType} instead */
+	int ImportAmbiguous =  ImportRelated + 389 + ProblemReasons.Ambiguous; // ImportRelated + 392
+	/** @deprecated - problem is no longer generated, use {@link #InternalTypeNameProvided} instead */
+	int ImportInternalNameProvided =  ImportRelated + 389 + ProblemReasons.InternalNameProvided; // ImportRelated + 393
+	/** @deprecated - problem is no longer generated, use {@link #InheritedTypeHidesEnclosingName} instead */
+	int ImportInheritedNameHidesEnclosingName =  ImportRelated + 389 + ProblemReasons.InheritedNameHidesEnclosingName; // ImportRelated + 394
+
+	/** @since 3.1 */
+	int InvalidTypeForStaticImport =  ImportRelated + 391;
+
+	// local variable related problems
+	int DuplicateModifierForVariable = MethodRelated + 395;
+	int IllegalModifierForVariable = MethodRelated + 396;
+	/** @deprecated - problem is no longer generated, use {@link #RedundantNullCheckOnNonNullLocalVariable} instead */
+	int LocalVariableCannotBeNull = Internal + 397; // since 3.3: semantics are LocalVariableRedundantCheckOnNonNull
+	/** @deprecated - problem is no longer generated, use {@link #NullLocalVariableReference}, {@link #RedundantNullCheckOnNullLocalVariable} or {@link #RedundantLocalVariableNullAssignment} instead */
+	int LocalVariableCanOnlyBeNull = Internal + 398; // since 3.3: split with LocalVariableRedundantCheckOnNull depending on context
+	/** @deprecated - problem is no longer generated, use {@link #PotentialNullLocalVariableReference} instead */
+	int LocalVariableMayBeNull = Internal + 399;
+
+	// method verifier problems
+	int AbstractMethodMustBeImplemented = MethodRelated + 400;
+	int FinalMethodCannotBeOverridden = MethodRelated + 401;
+	int IncompatibleExceptionInThrowsClause = MethodRelated + 402;
+	int IncompatibleExceptionInInheritedMethodThrowsClause = MethodRelated + 403;
+	int IncompatibleReturnType = MethodRelated + 404;
+	int InheritedMethodReducesVisibility = MethodRelated + 405;
+	int CannotOverrideAStaticMethodWithAnInstanceMethod = MethodRelated + 406;
+	int CannotHideAnInstanceMethodWithAStaticMethod = MethodRelated + 407;
+	int StaticInheritedMethodConflicts = MethodRelated + 408;
+	int MethodReducesVisibility = MethodRelated + 409;
+	int OverridingNonVisibleMethod = MethodRelated + 410;
+	int AbstractMethodCannotBeOverridden = MethodRelated + 411;
+	int OverridingDeprecatedMethod = MethodRelated + 412;
+	/** @since 2.1 */
+	int IncompatibleReturnTypeForNonInheritedInterfaceMethod = MethodRelated + 413;
+	/** @since 2.1 */
+	int IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod = MethodRelated + 414;
+	/** @since 3.1 */
+	int IllegalVararg = MethodRelated + 415;
+	/** @since 3.3 */
+	int OverridingMethodWithoutSuperInvocation = MethodRelated + 416;
+	/** @since 3.5 */
+	int MissingSynchronizedModifierInInheritedMethod= MethodRelated + 417;
+	/** @since 3.5 */
+	int AbstractMethodMustBeImplementedOverConcreteMethod = MethodRelated + 418;
+	/** @since 3.5 */
+	int InheritedIncompatibleReturnType = MethodRelated + 419;
+
+	// code snippet support
+	int CodeSnippetMissingClass = Internal + 420;
+	int CodeSnippetMissingMethod = Internal + 421;
+	int CannotUseSuperInCodeSnippet = Internal + 422;
+
+	//constant pool
+	int TooManyConstantsInConstantPool = Internal + 430;
+	/** @since 2.1 */
+	int TooManyBytesForStringConstant = Internal + 431;
+
+	// static constraints
+	/** @since 2.1 */
+	int TooManyFields = Internal + 432;
+	/** @since 2.1 */
+	int TooManyMethods = Internal + 433;
+	/** @since 3.7 */
+	int TooManyParametersForSyntheticMethod = Internal + 434;
+
+	// 1.4 features
+	// assertion warning
+	int UseAssertAsAnIdentifier = Internal + 440;
+
+	// 1.5 features
+	int UseEnumAsAnIdentifier = Internal + 441;
+	/** @since 3.2 */
+	int EnumConstantsCannotBeSurroundedByParenthesis = Syntax + Internal + 442;
+
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalUseOfUnderscoreAsAnIdentifier = Syntax + Internal + 443;
+	// detected task
+	/** @since 2.1 */
+	int Task = Internal + 450;
+
+	// local variables related problems, cont'd
+	/** @since 3.3 */
+	int NullLocalVariableReference = Internal + 451;
+	/** @since 3.3 */
+	int PotentialNullLocalVariableReference = Internal + 452;
+	/** @since 3.3 */
+	int RedundantNullCheckOnNullLocalVariable = Internal + 453;
+	/** @since 3.3 */
+	int NullLocalVariableComparisonYieldsFalse = Internal + 454;
+	/** @since 3.3 */
+	int RedundantLocalVariableNullAssignment = Internal + 455;
+	/** @since 3.3 */
+	int NullLocalVariableInstanceofYieldsFalse = Internal + 456;
+	/** @since 3.3 */
+	int RedundantNullCheckOnNonNullLocalVariable = Internal + 457;
+	/** @since 3.3 */
+	int NonNullLocalVariableComparisonYieldsFalse = Internal + 458;
+	/** @since 3.9 */
+	int PotentialNullUnboxing = Internal + 459;
+	/** @since 3.9 */
+	int NullUnboxing = Internal + 461;
+
+	// block
+	/** @since 3.0 */
+	int UndocumentedEmptyBlock = Internal + 460;
+
+	/*
+	 * Javadoc comments
+	 */
+	/**
+	 * Problem signaled on an invalid URL reference.
+	 * Valid syntax example: @see "http://www.eclipse.org/"
+	 * @since 3.4
+	 */
+	int JavadocInvalidSeeUrlReference = Javadoc + Internal + 462;
+	/**
+	 * Problem warned on missing tag description.
+	 * @since 3.4
+	 */
+	int JavadocMissingTagDescription = Javadoc + Internal + 463;
+	/**
+	 * Problem warned on duplicated tag.
+	 * @since 3.3
+	 */
+	int JavadocDuplicateTag = Javadoc + Internal + 464;
+	/**
+	 * Problem signaled on an hidden reference due to a too low visibility level.
+	 * @since 3.3
+	 */
+	int JavadocHiddenReference = Javadoc + Internal + 465;
+	/**
+	 * Problem signaled on an invalid qualification for member type reference.
+	 * @since 3.3
+	 */
+	int JavadocInvalidMemberTypeQualification = Javadoc + Internal + 466;
+	/** @since 3.2 */
+	int JavadocMissingIdentifier = Javadoc + Internal + 467;
+	/** @since 3.2 */
+	int JavadocNonStaticTypeFromStaticInvocation = Javadoc + Internal + 468;
+	/** @since 3.1 */
+	int JavadocInvalidParamTagTypeParameter = Javadoc + Internal + 469;
+	/** @since 3.0 */
+	int JavadocUnexpectedTag = Javadoc + Internal + 470;
+	/** @since 3.0 */
+	int JavadocMissingParamTag = Javadoc + Internal + 471;
+	/** @since 3.0 */
+	int JavadocMissingParamName = Javadoc + Internal + 472;
+	/** @since 3.0 */
+	int JavadocDuplicateParamName = Javadoc + Internal + 473;
+	/** @since 3.0 */
+	int JavadocInvalidParamName = Javadoc + Internal + 474;
+	/** @since 3.0 */
+	int JavadocMissingReturnTag = Javadoc + Internal + 475;
+	/** @since 3.0 */
+	int JavadocDuplicateReturnTag = Javadoc + Internal + 476;
+	/** @since 3.0 */
+	int JavadocMissingThrowsTag = Javadoc + Internal + 477;
+	/** @since 3.0 */
+	int JavadocMissingThrowsClassName = Javadoc + Internal + 478;
+	/** @since 3.0 */
+	int JavadocInvalidThrowsClass = Javadoc + Internal + 479;
+	/** @since 3.0 */
+	int JavadocDuplicateThrowsClassName = Javadoc + Internal + 480;
+	/** @since 3.0 */
+	int JavadocInvalidThrowsClassName = Javadoc + Internal + 481;
+	/** @since 3.0 */
+	int JavadocMissingSeeReference = Javadoc + Internal + 482;
+	/** @since 3.0 */
+	int JavadocInvalidSeeReference = Javadoc + Internal + 483;
+	/**
+	 * Problem signaled on an invalid URL reference that does not conform to the href syntax.
+	 * Valid syntax example: @see <a href="http://www.eclipse.org/">Eclipse Home Page</a>
+	 * @since 3.0
+	 */
+	int JavadocInvalidSeeHref = Javadoc + Internal + 484;
+	/** @since 3.0 */
+	int JavadocInvalidSeeArgs = Javadoc + Internal + 485;
+	/** @since 3.0 */
+	int JavadocMissing = Javadoc + Internal + 486;
+	/** @since 3.0 */
+	int JavadocInvalidTag = Javadoc + Internal + 487;
+	/*
+	 * ID for field errors in Javadoc
+	 */
+	/** @since 3.0 */
+	int JavadocUndefinedField = Javadoc + Internal + 488;
+	/** @since 3.0 */
+	int JavadocNotVisibleField = Javadoc + Internal + 489;
+	/** @since 3.0 */
+	int JavadocAmbiguousField = Javadoc + Internal + 490;
+	/** @since 3.0 */
+	int JavadocUsingDeprecatedField = Javadoc + Internal + 491;
+	/*
+	 * IDs for constructor errors in Javadoc
+	 */
+	/** @since 3.0 */
+	int JavadocUndefinedConstructor = Javadoc + Internal + 492;
+	/** @since 3.0 */
+	int JavadocNotVisibleConstructor = Javadoc + Internal + 493;
+	/** @since 3.0 */
+	int JavadocAmbiguousConstructor = Javadoc + Internal + 494;
+	/** @since 3.0 */
+	int JavadocUsingDeprecatedConstructor = Javadoc + Internal + 495;
+	/*
+	 * IDs for method errors in Javadoc
+	 */
+	/** @since 3.0 */
+	int JavadocUndefinedMethod = Javadoc + Internal + 496;
+	/** @since 3.0 */
+	int JavadocNotVisibleMethod = Javadoc + Internal + 497;
+	/** @since 3.0 */
+	int JavadocAmbiguousMethod = Javadoc + Internal + 498;
+	/** @since 3.0 */
+	int JavadocUsingDeprecatedMethod = Javadoc + Internal + 499;
+	/** @since 3.0 */
+	int JavadocNoMessageSendOnBaseType = Javadoc + Internal + 500;
+	/** @since 3.0 */
+	int JavadocParameterMismatch = Javadoc + Internal + 501;
+	/** @since 3.0 */
+	int JavadocNoMessageSendOnArrayType = Javadoc + Internal + 502;
+	/*
+	 * IDs for type errors in Javadoc
+	 */
+	/** @since 3.0 */
+	int JavadocUndefinedType = Javadoc + Internal + 503;
+	/** @since 3.0 */
+	int JavadocNotVisibleType = Javadoc + Internal + 504;
+	/** @since 3.0 */
+	int JavadocAmbiguousType = Javadoc + Internal + 505;
+	/** @since 3.0 */
+	int JavadocUsingDeprecatedType = Javadoc + Internal + 506;
+	/** @since 3.0 */
+	int JavadocInternalTypeNameProvided = Javadoc + Internal + 507;
+	/** @since 3.0 */
+	int JavadocInheritedMethodHidesEnclosingName = Javadoc + Internal + 508;
+	/** @since 3.0 */
+	int JavadocInheritedFieldHidesEnclosingName = Javadoc + Internal + 509;
+	/** @since 3.0 */
+	int JavadocInheritedNameHidesEnclosingTypeName = Javadoc + Internal + 510;
+	/** @since 3.0 */
+	int JavadocAmbiguousMethodReference = Javadoc + Internal + 511;
+	/** @since 3.0 */
+	int JavadocUnterminatedInlineTag = Javadoc + Internal + 512;
+	/** @since 3.0 */
+	int JavadocMalformedSeeReference = Javadoc + Internal + 513;
+	/** @since 3.0 */
+	int JavadocMessagePrefix = Internal + 514;
+
+	/** @since 3.1 */
+	int JavadocMissingHashCharacter = Javadoc + Internal + 515;
+	/** @since 3.1 */
+	int JavadocEmptyReturnTag = Javadoc + Internal + 516;
+	/** @since 3.1 */
+	int JavadocInvalidValueReference = Javadoc + Internal + 517;
+	/** @since 3.1 */
+	int JavadocUnexpectedText = Javadoc + Internal + 518;
+	/** @since 3.1 */
+	int JavadocInvalidParamTagName = Javadoc + Internal + 519;
+
+	/**
+	 * Generics
+	 */
+	/** @since 3.1 */
+	int DuplicateTypeVariable = Internal + 520;
+	/** @since 3.1 */
+	int IllegalTypeVariableSuperReference = Internal + 521;
+	/** @since 3.1 */
+	int NonStaticTypeFromStaticInvocation = Internal + 522;
+	/** @since 3.1 */
+	int ObjectCannotBeGeneric = Internal + 523;
+	/** @since 3.1 */
+	int NonGenericType = TypeRelated + 524;
+	/** @since 3.1 */
+	int IncorrectArityForParameterizedType = TypeRelated + 525;
+	/** @since 3.1 */
+	int TypeArgumentMismatch = TypeRelated + 526;
+	/** @since 3.1 */
+	int DuplicateMethodErasure = TypeRelated + 527;
+	/** @since 3.1 */
+	int ReferenceToForwardTypeVariable = TypeRelated + 528;
+    /** @since 3.1 */
+	int BoundMustBeAnInterface = TypeRelated + 529;
+    /** @since 3.1 */
+	int UnsafeRawConstructorInvocation = TypeRelated + 530;
+    /** @since 3.1 */
+	int UnsafeRawMethodInvocation = TypeRelated + 531;
+    /** @since 3.1 */
+	int UnsafeTypeConversion = TypeRelated + 532;
+    /** @since 3.1 */
+	int InvalidTypeVariableExceptionType = TypeRelated + 533;
+	/** @since 3.1 */
+	int InvalidParameterizedExceptionType = TypeRelated + 534;
+	/** @since 3.1 */
+	int IllegalGenericArray = TypeRelated + 535;
+	/** @since 3.1 */
+	int UnsafeRawFieldAssignment = TypeRelated + 536;
+	/** @since 3.1 */
+	int FinalBoundForTypeVariable = TypeRelated + 537;
+	/** @since 3.1 */
+	int UndefinedTypeVariable = Internal + 538;
+	/** @since 3.1 */
+	int SuperInterfacesCollide = TypeRelated + 539;
+	/** @since 3.1 */
+	int WildcardConstructorInvocation = TypeRelated + 540;
+	/** @since 3.1 */
+	int WildcardMethodInvocation = TypeRelated + 541;
+	/** @since 3.1 */
+	int WildcardFieldAssignment = TypeRelated + 542;
+	/** @since 3.1 */
+	int GenericMethodTypeArgumentMismatch = TypeRelated + 543;
+	/** @since 3.1 */
+	int GenericConstructorTypeArgumentMismatch = TypeRelated + 544;
+	/** @since 3.1 */
+	int UnsafeGenericCast = TypeRelated + 545;
+	/** @since 3.1 */
+	int IllegalInstanceofParameterizedType = Internal + 546;
+	/** @since 3.1 */
+	int IllegalInstanceofTypeParameter = Internal + 547;
+	/** @since 3.1 */
+	int NonGenericMethod = TypeRelated + 548;
+	/** @since 3.1 */
+	int IncorrectArityForParameterizedMethod = TypeRelated + 549;
+	/** @since 3.1 */
+	int ParameterizedMethodArgumentTypeMismatch = TypeRelated + 550;
+	/** @since 3.1 */
+	int NonGenericConstructor = TypeRelated + 551;
+	/** @since 3.1 */
+	int IncorrectArityForParameterizedConstructor = TypeRelated + 552;
+	/** @since 3.1 */
+	int ParameterizedConstructorArgumentTypeMismatch = TypeRelated + 553;
+	/** @since 3.1 */
+	int TypeArgumentsForRawGenericMethod = TypeRelated + 554;
+	/** @since 3.1 */
+	int TypeArgumentsForRawGenericConstructor = TypeRelated + 555;
+	/** @since 3.1 */
+	int SuperTypeUsingWildcard = TypeRelated + 556;
+	/** @since 3.1 */
+	int GenericTypeCannotExtendThrowable = TypeRelated + 557;
+	/** @since 3.1 */
+	int IllegalClassLiteralForTypeVariable = TypeRelated + 558;
+	/** @since 3.1 */
+	int UnsafeReturnTypeOverride = MethodRelated + 559;
+	/** @since 3.1 */
+	int MethodNameClash = MethodRelated + 560;
+	/** @since 3.1 */
+	int RawMemberTypeCannotBeParameterized = TypeRelated + 561;
+	/** @since 3.1 */
+	int MissingArgumentsForParameterizedMemberType = TypeRelated + 562;
+	/** @since 3.1 */
+	int StaticMemberOfParameterizedType = TypeRelated + 563;
+    /** @since 3.1 */
+	int BoundHasConflictingArguments = TypeRelated + 564;
+    /** @since 3.1 */
+	int DuplicateParameterizedMethods = MethodRelated + 565;
+	/** @since 3.1 */
+	int IllegalQualifiedParameterizedTypeAllocation = TypeRelated + 566;
+	/** @since 3.1 */
+	int DuplicateBounds = TypeRelated + 567;
+	/** @since 3.1 */
+	int BoundCannotBeArray = TypeRelated + 568;
+    /** @since 3.1 */
+	int UnsafeRawGenericConstructorInvocation = TypeRelated + 569;
+    /** @since 3.1 */
+	int UnsafeRawGenericMethodInvocation = TypeRelated + 570;
+	/** @since 3.1 */
+	int TypeParameterHidingType = TypeRelated + 571;
+	/** @since 3.2 */
+	int RawTypeReference = TypeRelated + 572;
+	/** @since 3.2 */
+	int NoAdditionalBoundAfterTypeVariable = TypeRelated + 573;
+	/** @since 3.2 */
+	int UnsafeGenericArrayForVarargs = MethodRelated + 574;
+	/** @since 3.2 */
+	int IllegalAccessFromTypeVariable = TypeRelated + 575;
+	/** @since 3.3 */
+	int TypeHidingTypeParameterFromType = TypeRelated + 576;
+	/** @since 3.3 */
+	int TypeHidingTypeParameterFromMethod = TypeRelated + 577;
+    /** @since 3.3 */
+    int InvalidUsageOfWildcard = Syntax + Internal + 578;
+    /** @since 3.4 */
+    int UnusedTypeArgumentsForMethodInvocation = MethodRelated + 579;
+
+	/**
+	 * Foreach
+	 */
+	/** @since 3.1 */
+	int IncompatibleTypesInForeach = TypeRelated + 580;
+	/** @since 3.1 */
+	int InvalidTypeForCollection = Internal + 581;
+	/** @since 3.6*/
+	int InvalidTypeForCollectionTarget14 = Internal + 582;
+
+	/** @since 3.7.1 */
+	int DuplicateInheritedMethods = MethodRelated + 583;
+	/** @since 3.8 */
+	int MethodNameClashHidden = MethodRelated + 584;
+
+	/** @since 3.9 */
+	int UnsafeElementTypeConversion = TypeRelated + 585;
+
+	/**
+	 * 1.5 Syntax errors (when source level < 1.5)
+	 */
+	/** @since 3.1 */
+    int InvalidUsageOfTypeParameters = Syntax + Internal + 590;
+    /** @since 3.1 */
+    int InvalidUsageOfStaticImports = Syntax + Internal + 591;
+    /** @since 3.1 */
+    int InvalidUsageOfForeachStatements = Syntax + Internal + 592;
+    /** @since 3.1 */
+    int InvalidUsageOfTypeArguments = Syntax + Internal + 593;
+    /** @since 3.1 */
+    int InvalidUsageOfEnumDeclarations = Syntax + Internal + 594;
+    /** @since 3.1 */
+    int InvalidUsageOfVarargs = Syntax + Internal + 595;
+    /** @since 3.1 */
+    int InvalidUsageOfAnnotations = Syntax + Internal + 596;
+    /** @since 3.1 */
+    int InvalidUsageOfAnnotationDeclarations = Syntax + Internal + 597;
+    /** @since 3.4 */
+    int InvalidUsageOfTypeParametersForAnnotationDeclaration = Syntax + Internal + 598;
+    /** @since 3.4 */
+    int InvalidUsageOfTypeParametersForEnumDeclaration = Syntax + Internal + 599;
+    /**
+     * Annotation
+     */
+	/** @since 3.1 */
+	int IllegalModifierForAnnotationMethod = MethodRelated + 600;
+    /** @since 3.1 */
+    int IllegalExtendedDimensions = MethodRelated + 601;
+    /** @since 3.1 */
+	int InvalidFileNameForPackageAnnotations = Syntax + Internal + 602;
+    /** @since 3.1 */
+	int IllegalModifierForAnnotationType = TypeRelated + 603;
+    /** @since 3.1 */
+	int IllegalModifierForAnnotationMemberType = TypeRelated + 604;
+    /** @since 3.1 */
+	int InvalidAnnotationMemberType = TypeRelated + 605;
+    /** @since 3.1 */
+	int AnnotationCircularitySelfReference = TypeRelated + 606;
+    /** @since 3.1 */
+	int AnnotationCircularity = TypeRelated + 607;
+	/** @since 3.1 */
+	int DuplicateAnnotation = TypeRelated + 608;
+	/** @since 3.1 */
+	int MissingValueForAnnotationMember = TypeRelated + 609;
+	/** @since 3.1 */
+	int DuplicateAnnotationMember = Internal + 610;
+	/** @since 3.1 */
+	int UndefinedAnnotationMember = MethodRelated + 611;
+	/** @since 3.1 */
+	int AnnotationValueMustBeClassLiteral = Internal + 612;
+	/** @since 3.1 */
+	int AnnotationValueMustBeConstant = Internal + 613;
+	/** @deprecated - problem is no longer generated (code is legite)
+	 *   @since 3.1 */
+	int AnnotationFieldNeedConstantInitialization = Internal + 614;
+	/** @since 3.1 */
+	int IllegalModifierForAnnotationField = Internal + 615;
+	/** @since 3.1 */
+	int AnnotationCannotOverrideMethod = MethodRelated + 616;
+	/** @since 3.1 */
+	int AnnotationMembersCannotHaveParameters = Syntax + Internal + 617;
+	/** @since 3.1 */
+	int AnnotationMembersCannotHaveTypeParameters = Syntax + Internal + 618;
+	/** @since 3.1 */
+	int AnnotationTypeDeclarationCannotHaveSuperclass = Syntax + Internal + 619;
+	/** @since 3.1 */
+	int AnnotationTypeDeclarationCannotHaveSuperinterfaces = Syntax + Internal + 620;
+	/** @since 3.1 */
+	int DuplicateTargetInTargetAnnotation = Internal + 621;
+	/** @since 3.1 */
+	int DisallowedTargetForAnnotation = TypeRelated + 622;
+	/** @since 3.1 */
+	int MethodMustOverride = MethodRelated + 623;
+	/** @since 3.1 */
+	int AnnotationTypeDeclarationCannotHaveConstructor = Syntax + Internal + 624;
+	/** @since 3.1 */
+	int AnnotationValueMustBeAnnotation = Internal + 625;
+	/** @since 3.1 */
+	int AnnotationTypeUsedAsSuperInterface = TypeRelated + 626;
+	/** @since 3.1 */
+	int MissingOverrideAnnotation = MethodRelated + 627;
+	/** @since 3.1 */
+	int FieldMissingDeprecatedAnnotation = Internal + 628;
+	/** @since 3.1 */
+	int MethodMissingDeprecatedAnnotation = Internal + 629;
+	/** @since 3.1 */
+	int TypeMissingDeprecatedAnnotation = Internal + 630;
+	/** @since 3.1 */
+	int UnhandledWarningToken = Internal + 631;
+	/** @since 3.2 */
+	int AnnotationValueMustBeArrayInitializer = Internal + 632;
+	/** @since 3.3 */
+	int AnnotationValueMustBeAnEnumConstant = Internal + 633;
+	/** @since 3.3 */
+	int MethodMustOverrideOrImplement = MethodRelated + 634;
+	/** @since 3.4 */
+	int UnusedWarningToken = Internal + 635;
+	/** @since 3.6 */
+	int MissingOverrideAnnotationForInterfaceMethodImplementation = MethodRelated + 636;
+	/** @since 3.9 BETA_JAVA8 */
+    int InvalidUsageOfTypeAnnotations = Syntax + Internal + 637;
+    /** @since 3.9 BETA_JAVA8 */
+    int DisallowedExplicitThisParameter = Syntax + Internal + 638;
+    /** @since 3.9 BETA_JAVA8 */
+    int MisplacedTypeAnnotations = Syntax + Internal + 639;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalTypeAnnotationsInStaticMemberAccess = Internal + Syntax + 640;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalUsageOfTypeAnnotations = Internal + Syntax + 641;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalDeclarationOfThisParameter = Internal + Syntax + 642;
+    /** @since 3.9 BETA_JAVA8 */
+    int ExplicitThisParameterNotBelow18 = Internal + Syntax + 643;
+    /** @since 3.9 BETA_JAVA8 */
+    int DefaultMethodNotBelow18 = Internal + Syntax + 644;
+    /** @since 3.9 BETA_JAVA8 */
+    int LambdaExpressionNotBelow18 = Internal + Syntax + 645;
+    /** @since 3.9 BETA_JAVA8 */
+    int MethodReferenceNotBelow18 = Internal + Syntax + 646;
+    /** @since 3.9 BETA_JAVA8 */
+    int ConstructorReferenceNotBelow18 = Internal + Syntax + 647;
+    /** @since 3.9 BETA_JAVA8 */
+    int ExplicitThisParameterNotInLambda = Internal + Syntax + 648;
+    /** @since 3.9 BETA_JAVA8 */
+    int ExplicitAnnotationTargetRequired = TypeRelated + 649;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalTypeForExplicitThis = Internal + Syntax + 650;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalQualifierForExplicitThis = Internal + Syntax + 651;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalQualifierForExplicitThis2 = Internal + Syntax + 652;
+    /** @since 3.9 BETA_JAVA8 */
+    int TargetTypeNotAFunctionalInterface = Internal + TypeRelated + 653;
+    /** @since 3.9 BETA_JAVA8 */
+    int IllegalVarargInLambda = Internal + TypeRelated + 654;
+    /** @since 3.9 BETA_JAVA8 */
+    int illFormedParameterizationOfFunctionalInterface = Internal + TypeRelated + 655;
+    /** @since 3.9 BETA_JAVA8 */
+    int lambdaSignatureMismatched = Internal + TypeRelated + 656;
+    /** @since 3.9 BETA_JAVA8 */
+    int lambdaParameterTypeMismatched = Internal + TypeRelated + 657;
+    /** @since 3.9 BETA_JAVA8 */
+    int IncompatibleLambdaParameterType = Internal + TypeRelated + 658;
+    /** @since 3.9 BETA_JAVA8 */
+    int NoGenericLambda = Internal + TypeRelated + 659;
+    /**
+	 * More problems in generics
+	 */
+    /** @since 3.4 */
+    int UnusedTypeArgumentsForConstructorInvocation = MethodRelated + 660;
+	/** @since 3.9 */
+	int UnusedTypeParameter = TypeRelated + 661;
+	/** @since 3.9 */
+	int IllegalArrayOfUnionType = TypeRelated + 662;
+	/** @since 3.9 BETA_JAVA8 */
+	int OuterLocalMustBeEffectivelyFinal = Internal + 663;
+	/** @since 3.9 BETA_JAVA8 */
+	int InterfaceNotFunctionalInterface = Internal + TypeRelated + 664;
+	/** @since 3.9 BETA_JAVA8 */
+	int ConstructionTypeMismatch = Internal + TypeRelated + 665;
+
+
+	/**
+	 * Null analysis for other kinds of expressions, syntactically nonnull
+	 */
+	/** @since 3.9 */
+	int NonNullExpressionComparisonYieldsFalse = Internal + 670;
+	/** @since 3.9 */
+	int RedundantNullCheckOnNonNullExpression = Internal + 671;
+	/** @since 3.9 */
+	int NullExpressionReference = Internal + 672;
+	/** @since 3.9 */
+	int PotentialNullExpressionReference = Internal + 673;
+
+	/**
+	 * Corrupted binaries
+	 */
+	/** @since 3.1 */
+	int CorruptedSignature = Internal + 700;
+	/**
+	 * Corrupted source
+	 */
+	/** @since 3.2 */
+	int InvalidEncoding = Internal + 701;
+	/** @since 3.2 */
+	int CannotReadSource = Internal + 702;
+
+	/**
+	 * Autoboxing
+	 */
+	/** @since 3.1 */
+	int BoxingConversion = Internal + 720;
+	/** @since 3.1 */
+	int UnboxingConversion = Internal + 721;
+
+	/**
+	 * Enum
+	 */
+	/** @since 3.1 */
+	int IllegalModifierForEnum = TypeRelated + 750;
+	/** @since 3.1 */
+	int IllegalModifierForEnumConstant = FieldRelated + 751;
+	/** @deprecated - problem could not be reported, enums cannot be local takes precedence 
+	 *   @since 3.1 */
+	int IllegalModifierForLocalEnum = TypeRelated + 752;
+	/** @since 3.1 */
+	int IllegalModifierForMemberEnum = TypeRelated + 753;
+	/** @since 3.1 */
+	int CannotDeclareEnumSpecialMethod = MethodRelated + 754;
+	/** @since 3.1 */
+	int IllegalQualifiedEnumConstantLabel = FieldRelated + 755;
+	/** @since 3.1 */
+	int CannotExtendEnum = TypeRelated + 756;
+	/** @since 3.1 */
+	int CannotInvokeSuperConstructorInEnum = MethodRelated + 757;
+	/** @since 3.1 */
+	int EnumAbstractMethodMustBeImplemented = MethodRelated + 758;
+	/** @since 3.1 */
+	int EnumSwitchCannotTargetField = FieldRelated + 759;
+	/** @since 3.1 */
+	int IllegalModifierForEnumConstructor = MethodRelated + 760;
+	/** @since 3.1 */
+	int MissingEnumConstantCase = FieldRelated + 761;
+	/** @since 3.2 */ // TODO need to fix 3.1.1 contribution (inline this constant on client side)
+	int EnumStaticFieldInInInitializerContext = FieldRelated + 762;
+	/** @since 3.4 */
+	int EnumConstantMustImplementAbstractMethod = MethodRelated + 763;
+	/** @since 3.5 */
+	int EnumConstantCannotDefineAbstractMethod = MethodRelated + 764;
+	/** @since 3.5 */
+	int AbstractMethodInEnum = MethodRelated + 765;
+	/** @since 3.8 */
+	int MissingEnumDefaultCase = Internal + 766;
+	/** @since 3.8 */
+	int MissingDefaultCase = Internal + 767;
+	/** @since 3.8 */
+	int MissingEnumConstantCaseDespiteDefault = FieldRelated + 768;
+	/** @since 3.8 */
+	int UninitializedLocalVariableHintMissingDefault = Internal + 769;
+	/** @since 3.8 */
+	int UninitializedBlankFinalFieldHintMissingDefault = FieldRelated + 770;
+	/** @since 3.8 */
+	int ShouldReturnValueHintMissingDefault = MethodRelated + 771;
+
+	/**
+	 * Var args
+	 */
+	/** @since 3.1 */
+	int IllegalExtendedDimensionsForVarArgs = Syntax + Internal + 800;
+	/** @since 3.1 */
+	int MethodVarargsArgumentNeedCast = MethodRelated + 801;
+	/** @since 3.1 */
+	int ConstructorVarargsArgumentNeedCast = ConstructorRelated + 802;
+	/** @since 3.1 */
+	int VarargsConflict = MethodRelated + 803;
+	/** @since 3.7.1 */
+	int SafeVarargsOnFixedArityMethod = MethodRelated + 804;
+	/** @since 3.7.1 */
+	int SafeVarargsOnNonFinalInstanceMethod = MethodRelated + 805;
+	/** @since 3.7.1 */
+	int PotentialHeapPollutionFromVararg = MethodRelated + 806;
+	/** @since 3.8 */
+	int VarargsElementTypeNotVisible = MethodRelated + 807;
+	/** @since 3.8 */
+	int VarargsElementTypeNotVisibleForConstructor = ConstructorRelated + 808;
+	/**
+	 * Javadoc Generic
+	 */
+	/** @since 3.1 */
+	int JavadocGenericMethodTypeArgumentMismatch = Javadoc + Internal + 850;
+	/** @since 3.1 */
+	int JavadocNonGenericMethod = Javadoc + Internal + 851;
+	/** @since 3.1 */
+	int JavadocIncorrectArityForParameterizedMethod = Javadoc + Internal + 852;
+	/** @since 3.1 */
+	int JavadocParameterizedMethodArgumentTypeMismatch = Javadoc + Internal + 853;
+	/** @since 3.1 */
+	int JavadocTypeArgumentsForRawGenericMethod = Javadoc + Internal + 854;
+	/** @since 3.1 */
+	int JavadocGenericConstructorTypeArgumentMismatch = Javadoc + Internal + 855;
+	/** @since 3.1 */
+	int JavadocNonGenericConstructor = Javadoc + Internal + 856;
+	/** @since 3.1 */
+	int JavadocIncorrectArityForParameterizedConstructor = Javadoc + Internal + 857;
+	/** @since 3.1 */
+	int JavadocParameterizedConstructorArgumentTypeMismatch = Javadoc + Internal + 858;
+	/** @since 3.1 */
+	int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
+
+	/**
+	 * Java 7 errors
+	 */
+	/** @since 3.7.1 */
+	int AssignmentToMultiCatchParameter = Internal + 870;
+	/** @since 3.7.1 */
+	int ResourceHasToImplementAutoCloseable = TypeRelated + 871;
+	/** @since 3.7.1 */
+	int AssignmentToResource = Internal + 872;
+	/** @since 3.7.1 */
+	int InvalidUnionTypeReferenceSequence = Internal + TypeRelated + 873; 
+	/** @since 3.7.1 */
+	int AutoManagedResourceNotBelow17 = Syntax + Internal + 874;
+	/** @since 3.7.1 */
+	int MultiCatchNotBelow17 =  Syntax + Internal + 875;
+	/** @since 3.7.1 */
+	int PolymorphicMethodNotBelow17 = MethodRelated + 876;
+	/** @since 3.7.1 */
+	int IncorrectSwitchType17 = TypeRelated + 877;
+	/** @since 3.7.1 */
+	int CannotInferElidedTypes = TypeRelated + 878;
+	/** @since 3.7.1 */
+	int CannotUseDiamondWithExplicitTypeArguments = TypeRelated + 879;
+	/** @since 3.7.1 */
+	int CannotUseDiamondWithAnonymousClasses = TypeRelated + 880;
+	/** @since 3.7.1 */
+	int SwitchOnStringsNotBelow17 = TypeRelated + 881;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348492
+	/** @since 3.7.1 */
+	int UnhandledExceptionOnAutoClose =  TypeRelated + 882;
+	/** @since 3.7.1 */
+	int DiamondNotBelow17 =  TypeRelated + 883;
+	/** @since 3.7.1 */
+	int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
+	/** @since 3.8 */
+	int PotentiallyUnclosedCloseable = Internal + 885;
+	/** @since 3.8 */
+	int PotentiallyUnclosedCloseableAtExit = Internal + 886;
+	/** @since 3.8 */
+	int UnclosedCloseable = Internal + 887;
+	/** @since 3.8 */
+	int UnclosedCloseableAtExit = Internal + 888;
+	/** @since 3.8 */
+	int ExplicitlyClosedAutoCloseable = Internal + 889;
+	/** @since 3.8 */
+	int SwitchOnEnumNotBelow15 = TypeRelated + 890;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317
+	/** @since 3.9 BETA_JAVA8 */
+	int IntersectionCastNotBelow18 = TypeRelated + 891;
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalBasetypeInIntersectionCast = TypeRelated + 892;
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalArrayTypeInIntersectionCast = TypeRelated + 893;
+	/** @since 3.9 BETA_JAVA8 */
+	int DuplicateBoundInIntersectionCast = TypeRelated + 894;
+	/** @since 3.9 BETA_JAVA8 */
+	int MultipleFunctionalInterfaces = TypeRelated + 895;
+	/** @since 3.9 BETA_JAVA8 */
+	int StaticInterfaceMethodNotBelow18 = Internal + Syntax + 896;
+	
+	/**
+	 * Errors/warnings from annotation based null analysis
+	 */
+	/** @since 3.8 */
+	int RequiredNonNullButProvidedNull = TypeRelated + 910;
+	/** @since 3.8 */
+	int RequiredNonNullButProvidedPotentialNull = TypeRelated + 911;
+	/** @since 3.8 */
+	int RequiredNonNullButProvidedUnknown = TypeRelated + 912;
+	/** @since 3.8 */
+	int MissingNonNullByDefaultAnnotationOnPackage = Internal + 913; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012
+	/** @since 3.8 */
+	int IllegalReturnNullityRedefinition = MethodRelated + 914;
+	/** @since 3.8 */
+	int IllegalRedefinitionToNonNullParameter = MethodRelated + 915;
+	/** @since 3.8 */
+	int IllegalDefinitionToNonNullParameter = MethodRelated + 916;
+	/** @since 3.8 */
+	int ParameterLackingNonNullAnnotation = MethodRelated + 917;
+	/** @since 3.8 */
+	int ParameterLackingNullableAnnotation = MethodRelated + 918;
+	/** @since 3.8 */
+	int PotentialNullMessageSendReference = Internal + 919;
+	/** @since 3.8 */
+	int RedundantNullCheckOnNonNullMessageSend = Internal + 920;
+	/** @since 3.8 */
+	int CannotImplementIncompatibleNullness = Internal + 921;
+	/** @since 3.8 */
+	int RedundantNullAnnotation = MethodRelated + 922;
+	/** @since 3.8 */
+	int IllegalAnnotationForBaseType = TypeRelated + 923;
+	/** @since 3.9 */
+	int NullableFieldReference = FieldRelated + 924;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotation = Internal + 925; // shouldn't actually occur any more after bug 366063
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationPackage = Internal + 926;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationType = Internal + 927;
+	/** @since 3.8 */
+	int RedundantNullDefaultAnnotationMethod = Internal + 928;
+	/** @since 3.8 */
+	int ContradictoryNullAnnotations = Internal + 929;
+	/** @since 3.8 */
+	int MissingNonNullByDefaultAnnotationOnType = Internal + 930; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012
+	/** @since 3.8 */
+	int RedundantNullCheckOnSpecdNonNullLocalVariable = Internal + 931;
+	/** @since 3.8 */
+	int SpecdNonNullLocalVariableComparisonYieldsFalse = Internal + 932;
+	/** @since 3.8 */
+	int RequiredNonNullButProvidedSpecdNullable = Internal + 933;
+	/** @since 3.9 */
+	int UninitializedNonNullField = FieldRelated + 934;
+	/** @since 3.9 */
+	int UninitializedNonNullFieldHintMissingDefault = FieldRelated + 935;
+	/** @since 3.9 */
+	int NonNullMessageSendComparisonYieldsFalse = Internal + 936;
+	/** @since 3.9 */
+	int RedundantNullCheckOnNonNullSpecdField = Internal + 937;
+	/** @since 3.9 */
+	int NonNullSpecdFieldComparisonYieldsFalse = Internal + 938;
+	/** @since 3.9 */
+	int ConflictingNullAnnotations = MethodRelated + 939;
+	/** @since 3.9 */
+	int ConflictingInheritedNullAnnotations = MethodRelated + 940;
+	
+	/** @since 3.9 BETA_JAVA8 */
+	int ArrayReferencePotentialNullReference = Internal + 951;
+	/** @since 3.9 BETA_JAVA8 */
+	int DereferencingNullableExpression = Internal + 952;
+	/** @since 3.9 BETA_JAVA8 */
+	int NullityMismatchingTypeAnnotation = Internal + 953;
+	/** @since 3.9 BETA_JAVA8 */
+	int NullityMismatchingTypeAnnotationUnchecked = Internal + 954;
+	/** @since 3.9 BETA_JAVA8 */
+	int ReferenceExpressionParameterMismatchPromisedNullable = MethodRelated + 955;
+	/** @since 3.9 BETA_JAVA8 */
+	int ReferenceExpressionParameterRequiredNonnullUnchecked = MethodRelated + 956;
+	/** @since 3.9 BETA_JAVA8 */
+	int ReferenceExpressionReturnNullRedef = MethodRelated + 957;
+	/** @since 3.9 BETA_JAVA8 */
+	int ReferenceExpressionReturnNullRedefUnchecked = MethodRelated + 958;
+
+	// Java 8 work
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalModifiersForElidedType = Internal + 1001;
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalModifiers = Internal + 1002;
+
+	// default methods:
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalModifierForInterfaceMethod18 = MethodRelated + 1050;
+
+	/** @since 3.9 BETA_JAVA8 */
+	int DefaultMethodOverridesObjectMethod = MethodRelated + 1051;
+	
+	/** @since 3.9 BETA_JAVA8 */
+	int InheritedDefaultMethodConflictsWithOtherInherited = MethodRelated + 1052;
+	
+	/** @since 3.9 BETA_JAVA8 */
+	int DuplicateInheritedDefaultMethods = MethodRelated + 1053;
+
+	/** @since 3.9 BETA_JAVA8 */
+	int SuperAccessCannotBypassDirectSuper = TypeRelated + 1054;
+	/** @since 3.9 BETA_JAVA8 */
+	int SuperCallCannotBypassOverride = MethodRelated + 1055;
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalModifierCombinationForInterfaceMethod = MethodRelated + 1056;
+	/** @since 3.9 BETA_JAVA8 */
+	int IllegalStrictfpForAbstractInterfaceMethod = MethodRelated + 1057;
+
+	/**
+	 * External problems -- These are problems defined by other plugins
+	 */
+
+	/** @since 3.2 */
+	int ExternalProblemNotFixable = 900;
+
+	// indicates an externally defined problem that has a quick-assist processor
+	// associated with it
+	/** @since 3.2 */
+	int ExternalProblemFixable = 901;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java
new file mode 100644
index 0000000..0b9f416
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+/**
+ * Exception thrown by a scanner when encountering lexical errors.
+ *
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class InvalidInputException extends Exception {
+
+	private static final long serialVersionUID = 2909732853499731592L; // backward compatible
+
+/**
+ * Creates a new exception with no detail message.
+ */
+public InvalidInputException() {
+	super();
+}
+
+/**
+ * Creates a new exception with the given detail message.
+ * @param message the detail message
+ */
+public InvalidInputException(String message) {
+	super(message);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/package.html b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/package.html
new file mode 100644
index 0000000..b039ea2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/package.html
@@ -0,0 +1,17 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+This package contains compiler associated infrastructure APIs.
+<h2>
+Package Specification</h2>
+
+<p><br>This package contains some compiler tooling APIs, allowing to perform operations at a lower-level 
+than using the JavaModel.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
new file mode 100644
index 0000000..faaa297
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
@@ -0,0 +1,1000 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+
+/**
+ * A visitor for iterating through the parse tree.
+ */
+public abstract class ASTVisitor {
+	public void acceptProblem(IProblem problem) {
+		// do nothing by default
+	}
+	public void endVisit(
+		AllocationExpression allocationExpression,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			AnnotationMethodDeclaration annotationTypeDeclaration,
+			ClassScope classScope) {
+			// do nothing by default
+	}
+	public void endVisit(Argument argument, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Argument argument,ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		ArrayAllocationExpression arrayAllocationExpression,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ArrayInitializer arrayInitializer, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ArrayReference arrayReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(AssertStatement assertStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Assignment assignment, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Block block, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(BreakStatement breakStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(CaseStatement caseStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(CastExpression castExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(CharLiteral charLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ClassLiteralAccess classLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Clinit clinit, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		CompilationUnitDeclaration compilationUnitDeclaration,
+		CompilationUnitScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(CompoundAssignment compoundAssignment, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			ConditionalExpression conditionalExpression,
+			BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		ConstructorDeclaration constructorDeclaration,
+		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ContinueStatement continueStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(DoStatement doStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(DoubleLiteral doubleLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(EmptyStatement emptyStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(EqualExpression equalExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		ExplicitConstructorCall explicitConstructor,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		ExtendedStringLiteral extendedStringLiteral,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(FalseLiteral falseLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(FieldReference fieldReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(FieldReference fieldReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(FloatLiteral floatLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ForeachStatement forStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ForStatement forStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(IfStatement ifStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ImportReference importRef, CompilationUnitScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Initializer initializer, MethodScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		InstanceOfExpression instanceOfExpression,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(IntLiteral intLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Javadoc javadoc, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Javadoc javadoc, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocAllocationExpression expression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocAllocationExpression expression, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArgumentExpression expression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArgumentExpression expression, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArrayQualifiedTypeReference typeRef, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArrayQualifiedTypeReference typeRef, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArraySingleTypeReference typeRef, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocArraySingleTypeReference typeRef, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocFieldReference fieldRef, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocFieldReference fieldRef, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocImplicitTypeReference implicitTypeReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocImplicitTypeReference implicitTypeReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocMessageSend messageSend, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocMessageSend messageSend, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocQualifiedTypeReference typeRef, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocQualifiedTypeReference typeRef, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocReturnStatement statement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocReturnStatement statement, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocSingleNameReference argument, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocSingleNameReference argument, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocSingleTypeReference typeRef, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(JavadocSingleTypeReference typeRef, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(LabeledStatement labeledStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(LocalDeclaration localDeclaration, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(LongLiteral longLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public void endVisit(MarkerAnnotation annotation, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 */
+	public void endVisit(MarkerAnnotation annotation, ClassScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param pair
+	 * @param scope
+	 */
+	public void endVisit(MemberValuePair pair, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param pair
+	 * @param scope
+	 */
+	public void endVisit(MemberValuePair pair, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(MessageSend messageSend, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(StringLiteralConcatenation literal, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public void endVisit(NormalAnnotation annotation, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(NormalAnnotation annotation, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(NullLiteral nullLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(PostfixExpression postfixExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(PrefixExpression prefixExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedAllocationExpression qualifiedAllocationExpression,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		QualifiedNameReference qualifiedNameReference,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			QualifiedNameReference qualifiedNameReference,
+			ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedSuperReference qualifiedSuperReference,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedSuperReference qualifiedSuperReference,
+    		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedThisReference qualifiedThisReference,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedThisReference qualifiedThisReference,
+    		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedTypeReference qualifiedTypeReference,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		QualifiedTypeReference qualifiedTypeReference,
+    		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ReturnStatement returnStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) {
+		// do nothing by default
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 */
+	public void endVisit(SingleMemberAnnotation annotation, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		SingleNameReference singleNameReference,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			SingleNameReference singleNameReference,
+			ClassScope scope) {
+			// do nothing by default
+	}
+	public void endVisit(
+    		SingleTypeReference singleTypeReference,
+    		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+    		SingleTypeReference singleTypeReference,
+    		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(StringLiteral stringLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(SuperReference superReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(SwitchStatement switchStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		SynchronizedStatement synchronizedStatement,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ThisReference thisReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ThisReference thisReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(TrueLiteral trueLiteral, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(TryStatement tryStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		TypeDeclaration localTypeDeclaration,
+		BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		TypeDeclaration memberTypeDeclaration,
+		ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+		TypeDeclaration typeDeclaration,
+		CompilationUnitScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(TypeParameter typeParameter, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(TypeParameter typeParameter, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			UnionTypeReference unionTypeReference,
+			BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			UnionTypeReference unionTypeReference,
+			ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(WhileStatement whileStatement, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Wildcard wildcard, BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(Wildcard wildcard, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(LambdaExpression lambdaExpression, BlockScope blockScope) {
+		// do nothing by default
+	}
+	public void endVisit(ReferenceExpression referenceExpression, BlockScope blockScope) {
+		// do nothing by default	
+	}
+	public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, ClassScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
+		// do nothing by default
+	}
+	public boolean visit(
+    		AllocationExpression allocationExpression,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			AnnotationMethodDeclaration annotationTypeDeclaration,
+			ClassScope classScope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Argument argument, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Argument argument, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ArrayAllocationExpression arrayAllocationExpression,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ArrayInitializer arrayInitializer, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ArrayReference arrayReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(AssertStatement assertStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Assignment assignment, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Block block, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(BreakStatement breakStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(CaseStatement caseStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(CastExpression castExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(CharLiteral charLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Clinit clinit, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		CompilationUnitDeclaration compilationUnitDeclaration,
+		CompilationUnitScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		ConditionalExpression conditionalExpression,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ConstructorDeclaration constructorDeclaration,
+		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ContinueStatement continueStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(DoStatement doStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(EmptyStatement emptyStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(EqualExpression equalExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ExplicitConstructorCall explicitConstructor,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		ExtendedStringLiteral extendedStringLiteral,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(FalseLiteral falseLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(FieldReference fieldReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(FieldReference fieldReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(FloatLiteral floatLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ForeachStatement forStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ForStatement forStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(IfStatement ifStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ImportReference importRef, CompilationUnitScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Initializer initializer, MethodScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		InstanceOfExpression instanceOfExpression,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(IntLiteral intLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Javadoc javadoc, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Javadoc javadoc, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocAllocationExpression expression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocAllocationExpression expression, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArgumentExpression expression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArgumentExpression expression, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArrayQualifiedTypeReference typeRef, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArrayQualifiedTypeReference typeRef, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArraySingleTypeReference typeRef, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocArraySingleTypeReference typeRef, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocFieldReference fieldRef, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocFieldReference fieldRef, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocImplicitTypeReference implicitTypeReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocImplicitTypeReference implicitTypeReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocMessageSend messageSend, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocMessageSend messageSend, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocQualifiedTypeReference typeRef, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocQualifiedTypeReference typeRef, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocReturnStatement statement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocReturnStatement statement, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocSingleNameReference argument, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocSingleNameReference argument, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocSingleTypeReference typeRef, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(JavadocSingleTypeReference typeRef, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(LabeledStatement labeledStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(LongLiteral longLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
+		return true;
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 */
+	public boolean visit(MarkerAnnotation annotation, ClassScope scope) {
+		return true;
+	}
+	/**
+	 * @param pair
+	 * @param scope
+	 * @since 3.1
+	 */
+	public boolean visit(MemberValuePair pair, BlockScope scope) {
+		return true;
+	}
+	/**
+	 * @param pair
+	 * @param scope
+	 */
+	public boolean visit(MemberValuePair pair, ClassScope scope) {
+		return true;
+	}
+	public boolean visit(MessageSend messageSend, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			StringLiteralConcatenation literal,
+			BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public boolean visit(NormalAnnotation annotation, BlockScope scope) {
+		return true;
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 */
+	public boolean visit(NormalAnnotation annotation, ClassScope scope) {
+		return true;
+	}
+	public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(PostfixExpression postfixExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		QualifiedAllocationExpression qualifiedAllocationExpression,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			QualifiedNameReference qualifiedNameReference,
+			BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			QualifiedNameReference qualifiedNameReference,
+			ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		QualifiedSuperReference qualifiedSuperReference,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		QualifiedSuperReference qualifiedSuperReference,
+    		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			QualifiedThisReference qualifiedThisReference,
+			BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			QualifiedThisReference qualifiedThisReference,
+			ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		QualifiedTypeReference qualifiedTypeReference,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		QualifiedTypeReference qualifiedTypeReference,
+    		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ReturnStatement returnStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 * @since 3.1
+	 */
+	public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
+		return true;
+	}
+	/**
+	 * @param annotation
+	 * @param scope
+	 */
+	public boolean visit(SingleMemberAnnotation annotation, ClassScope scope) {
+		return true;
+	}
+	public boolean visit(
+		SingleNameReference singleNameReference,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			SingleNameReference singleNameReference,
+			ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		SingleTypeReference singleTypeReference,
+    		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+    		SingleTypeReference singleTypeReference,
+    		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(SuperReference superReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(SwitchStatement switchStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		SynchronizedStatement synchronizedStatement,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ThisReference thisReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ThisReference thisReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ThrowStatement throwStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(TrueLiteral trueLiteral, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(TryStatement tryStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		TypeDeclaration localTypeDeclaration,
+		BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		TypeDeclaration memberTypeDeclaration,
+		ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+		TypeDeclaration typeDeclaration,
+		CompilationUnitScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(TypeParameter typeParameter, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(TypeParameter typeParameter, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			UnionTypeReference unionTypeReference,
+			BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			UnionTypeReference unionTypeReference,
+			ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(WhileStatement whileStatement, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Wildcard wildcard, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(Wildcard wildcard, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(LambdaExpression lambdaExpression, BlockScope blockScope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(ReferenceExpression referenceExpression, BlockScope blockScope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java
new file mode 100644
index 0000000..5c05f93
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/AbstractAnnotationProcessorManager.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     BEA - Patch for bug 172743
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.io.PrintWriter;
+
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+
+public abstract class AbstractAnnotationProcessorManager {
+	/**
+	 * Configure the receiver using the given batch compiler and the given options.
+	 * The parameter batchCompiler is expected to be an instance of the batch compiler. This method is
+	 * only used for the batch mode. For the IDE mode, please see {@link #configureFromPlatform(Compiler, Object, Object)}.
+	 *
+	 * @param batchCompiler the given batch compiler object
+	 * @param options the given options
+	 */
+	public abstract void configure(Object batchCompiler, String[] options);
+
+	/**
+	 * Configure the receiver using the given compiler, the given compilationUnitLocator and
+	 * the given java project.
+	 *
+	 * @param compiler the given compiler
+	 * @param compilationUnitLocator the given compilation unit locator
+	 * @param javaProject the given java project
+	 */
+	public abstract void configureFromPlatform(Compiler compiler, Object compilationUnitLocator, Object javaProject);
+
+	/**
+	 * Set the print writer for the standard output.
+	 *
+	 * @param out the given print writer for output
+	 */
+	public abstract void setOut(PrintWriter out);
+
+	/**
+	 * Set the print writer for the standard error.
+	 *
+	 * @param err the given print writer for error
+	 */
+	public abstract void setErr(PrintWriter err);
+
+	/**
+	 * Return the new units created in the last round.
+	 *
+	 * @return the new units created in the last round
+	 */
+	public abstract ICompilationUnit[] getNewUnits();
+
+	/**
+	 * Return the new binary bindings created in the last round.
+	 *
+	 * @return the new binary bindings created in the last round
+	 */
+	public abstract ReferenceBinding[] getNewClassFiles();
+
+	/**
+	 * Returns the deleted units.
+	 * @return the deleted units
+	 */
+	public abstract ICompilationUnit[] getDeletedUnits();
+
+	/**
+	 * Reinitialize the receiver
+	 */
+	public abstract void reset();
+
+	/**
+	 * Run a new annotation processing round on the given values.
+	 *
+	 * @param units the given source type
+	 * @param referenceBindings the given binary types
+	 * @param isLastRound flag to notify the last round
+	 */
+	public abstract void processAnnotations(CompilationUnitDeclaration[] units, ReferenceBinding[] referenceBindings, boolean isLastRound);
+
+	/**
+	 * Set the processors for annotation processing.
+	 *
+	 * @param processors the given processors
+	 */
+	public abstract void setProcessors(Object[] processors);
+}
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
new file mode 100644
index 0000000..b3547fb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -0,0 +1,6379 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
+import org.eclipse.jdt.internal.compiler.codegen.MultiCatchExceptionLabel;
+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.TypeAnnotationCodeStream;
+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;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Represents a class file wrapper on bytes, it is aware of its actual
+ * type name.
+ *
+ * Public APIs are listed below:
+ *
+ * byte[] getBytes();
+ *		Answer the actual bytes of the class file
+ *
+ * char[][] getCompoundName();
+ * 		Answer the compound name of the class file.
+ * 		For example, {{java}, {util}, {Hashtable}}.
+ *
+ * byte[] getReducedBytes();
+ * 		Answer a smaller byte format, which is only contains some structural
+ *      information. Those bytes are decodable with a regular class file reader,
+ *      such as DietClassFileReader
+ */
+public class ClassFile implements TypeConstants, TypeIds {
+
+	private byte[] bytes;
+	public CodeStream codeStream;
+	public ConstantPool constantPool;
+
+	public int constantPoolOffset;
+
+	// the header contains all the bytes till the end of the constant pool
+	public byte[] contents;
+
+	public int contentsOffset;
+
+	protected boolean creatingProblemType;
+
+	public ClassFile enclosingClassFile;
+	public byte[] header;
+	// that collection contains all the remaining bytes of the .class file
+	public int headerOffset;
+	public Set innerClassesBindings;
+	public List bootstrapMethods = null;
+	public int methodCount;
+	public int methodCountOffset;
+	// pool managment
+	boolean isShared = false;
+	// used to generate private access methods
+	// debug and stack map attributes
+	public int produceAttributes;
+	public SourceTypeBinding referenceBinding;
+	public boolean isNestedType;
+	public long targetJDK;
+
+	public List missingTypes = null;
+
+	public Set visitedTypes;
+
+	public static final int INITIAL_CONTENTS_SIZE = 400;
+	public static final int INITIAL_HEADER_SIZE = 1500;
+	public static final int INNER_CLASSES_SIZE = 5;
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Request the creation of a ClassFile compatible representation of a problematic type
+	 *
+	 * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
+	 * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
+	 */
+	public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
+		SourceTypeBinding typeBinding = typeDeclaration.binding;
+		ClassFile classFile = ClassFile.getNewInstance(typeBinding);
+		classFile.initialize(typeBinding, null, true);
+
+		if (typeBinding.hasMemberTypes()) {
+			// see bug 180109
+			ReferenceBinding[] members = typeBinding.memberTypes;
+			for (int i = 0, l = members.length; i < l; i++)
+				classFile.recordInnerClasses(members[i]);
+		}
+		// TODO (olivier) handle cases where a field cannot be generated (name too long)
+		// TODO (olivier) handle too many methods
+		// inner attributes
+		if (typeBinding.isNestedType()) {
+			classFile.recordInnerClasses(typeBinding);
+		}
+		TypeVariableBinding[] typeVariables = typeBinding.typeVariables();
+		for (int i = 0, max = typeVariables.length; i < max; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariables[i];
+			if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				Util.recordNestedType(classFile, typeVariableBinding);
+			}
+		}
+		// add its fields
+		FieldBinding[] fields = typeBinding.fields();
+		if ((fields != null) && (fields != Binding.NO_FIELDS)) {
+			classFile.addFieldInfos();
+		} else {
+			// we have to set the number of fields to be equals to 0
+			classFile.contents[classFile.contentsOffset++] = 0;
+			classFile.contents[classFile.contentsOffset++] = 0;
+		}
+		// leave some space for the methodCount
+		classFile.setForMethodInfos();
+		// add its user defined methods
+		int problemsLength;
+		CategorizedProblem[] problems = unitResult.getErrors();
+		if (problems == null) {
+			problems = new CategorizedProblem[0];
+		}
+		CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+
+		AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
+		if (methodDecls != null) {
+			if (typeBinding.isInterface()) {
+				// we cannot create problem methods for an interface. So we have to generate a clinit
+				// which should contain all the problem
+				classFile.addProblemClinit(problemsCopy);
+				for (int i = 0, length = methodDecls.length; i < length; i++) {
+					AbstractMethodDeclaration methodDecl = methodDecls[i];
+					MethodBinding method = methodDecl.binding;
+					if (method == null || method.isConstructor()) continue;
+					method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
+					classFile.addAbstractMethod(methodDecl, method);
+				}
+			} else {
+				for (int i = 0, length = methodDecls.length; i < length; i++) {
+					AbstractMethodDeclaration methodDecl = methodDecls[i];
+					MethodBinding method = methodDecl.binding;
+					if (method == null) continue;
+					if (method.isConstructor()) {
+						classFile.addProblemConstructor(methodDecl, method, problemsCopy);
+					} else if (method.isAbstract()) {
+						classFile.addAbstractMethod(methodDecl, method);
+					} else {
+						classFile.addProblemMethod(methodDecl, method, problemsCopy);
+					}
+				}
+			}
+			// add abstract methods
+			classFile.addDefaultAbstractMethods();
+		}
+
+		// propagate generation of (problem) member types
+		if (typeDeclaration.memberTypes != null) {
+			for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
+				TypeDeclaration memberType = typeDeclaration.memberTypes[i];
+				if (memberType.binding != null) {
+					ClassFile.createProblemType(memberType, unitResult);
+				}
+			}
+		}
+		classFile.addAttributes();
+		unitResult.record(typeBinding.constantPoolName(), classFile);
+	}
+	public static ClassFile getNewInstance(SourceTypeBinding typeBinding) {
+		LookupEnvironment env = typeBinding.scope.environment();
+		return env.classFilePool.acquire(typeBinding);
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods creates a new instance of the receiver.
+	 */
+	protected ClassFile() {
+		// default constructor for subclasses
+	}
+
+	public ClassFile(SourceTypeBinding typeBinding) {
+		// default constructor for subclasses
+		this.constantPool = new ConstantPool(this);
+		final CompilerOptions options = typeBinding.scope.compilerOptions();
+		this.targetJDK = options.targetJDK;
+		this.produceAttributes = options.produceDebugAttributes;
+		this.referenceBinding = typeBinding;
+		this.isNestedType = typeBinding.isNestedType();
+		if (this.targetJDK >= ClassFileConstants.JDK1_6) {
+			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
+			if (this.targetJDK >= ClassFileConstants.JDK1_8) {
+				this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
+				this.codeStream = new TypeAnnotationCodeStream(this);
+			} else {
+				this.codeStream = new StackMapFrameCodeStream(this);
+			}
+		} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
+			this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
+			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
+			this.codeStream = new StackMapFrameCodeStream(this);
+		} else {
+			this.codeStream = new CodeStream(this);
+		}
+		initByteArrays();
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem method info that correspond to a bogus method.
+	 *
+	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
+	 */
+	public void addAbstractMethod(
+			AbstractMethodDeclaration method,
+			MethodBinding methodBinding) {
+
+		this.generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		int attributeNumber = this.generateMethodInfoAttributes(methodBinding);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods generate all the attributes for the receiver.
+	 * For a class they could be:
+	 * - source file attribute
+	 * - inner classes attribute
+	 * - deprecated attribute
+	 */
+	public void addAttributes() {
+		// update the method count
+		this.contents[this.methodCountOffset++] = (byte) (this.methodCount >> 8);
+		this.contents[this.methodCountOffset] = (byte) this.methodCount;
+
+		int attributesNumber = 0;
+		// leave two bytes for the number of attributes and store the current offset
+		int attributeOffset = this.contentsOffset;
+		this.contentsOffset += 2;
+
+		// source attribute
+		if ((this.produceAttributes & ClassFileConstants.ATTR_SOURCE) != 0) {
+			String fullFileName =
+				new String(this.referenceBinding.scope.referenceCompilationUnit().getFileName());
+			fullFileName = fullFileName.replace('\\', '/');
+			int lastIndex = fullFileName.lastIndexOf('/');
+			if (lastIndex != -1) {
+				fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
+			}
+			attributesNumber += generateSourceAttribute(fullFileName);
+		}
+		// Deprecated attribute
+		if (this.referenceBinding.isDeprecated()) {
+			// check that there is enough space to write all the bytes for the field info corresponding
+			// to the @fieldBinding
+			attributesNumber += generateDeprecatedAttribute();
+		}
+		// add signature attribute
+		char[] genericSignature = this.referenceBinding.genericSignature();
+		if (genericSignature != null) {
+			attributesNumber += generateSignatureAttribute(genericSignature);
+		}
+		if (this.targetJDK >= ClassFileConstants.JDK1_5
+				&& this.referenceBinding.isNestedType()
+				&& !this.referenceBinding.isMemberType()) {
+			// add enclosing method attribute (1.5 mode only)
+			attributesNumber += generateEnclosingMethodAttribute();
+		}
+		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
+			TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
+			if (typeDeclaration != null) {
+				final Annotation[] annotations = typeDeclaration.annotations;
+				if (annotations != null) {
+					attributesNumber += generateRuntimeAnnotations(annotations);
+				}
+			}
+		}
+
+		if (this.referenceBinding.isHierarchyInconsistent()) {
+			ReferenceBinding superclass = this.referenceBinding.superclass;
+			if (superclass != null) {
+				this.missingTypes = superclass.collectMissingTypes(this.missingTypes);
+			}
+			ReferenceBinding[] superInterfaces = this.referenceBinding.superInterfaces();
+			for (int i = 0, max = superInterfaces.length; i < max; i++) {
+				this.missingTypes = superInterfaces[i].collectMissingTypes(this.missingTypes);
+			}
+			attributesNumber += generateHierarchyInconsistentAttribute();
+		}
+		// Functional expression and lambda bootstrap methods
+		if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) {
+			attributesNumber += generateBootstrapMethods(this.bootstrapMethods);
+		}
+		// Inner class attribute
+		int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
+		if (numberOfInnerClasses != 0) {
+			ReferenceBinding[] innerClasses = new ReferenceBinding[numberOfInnerClasses];
+			this.innerClassesBindings.toArray(innerClasses);
+			Arrays.sort(innerClasses, new Comparator() {
+				public int compare(Object o1, Object o2) {
+					TypeBinding binding1 = (TypeBinding) o1;
+					TypeBinding binding2 = (TypeBinding) o2;
+					return CharOperation.compareTo(binding1.constantPoolName(), binding2.constantPoolName());
+				}
+			});
+			attributesNumber += generateInnerClassAttribute(numberOfInnerClasses, innerClasses);
+		}
+		if (this.missingTypes != null) {
+			generateMissingTypesAttribute();
+			attributesNumber++;
+		}
+		
+		attributesNumber += generateTypeAnnotationAttributeForTypeDeclaration();
+		
+		// update the number of attributes
+		if (attributeOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		this.contents[attributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[attributeOffset] = (byte) attributesNumber;
+
+		// resynchronize all offsets of the classfile
+		this.header = this.constantPool.poolContent;
+		this.headerOffset = this.constantPool.currentOffset;
+		int constantPoolCount = this.constantPool.currentIndex;
+		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
+	 * the abstract methods inherited from superinterfaces.
+	 */
+	public void addDefaultAbstractMethods() { // default abstract methods
+		MethodBinding[] defaultAbstractMethods =
+			this.referenceBinding.getDefaultAbstractMethods();
+		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
+			MethodBinding methodBinding = defaultAbstractMethods[i];
+			generateMethodInfoHeader(methodBinding);
+			int methodAttributeOffset = this.contentsOffset;
+			int attributeNumber = generateMethodInfoAttributes(methodBinding);
+			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
+		}
+	}
+
+	private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffset) {
+		int attributesNumber = 0;
+		// 4.7.2 only static constant fields get a ConstantAttribute
+		// Generate the constantValueAttribute
+		Constant fieldConstant = fieldBinding.constant();
+		if (fieldConstant != Constant.NotAConstant){
+			attributesNumber += generateConstantValueAttribute(fieldConstant, fieldBinding, fieldAttributeOffset);
+		}
+		if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) {
+			attributesNumber += generateSyntheticAttribute();
+		}
+		if (fieldBinding.isDeprecated()) {
+			attributesNumber += generateDeprecatedAttribute();
+		}
+		// add signature attribute
+		char[] genericSignature = fieldBinding.genericSignature();
+		if (genericSignature != null) {
+			attributesNumber += generateSignatureAttribute(genericSignature);
+		}
+		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
+			FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
+			if (fieldDeclaration != null) {
+				Annotation[] annotations = fieldDeclaration.annotations;
+				if (annotations != null) {
+					attributesNumber += generateRuntimeAnnotations(annotations);
+				}
+
+				if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+					List allTypeAnnotationContexts = new ArrayList();
+					if (annotations != null && (fieldDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
+						fieldDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
+					}
+					int invisibleTypeAnnotationsCounter = 0;
+					int visibleTypeAnnotationsCounter = 0;
+					TypeReference fieldType = fieldDeclaration.type;
+					if (fieldType != null && ((fieldType.bits & ASTNode.HasTypeAnnotations) != 0)) {
+						fieldType.getAllAnnotationContexts(AnnotationTargetTypeConstants.FIELD, allTypeAnnotationContexts);
+					}
+					int size = allTypeAnnotationContexts.size();
+					if (size != 0) {
+						AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+						allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+						for (int i = 0, max = allTypeAnnotationContextsArray.length; i < max; i++) {
+							AnnotationContext annotationContext = allTypeAnnotationContextsArray[i];
+							if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+								invisibleTypeAnnotationsCounter++;
+								allTypeAnnotationContexts.add(annotationContext);
+							} else {
+								visibleTypeAnnotationsCounter++;
+								allTypeAnnotationContexts.add(annotationContext);
+							}
+						}
+						attributesNumber += generateRuntimeTypeAnnotations(
+								allTypeAnnotationContextsArray,
+								visibleTypeAnnotationsCounter,
+								invisibleTypeAnnotationsCounter);
+					}
+				}
+			}
+		}
+		if ((fieldBinding.tagBits & TagBits.HasMissingType) != 0) {
+			this.missingTypes = fieldBinding.type.collectMissingTypes(this.missingTypes);
+		}
+		return attributesNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods generates the bytes for the given field binding
+	 * @param fieldBinding the given field binding
+	 */
+	private void addFieldInfo(FieldBinding fieldBinding) {
+		// 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);
+		}
+		// Now we can generate all entries into the byte array
+		// First the accessFlags
+		int accessFlags = fieldBinding.getAccessFlags();
+		if (this.targetJDK < ClassFileConstants.JDK1_5) {
+			// pre 1.5, synthetic was an attribute, not a modifier
+			accessFlags &= ~ClassFileConstants.AccSynthetic;
+		}
+		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
+		this.contents[this.contentsOffset++] = (byte) accessFlags;
+		// Then the nameIndex
+		int nameIndex = this.constantPool.literalIndex(fieldBinding.name);
+		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) nameIndex;
+		// Then the descriptorIndex
+		int descriptorIndex = this.constantPool.literalIndex(fieldBinding.type);
+		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
+		int fieldAttributeOffset = this.contentsOffset;
+		int attributeNumber = 0;
+		// leave some space for the number of attributes
+		this.contentsOffset += 2;
+		attributeNumber += addFieldAttributes(fieldBinding, fieldAttributeOffset);
+		if (this.contentsOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		this.contents[fieldAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[fieldAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods generate all the fields infos for the receiver.
+	 * This includes:
+	 * - a field info for each defined field of that class
+	 * - a field info for each synthetic field (e.g. this$0)
+	 */
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods generate all the fields infos for the receiver.
+	 * This includes:
+	 * - a field info for each defined field of that class
+	 * - a field info for each synthetic field (e.g. this$0)
+	 */
+	public void addFieldInfos() {
+		SourceTypeBinding currentBinding = this.referenceBinding;
+		FieldBinding[] syntheticFields = currentBinding.syntheticFields();
+		int fieldCount = 	currentBinding.fieldCount() + (syntheticFields == null ? 0 : syntheticFields.length);
+
+		// write the number of fields
+		if (fieldCount > 0xFFFF) {
+			this.referenceBinding.scope.problemReporter().tooManyFields(this.referenceBinding.scope.referenceType());
+		}
+		this.contents[this.contentsOffset++] = (byte) (fieldCount >> 8);
+		this.contents[this.contentsOffset++] = (byte) fieldCount;
+
+		FieldDeclaration[] fieldDecls = currentBinding.scope.referenceContext.fields;
+		for (int i = 0, max = fieldDecls == null ? 0 : fieldDecls.length; i < max; i++) {
+			FieldDeclaration fieldDecl = fieldDecls[i];
+			if (fieldDecl.binding != null) {
+				addFieldInfo(fieldDecl.binding);
+			}
+		}
+
+		if (syntheticFields != null) {
+			for (int i = 0, max = syntheticFields.length; i < max; i++) {
+				addFieldInfo(syntheticFields[i]);
+			}
+		}
+	}
+
+	private void addMissingAbstractProblemMethod(MethodDeclaration methodDeclaration, MethodBinding methodBinding, CategorizedProblem problem, CompilationResult compilationResult) {
+		// 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 = generateMethodInfoAttributes(methodBinding);
+
+		// Code attribute
+		attributeNumber++;
+
+		int codeAttributeOffset = this.contentsOffset;
+		generateCodeAttributeHeader();
+		StringBuffer buffer = new StringBuffer(25);
+		buffer.append("\t"  + problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
+		buffer.insert(0, Messages.compilation_unresolvedProblem);
+		String problemString = buffer.toString();
+
+		this.codeStream.init(this);
+		this.codeStream.preserveUnusedLocals = true;
+		this.codeStream.initializeMaxLocals(methodBinding);
+
+		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
+		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
+
+		completeCodeAttributeForMissingAbstractProblemMethod(
+			methodBinding,
+			codeAttributeOffset,
+			compilationResult.getLineSeparatorPositions(),
+			problem.getSourceLineNumber());
+
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem clinit method info that correspond to a boggus method.
+	 *
+	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
+	 */
+	public void addProblemClinit(CategorizedProblem[] problems) {
+		generateMethodInfoHeaderForClinit();
+		// leave two spaces for the number of attributes
+		this.contentsOffset -= 2;
+		int attributeOffset = this.contentsOffset;
+		this.contentsOffset += 2;
+		int attributeNumber = 0;
+
+		int codeAttributeOffset = this.contentsOffset;
+		generateCodeAttributeHeader();
+		this.codeStream.resetForProblemClinit(this);
+		String problemString = "" ; //$NON-NLS-1$
+		int problemLine = 0;
+		if (problems != null) {
+			int max = problems.length;
+			StringBuffer buffer = new StringBuffer(25);
+			int count = 0;
+			for (int i = 0; i < max; i++) {
+				CategorizedProblem problem = problems[i];
+				if ((problem != null) && (problem.isError())) {
+					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
+					count++;
+					if (problemLine == 0) {
+						problemLine = problem.getSourceLineNumber();
+					}
+					problems[i] = null;
+				}
+			} // insert the top line afterwards, once knowing how many problems we have to consider
+			if (count > 1) {
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
+			} else {
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
+			}
+			problemString = buffer.toString();
+		}
+
+		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
+		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
+		attributeNumber++; // code attribute
+		completeCodeAttributeForClinit(
+			codeAttributeOffset,
+			problemLine);
+		if (this.contentsOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		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.
+	 *
+	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
+	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
+	 */
+	public void addProblemConstructor(
+		AbstractMethodDeclaration method,
+		MethodBinding methodBinding,
+		CategorizedProblem[] problems) {
+
+		// 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 attributesNumber = generateMethodInfoAttributes(methodBinding);
+
+		// Code attribute
+		attributesNumber++;
+		int codeAttributeOffset = this.contentsOffset;
+		generateCodeAttributeHeader();
+		this.codeStream.reset(method, this);
+		String problemString = "" ; //$NON-NLS-1$
+		int problemLine = 0;
+		if (problems != null) {
+			int max = problems.length;
+			StringBuffer buffer = new StringBuffer(25);
+			int count = 0;
+			for (int i = 0; i < max; i++) {
+				CategorizedProblem problem = problems[i];
+				if ((problem != null) && (problem.isError())) {
+					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
+					count++;
+					if (problemLine == 0) {
+						problemLine = problem.getSourceLineNumber();
+					}
+				}
+			} // insert the top line afterwards, once knowing how many problems we have to consider
+			if (count > 1) {
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
+			} else {
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
+			}
+			problemString = buffer.toString();
+		}
+
+		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
+		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
+		completeCodeAttributeForProblemMethod(
+			method,
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions(),
+			problemLine);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem method info that correspond to a boggus constructor.
+	 * Reset the position inside the contents byte array to the savedOffset.
+	 *
+	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
+	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
+	 * @param savedOffset <CODE>int</CODE>
+	 */
+	public void addProblemConstructor(
+		AbstractMethodDeclaration method,
+		MethodBinding methodBinding,
+		CategorizedProblem[] problems,
+		int savedOffset) {
+		// we need to move back the contentsOffset to the value at the beginning of the method
+		this.contentsOffset = savedOffset;
+		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.
+	 *
+	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
+	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
+	 */
+	public void addProblemMethod(
+		AbstractMethodDeclaration method,
+		MethodBinding methodBinding,
+		CategorizedProblem[] problems) {
+		if (methodBinding.isAbstract() && methodBinding.declaringClass.isInterface()) {
+			method.abort(ProblemSeverities.AbortType, null);
+		}
+		// 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 attributesNumber = generateMethodInfoAttributes(methodBinding);
+
+		// Code attribute
+		attributesNumber++;
+
+		int codeAttributeOffset = this.contentsOffset;
+		generateCodeAttributeHeader();
+		this.codeStream.reset(method, this);
+		String problemString = "" ; //$NON-NLS-1$
+		int problemLine = 0;
+		if (problems != null) {
+			int max = problems.length;
+			StringBuffer buffer = new StringBuffer(25);
+			int count = 0;
+			for (int i = 0; i < max; i++) {
+				CategorizedProblem problem = problems[i];
+				if ((problem != null)
+					&& (problem.isError())
+					&& (problem.getSourceStart() >= method.declarationSourceStart)
+					&& (problem.getSourceEnd() <= method.declarationSourceEnd)) {
+					buffer.append("\t"  +problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
+					count++;
+					if (problemLine == 0) {
+						problemLine = problem.getSourceLineNumber();
+					}
+					problems[i] = null;
+				}
+			} // insert the top line afterwards, once knowing how many problems we have to consider
+			if (count > 1) {
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
+			} else {
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
+			}
+			problemString = buffer.toString();
+		}
+
+		// return codeStream.generateCodeAttributeForProblemMethod(comp.options.runtimeExceptionNameForCompileError, "")
+		this.codeStream.generateCodeAttributeForProblemMethod(problemString);
+		completeCodeAttributeForProblemMethod(
+			method,
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions(),
+			problemLine);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem method info that correspond to a boggus method.
+	 * Reset the position inside the contents byte array to the savedOffset.
+	 *
+	 * @param method org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
+	 * @param problems org.eclipse.jdt.internal.compiler.problem.Problem[]
+	 * @param savedOffset <CODE>int</CODE>
+	 */
+	public void addProblemMethod(
+		AbstractMethodDeclaration method,
+		MethodBinding methodBinding,
+		CategorizedProblem[] problems,
+		int savedOffset) {
+		// we need to move back the contentsOffset to the value at the beginning of the method
+		this.contentsOffset = savedOffset;
+		this.methodCount--; // we need to remove the method that causes the problem
+		addProblemMethod(method, methodBinding, problems);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for all the special method infos.
+	 * They are:
+	 * - synthetic access methods
+	 * - default abstract methods
+	 * - lambda methods.
+	 */
+	public void addSpecialMethods() {
+
+		// add all methods (default abstract methods and synthetic)
+
+		// default abstract methods
+		generateMissingAbstractMethods(this.referenceBinding.scope.referenceType().missingAbstractMethods, this.referenceBinding.scope.referenceCompilationUnit().compilationResult);
+
+		MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods();
+		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
+			MethodBinding methodBinding = defaultAbstractMethods[i];
+			generateMethodInfoHeader(methodBinding);
+			int methodAttributeOffset = this.contentsOffset;
+			int attributeNumber = generateMethodInfoAttributes(methodBinding);
+			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
+		}
+		
+		// add synthetic methods infos
+		int emittedSyntheticsCount = 0;
+		boolean continueScanningSynthetics = true;
+		while (continueScanningSynthetics) {
+			continueScanningSynthetics = false;
+			SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods();
+			int currentSyntheticsCount = syntheticMethods == null ? 0: syntheticMethods.length;
+			if (emittedSyntheticsCount != currentSyntheticsCount) {
+				for (int i = emittedSyntheticsCount, max = currentSyntheticsCount; i < max; i++) {
+					SyntheticMethodBinding syntheticMethod = syntheticMethods[i];
+					switch (syntheticMethod.purpose) {
+						case SyntheticMethodBinding.FieldReadAccess :
+						case SyntheticMethodBinding.SuperFieldReadAccess :
+							// generate a method info to emulate an reading access to
+							// a non-accessible field
+							addSyntheticFieldReadAccessMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.FieldWriteAccess :
+						case SyntheticMethodBinding.SuperFieldWriteAccess :
+							// generate a method info to emulate an writing access to
+							// a non-accessible field
+							addSyntheticFieldWriteAccessMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.MethodAccess :
+						case SyntheticMethodBinding.SuperMethodAccess :
+						case SyntheticMethodBinding.BridgeMethod :
+							// generate a method info to emulate an access to a non-accessible method / super-method or bridge method
+							addSyntheticMethodAccessMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.ConstructorAccess :
+							// generate a method info to emulate an access to a non-accessible constructor
+							addSyntheticConstructorAccessMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.EnumValues :
+							// generate a method info to define <enum>#values()
+							addSyntheticEnumValuesMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.EnumValueOf :
+							// generate a method info to define <enum>#valueOf(String)
+							addSyntheticEnumValueOfMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.SwitchTable :
+							// generate a method info to define the switch table synthetic method
+							addSyntheticSwitchTable(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.TooManyEnumsConstants :
+							addSyntheticEnumInitializationMethod(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.LambdaMethod:
+							syntheticMethod.lambda.generateCode(this.referenceBinding.scope, this);
+							continueScanningSynthetics = true; // lambda code generation could schedule additional nested lambdas for code generation.
+							break;
+						case SyntheticMethodBinding.ArrayConstructor:
+							addSyntheticArrayConstructor(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.ArrayClone:
+							addSyntheticArrayClone(syntheticMethod);
+							break;
+						case SyntheticMethodBinding.FactoryMethod:
+							addSyntheticFactoryMethod(syntheticMethod);
+							break;	
+					}
+				}
+				emittedSyntheticsCount = currentSyntheticsCount;
+			}
+		}
+	}
+
+	public void addSyntheticArrayConstructor(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForArrayConstructor(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+	public void addSyntheticArrayClone(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForArrayClone(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+	public void addSyntheticFactoryMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForFactoryMethod(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the bytes for a synthetic method that provides an access to a private constructor.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForConstructorAccess(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 *  Generate the bytes for a synthetic method that implements Enum#valueOf(String) for a given enum type
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForEnumValueOf(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 *  Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForEnumValues(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	public void addSyntheticEnumInitializationMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForEnumInitializationMethod(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem method info that correspond to a synthetic method that
+	 * generate an read access to a private field.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for a problem method info that correspond to a synthetic method that
+	 * generate an write access to a private field.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the bytes for a synthetic method that provides access to a private method.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
+	 */
+	public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding);
+		int methodAttributeOffset = this.contentsOffset;
+		// this will add exception attribute, synthetic attribute, deprecated attribute,...
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
+		// Code attribute
+		int codeAttributeOffset = this.contentsOffset;
+		attributeNumber++; // add code attribute
+		generateCodeAttributeHeader();
+		this.codeStream.init(this);
+		this.codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
+		completeCodeAttributeForSyntheticMethod(
+			true,
+			methodBinding,
+			codeAttributeOffset,
+			((SourceTypeBinding) methodBinding.declaringClass)
+				.scope
+				.referenceCompilationUnit()
+				.compilationResult
+				.getLineSeparatorPositions());
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 *
+	 * @param codeAttributeOffset <CODE>int</CODE>
+	 */
+	public void completeCodeAttribute(int codeAttributeOffset) {
+		// reinitialize the localContents with the byte modified by the code stream
+		this.contents = this.codeStream.bCodeStream;
+		int localContentsOffset = this.codeStream.classFileOffset;
+		// codeAttributeOffset is the position inside localContents byte array before we started to write
+		// any information about the codeAttribute
+		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
+		// to get the right position, 6 for the max_stack etc...
+		int code_length = this.codeStream.position;
+		if (code_length > 65535) {
+			if (this.codeStream.methodDeclaration != null) {
+				this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.methodDeclaration);
+			} else {
+				this.codeStream.lambdaExpression.scope.problemReporter().bytecodeExceeds64KLimit(this.codeStream.lambdaExpression);
+			}
+		}
+		if (localContentsOffset + 20 >= this.contents.length) {
+			resizeContents(20);
+		}
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+
+		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
+		// write the exception table
+		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
+		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
+		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
+			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
+		}
+		int exSize = exceptionHandlersCount * 8 + 2;
+		if (exSize + localContentsOffset >= this.contents.length) {
+			resizeContents(exSize);
+		}
+		// there is no exception table, so we need to offset by 2 the current offset and move
+		// on the attribute generation
+		this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
+		this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
+		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+			ExceptionLabel exceptionLabel = exceptionLabels[i];
+			if (exceptionLabel != null) {
+				int iRange = 0, maxRange = exceptionLabel.getCount();
+				if ((maxRange & 1) != 0) {
+					if (this.codeStream.methodDeclaration != null) {
+						this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
+								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
+								this.codeStream.methodDeclaration);
+					} else {
+						this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
+								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.lambdaExpression.binding.selector)),
+								this.codeStream.lambdaExpression);
+					}
+				}
+				while (iRange < maxRange) {
+					int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
+					this.contents[localContentsOffset++] = (byte) (start >> 8);
+					this.contents[localContentsOffset++] = (byte) start;
+					int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
+					this.contents[localContentsOffset++] = (byte) (end >> 8);
+					this.contents[localContentsOffset++] = (byte) end;
+					int handlerPC = exceptionLabel.position;
+					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;
+					if (exceptionLabel.exceptionType == null) {
+						// any exception handler
+						this.contents[localContentsOffset++] = 0;
+						this.contents[localContentsOffset++] = 0;
+					} else {
+						int nameIndex;
+						if (exceptionLabel.exceptionType == TypeBinding.NULL) {
+							/* represents ClassNotFoundException, see class literal access*/
+							nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
+						} else {
+							nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
+						}
+						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+						this.contents[localContentsOffset++] = (byte) nameIndex;
+					}
+				}
+			}
+		}
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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) {
+			attributesNumber += generateLineNumberAttribute();
+		}
+		// then we do the local variable attribute
+		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
+			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.isStatic() : this.codeStream.lambdaExpression.binding.isStatic();
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
+		}
+
+		if (addStackMaps) {
+			attributesNumber += generateStackMapTableAttribute(
+					this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			attributesNumber += generateStackMapAttribute(
+					this.codeStream.methodDeclaration != null ? this.codeStream.methodDeclaration.binding : this.codeStream.lambdaExpression.binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+		
+		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+			attributesNumber += generateTypeAnnotationsOnCodeAttribute();
+		}
+
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+
+		// update the attribute length
+		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;
+	}
+	
+	public int generateTypeAnnotationsOnCodeAttribute() {
+		int attributesNumber = 0;
+		
+		List allTypeAnnotationContexts = ((TypeAnnotationCodeStream) this.codeStream).allTypeAnnotationContexts;
+		int invisibleTypeAnnotationsCounter = 0;
+		int visibleTypeAnnotationsCounter = 0;
+
+		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
+			LocalVariableBinding localVariable = this.codeStream.locals[i];
+			if (localVariable.isCatchParameter()) continue;
+			LocalDeclaration declaration = localVariable.declaration;
+			if (declaration == null
+					|| (declaration.isArgument() && ((declaration.bits & ASTNode.IsUnionType) == 0))
+					|| (localVariable.initializationCount == 0)
+					|| ((declaration.bits & ASTNode.HasTypeAnnotations) == 0)) {
+				continue;
+			}
+			int targetType = ((localVariable.tagBits & TagBits.IsResource) == 0) ? AnnotationTargetTypeConstants.LOCAL_VARIABLE : AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
+			declaration.getAllAnnotationContexts(targetType, localVariable, allTypeAnnotationContexts);
+		}
+		
+		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
+		int tableIndex = 0;
+		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+			ExceptionLabel exceptionLabel = exceptionLabels[i];
+			if (exceptionLabel instanceof MultiCatchExceptionLabel) {
+				MultiCatchExceptionLabel multiCatchExceptionLabel = (MultiCatchExceptionLabel)exceptionLabel;
+				tableIndex += multiCatchExceptionLabel.getAllAnnotationContexts(tableIndex, allTypeAnnotationContexts);
+			} else {
+				if (exceptionLabel.exceptionTypeReference != null) { // ignore those which cannot be annotated
+					exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, tableIndex, allTypeAnnotationContexts);
+				}
+				tableIndex++;
+			}
+		}
+		
+		int size = allTypeAnnotationContexts.size();
+		if (size != 0) {
+			AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+			allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+			for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
+				AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
+				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+					invisibleTypeAnnotationsCounter++;
+				} else {
+					visibleTypeAnnotationsCounter++;
+				}
+			}
+			attributesNumber += generateRuntimeTypeAnnotations(
+					allTypeAnnotationContextsArray,
+					visibleTypeAnnotationsCounter,
+					invisibleTypeAnnotationsCounter);
+		}
+		return attributesNumber;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 *
+	 * @param codeAttributeOffset <CODE>int</CODE>
+	 */
+	public void completeCodeAttributeForClinit(int codeAttributeOffset) {
+		// reinitialize the contents with the byte modified by the code stream
+		this.contents = this.codeStream.bCodeStream;
+		int localContentsOffset = this.codeStream.classFileOffset;
+		// codeAttributeOffset is the position inside contents byte array before we started to write
+		// any information about the codeAttribute
+		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
+		// to get the right position, 6 for the max_stack etc...
+		int code_length = this.codeStream.position;
+		if (code_length > 65535) {
+			this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
+				this.codeStream.methodDeclaration.scope.referenceType());
+		}
+		if (localContentsOffset + 20 >= this.contents.length) {
+			resizeContents(20);
+		}
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+
+		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
+		// write the exception table
+		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
+		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
+		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
+			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
+		}
+		int exSize = exceptionHandlersCount * 8 + 2;
+		if (exSize + localContentsOffset >= this.contents.length) {
+			resizeContents(exSize);
+		}
+		// there is no exception table, so we need to offset by 2 the current offset and move
+		// on the attribute generation
+		this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
+		this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
+		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+			ExceptionLabel exceptionLabel = exceptionLabels[i];
+			if (exceptionLabel != null) {
+				int iRange = 0, maxRange = exceptionLabel.getCount();
+				if ((maxRange & 1) != 0) {
+					this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
+							Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
+							this.codeStream.methodDeclaration);
+				}
+				while  (iRange < maxRange) {
+					int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
+					this.contents[localContentsOffset++] = (byte) (start >> 8);
+					this.contents[localContentsOffset++] = (byte) start;
+					int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
+					this.contents[localContentsOffset++] = (byte) (end >> 8);
+					this.contents[localContentsOffset++] = (byte) end;
+					int handlerPC = exceptionLabel.position;
+					this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
+					this.contents[localContentsOffset++] = (byte) handlerPC;
+					if (addStackMaps) {
+						StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
+						stackMapFrameCodeStream.addFramePosition(handlerPC);
+//						stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
+					}
+					if (exceptionLabel.exceptionType == null) {
+						// any exception handler
+						this.contents[localContentsOffset++] = 0;
+						this.contents[localContentsOffset++] = 0;
+					} else {
+						int nameIndex;
+						if (exceptionLabel.exceptionType == TypeBinding.NULL) {
+							/* represents denote ClassNotFoundException, see class literal access*/
+							nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
+						} else {
+							nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
+						}
+						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+						this.contents[localContentsOffset++] = (byte) nameIndex;
+					}
+				}
+			}
+		}
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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) {
+			attributesNumber += generateLineNumberAttribute();
+		}
+		// then we do the local variable attribute
+		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
+			attributesNumber += generateLocalVariableTableAttribute(code_length, true, false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
+			attributesNumber += generateStackMapTableAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			attributesNumber += generateStackMapAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
+		}
+
+		// update the number of attributes
+		// ensure first that there is enough space available inside the contents array
+		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+		// update the attribute length
+		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;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 */
+	public void completeCodeAttributeForClinit(
+			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;
+		// codeAttributeOffset is the position inside contents byte array before we started to write
+		// any information about the codeAttribute
+		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
+		// to get the right position, 6 for the max_stack etc...
+		int code_length = this.codeStream.position;
+		if (code_length > 65535) {
+			this.codeStream.methodDeclaration.scope.problemReporter().bytecodeExceeds64KLimit(
+				this.codeStream.methodDeclaration.scope.referenceType());
+		}
+		if (localContentsOffset + 20 >= this.contents.length) {
+			resizeContents(20);
+		}
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+
+		// write the exception table
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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) {
+			attributesNumber += generateLineNumberAttribute(problemLine);
+		}
+		localContentsOffset = this.contentsOffset;
+		// then we do the local variable attribute
+		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 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;
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = 2;
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = 0;
+			attributesNumber++;
+		}
+
+		this.contentsOffset = localContentsOffset;
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
+			attributesNumber += generateStackMapTableAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			attributesNumber += generateStackMapAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
+		}
+
+		// update the number of attributes
+		// ensure first that there is enough space available inside the contents array
+		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+		// update the attribute length
+		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;
+	}
+
+
+	/**
+	 *
+	 */
+	public void completeCodeAttributeForMissingAbstractProblemMethod(
+			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;
+		// codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		int code_length = this.codeStream.position;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+		// write the exception table
+		if (localContentsOffset + 50 >= this.contents.length) {
+			resizeContents(50);
+		}
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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 (problemLine == 0) {
+				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
+			}
+			attributesNumber += generateLineNumberAttribute(problemLine);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
+			attributesNumber += generateStackMapTableAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			attributesNumber += generateStackMapAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+
+		// then we do the local variable attribute
+		// 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) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+		// update the attribute length
+		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;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 *
+	 * @param codeAttributeOffset <CODE>int</CODE>
+	 */
+	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;
+		// codeAttributeOffset is the position inside localContents byte array before we started to write// any information about the codeAttribute// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset// to get the right position, 6 for the max_stack etc...
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		int code_length = this.codeStream.position;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+		// write the exception table
+		if (localContentsOffset + 50 >= this.contents.length) {
+			resizeContents(50);
+		}
+
+		// write the exception table
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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 (problemLine == 0) {
+				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
+			}
+			attributesNumber += generateLineNumberAttribute(problemLine);
+		}
+
+		// then we do the local variable attribute
+		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
+			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic();
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
+			attributesNumber += generateStackMapTableAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			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) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+		// update the attribute length
+		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;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 *
+	 * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
+	 * @param codeAttributeOffset <CODE>int</CODE>
+	 */
+	public void completeCodeAttributeForSyntheticMethod(
+			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;
+		// codeAttributeOffset is the position inside contents byte array before we started to write
+		// any information about the codeAttribute
+		// That means that to write the attribute_length you need to offset by 2 the value of codeAttributeOffset
+		// to get the right position, 6 for the max_stack etc...
+		int max_stack = this.codeStream.stackMax;
+		this.contents[codeAttributeOffset + 6] = (byte) (max_stack >> 8);
+		this.contents[codeAttributeOffset + 7] = (byte) max_stack;
+		int max_locals = this.codeStream.maxLocals;
+		this.contents[codeAttributeOffset + 8] = (byte) (max_locals >> 8);
+		this.contents[codeAttributeOffset + 9] = (byte) max_locals;
+		int code_length = this.codeStream.position;
+		this.contents[codeAttributeOffset + 10] = (byte) (code_length >> 24);
+		this.contents[codeAttributeOffset + 11] = (byte) (code_length >> 16);
+		this.contents[codeAttributeOffset + 12] = (byte) (code_length >> 8);
+		this.contents[codeAttributeOffset + 13] = (byte) code_length;
+		if ((localContentsOffset + 40) >= this.contents.length) {
+			resizeContents(40);
+		}
+
+		boolean addStackMaps = (this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0;
+		if (hasExceptionHandlers) {
+			// write the exception table
+			ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
+			int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
+			for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
+				exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
+			}
+			int exSize = exceptionHandlersCount * 8 + 2;
+			if (exSize + localContentsOffset >= this.contents.length) {
+				resizeContents(exSize);
+			}
+			// there is no exception table, so we need to offset by 2 the current offset and move
+			// on the attribute generation
+			this.contents[localContentsOffset++] = (byte) (exceptionHandlersCount >> 8);
+			this.contents[localContentsOffset++] = (byte) exceptionHandlersCount;
+			for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+				ExceptionLabel exceptionLabel = exceptionLabels[i];
+				if (exceptionLabel != null) {
+					int iRange = 0, maxRange = exceptionLabel.getCount();
+					if ((maxRange & 1) != 0) {
+						this.referenceBinding.scope.problemReporter().abortDueToInternalError(
+								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(binding.selector),
+										this.referenceBinding.scope.problemReporter().referenceContext));
+					}
+					while  (iRange < maxRange) {
+						int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
+						this.contents[localContentsOffset++] = (byte) (start >> 8);
+						this.contents[localContentsOffset++] = (byte) start;
+						int end = exceptionLabel.ranges[iRange++]; // odd ranges are end positions
+						this.contents[localContentsOffset++] = (byte) (end >> 8);
+						this.contents[localContentsOffset++] = (byte) end;
+						int handlerPC = exceptionLabel.position;
+						if (addStackMaps) {
+							StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
+							stackMapFrameCodeStream.addFramePosition(handlerPC);
+						}
+						this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
+						this.contents[localContentsOffset++] = (byte) handlerPC;
+						if (exceptionLabel.exceptionType == null) {
+							// any exception handler
+							this.contents[localContentsOffset++] = 0;
+							this.contents[localContentsOffset++] = 0;
+						} else {
+							int nameIndex;
+							switch(exceptionLabel.exceptionType.id) {
+								case T_null :
+									/* represents ClassNotFoundException, see class literal access*/
+									nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
+									break;
+								case T_long :
+									/* represents NoSuchFieldError, see switch table generation*/
+									nameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
+									break;
+								default:
+									nameIndex = this.constantPool.literalIndexForType(exceptionLabel.exceptionType);
+							}
+							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+							this.contents[localContentsOffset++] = (byte) nameIndex;
+						}
+					}
+				}
+			}
+		} else {
+			// there is no exception table, so we need to offset by 2 the current offset and move
+			// on the attribute generation
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = 0;
+		}
+		// debug attributes
+		int codeAttributeAttributeOffset = localContentsOffset;
+		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) {
+			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) {
+			final boolean methodDeclarationIsStatic = binding.isStatic();
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true);
+		}
+		if (addStackMaps) {
+			attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false);
+		}
+
+		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
+			attributesNumber += generateStackMapAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
+		}
+
+		// update the number of attributes
+		// ensure first that there is enough space available inside the contents array
+		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
+
+		// update the attribute length
+		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;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method completes the creation of the code attribute by setting
+	 * - the attribute_length
+	 * - max_stack
+	 * - max_locals
+	 * - code_length
+	 * - exception table
+	 * - and debug attributes if necessary.
+	 *
+	 * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
+	 * @param codeAttributeOffset <CODE>int</CODE>
+	 */
+	public void completeCodeAttributeForSyntheticMethod(
+			SyntheticMethodBinding binding,
+			int codeAttributeOffset,
+			int[] startLineIndexes) {
+
+		this.completeCodeAttributeForSyntheticMethod(
+				false,
+				binding,
+				codeAttributeOffset,
+				startLineIndexes);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Complete the creation of a method info by setting up the number of attributes at the right offset.
+	 *
+	 * @param methodAttributeOffset <CODE>int</CODE>
+	 * @param attributesNumber <CODE>int</CODE>
+	 */
+	public void completeMethodInfo(
+			MethodBinding binding,
+			int methodAttributeOffset,
+			int attributesNumber) {
+		
+		if ((this.produceAttributes & ClassFileConstants.ATTR_TYPE_ANNOTATION) != 0) {
+			List allTypeAnnotationContexts = new ArrayList();
+			int invisibleTypeAnnotationsCounter = 0;
+			int visibleTypeAnnotationsCounter = 0;
+			AbstractMethodDeclaration methodDeclaration = binding.sourceMethod();
+			if (methodDeclaration != null) {
+				if ((methodDeclaration.bits & ASTNode.HasTypeAnnotations) != 0) {
+					Argument[] arguments = methodDeclaration.arguments;
+					if (arguments != null) {
+						for (int i = 0, max = arguments.length; i < max; i++) {
+							Argument argument = arguments[i];
+							if ((argument.bits & ASTNode.HasTypeAnnotations) != 0) {
+								argument.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, i, allTypeAnnotationContexts);
+							}
+						}
+					}
+					Receiver receiver = methodDeclaration.receiver;
+					if (receiver != null && (receiver.type.bits & ASTNode.HasTypeAnnotations) != 0) {
+						receiver.type.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RECEIVER, allTypeAnnotationContexts);
+					}
+				}
+				Annotation[] annotations = methodDeclaration.annotations;
+				if (annotations != null && binding.returnType.id != T_void) {
+					methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
+				}
+				if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) {
+					MethodDeclaration declaration = (MethodDeclaration) methodDeclaration;
+					TypeReference typeReference = declaration.returnType;
+					if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+						typeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN, allTypeAnnotationContexts);
+					}
+				}
+				TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+				if (thrownExceptions != null) {
+					for (int i = 0, max = thrownExceptions.length; i < max; i++) {
+						TypeReference thrownException = thrownExceptions[i];
+						thrownException.getAllAnnotationContexts(AnnotationTargetTypeConstants.THROWS, i, allTypeAnnotationContexts);
+					}
+				}
+				TypeParameter[] typeParameters = methodDeclaration.typeParameters();
+				if (typeParameters != null) {
+					for (int i = 0, max = typeParameters.length; i < max; i++) {
+						TypeParameter typeParameter = typeParameters[i];
+						if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
+							typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER, i, allTypeAnnotationContexts);
+						}
+					}
+				}
+			}
+			int size = allTypeAnnotationContexts.size();
+			if (size != 0) {
+				AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+				allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+				for (int j = 0, max2 = allTypeAnnotationContextsArray.length; j < max2; j++) {
+					AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
+					if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+						invisibleTypeAnnotationsCounter++;
+					} else {
+						visibleTypeAnnotationsCounter++;
+					}
+				}
+				attributesNumber += generateRuntimeTypeAnnotations(
+						allTypeAnnotationContextsArray,
+						visibleTypeAnnotationsCounter,
+						invisibleTypeAnnotationsCounter);
+			}
+		}
+		// update the number of attributes
+		this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributesNumber;
+	}
+	
+	private void dumpLocations(int[] locations) {
+		if (locations == null) {
+			// no type path
+			if (this.contentsOffset + 1 >= this.contents.length) {
+				resizeContents(1);
+			}
+			this.contents[this.contentsOffset++] = (byte) 0;
+		} else {
+			int length = locations.length;
+			if (this.contentsOffset + length >= this.contents.length) {
+				resizeContents(length + 1);
+			}
+			this.contents[this.contentsOffset++] = (byte) (locations.length / 2);
+			for (int i = 0; i < length; i++) {
+				this.contents[this.contentsOffset++] = (byte) locations[i];
+			}
+		}
+	}
+	private void dumpTargetTypeContents(int targetType, AnnotationContext annotationContext) {
+		switch(targetType) {
+			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
+			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
+				// parameter index
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				break;
+
+			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
+				// type_parameter_index
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				// bound_index
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
+				break;				
+			case AnnotationTargetTypeConstants.FIELD :
+			case AnnotationTargetTypeConstants.METHOD_RECEIVER :
+			case AnnotationTargetTypeConstants.METHOD_RETURN :
+				 // target_info is empty_target
+				break;
+			case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
+				// target_info is parameter index
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				break;
+				
+			case AnnotationTargetTypeConstants.INSTANCEOF :
+			case AnnotationTargetTypeConstants.NEW :
+			case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
+			case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
+			case AnnotationTargetTypeConstants.METHOD_REFERENCE :
+				// bytecode offset for new/instanceof/method_reference
+				// exception table entry index for exception_parameter
+				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				break;
+			case AnnotationTargetTypeConstants.CAST :
+				// bytecode offset
+				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				// type_argument_index not set for cast
+				this.contents[this.contentsOffset++] = (byte)0;
+				break;
+				
+			case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+			case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+			case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+			case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+				// bytecode offset
+				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				// type_argument_index 
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
+				break;
+				
+			case AnnotationTargetTypeConstants.CLASS_EXTENDS :
+			case AnnotationTargetTypeConstants.THROWS :			
+				// For CLASS_EXTENDS - info is supertype index (-1 = superclass)
+				// For THROWS - info is exception table index
+				this.contents[this.contentsOffset++] = (byte) (annotationContext.info >> 8);
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				break;
+				
+			case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
+			case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
+				int localVariableTableOffset = this.contentsOffset;
+				LocalVariableBinding localVariable = annotationContext.variableBinding;
+				int actualSize = 0;
+				int initializationCount = localVariable.initializationCount;
+				actualSize += 6 * initializationCount;
+				// reserve enough space
+				if (this.contentsOffset + actualSize >= this.contents.length) {
+					resizeContents(actualSize);
+				}
+				this.contentsOffset += 2;
+				int numberOfEntries = 0;
+				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
+						// now we can safely add the local entry
+						numberOfEntries++;
+						this.contents[this.contentsOffset++] = (byte) (startPC >> 8);
+						this.contents[this.contentsOffset++] = (byte) startPC;
+						int length = endPC - startPC;
+						this.contents[this.contentsOffset++] = (byte) (length >> 8);
+						this.contents[this.contentsOffset++] = (byte) length;
+						int resolvedPosition = localVariable.resolvedPosition;
+						this.contents[this.contentsOffset++] = (byte) (resolvedPosition >> 8);
+						this.contents[this.contentsOffset++] = (byte) resolvedPosition;
+					}
+				}
+				this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
+				this.contents[localVariableTableOffset] = (byte) numberOfEntries;
+				break;
+			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info;
+				this.contents[this.contentsOffset++] = (byte) annotationContext.info2;
+				break;
+		}
+	}
+
+
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods returns a char[] representing the file name of the receiver
+	 *
+	 * @return char[]
+	 */
+	public char[] fileName() {
+		return this.constantPool.UTF8Cache.returnKeyFor(2);
+	}
+
+	private void generateAnnotation(Annotation annotation, int currentOffset) {
+		int startingContentsOffset = currentOffset;
+		if (this.contentsOffset + 4 >= this.contents.length) {
+			resizeContents(4);
+		}
+		TypeBinding annotationTypeBinding = annotation.resolvedType;
+		if (annotationTypeBinding == null) {
+			this.contentsOffset = startingContentsOffset;
+			return;
+		}
+		if (annotationTypeBinding.isMemberType()) {
+			this.recordInnerClasses(annotationTypeBinding);
+		}
+		final int typeIndex = this.constantPool.literalIndex(annotationTypeBinding.signature());
+		this.contents[this.contentsOffset++] = (byte) (typeIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) typeIndex;
+		if (annotation instanceof NormalAnnotation) {
+			NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
+			MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
+			if (memberValuePairs != null) {
+				final int memberValuePairsLength = memberValuePairs.length;
+				this.contents[this.contentsOffset++] = (byte) (memberValuePairsLength >> 8);
+				this.contents[this.contentsOffset++] = (byte) memberValuePairsLength;
+				for (int i = 0; i < memberValuePairsLength; i++) {
+					MemberValuePair memberValuePair = memberValuePairs[i];
+					if (this.contentsOffset + 2 >= this.contents.length) {
+						resizeContents(2);
+					}
+					final int elementNameIndex = this.constantPool.literalIndex(memberValuePair.name);
+					this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
+					this.contents[this.contentsOffset++] = (byte) elementNameIndex;
+					MethodBinding methodBinding = memberValuePair.binding;
+					if (methodBinding == null) {
+						this.contentsOffset = startingContentsOffset;
+					} else {
+						try {
+							generateElementValue(memberValuePair.value, methodBinding.returnType, startingContentsOffset);
+						} catch(ClassCastException e) {
+							this.contentsOffset = startingContentsOffset;
+						} catch(ShouldNotImplement e) {
+							this.contentsOffset = startingContentsOffset;
+						}
+					}
+				}
+			} else {
+				this.contents[this.contentsOffset++] = 0;
+				this.contents[this.contentsOffset++] = 0;
+			}
+		} else if (annotation instanceof SingleMemberAnnotation) {
+			SingleMemberAnnotation singleMemberAnnotation = (SingleMemberAnnotation) annotation;
+			// this is a single member annotation (one member value)
+			this.contents[this.contentsOffset++] = 0;
+			this.contents[this.contentsOffset++] = 1;
+			if (this.contentsOffset + 2 >= this.contents.length) {
+				resizeContents(2);
+			}
+			final int elementNameIndex = this.constantPool.literalIndex(VALUE);
+			this.contents[this.contentsOffset++] = (byte) (elementNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) elementNameIndex;
+			MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
+			if (methodBinding == null) {
+				this.contentsOffset = startingContentsOffset;
+			} else {
+				try {
+					generateElementValue(singleMemberAnnotation.memberValue, methodBinding.returnType, startingContentsOffset);
+				} catch(ClassCastException e) {
+					this.contentsOffset = startingContentsOffset;
+				} catch(ShouldNotImplement e) {
+					this.contentsOffset = startingContentsOffset;
+				}
+			}
+		} else {
+			// this is a marker annotation (no member value pairs)
+			this.contents[this.contentsOffset++] = 0;
+			this.contents[this.contentsOffset++] = 0;
+		}
+	}
+
+	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.
+	 * - the index inside the constant pool for the attribute name ("Code")
+	 * - leave some space for attribute_length(4), max_stack(2), max_locals(2), code_length(4).
+	 */
+	public void generateCodeAttributeHeader() {
+		if (this.contentsOffset + 20 >= this.contents.length) {
+			resizeContents(20);
+		}
+		int constantValueNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.CodeName);
+		this.contents[this.contentsOffset++] = (byte) (constantValueNameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) constantValueNameIndex;
+		// 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;
+						int max = fieldDecls == null ? 0 : fieldDecls.length;
+						for (int i = 0; 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,
+			int attributeOffset) {
+		Constant constant = defaultValue.constant;
+		TypeBinding defaultValueBinding = defaultValue.resolvedType;
+		if (defaultValueBinding == null) {
+			this.contentsOffset = attributeOffset;
+		} else {
+			if (defaultValueBinding.isMemberType()) {
+				this.recordInnerClasses(defaultValueBinding);
+			}
+			if (memberValuePairReturnType.isMemberType()) {
+				this.recordInnerClasses(memberValuePairReturnType);
+			}
+			if (memberValuePairReturnType.isArrayType() && !defaultValueBinding.isArrayType()) {
+				// automatic wrapping
+				if (this.contentsOffset + 3 >= this.contents.length) {
+					resizeContents(3);
+				}
+				this.contents[this.contentsOffset++] = (byte) '[';
+				this.contents[this.contentsOffset++] = (byte) 0;
+				this.contents[this.contentsOffset++] = (byte) 1;
+			}
+			if (constant != null && constant != Constant.NotAConstant) {
+				generateElementValue(attributeOffset, defaultValue, constant, memberValuePairReturnType.leafComponentType());
+			} else {
+				generateElementValueForNonConstantExpression(defaultValue, attributeOffset, defaultValueBinding);
+			}
+		}
+	}
+	/**
+	 * @param attributeOffset
+	 */
+	private void generateElementValue(int attributeOffset, Expression defaultValue, Constant constant, TypeBinding binding) {
+		if (this.contentsOffset + 3 >= this.contents.length) {
+			resizeContents(3);
+		}
+		switch (binding.id) {
+			case T_boolean :
+				this.contents[this.contentsOffset++] = (byte) 'Z';
+				int booleanValueIndex =
+					this.constantPool.literalIndex(constant.booleanValue() ? 1 : 0);
+				this.contents[this.contentsOffset++] = (byte) (booleanValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) booleanValueIndex;
+				break;
+			case T_byte :
+				this.contents[this.contentsOffset++] = (byte) 'B';
+				int integerValueIndex =
+					this.constantPool.literalIndex(constant.intValue());
+				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
+				break;
+			case T_char :
+				this.contents[this.contentsOffset++] = (byte) 'C';
+				integerValueIndex =
+					this.constantPool.literalIndex(constant.intValue());
+				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
+				break;
+			case T_int :
+				this.contents[this.contentsOffset++] = (byte) 'I';
+				integerValueIndex =
+					this.constantPool.literalIndex(constant.intValue());
+				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
+				break;
+			case T_short :
+				this.contents[this.contentsOffset++] = (byte) 'S';
+				integerValueIndex =
+					this.constantPool.literalIndex(constant.intValue());
+				this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) integerValueIndex;
+				break;
+			case T_float :
+				this.contents[this.contentsOffset++] = (byte) 'F';
+				int floatValueIndex =
+					this.constantPool.literalIndex(constant.floatValue());
+				this.contents[this.contentsOffset++] = (byte) (floatValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) floatValueIndex;
+				break;
+			case T_double :
+				this.contents[this.contentsOffset++] = (byte) 'D';
+				int doubleValueIndex =
+					this.constantPool.literalIndex(constant.doubleValue());
+				this.contents[this.contentsOffset++] = (byte) (doubleValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) doubleValueIndex;
+				break;
+			case T_long :
+				this.contents[this.contentsOffset++] = (byte) 'J';
+				int longValueIndex =
+					this.constantPool.literalIndex(constant.longValue());
+				this.contents[this.contentsOffset++] = (byte) (longValueIndex >> 8);
+				this.contents[this.contentsOffset++] = (byte) longValueIndex;
+				break;
+			case T_JavaLangString :
+				this.contents[this.contentsOffset++] = (byte) 's';
+				int stringValueIndex =
+					this.constantPool.literalIndex(((StringConstant) constant).stringValue().toCharArray());
+				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;
+						typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(defaultValue);
+					} else {
+						// already inside a problem type creation : no attribute
+						this.contentsOffset = attributeOffset;
+					}
+				} else {
+					this.contents[this.contentsOffset++] = (byte) (stringValueIndex >> 8);
+					this.contents[this.contentsOffset++] = (byte) stringValueIndex;
+				}
+		}
+	}
+	
+	private void generateElementValueForNonConstantExpression(Expression defaultValue, int attributeOffset, TypeBinding defaultValueBinding) {
+		if (defaultValueBinding != null) {
+			if (defaultValueBinding.isEnum()) {
+				if (this.contentsOffset + 5 >= this.contents.length) {
+					resizeContents(5);
+				}
+				this.contents[this.contentsOffset++] = (byte) 'e';
+				FieldBinding fieldBinding = null;
+				if (defaultValue instanceof QualifiedNameReference) {
+					QualifiedNameReference nameReference = (QualifiedNameReference) defaultValue;
+					fieldBinding = (FieldBinding) nameReference.binding;
+				} else if (defaultValue instanceof SingleNameReference) {
+					SingleNameReference nameReference = (SingleNameReference) defaultValue;
+					fieldBinding = (FieldBinding) nameReference.binding;
+				} else {
+					this.contentsOffset = attributeOffset;
+				}
+				if (fieldBinding != null) {
+					final int enumConstantTypeNameIndex = this.constantPool.literalIndex(fieldBinding.type.signature());
+					final int enumConstantNameIndex = this.constantPool.literalIndex(fieldBinding.name);
+					this.contents[this.contentsOffset++] = (byte) (enumConstantTypeNameIndex >> 8);
+					this.contents[this.contentsOffset++] = (byte) enumConstantTypeNameIndex;
+					this.contents[this.contentsOffset++] = (byte) (enumConstantNameIndex >> 8);
+					this.contents[this.contentsOffset++] = (byte) enumConstantNameIndex;
+				}
+			} else if (defaultValueBinding.isAnnotationType()) {
+				if (this.contentsOffset + 1 >= this.contents.length) {
+					resizeContents(1);
+				}
+				this.contents[this.contentsOffset++] = (byte) '@';
+				generateAnnotation((Annotation) defaultValue, attributeOffset);
+			} else if (defaultValueBinding.isArrayType()) {
+				// array type
+				if (this.contentsOffset + 3 >= this.contents.length) {
+					resizeContents(3);
+				}
+				this.contents[this.contentsOffset++] = (byte) '[';
+				if (defaultValue instanceof ArrayInitializer) {
+					ArrayInitializer arrayInitializer = (ArrayInitializer) defaultValue;
+					int arrayLength = arrayInitializer.expressions != null ? arrayInitializer.expressions.length : 0;
+					this.contents[this.contentsOffset++] = (byte) (arrayLength >> 8);
+					this.contents[this.contentsOffset++] = (byte) arrayLength;
+					for (int i = 0; i < arrayLength; i++) {
+						generateElementValue(arrayInitializer.expressions[i], defaultValueBinding.leafComponentType(), attributeOffset);
+					}
+				} else {
+					this.contentsOffset = attributeOffset;
+				}
+			} else {
+				// class type
+				if (this.contentsOffset + 3 >= this.contents.length) {
+					resizeContents(3);
+				}
+				this.contents[this.contentsOffset++] = (byte) 'c';
+				if (defaultValue instanceof ClassLiteralAccess) {
+					ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) defaultValue;
+					final int classInfoIndex = this.constantPool.literalIndex(classLiteralAccess.targetType.signature());
+					this.contents[this.contentsOffset++] = (byte) (classInfoIndex >> 8);
+					this.contents[this.contentsOffset++] = (byte) classInfoIndex;
+				} else {
+					this.contentsOffset = attributeOffset;
+				}
+			}
+		} else {
+			this.contentsOffset = attributeOffset;
+		}
+	}
+
+	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) {
+				int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this));
+				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();
+			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()) {
+				int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
+				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 generateBootstrapMethods(List functionalExpressionList) {
+		/* See JVM spec 4.7.21
+		   The BootstrapMethods attribute has the following format:
+		   BootstrapMethods_attribute {
+		      u2 attribute_name_index;
+		      u4 attribute_length;
+		      u2 num_bootstrap_methods;
+		      {   u2 bootstrap_method_ref;
+		          u2 num_bootstrap_arguments;
+		          u2 bootstrap_arguments[num_bootstrap_arguments];
+		      } bootstrap_methods[num_bootstrap_methods];
+		 }
+		*/
+		// Record inner classes for MethodHandles$Lookup
+		ReferenceBinding methodHandlesLookup = this.referenceBinding.scope.getJavaLangInvokeMethodHandlesLookup();
+		if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE.
+		recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also
+		ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory(); 
+		int indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory, 
+				ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
+
+		int numberOfBootstraps = functionalExpressionList.size();
+		int localContentsOffset = this.contentsOffset;
+		// Generate the boot strap attribute - since we are only making lambdas and
+		// functional expressions, we know the size ahead of time - this less general
+		// than the full invokedynamic scope, but fine for Java 8
+		int exSize = 10 * numberOfBootstraps + 8;
+		if (exSize + localContentsOffset >= this.contents.length) {
+			resizeContents(exSize);
+		}
+		this.contentsOffset += exSize;
+		
+		int attributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.BootstrapMethodsName);
+		this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) attributeNameIndex;
+		int value = (numberOfBootstraps * 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) (numberOfBootstraps >> 8);
+		this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
+		for (int i = 0; i < numberOfBootstraps; i++) {
+			FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i);
+			this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8);
+			this.contents[localContentsOffset++] = (byte) indexForMetaFactory;
+			
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = (byte) 3;
+			
+			int functionalDescriptorIndex = this.constantPool.literalIndexForMethodHandle(functional.descriptor.original());
+			this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
+
+			int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
+			this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+
+			char [] instantiatedSignature = functional.descriptor.signature();
+			int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
+			this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+		}
+		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 != null ? this.codeStream.methodDeclaration.binding.declaringClass : this.codeStream.lambdaExpression.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.
+	 * They could be:
+	 * - an exception attribute for each try/catch found inside the method
+	 * - a deprecated attribute
+	 * - a synthetic attribute for synthetic access methods
+	 *
+	 * It returns the number of attributes created for the code attribute.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
+	 * @return <CODE>int</CODE>
+	 */
+	public int generateMethodInfoAttributes(MethodBinding methodBinding) {
+		// leave two bytes for the attribute_number
+		this.contentsOffset += 2;
+		if (this.contentsOffset + 2 >= this.contents.length) {
+			resizeContents(2);
+		}
+		// now we can handle all the attribute for that method info:
+		// it could be:
+		// - a CodeAttribute
+		// - a ExceptionAttribute
+		// - a DeprecatedAttribute
+		// - a SyntheticAttribute
+
+		// Exception attribute
+		ReferenceBinding[] thrownsExceptions;
+		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
+			attributesNumber += generateExceptionsAttribute(thrownsExceptions);
+		}
+		if (methodBinding.isDeprecated()) {
+			// Deprecated attribute
+			attributesNumber += generateDeprecatedAttribute();
+		}
+		if (this.targetJDK < ClassFileConstants.JDK1_5) {
+			if (methodBinding.isSynthetic()) {
+				attributesNumber += generateSyntheticAttribute();
+			}
+			if (methodBinding.isVarargs()) {
+				attributesNumber += generateVarargsAttribute();
+			}
+		}
+		// add signature attribute
+		char[] genericSignature = methodBinding.genericSignature();
+		if (genericSignature != null) {
+			attributesNumber += generateSignatureAttribute(genericSignature);
+		}
+		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
+			AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
+			if (methodDeclaration != null) {
+				Annotation[] annotations = methodDeclaration.annotations;
+				if (annotations != null) {
+					attributesNumber += generateRuntimeAnnotations(annotations);
+				}
+				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
+					Argument[] arguments = methodDeclaration.arguments;
+					if (arguments != null) {
+						attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
+					}
+				}
+			} else {
+				LambdaExpression lambda = methodBinding.sourceLambda();
+				if (lambda != null) {
+					if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
+						Argument[] arguments = lambda.arguments;
+						if (arguments != null) {
+							int parameterCount = methodBinding.parameters.length;
+							int argumentCount = arguments.length;
+							if (parameterCount > argumentCount) { // synthetics prefixed 
+								int redShift = parameterCount - argumentCount;
+								System.arraycopy(arguments, 0, arguments = new Argument[parameterCount], redShift, argumentCount);
+								for (int i = 0; i < redShift; i++)
+									arguments[i] = new Argument(CharOperation.NO_CHAR, 0, null, 0);
+							}
+							attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
+						}
+					}	
+				}
+			}
+		}
+		if ((methodBinding.tagBits & TagBits.HasMissingType) != 0) {
+			this.missingTypes = methodBinding.collectMissingTypes(this.missingTypes);
+		}
+		return attributesNumber;
+	}
+	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
+			attributesNumber += generateAnnotationDefaultAttribute(declaration, attributeOffset);
+		}
+		return attributesNumber;
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method generates the header of a method info:
+	 * The header consists in:
+	 * - the access flags
+	 * - the name index of the method name inside the constant pool
+	 * - the descriptor index of the signature of the method inside the constant pool.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
+	 */
+	public void generateMethodInfoHeader(MethodBinding methodBinding) {
+		generateMethodInfoHeader(methodBinding, methodBinding.modifiers);
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method generates the header of a method info:
+	 * The header consists in:
+	 * - the access flags
+	 * - the name index of the method name inside the constant pool
+	 * - the descriptor index of the signature of the method inside the constant pool.
+	 *
+	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
+	 * @param accessFlags the access flags
+	 */
+	public void generateMethodInfoHeader(MethodBinding methodBinding, int accessFlags) {
+		// check that there is enough space to write all the bytes for the method info corresponding
+		// to the @methodBinding
+		this.methodCount++; // add one more method
+		if (this.contentsOffset + 10 >= this.contents.length) {
+			resizeContents(10);
+		}
+		if (this.targetJDK < ClassFileConstants.JDK1_5) {
+			// pre 1.5, synthetic is an attribute, not a modifier
+			// pre 1.5, varargs is an attribute, not a modifier (-target jsr14 mode)
+			accessFlags &= ~(ClassFileConstants.AccSynthetic | ClassFileConstants.AccVarargs);
+		}
+		if ((methodBinding.tagBits & TagBits.ClearPrivateModifier) != 0) {
+			accessFlags &= ~ClassFileConstants.AccPrivate;
+		}
+		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
+		this.contents[this.contentsOffset++] = (byte) accessFlags;
+		int nameIndex = this.constantPool.literalIndex(methodBinding.selector);
+		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) nameIndex;
+		int descriptorIndex = this.constantPool.literalIndex(methodBinding.signature(this));
+		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * That method generates the method info header of a clinit:
+	 * The header consists in:
+	 * - the access flags (always default access + static)
+	 * - the name index of the method name (always <clinit>) inside the constant pool
+	 * - the descriptor index of the signature (always ()V) of the method inside the constant pool.
+	 */
+	public void generateMethodInfoHeaderForClinit() {
+		// check that there is enough space to write all the bytes for the method info corresponding
+		// to the @methodBinding
+		this.methodCount++; // add one more method
+		if (this.contentsOffset + 10 >= this.contents.length) {
+			resizeContents(10);
+		}
+		this.contents[this.contentsOffset++] = (byte) ((ClassFileConstants.AccDefault | ClassFileConstants.AccStatic) >> 8);
+		this.contents[this.contentsOffset++] = (byte) (ClassFileConstants.AccDefault | ClassFileConstants.AccStatic);
+		int nameIndex = this.constantPool.literalIndex(ConstantPool.Clinit);
+		this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) nameIndex;
+		int descriptorIndex =
+			this.constantPool.literalIndex(ConstantPool.ClinitSignature);
+		this.contents[this.contentsOffset++] = (byte) (descriptorIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) descriptorIndex;
+		// We know that we won't get more than 1 attribute: the code attribute
+		this.contents[this.contentsOffset++] = 0;
+		this.contents[this.contentsOffset++] = 1;
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * Generate the byte for problem method infos that correspond to missing abstract methods.
+	 * http://dev.eclipse.org/bugs/show_bug.cgi?id=3179
+	 *
+	 * @param methodDeclarations Array of all missing abstract methods
+	 */
+	public void generateMissingAbstractMethods(MethodDeclaration[] methodDeclarations, CompilationResult compilationResult) {
+		if (methodDeclarations != null) {
+			TypeDeclaration currentDeclaration = this.referenceBinding.scope.referenceContext;
+			int typeDeclarationSourceStart = currentDeclaration.sourceStart();
+			int typeDeclarationSourceEnd = currentDeclaration.sourceEnd();
+			for (int i = 0, max = methodDeclarations.length; i < max; i++) {
+				MethodDeclaration methodDeclaration = methodDeclarations[i];
+				MethodBinding methodBinding = methodDeclaration.binding;
+				 String readableName = new String(methodBinding.readableName());
+				 CategorizedProblem[] problems = compilationResult.problems;
+				 int problemsCount = compilationResult.problemCount;
+				for (int j = 0; j < problemsCount; j++) {
+					CategorizedProblem problem = problems[j];
+					if (problem != null
+							&& problem.getID() == IProblem.AbstractMethodMustBeImplemented
+							&& problem.getMessage().indexOf(readableName) != -1
+							&& problem.getSourceStart() >= typeDeclarationSourceStart
+							&& problem.getSourceEnd() <= typeDeclarationSourceEnd) {
+						// we found a match
+						addMissingAbstractProblemMethod(methodDeclaration, methodBinding, problem, compilationResult);
+					}
+				}
+			}
+		}
+	}
+
+	private void generateMissingTypesAttribute() {
+		int initialSize = this.missingTypes.size();
+		int[] missingTypesIndexes = new int[initialSize];
+		int numberOfMissingTypes = 0;
+		if (initialSize > 1) {
+			Collections.sort(this.missingTypes, new Comparator() {
+				public int compare(Object o1, Object o2) {
+					TypeBinding typeBinding1 = (TypeBinding) o1;
+					TypeBinding typeBinding2 = (TypeBinding) o2;
+					return CharOperation.compareTo(typeBinding1.constantPoolName(), typeBinding2.constantPoolName());
+				}
+			});
+		}
+		int previousIndex = 0;
+		next: for (int i = 0; i < initialSize; i++) {
+			int missingTypeIndex = this.constantPool.literalIndexForType((TypeBinding) this.missingTypes.get(i));
+			if (previousIndex == missingTypeIndex) {
+				continue next;
+			}
+			previousIndex = missingTypeIndex;
+			missingTypesIndexes[numberOfMissingTypes++] = missingTypeIndex;
+		}
+		// we don't need to resize as we interate from 0 to numberOfMissingTypes when recording the indexes in the .class file
+		int attributeLength = numberOfMissingTypes * 2 + 2;
+		if (this.contentsOffset + attributeLength + 6 >= this.contents.length) {
+			resizeContents(attributeLength + 6);
+		}
+		int missingTypesNameIndex = this.constantPool.literalIndex(AttributeNamesConstants.MissingTypesName);
+		this.contents[this.contentsOffset++] = (byte) (missingTypesNameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) missingTypesNameIndex;
+
+		// generate attribute length
+		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;
+
+		// generate number of missing types
+		this.contents[this.contentsOffset++] = (byte) (numberOfMissingTypes >> 8);
+		this.contents[this.contentsOffset++] = (byte) numberOfMissingTypes;
+		// generate entry for each missing type
+		for (int i = 0; i < numberOfMissingTypes; i++) {
+			int missingTypeIndex = missingTypesIndexes[i];
+			this.contents[this.contentsOffset++] = (byte) (missingTypeIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) missingTypeIndex;
+		}
+	}
+
+	/**
+	 * @param annotations
+	 * @return the number of attributes created while dumping the annotations in the .class file
+	 */
+	private int generateRuntimeAnnotations(final Annotation[] annotations) {
+		int attributesNumber = 0;
+		final int length = annotations.length;
+		int visibleAnnotationsCounter = 0;
+		int invisibleAnnotationsCounter = 0;
+
+		for (int i = 0; i < length; i++) {
+			Annotation annotation = annotations[i];
+			if (annotation.isRuntimeInvisible()) {
+				invisibleAnnotationsCounter++;
+			} else if (annotation.isRuntimeVisible()) {
+				visibleAnnotationsCounter++;
+			}
+		}
+
+		int annotationAttributeOffset = this.contentsOffset;
+		int constantPOffset = this.constantPool.currentOffset;
+		int constantPoolIndex = this.constantPool.currentIndex;
+		if (invisibleAnnotationsCounter != 0) {
+			if (this.contentsOffset + 10 >= this.contents.length) {
+				resizeContents(10);
+			}
+			int runtimeInvisibleAnnotationsAttributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			int annotationsLengthOffset = this.contentsOffset;
+			this.contentsOffset += 2; // leave space for the annotations length
+
+			int counter = 0;
+			loop: for (int i = 0; i < length; i++) {
+				if (invisibleAnnotationsCounter == 0) break loop;
+				Annotation annotation = annotations[i];
+				if (annotation.isRuntimeInvisible()) {
+					int currentAnnotationOffset = this.contentsOffset;
+					generateAnnotation(annotation, currentAnnotationOffset);
+					invisibleAnnotationsCounter--;
+					if (this.contentsOffset != currentAnnotationOffset) {
+						counter++;
+					}
+				}
+			}
+			if (counter != 0) {
+				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
+				this.contents[annotationsLengthOffset++] = (byte) counter;
+
+				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++;
+			} else {
+				this.contentsOffset = annotationAttributeOffset;
+				// reset the constant pool to its state before the clinit
+				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleAnnotationsName, constantPoolIndex, constantPOffset);
+			}
+		}
+
+		annotationAttributeOffset = this.contentsOffset;
+		constantPOffset = this.constantPool.currentOffset;
+		constantPoolIndex = this.constantPool.currentIndex;
+		if (visibleAnnotationsCounter != 0) {
+			if (this.contentsOffset + 10 >= this.contents.length) {
+				resizeContents(10);
+			}
+			int runtimeVisibleAnnotationsAttributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			int annotationsLengthOffset = this.contentsOffset;
+			this.contentsOffset += 2; // leave space for the annotations length
+
+			int counter = 0;
+			loop: for (int i = 0; i < length; i++) {
+				if (visibleAnnotationsCounter == 0) break loop;
+				Annotation annotation = annotations[i];
+				if (annotation.isRuntimeVisible()) {
+					visibleAnnotationsCounter--;
+					int currentAnnotationOffset = this.contentsOffset;
+					generateAnnotation(annotation, currentAnnotationOffset);
+					if (this.contentsOffset != currentAnnotationOffset) {
+						counter++;
+					}
+				}
+			}
+			if (counter != 0) {
+				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
+				this.contents[annotationsLengthOffset++] = (byte) counter;
+
+				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++;
+			} else {
+				this.contentsOffset = annotationAttributeOffset;
+				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleAnnotationsName, constantPoolIndex, constantPOffset);
+			}
+		}
+		return attributesNumber;
+	}
+	private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
+		final int argumentsLength = arguments.length;
+		final int VISIBLE_INDEX = 0;
+		final int INVISIBLE_INDEX = 1;
+		int invisibleParametersAnnotationsCounter = 0;
+		int visibleParametersAnnotationsCounter = 0;
+		int[][] annotationsCounters = new int[argumentsLength][2];
+		for (int i = 0; i < argumentsLength; i++) {
+			Argument argument = arguments[i];
+			Annotation[] annotations = argument.annotations;
+			if (annotations != null) {
+				for (int j = 0, max2 = annotations.length; j < max2; j++) {
+					Annotation annotation = annotations[j];
+					if (annotation.isRuntimeInvisible()) {
+						annotationsCounters[i][INVISIBLE_INDEX]++;
+						invisibleParametersAnnotationsCounter++;
+					} else if (annotation.isRuntimeVisible()) {
+						annotationsCounters[i][VISIBLE_INDEX]++;
+						visibleParametersAnnotationsCounter++;
+					}
+				}
+			}
+		}
+		int attributesNumber = 0;
+		int annotationAttributeOffset = this.contentsOffset;
+		if (invisibleParametersAnnotationsCounter != 0) {
+			int globalCounter = 0;
+			if (this.contentsOffset + 7 >= this.contents.length) {
+				resizeContents(7);
+			}
+			int attributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			this.contents[this.contentsOffset++] = (byte) argumentsLength;
+			for (int i = 0; i < argumentsLength; i++) {
+				if (this.contentsOffset + 2 >= this.contents.length) {
+					resizeContents(2);
+				}
+				if (invisibleParametersAnnotationsCounter == 0) {
+					this.contents[this.contentsOffset++] = (byte) 0;
+					this.contents[this.contentsOffset++] = (byte) 0;
+				} else {
+					final int numberOfInvisibleAnnotations = annotationsCounters[i][INVISIBLE_INDEX];
+					int invisibleAnnotationsOffset = this.contentsOffset;
+					// leave space for number of annotations
+					this.contentsOffset += 2;
+					int counter = 0;
+					if (numberOfInvisibleAnnotations != 0) {
+						Argument argument = arguments[i];
+						Annotation[] annotations = argument.annotations;
+						for (int j = 0, max = annotations.length; j < max; j++) {
+							Annotation annotation = annotations[j];
+							if (annotation.isRuntimeInvisible()) {
+								int currentAnnotationOffset = this.contentsOffset;
+								generateAnnotation(annotation, currentAnnotationOffset);
+								if (this.contentsOffset != currentAnnotationOffset) {
+									counter++;
+									globalCounter++;
+								}
+								invisibleParametersAnnotationsCounter--;
+							}
+						}
+					}
+					this.contents[invisibleAnnotationsOffset++] = (byte) (counter >> 8);
+					this.contents[invisibleAnnotationsOffset] = (byte) counter;
+				}
+			}
+			if (globalCounter != 0) {
+				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++;
+			} else {
+				// if globalCounter is 0, this means that the code generation for all visible annotations failed
+				this.contentsOffset = annotationAttributeOffset;
+			}
+		}
+		if (visibleParametersAnnotationsCounter != 0) {
+			int globalCounter = 0;
+			if (this.contentsOffset + 7 >= this.contents.length) {
+				resizeContents(7);
+			}
+			int attributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			this.contents[this.contentsOffset++] = (byte) argumentsLength;
+			for (int i = 0; i < argumentsLength; i++) {
+				if (this.contentsOffset + 2 >= this.contents.length) {
+					resizeContents(2);
+				}
+				if (visibleParametersAnnotationsCounter == 0) {
+					this.contents[this.contentsOffset++] = (byte) 0;
+					this.contents[this.contentsOffset++] = (byte) 0;
+				} else {
+					final int numberOfVisibleAnnotations = annotationsCounters[i][VISIBLE_INDEX];
+					int visibleAnnotationsOffset = this.contentsOffset;
+					// leave space for number of annotations
+					this.contentsOffset += 2;
+					int counter = 0;
+					if (numberOfVisibleAnnotations != 0) {
+						Argument argument = arguments[i];
+						Annotation[] annotations = argument.annotations;
+						for (int j = 0, max = annotations.length; j < max; j++) {
+							Annotation annotation = annotations[j];
+							if (annotation.isRuntimeVisible()) {
+								int currentAnnotationOffset = this.contentsOffset;
+								generateAnnotation(annotation, currentAnnotationOffset);
+								if (this.contentsOffset != currentAnnotationOffset) {
+									counter++;
+									globalCounter++;
+								}
+								visibleParametersAnnotationsCounter--;
+							}
+						}
+					}
+					this.contents[visibleAnnotationsOffset++] = (byte) (counter >> 8);
+					this.contents[visibleAnnotationsOffset] = (byte) counter;
+				}
+			}
+			if (globalCounter != 0) {
+				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++;
+			} else {
+				// if globalCounter is 0, this means that the code generation for all visible annotations failed
+				this.contentsOffset = annotationAttributeOffset;
+			}
+		}
+		return attributesNumber;
+	}
+	
+	/**
+	 * @param annotationContexts the given annotation contexts
+	 * @param visibleTypeAnnotationsNumber the given number of visible type annotations
+	 * @param invisibleTypeAnnotationsNumber the given number of invisible type annotations
+	 * @return the number of attributes created while dumping the annotations in the .class file
+	 */
+	private int generateRuntimeTypeAnnotations(
+			final AnnotationContext[] annotationContexts, 
+			int visibleTypeAnnotationsNumber, 
+			int invisibleTypeAnnotationsNumber) {
+		int attributesNumber = 0;
+		final int length = annotationContexts.length;
+
+		int visibleTypeAnnotationsCounter = visibleTypeAnnotationsNumber;
+		int invisibleTypeAnnotationsCounter = invisibleTypeAnnotationsNumber;
+		int annotationAttributeOffset = this.contentsOffset;
+		int constantPOffset = this.constantPool.currentOffset;
+		int constantPoolIndex = this.constantPool.currentIndex;
+		if (invisibleTypeAnnotationsCounter != 0) {
+			if (this.contentsOffset + 10 >= this.contents.length) {
+				resizeContents(10);
+			}
+			int runtimeInvisibleAnnotationsAttributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (runtimeInvisibleAnnotationsAttributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) runtimeInvisibleAnnotationsAttributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			int annotationsLengthOffset = this.contentsOffset;
+			this.contentsOffset += 2; // leave space for the annotations length
+
+			int counter = 0;
+			loop: for (int i = 0; i < length; i++) {
+				if (invisibleTypeAnnotationsCounter == 0) break loop;
+				AnnotationContext annotationContext = annotationContexts[i];
+				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+					int currentAnnotationOffset = this.contentsOffset;
+					generateTypeAnnotation(annotationContext, currentAnnotationOffset);
+					invisibleTypeAnnotationsCounter--;
+					if (this.contentsOffset != currentAnnotationOffset) {
+						counter++;
+					}
+				}
+			}
+			if (counter != 0) {
+				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
+				this.contents[annotationsLengthOffset++] = (byte) counter;
+
+				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++;
+			} else {
+				this.contentsOffset = annotationAttributeOffset;
+				// reset the constant pool to its state before the clinit
+				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeInvisibleTypeAnnotationsName, constantPoolIndex, constantPOffset);
+			}
+		}
+
+		annotationAttributeOffset = this.contentsOffset;
+		constantPOffset = this.constantPool.currentOffset;
+		constantPoolIndex = this.constantPool.currentIndex;
+		if (visibleTypeAnnotationsCounter != 0) {
+			if (this.contentsOffset + 10 >= this.contents.length) {
+				resizeContents(10);
+			}
+			int runtimeVisibleAnnotationsAttributeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName);
+			this.contents[this.contentsOffset++] = (byte) (runtimeVisibleAnnotationsAttributeNameIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) runtimeVisibleAnnotationsAttributeNameIndex;
+			int attributeLengthOffset = this.contentsOffset;
+			this.contentsOffset += 4; // leave space for the attribute length
+
+			int annotationsLengthOffset = this.contentsOffset;
+			this.contentsOffset += 2; // leave space for the annotations length
+
+			int counter = 0;
+			loop: for (int i = 0; i < length; i++) {
+				if (visibleTypeAnnotationsCounter == 0) break loop;
+				AnnotationContext annotationContext = annotationContexts[i];
+				if ((annotationContext.visibility & AnnotationContext.VISIBLE) != 0) {
+					visibleTypeAnnotationsCounter--;
+					int currentAnnotationOffset = this.contentsOffset;
+					generateTypeAnnotation(annotationContext, currentAnnotationOffset);
+					if (this.contentsOffset != currentAnnotationOffset) {
+						counter++;
+					}
+				}
+			}
+			if (counter != 0) {
+				this.contents[annotationsLengthOffset++] = (byte) (counter >> 8);
+				this.contents[annotationsLengthOffset++] = (byte) counter;
+
+				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++;
+			} else {
+				this.contentsOffset = annotationAttributeOffset;
+				this.constantPool.resetForAttributeName(AttributeNamesConstants.RuntimeVisibleTypeAnnotationsName, constantPoolIndex, constantPOffset);
+			}
+		}
+		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()) {
+			Map frames = new HashMap();
+			List realFrames = traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+			int numberOfFrames = realFrames.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) realFrames.get(0);
+				for (int j = 1; j < numberOfFrames; j++) {
+					// select next frame
+					currentFrame = (StackMapFrame) realFrames.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()) {
+			Map frames = new HashMap();
+			List realFrames = traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+			int numberOfFrames = realFrames.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) realFrames.get(0);
+				StackMapFrame prevFrame = null;
+				for (int j = 1; j < numberOfFrames; j++) {
+					// select next frame
+					prevFrame = currentFrame;
+					currentFrame = (StackMapFrame) realFrames.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 void generateTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
+		if (annotationContext.wildcard != null) {
+			generateWildcardTypeAnnotation(annotationContext, currentOffset);
+			return;
+		}
+		
+		int targetType = annotationContext.targetType;
+
+		int[] locations = Annotation.getLocations(
+			annotationContext.typeReference,
+			annotationContext.primaryAnnotations,
+			annotationContext.annotation,
+			annotationContext.annotationsOnDimensions,
+			annotationContext.dimensions);
+
+		if (this.contentsOffset + 5 >= this.contents.length) {
+			resizeContents(5);
+		}
+		this.contents[this.contentsOffset++] = (byte) targetType;
+		dumpTargetTypeContents(targetType, annotationContext);
+		dumpLocations(locations);
+		
+		// common part between type annotation and annotation
+		generateAnnotation(annotationContext.annotation, currentOffset);
+	}
+
+	private void generateWildcardTypeAnnotation(AnnotationContext annotationContext, int currentOffset) {
+		int targetType = annotationContext.targetType;
+
+		int[] locations = Annotation.getLocations(
+				annotationContext.typeReference,
+				null,
+				annotationContext.annotation,
+				null,
+				0);
+		// reserve enough space
+		if (this.contentsOffset + 5 >= this.contents.length) {
+			resizeContents(5);
+		}
+		this.contents[this.contentsOffset++] = (byte) targetType;
+		dumpTargetTypeContents(targetType, annotationContext);
+		dumpLocations(locations);
+		generateAnnotation(annotationContext.annotation, currentOffset);
+	}
+	
+	private int generateTypeAnnotationAttributeForTypeDeclaration() {
+		TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
+		if ((typeDeclaration.bits & ASTNode.HasTypeAnnotations) == 0) {
+			return 0;
+		}
+		int attributesNumber = 0;
+		int visibleTypeAnnotationsCounter = 0;
+		int invisibleTypeAnnotationsCounter = 0;
+		TypeReference superclass = typeDeclaration.superclass;
+		List allTypeAnnotationContexts = new ArrayList();
+		if (superclass != null && (superclass.bits & ASTNode.HasTypeAnnotations) != 0) {
+			superclass.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, -1, allTypeAnnotationContexts);
+		}
+		TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			for (int i = 0; i < superInterfaces.length; i++) {
+				TypeReference superInterface = superInterfaces[i];
+				if ((superInterface.bits & ASTNode.HasTypeAnnotations) == 0) {
+					continue;
+				}
+				superInterface.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_EXTENDS, i, allTypeAnnotationContexts);
+			}
+		}
+		TypeParameter[] typeParameters = typeDeclaration.typeParameters;
+		if (typeParameters != null) {
+			for (int i = 0, max = typeParameters.length; i < max; i++) {
+				TypeParameter typeParameter = typeParameters[i];
+				if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
+					typeParameter.getAllAnnotationContexts(AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER, i, allTypeAnnotationContexts);
+				}
+			}
+		}
+		int size = allTypeAnnotationContexts.size();
+		if (size != 0) {
+			AnnotationContext[] allTypeAnnotationContextsArray = new AnnotationContext[size];
+			allTypeAnnotationContexts.toArray(allTypeAnnotationContextsArray);
+			for (int j = 0, max = allTypeAnnotationContextsArray.length; j < max; j++) {
+				AnnotationContext annotationContext = allTypeAnnotationContextsArray[j];
+				if ((annotationContext.visibility & AnnotationContext.INVISIBLE) != 0) {
+					invisibleTypeAnnotationsCounter++;
+					allTypeAnnotationContexts.add(annotationContext);
+				} else {
+					visibleTypeAnnotationsCounter++;
+					allTypeAnnotationContexts.add(annotationContext);
+				}
+			}
+			attributesNumber += generateRuntimeTypeAnnotations(
+					allTypeAnnotationContextsArray,
+					visibleTypeAnnotationsCounter,
+					invisibleTypeAnnotationsCounter);
+		}
+		return attributesNumber;
+	}
+	
+	
+	
+
+	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
+	 *
+	 * This method encodes the receiver structure into a byte array which is the content of the classfile.
+	 * Returns the byte array that represents the encoded structure of the receiver.
+	 *
+	 * @return byte[]
+	 */
+	public byte[] getBytes() {
+		if (this.bytes == null) {
+			this.bytes = new byte[this.headerOffset + this.contentsOffset];
+			System.arraycopy(this.header, 0, this.bytes, 0, this.headerOffset);
+			System.arraycopy(this.contents, 0, this.bytes, this.headerOffset, this.contentsOffset);
+		}
+		return this.bytes;
+	}
+	/**
+	 * EXTERNAL API
+	 * Answer the compound name of the class file.
+	 * @return char[][]
+	 * e.g. {{java}, {util}, {Hashtable}}.
+	 */
+	public char[][] getCompoundName() {
+		return CharOperation.splitOn('/', fileName());
+	}
+
+	private int getParametersCount(char[] methodSignature) {
+		int i = CharOperation.indexOf('(', methodSignature);
+		i++;
+		char currentCharacter = methodSignature[i];
+		if (currentCharacter == ')') {
+			return 0;
+		}
+		int result = 0;
+		while (true) {
+			currentCharacter = methodSignature[i];
+			if (currentCharacter == ')') {
+				return result;
+			}
+			switch (currentCharacter) {
+				case '[':
+					// array type
+					int scanType = scanType(methodSignature, i + 1);
+					result++;
+					i = scanType + 1;
+					break;
+				case 'L':
+					scanType = CharOperation.indexOf(';', methodSignature,
+							i + 1);
+					result++;
+					i = scanType + 1;
+					break;
+				case 'Z':
+				case 'B':
+				case 'C':
+				case 'D':
+				case 'F':
+				case 'I':
+				case 'J':
+				case 'S':
+					result++;
+					i++;
+					break;
+				default:
+					throw new IllegalArgumentException("Invalid starting type character : " + currentCharacter); //$NON-NLS-1$
+			}
+		}
+	}
+
+	private char[] getReturnType(char[] methodSignature) {
+		// skip type parameters
+		int paren = CharOperation.lastIndexOf(')', methodSignature);
+		// there could be thrown exceptions behind, thus scan one type exactly
+		return CharOperation.subarray(methodSignature, paren + 1,
+				methodSignature.length);
+	}
+
+	private final int i4At(byte[] reference, int relativeOffset,
+			int structOffset) {
+		int position = relativeOffset + structOffset;
+		return ((reference[position++] & 0xFF) << 24)
+				+ ((reference[position++] & 0xFF) << 16)
+				+ ((reference[position++] & 0xFF) << 8)
+				+ (reference[position] & 0xFF);
+	}
+
+	protected void initByteArrays() {
+		int members = this.referenceBinding.methods().length + this.referenceBinding.fields().length;
+		this.header = new byte[INITIAL_HEADER_SIZE];
+		this.contents = new byte[members < 15 ? INITIAL_CONTENTS_SIZE : INITIAL_HEADER_SIZE];
+	}
+
+	public void initialize(SourceTypeBinding aType, ClassFile parentClassFile, boolean createProblemType) {
+		// generate the magic numbers inside the header
+		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
+		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
+		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
+		this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);
+
+		long targetVersion = this.targetJDK;
+		this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high
+		this.header[this.headerOffset++] = (byte) (targetVersion>> 0); // minor low
+		this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high
+		this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low
+
+		this.constantPoolOffset = this.headerOffset;
+		this.headerOffset += 2;
+		this.constantPool.initialize(this);
+
+		// Modifier manipulations for classfile
+		int accessFlags = aType.getAccessFlags();
+		if (aType.isPrivate()) { // rewrite private to non-public
+			accessFlags &= ~ClassFileConstants.AccPublic;
+		}
+		if (aType.isProtected()) { // rewrite protected into public
+			accessFlags |= ClassFileConstants.AccPublic;
+		}
+		// clear all bits that are illegal for a class or an interface
+		accessFlags
+			&= ~(
+				ClassFileConstants.AccStrictfp
+					| ClassFileConstants.AccProtected
+					| ClassFileConstants.AccPrivate
+					| ClassFileConstants.AccStatic
+					| ClassFileConstants.AccSynchronized
+					| ClassFileConstants.AccNative);
+
+		// set the AccSuper flag (has to be done after clearing AccSynchronized - since same value)
+		if (!aType.isInterface()) { // class or enum
+			accessFlags |= ClassFileConstants.AccSuper;
+		}
+		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
+
+		// now we continue to generate the bytes inside the contents array
+		this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
+		this.contents[this.contentsOffset++] = (byte) accessFlags;
+		int classNameIndex = this.constantPool.literalIndexForType(aType);
+		this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) classNameIndex;
+		int superclassNameIndex;
+		if (aType.isInterface()) {
+			superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
+		} else {
+			if (aType.superclass != null) {
+				 if ((aType.superclass.tagBits & TagBits.HasMissingType) != 0) {
+						superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
+				 } else {
+						superclassNameIndex = this.constantPool.literalIndexForType(aType.superclass);
+				 }
+			} else {
+				superclassNameIndex = 0;
+			}
+		}
+		this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
+		ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
+		int interfacesCount = superInterfacesBinding.length;
+		int interfacesCountPosition = this.contentsOffset;
+		this.contentsOffset += 2;
+		int interfaceCounter = 0;
+		for (int i = 0; i < interfacesCount; i++) {
+			ReferenceBinding binding = superInterfacesBinding[i];
+			if ((binding.tagBits & TagBits.HasMissingType) != 0) {
+				continue;
+			}
+			interfaceCounter++;
+			int interfaceIndex = this.constantPool.literalIndexForType(binding);
+			this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
+			this.contents[this.contentsOffset++] = (byte) interfaceIndex;
+		}
+		this.contents[interfacesCountPosition++] = (byte) (interfaceCounter >> 8);
+		this.contents[interfacesCountPosition] = (byte) interfaceCounter;
+		this.creatingProblemType = createProblemType;
+
+		// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
+		// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
+		this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
+	}
+
+	private void initializeDefaultLocals(StackMapFrame frame,
+			MethodBinding methodBinding,
+			int maxLocals,
+			int codeLength) {
+		if (maxLocals != 0) {
+			int resolvedPosition = 0;
+			// take into account enum constructor synthetic name+ordinal
+			final boolean isConstructor = methodBinding.isConstructor();
+			if (isConstructor || !methodBinding.isStatic()) {
+				LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false);
+				localVariableBinding.resolvedPosition = 0;
+				this.codeStream.record(localVariableBinding);
+				localVariableBinding.recordInitializationStartPC(0);
+				localVariableBinding.recordInitializationEndPC(codeLength);
+				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
+						isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT,
+						methodBinding.declaringClass));
+				resolvedPosition++;
+			}
+
+			if (isConstructor) {
+				if (methodBinding.declaringClass.isEnum()) {
+					LocalVariableBinding localVariableBinding = new LocalVariableBinding(" name".toCharArray(), this.referenceBinding.scope.getJavaLangString(), 0, false); //$NON-NLS-1$
+					localVariableBinding.resolvedPosition = resolvedPosition;
+					this.codeStream.record(localVariableBinding);
+					localVariableBinding.recordInitializationStartPC(0);
+					localVariableBinding.recordInitializationEndPC(codeLength);
+
+					frame.putLocal(resolvedPosition, new VerificationTypeInfo(
+							TypeIds.T_JavaLangString,
+							ConstantPool.JavaLangStringConstantPoolName));
+					resolvedPosition++;
+
+					localVariableBinding = new LocalVariableBinding(" ordinal".toCharArray(), TypeBinding.INT, 0, false); //$NON-NLS-1$
+					localVariableBinding.resolvedPosition = resolvedPosition;
+					this.codeStream.record(localVariableBinding);
+					localVariableBinding.recordInitializationStartPC(0);
+					localVariableBinding.recordInitializationEndPC(codeLength);
+					frame.putLocal(resolvedPosition, new VerificationTypeInfo(
+							TypeBinding.INT));
+					resolvedPosition++;
+				}
+
+				// take into account the synthetic parameters
+				if (methodBinding.declaringClass.isNestedType()) {
+					ReferenceBinding enclosingInstanceTypes[];
+					if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
+						for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
+							// an enclosingInstanceType can only be a reference
+							// binding. It cannot be
+							// LongBinding or DoubleBinding
+							LocalVariableBinding localVariableBinding = new LocalVariableBinding((" enclosingType" + i).toCharArray(), enclosingInstanceTypes[i], 0, false); //$NON-NLS-1$
+							localVariableBinding.resolvedPosition = resolvedPosition;
+							this.codeStream.record(localVariableBinding);
+							localVariableBinding.recordInitializationStartPC(0);
+							localVariableBinding.recordInitializationEndPC(codeLength);
+
+							frame.putLocal(resolvedPosition,
+									new VerificationTypeInfo(enclosingInstanceTypes[i]));
+							resolvedPosition++;
+						}
+					}
+
+					TypeBinding[] arguments;
+					if ((arguments = methodBinding.parameters) != null) {
+						for (int i = 0, max = arguments.length; i < max; i++) {
+							final TypeBinding typeBinding = arguments[i];
+							frame.putLocal(resolvedPosition,
+									new VerificationTypeInfo(typeBinding));
+							switch (typeBinding.id) {
+								case TypeIds.T_double:
+								case TypeIds.T_long:
+									resolvedPosition += 2;
+									break;
+								default:
+									resolvedPosition++;
+							}
+						}
+					}
+
+					SyntheticArgumentBinding syntheticArguments[];
+					if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
+						for (int i = 0, max = syntheticArguments.length; i < max; i++) {
+							final TypeBinding typeBinding = syntheticArguments[i].type;
+							LocalVariableBinding localVariableBinding = new LocalVariableBinding((" synthetic" + i).toCharArray(), typeBinding, 0, false); //$NON-NLS-1$
+							localVariableBinding.resolvedPosition = resolvedPosition;
+							this.codeStream.record(localVariableBinding);
+							localVariableBinding.recordInitializationStartPC(0);
+							localVariableBinding.recordInitializationEndPC(codeLength);
+
+							frame.putLocal(resolvedPosition,
+									new VerificationTypeInfo(typeBinding));
+							switch (typeBinding.id) {
+								case TypeIds.T_double:
+								case TypeIds.T_long:
+									resolvedPosition += 2;
+									break;
+								default:
+									resolvedPosition++;
+							}
+						}
+					}
+				} else {
+					TypeBinding[] arguments;
+					if ((arguments = methodBinding.parameters) != null) {
+						for (int i = 0, max = arguments.length; i < max; i++) {
+							final TypeBinding typeBinding = arguments[i];
+							frame.putLocal(resolvedPosition,
+									new VerificationTypeInfo(typeBinding));
+							switch (typeBinding.id) {
+								case TypeIds.T_double:
+								case TypeIds.T_long:
+									resolvedPosition += 2;
+									break;
+								default:
+									resolvedPosition++;
+							}
+						}
+					}
+				}
+			} else {
+				TypeBinding[] arguments;
+				if ((arguments = methodBinding.parameters) != null) {
+					for (int i = 0, max = arguments.length; i < max; i++) {
+						final TypeBinding typeBinding = arguments[i];
+						frame.putLocal(resolvedPosition,
+								new VerificationTypeInfo(typeBinding));
+						switch (typeBinding.id) {
+							case TypeIds.T_double:
+							case TypeIds.T_long:
+								resolvedPosition += 2;
+								break;
+							default:
+								resolvedPosition++;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void initializeLocals(boolean isStatic, int currentPC, StackMapFrame currentFrame) {
+		VerificationTypeInfo[] locals = currentFrame.locals;
+		int localsLength = locals.length;
+		int i = 0;
+		if (!isStatic) {
+			// we don't want to reset the first local if the method is not static
+			i = 1;
+		}
+		for (; i < localsLength; i++) {
+			locals[i] = null;
+		}
+		i = 0;
+		locals: for (int max = this.codeStream.allLocalsCounter; i < max; i++) {
+			LocalVariableBinding localVariable = this.codeStream.locals[i];
+			if (localVariable == null) continue;
+			int resolvedPosition = localVariable.resolvedPosition;
+			final TypeBinding localVariableTypeBinding = localVariable.type;
+			inits: for (int j = 0; j < localVariable.initializationCount; j++) {
+				int startPC = localVariable.initializationPCs[j << 1];
+				int endPC = localVariable.initializationPCs[(j << 1) + 1];
+				if (currentPC < startPC) {
+					continue inits;
+				} else if (currentPC < endPC) {
+					// the current local is an active local
+					if (currentFrame.locals[resolvedPosition] == null) {
+						currentFrame.locals[resolvedPosition] =
+								new VerificationTypeInfo(
+										localVariableTypeBinding);
+					}
+					continue locals;
+				}
+			}
+		}
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name
+	 * for all inner types of the receiver.
+	 * @return org.eclipse.jdt.internal.compiler.codegen.ClassFile
+	 */
+	public ClassFile outerMostEnclosingClassFile() {
+		ClassFile current = this;
+		while (current.enclosingClassFile != null)
+			current = current.enclosingClassFile;
+		return current;
+	}
+
+	public void recordInnerClasses(TypeBinding binding) {
+		if (this.innerClassesBindings == null) {
+			this.innerClassesBindings = new HashSet(INNER_CLASSES_SIZE);
+		}
+		ReferenceBinding innerClass = (ReferenceBinding) binding;
+		this.innerClassesBindings.add(innerClass.erasure());
+		ReferenceBinding enclosingType = innerClass.enclosingType();
+		while (enclosingType != null
+				&& enclosingType.isNestedType()) {
+			this.innerClassesBindings.add(enclosingType.erasure());
+			enclosingType = enclosingType.enclosingType();
+		}
+	}
+
+	public int recordBootstrapMethod(FunctionalExpression expression) {
+		if (this.bootstrapMethods == null) {
+			this.bootstrapMethods = new ArrayList();
+		}
+		this.bootstrapMethods.add(expression);
+		return this.bootstrapMethods.size() - 1;
+	}
+
+	public void reset(SourceTypeBinding typeBinding) {
+		// the code stream is reinitialized for each method
+		final CompilerOptions options = typeBinding.scope.compilerOptions();
+		this.referenceBinding = typeBinding;
+		this.isNestedType = typeBinding.isNestedType();
+		this.targetJDK = options.targetJDK;
+		this.produceAttributes = options.produceDebugAttributes;
+		if (this.targetJDK >= ClassFileConstants.JDK1_6) {
+			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
+			if (this.targetJDK >= ClassFileConstants.JDK1_8) {
+				this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
+			}
+		} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
+			this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
+			this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
+		}
+		this.bytes = null;
+		this.constantPool.reset();
+		this.codeStream.reset(this);
+		this.constantPoolOffset = 0;
+		this.contentsOffset = 0;
+		this.creatingProblemType = false;
+		this.enclosingClassFile = null;
+		this.headerOffset = 0;
+		this.methodCount = 0;
+		this.methodCountOffset = 0;
+		if (this.innerClassesBindings != null) {
+			this.innerClassesBindings.clear();
+		}
+		if (this.bootstrapMethods != null) {
+			this.bootstrapMethods.clear();
+		}
+		this.missingTypes = null;
+		this.visitedTypes = null;
+	}
+
+	/**
+	 * Resize the pool contents
+	 */
+	private final void resizeContents(int minimalSize) {
+		int length = this.contents.length;
+		int toAdd = length;
+		if (toAdd < minimalSize)
+			toAdd = minimalSize;
+		System.arraycopy(this.contents, 0, this.contents = new byte[length + toAdd], 0, length);
+	}
+
+	private VerificationTypeInfo retrieveLocal(int currentPC, int resolvedPosition) {
+		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
+			LocalVariableBinding localVariable = this.codeStream.locals[i];
+			if (localVariable == null) continue;
+			if (resolvedPosition == localVariable.resolvedPosition) {
+				inits: for (int j = 0; j < localVariable.initializationCount; j++) {
+					int startPC = localVariable.initializationPCs[j << 1];
+					int endPC = localVariable.initializationPCs[(j << 1) + 1];
+					if (currentPC < startPC) {
+						continue inits;
+					} else if (currentPC < endPC) {
+						// the current local is an active local
+						return new VerificationTypeInfo(localVariable.type);
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	private int scanType(char[] methodSignature, int index) {
+		switch (methodSignature[index]) {
+			case '[':
+				// array type
+				return scanType(methodSignature, index + 1);
+			case 'L':
+				return CharOperation.indexOf(';', methodSignature, index + 1);
+			case 'Z':
+			case 'B':
+			case 'C':
+			case 'D':
+			case 'F':
+			case 'I':
+			case 'J':
+			case 'S':
+				return index;
+			default:
+				throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods leaves the space for method counts recording.
+	 */
+	public void setForMethodInfos() {
+		// leave some space for the methodCount
+		this.methodCountOffset = this.contentsOffset;
+		this.contentsOffset += 2;
+	}
+	
+	private List filterFakeFrames(Set realJumpTargets, Map frames, int codeLength) {
+		// no more frame to generate
+		// filter out "fake" frames
+		realJumpTargets.remove(new Integer(codeLength));
+		List result = new ArrayList();
+		for (Iterator iterator = realJumpTargets.iterator(); iterator.hasNext(); ) {
+			Integer jumpTarget = (Integer) iterator.next();
+			StackMapFrame frame = (StackMapFrame) frames.get(jumpTarget);
+			if (frame != null) {
+				result.add(frame);
+			}
+		}
+		Collections.sort(result, new Comparator() {
+			public int compare(Object o1, Object o2) {
+				StackMapFrame frame = (StackMapFrame) o1;
+				StackMapFrame frame2 = (StackMapFrame) o2;
+				return frame.pc - frame2.pc;
+			}
+		});
+		return result;
+	}
+
+	public List traverse(MethodBinding methodBinding, int maxLocals, byte[] bytecodes, int codeOffset, int codeLength, Map frames, boolean isClinit) {
+		Set realJumpTarget = new HashSet(); 
+
+		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
+		int[] framePositions = stackMapFrameCodeStream.getFramePositions();
+		int pc = codeOffset;
+		int index;
+		int[] constantPoolOffsets = this.constantPool.offsets;
+		byte[] poolContents = this.constantPool.poolContent;
+
+		// set initial values for frame positions
+		int indexInFramePositions = 0;
+		int framePositionsLength = framePositions.length;
+		int currentFramePosition = framePositions[0];
+
+		// set initial values for stack depth markers
+		int indexInStackDepthMarkers = 0;
+		StackDepthMarker[] stackDepthMarkers = stackMapFrameCodeStream.getStackDepthMarkers();
+		int stackDepthMarkersLength = stackDepthMarkers == null ? 0 : stackDepthMarkers.length;
+		boolean hasStackDepthMarkers = stackDepthMarkersLength != 0;
+		StackDepthMarker stackDepthMarker = null;
+		if (hasStackDepthMarkers) {
+			stackDepthMarker = stackDepthMarkers[0];
+		}
+
+		// set initial values for stack markers (used only in cldc mode)
+		int indexInStackMarkers = 0;
+		StackMarker[] stackMarkers = stackMapFrameCodeStream.getStackMarkers();
+		int stackMarkersLength = stackMarkers == null ? 0 : stackMarkers.length;
+		boolean hasStackMarkers = stackMarkersLength != 0;
+		StackMarker stackMarker = null;
+		if (hasStackMarkers) {
+			stackMarker = stackMarkers[0];
+		}
+
+		// set initial values for exception markers
+		int indexInExceptionMarkers = 0;
+		ExceptionMarker[] exceptionMarkers= stackMapFrameCodeStream.getExceptionMarkers();
+		int exceptionsMarkersLength = exceptionMarkers == null ? 0 : exceptionMarkers.length;
+		boolean hasExceptionMarkers = exceptionsMarkersLength != 0;
+		ExceptionMarker exceptionMarker = null;
+		if (hasExceptionMarkers) {
+			exceptionMarker = exceptionMarkers[0];
+		}
+
+		StackMapFrame frame = new StackMapFrame(maxLocals);
+		if (!isClinit) {
+			initializeDefaultLocals(frame, methodBinding, maxLocals, codeLength);
+		}
+		frame.pc = -1;
+		add(frames, frame.duplicate());
+		addRealJumpTarget(realJumpTarget, -1);
+		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
+			ExceptionLabel exceptionLabel = this.codeStream.exceptionLabels[i];
+			if (exceptionLabel != null) {
+				addRealJumpTarget(realJumpTarget, exceptionLabel.position);
+			}
+		}
+		while (true) {
+			int currentPC = pc - codeOffset;
+			if (hasStackMarkers && stackMarker.pc == currentPC) {
+				VerificationTypeInfo[] infos = frame.stackItems;
+				VerificationTypeInfo[] tempInfos = new VerificationTypeInfo[frame.numberOfStackItems];
+				System.arraycopy(infos, 0, tempInfos, 0, frame.numberOfStackItems);
+				stackMarker.setInfos(tempInfos);
+			} else if (hasStackMarkers && stackMarker.destinationPC == currentPC) {
+				VerificationTypeInfo[] infos = stackMarker.infos;
+				frame.stackItems = infos;
+				frame.numberOfStackItems = infos.length;
+				indexInStackMarkers++;
+				if (indexInStackMarkers < stackMarkersLength) {
+					stackMarker = stackMarkers[indexInStackMarkers];
+				} else {
+					hasStackMarkers = false;
+				}
+			}
+			if (hasStackDepthMarkers && stackDepthMarker.pc == currentPC) {
+				TypeBinding typeBinding = stackDepthMarker.typeBinding;
+				if (typeBinding != null) {
+					if (stackDepthMarker.delta > 0) {
+						frame.addStackItem(new VerificationTypeInfo(typeBinding));
+					} else {
+						frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
+					}
+				} else {
+					frame.numberOfStackItems--;
+				}
+				indexInStackDepthMarkers++;
+				if (indexInStackDepthMarkers < stackDepthMarkersLength) {
+					stackDepthMarker = stackDepthMarkers[indexInStackDepthMarkers];
+				} else {
+					hasStackDepthMarkers = false;
+				}
+			}
+			if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
+				frame.numberOfStackItems = 0;
+				frame.addStackItem(new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_OBJECT, exceptionMarker.constantPoolName));
+				indexInExceptionMarkers++;
+				if (indexInExceptionMarkers < exceptionsMarkersLength) {
+					exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
+				} else {
+					hasExceptionMarkers = false;
+				}
+			}
+			if (currentFramePosition < currentPC) {
+				do {
+					indexInFramePositions++;
+					if (indexInFramePositions < framePositionsLength) {
+						currentFramePosition = framePositions[indexInFramePositions];
+					} else {
+						currentFramePosition = Integer.MAX_VALUE;
+					}
+				} while (currentFramePosition < currentPC);
+			}
+			if (currentFramePosition == currentPC) {
+				// need to build a new frame and create a stack map attribute entry
+				StackMapFrame currentFrame = frame.duplicate();
+				currentFrame.pc = currentPC;
+				// initialize locals
+				initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, currentFrame);
+				// insert a new frame
+				add(frames, currentFrame);
+				indexInFramePositions++;
+				if (indexInFramePositions < framePositionsLength) {
+					currentFramePosition = framePositions[indexInFramePositions];
+				} else {
+					currentFramePosition = Integer.MAX_VALUE;
+				}
+			}
+			byte opcode = (byte) u1At(bytecodes, 0, pc);
+			switch (opcode) {
+				case Opcodes.OPC_nop:
+					pc++;
+					break;
+				case Opcodes.OPC_aconst_null:
+					frame.addStackItem(TypeBinding.NULL);
+					pc++;
+					break;
+				case Opcodes.OPC_iconst_m1:
+				case Opcodes.OPC_iconst_0:
+				case Opcodes.OPC_iconst_1:
+				case Opcodes.OPC_iconst_2:
+				case Opcodes.OPC_iconst_3:
+				case Opcodes.OPC_iconst_4:
+				case Opcodes.OPC_iconst_5:
+					frame.addStackItem(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_lconst_0:
+				case Opcodes.OPC_lconst_1:
+					frame.addStackItem(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_fconst_0:
+				case Opcodes.OPC_fconst_1:
+				case Opcodes.OPC_fconst_2:
+					frame.addStackItem(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_dconst_0:
+				case Opcodes.OPC_dconst_1:
+					frame.addStackItem(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_bipush:
+					frame.addStackItem(TypeBinding.BYTE);
+					pc += 2;
+					break;
+				case Opcodes.OPC_sipush:
+					frame.addStackItem(TypeBinding.SHORT);
+					pc += 3;
+					break;
+				case Opcodes.OPC_ldc:
+					index = u1At(bytecodes, 1, pc);
+					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
+						case ClassFileConstants.StringTag:
+							frame
+									.addStackItem(new VerificationTypeInfo(
+											TypeIds.T_JavaLangString,
+											ConstantPool.JavaLangStringConstantPoolName));
+							break;
+						case ClassFileConstants.IntegerTag:
+							frame.addStackItem(TypeBinding.INT);
+							break;
+						case ClassFileConstants.FloatTag:
+							frame.addStackItem(TypeBinding.FLOAT);
+							break;
+						case ClassFileConstants.ClassTag:
+							frame.addStackItem(new VerificationTypeInfo(
+									TypeIds.T_JavaLangClass,
+									ConstantPool.JavaLangClassConstantPoolName));
+					}
+					pc += 2;
+					break;
+				case Opcodes.OPC_ldc_w:
+					index = u2At(bytecodes, 1, pc);
+					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
+						case ClassFileConstants.StringTag:
+							frame
+									.addStackItem(new VerificationTypeInfo(
+											TypeIds.T_JavaLangString,
+											ConstantPool.JavaLangStringConstantPoolName));
+							break;
+						case ClassFileConstants.IntegerTag:
+							frame.addStackItem(TypeBinding.INT);
+							break;
+						case ClassFileConstants.FloatTag:
+							frame.addStackItem(TypeBinding.FLOAT);
+							break;
+						case ClassFileConstants.ClassTag:
+							frame.addStackItem(new VerificationTypeInfo(
+									TypeIds.T_JavaLangClass,
+									ConstantPool.JavaLangClassConstantPoolName));
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_ldc2_w:
+					index = u2At(bytecodes, 1, pc);
+					switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
+						case ClassFileConstants.DoubleTag:
+							frame.addStackItem(TypeBinding.DOUBLE);
+							break;
+						case ClassFileConstants.LongTag:
+							frame.addStackItem(TypeBinding.LONG);
+							break;
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_iload:
+					frame.addStackItem(TypeBinding.INT);
+					pc += 2;
+					break;
+				case Opcodes.OPC_lload:
+					frame.addStackItem(TypeBinding.LONG);
+					pc += 2;
+					break;
+				case Opcodes.OPC_fload:
+					frame.addStackItem(TypeBinding.FLOAT);
+					pc += 2;
+					break;
+				case Opcodes.OPC_dload:
+					frame.addStackItem(TypeBinding.DOUBLE);
+					pc += 2;
+					break;
+				case Opcodes.OPC_aload:
+					index = u1At(bytecodes, 1, pc);
+					VerificationTypeInfo localsN = retrieveLocal(currentPC, index);
+					frame.addStackItem(localsN);
+					pc += 2;
+					break;
+				case Opcodes.OPC_iload_0:
+				case Opcodes.OPC_iload_1:
+				case Opcodes.OPC_iload_2:
+				case Opcodes.OPC_iload_3:
+					frame.addStackItem(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_lload_0:
+				case Opcodes.OPC_lload_1:
+				case Opcodes.OPC_lload_2:
+				case Opcodes.OPC_lload_3:
+					frame.addStackItem(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_fload_0:
+				case Opcodes.OPC_fload_1:
+				case Opcodes.OPC_fload_2:
+				case Opcodes.OPC_fload_3:
+					frame.addStackItem(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_dload_0:
+				case Opcodes.OPC_dload_1:
+				case Opcodes.OPC_dload_2:
+				case Opcodes.OPC_dload_3:
+					frame.addStackItem(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_aload_0:
+					VerificationTypeInfo locals0 = frame.locals[0];
+					if (locals0 == null || locals0.tag != VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
+						// special case to handle uninitialized object
+						locals0 = retrieveLocal(currentPC, 0);
+					}
+					frame.addStackItem(locals0);
+					pc++;
+					break;
+				case Opcodes.OPC_aload_1:
+					VerificationTypeInfo locals1 = retrieveLocal(currentPC, 1);
+					frame.addStackItem(locals1);
+					pc++;
+					break;
+				case Opcodes.OPC_aload_2:
+					VerificationTypeInfo locals2 = retrieveLocal(currentPC, 2);
+					frame.addStackItem(locals2);
+					pc++;
+					break;
+				case Opcodes.OPC_aload_3:
+					VerificationTypeInfo locals3 = retrieveLocal(currentPC, 3);
+					frame.addStackItem(locals3);
+					pc++;
+					break;
+				case Opcodes.OPC_iaload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_laload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_faload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_daload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_aaload:
+					frame.numberOfStackItems--;
+					frame.replaceWithElementType();
+					pc++;
+					break;
+				case Opcodes.OPC_baload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.BYTE);
+					pc++;
+					break;
+				case Opcodes.OPC_caload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.CHAR);
+					pc++;
+					break;
+				case Opcodes.OPC_saload:
+					frame.numberOfStackItems -=2;
+					frame.addStackItem(TypeBinding.SHORT);
+					pc++;
+					break;
+				case Opcodes.OPC_istore:
+				case Opcodes.OPC_lstore:
+				case Opcodes.OPC_fstore:
+				case Opcodes.OPC_dstore:
+					frame.numberOfStackItems--;
+					pc += 2;
+					break;
+				case Opcodes.OPC_astore:
+					index = u1At(bytecodes, 1, pc);
+					frame.numberOfStackItems--;
+					pc += 2;
+					break;
+				case Opcodes.OPC_astore_0:
+					frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					pc++;
+					break;
+				case Opcodes.OPC_astore_1:
+				case Opcodes.OPC_astore_2:
+				case Opcodes.OPC_astore_3:
+				case Opcodes.OPC_istore_0:
+				case Opcodes.OPC_istore_1:
+				case Opcodes.OPC_istore_2:
+				case Opcodes.OPC_istore_3:
+				case Opcodes.OPC_lstore_0:
+				case Opcodes.OPC_lstore_1:
+				case Opcodes.OPC_lstore_2:
+				case Opcodes.OPC_lstore_3:
+				case Opcodes.OPC_fstore_0:
+				case Opcodes.OPC_fstore_1:
+				case Opcodes.OPC_fstore_2:
+				case Opcodes.OPC_fstore_3:
+				case Opcodes.OPC_dstore_0:
+				case Opcodes.OPC_dstore_1:
+				case Opcodes.OPC_dstore_2:
+				case Opcodes.OPC_dstore_3:
+					frame.numberOfStackItems--;
+					pc++;
+					break;
+				case Opcodes.OPC_iastore:
+				case Opcodes.OPC_lastore:
+				case Opcodes.OPC_fastore:
+				case Opcodes.OPC_dastore:
+				case Opcodes.OPC_aastore:
+				case Opcodes.OPC_bastore:
+				case Opcodes.OPC_castore:
+				case Opcodes.OPC_sastore:
+					frame.numberOfStackItems-=3;
+					pc++;
+					break;
+				case Opcodes.OPC_pop:
+					frame.numberOfStackItems--;
+					pc++;
+					break;
+				case Opcodes.OPC_pop2:
+					int numberOfStackItems = frame.numberOfStackItems;
+					switch(frame.stackItems[numberOfStackItems - 1].id()) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							frame.numberOfStackItems--;
+							break;
+						default:
+							frame.numberOfStackItems -= 2;
+					}
+					pc++;
+					break;
+				case Opcodes.OPC_dup:
+					frame.addStackItem(frame.stackItems[frame.numberOfStackItems - 1]);
+					pc++;
+					break;
+				case Opcodes.OPC_dup_x1:
+					VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					frame.addStackItem(info);
+					frame.addStackItem(info2);
+					frame.addStackItem(info);
+					pc++;
+					break;
+				case Opcodes.OPC_dup_x2:
+					info = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					info2 = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					switch(info2.id()) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							frame.addStackItem(info);
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+							break;
+						default:
+							numberOfStackItems = frame.numberOfStackItems;
+							VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
+							frame.numberOfStackItems--;
+							frame.addStackItem(info);
+							frame.addStackItem(info3);
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+					}
+					pc++;
+					break;
+				case Opcodes.OPC_dup2:
+					info = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					switch(info.id()) {
+						case TypeIds.T_double :
+						case TypeIds.T_long :
+							frame.addStackItem(info);
+							frame.addStackItem(info);
+							break;
+						default:
+							info2 = frame.stackItems[frame.numberOfStackItems - 1];
+							frame.numberOfStackItems--;
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+					}
+					pc++;
+					break;
+				case Opcodes.OPC_dup2_x1:
+					info = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					info2 = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					switch(info.id()) {
+						case TypeIds.T_double :
+						case TypeIds.T_long :
+							frame.addStackItem(info);
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+							break;
+						default:
+							VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1];
+							frame.numberOfStackItems--;
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+							frame.addStackItem(info3);
+							frame.addStackItem(info2);
+							frame.addStackItem(info);
+					}
+					pc++;
+					break;
+				case Opcodes.OPC_dup2_x2:
+					numberOfStackItems = frame.numberOfStackItems;
+					info = frame.stackItems[numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					info2 = frame.stackItems[frame.numberOfStackItems - 1];
+					frame.numberOfStackItems--;
+					switch(info.id()) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							switch(info2.id()) {
+								case TypeIds.T_long :
+								case TypeIds.T_double :
+									// form 4
+									frame.addStackItem(info);
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+									break;
+								default:
+									// form 2
+									numberOfStackItems = frame.numberOfStackItems;
+									VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
+									frame.numberOfStackItems--;
+									frame.addStackItem(info);
+									frame.addStackItem(info3);
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+							}
+							break;
+						default:
+							numberOfStackItems = frame.numberOfStackItems;
+							VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
+							frame.numberOfStackItems--;
+							switch(info3.id()) {
+								case TypeIds.T_long :
+								case TypeIds.T_double :
+									// form 3
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+									frame.addStackItem(info3);
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+									break;
+								default:
+									// form 1
+									numberOfStackItems = frame.numberOfStackItems;
+									VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1];
+									frame.numberOfStackItems--;
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+									frame.addStackItem(info4);
+									frame.addStackItem(info3);
+									frame.addStackItem(info2);
+									frame.addStackItem(info);
+							}
+					}
+					pc++;
+					break;
+				case Opcodes.OPC_swap:
+					numberOfStackItems = frame.numberOfStackItems;
+					info = frame.stackItems[numberOfStackItems - 1];
+					info2 = frame.stackItems[numberOfStackItems - 2];
+					frame.stackItems[numberOfStackItems - 1] = info2;
+					frame.stackItems[numberOfStackItems - 2] = info;
+					pc++;
+					break;
+				case Opcodes.OPC_iadd:
+				case Opcodes.OPC_ladd:
+				case Opcodes.OPC_fadd:
+				case Opcodes.OPC_dadd:
+				case Opcodes.OPC_isub:
+				case Opcodes.OPC_lsub:
+				case Opcodes.OPC_fsub:
+				case Opcodes.OPC_dsub:
+				case Opcodes.OPC_imul:
+				case Opcodes.OPC_lmul:
+				case Opcodes.OPC_fmul:
+				case Opcodes.OPC_dmul:
+				case Opcodes.OPC_idiv:
+				case Opcodes.OPC_ldiv:
+				case Opcodes.OPC_fdiv:
+				case Opcodes.OPC_ddiv:
+				case Opcodes.OPC_irem:
+				case Opcodes.OPC_lrem:
+				case Opcodes.OPC_frem:
+				case Opcodes.OPC_drem:
+				case Opcodes.OPC_ishl:
+				case Opcodes.OPC_lshl:
+				case Opcodes.OPC_ishr:
+				case Opcodes.OPC_lshr:
+				case Opcodes.OPC_iushr:
+				case Opcodes.OPC_lushr:
+				case Opcodes.OPC_iand:
+				case Opcodes.OPC_land:
+				case Opcodes.OPC_ior:
+				case Opcodes.OPC_lor:
+				case Opcodes.OPC_ixor:
+				case Opcodes.OPC_lxor:
+					frame.numberOfStackItems--;
+					pc++;
+					break;
+				case Opcodes.OPC_ineg:
+				case Opcodes.OPC_lneg:
+				case Opcodes.OPC_fneg:
+				case Opcodes.OPC_dneg:
+					pc++;
+					break;
+				case Opcodes.OPC_iinc:
+					pc += 3;
+					break;
+				case Opcodes.OPC_i2l:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_i2f:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_i2d:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_l2i:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_l2f:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_l2d:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_f2i:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_f2l:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_f2d:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
+					pc++;
+					break;
+				case Opcodes.OPC_d2i:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_d2l:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
+					pc++;
+					break;
+				case Opcodes.OPC_d2f:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
+					pc++;
+					break;
+				case Opcodes.OPC_i2b:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE);
+					pc++;
+					break;
+				case Opcodes.OPC_i2c:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR);
+					pc++;
+					break;
+				case Opcodes.OPC_i2s:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT);
+					pc++;
+					break;
+				case Opcodes.OPC_lcmp:
+				case Opcodes.OPC_fcmpl:
+				case Opcodes.OPC_fcmpg:
+				case Opcodes.OPC_dcmpl:
+				case Opcodes.OPC_dcmpg:
+					frame.numberOfStackItems-=2;
+					frame.addStackItem(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_ifeq:
+				case Opcodes.OPC_ifne:
+				case Opcodes.OPC_iflt:
+				case Opcodes.OPC_ifge:
+				case Opcodes.OPC_ifgt:
+				case Opcodes.OPC_ifle:
+					frame.numberOfStackItems--;
+					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+					pc += 3;
+					break;
+				case Opcodes.OPC_if_icmpeq:
+				case Opcodes.OPC_if_icmpne:
+				case Opcodes.OPC_if_icmplt:
+				case Opcodes.OPC_if_icmpge:
+				case Opcodes.OPC_if_icmpgt:
+				case Opcodes.OPC_if_icmple:
+				case Opcodes.OPC_if_acmpeq:
+				case Opcodes.OPC_if_acmpne:
+					frame.numberOfStackItems -= 2;
+					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+					pc += 3;
+					break;
+				case Opcodes.OPC_goto:
+					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+					pc += 3;
+					addRealJumpTarget(realJumpTarget, pc - codeOffset);
+					break;
+				case Opcodes.OPC_tableswitch:
+					pc++;
+					while (((pc - codeOffset) & 0x03) != 0) {
+						pc++;
+					}
+					// default offset
+					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+					pc += 4; // default
+					int low = i4At(bytecodes, 0, pc);
+					pc += 4;
+					int high = i4At(bytecodes, 0, pc);
+					pc += 4;
+					int length = high - low + 1;
+					for (int i = 0; i < length; i++) {
+						// pair offset
+						addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+						pc += 4;
+					}
+					frame.numberOfStackItems--;
+					break;
+				case Opcodes.OPC_lookupswitch:
+					pc++;
+					while (((pc - codeOffset) & 0x03) != 0) {
+						pc++;
+					}
+					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+					pc += 4; // default offset
+					int npairs = (int) u4At(bytecodes, 0, pc);
+					pc += 4; // npair value
+					for (int i = 0; i < npairs; i++) {
+						pc += 4; // case value
+						// pair offset
+						addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 0, pc));
+						pc += 4;
+					}
+					frame.numberOfStackItems--;
+					break;
+				case Opcodes.OPC_ireturn:
+				case Opcodes.OPC_lreturn:
+				case Opcodes.OPC_freturn:
+				case Opcodes.OPC_dreturn:
+				case Opcodes.OPC_areturn:
+					frame.numberOfStackItems--;
+					pc++;
+					addRealJumpTarget(realJumpTarget, pc - codeOffset);
+					break;
+				case Opcodes.OPC_return:
+					pc++;
+					addRealJumpTarget(realJumpTarget, pc - codeOffset);
+					break;
+				case Opcodes.OPC_getstatic:
+					index = u2At(bytecodes, 1, pc);
+					int nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					int utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					char[] descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					if (descriptor.length == 1) {
+						// base type
+						switch(descriptor[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else if (descriptor[0] == '[') {
+						frame.addStackItem(new VerificationTypeInfo(0, descriptor));
+					} else {
+						frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_putstatic:
+					frame.numberOfStackItems--;
+					pc += 3;
+					break;
+				case Opcodes.OPC_getfield:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.numberOfStackItems--;
+					if (descriptor.length == 1) {
+						// base type
+						switch(descriptor[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else if (descriptor[0] == '[') {
+						frame.addStackItem(new VerificationTypeInfo(0, descriptor));
+					} else {
+						frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_putfield:
+					frame.numberOfStackItems -= 2;
+					pc += 3;
+					break;
+				case Opcodes.OPC_invokevirtual:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[nameAndTypeIndex]);
+					char[] name = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
+					char[] returnType = getReturnType(descriptor);
+					if (returnType.length == 1) {
+						// base type
+						switch(returnType[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else {
+						if (returnType[0] == '[') {
+							frame.addStackItem(new VerificationTypeInfo(0, returnType));
+						} else {
+							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
+						}
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_invokedynamic:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.numberOfStackItems -= getParametersCount(descriptor);
+					returnType = getReturnType(descriptor);
+					if (returnType.length == 1) {
+						// base type
+						switch(returnType[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else {
+						if (returnType[0] == '[') {
+							frame.addStackItem(new VerificationTypeInfo(0, returnType));
+						} else {
+							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
+						}
+					}
+					pc += 5;
+					break;
+				case Opcodes.OPC_invokespecial:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[nameAndTypeIndex]);
+					name = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.numberOfStackItems -= getParametersCount(descriptor);
+					if (CharOperation.equals(ConstantPool.Init, name)) {
+						// constructor
+						frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT;
+					}
+					frame.numberOfStackItems--;
+					returnType = getReturnType(descriptor);
+					if (returnType.length == 1) {
+						// base type
+						switch(returnType[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else {
+						if (returnType[0] == '[') {
+							frame.addStackItem(new VerificationTypeInfo(0, returnType));
+						} else {
+							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
+						}
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_invokestatic:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[nameAndTypeIndex]);
+					name = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.numberOfStackItems -= getParametersCount(descriptor);
+					returnType = getReturnType(descriptor);
+					if (returnType.length == 1) {
+						// base type
+						switch(returnType[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else {
+						if (returnType[0] == '[') {
+							frame.addStackItem(new VerificationTypeInfo(0, returnType));
+						} else {
+							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
+						}
+					}
+					pc += 3;
+					break;
+				case Opcodes.OPC_invokeinterface:
+					index = u2At(bytecodes, 1, pc);
+					nameAndTypeIndex = u2At(poolContents, 3,
+							constantPoolOffsets[index]);
+					utf8index = u2At(poolContents, 3,
+							constantPoolOffsets[nameAndTypeIndex]);
+					descriptor = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[nameAndTypeIndex]);
+					name = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					// we don't need count and args
+					// u1At(bytecodes, 3, pc); // count
+					// u1At(bytecodes, 4, pc); // extra args
+					frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
+					returnType = getReturnType(descriptor);
+					if (returnType.length == 1) {
+						// base type
+						switch(returnType[0]) {
+							case 'Z':
+								frame.addStackItem(TypeBinding.BOOLEAN);
+								break;
+							case 'B':
+								frame.addStackItem(TypeBinding.BYTE);
+								break;
+							case 'C':
+								frame.addStackItem(TypeBinding.CHAR);
+								break;
+							case 'D':
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case 'F':
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case 'I':
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case 'J':
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case 'S':
+								frame.addStackItem(TypeBinding.SHORT);
+								break;
+						}
+					} else {
+						if (returnType[0] == '[') {
+							frame.addStackItem(new VerificationTypeInfo(0, returnType));
+						} else {
+							frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
+						}
+					}
+					pc += 5;
+					break;
+				case Opcodes.OPC_new:
+					index = u2At(bytecodes, 1, pc);
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[index]);
+					char[] className = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_UNINITIALIZED, className);
+					verificationTypeInfo.offset = currentPC;
+					frame.addStackItem(verificationTypeInfo);
+					pc += 3;
+					break;
+				case Opcodes.OPC_newarray:
+					char[] constantPoolName = null;
+					switch (u1At(bytecodes, 1, pc)) {
+						case ClassFileConstants.INT_ARRAY :
+							constantPoolName = new char[] { '[', 'I' };
+							break;
+						case ClassFileConstants.BYTE_ARRAY :
+							constantPoolName = new char[] { '[', 'B' };
+							break;
+						case ClassFileConstants.BOOLEAN_ARRAY :
+							constantPoolName = new char[] { '[', 'Z' };
+							break;
+						case ClassFileConstants.SHORT_ARRAY :
+							constantPoolName = new char[] { '[', 'S' };
+							break;
+						case ClassFileConstants.CHAR_ARRAY :
+							constantPoolName = new char[] { '[', 'C' };
+							break;
+						case ClassFileConstants.LONG_ARRAY :
+							constantPoolName = new char[] { '[', 'J' };
+							break;
+						case ClassFileConstants.FLOAT_ARRAY :
+							constantPoolName = new char[] { '[', 'F' };
+							break;
+						case ClassFileConstants.DOUBLE_ARRAY :
+							constantPoolName = new char[] { '[', 'D' };
+							break;
+					}
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName);
+					pc += 2;
+					break;
+				case Opcodes.OPC_anewarray:
+					index = u2At(bytecodes, 1, pc);
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[index]);
+					className = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					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] = ';';
+					} 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);
+						constantPoolName[0] = '[';
+					}
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, constantPoolName);
+					pc += 3;
+					break;
+				case Opcodes.OPC_arraylength:
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
+					pc++;
+					break;
+				case Opcodes.OPC_athrow:
+					frame.numberOfStackItems--;
+					pc++;
+					addRealJumpTarget(realJumpTarget, pc - codeOffset);
+					break;
+				case Opcodes.OPC_checkcast:
+					index = u2At(bytecodes, 1, pc);
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[index]);
+					className = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, className);
+					pc += 3;
+					break;
+				case Opcodes.OPC_instanceof:
+					// no need to know the class index = u2At(bytecodes, 1, pc);
+					frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
+					pc += 3;
+					break;
+				case Opcodes.OPC_monitorenter:
+				case Opcodes.OPC_monitorexit:
+					frame.numberOfStackItems--;
+					pc++;
+					break;
+				case Opcodes.OPC_wide:
+					opcode = (byte) u1At(bytecodes, 1, pc);
+					if (opcode == Opcodes.OPC_iinc) {
+						// index = u2At(bytecodes, 2, pc);
+						// i2At(bytecodes, 4, pc); // const
+						// we don't need the index and the const value
+						pc += 6;
+					} else {
+						index = u2At(bytecodes, 2, pc);
+						// need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
+						switch(opcode) {
+							case Opcodes.OPC_iload :
+								frame.addStackItem(TypeBinding.INT);
+								break;
+							case Opcodes.OPC_fload :
+								frame.addStackItem(TypeBinding.FLOAT);
+								break;
+							case Opcodes.OPC_aload :
+								localsN = frame.locals[index];
+								if (localsN == null) {
+									localsN = retrieveLocal(currentPC, index);
+								}
+								frame.addStackItem(localsN);
+								break;
+							case Opcodes.OPC_lload :
+								frame.addStackItem(TypeBinding.LONG);
+								break;
+							case Opcodes.OPC_dload :
+								frame.addStackItem(TypeBinding.DOUBLE);
+								break;
+							case Opcodes.OPC_istore :
+								frame.numberOfStackItems--;
+								break;
+							case Opcodes.OPC_fstore :
+								frame.numberOfStackItems--;
+								break;
+							case Opcodes.OPC_astore :
+								frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1];
+								frame.numberOfStackItems--;
+								break;
+							case Opcodes.OPC_lstore :
+								frame.numberOfStackItems--;
+								break;
+							case Opcodes.OPC_dstore :
+								frame.numberOfStackItems--;
+								break;
+						}
+						pc += 4;
+					}
+					break;
+				case Opcodes.OPC_multianewarray:
+					index = u2At(bytecodes, 1, pc);
+					utf8index = u2At(poolContents, 1,
+							constantPoolOffsets[index]);
+					className = utf8At(poolContents,
+							constantPoolOffsets[utf8index] + 3, u2At(
+									poolContents, 1,
+									constantPoolOffsets[utf8index]));
+					int dimensions = u1At(bytecodes, 3, pc); // dimensions
+					frame.numberOfStackItems -= dimensions;
+					classNameLength = className.length;
+					constantPoolName = new char[classNameLength + dimensions];
+					for (int i = 0; i < dimensions; i++) {
+						constantPoolName[i] = '[';
+					}
+					System.arraycopy(className, 0, constantPoolName, dimensions, classNameLength);
+					frame.addStackItem(new VerificationTypeInfo(0, constantPoolName));
+					pc += 4;
+					break;
+				case Opcodes.OPC_ifnull:
+				case Opcodes.OPC_ifnonnull:
+					frame.numberOfStackItems--;
+					addRealJumpTarget(realJumpTarget, currentPC + i2At(bytecodes, 1, pc));
+					pc += 3;
+					break;
+				case Opcodes.OPC_goto_w:
+					addRealJumpTarget(realJumpTarget, currentPC + i4At(bytecodes, 1, pc));
+					pc += 5;
+					addRealJumpTarget(realJumpTarget, pc - codeOffset); // handle infinite loop
+					break;
+				default: // should not occur
+					if (this.codeStream.methodDeclaration != null) {
+						this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
+								Messages.bind(
+										Messages.abort_invalidOpcode,
+										new Object[] {
+												new Byte(opcode),
+												new Integer(pc),
+												new String(methodBinding.shortReadableName()),
+										}),
+										this.codeStream.methodDeclaration);
+					} else {
+						this.codeStream.lambdaExpression.scope.problemReporter().abortDueToInternalError(
+								Messages.bind(
+										Messages.abort_invalidOpcode,
+										new Object[] {
+												new Byte(opcode),
+												new Integer(pc),
+												new String(methodBinding.shortReadableName()),
+										}),
+										this.codeStream.lambdaExpression);
+					}
+				break;
+			}
+			if (pc >= (codeLength + codeOffset)) {
+				break;
+			}
+		}
+		return filterFakeFrames(realJumpTarget, frames, codeLength);
+	}
+
+	private void addRealJumpTarget(Set realJumpTarget, int pc) {
+		realJumpTarget.add(new Integer(pc));
+	}
+	private void add(Map frames, StackMapFrame frame) {
+		frames.put(new Integer(frame.pc), frame);
+	}
+	private final int u1At(byte[] reference, int relativeOffset,
+			int structOffset) {
+		return (reference[relativeOffset + structOffset] & 0xFF);
+	}
+
+	private final int u2At(byte[] reference, int relativeOffset,
+			int structOffset) {
+		int position = relativeOffset + structOffset;
+		return ((reference[position++] & 0xFF) << 8)
+				+ (reference[position] & 0xFF);
+	}
+
+	private final long u4At(byte[] reference, int relativeOffset,
+			int structOffset) {
+		int position = relativeOffset + structOffset;
+		return (((reference[position++] & 0xFFL) << 24)
+				+ ((reference[position++] & 0xFF) << 16)
+				+ ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
+	}
+
+	private final int i2At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return (reference[position++] << 8) + (reference[position] & 0xFF);
+	}
+
+	public char[] utf8At(byte[] reference, int absoluteOffset,
+			int bytesAvailable) {
+		int length = bytesAvailable;
+		char outputBuf[] = new char[bytesAvailable];
+		int outputPos = 0;
+		int readOffset = absoluteOffset;
+
+		while (length != 0) {
+			int x = reference[readOffset++] & 0xFF;
+			length--;
+			if ((0x80 & x) != 0) {
+				if ((x & 0x20) != 0) {
+					length -= 2;
+					x = ((x & 0xF) << 12)
+							| ((reference[readOffset++] & 0x3F) << 6)
+							| (reference[readOffset++] & 0x3F);
+				} else {
+					length--;
+					x = ((x & 0x1F) << 6) | (reference[readOffset++] & 0x3F);
+				}
+			}
+			outputBuf[outputPos++] = (char) x;
+		}
+
+		if (outputPos != bytesAvailable) {
+			System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]),
+					0, outputPos);
+		}
+		return outputBuf;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFilePool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFilePool.java
new file mode 100644
index 0000000..37aeb71
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFilePool.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.Arrays;
+
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+
+public class ClassFilePool {
+	public static final int POOL_SIZE = 25; // need to have enough for 2 units
+	ClassFile[] classFiles;
+
+private ClassFilePool() {
+	// prevent instantiation
+	this.classFiles = new ClassFile[POOL_SIZE];
+}
+
+public static ClassFilePool newInstance() {
+	return new ClassFilePool();
+}
+
+public synchronized ClassFile acquire(SourceTypeBinding typeBinding) {
+	for (int i = 0; i < POOL_SIZE; i++) {
+		ClassFile classFile = this.classFiles[i];
+		if (classFile == null) {
+			ClassFile newClassFile = new ClassFile(typeBinding);
+			this.classFiles[i] = newClassFile;
+			newClassFile.isShared = true;
+			return newClassFile;
+		}
+		if (!classFile.isShared) {
+			classFile.reset(typeBinding);
+			classFile.isShared = true;
+			return classFile;
+		}
+	}
+	return new ClassFile(typeBinding);
+}
+public synchronized void release(ClassFile classFile) {
+	classFile.isShared = false;
+}
+public void reset() {
+	Arrays.fill(this.classFiles, null);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
new file mode 100644
index 0000000..7635c97
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
@@ -0,0 +1,460 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+/**
+ * A compilation result consists of all information returned by the compiler for
+ * a single compiled compilation source unit.  This includes:
+ * <ul>
+ * <li> the compilation unit that was compiled
+ * <li> for each type produced by compiling the compilation unit, its binary and optionally its principal structure
+ * <li> any problems (errors or warnings) produced
+ * <li> dependency info
+ * </ul>
+ *
+ * The principle structure and binary may be null if the compiler could not produce them.
+ * If neither could be produced, there is no corresponding entry for the type.
+ *
+ * The dependency info includes type references such as supertypes, field types, method
+ * parameter and return types, local variable types, types of intermediate expressions, etc.
+ * It also includes the namespaces (packages) in which names were looked up.
+ * It does <em>not</em> include finer grained dependencies such as information about
+ * specific fields and methods which were referenced, but does contain their
+ * declaring types and any other types used to locate such fields or methods.
+ */
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CompilationResult {
+
+	public CategorizedProblem problems[];
+	public CategorizedProblem tasks[];
+	public int problemCount;
+	public int taskCount;
+	public ICompilationUnit compilationUnit;
+	private Map problemsMap;
+	private Set firstErrors;
+	private int maxProblemPerUnit;
+	public char[][][] qualifiedReferences;
+	public char[][] simpleNameReferences;
+	public char[][] rootReferences;
+	public boolean hasAnnotations = false;
+	public int lineSeparatorPositions[];
+	public RecoveryScannerData recoveryScannerData;
+	public Map compiledTypes = new Hashtable(11);
+	public int unitIndex, totalUnitsKnown;
+	public boolean hasBeenAccepted = false;
+	public char[] fileName;
+	public boolean hasInconsistentToplevelHierarchies = false; // record the fact some toplevel types have inconsistent hierarchies
+	public boolean hasSyntaxError = false;
+	public char[][] packageName;
+	public boolean checkSecondaryTypes = false; // check for secondary types which were created after the initial buildTypeBindings call
+	private int numberOfErrors;
+	private boolean hasMandatoryErrors;
+
+	private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
+	private static final Comparator PROBLEM_COMPARATOR = new Comparator() {
+		public int compare(Object o1, Object o2) {
+			return ((CategorizedProblem) o1).getSourceStart() - ((CategorizedProblem) o2).getSourceStart();
+		}
+	};
+
+public CompilationResult(char[] fileName, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
+	this.fileName = fileName;
+	this.unitIndex = unitIndex;
+	this.totalUnitsKnown = totalUnitsKnown;
+	this.maxProblemPerUnit = maxProblemPerUnit;
+}
+
+public CompilationResult(ICompilationUnit compilationUnit, int unitIndex, int totalUnitsKnown, int maxProblemPerUnit){
+	this.fileName = compilationUnit.getFileName();
+	this.compilationUnit = compilationUnit;
+	this.unitIndex = unitIndex;
+	this.totalUnitsKnown = totalUnitsKnown;
+	this.maxProblemPerUnit = maxProblemPerUnit;
+}
+
+private int computePriority(CategorizedProblem problem){
+	final int P_STATIC = 10000;
+	final int P_OUTSIDE_METHOD = 40000;
+	final int P_FIRST_ERROR = 20000;
+	final int P_ERROR = 100000;
+
+	int priority = 10000 - problem.getSourceLineNumber(); // early problems first
+	if (priority < 0) priority = 0;
+	if (problem.isError()){
+		priority += P_ERROR;
+	}
+	ReferenceContext context = this.problemsMap == null ? null : (ReferenceContext) this.problemsMap.get(problem);
+	if (context != null){
+		if (context instanceof AbstractMethodDeclaration){
+			AbstractMethodDeclaration method = (AbstractMethodDeclaration) context;
+			if (method.isStatic()) {
+				priority += P_STATIC;
+			}
+		} else {
+			priority += P_OUTSIDE_METHOD;
+		}
+		if (this.firstErrors.contains(problem)){ // if context is null, firstErrors is null too
+		  priority += P_FIRST_ERROR;
+	    }
+	} else {
+		priority += P_OUTSIDE_METHOD;
+	}
+	return priority;
+}
+
+public CategorizedProblem[] getAllProblems() {
+	CategorizedProblem[] onlyProblems = getProblems();
+	int onlyProblemCount = onlyProblems != null ? onlyProblems.length : 0;
+	CategorizedProblem[] onlyTasks = getTasks();
+	int onlyTaskCount = onlyTasks != null ? onlyTasks.length : 0;
+	if (onlyTaskCount == 0) {
+		return onlyProblems;
+	}
+	if (onlyProblemCount == 0) {
+		return onlyTasks;
+	}
+	int totalNumberOfProblem = onlyProblemCount + onlyTaskCount;
+	CategorizedProblem[] allProblems = new CategorizedProblem[totalNumberOfProblem];
+	int allProblemIndex = 0;
+	int taskIndex = 0;
+	int problemIndex = 0;
+	while (taskIndex + problemIndex < totalNumberOfProblem) {
+		CategorizedProblem nextTask = null;
+		CategorizedProblem nextProblem = null;
+		if (taskIndex < onlyTaskCount) {
+			nextTask = onlyTasks[taskIndex];
+		}
+		if (problemIndex < onlyProblemCount) {
+			nextProblem = onlyProblems[problemIndex];
+		}
+		// select the next problem
+		CategorizedProblem currentProblem = null;
+		if (nextProblem != null) {
+			if (nextTask != null) {
+				if (nextProblem.getSourceStart() < nextTask.getSourceStart()) {
+					currentProblem = nextProblem;
+					problemIndex++;
+				} else {
+					currentProblem = nextTask;
+					taskIndex++;
+				}
+			} else {
+				currentProblem = nextProblem;
+				problemIndex++;
+			}
+		} else {
+			if (nextTask != null) {
+				currentProblem = nextTask;
+				taskIndex++;
+			}
+		}
+		allProblems[allProblemIndex++] = currentProblem;
+	}
+	return allProblems;
+}
+
+public ClassFile[] getClassFiles() {
+	ClassFile[] classFiles = new ClassFile[this.compiledTypes.size()];
+	this.compiledTypes.values().toArray(classFiles);
+	return classFiles;
+}
+
+/**
+ * Answer the initial compilation unit corresponding to the present compilation result
+ */
+public ICompilationUnit getCompilationUnit(){
+	return this.compilationUnit;
+}
+
+/**
+ * Answer the errors encountered during compilation.
+ */
+public CategorizedProblem[] getErrors() {
+	CategorizedProblem[] reportedProblems = getProblems();
+	int errorCount = 0;
+	for (int i = 0; i < this.problemCount; i++) {
+		if (reportedProblems[i].isError()) errorCount++;
+	}
+	if (errorCount == this.problemCount) return reportedProblems;
+	CategorizedProblem[] errors = new CategorizedProblem[errorCount];
+	int index = 0;
+	for (int i = 0; i < this.problemCount; i++) {
+		if (reportedProblems[i].isError()) errors[index++] = reportedProblems[i];
+	}
+	return errors;
+}
+
+
+/**
+ * Answer the initial file name
+ */
+public char[] getFileName(){
+	return this.fileName;
+}
+
+public int[] getLineSeparatorPositions() {
+	return this.lineSeparatorPositions == null ? CompilationResult.EMPTY_LINE_ENDS : this.lineSeparatorPositions;
+}
+
+/**
+ * Answer the problems (errors and warnings) encountered during compilation.
+ *
+ * This is not a compiler internal API - it has side-effects !
+ * It is intended to be used only once all problems have been detected,
+ * and makes sure the problems slot as the exact size of the number of
+ * problems.
+ */
+public CategorizedProblem[] getProblems() {
+	// Re-adjust the size of the problems if necessary.
+	if (this.problems != null) {
+		if (this.problemCount != this.problems.length) {
+			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
+		}
+
+		if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
+			quickPrioritize(this.problems, 0, this.problemCount - 1);
+			this.problemCount = this.maxProblemPerUnit;
+			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
+		}
+
+		// Stable sort problems per source positions.
+		Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
+		//quickSort(problems, 0, problems.length-1);
+	}
+	return this.problems;
+}
+/**
+ * Same as getProblems() but don't answer problems that actually concern the enclosing package.
+ */
+public CategorizedProblem[] getCUProblems() {
+	// Re-adjust the size of the problems if necessary and filter package problems
+	if (this.problems != null) {
+		CategorizedProblem[] filteredProblems = new CategorizedProblem[this.problemCount];
+		int keep = 0;
+		for (int i=0; i< this.problemCount; i++) {
+			CategorizedProblem problem = this.problems[i];
+			if (problem.getID() != IProblem.MissingNonNullByDefaultAnnotationOnPackage) {
+				filteredProblems[keep++] = problem;
+			} else if (this.compilationUnit != null) {
+				if (CharOperation.equals(this.compilationUnit.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
+					filteredProblems[keep++] = problem;
+				}
+			}
+		}
+		if (keep < this.problemCount) {
+			System.arraycopy(filteredProblems, 0, filteredProblems = new CategorizedProblem[keep], 0, keep);
+			this.problemCount = keep;
+		}
+		this.problems = filteredProblems;
+		if (this.maxProblemPerUnit > 0 && this.problemCount > this.maxProblemPerUnit){
+			quickPrioritize(this.problems, 0, this.problemCount - 1);
+			this.problemCount = this.maxProblemPerUnit;
+			System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount]), 0, this.problemCount);
+		}
+
+		// Stable sort problems per source positions.
+		Arrays.sort(this.problems, 0, this.problems.length, CompilationResult.PROBLEM_COMPARATOR);
+		//quickSort(problems, 0, problems.length-1);
+	}
+	return this.problems;
+}
+
+/**
+ * Answer the tasks (TO-DO, ...) encountered during compilation.
+ *
+ * This is not a compiler internal API - it has side-effects !
+ * It is intended to be used only once all problems have been detected,
+ * and makes sure the problems slot as the exact size of the number of
+ * problems.
+ */
+public CategorizedProblem[] getTasks() {
+	// Re-adjust the size of the tasks if necessary.
+	if (this.tasks != null) {
+
+		if (this.taskCount != this.tasks.length) {
+			System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount]), 0, this.taskCount);
+		}
+		// Stable sort problems per source positions.
+		Arrays.sort(this.tasks, 0, this.tasks.length, CompilationResult.PROBLEM_COMPARATOR);
+		//quickSort(tasks, 0, tasks.length-1);
+	}
+	return this.tasks;
+}
+
+public boolean hasErrors() {
+	return this.numberOfErrors != 0;
+}
+
+public boolean hasMandatoryErrors() {
+	return this.hasMandatoryErrors;
+}
+
+public boolean hasProblems() {
+	return this.problemCount != 0;
+}
+
+public boolean hasTasks() {
+	return this.taskCount != 0;
+}
+
+public boolean hasWarnings() {
+	if (this.problems != null)
+		for (int i = 0; i < this.problemCount; i++) {
+			if (this.problems[i].isWarning())
+				return true;
+		}
+	return false;
+}
+
+private void quickPrioritize(CategorizedProblem[] problemList, int left, int right) {
+	if (left >= right) return;
+	// sort the problems by their priority... starting with the highest priority
+	int original_left = left;
+	int original_right = right;
+	int mid = computePriority(problemList[left + (right - left) / 2]);
+	do {
+		while (computePriority(problemList[right]) < mid)
+			right--;
+		while (mid < computePriority(problemList[left]))
+			left++;
+		if (left <= right) {
+			CategorizedProblem tmp = problemList[left];
+			problemList[left] = problemList[right];
+			problemList[right] = tmp;
+			left++;
+			right--;
+		}
+	} while (left <= right);
+	if (original_left < right)
+		quickPrioritize(problemList, original_left, right);
+	if (left < original_right)
+		quickPrioritize(problemList, left, original_right);
+}
+
+/*
+ * Record the compilation unit result's package name
+ */
+public void recordPackageName(char[][] packName) {
+	this.packageName = packName;
+}
+
+public void record(CategorizedProblem newProblem, ReferenceContext referenceContext) {
+	record(newProblem, referenceContext, true);
+	return;
+}
+
+public void record(CategorizedProblem newProblem, ReferenceContext referenceContext, boolean mandatoryError) {
+	//new Exception("VERBOSE PROBLEM REPORTING").printStackTrace();
+	if(newProblem.getID() == IProblem.Task) {
+		recordTask(newProblem);
+		return;
+	}
+	if (this.problemCount == 0) {
+		this.problems = new CategorizedProblem[5];
+	} else if (this.problemCount == this.problems.length) {
+		System.arraycopy(this.problems, 0, (this.problems = new CategorizedProblem[this.problemCount * 2]), 0, this.problemCount);
+	}
+	this.problems[this.problemCount++] = newProblem;
+	if (referenceContext != null){
+		if (this.problemsMap == null) this.problemsMap = new HashMap(5);
+		if (this.firstErrors == null) this.firstErrors = new HashSet(5);
+		if (newProblem.isError() && !referenceContext.hasErrors()) this.firstErrors.add(newProblem);
+		this.problemsMap.put(newProblem, referenceContext);
+	}
+	if (newProblem.isError()) {
+		this.numberOfErrors++;
+		if (mandatoryError) this.hasMandatoryErrors = true;
+		if ((newProblem.getID() & IProblem.Syntax) != 0) {
+			this.hasSyntaxError = true;
+		}
+	}
+}
+
+/**
+ * For now, remember the compiled type using its compound name.
+ */
+public void record(char[] typeName, ClassFile classFile) {
+    SourceTypeBinding sourceType = classFile.referenceBinding;
+    if (!sourceType.isLocalType() && sourceType.isHierarchyInconsistent()) {
+        this.hasInconsistentToplevelHierarchies = true;
+    }
+	this.compiledTypes.put(typeName, classFile);
+}
+
+private void recordTask(CategorizedProblem newProblem) {
+	if (this.taskCount == 0) {
+		this.tasks = new CategorizedProblem[5];
+	} else if (this.taskCount == this.tasks.length) {
+		System.arraycopy(this.tasks, 0, (this.tasks = new CategorizedProblem[this.taskCount * 2]), 0, this.taskCount);
+	}
+	this.tasks[this.taskCount++] = newProblem;
+}
+public void removeProblem(CategorizedProblem problem) {
+	if (this.problemsMap != null) this.problemsMap.remove(problem);
+	if (this.firstErrors != null) this.firstErrors.remove(problem);
+	if (problem.isError()) {
+		this.numberOfErrors--;
+	}
+	this.problemCount--;
+}
+public CompilationResult tagAsAccepted(){
+	this.hasBeenAccepted = true;
+	this.problemsMap = null; // flush
+	this.firstErrors = null; // flush
+	return this;
+}
+
+public String toString(){
+	StringBuffer buffer = new StringBuffer();
+	if (this.fileName != null){
+		buffer.append("Filename : ").append(this.fileName).append('\n'); //$NON-NLS-1$
+	}
+	if (this.compiledTypes != null){
+		buffer.append("COMPILED type(s)	\n");  //$NON-NLS-1$
+		Iterator keys = this.compiledTypes.keySet().iterator();
+		while (keys.hasNext()) {
+			char[] typeName = (char[]) keys.next();
+			buffer.append("\t - ").append(typeName).append('\n');   //$NON-NLS-1$
+
+		}
+	} else {
+		buffer.append("No COMPILED type\n");  //$NON-NLS-1$
+	}
+	if (this.problems != null){
+		buffer.append(this.problemCount).append(" PROBLEM(s) detected \n"); //$NON-NLS-1$
+		for (int i = 0; i < this.problemCount; i++){
+			buffer.append("\t - ").append(this.problems[i]).append('\n'); //$NON-NLS-1$
+		}
+	} else {
+		buffer.append("No PROBLEM\n"); //$NON-NLS-1$
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
new file mode 100644
index 0000000..00ff614
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
@@ -0,0 +1,972 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contributions for 
+ *     							bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+ *     							bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+import java.io.*;
+import java.util.*;
+
+public class Compiler implements ITypeRequestor, ProblemSeverities {
+	public Parser parser;
+	public ICompilerRequestor requestor;
+	public CompilerOptions options;
+	public ProblemReporter problemReporter;
+	protected PrintWriter out; // output for messages that are not sent to problemReporter
+	public CompilerStats stats;
+	public CompilationProgress progress;
+	public int remainingIterations = 1;
+
+	// management of unit to be processed
+	//public CompilationUnitResult currentCompilationUnitResult;
+	public CompilationUnitDeclaration[] unitsToProcess;
+	public int totalUnits; // (totalUnits-1) gives the last unit in unitToProcess
+
+	// name lookup
+	public LookupEnvironment lookupEnvironment;
+
+	// ONCE STABILIZED, THESE SHOULD RETURN TO A FINAL FIELD
+	public static boolean DEBUG = false;
+	public int parseThreshold = -1;
+
+	public AbstractAnnotationProcessorManager annotationProcessorManager;
+	public int annotationProcessorStartIndex = 0;
+	public ReferenceBinding[] referenceBindings;
+	public boolean useSingleThread = true; // by default the compiler will not use worker threads to read/process/write
+
+	// number of initial units parsed at once (-1: none)
+
+	/*
+	 * Static requestor reserved to listening compilation results in debug mode,
+	 * so as for example to monitor compiler activity independantly from a particular
+	 * builder implementation. It is reset at the end of compilation, and should not
+	 * persist any information after having been reset.
+	 */
+	public static IDebugRequestor DebugRequestor = null;
+
+	/**
+	 * Answer a new compiler using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (e.g. in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *  @param settings java.util.Map
+	 *      The settings that control the compiler behavior.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 *
+	 *  @deprecated this constructor is kept to preserve 3.1 and 3.2M4 compatibility
+	 */
+	public Compiler(
+			INameEnvironment environment,
+			IErrorHandlingPolicy policy,
+			Map settings,
+			final ICompilerRequestor requestor,
+			IProblemFactory problemFactory) {
+		this(environment, policy, new CompilerOptions(settings), requestor, problemFactory, null /* printwriter */, null /* progress */);
+	}
+
+	/**
+	 * Answer a new compiler using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (e.g. in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *  @param settings java.util.Map
+	 *      The settings that control the compiler behavior.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 *
+	 *  @param parseLiteralExpressionsAsConstants <code>boolean</code>
+	 *		This parameter is used to optimize the literals or leave them as they are in the source.
+	 * 		If you put true, "Hello" + " world" will be converted to "Hello world".
+	 *
+	 *  @deprecated this constructor is kept to preserve 3.1 and 3.2M4 compatibility
+	 */
+	public Compiler(
+			INameEnvironment environment,
+			IErrorHandlingPolicy policy,
+			Map settings,
+			final ICompilerRequestor requestor,
+			IProblemFactory problemFactory,
+			boolean parseLiteralExpressionsAsConstants) {
+		this(environment, policy, new CompilerOptions(settings, parseLiteralExpressionsAsConstants), requestor, problemFactory, null /* printwriter */, null /* progress */);
+	}
+
+	/**
+	 * Answer a new compiler using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (e.g. in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *  @param options org.eclipse.jdt.internal.compiler.impl.CompilerOptions
+	 *      The options that control the compiler behavior.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 */
+	public Compiler(
+		INameEnvironment environment,
+		IErrorHandlingPolicy policy,
+		CompilerOptions options,
+		final ICompilerRequestor requestor,
+		IProblemFactory problemFactory) {
+		this(environment, policy, options, requestor, problemFactory, null /* printwriter */, null /* progress */);
+	}
+
+	/**
+	 * Answer a new compiler using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (e.g. in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *  @param options org.eclipse.jdt.internal.compiler.impl.CompilerOptions
+	 *      The options that control the compiler behavior.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 * @deprecated
+	 */
+	public Compiler(
+			INameEnvironment environment,
+			IErrorHandlingPolicy policy,
+			CompilerOptions options,
+			final ICompilerRequestor requestor,
+			IProblemFactory problemFactory,
+			PrintWriter out) {
+		this(environment, policy, options, requestor, problemFactory, out, null /* progress */);
+	}
+
+	public Compiler(
+			INameEnvironment environment,
+			IErrorHandlingPolicy policy,
+			CompilerOptions options,
+			final ICompilerRequestor requestor,
+			IProblemFactory problemFactory,
+			PrintWriter out,
+			CompilationProgress progress) {
+
+		this.options = options;
+		this.progress = progress;
+
+		// wrap requestor in DebugRequestor if one is specified
+		if(DebugRequestor == null) {
+			this.requestor = requestor;
+		} else {
+			this.requestor = new ICompilerRequestor(){
+				public void acceptResult(CompilationResult result){
+					if (DebugRequestor.isActive()){
+						DebugRequestor.acceptDebugResult(result);
+					}
+					requestor.acceptResult(result);
+				}
+			};
+		}
+		this.problemReporter = new ProblemReporter(policy, this.options, problemFactory);
+		this.lookupEnvironment = new LookupEnvironment(this, this.options, this.problemReporter, environment);
+		this.out = out == null ? new PrintWriter(System.out, true) : out;
+		this.stats = new CompilerStats();
+		initializeParser();
+	}
+
+	/**
+	 * Add an additional binary type
+	 */
+	public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		if (this.options.verbose) {
+			this.out.println(
+				Messages.bind(Messages.compilation_loadBinary, new String(binaryType.getName())));
+//			new Exception("TRACE BINARY").printStackTrace(System.out);
+//		    System.out.println();
+		}
+		this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
+	}
+
+	/**
+	 * Add an additional compilation unit into the loop
+	 *  ->  build compilation unit declarations, their bindings and record their results.
+	 */
+	public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+		// Switch the current policy and compilation result for this unit to the requested one.
+		CompilationResult unitResult =
+			new CompilationResult(sourceUnit, this.totalUnits, this.totalUnits, this.options.maxProblemsPerUnit);
+		unitResult.checkSecondaryTypes = true;
+		try {
+			if (this.options.verbose) {
+				String count = String.valueOf(this.totalUnits + 1);
+				this.out.println(
+					Messages.bind(Messages.compilation_request,
+						new String[] {
+							count,
+							count,
+							new String(sourceUnit.getFileName())
+						}));
+			}
+			// diet parsing for large collection of unit
+			CompilationUnitDeclaration parsedUnit;
+			if (this.totalUnits < this.parseThreshold) {
+				parsedUnit = this.parser.parse(sourceUnit, unitResult);
+			} else {
+				parsedUnit = this.parser.dietParse(sourceUnit, unitResult);
+			}
+			parsedUnit.bits |= ASTNode.IsImplicitUnit;
+			// initial type binding creation
+			this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
+			addCompilationUnit(sourceUnit, parsedUnit);
+
+			// binding resolution
+			this.lookupEnvironment.completeTypeBindings(parsedUnit);
+		} catch (AbortCompilationUnit e) {
+			// at this point, currentCompilationUnitResult may not be sourceUnit, but some other
+			// one requested further along to resolve sourceUnit.
+			if (unitResult.compilationUnit == sourceUnit) { // only report once
+				this.requestor.acceptResult(unitResult.tagAsAccepted());
+			} else {
+				throw e; // want to abort enclosing request to compile
+			}
+		}
+	}
+
+	/**
+	 * Add additional source types
+	 */
+	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		this.problemReporter.abortDueToInternalError(
+			Messages.bind(Messages.abort_againstSourceModel, new String[] { String.valueOf(sourceTypes[0].getName()), String.valueOf(sourceTypes[0].getFileName()) }));
+	}
+
+	protected synchronized void addCompilationUnit(
+		ICompilationUnit sourceUnit,
+		CompilationUnitDeclaration parsedUnit) {
+
+		if (this.unitsToProcess == null)
+			return; // not collecting units
+
+		// append the unit to the list of ones to process later on
+		int size = this.unitsToProcess.length;
+		if (this.totalUnits == size)
+			// when growing reposition units starting at position 0
+			System.arraycopy(
+				this.unitsToProcess,
+				0,
+				(this.unitsToProcess = new CompilationUnitDeclaration[size * 2]),
+				0,
+				this.totalUnits);
+		this.unitsToProcess[this.totalUnits++] = parsedUnit;
+	}
+
+	/**
+	 * Add the initial set of compilation units into the loop
+	 *  ->  build compilation unit declarations, their bindings and record their results.
+	 */
+	protected void beginToCompile(ICompilationUnit[] sourceUnits) {
+		int maxUnits = sourceUnits.length;
+		this.totalUnits = 0;
+		this.unitsToProcess = new CompilationUnitDeclaration[maxUnits];
+
+		internalBeginToCompile(sourceUnits, maxUnits);
+	}
+
+	/**
+	 * Checks whether the compilation has been canceled and reports the given progress to the compiler progress.
+	 */
+	protected void reportProgress(String taskDecription) {
+		if (this.progress != null) {
+			if (this.progress.isCanceled()) {
+				// Only AbortCompilation can stop the compiler cleanly.
+				// We check cancellation again following the call to compile.
+				throw new AbortCompilation(true, null);
+			}
+			this.progress.setTaskName(taskDecription);
+		}
+	}
+
+	/**
+	 * Checks whether the compilation has been canceled and reports the given work increment to the compiler progress.
+	 */
+	protected void reportWorked(int workIncrement, int currentUnitIndex) {
+		if (this.progress != null) {
+			if (this.progress.isCanceled()) {
+				// Only AbortCompilation can stop the compiler cleanly.
+				// We check cancellation again following the call to compile.
+				throw new AbortCompilation(true, null);
+			}
+			this.progress.worked(workIncrement, (this.totalUnits* this.remainingIterations) - currentUnitIndex - 1);
+		}
+	}
+
+	/**
+	 * General API
+	 * -> compile each of supplied files
+	 * -> recompile any required types for which we have an incomplete principle structure
+	 */
+	public void compile(ICompilationUnit[] sourceUnits) {
+		this.stats.startTime = System.currentTimeMillis();
+		CompilationUnitDeclaration unit = null;
+		ProcessTaskManager processingTask = null;
+		try {
+			// build and record parsed units
+			reportProgress(Messages.compilation_beginningToCompile);
+
+			if (this.annotationProcessorManager == null) {
+				beginToCompile(sourceUnits);
+			} else {
+				ICompilationUnit[] originalUnits = (ICompilationUnit[]) sourceUnits.clone(); // remember source units in case a source type collision occurs
+				try {
+					beginToCompile(sourceUnits);
+
+					processAnnotations();
+					if (!this.options.generateClassFiles) {
+						// -proc:only was set on the command line
+						return;
+					}
+				} catch (SourceTypeCollisionException e) {
+					reset();
+					// a generated type was referenced before it was created
+					// the compiler either created a MissingType or found a BinaryType for it
+					// so add the processor's generated files & start over,
+					// but remember to only pass the generated files to the annotation processor
+					int originalLength = originalUnits.length;
+					int newProcessedLength = e.newAnnotationProcessorUnits.length;
+					ICompilationUnit[] combinedUnits = new ICompilationUnit[originalLength + newProcessedLength];
+					System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength);
+					System.arraycopy(e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength);
+					this.annotationProcessorStartIndex  = originalLength;
+					compile(combinedUnits);
+					return;
+				}
+			}
+
+			if (this.useSingleThread) {
+				// process all units (some more could be injected in the loop by the lookup environment)
+				for (int i = 0; i < this.totalUnits; i++) {
+					unit = this.unitsToProcess[i];
+					reportProgress(Messages.bind(Messages.compilation_processing, new String(unit.getFileName())));
+					try {
+						if (this.options.verbose)
+							this.out.println(
+								Messages.bind(Messages.compilation_process,
+								new String[] {
+									String.valueOf(i + 1),
+									String.valueOf(this.totalUnits),
+									new String(this.unitsToProcess[i].getFileName())
+								}));
+						process(unit, i);
+					} finally {
+						// cleanup compilation unit result
+						unit.cleanUp();
+					}
+					this.unitsToProcess[i] = null; // release reference to processed unit declaration
+
+					reportWorked(1, i);
+					this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
+					long acceptStart = System.currentTimeMillis();
+					this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+					this.stats.generateTime += System.currentTimeMillis() - acceptStart; // record accept time as part of generation
+					if (this.options.verbose)
+						this.out.println(
+							Messages.bind(Messages.compilation_done,
+							new String[] {
+								String.valueOf(i + 1),
+								String.valueOf(this.totalUnits),
+								new String(unit.getFileName())
+							}));
+				}
+			} else {
+				processingTask = new ProcessTaskManager(this);
+				int acceptedCount = 0;
+				// process all units (some more could be injected in the loop by the lookup environment)
+				// the processTask can continue to process units until its fixed sized cache is full then it must wait
+				// for this this thread to accept the units as they appear (it only waits if no units are available)
+				while (true) {
+					try {
+						unit = processingTask.removeNextUnit(); // waits if no units are in the processed queue
+					} catch (Error e) {
+						unit = processingTask.unitToProcess;
+						throw e;
+					} catch (RuntimeException e) {
+						unit = processingTask.unitToProcess;
+						throw e;
+					}
+					if (unit == null) break;
+					reportWorked(1, acceptedCount++);
+					this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length;
+					this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+					if (this.options.verbose)
+						this.out.println(
+							Messages.bind(Messages.compilation_done,
+							new String[] {
+								String.valueOf(acceptedCount),
+								String.valueOf(this.totalUnits),
+								new String(unit.getFileName())
+							}));
+				}
+			}
+		} catch (AbortCompilation e) {
+			this.handleInternalException(e, unit);
+		} catch (Error e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} catch (RuntimeException e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} finally {
+			if (processingTask != null) {
+				processingTask.shutdown();
+				processingTask = null;
+			}
+			reset();
+			this.annotationProcessorStartIndex  = 0;
+			this.stats.endTime = System.currentTimeMillis();
+		}
+		if (this.options.verbose) {
+			if (this.totalUnits > 1) {
+				this.out.println(
+					Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
+			} else {
+				this.out.println(
+					Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
+			}
+		}
+	}
+
+	public synchronized CompilationUnitDeclaration getUnitToProcess(int next) {
+		if (next < this.totalUnits) {
+			CompilationUnitDeclaration unit = this.unitsToProcess[next];
+			this.unitsToProcess[next] = null; // release reference to processed unit declaration
+			return unit;
+		}
+		return null;
+	}
+
+	public void setBinaryTypes(ReferenceBinding[] binaryTypes) {
+		this.referenceBindings = binaryTypes;
+	}
+	/*
+	 * Compiler crash recovery in case of unexpected runtime exceptions
+	 */
+	protected void handleInternalException(
+		Throwable internalException,
+		CompilationUnitDeclaration unit,
+		CompilationResult result) {
+
+		if (result == null && unit != null) {
+			result = unit.compilationResult; // current unit being processed ?
+		}
+		// Lookup environment may be in middle of connecting types
+		if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
+		    result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
+		}
+		if (result == null) {
+			synchronized (this) {
+				if (this.unitsToProcess != null && this.totalUnits > 0)
+					result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
+			}
+		}
+		// last unit in beginToCompile ?
+
+		boolean needToPrint = true;
+		if (result != null) {
+			/* create and record a compilation problem */
+			// only keep leading portion of the trace
+			String[] pbArguments = new String[] {
+				Messages.bind(Messages.compilation_internalError, Util.getExceptionSummary(internalException)),
+			};
+
+			result
+				.record(
+					this.problemReporter
+						.createProblem(
+							result.getFileName(),
+							IProblem.Unclassified,
+							pbArguments,
+							pbArguments,
+							Error, // severity
+							0, // source start
+							0, // source end
+							0, // line number
+							0),// column number
+					unit, true);
+
+			/* hand back the compilation result */
+			if (!result.hasBeenAccepted) {
+				this.requestor.acceptResult(result.tagAsAccepted());
+				needToPrint = false;
+			}
+		}
+		if (needToPrint) {
+			/* dump a stack trace to the console */
+			internalException.printStackTrace();
+		}
+	}
+
+	/*
+	 * Compiler recovery in case of internal AbortCompilation event
+	 */
+	protected void handleInternalException(
+		AbortCompilation abortException,
+		CompilationUnitDeclaration unit) {
+
+		/* special treatment for SilentAbort: silently cancelling the compilation process */
+		if (abortException.isSilent) {
+			if (abortException.silentException == null) {
+				return;
+			}
+			throw abortException.silentException;
+		}
+
+		/* uncomment following line to see where the abort came from */
+		// abortException.printStackTrace();
+
+		// Exception may tell which compilation result it is related, and which problem caused it
+		CompilationResult result = abortException.compilationResult;
+		if (result == null && unit != null) {
+			result = unit.compilationResult; // current unit being processed ?
+		}
+		// Lookup environment may be in middle of connecting types
+		if (result == null && this.lookupEnvironment.unitBeingCompleted != null) {
+		    result = this.lookupEnvironment.unitBeingCompleted.compilationResult;
+		}
+		if (result == null) {
+			synchronized (this) {
+				if (this.unitsToProcess != null && this.totalUnits > 0)
+					result = this.unitsToProcess[this.totalUnits - 1].compilationResult;
+			}
+		}
+		// last unit in beginToCompile ?
+		if (result != null && !result.hasBeenAccepted) {
+			/* distant problem which could not be reported back there? */
+			if (abortException.problem != null) {
+				recordDistantProblem: {
+				CategorizedProblem distantProblem = abortException.problem;
+				CategorizedProblem[] knownProblems = result.problems;
+					for (int i = 0; i < result.problemCount; i++) {
+						if (knownProblems[i] == distantProblem) { // already recorded
+							break recordDistantProblem;
+						}
+					}
+					if (distantProblem instanceof DefaultProblem) { // fixup filename TODO (philippe) should improve API to make this official
+						((DefaultProblem) distantProblem).setOriginatingFileName(result.getFileName());
+					}
+					result.record(distantProblem, unit, true);
+				}
+			} else {
+				/* distant internal exception which could not be reported back there */
+				if (abortException.exception != null) {
+					this.handleInternalException(abortException.exception, null, result);
+					return;
+				}
+			}
+			/* hand back the compilation result */
+			if (!result.hasBeenAccepted) {
+				this.requestor.acceptResult(result.tagAsAccepted());
+			}
+		} else {
+			abortException.printStackTrace();
+		}
+	}
+
+	public void initializeParser() {
+
+		this.parser = new Parser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
+	}
+
+	/**
+	 * Add the initial set of compilation units into the loop
+	 *  ->  build compilation unit declarations, their bindings and record their results.
+	 */
+	protected void internalBeginToCompile(ICompilationUnit[] sourceUnits, int maxUnits) {
+		if (!this.useSingleThread && maxUnits >= ReadManager.THRESHOLD)
+			this.parser.readManager = new ReadManager(sourceUnits, maxUnits);
+
+		// Switch the current policy and compilation result for this unit to the requested one.
+		for (int i = 0; i < maxUnits; i++) {
+			CompilationResult unitResult = null;
+			try {
+				if (this.options.verbose) {
+					this.out.println(
+						Messages.bind(Messages.compilation_request,
+						new String[] {
+							String.valueOf(i + 1),
+							String.valueOf(maxUnits),
+							new String(sourceUnits[i].getFileName())
+						}));
+				}
+				// diet parsing for large collection of units
+				CompilationUnitDeclaration parsedUnit;
+				unitResult = new CompilationResult(sourceUnits[i], i, maxUnits, this.options.maxProblemsPerUnit);
+				long parseStart = System.currentTimeMillis();
+				if (this.totalUnits < this.parseThreshold) {
+					parsedUnit = this.parser.parse(sourceUnits[i], unitResult);
+				} else {
+					parsedUnit = this.parser.dietParse(sourceUnits[i], unitResult);
+				}
+				long resolveStart = System.currentTimeMillis();
+				this.stats.parseTime += resolveStart - parseStart;
+				// initial type binding creation
+				this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+				this.stats.resolveTime += System.currentTimeMillis() - resolveStart;
+				addCompilationUnit(sourceUnits[i], parsedUnit);
+				ImportReference currentPackage = parsedUnit.currentPackage;
+				if (currentPackage != null) {
+					unitResult.recordPackageName(currentPackage.tokens);
+				}
+				//} catch (AbortCompilationUnit e) {
+				//	requestor.acceptResult(unitResult.tagAsAccepted());
+			} catch (AbortCompilation a) {
+				// best effort to find a way for reporting this problem:
+				if (a.compilationResult == null)
+					a.compilationResult = unitResult;
+				throw a;
+			} finally {
+				sourceUnits[i] = null; // no longer hold onto the unit
+			}
+		}
+		if (this.parser.readManager != null) {
+			this.parser.readManager.shutdown();
+			this.parser.readManager = null;
+		}
+		// binding resolution
+		this.lookupEnvironment.completeTypeBindings();
+	}
+
+	/**
+	 * Process a compilation unit already parsed and build.
+	 */
+	public void process(CompilationUnitDeclaration unit, int i) {
+		this.lookupEnvironment.unitBeingCompleted = unit;
+		long parseStart = System.currentTimeMillis();
+
+		this.parser.getMethodBodies(unit);
+
+		long resolveStart = System.currentTimeMillis();
+		this.stats.parseTime += resolveStart - parseStart;
+
+		// fault in fields & methods
+		if (unit.scope != null)
+			unit.scope.faultInTypes();
+
+		// verify inherited methods
+		if (unit.scope != null)
+			unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
+
+		// type checking
+		unit.resolve();
+
+		long analyzeStart = System.currentTimeMillis();
+		this.stats.resolveTime += analyzeStart - resolveStart;
+		
+		//No need of analysis or generation of code if statements are not required		
+		if (!this.options.ignoreMethodBodies) unit.analyseCode(); // flow analysis
+
+		long generateStart = System.currentTimeMillis();
+		this.stats.analyzeTime += generateStart - analyzeStart;
+	
+		if (!this.options.ignoreMethodBodies) unit.generateCode(); // code generation
+		
+		// reference info
+		if (this.options.produceReferenceInfo && unit.scope != null)
+			unit.scope.storeDependencyInfo();
+
+		// finalize problems (suppressWarnings)
+		unit.finalizeProblems();
+
+		this.stats.generateTime += System.currentTimeMillis() - generateStart;
+
+		// refresh the total number of units known at this stage
+		unit.compilationResult.totalUnitsKnown = this.totalUnits;
+
+		this.lookupEnvironment.unitBeingCompleted = null;
+	}
+
+	protected void processAnnotations() {
+		int newUnitSize = 0;
+		int newClassFilesSize = 0;
+		int bottom = this.annotationProcessorStartIndex;
+		int top = this.totalUnits;
+		ReferenceBinding[] binaryTypeBindingsTemp = this.referenceBindings;
+		if (top == 0 && binaryTypeBindingsTemp == null) return;
+		this.referenceBindings = null;
+		do {
+			// extract units to process
+			int length = top - bottom;
+			CompilationUnitDeclaration[] currentUnits = new CompilationUnitDeclaration[length];
+			int index = 0;
+			for (int i = bottom; i < top; i++) {
+				CompilationUnitDeclaration currentUnit = this.unitsToProcess[i];
+				if ((currentUnit.bits & ASTNode.IsImplicitUnit) == 0) {
+					currentUnits[index++] = currentUnit;
+				}
+			}
+			if (index != length) {
+				System.arraycopy(currentUnits, 0, (currentUnits = new CompilationUnitDeclaration[index]), 0, index);
+			}
+			this.annotationProcessorManager.processAnnotations(currentUnits, binaryTypeBindingsTemp, false);
+			ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
+			newUnitSize = newUnits.length;
+			ReferenceBinding[] newClassFiles = this.annotationProcessorManager.getNewClassFiles();
+			binaryTypeBindingsTemp = newClassFiles;
+			newClassFilesSize = newClassFiles.length;
+			if (newUnitSize != 0) {
+				ICompilationUnit[] newProcessedUnits = (ICompilationUnit[]) newUnits.clone(); // remember new units in case a source type collision occurs
+				try {
+					this.lookupEnvironment.isProcessingAnnotations = true;
+					internalBeginToCompile(newUnits, newUnitSize);
+				} catch (SourceTypeCollisionException e) {
+					e.newAnnotationProcessorUnits = newProcessedUnits;
+					throw e;
+				} finally {
+					this.lookupEnvironment.isProcessingAnnotations = false;
+					this.annotationProcessorManager.reset();
+				}
+				bottom = top;
+				top = this.totalUnits; // last unit added
+			} else {
+				bottom = top;
+				this.annotationProcessorManager.reset();
+			}
+		} while (newUnitSize != 0 || newClassFilesSize != 0);
+		
+		this.annotationProcessorManager.processAnnotations(null, null, true);
+		// process potential units added in the final round see 329156 
+		ICompilationUnit[] newUnits = this.annotationProcessorManager.getNewUnits();
+		newUnitSize = newUnits.length;
+		if (newUnitSize != 0) {
+			ICompilationUnit[] newProcessedUnits = (ICompilationUnit[]) newUnits.clone(); // remember new units in case a source type collision occurs
+			try {
+				this.lookupEnvironment.isProcessingAnnotations = true;
+				internalBeginToCompile(newUnits, newUnitSize);
+			} catch (SourceTypeCollisionException e) {
+				e.newAnnotationProcessorUnits = newProcessedUnits;
+				throw e;
+			} finally {
+				this.lookupEnvironment.isProcessingAnnotations = false;
+				this.annotationProcessorManager.reset();
+			}
+		} else {
+			this.annotationProcessorManager.reset();
+		}
+	}
+
+	public void reset() {
+		this.lookupEnvironment.reset();
+		this.parser.scanner.source = null;
+		this.unitsToProcess = null;
+		if (DebugRequestor != null) DebugRequestor.reset();
+		this.problemReporter.reset();
+	}
+
+	/**
+	 * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
+	 */
+	public CompilationUnitDeclaration resolve(
+			CompilationUnitDeclaration unit,
+			ICompilationUnit sourceUnit,
+			boolean verifyMethods,
+			boolean analyzeCode,
+			boolean generateCode) {
+
+		try {
+			if (unit == null) {
+				// build and record parsed units
+				this.parseThreshold = 0; // will request a full parse
+				beginToCompile(new ICompilationUnit[] { sourceUnit });
+				// find the right unit from what was injected via accept(ICompilationUnit,..):
+				for (int i=0; i<this.totalUnits; i++) {
+					if (   this.unitsToProcess[i] != null
+						&& this.unitsToProcess[i].compilationResult.compilationUnit == sourceUnit)
+					{
+						unit = this.unitsToProcess[i];
+						break;
+					}
+				}
+				if (unit == null)
+					unit = this.unitsToProcess[0]; // fall back to old behavior
+
+			} else {
+				// initial type binding creation
+				this.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);
+
+				// binding resolution
+				this.lookupEnvironment.completeTypeBindings();
+			}
+			this.lookupEnvironment.unitBeingCompleted = unit;
+			this.parser.getMethodBodies(unit);
+			if (unit.scope != null) {
+				// fault in fields & methods
+				unit.scope.faultInTypes();
+				if (unit.scope != null && verifyMethods) {
+					// http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
+ 					// verify inherited methods
+					unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
+				}
+				// type checking
+				unit.resolve();
+
+				// flow analysis
+				if (analyzeCode) unit.analyseCode();
+
+				// code generation
+				if (generateCode) unit.generateCode();
+
+				// finalize problems (suppressWarnings)
+				unit.finalizeProblems();
+			}
+			if (this.unitsToProcess != null) this.unitsToProcess[0] = null; // release reference to processed unit declaration
+			this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+			return unit;
+		} catch (AbortCompilation e) {
+			this.handleInternalException(e, unit);
+			return unit == null ? this.unitsToProcess[0] : unit;
+		} catch (Error e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} catch (RuntimeException e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} finally {
+			// leave this.lookupEnvironment.unitBeingCompleted set to the unit, until another unit is resolved
+			// other calls to dom can cause classpath errors to be detected, resulting in AbortCompilation exceptions
+
+			// No reset is performed there anymore since,
+			// within the CodeAssist (or related tools),
+			// the compiler may be called *after* a call
+			// to this resolve(...) method. And such a call
+			// needs to have a compiler with a non-empty
+			// environment.
+			// this.reset();
+		}
+	}
+	/**
+	 * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
+	 */
+	public CompilationUnitDeclaration resolve(
+			ICompilationUnit sourceUnit,
+			boolean verifyMethods,
+			boolean analyzeCode,
+			boolean generateCode) {
+
+		return resolve(
+			null,
+			sourceUnit,
+			verifyMethods,
+			analyzeCode,
+			generateCode);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java
new file mode 100644
index 0000000..f5acdae
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+public class DefaultErrorHandlingPolicies {
+
+/*
+ * Accumulate all problems, then exit without proceeding.
+ *
+ * Typically, the #proceedWithProblems(Problem[]) should
+ * show the problems.
+ *
+ */
+public static IErrorHandlingPolicy exitAfterAllProblems() {
+	return new IErrorHandlingPolicy() {
+		public boolean stopOnFirstError() {
+			return false;
+		}
+		public boolean proceedOnErrors(){
+			return false;
+		}
+		public boolean ignoreAllErrors() {
+			return false;
+		}
+	};
+}
+/*
+ * Exit without proceeding on the first problem wich appears
+ * to be an error.
+ *
+ */
+public static IErrorHandlingPolicy exitOnFirstError() {
+	return new IErrorHandlingPolicy() {
+		public boolean stopOnFirstError() {
+			return true;
+		}
+		public boolean proceedOnErrors(){
+			return false;
+		}
+		public boolean ignoreAllErrors() {
+			return false;
+		}
+	};
+}
+/*
+ * Proceed on the first error met.
+ *
+ */
+public static IErrorHandlingPolicy proceedOnFirstError() {
+	return new IErrorHandlingPolicy() {
+		public boolean stopOnFirstError() {
+			return true;
+		}
+		public boolean proceedOnErrors(){
+			return true;
+		}
+		public boolean ignoreAllErrors() {
+			return false;
+		}
+	};
+}
+/*
+ * Accumulate all problems, then proceed with them.
+ *
+ */
+public static IErrorHandlingPolicy proceedWithAllProblems() {
+	return new IErrorHandlingPolicy() {
+		public boolean stopOnFirstError() {
+			return false;
+		}
+		public boolean proceedOnErrors(){
+			return true;
+		}
+		public boolean ignoreAllErrors() {
+			return false;
+		}
+	};
+}
+/*
+ * Accumulate all problems, then proceed with them, but never report them.
+ *
+ */
+public static IErrorHandlingPolicy ignoreAllProblems() {
+	return new IErrorHandlingPolicy() {
+		public boolean stopOnFirstError() {
+			return false;
+		}
+		public boolean proceedOnErrors(){
+			return true;
+		}
+		public boolean ignoreAllErrors() {
+			return true;
+		}
+	};
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java
new file mode 100644
index 0000000..08b45ec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+/**
+ * A callback interface for receiving compilation results.
+ */
+public interface ICompilerRequestor {
+
+	/**
+	 * Accept a compilation result.
+	 */
+	public void acceptResult(CompilationResult result);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java
new file mode 100644
index 0000000..89e6b82
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+public interface IDebugRequestor {
+
+	/*
+	 * Debug callback method allowing to take into account a new compilation result.
+	 * Any side-effect performed on the actual result might interfere with the
+	 * original compiler requestor, and should be prohibited.
+	 */
+	void acceptDebugResult(CompilationResult result);
+
+	/*
+	 * Answers true when in active mode
+	 */
+	boolean isActive();
+
+	/*
+	 * Activate debug callbacks
+	 */
+	void activate();
+
+	/*
+	 * Deactivate debug callbacks
+	 */
+	void deactivate();
+
+	/*
+	 * Reset debug requestor after compilation has finished
+	 */
+	void reset();
+}
+
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java
new file mode 100644
index 0000000..de68aba
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+/*
+ * Handler policy is responsible to answer the 3 following
+ * questions:
+ * 1. should the handler stop on first problem which appears
+ *	to be a real error (that is, not a warning),
+ * 2. should it proceed once it has gathered all problems
+ * 3. Should problems be reported at all ?
+ *
+ * The intent is that one can supply its own policy to implement
+ * some interactive error handling strategy where some UI would
+ * display problems and ask user if he wants to proceed or not.
+ */
+
+public interface IErrorHandlingPolicy {
+	boolean proceedOnErrors();
+	boolean stopOnFirstError();
+	boolean ignoreAllErrors();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java
new file mode 100644
index 0000000..29c3c3d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.Locale;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+/*
+ * Factory used from inside the compiler to build the actual problems
+ * which are handed back in the compilation result.
+ *
+ * This allows sharing the internal problem representation with the environment.
+ *
+ * Note: The factory is responsible for computing and storing a localized error message.
+ */
+
+public interface IProblemFactory {
+	CategorizedProblem createProblem(
+			char[] originatingFileName,
+			int problemId,
+			String[] problemArguments,
+			String[] messageArguments, // shorter versions of the problemArguments
+			int severity,
+			int startPosition,
+			int endPosition,
+			int lineNumber,
+			int columnNumber);
+
+	/**
+	 * Answer a new IProblem created according to the parameters values.
+	 * @param originatingFileName the name of the file from which the problem is originated
+	 * @param problemId the problem id
+	 * @param problemArguments the fully qualified arguments recorded inside the problem
+	 * @param elaborationId the message elaboration id (0 for problems that have no message elaboration)
+	 * @param messageArguments the arguments needed to set the error message (shorter names than problemArguments ones)
+	 * @param severity the severity of the problem
+	 * @param startPosition the start position of the problem
+	 * @param endPosition the end position of the problem
+	 * @param lineNumber the line on which the problem occurred
+	 * @return a new IProblem created according to the parameters values.
+	 */
+	CategorizedProblem createProblem(
+		char[] originatingFileName,
+		int problemId,
+		String[] problemArguments,
+		int elaborationId,
+		String[] messageArguments, // shorter versions of the problemArguments
+		int severity,
+		int startPosition,
+		int endPosition,
+		int lineNumber,
+		int columnNumber);
+
+	Locale getLocale();
+
+	String getLocalizedMessage(int problemId, String[] messageArguments);
+
+	/**
+	 * Inject the supplied message arguments into a localized template
+	 * elaborated from the supplied problem id and an optional elaboration id
+	 * and return the resulting message. The arguments number should match the
+	 * highest placeholder index in the template. When an elaboration id is
+	 * used, the template matching that elaboration id replaces '{0}' into the
+	 * template matching the problem id before the message arguments are
+	 * injected.
+	 * @param problemId the problem id taken from
+	 *        {@link org.eclipse.jdt.core.compiler.IProblem} constants
+	 * @param elaborationId 0 if the considered problem has no elaboration, a
+	 *        valid elaboration id else
+	 * @param messageArguments the arguments to inject into the template
+	 * @return a localized message elaborated from the supplied problem id,
+	 *         elaboration id and message parameters
+	 */
+	String getLocalizedMessage(int problemId, int elaborationId, String[] messageArguments);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ProcessTaskManager.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ProcessTaskManager.java
new file mode 100644
index 0000000..ad046c0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ProcessTaskManager.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+
+public class ProcessTaskManager implements Runnable {
+
+	Compiler compiler;
+	private int unitIndex;
+	private Thread processingThread;
+	CompilationUnitDeclaration unitToProcess;
+	private Throwable caughtException;
+
+	// queue
+	volatile int currentIndex, availableIndex, size, sleepCount;
+	CompilationUnitDeclaration[] units;
+
+	public static final int PROCESSED_QUEUE_SIZE = 12;
+
+public ProcessTaskManager(Compiler compiler) {
+	this.compiler = compiler;
+	this.unitIndex = 0;
+
+	this.currentIndex = 0;
+	this.availableIndex = 0;
+	this.size = PROCESSED_QUEUE_SIZE;
+	this.sleepCount = 0; // 0 is no one, +1 is the processing thread & -1 is the writing/main thread
+	this.units = new CompilationUnitDeclaration[this.size];
+
+	synchronized (this) {
+		this.processingThread = new Thread(this, "Compiler Processing Task"); //$NON-NLS-1$
+		this.processingThread.setDaemon(true);
+		this.processingThread.start();
+	}
+}
+
+// add unit to the queue - wait if no space is available
+private synchronized void addNextUnit(CompilationUnitDeclaration newElement) {
+	while (this.units[this.availableIndex] != null) {
+		//System.out.print('a');
+		//if (this.sleepCount < 0) throw new IllegalStateException(new Integer(this.sleepCount).toString());
+		this.sleepCount = 1;
+		try {
+			wait(250);
+		} catch (InterruptedException ignore) {
+			// ignore
+		}
+		this.sleepCount = 0;
+	}
+
+	this.units[this.availableIndex++] = newElement;
+	if (this.availableIndex >= this.size)
+		this.availableIndex = 0;
+	if (this.sleepCount <= -1)
+		notify(); // wake up writing thread to accept next unit - could be the last one - must avoid deadlock
+}
+
+public CompilationUnitDeclaration removeNextUnit() throws Error {
+	CompilationUnitDeclaration next = null;
+	boolean yield = false;
+	synchronized (this) {
+		next = this.units[this.currentIndex];
+		if (next == null || this.caughtException != null) {
+			do {
+				if (this.processingThread == null) {
+					if (this.caughtException != null) {
+						// rethrow the caught exception from the processingThread in the main compiler thread
+						if (this.caughtException instanceof Error)
+							throw (Error) this.caughtException;
+						throw (RuntimeException) this.caughtException;
+					}
+					return null;
+				}
+				//System.out.print('r');
+				//if (this.sleepCount > 0) throw new IllegalStateException(new Integer(this.sleepCount).toString());
+				this.sleepCount = -1;
+				try {
+					wait(100);
+				} catch (InterruptedException ignore) {
+					// ignore
+				}
+				this.sleepCount = 0;
+				next = this.units[this.currentIndex];
+			} while (next == null);
+		}
+
+		this.units[this.currentIndex++] = null;
+		if (this.currentIndex >= this.size)
+			this.currentIndex = 0;
+		if (this.sleepCount >= 1 && ++this.sleepCount > 4) {
+			notify(); // wake up processing thread to add next unit but only after removing some elements first
+			yield = this.sleepCount > 8;
+		}
+	}
+	if (yield)
+		Thread.yield();
+	return next;
+}
+
+public void run() {
+	while (this.processingThread != null) {
+		this.unitToProcess = null;
+		int index = -1;
+		try {
+			synchronized (this) {
+				if (this.processingThread == null) return;
+
+				this.unitToProcess = this.compiler.getUnitToProcess(this.unitIndex);
+				if (this.unitToProcess == null) {
+					this.processingThread = null;
+					return;
+				}
+				index = this.unitIndex++;
+			}
+
+			try {
+				this.compiler.reportProgress(Messages.bind(Messages.compilation_processing, new String(this.unitToProcess.getFileName())));
+				if (this.compiler.options.verbose)
+					this.compiler.out.println(
+						Messages.bind(Messages.compilation_process,
+						new String[] {
+							String.valueOf(index + 1),
+							String.valueOf(this.compiler.totalUnits),
+							new String(this.unitToProcess.getFileName())
+						}));
+				this.compiler.process(this.unitToProcess, index);
+			} finally {
+				if (this.unitToProcess != null)
+					this.unitToProcess.cleanUp();
+			}
+
+			addNextUnit(this.unitToProcess);
+		} catch (Error e) {
+			synchronized (this) {
+				this.processingThread = null;
+				this.caughtException = e;
+			}
+			return;
+		} catch (RuntimeException e) {
+			synchronized (this) {
+				this.processingThread = null;
+				this.caughtException = e;
+			}
+			return;
+		}
+	}
+}
+
+public void shutdown() {
+	try {
+		Thread t = null;
+		synchronized (this) {
+			if (this.processingThread != null) {
+				t = this.processingThread;
+				this.processingThread = null;
+				notifyAll();
+			}
+		}
+		if (t != null)
+			t.join(250); // do not wait forever
+	} catch (InterruptedException ignored) {
+		// ignore
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ReadManager.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ReadManager.java
new file mode 100644
index 0000000..2a1ad18
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ReadManager.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+
+public class ReadManager implements Runnable {
+	ICompilationUnit[] units;
+	int nextFileToRead;
+	ICompilationUnit[] filesRead;
+	char[][] contentsRead;
+	int readyToReadPosition;
+	int nextAvailablePosition;
+	Thread[] readingThreads;
+	char[] readInProcessMarker = new char[0];
+	int sleepingThreadCount;
+	private Throwable caughtException;
+
+	static final int START_CUSHION = 5;
+	public static final int THRESHOLD = 10;
+	static final int CACHE_SIZE = 15; // do not waste memory by keeping too many files in memory
+
+public ReadManager(ICompilationUnit[] files, int length) {
+	// start the background threads to read the file's contents
+	int threadCount = 0;
+	try {
+		Class runtime = Class.forName("java.lang.Runtime"); //$NON-NLS-1$
+		java.lang.reflect.Method m = runtime.getDeclaredMethod("availableProcessors", new Class[0]); //$NON-NLS-1$
+		if (m != null) {
+			Integer result = (Integer) m.invoke(Runtime.getRuntime(), null);
+			threadCount = result.intValue() + 1;
+			if (threadCount < 2)
+				threadCount = 0;
+			else if (threadCount > CACHE_SIZE)
+				threadCount = CACHE_SIZE;
+		}
+	} catch (IllegalAccessException ignored) { // ignored
+	} catch (ClassNotFoundException e) { // ignored
+	} catch (SecurityException e) { // ignored
+	} catch (NoSuchMethodException e) { // ignored
+	} catch (IllegalArgumentException e) { // ignored
+	} catch (InvocationTargetException e) { // ignored
+	}
+
+	if (threadCount > 0) {
+		synchronized (this) {
+			this.units = new ICompilationUnit[length];
+			System.arraycopy(files, 0, this.units, 0, length);
+			this.nextFileToRead = START_CUSHION; // skip some files to reduce the number of times we have to wait
+			this.filesRead = new ICompilationUnit[CACHE_SIZE];
+			this.contentsRead = new char[CACHE_SIZE][];
+			this.readyToReadPosition = 0;
+			this.nextAvailablePosition = 0;
+			this.sleepingThreadCount = 0;
+			this.readingThreads = new Thread[threadCount];
+			for (int i = threadCount; --i >= 0;) {
+				this.readingThreads[i] = new Thread(this, "Compiler Source File Reader"); //$NON-NLS-1$
+				this.readingThreads[i].setDaemon(true);
+				this.readingThreads[i].start();
+			}
+		}
+	}
+}
+
+public char[] getContents(ICompilationUnit unit) throws Error {
+	if (this.readingThreads == null || this.units.length == 0) {
+		if (this.caughtException != null) {
+			// rethrow the caught exception from the readingThreads in the main compiler thread
+			if (this.caughtException instanceof Error)
+				throw (Error) this.caughtException;
+			throw (RuntimeException) this.caughtException;
+		}
+		return unit.getContents();
+	}
+
+	boolean yield = false;
+	char[] result = null;
+	synchronized (this) {
+		if (unit == this.filesRead[this.readyToReadPosition]) {
+			result = this.contentsRead[this.readyToReadPosition];
+			while (result == this.readInProcessMarker || result == null) {
+				// let the readingThread know we're waiting
+				//System.out.print('|');
+				this.contentsRead[this.readyToReadPosition] = null;
+				try {
+					wait(250);
+				} catch (InterruptedException ignore) { // ignore
+				}
+				if (this.caughtException != null) {
+					// rethrow the caught exception from the readingThreads in the main compiler thread
+					if (this.caughtException instanceof Error)
+						throw (Error) this.caughtException;
+					throw (RuntimeException) this.caughtException;
+				}
+				result = this.contentsRead[this.readyToReadPosition];
+			}
+			// free spot for next file
+			this.filesRead[this.readyToReadPosition] = null;
+			this.contentsRead[this.readyToReadPosition] = null;
+			if (++this.readyToReadPosition >= this.contentsRead.length)
+				this.readyToReadPosition = 0;
+			if (this.sleepingThreadCount > 0) {
+				//System.out.print('+');
+				//System.out.print(this.nextFileToRead);
+				notify();
+				yield = this.sleepingThreadCount == this.readingThreads.length;
+			}
+		} else {
+			// must make sure we're reading ahead of the unit
+			int unitIndex = 0;
+			for (int l = this.units.length; unitIndex < l; unitIndex++)
+				if (this.units[unitIndex] == unit) break;
+			if (unitIndex == this.units.length) {
+				// attempting to read a unit that was not included in the initial files - should not happen
+				this.units = new ICompilationUnit[0]; // stop looking for more
+			} else if (unitIndex >= this.nextFileToRead) {
+				// start over
+				//System.out.println(unitIndex + " vs " + this.nextFileToRead);
+				this.nextFileToRead = unitIndex + START_CUSHION;
+				this.readyToReadPosition = 0;
+				this.nextAvailablePosition = 0;
+				this.filesRead = new ICompilationUnit[CACHE_SIZE];
+				this.contentsRead = new char[CACHE_SIZE][];
+				notifyAll();
+			}
+		}
+	}
+	if (yield)
+		Thread.yield(); // ensure other threads get a chance
+	if (result != null)
+		return result;
+	//System.out.print('-');
+	return unit.getContents();
+}
+
+public void run() {
+	try {
+		while (this.readingThreads != null && this.nextFileToRead < this.units.length) {
+			ICompilationUnit unit = null;
+			int position = -1;
+			synchronized (this) {
+				if (this.readingThreads == null) return;
+
+				while (this.filesRead[this.nextAvailablePosition] != null) {
+					this.sleepingThreadCount++;
+					try {
+						wait(250); // wait until a spot in contents is available
+					} catch (InterruptedException e) { // ignore
+					}
+					this.sleepingThreadCount--;
+					if (this.readingThreads == null) return;
+				}
+
+				if (this.nextFileToRead >= this.units.length) return;
+				unit = this.units[this.nextFileToRead++];
+				position = this.nextAvailablePosition;
+				if (++this.nextAvailablePosition >= this.contentsRead.length)
+					this.nextAvailablePosition = 0;
+				this.filesRead[position] = unit;
+				this.contentsRead[position] = this.readInProcessMarker; // mark the spot so we know its being read
+			}
+			char[] result = unit.getContents();
+			synchronized (this) {
+				if (this.filesRead[position] == unit) {
+					if (this.contentsRead[position] == null) // wake up main thread which is waiting for this file
+						notifyAll();
+					this.contentsRead[position] = result;
+				}
+			}
+		}
+	} catch (Error e) {
+		synchronized (this) {
+			this.caughtException = e;
+			shutdown();
+		}
+		return;
+	} catch (RuntimeException e) {
+		synchronized (this) {
+			this.caughtException = e;
+			shutdown();
+		}
+		return;
+	}
+}
+
+public synchronized void shutdown() {
+	this.readingThreads = null; // mark the read manager as shutting down so that the reading threads stop
+	notifyAll();
+}
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..6d10931
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+//dedicated treatment for the &&
+public class AND_AND_Expression extends BinaryExpression {
+
+	int rightInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+	public AND_AND_Expression(Expression left, Expression right, int operator) {
+		super(left, right, operator);
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+		Constant cst = this.left.optimizedBooleanConstant();
+		boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+		boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+		if (isLeftOptimizedTrue) {
+			// TRUE && anything
+			// need to be careful of scenario:
+			//  (x && y) && !z, if passing the left info to the right, it would
+			// be swapped by the !
+			FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo)
+					.unconditionalInits();
+			mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo);
+			this.mergedInitStateIndex = currentScope.methodScope()
+					.recordInitializationStates(mergedInfo);
+			return mergedInfo;
+		}
+
+		FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo);
+		if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0)
+			flowContext.expireNullCheckedFieldInfo();
+		// need to be careful of scenario:
+		//  (x && y) && !z, if passing the left info to the right, it would be
+		// swapped by the !
+		FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalCopy();
+		this.rightInitStateIndex = currentScope.methodScope().recordInitializationStates(rightInfo);
+
+		int previousMode = rightInfo.reachMode();
+		if (isLeftOptimizedFalse) {
+			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
+				currentScope.problemReporter().fakeReachable(this.right);
+				rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+			}
+		}
+		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
+		if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0)
+			flowContext.expireNullCheckedFieldInfo();
+		this.left.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		this.right.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		FlowInfo mergedInfo = FlowInfo.conditional(
+				rightInfo.safeInitsWhenTrue(),
+				leftInfo.initsWhenFalse().unconditionalInits().mergedWith(
+						rightInfo.initsWhenFalse().setReachMode(previousMode).unconditionalInits()));
+		// reset after trueMergedInfo got extracted
+		this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+
+	/**
+	 * Code generation for a binary operation
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		int pc = codeStream.position;
+		if (this.constant != Constant.NotAConstant) {
+			// inlined value
+			if (valueRequired)
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+		Constant cst = this.right.constant;
+		if (cst != Constant.NotAConstant) {
+			// <expr> && true --> <expr>
+			if (cst.booleanValue() == true) {
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+			} else {
+				// <expr> && false --> false
+				this.left.generateCode(currentScope, codeStream, false);
+				if (valueRequired) codeStream.iconst_0();
+			}
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		BranchLabel falseLabel = new BranchLabel(codeStream), endLabel;
+		cst = this.left.optimizedBooleanConstant();
+		boolean leftIsConst = cst != Constant.NotAConstant;
+		boolean leftIsTrue = leftIsConst && cst.booleanValue() == true;
+
+		cst = this.right.optimizedBooleanConstant();
+		boolean rightIsConst = cst != Constant.NotAConstant;
+		boolean rightIsTrue = rightIsConst && cst.booleanValue() == true;
+
+		generateOperands : {
+			if (leftIsConst) {
+				this.left.generateCode(currentScope, codeStream, false);
+				if (!leftIsTrue) {
+					break generateOperands; // no need to generate right operand
+				}
+			} else {
+				this.left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, true);
+				// need value, e.g. if (a == 1 && ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a!=1
+			}
+			if (this.rightInitStateIndex != -1) {
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+			}
+			if (rightIsConst) {
+				this.right.generateCode(currentScope, codeStream, false);
+			} else {
+				this.right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
+			}
+		}
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		/*
+		 * improving code gen for such a case: boolean b = i < 0 && false since
+		 * the label has never been used, we have the inlined value on the
+		 * stack.
+		 */
+		if (valueRequired) {
+			if (leftIsConst && !leftIsTrue) {
+				codeStream.iconst_0();
+			} else {
+				if (rightIsConst && !rightIsTrue) {
+					codeStream.iconst_0();
+				} else {
+					codeStream.iconst_1();
+				}
+				if (falseLabel.forwardReferenceCount() > 0) {
+					if ((this.bits & IsReturnedValue) != 0) {
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						falseLabel.place();
+						codeStream.iconst_0();
+					} else {
+						codeStream.goto_(endLabel = new BranchLabel(codeStream));
+						codeStream.decrStackSize(1);
+						falseLabel.place();
+						codeStream.iconst_0();
+						endLabel.place();
+					}
+				} else {
+					falseLabel.place();
+				}
+			}
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+		} else {
+			falseLabel.place();
+		}
+	}
+
+	/**
+	 * Boolean operator code generation Optimized operations are: &&
+	 */
+	public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+		if (this.constant != Constant.NotAConstant) {
+			super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel,
+					valueRequired);
+			return;
+		}
+
+		// <expr> && true --> <expr>
+		Constant cst = this.right.constant;
+		if (cst != Constant.NotAConstant && cst.booleanValue() == true) {
+			int pc = codeStream.position;
+			this.left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+		cst = this.left.optimizedBooleanConstant();
+		boolean leftIsConst = cst != Constant.NotAConstant;
+		boolean leftIsTrue = leftIsConst && cst.booleanValue() == true;
+
+		cst = this.right.optimizedBooleanConstant();
+		boolean rightIsConst = cst != Constant.NotAConstant;
+		boolean rightIsTrue = rightIsConst && cst.booleanValue() == true;
+
+		// default case
+		generateOperands : {
+			if (falseLabel == null) {
+				if (trueLabel != null) {
+					// implicit falling through the FALSE case
+					BranchLabel internalFalseLabel = new BranchLabel(codeStream);
+					this.left.generateOptimizedBoolean(currentScope, codeStream, null, internalFalseLabel, !leftIsConst);
+					// need value, e.g. if (a == 1 && ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a!=1
+					if (leftIsConst && !leftIsTrue) {
+						internalFalseLabel.place();
+						break generateOperands; // no need to generate right operand
+					}
+					if (this.rightInitStateIndex != -1) {
+						codeStream
+								.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+					}
+					this.right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null,
+							valueRequired && !rightIsConst);
+					if (valueRequired && rightIsConst && rightIsTrue) {
+						codeStream.goto_(trueLabel);
+						codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+					}
+					internalFalseLabel.place();
+				}
+			} else {
+				// implicit falling through the TRUE case
+				if (trueLabel == null) {
+					this.left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, !leftIsConst);
+					// need value, e.g. if (a == 1 && ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a!=1
+					int pc = codeStream.position;
+					if (leftIsConst && !leftIsTrue) {
+						if (valueRequired) {
+							codeStream.goto_(falseLabel);
+						}
+						codeStream.recordPositionsFrom(pc, this.sourceEnd);
+						break generateOperands; // no need to generate right operand
+					}
+					if (this.rightInitStateIndex != -1) {
+						codeStream
+								.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+					}
+					this.right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired && !rightIsConst);
+					if (valueRequired && rightIsConst && !rightIsTrue) {
+						codeStream.goto_(falseLabel);
+						codeStream.recordPositionsFrom(pc, this.sourceEnd);
+					}
+				} else {
+					// no implicit fall through TRUE/FALSE --> should never occur
+				}
+			}
+		}
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+	}
+
+	public boolean isCompactableOperation() {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.BinaryExpression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public TypeBinding resolveType(BlockScope scope) {
+		TypeBinding result = super.resolveType(scope);
+		// check whether comparing identical expressions
+		Binding leftDirect = Expression.getDirectBinding(this.left);
+		if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) {
+			if (!(this.right instanceof Assignment))
+				scope.problemReporter().comparingIdenticalExpressions(this);
+		}
+		return result;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			this.left.traverse(visitor, scope);
+			this.right.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
new file mode 100644
index 0000000..55091f8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -0,0 +1,908 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995
+ *     Karen Moore - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=207411
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *     							bug 185682 - Increment/decrement operators mark local variables as read
+ *     							bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 384870 - [compiler] @Deprecated annotation not detected if preceded by other annotation
+ *								bug 393719 - [compiler] inconsistent warnings on iteration variables
+ *     Jesper S Moller - Contributions for
+ *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+
+public abstract class ASTNode implements TypeConstants, TypeIds {
+
+	public int sourceStart, sourceEnd;
+
+	// storage for internal flags (32 bits)				BIT USAGE
+	public final static int Bit1 = 0x1;					// return type (operator) | name reference kind (name ref) | add assertion (type decl) | useful empty statement (empty statement)
+	public final static int Bit2 = 0x2;					// return type (operator) | name reference kind (name ref) | has local type (type, method, field decl) | if type elided (local)
+	public final static int Bit3 = 0x4;					// return type (operator) | name reference kind (name ref) | implicit this (this ref) | is argument(local)
+	public final static int Bit4 = 0x8;					// return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
+	public final static int Bit5 = 0x10;					// value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
+	public final static int Bit6 = 0x20;					// depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference)
+	public final static int Bit7 = 0x40;					// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression) | label used (labelStatement) | needFreeReturn (AbstractMethodDeclaration)
+	public final static int Bit8 = 0x80;					// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression) | is default constructor (constructor declaration) | isElseStatementUnreachable (if statement)
+	public final static int Bit9 = 0x100;				// depth (name ref, msg) | operator (operator) | is local type (type decl) | isThenStatementUnreachable (if statement) | can be static
+	public final static int Bit10= 0x200;				// depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
+	public final static int Bit11 = 0x400;				// depth (name ref, msg) | operator (operator) | is member type (type decl)
+	public final static int Bit12 = 0x800;				// depth (name ref, msg) | operator (operator) | has abstract methods (type decl)
+	public final static int Bit13 = 0x1000;			// depth (name ref, msg) | is secondary type (type decl)
+	public final static int Bit14 = 0x2000;			// strictly assigned (reference lhs) | discard enclosing instance (explicit constr call) | hasBeenGenerated (type decl)
+	public final static int Bit15 = 0x4000;			// is unnecessary cast (expression) | is varargs (type ref) | isSubRoutineEscaping (try statement) | superAccess (javadoc allocation expression/javadoc message send/javadoc return statement)
+	public final static int Bit16 = 0x8000;			// in javadoc comment (name ref, type ref, msg)
+	public final static int Bit17 = 0x10000;			// compound assigned (reference lhs) | unchecked (msg, alloc, explicit constr call)
+	public final static int Bit18 = 0x20000;			// non null (expression) | onDemand (import reference)
+	public final static int Bit19 = 0x40000;			// didResolve (parameterized qualified type ref/parameterized single type ref)  | empty (javadoc return statement) | needReceiverGenericCast (msg/fieldref)
+	public final static int Bit20 = 0x80000;			// contains syntax errors (method declaration, type declaration, field declarations, initializer), typeref: <> name ref: lambda capture)
+	public final static int Bit21 = 0x100000;
+	public final static int Bit22 = 0x200000;			// parenthesis count (expression) | used (import reference) shadows outer local (local declarations)
+	public final static int Bit23 = 0x400000;			// parenthesis count (expression)
+	public final static int Bit24 = 0x800000;			// parenthesis count (expression)
+	public final static int Bit25 = 0x1000000;		// parenthesis count (expression)
+	public final static int Bit26 = 0x2000000;		// parenthesis count (expression)
+	public final static int Bit27 = 0x4000000;		// parenthesis count (expression)
+	public final static int Bit28 = 0x8000000;		// parenthesis count (expression)
+	public final static int Bit29 = 0x10000000;		// parenthesis count (expression)
+	public final static int Bit30 = 0x20000000;		// elseif (if statement) | try block exit (try statement) | fall-through (case statement) | ignore no effect assign (expression ref) | needScope (for statement) | isAnySubRoutineEscaping (return statement) | blockExit (synchronized statement)
+	public final static int Bit31 = 0x40000000;		// local declaration reachable (local decl) | ignore raw type check (type ref) | discard entire assignment (assignment) | isSynchronized (return statement) | thenExit (if statement)
+	public final static int Bit32 = 0x80000000;		// reachable (statement)
+
+	public final static long Bit32L = 0x80000000L;
+	public final static long Bit33L = 0x100000000L;
+	public final static long Bit34L = 0x200000000L;
+	public final static long Bit35L = 0x400000000L;
+	public final static long Bit36L = 0x800000000L;
+	public final static long Bit37L = 0x1000000000L;
+	public final static long Bit38L = 0x2000000000L;
+	public final static long Bit39L = 0x4000000000L;
+	public final static long Bit40L = 0x8000000000L;
+	public final static long Bit41L = 0x10000000000L;
+	public final static long Bit42L = 0x20000000000L;
+	public final static long Bit43L = 0x40000000000L;
+	public final static long Bit44L = 0x80000000000L;
+	public final static long Bit45L = 0x100000000000L;
+	public final static long Bit46L = 0x200000000000L;
+	public final static long Bit47L = 0x400000000000L;
+	public final static long Bit48L = 0x800000000000L;
+	public final static long Bit49L = 0x1000000000000L;
+	public final static long Bit50L = 0x2000000000000L;
+	public final static long Bit51L = 0x4000000000000L;
+	public final static long Bit52L = 0x8000000000000L;
+	public final static long Bit53L = 0x10000000000000L;
+	public final static long Bit54L = 0x20000000000000L;
+	public final static long Bit55L = 0x40000000000000L;
+	public final static long Bit56L = 0x80000000000000L;
+	public final static long Bit57L = 0x100000000000000L;
+	public final static long Bit58L = 0x200000000000000L;
+	public final static long Bit59L = 0x400000000000000L;
+	public final static long Bit60L = 0x800000000000000L;
+	public final static long Bit61L = 0x1000000000000000L;
+	public final static long Bit62L = 0x2000000000000000L;
+	public final static long Bit63L = 0x4000000000000000L;
+	public final static long Bit64L = 0x8000000000000000L;
+
+	public int bits = IsReachable; 				// reachable by default
+
+	// for operators
+	public static final int ReturnTypeIDMASK = Bit1|Bit2|Bit3|Bit4;
+	public static final int OperatorSHIFT = 6;	// Bit7 -> Bit12
+	public static final int OperatorMASK = Bit7|Bit8|Bit9|Bit10|Bit11|Bit12; // 6 bits for operator ID
+
+	// for binary expressions
+	public static final int IsReturnedValue = Bit5;
+
+	// for cast expressions
+	public static final int UnnecessaryCast = Bit15;
+	public static final int DisableUnnecessaryCastCheck = Bit6;
+	public static final int GenerateCheckcast = Bit7;
+	public static final int UnsafeCast = Bit8;
+
+	// for name references
+	public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;
+
+	// for local decls
+	public static final int IsTypeElided = Bit2;  // type elided lambda argument.
+	public static final int IsArgument = Bit3;
+	public static final int IsLocalDeclarationReachable = Bit31;
+	public static final int IsForeachElementVariable = Bit5;
+	public static final int ShadowsOuterLocal = Bit22;
+
+	// for name refs or local decls
+	public static final int FirstAssignmentToLocal = Bit4;
+
+	// for msg or field references
+	public static final int NeedReceiverGenericCast = Bit19;
+	
+	// for this reference
+	public static final int IsImplicitThis = Bit3;
+
+	// for single name references
+	public static final int DepthSHIFT = 5;	// Bit6 -> Bit13
+	public static final int DepthMASK = Bit6|Bit7|Bit8|Bit9|Bit10|Bit11|Bit12|Bit13; // 8 bits for actual depth value (max. 255)
+	public static final int IsCapturedOuterLocal = Bit20;
+
+	// for statements
+	public static final int IsReachable = Bit32;
+	public static final int LabelUsed = Bit7;
+	public static final int DocumentedFallthrough = Bit30; // switch statement
+	public static final int DocumentedCasesOmitted = Bit31; // switch statement
+
+
+	// try statements
+	public static final int IsSubRoutineEscaping = Bit15;
+	public static final int IsTryBlockExiting = Bit30;
+
+	// for type declaration
+	public static final int ContainsAssertion = Bit1;
+	public static final int IsLocalType = Bit9;
+	public static final int IsAnonymousType = Bit10; // used to test for anonymous
+	public static final int IsMemberType = Bit11; // local member do not know it is local at parse time (need to look at binding)
+	public static final int HasAbstractMethods = Bit12; // used to promote abstract enums
+	public static final int IsSecondaryType = Bit13; // used to test for secondary
+	public static final int HasBeenGenerated = Bit14;
+
+	// for type, method and field declarations
+	public static final int HasLocalType = Bit2; // cannot conflict with AddAssertionMASK
+	public static final int HasBeenResolved = Bit5; // field decl only (to handle forward references)
+
+	// for expression
+	public static final int ParenthesizedSHIFT = 21; // Bit22 -> Bit29
+	public static final int ParenthesizedMASK = Bit22|Bit23|Bit24|Bit25|Bit26|Bit27|Bit28|Bit29; // 8 bits for parenthesis count value (max. 255)
+	public static final int IgnoreNoEffectAssignCheck = Bit30;
+
+	// for references on lhs of assignment
+	public static final int IsStrictlyAssigned = Bit14; // set only for true assignments, as opposed to compound ones
+	public static final int IsCompoundAssigned = Bit17; // set only for compound assignments, as opposed to other ones
+
+	// for explicit constructor call
+	public static final int DiscardEnclosingInstance = Bit14; // used for codegen
+
+	// for all method/constructor invocations (msg, alloc, expl. constr call)
+	public static final int Unchecked = Bit17;
+	
+	// for javadoc - used to indicate whether the javadoc has to be resolved
+	public static final int ResolveJavadoc = Bit17;
+	
+	// for empty statement
+	public static final int IsUsefulEmptyStatement = Bit1;
+
+	// for block and method declaration
+	public static final int UndocumentedEmptyBlock = Bit4;
+	public static final int OverridingMethodWithSupercall = Bit5;
+	public static final int CanBeStatic = Bit9;   // used to flag a method that can be declared static
+
+	// for initializer and method declaration
+	public static final int ErrorInSignature = Bit6;
+
+	// for abstract method declaration
+	public static final int NeedFreeReturn = Bit7; // abstract method declaration
+
+	// for constructor declaration
+	public static final int IsDefaultConstructor = Bit8;
+
+	// for compilation unit
+	public static final int HasAllMethodBodies = Bit5;
+	public static final int IsImplicitUnit = Bit1;
+
+	// for references in Javadoc comments
+	public static final int InsideJavadoc = Bit16;
+
+	// for javadoc allocation expression/javadoc message send/javadoc return statement
+	public static final int SuperAccess = Bit15;
+
+	// for javadoc return statement
+	public static final int Empty = Bit19;
+
+	// for if statement
+	public static final int IsElseIfStatement = Bit30;
+	public static final int ThenExit = Bit31;
+	public static final int IsElseStatementUnreachable = Bit8;
+	public static final int IsThenStatementUnreachable = Bit9;
+
+	// for type reference
+	public static final int IsSuperType = Bit5;
+	public static final int IsVarArgs = Bit15;
+	public static final int IgnoreRawTypeCheck = Bit31;
+
+	// for array initializer
+	public static final int IsAnnotationDefaultValue = Bit1;
+
+	// for null reference analysis
+	public static final int IsNonNull = Bit18;
+
+	// for for statement
+	public static final int NeededScope = Bit30;
+
+	// for import reference
+	public static final int OnDemand = Bit18;
+	public static final int Used = Bit2;
+
+	// for parameterized qualified/single type ref
+	public static final int DidResolve = Bit19;
+
+	// for return statement
+	public static final int IsAnySubRoutineEscaping = Bit30;
+	public static final int IsSynchronized = Bit31;
+
+	// for synchronized statement
+	public static final int BlockExit = Bit30;
+
+	// for annotation reference
+	public static final int IsRecovered = Bit6;
+
+	// for type declaration, initializer and method declaration
+	public static final int HasSyntaxErrors = Bit20;
+
+	// constants used when checking invocation arguments
+	public static final int INVOCATION_ARGUMENT_OK = 0;
+	public static final int INVOCATION_ARGUMENT_UNCHECKED = 1;
+	public static final int INVOCATION_ARGUMENT_WILDCARD = 2;
+
+	// for all declarations that can contain type references that have type annotations
+	public static final int HasTypeAnnotations = Bit21;
+	
+	// for type reference (diamond case) - Java 7
+	public static final int IsUnionType = Bit30;
+	// Used to tag ParameterizedSingleTypeReference or ParameterizedQualifiedTypeReference when they are
+	// used without any type args. It is also used to tag CompletionOnQualifiedExpression when the
+	// generics inference has failed and the resolved type still has <>.
+	public static final int IsDiamond = Bit20;
+
+	// this is only used for method invocation as the expression inside an expression statement
+	public static final int InsideExpressionStatement = Bit5;
+
+	// for annotation reference, signal if annotation was created from a default:
+	public static final int IsSynthetic = ASTNode.Bit7;
+	
+	public static final Argument [] NO_ARGUMENTS = new Argument [0];
+
+	public ASTNode() {
+
+		super();
+	}
+	private static int checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType, TypeBinding originalParameterType) {
+		argument.computeConversion(scope, parameterType, argumentType);
+
+		if (argumentType != TypeBinding.NULL && parameterType.kind() == Binding.WILDCARD_TYPE) { // intersection types are tolerated
+			WildcardBinding wildcard = (WildcardBinding) parameterType;
+			if (wildcard.boundKind != Wildcard.SUPER) {
+		    	return INVOCATION_ARGUMENT_WILDCARD;
+			}
+		}
+		TypeBinding checkedParameterType = parameterType; // originalParameterType == null ? parameterType : originalParameterType;
+		if (argumentType != checkedParameterType && argumentType.needsUncheckedConversion(checkedParameterType)) {
+			scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
+			return INVOCATION_ARGUMENT_UNCHECKED;
+		}
+		return INVOCATION_ARGUMENT_OK;
+	}
+	public static boolean checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
+		boolean is1_7 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7;
+		if (is1_7 && method.isPolymorphic()) {
+			return false;
+		}
+		TypeBinding[] params = method.parameters;
+		int paramLength = params.length;
+		boolean isRawMemberInvocation = !method.isStatic()
+				&& !receiverType.isUnboundWildcard()
+				&& method.declaringClass.isRawType()
+				&& method.hasSubstitutedParameters();
+
+		boolean uncheckedBoundCheck = (method.tagBits & TagBits.HasUncheckedTypeArgumentForBoundCheck) != 0;
+		MethodBinding rawOriginalGenericMethod = null;
+		if (!isRawMemberInvocation) {
+			if (method instanceof ParameterizedGenericMethodBinding) {
+				ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
+				if (paramMethod.isRaw && method.hasSubstitutedParameters()) {
+					rawOriginalGenericMethod = method.original();
+				}
+			}
+		}
+		int invocationStatus = INVOCATION_ARGUMENT_OK;
+		if (arguments == null) {
+			if (method.isVarargs()) {
+				TypeBinding parameterType = ((ArrayBinding) params[paramLength-1]).elementsType(); // no element was supplied for vararg parameter
+				if (!parameterType.isReifiable()
+						&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
+					scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
+				}
+			}
+		} else {
+			if (method.isVarargs()) {
+				// 4 possibilities exist for a call to the vararg method foo(int i, long ... value) : foo(1), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new long[] {1, 2})
+				int lastIndex = paramLength - 1;
+				for (int i = 0; i < lastIndex; i++) {
+					TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
+					invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i] , argumentTypes[i], originalRawParam);
+				}
+				int argLength = arguments.length;
+				if (lastIndex <= argLength) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337093
+					TypeBinding parameterType = params[lastIndex];
+					TypeBinding originalRawParam = null;
+
+					if (paramLength != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions()) {
+						parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
+						if (!parameterType.isReifiable()
+								&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
+							scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
+						}
+						originalRawParam = rawOriginalGenericMethod == null ? null : ((ArrayBinding)rawOriginalGenericMethod.parameters[lastIndex]).elementsType();
+					}
+					for (int i = lastIndex; i < argLength; i++) {
+						invocationStatus |= checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i], originalRawParam);
+					}
+				} 
+				if (paramLength == argLength) { // 70056
+					int varargsIndex = paramLength - 1;
+					ArrayBinding varargsType = (ArrayBinding) params[varargsIndex];
+					TypeBinding lastArgType = argumentTypes[varargsIndex];
+					int dimensions;
+					if (lastArgType == TypeBinding.NULL) {
+						if (!(varargsType.leafComponentType().isBaseType() && varargsType.dimensions() == 1))
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+					} else if (varargsType.dimensions <= (dimensions = lastArgType.dimensions())) {
+						if (lastArgType.leafComponentType().isBaseType()) {
+							dimensions--;
+						}
+						if (varargsType.dimensions < dimensions) {
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+						} else if (varargsType.dimensions == dimensions
+										&& lastArgType != varargsType
+										&& lastArgType.leafComponentType().erasure() != varargsType.leafComponentType.erasure()
+										&& lastArgType.isCompatibleWith(varargsType.elementsType())
+										&& lastArgType.isCompatibleWith(varargsType)) {
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+						}
+					}
+				}
+			} else {
+				for (int i = 0; i < paramLength; i++) {
+					TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
+					invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i], originalRawParam);
+				}
+			}
+			if (argsContainCast) {
+				CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
+			}
+		}
+		if ((invocationStatus & INVOCATION_ARGUMENT_WILDCARD) != 0) {
+			scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
+		} else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
+			if (scope.compilerOptions().reportUnavoidableGenericTypeProblems || receiver == null || !receiver.forcedToBeRaw(scope.referenceContext())) {
+				scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
+			}
+		} else if (rawOriginalGenericMethod != null 
+				|| uncheckedBoundCheck
+				|| ((invocationStatus & INVOCATION_ARGUMENT_UNCHECKED) != 0 
+						&& method instanceof ParameterizedGenericMethodBinding
+						/*&& method.returnType != scope.environment().convertToRawType(method.returnType.erasure(), true)*/)) {
+			scope.problemReporter().unsafeRawGenericMethodInvocation((ASTNode)invocationSite, method, argumentTypes);
+			return true;
+		}
+		return false;
+	}
+	public ASTNode concreteStatement() {
+		return this;
+	}
+
+	public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, int filteredBits) {
+		if ((this.bits & ASTNode.InsideJavadoc) == 0			// ignore references inside Javadoc comments 
+				&& (filteredBits & IsStrictlyAssigned) == 0 	// ignore write access
+				&& field.isOrEnclosedByPrivateType() 
+				&& !scope.isDefinedInField(field)) 				// ignore cases where field is used from inside itself 
+		{		
+			if (((filteredBits & IsCompoundAssigned) != 0))
+				// used, but usage may not be relevant
+				field.original().compoundUseFlag++;
+			else
+				field.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+		}
+
+		if ((field.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
+			AccessRestriction restriction =
+				scope.environment().getAccessRestriction(field.declaringClass.erasure());
+			if (restriction != null) {
+				scope.problemReporter().forbiddenReference(field, this,
+						restriction.classpathEntryType, restriction.classpathEntryName,
+						restriction.getProblemId());
+			}
+		}
+
+		if (!field.isViewedAsDeprecated()) return false;
+
+		// inside same unit - no report
+		if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
+
+		// if context is deprecated, may avoid reporting
+		if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+		return true;
+	}
+
+	public boolean isImplicitThis() {
+
+		return false;
+	}
+
+	public boolean receiverIsImplicitThis() {
+
+		return false;
+	}
+
+	/* Answer true if the method use is considered deprecated.
+	* An access in the same compilation unit is allowed.
+	*/
+	public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope,
+			boolean isExplicitUse) {
+		// ignore references insing Javadoc comments
+		if ((this.bits & ASTNode.InsideJavadoc) == 0 && method.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(method)) {
+			// ignore cases where method is used from inside itself (e.g. direct recursions)
+			method.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+		}
+
+		// TODO (maxime) consider separating concerns between deprecation and access restriction.
+		// 				 Caveat: this was not the case when access restriction funtion was added.
+		if (isExplicitUse && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
+			// note: explicit constructors calls warnings are kept despite the 'new C1()' case (two
+			//       warnings, one on type, the other on constructor), because of the 'super()' case.
+			AccessRestriction restriction =
+				scope.environment().getAccessRestriction(method.declaringClass.erasure());
+			if (restriction != null) {
+				scope.problemReporter().forbiddenReference(method, this,
+						restriction.classpathEntryType, restriction.classpathEntryName,
+						restriction.getProblemId());
+			}
+		}
+
+		if (!method.isViewedAsDeprecated()) return false;
+
+		// inside same unit - no report
+		if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
+
+		// non explicit use and non explicitly deprecated - no report
+		if (!isExplicitUse &&
+				(method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
+			return false;
+		}
+
+		// if context is deprecated, may avoid reporting
+		if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+		return true;
+	}
+
+	public boolean isSuper() {
+
+		return false;
+	}
+
+	public boolean isThis() {
+
+		return false;
+	}
+
+	/* Answer true if the type use is considered deprecated.
+	* An access in the same compilation unit is allowed.
+	*/
+	public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {
+
+		if (type.isArrayType()) {
+			type = ((ArrayBinding) type).leafComponentType;
+		}
+		if (type.isBaseType())
+			return false;
+
+		ReferenceBinding refType = (ReferenceBinding) type;
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397888
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
+		if ((this.bits & ASTNode.InsideJavadoc) == 0  && refType instanceof TypeVariableBinding) {
+			refType.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+		}
+		// ignore references insing Javadoc comments
+		if ((this.bits & ASTNode.InsideJavadoc) == 0 && refType.isOrEnclosedByPrivateType() && !scope.isDefinedInType(refType)) {
+			// ignore cases where type is used from inside itself
+			((ReferenceBinding)refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+		}
+
+		if (refType.hasRestrictedAccess()) {
+			AccessRestriction restriction = scope.environment().getAccessRestriction(type.erasure());
+			if (restriction != null) {
+				scope.problemReporter().forbiddenReference(type, this, restriction.classpathEntryType,
+						restriction.classpathEntryName, restriction.getProblemId());
+			}
+		}
+
+		// force annotations resolution before deciding whether the type may be deprecated
+		refType.initializeDeprecatedAnnotationTagBits();
+
+		if (!refType.isViewedAsDeprecated()) return false;
+
+		// inside same unit - no report
+		if (scope.isDefinedInSameUnit(refType)) return false;
+
+		// if context is deprecated, may avoid reporting
+		if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+		return true;
+	}
+
+	public abstract StringBuffer print(int indent, StringBuffer output);
+
+	public static StringBuffer printAnnotations(Annotation[] annotations, StringBuffer output) {
+		int length = annotations.length;
+		for (int i = 0; i < length; i++) {
+			if (i > 0) {
+				output.append(" "); //$NON-NLS-1$
+			}
+			Annotation annotation2 = annotations[i];
+			if (annotation2 != null) {
+				annotation2.print(0, output);
+			} else {
+				output.append('?');
+			}
+		}
+		return output;
+	}
+
+	public static StringBuffer printIndent(int indent, StringBuffer output) {
+
+		for (int i = indent; i > 0; i--) output.append("  "); //$NON-NLS-1$
+		return output;
+	}
+
+	public static StringBuffer printModifiers(int modifiers, StringBuffer output) {
+
+		if ((modifiers & ClassFileConstants.AccPublic) != 0)
+			output.append("public "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccPrivate) != 0)
+			output.append("private "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccProtected) != 0)
+			output.append("protected "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccStatic) != 0)
+			output.append("static "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccFinal) != 0)
+			output.append("final "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccSynchronized) != 0)
+			output.append("synchronized "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccVolatile) != 0)
+			output.append("volatile "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccTransient) != 0)
+			output.append("transient "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccNative) != 0)
+			output.append("native "); //$NON-NLS-1$
+		if ((modifiers & ClassFileConstants.AccAbstract) != 0)
+			output.append("abstract "); //$NON-NLS-1$
+		return output;
+	}
+
+	public static boolean polyExpressionsHaveErrors(BlockScope scope, MethodBinding methodBinding, Expression [] arguments, TypeBinding[] argumentTypes) {
+		boolean polyExpressionsHaveErrors = false;
+		MethodBinding candidateMethod;
+		if (methodBinding.isValidBinding()) {
+			candidateMethod = methodBinding;
+		} else if (methodBinding instanceof ProblemMethodBinding) {
+			candidateMethod = ((ProblemMethodBinding) methodBinding).closestMatch;
+		} else {
+			candidateMethod = null;
+		}
+		if (candidateMethod != null) {
+			boolean variableArity = candidateMethod.isVarargs();
+			final TypeBinding[] parameters = candidateMethod.parameters;
+			final int parametersLength = parameters.length;
+			for (int i = 0, length = arguments == null ? 0 : arguments.length; i < length; i++) {
+				if (argumentTypes[i] instanceof PolyTypeBinding) {
+					Expression argument = arguments[i];
+					TypeBinding parameterType = i < parametersLength ? parameters[i] : variableArity ? parameters[parametersLength - 1] : null;
+					argument.setExpressionContext(parameterType != null ? ExpressionContext.INVOCATION_CONTEXT: ExpressionContext.ASSIGNMENT_CONTEXT); // force the errors to surface.
+					if (variableArity && i >= parametersLength - 1)
+						argument.tagAsEllipsisArgument();
+					argument.setExpectedType(parameterType);
+					TypeBinding argumentType = argument.resolveType(scope);
+					if (argumentType == null || !argumentType.isValidBinding())
+						polyExpressionsHaveErrors = true;
+					if (argument instanceof LambdaExpression && ((LambdaExpression) argument).hasErrors())
+						polyExpressionsHaveErrors = true;
+				}
+			}
+		}
+		return polyExpressionsHaveErrors;
+	}
+	/**
+	 * Resolve annotations, and check duplicates, answers combined tagBits
+	 * for recognized standard annotations
+	 */
+	public static void resolveAnnotations(BlockScope scope, Annotation[] sourceAnnotations, Binding recipient) {
+		AnnotationBinding[] annotations = null;
+		int length = sourceAnnotations == null ? 0 : sourceAnnotations.length;
+		if (recipient != null) {
+			switch (recipient.kind()) {
+				case Binding.PACKAGE :
+					PackageBinding packageBinding = (PackageBinding) recipient;
+					if ((packageBinding.tagBits & TagBits.AnnotationResolved) != 0) return;
+					packageBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					break;
+				case Binding.TYPE :
+				case Binding.GENERIC_TYPE :
+					ReferenceBinding type = (ReferenceBinding) recipient;
+					if ((type.tagBits & TagBits.AnnotationResolved) != 0) return;
+					type.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						type.setAnnotations(annotations);
+					}
+					break;
+				case Binding.METHOD :
+					MethodBinding method = (MethodBinding) recipient;
+					if ((method.tagBits & TagBits.AnnotationResolved) != 0) return;
+					method.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						method.setAnnotations(annotations);
+					}
+					break;
+				case Binding.FIELD :
+					FieldBinding field = (FieldBinding) recipient;
+					if ((field.tagBits & TagBits.AnnotationResolved) != 0) return;
+					field.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						field.setAnnotations(annotations);
+					}
+					break;
+				case Binding.LOCAL :
+					LocalVariableBinding local = (LocalVariableBinding) recipient;
+					if ((local.tagBits & TagBits.AnnotationResolved) != 0) return;
+					local.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						local.setAnnotations(annotations, scope);
+					}
+					break;
+				case Binding.TYPE_PARAMETER :
+					// jsr308
+					ReferenceBinding typeVariableBinding = (ReferenceBinding) recipient;
+					if ((typeVariableBinding.tagBits & TagBits.AnnotationResolved) != 0) return;
+					typeVariableBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						typeVariableBinding.setAnnotations(annotations);
+					}
+					break;
+				case Binding.TYPE_USE :
+					ReferenceBinding typeUseBinding = (ReferenceBinding) recipient;
+					if ((typeUseBinding.tagBits & TagBits.AnnotationResolved) != 0) return;
+					typeUseBinding.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+					if (length > 0) {
+						annotations = new AnnotationBinding[length];
+						typeUseBinding.setAnnotations(annotations);
+					}
+					break;
+				default :
+					return;
+			}
+		}
+		if (sourceAnnotations == null)
+			return;
+		for (int i = 0; i < length; i++) {
+			Annotation annotation = sourceAnnotations[i];
+			final Binding annotationRecipient = annotation.recipient;
+			if (annotationRecipient != null && recipient != null) {
+				// only local and field can share annnotations
+				switch (recipient.kind()) {
+					case Binding.FIELD :
+						FieldBinding field = (FieldBinding) recipient;
+						field.tagBits = ((FieldBinding) annotationRecipient).tagBits;
+						if (annotations != null) {
+							// need to fill the instances array
+							for (int j = 0; j < length; j++) {
+								Annotation annot = sourceAnnotations[j];
+								annotations[j] = annot.getCompilerAnnotation();
+							}
+						}
+						break;
+					case Binding.LOCAL :
+						LocalVariableBinding local = (LocalVariableBinding) recipient;
+						long otherLocalTagBits = ((LocalVariableBinding) annotationRecipient).tagBits;
+						local.tagBits = otherLocalTagBits;
+						if ((otherLocalTagBits & TagBits.AnnotationSuppressWarnings) == 0) {
+							// None of the annotations is a SuppressWarnings annotation
+							// need to fill the instances array
+							if (annotations != null) {
+								for (int j = 0; j < length; j++) {
+									Annotation annot = sourceAnnotations[j];
+									annotations[j] = annot.getCompilerAnnotation();
+								}
+							}
+						} else if (annotations != null) {
+							// One of the annotations at least is a SuppressWarnings annotation
+							LocalDeclaration localDeclaration = local.declaration;
+							int declarationSourceEnd = localDeclaration.declarationSourceEnd;
+							int declarationSourceStart = localDeclaration.declarationSourceStart;
+							for (int j = 0; j < length; j++) {
+								Annotation annot = sourceAnnotations[j];
+								/*
+								 * Annotations are shared between two locals, but we still need to record
+								 * the suppress annotation range for the second local
+								 */
+								AnnotationBinding annotationBinding = annot.getCompilerAnnotation();
+								annotations[j] = annotationBinding;
+								if (annotationBinding != null) {
+									final ReferenceBinding annotationType = annotationBinding.getAnnotationType();
+									if (annotationType != null && annotationType.id == TypeIds.T_JavaLangSuppressWarnings) {
+										annot.recordSuppressWarnings(scope, declarationSourceStart, declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+									}
+								}
+							}
+						}
+						break;
+				}
+				return;
+			} else {
+				annotation.recipient = recipient;
+				annotation.resolveType(scope);
+				// null if receiver is a package binding
+				if (annotations != null) {
+					annotations[i] = annotation.getCompilerAnnotation();
+				}
+			}
+		}
+		// check duplicate annotations
+		if (annotations != null) {
+			AnnotationBinding[] distinctAnnotations = annotations; // only copy after 1st duplicate is detected
+			for (int i = 0; i < length; i++) {
+				AnnotationBinding annotation = distinctAnnotations[i];
+				if (annotation == null) continue;
+				TypeBinding annotationType = annotation.getAnnotationType();
+				boolean foundDuplicate = false;
+				for (int j = i+1; j < length; j++) {
+					AnnotationBinding otherAnnotation = distinctAnnotations[j];
+					if (otherAnnotation == null) continue;
+					if (otherAnnotation.getAnnotationType() == annotationType) {
+						foundDuplicate = true;
+						if (distinctAnnotations == annotations) {
+							System.arraycopy(distinctAnnotations, 0, distinctAnnotations = new AnnotationBinding[length], 0, length);
+						}
+						distinctAnnotations[j] = null; // report it only once
+						scope.problemReporter().duplicateAnnotation(sourceAnnotations[j]);
+					}
+				}
+				if (foundDuplicate) {
+					scope.problemReporter().duplicateAnnotation(sourceAnnotations[i]);
+				}
+			}
+		}
+	}
+
+/**
+ * Figures if @Deprecated annotation is specified, do not resolve entire annotations.
+ */
+public static void resolveDeprecatedAnnotations(BlockScope scope, Annotation[] annotations, Binding recipient) {
+	if (recipient != null) {
+		int kind = recipient.kind();
+		if (annotations != null) {
+			int length;
+			if ((length = annotations.length) >= 0) {
+				switch (kind) {
+					case Binding.PACKAGE :
+						PackageBinding packageBinding = (PackageBinding) recipient;
+						if ((packageBinding.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
+						break;
+					case Binding.TYPE :
+					case Binding.GENERIC_TYPE :
+						ReferenceBinding type = (ReferenceBinding) recipient;
+						if ((type.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
+						break;
+					case Binding.METHOD :
+						MethodBinding method = (MethodBinding) recipient;
+						if ((method.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
+						break;
+					case Binding.FIELD :
+						FieldBinding field = (FieldBinding) recipient;
+						if ((field.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
+						break;
+					case Binding.LOCAL :
+						LocalVariableBinding local = (LocalVariableBinding) recipient;
+						if ((local.tagBits & TagBits.DeprecatedAnnotationResolved) != 0) return;
+						break;
+					default :
+						return;
+				}
+				for (int i = 0; i < length; i++) {
+					TypeReference annotationTypeRef = annotations[i].type;
+					// only resolve type name if 'Deprecated' last token
+					if (!CharOperation.equals(TypeConstants.JAVA_LANG_DEPRECATED[2], annotationTypeRef.getLastToken())) continue;
+					TypeBinding annotationType = annotations[i].type.resolveType(scope);
+					if(annotationType != null && annotationType.isValidBinding() && annotationType.id == TypeIds.T_JavaLangDeprecated) {
+						switch (kind) {
+							case Binding.PACKAGE :
+								PackageBinding packageBinding = (PackageBinding) recipient;
+								packageBinding.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
+								return;
+							case Binding.TYPE :
+							case Binding.GENERIC_TYPE :
+							case Binding.TYPE_PARAMETER :
+								ReferenceBinding type = (ReferenceBinding) recipient;
+								type.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
+								return;
+							case Binding.METHOD :
+								MethodBinding method = (MethodBinding) recipient;
+								method.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
+								return;
+							case Binding.FIELD :
+								FieldBinding field = (FieldBinding) recipient;
+								field.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
+								return;
+							case Binding.LOCAL :
+								LocalVariableBinding local = (LocalVariableBinding) recipient;
+								local.tagBits |= (TagBits.AnnotationDeprecated | TagBits.DeprecatedAnnotationResolved);
+								return;
+							default:
+								return;
+						}
+					}
+				}
+			}
+		}
+		switch (kind) {
+			case Binding.PACKAGE :
+				PackageBinding packageBinding = (PackageBinding) recipient;
+				packageBinding.tagBits |= TagBits.DeprecatedAnnotationResolved;
+				return;
+			case Binding.TYPE :
+			case Binding.GENERIC_TYPE :
+			case Binding.TYPE_PARAMETER :
+				ReferenceBinding type = (ReferenceBinding) recipient;
+				type.tagBits |= TagBits.DeprecatedAnnotationResolved;
+				return;
+			case Binding.METHOD :
+				MethodBinding method = (MethodBinding) recipient;
+				method.tagBits |= TagBits.DeprecatedAnnotationResolved;
+				return;
+			case Binding.FIELD :
+				FieldBinding field = (FieldBinding) recipient;
+				field.tagBits |= TagBits.DeprecatedAnnotationResolved;
+				return;
+			case Binding.LOCAL :
+				LocalVariableBinding local = (LocalVariableBinding) recipient;
+				local.tagBits |= TagBits.DeprecatedAnnotationResolved;
+				return;
+			default:
+				return;
+		}
+	}
+}
+
+	public int sourceStart() {
+		return this.sourceStart;
+	}
+	public int sourceEnd() {
+		return this.sourceEnd;
+	}
+	public String toString() {
+
+		return print(0, new StringBuffer(30)).toString();
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		// do nothing by default
+	}
+}
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
new file mode 100644
index 0000000..a048315
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -0,0 +1,634 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 367203 - [compiler][null] detect assigning null to nonnull argument
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 401030 - [1.8][null] Null analysis support for lambda methods.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public abstract class AbstractMethodDeclaration
+	extends ASTNode
+	implements ProblemSeverities, ReferenceContext {
+
+	public MethodScope scope;
+	//it is not relevent for constructor but it helps to have the name of the constructor here
+	//which is always the name of the class.....parsing do extra work to fill it up while it do not have to....
+	public char[] selector;
+	public int declarationSourceStart;
+	public int declarationSourceEnd;
+	public int modifiers;
+	public int modifiersSourceStart;
+	public Annotation[] annotations;
+	// jsr 308
+	public Receiver receiver;
+	public Argument[] arguments;
+	public TypeReference[] thrownExceptions;
+	public Statement[] statements;
+	public int explicitDeclarations;
+	public MethodBinding binding;
+	public boolean ignoreFurtherInvestigation = false;
+
+	public Javadoc javadoc;
+
+	public int bodyStart;
+	public int bodyEnd = -1;
+	public CompilationResult compilationResult;
+
+	AbstractMethodDeclaration(CompilationResult compilationResult){
+		this.compilationResult = compilationResult;
+	}
+
+	/*
+	 *	We cause the compilation task to abort to a given extent.
+	 */
+	public void abort(int abortLevel, CategorizedProblem problem) {
+
+		switch (abortLevel) {
+			case AbortCompilation :
+				throw new AbortCompilation(this.compilationResult, problem);
+			case AbortCompilationUnit :
+				throw new AbortCompilationUnit(this.compilationResult, problem);
+			case AbortType :
+				throw new AbortType(this.compilationResult, problem);
+			default :
+				throw new AbortMethod(this.compilationResult, problem);
+		}
+	}
+
+	/**
+	 * When a method is accessed via SourceTypeBinding.resolveTypesFor(MethodBinding)
+	 * we create the argument binding and resolve annotations in order to compute null annotation tagbits.
+	 */
+	public void createArgumentBindings() {
+		createArgumentBindings(this.arguments, this.binding, this.scope);
+	}
+	// version for invocation from LambdaExpression:
+	static void createArgumentBindings(Argument[] arguments, MethodBinding binding, MethodScope scope) {
+		if (arguments != null && binding != null) {
+			for (int i = 0, length = arguments.length; i < length; i++) {
+				Argument argument = arguments[i];
+				argument.createBinding(scope, binding.parameters[i]);
+				// createBinding() has resolved annotations, now transfer nullness info from the argument to the method:
+				// prefer type annotation:
+				long argTypeTagBits = (argument.type.resolvedType.tagBits & TagBits.AnnotationNullMASK);
+				// if none found try SE7 annotation:
+				if (argTypeTagBits == 0) {
+					argTypeTagBits = (argument.binding.tagBits & TagBits.AnnotationNullMASK);
+				}
+				if (argTypeTagBits != 0) {
+					if (binding.parameterNonNullness == null) {
+						binding.parameterNonNullness = new Boolean[arguments.length];
+						binding.tagBits |= TagBits.IsNullnessKnown;
+					}
+					binding.parameterNonNullness[i] = Boolean.valueOf(argTypeTagBits == TagBits.AnnotationNonNull);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Bind and add argument's binding into the scope of the method
+	 */
+	public void bindArguments() {
+
+		if (this.arguments != null) {
+			// by default arguments in abstract/native methods are considered to be used (no complaint is expected)
+			if (this.binding == null) {
+				for (int i = 0, length = this.arguments.length; i < length; i++) {
+					this.arguments[i].bind(this.scope, null, true);
+				}
+				return;
+			}
+			boolean used = this.binding.isAbstract() || this.binding.isNative();
+			AnnotationBinding[][] paramAnnotations = null;
+			for (int i = 0, length = this.arguments.length; i < length; i++) {
+				Argument argument = this.arguments[i];
+				argument.bind(this.scope, this.binding.parameters[i], used);
+				if (argument.annotations != null) {
+					if (paramAnnotations == null) {
+						paramAnnotations = new AnnotationBinding[length][];
+						for (int j=0; j<i; j++) {
+							paramAnnotations[j] = Binding.NO_ANNOTATIONS;
+						}
+					}
+					paramAnnotations[i] = argument.binding.getAnnotations();
+				} else if (paramAnnotations != null) {
+					paramAnnotations[i] = Binding.NO_ANNOTATIONS;
+				}
+			}
+			if (paramAnnotations != null)
+				this.binding.setParameterAnnotations(paramAnnotations);
+		}
+	}
+
+	/**
+	 * Record the thrown exception type bindings in the corresponding type references.
+	 */
+	public void bindThrownExceptions() {
+
+		if (this.thrownExceptions != null
+			&& this.binding != null
+			&& this.binding.thrownExceptions != null) {
+			int thrownExceptionLength = this.thrownExceptions.length;
+			int length = this.binding.thrownExceptions.length;
+			if (length == thrownExceptionLength) {
+				for (int i = 0; i < length; i++) {
+					this.thrownExceptions[i].resolvedType = this.binding.thrownExceptions[i];
+				}
+			} else {
+				int bindingIndex = 0;
+				for (int i = 0; i < thrownExceptionLength && bindingIndex < length; i++) {
+					TypeReference thrownException = this.thrownExceptions[i];
+					ReferenceBinding thrownExceptionBinding = this.binding.thrownExceptions[bindingIndex];
+					char[][] bindingCompoundName = thrownExceptionBinding.compoundName;
+					if (bindingCompoundName == null) continue; // skip problem case
+					if (thrownException instanceof SingleTypeReference) {
+						// single type reference
+						int lengthName = bindingCompoundName.length;
+						char[] thrownExceptionTypeName = thrownException.getTypeName()[0];
+						if (CharOperation.equals(thrownExceptionTypeName, bindingCompoundName[lengthName - 1])) {
+							thrownException.resolvedType = thrownExceptionBinding;
+							bindingIndex++;
+						}
+					} else {
+						// qualified type reference
+						if (CharOperation.equals(thrownException.getTypeName(), bindingCompoundName)) {
+							thrownException.resolvedType = thrownExceptionBinding;
+							bindingIndex++;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Feed null information from argument annotations into the analysis and mark arguments as assigned.
+	 */
+	static void analyseArguments(FlowInfo flowInfo, Argument[] methodArguments, MethodBinding methodBinding) {
+		if (methodArguments != null) {
+			for (int i = 0, count = methodArguments.length; i < count; i++) {
+				if (methodBinding.parameterNonNullness != null) {
+					// leverage null-info from parameter annotations:
+					Boolean nonNullNess = methodBinding.parameterNonNullness[i];
+					if (nonNullNess != null) {
+						if (nonNullNess.booleanValue())
+							flowInfo.markAsDefinitelyNonNull(methodArguments[i].binding);
+						else
+							flowInfo.markPotentiallyNullBit(methodArguments[i].binding);
+					}
+				}
+				// tag parameters as being set:
+				flowInfo.markAsDefinitelyAssigned(methodArguments[i].binding);
+			}
+		}
+	}
+
+	public CompilationResult compilationResult() {
+
+		return this.compilationResult;
+	}
+
+	/**
+	 * Bytecode generation for a method
+	 * @param classScope
+	 * @param classFile
+	 */
+	public void generateCode(ClassScope classScope, ClassFile classFile) {
+
+		int problemResetPC = 0;
+		classFile.codeStream.wideMode = false; // reset wideMode to false
+		if (this.ignoreFurtherInvestigation) {
+			// method is known to have errors, dump a problem method
+			if (this.binding == null)
+				return; // handle methods with invalid signature or duplicates
+			int problemsLength;
+			CategorizedProblem[] problems =
+				this.scope.referenceCompilationUnit().compilationResult.getProblems();
+			CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+			System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+			classFile.addProblemMethod(this, this.binding, problemsCopy);
+			return;
+		}
+		boolean restart = false;
+		boolean abort = false;
+		// regular code generation
+		do {
+			try {
+				problemResetPC = classFile.contentsOffset;
+				this.generateCode(classFile);
+				restart = false;
+			} catch (AbortMethod e) {
+				// a fatal error was detected during code generation, need to restart code gen if possible
+				if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
+					// a branch target required a goto_w, restart code gen in wide mode.
+					classFile.contentsOffset = problemResetPC;
+					classFile.methodCount--;
+					classFile.codeStream.resetInWideMode(); // request wide mode
+					restart = true;
+				} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
+					classFile.contentsOffset = problemResetPC;
+					classFile.methodCount--;
+					classFile.codeStream.resetForCodeGenUnusedLocals();
+					restart = true;
+				} else {
+					restart = false;
+					abort = true; 
+				}
+			}
+		} while (restart);
+		// produce a problem method accounting for this fatal error
+		if (abort) {
+			int problemsLength;
+			CategorizedProblem[] problems =
+				this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
+			CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+			System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+			classFile.addProblemMethod(this, this.binding, problemsCopy, problemResetPC);
+		}
+	}
+
+	public void generateCode(ClassFile classFile) {
+
+		classFile.generateMethodInfoHeader(this.binding);
+		int methodAttributeOffset = classFile.contentsOffset;
+		int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
+		if ((!this.binding.isNative()) && (!this.binding.isAbstract())) {
+			int codeAttributeOffset = classFile.contentsOffset;
+			classFile.generateCodeAttributeHeader();
+			CodeStream codeStream = classFile.codeStream;
+			codeStream.reset(this, classFile);
+			// initialize local positions
+			this.scope.computeLocalVariablePositions(this.binding.isStatic() ? 0 : 1, codeStream);
+
+			// arguments initialization for local variable debug attributes
+			if (this.arguments != null) {
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					LocalVariableBinding argBinding;
+					codeStream.addVisibleLocalVariable(argBinding = this.arguments[i].binding);
+					argBinding.recordInitializationStartPC(0);
+				}
+			}
+			if (this.statements != null) {
+				for (int i = 0, max = this.statements.length; i < max; i++)
+					this.statements[i].generateCode(this.scope, codeStream);
+			}
+			// if a problem got reported during code gen, then trigger problem method creation
+			if (this.ignoreFurtherInvestigation) {
+				throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
+			}
+			if ((this.bits & ASTNode.NeedFreeReturn) != 0) {
+				codeStream.return_();
+			}
+			// local variable attributes
+			codeStream.exitUserScope(this.scope);
+			codeStream.recordPositionsFrom(0, this.declarationSourceEnd);
+			try {
+				classFile.completeCodeAttribute(codeAttributeOffset);
+			} catch(NegativeArraySizeException e) {
+				throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
+			}
+			attributeNumber++;
+		} else {
+			checkArgumentsSize();
+		}
+		classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
+	}
+
+	public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
+		// do nothing
+	}
+
+	private void checkArgumentsSize() {
+		TypeBinding[] parameters = this.binding.parameters;
+		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 :
+				case TypeIds.T_double :
+					size += 2;
+					break;
+				default :
+					size++;
+					break;
+			}
+			if (size > 0xFF) {
+				this.scope.problemReporter().noMoreAvailableSpaceForArgument(this.scope.locals[i], this.scope.locals[i].declaration);
+			}
+		}
+	}
+
+	public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+		if (this.scope != null) {
+			return this.scope.compilationUnitScope().referenceContext;
+		}
+		return null;
+	}
+
+	public boolean hasErrors() {
+		return this.ignoreFurtherInvestigation;
+	}
+
+	public boolean isAbstract() {
+
+		if (this.binding != null)
+			return this.binding.isAbstract();
+		return (this.modifiers & ClassFileConstants.AccAbstract) != 0;
+	}
+
+	public boolean isAnnotationMethod() {
+
+		return false;
+	}
+
+	public boolean isClinit() {
+
+		return false;
+	}
+
+	public boolean isConstructor() {
+
+		return false;
+	}
+
+	public boolean isDefaultConstructor() {
+
+		return false;
+	}
+
+	public boolean isDefaultMethod() {
+		return false;
+	}
+
+	public boolean isInitializationMethod() {
+
+		return false;
+	}
+
+	public boolean isMethod() {
+
+		return false;
+	}
+
+	public boolean isNative() {
+
+		if (this.binding != null)
+			return this.binding.isNative();
+		return (this.modifiers & ClassFileConstants.AccNative) != 0;
+	}
+
+	public boolean isStatic() {
+
+		if (this.binding != null)
+			return this.binding.isStatic();
+		return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+	}
+
+	/**
+	 * Fill up the method body with statement
+	 * @param parser
+	 * @param unit
+	 */
+	public abstract void parseStatements(Parser parser, CompilationUnitDeclaration unit);
+
+	public StringBuffer print(int tab, StringBuffer output) {
+
+		if (this.javadoc != null) {
+			this.javadoc.print(tab, output);
+		}
+		printIndent(tab, output);
+		printModifiers(this.modifiers, output);
+		if (this.annotations != null) {
+			printAnnotations(this.annotations, output);
+			output.append(' ');
+		}
+
+		TypeParameter[] typeParams = typeParameters();
+		if (typeParams != null) {
+			output.append('<');
+			int max = typeParams.length - 1;
+			for (int j = 0; j < max; j++) {
+				typeParams[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			typeParams[max].print(0, output);
+			output.append('>');
+		}
+
+		printReturnType(0, output).append(this.selector).append('(');
+		if (this.receiver != null) {
+			this.receiver.print(0, output);
+		}
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0 || this.receiver != null) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].print(0, output);
+			}
+		}
+		output.append(')');
+		if (this.thrownExceptions != null) {
+			output.append(" throws "); //$NON-NLS-1$
+			for (int i = 0; i < this.thrownExceptions.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.thrownExceptions[i].print(0, output);
+			}
+		}
+		printBody(tab + 1, output);
+		return output;
+	}
+
+	public StringBuffer printBody(int indent, StringBuffer output) {
+
+		if (isAbstract() || (this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
+			return output.append(';');
+
+		output.append(" {"); //$NON-NLS-1$
+		if (this.statements != null) {
+			for (int i = 0; i < this.statements.length; i++) {
+				output.append('\n');
+				this.statements[i].printStatement(indent, output);
+			}
+		}
+		output.append('\n');
+		printIndent(indent == 0 ? 0 : indent - 1, output).append('}');
+		return output;
+	}
+
+	public StringBuffer printReturnType(int indent, StringBuffer output) {
+
+		return output;
+	}
+
+	public void resolve(ClassScope upperScope) {
+
+		if (this.binding == null) {
+			this.ignoreFurtherInvestigation = true;
+		}
+
+		try {
+			bindArguments();
+			resolveReceiver();
+			bindThrownExceptions();
+			resolveJavadoc();
+			resolveAnnotations(this.scope, this.annotations, this.binding);
+			validateNullAnnotations();
+			resolveStatements();
+			// check @Deprecated annotation presence
+			if (this.binding != null
+					&& (this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0
+					&& (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0
+					&& this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+				this.scope.problemReporter().missingDeprecatedAnnotationForMethod(this);
+			}
+		} catch (AbortMethod e) {
+			// ========= abort on fatal error =============
+			this.ignoreFurtherInvestigation = true;
+		}
+	}
+
+	public void resolveReceiver() {
+		if (this.receiver == null) return;
+
+		if (this.receiver.modifiers != 0) {
+			this.scope.problemReporter().illegalModifiers(this.receiver.declarationSourceStart, this.receiver.declarationSourceEnd);
+		}
+
+		TypeBinding resolvedReceiverType = this.receiver.type.resolvedType;
+		if (this.binding == null || resolvedReceiverType == null || !resolvedReceiverType.isValidBinding()) {
+			return;
+		}
+
+		ReferenceBinding declaringClass = this.binding.declaringClass;
+		/* neither static methods nor methods in anonymous types can have explicit 'this' */
+		if (this.isStatic() || declaringClass.isAnonymousType()) {
+			this.scope.problemReporter().disallowedThisParameter(this.receiver);
+			this.receiver = null;
+			return; // No need to do further validation
+		}
+
+		ReferenceBinding enclosingReceiver = this.scope.enclosingReceiverType();
+		if (this.isConstructor()) {
+			/* Only non static member types or local types can declare explicit 'this' params in constructors */
+			if (declaringClass.isStatic()
+					|| (declaringClass.tagBits & (TagBits.IsLocalType | TagBits.IsMemberType)) == 0) { /* neither member nor local type */
+				this.scope.problemReporter().disallowedThisParameter(this.receiver);
+				this.receiver = null;
+				return; // No need to do further validation
+			}
+			enclosingReceiver = enclosingReceiver.enclosingType();
+		}
+
+		char[][] tokens = (this.receiver.qualifyingName == null) ? null : this.receiver.qualifyingName.getName();
+		if (this.isConstructor()) {
+			if (tokens == null || tokens.length > 1 || !CharOperation.equals(enclosingReceiver.sourceName(), tokens[0])) {
+				this.scope.problemReporter().illegalQualifierForExplicitThis(this.receiver, enclosingReceiver);
+				this.receiver.qualifyingName = null;
+			}
+		} else if (tokens != null && tokens.length > 0) {
+			this.scope.problemReporter().illegalQualifierForExplicitThis2(this.receiver);
+			this.receiver.qualifyingName = null;
+		}
+
+		if (enclosingReceiver != resolvedReceiverType) {
+			this.scope.problemReporter().illegalTypeForExplicitThis(this.receiver, enclosingReceiver);
+			this.receiver = null;
+		}
+	}
+	public void resolveJavadoc() {
+
+		if (this.binding == null) return;
+		if (this.javadoc != null) {
+			this.javadoc.resolve(this.scope);
+			return;
+		}
+		if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) {
+			// Set javadoc visibility
+			int javadocVisibility = this.binding.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+			ClassScope classScope = this.scope.classScope();
+			ProblemReporter reporter = this.scope.problemReporter();
+			int severity = reporter.computeSeverity(IProblem.JavadocMissing);
+			if (severity != ProblemSeverities.Ignore) {
+				if (classScope != null) {
+					javadocVisibility = Util.computeOuterMostVisibility(classScope.referenceType(), javadocVisibility);
+				}
+				int javadocModifiers = (this.binding.modifiers & ~ExtraCompilerModifiers.AccVisibilityMASK) | javadocVisibility;
+				reporter.javadocMissing(this.sourceStart, this.sourceEnd, severity, javadocModifiers);
+			}
+		}
+	}
+
+	public void resolveStatements() {
+
+		if (this.statements != null) {
+			for (int i = 0, length = this.statements.length; i < length; i++) {
+				this.statements[i].resolve(this.scope);
+			}
+		} else if ((this.bits & UndocumentedEmptyBlock) != 0) {
+			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);
+			}
+		}
+	}
+
+	public void tagAsHavingErrors() {
+		this.ignoreFurtherInvestigation = true;
+	}
+	
+	public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
+		// Nothing to do for this context;
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		ClassScope classScope) {
+		// default implementation: subclass will define it
+	}
+
+	public TypeParameter[] typeParameters() {
+	    return null;
+	}
+
+	void validateNullAnnotations() {
+		// null annotations on parameters?
+		if (this.binding != null && this.binding.parameterNonNullness != null) {
+			int length = this.binding.parameters.length;
+			for (int i=0; i<length; i++) {
+				if (this.binding.parameterNonNullness[i] != null) {
+					long nullAnnotationTagBit =  this.binding.parameterNonNullness[i].booleanValue()
+							? TagBits.AnnotationNonNull : TagBits.AnnotationNullable;
+					this.scope.validateNullAnnotation(nullAnnotationTagBit, this.arguments[i].type, this.arguments[i].annotations);
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java
new file mode 100644
index 0000000..813b44a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public abstract class AbstractVariableDeclaration extends Statement implements InvocationSite, ExpressionContext {
+	public int declarationEnd;
+	/**
+	 * For local declarations (outside of for statement initialization) and field declarations,
+	 * the declarationSourceEnd covers multiple locals if any.
+	 * For local declarations inside for statement initialization, this is not the case.
+	 */
+	public int declarationSourceEnd;
+	public int declarationSourceStart;
+	public int hiddenVariableDepth; // used to diagnose hiding scenarii
+	public Expression initialization;
+	public int modifiers;
+	public int modifiersSourceStart;
+	public Annotation[] annotations;
+
+	public char[] name;
+
+	public TypeReference type;
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		return flowInfo;
+	}
+
+	public static final int FIELD = 1;
+	public static final int INITIALIZER = 2;
+	public static final int ENUM_CONSTANT = 3;
+	public static final int LOCAL_VARIABLE = 4;
+	public static final int PARAMETER = 5;
+	public static final int TYPE_PARAMETER = 6;
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+	 */
+	public TypeBinding[] genericTypeArguments() {
+		return null;
+	}
+
+	/**
+	 * Returns the constant kind of this variable declaration
+	 */
+	public abstract int getKind();
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
+	 */
+	public boolean isSuperAccess() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isTypeAccess()
+	 */
+	public boolean isTypeAccess() {
+		return false;
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		printAsExpression(indent, output);
+		switch(getKind()) {
+			case ENUM_CONSTANT:
+				return output.append(',');
+			default:
+				return output.append(';');
+		}
+	}
+
+	public StringBuffer printAsExpression(int indent, StringBuffer output) {
+		printIndent(indent, output);
+		printModifiers(this.modifiers, output);
+		if (this.annotations != null) {
+			printAnnotations(this.annotations, output);
+			output.append(' ');
+		}
+
+		if (this.type != null) {
+			this.type.print(0, output).append(' ');
+		}
+		output.append(this.name);
+		switch(getKind()) {
+			case ENUM_CONSTANT:
+				if (this.initialization != null) {
+					this.initialization.printExpression(indent, output);
+				}
+				break;
+			default:
+				if (this.initialization != null) {
+					output.append(" = "); //$NON-NLS-1$
+					this.initialization.printExpression(indent, output);
+				}
+		}
+		return output;
+	}
+
+	public void resolve(BlockScope scope) {
+		// do nothing by default (redefined for local variables)
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#setActualReceiverType(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
+	 */
+	public void setActualReceiverType(ReferenceBinding receiverType) {
+		// do nothing by default
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#setDepth(int)
+	 */
+	public void setDepth(int depth) {
+
+		this.hiddenVariableDepth = depth;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#setFieldIndex(int)
+	 */
+	public void setFieldIndex(int depth) {
+		// do nothing by default
+	}
+}
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
new file mode 100644
index 0000000..2067bb6
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -0,0 +1,564 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     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
+ *     						bug 349326 - [1.7] new warning for missing try-with-resources
+ * 							bug 186342 - [compiler][null] Using annotations for null checking
+ *							bug 358903 - Filter practically unimportant resource leak warnings
+ *							bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *							bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *							bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *							bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *							bug 378674 - "The method can be declared as static" is wrong
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class AllocationExpression extends Expression implements InvocationSite {
+
+	public TypeReference type;
+	public Expression[] arguments;
+	public MethodBinding binding;							// exact binding resulting from lookup
+	MethodBinding syntheticAccessor;						// synthetic accessor for inner-emulation
+	public TypeReference[] typeArguments;
+	public TypeBinding[] genericTypeArguments;
+	public FieldDeclaration enumConstant; // for enum constant initializations
+	protected TypeBinding typeExpected;	  // for <> inference
+	public boolean inferredReturnType;
+
+	public FakedTrackingVariable closeTracker;	// when allocation a Closeable store a pre-liminary tracking variable here
+	private ExpressionContext expressionContext = VANILLA_CONTEXT;
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// check captured variables are initialized in current context (26134)
+	checkCapturedLocalInitializationIfNecessary((ReferenceBinding)this.binding.declaringClass.erasure(), currentScope, flowInfo);
+
+	// process arguments
+	if (this.arguments != null) {
+		boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+		boolean hasResourceWrapperType = analyseResources 
+				&& this.resolvedType instanceof ReferenceBinding 
+				&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
+		for (int i = 0, count = this.arguments.length; i < count; i++) {
+			flowInfo =
+				this.arguments[i]
+					.analyseCode(currentScope, flowContext, flowInfo)
+					.unconditionalInits();
+			// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+			if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
+				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
+			}
+			this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		}
+		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
+	}
+
+	// record some dependency information for exception types
+	ReferenceBinding[] thrownExceptions;
+	if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
+		if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+			thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
+		}		
+		// check exception handling
+		flowContext.checkExceptionHandlers(
+			thrownExceptions,
+			this,
+			flowInfo.unconditionalCopy(),
+			currentScope);
+	}
+
+	// after having analysed exceptions above start tracking newly allocated resource:
+	if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
+		FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
+
+	if (this.binding.declaringClass.isMemberType() && !this.binding.declaringClass.isStatic()) {
+		// allocating a non-static member type without an enclosing instance of parent type
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845
+		currentScope.tagAsAccessingEnclosingInstanceStateOf(this.binding.declaringClass.enclosingType(), false /* type variable access */);
+		// Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
+		// The corresponding problem (when called from static) is not produced until during code generation
+	}
+	manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+	manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+
+	// account for possible exceptions thrown by the constructor
+	flowContext.recordAbruptExit(); // TODO whitelist of ctors that cannot throw any exc.??
+
+	return flowInfo;
+}
+
+public void checkCapturedLocalInitializationIfNecessary(ReferenceBinding checkedType, BlockScope currentScope, FlowInfo flowInfo) {
+	if (((checkedType.tagBits & ( TagBits.AnonymousTypeMask|TagBits.LocalTypeMask)) == TagBits.LocalTypeMask)
+			&& !currentScope.isDefinedInType(checkedType)) { // only check external allocations
+		NestedTypeBinding nestedType = (NestedTypeBinding) checkedType;
+		SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
+		if (syntheticArguments != null)
+			for (int i = 0, count = syntheticArguments.length; i < count; i++){
+				SyntheticArgumentBinding syntheticArgument = syntheticArguments[i];
+				LocalVariableBinding targetLocal;
+				if ((targetLocal = syntheticArgument.actualOuterLocalVariable) == null) continue;
+				if (targetLocal.declaration != null && !flowInfo.isDefinitelyAssigned(targetLocal)){
+					currentScope.problemReporter().uninitializedLocalVariable(targetLocal, this);
+				}
+			}
+	}
+}
+
+public Expression enclosingInstance() {
+	return null;
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	if (!valueRequired)
+		currentScope.problemReporter().unusedObjectAllocation(this);
+
+	int pc = codeStream.position;
+	MethodBinding codegenBinding = this.binding.original();
+	ReferenceBinding allocatedType = codegenBinding.declaringClass;
+
+	codeStream.new_(this.type, allocatedType);
+	boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+	if (valueRequired || isUnboxing) {
+		codeStream.dup();
+	}
+	// better highlight for allocation: display the type individually
+	if (this.type != null) { // null for enum constant body
+		codeStream.recordPositionsFrom(pc, this.type.sourceStart);
+	} else {
+		// push enum constant name and ordinal
+		codeStream.ldc(String.valueOf(this.enumConstant.name));
+		codeStream.generateInlinedValue(this.enumConstant.binding.id);
+	}
+
+	// handling innerclass instance allocation - enclosing instance arguments
+	if (allocatedType.isNestedType()) {
+		codeStream.generateSyntheticEnclosingInstanceValues(
+			currentScope,
+			allocatedType,
+			enclosingInstance(),
+			this);
+	}
+	// generate the arguments for constructor
+	generateArguments(this.binding, this.arguments, currentScope, codeStream);
+	// handling innerclass instance allocation - outer local arguments
+	if (allocatedType.isNestedType()) {
+		codeStream.generateSyntheticOuterArgumentValues(
+			currentScope,
+			allocatedType,
+			this);
+	}
+	// invoke constructor
+	if (this.syntheticAccessor == null) {
+		codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
+	} else {
+		// synthetic accessor got some extra arguments appended to its signature, which need values
+		for (int i = 0,
+			max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
+			i < max;
+			i++) {
+			codeStream.aconst_null();
+		}
+		codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */);
+	}
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else if (isUnboxing) {
+		// conversion only generated if unboxing
+		codeStream.generateImplicitConversion(this.implicitConversion);
+		switch (postConversionType(currentScope).id) {
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			default :
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return this.genericTypeArguments;
+}
+
+public boolean isSuperAccess() {
+	return false;
+}
+
+public boolean isTypeAccess() {
+	return true;
+}
+
+/* Inner emulation consists in either recording a dependency
+ * link only, or performing one level of propagation.
+ *
+ * Dependency mechanism is used whenever dealing with source target
+ * types, since by the time we reach them, we might not yet know their
+ * exact need.
+ */
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+	ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
+
+	// perform some emulation work in case there is some and we are inside a local type only
+	if (allocatedTypeErasure.isNestedType()
+		&& currentScope.enclosingSourceType().isLocalType()) {
+
+		if (allocatedTypeErasure.isLocalType()) {
+			((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, false);
+			// request cascade of accesses
+		} else {
+			// locally propagate, since we already now the desired shape for sure
+			currentScope.propagateInnerEmulation(allocatedTypeErasure, false);
+			// request cascade of accesses
+		}
+	}
+}
+
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+	// if constructor from parameterized type got found, use the original constructor at codegen time
+	MethodBinding codegenBinding = this.binding.original();
+
+	ReferenceBinding declaringClass;
+	if (codegenBinding.isPrivate() && currentScope.enclosingSourceType() != (declaringClass = codegenBinding.declaringClass)) {
+
+		// from 1.4 on, local type constructor can lose their private flag to ease emulation
+		if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+			// constructor will not be dumped as private, no emulation required thus
+			codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
+		} else {
+			this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
+			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+		}
+	}
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	if (this.type != null) { // type null for enum constant initializations
+		output.append("new "); //$NON-NLS-1$
+	}
+	if (this.typeArguments != null) {
+		output.append('<');
+		int max = this.typeArguments.length - 1;
+		for (int j = 0; j < max; j++) {
+			this.typeArguments[j].print(0, output);
+			output.append(", ");//$NON-NLS-1$
+		}
+		this.typeArguments[max].print(0, output);
+		output.append('>');
+	}
+	if (this.type != null) { // type null for enum constant initializations
+		this.type.printExpression(0, output);
+	}
+	output.append('(');
+	if (this.arguments != null) {
+		for (int i = 0; i < this.arguments.length; i++) {
+			if (i > 0) output.append(", "); //$NON-NLS-1$
+			this.arguments[i].printExpression(0, output);
+		}
+	}
+	return output.append(')');
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// Propagate the type checking to the arguments, and check if the constructor is defined.
+	this.constant = Constant.NotAConstant;
+	if (this.type == null) {
+		// initialization of an enum constant
+		this.resolvedType = scope.enclosingReceiverType();
+	} else {
+		this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+		checkParameterizedAllocation: {
+			if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
+				ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
+				if (currentType == null) return currentType;
+				do {
+					// isStatic() is answering true for toplevel types
+					if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
+					if (currentType.isRawType()) break checkParameterizedAllocation;
+				} while ((currentType = currentType.enclosingType())!= null);
+				ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
+				for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
+					if (qRef.typeArguments[i] != null) {
+						scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
+						break;
+					}
+				}
+			}
+		}
+	}
+	// will check for null after args are resolved
+
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+	// resolve type arguments (for generic constructor call)
+	if (this.typeArguments != null) {
+		int length = this.typeArguments.length;
+		boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+		this.genericTypeArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			TypeReference typeReference = this.typeArguments[i];
+			if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+				argHasError = true;
+			}
+			if (argHasError && typeReference instanceof Wildcard) {
+				scope.problemReporter().illegalUsageOfWildcard(typeReference);
+			}
+		}
+		if (isDiamond) {
+			scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
+			return null;
+		}
+		if (argHasError) {
+			if (this.arguments != null) { // still attempt to resolve arguments
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					this.arguments[i].resolveType(scope);
+				}
+			}
+			return null;
+		}
+	}
+
+	// buffering the arguments' types
+	boolean argsContainCast = false;
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+	boolean polyExpressionSeen = false;
+	if (this.arguments != null) {
+		boolean argHasError = false;
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		TypeBinding argumentType;
+		for (int i = 0; i < length; i++) {
+			Expression argument = this.arguments[i];
+			if (argument instanceof CastExpression) {
+				argument.bits |= DisableUnnecessaryCastCheck; // will check later on
+				argsContainCast = true;
+			}
+			argument.setExpressionContext(INVOCATION_CONTEXT);
+			if ((argumentType = argumentTypes[i] = argument.resolveType(scope)) == null) {
+				argHasError = true;
+			}
+			if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+				polyExpressionSeen = true;
+		}
+		if (argHasError) {
+			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
+			   No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
+			   not return the partially resolved type.
+			 */
+			if (isDiamond) {
+				return null; // not the partially cooked this.resolvedType
+			}
+			if (this.resolvedType instanceof ReferenceBinding) {
+				// record a best guess, for clients who need hint about possible constructor match
+				TypeBinding[] pseudoArgs = new TypeBinding[length];
+				for (int i = length; --i >= 0;) {
+					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+				}
+				this.binding = scope.findMethod((ReferenceBinding) this.resolvedType, TypeConstants.INIT, pseudoArgs, this);
+				if (this.binding != null && !this.binding.isValidBinding()) {
+					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+					// record the closest match, for clients who may still need hint about possible method match
+					if (closestMatch != null) {
+						if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
+							// shouldn't return generic method outside its context, rather convert it to raw method (175409)
+							closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
+						}
+						this.binding = closestMatch;
+						MethodBinding closestMatchOriginal = closestMatch.original();
+						if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
+							// ignore cases where method is used from within inside itself (e.g. direct recursions)
+							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+						}
+					}
+				}
+			}
+			return this.resolvedType;
+		}
+	}
+	if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
+		return null;
+	}
+
+	// null type denotes fake allocation for enum constant inits
+	if (this.type != null && !this.resolvedType.canBeInstantiated()) {
+		scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
+		return this.resolvedType;
+	}
+	if (isDiamond) {
+		TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+		if (inferredTypes == null) {
+			scope.problemReporter().cannotInferElidedTypes(this);
+			return this.resolvedType = null;
+		}
+		this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+ 	}
+	
+	ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
+	this.binding = scope.getConstructor(allocationType, argumentTypes, this);
+	if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+		return null;
+	
+	if (!this.binding.isValidBinding()) {
+		if (this.binding.declaringClass == null) {
+			this.binding.declaringClass = allocationType;
+		}
+		if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+			return null;
+		}
+		scope.problemReporter().invalidConstructor(this, this.binding);
+		return this.resolvedType;
+	}
+	if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
+		scope.problemReporter().missingTypeInConstructor(this, this.binding);
+	}
+	if (isMethodUseDeprecated(this.binding, scope, true))
+		scope.problemReporter().deprecatedMethod(this.binding, this);
+	if (checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+		this.bits |= ASTNode.Unchecked;
+	}
+	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
+	}
+	if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
+ 		checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, null, argumentTypes, scope);
+ 	}
+	return allocationType;
+}
+
+public TypeBinding[] inferElidedTypes(ReferenceBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+	/* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
+	   method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
+	   If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
+	   to the types elided in the <>.
+	 */   
+	MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTypes, this);
+	if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
+		ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
+		this.inferredReturnType = genericFactory.inferredReturnType;
+		return ((ParameterizedTypeBinding)factory.returnType).arguments;
+	}
+	return null;
+}
+
+public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+	ProblemReporter reporter = scope.problemReporter();
+	if ((reporter.computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
+	if (allocationType.arguments == null) return;  // raw binding
+	if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
+	if (argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
+		ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
+		if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
+			// check the case when no ctor takes no params and inference uses the expected type directly
+			// eg. X<String> x = new X<String>()
+			int i;
+			for (i = 0; i < allocationType.arguments.length; i++) {
+				if (allocationType.arguments[i] != expected.arguments[i])
+					break;
+			}
+			if (i == allocationType.arguments.length) {
+				reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
+				return;
+			}	
+		}
+	}
+	TypeBinding [] inferredTypes = inferElidedTypes(allocationType.genericType(), enclosingType, argumentTypes, scope);
+	if (inferredTypes == null) {
+		return;
+	}
+	for (int i = 0; i < inferredTypes.length; i++) {
+		if (inferredTypes[i] != allocationType.arguments[i])
+			return;
+	}
+	reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
+}
+
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	// ignored
+}
+
+public void setDepth(int i) {
+	// ignored
+}
+
+public void setFieldIndex(int i) {
+	// ignored
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (this.typeArguments != null) {
+			for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+				this.typeArguments[i].traverse(visitor, scope);
+			}
+		}
+		if (this.type != null) { // enum constant scenario
+			this.type.traverse(visitor, scope);
+		}
+		if (this.arguments != null) {
+			for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
+				this.arguments[i].traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, scope);
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void setExpectedType(TypeBinding expectedType) {
+	this.typeExpected = expectedType;
+}
+
+public void setExpressionContext(ExpressionContext context) {
+	this.expressionContext = context;
+}
+
+public boolean isPolyExpression() {
+	return (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) &&
+			this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+}
+
+public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+	return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType()
+ */
+public TypeBinding expectedType() {
+	return this.typeExpected;
+}
+
+public boolean statementExpression() {
+	return true;
+}
+
+}
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
new file mode 100644
index 0000000..1bfac7b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -0,0 +1,1053 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.Stack;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Annotation
+ */
+public abstract class Annotation extends Expression {
+	
+	/**
+	 * Return the location for the corresponding annotation inside the type reference, <code>null</code> if none.
+	 */
+	public static int[] getLocations(
+			final TypeReference reference,
+			final Annotation[] primaryAnnotation,
+			final Annotation annotation,
+			final Annotation[][] annotationsOnDimensionsOnExpression,
+			final int dimensions) {
+	
+		class LocationCollector extends ASTVisitor {
+			Stack typePathEntries;
+			Annotation currentAnnotation;
+			boolean search = true;
+			
+			public LocationCollector(Annotation currentAnnotation) {
+				this.typePathEntries = new Stack();
+				this.currentAnnotation = currentAnnotation;
+			}
+			
+			public boolean visit(ParameterizedSingleTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+								
+				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
+				if (annotationsOnDimensions != null) {
+					for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+						Annotation[] annotations = annotationsOnDimensions[i];
+						if (annotations != null) {
+							for (int j = 0, max2 = annotations.length; j < max2; j++) {
+								Annotation current = annotations[j];
+								if (current == this.currentAnnotation) {
+									// found it, push any relevant type path entries
+									for (int k = 0; k < i; k++) {
+										this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+									}
+									this.search = false;
+									return false;
+								}
+							}
+						}
+						
+					}
+				}
+				
+				// Example cases handled here: @B(1) List<String>[]
+				Annotation[][] annotations = typeReference.annotations;
+				if (annotations == null) {
+					annotations = new Annotation[][] { primaryAnnotation };
+				}
+				int annotationsLevels = annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							this.search = false;
+							// Found it, insert any necessary type path elements
+							for (int k = 0; k < typeReference.dimensions; k++) {
+								this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+							}
+							return false;
+						}
+					}
+				}
+				
+				// If a type argument is annotated it is necessary jump past the array elements
+				if (typeReference.dimensions != 0) {
+					for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+						this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+					}
+				}
+				TypeReference[] typeReferences = typeReference.typeArguments;
+				for (int i = 0, max = typeReferences.length; i < max; i++) {
+					this.typePathEntries.add(new int[]{3,i});
+					typeReferences[i].traverse(this, scope);
+					if (!this.search) {
+						return false;
+					} else {
+						this.typePathEntries.pop();
+					}
+				}
+				if (typeReference.dimensions != 0) {
+					for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+						this.typePathEntries.pop();
+					}					
+				}
+				return true;
+			}
+
+			public boolean visit(SingleTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+
+				// depth allows for the syntax "outerInstance.new @A InnerType();"
+				int depth = 0;
+				if (typeReference.resolvedType instanceof ReferenceBinding) {
+					depth = getInnerDepth((ReferenceBinding)typeReference.resolvedType);
+				}
+				
+				if (dimensions != 0) {
+					for (int k = 0; k < dimensions; k++) {
+						this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+					}
+				}
+				Annotation[][] annotations = typeReference.annotations;
+				int annotationsLevels = annotations == null ? 0 : annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							// Found
+							this.search = false;
+							if (depth != 0) {
+								for (int k = 0; k<depth; k++) {
+									this.typePathEntries.add(TYPE_PATH_INNER_TYPE);
+								}
+							}
+							return false;
+						}
+					}
+				}
+				if (dimensions != 0) {
+					for (int k = 0; k < dimensions; k++) {
+						this.typePathEntries.pop();
+					}
+				}
+				return false;
+			}
+
+			public boolean visit(ArrayTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+				
+				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
+				if (annotationsOnDimensions != null) {
+					for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+						Annotation[] annotations = annotationsOnDimensions[i];
+						if (annotations != null) {
+							for (int j = 0, max2 = annotations.length; j < max2; j++) {
+								Annotation current = annotations[j];
+								if (current == this.currentAnnotation) {
+									for (int k = 0; k < i; k++) {
+										this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+									}
+									this.search = false;
+									return false;
+								}
+							}
+						}
+						
+					}
+				}
+				Annotation[][] annotations = typeReference.annotations;
+				if (annotations == null) {
+					annotations = new Annotation[][] { primaryAnnotation };
+				}
+				int annotationsLevels = annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							for (int k = 0, maxk=typeReference.dimensions; k < maxk; k++) {
+								this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+							}
+							this.search = false;
+							return false;
+						}
+					}
+				}
+				return true;
+			}
+			
+			public boolean visit(ArrayQualifiedTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
+				if (annotationsOnDimensions != null) {
+					for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+						Annotation[] annotations = annotationsOnDimensions[i];
+						if (annotations != null) {
+							for (int j = 0, max2 = annotations.length; j < max2; j++) {
+								Annotation current = annotations[j];
+								if (current == this.currentAnnotation) {
+									this.search = false;
+									// Found it, insert relevant type path elements
+									for (int k = 0, maxk = i; k < maxk; k++) {
+										this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+									}
+									return false;
+								}
+							}
+						}
+					}
+				}
+				Annotation[][] annotations = typeReference.annotations;
+				if (annotations == null) {
+					annotations = new Annotation[][] { primaryAnnotation };
+				}
+				int annotationsLevels = annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							this.search = false;
+							for (int k = 0, maxk=typeReference.dimensions; k < maxk; k++) {
+								this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+							}
+							return false;
+						}
+					}
+				}
+				return true;
+			}
+			
+			public boolean visit(ParameterizedQualifiedTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+				
+				// Example case handled by this block: java.util.List<String>[]@A[]
+				Annotation[][] annotationsOnDimensions = typeReference.annotationsOnDimensions;
+				if (annotationsOnDimensions != null) {
+					for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+						Annotation[] annotations = annotationsOnDimensions[i];
+						if (annotations != null) {
+							for (int j = 0, max2 = annotations.length; j < max2; j++) {
+								Annotation current = annotations[j];
+								if (current == this.currentAnnotation) {
+									this.search = false;
+									// Found it, insert relevant type path elements
+									for (int k = 0, maxk = i; k < maxk; k++) {
+										this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+									}
+									return false;
+								}
+							}
+						}
+					}
+				}
+
+				boolean[] needsInnerEntryInfo = computeInnerEntryInfo(typeReference);
+
+				// Example cases handled by this block:
+				// java.util.@A List<String>[][], com.demo.@A Outer.@B Inner<String>, java.util.Map.@A Entry<String,String>
+				Annotation[][] annotations = typeReference.annotations;
+				if (annotations == null) {
+					annotations = new Annotation[][] { primaryAnnotation };
+				}
+				int annotationsLevels = annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							this.search = false;
+							// Found, insert any relevant type path elements
+							for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+								this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+							}
+							// Found, insert any relevant type path elements
+							if (needsInnerEntryInfo != null) {
+								for (int k = 0; k <= i; k++) {
+									if (needsInnerEntryInfo[k]) {
+										this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+									}
+								}
+							}
+							return false;
+						}
+					}
+				}
+				
+				// Example cases handled by this block:
+				// java.util.List<@A String>
+				if (typeReference.dimensions != 0) {
+					for (int k = 0, maxk = typeReference.dimensions; k < maxk; k++) {
+						this.typePathEntries.push(TYPE_PATH_ELEMENT_ARRAY);
+					}
+				}
+				int toPop = 0;
+				for (int i = 0, max = typeReference.typeArguments.length; i < max; i++) {
+					TypeReference[] typeArgumentsForComponent = typeReference.typeArguments[i];
+					if (needsInnerEntryInfo != null && needsInnerEntryInfo[i]) { 
+						this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+						toPop++;
+					}
+					if (typeArgumentsForComponent != null) {
+						for (int j = 0, max2 = typeArgumentsForComponent.length; j < max2; j++) {
+							this.typePathEntries.push(new int[]{3,j});
+							typeArgumentsForComponent[j].traverse(this,scope);
+							if (!this.search) return false;
+							this.typePathEntries.pop();
+						}
+					}
+				}
+				toPop += typeReference.dimensions;
+				for (int k = 0, maxk = toPop; k < maxk; k++) {
+					this.typePathEntries.pop();
+				}
+				return true;
+			}
+			
+			public boolean visit(Wildcard typeReference, BlockScope scope) {
+				if (!this.search) return false;
+				TypeReference bound = typeReference.bound;
+				this.typePathEntries.push(TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND);
+				bound.traverse(this, scope);
+				if (!this.search) {
+					return false;
+				}
+				this.typePathEntries.pop();
+				return true;
+			}
+			
+			private boolean[] computeInnerEntryInfo(QualifiedTypeReference typeReference) {
+				ReferenceBinding resolvedType = (ReferenceBinding) 
+						(typeReference.resolvedType instanceof ArrayBinding ? typeReference.resolvedType.leafComponentType() : typeReference.resolvedType);
+				boolean[] needsInnerEntryInfo = null;
+				if (resolvedType != null && resolvedType.isNestedType()) {
+					// Work backwards computing whether a INNER_TYPE entry is required for each level
+					needsInnerEntryInfo = new boolean[typeReference.tokens.length];
+					int counter = needsInnerEntryInfo.length - 1;
+					ReferenceBinding type = resolvedType;//resolvedType.enclosingType();
+					while (type != null) {
+						needsInnerEntryInfo[counter--] = !type.isStatic();
+						type = type.enclosingType();
+					}
+				}
+				return needsInnerEntryInfo;
+			}
+			
+			private int getInnerDepth(ReferenceBinding resolvedType) {
+				int depth = 0;
+				ReferenceBinding type = resolvedType;
+				while (type != null) {
+					depth += (type.isStatic())?0:1;
+					type = type.enclosingType();
+				}
+				return depth;
+			}
+			
+			public boolean visit(QualifiedTypeReference typeReference, BlockScope scope) {
+				if (!this.search) return false;
+				boolean[] needsInnerEntryInfo = computeInnerEntryInfo(typeReference);
+				
+				// Example cases handled by this block:
+				// java.util.@A List, com.demo.@A Outer.@B Inner, java.util.Map.@A Entry
+				Annotation[][] annotations = typeReference.annotations;
+				if (annotations == null) {
+					annotations = new Annotation[][] { primaryAnnotation };
+				}
+				int annotationsLevels = annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation [] current = annotations[i];
+					int annotationsLength = current == null ? 0 : current.length;
+					for (int j = 0; j < annotationsLength; j++) {
+						if (current[j] == this.currentAnnotation) {
+							this.search = false;
+							// Found, insert any relevant type path elements
+							if (needsInnerEntryInfo != null) {
+								for (int k = 0; k <= i; k++) {
+									if (needsInnerEntryInfo[k]) {
+										this.typePathEntries.push(TYPE_PATH_INNER_TYPE);
+									}
+								}
+							}
+							return false;
+						}
+					}
+				}
+				return true;
+			}
+			
+			public String toString() {
+				StringBuffer buffer = new StringBuffer();
+				buffer
+					.append("search location for ") //$NON-NLS-1$
+					.append(this.currentAnnotation)
+					.append("\ncurrent type_path entries : "); //$NON-NLS-1$
+				for (int i = 0, maxi = this.typePathEntries.size(); i < maxi; i++) {
+					int[] typePathEntry = (int[]) this.typePathEntries.get(i);
+					buffer
+						.append('(')
+						.append(typePathEntry[0])
+						.append(',')
+						.append(typePathEntry[1])
+						.append(')');
+				}
+				return String.valueOf(buffer);
+			}
+		}
+		if (reference == null) return null;
+		LocationCollector collector = new LocationCollector(annotation);
+		reference.traverse(collector, (BlockScope) null);
+		if (collector.typePathEntries.isEmpty()) {
+			return null;
+		}
+		int size = collector.typePathEntries.size();
+		int[] result = new int[size*2];
+		int offset=0;
+		for (int i = 0; i < size; i++) {
+			int[] pathElement = (int[])collector.typePathEntries.get(i);
+			result[offset++] = pathElement[0];
+			result[offset++] = pathElement[1];
+		}
+		return result;
+	}
+		
+    // jsr 308
+	public static class TypeUseBinding extends ReferenceBinding {
+		private int kind;
+		public TypeUseBinding(int kind) {
+			this.tagBits = 0L;
+			this.kind = kind;
+		}
+		public int kind() {
+			return this.kind;
+		}
+		public boolean hasTypeBit(int bit) {
+			return false;
+		}
+	}
+
+	final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
+	private static final long TAGBITS_NULLABLE_OR_NONNULL = TagBits.AnnotationNullable|TagBits.AnnotationNonNull;
+
+	static final int[] TYPE_PATH_ELEMENT_ARRAY = new int[]{0,0};
+	static final int[] TYPE_PATH_INNER_TYPE = new int[]{1,0};
+	static final int[] TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND = new int[]{2,0};
+	
+	public int declarationSourceEnd;
+	public Binding recipient;
+
+	public TypeReference type;
+	/**
+	 *  The representation of this annotation in the type system.
+	 */
+	private AnnotationBinding compilerAnnotation = null;
+
+	public static long getRetentionPolicy(char[] policyName) {
+		if (policyName == null || policyName.length == 0)
+			return 0;
+		switch(policyName[0]) {
+			case 'C' :
+				if (CharOperation.equals(policyName, TypeConstants.UPPER_CLASS))
+					return TagBits.AnnotationClassRetention;
+				break;
+			case 'S' :
+				if (CharOperation.equals(policyName, TypeConstants.UPPER_SOURCE))
+					return TagBits.AnnotationSourceRetention;
+				break;
+			case 'R' :
+				if (CharOperation.equals(policyName, TypeConstants.UPPER_RUNTIME))
+					return TagBits.AnnotationRuntimeRetention;
+				break;
+		}
+		return 0; // unknown
+	}
+
+	public static long getTargetElementType(char[] elementName) {
+		if (elementName == null || elementName.length == 0)
+			return 0;
+		switch(elementName[0]) {
+			case 'A' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_ANNOTATION_TYPE))
+					return TagBits.AnnotationForAnnotationType;
+				break;
+			case 'C' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_CONSTRUCTOR))
+					return TagBits.AnnotationForConstructor;
+				break;
+			case 'F' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_FIELD))
+					return TagBits.AnnotationForField;
+				break;
+			case 'L' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_LOCAL_VARIABLE))
+					return TagBits.AnnotationForLocalVariable;
+				break;
+			case 'M' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_METHOD))
+					return TagBits.AnnotationForMethod;
+				break;
+			case 'P' :
+				if (CharOperation.equals(elementName, TypeConstants.UPPER_PARAMETER))
+					return TagBits.AnnotationForParameter;
+				else if (CharOperation.equals(elementName, TypeConstants.UPPER_PACKAGE))
+					return TagBits.AnnotationForPackage;
+				break;
+			case 'T' :
+				if (CharOperation.equals(elementName, TypeConstants.TYPE))
+					return TagBits.AnnotationForType;
+				if (CharOperation.equals(elementName, TypeConstants.TYPE_USE_TARGET))
+					return TagBits.AnnotationForTypeUse;
+				if (CharOperation.equals(elementName, TypeConstants.TYPE_PARAMETER_TARGET))
+					return TagBits.AnnotationForTypeParameter;
+				break;
+		}
+		return 0; // unknown
+	}
+
+	public ElementValuePair[] computeElementValuePairs() {
+		return Binding.NO_ELEMENT_VALUE_PAIRS;
+	}
+
+	/**
+	 * Compute the bit pattern for recognized standard annotations the compiler may need to act upon
+	 */
+	private long detectStandardAnnotation(Scope scope, ReferenceBinding annotationType, MemberValuePair valueAttribute) {
+		long tagBits = 0;
+		switch (annotationType.id) {
+			// retention annotation
+			case TypeIds.T_JavaLangAnnotationRetention :
+				if (valueAttribute != null) {
+					Expression expr = valueAttribute.value;
+					if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
+						FieldBinding field = ((Reference)expr).fieldBinding();
+						if (field != null && field.declaringClass.id == T_JavaLangAnnotationRetentionPolicy) {
+							tagBits |= getRetentionPolicy(field.name);
+						}
+					}
+				}
+				break;
+			// target annotation
+			case TypeIds.T_JavaLangAnnotationTarget :
+				tagBits |= TagBits.AnnotationTarget; // target specified (could be empty)
+				if (valueAttribute != null) {
+					Expression expr = valueAttribute.value;
+					if (expr instanceof ArrayInitializer) {
+						ArrayInitializer initializer = (ArrayInitializer) expr;
+						final Expression[] expressions = initializer.expressions;
+						if (expressions != null) {
+							for (int i = 0, length = expressions.length; i < length; i++) {
+								Expression initExpr = expressions[i];
+								if ((initExpr.bits & Binding.VARIABLE) == Binding.FIELD) {
+									FieldBinding field = ((Reference) initExpr).fieldBinding();
+									if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
+										long element = getTargetElementType(field.name);
+										if ((tagBits & element) != 0) {
+											scope.problemReporter().duplicateTargetInTargetAnnotation(annotationType, (NameReference)initExpr);
+										} else {
+											tagBits |= element;
+										}
+									}
+								}
+							}
+						}
+					} else if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
+						FieldBinding field = ((Reference) expr).fieldBinding();
+						if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
+							tagBits |= getTargetElementType(field.name);
+						}
+					}
+				}
+				break;
+			// marker annotations
+			case TypeIds.T_JavaLangDeprecated :
+				tagBits |= TagBits.AnnotationDeprecated;
+				break;
+			case TypeIds.T_JavaLangAnnotationDocumented :
+				tagBits |= TagBits.AnnotationDocumented;
+				break;
+			case TypeIds.T_JavaLangAnnotationInherited :
+				tagBits |= TagBits.AnnotationInherited;
+				break;
+			case TypeIds.T_JavaLangOverride :
+				tagBits |= TagBits.AnnotationOverride;
+				break;
+			case TypeIds.T_JavaLangFunctionalInterface :
+				tagBits |= TagBits.AnnotationFunctionalInterface;
+				break;
+			case TypeIds.T_JavaLangSuppressWarnings :
+				tagBits |= TagBits.AnnotationSuppressWarnings;
+				break;
+			case TypeIds.T_JavaLangSafeVarargs :
+				tagBits |= TagBits.AnnotationSafeVarargs;
+				break;
+			case TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature :
+				tagBits |= TagBits.AnnotationPolymorphicSignature;
+				break;
+			case TypeIds.T_ConfiguredAnnotationNullable :
+				tagBits |= TagBits.AnnotationNullable;
+				break;
+			case TypeIds.T_ConfiguredAnnotationNonNull :
+				tagBits |= TagBits.AnnotationNonNull;
+				break;
+			case TypeIds.T_ConfiguredAnnotationNonNullByDefault :
+				if (valueAttribute != null 
+					&& valueAttribute.value instanceof FalseLiteral) 
+				{
+					// parameter 'false' means: this annotation cancels any defaults
+					tagBits |= TagBits.AnnotationNullUnspecifiedByDefault;
+					break;
+				}
+				tagBits |= TagBits.AnnotationNonNullByDefault;
+				break;
+		}
+		return tagBits;
+	}
+
+	public AnnotationBinding getCompilerAnnotation() {
+		return this.compilerAnnotation;
+	}
+
+	public boolean isRuntimeInvisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
+
+		// we need to filter out only "pure" type use and type parameter annotations, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=392119
+		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
+			if ((metaTagBits & TagBits.SE7AnnotationTargetMASK) == 0) {  // not a hybrid target. 
+				return false;
+			}
+		}
+
+		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
+			return true; // by default the retention is CLASS
+
+		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
+	}
+
+	public boolean isRuntimeTypeInvisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
+
+		if ((metaTagBits & (TagBits.AnnotationTargetMASK)) == 0) { // explicit target required for JSR308 style annotations.
+			return false;
+		}
+		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
+			return false;
+		}
+
+		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
+			return true; // by default the retention is CLASS
+
+		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
+	}
+
+	public boolean isRuntimeTypeVisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits();
+
+		if ((metaTagBits & (TagBits.AnnotationTargetMASK)) == 0) { // explicit target required for JSR308 style annotations.
+			return false;
+		}
+		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
+			return false;
+		}
+		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
+			return false; // by default the retention is CLASS
+
+		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
+	}
+
+	public boolean isRuntimeVisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits();
+		// we need to filter out only "pure" type use and type parameter annotations, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=392119
+		if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
+			if ((metaTagBits & TagBits.SE7AnnotationTargetMASK) == 0) { // not a hybrid target.
+				return false;
+			}
+		}
+		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) {
+		output.append('@');
+		this.type.printExpression(0, output);
+		return output;
+	}
+
+	public void recordSuppressWarnings(Scope scope, int startSuppresss, int endSuppress, boolean isSuppressingWarnings) {
+		IrritantSet suppressWarningIrritants = null;
+		MemberValuePair[] pairs = memberValuePairs();
+		pairLoop: for (int i = 0, length = pairs.length; i < length; i++) {
+			MemberValuePair pair = pairs[i];
+			if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
+				Expression value = pair.value;
+				if (value instanceof ArrayInitializer) {
+					ArrayInitializer initializer = (ArrayInitializer) value;
+					Expression[] inits = initializer.expressions;
+					if (inits != null) {
+						for (int j = 0, initsLength = inits.length; j < initsLength; j++) {
+							Constant cst = inits[j].constant;
+							if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
+								IrritantSet irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
+								if (irritants != null) {
+									if (suppressWarningIrritants == null) {
+										suppressWarningIrritants = new IrritantSet(irritants);
+									} else if (suppressWarningIrritants.set(irritants) == null) {
+											scope.problemReporter().unusedWarningToken(inits[j]);
+									}
+								} else {
+									scope.problemReporter().unhandledWarningToken(inits[j]);
+								}
+							}
+						}
+					}
+				} else {
+					Constant cst = value.constant;
+					if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
+						IrritantSet irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
+						if (irritants != null) {
+							suppressWarningIrritants = new IrritantSet(irritants);
+							// TODO: should check for unused warning token against enclosing annotation as well ?
+						} else {
+							scope.problemReporter().unhandledWarningToken(value);
+						}
+					}
+				}
+				break pairLoop;
+			}
+		}
+		if (isSuppressingWarnings && suppressWarningIrritants != null) {
+			scope.referenceCompilationUnit().recordSuppressWarnings(suppressWarningIrritants, this, startSuppresss, endSuppress);
+		}
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		if (this.compilerAnnotation != null)
+			return this.resolvedType;
+		this.constant = Constant.NotAConstant;
+
+		TypeBinding typeBinding = this.type.resolveType(scope);
+		if (typeBinding == null) {
+			return null;
+		}
+		this.resolvedType = typeBinding;
+		// ensure type refers to an annotation type
+		if (!typeBinding.isAnnotationType() && typeBinding.isValidBinding()) {
+			scope.problemReporter().typeMismatchError(typeBinding, scope.getJavaLangAnnotationAnnotation(), this.type, null);
+			return null;
+		}
+
+		ReferenceBinding annotationType = (ReferenceBinding) this.resolvedType;
+		MethodBinding[] methods = annotationType.methods();
+		// clone valuePairs to keep track of unused ones
+		MemberValuePair[] originalValuePairs = memberValuePairs();
+		MemberValuePair valueAttribute = null; // remember the first 'value' pair
+		MemberValuePair[] pairs;
+		int pairsLength = originalValuePairs.length;
+		if (pairsLength > 0) {
+			System.arraycopy(originalValuePairs, 0, pairs = new MemberValuePair[pairsLength], 0, pairsLength);
+		} else {
+			pairs = originalValuePairs;
+		}
+
+		nextMember: for (int i = 0, requiredLength = methods.length; i < requiredLength; i++) {
+			MethodBinding method = methods[i];
+			char[] selector = method.selector;
+			boolean foundValue = false;
+			nextPair: for (int j = 0; j < pairsLength; j++) {
+				MemberValuePair pair = pairs[j];
+				if (pair == null) continue nextPair;
+				char[] name = pair.name;
+				if (CharOperation.equals(name, selector)) {
+					if (valueAttribute == null && CharOperation.equals(name, TypeConstants.VALUE)) {
+						valueAttribute = pair;
+					}
+					pair.binding = method;
+					pair.resolveTypeExpecting(scope, method.returnType);
+					pairs[j] = null; // consumed
+					foundValue = true;
+
+					// check duplicates
+					boolean foundDuplicate = false;
+					for (int k = j+1; k < pairsLength; k++) {
+						MemberValuePair otherPair = pairs[k];
+						if (otherPair == null) continue;
+						if (CharOperation.equals(otherPair.name, selector)) {
+							foundDuplicate = true;
+							scope.problemReporter().duplicateAnnotationValue(annotationType, otherPair);
+							otherPair.binding = method;
+							otherPair.resolveTypeExpecting(scope, method.returnType);
+							pairs[k] = null;
+						}
+					}
+					if (foundDuplicate) {
+						scope.problemReporter().duplicateAnnotationValue(annotationType, pair);
+						continue nextMember;
+					}
+				}
+			}
+			if (!foundValue
+					&& (method.modifiers & ClassFileConstants.AccAnnotationDefault) == 0
+					&& (this.bits & IsRecovered) == 0
+					&& annotationType.isValidBinding()) {
+				scope.problemReporter().missingValueForAnnotationMember(this, selector);
+			}
+		}
+		// check unused pairs
+		for (int i = 0; i < pairsLength; i++) {
+			if (pairs[i] != null) {
+				if (annotationType.isValidBinding()) {
+					scope.problemReporter().undefinedAnnotationValue(annotationType, pairs[i]);
+				}
+				pairs[i].resolveTypeExpecting(scope, null); // resilient
+			}
+		}
+//		if (scope.compilerOptions().storeAnnotations)
+		this.compilerAnnotation = scope.environment().createAnnotation((ReferenceBinding) this.resolvedType, computeElementValuePairs());
+		// recognize standard annotations ?
+		long tagBits = detectStandardAnnotation(scope, annotationType, valueAttribute);
+
+		// record annotation positions in the compilation result
+		scope.referenceCompilationUnit().recordSuppressWarnings(IrritantSet.NLS, null, this.sourceStart, this.declarationSourceEnd);
+		if (this.recipient != null) {
+			int kind = this.recipient.kind();
+			if (tagBits != 0) {
+				// tag bits onto recipient
+				switch (kind) {
+					case Binding.PACKAGE :
+						((PackageBinding)this.recipient).tagBits |= tagBits;
+						break;
+					case Binding.TYPE_PARAMETER:
+					case Binding.TYPE_USE:
+						ReferenceBinding typeAnnotationRecipient = (ReferenceBinding) this.recipient;
+						typeAnnotationRecipient.tagBits |= tagBits;
+						break;
+					case Binding.TYPE :
+					case Binding.GENERIC_TYPE :
+						SourceTypeBinding sourceType = (SourceTypeBinding) this.recipient;
+						sourceType.tagBits |= tagBits;
+						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+							TypeDeclaration typeDeclaration =  sourceType.scope.referenceContext;
+							int start;
+							if (scope.referenceCompilationUnit().types[0] == typeDeclaration) {
+								start = 0;
+							} else {
+								start = typeDeclaration.declarationSourceStart;
+							}
+							recordSuppressWarnings(scope, start, typeDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+						}
+						break;
+					case Binding.METHOD :
+						MethodBinding sourceMethod = (MethodBinding) this.recipient;
+						sourceMethod.tagBits |= tagBits;
+						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+							sourceType = (SourceTypeBinding) sourceMethod.declaringClass;
+							AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod);
+							recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+						}
+						if ((sourceMethod.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) {
+							scope.problemReporter().contradictoryNullAnnotations(this);
+							sourceMethod.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems
+						}
+						break;
+					case Binding.FIELD :
+						FieldBinding sourceField = (FieldBinding) this.recipient;
+						sourceField.tagBits |= tagBits;
+						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+							sourceType = (SourceTypeBinding) sourceField.declaringClass;
+							FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
+							recordSuppressWarnings(scope, fieldDeclaration.declarationSourceStart, fieldDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+						}
+						if ((sourceField.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) {
+							scope.problemReporter().contradictoryNullAnnotations(this);
+							sourceField.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems
+						}
+						break;
+					case Binding.LOCAL :
+						LocalVariableBinding variable = (LocalVariableBinding) this.recipient;
+						variable.tagBits |= tagBits;
+						if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+							 LocalDeclaration localDeclaration = variable.declaration;
+							recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+						}
+						if ((variable.tagBits & TAGBITS_NULLABLE_OR_NONNULL) == TAGBITS_NULLABLE_OR_NONNULL) {
+							scope.problemReporter().contradictoryNullAnnotations(this);
+							variable.tagBits &= ~TAGBITS_NULLABLE_OR_NONNULL; // avoid secondary problems
+						}
+						break;
+				}
+			}
+			// check (meta)target compatibility
+			checkTargetCompatibility: {
+				if (!annotationType.isValidBinding()) {
+					// no need to check annotation usage if missing
+					break checkTargetCompatibility;
+				}
+
+				long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
+				if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) {
+					// does not specify any target restriction - all locations supported in Java 7 and before are possible
+					if (kind == Binding.TYPE_PARAMETER || kind == Binding.TYPE_USE) {
+						scope.problemReporter().explitAnnotationTargetRequired(this);
+					}
+					break checkTargetCompatibility;
+				}
+
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391201
+				if ((metaTagBits & TagBits.SE7AnnotationTargetMASK) == 0
+						&& (metaTagBits & (TagBits.AnnotationForTypeUse | TagBits.AnnotationForTypeParameter)) != 0) {
+					if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) {
+						switch (kind) {
+							case Binding.PACKAGE :
+							case Binding.TYPE :
+							case Binding.GENERIC_TYPE :
+							case Binding.METHOD :
+							case Binding.FIELD :
+							case Binding.LOCAL :
+								scope.problemReporter().invalidUsageOfTypeAnnotations(this);
+						}
+					}
+				}
+				switch (kind) {
+					case Binding.PACKAGE :
+						if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
+							break checkTargetCompatibility;
+						break;
+					case Binding.TYPE_USE :
+						if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+							// jsr 308
+							break checkTargetCompatibility;
+						}
+						break;
+					case Binding.TYPE :
+					case Binding.GENERIC_TYPE :
+						if (((ReferenceBinding)this.recipient).isAnnotationType()) {
+							if ((metaTagBits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) != 0)
+							break checkTargetCompatibility;
+						} else if ((metaTagBits & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) {
+							break checkTargetCompatibility;
+						} else if ((metaTagBits & TagBits.AnnotationForPackage) != 0) {
+							if (CharOperation.equals(((ReferenceBinding)this.recipient).sourceName, TypeConstants.PACKAGE_INFO_NAME))
+								break checkTargetCompatibility;
+						}
+						break;
+					case Binding.METHOD :
+						MethodBinding methodBinding = (MethodBinding) this.recipient;
+						if (methodBinding.isConstructor()) {
+							if ((metaTagBits & (TagBits.AnnotationForConstructor | TagBits.AnnotationForTypeUse)) != 0)
+								break checkTargetCompatibility;
+						} else if ((metaTagBits & TagBits.AnnotationForMethod) != 0) {
+							break checkTargetCompatibility;
+						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+							SourceTypeBinding sourceType = (SourceTypeBinding) methodBinding.declaringClass;
+							MethodDeclaration methodDecl = (MethodDeclaration) sourceType.scope.referenceContext.declarationOf(methodBinding);
+							if (isTypeUseCompatible(methodDecl.returnType, scope)) {
+								break checkTargetCompatibility;
+							}
+						}
+						break;
+					case Binding.FIELD :
+						if ((metaTagBits & TagBits.AnnotationForField) != 0) {
+							break checkTargetCompatibility;
+						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+							FieldBinding sourceField = (FieldBinding) this.recipient;
+							SourceTypeBinding sourceType = (SourceTypeBinding) sourceField.declaringClass;
+							FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
+							if (isTypeUseCompatible(fieldDeclaration.type, scope)) {
+								break checkTargetCompatibility;
+							}
+						}
+						break;
+					case Binding.LOCAL :
+						LocalVariableBinding localVariableBinding = (LocalVariableBinding)this.recipient;
+						if ((localVariableBinding.tagBits & TagBits.IsArgument) != 0) {
+							if ((metaTagBits & TagBits.AnnotationForParameter) != 0) {
+								break checkTargetCompatibility;
+							} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+								if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
+									break checkTargetCompatibility;
+								}
+							}
+						} else if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0) {
+							break checkTargetCompatibility;
+						} else if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) {
+							if (isTypeUseCompatible(localVariableBinding.declaration.type, scope)) {
+								break checkTargetCompatibility;
+							}
+						}
+						break;
+					case Binding.TYPE_PARAMETER : // jsr308
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391196
+						if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) != 0) {
+							break checkTargetCompatibility;
+						}
+					}
+				scope.problemReporter().disallowedTargetForAnnotation(this);
+			}
+		}
+		return this.resolvedType;
+	}
+	private boolean isTypeUseCompatible(TypeReference reference, Scope scope) {
+		if (!(reference instanceof SingleTypeReference)) {
+			Binding binding = scope.getPackage(reference.getTypeName());
+			// In case of ProblemReferenceBinding, don't report additional error
+			if (binding instanceof PackageBinding) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public abstract void traverse(ASTVisitor visitor, BlockScope scope);
+
+	public abstract void traverse(ASTVisitor visitor, ClassScope scope);
+}
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
new file mode 100644
index 0000000..69840bb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+
+public class AnnotationMethodDeclaration extends MethodDeclaration {
+
+	public Expression defaultValue;
+	public int extendedDimensions;
+
+	/**
+	 * MethodDeclaration constructor comment.
+	 */
+	public AnnotationMethodDeclaration(CompilationResult compilationResult) {
+		super(compilationResult);
+	}
+
+	public void generateCode(ClassFile classFile) {
+		classFile.generateMethodInfoHeader(this.binding);
+		int methodAttributeOffset = classFile.contentsOffset;
+		int attributeNumber = classFile.generateMethodInfoAttributes(this.binding, this);
+		classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
+	}
+
+	public boolean isAnnotationMethod() {
+
+		return true;
+	}
+
+	public boolean isMethod() {
+
+		return false;
+	}
+
+	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+		// nothing to do
+		// annotation type member declaration don't have any body
+	}
+
+	public StringBuffer print(int tab, StringBuffer output) {
+
+		printIndent(tab, output);
+		printModifiers(this.modifiers, output);
+		if (this.annotations != null) {
+			printAnnotations(this.annotations, output);
+			output.append(' ');
+		}
+
+		TypeParameter[] typeParams = typeParameters();
+		if (typeParams != null) {
+			output.append('<');
+			int max = typeParams.length - 1;
+			for (int j = 0; j < max; j++) {
+				typeParams[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			typeParams[max].print(0, output);
+			output.append('>');
+		}
+
+		printReturnType(0, output).append(this.selector).append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].print(0, output);
+			}
+		}
+		output.append(')');
+		if (this.thrownExceptions != null) {
+			output.append(" throws "); //$NON-NLS-1$
+			for (int i = 0; i < this.thrownExceptions.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.thrownExceptions[i].print(0, output);
+			}
+		}
+
+		if (this.defaultValue != null) {
+			output.append(" default "); //$NON-NLS-1$
+			this.defaultValue.print(0, output);
+		}
+
+		printBody(tab + 1, output);
+		return output;
+	}
+
+	public void resolveStatements() {
+
+		super.resolveStatements();
+		if (this.arguments != null) {
+			this.scope.problemReporter().annotationMembersCannotHaveParameters(this);
+		}
+		if (this.typeParameters != null) {
+			this.scope.problemReporter().annotationMembersCannotHaveTypeParameters(this);
+		}
+		if (this.extendedDimensions != 0) {
+			this.scope.problemReporter().illegalExtendedDimensions(this);
+		}
+		if (this.binding == null) return;
+		TypeBinding returnTypeBinding = this.binding.returnType;
+		if (returnTypeBinding != null) {
+
+			// annotation methods can only return base types, String, Class, enum type, annotation types and arrays of these
+			checkAnnotationMethodType: {
+				TypeBinding leafReturnType = returnTypeBinding.leafComponentType();
+				if (returnTypeBinding.dimensions() <= 1) { // only 1-dimensional array permitted
+					switch (leafReturnType.erasure().id) {
+						case T_byte :
+						case T_short :
+						case T_char :
+						case T_int :
+						case T_long :
+						case T_float :
+						case T_double :
+						case T_boolean :
+						case T_JavaLangString :
+						case T_JavaLangClass :
+							break checkAnnotationMethodType;
+					}
+					if (leafReturnType.isEnum() || leafReturnType.isAnnotationType())
+						break checkAnnotationMethodType;
+				}
+				this.scope.problemReporter().invalidAnnotationMemberType(this);
+			}
+			if (this.defaultValue != null) {
+				MemberValuePair pair = new MemberValuePair(this.selector, this.sourceStart, this.sourceEnd, this.defaultValue);
+				pair.binding = this.binding;
+				pair.resolveTypeExpecting(this.scope, returnTypeBinding);
+				this.binding.setDefaultValue(org.eclipse.jdt.internal.compiler.lookup.ElementValuePair.getValue(this.defaultValue));
+			} else { // let it know it does not have a default value so it won't try to find it
+				this.binding.setDefaultValue(null);
+			}
+		}
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		ClassScope classScope) {
+
+		if (visitor.visit(this, classScope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, this.scope);
+			}
+			if (this.returnType != null) {
+				this.returnType.traverse(visitor, this.scope);
+			}
+			if (this.defaultValue != null) {
+				this.defaultValue.traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, classScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
new file mode 100644
index 0000000..5e08fc1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class Argument extends LocalDeclaration {
+
+	// prefix for setter method (to recognize special hiding argument)
+	private final static char[] SET = "set".toCharArray(); //$NON-NLS-1$
+
+	public Argument(char[] name, long posNom, TypeReference tr, int modifiers) {
+
+		super(name, (int) (posNom >>> 32), (int) posNom);
+		this.declarationSourceEnd = (int) posNom;
+		this.modifiers = modifiers;
+		this.type = tr;
+		if (tr != null) {
+			this.bits |= (tr.bits & ASTNode.HasTypeAnnotations);
+		}
+		this.bits |= (IsLocalDeclarationReachable | IsArgument);
+	}
+
+	public Argument(char[] name, long posNom, TypeReference tr, int modifiers, boolean typeElided) {
+
+		super(name, (int) (posNom >>> 32), (int) posNom);
+		this.declarationSourceEnd = (int) posNom;
+		this.modifiers = modifiers;
+		this.type = tr;
+		if (tr != null) {
+			this.bits |= (tr.bits & ASTNode.HasTypeAnnotations);
+		}
+		this.bits |= (IsLocalDeclarationReachable | IsArgument | IsTypeElided);
+	}
+
+	public void createBinding(MethodScope scope, TypeBinding typeBinding) {
+		if (this.binding == null) {
+			// for default constructors and fake implementation of abstract methods 
+			this.binding = new LocalVariableBinding(this, typeBinding, this.modifiers, true /*isArgument*/);
+		} else if (!this.binding.type.isValidBinding()) {
+			AbstractMethodDeclaration methodDecl = scope.referenceMethod();
+			if (methodDecl != null) {
+				MethodBinding methodBinding = methodDecl.binding;
+				if (methodBinding != null) {
+					methodBinding.tagBits |= TagBits.HasUnresolvedArguments;
+				}
+			}
+		}
+		resolveAnnotations(scope, this.annotations, this.binding);
+		this.binding.declaration = this;
+	}
+
+	public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) {
+		createBinding(scope, typeBinding); // basically a no-op if createBinding() was called before
+
+		// record the resolved type into the type reference
+		Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
+		if (existingVariable != null && existingVariable.isValidBinding()){
+			final boolean localExists = existingVariable instanceof LocalVariableBinding;
+			if (localExists && (this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope()) {
+				scope.problemReporter().lambdaRedeclaresArgument(this);
+			} else if (localExists && this.hiddenVariableDepth == 0) {
+				scope.problemReporter().redefineArgument(this);
+			} else {
+				boolean isSpecialArgument = false;
+				if (existingVariable instanceof FieldBinding) {
+					if (scope.isInsideConstructor()) {
+						isSpecialArgument = true; // constructor argument
+					} else {
+						AbstractMethodDeclaration methodDecl = scope.referenceMethod();
+						if (methodDecl != null && CharOperation.prefixEquals(SET, methodDecl.selector)) {
+							isSpecialArgument = true; // setter argument
+						}
+					}
+				}
+				scope.problemReporter().localVariableHiding(this, existingVariable, isSpecialArgument);
+			}
+		}
+		scope.addLocalVariable(this.binding);
+		this.binding.useFlag = used ? LocalVariableBinding.USED : LocalVariableBinding.UNUSED;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
+	 */
+	public int getKind() {
+		return (this.bits & ASTNode.IsArgument) != 0 ? PARAMETER : LOCAL_VARIABLE;
+	}
+
+	public boolean isArgument() {
+		return true;
+	}
+
+	public boolean isVarArgs() {
+		return this.type != null &&  (this.type.bits & IsVarArgs) != 0;
+	}
+	
+	public boolean hasElidedType() {
+		return (this.bits & IsTypeElided) != 0;
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		printIndent(indent, output);
+		printModifiers(this.modifiers, output);
+		if (this.annotations != null) {
+			printAnnotations(this.annotations, output);
+			output.append(' ');
+		}
+
+		if (this.type == null) {
+			output.append("<no type> "); //$NON-NLS-1$
+		} else {
+			this.type.print(0, output).append(' ');
+		}
+		return output.append(this.name);
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+
+		return print(indent, output).append(';');
+	}
+
+	public TypeBinding resolveForCatch(BlockScope scope) {
+		// resolution on an argument of a catch clause
+		// provide the scope with a side effect : insertion of a LOCAL
+		// that represents the argument. The type must be from JavaThrowable
+
+		TypeBinding exceptionType = this.type.resolveType(scope, true /* check bounds*/);
+		boolean hasError;
+		if (exceptionType == null) {
+			hasError = true;
+		} else {
+			hasError = false;
+			switch(exceptionType.kind()) {
+				case Binding.PARAMETERIZED_TYPE :
+					if (exceptionType.isBoundParameterizedType()) {
+						hasError = true;
+						scope.problemReporter().invalidParameterizedExceptionType(exceptionType, this);
+						// fall thru to create the variable - avoids additional errors because the variable is missing
+					}
+					break;
+				case Binding.TYPE_PARAMETER :
+					scope.problemReporter().invalidTypeVariableAsException(exceptionType, this);
+					hasError = true;
+					// fall thru to create the variable - avoids additional errors because the variable is missing
+					break;
+			}
+			if (exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null && exceptionType.isValidBinding()) {
+				scope.problemReporter().cannotThrowType(this.type, exceptionType);
+				hasError = true;
+				// fall thru to create the variable - avoids additional errors because the variable is missing
+			}
+		}
+		Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
+		if (existingVariable != null && existingVariable.isValidBinding()){
+			if (existingVariable instanceof LocalVariableBinding && this.hiddenVariableDepth == 0) {
+				scope.problemReporter().redefineArgument(this);
+			} else {
+				scope.problemReporter().localVariableHiding(this, existingVariable, false);
+			}
+		}
+		
+		if ((this.type.bits & ASTNode.IsUnionType) != 0) {
+			this.binding = new CatchParameterBinding(this, exceptionType, this.modifiers | ClassFileConstants.AccFinal, false); // argument decl, but local var  (where isArgument = false)
+			this.binding.tagBits |= TagBits.MultiCatchParameter;
+		} else {
+			this.binding = new CatchParameterBinding(this, exceptionType, this.modifiers, false); // argument decl, but local var  (where isArgument = false)
+		}
+		resolveAnnotations(scope, this.annotations, this.binding);
+
+		scope.addLocalVariable(this.binding);
+		this.binding.setConstant(Constant.NotAConstant);
+		if (hasError) return null;
+		return exceptionType;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, scope);
+			}
+			if (this.type != null)
+				this.type.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, scope);
+			}
+			if (this.type != null)
+				this.type.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..47cdc77
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ArrayAllocationExpression extends Expression {
+
+	public TypeReference type;
+
+	//dimensions.length gives the number of dimensions, but the
+	// last ones may be nulled as in new int[4][5][][]
+	public Expression[] dimensions;
+	public Annotation [][] annotationsOnDimensions; // jsr308 style annotations.
+	public ArrayInitializer initializer;
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		for (int i = 0, max = this.dimensions.length; i < max; i++) {
+			Expression dim;
+			if ((dim = this.dimensions[i]) != null) {
+				flowInfo = dim.analyseCode(currentScope, flowContext, flowInfo);
+				dim.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+			}
+		}
+		// account for potential OutOfMemoryError:
+		flowContext.recordAbruptExit();
+		if (this.initializer != null) {
+			return this.initializer.analyseCode(currentScope, flowContext, flowInfo);
+		}
+		return flowInfo;
+	}
+
+	/**
+	 * Code generation for a array allocation expression
+	 */
+	public void generateCode(BlockScope currentScope, 	CodeStream codeStream, boolean valueRequired) {
+
+		int pc = codeStream.position;
+
+		if (this.initializer != null) {
+			this.initializer.generateCode(this.type, this.annotationsOnDimensions, currentScope, codeStream, valueRequired);
+			return;
+		}
+
+		int explicitDimCount = 0;
+		for (int i = 0, max = this.dimensions.length; i < max; i++) {
+			Expression dimExpression;
+			if ((dimExpression = this.dimensions[i]) == null) break; // implicit dim, no further explict after this point
+			dimExpression.generateCode(currentScope, codeStream, true);
+			explicitDimCount++;
+		}
+
+		// array allocation
+		if (explicitDimCount == 1) {
+			// Mono-dimensional array
+			codeStream.newArray(this.type, this.annotationsOnDimensions, (ArrayBinding)this.resolvedType);
+		} else {
+			// Multi-dimensional array
+			codeStream.multianewarray(this.type, this.resolvedType, this.dimensions.length, this.annotationsOnDimensions);
+		}
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		} else {
+			codeStream.pop();
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("new "); //$NON-NLS-1$
+		this.type.print(0, output);
+		for (int i = 0; i < this.dimensions.length; i++) {
+			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+				output.append(' ');
+				printAnnotations(this.annotationsOnDimensions[i], output);
+				output.append(' ');
+			}
+			if (this.dimensions[i] == null)
+				output.append("[]"); //$NON-NLS-1$
+			else {
+				output.append('[');
+				this.dimensions[i].printExpression(0, output);
+				output.append(']');
+			}
+		}
+		if (this.initializer != null) this.initializer.printExpression(0, output);
+		return output;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		// Build an array type reference using the current dimensions
+		// The parser does not check for the fact that dimension may be null
+		// only at the -end- like new int [4][][]. The parser allows new int[][4][]
+		// so this must be checked here......(this comes from a reduction to LL1 grammar)
+
+		TypeBinding referenceType = this.type.resolveType(scope, true /* check bounds*/);
+
+		// will check for null after dimensions are checked
+		this.constant = Constant.NotAConstant;
+		if (referenceType == TypeBinding.VOID) {
+			scope.problemReporter().cannotAllocateVoidArray(this);
+			referenceType = null;
+		}
+
+		// check the validity of the dimension syntax (and test for all null dimensions)
+		int explicitDimIndex = -1;
+		loop: for (int i = this.dimensions.length; --i >= 0;) {
+			if (this.dimensions[i] != null) {
+				if (explicitDimIndex < 0) explicitDimIndex = i;
+			} else if (explicitDimIndex > 0) {
+				// should not have an empty dimension before an non-empty one
+				scope.problemReporter().incorrectLocationForNonEmptyDimension(this, explicitDimIndex);
+				break loop;
+			}
+		}
+
+		// explicitDimIndex < 0 says if all dimensions are nulled
+		// when an initializer is given, no dimension must be specified
+		if (this.initializer == null) {
+			if (explicitDimIndex < 0) {
+				scope.problemReporter().mustDefineDimensionsOrInitializer(this);
+			}
+			// allow new List<?>[5] - only check for generic array when no initializer, since also checked inside initializer resolution
+			if (referenceType != null && !referenceType.isReifiable()) {
+			    scope.problemReporter().illegalGenericArray(referenceType, this);
+			}
+		} else if (explicitDimIndex >= 0) {
+			scope.problemReporter().cannotDefineDimensionsAndInitializer(this);
+		}
+
+		// dimensions resolution
+		for (int i = 0; i <= explicitDimIndex; i++) {
+			Expression dimExpression;
+			if ((dimExpression = this.dimensions[i]) != null) {
+				TypeBinding dimensionType = dimExpression.resolveTypeExpecting(scope, TypeBinding.INT);
+				if (dimensionType != null) {
+					this.dimensions[i].computeConversion(scope, TypeBinding.INT, dimensionType);
+				}
+			}
+		}
+
+		// building the array binding
+		if (referenceType != null) {
+			if (this.dimensions.length > 255) {
+				scope.problemReporter().tooManyDimensions(this);
+			}
+			this.resolvedType = scope.createArrayType(referenceType, this.dimensions.length);
+
+			// check the initializer
+			if (this.initializer != null) {
+				if ((this.initializer.resolveTypeExpecting(scope, this.resolvedType)) != null)
+					this.initializer.binding = (ArrayBinding)this.resolvedType;
+			}
+			if ((referenceType.tagBits & TagBits.HasMissingType) != 0) {
+				return null;
+			}
+		}
+		if (this.annotationsOnDimensions != null) {
+			for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+				Annotation[] annotations = this.annotationsOnDimensions[i];
+				resolveAnnotations(scope, annotations, new Annotation.TypeUseBinding(Binding.TYPE_USE));
+			}
+		}
+		return this.resolvedType;
+	}
+
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			int dimensionsLength = this.dimensions.length;
+			this.type.traverse(visitor, scope);
+			for (int i = 0; i < dimensionsLength; i++) {
+				if (this.dimensions[i] != null)
+					this.dimensions[i].traverse(visitor, scope);
+			}
+			if (this.initializer != null)
+				this.initializer.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
new file mode 100644
index 0000000..d39eeef
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for 
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ArrayInitializer extends Expression {
+
+	public Expression[] expressions;
+	public ArrayBinding binding; //the type of the { , , , }
+
+	/**
+	 * ArrayInitializer constructor comment.
+	 */
+	public ArrayInitializer() {
+
+		super();
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+		if (this.expressions != null) {
+			boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+			for (int i = 0, max = this.expressions.length; i < max; i++) {
+				flowInfo = this.expressions[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+
+				if (analyseResources && FakedTrackingVariable.isAnyCloseable(this.expressions[i].resolvedType)) {
+					flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expressions[i], flowInfo, flowContext, false);
+				}
+			}
+		}
+		return flowInfo;
+	}
+
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		generateCode(null, null, currentScope, codeStream, valueRequired);
+	}
+	
+	/**
+	 * Code generation for a array initializer
+	 */
+	public void generateCode(TypeReference typeReference, Annotation[][] annotationsOnDimensions, BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		// Flatten the values and compute the dimensions, by iterating in depth into nested array initializers
+		int pc = codeStream.position;
+		int expressionLength = (this.expressions == null) ? 0: this.expressions.length;
+		codeStream.generateInlinedValue(expressionLength);
+		codeStream.newArray(typeReference, annotationsOnDimensions, this.binding);
+		if (this.expressions != null) {
+			// binding is an ArrayType, so I can just deal with the dimension
+			int elementsTypeID = this.binding.dimensions > 1 ? -1 : this.binding.leafComponentType.id;
+			for (int i = 0; i < expressionLength; i++) {
+				Expression expr;
+				if ((expr = this.expressions[i]).constant != Constant.NotAConstant) {
+					switch (elementsTypeID) { // filter out initializations to default values
+						case T_int :
+						case T_short :
+						case T_byte :
+						case T_char :
+						case T_long :
+							if (expr.constant.longValue() != 0) {
+								codeStream.dup();
+								codeStream.generateInlinedValue(i);
+								expr.generateCode(currentScope, codeStream, true);
+								codeStream.arrayAtPut(elementsTypeID, false);
+							}
+							break;
+						case T_float :
+						case T_double :
+							double constantValue = expr.constant.doubleValue();
+							if (constantValue == -0.0 || constantValue != 0) {
+								codeStream.dup();
+								codeStream.generateInlinedValue(i);
+								expr.generateCode(currentScope, codeStream, true);
+								codeStream.arrayAtPut(elementsTypeID, false);
+							}
+							break;
+						case T_boolean :
+							if (expr.constant.booleanValue() != false) {
+								codeStream.dup();
+								codeStream.generateInlinedValue(i);
+								expr.generateCode(currentScope, codeStream, true);
+								codeStream.arrayAtPut(elementsTypeID, false);
+							}
+							break;
+						default :
+							if (!(expr instanceof NullLiteral)) {
+								codeStream.dup();
+								codeStream.generateInlinedValue(i);
+								expr.generateCode(currentScope, codeStream, true);
+								codeStream.arrayAtPut(elementsTypeID, false);
+							}
+					}
+				} else if (!(expr instanceof NullLiteral)) {
+					codeStream.dup();
+					codeStream.generateInlinedValue(i);
+					expr.generateCode(currentScope, codeStream, true);
+					codeStream.arrayAtPut(elementsTypeID, false);
+				}
+			}
+		}
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		} else {
+			codeStream.pop();
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		output.append('{');
+		if (this.expressions != null) {
+			int j = 20 ;
+			for (int i = 0 ; i < this.expressions.length ; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.expressions[i].printExpression(0, output);
+				j -- ;
+				if (j == 0) {
+					output.append('\n');
+					printIndent(indent+1, output);
+					j = 20;
+				}
+			}
+		}
+		return output.append('}');
+	}
+
+	public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedType) {
+		// Array initializers can only occur on the right hand side of an assignment
+		// expression, therefore the expected type contains the valid information
+		// concerning the type that must be enforced by the elements of the array initializer.
+
+		// this method is recursive... (the test on isArrayType is the stop case)
+
+		this.constant = Constant.NotAConstant;
+
+		if (expectedType instanceof ArrayBinding) {
+			// allow new List<?>[5]
+			if ((this.bits & IsAnnotationDefaultValue) == 0) { // annotation default value need only to be commensurate JLS9.7
+				// allow new List<?>[5] - only check for generic array when no initializer, since also checked inside initializer resolution
+				TypeBinding leafComponentType = expectedType.leafComponentType();
+				if (!leafComponentType.isReifiable()) {
+				    scope.problemReporter().illegalGenericArray(leafComponentType, this);
+				}
+			}
+			this.resolvedType = this.binding = (ArrayBinding) expectedType;
+			if (this.expressions == null)
+				return this.binding;
+			TypeBinding elementType = this.binding.elementsType();
+			for (int i = 0, length = this.expressions.length; i < length; i++) {
+				Expression expression = this.expressions[i];
+				expression.setExpressionContext(ASSIGNMENT_CONTEXT);
+				expression.setExpectedType(elementType);
+				TypeBinding expressionType = expression instanceof ArrayInitializer
+						? expression.resolveTypeExpecting(scope, elementType)
+						: expression.resolveType(scope);
+				if (expressionType == null)
+					continue;
+
+				// Compile-time conversion required?
+				if (elementType != expressionType) // must call before computeConversion() and typeMismatchError()
+					scope.compilationUnitScope().recordTypeConversion(elementType, expressionType);
+
+				if (expression.isConstantValueOfTypeAssignableToType(expressionType, elementType) 
+						|| expressionType.isCompatibleWith(elementType)) {
+					expression.computeConversion(scope, elementType, expressionType);
+				} else if (isBoxingCompatible(expressionType, elementType, expression, scope)) {
+					expression.computeConversion(scope, elementType, expressionType);
+				} else {
+					scope.problemReporter().typeMismatchError(expressionType, elementType, expression, null);
+				}
+			}
+			return this.binding;
+		}
+
+		// infer initializer type for error reporting based on first element
+		TypeBinding leafElementType = null;
+		int dim = 1;
+		if (this.expressions == null) {
+			leafElementType = scope.getJavaLangObject();
+		} else {
+			Expression expression = this.expressions[0];
+			while(expression != null && expression instanceof ArrayInitializer) {
+				dim++;
+				Expression[] subExprs = ((ArrayInitializer) expression).expressions;
+				if (subExprs == null){
+					leafElementType = scope.getJavaLangObject();
+					expression = null;
+					break;
+				}
+				expression = ((ArrayInitializer) expression).expressions[0];
+			}
+			if (expression != null) {
+				leafElementType = expression.resolveType(scope);
+			}
+			// fault-tolerance - resolve other expressions as well
+			for (int i = 1, length = this.expressions.length; i < length; i++) {
+				expression = this.expressions[i];
+				if (expression != null) {
+					expression.resolveType(scope)	;
+				}
+			}		}
+		if (leafElementType != null) {
+			this.resolvedType = scope.createArrayType(leafElementType, dim);
+			if (expectedType != null)
+				scope.problemReporter().typeMismatchError(this.resolvedType, expectedType, this, null);
+		}
+		return null;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.expressions != null) {
+				int expressionsLength = this.expressions.length;
+				for (int i = 0; i < expressionsLength; i++)
+					this.expressions[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java
new file mode 100644
index 0000000..6145e74
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+
+public class ArrayQualifiedTypeReference extends QualifiedTypeReference {
+	int dimensions;
+	Annotation[][] annotationsOnDimensions;  // jsr308 style type annotations on dimensions
+
+	public ArrayQualifiedTypeReference(char[][] sources , int dim, long[] poss) {
+
+		super( sources , poss);
+		this.dimensions = dim ;
+		this.annotationsOnDimensions = null; 
+	}
+
+	public ArrayQualifiedTypeReference(char[][] sources, int dim, Annotation[][] annotationsOnDimensions, long[] poss) {
+		this(sources, dim, poss);
+		this.annotationsOnDimensions = annotationsOnDimensions;
+		if (annotationsOnDimensions != null)
+			this.bits |= ASTNode.HasTypeAnnotations;
+	}
+
+	public int dimensions() {
+
+		return this.dimensions;
+	}
+	
+	public Annotation[][] getAnnotationsOnDimensions() {
+		return this.annotationsOnDimensions;
+	}
+	
+	public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
+		this.annotationsOnDimensions = annotationsOnDimensions;
+	}
+
+	/**
+	 * @return char[][]
+	 */
+	public char [][] getParameterizedTypeName(){
+		int dim = this.dimensions;
+		char[] dimChars = new char[dim*2];
+		for (int i = 0; i < dim; i++) {
+			int index = i*2;
+			dimChars[index] = '[';
+			dimChars[index+1] = ']';
+		}
+		int length = this.tokens.length;
+		char[][] qParamName = new char[length][];
+		System.arraycopy(this.tokens, 0, qParamName, 0, length-1);
+		qParamName[length-1] = CharOperation.concat(this.tokens[length-1], dimChars);
+		return qParamName;
+	}
+
+	protected TypeBinding getTypeBinding(Scope scope) {
+
+		if (this.resolvedType != null)
+			return this.resolvedType;
+		if (this.dimensions > 255) {
+			scope.problemReporter().tooManyDimensions(this);
+		}
+		LookupEnvironment env = scope.environment();
+		try {
+			env.missingClassFileLocation = this;
+			TypeBinding leafComponentType = super.getTypeBinding(scope);
+			if (leafComponentType != null) {
+				return this.resolvedType = scope.createArrayType(leafComponentType, this.dimensions);
+			}
+			return null;
+		} catch (AbortCompilation e) {
+			e.updateContext(this, scope.referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	protected TypeBinding internalResolveType(Scope scope) {
+		TypeBinding internalResolveType = super.internalResolveType(scope);
+		return internalResolveType;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		super.printExpression(indent, output);
+		if ((this.bits & IsVarArgs) != 0) {
+			for (int i= 0 ; i < this.dimensions - 1; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(' ');
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(' ');
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
+				output.append(' ');
+				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
+				output.append(' ');
+			}
+			output.append("..."); //$NON-NLS-1$
+		} else {
+			for (int i= 0 ; i < this.dimensions; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
+						Annotation annotation = annotations2[j];
+						annotation.traverse(visitor, scope);
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
+						Annotation annotation = annotations2[j];
+						annotation.traverse(visitor, scope);
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
new file mode 100644
index 0000000..4c896b1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class ArrayReference extends Reference {
+
+	public Expression receiver;
+	public Expression position;
+
+public ArrayReference(Expression rec, Expression pos) {
+	this.receiver = rec;
+	this.position = pos;
+	this.sourceStart = rec.sourceStart;
+}
+
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean compoundAssignment) {
+	// TODO (maxime) optimization: unconditionalInits is applied to all existing calls
+	// account for potential ArrayIndexOutOfBoundsException:
+	flowContext.recordAbruptExit();
+	if (assignment.expression == null) {
+		return analyseCode(currentScope, flowContext, flowInfo);
+	}
+	flowInfo = assignment
+		.expression
+		.analyseCode(
+			currentScope,
+			flowContext,
+			analyseCode(currentScope, flowContext, flowInfo).unconditionalInits());
+	if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) {
+		int nullStatus = assignment.expression.nullStatus(flowInfo, flowContext);
+		if (nullStatus != FlowInfo.NON_NULL) {
+			currentScope.problemReporter().nullityMismatch(this, assignment.expression.resolvedType, this.resolvedType, nullStatus, currentScope.environment().getNonNullAnnotationName());
+		}
+	}
+	return flowInfo;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	this.receiver.checkNPE(currentScope, flowContext, flowInfo);
+	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo);
+	flowInfo = this.position.analyseCode(currentScope, flowContext, flowInfo);
+	this.position.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	// account for potential ArrayIndexOutOfBoundsException:
+	flowContext.recordAbruptExit();
+	return flowInfo;
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0) {
+		scope.problemReporter().arrayReferencePotentialNullReference(this);
+		return true;
+	} else {
+		return super.checkNPE(scope, flowContext, flowInfo);
+	}
+}
+
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	int pc = codeStream.position;
+	this.receiver.generateCode(currentScope, codeStream, true);
+	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
+			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
+		codeStream.checkcast(this.receiver.resolvedType);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+	this.position.generateCode(currentScope, codeStream, true);
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+
+/**
+ * Code generation for a array reference
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	this.receiver.generateCode(currentScope, codeStream, true);
+	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
+			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
+		codeStream.checkcast(this.receiver.resolvedType);
+	}
+	this.position.generateCode(currentScope, codeStream, true);
+	codeStream.arrayAt(this.resolvedType.id);
+	// Generating code for the potential runtime type checking
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else {
+		boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+		// conversion only generated if unboxing
+		if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+		switch (isUnboxing ? postConversionType(currentScope).id : this.resolvedType.id) {
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			default :
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	this.receiver.generateCode(currentScope, codeStream, true);
+	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
+			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
+		codeStream.checkcast(this.receiver.resolvedType);
+	}
+	this.position.generateCode(currentScope, codeStream, true);
+	codeStream.dup2();
+	codeStream.arrayAt(this.resolvedType.id);
+	int operationTypeID;
+	switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
+		case T_JavaLangString :
+		case T_JavaLangObject :
+		case T_undefined :
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+			break;
+		default :
+			// promote the array reference to the suitable operation type
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One) { // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
+}
+
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	this.receiver.generateCode(currentScope, codeStream, true);
+	if (this.receiver instanceof CastExpression	// ((type[])null)[0]
+			&& ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){
+		codeStream.checkcast(this.receiver.resolvedType);
+	}
+	this.position.generateCode(currentScope, codeStream, true);
+	codeStream.dup2();
+	codeStream.arrayAt(this.resolvedType.id);
+	if (valueRequired) {
+		switch(this.resolvedType.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2_x2();
+				break;
+			default :
+				codeStream.dup_x2();
+				break;
+		}
+	}
+	codeStream.generateImplicitConversion(this.implicitConversion);
+	codeStream.generateConstant(
+		postIncrement.expression.constant,
+		this.implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+	codeStream.generateImplicitConversion(
+		postIncrement.preAssignImplicitConversion);
+	codeStream.arrayAtPut(this.resolvedType.id, false);
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	this.receiver.printExpression(0, output).append('[');
+	return this.position.printExpression(0, output).append(']');
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	this.constant = Constant.NotAConstant;
+	if (this.receiver instanceof CastExpression	// no cast check for ((type[])null)[0]
+			&& ((CastExpression)this.receiver).innermostCastedExpression() instanceof NullLiteral) {
+		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+	}
+	TypeBinding arrayType = this.receiver.resolveType(scope);
+	if (arrayType != null) {
+		this.receiver.computeConversion(scope, arrayType, arrayType);
+		if (arrayType.isArrayType()) {
+			TypeBinding elementType = ((ArrayBinding) arrayType).elementsType();
+			this.resolvedType = ((this.bits & ASTNode.IsStrictlyAssigned) == 0) ? elementType.capture(scope, this.sourceEnd) : elementType;
+		} else {
+			scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this);
+		}
+	}
+	TypeBinding positionType = this.position.resolveTypeExpecting(scope, TypeBinding.INT);
+	if (positionType != null) {
+		this.position.computeConversion(scope, TypeBinding.INT, positionType);
+	}
+	return this.resolvedType;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.receiver.traverse(visitor, scope);
+		this.position.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
new file mode 100644
index 0000000..e6cd3e0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class ArrayTypeReference extends SingleTypeReference {
+	public int dimensions;
+	public Annotation[][] annotationsOnDimensions; // jsr308 style type annotations on dimensions.
+	public int originalSourceEnd;
+
+	/**
+	 * ArrayTypeReference constructor comment.
+	 * @param source char[]
+	 * @param dimensions int
+	 * @param pos int
+	 */
+	public ArrayTypeReference(char[] source, int dimensions, long pos) {
+
+		super(source, pos);
+		this.originalSourceEnd = this.sourceEnd;
+		this.dimensions = dimensions ;
+		this.annotationsOnDimensions = null;
+	}
+
+	public ArrayTypeReference(char[] source, int dimensions, Annotation[][] annotationsOnDimensions, long pos) {
+		this(source, dimensions, pos);
+		if (annotationsOnDimensions != null) {
+			this.bits |= ASTNode.HasTypeAnnotations;
+		}
+		this.annotationsOnDimensions = annotationsOnDimensions;
+	}
+
+	public int dimensions() {
+
+		return this.dimensions;
+	}
+	
+	public Annotation[][] getAnnotationsOnDimensions() {
+		return this.annotationsOnDimensions;
+	}
+	public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
+		this.annotationsOnDimensions = annotationsOnDimensions;
+	}
+	/**
+	 * @return char[][]
+	 */
+	public char [][] getParameterizedTypeName(){
+		int dim = this.dimensions;
+		char[] dimChars = new char[dim*2];
+		for (int i = 0; i < dim; i++) {
+			int index = i*2;
+			dimChars[index] = '[';
+			dimChars[index+1] = ']';
+		}
+		return new char[][]{ CharOperation.concat(this.token, dimChars) };
+	}
+	protected TypeBinding getTypeBinding(Scope scope) {
+
+		if (this.resolvedType != null) {
+			return this.resolvedType;
+		}
+		if (this.dimensions > 255) {
+			scope.problemReporter().tooManyDimensions(this);
+		}
+		TypeBinding leafComponentType = scope.getType(this.token);
+		return scope.createArrayType(leafComponentType, this.dimensions);
+
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		super.printExpression(indent, output);
+		if ((this.bits & IsVarArgs) != 0) {
+			for (int i= 0 ; i < this.dimensions - 1; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(' ');
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(' ');
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
+				output.append(' ');
+				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
+				output.append(' ');
+			}
+			output.append("..."); //$NON-NLS-1$
+		} else {
+			for (int i= 0 ; i < this.dimensions; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
+					typeAnnotations[i].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					if (annotations2 != null) {
+						for (int j = 0, max2 = annotations2.length; j < max2; j++) {
+							Annotation annotation = annotations2[j];
+							annotation.traverse(visitor, scope);
+						}
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
+					typeAnnotations[i].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					if (annotations2 != null) {
+						for (int j = 0, max2 = annotations2.length; j < max2; j++) {
+							Annotation annotation = annotations2[j];
+							annotation.traverse(visitor, scope);
+						}
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	protected TypeBinding internalResolveType(Scope scope) {
+		TypeBinding internalResolveType = super.internalResolveType(scope);
+		return internalResolveType;
+	}
+}
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
new file mode 100644
index 0000000..17cbc01
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+
+public class AssertStatement extends Statement {
+
+	public Expression assertExpression, exceptionArgument;
+
+	// for local variable attribute
+	int preAssertInitStateIndex = -1;
+	private FieldBinding assertionSyntheticFieldBinding;
+
+public AssertStatement(	Expression exceptionArgument, Expression assertExpression, int startPosition) {
+	this.assertExpression = assertExpression;
+	this.exceptionArgument = exceptionArgument;
+	this.sourceStart = startPosition;
+	this.sourceEnd = exceptionArgument.sourceEnd;
+}
+
+public AssertStatement(Expression assertExpression, int startPosition) {
+	this.assertExpression = assertExpression;
+	this.sourceStart = startPosition;
+	this.sourceEnd = assertExpression.sourceEnd;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	this.preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+
+	Constant cst = this.assertExpression.optimizedBooleanConstant();
+	this.assertExpression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true;
+	boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false;
+	
+	flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING;
+	FlowInfo conditionFlowInfo = this.assertExpression.analyseCode(currentScope, flowContext, flowInfo.copy());
+	flowContext.extendTimeToLiveForNullCheckedField(1); // survive this assert as a Statement
+	flowContext.tagBits &= ~FlowContext.HIDE_NULL_COMPARISON_WARNING;
+	UnconditionalFlowInfo assertWhenTrueInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits();
+	FlowInfo assertInfo = conditionFlowInfo.initsWhenFalse();
+	if (isOptimizedTrueAssertion) {
+		assertInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+	}
+
+	if (this.exceptionArgument != null) {
+		// only gets evaluated when escaping - results are not taken into account
+		FlowInfo exceptionInfo = this.exceptionArgument.analyseCode(currentScope, flowContext, assertInfo.copy());
+
+		if (isOptimizedTrueAssertion){
+			currentScope.problemReporter().fakeReachable(this.exceptionArgument);
+		} else {
+			flowContext.checkExceptionHandlers(
+				currentScope.getJavaLangAssertionError(),
+				this,
+				exceptionInfo,
+				currentScope);
+		}
+	}
+
+	if (!isOptimizedTrueAssertion){
+		// add the assert support in the clinit
+		manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+	}
+	// account for potential AssertionError:
+	flowContext.recordAbruptExit();
+	if (isOptimizedFalseAssertion) {
+		return flowInfo; // if assertions are enabled, the following code will be unreachable
+		// change this if we need to carry null analysis results of the assert
+		// expression downstream
+	} else {
+		CompilerOptions compilerOptions = currentScope.compilerOptions();
+		if (!compilerOptions.includeNullInfoFromAsserts) {
+			// keep just the initializations info, don't include assert's null info
+			// merge initialization info's and then add back the null info from flowInfo to
+			// make sure that the empty null info of assertInfo doesnt change flowInfo's null info.
+			return ((flowInfo.nullInfoLessUnconditionalCopy()).mergedWith(assertInfo.nullInfoLessUnconditionalCopy())).addNullInfoFrom(flowInfo);
+		}
+		return flowInfo.mergedWith(assertInfo.nullInfoLessUnconditionalCopy()).
+			addInitializationsFrom(assertWhenTrueInfo.discardInitializationInfo());
+		// keep the merge from the initial code for the definite assignment
+		// analysis, tweak the null part to influence nulls downstream
+	}
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	if (this.assertionSyntheticFieldBinding != null) {
+		BranchLabel assertionActivationLabel = new BranchLabel(codeStream);
+		codeStream.fieldAccess(Opcodes.OPC_getstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */);
+		codeStream.ifne(assertionActivationLabel);
+
+		BranchLabel falseLabel;
+		this.assertExpression.generateOptimizedBoolean(currentScope, codeStream, (falseLabel = new BranchLabel(codeStream)), null , true);
+		codeStream.newJavaLangAssertionError();
+		codeStream.dup();
+		if (this.exceptionArgument != null) {
+			this.exceptionArgument.generateCode(currentScope, codeStream, true);
+			codeStream.invokeJavaLangAssertionErrorConstructor(this.exceptionArgument.implicitConversion & 0xF);
+		} else {
+			codeStream.invokeJavaLangAssertionErrorDefaultConstructor();
+		}
+		codeStream.athrow();
+
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.preAssertInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preAssertInitStateIndex);
+		}
+		falseLabel.place();
+		assertionActivationLabel.place();
+	} else {
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.preAssertInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preAssertInitStateIndex);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public void resolve(BlockScope scope) {
+	this.assertExpression.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
+	if (this.exceptionArgument != null) {
+		TypeBinding exceptionArgumentType = this.exceptionArgument.resolveType(scope);
+		if (exceptionArgumentType != null){
+		    int id = exceptionArgumentType.id;
+		    switch(id) {
+				case T_void :
+					scope.problemReporter().illegalVoidExpression(this.exceptionArgument);
+					//$FALL-THROUGH$
+				default:
+				    id = T_JavaLangObject;
+				//$FALL-THROUGH$
+				case T_boolean :
+				case T_byte :
+				case T_char :
+				case T_short :
+				case T_double :
+				case T_float :
+				case T_int :
+				case T_long :
+				case T_JavaLangString :
+					this.exceptionArgument.implicitConversion = (id << 4) + id;
+			}
+		}
+	}
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.assertExpression.traverse(visitor, scope);
+		if (this.exceptionArgument != null) {
+			this.exceptionArgument.traverse(visitor, scope);
+		}
+	}
+	visitor.endVisit(this, scope);
+}
+
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		// need assertion flag: $assertionsDisabled on outer most source clas
+		// (in case of static member of interface, will use the outermost static member - bug 22334)
+		SourceTypeBinding outerMostClass = currentScope.enclosingSourceType();
+		while (outerMostClass.isLocalType()) {
+			ReferenceBinding enclosing = outerMostClass.enclosingType();
+			if (enclosing == null || enclosing.isInterface()) break;
+			outerMostClass = (SourceTypeBinding) enclosing;
+		}
+		this.assertionSyntheticFieldBinding = outerMostClass.addSyntheticFieldForAssert(currentScope);
+
+		// find <clinit> and enable assertion support
+		TypeDeclaration typeDeclaration = outerMostClass.scope.referenceType();
+		AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+		for (int i = 0, max = methods.length; i < max; i++) {
+			AbstractMethodDeclaration method = methods[i];
+			if (method.isClinit()) {
+				((Clinit) method).setAssertionSupport(this.assertionSyntheticFieldBinding, currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5);
+				break;
+			}
+		}
+	}
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	printIndent(tab, output);
+	output.append("assert "); //$NON-NLS-1$
+	this.assertExpression.printExpression(0, output);
+	if (this.exceptionArgument != null) {
+		output.append(": "); //$NON-NLS-1$
+		this.exceptionArgument.printExpression(0, output);
+	}
+	return output.append(';');
+}
+}
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
new file mode 100644
index 0000000..6385def
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Genady Beriozkin - added support for reporting assignment with no effect
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ * 							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ * 							bug 292478 - Report potentially null across variable assignment
+ *     						bug 335093 - [compiler][null] minimal hook for future null annotation support
+ *     						bug 349326 - [1.7] new warning for missing try-with-resources
+ *							bug 186342 - [compiler][null] Using annotations for null checking
+ *							bug 358903 - Filter practically unimportant resource leak warnings
+ *							bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *							bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *							bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *							bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *							bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *							bug 331649 - [compiler][null] consider null annotations for fields
+ *							bug 383368 - [compiler][null] syntactic null analysis for field references
+ *							bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *							bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class Assignment extends Expression {
+
+	public Expression lhs;
+	public Expression expression;
+
+public Assignment(Expression lhs, Expression expression, int sourceEnd) {
+	//lhs is always a reference by construction ,
+	//but is build as an expression ==> the checkcast cannot fail
+	this.lhs = lhs;
+	lhs.bits |= IsStrictlyAssigned; // tag lhs as assigned
+	this.expression = expression;
+	this.sourceStart = lhs.sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// record setting a variable: various scenarii are possible, setting an array reference,
+// a field reference, a blank final field reference, a field of an enclosing instance or
+// just a local variable.
+	LocalVariableBinding local = this.lhs.localVariableBinding();
+	this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	
+	FlowInfo preInitInfo = null;
+	CompilerOptions compilerOptions = currentScope.compilerOptions();
+	boolean shouldAnalyseResource = local != null
+			&& flowInfo.reachMode() == FlowInfo.REACHABLE
+			&& compilerOptions.analyseResourceLeaks
+			&& (FakedTrackingVariable.isAnyCloseable(this.expression.resolvedType)
+					|| this.expression.resolvedType == TypeBinding.NULL);
+	if (shouldAnalyseResource) {
+		preInitInfo = flowInfo.unconditionalCopy();
+		// analysis of resource leaks needs additional context while analyzing the RHS:
+		FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, local, this.expression, flowInfo);
+	}
+	
+	flowInfo = ((Reference) this.lhs)
+		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
+		.unconditionalInits();
+
+	if (shouldAnalyseResource)
+		FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, flowContext, this, this.expression, local);
+	else
+		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, this.lhs.bits, this.expression);
+
+	int nullStatus = this.expression.nullStatus(flowInfo, flowContext);
+	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+		if (nullStatus == FlowInfo.NULL) {
+			flowContext.recordUsingNullReference(currentScope, local, this.lhs,
+				FlowContext.CAN_ONLY_NULL | FlowContext.IN_ASSIGNMENT, flowInfo);
+		}
+	}
+	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+		VariableBinding var = this.lhs.nullAnnotatedVariableBinding(compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8);
+		if (var != null) {
+			nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, var, nullStatus, this.expression, this.expression.resolvedType);
+			if (nullStatus == FlowInfo.NON_NULL
+					&& var instanceof FieldBinding
+					&& this.lhs instanceof Reference
+					&& compilerOptions.enableSyntacticNullAnalysisForFields)
+			{
+				int timeToLive = (this.bits & InsideExpressionStatement) != 0
+									? 2  // assignment is statement: make info survives the end of this statement
+									: 1; // assignment is expression: expire on next event.
+				flowContext.recordNullCheckedFieldReference((Reference) this.lhs, timeToLive);
+			}
+		}
+	}
+	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+		flowInfo.markNullStatus(local, nullStatus);
+		flowContext.markFinallyNullStatus(local, nullStatus);
+	}
+	return flowInfo;
+}
+
+void checkAssignment(BlockScope scope, TypeBinding lhsType, TypeBinding rhsType) {
+	FieldBinding leftField = getLastField(this.lhs);
+	if (leftField != null &&  rhsType != TypeBinding.NULL && (lhsType.kind() == Binding.WILDCARD_TYPE) && ((WildcardBinding)lhsType).boundKind != Wildcard.SUPER) {
+	    scope.problemReporter().wildcardAssignment(lhsType, rhsType, this.expression);
+	} else if (leftField != null && !leftField.isStatic() && leftField.declaringClass != null /*length pseudo field*/&& leftField.declaringClass.isRawType()) {
+	    scope.problemReporter().unsafeRawFieldAssignment(leftField, rhsType, this.lhs);
+	} else if (rhsType.needsUncheckedConversion(lhsType)) {
+	    scope.problemReporter().unsafeTypeConversion(this.expression, rhsType, lhsType);
+	}
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	// various scenarii are possible, setting an array reference,
+	// a field reference, a blank final field reference, a field of an enclosing instance or
+	// just a local variable.
+
+	int pc = codeStream.position;
+	 ((Reference) this.lhs).generateAssignment(currentScope, codeStream, this, valueRequired);
+	// variable may have been optimized out
+	// the lhs is responsible to perform the implicitConversion generation for the assignment since optimized for unused local assignment.
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+FieldBinding getLastField(Expression someExpression) {
+    if (someExpression instanceof SingleNameReference) {
+        if ((someExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) {
+            return (FieldBinding) ((SingleNameReference)someExpression).binding;
+        }
+    } else if (someExpression instanceof FieldReference) {
+        return ((FieldReference)someExpression).binding;
+    } else if (someExpression instanceof QualifiedNameReference) {
+        QualifiedNameReference qName = (QualifiedNameReference) someExpression;
+        if (qName.otherBindings == null) {
+        	if ((someExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) {
+        		return (FieldBinding)qName.binding;
+        	}
+        } else {
+            return qName.otherBindings[qName.otherBindings.length - 1];
+        }
+    }
+    return null;
+}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	return this.expression.nullStatus(flowInfo, flowContext);
+}
+
+public StringBuffer print(int indent, StringBuffer output) {
+	//no () when used as a statement
+	printIndent(indent, output);
+	return printExpressionNoParenthesis(indent, output);
+}
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	//subclass redefine printExpressionNoParenthesis()
+	output.append('(');
+	return printExpressionNoParenthesis(0, output).append(')');
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+	this.lhs.printExpression(indent, output).append(" = "); //$NON-NLS-1$
+	return this.expression.printExpression(0, output);
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	//no () when used as a statement
+	return print(indent, output).append(';');
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// due to syntax lhs may be only a NameReference, a FieldReference or an ArrayReference
+	this.constant = Constant.NotAConstant;
+	if (!(this.lhs instanceof Reference) || this.lhs.isThis()) {
+		scope.problemReporter().expressionShouldBeAVariable(this.lhs);
+		return null;
+	}
+	TypeBinding lhsType = this.lhs.resolveType(scope);
+	this.expression.setExpressionContext(ASSIGNMENT_CONTEXT);
+	this.expression.setExpectedType(lhsType); // needed in case of generic method invocation
+	if (lhsType != null) {
+		this.resolvedType = lhsType.capture(scope, this.sourceEnd);
+	}
+	LocalVariableBinding localVariableBinding = this.lhs.localVariableBinding();
+	if (localVariableBinding != null && localVariableBinding.isCatchParameter()) { 
+		localVariableBinding.tagBits &= ~TagBits.IsEffectivelyFinal;  // as it is already definitely assigned, we can conclude already. Also note: catch parameter cannot be compound assigned.
+	}
+	TypeBinding rhsType = this.expression.resolveType(scope);
+	if (lhsType == null || rhsType == null) {
+		return null;
+	}
+	// check for assignment with no effect
+	Binding left = getDirectBinding(this.lhs);
+	if (left != null && !left.isVolatile() && left == getDirectBinding(this.expression)) {
+		scope.problemReporter().assignmentHasNoEffect(this, left.shortReadableName());
+	}
+
+	// Compile-time conversion of base-types : implicit narrowing integer into byte/short/character
+	// may require to widen the rhs expression at runtime
+	if (lhsType != rhsType) { // must call before computeConversion() and typeMismatchError()
+		scope.compilationUnitScope().recordTypeConversion(lhsType, rhsType);
+	}
+	if (this.expression.isConstantValueOfTypeAssignableToType(rhsType, lhsType)
+			|| rhsType.isCompatibleWith(lhsType, scope)) {
+		this.expression.computeConversion(scope, lhsType, rhsType);
+		checkAssignment(scope, lhsType, rhsType);
+		if (this.expression instanceof CastExpression
+				&& (this.expression.bits & ASTNode.UnnecessaryCast) == 0) {
+			CastExpression.checkNeedForAssignedCast(scope, lhsType, (CastExpression) this.expression);
+		}
+		return this.resolvedType;
+	} else if (isBoxingCompatible(rhsType, lhsType, this.expression, scope)) {
+		this.expression.computeConversion(scope, lhsType, rhsType);
+		if (this.expression instanceof CastExpression
+				&& (this.expression.bits & ASTNode.UnnecessaryCast) == 0) {
+			CastExpression.checkNeedForAssignedCast(scope, lhsType, (CastExpression) this.expression);
+		}
+		return this.resolvedType;
+	}
+	scope.problemReporter().typeMismatchError(rhsType, lhsType, this.expression, this.lhs);
+	return lhsType;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveTypeExpecting(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedType) {
+
+	TypeBinding type = super.resolveTypeExpecting(scope, expectedType);
+	if (type == null) return null;
+	TypeBinding lhsType = this.resolvedType;
+	TypeBinding rhsType = this.expression.resolvedType;
+	// signal possible accidental boolean assignment (instead of using '==' operator)
+	if (expectedType == TypeBinding.BOOLEAN
+			&& lhsType == TypeBinding.BOOLEAN
+			&& (this.lhs.bits & IsStrictlyAssigned) != 0) {
+		scope.problemReporter().possibleAccidentalBooleanAssignment(this);
+	}
+	checkAssignment(scope, lhsType, rhsType);
+	return type;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.lhs.traverse(visitor, scope);
+		this.expression.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+public LocalVariableBinding localVariableBinding() {
+	return this.lhs.localVariableBinding();
+}
+public boolean statementExpression() {
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
new file mode 100644
index 0000000..bcd3077
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
@@ -0,0 +1,1911 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class BinaryExpression extends OperatorExpression {
+
+/* Tracking helpers
+ * The following are used to elaborate realistic statistics about binary
+ * expressions. This must be neutralized in the released code.
+ * Search the keyword BE_INSTRUMENTATION to reenable.
+ * An external device must install a suitable probe so as to monitor the
+ * emission of events and publish the results.
+	public interface Probe {
+		public void ping(int depth);
+	}
+	public int depthTracker;
+	public static Probe probe;
+ */
+
+	public Expression left, right;
+	public Constant optimizedBooleanConstant;
+
+public BinaryExpression(Expression left, Expression right, int operator) {
+	this.left = left;
+	this.right = right;
+	this.bits |= operator << ASTNode.OperatorSHIFT; // encode operator
+	this.sourceStart = left.sourceStart;
+	this.sourceEnd = right.sourceEnd;
+	// BE_INSTRUMENTATION: neutralized in the released code
+//	if (left instanceof BinaryExpression &&
+//			((left.bits & OperatorMASK) ^ (this.bits & OperatorMASK)) == 0) {
+//		this.depthTracker = ((BinaryExpression)left).depthTracker + 1;
+//	} else {
+//		this.depthTracker = 1;
+//	}
+}
+public BinaryExpression(BinaryExpression expression) {
+	this.left = expression.left;
+	this.right = expression.right;
+	this.bits = expression.bits;
+	this.sourceStart = expression.sourceStart;
+	this.sourceEnd = expression.sourceEnd;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// keep implementation in sync with CombinedBinaryExpression#analyseCode
+	try {
+		if (this.resolvedType.id == TypeIds.T_JavaLangString) {
+			return this.right.analyseCode(
+								currentScope, flowContext,
+								this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
+							.unconditionalInits();
+		} else {
+			this.left.checkNPE(currentScope, flowContext, flowInfo);
+			flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+			if (((this.bits & OperatorMASK) >> OperatorSHIFT) != AND) {
+				flowContext.expireNullCheckedFieldInfo();
+			}
+			this.right.checkNPE(currentScope, flowContext, flowInfo);
+			flowInfo = this.right.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+			if (((this.bits & OperatorMASK) >> OperatorSHIFT) != AND) {
+				flowContext.expireNullCheckedFieldInfo();
+			}
+			return flowInfo;
+		}
+	} finally {
+		// account for exception possibly thrown by arithmetics
+		flowContext.recordAbruptExit();
+	}
+}
+
+public void computeConstant(BlockScope scope, int leftId, int rightId) {
+	//compute the constant when valid
+	if ((this.left.constant != Constant.NotAConstant)
+		&& (this.right.constant != Constant.NotAConstant)) {
+		try {
+			this.constant =
+				Constant.computeConstantOperation(
+					this.left.constant,
+					leftId,
+					(this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT,
+					this.right.constant,
+					rightId);
+		} catch (ArithmeticException e) {
+			this.constant = Constant.NotAConstant;
+			// 1.2 no longer throws an exception at compile-time
+			//scope.problemReporter().compileTimeConstantThrowsArithmeticException(this);
+		}
+	} else {
+		this.constant = Constant.NotAConstant;
+		//add some work for the boolean operators & |
+		this.optimizedBooleanConstant(
+			leftId,
+			(this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT,
+			rightId);
+	}
+}
+
+public Constant optimizedBooleanConstant() {
+	return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant;
+}
+
+/**
+ * Code generation for a binary operation
+ */
+// given the current focus of CombinedBinaryExpression on strings concatenation,
+// we do not provide a general, non-recursive implementation of generateCode,
+// but rely upon generateOptimizedStringConcatenationCreation instead
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired)
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
+		case PLUS :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_JavaLangString :
+					// BE_INSTRUMENTATION: neutralized in the released code
+//					if (probe != null) {
+//						probe.ping(this.depthTracker);
+//					}
+					codeStream.generateStringConcatenationAppend(currentScope, this.left, this.right);
+					if (!valueRequired)
+						codeStream.pop();
+					break;
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.iadd();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.ladd();
+					break;
+				case T_double :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.dadd();
+					break;
+				case T_float :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.fadd();
+					break;
+			}
+			break;
+		case MINUS :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.isub();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.lsub();
+					break;
+				case T_double :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.dsub();
+					break;
+				case T_float :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.fsub();
+					break;
+			}
+			break;
+		case MULTIPLY :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.imul();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.lmul();
+					break;
+				case T_double :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.dmul();
+					break;
+				case T_float :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.fmul();
+					break;
+			}
+			break;
+		case DIVIDE :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, true);
+					this.right.generateCode(currentScope, codeStream, true);
+					codeStream.idiv();
+					if (!valueRequired)
+						codeStream.pop();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, true);
+					this.right.generateCode(currentScope, codeStream, true);
+					codeStream.ldiv();
+					if (!valueRequired)
+						codeStream.pop2();
+					break;
+				case T_double :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.ddiv();
+					break;
+				case T_float :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.fdiv();
+					break;
+			}
+			break;
+		case REMAINDER :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, true);
+					this.right.generateCode(currentScope, codeStream, true);
+					codeStream.irem();
+					if (!valueRequired)
+						codeStream.pop();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, true);
+					this.right.generateCode(currentScope, codeStream, true);
+					codeStream.lrem();
+					if (!valueRequired)
+						codeStream.pop2();
+					break;
+				case T_double :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.drem();
+					break;
+				case T_float :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.frem();
+					break;
+			}
+			break;
+		case AND :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					// 0 & x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_int)
+						&& (this.left.constant.intValue() == 0)) {
+						this.right.generateCode(currentScope, codeStream, false);
+						if (valueRequired)
+							codeStream.iconst_0();
+					} else {
+						// x & 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_int)
+							&& (this.right.constant.intValue() == 0)) {
+							this.left.generateCode(currentScope, codeStream, false);
+							if (valueRequired)
+								codeStream.iconst_0();
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.iand();
+						}
+					}
+					break;
+				case T_long :
+					// 0 & x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_long)
+						&& (this.left.constant.longValue() == 0L)) {
+						this.right.generateCode(currentScope, codeStream, false);
+						if (valueRequired)
+							codeStream.lconst_0();
+					} else {
+						// x & 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_long)
+							&& (this.right.constant.longValue() == 0L)) {
+							this.left.generateCode(currentScope, codeStream, false);
+							if (valueRequired)
+								codeStream.lconst_0();
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.land();
+						}
+					}
+					break;
+				case T_boolean : // logical and
+					generateLogicalAnd(currentScope, codeStream, valueRequired);
+					break;
+			}
+			break;
+		case OR :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					// 0 | x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_int)
+						&& (this.left.constant.intValue() == 0)) {
+						this.right.generateCode(currentScope, codeStream, valueRequired);
+					} else {
+						// x | 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_int)
+							&& (this.right.constant.intValue() == 0)) {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.ior();
+						}
+					}
+					break;
+				case T_long :
+					// 0 | x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_long)
+						&& (this.left.constant.longValue() == 0L)) {
+						this.right.generateCode(currentScope, codeStream, valueRequired);
+					} else {
+						// x | 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_long)
+							&& (this.right.constant.longValue() == 0L)) {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.lor();
+						}
+					}
+					break;
+				case T_boolean : // logical or
+					generateLogicalOr(currentScope, codeStream, valueRequired);
+					break;
+			}
+			break;
+		case XOR :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					// 0 ^ x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_int)
+						&& (this.left.constant.intValue() == 0)) {
+						this.right.generateCode(currentScope, codeStream, valueRequired);
+					} else {
+						// x ^ 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_int)
+							&& (this.right.constant.intValue() == 0)) {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.ixor();
+						}
+					}
+					break;
+				case T_long :
+					// 0 ^ x
+					if ((this.left.constant != Constant.NotAConstant)
+						&& (this.left.constant.typeID() == TypeIds.T_long)
+						&& (this.left.constant.longValue() == 0L)) {
+						this.right.generateCode(currentScope, codeStream, valueRequired);
+					} else {
+						// x ^ 0
+						if ((this.right.constant != Constant.NotAConstant)
+							&& (this.right.constant.typeID() == TypeIds.T_long)
+							&& (this.right.constant.longValue() == 0L)) {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+						} else {
+							this.left.generateCode(currentScope, codeStream, valueRequired);
+							this.right.generateCode(currentScope, codeStream, valueRequired);
+							if (valueRequired)
+								codeStream.lxor();
+						}
+					}
+					break;
+				case T_boolean :
+					generateLogicalXor(currentScope, 	codeStream, valueRequired);
+					break;
+			}
+			break;
+		case LEFT_SHIFT :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.ishl();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.lshl();
+			}
+			break;
+		case RIGHT_SHIFT :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.ishr();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.lshr();
+			}
+			break;
+		case UNSIGNED_RIGHT_SHIFT :
+			switch (this.bits & ASTNode.ReturnTypeIDMASK) {
+				case T_int :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.iushr();
+					break;
+				case T_long :
+					this.left.generateCode(currentScope, codeStream, valueRequired);
+					this.right.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired)
+						codeStream.lushr();
+			}
+			break;
+		case GREATER :
+			BranchLabel falseLabel, endLabel;
+			generateOptimizedGreaterThan(
+				currentScope,
+				codeStream,
+				null,
+				(falseLabel = new BranchLabel(codeStream)),
+				valueRequired);
+			if (valueRequired) {
+				codeStream.iconst_1();
+				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					codeStream.goto_(endLabel = new BranchLabel(codeStream));
+					codeStream.decrStackSize(1);
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			}
+			break;
+		case GREATER_EQUAL :
+			generateOptimizedGreaterThanOrEqual(
+				currentScope,
+				codeStream,
+				null,
+				(falseLabel = new BranchLabel(codeStream)),
+				valueRequired);
+			if (valueRequired) {
+				codeStream.iconst_1();
+				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					codeStream.goto_(endLabel = new BranchLabel(codeStream));
+					codeStream.decrStackSize(1);
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			}
+			break;
+		case LESS :
+			generateOptimizedLessThan(
+				currentScope,
+				codeStream,
+				null,
+				(falseLabel = new BranchLabel(codeStream)),
+				valueRequired);
+			if (valueRequired) {
+				codeStream.iconst_1();
+				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					codeStream.goto_(endLabel = new BranchLabel(codeStream));
+					codeStream.decrStackSize(1);
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			}
+			break;
+		case LESS_EQUAL :
+			generateOptimizedLessThanOrEqual(
+				currentScope,
+				codeStream,
+				null,
+				(falseLabel = new BranchLabel(codeStream)),
+				valueRequired);
+			if (valueRequired) {
+				codeStream.iconst_1();
+				if ((this.bits & ASTNode.IsReturnedValue) != 0) {
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					codeStream.goto_(endLabel = new BranchLabel(codeStream));
+					codeStream.decrStackSize(1);
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			}
+	}
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * Boolean operator code generation
+ *	Optimized operations are: <, <=, >, >=, &, |, ^
+ */
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	if ((this.constant != Constant.NotAConstant) && (this.constant.typeID() == TypeIds.T_boolean)) {
+		super.generateOptimizedBoolean(
+			currentScope,
+			codeStream,
+			trueLabel,
+			falseLabel,
+			valueRequired);
+		return;
+	}
+	switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
+		case LESS :
+			generateOptimizedLessThan(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case LESS_EQUAL :
+			generateOptimizedLessThanOrEqual(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case GREATER :
+			generateOptimizedGreaterThan(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case GREATER_EQUAL :
+			generateOptimizedGreaterThanOrEqual(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case AND :
+			generateOptimizedLogicalAnd(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case OR :
+			generateOptimizedLogicalOr(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		case XOR :
+			generateOptimizedLogicalXor(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+	}
+	super.generateOptimizedBoolean(
+		currentScope,
+		codeStream,
+		trueLabel,
+		falseLabel,
+		valueRequired);
+}
+
+/**
+ * Boolean generation for >
+ */
+public void generateOptimizedGreaterThan(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	// both sides got promoted in the same way
+	if (promotedTypeID == TypeIds.T_int) {
+		// 0 > x
+		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.iflt(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifge(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+		// x > 0
+		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
+			this.left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifgt(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifle(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+	}
+	// default comparison
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmpgt(trueLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifgt(trueLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifgt(trueLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifgt(trueLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			}
+		} else {
+			if (trueLabel == null) {
+				// implicit falling through the TRUE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmple(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifle(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifle(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifle(falseLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+}
+
+/**
+ * Boolean generation for >=
+ */
+public void generateOptimizedGreaterThanOrEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	// both sides got promoted in the same way
+	if (promotedTypeID == TypeIds.T_int) {
+		// 0 >= x
+		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifle(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifgt(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+		// x >= 0
+		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
+			this.left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifge(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.iflt(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+	}
+	// default comparison
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmpge(trueLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifge(trueLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifge(trueLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifge(trueLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			}
+		} else {
+			if (trueLabel == null) {
+				// implicit falling through the TRUE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmplt(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.iflt(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.iflt(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.iflt(falseLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+}
+
+/**
+ * Boolean generation for <
+ */
+public void generateOptimizedLessThan(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	// both sides got promoted in the same way
+	if (promotedTypeID == TypeIds.T_int) {
+		// 0 < x
+		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifgt(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifle(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+		// x < 0
+		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
+			this.left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.iflt(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifge(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+	}
+	// default comparison
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmplt(trueLabel);
+						break;
+					case T_float :
+						codeStream.fcmpg();
+						codeStream.iflt(trueLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.iflt(trueLabel);
+						break;
+					case T_double :
+						codeStream.dcmpg();
+						codeStream.iflt(trueLabel);
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			}
+		} else {
+			if (trueLabel == null) {
+				// implicit falling through the TRUE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmpge(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpg();
+						codeStream.ifge(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifge(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpg();
+						codeStream.ifge(falseLabel);
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+}
+
+/**
+ * Boolean generation for <=
+ */
+public void generateOptimizedLessThanOrEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	int promotedTypeID = (this.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	// both sides got promoted in the same way
+	if (promotedTypeID == TypeIds.T_int) {
+		// 0 <= x
+		if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.intValue() == 0)) {
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifge(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.iflt(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+		// x <= 0
+		if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.intValue() == 0)) {
+			this.left.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicitly falling through the FALSE case
+						codeStream.ifle(trueLabel);
+					}
+				} else {
+					if (trueLabel == null) {
+						// implicitly falling through the TRUE case
+						codeStream.ifgt(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			// reposition the endPC
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			return;
+		}
+	}
+	// default comparison
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmple(trueLabel);
+						break;
+					case T_float :
+						codeStream.fcmpg();
+						codeStream.ifle(trueLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifle(trueLabel);
+						break;
+					case T_double :
+						codeStream.dcmpg();
+						codeStream.ifle(trueLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			}
+		} else {
+			if (trueLabel == null) {
+				// implicit falling through the TRUE case
+				switch (promotedTypeID) {
+					case T_int :
+						codeStream.if_icmpgt(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpg();
+						codeStream.ifgt(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifgt(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpg();
+						codeStream.ifgt(falseLabel);
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				return;
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+}
+
+/**
+ * Boolean generation for &
+ */
+public void generateLogicalAnd(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> & x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+			} else {
+				// <something equivalent to false> & x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_0();
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x & <something equivalent to true>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				this.right.generateCode(currentScope, codeStream, false);
+			} else {
+				// x & <something equivalent to false>
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_0();
+				}
+				// reposition the endPC
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.iand();
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+/**
+ * Boolean generation for |
+ */
+public void generateLogicalOr(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> | x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_1();
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			} else {
+				// <something equivalent to false> | x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x | <something equivalent to true>
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_1();
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			} else {
+				// x | <something equivalent to false>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				this.right.generateCode(currentScope, codeStream, false);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.ior();
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+/**
+ * Boolean generation for ^
+ */
+public void generateLogicalXor(BlockScope currentScope,	CodeStream codeStream, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> ^ x
+				this.left.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_1();
+				}
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					codeStream.ixor(); // negate
+					codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				}
+			} else {
+				// <something equivalent to false> ^ x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x ^ <something equivalent to true>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					codeStream.iconst_1();
+					codeStream.ixor(); // negate
+					codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+				}
+			} else {
+				// x ^ <something equivalent to false>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				this.right.generateCode(currentScope, codeStream, false);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.ixor();
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+/**
+ * Boolean generation for &
+ */
+public void generateOptimizedLogicalAnd(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> & x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+			} else {
+				// <something equivalent to false> & x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				if (valueRequired) {
+					if (falseLabel != null) {
+						// implicit falling through the TRUE case
+						codeStream.goto_(falseLabel);
+					}
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x & <something equivalent to true>
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+			} else {
+				// x & <something equivalent to false>
+				BranchLabel internalTrueLabel = new BranchLabel(codeStream);
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					internalTrueLabel,
+					falseLabel,
+					false);
+				internalTrueLabel.place();
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				if (valueRequired) {
+					if (falseLabel != null) {
+						// implicit falling through the TRUE case
+						codeStream.goto_(falseLabel);
+					}
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.iand();
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				codeStream.ifne(trueLabel);
+			}
+		} else {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				codeStream.ifeq(falseLabel);
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+/**
+ * Boolean generation for |
+ */
+public void generateOptimizedLogicalOr(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> | x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				BranchLabel internalFalseLabel = new BranchLabel(codeStream);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					internalFalseLabel,
+					false);
+				internalFalseLabel.place();
+				if (valueRequired) {
+					if (trueLabel != null) {
+						codeStream.goto_(trueLabel);
+					}
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			} else {
+				// <something equivalent to false> | x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x | <something equivalent to true>
+				BranchLabel internalFalseLabel = new BranchLabel(codeStream);
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					internalFalseLabel,
+					false);
+				internalFalseLabel.place();
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				if (valueRequired) {
+					if (trueLabel != null) {
+						codeStream.goto_(trueLabel);
+					}
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+			} else {
+				// x | <something equivalent to false>
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.ior();
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				codeStream.ifne(trueLabel);
+			}
+		} else {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				codeStream.ifeq(falseLabel);
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+/**
+ * Boolean generation for ^
+ */
+public void generateOptimizedLogicalXor(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	Constant condConst;
+	if ((this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK) == TypeIds.T_boolean) {
+		if ((condConst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// <something equivalent to true> ^ x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					falseLabel, // negating
+					trueLabel,
+					valueRequired);
+			} else {
+				// <something equivalent to false> ^ x
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+			}
+			return;
+		}
+		if ((condConst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+			if (condConst.booleanValue() == true) {
+				// x ^ <something equivalent to true>
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					falseLabel, // negating
+					trueLabel,
+					valueRequired);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+			} else {
+				// x ^ <something equivalent to false>
+				this.left.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					valueRequired);
+				this.right.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					trueLabel,
+					falseLabel,
+					false);
+			}
+			return;
+		}
+	}
+	// default case
+	this.left.generateCode(currentScope, codeStream, valueRequired);
+	this.right.generateCode(currentScope, codeStream, valueRequired);
+	if (valueRequired) {
+		codeStream.ixor();
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// implicit falling through the FALSE case
+				codeStream.ifne(trueLabel);
+			}
+		} else {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				codeStream.ifeq(falseLabel);
+			} else {
+				// no implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+}
+
+public void generateOptimizedStringConcatenation(BlockScope blockScope, CodeStream codeStream, int typeID) {
+	// keep implementation in sync with CombinedBinaryExpression
+	// #generateOptimizedStringConcatenation
+	/* In the case trying to make a string concatenation, there is no need to create a new
+	 * string buffer, thus use a lower-level API for code generation involving only the
+	 * appending of arguments to the existing StringBuffer
+	 */
+
+	if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
+		&& ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
+		if (this.constant != Constant.NotAConstant) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+			codeStream.invokeStringConcatenationAppendForType(this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+		} else {
+			int pc = codeStream.position;
+			this.left.generateOptimizedStringConcatenation(
+				blockScope,
+				codeStream,
+				this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.recordPositionsFrom(pc, this.left.sourceStart);
+			pc = codeStream.position;
+			this.right.generateOptimizedStringConcatenation(
+				blockScope,
+				codeStream,
+				this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.recordPositionsFrom(pc, this.right.sourceStart);
+		}
+	} else {
+		super.generateOptimizedStringConcatenation(blockScope, codeStream, typeID);
+	}
+}
+
+public void generateOptimizedStringConcatenationCreation(BlockScope blockScope, CodeStream codeStream, int typeID) {
+	// keep implementation in sync with CombinedBinaryExpression
+	// #generateOptimizedStringConcatenationCreation
+	/* In the case trying to make a string concatenation, there is no need to create a new
+	 * string buffer, thus use a lower-level API for code generation involving only the
+	 * appending of arguments to the existing StringBuffer
+	 */
+	if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS)
+		&& ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
+		if (this.constant != Constant.NotAConstant) {
+			codeStream.newStringContatenation(); // new: java.lang.StringBuffer
+			codeStream.dup();
+			codeStream.ldc(this.constant.stringValue());
+			codeStream.invokeStringConcatenationStringConstructor();
+			// invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
+		} else {
+			int pc = codeStream.position;
+			this.left.generateOptimizedStringConcatenationCreation(
+				blockScope,
+				codeStream,
+				this.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.recordPositionsFrom(pc, this.left.sourceStart);
+			pc = codeStream.position;
+			this.right.generateOptimizedStringConcatenation(
+				blockScope,
+				codeStream,
+				this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.recordPositionsFrom(pc, this.right.sourceStart);
+		}
+	} else {
+		super.generateOptimizedStringConcatenationCreation(blockScope, codeStream, typeID);
+	}
+}
+
+public boolean isCompactableOperation() {
+	return true;
+}
+
+/**
+ * Separates into a reusable method the subpart of {@link
+ * #resolveType(BlockScope)} that needs to be executed while climbing up the
+ * chain of expressions of this' leftmost branch. For use by {@link
+ * CombinedBinaryExpression#resolveType(BlockScope)}.
+ * @param scope the scope within which the resolution occurs
+ */
+void nonRecursiveResolveTypeUpwards(BlockScope scope) {
+	// keep implementation in sync with BinaryExpression#resolveType
+	boolean leftIsCast, rightIsCast;
+	TypeBinding leftType = this.left.resolvedType;
+
+	if ((rightIsCast = this.right instanceof CastExpression) == true) {
+		this.right.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+	}
+	TypeBinding rightType = this.right.resolveType(scope);
+
+	// use the id of the type to navigate into the table
+	if (leftType == null || rightType == null) {
+		this.constant = Constant.NotAConstant;
+		return;
+	}
+
+	int leftTypeID = leftType.id;
+	int rightTypeID = rightType.id;
+
+	// autoboxing support
+	boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+	if (use15specifics) {
+		if (!leftType.isBaseType() && rightTypeID != TypeIds.T_JavaLangString && rightTypeID != TypeIds.T_null) {
+			leftTypeID = scope.environment().computeBoxingType(leftType).id;
+		}
+		if (!rightType.isBaseType() && leftTypeID != TypeIds.T_JavaLangString && leftTypeID != TypeIds.T_null) {
+			rightTypeID = scope.environment().computeBoxingType(rightType).id;
+		}
+	}
+	if (leftTypeID > 15
+		|| rightTypeID > 15) { // must convert String + Object || Object + String
+		if (leftTypeID == TypeIds.T_JavaLangString) {
+			rightTypeID = TypeIds.T_JavaLangObject;
+		} else if (rightTypeID == TypeIds.T_JavaLangString) {
+			leftTypeID = TypeIds.T_JavaLangObject;
+		} else {
+			this.constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, leftType, rightType);
+			return;
+		}
+	}
+	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
+		if (leftTypeID == TypeIds.T_JavaLangString) {
+			this.left.computeConversion(scope, leftType, leftType);
+			if (rightType.isArrayType() && ((ArrayBinding) rightType).elementsType() == TypeBinding.CHAR) {
+				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
+			}
+		}
+		if (rightTypeID == TypeIds.T_JavaLangString) {
+			this.right.computeConversion(scope, rightType, rightType);
+			if (leftType.isArrayType() && ((ArrayBinding) leftType).elementsType() == TypeBinding.CHAR) {
+				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.left);
+			}
+		}
+	}
+
+	// the code is an int
+	// (cast)  left   Op (cast)  right --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       <<0
+
+	// Don't test for result = 0. If it is zero, some more work is done.
+	// On the one hand when it is not zero (correct code) we avoid doing the test
+	int operator = (this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+	int operatorSignature = OperatorExpression.OperatorSignatures[operator][(leftTypeID << 4) + rightTypeID];
+
+	this.left.computeConversion(scope, 	TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), leftType);
+	this.right.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), rightType);
+	this.bits |= operatorSignature & 0xF;
+	switch (operatorSignature & 0xF) { // record the current ReturnTypeID
+		// only switch on possible result type.....
+		case T_boolean :
+			this.resolvedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			this.resolvedType = TypeBinding.BYTE;
+			break;
+		case T_char :
+			this.resolvedType = TypeBinding.CHAR;
+			break;
+		case T_double :
+			this.resolvedType = TypeBinding.DOUBLE;
+			break;
+		case T_float :
+			this.resolvedType = TypeBinding.FLOAT;
+			break;
+		case T_int :
+			this.resolvedType = TypeBinding.INT;
+			break;
+		case T_long :
+			this.resolvedType = TypeBinding.LONG;
+			break;
+		case T_JavaLangString :
+			this.resolvedType = scope.getJavaLangString();
+			break;
+		default : //error........
+			this.constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, leftType, rightType);
+			return;
+	}
+
+	// check need for operand cast
+	if ((leftIsCast = (this.left instanceof CastExpression)) == true ||
+			rightIsCast) {
+		CastExpression.checkNeedForArgumentCasts(scope, operator, operatorSignature, this.left, leftTypeID, leftIsCast, this.right, rightTypeID, rightIsCast);
+	}
+	// compute the constant when valid
+	computeConstant(scope, leftTypeID, rightTypeID);
+}
+
+public void optimizedBooleanConstant(int leftId, int operator, int rightId) {
+	switch (operator) {
+		case AND :
+			if ((leftId != TypeIds.T_boolean) || (rightId != TypeIds.T_boolean))
+				return;
+			//$FALL-THROUGH$
+		case AND_AND :
+			Constant cst;
+			if ((cst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+				if (cst.booleanValue() == false) { // left is equivalent to false
+					this.optimizedBooleanConstant = cst; // constant(false)
+					return;
+				} else { //left is equivalent to true
+					if ((cst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+						this.optimizedBooleanConstant = cst;
+						// the conditional result is equivalent to the right conditional value
+					}
+					return;
+				}
+			}
+			if ((cst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+				if (cst.booleanValue() == false) { // right is equivalent to false
+					this.optimizedBooleanConstant = cst; // constant(false)
+				}
+			}
+			return;
+		case OR :
+			if ((leftId != TypeIds.T_boolean) || (rightId != TypeIds.T_boolean))
+				return;
+			//$FALL-THROUGH$
+		case OR_OR :
+			if ((cst = this.left.optimizedBooleanConstant()) != Constant.NotAConstant) {
+				if (cst.booleanValue() == true) { // left is equivalent to true
+					this.optimizedBooleanConstant = cst; // constant(true)
+					return;
+				} else { //left is equivalent to false
+					if ((cst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+						this.optimizedBooleanConstant = cst;
+					}
+					return;
+				}
+			}
+			if ((cst = this.right.optimizedBooleanConstant()) != Constant.NotAConstant) {
+				if (cst.booleanValue() == true) { // right is equivalent to true
+					this.optimizedBooleanConstant = cst; // constant(true)
+				}
+			}
+	}
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+	// keep implementation in sync with
+	// CombinedBinaryExpression#printExpressionNoParenthesis
+	this.left.printExpression(indent, output).append(' ').append(operatorToString()).append(' ');
+	return this.right.printExpression(0, output);
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// keep implementation in sync with CombinedBinaryExpression#resolveType
+	// and nonRecursiveResolveTypeUpwards
+	boolean leftIsCast, rightIsCast;
+	if ((leftIsCast = this.left instanceof CastExpression) == true) this.left.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+	TypeBinding leftType = this.left.resolveType(scope);
+
+	if ((rightIsCast = this.right instanceof CastExpression) == true) this.right.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+	TypeBinding rightType = this.right.resolveType(scope);
+
+	// use the id of the type to navigate into the table
+	if (leftType == null || rightType == null) {
+		this.constant = Constant.NotAConstant;
+		return null;
+	}
+
+	int leftTypeID = leftType.id;
+	int rightTypeID = rightType.id;
+
+	// autoboxing support
+	boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+	if (use15specifics) {
+		if (!leftType.isBaseType() && rightTypeID != TypeIds.T_JavaLangString && rightTypeID != TypeIds.T_null) {
+			leftTypeID = scope.environment().computeBoxingType(leftType).id;
+		}
+		if (!rightType.isBaseType() && leftTypeID != TypeIds.T_JavaLangString && leftTypeID != TypeIds.T_null) {
+			rightTypeID = scope.environment().computeBoxingType(rightType).id;
+		}
+	}
+	if (leftTypeID > 15
+		|| rightTypeID > 15) { // must convert String + Object || Object + String
+		if (leftTypeID == TypeIds.T_JavaLangString) {
+			rightTypeID = TypeIds.T_JavaLangObject;
+		} else if (rightTypeID == TypeIds.T_JavaLangString) {
+			leftTypeID = TypeIds.T_JavaLangObject;
+		} else {
+			this.constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, leftType, rightType);
+			return null;
+		}
+	}
+	if (((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
+		if (leftTypeID == TypeIds.T_JavaLangString) {
+			this.left.computeConversion(scope, leftType, leftType);
+			if (rightType.isArrayType() && ((ArrayBinding) rightType).elementsType() == TypeBinding.CHAR) {
+				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.right);
+			}
+		}
+		if (rightTypeID == TypeIds.T_JavaLangString) {
+			this.right.computeConversion(scope, rightType, rightType);
+			if (leftType.isArrayType() && ((ArrayBinding) leftType).elementsType() == TypeBinding.CHAR) {
+				scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(this.left);
+			}
+		}
+	}
+
+	// the code is an int
+	// (cast)  left   Op (cast)  right --> result
+	//  0000   0000       0000   0000      0000
+	//  <<16   <<12       <<8    <<4       <<0
+
+	// Don't test for result = 0. If it is zero, some more work is done.
+	// On the one hand when it is not zero (correct code) we avoid doing the test
+	int operator = (this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+	int operatorSignature = OperatorExpression.OperatorSignatures[operator][(leftTypeID << 4) + rightTypeID];
+
+	this.left.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), leftType);
+	this.right.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), rightType);
+	this.bits |= operatorSignature & 0xF;
+	switch (operatorSignature & 0xF) { // record the current ReturnTypeID
+		// only switch on possible result type.....
+		case T_boolean :
+			this.resolvedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			this.resolvedType = TypeBinding.BYTE;
+			break;
+		case T_char :
+			this.resolvedType = TypeBinding.CHAR;
+			break;
+		case T_double :
+			this.resolvedType = TypeBinding.DOUBLE;
+			break;
+		case T_float :
+			this.resolvedType = TypeBinding.FLOAT;
+			break;
+		case T_int :
+			this.resolvedType = TypeBinding.INT;
+			break;
+		case T_long :
+			this.resolvedType = TypeBinding.LONG;
+			break;
+		case T_JavaLangString :
+			this.resolvedType = scope.getJavaLangString();
+			break;
+		default : //error........
+			this.constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, leftType, rightType);
+			return null;
+	}
+
+	// check need for operand cast
+	if (leftIsCast || rightIsCast) {
+		CastExpression.checkNeedForArgumentCasts(scope, operator, operatorSignature, this.left, leftTypeID, leftIsCast, this.right, rightTypeID, rightIsCast);
+	}
+	// compute the constant when valid
+	computeConstant(scope, leftTypeID, rightTypeID);
+	return this.resolvedType;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.left.traverse(visitor, scope);
+		this.right.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
new file mode 100644
index 0000000..e7af82f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class Block extends Statement {
+
+	public Statement[] statements;
+	public int explicitDeclarations;
+	// the number of explicit declaration , used to create scope
+	public BlockScope scope;
+
+public Block(int explicitDeclarations) {
+	this.explicitDeclarations = explicitDeclarations;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// empty block
+	if (this.statements == null)	return flowInfo;
+	int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+	boolean enableSyntacticNullAnalysisForFields = currentScope.compilerOptions().enableSyntacticNullAnalysisForFields;
+	for (int i = 0, max = this.statements.length; i < max; i++) {
+		Statement stat = this.statements[i];
+		if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
+			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
+		}
+		// record the effect of stat on the finally block of an enclosing try-finally, if any:
+		flowContext.mergeFinallyNullInfo(flowInfo);
+		if (enableSyntacticNullAnalysisForFields) {
+			flowContext.expireNullCheckedFieldInfo();
+		}
+	}
+	if (this.explicitDeclarations > 0) {
+		// if block has its own scope analyze tracking vars now:
+		this.scope.checkUnclosedCloseables(flowInfo, flowContext, null, null);
+		// cleanup assignment info for locals that are scoped to this block:
+		LocalVariableBinding[] locals = this.scope.locals;
+		if (locals != null) {
+			int numLocals = this.scope.localIndex;
+			for (int i = 0; i < numLocals; i++) {
+				flowInfo.resetAssignmentInfo(locals[i]);
+			}
+		}
+	}
+	return flowInfo;
+}
+/**
+ * Code generation for a block
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	if (this.statements != null) {
+		for (int i = 0, max = this.statements.length; i < max; i++) {
+			this.statements[i].generateCode(this.scope, codeStream);
+		}
+	} // for local variable debug attributes
+	if (this.scope != currentScope) { // was really associated with its own scope
+		codeStream.exitUserScope(this.scope);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public boolean isEmptyBlock() {
+	return this.statements == null;
+}
+
+public StringBuffer printBody(int indent, StringBuffer output) {
+	if (this.statements == null) return output;
+	for (int i = 0; i < this.statements.length; i++) {
+		this.statements[i].printStatement(indent + 1, output);
+		output.append('\n');
+	}
+	return output;
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	printIndent(indent, output);
+	output.append("{\n"); //$NON-NLS-1$
+	printBody(indent, output);
+	return printIndent(indent, output).append('}');
+}
+
+public void resolve(BlockScope upperScope) {
+	if ((this.bits & UndocumentedEmptyBlock) != 0) {
+		upperScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
+	}
+	if (this.statements != null) {
+		this.scope =
+			this.explicitDeclarations == 0
+				? upperScope
+				: new BlockScope(upperScope, this.explicitDeclarations);
+		for (int i = 0, length = this.statements.length; i < length; i++) {
+			this.statements[i].resolve(this.scope);
+		}
+	}
+}
+
+public void resolveUsing(BlockScope givenScope) {
+	if ((this.bits & UndocumentedEmptyBlock) != 0) {
+		givenScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
+	}
+	// this optimized resolve(...) is sent only on none empty blocks
+	this.scope = givenScope;
+	if (this.statements != null) {
+		for (int i = 0, length = this.statements.length; i < length; i++) {
+			this.statements[i].resolve(this.scope);
+		}
+	}
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		if (this.statements != null) {
+			for (int i = 0, length = this.statements.length; i < length; i++)
+				this.statements[i].traverse(visitor, this.scope);
+		}
+	}
+	visitor.endVisit(this, blockScope);
+}
+
+/**
+ * Dispatch the call on its last statement.
+ */
+public void branchChainTo(BranchLabel label) {
+	if (this.statements != null) {
+		this.statements[this.statements.length - 1].branchChainTo(label);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
new file mode 100644
index 0000000..6273515
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class BranchStatement extends Statement {
+
+	public char[] label;
+	public BranchLabel targetLabel;
+	public SubRoutineStatement[] subroutines;
+	public int initStateIndex = -1;
+
+/**
+ * BranchStatement constructor comment.
+ */
+public BranchStatement(char[] label, int sourceStart,int sourceEnd) {
+	this.label = label ;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+/**
+ * Branch code generation
+ *
+ *   generate the finallyInvocationSequence.
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	// generation of code responsible for invoking the finally
+	// blocks in sequence
+	if (this.subroutines != null){
+		for (int i = 0, max = this.subroutines.length; i < max; i++){
+			SubRoutineStatement sub = this.subroutines[i];
+			boolean didEscape = sub.generateSubRoutineInvocation(currentScope, codeStream, this.targetLabel, this.initStateIndex, null);
+			if (didEscape) {
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, i, codeStream);
+					if (this.initStateIndex != -1) {
+						codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+						codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+					}
+					return;
+			}
+		}
+	}
+	codeStream.goto_(this.targetLabel);
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+	SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream);
+	if (this.initStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+		codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+	}
+}
+
+public void resolve(BlockScope scope) {
+	// nothing to do during name resolution
+}
+}
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
new file mode 100644
index 0000000..79f2eb0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class BreakStatement extends BranchStatement {
+
+public BreakStatement(char[] label, int sourceStart, int e) {
+	super(label, sourceStart, e);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// here requires to generate a sequence of finally blocks invocations depending corresponding
+	// to each of the traversed try statements, so that execution will terminate properly.
+
+	// lookup the label, this should answer the returnContext
+	FlowContext targetContext = (this.label == null)
+		? flowContext.getTargetContextForDefaultBreak()
+		: flowContext.getTargetContextForBreakLabel(this.label);
+
+	if (targetContext == null) {
+		if (this.label == null) {
+			currentScope.problemReporter().invalidBreak(this);
+		} else {
+			currentScope.problemReporter().undefinedLabel(this);
+		}
+		return flowInfo; // pretend it did not break since no actual target
+	}
+
+	targetContext.recordAbruptExit();
+
+	this.initStateIndex =
+		currentScope.methodScope().recordInitializationStates(flowInfo);
+
+	this.targetLabel = targetContext.breakLabel();
+	FlowContext traversedContext = flowContext;
+	int subCount = 0;
+	this.subroutines = new SubRoutineStatement[5];
+
+	do {
+		SubRoutineStatement sub;
+		if ((sub = traversedContext.subroutine()) != null) {
+			if (subCount == this.subroutines.length) {
+				System.arraycopy(this.subroutines, 0, (this.subroutines = new SubRoutineStatement[subCount*2]), 0, subCount); // grow
+			}
+			this.subroutines[subCount++] = sub;
+			if (sub.isSubRoutineEscaping()) {
+				break;
+			}
+		}
+		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
+		traversedContext.recordBreakTo(targetContext);
+
+		if (traversedContext instanceof InsideSubRoutineFlowContext) {
+			ASTNode node = traversedContext.associatedNode;
+			if (node instanceof TryStatement) {
+				TryStatement tryStatement = (TryStatement) node;
+				flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
+			}
+		} else if (traversedContext == targetContext) {
+			// only record break info once accumulated through subroutines, and only against target context
+			targetContext.recordBreakFrom(flowInfo);
+			break;
+		}
+	} while ((traversedContext = traversedContext.getLocalParent()) != null);
+
+	// resize subroutines
+	if (subCount != this.subroutines.length) {
+		System.arraycopy(this.subroutines, 0, (this.subroutines = new SubRoutineStatement[subCount]), 0, subCount);
+	}
+	return FlowInfo.DEAD_END;
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	printIndent(tab, output).append("break"); //$NON-NLS-1$
+	if (this.label != null) output.append(' ').append(this.label);
+	return output.append(';');
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockscope) {
+	visitor.visit(this, blockscope);
+	visitor.endVisit(this, blockscope);
+}
+}
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
new file mode 100644
index 0000000..13b2789
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IntConstant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CaseStatement extends Statement {
+
+	public Expression constantExpression;
+	public BranchLabel targetLabel;
+
+public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
+	this.constantExpression = constantExpression;
+	this.sourceEnd = sourceEnd;
+	this.sourceStart = sourceStart;
+}
+
+public FlowInfo analyseCode(
+	BlockScope currentScope,
+	FlowContext flowContext,
+	FlowInfo flowInfo) {
+
+	if (this.constantExpression != null) {
+		if (this.constantExpression.constant == Constant.NotAConstant
+				&& !this.constantExpression.resolvedType.isEnum()) {
+			currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression);
+		}
+		this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
+	}
+	return flowInfo;
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	printIndent(tab, output);
+	if (this.constantExpression == null) {
+		output.append("default :"); //$NON-NLS-1$
+	} else {
+		output.append("case "); //$NON-NLS-1$
+		this.constantExpression.printExpression(0, output).append(" :"); //$NON-NLS-1$
+	}
+	return output;
+}
+
+/**
+ * Case code generation
+ *
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	this.targetLabel.place();
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * No-op : should use resolveCase(...) instead.
+ */
+public void resolve(BlockScope scope) {
+	// no-op : should use resolveCase(...) instead.
+}
+
+/**
+ * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE
+ * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement)
+ */
+public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) {
+	// switchExpressionType maybe null in error case
+	scope.enclosingCase = this; // record entering in a switch case block
+
+	if (this.constantExpression == null) {
+		// remember the default case into the associated switch statement
+		if (switchStatement.defaultCase != null)
+			scope.problemReporter().duplicateDefaultCase(this);
+
+		// on error the last default will be the selected one ...
+		switchStatement.defaultCase = this;
+		return Constant.NotAConstant;
+	}
+	// add into the collection of cases of the associated switch statement
+	switchStatement.cases[switchStatement.caseCount++] = this;
+	// tag constant name with enum type for privileged access to its members
+	if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) {
+		((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType);
+	}
+	TypeBinding caseType = this.constantExpression.resolveType(scope);
+	if (caseType == null || switchExpressionType == null) return Constant.NotAConstant;
+	if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType)
+			|| caseType.isCompatibleWith(switchExpressionType)) {
+		if (caseType.isEnum()) {
+			if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+				scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression);
+			}
+
+			if (this.constantExpression instanceof NameReference
+					&& (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) {
+				NameReference reference = (NameReference) this.constantExpression;
+				FieldBinding field = reference.fieldBinding();
+				if ((field.modifiers & ClassFileConstants.AccEnum) == 0) {
+					 scope.problemReporter().enumSwitchCannotTargetField(reference, field);
+				} else 	if (reference instanceof QualifiedNameReference) {
+					 scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field);
+				}
+				return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810
+			}
+		} else {
+			return this.constantExpression.constant;
+		}
+	} else if (isBoxingCompatible(caseType, switchExpressionType, this.constantExpression, scope)) {
+		// constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion
+		return this.constantExpression.constant;
+	}
+	scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression, switchStatement.expression);
+	return Constant.NotAConstant;
+}
+
+public void traverse(ASTVisitor visitor, 	BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
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
new file mode 100644
index 0000000..279aa96
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -0,0 +1,608 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 401017 - [compiler][null] casted reference to @Nullable field lacks a warning
+ *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+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.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class CastExpression extends Expression {
+
+	public Expression expression;
+	public TypeReference type;
+	public TypeBinding expectedType; // when assignment conversion to a given expected type: String s = (String) t;
+
+//expression.implicitConversion holds the cast for baseType casting
+public CastExpression(Expression expression, TypeReference type) {
+	this.expression = expression;
+	this.type = type;
+	type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	FlowInfo result = this.expression
+		.analyseCode(currentScope, flowContext, flowInfo)
+		.unconditionalInits();
+	this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	// account for pot. CCE:
+	flowContext.recordAbruptExit();
+	return result;
+}
+
+/**
+ * Complain if assigned expression is cast, but not actually used as such, e.g. Object o = (List) object;
+ */
+public static void checkNeedForAssignedCast(BlockScope scope, TypeBinding expectedType, CastExpression rhs) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	TypeBinding castedExpressionType = rhs.expression.resolvedType;
+	//	int i = (byte) n; // cast still had side effect
+	// double d = (float) n; // cast to float is unnecessary
+	if (castedExpressionType == null || rhs.resolvedType.isBaseType()) return;
+	//if (castedExpressionType.id == T_null) return; // tolerate null expression cast
+	if (castedExpressionType.isCompatibleWith(expectedType, scope)) {
+		scope.problemReporter().unnecessaryCast(rhs);
+	}
+}
+
+
+/**
+ * Complain if cast expression is cast, but not actually needed, int i = (int)(Integer) 12;
+ * Note that this (int) cast is however needed:   Integer i = 0;  char c = (char)((int) i);
+ */
+public static void checkNeedForCastCast(BlockScope scope, CastExpression enclosingCast) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	CastExpression nestedCast = (CastExpression) enclosingCast.expression;
+	if ((nestedCast.bits & ASTNode.UnnecessaryCast) == 0) return;
+	// check if could cast directly to enclosing cast type, without intermediate type cast
+	CastExpression alternateCast = new CastExpression(null, enclosingCast.type);
+	alternateCast.resolvedType = enclosingCast.resolvedType;
+	if (!alternateCast.checkCastTypesCompatibility(scope, enclosingCast.resolvedType, nestedCast.expression.resolvedType, null /* no expr to avoid side-effects*/)) return;
+	scope.problemReporter().unnecessaryCast(nestedCast);
+}
+
+
+/**
+ * Casting an enclosing instance will considered as useful if removing it would actually bind to a different type
+ */
+public static void checkNeedForEnclosingInstanceCast(BlockScope scope, Expression enclosingInstance, TypeBinding enclosingInstanceType, TypeBinding memberType) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	TypeBinding castedExpressionType = ((CastExpression)enclosingInstance).expression.resolvedType;
+	if (castedExpressionType == null) return; // cannot do better
+	// obvious identity cast
+	if (castedExpressionType == enclosingInstanceType) {
+		scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance);
+	} else if (castedExpressionType == TypeBinding.NULL){
+		return; // tolerate null enclosing instance cast
+	} else {
+		TypeBinding alternateEnclosingInstanceType = castedExpressionType;
+		if (castedExpressionType.isBaseType() || castedExpressionType.isArrayType()) return; // error case
+		if (memberType == scope.getMemberType(memberType.sourceName(), (ReferenceBinding) alternateEnclosingInstanceType)) {
+			scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance);
+		}
+	}
+}
+
+/**
+ * Only complain for identity cast, since other type of casts may be useful: e.g.  ~((~(long) 0) << 32)  is different from: ~((~0) << 32)
+ */
+public static void checkNeedForArgumentCast(BlockScope scope, int operator, int operatorSignature, Expression expression, int expressionTypeId) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	// check need for left operand cast
+	if ((expression.bits & ASTNode.UnnecessaryCast) == 0 && expression.resolvedType.isBaseType()) {
+		// narrowing conversion on base type may change value, thus necessary
+		return;
+	} else {
+		TypeBinding alternateLeftType = ((CastExpression)expression).expression.resolvedType;
+		if (alternateLeftType == null) return; // cannot do better
+		if (alternateLeftType.id == expressionTypeId) { // obvious identity cast
+			scope.problemReporter().unnecessaryCast((CastExpression)expression);
+			return;
+		}
+	}
+}
+
+/**
+ * Cast expressions will considered as useful if removing them all would actually bind to a different method
+ * (no fine grain analysis on per casted argument basis, simply separate widening cast from narrowing ones)
+ */
+public static void checkNeedForArgumentCasts(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding binding, Expression[] arguments, TypeBinding[] argumentTypes, final InvocationSite invocationSite) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	int length = argumentTypes.length;
+
+	// iterate over arguments, and retrieve original argument types (before cast)
+	TypeBinding[] rawArgumentTypes = argumentTypes;
+	for (int i = 0; i < length; i++) {
+		Expression argument = arguments[i];
+		if (argument instanceof CastExpression) {
+			// narrowing conversion on base type may change value, thus necessary
+			if ((argument.bits & ASTNode.UnnecessaryCast) == 0 && argument.resolvedType.isBaseType()) {
+				continue;
+			}
+			TypeBinding castedExpressionType = ((CastExpression)argument).expression.resolvedType;
+			if (castedExpressionType == null) return; // cannot do better
+			// obvious identity cast
+			if (castedExpressionType == argumentTypes[i]) {
+				scope.problemReporter().unnecessaryCast((CastExpression)argument);
+			} else if (castedExpressionType == TypeBinding.NULL){
+				continue; // tolerate null argument cast
+			} else if ((argument.implicitConversion & TypeIds.BOXING) != 0) {
+				continue; // boxing has a side effect: (int) char   is not boxed as simple char
+			} else {
+				if (rawArgumentTypes == argumentTypes) {
+					System.arraycopy(rawArgumentTypes, 0, rawArgumentTypes = new TypeBinding[length], 0, length);
+				}
+				// retain original argument type
+				rawArgumentTypes[i] = castedExpressionType;
+			}
+		}
+	}
+	// perform alternate lookup with original types
+	if (rawArgumentTypes != argumentTypes) {
+		checkAlternateBinding(scope, receiver, receiverType, binding, arguments, argumentTypes, rawArgumentTypes, invocationSite);
+	}
+}
+
+/**
+ * Check binary operator casted arguments
+ */
+public static void checkNeedForArgumentCasts(BlockScope scope, int operator, int operatorSignature, Expression left, int leftTypeId, boolean leftIsCast, Expression right, int rightTypeId, boolean rightIsCast) {
+	if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+
+	// check need for left operand cast
+	int alternateLeftTypeId = leftTypeId;
+	if (leftIsCast) {
+		if ((left.bits & ASTNode.UnnecessaryCast) == 0 && left.resolvedType.isBaseType()) {
+			// narrowing conversion on base type may change value, thus necessary
+			leftIsCast = false;
+		} else  {
+			TypeBinding alternateLeftType = ((CastExpression)left).expression.resolvedType;
+			if (alternateLeftType == null) return; // cannot do better
+			if ((alternateLeftTypeId = alternateLeftType.id) == leftTypeId || scope.environment().computeBoxingType(alternateLeftType).id == leftTypeId) { // obvious identity cast
+				scope.problemReporter().unnecessaryCast((CastExpression)left);
+				leftIsCast = false;
+			} else if (alternateLeftTypeId == TypeIds.T_null) {
+				alternateLeftTypeId = leftTypeId;  // tolerate null argument cast
+				leftIsCast = false;
+			}
+		}
+	}
+	// check need for right operand cast
+	int alternateRightTypeId = rightTypeId;
+	if (rightIsCast) {
+		if ((right.bits & ASTNode.UnnecessaryCast) == 0 && right.resolvedType.isBaseType()) {
+			// narrowing conversion on base type may change value, thus necessary
+			rightIsCast = false;
+		} else {
+			TypeBinding alternateRightType = ((CastExpression)right).expression.resolvedType;
+			if (alternateRightType == null) return; // cannot do better
+			if ((alternateRightTypeId = alternateRightType.id) == rightTypeId || scope.environment().computeBoxingType(alternateRightType).id == rightTypeId) { // obvious identity cast
+				scope.problemReporter().unnecessaryCast((CastExpression)right);
+				rightIsCast = false;
+			} else if (alternateRightTypeId == TypeIds.T_null) {
+				alternateRightTypeId = rightTypeId;  // tolerate null argument cast
+				rightIsCast = false;
+			}
+		}
+	}
+	if (leftIsCast || rightIsCast) {
+		if (alternateLeftTypeId > 15 || alternateRightTypeId > 15) { // must convert String + Object || Object + String
+			if (alternateLeftTypeId == TypeIds.T_JavaLangString) {
+				alternateRightTypeId = TypeIds.T_JavaLangObject;
+			} else if (alternateRightTypeId == TypeIds.T_JavaLangString) {
+				alternateLeftTypeId = TypeIds.T_JavaLangObject;
+			} else {
+				return; // invalid operator
+			}
+		}
+		int alternateOperatorSignature = OperatorExpression.OperatorSignatures[operator][(alternateLeftTypeId << 4) + alternateRightTypeId];
+		// (cast)  left   Op (cast)  right --> result
+		//  1111   0000       1111   0000     1111
+		//  <<16   <<12       <<8    <<4       <<0
+		final int CompareMASK = (0xF<<16) + (0xF<<8) + 0xF; // mask hiding compile-time types
+		if ((operatorSignature & CompareMASK) == (alternateOperatorSignature & CompareMASK)) { // same promotions and result
+			if (leftIsCast) scope.problemReporter().unnecessaryCast((CastExpression)left);
+			if (rightIsCast) scope.problemReporter().unnecessaryCast((CastExpression)right);
+		}
+	}
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	checkNPEbyUnboxing(scope, flowContext, flowInfo);
+	return this.expression.checkNPE(scope, flowContext, flowInfo);
+}
+
+private static void checkAlternateBinding(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding binding, Expression[] arguments, TypeBinding[] originalArgumentTypes, TypeBinding[] alternateArgumentTypes, final InvocationSite invocationSite) {
+		InvocationSite fakeInvocationSite = new InvocationSite(){
+			public TypeBinding[] genericTypeArguments() { return null; }
+			public boolean isSuperAccess(){ return invocationSite.isSuperAccess(); }
+			public boolean isTypeAccess() { return invocationSite.isTypeAccess(); }
+			public void setActualReceiverType(ReferenceBinding actualReceiverType) { /* ignore */}
+			public void setDepth(int depth) { /* ignore */}
+			public void setFieldIndex(int depth){ /* ignore */}
+			public int sourceStart() { return 0; }
+			public int sourceEnd() { return 0; }
+			public TypeBinding expectedType() { return invocationSite.expectedType(); }
+			public boolean receiverIsImplicitThis() { return invocationSite.receiverIsImplicitThis();}
+		};
+		MethodBinding bindingIfNoCast;
+		if (binding.isConstructor()) {
+			bindingIfNoCast = scope.getConstructor((ReferenceBinding)receiverType, alternateArgumentTypes, fakeInvocationSite);
+		} else {
+			bindingIfNoCast = receiver.isImplicitThis()
+				? scope.getImplicitMethod(binding.selector, alternateArgumentTypes, fakeInvocationSite)
+				: scope.getMethod(receiverType, binding.selector, alternateArgumentTypes, fakeInvocationSite);
+		}
+		if (bindingIfNoCast == binding) {
+			int argumentLength = originalArgumentTypes.length;
+			if (binding.isVarargs()) {
+				int paramLength = binding.parameters.length;
+				if (paramLength == argumentLength) {
+					int varargsIndex = paramLength - 1;
+					ArrayBinding varargsType = (ArrayBinding) binding.parameters[varargsIndex];
+					TypeBinding lastArgType = alternateArgumentTypes[varargsIndex];
+					// originalType may be compatible already, but cast mandated
+					// to clarify between varargs/non-varargs call
+					if (varargsType.dimensions != lastArgType.dimensions()) {
+						return;
+					}
+					if (lastArgType.isCompatibleWith(varargsType.elementsType())
+							&& lastArgType.isCompatibleWith(varargsType)) {
+						return;
+					}
+				}
+			}
+			for (int i = 0; i < argumentLength; i++) {
+				if (originalArgumentTypes[i] != alternateArgumentTypes[i]
+                       /*&& !originalArgumentTypes[i].needsUncheckedConversion(alternateArgumentTypes[i])*/) {
+					scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
+				}
+			}
+		}
+}
+
+public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
+	if (match == castType) {
+		if (!isNarrowing && match == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
+			tagAsUnnecessaryCast(scope, castType);
+		}
+		return true;
+	}
+	if (match != null) {
+		if (isNarrowing
+				? match.isProvablyDistinct(expressionType)
+				: castType.isProvablyDistinct(match)) {
+			return false;
+		}
+	}
+	switch (castType.kind()) {
+		case Binding.PARAMETERIZED_TYPE :
+			if (!castType.isReifiable()) {
+				if (match == null) { // unrelated types
+					this.bits |= ASTNode.UnsafeCast;
+					return true;
+				}
+				switch (match.kind()) {
+					case Binding.PARAMETERIZED_TYPE :
+						if (isNarrowing) {
+							// [JLS 5.5] T <: S
+							if (expressionType.isRawType() || !expressionType.isEquivalentTo(match)) {
+								this.bits |= ASTNode.UnsafeCast;
+								return true;
+							}
+							// [JLS 5.5] S has no subtype X != T, such that |X| == |T|
+							// if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked
+							ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType;
+							ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match;
+							// easy case if less parameters on match
+							TypeBinding[] castArguments = paramCastType.arguments;
+							int length = castArguments == null ? 0 : castArguments.length;
+							if (paramMatch.arguments == null || length > paramMatch.arguments.length) {
+								this.bits |= ASTNode.UnsafeCast;
+							} else if ((paramCastType.tagBits & (TagBits.HasDirectWildcard|TagBits.HasTypeVariable)) != 0) {
+								// verify alternate cast type, substituting different type arguments
+								nextAlternateArgument: for (int i = 0; i < length; i++) {
+									switch (castArguments[i].kind()) {
+										case Binding.WILDCARD_TYPE :
+										case Binding.TYPE_PARAMETER :
+											break; // check substituting with other
+										default:
+											continue nextAlternateArgument; // no alternative possible
+									}
+									TypeBinding[] alternateArguments;
+									// need to clone for each iteration to avoid env paramtype cache interference
+									System.arraycopy(paramCastType.arguments, 0, alternateArguments = new TypeBinding[length], 0, length);
+									alternateArguments[i] = scope.getJavaLangObject();
+									LookupEnvironment environment = scope.environment();
+									ParameterizedTypeBinding alternateCastType = environment.createParameterizedType((ReferenceBinding)castType.erasure(), alternateArguments, castType.enclosingType());
+									if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
+										this.bits |= ASTNode.UnsafeCast;
+										break;
+									}
+								}
+							}
+							return true;
+						} else {
+							// [JLS 5.5] T >: S
+							if (!match.isEquivalentTo(castType)) {
+								this.bits |= ASTNode.UnsafeCast;
+								return true;
+							}
+						}
+						break;
+					case Binding.RAW_TYPE :
+						this.bits |= ASTNode.UnsafeCast; // upcast since castType is known to be bound paramType
+						return true;
+					default :
+						if (isNarrowing){
+							// match is not parameterized or raw, then any other subtype of match will erase  to |T|
+							this.bits |= ASTNode.UnsafeCast;
+							return true;
+						}
+						break;
+				}
+			}
+			break;
+		case Binding.ARRAY_TYPE :
+			TypeBinding leafType = castType.leafComponentType();
+			if (isNarrowing && (!leafType.isReifiable() || leafType.isTypeVariable())) {
+				this.bits |= ASTNode.UnsafeCast;
+				return true;
+			}
+			break;
+		case Binding.TYPE_PARAMETER :
+			this.bits |= ASTNode.UnsafeCast;
+			return true;
+//		(disabled) https://bugs.eclipse.org/bugs/show_bug.cgi?id=240807			
+//		case Binding.TYPE :
+//			if (isNarrowing && match == null && expressionType.isParameterizedType()) {
+//				this.bits |= ASTNode.UnsafeCast;
+//				return true;
+//			}
+//			break;
+	}
+	if (!isNarrowing && match == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
+		tagAsUnnecessaryCast(scope, castType);
+	}
+	return true;
+}
+
+/**
+ * Cast expression code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	boolean needRuntimeCheckcast = (this.bits & ASTNode.GenerateCheckcast) != 0;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired || needRuntimeCheckcast) { // Added for: 1F1W9IG: IVJCOM:WINNT - Compiler omits casting check
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+			if (needRuntimeCheckcast) {
+				codeStream.checkcast(this.type, this.resolvedType);
+			}
+			if (!valueRequired) {
+				// the resolveType cannot be double or long
+				codeStream.pop();
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	this.expression.generateCode(currentScope, codeStream, valueRequired || needRuntimeCheckcast);
+	if (needRuntimeCheckcast && this.expression.postConversionType(currentScope) != this.resolvedType.erasure()) { // no need to issue a checkcast if already done as genericCast
+		codeStream.checkcast(this.type, this.resolvedType);
+	}
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else if (needRuntimeCheckcast) {
+		codeStream.pop();
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public Expression innermostCastedExpression(){
+	Expression current = this.expression;
+	while (current instanceof CastExpression) {
+		current = ((CastExpression) current).expression;
+	}
+	return current;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#localVariableBinding()
+ */
+public LocalVariableBinding localVariableBinding() {
+	return this.expression.localVariableBinding();
+}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	return this.expression.nullStatus(flowInfo, flowContext);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#optimizedBooleanConstant()
+ */
+public Constant optimizedBooleanConstant() {
+	switch(this.resolvedType.id) {
+		case T_boolean :
+		case T_JavaLangBoolean :
+			return this.expression.optimizedBooleanConstant();
+	}
+	return Constant.NotAConstant;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	int parenthesesCount = (this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+	String suffix = ""; //$NON-NLS-1$
+	for(int i = 0; i < parenthesesCount; i++) {
+		output.append('(');
+		suffix += ')';
+	}
+	output.append('(');
+	this.type.print(0, output).append(") "); //$NON-NLS-1$
+	return this.expression.printExpression(0, output).append(suffix);
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// compute a new constant if the cast is effective
+
+	this.constant = Constant.NotAConstant;
+	this.implicitConversion = TypeIds.T_undefined;
+
+	boolean exprContainCast = false;
+
+	TypeBinding castType = this.resolvedType = this.type.resolveType(scope);
+	if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
+		this.expression.setExpressionContext(CASTING_CONTEXT);
+		if (this.expression instanceof FunctionalExpression) {
+			this.expression.setExpectedType(this.resolvedType);
+			this.bits |= ASTNode.DisableUnnecessaryCastCheck;
+		}
+	}
+	if (this.expression instanceof CastExpression) {
+		this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
+		exprContainCast = true;
+	}
+	TypeBinding expressionType = this.expression.resolveType(scope);
+	if (this.expression instanceof MessageSend) {
+		MessageSend messageSend = (MessageSend) this.expression;
+		MethodBinding methodBinding = messageSend.binding;
+		if (methodBinding != null && methodBinding.isPolymorphic()) {
+			messageSend.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) methodBinding, castType);
+			if (expressionType != castType) {
+				expressionType = castType;
+				this.bits |= ASTNode.DisableUnnecessaryCastCheck;
+			}
+		}
+	}
+	if (castType != null) {
+		if (expressionType != null) {
+			boolean isLegal = checkCastTypesCompatibility(scope, castType, expressionType, this.expression);
+			if (isLegal) {
+				this.expression.computeConversion(scope, castType, expressionType);
+				if ((this.bits & ASTNode.UnsafeCast) != 0) { // unsafe cast
+					if (scope.compilerOptions().reportUnavoidableGenericTypeProblems || !this.expression.forcedToBeRaw(scope.referenceContext())) {
+						scope.problemReporter().unsafeCast(this, scope);
+					}
+				} else {
+					if (castType.isRawType() && scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore){
+						scope.problemReporter().rawTypeReference(this.type, castType);
+					}
+					if ((this.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == ASTNode.UnnecessaryCast) { // unnecessary cast
+						if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
+							scope.problemReporter().unnecessaryCast(this);
+					}
+				}
+			} else { // illegal cast
+				if ((castType.tagBits & TagBits.HasMissingType) == 0) { // no complaint if secondary error
+					scope.problemReporter().typeCastError(this, castType, expressionType);
+				}
+				this.bits |= ASTNode.DisableUnnecessaryCastCheck; // disable further secondary diagnosis
+			}
+		}
+		this.resolvedType = castType.capture(scope, this.sourceEnd);
+		if (exprContainCast) {
+			checkNeedForCastCast(scope, this);
+		}
+	}
+	return this.resolvedType;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void setExpectedType(TypeBinding expectedType) {
+	this.expectedType = expectedType;
+}
+
+/**
+ * Determines whether apparent unnecessary cast wasn't actually used to
+ * perform return type inference of generic method invocation or boxing.
+ */
+private boolean isIndirectlyUsed() {
+	if (this.expression instanceof MessageSend) {
+		MethodBinding method = ((MessageSend)this.expression).binding;
+		if (method instanceof ParameterizedGenericMethodBinding
+					&& ((ParameterizedGenericMethodBinding)method).inferredReturnType) {
+			if (this.expectedType == null)
+				return true;
+			if (this.resolvedType != this.expectedType)
+				return true;
+		}
+	}
+	if (this.expectedType != null && this.resolvedType.isBaseType() && !this.resolvedType.isCompatibleWith(this.expectedType)) {
+		// boxing: Short s = (short) _byte
+		return true;
+	}
+	return false;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsNeedCheckCast()
+ */
+public void tagAsNeedCheckCast() {
+	this.bits |= ASTNode.GenerateCheckcast;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope, TypeBinding)
+ */
+public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
+	this.bits |= ASTNode.UnnecessaryCast;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		this.type.traverse(visitor, blockScope);
+		this.expression.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java
new file mode 100644
index 0000000..cd5f124
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+public class CharLiteral extends NumberLiteral {
+	
+	char value;
+	
+public CharLiteral(char[] token, int s, int e) {
+	super(token, s, e);
+	computeValue();
+}
+
+public void computeConstant() {
+	//The source is a  char[3] first and last char are '
+	//This is true for both regular char AND unicode char
+	//BUT not for escape char like '\b' which are char[4]....
+	this.constant = CharConstant.fromValue(this.value);
+}
+
+private void computeValue() {
+	//The source is a  char[3] first and last char are '
+	//This is true for both regular char AND unicode char
+	//BUT not for escape char like '\b' which are char[4]....
+	if ((this.value = this.source[1]) != '\\')
+		return;
+	char digit;
+	switch (digit = this.source[2]) {
+		case 'b' :
+			this.value = '\b';
+			break;
+		case 't' :
+			this.value = '\t';
+			break;
+		case 'n' :
+			this.value = '\n';
+			break;
+		case 'f' :
+			this.value = '\f';
+			break;
+		case 'r' :
+			this.value = '\r';
+			break;
+		case '\"' :
+			this.value = '\"';
+			break;
+		case '\'' :
+			this.value = '\'';
+			break;
+		case '\\' :
+			this.value = '\\';
+			break;
+		default : //octal (well-formed: ended by a ' )
+			int number = ScannerHelper.getNumericValue(digit);
+			if ((digit = this.source[3]) != '\'')
+				number = (number * 8) + ScannerHelper.getNumericValue(digit);
+			else {
+				this.constant = CharConstant.fromValue(this.value = (char) number);
+				break;
+			}
+			if ((digit = this.source[4]) != '\'')
+				number = (number * 8) + ScannerHelper.getNumericValue(digit);
+			this.value = (char) number;
+			break;
+	}
+}
+
+/**
+ * CharLiteral code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.CHAR;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	visitor.visit(this, blockScope);
+	visitor.endVisit(this, blockScope);
+}
+}
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
new file mode 100644
index 0000000..eefb1c2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ClassLiteralAccess extends Expression {
+
+	public TypeReference type;
+	public TypeBinding targetType;
+	FieldBinding syntheticField;
+
+	public ClassLiteralAccess(int sourceEnd, TypeReference type) {
+		this.type = type;
+		type.bits |= IgnoreRawTypeCheck; // no need to worry about raw type usage
+		this.sourceStart = type.sourceStart;
+		this.sourceEnd = sourceEnd;
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		// if reachable, request the addition of a synthetic field for caching the class descriptor
+		SourceTypeBinding sourceType = currentScope.outerMostClassScope().enclosingSourceType();
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=22334
+		if (!sourceType.isInterface()
+				&& !this.targetType.isBaseType()
+				&& currentScope.compilerOptions().targetJDK < ClassFileConstants.JDK1_5) {
+			this.syntheticField = sourceType.addSyntheticFieldForClassLiteral(this.targetType, currentScope);
+		}
+		return flowInfo;
+	}
+
+	/**
+	 * MessageSendDotClass code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	 */
+	public void generateCode(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		boolean valueRequired) {
+		int pc = codeStream.position;
+
+		// in interface case, no caching occurs, since cannot make a cache field for interface
+		if (valueRequired) {
+			codeStream.generateClassLiteralAccessForType(this.type.resolvedType, this.syntheticField);
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		return this.type.print(0, output).append(".class"); //$NON-NLS-1$
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		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;
+			TypeBinding leafComponentType = arrayBinding.leafComponentType;
+			if (leafComponentType == TypeBinding.VOID) {
+				scope.problemReporter().cannotAllocateVoidArray(this);
+				return null;
+			} else if (leafComponentType.isTypeVariable()) {
+				scope.problemReporter().illegalClassLiteralForTypeVariable((TypeVariableBinding)leafComponentType, this);
+			}
+		} else if (this.targetType.isTypeVariable()) {
+			scope.problemReporter().illegalClassLiteralForTypeVariable((TypeVariableBinding)this.targetType, this);
+		}
+		ReferenceBinding classType = scope.getJavaLangClass();
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328689
+		if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+			// Integer.class --> Class<Integer>, perform boxing of base types (int.class --> Class<Integer>)
+			TypeBinding boxedType = null;
+			if (this.targetType.id == T_void) {
+				boxedType = scope.environment().getResolvedType(JAVA_LANG_VOID, scope);
+			} else {
+				boxedType = scope.boxing(this.targetType);
+			}
+			this.resolvedType = scope.environment().createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/);
+		} else {
+			this.resolvedType = classType;
+		}
+		return this.resolvedType;
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.type.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
new file mode 100644
index 0000000..dba2c68
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Patrick Wienands <pwienands@abit.de> - Contribution for bug 393749
+ *     Stephan Herrmann - Contribution for
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+
+public class Clinit extends AbstractMethodDeclaration {
+	private static int ENUM_CONSTANTS_THRESHOLD = 2000;
+
+	private FieldBinding assertionSyntheticFieldBinding = null;
+	private FieldBinding classLiteralSyntheticField = null;
+
+	public Clinit(CompilationResult compilationResult) {
+		super(compilationResult);
+		this.modifiers = 0;
+		this.selector = TypeConstants.CLINIT;
+	}
+
+	public void analyseCode(
+		ClassScope classScope,
+		InitializationFlowContext staticInitializerFlowContext,
+		FlowInfo flowInfo) {
+
+		if (this.ignoreFurtherInvestigation)
+			return;
+		try {
+			ExceptionHandlingFlowContext clinitContext =
+				new ExceptionHandlingFlowContext(
+					staticInitializerFlowContext.parent,
+					this,
+					Binding.NO_EXCEPTIONS,
+					staticInitializerFlowContext,
+					this.scope,
+					FlowInfo.DEAD_END);
+
+			// check for missing returning path
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+				this.bits |= ASTNode.NeedFreeReturn;
+			}
+
+			// check missing blank final field initializations
+			flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
+			FieldBinding[] fields = this.scope.enclosingSourceType().fields();
+			for (int i = 0, count = fields.length; i < count; i++) {
+				FieldBinding field = fields[i];
+				if (field.isStatic()) {
+					if (!flowInfo.isDefinitelyAssigned(field)) {
+						if (field.isFinal()) {
+							this.scope.problemReporter().uninitializedBlankFinalField(
+									field,
+									this.scope.referenceType().declarationOf(field.original()));
+							// can complain against the field decl, since only one <clinit>
+						} else if (field.isNonNull()) {
+							this.scope.problemReporter().uninitializedNonNullField(
+									field,
+									this.scope.referenceType().declarationOf(field.original()));
+						}
+					}
+				}
+			}
+			// check static initializers thrown exceptions
+			staticInitializerFlowContext.checkInitializerExceptions(
+				this.scope,
+				clinitContext,
+				flowInfo);
+		} catch (AbortMethod e) {
+			this.ignoreFurtherInvestigation = true;
+		}
+	}
+
+	/**
+	 * Bytecode generation for a <clinit> method
+	 *
+	 * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
+	 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+	 */
+	public void generateCode(ClassScope classScope, ClassFile classFile) {
+
+		int clinitOffset = 0;
+		if (this.ignoreFurtherInvestigation) {
+			// should never have to add any <clinit> problem method
+			return;
+		}
+		boolean restart = false;
+		do {
+			try {
+				clinitOffset = classFile.contentsOffset;
+				this.generateCode(classScope, classFile, clinitOffset);
+				restart = false;
+			} catch (AbortMethod e) {
+				// should never occur
+				// the clinit referenceContext is the type declaration
+				// All clinit problems will be reported against the type: AbortType instead of AbortMethod
+				// reset the contentsOffset to the value before generating the clinit code
+				// decrement the number of method info as well.
+				// This is done in the addProblemMethod and addProblemConstructor for other
+				// cases.
+				if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
+					// a branch target required a goto_w, restart code gen in wide mode.
+					classFile.contentsOffset = clinitOffset;
+					classFile.methodCount--;
+					classFile.codeStream.resetInWideMode(); // request wide mode
+					// restart method generation
+					restart = true;
+				} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
+					classFile.contentsOffset = clinitOffset;
+					classFile.methodCount--;
+					classFile.codeStream.resetForCodeGenUnusedLocals();
+					// restart method generation
+					restart = true;
+				} else {
+					// produce a problem method accounting for this fatal error
+					classFile.contentsOffset = clinitOffset;
+					classFile.methodCount--;
+					restart = false;
+				}
+			}
+		} while (restart);
+	}
+
+	/**
+	 * Bytecode generation for a <clinit> method
+	 *
+	 * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
+	 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+	 */
+	private void generateCode(
+		ClassScope classScope,
+		ClassFile classFile,
+		int clinitOffset) {
+
+		ConstantPool constantPool = classFile.constantPool;
+		int constantPoolOffset = constantPool.currentOffset;
+		int constantPoolIndex = constantPool.currentIndex;
+		classFile.generateMethodInfoHeaderForClinit();
+		int codeAttributeOffset = classFile.contentsOffset;
+		classFile.generateCodeAttributeHeader();
+		CodeStream codeStream = classFile.codeStream;
+		resolve(classScope);
+
+		codeStream.reset(this, classFile);
+		TypeDeclaration declaringType = classScope.referenceContext;
+
+		// initialize local positions - including initializer scope.
+		MethodScope staticInitializerScope = declaringType.staticInitializerScope;
+		staticInitializerScope.computeLocalVariablePositions(0, codeStream);
+
+		// 1.4 feature
+		// This has to be done before any other initialization
+		if (this.assertionSyntheticFieldBinding != null) {
+			// generate code related to the activation of assertion for this class
+			codeStream.generateClassLiteralAccessForType(
+					classScope.outerMostClassScope().enclosingSourceType(),
+					this.classLiteralSyntheticField);
+			codeStream.invokeJavaLangClassDesiredAssertionStatus();
+			BranchLabel falseLabel = new BranchLabel(codeStream);
+			codeStream.ifne(falseLabel);
+			codeStream.iconst_1();
+			BranchLabel jumpLabel = new BranchLabel(codeStream);
+			codeStream.decrStackSize(1);
+			codeStream.goto_(jumpLabel);
+			falseLabel.place();
+			codeStream.iconst_0();
+			jumpLabel.place();
+			codeStream.fieldAccess(Opcodes.OPC_putstatic, this.assertionSyntheticFieldBinding, null /* default declaringClass */);
+		}
+		// generate static fields/initializers/enum constants
+		final FieldDeclaration[] fieldDeclarations = declaringType.fields;
+		int sourcePosition = -1;
+		int remainingFieldCount = 0;
+		if (TypeDeclaration.kind(declaringType.modifiers) == TypeDeclaration.ENUM_DECL) {
+			int enumCount = declaringType.enumConstantsCounter;
+			if (enumCount > ENUM_CONSTANTS_THRESHOLD) {
+				// generate synthetic methods to initialize all the enum constants
+				int begin = -1;
+				int count = 0;
+				if (fieldDeclarations != null) {
+					int max = fieldDeclarations.length;
+					for (int i = 0; i < max; i++) {
+						FieldDeclaration fieldDecl = fieldDeclarations[i];
+						if (fieldDecl.isStatic()) {
+							if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+								if (begin == -1) {
+									begin = i;
+								}
+								count++;
+								if (count > ENUM_CONSTANTS_THRESHOLD) {
+									SyntheticMethodBinding syntheticMethod = declaringType.binding.addSyntheticMethodForEnumInitialization(begin, i);
+									codeStream.invoke(Opcodes.OPC_invokestatic, syntheticMethod, null /* default declaringClass */);
+									begin = i;
+									count = 1;
+								}
+							} else {
+								remainingFieldCount++;
+							}
+						}
+					}
+					if (count != 0) {
+						// add last synthetic method
+						SyntheticMethodBinding syntheticMethod = declaringType.binding.addSyntheticMethodForEnumInitialization(begin, max);
+						codeStream.invoke(Opcodes.OPC_invokestatic, syntheticMethod, null /* default declaringClass */);
+					}
+				}
+			} else if (fieldDeclarations != null) {
+				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+					FieldDeclaration fieldDecl = fieldDeclarations[i];
+					if (fieldDecl.isStatic()) {
+						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+						} else {
+							remainingFieldCount++;
+						}
+					}
+				}
+			}
+			// enum need to initialize $VALUES synthetic cache of enum constants
+			// $VALUES := new <EnumType>[<enumCount>]
+			codeStream.generateInlinedValue(enumCount);
+			codeStream.anewarray(declaringType.binding);
+			if (enumCount > 0) {
+				if (fieldDeclarations != null) {
+					for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+						FieldDeclaration fieldDecl = fieldDeclarations[i];
+						// $VALUES[i] = <enum-constant-i>
+						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+							codeStream.dup();
+							codeStream.generateInlinedValue(fieldDecl.binding.id);
+							codeStream.fieldAccess(Opcodes.OPC_getstatic, fieldDecl.binding, null /* default declaringClass */);
+							codeStream.aastore();
+						}
+					}
+				}
+			}
+			codeStream.fieldAccess(Opcodes.OPC_putstatic, declaringType.enumValuesSyntheticfield, null /* default declaringClass */);
+			if (remainingFieldCount != 0) {
+				// if fields that are not enum constants need to be generated (static initializer/static field)
+				for (int i = 0, max = fieldDeclarations.length; i < max && remainingFieldCount >= 0; i++) {
+					FieldDeclaration fieldDecl = fieldDeclarations[i];
+					switch (fieldDecl.getKind()) {
+						case AbstractVariableDeclaration.ENUM_CONSTANT :
+							break;
+						case AbstractVariableDeclaration.INITIALIZER :
+							if (!fieldDecl.isStatic()) {
+								break;
+							}
+							remainingFieldCount--;
+							sourcePosition = ((Initializer) fieldDecl).block.sourceEnd;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+						case AbstractVariableDeclaration.FIELD :
+							if (!fieldDecl.binding.isStatic()) {
+								break;
+							}
+							remainingFieldCount--;
+							sourcePosition = fieldDecl.declarationEnd;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+					}
+				}
+			}
+		} else {
+			if (fieldDeclarations != null) {
+				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+					FieldDeclaration fieldDecl = fieldDeclarations[i];
+					switch (fieldDecl.getKind()) {
+						case AbstractVariableDeclaration.INITIALIZER :
+							if (!fieldDecl.isStatic())
+								break;
+							sourcePosition = ((Initializer) fieldDecl).block.sourceEnd;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+						case AbstractVariableDeclaration.FIELD :
+							if (!fieldDecl.binding.isStatic())
+								break;
+							sourcePosition = fieldDecl.declarationEnd;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+					}
+				}
+			}
+		}
+
+		if (codeStream.position == 0) {
+			// do not need to output a Clinit if no bytecodes
+			// so we reset the offset inside the byte array contents.
+			classFile.contentsOffset = clinitOffset;
+			// like we don't addd a method we need to undo the increment on the method count
+			classFile.methodCount--;
+			// reset the constant pool to its state before the clinit
+			constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
+		} else {
+			if ((this.bits & ASTNode.NeedFreeReturn) != 0) {
+				int before = codeStream.position;
+				codeStream.return_();
+				if (sourcePosition != -1) {
+					// expand the last initializer variables to include the trailing return
+					codeStream.recordPositionsFrom(before, sourcePosition);
+				}
+			}
+			// Record the end of the clinit: point to the declaration of the class
+			codeStream.recordPositionsFrom(0, declaringType.sourceStart);
+			classFile.completeCodeAttributeForClinit(codeAttributeOffset);
+		}
+	}
+
+	public boolean isClinit() {
+
+		return true;
+	}
+
+	public boolean isInitializationMethod() {
+
+		return true;
+	}
+
+	public boolean isStatic() {
+
+		return true;
+	}
+
+	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+		//the clinit is filled by hand ....
+	}
+
+	public StringBuffer print(int tab, StringBuffer output) {
+
+		printIndent(tab, output).append("<clinit>()"); //$NON-NLS-1$
+		printBody(tab + 1, output);
+		return output;
+	}
+
+	public void resolve(ClassScope classScope) {
+
+		this.scope = new MethodScope(classScope, classScope.referenceContext, true);
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		ClassScope classScope) {
+
+		visitor.visit(this, classScope);
+		visitor.endVisit(this, classScope);
+	}
+
+	public void setAssertionSupport(FieldBinding assertionSyntheticFieldBinding, boolean needClassLiteralField) {
+
+		this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding;
+
+		// we need to add the field right now, because the field infos are generated before the methods
+		if (needClassLiteralField) {
+			SourceTypeBinding sourceType =
+				this.scope.outerMostClassScope().enclosingSourceType();
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=22334
+			if (!sourceType.isInterface() && !sourceType.isBaseType()) {
+				this.classLiteralSyntheticField = sourceType.addSyntheticFieldForClassLiteral(sourceType, this.scope);
+			}
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CombinedBinaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CombinedBinaryExpression.java
new file mode 100644
index 0000000..7ff2fec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CombinedBinaryExpression.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * CombinedBinaryExpression is an implementation of BinaryExpression that
+ * specifically attempts to mitigate the issues raised by expressions which
+ * have a very deep leftmost branch. It does so by maintaining a table of
+ * direct references to its subexpressions, and implementing non-recursive
+ * variants of the most significant recursive algorithms of its ancestors.
+ * The subexpressions table only holds intermediate binary expressions. Its
+ * role is to provide the reversed navigation through the left relationship
+ * of BinaryExpression to Expression. To cope with potentially very deep
+ * left branches, an instance of CombinedBinaryExpression is created once in
+ * a while, using variable thresholds held by {@link #arityMax}.
+ * As a specific case, the topmost node of all binary expressions that are
+ * deeper than one is a CombinedBinaryExpression, but it has no references
+ * table.<br>
+ * Notes:
+ * <ul>
+ * <li>CombinedBinaryExpression is not meant to behave in other ways than
+ *     BinaryExpression in any observable respect;</li>
+ * <li>visitors that implement their own traversal upon binary expressions
+ *     should consider taking advantage of combined binary expressions, or
+ *     else face a risk of StackOverflowError upon deep instances;</li>
+ * <li>callers that need to change the operator should rebuild the expression
+ *     from scratch, or else amend the references table as needed to cope with
+ *     the resulting, separated expressions.</li>
+ * </ul>
+ */
+public class CombinedBinaryExpression extends BinaryExpression {
+
+	/**
+	 * The number of consecutive binary expressions of this' left branch that
+	 * bear the same operator as this.<br>
+	 * Notes:
+	 * <ul><li>the presence of a CombinedBinaryExpression instance resets
+	 *         arity, even when its operator is compatible;</li>
+	 *	   <li>this property is maintained by the parser.</li>
+	 * </ul>
+	 */
+	public int arity;
+
+	/**
+	 * The threshold that will trigger the creation of the next full-fledged
+	 * CombinedBinaryExpression. This field is only maintained for the
+	 * topmost binary expression (it is 0 otherwise). It enables a variable
+	 * policy, which scales better with very large expressions.
+	 */
+	public int arityMax;
+
+	/**
+	 * Upper limit for {@link #arityMax}.
+	 */
+	public static final int ARITY_MAX_MAX = 160;
+
+	/**
+	 * Default lower limit for {@link #arityMax}.
+	 */
+	public static final int ARITY_MAX_MIN = 20;
+
+	/**
+	 * Default value for the first term of the series of {@link #arityMax}
+	 * values. Changing this allows for experimentation. Not meant to be
+	 * changed during a parse operation.
+	 */
+	public static int defaultArityMaxStartingValue = ARITY_MAX_MIN;
+
+	/**
+	 * A table of references to the binary expressions of this' left branch.
+	 * Instances of CombinedBinaryExpression are not repeated here. Instead,
+	 * the left subexpression of referencesTable[0] may be a combined binary
+	 * expression, if appropriate. Null when this only cares about tracking
+	 * the expression's arity.
+	 */
+	public BinaryExpression referencesTable[];
+
+/**
+ * Make a new CombinedBinaryExpression. If arity is strictly greater than one,
+ * a references table is built and initialized with the reverse relationship of
+ * the one defined by {@link BinaryExpression#left}. arity and left must be
+ * compatible with each other (that is, there must be at least arity - 1
+ * consecutive compatible binary expressions into the leftmost branch of left,
+ * the topmost of which being left's immediate left expression).
+ * @param left the left branch expression
+ * @param right the right branch expression
+ * @param operator the operator for this binary expression - only PLUS for now
+ * @param arity the number of binary expressions of a compatible operator that
+ *        already exist into the leftmost branch of left (including left); must
+ *        be strictly greater than 0
+ */
+public CombinedBinaryExpression(Expression left, Expression right, int operator, int arity) {
+	super(left, right, operator);
+	initArity(left, arity);
+}
+public CombinedBinaryExpression(CombinedBinaryExpression expression) {
+	super(expression);
+	initArity(expression.left, expression.arity);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext,
+		FlowInfo flowInfo) {
+	// keep implementation in sync with BinaryExpression#analyseCode
+	if (this.referencesTable == null) {
+		return super.analyseCode(currentScope, flowContext, flowInfo);
+	}
+	try {
+		BinaryExpression cursor;
+		if ((cursor = this.referencesTable[0]).resolvedType.id !=
+				TypeIds.T_JavaLangString) {
+			cursor.left.checkNPE(currentScope, flowContext, flowInfo);
+		}
+		flowInfo = cursor.left.analyseCode(currentScope, flowContext, flowInfo).
+			unconditionalInits();
+		for (int i = 0, end = this.arity; i < end; i ++) {
+			if ((cursor = this.referencesTable[i]).resolvedType.id !=
+					TypeIds.T_JavaLangString) {
+				cursor.right.checkNPE(currentScope, flowContext, flowInfo);
+			}
+			flowInfo = cursor.right.
+				analyseCode(currentScope, flowContext, flowInfo).
+					unconditionalInits();
+		}
+		if (this.resolvedType.id != TypeIds.T_JavaLangString) {
+			this.right.checkNPE(currentScope, flowContext, flowInfo);
+		}
+		return this.right.analyseCode(currentScope, flowContext, flowInfo).
+			unconditionalInits();
+	} finally {
+		// account for exception possibly thrown by arithmetics
+		flowContext.recordAbruptExit();
+	}
+}
+
+public void generateOptimizedStringConcatenation(BlockScope blockScope,
+		CodeStream codeStream, int typeID) {
+	// keep implementation in sync with BinaryExpression and Expression
+	// #generateOptimizedStringConcatenation
+	if (this.referencesTable == null) {
+		super.generateOptimizedStringConcatenation(blockScope, codeStream,
+			typeID);
+	} else {
+		if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) ==
+				OperatorIds.PLUS)
+			&& ((this.bits & ASTNode.ReturnTypeIDMASK) == TypeIds.T_JavaLangString)) {
+			if (this.constant != Constant.NotAConstant) {
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+				codeStream.invokeStringConcatenationAppendForType(
+						this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			} else {
+				BinaryExpression cursor = this.referencesTable[0];
+
+				int restart = 0;
+	//			int cursorTypeID;
+				int pc = codeStream.position;
+				for (restart = this.arity - 1; restart >= 0; restart--) {
+					if ((cursor = this.referencesTable[restart]).constant !=
+							Constant.NotAConstant) {
+						codeStream.generateConstant(cursor.constant,
+							cursor.implicitConversion);
+						codeStream.invokeStringConcatenationAppendForType(
+							cursor.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+						break;
+					}
+					// never happens for now - may reconsider if we decide to
+					// cover more than string concatenation
+	//				if (!((((cursor = this.referencesTable[restart]).bits &
+	//						ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) ==
+	//							OperatorIds.PLUS) &
+	//						((cursorTypeID = cursor.bits & ASTNode.ReturnTypeIDMASK) ==
+	//							TypeIds.T_JavaLangString)) {
+	//					if (cursorTypeID == T_JavaLangString &&
+	//							cursor.constant != Constant.NotAConstant &&
+	//							cursor.constant.stringValue().length() == 0) {
+	//						break; // optimize str + ""
+	//					}
+	//					cursor.generateCode(blockScope, codeStream, true);
+	//					codeStream.invokeStringConcatenationAppendForType(
+	//							cursorTypeID);
+	//					break;
+	//				}
+				}
+				restart++;
+				if (restart == 0) { // reached the leftmost expression
+					cursor.left.generateOptimizedStringConcatenation(
+						blockScope,
+						codeStream,
+						cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+				}
+				int pcAux;
+				for (int i = restart; i < this.arity; i++) {
+					codeStream.recordPositionsFrom(pc,
+						(cursor = this.referencesTable[i]).left.sourceStart);
+					pcAux = codeStream.position;
+					cursor.right.generateOptimizedStringConcatenation(blockScope,
+						codeStream,	cursor.right.implicitConversion &
+							TypeIds.COMPILE_TYPE_MASK);
+					codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart);
+				}
+				codeStream.recordPositionsFrom(pc, this.left.sourceStart);
+				pc = codeStream.position;
+				this.right.generateOptimizedStringConcatenation(
+					blockScope,
+					codeStream,
+					this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+				codeStream.recordPositionsFrom(pc, this.right.sourceStart);
+			}
+		} else {
+			super.generateOptimizedStringConcatenation(blockScope, codeStream,
+				typeID);
+		}
+	}
+}
+
+public void generateOptimizedStringConcatenationCreation(BlockScope blockScope,
+		CodeStream codeStream, int typeID) {
+	// keep implementation in sync with BinaryExpression
+	// #generateOptimizedStringConcatenationCreation
+	if (this.referencesTable == null) {
+		super.generateOptimizedStringConcatenationCreation(blockScope,
+			codeStream,	typeID);
+	} else {
+		if ((((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) ==
+				OperatorIds.PLUS) &&
+					((this.bits & ASTNode.ReturnTypeIDMASK) ==
+						TypeIds.T_JavaLangString) &&
+					this.constant == Constant.NotAConstant) {
+			int pc = codeStream.position;
+			BinaryExpression cursor = this.referencesTable[this.arity - 1];
+				// silence warnings
+			int restart = 0;
+			for (restart = this.arity - 1; restart >= 0; restart--) {
+				if (((((cursor = this.referencesTable[restart]).bits &
+						ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) ==
+							OperatorIds.PLUS) &&
+						((cursor.bits & ASTNode.ReturnTypeIDMASK) ==
+							TypeIds.T_JavaLangString)) {
+					if (cursor.constant != Constant.NotAConstant) {
+						codeStream.newStringContatenation(); // new: java.lang.StringBuffer
+						codeStream.dup();
+						codeStream.ldc(cursor.constant.stringValue());
+						codeStream.invokeStringConcatenationStringConstructor();
+						// invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
+						break;
+					}
+				} else {
+					cursor.generateOptimizedStringConcatenationCreation(blockScope,
+						codeStream, cursor.implicitConversion &
+							TypeIds.COMPILE_TYPE_MASK);
+					break;
+				}
+			}
+			restart++;
+			if (restart == 0) { // reached the leftmost expression
+				cursor.left.generateOptimizedStringConcatenationCreation(
+					blockScope,
+					codeStream,
+					cursor.left.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			}
+			int pcAux;
+			for (int i = restart; i < this.arity; i++) {
+				codeStream.recordPositionsFrom(pc,
+					(cursor = this.referencesTable[i]).left.sourceStart);
+				pcAux = codeStream.position;
+				cursor.right.generateOptimizedStringConcatenation(blockScope,
+					codeStream,	cursor.right.implicitConversion &
+						TypeIds.COMPILE_TYPE_MASK);
+				codeStream.recordPositionsFrom(pcAux, cursor.right.sourceStart);
+			}
+			codeStream.recordPositionsFrom(pc, this.left.sourceStart);
+			pc = codeStream.position;
+			this.right.generateOptimizedStringConcatenation(
+				blockScope,
+				codeStream,
+				this.right.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.recordPositionsFrom(pc, this.right.sourceStart);
+		} else {
+			super.generateOptimizedStringConcatenationCreation(blockScope,
+				codeStream, typeID);
+		}
+	}
+}
+private void initArity(Expression expression, int value) {
+	this.arity = value;
+	if (value > 1) {
+		this.referencesTable = new BinaryExpression[value];
+		this.referencesTable[value - 1] = (BinaryExpression) expression;
+		for (int i = value - 1; i > 0; i--) {
+			this.referencesTable[i - 1] =
+				(BinaryExpression) this.referencesTable[i].left;
+		}
+	} else {
+		this.arityMax = defaultArityMaxStartingValue;
+	}
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent,
+		StringBuffer output) {
+	// keep implementation in sync with
+	// BinaryExpression#printExpressionNoParenthesis and
+	// OperatorExpression#printExpression
+	if (this.referencesTable == null) {
+		return super.printExpressionNoParenthesis(indent, output);
+	}
+	String operatorString = operatorToString();
+	for (int i = this.arity - 1; i >= 0; i--) {
+		output.append('(');
+	}
+	output = this.referencesTable[0].left.
+		printExpression(indent, output);
+	for (int i = 0, end = this.arity;
+				i < end; i++) {
+		output.append(' ').append(operatorString).append(' ');
+		output = this.referencesTable[i].right.
+			printExpression(0, output);
+		output.append(')');
+	}
+	output.append(' ').append(operatorString).append(' ');
+	return this.right.printExpression(0, output);
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// keep implementation in sync with BinaryExpression#resolveType
+	if (this.referencesTable == null) {
+		return super.resolveType(scope);
+	}
+	BinaryExpression cursor;
+	if ((cursor = this.referencesTable[0]).left instanceof CastExpression) {
+		cursor.left.bits |= ASTNode.DisableUnnecessaryCastCheck;
+			// will check later on
+	}
+	cursor.left.resolveType(scope);
+	for (int i = 0, end = this.arity; i < end; i ++) {
+		this.referencesTable[i].nonRecursiveResolveTypeUpwards(scope);
+	}
+	nonRecursiveResolveTypeUpwards(scope);
+	return this.resolvedType;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (this.referencesTable == null) {
+		super.traverse(visitor, scope);
+	} else {
+		if (visitor.visit(this, scope)) {
+			int restart;
+			for (restart = this.arity - 1;
+					restart >= 0;
+					restart--) {
+				if (!visitor.visit(
+						this.referencesTable[restart], scope)) {
+					visitor.endVisit(
+						this.referencesTable[restart], scope);
+					break;
+				}
+			}
+			restart++;
+			// restart now points to the deepest BE for which
+			// visit returned true, if any
+			if (restart == 0) {
+				this.referencesTable[0].left.traverse(visitor, scope);
+			}
+			for (int i = restart, end = this.arity;
+						i < end; i++) {
+				this.referencesTable[i].right.traverse(visitor, scope);
+				visitor.endVisit(this.referencesTable[i], scope);
+			}
+			this.right.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
+
+/**
+ * Change {@link #arityMax} if and as needed. The current policy is to double
+ * arityMax each time this method is called, until it reaches
+ * {@link #ARITY_MAX_MAX}. Other policies may consider incrementing it less
+ * agressively. Call only after an appropriate value has been assigned to
+ * {@link #left}.
+ */
+// more sophisticate increment policies would leverage the leftmost expression
+// to hold an indication of the number of uses of a given arityMax in a row
+public void tuneArityMax() {
+	if (this.arityMax < ARITY_MAX_MAX) {
+		this.arityMax *= 2;
+	}
+}
+}
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
new file mode 100644
index 0000000..1306b97
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -0,0 +1,732 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann  - Contribution for bug 295551
+ *     Jesper S Moller   - Contributions for
+ *							  Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.parser.NLSTag;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+import org.eclipse.jdt.internal.compiler.problem.AbortType;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.HashSetOfInt;
+
+public class CompilationUnitDeclaration extends ASTNode implements ProblemSeverities, ReferenceContext {
+
+	private static final Comparator STRING_LITERAL_COMPARATOR = new Comparator() {
+		public int compare(Object o1, Object o2) {
+			StringLiteral literal1 = (StringLiteral) o1;
+			StringLiteral literal2 = (StringLiteral) o2;
+			return literal1.sourceStart - literal2.sourceStart;
+		}
+	};
+	private static final int STRING_LITERALS_INCREMENT = 10;
+
+	public ImportReference currentPackage;
+	public ImportReference[] imports;
+	public TypeDeclaration[] types;
+	public int[][] comments;
+
+	public boolean ignoreFurtherInvestigation = false; // once pointless to investigate due to errors
+	public boolean ignoreMethodBodies = false;
+	public CompilationUnitScope scope;
+	public ProblemReporter problemReporter;
+	public CompilationResult compilationResult;
+
+	public LocalTypeBinding[] localTypes;
+	public int localTypeCount = 0;
+
+	public boolean isPropagatingInnerClassEmulation;
+
+	public Javadoc javadoc; // 1.5 addition for package-info.java
+
+	public NLSTag[] nlsTags;
+	private StringLiteral[] stringLiterals;
+	private int stringLiteralsPtr;
+	private HashSetOfInt stringLiteralsStart;
+
+	IrritantSet[] suppressWarningIrritants;  // irritant for suppressed warnings
+	Annotation[] suppressWarningAnnotations;
+	long[] suppressWarningScopePositions; // (start << 32) + end
+	int suppressWarningsCount;
+
+public CompilationUnitDeclaration(ProblemReporter problemReporter, CompilationResult compilationResult, int sourceLength) {
+	this.problemReporter = problemReporter;
+	this.compilationResult = compilationResult;
+	//by definition of a compilation unit....
+	this.sourceStart = 0;
+	this.sourceEnd = sourceLength - 1;
+}
+
+/*
+ *	We cause the compilation task to abort to a given extent.
+ */
+public void abort(int abortLevel, CategorizedProblem problem) {
+	switch (abortLevel) {
+		case AbortType :
+			throw new AbortType(this.compilationResult, problem);
+		case AbortMethod :
+			throw new AbortMethod(this.compilationResult, problem);
+		default :
+			throw new AbortCompilationUnit(this.compilationResult, problem);
+	}
+}
+
+/*
+ * Dispatch code analysis AND request saturation of inner emulation
+ */
+public void analyseCode() {
+	if (this.ignoreFurtherInvestigation)
+		return;
+	try {
+		if (this.types != null) {
+			for (int i = 0, count = this.types.length; i < count; i++) {
+				this.types[i].analyseCode(this.scope);
+			}
+		}
+		// request inner emulation propagation
+		propagateInnerEmulationForAllLocalTypes();
+	} catch (AbortCompilationUnit e) {
+		this.ignoreFurtherInvestigation = true;
+		return;
+	}
+}
+
+/*
+ * When unit result is about to be accepted, removed back pointers
+ * to compiler structures.
+ */
+public void cleanUp() {
+	if (this.types != null) {
+		for (int i = 0, max = this.types.length; i < max; i++) {
+			cleanUp(this.types[i]);
+		}
+		for (int i = 0, max = this.localTypeCount; i < max; i++) {
+		    LocalTypeBinding localType = this.localTypes[i];
+			// null out the type's scope backpointers
+			localType.scope = null; // local members are already in the list
+			localType.enclosingCase = null;
+		}
+	}
+
+	this.compilationResult.recoveryScannerData = null; // recovery is already done
+
+	ClassFile[] classFiles = this.compilationResult.getClassFiles();
+	for (int i = 0, max = classFiles.length; i < max; i++) {
+		// clear the classFile back pointer to the bindings
+		ClassFile classFile = classFiles[i];
+		// null out the classfile backpointer to a type binding
+		classFile.referenceBinding = null;
+		classFile.innerClassesBindings = null;
+		classFile.bootstrapMethods = null;
+		classFile.missingTypes = null;
+		classFile.visitedTypes = null;
+	}
+
+	this.suppressWarningAnnotations = null;
+}
+
+private void cleanUp(TypeDeclaration type) {
+	if (type.memberTypes != null) {
+		for (int i = 0, max = type.memberTypes.length; i < max; i++){
+			cleanUp(type.memberTypes[i]);
+		}
+	}
+	if (type.binding != null && type.binding.isAnnotationType())
+		this.compilationResult.hasAnnotations = true;
+	if (type.binding != null) {
+		// null out the type's scope backpointers
+		type.binding.scope = null;
+	}
+}
+
+public void checkUnusedImports(){
+	if (this.scope.imports != null){
+		for (int i = 0, max = this.scope.imports.length; i < max; i++){
+			ImportBinding importBinding = this.scope.imports[i];
+			ImportReference importReference = importBinding.reference;
+			if (importReference != null && ((importReference.bits & ASTNode.Used) == 0)){
+				this.scope.problemReporter().unusedImport(importReference);
+			}
+		}
+	}
+}
+
+public CompilationResult compilationResult() {
+	return this.compilationResult;
+}
+
+public void createPackageInfoType() {
+	TypeDeclaration declaration = new TypeDeclaration(this.compilationResult);
+	declaration.name = TypeConstants.PACKAGE_INFO_NAME;
+	declaration.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccInterface;
+	declaration.javadoc = this.javadoc;
+	this.types[0] = declaration; // Assumes the first slot is meant for this type
+}
+
+/*
+ * Finds the matching type amoung this compilation unit types.
+ * Returns null if no type with this name is found.
+ * The type name is a compound name
+ * e.g. if we're looking for X.A.B then a type name would be {X, A, B}
+ */
+public TypeDeclaration declarationOfType(char[][] typeName) {
+	for (int i = 0; i < this.types.length; i++) {
+		TypeDeclaration typeDecl = this.types[i].declarationOfType(typeName);
+		if (typeDecl != null) {
+			return typeDecl;
+		}
+	}
+	return null;
+}
+
+public void finalizeProblems() {
+	if (this.suppressWarningsCount == 0) return;
+	int removed = 0;
+	CategorizedProblem[] problems = this.compilationResult.problems;
+	int problemCount = this.compilationResult.problemCount;
+	IrritantSet[] foundIrritants = new IrritantSet[this.suppressWarningsCount];
+	CompilerOptions options = this.scope.compilerOptions();
+	boolean hasMandatoryErrors = false;
+	nextProblem: for (int iProblem = 0, length = problemCount; iProblem < length; iProblem++) {
+		CategorizedProblem problem = problems[iProblem];
+		int problemID = problem.getID();
+		int irritant = ProblemReporter.getIrritant(problemID);
+		boolean isError = problem.isError();
+		if (isError) {
+			if (irritant == 0) {
+				// tolerate unused warning tokens when mandatory errors
+				hasMandatoryErrors = true;
+				continue;
+			}
+			if (!options.suppressOptionalErrors) {
+				continue;
+			}
+		}
+		int start = problem.getSourceStart();
+		int end = problem.getSourceEnd();
+		nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
+			long position = this.suppressWarningScopePositions[iSuppress];
+			int startSuppress = (int) (position >>> 32);
+			int endSuppress = (int) position;
+			if (start < startSuppress) continue nextSuppress;
+			if (end > endSuppress) continue nextSuppress;
+			if (!this.suppressWarningIrritants[iSuppress].isSet(irritant))
+				continue nextSuppress;
+			// discard suppressed warning
+			removed++;
+			problems[iProblem] = null;
+			this.compilationResult.removeProblem(problem);
+			if (foundIrritants[iSuppress] == null){
+				foundIrritants[iSuppress] = new IrritantSet(irritant);
+			} else {
+				foundIrritants[iSuppress].set(irritant);
+			}
+			continue nextProblem;
+		}
+	}
+	// compact remaining problems
+	if (removed > 0) {
+		for (int i = 0, index = 0; i < problemCount; i++) {
+			CategorizedProblem problem;
+			if ((problem = problems[i]) != null) {
+				if (i > index) {
+					problems[index++] = problem;
+				} else {
+					index++;
+				}
+			}
+		}
+	}
+	// flag SuppressWarnings which had no effect (only if no (mandatory) error got detected within unit
+	if (!hasMandatoryErrors) {
+		int severity = options.getSeverity(CompilerOptions.UnusedWarningToken);
+		if (severity != ProblemSeverities.Ignore) {
+			boolean unusedWarningTokenIsWarning = (severity & ProblemSeverities.Error) == 0;
+			for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
+				Annotation annotation = this.suppressWarningAnnotations[iSuppress];
+				if (annotation == null) continue; // implicit annotation
+				IrritantSet irritants = this.suppressWarningIrritants[iSuppress];
+				if (unusedWarningTokenIsWarning && irritants.areAllSet()) continue; // @SuppressWarnings("all") also suppresses unused warning token
+				if (irritants != foundIrritants[iSuppress]) { // mismatch, some warning tokens were unused
+					MemberValuePair[] pairs = annotation.memberValuePairs();
+					pairLoop: for (int iPair = 0, pairCount = pairs.length; iPair < pairCount; iPair++) {
+						MemberValuePair pair = pairs[iPair];
+						if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
+							Expression value = pair.value;
+							if (value instanceof ArrayInitializer) {
+								ArrayInitializer initializer = (ArrayInitializer) value;
+								Expression[] inits = initializer.expressions;
+								if (inits != null) {
+									for (int iToken = 0, tokenCount = inits.length; iToken < tokenCount; iToken++) {
+										Constant cst = inits[iToken].constant;
+										if (cst != Constant.NotAConstant && cst.typeID() == TypeIds.T_JavaLangString) {
+											IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
+											if (tokenIrritants != null
+													&& !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
+													&& 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;
+													nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
+														long position = this.suppressWarningScopePositions[jSuppress];
+														int startSuppress = (int) (position >>> 32);
+														int endSuppress = (int) position;
+														if (start < startSuppress) continue nextSuppress;
+														if (end > endSuppress) continue nextSuppress;
+														if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+													}
+												}
+												this.scope.problemReporter().unusedWarningToken(inits[iToken]);
+											}
+										}
+									}
+								}
+							} else {
+								Constant cst = value.constant;
+								if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
+									IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
+									if (tokenIrritants != null
+											&& !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
+											&& 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;
+											nextSuppress: for (int jSuppress = iSuppress - 1; jSuppress >= 0; jSuppress--) {
+												long position = this.suppressWarningScopePositions[jSuppress];
+												int startSuppress = (int) (position >>> 32);
+												int endSuppress = (int) position;
+												if (start < startSuppress) continue nextSuppress;
+												if (end > endSuppress) continue nextSuppress;
+												if (this.suppressWarningIrritants[jSuppress].areAllSet()) break pairLoop; // suppress all?
+											}
+										}
+										this.scope.problemReporter().unusedWarningToken(value);
+									}
+								}
+							}
+							break pairLoop;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+/**
+ * Bytecode generation
+ */
+public void generateCode() {
+	if (this.ignoreFurtherInvestigation) {
+		if (this.types != null) {
+			for (int i = 0, count = this.types.length; i < count; i++) {
+				this.types[i].ignoreFurtherInvestigation = true;
+				// propagate the flag to request problem type creation
+				this.types[i].generateCode(this.scope);
+			}
+		}
+		return;
+	}
+	try {
+		if (this.types != null) {
+			for (int i = 0, count = this.types.length; i < count; i++)
+				this.types[i].generateCode(this.scope);
+		}
+	} catch (AbortCompilationUnit e) {
+		// ignore
+	}
+}
+
+public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+	return this;
+}
+
+public char[] getFileName() {
+	return this.compilationResult.getFileName();
+}
+
+public char[] getMainTypeName() {
+	if (this.compilationResult.compilationUnit == null) {
+		char[] fileName = this.compilationResult.getFileName();
+
+		int start = CharOperation.lastIndexOf('/', fileName) + 1;
+		if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName))
+			start = CharOperation.lastIndexOf('\\', fileName) + 1;
+
+		int end = CharOperation.lastIndexOf('.', fileName);
+		if (end == -1)
+			end = fileName.length;
+
+		return CharOperation.subarray(fileName, start, end);
+	} else {
+		return this.compilationResult.compilationUnit.getMainTypeName();
+	}
+}
+
+public boolean isEmpty() {
+	return (this.currentPackage == null) && (this.imports == null) && (this.types == null);
+}
+
+public boolean isPackageInfo() {
+	return CharOperation.equals(getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME);
+}
+
+public boolean isSuppressed(CategorizedProblem problem) {
+	if (this.suppressWarningsCount == 0) return false;
+	int irritant = ProblemReporter.getIrritant(problem.getID());
+	if (irritant == 0) return false;
+	int start = problem.getSourceStart();
+	int end = problem.getSourceEnd();
+	nextSuppress: for (int iSuppress = 0, suppressCount = this.suppressWarningsCount; iSuppress < suppressCount; iSuppress++) {
+		long position = this.suppressWarningScopePositions[iSuppress];
+		int startSuppress = (int) (position >>> 32);
+		int endSuppress = (int) position;
+		if (start < startSuppress) continue nextSuppress;
+		if (end > endSuppress) continue nextSuppress;
+		if (this.suppressWarningIrritants[iSuppress].isSet(irritant))
+			return true;
+	}
+	return false;
+}
+
+public boolean hasErrors() {
+	return this.ignoreFurtherInvestigation;
+}
+
+public StringBuffer print(int indent, StringBuffer output) {
+	if (this.currentPackage != null) {
+		printIndent(indent, output).append("package "); //$NON-NLS-1$
+		this.currentPackage.print(0, output, false).append(";\n"); //$NON-NLS-1$
+	}
+	if (this.imports != null)
+		for (int i = 0; i < this.imports.length; i++) {
+			printIndent(indent, output).append("import "); //$NON-NLS-1$
+			ImportReference currentImport = this.imports[i];
+			if (currentImport.isStatic()) {
+				output.append("static "); //$NON-NLS-1$
+			}
+			currentImport.print(0, output).append(";\n"); //$NON-NLS-1$
+		}
+
+	if (this.types != null) {
+		for (int i = 0; i < this.types.length; i++) {
+			this.types[i].print(indent, output).append("\n"); //$NON-NLS-1$
+		}
+	}
+	return output;
+}
+
+/*
+ * Force inner local types to update their innerclass emulation
+ */
+public void propagateInnerEmulationForAllLocalTypes() {
+	this.isPropagatingInnerClassEmulation = true;
+	for (int i = 0, max = this.localTypeCount; i < max; i++) {
+		LocalTypeBinding localType = this.localTypes[i];
+		// only propagate for reachable local types
+		if ((localType.scope.referenceType().bits & IsReachable) != 0) {
+			localType.updateInnerEmulationDependents();
+		}
+	}
+}
+
+public void recordStringLiteral(StringLiteral literal, boolean fromRecovery) {
+	if (this.stringLiteralsStart != null) {
+		if (this.stringLiteralsStart.contains(literal.sourceStart)) return;
+		this.stringLiteralsStart.add(literal.sourceStart);
+	} else if (fromRecovery) {
+		this.stringLiteralsStart = new HashSetOfInt(this.stringLiteralsPtr + STRING_LITERALS_INCREMENT);
+		for (int i = 0; i < this.stringLiteralsPtr; i++) {
+			this.stringLiteralsStart.add(this.stringLiterals[i].sourceStart);
+		}
+
+		if (this.stringLiteralsStart.contains(literal.sourceStart)) return;
+		this.stringLiteralsStart.add(literal.sourceStart);
+	}
+
+	if (this.stringLiterals == null) {
+		this.stringLiterals = new StringLiteral[STRING_LITERALS_INCREMENT];
+		this.stringLiteralsPtr = 0;
+	} else {
+		int stackLength = this.stringLiterals.length;
+		if (this.stringLiteralsPtr == stackLength) {
+			System.arraycopy(
+				this.stringLiterals,
+				0,
+				this.stringLiterals = new StringLiteral[stackLength + STRING_LITERALS_INCREMENT],
+				0,
+				stackLength);
+		}
+	}
+	this.stringLiterals[this.stringLiteralsPtr++] = literal;
+}
+
+public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd) {
+	if (this.suppressWarningIrritants == null) {
+		this.suppressWarningIrritants = new IrritantSet[3];
+		this.suppressWarningAnnotations = new Annotation[3];
+		this.suppressWarningScopePositions = new long[3];
+	} else if (this.suppressWarningIrritants.length == this.suppressWarningsCount) {
+		System.arraycopy(this.suppressWarningIrritants, 0,this.suppressWarningIrritants = new IrritantSet[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
+		System.arraycopy(this.suppressWarningAnnotations, 0,this.suppressWarningAnnotations = new Annotation[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
+		System.arraycopy(this.suppressWarningScopePositions, 0,this.suppressWarningScopePositions = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
+	}
+	final long scopePositions = ((long)scopeStart<<32) + scopeEnd;
+	for (int i = 0, max = this.suppressWarningsCount; i < max; i++) {
+		if (this.suppressWarningAnnotations[i] == annotation
+				&& this.suppressWarningScopePositions[i] == scopePositions
+				&& this.suppressWarningIrritants[i].hasSameIrritants(irritants)) {
+			// annotation data already recorded
+			return;
+		}
+	}
+	this.suppressWarningIrritants[this.suppressWarningsCount] = irritants;
+	this.suppressWarningAnnotations[this.suppressWarningsCount] = annotation;
+	this.suppressWarningScopePositions[this.suppressWarningsCount++] = scopePositions;
+}
+
+/*
+ * Keep track of all local types, so as to update their innerclass
+ * emulation later on.
+ */
+public void record(LocalTypeBinding localType) {
+	if (this.localTypeCount == 0) {
+		this.localTypes = new LocalTypeBinding[5];
+	} else if (this.localTypeCount == this.localTypes.length) {
+		System.arraycopy(this.localTypes, 0, (this.localTypes = new LocalTypeBinding[this.localTypeCount * 2]), 0, this.localTypeCount);
+	}
+	this.localTypes[this.localTypeCount++] = localType;
+}
+
+public void resolve() {
+	int startingTypeIndex = 0;
+	boolean isPackageInfo = isPackageInfo();
+	if (this.types != null && isPackageInfo) {
+		// resolve synthetic type declaration
+		final TypeDeclaration syntheticTypeDeclaration = this.types[0];
+		// set empty javadoc to avoid missing warning (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=95286)
+		if (syntheticTypeDeclaration.javadoc == null) {
+			syntheticTypeDeclaration.javadoc = new Javadoc(syntheticTypeDeclaration.declarationSourceStart, syntheticTypeDeclaration.declarationSourceStart);
+		}
+		syntheticTypeDeclaration.resolve(this.scope);
+		/*
+		 * resolve javadoc package if any, skip this step if we don't have a valid scope due to an earlier error (bug 252555)
+		 * we do it now as the javadoc in the fake type won't be resolved. The peculiar usage of MethodScope to resolve the
+		 * package level javadoc is because the CU level resolve method	is a NOP to mimic Javadoc's behavior and can't be used
+		 * as such.
+		 */
+		if (this.javadoc != null && syntheticTypeDeclaration.staticInitializerScope != null) {
+			this.javadoc.resolve(syntheticTypeDeclaration.staticInitializerScope);
+		}
+		startingTypeIndex = 1;
+	} else {
+		// resolve compilation unit javadoc package if any
+		if (this.javadoc != null) {
+			this.javadoc.resolve(this.scope);
+		}
+	}
+	if (this.currentPackage != null && this.currentPackage.annotations != null && !isPackageInfo) {
+		this.scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
+	}
+	try {
+		if (this.types != null) {
+			for (int i = startingTypeIndex, count = this.types.length; i < count; i++) {
+				this.types[i].resolve(this.scope);
+			}
+		}
+		if (!this.compilationResult.hasMandatoryErrors()) checkUnusedImports();
+		reportNLSProblems();
+	} catch (AbortCompilationUnit e) {
+		this.ignoreFurtherInvestigation = true;
+		return;
+	}
+}
+
+private void reportNLSProblems() {
+	if (this.nlsTags != null || this.stringLiterals != null) {
+		final int stringLiteralsLength = this.stringLiteralsPtr;
+		final int nlsTagsLength = this.nlsTags == null ? 0 : this.nlsTags.length;
+		if (stringLiteralsLength == 0) {
+			if (nlsTagsLength != 0) {
+				for (int i = 0; i < nlsTagsLength; i++) {
+					NLSTag tag = this.nlsTags[i];
+					if (tag != null) {
+						this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
+					}
+				}
+			}
+		} else if (nlsTagsLength == 0) {
+			// resize string literals
+			if (this.stringLiterals.length != stringLiteralsLength) {
+				System.arraycopy(this.stringLiterals, 0, (this.stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength);
+			}
+			Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR);
+			for (int i = 0; i < stringLiteralsLength; i++) {
+				this.scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]);
+			}
+		} else {
+			// need to iterate both arrays to find non matching elements
+			if (this.stringLiterals.length != stringLiteralsLength) {
+				System.arraycopy(this.stringLiterals, 0, (this.stringLiterals = new StringLiteral[stringLiteralsLength]), 0, stringLiteralsLength);
+			}
+			Arrays.sort(this.stringLiterals, STRING_LITERAL_COMPARATOR);
+			int indexInLine = 1;
+			int lastLineNumber = -1;
+			StringLiteral literal = null;
+			int index = 0;
+			int i = 0;
+			stringLiteralsLoop: for (; i < stringLiteralsLength; i++) {
+				literal = this.stringLiterals[i];
+				final int literalLineNumber = literal.lineNumber;
+				if (lastLineNumber != literalLineNumber) {
+					indexInLine = 1;
+					lastLineNumber = literalLineNumber;
+				} else {
+					indexInLine++;
+				}
+				if (index < nlsTagsLength) {
+					nlsTagsLoop: for (; index < nlsTagsLength; index++) {
+						NLSTag tag = this.nlsTags[index];
+						if (tag == null) continue nlsTagsLoop;
+						int tagLineNumber = tag.lineNumber;
+						if (literalLineNumber < tagLineNumber) {
+							this.scope.problemReporter().nonExternalizedStringLiteral(literal);
+							continue stringLiteralsLoop;
+						} else if (literalLineNumber == tagLineNumber) {
+							if (tag.index == indexInLine) {
+								this.nlsTags[index] = null;
+								index++;
+								continue stringLiteralsLoop;
+							} else {
+								nlsTagsLoop2: for (int index2 = index + 1; index2 < nlsTagsLength; index2++) {
+									NLSTag tag2 = this.nlsTags[index2];
+									if (tag2 == null) continue nlsTagsLoop2;
+									int tagLineNumber2 = tag2.lineNumber;
+									if (literalLineNumber == tagLineNumber2) {
+										if (tag2.index == indexInLine) {
+											this.nlsTags[index2] = null;
+											continue stringLiteralsLoop;
+										} else {
+											continue nlsTagsLoop2;
+										}
+									} else {
+										this.scope.problemReporter().nonExternalizedStringLiteral(literal);
+										continue stringLiteralsLoop;
+									}
+								}
+								this.scope.problemReporter().nonExternalizedStringLiteral(literal);
+								continue stringLiteralsLoop;
+							}
+						} else {
+							this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
+							continue nlsTagsLoop;
+						}
+					}
+				}
+				// all nls tags have been processed, so remaining string literals are not externalized
+				break stringLiteralsLoop;
+			}
+			for (; i < stringLiteralsLength; i++) {
+				this.scope.problemReporter().nonExternalizedStringLiteral(this.stringLiterals[i]);
+			}
+			if (index < nlsTagsLength) {
+				for (; index < nlsTagsLength; index++) {
+					NLSTag tag = this.nlsTags[index];
+					if (tag != null) {
+						this.scope.problemReporter().unnecessaryNLSTags(tag.start, tag.end);
+					}
+				}
+			}
+		}
+	}
+}
+
+public void tagAsHavingErrors() {
+	this.ignoreFurtherInvestigation = true;
+}
+
+public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
+	// Nothing to do for this context;
+}
+
+public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope) {
+	if (this.ignoreFurtherInvestigation)
+		return;
+	try {
+		if (visitor.visit(this, this.scope)) {
+			if (this.types != null && isPackageInfo()) {
+	            // resolve synthetic type declaration
+				final TypeDeclaration syntheticTypeDeclaration = this.types[0];
+				// resolve javadoc package if any
+				final MethodScope methodScope = syntheticTypeDeclaration.staticInitializerScope;
+				// Don't traverse in null scope and invite trouble a la bug 252555.
+				if (this.javadoc != null && methodScope != null) {
+					this.javadoc.traverse(visitor, methodScope);
+				}
+				// Don't traverse in null scope and invite trouble a la bug 252555.
+				if (this.currentPackage != null && methodScope != null) {
+					final Annotation[] annotations = this.currentPackage.annotations;
+					if (annotations != null) {
+						int annotationsLength = annotations.length;
+						for (int i = 0; i < annotationsLength; i++) {
+							annotations[i].traverse(visitor, methodScope);
+						}
+					}
+				}
+			}
+			if (this.currentPackage != null) {
+				this.currentPackage.traverse(visitor, this.scope);
+			}
+			if (this.imports != null) {
+				int importLength = this.imports.length;
+				for (int i = 0; i < importLength; i++) {
+					this.imports[i].traverse(visitor, this.scope);
+				}
+			}
+			if (this.types != null) {
+				int typesLength = this.types.length;
+				for (int i = 0; i < typesLength; i++) {
+					this.types[i].traverse(visitor, this.scope);
+				}
+			}
+		}
+		visitor.endVisit(this, this.scope);
+	} catch (AbortCompilationUnit e) {
+		// ignore
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
new file mode 100644
index 0000000..418b3aa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *     Jesper S Moller - Contributions for
+ *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class CompoundAssignment extends Assignment implements OperatorIds {
+	public int operator;
+	public int preAssignImplicitConversion;
+
+	//  var op exp is equivalent to var = (varType) var op exp
+	// assignmentImplicitConversion stores the cast needed for the assignment
+
+	public CompoundAssignment(Expression lhs, Expression expression,int operator, int sourceEnd) {
+		//lhs is always a reference by construction ,
+		//but is build as an expression ==> the checkcast cannot fail
+
+		super(lhs, expression, sourceEnd);
+		lhs.bits &= ~IsStrictlyAssigned; // tag lhs as NON assigned - it is also a read access
+		lhs.bits |= IsCompoundAssigned; // tag lhs as assigned by compound
+		this.operator = operator ;
+	}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext,
+		FlowInfo flowInfo) {
+	// record setting a variable: various scenarii are possible, setting an array reference,
+	// a field reference, a blank final field reference, a field of an enclosing instance or
+	// just a local variable.
+	if (this.resolvedType.id != T_JavaLangString) {
+		this.lhs.checkNPE(currentScope, flowContext, flowInfo);
+		// account for exceptions thrown by any arithmetics:
+		flowContext.recordAbruptExit();
+	}
+	flowInfo = ((Reference) this.lhs).analyseAssignment(currentScope, flowContext, flowInfo, this, true).unconditionalInits();
+	if (this.resolvedType.id == T_JavaLangString) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=339250
+		LocalVariableBinding local = this.lhs.localVariableBinding();
+		if (local != null) {
+			// compound assignment results in a definitely non null value for String
+			flowInfo.markAsDefinitelyNonNull(local);
+			flowContext.markFinallyNullStatus(local, FlowInfo.NON_NULL);
+		}
+	}
+	return flowInfo;
+}
+
+	public boolean checkCastCompatibility() {
+		return true;
+	}
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		// various scenarii are possible, setting an array reference,
+		// a field reference, a blank final field reference, a field of an enclosing instance or
+		// just a local variable.
+
+		int pc = codeStream.position;
+		 ((Reference) this.lhs).generateCompoundAssignment(currentScope, codeStream, this.expression, this.operator, this.preAssignImplicitConversion, valueRequired);
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	return FlowInfo.NON_NULL;
+	// we may have complained on checkNPE, but we avoid duplicate error
+}
+
+	public String operatorToString() {
+		switch (this.operator) {
+			case PLUS :
+				return "+="; //$NON-NLS-1$
+			case MINUS :
+				return "-="; //$NON-NLS-1$
+			case MULTIPLY :
+				return "*="; //$NON-NLS-1$
+			case DIVIDE :
+				return "/="; //$NON-NLS-1$
+			case AND :
+				return "&="; //$NON-NLS-1$
+			case OR :
+				return "|="; //$NON-NLS-1$
+			case XOR :
+				return "^="; //$NON-NLS-1$
+			case REMAINDER :
+				return "%="; //$NON-NLS-1$
+			case LEFT_SHIFT :
+				return "<<="; //$NON-NLS-1$
+			case RIGHT_SHIFT :
+				return ">>="; //$NON-NLS-1$
+			case UNSIGNED_RIGHT_SHIFT :
+				return ">>>="; //$NON-NLS-1$
+		}
+		return "unknown operator"; //$NON-NLS-1$
+	}
+
+	public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+
+		this.lhs.printExpression(indent, output).append(' ').append(operatorToString()).append(' ');
+		return this.expression.printExpression(0, output) ;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		this.constant = Constant.NotAConstant;
+		if (!(this.lhs instanceof Reference) || this.lhs.isThis()) {
+			scope.problemReporter().expressionShouldBeAVariable(this.lhs);
+			return null;
+		}
+		boolean expressionIsCast = this.expression instanceof CastExpression;
+		if (expressionIsCast)
+			this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+		TypeBinding originalLhsType = this.lhs.resolveType(scope);
+		TypeBinding originalExpressionType = this.expression.resolveType(scope);
+		if (originalLhsType == null || originalExpressionType == null)
+			return null;
+		// autoboxing support
+		LookupEnvironment env = scope.environment();
+		TypeBinding lhsType = originalLhsType, expressionType = originalExpressionType;
+		boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		boolean unboxedLhs = false;
+		if (use15specifics) {
+			if (!lhsType.isBaseType() && expressionType.id != T_JavaLangString && expressionType.id != T_null) {
+				TypeBinding unboxedType = env.computeBoxingType(lhsType);
+				if (unboxedType != lhsType) {
+					lhsType = unboxedType;
+					unboxedLhs = true;
+				}
+			}
+			if (!expressionType.isBaseType() && lhsType.id != T_JavaLangString  && lhsType.id != T_null) {
+				expressionType = env.computeBoxingType(expressionType);
+			}
+		}
+
+		if (restrainUsageToNumericTypes() && !lhsType.isNumericType()) {
+			scope.problemReporter().operatorOnlyValidOnNumericType(this, lhsType, expressionType);
+			return null;
+		}
+		int lhsID = lhsType.id;
+		int expressionID = expressionType.id;
+		if (lhsID > 15 || expressionID > 15) {
+			if (lhsID != T_JavaLangString) { // String += Thread is valid whereas Thread += String  is not
+				scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+				return null;
+			}
+			expressionID = T_JavaLangObject; // use the Object has tag table
+		}
+
+		// the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8     <<4        <<0
+
+		// the conversion is stored INTO the reference (info needed for the code gen)
+		int result = OperatorExpression.OperatorSignatures[this.operator][ (lhsID << 4) + expressionID];
+		if (result == T_undefined) {
+			scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+			return null;
+		}
+		if (this.operator == PLUS){
+			if(lhsID == T_JavaLangObject && (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7)) {
+				// <Object> += <String> is illegal (39248) for compliance < 1.7
+				scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+				return null;
+			} else {
+				// <int | boolean> += <String> is illegal
+				if ((lhsType.isNumericType() || lhsID == T_boolean) && !expressionType.isNumericType()){
+					scope.problemReporter().invalidOperator(this, lhsType, expressionType);
+					return null;
+				}
+			}
+		}
+		TypeBinding resultType = TypeBinding.wellKnownType(scope, result & 0x0000F);
+		if (checkCastCompatibility()) {
+			if (originalLhsType.id != T_JavaLangString && resultType.id != T_JavaLangString) {
+				if (!checkCastTypesCompatibility(scope, originalLhsType, resultType, null)) {
+					scope.problemReporter().invalidOperator(this, originalLhsType, expressionType);
+					return null;
+				}
+			}
+		}
+		this.lhs.computeConversion(scope, TypeBinding.wellKnownType(scope, (result >>> 16) & 0x0000F), originalLhsType);
+		this.expression.computeConversion(scope, TypeBinding.wellKnownType(scope, (result >>> 8) & 0x0000F), originalExpressionType);
+		this.preAssignImplicitConversion =  (unboxedLhs ? BOXING : 0) | (lhsID << 4) | (result & 0x0000F);
+		if (unboxedLhs) scope.problemReporter().autoboxing(this, lhsType, originalLhsType);
+		if (expressionIsCast)
+			CastExpression.checkNeedForArgumentCasts(scope, this.operator, result, this.lhs, originalLhsType.id, false, this.expression, originalExpressionType.id, true);
+		return this.resolvedType = originalLhsType;
+	}
+
+	public boolean restrainUsageToNumericTypes(){
+		return false ;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			this.lhs.traverse(visitor, scope);
+			this.expression.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..c892b9d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -0,0 +1,679 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for
+ *     						bug 133125 - [compiler][null] need to report the null status of expressions and analyze them simultaneously
+ *     						bug 292478 - Report potentially null across variable assignment
+ * 							bug 324178 - [null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
+ * 							bug 354554 - [null] conditional with redundant condition yields weak error message
+ *     						bug 349326 - [1.7] new warning for missing try-with-resources
+ *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *							bug 383368 - [compiler][null] syntactic null analysis for field references
+ *							bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ConditionalExpression extends OperatorExpression {
+
+	public Expression condition, valueIfTrue, valueIfFalse;
+	public Constant optimizedBooleanConstant;
+	public Constant optimizedIfTrueConstant;
+	public Constant optimizedIfFalseConstant;
+
+	// for local variables table attributes
+	int trueInitStateIndex = -1;
+	int falseInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+	
+	// we compute and store the null status during analyseCode (https://bugs.eclipse.org/324178):
+	private int nullStatus = FlowInfo.UNKNOWN;
+	private TypeBinding expectedType;
+	private ExpressionContext expressionContext = VANILLA_CONTEXT;
+	private boolean isPolyExpression = false;
+	private TypeBinding originalValueIfTrueType;
+	private TypeBinding originalValueIfFalseType;
+
+	public ConditionalExpression(
+		Expression condition,
+		Expression valueIfTrue,
+		Expression valueIfFalse) {
+		this.condition = condition;
+		this.valueIfTrue = valueIfTrue;
+		this.valueIfFalse = valueIfFalse;
+		this.sourceStart = condition.sourceStart;
+		this.sourceEnd = valueIfFalse.sourceEnd;
+	}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext,
+			FlowInfo flowInfo) {
+		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+		Constant cst = this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+		int mode = flowInfo.reachMode();
+		flowInfo = this.condition.analyseCode(currentScope, flowContext, flowInfo, cst == Constant.NotAConstant);
+
+		flowContext.conditionalLevel++;
+
+		// process the if-true part
+		FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy();
+		if (isConditionOptimizedFalse) {
+			if ((mode & FlowInfo.UNREACHABLE) == 0) {
+				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+			}
+			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
+				this.valueIfTrue.complainIfUnreachable(trueFlowInfo, currentScope, initialComplaintLevel, false);
+			}
+		}
+		this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo);
+		trueFlowInfo = this.valueIfTrue.analyseCode(currentScope, flowContext, trueFlowInfo);
+		this.valueIfTrue.checkNPEbyUnboxing(currentScope, flowContext, trueFlowInfo);
+
+		// may need to fetch this null status before expireNullCheckedFieldInfo():
+		int preComputedTrueNullStatus = -1;
+		if (currentScope.compilerOptions().enableSyntacticNullAnalysisForFields) {
+			preComputedTrueNullStatus = this.valueIfTrue.nullStatus(trueFlowInfo, flowContext);
+			// wipe information that was meant only for valueIfTrue:
+			flowContext.expireNullCheckedFieldInfo();
+		}
+
+		// process the if-false part
+		FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy();
+		if (isConditionOptimizedTrue) {
+			if ((mode & FlowInfo.UNREACHABLE) == 0) {
+				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+			}
+			if (!isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement) {
+				this.valueIfFalse.complainIfUnreachable(falseFlowInfo, currentScope, initialComplaintLevel, true);
+			}
+		}
+		this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo);
+		falseFlowInfo = this.valueIfFalse.analyseCode(currentScope, flowContext, falseFlowInfo);
+		this.valueIfFalse.checkNPEbyUnboxing(currentScope, flowContext, falseFlowInfo);
+
+		flowContext.conditionalLevel--;
+		
+		// merge if-true & if-false initializations
+		FlowInfo mergedInfo;
+		if (isConditionOptimizedTrue){
+			mergedInfo = trueFlowInfo.addPotentialInitializationsFrom(falseFlowInfo);
+			if (preComputedTrueNullStatus != -1) {
+				this.nullStatus = preComputedTrueNullStatus;
+			} else { 
+				this.nullStatus = this.valueIfTrue.nullStatus(trueFlowInfo, flowContext);
+			}
+		} else if (isConditionOptimizedFalse) {
+			mergedInfo = falseFlowInfo.addPotentialInitializationsFrom(trueFlowInfo);
+			this.nullStatus = this.valueIfFalse.nullStatus(falseFlowInfo, flowContext);
+		} else {
+			// this block must meet two conflicting requirements (see https://bugs.eclipse.org/324178):
+			// (1) For null analysis of "Object o2 = (o1 != null) ? o1 : new Object();" we need to distinguish
+			//     the paths *originating* from the evaluation of the condition to true/false respectively.
+			//     This is used to determine the possible null status of the entire conditional expression.
+			// (2) For definite assignment analysis (JLS 16.1.5) of boolean conditional expressions of the form
+			//     "if (c1 ? expr1 : expr2) use(v);" we need to check whether any variable v will be definitely
+			//     assigned whenever the entire conditional expression evaluates to true (to reach the then branch).
+			//     I.e., we need to collect flowInfo *towards* the overall outcome true/false 
+			//     (regardless of the evaluation of the condition).
+			
+			// to support (1) use the infos of both branches originating from the condition for computing the nullStatus:
+			computeNullStatus(preComputedTrueNullStatus, trueFlowInfo, falseFlowInfo, flowContext);
+			
+			// to support (2) we split the true/false branches according to their inner structure. Consider this:
+			// if (b ? false : (true && (v = false))) return v; -- ok
+			// - expr1 ("false") has no path towards true (mark as unreachable)
+			// - expr2 ("(true && (v = false))") has a branch towards true on which v is assigned.
+			//   -> merging these two branches yields: v is assigned
+			// - the paths towards false are irrelevant since the enclosing if has no else.
+			cst = this.optimizedIfTrueConstant;
+			boolean isValueIfTrueOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
+			boolean isValueIfTrueOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+			cst = this.optimizedIfFalseConstant;
+			boolean isValueIfFalseOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
+			boolean isValueIfFalseOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+			UnconditionalFlowInfo trueFlowTowardsTrue = trueFlowInfo.initsWhenTrue().unconditionalCopy();
+			UnconditionalFlowInfo falseFlowTowardsTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
+			UnconditionalFlowInfo trueFlowTowardsFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
+			UnconditionalFlowInfo falseFlowTowardsFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
+			if (isValueIfTrueOptimizedFalse) {
+				trueFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);				
+			}
+			if (isValueIfFalseOptimizedFalse) {
+				falseFlowTowardsTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
+			}
+			if (isValueIfTrueOptimizedTrue) {
+				trueFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
+			}
+			if (isValueIfFalseOptimizedTrue) {
+				falseFlowTowardsFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);	
+			}
+			mergedInfo =
+				FlowInfo.conditional(
+					trueFlowTowardsTrue.mergedWith(falseFlowTowardsTrue),
+					trueFlowTowardsFalse.mergedWith(falseFlowTowardsFalse));
+		}
+		this.mergedInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(mergedInfo);
+		mergedInfo.setReachMode(mode);
+		return mergedInfo;
+	}
+
+	public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+		if ((this.nullStatus & FlowInfo.NULL) != 0)
+			scope.problemReporter().expressionNullReference(this);
+		else if ((this.nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+			scope.problemReporter().expressionPotentialNullReference(this);
+		return true; // all checking done
+	}
+
+	private void computeNullStatus(int ifTrueNullStatus, FlowInfo trueBranchInfo, FlowInfo falseBranchInfo, FlowContext flowContext) {
+		// given that the condition cannot be optimized to a constant 
+		// we now merge the nullStatus from both branches:
+		if (ifTrueNullStatus == -1) { // has this status been pre-computed?
+			ifTrueNullStatus = this.valueIfTrue.nullStatus(trueBranchInfo, flowContext);
+		}
+		int ifFalseNullStatus = this.valueIfFalse.nullStatus(falseBranchInfo, flowContext);
+
+		if (ifTrueNullStatus == ifFalseNullStatus) {
+			this.nullStatus = ifTrueNullStatus;
+			return;
+		}
+		if (trueBranchInfo.reachMode() != FlowInfo.REACHABLE) {
+			this.nullStatus = ifFalseNullStatus;
+			return;
+		}
+		if (falseBranchInfo.reachMode() != FlowInfo.REACHABLE) {
+			this.nullStatus = ifTrueNullStatus;
+			return;
+		}
+
+		// 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)
+			this.nullStatus = status;
+	}
+
+	/**
+	 * Code generation for the conditional operator ?:
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	*/
+	public void generateCode(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		boolean valueRequired) {
+
+		int pc = codeStream.position;
+		BranchLabel endifLabel, falseLabel;
+		if (this.constant != Constant.NotAConstant) {
+			if (valueRequired)
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+		Constant cst = this.condition.optimizedBooleanConstant();
+		boolean needTruePart = !(cst != Constant.NotAConstant && cst.booleanValue() == false);
+		boolean needFalsePart = 	!(cst != Constant.NotAConstant && cst.booleanValue() == true);
+		endifLabel = new BranchLabel(codeStream);
+
+		// Generate code for the condition
+		falseLabel = new BranchLabel(codeStream);
+		falseLabel.tagBits |= BranchLabel.USED;
+		this.condition.generateOptimizedBoolean(
+			currentScope,
+			codeStream,
+			null,
+			falseLabel,
+			cst == Constant.NotAConstant);
+
+		if (this.trueInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(
+				currentScope,
+				this.trueInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.trueInitStateIndex);
+		}
+		// Then code generation
+		if (needTruePart) {
+			this.valueIfTrue.generateCode(currentScope, codeStream, valueRequired);
+			if (needFalsePart) {
+				// Jump over the else part
+				int position = codeStream.position;
+				codeStream.goto_(endifLabel);
+				codeStream.recordPositionsFrom(position, this.valueIfTrue.sourceEnd);
+				// Tune codestream stack size
+				if (valueRequired) {
+					switch(this.resolvedType.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.decrStackSize(2);
+							break;
+						default :
+							codeStream.decrStackSize(1);
+							break;
+					}
+				}
+			}
+		}
+		if (needFalsePart) {
+			if (this.falseInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(
+					currentScope,
+					this.falseInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.falseInitStateIndex);
+			}
+			if (falseLabel.forwardReferenceCount() > 0) {
+				falseLabel.place();
+			}
+			this.valueIfFalse.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				codeStream.recordExpressionType(this.resolvedType);
+			}
+			if (needTruePart) {
+				// End of if statement
+				endifLabel.place();
+			}
+		}
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(
+				currentScope,
+				this.mergedInitStateIndex);
+		}
+		// implicit conversion
+		if (valueRequired)
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	/**
+	 * Optimized boolean code generation for the conditional operator ?:
+	*/
+	public void generateOptimizedBoolean(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		BranchLabel trueLabel,
+		BranchLabel falseLabel,
+		boolean valueRequired) {
+
+		int pc = codeStream.position;
+
+		if ((this.constant != Constant.NotAConstant) && (this.constant.typeID() == T_boolean) // constant
+			|| ((this.valueIfTrue.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_boolean) { // non boolean values
+			super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			return;
+		}
+		Constant cst = this.condition.constant;
+		Constant condCst = this.condition.optimizedBooleanConstant();
+		boolean needTruePart =
+			!(((cst != Constant.NotAConstant) && (cst.booleanValue() == false))
+				|| ((condCst != Constant.NotAConstant) && (condCst.booleanValue() == false)));
+		boolean needFalsePart =
+			!(((cst != Constant.NotAConstant) && (cst.booleanValue() == true))
+				|| ((condCst != Constant.NotAConstant) && (condCst.booleanValue() == true)));
+
+		BranchLabel internalFalseLabel, endifLabel = new BranchLabel(codeStream);
+
+		// Generate code for the condition
+		boolean needConditionValue = (cst == Constant.NotAConstant) && (condCst == Constant.NotAConstant);
+		this.condition.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				null,
+				internalFalseLabel = new BranchLabel(codeStream),
+				needConditionValue);
+
+		if (this.trueInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(
+				currentScope,
+				this.trueInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.trueInitStateIndex);
+		}
+		// Then code generation
+		if (needTruePart) {
+			this.valueIfTrue.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+
+			if (needFalsePart) {
+				// Jump over the else part
+				JumpEndif: {
+					if (falseLabel == null) {
+						if (trueLabel != null) {
+							// implicit falling through the FALSE case
+							cst = this.optimizedIfTrueConstant;
+							boolean isValueIfTrueOptimizedTrue = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == true;
+							if (isValueIfTrueOptimizedTrue) break JumpEndif; // no need to jump over, since branched to true already
+						}
+					} else {
+						// implicit falling through the TRUE case
+						if (trueLabel == null) {
+							cst = this.optimizedIfTrueConstant;
+							boolean isValueIfTrueOptimizedFalse = cst != null && cst != Constant.NotAConstant && cst.booleanValue() == false;
+							if (isValueIfTrueOptimizedFalse) break JumpEndif; // no need to jump over, since branched to false already
+						} else {
+							// no implicit fall through TRUE/FALSE --> should never occur
+						}
+					}
+					int position = codeStream.position;
+					codeStream.goto_(endifLabel);
+					codeStream.recordPositionsFrom(position, this.valueIfTrue.sourceEnd);
+				}
+				// No need to decrement codestream stack size
+				// since valueIfTrue was already consumed by branch bytecode
+			}
+		}
+		if (needFalsePart) {
+			internalFalseLabel.place();
+			if (this.falseInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.falseInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.falseInitStateIndex);
+			}
+			this.valueIfFalse.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+
+			// End of if statement
+			endifLabel.place();
+		}
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		// no implicit conversion for boolean values
+		codeStream.recordPositionsFrom(pc, this.sourceEnd);
+	}
+
+	public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		return this.nullStatus;
+	}
+
+	public Constant optimizedBooleanConstant() {
+
+		return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant;
+	}
+
+	public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+
+		this.condition.printExpression(indent, output).append(" ? "); //$NON-NLS-1$
+		this.valueIfTrue.printExpression(0, output).append(" : "); //$NON-NLS-1$
+		return this.valueIfFalse.printExpression(0, output);
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		// JLS3 15.25
+		LookupEnvironment env = scope.environment();
+		final long sourceLevel = scope.compilerOptions().sourceLevel;
+		boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
+		boolean use18specifics = sourceLevel >= ClassFileConstants.JDK1_8;
+		
+		if (use18specifics) {
+			if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) {
+				this.valueIfTrue.setExpressionContext(this.expressionContext);
+				this.valueIfTrue.setExpectedType(this.expectedType);
+				this.valueIfFalse.setExpressionContext(this.expressionContext);
+				this.valueIfFalse.setExpectedType(this.expectedType);
+			}
+		}
+		
+		if (this.constant != Constant.NotAConstant) {
+			this.constant = Constant.NotAConstant;
+
+			TypeBinding conditionType = this.condition.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
+			this.condition.computeConversion(scope, TypeBinding.BOOLEAN, conditionType);
+
+			if (this.valueIfTrue instanceof CastExpression) this.valueIfTrue.bits |= DisableUnnecessaryCastCheck; // will check later on
+			this.originalValueIfTrueType = this.valueIfTrue.resolveType(scope);
+
+			if (this.valueIfFalse instanceof CastExpression) this.valueIfFalse.bits |= DisableUnnecessaryCastCheck; // will check later on
+			this.originalValueIfFalseType = this.valueIfFalse.resolveType(scope);
+
+			if (conditionType == null || this.originalValueIfTrueType == null || this.originalValueIfFalseType == null)
+				return null;
+			
+			if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE || this.originalValueIfFalseType.kind() == Binding.POLY_TYPE) {
+				this.isPolyExpression = true;
+				return new PolyTypeBinding(this);
+			}
+		} else {
+			if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE)
+				this.originalValueIfTrueType = this.valueIfTrue.resolveType(scope);
+			if (this.originalValueIfFalseType.kind() == Binding.POLY_TYPE)
+				this.originalValueIfFalseType = this.valueIfFalse.resolveType(scope);
+		}
+		
+		TypeBinding valueIfTrueType = this.originalValueIfTrueType;
+		TypeBinding valueIfFalseType = this.originalValueIfFalseType;
+		if (use15specifics && valueIfTrueType != valueIfFalseType) {
+			if (valueIfTrueType.isBaseType()) {
+				if (valueIfFalseType.isBaseType()) {
+					// bool ? baseType : baseType
+					if (valueIfTrueType == TypeBinding.NULL) {  // bool ? null : 12 --> Integer
+						valueIfFalseType = env.computeBoxingType(valueIfFalseType); // boxing
+					} else if (valueIfFalseType == TypeBinding.NULL) {  // bool ? 12 : null --> Integer
+						valueIfTrueType = env.computeBoxingType(valueIfTrueType); // boxing
+					}
+				} else {
+					// bool ? baseType : nonBaseType
+					TypeBinding unboxedIfFalseType = valueIfFalseType.isBaseType() ? valueIfFalseType : env.computeBoxingType(valueIfFalseType);
+					if (valueIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
+						valueIfFalseType = unboxedIfFalseType; // unboxing
+					} else if (valueIfTrueType != TypeBinding.NULL) {  // bool ? 12 : new Integer(12) --> int
+						valueIfFalseType = env.computeBoxingType(valueIfFalseType); // unboxing
+					}
+				}
+			} else if (valueIfFalseType.isBaseType()) {
+					// bool ? nonBaseType : baseType
+					TypeBinding unboxedIfTrueType = valueIfTrueType.isBaseType() ? valueIfTrueType : env.computeBoxingType(valueIfTrueType);
+					if (unboxedIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) {
+						valueIfTrueType = unboxedIfTrueType; // unboxing
+					} else if (valueIfFalseType != TypeBinding.NULL) {  // bool ? new Integer(12) : 12 --> int
+						valueIfTrueType = env.computeBoxingType(valueIfTrueType); // unboxing
+					}
+			} else {
+					// bool ? nonBaseType : nonBaseType
+					TypeBinding unboxedIfTrueType = env.computeBoxingType(valueIfTrueType);
+					TypeBinding unboxedIfFalseType = env.computeBoxingType(valueIfFalseType);
+					if (unboxedIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
+						valueIfTrueType = unboxedIfTrueType;
+						valueIfFalseType = unboxedIfFalseType;
+					}
+			}
+		}
+		// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible
+		Constant condConstant, trueConstant, falseConstant;
+		if ((condConstant = this.condition.constant) != Constant.NotAConstant
+			&& (trueConstant = this.valueIfTrue.constant) != Constant.NotAConstant
+			&& (falseConstant = this.valueIfFalse.constant) != Constant.NotAConstant) {
+			// all terms are constant expression so we can propagate the constant
+			// from valueIFTrue or valueIfFalse to the receiver constant
+			this.constant = condConstant.booleanValue() ? trueConstant : falseConstant;
+		}
+		if (valueIfTrueType == valueIfFalseType) { // harmed the implicit conversion
+			this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
+			this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
+			if (valueIfTrueType == TypeBinding.BOOLEAN) {
+				this.optimizedIfTrueConstant = this.valueIfTrue.optimizedBooleanConstant();
+				this.optimizedIfFalseConstant = this.valueIfFalse.optimizedBooleanConstant();
+				if (this.optimizedIfTrueConstant != Constant.NotAConstant
+						&& this.optimizedIfFalseConstant != Constant.NotAConstant
+						&& this.optimizedIfTrueConstant.booleanValue() == this.optimizedIfFalseConstant.booleanValue()) {
+					// a ? true : true  /   a ? false : false
+					this.optimizedBooleanConstant = this.optimizedIfTrueConstant;
+				} else if ((condConstant = this.condition.optimizedBooleanConstant()) != Constant.NotAConstant) { // Propagate the optimized boolean constant if possible
+					this.optimizedBooleanConstant = condConstant.booleanValue()
+						? this.optimizedIfTrueConstant
+						: this.optimizedIfFalseConstant;
+				}
+			}
+			return this.resolvedType = valueIfTrueType;
+		}
+		// Determine the return type depending on argument types
+		// Numeric types
+		if (valueIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) {
+			// (Short x Byte) or (Byte x Short)"
+			if ((valueIfTrueType == TypeBinding.BYTE && valueIfFalseType == TypeBinding.SHORT)
+				|| (valueIfTrueType == TypeBinding.SHORT && valueIfFalseType == TypeBinding.BYTE)) {
+				this.valueIfTrue.computeConversion(scope, TypeBinding.SHORT, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, TypeBinding.SHORT, this.originalValueIfFalseType);
+				return this.resolvedType = TypeBinding.SHORT;
+			}
+			// <Byte|Short|Char> x constant(Int)  ---> <Byte|Short|Char>   and reciprocally
+			if ((valueIfTrueType == TypeBinding.BYTE || valueIfTrueType == TypeBinding.SHORT || valueIfTrueType == TypeBinding.CHAR)
+					&& (valueIfFalseType == TypeBinding.INT
+						&& this.valueIfFalse.isConstantValueOfTypeAssignableToType(valueIfFalseType, valueIfTrueType))) {
+				this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, valueIfTrueType, this.originalValueIfFalseType);
+				return this.resolvedType = valueIfTrueType;
+			}
+			if ((valueIfFalseType == TypeBinding.BYTE
+					|| valueIfFalseType == TypeBinding.SHORT
+					|| valueIfFalseType == TypeBinding.CHAR)
+					&& (valueIfTrueType == TypeBinding.INT
+						&& this.valueIfTrue.isConstantValueOfTypeAssignableToType(valueIfTrueType, valueIfFalseType))) {
+				this.valueIfTrue.computeConversion(scope, valueIfFalseType, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
+				return this.resolvedType = valueIfFalseType;
+			}
+			// Manual binary numeric promotion
+			// int
+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_int)
+					&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_int)) {
+				this.valueIfTrue.computeConversion(scope, TypeBinding.INT, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, TypeBinding.INT, this.originalValueIfFalseType);
+				return this.resolvedType = TypeBinding.INT;
+			}
+			// long
+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_long)
+					&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_long)) {
+				this.valueIfTrue.computeConversion(scope, TypeBinding.LONG, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, TypeBinding.LONG, this.originalValueIfFalseType);
+				return this.resolvedType = TypeBinding.LONG;
+			}
+			// float
+			if (BaseTypeBinding.isNarrowing(valueIfTrueType.id, T_float)
+					&& BaseTypeBinding.isNarrowing(valueIfFalseType.id, T_float)) {
+				this.valueIfTrue.computeConversion(scope, TypeBinding.FLOAT, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, TypeBinding.FLOAT, this.originalValueIfFalseType);
+				return this.resolvedType = TypeBinding.FLOAT;
+			}
+			// double
+			this.valueIfTrue.computeConversion(scope, TypeBinding.DOUBLE, this.originalValueIfTrueType);
+			this.valueIfFalse.computeConversion(scope, TypeBinding.DOUBLE, this.originalValueIfFalseType);
+			return this.resolvedType = TypeBinding.DOUBLE;
+		}
+		// Type references (null null is already tested)
+		if (valueIfTrueType.isBaseType() && valueIfTrueType != TypeBinding.NULL) {
+			if (use15specifics) {
+				valueIfTrueType = env.computeBoxingType(valueIfTrueType);
+			} else {
+				scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
+				return null;
+			}
+		}
+		if (valueIfFalseType.isBaseType() && valueIfFalseType != TypeBinding.NULL) {
+			if (use15specifics) {
+				valueIfFalseType = env.computeBoxingType(valueIfFalseType);
+			} else {
+				scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
+				return null;
+			}
+		}
+		if (use15specifics) {
+			// >= 1.5 : LUB(operand types) must exist
+			TypeBinding commonType = null;
+			if (valueIfTrueType == TypeBinding.NULL) {
+				commonType = valueIfFalseType;
+			} else if (valueIfFalseType == TypeBinding.NULL) {
+				commonType = valueIfTrueType;
+			} else {
+				commonType = scope.lowerUpperBound(new TypeBinding[] { valueIfTrueType, valueIfFalseType });
+			}
+			if (commonType != null) {
+				this.valueIfTrue.computeConversion(scope, commonType, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, commonType, this.originalValueIfFalseType);
+				return this.resolvedType = commonType.capture(scope, this.sourceEnd);
+			}
+		} else {
+			// < 1.5 : one operand must be convertible to the other
+			if (valueIfFalseType.isCompatibleWith(valueIfTrueType)) {
+				this.valueIfTrue.computeConversion(scope, valueIfTrueType, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, valueIfTrueType, this.originalValueIfFalseType);
+				return this.resolvedType = valueIfTrueType;
+			} else if (valueIfTrueType.isCompatibleWith(valueIfFalseType)) {
+				this.valueIfTrue.computeConversion(scope, valueIfFalseType, this.originalValueIfTrueType);
+				this.valueIfFalse.computeConversion(scope, valueIfFalseType, this.originalValueIfFalseType);
+				return this.resolvedType = valueIfFalseType;
+			}
+		}
+		scope.problemReporter().conditionalArgumentsIncompatibleTypes(
+			this,
+			valueIfTrueType,
+			valueIfFalseType);
+		return null;
+	}
+
+	public void setExpectedType(TypeBinding expectedType) {
+		this.expectedType = expectedType;
+	}
+	
+	public void setExpressionContext(ExpressionContext context) {
+		this.expressionContext = context;
+	}
+	
+	public boolean isPolyExpression() throws UnsupportedOperationException {
+		if (this.expressionContext != ASSIGNMENT_CONTEXT && this.expressionContext != INVOCATION_CONTEXT)
+			return false;
+		
+		return this.isPolyExpression;
+	}
+	
+	public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+		return this.valueIfTrue.isCompatibleWith(left, scope) && this.valueIfFalse.isCompatibleWith(left, scope);
+	}
+	
+	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+		return isPolyExpression() ?
+				this.valueIfTrue.tIsMoreSpecific(t, s) && this.valueIfFalse.tIsMoreSpecific(t, s):
+				super.tIsMoreSpecific(t, s);
+	}
+	
+	public void tagAsEllipsisArgument() {
+		this.valueIfTrue.tagAsEllipsisArgument();
+		this.valueIfFalse.tagAsEllipsisArgument();
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			this.condition.traverse(visitor, scope);
+			this.valueIfTrue.traverse(visitor, scope);
+			this.valueIfFalse.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..1338801
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -0,0 +1,596 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 343713 - [compiler] bogus line number in constructor of inner class in 1.5 compliance
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 383690 - [compiler] location of error re uninitialized final field should be aligned
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ConstructorDeclaration extends AbstractMethodDeclaration {
+
+	public ExplicitConstructorCall constructorCall;
+
+	public TypeParameter[] typeParameters;
+
+public ConstructorDeclaration(CompilationResult compilationResult){
+	super(compilationResult);
+}
+/**
+ * The flowInfo corresponds to non-static field initialization infos. It may be unreachable (155423), but still the explicit constructor call must be
+ * analyzed as reachable, since it will be generated in the end.
+ */
+public void analyseCode(ClassScope classScope, InitializationFlowContext initializerFlowContext, FlowInfo flowInfo, int initialReachMode) {
+	if (this.ignoreFurtherInvestigation)
+		return;
+
+	int nonStaticFieldInfoReachMode = flowInfo.reachMode();
+	flowInfo.setReachMode(initialReachMode);
+
+	checkUnused: {
+		MethodBinding constructorBinding;
+		if ((constructorBinding = this.binding) == null) break checkUnused;
+		if ((this.bits & ASTNode.IsDefaultConstructor) != 0) break checkUnused;
+		if (constructorBinding.isUsed()) break checkUnused;
+		if (constructorBinding.isPrivate()) {
+			if ((this.binding.declaringClass.tagBits & TagBits.HasNonPrivateConstructor) == 0)
+				break checkUnused; // tolerate as known pattern to block instantiation
+		} else if (!constructorBinding.isOrEnclosedByPrivateType()) {
+			break checkUnused;
+ 		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=270446, When the AST built is an abridged version
+		// we don't have all tree nodes we would otherwise expect. (see ASTParser.setFocalPosition)
+		if (this.constructorCall == null)
+			break checkUnused; 
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=264991, Don't complain about this
+		// constructor being unused if the base class doesn't have a no-arg constructor.
+		// See that a seemingly unused constructor that chains to another constructor with a
+		// this(...) can be flagged as being unused without hesitation.
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142
+		if (this.constructorCall.accessMode != ExplicitConstructorCall.This) {
+			ReferenceBinding superClass = constructorBinding.declaringClass.superclass();
+			if (superClass == null)
+				break checkUnused;
+			// see if there is a no-arg super constructor
+			MethodBinding methodBinding = superClass.getExactConstructor(Binding.NO_PARAMETERS);
+			if (methodBinding == null)
+				break checkUnused;
+			if (!methodBinding.canBeSeenBy(SuperReference.implicitSuperConstructorCall(), this.scope))
+				break checkUnused;
+			// otherwise default super constructor exists, so go ahead and complain unused.
+		}
+		// complain unused
+		this.scope.problemReporter().unusedPrivateConstructor(this);
+	}
+
+	// check constructor recursion, once all constructor got resolved
+	if (isRecursive(null /*lazy initialized visited list*/)) {
+		this.scope.problemReporter().recursiveConstructorInvocation(this.constructorCall);
+	}
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
+	if (this.typeParameters != null  &&
+			!this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+		for (int i = 0, length = this.typeParameters.length; i < length; ++i) {
+			TypeParameter typeParameter = this.typeParameters[i];
+			if ((typeParameter.binding.modifiers & ExtraCompilerModifiers.AccLocallyUsed) == 0) {
+				this.scope.problemReporter().unusedTypeParameter(typeParameter);						
+			}
+		}
+	}
+	try {
+		ExceptionHandlingFlowContext constructorContext =
+			new ExceptionHandlingFlowContext(
+				initializerFlowContext.parent,
+				this,
+				this.binding.thrownExceptions,
+				initializerFlowContext,
+				this.scope,
+				FlowInfo.DEAD_END);
+		initializerFlowContext.checkInitializerExceptions(
+			this.scope,
+			constructorContext,
+			flowInfo);
+
+		// anonymous constructor can gain extra thrown exceptions from unhandled ones
+		if (this.binding.declaringClass.isAnonymousType()) {
+			ArrayList computedExceptions = constructorContext.extendedExceptions;
+			if (computedExceptions != null){
+				int size;
+				if ((size = computedExceptions.size()) > 0){
+					ReferenceBinding[] actuallyThrownExceptions;
+					computedExceptions.toArray(actuallyThrownExceptions = new ReferenceBinding[size]);
+					this.binding.thrownExceptions = actuallyThrownExceptions;
+				}
+			}
+		}
+
+		// nullity and mark as assigned
+		analyseArguments(flowInfo, this.arguments, this.binding);
+
+		// propagate to constructor call
+		if (this.constructorCall != null) {
+			// if calling 'this(...)', then flag all non-static fields as definitely
+			// set since they are supposed to be set inside other local constructor
+			if (this.constructorCall.accessMode == ExplicitConstructorCall.This) {
+				FieldBinding[] fields = this.binding.declaringClass.fields();
+				for (int i = 0, count = fields.length; i < count; i++) {
+					FieldBinding field;
+					if (!(field = fields[i]).isStatic()) {
+						flowInfo.markAsDefinitelyAssigned(field);
+					}
+				}
+			}
+			flowInfo = this.constructorCall.analyseCode(this.scope, constructorContext, flowInfo);
+		}
+
+		// reuse the reachMode from non static field info
+		flowInfo.setReachMode(nonStaticFieldInfoReachMode);
+
+		// propagate to statements
+		if (this.statements != null) {
+			boolean enableSyntacticNullAnalysisForFields = this.scope.compilerOptions().enableSyntacticNullAnalysisForFields;
+			int complaintLevel = (nonStaticFieldInfoReachMode & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
+			for (int i = 0, count = this.statements.length; i < count; i++) {
+				Statement stat = this.statements[i];
+				if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
+					flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo);
+				}
+				if (enableSyntacticNullAnalysisForFields) {
+					constructorContext.expireNullCheckedFieldInfo();
+				}
+			}
+		}
+		// check for missing returning path
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.bits |= ASTNode.NeedFreeReturn;
+		}
+
+		// reuse the initial reach mode for diagnosing missing blank finals
+		// no, we should use the updated reach mode for diagnosing uninitialized blank finals.
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=235781
+		// flowInfo.setReachMode(initialReachMode);
+
+		// check missing blank final field initializations (plus @NonNull)
+		if ((this.constructorCall != null)
+			&& (this.constructorCall.accessMode != ExplicitConstructorCall.This)) {
+			flowInfo = flowInfo.mergedWith(constructorContext.initsOnReturn);
+			FieldBinding[] fields = this.binding.declaringClass.fields();
+			for (int i = 0, count = fields.length; i < count; i++) {
+				FieldBinding field = fields[i];
+				if (!field.isStatic() && !flowInfo.isDefinitelyAssigned(field)) {
+					if (field.isFinal()) {
+						this.scope.problemReporter().uninitializedBlankFinalField(
+								field,
+								((this.bits & ASTNode.IsDefaultConstructor) != 0)
+									? (ASTNode) this.scope.referenceType().declarationOf(field.original())
+									: this);
+					} else if (field.isNonNull()) {
+						FieldDeclaration fieldDecl = this.scope.referenceType().declarationOf(field.original());
+						if (!isValueProvidedUsingAnnotation(fieldDecl))
+							this.scope.problemReporter().uninitializedNonNullField(
+								field,
+								((this.bits & ASTNode.IsDefaultConstructor) != 0) 
+									? (ASTNode) fieldDecl
+									: this);
+					}
+				}
+			}
+		}
+		// check unreachable catch blocks
+		constructorContext.complainIfUnusedExceptionHandlers(this);
+		// check unused parameters
+		this.scope.checkUnusedParameters(this.binding);
+		this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null);
+	} catch (AbortMethod e) {
+		this.ignoreFurtherInvestigation = true;
+	}
+}
+
+boolean isValueProvidedUsingAnnotation(FieldDeclaration fieldDecl) {
+	// a member field annotated with @Inject is considered to be initialized by the injector 
+	if (fieldDecl.annotations != null) {
+		int length = fieldDecl.annotations.length;
+		for (int i = 0; i < length; i++) {
+			Annotation annotation = fieldDecl.annotations[i];
+			if (annotation.resolvedType.id == TypeIds.T_JavaxInjectInject) {
+				return true; // no concept of "optional"
+			} else if (annotation.resolvedType.id == TypeIds.T_ComGoogleInjectInject) {
+				MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+				if (memberValuePairs == Annotation.NoValuePairs)
+					return true;
+				for (int j = 0; j < memberValuePairs.length; j++) {
+					// if "optional=false" is specified, don't rely on initialization by the injector:
+					if (CharOperation.equals(memberValuePairs[j].name, TypeConstants.OPTIONAL))
+						return memberValuePairs[j].value instanceof FalseLiteral;
+				}
+			}
+		}
+	}
+	return false;
+}
+
+/**
+ * Bytecode generation for a constructor
+ *
+ * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
+ * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+ */
+public void generateCode(ClassScope classScope, ClassFile classFile) {
+	int problemResetPC = 0;
+	if (this.ignoreFurtherInvestigation) {
+		if (this.binding == null)
+			return; // Handle methods with invalid signature or duplicates
+		int problemsLength;
+		CategorizedProblem[] problems =
+			this.scope.referenceCompilationUnit().compilationResult.getProblems();
+		CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+		classFile.addProblemConstructor(this, this.binding, problemsCopy);
+		return;
+	}
+	boolean restart = false;
+	boolean abort = false;
+	do {
+		try {
+			problemResetPC = classFile.contentsOffset;
+			internalGenerateCode(classScope, classFile);
+			restart = false;
+		} catch (AbortMethod e) {
+			if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
+				// a branch target required a goto_w, restart code gen in wide mode.
+				classFile.contentsOffset = problemResetPC;
+				classFile.methodCount--;
+				classFile.codeStream.resetInWideMode(); // request wide mode
+				restart = true;
+			} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
+				classFile.contentsOffset = problemResetPC;
+				classFile.methodCount--;
+				classFile.codeStream.resetForCodeGenUnusedLocals();
+				restart = true;
+			} else {
+				restart = false;
+				abort = true;
+			}
+		}
+	} while (restart);
+	if (abort) {
+		int problemsLength;
+		CategorizedProblem[] problems =
+				this.scope.referenceCompilationUnit().compilationResult.getAllProblems();
+		CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+		classFile.addProblemConstructor(this, this.binding, problemsCopy, problemResetPC);
+	}
+}
+
+public void generateSyntheticFieldInitializationsIfNecessary(MethodScope methodScope, CodeStream codeStream, ReferenceBinding declaringClass) {
+	if (!declaringClass.isNestedType()) return;
+
+	NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
+
+	SyntheticArgumentBinding[] syntheticArgs = nestedType.syntheticEnclosingInstances();
+	if (syntheticArgs != null) {
+		for (int i = 0, max = syntheticArgs.length; i < max; i++) {
+			SyntheticArgumentBinding syntheticArg;
+			if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
+				codeStream.aload_0();
+				codeStream.load(syntheticArg);
+				codeStream.fieldAccess(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */);
+			}
+		}
+	}
+	syntheticArgs = nestedType.syntheticOuterLocalVariables();
+	if (syntheticArgs != null) {
+		for (int i = 0, max = syntheticArgs.length; i < max; i++) {
+			SyntheticArgumentBinding syntheticArg;
+			if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
+				codeStream.aload_0();
+				codeStream.load(syntheticArg);
+				codeStream.fieldAccess(Opcodes.OPC_putfield, syntheticArg.matchingField, null /* default declaringClass */);
+			}
+		}
+	}
+}
+
+private void internalGenerateCode(ClassScope classScope, ClassFile classFile) {
+	classFile.generateMethodInfoHeader(this.binding);
+	int methodAttributeOffset = classFile.contentsOffset;
+	int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
+	if ((!this.binding.isNative()) && (!this.binding.isAbstract())) {
+
+		TypeDeclaration declaringType = classScope.referenceContext;
+		int codeAttributeOffset = classFile.contentsOffset;
+		classFile.generateCodeAttributeHeader();
+		CodeStream codeStream = classFile.codeStream;
+		codeStream.reset(this, classFile);
+
+		// initialize local positions - including initializer scope.
+		ReferenceBinding declaringClass = this.binding.declaringClass;
+
+		int enumOffset = declaringClass.isEnum() ? 2 : 0; // String name, int ordinal
+		int argSlotSize = 1 + enumOffset; // this==aload0
+
+		if (declaringClass.isNestedType()){
+			this.scope.extraSyntheticArguments = declaringClass.syntheticOuterLocalVariables();
+			this.scope.computeLocalVariablePositions(// consider synthetic arguments if any
+					declaringClass.getEnclosingInstancesSlotSize() + 1 + enumOffset,
+				codeStream);
+			argSlotSize += declaringClass.getEnclosingInstancesSlotSize();
+			argSlotSize += declaringClass.getOuterLocalVariablesSlotSize();
+		} else {
+			this.scope.computeLocalVariablePositions(1 + enumOffset,  codeStream);
+		}
+
+		if (this.arguments != null) {
+			for (int i = 0, max = this.arguments.length; i < max; i++) {
+				// arguments initialization for local variable debug attributes
+				LocalVariableBinding argBinding;
+				codeStream.addVisibleLocalVariable(argBinding = this.arguments[i].binding);
+				argBinding.recordInitializationStartPC(0);
+				switch(argBinding.type.id) {
+					case TypeIds.T_long :
+					case TypeIds.T_double :
+						argSlotSize += 2;
+						break;
+					default :
+						argSlotSize++;
+						break;
+				}
+			}
+		}
+
+		MethodScope initializerScope = declaringType.initializerScope;
+		initializerScope.computeLocalVariablePositions(argSlotSize, codeStream); // offset by the argument size (since not linked to method scope)
+
+		boolean needFieldInitializations = this.constructorCall == null || this.constructorCall.accessMode != ExplicitConstructorCall.This;
+
+		// post 1.4 target level, synthetic initializations occur prior to explicit constructor call
+		boolean preInitSyntheticFields = this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_4;
+
+		if (needFieldInitializations && preInitSyntheticFields){
+			generateSyntheticFieldInitializationsIfNecessary(this.scope, codeStream, declaringClass);
+			codeStream.recordPositionsFrom(0, this.bodyStart);
+		}
+		// generate constructor call
+		if (this.constructorCall != null) {
+			this.constructorCall.generateCode(this.scope, codeStream);
+		}
+		// generate field initialization - only if not invoking another constructor call of the same class
+		if (needFieldInitializations) {
+			if (!preInitSyntheticFields){
+				generateSyntheticFieldInitializationsIfNecessary(this.scope, codeStream, declaringClass);
+			}
+			// generate user field initialization
+			if (declaringType.fields != null) {
+				for (int i = 0, max = declaringType.fields.length; i < max; i++) {
+					FieldDeclaration fieldDecl;
+					if (!(fieldDecl = declaringType.fields[i]).isStatic()) {
+						fieldDecl.generateCode(initializerScope, codeStream);
+					}
+				}
+			}
+		}
+		// generate statements
+		if (this.statements != null) {
+			for (int i = 0, max = this.statements.length; i < max; i++) {
+				this.statements[i].generateCode(this.scope, codeStream);
+			}
+		}
+		// if a problem got reported during code gen, then trigger problem method creation
+		if (this.ignoreFurtherInvestigation) {
+			throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
+		}
+		if ((this.bits & ASTNode.NeedFreeReturn) != 0) {
+			codeStream.return_();
+		}
+		// local variable attributes
+		codeStream.exitUserScope(this.scope);
+		codeStream.recordPositionsFrom(0, this.bodyEnd);
+		try {
+			classFile.completeCodeAttribute(codeAttributeOffset);
+		} catch(NegativeArraySizeException e) {
+			throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
+		}
+		attributeNumber++;
+		if ((codeStream instanceof StackMapFrameCodeStream)
+				&& needFieldInitializations
+				&& declaringType.fields != null) {
+			((StackMapFrameCodeStream) codeStream).resetSecretLocals();
+		}
+	}
+	classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
+}
+
+public boolean isConstructor() {
+	return true;
+}
+
+public boolean isDefaultConstructor() {
+	return (this.bits & ASTNode.IsDefaultConstructor) != 0;
+}
+
+public boolean isInitializationMethod() {
+	return true;
+}
+
+/*
+ * Returns true if the constructor is directly involved in a cycle.
+ * Given most constructors aren't, we only allocate the visited list
+ * lazily.
+ */
+public boolean isRecursive(ArrayList visited) {
+	if (this.binding == null
+			|| this.constructorCall == null
+			|| this.constructorCall.binding == null
+			|| this.constructorCall.isSuperAccess()
+			|| !this.constructorCall.binding.isValidBinding()) {
+		return false;
+	}
+
+	ConstructorDeclaration targetConstructor =
+		((ConstructorDeclaration)this.scope.referenceType().declarationOf(this.constructorCall.binding.original()));
+	if (targetConstructor == null) return false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=358762
+	if (this == targetConstructor) return true; // direct case
+
+	if (visited == null) { // lazy allocation
+		visited = new ArrayList(1);
+	} else {
+		int index = visited.indexOf(this);
+		if (index >= 0) return index == 0; // only blame if directly part of the cycle
+	}
+	visited.add(this);
+
+	return targetConstructor.isRecursive(visited);
+}
+
+public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+	//fill up the constructor body with its statements
+	if (((this.bits & ASTNode.IsDefaultConstructor) != 0) && this.constructorCall == null){
+		this.constructorCall = SuperReference.implicitSuperConstructorCall();
+		this.constructorCall.sourceStart = this.sourceStart;
+		this.constructorCall.sourceEnd = this.sourceEnd;
+		return;
+	}
+	parser.parse(this, unit, false);
+
+}
+
+public StringBuffer printBody(int indent, StringBuffer output) {
+	output.append(" {"); //$NON-NLS-1$
+	if (this.constructorCall != null) {
+		output.append('\n');
+		this.constructorCall.printStatement(indent, output);
+	}
+	if (this.statements != null) {
+		for (int i = 0; i < this.statements.length; i++) {
+			output.append('\n');
+			this.statements[i].printStatement(indent, output);
+		}
+	}
+	output.append('\n');
+	printIndent(indent == 0 ? 0 : indent - 1, output).append('}');
+	return output;
+}
+
+public void resolveJavadoc() {
+	if (this.binding == null || this.javadoc != null) {
+		super.resolveJavadoc();
+	} else if ((this.bits & ASTNode.IsDefaultConstructor) == 0) {
+		if (this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) {
+			// Set javadoc visibility
+			int javadocVisibility = this.binding.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+			ClassScope classScope = this.scope.classScope();
+			ProblemReporter reporter = this.scope.problemReporter();
+			int severity = reporter.computeSeverity(IProblem.JavadocMissing);
+			if (severity != ProblemSeverities.Ignore) {
+				if (classScope != null) {
+					javadocVisibility = Util.computeOuterMostVisibility(classScope.referenceType(), javadocVisibility);
+				}
+				int javadocModifiers = (this.binding.modifiers & ~ExtraCompilerModifiers.AccVisibilityMASK) | javadocVisibility;
+				reporter.javadocMissing(this.sourceStart, this.sourceEnd, severity, javadocModifiers);
+			}
+		}
+	}
+}
+
+/*
+ * Type checking for constructor, just another method, except for special check
+ * for recursive constructor invocations.
+ */
+public void resolveStatements() {
+	SourceTypeBinding sourceType = this.scope.enclosingSourceType();
+	if (!CharOperation.equals(sourceType.sourceName, this.selector)){
+		this.scope.problemReporter().missingReturnType(this);
+	}
+	if (this.typeParameters != null) {
+		for (int i = 0, length = this.typeParameters.length; i < length; i++) {
+			this.typeParameters[i].resolve(this.scope);
+		}
+	}
+	if (this.binding != null && !this.binding.isPrivate()) {
+		sourceType.tagBits |= TagBits.HasNonPrivateConstructor;
+	}
+	// if null ==> an error has occurs at parsing time ....
+	if (this.constructorCall != null) {
+		if (sourceType.id == TypeIds.T_JavaLangObject
+				&& this.constructorCall.accessMode != ExplicitConstructorCall.This) {
+			// cannot use super() in java.lang.Object
+			if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) {
+				this.scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall);
+			}
+			this.constructorCall = null;
+		} else {
+			this.constructorCall.resolve(this.scope);
+		}
+	}
+	if ((this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) {
+		this.scope.problemReporter().methodNeedBody(this);
+	}
+	super.resolveStatements();
+}
+
+public void traverse(ASTVisitor visitor, ClassScope classScope) {
+	if (visitor.visit(this, classScope)) {
+		if (this.javadoc != null) {
+			this.javadoc.traverse(visitor, this.scope);
+		}
+		if (this.annotations != null) {
+			int annotationsLength = this.annotations.length;
+			for (int i = 0; i < annotationsLength; i++)
+				this.annotations[i].traverse(visitor, this.scope);
+		}
+		if (this.typeParameters != null) {
+			int typeParametersLength = this.typeParameters.length;
+			for (int i = 0; i < typeParametersLength; i++) {
+				this.typeParameters[i].traverse(visitor, this.scope);
+			}
+		}
+		if (this.arguments != null) {
+			int argumentLength = this.arguments.length;
+			for (int i = 0; i < argumentLength; i++)
+				this.arguments[i].traverse(visitor, this.scope);
+		}
+		if (this.thrownExceptions != null) {
+			int thrownExceptionsLength = this.thrownExceptions.length;
+			for (int i = 0; i < thrownExceptionsLength; i++)
+				this.thrownExceptions[i].traverse(visitor, this.scope);
+		}
+		if (this.constructorCall != null)
+			this.constructorCall.traverse(visitor, this.scope);
+		if (this.statements != null) {
+			int statementsLength = this.statements.length;
+			for (int i = 0; i < statementsLength; i++)
+				this.statements[i].traverse(visitor, this.scope);
+		}
+	}
+	visitor.endVisit(this, classScope);
+}
+public TypeParameter[] typeParameters() {
+    return this.typeParameters;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
new file mode 100644
index 0000000..1337cdd
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ContinueStatement extends BranchStatement {
+
+public ContinueStatement(char[] label, int sourceStart, int sourceEnd) {
+	super(label, sourceStart, sourceEnd);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// here requires to generate a sequence of finally blocks invocations depending corresponding
+	// to each of the traversed try statements, so that execution will terminate properly.
+
+	// lookup the label, this should answer the returnContext
+	FlowContext targetContext = (this.label == null)
+			? flowContext.getTargetContextForDefaultContinue()
+			: flowContext.getTargetContextForContinueLabel(this.label);
+
+	if (targetContext == null) {
+		if (this.label == null) {
+			currentScope.problemReporter().invalidContinue(this);
+		} else {
+			currentScope.problemReporter().undefinedLabel(this);
+		}
+		return flowInfo; // pretend it did not continue since no actual target
+	}
+
+	targetContext.recordAbruptExit();
+
+	if (targetContext == FlowContext.NotContinuableContext) {
+		currentScope.problemReporter().invalidContinue(this);
+		return flowInfo; // pretend it did not continue since no actual target
+	}
+	this.initStateIndex =
+		currentScope.methodScope().recordInitializationStates(flowInfo);
+
+	this.targetLabel = targetContext.continueLabel();
+	FlowContext traversedContext = flowContext;
+	int subCount = 0;
+	this.subroutines = new SubRoutineStatement[5];
+
+	do {
+		SubRoutineStatement sub;
+		if ((sub = traversedContext.subroutine()) != null) {
+			if (subCount == this.subroutines.length) {
+				System.arraycopy(this.subroutines, 0, this.subroutines = new SubRoutineStatement[subCount*2], 0, subCount); // grow
+			}
+			this.subroutines[subCount++] = sub;
+			if (sub.isSubRoutineEscaping()) {
+				break;
+			}
+		}
+		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
+
+		if (traversedContext instanceof InsideSubRoutineFlowContext) {
+			ASTNode node = traversedContext.associatedNode;
+			if (node instanceof TryStatement) {
+				TryStatement tryStatement = (TryStatement) node;
+				flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
+			}
+		} else if (traversedContext == targetContext) {
+			// only record continue info once accumulated through subroutines, and only against target context
+			targetContext.recordContinueFrom(flowContext, flowInfo);
+			break;
+		}
+	} while ((traversedContext = traversedContext.getLocalParent()) != null);
+
+	// resize subroutines
+	if (subCount != this.subroutines.length) {
+		System.arraycopy(this.subroutines, 0, this.subroutines = new SubRoutineStatement[subCount], 0, subCount);
+	}
+	return FlowInfo.DEAD_END;
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	printIndent(tab, output).append("continue "); //$NON-NLS-1$
+	if (this.label != null) output.append(this.label);
+	return output.append(';');
+}
+
+public void traverse(ASTVisitor visitor, 	BlockScope blockScope) {
+	visitor.visit(this, blockScope);
+	visitor.endVisit(this, blockScope);
+}
+}
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
new file mode 100644
index 0000000..267ba15
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class DoStatement extends Statement {
+
+	public Expression condition;
+	public Statement action;
+
+	private BranchLabel breakLabel, continueLabel;
+
+	// for local variables table attributes
+	int mergedInitStateIndex = -1;
+	int preConditionInitStateIndex = -1;
+
+public DoStatement(Expression condition, Statement action, int sourceStart, int sourceEnd) {
+
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+	this.condition = condition;
+	this.action = action;
+	// remember useful empty statement
+	if (action instanceof EmptyStatement) action.bits |= ASTNode.IsUsefulEmptyStatement;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	this.breakLabel = new BranchLabel();
+	this.continueLabel = new BranchLabel();
+	LoopingFlowContext loopingContext =
+		new LoopingFlowContext(
+			flowContext,
+			flowInfo,
+			this,
+			this.breakLabel,
+			this.continueLabel,
+			currentScope,
+			false);
+
+	Constant cst = this.condition.constant;
+	boolean isConditionTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+	cst = this.condition.optimizedBooleanConstant();
+	boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+	boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+	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
+	// or catch blocks
+	if ((this.action != null) && !this.action.isEmptyBlock()) {
+		actionInfo = this.action.
+			analyseCode(currentScope, loopingContext, actionInfo).
+			unconditionalInits();
+
+		// code generation can be optimized when no need to continue in the loop
+		if ((actionInfo.tagBits &
+				loopingContext.initsOnContinue.tagBits &
+				FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
+			this.continueLabel = null;
+		}
+		if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+			initsOnCondition = flowInfo.unconditionalInits().
+									addInitializationsFrom(
+										actionInfo.mergedWith(loopingContext.initsOnContinue));
+		}
+	}
+	this.condition.checkNPEbyUnboxing(currentScope, flowContext, initsOnCondition);
+	/* Reset reach mode, to address following scenario.
+	 *   final blank;
+	 *   do { if (true) break; else blank = 0; } while(false);
+	 *   blank = 1; // may be initialized already
+	 */
+	actionInfo.setReachMode(previousMode);
+
+	LoopingFlowContext condLoopContext;
+	FlowInfo condInfo =
+		this.condition.analyseCode(
+			currentScope,
+			(condLoopContext =
+				new LoopingFlowContext(flowContext,	flowInfo, this, null,
+					null, currentScope, true)),
+			(this.action == null
+				? actionInfo
+				: (actionInfo.mergedWith(loopingContext.initsOnContinue))).copy());
+	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=367023, we reach the condition at the bottom via two arcs, 
+	   one by free fall and another by continuing... Merge initializations propagated through the two pathways,
+	   cf, while and for loops.
+	*/
+	this.preConditionInitStateIndex = currentScope.methodScope().recordInitializationStates(actionInfo.mergedWith(loopingContext.initsOnContinue));
+	if (!isConditionOptimizedFalse && this.continueLabel != null) {
+		loopingContext.complainOnDeferredFinalChecks(currentScope, condInfo);
+		condLoopContext.complainOnDeferredFinalChecks(currentScope, condInfo);
+		loopingContext.complainOnDeferredNullChecks(currentScope,
+				flowInfo.unconditionalCopy().addPotentialNullInfoFrom(
+					  condInfo.initsWhenTrue().unconditionalInits()));
+		condLoopContext.complainOnDeferredNullChecks(currentScope,
+				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(
+						(loopingContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) != 0
+								? loopingContext.initsOnBreak
+								: flowInfo.unconditionalCopy().addInitializationsFrom(loopingContext.initsOnBreak),
+								// recover upstream null info
+						isConditionOptimizedTrue,
+						(condInfo.tagBits & FlowInfo.UNREACHABLE) == 0
+								? flowInfo.copy().addInitializationsFrom(condInfo.initsWhenFalse()) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=380927
+								: condInfo,
+							// recover null inits from before condition analysis
+						false, // never consider opt false case for DO loop, since break can always occur (47776)
+						!isConditionTrue /*do{}while(true); unreachable(); */);
+	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+	return mergedInfo;
+}
+
+/**
+ * Do statement code generation
+ *
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+
+	// labels management
+	BranchLabel actionLabel = new BranchLabel(codeStream);
+	if (this.action != null) actionLabel.tagBits |= BranchLabel.USED;
+	actionLabel.place();
+	this.breakLabel.initialize(codeStream);
+	boolean hasContinueLabel = this.continueLabel != null;
+	if (hasContinueLabel) {
+		this.continueLabel.initialize(codeStream);
+	}
+
+	// generate action
+	if (this.action != null) {
+		this.action.generateCode(currentScope, codeStream);
+	}
+	// continue label (135602)
+	if (hasContinueLabel) {
+		this.continueLabel.place();
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.preConditionInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preConditionInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.preConditionInitStateIndex);
+		}
+		// generate condition
+		Constant cst = this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+		if (isConditionOptimizedFalse){
+			this.condition.generateCode(currentScope, codeStream, false);
+		} else {
+			this.condition.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				actionLabel,
+				null,
+				true);
+		}
+	}
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (this.mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+	}
+	if (this.breakLabel.forwardReferenceCount() > 0) {
+		this.breakLabel.place();
+	}
+
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	printIndent(indent, output).append("do"); //$NON-NLS-1$
+	if (this.action == null)
+		output.append(" ;\n"); //$NON-NLS-1$
+	else {
+		output.append('\n');
+		this.action.printStatement(indent + 1, output).append('\n');
+	}
+	output.append("while ("); //$NON-NLS-1$
+	return this.condition.printExpression(0, output).append(");"); //$NON-NLS-1$
+}
+
+public void resolve(BlockScope scope) {
+	TypeBinding type = this.condition.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
+	this.condition.computeConversion(scope, type, type);
+	if (this.action != null)
+		this.action.resolve(scope);
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (this.action != null) {
+			this.action.traverse(visitor, scope);
+		}
+		this.condition.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java
new file mode 100644
index 0000000..1a7ef12
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.FloatUtil;
+
+public class DoubleLiteral extends NumberLiteral {
+	
+	double value;
+	
+public DoubleLiteral(char[] token, int s, int e) {
+	super(token, s, e);
+}
+
+public void computeConstant() {
+	Double computedValue;
+	boolean containsUnderscores = CharOperation.indexOf('_', this.source) > 0;
+	if (containsUnderscores) {
+		// remove all underscores from source
+		this.source = CharOperation.remove(this.source, '_');
+	}
+	try {
+		computedValue = Double.valueOf(String.valueOf(this.source));
+	} catch (NumberFormatException e) {
+		// hex floating point literal
+		// being rejected by 1.4 libraries where Double.valueOf(...) doesn't handle hex decimal floats
+		try {
+			double v = FloatUtil.valueOfHexDoubleLiteral(this.source);
+			if (v == Double.POSITIVE_INFINITY) {
+				// error: the number is too large to represent
+				return;
+			}
+			if (Double.isNaN(v)) {
+				// error: the number is too small to represent
+				return;
+			}
+			this.value = v;
+			this.constant = DoubleConstant.fromValue(v);
+		} catch (NumberFormatException e1) {
+			// if the computation of the constant fails
+		}
+		return;
+	}
+	final double doubleValue = computedValue.doubleValue();
+	if (doubleValue > Double.MAX_VALUE) {
+		// error: the number is too large to represent
+		return;
+	}
+	if (doubleValue < Double.MIN_VALUE) {
+		// see 1F6IGUU
+		// a true 0 only has '0' and '.' in mantissa
+		// 1.0e-5000d is non-zero, but underflows to 0
+		boolean isHexaDecimal = false;
+		label : for (int i = 0; i < this.source.length; i++) { //it is welled formated so just test against '0' and potential . D d
+			switch (this.source[i]) {
+				case '0' :
+				case '.' :
+					break;
+				case 'x' :
+				case 'X' :
+					isHexaDecimal = true;
+					break;
+				case 'e' :
+				case 'E' :
+				case 'f' :
+				case 'F' :
+				case 'd' :
+				case 'D' :
+					if (isHexaDecimal) {
+						return;
+					}
+					// starting the exponent - mantissa is all zero
+					// no exponent - mantissa is all zero
+					break label;
+				case 'p' :
+				case 'P' :
+					break label;
+				default :
+					// error: the number is too small to represent
+					return;
+			}
+		}
+	}
+	this.value = doubleValue;
+	this.constant = DoubleConstant.fromValue(this.value);
+}
+
+/**
+ * Code generation for the double literak
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.DOUBLE;
+}
+
+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/EmptyStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
new file mode 100644
index 0000000..904e564
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+
+public class EmptyStatement extends Statement {
+
+	public EmptyStatement(int startPosition, int endPosition) {
+		this.sourceStart = startPosition;
+		this.sourceEnd = endPosition;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		return flowInfo;
+	}
+
+	// Report an error if necessary
+	public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel, boolean endOfBlock) {
+		// before 1.4, empty statements are tolerated anywhere
+		if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
+			return complaintLevel;
+		}
+		return super.complainIfUnreachable(flowInfo, scope, complaintLevel, endOfBlock);
+	}
+
+	public void generateCode(BlockScope currentScope, CodeStream codeStream){
+		// no bytecode, no need to check for reachability or recording source positions
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+		return printIndent(tab, output).append(';');
+	}
+
+	public void resolve(BlockScope scope) {
+		if ((this.bits & IsUsefulEmptyStatement) == 0) {
+			scope.problemReporter().superfluousSemicolon(this.sourceStart, this.sourceEnd);
+		} else {
+			scope.problemReporter().emptyControlFlowStatement(this.sourceStart, this.sourceEnd);
+		}
+	}
+
+	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/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
new file mode 100644
index 0000000..909bc0d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -0,0 +1,938 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class EqualExpression extends BinaryExpression {
+
+	public EqualExpression(Expression left, Expression right,int operator) {
+		super(left,right,operator);
+	}
+	private void checkNullComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse) {
+
+		// collect null status of child nodes:
+		int rightStatus = this.right.nullStatus(flowInfo, flowContext);
+		int leftStatus = this.left.nullStatus(flowInfo, flowContext);
+
+		boolean leftNonNullChecked = false;
+		boolean rightNonNullChecked = false;
+
+		// check if either is a non-local expression known to be nonnull and compared to null, candidates are
+		// - method/field annotated @NonNull
+		// - allocation expression, some literals, this reference (see inside expressionNonNullComparison(..))
+		// these checks do not leverage the flowInfo.
+		boolean checkEquality = ((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL;
+		if (leftStatus == FlowInfo.NON_NULL && rightStatus == FlowInfo.NULL) {
+			leftNonNullChecked = scope.problemReporter().expressionNonNullComparison(this.left, checkEquality);
+		} else if (leftStatus == FlowInfo.NULL && rightStatus == FlowInfo.NON_NULL) {
+			rightNonNullChecked = scope.problemReporter().expressionNonNullComparison(this.right, checkEquality);
+		}
+		
+		boolean contextualCheckEquality = checkEquality ^ ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) != 0);
+		// perform flowInfo-based checks for variables and record info for syntactic null analysis for fields:
+		if (!leftNonNullChecked) {
+			LocalVariableBinding local = this.left.localVariableBinding();
+			if (local != null) {
+				if ((local.type.tagBits & TagBits.IsBaseType) == 0) {
+					checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, rightStatus, this.left);
+				}
+			} else if (this.left instanceof Reference
+							&& ((!contextualCheckEquality && rightStatus == FlowInfo.NULL) 
+									|| (contextualCheckEquality && rightStatus == FlowInfo.NON_NULL))
+							&& scope.compilerOptions().enableSyntacticNullAnalysisForFields)
+			{
+				FieldBinding field = ((Reference)this.left).lastFieldBinding();
+				if (field != null && (field.type.tagBits & TagBits.IsBaseType) == 0) {
+					flowContext.recordNullCheckedFieldReference((Reference) this.left, 1);
+				}
+			}
+		}
+		if (!rightNonNullChecked) {
+			LocalVariableBinding local = this.right.localVariableBinding();
+			if (local != null) { 
+				if ((local.type.tagBits & TagBits.IsBaseType) == 0) {
+					checkVariableComparison(scope, flowContext, flowInfo, initsWhenTrue, initsWhenFalse, local, leftStatus, this.right);
+				}
+			} else if (this.right instanceof Reference
+							&& ((!contextualCheckEquality && leftStatus == FlowInfo.NULL) 
+									|| (contextualCheckEquality && leftStatus == FlowInfo.NON_NULL))
+							&& scope.compilerOptions().enableSyntacticNullAnalysisForFields) 
+			{
+				FieldBinding field = ((Reference)this.right).lastFieldBinding();
+				if (field != null && (field.type.tagBits & TagBits.IsBaseType) == 0) {
+					flowContext.recordNullCheckedFieldReference((Reference) this.right, 1);
+				}				
+			}
+		}
+
+		// handle reachability:
+		if (leftNonNullChecked || rightNonNullChecked) {
+			// above checks have not propagated unreachable into the corresponding branch, do it now:
+			if (checkEquality) {
+				initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+			} else {
+				initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+			}
+		}
+	}
+	private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) {
+		switch (nullStatus) {
+			case FlowInfo.NULL :
+				if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+					flowContext.recordUsingNullReference(scope, local, reference,
+							FlowContext.CAN_ONLY_NULL_NON_NULL | FlowContext.IN_COMPARISON_NULL, flowInfo);
+					initsWhenTrue.markAsComparedEqualToNull(local); // from thereon it is set
+					initsWhenFalse.markAsComparedEqualToNonNull(local); // from thereon it is set
+				} else {
+					flowContext.recordUsingNullReference(scope, local, reference,
+							FlowContext.CAN_ONLY_NULL_NON_NULL | FlowContext.IN_COMPARISON_NON_NULL, flowInfo);
+					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
+					initsWhenFalse.markAsComparedEqualToNull(local); // from thereon it is set
+				}
+				break;
+			case FlowInfo.NON_NULL :
+				if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+					flowContext.recordUsingNullReference(scope, local, reference,
+							FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NON_NULL, flowInfo);
+					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
+				} else {
+					flowContext.recordUsingNullReference(scope, local, reference,
+							FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NULL, flowInfo);
+				}
+				break;
+		}
+		// we do not impact enclosing try context because this kind of protection
+		// does not preclude the variable from being null in an enclosing scope
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		FlowInfo result;
+		if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+			if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.typeID() == T_boolean)) {
+				if (this.left.constant.booleanValue()) { //  true == anything
+					//  this is equivalent to the right argument inits
+					result = this.right.analyseCode(currentScope, flowContext, flowInfo);
+				} else { // false == anything
+					//  this is equivalent to the right argument inits negated
+					result = this.right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+				}
+			}
+			else if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.typeID() == T_boolean)) {
+				if (this.right.constant.booleanValue()) { //  anything == true
+					//  this is equivalent to the left argument inits
+					result = this.left.analyseCode(currentScope, flowContext, flowInfo);
+				} else { // anything == false
+					//  this is equivalent to the right argument inits negated
+					result = this.left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+				}
+			}
+			else {
+				result = this.right.analyseCode(
+					currentScope, flowContext,
+					this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).unconditionalInits();
+			}
+		} else { //NOT_EQUAL :
+			if ((this.left.constant != Constant.NotAConstant) && (this.left.constant.typeID() == T_boolean)) {
+				if (!this.left.constant.booleanValue()) { //  false != anything
+					//  this is equivalent to the right argument inits
+					result = this.right.analyseCode(currentScope, flowContext, flowInfo);
+				} else { // true != anything
+					//  this is equivalent to the right argument inits negated
+					result = this.right.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+				}
+			}
+			else if ((this.right.constant != Constant.NotAConstant) && (this.right.constant.typeID() == T_boolean)) {
+				if (!this.right.constant.booleanValue()) { //  anything != false
+					//  this is equivalent to the right argument inits
+					result = this.left.analyseCode(currentScope, flowContext, flowInfo);
+				} else { // anything != true
+					//  this is equivalent to the right argument inits negated
+					result = this.left.analyseCode(currentScope, flowContext, flowInfo).asNegatedCondition();
+				}
+			}
+			else {
+				result = this.right.analyseCode(
+					currentScope, flowContext,
+					this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).
+					/* unneeded since we flatten it: asNegatedCondition(). */
+					unconditionalInits();
+			}
+		}
+		if (result instanceof UnconditionalFlowInfo &&
+				(result.tagBits & FlowInfo.UNREACHABLE) == 0) { // the flow info is flat
+			result = FlowInfo.conditional(result.copy(), result.copy());
+			// TODO (maxime) check, reintroduced copy
+		}
+	  checkNullComparison(currentScope, flowContext, result, result.initsWhenTrue(), result.initsWhenFalse());
+	  return result;
+	}
+
+	public final void computeConstant(TypeBinding leftType, TypeBinding rightType) {
+		if ((this.left.constant != Constant.NotAConstant) && (this.right.constant != Constant.NotAConstant)) {
+			this.constant =
+				Constant.computeConstantOperationEQUAL_EQUAL(
+					this.left.constant,
+					leftType.id,
+					this.right.constant,
+					rightType.id);
+			if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL)
+				this.constant = BooleanConstant.fromValue(!this.constant.booleanValue());
+		} else {
+			this.constant = Constant.NotAConstant;
+			// no optimization for null == null
+		}
+	}
+	/**
+	 * Normal == or != code generation.
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		int pc = codeStream.position;
+		if (this.constant != Constant.NotAConstant) {
+			if (valueRequired)
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		if ((this.left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
+			generateBooleanEqual(currentScope, codeStream, valueRequired);
+		} else {
+			generateNonBooleanEqual(currentScope, codeStream, valueRequired);
+		}
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	/**
+	 * Boolean operator code generation
+	 *	Optimized operations are: == and !=
+	 */
+	public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+		if (this.constant != Constant.NotAConstant) {
+			super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			return;
+		}
+		if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+			if ((this.left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
+				generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			} else {
+				generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			}
+		} else {
+			if ((this.left.implicitConversion & COMPILE_TYPE_MASK) /*compile-time*/ == T_boolean) {
+				generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+			} else {
+				generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+			}
+		}
+	}
+
+	/**
+	 * Boolean generation for == with boolean operands
+	 *
+	 * Note this code does not optimize conditional constants !!!!
+	 */
+	public void generateBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		// optimized cases: <something equivalent to true> == x, <something equivalent to false> == x,
+		// optimized cases: <something equivalent to false> != x, <something equivalent to true> != x,
+		boolean isEqualOperator = ((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL;
+		Constant cst = this.left.optimizedBooleanConstant();
+		if (cst != Constant.NotAConstant) {
+			Constant rightCst = this.right.optimizedBooleanConstant();
+			if (rightCst != Constant.NotAConstant) {
+				// <something equivalent to true> == <something equivalent to true>, <something equivalent to false> != <something equivalent to true>
+				// <something equivalent to true> == <something equivalent to false>, <something equivalent to false> != <something equivalent to false>
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, false);
+				if (valueRequired) {
+					boolean leftBool = cst.booleanValue();
+					boolean rightBool = rightCst.booleanValue();
+					if (isEqualOperator) {
+						if (leftBool == rightBool) {
+							codeStream.iconst_1();
+						} else {
+							codeStream.iconst_0();
+						}
+					} else {
+						if (leftBool != rightBool) {
+							codeStream.iconst_1();
+						} else {
+							codeStream.iconst_0();
+						}
+					}
+				}
+			} else if (cst.booleanValue() == isEqualOperator) {
+				// <something equivalent to true> == x, <something equivalent to false> != x
+				this.left.generateCode(currentScope, codeStream, false);
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+			} else {
+				// <something equivalent to false> == x, <something equivalent to true> != x
+				if (valueRequired) {
+					BranchLabel falseLabel = new BranchLabel(codeStream);
+					this.left.generateCode(currentScope, codeStream, false);
+					this.right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
+					// comparison is TRUE
+					codeStream.iconst_0();
+					if ((this.bits & IsReturnedValue) != 0){
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_1();
+					} else {
+						BranchLabel endLabel = new BranchLabel(codeStream);
+						codeStream.goto_(endLabel);
+						codeStream.decrStackSize(1);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_1();
+						endLabel.place();
+					}
+				} else {
+					this.left.generateCode(currentScope, codeStream, false);
+					this.right.generateCode(currentScope, codeStream, false);
+				}
+//				left.generateCode(currentScope, codeStream, false);
+//				right.generateCode(currentScope, codeStream, valueRequired);
+//				if (valueRequired) {
+//					codeStream.iconst_1();
+//					codeStream.ixor(); // negate
+//				}
+			}
+			return;
+		}
+		cst = this.right.optimizedBooleanConstant();
+		if (cst != Constant.NotAConstant) {
+			if (cst.booleanValue() == isEqualOperator) {
+				// x == <something equivalent to true>, x != <something equivalent to false>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				this.right.generateCode(currentScope, codeStream, false);
+			} else {
+				// x == <something equivalent to false>, x != <something equivalent to true>
+				if (valueRequired) {
+					BranchLabel falseLabel = new BranchLabel(codeStream);
+					this.left.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired);
+					this.right.generateCode(currentScope, codeStream, false);
+					// comparison is TRUE
+					codeStream.iconst_0();
+					if ((this.bits & IsReturnedValue) != 0){
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_1();
+					} else {
+						BranchLabel endLabel = new BranchLabel(codeStream);
+						codeStream.goto_(endLabel);
+						codeStream.decrStackSize(1);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_1();
+						endLabel.place();
+					}
+				} else {
+					this.left.generateCode(currentScope, codeStream, false);
+					this.right.generateCode(currentScope, codeStream, false);
+				}
+//				left.generateCode(currentScope, codeStream, valueRequired);
+//				right.generateCode(currentScope, codeStream, false);
+//				if (valueRequired) {
+//					codeStream.iconst_1();
+//					codeStream.ixor(); // negate
+//				}
+			}
+			return;
+		}
+		// default case
+		this.left.generateCode(currentScope, codeStream, valueRequired);
+		this.right.generateCode(currentScope, codeStream, valueRequired);
+
+		if (valueRequired) {
+			if (isEqualOperator) {
+				BranchLabel falseLabel;
+				codeStream.if_icmpne(falseLabel = new BranchLabel(codeStream));
+				// comparison is TRUE
+				codeStream.iconst_1();
+				if ((this.bits & IsReturnedValue) != 0){
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					// comparison is FALSE
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					BranchLabel endLabel = new BranchLabel(codeStream);
+					codeStream.goto_(endLabel);
+					codeStream.decrStackSize(1);
+					// comparison is FALSE
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			} else {
+				codeStream.ixor();
+			}
+		}
+	}
+
+	/**
+	 * Boolean generation for == with boolean operands
+	 *
+	 * Note this code does not optimize conditional constants !!!!
+	 */
+	public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+		// optimized cases: true == x, false == x
+		if (this.left.constant != Constant.NotAConstant) {
+			boolean inline = this.left.constant.booleanValue();
+			this.right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+			return;
+		} // optimized cases: x == true, x == false
+		if (this.right.constant != Constant.NotAConstant) {
+			boolean inline = this.right.constant.booleanValue();
+			this.left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+			return;
+		}
+		// default case
+		this.left.generateCode(currentScope, codeStream, valueRequired);
+		this.right.generateCode(currentScope, codeStream, valueRequired);
+		int pc = codeStream.position;
+		if (valueRequired) {
+			if (falseLabel == null) {
+				if (trueLabel != null) {
+					// implicit falling through the FALSE case
+					codeStream.if_icmpeq(trueLabel);
+				}
+			} else {
+				// implicit falling through the TRUE case
+				if (trueLabel == null) {
+					codeStream.if_icmpne(falseLabel);
+				} else {
+					// no implicit fall through TRUE/FALSE --> should never occur
+				}
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceEnd);
+	}
+	/**
+	 * Boolean generation for == with non-boolean operands
+	 *
+	 */
+	public void generateNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		boolean isEqualOperator = ((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL;
+		if (((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_int) {
+			Constant cst;
+			if ((cst = this.left.constant) != Constant.NotAConstant && cst.intValue() == 0) {
+				// optimized case: 0 == x, 0 != x
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					BranchLabel falseLabel = new BranchLabel(codeStream);
+					if (isEqualOperator) {
+						codeStream.ifne(falseLabel);
+					} else {
+						codeStream.ifeq(falseLabel);
+					}
+					// comparison is TRUE
+					codeStream.iconst_1();
+					if ((this.bits & IsReturnedValue) != 0){
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+					} else {
+						BranchLabel endLabel = new BranchLabel(codeStream);
+						codeStream.goto_(endLabel);
+						codeStream.decrStackSize(1);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+						endLabel.place();
+					}
+				}
+				return;
+			}
+			if ((cst = this.right.constant) != Constant.NotAConstant && cst.intValue() == 0) {
+				// optimized case: x == 0, x != 0
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					BranchLabel falseLabel = new BranchLabel(codeStream);
+					if (isEqualOperator) {
+						codeStream.ifne(falseLabel);
+					} else {
+						codeStream.ifeq(falseLabel);
+					}
+					// comparison is TRUE
+					codeStream.iconst_1();
+					if ((this.bits & IsReturnedValue) != 0){
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+					} else {
+						BranchLabel endLabel = new BranchLabel(codeStream);
+						codeStream.goto_(endLabel);
+						codeStream.decrStackSize(1);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+						endLabel.place();
+					}
+				}
+				return;
+			}
+		}
+
+		// null cases
+		if (this.right instanceof NullLiteral) {
+			if (this.left instanceof NullLiteral) {
+				// null == null, null != null
+				if (valueRequired) {
+					if (isEqualOperator) {
+						codeStream.iconst_1();
+					} else {
+						codeStream.iconst_0();
+					}
+				}
+			} else {
+				// x == null, x != null
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					BranchLabel falseLabel = new BranchLabel(codeStream);
+					if (isEqualOperator) {
+						codeStream.ifnonnull(falseLabel);
+					} else {
+						codeStream.ifnull(falseLabel);
+					}
+					// comparison is TRUE
+					codeStream.iconst_1();
+					if ((this.bits & IsReturnedValue) != 0){
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+					} else {
+						BranchLabel endLabel = new BranchLabel(codeStream);
+						codeStream.goto_(endLabel);
+						codeStream.decrStackSize(1);
+						// comparison is FALSE
+						falseLabel.place();
+						codeStream.iconst_0();
+						endLabel.place();
+					}
+				}
+			}
+			return;
+		} else if (this.left instanceof NullLiteral) {
+			// null = x, null != x
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				BranchLabel falseLabel = new BranchLabel(codeStream);
+				if (isEqualOperator) {
+					codeStream.ifnonnull(falseLabel);
+				} else {
+					codeStream.ifnull(falseLabel);
+				}
+				// comparison is TRUE
+				codeStream.iconst_1();
+				if ((this.bits & IsReturnedValue) != 0){
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
+					// comparison is FALSE
+					falseLabel.place();
+					codeStream.iconst_0();
+				} else {
+					BranchLabel endLabel = new BranchLabel(codeStream);
+					codeStream.goto_(endLabel);
+					codeStream.decrStackSize(1);
+					// comparison is FALSE
+					falseLabel.place();
+					codeStream.iconst_0();
+					endLabel.place();
+				}
+			}
+			return;
+		}
+
+		// default case
+		this.left.generateCode(currentScope, codeStream, valueRequired);
+		this.right.generateCode(currentScope, codeStream, valueRequired);
+		if (valueRequired) {
+			BranchLabel falseLabel = new BranchLabel(codeStream);
+			if (isEqualOperator) {
+				switch ((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type
+					case T_int :
+						codeStream.if_icmpne(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifne(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifne(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifne(falseLabel);
+						break;
+					default :
+						codeStream.if_acmpne(falseLabel);
+				}
+			} else {
+				switch ((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type
+					case T_int :
+						codeStream.if_icmpeq(falseLabel);
+						break;
+					case T_float :
+						codeStream.fcmpl();
+						codeStream.ifeq(falseLabel);
+						break;
+					case T_long :
+						codeStream.lcmp();
+						codeStream.ifeq(falseLabel);
+						break;
+					case T_double :
+						codeStream.dcmpl();
+						codeStream.ifeq(falseLabel);
+						break;
+					default :
+						codeStream.if_acmpeq(falseLabel);
+				}
+			}
+			// comparison is TRUE
+			codeStream.iconst_1();
+			if ((this.bits & IsReturnedValue) != 0){
+				codeStream.generateImplicitConversion(this.implicitConversion);
+				codeStream.generateReturnBytecode(this);
+				// comparison is FALSE
+				falseLabel.place();
+				codeStream.iconst_0();
+			} else {
+				BranchLabel endLabel = new BranchLabel(codeStream);
+				codeStream.goto_(endLabel);
+				codeStream.decrStackSize(1);
+				// comparison is FALSE
+				falseLabel.place();
+				codeStream.iconst_0();
+				endLabel.place();
+			}
+		}
+	}
+
+	/**
+	 * Boolean generation for == with non-boolean operands
+	 *
+	 */
+	public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+		int pc = codeStream.position;
+		Constant inline;
+		if ((inline = this.right.constant) != Constant.NotAConstant) {
+			// optimized case: x == 0
+			if ((((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_int) && (inline.intValue() == 0)) {
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					if (falseLabel == null) {
+						if (trueLabel != null) {
+							// implicit falling through the FALSE case
+							codeStream.ifeq(trueLabel);
+						}
+					} else {
+						// implicit falling through the TRUE case
+						if (trueLabel == null) {
+							codeStream.ifne(falseLabel);
+						} else {
+							// no implicit fall through TRUE/FALSE --> should never occur
+						}
+					}
+				}
+				codeStream.recordPositionsFrom(pc, this.sourceStart);
+				return;
+			}
+		}
+		if ((inline = this.left.constant) != Constant.NotAConstant) {
+			// optimized case: 0 == x
+			if ((((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_int)
+				&& (inline.intValue() == 0)) {
+				this.right.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					if (falseLabel == null) {
+						if (trueLabel != null) {
+							// implicit falling through the FALSE case
+							codeStream.ifeq(trueLabel);
+						}
+					} else {
+						// implicit falling through the TRUE case
+						if (trueLabel == null) {
+							codeStream.ifne(falseLabel);
+						} else {
+							// no implicit fall through TRUE/FALSE --> should never occur
+						}
+					}
+				}
+				codeStream.recordPositionsFrom(pc, this.sourceStart);
+				return;
+			}
+		}
+		// null cases
+		// optimized case: x == null
+		if (this.right instanceof NullLiteral) {
+			if (this.left instanceof NullLiteral) {
+				// null == null
+				if (valueRequired) {
+					if (falseLabel == null) {
+						// implicit falling through the FALSE case
+						if (trueLabel != null) {
+							codeStream.goto_(trueLabel);
+						}
+					}
+				}
+			} else {
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+				if (valueRequired) {
+					if (falseLabel == null) {
+						if (trueLabel != null) {
+							// implicit falling through the FALSE case
+							codeStream.ifnull(trueLabel);
+						}
+					} else {
+						// implicit falling through the TRUE case
+						if (trueLabel == null) {
+							codeStream.ifnonnull(falseLabel);
+						} else {
+							// no implicit fall through TRUE/FALSE --> should never occur
+						}
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		} else if (this.left instanceof NullLiteral) { // optimized case: null == x
+			this.right.generateCode(currentScope, codeStream, valueRequired);
+			if (valueRequired) {
+				if (falseLabel == null) {
+					if (trueLabel != null) {
+						// implicit falling through the FALSE case
+						codeStream.ifnull(trueLabel);
+					}
+				} else {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.ifnonnull(falseLabel);
+					} else {
+						// no implicit fall through TRUE/FALSE --> should never occur
+					}
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		// default case
+		this.left.generateCode(currentScope, codeStream, valueRequired);
+		this.right.generateCode(currentScope, codeStream, valueRequired);
+		if (valueRequired) {
+			if (falseLabel == null) {
+				if (trueLabel != null) {
+					// implicit falling through the FALSE case
+					switch ((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type
+						case T_int :
+							codeStream.if_icmpeq(trueLabel);
+							break;
+						case T_float :
+							codeStream.fcmpl();
+							codeStream.ifeq(trueLabel);
+							break;
+						case T_long :
+							codeStream.lcmp();
+							codeStream.ifeq(trueLabel);
+							break;
+						case T_double :
+							codeStream.dcmpl();
+							codeStream.ifeq(trueLabel);
+							break;
+						default :
+							codeStream.if_acmpeq(trueLabel);
+					}
+				}
+			} else {
+				// implicit falling through the TRUE case
+				if (trueLabel == null) {
+					switch ((this.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { // operand runtime type
+						case T_int :
+							codeStream.if_icmpne(falseLabel);
+							break;
+						case T_float :
+							codeStream.fcmpl();
+							codeStream.ifne(falseLabel);
+							break;
+						case T_long :
+							codeStream.lcmp();
+							codeStream.ifne(falseLabel);
+							break;
+						case T_double :
+							codeStream.dcmpl();
+							codeStream.ifne(falseLabel);
+							break;
+						default :
+							codeStream.if_acmpne(falseLabel);
+					}
+				} else {
+					// no implicit fall through TRUE/FALSE --> should never occur
+				}
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	public boolean isCompactableOperation() {
+		return false;
+	}
+	public TypeBinding resolveType(BlockScope scope) {
+
+			boolean leftIsCast, rightIsCast;
+			if ((leftIsCast = this.left instanceof CastExpression) == true) this.left.bits |= DisableUnnecessaryCastCheck; // will check later on
+			TypeBinding originalLeftType = this.left.resolveType(scope);
+
+			if ((rightIsCast = this.right instanceof CastExpression) == true) this.right.bits |= DisableUnnecessaryCastCheck; // will check later on
+			TypeBinding originalRightType = this.right.resolveType(scope);
+
+		// always return BooleanBinding
+		if (originalLeftType == null || originalRightType == null){
+			this.constant = Constant.NotAConstant;
+			return null;
+		}
+
+		// autoboxing support
+		boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		TypeBinding leftType = originalLeftType, rightType = originalRightType;
+		if (use15specifics) {
+			if (leftType != TypeBinding.NULL && leftType.isBaseType()) {
+				if (!rightType.isBaseType()) {
+					rightType = scope.environment().computeBoxingType(rightType);
+				}
+			} else {
+				if (rightType != TypeBinding.NULL && rightType.isBaseType()) {
+					leftType = scope.environment().computeBoxingType(leftType);
+				}
+			}
+		}
+		// both base type
+		if (leftType.isBaseType() && rightType.isBaseType()) {
+			int leftTypeID = leftType.id;
+			int rightTypeID = rightType.id;
+
+			// the code is an int
+			// (cast)  left   == (cast)  right --> result
+			//  0000   0000       0000   0000      0000
+			//  <<16   <<12       <<8    <<4       <<0
+			int operatorSignature = OperatorSignatures[EQUAL_EQUAL][ (leftTypeID << 4) + rightTypeID];
+			this.left.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), originalLeftType);
+			this.right.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), originalRightType);
+			this.bits |= operatorSignature & 0xF;
+			if ((operatorSignature & 0x0000F) == T_undefined) {
+				this.constant = Constant.NotAConstant;
+				scope.problemReporter().invalidOperator(this, leftType, rightType);
+				return null;
+			}
+			// check need for operand cast
+			if (leftIsCast || rightIsCast) {
+				CastExpression.checkNeedForArgumentCasts(scope, EQUAL_EQUAL, operatorSignature, this.left, leftType.id, leftIsCast, this.right, rightType.id, rightIsCast);
+			}
+			computeConstant(leftType, rightType);
+
+			// check whether comparing identical expressions
+			Binding leftDirect = Expression.getDirectBinding(this.left);
+			if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) {
+				if (leftTypeID != TypeIds.T_double && leftTypeID != TypeIds.T_float
+						&&(!(this.right instanceof Assignment))) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=281776
+					scope.problemReporter().comparingIdenticalExpressions(this);
+			} else if (this.constant != Constant.NotAConstant) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=276740
+				int operator = (this.bits & OperatorMASK) >> OperatorSHIFT;
+				if ((operator == EQUAL_EQUAL && this.constant == BooleanConstant.fromValue(true))
+						|| (operator == NOT_EQUAL && this.constant == BooleanConstant.fromValue(false)))
+					scope.problemReporter().comparingIdenticalExpressions(this);
+			}
+			return this.resolvedType = TypeBinding.BOOLEAN;
+		}
+
+		// Object references
+		// spec 15.20.3
+		if ((!leftType.isBaseType() || leftType == TypeBinding.NULL) // cannot compare: Object == (int)0
+				&& (!rightType.isBaseType() || rightType == TypeBinding.NULL)
+				&& (checkCastTypesCompatibility(scope, leftType, rightType, null)
+						|| checkCastTypesCompatibility(scope, rightType, leftType, null))) {
+
+			// (special case for String)
+			if ((rightType.id == T_JavaLangString) && (leftType.id == T_JavaLangString)) {
+				computeConstant(leftType, rightType);
+			} else {
+				this.constant = Constant.NotAConstant;
+			}
+			TypeBinding objectType = scope.getJavaLangObject();
+			this.left.computeConversion(scope, objectType, leftType);
+			this.right.computeConversion(scope, objectType, rightType);
+			// check need for operand cast
+			boolean unnecessaryLeftCast = (this.left.bits & UnnecessaryCast) != 0;
+			boolean unnecessaryRightCast = (this.right.bits & UnnecessaryCast) != 0;
+			if (unnecessaryLeftCast || unnecessaryRightCast) {
+				TypeBinding alternateLeftType = unnecessaryLeftCast ? ((CastExpression)this.left).expression.resolvedType : leftType;
+				TypeBinding alternateRightType = unnecessaryRightCast ? ((CastExpression)this.right).expression.resolvedType : rightType;
+				if (checkCastTypesCompatibility(scope, alternateLeftType, alternateRightType, null)
+						|| checkCastTypesCompatibility(scope, alternateRightType, alternateLeftType, null)) {
+					if (unnecessaryLeftCast) scope.problemReporter().unnecessaryCast((CastExpression)this.left);
+					if (unnecessaryRightCast) scope.problemReporter().unnecessaryCast((CastExpression)this.right);
+				}
+			}
+			// check whether comparing identical expressions
+			Binding leftDirect = Expression.getDirectBinding(this.left);
+			if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) {
+				if (!(this.right instanceof Assignment)) {
+					scope.problemReporter().comparingIdenticalExpressions(this);
+				}
+			}
+			return this.resolvedType = TypeBinding.BOOLEAN;
+		}
+		this.constant = Constant.NotAConstant;
+		scope.problemReporter().notCompatibleTypesError(this, leftType, rightType);
+		return null;
+	}
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			this.left.traverse(visitor, scope);
+			this.right.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..89b0e42
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 361407 - Resource leak warning when resource is assigned to a field outside of constructor
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+public class ExplicitConstructorCall extends Statement implements InvocationSite, ExpressionContext {
+
+	public Expression[] arguments;
+	public Expression qualification;
+	public MethodBinding binding;							// exact binding resulting from lookup
+	MethodBinding syntheticAccessor;						// synthetic accessor for inner-emulation
+	public int accessMode;
+	public TypeReference[] typeArguments;
+	public TypeBinding[] genericTypeArguments;
+
+	public final static int ImplicitSuper = 1;
+	public final static int Super = 2;
+	public final static int This = 3;
+
+	public VariableBinding[][] implicitArguments;
+
+	// TODO Remove once DOMParser is activated
+	public int typeArgumentsSourceStart;
+
+	public ExplicitConstructorCall(int accessMode) {
+		this.accessMode = accessMode;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		// must verify that exceptions potentially thrown by this expression are caught in the method.
+
+		try {
+			((MethodScope) currentScope).isConstructorCall = true;
+
+			// process enclosing instance
+			if (this.qualification != null) {
+				flowInfo =
+					this.qualification
+						.analyseCode(currentScope, flowContext, flowInfo)
+						.unconditionalInits();
+			}
+			// process arguments
+			if (this.arguments != null) {
+				boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					flowInfo =
+						this.arguments[i]
+							.analyseCode(currentScope, flowContext, flowInfo)
+							.unconditionalInits();
+					if (analyseResources) {
+						// if argument is an AutoCloseable insert info that it *may* be closed (by the target constructor, i.e.)
+						flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
+					}
+					this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+				}
+				analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
+			}
+
+			ReferenceBinding[] thrownExceptions;
+			if ((thrownExceptions = this.binding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
+				if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+					thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
+				}				
+				// check exceptions
+				flowContext.checkExceptionHandlers(
+					thrownExceptions,
+					(this.accessMode == ExplicitConstructorCall.ImplicitSuper)
+						? (ASTNode) currentScope.methodScope().referenceContext
+						: (ASTNode) this,
+					flowInfo,
+					currentScope);
+			}
+			manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+			manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+			return flowInfo;
+		} finally {
+			((MethodScope) currentScope).isConstructorCall = false;
+		}
+	}
+
+	/**
+	 * Constructor call code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+		if ((this.bits & ASTNode.IsReachable) == 0) {
+			return;
+		}
+		try {
+			((MethodScope) currentScope).isConstructorCall = true;
+
+			int pc = codeStream.position;
+			codeStream.aload_0();
+
+			MethodBinding codegenBinding = this.binding.original();
+			ReferenceBinding targetType = codegenBinding.declaringClass;
+
+			// special name&ordinal argument generation for enum constructors
+			if (targetType.erasure().id == TypeIds.T_JavaLangEnum || targetType.isEnum()) {
+				codeStream.aload_1(); // pass along name param as name arg
+				codeStream.iload_2(); // pass along ordinal param as ordinal arg
+			}
+			// handling innerclass constructor invocation
+			// handling innerclass instance allocation - enclosing instance arguments
+			if (targetType.isNestedType()) {
+				codeStream.generateSyntheticEnclosingInstanceValues(
+					currentScope,
+					targetType,
+					(this.bits & ASTNode.DiscardEnclosingInstance) != 0 ? null : this.qualification,
+					this);
+			}
+			// generate arguments
+			generateArguments(this.binding, this.arguments, currentScope, codeStream);
+
+			// handling innerclass instance allocation - outer local arguments
+			if (targetType.isNestedType()) {
+				codeStream.generateSyntheticOuterArgumentValues(
+					currentScope,
+					targetType,
+					this);
+			}
+			if (this.syntheticAccessor != null) {
+				// synthetic accessor got some extra arguments appended to its signature, which need values
+				for (int i = 0,
+					max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
+					i < max;
+					i++) {
+					codeStream.aconst_null();
+				}
+				codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */);
+			} else {
+				codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		} finally {
+			((MethodScope) currentScope).isConstructorCall = false;
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+	 */
+	public TypeBinding[] genericTypeArguments() {
+		return this.genericTypeArguments;
+	}
+
+	public boolean isImplicitSuper() {
+		return (this.accessMode == ExplicitConstructorCall.ImplicitSuper);
+	}
+
+	public boolean isSuperAccess() {
+		return this.accessMode != ExplicitConstructorCall.This;
+	}
+
+	public boolean isTypeAccess() {
+		return true;
+	}
+
+	/* Inner emulation consists in either recording a dependency
+	 * link only, or performing one level of propagation.
+	 *
+	 * Dependency mechanism is used whenever dealing with source target
+	 * types, since by the time we reach them, we might not yet know their
+	 * exact need.
+	 */
+	void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+		ReferenceBinding superTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
+
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+		// perform some emulation work in case there is some and we are inside a local type only
+		if (superTypeErasure.isNestedType()
+			&& currentScope.enclosingSourceType().isLocalType()) {
+
+			if (superTypeErasure.isLocalType()) {
+				((LocalTypeBinding) superTypeErasure).addInnerEmulationDependent(currentScope, this.qualification != null);
+			} else {
+				// locally propagate, since we already now the desired shape for sure
+				currentScope.propagateInnerEmulation(superTypeErasure, this.qualification != null);
+			}
+		}
+		}
+	}
+
+	public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+			// if constructor from parameterized type got found, use the original constructor at codegen time
+			MethodBinding codegenBinding = this.binding.original();
+
+			// perform some emulation work in case there is some and we are inside a local type only
+			if (this.binding.isPrivate() && this.accessMode != ExplicitConstructorCall.This) {
+				ReferenceBinding declaringClass = codegenBinding.declaringClass;
+				// from 1.4 on, local type constructor can lose their private flag to ease emulation
+				if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+					// constructor will not be dumped as private, no emulation required thus
+					codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
+				} else {
+					this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
+					currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+				}
+			}
+		}
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		printIndent(indent, output);
+		if (this.qualification != null) this.qualification.printExpression(0, output).append('.');
+		if (this.typeArguments != null) {
+			output.append('<');
+			int max = this.typeArguments.length - 1;
+			for (int j = 0; j < max; j++) {
+				this.typeArguments[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+			output.append('>');
+		}
+		if (this.accessMode == ExplicitConstructorCall.This) {
+			output.append("this("); //$NON-NLS-1$
+		} else {
+			output.append("super("); //$NON-NLS-1$
+		}
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(");"); //$NON-NLS-1$
+	}
+
+	public void resolve(BlockScope scope) {
+		// the return type should be void for a constructor.
+		// the test is made into getConstructor
+
+		// mark the fact that we are in a constructor call.....
+		// unmark at all returns
+		MethodScope methodScope = scope.methodScope();
+		try {
+			AbstractMethodDeclaration methodDeclaration = methodScope.referenceMethod();
+			if (methodDeclaration == null
+					|| !methodDeclaration.isConstructor()
+					|| ((ConstructorDeclaration) methodDeclaration).constructorCall != this) {
+				scope.problemReporter().invalidExplicitConstructorCall(this);
+				// fault-tolerance
+				if (this.qualification != null) {
+					this.qualification.resolveType(scope);
+				}
+				if (this.typeArguments != null) {
+					for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+						this.typeArguments[i].resolveType(scope, true /* check bounds*/);
+					}
+				}
+				if (this.arguments != null) {
+					for (int i = 0, max = this.arguments.length; i < max; i++) {
+						this.arguments[i].resolveType(scope);
+					}
+				}
+				return;
+			}
+			methodScope.isConstructorCall = true;
+			ReferenceBinding receiverType = scope.enclosingReceiverType();
+			boolean rcvHasError = false;
+			if (this.accessMode != ExplicitConstructorCall.This) {
+				receiverType = receiverType.superclass();
+				TypeReference superclassRef = scope.referenceType().superclass;
+				if (superclassRef != null && superclassRef.resolvedType != null && !superclassRef.resolvedType.isValidBinding()) {
+					rcvHasError = true;
+				}
+			}
+			if (receiverType != null) {
+				// prevent (explicit) super constructor invocation from within enum
+				if (this.accessMode == ExplicitConstructorCall.Super && receiverType.erasure().id == TypeIds.T_JavaLangEnum) {
+					scope.problemReporter().cannotInvokeSuperConstructorInEnum(this, methodScope.referenceMethod().binding);
+				}
+				// qualification should be from the type of the enclosingType
+				if (this.qualification != null) {
+					if (this.accessMode != ExplicitConstructorCall.Super) {
+						scope.problemReporter().unnecessaryEnclosingInstanceSpecification(
+							this.qualification,
+							receiverType);
+					}
+					if (!rcvHasError) {
+						ReferenceBinding enclosingType = receiverType.enclosingType();
+						if (enclosingType == null) {
+							scope.problemReporter().unnecessaryEnclosingInstanceSpecification(this.qualification, receiverType);
+							this.bits |= ASTNode.DiscardEnclosingInstance;
+						} else {
+							TypeBinding qTb = this.qualification.resolveTypeExpecting(scope, enclosingType);
+							this.qualification.computeConversion(scope, qTb, qTb);
+						}
+					}
+				}
+			}
+			// resolve type arguments (for generic constructor call)
+			if (this.typeArguments != null) {
+				boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+				int length = this.typeArguments.length;
+				this.genericTypeArguments = new TypeBinding[length];
+				for (int i = 0; i < length; i++) {
+					TypeReference typeReference = this.typeArguments[i];
+					if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+						argHasError = true;
+					}
+					if (argHasError && typeReference instanceof Wildcard) {
+						scope.problemReporter().illegalUsageOfWildcard(typeReference);
+					}
+				}
+				if (argHasError) {
+					if (this.arguments != null) { // still attempt to resolve arguments
+						for (int i = 0, max = this.arguments.length; i < max; i++) {
+							this.arguments[i].resolveType(scope);
+						}
+					}
+					return;
+				}
+			}
+			// arguments buffering for the method lookup
+			TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+			boolean argsContainCast = false;
+			boolean polyExpressionSeen = false;
+			if (this.arguments != null) {
+				boolean argHasError = false; // typeChecks all arguments
+				int length = this.arguments.length;
+				argumentTypes = new TypeBinding[length];
+				TypeBinding argumentType;
+				for (int i = 0; i < length; i++) {
+					Expression argument = this.arguments[i];
+					if (argument instanceof CastExpression) {
+						argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+						argsContainCast = true;
+					}
+					argument.setExpressionContext(INVOCATION_CONTEXT);
+					if ((argumentType = argumentTypes[i] = argument.resolveType(scope)) == null) {
+						argHasError = true;
+					}
+					if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+						polyExpressionSeen = true;
+				}
+				if (argHasError) {
+					if (receiverType == null) {
+						return;
+					}
+					// record a best guess, for clients who need hint about possible contructor match
+					TypeBinding[] pseudoArgs = new TypeBinding[length];
+					for (int i = length; --i >= 0;) {
+						pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+					}
+					this.binding = scope.findMethod(receiverType, TypeConstants.INIT, pseudoArgs, this);
+					if (this.binding != null && !this.binding.isValidBinding()) {
+						MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+						// record the closest match, for clients who may still need hint about possible method match
+						if (closestMatch != null) {
+							if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
+								// shouldn't return generic method outside its context, rather convert it to raw method (175409)
+								closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
+							}
+							this.binding = closestMatch;
+							MethodBinding closestMatchOriginal = closestMatch.original();
+							if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
+								// ignore cases where method is used from within inside itself (e.g. direct recursions)
+								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+							}
+						}
+					}
+					return;
+				}
+			} else if (receiverType.erasure().id == TypeIds.T_JavaLangEnum) {
+				// TODO (philippe) get rid of once well-known binding is available
+				argumentTypes = new TypeBinding[] { scope.getJavaLangString(), TypeBinding.INT };
+			}
+			if (receiverType == null) {
+				return;
+			}
+			this.binding = scope.getConstructor(receiverType, argumentTypes, this);
+			if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+				return;
+			if (this.binding.isValidBinding()) {
+				if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
+					if (!methodScope.enclosingSourceType().isAnonymousType()) {
+						scope.problemReporter().missingTypeInConstructor(this, this.binding);
+					}
+				}
+				if (isMethodUseDeprecated(this.binding, scope, this.accessMode != ExplicitConstructorCall.ImplicitSuper)) {
+					scope.problemReporter().deprecatedMethod(this.binding, this);
+				}
+				if (checkInvocationArguments(scope, null, receiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+					this.bits |= ASTNode.Unchecked;
+				}
+				if (this.binding.isOrEnclosedByPrivateType()) {
+					this.binding.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+				}
+				if (this.typeArguments != null
+						&& this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+					scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
+				}
+			} else {
+				if (this.binding.declaringClass == null) {
+					this.binding.declaringClass = receiverType;
+				}
+				if (rcvHasError)
+					return;
+				scope.problemReporter().invalidConstructor(this, this.binding);
+			}
+		} finally {
+			methodScope.isConstructorCall = false;
+		}
+	}
+
+	public void setActualReceiverType(ReferenceBinding receiverType) {
+		// ignored
+	}
+
+	public void setDepth(int depth) {
+		// ignore for here
+	}
+
+	public void setFieldIndex(int depth) {
+		// ignore for here
+	}
+	
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.qualification != null) {
+				this.qualification.traverse(visitor, scope);
+			}
+			if (this.typeArguments != null) {
+				for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+					this.typeArguments[i].traverse(visitor, scope);
+				}
+			}
+			if (this.arguments != null) {
+				for (int i = 0, argumentLength = this.arguments.length; i < argumentLength; i++)
+					this.arguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..8b6189a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -0,0 +1,1220 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *								bug 292478 - Report potentially null across variable assignment
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+
+public abstract class Expression extends Statement implements ExpressionContext {
+
+	public Constant constant;
+
+	public int statementEnd = -1;
+
+	//Some expression may not be used - from a java semantic point
+	//of view only - as statements. Other may. In order to avoid the creation
+	//of wrappers around expression in order to tune them as expression
+	//Expression is a subclass of Statement. See the message isValidJavaStatement()
+
+	public int implicitConversion;
+	public TypeBinding resolvedType;
+
+public static final boolean isConstantValueRepresentable(Constant constant, int constantTypeID, int targetTypeID) {
+	//true if there is no loss of precision while casting.
+	// constantTypeID == constant.typeID
+	if (targetTypeID == constantTypeID)
+		return true;
+	switch (targetTypeID) {
+		case T_char :
+			switch (constantTypeID) {
+				case T_char :
+					return true;
+				case T_double :
+					return constant.doubleValue() == constant.charValue();
+				case T_float :
+					return constant.floatValue() == constant.charValue();
+				case T_int :
+					return constant.intValue() == constant.charValue();
+				case T_short :
+					return constant.shortValue() == constant.charValue();
+				case T_byte :
+					return constant.byteValue() == constant.charValue();
+				case T_long :
+					return constant.longValue() == constant.charValue();
+				default :
+					return false;//boolean
+			}
+
+		case T_float :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.floatValue();
+				case T_double :
+					return constant.doubleValue() == constant.floatValue();
+				case T_float :
+					return true;
+				case T_int :
+					return constant.intValue() == constant.floatValue();
+				case T_short :
+					return constant.shortValue() == constant.floatValue();
+				case T_byte :
+					return constant.byteValue() == constant.floatValue();
+				case T_long :
+					return constant.longValue() == constant.floatValue();
+				default :
+					return false;//boolean
+			}
+
+		case T_double :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.doubleValue();
+				case T_double :
+					return true;
+				case T_float :
+					return constant.floatValue() == constant.doubleValue();
+				case T_int :
+					return constant.intValue() == constant.doubleValue();
+				case T_short :
+					return constant.shortValue() == constant.doubleValue();
+				case T_byte :
+					return constant.byteValue() == constant.doubleValue();
+				case T_long :
+					return constant.longValue() == constant.doubleValue();
+				default :
+					return false; //boolean
+			}
+
+		case T_byte :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.byteValue();
+				case T_double :
+					return constant.doubleValue() == constant.byteValue();
+				case T_float :
+					return constant.floatValue() == constant.byteValue();
+				case T_int :
+					return constant.intValue() == constant.byteValue();
+				case T_short :
+					return constant.shortValue() == constant.byteValue();
+				case T_byte :
+					return true;
+				case T_long :
+					return constant.longValue() == constant.byteValue();
+				default :
+					return false; //boolean
+			}
+
+		case T_short :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.shortValue();
+				case T_double :
+					return constant.doubleValue() == constant.shortValue();
+				case T_float :
+					return constant.floatValue() == constant.shortValue();
+				case T_int :
+					return constant.intValue() == constant.shortValue();
+				case T_short :
+					return true;
+				case T_byte :
+					return constant.byteValue() == constant.shortValue();
+				case T_long :
+					return constant.longValue() == constant.shortValue();
+				default :
+					return false; //boolean
+			}
+
+		case T_int :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.intValue();
+				case T_double :
+					return constant.doubleValue() == constant.intValue();
+				case T_float :
+					return constant.floatValue() == constant.intValue();
+				case T_int :
+					return true;
+				case T_short :
+					return constant.shortValue() == constant.intValue();
+				case T_byte :
+					return constant.byteValue() == constant.intValue();
+				case T_long :
+					return constant.longValue() == constant.intValue();
+				default :
+					return false; //boolean
+			}
+
+		case T_long :
+			switch (constantTypeID) {
+				case T_char :
+					return constant.charValue() == constant.longValue();
+				case T_double :
+					return constant.doubleValue() == constant.longValue();
+				case T_float :
+					return constant.floatValue() == constant.longValue();
+				case T_int :
+					return constant.intValue() == constant.longValue();
+				case T_short :
+					return constant.shortValue() == constant.longValue();
+				case T_byte :
+					return constant.byteValue() == constant.longValue();
+				case T_long :
+					return true;
+				default :
+					return false; //boolean
+			}
+
+		default :
+			return false; //boolean
+	}
+}
+
+public Expression() {
+	super();
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return flowInfo;
+}
+
+/**
+ * More sophisticated for of the flow analysis used for analyzing expressions, and be able to optimize out
+ * portions of expressions where no actual value is required.
+ *
+ * @param currentScope
+ * @param flowContext
+ * @param flowInfo
+ * @param valueRequired
+ * @return The state of initialization after the analysis of the current expression
+ */
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	return analyseCode(currentScope, flowContext, flowInfo);
+}
+
+/**
+ * Returns false if cast is not legal.
+ */
+public final boolean checkCastTypesCompatibility(Scope scope, TypeBinding castType, TypeBinding expressionType, Expression expression) {
+	// see specifications 5.5
+	// handle errors and process constant when needed
+
+	// if either one of the type is null ==>
+	// some error has been already reported some where ==>
+	// we then do not report an obvious-cascade-error.
+
+	if (castType == null || expressionType == null) return true;
+
+	// identity conversion cannot be performed upfront, due to side-effects
+	// like constant propagation
+	boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+	boolean use17specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7;
+	if (castType.isBaseType()) {
+		if (expressionType.isBaseType()) {
+			if (expressionType == castType) {
+				if (expression != null) {
+					this.constant = expression.constant; //use the same constant
+				}
+				tagAsUnnecessaryCast(scope, castType);
+				return true;
+			}
+			boolean necessary = false;
+			if (expressionType.isCompatibleWith(castType)
+					|| (necessary = BaseTypeBinding.isNarrowing(castType.id, expressionType.id))) {
+				if (expression != null) {
+					expression.implicitConversion = (castType.id << 4) + expressionType.id;
+					if (expression.constant != Constant.NotAConstant) {
+						this.constant = expression.constant.castTo(expression.implicitConversion);
+					}
+				}
+				if (!necessary) tagAsUnnecessaryCast(scope, castType);
+				return true;
+
+			}
+		} else if (use17specifics && expressionType.id == TypeIds.T_JavaLangObject){
+			// cast from Object to base type allowed from 1.7, see JLS $5.5
+			return true;
+		} else if (use15specifics
+							&& scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { // unboxing - only widening match is allowed
+			tagAsUnnecessaryCast(scope, castType);
+			return true;
+		}
+		return false;
+	} else if (use15specifics
+						&& expressionType.isBaseType()
+						&& scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { // boxing - only widening match is allowed
+		tagAsUnnecessaryCast(scope, castType);
+		return true;
+	}
+
+	if (castType.isIntersectionCastType()) {
+		ReferenceBinding [] intersectingTypes = castType.getIntersectingTypes();
+		for (int i = 0, length = intersectingTypes.length; i < length; i++) {
+			if (!checkCastTypesCompatibility(scope, intersectingTypes[i], expressionType, expression))
+				return false;
+		}
+		return true;
+	}
+	
+	switch(expressionType.kind()) {
+		case Binding.BASE_TYPE :
+			//-----------cast to something which is NOT a base type--------------------------
+			if (expressionType == TypeBinding.NULL) {
+				tagAsUnnecessaryCast(scope, castType);
+				return true; //null is compatible with every thing
+			}
+			return false;
+
+		case Binding.ARRAY_TYPE :
+			if (castType == expressionType) {
+				tagAsUnnecessaryCast(scope, castType);
+				return true; // identity conversion
+			}
+			switch (castType.kind()) {
+				case Binding.ARRAY_TYPE :
+					// ( ARRAY ) ARRAY
+					TypeBinding castElementType = ((ArrayBinding) castType).elementsType();
+					TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType();
+					if (exprElementType.isBaseType() || castElementType.isBaseType()) {
+						if (castElementType == exprElementType) {
+							tagAsNeedCheckCast();
+							return true;
+						}
+						return false;
+					}
+					// recurse on array type elements
+					return checkCastTypesCompatibility(scope, castElementType, exprElementType, expression);
+
+				case Binding.TYPE_PARAMETER :
+					// ( TYPE_PARAMETER ) ARRAY
+					TypeBinding match = expressionType.findSuperTypeOriginatingFrom(castType);
+					if (match == null) {
+						checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
+					}
+					// recurse on the type variable upper bound
+					return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+				default:
+					// ( CLASS/INTERFACE ) ARRAY
+					switch (castType.id) {
+						case T_JavaLangCloneable :
+						case T_JavaIoSerializable :
+							tagAsNeedCheckCast();
+							return true;
+						case T_JavaLangObject :
+							tagAsUnnecessaryCast(scope, castType);
+							return true;
+						default :
+							return false;
+					}
+			}
+
+		case Binding.TYPE_PARAMETER :
+			TypeBinding match = expressionType.findSuperTypeOriginatingFrom(castType);
+			if (match != null) {
+				return checkUnsafeCast(scope, castType, expressionType, match, false);
+			}
+			// recursively on the type variable upper bound
+			return checkCastTypesCompatibility(scope, castType, ((TypeVariableBinding)expressionType).upperBound(), expression);
+
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+			match = expressionType.findSuperTypeOriginatingFrom(castType);
+			if (match != null) {
+				return checkUnsafeCast(scope, castType, expressionType, match, false);
+			}
+			// recursively on the type variable upper bound
+			return checkCastTypesCompatibility(scope, castType, ((WildcardBinding)expressionType).bound, expression);
+		case Binding.INTERSECTION_CAST_TYPE:
+			ReferenceBinding [] intersectingTypes = expressionType.getIntersectingTypes();
+			for (int i = 0, length = intersectingTypes.length; i < length; i++) {
+				if (checkCastTypesCompatibility(scope, castType, intersectingTypes[i], expression))
+					return true;
+			}
+			return false;
+		default:
+			if (expressionType.isInterface()) {
+				switch (castType.kind()) {
+					case Binding.ARRAY_TYPE :
+						// ( ARRAY ) INTERFACE
+						switch (expressionType.id) {
+							case T_JavaLangCloneable :
+							case T_JavaIoSerializable :
+								tagAsNeedCheckCast();
+								return true;
+							default :
+								return false;
+						}
+
+					case Binding.TYPE_PARAMETER :
+						// ( INTERFACE ) TYPE_PARAMETER
+						match = expressionType.findSuperTypeOriginatingFrom(castType);
+						if (match == null) {
+							checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
+						}
+						// recurse on the type variable upper bound
+						return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+					default :
+						if (castType.isInterface()) {
+							// ( INTERFACE ) INTERFACE
+							ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
+							match = interfaceType.findSuperTypeOriginatingFrom(castType);
+							if (match != null) {
+								return checkUnsafeCast(scope, castType, interfaceType, match, false);
+							}
+							tagAsNeedCheckCast();
+							match = castType.findSuperTypeOriginatingFrom(interfaceType);
+							if (match != null) {
+								return checkUnsafeCast(scope, castType, interfaceType, match, true);
+							}
+							if (use15specifics) {
+								checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
+								// ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+								if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+									if (interfaceType.hasIncompatibleSuperType((ReferenceBinding) castType)) {
+										return false;
+									}
+								} else if (!castType.isRawType() && interfaceType.hasIncompatibleSuperType((ReferenceBinding) castType)) {
+									return false;
+								}
+							} else {
+								// pre1.5 semantics - no covariance allowed (even if 1.5 compliant, but 1.4 source)
+								// look at original methods rather than the parameterized variants at 1.4 to detect
+								// covariance. Otherwise when confronted with one raw type and one parameterized type,
+								// we could mistakenly detect covariance and scream foul. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=332744
+								MethodBinding[] castTypeMethods = getAllOriginalInheritedMethods((ReferenceBinding) castType);
+								MethodBinding[] expressionTypeMethods = getAllOriginalInheritedMethods((ReferenceBinding) expressionType);
+								int exprMethodsLength = expressionTypeMethods.length;
+								for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) {
+									for (int j = 0; j < exprMethodsLength; j++) {
+										if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
+												&& (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector))
+												&& castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
+											return false;
+
+										}
+									}
+								}
+							}
+							return true;
+						} else {
+							// ( CLASS ) INTERFACE
+							if (castType.id == TypeIds.T_JavaLangObject) { // no runtime error
+								tagAsUnnecessaryCast(scope, castType);
+								return true;
+							}
+							// can only be a downcast
+							tagAsNeedCheckCast();
+							match = castType.findSuperTypeOriginatingFrom(expressionType);
+							if (match != null) {
+								return checkUnsafeCast(scope, castType, expressionType, match, true);
+							}
+							if (((ReferenceBinding) castType).isFinal()) {
+								// no subclass for castType, thus compile-time check is invalid
+								return false;
+							}
+							if (use15specifics) {
+								checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
+								// ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+								if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+									if (((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType)) {
+										return false;
+									}
+								} else if (!castType.isRawType() && ((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType)) {
+									return false;
+								}
+							}
+							return true;
+						}
+				}
+			} else {
+				switch (castType.kind()) {
+					case Binding.ARRAY_TYPE :
+						// ( ARRAY ) CLASS
+						if (expressionType.id == TypeIds.T_JavaLangObject) { // potential runtime error
+							if (use15specifics) checkUnsafeCast(scope, castType, expressionType, expressionType, true);
+							tagAsNeedCheckCast();
+							return true;
+						}
+						return false;
+
+					case Binding.TYPE_PARAMETER :
+						// ( TYPE_PARAMETER ) CLASS
+						match = expressionType.findSuperTypeOriginatingFrom(castType);
+						if (match == null) {
+							checkUnsafeCast(scope, castType, expressionType, null, true);
+						}
+						// recurse on the type variable upper bound
+						return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+					default :
+						if (castType.isInterface()) {
+							// ( INTERFACE ) CLASS
+							ReferenceBinding refExprType = (ReferenceBinding) expressionType;
+							match = refExprType.findSuperTypeOriginatingFrom(castType);
+							if (match != null) {
+								return checkUnsafeCast(scope, castType, expressionType, match, false);
+							}
+							// unless final a subclass may implement the interface ==> no check at compile time
+							if (refExprType.isFinal()) {
+								return false;
+							}
+							tagAsNeedCheckCast();
+							match = castType.findSuperTypeOriginatingFrom(expressionType);
+							if (match != null) {
+								return checkUnsafeCast(scope, castType, expressionType, match, true);
+							}
+							if (use15specifics) {
+								checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
+								// ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+								if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+									if (refExprType.hasIncompatibleSuperType((ReferenceBinding) castType)) {
+										return false;
+									}
+								} else if (!castType.isRawType() && refExprType.hasIncompatibleSuperType((ReferenceBinding) castType)) {
+									return false;
+								}
+							}
+							return true;
+						} else {
+							// ( CLASS ) CLASS
+							match = expressionType.findSuperTypeOriginatingFrom(castType);
+							if (match != null) {
+								if (expression != null && castType.id == TypeIds.T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
+								return checkUnsafeCast(scope, castType, expressionType, match, false);
+							}
+							match = castType.findSuperTypeOriginatingFrom(expressionType);
+							if (match != null) {
+								tagAsNeedCheckCast();
+								return checkUnsafeCast(scope, castType, expressionType, match, true);
+							}
+							return false;
+						}
+				}
+			}
+	}
+}
+
+/**
+ * Check this expression against potential NPEs, which may occur:
+ * <ul>
+ * <li>if the expression is the receiver in a field access, qualified allocation, array reference or message send
+ * 		incl. implicit message sends like it happens for the collection in a foreach statement.</li>
+ * <li>if the expression is subject to unboxing</li>
+ * <li>if the expression is the exception in a throw statement</li>
+ * </ul>
+ * If a risk of NPE is detected report it to the context.
+ * If the expression denotes a local variable, mark it as checked, which affects the flow info.
+ * @param scope the scope of the analysis
+ * @param flowContext the current flow context
+ * @param flowInfo the upstream flow info; caveat: may get modified
+ * @return could this expression be checked by the current implementation?
+ */
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (this.resolvedType != null) {
+		if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0) {
+			return true; // no danger
+		} else if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0) {
+			scope.problemReporter().dereferencingNullableExpression(this, scope.environment());
+			return true; // danger is definite.
+			// stopping analysis at this point requires that the above error is not suppressable
+			// unless suppressing all null warnings (otherwise we'd miss a stronger warning below).
+		}
+	}
+	LocalVariableBinding local = localVariableBinding();
+	if (local != null &&
+			(local.type.tagBits & TagBits.IsBaseType) == 0) {
+		if ((this.bits & ASTNode.IsNonNull) == 0) {
+			flowContext.recordUsingNullReference(scope, local, this,
+					FlowContext.MAY_NULL, flowInfo);
+			// account for possible NPE:
+			if (!flowInfo.isDefinitelyNonNull(local)) {
+				flowContext.recordAbruptExit();
+			}
+		}
+		flowInfo.markAsComparedEqualToNonNull(local);
+			// from thereon it is set
+		flowContext.markFinallyNullStatus(local, FlowInfo.NON_NULL);
+		return true;
+	}
+	return false; // not checked
+}
+
+/** If this expression requires unboxing check if that operation can throw NPE. */
+protected void checkNPEbyUnboxing(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	int status;
+	if ((this.implicitConversion & UNBOXING) != 0
+			&& (this.bits & ASTNode.IsNonNull) == 0
+			&& (status = nullStatus(flowInfo, flowContext)) != FlowInfo.NON_NULL)
+	{
+		flowContext.recordUnboxing(scope, this, status, flowInfo);
+	}
+}
+
+public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
+	if (match == castType) {
+		if (!isNarrowing) tagAsUnnecessaryCast(scope, castType);
+		return true;
+	}
+	if (match != null && (!castType.isReifiable() || !expressionType.isReifiable())) {
+		if(isNarrowing
+				? match.isProvablyDistinct(expressionType)
+				: castType.isProvablyDistinct(match)) {
+			return false;
+		}
+	}
+	if (!isNarrowing) tagAsUnnecessaryCast(scope, castType);
+	return true;
+}
+
+/**
+ * Base types need that the widening is explicitly done by the compiler using some bytecode like i2f.
+ * Also check unsafe type operations.
+ */
+public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) {
+	if (runtimeType == null || compileTimeType == null)
+		return;
+	if (this.implicitConversion != 0) return; // already set independently
+
+	// it is possible for a Byte to be unboxed to a byte & then converted to an int
+	// but it is not possible for a byte to become Byte & then assigned to an Integer,
+	// or to become an int before boxed into an Integer
+	if (runtimeType != TypeBinding.NULL && runtimeType.isBaseType()) {
+		if (!compileTimeType.isBaseType()) {
+			TypeBinding unboxedType = scope.environment().computeBoxingType(compileTimeType);
+			this.implicitConversion = TypeIds.UNBOXING;
+			scope.problemReporter().autoboxing(this, compileTimeType, runtimeType);
+			compileTimeType = unboxedType;
+		}
+	} else if (compileTimeType != TypeBinding.NULL && compileTimeType.isBaseType()) {
+		TypeBinding boxedType = scope.environment().computeBoxingType(runtimeType);
+		if (boxedType == runtimeType) // Object o = 12;
+			boxedType = compileTimeType;
+		this.implicitConversion = TypeIds.BOXING | (boxedType.id << 4) + compileTimeType.id;
+		scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType));
+		return;
+	} else if (this.constant != Constant.NotAConstant && this.constant.typeID() != TypeIds.T_JavaLangString) {
+		this.implicitConversion = TypeIds.BOXING;
+		return;
+	}
+	int compileTimeTypeID, runtimeTypeID;
+	if ((compileTimeTypeID = compileTimeType.id) == TypeIds.NoId) { // e.g. ? extends String  ==> String (103227)
+		compileTimeTypeID = compileTimeType.erasure().id == TypeIds.T_JavaLangString ? TypeIds.T_JavaLangString : TypeIds.T_JavaLangObject;
+	}
+	switch (runtimeTypeID = runtimeType.id) {
+		case T_byte :
+		case T_short :
+		case T_char :
+			if (compileTimeTypeID == TypeIds.T_JavaLangObject) {
+				this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID;
+			} else {
+				this.implicitConversion |= (TypeIds.T_int << 4) + compileTimeTypeID;
+			}
+			break;
+		case T_JavaLangString :
+		case T_float :
+		case T_boolean :
+		case T_double :
+		case T_int : //implicitConversion may result in i2i which will result in NO code gen
+		case T_long :
+			this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID;
+			break;
+		default : // regular object ref
+//				if (compileTimeType.isRawType() && runtimeTimeType.isBoundParameterizedType()) {
+//				    scope.problemReporter().unsafeRawExpression(this, compileTimeType, runtimeTimeType);
+//				}
+	}
+}
+
+/**
+ * Expression statements are plain expressions, however they generate like
+ * normal expressions with no value required.
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	generateCode(currentScope, codeStream, false);
+}
+
+/**
+ * Every expression is responsible for generating its implicit conversion when necessary.
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	if (this.constant != Constant.NotAConstant) {
+		// generate a constant expression
+		int pc = codeStream.position;
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	} else {
+		// actual non-constant code generation
+		throw new ShouldNotImplement(Messages.ast_missingCode);
+	}
+}
+
+/**
+ * Default generation of a boolean value
+ * @param currentScope
+ * @param codeStream
+ * @param trueLabel
+ * @param falseLabel
+ * @param valueRequired
+ */
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+	// a label valued to nil means: by default we fall through the case...
+	// both nil means we leave the value on the stack
+
+	Constant cst = optimizedBooleanConstant();
+	generateCode(currentScope, codeStream, valueRequired && cst == Constant.NotAConstant);
+	if ((cst != Constant.NotAConstant) && (cst.typeID() == TypeIds.T_boolean)) {
+		int pc = codeStream.position;
+		if (cst.booleanValue() == true) {
+			// constant == true
+			if (valueRequired) {
+				if (falseLabel == null) {
+					// implicit falling through the FALSE case
+					if (trueLabel != null) {
+						codeStream.goto_(trueLabel);
+					}
+				}
+			}
+		} else {
+			if (valueRequired) {
+				if (falseLabel != null) {
+					// implicit falling through the TRUE case
+					if (trueLabel == null) {
+						codeStream.goto_(falseLabel);
+					}
+				}
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	// branching
+	int position = codeStream.position;
+	if (valueRequired) {
+		if (falseLabel == null) {
+			if (trueLabel != null) {
+				// Implicit falling through the FALSE case
+				codeStream.ifne(trueLabel);
+			}
+		} else {
+			if (trueLabel == null) {
+				// Implicit falling through the TRUE case
+				codeStream.ifeq(falseLabel);
+			} else {
+				// No implicit fall through TRUE/FALSE --> should never occur
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(position, this.sourceEnd);
+}
+
+/* Optimized (java) code generation for string concatenations that involve StringBuffer
+ * creation: going through this path means that there is no need for a new StringBuffer
+ * creation, further operands should rather be only appended to the current one.
+ * By default: no optimization.
+ */
+public void generateOptimizedStringConcatenation(BlockScope blockScope, CodeStream codeStream, int typeID) {
+	if (typeID == TypeIds.T_JavaLangString && this.constant != Constant.NotAConstant && this.constant.stringValue().length() == 0) {
+		return; // optimize str + ""
+	}
+	generateCode(blockScope, codeStream, true);
+	codeStream.invokeStringConcatenationAppendForType(typeID);
+}
+
+/* Optimized (java) code generation for string concatenations that involve StringBuffer
+ * creation: going through this path means that there is no need for a new StringBuffer
+ * creation, further operands should rather be only appended to the current one.
+ */
+public void generateOptimizedStringConcatenationCreation(BlockScope blockScope, CodeStream codeStream, int typeID) {
+	codeStream.newStringContatenation();
+	codeStream.dup();
+	switch (typeID) {
+		case T_JavaLangObject :
+		case T_undefined :
+			// in the case the runtime value of valueOf(Object) returns null, we have to use append(Object) instead of directly valueOf(Object)
+			// append(Object) returns append(valueOf(Object)), which means that the null case is handled by the next case.
+			codeStream.invokeStringConcatenationDefaultConstructor();
+			generateCode(blockScope, codeStream, true);
+			codeStream.invokeStringConcatenationAppendForType(TypeIds.T_JavaLangObject);
+			return;
+		case T_JavaLangString :
+		case T_null :
+			if (this.constant != Constant.NotAConstant) {
+				String stringValue = this.constant.stringValue();
+				if (stringValue.length() == 0) {  // optimize ""+<str>
+					codeStream.invokeStringConcatenationDefaultConstructor();
+					return;
+				}
+				codeStream.ldc(stringValue);
+			} else {
+				// null case is not a constant
+				generateCode(blockScope, codeStream, true);
+				codeStream.invokeStringValueOf(TypeIds.T_JavaLangObject);
+			}
+			break;
+		default :
+			generateCode(blockScope, codeStream, true);
+			codeStream.invokeStringValueOf(typeID);
+	}
+	codeStream.invokeStringConcatenationStringConstructor();
+}
+
+private MethodBinding[] getAllOriginalInheritedMethods(ReferenceBinding binding) {
+	ArrayList collector = new ArrayList();
+	getAllInheritedMethods0(binding, collector);
+	for (int i = 0, len = collector.size(); i < len; i++) {
+		collector.set(i, ((MethodBinding)collector.get(i)).original());
+	}
+	return (MethodBinding[]) collector.toArray(new MethodBinding[collector.size()]);
+}
+
+private void getAllInheritedMethods0(ReferenceBinding binding, ArrayList collector) {
+	if (!binding.isInterface()) return;
+	MethodBinding[] methodBindings = binding.methods();
+	for (int i = 0, max = methodBindings.length; i < max; i++) {
+		collector.add(methodBindings[i]);
+	}
+	ReferenceBinding[] superInterfaces = binding.superInterfaces();
+	for (int i = 0, max = superInterfaces.length; i < max; i++) {
+		getAllInheritedMethods0(superInterfaces[i], collector);
+	}
+}
+
+public static Binding getDirectBinding(Expression someExpression) {
+	if ((someExpression.bits & ASTNode.IgnoreNoEffectAssignCheck) != 0) {
+		return null;
+	}
+	if (someExpression instanceof SingleNameReference) {
+		return ((SingleNameReference)someExpression).binding;
+	} else if (someExpression instanceof FieldReference) {
+		FieldReference fieldRef = (FieldReference)someExpression;
+		if (fieldRef.receiver.isThis() && !(fieldRef.receiver instanceof QualifiedThisReference)) {
+			return fieldRef.binding;
+		}
+	} else if (someExpression instanceof Assignment) {
+		Expression lhs = ((Assignment)someExpression).lhs;
+		if ((lhs.bits & ASTNode.IsStrictlyAssigned) != 0) {
+			// i = i = ...; // eq to int i = ...;
+			return getDirectBinding (((Assignment)someExpression).lhs);
+		} else if (someExpression instanceof PrefixExpression) {
+			// i = i++; // eq to ++i;
+			return getDirectBinding (((Assignment)someExpression).lhs);
+		}
+	} else if (someExpression instanceof QualifiedNameReference) {
+		QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) someExpression;
+		if (qualifiedNameReference.indexOfFirstFieldBinding != 1
+				&& qualifiedNameReference.otherBindings == null) {
+			// case where a static field is retrieved using ClassName.fieldname
+			return qualifiedNameReference.binding;
+		}
+	} else if (someExpression.isThis()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=276741
+		return someExpression.resolvedType;
+	}
+//		} else if (someExpression instanceof PostfixExpression) { // recurse for postfix: i++ --> i
+//			// note: "b = b++" is equivalent to doing nothing, not to "b++"
+//			return getDirectBinding(((PostfixExpression) someExpression).lhs);
+	return null;
+}
+
+public boolean isCompactableOperation() {
+	return false;
+}
+
+//Return true if the conversion is done AUTOMATICALLY by the vm
+//while the javaVM is an int based-machine, thus for example pushing
+//a byte onto the stack , will automatically create an int on the stack
+//(this request some work d be done by the VM on signed numbers)
+public boolean isConstantValueOfTypeAssignableToType(TypeBinding constantType, TypeBinding targetType) {
+
+	if (this.constant == Constant.NotAConstant)
+		return false;
+	if (constantType == targetType)
+		return true;
+	//No free assignment conversion from anything but to integral ones.
+	if (BaseTypeBinding.isWidening(TypeIds.T_int, constantType.id)
+			&& (BaseTypeBinding.isNarrowing(targetType.id, TypeIds.T_int))) {
+		//use current explicit conversion in order to get some new value to compare with current one
+		return isConstantValueRepresentable(this.constant, constantType.id, targetType.id);
+	}
+	return false;
+}
+
+public boolean isAssignmentCompatible (TypeBinding left, Scope scope) {
+	if (this.resolvedType == null)
+		return false;
+	return isConstantValueOfTypeAssignableToType(this.resolvedType, left) || 
+				this.resolvedType.isCompatibleWith(left) || 
+				isBoxingCompatible(this.resolvedType, left, this, scope);
+}
+
+public boolean isTypeReference() {
+	return false;
+}
+
+/**
+ * Returns the local variable referenced by this node. Can be a direct reference (SingleNameReference)
+ * or thru a cast expression etc...
+ */
+public LocalVariableBinding localVariableBinding() {
+	return null;
+}
+
+/**
+ * Mark this expression as being non null, per a specific tag in the
+ * source code.
+ */
+// this is no more called for now, waiting for inter procedural null reference analysis
+public void markAsNonNull() {
+	this.bits |= ASTNode.IsNonNull;
+}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	// many kinds of expression need no analysis / are always non-null, make it the default:
+	return FlowInfo.NON_NULL;
+}
+
+/**
+ * Constant usable for bytecode pattern optimizations, but cannot be inlined
+ * since it is not strictly equivalent to the definition of constant expressions.
+ * In particular, some side-effects may be required to occur (only the end value
+ * is known).
+ * @return Constant known to be of boolean type
+ */
+public Constant optimizedBooleanConstant() {
+	return this.constant;
+}
+
+/**
+ * Returns the type of the expression after required implicit conversions. When expression type gets promoted
+ * or inserted a generic cast, the converted type will differ from the resolved type (surface side-effects from
+ * #computeConversion(...)).
+ * @return the type after implicit conversion
+ */
+public TypeBinding postConversionType(Scope scope) {
+	TypeBinding convertedType = this.resolvedType;
+	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	switch (runtimeType) {
+		case T_boolean :
+			convertedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			convertedType = TypeBinding.BYTE;
+			break;
+		case T_short :
+			convertedType = TypeBinding.SHORT;
+			break;
+		case T_char :
+			convertedType = TypeBinding.CHAR;
+			break;
+		case T_int :
+			convertedType = TypeBinding.INT;
+			break;
+		case T_float :
+			convertedType = TypeBinding.FLOAT;
+			break;
+		case T_long :
+			convertedType = TypeBinding.LONG;
+			break;
+		case T_double :
+			convertedType = TypeBinding.DOUBLE;
+			break;
+		default :
+	}
+	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
+		convertedType = scope.environment().computeBoxingType(convertedType);
+	}
+	return convertedType;
+}
+
+public StringBuffer print(int indent, StringBuffer output) {
+	printIndent(indent, output);
+	return printExpression(indent, output);
+}
+
+public abstract StringBuffer printExpression(int indent, StringBuffer output);
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	return print(indent, output).append(";"); //$NON-NLS-1$
+}
+
+public void resolve(BlockScope scope) {
+	// drops the returning expression's type whatever the type is.
+	this.resolveType(scope);
+	return;
+}
+
+/**
+ * Resolve the type of this expression in the context of a blockScope
+ *
+ * @param scope
+ * @return
+ * 	Return the actual type of this expression after resolution
+ */
+public TypeBinding resolveType(BlockScope scope) {
+	// by default... subclasses should implement a better TB if required.
+	return null;
+}
+
+/**
+ * Resolve the type of this expression in the context of a classScope
+ *
+ * @param scope
+ * @return
+ * 	Return the actual type of this expression after resolution
+ */
+public TypeBinding resolveType(ClassScope scope) {
+	// by default... subclasses should implement a better TB if required.
+	return null;
+}
+
+public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedType) {
+	setExpectedType(expectedType); // needed in case of generic method invocation
+	TypeBinding expressionType = this.resolveType(scope);
+	if (expressionType == null) return null;
+	if (expressionType == expectedType) return expressionType;
+
+	if (!expressionType.isCompatibleWith(expectedType)) {
+		if (scope.isBoxingCompatibleWith(expressionType, expectedType)) {
+			computeConversion(scope, expectedType, expressionType);
+		} else {
+			scope.problemReporter().typeMismatchError(expressionType, expectedType, this, null);
+			return null;
+		}
+	}
+	return expressionType;
+}
+/**
+ * Returns true if the receiver is forced to be of raw type either to satisfy the contract imposed
+ * by a super type or because it *is* raw and the current type has no control over it (i.e the rawness
+ * originates from some other file.)
+ */
+public boolean forcedToBeRaw(ReferenceContext referenceContext) {
+	if (this instanceof NameReference) {
+		final Binding receiverBinding = ((NameReference) this).binding;
+		if (receiverBinding.isParameter() && (((LocalVariableBinding) receiverBinding).tagBits & TagBits.ForcedToBeRawType) != 0) {
+			return true;  // parameter is forced to be raw since super method uses raw types.
+		} else if (receiverBinding instanceof FieldBinding) {
+			FieldBinding field = (FieldBinding) receiverBinding;
+			if (field.type.isRawType()) {
+				if (referenceContext instanceof AbstractMethodDeclaration) {
+					AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) referenceContext;
+					if (field.declaringClass != methodDecl.binding.declaringClass) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+						return true;
+					}
+				} else if (referenceContext instanceof TypeDeclaration) {
+					TypeDeclaration type = (TypeDeclaration) referenceContext;
+					if (field.declaringClass != type.binding) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+						return true;
+					}
+				}
+			}
+		}
+	} else if (this instanceof MessageSend) {
+		if (!CharOperation.equals(((MessageSend) this).binding.declaringClass.getFileName(),
+				referenceContext.compilationResult().getFileName())) {  // problem is rooted elsewhere
+			return true;
+		}
+	} else if (this instanceof FieldReference) {
+		FieldBinding field = ((FieldReference) this).binding;
+		if (!CharOperation.equals(field.declaringClass.getFileName(),
+				referenceContext.compilationResult().getFileName())) { // problem is rooted elsewhere
+			return true;
+		}
+		if (field.type.isRawType()) {
+			if (referenceContext instanceof AbstractMethodDeclaration) {
+				AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration) referenceContext;
+				if (field.declaringClass != methodDecl.binding.declaringClass) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+					return true;
+				}
+			} else if (referenceContext instanceof TypeDeclaration) {
+				TypeDeclaration type = (TypeDeclaration) referenceContext;
+				if (field.declaringClass != type.binding) { // inherited raw field, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962
+					return true;
+				}
+			}
+		}
+	} else if (this instanceof ConditionalExpression) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337751
+		ConditionalExpression ternary = (ConditionalExpression) this;
+		if (ternary.valueIfTrue.forcedToBeRaw(referenceContext) || ternary.valueIfFalse.forcedToBeRaw(referenceContext)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns an object which can be used to identify identical JSR sequence targets
+ * (see TryStatement subroutine codegen)
+ * or <code>null</null> if not reusable
+ */
+public Object reusableJSRTarget() {
+	if (this.constant != Constant.NotAConstant && (this.implicitConversion & TypeIds.BOXING) == 0) {
+		return this.constant;
+	}
+	return null;
+}
+
+/**
+ * Record the type expectation before this expression is typechecked.
+ * e.g. String s = foo();, foo() will be tagged as being expected of type String
+ * Used to trigger proper inference of generic method invocations.
+ *
+ * @param expectedType
+ * 	The type denoting an expectation in the context of an assignment conversion
+ */
+public void setExpectedType(TypeBinding expectedType) {
+    // do nothing by default
+}
+
+public void setExpressionContext(ExpressionContext context) {
+	// don't care. Subclasses that are poly expressions in specific contexts should listen in and make note.
+}
+
+public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+	throw new UnsupportedOperationException("Unexpected control flow, should not have reached Expression.isCompatibleWith"); //$NON-NLS-1$
+}
+
+public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+	TypeBinding expressionType = this.resolvedType;
+	if (expressionType == null || !expressionType.isValidBinding()) // Shouldn't get here, just to play it safe
+		return false; // trigger ambiguity.
+	
+	if (t.findSuperTypeOriginatingFrom(s) == s)
+		return true;
+	
+	final boolean tIsBaseType = t.isBaseType();
+	final boolean sIsBaseType = s.isBaseType();
+	
+	return expressionType.isBaseType() ? tIsBaseType && !sIsBaseType : !tIsBaseType && sIsBaseType;
+}
+
+public void tagAsEllipsisArgument() {
+	// don't care. Subclasses that are poly expressions in specific contexts should listen in and make note.
+}
+
+/* Answer if the receiver is a poly expression in the prevailing context. Caveat emptor: Some constructs (notably method calls)
+   cannot answer this question until after resolution is over and may throw unsupported operation exception if queried ahead of 
+   resolution. Default implementation here returns false which is true for vast majority of AST nodes. The ones that are poly
+   expressions under one or more contexts should override and return suitable value.  
+ */
+public boolean isPolyExpression() throws UnsupportedOperationException {
+	return false;
+}
+
+public void tagAsNeedCheckCast() {
+    // do nothing by default
+}
+
+/**
+ * Record the fact a cast expression got detected as being unnecessary.
+ *
+ * @param scope
+ * @param castType
+ */
+public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
+    // do nothing by default
+}
+
+public Expression toTypeReference() {
+	//by default undefined
+
+	//this method is meanly used by the parser in order to transform
+	//an expression that is used as a type reference in a cast ....
+	//--appreciate the fact that castExpression and ExpressionWithParenthesis
+	//--starts with the same pattern.....
+
+	return this;
+}
+
+/**
+ * Traverse an expression in the context of a blockScope
+ * @param visitor
+ * @param scope
+ */
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	// nothing to do
+}
+
+/**
+ * Traverse an expression in the context of a classScope
+ * @param visitor
+ * @param scope
+ */
+public void traverse(ASTVisitor visitor, ClassScope scope) {
+	// nothing to do
+}
+// return true if this expression can be a stand alone statement when terminated with a semicolon
+public boolean statementExpression() {
+	return false;
+}
+
+/**
+ * Used on the lhs of an assignment for detecting null spec violation.
+ * If this expression represents a null-annotated variable return the variable binding,
+ * otherwise null.
+ * @param supportTypeAnnotations if true this causes any variable binding to be used
+ *   independent of declaration annotations (for in-depth analysis of type annotations)
+*/
+public VariableBinding nullAnnotatedVariableBinding(boolean supportTypeAnnotations) {
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExpressionContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExpressionContext.java
new file mode 100644
index 0000000..6fe1a8a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExpressionContext.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+public interface ExpressionContext {
+	
+	/* Assignment context: potential poly-expressions are: method invocations, lambdas, reference expressions, 
+	   conditional expressions and allocation expressions. This is the only Java 7 context where target type
+	   influenced evaluation of some expression.
+	   
+	   Context induced by: ReturnStatement, ArrayInitializer, Assignment, FieldDeclaration and LocalDeclaration. 
+	*/
+	public static final ExpressionContext ASSIGNMENT_CONTEXT = 
+								new ExpressionContext() {
+									public String toString() {
+										return "assignment context"; //$NON-NLS-1$
+									}
+								};
+	
+	/* Invocation context: potential poly-expressions are: method invocations, lambdas, reference expressions, 
+	   conditional expressions and allocation expressions. At this point, we don't distinguish between strict 
+	   and loose invocation contexts - we may have to cross the bridge some day.
+	   
+	   Context induced by: AllocationExpression, QualifiedAllocationExpression, ExplicitConstructorCall, MessageSend
+	   CodeSnippetAllocationExpression and CodeSnippetMessageSend.
+	*/													
+	public static final ExpressionContext INVOCATION_CONTEXT = 
+								new ExpressionContext() {
+									public String toString() {
+										return "invocation context"; //$NON-NLS-1$
+									}
+								};
+	
+	/* Casting context: potential poly-expressions are: lambdas and reference expressions
+	   Context induced by: CastExpression.
+	*/
+	public static final ExpressionContext CASTING_CONTEXT = 
+								new ExpressionContext() {
+									public String toString() {
+										return "casting context"; //$NON-NLS-1$
+									}
+								};
+	
+	/* Vanilla context (string, numeric): potential poly-expressions are: NONE. This is the nonpoly context in which 
+	   expressions get evaluated, unless they feature in one of the above contexts. 
+	*/
+	public static final ExpressionContext VANILLA_CONTEXT = 
+								new ExpressionContext() {
+									public String toString() {
+										return "vanilla context"; //$NON-NLS-1$
+									}
+								};
+		
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
new file mode 100644
index 0000000..05cfb0a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+public class ExtendedStringLiteral extends StringLiteral {
+
+	/**
+	 *  Build a string+char literal
+	 */
+	public ExtendedStringLiteral(StringLiteral str, CharLiteral character) {
+
+		super(str.source, str.sourceStart, str.sourceEnd, str.lineNumber);
+		extendWith(character);
+	}
+
+	/**
+	 * Build a two-strings literal
+	 * */
+	public ExtendedStringLiteral(StringLiteral str1, StringLiteral str2) {
+
+		super(str1.source, str1.sourceStart, str1.sourceEnd, str1.lineNumber);
+		extendWith(str2);
+	}
+
+	/**
+	 * Add the lit source to mine, just as if it was mine
+	 */
+	public ExtendedStringLiteral extendWith(CharLiteral lit) {
+
+		//update the source
+		int length = this.source.length;
+		System.arraycopy(this.source, 0, (this.source = new char[length + 1]), 0, length);
+		this.source[length] = lit.value;
+		//position at the end of all literals
+		this.sourceEnd = lit.sourceEnd;
+		return this;
+	}
+
+	/**
+	 *  Add the lit source to mine, just as if it was mine
+	 */
+	public ExtendedStringLiteral extendWith(StringLiteral lit) {
+
+		//uddate the source
+		int length = this.source.length;
+		System.arraycopy(
+			this.source,
+			0,
+			this.source = new char[length + lit.source.length],
+			0,
+			length);
+		System.arraycopy(lit.source, 0, this.source, length, lit.source.length);
+		//position at the end of all literals
+		this.sourceEnd = lit.sourceEnd;
+		return this;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		return output.append("ExtendedStringLiteral{").append(this.source).append('}'); //$NON-NLS-1$
+	}
+
+	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/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
new file mode 100644
index 0000000..655375b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -0,0 +1,856 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FinallyFlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * A faked local variable declaration used for keeping track of data flows of a
+ * special variable. Certain events will be recorded by changing the null info
+ * for this variable.
+ * 
+ * See bug 349326 - [1.7] new warning for missing try-with-resources
+ */
+public class FakedTrackingVariable extends LocalDeclaration {
+
+	private static final char[] UNASSIGNED_CLOSEABLE_NAME = "<unassigned Closeable value>".toCharArray(); //$NON-NLS-1$
+	private static final char[] UNASSIGNED_CLOSEABLE_NAME_TEMPLATE = "<unassigned Closeable value from line {0}>".toCharArray(); //$NON-NLS-1$
+	private static final char[] TEMPLATE_ARGUMENT = "{0}".toCharArray(); //$NON-NLS-1$
+
+	// a call to close() was seen at least on one path:
+	private static final int CLOSE_SEEN = 1;
+	// the resource is shared with outside code either by
+	// - passing as an arg in a method call or
+	// - obtaining this from a method call or array reference
+	// Interpret that we may or may not be responsible for closing
+	private static final int SHARED_WITH_OUTSIDE = 2;
+	// the resource is likely owned by outside code (owner has responsibility to close): 
+	// - obtained as argument of the current method, or via a field read
+	// - stored into a field
+	// - returned as the result of this method 
+	private static final int OWNED_BY_OUTSIDE = 4;
+	// If close() is invoked from a nested method (inside a local type) report remaining problems only as potential:
+	private static final int CLOSED_IN_NESTED_METHOD = 8;
+	// explicit closing has been reported already against this resource:
+	private static final int REPORTED_EXPLICIT_CLOSE = 16;
+	// a location independent potential problem has been reported against this resource:
+	private static final int REPORTED_POTENTIAL_LEAK = 32;
+	// a location independent definitive problem has been reported against this resource:
+	private static final int REPORTED_DEFINITIVE_LEAK = 64;
+	
+	public static boolean TEST_372319 = false; // see https://bugs.eclipse.org/372319
+
+	/**
+	 * Bitset of {@link #CLOSE_SEEN}, {@link #SHARED_WITH_OUTSIDE}, {@link #OWNED_BY_OUTSIDE}, {@link #CLOSED_IN_NESTED_METHOD}, {@link #REPORTED_EXPLICIT_CLOSE}, {@link #REPORTED_POTENTIAL_LEAK} and {@link #REPORTED_DEFINITIVE_LEAK}.
+	 */
+	private int globalClosingState = 0;
+
+	public LocalVariableBinding originalBinding; // the real local being tracked, can be null for preliminary track vars for allocation expressions
+	
+	public FakedTrackingVariable innerTracker; // chained tracking variable of a chained (wrapped) resource
+	public FakedTrackingVariable outerTracker; // inverse of 'innerTracker'
+
+	MethodScope methodScope; // designates the method declaring this variable
+
+	private HashMap recordedLocations; // initially null, ASTNode -> Integer
+
+	// temporary storage while analyzing "res = new Res();":
+	private ASTNode currentAssignment; // temporarily store the assignment as the location for error reporting
+	
+	// if tracking var was allocated from a finally context, record here the flow context of the corresponding try block
+	private FlowContext tryContext;
+
+	public FakedTrackingVariable(LocalVariableBinding original, ASTNode location, FlowInfo flowInfo, FlowContext flowContext, int nullStatus) {
+		super(original.name, location.sourceStart, location.sourceEnd);
+		this.type = new SingleTypeReference(
+				TypeConstants.OBJECT,
+				((long)this.sourceStart <<32)+this.sourceEnd);
+		this.methodScope = original.declaringScope.methodScope();
+		this.originalBinding = original;
+		// inside a finally block?
+		while (flowContext != null) {
+			if (flowContext instanceof FinallyFlowContext) {
+				// yes -> connect to the corresponding try block:
+				this.tryContext = ((FinallyFlowContext) flowContext).tryContext;
+				break;
+			}
+			flowContext = flowContext.parent;
+		}
+		resolve(original.declaringScope);
+		if (nullStatus != 0)
+			flowInfo.markNullStatus(this.binding, nullStatus); // mark that this flow has seen the resource
+	}
+
+	/* Create an unassigned tracking variable while analyzing an allocation expression: */
+	private FakedTrackingVariable(BlockScope scope, ASTNode location, FlowInfo flowInfo, int nullStatus) {
+		super(UNASSIGNED_CLOSEABLE_NAME, location.sourceStart, location.sourceEnd);
+		this.type = new SingleTypeReference(
+				TypeConstants.OBJECT,
+				((long)this.sourceStart <<32)+this.sourceEnd);
+		this.methodScope = scope.methodScope();
+		this.originalBinding = null;
+		resolve(scope);
+		if (nullStatus != 0)
+			flowInfo.markNullStatus(this.binding, nullStatus); // mark that this flow has seen the resource
+	}
+	
+	public void generateCode(BlockScope currentScope, CodeStream codeStream)
+	{ /* NOP - this variable is completely dummy, ie. for analysis only. */ }
+
+	public void resolve (BlockScope scope) {
+		// only need the binding, which is used as reference in FlowInfo methods.
+		this.binding = new LocalVariableBinding(
+				this.name,
+				scope.getJavaLangObject(),  // dummy, just needs to be a reference type
+				0,
+				false);
+		this.binding.closeTracker = this;
+		this.binding.declaringScope = scope;
+		this.binding.setConstant(Constant.NotAConstant);
+		this.binding.useFlag = LocalVariableBinding.USED;
+		// use a free slot without assigning it:
+		this.binding.id = scope.registerTrackingVariable(this);
+	}
+
+	/**
+	 * If expression resolves to a value of type AutoCloseable answer the variable that tracks closing of that local.
+	 * Covers two cases:
+	 * <ul>
+	 * <li>value is a local variable reference, create tracking variable it if needed.
+	 * <li>value is an allocation expression, return a preliminary tracking variable if set.
+	 * </ul>
+	 * @param expression
+	 * @return a new {@link FakedTrackingVariable} or null.
+	 */
+	public static FakedTrackingVariable getCloseTrackingVariable(Expression expression, FlowInfo flowInfo, FlowContext flowContext) {
+		while (true) {
+			if (expression instanceof CastExpression)
+				expression = ((CastExpression) expression).expression;
+			else if (expression instanceof Assignment)
+				expression = ((Assignment) expression).expression;
+			else
+				break;
+		}
+		if (expression instanceof SingleNameReference) {
+			SingleNameReference name = (SingleNameReference) expression;
+			if (name.binding instanceof LocalVariableBinding) {
+				LocalVariableBinding local = (LocalVariableBinding)name.binding;
+				if (local.closeTracker != null)
+					return local.closeTracker;
+				if (!isAnyCloseable(expression.resolvedType))
+					return null;
+				// tracking var doesn't yet exist. This happens in finally block
+				// which is analyzed before the corresponding try block
+				Statement location = local.declaration;
+				local.closeTracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.UNKNOWN);
+				if (local.isParameter()) {
+					local.closeTracker.globalClosingState |= OWNED_BY_OUTSIDE;
+					// status of this tracker is now UNKNOWN
+				}
+				return local.closeTracker;
+			}
+		} else if (expression instanceof AllocationExpression) {
+			// return any preliminary tracking variable from analyseCloseableAllocation 
+			return ((AllocationExpression) expression).closeTracker;
+		}		
+		return null;
+	}
+
+	/**
+	 * Before analyzing an assignment of this shape: <code>singleName = new Allocation()</code>
+	 * connect any tracking variable of the LHS with the allocation on the RHS.
+	 * Also the assignment is temporarily stored in the tracking variable in case we need to
+	 * report errors because the assignment leaves the old LHS value unclosed.
+	 * In this case the assignment should be used as the error location.
+	 * 
+	 * @param location the assignment/local declaration being analyzed
+	 * @param local the local variable being assigned to
+	 * @param rhs the rhs of the assignment resp. the initialization of the local variable declaration.
+	 * 		<strong>Precondition:</strong> client has already checked that the resolved type of this expression is either a closeable type or NULL.
+	 */
+	public static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, Expression rhs, FlowInfo flowInfo) {
+		FakedTrackingVariable closeTracker = null;
+		if (rhs instanceof AllocationExpression) {
+			closeTracker = local.closeTracker;
+			if (closeTracker == null) {
+				if (rhs.resolvedType != TypeBinding.NULL) { // not NULL means valid closeable as per method precondition
+					closeTracker = new FakedTrackingVariable(local, location, flowInfo, null, FlowInfo.UNKNOWN);
+					if (local.isParameter()) {
+						closeTracker.globalClosingState |= OWNED_BY_OUTSIDE;
+					}
+				}					
+			}
+			if (closeTracker != null) {
+				closeTracker.currentAssignment = location;
+				AllocationExpression allocation = (AllocationExpression)rhs;
+				allocation.closeTracker = closeTracker;
+				if (allocation.arguments != null && allocation.arguments.length > 0) {
+					// also push into nested allocations, see https://bugs.eclipse.org/368709
+					preConnectTrackerAcrossAssignment(location, local, allocation.arguments[0], flowInfo);
+				}
+			}
+		}
+	}
+
+	/** 
+	 * Compute/assign a tracking variable for a freshly allocated closeable value, using information from our white lists.
+	 * See  Bug 358903 - Filter practically unimportant resource leak warnings 
+	 */
+	public static void analyseCloseableAllocation(BlockScope scope, FlowInfo flowInfo, AllocationExpression allocation) {
+		// client has checked that the resolvedType is an AutoCloseable, hence the following cast is safe:
+		if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable)) {
+			// remove unnecessary attempts (closeable is not relevant)
+			if (allocation.closeTracker != null) {
+				scope.removeTrackingVar(allocation.closeTracker);
+				allocation.closeTracker = null;
+			}
+		} else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) {
+			boolean isWrapper = true;
+			if (allocation.arguments != null &&  allocation.arguments.length > 0) {
+				// find the wrapped resource represented by its tracking var:
+				FakedTrackingVariable innerTracker = findCloseTracker(scope, flowInfo, allocation.arguments[0]);
+				if (innerTracker != null) {
+					FakedTrackingVariable currentInner = innerTracker;
+					do {
+						if (currentInner == allocation.closeTracker)
+							return; // self wrap (res = new Res(res)) -> neither change (here) nor remove (below)
+						// also check for indirect cycles, see https://bugs.eclipse.org/368709
+						currentInner = currentInner.innerTracker;
+					} while (currentInner != null);
+					int newStatus = FlowInfo.NULL;
+					if (allocation.closeTracker == null) {
+						allocation.closeTracker = new FakedTrackingVariable(scope, allocation, flowInfo, FlowInfo.UNKNOWN); // no local available, closeable is unassigned
+					} else {
+						if (scope.finallyInfo != null) {
+							// inject results from analysing a finally block onto the newly connected wrapper
+							int finallyStatus = scope.finallyInfo.nullStatus(allocation.closeTracker.binding);
+							if (finallyStatus != FlowInfo.UNKNOWN)
+								newStatus = finallyStatus;
+						}
+					}
+					allocation.closeTracker.innerTracker = innerTracker;
+					innerTracker.outerTracker = allocation.closeTracker;
+					flowInfo.markNullStatus(allocation.closeTracker.binding, newStatus);
+					if (newStatus != FlowInfo.NULL) {
+						// propagate results from a finally block also into nested resources:
+						FakedTrackingVariable currentTracker = innerTracker;
+						while (currentTracker != null) {
+							flowInfo.markNullStatus(currentTracker.binding, newStatus);
+							currentTracker.globalClosingState |= allocation.closeTracker.globalClosingState;
+							currentTracker = currentTracker.innerTracker;
+						}
+					}
+					return; // keep chaining wrapper (by avoiding to fall through to removeTrackingVar below)
+				} else {
+					if (!isAnyCloseable(allocation.arguments[0].resolvedType)) {
+						isWrapper = false; // argument is not closeable
+					}
+				}
+			} else {
+				isWrapper = false; // no argument
+			}
+			// successful wrapper detection has exited above, let's see why that failed
+			if (isWrapper) {
+				// remove unnecessary attempts (wrapper has no relevant inner)
+				if (allocation.closeTracker != null) {
+					scope.removeTrackingVar(allocation.closeTracker);
+					allocation.closeTracker = null;
+				}
+			} else {
+				// allocation does not provide a resource as the first argument -> don't treat as a wrapper
+				handleRegularResource(scope, flowInfo, allocation);
+			}
+		} else { // regular resource
+			handleRegularResource(scope, flowInfo, allocation);
+		}
+	}
+
+	private static void handleRegularResource(BlockScope scope, FlowInfo flowInfo, AllocationExpression allocation) {
+		FakedTrackingVariable presetTracker = allocation.closeTracker;
+		if (presetTracker != null && presetTracker.originalBinding != null) {
+			// the current assignment forgets a previous resource in the LHS, may cause a leak
+			// report now because handleResourceAssignment can't distinguish this from a self-wrap situation
+			int closeStatus = flowInfo.nullStatus(presetTracker.binding);
+			if (closeStatus != FlowInfo.NON_NULL		// old resource was not closed
+					&& closeStatus != FlowInfo.UNKNOWN	// old resource had some flow information
+					&& !flowInfo.isDefinitelyNull(presetTracker.originalBinding)		// old resource was not null
+					&& !(presetTracker.currentAssignment instanceof LocalDeclaration))	// forgetting old val in local decl is syntactically impossible
+				allocation.closeTracker.recordErrorLocation(presetTracker.currentAssignment, closeStatus);
+		} else {
+			allocation.closeTracker = new FakedTrackingVariable(scope, allocation, flowInfo, FlowInfo.UNKNOWN); // no local available, closeable is unassigned
+		}
+		flowInfo.markAsDefinitelyNull(allocation.closeTracker.binding);
+	}
+
+	/** Find an existing tracking variable for the argument of an allocation for a resource wrapper. */
+	private static FakedTrackingVariable findCloseTracker(BlockScope scope, FlowInfo flowInfo, Expression arg)
+	{
+		while (arg instanceof Assignment) {
+			Assignment assign = (Assignment)arg;
+			LocalVariableBinding innerLocal = assign.localVariableBinding();
+			if (innerLocal != null) {
+				// nested assignment has already been processed
+				return innerLocal.closeTracker;
+			} else {
+				arg = assign.expression; // unwrap assignment and fall through
+			}
+		}
+		if (arg instanceof SingleNameReference) {
+			// is allocation arg a reference to an existing closeable?
+			LocalVariableBinding local = arg.localVariableBinding();
+			if (local != null) {
+				return local.closeTracker;
+			}
+		} else if (arg instanceof AllocationExpression) {
+			// nested allocation
+			return ((AllocationExpression)arg).closeTracker;
+		}
+		return null; // not a tracked expression
+	}
+
+	/** 
+	 * Check if the rhs of an assignment or local declaration is an (Auto)Closeable.
+	 * If so create or re-use a tracking variable, and wire and initialize everything.
+	 * @param scope scope containing the assignment
+	 * @param upstreamInfo info without analysis of the rhs, use this to determine the status of a resource being disconnected
+	 * @param flowInfo info with analysis of the rhs, use this for recording resource status because this will be passed downstream
+	 * @param flowContext 
+	 * @param location where to report warnigs/errors against
+	 * @param rhs the right hand side of the assignment, this expression is to be analyzed.
+	 *			The caller has already checked that the rhs is either of a closeable type or null.
+	 * @param local the local variable into which the rhs is being assigned
+	 */
+	public static void handleResourceAssignment(BlockScope scope, FlowInfo upstreamInfo, FlowInfo flowInfo, FlowContext flowContext, ASTNode location, Expression rhs, LocalVariableBinding local)
+	{
+		// does the LHS (local) already have a tracker, indicating we may leak a resource by the assignment?
+		FakedTrackingVariable previousTracker = null;
+		FakedTrackingVariable disconnectedTracker = null;
+		if (local.closeTracker != null) {
+			// assigning to a variable already holding an AutoCloseable, has it been closed before?
+			previousTracker = local.closeTracker;
+			int nullStatus = upstreamInfo.nullStatus(local);
+			if (nullStatus != FlowInfo.NULL && nullStatus != FlowInfo.UNKNOWN) // only if previous value may be relevant
+				disconnectedTracker = previousTracker; // report error below, unless we have a self-wrap assignment
+		}
+
+		rhsAnalyis:
+		if (rhs.resolvedType != TypeBinding.NULL) {
+			// new value is AutoCloseable, start tracking, possibly re-using existing tracker var:
+			FakedTrackingVariable rhsTrackVar = getCloseTrackingVariable(rhs, flowInfo, flowContext);
+			if (rhsTrackVar != null) {								// 1. if RHS has a tracking variable...
+				if (local.closeTracker == null) {
+					// null shouldn't occur but let's play safe:
+					if (rhsTrackVar.originalBinding != null)
+						local.closeTracker = rhsTrackVar;			//		a.: let fresh LHS share it
+					if (rhsTrackVar.currentAssignment == location) {
+						// pre-set tracker from lhs - passed from outside?
+						// now it's a fresh resource
+						rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE);
+					}
+				} else {
+					if (rhs instanceof AllocationExpression) {
+						if (rhsTrackVar == disconnectedTracker)
+							return;									// 		b.: self wrapper: res = new Wrap(res); -> done!
+						if (local.closeTracker == rhsTrackVar 
+								&& ((rhsTrackVar.globalClosingState & OWNED_BY_OUTSIDE) != 0)) {
+																	// 		c.: assigning a fresh resource (pre-connected alloc) 
+																	//			to a local previously holding an alien resource -> start over
+							local.closeTracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.NULL);
+							// still check disconnectedTracker below
+							break rhsAnalyis;
+						}
+					}
+					local.closeTracker = rhsTrackVar;				//		d.: conflicting LHS and RHS, proceed with recordErrorLocation below
+				}
+				// keep close-status of RHS unchanged across this assignment
+			} else if (previousTracker != null) {					// 2. re-use tracking variable from the LHS?
+				FlowContext currentFlowContext = flowContext;
+				checkReuseTracker : {
+					if (previousTracker.tryContext != null) {
+						while (currentFlowContext != null) {
+							if (previousTracker.tryContext == currentFlowContext) {
+								// "previous" location was the finally block of the current try statement.
+								// -> This is not a re-assignment.
+								// see https://bugs.eclipse.org/388996
+								break checkReuseTracker;
+							}
+							currentFlowContext = currentFlowContext.parent;
+						}
+					}
+					// re-assigning from a fresh value, mark as not-closed again:
+					if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0
+							&& flowInfo.hasNullInfoFor(previousTracker.binding)) // avoid spilling info into a branch that doesn't see the corresponding resource
+						flowInfo.markAsDefinitelyNull(previousTracker.binding);
+					local.closeTracker = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, previousTracker);
+				}
+			} else {												// 3. no re-use, create a fresh tracking variable:
+				rhsTrackVar = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, null);
+				if (rhsTrackVar != null) {
+					local.closeTracker = rhsTrackVar;
+					// a fresh resource, mark as not-closed:
+					if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0)
+						flowInfo.markAsDefinitelyNull(rhsTrackVar.binding);
+// TODO(stephan): this might be useful, but I could not find a test case for it: 
+//					if (flowContext.initsOnFinally != null)
+//						flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding);
+				}
+			}
+		}
+
+		if (disconnectedTracker != null) {
+			if (disconnectedTracker.innerTracker != null && disconnectedTracker.innerTracker.binding.declaringScope == scope) {
+				// discard tracker for the wrapper but keep the inner:
+				disconnectedTracker.innerTracker.outerTracker = null;
+				scope.pruneWrapperTrackingVar(disconnectedTracker);
+			} else {
+				int upstreamStatus = upstreamInfo.nullStatus(disconnectedTracker.binding);
+				if (upstreamStatus != FlowInfo.NON_NULL)
+					disconnectedTracker.recordErrorLocation(location, upstreamStatus);
+			}
+		}
+	}
+	/**
+	 * Analyze structure of a closeable expression, matching (chained) resources against our white lists.
+	 * @param flowInfo where to record close status
+	 * @param local local variable to which the closeable is being assigned
+	 * @param location where to flag errors/warnings against
+	 * @param expression expression to be analyzed
+	 * @param previousTracker when analyzing a re-assignment we may already have a tracking variable for local,
+	 *  		which we should then re-use
+	 * @return a tracking variable associated with local or null if no need to track
+	 */
+	private static FakedTrackingVariable analyseCloseableExpression(FlowInfo flowInfo, FlowContext flowContext, LocalVariableBinding local, 
+									ASTNode location, Expression expression, FakedTrackingVariable previousTracker) 
+	{
+		// unwrap uninteresting nodes:
+		while (true) {
+			if (expression instanceof Assignment)
+				expression = ((Assignment)expression).expression;
+			else if (expression instanceof CastExpression)
+				expression = ((CastExpression) expression).expression;
+			else
+				break;
+		}
+
+		// analyze by node type:
+		if (expression instanceof AllocationExpression) {
+			// allocation expressions already have their tracking variables analyzed by analyseCloseableAllocation(..)
+			FakedTrackingVariable tracker = ((AllocationExpression) expression).closeTracker;
+			if (tracker != null && tracker.originalBinding == null) {
+				// tracker without original binding (unassigned closeable) shouldn't reach here but let's play safe
+				return null;
+			}
+			return tracker;
+		} else if (expression instanceof MessageSend 
+				|| expression instanceof ArrayReference) 
+		{
+			// we *might* be responsible for the resource obtained
+			FakedTrackingVariable tracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.POTENTIALLY_NULL); // shed some doubt
+			tracker.globalClosingState |= SHARED_WITH_OUTSIDE;
+			return tracker;
+		} else if (
+				(expression.bits & RestrictiveFlagMASK) == Binding.FIELD
+				||((expression instanceof QualifiedNameReference)
+						&& ((QualifiedNameReference) expression).isFieldAccess()))
+		{
+			// responsibility for this resource probably lies at a higher level
+			FakedTrackingVariable tracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.UNKNOWN);
+			tracker.globalClosingState |= OWNED_BY_OUTSIDE;
+			// leave state as UNKNOWN, the bit OWNED_BY_OUTSIDE will prevent spurious warnings
+			return tracker;			
+		}
+
+		if (expression.resolvedType instanceof ReferenceBinding) {
+			ReferenceBinding resourceType = (ReferenceBinding) expression.resolvedType;
+			if (resourceType.hasTypeBit(TypeIds.BitResourceFreeCloseable)) {
+				// (a) resource-free closeable: -> null
+				return null;
+			}
+		}
+		if (local.closeTracker != null)
+			// (c): inner has already been analyzed: -> re-use track var
+			return local.closeTracker;
+		FakedTrackingVariable newTracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.UNKNOWN);
+		LocalVariableBinding rhsLocal = expression.localVariableBinding();
+		if (rhsLocal != null && rhsLocal.isParameter()) {
+			newTracker.globalClosingState |= OWNED_BY_OUTSIDE;
+		}
+		return newTracker;
+	}
+
+	public static void cleanUpAfterAssignment(BlockScope currentScope, int lhsBits, Expression expression) {
+		// remove all remaining track vars with no original binding
+
+		// unwrap uninteresting nodes:
+		while (true) {
+			if (expression instanceof Assignment)
+				expression = ((Assignment)expression).expression;
+			else if (expression instanceof CastExpression)
+				expression = ((CastExpression) expression).expression;
+			else
+				break;
+		}
+		if (expression instanceof AllocationExpression) {
+			FakedTrackingVariable tracker = ((AllocationExpression) expression).closeTracker;
+			if (tracker != null && tracker.originalBinding == null) {
+				currentScope.removeTrackingVar(tracker);
+				((AllocationExpression) expression).closeTracker = null;
+			}
+		} else {
+			// assignment passing a local into a field?
+			LocalVariableBinding local = expression.localVariableBinding();
+			if (local != null && local.closeTracker != null && ((lhsBits & Binding.FIELD) != 0))
+				currentScope.removeTrackingVar(local.closeTracker); // TODO: may want to use local.closeTracker.markPassedToOutside(..,true)
+		}
+	}
+
+	/** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */
+	public static boolean isAnyCloseable(TypeBinding typeBinding) {
+		return typeBinding instanceof ReferenceBinding
+			&& ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable);
+	}
+
+	public int findMostSpecificStatus(FlowInfo flowInfo, BlockScope currentScope, BlockScope locationScope) {
+		int status = FlowInfo.UNKNOWN;
+		FakedTrackingVariable currentTracker = this;
+		// loop as to consider wrappers (per white list) encapsulating an inner resource.
+		while (currentTracker != null) {
+			LocalVariableBinding currentVar = currentTracker.binding;
+			int currentStatus = getNullStatusAggressively(currentVar, flowInfo);
+			if (locationScope != null) // only check at method exit points
+				currentStatus = mergeCloseStatus(locationScope, currentStatus, currentVar, currentScope);
+			if (currentStatus == FlowInfo.NON_NULL) {
+				status = currentStatus;
+				break; // closed -> stop searching
+			} else if (status == FlowInfo.NULL || status == FlowInfo.UNKNOWN) {
+				status = currentStatus; // improved although not yet safe -> keep searching for better
+			}
+			currentTracker = currentTracker.innerTracker;
+		}
+		return status;
+	}
+
+	/**
+	 * Get the null status looking even into unreachable flows
+	 * @param local
+	 * @param flowInfo
+	 * @return one of the constants FlowInfo.{NULL,POTENTIALLY_NULL,POTENTIALLY_NON_NULL,NON_NULL}.
+	 */
+	private int getNullStatusAggressively(LocalVariableBinding local, FlowInfo flowInfo) {
+		if (flowInfo == FlowInfo.DEAD_END) {
+			return FlowInfo.UNKNOWN;
+		}
+		int reachMode = flowInfo.reachMode();
+		int status = 0;
+		try {
+			// unreachable flowInfo is too shy in reporting null-issues, temporarily forget reachability:
+			if (reachMode != FlowInfo.REACHABLE)
+				flowInfo.tagBits &= ~FlowInfo.UNREACHABLE;
+			status = flowInfo.nullStatus(local);
+			if (TEST_372319) { // see https://bugs.eclipse.org/372319
+				try {
+					Thread.sleep(5); // increase probability of concurrency bug
+				} catch (InterruptedException e) { /* nop */ }
+			}
+		} finally {
+			// reset
+			flowInfo.tagBits |= reachMode;
+		}
+		// at this point some combinations are not useful so flatten to a single bit:
+		if ((status & FlowInfo.NULL) != 0) {
+			if ((status & (FlowInfo.NON_NULL | FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+				return FlowInfo.POTENTIALLY_NULL; 	// null + doubt = pot null
+			return FlowInfo.NULL;
+		} else if ((status & FlowInfo.NON_NULL) != 0) {
+			if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+				return FlowInfo.POTENTIALLY_NULL;	// non-null + doubt = pot null
+			return FlowInfo.NON_NULL;
+		} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0)
+			return FlowInfo.POTENTIALLY_NULL;
+		return status;
+	}
+
+	public int mergeCloseStatus(BlockScope currentScope, int status, LocalVariableBinding local, BlockScope outerScope) {
+		// get the most suitable null status representing whether resource 'binding' has been closed
+		// start at 'currentScope' and potentially travel out until 'outerScope'
+		// at each scope consult any recorded 'finallyInfo'.
+		if (status != FlowInfo.NON_NULL) {
+			if (currentScope.finallyInfo != null) {
+				int finallyStatus = currentScope.finallyInfo.nullStatus(local);
+				if (finallyStatus == FlowInfo.NON_NULL)
+					return finallyStatus;
+				if (finallyStatus != FlowInfo.NULL) // neither is NON_NULL, but not both are NULL => call it POTENTIALLY_NULL
+					status = FlowInfo.POTENTIALLY_NULL;
+			}
+			if (currentScope != outerScope && currentScope.parent instanceof BlockScope)
+				return mergeCloseStatus(((BlockScope) currentScope.parent), status, local, outerScope);
+		}
+		return status;
+	}
+
+	/** Mark that this resource is closed locally. */
+	public void markClose(FlowInfo flowInfo, FlowContext flowContext) {
+		FakedTrackingVariable current = this;
+		do {
+			flowInfo.markAsDefinitelyNonNull(current.binding);
+			current.globalClosingState |= CLOSE_SEEN;
+			flowContext.markFinallyNullStatus(this.binding, FlowInfo.NON_NULL);
+			current = current.innerTracker;
+		} while (current != null);
+	}
+
+	/** Mark that this resource is closed from a nested method (inside a local class). */
+	public void markClosedInNestedMethod() {
+		this.globalClosingState |= CLOSED_IN_NESTED_METHOD;
+	}
+
+	/** 
+	 * Mark that this resource is passed to some outside code
+	 * (as argument to a method/ctor call or as a return value from the current method), 
+	 * and thus should be considered as potentially closed.
+	 * @param owned should the resource be considered owned by some outside?
+	 */
+	public static FlowInfo markPassedToOutside(BlockScope scope, Expression expression, FlowInfo flowInfo, FlowContext flowContext, boolean owned) {	
+		
+		FakedTrackingVariable trackVar = getCloseTrackingVariable(expression, flowInfo, flowContext);
+		if (trackVar != null) {
+			// insert info that the tracked resource *may* be closed (by the target method, i.e.)
+			FlowInfo infoResourceIsClosed = owned ? flowInfo : flowInfo.copy();
+			int flag = owned ? OWNED_BY_OUTSIDE : SHARED_WITH_OUTSIDE;
+			do {
+				trackVar.globalClosingState |= flag;
+				if (scope.methodScope() != trackVar.methodScope)
+					trackVar.globalClosingState |= CLOSED_IN_NESTED_METHOD;
+				infoResourceIsClosed.markAsDefinitelyNonNull(trackVar.binding);
+			} while ((trackVar = trackVar.innerTracker) != null);
+			if (owned) {
+				return infoResourceIsClosed; // don't let downstream signal any problems on this flow
+			} else {
+				return FlowInfo.conditional(flowInfo, infoResourceIsClosed); // only report potential problems on this flow
+			}
+		}
+		return flowInfo;
+	}
+
+	/** 
+	 * Pick tracking variables from 'varsOfScope' to establish a proper order of processing:
+	 * As much as possible pick wrapper resources before their inner resources.
+	 * Also consider cases of wrappers and their inners being declared at different scopes.
+	 */
+	public static FakedTrackingVariable pickVarForReporting(Set varsOfScope, BlockScope scope, boolean atExit) {
+		if (varsOfScope.isEmpty()) return null;
+		FakedTrackingVariable trackingVar = (FakedTrackingVariable) varsOfScope.iterator().next();
+		while (trackingVar.outerTracker != null) {
+			// resource is wrapped, is wrapper defined in this scope?
+			if (varsOfScope.contains(trackingVar.outerTracker)) {
+				// resource from same scope, travel up the wrapper chain
+				trackingVar = trackingVar.outerTracker;
+			} else if (atExit) {
+				// at an exit point we report against inner despite a wrapper that may/may not be closed later
+				break;
+			} else {
+				BlockScope outerTrackerScope = trackingVar.outerTracker.binding.declaringScope;
+				if (outerTrackerScope == scope) {
+					// outerTracker is from same scope and already processed -> pick trackingVar now
+					break;
+				} else {
+					// outer resource is from other (outer?) scope
+					Scope currentScope = scope;
+					while ((currentScope = currentScope.parent) instanceof BlockScope) {
+						if (outerTrackerScope == currentScope) {
+							// at end of block pass responsibility for inner resource to outer scope holding a wrapper
+							varsOfScope.remove(trackingVar); // drop this one
+							// pick a next candidate:
+							return pickVarForReporting(varsOfScope, scope, atExit);
+						}
+					}
+					break; // not parent owned -> pick this var
+				}
+			}
+		}
+		varsOfScope.remove(trackingVar);
+		return trackingVar;
+	}
+
+	/**
+	 * Answer true if we know for sure that no resource is bound to this variable
+	 * at the point of 'flowInfo'. 
+	 */
+	public boolean hasDefinitelyNoResource(FlowInfo flowInfo) {
+		if (this.originalBinding == null) return false; // shouldn't happen but keep quiet.
+		if (flowInfo.isDefinitelyNull(this.originalBinding)) {
+			return true;
+		}
+		if (!(flowInfo.isDefinitelyAssigned(this.originalBinding) 
+				|| flowInfo.isPotentiallyAssigned(this.originalBinding))) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean isClosedInFinallyOfEnclosing(BlockScope scope) {
+		BlockScope currentScope = scope;
+		while (true) {			
+			if (currentScope.finallyInfo != null
+					&& currentScope.finallyInfo.isDefinitelyNonNull(this.binding)) {
+				return true; // closed in enclosing finally
+			}
+			if (!(currentScope.parent instanceof BlockScope)) {
+				return false;
+			}
+			currentScope = (BlockScope) currentScope.parent;
+		} 
+	}
+	/** 
+	 * If current is the same as 'returnedResource' or a wrapper thereof,
+	 * mark as reported and return true, otherwise false.
+	 */
+	public boolean isResourceBeingReturned(FakedTrackingVariable returnedResource) {
+		FakedTrackingVariable current = this;
+		do {
+			if (current == returnedResource) {
+				this.globalClosingState |= REPORTED_DEFINITIVE_LEAK;
+				return true;
+			}
+			current = current.innerTracker;
+		} while (current != null);
+		return false;
+	}
+
+	public void recordErrorLocation(ASTNode location, int nullStatus) {
+		if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
+			return;
+		}
+		if (this.recordedLocations == null)
+			this.recordedLocations = new HashMap();
+		this.recordedLocations.put(location, new Integer(nullStatus));
+	}
+
+	public boolean reportRecordedErrors(Scope scope, int mergedStatus) {
+		FakedTrackingVariable current = this;
+		while (current.globalClosingState == 0) {
+			current = current.innerTracker;
+			if (current == null) {
+				// no relevant state found -> report:
+				reportError(scope.problemReporter(), null, mergedStatus);
+				return true;
+			}
+		}
+		boolean hasReported = false;
+		if (this.recordedLocations != null) {
+			Iterator locations = this.recordedLocations.entrySet().iterator();
+			int reportFlags = 0;
+			while (locations.hasNext()) {
+				Map.Entry entry = (Entry) locations.next();
+				reportFlags |= reportError(scope.problemReporter(), (ASTNode)entry.getKey(), ((Integer)entry.getValue()).intValue());
+				hasReported = true;
+			}
+			if (reportFlags != 0) {
+				// after all locations have been reported, mark as reported to prevent duplicate report via an outer wrapper
+				current = this;
+				do {
+					current.globalClosingState |= reportFlags;
+				} while ((current = current.innerTracker) != null);
+			}
+		}
+		return hasReported;
+	}
+	
+	public int reportError(ProblemReporter problemReporter, ASTNode location, int nullStatus) {
+		if ((this.globalClosingState & OWNED_BY_OUTSIDE) != 0) {
+			return 0; // TODO: should we still propagate some flags??
+		}
+		// which degree of problem?
+		boolean isPotentialProblem = false;
+		if (nullStatus == FlowInfo.NULL) {
+			if ((this.globalClosingState & CLOSED_IN_NESTED_METHOD) != 0)
+				isPotentialProblem = true;
+		} else if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) {
+			isPotentialProblem = true;
+		}
+		// report:
+		if (isPotentialProblem) {
+			if ((this.globalClosingState & (REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK)) != 0)
+				return 0;
+			problemReporter.potentiallyUnclosedCloseable(this, location);	
+		} else {
+			if ((this.globalClosingState & (REPORTED_DEFINITIVE_LEAK)) != 0)
+				return 0;
+			problemReporter.unclosedCloseable(this, location);			
+		}
+		// propagate flag to inners:
+		int reportFlag = isPotentialProblem ? REPORTED_POTENTIAL_LEAK : REPORTED_DEFINITIVE_LEAK;
+		if (location == null) { // if location != null flags will be set after the loop over locations 
+			FakedTrackingVariable current = this;
+			do {
+				current.globalClosingState |= reportFlag;
+			} while ((current = current.innerTracker) != null);
+		}
+		return reportFlag;
+	}
+
+	public void reportExplicitClosing(ProblemReporter problemReporter) {
+		if ((this.globalClosingState & (OWNED_BY_OUTSIDE|REPORTED_EXPLICIT_CLOSE)) == 0) { // can't use t-w-r for OWNED_BY_OUTSIDE
+			this.globalClosingState |= REPORTED_EXPLICIT_CLOSE;
+			problemReporter.explicitlyClosedAutoCloseable(this);
+		}
+	}
+
+	public void resetReportingBits() {
+		FakedTrackingVariable current = this;
+		do {
+			current.globalClosingState &= ~(REPORTED_POTENTIAL_LEAK|REPORTED_DEFINITIVE_LEAK);
+			current = current.innerTracker;
+		} while (current != null);
+	}
+
+	public String nameForReporting(ASTNode location, ReferenceContext referenceContext) {
+		if (this.name == UNASSIGNED_CLOSEABLE_NAME) {
+			if (location != null && referenceContext != null) {
+				CompilationResult compResult = referenceContext.compilationResult();
+				if (compResult != null) {
+					int[] lineEnds = compResult.getLineSeparatorPositions();
+					int resourceLine = Util.getLineNumber(this.sourceStart, lineEnds , 0, lineEnds.length-1);
+					int reportLine = Util.getLineNumber(location.sourceStart, lineEnds , 0, lineEnds.length-1);
+					if (resourceLine != reportLine) {
+						char[] replacement = Integer.toString(resourceLine).toCharArray();
+						return String.valueOf(CharOperation.replace(UNASSIGNED_CLOSEABLE_NAME_TEMPLATE, TEMPLATE_ARGUMENT, replacement));
+					}
+				}
+			}
+		}
+		return String.valueOf(this.name);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java
new file mode 100644
index 0000000..aba1c3b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class FalseLiteral extends MagicLiteral {
+	
+	static final char[] source = {'f', 'a', 'l', 's', 'e'};
+	
+public FalseLiteral(int s , int e) {
+	super(s,e);
+}
+public void computeConstant() {
+	this.constant = BooleanConstant.fromValue(false);
+}
+/**
+ * Code generation for false literal
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+	// falseLabel being not nil means that we will not fall through into the FALSE case
+
+	int pc = codeStream.position;
+	if (valueRequired) {
+		if (falseLabel != null) {
+			// implicit falling through the TRUE case
+			if (trueLabel == null) {
+				codeStream.goto_(falseLabel);
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.BOOLEAN;
+}
+/**
+ *
+ */
+public char[] source() {
+	return source;
+}
+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/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
new file mode 100644
index 0000000..b82f850
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class FieldDeclaration extends AbstractVariableDeclaration {
+
+	public FieldBinding binding;
+	public Javadoc javadoc;
+
+	//allows to retrieve both the "type" part of the declaration (part1)
+	//and also the part that decribe the name and the init and optionally
+	//some other dimension ! ....
+	//public int[] a, b[] = X, c ;
+	//for b that would give for
+	// - part1 : public int[]
+	// - part2 : b[] = X,
+
+	public int endPart1Position;
+	public int endPart2Position;
+
+public FieldDeclaration() {
+	// for subtypes or conversion
+}
+
+public FieldDeclaration(	char[] name, int sourceStart, int sourceEnd) {
+	this.name = name;
+	//due to some declaration like
+	// int x, y = 3, z , x ;
+	//the sourceStart and the sourceEnd is ONLY on  the name
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public FlowInfo analyseCode(MethodScope initializationScope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (this.binding != null && !this.binding.isUsed() && this.binding.isOrEnclosedByPrivateType()) {
+		if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+			initializationScope.problemReporter().unusedPrivateField(this);
+		}
+	}
+	// cannot define static non-constant field inside nested class
+	if (this.binding != null
+			&& this.binding.isValidBinding()
+			&& this.binding.isStatic()
+			&& this.binding.constant() == Constant.NotAConstant
+			&& this.binding.declaringClass.isNestedType()
+			&& !this.binding.declaringClass.isStatic()) {
+		initializationScope.problemReporter().unexpectedStaticModifierForField(
+			(SourceTypeBinding) this.binding.declaringClass,
+			this);
+	}
+
+	if (this.initialization != null) {
+		flowInfo =
+			this.initialization
+				.analyseCode(initializationScope, flowContext, flowInfo)
+				.unconditionalInits();
+		flowInfo.markAsDefinitelyAssigned(this.binding);
+	}
+	if (this.initialization != null) {
+		if (this.binding.isNonNull()) {
+			int nullStatus = this.initialization.nullStatus(flowInfo, flowContext);
+			// check against annotation @NonNull:
+			if (nullStatus != FlowInfo.NON_NULL) {
+				char[][] annotationName = initializationScope.environment().getNonNullAnnotationName();
+				initializationScope.problemReporter().nullityMismatch(this.initialization, this.initialization.resolvedType, this.binding.type, nullStatus, annotationName);
+			}
+		}
+		this.initialization.checkNPEbyUnboxing(initializationScope, flowContext, flowInfo);
+	}
+	return flowInfo;
+}
+
+/**
+ * Code generation for a field declaration:
+ *	   standard assignment to a field
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & IsReachable) == 0) {
+		return;
+	}
+	// do not generate initialization code if final and static (constant is then
+	// recorded inside the field itself).
+	int pc = codeStream.position;
+	boolean isStatic;
+	if (this.initialization != null
+			&& !((isStatic = this.binding.isStatic()) && this.binding.constant() != Constant.NotAConstant)) {
+		// non-static field, need receiver
+		if (!isStatic)
+			codeStream.aload_0();
+		// generate initialization value
+		this.initialization.generateCode(currentScope, codeStream, true);
+		// store into field
+		if (isStatic) {
+			codeStream.fieldAccess(Opcodes.OPC_putstatic, this.binding, null /* default declaringClass */);
+		} else {
+			codeStream.fieldAccess(Opcodes.OPC_putfield, this.binding, null /* default declaringClass */);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
+	for (int i = 0, max = this.annotations.length; i < max; i++) {
+		Annotation annotation = this.annotations[i];
+		annotation.traverse(collector, (BlockScope) null);
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
+ */
+public int getKind() {
+	return this.type == null ? ENUM_CONSTANT : FIELD;
+}
+
+public boolean isStatic() {
+	if (this.binding != null)
+		return this.binding.isStatic();
+	return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+}
+
+public boolean isFinal() {
+	if (this.binding != null)
+		return this.binding.isFinal();
+	return (this.modifiers & ClassFileConstants.AccFinal) != 0;
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	if (this.javadoc != null) {
+		this.javadoc.print(indent, output);
+	}
+	return super.printStatement(indent, output);
+}
+
+public void resolve(MethodScope initializationScope) {
+	// the two <constant = Constant.NotAConstant> could be regrouped into
+	// a single line but it is clearer to have two lines while the reason of their
+	// existence is not at all the same. See comment for the second one.
+
+	//--------------------------------------------------------
+	if ((this.bits & ASTNode.HasBeenResolved) != 0) return;
+	if (this.binding == null || !this.binding.isValidBinding()) return;
+
+	this.bits |= ASTNode.HasBeenResolved;
+
+	// check if field is hiding some variable - issue is that field binding already got inserted in scope
+	// thus must lookup separately in super type and outer context
+	ClassScope classScope = initializationScope.enclosingClassScope();
+
+	if (classScope != null) {
+		checkHiding: {
+			SourceTypeBinding declaringType = classScope.enclosingSourceType();
+			checkHidingSuperField: {
+				if (declaringType.superclass == null) break checkHidingSuperField;
+				// 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
+				if (!existingVariable.canBeSeenBy(declaringType, this, initializationScope)) break checkHidingSuperField; // keep checking outer scenario
+				// collision with supertype field
+				initializationScope.problemReporter().fieldHiding(this, existingVariable);
+				break checkHiding; // already found a matching field
+			}
+			// only corner case is: lookup of outer field through static declaringType, which isn't detected by #getBinding as lookup starts
+			// from outer scope. Subsequent static contexts are detected for free.
+			Scope outerScope = classScope.parent;
+			if (outerScope.kind == Scope.COMPILATION_UNIT_SCOPE) break checkHiding;
+			Binding existingVariable = outerScope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
+			if (existingVariable == null) break checkHiding;
+			if (!existingVariable.isValidBinding()) break checkHiding;
+			if (existingVariable == this.binding) break checkHiding;
+			if (existingVariable instanceof FieldBinding) {
+				FieldBinding existingField = (FieldBinding) existingVariable;
+				if (existingField.original() == this.binding) break checkHiding;
+				if (!existingField.isStatic() && declaringType.isStatic()) break checkHiding;
+			}
+			// collision with outer field or local variable
+			initializationScope.problemReporter().fieldHiding(this, existingVariable);
+		}
+	}
+
+	if (this.type != null ) { // enum constants have no declared type
+		this.type.resolvedType = this.binding.type; // update binding for type reference
+	}
+
+	FieldBinding previousField = initializationScope.initializedField;
+	int previousFieldID = initializationScope.lastVisibleFieldID;
+	try {
+		initializationScope.initializedField = this.binding;
+		initializationScope.lastVisibleFieldID = this.binding.id;
+
+		resolveAnnotations(initializationScope, this.annotations, this.binding);
+		// check @Deprecated annotation presence
+		if ((this.binding.getAnnotationTagBits() & TagBits.AnnotationDeprecated) == 0
+				&& (this.binding.modifiers & ClassFileConstants.AccDeprecated) != 0
+				&& initializationScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+			initializationScope.problemReporter().missingDeprecatedAnnotationForField(this);
+		}
+		// the resolution of the initialization hasn't been done
+		if (this.initialization == null) {
+			this.binding.setConstant(Constant.NotAConstant);
+		} else {
+			// break dead-lock cycles by forcing constant to NotAConstant
+			this.binding.setConstant(Constant.NotAConstant);
+
+			TypeBinding fieldType = this.binding.type;
+			TypeBinding initializationType;
+			this.initialization.setExpressionContext(ASSIGNMENT_CONTEXT);
+			this.initialization.setExpectedType(fieldType); // needed in case of generic method invocation
+			if (this.initialization instanceof ArrayInitializer) {
+
+				if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) {
+					((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType;
+					this.initialization.computeConversion(initializationScope, fieldType, initializationType);
+				}
+			} else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) {
+
+				if (fieldType != initializationType) // must call before computeConversion() and typeMismatchError()
+					initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType);
+				if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType)
+						|| initializationType.isCompatibleWith(fieldType, classScope)) {
+					this.initialization.computeConversion(initializationScope, fieldType, initializationType);
+					if (initializationType.needsUncheckedConversion(fieldType)) {
+						    initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType);
+					}
+					if (this.initialization instanceof CastExpression
+							&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
+						CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization);
+					}
+				} else if (isBoxingCompatible(initializationType, fieldType, this.initialization, initializationScope)) {
+					this.initialization.computeConversion(initializationScope, fieldType, initializationType);
+					if (this.initialization instanceof CastExpression
+							&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
+						CastExpression.checkNeedForAssignedCast(initializationScope, fieldType, (CastExpression) this.initialization);
+					}
+				} else {
+					if ((fieldType.tagBits & TagBits.HasMissingType) == 0) {
+						// if problem already got signaled on type, do not report secondary problem
+						initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this.initialization, null);
+					}
+				}
+				if (this.binding.isFinal()){ // cast from constant actual type to variable type
+					this.binding.setConstant(this.initialization.constant.castTo((this.binding.type.id << 4) + this.initialization.constant.typeID()));
+				}
+			} else {
+				this.binding.setConstant(Constant.NotAConstant);
+			}
+			// check for assignment with no effect
+			if (this.binding == Expression.getDirectBinding(this.initialization)) {
+				initializationScope.problemReporter().assignmentHasNoEffect(this, this.name);
+			}
+		}
+		// Resolve Javadoc comment if one is present
+		if (this.javadoc != null) {
+			this.javadoc.resolve(initializationScope);
+		} else if (this.binding != null && this.binding.declaringClass != null && !this.binding.declaringClass.isLocalType()) {
+			// Set javadoc visibility
+			int javadocVisibility = this.binding.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+			ProblemReporter reporter = initializationScope.problemReporter();
+			int severity = reporter.computeSeverity(IProblem.JavadocMissing);
+			if (severity != ProblemSeverities.Ignore) {
+				if (classScope != null) {
+					javadocVisibility = Util.computeOuterMostVisibility(classScope.referenceType(), javadocVisibility);
+				}
+				int javadocModifiers = (this.binding.modifiers & ~ExtraCompilerModifiers.AccVisibilityMASK) | javadocVisibility;
+				reporter.javadocMissing(this.sourceStart, this.sourceEnd, severity, javadocModifiers);
+			}
+		}
+	} finally {
+		initializationScope.initializedField = previousField;
+		initializationScope.lastVisibleFieldID = previousFieldID;
+		if (this.binding.constant() == null)
+			this.binding.setConstant(Constant.NotAConstant);
+	}
+}
+
+public void traverse(ASTVisitor visitor, MethodScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (this.javadoc != null) {
+			this.javadoc.traverse(visitor, scope);
+		}
+		if (this.annotations != null) {
+			int annotationsLength = this.annotations.length;
+			for (int i = 0; i < annotationsLength; i++)
+				this.annotations[i].traverse(visitor, scope);
+		}
+		if (this.type != null) {
+			this.type.traverse(visitor, scope);
+		}
+		if (this.initialization != null)
+			this.initialization.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
new file mode 100644
index 0000000..772bb94
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -0,0 +1,734 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+public class FieldReference extends Reference implements InvocationSite {
+
+	public static final int READ = 0;
+	public static final int WRITE = 1;
+	public Expression receiver;
+	public char[] token;
+	public FieldBinding binding;															// exact binding resulting from lookup
+	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
+
+	public long nameSourcePosition; //(start<<32)+end
+	public TypeBinding actualReceiverType;
+	public TypeBinding genericCast;
+
+public FieldReference(char[] source, long pos) {
+	this.token = source;
+	this.nameSourcePosition = pos;
+	//by default the position are the one of the field (not true for super access)
+	this.sourceStart = (int) (pos >>> 32);
+	this.sourceEnd = (int) (pos & 0x00000000FFFFFFFFL);
+	this.bits |= Binding.FIELD;
+
+}
+
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+	// compound assignment extra work
+	if (isCompound) { // check the variable part is initialized if blank final
+		if (this.binding.isBlankFinal()
+			&& this.receiver.isThis()
+			&& currentScope.needBlankFinalFieldInitializationCheck(this.binding)) {
+			FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(this.binding.declaringClass.original(), flowInfo);
+			if (!fieldInits.isDefinitelyAssigned(this.binding)) {
+				currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this);
+				// we could improve error msg here telling "cannot use compound assignment on final blank field"
+			}
+		}
+		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
+	}
+	flowInfo =
+		this.receiver
+			.analyseCode(currentScope, flowContext, flowInfo, !this.binding.isStatic())
+			.unconditionalInits();
+	if (assignment.expression != null) {
+		flowInfo =
+			assignment
+				.expression
+				.analyseCode(currentScope, flowContext, flowInfo)
+				.unconditionalInits();
+	}
+	manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
+
+	// check if assigning a final field
+	if (this.binding.isFinal()) {
+		// in a context where it can be assigned?
+		if (this.binding.isBlankFinal()
+			&& !isCompound
+			&& this.receiver.isThis()
+			&& !(this.receiver instanceof QualifiedThisReference)
+			&& ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0) // (this).x is forbidden
+			&& currentScope.allowBlankFinalFieldAssignment(this.binding)) {
+			if (flowInfo.isPotentiallyAssigned(this.binding)) {
+				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(
+					this.binding,
+					this);
+			} else {
+				flowContext.recordSettingFinal(this.binding, this, flowInfo);
+			}
+			flowInfo.markAsDefinitelyAssigned(this.binding);
+		} else {
+			// assigning a final field outside an initializer or constructor or wrong reference
+			currentScope.problemReporter().cannotAssignToFinalField(this.binding, this);
+		}
+	} else if (this.binding.isNonNull()) {
+		// in a context where it can be assigned?
+		if (   !isCompound
+			&& this.receiver.isThis()
+			&& !(this.receiver instanceof QualifiedThisReference)
+			&& ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0)) { // (this).x is forbidden
+			flowInfo.markAsDefinitelyAssigned(this.binding);
+		}		
+	}
+	return flowInfo;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	boolean nonStatic = !this.binding.isStatic();
+	this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
+	if (nonStatic) {
+		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
+	}
+
+	if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
+	}
+	return flowInfo;
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (flowContext.isNullcheckedFieldAccess(this)) {
+		return true; // enough seen
+	}
+	return checkNullableFieldDereference(scope, this.binding, this.nameSourcePosition);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+	if (runtimeTimeType == null || compileTimeType == null)
+		return;
+	// set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
+	if (this.binding != null && this.binding.isValidBinding()) {
+		FieldBinding originalBinding = this.binding.original();
+		TypeBinding originalType = originalBinding.type;
+	    // extra cast needed if field type is type variable
+		if (originalType.leafComponentType().isTypeVariable()) {
+	    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
+	    		? compileTimeType  // unboxing: checkcast before conversion
+	    		: runtimeTimeType;
+	        this.genericCast = originalBinding.type.genericCast(targetType);
+	        if (this.genericCast instanceof ReferenceBinding) {
+				ReferenceBinding referenceCast = (ReferenceBinding) this.genericCast;
+				if (!referenceCast.canBeSeenBy(scope)) {
+		        	scope.problemReporter().invalidType(this,
+		        			new ProblemReferenceBinding(
+								CharOperation.splitOn('.', referenceCast.shortReadableName()),
+								referenceCast,
+								ProblemReasons.NotVisible));
+				}
+	        }
+		}
+	}
+	super.computeConversion(scope, runtimeTimeType, compileTimeType);
+}
+
+public FieldBinding fieldBinding() {
+	return this.binding;
+}
+
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	int pc = codeStream.position;
+	FieldBinding codegenBinding = this.binding.original();
+	this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic());
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	fieldStore(currentScope, codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], this.actualReceiverType, this.receiver.isImplicitThis(), valueRequired);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+	// no need for generic cast as value got dupped
+}
+
+/**
+ * Field reference code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	FieldBinding codegenBinding = this.binding.original();
+	boolean isStatic = codegenBinding.isStatic();
+	boolean isThisReceiver = this.receiver instanceof ThisReference;
+	Constant fieldConstant = codegenBinding.constant();
+	if (fieldConstant != Constant.NotAConstant) {
+		if (!isThisReceiver) {
+			this.receiver.generateCode(currentScope, codeStream, !isStatic);
+			if (!isStatic){
+				codeStream.invokeObjectGetClass();
+				codeStream.pop();
+			}
+		}
+		if (valueRequired) {
+			codeStream.generateConstant(fieldConstant, this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	if (valueRequired
+			|| (!isThisReceiver && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+			|| ((this.implicitConversion & TypeIds.UNBOXING) != 0)
+			|| (this.genericCast != null)) {
+		this.receiver.generateCode(currentScope, codeStream, !isStatic);
+		if ((this.bits & NeedReceiverGenericCast) != 0) {
+			codeStream.checkcast(this.actualReceiverType);
+		}		
+		pc = codeStream.position;
+		if (codegenBinding.declaringClass == null) { // array length
+			codeStream.arraylength();
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(this.implicitConversion);
+			} else {
+				// could occur if !valueRequired but compliance >= 1.4
+				codeStream.pop();
+			}
+		} else {
+			if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
+				TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+				if (isStatic) {
+					codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
+				} else {
+					codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
+				}
+			} else {
+				codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
+			}
+			// required cast must occur even if no value is required
+			if (this.genericCast != null) codeStream.checkcast(this.genericCast);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(this.implicitConversion);
+			} else {
+				boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+				// conversion only generated if unboxing
+				if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+				switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.type.id) {
+					case T_long :
+					case T_double :
+						codeStream.pop2();
+						break;
+					default :
+						codeStream.pop();
+				}
+			}
+		}
+	} else {
+		if (isThisReceiver) {
+			if (isStatic){
+				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
+				if (this.binding.original().declaringClass != this.actualReceiverType.erasure()) {
+					MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ];
+					if (accessor == null) {
+						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+						codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
+					} else {
+						codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+					}
+					switch (codegenBinding.type.id) {
+						case T_long :
+						case T_double :
+							codeStream.pop2();
+							break;
+						default :
+							codeStream.pop();
+					}
+				}
+			}
+		} else {
+			this.receiver.generateCode(currentScope, codeStream, !isStatic);
+			if (!isStatic){
+				codeStream.invokeObjectGetClass(); // perform null check
+				codeStream.pop();
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceEnd);
+}
+
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	boolean isStatic;
+	// check if compound assignment is the only usage of a private field
+	reportOnlyUselesslyReadPrivateField(currentScope, this.binding, valueRequired);
+	FieldBinding codegenBinding = this.binding.original();
+	this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
+	if (isStatic) {
+		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+			codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
+		}
+	} else {
+		codeStream.dup();
+		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+			codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
+		}
+	}
+	int operationTypeID;
+	switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
+		case T_JavaLangString :
+		case T_JavaLangObject :
+		case T_undefined :
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+			break;
+		default :
+			if (this.genericCast != null)
+				codeStream.checkcast(this.genericCast);
+			// promote the array reference to the suitable operation type
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One) { // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	fieldStore(currentScope, codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], this.actualReceiverType, this.receiver.isImplicitThis(), valueRequired);
+	// no need for generic cast as value got dupped
+}
+
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	boolean isStatic;
+	// check if postIncrement is the only usage of a private field
+	reportOnlyUselesslyReadPrivateField(currentScope, this.binding, valueRequired);
+	FieldBinding codegenBinding = this.binding.original();
+	this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
+	if (isStatic) {
+		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+			codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
+		}
+	} else {
+		codeStream.dup();
+		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+			codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[FieldReference.READ], null /* default declaringClass */);
+		}
+	}
+	TypeBinding operandType;
+	if (this.genericCast != null) {
+		codeStream.checkcast(this.genericCast);
+		operandType = this.genericCast;
+	} else {
+		operandType = codegenBinding.type;
+	}	
+	if (valueRequired) {
+		if (isStatic) {
+			switch (operandType.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2();
+					break;
+				default :
+					codeStream.dup();
+					break;
+			}			
+		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+			switch (operandType.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2_x1();
+					break;
+				default :
+					codeStream.dup_x1();
+					break;
+			}			
+		}
+	}
+	codeStream.generateImplicitConversion(this.implicitConversion);		
+	codeStream.generateConstant(
+		postIncrement.expression.constant,
+		this.implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+	codeStream.generateImplicitConversion(
+		postIncrement.preAssignImplicitConversion);
+	fieldStore(currentScope, codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], this.actualReceiverType, this.receiver.isImplicitThis(), false);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return null;
+}
+
+public boolean isEquivalent(Reference reference) {
+	// only consider field references relative to "this":
+	if (this.receiver.isThis() && !(this.receiver instanceof QualifiedThisReference)) {
+		// current is a simple "this.f1"
+		char[] otherToken = null;
+		// matching 'reference' could be "f1" or "this.f1":
+		if (reference instanceof SingleNameReference) {
+			otherToken = ((SingleNameReference) reference).token;
+		} else if (reference instanceof FieldReference) {
+			FieldReference fr = (FieldReference) reference;
+			if (fr.receiver.isThis() && !(fr.receiver instanceof QualifiedThisReference)) {
+				otherToken = fr.token;
+			}		
+		}
+		return otherToken != null && CharOperation.equals(this.token, otherToken);
+	} else {
+		// search deeper for "this" inside:
+		char[][] thisTokens = getThisFieldTokens(1);
+		if (thisTokens == null) {
+			return false;
+		}
+		// other can be "this.f1.f2", too, or "f1.f2":
+		char[][] otherTokens = null;
+		if (reference instanceof FieldReference) {
+			otherTokens = ((FieldReference) reference).getThisFieldTokens(1);
+		} else if (reference instanceof QualifiedNameReference) {
+			if (((QualifiedNameReference)reference).binding instanceof LocalVariableBinding)
+				return false; // initial variable mismatch: local (from f1.f2) vs. field (from this.f1.f2)
+			otherTokens = ((QualifiedNameReference) reference).tokens;
+		}
+		return CharOperation.equals(thisTokens, otherTokens);
+	}
+}
+
+private char[][] getThisFieldTokens(int nestingCount) {
+	char[][] result = null;
+	if (this.receiver.isThis() && ! (this.receiver instanceof QualifiedThisReference)) {
+		// found an inner-most this-reference, start building the token array:
+		result = new char[nestingCount][];
+		// fill it front to tail while traveling back out:
+		result[0] = this.token;
+	} else if (this.receiver instanceof FieldReference) {
+		result = ((FieldReference)this.receiver).getThisFieldTokens(nestingCount+1);
+		if (result != null) {
+			// front to tail: outermost is last:
+			result[result.length-nestingCount] = this.token;
+		}
+	}
+	return result;
+}
+
+public boolean isSuperAccess() {
+	return this.receiver.isSuper();
+}
+
+public boolean isTypeAccess() {
+	return this.receiver != null && this.receiver.isTypeReference();
+}
+
+public FieldBinding lastFieldBinding() {
+	return this.binding;
+}
+
+/*
+ * No need to emulate access to protected fields since not implicitly accessed
+ */
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
+	
+	// if field from parameterized type got found, use the original field at codegen time
+	FieldBinding codegenBinding = this.binding.original();
+	if (this.binding.isPrivate()) {
+		if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass)
+				&& this.binding.constant() == Constant.NotAConstant) {
+			if (this.syntheticAccessors == null)
+				this.syntheticAccessors = new MethodBinding[2];
+			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
+				((SourceTypeBinding) codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, isReadAccess, false /* not super ref in remote type*/);
+			currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
+			return;
+		}
+	} else if (this.receiver instanceof QualifiedSuperReference) { // qualified super
+		// qualified super need emulation always
+		SourceTypeBinding destinationType = (SourceTypeBinding) (((QualifiedSuperReference) this.receiver).currentCompatibleType);
+		if (this.syntheticAccessors == null)
+			this.syntheticAccessors = new MethodBinding[2];
+		this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(codegenBinding, isReadAccess, isSuperAccess());
+		currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
+		return;
+
+	} else if (this.binding.isProtected()) {
+		SourceTypeBinding enclosingSourceType;
+		if (((this.bits & ASTNode.DepthMASK) != 0)
+			&& this.binding.declaringClass.getPackage()
+				!= (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) {
+
+			SourceTypeBinding currentCompatibleType =
+				(SourceTypeBinding) enclosingSourceType.enclosingTypeAt(
+					(this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+			if (this.syntheticAccessors == null)
+				this.syntheticAccessors = new MethodBinding[2];
+			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(codegenBinding, isReadAccess, isSuperAccess());
+			currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
+			return;
+		}
+	}
+}
+
+public Constant optimizedBooleanConstant() {
+	switch (this.resolvedType.id) {
+		case T_boolean :
+		case T_JavaLangBoolean :
+			return this.constant != Constant.NotAConstant ? this.constant : this.binding.constant();
+		default :
+			return Constant.NotAConstant;
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
+ */
+public TypeBinding postConversionType(Scope scope) {
+	TypeBinding convertedType = this.resolvedType;
+	if (this.genericCast != null)
+		convertedType = this.genericCast;
+	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	switch (runtimeType) {
+		case T_boolean :
+			convertedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			convertedType = TypeBinding.BYTE;
+			break;
+		case T_short :
+			convertedType = TypeBinding.SHORT;
+			break;
+		case T_char :
+			convertedType = TypeBinding.CHAR;
+			break;
+		case T_int :
+			convertedType = TypeBinding.INT;
+			break;
+		case T_float :
+			convertedType = TypeBinding.FLOAT;
+			break;
+		case T_long :
+			convertedType = TypeBinding.LONG;
+			break;
+		case T_double :
+			convertedType = TypeBinding.DOUBLE;
+			break;
+		default :
+	}
+	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
+		convertedType = scope.environment().computeBoxingType(convertedType);
+	}
+	return convertedType;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	return this.receiver.printExpression(0, output).append('.').append(this.token);
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature type of the field.
+	// constants are propaged when the field is final
+	// and initialized with a (compile time) constant
+
+	//always ignore receiver cast, since may affect constant pool reference
+	boolean receiverCast = false;
+	if (this.receiver instanceof CastExpression) {
+		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+		receiverCast = true;
+	}
+	this.actualReceiverType = this.receiver.resolveType(scope);
+	if (this.actualReceiverType == null) {
+		this.constant = Constant.NotAConstant;
+		return null;
+	}
+	if (receiverCast) {
+		 // due to change of declaring class with receiver type, only identity cast should be notified
+		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+				scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
+		}
+	}
+	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
+	FieldBinding fieldBinding = this.binding = scope.getField(this.actualReceiverType, this.token, this);
+	if (!fieldBinding.isValidBinding()) {
+		this.constant = Constant.NotAConstant;
+		if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
+			// problem already got signaled on receiver, do not report secondary problem
+			return null;
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007 avoid secondary errors in case of
+		// missing super type for anonymous classes ... 
+		ReferenceBinding declaringClass = fieldBinding.declaringClass;
+		boolean avoidSecondary = declaringClass != null &&
+								 declaringClass.isAnonymousType() &&
+								 declaringClass.superclass() instanceof MissingTypeBinding;
+		if (!avoidSecondary) {
+			scope.problemReporter().invalidField(this, this.actualReceiverType);
+		}
+		if (fieldBinding instanceof ProblemFieldBinding) {
+			ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) fieldBinding;
+			FieldBinding closestMatch = problemFieldBinding.closestMatch;
+			switch(problemFieldBinding.problemId()) {
+				case ProblemReasons.InheritedNameHidesEnclosingName :
+				case ProblemReasons.NotVisible :
+				case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+				case ProblemReasons.NonStaticReferenceInStaticContext :
+					if (closestMatch != null) {
+						fieldBinding = closestMatch;
+					}
+			}
+		}
+		if (!fieldBinding.isValidBinding()) {
+			return null;
+		}
+	}
+	// handle indirect inheritance thru variable secondary bound
+	// receiver may receive generic cast, as part of implicit conversion
+	TypeBinding oldReceiverType = this.actualReceiverType;
+	this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(fieldBinding.declaringClass);
+	this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
+	if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+		this.bits |= NeedReceiverGenericCast;
+	}
+	if (isFieldUseDeprecated(fieldBinding, scope, this.bits)) {
+		scope.problemReporter().deprecatedField(fieldBinding, this);
+	}
+	boolean isImplicitThisRcv = this.receiver.isImplicitThis();
+	this.constant = isImplicitThisRcv ? fieldBinding.constant() : Constant.NotAConstant;
+	if (fieldBinding.isStatic()) {
+		// static field accessed through receiver? legal but unoptimal (optional warning)
+		if (!(isImplicitThisRcv
+				|| (this.receiver instanceof NameReference
+					&& (((NameReference) this.receiver).bits & Binding.TYPE) != 0))) {
+			scope.problemReporter().nonStaticAccessToStaticField(this, fieldBinding);
+		}
+		ReferenceBinding declaringClass = this.binding.declaringClass;
+		if (!isImplicitThisRcv
+				&& declaringClass != this.actualReceiverType
+				&& declaringClass.canBeSeenBy(scope)) {
+			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
+		}
+		// check if accessing enum static field in initializer
+		if (declaringClass.isEnum()) {
+			MethodScope methodScope = scope.methodScope();
+			SourceTypeBinding sourceType = scope.enclosingSourceType();
+			if (this.constant == Constant.NotAConstant
+					&& !methodScope.isStatic
+					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+					&& methodScope.isInsideInitializerOrConstructor()) {
+				scope.problemReporter().enumStaticFieldUsedDuringInitialization(this.binding, this);
+			}
+		}
+	}
+	TypeBinding fieldType = fieldBinding.type;
+	if (fieldType != null) {
+		if ((this.bits & ASTNode.IsStrictlyAssigned) == 0) {
+			fieldType = fieldType.capture(scope, this.sourceEnd);	// perform capture conversion if read access
+		}
+		this.resolvedType = fieldType;
+		if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
+			scope.problemReporter().invalidType(this, fieldType);
+			return null;
+		}
+	}
+	return fieldType;
+}
+
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	this.actualReceiverType = receiverType;
+}
+
+public void setDepth(int depth) {
+	this.bits &= ~ASTNode.DepthMASK; // flush previous depth if any
+	if (depth > 0) {
+		this.bits |= (depth & 0xFF) << ASTNode.DepthSHIFT; // encoded on 8 bits
+	}
+}
+
+public void setFieldIndex(int index) {
+	// ignored
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.receiver.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+
+public VariableBinding nullAnnotatedVariableBinding(boolean supportTypeAnnotations) {
+	if (this.binding != null) {
+		if (supportTypeAnnotations
+				|| ((this.binding.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) != 0)) {
+			return this.binding;
+		}
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java
new file mode 100644
index 0000000..f3e4b26
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.FloatUtil;
+
+public class FloatLiteral extends NumberLiteral {
+	
+	float value;
+	
+public FloatLiteral(char[] token, int s, int e) {
+	super(token, s, e);
+}
+
+public void computeConstant() {
+	Float computedValue;
+	boolean containsUnderscores = CharOperation.indexOf('_', this.source) > 0;
+	if (containsUnderscores) {
+		// remove all underscores from source
+		this.source = CharOperation.remove(this.source, '_');
+	}
+	try {
+		computedValue = Float.valueOf(String.valueOf(this.source));
+	} catch (NumberFormatException e) {
+		// hex floating point literal
+		// being rejected by 1.4 libraries where Float.valueOf(...) doesn't handle hex decimal floats
+		try {
+			float v = FloatUtil.valueOfHexFloatLiteral(this.source);
+			if (v == Float.POSITIVE_INFINITY) {
+				// error: the number is too large to represent
+				return;
+			}
+			if (Float.isNaN(v)) {
+				// error: the number is too small to represent
+				return;
+			}
+			this.value = v;
+			this.constant = FloatConstant.fromValue(v);
+		} catch (NumberFormatException e1) {
+			// if the computation of the constant fails
+		}
+		return;
+	}
+	final float floatValue = computedValue.floatValue();
+	if (floatValue > Float.MAX_VALUE) {
+		// error: the number is too large to represent
+		return;
+	}
+	if (floatValue < Float.MIN_VALUE) {
+		// see 1F6IGUU
+		// a true 0 only has '0' and '.' in mantissa
+		// 1.0e-5000d is non-zero, but underflows to 0
+		boolean isHexaDecimal = false;
+		label : for (int i = 0; i < this.source.length; i++) { //it is welled formated so just test against '0' and potential . D d
+			switch (this.source[i]) {
+				case '0' :
+				case '.' :
+					break;
+				case 'x' :
+				case 'X' :
+					isHexaDecimal = true;
+					break;
+				case 'e' :
+				case 'E' :
+				case 'f' :
+				case 'F' :
+				case 'd' :
+				case 'D' :
+					if (isHexaDecimal) {
+						return;
+					}
+					// starting the exponent - mantissa is all zero
+					// no exponent - mantissa is all zero
+					break label;
+				case 'p' :
+				case 'P' :
+					break label;
+				default :
+					// error: the number is too small to represent
+					return;
+			}
+		}
+	}
+	this.value = floatValue;
+	this.constant = FloatConstant.fromValue(this.value);
+}
+
+/**
+ * Code generation for float literal
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.FLOAT;
+}
+
+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/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
new file mode 100644
index 0000000..37dac8e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -0,0 +1,430 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for 
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ForStatement extends Statement {
+
+	public Statement[] initializations;
+	public Expression condition;
+	public Statement[] increments;
+	public Statement action;
+
+	//when there is no local declaration, there is no need of a new scope
+	//scope is positioned either to a new scope, or to the "upper"scope (see resolveType)
+	public BlockScope scope;
+
+	private BranchLabel breakLabel, continueLabel;
+
+	// for local variables table attributes
+	int preCondInitStateIndex = -1;
+	int preIncrementsInitStateIndex = -1;
+	int condIfTrueInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+	public ForStatement(
+		Statement[] initializations,
+		Expression condition,
+		Statement[] increments,
+		Statement action,
+		boolean neededScope,
+		int s,
+		int e) {
+
+		this.sourceStart = s;
+		this.sourceEnd = e;
+		this.initializations = initializations;
+		this.condition = condition;
+		this.increments = increments;
+		this.action = action;
+		// remember useful empty statement
+		if (action instanceof EmptyStatement) action.bits |= ASTNode.IsUsefulEmptyStatement;
+		if (neededScope) {
+			this.bits |= ASTNode.NeededScope;
+		}
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		this.breakLabel = new BranchLabel();
+		this.continueLabel = new BranchLabel();
+		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+
+		// process the initializations
+		if (this.initializations != null) {
+			for (int i = 0, count = this.initializations.length; i < count; i++) {
+				flowInfo = this.initializations[i].analyseCode(this.scope, flowContext, flowInfo);
+			}
+		}
+		this.preCondInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(flowInfo);
+
+		Constant cst = this.condition == null ? null : this.condition.constant;
+		boolean isConditionTrue = cst == null || (cst != Constant.NotAConstant && cst.booleanValue() == true);
+		boolean isConditionFalse = cst != null && (cst != Constant.NotAConstant && cst.booleanValue() == false);
+
+		cst = this.condition == null ? null : this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedTrue = cst == null ||  (cst != Constant.NotAConstant && cst.booleanValue() == true);
+		boolean isConditionOptimizedFalse = cst != null && (cst != Constant.NotAConstant && cst.booleanValue() == false);
+		
+		// process the condition
+		LoopingFlowContext condLoopContext = null;
+		FlowInfo condInfo = flowInfo.nullInfoLessUnconditionalCopy();
+		if (this.condition != null) {
+			if (!isConditionTrue) {
+				condInfo =
+					this.condition.analyseCode(
+						this.scope,
+						(condLoopContext =
+							new LoopingFlowContext(flowContext, flowInfo, this, null,
+								null, this.scope, true)),
+						condInfo);
+				this.condition.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+			}
+		}
+
+		// process the action
+		LoopingFlowContext loopingContext;
+		UnconditionalFlowInfo actionInfo;
+		if (this.action == null
+			|| (this.action.isEmptyBlock() && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3)) {
+			if (condLoopContext != null)
+				condLoopContext.complainOnDeferredFinalChecks(this.scope, condInfo);
+			if (isConditionTrue) {
+				if (condLoopContext != null) {
+					condLoopContext.complainOnDeferredNullChecks(currentScope,
+						condInfo);
+				}
+				return FlowInfo.DEAD_END;
+			} else {
+				if (isConditionFalse){
+					this.continueLabel = null; // for(;false;p());
+				}
+				actionInfo = condInfo.initsWhenTrue().unconditionalCopy();
+				loopingContext =
+					new LoopingFlowContext(flowContext, flowInfo, this,
+						this.breakLabel, this.continueLabel, this.scope, false);
+						// there is no action guarded by a preTest, so we use preTest=false
+						// to avoid pointless burdens of updating FlowContext.conditionalLevel
+			}
+		}
+		else {
+			loopingContext =
+				new LoopingFlowContext(flowContext, flowInfo, this, this.breakLabel,
+					this.continueLabel, this.scope, true);
+			FlowInfo initsWhenTrue = condInfo.initsWhenTrue();
+			this.condIfTrueInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(initsWhenTrue);
+
+				if (isConditionFalse) {
+					actionInfo = FlowInfo.DEAD_END;
+				} else {
+					actionInfo = initsWhenTrue.unconditionalCopy();
+					if (isConditionOptimizedFalse){
+						actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+					}
+				}
+			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
+				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits();
+			}
+
+			// code generation can be optimized when no need to continue in the loop
+			if ((actionInfo.tagBits &
+					loopingContext.initsOnContinue.tagBits &
+					FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
+				this.continueLabel = null;
+			}
+			else {
+				if (condLoopContext != null) {
+					condLoopContext.complainOnDeferredFinalChecks(this.scope,
+							condInfo);
+				}
+				actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
+				loopingContext.complainOnDeferredFinalChecks(this.scope,
+						actionInfo);
+			}
+		}
+		// for increments
+		FlowInfo exitBranch = flowInfo.copy();
+		// recover null inits from before condition analysis
+		LoopingFlowContext incrementContext = null;
+		if (this.continueLabel != null) {
+			if (this.increments != null) {
+				incrementContext =
+					new LoopingFlowContext(flowContext, flowInfo, this, null,
+						null, this.scope, true);
+				FlowInfo incrementInfo = actionInfo;
+				this.preIncrementsInitStateIndex =
+					currentScope.methodScope().recordInitializationStates(incrementInfo);
+				for (int i = 0, count = this.increments.length; i < count; i++) {
+					incrementInfo = this.increments[i].
+						analyseCode(this.scope, incrementContext, incrementInfo);
+				}
+				incrementContext.complainOnDeferredFinalChecks(this.scope,
+						actionInfo = incrementInfo.unconditionalInits());
+			}
+			exitBranch.addPotentialInitializationsFrom(actionInfo).
+				addInitializationsFrom(condInfo.initsWhenFalse());
+		} else {
+			exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
+			if (this.increments != null) {
+				if (initialComplaintLevel == Statement.NOT_COMPLAINED) {
+					currentScope.problemReporter().fakeReachable(this.increments[0]);
+				}
+			}
+		}
+		// nulls checks
+		if (condLoopContext != null) {
+			condLoopContext.complainOnDeferredNullChecks(currentScope,
+				actionInfo);
+		}
+		loopingContext.complainOnDeferredNullChecks(currentScope,
+			actionInfo);
+		if (incrementContext != null) {
+			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 &
+					FlowInfo.UNREACHABLE) != 0 ?
+					loopingContext.initsOnBreak :
+					flowInfo.addInitializationsFrom(loopingContext.initsOnBreak), // recover upstream null info
+				isConditionOptimizedTrue,
+				exitBranch,
+				isConditionOptimizedFalse,
+				!isConditionTrue /*for(;;){}while(true); unreachable(); */);
+		// Variables initialized only for the purpose of the for loop can be removed for further flow info
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=359495
+		if (this.initializations != null) {
+			for (int i = 0; i < this.initializations.length; i++) {
+				Statement init = this.initializations[i];
+				if (init instanceof LocalDeclaration) {
+					LocalVariableBinding binding = ((LocalDeclaration) init).binding;
+					mergedInfo.resetAssignmentInfo(binding);
+				}
+			}
+		}
+		this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+
+	/**
+	 * For statement code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+
+		// generate the initializations
+		if (this.initializations != null) {
+			for (int i = 0, max = this.initializations.length; i < max; i++) {
+				this.initializations[i].generateCode(this.scope, codeStream);
+			}
+		}
+		Constant cst = this.condition == null ? null : this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedFalse = cst != null && (cst != Constant.NotAConstant && cst.booleanValue() == false);
+		if (isConditionOptimizedFalse) {
+			this.condition.generateCode(this.scope, codeStream, false);
+			// May loose some local variable initializations : affecting the local variable attributes
+			if ((this.bits & ASTNode.NeededScope) != 0) {
+				codeStream.exitUserScope(this.scope);
+			}
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		// label management
+		BranchLabel actionLabel = new BranchLabel(codeStream);
+		actionLabel.tagBits |= BranchLabel.USED;
+		BranchLabel conditionLabel = new BranchLabel(codeStream);
+		this.breakLabel.initialize(codeStream);
+		if (this.continueLabel == null) {
+			conditionLabel.place();
+			if ((this.condition != null) && (this.condition.constant == Constant.NotAConstant)) {
+				this.condition.generateOptimizedBoolean(this.scope, codeStream, null, this.breakLabel, true);
+			}
+		} else {
+			this.continueLabel.initialize(codeStream);
+			// jump over the actionBlock
+			if ((this.condition != null)
+				&& (this.condition.constant == Constant.NotAConstant)
+				&& !((this.action == null || this.action.isEmptyBlock()) && (this.increments == null))) {
+				conditionLabel.tagBits |= BranchLabel.USED;
+				int jumpPC = codeStream.position;
+				codeStream.goto_(conditionLabel);
+				codeStream.recordPositionsFrom(jumpPC, this.condition.sourceStart);
+			}
+		}
+
+		// generate the loop action
+		if (this.action != null) {
+			// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+			if (this.condIfTrueInitStateIndex != -1) {
+				// insert all locals initialized inside the condition into the action generated prior to the condition
+				codeStream.addDefinitelyAssignedVariables(
+					currentScope,
+					this.condIfTrueInitStateIndex);
+			}
+			actionLabel.place();
+			this.action.generateCode(this.scope, codeStream);
+		} else {
+			actionLabel.place();
+		}
+		if (this.preIncrementsInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preIncrementsInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.preIncrementsInitStateIndex);
+		}
+		// continuation point
+		if (this.continueLabel != null) {
+			this.continueLabel.place();
+			// generate the increments for next iteration
+			if (this.increments != null) {
+				for (int i = 0, max = this.increments.length; i < max; i++) {
+					this.increments[i].generateCode(this.scope, codeStream);
+				}
+			}
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.preCondInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preCondInitStateIndex);
+			}
+			// generate the condition
+			conditionLabel.place();
+			if ((this.condition != null) && (this.condition.constant == Constant.NotAConstant)) {
+				this.condition.generateOptimizedBoolean(this.scope, codeStream, actionLabel, null, true);
+			} else {
+				codeStream.goto_(actionLabel);
+			}
+
+		} else {
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.preCondInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preCondInitStateIndex);
+			}
+		}
+
+
+		// May loose some local variable initializations : affecting the local variable attributes
+		if ((this.bits & ASTNode.NeededScope) != 0) {
+			codeStream.exitUserScope(this.scope);
+		}
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		this.breakLabel.place();
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output).append("for ("); //$NON-NLS-1$
+		//inits
+		if (this.initializations != null) {
+			for (int i = 0; i < this.initializations.length; i++) {
+				//nice only with expressions
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.initializations[i].print(0, output);
+			}
+		}
+		output.append("; "); //$NON-NLS-1$
+		//cond
+		if (this.condition != null) this.condition.printExpression(0, output);
+		output.append("; "); //$NON-NLS-1$
+		//updates
+		if (this.increments != null) {
+			for (int i = 0; i < this.increments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.increments[i].print(0, output);
+			}
+		}
+		output.append(") "); //$NON-NLS-1$
+		//block
+		if (this.action == null)
+			output.append(';');
+		else {
+			output.append('\n');
+			this.action.printStatement(tab + 1, output);
+		}
+		return output;
+	}
+
+	public void resolve(BlockScope upperScope) {
+
+		// use the scope that will hold the init declarations
+		this.scope = (this.bits & ASTNode.NeededScope) != 0 ? new BlockScope(upperScope) : upperScope;
+		if (this.initializations != null)
+			for (int i = 0, length = this.initializations.length; i < length; i++)
+				this.initializations[i].resolve(this.scope);
+		if (this.condition != null) {
+			TypeBinding type = this.condition.resolveTypeExpecting(this.scope, TypeBinding.BOOLEAN);
+			this.condition.computeConversion(this.scope, type, type);
+		}
+		if (this.increments != null)
+			for (int i = 0, length = this.increments.length; i < length; i++)
+				this.increments[i].resolve(this.scope);
+		if (this.action != null)
+			this.action.resolve(this.scope);
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			if (this.initializations != null) {
+				int initializationsLength = this.initializations.length;
+				for (int i = 0; i < initializationsLength; i++)
+					this.initializations[i].traverse(visitor, this.scope);
+			}
+
+			if (this.condition != null)
+				this.condition.traverse(visitor, this.scope);
+
+			if (this.increments != null) {
+				int incrementsLength = this.increments.length;
+				for (int i = 0; i < incrementsLength; i++)
+					this.increments[i].traverse(visitor, this.scope);
+			}
+
+			if (this.action != null)
+				this.action.traverse(visitor, this.scope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
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
new file mode 100644
index 0000000..d467e83
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -0,0 +1,579 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 370930 - NonNull annotation not considered for enhanced for loops
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 393719 - [compiler] inconsistent warnings on iteration variables
+ *     Jesper S Moller -  Contribution for
+ *								bug 401853 - Eclipse Java compiler creates invalid bytecode (java.lang.VerifyError)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.flow.LoopingFlowContext;
+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class ForeachStatement extends Statement {
+
+	public LocalDeclaration elementVariable;
+	public int elementVariableImplicitWidening = -1;
+	public Expression collection;
+	public Statement action;
+
+	// set the kind of foreach
+	private int kind;
+	// possible kinds of iterating behavior
+	private static final int ARRAY = 0;
+	private static final int RAW_ITERABLE = 1;
+	private static final int GENERIC_ITERABLE = 2;
+
+	private TypeBinding iteratorReceiverType;
+	private TypeBinding collectionElementType;
+
+	// loop labels
+	private BranchLabel breakLabel;
+	private BranchLabel continueLabel;
+
+	public BlockScope scope;
+
+	// secret variables for codegen
+	public LocalVariableBinding indexVariable;
+	public LocalVariableBinding collectionVariable;	// to store the collection expression value
+	public LocalVariableBinding maxVariable;
+	// secret variable names
+	private static final char[] SecretIteratorVariableName = " iterator".toCharArray(); //$NON-NLS-1$
+	private static final char[] SecretIndexVariableName = " index".toCharArray(); //$NON-NLS-1$
+	private static final char[] SecretCollectionVariableName = " collection".toCharArray(); //$NON-NLS-1$
+	private static final char[] SecretMaxVariableName = " max".toCharArray(); //$NON-NLS-1$
+
+	int postCollectionInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+	public ForeachStatement(
+		LocalDeclaration elementVariable,
+		int start) {
+
+		this.elementVariable = elementVariable;
+		this.sourceStart = start;
+		this.kind = -1;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		// initialize break and continue labels
+		this.breakLabel = new BranchLabel();
+		this.continueLabel = new BranchLabel();
+		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+
+		// process the element variable and collection
+		this.collection.checkNPE(currentScope, flowContext, flowInfo);
+		flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);		
+		FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
+		LocalVariableBinding elementVarBinding = this.elementVariable.binding;
+
+		// element variable will be assigned when iterating
+		condInfo.markAsDefinitelyAssigned(elementVarBinding);
+
+		this.postCollectionInitStateIndex = currentScope.methodScope().recordInitializationStates(condInfo);
+
+
+		// process the action
+		LoopingFlowContext loopingContext =
+			new LoopingFlowContext(flowContext, flowInfo, this, this.breakLabel,
+				this.continueLabel, this.scope, true);
+		UnconditionalFlowInfo actionInfo =
+			condInfo.nullInfoLessUnconditionalCopy();
+		actionInfo.markAsDefinitelyUnknown(elementVarBinding);
+		if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+			// this currently produces an unavoidable warning against all @NonNull element vars:
+			int nullStatus = this.elementVariable.checkAssignmentAgainstNullAnnotation(currentScope, flowContext, 
+															elementVarBinding, FlowInfo.UNKNOWN, this.collection, this.collectionElementType);
+			// TODO (stephan): 	once we have JSR 308 fetch nullStatus from the collection element type
+			//              	and feed the result into the above check (instead of FlowInfo.UNKNOWN)
+			if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) {
+				actionInfo.markNullStatus(elementVarBinding, nullStatus);
+			}
+		}
+		FlowInfo exitBranch;
+		if (!(this.action == null || (this.action.isEmptyBlock()
+				&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
+
+			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
+				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
+			}
+
+			// code generation can be optimized when no need to continue in the loop
+			exitBranch = flowInfo.unconditionalCopy().
+					addInitializationsFrom(condInfo.initsWhenFalse());
+			// TODO (maxime) no need to test when false: can optimize (same for action being unreachable above)
+			if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits &
+					FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
+				this.continueLabel = null;
+			} else {
+				actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
+				loopingContext.complainOnDeferredFinalChecks(this.scope, actionInfo);
+				exitBranch.addPotentialInitializationsFrom(actionInfo);
+			}
+		} else {
+			exitBranch = condInfo.initsWhenFalse();
+		}
+
+		// we need the variable to iterate the collection even if the
+		// element variable is not used
+		final boolean hasEmptyAction = this.action == null
+		|| this.action.isEmptyBlock()
+		|| ((this.action.bits & IsUsefulEmptyStatement) != 0);
+
+		switch(this.kind) {
+			case ARRAY :
+				if (!hasEmptyAction
+						|| elementVarBinding.resolvedPosition != -1) {
+					this.collectionVariable.useFlag = LocalVariableBinding.USED;
+					if (this.continueLabel != null) {
+						this.indexVariable.useFlag = LocalVariableBinding.USED;
+						this.maxVariable.useFlag = LocalVariableBinding.USED;
+					}
+				}
+				break;
+			case RAW_ITERABLE :
+			case GENERIC_ITERABLE :
+				this.indexVariable.useFlag = LocalVariableBinding.USED;
+				break;
+		}
+		//end of loop
+		loopingContext.complainOnDeferredNullChecks(currentScope, actionInfo);
+
+		FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
+				(loopingContext.initsOnBreak.tagBits &
+						FlowInfo.UNREACHABLE) != 0 ?
+								loopingContext.initsOnBreak :
+									flowInfo.addInitializationsFrom(loopingContext.initsOnBreak), // recover upstream null info
+									false,
+									exitBranch,
+									false,
+									true /*for(;;){}while(true); unreachable(); */);
+		mergedInfo.resetAssignmentInfo(this.elementVariable.binding);
+		this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+
+	/**
+	 * For statement code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+		final boolean hasEmptyAction = this.action == null
+			|| this.action.isEmptyBlock()
+			|| ((this.action.bits & IsUsefulEmptyStatement) != 0);
+
+		if (hasEmptyAction
+				&& this.elementVariable.binding.resolvedPosition == -1
+				&& this.kind == ARRAY) {
+			this.collection.generateCode(this.scope, codeStream, false);
+			codeStream.exitUserScope(this.scope);
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		// generate the initializations
+		switch(this.kind) {
+			case ARRAY :
+				this.collection.generateCode(this.scope, codeStream, true);
+				codeStream.store(this.collectionVariable, true);
+				codeStream.addVariable(this.collectionVariable);
+				if (this.continueLabel != null) {
+					// int length = (collectionVariable = [collection]).length;
+					codeStream.arraylength();
+					codeStream.store(this.maxVariable, false);
+					codeStream.addVariable(this.maxVariable);
+					codeStream.iconst_0();
+					codeStream.store(this.indexVariable, false);
+					codeStream.addVariable(this.indexVariable);
+				} else {
+					// leave collectionVariable on execution stack (will be consumed when swapping condition further down)
+				}
+				break;
+			case RAW_ITERABLE :
+			case GENERIC_ITERABLE :
+				this.collection.generateCode(this.scope, codeStream, true);
+				// declaringClass.iterator();
+				codeStream.invokeIterableIterator(this.iteratorReceiverType);
+				codeStream.store(this.indexVariable, false);
+				codeStream.addVariable(this.indexVariable);
+				break;
+		}
+		// label management
+		BranchLabel actionLabel = new BranchLabel(codeStream);
+		actionLabel.tagBits |= BranchLabel.USED;
+		BranchLabel conditionLabel = new BranchLabel(codeStream);
+		conditionLabel.tagBits |= BranchLabel.USED;
+		this.breakLabel.initialize(codeStream);
+		if (this.continueLabel == null) {
+			// generate the condition (swapped for optimizing)
+			conditionLabel.place();
+			int conditionPC = codeStream.position;
+			switch(this.kind) {
+				case ARRAY :
+					// inline the arraylength call
+					// collectionVariable is already on execution stack
+					codeStream.arraylength();
+					codeStream.ifeq(this.breakLabel);
+					break;
+				case RAW_ITERABLE :
+				case GENERIC_ITERABLE :
+					codeStream.load(this.indexVariable);
+					codeStream.invokeJavaUtilIteratorHasNext();
+					codeStream.ifeq(this.breakLabel);
+					break;
+			}
+			codeStream.recordPositionsFrom(conditionPC, this.elementVariable.sourceStart);
+		} else {
+			this.continueLabel.initialize(codeStream);
+			this.continueLabel.tagBits |= BranchLabel.USED;
+			// jump over the actionBlock
+			codeStream.goto_(conditionLabel);
+		}
+
+		// generate the loop action
+		actionLabel.place();
+
+		// generate the loop action
+		switch(this.kind) {
+			case ARRAY :
+				if (this.elementVariable.binding.resolvedPosition != -1) {
+					codeStream.load(this.collectionVariable);
+					if (this.continueLabel == null) {
+						codeStream.iconst_0(); // no continue, thus simply hardcode offset 0
+					} else {
+						codeStream.load(this.indexVariable);
+					}
+					codeStream.arrayAt(this.collectionElementType.id);
+					if (this.elementVariableImplicitWidening != -1) {
+						codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
+					}
+					codeStream.store(this.elementVariable.binding, false);
+					codeStream.addVisibleLocalVariable(this.elementVariable.binding);
+					if (this.postCollectionInitStateIndex != -1) {
+						codeStream.addDefinitelyAssignedVariables(
+							currentScope,
+							this.postCollectionInitStateIndex);
+					}
+				}
+				break;
+			case RAW_ITERABLE :
+			case GENERIC_ITERABLE :
+				codeStream.load(this.indexVariable);
+				codeStream.invokeJavaUtilIteratorNext();
+				if (this.elementVariable.binding.type.id != T_JavaLangObject) {
+					if (this.elementVariableImplicitWidening != -1) {
+						codeStream.checkcast(this.collectionElementType);
+						codeStream.generateImplicitConversion(this.elementVariableImplicitWidening);
+					} else {
+						codeStream.checkcast(this.elementVariable.binding.type);
+					}
+				}
+				if (this.elementVariable.binding.resolvedPosition == -1) {
+					switch (this.elementVariable.binding.type.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.pop2();
+							break;
+						default:
+							codeStream.pop();
+							break;
+					}
+				} else {
+					codeStream.store(this.elementVariable.binding, false);
+					codeStream.addVisibleLocalVariable(this.elementVariable.binding);
+					if (this.postCollectionInitStateIndex != -1) {
+						codeStream.addDefinitelyAssignedVariables(
+							currentScope,
+							this.postCollectionInitStateIndex);
+					}
+				}
+				break;
+		}
+
+		if (!hasEmptyAction) {
+			this.action.generateCode(this.scope, codeStream);
+		}
+		codeStream.removeVariable(this.elementVariable.binding);
+		if (this.postCollectionInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postCollectionInitStateIndex);
+		}
+		// continuation point
+		if (this.continueLabel != null) {
+			this.continueLabel.place();
+			int continuationPC = codeStream.position;
+			// generate the increments for next iteration
+			switch(this.kind) {
+				case ARRAY :
+					if (!hasEmptyAction || this.elementVariable.binding.resolvedPosition >= 0) {
+						codeStream.iinc(this.indexVariable.resolvedPosition, 1);
+					}
+					// generate the condition
+					conditionLabel.place();
+					codeStream.load(this.indexVariable);
+					codeStream.load(this.maxVariable);
+					codeStream.if_icmplt(actionLabel);
+					break;
+				case RAW_ITERABLE :
+				case GENERIC_ITERABLE :
+					// generate the condition
+					conditionLabel.place();
+					codeStream.load(this.indexVariable);
+					codeStream.invokeJavaUtilIteratorHasNext();
+					codeStream.ifne(actionLabel);
+					break;
+			}
+			codeStream.recordPositionsFrom(continuationPC, this.elementVariable.sourceStart);
+		}
+		switch(this.kind) {
+			case ARRAY :
+				codeStream.removeVariable(this.indexVariable);
+				codeStream.removeVariable(this.maxVariable);
+				codeStream.removeVariable(this.collectionVariable);
+				break;
+			case RAW_ITERABLE :
+			case GENERIC_ITERABLE :
+				// generate the condition
+				codeStream.removeVariable(this.indexVariable);
+				break;
+		}
+		codeStream.exitUserScope(this.scope);
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		this.breakLabel.place();
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+
+		printIndent(indent, output).append("for ("); //$NON-NLS-1$
+		this.elementVariable.printAsExpression(0, output);
+		output.append(" : ");//$NON-NLS-1$
+		if (this.collection != null) {
+			this.collection.print(0, output).append(") "); //$NON-NLS-1$
+		} else {
+			output.append(')');
+		}
+		//block
+		if (this.action == null) {
+			output.append(';');
+		} else {
+			output.append('\n');
+			this.action.printStatement(indent + 1, output);
+		}
+		return output;
+	}
+
+	public void resolve(BlockScope upperScope) {
+		// use the scope that will hold the init declarations
+		this.scope = new BlockScope(upperScope);
+		this.elementVariable.resolve(this.scope); // collection expression can see itemVariable
+		TypeBinding elementType = this.elementVariable.type.resolvedType;
+		TypeBinding collectionType = this.collection == null ? null : this.collection.resolveType(this.scope);
+
+		TypeBinding expectedCollectionType = null;
+		if (elementType != null && collectionType != null) {
+			boolean isTargetJsr14 = this.scope.compilerOptions().targetJDK == ClassFileConstants.JDK1_4;
+			if (collectionType.isArrayType()) { // for(E e : E[])
+				this.kind = ARRAY;
+				this.collectionElementType = ((ArrayBinding) collectionType).elementsType();
+				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().unsafeElementTypeConversion(this.collection, this.collectionElementType, elementType);
+				}
+				// in case we need to do a conversion
+				int compileTimeTypeID = this.collectionElementType.id;
+				if (elementType.isBaseType()) {
+					this.collection.computeConversion(this.scope, collectionType, collectionType);
+					if (!this.collectionElementType.isBaseType()) {
+						compileTimeTypeID = this.scope.environment().computeBoxingType(this.collectionElementType).id;
+						this.elementVariableImplicitWidening = UNBOXING;
+						if (elementType.isBaseType()) {
+							this.elementVariableImplicitWidening |= (elementType.id << 4) + compileTimeTypeID;
+							this.scope.problemReporter().autoboxing(this.collection, this.collectionElementType, elementType);
+						}
+					} else {
+						this.elementVariableImplicitWidening = (elementType.id << 4) + compileTimeTypeID;
+					}
+				} else if (this.collectionElementType.isBaseType()) {
+					this.collection.computeConversion(this.scope, collectionType, collectionType);
+					int boxedID = this.scope.environment().computeBoxingType(this.collectionElementType).id;
+					this.elementVariableImplicitWidening = BOXING | (compileTimeTypeID << 4) | compileTimeTypeID; // use primitive type in implicit conversion
+					compileTimeTypeID = boxedID;
+					this.scope.problemReporter().autoboxing(this.collection, this.collectionElementType, elementType);
+				} else {
+					expectedCollectionType = upperScope.createArrayType(elementType, 1);
+					this.collection.computeConversion(this.scope, expectedCollectionType, collectionType);
+				}
+			} else if (collectionType instanceof ReferenceBinding) {
+				ReferenceBinding iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaLangIterable, false /*Iterable is not a class*/);
+				if (iterableType == null && isTargetJsr14) {
+					iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaUtilCollection, false /*Iterable is not a class*/);
+				}
+				checkIterable: {
+					if (iterableType == null) break checkIterable;
+
+					this.iteratorReceiverType = collectionType.erasure();
+					if (isTargetJsr14) {
+						if (((ReferenceBinding)this.iteratorReceiverType).findSuperTypeOriginatingFrom(T_JavaUtilCollection, false) == null) {
+							this.iteratorReceiverType = iterableType; // handle indirect inheritance thru variable secondary bound
+							this.collection.computeConversion(this.scope, iterableType, collectionType);
+						} else {
+							this.collection.computeConversion(this.scope, collectionType, collectionType);
+						}
+					} else if (((ReferenceBinding)this.iteratorReceiverType).findSuperTypeOriginatingFrom(T_JavaLangIterable, false) == null) {
+						this.iteratorReceiverType = iterableType; // handle indirect inheritance thru variable secondary bound
+						this.collection.computeConversion(this.scope, iterableType, collectionType);
+					} else {
+						this.collection.computeConversion(this.scope, collectionType, collectionType);
+					}
+
+					TypeBinding[] arguments = null;
+					switch (iterableType.kind()) {
+						case Binding.RAW_TYPE : // for(Object o : Iterable)
+							this.kind = RAW_ITERABLE;
+							this.collectionElementType = this.scope.getJavaLangObject();
+							if (!this.collectionElementType.isCompatibleWith(elementType)
+									&& !this.scope.isBoxingCompatibleWith(this.collectionElementType, elementType)) {
+								this.scope.problemReporter().notCompatibleTypesErrorInForeach(this.collection, this.collectionElementType, elementType);
+							}
+							// no conversion needed as only for reference types
+							break checkIterable;
+
+						case Binding.GENERIC_TYPE : // for (T t : Iterable<T>) - in case used inside Iterable itself
+							arguments = iterableType.typeVariables();
+							break;
+
+						case Binding.PARAMETERIZED_TYPE : // for(E e : Iterable<E>)
+							arguments = ((ParameterizedTypeBinding)iterableType).arguments;
+							break;
+
+						default:
+							break checkIterable;
+					}
+					// generic or parameterized case
+					if (arguments.length != 1) break checkIterable; // per construction can only be one
+					this.kind = GENERIC_ITERABLE;
+
+					this.collectionElementType = arguments[0];
+					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=393719
+					    this.scope.problemReporter().unsafeElementTypeConversion(this.collection, this.collectionElementType, elementType);
+					}
+					int compileTimeTypeID = this.collectionElementType.id;
+					// no conversion needed as only for reference types
+					if (elementType.isBaseType()) {
+						if (!this.collectionElementType.isBaseType()) {
+							compileTimeTypeID = this.scope.environment().computeBoxingType(this.collectionElementType).id;
+							this.elementVariableImplicitWidening = UNBOXING;
+							if (elementType.isBaseType()) {
+								this.elementVariableImplicitWidening |= (elementType.id << 4) + compileTimeTypeID;
+							}
+						} else {
+							this.elementVariableImplicitWidening = (elementType.id << 4) + compileTimeTypeID;
+						}
+					} else {
+						if (this.collectionElementType.isBaseType()) {
+							this.elementVariableImplicitWidening = BOXING | (compileTimeTypeID << 4) | compileTimeTypeID; // use primitive type in implicit conversion
+						}
+					}
+				}
+			}
+			switch(this.kind) {
+				case ARRAY :
+					// allocate #index secret variable (of type int)
+					this.indexVariable = new LocalVariableBinding(SecretIndexVariableName, TypeBinding.INT, ClassFileConstants.AccDefault, false);
+					this.scope.addLocalVariable(this.indexVariable);
+					this.indexVariable.setConstant(Constant.NotAConstant); // not inlinable
+					// allocate #max secret variable
+					this.maxVariable = new LocalVariableBinding(SecretMaxVariableName, TypeBinding.INT, ClassFileConstants.AccDefault, false);
+					this.scope.addLocalVariable(this.maxVariable);
+					this.maxVariable.setConstant(Constant.NotAConstant); // not inlinable
+					// add #array secret variable (of collection type)
+					if (expectedCollectionType == null) {
+						this.collectionVariable = new LocalVariableBinding(SecretCollectionVariableName, collectionType, ClassFileConstants.AccDefault, false);
+					} else {
+						this.collectionVariable = new LocalVariableBinding(SecretCollectionVariableName, expectedCollectionType, ClassFileConstants.AccDefault, false);
+					}
+					this.scope.addLocalVariable(this.collectionVariable);
+					this.collectionVariable.setConstant(Constant.NotAConstant); // not inlinable
+					break;
+				case RAW_ITERABLE :
+				case GENERIC_ITERABLE :
+					// allocate #index secret variable (of type Iterator)
+					this.indexVariable = new LocalVariableBinding(SecretIteratorVariableName, this.scope.getJavaUtilIterator(), ClassFileConstants.AccDefault, false);
+					this.scope.addLocalVariable(this.indexVariable);
+					this.indexVariable.setConstant(Constant.NotAConstant); // not inlinable
+					break;
+				default :
+					if (isTargetJsr14) {
+						this.scope.problemReporter().invalidTypeForCollectionTarget14(this.collection);
+					} else {
+						this.scope.problemReporter().invalidTypeForCollection(this.collection);
+					}
+			}
+		}
+		if (this.action != null) {
+			this.action.resolve(this.scope);
+		}
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.elementVariable.traverse(visitor, this.scope);
+			if (this.collection != null) {
+				this.collection.traverse(visitor, this.scope);
+			}
+			if (this.action != null) {
+				this.action.traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
new file mode 100644
index 0000000..4e64752
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FunctionalExpression.java
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335        
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBindingVisitor;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+public abstract class FunctionalExpression extends Expression {
+	
+	TypeBinding expectedType;
+	public MethodBinding descriptor;
+	public MethodBinding binding;
+	boolean ignoreFurtherInvestigation;
+	protected ExpressionContext expressionContext = VANILLA_CONTEXT;
+	protected SimpleLookupTable resultExpressions;
+	protected boolean hasIgnoredMandatoryErrors = false;
+	protected CompilationResult compilationResult;
+	protected BlockScope enclosingScope;
+	protected boolean ellipsisArgument;
+	protected static IErrorHandlingPolicy silentErrorHandlingPolicy = DefaultErrorHandlingPolicies.ignoreAllProblems();
+	
+	public FunctionalExpression(CompilationResult compilationResult) {
+		this.compilationResult = compilationResult;
+	}
+
+	public void setExpectedType(TypeBinding expectedType) {
+		this.expectedType = this.ellipsisArgument ? ((ArrayBinding) expectedType).elementsType() : expectedType;
+	}
+	
+	public void setExpressionContext(ExpressionContext context) {
+		this.expressionContext = context;
+	}
+	
+	public void tagAsEllipsisArgument() {
+		this.ellipsisArgument = true;
+	}
+	public boolean isPolyExpression() {
+		return this.expressionContext != VANILLA_CONTEXT;
+	}
+
+	public TypeBinding expectedType() {
+		return this.expectedType;
+	}
+	
+	public TypeBinding resolveType(BlockScope blockScope) {
+		this.constant = Constant.NotAConstant;
+		MethodBinding sam = this.expectedType == null ? null : this.expectedType.getSingleAbstractMethod(blockScope);
+		if (sam == null) {
+			blockScope.problemReporter().targetTypeIsNotAFunctionalInterface(this);
+			return null;
+		}
+		if (!sam.isValidBinding()) {
+			switch (sam.problemId()) {
+				case ProblemReasons.NoSuchSingleAbstractMethod:
+					blockScope.problemReporter().targetTypeIsNotAFunctionalInterface(this);
+					break;
+				case ProblemReasons.NotAWellFormedParameterizedType:
+					blockScope.problemReporter().illFormedParameterizationOfFunctionalInterface(this);
+					break;
+				case ProblemReasons.IntersectionHasMultipleFunctionalInterfaces:
+					blockScope.problemReporter().multipleFunctionalInterfaces(this);
+					break;
+			}
+			return null;
+		}
+		
+		this.descriptor = sam;
+		if (kosherDescriptor(blockScope, sam, true)) {
+			return this.resolvedType = this.expectedType;		
+		}
+		
+		return this.resolvedType = null;
+	}
+
+	class VisibilityInspector extends TypeBindingVisitor {
+
+		private Scope scope;
+		private boolean shouldChatter;
+        private boolean visible = true;
+		private FunctionalExpression expression;
+        
+		public VisibilityInspector(FunctionalExpression expression, Scope scope, boolean shouldChatter) {
+			this.scope = scope;
+			this.shouldChatter = shouldChatter;
+			this.expression = expression;
+		}
+
+		private void checkVisibility(ReferenceBinding referenceBinding) {
+			if (!referenceBinding.canBeSeenBy(this.scope)) {
+				this.visible = false;
+				if (this.shouldChatter)
+					this.scope.problemReporter().descriptorHasInvisibleType(this.expression, referenceBinding);
+			}
+		}
+		
+		public boolean visit(ReferenceBinding referenceBinding) {
+			checkVisibility(referenceBinding);
+			return true;
+		}
+
+		
+		public boolean visit(ParameterizedTypeBinding parameterizedTypeBinding) {
+			checkVisibility(parameterizedTypeBinding);
+			return true;
+		}
+		
+		public boolean visit(RawTypeBinding rawTypeBinding) {
+			checkVisibility(rawTypeBinding);
+			return true;
+		}
+
+		public boolean visible(TypeBinding type) {
+			TypeBindingVisitor.visit(this, type);
+			return this.visible;
+		}
+
+		public boolean visible(TypeBinding[] types) {
+			TypeBindingVisitor.visit(this, types);
+			return this.visible;
+		}
+		
+	}
+
+	public boolean kosherDescriptor(Scope scope, MethodBinding sam, boolean shouldChatter) {
+	
+		VisibilityInspector inspector = new VisibilityInspector(this, scope, shouldChatter);
+		
+		boolean status = true;
+		
+		if (!inspector.visible(sam.returnType))
+			status = false;
+		if (!inspector.visible(sam.parameters))
+			status = false;
+		if (!inspector.visible(sam.thrownExceptions))
+			status = false;
+		
+		return status;
+	}
+
+	public int nullStatus(FlowInfo flowInfo) {
+		return FlowInfo.NON_NULL;
+	}
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..254ff71
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for 
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class IfStatement extends Statement {
+
+	//this class represents the case of only one statement in
+	//either else and/or then branches.
+
+	public Expression condition;
+	public Statement thenStatement;
+	public Statement elseStatement;
+
+	// for local variables table attributes
+	int thenInitStateIndex = -1;
+	int elseInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+public IfStatement(Expression condition, Statement thenStatement, int sourceStart, int sourceEnd) {
+	this.condition = condition;
+	this.thenStatement = thenStatement;
+	// remember useful empty statement
+	if (thenStatement instanceof EmptyStatement) thenStatement.bits |= IsUsefulEmptyStatement;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public IfStatement(Expression condition, Statement thenStatement, Statement elseStatement, int sourceStart, int sourceEnd) {
+	this.condition = condition;
+	this.thenStatement = thenStatement;
+	// remember useful empty statement
+	if (thenStatement instanceof EmptyStatement) thenStatement.bits |= IsUsefulEmptyStatement;
+	this.elseStatement = elseStatement;
+	if (elseStatement instanceof IfStatement) elseStatement.bits |= IsElseIfStatement;
+	if (elseStatement instanceof EmptyStatement) elseStatement.bits |= IsUsefulEmptyStatement;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// process the condition
+	FlowInfo conditionFlowInfo = this.condition.analyseCode(currentScope, flowContext, flowInfo);
+	int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+
+	Constant cst = this.condition.optimizedBooleanConstant();
+	this.condition.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+	boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+	flowContext.conditionalLevel++;
+
+	// process the THEN part
+	FlowInfo thenFlowInfo = conditionFlowInfo.safeInitsWhenTrue();
+	if (isConditionOptimizedFalse) {
+		thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+	}
+	FlowInfo elseFlowInfo = conditionFlowInfo.initsWhenFalse().copy();
+	if (isConditionOptimizedTrue) {
+		elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+	}
+	if (((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) && 
+			((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)) {
+		// Mark then block as unreachable
+		// No need if the whole if-else construct itself lies in unreachable code
+		this.bits |= ASTNode.IsThenStatementUnreachable;
+	} else if (((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) &&
+			((elseFlowInfo.tagBits & FlowInfo.UNREACHABLE) != 0)) {
+		// Mark else block as unreachable
+		// No need if the whole if-else construct itself lies in unreachable code
+		this.bits |= ASTNode.IsElseStatementUnreachable;
+	}
+	boolean reportDeadCodeForKnownPattern = !isKnowDeadCodePattern(this.condition) || currentScope.compilerOptions().reportDeadCodeInTrivialIfStatement;
+	if (this.thenStatement != null) {
+		// Save info for code gen
+		this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
+		if (isConditionOptimizedFalse || ((this.bits & ASTNode.IsThenStatementUnreachable) != 0)) {
+			if (reportDeadCodeForKnownPattern) {
+				this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel, false);
+			} else {
+				// its a known coding pattern which should be tolerated by dead code analysis
+				// according to isKnowDeadCodePattern()
+				this.bits &= ~ASTNode.IsThenStatementUnreachable;
+			}
+		}
+		thenFlowInfo = this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
+	}
+	// any null check from the condition is now expired
+	flowContext.expireNullCheckedFieldInfo();
+	// code gen: optimizing the jump around the ELSE part
+	if ((thenFlowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
+		this.bits |= ASTNode.ThenExit;
+	}
+
+	// process the ELSE part
+	if (this.elseStatement != null) {
+		// signal else clause unnecessarily nested, tolerate else-if code pattern
+		if (thenFlowInfo == FlowInfo.DEAD_END
+				&& (this.bits & IsElseIfStatement) == 0 	// else of an else-if
+				&& !(this.elseStatement instanceof IfStatement)) {
+			currentScope.problemReporter().unnecessaryElse(this.elseStatement);
+		}
+		// Save info for code gen
+		this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
+		if (isConditionOptimizedTrue || ((this.bits & ASTNode.IsElseStatementUnreachable) != 0)) {
+			if (reportDeadCodeForKnownPattern) {
+				this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel, false);
+			} else {
+				// its a known coding pattern which should be tolerated by dead code analysis
+				// according to isKnowDeadCodePattern()
+				this.bits &= ~ASTNode.IsElseStatementUnreachable;
+			}
+		}
+		elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
+	}
+	// process AutoCloseable resources closed in only one branch:
+	currentScope.correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
+	// merge THEN & ELSE initializations
+	FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranchesIfElse(
+		thenFlowInfo,
+		isConditionOptimizedTrue,
+		elseFlowInfo,
+		isConditionOptimizedFalse,
+		true /*if(true){ return; }  fake-reachable(); */,
+		flowInfo,
+		this,
+		reportDeadCodeForKnownPattern);
+	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+	flowContext.conditionalLevel--;
+	return mergedInfo;
+}
+
+/**
+ * If code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	BranchLabel endifLabel = new BranchLabel(codeStream);
+
+	// optimizing the then/else part code gen
+	Constant cst;
+	boolean hasThenPart =
+		!(((cst = this.condition.optimizedBooleanConstant()) != Constant.NotAConstant
+				&& cst.booleanValue() == false)
+			|| this.thenStatement == null
+			|| this.thenStatement.isEmptyBlock());
+	boolean hasElsePart =
+		!((cst != Constant.NotAConstant && cst.booleanValue() == true)
+			|| this.elseStatement == null
+			|| this.elseStatement.isEmptyBlock());
+	if (hasThenPart) {
+		BranchLabel falseLabel = null;
+		// generate boolean condition only if needed
+		if (cst != Constant.NotAConstant && cst.booleanValue() == true) {
+			this.condition.generateCode(currentScope, codeStream, false);
+		} else {
+			this.condition.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				null,
+				hasElsePart ? (falseLabel = new BranchLabel(codeStream)) : endifLabel,
+				true/*cst == Constant.NotAConstant*/);
+		}
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.thenInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.thenInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.thenInitStateIndex);
+		}
+		// generate then statement
+		this.thenStatement.generateCode(currentScope, codeStream);
+		// jump around the else statement
+		if (hasElsePart) {
+			if ((this.bits & ASTNode.ThenExit) == 0) {
+				this.thenStatement.branchChainTo(endifLabel);
+				int position = codeStream.position;
+				codeStream.goto_(endifLabel);
+				//goto is pointing to the last line of the thenStatement
+				codeStream.recordPositionsFrom(position, this.thenStatement.sourceEnd);
+				// generate else statement
+			}
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.elseInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(
+					currentScope,
+					this.elseInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.elseInitStateIndex);
+			}
+			if (falseLabel != null) falseLabel.place();
+			this.elseStatement.generateCode(currentScope, codeStream);
+		}
+	} else if (hasElsePart) {
+		// generate boolean condition only if needed
+		if (cst != Constant.NotAConstant && cst.booleanValue() == false) {
+			this.condition.generateCode(currentScope, codeStream, false);
+		} else {
+			this.condition.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				endifLabel,
+				null,
+				true/*cst == Constant.NotAConstant*/);
+		}
+		// generate else statement
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.elseInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(
+				currentScope,
+				this.elseInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.elseInitStateIndex);
+		}
+		this.elseStatement.generateCode(currentScope, codeStream);
+	} else {
+		// generate condition side-effects
+		this.condition.generateCode(currentScope, codeStream, false);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (this.mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(
+			currentScope,
+			this.mergedInitStateIndex);
+		codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+	}
+	endifLabel.place();
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	printIndent(indent, output).append("if ("); //$NON-NLS-1$
+	this.condition.printExpression(0, output).append(")\n");	//$NON-NLS-1$
+	this.thenStatement.printStatement(indent + 2, output);
+	if (this.elseStatement != null) {
+		output.append('\n');
+		printIndent(indent, output);
+		output.append("else\n"); //$NON-NLS-1$
+		this.elseStatement.printStatement(indent + 2, output);
+	}
+	return output;
+}
+
+public void resolve(BlockScope scope) {
+	TypeBinding type = this.condition.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
+	this.condition.computeConversion(scope, type, type);
+	if (this.thenStatement != null)
+		this.thenStatement.resolve(scope);
+	if (this.elseStatement != null)
+		this.elseStatement.resolve(scope);
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		this.condition.traverse(visitor, blockScope);
+		if (this.thenStatement != null)
+			this.thenStatement.traverse(visitor, blockScope);
+		if (this.elseStatement != null)
+			this.elseStatement.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
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
new file mode 100644
index 0000000..6011941
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ImportReference extends ASTNode {
+
+	public char[][] tokens;
+	public long[] sourcePositions; //each entry is using the code : (start<<32) + end
+	public int declarationEnd; // doesn't include an potential trailing comment
+	public int declarationSourceStart;
+	public int declarationSourceEnd;
+	public int modifiers; // 1.5 addition for static imports
+	public Annotation[] annotations;
+	// star end position
+	public int trailingStarPosition;
+
+	public ImportReference(
+			char[][] tokens,
+			long[] sourcePositions,
+			boolean onDemand,
+			int modifiers) {
+
+		this.tokens = tokens;
+		this.sourcePositions = sourcePositions;
+		if (onDemand) {
+			this.bits |= ASTNode.OnDemand;
+		}
+		this.sourceEnd = (int) (sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFF);
+		this.sourceStart = (int) (sourcePositions[0] >>> 32);
+		this.modifiers = modifiers;
+	}
+
+	public boolean isStatic() {
+		return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+	}
+
+	/**
+	 * @return char[][]
+	 */
+	public char[][] getImportName() {
+
+		return this.tokens;
+	}
+
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		return print(indent, output, true);
+	}
+
+	public StringBuffer print(int tab, StringBuffer output, boolean withOnDemand) {
+
+		/* when withOnDemand is false, only the name is printed */
+		for (int i = 0; i < this.tokens.length; i++) {
+			if (i > 0) output.append('.');
+			output.append(this.tokens[i]);
+		}
+		if (withOnDemand && ((this.bits & ASTNode.OnDemand) != 0)) {
+			output.append(".*"); //$NON-NLS-1$
+		}
+		return output;
+	}
+
+	public void traverse(ASTVisitor visitor, CompilationUnitScope scope) {
+		// annotations are traversed during the compilation unit traversal using a class scope
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
new file mode 100644
index 0000000..8a14ea4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+
+public class Initializer extends FieldDeclaration {
+
+	public Block block;
+	public int lastVisibleFieldID;
+	public int bodyStart;
+	public int bodyEnd;
+
+	public Initializer(Block block, int modifiers) {
+		this.block = block;
+		this.modifiers = modifiers;
+
+		if (block != null) {
+			this.declarationSourceStart = this.sourceStart = block.sourceStart;
+		}
+	}
+
+	public FlowInfo analyseCode(
+		MethodScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		if (this.block != null) {
+			return this.block.analyseCode(currentScope, flowContext, flowInfo);
+		}
+		return flowInfo;
+	}
+
+	/**
+	 * Code generation for a non-static initializer:
+	 *    standard block code gen
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+		if (this.block != null) this.block.generateCode(currentScope, codeStream);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
+	 */
+	public int getKind() {
+		return INITIALIZER;
+	}
+
+	public boolean isStatic() {
+
+		return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+	}
+
+	public void parseStatements(
+		Parser parser,
+		TypeDeclaration typeDeclaration,
+		CompilationUnitDeclaration unit) {
+
+		//fill up the method body with statement
+		parser.parse(this, typeDeclaration, unit);
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+
+		if (this.modifiers != 0) {
+			printIndent(indent, output);
+			printModifiers(this.modifiers, output);
+			if (this.annotations != null) {
+				printAnnotations(this.annotations, output);
+				output.append(' ');
+			}
+			output.append("{\n"); //$NON-NLS-1$
+			if (this.block != null) {
+				this.block.printBody(indent, output);
+			}
+			printIndent(indent, output).append('}');
+			return output;
+		} else if (this.block != null) {
+			this.block.printStatement(indent, output);
+		} else {
+			printIndent(indent, output).append("{}"); //$NON-NLS-1$
+		}
+		return output;
+	}
+
+	public void resolve(MethodScope scope) {
+
+		FieldBinding previousField = scope.initializedField;
+		int previousFieldID = scope.lastVisibleFieldID;
+		try {
+			scope.initializedField = null;
+			scope.lastVisibleFieldID = this.lastVisibleFieldID;
+			if (isStatic()) {
+				ReferenceBinding declaringType = scope.enclosingSourceType();
+				if (declaringType.isNestedType() && !declaringType.isStatic())
+					scope.problemReporter().innerTypesCannotDeclareStaticInitializers(
+						declaringType,
+						this);
+			}
+			if (this.block != null) this.block.resolve(scope);
+		} finally {
+		    scope.initializedField = previousField;
+			scope.lastVisibleFieldID = previousFieldID;
+		}
+	}
+
+	public void traverse(ASTVisitor visitor, MethodScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.block != null) this.block.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..a7e9e20
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class InstanceOfExpression extends OperatorExpression {
+
+	public Expression expression;
+	public TypeReference type;
+
+public InstanceOfExpression(Expression expression, TypeReference type) {
+	this.expression = expression;
+	this.type = type;
+	type.bits |= IgnoreRawTypeCheck; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=282141
+	this.bits |= INSTANCEOF << OperatorSHIFT;
+	this.sourceStart = expression.sourceStart;
+	this.sourceEnd = type.sourceEnd;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	LocalVariableBinding local = this.expression.localVariableBinding();
+	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
+		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo).
+			unconditionalInits();
+		FlowInfo initsWhenTrue = flowInfo.copy();
+		initsWhenTrue.markAsComparedEqualToNonNull(local);
+		flowContext.recordUsingNullReference(currentScope, local,
+				this.expression, FlowContext.CAN_ONLY_NULL | FlowContext.IN_INSTANCEOF, flowInfo);
+		// no impact upon enclosing try context
+		return FlowInfo.conditional(initsWhenTrue, flowInfo.copy());
+	}
+	if (this.expression instanceof Reference && currentScope.compilerOptions().enableSyntacticNullAnalysisForFields) {
+		FieldBinding field = ((Reference)this.expression).lastFieldBinding();
+		if (field != null && (field.type.tagBits & TagBits.IsBaseType) == 0) {
+			flowContext.recordNullCheckedFieldReference((Reference) this.expression, 1);
+		}
+	}
+	return this.expression.analyseCode(currentScope, flowContext, flowInfo).
+			unconditionalInits();
+}
+
+/**
+ * Code generation for instanceOfExpression
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+*/
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	this.expression.generateCode(currentScope, codeStream, true);
+	codeStream.instance_of(this.type, this.type.resolvedType);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else {
+		codeStream.pop();
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+	this.expression.printExpression(indent, output).append(" instanceof "); //$NON-NLS-1$
+	return this.type.print(0, output);
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	this.constant = Constant.NotAConstant;
+	TypeBinding expressionType = this.expression.resolveType(scope);
+	TypeBinding checkedType = this.type.resolveType(scope, true /* check bounds*/);
+	if (expressionType == null || checkedType == null)
+		return null;
+
+	if (!checkedType.isReifiable()) {
+		scope.problemReporter().illegalInstanceOfGenericType(checkedType, this);
+	} else if (checkedType.isValidBinding()) {
+		// if not a valid binding, an error has already been reported for unresolved type
+		if ((expressionType != TypeBinding.NULL && expressionType.isBaseType()) // disallow autoboxing
+				|| !checkCastTypesCompatibility(scope, checkedType, expressionType, null)) {
+			scope.problemReporter().notCompatibleTypesError(this, expressionType, checkedType);
+		}
+	}
+	return this.resolvedType = TypeBinding.BOOLEAN;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope,TypeBinding)
+ */
+public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
+	// null is not instanceof Type, recognize direct scenario
+	if (this.expression.resolvedType != TypeBinding.NULL)
+		scope.problemReporter().unnecessaryInstanceof(this, castType);
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.expression.traverse(visitor, scope);
+		this.type.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
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
new file mode 100644
index 0000000..2fa4070
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IntConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+public class IntLiteral extends NumberLiteral {
+	private static final char[] HEXA_MIN_VALUE        = "0x80000000".toCharArray(); //$NON-NLS-1$
+	private static final char[] HEXA_MINUS_ONE_VALUE  = "0xffffffff".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MIN_VALUE       = "020000000000".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MINUS_ONE_VALUE = "037777777777".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MIN_VALUE     = "2147483648".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MAX_VALUE     = "2147483647".toCharArray(); //$NON-NLS-1$
+
+	private char[] reducedForm; // no underscores
+
+	public int value;
+
+	//used for ++ and --
+	public static final IntLiteral One = new IntLiteral(new char[]{'1'}, null, 0, 0, 1, IntConstant.fromValue(1));
+
+	public static IntLiteral buildIntLiteral(char[] token, int s, int e) {
+		// remove '_' and prefix '0' first
+		char[] intReducedToken = removePrefixZerosAndUnderscores(token, false);
+		switch(intReducedToken.length) {
+			case 10 :
+				// 0x80000000
+				if (CharOperation.equals(intReducedToken, HEXA_MIN_VALUE)) {
+					return new IntLiteralMinValue(token, intReducedToken != token ? intReducedToken : null, s, e);
+				}
+				break;
+			case 12 :
+				// 020000000000
+				if (CharOperation.equals(intReducedToken, OCTAL_MIN_VALUE)) {
+					return new IntLiteralMinValue(token, intReducedToken != token ? intReducedToken : null, s, e);
+				}
+				break;
+		}
+		return new IntLiteral(token, intReducedToken != token ? intReducedToken : null, s, e);
+	}
+IntLiteral(char[] token, char[] reducedForm, int start, int end) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
+}
+IntLiteral(char[] token, char[] reducedForm, int start, int end, int value, Constant constant) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
+	this.value = value;
+	this.constant = constant;
+}
+public void computeConstant() {
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	int tokenLength = token.length;
+	int radix = 10;
+	int j = 0;
+	if (token[0] == '0') {
+		if (tokenLength == 1) {
+			this.constant = IntConstant.fromValue(0);
+			return;
+		}
+		if ((token[1] == 'x') || (token[1] == 'X')) {
+			radix = 16;
+			j = 2;
+		} else if ((token[1] == 'b') || (token[1] == 'B')) {
+			radix = 2;
+			j = 2;
+		} else {
+			radix = 8;
+			j = 1;
+		}
+	}
+	switch(radix) {
+		case 2 :
+			if ((tokenLength - 2) > 32) {
+				// remove 0b or 0B
+				return; /*constant stays null*/
+			}
+			computeValue(token, tokenLength, radix, j);
+			return;
+		case 16 :
+			if (tokenLength <= 10) {
+				if (CharOperation.equals(token, HEXA_MINUS_ONE_VALUE)) {
+					this.constant = IntConstant.fromValue(-1);
+					return;
+				}
+				computeValue(token, tokenLength, radix, j);
+				return;
+			}
+			break;
+		case 10 :
+			if (tokenLength > DECIMAL_MAX_VALUE.length
+					|| (tokenLength == DECIMAL_MAX_VALUE.length
+							&& CharOperation.compareTo(token, DECIMAL_MAX_VALUE) > 0)) {
+				return; /*constant stays null*/
+			}
+			computeValue(token, tokenLength, radix, j);
+			break;
+		case 8 :
+			if (tokenLength <= 12) {
+				if (tokenLength == 12 && token[j] > '4') {
+					return; /*constant stays null*/
+				}
+				if (CharOperation.equals(token, OCTAL_MINUS_ONE_VALUE)) {
+					this.constant = IntConstant.fromValue(-1);
+					return;
+				}
+				computeValue(token, tokenLength, radix, j);
+				return;
+			}
+			break;
+	}
+}
+private void computeValue(char[] token, int tokenLength, int radix, int j) {
+	int digitValue;
+	int computedValue = 0;
+	while (j < tokenLength) {
+		if ((digitValue = ScannerHelper.digit(token[j++],radix)) < 0) {
+			return; /*constant stays null*/
+		}
+		computedValue = (computedValue * radix) + digitValue ;
+	}
+	this.constant = IntConstant.fromValue(computedValue);
+}
+public IntLiteral convertToMinValue() {
+	if (((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+		return this;
+	}
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	switch(token.length) {
+		case 10 :
+			// 2147483648
+			if (CharOperation.equals(token, DECIMAL_MIN_VALUE)) {
+				return new IntLiteralMinValue(this.source, this.reducedForm, this.sourceStart, this.sourceEnd);
+			}
+			break;
+	}
+	return this;
+}
+/**
+ * Code generation for long literal
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.INT;
+}
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
new file mode 100644
index 0000000..f175fe7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.impl.*;
+
+public class IntLiteralMinValue extends IntLiteral {
+
+	final static char[] CharValue = new char[]{'-','2','1','4','7','4','8','3','6','4','8'};
+
+public IntLiteralMinValue(char[] token, char[] reducedToken, int start, int end) {
+	super(token, reducedToken, start, end, Integer.MIN_VALUE, IntConstant.fromValue(Integer.MIN_VALUE));
+}
+
+public void computeConstant(){
+	/*precomputed at creation time*/ }
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
new file mode 100644
index 0000000..f4020cb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntersectionCastTypeReference.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class IntersectionCastTypeReference extends TypeReference {
+	public TypeReference[] typeReferences;
+
+	public IntersectionCastTypeReference(TypeReference[] typeReferences) {
+		this.typeReferences = typeReferences;
+		this.sourceStart = typeReferences[0].sourceStart;
+		int length = typeReferences.length;
+		this.sourceEnd = typeReferences[length - 1].sourceEnd;
+	}
+
+	public TypeReference copyDims(int dim) {
+		throw new UnsupportedOperationException(); // no syntax for this.
+	}
+	
+	public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions) {
+		throw new UnsupportedOperationException(); // no syntax for this.
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getLastToken()
+	 */
+	public char[] getLastToken() {
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding getTypeBinding(Scope scope) {
+		return null; // not supported here - combined with resolveType(...)
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+
+		int length = this.typeReferences.length;
+		ReferenceBinding[] intersectingTypes = new ReferenceBinding[length];
+		boolean hasError = false;
+		
+		for (int i = 0; i < length; i++) {
+			final TypeReference typeReference = this.typeReferences[i];
+			TypeBinding type = typeReference.resolveType(scope, checkBounds);
+			if (type == null || ((type.tagBits & TagBits.HasMissingType) != 0)) {
+				hasError = true;
+				continue;
+			}
+			if (i == 0) {
+				if (type.isBaseType()) { // rejected in grammar for i > 0
+					scope.problemReporter().onlyReferenceTypesInIntersectionCast(typeReference);
+					hasError = true;
+					continue;
+				}
+				if (type.isArrayType()) { // javac rejects the pedantic cast: (X[] & Serializable & Cloneable) new X[0], what is good for the goose ...
+					scope.problemReporter().illegalArrayTypeInIntersectionCast(typeReference);
+					hasError = true;
+					continue;
+				}
+			} else if (!type.isInterface()) {  // TODO: understand how annotations play here ...
+				scope.problemReporter().boundMustBeAnInterface(typeReference, type);
+				hasError = true;
+				continue;
+			}
+			for (int j = 0; j < i; j++) {
+				if (intersectingTypes[j] == type) {
+					scope.problemReporter().duplicateBoundInIntersectionCast(typeReference);
+					hasError = true;
+					continue;
+				}
+			}
+			intersectingTypes[i] = (ReferenceBinding) type;
+		}
+		if (hasError) {
+			return null;
+		}
+		return (this.resolvedType = scope.environment().createIntersectionCastType(intersectingTypes));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
+	 */
+	public char[][] getTypeName() {
+		// we need to keep a return value that is a char[][]
+		return this.typeReferences[0].getTypeName();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+			for (int i = 0; i < length; i++) {
+				this.typeReferences[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		throw new UnsupportedOperationException("Unexpected traversal request: IntersectionTypeReference in class scope"); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+		printIndent(indent, output);
+		for (int i = 0; i < length; i++) {
+			this.typeReferences[i].printExpression(0, output);
+			if (i != length - 1) {
+				output.append(" & "); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
new file mode 100644
index 0000000..9e05d89
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -0,0 +1,944 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+
+/**
+ * Node representing a structured Javadoc comment
+ */
+public class Javadoc extends ASTNode {
+
+	public JavadocSingleNameReference[] paramReferences; // @param
+	public JavadocSingleTypeReference[] paramTypeParameters; // @param
+	public TypeReference[] exceptionReferences; // @throws, @exception
+	public JavadocReturnStatement returnStatement; // @return
+	public Expression[] seeReferences; // @see
+	public long[] inheritedPositions = null;
+	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+	// Store param references for tag with invalid syntax
+	public JavadocSingleNameReference[] invalidParameters; // @param
+	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399
+	// Store value tag positions
+	public long valuePositions = -1;
+
+	public Javadoc(int sourceStart, int sourceEnd) {
+		this.sourceStart = sourceStart;
+		this.sourceEnd = sourceEnd;
+		this.bits |= ASTNode.ResolveJavadoc;
+	}
+	/**
+	 * Returns whether a type can be seen at a given visibility level or not.
+	 *
+	 * @param visibility Level of visiblity allowed to see references
+	 * @param modifiers modifiers of java element to be seen
+	 * @return true if the type can be seen, false otherwise
+	 */
+	boolean canBeSeen(int visibility, int modifiers) {
+		if (modifiers < 0) return true;
+		switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) {
+			case ClassFileConstants.AccPublic :
+				return true;
+			case ClassFileConstants.AccProtected:
+				return (visibility != ClassFileConstants.AccPublic);
+			case ClassFileConstants.AccDefault:
+				return (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate);
+			case ClassFileConstants.AccPrivate:
+				return (visibility == ClassFileConstants.AccPrivate);
+		}
+		return true;
+	}
+
+	/*
+	 * Search node with a given staring position in javadoc objects arrays.
+	 */
+	public ASTNode getNodeStartingAt(int start) {
+		int length = 0;
+		// parameters array
+		if (this.paramReferences != null) {
+			length = this.paramReferences.length;
+			for (int i=0; i<length; i++) {
+				JavadocSingleNameReference param = this.paramReferences[i];
+				if (param.sourceStart==start) {
+					return param;
+				}
+			}
+		}
+		// array of invalid syntax tags parameters
+		if (this.invalidParameters != null) {
+			length = this.invalidParameters.length;
+			for (int i=0; i<length; i++) {
+				JavadocSingleNameReference param = this.invalidParameters[i];
+				if (param.sourceStart==start) {
+					return param;
+				}
+			}
+		}
+		// type parameters array
+		if (this.paramTypeParameters != null) {
+			length = this.paramTypeParameters.length;
+			for (int i=0; i<length; i++) {
+				JavadocSingleTypeReference param = this.paramTypeParameters[i];
+				if (param.sourceStart==start) {
+					return param;
+				}
+			}
+		}
+		// thrown exception array
+		if (this.exceptionReferences != null) {
+			length = this.exceptionReferences.length;
+			for (int i=0; i<length; i++) {
+				TypeReference typeRef = this.exceptionReferences[i];
+				if (typeRef.sourceStart==start) {
+					return typeRef;
+				}
+			}
+		}
+		// references array
+		if (this.seeReferences != null) {
+			length = this.seeReferences.length;
+			for (int i=0; i<length; i++) {
+				org.eclipse.jdt.internal.compiler.ast.Expression expression = this.seeReferences[i];
+				if (expression.sourceStart==start) {
+					return expression;
+				} else if (expression instanceof JavadocAllocationExpression) {
+					JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i];
+					// if binding is valid then look at arguments
+					if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) {
+						if (allocationExpr.arguments != null) {
+							for (int j=0, l=allocationExpr.arguments.length; j<l; j++) {
+								if (allocationExpr.arguments[j].sourceStart == start) {
+									return allocationExpr.arguments[j];
+								}
+							}
+						}
+					}
+				} else if (expression instanceof JavadocMessageSend) {
+					JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i];
+					// if binding is valid then look at arguments
+					if (messageSend.binding != null && messageSend.binding.isValidBinding()) {
+						if (messageSend.arguments != null) {
+							for (int j=0, l=messageSend.arguments.length; j<l; j++) {
+								if (messageSend.arguments[j].sourceStart == start) {
+									return messageSend.arguments[j];
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer print(int indent, StringBuffer output) {
+		printIndent(indent, output).append("/**\n"); //$NON-NLS-1$
+		if (this.paramReferences != null) {
+			for (int i = 0, length = this.paramReferences.length; i < length; i++) {
+				printIndent(indent + 1, output).append(" * @param "); //$NON-NLS-1$
+				this.paramReferences[i].print(indent, output).append('\n');
+			}
+		}
+		if (this.paramTypeParameters != null) {
+			for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
+				printIndent(indent + 1, output).append(" * @param <"); //$NON-NLS-1$
+				this.paramTypeParameters[i].print(indent, output).append(">\n"); //$NON-NLS-1$
+			}
+		}
+		if (this.returnStatement != null) {
+			printIndent(indent + 1, output).append(" * @"); //$NON-NLS-1$
+			this.returnStatement.print(indent, output).append('\n');
+		}
+		if (this.exceptionReferences != null) {
+			for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
+				printIndent(indent + 1, output).append(" * @throws "); //$NON-NLS-1$
+				this.exceptionReferences[i].print(indent, output).append('\n');
+			}
+		}
+		if (this.seeReferences != null) {
+			for (int i = 0, length = this.seeReferences.length; i < length; i++) {
+				printIndent(indent + 1, output).append(" * @see "); //$NON-NLS-1$
+				this.seeReferences[i].print(indent, output).append('\n');
+			}
+		}
+		printIndent(indent, output).append(" */\n"); //$NON-NLS-1$
+		return output;
+	}
+
+	/*
+	 * Resolve type javadoc
+	 */
+	public void resolve(ClassScope scope) {
+		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
+			return;
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc tag cannot
+		// be used in the documentation comment for a class or interface.
+		if (this.inheritedPositions != null) {
+			int length = this.inheritedPositions.length;
+			for (int i = 0; i < length; ++i) {
+				int start = (int) (this.inheritedPositions[i] >>> 32);
+				int end = (int) this.inheritedPositions[i];
+				scope.problemReporter().javadocUnexpectedTag(start, end);
+			}
+		}
+		// @param tags
+		int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
+		for (int i = 0; i < paramTagsSize; i++) {
+			JavadocSingleNameReference param = this.paramReferences[i];
+			scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
+		}
+		resolveTypeParameterTags(scope, true);
+
+		// @return tags
+		if (this.returnStatement != null) {
+			scope.problemReporter().javadocUnexpectedTag(this.returnStatement.sourceStart, this.returnStatement.sourceEnd);
+		}
+
+		// @throws/@exception tags
+		int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length;
+		for (int i = 0; i < throwsTagsLength; i++) {
+			TypeReference typeRef = this.exceptionReferences[i];
+			int start, end;
+			if (typeRef instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
+				start = singleRef.tagSourceStart;
+				end = singleRef.tagSourceEnd;
+			} else if (typeRef instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) typeRef;
+				start = qualifiedRef.tagSourceStart;
+				end = qualifiedRef.tagSourceEnd;
+			} else {
+				start = typeRef.sourceStart;
+				end = typeRef.sourceEnd;
+			}
+			scope.problemReporter().javadocUnexpectedTag(start, end);
+		}
+
+		// @see tags
+		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
+		for (int i = 0; i < seeTagsLength; i++) {
+			resolveReference(this.seeReferences[i], scope);
+		}
+
+		// @value tag
+		boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		if (!source15 && this.valuePositions != -1) {
+			scope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions);
+		}
+	}
+
+	/*
+	 * Resolve compilation unit javadoc
+	 */
+	public void resolve(CompilationUnitScope unitScope) {
+		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
+			return;
+		}
+		// Do nothing - This is to mimic the SDK's javadoc tool behavior, which neither
+		// sanity checks nor generates documentation using comments at the CU scope 
+		// (unless the unit happens to be package-info.java - in which case we don't come here.) 
+	}
+
+	/*
+	 * Resolve method javadoc
+	 */
+	public void resolve(MethodScope methScope) {
+		if ((this.bits & ASTNode.ResolveJavadoc) == 0) {
+			return;
+		}
+		// get method declaration
+		AbstractMethodDeclaration methDecl = methScope.referenceMethod();
+		boolean overriding = methDecl == null /* field declaration */ || methDecl.binding == null /* compiler error */
+			? false :
+			!methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) != 0);
+
+		// @see tags
+		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
+		boolean superRef = false;
+		for (int i = 0; i < seeTagsLength; i++) {
+
+			// Resolve reference
+			resolveReference(this.seeReferences[i], methScope);
+
+			// see whether we can have a super reference
+			if (methDecl != null && !superRef) {
+				if (!methDecl.isConstructor()) {
+					if (overriding && this.seeReferences[i] instanceof JavadocMessageSend) {
+						JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i];
+						// if binding is valid then look if we have a reference to an overriden method/constructor
+						if (messageSend.binding != null && messageSend.binding.isValidBinding() && messageSend.actualReceiverType instanceof ReferenceBinding) {
+							ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
+							TypeBinding superType = methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(methodReceiverType);
+							if (superType != null && superType.original() != methDecl.binding.declaringClass && CharOperation.equals(messageSend.selector, methDecl.selector)) {
+								if (methScope.environment().methodVerifier().doesMethodOverride(methDecl.binding, messageSend.binding.original())) {
+									superRef = true;
+								}
+							}
+						}
+					}
+				} else if (this.seeReferences[i] instanceof JavadocAllocationExpression) {
+					JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i];
+					// if binding is valid then look if we have a reference to an overriden method/constructor
+					if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) {
+						ReferenceBinding allocType = (ReferenceBinding) allocationExpr.resolvedType.original();
+						ReferenceBinding superType = (ReferenceBinding) methDecl.binding.declaringClass.findSuperTypeOriginatingFrom(allocType);
+						if (superType != null && superType.original() != methDecl.binding.declaringClass) {
+							MethodBinding superConstructor = methScope.getConstructor(superType, methDecl.binding.parameters, allocationExpr);
+							if (superConstructor.isValidBinding() && superConstructor.original() == allocationExpr.binding.original()) {
+								if (superConstructor.areParametersEqual(methDecl.binding)) {
+									superRef = true;
+								}
+							}
+						}						
+					}
+				}
+			}
+		}
+
+		// Look at @Override annotations
+		if (!superRef && methDecl != null && methDecl.annotations != null) {
+			int length = methDecl.annotations.length;
+			for (int i=0; i<length && !superRef; i++) {
+				superRef = (methDecl.binding.tagBits & TagBits.AnnotationOverride) != 0;
+			}
+		}
+
+		// Store if a reference exists to an overriden method/constructor or the method is in a local type,
+		boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != null) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
+		if (!overriding && this.inheritedPositions != null) {
+			int length = this.inheritedPositions.length;
+			for (int i = 0; i < length; ++i) {
+				int start = (int) (this.inheritedPositions[i] >>> 32);
+				int end = (int) this.inheritedPositions[i];
+				methScope.problemReporter().javadocUnexpectedTag(start, end);
+			}
+		}
+
+		// @param tags
+		CompilerOptions compilerOptions = methScope.compilerOptions();
+		resolveParamTags(methScope, reportMissing, compilerOptions.reportUnusedParameterIncludeDocCommentReference /* considerParamRefAsUsage*/);
+		resolveTypeParameterTags(methScope, reportMissing && compilerOptions.reportMissingJavadocTagsMethodTypeParameters);
+
+		// @return tags
+		if (this.returnStatement == null) {
+			if (reportMissing && methDecl != null) {
+				if (methDecl.isMethod()) {
+					MethodDeclaration meth = (MethodDeclaration) methDecl;
+					if (meth.binding.returnType != TypeBinding.VOID) {
+						// method with return should have @return tag
+						methScope.problemReporter().javadocMissingReturnTag(meth.returnType.sourceStart, meth.returnType.sourceEnd, methDecl.binding.modifiers);
+					}
+				}
+			}
+		} else {
+			this.returnStatement.resolve(methScope);
+		}
+
+		// @throws/@exception tags
+		resolveThrowsTags(methScope, reportMissing);
+
+		// @value tag
+		boolean source15 = compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5;
+		if (!source15 && methDecl != null && this.valuePositions != -1) {
+			methScope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions);
+		}
+
+		// Resolve param tags with invalid syntax
+		int length = this.invalidParameters == null ? 0 : this.invalidParameters.length;
+		for (int i = 0; i < length; i++) {
+			this.invalidParameters[i].resolve(methScope, false, false);
+		}
+	}
+
+	private void resolveReference(Expression reference, Scope scope) {
+
+		// Perform resolve
+		int problemCount = scope.referenceContext().compilationResult().problemCount;
+		switch (scope.kind) {
+			case Scope.METHOD_SCOPE:
+				reference.resolveType((MethodScope)scope);
+				break;
+			case Scope.CLASS_SCOPE:
+				reference.resolveType((ClassScope)scope);
+				break;
+		}
+		boolean hasProblems = scope.referenceContext().compilationResult().problemCount > problemCount;
+
+		// Verify field references
+		boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		int scopeModifiers = -1;
+		if (reference instanceof JavadocFieldReference) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
+
+			// Verify if this is a method reference
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51911
+			if (fieldRef.methodBinding != null) {
+				// cannot refer to method for @value tag
+				if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) {
+					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
+				}
+				else if (fieldRef.actualReceiverType != null) {
+					if (scope.enclosingSourceType().isCompatibleWith(fieldRef.actualReceiverType)) {
+						fieldRef.bits |= ASTNode.SuperAccess;
+					}
+					ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
+					if (CharOperation.equals(resolvedType.sourceName(), fieldRef.token)) {
+						fieldRef.methodBinding = scope.getConstructor(resolvedType, Binding.NO_TYPES, fieldRef);
+					} else {
+						fieldRef.methodBinding = scope.findMethod(resolvedType, fieldRef.token, Binding.NO_TYPES, fieldRef);
+					}
+				}
+			}
+
+			// Verify whether field ref should be static or not (for @value tags)
+			else if (source15 && fieldRef.binding != null && fieldRef.binding.isValidBinding()) {
+				if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE && !fieldRef.binding.isStatic()) {
+					if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+					scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers);
+				}
+			}
+
+			// Verify type references
+			if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.actualReceiverType instanceof ReferenceBinding) {
+				ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.actualReceiverType;
+				verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers);
+			}
+
+			// That's it for field references
+			return;
+		}
+
+		// Verify type references
+		if (!hasProblems && (reference instanceof JavadocSingleTypeReference || reference instanceof JavadocQualifiedTypeReference) && reference.resolvedType instanceof ReferenceBinding) {
+			ReferenceBinding resolvedType = (ReferenceBinding) reference.resolvedType;
+			verifyTypeReference(reference, reference, scope, source15, resolvedType, resolvedType.modifiers);
+		}
+
+		// Verify that message reference are not used for @value tags
+		if (reference instanceof JavadocMessageSend) {
+			JavadocMessageSend msgSend = (JavadocMessageSend) reference;
+
+			// tag value
+			if (source15 && msgSend.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { // cannot refer to method for @value tag
+				if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+				scope.problemReporter().javadocInvalidValueReference(msgSend.sourceStart, msgSend.sourceEnd, scopeModifiers);
+			}
+
+			// Verify type references
+			if (!hasProblems && msgSend.binding != null && msgSend.binding.isValidBinding() && msgSend.actualReceiverType instanceof ReferenceBinding) {
+				ReferenceBinding resolvedType = (ReferenceBinding) msgSend.actualReceiverType;
+				verifyTypeReference(msgSend, msgSend.receiver, scope, source15, resolvedType, msgSend.binding.modifiers);
+			}
+		}
+
+		// Verify that constructor reference are not used for @value tags
+		else if (reference instanceof JavadocAllocationExpression) {
+			JavadocAllocationExpression alloc = (JavadocAllocationExpression) reference;
+
+			// tag value
+			if (source15 && alloc.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { // cannot refer to method for @value tag
+				if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+				scope.problemReporter().javadocInvalidValueReference(alloc.sourceStart, alloc.sourceEnd, scopeModifiers);
+			}
+
+			// Verify type references
+			if (!hasProblems && alloc.binding != null && alloc.binding.isValidBinding() && alloc.resolvedType instanceof ReferenceBinding) {
+				ReferenceBinding resolvedType = (ReferenceBinding) alloc.resolvedType;
+				verifyTypeReference(alloc, alloc.type, scope, source15, resolvedType, alloc.binding.modifiers);
+			}
+		}
+
+		// Verify that there's no type variable reference
+		// (javadoc does not accept them and this is not a referenced bug or requested enhancement)
+		if (reference.resolvedType != null && reference.resolvedType.isTypeVariable()) {
+			scope.problemReporter().javadocInvalidReference(reference.sourceStart, reference.sourceEnd);
+		}
+	}
+
+	/*
+	 * Resolve @param tags while method scope
+	 */
+	private void resolveParamTags(MethodScope scope, boolean reportMissing, boolean considerParamRefAsUsage) {
+		AbstractMethodDeclaration methodDecl = scope.referenceMethod();
+		int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
+
+		// If no referenced method (field initializer for example) then report a problem for each param tag
+		if (methodDecl == null) {
+			for (int i = 0; i < paramTagsSize; i++) {
+				JavadocSingleNameReference param = this.paramReferences[i];
+				scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
+			}
+			return;
+		}
+
+		// If no param tags then report a problem for each method argument
+		int argumentsSize = methodDecl.arguments == null ? 0 : methodDecl.arguments.length;
+		if (paramTagsSize == 0) {
+			if (reportMissing) {
+				for (int i = 0; i < argumentsSize; i++) {
+					Argument arg = methodDecl.arguments[i];
+					scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers);
+				}
+			}
+		} else {
+			LocalVariableBinding[] bindings = new LocalVariableBinding[paramTagsSize];
+			int maxBindings = 0;
+
+			// Scan all @param tags
+			for (int i = 0; i < paramTagsSize; i++) {
+				JavadocSingleNameReference param = this.paramReferences[i];
+				param.resolve(scope, true, considerParamRefAsUsage);
+				if (param.binding != null && param.binding.isValidBinding()) {
+					// Verify duplicated tags
+					boolean found = false;
+					for (int j = 0; j < maxBindings && !found; j++) {
+						if (bindings[j] == param.binding) {
+							scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, methodDecl.binding.modifiers);
+							found = true;
+						}
+					}
+					if (!found) {
+						bindings[maxBindings++] = (LocalVariableBinding) param.binding;
+					}
+				}
+			}
+
+			// Look for undocumented arguments
+			if (reportMissing) {
+				for (int i = 0; i < argumentsSize; i++) {
+					Argument arg = methodDecl.arguments[i];
+					boolean found = false;
+					for (int j = 0; j < maxBindings && !found; j++) {
+						LocalVariableBinding binding = bindings[j];
+						if (arg.binding == binding) {
+							found = true;
+						}
+					}
+					if (!found) {
+						scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers);
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * Resolve @param tags for type parameters
+	 */
+	private void resolveTypeParameterTags(Scope scope, boolean reportMissing) {
+		int paramTypeParamLength = this.paramTypeParameters == null ? 0 : this.paramTypeParameters.length;
+
+		// Get declaration infos
+		TypeParameter[] parameters = null;
+		TypeVariableBinding[] typeVariables = null;
+		int modifiers = -1;
+		switch (scope.kind) {
+			case Scope.METHOD_SCOPE:
+				AbstractMethodDeclaration methodDeclaration = ((MethodScope)scope).referenceMethod();
+				// If no referenced method (field initializer for example) then report a problem for each param tag
+				if (methodDeclaration == null) {
+					for (int i = 0; i < paramTypeParamLength; i++) {
+						JavadocSingleTypeReference param = this.paramTypeParameters[i];
+						scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
+					}
+					return;
+				}
+				parameters = methodDeclaration.typeParameters();
+				typeVariables = methodDeclaration.binding.typeVariables;
+				modifiers = methodDeclaration.binding.modifiers;
+				break;
+			case Scope.CLASS_SCOPE:
+				TypeDeclaration typeDeclaration = ((ClassScope) scope).referenceContext;
+				parameters = typeDeclaration.typeParameters;
+				typeVariables = typeDeclaration.binding.typeVariables;
+				modifiers = typeDeclaration.binding.modifiers;
+				break;
+		}
+
+		// If no type variables then report a problem for each param type parameter tag
+		if (typeVariables == null || typeVariables.length == 0) {
+			for (int i = 0; i < paramTypeParamLength; i++) {
+				JavadocSingleTypeReference param = this.paramTypeParameters[i];
+				scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
+			}
+			return;
+		}
+
+		// If no param tags then report a problem for each declaration type parameter
+		if (parameters != null) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, avoid secondary errors when <= 1.4 
+			reportMissing = reportMissing && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+			int typeParametersLength = parameters.length;
+			if (paramTypeParamLength == 0) {
+				if (reportMissing) {
+					for (int i = 0, l=typeParametersLength; i<l; i++) {
+						scope.problemReporter().javadocMissingParamTag(parameters[i].name, parameters[i].sourceStart, parameters[i].sourceEnd, modifiers);
+					}
+				}
+
+			// Otherwise verify that all param tags match type parameters
+			} else if (typeVariables.length == typeParametersLength) {
+				TypeVariableBinding[] bindings = new TypeVariableBinding[paramTypeParamLength];
+
+				// Scan all @param tags
+				for (int i = 0; i < paramTypeParamLength; i++) {
+					JavadocSingleTypeReference param = this.paramTypeParameters[i];
+					TypeBinding paramBindind = param.internalResolveType(scope);
+					if (paramBindind != null && paramBindind.isValidBinding()) {
+						if (paramBindind.isTypeVariable()) {
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397888
+							if (scope.compilerOptions().reportUnusedParameterIncludeDocCommentReference) {
+								TypeVariableBinding typeVariableBinding = (TypeVariableBinding) paramBindind;
+								typeVariableBinding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+							}
+							// Verify duplicated tags
+							boolean duplicate = false;
+							for (int j = 0; j < i && !duplicate; j++) {
+								if (bindings[j] == param.resolvedType) {
+									scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers);
+									duplicate = true;
+								}
+							}
+							if (!duplicate) {
+								bindings[i] = (TypeVariableBinding) param.resolvedType;
+							}
+						} else {
+							scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
+						}
+					}
+				}
+
+				// Look for undocumented type parameters
+				for (int i = 0; i < typeParametersLength; i++) {
+					TypeParameter parameter = parameters[i];
+					boolean found = false;
+					for (int j = 0; j < paramTypeParamLength && !found; j++) {
+						if (parameter.binding == bindings[j]) {
+							found = true;
+							bindings[j] = null;
+						}
+					}
+					if (!found && reportMissing) {
+						scope.problemReporter().javadocMissingParamTag(parameter.name, parameter.sourceStart, parameter.sourceEnd, modifiers);
+					}
+				}
+
+				// Report invalid param
+				for (int i=0; i<paramTypeParamLength; i++) {
+					if (bindings[i] != null) {
+						JavadocSingleTypeReference param = this.paramTypeParameters[i];
+						scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * Resolve @throws/@exception tags while method scope
+	 */
+	private void resolveThrowsTags(MethodScope methScope, boolean reportMissing) {
+		AbstractMethodDeclaration md = methScope.referenceMethod();
+		int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length;
+
+		// If no referenced method (field initializer for example) then report a problem for each throws tag
+		if (md == null) {
+			for (int i = 0; i < throwsTagsLength; i++) {
+				TypeReference typeRef = this.exceptionReferences[i];
+				int start = typeRef.sourceStart;
+				int end = typeRef.sourceEnd;
+				if (typeRef instanceof JavadocQualifiedTypeReference) {
+					start = ((JavadocQualifiedTypeReference) typeRef).tagSourceStart;
+					end = ((JavadocQualifiedTypeReference) typeRef).tagSourceEnd;
+				} else if (typeRef instanceof JavadocSingleTypeReference) {
+					start = ((JavadocSingleTypeReference) typeRef).tagSourceStart;
+					end = ((JavadocSingleTypeReference) typeRef).tagSourceEnd;
+				}
+				methScope.problemReporter().javadocUnexpectedTag(start, end);
+			}
+			return;
+		}
+
+		// If no throws tags then report a problem for each method thrown exception
+		int boundExceptionLength = (md.binding == null) ? 0 : md.binding.thrownExceptions.length;
+		int thrownExceptionLength = md.thrownExceptions == null ? 0 : md.thrownExceptions.length;
+		if (throwsTagsLength == 0) {
+			if (reportMissing) {
+				for (int i = 0; i < boundExceptionLength; i++) {
+					ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i];
+					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
+						int j=i;
+						while (j<thrownExceptionLength && exceptionBinding != md.thrownExceptions[j].resolvedType) j++;
+						if (j<thrownExceptionLength) {
+							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[j], md.binding.modifiers);
+						}
+					}
+				}
+			}
+		} else {
+			int maxRef = 0;
+			TypeReference[] typeReferences = new TypeReference[throwsTagsLength];
+
+			// Scan all @throws tags
+			for (int i = 0; i < throwsTagsLength; i++) {
+				TypeReference typeRef = this.exceptionReferences[i];
+				typeRef.resolve(methScope);
+				TypeBinding typeBinding = typeRef.resolvedType;
+
+				if (typeBinding != null && typeBinding.isValidBinding() && typeBinding.isClass()) {
+					// accept only valid class binding
+					typeReferences[maxRef++] = typeRef;
+				}
+			}
+
+			// Look for undocumented thrown exception
+			for (int i = 0; i < boundExceptionLength; i++) {
+				ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i];
+				if (exceptionBinding != null) exceptionBinding = (ReferenceBinding) exceptionBinding.erasure();
+				boolean found = false;
+				for (int j = 0; j < maxRef && !found; j++) {
+					if (typeReferences[j] != null) {
+						TypeBinding typeBinding = typeReferences[j].resolvedType;
+						if (exceptionBinding == typeBinding) {
+							found = true;
+							typeReferences[j] = null;
+						}
+					}
+				}
+				if (!found && reportMissing) {
+					if (exceptionBinding != null && exceptionBinding.isValidBinding()) { // flag only valid class name
+						int k=i;
+						while (k<thrownExceptionLength && exceptionBinding != md.thrownExceptions[k].resolvedType) k++;
+						if (k<thrownExceptionLength) {
+							methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[k], md.binding.modifiers);
+						}
+					}
+				}
+			}
+
+			// Verify additional @throws tags
+			for (int i = 0; i < maxRef; i++) {
+				TypeReference typeRef = typeReferences[i];
+				if (typeRef != null) {
+					boolean compatible = false;
+					// thrown exceptions subclasses are accepted
+					for (int j = 0; j<thrownExceptionLength && !compatible; j++) {
+						TypeBinding exceptionBinding = md.thrownExceptions[j].resolvedType;
+						if (exceptionBinding != null) {
+							compatible = typeRef.resolvedType.isCompatibleWith(exceptionBinding);
+						}
+					}
+
+					//  If not compatible only complain on unchecked exception
+					if (!compatible && !typeRef.resolvedType.isUncheckedException(false)) {
+						methScope.problemReporter().javadocInvalidThrowsClassName(typeRef, md.binding.modifiers);
+					}
+				}
+			}
+		}
+	}
+
+	private void verifyTypeReference(Expression reference, Expression typeReference, Scope scope, boolean source15, ReferenceBinding resolvedType, int modifiers) {
+		if (resolvedType.isValidBinding()) {
+			int scopeModifiers = -1;
+
+			// reference must have enough visibility to be used
+			if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, modifiers)) {
+				scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, reference.sourceEnd, scope, modifiers);
+				return;
+			}
+
+			// type reference must have enough visibility to be used
+			if (reference != typeReference) {
+				if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, resolvedType.modifiers)) {
+					scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, typeReference.sourceEnd, scope, resolvedType.modifiers);
+					return;
+				}
+			}
+
+			// member types
+			if (resolvedType.isMemberType()) {
+				ReferenceBinding topLevelType = resolvedType;
+				// rebuild and store (in reverse order) compound name to handle embedded inner class
+				int packageLength = topLevelType.fPackage.compoundName.length;
+				int depth = resolvedType.depth();
+				int idx = depth + packageLength;
+				char[][] computedCompoundName = new char[idx+1][];
+				computedCompoundName[idx] = topLevelType.sourceName;
+				while (topLevelType.enclosingType() != null) {
+					topLevelType = topLevelType.enclosingType();
+					computedCompoundName[--idx] = topLevelType.sourceName;
+				}
+
+				// add package information
+				for (int i = packageLength; --i >= 0;) {
+					computedCompoundName[--idx] = topLevelType.fPackage.compoundName[i];
+				}
+
+				ClassScope topLevelScope = scope.classScope();
+				// when scope is not on compilation unit type, then inner class may not be visible...
+				if (topLevelScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ||
+					!CharOperation.equals(topLevelType.sourceName, topLevelScope.referenceContext.name)) {
+					topLevelScope = topLevelScope.outerMostClassScope();
+					if (typeReference instanceof JavadocSingleTypeReference) {
+						// inner class single reference can only be done in same unit
+						if ((!source15 && depth == 1) || topLevelType != topLevelScope.referenceContext.binding) {
+							// search for corresponding import
+							boolean hasValidImport = false;
+							if (source15) {
+								CompilationUnitScope unitScope = topLevelScope.compilationUnitScope();
+								ImportBinding[] imports = unitScope.imports;
+								int length = imports == null ? 0 : imports.length;
+								mainLoop: for (int i=0; i<length; i++) {
+									char[][] compoundName = imports[i].compoundName;
+									int compoundNameLength = compoundName.length;
+									if ((imports[i].onDemand && compoundNameLength == computedCompoundName.length-1) 
+											|| (compoundNameLength == computedCompoundName.length)) {
+										for (int j = compoundNameLength; --j >= 0;) {
+											if (CharOperation.equals(imports[i].compoundName[j], computedCompoundName[j])) {
+												if (j == 0) {
+													hasValidImport = true;
+													ImportReference importReference = imports[i].reference;
+													if (importReference != null) {
+														importReference.bits |= ASTNode.Used;
+													}
+													break mainLoop;
+												}
+											} else {
+												break;
+											}
+										}
+									}
+								}
+								if (!hasValidImport) {
+									if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+									scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
+								}
+							} else {
+								if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+								scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
+								return;
+							}
+						}
+					}
+				}
+				if (typeReference instanceof JavadocQualifiedTypeReference && !scope.isDefinedInSameUnit(resolvedType)) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=222188
+					// partially qualified references from a different CU should be warned
+					char[][] typeRefName = ((JavadocQualifiedTypeReference) typeReference).getTypeName();
+					int skipLength = 0;
+					if (topLevelScope.getCurrentPackage() == resolvedType.getPackage()
+							&& typeRefName.length < computedCompoundName.length) {
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=221539: references can be partially qualified
+						// in same package and hence if the package name is not given, ignore package name check
+						skipLength = resolvedType.fPackage.compoundName.length;
+					}
+					boolean valid = true;
+					if (typeRefName.length == computedCompoundName.length - skipLength) {
+						checkQualification: for (int i = 0; i < typeRefName.length; i++) {
+							if (!CharOperation.equals(typeRefName[i], computedCompoundName[i + skipLength])) {
+								valid = false;
+								break checkQualification;
+							}
+						}
+					} else {
+						valid = false;
+					}
+					// report invalid reference
+					if (!valid) {
+						if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers();
+						scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers);
+						return;
+					}
+				}
+			}
+			/*
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=286918
+			 *
+			 * We are concerned only about the Single type references (i.e. without any package) If they are not in default package,
+			 * then report an error. References with qualified yet incorrect names would have already been taken care of.
+			 */
+			if (scope.referenceCompilationUnit().isPackageInfo() && typeReference instanceof JavadocSingleTypeReference) {
+				if (resolvedType.fPackage.compoundName.length > 0) {
+					scope.problemReporter().javadocInvalidReference(typeReference.sourceStart, typeReference.sourceEnd);
+					return; // Not really needed - just in case more code added in future
+				}
+			}
+		}
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.paramReferences != null) {
+				for (int i = 0, length = this.paramReferences.length; i < length; i++) {
+					this.paramReferences[i].traverse(visitor, scope);
+				}
+			}
+			if (this.paramTypeParameters != null) {
+				for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
+					this.paramTypeParameters[i].traverse(visitor, scope);
+				}
+			}
+			if (this.returnStatement != null) {
+				this.returnStatement.traverse(visitor, scope);
+			}
+			if (this.exceptionReferences != null) {
+				for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
+					this.exceptionReferences[i].traverse(visitor, scope);
+				}
+			}
+			if (this.seeReferences != null) {
+				for (int i = 0, length = this.seeReferences.length; i < length; i++) {
+					this.seeReferences[i].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.paramReferences != null) {
+				for (int i = 0, length = this.paramReferences.length; i < length; i++) {
+					this.paramReferences[i].traverse(visitor, scope);
+				}
+			}
+			if (this.paramTypeParameters != null) {
+				for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) {
+					this.paramTypeParameters[i].traverse(visitor, scope);
+				}
+			}
+			if (this.returnStatement != null) {
+				this.returnStatement.traverse(visitor, scope);
+			}
+			if (this.exceptionReferences != null) {
+				for (int i = 0, length = this.exceptionReferences.length; i < length; i++) {
+					this.exceptionReferences[i].traverse(visitor, scope);
+				}
+			}
+			if (this.seeReferences != null) {
+				for (int i = 0, length = this.seeReferences.length; i < length; i++) {
+					this.seeReferences[i].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
new file mode 100644
index 0000000..f270a49
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class JavadocAllocationExpression extends AllocationExpression {
+
+	public int tagSourceStart, tagSourceEnd;
+	public int tagValue, memberStart;
+	public char[][] qualification;
+
+	public JavadocAllocationExpression(int start, int end) {
+		this.sourceStart = start;
+		this.sourceEnd = end;
+		this.bits |= InsideJavadoc;
+	}
+	public JavadocAllocationExpression(long pos) {
+		this((int) (pos >>> 32), (int) pos);
+	}
+
+	TypeBinding internalResolveType(Scope scope) {
+
+		// Propagate the type checking to the arguments, and check if the constructor is defined.
+		this.constant = Constant.NotAConstant;
+		if (this.type == null) {
+			this.resolvedType = scope.enclosingSourceType();
+		} else if (scope.kind == Scope.CLASS_SCOPE) {
+			this.resolvedType = this.type.resolveType((ClassScope)scope);
+		} else {
+			this.resolvedType = this.type.resolveType((BlockScope)scope, true /* check bounds*/);
+		}
+
+		// buffering the arguments' types
+		TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+		boolean hasTypeVarArgs = false;
+		if (this.arguments != null) {
+			boolean argHasError = false;
+			int length = this.arguments.length;
+			argumentTypes = new TypeBinding[length];
+			for (int i = 0; i < length; i++) {
+				Expression argument = this.arguments[i];
+				if (scope.kind == Scope.CLASS_SCOPE) {
+					argumentTypes[i] = argument.resolveType((ClassScope)scope);
+				} else {
+					argumentTypes[i] = argument.resolveType((BlockScope)scope);
+				}
+				if (argumentTypes[i] == null) {
+					argHasError = true;
+				} else if (!hasTypeVarArgs) {
+					hasTypeVarArgs = argumentTypes[i].isTypeVariable();
+				}
+			}
+			if (argHasError) {
+				return null;
+			}
+		}
+
+		// check resolved type
+		if (this.resolvedType == null) {
+			return null;
+		}
+		this.resolvedType = scope.environment().convertToRawType(this.type.resolvedType,  true /*force the conversion of enclosing types*/);
+		SourceTypeBinding enclosingType = scope.enclosingSourceType();
+		if (enclosingType == null ? false : enclosingType.isCompatibleWith(this.resolvedType)) {
+			this.bits |= ASTNode.SuperAccess;
+		}
+
+		ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
+		this.binding = scope.getConstructor(allocationType, argumentTypes, this);
+		if (!this.binding.isValidBinding()) {
+			ReferenceBinding enclosingTypeBinding = allocationType;
+			MethodBinding contructorBinding = this.binding;
+			while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+				enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+				contructorBinding = scope.getConstructor(enclosingTypeBinding, argumentTypes, this);
+			}
+			if (contructorBinding.isValidBinding()) {
+				this.binding = contructorBinding;
+			}
+		}
+		if (!this.binding.isValidBinding()) {
+			// First try to search a method instead
+			MethodBinding methodBinding = scope.getMethod(this.resolvedType, this.resolvedType.sourceName(), argumentTypes, this);
+			if (methodBinding.isValidBinding()) {
+				this.binding = methodBinding;
+			} else {
+				if (this.binding.declaringClass == null) {
+					this.binding.declaringClass = allocationType;
+				}
+				scope.problemReporter().javadocInvalidConstructor(this, this.binding, scope.getDeclarationModifiers());
+			}
+			return this.resolvedType;
+		} else if (this.binding.isVarargs()) {
+			int length = argumentTypes.length;
+			if (!(this.binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
+				MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+				scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+			}
+		} else if (hasTypeVarArgs) {
+			MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+			scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+		} else if (this.binding instanceof ParameterizedMethodBinding) {
+			ParameterizedMethodBinding paramMethodBinding = (ParameterizedMethodBinding) this.binding;
+			if (paramMethodBinding.hasSubstitutedParameters()) {
+				int length = argumentTypes.length;
+				for (int i=0; i<length; i++) {
+					if (paramMethodBinding.parameters[i] != argumentTypes[i] &&
+							paramMethodBinding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+						MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+						scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+						break;
+					}
+				}
+			}
+		} else if (this.resolvedType.isMemberType()) {
+			int length = this.qualification.length;
+			if (length > 1) { // accept qualified member class constructor reference => see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=103304
+				ReferenceBinding enclosingTypeBinding = allocationType;
+				if (this.type instanceof JavadocQualifiedTypeReference && ((JavadocQualifiedTypeReference)this.type).tokens.length != length) {
+					scope.problemReporter().javadocInvalidMemberTypeQualification(this.memberStart+1, this.sourceEnd, scope.getDeclarationModifiers());
+				} else {
+					int idx = length;
+					while (idx > 0 && CharOperation.equals(this.qualification[--idx], enclosingTypeBinding.sourceName) && (enclosingTypeBinding = enclosingTypeBinding.enclosingType()) != null) {
+						// verify that each qualification token matches enclosing types
+					}
+					if (idx > 0 || enclosingTypeBinding != null) {
+						scope.problemReporter().javadocInvalidMemberTypeQualification(this.memberStart+1, this.sourceEnd, scope.getDeclarationModifiers());
+					}
+				}
+			}
+		}
+		if (isMethodUseDeprecated(this.binding, scope, true)) {
+			scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
+		}
+		return allocationType;
+	}
+
+	public boolean isSuperAccess() {
+		return (this.bits & ASTNode.SuperAccess) != 0;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		return internalResolveType(scope);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		return internalResolveType(scope);
+	}
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.typeArguments != null) {
+				for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+					this.typeArguments[i].traverse(visitor, scope);
+				}
+			}
+			if (this.type != null) { // enum constant scenario
+				this.type.traverse(visitor, scope);
+			}
+			if (this.arguments != null) {
+				for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
+					this.arguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.typeArguments != null) {
+				for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+					this.typeArguments[i].traverse(visitor, scope);
+				}
+			}
+			if (this.type != null) { // enum constant scenario
+				this.type.traverse(visitor, scope);
+			}
+			if (this.arguments != null) {
+				for (int i = 0, argumentsLength = this.arguments.length; i < argumentsLength; i++)
+					this.arguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
new file mode 100644
index 0000000..e46bf87
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class JavadocArgumentExpression extends Expression {
+	public char[] token;
+	public Argument argument;
+
+	public JavadocArgumentExpression(char[] name, int startPos, int endPos, TypeReference typeRef) {
+		this.token = name;
+		this.sourceStart = startPos;
+		this.sourceEnd = endPos;
+		long pos = (((long) startPos) << 32) + endPos;
+		this.argument = new Argument(name, pos, typeRef, ClassFileConstants.AccDefault);
+		this.bits |= InsideJavadoc;
+	}
+
+	/*
+	 * Resolves type on a Block or Class scope.
+	 */
+	private TypeBinding internalResolveType(Scope scope) {
+		this.constant = Constant.NotAConstant;
+		if (this.resolvedType != null) // is a shared type reference which was already resolved
+			return this.resolvedType.isValidBinding() ? this.resolvedType : null; // already reported error
+
+		if (this.argument != null) {
+			TypeReference typeRef = this.argument.type;
+			if (typeRef != null) {
+				this.resolvedType = typeRef.getTypeBinding(scope);
+				typeRef.resolvedType = this.resolvedType;
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=195374
+				// reproduce javadoc 1.3.1 / 1.4.2 behavior
+				if (this.resolvedType == null) {
+					return null;
+				}
+				if (typeRef instanceof SingleTypeReference &&
+						this.resolvedType.leafComponentType().enclosingType() != null &&
+						scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_4) {
+					scope.problemReporter().javadocInvalidMemberTypeQualification(this.sourceStart, this.sourceEnd, scope.getDeclarationModifiers());
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=228648
+					// do not return now but report unresolved reference as expected depending on compliance settings
+				} else if (typeRef instanceof QualifiedTypeReference) {
+					TypeBinding enclosingType = this.resolvedType.leafComponentType().enclosingType();
+					if (enclosingType != null) {
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=233187
+						// inner type references should be fully qualified
+						int compoundLength = 2;
+						while ((enclosingType = enclosingType.enclosingType()) != null) compoundLength++;
+						int typeNameLength = typeRef.getTypeName().length;
+						if (typeNameLength != compoundLength && typeNameLength != (compoundLength+this.resolvedType.getPackage().compoundName.length)) {
+							scope.problemReporter().javadocInvalidMemberTypeQualification(typeRef.sourceStart, typeRef.sourceEnd, scope.getDeclarationModifiers());
+						}
+					}
+				}
+				if (!this.resolvedType.isValidBinding()) {
+					scope.problemReporter().javadocInvalidType(typeRef, this.resolvedType, scope.getDeclarationModifiers());
+					return null;
+				}
+				if (isTypeUseDeprecated(this.resolvedType, scope)) {
+					scope.problemReporter().javadocDeprecatedType(this.resolvedType, typeRef, scope.getDeclarationModifiers());
+				}
+				return this.resolvedType = scope.environment().convertToRawType(this.resolvedType,  true /*force the conversion of enclosing types*/);
+			}
+		}
+		return null;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		if (this.argument == null) {
+			if (this.token != null) {
+				output.append(this.token);
+			}
+		}
+		else {
+			this.argument.print(indent, output);
+		}
+		return output;
+	}
+
+	public void resolve(BlockScope scope) {
+		if (this.argument != null) {
+			this.argument.resolve(scope);
+		}
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		return internalResolveType(scope);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		return internalResolveType(scope);
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+		if (visitor.visit(this, blockScope)) {
+			if (this.argument != null) {
+				this.argument.traverse(visitor, blockScope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope blockScope) {
+		if (visitor.visit(this, blockScope)) {
+			if (this.argument != null) {
+				this.argument.traverse(visitor, blockScope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java
new file mode 100644
index 0000000..43d4fba
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+
+public class JavadocArrayQualifiedTypeReference extends ArrayQualifiedTypeReference {
+
+	public int tagSourceStart, tagSourceEnd;
+
+	public JavadocArrayQualifiedTypeReference(JavadocQualifiedTypeReference typeRef, int dim) {
+		super(typeRef.tokens, dim, typeRef.sourcePositions);
+	}
+
+	protected void reportInvalidType(Scope scope) {
+		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+	}
+	protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java
new file mode 100644
index 0000000..9c2d921
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class JavadocArraySingleTypeReference extends ArrayTypeReference {
+
+	public JavadocArraySingleTypeReference(char[] name, int dim, long pos) {
+		super(name, dim, pos);
+		this.bits |= InsideJavadoc;
+	}
+
+	protected void reportInvalidType(Scope scope) {
+		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+	}
+	protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
new file mode 100644
index 0000000..b6bab94
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class JavadocFieldReference extends FieldReference {
+
+	public int tagSourceStart, tagSourceEnd;
+	public int tagValue;
+	public MethodBinding methodBinding;
+
+	public JavadocFieldReference(char[] source, long pos) {
+		super(source, pos);
+		this.bits |= InsideJavadoc;
+	}
+
+	/*
+	public Binding getBinding() {
+		if (this.methodBinding != null) {
+			return this.methodBinding;
+		}
+		return this.binding;
+	}
+	*/
+
+	/*
+	 * Resolves type on a Block or Class scope.
+	 */
+	protected TypeBinding internalResolveType(Scope scope) {
+
+		this.constant = Constant.NotAConstant;
+		if (this.receiver == null) {
+			this.actualReceiverType = scope.enclosingReceiverType();
+		} else if (scope.kind == Scope.CLASS_SCOPE) {
+			this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
+		} else {
+			this.actualReceiverType = this.receiver.resolveType((BlockScope)scope);
+		}
+		if (this.actualReceiverType == null) {
+			return null;
+		}
+
+		Binding fieldBinding = (this.receiver != null && this.receiver.isThis())
+			? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/)
+			: scope.getField(this.actualReceiverType, this.token, this);
+		if (!fieldBinding.isValidBinding()) {
+			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
+			switch (fieldBinding.problemId()) {
+				case ProblemReasons.NonStaticReferenceInConstructorInvocation:
+				case ProblemReasons.NonStaticReferenceInStaticContext:
+				case ProblemReasons.InheritedNameHidesEnclosingName :
+					FieldBinding closestMatch = ((ProblemFieldBinding)fieldBinding).closestMatch;
+					if (closestMatch != null) {
+						fieldBinding = closestMatch; // ignore problem if can reach target field through it
+					}
+			}
+		}
+		// When there's no valid field binding, try to resolve possible method reference without parenthesis
+		if (!fieldBinding.isValidBinding() || !(fieldBinding instanceof FieldBinding)) {
+			if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
+				// problem already got signaled on receiver, do not report secondary problem
+				return null;
+			}
+			if (this.actualReceiverType instanceof ReferenceBinding) {
+				ReferenceBinding refBinding = (ReferenceBinding) this.actualReceiverType;
+				char[] selector = this.token;
+				MethodBinding possibleMethod = null;
+				if (CharOperation.equals(this.actualReceiverType.sourceName(), selector)) {
+					possibleMethod = scope.getConstructor(refBinding, Binding.NO_TYPES, this);
+				} else {
+					possibleMethod = this.receiver.isThis()
+						? scope.getImplicitMethod(selector, Binding.NO_TYPES, this)
+						: scope.getMethod(refBinding, selector, Binding.NO_TYPES, this);
+				}
+				if (possibleMethod.isValidBinding()) {
+					this.methodBinding = possibleMethod;
+				} else {
+					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) possibleMethod;
+					if (problemMethodBinding.closestMatch == null) {
+						if (fieldBinding.isValidBinding()) {
+							// When the binding is not on a field (e.g. local variable), we need to create a problem field binding to report the correct problem
+							// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=254825
+							fieldBinding = new ProblemFieldBinding(refBinding, fieldBinding.readableName(), ProblemReasons.NotFound);
+						}
+						scope.problemReporter().javadocInvalidField(this, fieldBinding, this.actualReceiverType, scope.getDeclarationModifiers());
+					} else {
+						this.methodBinding = problemMethodBinding.closestMatch;
+					}
+				}
+			}
+			return null;
+		}
+		this.binding = (FieldBinding) fieldBinding;
+
+		if (isFieldUseDeprecated(this.binding, scope, this.bits)) {
+			scope.problemReporter().javadocDeprecatedField(this.binding, this, scope.getDeclarationModifiers());
+		}
+		return this.resolvedType = this.binding.type;
+	}
+
+	public boolean isSuperAccess() {
+		return (this.bits & ASTNode.SuperAccess) != 0;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		if (this.receiver != null) {
+			this.receiver.printExpression(0, output);
+		}
+		output.append('#').append(this.token);
+		return output;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		return internalResolveType(scope);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		return internalResolveType(scope);
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.receiver != null) {
+				this.receiver.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.receiver != null) {
+				this.receiver.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
new file mode 100644
index 0000000..7f985aa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class JavadocImplicitTypeReference extends TypeReference {
+
+	public char[] token;
+
+	public JavadocImplicitTypeReference(char[] name, int pos) {
+		super();
+		this.token = name;
+		this.sourceStart = pos;
+		this.sourceEnd = pos;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
+	 */
+	public TypeReference copyDims(int dim) {
+		return null;
+	}
+	
+	public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding getTypeBinding(Scope scope) {
+		this.constant = Constant.NotAConstant;
+		return this.resolvedType = scope.enclosingReceiverType();
+	}
+
+	public char[] getLastToken() {
+		return this.token;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
+	 */
+	public char[][] getTypeName() {
+		if (this.token != null) {
+			char[][] tokens = { this.token };
+			return tokens;
+		}
+		return null;
+	}
+	public boolean isThis() {
+		return true;
+	}
+
+	/*
+	 * Resolves type on a Block, Class or CompilationUnit scope.
+	 * We need to modify resoling behavior to avoid raw type creation.
+	 */
+	protected TypeBinding internalResolveType(Scope scope) {
+		// handle the error here
+		this.constant = Constant.NotAConstant;
+		if (this.resolvedType != null) { // is a shared type reference which was already resolved
+			if (this.resolvedType.isValidBinding()) {
+				return this.resolvedType;
+			} else {
+				switch (this.resolvedType.problemId()) {
+					case ProblemReasons.NotFound :
+					case ProblemReasons.NotVisible :
+						TypeBinding type = this.resolvedType.closestMatch();
+						return type;
+					default :
+						return null;
+				}
+			}
+		}
+		boolean hasError;
+		TypeBinding type = this.resolvedType = getTypeBinding(scope);
+		if (type == null) {
+			return null; // detected cycle while resolving hierarchy
+		} else if ((hasError = !type.isValidBinding())== true) {
+			reportInvalidType(scope);
+			switch (type.problemId()) {
+				case ProblemReasons.NotFound :
+				case ProblemReasons.NotVisible :
+					type = type.closestMatch();
+					if (type == null) return null;
+					break;
+				default :
+					return null;
+			}
+		}
+		if (type.isArrayType() && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
+			scope.problemReporter().cannotAllocateVoidArray(this);
+			return null;
+		}
+		if (isTypeUseDeprecated(type, scope)) {
+			reportDeprecatedType(type, scope);
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=209936
+		// raw convert all enclosing types when dealing with Javadoc references
+		if (type.isGenericType() || type.isParameterizedType()) {
+			type = scope.environment().convertToRawType(type, true /*force the conversion of enclosing types*/);
+		}
+
+		if (hasError) {
+			// do not store the computed type, keep the problem type instead
+			return type;
+		}
+		return this.resolvedType = type;
+	}
+
+	protected void reportInvalidType(Scope scope) {
+		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+	}
+	protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		return new StringBuffer();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
new file mode 100644
index 0000000..5d90545
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+
+public class JavadocMessageSend extends MessageSend {
+
+	public int tagSourceStart, tagSourceEnd;
+	public int tagValue;
+
+	public JavadocMessageSend(char[] name, long pos) {
+		this.selector = name;
+		this.nameSourcePosition = pos;
+		this.sourceStart = (int) (this.nameSourcePosition >>> 32);
+		this.sourceEnd = (int) this.nameSourcePosition;
+		this.bits |= InsideJavadoc;
+	}
+	public JavadocMessageSend(char[] name, long pos, JavadocArgumentExpression[] arguments) {
+		this(name, pos);
+		this.arguments = arguments;
+	}
+
+	/*
+	 * Resolves type on a Block or Class scope.
+	 */
+	private TypeBinding internalResolveType(Scope scope) {
+		// Answer the signature return type
+		// Base type promotion
+		this.constant = Constant.NotAConstant;
+		if (this.receiver == null) {
+			this.actualReceiverType = scope.enclosingReceiverType();
+		} else if (scope.kind == Scope.CLASS_SCOPE) {
+			this.actualReceiverType = this.receiver.resolveType((ClassScope) scope);
+		} else {
+			this.actualReceiverType = this.receiver.resolveType((BlockScope) scope);
+		}
+
+		// will check for null after args are resolved
+
+		TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+		boolean hasArgsTypeVar = false;
+		if (this.arguments != null) {
+			boolean argHasError = false; // typeChecks all arguments
+			int length = this.arguments.length;
+			argumentTypes = new TypeBinding[length];
+			for (int i = 0; i < length; i++){
+				Expression argument = this.arguments[i];
+				if (scope.kind == Scope.CLASS_SCOPE) {
+					argumentTypes[i] = argument.resolveType((ClassScope)scope);
+				} else {
+					argumentTypes[i] = argument.resolveType((BlockScope)scope);
+				}
+				if (argumentTypes[i] == null) {
+					argHasError = true;
+				} else if (!hasArgsTypeVar) {
+					hasArgsTypeVar = argumentTypes[i].isTypeVariable();
+				}
+			}
+			if (argHasError) {
+				return null;
+			}
+		}
+
+		// check receiver type
+		if (this.actualReceiverType == null) {
+			return null;
+		}
+		this.actualReceiverType = scope.environment().convertToRawType(this.receiver.resolvedType, true /*force the conversion of enclosing types*/);
+		ReferenceBinding enclosingType = scope.enclosingReceiverType();
+		if (enclosingType==null ? false : enclosingType.isCompatibleWith(this.actualReceiverType)) {
+			this.bits |= ASTNode.SuperAccess;
+		}
+
+		// base type cannot receive any message
+		if (this.actualReceiverType.isBaseType()) {
+			scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
+			return null;
+		}
+		this.binding = scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+		if (!this.binding.isValidBinding()) {
+			// Try method in enclosing types
+			TypeBinding enclosingTypeBinding = this.actualReceiverType;
+			MethodBinding methodBinding = this.binding;
+			while (!methodBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+				enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+				methodBinding = scope.getMethod(enclosingTypeBinding, this.selector, argumentTypes, this);
+			}
+			if (methodBinding.isValidBinding()) {
+				this.binding = methodBinding;
+			} else {
+				// Try to search a constructor instead
+				enclosingTypeBinding = this.actualReceiverType;
+				MethodBinding contructorBinding = this.binding;
+				if (!contructorBinding.isValidBinding() && CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
+					contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
+				}
+				while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+					enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+					if (CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
+						contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
+					}
+				}
+				if (contructorBinding.isValidBinding()) {
+					this.binding = contructorBinding;
+				}
+			}
+		}
+		if (!this.binding.isValidBinding()) {
+			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
+			switch (this.binding.problemId()) {
+				case ProblemReasons.NonStaticReferenceInConstructorInvocation:
+				case ProblemReasons.NonStaticReferenceInStaticContext:
+				case ProblemReasons.InheritedNameHidesEnclosingName :
+				case ProblemReasons.Ambiguous:
+					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+					if (closestMatch != null) {
+						this.binding = closestMatch; // ignore problem if can reach target method through it
+					}
+			}
+		}
+		if (!this.binding.isValidBinding()) {
+			if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
+				// problem already got signaled on receiver, do not report secondary problem
+				return null;
+			}
+			if (this.binding.declaringClass == null) {
+				if (this.actualReceiverType instanceof ReferenceBinding) {
+					this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
+				} else {
+					scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
+					return null;
+				}
+			}
+			scope.problemReporter().javadocInvalidMethod(this, this.binding, scope.getDeclarationModifiers());
+			// record the closest match, for clients who may still need hint about possible method match
+			if (this.binding instanceof ProblemMethodBinding) {
+				MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+				if (closestMatch != null) this.binding = closestMatch;
+			}
+			return this.resolvedType = this.binding == null ? null : this.binding.returnType;
+		} else if (hasArgsTypeVar) {
+			MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+			scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+		} else if (this.binding.isVarargs()) {
+			int length = argumentTypes.length;
+			if (!(this.binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
+				MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+				scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+			}
+		} else {
+			int length = argumentTypes.length;
+			for (int i=0; i<length; i++) {
+				if (this.binding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+					MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+					scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+					break;
+				}
+			}
+		}
+		if (isMethodUseDeprecated(this.binding, scope, true)) {
+			scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
+		}
+
+		return this.resolvedType = this.binding.returnType;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
+	 */
+	public boolean isSuperAccess() {
+		return (this.bits & ASTNode.SuperAccess) != 0;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		if (this.receiver != null) {
+			this.receiver.printExpression(0, output);
+		}
+		output.append('#').append(this.selector).append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length ; i ++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].printExpression(0, output);
+			}
+		}
+		return output.append(')');
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		return internalResolveType(scope);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+		return internalResolveType(scope);
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+		if (visitor.visit(this, blockScope)) {
+			if (this.receiver != null) {
+				this.receiver.traverse(visitor, blockScope);
+			}
+			if (this.arguments != null) {
+				int argumentsLength = this.arguments.length;
+				for (int i = 0; i < argumentsLength; i++)
+					this.arguments[i].traverse(visitor, blockScope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.receiver != null) {
+				this.receiver.traverse(visitor, scope);
+			}
+			if (this.arguments != null) {
+				int argumentsLength = this.arguments.length;
+				for (int i = 0; i < argumentsLength; i++)
+					this.arguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
new file mode 100644
index 0000000..ee7df88
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class JavadocQualifiedTypeReference extends QualifiedTypeReference {
+
+	public int tagSourceStart, tagSourceEnd;
+	public PackageBinding packageBinding;
+
+	public JavadocQualifiedTypeReference(char[][] sources, long[] pos, int tagStart, int tagEnd) {
+		super(sources, pos);
+		this.tagSourceStart = tagStart;
+		this.tagSourceEnd = tagEnd;
+		this.bits |= ASTNode.InsideJavadoc;
+	}
+
+	/*
+	 * We need to modify resolving behavior to handle package references
+	 */
+	private TypeBinding internalResolveType(Scope scope, boolean checkBounds) {
+		// handle the error here
+		this.constant = Constant.NotAConstant;
+		if (this.resolvedType != null) // is a shared type reference which was already resolved
+			return this.resolvedType.isValidBinding() ? this.resolvedType : this.resolvedType.closestMatch(); // already reported error
+
+		TypeBinding type = this.resolvedType = getTypeBinding(scope);
+		// End resolution when getTypeBinding(scope) returns null. This may happen in
+		// certain circumstances, typically when an illegal access is done on a type
+		// variable (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=204749)
+		if (type == null) return null;
+		if (!type.isValidBinding()) {
+			Binding binding = scope.getTypeOrPackage(this.tokens);
+			if (binding instanceof PackageBinding) {
+				this.packageBinding = (PackageBinding) binding;
+				// Valid package references are allowed in Javadoc (https://bugs.eclipse.org/bugs/show_bug.cgi?id=281609)
+			} else {
+				reportInvalidType(scope);
+			}
+			return null;
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=209936
+		// raw convert all enclosing types when dealing with Javadoc references
+		if (type.isGenericType() || type.isParameterizedType()) {
+			this.resolvedType = scope.environment().convertToRawType(type, true /*force the conversion of enclosing types*/);
+		}
+		return this.resolvedType;
+	}
+	protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
+	}
+	
+	protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers(), index);
+	}
+
+	protected void reportInvalidType(Scope scope) {
+		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+	}
+	public TypeBinding resolveType(BlockScope blockScope, boolean checkBounds) {
+		return internalResolveType(blockScope, checkBounds);
+	}
+
+	public TypeBinding resolveType(ClassScope classScope) {
+		return internalResolveType(classScope, false);
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java
new file mode 100644
index 0000000..25cb038
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+
+public class JavadocReturnStatement extends ReturnStatement {
+
+	public JavadocReturnStatement(int s, int e) {
+		super(null, s, e);
+		this.bits |= (ASTNode.InsideJavadoc | ASTNode.Empty);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolve(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void resolve(BlockScope scope) {
+		MethodScope methodScope = scope.methodScope();
+		MethodBinding methodBinding = null;
+		TypeBinding methodType =
+			(methodScope.referenceContext instanceof AbstractMethodDeclaration)
+				? ((methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding) == null
+					? null
+					: methodBinding.returnType)
+				: TypeBinding.VOID;
+		if (methodType == null || methodType == TypeBinding.VOID) {
+			scope.problemReporter().javadocUnexpectedTag(this.sourceStart, this.sourceEnd);
+		} else if ((this.bits & ASTNode.Empty) != 0) {
+			scope.problemReporter().javadocEmptyReturnTag(this.sourceStart, this.sourceEnd, scope.getDeclarationModifiers());
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Statement#printStatement(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+		printIndent(tab, output).append("return"); //$NON-NLS-1$
+		if ((this.bits & ASTNode.Empty) == 0)
+			output.append(' ').append(" <not empty>"); //$NON-NLS-1$
+		return output;
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java
new file mode 100644
index 0000000..afb2360
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class JavadocSingleNameReference extends SingleNameReference {
+
+	public int tagSourceStart, tagSourceEnd;
+
+	public JavadocSingleNameReference(char[] source, long pos, int tagStart, int tagEnd) {
+		super(source, pos);
+		this.tagSourceStart = tagStart;
+		this.tagSourceEnd = tagEnd;
+		this.bits |= InsideJavadoc;
+	}
+
+	public void resolve(BlockScope scope) {
+		resolve(scope, true, scope.compilerOptions().reportUnusedParameterIncludeDocCommentReference);
+	}
+
+	/**
+	 * Resolve without warnings
+	 */
+	public void resolve(BlockScope scope, boolean warn, boolean considerParamRefAsUsage) {
+
+		LocalVariableBinding variableBinding = scope.findVariable(this.token);
+		if (variableBinding != null && variableBinding.isValidBinding() && ((variableBinding.tagBits & TagBits.IsArgument) != 0)) {
+			this.binding = variableBinding;
+			if (considerParamRefAsUsage) {
+				variableBinding.useFlag = LocalVariableBinding.USED;
+			}
+			return;
+		}
+		if (warn) {
+			try {
+				MethodScope methScope = (MethodScope) scope;
+				scope.problemReporter().javadocUndeclaredParamTagName(this.token, this.sourceStart, this.sourceEnd, methScope.referenceMethod().modifiers);
+			}
+			catch (Exception e) {
+				scope.problemReporter().javadocUndeclaredParamTagName(this.token, this.sourceStart, this.sourceEnd, -1);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
new file mode 100644
index 0000000..19aed08
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+
+public class JavadocSingleTypeReference extends SingleTypeReference {
+
+	public int tagSourceStart, tagSourceEnd;
+	public PackageBinding packageBinding;
+
+	public JavadocSingleTypeReference(char[] source, long pos, int tagStart, int tagEnd) {
+		super(source, pos);
+		this.tagSourceStart = tagStart;
+		this.tagSourceEnd = tagEnd;
+		this.bits |= ASTNode.InsideJavadoc;
+	}
+
+	/*
+	 * We need to modify resolving behavior to handle package references
+	 */
+	protected TypeBinding internalResolveType(Scope scope) {
+		// handle the error here
+		this.constant = Constant.NotAConstant;
+		if (this.resolvedType != null) { // is a shared type reference which was already resolved
+			if (this.resolvedType.isValidBinding()) {
+				return this.resolvedType;
+			} else {
+				switch (this.resolvedType.problemId()) {
+					case ProblemReasons.NotFound :
+					case ProblemReasons.NotVisible :
+					case ProblemReasons.InheritedNameHidesEnclosingName :
+						TypeBinding type = this.resolvedType.closestMatch();
+						return type;
+					default :
+						return null;
+				}
+			}
+		}
+		this.resolvedType = getTypeBinding(scope);
+		// End resolution when getTypeBinding(scope) returns null. This may happen in
+		// certain circumstances, typically when an illegal access is done on a type
+		// variable (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=204749)
+		if (this.resolvedType == null) return null;
+
+		if (!this.resolvedType.isValidBinding()) {
+			char[][] tokens = { this.token };
+			Binding binding = scope.getTypeOrPackage(tokens);
+			if (binding instanceof PackageBinding) {
+				this.packageBinding = (PackageBinding) binding;
+				// Valid package references are allowed in Javadoc (https://bugs.eclipse.org/bugs/show_bug.cgi?id=281609)
+			} else {
+				if (this.resolvedType.problemId() == ProblemReasons.NonStaticReferenceInStaticContext) {
+					TypeBinding closestMatch = this.resolvedType.closestMatch();
+					if (closestMatch != null && closestMatch.isTypeVariable()) {
+						this.resolvedType = closestMatch; // ignore problem as we want report specific javadoc one instead
+						return this.resolvedType;
+					}
+				}
+				reportInvalidType(scope);
+			}
+			return null;
+		}
+		if (isTypeUseDeprecated(this.resolvedType, scope))
+			reportDeprecatedType(this.resolvedType, scope);
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=209936
+		// raw convert all enclosing types when dealing with Javadoc references
+		if (this.resolvedType.isGenericType() || this.resolvedType.isParameterizedType()) {
+			this.resolvedType = scope.environment().convertToRawType(this.resolvedType, true /*force the conversion of enclosing types*/);
+		}
+		return this.resolvedType;
+	}
+	protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+		scope.problemReporter().javadocDeprecatedType(type, this, scope.getDeclarationModifiers());
+	}
+
+	protected void reportInvalidType(Scope scope) {
+		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+	}
+
+	/* (non-Javadoc)
+	 * Redefine to capture javadoc specific signatures
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		visitor.visit(this, scope);
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
new file mode 100644
index 0000000..9fffa3e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class LabeledStatement extends Statement {
+
+	public Statement statement;
+	public char[] label;
+	public BranchLabel targetLabel;
+	public int labelEnd;
+
+	// for local variables table attributes
+	int mergedInitStateIndex = -1;
+
+	/**
+	 * LabeledStatement constructor comment.
+	 */
+	public LabeledStatement(char[] label, Statement statement, long labelPosition, int sourceEnd) {
+
+		this.statement = statement;
+		// remember useful empty statement
+		if (statement instanceof EmptyStatement) statement.bits |= IsUsefulEmptyStatement;
+		this.label = label;
+		this.sourceStart = (int)(labelPosition >>> 32);
+		this.labelEnd = (int) labelPosition;
+		this.sourceEnd = sourceEnd;
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		// need to stack a context to store explicit label, answer inits in case of normal completion merged
+		// with those relative to the exit path from break statement occurring inside the labeled statement.
+		if (this.statement == null) {
+			return flowInfo;
+		} else {
+			LabelFlowContext labelContext;
+			FlowInfo statementInfo, mergedInfo;
+			statementInfo = this.statement.analyseCode(
+				currentScope,
+				(labelContext =
+					new LabelFlowContext(
+						flowContext,
+						this,
+						this.label,
+						(this.targetLabel = new BranchLabel()),
+						currentScope)),
+				flowInfo);
+			boolean reinjectNullInfo = (statementInfo.tagBits & FlowInfo.UNREACHABLE) != 0 &&
+				(labelContext.initsOnBreak.tagBits & FlowInfo.UNREACHABLE) == 0;
+			mergedInfo = statementInfo.mergedWith(labelContext.initsOnBreak);
+			if (reinjectNullInfo) {
+				// an embedded loop has had no chance to reinject forgotten null info
+				((UnconditionalFlowInfo)mergedInfo).addInitializationsFrom(flowInfo.unconditionalFieldLessCopy()).
+					addInitializationsFrom(labelContext.initsOnBreak.unconditionalFieldLessCopy());
+			}
+			this.mergedInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(mergedInfo);
+			if ((this.bits & ASTNode.LabelUsed) == 0) {
+				currentScope.problemReporter().unusedLabel(this);
+			}
+			return mergedInfo;
+		}
+	}
+
+	public ASTNode concreteStatement() {
+
+		// return statement.concreteStatement(); // for supporting nested labels:   a:b:c: someStatement (see 21912)
+		return this.statement;
+	}
+
+	/**
+	 * Code generation for labeled statement
+	 *
+	 * may not need actual source positions recording
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+		if (this.targetLabel != null) {
+			this.targetLabel.initialize(codeStream);
+			if (this.statement != null) {
+				this.statement.generateCode(currentScope, codeStream);
+			}
+			this.targetLabel.place();
+		}
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output).append(this.label).append(": "); //$NON-NLS-1$
+		if (this.statement == null)
+			output.append(';');
+		else
+			this.statement.printStatement(0, output);
+		return output;
+	}
+
+	public void resolve(BlockScope scope) {
+
+		if (this.statement != null) {
+			this.statement.resolve(scope);
+		}
+	}
+
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			if (this.statement != null) this.statement.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
new file mode 100644
index 0000000..2ce4373
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java
@@ -0,0 +1,781 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *							bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *     Stephan Herrmann - Contribution for
+ *							bug 401030 - [1.8][null] Null analysis support for lambda methods.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+import org.eclipse.jdt.internal.compiler.problem.AbortType;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+public class LambdaExpression extends FunctionalExpression implements ReferenceContext, ProblemSeverities {
+	public Argument [] arguments;
+	public Statement body;
+	public boolean hasParentheses;
+	public MethodScope scope;
+	private boolean voidCompatible = true;
+	private boolean valueCompatible = false;
+	private boolean shapeAnalysisComplete = false;
+	private boolean returnsValue;
+	private boolean returnsVoid;
+	private boolean throwsException;
+	private LambdaExpression original = this;
+	private SyntheticArgumentBinding[] outerLocalVariables = NO_SYNTHETIC_ARGUMENTS;
+	private int outerLocalVariablesSlotSize = 0;
+	public boolean shouldCaptureInstance = false;
+	private static final SyntheticArgumentBinding [] NO_SYNTHETIC_ARGUMENTS = new SyntheticArgumentBinding[0];
+	
+	public LambdaExpression(CompilationResult compilationResult, Argument [] arguments, Statement body) {
+		super(compilationResult);
+		this.arguments = arguments != null ? arguments : ASTNode.NO_ARGUMENTS;
+		this.body = body;
+	}
+	
+	protected FunctionalExpression original() {
+		return this.original;
+	}
+	
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		if (this.shouldCaptureInstance) {
+			this.binding.modifiers &= ~ClassFileConstants.AccStatic;
+		} else {
+			this.binding.modifiers |= ClassFileConstants.AccStatic;
+		}
+		SourceTypeBinding sourceType = currentScope.enclosingSourceType();
+		this.binding = sourceType.addSyntheticMethod(this);
+		int pc = codeStream.position;
+		StringBuffer signature = new StringBuffer();
+		signature.append('(');
+		if (this.shouldCaptureInstance) {
+			codeStream.aload_0();
+			signature.append(sourceType.signature());
+		}
+		for (int i = 0, length = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length; i < length; i++) {
+			SyntheticArgumentBinding syntheticArgument = this.outerLocalVariables[i];
+			if (this.shouldCaptureInstance) {
+				syntheticArgument.resolvedPosition++;
+			}
+			signature.append(syntheticArgument.type.signature());
+			LocalVariableBinding capturedOuterLocal = syntheticArgument.actualOuterLocalVariable;
+			VariableBinding[] path = currentScope.getEmulationPath(capturedOuterLocal);
+			codeStream.generateOuterAccess(path, this, capturedOuterLocal, currentScope);
+		}
+		signature.append(')');
+		signature.append(this.expectedType.signature());
+		int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
+		codeStream.invokeDynamic(invokeDynamicNumber, (this.shouldCaptureInstance ? 1 : 0) + this.outerLocalVariablesSlotSize, 1, TypeConstants.ANONYMOUS_METHOD, signature.toString().toCharArray());
+		codeStream.recordPositionsFrom(pc, this.sourceStart);		
+	}
+
+	public boolean kosherDescriptor(Scope currentScope, MethodBinding sam, boolean shouldChatter) {
+		if (sam.typeVariables != Binding.NO_TYPE_VARIABLES) {
+			if (shouldChatter)
+				currentScope.problemReporter().lambdaExpressionCannotImplementGenericMethod(this, sam);
+			return false;
+		}
+		return super.kosherDescriptor(currentScope, sam, shouldChatter);
+	}
+	
+	/* This code is arranged so that we can continue with as much analysis as possible while avoiding 
+	 * mine fields that would result in a slew of spurious messages. This method is a merger of:
+	 * @see org.eclipse.jdt.internal.compiler.lookup.MethodScope.createMethod(AbstractMethodDeclaration)
+	 * @see org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.resolveTypesFor(MethodBinding)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration.resolve(ClassScope)
+	 */
+	public TypeBinding resolveType(BlockScope blockScope) {
+		
+		this.constant = Constant.NotAConstant;
+		this.enclosingScope = blockScope;
+		
+		if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
+			return new PolyTypeBinding(this);
+		} 
+		
+		MethodScope methodScope = blockScope.methodScope();
+		this.scope = new MethodScope(blockScope, this, methodScope.isStatic);
+		this.scope.isConstructorCall = methodScope.isConstructorCall;
+
+		super.resolveType(blockScope); // compute & capture interface function descriptor in singleAbstractMethod.
+		
+		final boolean argumentsTypeElided = argumentsTypeElided();
+		final boolean haveDescriptor = this.descriptor != null;
+		
+		if (haveDescriptor && this.descriptor.typeVariables != Binding.NO_TYPE_VARIABLES) // already complained in kosher*
+			return null;
+		
+		if (!haveDescriptor && argumentsTypeElided) 
+			return null; // FUBAR, bail out...
+
+		this.binding = new MethodBinding(ClassFileConstants.AccPrivate | ClassFileConstants.AccSynthetic | ExtraCompilerModifiers.AccUnresolved,
+							TypeConstants.ANONYMOUS_METHOD, // will be fixed up later.
+							haveDescriptor ? this.descriptor.returnType : null, 
+							Binding.NO_PARAMETERS, // for now. 
+							haveDescriptor ? this.descriptor.thrownExceptions : Binding.NO_EXCEPTIONS, 
+							blockScope.enclosingSourceType());
+		this.binding.typeVariables = Binding.NO_TYPE_VARIABLES;
+		
+		if (haveDescriptor) {
+			int descriptorParameterCount = this.descriptor.parameters.length;
+			int lambdaArgumentCount = this.arguments != null ? this.arguments.length : 0;
+            if (descriptorParameterCount != lambdaArgumentCount) {
+            	this.scope.problemReporter().lambdaSignatureMismatched(this);
+            	if (argumentsTypeElided) 
+            		return null; // FUBAR, bail out ...
+            }
+		}
+		
+		boolean buggyArguments = false;
+		int length = this.arguments == null ? 0 : this.arguments.length;
+		TypeBinding[] newParameters = new TypeBinding[length];
+
+		AnnotationBinding [][] parameterAnnotations = null;
+		for (int i = 0; i < length; i++) {
+			Argument argument = this.arguments[i];
+			if (argument.isVarArgs()) {
+				if (i == length - 1) {
+					this.binding.modifiers |= ClassFileConstants.AccVarargs;
+				} else {
+					this.scope.problemReporter().illegalVarargInLambda(argument);
+					buggyArguments = true;
+				}
+			}
+			
+			TypeBinding parameterType;
+			final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null;
+			parameterType = argumentsTypeElided ? expectedParameterType : argument.type.resolveType(this.scope, true /* check bounds*/);
+			if (parameterType == null) {
+				buggyArguments = true;
+			} else if (parameterType == TypeBinding.VOID) {
+				this.scope.problemReporter().argumentTypeCannotBeVoid(this, argument);
+				buggyArguments = true;
+			} else {
+				if (!parameterType.isValidBinding()) {
+					this.binding.tagBits |= TagBits.HasUnresolvedArguments;
+				}
+				if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
+					this.binding.tagBits |= TagBits.HasMissingType;
+				}
+				if (haveDescriptor && expectedParameterType != null && parameterType.isValidBinding() && parameterType != expectedParameterType) {
+					this.scope.problemReporter().lambdaParameterTypeMismatched(argument, argument.type, expectedParameterType);
+				}
+
+				TypeBinding leafType = parameterType.leafComponentType();
+				if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+					this.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+				newParameters[i] = parameterType;
+				argument.bind(this.scope, parameterType, false);
+				if (argument.annotations != null) {
+					this.binding.tagBits |= TagBits.HasParameterAnnotations;
+					if (parameterAnnotations == null) {
+						parameterAnnotations = new AnnotationBinding[length][];
+						for (int j = 0; j < i; j++) {
+							parameterAnnotations[j] = Binding.NO_ANNOTATIONS;
+						}
+					}
+					parameterAnnotations[i] = argument.binding.getAnnotations();
+				} else if (parameterAnnotations != null) {
+					parameterAnnotations[i] = Binding.NO_ANNOTATIONS;
+				}
+			}
+		}
+		// only assign parameters if no problems are found
+		if (!buggyArguments) {
+			this.binding.parameters = newParameters;
+			if (parameterAnnotations != null)
+				this.binding.setParameterAnnotations(parameterAnnotations);
+		}
+	
+		if (!argumentsTypeElided && this.binding.isVarargs()) {
+			if (!this.binding.parameters[this.binding.parameters.length - 1].isReifiable()) {
+				this.scope.problemReporter().possibleHeapPollutionFromVararg(this.arguments[this.arguments.length - 1]);
+			}
+		}
+
+		ReferenceBinding [] exceptions = this.binding.thrownExceptions;
+		length = exceptions.length;
+		for (int i = 0; i < length; i++) {
+			ReferenceBinding exception = exceptions[i];
+			if ((exception.tagBits & TagBits.HasMissingType) != 0) {
+				this.binding.tagBits |= TagBits.HasMissingType;
+			}
+			this.binding.modifiers |= (exception.modifiers & ExtraCompilerModifiers.AccGenericSignature);
+		}
+		
+		TypeBinding returnType = this.binding.returnType;
+		if (returnType != null) {
+			if ((returnType.tagBits & TagBits.HasMissingType) != 0) {
+				this.binding.tagBits |= TagBits.HasMissingType;
+			}
+			TypeBinding leafType = returnType.leafComponentType();
+			if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+				this.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+		} // TODO (stephan): else? (can that happen?)
+
+		if (haveDescriptor && blockScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+			if (!argumentsTypeElided) {
+				AbstractMethodDeclaration.createArgumentBindings(this.arguments, this.binding, this.scope);
+				validateNullAnnotations();
+				// no application of null-ness default, hence also no warning regarding redundant null annotation
+				mergeParameterNullAnnotations(blockScope);
+			}
+			this.binding.tagBits |= (this.descriptor.tagBits & TagBits.AnnotationNullMASK);
+		}
+
+		this.binding.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+		
+		if (this.body instanceof Expression) {
+			Expression expression = (Expression) this.body;
+			new ReturnStatement(expression, expression.sourceStart, expression.sourceEnd, true).resolve(this.scope); // :-) ;-)
+		} else {
+			this.body.resolve(this.scope);
+		}
+		return this.resolvedType;
+	}
+	
+	private boolean argumentsTypeElided() {
+		return this.arguments.length > 0 && this.arguments[0].hasElidedType();
+	}
+
+	private boolean doesNotCompleteNormally() {
+		return this.body.analyseCode(this.scope, 
+									 new ExceptionHandlingFlowContext(null, this, Binding.NO_EXCEPTIONS, null, this.scope, FlowInfo.DEAD_END), 
+									 FlowInfo.initial(this.scope.referenceType().maxFieldCount)) == FlowInfo.DEAD_END; 
+	}
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, final FlowInfo flowInfo) {
+		
+		if (this.ignoreFurtherInvestigation) 
+			return flowInfo;
+		
+		FlowInfo lambdaInfo = flowInfo.copy(); // what happens in vegas, stays in vegas ...
+		ExceptionHandlingFlowContext methodContext =
+				new ExceptionHandlingFlowContext(
+						flowContext,
+						this,
+						this.binding.thrownExceptions,
+						null,
+						this.scope,
+						FlowInfo.DEAD_END);
+
+		// nullity and mark as assigned
+		MethodBinding methodWithParameterDeclaration = argumentsTypeElided() ? this.descriptor : this.binding;
+		AbstractMethodDeclaration.analyseArguments(lambdaInfo, this.arguments, methodWithParameterDeclaration);
+
+		if (this.arguments != null) {
+			for (int i = 0, count = this.arguments.length; i < count; i++) {
+				this.bits |= (this.arguments[i].bits & ASTNode.HasTypeAnnotations);
+			}
+		}
+		
+		lambdaInfo = this.body.analyseCode(this.scope, methodContext, lambdaInfo);
+		
+		// check for missing returning path for block body's ...
+		if (this.body instanceof Block) {
+			TypeBinding returnTypeBinding = expectedResultType();
+			if ((returnTypeBinding == TypeBinding.VOID)) {
+				if ((lambdaInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0 || ((Block) this.body).statements == null) {
+					this.bits |= ASTNode.NeedFreeReturn;
+				}
+			} else {
+				if (lambdaInfo != FlowInfo.DEAD_END) {
+					this.scope.problemReporter().shouldReturn(returnTypeBinding, this);
+				}
+			}
+		} else { // Expression
+			if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled 
+					&& flowInfo.reachMode() == FlowInfo.REACHABLE)
+			{
+				Expression expression = (Expression)this.body;
+				checkAgainstNullAnnotation(flowContext, expression, expression.nullStatus(flowInfo, flowContext));
+			}
+		}
+		return flowInfo;
+	}
+
+	// cf. AbstractMethodDeclaration.validateNullAnnotations()
+	// pre: !argumentTypeElided()
+	void validateNullAnnotations() {
+		// null annotations on parameters?
+		if (this.binding != null && this.binding.parameterNonNullness != null) {
+			int length = this.binding.parameters.length;
+			for (int i=0; i<length; i++) {
+				if (this.binding.parameterNonNullness[i] != null) {
+					long nullAnnotationTagBit =  this.binding.parameterNonNullness[i].booleanValue()
+							? TagBits.AnnotationNonNull : TagBits.AnnotationNullable;
+					this.scope.validateNullAnnotation(nullAnnotationTagBit, this.arguments[i].type, this.arguments[i].annotations);
+				}
+			}
+		}
+	}
+
+	// pre: !argumentTypeElided()
+	// try to merge null annotations from descriptor into binding, complaining about any incompatibilities found
+	private void mergeParameterNullAnnotations(BlockScope currentScope) {
+		if (this.descriptor.parameterNonNullness == null)
+			return;
+		if (this.binding.parameterNonNullness == null) {
+			this.binding.parameterNonNullness = this.descriptor.parameterNonNullness;
+			return;
+		}
+		LookupEnvironment env = currentScope.environment();
+		Boolean[] ourNonNullness = this.binding.parameterNonNullness;
+		Boolean[] descNonNullness = this.descriptor.parameterNonNullness;
+		int len = Math.min(ourNonNullness.length, descNonNullness.length);
+		for (int i = 0; i < len; i++) {
+			if (ourNonNullness[i] == null) {
+				ourNonNullness[i] = descNonNullness[i];
+			} else if (ourNonNullness[i] != descNonNullness[i]) {
+				if (ourNonNullness[i] == Boolean.TRUE) { // requested @NonNull not provided
+					char[][] inheritedAnnotationName = null;
+					if (descNonNullness[i] == Boolean.FALSE)
+						inheritedAnnotationName = env.getNullableAnnotationName();
+					currentScope.problemReporter().illegalRedefinitionToNonNullParameter(this.arguments[i], this.descriptor.declaringClass, inheritedAnnotationName);
+				}
+			}			
+		}
+	}
+
+	// simplified version of ReturnStatement.checkAgainstNullAnnotation()
+	void checkAgainstNullAnnotation(FlowContext flowContext, Expression expression, int nullStatus) {
+		if (nullStatus != FlowInfo.NON_NULL) {
+			// if we can't prove non-null check against declared null-ness of the descriptor method:
+			// Note that this.binding never has a return type declaration, always inherit null-ness from the descriptor
+			if ((this.descriptor.tagBits & TagBits.AnnotationNonNull) != 0) {
+				flowContext.recordNullityMismatch(this.scope, expression, expression.resolvedType, this.descriptor.returnType, nullStatus);
+			}
+		}
+	}
+
+	public StringBuffer printExpression(int tab, StringBuffer output) {
+		int parenthesesCount = (this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		String suffix = ""; //$NON-NLS-1$
+		for(int i = 0; i < parenthesesCount; i++) {
+			output.append('(');
+			suffix += ')';
+		}
+		output.append('(');
+		if (this.arguments != null) {
+			for (int i = 0; i < this.arguments.length; i++) {
+				if (i > 0) output.append(", "); //$NON-NLS-1$
+				this.arguments[i].print(0, output);
+			}
+		}
+		output.append(") -> " ); //$NON-NLS-1$
+		this.body.print(this.body instanceof Block ? tab : 0, output);
+		return output.append(suffix);
+	}
+
+	public TypeBinding expectedResultType() {
+		return this.descriptor != null && this.descriptor.isValidBinding() ? this.descriptor.returnType : null;
+	}
+	
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+
+			if (visitor.visit(this, blockScope)) {
+				if (this.arguments != null) {
+					int argumentsLength = this.arguments.length;
+					for (int i = 0; i < argumentsLength; i++)
+						this.arguments[i].traverse(visitor, this.scope);
+				}
+
+				if (this.body != null) {
+					this.body.traverse(visitor, this.scope);
+				}
+			}
+			visitor.endVisit(this, blockScope);
+	}
+	
+	public MethodScope getScope() {
+		return this.scope;
+	}
+		
+	protected boolean errorEqualsIncompatibility() {
+		return this.original.shapeAnalysisComplete; // so as not to abort shape analysis.
+	}
+	
+	public boolean isCompatibleWith(final TypeBinding left, final Scope someScope) {
+		
+		final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
+		
+		if (sam == null || !sam.isValidBinding())
+			return false;
+		if (sam.parameters.length != this.arguments.length)
+			return false;
+		
+		if (!this.shapeAnalysisComplete && this.body instanceof Expression) {
+			Expression expression = (Expression) this.body;
+			this.voidCompatible = expression.statementExpression();
+			this.valueCompatible = true;
+			this.shapeAnalysisComplete = true;
+		}
+
+		if (this.shapeAnalysisComplete) {
+			if (squarePegInRoundHole(sam))
+				return false;
+		} 
+
+		IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
+		this.hasIgnoredMandatoryErrors = false;
+		try {
+			final LambdaExpression copy = copy();
+			if (copy == null)
+				return false;
+			copy.setExpressionContext(this.expressionContext);
+			copy.setExpectedType(left);
+			if (this.resultExpressions == null)
+				this.resultExpressions = new SimpleLookupTable(); // gather result expressions for most specific method analysis.
+			this.resultExpressions.put(left, new Expression[0]);
+			copy.resolveType(this.enclosingScope);
+			if (!this.shapeAnalysisComplete) {
+				boolean lambdaIsFubar = this.hasIgnoredMandatoryErrors; // capture now, before doesNotCompleteNormally which runs analyzeCode on lambda body *without* the enclosing context being analyzed 
+				if (!this.returnsVoid && !this.returnsValue && this.throwsException) {  // () -> { throw new Exception(); } is value compatible.
+					Block block = (Block) this.body;
+					final Statement[] statements = block.statements;
+					final int statementsLength = statements == null ? 0 : statements.length;
+					Statement ultimateStatement = statementsLength == 0 ? null : statements[statementsLength - 1];
+					this.valueCompatible = ultimateStatement instanceof ThrowStatement ? true: copy.doesNotCompleteNormally(); 
+				}
+				this.shapeAnalysisComplete = true;
+				if (squarePegInRoundHole(sam) || lambdaIsFubar)
+					return false;
+			}
+		} catch (IncongruentLambdaException e) {
+			return false;
+		} finally {
+			this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
+			this.hasIgnoredMandatoryErrors = false;
+		}
+		return true;
+	}
+	
+	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+		/* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here, 
+		   but have been left in for completeness/documentation sakes. These should be cheap anyways. 
+		*/
+		
+		// Both t and s are functional interface types ... 
+		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		if (tSam == null || !tSam.isValidBinding())
+			return false;
+		MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
+		if (sSam == null || !sSam.isValidBinding())
+			return false;
+		
+		// t should neither be a subinterface nor a superinterface of s
+		if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+			return false;
+
+		// If the lambda expression's parameters have inferred types, then the descriptor parameter types of t are the same as the descriptor parameter types of s.
+		if (argumentsTypeElided()) {
+			if (tSam.parameters.length != sSam.parameters.length)
+				return false;
+			for (int i = 0, length = tSam.parameters.length; i < length; i++) {
+				if (tSam.parameters[i] != sSam.parameters[i])
+					return false;
+			}
+		}
+		
+		// either the descriptor return type of s is void or ...
+		if (sSam.returnType.id == TypeIds.T_void)
+			return true;
+		
+		/* ... or for all result expressions in the lambda body (or for the body itself if the body is an expression), 
+           the descriptor return type of the capture of T is more specific than the descriptor return type of S.
+		*/
+		Expression [] returnExpressions = (Expression[]) this.resultExpressions.get(t); // should be same as for s
+		int returnExpressionsLength = returnExpressions == null ? 0 : returnExpressions.length;
+		if (returnExpressionsLength == 0)
+			return true; // as good as or as bad as false.
+		
+		t = t.capture(this.enclosingScope, this.sourceEnd);
+		tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		for (int i = 0; i < returnExpressionsLength; i++) {
+			Expression resultExpression = returnExpressions[i];
+			if (!resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType))
+				return false;
+		}
+		return true;
+	}
+
+	private boolean squarePegInRoundHole(final MethodBinding sam) {
+		if (sam.returnType.id == TypeIds.T_void) {
+			if (!this.voidCompatible)
+				return true;
+		} else {
+			if (!this.valueCompatible)
+				return true;
+		}
+		return false;
+	}
+
+	LambdaExpression copy() {
+		final Parser parser = new Parser(this.enclosingScope.problemReporter(), false);
+		final char[] source = this.compilationResult.getCompilationUnit().getContents();
+		LambdaExpression copy =  (LambdaExpression) parser.parseLambdaExpression(source, this.sourceStart, this.sourceEnd - this.sourceStart + 1, 
+										this.enclosingScope.referenceCompilationUnit(), false /* record line separators */);
+
+		if (copy != null) { // ==> syntax errors == null
+			copy.original = this;
+		}
+		return copy;
+	}
+
+	public void returnsExpression(Expression expression, TypeBinding resultType) {
+		if (this.original == this) // not in overload resolution context.
+			return;
+		if (expression != null) {
+			this.original.returnsValue = true;
+			this.original.voidCompatible = false;
+			this.original.valueCompatible = !this.original.returnsVoid;
+			if (resultType != null) {
+				Expression [] results = (Expression[]) this.original.resultExpressions.get(this.expectedType);
+				int resultsLength = results.length;
+				System.arraycopy(results, 0, results = new Expression[resultsLength + 1], 0, resultsLength);
+				results[resultsLength] = expression;
+			}
+		} else {
+			this.original.returnsVoid = true;
+			this.original.valueCompatible = false;
+			this.original.voidCompatible = !this.original.returnsValue;
+		}
+	}
+
+	public void throwsException(TypeBinding exceptionType) {
+		if (this.expressionContext != INVOCATION_CONTEXT)
+			return;
+		this.original.throwsException = true;
+	}
+	
+	public CompilationResult compilationResult() {
+		return this.compilationResult;
+	}
+
+	public void abort(int abortLevel, CategorizedProblem problem) {
+	
+		switch (abortLevel) {
+			case AbortCompilation :
+				throw new AbortCompilation(this.compilationResult, problem);
+			case AbortCompilationUnit :
+				throw new AbortCompilationUnit(this.compilationResult, problem);
+			case AbortType :
+				throw new AbortType(this.compilationResult, problem);
+			default :
+				throw new AbortMethod(this.compilationResult, problem);
+		}
+	}
+
+	public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+		return this.enclosingScope == null ? null : this.enclosingScope.compilationUnitScope().referenceContext;
+	}
+
+	public boolean hasErrors() {
+		return this.ignoreFurtherInvestigation;
+	}
+
+	public void tagAsHavingErrors() {
+		this.ignoreFurtherInvestigation = true;
+		Scope parent = this.enclosingScope.parent;
+		while (parent != null) {
+			switch(parent.kind) {
+				case Scope.CLASS_SCOPE:
+				case Scope.METHOD_SCOPE:
+					parent.referenceContext().tagAsHavingErrors();
+					return;
+				default:
+					parent = parent.parent;
+					break;
+			}
+		}
+	}
+	
+	public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
+		// 15.27.3 requires exception throw related errors to not influence congruence. Other errors should. Also don't abort shape analysis.
+		switch (problemId) {
+			case IProblem.UnhandledExceptionOnAutoClose:
+			case IProblem.UnhandledExceptionInDefaultConstructor:
+			case IProblem.UnhandledException:
+				return;
+			default: 
+				if (errorEqualsIncompatibility())
+					throw new IncongruentLambdaException();
+				this.original().hasIgnoredMandatoryErrors = true;
+				return;
+		}
+	}
+
+	public void generateCode(ClassScope classScope, ClassFile classFile) {
+		int problemResetPC = 0;
+		classFile.codeStream.wideMode = false;
+		boolean restart = false;
+		do {
+			try {
+				problemResetPC = classFile.contentsOffset;
+				this.generateCode(classFile);
+				restart = false;
+			} catch (AbortMethod e) {
+				// Restart code generation if possible ...
+				if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
+					// a branch target required a goto_w, restart code generation in wide mode.
+					classFile.contentsOffset = problemResetPC;
+					classFile.methodCount--;
+					classFile.codeStream.resetInWideMode(); // request wide mode
+					restart = true;
+				} else if (e.compilationResult == CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE) {
+					classFile.contentsOffset = problemResetPC;
+					classFile.methodCount--;
+					classFile.codeStream.resetForCodeGenUnusedLocals();
+					restart = true;
+				} else {
+					throw new AbortType(this.compilationResult, e.problem);
+				}
+			}
+		} while (restart);
+	}
+	
+	public void generateCode(ClassFile classFile) {
+		classFile.generateMethodInfoHeader(this.binding);
+		int methodAttributeOffset = classFile.contentsOffset;
+		int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
+		int codeAttributeOffset = classFile.contentsOffset;
+		classFile.generateCodeAttributeHeader();
+		CodeStream codeStream = classFile.codeStream;
+		codeStream.reset(this, classFile);
+		// initialize local positions
+		this.scope.computeLocalVariablePositions(this.outerLocalVariablesSlotSize + (this.binding.isStatic() ? 0 : 1), codeStream);
+		if (this.outerLocalVariables != null) {
+			for (int i = 0, max = this.outerLocalVariables.length; i < max; i++) {
+				LocalVariableBinding argBinding;
+				codeStream.addVisibleLocalVariable(argBinding = this.outerLocalVariables[i]);
+				codeStream.record(argBinding);
+				argBinding.recordInitializationStartPC(0);
+			}
+		}
+		// arguments initialization for local variable debug attributes
+		if (this.arguments != null) {
+			for (int i = 0, max = this.arguments.length; i < max; i++) {
+				LocalVariableBinding argBinding;
+				codeStream.addVisibleLocalVariable(argBinding = this.arguments[i].binding);
+				argBinding.recordInitializationStartPC(0);
+			}
+		}
+		if (this.body instanceof Block) {
+			this.body.generateCode(this.scope, codeStream);
+			if ((this.bits & ASTNode.NeedFreeReturn) != 0) {
+				codeStream.return_();
+			}
+		} else {
+			Expression expression = (Expression) this.body;
+			expression.generateCode(this.scope, codeStream, true);
+			if (this.binding.returnType == TypeBinding.VOID) {
+				codeStream.return_();
+			} else {
+				codeStream.generateReturnBytecode(expression);
+			}
+		}
+		// local variable attributes
+		codeStream.exitUserScope(this.scope);
+		codeStream.recordPositionsFrom(0, this.sourceEnd); // WAS declarationSourceEnd.
+		try {
+			classFile.completeCodeAttribute(codeAttributeOffset);
+		} catch(NegativeArraySizeException e) {
+			throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
+		}
+		attributeNumber++;
+
+		classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
+	}
+	
+	public void addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
+		
+		if (this.original != this || this.binding == null) 
+			return; // Do not bother tracking outer locals for clones created during overload resolution.
+		
+		SyntheticArgumentBinding syntheticLocal = null;
+		int newSlot = this.outerLocalVariables.length;
+		for (int i = 0; i < newSlot; i++) {
+			if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
+				return;
+		}
+		System.arraycopy(this.outerLocalVariables, 0, this.outerLocalVariables = new SyntheticArgumentBinding[newSlot + 1], 0, newSlot);
+		this.outerLocalVariables[newSlot] = syntheticLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
+		syntheticLocal.resolvedPosition = this.outerLocalVariablesSlotSize; // may need adjusting later if we need to generate an instance method for the lambda.
+		syntheticLocal.declaringScope = this.scope;
+		int parameterCount = this.binding.parameters.length;
+		TypeBinding [] newParameters = new TypeBinding[parameterCount + 1];
+		newParameters[newSlot] = actualOuterLocalVariable.type;
+		for (int i = 0, j = 0; i < parameterCount; i++, j++) {
+			if (i == newSlot) j++;
+			newParameters[j] = this.binding.parameters[i];
+		}
+		this.binding.parameters = newParameters;
+		switch (syntheticLocal.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				this.outerLocalVariablesSlotSize  += 2;
+				break;
+			default :
+				this.outerLocalVariablesSlotSize++;
+				break;
+		}		
+	}
+
+	public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
+		for (int i = 0, length = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length; i < length; i++)
+			if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
+				return this.outerLocalVariables[i];
+		return null;
+	}
+}
+class IncongruentLambdaException extends RuntimeException {
+	private static final long serialVersionUID = 4145723509219836114L;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
new file mode 100644
index 0000000..18abfff
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class Literal extends Expression {
+
+	public Literal(int s, int e) {
+
+		this.sourceStart = s;
+		this.sourceEnd = e;
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		return flowInfo;
+	}
+
+	public abstract void computeConstant();
+
+	public abstract TypeBinding literalType(BlockScope scope);
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		return output.append(source());
+	 }
+
+	public TypeBinding resolveType(BlockScope scope) {
+		// compute the real value, which must range its type's range
+		this.resolvedType = literalType(scope);
+
+		// in case of error, constant did remain null
+		computeConstant();
+		if (this.constant == null) {
+			scope.problemReporter().constantOutOfRange(this, this.resolvedType);
+			this.constant = Constant.NotAConstant;
+		}
+		return this.resolvedType;
+	}
+
+	public abstract char[] source();
+}
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
new file mode 100644
index 0000000..4da91f5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *							bug 292478 - Report potentially null across variable assignment
+ *							bug 335093 - [compiler][null] minimal hook for future null annotation support
+ *							bug 349326 - [1.7] new warning for missing try-with-resources
+ *							bug 186342 - [compiler][null] Using annotations for null checking
+ *							bug 358903 - Filter practically unimportant resource leak warnings
+ *							bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *							bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *							bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *							bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *							bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *							bug 383368 - [compiler][null] syntactic null analysis for field references
+ *							bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *     Jesper S Moller - Contributions for
+ *							Bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class LocalDeclaration extends AbstractVariableDeclaration {
+
+	public LocalVariableBinding binding;
+
+	public LocalDeclaration(
+		char[] name,
+		int sourceStart,
+		int sourceEnd) {
+
+		this.name = name;
+		this.sourceStart = sourceStart;
+		this.sourceEnd = sourceEnd;
+		this.declarationEnd = sourceEnd;
+	}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	// record variable initialization if any
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		this.bits |= ASTNode.IsLocalDeclarationReachable; // only set if actually reached
+	}
+	if (this.initialization == null) {
+		return flowInfo;
+	}
+	this.initialization.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+	
+	FlowInfo preInitInfo = null;
+	boolean shouldAnalyseResource = this.binding != null 
+			&& flowInfo.reachMode() == FlowInfo.REACHABLE
+			&& currentScope.compilerOptions().analyseResourceLeaks
+			&& FakedTrackingVariable.isAnyCloseable(this.initialization.resolvedType);
+	if (shouldAnalyseResource) {
+		preInitInfo = flowInfo.unconditionalCopy();
+		// analysis of resource leaks needs additional context while analyzing the RHS:
+		FakedTrackingVariable.preConnectTrackerAcrossAssignment(this, this.binding, this.initialization, flowInfo);
+	}
+
+	flowInfo =
+		this.initialization
+			.analyseCode(currentScope, flowContext, flowInfo)
+			.unconditionalInits();
+
+	if (shouldAnalyseResource)
+		FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, flowContext, this, this.initialization, this.binding);
+	else
+		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, Binding.LOCAL, this.initialization);
+
+	int nullStatus = this.initialization.nullStatus(flowInfo, flowContext);
+	if (!flowInfo.isDefinitelyAssigned(this.binding)){// for local variable debug attributes
+		this.bits |= FirstAssignmentToLocal;
+	} else {
+		this.bits &= ~FirstAssignmentToLocal;  // int i = (i = 0);
+	}
+	flowInfo.markAsDefinitelyAssigned(this.binding);
+	nullStatus = checkAssignmentAgainstNullAnnotation(currentScope, flowContext, this.binding, nullStatus, this.initialization, this.initialization.resolvedType);
+	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
+		flowInfo.markNullStatus(this.binding, nullStatus);
+		// no need to inform enclosing try block since its locals won't get
+		// known by the finally block
+	}
+	return flowInfo;
+}
+
+	public void checkModifiers() {
+
+		//only potential valid modifier is <<final>>
+		if (((this.modifiers & ExtraCompilerModifiers.AccJustFlag) & ~ClassFileConstants.AccFinal) != 0)
+			//AccModifierProblem -> other (non-visibility problem)
+			//AccAlternateModifierProblem -> duplicate modifier
+			//AccModifierProblem | AccAlternateModifierProblem -> visibility problem"
+
+			this.modifiers = (this.modifiers & ~ExtraCompilerModifiers.AccAlternateModifierProblem) | ExtraCompilerModifiers.AccModifierProblem;
+	}
+
+	/**
+	 * Code generation for a local declaration:
+	 *	i.e.&nbsp;normal assignment to a local variable + unused variable handling
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		// even if not reachable, variable must be added to visible if allocated (28298)
+		if (this.binding.resolvedPosition != -1) {
+			codeStream.addVisibleLocalVariable(this.binding);
+		}
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+
+		// something to initialize?
+		generateInit: {
+			if (this.initialization == null)
+				break generateInit;
+			// forget initializing unused or final locals set to constant value (final ones are inlined)
+			if (this.binding.resolvedPosition < 0) {
+				if (this.initialization.constant != Constant.NotAConstant)
+					break generateInit;
+				// if binding unused generate then discard the value
+				this.initialization.generateCode(currentScope, codeStream, false);
+				break generateInit;
+			}
+			this.initialization.generateCode(currentScope, codeStream, true);
+			// 26903, need extra cast to store null in array local var
+			if (this.binding.type.isArrayType()
+				&& ((this.initialization instanceof CastExpression)	// arrayLoc = (type[])null
+						&& (((CastExpression)this.initialization).innermostCastedExpression().resolvedType == TypeBinding.NULL))){
+				codeStream.checkcast(this.binding.type);
+			}
+			codeStream.store(this.binding, false);
+			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) {
+				/* Variable may have been initialized during the code initializing it
+					e.g. int i = (i = 1);
+				*/
+				this.binding.recordInitializationStartPC(codeStream.position);
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
+	 */
+	public int getKind() {
+		return LOCAL_VARIABLE;
+	}
+
+	// for local variables
+	public void getAllAnnotationContexts(int targetType, LocalVariableBinding localVariable, List allAnnotationContexts) {
+		AnnotationCollector collector = new AnnotationCollector(this, targetType, localVariable, allAnnotationContexts);
+		this.traverse(collector, (BlockScope) null);
+	}
+	// for arguments
+	public void getAllAnnotationContexts(int targetType, int parameterIndex, List allAnnotationContexts) {
+		AnnotationCollector collector = new AnnotationCollector(this, targetType, parameterIndex, allAnnotationContexts);
+		this.traverse(collector, (BlockScope) null);
+	}
+	public boolean isArgument() {
+		return false;
+	}
+	public boolean isReceiver() {
+		return false;
+	}
+	public void resolve(BlockScope scope) {
+
+		// create a binding and add it to the scope
+		TypeBinding variableType = this.type.resolveType(scope, true /* check bounds*/);
+
+		this.bits |= (this.type.bits & ASTNode.HasTypeAnnotations);
+		checkModifiers();
+		if (variableType != null) {
+			if (variableType == TypeBinding.VOID) {
+				scope.problemReporter().variableTypeCannotBeVoid(this);
+				return;
+			}
+			if (variableType.isArrayType() && ((ArrayBinding) variableType).leafComponentType == TypeBinding.VOID) {
+				scope.problemReporter().variableTypeCannotBeVoidArray(this);
+				return;
+			}
+		}
+
+		Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
+		if (existingVariable != null && existingVariable.isValidBinding()){
+			boolean localExists = existingVariable instanceof LocalVariableBinding; 
+			if (localExists && (this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope()) {
+					scope.problemReporter().lambdaRedeclaresLocal(this);
+			} else if (localExists && this.hiddenVariableDepth == 0) {
+					scope.problemReporter().redefineLocal(this);
+			} else {
+				scope.problemReporter().localVariableHiding(this, existingVariable, false);
+			}
+		}
+
+		if ((this.modifiers & ClassFileConstants.AccFinal)!= 0 && this.initialization == null) {
+			this.modifiers |= ExtraCompilerModifiers.AccBlankFinal;
+		}
+		this.binding = new LocalVariableBinding(this, variableType, this.modifiers, false /*isArgument*/);
+		scope.addLocalVariable(this.binding);
+		this.binding.setConstant(Constant.NotAConstant);
+		// allow to recursivelly target the binding....
+		// the correct constant is harmed if correctly computed at the end of this method
+
+		if (variableType == null) {
+			if (this.initialization != null)
+				this.initialization.resolveType(scope); // want to report all possible errors
+			return;
+		}
+
+		// store the constant for final locals
+		if (this.initialization != null) {
+			if (this.initialization instanceof ArrayInitializer) {
+				TypeBinding initializationType = this.initialization.resolveTypeExpecting(scope, variableType);
+				if (initializationType != null) {
+					((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType;
+					this.initialization.computeConversion(scope, variableType, initializationType);
+				}
+			} else {
+				this.initialization.setExpressionContext(ASSIGNMENT_CONTEXT);
+				this.initialization.setExpectedType(variableType);
+				TypeBinding initializationType = this.initialization.resolveType(scope);
+				if (initializationType != null) {
+					if (variableType != initializationType) // must call before computeConversion() and typeMismatchError()
+						scope.compilationUnitScope().recordTypeConversion(variableType, initializationType);
+					if (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, variableType)
+						|| initializationType.isCompatibleWith(variableType, scope)) {
+						this.initialization.computeConversion(scope, variableType, initializationType);
+						if (initializationType.needsUncheckedConversion(variableType)) {
+						    scope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, variableType);
+						}
+						if (this.initialization instanceof CastExpression
+								&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
+							CastExpression.checkNeedForAssignedCast(scope, variableType, (CastExpression) this.initialization);
+						}
+					} else if (isBoxingCompatible(initializationType, variableType, this.initialization, scope)) {
+						this.initialization.computeConversion(scope, variableType, initializationType);
+						if (this.initialization instanceof CastExpression
+								&& (this.initialization.bits & ASTNode.UnnecessaryCast) == 0) {
+							CastExpression.checkNeedForAssignedCast(scope, variableType, (CastExpression) this.initialization);
+						}
+					} else {
+						if ((variableType.tagBits & TagBits.HasMissingType) == 0) {
+							// if problem already got signaled on type, do not report secondary problem
+							scope.problemReporter().typeMismatchError(initializationType, variableType, this.initialization, null);
+						}
+					}
+				}
+			}
+			// check for assignment with no effect
+			if (this.binding == Expression.getDirectBinding(this.initialization)) {
+				scope.problemReporter().assignmentHasNoEffect(this, this.name);
+			}
+			// change the constant in the binding when it is final
+			// (the optimization of the constant propagation will be done later on)
+			// cast from constant actual type to variable type
+			this.binding.setConstant(
+				this.binding.isFinal()
+					? this.initialization.constant.castTo((variableType.id << 4) + this.initialization.constant.typeID())
+					: Constant.NotAConstant);
+		}
+		// only resolve annotation at the end, for constant to be positioned before (96991)
+		resolveAnnotations(scope, this.annotations, this.binding);
+		scope.validateNullAnnotation(this.binding.tagBits, this.type, this.annotations);
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, scope);
+			}
+			this.type.traverse(visitor, scope);
+			if (this.initialization != null)
+				this.initialization.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
new file mode 100644
index 0000000..87ca75c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.LongConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+public class LongLiteral extends NumberLiteral {
+
+	private static final char[] HEXA_MIN_VALUE        = "0x8000000000000000L".toCharArray(); //$NON-NLS-1$
+	private static final char[] HEXA_MINUS_ONE_VALUE  = "0xffffffffffffffffL".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MIN_VALUE       = "01000000000000000000000L".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MINUS_ONE_VALUE = "01777777777777777777777L".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MIN_VALUE     = "9223372036854775808L".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MAX_VALUE     = "9223372036854775807L".toCharArray(); //$NON-NLS-1$
+
+	private char[] reducedForm; // no underscores
+
+	public static LongLiteral buildLongLiteral(char[] token, int s, int e) {
+		// remove '_' and prefix '0' first
+		char[] longReducedToken = removePrefixZerosAndUnderscores(token, true);
+		switch(longReducedToken.length) {
+			case 19 :
+				// 0x8000000000000000L
+				if (CharOperation.equals(longReducedToken, HEXA_MIN_VALUE)) {
+					return new LongLiteralMinValue(token, longReducedToken != token ? longReducedToken : null, s, e);
+				}
+				break;
+			case 24 :
+				// 01000000000000000000000L
+				if (CharOperation.equals(longReducedToken, OCTAL_MIN_VALUE)) {
+					return new LongLiteralMinValue(token, longReducedToken != token ? longReducedToken : null, s, e);
+				}
+				break;
+		}
+		return new LongLiteral(token, longReducedToken != token ? longReducedToken : null, s, e);
+	}
+
+LongLiteral(char[] token, char[] reducedForm, int start, int end) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
+}
+public LongLiteral convertToMinValue() {
+	if (((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+		return this;
+	}
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	switch(token.length) {
+		case 20 :
+			// 9223372036854775808L
+			if (CharOperation.equals(token, DECIMAL_MIN_VALUE, false)) {
+				return new LongLiteralMinValue(this.source, this.reducedForm, this.sourceStart, this.sourceEnd);
+			}
+			break;
+	}
+	return this;
+}
+public void computeConstant() {
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	int tokenLength = token.length;
+	int length = tokenLength - 1;
+	int radix = 10;
+	int j = 0;
+	if (token[0] == '0') {
+		if (length == 1) {
+			this.constant = LongConstant.fromValue(0L);
+			return;
+		}
+		if ((token[1] == 'x') || (token[1] == 'X')) {
+			radix = 16;
+			j = 2;
+		} else if ((token[1] == 'b') || (token[1] == 'B')) {
+			radix = 2;
+			j = 2;
+		} else {
+			radix = 8;
+			j = 1;
+		}
+	}
+	switch(radix) {
+		case 2 :
+			if ((length - 2) > 64) { // remove 0b or 0B
+				return; /*constant stays null*/
+			}
+			computeValue(token, length, radix, j);
+			break;
+		case 16 :
+			if (tokenLength <= 19) {
+				if (CharOperation.equals(token, HEXA_MINUS_ONE_VALUE)) {
+					this.constant = LongConstant.fromValue(-1L);
+					return;
+				}
+				computeValue(token, length, radix, j);
+			}
+			break;
+		case 10 :
+			if (tokenLength > DECIMAL_MAX_VALUE.length
+					|| (tokenLength == DECIMAL_MAX_VALUE.length
+							&& CharOperation.compareTo(token, DECIMAL_MAX_VALUE, 0, length) > 0)) {
+				return; /*constant stays null*/
+			}
+			computeValue(token, length, radix, j);
+			break;
+		case 8 :
+			if (tokenLength <= 24) {
+				if (tokenLength == 24 && token[j] > '1') {
+					return; /*constant stays null*/
+				}
+				if (CharOperation.equals(token, OCTAL_MINUS_ONE_VALUE)) {
+					this.constant = LongConstant.fromValue(-1L);
+					return;
+				}
+				computeValue(token, length, radix, j);
+			}
+			break;
+	}
+}
+private void computeValue(char[] token, int tokenLength, int radix, int j) {
+	int digitValue;
+	long computedValue = 0;
+	while (j < tokenLength) {
+		if ((digitValue = ScannerHelper.digit(token[j++],radix)) < 0) {
+			return; /*constant stays null*/
+		}
+		computedValue = (computedValue * radix) + digitValue ;
+	}
+	this.constant = LongConstant.fromValue(computedValue);
+}
+/**
+ * Code generation for long literal
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.LONG;
+}
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
new file mode 100644
index 0000000..962b874
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.impl.*;
+
+public class LongLiteralMinValue extends LongLiteral {
+
+	final static char[] CharValue = new char[]{'-', '9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8','L'};
+
+public LongLiteralMinValue(char[] token, char[] reducedForm, int start, int end) {
+	super(token, reducedForm, start, end);
+	this.constant = LongConstant.fromValue(Long.MIN_VALUE);
+}
+public void computeConstant() {
+	/*precomputed at creation time*/}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
new file mode 100644
index 0000000..7eb9111
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+public abstract class  MagicLiteral extends Literal {
+
+	public MagicLiteral(int start , int end) {
+
+		super(start,end);
+	}
+
+	public boolean isValidJavaStatement(){
+
+		return false ;
+	}
+
+	public char[] source() {
+
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java
new file mode 100644
index 0000000..eae5b91
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+/*
+ * Created on 2004-03-11
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class MarkerAnnotation extends Annotation {
+
+	public MarkerAnnotation(TypeReference type, int sourceStart) {
+		this.type = type;
+		this.sourceStart = sourceStart;
+		this.sourceEnd = type.sourceEnd;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.Annotation#memberValuePairs()
+	 */
+	public MemberValuePair[] memberValuePairs() {
+		return NoValuePairs;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
new file mode 100644
index 0000000..21871fe
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/**
+ * MemberValuePair node
+ */
+public class MemberValuePair extends ASTNode {
+
+	public char[] name;
+	public Expression value;
+	public MethodBinding binding;
+	/**
+	 *  The representation of this pair in the type system.
+	 */
+	public ElementValuePair compilerElementPair = null;
+
+	public MemberValuePair(char[] token, int sourceStart, int sourceEnd, Expression value) {
+		this.name = token;
+		this.sourceStart = sourceStart;
+		this.sourceEnd = sourceEnd;
+		this.value = value;
+		if (value instanceof ArrayInitializer) {
+			value.bits |= IsAnnotationDefaultValue;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.ASTNode#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer print(int indent, StringBuffer output) {
+		output
+			.append(this.name)
+			.append(" = "); //$NON-NLS-1$
+		this.value.print(0, output);
+		return output;
+	}
+
+	public void resolveTypeExpecting(BlockScope scope, TypeBinding requiredType) {
+
+		if (this.value == null) {
+			this.compilerElementPair = new ElementValuePair(this.name, this.value, this.binding);
+			return;
+		}
+		if (requiredType == null) {
+			// fault tolerance: keep resolving
+			if (this.value instanceof ArrayInitializer) {
+				this.value.resolveTypeExpecting(scope, null);
+			} else {
+				this.value.resolveType(scope);
+			}
+			this.compilerElementPair = new ElementValuePair(this.name, this.value, this.binding);
+			return;
+		}
+
+		this.value.setExpectedType(requiredType); // needed in case of generic method invocation - looks suspect, generic method invocation here ???
+		TypeBinding valueType;
+		if (this.value instanceof ArrayInitializer) {
+			ArrayInitializer initializer = (ArrayInitializer) this.value;
+			valueType = initializer.resolveTypeExpecting(scope, this.binding.returnType);
+		} else if (this.value instanceof ArrayAllocationExpression) {
+			scope.problemReporter().annotationValueMustBeArrayInitializer(this.binding.declaringClass, this.name, this.value);
+			this.value.resolveType(scope);
+			valueType = null; // no need to pursue
+		} else {
+			valueType = this.value.resolveType(scope);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=248897
+			ASTVisitor visitor = new ASTVisitor() {
+				public boolean visit(SingleNameReference reference, BlockScope scop) {
+					if (reference.binding instanceof LocalVariableBinding) {
+						((LocalVariableBinding) reference.binding).useFlag = LocalVariableBinding.USED;
+					}
+					return true;
+				}
+			};
+			this.value.traverse(visitor, scope);
+		}
+		this.compilerElementPair = new ElementValuePair(this.name, this.value, this.binding);
+		if (valueType == null)
+			return;
+
+		TypeBinding leafType = requiredType.leafComponentType();
+		if (!(this.value.isConstantValueOfTypeAssignableToType(valueType, requiredType)
+				|| valueType.isCompatibleWith(requiredType))) {
+
+			if (!(requiredType.isArrayType()
+					&& requiredType.dimensions() == 1
+					&& (this.value.isConstantValueOfTypeAssignableToType(valueType, leafType)
+							|| valueType.isCompatibleWith(leafType)))) {
+
+				if (leafType.isAnnotationType() && !valueType.isAnnotationType()) {
+					scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, this.value, leafType);
+				} else {
+					scope.problemReporter().typeMismatchError(valueType, requiredType, this.value, null);
+				}
+				return; // may allow to proceed to find more errors at once
+			}
+		} else {
+			scope.compilationUnitScope().recordTypeConversion(requiredType.leafComponentType(), valueType.leafComponentType());
+			this.value.computeConversion(scope, requiredType, valueType);
+		}
+
+		// annotation methods can only return base types, String, Class, enum type, annotation types and arrays of these
+		checkAnnotationMethodType: {
+			switch (leafType.erasure().id) {
+				case T_byte :
+				case T_short :
+				case T_char :
+				case T_int :
+				case T_long :
+				case T_float :
+				case T_double :
+				case T_boolean :
+				case T_JavaLangString :
+					if (this.value instanceof ArrayInitializer) {
+						ArrayInitializer initializer = (ArrayInitializer) this.value;
+						final Expression[] expressions = initializer.expressions;
+						if (expressions != null) {
+							for (int i =0, max = expressions.length; i < max; i++) {
+								Expression expression = expressions[i];
+								if (expression.resolvedType == null) continue; // fault-tolerance
+								if (expression.constant == Constant.NotAConstant) {
+									scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, expressions[i], false);
+								}
+							}
+						}
+					} else if (this.value.constant == Constant.NotAConstant) {
+						if (valueType.isArrayType()) {
+							scope.problemReporter().annotationValueMustBeArrayInitializer(this.binding.declaringClass, this.name, this.value);
+						} else {
+							scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, this.value, false);
+						}
+					}
+					break checkAnnotationMethodType;
+				case T_JavaLangClass :
+					if (this.value instanceof ArrayInitializer) {
+						ArrayInitializer initializer = (ArrayInitializer) this.value;
+						final Expression[] expressions = initializer.expressions;
+						if (expressions != null) {
+							for (int i =0, max = expressions.length; i < max; i++) {
+								Expression currentExpression = expressions[i];
+								if (!(currentExpression instanceof ClassLiteralAccess)) {
+									scope.problemReporter().annotationValueMustBeClassLiteral(this.binding.declaringClass, this.name, currentExpression);
+								}
+							}
+						}
+					} else if (!(this.value instanceof ClassLiteralAccess)) {
+						scope.problemReporter().annotationValueMustBeClassLiteral(this.binding.declaringClass, this.name, this.value);
+					}
+					break checkAnnotationMethodType;
+			}
+			if (leafType.isEnum()) {
+				if (this.value instanceof NullLiteral) {
+					scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, this.value, true);
+				} else if (this.value instanceof ArrayInitializer) {
+					ArrayInitializer initializer = (ArrayInitializer) this.value;
+					final Expression[] expressions = initializer.expressions;
+					if (expressions != null) {
+						for (int i =0, max = expressions.length; i < max; i++) {
+							Expression currentExpression = expressions[i];
+							if (currentExpression instanceof NullLiteral) {
+								scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, currentExpression, true);
+							} else if (currentExpression instanceof NameReference) {
+								NameReference nameReference = (NameReference) currentExpression;
+								final Binding nameReferenceBinding = nameReference.binding;
+								if (nameReferenceBinding.kind() == Binding.FIELD) {
+									FieldBinding fieldBinding = (FieldBinding) nameReferenceBinding;
+									if (!fieldBinding.declaringClass.isEnum()) {
+										scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, currentExpression, true);
+									}
+								}
+							}
+						}
+					}
+				} else if (this.value instanceof NameReference) {
+					NameReference nameReference = (NameReference) this.value;
+					final Binding nameReferenceBinding = nameReference.binding;
+					if (nameReferenceBinding.kind() == Binding.FIELD) {
+						FieldBinding fieldBinding = (FieldBinding) nameReferenceBinding;
+						if (!fieldBinding.declaringClass.isEnum()) {
+							if (!fieldBinding.type.isArrayType()) {
+								scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, this.value, true);
+							} else {
+								scope.problemReporter().annotationValueMustBeArrayInitializer(this.binding.declaringClass, this.name, this.value);
+							}
+						}
+					}
+				}  else {
+					scope.problemReporter().annotationValueMustBeConstant(this.binding.declaringClass, this.name, this.value, true);
+				}
+				break checkAnnotationMethodType;
+			}
+			if (leafType.isAnnotationType()) {
+				if (!valueType.leafComponentType().isAnnotationType()) { // check annotation type and also reject null literal
+					scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, this.value, leafType);
+				} else if (this.value instanceof ArrayInitializer) {
+					ArrayInitializer initializer = (ArrayInitializer) this.value;
+					final Expression[] expressions = initializer.expressions;
+					if (expressions != null) {
+						for (int i =0, max = expressions.length; i < max; i++) {
+							Expression currentExpression = expressions[i];
+							if (currentExpression instanceof NullLiteral || !(currentExpression instanceof Annotation)) {
+								scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, currentExpression, leafType);
+							}
+						}
+					}
+				} else if (!(this.value instanceof Annotation)) {
+					scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, this.value, leafType);
+				}
+				break checkAnnotationMethodType;
+			}
+		}
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.value != null) {
+				this.value.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.value != null) {
+				this.value.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..b379cf5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -0,0 +1,901 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 379784 - [compiler] "Method can be static" is not getting reported
+ *								bug 379834 - Wrong "method can be static" in presence of qualified super and different staticness of nested super class.
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *								bug 381445 - [compiler][resource] Can the resource leak check be made aware of Closeables.closeQuietly?
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *								bug 382350 - [1.8][compiler] Unable to invoke inherited default method via I.super.m() syntax
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.ImplicitNullAnnotationVerifier;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class MessageSend extends Expression implements InvocationSite {
+
+	public Expression receiver;
+	public char[] selector;
+	public Expression[] arguments;
+	public MethodBinding binding;							// exact binding resulting from lookup
+	public MethodBinding syntheticAccessor;						// synthetic accessor for inner-emulation
+	public TypeBinding expectedType;					// for generic method invocation (return type inference)
+
+	public long nameSourcePosition ; //(start<<32)+end
+
+	public TypeBinding actualReceiverType;
+	public TypeBinding valueCast; // extra reference type cast to perform on method returned value
+	public TypeReference[] typeArguments;
+	public TypeBinding[] genericTypeArguments;
+	private ExpressionContext expressionContext = VANILLA_CONTEXT;
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	boolean nonStatic = !this.binding.isStatic();
+	boolean wasInsideAssert = ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0);
+	flowInfo = this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic).unconditionalInits();
+
+	// recording the closing of AutoCloseable resources:
+	boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+	if (analyseResources) {
+		Expression closeTarget = null;
+		if (nonStatic) {
+			// closeable.close()
+			if (CharOperation.equals(TypeConstants.CLOSE, this.selector)) {
+				closeTarget = this.receiver;
+			}
+		} else if (this.arguments != null && this.arguments.length > 0 && FakedTrackingVariable.isAnyCloseable(this.arguments[0].resolvedType)) {
+			// Helper.closeMethod(closeable, ..)
+			for (int i=0; i<TypeConstants.closeMethods.length; i++) {
+				CloseMethodRecord record = TypeConstants.closeMethods[i];
+				if (CharOperation.equals(record.selector, this.selector)
+						&& CharOperation.equals(record.typeName, this.binding.declaringClass.compoundName)) 
+				{
+					closeTarget = this.arguments[0];
+					break;
+				}
+			}
+		}
+		if (closeTarget != null) {
+			FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(closeTarget, flowInfo, flowContext);
+			if (trackingVariable != null) { // null happens if target is not a local variable or not an AutoCloseable
+				if (trackingVariable.methodScope == currentScope.methodScope()) {
+					trackingVariable.markClose(flowInfo, flowContext);
+				} else {
+					trackingVariable.markClosedInNestedMethod();
+				}
+			}
+		}
+	}
+
+	if (nonStatic) {
+		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
+	}
+
+	if (this.arguments != null) {
+		int length = this.arguments.length;
+		for (int i = 0; i < length; i++) {
+			Expression argument = this.arguments[i];
+			argument.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+			switch (detectAssertionUtility(i)) {
+				case TRUE_ASSERTION:
+					flowInfo = analyseBooleanAssertion(currentScope, argument, flowContext, flowInfo, wasInsideAssert, true);
+					break;
+				case FALSE_ASSERTION:
+					flowInfo = analyseBooleanAssertion(currentScope, argument, flowContext, flowInfo, wasInsideAssert, false);
+					break;
+				case NONNULL_ASSERTION:
+					flowInfo = analyseNullAssertion(currentScope, argument, flowContext, flowInfo, false);
+					break;
+				case NULL_ASSERTION:
+					flowInfo = analyseNullAssertion(currentScope, argument, flowContext, flowInfo, true);
+					break;
+				default:
+					flowInfo = argument.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+			}
+			if (analyseResources) {
+				// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, argument, flowInfo, flowContext, false);
+			}
+		}
+		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
+	}
+	ReferenceBinding[] thrownExceptions;
+	if ((thrownExceptions = this.binding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
+		if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+			thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
+		}
+		// must verify that exceptions potentially thrown by this expression are caught in the method
+		flowContext.checkExceptionHandlers(thrownExceptions, this, flowInfo.copy(), currentScope);
+		// TODO (maxime) the copy above is needed because of a side effect into
+		//               checkExceptionHandlers; consider protecting there instead of here;
+		//               NullReferenceTest#test0510
+	}
+	manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+	// account for pot. exceptions thrown by method execution
+	flowContext.recordAbruptExit();
+	flowContext.expireNullCheckedFieldInfo(); // no longer trust this info after any message send
+	return flowInfo;
+}
+
+// classification of well-known assertion utilities:
+private static final int TRUE_ASSERTION = 1;
+private static final int FALSE_ASSERTION = 2;
+private static final int NULL_ASSERTION = 3;
+private static final int NONNULL_ASSERTION = 4;
+
+// is the argument at the given position being checked by a well-known assertion utility?
+// if so answer what kind of assertion we are facing.
+private int detectAssertionUtility(int argumentIdx) {
+	TypeBinding[] parameters = this.binding.original().parameters;
+	if (argumentIdx < parameters.length) {
+		TypeBinding parameterType = parameters[argumentIdx];
+		if (this.actualReceiverType != null && parameterType != null) {
+			switch (this.actualReceiverType.id) {
+				case TypeIds.T_OrgEclipseCoreRuntimeAssert:
+					if (parameterType.id == TypeIds.T_boolean)
+						return TRUE_ASSERTION;
+					if (parameterType.id == TypeIds.T_JavaLangObject && CharOperation.equals(TypeConstants.IS_NOTNULL, this.selector))
+						return NONNULL_ASSERTION;
+					break;
+				case TypeIds.T_JunitFrameworkAssert:
+				case TypeIds.T_OrgJunitAssert:
+					if (parameterType.id == TypeIds.T_boolean) {
+						if (CharOperation.equals(TypeConstants.ASSERT_TRUE, this.selector))
+							return TRUE_ASSERTION;
+						if (CharOperation.equals(TypeConstants.ASSERT_FALSE, this.selector))
+							return FALSE_ASSERTION;
+					} else if (parameterType.id == TypeIds.T_JavaLangObject) {
+						if (CharOperation.equals(TypeConstants.ASSERT_NOTNULL, this.selector))
+							return NONNULL_ASSERTION;
+						if (CharOperation.equals(TypeConstants.ASSERT_NULL, this.selector))
+							return NULL_ASSERTION;
+					}
+					break;
+				case TypeIds.T_OrgApacheCommonsLangValidate:
+					if (parameterType.id == TypeIds.T_boolean) {
+						if (CharOperation.equals(TypeConstants.IS_TRUE, this.selector))
+							return TRUE_ASSERTION;
+					} else if (parameterType.id == TypeIds.T_JavaLangObject) {
+						if (CharOperation.equals(TypeConstants.NOT_NULL, this.selector))
+							return NONNULL_ASSERTION;
+					}
+					break;
+				case TypeIds.T_OrgApacheCommonsLang3Validate:
+					if (parameterType.id == TypeIds.T_boolean) {
+						if (CharOperation.equals(TypeConstants.IS_TRUE, this.selector))
+							return TRUE_ASSERTION;
+					} else if (parameterType.isTypeVariable()) {
+						if (CharOperation.equals(TypeConstants.NOT_NULL, this.selector))
+							return NONNULL_ASSERTION;
+					}
+					break;
+				case TypeIds.T_ComGoogleCommonBasePreconditions:
+					if (parameterType.id == TypeIds.T_boolean) {
+						if (CharOperation.equals(TypeConstants.CHECK_ARGUMENT, this.selector)
+							|| CharOperation.equals(TypeConstants.CHECK_STATE, this.selector))
+							return TRUE_ASSERTION;
+					} else if (parameterType.isTypeVariable()) {
+						if (CharOperation.equals(TypeConstants.CHECK_NOT_NULL, this.selector))
+							return NONNULL_ASSERTION;
+					}
+					break;					
+				case TypeIds.T_JavaUtilObjects:
+					if (parameterType.isTypeVariable()) {
+						if (CharOperation.equals(TypeConstants.REQUIRE_NON_NULL, this.selector))
+							return NONNULL_ASSERTION;
+					}
+					break;					
+			}
+		}
+	}
+	return 0;
+}
+private FlowInfo analyseBooleanAssertion(BlockScope currentScope, Expression argument,
+		FlowContext flowContext, FlowInfo flowInfo, boolean wasInsideAssert, boolean passOnTrue)
+{
+	Constant cst = argument.optimizedBooleanConstant();
+	boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true;
+	boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false;
+	int tagBitsSave = flowContext.tagBits;
+	flowContext.tagBits |= FlowContext.HIDE_NULL_COMPARISON_WARNING;
+	if (!passOnTrue)
+		flowContext.tagBits |= FlowContext.INSIDE_NEGATION; // this affects syntactic analysis for fields in EqualExpression
+	FlowInfo conditionFlowInfo = argument.analyseCode(currentScope, flowContext, flowInfo.copy());
+	flowContext.extendTimeToLiveForNullCheckedField(2); // survive this assert as a MessageSend and as a Statement
+	flowContext.tagBits = tagBitsSave;
+
+	UnconditionalFlowInfo assertWhenPassInfo;
+	FlowInfo assertWhenFailInfo;
+	boolean isOptimizedPassing;
+	boolean isOptimizedFailing;
+	if (passOnTrue) {
+		assertWhenPassInfo = conditionFlowInfo.initsWhenTrue().unconditionalInits();
+		assertWhenFailInfo = conditionFlowInfo.initsWhenFalse();
+		isOptimizedPassing = isOptimizedTrueAssertion;
+		isOptimizedFailing = isOptimizedFalseAssertion;
+	} else {
+		assertWhenPassInfo = conditionFlowInfo.initsWhenFalse().unconditionalInits();
+		assertWhenFailInfo = conditionFlowInfo.initsWhenTrue();
+		isOptimizedPassing = isOptimizedFalseAssertion;
+		isOptimizedFailing = isOptimizedTrueAssertion;
+	}
+	if (isOptimizedPassing) {
+		assertWhenFailInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+	}
+	if (!isOptimizedFailing) {
+		// if assertion is not failing for sure, only then it makes sense to carry the flow info ahead.
+		// if the code does reach ahead, it means the assert didn't cause an exit, and so
+		// the expression inside it shouldn't change the prior flowinfo
+		// viz. org.eclipse.core.runtime.Assert.isLegal(false && o != null)
+		
+		// keep the merge from the initial code for the definite assignment
+		// analysis, tweak the null part to influence nulls downstream
+		flowInfo = flowInfo.mergedWith(assertWhenFailInfo.nullInfoLessUnconditionalCopy()).
+			addInitializationsFrom(assertWhenPassInfo.discardInitializationInfo());
+	}
+	return flowInfo;
+}
+private FlowInfo analyseNullAssertion(BlockScope currentScope, Expression argument,
+		FlowContext flowContext, FlowInfo flowInfo, boolean expectingNull)
+{
+	int nullStatus = argument.nullStatus(flowInfo, flowContext);
+	boolean willFail = (nullStatus == (expectingNull ? FlowInfo.NON_NULL : FlowInfo.NULL));
+	flowInfo = argument.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+	LocalVariableBinding local = argument.localVariableBinding();
+	if (local != null) {// beyond this point the argument can only be null/nonnull
+		if (expectingNull) 
+			flowInfo.markAsDefinitelyNull(local);
+		else 
+			flowInfo.markAsDefinitelyNonNull(local);
+	} else {
+		if (!expectingNull
+			&& argument instanceof Reference 
+			&& currentScope.compilerOptions().enableSyntacticNullAnalysisForFields) 
+		{
+			FieldBinding field = ((Reference)argument).lastFieldBinding();
+			if (field != null && (field.type.tagBits & TagBits.IsBaseType) == 0) {
+				flowContext.recordNullCheckedFieldReference((Reference) argument, 3); // survive this assert as a MessageSend and as a Statement
+			}
+		}
+	}
+	if (willFail)
+		flowInfo.setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+	return flowInfo;
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	// message send as a receiver
+	if ((nullStatus(flowInfo, flowContext) & FlowInfo.POTENTIALLY_NULL) != 0) // note that flowInfo is not used inside nullStatus(..)
+		scope.problemReporter().messageSendPotentialNullReference(this.binding, this);
+	return true; // done all possible checking
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+	if (runtimeTimeType == null || compileTimeType == null)
+		return;
+	// set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
+	if (this.binding != null && this.binding.isValidBinding()) {
+		MethodBinding originalBinding = this.binding.original();
+		TypeBinding originalType = originalBinding.returnType;
+	    // extra cast needed if method return type is type variable
+		if (originalType.leafComponentType().isTypeVariable()) {
+	    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
+	    		? compileTimeType  // unboxing: checkcast before conversion
+	    		: runtimeTimeType;
+	        this.valueCast = originalType.genericCast(targetType);
+		} 	else if (this.binding == scope.environment().arrayClone
+				&& runtimeTimeType.id != TypeIds.T_JavaLangObject
+				&& scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+					// from 1.5 source level on, array#clone() resolves to array type, but codegen to #clone()Object - thus require extra inserted cast
+			this.valueCast = runtimeTimeType;
+		}
+        if (this.valueCast instanceof ReferenceBinding) {
+			ReferenceBinding referenceCast = (ReferenceBinding) this.valueCast;
+			if (!referenceCast.canBeSeenBy(scope)) {
+	        	scope.problemReporter().invalidType(this,
+	        			new ProblemReferenceBinding(
+							CharOperation.splitOn('.', referenceCast.shortReadableName()),
+							referenceCast,
+							ProblemReasons.NotVisible));
+			}
+        }
+	}
+	super.computeConversion(scope, runtimeTimeType, compileTimeType);
+}
+
+/**
+ * MessageSend code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	// generate receiver/enclosing instance access
+	MethodBinding codegenBinding = this.binding instanceof PolymorphicMethodBinding ? this.binding : this.binding.original();
+	boolean isStatic = codegenBinding.isStatic();
+	if (isStatic) {
+		this.receiver.generateCode(currentScope, codeStream, false);
+	} else if ((this.bits & ASTNode.DepthMASK) != 0 && this.receiver.isImplicitThis()) { // outer access ?
+		// outer method can be reached through emulation if implicit access
+		ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+		Object[] path = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+		codeStream.generateOuterAccess(path, this, targetType, currentScope);
+	} else {
+		this.receiver.generateCode(currentScope, codeStream, true);
+		if ((this.bits & NeedReceiverGenericCast) != 0) {
+			codeStream.checkcast(this.actualReceiverType);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+	// generate arguments
+	generateArguments(this.binding, this.arguments, currentScope, codeStream);
+	pc = codeStream.position;
+	// actual message invocation
+	if (this.syntheticAccessor == null){
+		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+		if (isStatic){
+			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
+		} else if((this.receiver.isSuper()) || codegenBinding.isPrivate()){
+			codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
+		} else if (constantPoolDeclaringClass.isInterface()) { // interface or annotation type
+			codeStream.invoke(Opcodes.OPC_invokeinterface, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokevirtual, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
+		}
+	} else {
+		codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessor, null /* default declaringClass */);
+	}
+	// required cast must occur even if no value is required
+	if (this.valueCast != null) codeStream.checkcast(this.valueCast);
+	if (valueRequired){
+		// implicit conversion if necessary
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else {
+		boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+		// conversion only generated if unboxing
+		if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+		switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.returnType.id) {
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			case T_void :
+				break;
+			default :
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return this.genericTypeArguments;
+}
+
+public boolean isSuperAccess() {
+	return this.receiver.isSuper();
+}
+public boolean isTypeAccess() {
+	return this.receiver != null && this.receiver.isTypeReference();
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo){
+
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
+
+	// if method from parameterized type got found, use the original method at codegen time
+	MethodBinding codegenBinding = this.binding.original();
+	if (this.binding.isPrivate()){
+
+		// depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy)
+		if (currentScope.enclosingSourceType() != codegenBinding.declaringClass){
+			this.syntheticAccessor = ((SourceTypeBinding)codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, false /* not super access there */);
+			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+			return;
+		}
+
+	} else if (this.receiver instanceof QualifiedSuperReference) { 	// qualified super
+		if (this.actualReceiverType.isInterface()) 
+			return; // invoking an overridden default method, which is accessible/public by definition
+		// qualified super need emulation always
+		SourceTypeBinding destinationType = (SourceTypeBinding)(((QualifiedSuperReference)this.receiver).currentCompatibleType);
+		this.syntheticAccessor = destinationType.addSyntheticMethod(codegenBinding, isSuperAccess());
+		currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+		return;
+
+	} else if (this.binding.isProtected()){
+
+		SourceTypeBinding enclosingSourceType;
+		if (((this.bits & ASTNode.DepthMASK) != 0)
+				&& codegenBinding.declaringClass.getPackage()
+					!= (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()){
+
+			SourceTypeBinding currentCompatibleType = (SourceTypeBinding)enclosingSourceType.enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+			this.syntheticAccessor = currentCompatibleType.addSyntheticMethod(codegenBinding, isSuperAccess());
+			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+			return;
+		}
+	}
+}
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	if (this.binding.isValidBinding()) {
+		// try to retrieve null status of this message send from an annotation of the called method:
+		long tagBits = this.binding.tagBits;
+		if ((tagBits & TagBits.AnnotationNonNull) != 0)
+			return FlowInfo.NON_NULL;
+		if ((tagBits & TagBits.AnnotationNullable) != 0)
+			return FlowInfo.POTENTIALLY_NULL | FlowInfo.POTENTIALLY_NON_NULL;
+	}
+	return FlowInfo.UNKNOWN;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
+ */
+public TypeBinding postConversionType(Scope scope) {
+	TypeBinding convertedType = this.resolvedType;
+	if (this.valueCast != null)
+		convertedType = this.valueCast;
+	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	switch (runtimeType) {
+		case T_boolean :
+			convertedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			convertedType = TypeBinding.BYTE;
+			break;
+		case T_short :
+			convertedType = TypeBinding.SHORT;
+			break;
+		case T_char :
+			convertedType = TypeBinding.CHAR;
+			break;
+		case T_int :
+			convertedType = TypeBinding.INT;
+			break;
+		case T_float :
+			convertedType = TypeBinding.FLOAT;
+			break;
+		case T_long :
+			convertedType = TypeBinding.LONG;
+			break;
+		case T_double :
+			convertedType = TypeBinding.DOUBLE;
+			break;
+		default :
+	}
+	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
+		convertedType = scope.environment().computeBoxingType(convertedType);
+	}
+	return convertedType;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output){
+
+	if (!this.receiver.isImplicitThis()) this.receiver.printExpression(0, output).append('.');
+	if (this.typeArguments != null) {
+		output.append('<');
+		int max = this.typeArguments.length - 1;
+		for (int j = 0; j < max; j++) {
+			this.typeArguments[j].print(0, output);
+			output.append(", ");//$NON-NLS-1$
+		}
+		this.typeArguments[max].print(0, output);
+		output.append('>');
+	}
+	output.append(this.selector).append('(') ;
+	if (this.arguments != null) {
+		for (int i = 0; i < this.arguments.length ; i ++) {
+			if (i > 0) output.append(", "); //$NON-NLS-1$
+			this.arguments[i].printExpression(0, output);
+		}
+	}
+	return output.append(')');
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature return type
+	// Base type promotion
+
+	this.constant = Constant.NotAConstant;
+	boolean receiverCast = false, argsContainCast = false;
+	if (this.receiver instanceof CastExpression) {
+		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+		receiverCast = true;
+	}
+	this.actualReceiverType = this.receiver.resolveType(scope);
+	boolean receiverIsType = this.receiver instanceof NameReference && (((NameReference) this.receiver).bits & Binding.TYPE) != 0;
+	if (receiverCast && this.actualReceiverType != null) {
+		 // due to change of declaring class with receiver type, only identity cast should be notified
+		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+			scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
+		}
+	}
+	// resolve type arguments (for generic constructor call)
+	if (this.typeArguments != null) {
+		int length = this.typeArguments.length;
+		boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5; // typeChecks all arguments
+		this.genericTypeArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			TypeReference typeReference = this.typeArguments[i];
+			if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+				argHasError = true;
+			}
+			if (argHasError && typeReference instanceof Wildcard) {
+				scope.problemReporter().illegalUsageOfWildcard(typeReference);
+			}
+		}
+		if (argHasError) {
+			if (this.arguments != null) { // still attempt to resolve arguments
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					this.arguments[i].resolveType(scope);
+				}
+			}
+			return null;
+		}
+	}
+	// will check for null after args are resolved
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+	boolean polyExpressionSeen = false;
+	if (this.arguments != null) {
+		boolean argHasError = false; // typeChecks all arguments
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		TypeBinding argumentType;
+		for (int i = 0; i < length; i++){
+			Expression argument = this.arguments[i];
+			if (argument instanceof CastExpression) {
+				argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+				argsContainCast = true;
+			}
+			argument.setExpressionContext(INVOCATION_CONTEXT);
+			if ((argumentType = argumentTypes[i] = argument.resolveType(scope)) == null){
+				argHasError = true;
+			}
+			if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+				polyExpressionSeen = true;
+		}
+		if (argHasError) {
+			if (this.actualReceiverType instanceof ReferenceBinding) {
+				//  record a best guess, for clients who need hint about possible method match
+				TypeBinding[] pseudoArgs = new TypeBinding[length];
+				for (int i = length; --i >= 0;)
+					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+				this.binding =
+					this.receiver.isImplicitThis()
+						? scope.getImplicitMethod(this.selector, pseudoArgs, this)
+						: scope.findMethod((ReferenceBinding) this.actualReceiverType, this.selector, pseudoArgs, this);
+				if (this.binding != null && !this.binding.isValidBinding()) {
+					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+					// record the closest match, for clients who may still need hint about possible method match
+					if (closestMatch != null) {
+						if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
+							// shouldn't return generic method outside its context, rather convert it to raw method (175409)
+							closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
+						}
+						this.binding = closestMatch;
+						MethodBinding closestMatchOriginal = closestMatch.original();
+						if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
+							// ignore cases where method is used from within inside itself (e.g. direct recursions)
+							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+						}
+					}
+				}
+			}
+			return null;
+		}
+	}
+	if (this.actualReceiverType == null) {
+		return null;
+	}
+	// base type cannot receive any message
+	if (this.actualReceiverType.isBaseType()) {
+		scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+		return null;
+	}
+	this.binding = this.receiver.isImplicitThis()
+			? scope.getImplicitMethod(this.selector, argumentTypes, this)
+			: scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+	
+	if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+		return null;
+
+	if (!this.binding.isValidBinding()) {
+		if (this.binding.declaringClass == null) {
+			if (this.actualReceiverType instanceof ReferenceBinding) {
+				this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
+			} else {
+				scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+				return null;
+			}
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007 avoid secondary errors in case of
+		// missing super type for anonymous classes ... 
+		ReferenceBinding declaringClass = this.binding.declaringClass;
+		boolean avoidSecondary = declaringClass != null &&
+								 declaringClass.isAnonymousType() &&
+								 declaringClass.superclass() instanceof MissingTypeBinding;
+		if (!avoidSecondary)
+			scope.problemReporter().invalidMethod(this, this.binding);
+		MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+		switch (this.binding.problemId()) {
+			case ProblemReasons.Ambiguous :
+				break; // no resilience on ambiguous
+			case ProblemReasons.NotVisible :
+			case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+			case ProblemReasons.NonStaticReferenceInStaticContext :
+			case ProblemReasons.ReceiverTypeNotVisible :
+			case ProblemReasons.ParameterBoundMismatch :
+				// only steal returnType in cases listed above
+				if (closestMatch != null) this.resolvedType = closestMatch.returnType;
+				break;
+		}
+		// record the closest match, for clients who may still need hint about possible method match
+		if (closestMatch != null) {
+			this.binding = closestMatch;
+			MethodBinding closestMatchOriginal = closestMatch.original();
+			if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
+				// ignore cases where method is used from within inside itself (e.g. direct recursions)
+				closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+			}
+		}
+		return (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) == 0)
+						? this.resolvedType
+						: null;
+	}
+	final CompilerOptions compilerOptions = scope.compilerOptions();
+	if (compilerOptions.complianceLevel <= ClassFileConstants.JDK1_6
+			&& this.binding.isPolymorphic()) {
+		scope.problemReporter().polymorphicMethodNotBelow17(this);
+		return null;
+	}
+
+	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
+		// not interested in reporting problems against this.binding:
+		new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations)
+				.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
+	}
+	
+	if (((this.bits & ASTNode.InsideExpressionStatement) != 0)
+			&& this.binding.isPolymorphic()) {
+		// we only set the return type to be void if this method invocation is used inside an expression statement
+		this.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) this.binding, TypeBinding.VOID);
+	}
+	if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
+		scope.problemReporter().missingTypeInMethod(this, this.binding);
+	}
+	if (!this.binding.isStatic()) {
+		// the "receiver" must not be a type
+		if (receiverIsType) {
+			scope.problemReporter().mustUseAStaticMethod(this, this.binding);
+			if (this.actualReceiverType.isRawType()
+					&& (this.receiver.bits & ASTNode.IgnoreRawTypeCheck) == 0
+					&& compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
+				scope.problemReporter().rawTypeReference(this.receiver, this.actualReceiverType);
+			}
+		} else {
+			// handle indirect inheritance thru variable secondary bound
+			// receiver may receive generic cast, as part of implicit conversion
+			TypeBinding oldReceiverType = this.actualReceiverType;
+			this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(this.binding.declaringClass);
+			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
+			if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+				this.bits |= NeedReceiverGenericCast;
+			}
+		}
+	} else {
+		// static message invoked through receiver? legal but unoptimal (optional warning).
+		if (!(this.receiver.isImplicitThis() || this.receiver.isSuper() || receiverIsType)) {
+			scope.problemReporter().nonStaticAccessToStaticMethod(this, this.binding);
+		}
+		if (!this.receiver.isImplicitThis() && this.binding.declaringClass != this.actualReceiverType) {
+			scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
+		}
+	}
+	if (checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+		this.bits |= ASTNode.Unchecked;
+	}
+
+	//-------message send that are known to fail at compile time-----------
+	if (this.binding.isAbstract()) {
+		if (this.receiver.isSuper()) {
+			scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
+		}
+		// abstract private methods cannot occur nor abstract static............
+	}
+	if (isMethodUseDeprecated(this.binding, scope, true))
+		scope.problemReporter().deprecatedMethod(this.binding, this);
+
+	// from 1.5 source level on, array#clone() returns the array type (but binding still shows Object)
+	if (this.binding == scope.environment().arrayClone && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5) {
+		this.resolvedType = this.actualReceiverType;
+	} else {
+		TypeBinding returnType;
+		if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+			returnType = this.binding.returnType;
+			if (returnType != null) {
+				returnType = scope.environment().convertToRawType(returnType.erasure(), true);
+			}
+		} else {
+			returnType = this.binding.returnType;
+			if (returnType != null) {
+				returnType = returnType.capture(scope, this.sourceEnd);
+			}
+		}
+		this.resolvedType = returnType;
+	}
+	if (this.receiver.isSuper() && compilerOptions.getSeverity(CompilerOptions.OverridingMethodWithoutSuperInvocation) != ProblemSeverities.Ignore) {
+		final ReferenceContext referenceContext = scope.methodScope().referenceContext;
+		if (referenceContext instanceof AbstractMethodDeclaration) {
+			final AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) referenceContext;
+			MethodBinding enclosingMethodBinding = abstractMethodDeclaration.binding;
+			if (enclosingMethodBinding.isOverriding()
+					&& CharOperation.equals(this.binding.selector, enclosingMethodBinding.selector)
+					&& this.binding.areParametersEqual(enclosingMethodBinding)) {
+				abstractMethodDeclaration.bits |= ASTNode.OverridingMethodWithSupercall;
+			}
+		}
+	}
+	if (this.receiver.isSuper() && this.actualReceiverType.isInterface()) {
+		// 15.12.3 (Java 8)
+		scope.checkAppropriateMethodAgainstSupers(this.selector, this.binding, argumentTypes, this);
+	}
+	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
+	}
+	return (this.resolvedType.tagBits & TagBits.HasMissingType) == 0
+				? this.resolvedType
+				: null;
+}
+
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	if (receiverType == null) return; // error scenario only
+	this.actualReceiverType = receiverType;
+}
+public void setDepth(int depth) {
+	this.bits &= ~ASTNode.DepthMASK; // flush previous depth if any
+	if (depth > 0) {
+		this.bits |= (depth & 0xFF) << ASTNode.DepthSHIFT; // encoded on 8 bits
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void setExpectedType(TypeBinding expectedType) {
+    this.expectedType = expectedType;
+}
+
+public void setExpressionContext(ExpressionContext context) {
+	this.expressionContext = context;
+}
+
+public boolean isPolyExpression() {
+	
+	/* 15.12 has four requirements: 1) The invocation appears in an assignment context or an invocation context
+       2) The invocation elides NonWildTypeArguments 3) the method to be invoked is a generic method (8.4.4).
+       4) The return type of the method to be invoked mentions at least one of the method's type parameters.
+
+       We are in no position to ascertain the last two until after resolution has happened. So no client should
+       depend on asking this question before resolution.
+	*/
+	if (this.expressionContext != ASSIGNMENT_CONTEXT && this.expressionContext != INVOCATION_CONTEXT)
+		return false;
+	
+	if (this.typeArguments != null && this.typeArguments.length > 0)
+		return false;
+	
+	if (this.constant != Constant.NotAConstant)
+		throw new UnsupportedOperationException("Unresolved MessageSend can't be queried if it is a polyexpression"); //$NON-NLS-1$
+	
+	if (this.binding != null && this.binding instanceof ParameterizedGenericMethodBinding) {
+		ParameterizedGenericMethodBinding pgmb = (ParameterizedGenericMethodBinding) this.binding;
+		return pgmb.inferredReturnType;
+	}
+	
+	return false;
+}
+
+public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+	return isPolyExpression() ? !t.isBaseType() && s.isBaseType() : super.tIsMoreSpecific(t, s);
+}
+
+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)) {
+		this.receiver.traverse(visitor, blockScope);
+		if (this.typeArguments != null) {
+			for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+				this.typeArguments[i].traverse(visitor, blockScope);
+			}
+		}
+		if (this.arguments != null) {
+			int argumentsLength = this.arguments.length;
+			for (int i = 0; i < argumentsLength; i++)
+				this.arguments[i].traverse(visitor, blockScope);
+		}
+	}
+	visitor.endVisit(this, blockScope);
+}
+public boolean statementExpression() {
+	return true;
+}
+public boolean receiverIsImplicitThis() {
+	return this.receiver.isImplicitThis();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
new file mode 100644
index 0000000..f6aacc7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -0,0 +1,360 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
+
+public class MethodDeclaration extends AbstractMethodDeclaration {
+
+	public TypeReference returnType;
+	public TypeParameter[] typeParameters;
+
+	/**
+	 * MethodDeclaration constructor comment.
+	 */
+	public MethodDeclaration(CompilationResult compilationResult) {
+		super(compilationResult);
+		this.bits |= ASTNode.CanBeStatic; // Start with this assumption, will course correct during resolve and analyseCode.
+	}
+
+	public void analyseCode(ClassScope classScope, FlowContext flowContext, FlowInfo flowInfo) {
+		// starting of the code analysis for methods
+		if (this.ignoreFurtherInvestigation)
+			return;
+		try {
+			if (this.binding == null)
+				return;
+
+			if (!this.binding.isUsed() && !this.binding.isAbstract()) {
+				if (this.binding.isPrivate()
+					|| (((this.binding.modifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == 0)
+						&& this.binding.isOrEnclosedByPrivateType())) {
+					if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+						this.scope.problemReporter().unusedPrivateMethod(this);
+					}
+				}
+			}
+
+			// skip enum implicit methods
+			if (this.binding.declaringClass.isEnum() && (this.selector == TypeConstants.VALUES || this.selector == TypeConstants.VALUEOF))
+				return;
+
+			// may be in a non necessary <clinit> for innerclass with static final constant fields
+			if (this.binding.isAbstract() || this.binding.isNative())
+				return;
+			
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
+			if (this.typeParameters != null &&
+					!this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+				for (int i = 0, length = this.typeParameters.length; i < length; ++i) {
+					TypeParameter typeParameter = this.typeParameters[i];
+					if ((typeParameter.binding.modifiers  & ExtraCompilerModifiers.AccLocallyUsed) == 0) {
+						this.scope.problemReporter().unusedTypeParameter(typeParameter);						
+					}
+				}
+			}
+			ExceptionHandlingFlowContext methodContext =
+				new ExceptionHandlingFlowContext(
+					flowContext,
+					this,
+					this.binding.thrownExceptions,
+					null,
+					this.scope,
+					FlowInfo.DEAD_END);
+
+			// nullity and mark as assigned
+			analyseArguments(flowInfo, this.arguments, this.binding);
+
+			if (this.binding.declaringClass instanceof MemberTypeBinding && !this.binding.declaringClass.isStatic()) {
+				// method of a non-static member type can't be static.
+				this.bits &= ~ASTNode.CanBeStatic;
+			}
+			// propagate to statements
+			if (this.statements != null) {
+				boolean enableSyntacticNullAnalysisForFields = this.scope.compilerOptions().enableSyntacticNullAnalysisForFields;
+				int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0 ? Statement.NOT_COMPLAINED : Statement.COMPLAINED_FAKE_REACHABLE;
+				for (int i = 0, count = this.statements.length; i < count; i++) {
+					Statement stat = this.statements[i];
+					if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
+						flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
+					}
+					if (enableSyntacticNullAnalysisForFields) {
+						methodContext.expireNullCheckedFieldInfo();
+					}
+				}
+			} else {
+				// method with empty body should not be flagged as static.
+				this.bits &= ~ASTNode.CanBeStatic;
+			}
+			// check for missing returning path
+			TypeBinding returnTypeBinding = this.binding.returnType;
+			if ((returnTypeBinding == TypeBinding.VOID) || isAbstract()) {
+				if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+					this.bits |= ASTNode.NeedFreeReturn;
+				}
+			} else {
+				if (flowInfo != FlowInfo.DEAD_END) {
+					this.scope.problemReporter().shouldReturn(returnTypeBinding, this);
+				}
+			}
+			// check unreachable catch blocks
+			methodContext.complainIfUnusedExceptionHandlers(this);
+			// check unused parameters
+			this.scope.checkUnusedParameters(this.binding);
+			// check if the method could have been static
+			if (!this.binding.isStatic() && (this.bits & ASTNode.CanBeStatic) != 0 && !this.isDefaultMethod()) {
+				if(!this.binding.isOverriding() && !this.binding.isImplementing()) {
+					if (this.binding.isPrivate() || this.binding.isFinal() || this.binding.declaringClass.isFinal()) {
+						this.scope.problemReporter().methodCanBeDeclaredStatic(this);
+					} else {
+						this.scope.problemReporter().methodCanBePotentiallyDeclaredStatic(this);
+					}
+				}
+					
+			}
+			this.scope.checkUnclosedCloseables(flowInfo, null, null/*don't report against a specific location*/, null);
+		} catch (AbortMethod e) {
+			this.ignoreFurtherInvestigation = true;
+		}
+	}
+
+	public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
+		AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
+		for (int i = 0, max = this.annotations.length; i < max; i++) {
+			Annotation annotation = this.annotations[i];
+			annotation.traverse(collector, (BlockScope) null);
+		}
+	}
+
+	public boolean isDefaultMethod() {
+		return (this.modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0;
+	}
+
+	public boolean isMethod() {
+		return true;
+	}
+
+	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
+		//fill up the method body with statement
+		parser.parse(this, unit);
+	}
+
+	public StringBuffer printReturnType(int indent, StringBuffer output) {
+		if (this.returnType == null) return output;
+		return this.returnType.printExpression(0, output).append(' ');
+	}
+
+	public void resolveStatements() {
+		// ========= abort on fatal error =============
+		if (this.returnType != null && this.binding != null) {
+			this.bits |= (this.returnType.bits & ASTNode.HasTypeAnnotations);
+			this.returnType.resolvedType = this.binding.returnType;
+			// record the return type binding
+		}
+		// check if method with constructor name
+		if (CharOperation.equals(this.scope.enclosingSourceType().sourceName, this.selector)) {
+			this.scope.problemReporter().methodWithConstructorName(this);
+		}
+		// to check whether the method returns a type parameter not declared by it.
+		boolean returnsUndeclTypeVar = false;
+		if (this.returnType != null && this.returnType.resolvedType instanceof TypeVariableBinding) {
+			returnsUndeclTypeVar = true;
+		}
+		if (this.typeParameters != null) {
+			for (int i = 0, length = this.typeParameters.length; i < length; i++) {
+				TypeParameter typeParameter = this.typeParameters[i];
+				this.bits |= (typeParameter.bits & ASTNode.HasTypeAnnotations);
+				typeParameter.resolve(this.scope);
+				if (returnsUndeclTypeVar && this.typeParameters[i].binding == this.returnType.resolvedType) {
+					returnsUndeclTypeVar = false;
+				}
+			}
+		}
+
+		// check @Override annotation
+		final CompilerOptions compilerOptions = this.scope.compilerOptions();
+		checkOverride: {
+			if (this.binding == null) break checkOverride;
+			long complianceLevel = compilerOptions.complianceLevel;
+			if (complianceLevel < ClassFileConstants.JDK1_5) break checkOverride;
+			int bindingModifiers = this.binding.modifiers;
+			boolean hasOverrideAnnotation = (this.binding.tagBits & TagBits.AnnotationOverride) != 0;
+			boolean hasUnresolvedArguments = (this.binding.tagBits & TagBits.HasUnresolvedArguments) != 0;
+			if (hasOverrideAnnotation  && !hasUnresolvedArguments) {
+				// no static method is considered overriding
+				if ((bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccOverriding)) == ExtraCompilerModifiers.AccOverriding)
+					break checkOverride;
+				//	in 1.5, strictly for overriding superclass method
+				//	in 1.6 and above, also tolerate implementing interface method
+				if (complianceLevel >= ClassFileConstants.JDK1_6
+						&& ((bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccImplementing)) == ExtraCompilerModifiers.AccImplementing))
+					break checkOverride;
+				// claims to override, and doesn't actually do so
+				this.scope.problemReporter().methodMustOverride(this, complianceLevel);
+			} else {
+				//In case of  a concrete class method, we have to check if it overrides(in 1.5 and above) OR implements a method(1.6 and above).
+				//Also check if the method has a signature that is override-equivalent to that of any public method declared in Object.
+				if (!this.binding.declaringClass.isInterface()){
+						if((bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccOverriding)) == ExtraCompilerModifiers.AccOverriding) {
+							this.scope.problemReporter().missingOverrideAnnotation(this);
+						} else {
+							if(complianceLevel >= ClassFileConstants.JDK1_6
+								&& compilerOptions.reportMissingOverrideAnnotationForInterfaceMethodImplementation
+								&& this.binding.isImplementing()) {
+									// actually overrides, but did not claim to do so
+									this.scope.problemReporter().missingOverrideAnnotationForInterfaceMethodImplementation(this);
+							}
+							
+						}
+				}
+				else {	//For 1.6 and above only
+					//In case of a interface class method, we have to check if it overrides a method (isImplementing returns true in case it overrides)
+					//Also check if the method has a signature that is override-equivalent to that of any public method declared in Object.
+					if(complianceLevel >= ClassFileConstants.JDK1_6
+							&& compilerOptions.reportMissingOverrideAnnotationForInterfaceMethodImplementation
+							&& (((bindingModifiers & (ClassFileConstants.AccStatic|ExtraCompilerModifiers.AccOverriding)) == ExtraCompilerModifiers.AccOverriding) || this.binding.isImplementing())){
+						// actually overrides, but did not claim to do so
+						this.scope.problemReporter().missingOverrideAnnotationForInterfaceMethodImplementation(this);
+					}
+				}
+			}
+		}
+
+		switch (TypeDeclaration.kind(this.scope.referenceType().modifiers)) {
+			case TypeDeclaration.ENUM_DECL :
+				if (this.selector == TypeConstants.VALUES) break;
+				if (this.selector == TypeConstants.VALUEOF) break;
+				//$FALL-THROUGH$
+			case TypeDeclaration.CLASS_DECL :
+				// if a method has an semicolon body and is not declared as abstract==>error
+				// native methods may have a semicolon body
+				if ((this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) {
+					if ((this.modifiers & ClassFileConstants.AccNative) == 0)
+						if ((this.modifiers & ClassFileConstants.AccAbstract) == 0)
+							this.scope.problemReporter().methodNeedBody(this);
+				} else {
+					// the method HAS a body --> abstract native modifiers are forbidden
+					if (((this.modifiers & ClassFileConstants.AccNative) != 0) || ((this.modifiers & ClassFileConstants.AccAbstract) != 0))
+						this.scope.problemReporter().methodNeedingNoBody(this);
+					else if (this.binding == null || this.binding.isStatic() || (this.binding.declaringClass instanceof LocalTypeBinding) || returnsUndeclTypeVar) {
+						// Cannot be static for one of the reasons stated above
+						this.bits &= ~ASTNode.CanBeStatic;
+					}
+				}
+				break;
+			case TypeDeclaration.INTERFACE_DECL :
+				if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8
+						&& (this.modifiers & (ExtraCompilerModifiers.AccSemicolonBody | ClassFileConstants.AccAbstract)) == ExtraCompilerModifiers.AccSemicolonBody) {
+					if ((this.modifiers & (ClassFileConstants.AccStatic | ExtraCompilerModifiers.AccDefaultMethod)) != 0) {
+							this.scope.problemReporter().methodNeedBody(this);
+					}
+				}
+				break;
+		}
+		super.resolveStatements();
+
+		// TagBits.OverridingMethodWithSupercall is set during the resolveStatements() call
+		if (compilerOptions.getSeverity(CompilerOptions.OverridingMethodWithoutSuperInvocation) != ProblemSeverities.Ignore) {
+			if (this.binding != null) {
+        		int bindingModifiers = this.binding.modifiers;
+        		if ((bindingModifiers & (ExtraCompilerModifiers.AccOverriding|ExtraCompilerModifiers.AccImplementing)) == ExtraCompilerModifiers.AccOverriding
+        				&& (this.bits & ASTNode.OverridingMethodWithSupercall) == 0) {
+        			this.scope.problemReporter().overridesMethodWithoutSuperInvocation(this.binding);
+        		}
+			}
+		}
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		ClassScope classScope) {
+
+		if (visitor.visit(this, classScope)) {
+			if (this.javadoc != null) {
+				this.javadoc.traverse(visitor, this.scope);
+			}
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, this.scope);
+			}
+			if (this.typeParameters != null) {
+				int typeParametersLength = this.typeParameters.length;
+				for (int i = 0; i < typeParametersLength; i++) {
+					this.typeParameters[i].traverse(visitor, this.scope);
+				}
+			}
+			if (this.returnType != null)
+				this.returnType.traverse(visitor, this.scope);
+			if (this.arguments != null) {
+				int argumentLength = this.arguments.length;
+				for (int i = 0; i < argumentLength; i++)
+					this.arguments[i].traverse(visitor, this.scope);
+			}
+			if (this.thrownExceptions != null) {
+				int thrownExceptionsLength = this.thrownExceptions.length;
+				for (int i = 0; i < thrownExceptionsLength; i++)
+					this.thrownExceptions[i].traverse(visitor, this.scope);
+			}
+			if (this.statements != null) {
+				int statementsLength = this.statements.length;
+				for (int i = 0; i < statementsLength; i++)
+					this.statements[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, classScope);
+	}
+	public TypeParameter[] typeParameters() {
+	    return this.typeParameters;
+	}
+	
+	void validateNullAnnotations() {
+		super.validateNullAnnotations();
+		// null-annotations on the return type?
+		if (this.binding != null)
+			this.scope.validateNullAnnotation(this.binding.tagBits, this.returnType, this.annotations);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
new file mode 100644
index 0000000..bc90626
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *     Jesper S Moller - Contributions for
+ *							bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+
+public abstract class NameReference extends Reference implements InvocationSite {
+
+	public Binding binding; //may be aTypeBinding-aFieldBinding-aLocalVariableBinding
+
+	public TypeBinding actualReceiverType;	// modified receiver type - actual one according to namelookup
+
+	//the error printing
+	//some name reference are build as name reference but
+	//only used as type reference. When it happens, instead of
+	//creating a new object (aTypeReference) we just flag a boolean
+	//This concesion is valuable while there are cases when the NameReference
+	//will be a TypeReference (static message sends.....) and there is
+	//no changeClass in java.
+public NameReference() {
+	this.bits |= Binding.TYPE | Binding.VARIABLE; // restrictiveFlag
+}
+
+/** 
+ * Use this method only when sure that the current reference is <strong>not</strong>
+ * a chain of several fields (QualifiedNameReference with more than one field).
+ * Otherwise use {@link #lastFieldBinding()}.
+ */
+public FieldBinding fieldBinding() {
+	//this method should be sent ONLY after a check against isFieldReference()
+	//check its use doing senders.........
+	return (FieldBinding) this.binding ;
+}
+
+public FieldBinding lastFieldBinding() {
+	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD)
+		return fieldBinding(); // most subclasses only refer to one field anyway
+	return null;
+}
+
+public boolean isSuperAccess() {
+	return false;
+}
+
+public boolean isTypeAccess() {
+	// null is acceptable when we are resolving the first part of a reference
+	return this.binding == null || this.binding instanceof ReferenceBinding;
+}
+
+public boolean isTypeReference() {
+	return this.binding instanceof ReferenceBinding;
+}
+
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	if (receiverType == null) return; // error scenario only
+	this.actualReceiverType = receiverType;
+}
+
+public void setDepth(int depth) {
+	this.bits &= ~DepthMASK; // flush previous depth if any
+	if (depth > 0) {
+		this.bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
+	}
+}
+
+public void setFieldIndex(int index){
+	// ignored
+}
+
+public abstract String unboundReferenceErrorName();
+
+public abstract char[][] getName();
+
+/* Called during code generation to ensure that outer locals's effectively finality is guaranteed. 
+   Aborts if constraints are violated. Due to various complexities, this check is not conveniently
+   implementable in resolve/analyze phases.
+*/
+protected void checkEffectiveFinality(LocalVariableBinding localBinding, Scope scope) {
+	if ((this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+		if (!localBinding.isFinal() && !localBinding.isEffectivelyFinal()) {
+			scope.problemReporter().cannotReferToNonEffectivelyFinalOuterLocal(localBinding, this);
+			throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java
new file mode 100644
index 0000000..381cc9a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Normal annotation node
+ */
+public class NormalAnnotation extends Annotation {
+
+	public MemberValuePair[] memberValuePairs;
+
+	public NormalAnnotation(TypeReference type, int sourceStart) {
+		this.type = type;
+		this.sourceStart = sourceStart;
+		this.sourceEnd = type.sourceEnd;
+	}
+
+	public ElementValuePair[] computeElementValuePairs() {
+		int numberOfPairs = this.memberValuePairs == null ? 0 : this.memberValuePairs.length;
+		if (numberOfPairs == 0)
+			return Binding.NO_ELEMENT_VALUE_PAIRS;
+
+		ElementValuePair[] pairs = new ElementValuePair[numberOfPairs];
+		for (int i = 0; i < numberOfPairs; i++)
+			pairs[i] = this.memberValuePairs[i].compilerElementPair;
+		return pairs;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.Annotation#memberValuePairs()
+	 */
+	public MemberValuePair[] memberValuePairs() {
+		return this.memberValuePairs == null ? NoValuePairs : this.memberValuePairs;
+	}
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		super.printExpression(indent, output);
+		output.append('(');
+		if (this.memberValuePairs != null) {
+			for (int i = 0, max = this.memberValuePairs.length; i < max; i++) {
+				if (i > 0) {
+					output.append(',');
+				}
+				this.memberValuePairs[i].print(indent, output);
+			}
+		}
+		output.append(')');
+		return output;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.memberValuePairs != null) {
+				int memberValuePairsLength = this.memberValuePairs.length;
+				for (int i = 0; i < memberValuePairsLength; i++)
+					this.memberValuePairs[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.memberValuePairs != null) {
+				int memberValuePairsLength = this.memberValuePairs.length;
+				for (int i = 0; i < memberValuePairsLength; i++)
+					this.memberValuePairs[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java
new file mode 100644
index 0000000..d24a3ef
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class NullLiteral extends MagicLiteral {
+
+	static final char[] source = {'n' , 'u' , 'l' , 'l'};
+
+	public NullLiteral(int s , int e) {
+
+		super(s,e);
+	}
+
+	public void computeConstant() {
+
+		this.constant = Constant.NotAConstant;
+	}
+
+	/**
+	 * Code generation for the null literal
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		int pc = codeStream.position;
+		if (valueRequired) {
+			codeStream.aconst_null();
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	public TypeBinding literalType(BlockScope scope) {
+		return TypeBinding.NULL;
+	}
+
+	public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		return FlowInfo.NULL;
+	}
+
+	public Object reusableJSRTarget() {
+		return TypeBinding.NULL;
+	}
+
+	public char[] source() {
+		return source;
+	}
+
+	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/NumberLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
new file mode 100644
index 0000000..f73810e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+public abstract class NumberLiteral extends Literal {
+
+	char[] source;
+
+	public NumberLiteral(char[] token, int s, int e) {
+		this(s,e) ;
+		this.source = token ;
+	}
+
+	public NumberLiteral(int s, int e) {
+		super (s,e) ;
+	}
+
+	public boolean isValidJavaStatement(){
+		return false ;
+	}
+
+	public char[] source(){
+		return this.source;
+	}
+	protected static char[] removePrefixZerosAndUnderscores(char[] token, boolean isLong) {
+		int max = token.length;
+		int start = 0;
+		int end = max - 1;
+		if (isLong) {
+			end--; // remove the 'L' or 'l'
+		}
+		if (max > 1 && token[0] == '0') {
+			if (max > 2 && (token[1] == 'x' || token[1] == 'X')) {
+				start = 2;
+			} else if (max > 2 && (token[1] == 'b' || token[1] == 'B')) {
+				start = 2;
+			} else {
+				start = 1;
+			}
+		}
+		boolean modified = false;
+		boolean ignore = true;
+		loop: for (int i = start; i < max; i++) {
+			char currentChar = token[i];
+			switch(currentChar) {
+				case '0' :
+					// this is a prefix '0'
+					if (ignore && !modified && (i < end)) {
+						modified = true;
+					}
+					break;
+				case '_' :
+					modified = true;
+					break loop;
+				default :
+					ignore = false;
+			}
+		}
+		if (!modified) {
+			return token;
+		}
+		ignore = true;
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(token, 0, start);
+		loop: for (int i = start; i < max; i++) {
+			char currentChar = token[i];
+			switch(currentChar) {
+				case '0' :
+					if (ignore && (i < end)) {
+						// this is a prefix '0'
+						continue loop;
+					}
+					break;
+				case '_' :
+					continue loop;
+				default:
+					ignore = false;
+			}
+			buffer.append(currentChar);
+		}
+		return buffer.toString().toCharArray();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
new file mode 100644
index 0000000..5e81242
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+//dedicated treatment for the ||
+public class OR_OR_Expression extends BinaryExpression {
+
+	int rightInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+	public OR_OR_Expression(Expression left, Expression right, int operator) {
+		super(left, right, operator);
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		Constant cst = this.left.optimizedBooleanConstant();
+		boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+		boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+		if (isLeftOptimizedFalse) {
+			// FALSE || anything
+			 // need to be careful of scenario:
+			//		(x || y) || !z, if passing the left info to the right, it would be swapped by the !
+			FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+			flowContext.expireNullCheckedFieldInfo();
+			mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo);
+			flowContext.expireNullCheckedFieldInfo();
+			this.mergedInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(mergedInfo);
+			return mergedInfo;
+		}
+
+		FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo);
+		if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) == 0)
+			flowContext.expireNullCheckedFieldInfo();
+
+		 // need to be careful of scenario:
+		//		(x || y) || !z, if passing the left info to the right, it would be swapped by the !
+		FlowInfo rightInfo = leftInfo.initsWhenFalse().unconditionalCopy();
+		this.rightInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(rightInfo);
+
+		int previousMode = rightInfo.reachMode();
+		if (isLeftOptimizedTrue){
+			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
+				currentScope.problemReporter().fakeReachable(this.right);
+				rightInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+			}
+		}
+		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
+		if ((flowContext.tagBits & FlowContext.INSIDE_NEGATION) == 0)
+			flowContext.expireNullCheckedFieldInfo();
+		this.left.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		this.right.checkNPEbyUnboxing(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());
+		FlowInfo mergedInfo = FlowInfo.conditional(
+					// merging two true initInfos for such a negative case: if ((t && (b = t)) || f) r = b; // b may not have been initialized
+				leftInfoWhenTrueForMerging.unconditionalInits().mergedWith(
+						rightInfo.safeInitsWhenTrue().setReachMode(previousMode).unconditionalInits()),
+					rightInfo.initsWhenFalse());
+		this.mergedInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+
+	/**
+	 * Code generation for a binary operation
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		int pc = codeStream.position;
+		if (this.constant != Constant.NotAConstant) {
+			// inlined value
+			if (valueRequired)
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+		Constant cst = this.right.constant;
+		if (cst != Constant.NotAConstant) {
+			// <expr> || true --> true
+			if (cst.booleanValue() == true) {
+				this.left.generateCode(currentScope, codeStream, false);
+				if (valueRequired) codeStream.iconst_1();
+			} else {
+				// <expr>|| false --> <expr>
+				this.left.generateCode(currentScope, codeStream, valueRequired);
+			}
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		BranchLabel trueLabel = new BranchLabel(codeStream), endLabel;
+		cst = this.left.optimizedBooleanConstant();
+		boolean leftIsConst = cst != Constant.NotAConstant;
+		boolean leftIsTrue = leftIsConst && cst.booleanValue() == true;
+
+		cst = this.right.optimizedBooleanConstant();
+		boolean rightIsConst = cst != Constant.NotAConstant;
+		boolean rightIsTrue = rightIsConst && cst.booleanValue() == true;
+
+		generateOperands : {
+			if (leftIsConst) {
+				this.left.generateCode(currentScope, codeStream, false);
+				if (leftIsTrue) {
+					break generateOperands; // no need to generate right operand
+				}
+			} else {
+				this.left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, true);
+				// need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
+			}
+			if (this.rightInitStateIndex != -1) {
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+			}
+			if (rightIsConst) {
+				this.right.generateCode(currentScope, codeStream, false);
+			} else {
+				this.right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired);
+			}
+		}
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		/*
+		 * improving code gen for such a case: boolean b = i < 0 || true since
+		 * the label has never been used, we have the inlined value on the
+		 * stack.
+		 */
+		if (valueRequired) {
+			if (leftIsConst && leftIsTrue) {
+				codeStream.iconst_1();
+				codeStream.recordPositionsFrom(codeStream.position, this.left.sourceEnd);
+			} else {
+				if (rightIsConst && rightIsTrue) {
+					codeStream.iconst_1();
+					codeStream.recordPositionsFrom(codeStream.position, this.left.sourceEnd);
+				} else {
+					codeStream.iconst_0();
+				}
+				if (trueLabel.forwardReferenceCount() > 0) {
+					if ((this.bits & IsReturnedValue) != 0) {
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
+						trueLabel.place();
+						codeStream.iconst_1();
+					} else {
+						codeStream.goto_(endLabel = new BranchLabel(codeStream));
+						codeStream.decrStackSize(1);
+						trueLabel.place();
+						codeStream.iconst_1();
+						endLabel.place();
+					}
+				} else {
+					trueLabel.place();
+				}
+			}
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+		} else {
+			trueLabel.place();
+		}
+	}
+
+	/**
+	 * Boolean operator code generation Optimized operations are: ||
+	 */
+	public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+		if (this.constant != Constant.NotAConstant) {
+			super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			return;
+		}
+
+		// <expr> || false --> <expr>
+		Constant cst = this.right.constant;
+		if (cst != Constant.NotAConstant && cst.booleanValue() == false) {
+			int pc = codeStream.position;
+			this.left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		cst = this.left.optimizedBooleanConstant();
+		boolean leftIsConst = cst != Constant.NotAConstant;
+		boolean leftIsTrue = leftIsConst && cst.booleanValue() == true;
+
+		cst = this.right.optimizedBooleanConstant();
+		boolean rightIsConst = cst != Constant.NotAConstant;
+		boolean rightIsTrue = rightIsConst && cst.booleanValue() == true;
+
+		// default case
+		generateOperands : {
+			if (falseLabel == null) {
+				if (trueLabel != null) {
+					// implicit falling through the FALSE case
+					this.left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, !leftIsConst);
+					// need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
+					if (leftIsTrue) {
+						if (valueRequired) codeStream.goto_(trueLabel);
+						codeStream.recordPositionsFrom(codeStream.position, this.left.sourceEnd);
+						break generateOperands; // no need to generate right operand
+					}
+					if (this.rightInitStateIndex != -1) {
+						codeStream.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+					}
+					this.right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired && !rightIsConst);
+					if (valueRequired && rightIsTrue) {
+						codeStream.goto_(trueLabel);
+						codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd);
+					}
+				}
+			} else {
+				// implicit falling through the TRUE case
+				if (trueLabel == null) {
+					BranchLabel internalTrueLabel = new BranchLabel(codeStream);
+					this.left.generateOptimizedBoolean(currentScope, codeStream, internalTrueLabel, null, !leftIsConst);
+					// need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
+					if (leftIsTrue) {
+						internalTrueLabel.place();
+						break generateOperands; // no need to generate right operand
+					}
+					if (this.rightInitStateIndex != -1) {
+						codeStream
+								.addDefinitelyAssignedVariables(currentScope, this.rightInitStateIndex);
+					}
+					this.right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired && !rightIsConst);
+					int pc = codeStream.position;
+					if (valueRequired && rightIsConst && !rightIsTrue) {
+						codeStream.goto_(falseLabel);
+						codeStream.recordPositionsFrom(pc, this.sourceEnd);
+					}
+					internalTrueLabel.place();
+				} else {
+					// no implicit fall through TRUE/FALSE --> should never occur
+				}
+			}
+		}
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+	}
+
+	public boolean isCompactableOperation() {
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.BinaryExpression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public TypeBinding resolveType(BlockScope scope) {
+		TypeBinding result = super.resolveType(scope);
+		// check whether comparing identical expressions
+		Binding leftDirect = Expression.getDirectBinding(this.left);
+		if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) {
+			if (!(this.right instanceof Assignment))
+				scope.problemReporter().comparingIdenticalExpressions(this);
+		}
+		return result;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			this.left.traverse(visitor, scope);
+			this.right.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
new file mode 100644
index 0000000..7835b6f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
@@ -0,0 +1,1567 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Perry James - nullStatus method improvement (165346)
+ *     Stephan Herrmann - Contribution for
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public abstract class OperatorExpression extends Expression implements OperatorIds {
+
+	public static int[][] OperatorSignatures = new int[NumberOfTables][];
+
+	static {classInitialize();}
+
+	/**
+	 * OperatorExpression constructor comment.
+	 */
+	public OperatorExpression() {
+		super();
+	}
+	public static final void classInitialize() {
+		OperatorSignatures[AND] = get_AND();
+		OperatorSignatures[AND_AND] = get_AND_AND();
+		OperatorSignatures[DIVIDE] = get_DIVIDE();
+		OperatorSignatures[EQUAL_EQUAL] = get_EQUAL_EQUAL();
+		OperatorSignatures[GREATER] = get_GREATER();
+		OperatorSignatures[GREATER_EQUAL] = get_GREATER_EQUAL();
+		OperatorSignatures[LEFT_SHIFT] = get_LEFT_SHIFT();
+		OperatorSignatures[LESS] = get_LESS();
+		OperatorSignatures[LESS_EQUAL] = get_LESS_EQUAL();
+		OperatorSignatures[MINUS] = get_MINUS();
+		OperatorSignatures[MULTIPLY] = get_MULTIPLY();
+		OperatorSignatures[OR] = get_OR();
+		OperatorSignatures[OR_OR] = get_OR_OR();
+		OperatorSignatures[PLUS] = get_PLUS();
+		OperatorSignatures[REMAINDER] = get_REMAINDER();
+		OperatorSignatures[RIGHT_SHIFT] = get_RIGHT_SHIFT();
+		OperatorSignatures[UNSIGNED_RIGHT_SHIFT] = get_UNSIGNED_RIGHT_SHIFT();
+		OperatorSignatures[XOR] = get_XOR();
+	}
+
+	public static final String generateTableTestCase(){
+		//return a String which is a java method allowing to test
+		//the non zero entries of all tables
+
+		/*
+		org.eclipse.jdt.internal.compiler.ast.
+		OperatorExpression.generateTableTestCase();
+		*/
+
+		int[] operators = new int[]{AND,AND_AND,DIVIDE,GREATER,GREATER_EQUAL,
+				LEFT_SHIFT,LESS,LESS_EQUAL,MINUS,MULTIPLY,OR,OR_OR,PLUS,REMAINDER,
+				RIGHT_SHIFT,UNSIGNED_RIGHT_SHIFT,XOR};
+
+		class Decode {
+			public  final String constant(int code){
+				switch(code){
+					case T_boolean 	: return "true"; //$NON-NLS-1$
+					case T_byte		: return "((byte) 3)"; //$NON-NLS-1$
+					case T_char		: return "'A'"; //$NON-NLS-1$
+					case T_double	: return "300.0d"; //$NON-NLS-1$
+					case T_float	: return "100.0f"; //$NON-NLS-1$
+					case T_int		: return "1"; //$NON-NLS-1$
+					case T_long		: return "7L"; //$NON-NLS-1$
+					case T_JavaLangString	: return "\"hello-world\""; //$NON-NLS-1$
+					case T_null		: return "null"; //$NON-NLS-1$
+					case T_short	: return "((short) 5)"; //$NON-NLS-1$
+					case T_JavaLangObject	: return "null";} //$NON-NLS-1$
+				return Util.EMPTY_STRING;}
+
+			public  final String type(int code){
+				switch(code){
+					case T_boolean 	: return "z"; //$NON-NLS-1$
+					case T_byte		: return "b"; //$NON-NLS-1$
+					case T_char		: return "c"; //$NON-NLS-1$
+					case T_double	: return "d"; //$NON-NLS-1$
+					case T_float	: return "f"; //$NON-NLS-1$
+					case T_int		: return "i"; //$NON-NLS-1$
+					case T_long		: return "l"; //$NON-NLS-1$
+					case T_JavaLangString	: return "str"; //$NON-NLS-1$
+					case T_null		: return "null"; //$NON-NLS-1$
+					case T_short	: return "s"; //$NON-NLS-1$
+					case T_JavaLangObject	: return "obj";} //$NON-NLS-1$
+				return "xxx";} //$NON-NLS-1$
+
+			public  final String operator(int operator){
+					switch (operator) {
+					case EQUAL_EQUAL :	return "=="; //$NON-NLS-1$
+					case LESS_EQUAL :	return "<="; //$NON-NLS-1$
+					case GREATER_EQUAL :return ">="; //$NON-NLS-1$
+					case LEFT_SHIFT :	return "<<"; //$NON-NLS-1$
+					case RIGHT_SHIFT :	return ">>"; //$NON-NLS-1$
+					case UNSIGNED_RIGHT_SHIFT :	return ">>>"; //$NON-NLS-1$
+					case OR_OR :return "||"; //$NON-NLS-1$
+					case AND_AND :		return "&&"; //$NON-NLS-1$
+					case PLUS :			return "+"; //$NON-NLS-1$
+					case MINUS :		return "-"; //$NON-NLS-1$
+					case NOT :			return "!"; //$NON-NLS-1$
+					case REMAINDER :	return "%"; //$NON-NLS-1$
+					case XOR :			return "^"; //$NON-NLS-1$
+					case AND :			return "&"; //$NON-NLS-1$
+					case MULTIPLY :		return "*"; //$NON-NLS-1$
+					case OR :			return "|"; //$NON-NLS-1$
+					case TWIDDLE :		return "~"; //$NON-NLS-1$
+					case DIVIDE :		return "/"; //$NON-NLS-1$
+					case GREATER :		return ">"; //$NON-NLS-1$
+					case LESS :			return "<";	} //$NON-NLS-1$
+				return "????";} //$NON-NLS-1$
+		}
+
+
+		Decode decode = new Decode();
+		String s;
+
+		s = "\tpublic static void binaryOperationTablesTestCase(){\n" + //$NON-NLS-1$
+
+			"\t\t//TC test : all binary operation (described in tables)\n"+ //$NON-NLS-1$
+			"\t\t//method automatically generated by\n"+ //$NON-NLS-1$
+			"\t\t//org.eclipse.jdt.internal.compiler.ast.OperatorExpression.generateTableTestCase();\n"+ //$NON-NLS-1$
+
+			"\t\tString str0;\t String str\t= "+decode.constant(T_JavaLangString)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tint i0;\t int i\t= "+decode.constant(T_int)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tboolean z0;\t boolean z\t= "+decode.constant(T_boolean)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tchar c0; \t char  c\t= "+decode.constant(T_char)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tfloat f0; \t float f\t= "+decode.constant(T_float)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tdouble d0;\t double d\t= "+decode.constant(T_double)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tbyte b0; \t byte b\t= "+decode.constant(T_byte)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tshort s0; \t short s\t= "+decode.constant(T_short)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tlong l0; \t long l\t= "+decode.constant(T_long)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\t\tObject obj0; \t Object obj\t= "+decode.constant(T_JavaLangObject)+";\n"+ //$NON-NLS-1$ //$NON-NLS-2$
+			"\n"; //$NON-NLS-1$
+
+		int error = 0;
+		for (int i=0; i < operators.length; i++)
+		{	int operator = operators[i];
+			for (int left=0; left<16;left++)
+			for (int right=0; right<16;right++)
+			{	int result = (OperatorSignatures[operator][(left<<4)+right]) & 0x0000F;
+				if (result != T_undefined)
+
+					//1/ First regular computation then 2/ comparaison
+					//with a compile time constant (generated by the compiler)
+					//	z0 = s >= s;
+					//	if ( z0 != (((short) 5) >= ((short) 5)))
+					//		System.out.println(155);
+
+				{	s += "\t\t"+decode.type(result)+"0"+" = "+decode.type(left); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$
+					s += " "+decode.operator(operator)+" "+decode.type(right)+";\n"; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-3$
+					String begin = result == T_JavaLangString ? "\t\tif (! " : "\t\tif ( "; //$NON-NLS-2$ //$NON-NLS-1$
+					String test = result == T_JavaLangString ? ".equals(" : " != ("; //$NON-NLS-2$ //$NON-NLS-1$
+					s += begin	+decode.type(result)+"0"+test //$NON-NLS-1$
+								+decode.constant(left)+" " //$NON-NLS-1$
+								+decode.operator(operator)+" " //$NON-NLS-1$
+								+decode.constant(right)+"))\n"; //$NON-NLS-1$
+					s += "\t\t\tSystem.out.println("+ (++error) +");\n"; //$NON-NLS-1$ //$NON-NLS-2$
+
+					}
+				}
+			}
+
+		return s += "\n\t\tSystem.out.println(\"binary tables test : done\");}"; //$NON-NLS-1$
+	}
+
+	public static final int[] get_AND(){
+
+		//the code is an int, only 20 bits are used, see below.
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//	table[(T_undefined<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_short] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_float] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12) +(Byte2Int<<4) +T_int;
+		table[(T_byte<<4)+T_long]		= (Byte2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_byte<<4)+T_short] 		= (Byte2Int<<12) +(Short2Int<<4)+T_int;
+		//	table[(T_byte<<4)+T_void] 		= T_undefined;
+		//	table[(T_byte<<4)+T_String] 	= T_undefined;
+		//	table[(T_byte<<4)+T_Object] 	= T_undefined;
+		//	table[(T_byte<<4)+T_double] 	= T_undefined;
+		//	table[(T_byte<<4)+T_float] 		= T_undefined;
+		//	table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		table[(T_byte<<4)+T_char] 		= (Byte2Int<<12) +(Char2Int<<4) +T_int;
+		table[(T_byte<<4)+T_int] 		= (Byte2Int<<12) +(Int2Int<<4)  +T_int;
+		//	table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_long<<4)+T_undefined] 	= T_undefined;
+		table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
+		table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long;
+		//	table[(T_long<<4)+T_void] 		= T_undefined;
+		//	table[(T_long<<4)+T_String] 	= T_undefined;
+		//	table[(T_long<<4)+T_Object] 	= T_undefined;
+		//	table[(T_long<<4)+T_double] 	= T_undefined;
+		//	table[(T_long<<4)+T_float] 		= T_undefined;
+		//	table[(T_long<<4)+T_boolean] 	= T_undefined;
+		table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long;
+		table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long;
+		//	table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_short<<4)+T_undefined] 	= T_undefined;
+		table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_void] 			= T_undefined;
+		//	table[(T_short<<4)+T_String] 		= T_undefined;
+		//	table[(T_short<<4)+T_Object] 		= T_undefined;
+		//	table[(T_short<<4)+T_double] 		= T_undefined;
+		//	table[(T_short<<4)+T_float] 		= T_undefined;
+		//	table[(T_short<<4)+T_boolean] 		= T_undefined;
+		table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_void<<4)+T_byte] 		= T_undefined;
+		//	table[(T_void<<4)+T_long] 		= T_undefined;
+		//	table[(T_void<<4)+T_short] 		= T_undefined;
+		//	table[(T_void<<4)+T_void] 		= T_undefined;
+		//	table[(T_void<<4)+T_String] 	= T_undefined;
+		//	table[(T_void<<4)+T_Object] 	= T_undefined;
+		//	table[(T_void<<4)+T_double] 	= T_undefined;
+		//	table[(T_void<<4)+T_float] 		= T_undefined;
+		//	table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//	table[(T_void<<4)+T_char] 		= T_undefined;
+		//	table[(T_void<<4)+T_int] 		= T_undefined;
+		//	table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_String<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_String<<4)+T_byte] 		= T_undefined;
+		//	table[(T_String<<4)+T_long] 		= T_undefined;
+		//	table[(T_String<<4)+T_short] 		= T_undefined;
+		//	table[(T_String<<4)+T_void] 		= T_undefined;
+		//	table[(T_String<<4)+T_String] 		= T_undefined;
+		//	table[(T_String<<4)+T_Object] 		= T_undefined;
+		//	table[(T_String<<4)+T_double] 		= T_undefined;
+		//	table[(T_String<<4)+T_float] 		= T_undefined;
+		//	table[(T_String<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_String<<4)+T_char] 		= T_undefined;
+		//	table[(T_String<<4)+T_int] 			= T_undefined;
+		//	table[(T_String<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//	table[(T_Object<<4)+T_long] 		= T_undefined;
+		//	table[(T_Object<<4)+T_short]		= T_undefined;
+		//	table[(T_Object<<4)+T_void] 		= T_undefined;
+		//	table[(T_Object<<4)+T_String] 		= T_undefined;
+		//	table[(T_Object<<4)+T_Object] 		= T_undefined;
+		//	table[(T_Object<<4)+T_double] 		= T_undefined;
+		//	table[(T_Object<<4)+T_float] 		= T_undefined;
+		//	table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//	table[(T_Object<<4)+T_char] 		= T_undefined;
+		//	table[(T_Object<<4)+T_int] 			= T_undefined;
+		//	table[(T_Object<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_double<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_double<<4)+T_byte] 		= T_undefined;
+		//	table[(T_double<<4)+T_long] 		= T_undefined;
+		//	table[(T_double<<4)+T_short] 		= T_undefined;
+		//	table[(T_double<<4)+T_void] 		= T_undefined;
+		//	table[(T_double<<4)+T_String] 		= T_undefined;
+		//	table[(T_double<<4)+T_Object] 		= T_undefined;
+		//	table[(T_double<<4)+T_double] 		= T_undefined;
+		//	table[(T_double<<4)+T_float] 		= T_undefined;
+		//	table[(T_double<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_double<<4)+T_char] 		= T_undefined;
+		//	table[(T_double<<4)+T_int] 			= T_undefined;
+		//	table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_float<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_float<<4)+T_byte] 			= T_undefined;
+		//	table[(T_float<<4)+T_long] 			= T_undefined;
+		//	table[(T_float<<4)+T_short] 		= T_undefined;
+		//	table[(T_float<<4)+T_void] 			= T_undefined;
+		//	table[(T_float<<4)+T_String] 		= T_undefined;
+		//	table[(T_float<<4)+T_Object] 		= T_undefined;
+		//	table[(T_float<<4)+T_double] 		= T_undefined;
+		//	table[(T_float<<4)+T_float] 		= T_undefined;
+		//	table[(T_float<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_float<<4)+T_char] 			= T_undefined;
+		//	table[(T_float<<4)+T_int] 			= T_undefined;
+		//	table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_void] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_String] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_float] 			= T_undefined;
+		table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean << 12)+(Boolean2Boolean << 4)+T_boolean;
+		//	table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_char<<4)+T_undefined] 		= T_undefined;
+		table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_void] 			= T_undefined;
+		//	table[(T_char<<4)+T_String] 		= T_undefined;
+		//	table[(T_char<<4)+T_Object] 		= T_undefined;
+		//	table[(T_char<<4)+T_double] 		= T_undefined;
+		//	table[(T_char<<4)+T_float] 			= T_undefined;
+		//	table[(T_char<<4)+T_boolean] 		= T_undefined;
+		table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_int<<4)+T_undefined] 	= T_undefined;
+		table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_void] 		= T_undefined;
+		//	table[(T_int<<4)+T_String] 		= T_undefined;
+		//	table[(T_int<<4)+T_Object] 		= T_undefined;
+		//	table[(T_int<<4)+T_double] 		= T_undefined;
+		//	table[(T_int<<4)+T_float] 		= T_undefined;
+		//	table[(T_int<<4)+T_boolean] 	= T_undefined;
+		table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_null<<4)+T_byte] 			= T_undefined;
+		//	table[(T_null<<4)+T_long] 			= T_undefined;
+		//	table[(T_null<<4)+T_short] 			= T_undefined;
+		//	table[(T_null<<4)+T_void] 			= T_undefined;
+		//	table[(T_null<<4)+T_String] 		= T_undefined;
+		//	table[(T_null<<4)+T_Object] 		= T_undefined;
+		//	table[(T_null<<4)+T_double] 		= T_undefined;
+		//	table[(T_null<<4)+T_float] 			= T_undefined;
+		//	table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_null<<4)+T_char] 			= T_undefined;
+		//	table[(T_null<<4)+T_int] 			= T_undefined;
+		//	table[(T_null<<4)+T_null] 			= T_undefined;
+
+		return table;
+	}
+
+	public static final int[] get_AND_AND(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//     table[(T_undefined<<4)+T_undefined] 		= T_undefined;
+		//     table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_short] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//     table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//     table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//     table[(T_undefined<<4)+T_float] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//     table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//     table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_byte<<4)+T_byte] 		= T_undefined;
+		//     table[(T_byte<<4)+T_long] 		= T_undefined;
+		//     table[(T_byte<<4)+T_short] 		= T_undefined;
+		//     table[(T_byte<<4)+T_void] 		= T_undefined;
+		//     table[(T_byte<<4)+T_String] 		= T_undefined;
+		//     table[(T_byte<<4)+T_Object] 		= T_undefined;
+		//     table[(T_byte<<4)+T_double] 		= T_undefined;
+		//     table[(T_byte<<4)+T_float] 		= T_undefined;
+		//     table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		//     table[(T_byte<<4)+T_char] 		= T_undefined;
+		//     table[(T_byte<<4)+T_int] 		= T_undefined;
+		//     table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_long<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_long<<4)+T_byte] 		= T_undefined;
+		//     table[(T_long<<4)+T_long] 		= T_undefined;
+		//     table[(T_long<<4)+T_short] 		= T_undefined;
+		//     table[(T_long<<4)+T_void] 		= T_undefined;
+		//     table[(T_long<<4)+T_String] 		= T_undefined;
+		//     table[(T_long<<4)+T_Object] 		= T_undefined;
+		//     table[(T_long<<4)+T_double] 		= T_undefined;
+		//     table[(T_long<<4)+T_float] 		= T_undefined;
+		//     table[(T_long<<4)+T_boolean] 	= T_undefined;
+		//     table[(T_long<<4)+T_char] 		= T_undefined;
+		//     table[(T_long<<4)+T_int] 		= T_undefined;
+		//     table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_short<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_short<<4)+T_byte] 		= T_undefined;
+		//     table[(T_short<<4)+T_long] 		= T_undefined;
+		//     table[(T_short<<4)+T_short] 		= T_undefined;
+		//     table[(T_short<<4)+T_void] 		= T_undefined;
+		//     table[(T_short<<4)+T_String] 	= T_undefined;
+		//     table[(T_short<<4)+T_Object] 	= T_undefined;
+		//     table[(T_short<<4)+T_double] 	= T_undefined;
+		//     table[(T_short<<4)+T_float] 		= T_undefined;
+		//     table[(T_short<<4)+T_boolean]	= T_undefined;
+		//     table[(T_short<<4)+T_char] 		= T_undefined;
+		//     table[(T_short<<4)+T_int] 		= T_undefined;
+		//     table[(T_short<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_void<<4)+T_byte] 		= T_undefined;
+		//     table[(T_void<<4)+T_long] 		= T_undefined;
+		//     table[(T_void<<4)+T_short] 		= T_undefined;
+		//     table[(T_void<<4)+T_void] 		= T_undefined;
+		//     table[(T_void<<4)+T_String] 	= T_undefined;
+		//     table[(T_void<<4)+T_Object] 	= T_undefined;
+		//     table[(T_void<<4)+T_double] 	= T_undefined;
+		//     table[(T_void<<4)+T_float] 		= T_undefined;
+		//     table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//     table[(T_void<<4)+T_char] 		= T_undefined;
+		//     table[(T_void<<4)+T_int] 		= T_undefined;
+		//     table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_String<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_String<<4)+T_byte] 		= T_undefined;
+		//     table[(T_String<<4)+T_long] 		= T_undefined;
+		//     table[(T_String<<4)+T_short] 		= T_undefined;
+		//     table[(T_String<<4)+T_void] 		= T_undefined;
+		//     table[(T_String<<4)+T_String] 		= T_undefined;
+		//     table[(T_String<<4)+T_Object] 		= T_undefined;
+		//     table[(T_String<<4)+T_double] 		= T_undefined;
+		//     table[(T_String<<4)+T_float] 		= T_undefined;
+		//     table[(T_String<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_String<<4)+T_char] 		= T_undefined;
+		//     table[(T_String<<4)+T_int] 			= T_undefined;
+		//     table[(T_String<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//     table[(T_Object<<4)+T_long] 		= T_undefined;
+		//     table[(T_Object<<4)+T_short]		= T_undefined;
+		//     table[(T_Object<<4)+T_void] 		= T_undefined;
+		//     table[(T_Object<<4)+T_String] 		= T_undefined;
+		//     table[(T_Object<<4)+T_Object] 		= T_undefined;
+		//     table[(T_Object<<4)+T_double] 		= T_undefined;
+		//     table[(T_Object<<4)+T_float] 		= T_undefined;
+		//     table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//     table[(T_Object<<4)+T_char] 		= T_undefined;
+		//     table[(T_Object<<4)+T_int] 			= T_undefined;
+		//     table[(T_Object<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_double<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_double<<4)+T_byte] 		= T_undefined;
+		//     table[(T_double<<4)+T_long] 		= T_undefined;
+		//     table[(T_double<<4)+T_short] 		= T_undefined;
+		//     table[(T_double<<4)+T_void] 		= T_undefined;
+		//     table[(T_double<<4)+T_String] 		= T_undefined;
+		//     table[(T_double<<4)+T_Object] 		= T_undefined;
+		//     table[(T_double<<4)+T_double] 		= T_undefined;
+		//     table[(T_double<<4)+T_float] 		= T_undefined;
+		//     table[(T_double<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_double<<4)+T_char] 		= T_undefined;
+		//     table[(T_double<<4)+T_int] 			= T_undefined;
+		//     table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_float<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_float<<4)+T_byte] 			= T_undefined;
+		//     table[(T_float<<4)+T_long] 			= T_undefined;
+		//     table[(T_float<<4)+T_short] 		= T_undefined;
+		//     table[(T_float<<4)+T_void] 			= T_undefined;
+		//     table[(T_float<<4)+T_String] 		= T_undefined;
+		//     table[(T_float<<4)+T_Object] 		= T_undefined;
+		//     table[(T_float<<4)+T_double] 		= T_undefined;
+		//     table[(T_float<<4)+T_float] 		= T_undefined;
+		//     table[(T_float<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_float<<4)+T_char] 			= T_undefined;
+		//     table[(T_float<<4)+T_int] 			= T_undefined;
+		//     table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//     table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//     table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_void] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_String] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_float] 			= T_undefined;
+	   table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean;
+		//     table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//     table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//     table[(T_char<<4)+T_undefined] 		= T_undefined;
+		//     table[(T_char<<4)+T_byte] 			= T_undefined;
+		//     table[(T_char<<4)+T_long] 			= T_undefined;
+		//     table[(T_char<<4)+T_short] 			= T_undefined;
+		//     table[(T_char<<4)+T_void] 			= T_undefined;
+		//     table[(T_char<<4)+T_String] 		= T_undefined;
+		//     table[(T_char<<4)+T_Object] 		= T_undefined;
+		//     table[(T_char<<4)+T_double] 		= T_undefined;
+		//     table[(T_char<<4)+T_float] 			= T_undefined;
+		//     table[(T_char<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_char<<4)+T_char] 			= T_undefined;
+		//     table[(T_char<<4)+T_int] 			= T_undefined;
+		//     table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//     table[(T_int<<4)+T_undefined] 	= T_undefined;
+		//     table[(T_int<<4)+T_byte] 		= T_undefined;
+		//     table[(T_int<<4)+T_long] 		= T_undefined;
+		//     table[(T_int<<4)+T_short] 		= T_undefined;
+		//     table[(T_int<<4)+T_void] 		= T_undefined;
+		//     table[(T_int<<4)+T_String] 		= T_undefined;
+		//     table[(T_int<<4)+T_Object] 		= T_undefined;
+		//     table[(T_int<<4)+T_double] 		= T_undefined;
+		//     table[(T_int<<4)+T_float] 		= T_undefined;
+		//     table[(T_int<<4)+T_boolean] 	= T_undefined;
+		//     table[(T_int<<4)+T_char] 		= T_undefined;
+		//     table[(T_int<<4)+T_int] 		= T_undefined;
+		//     table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//     table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//     table[(T_null<<4)+T_byte] 			= T_undefined;
+		//     table[(T_null<<4)+T_long] 			= T_undefined;
+		//     table[(T_null<<4)+T_short] 			= T_undefined;
+		//     table[(T_null<<4)+T_void] 			= T_undefined;
+		//     table[(T_null<<4)+T_String] 		= T_undefined;
+		//     table[(T_null<<4)+T_Object] 		= T_undefined;
+		//     table[(T_null<<4)+T_double] 		= T_undefined;
+		//     table[(T_null<<4)+T_float] 			= T_undefined;
+		//     table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//     table[(T_null<<4)+T_char] 			= T_undefined;
+		//     table[(T_null<<4)+T_int] 			= T_undefined;
+		//     table[(T_null<<4)+T_null] 			= T_undefined;
+		return table;
+	}
+
+	public static final int[] get_DIVIDE(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+
+	//	int[] table  = new int[16*16];
+
+		return get_MINUS();
+	}
+
+	public static final int[] get_EQUAL_EQUAL(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//	table[(T_undefined<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_short] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_float] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_void] 		= T_undefined;
+		//	table[(T_byte<<4)+T_String] 	= T_undefined;
+		//	table[(T_byte<<4)+T_Object] 	= T_undefined;
+		table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_long<<4)+T_undefined] 	= T_undefined;
+		table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean;
+		//	table[(T_long<<4)+T_void] 		= T_undefined;
+		//	table[(T_long<<4)+T_String] 	= T_undefined;
+		//	table[(T_long<<4)+T_Object] 	= T_undefined;
+		table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_long<<4)+T_boolean] 	= T_undefined;
+		table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean;
+		//	table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_short<<4)+T_undefined] 	= T_undefined;
+		table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_short<<4)+T_void] 			= T_undefined;
+		//	table[(T_short<<4)+T_String] 		= T_undefined;
+		//	table[(T_short<<4)+T_Object] 		= T_undefined;
+		table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_short<<4)+T_boolean] 		= T_undefined;
+		table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_short<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_void<<4)+T_byte] 		= T_undefined;
+		//	table[(T_void<<4)+T_long] 		= T_undefined;
+		//	table[(T_void<<4)+T_short] 		= T_undefined;
+		//	table[(T_void<<4)+T_void] 		= T_undefined;
+		//	table[(T_void<<4)+T_String] 	= T_undefined;
+		//	table[(T_void<<4)+T_Object] 	= T_undefined;
+		//	table[(T_void<<4)+T_double] 	= T_undefined;
+		//	table[(T_void<<4)+T_float] 		= T_undefined;
+		//	table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//	table[(T_void<<4)+T_char] 		= T_undefined;
+		//	table[(T_void<<4)+T_int] 		= T_undefined;
+		//	table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_String<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_String<<4)+T_byte] 		= T_undefined;
+		//	table[(T_String<<4)+T_long] 		= T_undefined;
+		//	table[(T_String<<4)+T_short] 		= T_undefined;
+		//	table[(T_String<<4)+T_void] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_JavaLangString] 		= /*String2Object                 String2Object*/
+											  (T_JavaLangObject<<16)+(T_JavaLangString<<12)+(T_JavaLangObject<<8)+(T_JavaLangString<<4)+T_boolean;
+		table[(T_JavaLangString<<4)+T_JavaLangObject] 		= /*String2Object                 Object2Object*/
+											  (T_JavaLangObject<<16)+(T_JavaLangString<<12)+(T_JavaLangObject<<8)+(T_JavaLangObject<<4)+T_boolean;
+		//	table[(T_String<<4)+T_double] 		= T_undefined;
+		//	table[(T_String<<4)+T_float] 		= T_undefined;
+		//	table[(T_String<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_String<<4)+T_char] 		= T_undefined;
+		//	table[(T_String<<4)+T_int] 			= T_undefined;
+		table[(T_JavaLangString<<4)+T_null] 		= /*Object2String                null2Object */
+											  (T_JavaLangObject<<16)+(T_JavaLangString<<12)+(T_JavaLangObject<<8)+(T_null<<4)+T_boolean;
+
+		//	table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//	table[(T_Object<<4)+T_long] 		= T_undefined;
+		//	table[(T_Object<<4)+T_short]		= T_undefined;
+		//	table[(T_Object<<4)+T_void] 		= T_undefined;
+		table[(T_JavaLangObject<<4)+T_JavaLangString] 		= /*Object2Object                 String2Object*/
+											  (T_JavaLangObject<<16)+(T_JavaLangObject<<12)+(T_JavaLangObject<<8)+(T_JavaLangString<<4)+T_boolean;
+		table[(T_JavaLangObject<<4)+T_JavaLangObject] 		= /*Object2Object                 Object2Object*/
+											  (T_JavaLangObject<<16)+(T_JavaLangObject<<12)+(T_JavaLangObject<<8)+(T_JavaLangObject<<4)+T_boolean;
+		//	table[(T_Object<<4)+T_double] 		= T_undefined;
+		//	table[(T_Object<<4)+T_float] 		= T_undefined;
+		//	table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//	table[(T_Object<<4)+T_char] 		= T_undefined;
+		//	table[(T_Object<<4)+T_int] 			= T_undefined;
+		table[(T_JavaLangObject<<4)+T_null] 		= /*Object2Object                 null2Object*/
+											  (T_JavaLangObject<<16)+(T_JavaLangObject<<12)+(T_JavaLangObject<<8)+(T_null<<4)+T_boolean;
+
+		//	table[(T_double<<4)+T_undefined] 	= T_undefined;
+		table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_void] 		= T_undefined;
+		//	table[(T_double<<4)+T_String] 		= T_undefined;
+		//	table[(T_double<<4)+T_Object] 		= T_undefined;
+		table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_boolean] 		= T_undefined;
+		table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_float<<4)+T_undefined] 	= T_undefined;
+		table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_void] 			= T_undefined;
+		//	table[(T_float<<4)+T_String] 		= T_undefined;
+		//	table[(T_float<<4)+T_Object] 		= T_undefined;
+		table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_boolean] 		= T_undefined;
+		table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_void] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_String] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_float] 			= T_undefined;
+		table[(T_boolean<<4)+T_boolean] 		= (Boolean2Boolean<<12)+(Boolean2Boolean<<4)+T_boolean;
+		//	table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_char<<4)+T_undefined] 		= T_undefined;
+		table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_char<<4)+T_void] 			= T_undefined;
+		//	table[(T_char<<4)+T_String] 		= T_undefined;
+		//	table[(T_char<<4)+T_Object] 		= T_undefined;
+		table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_char<<4)+T_boolean] 		= T_undefined;
+		table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_int<<4)+T_undefined] 	= T_undefined;
+		table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_int<<4)+T_void] 		= T_undefined;
+		//	table[(T_int<<4)+T_String] 		= T_undefined;
+		//	table[(T_int<<4)+T_Object] 		= T_undefined;
+		table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_int<<4)+T_boolean] 	= T_undefined;
+		table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_null<<4)+T_byte] 			= T_undefined;
+		//	table[(T_null<<4)+T_long] 			= T_undefined;
+		//	table[(T_null<<4)+T_short] 			= T_undefined;
+		//	table[(T_null<<4)+T_void] 			= T_undefined;
+		table[(T_null<<4)+T_JavaLangString] 		= /*null2Object                 String2Object*/
+											  (T_JavaLangObject<<16)+(T_null<<12)+(T_JavaLangObject<<8)+(T_JavaLangString<<4)+T_boolean;
+		table[(T_null<<4)+T_JavaLangObject] 		= /*null2Object                 Object2Object*/
+											  (T_JavaLangObject<<16)+(T_null<<12)+(T_JavaLangObject<<8)+(T_JavaLangObject<<4)+T_boolean;
+		//	table[(T_null<<4)+T_double] 		= T_undefined;
+		//	table[(T_null<<4)+T_float] 			= T_undefined;
+		//	table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_null<<4)+T_char] 			= T_undefined;
+		//	table[(T_null<<4)+T_int] 			= T_undefined;
+		table[(T_null<<4)+T_null] 			= /*null2Object                 null2Object*/
+											  (T_JavaLangObject<<16)+(T_null<<12)+(T_JavaLangObject<<8)+(T_null<<4)+T_boolean;
+		return table;
+	}
+
+	public static final int[] get_GREATER(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_LESS();
+	}
+
+	public static final int[] get_GREATER_EQUAL(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_LESS();
+	}
+
+	public static final int[] get_LEFT_SHIFT(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//	table[(T_undefined<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_short] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_float] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_byte<<4)+T_long] 		= (Byte2Int<<12)+(Long2Int<<4)+T_int;
+		table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_byte<<4)+T_void] 		= T_undefined;
+		//	table[(T_byte<<4)+T_String] 	= T_undefined;
+		//	table[(T_byte<<4)+T_Object] 	= T_undefined;
+		//	table[(T_byte<<4)+T_double] 	= T_undefined;
+		//	table[(T_byte<<4)+T_float] 		= T_undefined;
+		//	table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_long<<4)+T_undefined] 	= T_undefined;
+		table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Int<<4)+T_long;
+		table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Int<<4)+T_long;
+		table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Int<<4)+T_long;
+		//	table[(T_long<<4)+T_void] 		= T_undefined;
+		//	table[(T_long<<4)+T_String] 	= T_undefined;
+		//	table[(T_long<<4)+T_Object] 	= T_undefined;
+		//	table[(T_long<<4)+T_double] 	= T_undefined;
+		//	table[(T_long<<4)+T_float] 		= T_undefined;
+		//	table[(T_long<<4)+T_boolean] 	= T_undefined;
+		table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Int<<4)+T_long;
+		table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Int<<4)+T_long;
+		//	table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_short<<4)+T_undefined] 	= T_undefined;
+		table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_short<<4)+T_long] 			= (Short2Int<<12)+(Long2Int<<4)+T_int;
+		table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_void] 			= T_undefined;
+		//	table[(T_short<<4)+T_String] 		= T_undefined;
+		//	table[(T_short<<4)+T_Object] 		= T_undefined;
+		//	table[(T_short<<4)+T_double] 		= T_undefined;
+		//	table[(T_short<<4)+T_float] 		= T_undefined;
+		//	table[(T_short<<4)+T_boolean] 		= T_undefined;
+		table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_void<<4)+T_byte] 		= T_undefined;
+		//	table[(T_void<<4)+T_long] 		= T_undefined;
+		//	table[(T_void<<4)+T_short] 		= T_undefined;
+		//	table[(T_void<<4)+T_void] 		= T_undefined;
+		//	table[(T_void<<4)+T_String] 	= T_undefined;
+		//	table[(T_void<<4)+T_Object] 	= T_undefined;
+		//	table[(T_void<<4)+T_double] 	= T_undefined;
+		//	table[(T_void<<4)+T_float] 		= T_undefined;
+		//	table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//	table[(T_void<<4)+T_char] 		= T_undefined;
+		//	table[(T_void<<4)+T_int] 		= T_undefined;
+		//	table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_String<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_String<<4)+T_byte] 		= T_undefined;
+		//	table[(T_String<<4)+T_long] 		= T_undefined;
+		//	table[(T_String<<4)+T_short] 		= T_undefined;
+		//	table[(T_String<<4)+T_void] 		= T_undefined;
+		//	table[(T_String<<4)+T_String] 		= T_undefined;
+		//	table[(T_String<<4)+T_Object] 		= T_undefined;
+		//	table[(T_String<<4)+T_double] 		= T_undefined;
+		//	table[(T_String<<4)+T_float] 		= T_undefined;
+		//	table[(T_String<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_String<<4)+T_char] 		= T_undefined;
+		//	table[(T_String<<4)+T_int] 			= T_undefined;
+		//	table[(T_String<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//	table[(T_Object<<4)+T_long] 		= T_undefined;
+		//	table[(T_Object<<4)+T_short]		= T_undefined;
+		//	table[(T_Object<<4)+T_void] 		= T_undefined;
+		//	table[(T_Object<<4)+T_String] 		= T_undefined;
+		//	table[(T_Object<<4)+T_Object] 		= T_undefined;
+		//	table[(T_Object<<4)+T_double] 		= T_undefined;
+		//	table[(T_Object<<4)+T_float] 		= T_undefined;
+		//	table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//	table[(T_Object<<4)+T_char] 		= T_undefined;
+		//	table[(T_Object<<4)+T_int] 			= T_undefined;
+		//	table[(T_Object<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_double<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_double<<4)+T_byte] 		= T_undefined;
+		//	table[(T_double<<4)+T_long] 		= T_undefined;
+		//	table[(T_double<<4)+T_short] 		= T_undefined;
+		//	table[(T_double<<4)+T_void] 		= T_undefined;
+		//	table[(T_double<<4)+T_String] 		= T_undefined;
+		//	table[(T_double<<4)+T_Object] 		= T_undefined;
+		//	table[(T_double<<4)+T_double] 		= T_undefined;
+		//	table[(T_double<<4)+T_float] 		= T_undefined;
+		//	table[(T_double<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_double<<4)+T_char] 		= T_undefined;
+		//	table[(T_double<<4)+T_int] 			= T_undefined;
+		//	table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_float<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_float<<4)+T_byte] 			= T_undefined;
+		//	table[(T_float<<4)+T_long] 			= T_undefined;
+		//	table[(T_float<<4)+T_short] 		= T_undefined;
+		//	table[(T_float<<4)+T_void] 			= T_undefined;
+		//	table[(T_float<<4)+T_String] 		= T_undefined;
+		//	table[(T_float<<4)+T_Object] 		= T_undefined;
+		//	table[(T_float<<4)+T_double] 		= T_undefined;
+		//	table[(T_float<<4)+T_float] 		= T_undefined;
+		//	table[(T_float<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_float<<4)+T_char] 			= T_undefined;
+		//	table[(T_float<<4)+T_int] 			= T_undefined;
+		//	table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_void] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_String] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_float] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_char<<4)+T_undefined] 		= T_undefined;
+		table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_char<<4)+T_long] 			= (Char2Int<<12)+(Long2Int<<4)+T_int;
+		table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_void] 			= T_undefined;
+		//	table[(T_char<<4)+T_String] 		= T_undefined;
+		//	table[(T_char<<4)+T_Object] 		= T_undefined;
+		//	table[(T_char<<4)+T_double] 		= T_undefined;
+		//	table[(T_char<<4)+T_float] 			= T_undefined;
+		//	table[(T_char<<4)+T_boolean] 		= T_undefined;
+		table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_int<<4)+T_undefined] 	= T_undefined;
+		table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_int<<4)+T_long] 		= (Int2Int<<12)+(Long2Int<<4)+T_int;
+		table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_void] 		= T_undefined;
+		//	table[(T_int<<4)+T_String] 		= T_undefined;
+		//	table[(T_int<<4)+T_Object] 		= T_undefined;
+		//	table[(T_int<<4)+T_double] 		= T_undefined;
+		//	table[(T_int<<4)+T_float] 		= T_undefined;
+		//	table[(T_int<<4)+T_boolean] 	= T_undefined;
+		table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_null<<4)+T_byte] 			= T_undefined;
+		//	table[(T_null<<4)+T_long] 			= T_undefined;
+		//	table[(T_null<<4)+T_short] 			= T_undefined;
+		//	table[(T_null<<4)+T_void] 			= T_undefined;
+		//	table[(T_null<<4)+T_String] 		= T_undefined;
+		//	table[(T_null<<4)+T_Object] 		= T_undefined;
+		//	table[(T_null<<4)+T_double] 		= T_undefined;
+		//	table[(T_null<<4)+T_float] 			= T_undefined;
+		//	table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_null<<4)+T_char] 			= T_undefined;
+		//	table[(T_null<<4)+T_int] 			= T_undefined;
+		//	table[(T_null<<4)+T_null] 			= T_undefined;
+
+		return table;
+	}
+
+	public static final int[] get_LESS(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//	table[(T_undefined<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_short] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_float] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_void] 		= T_undefined;
+		//	table[(T_byte<<4)+T_String] 	= T_undefined;
+		//	table[(T_byte<<4)+T_Object] 	= T_undefined;
+		table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_long<<4)+T_undefined] 	= T_undefined;
+		table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_boolean;
+		//	table[(T_long<<4)+T_void] 		= T_undefined;
+		//	table[(T_long<<4)+T_String] 	= T_undefined;
+		//	table[(T_long<<4)+T_Object] 	= T_undefined;
+		table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_long<<4)+T_boolean] 	= T_undefined;
+		table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_boolean;
+		table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_boolean;
+		//	table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_short<<4)+T_undefined] 	= T_undefined;
+		table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_short<<4)+T_void] 			= T_undefined;
+		//	table[(T_short<<4)+T_String] 		= T_undefined;
+		//	table[(T_short<<4)+T_Object] 		= T_undefined;
+		table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_short<<4)+T_boolean] 		= T_undefined;
+		table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_short<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_void<<4)+T_byte] 		= T_undefined;
+		//	table[(T_void<<4)+T_long] 		= T_undefined;
+		//	table[(T_void<<4)+T_short] 		= T_undefined;
+		//	table[(T_void<<4)+T_void] 		= T_undefined;
+		//	table[(T_void<<4)+T_String] 	= T_undefined;
+		//	table[(T_void<<4)+T_Object] 	= T_undefined;
+		//	table[(T_void<<4)+T_double] 	= T_undefined;
+		//	table[(T_void<<4)+T_float] 		= T_undefined;
+		//	table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//	table[(T_void<<4)+T_char] 		= T_undefined;
+		//	table[(T_void<<4)+T_int] 		= T_undefined;
+		//	table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_String<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_String<<4)+T_byte] 		= T_undefined;
+		//	table[(T_String<<4)+T_long] 		= T_undefined;
+		//	table[(T_String<<4)+T_short] 		= T_undefined;
+		//	table[(T_String<<4)+T_void] 		= T_undefined;
+		//	table[(T_String<<4)+T_String] 		= T_undefined;
+		//	table[(T_String<<4)+T_Object] 		= T_undefined;
+		//	table[(T_String<<4)+T_double] 		= T_undefined;
+		//	table[(T_String<<4)+T_float] 		= T_undefined;
+		//	table[(T_String<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_String<<4)+T_char] 		= T_undefined;
+		//	table[(T_String<<4)+T_int] 			= T_undefined;
+		//	table[(T_String<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//	table[(T_Object<<4)+T_long] 		= T_undefined;
+		//	table[(T_Object<<4)+T_short]		= T_undefined;
+		//	table[(T_Object<<4)+T_void] 		= T_undefined;
+		//	table[(T_Object<<4)+T_String] 		= T_undefined;
+		//	table[(T_Object<<4)+T_Object] 		= T_undefined;
+		//	table[(T_Object<<4)+T_double] 		= T_undefined;
+		//	table[(T_Object<<4)+T_float] 		= T_undefined;
+		//	table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//	table[(T_Object<<4)+T_char] 		= T_undefined;
+		//	table[(T_Object<<4)+T_int] 			= T_undefined;
+		//	table[(T_Object<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_double<<4)+T_undefined] 	= T_undefined;
+		table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_void] 		= T_undefined;
+		//	table[(T_double<<4)+T_String] 		= T_undefined;
+		//	table[(T_double<<4)+T_Object] 		= T_undefined;
+		table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_boolean] 		= T_undefined;
+		table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_boolean;
+		table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_boolean;
+		//	table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_float<<4)+T_undefined] 	= T_undefined;
+		table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_void] 			= T_undefined;
+		//	table[(T_float<<4)+T_String] 		= T_undefined;
+		//	table[(T_float<<4)+T_Object] 		= T_undefined;
+		table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_boolean] 		= T_undefined;
+		table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_boolean;
+		table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_boolean;
+		//	table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_void] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_String] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_float] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_char<<4)+T_undefined] 		= T_undefined;
+		table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_char<<4)+T_void] 			= T_undefined;
+		//	table[(T_char<<4)+T_String] 		= T_undefined;
+		//	table[(T_char<<4)+T_Object] 		= T_undefined;
+		table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_char<<4)+T_boolean] 		= T_undefined;
+		table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_int<<4)+T_undefined] 	= T_undefined;
+		table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_boolean;
+		table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_boolean;
+		table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_boolean;
+		//	table[(T_int<<4)+T_void] 		= T_undefined;
+		//	table[(T_int<<4)+T_String] 		= T_undefined;
+		//	table[(T_int<<4)+T_Object] 		= T_undefined;
+		table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_boolean;
+		table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_boolean;
+		//	table[(T_int<<4)+T_boolean] 	= T_undefined;
+		table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_boolean;
+		table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_boolean;
+		//	table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_null<<4)+T_byte] 			= T_undefined;
+		//	table[(T_null<<4)+T_long] 			= T_undefined;
+		//	table[(T_null<<4)+T_short] 			= T_undefined;
+		//	table[(T_null<<4)+T_void] 			= T_undefined;
+		//	table[(T_null<<4)+T_String] 		= T_undefined;
+		//	table[(T_null<<4)+T_Object] 		= T_undefined;
+		//	table[(T_null<<4)+T_double] 		= T_undefined;
+		//	table[(T_null<<4)+T_float] 			= T_undefined;
+		//	table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_null<<4)+T_char] 			= T_undefined;
+		//	table[(T_null<<4)+T_int] 			= T_undefined;
+		//	table[(T_null<<4)+T_null] 			= T_undefined;
+
+		return table;
+	}
+
+	public static final int[] get_LESS_EQUAL(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_LESS();
+	}
+
+	public static final int[] get_MINUS(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table = (int[]) get_PLUS().clone();
+
+		// customization
+		table[(T_JavaLangString<<4)+T_byte] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_long] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_short] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_void] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_JavaLangString] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_JavaLangObject] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_double] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_float] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_boolean] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_char] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_int] 			= T_undefined;
+		table[(T_JavaLangString<<4)+T_null] 		= T_undefined;
+
+		table[(T_byte<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_long<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_short<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_void<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_JavaLangObject<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_double<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_float<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_boolean<<4)+T_JavaLangString] 		= T_undefined;
+		table[(T_char<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_int<<4)	+T_JavaLangString] 		= T_undefined;
+		table[(T_null<<4)	+T_JavaLangString] 		= T_undefined;
+
+		table[(T_null<<4)	+T_null] 		= T_undefined;
+
+		return table;
+	}
+
+	public static final int[] get_MULTIPLY(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_MINUS();
+	}
+
+	public static final int[] get_OR(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+
+		//	int[] table  = new int[16*16];
+		return get_AND();
+	}
+
+	public static final int[] get_OR_OR(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_AND_AND();
+	}
+
+	public static final int[] get_PLUS(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		int[] table  = new int[16*16];
+
+		//	table[(T_undefined<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_undefined<<4)+T_byte] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_long] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_short] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_void] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_String] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_Object] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_double] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_float] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_undefined<<4)+T_char] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_int] 			= T_undefined;
+		//	table[(T_undefined<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_byte<<4)+T_undefined] 	= T_undefined;
+		table[(T_byte<<4)+T_byte] 		= (Byte2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_byte<<4)+T_long] 		= (Byte2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_byte<<4)+T_short] 		= (Byte2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_byte<<4)+T_void] 		= T_undefined;
+		table[(T_byte<<4)+T_JavaLangString] 	= (Byte2Byte<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_byte<<4)+T_Object] 	= T_undefined;
+		table[(T_byte<<4)+T_double] 	= (Byte2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_byte<<4)+T_float] 		= (Byte2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_byte<<4)+T_boolean] 	= T_undefined;
+		table[(T_byte<<4)+T_char] 		= (Byte2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_byte<<4)+T_int] 		= (Byte2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_byte<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_long<<4)+T_undefined] 	= T_undefined;
+		table[(T_long<<4)+T_byte] 		= (Long2Long<<12)+(Byte2Long<<4)+T_long;
+		table[(T_long<<4)+T_long] 		= (Long2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_long<<4)+T_short] 		= (Long2Long<<12)+(Short2Long<<4)+T_long;
+		//	table[(T_long<<4)+T_void] 		= T_undefined;
+		table[(T_long<<4)+T_JavaLangString] 	= (Long2Long<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_long<<4)+T_Object] 	= T_undefined;
+		table[(T_long<<4)+T_double] 	= (Long2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_long<<4)+T_float] 		= (Long2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_long<<4)+T_boolean] 	= T_undefined;
+		table[(T_long<<4)+T_char] 		= (Long2Long<<12)+(Char2Long<<4)+T_long;
+		table[(T_long<<4)+T_int] 		= (Long2Long<<12)+(Int2Long<<4)+T_long;
+		//	table[(T_long<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_short<<4)+T_undefined] 	= T_undefined;
+		table[(T_short<<4)+T_byte] 			= (Short2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_short<<4)+T_long] 			= (Short2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_short<<4)+T_short] 		= (Short2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_void] 			= T_undefined;
+		table[(T_short<<4)+T_JavaLangString] 		= (Short2Short<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_short<<4)+T_Object] 		= T_undefined;
+		table[(T_short<<4)+T_double] 		= (Short2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_short<<4)+T_float] 		= (Short2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_short<<4)+T_boolean] 		= T_undefined;
+		table[(T_short<<4)+T_char] 			= (Short2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_short<<4)+T_int] 			= (Short2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_short<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_void<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_void<<4)+T_byte] 		= T_undefined;
+		//	table[(T_void<<4)+T_long] 		= T_undefined;
+		//	table[(T_void<<4)+T_short] 		= T_undefined;
+		//	table[(T_void<<4)+T_void] 		= T_undefined;
+		//	table[(T_void<<4)+T_String] 	= T_undefined;
+		//	table[(T_void<<4)+T_Object] 	= T_undefined;
+		//	table[(T_void<<4)+T_double] 	= T_undefined;
+		//	table[(T_void<<4)+T_float] 		= T_undefined;
+		//	table[(T_void<<4)+T_boolean] 	= T_undefined;
+		//	table[(T_void<<4)+T_char] 		= T_undefined;
+		//	table[(T_void<<4)+T_int] 		= T_undefined;
+		//	table[(T_void<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_String<<4)+T_undefined] 	= T_undefined;
+		table[(T_JavaLangString<<4)+T_byte] 		= (String2String<<12)+(Byte2Byte<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_long] 		= (String2String<<12)+(Long2Long<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_short] 		= (String2String<<12)+(Short2Short<<4)+T_JavaLangString;
+		//	table[(T_String<<4)+T_void] 		= T_undefined;
+		table[(T_JavaLangString<<4)+T_JavaLangString] 		= (String2String<<12)+(String2String<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_JavaLangObject] 		= (String2String<<12)+(Object2Object<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_double] 		= (String2String<<12)+(Double2Double<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_float] 		= (String2String<<12)+(Float2Float<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_boolean] 		= (String2String<<12)+(Boolean2Boolean<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_char] 		= (String2String<<12)+(Char2Char<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_int] 			= (String2String<<12)+(Int2Int<<4)+T_JavaLangString;
+		table[(T_JavaLangString<<4)+T_null] 		= (String2String<<12)+(T_null<<8)+(T_null<<4)+T_JavaLangString;
+
+		//	table[(T_Object<<4)+T_undefined] 	= T_undefined;
+		//	table[(T_Object<<4)+T_byte] 		= T_undefined;
+		//	table[(T_Object<<4)+T_long] 		= T_undefined;
+		//	table[(T_Object<<4)+T_short]		= T_undefined;
+		//	table[(T_Object<<4)+T_void] 		= T_undefined;
+		table[(T_JavaLangObject<<4)+T_JavaLangString] 		= (Object2Object<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_Object<<4)+T_Object] 		= T_undefined;
+		//	table[(T_Object<<4)+T_double] 		= T_undefined;
+		//	table[(T_Object<<4)+T_float] 		= T_undefined;
+		//	table[(T_Object<<4)+T_boolean]		= T_undefined;
+		//	table[(T_Object<<4)+T_char] 		= T_undefined;
+		//	table[(T_Object<<4)+T_int] 			= T_undefined;
+		//	table[(T_Object<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_double<<4)+T_undefined] 	= T_undefined;
+		table[(T_double<<4)+T_byte] 		= (Double2Double<<12)+(Byte2Double<<4)+T_double;
+		table[(T_double<<4)+T_long] 		= (Double2Double<<12)+(Long2Double<<4)+T_double;
+		table[(T_double<<4)+T_short] 		= (Double2Double<<12)+(Short2Double<<4)+T_double;
+		//	table[(T_double<<4)+T_void] 		= T_undefined;
+		table[(T_double<<4)+T_JavaLangString] 		= (Double2Double<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_double<<4)+T_Object] 		= T_undefined;
+		table[(T_double<<4)+T_double] 		= (Double2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_double<<4)+T_float] 		= (Double2Double<<12)+(Float2Double<<4)+T_double;
+		//	table[(T_double<<4)+T_boolean] 		= T_undefined;
+		table[(T_double<<4)+T_char] 		= (Double2Double<<12)+(Char2Double<<4)+T_double;
+		table[(T_double<<4)+T_int] 			= (Double2Double<<12)+(Int2Double<<4)+T_double;
+		//	table[(T_double<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_float<<4)+T_undefined] 	= T_undefined;
+		table[(T_float<<4)+T_byte] 			= (Float2Float<<12)+(Byte2Float<<4)+T_float;
+		table[(T_float<<4)+T_long] 			= (Float2Float<<12)+(Long2Float<<4)+T_float;
+		table[(T_float<<4)+T_short] 		= (Float2Float<<12)+(Short2Float<<4)+T_float;
+		//	table[(T_float<<4)+T_void] 			= T_undefined;
+		table[(T_float<<4)+T_JavaLangString] 		= (Float2Float<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_float<<4)+T_Object] 		= T_undefined;
+		table[(T_float<<4)+T_double] 		= (Float2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_float<<4)+T_float] 		= (Float2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_float<<4)+T_boolean] 		= T_undefined;
+		table[(T_float<<4)+T_char] 			= (Float2Float<<12)+(Char2Float<<4)+T_float;
+		table[(T_float<<4)+T_int] 			= (Float2Float<<12)+(Int2Float<<4)+T_float;
+		//	table[(T_float<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_boolean<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_byte] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_long] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_short] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_void] 			= T_undefined;
+		table[(T_boolean<<4)+T_JavaLangString] 			= (Boolean2Boolean<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_boolean<<4)+T_Object] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_double] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_float] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_boolean<<4)+T_char] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_int] 			= T_undefined;
+		//	table[(T_boolean<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_char<<4)+T_undefined] 		= T_undefined;
+		table[(T_char<<4)+T_byte] 			= (Char2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_char<<4)+T_long] 			= (Char2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_char<<4)+T_short] 			= (Char2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_void] 			= T_undefined;
+		table[(T_char<<4)+T_JavaLangString] 		= (Char2Char<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_char<<4)+T_Object] 		= T_undefined;
+		table[(T_char<<4)+T_double] 		= (Char2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_char<<4)+T_float] 			= (Char2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_char<<4)+T_boolean] 		= T_undefined;
+		table[(T_char<<4)+T_char] 			= (Char2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_char<<4)+T_int] 			= (Char2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_char<<4)+T_null] 			= T_undefined;
+
+		//	table[(T_int<<4)+T_undefined] 	= T_undefined;
+		table[(T_int<<4)+T_byte] 		= (Int2Int<<12)+(Byte2Int<<4)+T_int;
+		table[(T_int<<4)+T_long] 		= (Int2Long<<12)+(Long2Long<<4)+T_long;
+		table[(T_int<<4)+T_short] 		= (Int2Int<<12)+(Short2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_void] 		= T_undefined;
+		table[(T_int<<4)+T_JavaLangString] 		= (Int2Int<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_int<<4)+T_Object] 		= T_undefined;
+		table[(T_int<<4)+T_double] 		= (Int2Double<<12)+(Double2Double<<4)+T_double;
+		table[(T_int<<4)+T_float] 		= (Int2Float<<12)+(Float2Float<<4)+T_float;
+		//	table[(T_int<<4)+T_boolean] 	= T_undefined;
+		table[(T_int<<4)+T_char] 		= (Int2Int<<12)+(Char2Int<<4)+T_int;
+		table[(T_int<<4)+T_int] 		= (Int2Int<<12)+(Int2Int<<4)+T_int;
+		//	table[(T_int<<4)+T_null] 		= T_undefined;
+
+		//	table[(T_null<<4)+T_undefined] 		= T_undefined;
+		//	table[(T_null<<4)+T_byte] 			= T_undefined;
+		//	table[(T_null<<4)+T_long] 			= T_undefined;
+		//	table[(T_null<<4)+T_short] 			= T_undefined;
+		//	table[(T_null<<4)+T_void] 			= T_undefined;
+		table[(T_null<<4)+T_JavaLangString] 		= (T_null<<16)+(T_null<<12)+(String2String<<4)+T_JavaLangString;
+		//	table[(T_null<<4)+T_Object] 		= T_undefined;
+		//	table[(T_null<<4)+T_double] 		= T_undefined;
+		//	table[(T_null<<4)+T_float] 			= T_undefined;
+		//	table[(T_null<<4)+T_boolean] 		= T_undefined;
+		//	table[(T_null<<4)+T_char] 			= T_undefined;
+		//	table[(T_null<<4)+T_int] 			= T_undefined;
+		//	table[(T_null<<4)+T_null] 			= (Null2String<<12)+(Null2String<<4)+T_String;;
+
+		return table;
+	}
+
+	public static final int[] get_REMAINDER(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_MINUS();
+	}
+
+	public static final int[] get_RIGHT_SHIFT(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_LEFT_SHIFT();
+	}
+
+	public static final int[] get_UNSIGNED_RIGHT_SHIFT(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_LEFT_SHIFT();
+	}
+
+	public static final int[] get_XOR(){
+
+		//the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4
+
+		//	int[] table  = new int[16*16];
+		return get_AND();
+	}
+
+	public String operatorToString() {
+		switch ((this.bits & OperatorMASK) >> OperatorSHIFT) {
+			case EQUAL_EQUAL :
+				return "=="; //$NON-NLS-1$
+			case LESS_EQUAL :
+				return "<="; //$NON-NLS-1$
+			case GREATER_EQUAL :
+				return ">="; //$NON-NLS-1$
+			case NOT_EQUAL :
+				return "!="; //$NON-NLS-1$
+			case LEFT_SHIFT :
+				return "<<"; //$NON-NLS-1$
+			case RIGHT_SHIFT :
+				return ">>"; //$NON-NLS-1$
+			case UNSIGNED_RIGHT_SHIFT :
+				return ">>>"; //$NON-NLS-1$
+			case OR_OR :
+				return "||"; //$NON-NLS-1$
+			case AND_AND :
+				return "&&"; //$NON-NLS-1$
+			case PLUS :
+				return "+"; //$NON-NLS-1$
+			case MINUS :
+				return "-"; //$NON-NLS-1$
+			case NOT :
+				return "!"; //$NON-NLS-1$
+			case REMAINDER :
+				return "%"; //$NON-NLS-1$
+			case XOR :
+				return "^"; //$NON-NLS-1$
+			case AND :
+				return "&"; //$NON-NLS-1$
+			case MULTIPLY :
+				return "*"; //$NON-NLS-1$
+			case OR :
+				return "|"; //$NON-NLS-1$
+			case TWIDDLE :
+				return "~"; //$NON-NLS-1$
+			case DIVIDE :
+				return "/"; //$NON-NLS-1$
+			case GREATER :
+				return ">"; //$NON-NLS-1$
+			case LESS :
+				return "<"; //$NON-NLS-1$
+			case QUESTIONCOLON :
+				return "?:"; //$NON-NLS-1$
+			case EQUAL :
+				return "="; //$NON-NLS-1$
+		}
+		return "unknown operator"; //$NON-NLS-1$
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		output.append('(');
+		return printExpressionNoParenthesis(0, output).append(')');
+	}
+
+	public abstract StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
new file mode 100644
index 0000000..886a639
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+public interface OperatorIds {
+	public static final int AND_AND = 0;
+	public static final int OR_OR = 1;
+	public static final int AND = 2;
+	public static final int OR = 3;
+	public static final int LESS = 4;
+	public static final int LESS_EQUAL = 5;
+	public static final int GREATER = 6;
+	public static final int GREATER_EQUAL = 7;
+	public static final int XOR = 8;
+	public static final int DIVIDE = 9;
+	public static final int LEFT_SHIFT = 10;
+	public static final int NOT = 11;
+	public static final int TWIDDLE = 12;
+	public static final int MINUS = 13;
+	public static final int PLUS = 14;
+	public static final int MULTIPLY = 15;
+	public static final int REMAINDER = 16;
+	public static final int RIGHT_SHIFT = 17;
+	public static final int EQUAL_EQUAL = 18;
+	public static final int UNSIGNED_RIGHT_SHIFT= 19;
+	public static final int NumberOfTables = 20;
+
+	public static final int QUESTIONCOLON = 23;
+
+	public static final int NOT_EQUAL = 29;
+	public static final int EQUAL = 30;
+	public static final int INSTANCEOF = 31;
+	public static final int PLUS_PLUS = 32;
+	public static final int MINUS_MINUS = 33;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
new file mode 100644
index 0000000..0f40e66
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Syntactic representation of a reference to a generic type.
+ * Note that it might also have a dimension.
+ */
+public class ParameterizedQualifiedTypeReference extends ArrayQualifiedTypeReference {
+
+	public TypeReference[][] typeArguments;
+
+	/**
+	 * @param tokens
+	 * @param dim
+	 * @param positions
+	 */
+	public ParameterizedQualifiedTypeReference(char[][] tokens, TypeReference[][] typeArguments, int dim, long[] positions) {
+
+		super(tokens, dim, positions);
+		this.typeArguments = typeArguments;
+		annotationSearch: for (int i = 0, max = typeArguments.length; i < max; i++) {
+			TypeReference[] typeArgumentsOnTypeComponent = typeArguments[i];
+			if (typeArgumentsOnTypeComponent != null) {
+				for (int j = 0, max2 = typeArgumentsOnTypeComponent.length; j < max2; j++) {
+					if ((typeArgumentsOnTypeComponent[j].bits & ASTNode.HasTypeAnnotations) != 0) {
+						this.bits |= ASTNode.HasTypeAnnotations;
+						break annotationSearch;
+					}
+				}
+			}
+		}
+	}
+	public ParameterizedQualifiedTypeReference(char[][] tokens, TypeReference[][] typeArguments, int dim, Annotation[][] annotationsOnDimensions, long[] positions) {
+		this(tokens, typeArguments, dim, positions);
+		this.annotationsOnDimensions = annotationsOnDimensions;
+		if (annotationsOnDimensions != null) {
+			this.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+	public void checkBounds(Scope scope) {
+		if (this.resolvedType == null) return;
+
+		checkBounds(
+			(ReferenceBinding) this.resolvedType.leafComponentType(),
+			scope,
+			this.typeArguments.length - 1);
+	}
+	public void checkBounds(ReferenceBinding type, Scope scope, int index) {
+		// recurse on enclosing type if any, and assuming explictly  part of the reference (index>0)
+		if (index > 0 &&  type.enclosingType() != null) {
+			checkBounds(type.enclosingType(), scope, index - 1);
+		}
+		if (type.isParameterizedTypeWithActualArguments()) {
+			ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
+			ReferenceBinding currentType = parameterizedType.genericType();
+			TypeVariableBinding[] typeVariables = currentType.typeVariables();
+			if (typeVariables != null) { // argTypes may be null in error cases
+				parameterizedType.boundCheck(scope, this.typeArguments[index]);
+			}
+		}
+	}
+	public TypeReference copyDims(int dim){
+		return new ParameterizedQualifiedTypeReference(this.tokens, this.typeArguments, dim, this.sourcePositions);
+	}
+	public TypeReference copyDims(int dim, Annotation[][] dimensionAnnotations){
+		ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = new ParameterizedQualifiedTypeReference(this.tokens, this.typeArguments, dim, dimensionAnnotations, this.sourcePositions);
+		parameterizedQualifiedTypeReference.bits |= (this.bits & ASTNode.HasTypeAnnotations);
+		if (dimensionAnnotations != null) {
+			parameterizedQualifiedTypeReference.bits |= ASTNode.HasTypeAnnotations;
+		}
+		return parameterizedQualifiedTypeReference;
+	}
+	public boolean isParameterizedTypeReference() {
+		return true;
+	}
+
+	/**
+	 * @return char[][]
+	 */
+	public char [][] getParameterizedTypeName(){
+		int length = this.tokens.length;
+		char[][] qParamName = new char[length][];
+		for (int i = 0; i < length; i++) {
+			TypeReference[] arguments = this.typeArguments[i];
+			if (arguments == null) {
+				qParamName[i] = this.tokens[i];
+			} else {
+				StringBuffer buffer = new StringBuffer(5);
+				buffer.append(this.tokens[i]);
+				buffer.append('<');
+				for (int j = 0, argLength =arguments.length; j < argLength; j++) {
+					if (j > 0) buffer.append(',');
+					buffer.append(CharOperation.concatWith(arguments[j].getParameterizedTypeName(), '.'));
+				}
+				buffer.append('>');
+				int nameLength = buffer.length();
+				qParamName[i] = new char[nameLength];
+				buffer.getChars(0, nameLength, qParamName[i], 0);
+			}
+		}
+		int dim = this.dimensions;
+		if (dim > 0) {
+			char[] dimChars = new char[dim*2];
+			for (int i = 0; i < dim; i++) {
+				int index = i*2;
+				dimChars[index] = '[';
+				dimChars[index+1] = ']';
+			}
+			qParamName[length-1] = CharOperation.concat(qParamName[length-1], dimChars);
+		}
+		return qParamName;
+	}
+
+	/* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+     */
+    protected TypeBinding getTypeBinding(Scope scope) {
+        return null; // not supported here - combined with resolveType(...)
+    }
+
+    /*
+     * No need to check for reference to raw type per construction
+     */
+	private TypeBinding internalResolveType(Scope scope, boolean checkBounds) {
+		// handle the error here
+		this.constant = Constant.NotAConstant;
+		if ((this.bits & ASTNode.DidResolve) != 0) { // is a shared type reference which was already resolved
+			if (this.resolvedType != null) { // is a shared type reference which was already resolved
+				if (this.resolvedType.isValidBinding()) {
+					return this.resolvedType;
+				} else {
+					switch (this.resolvedType.problemId()) {
+						case ProblemReasons.NotFound :
+						case ProblemReasons.NotVisible :
+						case ProblemReasons.InheritedNameHidesEnclosingName :
+							TypeBinding type = this.resolvedType.closestMatch();
+							return type;
+						default :
+							return null;
+					}
+				}
+			}
+		}
+		this.bits |= ASTNode.DidResolve;
+		resolveAnnotations(scope);
+		TypeBinding type = internalResolveLeafType(scope, checkBounds);
+		createArrayType(scope);
+		return type == null ? type : this.resolvedType;
+	}
+	private TypeBinding internalResolveLeafType(Scope scope, boolean checkBounds) {
+		boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
+		Binding binding = scope.getPackage(this.tokens);
+		if (binding != null && !binding.isValidBinding()) {
+			this.resolvedType = (ReferenceBinding) binding;
+			reportInvalidType(scope);
+			// be resilient, still attempt resolving arguments
+			for (int i = 0, max = this.tokens.length; i < max; i++) {
+				TypeReference[] args = this.typeArguments[i];
+				if (args != null) {
+					int argLength = args.length;
+					for (int j = 0; j < argLength; j++) {
+						TypeReference typeArgument = args[j];
+						if (isClassScope) {
+							typeArgument.resolveType((ClassScope) scope);
+						} else {
+							typeArgument.resolveType((BlockScope) scope, checkBounds);
+						}
+					}
+				}
+			}
+			return null;
+		}
+
+		PackageBinding packageBinding = binding == null ? null : (PackageBinding) binding;
+		rejectAnnotationsOnPackageQualifiers(scope, packageBinding);
+
+		boolean typeIsConsistent = true;
+		ReferenceBinding qualifyingType = null;
+		for (int i = packageBinding == null ? 0 : packageBinding.compoundName.length, max = this.tokens.length; i < max; i++) {
+			findNextTypeBinding(i, scope, packageBinding);
+			if (!(this.resolvedType.isValidBinding())) {
+				reportInvalidType(scope);
+				// be resilient, still attempt resolving arguments
+				for (int j = i; j < max; j++) {
+				    TypeReference[] args = this.typeArguments[j];
+				    if (args != null) {
+						int argLength = args.length;
+						for (int k = 0; k < argLength; k++) {
+						    TypeReference typeArgument = args[k];
+						    if (isClassScope) {
+						    	typeArgument.resolveType((ClassScope) scope);
+						    } else {
+						    	typeArgument.resolveType((BlockScope) scope);
+						    }
+						}
+				    }
+				}
+				return null;
+			}
+			ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
+			if (qualifyingType == null) {
+				qualifyingType = currentType.enclosingType(); // if member type
+				if (qualifyingType != null) {
+					qualifyingType = currentType.isStatic()
+						? (ReferenceBinding) scope.environment().convertToRawType(qualifyingType, false /*do not force conversion of enclosing types*/)
+						: scope.environment().convertToParameterizedType(qualifyingType);
+				}
+			} else {
+				 rejectAnnotationsOnStaticMemberQualififer(scope, currentType, i);
+				if (typeIsConsistent && currentType.isStatic()
+						&& (qualifyingType.isParameterizedTypeWithActualArguments() || qualifyingType.isGenericType())) {
+					scope.problemReporter().staticMemberOfParameterizedType(this, scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifyingType), i);
+					typeIsConsistent = false;
+				}
+				ReferenceBinding enclosingType = currentType.enclosingType();
+				if (enclosingType != null && enclosingType.erasure() != qualifyingType.erasure()) { // qualifier != declaring/enclosing
+					qualifyingType = enclosingType; // inherited member type, leave it associated with its enclosing rather than subtype
+				}
+			}
+
+			// check generic and arity
+		    TypeReference[] args = this.typeArguments[i];
+		    if (args != null) {
+			    TypeReference keep = null;
+			    if (isClassScope) {
+			    	keep = ((ClassScope) scope).superTypeReference;
+			    	((ClassScope) scope).superTypeReference = null;
+			    }
+				int argLength = args.length;
+				boolean isDiamond = argLength == 0 && (i == (max -1)) && ((this.bits & ASTNode.IsDiamond) != 0);
+				TypeBinding[] argTypes = new TypeBinding[argLength];
+				boolean argHasError = false;
+				ReferenceBinding currentOriginal = (ReferenceBinding)currentType.original();
+				for (int j = 0; j < argLength; j++) {
+				    TypeReference arg = args[j];
+				    TypeBinding argType = isClassScope
+						? arg.resolveTypeArgument((ClassScope) scope, currentOriginal, j)
+						: arg.resolveTypeArgument((BlockScope) scope, currentOriginal, j);
+					if (argType == null) {
+						argHasError = true;
+					} else {
+						if (arg.annotations != null)
+							argTypes[j] = captureTypeAnnotations(scope, qualifyingType, argType, arg.annotations[0]);
+						else
+							argTypes[j] = argType;
+					}
+				}
+				if (argHasError) {
+					return null;
+				}
+				if (isClassScope) {
+					((ClassScope) scope).superTypeReference = keep;
+					if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this))
+						return null;
+				}
+
+			    TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
+				if (typeVariables == Binding.NO_TYPE_VARIABLES) { // check generic
+					if (scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5) { // below 1.5, already reported as syntax error
+						scope.problemReporter().nonGenericTypeCannotBeParameterized(i, this, currentType, argTypes);
+						return null;
+					}
+					this.resolvedType =  (qualifyingType != null && qualifyingType.isParameterizedType())
+						? scope.environment().createParameterizedType(currentOriginal, null, qualifyingType)
+						: currentType;
+					return this.resolvedType;
+				} else if (argLength != typeVariables.length) {
+					if (!isDiamond) { // check arity
+						scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes, i);
+						return null;
+					}
+				}
+				// check parameterizing non-static member type of raw type
+				if (typeIsConsistent && !currentType.isStatic()) {
+					ReferenceBinding actualEnclosing = currentType.enclosingType();
+					if (actualEnclosing != null && actualEnclosing.isRawType()) {
+						scope.problemReporter().rawMemberTypeCannotBeParameterized(
+								this, scope.environment().createRawType(currentOriginal, actualEnclosing), argTypes);
+						typeIsConsistent = false;
+					}
+				}
+				ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(currentOriginal, argTypes, currentType.tagBits & TagBits.AnnotationNullMASK, qualifyingType);
+				// check argument type compatibility for non <> cases - <> case needs no bounds check, we will scream foul if needed during inference.
+				if (!isDiamond) {
+					if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+						parameterizedType.boundCheck(scope, args);
+					else
+						scope.deferBoundCheck(this);
+				}
+				qualifyingType = parameterizedType;
+		    } else {
+				ReferenceBinding currentOriginal = (ReferenceBinding)currentType.original();
+				if (isClassScope)
+					if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this))
+						return null;
+				if (currentOriginal.isGenericType()) {
+	   			    if (typeIsConsistent && qualifyingType != null && qualifyingType.isParameterizedType()) {
+						scope.problemReporter().parameterizedMemberTypeMissingArguments(this, scope.environment().createParameterizedType(currentOriginal, null, qualifyingType), i);
+						typeIsConsistent = false;
+					}
+	   			    qualifyingType = scope.environment().createRawType(currentOriginal, qualifyingType); // raw type
+				} else {
+					qualifyingType = (qualifyingType != null && qualifyingType.isParameterizedType())
+													? scope.environment().createParameterizedType(currentOriginal, null, qualifyingType)
+													: currentType;
+				}
+			}
+			if (isTypeUseDeprecated(qualifyingType, scope))
+				reportDeprecatedType(qualifyingType, scope, i);
+			this.resolvedType = qualifyingType;
+			recordResolution(scope.environment(), this.resolvedType);
+		}
+		return this.resolvedType;
+	}
+	private void createArrayType(Scope scope) {
+		if (this.dimensions > 0) {
+			if (this.dimensions > 255)
+				scope.problemReporter().tooManyDimensions(this);
+			this.resolvedType = scope.createArrayType(this.resolvedType, this.dimensions);
+		}
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		int length = this.tokens.length;
+		for (int i = 0; i < length - 1; i++) {
+			if (this.annotations != null && this.annotations[i] != null) {
+				printAnnotations(this.annotations[i], output);
+				output.append(' ');
+			}
+			output.append(this.tokens[i]);
+			TypeReference[] typeArgument = this.typeArguments[i];
+			if (typeArgument != null) {
+				output.append('<');
+				int typeArgumentLength = typeArgument.length;
+				if (typeArgumentLength > 0) {
+					int max = typeArgumentLength - 1;
+					for (int j = 0; j < max; j++) {
+						typeArgument[j].print(0, output);
+						output.append(", ");//$NON-NLS-1$
+					}
+					typeArgument[max].print(0, output);
+				}
+				output.append('>');
+			}
+			output.append('.');
+		}
+		if (this.annotations != null && this.annotations[length - 1] != null) {
+			output.append(" "); //$NON-NLS-1$
+			printAnnotations(this.annotations[length - 1], output);
+			output.append(' ');
+		}
+		output.append(this.tokens[length - 1]);
+		TypeReference[] typeArgument = this.typeArguments[length - 1];
+		if (typeArgument != null) {
+			output.append('<');
+			int typeArgumentLength = typeArgument.length;
+			if (typeArgumentLength > 0) {
+				int max = typeArgumentLength - 1;
+				for (int j = 0; j < max; j++) {
+					typeArgument[j].print(0, output);
+					output.append(", ");//$NON-NLS-1$
+				}
+				typeArgument[max].print(0, output);
+			}
+			output.append('>');
+		}
+		if ((this.bits & IsVarArgs) != 0) {
+			for (int i= 0 ; i < this.dimensions - 1; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
+				output.append(" "); //$NON-NLS-1$
+				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
+				output.append(" "); //$NON-NLS-1$
+			}
+			output.append("..."); //$NON-NLS-1$
+		} else {
+			for (int i= 0 ; i < this.dimensions; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+	    return internalResolveType(scope, checkBounds);
+	}
+	public TypeBinding resolveType(ClassScope scope) {
+	    return internalResolveType(scope, false);
+	}
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
+						Annotation annotation = annotations2[j];
+						annotation.traverse(visitor, scope);
+					}
+				}
+			}
+			for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+				if (this.typeArguments[i] != null) {
+					for (int j = 0, max2 = this.typeArguments[i].length; j < max2; j++) {
+						this.typeArguments[i][j].traverse(visitor, scope);
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					for (int j = 0, max2 = annotations2 == null ? 0 : annotations2.length; j < max2; j++) {
+						Annotation annotation = annotations2[j];
+						annotation.traverse(visitor, scope);
+					}
+				}
+			}
+			for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+				if (this.typeArguments[i] != null) {
+					for (int j = 0, max2 = this.typeArguments[i].length; j < max2; j++) {
+						this.typeArguments[i][j].traverse(visitor, scope);
+					}
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
new file mode 100644
index 0000000..b3b26f2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Syntactic representation of a reference to a generic type.
+ * Note that it might also have a dimension.
+ */
+public class ParameterizedSingleTypeReference extends ArrayTypeReference {
+
+	public TypeReference[] typeArguments;
+
+	public ParameterizedSingleTypeReference(char[] name, TypeReference[] typeArguments, int dim, long pos){
+		super(name, dim, pos);
+		this.originalSourceEnd = this.sourceEnd;
+		this.typeArguments = typeArguments;
+		for (int i = 0, max = typeArguments.length; i < max; i++) {
+			if ((typeArguments[i].bits & ASTNode.HasTypeAnnotations) != 0) {
+				this.bits |= ASTNode.HasTypeAnnotations;
+				break;
+			}
+		}
+	}
+	public ParameterizedSingleTypeReference(char[] name, TypeReference[] typeArguments, int dim, Annotation[][] annotationsOnDimensions, long pos) {
+		this(name, typeArguments, dim, pos);
+		this.annotationsOnDimensions = annotationsOnDimensions;
+		if (annotationsOnDimensions != null) {
+			this.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+	public void checkBounds(Scope scope) {
+		if (this.resolvedType == null) return;
+
+		if (this.resolvedType.leafComponentType() instanceof ParameterizedTypeBinding) {
+			ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) this.resolvedType.leafComponentType();
+			ReferenceBinding currentType = parameterizedType.genericType();
+			TypeVariableBinding[] typeVariables = currentType.typeVariables();
+			TypeBinding[] argTypes = parameterizedType.arguments;
+			if (argTypes != null && typeVariables != null) { // may be null in error cases
+				parameterizedType.boundCheck(scope, this.typeArguments);
+			}
+		}
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
+	 */
+	public TypeReference copyDims(int dim) {
+		return new ParameterizedSingleTypeReference(this.token, this.typeArguments, dim, (((long)this.sourceStart)<<32)+this.sourceEnd);
+	}
+	public TypeReference copyDims(int dim, Annotation [][] annotationsOnDims) {
+		ParameterizedSingleTypeReference parameterizedSingleTypeReference = new ParameterizedSingleTypeReference(this.token, this.typeArguments, dim, annotationsOnDims, (((long)this.sourceStart)<<32)+this.sourceEnd);
+		parameterizedSingleTypeReference.bits |= (this.bits & ASTNode.HasTypeAnnotations);
+		if (annotationsOnDims != null) {
+			parameterizedSingleTypeReference.bits |= ASTNode.HasTypeAnnotations;
+		}
+		return parameterizedSingleTypeReference;
+	}
+
+	/**
+	 * @return char[][]
+	 */
+	public char [][] getParameterizedTypeName(){
+		StringBuffer buffer = new StringBuffer(5);
+		buffer.append(this.token).append('<');
+		for (int i = 0, length = this.typeArguments.length; i < length; i++) {
+			if (i > 0) buffer.append(',');
+			buffer.append(CharOperation.concatWith(this.typeArguments[i].getParameterizedTypeName(), '.'));
+		}
+		buffer.append('>');
+		int nameLength = buffer.length();
+		char[] name = new char[nameLength];
+		buffer.getChars(0, nameLength, name, 0);
+		int dim = this.dimensions;
+		if (dim > 0) {
+			char[] dimChars = new char[dim*2];
+			for (int i = 0; i < dim; i++) {
+				int index = i*2;
+				dimChars[index] = '[';
+				dimChars[index+1] = ']';
+			}
+			name = CharOperation.concat(name, dimChars);
+		}
+		return new char[][]{ name };
+	}
+	/**
+     * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+     */
+    protected TypeBinding getTypeBinding(Scope scope) {
+        return null; // not supported here - combined with resolveType(...)
+    }
+    
+    public boolean isParameterizedTypeReference() {
+    	return true;
+    }
+
+    /*
+     * No need to check for reference to raw type per construction
+     */
+	private TypeBinding internalResolveType(Scope scope, ReferenceBinding enclosingType, boolean checkBounds) {
+		// handle the error here
+		this.constant = Constant.NotAConstant;
+		if ((this.bits & ASTNode.DidResolve) != 0) { // is a shared type reference which was already resolved
+			if (this.resolvedType != null) { // is a shared type reference which was already resolved
+				if (this.resolvedType.isValidBinding()) {
+					return this.resolvedType;
+				} else {
+					switch (this.resolvedType.problemId()) {
+						case ProblemReasons.NotFound :
+						case ProblemReasons.NotVisible :
+						case ProblemReasons.InheritedNameHidesEnclosingName :
+							TypeBinding type = this.resolvedType.closestMatch();
+							return type;
+						default :
+							return null;
+					}
+				}
+			}
+		}
+		this.bits |= ASTNode.DidResolve;
+		TypeBinding type = internalResolveLeafType(scope, enclosingType, checkBounds);
+		resolveAnnotations(scope);
+		// handle three different outcomes:
+		if (type == null) {
+			this.resolvedType = createArrayType(scope, this.resolvedType);
+			return null;							// no useful type, but still captured dimensions into this.resolvedType
+		} else {
+			type = createArrayType(scope, type);
+			if (!this.resolvedType.isValidBinding())
+				return type;						// found some error, but could recover useful type (like closestMatch)
+			else 
+				return this.resolvedType = type; 	// no complaint, keep fully resolved type (incl. dimensions)
+		}
+	}
+	private TypeBinding internalResolveLeafType(Scope scope, ReferenceBinding enclosingType, boolean checkBounds) {
+		ReferenceBinding currentType;
+		if (enclosingType == null) {
+			this.resolvedType = scope.getType(this.token);
+			if (this.resolvedType.isValidBinding()) {
+				currentType = (ReferenceBinding) this.resolvedType;
+			} else {
+				reportInvalidType(scope);
+				switch (this.resolvedType.problemId()) {
+					case ProblemReasons.NotFound :
+					case ProblemReasons.NotVisible :
+					case ProblemReasons.InheritedNameHidesEnclosingName :
+						TypeBinding type = this.resolvedType.closestMatch();
+						if (type instanceof ReferenceBinding) {
+							currentType = (ReferenceBinding) type;
+							break;
+						}
+						//$FALL-THROUGH$ - unable to complete type binding, but still resolve type arguments
+					default :
+						boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
+					int argLength = this.typeArguments.length;
+					for (int i = 0; i < argLength; i++) {
+						TypeReference typeArgument = this.typeArguments[i];
+						if (isClassScope) {
+							typeArgument.resolveType((ClassScope) scope);
+						} else {
+							typeArgument.resolveType((BlockScope) scope, checkBounds);
+						}
+					}
+					return null;
+				}
+				// be resilient, still attempt resolving arguments
+			}
+			enclosingType = currentType.enclosingType(); // if member type
+			if (enclosingType != null) {
+				enclosingType = currentType.isStatic()
+					? (ReferenceBinding) scope.environment().convertToRawType(enclosingType, false /*do not force conversion of enclosing types*/)
+					: scope.environment().convertToParameterizedType(enclosingType);
+				currentType = scope.environment().createParameterizedType((ReferenceBinding) currentType.erasure(), null /* no arg */, enclosingType);
+			}
+		} else { // resolving member type (relatively to enclosingType)
+			this.resolvedType = currentType = scope.getMemberType(this.token, enclosingType);
+			if (!this.resolvedType.isValidBinding()) {
+				scope.problemReporter().invalidEnclosingType(this, currentType, enclosingType);
+				return null;
+			}
+			if (isTypeUseDeprecated(currentType, scope))
+				scope.problemReporter().deprecatedType(currentType, this);
+			ReferenceBinding currentEnclosing = currentType.enclosingType();
+			if (currentEnclosing != null && currentEnclosing.erasure() != enclosingType.erasure()) {
+				enclosingType = currentEnclosing; // inherited member type, leave it associated with its enclosing rather than subtype
+			}
+		}
+
+		// check generic and arity
+	    boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
+	    TypeReference keep = null;
+	    if (isClassScope) {
+	    	keep = ((ClassScope) scope).superTypeReference;
+	    	((ClassScope) scope).superTypeReference = null;
+	    }
+		int argLength = this.typeArguments.length;
+		TypeBinding[] argTypes = new TypeBinding[argLength];
+		boolean argHasError = false;
+		ReferenceBinding currentOriginal = (ReferenceBinding)currentType.original();
+		for (int i = 0; i < argLength; i++) {
+		    TypeReference typeArgument = this.typeArguments[i];
+		    TypeBinding argType = isClassScope
+				? typeArgument.resolveTypeArgument((ClassScope) scope, currentOriginal, i)
+				: typeArgument.resolveTypeArgument((BlockScope) scope, currentOriginal, i);
+			this.bits |= (typeArgument.bits & ASTNode.HasTypeAnnotations);
+		     if (argType == null) {
+		         argHasError = true;
+		     } else {
+			    if (typeArgument.annotations != null)
+			    	argTypes[i] = captureTypeAnnotations(scope, enclosingType, argType, typeArgument.annotations[0]);
+			    else
+			    	argTypes[i] = argType;
+		     }
+		}
+		if (argHasError) {
+			return null;
+		}
+		if (isClassScope) {
+	    	((ClassScope) scope).superTypeReference = keep;
+			if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this))
+				return null;
+		}
+
+		final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
+		TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
+		if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
+			boolean isCompliant15 = scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
+			if ((currentOriginal.tagBits & TagBits.HasMissingType) == 0) {
+				if (isCompliant15) { // below 1.5, already reported as syntax error
+					this.resolvedType = currentType;
+					scope.problemReporter().nonGenericTypeCannotBeParameterized(0, this, currentType, argTypes);
+					return null;
+				}
+			}
+			// resilience do not rebuild a parameterized type unless compliance is allowing it
+			if (!isCompliant15) {
+				if (!this.resolvedType.isValidBinding())
+					return currentType;
+				return this.resolvedType = currentType;
+			}
+			// if missing generic type, and compliance >= 1.5, then will rebuild a parameterized binding
+		} else if (argLength != typeVariables.length) {
+			if (!isDiamond) { // check arity, IsDiamond never set for 1.6-
+				scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
+				return null;
+			} 
+		} else if (!currentType.isStatic()) {
+			ReferenceBinding actualEnclosing = currentType.enclosingType();
+			if (actualEnclosing != null && actualEnclosing.isRawType()){
+				scope.problemReporter().rawMemberTypeCannotBeParameterized(
+						this, scope.environment().createRawType(currentOriginal, actualEnclosing), argTypes);
+				return null;
+			}
+		}
+
+    	ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(currentOriginal, argTypes, enclosingType);
+		// check argument type compatibility for non <> cases - <> case needs no bounds check, we will scream foul if needed during inference.
+    	if (!isDiamond) {
+    		if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+    			parameterizedType.boundCheck(scope, this.typeArguments);
+    		else
+    			scope.deferBoundCheck(this);
+    	}
+		if (isTypeUseDeprecated(parameterizedType, scope))
+			reportDeprecatedType(parameterizedType, scope);
+
+		if (!this.resolvedType.isValidBinding()) {
+			return parameterizedType;
+		}
+		return this.resolvedType = parameterizedType;
+	}
+	private TypeBinding createArrayType(Scope scope, TypeBinding type) {
+		if (this.dimensions > 0) {
+			if (this.dimensions > 255)
+				scope.problemReporter().tooManyDimensions(this);
+			return scope.createArrayType(type, this.dimensions);
+		}
+		return type;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+		if (this.annotations != null && this.annotations[0] != null) {
+			printAnnotations(this.annotations[0], output);
+			output.append(' ');
+		}
+		output.append(this.token);
+		output.append("<"); //$NON-NLS-1$
+		int length = this.typeArguments.length;
+		if (length > 0) {
+			int max = length - 1;
+			for (int i= 0; i < max; i++) {
+				this.typeArguments[i].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+		}
+		output.append(">"); //$NON-NLS-1$
+		if ((this.bits & IsVarArgs) != 0) {
+			for (int i= 0 ; i < this.dimensions - 1; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[this.dimensions - 1] != null) {
+				output.append(" "); //$NON-NLS-1$
+				printAnnotations(this.annotationsOnDimensions[this.dimensions - 1], output);
+				output.append(" "); //$NON-NLS-1$
+			}
+			output.append("..."); //$NON-NLS-1$
+		} else {
+			for (int i= 0 ; i < this.dimensions; i++) {
+				if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
+					output.append(" "); //$NON-NLS-1$
+					printAnnotations(this.annotationsOnDimensions[i], output);
+					output.append(" "); //$NON-NLS-1$
+				}
+				output.append("[]"); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+	    return internalResolveType(scope, null, checkBounds);
+	}
+
+	public TypeBinding resolveType(ClassScope scope) {
+	    return internalResolveType(scope, null, false /*no bounds check in classScope*/);
+	}
+
+	public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
+	    return internalResolveType(scope, enclosingType, true/*check bounds*/);
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
+					typeAnnotations[i].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					if (annotations2 != null) {
+						for (int j = 0, max2 = annotations2.length; j < max2; j++) {
+							Annotation annotation = annotations2[j];
+							annotation.traverse(visitor, scope);
+						}
+					}
+				}
+			}
+			for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+				this.typeArguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++) {
+					typeAnnotations[i].traverse(visitor, scope);
+				}
+			}
+			if (this.annotationsOnDimensions != null) {
+				for (int i = 0, max = this.annotationsOnDimensions.length; i < max; i++) {
+					Annotation[] annotations2 = this.annotationsOnDimensions[i];
+					for (int j = 0, max2 = annotations2.length; j < max2; j++) {
+						Annotation annotation = annotations2[j];
+						annotation.traverse(visitor, scope);
+					}
+				}
+			}
+			for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+				this.typeArguments[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
new file mode 100644
index 0000000..3bd8187
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class PostfixExpression extends CompoundAssignment {
+
+public PostfixExpression(Expression lhs, Expression expression, int operator, int pos) {
+	super(lhs, expression, operator, pos);
+	this.sourceStart = lhs.sourceStart;
+	this.sourceEnd = pos;
+}
+public boolean checkCastCompatibility() {
+	return false;
+}
+/**
+ * Code generation for PostfixExpression
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	// various scenarii are possible, setting an array reference,
+	// a field reference, a blank final field reference, a field of an enclosing instance or
+	// just a local variable.
+
+	int pc = codeStream.position;
+	 ((Reference) this.lhs).generatePostIncrement(currentScope, codeStream, this, valueRequired);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public String operatorToString() {
+	switch (this.operator) {
+		case PLUS :
+			return "++"; //$NON-NLS-1$
+		case MINUS :
+			return "--"; //$NON-NLS-1$
+	}
+	return "unknown operator"; //$NON-NLS-1$
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+	return this.lhs.printExpression(indent, output).append(' ').append(operatorToString());
+}
+
+public boolean restrainUsageToNumericTypes() {
+	return true;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+
+	if (visitor.visit(this, scope)) {
+		this.lhs.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
new file mode 100644
index 0000000..19ecf14
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class PrefixExpression extends CompoundAssignment {
+
+/**
+ * PrefixExpression constructor comment.
+ * @param lhs org.eclipse.jdt.internal.compiler.ast.Expression
+ * @param expression org.eclipse.jdt.internal.compiler.ast.Expression
+ * @param operator int
+ */
+public PrefixExpression(Expression lhs, Expression expression, int operator, int pos) {
+	super(lhs, expression, operator, lhs.sourceEnd);
+	this.sourceStart = pos;
+	this.sourceEnd = lhs.sourceEnd;
+}
+public boolean checkCastCompatibility() {
+	return false;
+}
+public String operatorToString() {
+	switch (this.operator) {
+		case PLUS :
+			return "++"; //$NON-NLS-1$
+		case MINUS :
+			return "--"; //$NON-NLS-1$
+	}
+	return "unknown operator"; //$NON-NLS-1$
+}
+
+public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+
+	output.append(operatorToString()).append(' ');
+	return this.lhs.printExpression(0, output);
+}
+
+public boolean restrainUsageToNumericTypes() {
+	return true;
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		this.lhs.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
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
new file mode 100644
index 0000000..ec3a54f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -0,0 +1,585 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ ******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * Variation on allocation, where can optionally be specified any of:
+ * - leading enclosing instance
+ * - trailing anonymous type
+ * - generic type arguments for generic constructor invocation
+ */
+public class QualifiedAllocationExpression extends AllocationExpression {
+
+	//qualification may be on both side
+	public Expression enclosingInstance;
+	public TypeDeclaration anonymousType;
+
+	public QualifiedAllocationExpression() {
+		// for subtypes
+	}
+
+	public QualifiedAllocationExpression(TypeDeclaration anonymousType) {
+		this.anonymousType = anonymousType;
+		anonymousType.allocation = this;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		// analyse the enclosing instance
+		if (this.enclosingInstance != null) {
+			flowInfo = this.enclosingInstance.analyseCode(currentScope, flowContext, flowInfo);
+		} else {
+			if (this.binding != null && this.binding.declaringClass != null) {
+				ReferenceBinding superclass = this.binding.declaringClass.superclass();
+				if (superclass != null && superclass.isMemberType() && !superclass.isStatic()) {
+					// creating an anonymous type of a non-static member type without an enclosing instance of parent type
+					currentScope.tagAsAccessingEnclosingInstanceStateOf(superclass.enclosingType(), false /* type variable access */);
+					// Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
+					// The corresponding problem (when called from static) is not produced until during code generation
+				}
+			}
+			
+		}
+
+		// check captured variables are initialized in current context (26134)
+		checkCapturedLocalInitializationIfNecessary(
+			(ReferenceBinding)(this.anonymousType == null
+				? this.binding.declaringClass.erasure()
+				: this.binding.declaringClass.superclass().erasure()),
+			currentScope,
+			flowInfo);
+
+		// process arguments
+		if (this.arguments != null) {
+			boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
+			boolean hasResourceWrapperType = analyseResources 
+						&& this.resolvedType instanceof ReferenceBinding 
+						&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
+			for (int i = 0, count = this.arguments.length; i < count; i++) {
+				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
+				if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
+					// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
+					flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
+				}
+				this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+			}
+			analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
+		}
+
+		// analyse the anonymous nested type
+		if (this.anonymousType != null) {
+			flowInfo = this.anonymousType.analyseCode(currentScope, flowContext, flowInfo);
+		}
+
+		// record some dependency information for exception types
+		ReferenceBinding[] thrownExceptions;
+		if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
+			if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+				thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
+			}			
+			// check exception handling
+			flowContext.checkExceptionHandlers(
+				thrownExceptions,
+				this,
+				flowInfo.unconditionalCopy(),
+				currentScope);
+		}
+
+		// after having analysed exceptions above start tracking newly allocated resource:
+		if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType)) {
+			FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
+		}
+
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+		manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+
+		// account for possible exceptions thrown by constructor execution:
+		flowContext.recordAbruptExit();
+
+		return flowInfo;
+	}
+
+	public Expression enclosingInstance() {
+
+		return this.enclosingInstance;
+	}
+
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		if (!valueRequired)
+			currentScope.problemReporter().unusedObjectAllocation(this);
+		int pc = codeStream.position;
+		MethodBinding codegenBinding = this.binding.original();
+		ReferenceBinding allocatedType = codegenBinding.declaringClass;
+		codeStream.new_(this.type, allocatedType);
+		boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+		if (valueRequired || isUnboxing) {
+			codeStream.dup();
+		}
+		// better highlight for allocation: display the type individually
+		if (this.type != null) { // null for enum constant body
+			codeStream.recordPositionsFrom(pc, this.type.sourceStart);
+		} else {
+			// push enum constant name and ordinal
+			codeStream.ldc(String.valueOf(this.enumConstant.name));
+			codeStream.generateInlinedValue(this.enumConstant.binding.id);
+		}
+		// handling innerclass instance allocation - enclosing instance arguments
+		if (allocatedType.isNestedType()) {
+			codeStream.generateSyntheticEnclosingInstanceValues(
+				currentScope,
+				allocatedType,
+				enclosingInstance(),
+				this);
+		}
+		// generate the arguments for constructor
+		generateArguments(this.binding, this.arguments, currentScope, codeStream);
+		// handling innerclass instance allocation - outer local arguments
+		if (allocatedType.isNestedType()) {
+			codeStream.generateSyntheticOuterArgumentValues(
+				currentScope,
+				allocatedType,
+				this);
+		}
+
+		// invoke constructor
+		if (this.syntheticAccessor == null) {
+			codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments);
+		} else {
+			// synthetic accessor got some extra arguments appended to its signature, which need values
+			for (int i = 0,
+				max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
+				i < max;
+				i++) {
+				codeStream.aconst_null();
+			}
+			codeStream.invoke(Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */);
+		}
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		} else if (isUnboxing) {
+			// conversion only generated if unboxing
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			switch (postConversionType(currentScope).id) {
+				case T_long :
+				case T_double :
+					codeStream.pop2();
+					break;
+				default :
+					codeStream.pop();
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+
+		if (this.anonymousType != null) {
+			this.anonymousType.generateCode(currentScope, codeStream);
+		}
+	}
+
+	public boolean isSuperAccess() {
+
+		// necessary to lookup super constructor of anonymous type
+		return this.anonymousType != null;
+	}
+
+	/* Inner emulation consists in either recording a dependency
+	 * link only, or performing one level of propagation.
+	 *
+	 * Dependency mechanism is used whenever dealing with source target
+	 * types, since by the time we reach them, we might not yet know their
+	 * exact need.
+	 */
+	public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+		ReferenceBinding allocatedTypeErasure = (ReferenceBinding) this.binding.declaringClass.erasure();
+
+		// perform some extra emulation work in case there is some and we are inside a local type only
+		if (allocatedTypeErasure.isNestedType()
+			&& currentScope.enclosingSourceType().isLocalType()) {
+
+			if (allocatedTypeErasure.isLocalType()) {
+				((LocalTypeBinding) allocatedTypeErasure).addInnerEmulationDependent(currentScope, this.enclosingInstance != null);
+			} else {
+				// locally propagate, since we already now the desired shape for sure
+				currentScope.propagateInnerEmulation(allocatedTypeErasure, this.enclosingInstance != null);
+			}
+		}
+		}
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		if (this.enclosingInstance != null)
+			this.enclosingInstance.printExpression(0, output).append('.');
+		super.printExpression(0, output);
+		if (this.anonymousType != null) {
+			this.anonymousType.print(indent, output);
+		}
+		return output;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		// added for code assist...cannot occur with 'normal' code
+		if (this.anonymousType == null && this.enclosingInstance == null) {
+			return super.resolveType(scope);
+		}
+
+		// Propagate the type checking to the arguments, and checks if the constructor is defined.
+		// ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+		// ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+
+		this.constant = Constant.NotAConstant;
+		TypeBinding enclosingInstanceType = null;
+		ReferenceBinding enclosingInstanceReference = null;
+		TypeBinding receiverType = null;
+		boolean hasError = false;
+		boolean enclosingInstanceContainsCast = false;
+		boolean argsContainCast = false;
+
+		if (this.enclosingInstance != null) {
+			if (this.enclosingInstance instanceof CastExpression) {
+				this.enclosingInstance.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+				enclosingInstanceContainsCast = true;
+			}
+			if ((enclosingInstanceType = this.enclosingInstance.resolveType(scope)) == null){
+				hasError = true;
+			} else if (enclosingInstanceType.isBaseType() || enclosingInstanceType.isArrayType()) {
+				scope.problemReporter().illegalPrimitiveOrArrayTypeForEnclosingInstance(
+					enclosingInstanceType,
+					this.enclosingInstance);
+				hasError = true;
+			} 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) {
+					CastExpression.checkNeedForEnclosingInstanceCast(scope, this.enclosingInstance, enclosingInstanceType, receiverType);
+				}
+			}
+		} else {
+			if (this.type == null) {
+				// initialization of an enum constant
+				receiverType = scope.enclosingSourceType();
+			} else {
+				receiverType = this.type.resolveType(scope, true /* check bounds*/);
+				checkParameterizedAllocation: {
+					if (receiverType == null || !receiverType.isValidBinding()) break checkParameterizedAllocation;
+					if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
+						ReferenceBinding currentType = (ReferenceBinding)receiverType;
+						do {
+							// isStatic() is answering true for toplevel types
+							if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
+							if (currentType.isRawType()) break checkParameterizedAllocation;
+						} while ((currentType = currentType.enclosingType())!= null);
+						ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
+						for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
+							if (qRef.typeArguments[i] != null) {
+								scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, receiverType);
+								break;
+							}
+						}
+					}
+				}
+			}
+		}
+		if (receiverType == null || !receiverType.isValidBinding()) {
+			hasError = true;
+		}
+
+		// resolve type arguments (for generic constructor call)
+		final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+		if (this.typeArguments != null) {
+			int length = this.typeArguments.length;
+			boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+			this.genericTypeArguments = new TypeBinding[length];
+			for (int i = 0; i < length; i++) {
+				TypeReference typeReference = this.typeArguments[i];
+				if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+					argHasError = true;
+				}
+				if (argHasError && typeReference instanceof Wildcard) {
+					scope.problemReporter().illegalUsageOfWildcard(typeReference);
+				}
+			}
+			if (isDiamond) {
+				scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
+				return null;
+			}
+			if (argHasError) {
+				if (this.arguments != null) { // still attempt to resolve arguments
+					for (int i = 0, max = this.arguments.length; i < max; i++) {
+						this.arguments[i].resolveType(scope);
+					}
+				}
+				return null;
+			}
+		}
+
+		// will check for null after args are resolved
+		TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+		boolean polyExpressionSeen = false;
+		if (this.arguments != null) {
+			int length = this.arguments.length;
+			argumentTypes = new TypeBinding[length];
+			TypeBinding argumentType;
+			for (int i = 0; i < length; i++) {
+				Expression argument = this.arguments[i];
+				if (argument instanceof CastExpression) {
+					argument.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
+					argsContainCast = true;
+				}
+				argument.setExpressionContext(INVOCATION_CONTEXT);
+				if ((argumentType = argumentTypes[i] = argument.resolveType(scope)) == null){
+					hasError = true;
+				}
+				if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+					polyExpressionSeen = true;
+			}
+		}
+
+		// limit of fault-tolerance
+		if (hasError) {
+			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
+			   No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
+			   not return the partially resolved type.
+			 */
+			if (isDiamond) {
+				return null; // not the partially cooked this.resolvedType
+			}
+			if (receiverType instanceof ReferenceBinding) {
+				ReferenceBinding referenceReceiver = (ReferenceBinding) receiverType;
+				if (receiverType.isValidBinding()) {
+					// record a best guess, for clients who need hint about possible contructor match
+					int length = this.arguments  == null ? 0 : this.arguments.length;
+					TypeBinding[] pseudoArgs = new TypeBinding[length];
+					for (int i = length; --i >= 0;) {
+						pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
+					}
+					this.binding = scope.findMethod(referenceReceiver, TypeConstants.INIT, pseudoArgs, this);
+					if (this.binding != null && !this.binding.isValidBinding()) {
+						MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+						// record the closest match, for clients who may still need hint about possible method match
+						if (closestMatch != null) {
+							if (closestMatch.original().typeVariables != Binding.NO_TYPE_VARIABLES) { // generic method
+								// shouldn't return generic method outside its context, rather convert it to raw method (175409)
+								closestMatch = scope.environment().createParameterizedGenericMethod(closestMatch.original(), (RawTypeBinding)null);
+							}
+							this.binding = closestMatch;
+							MethodBinding closestMatchOriginal = closestMatch.original();
+							if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
+								// ignore cases where method is used from within inside itself (e.g. direct recursions)
+								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+							}
+						}
+					}
+				}
+				if (this.anonymousType != null) {
+					// insert anonymous type in scope (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210070)
+					scope.addAnonymousType(this.anonymousType, referenceReceiver);
+					this.anonymousType.resolve(scope);
+					return this.resolvedType = this.anonymousType.binding;
+				}
+			}
+			return this.resolvedType = receiverType;
+		}
+		if (this.anonymousType == null) {
+			// qualified allocation with no anonymous type
+			if (!receiverType.canBeInstantiated()) {
+				scope.problemReporter().cannotInstantiate(this.type, receiverType);
+				return this.resolvedType = receiverType;
+			}
+			if (isDiamond) {
+				TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) receiverType).genericType(), receiverType.enclosingType(), argumentTypes, scope);
+				if (inferredTypes == null) {
+					scope.problemReporter().cannotInferElidedTypes(this);
+					return this.resolvedType = null;
+				}
+				receiverType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) receiverType).genericType(), inferredTypes, ((ParameterizedTypeBinding) receiverType).enclosingType());
+			}
+			ReferenceBinding allocationType = (ReferenceBinding) receiverType;
+			this.binding = scope.getConstructor(allocationType, argumentTypes, this);
+			if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+				return null;
+			if (this.binding.isValidBinding()) {	
+				if (isMethodUseDeprecated(this.binding, scope, true)) {
+					scope.problemReporter().deprecatedMethod(this.binding, this);
+				}
+				if (checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+					this.bits |= ASTNode.Unchecked;
+				}
+				if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+					scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
+				}
+			} else {
+				if (this.binding.declaringClass == null) {
+					this.binding.declaringClass = allocationType;
+				}
+				if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+					// problem already got signaled on type reference, do not report secondary problem
+					return null;
+				}
+				scope.problemReporter().invalidConstructor(this, this.binding);
+				return this.resolvedType = receiverType;
+			}
+			if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
+				scope.problemReporter().missingTypeInConstructor(this, this.binding);
+			}
+			if (!isDiamond && receiverType.isParameterizedTypeWithActualArguments()) {
+		 		checkTypeArgumentRedundancy((ParameterizedTypeBinding)receiverType, receiverType.enclosingType(), argumentTypes , scope);
+		 	}
+			// The enclosing instance must be compatible with the innermost enclosing type
+			ReferenceBinding expectedType = this.binding.declaringClass.enclosingType();
+			if (expectedType != enclosingInstanceType) // must call before computeConversion() and typeMismatchError()
+				scope.compilationUnitScope().recordTypeConversion(expectedType, enclosingInstanceType);
+			if (enclosingInstanceType.isCompatibleWith(expectedType) || scope.isBoxingCompatibleWith(enclosingInstanceType, expectedType)) {
+				this.enclosingInstance.computeConversion(scope, expectedType, enclosingInstanceType);
+				return this.resolvedType = receiverType;
+			}
+			scope.problemReporter().typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance, null);
+			return this.resolvedType = receiverType;
+		} else {
+			if (isDiamond) {
+				scope.problemReporter().diamondNotWithAnoymousClasses(this.type);
+				return null;
+			}	
+		}
+		ReferenceBinding superType = (ReferenceBinding) receiverType;
+		if (superType.isTypeVariable()) {
+			superType = new ProblemReferenceBinding(new char[][]{superType.sourceName()}, superType, ProblemReasons.IllegalSuperTypeVariable);
+			scope.problemReporter().invalidType(this, superType);
+			return null;
+		} else if (this.type != null && superType.isEnum()) { // tolerate enum constant body
+			scope.problemReporter().cannotInstantiate(this.type, superType);
+			return this.resolvedType = superType;
+		}
+		// anonymous type scenario
+		// an anonymous class inherits from java.lang.Object when declared "after" an interface
+		ReferenceBinding anonymousSuperclass = superType.isInterface() ? scope.getJavaLangObject() : superType;
+		// insert anonymous type in scope
+		scope.addAnonymousType(this.anonymousType, superType);
+		this.anonymousType.resolve(scope);
+
+		// find anonymous super constructor
+		this.resolvedType = this.anonymousType.binding; // 1.2 change
+		if ((this.resolvedType.tagBits & TagBits.HierarchyHasProblems) != 0) {
+			return null; // stop secondary errors
+		}
+		MethodBinding inheritedBinding = scope.getConstructor(anonymousSuperclass, argumentTypes, this);
+		if (polyExpressionSeen && polyExpressionsHaveErrors(scope, inheritedBinding, this.arguments, argumentTypes))
+			return null;
+		if (!inheritedBinding.isValidBinding()) {
+			if (inheritedBinding.declaringClass == null) {
+				inheritedBinding.declaringClass = anonymousSuperclass;
+			}
+			if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+				// problem already got signaled on type reference, do not report secondary problem
+				return null;
+			}
+			scope.problemReporter().invalidConstructor(this, inheritedBinding);
+			return this.resolvedType;
+		}
+		if ((inheritedBinding.tagBits & TagBits.HasMissingType) != 0) {
+			scope.problemReporter().missingTypeInConstructor(this, inheritedBinding);
+		}
+		if (this.enclosingInstance != null) {
+			ReferenceBinding targetEnclosing = inheritedBinding.declaringClass.enclosingType();
+			if (targetEnclosing == null) {
+				scope.problemReporter().unnecessaryEnclosingInstanceSpecification(this.enclosingInstance, superType);
+				return this.resolvedType;
+			} else if (!enclosingInstanceType.isCompatibleWith(targetEnclosing) && !scope.isBoxingCompatibleWith(enclosingInstanceType, targetEnclosing)) {
+				scope.problemReporter().typeMismatchError(enclosingInstanceType, targetEnclosing, this.enclosingInstance, null);
+				return this.resolvedType;
+			}
+			this.enclosingInstance.computeConversion(scope, targetEnclosing, enclosingInstanceType);
+		}
+		if (this.arguments != null) {
+			if (checkInvocationArguments(scope, null, anonymousSuperclass, inheritedBinding, this.arguments, argumentTypes, argsContainCast, this)) {
+				this.bits |= ASTNode.Unchecked;
+			}
+		}
+		if (this.typeArguments != null && inheritedBinding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+			scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(inheritedBinding, this.genericTypeArguments, this.typeArguments);
+		}
+		// Update the anonymous inner class : superclass, interface
+		this.binding = this.anonymousType.createDefaultConstructorWithBinding(inheritedBinding, 	(this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null);
+		return this.resolvedType;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.enclosingInstance != null)
+				this.enclosingInstance.traverse(visitor, scope);
+			if (this.typeArguments != null) {
+				for (int i = 0, typeArgumentsLength = this.typeArguments.length; i < typeArgumentsLength; i++) {
+					this.typeArguments[i].traverse(visitor, scope);
+				}
+			}
+			if (this.type != null) // case of enum constant
+				this.type.traverse(visitor, scope);
+			if (this.arguments != null) {
+				int argumentsLength = this.arguments.length;
+				for (int i = 0; i < argumentsLength; i++)
+					this.arguments[i].traverse(visitor, scope);
+			}
+			if (this.anonymousType != null)
+				this.anonymousType.traverse(visitor, scope);
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..d9b4283
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -0,0 +1,1165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     							bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *     Jesper S Moller - Contributions for
+ *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class QualifiedNameReference extends NameReference {
+
+	public char[][] tokens;
+	public long[] sourcePositions;
+	public FieldBinding[] otherBindings;
+	int[] otherDepths;
+	public int indexOfFirstFieldBinding;//points (into tokens) for the first token that corresponds to first FieldBinding
+	public SyntheticMethodBinding syntheticWriteAccessor;
+	public SyntheticMethodBinding[] syntheticReadAccessors;
+	public TypeBinding genericCast;
+	public TypeBinding[] otherGenericCasts;
+
+public QualifiedNameReference(char[][] tokens, long[] positions, int sourceStart, int sourceEnd) {
+	this.tokens = tokens;
+	this.sourcePositions = positions;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
+	boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
+	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
+	FieldBinding lastFieldBinding = null;
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			lastFieldBinding = (FieldBinding) this.binding;
+			if (needValue || complyTo14) {
+				manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, 0, flowInfo);
+			}
+			// check if final blank field
+			if (lastFieldBinding.isBlankFinal()
+				    && this.otherBindings != null // the last field binding is only assigned
+	 				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
+				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass.original(), flowInfo);
+				if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
+					currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
+				}
+			}
+			break;
+		case Binding.LOCAL :
+			// first binding is a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo
+				.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+				localBinding.useFlag = LocalVariableBinding.USED;
+			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
+				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
+			}
+			if (needValue) {
+				checkInternalNPE(currentScope, flowContext, flowInfo, true);
+			}
+	}
+
+	if (needValue) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+		// only for first binding
+	}
+	// all intermediate field accesses are read accesses
+	if (this.otherBindings != null) {
+		for (int i = 0; i < otherBindingsCount-1; i++) {
+			lastFieldBinding = this.otherBindings[i];
+			needValue = !this.otherBindings[i+1].isStatic();
+			if (needValue || complyTo14) {
+				manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, i + 1, flowInfo);
+			}
+		}
+		lastFieldBinding = this.otherBindings[otherBindingsCount-1];
+	}
+
+	if (isCompound) {
+		if (otherBindingsCount == 0
+				&& lastFieldBinding.isBlankFinal()
+				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
+			FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass, flowInfo);
+			if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
+				currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
+			}
+		}
+		manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, otherBindingsCount, flowInfo);
+	}
+
+	if (assignment.expression != null) {
+		flowInfo =
+			assignment
+				.expression
+				.analyseCode(currentScope, flowContext, flowInfo)
+				.unconditionalInits();
+	}
+
+	// the last field access is a write access
+	if (lastFieldBinding.isFinal()) {
+		// in a context where it can be assigned?
+		if (otherBindingsCount == 0
+				&& this.indexOfFirstFieldBinding == 1
+				&& lastFieldBinding.isBlankFinal()
+				&& !isCompound
+				&& currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
+			if (flowInfo.isPotentiallyAssigned(lastFieldBinding)) {
+				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(lastFieldBinding, this);
+			} else {
+				flowContext.recordSettingFinal(lastFieldBinding, this, flowInfo);
+			}
+			flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
+		} else {
+			currentScope.problemReporter().cannotAssignToFinalField(lastFieldBinding, this);
+			if (otherBindingsCount == 0 && currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) { // pretend it got assigned
+				flowInfo.markAsDefinitelyAssigned(lastFieldBinding);
+			}
+		}
+	}
+	// note: not covering def.assign for @NonNull: QNR cannot provably refer to a variable of the current object
+	manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, -1 /*write-access*/, flowInfo);
+
+	return flowInfo;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
+
+	boolean needValue = otherBindingsCount == 0 ? valueRequired : !this.otherBindings[0].isStatic();
+	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			if (needValue || complyTo14) {
+				manageSyntheticAccessIfNecessary(currentScope, (FieldBinding) this.binding, 0, flowInfo);
+			}
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
+				// check if reading a final blank field
+				if (fieldBinding.isBlankFinal()
+						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
+					FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+					if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+					}
+				}
+			}
+			break;
+		case Binding.LOCAL : // reading a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+				localBinding.useFlag = LocalVariableBinding.USED;
+			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
+				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
+			}
+	}
+	if (needValue) {
+		checkInternalNPE(currentScope, flowContext, flowInfo, true);
+	}
+	if (needValue) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+		// only for first binding (if value needed only)
+	}
+	if (this.otherBindings != null) {
+		for (int i = 0; i < otherBindingsCount; i++) {
+			needValue = i < otherBindingsCount-1 ? !this.otherBindings[i+1].isStatic() : valueRequired;
+			if (needValue || complyTo14) {
+				manageSyntheticAccessIfNecessary(currentScope, this.otherBindings[i], i + 1, flowInfo);
+			}
+		}
+	}
+	return flowInfo;
+}
+
+/* check if any dot in this QNR may trigger an NPE. */
+private void checkInternalNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, boolean checkString) {
+	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
+		LocalVariableBinding local = (LocalVariableBinding) this.binding;
+		if (local != null &&
+			(local.type.tagBits & TagBits.IsBaseType) == 0 &&
+			(checkString || local.type.id != TypeIds.T_JavaLangString)) {
+			if ((this.bits & ASTNode.IsNonNull) == 0) {
+				flowContext.recordUsingNullReference(scope, local, this,
+					FlowContext.MAY_NULL, flowInfo);
+			}
+			flowInfo.markAsComparedEqualToNonNull(local);
+			// from thereon it is set
+			flowContext.markFinallyNullStatus(local, FlowInfo.NON_NULL);
+		}
+	}
+	if (this.otherBindings != null) {
+		if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) {
+			// is the first field dereferenced annotated Nullable? If so, report immediately
+			checkNullableFieldDereference(scope, (FieldBinding) this.binding, this.sourcePositions[0]);
+		}
+		// look for annotated fields, they do not depend on flow context -> check immediately:
+		int length = this.otherBindings.length - 1; // don't check the last binding
+		for (int i = 0; i < length; i++) {
+			checkNullableFieldDereference(scope, this.otherBindings[i], this.sourcePositions[i+1]);
+		}
+	}
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (super.checkNPE(scope, flowContext, flowInfo)) {
+		return true;
+	}
+	FieldBinding fieldBinding = null;
+	long position = 0L;
+	if (this.otherBindings == null) {
+		if ((this.bits & RestrictiveFlagMASK) == Binding.FIELD) {
+			fieldBinding = (FieldBinding) this.binding;
+			position = this.sourcePositions[0];
+		}
+	} else {
+		fieldBinding = this.otherBindings[this.otherBindings.length - 1];
+		position = this.sourcePositions[this.sourcePositions.length - 1];
+	}
+	if (fieldBinding != null) {
+		return checkNullableFieldDereference(scope, fieldBinding, position);
+	}
+	return false;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+	if (runtimeTimeType == null || compileTimeType == null)
+		return;
+	// set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
+	FieldBinding field = null;
+	int length = this.otherBindings == null ? 0 : this.otherBindings.length;
+	if (length == 0) {
+		if ((this.bits & Binding.FIELD) != 0 && this.binding != null && this.binding.isValidBinding()) {
+			field = (FieldBinding) this.binding;
+		}
+	} else {
+		field  = this.otherBindings[length-1];
+	}
+	if (field != null) {
+		FieldBinding originalBinding = field.original();
+		TypeBinding originalType = originalBinding.type;
+		// extra cast needed if field type is type variable
+		if (originalType.leafComponentType().isTypeVariable()) {
+			TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
+			? compileTimeType  // unboxing: checkcast before conversion
+					: runtimeTimeType;
+			TypeBinding typeCast = originalType.genericCast(targetType);
+			setGenericCast(length, typeCast);
+			if (typeCast instanceof ReferenceBinding) {
+				ReferenceBinding referenceCast = (ReferenceBinding) typeCast;
+				if (!referenceCast.canBeSeenBy(scope)) {
+					scope.problemReporter().invalidType(this,
+							new ProblemReferenceBinding(
+									CharOperation.splitOn('.', referenceCast.shortReadableName()),
+									referenceCast,
+									ProblemReasons.NotVisible));
+				}
+			}
+		}
+	}
+	super.computeConversion(scope, runtimeTimeType, compileTimeType);
+}
+
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	int pc = codeStream.position;
+	FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	codeStream.recordPositionsFrom(pc , this.sourceStart);
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	fieldStore(currentScope, codeStream, lastFieldBinding, this.syntheticWriteAccessor, getFinalReceiverType(), false /*implicit this*/, valueRequired);
+	// equivalent to valuesRequired[maxOtherBindings]
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		}
+	} else {
+		FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+		if (lastFieldBinding != null) {
+			boolean isStatic = lastFieldBinding.isStatic();
+			Constant fieldConstant = lastFieldBinding.constant();
+			if (fieldConstant != Constant.NotAConstant) {
+				if (!isStatic){
+					codeStream.invokeObjectGetClass();
+					codeStream.pop();
+				}
+				if (valueRequired) { // inline the last field constant
+					codeStream.generateConstant(fieldConstant, this.implicitConversion);
+				}
+			} else {
+				boolean isFirst = lastFieldBinding == this.binding
+												&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+												&& this.otherBindings == null; // could be dup: next.next.next
+				TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
+				if (valueRequired
+						|| (!isFirst && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+						|| ((this.implicitConversion & TypeIds.UNBOXING) != 0)
+						|| requiredGenericCast != null) {
+					int lastFieldPc = codeStream.position;
+					if (lastFieldBinding.declaringClass == null) { // array length
+						codeStream.arraylength();
+						if (valueRequired) {
+							codeStream.generateImplicitConversion(this.implicitConversion);
+						} else {
+							// could occur if !valueRequired but compliance >= 1.4
+							codeStream.pop();
+						}
+					} else {
+						SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
+						if (accessor == null) {
+							TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);
+							if (isStatic) {
+								codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+							} else {
+								codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
+							}
+						} else {
+							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+						}
+						if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
+						if (valueRequired) {
+							codeStream.generateImplicitConversion(this.implicitConversion);
+						} else {
+							boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+							// conversion only generated if unboxing
+							if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+							switch (isUnboxing ? postConversionType(currentScope).id : lastFieldBinding.type.id) {
+								case T_long :
+								case T_double :
+									codeStream.pop2();
+									break;
+								default :
+									codeStream.pop();
+									break;
+							}
+						}
+					}
+
+					int fieldPosition = (int) (this.sourcePositions[this.sourcePositions.length - 1] >>> 32);
+					codeStream.recordPositionsFrom(lastFieldPc, fieldPosition);
+				} else {
+					if (!isStatic){
+						codeStream.invokeObjectGetClass(); // perform null check
+						codeStream.pop();
+					}
+				}
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	// check if compound assignment is the only usage of a private field
+	reportOnlyUselesslyReadPrivateField(currentScope, lastFieldBinding, valueRequired);
+	boolean isFirst = lastFieldBinding == this.binding
+		&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+		&& this.otherBindings == null; // could be dup: next.next.next
+	TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);			
+	SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
+	if (lastFieldBinding.isStatic()) {
+		if (accessor == null) {
+			codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+		}
+	} else {
+		codeStream.dup();
+		if (accessor == null) {
+			codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+		}
+	}
+	// the last field access is a write access
+	// perform the actual compound operation
+	int operationTypeID;
+	switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
+		case T_JavaLangString :
+		case T_JavaLangObject :
+		case T_undefined :
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+			break;
+		default :
+			TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
+			if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
+			// promote the array reference to the suitable operation type
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One) { // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// actual assignment
+	fieldStore(currentScope, codeStream, lastFieldBinding, this.syntheticWriteAccessor, getFinalReceiverType(), false /*implicit this*/, valueRequired);
+	// equivalent to valuesRequired[maxOtherBindings]
+}
+
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	// check if this post increment is the only usage of a private field
+	reportOnlyUselesslyReadPrivateField(currentScope, lastFieldBinding, valueRequired);
+	boolean isFirst = lastFieldBinding == this.binding
+		&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+		&& this.otherBindings == null; // could be dup: next.next.next
+	TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);			
+	SyntheticMethodBinding accessor = this.syntheticReadAccessors == null
+			? null
+			: this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
+	if (lastFieldBinding.isStatic()) {
+		if (accessor == null) {
+			codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, constantPoolDeclaringClass);
+		}
+	} else {
+		codeStream.dup();
+		if (accessor == null) {
+			codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, null /* default declaringClass */);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+		}
+	}
+	TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
+	TypeBinding operandType;
+	if (requiredGenericCast != null) {
+		codeStream.checkcast(requiredGenericCast);
+		operandType = requiredGenericCast;
+	} else {
+		operandType = lastFieldBinding.type;
+	}		
+	// duplicate the old field value
+	if (valueRequired) {
+		if (lastFieldBinding.isStatic()) {
+			switch (operandType.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2();
+					break;
+				default:
+					codeStream.dup();
+					break;
+			}			
+		} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+			switch (operandType.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2_x1();
+					break;
+				default:
+					codeStream.dup_x1();
+					break;
+			}			
+		}
+	}
+	codeStream.generateImplicitConversion(this.implicitConversion);		
+	codeStream.generateConstant(
+		postIncrement.expression.constant,
+		this.implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+	codeStream.generateImplicitConversion(
+		postIncrement.preAssignImplicitConversion);
+	fieldStore(currentScope, codeStream, lastFieldBinding, this.syntheticWriteAccessor, getFinalReceiverType(), false /*implicit this*/, false);
+}
+
+/*
+ * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
+ * for a read or write access.
+ */
+public FieldBinding generateReadSequence(BlockScope currentScope, CodeStream codeStream) {
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
+	boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
+	FieldBinding lastFieldBinding;
+	TypeBinding lastGenericCast;
+	TypeBinding lastReceiverType;
+	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
+
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD :
+			lastFieldBinding = ((FieldBinding) this.binding).original();
+			lastGenericCast = this.genericCast;
+			lastReceiverType = this.actualReceiverType;
+			// if first field is actually constant, we can inline it
+			if (lastFieldBinding.constant() != Constant.NotAConstant) {
+				break;
+			}
+			if ((needValue && !lastFieldBinding.isStatic()) || lastGenericCast != null) {
+				int pc = codeStream.position;
+				if ((this.bits & ASTNode.DepthMASK) != 0) {
+					ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+					Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+					codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+				} else {
+					generateReceiver(codeStream);
+				}
+				codeStream.recordPositionsFrom(pc, this.sourceStart);
+			}
+			break;
+		case Binding.LOCAL : // reading the first local variable
+			lastFieldBinding = null;
+			lastGenericCast = null;
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			lastReceiverType = localBinding.type;
+			if (!needValue) break; // no value needed
+			// regular local variable read
+			Constant localConstant = localBinding.constant();
+			if (localConstant != Constant.NotAConstant) {
+				codeStream.generateConstant(localConstant, 0);
+				// no implicit conversion
+			} else {
+				// outer local?
+				if ((this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+					checkEffectiveFinality(localBinding, currentScope);
+					// outer local can be reached either through a synthetic arg or a synthetic field
+					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+					codeStream.generateOuterAccess(path, this, localBinding, currentScope);
+				} else {
+					codeStream.load(localBinding);
+				}
+			}
+			break;
+		default : // should not occur
+			return null;
+	}
+
+	// all intermediate field accesses are read accesses
+	// only the last field binding is a write access
+	int positionsLength = this.sourcePositions.length;
+	FieldBinding initialFieldBinding = lastFieldBinding; // can be null if initial was a local binding
+	if (this.otherBindings != null) {
+		for (int i = 0; i < otherBindingsCount; i++) {
+			int pc = codeStream.position;
+			FieldBinding nextField = this.otherBindings[i].original();
+			TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
+			if (lastFieldBinding != null) {
+				needValue = !nextField.isStatic();
+				Constant fieldConstant = lastFieldBinding.constant();
+				if (fieldConstant != Constant.NotAConstant) {
+					if (i > 0 && !lastFieldBinding.isStatic()) {
+						codeStream.invokeObjectGetClass(); // perform null check
+						codeStream.pop();
+					}
+					if (needValue) {
+						codeStream.generateConstant(fieldConstant, 0);
+					}
+				} else {
+					if (needValue || (i > 0 && complyTo14) || lastGenericCast != null) {
+						MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
+						if (accessor == null) {
+							TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
+							if (lastFieldBinding.isStatic()) {
+								codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+							} else {
+								codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
+							}
+						} else {
+							codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+						}
+						if (lastGenericCast != null) {
+							codeStream.checkcast(lastGenericCast);
+							lastReceiverType = lastGenericCast;
+						} else {
+							lastReceiverType = lastFieldBinding.type;
+						}
+						if (!needValue) codeStream.pop();
+					} else {
+						if (lastFieldBinding == initialFieldBinding) {
+							if (lastFieldBinding.isStatic()){
+								// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
+								if (initialFieldBinding.declaringClass != this.actualReceiverType.erasure()) {
+									MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
+									if (accessor == null) {
+										TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
+										codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+									} else {
+										codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+									}
+									codeStream.pop();
+								}
+							}
+						} else if (!lastFieldBinding.isStatic()){
+							codeStream.invokeObjectGetClass(); // perform null check
+							codeStream.pop();
+						}
+						lastReceiverType = lastFieldBinding.type;
+					}
+					if ((positionsLength - otherBindingsCount + i - 1) >= 0) {
+						int fieldPosition = (int) (this.sourcePositions[positionsLength - otherBindingsCount + i - 1] >>>32);
+						codeStream.recordPositionsFrom(pc, fieldPosition);
+					}
+				}
+			}
+			lastFieldBinding = nextField;
+			lastGenericCast = nextGenericCast;
+		}
+	}
+	return lastFieldBinding;
+}
+
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return null;
+}
+
+protected FieldBinding getCodegenBinding(int index) {
+  if (index == 0){
+		return ((FieldBinding)this.binding).original();
+	} else {
+		return this.otherBindings[index-1].original();
+	}
+}
+
+/**
+ * Returns the receiver type for the final field in sequence (i.e. the return type of the previous binding)
+ * @return receiver type for the final field in sequence
+ */
+protected TypeBinding getFinalReceiverType() {
+	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
+	switch (otherBindingsCount) {
+		case 0 :
+			return this.actualReceiverType;
+		case 1 :
+			return this.genericCast != null ? this.genericCast : ((VariableBinding)this.binding).type;
+		default:
+			TypeBinding previousGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[otherBindingsCount-2];
+			return previousGenericCast != null ? previousGenericCast : this.otherBindings[otherBindingsCount-2].type;
+	}	
+}
+
+// get the matching generic cast
+protected TypeBinding getGenericCast(int index) {
+   if (index == 0){
+		return this.genericCast;
+	} else {
+	    if (this.otherGenericCasts == null) return null;
+		return this.otherGenericCasts[index-1];
+	}
+}
+public TypeBinding getOtherFieldBindings(BlockScope scope) {
+	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
+	int length = this.tokens.length;
+	FieldBinding field = ((this.bits & Binding.FIELD) != 0) ? (FieldBinding) this.binding : null;
+	TypeBinding type = ((VariableBinding) this.binding).type;
+	int index = this.indexOfFirstFieldBinding;
+	if (index == length) { //	restrictiveFlag == FIELD
+		this.constant = ((FieldBinding) this.binding).constant();
+		// perform capture conversion if read access
+		return (type != null && (this.bits & ASTNode.IsStrictlyAssigned) == 0)
+				? type.capture(scope, this.sourceEnd)
+				: type;
+	}
+	// allocation of the fieldBindings array	and its respective constants
+	int otherBindingsLength = length - index;
+	this.otherBindings = new FieldBinding[otherBindingsLength];
+	this.otherDepths = new int[otherBindingsLength];
+
+	// fill the first constant (the one of the binding)
+	this.constant = ((VariableBinding) this.binding).constant();
+	// save first depth, since will be updated by visibility checks of other bindings
+	int firstDepth = (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT;
+	// iteration on each field
+	while (index < length) {
+		char[] token = this.tokens[index];
+		if (type == null)
+			return null; // could not resolve type prior to this point
+
+		this.bits &= ~ASTNode.DepthMASK; // flush previous depth if any
+		FieldBinding previousField = field;
+		field = scope.getField(type.capture(scope, (int)this.sourcePositions[index]), token, this);
+		int place = index - this.indexOfFirstFieldBinding;
+		this.otherBindings[place] = field;
+		this.otherDepths[place] = (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT;
+		if (field.isValidBinding()) {
+			// set generic cast of for previous field (if any)
+			if (previousField != null) {
+				TypeBinding fieldReceiverType = type;
+				TypeBinding oldReceiverType = fieldReceiverType;
+				fieldReceiverType = fieldReceiverType.getErasureCompatibleType(field.declaringClass);// handle indirect inheritance thru variable secondary bound
+				FieldBinding originalBinding = previousField.original();
+				if (fieldReceiverType != oldReceiverType || originalBinding.type.leafComponentType().isTypeVariable()) { // record need for explicit cast at codegen
+			    	setGenericCast(index-1,originalBinding.type.genericCast(fieldReceiverType)); // type cannot be base-type even in boxing case
+				}				
+		    }
+			// only last field is actually a write access if any
+			if (isFieldUseDeprecated(field, scope, index+1 == length ? this.bits : 0)) {
+				scope.problemReporter().deprecatedField(field, this);
+			}
+			// constant propagation can only be performed as long as the previous one is a constant too.
+			if (this.constant != Constant.NotAConstant) {
+				this.constant = field.constant();
+			}
+
+			if (field.isStatic()) {
+				if ((field.modifiers & ClassFileConstants.AccEnum) != 0) { // enum constants are checked even when qualified)
+					ReferenceBinding declaringClass = field.original().declaringClass;
+					MethodScope methodScope = scope.methodScope();
+					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
+					if ((this.bits & ASTNode.IsStrictlyAssigned) == 0
+							&& sourceType == declaringClass
+							&& methodScope.lastVisibleFieldID >= 0
+							&& field.id >= methodScope.lastVisibleFieldID
+							&& (!field.isStatic() || methodScope.isStatic)) {
+						scope.problemReporter().forwardReference(this, index, field);
+					}					
+					// check if accessing enum static field in initializer
+					if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+							&& field.constant() == Constant.NotAConstant
+							&& !methodScope.isStatic
+							&& methodScope.isInsideInitializerOrConstructor()) {
+						scope.problemReporter().enumStaticFieldUsedDuringInitialization(field, this);
+					}
+				}
+				// static field accessed through receiver? legal but unoptimal (optional warning)
+				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
+				// indirect static reference ?
+				if (field.declaringClass != type) {
+					scope.problemReporter().indirectAccessToStaticField(this, field);
+				}
+			}
+			type = field.type;
+			index++;
+		} else {
+			this.constant = Constant.NotAConstant; //don't fill other constants slots...
+			scope.problemReporter().invalidField(this, field, index, type);
+			setDepth(firstDepth);
+			return null;
+		}
+	}
+	setDepth(firstDepth);
+	type = (this.otherBindings[otherBindingsLength - 1]).type;
+	// perform capture conversion if read access
+	return (type != null && (this.bits & ASTNode.IsStrictlyAssigned) == 0)
+			? type.capture(scope, this.sourceEnd)
+			: type;
+}
+
+public boolean isEquivalent(Reference reference) {
+	if (reference instanceof FieldReference) {
+		return reference.isEquivalent(this); // comparison FR <-> QNR is implemented only once
+	}
+	if (!(reference instanceof QualifiedNameReference)) return false;
+	// straight-forward test of equality of two QNRs:
+	QualifiedNameReference qualifiedReference = (QualifiedNameReference) reference;
+	if (this.tokens.length != qualifiedReference.tokens.length) return false;
+	if (this.binding != qualifiedReference.binding) return false;
+	if (this.otherBindings != null) {
+		if (qualifiedReference.otherBindings == null) return false;
+		int len = this.otherBindings.length;
+		if (len != qualifiedReference.otherBindings.length) return false;
+		for (int i=0; i<len; i++) {
+			if (this.otherBindings[i] != qualifiedReference.otherBindings[i]) return false;
+		}
+	} else if (qualifiedReference.otherBindings != null) {
+		return false;
+	}
+	return true;
+}
+
+public boolean isFieldAccess() {
+	if (this.otherBindings != null) {
+		return true;
+	}
+	return (this.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD;
+}
+
+public FieldBinding lastFieldBinding() {
+	if (this.otherBindings != null) {
+		return this.otherBindings[this.otherBindings.length - 1];		
+	} else if (this.binding != null && (this.bits & RestrictiveFlagMASK) == Binding.FIELD) {
+		return (FieldBinding) this.binding;
+	}
+	return null;
+}
+
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (((this.bits & ASTNode.DepthMASK) == 0 && (this.bits & ASTNode.IsCapturedOuterLocal) == 0) || (this.constant != Constant.NotAConstant)) {
+		return;
+	}
+	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 :
+					currentScope.emulateOuterAccess(localVariableBinding);
+			}
+		}
+	}
+}
+
+/**
+ * index is <0 to denote write access emulation
+ */
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+	// index == 0 denotes the first fieldBinding, index > 0 denotes one of the 'otherBindings', index < 0 denotes a write access (to last binding)
+	if (fieldBinding.constant() != Constant.NotAConstant)
+		return;
+
+	if (fieldBinding.isPrivate()) { // private access
+	    FieldBinding codegenField = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index);
+	    ReferenceBinding declaringClass = codegenField.declaringClass;
+		if (declaringClass != currentScope.enclosingSourceType()) {
+		    setSyntheticAccessor(fieldBinding, index, ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenField, index >= 0 /*read-access?*/, false /*not super access*/));
+			currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, index >= 0 /*read-access?*/);
+			return;
+		}
+	} else if (fieldBinding.isProtected()){
+	    int depth = (index == 0 || (index < 0 && this.otherDepths == null))
+	    		? (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT
+	    		 : this.otherDepths[index < 0 ? this.otherDepths.length-1 : index-1];
+
+		// implicit protected access
+		if (depth > 0 && (fieldBinding.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage())) {
+		    FieldBinding codegenField = getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index);
+		    setSyntheticAccessor(fieldBinding, index,
+		            ((SourceTypeBinding) currentScope.enclosingSourceType().enclosingTypeAt(depth)).addSyntheticMethod(codegenField, index >= 0 /*read-access?*/, false /*not super access*/));
+			currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, index >= 0 /*read-access?*/);
+			return;
+		}
+	}
+}
+
+public Constant optimizedBooleanConstant() {
+	switch (this.resolvedType.id) {
+		case T_boolean :
+		case T_JavaLangBoolean :
+			if (this.constant != Constant.NotAConstant) return this.constant;
+			switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+				case Binding.FIELD : // reading a field
+					if (this.otherBindings == null)
+						return ((FieldBinding)this.binding).constant();
+					//$FALL-THROUGH$
+				case Binding.LOCAL : // reading a local variable
+					return this.otherBindings[this.otherBindings.length-1].constant();
+		}
+	}
+	return Constant.NotAConstant;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
+ */
+public TypeBinding postConversionType(Scope scope) {
+	TypeBinding convertedType = this.resolvedType;
+	TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
+	if (requiredGenericCast != null)
+		convertedType = requiredGenericCast;
+	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	switch (runtimeType) {
+		case T_boolean :
+			convertedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			convertedType = TypeBinding.BYTE;
+			break;
+		case T_short :
+			convertedType = TypeBinding.SHORT;
+			break;
+		case T_char :
+			convertedType = TypeBinding.CHAR;
+			break;
+		case T_int :
+			convertedType = TypeBinding.INT;
+			break;
+		case T_float :
+			convertedType = TypeBinding.FLOAT;
+			break;
+		case T_long :
+			convertedType = TypeBinding.LONG;
+			break;
+		case T_double :
+			convertedType = TypeBinding.DOUBLE;
+			break;
+		default :
+	}
+	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
+		convertedType = scope.environment().computeBoxingType(convertedType);
+	}
+	return convertedType;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	for (int i = 0; i < this.tokens.length; i++) {
+		if (i > 0) output.append('.');
+		output.append(this.tokens[i]);
+	}
+	return output;
+}
+
+/**
+ * Normal field binding did not work, try to bind to a field of the delegate receiver.
+ */
+public TypeBinding reportError(BlockScope scope) {
+	if (this.binding instanceof ProblemFieldBinding) {
+		scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
+	} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
+		scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
+	} else {
+		scope.problemReporter().unresolvableReference(this, this.binding);
+	}
+	return null;
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// field and/or local are done before type lookups
+	// the only available value for the restrictiveFlag BEFORE
+	// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField
+	this.actualReceiverType = scope.enclosingReceiverType();
+	this.constant = Constant.NotAConstant;
+	if ((this.binding = scope.getBinding(this.tokens, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/)).isValidBinding()) {
+		switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+			case Binding.VARIABLE : //============only variable===========
+			case Binding.TYPE | Binding.VARIABLE :
+				if (this.binding instanceof LocalVariableBinding) {
+					this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
+					this.bits |= Binding.LOCAL;
+					LocalVariableBinding local = (LocalVariableBinding) this.binding;
+					if (!local.isFinal() && (this.bits & ASTNode.IsCapturedOuterLocal) != 0) { 
+						if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) // for 8, defer till effective finality could be ascertained.
+							scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding) this.binding, this);
+					}
+					if (local.type != null && (local.type.tagBits & TagBits.HasMissingType) != 0) {
+						// only complain if field reference (for local, its type got flagged already)
+						return null;
+					}
+					this.resolvedType = getOtherFieldBindings(scope);
+					if (this.resolvedType != null && (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+						FieldBinding lastField = this.otherBindings[this.otherBindings.length - 1];
+						scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType());
+						return null;
+					}
+					return this.resolvedType;
+				}
+				if (this.binding instanceof FieldBinding) {
+					this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
+					this.bits |= Binding.FIELD;
+					FieldBinding fieldBinding = (FieldBinding) this.binding;
+					MethodScope methodScope = scope.methodScope();
+					ReferenceBinding declaringClass = fieldBinding.original().declaringClass;
+					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
+					// check for forward references
+					if ((this.indexOfFirstFieldBinding == 1 || (fieldBinding.modifiers & ClassFileConstants.AccEnum) != 0 || (!fieldBinding.isFinal() && declaringClass.isEnum())) // enum constants are checked even when qualified
+							&& sourceType == declaringClass
+							&& methodScope.lastVisibleFieldID >= 0
+							&& fieldBinding.id >= methodScope.lastVisibleFieldID
+							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
+						if (methodScope.insideTypeAnnotation && fieldBinding.id == methodScope.lastVisibleFieldID) {
+							// false alarm, location is NOT a field initializer but the value in a memberValuePair
+						} else {
+							scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding-1, fieldBinding);
+						}
+					}
+					if (isFieldUseDeprecated(fieldBinding, scope, this.indexOfFirstFieldBinding == this.tokens.length ? this.bits : 0)) {
+						scope.problemReporter().deprecatedField(fieldBinding, this);	
+					}
+					if (fieldBinding.isStatic()) {
+						// only last field is actually a write access if any
+						// check if accessing enum static field in initializer
+						if (declaringClass.isEnum()) {
+							if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+									&& fieldBinding.constant() == Constant.NotAConstant
+									&& !methodScope.isStatic
+									&& methodScope.isInsideInitializerOrConstructor()) {
+								scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
+							}
+						}
+						if (this.indexOfFirstFieldBinding > 1
+								&& fieldBinding.declaringClass != this.actualReceiverType
+								&& fieldBinding.declaringClass.canBeSeenBy(scope)) {
+							scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
+						}						
+					} else {
+						boolean inStaticContext = scope.methodScope().isStatic;
+						if (this.indexOfFirstFieldBinding == 1) {
+							if (scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
+								scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
+							}
+							if (!inStaticContext) {
+								scope.tagAsAccessingEnclosingInstanceStateOf(fieldBinding.declaringClass, false /* type variable access */);
+							}
+						}
+						//must check for the static status....
+						if (this.indexOfFirstFieldBinding > 1  //accessing to a field using a type as "receiver" is allowed only with static field
+								 || inStaticContext) { 	// the field is the first token of the qualified reference....
+							scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
+							return null;
+						 }
+					}
+					
+					this.resolvedType = getOtherFieldBindings(scope);
+					if (this.resolvedType != null
+							&& (this.resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+						FieldBinding lastField = this.indexOfFirstFieldBinding == this.tokens.length ? (FieldBinding)this.binding : this.otherBindings[this.otherBindings.length - 1];
+						scope.problemReporter().invalidField(this, new ProblemFieldBinding(lastField.declaringClass, lastField.name, ProblemReasons.NotFound), this.tokens.length, this.resolvedType.leafComponentType());
+						return null;
+					}
+					return this.resolvedType;
+				}
+				// thus it was a type
+				this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
+				this.bits |= Binding.TYPE;
+				//$FALL-THROUGH$
+			case Binding.TYPE : //=============only type ==============
+			    TypeBinding type = (TypeBinding) this.binding;
+//					if (isTypeUseDeprecated(type, scope))
+//						scope.problemReporter().deprecatedType(type, this);
+				type = scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
+				return this.resolvedType = type;
+		}
+	}
+	//========error cases===============
+	return this.resolvedType = reportError(scope);
+}
+
+public void setFieldIndex(int index) {
+	this.indexOfFirstFieldBinding = index;
+}
+
+// set the matching codegenBinding and generic cast
+protected void setGenericCast(int index, TypeBinding someGenericCast) {
+	if (someGenericCast == null) return;
+	if (index == 0){
+		this.genericCast = someGenericCast;
+	} else {
+	    if (this.otherGenericCasts == null) {
+	        this.otherGenericCasts = new TypeBinding[this.otherBindings.length];
+	    }
+	    this.otherGenericCasts[index-1] = someGenericCast;
+	}
+}
+
+// set the matching synthetic accessor
+protected void setSyntheticAccessor(FieldBinding fieldBinding, int index, SyntheticMethodBinding syntheticAccessor) {
+	if (index < 0) { // write-access ?
+		this.syntheticWriteAccessor = syntheticAccessor;
+    } else {
+		if (this.syntheticReadAccessors == null) {
+			this.syntheticReadAccessors = new SyntheticMethodBinding[this.otherBindings == null ? 1 : this.otherBindings.length + 1];
+		}
+		this.syntheticReadAccessors[index] = syntheticAccessor;
+    }
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+
+public void traverse(ASTVisitor visitor, ClassScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+
+public String unboundReferenceErrorName() {
+	return new String(this.tokens[0]);
+}
+
+public char[][] getName() {
+	return this.tokens;
+}
+
+public VariableBinding nullAnnotatedVariableBinding(boolean supportTypeAnnotations) {
+	if (this.binding != null && isFieldAccess()) {
+		FieldBinding fieldBinding;
+		if (this.otherBindings == null) {
+			fieldBinding = (FieldBinding) this.binding;
+		} else {
+			fieldBinding = this.otherBindings[this.otherBindings.length - 1];
+		}
+		if (supportTypeAnnotations || fieldBinding.isNullable() || fieldBinding.isNonNull()) {
+			return fieldBinding;
+		}
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
new file mode 100644
index 0000000..66f2e82
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 382350 - [1.8][compiler] Unable to invoke inherited default method via I.super.m() syntax
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *								bug 404728 - [1.8]NPE on QualifiedSuperReference error
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedSuperReference extends QualifiedThisReference {
+
+public QualifiedSuperReference(TypeReference name, int pos, int sourceEnd) {
+	super(name, pos, sourceEnd);
+}
+
+public boolean isSuper() {
+	return true;
+}
+
+public boolean isThis() {
+	return false;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output) {
+	return this.qualification.print(0, output).append(".super"); //$NON-NLS-1$
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	if ((this.bits & ParenthesizedMASK) != 0) {
+		scope.problemReporter().invalidParenthesizedExpression(this);
+		return null;
+	}
+	super.resolveType(scope);
+	if (this.resolvedType != null && !this.resolvedType.isValidBinding()) {
+		scope.problemReporter().illegalSuperAccess(this.qualification.resolvedType, this.resolvedType, this);
+		return null;
+	}
+	if (this.currentCompatibleType == null)
+		return null; // error case
+
+	if (this.currentCompatibleType.id == T_JavaLangObject) {
+		scope.problemReporter().cannotUseSuperInJavaLangObject(this);
+		return null;
+	}
+	return this.resolvedType = (this.currentCompatibleType.isInterface()
+			? this.currentCompatibleType
+			: this.currentCompatibleType.superclass());
+}
+
+int findCompatibleEnclosing(ReferenceBinding enclosingType, TypeBinding type) {
+	if (type.isInterface()) {
+		// super call to an overridden default method? (not considering outer enclosings)
+		ReferenceBinding[] supers = enclosingType.superInterfaces();
+		int length = supers.length;
+		boolean isLegal = true; // false => compoundName != null && closestMatch != null
+		char[][] compoundName = null;
+		ReferenceBinding closestMatch = null;
+		for (int i = 0; i < length; i++) {
+			if (supers[i].erasure() == type) {
+				this.currentCompatibleType = closestMatch = supers[i];
+			} else if (supers[i].erasure().isCompatibleWith(type)) {
+				isLegal = false;
+				compoundName = supers[i].compoundName;
+				if (closestMatch == null)
+					closestMatch = supers[i];
+				// keep looking to ensure we always find the referenced type (even if illegal) 
+			}
+		}
+		if (!isLegal) {
+			this.currentCompatibleType = null;
+			// Please note the slightly unconventional use of the ProblemReferenceBinding:
+			// we use the problem's compoundName to report the type being illegally bypassed,
+			// whereas the closestMatch denotes the resolved (though illegal) target type
+			// for downstream resolving.
+			this.resolvedType =  new ProblemReferenceBinding(compoundName, 
+					closestMatch, ProblemReasons.AttemptToBypassDirectSuper);
+		}
+		return 0; // never an outer enclosing type
+	}
+	return super.findCompatibleEnclosing(enclosingType, type);
+}
+
+public void traverse(
+	ASTVisitor visitor,
+	BlockScope blockScope) {
+
+	if (visitor.visit(this, blockScope)) {
+		this.qualification.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+public void traverse(
+		ASTVisitor visitor,
+		ClassScope blockScope) {
+
+	if (visitor.visit(this, blockScope)) {
+		this.qualification.traverse(visitor, blockScope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
new file mode 100644
index 0000000..0158bbb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 382350 - [1.8][compiler] Unable to invoke inherited default method via I.super.m() syntax
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class QualifiedThisReference extends ThisReference {
+
+	public TypeReference qualification;
+	ReferenceBinding currentCompatibleType;
+
+	public QualifiedThisReference(TypeReference name, int sourceStart, int sourceEnd) {
+		super(sourceStart, sourceEnd);
+		this.qualification = name;
+		name.bits |= IgnoreRawTypeCheck; // no need to worry about raw type usage
+		this.sourceStart = name.sourceStart;
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+
+		return flowInfo;
+	}
+
+	public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo,
+		boolean valueRequired) {
+
+		return flowInfo;
+	}
+
+	/**
+	 * Code generation for QualifiedThisReference
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	 */
+	public void generateCode(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		boolean valueRequired) {
+
+		int pc = codeStream.position;
+		if (valueRequired) {
+			if ((this.bits & DepthMASK) != 0) {
+				Object[] emulationPath =
+					currentScope.getEmulationPath(this.currentCompatibleType, true /*only exact match*/, false/*consider enclosing arg*/);
+				codeStream.generateOuterAccess(emulationPath, this, this.currentCompatibleType, currentScope);
+			} else {
+				// nothing particular after all
+				codeStream.aload_0();
+			}
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		this.constant = Constant.NotAConstant;
+		// X.this is not a param/raw type as denoting enclosing instance
+		TypeBinding type = this.qualification.resolveType(scope, true /* check bounds*/);
+		if (type == null || !type.isValidBinding()) return null;
+		// X.this is not a param/raw type as denoting enclosing instance
+		type = type.erasure();
+
+		// resolvedType needs to be converted to parameterized
+		if (type instanceof ReferenceBinding) {
+			this.resolvedType = scope.environment().convertToParameterizedType((ReferenceBinding) type);
+		} else {
+			// error case
+			this.resolvedType = type;
+		}
+
+		// the qualification MUST exactly match some enclosing type name
+		// It is possible to qualify 'this' by the name of the current class
+		int depth = findCompatibleEnclosing(scope.referenceType().binding, type);
+		this.bits &= ~DepthMASK; // flush previous depth if any
+		this.bits |= (depth & 0xFF) << DepthSHIFT; // encoded depth into 8 bits
+
+		if (this.currentCompatibleType == null) {
+			if (this.resolvedType.isValidBinding())
+				scope.problemReporter().noSuchEnclosingInstance(type, this, false);
+			// otherwise problem will be reported by the caller
+			return this.resolvedType;
+		} else {
+			scope.tagAsAccessingEnclosingInstanceStateOf(this.currentCompatibleType, false /* type variable access */);
+		}
+
+		// Ensure one cannot write code like: B() { super(B.this); }
+		if (depth == 0) {
+			checkAccess(scope, null);
+		} // if depth>0, path emulation will diagnose bad scenarii
+
+		return this.resolvedType;
+	}
+
+	int findCompatibleEnclosing(ReferenceBinding enclosingType, TypeBinding type) {
+		int depth = 0;
+		this.currentCompatibleType = enclosingType;
+		while (this.currentCompatibleType != null && this.currentCompatibleType != type) {
+			depth++;
+			this.currentCompatibleType = this.currentCompatibleType.isStatic() ? null : this.currentCompatibleType.enclosingType();
+		}
+		return depth;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		return this.qualification.print(0, output).append(".this"); //$NON-NLS-1$
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.qualification.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+
+	public void traverse(
+			ASTVisitor visitor,
+			ClassScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.qualification.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
new file mode 100644
index 0000000..5d76385
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+
+public class QualifiedTypeReference extends TypeReference {
+
+	public char[][] tokens;
+	public long[] sourcePositions;
+
+	public QualifiedTypeReference(char[][] sources , long[] poss) {
+
+		this.tokens = sources ;
+		this.sourcePositions = poss ;
+		this.sourceStart = (int) (this.sourcePositions[0]>>>32) ;
+		this.sourceEnd = (int)(this.sourcePositions[this.sourcePositions.length-1] & 0x00000000FFFFFFFFL ) ;
+	}
+
+	public TypeReference copyDims(int dim){
+		//return a type reference copy of me with some dimensions
+		//warning : the new type ref has a null binding
+		return new ArrayQualifiedTypeReference(this.tokens, dim, this.sourcePositions);
+	}
+	
+	public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions) {
+		//return a type reference copy of me with some dimensions
+		//warning : the new type ref has a null binding
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference = new ArrayQualifiedTypeReference(this.tokens, dim, annotationsOnDimensions, this.sourcePositions);
+		arrayQualifiedTypeReference.bits |= (this.bits & ASTNode.HasTypeAnnotations);
+		if (annotationsOnDimensions != null) {
+			arrayQualifiedTypeReference.bits |= ASTNode.HasTypeAnnotations;
+		}
+		return arrayQualifiedTypeReference;
+	}
+
+	protected TypeBinding findNextTypeBinding(int tokenIndex, Scope scope, PackageBinding packageBinding) {
+		LookupEnvironment env = scope.environment();
+		try {
+			env.missingClassFileLocation = this;
+			ReferenceBinding previousType = null;
+			if (this.resolvedType == null) {
+				this.resolvedType = scope.getType(this.tokens[tokenIndex], packageBinding);
+			} else {
+				if (this.resolvedType instanceof ReferenceBinding)
+					previousType = (ReferenceBinding) this.resolvedType;
+				this.resolvedType = scope.getMemberType(this.tokens[tokenIndex], (ReferenceBinding) this.resolvedType);
+				if (!this.resolvedType.isValidBinding()) {
+					this.resolvedType = new ProblemReferenceBinding(
+						CharOperation.subarray(this.tokens, 0, tokenIndex + 1),
+						(ReferenceBinding)this.resolvedType.closestMatch(),
+						this.resolvedType.problemId());
+				}
+			}
+			if (this.annotations != null && this.annotations[tokenIndex] != null) {
+				this.resolvedType = captureTypeAnnotations(scope, previousType, this.resolvedType, this.annotations[tokenIndex]);
+			}
+			return this.resolvedType;
+		} catch (AbortCompilation e) {
+			e.updateContext(this, scope.referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	public char[] getLastToken() {
+		return this.tokens[this.tokens.length-1];
+	}
+
+	protected void rejectAnnotationsOnPackageQualifiers(Scope scope, PackageBinding packageBinding) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=390882
+		if (packageBinding == null || this.annotations == null) return;
+
+		int i = packageBinding.compoundName.length;
+		for (int j = 0; j < i; j++) {
+			Annotation[] qualifierAnnot = this.annotations[j];
+			if (qualifierAnnot != null && qualifierAnnot.length > 0) {
+				scope.problemReporter().misplacedTypeAnnotations(qualifierAnnot[0], qualifierAnnot[qualifierAnnot.length - 1]);
+				this.annotations[j] = null;
+			}
+		}
+	}
+
+	protected void rejectAnnotationsOnStaticMemberQualififer(Scope scope, ReferenceBinding currentType, int tokenIndex) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385137
+		if (this.annotations != null && currentType.isMemberType() && currentType.isStatic()) {
+			Annotation[] qualifierAnnot = this.annotations[tokenIndex - 1];
+			if (qualifierAnnot != null) {
+				scope.problemReporter().illegalTypeAnnotationsInStaticMemberAccess(qualifierAnnot[0],
+						qualifierAnnot[qualifierAnnot.length - 1]);
+			}
+		}
+	}
+
+	protected TypeBinding getTypeBinding(Scope scope) {
+
+		if (this.resolvedType != null) {
+			return this.resolvedType;
+		}
+		Binding binding = scope.getPackage(this.tokens);
+		if (binding != null && !binding.isValidBinding()) {
+			if (binding instanceof ProblemReferenceBinding && binding.problemId() == ProblemReasons.NotFound) {
+				ProblemReferenceBinding problemBinding = (ProblemReferenceBinding) binding;
+				Binding pkg = scope.getTypeOrPackage(this.tokens);
+				return new ProblemReferenceBinding(problemBinding.compoundName, pkg instanceof PackageBinding ? null : scope.environment().createMissingType(null, this.tokens), ProblemReasons.NotFound);
+			}
+			return (ReferenceBinding) binding; // not found
+		}
+	    PackageBinding packageBinding = binding == null ? null : (PackageBinding) binding;
+	    rejectAnnotationsOnPackageQualifiers(scope, packageBinding);
+
+	    boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
+	    ReferenceBinding qualifiedType = null;
+		for (int i = packageBinding == null ? 0 : packageBinding.compoundName.length, max = this.tokens.length, last = max-1; i < max; i++) {
+			findNextTypeBinding(i, scope, packageBinding);
+			if (!this.resolvedType.isValidBinding())
+				return this.resolvedType;
+			if (i == 0 && this.resolvedType.isTypeVariable() && ((TypeVariableBinding) this.resolvedType).firstBound == null) { // cannot select from a type variable
+				scope.problemReporter().illegalAccessFromTypeVariable((TypeVariableBinding) this.resolvedType, this);
+				return null;
+			}
+			if (i <= last && isTypeUseDeprecated(this.resolvedType, scope)) {
+				reportDeprecatedType(this.resolvedType, scope, i);
+			}
+			if (isClassScope)
+				if (((ClassScope) scope).detectHierarchyCycle(this.resolvedType, this)) // must connect hierarchy to find inherited member types
+					return null;
+			ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
+			if (qualifiedType != null) {
+				rejectAnnotationsOnStaticMemberQualififer(scope, currentType, i);
+				ReferenceBinding enclosingType = currentType.enclosingType();
+				if (enclosingType != null && enclosingType.erasure() != qualifiedType.erasure()) {
+					qualifiedType = enclosingType; // inherited member type, leave it associated with its enclosing rather than subtype
+				}
+				boolean rawQualified;
+				if (currentType.isGenericType()) {
+					qualifiedType = scope.environment().createRawType(currentType, qualifiedType);
+				} else if ((rawQualified = qualifiedType.isRawType()) && !currentType.isStatic()) {
+					qualifiedType = scope.environment().createRawType((ReferenceBinding)currentType.erasure(), qualifiedType);
+				} else if ((rawQualified || qualifiedType.isParameterizedType()) && qualifiedType.erasure() == currentType.enclosingType().erasure()) {
+					qualifiedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType);
+				} else {
+					qualifiedType = currentType;
+				}
+			} else {
+				qualifiedType = currentType.isGenericType() ? (ReferenceBinding)scope.environment().convertToRawType(currentType, false /*do not force conversion of enclosing types*/) : currentType;
+			}
+			recordResolution(scope.environment(), qualifiedType);
+		}
+		this.resolvedType = qualifiedType;
+		return this.resolvedType;
+	}
+
+	void recordResolution(LookupEnvironment env, TypeBinding typeFound) {
+		if (typeFound != null && typeFound.isValidBinding())
+			for (int i = 0; i < env.resolutionListeners.length; i++) {
+				env.resolutionListeners[i].recordResolution(this, typeFound);
+			}
+	}
+
+	public char[][] getTypeName(){
+
+		return this.tokens;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		for (int i = 0; i < this.tokens.length; i++) {
+			if (i > 0) output.append('.');
+			if (this.annotations != null && this.annotations[i] != null) {
+				printAnnotations(this.annotations[i], output);
+				output.append(' ');
+			}
+			output.append(this.tokens[i]);
+		}
+		return output;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					int annotationsLength = this.annotations[i] == null ? 0 : this.annotations[i].length;
+					for (int j = 0; j < annotationsLength; j++)
+						this.annotations[i][j].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public int getAnnotatableLevels() {
+		return this.tokens.length;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java
new file mode 100644
index 0000000..15ab52c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Receiver.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.ast;
+
+public class Receiver extends Argument {
+	public NameReference qualifyingName;
+	public Receiver(char[] name, long posNom, TypeReference typeReference, NameReference qualifyingName, int modifiers) {
+		super(name, posNom, typeReference, modifiers);
+		this.qualifyingName = qualifyingName;
+	}
+	public boolean isReceiver() {
+		return true;
+	}
+	
+	public StringBuffer print(int indent, StringBuffer output) {
+
+		printIndent(indent, output);
+		printModifiers(this.modifiers, output);
+
+		if (this.type == null) {
+			output.append("<no type> "); //$NON-NLS-1$
+		} else {
+			this.type.print(0, output).append(' ');
+		}
+		if (this.qualifyingName != null) {
+			this.qualifyingName.print(indent, output);
+			output.append('.');
+		}
+		return output.append(this.name);
+	}
+}
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
new file mode 100644
index 0000000..38e7041
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public abstract class Reference extends Expression  {
+/**
+ * BaseLevelReference constructor comment.
+ */
+public Reference() {
+	super();
+}
+public abstract FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound);
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return flowInfo;
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (flowContext.isNullcheckedFieldAccess(this)) {
+		return true; // enough seen
+	}
+	return super.checkNPE(scope, flowContext, flowInfo);
+}
+
+protected boolean checkNullableFieldDereference(Scope scope, FieldBinding field, long sourcePosition) {
+	if ((field.tagBits & TagBits.AnnotationNullable) != 0) {
+		scope.problemReporter().nullableFieldDereference(field, sourcePosition);
+		return true;
+	}
+	return false;
+}
+
+public FieldBinding fieldBinding() {
+	//this method should be sent one FIELD-tagged references
+	//  (ref.bits & BindingIds.FIELD != 0)()
+	return null ;
+}
+
+public void fieldStore(Scope currentScope, CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, TypeBinding receiverType, boolean isImplicitThisReceiver, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (fieldBinding.isStatic()) {
+		if (valueRequired) {
+			switch (fieldBinding.type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2();
+					break;
+				default : 
+					codeStream.dup();
+					break;
+			}
+		}
+		if (syntheticWriteAccessor == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, fieldBinding, receiverType, isImplicitThisReceiver);
+			codeStream.fieldAccess(Opcodes.OPC_putstatic, fieldBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
+		}
+	} else { // Stack:  [owner][new field value]  ---> [new field value][owner][new field value]
+		if (valueRequired) {
+			switch (fieldBinding.type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2_x1();
+					break;
+				default : 
+					codeStream.dup_x1();
+					break;
+			}
+		}
+		if (syntheticWriteAccessor == null) {
+			TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, fieldBinding, receiverType, isImplicitThisReceiver);
+			codeStream.fieldAccess(Opcodes.OPC_putfield, fieldBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.invoke(Opcodes.OPC_invokestatic, syntheticWriteAccessor, null /* default declaringClass */);
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired);
+
+public abstract void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired);
+
+public abstract void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired);
+
+/** 
+ * Is the given reference equivalent to the receiver, 
+ * meaning that both denote the same path of field reads?
+ * Used from {@link FlowContext#isNullcheckedFieldAccess(Reference)}.
+ */
+public boolean isEquivalent(Reference reference) {
+	return false;
+}
+
+public FieldBinding lastFieldBinding() {
+	// override to answer the field designated by the entire reference
+	// (as opposed to fieldBinding() which answers the first field in a QNR)
+	return null;
+}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	FieldBinding fieldBinding = lastFieldBinding();
+	if (fieldBinding != null) {
+		if (fieldBinding.isNonNull() || flowContext.isNullcheckedFieldAccess(this)) {
+			return FlowInfo.NON_NULL;
+		} else if (fieldBinding.isNullable()) {
+			return FlowInfo.POTENTIALLY_NULL;
+		}
+	}
+	if (this.resolvedType != null) {
+		if ((this.resolvedType.tagBits & TagBits.AnnotationNonNull) != 0)
+			return FlowInfo.NON_NULL;
+		else if ((this.resolvedType.tagBits & TagBits.AnnotationNullable) != 0)
+			return FlowInfo.POTENTIALLY_NULL;
+	}
+	return FlowInfo.UNKNOWN;
+}
+
+/* report if a private field is only read from a 'special operator',
+ * i.e., in a postIncrement expression or a compound assignment,
+ * where the information is never flowing out off the field. */
+void reportOnlyUselesslyReadPrivateField(BlockScope currentScope, FieldBinding fieldBinding, boolean valueRequired) {
+	if (valueRequired) {
+		// access is relevant, turn compound use into real use:
+		fieldBinding.compoundUseFlag = 0;
+		fieldBinding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+	} else {
+		if (fieldBinding.isUsedOnlyInCompound()) {
+			fieldBinding.compoundUseFlag--; // consume one
+			if (fieldBinding.compoundUseFlag == 0					// report only the last usage
+					&& fieldBinding.isOrEnclosedByPrivateType() 
+					&& (this.implicitConversion & TypeIds.UNBOXING) == 0) // don't report if unboxing is involved (might cause NPE)
+			{
+				// compoundAssignment/postIncrement is the only usage of this field
+				currentScope.problemReporter().unusedPrivateField(fieldBinding.sourceField());
+				fieldBinding.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // don't report again
+			}
+		}
+	}
+}
+/* report a local/arg that is only read from a 'special operator',
+ * i.e., in a postIncrement expression or a compound assignment,
+ * where the information is never flowing out off the local/arg. */
+static void reportOnlyUselesslyReadLocal(BlockScope currentScope, LocalVariableBinding localBinding, boolean valueRequired) {
+	if (localBinding.declaration == null)
+		return;  // secret local
+	if ((localBinding.declaration.bits & ASTNode.IsLocalDeclarationReachable) == 0)
+		return;  // declaration is unreachable
+	if (localBinding.useFlag >= LocalVariableBinding.USED)
+		return;  // we're only interested in cases with only compound access (negative count)
+
+	if (valueRequired) {
+		// access is relevant
+		localBinding.useFlag = LocalVariableBinding.USED;
+		return;
+	} else {
+		localBinding.useFlag++;
+		if (localBinding.useFlag != LocalVariableBinding.UNUSED) // have all negative counts been consumed?
+			return; // still waiting to see more usages of this kind
+	}
+	// at this point we know we have something to report
+	if (localBinding.declaration instanceof Argument) {
+		// check compiler options to report against unused arguments
+		MethodScope methodScope = currentScope.methodScope();
+		if (methodScope != null && !methodScope.isLambdaScope()) { // lambda must be congruent with the descriptor.
+			MethodBinding method = ((AbstractMethodDeclaration)methodScope.referenceContext()).binding;
+			
+			boolean shouldReport = !method.isMain();
+			if (method.isImplementing()) {
+				shouldReport &= currentScope.compilerOptions().reportUnusedParameterWhenImplementingAbstract;
+			} else if (method.isOverriding()) {
+				shouldReport &= currentScope.compilerOptions().reportUnusedParameterWhenOverridingConcrete;
+			}
+			
+			if (shouldReport) {
+				// report the case of an argument that is unread except through a special operator
+				currentScope.problemReporter().unusedArgument(localBinding.declaration);
+			}
+		}
+	} else {
+		// report the case of a local variable that is unread except for a special operator
+		currentScope.problemReporter().unusedLocalVariable(localBinding.declaration);
+	}
+	localBinding.useFlag = LocalVariableBinding.USED; // don't report again
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
new file mode 100644
index 0000000..1fdae07
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReferenceExpression.java
@@ -0,0 +1,631 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *                          Bug 384687 - [1.8] Wildcard type arguments should be rejected for lambda and reference expressions
+ *	   Stephan Herrmann - Contribution for
+ *							bug 402028 - [1.8][compiler] null analysis for reference expressions 
+ *							bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super via I.super.m() syntax
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contribution for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+public class ReferenceExpression extends FunctionalExpression implements InvocationSite {
+	
+	private static char [] LAMBDA = { 'l', 'a', 'm', 'b', 'd', 'a' };
+	public Expression lhs;
+	public TypeReference [] typeArguments;
+	public char [] selector;
+	
+	private TypeBinding receiverType;
+	private boolean haveReceiver;
+	public TypeBinding[] resolvedTypeArguments;
+	private boolean typeArgumentsHaveErrors;
+	
+	MethodBinding syntheticAccessor;	// synthetic accessor for inner-emulation
+	private int depth;
+	
+	public ReferenceExpression(CompilationResult compilationResult, Expression lhs, TypeReference [] typeArguments, char [] selector, int sourceEnd) {
+		super(compilationResult);
+		this.lhs = lhs;
+		this.typeArguments = typeArguments;
+		this.selector = selector;
+		this.sourceStart = lhs.sourceStart;
+		this.sourceEnd = sourceEnd;
+	}
+ 
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		SourceTypeBinding sourceType = currentScope.enclosingSourceType();
+		if (this.receiverType.isArrayType()) {
+			if (isConstructorReference()) {
+				this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
+			} else if (CharOperation.equals(this.selector, TypeConstants.CLONE)) {
+				this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
+			}
+		} else if (this.syntheticAccessor != null) {
+			if (this.lhs.isSuper() || isMethodReference())
+				this.binding = this.syntheticAccessor;
+		}
+		
+		int pc = codeStream.position;
+		StringBuffer buffer = new StringBuffer();
+		int argumentsSize = 0;
+		buffer.append('(');
+		if (this.haveReceiver) {
+			this.lhs.generateCode(currentScope, codeStream, true);
+			if (this.lhs.isSuper()) {
+				if (this.lhs instanceof QualifiedSuperReference) {
+					QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) this.lhs;
+					TypeReference qualification = qualifiedSuperReference.qualification;
+					if (qualification.resolvedType.isInterface()) {
+						buffer.append(sourceType.signature());
+					} else {
+						buffer.append(((QualifiedSuperReference) this.lhs).currentCompatibleType.signature());
+					}
+				} else { 
+					buffer.append(sourceType.signature());
+				}
+			} else {
+				buffer.append(this.receiverType.signature());
+			}
+			argumentsSize = 1;
+		} else {
+			if (this.isConstructorReference()) {
+				ReferenceBinding[] enclosingInstances = Binding.UNINITIALIZED_REFERENCE_TYPES;
+				if (this.receiverType.isNestedType()) {
+					NestedTypeBinding nestedType = null;
+					if (this.receiverType instanceof ParameterizedTypeBinding) {
+						nestedType = (NestedTypeBinding)((ParameterizedTypeBinding) this.receiverType).genericType();
+					} else {
+						nestedType = (NestedTypeBinding) this.receiverType;
+					}
+					if ((enclosingInstances = nestedType.syntheticEnclosingInstanceTypes()) != null) {
+						int length = enclosingInstances.length;
+						argumentsSize = length;
+						for (int i = 0 ; i < length; i++) {
+							ReferenceBinding syntheticArgumentType = enclosingInstances[i];
+							buffer.append(syntheticArgumentType.signature());
+							Object[] emulationPath = currentScope.getEmulationPath(
+									syntheticArgumentType,
+									false /* allow compatible match */,
+									true /* disallow instance reference in explicit constructor call */);
+							codeStream.generateOuterAccess(emulationPath, this, syntheticArgumentType, currentScope);
+						}
+					}
+					// Reject types that capture outer local arguments, these cannot be manufactured by the metafactory.
+					if (nestedType.syntheticOuterLocalVariables() != null) {
+						currentScope.problemReporter().noSuchEnclosingInstance(nestedType.enclosingType, this, false);
+						return;
+					}
+				}
+				if (this.syntheticAccessor != null) {
+					this.binding = sourceType.addSyntheticFactoryMethod(this.binding, this.syntheticAccessor, enclosingInstances);
+				}
+			}
+		}
+		buffer.append(')');
+		buffer.append('L');
+		buffer.append(this.resolvedType.constantPoolName());
+		buffer.append(';');
+		int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
+		codeStream.invokeDynamic(invokeDynamicNumber, argumentsSize, 1, LAMBDA, buffer.toString().toCharArray(), 
+				this.isConstructorReference(), (this.lhs instanceof TypeReference? (TypeReference) this.lhs : null), this.typeArguments);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	
+	public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+		
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0 || this.binding == null || !this.binding.isValidBinding()) 
+			return;
+		
+		MethodBinding codegenBinding = this.binding.original();
+		SourceTypeBinding enclosingSourceType = currentScope.enclosingSourceType();
+		
+		if (this.isConstructorReference()) {
+			ReferenceBinding allocatedType = codegenBinding.declaringClass;
+			if (codegenBinding.isPrivate() && enclosingSourceType != (allocatedType = codegenBinding.declaringClass)) {
+				if ((allocatedType.tagBits & TagBits.IsLocalType) != 0) {
+					codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
+				} else {
+					this.syntheticAccessor = ((SourceTypeBinding) allocatedType).addSyntheticMethod(codegenBinding, false);
+					currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+				}
+			}
+			return;
+		}
+	
+		// -----------------------------------   Only method references from now on -----------
+		if (this.binding.isPrivate()) {
+			if (enclosingSourceType != codegenBinding.declaringClass){
+				this.syntheticAccessor = ((SourceTypeBinding)codegenBinding.declaringClass).addSyntheticMethod(codegenBinding, false /* not super access */);
+				currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+			}
+			return;
+		}
+		
+		if (this.lhs.isSuper()) {
+			SourceTypeBinding destinationType = enclosingSourceType;
+			if (this.lhs instanceof QualifiedSuperReference) { 	// qualified super
+				QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) this.lhs;
+				TypeReference qualification = qualifiedSuperReference.qualification;
+				if (!qualification.resolvedType.isInterface()) // we can't drop the bridge in I, it may not even be a source type.
+					destinationType = (SourceTypeBinding) (qualifiedSuperReference.currentCompatibleType);
+			}
+			
+			this.syntheticAccessor = destinationType.addSyntheticMethod(codegenBinding, true);
+			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+			return;
+		}
+		
+		if (this.binding.isProtected() && (this.bits & ASTNode.DepthMASK) != 0 && codegenBinding.declaringClass.getPackage() != enclosingSourceType.getPackage()) {
+			SourceTypeBinding currentCompatibleType = (SourceTypeBinding) enclosingSourceType.enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+			this.syntheticAccessor = currentCompatibleType.addSyntheticMethod(codegenBinding, isSuperAccess());
+			currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
+			return;
+		}
+	}
+	
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		// static methods with receiver value never get here
+		if (this.haveReceiver) {
+			this.lhs.checkNPE(currentScope, flowContext, flowInfo);
+			this.lhs.analyseCode(currentScope, flowContext, flowInfo, true);
+		}
+		manageSyntheticAccessIfNecessary(currentScope, flowInfo);
+		return flowInfo;
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		
+		final CompilerOptions compilerOptions = scope.compilerOptions();
+		TypeBinding lhsType;
+    	if (this.constant != Constant.NotAConstant) {
+    		this.constant = Constant.NotAConstant;
+    		this.enclosingScope = scope;
+    		if (isConstructorReference())
+    			this.lhs.bits |= ASTNode.IgnoreRawTypeCheck; // raw types in constructor references are to be treated as though <> were specified.
+
+    		lhsType = this.lhs.resolveType(scope);
+    		if (this.typeArguments != null) {
+    			int length = this.typeArguments.length;
+    			this.typeArgumentsHaveErrors = compilerOptions.sourceLevel < ClassFileConstants.JDK1_5;
+    			this.resolvedTypeArguments = new TypeBinding[length];
+    			for (int i = 0; i < length; i++) {
+    				TypeReference typeReference = this.typeArguments[i];
+    				if ((this.resolvedTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+    					this.typeArgumentsHaveErrors = true;
+    				}
+    				if (this.typeArgumentsHaveErrors && typeReference instanceof Wildcard) { // resolveType on wildcard always return null above, resolveTypeArgument is the real workhorse.
+    					scope.problemReporter().illegalUsageOfWildcard(typeReference);
+    				}
+    			}
+    			if (this.typeArgumentsHaveErrors)
+    				return this.resolvedType = null;
+    		}
+    	} else {
+    		if (this.typeArgumentsHaveErrors)
+				return this.resolvedType = null;
+    		lhsType = this.lhs.resolvedType;
+    	}
+
+    	if (this.expectedType == null && this.expressionContext == INVOCATION_CONTEXT) {
+			return new PolyTypeBinding(this);
+		}
+		super.resolveType(scope);
+		
+    	if (lhsType == null) 
+			return this.resolvedType = null; 	// no hope
+		if (lhsType.problemId() == ProblemReasons.AttemptToBypassDirectSuper)
+			lhsType = lhsType.closestMatch();	// improve resolving experience
+    	if (!lhsType.isValidBinding()) 
+			return this.resolvedType = null;	// nope, no useful type found
+		
+		final TypeBinding[] descriptorParameters = this.descriptor != null ? this.descriptor.parameters : Binding.NO_PARAMETERS;
+		if (lhsType.isBaseType()) {
+			scope.problemReporter().errorNoMethodFor(this.lhs, lhsType, this.selector, descriptorParameters);
+			return this.resolvedType = null;
+		}
+		
+		if (isConstructorReference() && !lhsType.canBeInstantiated()) {
+			scope.problemReporter().cannotInstantiate(this.lhs, lhsType);
+			return this.resolvedType = null;
+		}
+		
+		/* 15.28: "It is a compile-time error if a method reference of the form super :: NonWildTypeArgumentsopt Identifier or of the form 
+		   TypeName . super :: NonWildTypeArgumentsopt Identifier occurs in a static context.": This is nop since the primary when it resolves
+		   itself will complain automatically.
+		
+		   15.28: "The immediately enclosing instance of an inner class instance (15.9.2) must be provided for a constructor reference by a lexically 
+		   enclosing instance of this (8.1.3)", we will actually implement this check in code generation. Emulation path computation will fail if there
+		   is no suitable enclosing instance. While this could be pulled up to here, leaving it to code generation is more consistent with Java 5,6,7 
+		   modus operandi.
+		*/
+		
+		// handle the special case of array construction first.
+        this.receiverType = lhsType;
+		final int parametersLength = descriptorParameters.length;
+        if (isConstructorReference() && lhsType.isArrayType()) {
+        	final TypeBinding leafComponentType = lhsType.leafComponentType();
+			if (leafComponentType.isParameterizedType()) {
+        		scope.problemReporter().illegalGenericArray(leafComponentType, this);
+        		return this.resolvedType = null;
+        	}
+        	if (parametersLength != 1 || scope.parameterCompatibilityLevel(descriptorParameters[0], TypeBinding.INT) == Scope.NOT_COMPATIBLE) {
+        		scope.problemReporter().invalidArrayConstructorReference(this, lhsType, descriptorParameters);
+        		return this.resolvedType = null;
+        	}
+        	if (!lhsType.isCompatibleWith(this.descriptor.returnType)) {
+        		scope.problemReporter().constructedArrayIncompatible(this, lhsType, this.descriptor.returnType);
+        		return this.resolvedType = null;
+        	}
+        	return this.resolvedType; // No binding construction possible right now. Code generator will have to conjure up a rabbit.
+        }
+		
+		this.haveReceiver = true;
+		if (this.lhs instanceof NameReference) {
+			if ((this.lhs.bits & ASTNode.RestrictiveFlagMASK) == Binding.TYPE) {
+				this.haveReceiver = false;
+			}
+		} else if (this.lhs instanceof TypeReference) {
+			this.haveReceiver = false;
+		}
+
+		/* For Reference expressions unlike other call sites, we always have a receiver _type_ since LHS of :: cannot be empty. 
+		   LHS's resolved type == actual receiver type. All code below only when a valid descriptor is available.
+		 */
+        if (this.descriptor == null || !this.descriptor.isValidBinding())
+        	return this.resolvedType =  null;
+        
+        // 15.28.1
+        final boolean isMethodReference = isMethodReference();
+        this.depth = 0;
+        MethodBinding someMethod = isMethodReference ? scope.getMethod(this.receiverType, this.selector, descriptorParameters, this) :
+        											       scope.getConstructor((ReferenceBinding) this.receiverType, descriptorParameters, this);
+        int someMethodDepth = this.depth, anotherMethodDepth = 0;
+    	if (someMethod != null && someMethod.isValidBinding()) {
+        	final boolean isStatic = someMethod.isStatic();
+        	if (isStatic && (this.haveReceiver || this.receiverType.isParameterizedType())) {
+    			scope.problemReporter().methodMustBeAccessedStatically(this, someMethod);
+    			return this.resolvedType = null;
+    		}
+        	if (!this.haveReceiver) {
+        		if (!isStatic && !someMethod.isConstructor()) {
+        			scope.problemReporter().methodMustBeAccessedWithInstance(this, someMethod);
+        			return this.resolvedType = null;
+        		}
+        	} 
+        } else {
+        	if (this.lhs instanceof NameReference && !this.haveReceiver && isMethodReference() && this.receiverType.isRawType()) {
+        		if ((this.lhs.bits & ASTNode.IgnoreRawTypeCheck) == 0 && compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
+        			scope.problemReporter().rawTypeReference(this.lhs, this.receiverType);
+        		}
+        	}
+        }
+    	if (this.lhs.isSuper() && this.lhs.resolvedType.isInterface()) {
+    		scope.checkAppropriateMethodAgainstSupers(this.selector, someMethod, this.descriptor.parameters, this);
+    	}
+
+        MethodBinding anotherMethod = null;
+        if (!this.haveReceiver && isMethodReference && parametersLength > 0) {
+        	final TypeBinding potentialReceiver = descriptorParameters[0];
+        	if (potentialReceiver.isCompatibleWith(this.receiverType, scope)) {
+        		TypeBinding typeToSearch = this.receiverType;
+        		if (this.receiverType.isRawType()) {
+        			TypeBinding superType = potentialReceiver.findSuperTypeOriginatingFrom(this.receiverType);
+        			if (superType != null)
+        				typeToSearch = superType;
+        		}
+        		TypeBinding [] parameters = Binding.NO_PARAMETERS;
+        		if (parametersLength > 1) {
+        			parameters = new TypeBinding[parametersLength - 1];
+        			System.arraycopy(descriptorParameters, 1, parameters, 0, parametersLength - 1);
+        		}
+        		this.depth = 0;
+        		anotherMethod = scope.getMethod(typeToSearch, this.selector, parameters, this);
+        		anotherMethodDepth = this.depth;
+        		this.depth = 0;
+        	}
+        	if (anotherMethod != null && anotherMethod.isValidBinding() && anotherMethod.isStatic()) {
+        		scope.problemReporter().methodMustBeAccessedStatically(this, anotherMethod);
+        		return this.resolvedType = null;
+        	}
+        }
+        
+        if (someMethod != null && someMethod.isValidBinding() && anotherMethod != null && anotherMethod.isValidBinding()) {
+        	scope.problemReporter().methodReferenceSwingsBothWays(this, anotherMethod, someMethod);
+        	return this.resolvedType = null;
+        }
+        
+        if (someMethod != null && someMethod.isValidBinding()) {
+        	this.binding = someMethod;
+        	this.bits &= ~ASTNode.DepthMASK;
+        	if (someMethodDepth > 0) {
+        		this.bits |= (someMethodDepth & 0xFF) << ASTNode.DepthSHIFT;
+        	}
+        } else if (anotherMethod != null && anotherMethod.isValidBinding()) {
+        	this.binding = anotherMethod;
+        	this.bits &= ~ASTNode.DepthMASK;
+        	if (anotherMethodDepth > 0) {
+        		this.bits |= (anotherMethodDepth & 0xFF) << ASTNode.DepthSHIFT;
+        	}
+        } else {
+        	this.binding = null;
+        	this.bits &= ~ASTNode.DepthMASK;
+        }
+
+        if (this.binding == null) {
+        	char [] visibleName = isConstructorReference() ? this.receiverType.sourceName() : this.selector;
+        	scope.problemReporter().danglingReference(this, this.receiverType, visibleName, descriptorParameters);
+			return this.resolvedType = null;
+        }
+        
+        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=382350#c2, I.super::abstractMethod will be handled there.
+
+        if (this.binding.isAbstract() && this.lhs.isSuper())
+        	scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
+        
+        if (this.binding.isStatic()) {
+        	if (this.binding.declaringClass != this.receiverType)
+        		scope.problemReporter().indirectAccessToStaticMethod(this, this.binding);
+        } else {
+        	AbstractMethodDeclaration srcMethod = this.binding.sourceMethod();
+        	if (srcMethod != null && srcMethod.isMethod())
+        		srcMethod.bits &= ~ASTNode.CanBeStatic;
+        }
+        
+    	if (isMethodUseDeprecated(this.binding, scope, true))
+    		scope.problemReporter().deprecatedMethod(this.binding, this);
+
+    	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES)
+    		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.resolvedTypeArguments, this.typeArguments);
+    	
+    	if ((this.binding.tagBits & TagBits.HasMissingType) != 0)
+    		scope.problemReporter().missingTypeInMethod(this, this.binding);
+    	
+
+        // OK, we have a compile time declaration, see if it passes muster.
+        TypeBinding [] methodExceptions = this.binding.thrownExceptions;
+        TypeBinding [] kosherExceptions = this.descriptor.thrownExceptions;
+        next: for (int i = 0, iMax = methodExceptions.length; i < iMax; i++) {
+        	for (int j = 0, jMax = kosherExceptions.length; j < jMax; j++) {
+        		if (methodExceptions[i].isCompatibleWith(kosherExceptions[j], scope))
+        			continue next;
+        	}
+        	scope.problemReporter().unhandledException(methodExceptions[i], this);
+        }
+        if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
+        	int len = this.descriptor.parameters.length;
+    		for (int i = 0; i < len; i++) {
+    			Boolean declared = this.descriptor.parameterNonNullness == null ? null : this.descriptor.parameterNonNullness[i];
+    			Boolean implemented = this.binding.parameterNonNullness == null ? null : this.binding.parameterNonNullness[i];
+    			if (declared == Boolean.FALSE) { // promise to accept null
+    				if (implemented != Boolean.FALSE) {
+    					char[][] requiredAnnot = implemented == null ? null : scope.environment().getNonNullAnnotationName();
+    					scope.problemReporter().parameterLackingNullableAnnotation(this, this.descriptor, i, 
+    							scope.environment().getNullableAnnotationName(),
+    							requiredAnnot, this.binding.parameters[i]);
+    				}
+    			} else if (declared == null) {
+    				if (implemented == Boolean.TRUE) {
+    					scope.problemReporter().parameterRequiresNonnull(this, this.descriptor, i,
+    							scope.environment().getNonNullAnnotationName(), this.binding.parameters[i]);
+    				}
+    			}
+    		}
+        	if ((this.descriptor.tagBits & TagBits.AnnotationNonNull) != 0) {
+        		if ((this.binding.tagBits & TagBits.AnnotationNonNull) == 0) {
+        			char[][] providedAnnotationName = ((this.binding.tagBits & TagBits.AnnotationNullable) != 0) ?
+        					scope.environment().getNullableAnnotationName() : null;
+        			scope.problemReporter().illegalReturnRedefinition(this, this.descriptor,
+        					scope.environment().getNonNullAnnotationName(),
+        					providedAnnotationName, this.binding.returnType);
+        		}
+        	}
+        }
+        
+    	if (checkInvocationArguments(scope, null, this.receiverType, this.binding, null, descriptorParameters, false, this))
+    		this.bits |= ASTNode.Unchecked;
+
+    	if (this.descriptor.returnType.id != TypeIds.T_void) {
+    		// from 1.5 source level on, array#clone() returns the array type (but binding still shows Object)
+    		TypeBinding returnType = null;
+    		if (this.binding == scope.environment().arrayClone || this.binding.isConstructor()) {
+    			returnType = this.receiverType;
+    		} else {
+    			if ((this.bits & ASTNode.Unchecked) != 0 && this.resolvedTypeArguments == null) {
+    				returnType = this.binding.returnType;
+    				if (returnType != null) {
+    					returnType = scope.environment().convertToRawType(returnType.erasure(), true);
+    				}
+    			} else {
+    				returnType = this.binding.returnType;
+    				if (returnType != null) {
+    					returnType = returnType.capture(scope, this.sourceEnd);
+    				}
+    			}
+    		}
+    		if (!returnType.isCompatibleWith(this.descriptor.returnType, scope) && !isBoxingCompatible(returnType, this.descriptor.returnType, this, scope)) {
+    			scope.problemReporter().incompatibleReturnType(this, this.binding, this.descriptor.returnType);
+    			this.binding = null;
+    			this.resolvedType = null;
+    		}
+    	}
+
+    	return this.resolvedType; // Phew !
+	}
+
+	public final boolean isConstructorReference() {
+		return CharOperation.equals(this.selector,  ConstantPool.Init);
+	}
+	
+	public final boolean isMethodReference() {
+		return !CharOperation.equals(this.selector,  ConstantPool.Init);
+	}
+	
+	public TypeBinding[] genericTypeArguments() {
+		return null;
+	}
+
+	public boolean isSuperAccess() {
+		return false;
+	}
+
+	public boolean isTypeAccess() {
+		return false;
+	}
+
+	public void setActualReceiverType(ReferenceBinding receiverType) {
+		return;
+	}
+
+	public void setDepth(int depth) {
+		this.depth = depth;
+	}
+
+	public void setFieldIndex(int depth) {
+		return;
+	}
+
+	public StringBuffer printExpression(int tab, StringBuffer output) {
+		
+		this.lhs.print(0, output);
+		output.append("::"); //$NON-NLS-1$
+		if (this.typeArguments != null) {
+			output.append('<');
+			int max = this.typeArguments.length - 1;
+			for (int j = 0; j < max; j++) {
+				this.typeArguments[j].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+			output.append('>');
+		}
+		if (isConstructorReference())
+			output.append("new"); //$NON-NLS-1$
+		else 
+			output.append(this.selector);
+		
+		return output;
+	}
+		
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			
+			this.lhs.traverse(visitor, blockScope);
+			
+			int length = this.typeArguments == null ? 0 : this.typeArguments.length;
+			for (int i = 0; i < length; i++) {
+				this.typeArguments[i].traverse(visitor, blockScope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+
+	public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+		// 15.28.1
+		final MethodBinding sam = left.getSingleAbstractMethod(this.enclosingScope);
+		if (sam == null || !sam.isValidBinding())
+			return false;
+		boolean isCompatible;
+		setExpectedType(left);
+		IErrorHandlingPolicy oldPolicy = this.enclosingScope.problemReporter().switchErrorHandlingPolicy(silentErrorHandlingPolicy);
+		try {
+			this.binding = null;
+			resolveType(this.enclosingScope);
+		} finally {
+			this.enclosingScope.problemReporter().switchErrorHandlingPolicy(oldPolicy);
+			isCompatible = this.binding != null && this.binding.isValidBinding();
+			if (isCompatible) {
+				if (this.resultExpressions == null)
+					this.resultExpressions = new SimpleLookupTable(); // gather for more specific analysis later.
+				this.resultExpressions.put(left, this.binding.returnType);
+			}
+			this.binding = null;
+			setExpectedType(null);
+		}
+		return isCompatible;
+	}
+	public boolean tIsMoreSpecific(TypeBinding t, TypeBinding s) {
+		/* 15.12.2.5 t is more specific than s iff ... Some of the checks here are redundant by the very fact of control reaching here, 
+		   but have been left in for completeness/documentation sakes. These should be cheap anyways. 
+		*/
+		
+		// Both t and s are functional interface types ... 
+		MethodBinding tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		if (tSam == null || !tSam.isValidBinding())
+			return false;
+		MethodBinding sSam = s.getSingleAbstractMethod(this.enclosingScope);
+		if (sSam == null || !sSam.isValidBinding())
+			return false;
+		
+		// t should neither be a subinterface nor a superinterface of s
+		if (t.findSuperTypeOriginatingFrom(s) != null || s.findSuperTypeOriginatingFrom(t) != null)
+			return false;
+
+		// The descriptor parameter types of t are the same as the descriptor parameter types of s.
+		if (tSam.parameters.length != sSam.parameters.length)
+			return false;
+		for (int i = 0, length = tSam.parameters.length; i < length; i++) {
+			if (tSam.parameters[i] != sSam.parameters[i])
+				return false;
+		}
+		
+		// Either the descriptor return type of s is void or ...
+		if (sSam.returnType.id == TypeIds.T_void)
+			return true;
+		
+		/* ... or the descriptor return type of the capture of T is more specific than the descriptor return type of S for 
+		   an invocation expression of the same form as the method reference..
+		*/
+		Expression resultExpression = (Expression) this.resultExpressions.get(t); // should be same as for s
+		
+		t = t.capture(this.enclosingScope, this.sourceEnd);
+		tSam = t.getSingleAbstractMethod(this.enclosingScope);
+		return resultExpression.tIsMoreSpecific(tSam.returnType, sSam.returnType);
+	}
+}
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
new file mode 100644
index 0000000..8145e39
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *     							bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365835 - [compiler][null] inconsistent error reporting.
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *								bug 401030 - [1.8][null] Null analysis support for lambda methods. 
+ *     Jesper S Moller - Contributions for
+ *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ReturnStatement extends Statement implements ExpressionContext {
+
+	public Expression expression;
+	public SubRoutineStatement[] subroutines;
+	public LocalVariableBinding saveValueVariable;
+	public int initStateIndex = -1;
+	private boolean implicitReturn;
+
+public ReturnStatement(Expression expression, int sourceStart, int sourceEnd) {
+	this(expression, sourceStart, sourceEnd, false);
+}
+
+public ReturnStatement(Expression expression, int sourceStart, int sourceEnd, boolean implicitReturn) {
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+	this.expression = expression;
+	this.implicitReturn = implicitReturn;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {	// here requires to generate a sequence of finally blocks invocations depending corresponding
+	// to each of the traversed try statements, so that execution will terminate properly.
+
+	// lookup the label, this should answer the returnContext
+
+	MethodScope methodScope = currentScope.methodScope();
+	if (this.expression != null) {
+		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
+		this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		if (flowInfo.reachMode() == FlowInfo.REACHABLE)
+			checkAgainstNullAnnotation(currentScope, flowContext, this.expression.nullStatus(flowInfo, flowContext));
+		if (currentScope.compilerOptions().analyseResourceLeaks) {
+			FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression, flowInfo, flowContext);
+			if (trackingVariable != null) {
+				if (methodScope != trackingVariable.methodScope)
+					trackingVariable.markClosedInNestedMethod();
+				// by returning the method passes the responsibility to the caller:
+				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.expression, flowInfo, flowContext, true);
+			}
+		}
+	}
+	this.initStateIndex =
+		methodScope.recordInitializationStates(flowInfo);
+	// compute the return sequence (running the finally blocks)
+	FlowContext traversedContext = flowContext;
+	int subCount = 0;
+	boolean saveValueNeeded = false;
+	boolean hasValueToSave = needValueStore();
+	boolean noAutoCloseables = true;
+	do {
+		SubRoutineStatement sub;
+		if ((sub = traversedContext.subroutine()) != null) {
+			if (this.subroutines == null){
+				this.subroutines = new SubRoutineStatement[5];
+			}
+			if (subCount == this.subroutines.length) {
+				System.arraycopy(this.subroutines, 0, (this.subroutines = new SubRoutineStatement[subCount*2]), 0, subCount); // grow
+			}
+			this.subroutines[subCount++] = sub;
+			if (sub.isSubRoutineEscaping()) {
+				saveValueNeeded = false;
+				this.bits |= ASTNode.IsAnySubRoutineEscaping;
+				break;
+			}
+			if (sub instanceof TryStatement) {
+				if (((TryStatement) sub).resources.length > 0) {
+					noAutoCloseables = false;
+				}
+			}
+		}
+		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
+
+		if (traversedContext instanceof InsideSubRoutineFlowContext) {
+			ASTNode node = traversedContext.associatedNode;
+			if (node instanceof SynchronizedStatement) {
+				this.bits |= ASTNode.IsSynchronized;
+			} else if (node instanceof TryStatement) {
+				TryStatement tryStatement = (TryStatement) node;
+				flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
+				if (hasValueToSave) {
+					if (this.saveValueVariable == null){ // closest subroutine secret variable is used
+						prepareSaveValueLocation(tryStatement);
+					}
+					saveValueNeeded = true;
+					this.initStateIndex =
+						methodScope.recordInitializationStates(flowInfo);
+				}
+			}
+		} else if (traversedContext instanceof InitializationFlowContext) {
+				currentScope.problemReporter().cannotReturnInInitializer(this);
+				return FlowInfo.DEAD_END;
+		}
+	} while ((traversedContext = traversedContext.getLocalParent()) != null);
+
+	// resize subroutines
+	if ((this.subroutines != null) && (subCount != this.subroutines.length)) {
+		System.arraycopy(this.subroutines, 0, (this.subroutines = new SubRoutineStatement[subCount]), 0, subCount);
+	}
+
+	// secret local variable for return value (note that this can only occur in a real method)
+	if (saveValueNeeded) {
+		if (this.saveValueVariable != null) {
+			this.saveValueVariable.useFlag = LocalVariableBinding.USED;
+		}
+	} else {
+		this.saveValueVariable = null;
+		if (((this.bits & ASTNode.IsSynchronized) == 0) && this.expression != null && this.expression.resolvedType == TypeBinding.BOOLEAN) {
+			if (noAutoCloseables) { // can't abruptly return in the presence of autocloseables. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=367566
+				this.expression.bits |= ASTNode.IsReturnedValue;
+			}
+		}
+	}
+	currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope);
+	// inside conditional structure respect that a finally-block may conditionally be entered directly from here
+	flowContext.recordAbruptExit();
+	return FlowInfo.DEAD_END;
+}
+void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, int nullStatus) {
+	if (nullStatus != FlowInfo.NON_NULL) {
+		// if we can't prove non-null check against declared null-ness of the enclosing method:
+		long tagBits;
+		MethodBinding methodBinding;
+		try {
+			methodBinding = scope.methodScope().referenceMethodBinding();
+			tagBits = methodBinding.tagBits;
+		} catch (NullPointerException npe) {
+			// chain of references in try-block has several potential nulls;
+			// any null means we cannot perform the following check
+			return;			
+		}
+		if ((tagBits & TagBits.AnnotationNonNull) != 0) {
+			flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, nullStatus);
+		}
+	}
+}
+
+/**
+ * Retrun statement code generation
+ *
+ *   generate the finallyInvocationSequence.
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	int pc = codeStream.position;
+	boolean alreadyGeneratedExpression = false;
+	// generate the expression
+	if (needValueStore()) {
+		alreadyGeneratedExpression = true;
+		this.expression.generateCode(currentScope, codeStream, needValue()); // no value needed if non-returning subroutine
+		generateStoreSaveValueIfNecessary(codeStream);
+	}
+
+	// generation of code responsible for invoking the finally blocks in sequence
+	if (this.subroutines != null) {
+		Object reusableJSRTarget = this.expression == null ? (Object)TypeBinding.VOID : this.expression.reusableJSRTarget();
+		for (int i = 0, max = this.subroutines.length; i < max; i++) {
+			SubRoutineStatement sub = this.subroutines[i];
+			boolean didEscape = sub.generateSubRoutineInvocation(currentScope, codeStream, reusableJSRTarget, this.initStateIndex, this.saveValueVariable);
+			if (didEscape) {
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, i, codeStream);
+					return;
+			}
+		}
+	}
+	if (this.saveValueVariable != null) {
+		codeStream.load(this.saveValueVariable);
+	}
+	if (this.expression != null && !alreadyGeneratedExpression) {
+		this.expression.generateCode(currentScope, codeStream, true);
+		// hook necessary for Code Snippet
+		generateStoreSaveValueIfNecessary(codeStream);
+	}
+	// output the suitable return bytecode or wrap the value inside a descriptor for doits
+	generateReturnBytecode(codeStream);
+	if (this.saveValueVariable != null) {
+		codeStream.removeVariable(this.saveValueVariable);
+	}
+	if (this.initStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+		codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+	SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream);
+}
+
+/**
+ * Dump the suitable return bytecode for a return statement
+ *
+ */
+public void generateReturnBytecode(CodeStream codeStream) {
+	codeStream.generateReturnBytecode(this.expression);
+}
+
+public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
+	if (this.saveValueVariable != null) {
+		codeStream.store(this.saveValueVariable, false);
+		// the variable is visible as soon as the local is stored
+		codeStream.addVariable(this.saveValueVariable);
+	}
+}
+
+private boolean needValueStore() {
+	return this.expression != null
+					&& (this.expression.constant == Constant.NotAConstant || (this.expression.implicitConversion & TypeIds.BOXING)!= 0)
+					&& !(this.expression instanceof NullLiteral);
+}
+
+public boolean needValue() {
+	return this.saveValueVariable != null
+					|| (this.bits & ASTNode.IsSynchronized) != 0
+					|| ((this.bits & ASTNode.IsAnySubRoutineEscaping) == 0);
+}
+
+public void prepareSaveValueLocation(TryStatement targetTryStatement){
+	this.saveValueVariable = targetTryStatement.secretReturnValue;
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output){
+	printIndent(tab, output).append("return "); //$NON-NLS-1$
+	if (this.expression != null )
+		this.expression.printExpression(0, output) ;
+	return output.append(';');
+}
+
+public void resolve(BlockScope scope) {
+	MethodScope methodScope = scope.methodScope();
+	MethodBinding methodBinding;
+	LambdaExpression lambda = methodScope.referenceContext instanceof LambdaExpression ? (LambdaExpression) methodScope.referenceContext : null;
+	TypeBinding methodType =
+		lambda != null ? lambda.expectedResultType() :
+		(methodScope.referenceContext instanceof AbstractMethodDeclaration)
+			? ((methodBinding = ((AbstractMethodDeclaration) methodScope.referenceContext).binding) == null
+				? null
+				: methodBinding.returnType)
+			: TypeBinding.VOID;
+	TypeBinding expressionType;
+	
+	if (this.expression != null) {
+		this.expression.setExpressionContext(ASSIGNMENT_CONTEXT);
+		this.expression.setExpectedType(methodType);
+	}
+	
+	if (methodType == TypeBinding.VOID) {
+		// the expression should be null, exceptions exist for lambda expressions.
+		if (this.expression == null) {
+			if (lambda != null)
+				lambda.returnsExpression(null, TypeBinding.VOID);
+			return;
+		}
+		expressionType = this.expression.resolveType(scope);
+		if (lambda != null && !this.implicitReturn)
+			lambda.returnsExpression(this.expression, expressionType);
+		if (this.implicitReturn && (expressionType == TypeBinding.VOID || this.expression.statementExpression()))
+			return;
+		if (expressionType != null)
+			scope.problemReporter().attemptToReturnNonVoidExpression(this, expressionType);
+		return;
+	}
+	if (this.expression == null) {
+		if (lambda != null)
+			lambda.returnsExpression(null,  methodType);
+		if (methodType != null) scope.problemReporter().shouldReturn(methodType, this);
+		return;
+	}
+	
+	expressionType = this.expression.resolveType(scope);
+	if (lambda != null)
+		lambda.returnsExpression(this.expression, expressionType);
+	
+	if (expressionType == null) return;
+	if (expressionType == TypeBinding.VOID) {
+		scope.problemReporter().attemptToReturnVoidValue(this);
+		return;
+	}
+	if (methodType == null)
+		return;
+
+	if (methodType != expressionType) // must call before computeConversion() and typeMismatchError()
+		scope.compilationUnitScope().recordTypeConversion(methodType, expressionType);
+	if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, methodType)
+			|| expressionType.isCompatibleWith(methodType)) {
+
+		this.expression.computeConversion(scope, methodType, expressionType);
+		if (expressionType.needsUncheckedConversion(methodType)) {
+		    scope.problemReporter().unsafeTypeConversion(this.expression, expressionType, methodType);
+		}
+		if (this.expression instanceof CastExpression
+				&& (this.expression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
+			CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
+		}
+		return;
+	} else if (isBoxingCompatible(expressionType, methodType, this.expression, scope)) {
+		this.expression.computeConversion(scope, methodType, expressionType);
+		if (this.expression instanceof CastExpression
+				&& (this.expression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
+			CastExpression.checkNeedForAssignedCast(scope, methodType, (CastExpression) this.expression);
+		}			return;
+	}
+	if ((methodType.tagBits & TagBits.HasMissingType) == 0) {
+		// no need to complain if return type was missing (avoid secondary error : 220967)
+		scope.problemReporter().typeMismatchError(expressionType, methodType, this.expression, null);
+	}
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	if (visitor.visit(this, scope)) {
+		if (this.expression != null)
+			this.expression.traverse(visitor, scope);
+	}
+	visitor.endVisit(this, scope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
new file mode 100644
index 0000000..2eff389
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * SingleMemberAnnotation node
+ */
+public class SingleMemberAnnotation extends Annotation {
+
+	public Expression memberValue;
+	private MemberValuePair[] singlePairs; // fake pair set, only value has accurate positions
+
+	public SingleMemberAnnotation(TypeReference type, int sourceStart) {
+		this.type = type;
+		this.sourceStart = sourceStart;
+		this.sourceEnd = type.sourceEnd;
+	}
+
+	public ElementValuePair[] computeElementValuePairs() {
+		return new ElementValuePair[] {memberValuePairs()[0].compilerElementPair};
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.Annotation#memberValuePairs()
+	 */
+	public MemberValuePair[] memberValuePairs() {
+		if (this.singlePairs == null) {
+			this.singlePairs =
+				new MemberValuePair[]{
+					new MemberValuePair(VALUE, this.memberValue.sourceStart, this.memberValue.sourceEnd, this.memberValue)
+				};
+		}
+		return this.singlePairs;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		super.printExpression(indent, output);
+		output.append('(');
+		this.memberValue.printExpression(indent, output);
+		return output.append(')');
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.memberValue != null) {
+				this.memberValue.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.memberValue != null) {
+				this.memberValue.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..4766f6d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -0,0 +1,1049 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 292478 - Report potentially null across variable assignment,
+ *								bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *     Jesper S Moller - <jesper@selskabet.org>   - Contributions for 
+ *     							bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class SingleNameReference extends NameReference implements OperatorIds {
+
+	public static final int READ = 0;
+	public static final int WRITE = 1;
+	public char[] token;
+	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
+	public TypeBinding genericCast;
+
+public SingleNameReference(char[] source, long pos) {
+	super();
+	this.token = source;
+	this.sourceStart = (int) (pos >>> 32);
+	this.sourceEnd = (int) pos;
+}
+
+public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+	boolean isReachable = (flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0;
+	// compound assignment extra work
+	if (isCompound) { // check the variable part is initialized if blank final
+		switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+			case Binding.FIELD : // reading a field
+				FieldBinding fieldBinding = (FieldBinding) this.binding;
+				if (fieldBinding.isBlankFinal()
+						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
+					FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+					if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+					}
+				}
+				manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
+				break;
+			case Binding.LOCAL : // reading a local variable
+				// check if assigning a final blank field
+				LocalVariableBinding localBinding;
+				if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
+					currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+					// we could improve error msg here telling "cannot use compound assignment on final local variable"
+				}
+				if (localBinding.useFlag != LocalVariableBinding.USED) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
+					// access from compound assignment does not prevent "unused" warning, unless unboxing is involved:
+					if (isReachable && (this.implicitConversion & TypeIds.UNBOXING) != 0) {
+						localBinding.useFlag = LocalVariableBinding.USED;
+					} else {
+						// use values < 0 to count the number of compound uses:
+						if (localBinding.useFlag <= LocalVariableBinding.UNUSED)
+							localBinding.useFlag--;
+					}
+				}
+		}
+	}
+	if (assignment.expression != null) {
+		flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
+	}
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
+
+			// check if assigning a final field
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			if (fieldBinding.isFinal()) {
+				// inside a context where allowed
+				if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
+					if (flowInfo.isPotentiallyAssigned(fieldBinding)) {
+						currentScope.problemReporter().duplicateInitializationOfBlankFinalField(fieldBinding, this);
+					} else {
+						flowContext.recordSettingFinal(fieldBinding, this, flowInfo);
+					}
+					flowInfo.markAsDefinitelyAssigned(fieldBinding);
+				} else {
+					currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this);
+				}
+			} else if (!isCompound && fieldBinding.isNonNull()) {
+				// record assignment for detecting uninitialized non-null fields:
+				flowInfo.markAsDefinitelyAssigned(fieldBinding);
+			}
+			break;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			final boolean isFinal = localBinding.isFinal();
+			if (!flowInfo.isDefinitelyAssigned(localBinding)){// for local variable debug attributes
+				this.bits |= ASTNode.FirstAssignmentToLocal;
+			} else {
+				this.bits &= ~ASTNode.FirstAssignmentToLocal;
+			}
+			if (flowInfo.isPotentiallyAssigned(localBinding)) {
+				localBinding.tagBits &= ~TagBits.IsEffectivelyFinal;
+				if (!isFinal && (this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+					currentScope.problemReporter().cannotReferToNonEffectivelyFinalOuterLocal(localBinding, this);
+				}
+			}
+			if (isFinal) {
+				if ((this.bits & ASTNode.DepthMASK) == 0) {
+					// tolerate assignment to final local in unreachable code (45674)
+					if ((isReachable && isCompound) || !localBinding.isBlankFinal()){
+						currentScope.problemReporter().cannotAssignToFinalLocal(localBinding, this);
+					} else if (flowInfo.isPotentiallyAssigned(localBinding)) {
+						currentScope.problemReporter().duplicateInitializationOfFinalLocal(localBinding, this);
+					} else {
+						flowContext.recordSettingFinal(localBinding, this, flowInfo);
+					}
+				} else {
+					currentScope.problemReporter().cannotAssignToFinalOuterLocal(localBinding, this);
+				}
+			}
+			else /* avoid double diagnostic */ if ((localBinding.tagBits & TagBits.IsArgument) != 0) {
+				currentScope.problemReporter().parameterAssignment(localBinding, this);
+			}
+			flowInfo.markAsDefinitelyAssigned(localBinding);
+	}
+	manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+	return flowInfo;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return analyseCode(currentScope, flowContext, flowInfo, true);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+				manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
+			}
+			// check if reading a final blank field
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
+				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+				if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+				}
+			}
+			break;
+		case Binding.LOCAL : // reading a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+				localBinding.useFlag = LocalVariableBinding.USED;
+			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
+				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
+			}
+	}
+	if (valueRequired) {
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+	}
+	return flowInfo;
+}
+
+public TypeBinding checkFieldAccess(BlockScope scope) {
+	FieldBinding fieldBinding = (FieldBinding) this.binding;
+	this.constant = fieldBinding.constant();
+
+	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
+	this.bits |= Binding.FIELD;
+	MethodScope methodScope = scope.methodScope();
+	if (fieldBinding.isStatic()) {
+		// check if accessing enum static field in initializer
+		ReferenceBinding declaringClass = fieldBinding.declaringClass;
+		if (declaringClass.isEnum()) {
+			SourceTypeBinding sourceType = scope.enclosingSourceType();
+			if (this.constant == Constant.NotAConstant
+					&& !methodScope.isStatic
+					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+					&& methodScope.isInsideInitializerOrConstructor()) {
+				scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
+			}
+		}
+	} else {
+		if (scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
+			scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
+		}
+		// must check for the static status....
+		if (methodScope.isStatic) {
+			scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
+			return fieldBinding.type;
+		} else {
+			scope.tagAsAccessingEnclosingInstanceStateOf(fieldBinding.declaringClass, false /* type variable access */);
+		}
+	}
+
+	if (isFieldUseDeprecated(fieldBinding, scope, this.bits))
+		scope.problemReporter().deprecatedField(fieldBinding, this);
+
+	if ((this.bits & ASTNode.IsStrictlyAssigned) == 0
+			&& methodScope.enclosingSourceType() == fieldBinding.original().declaringClass
+			&& methodScope.lastVisibleFieldID >= 0
+			&& fieldBinding.id >= methodScope.lastVisibleFieldID
+			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
+		scope.problemReporter().forwardReference(this, 0, fieldBinding);
+		this.bits |= ASTNode.IgnoreNoEffectAssignCheck;
+	}
+	return fieldBinding.type;
+
+}
+
+public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (!super.checkNPE(scope, flowContext, flowInfo)) {
+		CompilerOptions compilerOptions = scope.compilerOptions();
+		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+			VariableBinding var = nullAnnotatedVariableBinding(compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8);
+			if (var instanceof FieldBinding) {
+				checkNullableFieldDereference(scope, (FieldBinding) var, ((long)this.sourceStart<<32)+this.sourceEnd);
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+	if (runtimeTimeType == null || compileTimeType == null)
+		return;
+	if ((this.bits & Binding.FIELD) != 0 && this.binding != null && this.binding.isValidBinding()) {
+		// set the generic cast after the fact, once the type expectation is fully known (no need for strict cast)
+		FieldBinding field = (FieldBinding) this.binding;
+		FieldBinding originalBinding = field.original();
+		TypeBinding originalType = originalBinding.type;
+		// extra cast needed if field type is type variable
+		if (originalType.leafComponentType().isTypeVariable()) {
+	    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
+	    		? compileTimeType  // unboxing: checkcast before conversion
+	    		: runtimeTimeType;
+	        this.genericCast = originalType.genericCast(scope.boxing(targetType));
+	        if (this.genericCast instanceof ReferenceBinding) {
+				ReferenceBinding referenceCast = (ReferenceBinding) this.genericCast;
+				if (!referenceCast.canBeSeenBy(scope)) {
+		        	scope.problemReporter().invalidType(this,
+		        			new ProblemReferenceBinding(
+								CharOperation.splitOn('.', referenceCast.shortReadableName()),
+								referenceCast,
+								ProblemReasons.NotVisible));
+				}
+	        }
+		}
+	}
+	super.computeConversion(scope, runtimeTimeType, compileTimeType);
+}
+
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	// optimizing assignment like: i = i + 1 or i = 1 + i
+	if (assignment.expression.isCompactableOperation()) {
+		BinaryExpression operation = (BinaryExpression) assignment.expression;
+		int operator = (operation.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+		SingleNameReference variableReference;
+		if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == this.binding)) {
+			// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], operation.right, operator, operation.implicitConversion, valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			return;
+		}
+		if ((operation.right instanceof SingleNameReference)
+				&& ((operator == OperatorIds.PLUS) || (operator == OperatorIds.MULTIPLY)) // only commutative operations
+				&& ((variableReference = (SingleNameReference) operation.right).binding == this.binding)
+				&& (operation.left.constant != Constant.NotAConstant) // exclude non constant expressions, since could have side-effect
+				&& (((operation.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) != TypeIds.T_JavaLangString) // exclude string concatenation which would occur backwards
+				&& (((operation.right.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) != TypeIds.T_JavaLangString)) { // exclude string concatenation which would occur backwards
+			// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			return;
+		}
+	}
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			int pc = codeStream.position;
+			FieldBinding codegenBinding = ((FieldBinding) this.binding).original();
+			if (!codegenBinding.isStatic()) { // need a receiver?
+				if ((this.bits & ASTNode.DepthMASK) != 0) {
+					ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+					Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+					codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+				} else {
+					generateReceiver(codeStream);
+				}
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			assignment.expression.generateCode(currentScope, codeStream, true);
+			fieldStore(currentScope, codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], this.actualReceiverType, true /*implicit this*/, valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			// no need for generic cast as value got dupped
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			if (localBinding.resolvedPosition != -1) {
+				assignment.expression.generateCode(currentScope, codeStream, true);
+			} else {
+				if (assignment.expression.constant != Constant.NotAConstant) {
+					// assigning an unused local to a constant value = no actual assignment is necessary
+					if (valueRequired) {
+						codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion);
+					}
+				} else {
+					assignment.expression.generateCode(currentScope, codeStream, true);
+					/* Even though the value may not be required, we force it to be produced, and discard it later
+					on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3.	*/
+					if (valueRequired) {
+						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
+					} else {
+						switch(localBinding.type.id) {
+							case TypeIds.T_long :
+							case TypeIds.T_double :
+								codeStream.pop2();
+								break;
+							default :
+								codeStream.pop();
+								break;
+						}						
+					}
+				}
+				return;
+			}
+			// 26903, need extra cast to store null in array local var
+			if (localBinding.type.isArrayType()
+				&& ((assignment.expression instanceof CastExpression)	// arrayLoc = (type[])null
+						&& (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL))){
+				codeStream.checkcast(localBinding.type);
+			}
+
+			// normal local assignment (since cannot store in outer local which are final locations)
+			codeStream.store(localBinding, valueRequired);
+			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) { // for local variable debug attributes
+				localBinding.recordInitializationStartPC(codeStream.position);
+			}
+			// implicit conversion
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+	}
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	} else {
+		switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+			case Binding.FIELD : // reading a field
+				FieldBinding codegenField = ((FieldBinding) this.binding).original();
+				Constant fieldConstant = codegenField.constant();
+				if (fieldConstant != Constant.NotAConstant) {
+					// directly use inlined value for constant fields
+					if (valueRequired) {
+						codeStream.generateConstant(fieldConstant, this.implicitConversion);
+					}
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					return;
+				}
+				if (codegenField.isStatic()) {
+					if (!valueRequired
+							// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
+							&& ((FieldBinding)this.binding).original().declaringClass == this.actualReceiverType.erasure()
+							&& ((this.implicitConversion & TypeIds.UNBOXING) == 0)
+							&& this.genericCast == null) {
+						// if no valueRequired, optimize out entire gen
+						codeStream.recordPositionsFrom(pc, this.sourceStart);
+						return;
+					}
+					// managing private access
+					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);
+						codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
+					} else {
+						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+					}
+				} else {
+					if (!valueRequired
+							&& (this.implicitConversion & TypeIds.UNBOXING) == 0
+							&& this.genericCast == null) {
+						// if no valueRequired, optimize out entire gen
+						codeStream.recordPositionsFrom(pc, this.sourceStart);
+						return;
+					}
+					// managing enclosing instance access
+					if ((this.bits & ASTNode.DepthMASK) != 0) {
+						ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+						Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+						codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+					} else {
+						generateReceiver(codeStream);
+					}
+					// managing private access
+					if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);
+						codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
+					} else {
+						codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+					}
+				}
+				break;
+			case Binding.LOCAL : // reading a local
+				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+				if (localBinding.resolvedPosition == -1) {
+					if (valueRequired) {
+						// restart code gen
+						localBinding.useFlag = LocalVariableBinding.USED;
+						throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+					}
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					return;
+				}
+				if (!valueRequired && (this.implicitConversion & TypeIds.UNBOXING) == 0) {
+					// if no valueRequired, optimize out entire gen
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					return;
+				}
+				// outer local?
+				if ((this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+					checkEffectiveFinality(localBinding, currentScope);
+					// outer local can be reached either through a synthetic arg or a synthetic field
+					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+					codeStream.generateOuterAccess(path, this, localBinding, currentScope);
+				} else {
+					// regular local variable read
+					codeStream.load(localBinding);
+				}
+				break;
+			default: // type
+				codeStream.recordPositionsFrom(pc, this.sourceStart);
+				return;
+		}
+	}
+	// required cast must occur even if no value is required
+	if (this.genericCast != null) codeStream.checkcast(this.genericCast);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else {
+		boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+		// conversion only generated if unboxing
+		if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+		switch (isUnboxing ? postConversionType(currentScope).id : this.resolvedType.id) {
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			default :
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/*
+ * Regular API for compound assignment, relies on the fact that there is only one reference to the
+ * variable, which carries both synthetic read/write accessors.
+ * The APIs with an extra argument is used whenever there are two references to the same variable which
+ * are optimized in one access: e.g "a = a + 1" optimized into "a++".
+ */
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.LOCAL:
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			// check if compound assignment is the only usage of this local
+			Reference.reportOnlyUselesslyReadLocal(currentScope, localBinding, valueRequired);
+			break;
+		case Binding.FIELD:
+			// check if compound assignment is the only usage of a private field
+			reportOnlyUselesslyReadPrivateField(currentScope, (FieldBinding)this.binding, valueRequired);
+	}
+	this.generateCompoundAssignment(
+		currentScope,
+		codeStream,
+		this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE],
+		expression,
+		operator,
+		assignmentImplicitConversion,
+		valueRequired);
+}
+
+/*
+ * The APIs with an extra argument is used whenever there are two references to the same variable which
+ * are optimized in one access: e.g "a = a + 1" optimized into "a++".
+ */
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			if (codegenField.isStatic()) {
+				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);					
+					codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
+				} else {
+					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+				}
+			} else {
+				if ((this.bits & ASTNode.DepthMASK) != 0) {
+					ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+					Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+					codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+				} else {
+					codeStream.aload_0();
+				}
+				codeStream.dup();
+				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);
+					codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
+				} else {
+					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+				}
+			}
+			break;
+		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			// using incr bytecode if possible
+			Constant assignConstant;
+			switch (localBinding.type.id) {
+				case T_JavaLangString :
+					codeStream.generateStringConcatenationAppend(currentScope, this, expression);
+					if (valueRequired) {
+						codeStream.dup();
+					}
+					codeStream.store(localBinding, false);
+					return;
+				case T_int :
+					assignConstant = expression.constant;
+					if (localBinding.resolvedPosition == -1) {
+						if (valueRequired) {
+							/*
+							 * restart code gen because we either:
+							 * - need the value
+							 * - the constant can have potential side-effect
+							 */
+							localBinding.useFlag = LocalVariableBinding.USED;
+							throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+						} else if (assignConstant == Constant.NotAConstant) {
+							// we only need to generate the value of the expression's constant if it is not a constant expression
+							expression.generateCode(currentScope, codeStream, false);
+						}
+						return;
+					}
+					if ((assignConstant != Constant.NotAConstant)
+							&& (assignConstant.typeID() != TypeIds.T_float) // only for integral types
+							&& (assignConstant.typeID() != TypeIds.T_double)) { // TODO (philippe) is this test needed ?
+						switch (operator) {
+							case PLUS :
+								int increment  = assignConstant.intValue();
+								if (increment != (short) increment) break; // not representable as a 16-bits value
+								codeStream.iinc(localBinding.resolvedPosition, increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+							case MINUS :
+								increment  = -assignConstant.intValue();
+								if (increment != (short) increment) break; // not representable as a 16-bits value
+								codeStream.iinc(localBinding.resolvedPosition, increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+						}
+					}
+					//$FALL-THROUGH$
+				default :
+					if (localBinding.resolvedPosition == -1) {
+						assignConstant = expression.constant;
+						if (valueRequired) {
+							/*
+							 * restart code gen because we either:
+							 * - need the value
+							 * - the constant can have potential side-effect
+							 */
+							localBinding.useFlag = LocalVariableBinding.USED;
+							throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+						} else if (assignConstant == Constant.NotAConstant) {
+							// we only need to generate the value of the expression's constant if it is not a constant expression
+							expression.generateCode(currentScope, codeStream, false);
+						}
+						return;
+					}
+					codeStream.load(localBinding);
+			}
+	}
+	// perform the actual compound operation
+	int operationTypeID;
+	switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
+		case T_JavaLangString :
+		case T_JavaLangObject :
+		case T_undefined :
+			// we enter here if the single name reference is a field of type java.lang.String or if the type of the
+			// operation is java.lang.Object
+			// For example: o = o + ""; // where the compiled type of o is java.lang.Object.
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+			// no need for generic cast on previous #getfield since using Object string buffer methods.
+			break;
+		default :
+			// promote the array reference to the suitable operation type
+			if (this.genericCast != null)
+				codeStream.checkcast(this.genericCast);
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One){ // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// store the result back into the variable
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			fieldStore(currentScope, codeStream, codegenField, writeAccessor, this.actualReceiverType, true /* implicit this*/, valueRequired);
+			// no need for generic cast as value got dupped
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			if (valueRequired) {
+				switch (localBinding.type.id) {
+					case TypeIds.T_long :
+					case TypeIds.T_double :
+						codeStream.dup2();
+						break;
+					default:
+						codeStream.dup();
+						break;
+				}
+			}
+			codeStream.store(localBinding, false);
+	}
+}
+
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding fieldBinding = (FieldBinding)this.binding;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
+			// check if postIncrement is the only usage of a private field
+			reportOnlyUselesslyReadPrivateField(currentScope, fieldBinding, valueRequired);
+			FieldBinding codegenField = fieldBinding.original();
+			if (codegenField.isStatic()) {
+				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);
+					codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
+				} else {
+					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+				}
+			} else {
+				if ((this.bits & ASTNode.DepthMASK) != 0) {
+					ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
+					Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+					codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+				} else {
+					codeStream.aload_0();
+				}
+				codeStream.dup();
+				if ((this.syntheticAccessors == null) || (this.syntheticAccessors[SingleNameReference.READ] == null)) {
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, this.actualReceiverType, true /* implicit this */);
+					codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
+				} else {
+					codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessors[SingleNameReference.READ], null /* default declaringClass */);
+				}
+			}
+			TypeBinding operandType;
+			if (this.genericCast != null) {
+				codeStream.checkcast(this.genericCast);
+				operandType = this.genericCast;
+			} else {
+				operandType = codegenField.type;
+			}
+			if (valueRequired) {
+				if (codegenField.isStatic()) {
+					switch (operandType.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.dup2();
+							break;
+						default:
+							codeStream.dup();
+							break;
+					}					
+				} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
+					switch (operandType.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.dup2_x1();
+							break;
+						default:
+							codeStream.dup_x1();
+							break;
+					}
+				}
+			}
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+			codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+			codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+			fieldStore(currentScope, codeStream, codegenField, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], this.actualReceiverType, true /*implicit this*/, false);
+			// no need for generic cast 
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185682
+			// check if postIncrement is the only usage of this local
+			Reference.reportOnlyUselesslyReadLocal(currentScope, localBinding, valueRequired);
+			if (localBinding.resolvedPosition == -1) {
+				if (valueRequired) {
+					// restart code gen
+					localBinding.useFlag = LocalVariableBinding.USED;
+					throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+				}
+				return;
+			}
+
+			// using incr bytecode if possible
+			if (localBinding.type == TypeBinding.INT) {
+				if (valueRequired) {
+					codeStream.load(localBinding);
+				}
+				if (postIncrement.operator == OperatorIds.PLUS) {
+					codeStream.iinc(localBinding.resolvedPosition, 1);
+				} else {
+					codeStream.iinc(localBinding.resolvedPosition, -1);
+				}
+			} else {
+				codeStream.load(localBinding);
+				if (valueRequired){
+					switch (localBinding.type.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.dup2();
+							break;
+						default:
+							codeStream.dup();
+							break;
+					}					
+				}
+				codeStream.generateImplicitConversion(this.implicitConversion);
+				codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+				codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+				codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+				codeStream.store(localBinding, false);
+			}
+	}
+}
+
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return null;
+}
+
+public boolean isEquivalent(Reference reference) {
+	char[] otherToken = null;
+	if (reference instanceof SingleNameReference) {
+		otherToken = ((SingleNameReference) reference).token;
+	} else if (reference instanceof FieldReference) {
+		// test for comparison "f1" vs. "this.f1":
+		FieldReference fr = (FieldReference) reference;
+		if (fr.receiver.isThis() && !(fr.receiver instanceof QualifiedThisReference))
+			otherToken = fr.token;
+	}
+	return otherToken != null && CharOperation.equals(this.token, otherToken);
+}
+
+/**
+ * Returns the local variable referenced by this node. Can be a direct reference (SingleNameReference)
+ * or thru a cast expression etc...
+ */
+public LocalVariableBinding localVariableBinding() {
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			break;
+		case Binding.LOCAL : // reading a local variable
+			return (LocalVariableBinding) this.binding;
+	}
+	return null;
+}
+
+public VariableBinding nullAnnotatedVariableBinding(boolean supportTypeAnnotations) {
+	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+		case Binding.LOCAL : // reading a local variable
+			if (supportTypeAnnotations 
+					|| (((VariableBinding)this.binding).tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) != 0)
+				return (VariableBinding) this.binding;
+	}
+	return null;
+}
+
+public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+	LocalVariableBinding local = localVariableBinding();
+	if (local != null) {
+		return flowInfo.nullStatus(local);
+	}
+	return super.nullStatus(flowInfo, flowContext);
+}
+
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (((this.bits & ASTNode.DepthMASK) == 0 && (this.bits & ASTNode.IsCapturedOuterLocal) == 0) || (this.constant != Constant.NotAConstant)) {
+		return;
+	}
+	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 :
+					currentScope.emulateOuterAccess(localVariableBinding);
+			}
+		}
+	}
+}
+
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)	return;
+
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (this.constant != Constant.NotAConstant)
+		return;
+
+	if ((this.bits & Binding.FIELD) != 0) {
+		FieldBinding fieldBinding = (FieldBinding) this.binding;
+		FieldBinding codegenField = fieldBinding.original();
+		if (((this.bits & ASTNode.DepthMASK) != 0)
+			&& (codegenField.isPrivate() // private access
+				|| (codegenField.isProtected() // implicit protected access
+						&& codegenField.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage()))) {
+			if (this.syntheticAccessors == null)
+				this.syntheticAccessors = new MethodBinding[2];
+			this.syntheticAccessors[isReadAccess ? SingleNameReference.READ : SingleNameReference.WRITE] =
+			    ((SourceTypeBinding)currentScope.enclosingSourceType().
+					enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT)).addSyntheticMethod(codegenField, isReadAccess, false /*not super access*/);
+			currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess);
+			return;
+		}
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#postConversionType(Scope)
+ */
+public TypeBinding postConversionType(Scope scope) {
+	TypeBinding convertedType = this.resolvedType;
+	if (this.genericCast != null)
+		convertedType = this.genericCast;
+	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	switch (runtimeType) {
+		case T_boolean :
+			convertedType = TypeBinding.BOOLEAN;
+			break;
+		case T_byte :
+			convertedType = TypeBinding.BYTE;
+			break;
+		case T_short :
+			convertedType = TypeBinding.SHORT;
+			break;
+		case T_char :
+			convertedType = TypeBinding.CHAR;
+			break;
+		case T_int :
+			convertedType = TypeBinding.INT;
+			break;
+		case T_float :
+			convertedType = TypeBinding.FLOAT;
+			break;
+		case T_long :
+			convertedType = TypeBinding.LONG;
+			break;
+		case T_double :
+			convertedType = TypeBinding.DOUBLE;
+			break;
+		default :
+	}
+	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
+		convertedType = scope.environment().computeBoxingType(convertedType);
+	}
+	return convertedType;
+}
+
+public StringBuffer printExpression(int indent, StringBuffer output){
+	return output.append(this.token);
+}
+public TypeBinding reportError(BlockScope scope) {
+	//=====error cases=======
+	this.constant = Constant.NotAConstant;
+	if (this.binding instanceof ProblemFieldBinding) {
+		scope.problemReporter().invalidField(this, (FieldBinding) this.binding);
+	} else if (this.binding instanceof ProblemReferenceBinding || this.binding instanceof MissingTypeBinding) {
+		scope.problemReporter().invalidType(this, (TypeBinding) this.binding);
+	} else {
+		scope.problemReporter().unresolvableReference(this, this.binding);
+	}
+	return null;
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	// for code gen, harm the restrictiveFlag
+
+	if (this.actualReceiverType != null) {
+		this.binding = scope.getField(this.actualReceiverType, this.token, this);
+	} else {
+		this.actualReceiverType = scope.enclosingSourceType();
+		this.binding = scope.getBinding(this.token, this.bits & ASTNode.RestrictiveFlagMASK, this, true /*resolve*/);
+	}
+	if (this.binding.isValidBinding()) {
+		switch (this.bits & ASTNode.RestrictiveFlagMASK) {
+			case Binding.VARIABLE : // =========only variable============
+			case Binding.VARIABLE | Binding.TYPE : //====both variable and type============
+				if (this.binding instanceof VariableBinding) {
+					VariableBinding variable = (VariableBinding) this.binding;
+					TypeBinding variableType;
+					if (this.binding instanceof LocalVariableBinding) {
+						this.bits &= ~ASTNode.RestrictiveFlagMASK;  // clear bits
+						this.bits |= Binding.LOCAL;
+						if (!variable.isFinal() && (this.bits & ASTNode.IsCapturedOuterLocal) != 0) {
+							if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) // for 8, defer till effective finality could be ascertained.
+								scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this);
+						}
+						variableType = variable.type;
+						this.constant = (this.bits & ASTNode.IsStrictlyAssigned) == 0 ? variable.constant() : Constant.NotAConstant;
+					} else {
+						// a field
+						variableType = checkFieldAccess(scope);
+					}
+					// perform capture conversion if read access
+					if (variableType != null) {
+						this.resolvedType = variableType = (((this.bits & ASTNode.IsStrictlyAssigned) == 0)
+								? variableType.capture(scope, this.sourceEnd)
+								: variableType);
+						if ((variableType.tagBits & TagBits.HasMissingType) != 0) {
+							if ((this.bits & Binding.LOCAL) == 0) {
+								// only complain if field reference (for local, its type got flagged already)
+								scope.problemReporter().invalidType(this, variableType);
+							}
+							return null;
+						}
+					}
+					return variableType;
+				}
+
+				// thus it was a type
+				this.bits &= ~ASTNode.RestrictiveFlagMASK;  // clear bits
+				this.bits |= Binding.TYPE;
+				//$FALL-THROUGH$
+			case Binding.TYPE : //========only type==============
+				this.constant = Constant.NotAConstant;
+				//deprecated test
+				TypeBinding type = (TypeBinding)this.binding;
+				if (isTypeUseDeprecated(type, scope))
+					scope.problemReporter().deprecatedType(type, this);
+				type = scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
+				return this.resolvedType = type;
+		}
+	}
+	// error scenario
+	return this.resolvedType = reportError(scope);
+}
+
+public void traverse(ASTVisitor visitor, BlockScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+
+public void traverse(ASTVisitor visitor, ClassScope scope) {
+	visitor.visit(this, scope);
+	visitor.endVisit(this, scope);
+}
+
+public String unboundReferenceErrorName(){
+	return new String(this.token);
+}
+
+public char[][] getName() {
+	return new char[][] {this.token};
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
new file mode 100644
index 0000000..cd6fb0c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class SingleTypeReference extends TypeReference {
+
+	public char[] token;
+
+	public SingleTypeReference(char[] source, long pos) {
+
+			this.token = source;
+			this.sourceStart = (int) (pos>>>32)  ;
+			this.sourceEnd = (int) (pos & 0x00000000FFFFFFFFL) ;
+
+	}
+
+	public TypeReference copyDims(int dim){
+		//return a type reference copy of me with some dimensions
+		//warning : the new type ref has a null binding
+
+		return new ArrayTypeReference(this.token, dim,(((long)this.sourceStart)<<32)+this.sourceEnd);
+	}
+	
+	public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions){
+		//return a type reference copy of me with some dimensions
+		//warning : the new type ref has a null binding
+		ArrayTypeReference arrayTypeReference = new ArrayTypeReference(this.token, dim, annotationsOnDimensions, (((long)this.sourceStart)<<32)+this.sourceEnd);
+		arrayTypeReference.bits |= (this.bits & ASTNode.HasTypeAnnotations);
+		if (annotationsOnDimensions != null) {
+			arrayTypeReference.bits |= ASTNode.HasTypeAnnotations;
+		}
+		return arrayTypeReference;
+	}
+
+	public char[] getLastToken() {
+		return this.token;
+	}
+	protected TypeBinding getTypeBinding(Scope scope) {
+		if (this.resolvedType != null)
+			return this.resolvedType;
+
+		this.resolvedType = scope.getType(this.token);
+		
+		if (this.resolvedType instanceof TypeVariableBinding) {
+			TypeVariableBinding typeVariable = (TypeVariableBinding) this.resolvedType;
+			if (typeVariable.declaringElement instanceof SourceTypeBinding) {
+				scope.tagAsAccessingEnclosingInstanceStateOf((ReferenceBinding) typeVariable.declaringElement, true /* type variable access */);
+			}
+		}
+
+		if (scope.kind == Scope.CLASS_SCOPE && this.resolvedType.isValidBinding())
+			if (((ClassScope) scope).detectHierarchyCycle(this.resolvedType, this))
+				return null;
+		return this.resolvedType;
+	}
+
+	public char [][] getTypeName() {
+		return new char[][] { this.token };
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+		if (this.annotations != null && this.annotations[0] != null) {
+			printAnnotations(this.annotations[0], output);
+			output.append(' ');
+		}
+		return output.append(this.token);
+	}
+
+	public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclosingType) {
+		TypeBinding memberType = this.resolvedType = scope.getMemberType(this.token, enclosingType);
+		boolean hasError = false;
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391500
+		resolveAnnotations(scope);
+		if (!memberType.isValidBinding()) {
+			hasError = true;
+			scope.problemReporter().invalidEnclosingType(this, memberType, enclosingType);
+			memberType = ((ReferenceBinding)memberType).closestMatch();
+			if (memberType == null) {
+				return null;
+			}
+		}
+		if (isTypeUseDeprecated(memberType, scope))
+			reportDeprecatedType(memberType, scope);
+		memberType = scope.environment().convertToRawType(memberType, false /*do not force conversion of enclosing types*/);
+		if (memberType.isRawType()
+				&& (this.bits & IgnoreRawTypeCheck) == 0
+				&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore){
+			scope.problemReporter().rawTypeReference(this, memberType);
+		}
+		if (hasError) {
+			// do not store the computed type, keep the problem type instead
+			return memberType;
+		}
+		return this.resolvedType = memberType;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++)
+					typeAnnotations[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				Annotation [] typeAnnotations = this.annotations[0];
+				for (int i = 0, length = typeAnnotations == null ? 0 : typeAnnotations.length; i < length; i++)
+					typeAnnotations[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
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
new file mode 100644
index 0000000..9cd61ce
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 335093 - [compiler][null] minimal hook for future null annotation support
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365983 - [compiler][null] AIOOB with null annotation analysis and varargs
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 370930 - NonNull annotation not considered for enhanced for loops
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public abstract class Statement extends ASTNode {
+
+	/**
+	 * Answers true if the if is identified as a known coding pattern which
+	 * should be tolerated by dead code analysis.
+	 * e.g. if (DEBUG) print(); // no complaint
+	 * Only invoked when overall condition is known to be optimizeable into false/true.
+	 */
+	protected static boolean isKnowDeadCodePattern(Expression expression) {
+		// if (!DEBUG) print(); - tolerated
+		if (expression instanceof UnaryExpression) {
+			expression = ((UnaryExpression) expression).expression;
+		}
+		// if (DEBUG) print(); - tolerated
+		if (expression instanceof Reference) return true;
+
+//		if (expression instanceof BinaryExpression) {
+//			BinaryExpression binary = (BinaryExpression) expression;
+//			switch ((binary.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT/* operator */) {
+//				case OperatorIds.AND_AND :
+//				case OperatorIds.OR_OR :
+//					break;
+//				default: 
+//					// if (DEBUG_LEVEL > 0) print(); - tolerated
+//					if ((binary.left instanceof Reference) && binary.right.constant != Constant.NotAConstant)
+//						return true;
+//					// if (0 < DEBUG_LEVEL) print(); - tolerated
+//					if ((binary.right instanceof Reference) && binary.left.constant != Constant.NotAConstant)
+//						return true;
+//			}
+//		}
+		return false;
+	}
+public abstract FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo);
+
+	public static final int NOT_COMPLAINED = 0;
+	public static final int COMPLAINED_FAKE_REACHABLE = 1;
+	public static final int COMPLAINED_UNREACHABLE = 2;
+	
+
+/** Analysing arguments of MessageSend, ExplicitConstructorCall, AllocationExpression. */
+protected void analyseArguments(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, MethodBinding methodBinding, Expression[] arguments)
+{
+	// compare actual null-status against parameter annotations of the called method:
+	if (arguments != null) {
+		CompilerOptions compilerOptions = currentScope.compilerOptions();
+		boolean considerTypeAnnotations = compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8
+				&& compilerOptions.isAnnotationBasedNullAnalysisEnabled;
+		boolean hasJDK15NullAnnotations = methodBinding.parameterNonNullness != null;
+		int numParamsToCheck = methodBinding.parameters.length;
+		if (considerTypeAnnotations || hasJDK15NullAnnotations) {
+			// check if varargs need special treatment:
+			boolean passThrough = false;
+			if (methodBinding.isVarargs()) {
+				int varArgPos = numParamsToCheck-1;
+				// this if-block essentially copied from generateArguments(..):
+				if (numParamsToCheck == arguments.length) {
+					TypeBinding varArgsType = methodBinding.parameters[varArgPos];
+					TypeBinding lastType = arguments[varArgPos].resolvedType;
+					if (lastType == TypeBinding.NULL
+							|| (varArgsType.dimensions() == lastType.dimensions()
+							&& lastType.isCompatibleWith(varArgsType)))
+						passThrough = true; // pass directly as-is
+				}
+				if (!passThrough)
+					numParamsToCheck--; // with non-passthrough varargs last param is fed from individual args -> don't check
+			}
+		}
+		if (considerTypeAnnotations) {
+			for (int i=0; i<numParamsToCheck; i++) {
+				TypeBinding expectedType = methodBinding.parameters[i];
+				Expression argument = arguments[i];
+				// prefer check based on type annotations:
+				int severity = findNullTypeAnnotationMismatch(expectedType, argument.resolvedType);
+				if (severity > 0) {
+					// immediate reporting:
+					currentScope.problemReporter().nullityMismatchingTypeAnnotation(argument, argument.resolvedType, expectedType, severity==1, currentScope.environment());
+					// next check flow-based null status against null JDK15-style annotations:
+				} else if (hasJDK15NullAnnotations && methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
+					int nullStatus = argument.nullStatus(flowInfo, flowContext); // slight loss of precision: should also use the null info from the receiver.
+					if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
+						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+				}
+			}
+		} else if (hasJDK15NullAnnotations) {
+			for (int i = 0; i < numParamsToCheck; i++) {
+				if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
+					TypeBinding expectedType = methodBinding.parameters[i];
+					Expression argument = arguments[i];
+					int nullStatus = argument.nullStatus(flowInfo, flowContext); // slight loss of precision: should also use the null info from the receiver.
+					if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
+						flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, nullStatus);
+				}
+			}
+		} 
+	}
+}
+
+/** Check null-ness of 'var' against a possible null annotation */
+protected int checkAssignmentAgainstNullAnnotation(BlockScope currentScope, FlowContext flowContext,
+												   VariableBinding var, int nullStatus, Expression expression, TypeBinding providedType)
+{
+	int severity = 0;
+	if ((var.tagBits & TagBits.AnnotationNonNull) != 0
+			&& nullStatus != FlowInfo.NON_NULL) {
+		flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, nullStatus);
+		return FlowInfo.NON_NULL;
+	} else if ((severity = findNullTypeAnnotationMismatch(var.type, providedType)) > 0) {
+		currentScope.problemReporter().nullityMismatchingTypeAnnotation(expression, providedType, var.type, severity==1, currentScope.environment());
+	} else if ((var.tagBits & TagBits.AnnotationNullable) != 0
+			&& nullStatus == FlowInfo.UNKNOWN) {	// provided a legacy type?
+		return FlowInfo.POTENTIALLY_NULL;			// -> use more specific info from the annotation
+	}
+	return nullStatus;
+}
+protected int findNullTypeAnnotationMismatch(TypeBinding requiredType, TypeBinding providedType) {
+	int severity = 0;
+	if (requiredType instanceof ArrayBinding) {
+		long[] requiredDimsTagBits = ((ArrayBinding)requiredType).nullTagBitsPerDimension;
+		if (requiredDimsTagBits != null) {
+			int dims = requiredType.dimensions();
+			if (requiredType.dimensions() == providedType.dimensions()) {
+				long[] providedDimsTagBits = ((ArrayBinding)providedType).nullTagBitsPerDimension;
+				if (providedDimsTagBits == null) {
+					severity = 1; // required is annotated, provided not, need unchecked conversion
+				} else {
+					for (int i=0; i<dims; i++) {
+						long requiredBits = requiredDimsTagBits[i] & TagBits.AnnotationNullMASK;
+						long providedBits = providedDimsTagBits[i] & TagBits.AnnotationNullMASK;
+						if (requiredBits != 0 && requiredBits != providedBits) {
+							if (providedBits == 0)
+								severity = 1; // need unchecked conversion regarding type detail
+							else
+								return 2; // mismatching annotations
+						}
+					}
+				}
+			}
+		}
+	}
+	return severity;
+}
+/**
+ * INTERNAL USE ONLY.
+ * This is used to redirect inter-statements jumps.
+ */
+public void branchChainTo(BranchLabel label) {
+	// do nothing by default
+}
+
+// Report an error if necessary (if even more unreachable than previously reported
+// complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
+public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel, boolean endOfBlock) {
+	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
+		if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+			this.bits &= ~ASTNode.IsReachable;
+		if (flowInfo == FlowInfo.DEAD_END) {
+			if (previousComplaintLevel < COMPLAINED_UNREACHABLE) {
+				scope.problemReporter().unreachableCode(this);
+				if (endOfBlock)
+					scope.checkUnclosedCloseables(flowInfo, null, null, null);
+			}
+			return COMPLAINED_UNREACHABLE;
+		} else {
+			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
+				scope.problemReporter().fakeReachable(this);
+				if (endOfBlock)
+					scope.checkUnclosedCloseables(flowInfo, null, null, null);
+			}
+			return COMPLAINED_FAKE_REACHABLE;
+		}
+	}
+	return previousComplaintLevel;
+}
+
+/**
+ * Generate invocation arguments, considering varargs methods
+ */
+public void generateArguments(MethodBinding binding, Expression[] arguments, BlockScope currentScope, CodeStream codeStream) {
+	if (binding.isVarargs()) {
+		// 5 possibilities exist for a call to the vararg method foo(int i, int ... value) :
+		//      foo(1), foo(1, null), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new int[] {1, 2})
+		TypeBinding[] params = binding.parameters;
+		int paramLength = params.length;
+		int varArgIndex = paramLength - 1;
+		for (int i = 0; i < varArgIndex; i++) {
+			arguments[i].generateCode(currentScope, codeStream, true);
+		}
+		ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
+		ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.parameters[varArgIndex].erasure();
+		int elementsTypeID = varArgsType.elementsType().id;
+		int argLength = arguments == null ? 0 : arguments.length;
+
+		if (argLength > paramLength) {
+			// right number but not directly compatible or too many arguments - wrap extra into array
+			// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
+			// need to gen elements into an array, then gen each remaining element into created array
+			codeStream.generateInlinedValue(argLength - varArgIndex);
+			codeStream.newArray(null, codeGenVarArgsType); // create a mono-dimensional array
+			for (int i = varArgIndex; i < argLength; i++) {
+				codeStream.dup();
+				codeStream.generateInlinedValue(i - varArgIndex);
+				arguments[i].generateCode(currentScope, codeStream, true);
+				codeStream.arrayAtPut(elementsTypeID, false);
+			}
+		} else if (argLength == paramLength) {
+			// right number of arguments - could be inexact - pass argument as is
+			TypeBinding lastType = arguments[varArgIndex].resolvedType;
+			if (lastType == TypeBinding.NULL
+				|| (varArgsType.dimensions() == lastType.dimensions()
+					&& lastType.isCompatibleWith(varArgsType))) {
+				// foo(1, new int[]{2, 3}) or foo(1, null) --> last arg is passed as-is
+				arguments[varArgIndex].generateCode(currentScope, codeStream, true);
+			} else {
+				// right number but not directly compatible or too many arguments - wrap extra into array
+				// need to gen elements into an array, then gen each remaining element into created array
+				codeStream.generateInlinedValue(1);
+				codeStream.newArray(null, codeGenVarArgsType); // create a mono-dimensional array
+				codeStream.dup();
+				codeStream.generateInlinedValue(0);
+				arguments[varArgIndex].generateCode(currentScope, codeStream, true);
+				codeStream.arrayAtPut(elementsTypeID, false);
+			}
+		} else { // not enough arguments - pass extra empty array
+			// scenario: foo(1) --> foo(1, new int[0])
+			// generate code for an empty array of parameterType
+			codeStream.generateInlinedValue(0);
+			codeStream.newArray(null, codeGenVarArgsType); // create a mono-dimensional array
+		}
+	} else if (arguments != null) { // standard generation for method arguments
+		for (int i = 0, max = arguments.length; i < max; i++)
+			arguments[i].generateCode(currentScope, codeStream, true);
+	}
+}
+
+public abstract void generateCode(BlockScope currentScope, CodeStream codeStream);
+
+protected boolean isBoxingCompatible(TypeBinding expressionType, TypeBinding targetType, Expression expression, Scope scope) {
+	if (scope.isBoxingCompatibleWith(expressionType, targetType))
+		return true;
+
+	return expressionType.isBaseType()  // narrowing then boxing ? Only allowed for some target types see 362279
+		&& !targetType.isBaseType()
+		&& !targetType.isTypeVariable()
+		&& scope.compilerOptions().sourceLevel >= org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5 // autoboxing
+		&& (targetType.id == TypeIds.T_JavaLangByte || targetType.id == TypeIds.T_JavaLangShort || targetType.id == TypeIds.T_JavaLangCharacter)
+		&& expression.isConstantValueOfTypeAssignableToType(expressionType, scope.environment().computeBoxingType(targetType));
+}
+
+public boolean isEmptyBlock() {
+	return false;
+}
+
+public boolean isValidJavaStatement() {
+	//the use of this method should be avoid in most cases
+	//and is here mostly for documentation purpose.....
+	//while the parser is responsible for creating
+	//welled formed expression statement, which results
+	//in the fact that java-non-semantic-expression-used-as-statement
+	//should not be parsed...thus not being built.
+	//It sounds like the java grammar as help the compiler job in removing
+	//-by construction- some statement that would have no effect....
+	//(for example all expression that may do side-effects are valid statement
+	// -this is an approximative idea.....-)
+
+	return true;
+}
+
+public StringBuffer print(int indent, StringBuffer output) {
+	return printStatement(indent, output);
+}
+
+public abstract StringBuffer printStatement(int indent, StringBuffer output);
+
+public abstract void resolve(BlockScope scope);
+
+/**
+ * Returns case constant associated to this statement (NotAConstant if none)
+ */
+public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
+	// statement within a switch that are not case are treated as normal statement....
+	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/StringLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
new file mode 100644
index 0000000..211cf17
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.StringConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class StringLiteral extends Literal {
+
+	char[] source;
+	int lineNumber;
+
+	public StringLiteral(char[] token, int start, int end, int lineNumber) {
+
+		this(start,end);
+		this.source = token;
+		this.lineNumber = lineNumber - 1; // line number is 1 based
+	}
+
+	public StringLiteral(int s, int e) {
+
+		super(s,e);
+	}
+
+	public void computeConstant() {
+
+		this.constant = StringConstant.fromValue(String.valueOf(this.source));
+	}
+
+	public ExtendedStringLiteral extendWith(CharLiteral lit){
+
+		//add the lit source to mine, just as if it was mine
+		return new ExtendedStringLiteral(this,lit);
+	}
+
+	public ExtendedStringLiteral extendWith(StringLiteral lit){
+
+		//add the lit source to mine, just as if it was mine
+		return new ExtendedStringLiteral(this,lit);
+	}
+
+	/**
+	 *  Add the lit source to mine, just as if it was mine
+	 */
+	public StringLiteralConcatenation extendsWith(StringLiteral lit) {
+		return new StringLiteralConcatenation(this, lit);
+	}
+	/**
+	 * Code generation for string literal
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		int pc = codeStream.position;
+		if (valueRequired)
+			codeStream.ldc(this.constant.stringValue());
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public TypeBinding literalType(BlockScope scope) {
+
+		return scope.getJavaLangString();
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+
+		// handle some special char.....
+		output.append('\"');
+		for (int i = 0; i < this.source.length; i++) {
+			switch (this.source[i]) {
+				case '\b' :
+					output.append("\\b"); //$NON-NLS-1$
+					break;
+				case '\t' :
+					output.append("\\t"); //$NON-NLS-1$
+					break;
+				case '\n' :
+					output.append("\\n"); //$NON-NLS-1$
+					break;
+				case '\f' :
+					output.append("\\f"); //$NON-NLS-1$
+					break;
+				case '\r' :
+					output.append("\\r"); //$NON-NLS-1$
+					break;
+				case '\"' :
+					output.append("\\\""); //$NON-NLS-1$
+					break;
+				case '\'' :
+					output.append("\\'"); //$NON-NLS-1$
+					break;
+				case '\\' : //take care not to display the escape as a potential real char
+					output.append("\\\\"); //$NON-NLS-1$
+					break;
+				default :
+					output.append(this.source[i]);
+			}
+		}
+		output.append('\"');
+		return output;
+	}
+
+	public char[] source() {
+
+		return this.source;
+	}
+
+	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/StringLiteralConcatenation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java
new file mode 100644
index 0000000..4f393f0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+/**
+ * Flatten string literal
+ */
+public class StringLiteralConcatenation extends StringLiteral {
+	private static final int INITIAL_SIZE = 5;
+	public Expression[] literals;
+	public int counter;
+	/**
+	 * Build a two-strings literal
+	 * */
+	public StringLiteralConcatenation(StringLiteral str1, StringLiteral str2) {
+		super(str1.sourceStart, str1.sourceEnd);
+		this.source = str1.source;
+		this.literals = new StringLiteral[INITIAL_SIZE];
+		this.counter = 0;
+		this.literals[this.counter++] = str1;
+		extendsWith(str2);
+	}
+
+	/**
+	 *  Add the lit source to mine, just as if it was mine
+	 */
+	public StringLiteralConcatenation extendsWith(StringLiteral lit) {
+		this.sourceEnd = lit.sourceEnd;
+		final int literalsLength = this.literals.length;
+		if (this.counter == literalsLength) {
+			// resize
+			System.arraycopy(this.literals, 0, this.literals = new StringLiteral[literalsLength + INITIAL_SIZE], 0, literalsLength);
+		}
+		//uddate the source
+		int length = this.source.length;
+		System.arraycopy(
+			this.source,
+			0,
+			this.source = new char[length + lit.source.length],
+			0,
+			length);
+		System.arraycopy(lit.source, 0, this.source, length, lit.source.length);
+		this.literals[this.counter++] = lit;
+		return this;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append("StringLiteralConcatenation{"); //$NON-NLS-1$
+		for (int i = 0, max = this.counter; i < max; i++) {
+			this.literals[i].printExpression(indent, output);
+			output.append("+\n");//$NON-NLS-1$
+		}
+		return output.append('}');
+	}
+
+	public char[] source() {
+		return this.source;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			for (int i = 0, max = this.counter; i < max; i++) {
+				this.literals[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java
new file mode 100644
index 0000000..1d98294
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+
+/**
+ * Extra behavior for statements which are generating subroutines
+ */
+public abstract class SubRoutineStatement extends Statement {
+
+	public static void reenterAllExceptionHandlers(SubRoutineStatement[] subroutines, int max, CodeStream codeStream) {
+		if (subroutines == null) return;
+		if (max < 0) max = subroutines.length;
+		for (int i = 0; i < max; i++) {
+			SubRoutineStatement sub = subroutines[i];
+			sub.enterAnyExceptionHandler(codeStream);
+			sub.enterDeclaredExceptionHandlers(codeStream);
+		}
+	}
+
+	ExceptionLabel anyExceptionLabel;
+
+	public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) {
+
+		if (this.anyExceptionLabel == null) {
+			this.anyExceptionLabel = new ExceptionLabel(codeStream, null /*any exception*/);
+		}
+		this.anyExceptionLabel.placeStart();
+		return this.anyExceptionLabel;
+	}
+
+	public void enterDeclaredExceptionHandlers(CodeStream codeStream) {
+		// do nothing by default
+	}
+
+	public void exitAnyExceptionHandler() {
+		if (this.anyExceptionLabel != null) {
+			this.anyExceptionLabel.placeEnd();
+		}
+	}
+
+	public void exitDeclaredExceptionHandlers(CodeStream codeStream) {
+		// do nothing by default
+	}
+
+
+	/**
+	 * Generate an invocation of a subroutine (e.g. jsr finally) in current context.
+	 * @param currentScope
+	 * @param codeStream
+	 * @param targetLocation
+	 * @param stateIndex
+	 * @param secretLocal
+	 * @return boolean, <code>true</code> if the generated code will abrupt completion
+	 */
+	public abstract boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal);
+
+	public abstract boolean isSubRoutineEscaping();
+
+	public void placeAllAnyExceptionHandler() {
+		this.anyExceptionLabel.place();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
new file mode 100644
index 0000000..a7069ef
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class SuperReference extends ThisReference {
+
+	public SuperReference(int sourceStart, int sourceEnd) {
+
+		super(sourceStart, sourceEnd);
+	}
+
+	public static ExplicitConstructorCall implicitSuperConstructorCall() {
+
+		return new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
+	}
+
+	public boolean isImplicitThis() {
+
+		return false;
+	}
+
+	public boolean isSuper() {
+
+		return true;
+	}
+
+	public boolean isThis() {
+
+		return false ;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		return output.append("super"); //$NON-NLS-1$
+
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		this.constant = Constant.NotAConstant;
+		ReferenceBinding enclosingReceiverType = scope.enclosingReceiverType();
+		if (!checkAccess(scope, enclosingReceiverType))
+			return null;
+		if (enclosingReceiverType.id == T_JavaLangObject) {
+			scope.problemReporter().cannotUseSuperInJavaLangObject(this);
+			return null;
+		}
+		return this.resolvedType = enclosingReceiverType.superclass();
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+		visitor.visit(this, blockScope);
+		visitor.endVisit(this, blockScope);
+	}
+}
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
new file mode 100644
index 0000000..7a71bd1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -0,0 +1,633 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for 
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 265744 - Enum switch should warn about missing default
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.Arrays;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public class SwitchStatement extends Statement {
+
+	public Expression expression;
+	public Statement[] statements;
+	public BlockScope scope;
+	public int explicitDeclarations;
+	public BranchLabel breakLabel;
+	public CaseStatement[] cases;
+	public CaseStatement defaultCase;
+	public int blockStart;
+	public int caseCount;
+	int[] constants;
+	String[] stringConstants;
+
+	// fallthrough
+	public final static int CASE = 0;
+	public final static int FALLTHROUGH = 1;
+	public final static int ESCAPING = 2;
+	
+	// for switch on strings
+	private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$
+
+
+	public SyntheticMethodBinding synthetic; // use for switch on enums types
+
+	// for local variables table attributes
+	int preSwitchInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+	
+	CaseStatement[] duplicateCaseStatements = null;
+	int duplicateCaseStatementsCounter = 0;
+	private LocalVariableBinding dispatchStringCopy = null;
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		try {
+			flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
+			if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0
+					|| (this.expression.resolvedType != null && this.expression.resolvedType.id == T_JavaLangString)) {
+				this.expression.checkNPE(currentScope, flowContext, flowInfo);
+			}
+			SwitchFlowContext switchContext =
+				new SwitchFlowContext(flowContext, this, (this.breakLabel = new BranchLabel()), true);
+
+			// analyse the block by considering specially the case/default statements (need to bind them
+			// to the entry point)
+			FlowInfo caseInits = FlowInfo.DEAD_END;
+			// in case of statements before the first case
+			this.preSwitchInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+			int caseIndex = 0;
+			if (this.statements != null) {
+				int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+				int complaintLevel = initialComplaintLevel;
+				int fallThroughState = CASE;
+				for (int i = 0, max = this.statements.length; i < max; i++) {
+					Statement statement = this.statements[i];
+					if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statement is a case
+						this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
+						caseIndex++;
+						if (fallThroughState == FALLTHROUGH
+								&& (statement.bits & ASTNode.DocumentedFallthrough) == 0) { // the case is not fall-through protected by a line comment
+							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
+						}
+						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
+						complaintLevel = initialComplaintLevel; // reset complaint
+						fallThroughState = CASE;
+					} else if (statement == this.defaultCase) { // statement is the default case
+						this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
+						if (fallThroughState == FALLTHROUGH
+								&& (statement.bits & ASTNode.DocumentedFallthrough) == 0) {
+							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
+						}
+						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
+						complaintLevel = initialComplaintLevel; // reset complaint
+						fallThroughState = CASE;
+					} else {
+						fallThroughState = FALLTHROUGH; // reset below if needed
+					}
+					if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
+						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
+						if (caseInits == FlowInfo.DEAD_END) {
+							fallThroughState = ESCAPING;
+						}
+					}
+				}
+			}
+
+			final TypeBinding resolvedTypeBinding = this.expression.resolvedType;
+			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
+			if (this.defaultCase == null) {
+				// only retain the potential initializations
+				flowInfo.addPotentialInitializationsFrom(caseInits.mergedWith(switchContext.initsOnBreak));
+				this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+				return flowInfo;
+			}
+
+			// merge all branches inits
+			FlowInfo mergedInfo = caseInits.mergedWith(switchContext.initsOnBreak);
+			this.mergedInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(mergedInfo);
+			return mergedInfo;
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+
+	/**
+	 * Switch on String code generation
+	 * This assumes that hashCode() specification for java.lang.String is API
+	 * and is stable.
+	 *
+	 * @see "http://download.oracle.com/javase/6/docs/api/java/lang/String.html"
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCodeForStringSwitch(BlockScope currentScope, CodeStream codeStream) {
+
+		try {
+			if ((this.bits & IsReachable) == 0) {
+				return;
+			}
+			int pc = codeStream.position;
+			
+			class StringSwitchCase implements Comparable {
+				int hashCode;
+				String string;
+				BranchLabel label;
+				public StringSwitchCase(int hashCode, String string, BranchLabel label) {
+					this.hashCode = hashCode;
+					this.string = string;
+					this.label = label;
+				}
+				public int compareTo(Object o) {
+					StringSwitchCase that = (StringSwitchCase) o;
+					if (this.hashCode == that.hashCode) {
+						return 0;
+					}
+					if (this.hashCode > that.hashCode) {
+						return 1;
+					}
+					return -1;
+				}
+				public String toString() {
+					return "StringSwitchCase :\n" + //$NON-NLS-1$
+					       "case " + this.hashCode + ":(" + this.string + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$	       
+				}
+			}
+
+			final boolean hasCases = this.caseCount != 0;
+
+			StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code.
+			BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount];
+			CaseLabel [] hashCodeCaseLabels = new CaseLabel[this.caseCount];
+			this.constants = new int[this.caseCount];  // hashCode() values.
+			for (int i = 0, max = this.caseCount; i < max; i++) {
+				this.cases[i].targetLabel = (sourceCaseLabels[i] = new BranchLabel(codeStream));  // A branch label, not a case label.
+				sourceCaseLabels[i].tagBits |= BranchLabel.USED;
+				stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[i]);
+				hashCodeCaseLabels[i] = new CaseLabel(codeStream);
+				hashCodeCaseLabels[i].tagBits |= BranchLabel.USED;
+				
+			}
+			Arrays.sort(stringCases);
+
+			int uniqHashCount = 0;
+			int lastHashCode = 0; 
+			for (int i = 0, length = this.caseCount; i < length; ++i) {
+				int hashCode = stringCases[i].hashCode;
+				if (i == 0 || hashCode != lastHashCode) {
+					lastHashCode = this.constants[uniqHashCount++] = hashCode;
+				}
+			}
+				
+			if (uniqHashCount != this.caseCount) { // multiple keys hashed to the same value.
+				System.arraycopy(this.constants, 0, this.constants = new int[uniqHashCount], 0, uniqHashCount);
+				System.arraycopy(hashCodeCaseLabels, 0, hashCodeCaseLabels = new CaseLabel[uniqHashCount], 0, uniqHashCount);
+			}
+			int[] sortedIndexes = new int[uniqHashCount]; // hash code are sorted already anyways.
+			for (int i = 0; i < uniqHashCount; i++) {
+				sortedIndexes[i] = i;
+			}
+
+			CaseLabel defaultCaseLabel = new CaseLabel(codeStream);
+			defaultCaseLabel.tagBits |= BranchLabel.USED;
+
+			// prepare the labels and constants
+			this.breakLabel.initialize(codeStream);
+			
+			BranchLabel defaultBranchLabel = new BranchLabel(codeStream);
+			if (hasCases) defaultBranchLabel.tagBits |= BranchLabel.USED;
+			if (this.defaultCase != null) {
+				this.defaultCase.targetLabel = defaultBranchLabel;
+			}
+			// generate expression
+			this.expression.generateCode(currentScope, codeStream, true);
+			codeStream.store(this.dispatchStringCopy, true);  // leaves string on operand stack
+			codeStream.addVariable(this.dispatchStringCopy);
+			codeStream.invokeStringHashCode();
+			if (hasCases) {
+				codeStream.lookupswitch(defaultCaseLabel, this.constants, sortedIndexes, hashCodeCaseLabels);
+				for (int i = 0, j = 0, max = this.caseCount; i < max; i++) {
+					int hashCode = stringCases[i].hashCode;
+					if (i == 0 || hashCode != lastHashCode) {
+						lastHashCode = hashCode;
+						if (i != 0) {
+							codeStream.goto_(defaultBranchLabel);
+						}
+						hashCodeCaseLabels[j++].place();
+					}
+					codeStream.load(this.dispatchStringCopy);
+					codeStream.ldc(stringCases[i].string);
+					codeStream.invokeStringEquals();
+					codeStream.ifne(stringCases[i].label);
+				}
+				codeStream.goto_(defaultBranchLabel);
+			} else {
+				codeStream.pop();
+			}
+
+			// generate the switch block statements
+			int caseIndex = 0;
+			if (this.statements != null) {
+				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
+					Statement statement = this.statements[i];
+					if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case
+						this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
+						if (this.preSwitchInitStateIndex != -1) {
+							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+						}
+						caseIndex++;
+					} else {
+						if (statement == this.defaultCase) { // statements[i] is a case or a default case
+							defaultCaseLabel.place(); // branch label gets placed by generateCode below.
+							this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
+							if (this.preSwitchInitStateIndex != -1) {
+								codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+							}
+						}
+					}
+					statement.generateCode(this.scope, codeStream);
+				}
+			}
+			
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.removeVariable(this.dispatchStringCopy);
+			if (this.scope != currentScope) {
+				codeStream.exitUserScope(this.scope);
+			}
+			// place the trailing labels (for break and default case)
+			this.breakLabel.place();
+			if (this.defaultCase == null) {
+				// we want to force an line number entry to get an end position after the switch statement
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true);
+				defaultCaseLabel.place();
+				defaultBranchLabel.place();
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+		finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+
+	
+	/**
+	 * Switch code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+		if (this.expression.resolvedType.id == TypeIds.T_JavaLangString) {
+			generateCodeForStringSwitch(currentScope, codeStream);
+			return;
+		}
+		try {
+			if ((this.bits & IsReachable) == 0) {
+				return;
+			}
+			int pc = codeStream.position;
+
+			// prepare the labels and constants
+			this.breakLabel.initialize(codeStream);
+			CaseLabel[] caseLabels = new CaseLabel[this.caseCount];
+			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);
+			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()) {
+				// 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, valueRequired);
+			}
+			// generate the appropriate switch table/lookup bytecode
+			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++) {
+					sortedIndexes[i] = i;
+				}
+				int[] localKeysCopy;
+				System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount);
+				CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes);
+
+				int max = localKeysCopy[this.caseCount - 1];
+				int min = localKeysCopy[0];
+				if ((long) (this.caseCount * 2.5) > ((long) max - (long) min)) {
+
+					// work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode
+					// see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557
+					if (max > 0x7FFF0000 && currentScope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
+						codeStream.lookupswitch(defaultLabel, this.constants, sortedIndexes, caseLabels);
+
+					} else {
+						codeStream.tableswitch(
+							defaultLabel,
+							min,
+							max,
+							this.constants,
+							sortedIndexes,
+							caseLabels);
+					}
+				} else {
+					codeStream.lookupswitch(defaultLabel, this.constants, sortedIndexes, caseLabels);
+				}
+				codeStream.recordPositionsFrom(codeStream.position, this.expression.sourceEnd);
+			} else if (valueRequired) {
+				codeStream.pop();
+			}
+
+			// generate the switch block statements
+			int caseIndex = 0;
+			if (this.statements != null) {
+				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
+					Statement statement = this.statements[i];
+					if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case
+						this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
+						if (this.preSwitchInitStateIndex != -1) {
+							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+						}
+						caseIndex++;
+					} else {
+						if (statement == this.defaultCase) { // statements[i] is a case or a default case
+							this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
+							if (this.preSwitchInitStateIndex != -1) {
+								codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+							}
+						}
+					}
+					statement.generateCode(this.scope, codeStream);
+				}
+			}
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			if (this.scope != currentScope) {
+				codeStream.exitUserScope(this.scope);
+			}
+			// place the trailing labels (for break and default case)
+			this.breakLabel.place();
+			if (this.defaultCase == null) {
+				// we want to force an line number entry to get an end position after the switch statement
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true);
+				defaultLabel.place();
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+
+		printIndent(indent, output).append("switch ("); //$NON-NLS-1$
+		this.expression.printExpression(0, output).append(") {"); //$NON-NLS-1$
+		if (this.statements != null) {
+			for (int i = 0; i < this.statements.length; i++) {
+				output.append('\n');
+				if (this.statements[i] instanceof CaseStatement) {
+					this.statements[i].printStatement(indent, output);
+				} else {
+					this.statements[i].printStatement(indent+2, output);
+				}
+			}
+		}
+		output.append("\n"); //$NON-NLS-1$
+		return printIndent(indent, output).append('}');
+	}
+
+	public void resolve(BlockScope upperScope) {
+		try {
+			boolean isEnumSwitch = false;
+			boolean isStringSwitch = false;
+			TypeBinding expressionType = this.expression.resolveType(upperScope);
+			CompilerOptions compilerOptions = upperScope.compilerOptions();
+			if (expressionType != null) {
+				this.expression.computeConversion(upperScope, expressionType, expressionType);
+				checkType: {
+					if (!expressionType.isValidBinding()) {
+						expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon
+						break checkType;
+					} else if (expressionType.isBaseType()) {
+						if (this.expression.isConstantValueOfTypeAssignableToType(expressionType, TypeBinding.INT))
+							break checkType;
+						if (expressionType.isCompatibleWith(TypeBinding.INT))
+							break checkType;
+					} else if (expressionType.isEnum()) {
+						isEnumSwitch = true;
+						if (compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) {
+							upperScope.problemReporter().incorrectSwitchType(this.expression, expressionType); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360317
+						}
+						break checkType;
+					} else if (upperScope.isBoxingCompatibleWith(expressionType, TypeBinding.INT)) {
+						this.expression.computeConversion(upperScope, TypeBinding.INT, expressionType);
+						break checkType;
+					} else if (compilerOptions.complianceLevel >= ClassFileConstants.JDK1_7 && expressionType.id == TypeIds.T_JavaLangString) {
+						isStringSwitch = true;
+						break checkType;
+					}
+					upperScope.problemReporter().incorrectSwitchType(this.expression, expressionType);
+					expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon
+				}
+			}
+			if (isStringSwitch) {
+				// the secret variable should be created before iterating over the switch's statements that could
+				// create more locals. This must be done to prevent overlapping of locals
+				// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=356002
+				this.dispatchStringCopy  = new LocalVariableBinding(SecretStringVariableName, upperScope.getJavaLangString(), ClassFileConstants.AccDefault, false);
+				upperScope.addLocalVariable(this.dispatchStringCopy);
+				this.dispatchStringCopy.setConstant(Constant.NotAConstant);
+				this.dispatchStringCopy.useFlag = LocalVariableBinding.USED;
+			}
+			if (this.statements != null) {
+				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];
+				if (!isStringSwitch) {
+					this.constants = new int[length];
+				} else {
+					this.stringConstants = new String[length];
+				}
+				int counter = 0;
+				for (int i = 0; i < length; i++) {
+					Constant constant;
+					final Statement statement = this.statements[i];
+					if ((constant = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) {
+						if (!isStringSwitch) {
+							int key = constant.intValue();
+							//----check for duplicate case statement------------
+							for (int j = 0; j < counter; j++) {
+								if (this.constants[j] == key) {
+									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+								}
+							}
+							this.constants[counter++] = key;
+						} else {
+							String key = constant.stringValue();
+							//----check for duplicate case statement------------
+							for (int j = 0; j < counter; j++) {
+								if (this.stringConstants[j].equals(key)) {
+									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+								}
+							}
+							this.stringConstants[counter++] = key;			
+						}
+					}
+				}
+				if (length != counter) { // resize constants array
+					if (!isStringSwitch) {
+						System.arraycopy(this.constants, 0, this.constants = new int[counter], 0, counter);
+					} else {
+						System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter], 0, counter);
+					}
+				}
+			} else {
+				if ((this.bits & UndocumentedEmptyBlock) != 0) {
+					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
+				}
+			}
+			// check default case for all kinds of switch:
+			if (this.defaultCase == null) {
+				if (compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore) {
+					if (isEnumSwitch) {
+						upperScope.methodScope().hasMissingSwitchDefault = true;
+					}
+				} else {
+					upperScope.problemReporter().missingDefaultCase(this, isEnumSwitch, expressionType);
+				}
+			}
+			// for enum switch, check if all constants are accounted for (perhaps depending on existence of a default case)
+			if (isEnumSwitch && compilerOptions.complianceLevel >= ClassFileConstants.JDK1_5) {
+				if (this.defaultCase == null || compilerOptions.reportMissingEnumCaseDespiteDefault) {
+					int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement
+					if (constantCount == this.caseCount
+							&& this.caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) {
+						FieldBinding[] enumFields = ((ReferenceBinding)expressionType.erasure()).fields();
+						for (int i = 0, max = enumFields.length; i <max; i++) {
+							FieldBinding enumConstant = enumFields[i];
+							if ((enumConstant.modifiers & ClassFileConstants.AccEnum) == 0) continue;
+							findConstant : {
+								for (int j = 0; j < this.caseCount; j++) {
+									if ((enumConstant.id + 1) == this.constants[j]) // zero should not be returned see bug 141810
+										break findConstant;
+								}
+								// enum constant did not get referenced from switch
+								boolean suppress = (this.defaultCase != null && (this.defaultCase.bits & DocumentedCasesOmitted) != 0);
+								if (!suppress) {
+									upperScope.problemReporter().missingEnumConstantCase(this, enumConstant);
+								}
+							}
+						}
+					}
+				}
+			}
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+
+	private void reportDuplicateCase(final CaseStatement duplicate, final CaseStatement original, int length) {
+		if (this.duplicateCaseStatements == null) {
+			this.scope.problemReporter().duplicateCase(original);
+			this.scope.problemReporter().duplicateCase(duplicate);
+			this.duplicateCaseStatements = new CaseStatement[length];
+			this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = original;
+			this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = duplicate;
+		} else {
+			boolean found = false;
+			searchReportedDuplicate: for (int k = 2; k < this.duplicateCaseStatementsCounter; k++) {
+				if (this.duplicateCaseStatements[k] == duplicate) {
+					found = true;
+					break searchReportedDuplicate;
+				}
+			}
+			if (!found) {
+				this.scope.problemReporter().duplicateCase(duplicate);
+				this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = duplicate;
+			}
+		}
+	}
+
+	public void traverse(
+			ASTVisitor visitor,
+			BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.expression.traverse(visitor, blockScope);
+			if (this.statements != null) {
+				int statementsLength = this.statements.length;
+				for (int i = 0; i < statementsLength; i++)
+					this.statements[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+
+	/**
+	 * Dispatch the call on its last statement.
+	 */
+	public void branchChainTo(BranchLabel label) {
+
+		// in order to improve debug attributes for stepping (11431)
+		// we want to inline the jumps to #breakLabel which already got
+		// generated (if any), and have them directly branch to a better
+		// location (the argument label).
+		// we know at this point that the breakLabel already got placed
+		if (this.breakLabel.forwardReferenceCount() > 0) {
+			label.becomeDelegateFor(this.breakLabel);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
new file mode 100644
index 0000000..b2c6dfd
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class SynchronizedStatement extends SubRoutineStatement {
+
+	public Expression expression;
+	public Block block;
+	public BlockScope scope;
+	public LocalVariableBinding synchroVariable;
+	static final char[] SecretLocalDeclarationName = " syncValue".toCharArray(); //$NON-NLS-1$
+
+	// for local variables table attributes
+	int preSynchronizedInitStateIndex = -1;
+	int mergedSynchronizedInitStateIndex = -1;
+
+public SynchronizedStatement(
+	Expression expression,
+	Block statement,
+	int s,
+	int e) {
+
+	this.expression = expression;
+	this.block = statement;
+	this.sourceEnd = e;
+	this.sourceStart = s;
+}
+
+public FlowInfo analyseCode(
+	BlockScope currentScope,
+	FlowContext flowContext,
+	FlowInfo flowInfo) {
+
+	this.preSynchronizedInitStateIndex =
+		currentScope.methodScope().recordInitializationStates(flowInfo);
+    // TODO (philippe) shouldn't it be protected by a check whether reachable statement ?
+
+	// mark the synthetic variable as being used
+	this.synchroVariable.useFlag = LocalVariableBinding.USED;
+
+	// simple propagation to subnodes
+	flowInfo =
+		this.block.analyseCode(
+			this.scope,
+			new InsideSubRoutineFlowContext(flowContext, this),
+			this.expression.analyseCode(this.scope, flowContext, flowInfo));
+
+	this.mergedSynchronizedInitStateIndex =
+		currentScope.methodScope().recordInitializationStates(flowInfo);
+
+	// optimizing code gen
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
+		this.bits |= ASTNode.BlockExit;
+	}
+
+	return flowInfo;
+}
+
+public boolean isSubRoutineEscaping() {
+	return false;
+}
+
+/**
+ * Synchronized statement code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & IsReachable) == 0) {
+		return;
+	}
+	// in case the labels needs to be reinitialized
+	// when the code generation is restarted in wide mode
+	this.anyExceptionLabel = null;
+
+	int pc = codeStream.position;
+
+	// generate the synchronization expression
+	this.expression.generateCode(this.scope, codeStream, true);
+	if (this.block.isEmptyBlock()) {
+		switch(this.synchroVariable.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2();
+				break;
+			default :
+				codeStream.dup();
+				break;
+		}		
+		// only take the lock
+		codeStream.monitorenter();
+		codeStream.monitorexit();
+		if (this.scope != currentScope) {
+			codeStream.exitUserScope(this.scope);
+		}
+	} else {
+		// enter the monitor
+		codeStream.store(this.synchroVariable, true);
+		codeStream.addVariable(this.synchroVariable);
+		codeStream.monitorenter();
+
+		// generate  the body of the synchronized block
+		enterAnyExceptionHandler(codeStream);
+		this.block.generateCode(this.scope, codeStream);
+		if (this.scope != currentScope) {
+			// close all locals defined in the synchronized block except the secret local
+			codeStream.exitUserScope(this.scope, this.synchroVariable);
+		}
+
+		BranchLabel endLabel = new BranchLabel(codeStream);
+		if ((this.bits & ASTNode.BlockExit) == 0) {
+			codeStream.load(this.synchroVariable);
+			codeStream.monitorexit();
+			exitAnyExceptionHandler();
+			codeStream.goto_(endLabel);
+			enterAnyExceptionHandler(codeStream);
+		}
+		// generate the body of the exception handler
+		codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
+		if (this.preSynchronizedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSynchronizedInitStateIndex);
+		}
+		placeAllAnyExceptionHandler();
+		codeStream.load(this.synchroVariable);
+		codeStream.monitorexit();
+		exitAnyExceptionHandler();
+		codeStream.athrow();
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.mergedSynchronizedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedSynchronizedInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedSynchronizedInitStateIndex);
+		}
+		if (this.scope != currentScope) {
+			codeStream.removeVariable(this.synchroVariable);
+		}
+		if ((this.bits & ASTNode.BlockExit) == 0) {
+			endLabel.place();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * @see SubRoutineStatement#generateSubRoutineInvocation(BlockScope, CodeStream, Object, int, LocalVariableBinding)
+ */
+public boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal) {
+	codeStream.load(this.synchroVariable);
+	codeStream.monitorexit();
+	exitAnyExceptionHandler();
+	return false;
+}
+
+public void resolve(BlockScope upperScope) {
+	// special scope for secret locals optimization.
+	this.scope = new BlockScope(upperScope);
+	TypeBinding type = this.expression.resolveType(this.scope);
+	if (type == null)
+		return;
+	switch (type.id) {
+		case T_boolean :
+		case T_char :
+		case T_float :
+		case T_double :
+		case T_byte :
+		case T_short :
+		case T_int :
+		case T_long :
+			this.scope.problemReporter().invalidTypeToSynchronize(this.expression, type);
+			break;
+		case T_void :
+			this.scope.problemReporter().illegalVoidExpression(this.expression);
+			break;
+		case T_null :
+			this.scope.problemReporter().invalidNullToSynchronize(this.expression);
+			break;
+	}
+	//continue even on errors in order to have the TC done into the statements
+	this.synchroVariable = new LocalVariableBinding(SecretLocalDeclarationName, type, ClassFileConstants.AccDefault, false);
+	this.scope.addLocalVariable(this.synchroVariable);
+	this.synchroVariable.setConstant(Constant.NotAConstant); // not inlinable
+	this.expression.computeConversion(this.scope, type, type);
+	this.block.resolveUsing(this.scope);
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	printIndent(indent, output);
+	output.append("synchronized ("); //$NON-NLS-1$
+	this.expression.printExpression(0, output).append(')');
+	output.append('\n');
+	return this.block.printStatement(indent + 1, output);
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		this.expression.traverse(visitor, this.scope);
+		this.block.traverse(visitor, this.scope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java
new file mode 100644
index 0000000..31cad42
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class ThisReference extends Reference {
+
+	public static ThisReference implicitThis(){
+
+		ThisReference implicitThis = new ThisReference(0, 0);
+		implicitThis.bits |= IsImplicitThis;
+		return implicitThis;
+	}
+
+	public ThisReference(int sourceStart, int sourceEnd) {
+
+		this.sourceStart = sourceStart;
+		this.sourceEnd = sourceEnd;
+	}
+
+	/*
+	 * @see Reference#analyseAssignment(...)
+	 */
+	public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
+
+		return flowInfo; // this cannot be assigned
+	}
+
+	public boolean checkAccess(BlockScope scope, ReferenceBinding receiverType) {
+
+		MethodScope methodScope = scope.methodScope();
+		// this/super cannot be used in constructor call
+		if (methodScope.isConstructorCall) {
+			methodScope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this);
+			return false;
+		}
+
+		// static may not refer to this/super
+		if (methodScope.isStatic) {
+			methodScope.problemReporter().errorThisSuperInStatic(this);
+			return false;
+		}
+		if (receiverType != null)
+			scope.tagAsAccessingEnclosingInstanceStateOf(receiverType, false /* type variable access */);
+		return true;
+	}
+
+	public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
+		return true; // never problematic
+	}
+
+	/*
+	 * @see Reference#generateAssignment(...)
+	 */
+	public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+
+		 // this cannot be assigned
+	}
+
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+
+		int pc = codeStream.position;
+		if (valueRequired)
+			codeStream.aload_0();
+		if ((this.bits & IsImplicitThis) == 0) codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	/*
+	 * @see Reference#generateCompoundAssignment(...)
+	 */
+	public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion,  boolean valueRequired) {
+
+		 // this cannot be assigned
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.compiler.ast.Reference#generatePostIncrement()
+	 */
+	public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+
+		 // this cannot be assigned
+	}
+
+	public boolean isImplicitThis() {
+
+		return (this.bits & IsImplicitThis) != 0;
+	}
+
+	public boolean isThis() {
+
+		return true ;
+	}
+
+	public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		return FlowInfo.NON_NULL;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		if (isImplicitThis()) return output;
+		return output.append("this"); //$NON-NLS-1$
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+
+		this.constant = Constant.NotAConstant;
+		
+		ReferenceBinding enclosingReceiverType = scope.enclosingReceiverType();
+		if (!isImplicitThis() &&!checkAccess(scope, enclosingReceiverType)) {
+			return null;
+		}
+		return this.resolvedType = enclosingReceiverType;
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+
+		visitor.visit(this, blockScope);
+		visitor.endVisit(this, blockScope);
+	}
+	public void traverse(ASTVisitor visitor, ClassScope blockScope) {
+
+		visitor.visit(this, blockScope);
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
new file mode 100644
index 0000000..02cf189
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class ThrowStatement extends Statement {
+
+	public Expression exception;
+	public TypeBinding exceptionType;
+
+public ThrowStatement(Expression exception, int sourceStart, int sourceEnd) {
+	this.exception = exception;
+	this.sourceStart = sourceStart;
+	this.sourceEnd = sourceEnd;
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	this.exception.analyseCode(currentScope, flowContext, flowInfo);
+	this.exception.checkNPE(currentScope, flowContext, flowInfo);
+	// need to check that exception thrown is actually caught somewhere
+	flowContext.checkExceptionHandlers(this.exceptionType, this, flowInfo, currentScope);
+	currentScope.checkUnclosedCloseables(flowInfo, flowContext, this, currentScope);
+	flowContext.recordAbruptExit();
+	return FlowInfo.DEAD_END;
+}
+
+/**
+ * Throw code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0)
+		return;
+	int pc = codeStream.position;
+	this.exception.generateCode(currentScope, codeStream, true);
+	codeStream.athrow();
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	printIndent(indent, output).append("throw "); //$NON-NLS-1$
+	this.exception.printExpression(0, output);
+	return output.append(';');
+}
+
+public void resolve(BlockScope scope) {
+	this.exceptionType = this.exception.resolveType(scope);
+	MethodScope methodScope = scope.methodScope();
+	LambdaExpression lambda = methodScope.referenceContext instanceof LambdaExpression ? (LambdaExpression) methodScope.referenceContext : null;
+	if (lambda != null) {
+		lambda.throwsException(this.exceptionType);
+	}
+	if (this.exceptionType != null && this.exceptionType.isValidBinding()) {
+		if (this.exceptionType == TypeBinding.NULL) {
+			if (scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3){
+				// if compliant with 1.4, this problem will not be reported
+				scope.problemReporter().cannotThrowNull(this.exception);
+			}
+	 	} else if (this.exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
+			scope.problemReporter().cannotThrowType(this.exception, this.exceptionType);
+		}
+		this.exception.computeConversion(scope, this.exceptionType, this.exceptionType);
+	}
+}
+
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope))
+		this.exception.traverse(visitor, blockScope);
+	visitor.endVisit(this, blockScope);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java
new file mode 100644
index 0000000..d685f81
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class TrueLiteral extends MagicLiteral {
+	
+	static final char[] source = {'t' , 'r' , 'u' , 'e'};
+	
+public TrueLiteral(int s , int e) {
+	super(s,e);
+}
+public void computeConstant() {
+	this.constant = BooleanConstant.fromValue(true);
+}
+/**
+ * Code generation for the true literal
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (valueRequired) {
+		codeStream.generateConstant(this.constant, this.implicitConversion);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) {
+
+	// trueLabel being not nil means that we will not fall through into the TRUE case
+
+	int pc = codeStream.position;
+	// constant == true
+	if (valueRequired) {
+		if (falseLabel == null) {
+			// implicit falling through the FALSE case
+			if (trueLabel != null) {
+				codeStream.goto_(trueLabel);
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+public TypeBinding literalType(BlockScope scope) {
+	return TypeBinding.BOOLEAN;
+}
+/**
+ *
+ */
+public char[] source() {
+	return source;
+}
+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/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
new file mode 100644
index 0000000..32dd3d8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -0,0 +1,1210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 332637 - Dead Code detection removing code that isn't dead
+ *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *     							bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 401088 - [compiler][null] Wrong warning "Redundant null check" inside nested try statement
+ *								bug 401092 - [compiler][null] Wrong warning "Redundant null check" in outer catch of nested try
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *								bug 384380 - False positive on a ?? Potential null pointer access ?? after a continue
+ *     Jesper Steen Moller - Contributions for
+ *								bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
+ *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class TryStatement extends SubRoutineStatement {
+
+	static final char[] SECRET_RETURN_ADDRESS_NAME = " returnAddress".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_ANY_HANDLER_NAME = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_PRIMARY_EXCEPTION_VARIABLE_NAME = " primaryException".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_CAUGHT_THROWABLE_VARIABLE_NAME = " caughtThrowable".toCharArray(); //$NON-NLS-1$;
+	static final char[] SECRET_RETURN_VALUE_NAME = " returnValue".toCharArray(); //$NON-NLS-1$
+
+	private static LocalDeclaration [] NO_RESOURCES = new LocalDeclaration[0];
+	public LocalDeclaration[] resources = NO_RESOURCES;
+
+	public Block tryBlock;
+	public Block[] catchBlocks;
+
+	public Argument[] catchArguments;
+
+	public Block finallyBlock;
+	BlockScope scope;
+
+	public UnconditionalFlowInfo subRoutineInits;
+	ReferenceBinding[] caughtExceptionTypes;
+	boolean[] catchExits;
+
+	BranchLabel subRoutineStartLabel;
+	public LocalVariableBinding anyExceptionVariable,
+		returnAddressVariable,
+		secretReturnValue;
+
+	ExceptionLabel[] declaredExceptionLabels; // only set while generating code
+
+	// for inlining/optimizing JSR instructions
+	private Object[] reusableJSRTargets;
+	private BranchLabel[] reusableJSRSequenceStartLabels;
+	private int[] reusableJSRStateIndexes;
+	private int reusableJSRTargetsCount = 0;
+
+	private static final int NO_FINALLY = 0;										// no finally block
+	private static final int FINALLY_SUBROUTINE = 1; 					// finally is generated as a subroutine (using jsr/ret bytecodes)
+	private static final int FINALLY_DOES_NOT_COMPLETE = 2;		// non returning finally is optimized with only one instance of finally block
+	private static final int FINALLY_INLINE = 3;								// finally block must be inlined since cannot use jsr/ret bytecodes >1.5
+
+	// for local variables table attributes
+	int mergedInitStateIndex = -1;
+	int preTryInitStateIndex = -1;
+	int postTryInitStateIndex = -1;
+	int[] postResourcesInitStateIndexes;
+	int naturalExitMergeInitStateIndex = -1;
+	int[] catchExitInitStateIndexes;
+	private LocalVariableBinding primaryExceptionVariable;
+	private LocalVariableBinding caughtThrowableVariable;
+	private ExceptionLabel[] resourceExceptionLabels;
+	private int[] caughtExceptionsCatchBlocks;
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+	// Consider the try block and catch block so as to compute the intersection of initializations and
+	// the minimum exit relative depth amongst all of them. Then consider the subroutine, and append its
+	// initialization to the try/catch ones, if the subroutine completes normally. If the subroutine does not
+	// complete, then only keep this result for the rest of the analysis
+
+	// process the finally block (subroutine) - create a context for the subroutine
+
+	this.preTryInitStateIndex =
+		currentScope.methodScope().recordInitializationStates(flowInfo);
+
+	if (this.anyExceptionVariable != null) {
+		this.anyExceptionVariable.useFlag = LocalVariableBinding.USED;
+	}
+	if (this.primaryExceptionVariable != null) {
+		this.primaryExceptionVariable.useFlag = LocalVariableBinding.USED;
+	}
+	if (this.caughtThrowableVariable != null) {
+		this.caughtThrowableVariable.useFlag = LocalVariableBinding.USED;
+	}
+	if (this.returnAddressVariable != null) { // TODO (philippe) if subroutine is escaping, unused
+		this.returnAddressVariable.useFlag = LocalVariableBinding.USED;
+	}
+	int resourcesLength = this.resources.length;
+	if (resourcesLength > 0) {
+		this.postResourcesInitStateIndexes = new int[resourcesLength];
+	}
+
+
+	if (this.subRoutineStartLabel == null) {
+		// no finally block -- this is a simplified copy of the else part
+		if (flowContext instanceof FinallyFlowContext) {
+			// if this TryStatement sits inside another TryStatement, establish the wiring so that
+			// FlowContext.markFinallyNullStatus can report into initsOnFinally of the outer try context:
+			FinallyFlowContext finallyContext = (FinallyFlowContext) flowContext;
+			finallyContext.outerTryContext = finallyContext.tryContext;
+		}
+		// process the try block in a context handling the local exceptions.
+		ExceptionHandlingFlowContext handlingContext =
+			new ExceptionHandlingFlowContext(
+				flowContext,
+				this,
+				this.caughtExceptionTypes,
+				this.caughtExceptionsCatchBlocks,
+				null,
+				this.scope,
+				flowInfo);
+		handlingContext.conditionalLevel = 0; // start collection initsOnFinally
+		// only try blocks initialize that member - may consider creating a
+		// separate class if needed
+
+		FlowInfo tryInfo = flowInfo.copy();
+		for (int i = 0; i < resourcesLength; i++) {
+			final LocalDeclaration resource = this.resources[i];
+			tryInfo = resource.analyseCode(currentScope, handlingContext, tryInfo);
+			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(tryInfo);
+			LocalVariableBinding resourceBinding = resource.binding;
+			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+			if (resourceBinding.closeTracker != null) {
+				// this was false alarm, we don't need to track the resource
+				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
+				// keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block
+			}
+			MethodBinding closeMethod = findCloseMethod(resource, resourceBinding);
+			if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
+				ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
+				for (int j = 0, length = thrownExceptions.length; j < length; j++) {
+					handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], tryInfo, currentScope, true);
+				}
+			}
+		}
+		if (!this.tryBlock.isEmptyBlock()) {
+			tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, tryInfo);
+			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+				this.bits |= ASTNode.IsTryBlockExiting;
+		}
+		if (resourcesLength > 0) {
+			this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo);
+			// the resources are not in scope after the try block, so remove their assignment info
+			// to avoid polluting the state indices. However, do this after the postTryInitStateIndex is calculated since
+			// it is used to add or remove assigned resources during code gen
+			for (int i = 0; i < resourcesLength; i++) {
+				tryInfo.resetAssignmentInfo(this.resources[i].binding);
+			}
+		}
+		// check unreachable catch blocks
+		handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
+
+		// process the catch blocks - computing the minimal exit depth amongst try/catch
+		if (this.catchArguments != null) {
+			int catchCount;
+			this.catchExits = new boolean[catchCount = this.catchBlocks.length];
+			this.catchExitInitStateIndexes = new int[catchCount];
+			for (int i = 0; i < catchCount; i++) {
+				// keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
+				FlowInfo catchInfo = prepareCatchInfo(flowInfo, handlingContext, tryInfo, i);
+				flowContext.conditionalLevel++;
+				catchInfo =
+					this.catchBlocks[i].analyseCode(
+						currentScope,
+						flowContext,
+						catchInfo);
+				flowContext.conditionalLevel--;
+				this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
+				this.catchExits[i] =
+					(catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
+				tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
+			}
+		}
+		this.mergedInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(tryInfo);
+
+		// chain up null info registry
+		flowContext.mergeFinallyNullInfo(handlingContext.initsOnFinally);
+
+		return tryInfo;
+	} else {
+		InsideSubRoutineFlowContext insideSubContext;
+		FinallyFlowContext finallyContext;
+		UnconditionalFlowInfo subInfo;
+		// analyse finally block first
+		insideSubContext = new InsideSubRoutineFlowContext(flowContext, this);
+		if (flowContext instanceof FinallyFlowContext) {
+			// if this TryStatement sits inside another TryStatement, establish the wiring so that
+			// FlowContext.markFinallyNullStatus can report into initsOnFinally of the outer try context:
+			insideSubContext.outerTryContext = ((FinallyFlowContext)flowContext).tryContext;
+		}
+
+		// process the try block in a context handling the local exceptions.
+		// (advance instantiation so we can wire this into the FinallyFlowContext)
+		ExceptionHandlingFlowContext handlingContext =
+			new ExceptionHandlingFlowContext(
+				insideSubContext,
+				this,
+				this.caughtExceptionTypes,
+				this.caughtExceptionsCatchBlocks,
+				null,
+				this.scope,
+				flowInfo);
+		insideSubContext.initsOnFinally = handlingContext.initsOnFinally; 
+
+		subInfo =
+			this.finallyBlock
+				.analyseCode(
+					currentScope,
+					finallyContext = new FinallyFlowContext(flowContext, this.finallyBlock, handlingContext),
+					flowInfo.nullInfoLessUnconditionalCopy())
+				.unconditionalInits();
+		handlingContext.conditionalLevel = 0; // start collection initsOnFinally only after analysing the finally block
+		if (subInfo == FlowInfo.DEAD_END) {
+			this.bits |= ASTNode.IsSubRoutineEscaping;
+			this.scope.problemReporter().finallyMustCompleteNormally(this.finallyBlock);
+		} else {
+			// for resource analysis we need the finallyInfo in these nested scopes:
+			FlowInfo finallyInfo = subInfo.copy();
+			this.tryBlock.scope.finallyInfo = finallyInfo;
+			if (this.catchBlocks != null) {
+				for (int i = 0; i < this.catchBlocks.length; i++)
+					this.catchBlocks[i].scope.finallyInfo = finallyInfo;
+			}
+		}
+		this.subRoutineInits = subInfo;
+		// only try blocks initialize that member - may consider creating a
+		// separate class if needed
+
+		FlowInfo tryInfo = flowInfo.copy();
+		for (int i = 0; i < resourcesLength; i++) {
+			final LocalDeclaration resource = this.resources[i];
+			tryInfo = resource.analyseCode(currentScope, handlingContext, tryInfo);
+			this.postResourcesInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(tryInfo);
+			LocalVariableBinding resourceBinding = resource.binding;
+			resourceBinding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+			if (resourceBinding.closeTracker != null) {
+				// this was false alarm, we don't need to track the resource
+				this.tryBlock.scope.removeTrackingVar(resourceBinding.closeTracker);
+				// keep the tracking variable in the resourceBinding in order to prevent creating a new one while analyzing the try block
+			}
+			MethodBinding closeMethod = findCloseMethod(resource, resourceBinding);
+			if (closeMethod != null && closeMethod.isValidBinding() && closeMethod.returnType.id == TypeIds.T_void) {
+				ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
+				for (int j = 0, length = thrownExceptions.length; j < length; j++) {
+					handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], tryInfo, currentScope, true);
+				}
+			}
+		}
+		if (!this.tryBlock.isEmptyBlock()) {
+			tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, tryInfo);
+			if ((tryInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+				this.bits |= ASTNode.IsTryBlockExiting;
+		}
+		if (resourcesLength > 0) {
+			this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo);
+			// the resources are not in scope after the try block, so remove their assignment info
+			// to avoid polluting the state indices. However, do this after the postTryInitStateIndex is calculated since
+			// it is used to add or remove assigned resources during code gen
+			for (int i = 0; i < resourcesLength; i++) {
+				tryInfo.resetAssignmentInfo(this.resources[i].binding);
+			}
+		}
+		// check unreachable catch blocks
+		handlingContext.complainIfUnusedExceptionHandlers(this.scope, this);
+
+		// process the catch blocks - computing the minimal exit depth amongst try/catch
+		if (this.catchArguments != null) {
+			int catchCount;
+			this.catchExits = new boolean[catchCount = this.catchBlocks.length];
+			this.catchExitInitStateIndexes = new int[catchCount];
+			for (int i = 0; i < catchCount; i++) {
+				// keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
+				FlowInfo catchInfo = prepareCatchInfo(flowInfo, handlingContext, tryInfo, i);
+				insideSubContext.conditionalLevel = 1;
+				catchInfo =
+					this.catchBlocks[i].analyseCode(
+						currentScope,
+						insideSubContext,
+						catchInfo);
+				this.catchExitInitStateIndexes[i] = currentScope.methodScope().recordInitializationStates(catchInfo);
+				this.catchExits[i] =
+					(catchInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0;
+				tryInfo = tryInfo.mergedWith(catchInfo.unconditionalInits());
+			}
+		}
+		// we also need to check potential multiple assignments of final variables inside the finally block
+		// need to include potential inits from returns inside the try/catch parts - 1GK2AOF
+		finallyContext.complainOnDeferredChecks(
+			((tryInfo.tagBits & FlowInfo.UNREACHABLE) == 0 ?
+				flowInfo.unconditionalCopy().
+					addPotentialInitializationsFrom(tryInfo).
+					// lighten the influence of the try block, which may have
+					// exited at any point
+					addPotentialInitializationsFrom(insideSubContext.initsOnReturn) :
+				insideSubContext.initsOnReturn).
+			addNullInfoFrom(
+					handlingContext.initsOnFinally),
+			currentScope);
+
+		// chain up null info registry
+		flowContext.mergeFinallyNullInfo(handlingContext.initsOnFinally);
+
+		this.naturalExitMergeInitStateIndex =
+			currentScope.methodScope().recordInitializationStates(tryInfo);
+		if (subInfo == FlowInfo.DEAD_END) {
+			this.mergedInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(subInfo);
+			return subInfo;
+		} else {
+			FlowInfo mergedInfo = tryInfo.addInitializationsFrom(subInfo);
+			this.mergedInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(mergedInfo);
+			return mergedInfo;
+		}
+	}
+}
+private MethodBinding findCloseMethod(final LocalDeclaration resource, LocalVariableBinding resourceBinding) {
+	MethodBinding closeMethod = null;
+	TypeBinding type = resourceBinding.type;
+	if (type != null && type.isValidBinding()) {
+		ReferenceBinding binding = (ReferenceBinding) type;
+		closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
+		if(closeMethod == null) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=380112
+			// closeMethod could be null if the binding is from an interface
+			// extending from multiple interfaces.
+			InvocationSite site = new InvocationSite.EmptyWithAstNode(resource);
+			closeMethod = this.scope.compilationUnitScope().findMethod(binding, ConstantPool.Close, new TypeBinding[0], site, false);
+		}
+	}
+	return closeMethod;
+}
+private FlowInfo prepareCatchInfo(FlowInfo flowInfo, ExceptionHandlingFlowContext handlingContext, FlowInfo tryInfo, int i) {
+	FlowInfo catchInfo;
+	if (isUncheckedCatchBlock(i)) {
+		catchInfo =
+			flowInfo.unconditionalCopy().
+				addPotentialInitializationsFrom(
+					handlingContext.initsOnException(i)).
+				addPotentialInitializationsFrom(tryInfo).
+				addPotentialInitializationsFrom(
+					handlingContext.initsOnReturn).
+			addNullInfoFrom(handlingContext.initsOnFinally);
+	} else {
+		FlowInfo initsOnException = handlingContext.initsOnException(i);
+		if ((handlingContext.tagBits & (FlowContext.DEFER_NULL_DIAGNOSTIC | FlowContext.PREEMPT_NULL_DIAGNOSTIC))
+				== FlowContext.DEFER_NULL_DIAGNOSTIC)
+		{
+			// if null diagnostics are being deferred, initsOnException are incomplete,
+			// need to start with the more accurate upstream flowInfo
+			catchInfo =
+				flowInfo.unconditionalCopy()
+					.addPotentialInitializationsFrom(initsOnException)
+					.addPotentialInitializationsFrom(
+							tryInfo.unconditionalCopy())
+					.addPotentialInitializationsFrom(
+							handlingContext.initsOnReturn.nullInfoLessUnconditionalCopy());						
+		} else {
+			// here initsOnException are precise, so use them as the only source for null information into the catch block:
+			catchInfo =
+				flowInfo.nullInfoLessUnconditionalCopy()
+					.addPotentialInitializationsFrom(initsOnException)
+					.addNullInfoFrom(initsOnException)
+					.addPotentialInitializationsFrom(
+							tryInfo.nullInfoLessUnconditionalCopy())
+					.addPotentialInitializationsFrom(
+							handlingContext.initsOnReturn.nullInfoLessUnconditionalCopy());
+		}
+	}
+
+	// catch var is always set
+	LocalVariableBinding catchArg = this.catchArguments[i].binding;
+	catchInfo.markAsDefinitelyAssigned(catchArg);
+	catchInfo.markAsDefinitelyNonNull(catchArg);
+	/*
+	"If we are about to consider an unchecked exception handler, potential inits may have occured inside
+	the try block that need to be detected , e.g.
+	try { x = 1; throwSomething();} catch(Exception e){ x = 2} "
+	"(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index])
+	ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
+	*/
+	if (this.tryBlock.statements == null && this.resources == NO_RESOURCES) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350579
+		catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+	}
+	return catchInfo;
+}
+// Return true if the catch block corresponds to an unchecked exception making allowance for multi-catch blocks.
+private boolean isUncheckedCatchBlock(int catchBlock) {
+	if (this.caughtExceptionsCatchBlocks == null) {
+		return this.caughtExceptionTypes[catchBlock].isUncheckedException(true);
+	}
+	for (int i = 0, length = this.caughtExceptionsCatchBlocks.length; i < length; i++) {
+		if (this.caughtExceptionsCatchBlocks[i] == catchBlock) {
+			if (this.caughtExceptionTypes[i].isUncheckedException(true)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) {
+	if (this.subRoutineStartLabel == null)
+		return null;
+	return super.enterAnyExceptionHandler(codeStream);
+}
+
+public void enterDeclaredExceptionHandlers(CodeStream codeStream) {
+	for (int i = 0, length = this.declaredExceptionLabels == null ? 0 : this.declaredExceptionLabels.length; i < length; i++) {
+		this.declaredExceptionLabels[i].placeStart();
+	}
+}
+
+public void exitAnyExceptionHandler() {
+	if (this.subRoutineStartLabel == null)
+		return;
+	super.exitAnyExceptionHandler();
+}
+
+public void exitDeclaredExceptionHandlers(CodeStream codeStream) {
+	for (int i = 0, length = this.declaredExceptionLabels == null ? 0 : this.declaredExceptionLabels.length; i < length; i++) {
+		this.declaredExceptionLabels[i].placeEnd();
+	}
+}
+
+private int finallyMode() {
+	if (this.subRoutineStartLabel == null) {
+		return NO_FINALLY;
+	} else if (isSubRoutineEscaping()) {
+		return FINALLY_DOES_NOT_COMPLETE;
+	} else if (this.scope.compilerOptions().inlineJsrBytecode) {
+		return FINALLY_INLINE;
+	} else {
+		return FINALLY_SUBROUTINE;
+	}
+}
+/**
+ * Try statement code generation with or without jsr bytecode use
+ *	post 1.5 target level, cannot use jsr bytecode, must instead inline finally block
+ * returnAddress is only allocated if jsr is allowed
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	boolean isStackMapFrameCodeStream = codeStream instanceof StackMapFrameCodeStream;
+	// in case the labels needs to be reinitialized
+	// when the code generation is restarted in wide mode
+	this.anyExceptionLabel = null;
+	this.reusableJSRTargets = null;
+	this.reusableJSRSequenceStartLabels = null;
+	this.reusableJSRTargetsCount = 0;
+
+	int pc = codeStream.position;
+	int finallyMode = finallyMode();
+
+	boolean requiresNaturalExit = false;
+	// preparing exception labels
+	int maxCatches = this.catchArguments == null ? 0 : this.catchArguments.length;
+	ExceptionLabel[] exceptionLabels;
+	if (maxCatches > 0) {
+		exceptionLabels = new ExceptionLabel[maxCatches];
+		for (int i = 0; i < maxCatches; i++) {
+			Argument argument = this.catchArguments[i];
+			ExceptionLabel exceptionLabel = null;
+			if ((argument.binding.tagBits & TagBits.MultiCatchParameter) != 0) {
+				MultiCatchExceptionLabel multiCatchExceptionLabel = new MultiCatchExceptionLabel(codeStream, argument.binding.type);
+				multiCatchExceptionLabel.initialize((UnionTypeReference) argument.type);
+				exceptionLabel = multiCatchExceptionLabel;
+			} else {
+				exceptionLabel = new ExceptionLabel(codeStream, argument.binding.type, argument.type);
+			}
+			exceptionLabel.placeStart();
+			exceptionLabels[i] = exceptionLabel;
+		}
+	} else {
+		exceptionLabels = null;
+	}
+	if (this.subRoutineStartLabel != null) {
+		this.subRoutineStartLabel.initialize(codeStream);
+		enterAnyExceptionHandler(codeStream);
+	}
+	// generate the try block
+	try {
+		this.declaredExceptionLabels = exceptionLabels;
+		int resourceCount = this.resources.length;
+		if (resourceCount > 0) {
+			// Please see https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16
+			this.resourceExceptionLabels = new ExceptionLabel[resourceCount + 1];
+			codeStream.aconst_null();
+			codeStream.store(this.primaryExceptionVariable, false /* value not required */);
+			codeStream.addVariable(this.primaryExceptionVariable);
+			codeStream.aconst_null();
+			codeStream.store(this.caughtThrowableVariable, false /* value not required */);
+			codeStream.addVariable(this.caughtThrowableVariable);
+			for (int i = 0; i <= resourceCount; i++) {
+				// put null for the exception type to treat them as any exception handlers (equivalent to a try/finally)
+				this.resourceExceptionLabels[i] = new ExceptionLabel(codeStream, null);
+				this.resourceExceptionLabels[i].placeStart();
+				if (i < resourceCount) {
+					this.resources[i].generateCode(this.scope, codeStream); // Initialize resources ...
+				}
+			}
+		}
+		this.tryBlock.generateCode(this.scope, codeStream);
+		if (resourceCount > 0) {
+			for (int i = resourceCount; i >= 0; i--) {
+				BranchLabel exitLabel = new BranchLabel(codeStream);
+				this.resourceExceptionLabels[i].placeEnd(); // outer handler if any is the one that should catch exceptions out of close()
+				
+				LocalVariableBinding localVariable = i > 0 ? this.resources[i-1].binding : null;
+				if ((this.bits & ASTNode.IsTryBlockExiting) == 0) {
+					// inline resource closure
+					if (i > 0) {
+						int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785
+						if (this.postTryInitStateIndex != -1) {
+							/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=361053, we are just past a synthetic instance of try-catch-finally.
+							   Our initialization type state is the same as it was at the end of the just concluded try (catch rethrows)
+							*/
+							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex);
+							codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex);
+						}
+						codeStream.load(localVariable);
+						codeStream.ifnull(exitLabel);
+						codeStream.load(localVariable);
+						codeStream.invokeAutoCloseableClose(localVariable.type);
+						codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);
+					}
+					codeStream.goto_(exitLabel); // skip over the catch block.
+				}
+
+				if (i > 0) {
+					// i is off by one
+					codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postResourcesInitStateIndexes[i - 1]);
+					codeStream.addDefinitelyAssignedVariables(currentScope, this.postResourcesInitStateIndexes[i - 1]);
+				} else {
+					// For the first resource, its preset state is the preTryInitStateIndex
+					codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+					codeStream.addDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+				}
+
+				codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
+				this.resourceExceptionLabels[i].place();
+				if (i == resourceCount) { 
+					// inner most try's catch/finally can be a lot simpler. 
+					codeStream.store(this.primaryExceptionVariable, false);
+					// fall through, invoke close() and re-throw.
+				} else {
+					BranchLabel elseLabel = new BranchLabel(codeStream), postElseLabel = new BranchLabel(codeStream);
+					codeStream.store(this.caughtThrowableVariable, false);
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.ifnonnull(elseLabel);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.store(this.primaryExceptionVariable, false);
+					codeStream.goto_(postElseLabel);
+					elseLabel.place();
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.if_acmpeq(postElseLabel);
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.invokeThrowableAddSuppressed();
+					postElseLabel.place();
+				}
+				if (i > 0) {
+					// inline resource close here rather than bracketing the current catch block with a try region.
+					BranchLabel postCloseLabel = new BranchLabel(codeStream);
+					int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785			
+					codeStream.load(localVariable);
+					codeStream.ifnull(postCloseLabel);
+					codeStream.load(localVariable);
+					codeStream.invokeAutoCloseableClose(localVariable.type);
+					codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);
+					codeStream.removeVariable(localVariable);
+					postCloseLabel.place();
+				}
+				codeStream.load(this.primaryExceptionVariable);
+				codeStream.athrow();
+				exitLabel.place();
+			}
+			codeStream.removeVariable(this.primaryExceptionVariable);
+			codeStream.removeVariable(this.caughtThrowableVariable);
+		}
+	} finally {
+		this.declaredExceptionLabels = null;
+		this.resourceExceptionLabels = null;  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=375248
+	}
+	boolean tryBlockHasSomeCode = codeStream.position != pc;
+	// flag telling if some bytecodes were issued inside the try block
+
+	// place end positions of user-defined exception labels
+	if (tryBlockHasSomeCode) {
+		// natural exit may require subroutine invocation (if finally != null)
+		BranchLabel naturalExitLabel = new BranchLabel(codeStream);
+		BranchLabel postCatchesFinallyLabel = null;
+		for (int i = 0; i < maxCatches; i++) {
+			exceptionLabels[i].placeEnd();
+		}
+		if ((this.bits & ASTNode.IsTryBlockExiting) == 0) {
+			int position = codeStream.position;
+			switch(finallyMode) {
+				case FINALLY_SUBROUTINE :
+				case FINALLY_INLINE :
+					requiresNaturalExit = true;
+					if (this.naturalExitMergeInitStateIndex != -1) {
+						codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+						codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+					}
+					codeStream.goto_(naturalExitLabel);
+					break;
+				case NO_FINALLY :
+					if (this.naturalExitMergeInitStateIndex != -1) {
+						codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+						codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+					}
+					codeStream.goto_(naturalExitLabel);
+					break;
+				case FINALLY_DOES_NOT_COMPLETE :
+					codeStream.goto_(this.subRoutineStartLabel);
+					break;
+			}
+			codeStream.recordPositionsFrom(position, this.tryBlock.sourceEnd);
+			//goto is tagged as part of the try block
+		}
+		/* generate sequence of handler, all starting by storing the TOS (exception
+		thrown) into their own catch variables, the one specified in the source
+		that must denote the handled exception.
+		*/
+		exitAnyExceptionHandler();
+		if (this.catchArguments != null) {
+			postCatchesFinallyLabel = new BranchLabel(codeStream);
+
+			for (int i = 0; i < maxCatches; i++) {
+				/*
+				 * This should not happen. For consistency purpose, if the exception label is never used
+				 * we also don't generate the corresponding catch block, otherwise we have some
+				 * unreachable bytecodes
+				 */
+				if (exceptionLabels[i].getCount() == 0) continue;
+				enterAnyExceptionHandler(codeStream);
+				// May loose some local variable initializations : affecting the local variable attributes
+				if (this.preTryInitStateIndex != -1) {
+					codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+					codeStream.addDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+				}
+				codeStream.pushExceptionOnStack(exceptionLabels[i].exceptionType);
+				exceptionLabels[i].place();
+				// optimizing the case where the exception variable is not actually used
+				LocalVariableBinding catchVar;
+				int varPC = codeStream.position;
+				if ((catchVar = this.catchArguments[i].binding).resolvedPosition != -1) {
+					codeStream.store(catchVar, false);
+					catchVar.recordInitializationStartPC(codeStream.position);
+					codeStream.addVisibleLocalVariable(catchVar);
+				} else {
+					codeStream.pop();
+				}
+				codeStream.recordPositionsFrom(varPC, this.catchArguments[i].sourceStart);
+				// Keep track of the pcs at diverging point for computing the local attribute
+				// since not passing the catchScope, the block generation will exitUserScope(catchScope)
+				this.catchBlocks[i].generateCode(this.scope, codeStream);
+				exitAnyExceptionHandler();
+				if (!this.catchExits[i]) {
+					switch(finallyMode) {
+						case FINALLY_INLINE :
+							// inlined finally here can see all merged variables
+							if (isStackMapFrameCodeStream) {
+								((StackMapFrameCodeStream) codeStream).pushStateIndex(this.naturalExitMergeInitStateIndex);
+							}
+							if (this.catchExitInitStateIndexes[i] != -1) {
+								codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.catchExitInitStateIndexes[i]);
+								codeStream.addDefinitelyAssignedVariables(currentScope, this.catchExitInitStateIndexes[i]);
+							}
+							// entire sequence for finally is associated to finally block
+							this.finallyBlock.generateCode(this.scope, codeStream);
+							codeStream.goto_(postCatchesFinallyLabel);
+							if (isStackMapFrameCodeStream) {
+								((StackMapFrameCodeStream) codeStream).popStateIndex();
+							}
+							break;
+						case FINALLY_SUBROUTINE :
+							requiresNaturalExit = true;
+							//$FALL-THROUGH$
+						case NO_FINALLY :
+							if (this.naturalExitMergeInitStateIndex != -1) {
+								codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+								codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+							}
+							codeStream.goto_(naturalExitLabel);
+							break;
+						case FINALLY_DOES_NOT_COMPLETE :
+							codeStream.goto_(this.subRoutineStartLabel);
+							break;
+					}
+				}
+			}
+		}
+		// extra handler for trailing natural exit (will be fixed up later on when natural exit is generated below)
+		ExceptionLabel naturalExitExceptionHandler = requiresNaturalExit && (finallyMode == FINALLY_SUBROUTINE)
+					? new ExceptionLabel(codeStream, null)
+					: null;
+
+		// addition of a special handler so as to ensure that any uncaught exception (or exception thrown
+		// inside catch blocks) will run the finally block
+		int finallySequenceStartPC = codeStream.position;
+		if (this.subRoutineStartLabel != null && this.anyExceptionLabel.getCount() != 0) {
+			codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
+			if (this.preTryInitStateIndex != -1) {
+				// reset initialization state, as for a normal catch block
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+			}
+			placeAllAnyExceptionHandler();
+			if (naturalExitExceptionHandler != null) naturalExitExceptionHandler.place();
+
+			switch(finallyMode) {
+				case FINALLY_SUBROUTINE :
+					// any exception handler
+					codeStream.store(this.anyExceptionVariable, false);
+					codeStream.jsr(this.subRoutineStartLabel);
+					codeStream.recordPositionsFrom(finallySequenceStartPC, this.finallyBlock.sourceStart);
+					int position = codeStream.position;
+					codeStream.throwAnyException(this.anyExceptionVariable);
+					codeStream.recordPositionsFrom(position, this.finallyBlock.sourceEnd);
+					// subroutine
+					this.subRoutineStartLabel.place();
+					codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
+					position = codeStream.position;
+					codeStream.store(this.returnAddressVariable, false);
+					codeStream.recordPositionsFrom(position, this.finallyBlock.sourceStart);
+					this.finallyBlock.generateCode(this.scope, codeStream);
+					position = codeStream.position;
+					codeStream.ret(this.returnAddressVariable.resolvedPosition);
+					codeStream.recordPositionsFrom(
+						position,
+						this.finallyBlock.sourceEnd);
+					// the ret bytecode is part of the subroutine
+					break;
+				case FINALLY_INLINE :
+					// any exception handler
+					codeStream.store(this.anyExceptionVariable, false);
+					codeStream.addVariable(this.anyExceptionVariable);
+					codeStream.recordPositionsFrom(finallySequenceStartPC, this.finallyBlock.sourceStart);
+					// subroutine
+					this.finallyBlock.generateCode(currentScope, codeStream);
+					position = codeStream.position;
+					codeStream.throwAnyException(this.anyExceptionVariable);
+					codeStream.removeVariable(this.anyExceptionVariable);
+					if (this.preTryInitStateIndex != -1) {
+						codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex);
+					}
+					this.subRoutineStartLabel.place();
+					codeStream.recordPositionsFrom(position, this.finallyBlock.sourceEnd);
+					break;
+				case FINALLY_DOES_NOT_COMPLETE :
+					// any exception handler
+					codeStream.pop();
+					this.subRoutineStartLabel.place();
+					codeStream.recordPositionsFrom(finallySequenceStartPC, this.finallyBlock.sourceStart);
+					// subroutine
+					this.finallyBlock.generateCode(this.scope, codeStream);
+					break;
+			}
+
+			// will naturally fall into subsequent code after subroutine invocation
+			if (requiresNaturalExit) {
+				switch(finallyMode) {
+					case FINALLY_SUBROUTINE :
+						naturalExitLabel.place();
+						int position = codeStream.position;
+						naturalExitExceptionHandler.placeStart();
+						codeStream.jsr(this.subRoutineStartLabel);
+						naturalExitExceptionHandler.placeEnd();
+						codeStream.recordPositionsFrom(
+							position,
+							this.finallyBlock.sourceEnd);
+						break;
+					case FINALLY_INLINE :
+						// inlined finally here can see all merged variables
+						if (isStackMapFrameCodeStream) {
+							((StackMapFrameCodeStream) codeStream).pushStateIndex(this.naturalExitMergeInitStateIndex);
+						}
+						if (this.naturalExitMergeInitStateIndex != -1) {
+							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+							codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
+						}
+						naturalExitLabel.place();
+						// entire sequence for finally is associated to finally block
+						this.finallyBlock.generateCode(this.scope, codeStream);
+						if (postCatchesFinallyLabel != null) {
+							position = codeStream.position;
+							// entire sequence for finally is associated to finally block
+							codeStream.goto_(postCatchesFinallyLabel);
+							codeStream.recordPositionsFrom(
+									position,
+									this.finallyBlock.sourceEnd);
+						}
+						if (isStackMapFrameCodeStream) {
+							((StackMapFrameCodeStream) codeStream).popStateIndex();
+						}
+						break;
+					case FINALLY_DOES_NOT_COMPLETE :
+						break;
+					default :
+						naturalExitLabel.place();
+						break;
+				}
+			}
+			if (postCatchesFinallyLabel != null) {
+				postCatchesFinallyLabel.place();
+			}
+		} else {
+			// no subroutine, simply position end label (natural exit == end)
+			naturalExitLabel.place();
+		}
+	} else {
+		// try block had no effect, only generate the body of the finally block if any
+		if (this.subRoutineStartLabel != null) {
+			this.finallyBlock.generateCode(this.scope, codeStream);
+		}
+	}
+	// May loose some local variable initializations : affecting the local variable attributes
+	if (this.mergedInitStateIndex != -1) {
+		codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * @see SubRoutineStatement#generateSubRoutineInvocation(BlockScope, CodeStream, Object, int, LocalVariableBinding)
+ */
+public boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal) {
+
+	int resourceCount = this.resources.length;
+	if (resourceCount > 0 && this.resourceExceptionLabels != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=375248
+		for (int i = resourceCount; i > 0; --i) {
+			// Disarm the handlers and take care of resource closure.
+			this.resourceExceptionLabels[i].placeEnd();
+			LocalVariableBinding localVariable = this.resources[i-1].binding;
+			BranchLabel exitLabel = new BranchLabel(codeStream);
+			int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785
+			codeStream.load(localVariable);
+			codeStream.ifnull(exitLabel);
+			codeStream.load(localVariable);
+			codeStream.invokeAutoCloseableClose(localVariable.type);
+			codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);
+			exitLabel.place();
+		}
+		// Reinstall handlers
+		for (int i = resourceCount; i > 0; --i) {
+			this.resourceExceptionLabels[i].placeStart();
+		}
+	}
+
+	boolean isStackMapFrameCodeStream = codeStream instanceof StackMapFrameCodeStream;
+	int finallyMode = finallyMode();
+	switch(finallyMode) {
+		case FINALLY_DOES_NOT_COMPLETE :
+			codeStream.goto_(this.subRoutineStartLabel);
+			return true;
+
+		case NO_FINALLY :
+			exitDeclaredExceptionHandlers(codeStream);
+			return false;
+	}
+	// optimize subroutine invocation sequences, using the targetLocation (if any)
+	CompilerOptions options = this.scope.compilerOptions();
+	if (options.shareCommonFinallyBlocks && targetLocation != null) {
+		boolean reuseTargetLocation = true;
+		if (this.reusableJSRTargetsCount > 0) {
+			nextReusableTarget: for (int i = 0, count = this.reusableJSRTargetsCount; i < count; i++) {
+				Object reusableJSRTarget = this.reusableJSRTargets[i];
+				differentTarget: {
+					if (targetLocation == reusableJSRTarget)
+						break differentTarget;
+					if (targetLocation instanceof Constant
+							&& reusableJSRTarget instanceof Constant
+							&& ((Constant)targetLocation).hasSameValue((Constant) reusableJSRTarget)) {
+						break differentTarget;
+					}
+					// cannot reuse current target
+					continue nextReusableTarget;
+				}
+				// current target has been used in the past, simply branch to its label
+				if ((this.reusableJSRStateIndexes[i] != stateIndex) && finallyMode == FINALLY_INLINE) {
+					reuseTargetLocation = false;
+					break nextReusableTarget;
+				} else {
+					codeStream.goto_(this.reusableJSRSequenceStartLabels[i]);
+					return true;
+				}
+			}
+		} else {
+			this.reusableJSRTargets = new Object[3];
+			this.reusableJSRSequenceStartLabels = new BranchLabel[3];
+			this.reusableJSRStateIndexes = new int[3];
+		}
+		if (reuseTargetLocation) {
+			if (this.reusableJSRTargetsCount == this.reusableJSRTargets.length) {
+				System.arraycopy(this.reusableJSRTargets, 0, this.reusableJSRTargets = new Object[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
+				System.arraycopy(this.reusableJSRSequenceStartLabels, 0, this.reusableJSRSequenceStartLabels = new BranchLabel[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
+				System.arraycopy(this.reusableJSRStateIndexes, 0, this.reusableJSRStateIndexes = new int[2*this.reusableJSRTargetsCount], 0, this.reusableJSRTargetsCount);
+			}
+			this.reusableJSRTargets[this.reusableJSRTargetsCount] = targetLocation;
+			BranchLabel reusableJSRSequenceStartLabel = new BranchLabel(codeStream);
+			reusableJSRSequenceStartLabel.place();
+			this.reusableJSRStateIndexes[this.reusableJSRTargetsCount] = stateIndex;
+			this.reusableJSRSequenceStartLabels[this.reusableJSRTargetsCount++] = reusableJSRSequenceStartLabel;
+		}
+	}
+	if (finallyMode == FINALLY_INLINE) {
+		if (isStackMapFrameCodeStream) {
+			((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex);
+		}
+		// cannot use jsr bytecode, then simply inline the subroutine
+		// inside try block, ensure to deactivate all catch block exception handlers while inlining finally block
+		exitAnyExceptionHandler();
+		exitDeclaredExceptionHandlers(codeStream);
+		this.finallyBlock.generateCode(currentScope, codeStream);
+		if (isStackMapFrameCodeStream) {
+			((StackMapFrameCodeStream) codeStream).popStateIndex();
+		}
+	} else {
+		// classic subroutine invocation, distinguish case of non-returning subroutine
+		codeStream.jsr(this.subRoutineStartLabel);
+		exitAnyExceptionHandler();
+		exitDeclaredExceptionHandlers(codeStream);
+	}
+	return false;
+}
+public boolean isSubRoutineEscaping() {
+	return (this.bits & ASTNode.IsSubRoutineEscaping) != 0;
+}
+
+public StringBuffer printStatement(int indent, StringBuffer output) {
+	int length = this.resources.length;
+	printIndent(indent, output).append("try" + (length == 0 ? "\n" : " (")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	for (int i = 0; i < length; i++) {
+		this.resources[i].printAsExpression(0, output);
+		if (i != length - 1) {
+			output.append(";\n"); //$NON-NLS-1$
+			printIndent(indent + 2, output);
+		}
+	}
+	if (length > 0) {
+		output.append(")\n"); //$NON-NLS-1$
+	}
+	this.tryBlock.printStatement(indent + 1, output);
+
+	//catches
+	if (this.catchBlocks != null)
+		for (int i = 0; i < this.catchBlocks.length; i++) {
+				output.append('\n');
+				printIndent(indent, output).append("catch ("); //$NON-NLS-1$
+				this.catchArguments[i].print(0, output).append(")\n"); //$NON-NLS-1$
+				this.catchBlocks[i].printStatement(indent + 1, output);
+		}
+	//finally
+	if (this.finallyBlock != null) {
+		output.append('\n');
+		printIndent(indent, output).append("finally\n"); //$NON-NLS-1$
+		this.finallyBlock.printStatement(indent + 1, output);
+	}
+	return output;
+}
+
+public void resolve(BlockScope upperScope) {
+	// special scope for secret locals optimization.
+	this.scope = new BlockScope(upperScope);
+
+	BlockScope finallyScope = null;
+    BlockScope resourceManagementScope = null; // Single scope to hold all resources and additional secret variables.
+	int resourceCount = this.resources.length;
+	if (resourceCount > 0) {
+		resourceManagementScope = new BlockScope(this.scope);
+		this.primaryExceptionVariable =
+			new LocalVariableBinding(TryStatement.SECRET_PRIMARY_EXCEPTION_VARIABLE_NAME, this.scope.getJavaLangThrowable(), ClassFileConstants.AccDefault, false);
+		resourceManagementScope.addLocalVariable(this.primaryExceptionVariable);
+		this.primaryExceptionVariable.setConstant(Constant.NotAConstant); // not inlinable
+		this.caughtThrowableVariable =
+			new LocalVariableBinding(TryStatement.SECRET_CAUGHT_THROWABLE_VARIABLE_NAME, this.scope.getJavaLangThrowable(), ClassFileConstants.AccDefault, false);
+		resourceManagementScope.addLocalVariable(this.caughtThrowableVariable);
+		this.caughtThrowableVariable.setConstant(Constant.NotAConstant); // not inlinable
+	}
+	for (int i = 0; i < resourceCount; i++) {
+		this.resources[i].resolve(resourceManagementScope);
+		LocalVariableBinding localVariableBinding = this.resources[i].binding;
+		if (localVariableBinding != null && localVariableBinding.isValidBinding()) {
+			localVariableBinding.modifiers |= ClassFileConstants.AccFinal;
+			localVariableBinding.tagBits |= TagBits.IsResource;
+			TypeBinding resourceType = localVariableBinding.type;
+			if (resourceType instanceof ReferenceBinding) {
+				if (resourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangAutoCloseable, false /*AutoCloseable is not a class*/) == null && resourceType.isValidBinding()) {
+					upperScope.problemReporter().resourceHasToImplementAutoCloseable(resourceType, this.resources[i].type);
+					localVariableBinding.type = new ProblemReferenceBinding(CharOperation.splitOn('.', resourceType.shortReadableName()), null, ProblemReasons.InvalidTypeForAutoManagedResource);
+				}
+			} else if (resourceType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862, avoid secondary error in problematic null case
+				upperScope.problemReporter().resourceHasToImplementAutoCloseable(resourceType, this.resources[i].type);
+				localVariableBinding.type = new ProblemReferenceBinding(CharOperation.splitOn('.', resourceType.shortReadableName()), null, ProblemReasons.InvalidTypeForAutoManagedResource);
+			}
+		}
+	}
+	BlockScope tryScope = new BlockScope(resourceManagementScope != null ? resourceManagementScope : this.scope);
+
+	if (this.finallyBlock != null) {
+		if (this.finallyBlock.isEmptyBlock()) {
+			if ((this.finallyBlock.bits & ASTNode.UndocumentedEmptyBlock) != 0) {
+				this.scope.problemReporter().undocumentedEmptyBlock(this.finallyBlock.sourceStart, this.finallyBlock.sourceEnd);
+			}
+		} else {
+			finallyScope = new BlockScope(this.scope, false); // don't add it yet to parent scope
+
+			// provision for returning and forcing the finally block to run
+			MethodScope methodScope = this.scope.methodScope();
+
+			// the type does not matter as long as it is not a base type
+			if (!upperScope.compilerOptions().inlineJsrBytecode) {
+				this.returnAddressVariable =
+					new LocalVariableBinding(TryStatement.SECRET_RETURN_ADDRESS_NAME, upperScope.getJavaLangObject(), ClassFileConstants.AccDefault, false);
+				finallyScope.addLocalVariable(this.returnAddressVariable);
+				this.returnAddressVariable.setConstant(Constant.NotAConstant); // not inlinable
+			}
+			this.subRoutineStartLabel = new BranchLabel();
+
+			this.anyExceptionVariable =
+				new LocalVariableBinding(TryStatement.SECRET_ANY_HANDLER_NAME, this.scope.getJavaLangThrowable(), ClassFileConstants.AccDefault, false);
+			finallyScope.addLocalVariable(this.anyExceptionVariable);
+			this.anyExceptionVariable.setConstant(Constant.NotAConstant); // not inlinable
+
+			if (!methodScope.isInsideInitializer()) {
+				MethodBinding methodBinding =
+					((AbstractMethodDeclaration) methodScope.referenceContext).binding;
+				if (methodBinding != null) {
+					TypeBinding methodReturnType = methodBinding.returnType;
+					if (methodReturnType.id != TypeIds.T_void) {
+						this.secretReturnValue =
+							new LocalVariableBinding(
+								TryStatement.SECRET_RETURN_VALUE_NAME,
+								methodReturnType,
+								ClassFileConstants.AccDefault,
+								false);
+						finallyScope.addLocalVariable(this.secretReturnValue);
+						this.secretReturnValue.setConstant(Constant.NotAConstant); // not inlinable
+					}
+				}
+			}
+			this.finallyBlock.resolveUsing(finallyScope);
+			// force the finally scope to have variable positions shifted after its try scope and catch ones
+			int shiftScopesLength = this.catchArguments == null ? 1 : this.catchArguments.length + 1;
+			finallyScope.shiftScopes = new BlockScope[shiftScopesLength];
+			finallyScope.shiftScopes[0] = tryScope;
+		}
+	}
+	this.tryBlock.resolveUsing(tryScope);
+
+	// arguments type are checked against JavaLangThrowable in resolveForCatch(..)
+	if (this.catchBlocks != null) {
+		int length = this.catchArguments.length;
+		TypeBinding[] argumentTypes = new TypeBinding[length];
+		boolean containsUnionTypes = false;
+		boolean catchHasError = false;
+		for (int i = 0; i < length; i++) {
+			BlockScope catchScope = new BlockScope(this.scope);
+			if (finallyScope != null){
+				finallyScope.shiftScopes[i+1] = catchScope;
+			}
+			// side effect on catchScope in resolveForCatch(..)
+			Argument catchArgument = this.catchArguments[i];
+			containsUnionTypes |= (catchArgument.type.bits & ASTNode.IsUnionType) != 0;
+			if ((argumentTypes[i] = catchArgument.resolveForCatch(catchScope)) == null) {
+				catchHasError = true;
+			}
+			this.catchBlocks[i].resolveUsing(catchScope);
+		}
+		if (catchHasError) {
+			return;
+		}
+		// Verify that the catch clause are ordered in the right way:
+		// more specialized first.
+		verifyDuplicationAndOrder(length, argumentTypes, containsUnionTypes);
+	} else {
+		this.caughtExceptionTypes = new ReferenceBinding[0];
+	}
+
+	if (finallyScope != null){
+		// add finallyScope as last subscope, so it can be shifted behind try/catch subscopes.
+		// the shifting is necessary to achieve no overlay in between the finally scope and its
+		// sibling in term of local variable positions.
+		this.scope.addSubscope(finallyScope);
+	}
+}
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	if (visitor.visit(this, blockScope)) {
+		LocalDeclaration[] localDeclarations = this.resources;
+		for (int i = 0, max = localDeclarations.length; i < max; i++) {
+			localDeclarations[i].traverse(visitor, this.scope);
+		}
+		this.tryBlock.traverse(visitor, this.scope);
+		if (this.catchArguments != null) {
+			for (int i = 0, max = this.catchBlocks.length; i < max; i++) {
+				this.catchArguments[i].traverse(visitor, this.scope);
+				this.catchBlocks[i].traverse(visitor, this.scope);
+			}
+		}
+		if (this.finallyBlock != null)
+			this.finallyBlock.traverse(visitor, this.scope);
+	}
+	visitor.endVisit(this, blockScope);
+}
+protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes, boolean containsUnionTypes) {
+	// Verify that the catch clause are ordered in the right way:
+	// more specialized first.
+	if (containsUnionTypes) {
+		int totalCount = 0;
+		ReferenceBinding[][] allExceptionTypes = new ReferenceBinding[length][];
+		for (int i = 0; i < length; i++) {
+			ReferenceBinding currentExceptionType = (ReferenceBinding) argumentTypes[i];
+			TypeReference catchArgumentType = this.catchArguments[i].type;
+			if ((catchArgumentType.bits & ASTNode.IsUnionType) != 0) {
+				TypeReference[] typeReferences = ((UnionTypeReference) catchArgumentType).typeReferences;
+				int typeReferencesLength = typeReferences.length;
+				ReferenceBinding[] unionExceptionTypes = new ReferenceBinding[typeReferencesLength];
+				for (int j = 0; j < typeReferencesLength; j++) {
+					unionExceptionTypes[j] = (ReferenceBinding) typeReferences[j].resolvedType;
+				}
+				totalCount += typeReferencesLength;
+				allExceptionTypes[i] = unionExceptionTypes;
+			} else {
+				allExceptionTypes[i] = new ReferenceBinding[] { currentExceptionType };
+				totalCount++;
+			}
+		}
+		this.caughtExceptionTypes = new ReferenceBinding[totalCount];
+		this.caughtExceptionsCatchBlocks  = new int[totalCount];
+		for (int i = 0, l = 0; i < length; i++) {
+			ReferenceBinding[] currentExceptions = allExceptionTypes[i];
+			loop: for (int j = 0, max = currentExceptions.length; j < max; j++) {
+				ReferenceBinding exception = currentExceptions[j];
+				this.caughtExceptionTypes[l] = exception;
+				this.caughtExceptionsCatchBlocks[l++] = i;
+				// now iterate over all previous exceptions
+				for (int k = 0; k < i; k++) {
+					ReferenceBinding[] exceptions = allExceptionTypes[k];
+					for (int n = 0, max2 = exceptions.length; n < max2; n++) {
+						ReferenceBinding currentException = exceptions[n];
+						if (exception.isCompatibleWith(currentException)) {
+							TypeReference catchArgumentType = this.catchArguments[i].type;
+							if ((catchArgumentType.bits & ASTNode.IsUnionType) != 0) {
+								catchArgumentType = ((UnionTypeReference) catchArgumentType).typeReferences[j];
+							}
+							this.scope.problemReporter().wrongSequenceOfExceptionTypesError(
+								catchArgumentType,
+								exception,
+								currentException);
+							break loop;
+						}
+					}
+				}
+			}
+		}
+	} else {
+		this.caughtExceptionTypes = new ReferenceBinding[length];
+		for (int i = 0; i < length; i++) {
+			this.caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i];
+			for (int j = 0; j < i; j++) {
+				if (this.caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) {
+					this.scope.problemReporter().wrongSequenceOfExceptionTypesError(
+						this.catchArguments[i].type,
+						this.caughtExceptionTypes[i],
+						argumentTypes[j]);
+				}
+			}
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
new file mode 100644
index 0000000..b1aa526
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -0,0 +1,1516 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+ *								Bug 388630 - @NonNull diagnostics at line 0
+ *     Keigo Imai - Contribution for  bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class TypeDeclaration extends Statement implements ProblemSeverities, ReferenceContext {
+	// Type decl kinds
+	public static final int CLASS_DECL = 1;
+	public static final int INTERFACE_DECL = 2;
+	public static final int ENUM_DECL = 3;
+	public static final int ANNOTATION_TYPE_DECL = 4;
+
+	public int modifiers = ClassFileConstants.AccDefault;
+	public int modifiersSourceStart;
+	public Annotation[] annotations;
+	public char[] name;
+	public TypeReference superclass;
+	public TypeReference[] superInterfaces;
+	public FieldDeclaration[] fields;
+	public AbstractMethodDeclaration[] methods;
+	public TypeDeclaration[] memberTypes;
+	public SourceTypeBinding binding;
+	public ClassScope scope;
+	public MethodScope initializerScope;
+	public MethodScope staticInitializerScope;
+	public boolean ignoreFurtherInvestigation = false;
+	public int maxFieldCount;
+	public int declarationSourceStart;
+	public int declarationSourceEnd;
+	public int bodyStart;
+	public int bodyEnd; // doesn't include the trailing comment if any.
+	public CompilationResult compilationResult;
+	public MethodDeclaration[] missingAbstractMethods;
+	public Javadoc javadoc;
+
+	public QualifiedAllocationExpression allocation; // for anonymous only
+	public TypeDeclaration enclosingType; // for member types only
+
+	public FieldBinding enumValuesSyntheticfield; 	// for enum
+	public int enumConstantsCounter;
+
+	// 1.5 support
+	public TypeParameter[] typeParameters;
+
+public TypeDeclaration(CompilationResult compilationResult){
+	this.compilationResult = compilationResult;
+}
+
+/*
+ *	We cause the compilation task to abort to a given extent.
+ */
+public void abort(int abortLevel, CategorizedProblem problem) {
+	switch (abortLevel) {
+		case AbortCompilation :
+			throw new AbortCompilation(this.compilationResult, problem);
+		case AbortCompilationUnit :
+			throw new AbortCompilationUnit(this.compilationResult, problem);
+		case AbortMethod :
+			throw new AbortMethod(this.compilationResult, problem);
+		default :
+			throw new AbortType(this.compilationResult, problem);
+	}
+}
+
+/**
+ * This method is responsible for adding a <clinit> method declaration to the type method collections.
+ * Note that this implementation is inserting it in first place (as VAJ or javac), and that this
+ * impacts the behavior of the method ConstantPool.resetForClinit(int. int), in so far as
+ * the latter will have to reset the constant pool state accordingly (if it was added first, it does
+ * not need to preserve some of the method specific cached entries since this will be the first method).
+ * inserts the clinit method declaration in the first position.
+ *
+ * @see org.eclipse.jdt.internal.compiler.codegen.ConstantPool#resetForClinit(int, int)
+ */
+public final void addClinit() {
+	//see comment on needClassInitMethod
+	if (needClassInitMethod()) {
+		int length;
+		AbstractMethodDeclaration[] methodDeclarations;
+		if ((methodDeclarations = this.methods) == null) {
+			length = 0;
+			methodDeclarations = new AbstractMethodDeclaration[1];
+		} else {
+			length = methodDeclarations.length;
+			System.arraycopy(
+				methodDeclarations,
+				0,
+				(methodDeclarations = new AbstractMethodDeclaration[length + 1]),
+				1,
+				length);
+		}
+		Clinit clinit = new Clinit(this.compilationResult);
+		methodDeclarations[0] = clinit;
+		// clinit is added in first location, so as to minimize the use of ldcw (big consumer of constant inits)
+		clinit.declarationSourceStart = clinit.sourceStart = this.sourceStart;
+		clinit.declarationSourceEnd = clinit.sourceEnd = this.sourceEnd;
+		clinit.bodyEnd = this.sourceEnd;
+		this.methods = methodDeclarations;
+	}
+}
+
+/*
+ * INTERNAL USE ONLY - Creates a fake method declaration for the corresponding binding.
+ * It is used to report errors for missing abstract methods.
+ */
+public MethodDeclaration addMissingAbstractMethodFor(MethodBinding methodBinding) {
+	TypeBinding[] argumentTypes = methodBinding.parameters;
+	int argumentsLength = argumentTypes.length;
+	//the constructor
+	MethodDeclaration methodDeclaration = new MethodDeclaration(this.compilationResult);
+	methodDeclaration.selector = methodBinding.selector;
+	methodDeclaration.sourceStart = this.sourceStart;
+	methodDeclaration.sourceEnd = this.sourceEnd;
+	methodDeclaration.modifiers = methodBinding.getAccessFlags() & ~ClassFileConstants.AccAbstract;
+
+	if (argumentsLength > 0) {
+		String baseName = "arg";//$NON-NLS-1$
+		Argument[] arguments = (methodDeclaration.arguments = new Argument[argumentsLength]);
+		for (int i = argumentsLength; --i >= 0;) {
+			arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, ClassFileConstants.AccDefault);
+		}
+	}
+
+	//adding the constructor in the methods list
+	if (this.missingAbstractMethods == null) {
+		this.missingAbstractMethods = new MethodDeclaration[] { methodDeclaration };
+	} else {
+		MethodDeclaration[] newMethods;
+		System.arraycopy(
+			this.missingAbstractMethods,
+			0,
+			newMethods = new MethodDeclaration[this.missingAbstractMethods.length + 1],
+			1,
+			this.missingAbstractMethods.length);
+		newMethods[0] = methodDeclaration;
+		this.missingAbstractMethods = newMethods;
+	}
+
+	//============BINDING UPDATE==========================
+	methodDeclaration.binding = new MethodBinding(
+			methodDeclaration.modifiers | ClassFileConstants.AccSynthetic, //methodDeclaration
+			methodBinding.selector,
+			methodBinding.returnType,
+			argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, //arguments bindings
+			methodBinding.thrownExceptions, //exceptions
+			this.binding); //declaringClass
+
+	methodDeclaration.scope = new MethodScope(this.scope, methodDeclaration, true);
+	methodDeclaration.bindArguments();
+
+/*		if (binding.methods == null) {
+			binding.methods = new MethodBinding[] { methodDeclaration.binding };
+		} else {
+			MethodBinding[] newMethods;
+			System.arraycopy(
+				binding.methods,
+				0,
+				newMethods = new MethodBinding[binding.methods.length + 1],
+				1,
+				binding.methods.length);
+			newMethods[0] = methodDeclaration.binding;
+			binding.methods = newMethods;
+		}*/
+	//===================================================
+
+	return methodDeclaration;
+}
+
+/**
+ *	Flow analysis for a local innertype
+ *
+ */
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (this.ignoreFurtherInvestigation)
+		return flowInfo;
+	try {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.bits |= ASTNode.IsReachable;
+			LocalTypeBinding localType = (LocalTypeBinding) this.binding;
+			localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
+		}
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+		updateMaxFieldCount(); // propagate down the max field count
+		internalAnalyseCode(flowContext, flowInfo);
+	} catch (AbortType e) {
+		this.ignoreFurtherInvestigation = true;
+	}
+	return flowInfo;
+}
+
+/**
+ *	Flow analysis for a member innertype
+ *
+ */
+public void analyseCode(ClassScope enclosingClassScope) {
+	if (this.ignoreFurtherInvestigation)
+		return;
+	try {
+		// propagate down the max field count
+		updateMaxFieldCount();
+		internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount));
+	} catch (AbortType e) {
+		this.ignoreFurtherInvestigation = true;
+	}
+}
+
+/**
+ *	Flow analysis for a local member innertype
+ *
+ */
+public void analyseCode(ClassScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	if (this.ignoreFurtherInvestigation)
+		return;
+	try {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.bits |= ASTNode.IsReachable;
+			LocalTypeBinding localType = (LocalTypeBinding) this.binding;
+			localType.setConstantPoolName(currentScope.compilationUnitScope().computeConstantPoolName(localType));
+		}
+		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
+		updateMaxFieldCount(); // propagate down the max field count
+		internalAnalyseCode(flowContext, flowInfo);
+	} catch (AbortType e) {
+		this.ignoreFurtherInvestigation = true;
+	}
+}
+
+/**
+ *	Flow analysis for a package member type
+ *
+ */
+public void analyseCode(CompilationUnitScope unitScope) {
+	if (this.ignoreFurtherInvestigation)
+		return;
+	try {
+		internalAnalyseCode(null, FlowInfo.initial(this.maxFieldCount));
+	} catch (AbortType e) {
+		this.ignoreFurtherInvestigation = true;
+	}
+}
+
+/**
+ * Check for constructor vs. method with no return type.
+ * Answers true if at least one constructor is defined
+ */
+public boolean checkConstructors(Parser parser) {
+	//if a constructor has not the name of the type,
+	//convert it into a method with 'null' as its return type
+	boolean hasConstructor = false;
+	if (this.methods != null) {
+		for (int i = this.methods.length; --i >= 0;) {
+			AbstractMethodDeclaration am;
+			if ((am = this.methods[i]).isConstructor()) {
+				if (!CharOperation.equals(am.selector, this.name)) {
+					// the constructor was in fact a method with no return type
+					// unless an explicit constructor call was supplied
+					ConstructorDeclaration c = (ConstructorDeclaration) am;
+					if (c.constructorCall == null || c.constructorCall.isImplicitSuper()) { //changed to a method
+						MethodDeclaration m = parser.convertToMethodDeclaration(c, this.compilationResult);
+						this.methods[i] = m;
+					}
+				} else {
+					switch (kind(this.modifiers)) {
+						case TypeDeclaration.INTERFACE_DECL :
+							// report the problem and continue the parsing
+							parser.problemReporter().interfaceCannotHaveConstructors((ConstructorDeclaration) am);
+							break;
+						case TypeDeclaration.ANNOTATION_TYPE_DECL :
+							// report the problem and continue the parsing
+							parser.problemReporter().annotationTypeDeclarationCannotHaveConstructor((ConstructorDeclaration) am);
+							break;
+
+					}
+					hasConstructor = true;
+				}
+			}
+		}
+	}
+	return hasConstructor;
+}
+
+public CompilationResult compilationResult() {
+	return this.compilationResult;
+}
+
+public ConstructorDeclaration createDefaultConstructor(	boolean needExplicitConstructorCall, boolean needToInsert) {
+	//Add to method'set, the default constuctor that just recall the
+	//super constructor with no arguments
+	//The arguments' type will be positionned by the TC so just use
+	//the default int instead of just null (consistency purpose)
+
+	//the constructor
+	ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult);
+	constructor.bits |= ASTNode.IsDefaultConstructor;
+	constructor.selector = this.name;
+	constructor.modifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+
+	//if you change this setting, please update the
+	//SourceIndexer2.buildTypeDeclaration(TypeDeclaration,char[]) method
+	constructor.declarationSourceStart = constructor.sourceStart = this.sourceStart;
+	constructor.declarationSourceEnd =
+		constructor.sourceEnd = constructor.bodyEnd = this.sourceEnd;
+
+	//the super call inside the constructor
+	if (needExplicitConstructorCall) {
+		constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
+		constructor.constructorCall.sourceStart = this.sourceStart;
+		constructor.constructorCall.sourceEnd = this.sourceEnd;
+	}
+
+	//adding the constructor in the methods list: rank is not critical since bindings will be sorted
+	if (needToInsert) {
+		if (this.methods == null) {
+			this.methods = new AbstractMethodDeclaration[] { constructor };
+		} else {
+			AbstractMethodDeclaration[] newMethods;
+			System.arraycopy(
+				this.methods,
+				0,
+				newMethods = new AbstractMethodDeclaration[this.methods.length + 1],
+				1,
+				this.methods.length);
+			newMethods[0] = constructor;
+			this.methods = newMethods;
+		}
+	}
+	return constructor;
+}
+
+// anonymous type constructor creation: rank is important since bindings already got sorted
+public MethodBinding createDefaultConstructorWithBinding(MethodBinding inheritedConstructorBinding, boolean eraseThrownExceptions) {
+	//Add to method'set, the default constuctor that just recall the
+	//super constructor with the same arguments
+	String baseName = "$anonymous"; //$NON-NLS-1$
+	TypeBinding[] argumentTypes = inheritedConstructorBinding.parameters;
+	int argumentsLength = argumentTypes.length;
+	//the constructor
+	ConstructorDeclaration constructor = new ConstructorDeclaration(this.compilationResult);
+	constructor.selector = new char[] { 'x' }; //no maining
+	constructor.sourceStart = this.sourceStart;
+	constructor.sourceEnd = this.sourceEnd;
+	int newModifiers = this.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+	if (inheritedConstructorBinding.isVarargs()) {
+		newModifiers |= ClassFileConstants.AccVarargs;
+	}
+	constructor.modifiers = newModifiers;
+	constructor.bits |= ASTNode.IsDefaultConstructor;
+
+	if (argumentsLength > 0) {
+		Argument[] arguments = (constructor.arguments = new Argument[argumentsLength]);
+		for (int i = argumentsLength; --i >= 0;) {
+			arguments[i] = new Argument((baseName + i).toCharArray(), 0L, null /*type ref*/, ClassFileConstants.AccDefault);
+		}
+	}
+	//the super call inside the constructor
+	constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
+	constructor.constructorCall.sourceStart = this.sourceStart;
+	constructor.constructorCall.sourceEnd = this.sourceEnd;
+
+	if (argumentsLength > 0) {
+		Expression[] args;
+		args = constructor.constructorCall.arguments = new Expression[argumentsLength];
+		for (int i = argumentsLength; --i >= 0;) {
+			args[i] = new SingleNameReference((baseName + i).toCharArray(), 0L);
+		}
+	}
+
+	//adding the constructor in the methods list
+	if (this.methods == null) {
+		this.methods = new AbstractMethodDeclaration[] { constructor };
+	} else {
+		AbstractMethodDeclaration[] newMethods;
+		System.arraycopy(this.methods, 0, newMethods = new AbstractMethodDeclaration[this.methods.length + 1], 1, this.methods.length);
+		newMethods[0] = constructor;
+		this.methods = newMethods;
+	}
+
+	//============BINDING UPDATE==========================
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
+	ReferenceBinding[] thrownExceptions = eraseThrownExceptions
+			? this.scope.environment().convertToRawTypes(inheritedConstructorBinding.thrownExceptions, true, true)
+			: inheritedConstructorBinding.thrownExceptions;
+
+	SourceTypeBinding sourceType = this.binding;
+	constructor.binding = new MethodBinding(
+			constructor.modifiers, //methodDeclaration
+			argumentsLength == 0 ? Binding.NO_PARAMETERS : argumentTypes, //arguments bindings
+			thrownExceptions, //exceptions
+			sourceType); //declaringClass
+	constructor.binding.tagBits |= (inheritedConstructorBinding.tagBits & TagBits.HasMissingType);
+	constructor.binding.modifiers |= ExtraCompilerModifiers.AccIsDefaultConstructor;
+	if (inheritedConstructorBinding.parameterNonNullness != null // this implies that annotation based null analysis is enabled
+			&& argumentsLength > 0) 
+	{
+		// copy nullness info from inherited constructor to the new constructor:
+		int len = inheritedConstructorBinding.parameterNonNullness.length;
+		System.arraycopy(inheritedConstructorBinding.parameterNonNullness, 0, 
+				constructor.binding.parameterNonNullness = new Boolean[len], 0, len);
+	}
+
+	constructor.scope = new MethodScope(this.scope, constructor, true);
+	constructor.bindArguments();
+	constructor.constructorCall.resolve(constructor.scope);
+
+	MethodBinding[] methodBindings = sourceType.methods(); // trigger sorting
+	int length;
+	System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[(length = methodBindings.length) + 1], 1, length);
+	methodBindings[0] = constructor.binding;
+	if (++length > 1)
+		ReferenceBinding.sortMethods(methodBindings, 0, length);	// need to resort, since could be valid methods ahead (140643) - DOM needs eager sorting
+	sourceType.setMethods(methodBindings);
+	//===================================================
+
+	return constructor.binding;
+}
+
+/**
+ * Find the matching parse node, answers null if nothing found
+ */
+public FieldDeclaration declarationOf(FieldBinding fieldBinding) {
+	if (fieldBinding != null && this.fields != null) {
+		for (int i = 0, max = this.fields.length; i < max; i++) {
+			FieldDeclaration fieldDecl;
+			if ((fieldDecl = this.fields[i]).binding == fieldBinding)
+				return fieldDecl;
+		}
+	}
+	return null;
+}
+
+/**
+ * Find the matching parse node, answers null if nothing found
+ */
+public TypeDeclaration declarationOf(MemberTypeBinding memberTypeBinding) {
+	if (memberTypeBinding != null && this.memberTypes != null) {
+		for (int i = 0, max = this.memberTypes.length; i < max; i++) {
+			TypeDeclaration memberTypeDecl;
+			if ((memberTypeDecl = this.memberTypes[i]).binding == memberTypeBinding)
+				return memberTypeDecl;
+		}
+	}
+	return null;
+}
+
+/**
+ * Find the matching parse node, answers null if nothing found
+ */
+public AbstractMethodDeclaration declarationOf(MethodBinding methodBinding) {
+	if (methodBinding != null && this.methods != null) {
+		for (int i = 0, max = this.methods.length; i < max; i++) {
+			AbstractMethodDeclaration methodDecl;
+
+			if ((methodDecl = this.methods[i]).binding == methodBinding)
+				return methodDecl;
+		}
+	}
+	return null;
+}
+
+/**
+ * Finds the matching type amoung this type's member types.
+ * Returns null if no type with this name is found.
+ * The type name is a compound name relative to this type
+ * e.g. if this type is X and we're looking for Y.X.A.B
+ *     then a type name would be {X, A, B}
+ */
+public TypeDeclaration declarationOfType(char[][] typeName) {
+	int typeNameLength = typeName.length;
+	if (typeNameLength < 1 || !CharOperation.equals(typeName[0], this.name)) {
+		return null;
+	}
+	if (typeNameLength == 1) {
+		return this;
+	}
+	char[][] subTypeName = new char[typeNameLength - 1][];
+	System.arraycopy(typeName, 1, subTypeName, 0, typeNameLength - 1);
+	for (int i = 0; i < this.memberTypes.length; i++) {
+		TypeDeclaration typeDecl = this.memberTypes[i].declarationOfType(subTypeName);
+		if (typeDecl != null) {
+			return typeDecl;
+		}
+	}
+	return null;
+}
+
+public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+	if (this.scope != null) {
+		return this.scope.compilationUnitScope().referenceContext;
+	}
+	return null;
+}
+
+/**
+ * Generic bytecode generation for type
+ */
+public void generateCode(ClassFile enclosingClassFile) {
+	if ((this.bits & ASTNode.HasBeenGenerated) != 0)
+		return;
+	this.bits |= ASTNode.HasBeenGenerated;
+	if (this.ignoreFurtherInvestigation) {
+		if (this.binding == null)
+			return;
+		ClassFile.createProblemType(
+			this,
+			this.scope.referenceCompilationUnit().compilationResult);
+		return;
+	}
+	try {
+		// create the result for a compiled type
+		ClassFile classFile = ClassFile.getNewInstance(this.binding);
+		classFile.initialize(this.binding, enclosingClassFile, false);
+		if (this.binding.isMemberType()) {
+			classFile.recordInnerClasses(this.binding);
+		} else if (this.binding.isLocalType()) {
+			enclosingClassFile.recordInnerClasses(this.binding);
+			classFile.recordInnerClasses(this.binding);
+		}
+		TypeVariableBinding[] typeVariables = this.binding.typeVariables();
+		for (int i = 0, max = typeVariables.length; i < max; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariables[i];
+			if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				Util.recordNestedType(classFile, typeVariableBinding);
+			}
+		}
+
+		// generate all fiels
+		classFile.addFieldInfos();
+
+		if (this.memberTypes != null) {
+			for (int i = 0, max = this.memberTypes.length; i < max; i++) {
+				TypeDeclaration memberType = this.memberTypes[i];
+				classFile.recordInnerClasses(memberType.binding);
+				memberType.generateCode(this.scope, classFile);
+			}
+		}
+		// generate all methods
+		classFile.setForMethodInfos();
+		if (this.methods != null) {
+			for (int i = 0, max = this.methods.length; i < max; i++) {
+				this.methods[i].generateCode(this.scope, classFile);
+			}
+		}
+		// generate all synthetic and abstract methods
+		classFile.addSpecialMethods();
+
+		if (this.ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors
+			throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);
+		}
+
+		// finalize the compiled type result
+		classFile.addAttributes();
+		this.scope.referenceCompilationUnit().compilationResult.record(
+			this.binding.constantPoolName(),
+			classFile);
+	} catch (AbortType e) {
+		if (this.binding == null)
+			return;
+		ClassFile.createProblemType(
+			this,
+			this.scope.referenceCompilationUnit().compilationResult);
+	}
+}
+
+/**
+ * Bytecode generation for a local inner type (API as a normal statement code gen)
+ */
+public void generateCode(BlockScope blockScope, CodeStream codeStream) {
+	if ((this.bits & ASTNode.IsReachable) == 0) {
+		return;
+	}
+	if ((this.bits & ASTNode.HasBeenGenerated) != 0) return;
+	int pc = codeStream.position;
+	if (this.binding != null) {
+		SyntheticArgumentBinding[] enclosingInstances = ((NestedTypeBinding) this.binding).syntheticEnclosingInstances();
+		for (int i = 0, slotSize = 0, count = enclosingInstances == null ? 0 : enclosingInstances.length; i < count; i++){
+			SyntheticArgumentBinding enclosingInstance = enclosingInstances[i];
+			enclosingInstance.resolvedPosition = ++slotSize; // shift by 1 to leave room for aload0==this
+			if (slotSize > 0xFF) { // no more than 255 words of arguments
+				blockScope.problemReporter().noMoreAvailableSpaceForArgument(enclosingInstance, blockScope.referenceType());
+			}
+		}
+	}
+	generateCode(codeStream.classFile);
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+/**
+ * Bytecode generation for a member inner type
+ */
+public void generateCode(ClassScope classScope, ClassFile enclosingClassFile) {
+	if ((this.bits & ASTNode.HasBeenGenerated) != 0) return;
+	if (this.binding != null) {
+		SyntheticArgumentBinding[] enclosingInstances = ((NestedTypeBinding) this.binding).syntheticEnclosingInstances();
+		for (int i = 0, slotSize = 0, count = enclosingInstances == null ? 0 : enclosingInstances.length; i < count; i++){
+			SyntheticArgumentBinding enclosingInstance = enclosingInstances[i];
+			enclosingInstance.resolvedPosition = ++slotSize; // shift by 1 to leave room for aload0==this
+			if (slotSize > 0xFF) { // no more than 255 words of arguments
+				classScope.problemReporter().noMoreAvailableSpaceForArgument(enclosingInstance, classScope.referenceType());
+			}
+		}
+	}
+	generateCode(enclosingClassFile);
+}
+
+/**
+ * Bytecode generation for a package member
+ */
+public void generateCode(CompilationUnitScope unitScope) {
+	generateCode((ClassFile) null);
+}
+
+public boolean hasErrors() {
+	return this.ignoreFurtherInvestigation;
+}
+
+/**
+ *	Common flow analysis for all types
+ */
+private void internalAnalyseCode(FlowContext flowContext, FlowInfo flowInfo) {
+	if (!this.binding.isUsed() && this.binding.isOrEnclosedByPrivateType()) {
+		if (!this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+			this.scope.problemReporter().unusedPrivateType(this);
+		}
+	}
+	
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=385780
+	if (this.typeParameters != null && 
+			!this.scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+		for (int i = 0, length = this.typeParameters.length; i < length; ++i) {
+			TypeParameter typeParameter = this.typeParameters[i];
+			if ((typeParameter.binding.modifiers & ExtraCompilerModifiers.AccLocallyUsed) == 0) {
+				this.scope.problemReporter().unusedTypeParameter(typeParameter);			
+			}
+		}
+	}
+	
+	// for local classes we use the flowContext as our parent, but never use an initialization context for this purpose
+	// see Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
+	FlowContext parentContext = (flowContext instanceof InitializationFlowContext) ? null : flowContext;
+	InitializationFlowContext initializerContext = new InitializationFlowContext(parentContext, this, flowInfo, flowContext, this.initializerScope);
+	// no static initializer in local classes, thus no need to set parent:
+	InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.staticInitializerScope);
+	FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy();
+	FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy();
+	if (this.fields != null) {
+		for (int i = 0, count = this.fields.length; i < count; i++) {
+			FieldDeclaration field = this.fields[i];
+			if (field.isStatic()) {
+				if ((staticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+					field.bits &= ~ASTNode.IsReachable;
+
+				/*if (field.isField()){
+					staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
+				} else {*/
+				staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
+				/*}*/
+				staticFieldInfo = field.analyseCode(this.staticInitializerScope, staticInitializerContext, staticFieldInfo);
+				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
+				// branch, since the previous initializer already got the blame.
+				if (staticFieldInfo == FlowInfo.DEAD_END) {
+					this.staticInitializerScope.problemReporter().initializerMustCompleteNormally(field);
+					staticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+				}
+			} else {
+				if ((nonStaticFieldInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+					field.bits &= ~ASTNode.IsReachable;
+
+				/*if (field.isField()){
+					initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
+				} else {*/
+					initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
+				/*}*/
+				nonStaticFieldInfo = field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo);
+				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
+				// branch, since the previous initializer already got the blame.
+				if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
+					this.initializerScope.problemReporter().initializerMustCompleteNormally(field);
+					nonStaticFieldInfo = FlowInfo.initial(this.maxFieldCount).setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+				}
+			}
+		}
+	}
+	if (this.memberTypes != null) {
+		for (int i = 0, count = this.memberTypes.length; i < count; i++) {
+			if (flowContext != null){ // local type
+				this.memberTypes[i].analyseCode(this.scope, flowContext, nonStaticFieldInfo.copy().setReachMode(flowInfo.reachMode())); // reset reach mode in case initializers did abrupt completely
+			} else {
+				this.memberTypes[i].analyseCode(this.scope);
+			}
+		}
+	}
+	if (this.methods != null) {
+		UnconditionalFlowInfo outerInfo = flowInfo.unconditionalFieldLessCopy();
+		FlowInfo constructorInfo = nonStaticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo);
+		for (int i = 0, count = this.methods.length; i < count; i++) {
+			AbstractMethodDeclaration method = this.methods[i];
+			if (method.ignoreFurtherInvestigation)
+				continue;
+			if (method.isInitializationMethod()) {
+				// pass down the appropriate initializerContext:
+				if (method.isStatic()) { // <clinit>
+					((Clinit)method).analyseCode(
+						this.scope,
+						staticInitializerContext,
+						staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo));
+				} else { // constructor
+					((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode());
+				}
+			} else { // regular method
+				// pass down the parentContext (NOT an initializer context, see above):
+				((MethodDeclaration)method).analyseCode(this.scope, parentContext, flowInfo.copy());
+			}
+		}
+	}
+	// enable enum support ?
+	if (this.binding.isEnum() && !this.binding.isAnonymousType()) {
+		this.enumValuesSyntheticfield = this.binding.addSyntheticFieldForEnumValues();
+	}
+}
+
+public final static int kind(int flags) {
+	switch (flags & (ClassFileConstants.AccInterface|ClassFileConstants.AccAnnotation|ClassFileConstants.AccEnum)) {
+		case ClassFileConstants.AccInterface :
+			return TypeDeclaration.INTERFACE_DECL;
+		case ClassFileConstants.AccInterface|ClassFileConstants.AccAnnotation :
+			return TypeDeclaration.ANNOTATION_TYPE_DECL;
+		case ClassFileConstants.AccEnum :
+			return TypeDeclaration.ENUM_DECL;
+		default :
+			return TypeDeclaration.CLASS_DECL;
+	}
+}
+
+/*
+ * Access emulation for a local type
+ * force to emulation of access to direct enclosing instance.
+ * By using the initializer scope, we actually only request an argument emulation, the
+ * field is not added until actually used. However we will force allocations to be qualified
+ * with an enclosing instance.
+ * 15.9.2
+ */
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+	NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
+
+	MethodScope methodScope = currentScope.methodScope();
+	if (!methodScope.isStatic && !methodScope.isConstructorCall){
+		nestedType.addSyntheticArgumentAndField(nestedType.enclosingType());
+	}
+	// add superclass enclosing instance arg for anonymous types (if necessary)
+	if (nestedType.isAnonymousType()) {
+		ReferenceBinding superclassBinding = (ReferenceBinding)nestedType.superclass.erasure();
+		if (superclassBinding.enclosingType() != null && !superclassBinding.isStatic()) {
+			if (!superclassBinding.isLocalType()
+					|| ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null){
+
+				nestedType.addSyntheticArgument(superclassBinding.enclosingType());
+			}
+		}
+		// From 1.5 on, provide access to enclosing instance synthetic constructor argument when declared inside constructor call
+		// only for direct anonymous type
+		//public class X {
+		//	void foo() {}
+		//	class M {
+		//		M(Object o) {}
+		//		M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
+		//	}
+		//}
+		if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
+			ReferenceBinding enclosing = nestedType.enclosingType();
+			if (enclosing.isNestedType()) {
+				NestedTypeBinding nestedEnclosing = (NestedTypeBinding)enclosing;
+//					if (nestedEnclosing.findSuperTypeErasingTo(nestedEnclosing.enclosingType()) == null) { // only if not inheriting
+					SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing.getSyntheticArgument(nestedEnclosing.enclosingType(), true, false);
+					if (syntheticEnclosingInstanceArgument != null) {
+						nestedType.addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument);
+					}
+				}
+//				}
+		}
+	}
+}
+
+/**
+ * Access emulation for a local member type
+ * force to emulation of access to direct enclosing instance.
+ * By using the initializer scope, we actually only request an argument emulation, the
+ * field is not added until actually used. However we will force allocations to be qualified
+ * with an enclosing instance.
+ *
+ * Local member cannot be static.
+ */
+public void manageEnclosingInstanceAccessIfNecessary(ClassScope currentScope, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+	NestedTypeBinding nestedType = (NestedTypeBinding) this.binding;
+	nestedType.addSyntheticArgumentAndField(this.binding.enclosingType());
+	}
+}
+
+/**
+ * A <clinit> will be requested as soon as static fields or assertions are present. It will be eliminated during
+ * classfile creation if no bytecode was actually produced based on some optimizations/compiler settings.
+ */
+public final boolean needClassInitMethod() {
+	// always need a <clinit> when assertions are present
+	if ((this.bits & ASTNode.ContainsAssertion) != 0)
+		return true;
+
+	switch (kind(this.modifiers)) {
+		case TypeDeclaration.INTERFACE_DECL:
+		case TypeDeclaration.ANNOTATION_TYPE_DECL:
+			return this.fields != null; // fields are implicitly statics
+		case TypeDeclaration.ENUM_DECL:
+			return true; // even if no enum constants, need to set $VALUES array
+	}
+	if (this.fields != null) {
+		for (int i = this.fields.length; --i >= 0;) {
+			FieldDeclaration field = this.fields[i];
+			//need to test the modifier directly while there is no binding yet
+			if ((field.modifiers & ClassFileConstants.AccStatic) != 0)
+				return true; // TODO (philippe) shouldn't it check whether field is initializer or has some initial value ?
+		}
+	}
+	return false;
+}
+
+public void parseMethods(Parser parser, CompilationUnitDeclaration unit) {
+	//connect method bodies
+	if (unit.ignoreMethodBodies)
+		return;
+
+	//members
+	if (this.memberTypes != null) {
+		int length = this.memberTypes.length;
+		for (int i = 0; i < length; i++) {
+			TypeDeclaration typeDeclaration = this.memberTypes[i];
+			typeDeclaration.parseMethods(parser, unit);
+			this.bits |= (typeDeclaration.bits & ASTNode.HasSyntaxErrors);
+		}
+	}
+
+	//methods
+	if (this.methods != null) {
+		int length = this.methods.length;
+		for (int i = 0; i < length; i++) {
+			AbstractMethodDeclaration abstractMethodDeclaration = this.methods[i];
+			abstractMethodDeclaration.parseStatements(parser, unit);
+			this.bits |= (abstractMethodDeclaration.bits & ASTNode.HasSyntaxErrors);
+		}
+	}
+
+	//initializers
+	if (this.fields != null) {
+		int length = this.fields.length;
+		for (int i = 0; i < length; i++) {
+			final FieldDeclaration fieldDeclaration = this.fields[i];
+			switch(fieldDeclaration.getKind()) {
+				case AbstractVariableDeclaration.INITIALIZER:
+					((Initializer) fieldDeclaration).parseStatements(parser, this, unit);
+					this.bits |= (fieldDeclaration.bits & ASTNode.HasSyntaxErrors);
+					break;
+			}
+		}
+	}
+}
+
+public StringBuffer print(int indent, StringBuffer output) {
+	if (this.javadoc != null) {
+		this.javadoc.print(indent, output);
+	}
+	if ((this.bits & ASTNode.IsAnonymousType) == 0) {
+		printIndent(indent, output);
+		printHeader(0, output);
+	}
+	return printBody(indent, output);
+}
+
+public StringBuffer printBody(int indent, StringBuffer output) {
+	output.append(" {"); //$NON-NLS-1$
+	if (this.memberTypes != null) {
+		for (int i = 0; i < this.memberTypes.length; i++) {
+			if (this.memberTypes[i] != null) {
+				output.append('\n');
+				this.memberTypes[i].print(indent + 1, output);
+			}
+		}
+	}
+	if (this.fields != null) {
+		for (int fieldI = 0; fieldI < this.fields.length; fieldI++) {
+			if (this.fields[fieldI] != null) {
+				output.append('\n');
+				this.fields[fieldI].print(indent + 1, output);
+			}
+		}
+	}
+	if (this.methods != null) {
+		for (int i = 0; i < this.methods.length; i++) {
+			if (this.methods[i] != null) {
+				output.append('\n');
+				this.methods[i].print(indent + 1, output);
+			}
+		}
+	}
+	output.append('\n');
+	return printIndent(indent, output).append('}');
+}
+
+public StringBuffer printHeader(int indent, StringBuffer output) {
+	printModifiers(this.modifiers, output);
+	if (this.annotations != null) {
+		printAnnotations(this.annotations, output);
+		output.append(' ');
+	}
+
+	switch (kind(this.modifiers)) {
+		case TypeDeclaration.CLASS_DECL :
+			output.append("class "); //$NON-NLS-1$
+			break;
+		case TypeDeclaration.INTERFACE_DECL :
+			output.append("interface "); //$NON-NLS-1$
+			break;
+		case TypeDeclaration.ENUM_DECL :
+			output.append("enum "); //$NON-NLS-1$
+			break;
+		case TypeDeclaration.ANNOTATION_TYPE_DECL :
+			output.append("@interface "); //$NON-NLS-1$
+			break;
+	}
+	output.append(this.name);
+	if (this.typeParameters != null) {
+		output.append("<");//$NON-NLS-1$
+		for (int i = 0; i < this.typeParameters.length; i++) {
+			if (i > 0) output.append( ", "); //$NON-NLS-1$
+			this.typeParameters[i].print(0, output);
+		}
+		output.append(">");//$NON-NLS-1$
+	}
+	if (this.superclass != null) {
+		output.append(" extends ");  //$NON-NLS-1$
+		this.superclass.print(0, output);
+	}
+	if (this.superInterfaces != null && this.superInterfaces.length > 0) {
+		switch (kind(this.modifiers)) {
+			case TypeDeclaration.CLASS_DECL :
+			case TypeDeclaration.ENUM_DECL :
+				output.append(" implements "); //$NON-NLS-1$
+				break;
+			case TypeDeclaration.INTERFACE_DECL :
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				output.append(" extends "); //$NON-NLS-1$
+				break;
+		}
+		for (int i = 0; i < this.superInterfaces.length; i++) {
+			if (i > 0) output.append( ", "); //$NON-NLS-1$
+			this.superInterfaces[i].print(0, output);
+		}
+	}
+	return output;
+}
+
+public StringBuffer printStatement(int tab, StringBuffer output) {
+	return print(tab, output);
+}
+
+
+
+public void resolve() {
+	SourceTypeBinding sourceType = this.binding;
+	if (sourceType == null) {
+		this.ignoreFurtherInvestigation = true;
+		return;
+	}
+	try {
+		boolean old = this.staticInitializerScope.insideTypeAnnotation;
+		try {
+			this.staticInitializerScope.insideTypeAnnotation = true;
+			resolveAnnotations(this.staticInitializerScope, this.annotations, sourceType);
+		} finally {
+			this.staticInitializerScope.insideTypeAnnotation = old;
+		}
+		// check @Deprecated annotation
+		long annotationTagBits = sourceType.getAnnotationTagBits();
+		if ((annotationTagBits & TagBits.AnnotationDeprecated) == 0
+				&& (sourceType.modifiers & ClassFileConstants.AccDeprecated) != 0
+				&& this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+			this.scope.problemReporter().missingDeprecatedAnnotationForType(this);
+		}
+		if ((annotationTagBits & TagBits.AnnotationFunctionalInterface) != 0) {
+			if(!this.binding.isFunctionalInterface(this.scope)) {
+				this.scope.problemReporter().notAFunctionalInterface(this);
+			}
+		}
+
+		if ((this.bits & ASTNode.UndocumentedEmptyBlock) != 0) {
+			this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd);
+		}
+		boolean needSerialVersion =
+						this.scope.compilerOptions().getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore
+						&& sourceType.isClass()
+						&& sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoExternalizable, false /*Externalizable is not a class*/) == null
+						&& sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null;
+
+		if (needSerialVersion) {
+			// if Object writeReplace() throws java.io.ObjectStreamException is present, then no serialVersionUID is needed
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=101476
+			CompilationUnitScope compilationUnitScope = this.scope.compilationUnitScope();
+			MethodBinding methodBinding = sourceType.getExactMethod(TypeConstants.WRITEREPLACE, Binding.NO_TYPES, compilationUnitScope);
+			ReferenceBinding[] throwsExceptions;
+			needSerialVersion =
+				methodBinding == null
+					|| !methodBinding.isValidBinding()
+					|| methodBinding.returnType.id != TypeIds.T_JavaLangObject
+					|| (throwsExceptions = methodBinding.thrownExceptions).length != 1
+					|| throwsExceptions[0].id != TypeIds.T_JavaIoObjectStreamException;
+			if (needSerialVersion) {
+				// check the presence of an implementation of the methods
+				// private void writeObject(java.io.ObjectOutputStream out) throws IOException
+				// private void readObject(java.io.ObjectInputStream out) throws IOException
+				boolean hasWriteObjectMethod = false;
+				boolean hasReadObjectMethod = false;
+				TypeBinding argumentTypeBinding = this.scope.getType(TypeConstants.JAVA_IO_OBJECTOUTPUTSTREAM, 3);
+				if (argumentTypeBinding.isValidBinding()) {
+					methodBinding = sourceType.getExactMethod(TypeConstants.WRITEOBJECT, new TypeBinding[] { argumentTypeBinding }, compilationUnitScope);
+					hasWriteObjectMethod = methodBinding != null
+							&& methodBinding.isValidBinding()
+							&& methodBinding.modifiers == ClassFileConstants.AccPrivate
+							&& methodBinding.returnType == TypeBinding.VOID
+							&& (throwsExceptions = methodBinding.thrownExceptions).length == 1
+							&& throwsExceptions[0].id == TypeIds.T_JavaIoException;
+				}
+				argumentTypeBinding = this.scope.getType(TypeConstants.JAVA_IO_OBJECTINPUTSTREAM, 3);
+				if (argumentTypeBinding.isValidBinding()) {
+					methodBinding = sourceType.getExactMethod(TypeConstants.READOBJECT, new TypeBinding[] { argumentTypeBinding }, compilationUnitScope);
+					hasReadObjectMethod = methodBinding != null
+							&& methodBinding.isValidBinding()
+							&& methodBinding.modifiers == ClassFileConstants.AccPrivate
+							&& methodBinding.returnType == TypeBinding.VOID
+							&& (throwsExceptions = methodBinding.thrownExceptions).length == 1
+							&& throwsExceptions[0].id == TypeIds.T_JavaIoException;
+				}
+				needSerialVersion = !hasWriteObjectMethod || !hasReadObjectMethod;
+			}
+		}
+		// generics (and non static generic members) cannot extend Throwable
+		if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) != null) {
+			ReferenceBinding current = sourceType;
+			checkEnclosedInGeneric : do {
+				if (current.isGenericType()) {
+					this.scope.problemReporter().genericTypeCannotExtendThrowable(this);
+					break checkEnclosedInGeneric;
+				}
+				if (current.isStatic()) break checkEnclosedInGeneric;
+				if (current.isLocalType()) {
+					NestedTypeBinding nestedType = (NestedTypeBinding) current.erasure();
+					if (nestedType.scope.methodScope().isStatic) break checkEnclosedInGeneric;
+				}
+			} while ((current = current.enclosingType()) != null);
+		}
+		// this.maxFieldCount might already be set
+		int localMaxFieldCount = 0;
+		int lastVisibleFieldID = -1;
+		boolean hasEnumConstants = false;
+		FieldDeclaration[] enumConstantsWithoutBody = null;
+
+		if (this.typeParameters != null) {
+			for (int i = 0, count = this.typeParameters.length; i < count; i++) {
+				this.typeParameters[i].resolve(this.scope);
+			}
+		}
+		if (this.memberTypes != null) {
+			for (int i = 0, count = this.memberTypes.length; i < count; i++) {
+				this.memberTypes[i].resolve(this.scope);
+			}
+		}
+		if (this.fields != null) {
+			for (int i = 0, count = this.fields.length; i < count; i++) {
+				FieldDeclaration field = this.fields[i];
+				switch(field.getKind()) {
+					case AbstractVariableDeclaration.ENUM_CONSTANT:
+						hasEnumConstants = true;
+						if (!(field.initialization instanceof QualifiedAllocationExpression)) {
+							if (enumConstantsWithoutBody == null)
+								enumConstantsWithoutBody = new FieldDeclaration[count];
+							enumConstantsWithoutBody[i] = field;
+						}
+						//$FALL-THROUGH$
+					case AbstractVariableDeclaration.FIELD:
+						FieldBinding fieldBinding = field.binding;
+						if (fieldBinding == null) {
+							// still discover secondary errors
+							if (field.initialization != null) field.initialization.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope);
+							this.ignoreFurtherInvestigation = true;
+							continue;
+						}
+						if (needSerialVersion
+								&& ((fieldBinding.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal)) == (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal))
+								&& CharOperation.equals(TypeConstants.SERIALVERSIONUID, fieldBinding.name)
+								&& TypeBinding.LONG == fieldBinding.type) {
+							needSerialVersion = false;
+						}
+						localMaxFieldCount++;
+						lastVisibleFieldID = field.binding.id;
+						break;
+
+					case AbstractVariableDeclaration.INITIALIZER:
+						 ((Initializer) field).lastVisibleFieldID = lastVisibleFieldID + 1;
+						break;
+				}
+				field.resolve(field.isStatic() ? this.staticInitializerScope : this.initializerScope);
+			}
+		}
+		if (this.maxFieldCount < localMaxFieldCount) {
+			this.maxFieldCount = localMaxFieldCount;
+		}
+		if (needSerialVersion) {
+			//check that the current type doesn't extend javax.rmi.CORBA.Stub
+			TypeBinding javaxRmiCorbaStub = this.scope.getType(TypeConstants.JAVAX_RMI_CORBA_STUB, 4);
+			if (javaxRmiCorbaStub.isValidBinding()) {
+				ReferenceBinding superclassBinding = this.binding.superclass;
+				loop: while (superclassBinding != null) {
+					if (superclassBinding == javaxRmiCorbaStub) {
+						needSerialVersion = false;
+						break loop;
+					}
+					superclassBinding = superclassBinding.superclass();
+				}
+			}
+			if (needSerialVersion) {
+				this.scope.problemReporter().missingSerialVersion(this);
+			}
+		}
+
+		// check extends/implements for annotation type
+		switch(kind(this.modifiers)) {
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				if (this.superclass != null) {
+					this.scope.problemReporter().annotationTypeDeclarationCannotHaveSuperclass(this);
+				}
+				if (this.superInterfaces != null) {
+					this.scope.problemReporter().annotationTypeDeclarationCannotHaveSuperinterfaces(this);
+				}
+				break;
+			case TypeDeclaration.ENUM_DECL :
+				// check enum abstract methods
+				if (this.binding.isAbstract()) {
+					if (!hasEnumConstants) {
+						for (int i = 0, count = this.methods.length; i < count; i++) {
+							final AbstractMethodDeclaration methodDeclaration = this.methods[i];
+							if (methodDeclaration.isAbstract() && methodDeclaration.binding != null)
+								this.scope.problemReporter().enumAbstractMethodMustBeImplemented(methodDeclaration);
+						}
+					} else if (enumConstantsWithoutBody != null) {
+						for (int i = 0, count = this.methods.length; i < count; i++) {
+							final AbstractMethodDeclaration methodDeclaration = this.methods[i];
+							if (methodDeclaration.isAbstract() && methodDeclaration.binding != null) {
+								for (int f = 0, l = enumConstantsWithoutBody.length; f < l; f++)
+									if (enumConstantsWithoutBody[f] != null)
+										this.scope.problemReporter().enumConstantMustImplementAbstractMethod(methodDeclaration, enumConstantsWithoutBody[f]);
+							}
+						}
+					}
+				}
+				break;
+		}
+
+		int missingAbstractMethodslength = this.missingAbstractMethods == null ? 0 : this.missingAbstractMethods.length;
+		int methodsLength = this.methods == null ? 0 : this.methods.length;
+		if ((methodsLength + missingAbstractMethodslength) > 0xFFFF) {
+			this.scope.problemReporter().tooManyMethods(this);
+		}
+		if (this.methods != null) {
+			for (int i = 0, count = this.methods.length; i < count; i++) {
+				this.methods[i].resolve(this.scope);
+			}
+		}
+		// Resolve javadoc
+		if (this.javadoc != null) {
+			if (this.scope != null && (this.name != TypeConstants.PACKAGE_INFO_NAME)) {
+				// if the type is package-info, the javadoc was resolved as part of the compilation unit javadoc
+				this.javadoc.resolve(this.scope);
+			}
+		} else if (!sourceType.isLocalType()) {
+			// Set javadoc visibility
+			int visibility = sourceType.modifiers & ExtraCompilerModifiers.AccVisibilityMASK;
+			ProblemReporter reporter = this.scope.problemReporter();
+			int severity = reporter.computeSeverity(IProblem.JavadocMissing);
+			if (severity != ProblemSeverities.Ignore) {
+				if (this.enclosingType != null) {
+					visibility = Util.computeOuterMostVisibility(this.enclosingType, visibility);
+				}
+				int javadocModifiers = (this.binding.modifiers & ~ExtraCompilerModifiers.AccVisibilityMASK) | visibility;
+				reporter.javadocMissing(this.sourceStart, this.sourceEnd, severity, javadocModifiers);
+			}
+		}
+	} catch (AbortType e) {
+		this.ignoreFurtherInvestigation = true;
+		return;
+	}
+}
+
+/**
+ * Resolve a local type declaration
+ */
+public void resolve(BlockScope blockScope) {
+
+	// need to build its scope first and proceed with binding's creation
+	if ((this.bits & ASTNode.IsAnonymousType) == 0) {
+		// check collision scenarii
+		Binding existing = blockScope.getType(this.name);
+		if (existing instanceof ReferenceBinding
+				&& existing != this.binding
+				&& existing.isValidBinding()) {
+			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() || blockScope.isLambdaSubscope())) {
+					// dup in same method
+					blockScope.problemReporter().duplicateNestedType(this);
+			} else if (blockScope.isDefinedInType(existingType)) {
+				//	collision with enclosing type
+				blockScope.problemReporter().typeCollidesWithEnclosingType(this);
+			} else if (blockScope.isDefinedInSameUnit(existingType)){ // only consider hiding inside same unit
+				// hiding sibling
+				blockScope.problemReporter().typeHiding(this, existingType);
+			}
+		}
+		blockScope.addLocalType(this);
+	}
+
+	if (this.binding != null) {
+		// remember local types binding for innerclass emulation propagation
+		blockScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding);
+
+		// binding is not set if the receiver could not be created
+		resolve();
+		updateMaxFieldCount();
+	}
+}
+
+/**
+ * Resolve a member type declaration (can be a local member)
+ */
+public void resolve(ClassScope upperScope) {
+	// member scopes are already created
+	// request the construction of a binding if local member type
+
+	if (this.binding != null && this.binding instanceof LocalTypeBinding) {
+		// remember local types binding for innerclass emulation propagation
+		upperScope.referenceCompilationUnit().record((LocalTypeBinding)this.binding);
+	}
+	resolve();
+	updateMaxFieldCount();
+}
+
+/**
+ * Resolve a top level type declaration
+ */
+public void resolve(CompilationUnitScope upperScope) {
+	// top level : scope are already created
+	resolve();
+	updateMaxFieldCount();
+}
+
+public void tagAsHavingErrors() {
+	this.ignoreFurtherInvestigation = true;
+}
+
+public void tagAsHavingIgnoredMandatoryErrors(int problemId) {
+	// Nothing to do for this context;
+}
+
+/**
+ *	Iteration for a package member type
+ *
+ */
+public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope) {
+	try {
+		if (visitor.visit(this, unitScope)) {
+			if (this.javadoc != null) {
+				this.javadoc.traverse(visitor, this.scope);
+			}
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, this.staticInitializerScope);
+			}
+			if (this.superclass != null)
+				this.superclass.traverse(visitor, this.scope);
+			if (this.superInterfaces != null) {
+				int length = this.superInterfaces.length;
+				for (int i = 0; i < length; i++)
+					this.superInterfaces[i].traverse(visitor, this.scope);
+			}
+			if (this.typeParameters != null) {
+				int length = this.typeParameters.length;
+				for (int i = 0; i < length; i++) {
+					this.typeParameters[i].traverse(visitor, this.scope);
+				}
+			}
+			if (this.memberTypes != null) {
+				int length = this.memberTypes.length;
+				for (int i = 0; i < length; i++)
+					this.memberTypes[i].traverse(visitor, this.scope);
+			}
+			if (this.fields != null) {
+				int length = this.fields.length;
+				for (int i = 0; i < length; i++) {
+					FieldDeclaration field;
+					if ((field = this.fields[i]).isStatic()) {
+						field.traverse(visitor, this.staticInitializerScope);
+					} else {
+						field.traverse(visitor, this.initializerScope);
+					}
+				}
+			}
+			if (this.methods != null) {
+				int length = this.methods.length;
+				for (int i = 0; i < length; i++)
+					this.methods[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, unitScope);
+	} catch (AbortType e) {
+		// silent abort
+	}
+}
+
+/**
+ *	Iteration for a local inner type
+ */
+public void traverse(ASTVisitor visitor, BlockScope blockScope) {
+	try {
+		if (visitor.visit(this, blockScope)) {
+			if (this.javadoc != null) {
+				this.javadoc.traverse(visitor, this.scope);
+			}
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, this.staticInitializerScope);
+			}
+			if (this.superclass != null)
+				this.superclass.traverse(visitor, this.scope);
+			if (this.superInterfaces != null) {
+				int length = this.superInterfaces.length;
+				for (int i = 0; i < length; i++)
+					this.superInterfaces[i].traverse(visitor, this.scope);
+			}
+			if (this.typeParameters != null) {
+				int length = this.typeParameters.length;
+				for (int i = 0; i < length; i++) {
+					this.typeParameters[i].traverse(visitor, this.scope);
+				}
+			}
+			if (this.memberTypes != null) {
+				int length = this.memberTypes.length;
+				for (int i = 0; i < length; i++)
+					this.memberTypes[i].traverse(visitor, this.scope);
+			}
+			if (this.fields != null) {
+				int length = this.fields.length;
+				for (int i = 0; i < length; i++) {
+					FieldDeclaration field = this.fields[i];
+					if (field.isStatic() && !field.isFinal()) {
+						// local type cannot have static fields that are not final, https://bugs.eclipse.org/bugs/show_bug.cgi?id=244544
+					} else {
+						field.traverse(visitor, this.initializerScope);
+					}
+				}
+			}
+			if (this.methods != null) {
+				int length = this.methods.length;
+				for (int i = 0; i < length; i++)
+					this.methods[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	} catch (AbortType e) {
+		// silent abort
+	}
+}
+
+/**
+ *	Iteration for a member innertype
+ *
+ */
+public void traverse(ASTVisitor visitor, ClassScope classScope) {
+	try {
+		if (visitor.visit(this, classScope)) {
+			if (this.javadoc != null) {
+				this.javadoc.traverse(visitor, this.scope);
+			}
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, this.staticInitializerScope);
+			}
+			if (this.superclass != null)
+				this.superclass.traverse(visitor, this.scope);
+			if (this.superInterfaces != null) {
+				int length = this.superInterfaces.length;
+				for (int i = 0; i < length; i++)
+					this.superInterfaces[i].traverse(visitor, this.scope);
+			}
+			if (this.typeParameters != null) {
+				int length = this.typeParameters.length;
+				for (int i = 0; i < length; i++) {
+					this.typeParameters[i].traverse(visitor, this.scope);
+				}
+			}
+			if (this.memberTypes != null) {
+				int length = this.memberTypes.length;
+				for (int i = 0; i < length; i++)
+					this.memberTypes[i].traverse(visitor, this.scope);
+			}
+			if (this.fields != null) {
+				int length = this.fields.length;
+				for (int i = 0; i < length; i++) {
+					FieldDeclaration field;
+					if ((field = this.fields[i]).isStatic()) {
+						field.traverse(visitor, this.staticInitializerScope);
+					} else {
+						field.traverse(visitor, this.initializerScope);
+					}
+				}
+			}
+			if (this.methods != null) {
+				int length = this.methods.length;
+				for (int i = 0; i < length; i++)
+					this.methods[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, classScope);
+	} catch (AbortType e) {
+		// silent abort
+	}
+}
+
+/**
+ * MaxFieldCount's computation is necessary so as to reserve space for
+ * the flow info field portions. It corresponds to the maximum amount of
+ * fields this class or one of its innertypes have.
+ *
+ * During name resolution, types are traversed, and the max field count is recorded
+ * on the outermost type. It is then propagated down during the flow analysis.
+ *
+ * This method is doing either up/down propagation.
+ */
+void updateMaxFieldCount() {
+	if (this.binding == null)
+		return; // error scenario
+	TypeDeclaration outerMostType = this.scope.outerMostClassScope().referenceType();
+	if (this.maxFieldCount > outerMostType.maxFieldCount) {
+		outerMostType.maxFieldCount = this.maxFieldCount; // up
+	} else {
+		this.maxFieldCount = outerMostType.maxFieldCount; // down
+	}
+}
+
+/**
+ * Returns whether the type is a secondary one or not.
+ */
+public boolean isSecondary() {
+	return (this.bits & ASTNode.IsSecondaryType) != 0;
+}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
new file mode 100644
index 0000000..2408856
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+
+public class TypeParameter extends AbstractVariableDeclaration {
+
+    public TypeVariableBinding binding;
+	public TypeReference[] bounds;
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration#getKind()
+	 */
+	public int getKind() {
+		return TYPE_PARAMETER;
+	}
+
+	public void checkBounds(Scope scope) {
+
+		if (this.type != null) {
+			this.type.checkBounds(scope);
+		}
+		if (this.bounds != null) {
+			for (int i = 0, length = this.bounds.length; i < length; i++) {
+				this.bounds[i].checkBounds(scope);
+			}
+		}
+	}
+
+	public void getAllAnnotationContexts(int targetType, int typeParameterIndex, List allAnnotationContexts) {
+		AnnotationCollector collector = new AnnotationCollector(this, targetType, typeParameterIndex, allAnnotationContexts);
+		if (this.annotations != null) {
+			int annotationsLength = this.annotations.length;
+			for (int i = 0; i < annotationsLength; i++)
+				this.annotations[i].traverse(collector, (BlockScope) null);
+		}
+		switch(collector.targetType) {
+			case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
+				collector.targetType = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND;
+				break;
+			case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
+				collector.targetType = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND;
+		}
+		if (this.type != null && ((this.type.bits & ASTNode.HasTypeAnnotations) != 0)) {
+			collector.info2 = 0;
+			this.type.traverse(collector, (BlockScope) null);
+		}
+		if (this.bounds != null) {
+			int boundsLength = this.bounds.length;
+			for (int i = 0; i < boundsLength; i++) {
+				TypeReference bound = this.bounds[i];
+				if ((bound.bits & ASTNode.HasTypeAnnotations) == 0) {
+					continue;
+				}
+				collector.info2 = i + 1;
+				bound.traverse(collector, (BlockScope) null);
+			}
+		}
+	}
+	private void internalResolve(Scope scope, boolean staticContext) {
+	    // detect variable/type name collisions
+		if (this.binding != null) {
+			Binding existingType = scope.parent.getBinding(this.name, Binding.TYPE, this, false/*do not resolve hidden field*/);
+			if (existingType != null
+					&& this.binding != existingType
+					&& existingType.isValidBinding()
+					&& (existingType.kind() != Binding.TYPE_PARAMETER || !staticContext)) {
+				scope.problemReporter().typeHiding(this, existingType);
+			}
+		}
+		if (this.annotations != null) {
+			resolveAnnotations(scope);
+		}
+	}
+
+	public void resolve(BlockScope scope) {
+		internalResolve(scope, scope.methodScope().isStatic);
+	}
+
+	public void resolve(ClassScope scope) {
+		internalResolve(scope, scope.enclosingSourceType().isStatic());
+	}
+
+	public void resolveAnnotations(Scope scope) {
+		BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
+		if (resolutionScope != null) {
+			resolveAnnotations(resolutionScope, this.annotations, new Annotation.TypeUseBinding(Binding.TYPE_PARAMETER));
+		}	
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.AstNode#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		if (this.annotations != null) {
+			printAnnotations(this.annotations, output);
+			output.append(' ');
+		}
+		output.append(this.name);
+		if (this.type != null) {
+			output.append(" extends "); //$NON-NLS-1$
+			this.type.print(0, output);
+		}
+		if (this.bounds != null){
+			for (int i = 0; i < this.bounds.length; i++) {
+				output.append(" & "); //$NON-NLS-1$
+				this.bounds[i].print(0, output);
+			}
+		}
+		return output;
+	}
+
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+	    // nothing to do
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, scope);
+			}
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.bounds != null) {
+				int boundsLength = this.bounds.length;
+				for (int i = 0; i < boundsLength; i++) {
+					this.bounds[i].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.annotations != null) {
+				int annotationsLength = this.annotations.length;
+				for (int i = 0; i < annotationsLength; i++)
+					this.annotations[i].traverse(visitor, scope);
+			}
+			if (this.type != null) {
+				this.type.traverse(visitor, scope);
+			}
+			if (this.bounds != null) {
+				int boundsLength = this.bounds.length;
+				for (int i = 0; i < boundsLength; i++) {
+					this.bounds[i].traverse(visitor, scope);
+				}
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
new file mode 100644
index 0000000..3a2d918
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -0,0 +1,626 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationContext;
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+public abstract class TypeReference extends Expression {
+	public static final TypeReference[] NO_TYPE_ARGUMENTS = new TypeReference[0];
+static class AnnotationCollector extends ASTVisitor {
+	List annotationContexts;
+	TypeReference typeReference;
+	int targetType;
+	Annotation[] primaryAnnotations;
+	int info = -1;
+	int info2 = -1;
+	LocalVariableBinding localVariable;
+	Annotation[][] annotationsOnDimensions;
+	int dimensions;
+	Wildcard currentWildcard;
+
+	public AnnotationCollector(
+			TypeParameter typeParameter,
+			int targetType,
+			int typeParameterIndex,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = typeParameter.type;
+		this.targetType = targetType;
+		this.primaryAnnotations = typeParameter.annotations;
+		this.info = typeParameterIndex;
+	}
+
+	public AnnotationCollector(
+			LocalDeclaration localDeclaration,
+			int targetType,
+			LocalVariableBinding localVariable,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = localDeclaration.type;
+		this.targetType = targetType;
+		this.primaryAnnotations = localDeclaration.annotations;
+		this.localVariable = localVariable;
+	}
+
+	public AnnotationCollector(
+			LocalDeclaration localDeclaration,
+			int targetType,
+			int parameterIndex,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = localDeclaration.type;
+		this.targetType = targetType;
+		this.primaryAnnotations = localDeclaration.annotations;
+		this.info = parameterIndex;
+	}
+
+	public AnnotationCollector(
+			MethodDeclaration methodDeclaration,
+			int targetType,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = methodDeclaration.returnType;
+		this.targetType = targetType;
+		this.primaryAnnotations = methodDeclaration.annotations;
+	}
+
+	public AnnotationCollector(
+			FieldDeclaration fieldDeclaration,
+			int targetType,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = fieldDeclaration.type;
+		this.targetType = targetType;
+		this.primaryAnnotations = fieldDeclaration.annotations;
+	}
+	public AnnotationCollector(
+			TypeReference typeReference,
+			int targetType,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = typeReference;
+		this.targetType = targetType;
+	}
+	public AnnotationCollector(
+			TypeReference typeReference,
+			int targetType,
+			int info,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = typeReference;
+		this.info = info;
+		this.targetType = targetType;
+	}
+	public AnnotationCollector(
+			TypeReference typeReference,
+			int targetType,
+			int info,
+			int typeIndex,
+			List annotationContexts) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = typeReference;
+		this.info = info;
+		this.targetType = targetType;
+		this.info2 = typeIndex;
+	}
+	public AnnotationCollector(
+			TypeReference typeReference,
+			int targetType,
+			int info,
+			List annotationContexts,
+			Annotation[][] annotationsOnDimensions,
+			int dimensions) {
+		this.annotationContexts = annotationContexts;
+		this.typeReference = typeReference;
+		this.info = info;
+		this.targetType = targetType;
+		this.annotationsOnDimensions = annotationsOnDimensions;
+		// Array references like 'new String[]' manifest as an ArrayAllocationExpression
+		// with a 'type' of String.  When the type is not carrying the dimensions count
+		// it is passed in via the dimensions parameter.  It is not possible to use
+		// annotationsOnDimensions as it will be null if there are no annotations on any
+		// of the dimensions.
+		this.dimensions = dimensions;
+	}
+	
+	private boolean internalVisit(Annotation annotation) {
+		AnnotationContext annotationContext = null;
+		if (annotation.isRuntimeTypeInvisible()) {
+			annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.INVISIBLE, this.annotationsOnDimensions, this.dimensions);
+		} else if (annotation.isRuntimeTypeVisible()) {
+			annotationContext = new AnnotationContext(annotation, this.typeReference, this.targetType, this.primaryAnnotations, AnnotationContext.VISIBLE, this.annotationsOnDimensions, this.dimensions);
+		}
+		if (annotationContext != null) {
+			annotationContext.wildcard = this.currentWildcard;
+			switch(this.targetType) {
+				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER :
+				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER :
+				case AnnotationTargetTypeConstants.CLASS_EXTENDS:
+				case AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER :
+				case AnnotationTargetTypeConstants.THROWS :
+				case AnnotationTargetTypeConstants.EXCEPTION_PARAMETER :
+				case AnnotationTargetTypeConstants.INSTANCEOF:
+				case AnnotationTargetTypeConstants.NEW :
+				case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE :
+				case AnnotationTargetTypeConstants.METHOD_REFERENCE :
+				case AnnotationTargetTypeConstants.CAST:
+					annotationContext.info = this.info;
+					break;
+				case AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND :
+				case AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND :
+					annotationContext.info2 = this.info2;
+					annotationContext.info = this.info;
+					break;
+				case AnnotationTargetTypeConstants.LOCAL_VARIABLE :
+				case AnnotationTargetTypeConstants.RESOURCE_VARIABLE :
+					annotationContext.variableBinding = this.localVariable;
+					break;
+				case AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+				case AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+				case AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+				case AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+					annotationContext.info2 = this.info2;
+					annotationContext.info = this.info;
+					break;
+				case AnnotationTargetTypeConstants.FIELD :
+				case AnnotationTargetTypeConstants.METHOD_RETURN :
+				case AnnotationTargetTypeConstants.METHOD_RECEIVER :
+					break;
+					
+			}
+			this.annotationContexts.add(annotationContext);
+		}
+		return true;
+	}
+	public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
+		return internalVisit(annotation);
+	}
+	public boolean visit(NormalAnnotation annotation, BlockScope scope) {
+		return internalVisit(annotation);
+	}
+	public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
+		return internalVisit(annotation);
+	}
+	public boolean visit(Wildcard wildcard, BlockScope scope) {
+		this.currentWildcard = wildcard;
+		return true;
+	}
+	public boolean visit(Argument argument, BlockScope scope) {
+		if ((argument.bits & ASTNode.IsUnionType) == 0) {
+			return true;
+		}
+		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+			int startPC = this.localVariable.initializationPCs[i << 1];
+			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+			if (startPC != endPC) { // only entries for non zero length
+				return true;
+			}
+		}
+		return false;
+	}
+	public boolean visit(Argument argument, ClassScope scope) {
+		if ((argument.bits & ASTNode.IsUnionType) == 0) {
+			return true;
+		}
+		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+			int startPC = this.localVariable.initializationPCs[i << 1];
+			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+			if (startPC != endPC) { // only entries for non zero length
+				return true;
+			}
+		}
+		return false;
+	}
+	public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
+		for (int i = 0, max = this.localVariable.initializationCount; i < max; i++) {
+			int startPC = this.localVariable.initializationPCs[i << 1];
+			int endPC = this.localVariable.initializationPCs[(i << 1) + 1];
+			if (startPC != endPC) { // only entries for non zero length
+				return true;
+			}
+		}
+		return false;
+	}
+	public void endVisit(Wildcard wildcard, BlockScope scope) {
+		this.currentWildcard = null;
+	}
+}
+/*
+ * Answer a base type reference (can be an array of base type).
+ */
+public static final TypeReference baseTypeReference(int baseType, int dim, Annotation [][] dimAnnotations) {
+
+	if (dim == 0) {
+		switch (baseType) {
+			case (TypeIds.T_void) :
+				return new SingleTypeReference(TypeBinding.VOID.simpleName, 0);
+			case (TypeIds.T_boolean) :
+				return new SingleTypeReference(TypeBinding.BOOLEAN.simpleName, 0);
+			case (TypeIds.T_char) :
+				return new SingleTypeReference(TypeBinding.CHAR.simpleName, 0);
+			case (TypeIds.T_float) :
+				return new SingleTypeReference(TypeBinding.FLOAT.simpleName, 0);
+			case (TypeIds.T_double) :
+				return new SingleTypeReference(TypeBinding.DOUBLE.simpleName, 0);
+			case (TypeIds.T_byte) :
+				return new SingleTypeReference(TypeBinding.BYTE.simpleName, 0);
+			case (TypeIds.T_short) :
+				return new SingleTypeReference(TypeBinding.SHORT.simpleName, 0);
+			case (TypeIds.T_int) :
+				return new SingleTypeReference(TypeBinding.INT.simpleName, 0);
+			default : //T_long
+				return new SingleTypeReference(TypeBinding.LONG.simpleName, 0);
+		}
+	}
+	switch (baseType) {
+		case (TypeIds.T_void) :
+			return new ArrayTypeReference(TypeBinding.VOID.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_boolean) :
+			return new ArrayTypeReference(TypeBinding.BOOLEAN.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_char) :
+			return new ArrayTypeReference(TypeBinding.CHAR.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_float) :
+			return new ArrayTypeReference(TypeBinding.FLOAT.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_double) :
+			return new ArrayTypeReference(TypeBinding.DOUBLE.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_byte) :
+			return new ArrayTypeReference(TypeBinding.BYTE.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_short) :
+			return new ArrayTypeReference(TypeBinding.SHORT.simpleName, dim, dimAnnotations, 0);
+		case (TypeIds.T_int) :
+			return new ArrayTypeReference(TypeBinding.INT.simpleName, dim, dimAnnotations, 0);
+		default : //T_long
+			return new ArrayTypeReference(TypeBinding.LONG.simpleName, dim, dimAnnotations, 0);
+	}
+}
+
+// JSR308 type annotations...
+public Annotation[][] annotations = null;
+
+// allows us to trap completion & selection nodes
+public void aboutToResolve(Scope scope) {
+	// default implementation: do nothing
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	return flowInfo;
+}
+public void checkBounds(Scope scope) {
+	// only parameterized type references have bounds
+}
+public abstract TypeReference copyDims(int dim);
+public abstract TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions);
+public int dimensions() {
+	return 0;
+}
+public AnnotationContext[] getAllAnnotationContexts(int targetType) {
+	List allAnnotationContexts = new ArrayList();
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
+	this.traverse(collector, (BlockScope) null);
+	return (AnnotationContext[]) allAnnotationContexts.toArray(new AnnotationContext[allAnnotationContexts.size()]);
+}
+/**
+ * info can be either a type index (superclass/superinterfaces) or a pc into the bytecode
+ * @param targetType
+ * @param info
+ * @param allAnnotationContexts
+ */
+public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts) {
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts);
+	this.traverse(collector, (BlockScope) null);
+}
+/**
+ * info can be either a type index (superclass/superinterfaces) or a pc into the bytecode
+ */
+public void getAllAnnotationContexts(int targetType, int info, List allAnnotationContexts, Annotation[][] annotationsOnDimensions, int dimensions) {
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allAnnotationContexts, annotationsOnDimensions, dimensions);
+	this.traverse(collector, (BlockScope) null);
+	if (annotationsOnDimensions != null) {
+		for (int i = 0, max = annotationsOnDimensions.length; i < max; i++) {
+			Annotation[] annotationsOnDimension = annotationsOnDimensions[i];
+			if (annotationsOnDimension != null) {
+				for (int j = 0, max2 = annotationsOnDimension.length; j< max2; j++) {
+					annotationsOnDimension[j].traverse(collector, (BlockScope) null);
+				}
+			}
+		}
+	}
+}
+public void getAllAnnotationContexts(int targetType, int info, int typeIndex, List allAnnotationContexts) {
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, info, typeIndex, allAnnotationContexts);
+	this.traverse(collector, (BlockScope) null);
+}
+public void getAllAnnotationContexts(int targetType, List allAnnotationContexts) {
+	AnnotationCollector collector = new AnnotationCollector(this, targetType, allAnnotationContexts);
+	this.traverse(collector, (BlockScope) null);
+}
+public Annotation[][] getAnnotationsOnDimensions() {
+	return null;
+}
+
+public void setAnnotationsOnDimensions(Annotation [][] annotationsOnDimensions) {
+	// nothing to do. Subtypes should react suitably.
+}
+
+public abstract char[] getLastToken();
+
+/**
+ * @return char[][]
+ * TODO (jerome) should merge back into #getTypeName()
+ */
+public char [][] getParameterizedTypeName(){
+	return getTypeName();
+}
+protected abstract TypeBinding getTypeBinding(Scope scope);
+/**
+ * @return char[][]
+ */
+public abstract char [][] getTypeName() ;
+
+protected TypeBinding internalResolveType(Scope scope) {
+	// handle the error here
+	this.constant = Constant.NotAConstant;
+	if (this.resolvedType != null) { // is a shared type reference which was already resolved
+		if (this.resolvedType.isValidBinding()) {
+			return this.resolvedType;
+		} else {
+			switch (this.resolvedType.problemId()) {
+				case ProblemReasons.NotFound :
+				case ProblemReasons.NotVisible :
+				case ProblemReasons.InheritedNameHidesEnclosingName :
+					TypeBinding type = this.resolvedType.closestMatch();
+					if (type == null) return null;
+					return scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
+				default :
+					return null;
+			}
+		}
+	}
+	boolean hasError;
+	TypeBinding type = this.resolvedType = getTypeBinding(scope);
+	if (type == null) {
+		return null; // detected cycle while resolving hierarchy
+	} else if ((hasError = !type.isValidBinding()) == true) {
+		reportInvalidType(scope);
+		switch (type.problemId()) {
+			case ProblemReasons.NotFound :
+			case ProblemReasons.NotVisible :
+			case ProblemReasons.InheritedNameHidesEnclosingName :
+				type = type.closestMatch();
+				if (type == null) return null;
+				break;
+			default :
+				return null;
+		}
+	}
+	if (type.isArrayType() && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
+		scope.problemReporter().cannotAllocateVoidArray(this);
+		return null;
+	}
+	if (!(this instanceof QualifiedTypeReference)   // QualifiedTypeReference#getTypeBinding called above will have already checked deprecation
+			&& isTypeUseDeprecated(type, scope)) {
+		reportDeprecatedType(type, scope);
+	}
+	type = scope.environment().convertToRawType(type, false /*do not force conversion of enclosing types*/);
+	if (type.leafComponentType().isRawType()
+			&& (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
+			&& scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
+		scope.problemReporter().rawTypeReference(this, type);
+	}
+	if (hasError) {
+		resolveAnnotations(scope);		
+		return type;
+	} else {
+		// store the computed type only if no error, otherwise keep the problem type instead
+		this.resolvedType = type;
+		resolveAnnotations(scope);
+		return this.resolvedType; // pick up value that may have been changed in resolveAnnotations(..)
+	}
+}
+public boolean isTypeReference() {
+	return true;
+}
+public boolean isWildcard() {
+	return false;
+}
+public boolean isParameterizedTypeReference() {
+	return false;
+}
+protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
+	scope.problemReporter().deprecatedType(type, this, index);
+}
+
+protected void reportDeprecatedType(TypeBinding type, Scope scope) {
+	scope.problemReporter().deprecatedType(type, this, Integer.MAX_VALUE);
+}
+
+protected void reportInvalidType(Scope scope) {
+	scope.problemReporter().invalidType(this, this.resolvedType);
+}
+
+public TypeBinding resolveSuperType(ClassScope scope) {
+	// assumes the implementation of resolveType(ClassScope) will call back to detect cycles
+	TypeBinding superType = resolveType(scope);
+	if (superType == null) return null;
+
+	if (superType.isTypeVariable()) {
+		if (this.resolvedType.isValidBinding()) {
+			this.resolvedType = new ProblemReferenceBinding(getTypeName(), (ReferenceBinding)this.resolvedType, ProblemReasons.IllegalSuperTypeVariable);
+			reportInvalidType(scope);
+		}
+		return null;
+	}
+	return superType;
+}
+
+public final TypeBinding resolveType(BlockScope blockScope) {
+	return resolveType(blockScope, true /* checkbounds if any */);
+}
+
+public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+	return internalResolveType(scope);
+}
+
+public TypeBinding resolveType(ClassScope scope) {
+	return internalResolveType(scope);
+}
+
+public TypeBinding resolveTypeArgument(BlockScope blockScope, ReferenceBinding genericType, int rank) {
+    return resolveType(blockScope, true /* check bounds*/);
+}
+
+public TypeBinding resolveTypeArgument(ClassScope classScope, ReferenceBinding genericType, int rank) {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057, circularity is allowed when we are
+	// resolving type arguments i.e interface A<T extends C> {}	interface B extends A<D> {}
+	// interface D extends C {}	interface C extends B {}
+	ReferenceBinding ref = classScope.referenceContext.binding;
+	boolean pauseHierarchyCheck = false;
+	try {
+		if (ref.isHierarchyBeingConnected()) {
+			ref.tagBits |= TagBits.PauseHierarchyCheck;
+			pauseHierarchyCheck = true;
+		}
+	    return resolveType(classScope);
+	} finally {
+		if (pauseHierarchyCheck) {
+			ref.tagBits &= ~TagBits.PauseHierarchyCheck;
+		}
+	}
+}
+
+public abstract void traverse(ASTVisitor visitor, BlockScope scope);
+
+public abstract void traverse(ASTVisitor visitor, ClassScope scope);
+
+protected void resolveAnnotations(Scope scope) {
+	Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions();
+	if (this.annotations != null || annotationsOnDimensions != null) {
+		BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
+		if (resolutionScope != null) {
+			long[] tagBitsPerDimension = null;
+			int dimensions = this.dimensions();
+			boolean shouldAnalyzeArrayNullAnnotations = scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled && this instanceof ArrayTypeReference;
+			if (this.annotations != null) {
+				int annotationsLevels = this.annotations.length;
+				for (int i = 0; i < annotationsLevels; i++) {
+					Annotation[] currentAnnotations = this.annotations[i];
+					if (currentAnnotations != null) {
+						resolveAnnotations(resolutionScope, currentAnnotations, new Annotation.TypeUseBinding(isWildcard() ? Binding.TYPE_PARAMETER : Binding.TYPE_USE));
+						if (shouldAnalyzeArrayNullAnnotations) {
+							int len = currentAnnotations.length;
+							for (int j=0; j<len; j++) {
+								Binding recipient = currentAnnotations[j].recipient;
+								if (recipient instanceof Annotation.TypeUseBinding) {
+									if (tagBitsPerDimension == null)
+										tagBitsPerDimension = new long[dimensions+1]; // each dimension plus leaf component type at last position
+									// @NonNull Foo [][][] means the leaf component type is @NonNull:
+									tagBitsPerDimension[dimensions] = ((Annotation.TypeUseBinding)recipient).tagBits & TagBits.AnnotationNullMASK;
+								}
+							}
+						}
+					}
+				}
+			}
+
+			if (annotationsOnDimensions != null) {
+				for (int i = 0, length = annotationsOnDimensions.length; i < length; i++) {
+					Annotation [] dimensionAnnotations = annotationsOnDimensions[i];
+					if (dimensionAnnotations  != null) {
+						resolveAnnotations(resolutionScope, dimensionAnnotations, new Annotation.TypeUseBinding(Binding.TYPE_USE));
+						if (shouldAnalyzeArrayNullAnnotations) {
+							int len = dimensionAnnotations.length;
+							for (int j=0; j<len; j++) {
+								Binding recipient = dimensionAnnotations[j].recipient;
+								if (recipient instanceof Annotation.TypeUseBinding) {
+									if (tagBitsPerDimension == null)
+										tagBitsPerDimension = new long[dimensions+1];
+									tagBitsPerDimension[i] = ((Annotation.TypeUseBinding)recipient).tagBits & TagBits.AnnotationNullMASK;
+								}
+							}
+						}
+					}
+				}
+			}
+			if (tagBitsPerDimension != null && this.resolvedType.isValidBinding()) {
+				// TODO(stephan): wouldn't it be more efficient to store the array bindings inside the type binding rather than the environment?
+				// cf. LocalTypeBinding.createArrayType()
+				this.resolvedType = scope.environment().createArrayType(this.resolvedType.leafComponentType(), dimensions, tagBitsPerDimension);
+			}
+		}
+	}
+}
+public int getAnnotatableLevels() {
+	return 1;
+}
+// If typeArgumentAnnotations contain any that are evaluated by the compiler
+// create/retrieve a parameterized type binding
+// capturing the effect of these annotations into the resolved type binding.
+protected TypeBinding captureTypeAnnotations(Scope scope, ReferenceBinding enclosingType, TypeBinding argType, Annotation[] typeArgumentAnnotations) {
+	if (!scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled
+			|| typeArgumentAnnotations == null 
+			|| !(argType instanceof ReferenceBinding))
+	{
+		return argType;
+	}
+    int annotLen = typeArgumentAnnotations.length;
+    long annotationBits = 0L;
+    for (int i = 0; i < annotLen; i++) {
+		if (typeArgumentAnnotations[i] instanceof MarkerAnnotation) {
+			AnnotationBinding compilerAnnotation = ((MarkerAnnotation)typeArgumentAnnotations[i]).getCompilerAnnotation();
+			if (compilerAnnotation != null) {
+				switch (compilerAnnotation.getAnnotationType().id) {
+					case TypeIds.T_ConfiguredAnnotationNonNull :
+						annotationBits |= TagBits.AnnotationNonNull;
+						break;
+					case TypeIds.T_ConfiguredAnnotationNullable :
+						annotationBits |= TagBits.AnnotationNullable;
+						break;
+					default: // no other annotations are currently handled
+				}
+			}
+		}
+	}
+    if (annotationBits == 0L)
+    	return argType;
+	return scope.environment().createParameterizedType((ReferenceBinding) argType, null, annotationBits, enclosingType);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
new file mode 100644
index 0000000..ed03863
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class UnaryExpression extends OperatorExpression {
+
+	public Expression expression;
+	public Constant optimizedBooleanConstant;
+
+	public UnaryExpression(Expression expression, int operator) {
+		this.expression = expression;
+		this.bits |= operator << OperatorSHIFT; // encode operator
+	}
+
+public FlowInfo analyseCode(
+		BlockScope currentScope,
+		FlowContext flowContext,
+		FlowInfo flowInfo) {
+	this.expression.checkNPE(currentScope, flowContext, flowInfo);
+	if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT) {
+		flowContext.tagBits ^= FlowContext.INSIDE_NEGATION;
+		flowInfo = this.expression.
+			analyseCode(currentScope, flowContext, flowInfo).
+			asNegatedCondition();
+		flowContext.tagBits ^= FlowContext.INSIDE_NEGATION;
+		return flowInfo;
+	} else {
+		return this.expression.
+			analyseCode(currentScope, flowContext, flowInfo);
+	}
+}
+
+	public Constant optimizedBooleanConstant() {
+
+		return this.optimizedBooleanConstant == null
+				? this.constant
+				: this.optimizedBooleanConstant;
+	}
+
+	/**
+	 * Code generation for an unary operation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 * @param valueRequired boolean
+	 */
+	public void generateCode(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		boolean valueRequired) {
+
+		int pc = codeStream.position;
+		BranchLabel falseLabel, endifLabel;
+		if (this.constant != Constant.NotAConstant) {
+			// inlined value
+			if (valueRequired) {
+				codeStream.generateConstant(this.constant, this.implicitConversion);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+		switch ((this.bits & OperatorMASK) >> OperatorSHIFT) {
+			case NOT :
+				switch ((this.expression.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) /* runtime type */ {
+					case T_boolean :
+						// ! <boolean>
+						// Generate code for the condition
+						this.expression.generateOptimizedBoolean(
+							currentScope,
+							codeStream,
+							null,
+							(falseLabel = new BranchLabel(codeStream)),
+							valueRequired);
+						if (valueRequired) {
+							codeStream.iconst_0();
+							if (falseLabel.forwardReferenceCount() > 0) {
+								codeStream.goto_(endifLabel = new BranchLabel(codeStream));
+								codeStream.decrStackSize(1);
+								falseLabel.place();
+								codeStream.iconst_1();
+								endifLabel.place();
+							}
+						} else { // 6596: if (!(a && b)){} - must still place falseLabel
+							falseLabel.place();
+						}
+						break;
+				}
+				break;
+			case TWIDDLE :
+				switch ((this.expression.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4 /* runtime */) {
+					case T_int :
+						// ~int
+						this.expression.generateCode(currentScope, codeStream, valueRequired);
+						if (valueRequired) {
+							codeStream.iconst_m1();
+							codeStream.ixor();
+						}
+						break;
+					case T_long :
+						this.expression.generateCode(currentScope, codeStream, valueRequired);
+						if (valueRequired) {
+							codeStream.ldc2_w(-1L);
+							codeStream.lxor();
+						}
+				}
+				break;
+			case MINUS :
+				// - <num>
+				if (this.constant != Constant.NotAConstant) {
+					if (valueRequired) {
+						switch ((this.expression.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4){ /* runtime */
+							case T_int :
+								codeStream.generateInlinedValue(this.constant.intValue() * -1);
+								break;
+							case T_float :
+								codeStream.generateInlinedValue(this.constant.floatValue() * -1.0f);
+								break;
+							case T_long :
+								codeStream.generateInlinedValue(this.constant.longValue() * -1L);
+								break;
+							case T_double :
+								codeStream.generateInlinedValue(this.constant.doubleValue() * -1.0);
+						}
+					}
+				} else {
+					this.expression.generateCode(currentScope, codeStream, valueRequired);
+					if (valueRequired) {
+						switch ((this.expression.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4){ /* runtime type */
+							case T_int :
+								codeStream.ineg();
+								break;
+							case T_float :
+								codeStream.fneg();
+								break;
+							case T_long :
+								codeStream.lneg();
+								break;
+							case T_double :
+								codeStream.dneg();
+						}
+					}
+				}
+				break;
+			case PLUS :
+				this.expression.generateCode(currentScope, codeStream, valueRequired);
+		}
+		if (valueRequired) {
+			codeStream.generateImplicitConversion(this.implicitConversion);
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	/**
+	 * Boolean operator code generation
+	 *	Optimized operations are: &&, ||, <, <=, >, >=, &, |, ^
+	 */
+	public void generateOptimizedBoolean(
+		BlockScope currentScope,
+		CodeStream codeStream,
+		BranchLabel trueLabel,
+		BranchLabel falseLabel,
+		boolean valueRequired) {
+
+		if ((this.constant != Constant.NotAConstant) && (this.constant.typeID() == T_boolean)) {
+			super.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+			return;
+		}
+		if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT) {
+			this.expression.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				falseLabel,
+				trueLabel,
+				valueRequired);
+		} else {
+			super.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				trueLabel,
+				falseLabel,
+				valueRequired);
+		}
+	}
+
+	public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
+
+		output.append(operatorToString()).append(' ');
+		return this.expression.printExpression(0, output);
+	}
+
+	public TypeBinding resolveType(BlockScope scope) {
+		boolean expressionIsCast;
+		if ((expressionIsCast = this.expression instanceof CastExpression) == true) this.expression.bits |= DisableUnnecessaryCastCheck; // will check later on
+		TypeBinding expressionType = this.expression.resolveType(scope);
+		if (expressionType == null) {
+			this.constant = Constant.NotAConstant;
+			return null;
+		}
+		int expressionTypeID = expressionType.id;
+		// autoboxing support
+		boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		if (use15specifics) {
+			if (!expressionType.isBaseType()) {
+				expressionTypeID = scope.environment().computeBoxingType(expressionType).id;
+			}
+		}
+		if (expressionTypeID > 15) {
+			this.constant = Constant.NotAConstant;
+			scope.problemReporter().invalidOperator(this, expressionType);
+			return null;
+		}
+
+		int tableId;
+		switch ((this.bits & OperatorMASK) >> OperatorSHIFT) {
+			case NOT :
+				tableId = AND_AND;
+				break;
+			case TWIDDLE :
+				tableId = LEFT_SHIFT;
+				break;
+			default :
+				tableId = MINUS;
+		} //+ and - cases
+
+		// the code is an int
+		// (cast)  left   Op (cast)  rigth --> result
+		//  0000   0000       0000   0000      0000
+		//  <<16   <<12       <<8    <<4       <<0
+		int operatorSignature = OperatorSignatures[tableId][(expressionTypeID << 4) + expressionTypeID];
+		this.expression.computeConversion(scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), expressionType);
+		this.bits |= operatorSignature & 0xF;
+		switch (operatorSignature & 0xF) { // only switch on possible result type.....
+			case T_boolean :
+				this.resolvedType = TypeBinding.BOOLEAN;
+				break;
+			case T_byte :
+				this.resolvedType = TypeBinding.BYTE;
+				break;
+			case T_char :
+				this.resolvedType = TypeBinding.CHAR;
+				break;
+			case T_double :
+				this.resolvedType = TypeBinding.DOUBLE;
+				break;
+			case T_float :
+				this.resolvedType = TypeBinding.FLOAT;
+				break;
+			case T_int :
+				this.resolvedType = TypeBinding.INT;
+				break;
+			case T_long :
+				this.resolvedType = TypeBinding.LONG;
+				break;
+			default : //error........
+				this.constant = Constant.NotAConstant;
+				if (expressionTypeID != T_undefined)
+					scope.problemReporter().invalidOperator(this, expressionType);
+				return null;
+		}
+		// compute the constant when valid
+		if (this.expression.constant != Constant.NotAConstant) {
+			this.constant =
+				Constant.computeConstantOperation(
+					this.expression.constant,
+					expressionTypeID,
+					(this.bits & OperatorMASK) >> OperatorSHIFT);
+		} else {
+			this.constant = Constant.NotAConstant;
+			if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT) {
+				Constant cst = this.expression.optimizedBooleanConstant();
+				if (cst != Constant.NotAConstant)
+					this.optimizedBooleanConstant = BooleanConstant.fromValue(!cst.booleanValue());
+			}
+		}
+		if (expressionIsCast) {
+		// check need for operand cast
+			CastExpression.checkNeedForArgumentCast(scope, tableId, operatorSignature, this.expression, expressionTypeID);
+		}
+		return this.resolvedType;
+	}
+
+	public void traverse(
+    		ASTVisitor visitor,
+    		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.expression.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java
new file mode 100644
index 0000000..9a4e07c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class UnionTypeReference extends TypeReference {
+	public TypeReference[] typeReferences;
+
+	public UnionTypeReference(TypeReference[] typeReferences) {
+		this.bits |= ASTNode.IsUnionType;
+		this.typeReferences = typeReferences;
+		this.sourceStart = typeReferences[0].sourceStart;
+		int length = typeReferences.length;
+		this.sourceEnd = typeReferences[length - 1].sourceEnd;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
+	 */
+	public TypeReference copyDims(int dim) {
+		return this; // arrays are not legal as union types.
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getLastToken()
+	 */
+	public char[] getLastToken() {
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding getTypeBinding(Scope scope) {
+		return null; // not supported here - combined with resolveType(...)
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		// return the lub (least upper bound of all type binding) 
+		int length = this.typeReferences.length;
+		TypeBinding[] allExceptionTypes = new TypeBinding[length];
+		boolean hasError = false;
+		for (int i = 0; i < length; i++) {
+			TypeBinding exceptionType = this.typeReferences[i].resolveType(scope, checkBounds);
+			if (exceptionType == null) {
+				return null;
+			}
+			switch(exceptionType.kind()) {
+				case Binding.PARAMETERIZED_TYPE :
+					if (exceptionType.isBoundParameterizedType()) {
+						hasError = true;
+						scope.problemReporter().invalidParameterizedExceptionType(exceptionType, this.typeReferences[i]);
+						// fall thru to create the variable - avoids additional errors because the variable is missing
+					}
+					break;
+				case Binding.TYPE_PARAMETER :
+					scope.problemReporter().invalidTypeVariableAsException(exceptionType, this.typeReferences[i]);
+					hasError = true;
+					// fall thru to create the variable - avoids additional errors because the variable is missing
+					break;
+			}
+			if (exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null
+					&& exceptionType.isValidBinding()) {
+				scope.problemReporter().cannotThrowType(this.typeReferences[i], exceptionType);
+				hasError = true;
+			}
+			allExceptionTypes[i] = exceptionType;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=340486, ensure types are of union type.
+			for (int j = 0; j < i; j++) {
+				if (allExceptionTypes[j].isCompatibleWith(exceptionType)) {
+					scope.problemReporter().wrongSequenceOfExceptionTypes(
+							this.typeReferences[j],
+							allExceptionTypes[j],
+							exceptionType);
+					hasError = true;
+				} else if (exceptionType.isCompatibleWith(allExceptionTypes[j])) {
+					scope.problemReporter().wrongSequenceOfExceptionTypes(
+							this.typeReferences[i],
+							exceptionType,
+							allExceptionTypes[j]);
+					hasError = true;
+				}
+			}
+		}
+		if (hasError) {
+			return null;
+		}
+		// compute lub
+		return (this.resolvedType = scope.lowerUpperBound(allExceptionTypes));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
+	 */
+	public char[][] getTypeName() {
+		// we need to keep a return value that is a char[][]
+		return this.typeReferences[0].getTypeName();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+			for (int i = 0; i < length; i++) {
+				this.typeReferences[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+			for (int i = 0; i < length; i++) {
+				this.typeReferences[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+		printIndent(indent, output);
+		for (int i = 0; i < length; i++) {
+			this.typeReferences[i].printExpression(0, output);
+			if (i != length - 1) {
+				output.append(" | "); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+	public TypeReference copyDims(int dim, Annotation[][] annotationsOnDimensions) {
+		return this; // arrays are not legal as union types.
+	}
+
+}
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
new file mode 100644
index 0000000..837f432
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for 
+ *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.*;
+import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class WhileStatement extends Statement {
+
+	public Expression condition;
+	public Statement action;
+	private BranchLabel breakLabel, continueLabel;
+	int preCondInitStateIndex = -1;
+	int condIfTrueInitStateIndex = -1;
+	int mergedInitStateIndex = -1;
+
+	public WhileStatement(Expression condition, Statement action, int s, int e) {
+
+		this.condition = condition;
+		this.action = action;
+		// remember useful empty statement
+		if (action instanceof EmptyStatement) action.bits |= IsUsefulEmptyStatement;
+		this.sourceStart = s;
+		this.sourceEnd = e;
+	}
+
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+
+		this.breakLabel = new BranchLabel();
+		this.continueLabel = new BranchLabel();
+		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
+
+		Constant cst = this.condition.constant;
+		boolean isConditionTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+		boolean isConditionFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+		cst = this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
+		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+
+		this.preCondInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
+		LoopingFlowContext condLoopContext;
+		FlowInfo condInfo =	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
+		// or catch blocks
+		condInfo = this.condition.analyseCode(
+				currentScope,
+				(condLoopContext =
+					new LoopingFlowContext(flowContext, flowInfo, this, null,
+						null, currentScope, true)),
+				condInfo);
+		this.condition.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+
+		LoopingFlowContext loopingContext;
+		FlowInfo actionInfo;
+		FlowInfo exitBranch;
+		if (this.action == null
+			|| (this.action.isEmptyBlock() && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3)) {
+			condLoopContext.complainOnDeferredFinalChecks(currentScope,
+					condInfo);
+			condLoopContext.complainOnDeferredNullChecks(currentScope,
+				condInfo.unconditionalInits());
+			if (isConditionTrue) {
+				return FlowInfo.DEAD_END;
+			} else {
+				FlowInfo mergedInfo = flowInfo.copy().addInitializationsFrom(condInfo.initsWhenFalse());
+				if (isConditionOptimizedTrue){
+					mergedInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+				}
+				this.mergedInitStateIndex =
+					currentScope.methodScope().recordInitializationStates(mergedInfo);
+				return mergedInfo;
+			}
+		} else {
+			// in case the condition was inlined to false, record the fact that there is no way to reach any
+			// statement inside the looping action
+			loopingContext =
+				new LoopingFlowContext(
+					flowContext,
+					flowInfo,
+					this,
+					this.breakLabel,
+					this.continueLabel,
+					currentScope,
+					true);
+			if (isConditionFalse) {
+				actionInfo = FlowInfo.DEAD_END;
+			} else {
+				actionInfo = condInfo.initsWhenTrue().copy();
+				if (isConditionOptimizedFalse){
+					actionInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
+				}
+			}
+
+			// for computing local var attributes
+			this.condIfTrueInitStateIndex =
+				currentScope.methodScope().recordInitializationStates(
+					condInfo.initsWhenTrue());
+
+			if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
+				actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo);
+			}
+
+			// code generation can be optimized when no need to continue in the loop
+			exitBranch = flowInfo.copy();
+			// need to start over from flowInfo so as to get null inits
+            int combinedTagBits = actionInfo.tagBits & loopingContext.initsOnContinue.tagBits;
+			if ((combinedTagBits & FlowInfo.UNREACHABLE) != 0) {
+				if ((combinedTagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0)
+					this.continueLabel = null;
+				exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
+			} else {
+				condLoopContext.complainOnDeferredFinalChecks(currentScope,
+						condInfo);
+				actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue.unconditionalInits());
+				condLoopContext.complainOnDeferredNullChecks(currentScope,
+						actionInfo);
+				loopingContext.complainOnDeferredFinalChecks(currentScope,
+						actionInfo);
+				loopingContext.complainOnDeferredNullChecks(currentScope,
+						actionInfo);
+				exitBranch.
+					addPotentialInitializationsFrom(
+						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
+		FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
+				(loopingContext.initsOnBreak.tagBits &
+					FlowInfo.UNREACHABLE) != 0 ?
+					loopingContext.initsOnBreak :
+					flowInfo.addInitializationsFrom(loopingContext.initsOnBreak), // recover upstream null info
+				isConditionOptimizedTrue,
+				exitBranch,
+				isConditionOptimizedFalse,
+				!isConditionTrue /*while(true); unreachable(); */);
+		this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
+		return mergedInfo;
+	}
+
+	/**
+	 * While code generation
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+
+		if ((this.bits & IsReachable) == 0) {
+			return;
+		}
+		int pc = codeStream.position;
+		Constant cst = this.condition.optimizedBooleanConstant();
+		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
+		if (isConditionOptimizedFalse) {
+			this.condition.generateCode(currentScope, codeStream, false);
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+			return;
+		}
+
+		this.breakLabel.initialize(codeStream);
+
+		// generate condition
+		if (this.continueLabel == null) {
+			// no need to reverse condition
+			if (this.condition.constant == Constant.NotAConstant) {
+				this.condition.generateOptimizedBoolean(
+					currentScope,
+					codeStream,
+					null,
+					this.breakLabel,
+					true);
+			}
+		} else {
+			this.continueLabel.initialize(codeStream);
+			if (!(((this.condition.constant != Constant.NotAConstant)
+				&& (this.condition.constant.booleanValue() == true))
+				|| (this.action == null)
+				|| this.action.isEmptyBlock())) {
+				int jumpPC = codeStream.position;
+				codeStream.goto_(this.continueLabel);
+				codeStream.recordPositionsFrom(jumpPC, this.condition.sourceStart);
+			}
+		}
+		// generate the action
+		BranchLabel actionLabel = new BranchLabel(codeStream);
+		if (this.action != null) {
+			actionLabel.tagBits |= BranchLabel.USED;
+			// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+			if (this.condIfTrueInitStateIndex != -1) {
+				// insert all locals initialized inside the condition into the action generated prior to the condition
+				codeStream.addDefinitelyAssignedVariables(
+					currentScope,
+					this.condIfTrueInitStateIndex);
+			}
+			actionLabel.place();
+			this.action.generateCode(currentScope, codeStream);
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.preCondInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preCondInitStateIndex);
+			}
+		} else {
+			actionLabel.place();
+		}
+		// output condition and branch back to the beginning of the repeated action
+		if (this.continueLabel != null) {
+			this.continueLabel.place();
+			this.condition.generateOptimizedBoolean(
+				currentScope,
+				codeStream,
+				actionLabel,
+				null,
+				true);
+		}
+
+		// May loose some local variable initializations : affecting the local variable attributes
+		if (this.mergedInitStateIndex != -1) {
+			codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+		}
+		this.breakLabel.place();
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+
+	public void resolve(BlockScope scope) {
+
+		TypeBinding type = this.condition.resolveTypeExpecting(scope, TypeBinding.BOOLEAN);
+		this.condition.computeConversion(scope, type, type);
+		if (this.action != null)
+			this.action.resolve(scope);
+	}
+
+	public StringBuffer printStatement(int tab, StringBuffer output) {
+
+		printIndent(tab, output).append("while ("); //$NON-NLS-1$
+		this.condition.printExpression(0, output).append(')');
+		if (this.action == null)
+			output.append(';');
+		else
+			this.action.printStatement(tab + 1, output);
+		return output;
+	}
+
+	public void traverse(
+		ASTVisitor visitor,
+		BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.condition.traverse(visitor, blockScope);
+			if (this.action != null)
+				this.action.traverse(visitor, blockScope);
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
new file mode 100644
index 0000000..1a0f7db
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Node to represent Wildcard
+ */
+public class Wildcard extends SingleTypeReference {
+
+    public static final int UNBOUND = 0;
+    public static final int EXTENDS = 1;
+    public static final int SUPER = 2;
+
+	public TypeReference bound;
+	public int kind;
+
+	public Wildcard(int kind) {
+		super(WILDCARD_NAME, 0);
+		this.kind = kind;
+	}
+
+	public char [][] getParameterizedTypeName() {
+		switch (this.kind) {
+			case Wildcard.UNBOUND :
+				return new char[][] { WILDCARD_NAME };
+			case Wildcard.EXTENDS :
+				return new char[][] { CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, CharOperation.concatWith(this.bound.getParameterizedTypeName(), '.')) };
+			default: // SUPER
+				return new char[][] { CharOperation.concat(WILDCARD_NAME, WILDCARD_SUPER, CharOperation.concatWith(this.bound.getParameterizedTypeName(), '.')) };
+		}
+	}
+
+	public char [][] getTypeName() {
+		switch (this.kind) {
+			case Wildcard.UNBOUND :
+				return new char[][] { WILDCARD_NAME };
+			case Wildcard.EXTENDS :
+				return new char[][] { CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, CharOperation.concatWith(this.bound.getTypeName(), '.')) };
+			default: // SUPER
+				return new char[][] { CharOperation.concat(WILDCARD_NAME, WILDCARD_SUPER, CharOperation.concatWith(this.bound.getTypeName(), '.')) };
+		}
+	}
+
+	private TypeBinding internalResolveType(Scope scope, ReferenceBinding genericType, int rank) {
+		TypeBinding boundType = null;
+		resolveAnnotations(scope);
+		if (this.bound != null) {
+			boundType = scope.kind == Scope.CLASS_SCOPE
+					? this.bound.resolveType((ClassScope)scope)
+					: this.bound.resolveType((BlockScope)scope, true /* check bounds*/);
+			this.bits |= (this.bound.bits & ASTNode.HasTypeAnnotations);
+			if (boundType == null) {
+				return null;
+			}
+		}
+		WildcardBinding wildcard = scope.environment().createWildcard(genericType, rank, boundType, null /*no extra bound*/, this.kind);
+		return this.resolvedType = wildcard;
+	}
+
+	public StringBuffer printExpression(int indent, StringBuffer output){
+		if (this.annotations != null && this.annotations[0] != null) {
+			printAnnotations(this.annotations[0], output);
+			output.append(' ');
+		}
+		switch (this.kind) {
+			case Wildcard.UNBOUND :
+				output.append(WILDCARD_NAME);
+				break;
+			case Wildcard.EXTENDS :
+				output.append(WILDCARD_NAME).append(WILDCARD_EXTENDS);
+				this.bound.printExpression(0, output);
+				break;
+			default: // SUPER
+			output.append(WILDCARD_NAME).append(WILDCARD_SUPER);
+			this.bound.printExpression(0, output);
+			break;
+		}
+		return output;
+	}
+
+	// only invoked for improving resilience when unable to bind generic type from parameterized reference
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		if (this.bound != null) {
+			this.bound.resolveType(scope, checkBounds);
+			this.bits |= (this.bound.bits & ASTNode.HasTypeAnnotations);
+		}
+		return null;
+	}
+	// only invoked for improving resilience when unable to bind generic type from parameterized reference
+	public TypeBinding resolveType(ClassScope scope) {
+		if (this.bound != null) {
+			this.bound.resolveType(scope);
+			this.bits |= (this.bound.bits & ASTNode.HasTypeAnnotations);
+		}
+		return null;
+	}
+	public TypeBinding resolveTypeArgument(BlockScope blockScope, ReferenceBinding genericType, int rank) {
+	    return internalResolveType(blockScope, genericType, rank);
+	}
+
+	public TypeBinding resolveTypeArgument(ClassScope classScope, ReferenceBinding genericType, int rank) {
+	    return internalResolveType(classScope, genericType, rank);
+	}
+
+	public void traverse(ASTVisitor visitor, BlockScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.bound != null) {
+				this.bound.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	public void traverse(ASTVisitor visitor, ClassScope scope) {
+		if (visitor.visit(this, scope)) {
+			if (this.bound != null) {
+				this.bound.traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+	public boolean isWildcard() {
+		return true;
+	}
+}
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
new file mode 100644
index 0000000..9081769
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java
@@ -0,0 +1,421 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * 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 */
+	private char[] typename;
+	/**
+	 * null until this annotation is initialized
+	 * @see #getElementValuePairs()
+	 */
+	private ElementValuePairInfo[] pairs;
+
+	long standardAnnotationTagBits = 0;
+	int readOffset = 0;
+
+	static Object[] EmptyValueArray = new Object[0];
+
+AnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset) {
+	super(classFileBytes, contantPoolOffsets, offset);
+}
+/**
+ * @param classFileBytes
+ * @param offset the offset into <code>classFileBytes</code> for the "type_index" of the annotation attribute.
+ * @param populate <code>true</code> to indicate to build out the annotation structure.
+ */
+AnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset, boolean runtimeVisible, boolean populate) {
+	this(classFileBytes, contantPoolOffsets, offset);
+	if (populate)
+		decodeAnnotation();
+	else
+		this.readOffset = scanAnnotation(0, runtimeVisible, true);
+}
+private void decodeAnnotation() {
+	this.readOffset = 0;
+	int utf8Offset = this.constantPoolOffsets[u2At(0)] - this.structOffset;
+	this.typename = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	int numberOfPairs = u2At(2);
+	// u2 type_index + u2 num_member_value_pair
+	this.readOffset += 4;
+	this.pairs = numberOfPairs == 0 ? ElementValuePairInfo.NoMembers : new ElementValuePairInfo[numberOfPairs];
+	for (int i = 0; i < numberOfPairs; i++) {
+		// u2 member_name_index;
+		utf8Offset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+		char[] membername = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		this.readOffset += 2;
+		Object value = decodeDefaultValue();
+		this.pairs[i] = new ElementValuePairInfo(membername, value);
+	}
+}
+Object decodeDefaultValue() {
+	Object value = null;
+	// u1 tag;
+	int tag = u1At(this.readOffset);
+	this.readOffset++;
+	int constValueOffset = -1;
+	switch (tag) {
+		case 'Z': // boolean constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = BooleanConstant.fromValue(i4At(constValueOffset + 1) == 1);
+			this.readOffset += 2;
+			break;
+		case 'I': // integer constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = IntConstant.fromValue(i4At(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'C': // char constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = CharConstant.fromValue((char) i4At(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'B': // byte constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = ByteConstant.fromValue((byte) i4At(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'S': // short constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = ShortConstant.fromValue((short) i4At(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'D': // double constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = DoubleConstant.fromValue(doubleAt(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'F': // float constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = FloatConstant.fromValue(floatAt(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 'J': // long constant
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = LongConstant.fromValue(i8At(constValueOffset + 1));
+			this.readOffset += 2;
+			break;
+		case 's': // String
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			value = StringConstant.fromValue(String.valueOf(utf8At(constValueOffset + 3, u2At(constValueOffset + 1))));
+			this.readOffset += 2;
+			break;
+		case 'e':
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			char[] typeName = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
+			this.readOffset += 2;
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			char[] constName = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
+			this.readOffset += 2;
+			value = new EnumConstantSignature(typeName, constName);
+			break;
+		case 'c':
+			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
+			char[] className = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
+			value = new ClassSignature(className);
+			this.readOffset += 2;
+			break;
+		case '@':
+			value = new AnnotationInfo(this.reference, this.constantPoolOffsets, this.readOffset + this.structOffset, false, true);
+			this.readOffset += ((AnnotationInfo) value).readOffset;
+			break;
+		case '[':
+			int numberOfValues = u2At(this.readOffset);
+			this.readOffset += 2;
+			if (numberOfValues == 0) {
+				value = EmptyValueArray;
+			} else {
+				Object[] arrayElements = new Object[numberOfValues];
+				value = arrayElements;
+				for (int i = 0; i < numberOfValues; i++)
+					arrayElements[i] = decodeDefaultValue();
+			}
+			break;
+		default:
+			throw new IllegalStateException("Unrecognized tag " + (char) tag); //$NON-NLS-1$
+	}
+	return value;
+}
+public IBinaryElementValuePair[] getElementValuePairs() {
+	if (this.pairs == null)
+		initialize();
+	return this.pairs;
+}
+public char[] getTypeName() {
+	return this.typename;
+}
+void initialize() {
+	if (this.pairs == null)
+		decodeAnnotation();
+}
+private int readRetentionPolicy(int offset) {
+	int currentOffset = offset;
+	int tag = u1At(currentOffset);
+	currentOffset++;
+	switch (tag) {
+		case 'e':
+			int utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
+			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+			currentOffset += 2;
+			if (typeName.length == 38 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTIONPOLICY)) {
+				utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
+				char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+				this.standardAnnotationTagBits |= Annotation.getRetentionPolicy(constName);
+			}
+			currentOffset += 2;
+			break;
+		case 'B':
+		case 'C':
+		case 'D':
+		case 'F':
+		case 'I':
+		case 'J':
+		case 'S':
+		case 'Z':
+		case 's':
+		case 'c':
+			currentOffset += 2;
+			break;
+		case '@':
+			// none of the supported standard annotation are in the nested
+			// level.
+			currentOffset = scanAnnotation(currentOffset, false, false);
+			break;
+		case '[':
+			int numberOfValues = u2At(currentOffset);
+			currentOffset += 2;
+			for (int i = 0; i < numberOfValues; i++)
+				currentOffset = scanElementValue(currentOffset);
+			break;
+		default:
+			throw new IllegalStateException();
+	}
+	return currentOffset;
+}
+private int readTargetValue(int offset) {
+	int currentOffset = offset;
+	int tag = u1At(currentOffset);
+	currentOffset++;
+	switch (tag) {
+		case 'e':
+			int utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
+			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+			currentOffset += 2;
+			if (typeName.length == 34 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_ELEMENTTYPE)) {
+				utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
+				char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+				this.standardAnnotationTagBits |= Annotation.getTargetElementType(constName);
+			}
+			currentOffset += 2;
+			break;
+		case 'B':
+		case 'C':
+		case 'D':
+		case 'F':
+		case 'I':
+		case 'J':
+		case 'S':
+		case 'Z':
+		case 's':
+		case 'c':
+			currentOffset += 2;
+			break;
+		case '@':
+			// none of the supported standard annotation are in the nested
+			// level.
+			currentOffset = scanAnnotation(currentOffset, false, false);
+			break;
+		case '[':
+			int numberOfValues = u2At(currentOffset);
+			currentOffset += 2;
+			if (numberOfValues == 0) {
+				this.standardAnnotationTagBits |= TagBits.AnnotationTarget;
+			} else {
+				for (int i = 0; i < numberOfValues; i++)
+					currentOffset = readTargetValue(currentOffset);
+			}
+			break;
+		default:
+			throw new IllegalStateException();
+	}
+	return currentOffset;
+}
+/**
+ * Read through this annotation in order to figure out the necessary tag
+ * bits and the length of this annotation. The data structure will not be
+ * flushed out.
+ *
+ * The tag bits are derived from the following (supported) standard
+ * annotation. java.lang.annotation.Documented,
+ * java.lang.annotation.Retention, java.lang.annotation.Target, and
+ * java.lang.Deprecated
+ *
+ * @param expectRuntimeVisibleAnno
+ *            <code>true</cod> to indicate that this is a runtime-visible annotation
+ * @param toplevel <code>false</code> to indicate that an nested annotation is read.
+ * 		<code>true</code> otherwise
+ * @return the next offset to read.
+ */
+private int scanAnnotation(int offset, boolean expectRuntimeVisibleAnno, boolean toplevel) {
+	int currentOffset = offset;
+	int utf8Offset = this.constantPoolOffsets[u2At(offset)] - this.structOffset;
+	char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	if (toplevel)
+		this.typename = typeName;
+	int numberOfPairs = u2At(offset + 2);
+	// u2 type_index + u2 number_member_value_pair
+	currentOffset += 4;
+	if (expectRuntimeVisibleAnno && toplevel) {
+		switch (typeName.length) {
+			case 22:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_DEPRECATED)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationDeprecated;
+					return currentOffset;
+				}
+				break;
+			case 23:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_SAFEVARARGS)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationSafeVarargs;
+					return currentOffset;
+				}
+				break;
+			case 29:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_TARGET)) {
+					currentOffset += 2;
+					return readTargetValue(currentOffset);
+				}
+				break;
+			case 32:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) {
+					currentOffset += 2;
+					return readRetentionPolicy(currentOffset);
+				}
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_INHERITED)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationInherited;
+					return currentOffset;
+				}
+				break;
+			case 33:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationDocumented;
+					return currentOffset;
+				}
+				break;
+			case 52:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationPolymorphicSignature;
+					return currentOffset;
+				}
+				break;
+		}
+	}
+	for (int i = 0; i < numberOfPairs; i++) {
+		// u2 member_name_index
+		currentOffset += 2;
+		currentOffset = scanElementValue(currentOffset);
+	}
+	return currentOffset;
+}
+/**
+ * @param offset
+ *            the offset to start reading.
+ * @return the next offset to read.
+ */
+private int scanElementValue(int offset) {
+	int currentOffset = offset;
+	int tag = u1At(currentOffset);
+	currentOffset++;
+	switch (tag) {
+		case 'B':
+		case 'C':
+		case 'D':
+		case 'F':
+		case 'I':
+		case 'J':
+		case 'S':
+		case 'Z':
+		case 's':
+		case 'c':
+			currentOffset += 2;
+			break;
+		case 'e':
+			currentOffset += 4;
+			break;
+		case '@':
+			// none of the supported standard annotation are in the nested
+			// level.
+			currentOffset = scanAnnotation(currentOffset, false, false);
+			break;
+		case '[':
+			int numberOfValues = u2At(currentOffset);
+			currentOffset += 2;
+			for (int i = 0; i < numberOfValues; i++)
+				currentOffset = scanElementValue(currentOffset);
+			break;
+		default:
+			throw new IllegalStateException();
+	}
+	return currentOffset;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append('@');
+	buffer.append(this.typename);
+	if (this.pairs != null) {
+		buffer.append('(');
+		buffer.append("\n\t"); //$NON-NLS-1$
+		for (int i = 0, len = this.pairs.length; i < len; i++) {
+			if (i > 0)
+				buffer.append(",\n\t"); //$NON-NLS-1$
+			buffer.append(this.pairs[i]);
+		}
+		buffer.append(')');
+	}
+	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/AnnotationMethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java
new file mode 100644
index 0000000..6ddba77
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+
+public class AnnotationMethodInfo extends MethodInfo {
+	protected Object defaultValue = null;
+
+public static MethodInfo createAnnotationMethod(byte classFileBytes[], int offsets[], int offset) {
+	MethodInfo methodInfo = new MethodInfo(classFileBytes, offsets, offset);
+	int attributesCount = methodInfo.u2At(6);
+	int readOffset = 8;
+	AnnotationInfo[] annotations = null;
+	Object defaultValue = null;
+	for (int i = 0; i < attributesCount; i++) {
+		// check the name of each attribute
+		int utf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset)] - methodInfo.structOffset;
+		char[] attributeName = methodInfo.utf8At(utf8Offset + 3, methodInfo.u2At(utf8Offset + 1));
+		if (attributeName.length > 0) {
+			switch(attributeName[0]) {
+				case 'A':
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.AnnotationDefaultName)) {
+						// readOffset + 6 so the offset is at the start of the 'member_value' entry
+						// u2 attribute_name_index + u4 attribute_length = + 6
+						AnnotationInfo info =
+							new AnnotationInfo(methodInfo.reference, methodInfo.constantPoolOffsets, readOffset + 6 + methodInfo.structOffset);
+						defaultValue = info.decodeDefaultValue();
+					}
+					break;
+				case 'S' :
+					if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName))
+						methodInfo.signatureUtf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset + 6)] - methodInfo.structOffset;
+					break;
+				case 'R' :
+					AnnotationInfo[] methodAnnotations = null;
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
+						methodAnnotations = decodeMethodAnnotations(readOffset, true, methodInfo);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
+						methodAnnotations = decodeMethodAnnotations(readOffset, false, methodInfo);
+					}
+					if (methodAnnotations != null) {
+						if (annotations == null) {
+							annotations = methodAnnotations;
+						} else {
+							int length = annotations.length;
+							AnnotationInfo[] newAnnotations = new AnnotationInfo[length + methodAnnotations.length];
+							System.arraycopy(annotations, 0, newAnnotations, 0, length);
+							System.arraycopy(methodAnnotations, 0, newAnnotations, length, methodAnnotations.length);
+							annotations = newAnnotations;
+						}
+					}
+					break;
+			}
+		}
+		readOffset += (6 + methodInfo.u4At(readOffset + 2));
+	}
+	methodInfo.attributeBytes = readOffset;
+
+	if (defaultValue != null) {
+		if (annotations != null) {
+			return new AnnotationMethodInfoWithAnnotations(methodInfo, defaultValue, annotations);
+		}
+		return new AnnotationMethodInfo(methodInfo, defaultValue);
+	}
+	if (annotations != null)
+		return new MethodInfoWithAnnotations(methodInfo, annotations);
+	return methodInfo;
+}
+
+AnnotationMethodInfo(MethodInfo methodInfo, Object defaultValue) {
+	super(methodInfo.reference, methodInfo.constantPoolOffsets, methodInfo.structOffset);
+	this.defaultValue = defaultValue;
+
+	this.accessFlags = methodInfo.accessFlags;
+	this.attributeBytes = methodInfo.attributeBytes;
+	this.descriptor = methodInfo.descriptor;
+	this.exceptionNames = methodInfo.exceptionNames;
+	this.name = methodInfo.name;
+	this.signature = methodInfo.signature;
+	this.signatureUtf8Offset = methodInfo.signatureUtf8Offset;
+	this.tagBits = methodInfo.tagBits;
+}
+public Object getDefaultValue() {
+	return this.defaultValue;
+}
+protected void toStringContent(StringBuffer buffer) {
+	super.toStringContent(buffer);
+	if (this.defaultValue != null) {
+		buffer.append(" default "); //$NON-NLS-1$
+		if (this.defaultValue instanceof Object[]) {
+			buffer.append('{');
+			Object[] elements = (Object[]) this.defaultValue;
+			for (int i = 0, len = elements.length; i < len; i++) {
+				if (i > 0)
+					buffer.append(", "); //$NON-NLS-1$
+				buffer.append(elements[i]);
+			}
+			buffer.append('}');
+		} else {
+			buffer.append(this.defaultValue);
+		}
+		buffer.append('\n');
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfoWithAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfoWithAnnotations.java
new file mode 100644
index 0000000..bd1cce8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfoWithAnnotations.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+
+public class AnnotationMethodInfoWithAnnotations extends AnnotationMethodInfo {
+	private AnnotationInfo[] annotations;
+
+AnnotationMethodInfoWithAnnotations(MethodInfo methodInfo, Object defaultValue, AnnotationInfo[] annotations) {
+	super(methodInfo, defaultValue);
+	this.annotations = annotations;
+}
+public IBinaryAnnotation[] getAnnotations() {
+	return this.annotations;
+}
+protected void initialize() {
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++)
+		if (this.annotations[i] != null)
+			this.annotations[i].initialize();
+	super.initialize();
+}
+protected void reset() {
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++)
+		if (this.annotations[i] != null)
+			this.annotations[i].reset();
+	super.reset();
+}
+protected void toStringContent(StringBuffer buffer) {
+	super.toStringContent(buffer);
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++) {
+		buffer.append(this.annotations[i]);
+		buffer.append('\n');
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
new file mode 100644
index 0000000..c2cafd7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+public interface ClassFileConstants {
+
+	int AccDefault = 0;
+	/*
+	 * Modifiers
+	 */
+	int AccPublic       = 0x0001;
+	int AccPrivate      = 0x0002;
+	int AccProtected    = 0x0004;
+	int AccStatic       = 0x0008;
+	int AccFinal        = 0x0010;
+	int AccSynchronized = 0x0020;
+	int AccVolatile     = 0x0040;
+	int AccBridge       = 0x0040;
+	int AccTransient    = 0x0080;
+	int AccVarargs      = 0x0080;
+	int AccNative       = 0x0100;
+	int AccInterface    = 0x0200;
+	int AccAbstract     = 0x0400;
+	int AccStrictfp     = 0x0800;
+	int AccSynthetic    = 0x1000;
+	int AccAnnotation   = 0x2000;
+	int AccEnum         = 0x4000;
+
+	/**
+	 * Other VM flags.
+	 */
+	int AccSuper = 0x0020;
+
+	/**
+	 * Extra flags for types and members attributes (not from the JVMS, should have been defined in ExtraCompilerModifiers).
+	 */
+	int AccAnnotationDefault = ASTNode.Bit18; // indicate presence of an attribute  "DefaultValue" (annotation method)
+	int AccDeprecated = ASTNode.Bit21; // indicate presence of an attribute "Deprecated"
+
+	int Utf8Tag = 1;
+	int IntegerTag = 3;
+	int FloatTag = 4;
+	int LongTag = 5;
+	int DoubleTag = 6;
+	int ClassTag = 7;
+	int StringTag = 8;
+	int FieldRefTag = 9;
+	int MethodRefTag = 10;
+	int InterfaceMethodRefTag = 11;
+	int NameAndTypeTag = 12;
+	int MethodHandleTag = 15;
+	int MethodTypeTag = 16;
+	int InvokeDynamicTag = 18;
+
+	int ConstantMethodRefFixedSize = 5;
+	int ConstantClassFixedSize = 3;
+	int ConstantDoubleFixedSize = 9;
+	int ConstantFieldRefFixedSize = 5;
+	int ConstantFloatFixedSize = 5;
+	int ConstantIntegerFixedSize = 5;
+	int ConstantInterfaceMethodRefFixedSize = 5;
+	int ConstantLongFixedSize = 9;
+	int ConstantStringFixedSize = 3;
+	int ConstantUtf8FixedSize = 3;
+	int ConstantNameAndTypeFixedSize = 5;
+	int ConstantMethodHandleFixedSize = 4;
+	int ConstantMethodTypeFixedSize = 3;
+	int ConstantInvokeDynamicFixedSize = 5;
+
+	// JVMS 4.4.8
+	int MethodHandleRefKindGetField = 1;
+	int MethodHandleRefKindGetStatic = 2;
+	int MethodHandleRefKindPutField = 3;
+	int MethodHandleRefKindPutStatic = 4;
+	int MethodHandleRefKindInvokeVirtual = 5;
+	int MethodHandleRefKindInvokeStatic = 6;
+	int MethodHandleRefKindInvokeSpecial = 7;
+	int MethodHandleRefKindNewInvokeSpecial = 8;
+	int MethodHandleRefKindInvokeInterface = 9;
+
+	int MAJOR_VERSION_1_1 = 45;
+	int MAJOR_VERSION_1_2 = 46;
+	int MAJOR_VERSION_1_3 = 47;
+	int MAJOR_VERSION_1_4 = 48;
+	int MAJOR_VERSION_1_5 = 49;
+	int MAJOR_VERSION_1_6 = 50;
+	int MAJOR_VERSION_1_7 = 51;
+	int MAJOR_VERSION_1_8 = 52;
+
+	int MINOR_VERSION_0 = 0;
+	int MINOR_VERSION_1 = 1;
+	int MINOR_VERSION_2 = 2;
+	int MINOR_VERSION_3 = 3;
+	int MINOR_VERSION_4 = 4;
+
+	// JDK 1.1 -> 1.8, comparable value allowing to check both major/minor version at once 1.4.1 > 1.4.0
+	// 16 unsigned bits for major, then 16 bits for minor
+	long JDK1_1 = ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_3; // 1.1. is 45.3
+	long JDK1_2 =  ((long)ClassFileConstants.MAJOR_VERSION_1_2 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_3 =  ((long)ClassFileConstants.MAJOR_VERSION_1_3 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_4 = ((long)ClassFileConstants.MAJOR_VERSION_1_4 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_5 = ((long)ClassFileConstants.MAJOR_VERSION_1_5 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_6 = ((long)ClassFileConstants.MAJOR_VERSION_1_6 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_7 = ((long)ClassFileConstants.MAJOR_VERSION_1_7 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK1_8 = ((long)ClassFileConstants.MAJOR_VERSION_1_8 << 16) + ClassFileConstants.MINOR_VERSION_0;
+
+	/*
+	 * cldc1.1 is 45.3, but we modify it to be different from JDK1_1.
+	 * In the code gen, we will generate the same target value as JDK1_1
+	 */
+	long CLDC_1_1 = ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_4;
+
+	// jdk level used to denote future releases: optional behavior is not enabled for now, but may become so. In order to enable these,
+	// search for references to this constant, and change it to one of the official JDT constants above.
+	long JDK_DEFERRED = Long.MAX_VALUE;
+
+	int INT_ARRAY = 10;
+	int BYTE_ARRAY = 8;
+	int BOOLEAN_ARRAY = 4;
+	int SHORT_ARRAY = 9;
+	int CHAR_ARRAY = 5;
+	int LONG_ARRAY = 11;
+	int FLOAT_ARRAY = 6;
+	int DOUBLE_ARRAY = 7;
+
+	// Debug attributes
+	int ATTR_SOURCE = 0x1; // SourceFileAttribute
+	int ATTR_LINES = 0x2; // LineNumberAttribute
+	int ATTR_VARS = 0x4; // LocalVariableTableAttribute
+	int ATTR_STACK_MAP_TABLE = 0x8; // Stack map table attribute
+	int ATTR_STACK_MAP = 0x10; // Stack map attribute: cldc
+	int ATTR_TYPE_ANNOTATION = 0x20; // type annotation attribute (jsr 308)
+}
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
new file mode 100644
index 0000000..fa2fb0f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -0,0 +1,1207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 365992 - [builder] [null] Change of nullness for a parameter doesn't trigger a build for the files that call the method
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClassFileReader extends ClassFileStruct implements IBinaryType {
+
+	private int accessFlags;
+	private char[] classFileName;
+	private char[] className;
+	private int classNameIndex;
+	private int constantPoolCount;
+	private AnnotationInfo[] annotations;
+	private FieldInfo[] fields;
+	private int fieldsCount;
+
+	// initialized in case the .class file is a nested type
+	private InnerClassInfo innerInfo;
+	private int innerInfoIndex;
+	private InnerClassInfo[] innerInfos;
+	private char[][] interfaceNames;
+	private int interfacesCount;
+	private MethodInfo[] methods;
+	private int methodsCount;
+	private char[] signature;
+	private char[] sourceName;
+	private char[] sourceFileName;
+	private char[] superclassName;
+	private long tagBits;
+	private long version;
+	private char[] enclosingTypeName;
+	private char[][][] missingTypeNames;
+	private int enclosingNameAndTypeIndex;
+	private char[] enclosingMethod;
+
+private static String printTypeModifiers(int modifiers) {
+	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
+	java.io.PrintWriter print = new java.io.PrintWriter(out);
+
+	if ((modifiers & ClassFileConstants.AccPublic) != 0) print.print("public "); //$NON-NLS-1$
+	if ((modifiers & ClassFileConstants.AccPrivate) != 0) print.print("private "); //$NON-NLS-1$
+	if ((modifiers & ClassFileConstants.AccFinal) != 0) print.print("final "); //$NON-NLS-1$
+	if ((modifiers & ClassFileConstants.AccSuper) != 0) print.print("super "); //$NON-NLS-1$
+	if ((modifiers & ClassFileConstants.AccInterface) != 0) print.print("interface "); //$NON-NLS-1$
+	if ((modifiers & ClassFileConstants.AccAbstract) != 0) print.print("abstract "); //$NON-NLS-1$
+	print.flush();
+	return out.toString();
+}
+
+public static ClassFileReader read(File file) throws ClassFormatException, IOException {
+	return read(file, false);
+}
+
+public static ClassFileReader read(File file, boolean fullyInitialize) throws ClassFormatException, IOException {
+	byte classFileBytes[] = Util.getFileByteContent(file);
+	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, file.getAbsolutePath().toCharArray());
+	if (fullyInitialize) {
+		classFileReader.initialize();
+	}
+	return classFileReader;
+}
+
+public static ClassFileReader read(InputStream stream, String fileName) throws ClassFormatException, IOException {
+	return read(stream, fileName, false);
+}
+
+public static ClassFileReader read(InputStream stream, String fileName, boolean fullyInitialize) throws ClassFormatException, IOException {
+	byte classFileBytes[] = Util.getInputStreamAsByteArray(stream, -1);
+	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, fileName.toCharArray());
+	if (fullyInitialize) {
+		classFileReader.initialize();
+	}
+	return classFileReader;
+}
+
+public static ClassFileReader read(
+	java.util.zip.ZipFile zip,
+	String filename)
+	throws ClassFormatException, java.io.IOException {
+		return read(zip, filename, false);
+}
+
+public static ClassFileReader read(
+	java.util.zip.ZipFile zip,
+	String filename,
+	boolean fullyInitialize)
+	throws ClassFormatException, java.io.IOException {
+	java.util.zip.ZipEntry ze = zip.getEntry(filename);
+	if (ze == null)
+		return null;
+	byte classFileBytes[] = Util.getZipEntryByteContent(ze, zip);
+	ClassFileReader classFileReader = new ClassFileReader(classFileBytes, filename.toCharArray());
+	if (fullyInitialize) {
+		classFileReader.initialize();
+	}
+	return classFileReader;
+}
+
+public static ClassFileReader read(String fileName) throws ClassFormatException, java.io.IOException {
+	return read(fileName, false);
+}
+
+public static ClassFileReader read(String fileName, boolean fullyInitialize) throws ClassFormatException, java.io.IOException {
+	return read(new File(fileName), fullyInitialize);
+}
+
+/**
+ * @param classFileBytes Actual bytes of a .class file
+ * @param fileName	Actual name of the file that contains the bytes, can be null
+ *
+ * @exception ClassFormatException
+ */
+public ClassFileReader(byte classFileBytes[], char[] fileName) throws ClassFormatException {
+	this(classFileBytes, fileName, false);
+}
+
+/**
+ * @param classFileBytes byte[]
+ * 		Actual bytes of a .class file
+ *
+ * @param fileName char[]
+ * 		Actual name of the file that contains the bytes, can be null
+ *
+ * @param fullyInitialize boolean
+ * 		Flag to fully initialize the new object
+ * @exception ClassFormatException
+ */
+public ClassFileReader(byte[] classFileBytes, char[] fileName, boolean fullyInitialize) throws ClassFormatException {
+	// This method looks ugly but is actually quite simple, the constantPool is constructed
+	// in 3 passes.  All non-primitive constant pool members that usually refer to other members
+	// by index are tweaked to have their value in inst vars, this minor cost at read-time makes
+	// all subsequent uses of the constant pool element faster.
+	super(classFileBytes, null, 0);
+	this.classFileName = fileName;
+	int readOffset = 10;
+	try {
+		this.version = ((long)u2At(6) << 16) + u2At(4); // major<<16 + minor
+		this.constantPoolCount = u2At(8);
+		// Pass #1 - Fill in all primitive constants
+		this.constantPoolOffsets = new int[this.constantPoolCount];
+		for (int i = 1; i < this.constantPoolCount; i++) {
+			int tag = u1At(readOffset);
+			switch (tag) {
+				case ClassFileConstants.Utf8Tag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += u2At(readOffset + 1);
+					readOffset += ClassFileConstants.ConstantUtf8FixedSize;
+					break;
+				case ClassFileConstants.IntegerTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantIntegerFixedSize;
+					break;
+				case ClassFileConstants.FloatTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantFloatFixedSize;
+					break;
+				case ClassFileConstants.LongTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantLongFixedSize;
+					i++;
+					break;
+				case ClassFileConstants.DoubleTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantDoubleFixedSize;
+					i++;
+					break;
+				case ClassFileConstants.ClassTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantClassFixedSize;
+					break;
+				case ClassFileConstants.StringTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantStringFixedSize;
+					break;
+				case ClassFileConstants.FieldRefTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantFieldRefFixedSize;
+					break;
+				case ClassFileConstants.MethodRefTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantMethodRefFixedSize;
+					break;
+				case ClassFileConstants.InterfaceMethodRefTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantInterfaceMethodRefFixedSize;
+					break;
+				case ClassFileConstants.NameAndTypeTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantNameAndTypeFixedSize;
+					break;
+				case ClassFileConstants.MethodHandleTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantMethodHandleFixedSize;
+					break;
+				case ClassFileConstants.MethodTypeTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantMethodTypeFixedSize;
+					break;
+				case ClassFileConstants.InvokeDynamicTag :
+					this.constantPoolOffsets[i] = readOffset;
+					readOffset += ClassFileConstants.ConstantInvokeDynamicFixedSize;
+					break;
+			}
+		}
+		// Read and validate access flags
+		this.accessFlags = u2At(readOffset);
+		readOffset += 2;
+
+		// Read the classname, use exception handlers to catch bad format
+		this.classNameIndex = u2At(readOffset);
+		this.className = getConstantClassNameAt(this.classNameIndex);
+		readOffset += 2;
+
+		// Read the superclass name, can be null for java.lang.Object
+		int superclassNameIndex = u2At(readOffset);
+		readOffset += 2;
+		// if superclassNameIndex is equals to 0 there is no need to set a value for the
+		// field this.superclassName. null is fine.
+		if (superclassNameIndex != 0) {
+			this.superclassName = getConstantClassNameAt(superclassNameIndex);
+		}
+
+		// Read the interfaces, use exception handlers to catch bad format
+		this.interfacesCount = u2At(readOffset);
+		readOffset += 2;
+		if (this.interfacesCount != 0) {
+			this.interfaceNames = new char[this.interfacesCount][];
+			for (int i = 0; i < this.interfacesCount; i++) {
+				this.interfaceNames[i] = getConstantClassNameAt(u2At(readOffset));
+				readOffset += 2;
+			}
+		}
+		// Read the fields, use exception handlers to catch bad format
+		this.fieldsCount = u2At(readOffset);
+		readOffset += 2;
+		if (this.fieldsCount != 0) {
+			FieldInfo field;
+			this.fields = new FieldInfo[this.fieldsCount];
+			for (int i = 0; i < this.fieldsCount; i++) {
+				field = FieldInfo.createField(this.reference, this.constantPoolOffsets, readOffset);
+				this.fields[i] = field;
+				readOffset += field.sizeInBytes();
+			}
+		}
+		// Read the methods
+		this.methodsCount = u2At(readOffset);
+		readOffset += 2;
+		if (this.methodsCount != 0) {
+			this.methods = new MethodInfo[this.methodsCount];
+			boolean isAnnotationType = (this.accessFlags & ClassFileConstants.AccAnnotation) != 0;
+			for (int i = 0; i < this.methodsCount; i++) {
+				this.methods[i] = isAnnotationType
+					? AnnotationMethodInfo.createAnnotationMethod(this.reference, this.constantPoolOffsets, readOffset)
+					: MethodInfo.createMethod(this.reference, this.constantPoolOffsets, readOffset);
+				readOffset += this.methods[i].sizeInBytes();
+			}
+		}
+
+		// Read the attributes
+		int attributesCount = u2At(readOffset);
+		readOffset += 2;
+
+		for (int i = 0; i < attributesCount; i++) {
+			int utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
+			char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+			if (attributeName.length == 0) {
+				readOffset += (6 + u4At(readOffset + 2));
+				continue;
+			}
+			switch(attributeName[0] ) {
+				case 'E' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.EnclosingMethodName)) {
+						utf8Offset =
+							this.constantPoolOffsets[u2At(this.constantPoolOffsets[u2At(readOffset + 6)] + 1)];
+ 						this.enclosingTypeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+						this.enclosingNameAndTypeIndex = u2At(readOffset + 8);
+					}
+					break;
+				case 'D' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.DeprecatedName)) {
+						this.accessFlags |= ClassFileConstants.AccDeprecated;
+					}
+					break;
+				case 'I' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.InnerClassName)) {
+						int innerOffset = readOffset + 6;
+						int number_of_classes = u2At(innerOffset);
+						if (number_of_classes != 0) {
+							innerOffset+= 2;
+							this.innerInfos = new InnerClassInfo[number_of_classes];
+							for (int j = 0; j < number_of_classes; j++) {
+								this.innerInfos[j] =
+									new InnerClassInfo(this.reference, this.constantPoolOffsets, innerOffset);
+								if (this.classNameIndex == this.innerInfos[j].innerClassNameIndex) {
+									this.innerInfo = this.innerInfos[j];
+									this.innerInfoIndex = j;
+								}
+								innerOffset += 8;
+							}
+							if (this.innerInfo != null) {
+								char[] enclosingType = this.innerInfo.getEnclosingTypeName();
+								if (enclosingType != null) {
+									this.enclosingTypeName = enclosingType;
+								}
+							}
+						}
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.InconsistentHierarchy)) {
+						this.tagBits |= TagBits.HierarchyHasProblems;
+					}
+					break;
+				case 'S' :
+					if (attributeName.length > 2) {
+						switch(attributeName[1]) {
+							case 'o' :
+								if (CharOperation.equals(attributeName, AttributeNamesConstants.SourceName)) {
+									utf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)];
+									this.sourceFileName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+								}
+								break;
+							case 'y' :
+								if (CharOperation.equals(attributeName, AttributeNamesConstants.SyntheticName)) {
+									this.accessFlags |= ClassFileConstants.AccSynthetic;
+								}
+								break;
+							case 'i' :
+								if (CharOperation.equals(attributeName, AttributeNamesConstants.SignatureName)) {
+									utf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)];
+									this.signature = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+								}
+						}
+					}
+					break;
+				case 'R' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
+						decodeAnnotations(readOffset, true);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
+						decodeAnnotations(readOffset, false);
+					}
+					break;
+				case 'M' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.MissingTypesName)) {
+						// decode the missing types
+						int missingTypeOffset = readOffset + 6;
+						int numberOfMissingTypes = u2At(missingTypeOffset);
+						if (numberOfMissingTypes != 0) {
+							this.missingTypeNames = new char[numberOfMissingTypes][][];
+							missingTypeOffset += 2;
+							for (int j = 0; j < numberOfMissingTypes; j++) {
+								utf8Offset = this.constantPoolOffsets[u2At(this.constantPoolOffsets[u2At(missingTypeOffset)] + 1)];
+								char[] missingTypeConstantPoolName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+								this.missingTypeNames[j] = CharOperation.splitOn('/', missingTypeConstantPoolName);
+								missingTypeOffset += 2;
+							}
+						}
+					}
+			}
+			readOffset += (6 + u4At(readOffset + 2));
+		}
+		if (fullyInitialize) {
+			initialize();
+		}
+	} catch(ClassFormatException e) {
+		throw e;
+	} catch (Exception e) {
+		throw new ClassFormatException(
+			ClassFormatException.ErrTruncatedInput,
+			readOffset);
+	}
+}
+
+/**
+ * Answer the receiver's access flags.  The value of the access_flags
+ *	item is a mask of modifiers used with class and interface declarations.
+ *  @return int
+ */
+public int accessFlags() {
+	return this.accessFlags;
+}
+
+private void decodeAnnotations(int offset, boolean runtimeVisible) {
+	int numberOfAnnotations = u2At(offset + 6);
+	if (numberOfAnnotations > 0) {
+		int readOffset = offset + 8;
+		AnnotationInfo[] newInfos = null;
+		int newInfoCount = 0;
+		for (int i = 0; i < numberOfAnnotations; i++) {
+			// With the last parameter being 'false', the data structure will not be flushed out
+			AnnotationInfo newInfo = new AnnotationInfo(this.reference, this.constantPoolOffsets, readOffset, runtimeVisible, false);
+			readOffset += newInfo.readOffset;
+			long standardTagBits = newInfo.standardAnnotationTagBits;
+			if (standardTagBits != 0) {
+				this.tagBits |= standardTagBits;
+			} else {
+				if (newInfos == null)
+					newInfos = new AnnotationInfo[numberOfAnnotations - i];
+				newInfos[newInfoCount++] = newInfo;
+			}
+		}
+		if (newInfos == null)
+			return; // nothing to record in this.annotations
+
+		if (this.annotations == null) {
+			if (newInfoCount != newInfos.length)
+				System.arraycopy(newInfos, 0, newInfos = new AnnotationInfo[newInfoCount], 0, newInfoCount);
+			this.annotations = newInfos;
+		} else {
+			int length = this.annotations.length;
+			AnnotationInfo[] temp = new AnnotationInfo[length + newInfoCount];
+			System.arraycopy(this.annotations, 0, temp, 0, length);
+			System.arraycopy(newInfos, 0, temp, length, newInfoCount);
+			this.annotations = temp;
+		}
+	}
+}
+
+/**
+ * @return the annotations or null if there is none.
+ */
+public IBinaryAnnotation[] getAnnotations() {
+	return this.annotations;
+}
+
+/**
+ * Answer the char array that corresponds to the class name of the constant class.
+ * constantPoolIndex is the index in the constant pool that is a constant class entry.
+ *
+ * @param constantPoolIndex int
+ * @return char[]
+ */
+private char[] getConstantClassNameAt(int constantPoolIndex) {
+	int utf8Offset = this.constantPoolOffsets[u2At(this.constantPoolOffsets[constantPoolIndex] + 1)];
+	return utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+}
+
+/**
+ * Answer the int array that corresponds to all the offsets of each entry in the constant pool
+ *
+ * @return int[]
+ */
+public int[] getConstantPoolOffsets() {
+	return this.constantPoolOffsets;
+}
+
+public char[] getEnclosingMethod() {
+	if (this.enclosingNameAndTypeIndex <= 0) {
+		return null;
+	}
+	if (this.enclosingMethod == null) {
+		// read the name
+		StringBuffer buffer = new StringBuffer();
+		
+		int nameAndTypeOffset = this.constantPoolOffsets[this.enclosingNameAndTypeIndex];
+		int utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 1)];
+		buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
+
+		utf8Offset = this.constantPoolOffsets[u2At(nameAndTypeOffset + 3)];
+		buffer.append(utf8At(utf8Offset + 3, u2At(utf8Offset + 1)));
+
+		this.enclosingMethod = String.valueOf(buffer).toCharArray();
+	}
+	return this.enclosingMethod;
+}
+
+/*
+ * Answer the resolved compoundName of the enclosing type
+ * or null if the receiver is a top level type.
+ */
+public char[] getEnclosingTypeName() {
+	return this.enclosingTypeName;
+}
+
+/**
+ * Answer the receiver's this.fields or null if the array is empty.
+ * @return org.eclipse.jdt.internal.compiler.api.IBinaryField[]
+ */
+public IBinaryField[] getFields() {
+	return this.fields;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.classFileName;
+}
+
+public char[] getGenericSignature() {
+	return this.signature;
+}
+
+/**
+ * Answer the source name if the receiver is a inner type. Return null if it is an anonymous class or if the receiver is a top-level class.
+ * e.g.
+ * public class A {
+ *	public class B {
+ *	}
+ *	public void foo() {
+ *		class C {}
+ *	}
+ *	public Runnable bar() {
+ *		return new Runnable() {
+ *			public void run() {}
+ *		};
+ *	}
+ * }
+ * It returns {'B'} for the member A$B
+ * It returns null for A
+ * It returns {'C'} for the local class A$1$C
+ * It returns null for the anonymous A$1
+ * @return char[]
+ */
+public char[] getInnerSourceName() {
+	if (this.innerInfo != null)
+		return this.innerInfo.getSourceName();
+	return null;
+}
+
+/**
+ * Answer the resolved names of the receiver's interfaces in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[][]
+ */
+public char[][] getInterfaceNames() {
+	return this.interfaceNames;
+}
+
+/**
+ * Answer the receiver's nested types or null if the array is empty.
+ *
+ * This nested type info is extracted from the inner class attributes. Ask the
+ * name environment to find a member type using its compound name
+ *
+ * @return org.eclipse.jdt.internal.compiler.api.IBinaryNestedType[]
+ */
+public IBinaryNestedType[] getMemberTypes() {
+	// we might have some member types of the current type
+	if (this.innerInfos == null) return null;
+
+	int length = this.innerInfos.length;
+	int startingIndex = this.innerInfo != null ? this.innerInfoIndex + 1 : 0;
+	if (length != startingIndex) {
+		IBinaryNestedType[] memberTypes =
+			new IBinaryNestedType[length - this.innerInfoIndex];
+		int memberTypeIndex = 0;
+		for (int i = startingIndex; i < length; i++) {
+			InnerClassInfo currentInnerInfo = this.innerInfos[i];
+			int outerClassNameIdx = currentInnerInfo.outerClassNameIndex;
+			int innerNameIndex = currentInnerInfo.innerNameIndex;
+			/*
+			 * Checking that outerClassNameIDx is different from 0 should be enough to determine if an inner class
+			 * attribute entry is a member class, but due to the bug:
+			 * http://dev.eclipse.org/bugs/show_bug.cgi?id=14592
+			 * we needed to add an extra check. So we check that innerNameIndex is different from 0 as well.
+			 *
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=49879
+			 * From JavaMail 1.2, the class javax.mail.Folder contains an anonymous class in the
+			 * terminateQueue() method for which the inner attribute is boggus.
+			 * outerClassNameIdx is not 0, innerNameIndex is not 0, but the sourceName length is 0.
+			 * So I added this extra check to filter out this anonymous class from the
+			 * member types.
+			 */
+			if (outerClassNameIdx != 0
+				&& innerNameIndex != 0
+				&& outerClassNameIdx == this.classNameIndex
+				&& currentInnerInfo.getSourceName().length != 0) {
+				memberTypes[memberTypeIndex++] = currentInnerInfo;
+			}
+		}
+		if (memberTypeIndex == 0) return null;
+		if (memberTypeIndex != memberTypes.length) {
+			// we need to resize the memberTypes array. Some local or anonymous classes
+			// are present in the current class.
+			System.arraycopy(
+				memberTypes,
+				0,
+				(memberTypes = new IBinaryNestedType[memberTypeIndex]),
+				0,
+				memberTypeIndex);
+		}
+		return memberTypes;
+	}
+	return null;
+}
+
+/**
+ * Answer the receiver's this.methods or null if the array is empty.
+ * @return org.eclipse.jdt.internal.compiler.api.env.IBinaryMethod[]
+ */
+public IBinaryMethod[] getMethods() {
+	return this.methods;
+}
+
+/*
+public static void main(String[] args) throws ClassFormatException, IOException {
+	if (args == null || args.length != 1) {
+		System.err.println("ClassFileReader <filename>"); //$NON-NLS-1$
+		System.exit(1);
+	}
+	File file = new File(args[0]);
+	ClassFileReader reader = read(file, true);
+	if (reader.annotations != null) {
+		System.err.println();
+		for (int i = 0; i < reader.annotations.length; i++)
+			System.err.println(reader.annotations[i]);
+	}
+	System.err.print("class "); //$NON-NLS-1$
+	System.err.print(reader.getName());
+	char[] superclass = reader.getSuperclassName();
+	if (superclass != null) {
+		System.err.print(" extends "); //$NON-NLS-1$
+		System.err.print(superclass);
+	}
+	System.err.println();
+	char[][] interfaces = reader.getInterfaceNames();
+	if (interfaces != null && interfaces.length > 0) {
+		System.err.print(" implements "); //$NON-NLS-1$
+		for (int i = 0; i < interfaces.length; i++) {
+			if (i != 0) System.err.print(", "); //$NON-NLS-1$
+			System.err.println(interfaces[i]);
+		}
+	}
+	System.err.println();
+	System.err.println('{');
+	if (reader.fields != null) {
+		for (int i = 0; i < reader.fields.length; i++) {
+			System.err.println(reader.fields[i]);
+			System.err.println();
+		}
+	}
+	if (reader.methods != null) {
+		for (int i = 0; i < reader.methods.length; i++) {
+			System.err.println(reader.methods[i]);
+			System.err.println();
+		}
+	}
+	System.err.println();
+	System.err.println('}');
+}
+*/
+public char[][][] getMissingTypeNames() {
+	return this.missingTypeNames;
+}
+
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Set the AccDeprecated and AccSynthetic bits if necessary
+ * @return int
+ */
+public int getModifiers() {
+	int modifiers;
+	if (this.innerInfo != null) {
+		modifiers = this.innerInfo.getModifiers()
+			| (this.accessFlags & ClassFileConstants.AccDeprecated)
+			| (this.accessFlags & ClassFileConstants.AccSynthetic);
+	} else {
+		modifiers = this.accessFlags;
+	}
+	return modifiers;
+}
+
+/**
+ * Answer the resolved name of the type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[]
+ */
+public char[] getName() {
+	return this.className;
+}
+
+public char[] getSourceName() {
+	if (this.sourceName != null)
+		return this.sourceName;
+
+	char[] name = getInnerSourceName(); // member or local scenario
+	if (name == null) {
+		name = getName(); // extract from full name
+		int start;
+		if (isAnonymous()) {
+			start = CharOperation.indexOf('$', name, CharOperation.lastIndexOf('/', name) + 1) + 1;
+		} else {
+			start = CharOperation.lastIndexOf('/', name) + 1;
+		}
+		if (start > 0) {
+			char[] newName = new char[name.length - start];
+			System.arraycopy(name, start, newName, 0, newName.length);
+			name = newName;
+		}
+	}
+	return this.sourceName = name;
+}
+
+/**
+ * Answer the resolved name of the receiver's superclass in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if it does not have one.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[]
+ */
+public char[] getSuperclassName() {
+	return this.superclassName;
+}
+
+public long getTagBits() {
+	return this.tagBits;
+}
+
+/**
+ * Answer the major/minor version defined in this class file according to the VM spec.
+ * as a long: (major<<16)+minor
+ * @return the major/minor version found
+ */
+public long getVersion() {
+	return this.version;
+}
+
+private boolean hasNonSyntheticFieldChanges(FieldInfo[] currentFieldInfos, FieldInfo[] otherFieldInfos) {
+	int length1 = currentFieldInfos == null ? 0 : currentFieldInfos.length;
+	int length2 = otherFieldInfos == null ? 0 : otherFieldInfos.length;
+	int index1 = 0;
+	int index2 = 0;
+
+	end : while (index1 < length1 && index2 < length2) {
+		while (currentFieldInfos[index1].isSynthetic()) {
+			if (++index1 >= length1) break end;
+		}
+		while (otherFieldInfos[index2].isSynthetic()) {
+			if (++index2 >= length2) break end;
+		}
+		if (hasStructuralFieldChanges(currentFieldInfos[index1++], otherFieldInfos[index2++]))
+			return true;
+	}
+
+	while (index1 < length1) {
+		if (!currentFieldInfos[index1++].isSynthetic()) return true;
+	}
+	while (index2 < length2) {
+		if (!otherFieldInfos[index2++].isSynthetic()) return true;
+	}
+	return false;
+}
+
+private boolean hasNonSyntheticMethodChanges(MethodInfo[] currentMethodInfos, MethodInfo[] otherMethodInfos) {
+	int length1 = currentMethodInfos == null ? 0 : currentMethodInfos.length;
+	int length2 = otherMethodInfos == null ? 0 : otherMethodInfos.length;
+	int index1 = 0;
+	int index2 = 0;
+
+	MethodInfo m;
+	end : while (index1 < length1 && index2 < length2) {
+		while ((m = currentMethodInfos[index1]).isSynthetic() || m.isClinit()) {
+			if (++index1 >= length1) break end;
+		}
+		while ((m = otherMethodInfos[index2]).isSynthetic() || m.isClinit()) {
+			if (++index2 >= length2) break end;
+		}
+		if (hasStructuralMethodChanges(currentMethodInfos[index1++], otherMethodInfos[index2++]))
+			return true;
+	}
+
+	while (index1 < length1) {
+		if (!((m = currentMethodInfos[index1++]).isSynthetic() || m.isClinit())) return true;
+	}
+	while (index2 < length2) {
+		if (!((m = otherMethodInfos[index2++]).isSynthetic() || m.isClinit())) return true;
+	}
+	return false;
+}
+
+/**
+ * Check if the receiver has structural changes compare to the byte array in argument.
+ * Structural changes are:
+ * - modifiers changes for the class, the this.fields or the this.methods
+ * - signature changes for this.fields or this.methods.
+ * - changes in the number of this.fields or this.methods
+ * - changes for field constants
+ * - changes for thrown exceptions
+ * - change for the super class or any super interfaces.
+ * - changes for member types name or modifiers
+ * If any of these changes occurs, the method returns true. false otherwise.
+ * The synthetic fields are included and the members are not required to be sorted.
+ * @param newBytes the bytes of the .class file we want to compare the receiver to
+ * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
+ */
+public boolean hasStructuralChanges(byte[] newBytes) {
+	return hasStructuralChanges(newBytes, true, true);
+}
+
+/**
+ * Check if the receiver has structural changes compare to the byte array in argument.
+ * Structural changes are:
+ * - modifiers changes for the class, the this.fields or the this.methods
+ * - signature changes for this.fields or this.methods.
+ * - changes in the number of this.fields or this.methods
+ * - changes for field constants
+ * - changes for thrown exceptions
+ * - change for the super class or any super interfaces.
+ * - changes for member types name or modifiers
+ * If any of these changes occurs, the method returns true. false otherwise.
+ * @param newBytes the bytes of the .class file we want to compare the receiver to
+ * @param orderRequired a boolean indicating whether the members should be sorted or not
+ * @param excludesSynthetic a boolean indicating whether the synthetic members should be used in the comparison
+ * @return boolean Returns true is there is a structural change between the two .class files, false otherwise
+ */
+public boolean hasStructuralChanges(byte[] newBytes, boolean orderRequired, boolean excludesSynthetic) {
+	try {
+		ClassFileReader newClassFile =
+			new ClassFileReader(newBytes, this.classFileName);
+		// type level comparison
+		// modifiers
+		if (getModifiers() != newClassFile.getModifiers())
+			return true;
+
+		// only consider a portion of the tagbits which indicate a structural change for dependents
+		// e.g. @Override change has no influence outside
+		long OnlyStructuralTagBits = TagBits.AnnotationTargetMASK // different @Target status ?
+			| TagBits.AnnotationDeprecated // different @Deprecated status ?
+			| TagBits.AnnotationRetentionMASK // different @Retention status ?
+			| TagBits.HierarchyHasProblems; // different hierarchy status ?
+
+		// meta-annotations
+		if ((getTagBits() & OnlyStructuralTagBits) != (newClassFile.getTagBits() & OnlyStructuralTagBits))
+			return true;
+		// annotations
+		if (hasStructuralAnnotationChanges(getAnnotations(), newClassFile.getAnnotations()))
+			return true;
+
+		// generic signature
+		if (!CharOperation.equals(getGenericSignature(), newClassFile.getGenericSignature()))
+			return true;
+		// superclass
+		if (!CharOperation.equals(getSuperclassName(), newClassFile.getSuperclassName()))
+			return true;
+		// interfaces
+		char[][] newInterfacesNames = newClassFile.getInterfaceNames();
+		if (this.interfaceNames != newInterfacesNames) { // TypeConstants.NoSuperInterfaces
+			int newInterfacesLength = newInterfacesNames == null ? 0 : newInterfacesNames.length;
+			if (newInterfacesLength != this.interfacesCount)
+				return true;
+			for (int i = 0, max = this.interfacesCount; i < max; i++)
+				if (!CharOperation.equals(this.interfaceNames[i], newInterfacesNames[i]))
+					return true;
+		}
+
+		// member types
+		IBinaryNestedType[] currentMemberTypes = getMemberTypes();
+		IBinaryNestedType[] otherMemberTypes = newClassFile.getMemberTypes();
+		if (currentMemberTypes != otherMemberTypes) { // TypeConstants.NoMemberTypes
+			int currentMemberTypeLength = currentMemberTypes == null ? 0 : currentMemberTypes.length;
+			int otherMemberTypeLength = otherMemberTypes == null ? 0 : otherMemberTypes.length;
+			if (currentMemberTypeLength != otherMemberTypeLength)
+				return true;
+			for (int i = 0; i < currentMemberTypeLength; i++)
+				if (!CharOperation.equals(currentMemberTypes[i].getName(), otherMemberTypes[i].getName())
+					|| currentMemberTypes[i].getModifiers() != otherMemberTypes[i].getModifiers())
+						return true;
+		}
+
+		// fields
+		FieldInfo[] otherFieldInfos = (FieldInfo[]) newClassFile.getFields();
+		int otherFieldInfosLength = otherFieldInfos == null ? 0 : otherFieldInfos.length;
+		boolean compareFields = true;
+		if (this.fieldsCount == otherFieldInfosLength) {
+			int i = 0;
+			for (; i < this.fieldsCount; i++)
+				if (hasStructuralFieldChanges(this.fields[i], otherFieldInfos[i])) break;
+			if ((compareFields = i != this.fieldsCount) && !orderRequired && !excludesSynthetic)
+				return true;
+		}
+		if (compareFields) {
+			if (this.fieldsCount != otherFieldInfosLength && !excludesSynthetic)
+				return true;
+			if (orderRequired) {
+				if (this.fieldsCount != 0)
+					Arrays.sort(this.fields);
+				if (otherFieldInfosLength != 0)
+					Arrays.sort(otherFieldInfos);
+			}
+			if (excludesSynthetic) {
+				if (hasNonSyntheticFieldChanges(this.fields, otherFieldInfos))
+					return true;
+			} else {
+				for (int i = 0; i < this.fieldsCount; i++)
+					if (hasStructuralFieldChanges(this.fields[i], otherFieldInfos[i]))
+						return true;
+			}
+		}
+
+		// methods
+		MethodInfo[] otherMethodInfos = (MethodInfo[]) newClassFile.getMethods();
+		int otherMethodInfosLength = otherMethodInfos == null ? 0 : otherMethodInfos.length;
+		boolean compareMethods = true;
+		if (this.methodsCount == otherMethodInfosLength) {
+			int i = 0;
+			for (; i < this.methodsCount; i++)
+				if (hasStructuralMethodChanges(this.methods[i], otherMethodInfos[i])) break;
+			if ((compareMethods = i != this.methodsCount) && !orderRequired && !excludesSynthetic)
+				return true;
+		}
+		if (compareMethods) {
+			if (this.methodsCount != otherMethodInfosLength && !excludesSynthetic)
+				return true;
+			if (orderRequired) {
+				if (this.methodsCount != 0)
+					Arrays.sort(this.methods);
+				if (otherMethodInfosLength != 0)
+					Arrays.sort(otherMethodInfos);
+			}
+			if (excludesSynthetic) {
+				if (hasNonSyntheticMethodChanges(this.methods, otherMethodInfos))
+					return true;
+			} else {
+				for (int i = 0; i < this.methodsCount; i++)
+					if (hasStructuralMethodChanges(this.methods[i], otherMethodInfos[i]))
+						return true;
+			}
+		}
+
+		// missing types
+		char[][][] missingTypes = getMissingTypeNames();
+		char[][][] newMissingTypes = newClassFile.getMissingTypeNames();
+		if (missingTypes != null) {
+			if (newMissingTypes == null) {
+				return true;
+			}
+			int length = missingTypes.length;
+			if (length != newMissingTypes.length) {
+				return true;
+			}
+			for (int i = 0; i < length; i++) {
+				if (!CharOperation.equals(missingTypes[i], newMissingTypes[i])) {
+					return true;
+				}
+			}
+		} else if (newMissingTypes != null) {
+			return true;
+		}
+		return false;
+	} catch (ClassFormatException e) {
+		return true;
+	}
+}
+
+private boolean hasStructuralAnnotationChanges(IBinaryAnnotation[] currentAnnotations, IBinaryAnnotation[] otherAnnotations) {
+	if (currentAnnotations == otherAnnotations)
+		return false;
+
+	int currentAnnotationsLength = currentAnnotations == null ? 0 : currentAnnotations.length;
+	int otherAnnotationsLength = otherAnnotations == null ? 0 : otherAnnotations.length;
+	if (currentAnnotationsLength != otherAnnotationsLength)
+		return true;
+	for (int i = 0; i < currentAnnotationsLength; i++) {
+		if (!CharOperation.equals(currentAnnotations[i].getTypeName(), otherAnnotations[i].getTypeName()))
+			return true;
+		IBinaryElementValuePair[] currentPairs = currentAnnotations[i].getElementValuePairs();
+		IBinaryElementValuePair[] otherPairs = otherAnnotations[i].getElementValuePairs();
+		int currentPairsLength = currentPairs == null ? 0 : currentPairs.length;
+		int otherPairsLength = otherPairs == null ? 0 : otherPairs.length;
+		if (currentPairsLength != otherPairsLength)
+			return true;
+		for (int j = 0; j < currentPairsLength; j++) {
+			if (!CharOperation.equals(currentPairs[j].getName(), otherPairs[j].getName()))
+				return true;
+			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;
+}
+
+private boolean hasStructuralFieldChanges(FieldInfo currentFieldInfo, FieldInfo otherFieldInfo) {
+	// generic signature
+	if (!CharOperation.equals(currentFieldInfo.getGenericSignature(), otherFieldInfo.getGenericSignature()))
+		return true;
+	if (currentFieldInfo.getModifiers() != otherFieldInfo.getModifiers())
+		return true;
+	if ((currentFieldInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherFieldInfo.getTagBits() & TagBits.AnnotationDeprecated))
+		return true;
+	if (hasStructuralAnnotationChanges(currentFieldInfo.getAnnotations(), otherFieldInfo.getAnnotations()))
+		return true;
+	if (!CharOperation.equals(currentFieldInfo.getName(), otherFieldInfo.getName()))
+		return true;
+	if (!CharOperation.equals(currentFieldInfo.getTypeName(), otherFieldInfo.getTypeName()))
+		return true;
+	if (currentFieldInfo.hasConstant() != otherFieldInfo.hasConstant())
+		return true;
+	if (currentFieldInfo.hasConstant()) {
+		Constant currentConstant = currentFieldInfo.getConstant();
+		Constant otherConstant = otherFieldInfo.getConstant();
+		if (currentConstant.typeID() != otherConstant.typeID())
+			return true;
+		if (!currentConstant.getClass().equals(otherConstant.getClass()))
+			return true;
+		switch (currentConstant.typeID()) {
+			case TypeIds.T_int :
+				return currentConstant.intValue() != otherConstant.intValue();
+			case TypeIds.T_byte :
+				return currentConstant.byteValue() != otherConstant.byteValue();
+			case TypeIds.T_short :
+				return currentConstant.shortValue() != otherConstant.shortValue();
+			case TypeIds.T_char :
+				return currentConstant.charValue() != otherConstant.charValue();
+			case TypeIds.T_long :
+				return currentConstant.longValue() != otherConstant.longValue();
+			case TypeIds.T_float :
+				return currentConstant.floatValue() != otherConstant.floatValue();
+			case TypeIds.T_double :
+				return currentConstant.doubleValue() != otherConstant.doubleValue();
+			case TypeIds.T_boolean :
+				return currentConstant.booleanValue() != otherConstant.booleanValue();
+			case TypeIds.T_JavaLangString :
+				return !currentConstant.stringValue().equals(otherConstant.stringValue());
+		}
+	}
+	return false;
+}
+
+private boolean hasStructuralMethodChanges(MethodInfo currentMethodInfo, MethodInfo otherMethodInfo) {
+	// generic signature
+	if (!CharOperation.equals(currentMethodInfo.getGenericSignature(), otherMethodInfo.getGenericSignature()))
+		return true;
+	if (currentMethodInfo.getModifiers() != otherMethodInfo.getModifiers())
+		return true;
+	if ((currentMethodInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherMethodInfo.getTagBits() & TagBits.AnnotationDeprecated))
+		return true;
+	if (hasStructuralAnnotationChanges(currentMethodInfo.getAnnotations(), otherMethodInfo.getAnnotations()))
+		return true;
+	// parameter annotations:
+	int currentAnnotatedParamsCount = currentMethodInfo.getAnnotatedParametersCount();
+	int otherAnnotatedParamsCount = otherMethodInfo.getAnnotatedParametersCount();
+	if (currentAnnotatedParamsCount != otherAnnotatedParamsCount)
+		return true;
+	for (int i=0; i<currentAnnotatedParamsCount; i++) {
+		if (hasStructuralAnnotationChanges(currentMethodInfo.getParameterAnnotations(i), otherMethodInfo.getParameterAnnotations(i)))
+			return true;
+	}
+
+	if (!CharOperation.equals(currentMethodInfo.getSelector(), otherMethodInfo.getSelector()))
+		return true;
+	if (!CharOperation.equals(currentMethodInfo.getMethodDescriptor(), otherMethodInfo.getMethodDescriptor()))
+		return true;
+	if (!CharOperation.equals(currentMethodInfo.getGenericSignature(), otherMethodInfo.getGenericSignature()))
+		return true;
+
+	char[][] currentThrownExceptions = currentMethodInfo.getExceptionTypeNames();
+	char[][] otherThrownExceptions = otherMethodInfo.getExceptionTypeNames();
+	if (currentThrownExceptions != otherThrownExceptions) { // TypeConstants.NoExceptions
+		int currentThrownExceptionsLength = currentThrownExceptions == null ? 0 : currentThrownExceptions.length;
+		int otherThrownExceptionsLength = otherThrownExceptions == null ? 0 : otherThrownExceptions.length;
+		if (currentThrownExceptionsLength != otherThrownExceptionsLength)
+			return true;
+		for (int k = 0; k < currentThrownExceptionsLength; k++)
+			if (!CharOperation.equals(currentThrownExceptions[k], otherThrownExceptions[k]))
+				return true;
+	}
+	return false;
+}
+
+/**
+ * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
+ * will be therefore fully initialized and we can get rid of the bytes.
+ */
+private void initialize() throws ClassFormatException {
+	try {
+		for (int i = 0, max = this.fieldsCount; i < max; i++) {
+			this.fields[i].initialize();
+		}
+		for (int i = 0, max = this.methodsCount; i < max; i++) {
+			this.methods[i].initialize();
+		}
+		if (this.innerInfos != null) {
+			for (int i = 0, max = this.innerInfos.length; i < max; i++) {
+				this.innerInfos[i].initialize();
+			}
+		}
+		if (this.annotations != null) {
+			for (int i = 0, max = this.annotations.length; i < max; i++) {
+				this.annotations[i].initialize();
+			}
+		}
+		this.getEnclosingMethod();
+		reset();
+	} catch(RuntimeException e) {
+		ClassFormatException exception = new ClassFormatException(e, this.classFileName);
+		throw exception;
+	}
+}
+
+/**
+ * Answer true if the receiver is an anonymous type, false otherwise
+ *
+ * @return <CODE>boolean</CODE>
+ */
+public boolean isAnonymous() {
+	if (this.innerInfo == null) return false;
+	char[] innerSourceName = this.innerInfo.getSourceName();
+	return (innerSourceName == null || innerSourceName.length == 0);
+}
+
+/**
+ * Answer whether the receiver contains the resolved binary form
+ * or the unresolved source form of the type.
+ * @return boolean
+ */
+public boolean isBinaryType() {
+	return true;
+}
+
+/**
+ * Answer true if the receiver is a local type, false otherwise
+ *
+ * @return <CODE>boolean</CODE>
+ */
+public boolean isLocal() {
+	if (this.innerInfo == null) return false;
+	if (this.innerInfo.getEnclosingTypeName() != null) return false;
+	char[] innerSourceName = this.innerInfo.getSourceName();
+	return (innerSourceName != null && innerSourceName.length > 0);
+}
+
+/**
+ * Answer true if the receiver is a member type, false otherwise
+ *
+ * @return <CODE>boolean</CODE>
+ */
+public boolean isMember() {
+	if (this.innerInfo == null) return false;
+	if (this.innerInfo.getEnclosingTypeName() == null) return false;
+	char[] innerSourceName = this.innerInfo.getSourceName();
+	return (innerSourceName != null && innerSourceName.length > 0);	 // protection against ill-formed attributes (67600)
+}
+
+/**
+ * Answer true if the receiver is a nested type, false otherwise
+ *
+ * @return <CODE>boolean</CODE>
+ */
+public boolean isNestedType() {
+	return this.innerInfo != null;
+}
+
+/**
+ * Answer the source file name attribute. Return null if there is no source file attribute for the receiver.
+ *
+ * @return char[]
+ */
+public char[] sourceFileName() {
+	return this.sourceFileName;
+}
+
+public String toString() {
+	java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
+	java.io.PrintWriter print = new java.io.PrintWriter(out);
+	print.println(getClass().getName() + "{"); //$NON-NLS-1$
+	print.println(" this.className: " + new String(getName())); //$NON-NLS-1$
+	print.println(" this.superclassName: " + (getSuperclassName() == null ? "null" : new String(getSuperclassName()))); //$NON-NLS-2$ //$NON-NLS-1$
+	print.println(" access_flags: " + printTypeModifiers(accessFlags()) + "(" + accessFlags() + ")"); //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$
+	print.flush();
+	return out.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
new file mode 100644
index 0000000..982d3ec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+abstract public class ClassFileStruct {
+	byte[] reference;
+	int[] constantPoolOffsets;
+	int structOffset;
+public ClassFileStruct(byte[] classFileBytes, int[] offsets, int offset) {
+	this.reference = classFileBytes;
+	this.constantPoolOffsets = offsets;
+	this.structOffset = offset;
+}
+public double doubleAt(int relativeOffset) {
+	return (Double.longBitsToDouble(i8At(relativeOffset)));
+}
+public float floatAt(int relativeOffset) {
+	return (Float.intBitsToFloat(i4At(relativeOffset)));
+}
+public int i4At(int relativeOffset) {
+	int position = relativeOffset + this.structOffset;
+	return ((this.reference[position++] & 0xFF) << 24) | ((this.reference[position++] & 0xFF) << 16) | ((this.reference[position++] & 0xFF) << 8) + (this.reference[position] & 0xFF);
+}
+public long i8At(int relativeOffset) {
+	int position = relativeOffset + this.structOffset;
+	return (((long) (this.reference[position++] & 0xFF)) << 56)
+					| (((long) (this.reference[position++] & 0xFF)) << 48)
+					| (((long) (this.reference[position++] & 0xFF)) << 40)
+					| (((long) (this.reference[position++] & 0xFF)) << 32)
+					| (((long) (this.reference[position++] & 0xFF)) << 24)
+					| (((long) (this.reference[position++] & 0xFF)) << 16)
+					| (((long) (this.reference[position++] & 0xFF)) << 8)
+					| (this.reference[position++] & 0xFF);
+}
+protected void reset() {
+	this.reference = null;
+	this.constantPoolOffsets = null;
+}
+public int u1At(int relativeOffset) {
+	return (this.reference[relativeOffset + this.structOffset] & 0xFF);
+}
+public int u2At(int relativeOffset) {
+	int position = relativeOffset + this.structOffset;
+	return ((this.reference[position++] & 0xFF) << 8) | (this.reference[position] & 0xFF);
+}
+public long u4At(int relativeOffset) {
+	int position = relativeOffset + this.structOffset;
+	return (((this.reference[position++] & 0xFFL) << 24) | ((this.reference[position++] & 0xFF) << 16) | ((this.reference[position++] & 0xFF) << 8) | (this.reference[position] & 0xFF));
+}
+public char[] utf8At(int relativeOffset, int bytesAvailable) {
+	int length = bytesAvailable;
+	char outputBuf[] = new char[bytesAvailable];
+	int outputPos = 0;
+	int readOffset = this.structOffset + relativeOffset;
+
+	while (length != 0) {
+		int x = this.reference[readOffset++] & 0xFF;
+		length--;
+		if ((0x80 & x) != 0) {
+			if ((x & 0x20) != 0) {
+				length-=2;
+				x = ((x & 0xF) << 12) | ((this.reference[readOffset++] & 0x3F) << 6) | (this.reference[readOffset++] & 0x3F);
+			} else {
+				length--;
+				x = ((x & 0x1F) << 6) | (this.reference[readOffset++] & 0x3F);
+			}
+		}
+		outputBuf[outputPos++] = (char) x;
+	}
+
+	if (outputPos != bytesAvailable) {
+		System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
+	}
+	return outputBuf;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
new file mode 100644
index 0000000..d465d9a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+public class ClassFormatException extends Exception {
+
+	public static final int ErrBadMagic = 1;
+	public static final int ErrBadMinorVersion = 2;
+	public static final int ErrBadMajorVersion = 3;
+	public static final int ErrBadConstantClass = 4;
+	public static final int ErrBadConstantString = 5;
+	public static final int ErrBadConstantNameAndType = 6;
+	public static final int ErrBadConstantFieldRef = 7;
+	public static final int ErrBadConstantMethodRef = 8;
+	public static final int ErrBadConstantInterfaceMethodRef = 9;
+	public static final int ErrBadConstantPoolIndex = 10;
+	public static final int ErrBadSuperclassName = 11;
+	public static final int ErrInterfaceCannotBeFinal = 12;
+	public static final int ErrInterfaceMustBeAbstract = 13;
+	public static final int ErrBadModifiers = 14;
+	public static final int ErrClassCannotBeAbstractFinal = 15;
+	public static final int ErrBadClassname = 16;
+	public static final int ErrBadFieldInfo = 17;
+	public static final int ErrBadMethodInfo = 17;
+	public static final int ErrEmptyConstantPool = 18;
+	public static final int ErrMalformedUtf8 = 19;
+	public static final int ErrUnknownConstantTag = 20;
+	public static final int ErrTruncatedInput = 21;
+	public static final int ErrMethodMustBeAbstract = 22;
+	public static final int ErrMalformedAttribute = 23;
+	public static final int ErrBadInterface = 24;
+	public static final int ErrInterfaceMustSubclassObject = 25;
+	public static final int ErrIncorrectInterfaceMethods = 26;
+	public static final int ErrInvalidMethodName = 27;
+	public static final int ErrInvalidMethodSignature = 28;
+
+	private static final long serialVersionUID = 6667458511042774540L; // backward compatible
+
+	private int errorCode;
+	private int bufferPosition;
+	private RuntimeException nestedException;
+	private char[] fileName;
+
+	public ClassFormatException(RuntimeException e, char[] fileName) {
+		this.nestedException = e;
+		this.fileName = fileName;
+	}
+	public ClassFormatException(int code) {
+		this.errorCode = code;
+	}
+	public ClassFormatException(int code, int bufPos) {
+		this.errorCode = code;
+		this.bufferPosition = bufPos;
+	}
+	/**
+	 * @return int
+	 */
+	public int getErrorCode() {
+		return this.errorCode;
+	}
+	/**
+	 * @return int
+	 */
+	public int getBufferPosition() {
+		return this.bufferPosition;
+	}
+	/**
+	 * Returns the underlying <code>Throwable</code> that caused the failure.
+	 *
+	 * @return the wrappered <code>Throwable</code>, or <code>null</code>
+	 *         if the direct case of the failure was at the Java model layer
+	 */
+	public Throwable getException() {
+		return this.nestedException;
+	}
+	public void printStackTrace() {
+		printStackTrace(System.err);
+	}
+	/**
+	 * Prints this exception's stack trace to the given print stream.
+	 *
+	 * @param output
+	 *            the print stream
+	 * @since 3.0
+	 */
+	public void printStackTrace(PrintStream output) {
+		synchronized (output) {
+			super.printStackTrace(output);
+			Throwable throwable = getException();
+			if (throwable != null) {
+				if (this.fileName != null) {
+					output.print("Caused in "); //$NON-NLS-1$
+					output.print(this.fileName);
+					output.print(" by: "); //$NON-NLS-1$
+				} else {
+					output.print("Caused by: "); //$NON-NLS-1$
+				}
+				throwable.printStackTrace(output);
+			}
+		}
+	}
+	/**
+	 * Prints this exception's stack trace to the given print writer.
+	 *
+	 * @param output
+	 *            the print writer
+	 * @since 3.0
+	 */
+	public void printStackTrace(PrintWriter output) {
+		synchronized (output) {
+			super.printStackTrace(output);
+			Throwable throwable = getException();
+			if (throwable != null) {
+				if (this.fileName != null) {
+					output.print("Caused in "); //$NON-NLS-1$
+					output.print(this.fileName);
+					output.print(" by: "); //$NON-NLS-1$
+				} else {
+					output.print("Caused by: "); //$NON-NLS-1$
+				}
+				throwable.printStackTrace(output);
+			}
+		}
+	}
+}
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
new file mode 100644
index 0000000..5a40c0d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * 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];
+
+	private char[] name;
+	private Object value;
+
+ElementValuePairInfo(char[] name, Object value) {
+	this.name = name;
+	this.value = value;
+}
+public char[] getName() {
+	return this.name;
+}
+public Object getValue() {
+	return this.value;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(this.name);
+	buffer.append('=');
+	if (this.value instanceof Object[]) {
+		final Object[] values = (Object[]) this.value;
+		buffer.append('{');
+		for (int i = 0, l = values.length; i < l; i++) {
+			if (i > 0)
+				buffer.append(", "); //$NON-NLS-1$
+			buffer.append(values[i]);
+		}
+		buffer.append('}');
+	} else {
+		buffer.append(this.value);
+	}
+	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/classfmt/FieldInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
new file mode 100644
index 0000000..8eaea09
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class FieldInfo extends ClassFileStruct implements IBinaryField, Comparable {
+	protected int accessFlags;
+	protected int attributeBytes;
+	protected Constant constant;
+	protected char[] descriptor;
+	protected char[] name;
+	protected char[] signature;
+	protected int signatureUtf8Offset;
+	protected long tagBits;
+	protected Object wrappedConstantValue;
+
+public static FieldInfo createField(byte classFileBytes[], int offsets[], int offset) {
+	FieldInfo fieldInfo = new FieldInfo(classFileBytes, offsets, offset);
+	AnnotationInfo[] annotations = fieldInfo.readAttributes();
+	if (annotations == null)
+		return fieldInfo;
+	return new FieldInfoWithAnnotation(fieldInfo, annotations);
+}
+
+/**
+ * @param classFileBytes byte[]
+ * @param offsets int[]
+ * @param offset int
+ */
+protected FieldInfo (byte classFileBytes[], int offsets[], int offset) {
+	super(classFileBytes, offsets, offset);
+	this.accessFlags = -1;
+	this.signatureUtf8Offset = -1;
+}
+private AnnotationInfo[] decodeAnnotations(int offset, boolean runtimeVisible) {
+	int numberOfAnnotations = u2At(offset + 6);
+	if (numberOfAnnotations > 0) {
+		int readOffset = offset + 8;
+		AnnotationInfo[] newInfos = null;
+		int newInfoCount = 0;
+		for (int i = 0; i < numberOfAnnotations; i++) {
+			// With the last parameter being 'false', the data structure will not be flushed out
+			AnnotationInfo newInfo = new AnnotationInfo(this.reference, this.constantPoolOffsets,
+				readOffset + this.structOffset, runtimeVisible, false);
+			readOffset += newInfo.readOffset;
+			long standardTagBits = newInfo.standardAnnotationTagBits;
+			if (standardTagBits != 0) {
+				this.tagBits |= standardTagBits;
+			} else {
+				if (newInfos == null)
+					newInfos = new AnnotationInfo[numberOfAnnotations - i];
+				newInfos[newInfoCount++] = newInfo;
+			}
+		}
+		if (newInfos != null) {
+			if (newInfoCount != newInfos.length)
+				System.arraycopy(newInfos, 0, newInfos = new AnnotationInfo[newInfoCount], 0, newInfoCount);
+			return newInfos;
+		}
+	}
+	return null; // nothing to record
+}
+public int compareTo(Object o) {
+	return new String(getName()).compareTo(new String(((FieldInfo) o).getName()));
+}
+public boolean equals(Object o) {
+	if (!(o instanceof FieldInfo)) {
+		return false;
+	}
+	return CharOperation.equals(getName(), ((FieldInfo) o).getName());
+}
+public int hashCode() {
+	return CharOperation.hashCode(getName());
+}
+/**
+ * Return the constant of the field.
+ * Return org.eclipse.jdt.internal.compiler.impl.Constant.NotAConstant if there is none.
+ * @return org.eclipse.jdt.internal.compiler.impl.Constant
+ */
+public Constant getConstant() {
+	if (this.constant == null) {
+		// read constant
+		readConstantAttribute();
+	}
+	return this.constant;
+}
+public char[] getGenericSignature() {
+	if (this.signatureUtf8Offset != -1) {
+		if (this.signature == null) {
+			// decode the signature
+			this.signature = utf8At(this.signatureUtf8Offset + 3, u2At(this.signatureUtf8Offset + 1));
+		}
+		return this.signature;
+	}
+	return null;
+}
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Set the AccDeprecated and AccSynthetic bits if necessary
+ * @return int
+ */
+public int getModifiers() {
+	if (this.accessFlags == -1) {
+		// compute the accessflag. Don't forget the deprecated attribute
+		this.accessFlags = u2At(0);
+		readModifierRelatedAttributes();
+	}
+	return this.accessFlags;
+}
+/**
+ * Answer the name of the field.
+ * @return char[]
+ */
+public char[] getName() {
+	if (this.name == null) {
+		// read the name
+		int utf8Offset = this.constantPoolOffsets[u2At(2)] - this.structOffset;
+		this.name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return this.name;
+}
+public long getTagBits() {
+	return this.tagBits;
+}
+/**
+ * Answer the resolved name of the receiver's type in the
+ * class file format as specified in section 4.3.2 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - java.lang.String is Ljava/lang/String;
+ *   - an int is I
+ *   - a 2 dimensional array of strings is [[Ljava/lang/String;
+ *   - an array of floats is [F
+ * @return char[]
+ */
+public char[] getTypeName() {
+	if (this.descriptor == null) {
+		// read the signature
+		int utf8Offset = this.constantPoolOffsets[u2At(4)] - this.structOffset;
+		this.descriptor = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return this.descriptor;
+}
+/**
+ * @return the annotations or null if there is none.
+ */
+public IBinaryAnnotation[] getAnnotations() {
+	return null;
+}
+/**
+ * Return a wrapper that contains the constant of the field.
+ * @return java.lang.Object
+ */
+public Object getWrappedConstantValue() {
+
+	if (this.wrappedConstantValue == null) {
+		if (hasConstant()) {
+			Constant fieldConstant = getConstant();
+			switch (fieldConstant.typeID()) {
+				case TypeIds.T_int :
+					this.wrappedConstantValue = new Integer(fieldConstant.intValue());
+					break;
+				case TypeIds.T_byte :
+					this.wrappedConstantValue = new Byte(fieldConstant.byteValue());
+					break;
+				case TypeIds.T_short :
+					this.wrappedConstantValue = new Short(fieldConstant.shortValue());
+					break;
+				case TypeIds.T_char :
+					this.wrappedConstantValue = new Character(fieldConstant.charValue());
+					break;
+				case TypeIds.T_float :
+					this.wrappedConstantValue = new Float(fieldConstant.floatValue());
+					break;
+				case TypeIds.T_double :
+					this.wrappedConstantValue = new Double(fieldConstant.doubleValue());
+					break;
+				case TypeIds.T_boolean :
+					this.wrappedConstantValue = Util.toBoolean(fieldConstant.booleanValue());
+					break;
+				case TypeIds.T_long :
+					this.wrappedConstantValue = new Long(fieldConstant.longValue());
+					break;
+				case TypeIds.T_JavaLangString :
+					this.wrappedConstantValue = fieldConstant.stringValue();
+			}
+		}
+	}
+	return this.wrappedConstantValue;
+}
+/**
+ * Return true if the field has a constant value attribute, false otherwise.
+ * @return boolean
+ */
+public boolean hasConstant() {
+	return getConstant() != Constant.NotAConstant;
+}
+/**
+ * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
+ * will be therefore fully initialized and we can get rid of the bytes.
+ */
+protected void initialize() {
+	getModifiers();
+	getName();
+	getConstant();
+	getTypeName();
+	getGenericSignature();
+	reset();
+}
+/**
+ * Return true if the field is a synthetic field, false otherwise.
+ * @return boolean
+ */
+public boolean isSynthetic() {
+	return (getModifiers() & ClassFileConstants.AccSynthetic) != 0;
+}
+private AnnotationInfo[] readAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	AnnotationInfo[] annotations = null;
+	for (int i = 0; i < attributesCount; i++) {
+		// check the name of each attribute
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (attributeName.length > 0) {
+			switch(attributeName[0]) {
+				case 'S' :
+					if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName))
+						this.signatureUtf8Offset = this.constantPoolOffsets[u2At(readOffset + 6)] - this.structOffset;
+					break;
+				case 'R' :
+					AnnotationInfo[] decodedAnnotations = null;
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
+						decodedAnnotations = decodeAnnotations(readOffset, true);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
+						decodedAnnotations = decodeAnnotations(readOffset, false);
+					}
+					if (decodedAnnotations != null) {
+						if (annotations == null) {
+							annotations = decodedAnnotations;
+						} else {
+							int length = annotations.length;
+							AnnotationInfo[] combined = new AnnotationInfo[length + decodedAnnotations.length];
+							System.arraycopy(annotations, 0, combined, 0, length);
+							System.arraycopy(decodedAnnotations, 0, combined, length, decodedAnnotations.length);
+							annotations = combined;
+						}
+					}
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	this.attributeBytes = readOffset;
+	return annotations;
+}
+private void readConstantAttribute() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	boolean isConstant = false;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation
+			.equals(attributeName, AttributeNamesConstants.ConstantValueName)) {
+			isConstant = true;
+			// read the right constant
+			int relativeOffset = this.constantPoolOffsets[u2At(readOffset + 6)] - this.structOffset;
+			switch (u1At(relativeOffset)) {
+				case ClassFileConstants.IntegerTag :
+					char[] sign = getTypeName();
+					if (sign.length == 1) {
+						switch (sign[0]) {
+							case 'Z' : // boolean constant
+								this.constant = BooleanConstant.fromValue(i4At(relativeOffset + 1) == 1);
+								break;
+							case 'I' : // integer constant
+								this.constant = IntConstant.fromValue(i4At(relativeOffset + 1));
+								break;
+							case 'C' : // char constant
+								this.constant = CharConstant.fromValue((char) i4At(relativeOffset + 1));
+								break;
+							case 'B' : // byte constant
+								this.constant = ByteConstant.fromValue((byte) i4At(relativeOffset + 1));
+								break;
+							case 'S' : // short constant
+								this.constant = ShortConstant.fromValue((short) i4At(relativeOffset + 1));
+								break;
+							default:
+								this.constant = Constant.NotAConstant;
+						}
+					} else {
+						this.constant = Constant.NotAConstant;
+					}
+					break;
+				case ClassFileConstants.FloatTag :
+					this.constant = FloatConstant.fromValue(floatAt(relativeOffset + 1));
+					break;
+				case ClassFileConstants.DoubleTag :
+					this.constant = DoubleConstant.fromValue(doubleAt(relativeOffset + 1));
+					break;
+				case ClassFileConstants.LongTag :
+					this.constant = LongConstant.fromValue(i8At(relativeOffset + 1));
+					break;
+				case ClassFileConstants.StringTag :
+					utf8Offset = this.constantPoolOffsets[u2At(relativeOffset + 1)] - this.structOffset;
+					this.constant =
+						StringConstant.fromValue(
+							String.valueOf(utf8At(utf8Offset + 3, u2At(utf8Offset + 1))));
+					break;
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+	if (!isConstant) {
+		this.constant = Constant.NotAConstant;
+	}
+}
+private void readModifierRelatedAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		// test added for obfuscated .class file. See 79772
+		if (attributeName.length != 0) {
+			switch(attributeName[0]) {
+				case 'D' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.DeprecatedName))
+						this.accessFlags |= ClassFileConstants.AccDeprecated;
+					break;
+				case 'S' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.SyntheticName))
+						this.accessFlags |= ClassFileConstants.AccSynthetic;
+					break;
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+}
+/**
+ * Answer the size of the receiver in bytes.
+ *
+ * @return int
+ */
+public int sizeInBytes() {
+	return this.attributeBytes;
+}
+public void throwFormatException() throws ClassFormatException {
+	throw new ClassFormatException(ClassFormatException.ErrBadFieldInfo);
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer(getClass().getName());
+	toStringContent(buffer);
+	return buffer.toString();
+}
+protected void toStringContent(StringBuffer buffer) {
+	int modifiers = getModifiers();
+	buffer
+		.append('{')
+		.append(
+			((modifiers & ClassFileConstants.AccDeprecated) != 0 ? "deprecated " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0001) == 1 ? "public " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0002) == 0x0002 ? "private " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0004) == 0x0004 ? "protected " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0008) == 0x000008 ? "static " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0010) == 0x0010 ? "final " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0040) == 0x0040 ? "volatile " : Util.EMPTY_STRING) //$NON-NLS-1$
+				+ ((modifiers & 0x0080) == 0x0080 ? "transient " : Util.EMPTY_STRING)) //$NON-NLS-1$
+		.append(getTypeName())
+		.append(' ')
+		.append(getName())
+		.append(' ')
+		.append(getConstant())
+		.append('}')
+		.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithAnnotation.java
new file mode 100644
index 0000000..4e3c435
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithAnnotation.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+public final class FieldInfoWithAnnotation extends FieldInfo {
+	private AnnotationInfo[] annotations;
+
+FieldInfoWithAnnotation(FieldInfo info, AnnotationInfo[] annos) {
+	super(info.reference, info.constantPoolOffsets, info.structOffset);
+	this.accessFlags = info.accessFlags;
+	this.attributeBytes = info.attributeBytes;
+	this.constant = info.constant;
+	this.constantPoolOffsets = info.constantPoolOffsets;
+	this.descriptor = info.descriptor;
+	this.name = info.name;
+	this.signature = info.signature;
+	this.signatureUtf8Offset = info.signatureUtf8Offset;
+	this.tagBits = info.tagBits;
+	this.wrappedConstantValue = info.wrappedConstantValue;
+	this.annotations = annos;
+}
+public org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation[] getAnnotations() {
+	return this.annotations;
+}
+protected void initialize() {
+	for (int i = 0, max = this.annotations.length; i < max; i++)
+		this.annotations[i].initialize();
+	super.initialize();
+}
+protected void reset() {
+	if (this.annotations != null)
+		for (int i = 0, max = this.annotations.length; i < max; i++)
+			this.annotations[i].reset();
+	super.reset();
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer(getClass().getName());
+	if (this.annotations != null) {
+		buffer.append('\n');
+		for (int i = 0; i < this.annotations.length; i++) {
+			buffer.append(this.annotations[i]);
+			buffer.append('\n');
+		}
+	}
+	toStringContent(buffer);
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java
new file mode 100644
index 0000000..32efeb0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+
+/**
+ * Describes one entry in the classes table of the InnerClasses attribute.
+ * See the inner class specification (The class file attribute "InnerClasses").
+ */
+
+public class InnerClassInfo extends ClassFileStruct implements IBinaryNestedType {
+	int innerClassNameIndex = -1;
+	int outerClassNameIndex = -1;
+	int innerNameIndex = -1;
+	private char[] innerClassName;
+	private char[] outerClassName;
+	private char[] innerName;
+	private int accessFlags = -1;
+	private boolean readInnerClassName = false;
+	private boolean readOuterClassName = false;
+	private boolean readInnerName = false;
+
+public InnerClassInfo(byte classFileBytes[], int offsets[], int offset) {
+	super(classFileBytes, offsets, offset);
+	this.innerClassNameIndex = u2At(0);
+	this.outerClassNameIndex = u2At(2);
+	this.innerNameIndex = u2At(4);
+}
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[]
+ */
+public char[] getEnclosingTypeName() {
+	if (!this.readOuterClassName) {
+		// read outer class name
+		this.readOuterClassName = true;
+		if (this.outerClassNameIndex != 0) {
+			int utf8Offset =
+				this.constantPoolOffsets[u2At(
+					this.constantPoolOffsets[this.outerClassNameIndex] - this.structOffset + 1)]
+					- this.structOffset;
+			this.outerClassName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		}
+
+	}
+	return this.outerClassName;
+}
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * @return int
+ */
+public int getModifiers() {
+	if (this.accessFlags == -1) {
+		// read access flag
+		this.accessFlags = u2At(6);
+	}
+	return this.accessFlags;
+}
+/**
+ * Answer the resolved name of the member type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, p1.p2.A.M is p1/p2/A$M.
+ * @return char[]
+ */
+public char[] getName() {
+	if (!this.readInnerClassName) {
+		// read the inner class name
+		this.readInnerClassName = true;
+		if (this.innerClassNameIndex != 0) {
+			int  classOffset = this.constantPoolOffsets[this.innerClassNameIndex] - this.structOffset;
+			int utf8Offset = this.constantPoolOffsets[u2At(classOffset + 1)] - this.structOffset;
+			this.innerClassName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		}
+	}
+	return this.innerClassName;
+}
+/**
+ * Answer the source name of the member type.
+ *
+ * For example, p1.p2.A.M is M.
+ * @return char[]
+ */
+public char[] getSourceName() {
+	if (!this.readInnerName) {
+		this.readInnerName = true;
+		if (this.innerNameIndex != 0) {
+			int utf8Offset = this.constantPoolOffsets[this.innerNameIndex] - this.structOffset;
+			this.innerName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		}
+	}
+	return this.innerName;
+}
+/**
+ * Answer the string representation of the receiver
+ * @return java.lang.String
+ */
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	if (getName() != null) {
+		buffer.append(getName());
+	}
+	buffer.append("\n"); //$NON-NLS-1$
+	if (getEnclosingTypeName() != null) {
+		buffer.append(getEnclosingTypeName());
+	}
+	buffer.append("\n"); //$NON-NLS-1$
+	if (getSourceName() != null) {
+		buffer.append(getSourceName());
+	}
+	return buffer.toString();
+}
+/**
+ * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
+ * will be therefore fully initialized and we can get rid of the bytes.
+ */
+void initialize() {
+	getModifiers();
+	getName();
+	getSourceName();
+	getEnclosingTypeName();
+	reset();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
new file mode 100644
index 0000000..88d60ac
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
@@ -0,0 +1,498 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class MethodInfo extends ClassFileStruct implements IBinaryMethod, Comparable {
+	static private final char[][] noException = CharOperation.NO_CHAR_CHAR;
+	static private final char[][] noArgumentNames = CharOperation.NO_CHAR_CHAR;
+	protected int accessFlags;
+	protected int attributeBytes;
+	protected char[] descriptor;
+	protected char[][] exceptionNames;
+	protected char[] name;
+	protected char[] signature;
+	protected int signatureUtf8Offset;
+	protected long tagBits;
+	protected char[][] argumentNames;
+	protected int argumentNamesIndex;
+
+public static MethodInfo createMethod(byte classFileBytes[], int offsets[], int offset) {
+	MethodInfo methodInfo = new MethodInfo(classFileBytes, offsets, offset);
+	int attributesCount = methodInfo.u2At(6);
+	int readOffset = 8;
+	AnnotationInfo[] annotations = null;
+	AnnotationInfo[][] parameterAnnotations = null;
+	for (int i = 0; i < attributesCount; i++) {
+		// check the name of each attribute
+		int utf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset)] - methodInfo.structOffset;
+		char[] attributeName = methodInfo.utf8At(utf8Offset + 3, methodInfo.u2At(utf8Offset + 1));
+		if (attributeName.length > 0) {
+			switch(attributeName[0]) {
+				case 'S' :
+					if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName))
+						methodInfo.signatureUtf8Offset = methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset + 6)] - methodInfo.structOffset;
+					break;
+				case 'R' :
+					AnnotationInfo[] methodAnnotations = null;
+					AnnotationInfo[][] paramAnnotations = null;
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
+						methodAnnotations = decodeMethodAnnotations(readOffset, true, methodInfo);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
+						methodAnnotations = decodeMethodAnnotations(readOffset, false, methodInfo);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleParameterAnnotationsName)) {
+						paramAnnotations = decodeParamAnnotations(readOffset, true, methodInfo);
+					} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleParameterAnnotationsName)) {
+						paramAnnotations = decodeParamAnnotations(readOffset, false, methodInfo);
+					}
+					if (methodAnnotations != null) {
+						if (annotations == null) {
+							annotations = methodAnnotations;
+						} else {
+							int length = annotations.length;
+							AnnotationInfo[] newAnnotations = new AnnotationInfo[length + methodAnnotations.length];
+							System.arraycopy(annotations, 0, newAnnotations, 0, length);
+							System.arraycopy(methodAnnotations, 0, newAnnotations, length, methodAnnotations.length);
+							annotations = newAnnotations;
+						}
+					} else if (paramAnnotations != null) {
+						int numberOfParameters = paramAnnotations.length;
+						if (parameterAnnotations == null) {
+							parameterAnnotations = paramAnnotations;
+						} else {
+							for (int p = 0; p < numberOfParameters; p++) {
+								int numberOfAnnotations = paramAnnotations[p] == null ? 0 : paramAnnotations[p].length;
+								if (numberOfAnnotations > 0) {
+									if (parameterAnnotations[p] == null) {
+										parameterAnnotations[p] = paramAnnotations[p];
+									} else {
+										int length = parameterAnnotations[p].length;
+										AnnotationInfo[] newAnnotations = new AnnotationInfo[length + numberOfAnnotations];
+										System.arraycopy(parameterAnnotations[p], 0, newAnnotations, 0, length);
+										System.arraycopy(paramAnnotations[p], 0, newAnnotations, length, numberOfAnnotations);
+										parameterAnnotations[p] = newAnnotations;
+									}
+								}
+							}
+						}
+					}
+					break;
+			}
+		}
+		readOffset += (6 + methodInfo.u4At(readOffset + 2));
+	}
+	methodInfo.attributeBytes = readOffset;
+
+	if (parameterAnnotations != null)
+		return new MethodInfoWithParameterAnnotations(methodInfo, annotations, parameterAnnotations);
+	if (annotations != null)
+		return new MethodInfoWithAnnotations(methodInfo, annotations);
+	return methodInfo;
+}
+static AnnotationInfo[] decodeAnnotations(int offset, boolean runtimeVisible, int numberOfAnnotations, MethodInfo methodInfo) {
+	AnnotationInfo[] result = new AnnotationInfo[numberOfAnnotations];
+	int readOffset = offset;
+	for (int i = 0; i < numberOfAnnotations; i++) {
+		result[i] = new AnnotationInfo(methodInfo.reference, methodInfo.constantPoolOffsets,
+			readOffset + methodInfo.structOffset, runtimeVisible, false);
+		readOffset += result[i].readOffset;
+	}
+	return result;
+}
+static AnnotationInfo[] decodeMethodAnnotations(int offset, boolean runtimeVisible, MethodInfo methodInfo) {
+	int numberOfAnnotations = methodInfo.u2At(offset + 6);
+	if (numberOfAnnotations > 0) {
+		AnnotationInfo[] annos = decodeAnnotations(offset + 8, runtimeVisible, numberOfAnnotations, methodInfo);
+		if (runtimeVisible){
+			int numStandardAnnotations = 0;
+			for( int i=0; i<numberOfAnnotations; i++ ){
+				long standardAnnoTagBits = annos[i].standardAnnotationTagBits;
+				methodInfo.tagBits |= standardAnnoTagBits;
+				if(standardAnnoTagBits != 0){
+					annos[i] = null;
+					numStandardAnnotations ++;
+				}
+			}
+
+			if( numStandardAnnotations != 0 ){
+				if( numStandardAnnotations == numberOfAnnotations )
+					return null;
+
+				// need to resize
+				AnnotationInfo[] temp = new AnnotationInfo[numberOfAnnotations - numStandardAnnotations ];
+				int tmpIndex = 0;
+				for (int i = 0; i < numberOfAnnotations; i++)
+					if (annos[i] != null)
+						temp[tmpIndex ++] = annos[i];
+				annos = temp;
+			}
+		}
+		return annos;
+	}
+	return null;
+}
+static AnnotationInfo[][] decodeParamAnnotations(int offset, boolean runtimeVisible, MethodInfo methodInfo) {
+	AnnotationInfo[][] allParamAnnotations = null;
+	int numberOfParameters = methodInfo.u1At(offset + 6);
+	if (numberOfParameters > 0) {
+		// u2 attribute_name_index + u4 attribute_length + u1 num_parameters
+		int readOffset = offset + 7;
+		for (int i=0 ; i < numberOfParameters; i++) {
+			int numberOfAnnotations = methodInfo.u2At(readOffset);
+			readOffset += 2;
+			if (numberOfAnnotations > 0) {
+				if (allParamAnnotations == null)
+					allParamAnnotations = new AnnotationInfo[numberOfParameters][];
+				AnnotationInfo[] annos = decodeAnnotations(readOffset, runtimeVisible, numberOfAnnotations, methodInfo);
+				allParamAnnotations[i] = annos;
+				for (int aIndex = 0; aIndex < annos.length; aIndex++)
+					readOffset += annos[aIndex].readOffset;
+			}
+		}
+	}
+	return allParamAnnotations;
+}
+
+/**
+ * @param classFileBytes byte[]
+ * @param offsets int[]
+ * @param offset int
+ */
+protected MethodInfo (byte classFileBytes[], int offsets[], int offset) {
+	super(classFileBytes, offsets, offset);
+	this.accessFlags = -1;
+	this.signatureUtf8Offset = -1;
+}
+public int compareTo(Object o) {
+	MethodInfo otherMethod = (MethodInfo) o;
+	int result = new String(getSelector()).compareTo(new String(otherMethod.getSelector()));
+	if (result != 0) return result;
+	return new String(getMethodDescriptor()).compareTo(new String(otherMethod.getMethodDescriptor()));
+}
+public boolean equals(Object o) {
+	if (!(o instanceof MethodInfo)) {
+		return false;
+	}
+	MethodInfo otherMethod = (MethodInfo) o;
+	return CharOperation.equals(getSelector(), otherMethod.getSelector())
+			&& CharOperation.equals(getMethodDescriptor(), otherMethod.getMethodDescriptor());
+}
+public int hashCode() {
+	return CharOperation.hashCode(getSelector()) + CharOperation.hashCode(getMethodDescriptor());
+}
+/**
+ * @return the annotations or null if there is none.
+ */
+public IBinaryAnnotation[] getAnnotations() {
+	return null;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IGenericMethod#getArgumentNames()
+ */
+public char[][] getArgumentNames() {
+	if (this.argumentNames == null) {
+		readCodeAttribute();
+	}
+	return this.argumentNames;
+}
+public Object getDefaultValue() {
+	return null;
+}
+/**
+ * Answer the resolved names of the exception types in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ * @return char[][]
+ */
+public char[][] getExceptionTypeNames() {
+	if (this.exceptionNames == null) {
+		readExceptionAttributes();
+	}
+	return this.exceptionNames;
+}
+public char[] getGenericSignature() {
+	if (this.signatureUtf8Offset != -1) {
+		if (this.signature == null) {
+			// decode the signature
+			this.signature = utf8At(this.signatureUtf8Offset + 3, u2At(this.signatureUtf8Offset + 1));
+		}
+		return this.signature;
+	}
+	return null;
+}
+/**
+ * Answer the receiver's method descriptor which describes the parameter &
+ * return types as specified in section 4.3.3 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - int foo(String) is (Ljava/lang/String;)I
+ *   - void foo(Object[]) is (I)[Ljava/lang/Object;
+ * @return char[]
+ */
+public char[] getMethodDescriptor() {
+	if (this.descriptor == null) {
+		// read the name
+		int utf8Offset = this.constantPoolOffsets[u2At(4)] - this.structOffset;
+		this.descriptor = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return this.descriptor;
+}
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Set the AccDeprecated and AccSynthetic bits if necessary
+ * @return int
+ */
+public int getModifiers() {
+	if (this.accessFlags == -1) {
+		// compute the accessflag. Don't forget the deprecated attribute
+		this.accessFlags = u2At(0);
+		readModifierRelatedAttributes();
+	}
+	return this.accessFlags;
+}
+public IBinaryAnnotation[] getParameterAnnotations(int index) {
+	return null;
+}
+public int getAnnotatedParametersCount() {
+	return 0;
+}
+/**
+ * Answer the name of the method.
+ *
+ * For a constructor, answer <init> & <clinit> for a clinit method.
+ * @return char[]
+ */
+public char[] getSelector() {
+	if (this.name == null) {
+		// read the name
+		int utf8Offset = this.constantPoolOffsets[u2At(2)] - this.structOffset;
+		this.name = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+	}
+	return this.name;
+}
+public long getTagBits() {
+	return this.tagBits;
+}
+/**
+ * This method is used to fully initialize the contents of the receiver. All methodinfos, fields infos
+ * will be therefore fully initialized and we can get rid of the bytes.
+ */
+protected void initialize() {
+	getModifiers();
+	getSelector();
+	getMethodDescriptor();
+	getExceptionTypeNames();
+	getGenericSignature();
+	getArgumentNames();
+	reset();
+}
+/**
+ * Answer true if the method is a class initializer, false otherwise.
+ * @return boolean
+ */
+public boolean isClinit() {
+	char[] selector = getSelector();
+	return selector[0] == '<' && selector.length == 8; // Can only match <clinit>
+}
+/**
+ * Answer true if the method is a constructor, false otherwise.
+ * @return boolean
+ */
+public boolean isConstructor() {
+	char[] selector = getSelector();
+	return selector[0] == '<' && selector.length == 6; // Can only match <init>
+}
+/**
+ * Return true if the field is a synthetic method, false otherwise.
+ * @return boolean
+ */
+public boolean isSynthetic() {
+	return (getModifiers() & ClassFileConstants.AccSynthetic) != 0;
+}
+private void readExceptionAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, AttributeNamesConstants.ExceptionsName)) {
+			// read the number of exception entries
+			int entriesNumber = u2At(readOffset + 6);
+			// place the readOffset at the beginning of the exceptions table
+			readOffset += 8;
+			if (entriesNumber == 0) {
+				this.exceptionNames = noException;
+			} else {
+				this.exceptionNames = new char[entriesNumber][];
+				for (int j = 0; j < entriesNumber; j++) {
+					utf8Offset =
+						this.constantPoolOffsets[u2At(
+							this.constantPoolOffsets[u2At(readOffset)] - this.structOffset + 1)]
+							- this.structOffset;
+					this.exceptionNames[j] = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+					readOffset += 2;
+				}
+			}
+		} else {
+			readOffset += (6 + u4At(readOffset + 2));
+		}
+	}
+	if (this.exceptionNames == null) {
+		this.exceptionNames = noException;
+	}
+}
+private void readModifierRelatedAttributes() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		// test added for obfuscated .class file. See 79772
+		if (attributeName.length != 0) {
+			switch(attributeName[0]) {
+				case 'D' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.DeprecatedName))
+						this.accessFlags |= ClassFileConstants.AccDeprecated;
+					break;
+				case 'S' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.SyntheticName))
+						this.accessFlags |= ClassFileConstants.AccSynthetic;
+					break;
+				case 'A' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.AnnotationDefaultName))
+						this.accessFlags |= ClassFileConstants.AccAnnotationDefault;
+					break;
+				case 'V' :
+					if (CharOperation.equals(attributeName, AttributeNamesConstants.VarargsName))
+						this.accessFlags |= ClassFileConstants.AccVarargs;
+			}
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+}
+/**
+ * Answer the size of the receiver in bytes.
+ *
+ * @return int
+ */
+public int sizeInBytes() {
+	return this.attributeBytes;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	toString(buffer);
+	return buffer.toString();
+}
+void toString(StringBuffer buffer) {
+	buffer.append(getClass().getName());
+	toStringContent(buffer);
+}
+protected void toStringContent(StringBuffer buffer) {
+	int modifiers = getModifiers();
+	char[] desc = getGenericSignature();
+	if (desc == null)
+		desc = getMethodDescriptor();
+	buffer
+	.append('{')
+	.append(
+		((modifiers & ClassFileConstants.AccDeprecated) != 0 ? "deprecated " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0001) == 1 ? "public " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0002) == 0x0002 ? "private " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0004) == 0x0004 ? "protected " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0008) == 0x000008 ? "static " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0010) == 0x0010 ? "final " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0040) == 0x0040 ? "bridge " : Util.EMPTY_STRING) //$NON-NLS-1$
+			+ ((modifiers & 0x0080) == 0x0080 ? "varargs " : Util.EMPTY_STRING)) //$NON-NLS-1$
+	.append(getSelector())
+	.append(desc)
+	.append('}');
+}
+private void readCodeAttribute() {
+	int attributesCount = u2At(6);
+	int readOffset = 8;
+	if (attributesCount != 0) {
+		for (int i = 0; i < attributesCount; i++) {
+			int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+			char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+			if (CharOperation.equals(attributeName, AttributeNamesConstants.CodeName)) {
+				decodeCodeAttribute(readOffset);
+				if (this.argumentNames == null) {
+					this.argumentNames = noArgumentNames;
+				}
+				return;
+			} else {
+				readOffset += (6 + u4At(readOffset + 2));
+			}
+		}
+	}
+	this.argumentNames = noArgumentNames;
+}
+private void decodeCodeAttribute(int offset) {
+	int readOffset = offset + 10;
+	int codeLength = (int) u4At(readOffset);
+	readOffset += (4 + codeLength);
+	int exceptionTableLength = u2At(readOffset);
+	readOffset += 2;
+	if (exceptionTableLength != 0) {
+		for (int i = 0; i < exceptionTableLength; i++) {
+			readOffset += 8;
+		}
+	}
+	int attributesCount = u2At(readOffset);
+	readOffset += 2;
+	for (int i = 0; i < attributesCount; i++) {
+		int utf8Offset = this.constantPoolOffsets[u2At(readOffset)] - this.structOffset;
+		char[] attributeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+		if (CharOperation.equals(attributeName, AttributeNamesConstants.LocalVariableTableName)) {
+			decodeLocalVariableAttribute(readOffset, codeLength);
+		}
+		readOffset += (6 + u4At(readOffset + 2));
+	}
+}
+private void decodeLocalVariableAttribute(int offset, int codeLength) {
+	int readOffset = offset + 6;
+	final int length = u2At(readOffset);
+	if (length != 0) {
+		readOffset += 2;
+		this.argumentNames = new char[length][];
+		this.argumentNamesIndex = 0;
+		for (int i = 0; i < length; i++) {
+			int startPC = u2At(readOffset);
+			if (startPC == 0) {
+				int nameIndex = u2At(4 + readOffset);
+				int utf8Offset = this.constantPoolOffsets[nameIndex] - this.structOffset;
+				char[] localVariableName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
+				if (!CharOperation.equals(localVariableName, ConstantPool.This)) {
+					this.argumentNames[this.argumentNamesIndex++] = localVariableName;
+				}
+			} else {
+				break;
+			}
+			readOffset += 10;
+		}
+		if (this.argumentNamesIndex != this.argumentNames.length) {
+			// resize
+			System.arraycopy(this.argumentNames, 0, (this.argumentNames = new char[this.argumentNamesIndex][]), 0, this.argumentNamesIndex);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java
new file mode 100644
index 0000000..4db5b95
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+
+public class MethodInfoWithAnnotations extends MethodInfo {
+	protected AnnotationInfo[] annotations;
+
+MethodInfoWithAnnotations(MethodInfo methodInfo, AnnotationInfo[] annotations) {
+	super(methodInfo.reference, methodInfo.constantPoolOffsets, methodInfo.structOffset);
+	this.annotations = annotations;
+
+	this.accessFlags = methodInfo.accessFlags;
+	this.attributeBytes = methodInfo.attributeBytes;
+	this.descriptor = methodInfo.descriptor;
+	this.exceptionNames = methodInfo.exceptionNames;
+	this.name = methodInfo.name;
+	this.signature = methodInfo.signature;
+	this.signatureUtf8Offset = methodInfo.signatureUtf8Offset;
+	this.tagBits = methodInfo.tagBits;
+}
+public IBinaryAnnotation[] getAnnotations() {
+	return this.annotations;
+}
+protected void initialize() {
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++)
+		if (this.annotations[i] != null)
+			this.annotations[i].initialize();
+	super.initialize();
+}
+protected void reset() {
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++)
+		if (this.annotations[i] != null)
+			this.annotations[i].reset();
+	super.reset();
+}
+protected void toStringContent(StringBuffer buffer) {
+	super.toStringContent(buffer);
+	for (int i = 0, l = this.annotations == null ? 0 : this.annotations.length; i < l; i++) {
+		buffer.append(this.annotations[i]);
+		buffer.append('\n');
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java
new file mode 100644
index 0000000..27f4ea2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com  - initial API and implementation
+ *    IBM Corporation - fix for bug 342757
+ *    Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.classfmt;
+
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+
+class MethodInfoWithParameterAnnotations extends MethodInfoWithAnnotations {
+	private AnnotationInfo[][] parameterAnnotations;
+
+MethodInfoWithParameterAnnotations(MethodInfo methodInfo, AnnotationInfo[] annotations, AnnotationInfo[][] parameterAnnotations) {
+	super(methodInfo, annotations);
+	this.parameterAnnotations = parameterAnnotations;
+}
+public IBinaryAnnotation[] getParameterAnnotations(int index) {
+	return this.parameterAnnotations[index];
+}
+public int getAnnotatedParametersCount() {
+	return this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length;
+}
+protected void initialize() {
+	for (int i = 0, l = this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length; i < l; i++) {
+		AnnotationInfo[] infos = this.parameterAnnotations[i];
+		for (int j = 0, k = infos == null ? 0 : infos.length; j < k; j++)
+			infos[j].initialize();
+	}
+	super.initialize();
+}
+protected void reset() {
+	for (int i = 0, l = this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length; i < l; i++) {
+		AnnotationInfo[] infos = this.parameterAnnotations[i];
+		for (int j = 0, k = infos == null ? 0 : infos.length; j < k; j++)
+			infos[j].reset();
+	}
+	super.reset();
+}
+protected void toStringContent(StringBuffer buffer) {
+	super.toStringContent(buffer);
+	for (int i = 0, l = this.parameterAnnotations == null ? 0 : this.parameterAnnotations.length; i < l; i++) {
+		buffer.append("param" + (i - 1)); //$NON-NLS-1$
+		buffer.append('\n');
+		AnnotationInfo[] infos = this.parameterAnnotations[i];
+		for (int j = 0, k = infos == null ? 0 : infos.length; j < k; j++) {
+			buffer.append(infos[j]);
+			buffer.append('\n');
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java
new file mode 100644
index 0000000..c743d43
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationContext.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+
+public class AnnotationContext {
+	public static final int VISIBLE = 0x1;
+	public static final int INVISIBLE = 0x2;
+	public Annotation annotation;
+	public TypeReference typeReference;
+	public int targetType;
+	public int info;
+	public int info2;
+	public int visibility;
+	public Annotation[] primaryAnnotations;
+	public LocalVariableBinding variableBinding;
+	public Annotation[][] annotationsOnDimensions;
+	public Wildcard wildcard;
+	// annotationsOnDimensions might be null but the dimensions may still be important. In some
+	// cases they are not on the reference.
+	public int dimensions;
+
+	public AnnotationContext(
+			Annotation annotation,
+			TypeReference typeReference,
+			int targetType,
+			Annotation[] primaryAnnotations,
+			int visibility,
+			Annotation[][] annotationsOnDimensions,
+			int dimensions) {
+		this.annotation = annotation;
+		this.typeReference = typeReference;
+		this.targetType = targetType;
+		this.primaryAnnotations = primaryAnnotations;
+		this.visibility = visibility;
+		this.annotationsOnDimensions = annotationsOnDimensions;
+		this.dimensions = dimensions;
+	}
+
+	public String toString() {
+		return "AnnotationContext [annotation=" //$NON-NLS-1$
+				+ this.annotation
+				+ ", typeReference=" //$NON-NLS-1$
+				+ this.typeReference
+				+ ", targetType=" //$NON-NLS-1$
+				+ this.targetType
+				+ ", info =" //$NON-NLS-1$
+				+ this.info
+				+ ", boundIndex=" //$NON-NLS-1$
+				+ this.info2
+				+ "]"; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java
new file mode 100644
index 0000000..919247a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AnnotationTargetTypeConstants.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public interface AnnotationTargetTypeConstants {
+
+	// Targets for type parameter declarations
+	int CLASS_TYPE_PARAMETER                 = 0x00;
+	int METHOD_TYPE_PARAMETER                = 0x01;
+
+	// Targets that may be externally visible in classes and members
+	int CLASS_EXTENDS                        = 0x10;
+	int CLASS_TYPE_PARAMETER_BOUND           = 0x11;
+	int METHOD_TYPE_PARAMETER_BOUND          = 0x12;
+	int FIELD                                = 0x13;
+	int METHOD_RETURN                        = 0x14;
+	int METHOD_RECEIVER                      = 0x15;
+	int METHOD_FORMAL_PARAMETER              = 0x16;
+	int THROWS                               = 0x17;
+
+	// Targets for type uses that occur only within code blocks
+	int LOCAL_VARIABLE                       = 0x40;
+	int RESOURCE_VARIABLE                    = 0x41;
+	int EXCEPTION_PARAMETER                  = 0x42;
+	int INSTANCEOF                           = 0x43;
+	int NEW                                  = 0x44;
+	int CONSTRUCTOR_REFERENCE                = 0x45;
+	int METHOD_REFERENCE                     = 0x46;
+	int CAST                                 = 0x47;
+	int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
+	int METHOD_INVOCATION_TYPE_ARGUMENT      = 0x49;
+	int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT  = 0x4A;
+	int METHOD_REFERENCE_TYPE_ARGUMENT       = 0x4B;
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
new file mode 100644
index 0000000..8fd41ec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public interface AttributeNamesConstants {
+	final char[] SyntheticName = "Synthetic".toCharArray(); //$NON-NLS-1$
+	final char[] ConstantValueName = "ConstantValue".toCharArray(); //$NON-NLS-1$
+	final char[] LineNumberTableName = "LineNumberTable".toCharArray(); //$NON-NLS-1$
+	final char[] LocalVariableTableName = "LocalVariableTable".toCharArray(); //$NON-NLS-1$
+	final char[] InnerClassName = "InnerClasses".toCharArray(); //$NON-NLS-1$
+	final char[] CodeName = "Code".toCharArray(); //$NON-NLS-1$
+	final char[] ExceptionsName = "Exceptions".toCharArray(); //$NON-NLS-1$
+	final char[] SourceName = "SourceFile".toCharArray(); //$NON-NLS-1$
+	final char[] DeprecatedName = "Deprecated".toCharArray(); //$NON-NLS-1$
+	final char[] SignatureName = "Signature".toCharArray(); //$NON-NLS-1$
+	final char[] LocalVariableTypeTableName = "LocalVariableTypeTable".toCharArray(); //$NON-NLS-1$
+	final char[] EnclosingMethodName = "EnclosingMethod".toCharArray(); //$NON-NLS-1$
+	final char[] AnnotationDefaultName = "AnnotationDefault".toCharArray(); //$NON-NLS-1$
+	final char[] RuntimeInvisibleAnnotationsName = "RuntimeInvisibleAnnotations".toCharArray(); //$NON-NLS-1$
+	final char[] RuntimeVisibleAnnotationsName = "RuntimeVisibleAnnotations".toCharArray(); //$NON-NLS-1$
+	final char[] RuntimeInvisibleParameterAnnotationsName = "RuntimeInvisibleParameterAnnotations".toCharArray(); //$NON-NLS-1$
+	final char[] RuntimeVisibleParameterAnnotationsName = "RuntimeVisibleParameterAnnotations".toCharArray(); //$NON-NLS-1$
+	final char[] StackMapTableName = "StackMapTable".toCharArray(); //$NON-NLS-1$
+	final char[] InconsistentHierarchy = "InconsistentHierarchy".toCharArray(); //$NON-NLS-1$
+	final char[] VarargsName = "Varargs".toCharArray(); //$NON-NLS-1$
+	final char[] StackMapName = "StackMap".toCharArray(); //$NON-NLS-1$
+	final char[] MissingTypesName = "MissingTypes".toCharArray(); //$NON-NLS-1$
+	final char[] BootstrapMethodsName = "BootstrapMethods".toCharArray(); //$NON-NLS-1$
+	// jsr308
+	final char[] RuntimeVisibleTypeAnnotationsName = "RuntimeVisibleTypeAnnotations".toCharArray(); //$NON-NLS-1$
+	final char[] RuntimeInvisibleTypeAnnotationsName = "RuntimeInvisibleTypeAnnotations".toCharArray(); //$NON-NLS-1$
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/BranchLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/BranchLabel.java
new file mode 100644
index 0000000..ccf4cc7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/BranchLabel.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import java.util.Arrays;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+
+public class BranchLabel extends Label {
+
+	private int[] forwardReferences = new int[10]; // Add an overflow check here.
+	private int forwardReferenceCount = 0;
+	BranchLabel delegate; //
+
+	// Label tagbits
+	public int tagBits;
+	public final static int WIDE = 1;
+	public final static int USED = 2;
+
+public BranchLabel() {
+	// for creating labels ahead of code generation
+}
+
+/**
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public BranchLabel(CodeStream codeStream) {
+	super(codeStream);
+}
+
+/**
+ * Add a forward refrence for the array.
+ */
+void addForwardReference(int pos) {
+	if (this.delegate != null) {
+		this.delegate.addForwardReference(pos);
+		return;
+	}
+	final int count = this.forwardReferenceCount;
+	if (count >= 1) {
+		int previousValue = this.forwardReferences[count - 1];
+		if (previousValue < pos) {
+			int length;
+			if (count >= (length = this.forwardReferences.length))
+				System.arraycopy(this.forwardReferences, 0, (this.forwardReferences = new int[2*length]), 0, length);
+			this.forwardReferences[this.forwardReferenceCount++] = pos;
+		} else if (previousValue > pos) {
+			int[] refs = this.forwardReferences;
+			// check for duplicates
+			for (int i = 0, max = this.forwardReferenceCount; i < max; i++) {
+				if (refs[i] == pos) return; // already recorded
+			}
+			int length;
+			if (count >= (length = refs.length))
+				System.arraycopy(refs, 0, (this.forwardReferences = new int[2*length]), 0, length);
+			this.forwardReferences[this.forwardReferenceCount++] = pos;
+			Arrays.sort(this.forwardReferences, 0, this.forwardReferenceCount);
+		}
+	} else {
+		int length;
+		if (count >= (length = this.forwardReferences.length))
+			System.arraycopy(this.forwardReferences, 0, (this.forwardReferences = new int[2*length]), 0, length);
+		this.forwardReferences[this.forwardReferenceCount++] = pos;
+	}
+}
+
+/**
+ * Makes the current label inline all references to the other label
+ */
+public void becomeDelegateFor(BranchLabel otherLabel) {
+	// other label is delegating to receiver from now on
+	otherLabel.delegate = this;
+
+	// all existing forward refs to other label are inlined into current label
+	final int otherCount = otherLabel.forwardReferenceCount;
+	if (otherCount == 0) return;
+	// need to merge the two sorted arrays of forward references
+	int[] mergedForwardReferences = new int[this.forwardReferenceCount + otherCount];
+	int indexInMerge = 0;
+	int j = 0;
+	int i = 0;
+	int max = this.forwardReferenceCount;
+	int max2 = otherLabel.forwardReferenceCount;
+	loop1 : for (; i < max; i++) {
+		final int value1 = this.forwardReferences[i];
+		for (; j < max2; j++) {
+			final int value2 = otherLabel.forwardReferences[j];
+			if (value1 < value2) {
+				mergedForwardReferences[indexInMerge++] = value1;
+				continue loop1;
+			} else if (value1 == value2) {
+				mergedForwardReferences[indexInMerge++] = value1;
+				j++;
+				continue loop1;
+			} else {
+				mergedForwardReferences[indexInMerge++] = value2;
+			}
+		}
+		mergedForwardReferences[indexInMerge++] = value1;
+	}
+	for (; j < max2; j++) {
+		mergedForwardReferences[indexInMerge++] = otherLabel.forwardReferences[j];
+	}
+	this.forwardReferences = mergedForwardReferences;
+	this.forwardReferenceCount = indexInMerge;
+}
+
+/*
+* Put down  a reference to the array at the location in the codestream.
+*/
+void branch() {
+	this.tagBits |= BranchLabel.USED;
+	if (this.delegate != null) {
+		this.delegate.branch();
+		return;
+	}
+	if (this.position == Label.POS_NOT_SET) {
+		addForwardReference(this.codeStream.position);
+		// Leave two bytes free to generate the jump afterwards
+		this.codeStream.position += 2;
+		this.codeStream.classFileOffset += 2;
+	} else {
+		/*
+		 * Position is set. Write it if it is not a wide branch.
+		 */
+		this.codeStream.writePosition(this);
+	}
+}
+
+/*
+* No support for wide branches yet
+*/
+void branchWide() {
+	this.tagBits |= BranchLabel.USED;
+	if (this.delegate != null) {
+		this.delegate.branchWide();
+		return;
+	}
+	if (this.position == Label.POS_NOT_SET) {
+		addForwardReference(this.codeStream.position);
+		// Leave 4 bytes free to generate the jump offset afterwards
+		this.tagBits |= BranchLabel.WIDE;
+		this.codeStream.position += 4;
+		this.codeStream.classFileOffset += 4;
+	} else { //Position is set. Write it!
+		this.codeStream.writeWidePosition(this);
+	}
+}
+
+public int forwardReferenceCount() {
+	if (this.delegate != null) this.delegate.forwardReferenceCount();
+	return this.forwardReferenceCount;
+}
+public int[] forwardReferences() {
+	if (this.delegate != null) this.delegate.forwardReferences();
+	return this.forwardReferences;
+}
+public void initialize(CodeStream stream) {
+    this.codeStream = stream;
+   	this.position = Label.POS_NOT_SET;
+	this.forwardReferenceCount = 0;
+	this.delegate = null;
+}
+public boolean isCaseLabel() {
+	return false;
+}
+public boolean isStandardLabel(){
+	return true;
+}
+
+/*
+* Place the label. If we have forward references resolve them.
+*/
+public void place() { // Currently lacking wide support.
+//	if ((this.tagBits & USED) == 0 && this.forwardReferenceCount == 0) {
+//		return;
+//	}
+
+	//TODO how can position be set already ? cannot place more than once
+	if (this.position == Label.POS_NOT_SET) {
+		this.position = this.codeStream.position;
+		this.codeStream.addLabel(this);
+		int oldPosition = this.position;
+		boolean isOptimizedBranch = false;
+		if (this.forwardReferenceCount != 0) {
+			isOptimizedBranch = (this.forwardReferences[this.forwardReferenceCount - 1] + 2 == this.position) && (this.codeStream.bCodeStream[this.codeStream.classFileOffset - 3] == Opcodes.OPC_goto);
+			if (isOptimizedBranch) {
+				if (this.codeStream.lastAbruptCompletion == this.position) {
+					this.codeStream.lastAbruptCompletion = -1;
+				}
+				this.codeStream.position = (this.position -= 3);
+				this.codeStream.classFileOffset -= 3;
+				this.forwardReferenceCount--;
+				if (this.codeStream.lastEntryPC == oldPosition) {
+					this.codeStream.lastEntryPC = this.position;
+				}
+				// end of new code
+				if ((this.codeStream.generateAttributes & (ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_STACK_MAP_TABLE | ClassFileConstants.ATTR_STACK_MAP)) != 0) {
+					LocalVariableBinding locals[] = this.codeStream.locals;
+					for (int i = 0, max = locals.length; i < max; i++) {
+						LocalVariableBinding local = locals[i];
+						if ((local != null) && (local.initializationCount > 0)) {
+							if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == oldPosition) {
+								// we want to prevent interval of size 0 to have a negative size.
+								// see PR 1GIRQLA: ITPJCORE:ALL - ClassFormatError for local variable attribute
+								local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position;
+							}
+							if (local.initializationPCs[(local.initializationCount - 1) << 1] == oldPosition) {
+								local.initializationPCs[(local.initializationCount - 1) << 1] = this.position;
+							}
+						}
+					}
+				}
+				if ((this.codeStream.generateAttributes & ClassFileConstants.ATTR_LINES) != 0) {
+					// we need to remove all entries that is beyond this.position inside the pcToSourcerMap table
+					this.codeStream.removeUnusedPcToSourceMapEntries();
+				}
+			}
+		}
+		for (int i = 0; i < this.forwardReferenceCount; i++) {
+			this.codeStream.writePosition(this, this.forwardReferences[i]);
+		}
+		// For all labels placed at that position we check if we need to rewrite the jump
+		// offset. It is the case each time a label had a forward reference to the current position.
+		// Like we change the current position, we have to change the jump offset. See 1F4IRD9 for more details.
+		if (isOptimizedBranch) {
+			this.codeStream.optimizeBranch(oldPosition, this);
+		}
+	}
+}
+
+/**
+ * Print out the receiver
+ */
+public String toString() {
+	String basic = getClass().getName();
+	basic = basic.substring(basic.lastIndexOf('.')+1);
+	StringBuffer buffer = new StringBuffer(basic);
+	buffer.append('@').append(Integer.toHexString(hashCode()));
+	buffer.append("(position=").append(this.position); //$NON-NLS-1$
+	if (this.delegate != null) buffer.append("delegate=").append(this.delegate); //$NON-NLS-1$
+	buffer.append(", forwards = ["); //$NON-NLS-1$
+	for (int i = 0; i < this.forwardReferenceCount - 1; i++)
+		buffer.append(this.forwardReferences[i] + ", "); //$NON-NLS-1$
+	if (this.forwardReferenceCount >= 1)
+		buffer.append(this.forwardReferences[this.forwardReferenceCount-1]);
+	buffer.append("] )"); //$NON-NLS-1$
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CachedIndexEntry.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CachedIndexEntry.java
new file mode 100644
index 0000000..b1ad89b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CachedIndexEntry.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class CachedIndexEntry {
+	public char[] signature;
+	public int index;
+
+	public CachedIndexEntry(char[] signature, int index) {
+		this.signature = signature;
+		this.index = index;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
new file mode 100644
index 0000000..ed1180b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class CaseLabel extends BranchLabel {
+
+	public int instructionPosition = POS_NOT_SET;
+
+/**
+ * CaseLabel constructor comment.
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ */
+public CaseLabel(CodeStream codeStream) {
+	super(codeStream);
+}
+
+/*
+* Put down  a reference to the array at the location in the codestream.
+* #placeInstruction() must be performed prior to any #branch()
+*/
+void branch() {
+	if (this.position == POS_NOT_SET) {
+		addForwardReference(this.codeStream.position);
+		// Leave 4 bytes free to generate the jump offset afterwards
+		this.codeStream.position += 4;
+		this.codeStream.classFileOffset += 4;
+	} else { //Position is set. Write it!
+		/*
+		 * Position is set. Write it if it is not a wide branch.
+		 */
+		this.codeStream.writeSignedWord(this.position - this.instructionPosition);
+	}
+}
+
+/*
+* No support for wide branches yet
+*/
+void branchWide() {
+	branch(); // case label branch is already wide
+}
+
+public boolean isCaseLabel() {
+	return true;
+}
+public boolean isStandardLabel(){
+	return false;
+}
+/*
+* Put down  a reference to the array at the location in the codestream.
+*/
+public void place() {
+	if ((this.tagBits & USED) != 0) {
+		this.position = this.codeStream.getPosition();
+	} else {
+		this.position = this.codeStream.position;
+	}
+	if (this.instructionPosition != POS_NOT_SET) {
+		int offset = this.position - this.instructionPosition;
+		int[] forwardRefs = forwardReferences();
+		for (int i = 0, length = forwardReferenceCount(); i < length; i++) {
+			this.codeStream.writeSignedWord(forwardRefs[i], offset);
+		}
+		// add the label in the codeStream labels collection
+		this.codeStream.addLabel(this);
+	}
+}
+
+/*
+* Put down  a reference to the array at the location in the codestream.
+*/
+void placeInstruction() {
+	if (this.instructionPosition == POS_NOT_SET) {
+		this.instructionPosition = this.codeStream.position;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java
new file mode 100644
index 0000000..177e5f5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class CharArrayCache {
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[] keyTable[];
+	public int valueTable[];
+	int elementSize; // number of elements in the table
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity is used.
+ * Note that the hashtable will automatically grow when it gets full.
+ */
+public CharArrayCache() {
+	this(9);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *	the initial number of buckets; must be less than Integer.MAX_VALUE / 2
+ */
+public CharArrayCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.threshold = (initialCapacity * 2) / 3; // faster than float operation
+	this.keyTable = new char[initialCapacity][];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = null;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key char[] the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(char[] key) {
+	int length = this.keyTable.length, index = CharOperation.hashCode(key) % length;
+	while (this.keyTable[index] != null) {
+		if (CharOperation.equals(this.keyTable[index], key))
+			return true;
+		if (++index == length) { // faster than modulo
+			index = 0;
+		}
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>char[]</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *	defined in the hash table.
+ */
+public int get(char[] key) {
+	int length = this.keyTable.length, index = CharOperation.hashCode(key) % length;
+	while (this.keyTable[index] != null) {
+		if (CharOperation.equals(this.keyTable[index], key))
+			return this.valueTable[index];
+		if (++index == length) { // faster than modulo
+			index = 0;
+		}
+	}
+	return -1;
+}
+/**
+ * Puts the specified element into the hashtable if it wasn't there already,
+ * using the specified key.  The element may be retrieved by doing a get() with the same key.
+ * The key and the element cannot be null.
+ *
+ * @param key the given key in the hashtable
+ * @param value the given value
+ * @return int the old value of the key, or -value if it did not have one.
+ */
+public int putIfAbsent(char[] key, int value) {
+	int length = this.keyTable.length, index = CharOperation.hashCode(key) % length;
+	while (this.keyTable[index] != null) {
+		if (CharOperation.equals(this.keyTable[index], key))
+			return this.valueTable[index];
+		if (++index == length) { // faster than modulo
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return -value; // negative when added (value is assumed to be > 0)
+}
+
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * The key and the element cannot be null.
+ *
+ * @param key <CODE>Object</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int the old value of the key, or -1 if it did not have one.
+ */
+private int put(char[] key, int value) {
+	int length = this.keyTable.length, index = CharOperation.hashCode(key) % length;
+	while (this.keyTable[index] != null) {
+		if (CharOperation.equals(this.keyTable[index], key))
+			return this.valueTable[index] = value;
+		if (++index == length) { // faster than modulo
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	CharArrayCache newHashtable = new CharArrayCache(this.keyTable.length * 2);
+	for (int i = this.keyTable.length; --i >= 0;)
+		if (this.keyTable[i] != null)
+			newHashtable.put(this.keyTable[i], this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/** Remove the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>char[]</CODE> the specified key
+ */
+public void remove(char[] key) {
+	int length = this.keyTable.length, index = CharOperation.hashCode(key) % length;
+	while (this.keyTable[index] != null) {
+		if (CharOperation.equals(this.keyTable[index], key)) {
+			this.valueTable[index] = 0;
+			this.keyTable[index] = null;
+			return;
+		}
+		if (++index == length) { // faster than modulo
+			index = 0;
+		}
+	}
+}
+/**
+ * Returns the key corresponding to the value. Returns null if the
+ * receiver doesn't contain the value.
+ * @param value int the value that we are looking for
+ * @return Object
+ */
+public char[] returnKeyFor(int value) {
+	for (int i = this.keyTable.length; i-- > 0;) {
+		if (this.valueTable[i] == value) {
+			return this.keyTable[i];
+		}
+	}
+	return null;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return this.elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if (this.keyTable[i] != null) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
new file mode 100644
index 0000000..f6715da
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -0,0 +1,6928 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 400710 - [1.8][compiler] synthetic access to default method generates wrong code
+ *								bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335        
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+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.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CodeStream {
+
+	// It will be responsible for the following items.
+	// -> Tracking Max Stack.
+
+	public static FieldBinding[] ImplicitThis = new FieldBinding[] {};
+	public static final int LABELS_INCREMENT = 5;
+	// local variable attributes output
+	public static final int LOCALS_INCREMENT = 10;
+	static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT];
+	static BranchLabel[] noLabels = new BranchLabel[LABELS_INCREMENT];
+	static LocalVariableBinding[] noLocals = new LocalVariableBinding[LOCALS_INCREMENT];
+	static LocalVariableBinding[] noVisibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
+	public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0);
+	public static final CompilationResult RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE = new CompilationResult((char[])null, 0, 0, 0);
+
+	public int allLocalsCounter;
+	public byte[] bCodeStream;
+	public ClassFile classFile; // The current classfile it is associated to.
+	public int classFileOffset;
+	public ConstantPool constantPool; // The constant pool used to generate bytecodes that need to store information into the constant pool
+	public int countLabels;
+	public ExceptionLabel[] exceptionLabels = new ExceptionLabel[LABELS_INCREMENT];
+	public int exceptionLabelsCounter;
+	public int generateAttributes;
+	// store all the labels placed at the current position to be able to optimize
+	// a jump to the next bytecode.
+	static final int L_UNKNOWN = 0, L_OPTIMIZABLE = 2, L_CANNOT_OPTIMIZE = 4;
+	public BranchLabel[] labels = new BranchLabel[LABELS_INCREMENT];
+	public int lastEntryPC; // last entry recorded
+	public int lastAbruptCompletion; // position of last instruction which abrupts completion: goto/return/athrow
+
+	public int[] lineSeparatorPositions;
+	// line number of the body start and the body end
+	public int lineNumberStart;
+
+	public int lineNumberEnd;
+	public LocalVariableBinding[] locals = new LocalVariableBinding[LOCALS_INCREMENT];
+	public int maxFieldCount;
+	public int maxLocals;
+	public AbstractMethodDeclaration methodDeclaration;
+	public LambdaExpression lambdaExpression;
+	public int[] pcToSourceMap = new int[24];
+	public int pcToSourceMapSize;
+	public int position; // So when first set can be incremented
+	public boolean preserveUnusedLocals;
+
+	public int stackDepth; // Use Ints to keep from using extra bc when adding
+
+	public int stackMax; // Use Ints to keep from using extra bc when adding
+	public int startingClassFileOffset; // I need to keep the starting point inside the byte array
+	// target level to manage different code generation between different target levels
+	protected long targetLevel;
+
+	public LocalVariableBinding[] visibleLocals = new LocalVariableBinding[LOCALS_INCREMENT];
+		
+	int visibleLocalsCount;
+	
+	// to handle goto_w
+	public boolean wideMode = false;	
+	
+public CodeStream(ClassFile givenClassFile) {
+	this.targetLevel = givenClassFile.targetJDK;
+	this.generateAttributes = givenClassFile.produceAttributes;
+	if ((givenClassFile.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
+		this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
+	}
+}
+/**
+ * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc.
+ * If there is an existing entry it returns -1 (no insertion required).
+ * Otherwise it returns the index where the entry for the pc has to be inserted.
+ * This is based on the fact that the pcToSourceMap table is sorted according to the pc.
+ *
+ * @param pcToSourceMap the given pcToSourceMap array
+ * @param length the given length
+ * @param pc the given pc
+ * @return int
+ */
+public static int insertionIndex(int[] pcToSourceMap, int length, int pc) {
+	int g = 0;
+	int d = length - 2;
+	int m = 0;
+	while (g <= d) {
+		m = (g + d) / 2;
+		// we search only on even indexes
+		if ((m & 1) != 0) // faster than ((m % 2) != 0)
+			m--;
+		int currentPC = pcToSourceMap[m];
+		if (pc < currentPC) {
+			d = m - 2;
+		} else
+			if (pc > currentPC) {
+				g = m + 2;
+			} else {
+				return -1;
+			}
+	}
+	if (pc < pcToSourceMap[m])
+		return m;
+	return m + 2;
+}
+public static final void sort(int[] tab, int lo0, int hi0, int[] result) {
+	int lo = lo0;
+	int hi = hi0;
+	int mid;
+	if (hi0 > lo0) {
+		/* Arbitrarily establishing partition element as the midpoint of
+		  * the array.
+		  */
+		mid = tab[lo0 + (hi0 - lo0) / 2];
+		// loop through the array until indices cross
+		while (lo <= hi) {
+			/* find the first element that is greater than or equal to
+			 * the partition element starting from the left Index.
+			 */
+			while ((lo < hi0) && (tab[lo] < mid))
+				++lo;
+			/* find an element that is smaller than or equal to
+			 * the partition element starting from the right Index.
+			 */
+			while ((hi > lo0) && (tab[hi] > mid))
+				--hi;
+			// if the indexes have not crossed, swap
+			if (lo <= hi) {
+				swap(tab, lo, hi, result);
+				++lo;
+				--hi;
+			}
+		}
+		/* If the right index has not reached the left side of array
+		  * must now sort the left partition.
+		  */
+		if (lo0 < hi)
+			sort(tab, lo0, hi, result);
+		/* If the left index has not reached the right side of array
+		  * must now sort the right partition.
+		  */
+		if (lo < hi0)
+			sort(tab, lo, hi0, result);
+	}
+}
+
+
+private static final void swap(int a[], int i, int j, int result[]) {
+	int T;
+	T = a[i];
+	a[i] = a[j];
+	a[j] = T;
+	T = result[j];
+	result[j] = result[i];
+	result[i] = T;
+}
+
+public void aaload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aaload;
+}
+
+public void aastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aastore;
+}
+
+public void aconst_null() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aconst_null;
+}
+
+public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+	// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+	for (int i = 0; i < this.visibleLocalsCount; i++) {
+		LocalVariableBinding localBinding = this.visibleLocals[i];
+		if (localBinding != null) {
+			// Check if the local is definitely assigned
+			if (isDefinitelyAssigned(scope, initStateIndex, localBinding)) {
+				if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
+					/* There are two cases:
+					 * 1) there is no initialization interval opened ==> add an opened interval
+					 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
+					 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
+					 * is equals to -1.
+					 * initializationPCs is a collection of pairs of int:
+					 * 	first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
+					 * 	is not closed yet.
+					 */
+					localBinding.recordInitializationStartPC(this.position);
+				}
+			}
+		}
+	}
+}
+
+public void addLabel(BranchLabel aLabel) {
+	if (this.countLabels == this.labels.length)
+		System.arraycopy(this.labels, 0, this.labels = new BranchLabel[this.countLabels + LABELS_INCREMENT], 0, this.countLabels);
+	this.labels[this.countLabels++] = aLabel;
+}
+
+public void addVariable(LocalVariableBinding localBinding) {
+	/* do nothing */
+}
+
+public void addVisibleLocalVariable(LocalVariableBinding localBinding) {
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+
+	if (this.visibleLocalsCount >= this.visibleLocals.length)
+		System.arraycopy(this.visibleLocals, 0, this.visibleLocals = new LocalVariableBinding[this.visibleLocalsCount * 2], 0, this.visibleLocalsCount);
+	this.visibleLocals[this.visibleLocalsCount++] = localBinding;
+}
+
+public void aload(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload;
+		writeUnsignedShort(iArg);
+	} else {
+		// Don't need to use the wide bytecode
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void aload_0() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (this.maxLocals == 0) {
+		this.maxLocals = 1;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload_0;
+}
+
+public void aload_1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload_1;
+}
+
+public void aload_2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload_2;
+}
+
+public void aload_3() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_aload_3;
+}
+
+public void anewarray(TypeBinding typeBinding) {
+	this.countLabels = 0;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_anewarray;
+	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
+}
+
+public void areturn() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_areturn;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void arrayAt(int typeBindingID) {
+	switch (typeBindingID) {
+		case TypeIds.T_int :
+			iaload();
+			break;
+		case TypeIds.T_byte :
+		case TypeIds.T_boolean :
+			baload();
+			break;
+		case TypeIds.T_short :
+			saload();
+			break;
+		case TypeIds.T_char :
+			caload();
+			break;
+		case TypeIds.T_long :
+			laload();
+			break;
+		case TypeIds.T_float :
+			faload();
+			break;
+		case TypeIds.T_double :
+			daload();
+			break;
+		default :
+			aaload();
+	}
+}
+
+public void arrayAtPut(int elementTypeID, boolean valueRequired) {
+	switch (elementTypeID) {
+		case TypeIds.T_int :
+			if (valueRequired)
+				dup_x2();
+			iastore();
+			break;
+		case TypeIds.T_byte :
+		case TypeIds.T_boolean :
+			if (valueRequired)
+				dup_x2();
+			bastore();
+			break;
+		case TypeIds.T_short :
+			if (valueRequired)
+				dup_x2();
+			sastore();
+			break;
+		case TypeIds.T_char :
+			if (valueRequired)
+				dup_x2();
+			castore();
+			break;
+		case TypeIds.T_long :
+			if (valueRequired)
+				dup2_x2();
+			lastore();
+			break;
+		case TypeIds.T_float :
+			if (valueRequired)
+				dup_x2();
+			fastore();
+			break;
+		case TypeIds.T_double :
+			if (valueRequired)
+				dup2_x2();
+			dastore();
+			break;
+		default :
+			if (valueRequired)
+				dup_x2();
+			aastore();
+	}
+}
+
+public void arraylength() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_arraylength;
+}
+
+public void astore(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position+=2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position+=2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void astore_0() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals == 0) {
+		this.maxLocals = 1;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore_0;
+}
+
+public void astore_1() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore_1;
+}
+
+public void astore_2() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore_2;
+}
+
+public void astore_3() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_astore_3;
+}
+
+public void athrow() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_athrow;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void baload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_baload;
+}
+
+public void bastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_bastore;
+}
+
+public void bipush(byte b) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position += 2;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_bipush;
+	this.bCodeStream[this.classFileOffset++] = b;
+}
+
+public void caload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_caload;
+}
+
+public void castore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_castore;
+}
+
+public void checkcast(int baseId) {
+	this.countLabels = 0;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_checkcast;
+	switch (baseId) {
+		case TypeIds.T_byte :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
+			break;
+		case TypeIds.T_short :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
+			break;
+		case TypeIds.T_char :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
+			break;
+		case TypeIds.T_int :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
+			break;
+		case TypeIds.T_long :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
+			break;
+		case TypeIds.T_float :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
+			break;
+		case TypeIds.T_double :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
+			break;
+		case TypeIds.T_boolean :
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
+	}
+}
+
+public void checkcast(TypeBinding typeBinding) {
+	this.checkcast(null, typeBinding);
+}
+
+public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
+	/* We use a slightly sub-optimal generation for intersection casts by resorting to a runtime cast for every intersecting type, but in
+	   reality this should not matter. In its intended use form such as (I & Serializable) () -> {}, no cast is emitted at all
+	*/
+	TypeBinding [] types = typeBinding instanceof IntersectionCastTypeBinding ? typeBinding.getIntersectingTypes() : new TypeBinding [] { typeBinding };
+	for (int i = types.length - 1; i >=0; i--) {
+		this.countLabels = 0;
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_checkcast;
+		writeUnsignedShort(this.constantPool.literalIndexForType(types[i]));
+	}
+}
+
+public void d2f() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_d2f;
+}
+
+public void d2i() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_d2i;
+}
+
+public void d2l() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_d2l;
+}
+
+public void dadd() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dadd;
+}
+
+public void daload() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_daload;
+}
+
+public void dastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 4;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dastore;
+}
+
+public void dcmpg() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dcmpg;
+}
+
+public void dcmpl() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dcmpl;
+}
+
+public void dconst_0() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dconst_0;
+}
+
+public void dconst_1() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dconst_1;
+}
+
+public void ddiv() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ddiv;
+}
+
+public void decrStackSize(int offset) {
+	this.stackDepth -= offset;
+}
+
+public void dload(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals < iArg + 2) {
+		this.maxLocals = iArg + 2; // + 2 because it is a double
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload;
+		writeUnsignedShort(iArg);
+	} else {
+		// Don't need to use the wide bytecode
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void dload_0() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals < 2) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload_0;
+}
+
+public void dload_1() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals < 3) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload_1;
+}
+
+public void dload_2() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals < 4) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload_2;
+}
+
+public void dload_3() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.maxLocals < 5) {
+		this.maxLocals = 5;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dload_3;
+}
+
+public void dmul() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dmul;
+}
+
+public void dneg() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dneg;
+}
+
+public void drem() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_drem;
+}
+
+public void dreturn() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dreturn;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void dstore(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals <= iArg + 1) {
+		this.maxLocals = iArg + 2;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void dstore_0() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 2) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore_0;
+}
+
+public void dstore_1() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 3) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore_1;
+}
+
+public void dstore_2() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 4) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore_2;
+}
+
+public void dstore_3() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 5) {
+		this.maxLocals = 5;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dstore_3;
+}
+
+public void dsub() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dsub;
+}
+
+public void dup() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup;
+}
+
+public void dup_x1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup_x1;
+}
+
+public void dup_x2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup_x2;
+}
+
+public void dup2() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup2;
+}
+
+public void dup2_x1() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup2_x1;
+}
+
+public void dup2_x2() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_dup2_x2;
+}
+
+public void exitUserScope(BlockScope currentScope) {
+	// mark all the scope's locals as losing their definite assignment
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+	int index = this.visibleLocalsCount - 1;
+	while (index >= 0) {
+		LocalVariableBinding visibleLocal = this.visibleLocals[index];
+		if (visibleLocal == null || visibleLocal.declaringScope != currentScope) {
+			// left currentScope
+			index--;
+			continue;
+		}
+
+		// there may be some preserved locals never initialized
+		if (visibleLocal.initializationCount > 0) {
+			visibleLocal.recordInitializationEndPC(this.position);
+		}
+		this.visibleLocals[index--] = null; // this variable is no longer visible afterwards
+	}
+}
+
+public void exitUserScope(BlockScope currentScope, LocalVariableBinding binding) {
+	// mark all the scope's locals as losing their definite assignment
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+	int index = this.visibleLocalsCount - 1;
+	while (index >= 0) {
+		LocalVariableBinding visibleLocal = this.visibleLocals[index];
+		if (visibleLocal == null || visibleLocal.declaringScope != currentScope || visibleLocal == binding) {
+			// left currentScope
+			index--;
+			continue;
+		}
+		// there may be some preserved locals never initialized
+		if (visibleLocal.initializationCount > 0) {
+			visibleLocal.recordInitializationEndPC(this.position);
+		}
+		this.visibleLocals[index--] = null; // this variable is no longer visible afterwards
+	}
+}
+
+public void f2d() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_f2d;
+}
+
+public void f2i() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_f2i;
+}
+
+public void f2l() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_f2l;
+}
+
+public void fadd() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fadd;
+}
+
+public void faload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_faload;
+}
+
+public void fastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fastore;
+}
+
+public void fcmpg() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fcmpg;
+}
+
+public void fcmpl() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fcmpl;
+}
+
+public void fconst_0() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fconst_0;
+}
+
+public void fconst_1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fconst_1;
+}
+
+public void fconst_2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fconst_2;
+}
+
+public void fdiv() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fdiv;
+}
+
+public void fieldAccess(byte opcode, FieldBinding fieldBinding, TypeBinding declaringClass) {
+	if (declaringClass == null) declaringClass = fieldBinding.declaringClass;
+	if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+		Util.recordNestedType(this.classFile, declaringClass);
+	}
+	TypeBinding returnType = fieldBinding.type;
+	int returnTypeSize;
+	switch (returnType.id) {
+		case TypeIds.T_long :
+		case TypeIds.T_double :
+			returnTypeSize = 2;
+			break;
+		default :
+			returnTypeSize = 1;
+			break;
+	}
+	this.fieldAccess(opcode, returnTypeSize, declaringClass.constantPoolName(), fieldBinding.name, returnType.signature());
+}
+
+private void fieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] fieldName, char[] signature) {
+	this.countLabels = 0;
+	switch(opcode) {
+		case Opcodes.OPC_getfield :
+			if (returnTypeSize == 2) {
+				this.stackDepth++;
+			}
+			break;
+		case Opcodes.OPC_getstatic :
+			if (returnTypeSize == 2) {
+				this.stackDepth += 2;
+			} else {
+				this.stackDepth++;
+			}
+			break;
+		case Opcodes.OPC_putfield :
+			if (returnTypeSize == 2) {
+				this.stackDepth -= 3;
+			} else {
+				this.stackDepth -= 2;
+			}
+			break;
+		case Opcodes.OPC_putstatic :
+			if (returnTypeSize == 2) {
+				this.stackDepth -= 2;
+			} else {
+				this.stackDepth--;
+			}
+	}
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = opcode;
+	writeUnsignedShort(this.constantPool.literalIndexForField(declaringClass, fieldName, signature));
+}
+
+public void fload(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void fload_0() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals == 0) {
+		this.maxLocals = 1;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload_0;
+}
+
+public void fload_1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload_1;
+}
+
+public void fload_2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload_2;
+}
+
+public void fload_3() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fload_3;
+}
+
+public void fmul() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fmul;
+}
+
+public void fneg() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fneg;
+}
+
+public void frem() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_frem;
+}
+
+public void freturn() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_freturn;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void fstore(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void fstore_0() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals == 0) {
+		this.maxLocals = 1;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore_0;
+}
+
+public void fstore_1() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore_1;
+}
+
+public void fstore_2() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore_2;
+}
+
+public void fstore_3() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fstore_3;
+}
+
+public void fsub() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_fsub;
+}
+
+public void generateBoxingConversion(int unboxedTypeID) {
+    switch (unboxedTypeID) {
+        case TypeIds.T_byte :
+            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+               // invokestatic: Byte.valueOf(byte)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangByteConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.byteByteSignature);
+            } else {
+               // new Byte( byte )
+                newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangByteConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.ByteConstrSignature);
+            }
+            break;
+        case TypeIds.T_short :
+            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
+                // invokestatic: Short.valueOf(short)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangShortConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.shortShortSignature);
+            } else {
+                // new Short(short)
+            	newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangShortConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.ShortConstrSignature);
+            }
+            break;
+        case TypeIds.T_char :
+            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
+                // invokestatic: Character.valueOf(char)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangCharacterConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.charCharacterSignature);
+            } else {
+                // new Char( char )
+                newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangCharacterConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.CharConstrSignature);
+            }
+            break;
+        case TypeIds.T_int :
+            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+                // invokestatic: Integer.valueOf(int)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangIntegerConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.IntIntegerSignature);
+            } else {
+                // new Integer(int)
+                newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangIntegerConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.IntConstrSignature);
+            }
+            break;
+        case TypeIds.T_long :
+            if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+                // invokestatic: Long.valueOf(long)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    2, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangLongConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.longLongSignature);
+            } else {
+                // new Long( long )
+                newWrapperFor(unboxedTypeID);
+                dup_x2();
+                dup_x2();
+                pop();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    3, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangLongConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.LongConstrSignature);
+            }
+            break;
+        case TypeIds.T_float :
+            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
+                // invokestatic: Float.valueOf(float)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangFloatConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.floatFloatSignature);
+            } else {
+                // new Float(float)
+                newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangFloatConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.FloatConstrSignature);
+            }
+            break;
+        case TypeIds.T_double :
+            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
+                // invokestatic: Double.valueOf(double)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    2, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangDoubleConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.doubleDoubleSignature);
+            } else {
+                // new Double( double )
+            	newWrapperFor(unboxedTypeID);
+                dup_x2();
+                dup_x2();
+                pop();
+
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    3, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangDoubleConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.DoubleConstrSignature);
+            }
+
+            break;
+        case TypeIds.T_boolean :
+            if ( this.targetLevel >= ClassFileConstants.JDK1_5 ) {
+                // invokestatic: Boolean.valueOf(boolean)
+                invoke(
+                    Opcodes.OPC_invokestatic,
+                    1, // receiverAndArgsSize
+                    1, // return type size
+                    ConstantPool.JavaLangBooleanConstantPoolName,
+                    ConstantPool.ValueOf,
+                    ConstantPool.booleanBooleanSignature);
+            } else {
+                // new Boolean(boolean)
+                newWrapperFor(unboxedTypeID);
+                dup_x1();
+                swap();
+                invoke(
+                    Opcodes.OPC_invokespecial,
+                    2, // receiverAndArgsSize
+                    0, // return type size
+                    ConstantPool.JavaLangBooleanConstantPoolName,
+                    ConstantPool.Init,
+                    ConstantPool.BooleanConstrSignature);
+            }
+    }
+}
+
+/**
+ * Macro for building a class descriptor object
+ */
+public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
+	if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
+		getTYPE(accessedType.id);
+		return;
+	}
+	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+		// generation using the new ldc_w bytecode
+		this.ldc(accessedType);
+	} else {
+		BranchLabel endLabel = new BranchLabel(this);
+		if (syntheticFieldBinding != null) { // non interface case
+			fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
+			dup();
+			ifnonnull(endLabel);
+			pop();
+		}
+
+		/* Macro for building a class descriptor object... using or not a field cache to store it into...
+		this sequence is responsible for building the actual class descriptor.
+
+		If the fieldCache is set, then it is supposed to be the body of a synthetic access method
+		factoring the actual descriptor creation out of the invocation site (saving space).
+		If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
+		we have no way to get a hand on the field cache to do better. */
+
+
+		// Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
+
+		ExceptionLabel classNotFoundExceptionHandler = new ExceptionLabel(this, TypeBinding.NULL /*represents ClassNotFoundException*/);
+		classNotFoundExceptionHandler.placeStart();
+		this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
+		invokeClassForName();
+
+		/* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
+		if (accessedType == BaseTypes.NullBinding) {
+			this.ldc("java.lang.Object"); //$NON-NLS-1$
+		} else if (accessedType.isArrayType()) {
+			this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
+		} else {
+			// we make it an array type (to avoid class initialization)
+			this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		this.invokeClassForName();
+		if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
+			this.invokeJavaLangClassGetComponentType();
+		}
+		*/
+		/* We need to protect the runtime code from binary inconsistencies
+		in case the accessedType is missing, the ClassNotFoundException has to be converted
+		into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
+		classNotFoundExceptionHandler.placeEnd();
+
+		if (syntheticFieldBinding != null) { // non interface case
+			dup();
+			fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
+		}
+		goto_(endLabel);
+
+		int savedStackDepth = this.stackDepth;
+		// Generate the body of the exception handler
+		/* ClassNotFoundException on stack -- the class literal could be doing more things
+		on the stack, which means that the stack may not be empty at this point in the
+		above code gen. So we save its state and restart it from 1. */
+
+		pushExceptionOnStack(TypeBinding.NULL);/*represents ClassNotFoundException*/
+		classNotFoundExceptionHandler.place();
+
+		// Transform the current exception, and repush and throw a
+		// NoClassDefFoundError(ClassNotFound.getMessage())
+
+		newNoClassDefFoundError();
+		dup_x1();
+		this.swap();
+
+		// Retrieve the message from the old exception
+		invokeThrowableGetMessage();
+
+		// Send the constructor taking a message string as an argument
+		invokeNoClassDefFoundErrorStringConstructor();
+		athrow();
+		endLabel.place();
+		this.stackDepth = savedStackDepth;
+	}
+}
+
+/**
+ * This method generates the code attribute bytecode
+ */
+final public void generateCodeAttributeForProblemMethod(String problemMessage) {
+	newJavaLangError();
+	dup();
+	ldc(problemMessage);
+	invokeJavaLangErrorConstructor();
+	athrow();
+}
+
+public void generateConstant(Constant constant, int implicitConversionCode) {
+	int targetTypeID = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+	if (targetTypeID == 0) targetTypeID = constant.typeID(); // use default constant type
+	switch (targetTypeID) {
+		case TypeIds.T_boolean :
+			generateInlinedValue(constant.booleanValue());
+			break;
+		case TypeIds.T_char :
+			generateInlinedValue(constant.charValue());
+			break;
+		case TypeIds.T_byte :
+			generateInlinedValue(constant.byteValue());
+			break;
+		case TypeIds.T_short :
+			generateInlinedValue(constant.shortValue());
+			break;
+		case TypeIds.T_int :
+			generateInlinedValue(constant.intValue());
+			break;
+		case TypeIds.T_long :
+			generateInlinedValue(constant.longValue());
+			break;
+		case TypeIds.T_float :
+			generateInlinedValue(constant.floatValue());
+			break;
+		case TypeIds.T_double :
+			generateInlinedValue(constant.doubleValue());
+			break;
+		case TypeIds.T_JavaLangString :
+			ldc(constant.stringValue());
+	}
+	if ((implicitConversionCode & TypeIds.BOXING) != 0) {
+		// need boxing
+		generateBoxingConversion(targetTypeID);
+	}
+}
+
+public void generateEmulatedReadAccessForField(FieldBinding fieldBinding) {
+	generateEmulationForField(fieldBinding);
+	// swap  the field with the receiver
+	this.swap();
+	invokeJavaLangReflectFieldGetter(fieldBinding.type.id);
+	if (!fieldBinding.type.isBaseType()) {
+		this.checkcast(fieldBinding.type);
+	}
+}
+
+public void generateEmulatedWriteAccessForField(FieldBinding fieldBinding) {
+	invokeJavaLangReflectFieldSetter(fieldBinding.type.id);
+}
+
+public void generateEmulationForConstructor(Scope scope, MethodBinding methodBinding) {
+	// leave a java.lang.reflect.Field object on the stack
+	this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
+	invokeClassForName();
+	int paramLength = methodBinding.parameters.length;
+	this.generateInlinedValue(paramLength);
+	newArray(null, scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
+	if (paramLength > 0) {
+		dup();
+		for (int i = 0; i < paramLength; i++) {
+			this.generateInlinedValue(i);
+			TypeBinding parameter = methodBinding.parameters[i];
+			if (parameter.isBaseType()) {
+				getTYPE(parameter.id);
+			} else if (parameter.isArrayType()) {
+				ArrayBinding array = (ArrayBinding)parameter;
+				if (array.leafComponentType.isBaseType()) {
+					getTYPE(array.leafComponentType.id);
+				} else {
+					this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
+					invokeClassForName();
+				}
+				int dimensions = array.dimensions;
+				this.generateInlinedValue(dimensions);
+				newarray(TypeIds.T_int);
+				invokeArrayNewInstance();
+				invokeObjectGetClass();
+			} else {
+				// parameter is a reference binding
+				this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
+				invokeClassForName();
+			}
+			aastore();
+			if (i < paramLength - 1) {
+				dup();
+			}
+		}
+	}
+	invokeClassGetDeclaredConstructor();
+	dup();
+	iconst_1();
+	invokeAccessibleObjectSetAccessible();
+}
+
+public void generateEmulationForField(FieldBinding fieldBinding) {
+	// leave a java.lang.reflect.Field object on the stack
+	this.ldc(String.valueOf(fieldBinding.declaringClass.constantPoolName()).replace('/', '.'));
+	invokeClassForName();
+	this.ldc(String.valueOf(fieldBinding.name));
+	invokeClassGetDeclaredField();
+	dup();
+	iconst_1();
+	invokeAccessibleObjectSetAccessible();
+}
+
+public void generateEmulationForMethod(Scope scope, MethodBinding methodBinding) {
+	// leave a java.lang.reflect.Field object on the stack
+	this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
+	invokeClassForName();
+	this.ldc(String.valueOf(methodBinding.selector));
+	int paramLength = methodBinding.parameters.length;
+	this.generateInlinedValue(paramLength);
+	newArray(null, scope.createArrayType(scope.getType(TypeConstants.JAVA_LANG_CLASS, 3), 1));
+	if (paramLength > 0) {
+		dup();
+		for (int i = 0; i < paramLength; i++) {
+			this.generateInlinedValue(i);
+			TypeBinding parameter = methodBinding.parameters[i];
+			if (parameter.isBaseType()) {
+				getTYPE(parameter.id);
+			} else if (parameter.isArrayType()) {
+				ArrayBinding array = (ArrayBinding)parameter;
+				if (array.leafComponentType.isBaseType()) {
+					getTYPE(array.leafComponentType.id);
+				} else {
+					this.ldc(String.valueOf(array.leafComponentType.constantPoolName()).replace('/', '.'));
+					invokeClassForName();
+				}
+				int dimensions = array.dimensions;
+				this.generateInlinedValue(dimensions);
+				newarray(TypeIds.T_int);
+				invokeArrayNewInstance();
+				invokeObjectGetClass();
+			} else {
+				// parameter is a reference binding
+				this.ldc(String.valueOf(methodBinding.declaringClass.constantPoolName()).replace('/', '.'));
+				invokeClassForName();
+			}
+			aastore();
+			if (i < paramLength - 1) {
+				dup();
+			}
+		}
+	}
+	invokeClassGetDeclaredMethod();
+	dup();
+	iconst_1();
+	invokeAccessibleObjectSetAccessible();
+}
+
+/**
+ * Generates the sequence of instructions which will perform the conversion of the expression
+ * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted).
+ * @param implicitConversionCode int
+ */
+public void generateImplicitConversion(int implicitConversionCode) {
+	if ((implicitConversionCode & TypeIds.UNBOXING) != 0) {
+		final int typeId = implicitConversionCode & TypeIds.COMPILE_TYPE_MASK;
+		generateUnboxingConversion(typeId);
+		// unboxing can further involve base type conversions
+	}
+	switch (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) {
+		case TypeIds.Float2Char :
+			f2i();
+			i2c();
+			break;
+		case TypeIds.Double2Char :
+			d2i();
+			i2c();
+			break;
+		case TypeIds.Int2Char :
+		case TypeIds.Short2Char :
+		case TypeIds.Byte2Char :
+			i2c();
+			break;
+		case TypeIds.Long2Char :
+			l2i();
+			i2c();
+			break;
+		case TypeIds.Char2Float :
+		case TypeIds.Short2Float :
+		case TypeIds.Int2Float :
+		case TypeIds.Byte2Float :
+			i2f();
+			break;
+		case TypeIds.Double2Float :
+			d2f();
+			break;
+		case TypeIds.Long2Float :
+			l2f();
+			break;
+		case TypeIds.Float2Byte :
+			f2i();
+			i2b();
+			break;
+		case TypeIds.Double2Byte :
+			d2i();
+			i2b();
+			break;
+		case TypeIds.Int2Byte :
+		case TypeIds.Short2Byte :
+		case TypeIds.Char2Byte :
+			i2b();
+			break;
+		case TypeIds.Long2Byte :
+			l2i();
+			i2b();
+			break;
+		case TypeIds.Byte2Double :
+		case TypeIds.Char2Double :
+		case TypeIds.Short2Double :
+		case TypeIds.Int2Double :
+			i2d();
+			break;
+		case TypeIds.Float2Double :
+			f2d();
+			break;
+		case TypeIds.Long2Double :
+			l2d();
+			break;
+		case TypeIds.Byte2Short :
+		case TypeIds.Char2Short :
+		case TypeIds.Int2Short :
+			i2s();
+			break;
+		case TypeIds.Double2Short :
+			d2i();
+			i2s();
+			break;
+		case TypeIds.Long2Short :
+			l2i();
+			i2s();
+			break;
+		case TypeIds.Float2Short :
+			f2i();
+			i2s();
+			break;
+		case TypeIds.Double2Int :
+			d2i();
+			break;
+		case TypeIds.Float2Int :
+			f2i();
+			break;
+		case TypeIds.Long2Int :
+			l2i();
+			break;
+		case TypeIds.Int2Long :
+		case TypeIds.Char2Long :
+		case TypeIds.Byte2Long :
+		case TypeIds.Short2Long :
+			i2l();
+			break;
+		case TypeIds.Double2Long :
+			d2l();
+			break;
+		case TypeIds.Float2Long :
+			f2l();
+			break;
+		case TypeIds.Object2boolean:
+		case TypeIds.Object2byte:
+		case TypeIds.Object2short:
+		case TypeIds.Object2int:
+		case TypeIds.Object2long:
+		case TypeIds.Object2float:
+		case TypeIds.Object2char:
+		case TypeIds.Object2double:
+			// see table 5.1 in JLS S5.5
+			// an Object to x conversion should have a check cast
+			// and an unboxing conversion.
+			int runtimeType = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+			checkcast(runtimeType);
+			generateUnboxingConversion(runtimeType);
+			break;	
+	}
+	if ((implicitConversionCode & TypeIds.BOXING) != 0) {
+		// need to unbox/box the constant
+		final int typeId = (implicitConversionCode & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+		generateBoxingConversion(typeId);
+	}
+}
+
+public void generateInlinedValue(boolean inlinedValue) {
+	if (inlinedValue)
+		iconst_1();
+	else
+		iconst_0();
+}
+
+public void generateInlinedValue(byte inlinedValue) {
+	switch (inlinedValue) {
+		case -1 :
+			iconst_m1();
+			break;
+		case 0 :
+			iconst_0();
+			break;
+		case 1 :
+			iconst_1();
+			break;
+		case 2 :
+			iconst_2();
+			break;
+		case 3 :
+			iconst_3();
+			break;
+		case 4 :
+			iconst_4();
+			break;
+		case 5 :
+			iconst_5();
+			break;
+		default :
+			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
+				bipush(inlinedValue);
+				return;
+			}
+	}
+}
+
+public void generateInlinedValue(char inlinedValue) {
+	switch (inlinedValue) {
+		case 0 :
+			iconst_0();
+			break;
+		case 1 :
+			iconst_1();
+			break;
+		case 2 :
+			iconst_2();
+			break;
+		case 3 :
+			iconst_3();
+			break;
+		case 4 :
+			iconst_4();
+			break;
+		case 5 :
+			iconst_5();
+			break;
+		default :
+			if ((6 <= inlinedValue) && (inlinedValue <= 127)) {
+				bipush((byte) inlinedValue);
+				return;
+			}
+			if ((128 <= inlinedValue) && (inlinedValue <= 32767)) {
+				sipush(inlinedValue);
+				return;
+			}
+			this.ldc(inlinedValue);
+	}
+}
+
+public void generateInlinedValue(double inlinedValue) {
+	if (inlinedValue == 0.0) {
+		if (Double.doubleToLongBits(inlinedValue) != 0L)
+			this.ldc2_w(inlinedValue);
+		else
+			dconst_0();
+		return;
+	}
+	if (inlinedValue == 1.0) {
+		dconst_1();
+		return;
+	}
+	this.ldc2_w(inlinedValue);
+}
+
+public void generateInlinedValue(float inlinedValue) {
+	if (inlinedValue == 0.0f) {
+		if (Float.floatToIntBits(inlinedValue) != 0)
+			this.ldc(inlinedValue);
+		else
+			fconst_0();
+		return;
+	}
+	if (inlinedValue == 1.0f) {
+		fconst_1();
+		return;
+	}
+	if (inlinedValue == 2.0f) {
+		fconst_2();
+		return;
+	}
+	this.ldc(inlinedValue);
+}
+
+public void generateInlinedValue(int inlinedValue) {
+	switch (inlinedValue) {
+		case -1 :
+			iconst_m1();
+			break;
+		case 0 :
+			iconst_0();
+			break;
+		case 1 :
+			iconst_1();
+			break;
+		case 2 :
+			iconst_2();
+			break;
+		case 3 :
+			iconst_3();
+			break;
+		case 4 :
+			iconst_4();
+			break;
+		case 5 :
+			iconst_5();
+			break;
+		default :
+			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
+				bipush((byte) inlinedValue);
+				return;
+			}
+			if ((-32768 <= inlinedValue) && (inlinedValue <= 32767)) {
+				sipush(inlinedValue);
+				return;
+			}
+			this.ldc(inlinedValue);
+	}
+}
+
+public void generateInlinedValue(long inlinedValue) {
+	if (inlinedValue == 0) {
+		lconst_0();
+		return;
+	}
+	if (inlinedValue == 1) {
+		lconst_1();
+		return;
+	}
+	this.ldc2_w(inlinedValue);
+}
+
+public void generateInlinedValue(short inlinedValue) {
+	switch (inlinedValue) {
+		case -1 :
+			iconst_m1();
+			break;
+		case 0 :
+			iconst_0();
+			break;
+		case 1 :
+			iconst_1();
+			break;
+		case 2 :
+			iconst_2();
+			break;
+		case 3 :
+			iconst_3();
+			break;
+		case 4 :
+			iconst_4();
+			break;
+		case 5 :
+			iconst_5();
+			break;
+		default :
+			if ((-128 <= inlinedValue) && (inlinedValue <= 127)) {
+				bipush((byte) inlinedValue);
+				return;
+			}
+			sipush(inlinedValue);
+	}
+}
+
+public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
+	if (mappingSequence == null) {
+		if (target instanceof LocalVariableBinding) {
+			scope.problemReporter().needImplementation(invocationSite); //TODO (philippe) should improve local emulation failure reporting
+		} else {
+			scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
+		}
+		return;
+	}
+	if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
+		scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
+		return;
+	} else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
+		scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
+		return;
+	}
+
+	if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
+		aload_0();
+		return;
+	} else if (mappingSequence[0] instanceof FieldBinding) {
+		FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
+		aload_0();
+		fieldAccess(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
+	} else {
+		load((LocalVariableBinding) mappingSequence[0]);
+	}
+	for (int i = 1, length = mappingSequence.length; i < length; i++) {
+		if (mappingSequence[i] instanceof FieldBinding) {
+			FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
+			fieldAccess(Opcodes.OPC_getfield, fieldBinding, null /* default declaringClass */);
+		} else {
+			invoke(Opcodes.OPC_invokestatic, (MethodBinding) mappingSequence[i], null /* default declaringClass */);
+		}
+	}
+}
+
+public void generateReturnBytecode(Expression expression) {
+	if (expression == null) {
+		return_();
+	} else {
+		final int implicitConversion = expression.implicitConversion;
+		if ((implicitConversion & TypeIds.BOXING) != 0) {
+			areturn();
+			return;
+		}
+		int runtimeType = (implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
+		switch (runtimeType) {
+			case TypeIds.T_boolean :
+			case TypeIds.T_int :
+				ireturn();
+				break;
+			case TypeIds.T_float :
+				freturn();
+				break;
+			case TypeIds.T_long :
+				lreturn();
+				break;
+			case TypeIds.T_double :
+				dreturn();
+				break;
+			default :
+				areturn();
+		}
+	}
+}
+
+/**
+ * The equivalent code performs a string conversion:
+ *
+ * @param blockScope the given blockScope
+ * @param oper1 the first expression
+ * @param oper2 the second expression
+ */
+public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) {
+	int pc;
+	if (oper1 == null) {
+		/* Operand is already on the stack, and maybe nil:
+		note type1 is always to  java.lang.String here.*/
+		newStringContatenation();
+		dup_x1();
+		this.swap();
+		// If argument is reference type, need to transform it
+		// into a string (handles null case)
+		invokeStringValueOf(TypeIds.T_JavaLangObject);
+		invokeStringConcatenationStringConstructor();
+	} else {
+		pc = this.position;
+		oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+		this.recordPositionsFrom(pc, oper1.sourceStart);
+	}
+	pc = this.position;
+	oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
+	this.recordPositionsFrom(pc, oper2.sourceStart);
+	invokeStringConcatenationToString();
+}
+
+/**
+ * @param accessBinding the access method binding to generate
+ */
+public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) {
+	initializeMaxLocals(accessBinding);
+	MethodBinding constructorBinding = accessBinding.targetMethod;
+	TypeBinding[] parameters = constructorBinding.parameters;
+	int length = parameters.length;
+	int resolvedPosition = 1;
+	aload_0();
+	// special name&ordinal argument generation for enum constructors
+	TypeBinding declaringClass = constructorBinding.declaringClass;
+	if (declaringClass.erasure().id == TypeIds.T_JavaLangEnum || declaringClass.isEnum()) {
+		aload_1(); // pass along name param as name arg
+		iload_2(); // pass along ordinal param as ordinal arg
+		resolvedPosition += 2;
+	}
+	if (declaringClass.isNestedType()) {
+		NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
+		SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances();
+		for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
+			TypeBinding type;
+			load((type = syntheticArguments[i].type), resolvedPosition);
+			switch(type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					resolvedPosition += 2;
+					break;
+				default :
+					resolvedPosition++;
+					break;
+			}
+		}
+	}
+	for (int i = 0; i < length; i++) {
+		TypeBinding parameter;
+		load(parameter = parameters[i], resolvedPosition);
+		switch(parameter.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				resolvedPosition += 2;
+				break;
+			default :
+				resolvedPosition++;
+				break;
+		}
+	}
+
+	if (declaringClass.isNestedType()) {
+		NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
+		SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
+		for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) {
+			TypeBinding type;
+			load(type = syntheticArguments[i].type, resolvedPosition);
+			switch(type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					resolvedPosition += 2;
+					break;
+				default :
+					resolvedPosition++;
+					break;
+			}
+		}
+	}
+	invoke(Opcodes.OPC_invokespecial, constructorBinding, null /* default declaringClass */);
+	return_();
+}
+public void generateSyntheticBodyForArrayConstructor(SyntheticMethodBinding methodBinding) {
+	initializeMaxLocals(methodBinding);
+	iload_0();
+	anewarray(((ArrayBinding) methodBinding.returnType).elementsType());
+	areturn();
+}
+public void generateSyntheticBodyForArrayClone(SyntheticMethodBinding methodBinding) {
+	initializeMaxLocals(methodBinding);
+	TypeBinding arrayType = methodBinding.parameters[0];
+	aload_0();
+	invoke(   // // invokevirtual: "[I".clone:()Ljava/lang/Object;
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			arrayType.signature(), // declaring class e.g "[I"
+			ConstantPool.Clone,
+			ConstantPool.CloneSignature);
+	checkcast(arrayType);
+	areturn();
+}
+public void generateSyntheticBodyForFactoryMethod(SyntheticMethodBinding methodBinding) {
+	initializeMaxLocals(methodBinding);
+	MethodBinding constructorBinding = methodBinding.targetMethod;
+	TypeBinding[] parameters = methodBinding.parameters;
+	int length = parameters.length;
+	
+	new_(constructorBinding.declaringClass);
+	dup();
+	
+	int resolvedPosition = 0;
+	for (int i = 0; i < length; i++) {
+		TypeBinding parameter;
+		load(parameter = parameters[i], resolvedPosition);
+		switch(parameter.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				resolvedPosition += 2;
+				break;
+			default :
+				resolvedPosition++;
+				break;
+		}
+	}
+	for (int i = 0; i < methodBinding.fakePaddedParameters; i++)
+		aconst_null();
+	
+	invoke(Opcodes.OPC_invokespecial, constructorBinding, null /* default declaringClass */);
+	areturn();
+}
+//static X valueOf(String name) {
+// return (X) Enum.valueOf(X.class, name);
+//}
+public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) {
+	initializeMaxLocals(methodBinding);
+	final ReferenceBinding declaringClass = methodBinding.declaringClass;
+	generateClassLiteralAccessForType(declaringClass, null);
+	aload_0();
+	invokeJavaLangEnumvalueOf(declaringClass);
+	this.checkcast(declaringClass);
+	areturn();
+}
+
+//static X[] values() {
+// X[] values;
+// int length;
+// X[] result;
+// System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length)
+// return result;
+//}
+public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) {
+	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
+	initializeMaxLocals(methodBinding);
+	TypeBinding enumArray = methodBinding.returnType;
+	fieldAccess(Opcodes.OPC_getstatic, scope.referenceContext.enumValuesSyntheticfield, null /* default declaringClass */);
+	dup();
+	astore_0();
+	iconst_0();
+	aload_0();
+	arraylength();
+	dup();
+	istore_1();
+	newArray(null, (ArrayBinding) enumArray);
+	dup();
+	astore_2();
+	iconst_0();
+	iload_1();
+	invokeSystemArraycopy();
+	aload_2();
+	areturn();
+}
+public void generateSyntheticBodyForEnumInitializationMethod(SyntheticMethodBinding methodBinding) {
+	// no local used
+	this.maxLocals = 0;
+	// generate all enum constants
+	SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) methodBinding.declaringClass;
+	TypeDeclaration typeDeclaration = sourceTypeBinding.scope.referenceContext;
+	BlockScope staticInitializerScope = typeDeclaration.staticInitializerScope;
+	FieldDeclaration[] fieldDeclarations = typeDeclaration.fields;
+	for (int i = methodBinding.startIndex, max = methodBinding.endIndex; i < max; i++) {
+		FieldDeclaration fieldDecl = fieldDeclarations[i];
+		if (fieldDecl.isStatic()) {
+			if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+				fieldDecl.generateCode(staticInitializerScope, this);
+			}
+		}
+	}
+	return_();
+}
+public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessMethod) {
+	initializeMaxLocals(accessMethod);
+	FieldBinding fieldBinding = accessMethod.targetReadField;
+	// target method declaring class may not be accessible (247953);
+	TypeBinding declaringClass = accessMethod.purpose == SyntheticMethodBinding.SuperFieldReadAccess 
+			? accessMethod.declaringClass.superclass() 
+			: accessMethod.declaringClass;
+	if (fieldBinding.isStatic()) {
+		fieldAccess(Opcodes.OPC_getstatic, fieldBinding, declaringClass); 
+	} else {
+		aload_0();
+		fieldAccess(Opcodes.OPC_getfield, fieldBinding, declaringClass);
+	}
+	switch (fieldBinding.type.id) {
+//		case T_void :
+//			this.return_();
+//			break;
+		case TypeIds.T_boolean :
+		case TypeIds.T_byte :
+		case TypeIds.T_char :
+		case TypeIds.T_short :
+		case TypeIds.T_int :
+			ireturn();
+			break;
+		case TypeIds.T_long :
+			lreturn();
+			break;
+		case TypeIds.T_float :
+			freturn();
+			break;
+		case TypeIds.T_double :
+			dreturn();
+			break;
+		default :
+			areturn();
+	}
+}
+
+public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessMethod) {
+	initializeMaxLocals(accessMethod);
+	FieldBinding fieldBinding = accessMethod.targetWriteField;
+	// target method declaring class may not be accessible (247953);
+	TypeBinding declaringClass = accessMethod.purpose == SyntheticMethodBinding.SuperFieldWriteAccess 
+			? accessMethod.declaringClass.superclass() 
+			: accessMethod.declaringClass;	
+	if (fieldBinding.isStatic()) {
+		load(fieldBinding.type, 0);
+		fieldAccess(Opcodes.OPC_putstatic, fieldBinding, declaringClass);
+	} else {
+		aload_0();
+		load(fieldBinding.type, 1);
+		fieldAccess(Opcodes.OPC_putfield, fieldBinding, declaringClass);
+	}
+	return_();
+}
+
+public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessMethod) {
+	initializeMaxLocals(accessMethod);
+	MethodBinding targetMethod = accessMethod.targetMethod;
+	TypeBinding[] parameters = targetMethod.parameters;
+	int length = parameters.length;
+	TypeBinding[] arguments = accessMethod.purpose == SyntheticMethodBinding.BridgeMethod
+													? accessMethod.parameters
+													: null;
+	int resolvedPosition;
+	if (targetMethod.isStatic())
+		resolvedPosition = 0;
+	else {
+		aload_0();
+		resolvedPosition = 1;
+	}
+	for (int i = 0; i < length; i++) {
+	    TypeBinding parameter = parameters[i];
+	    if (arguments != null) { // for bridge methods
+		    TypeBinding argument = arguments[i];
+			load(argument, resolvedPosition);
+			if (argument != parameter)
+			    checkcast(parameter);
+	    } else {
+			load(parameter, resolvedPosition);
+		}
+		switch(parameter.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				resolvedPosition += 2;
+				break;
+			default :
+				resolvedPosition++;
+				break;
+		}
+	}
+	if (targetMethod.isStatic())
+		invoke(Opcodes.OPC_invokestatic, targetMethod, accessMethod.declaringClass); // target method declaring class may not be accessible (128563)
+	else {
+		if (targetMethod.isConstructor()
+				|| targetMethod.isPrivate()
+				// qualified super "X.super.foo()" targets methods from superclass
+				|| accessMethod.purpose == SyntheticMethodBinding.SuperMethodAccess){
+			// target method declaring class may not be accessible (247953);
+			TypeBinding declaringClass = accessMethod.purpose == SyntheticMethodBinding.SuperMethodAccess 
+					? findDirectSuperTypeTowards(accessMethod, targetMethod)
+					: accessMethod.declaringClass;
+			invoke(Opcodes.OPC_invokespecial, targetMethod, declaringClass);
+		} else {
+			if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
+				invoke(Opcodes.OPC_invokeinterface, targetMethod, null /* default declaringClass */);
+			} else {
+				invoke(Opcodes.OPC_invokevirtual, targetMethod, accessMethod.declaringClass); // target method declaring class may not be accessible (128563)
+			}
+		}
+	}
+	switch (targetMethod.returnType.id) {
+		case TypeIds.T_void :
+			return_();
+			break;
+		case TypeIds.T_boolean :
+		case TypeIds.T_byte :
+		case TypeIds.T_char :
+		case TypeIds.T_short :
+		case TypeIds.T_int :
+			ireturn();
+			break;
+		case TypeIds.T_long :
+			lreturn();
+			break;
+		case TypeIds.T_float :
+			freturn();
+			break;
+		case TypeIds.T_double :
+			dreturn();
+			break;
+		default :
+			TypeBinding accessErasure = accessMethod.returnType.erasure();
+			TypeBinding match = targetMethod.returnType.findSuperTypeOriginatingFrom(accessErasure);
+			if (match == null) {
+				this.checkcast(accessErasure); // for bridge methods
+			}
+			areturn();
+	}
+}
+/** When generating SuperMetodAccess towards targetMethod,
+ *  find the suitable direct super type, that will eventually lead to targetMethod.declaringClass.*/
+ReferenceBinding findDirectSuperTypeTowards(SyntheticMethodBinding accessMethod, MethodBinding targetMethod) {
+	ReferenceBinding currentType = accessMethod.declaringClass;
+	ReferenceBinding superclass = currentType.superclass();
+	if (targetMethod.isDefaultMethod()) {
+		// could be inherited via superclass *or* a super interface 
+		ReferenceBinding targetType = targetMethod.declaringClass;
+		if (superclass.isCompatibleWith(targetType))
+			return superclass;
+		ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+		if (superInterfaces != null) {
+			for (int i = 0; i < superInterfaces.length; i++) {
+				ReferenceBinding superIfc = superInterfaces[i];
+				if (superIfc.isCompatibleWith(targetType))
+					return superIfc;
+			}
+		}
+		throw new RuntimeException("Assumption violated: some super type must be conform to the declaring class of a super method"); //$NON-NLS-1$
+	} else {
+		// only one path possible:
+		return superclass;
+	}
+}
+
+public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
+	ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
+	initializeMaxLocals(methodBinding);
+	final BranchLabel nullLabel = new BranchLabel(this);
+	FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
+	fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
+	dup();
+	ifnull(nullLabel);
+	areturn();
+	pushOnStack(syntheticFieldBinding.type);
+	nullLabel.place();
+	pop();
+	ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
+	ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
+	invokeJavaLangEnumValues(enumBinding, arrayBinding);
+	arraylength();
+	newarray(ClassFileConstants.INT_ARRAY);
+	astore_0();
+	LocalVariableBinding localVariableBinding = new LocalVariableBinding(" tab".toCharArray(), scope.createArrayType(TypeBinding.INT, 1), 0, false); //$NON-NLS-1$
+	addVariable(localVariableBinding);
+	final FieldBinding[] fields = enumBinding.fields();
+	if (fields != null) {
+		for (int i = 0, max = fields.length; i < max; i++) {
+			FieldBinding fieldBinding = fields[i];
+			if ((fieldBinding.getAccessFlags() & ClassFileConstants.AccEnum) != 0) {
+				final BranchLabel endLabel = new BranchLabel(this);
+				final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, TypeBinding.LONG /* represents NoSuchFieldError*/);
+				anyExceptionHandler.placeStart();
+				aload_0();
+				fieldAccess(Opcodes.OPC_getstatic, fieldBinding, null /* default declaringClass */);
+				invokeEnumOrdinal(enumBinding.constantPoolName());
+				this.generateInlinedValue(fieldBinding.id + 1); // zero should not be returned see bug 141810
+				iastore();
+				anyExceptionHandler.placeEnd();
+				goto_(endLabel);
+				// Generate the body of the exception handler
+				pushExceptionOnStack(TypeBinding.LONG /*represents NoSuchFieldError*/);
+				anyExceptionHandler.place();
+				pop(); // we don't use it so we can pop it
+				endLabel.place();
+			}
+		}
+	}
+	aload_0();
+	dup();
+	fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
+	areturn();
+	removeVariable(localVariableBinding);
+}
+
+/**
+ * Code responsible to generate the suitable code to supply values for the synthetic enclosing
+ * instance arguments of a constructor invocation of a nested type.
+ */
+public void generateSyntheticEnclosingInstanceValues(BlockScope currentScope, ReferenceBinding targetType, Expression enclosingInstance, ASTNode invocationSite) {
+	// supplying enclosing instance for the anonymous type's superclass
+	ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? (ReferenceBinding)targetType.superclass().erasure() : targetType;
+	boolean hasExtraEnclosingInstance = enclosingInstance != null;
+	if (hasExtraEnclosingInstance
+			&& (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
+		currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
+		return;
+	}
+
+	// perform some emulation work in case there is some and we are inside a local type only
+	ReferenceBinding[] syntheticArgumentTypes;
+	if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
+
+		ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
+		long compliance = currentScope.compilerOptions().complianceLevel;
+
+		// deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
+		// always consider it if complying to 1.5
+		boolean denyEnclosingArgInConstructorCall;
+		if (compliance <= ClassFileConstants.JDK1_3) {
+			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
+		} else if (compliance == ClassFileConstants.JDK1_4){
+			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
+				|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess();
+		} else {
+			//compliance >= JDK1_5
+			denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression
+					|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())
+				&& !targetType.isLocalType();
+		}
+
+		boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
+		for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
+			ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
+			if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
+				hasExtraEnclosingInstance = false;
+				enclosingInstance.generateCode(currentScope, this, true);
+				if (complyTo14){
+					dup();
+					invokeObjectGetClass(); // will perform null check
+					pop();
+				}
+			} else {
+				Object[] emulationPath = currentScope.getEmulationPath(
+						syntheticArgType,
+						false /*not only exact match (that is, allow compatible)*/,
+						denyEnclosingArgInConstructorCall);
+				generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
+			}
+		}
+		if (hasExtraEnclosingInstance){
+			currentScope.problemReporter().unnecessaryEnclosingInstanceSpecification(enclosingInstance, checkedTargetType);
+		}
+	}
+}
+
+/**
+ * Code responsible to generate the suitable code to supply values for the synthetic outer local
+ * variable arguments of a constructor invocation of a nested type.
+ * (bug 26122) - synthetic values for outer locals must be passed after user arguments, e.g. new X(i = 1){}
+ */
+public void generateSyntheticOuterArgumentValues(BlockScope currentScope, ReferenceBinding targetType, ASTNode invocationSite) {
+	// generate the synthetic outer arguments then
+	SyntheticArgumentBinding syntheticArguments[];
+	if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
+		for (int i = 0, max = syntheticArguments.length; i < max; i++) {
+			LocalVariableBinding targetVariable = syntheticArguments[i].actualOuterLocalVariable;
+			VariableBinding[] emulationPath = currentScope.getEmulationPath(targetVariable);
+			generateOuterAccess(emulationPath, invocationSite, targetVariable, currentScope);
+		}
+	}
+}
+
+public void generateUnboxingConversion(int unboxedTypeID) {
+	switch (unboxedTypeID) {
+		case TypeIds.T_byte :
+			// invokevirtual: byteValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangByteConstantPoolName,
+					ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
+					ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_short :
+			// invokevirtual: shortValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangShortConstantPoolName,
+					ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
+					ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_char :
+			// invokevirtual: charValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangCharacterConstantPoolName,
+					ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
+					ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_int :
+			// invokevirtual: intValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangIntegerConstantPoolName,
+					ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
+					ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_long :
+			// invokevirtual: longValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					2, // return type size
+					ConstantPool.JavaLangLongConstantPoolName,
+					ConstantPool.LONGVALUE_LONG_METHOD_NAME,
+					ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_float :
+			// invokevirtual: floatValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangFloatConstantPoolName,
+					ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
+					ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_double :
+			// invokevirtual: doubleValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					2, // return type size
+					ConstantPool.JavaLangDoubleConstantPoolName,
+					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
+					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_boolean :
+			// invokevirtual: booleanValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangBooleanConstantPoolName,
+					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
+					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
+	}
+}
+
+/*
+ * Wide conditional branch compare, improved by swapping comparison opcode
+ *   ifeq WideTarget
+ * becomes
+ *    ifne Intermediate
+ *    gotow WideTarget
+ *    Intermediate:
+ */
+public void generateWideRevertedConditionalBranch(byte revertedOpcode, BranchLabel wideTarget) {
+		BranchLabel intermediate = new BranchLabel(this);
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = revertedOpcode;
+		intermediate.branch();
+		goto_w(wideTarget);
+		intermediate.place();
+}
+
+public void getBaseTypeValue(int baseTypeID) {
+	switch (baseTypeID) {
+		case TypeIds.T_byte :
+			// invokevirtual: byteValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangByteConstantPoolName,
+					ConstantPool.BYTEVALUE_BYTE_METHOD_NAME,
+					ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_short :
+			// invokevirtual: shortValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangShortConstantPoolName,
+					ConstantPool.SHORTVALUE_SHORT_METHOD_NAME,
+					ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_char :
+			// invokevirtual: charValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangCharacterConstantPoolName,
+					ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME,
+					ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_int :
+			// invokevirtual: intValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangIntegerConstantPoolName,
+					ConstantPool.INTVALUE_INTEGER_METHOD_NAME,
+					ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_long :
+			// invokevirtual: longValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					2, // return type size
+					ConstantPool.JavaLangLongConstantPoolName,
+					ConstantPool.LONGVALUE_LONG_METHOD_NAME,
+					ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_float :
+			// invokevirtual: floatValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangFloatConstantPoolName,
+					ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME,
+					ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_double :
+			// invokevirtual: doubleValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					2, // return type size
+					ConstantPool.JavaLangDoubleConstantPoolName,
+					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME,
+					ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE);
+			break;
+		case TypeIds.T_boolean :
+			// invokevirtual: booleanValue()
+			invoke(
+					Opcodes.OPC_invokevirtual,
+					1, // receiverAndArgsSize
+					1, // return type size
+					ConstantPool.JavaLangBooleanConstantPoolName,
+					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME,
+					ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE);
+	}
+}
+
+final public byte[] getContents() {
+	byte[] contents;
+	System.arraycopy(this.bCodeStream, 0, contents = new byte[this.position], 0, this.position);
+	return contents;
+}
+
+/**
+ * Returns the type that should be substituted to original binding declaring class as the proper receiver type
+ * @param currentScope
+ * @param codegenBinding
+ * @param actualReceiverType
+ * @param isImplicitThisReceiver
+ * @return the receiver type to use in constant pool
+ */
+public static TypeBinding getConstantPoolDeclaringClass(Scope currentScope, FieldBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) {
+	ReferenceBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
+	// if the binding declaring class is not visible, need special action
+	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
+	// and not from Object or implicit static field access.
+	if (constantPoolDeclaringClass != actualReceiverType.erasure()
+			&& !actualReceiverType.isArrayType()
+			&& constantPoolDeclaringClass != null // array.length
+			&& codegenBinding.constant() == Constant.NotAConstant) {
+		CompilerOptions options = currentScope.compilerOptions();
+		if ((options.targetJDK >= ClassFileConstants.JDK1_2
+					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
+					&& constantPoolDeclaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
+				|| !constantPoolDeclaringClass.canBeSeenBy(currentScope)) {
+
+			return actualReceiverType.erasure();
+		}
+	}	
+	return constantPoolDeclaringClass;
+}
+
+/**
+ * Returns the type that should be substituted to original binding declaring class as the proper receiver type
+ * @param currentScope
+ * @param codegenBinding
+ * @param actualReceiverType
+ * @param isImplicitThisReceiver
+ * @return the receiver type to use in constant pool
+ */
+public static TypeBinding getConstantPoolDeclaringClass(Scope currentScope, MethodBinding codegenBinding, TypeBinding actualReceiverType, boolean isImplicitThisReceiver) {
+	TypeBinding constantPoolDeclaringClass = codegenBinding.declaringClass;
+	// Post 1.4.0 target, array clone() invocations are qualified with array type
+	// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
+	if (codegenBinding == currentScope.environment().arrayClone) {
+		CompilerOptions options = currentScope.compilerOptions();
+		if (options.sourceLevel > ClassFileConstants.JDK1_4 ) {
+			constantPoolDeclaringClass = actualReceiverType.erasure();
+		}
+	} else {
+		// if the binding declaring class is not visible, need special action
+		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+		// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
+		// and not from Object or implicit static method call.
+		if (constantPoolDeclaringClass != actualReceiverType.erasure() && !actualReceiverType.isArrayType()) {
+			CompilerOptions options = currentScope.compilerOptions();
+			if ((options.targetJDK >= ClassFileConstants.JDK1_2
+						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(isImplicitThisReceiver && codegenBinding.isStatic()))
+						&& codegenBinding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object methods
+					|| !codegenBinding.declaringClass.canBeSeenBy(currentScope)) {
+				constantPoolDeclaringClass = actualReceiverType.erasure();
+			}
+		}				
+	}
+	return constantPoolDeclaringClass;
+}
+protected int getPosition() {
+	return this.position;
+}
+
+public void getTYPE(int baseTypeID) {
+	this.countLabels = 0;
+	switch (baseTypeID) {
+		case TypeIds.T_byte :
+			// getstatic: java.lang.Byte.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangByteConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_short :
+			// getstatic: java.lang.Short.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangShortConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_char :
+			// getstatic: java.lang.Character.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangCharacterConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_int :
+			// getstatic: java.lang.Integer.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangIntegerConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_long :
+			// getstatic: java.lang.Long.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangLongConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_float :
+			// getstatic: java.lang.Float.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangFloatConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_double :
+			// getstatic: java.lang.Double.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangDoubleConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_boolean :
+			// getstatic: java.lang.Boolean.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangBooleanConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+		case TypeIds.T_void :
+			// getstatic: java.lang.Void.TYPE
+			fieldAccess(
+					Opcodes.OPC_getstatic,
+					1, // return type size
+					ConstantPool.JavaLangVoidConstantPoolName,
+					ConstantPool.TYPE,
+					ConstantPool.JavaLangClassSignature);
+			break;
+	}
+}
+
+/**
+ * We didn't call it goto, because there is a conflit with the goto keyword
+ */
+public void goto_(BranchLabel label) {
+	if (this.wideMode) {
+		goto_w(label);
+		return;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	boolean chained = inlineForwardReferencesFromLabelsTargeting(label, this.position);
+	/*
+	 Possible optimization for code such as:
+	 public Object foo() {
+		boolean b = true;
+		if (b) {
+			if (b)
+				return null;
+		} else {
+			if (b) {
+				return null;
+			}
+		}
+		return null;
+	}
+	The goto around the else block for the first if will
+	be unreachable, because the thenClause of the second if
+	returns. Also see 114894
+	}*/
+	if (chained && this.lastAbruptCompletion == this.position) {
+		if (label.position != Label.POS_NOT_SET) { // ensure existing forward references are updated
+			int[] forwardRefs = label.forwardReferences();
+			for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
+				this.writePosition(label, forwardRefs[i]);
+			}
+			this.countLabels = 0; // backward jump, no further chaining allowed
+		}
+		return;
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_goto;
+	label.branch();
+	this.lastAbruptCompletion = this.position;
+}
+
+public void goto_w(BranchLabel label) {
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_goto_w;
+	label.branchWide();
+	this.lastAbruptCompletion = this.position;
+}
+
+public void i2b() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2b;
+}
+
+public void i2c() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2c;
+}
+
+public void i2d() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2d;
+}
+
+public void i2f() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2f;
+}
+
+public void i2l() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2l;
+}
+
+public void i2s() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_i2s;
+}
+
+public void iadd() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iadd;
+}
+
+public void iaload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iaload;
+}
+
+public void iand() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iand;
+}
+
+public void iastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iastore;
+}
+
+public void iconst_0() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_0;
+}
+
+public void iconst_1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_1;
+}
+
+public void iconst_2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_2;
+}
+public void iconst_3() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_3;
+}
+
+public void iconst_4() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_4;
+}
+
+public void iconst_5() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_5;
+}
+
+public void iconst_m1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iconst_m1;
+}
+
+public void idiv() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_idiv;
+}
+
+public void if_acmpeq(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth-=2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_acmpne, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_acmpeq;
+		lbl.branch();
+	}
+}
+
+public void if_acmpne(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth-=2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_acmpeq, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_acmpne;
+		lbl.branch();
+	}
+}
+
+public void if_icmpeq(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpne, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmpeq;
+		lbl.branch();
+	}
+}
+
+public void if_icmpge(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmplt, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmpge;
+		lbl.branch();
+	}
+}
+
+public void if_icmpgt(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmple, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmpgt;
+		lbl.branch();
+	}
+}
+
+public void if_icmple(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpgt, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmple;
+		lbl.branch();
+	}
+}
+
+public void if_icmplt(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpge, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmplt;
+		lbl.branch();
+	}
+}
+
+public void if_icmpne(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_if_icmpeq, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_if_icmpne;
+		lbl.branch();
+	}
+}
+
+public void ifeq(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifne, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifeq;
+		lbl.branch();
+	}
+}
+
+public void ifge(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_iflt, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifge;
+		lbl.branch();
+	}
+}
+
+public void ifgt(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifle, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifgt;
+		lbl.branch();
+	}
+}
+
+public void ifle(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifgt, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifle;
+		lbl.branch();
+	}
+}
+
+public void iflt(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifge, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iflt;
+		lbl.branch();
+	}
+}
+
+public void ifne(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifeq, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifne;
+		lbl.branch();
+	}
+}
+
+public void ifnonnull(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifnull, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifnonnull;
+		lbl.branch();
+	}
+}
+
+public void ifnull(BranchLabel lbl) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.wideMode) {
+		generateWideRevertedConditionalBranch(Opcodes.OPC_ifnonnull, lbl);
+	} else {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ifnull;
+		lbl.branch();
+	}
+}
+
+final public void iinc(int index, int value) {
+	this.countLabels = 0;
+	if ((index > 255) || (value < -128 || value > 127)) { // have to widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iinc;
+		writeUnsignedShort(index);
+		writeSignedShort(value);
+	} else {
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 3;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iinc;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+		this.bCodeStream[this.classFileOffset++] = (byte) value;
+	}
+}
+
+public void iload(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void iload_0() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 0) {
+		this.maxLocals = 1;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload_0;
+}
+
+public void iload_1() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload_1;
+}
+
+public void iload_2() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload_2;
+}
+
+public void iload_3() {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iload_3;
+}
+
+public void imul() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_imul;
+}
+
+public int indexOfSameLineEntrySincePC(int pc, int line) {
+	for (int index = pc, max = this.pcToSourceMapSize; index < max; index+=2) {
+		if (this.pcToSourceMap[index+1] == line)
+			return index;
+	}
+	return -1;
+}
+
+public void ineg() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ineg;
+}
+
+public void init(ClassFile targetClassFile) {
+	this.classFile = targetClassFile;
+	this.constantPool = targetClassFile.constantPool;
+	this.bCodeStream = targetClassFile.contents;
+	this.classFileOffset = targetClassFile.contentsOffset;
+	this.startingClassFileOffset = this.classFileOffset;
+	this.pcToSourceMapSize = 0;
+	this.lastEntryPC = 0;
+	int length = this.visibleLocals.length;
+	if (noVisibleLocals.length < length) {
+		noVisibleLocals = new LocalVariableBinding[length];
+	}
+	System.arraycopy(noVisibleLocals, 0, this.visibleLocals, 0, length);
+	this.visibleLocalsCount = 0;
+
+	length = this.locals.length;
+	if (noLocals.length < length) {
+		noLocals = new LocalVariableBinding[length];
+	}
+	System.arraycopy(noLocals, 0, this.locals, 0, length);
+	this.allLocalsCounter = 0;
+
+	length = this.exceptionLabels.length;
+	if (noExceptionHandlers.length < length) {
+		noExceptionHandlers = new ExceptionLabel[length];
+	}
+	System.arraycopy(noExceptionHandlers, 0, this.exceptionLabels, 0, length);
+	this.exceptionLabelsCounter = 0;
+
+	length = this.labels.length;
+	if (noLabels.length < length) {
+		noLabels = new BranchLabel[length];
+	}
+	System.arraycopy(noLabels, 0, this.labels, 0, length);
+	this.countLabels = 0;
+	this.lastAbruptCompletion = -1;
+
+	this.stackMax = 0;
+	this.stackDepth = 0;
+	this.maxLocals = 0;
+	this.position = 0;
+}
+
+/**
+ * @param methodBinding the given method binding to initialize the max locals
+ */
+public void initializeMaxLocals(MethodBinding methodBinding) {
+	if (methodBinding == null) {
+		this.maxLocals = 0;
+		return;
+	}
+	this.maxLocals = methodBinding.isStatic() ? 0 : 1;
+	ReferenceBinding declaringClass = methodBinding.declaringClass;
+	// take into account enum constructor synthetic name+ordinal
+	if (methodBinding.isConstructor() && declaringClass.isEnum()) {
+		this.maxLocals += 2; // String and int (enum constant name+ordinal)
+	}
+
+	// take into account the synthetic parameters
+	if (methodBinding.isConstructor() && declaringClass.isNestedType()) {
+		this.maxLocals += declaringClass.getEnclosingInstancesSlotSize();
+		this.maxLocals += declaringClass.getOuterLocalVariablesSlotSize();
+	}
+	TypeBinding[] parameterTypes;
+	if ((parameterTypes = methodBinding.parameters) != null) {
+		for (int i = 0, max = parameterTypes.length; i < max; i++) {
+			switch (parameterTypes[i].id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					this.maxLocals += 2;
+					break;
+				default: 
+					this.maxLocals++;
+			}
+		}
+	}
+}
+
+/**
+ * Some placed labels might be branching to a goto bytecode which we can optimize better.
+ */
+public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabel, int gotoLocation) {
+	if (targetLabel.delegate != null) return false; // already inlined
+	int chaining = L_UNKNOWN;
+	for (int i = this.countLabels - 1; i >= 0; i--) {
+		BranchLabel currentLabel = this.labels[i];
+		if (currentLabel.position != gotoLocation) break;
+		if (currentLabel == targetLabel) {
+			chaining |= L_CANNOT_OPTIMIZE; // recursive
+			continue;
+		}
+		if (currentLabel.isStandardLabel()) {
+			if (currentLabel.delegate != null) continue; // ignore since already inlined
+			targetLabel.becomeDelegateFor(currentLabel);
+			chaining |= L_OPTIMIZABLE; // optimizable, providing no vetoing
+			continue;
+		}
+		// case label
+		chaining |= L_CANNOT_OPTIMIZE;
+	}
+	return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive
+}
+
+/**
+ * We didn't call it instanceof because there is a conflict with the
+ * instanceof keyword
+ */
+public void instance_of(TypeBinding typeBinding) {
+	this.instance_of(null, typeBinding);
+}
+
+/**
+ * We didn't call it instanceof because there is a conflict with the
+ * instanceof keyword
+ */
+public void instance_of(TypeReference typeReference, TypeBinding typeBinding) {
+	this.countLabels = 0;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_instanceof;
+	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
+}
+
+protected void invoke(byte opcode, int receiverAndArgsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) {
+	this.countLabels = 0;
+	if (opcode == Opcodes.OPC_invokeinterface) {
+		// invokeinterface
+		if (this.classFileOffset + 4 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position +=3;
+		this.bCodeStream[this.classFileOffset++] = opcode;
+		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, true));
+		this.bCodeStream[this.classFileOffset++] = (byte) receiverAndArgsSize;
+		this.bCodeStream[this.classFileOffset++] = 0;
+	} else {
+		// invokespecial
+		// invokestatic
+		// invokevirtual
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = opcode;
+		writeUnsignedShort(this.constantPool.literalIndexForMethod(declaringClass, selector, signature, false));
+	}
+	this.stackDepth += returnTypeSize - receiverAndArgsSize;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+}
+
+public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature) {
+	this.invokeDynamic(bootStrapIndex, argsSize, returnTypeSize, selector, signature, false, null, null);
+}
+
+public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature, boolean isConstructorReference, TypeReference lhsTypeReference, TypeReference [] typeArguments) {
+	if (this.classFileOffset + 4 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	int invokeDynamicIndex = this.constantPool.literalIndexForInvokeDynamic(bootStrapIndex, selector, signature);
+	this.position +=3;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_invokedynamic;
+	writeUnsignedShort(invokeDynamicIndex);
+	this.bCodeStream[this.classFileOffset++] = 0;
+	this.bCodeStream[this.classFileOffset++] = 0;
+	this.stackDepth += returnTypeSize - argsSize;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+}
+
+public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) {
+	this.invoke(opcode, methodBinding, declaringClass, null);
+}
+
+public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass, TypeReference[] typeArguments) {
+	if (declaringClass == null) declaringClass = methodBinding.declaringClass;
+	if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+		Util.recordNestedType(this.classFile, declaringClass);
+	}
+	// compute receiverAndArgsSize
+	int receiverAndArgsSize;
+	switch(opcode) {
+		case Opcodes.OPC_invokestatic :
+			receiverAndArgsSize = 0; // no receiver
+			break;
+		case Opcodes.OPC_invokeinterface :
+		case Opcodes.OPC_invokevirtual :
+			receiverAndArgsSize = 1; // receiver
+			break;
+		case Opcodes.OPC_invokespecial :
+			receiverAndArgsSize = 1; // receiver
+			if (methodBinding.isConstructor()) {
+				if (declaringClass.isNestedType()) {
+					ReferenceBinding nestedType = (ReferenceBinding) declaringClass;
+					// enclosing instances
+					receiverAndArgsSize += nestedType.getEnclosingInstancesSlotSize();
+					// outer local variables
+					SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables();
+					if (syntheticArguments != null) {
+						for (int i = 0, max = syntheticArguments.length; i < max; i++) {
+							switch (syntheticArguments[i].id)  {
+								case TypeIds.T_double :
+								case TypeIds.T_long :
+									receiverAndArgsSize += 2;
+									break;
+								default: 
+									receiverAndArgsSize++;
+									break;
+							}    						
+						}
+					}
+				}
+				if (declaringClass.isEnum()) {
+					// adding String (name) and int (ordinal)
+					receiverAndArgsSize += 2;
+				}
+			}    		
+			break;
+		default :
+			return; // should not occur
+
+	}
+	for (int i = methodBinding.parameters.length - 1; i >= 0; i--) {
+		switch (methodBinding.parameters[i].id) {
+			case TypeIds.T_double :
+			case TypeIds.T_long :
+				receiverAndArgsSize += 2;
+				break;
+			default :
+				receiverAndArgsSize ++;
+				break;
+		}
+	}
+	// compute return type size
+	int returnTypeSize;
+	switch (methodBinding.returnType.id) {
+		case TypeIds.T_double :
+		case TypeIds.T_long :
+			returnTypeSize = 2;
+			break;
+		case TypeIds.T_void :
+			returnTypeSize = 0;
+			break;
+		default :
+			returnTypeSize = 1;
+			break;
+	}
+	invoke(
+			opcode, 
+			receiverAndArgsSize, 
+			returnTypeSize, 
+			declaringClass.constantPoolName(), 
+			methodBinding.selector, 
+			methodBinding.signature(this.classFile));
+}
+
+protected void invokeAccessibleObjectSetAccessible() {
+	// invokevirtual: java.lang.reflect.AccessibleObject.setAccessible(Z)V;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME,
+			ConstantPool.SETACCESSIBLE_NAME,
+			ConstantPool.SETACCESSIBLE_SIGNATURE);
+}
+
+protected void invokeArrayNewInstance() {
+	// invokestatic: java.lang.reflect.Array.newInstance(Ljava.lang.Class;int[])Ljava.lang.Object;
+	invoke(
+			Opcodes.OPC_invokestatic,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JAVALANGREFLECTARRAY_CONSTANTPOOLNAME,
+			ConstantPool.NewInstance,
+			ConstantPool.NewInstanceSignature);
+}
+public void invokeClassForName() {
+	// invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;
+	invoke(
+		Opcodes.OPC_invokestatic,
+		1, // receiverAndArgsSize
+		1, // return type size
+		ConstantPool.JavaLangClassConstantPoolName,
+		ConstantPool.ForName,
+		ConstantPool.ForNameSignature);
+}
+
+protected void invokeClassGetDeclaredConstructor() {
+	// invokevirtual: java.lang.Class getDeclaredConstructor([Ljava.lang.Class)Ljava.lang.reflect.Constructor;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangClassConstantPoolName,
+			ConstantPool.GETDECLAREDCONSTRUCTOR_NAME,
+			ConstantPool.GETDECLAREDCONSTRUCTOR_SIGNATURE);
+}
+
+protected void invokeClassGetDeclaredField() {
+	// invokevirtual: java.lang.Class.getDeclaredField(Ljava.lang.String)Ljava.lang.reflect.Field;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangClassConstantPoolName,
+			ConstantPool.GETDECLAREDFIELD_NAME,
+			ConstantPool.GETDECLAREDFIELD_SIGNATURE);
+}
+
+protected void invokeClassGetDeclaredMethod() {
+	// invokevirtual: java.lang.Class getDeclaredMethod(Ljava.lang.String, [Ljava.lang.Class)Ljava.lang.reflect.Method;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			3, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangClassConstantPoolName,
+			ConstantPool.GETDECLAREDMETHOD_NAME,
+			ConstantPool.GETDECLAREDMETHOD_SIGNATURE);
+}
+
+public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
+	// invokevirtual: <enumConstantPoolName>.ordinal()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			enumTypeConstantPoolName,
+			ConstantPool.Ordinal,
+			ConstantPool.OrdinalSignature);
+}
+
+public void invokeIterableIterator(TypeBinding iterableReceiverType) {
+	// invokevirtual/interface: <iterableReceiverType>.iterator()
+	if ((iterableReceiverType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+		Util.recordNestedType(this.classFile, iterableReceiverType);
+	}
+	invoke(
+			iterableReceiverType.isInterface() ? Opcodes.OPC_invokeinterface : Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // returnTypeSize
+			iterableReceiverType.constantPoolName(), 
+			ConstantPool.ITERATOR_NAME, 
+			ConstantPool.ITERATOR_SIGNATURE);
+}
+
+public void invokeAutoCloseableClose(TypeBinding resourceType) {
+	// invokevirtual/interface: <resourceType>.close()
+	invoke(
+			resourceType.erasure().isInterface() ? Opcodes.OPC_invokeinterface : Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			0, // returnTypeSize
+			resourceType.constantPoolName(), 
+			ConstantPool.Close, 
+			ConstantPool.CloseSignature);
+}
+
+public void invokeThrowableAddSuppressed() {
+	invoke(Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			0, // returnTypeSize
+			ConstantPool.JavaLangThrowableConstantPoolName,
+			ConstantPool.AddSuppressed, 
+			ConstantPool.AddSuppressedSignature);
+}
+
+public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
+	// invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
+	int receiverAndArgsSize;
+	char[] signature;
+	switch (typeBindingID) {
+		case TypeIds.T_int :
+		case TypeIds.T_byte :
+		case TypeIds.T_short :
+			signature = ConstantPool.IntConstrSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_long :
+			signature = ConstantPool.LongConstrSignature;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_float :
+			signature = ConstantPool.FloatConstrSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_double :
+			signature = ConstantPool.DoubleConstrSignature;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_char :
+			signature = ConstantPool.CharConstrSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_boolean :
+			signature = ConstantPool.BooleanConstrSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_JavaLangObject :
+		case TypeIds.T_JavaLangString :
+		case TypeIds.T_null :
+			signature = ConstantPool.ObjectConstrSignature;
+			receiverAndArgsSize = 2;
+			break;
+		default:
+			return; // should not occur
+	}
+	invoke(
+			Opcodes.OPC_invokespecial,
+			receiverAndArgsSize,
+			0, // return type size
+			ConstantPool.JavaLangAssertionErrorConstantPoolName,
+			ConstantPool.Init,
+			signature);
+}
+
+public void invokeJavaLangAssertionErrorDefaultConstructor() {
+	// invokespecial: java.lang.AssertionError.<init>()V
+	invoke(
+			Opcodes.OPC_invokespecial,
+			1, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JavaLangAssertionErrorConstantPoolName,
+			ConstantPool.Init,
+			ConstantPool.DefaultConstructorSignature);
+}
+
+public void invokeJavaLangClassDesiredAssertionStatus() {
+	// invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangClassConstantPoolName,
+			ConstantPool.DesiredAssertionStatus,
+			ConstantPool.DesiredAssertionStatusSignature);
+}
+
+public void invokeJavaLangEnumvalueOf(ReferenceBinding binding) {
+	// invokestatic: java.lang.Enum.valueOf(Class,String)
+	invoke(
+			Opcodes.OPC_invokestatic,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangEnumConstantPoolName,
+			ConstantPool.ValueOf,
+			ConstantPool.ValueOfStringClassSignature);
+}
+
+public void invokeJavaLangEnumValues(TypeBinding enumBinding, ArrayBinding arrayBinding) {
+	char[] signature = "()".toCharArray(); //$NON-NLS-1$
+	signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
+	invoke(
+			Opcodes.OPC_invokestatic, 
+			0,  // receiverAndArgsSize
+			1,  // return type size
+			enumBinding.constantPoolName(), 
+			TypeConstants.VALUES, 
+			signature);
+}
+
+public void invokeJavaLangErrorConstructor() {
+	// invokespecial: java.lang.Error<init>(Ljava.lang.String;)V
+	invoke(
+			Opcodes.OPC_invokespecial,
+			2, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JavaLangErrorConstantPoolName,
+			ConstantPool.Init,
+			ConstantPool.StringConstructorSignature);
+}
+
+public void invokeJavaLangReflectConstructorNewInstance() {
+	// invokevirtual: java.lang.reflect.Constructor.newInstance([Ljava.lang.Object;)Ljava.lang.Object;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangReflectConstructorConstantPoolName,
+			ConstantPool.NewInstance,
+			ConstantPool.JavaLangReflectConstructorNewInstanceSignature);
+}
+
+protected void invokeJavaLangReflectFieldGetter(int typeID) {
+	char[] selector;
+	char[] signature;
+	int returnTypeSize;
+	switch (typeID) {
+		case TypeIds.T_int :
+			selector = ConstantPool.GET_INT_METHOD_NAME;
+			signature = ConstantPool.GET_INT_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		case TypeIds.T_byte :
+			selector = ConstantPool.GET_BYTE_METHOD_NAME;
+			signature = ConstantPool.GET_BYTE_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		case TypeIds.T_short :
+			selector = ConstantPool.GET_SHORT_METHOD_NAME;
+			signature = ConstantPool.GET_SHORT_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		case TypeIds.T_long :
+			selector = ConstantPool.GET_LONG_METHOD_NAME;
+			signature = ConstantPool.GET_LONG_METHOD_SIGNATURE;
+			returnTypeSize = 2;
+			break;
+		case TypeIds.T_float :
+			selector = ConstantPool.GET_FLOAT_METHOD_NAME;
+			signature = ConstantPool.GET_FLOAT_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		case TypeIds.T_double :
+			selector = ConstantPool.GET_DOUBLE_METHOD_NAME;
+			signature = ConstantPool.GET_DOUBLE_METHOD_SIGNATURE;
+			returnTypeSize = 2;
+			break;
+		case TypeIds.T_char :
+			selector = ConstantPool.GET_CHAR_METHOD_NAME;
+			signature = ConstantPool.GET_CHAR_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		case TypeIds.T_boolean :
+			selector = ConstantPool.GET_BOOLEAN_METHOD_NAME;
+			signature = ConstantPool.GET_BOOLEAN_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+		default :
+			selector = ConstantPool.GET_OBJECT_METHOD_NAME;
+			signature = ConstantPool.GET_OBJECT_METHOD_SIGNATURE;
+			returnTypeSize = 1;
+			break;
+	}
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			returnTypeSize, // return type size
+			ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
+			selector,
+			signature);
+}
+
+protected void invokeJavaLangReflectFieldSetter(int typeID) {
+	char[] selector;
+	char[] signature;
+	int receiverAndArgsSize;
+	switch (typeID) {
+		case TypeIds.T_int :
+			selector = ConstantPool.SET_INT_METHOD_NAME;
+			signature = ConstantPool.SET_INT_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_byte :
+			selector = ConstantPool.SET_BYTE_METHOD_NAME;
+			signature = ConstantPool.SET_BYTE_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_short :
+			selector = ConstantPool.SET_SHORT_METHOD_NAME;
+			signature = ConstantPool.SET_SHORT_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_long :
+			selector = ConstantPool.SET_LONG_METHOD_NAME;
+			signature = ConstantPool.SET_LONG_METHOD_SIGNATURE;
+			receiverAndArgsSize = 4;
+			break;
+		case TypeIds.T_float :
+			selector = ConstantPool.SET_FLOAT_METHOD_NAME;
+			signature = ConstantPool.SET_FLOAT_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_double :
+			selector = ConstantPool.SET_DOUBLE_METHOD_NAME;
+			signature = ConstantPool.SET_DOUBLE_METHOD_SIGNATURE;
+			receiverAndArgsSize = 4;
+			break;
+		case TypeIds.T_char :
+			selector = ConstantPool.SET_CHAR_METHOD_NAME;
+			signature = ConstantPool.SET_CHAR_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_boolean :
+			selector = ConstantPool.SET_BOOLEAN_METHOD_NAME;
+			signature = ConstantPool.SET_BOOLEAN_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+		default :
+			selector = ConstantPool.SET_OBJECT_METHOD_NAME;
+			signature = ConstantPool.SET_OBJECT_METHOD_SIGNATURE;
+			receiverAndArgsSize = 3;
+			break;
+	}
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			receiverAndArgsSize,
+			0, // return type size
+			ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME,
+			selector,
+			signature);
+}
+
+public void invokeJavaLangReflectMethodInvoke() {
+	// invokevirtual: java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			3, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME,
+			ConstantPool.INVOKE_METHOD_METHOD_NAME,
+			ConstantPool.INVOKE_METHOD_METHOD_SIGNATURE);
+}
+
+public void invokeJavaUtilIteratorHasNext() {
+	// invokeinterface java.util.Iterator.hasNext()Z
+	invoke(
+			Opcodes.OPC_invokeinterface,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaUtilIteratorConstantPoolName,
+			ConstantPool.HasNext,
+			ConstantPool.HasNextSignature);
+}
+
+public void invokeJavaUtilIteratorNext() {
+	// invokeinterface java.util.Iterator.next()java.lang.Object
+	invoke(
+			Opcodes.OPC_invokeinterface,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaUtilIteratorConstantPoolName,
+			ConstantPool.Next,
+			ConstantPool.NextSignature);
+}
+
+public void invokeNoClassDefFoundErrorStringConstructor() {
+	// invokespecial: java.lang.NoClassDefFoundError.<init>(Ljava.lang.String;)V
+	invoke(
+			Opcodes.OPC_invokespecial,
+			2, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName,
+			ConstantPool.Init,
+			ConstantPool.StringConstructorSignature);
+}
+
+public void invokeObjectGetClass() {
+	// invokevirtual: java.lang.Object.getClass()Ljava.lang.Class;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangObjectConstantPoolName,
+			ConstantPool.GetClass,
+			ConstantPool.GetClassSignature);
+}
+
+/**
+ * The equivalent code performs a string conversion of the TOS
+ * @param typeID <CODE>int</CODE>
+ */
+public void invokeStringConcatenationAppendForType(int typeID) {
+	int receiverAndArgsSize;
+	char[] declaringClass = null;
+	char[] selector = ConstantPool.Append;
+	char[] signature = null;
+	switch (typeID) {
+		case TypeIds.T_int :
+		case TypeIds.T_byte :
+		case TypeIds.T_short :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendIntSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendIntSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_long :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendLongSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendLongSignature;
+			}
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_float :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendFloatSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendFloatSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_double :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendDoubleSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendDoubleSignature;
+			}
+			receiverAndArgsSize = 3;
+			break;
+		case TypeIds.T_char :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendCharSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendCharSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_boolean :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendBooleanSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendBooleanSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_JavaLangString :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendStringSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendStringSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+		default :
+			if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+				declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+				signature = ConstantPool.StringBuilderAppendObjectSignature;
+			} else {
+				declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+				signature = ConstantPool.StringBufferAppendObjectSignature;
+			}
+			receiverAndArgsSize = 2;
+			break;
+	}
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			receiverAndArgsSize,
+			1, // return type size
+			declaringClass,
+			selector,
+			signature);
+}
+
+public void invokeStringConcatenationDefaultConstructor() {
+	// invokespecial: java.lang.StringBuffer.<init>()V
+	// or invokespecial: java.lang.StringBuilder.<init>()V
+	char[] declaringClass;
+	if (this.targetLevel < ClassFileConstants.JDK1_5) {
+		declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+	} else {
+		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+	}
+	invoke(
+			Opcodes.OPC_invokespecial,
+			1, // receiverAndArgsSize
+			0, // return type size
+			declaringClass,
+			ConstantPool.Init,
+			ConstantPool.DefaultConstructorSignature);
+}
+
+public void invokeStringConcatenationStringConstructor() {
+	// invokespecial: java.lang.StringBuffer.<init>(java.lang.String)V
+	// or invokespecial: java.lang.StringBuilder.<init>(java.lang.String)V
+	char[] declaringClass;
+	if (this.targetLevel < ClassFileConstants.JDK1_5) {
+		// invokespecial: java.lang.StringBuffer.<init>()V
+		declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+	} else {
+		// invokespecial: java.lang.StringStringBuilder.<init>(java.langString)V
+		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+	}
+	invoke(
+			Opcodes.OPC_invokespecial,
+			2, // receiverAndArgsSize
+			0, // return type size
+			declaringClass,
+			ConstantPool.Init,
+			ConstantPool.StringConstructorSignature);
+}
+
+public void invokeStringConcatenationToString() {
+	// invokespecial: java.lang.StringBuffer.toString()java.lang.String
+	// or invokespecial: java.lang.StringBuilder.toString()java.lang.String
+	char[] declaringClass;
+	if (this.targetLevel < ClassFileConstants.JDK1_5) {
+		// invokespecial: java.lang.StringBuffer.<init>()V
+		declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName;
+	} else {
+		// invokespecial: java.lang.StringStringBuilder.<init>(java.langString)V
+		declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName;
+	}	
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			declaringClass,
+			ConstantPool.ToString,
+			ConstantPool.ToStringSignature);
+}
+public void invokeStringEquals() {
+	// invokevirtual: java.lang.String.equals()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.Equals,
+			ConstantPool.EqualsSignature);
+}
+public void invokeStringHashCode() {
+	// invokevirtual: java.lang.String.hashCode()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.HashCode,
+			ConstantPool.HashCodeSignature);
+}
+public void invokeStringIntern() {
+	// invokevirtual: java.lang.String.intern()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.Intern,
+			ConstantPool.InternSignature);
+}
+public void invokeStringValueOf(int typeID) {
+	// invokestatic: java.lang.String.valueOf(argumentType)
+	char[] signature;
+	int receiverAndArgsSize;
+	switch (typeID) {
+		case TypeIds.T_int :
+		case TypeIds.T_byte :
+		case TypeIds.T_short :
+			signature = ConstantPool.ValueOfIntSignature;
+			receiverAndArgsSize = 1;
+			break;
+		case TypeIds.T_long :
+			signature = ConstantPool.ValueOfLongSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_float :
+			signature = ConstantPool.ValueOfFloatSignature;
+			receiverAndArgsSize = 1;
+			break;
+		case TypeIds.T_double :
+			signature = ConstantPool.ValueOfDoubleSignature;
+			receiverAndArgsSize = 2;
+			break;
+		case TypeIds.T_char :
+			signature = ConstantPool.ValueOfCharSignature;
+			receiverAndArgsSize = 1;
+			break;
+		case TypeIds.T_boolean :
+			signature = ConstantPool.ValueOfBooleanSignature;
+			receiverAndArgsSize = 1;
+			break;
+		case TypeIds.T_JavaLangObject :
+		case TypeIds.T_JavaLangString :
+		case TypeIds.T_null :
+		case TypeIds.T_undefined :
+			signature = ConstantPool.ValueOfObjectSignature;
+			receiverAndArgsSize = 1;
+			break;
+		default :
+			return; // should not occur
+	}
+	invoke(
+			Opcodes.OPC_invokestatic,
+			receiverAndArgsSize, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.ValueOf,
+			signature);
+}
+
+public void invokeSystemArraycopy() {
+	// invokestatic #21 <Method java/lang/System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>
+	invoke(
+			Opcodes.OPC_invokestatic,
+			5, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JavaLangSystemConstantPoolName,
+			ConstantPool.ArrayCopy,
+			ConstantPool.ArrayCopySignature);
+}
+
+public void invokeThrowableGetMessage() {
+	// invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangThrowableConstantPoolName,
+			ConstantPool.GetMessage,
+			ConstantPool.GetMessageSignature);
+}
+
+public void ior() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ior;
+}
+
+public void irem() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_irem;
+}
+
+public void ireturn() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ireturn;
+	this.lastAbruptCompletion = this.position;
+}
+
+public boolean isDefinitelyAssigned(Scope scope, int initStateIndex, LocalVariableBinding local) {
+	// Mirror of UnconditionalFlowInfo.isDefinitelyAssigned(..)
+	if ((local.tagBits & TagBits.IsArgument) != 0) {
+		return true;
+	}
+	if (initStateIndex == -1)
+		return false;
+	int localPosition = local.id + this.maxFieldCount;
+	MethodScope methodScope = scope.methodScope();
+	// id is zero-based
+	if (localPosition < UnconditionalFlowInfo.BitCacheSize) {
+		return (methodScope.definiteInits[initStateIndex] & (1L << localPosition)) != 0; // use bits
+	}
+	// use extra vector
+	long[] extraInits = methodScope.extraDefiniteInits[initStateIndex];
+	if (extraInits == null)
+		return false; // if vector not yet allocated, then not initialized
+	int vectorIndex;
+	if ((vectorIndex = (localPosition / UnconditionalFlowInfo.BitCacheSize) - 1) >= extraInits.length)
+		return false; // if not enough room in vector, then not initialized
+	return ((extraInits[vectorIndex]) & (1L << (localPosition % UnconditionalFlowInfo.BitCacheSize))) != 0;
+}
+
+public void ishl() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ishl;
+}
+
+public void ishr() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ishr;
+}
+
+public void istore(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= iArg) {
+		this.maxLocals = iArg + 1;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void istore_0() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals == 0) {
+		this.maxLocals = 1;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore_0;
+}
+
+public void istore_1() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 1) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore_1;
+}
+
+public void istore_2() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 2) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore_2;
+}
+
+public void istore_3() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.maxLocals <= 3) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_istore_3;
+}
+
+public void isub() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_isub;
+}
+
+public void iushr() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_iushr;
+}
+
+public void ixor() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ixor;
+}
+
+final public void jsr(BranchLabel lbl) {
+	if (this.wideMode) {
+		jsr_w(lbl);
+		return;
+	}
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_jsr;
+	lbl.branch();
+}
+
+final public void jsr_w(BranchLabel lbl) {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_jsr_w;
+	lbl.branchWide();
+}
+
+public void l2d() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_l2d;
+}
+
+public void l2f() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_l2f;
+}
+
+public void l2i() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_l2i;
+}
+
+public void ladd() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ladd;
+}
+
+public void laload() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_laload;
+}
+
+public void land() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_land;
+}
+
+public void lastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 4;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lastore;
+}
+
+public void lcmp() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lcmp;
+}
+
+public void lconst_0() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lconst_0;
+}
+
+public void lconst_1() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lconst_1;
+}
+
+public void ldc(float constant) {
+	this.countLabels = 0;
+	int index = this.constantPool.literalIndex(constant);
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (index > 255) {
+		// Generate a ldc_w
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc_w;
+		writeUnsignedShort(index);
+	} else {
+		// Generate a ldc
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+	}
+}
+
+public void ldc(int constant) {
+	this.countLabels = 0;
+	int index = this.constantPool.literalIndex(constant);
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (index > 255) {
+		// Generate a ldc_w
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc_w;
+		writeUnsignedShort(index);
+	} else {
+		// Generate a ldc
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+	}
+}
+
+public void ldc(String constant) {
+	this.countLabels = 0;
+	int currentCodeStreamPosition = this.position;
+	char[] constantChars = constant.toCharArray();
+	int index = this.constantPool.literalIndexForLdc(constantChars);
+	if (index > 0) {
+		// the string already exists inside the constant pool
+		// we reuse the same index
+		ldcForIndex(index);
+	} else {
+		// the string is too big to be utf8-encoded in one pass.
+		// we have to split it into different pieces.
+		// first we clean all side-effects due to the code above
+		// this case is very rare, so we can afford to lose time to handle it
+		this.position = currentCodeStreamPosition;
+		int i = 0;
+		int length = 0;
+		int constantLength = constant.length();
+		byte[] utf8encoding = new byte[Math.min(constantLength + 100, 65535)];
+		int utf8encodingLength = 0;
+		while ((length < 65532) && (i < constantLength)) {
+			char current = constantChars[i];
+			// we resize the byte array immediately if necessary
+			if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
+				System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
+			}
+			if ((current >= 0x0001) && (current <= 0x007F)) {
+				// we only need one byte: ASCII table
+				utf8encoding[length++] = (byte) current;
+			} else {
+				if (current > 0x07FF) {
+					// we need 3 bytes
+					utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+					utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+					utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+				} else {
+					// we can be 0 or between 0x0080 and 0x07FF
+					// In that case we only need 2 bytes
+					utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+					utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+				}
+			}
+			i++;
+		}
+		// check if all the string is encoded (PR 1PR2DWJ)
+		// the string is too big to be encoded in one pass
+		newStringContatenation();
+		dup();
+		// write the first part
+		char[] subChars = new char[i];
+		System.arraycopy(constantChars, 0, subChars, 0, i);
+		System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
+		index = this.constantPool.literalIndex(subChars, utf8encoding);
+		ldcForIndex(index);
+		// write the remaining part
+		invokeStringConcatenationStringConstructor();
+		while (i < constantLength) {
+			length = 0;
+			utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)];
+			int startIndex = i;
+			while ((length < 65532) && (i < constantLength)) {
+				char current = constantChars[i];
+				// we resize the byte array immediately if necessary
+				if (length + 3 > (utf8encodingLength = utf8encoding.length)) {
+					System.arraycopy(utf8encoding, 0, utf8encoding = new byte[Math.min(utf8encodingLength + 100, 65535)], 0, length);
+				}
+				if ((current >= 0x0001) && (current <= 0x007F)) {
+					// we only need one byte: ASCII table
+					utf8encoding[length++] = (byte) current;
+				} else {
+					if (current > 0x07FF) {
+						// we need 3 bytes
+						utf8encoding[length++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+						utf8encoding[length++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+						utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					} else {
+						// we can be 0 or between 0x0080 and 0x07FF
+						// In that case we only need 2 bytes
+						utf8encoding[length++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+						utf8encoding[length++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					}
+				}
+				i++;
+			}
+			// the next part is done
+			int newCharLength = i - startIndex;
+			subChars = new char[newCharLength];
+			System.arraycopy(constantChars, startIndex, subChars, 0, newCharLength);
+			System.arraycopy(utf8encoding, 0, utf8encoding = new byte[length], 0, length);
+			index = this.constantPool.literalIndex(subChars, utf8encoding);
+			ldcForIndex(index);
+			// now on the stack it should be a StringBuffer and a string.
+			invokeStringConcatenationAppendForType(TypeIds.T_JavaLangString);
+		}
+		invokeStringConcatenationToString();
+		invokeStringIntern();
+	}
+}
+
+public void ldc(TypeBinding typeBinding) {
+	this.countLabels = 0;
+	int index = this.constantPool.literalIndexForType(typeBinding);
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (index > 255) {
+		// Generate a ldc_w
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc_w;
+		writeUnsignedShort(index);
+	} else {
+		// Generate a ldc
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+	}
+}
+
+public void ldc2_w(double constant) {
+	this.countLabels = 0;
+	int index = this.constantPool.literalIndex(constant);
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	// Generate a ldc2_w
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc2_w;
+	writeUnsignedShort(index);
+}
+
+public void ldc2_w(long constant) {
+	this.countLabels = 0;
+	int index = this.constantPool.literalIndex(constant);
+	this.stackDepth += 2;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	// Generate a ldc2_w
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc2_w;
+	writeUnsignedShort(index);
+}
+
+public void ldcForIndex(int index) {
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (index > 255) {
+		// Generate a ldc_w
+		if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc_w;
+		writeUnsignedShort(index);
+	} else {
+		// Generate a ldc
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldc;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+	}
+}
+
+public void ldiv() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ldiv;
+}
+
+public void lload(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.maxLocals <= iArg + 1) {
+		this.maxLocals = iArg + 2;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void lload_0() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.maxLocals < 2) {
+		this.maxLocals = 2;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload_0;
+}
+
+public void lload_1() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.maxLocals < 3) {
+		this.maxLocals = 3;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload_1;
+}
+
+public void lload_2() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.maxLocals < 4) {
+		this.maxLocals = 4;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload_2;
+}
+
+public void lload_3() {
+	this.countLabels = 0;
+	this.stackDepth += 2;
+	if (this.maxLocals < 5) {
+		this.maxLocals = 5;
+	}
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lload_3;
+}
+
+public void lmul() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lmul;
+}
+
+public void lneg() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lneg;
+}
+
+public final void load(LocalVariableBinding localBinding) {
+	load(localBinding.type, localBinding.resolvedPosition);
+}
+
+protected final void load(TypeBinding typeBinding, int resolvedPosition) {
+	this.countLabels = 0;
+	// Using dedicated int bytecode
+	switch(typeBinding.id) {
+		case TypeIds.T_int :
+		case TypeIds.T_byte :
+		case TypeIds.T_char :
+		case TypeIds.T_boolean :
+		case TypeIds.T_short :
+			switch (resolvedPosition) {
+				case 0 :
+					iload_0();
+					break;
+				case 1 :
+					iload_1();
+					break;
+				case 2 :
+					iload_2();
+					break;
+				case 3 :
+					iload_3();
+					break;
+				//case -1 :
+				// internal failure: trying to load variable not supposed to be generated
+				//	break;
+				default :
+					iload(resolvedPosition);
+			}
+			break;
+		case TypeIds.T_float :
+			switch (resolvedPosition) {
+				case 0 :
+					fload_0();
+					break;
+				case 1 :
+					fload_1();
+					break;
+				case 2 :
+					fload_2();
+					break;
+				case 3 :
+					fload_3();
+					break;
+				default :
+					fload(resolvedPosition);
+			}
+			break;
+		case TypeIds.T_long :
+			switch (resolvedPosition) {
+				case 0 :
+					lload_0();
+					break;
+				case 1 :
+					lload_1();
+					break;
+				case 2 :
+					lload_2();
+					break;
+				case 3 :
+					lload_3();
+					break;
+				default :
+					lload(resolvedPosition);
+			}
+			break;
+		case TypeIds.T_double :
+			switch (resolvedPosition) {
+				case 0 :
+					dload_0();
+					break;
+				case 1 :
+					dload_1();
+					break;
+				case 2 :
+					dload_2();
+					break;
+				case 3 :
+					dload_3();
+					break;
+				default :
+					dload(resolvedPosition);
+			}
+			break;
+		default :
+			switch (resolvedPosition) {
+				case 0 :
+					aload_0();
+					break;
+				case 1 :
+					aload_1();
+					break;
+				case 2 :
+					aload_2();
+					break;
+				case 3 :
+					aload_3();
+					break;
+				default :
+					aload(resolvedPosition);
+			}
+	}
+}
+
+public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	int length = keys.length;
+	int pos = this.position;
+	defaultLabel.placeInstruction();
+	for (int i = 0; i < length; i++) {
+		casesLabel[i].placeInstruction();
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lookupswitch;
+	for (int i = (3 - (pos & 3)); i > 0; i--) { // faster than % 4
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = 0;
+	}
+	defaultLabel.branch();
+	writeSignedWord(length);
+	for (int i = 0; i < length; i++) {
+		writeSignedWord(keys[sortedIndexes[i]]);
+		casesLabel[sortedIndexes[i]].branch();
+	}
+}
+
+public void lor() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lor;
+}
+
+public void lrem() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lrem;
+}
+
+public void lreturn() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lreturn;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void lshl() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lshl;
+}
+
+public void lshr() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lshr;
+}
+
+public void lstore(int iArg) {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals <= iArg + 1) {
+		this.maxLocals = iArg + 2;
+	}
+	if (iArg > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore;
+		writeUnsignedShort(iArg);
+	} else {
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore;
+		this.bCodeStream[this.classFileOffset++] = (byte) iArg;
+	}
+}
+
+public void lstore_0() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 2) {
+		this.maxLocals = 2;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore_0;
+}
+
+public void lstore_1() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 3) {
+		this.maxLocals = 3;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore_1;
+}
+
+public void lstore_2() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 4) {
+		this.maxLocals = 4;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore_2;
+}
+
+public void lstore_3() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.maxLocals < 5) {
+		this.maxLocals = 5;
+	}
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lstore_3;
+}
+
+public void lsub() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lsub;
+}
+
+public void lushr() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lushr;
+}
+
+public void lxor() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_lxor;
+}
+
+public void monitorenter() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_monitorenter;
+}
+
+public void monitorexit() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_monitorexit;
+}
+
+public void multianewarray(TypeBinding typeBinding, int dimensions) {
+	this.multianewarray(null, typeBinding, dimensions, null);
+}
+
+public void multianewarray(
+		TypeReference typeReference,
+		TypeBinding typeBinding,
+		int dimensions,
+		Annotation [][] annotationsOnDimensions) {
+	this.countLabels = 0;
+	this.stackDepth += (1 - dimensions);
+	if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position += 2;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_multianewarray;
+	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
+	this.bCodeStream[this.classFileOffset++] = (byte) dimensions;
+}
+
+// We didn't call it new, because there is a conflit with the new keyword
+public void new_(TypeBinding typeBinding) {
+	this.new_(null, typeBinding);
+}
+
+// We didn't call it new, because there is a conflit with the new keyword
+public void new_(TypeReference typeReference, TypeBinding typeBinding) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	writeUnsignedShort(this.constantPool.literalIndexForType(typeBinding));
+}
+
+public void newarray(int array_Type) {
+	this.countLabels = 0;
+	if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position += 2;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_newarray;
+	this.bCodeStream[this.classFileOffset++] = (byte) array_Type;
+}
+
+public void newArray(ArrayBinding arrayBinding) {
+	this.newArray(null, arrayBinding);
+}
+
+public void newArray(TypeReference typeReference, ArrayBinding arrayBinding) {
+	this.newArray(null, null, arrayBinding);
+}
+
+public void newArray(TypeReference typeReference, Annotation[][] annotationsOnDimensions, ArrayBinding arrayBinding) {
+	TypeBinding component = arrayBinding.elementsType();
+	switch (component.id) {
+		case TypeIds.T_int :
+			newarray(ClassFileConstants.INT_ARRAY);
+			break;
+		case TypeIds.T_byte :
+			newarray(ClassFileConstants.BYTE_ARRAY);
+			break;
+		case TypeIds.T_boolean :
+			newarray(ClassFileConstants.BOOLEAN_ARRAY);
+			break;
+		case TypeIds.T_short :
+			newarray(ClassFileConstants.SHORT_ARRAY);
+			break;
+		case TypeIds.T_char :
+			newarray(ClassFileConstants.CHAR_ARRAY);
+			break;
+		case TypeIds.T_long :
+			newarray(ClassFileConstants.LONG_ARRAY);
+			break;
+		case TypeIds.T_float :
+			newarray(ClassFileConstants.FLOAT_ARRAY);
+			break;
+		case TypeIds.T_double :
+			newarray(ClassFileConstants.DOUBLE_ARRAY);
+			break;
+		default :
+			anewarray(component);
+	}
+}
+
+public void newJavaLangAssertionError() {
+	// new: java.lang.AssertionError
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName));
+}
+
+public void newJavaLangError() {
+	// new: java.lang.Error
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
+}
+
+public void newNoClassDefFoundError() {
+	// new: java.lang.NoClassDefFoundError
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName));
+}
+
+public void newStringContatenation() {
+	// new: java.lang.StringBuffer
+	// new: java.lang.StringBuilder
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax) {
+		this.stackMax = this.stackDepth;
+	}
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+		writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName));
+	} else {
+		writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName));
+	}
+}
+
+public void newWrapperFor(int typeID) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	switch (typeID) {
+		case TypeIds.T_int : // new: java.lang.Integer
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName));
+			break;
+		case TypeIds.T_boolean : // new: java.lang.Boolean
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName));
+			break;
+		case TypeIds.T_byte : // new: java.lang.Byte
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName));
+			break;
+		case TypeIds.T_char : // new: java.lang.Character
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName));
+			break;
+		case TypeIds.T_float : // new: java.lang.Float
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName));
+			break;
+		case TypeIds.T_double : // new: java.lang.Double
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName));
+			break;
+		case TypeIds.T_short : // new: java.lang.Short
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName));
+			break;
+		case TypeIds.T_long : // new: java.lang.Long
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName));
+			break;
+		case TypeIds.T_void : // new: java.lang.Void
+			writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName));
+	}
+}
+
+public void nop() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_nop;
+}
+
+public void optimizeBranch(int oldPosition, BranchLabel lbl) {
+	for (int i = 0; i < this.countLabels; i++) {
+		BranchLabel label = this.labels[i];
+		if (oldPosition == label.position) {
+			label.position = this.position;
+			if (label instanceof CaseLabel) {
+				int offset = this.position - ((CaseLabel) label).instructionPosition;
+				int[] forwardRefs = label.forwardReferences();
+				for (int j = 0, length = label.forwardReferenceCount(); j < length; j++) {
+					int forwardRef = forwardRefs[j];
+					this.writeSignedWord(forwardRef, offset);
+				}
+			} else {
+				int[] forwardRefs = label.forwardReferences();
+				for (int j = 0, length = label.forwardReferenceCount(); j < length; j++) {
+					final int forwardRef = forwardRefs[j];
+					this.writePosition(lbl, forwardRef);
+				}
+			}
+		}
+	}
+}
+
+public void pop() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_pop;
+}
+
+public void pop2() {
+	this.countLabels = 0;
+	this.stackDepth -= 2;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_pop2;
+}
+
+public void pushExceptionOnStack(TypeBinding binding) {
+	this.stackDepth = 1;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+}
+
+public void pushOnStack(TypeBinding binding) {
+	if (++this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+}
+
+public void record(LocalVariableBinding local) {
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+	if (this.allLocalsCounter == this.locals.length) {
+		// resize the collection
+		System.arraycopy(this.locals, 0, this.locals = new LocalVariableBinding[this.allLocalsCounter + LOCALS_INCREMENT], 0, this.allLocalsCounter);
+	}
+	this.locals[this.allLocalsCounter++] = local;
+	local.initializationPCs = new int[4];
+	local.initializationCount = 0;
+}
+
+public void recordExpressionType(TypeBinding typeBinding) {
+	// nothing to do
+}
+
+public void recordPositionsFrom(int startPC, int sourcePos) {
+	this.recordPositionsFrom(startPC, sourcePos, false);
+}
+
+public void recordPositionsFrom(int startPC, int sourcePos, boolean widen) {
+	/* Record positions in the table, only if nothing has
+	 * already been recorded. Since we output them on the way
+	 * up (children first for more specific info)
+	 * The pcToSourceMap table is always sorted.
+	 */
+	if ((this.generateAttributes & ClassFileConstants.ATTR_LINES) == 0
+			|| sourcePos == 0
+			|| (startPC == this.position && !widen)
+			|| startPC > this.position)
+		return;
+
+	// Widening an existing entry that already has the same source positions
+	if (this.pcToSourceMapSize + 4 > this.pcToSourceMap.length) {
+		// resize the array pcToSourceMap
+		System.arraycopy(this.pcToSourceMap, 0, this.pcToSourceMap = new int[this.pcToSourceMapSize << 1], 0, this.pcToSourceMapSize);
+	}
+	// lastEntryPC represents the endPC of the lastEntry.
+	if (this.pcToSourceMapSize > 0) {
+		int lineNumber;
+		int previousLineNumber = this.pcToSourceMap[this.pcToSourceMapSize - 1];
+		if (this.lineNumberStart == this.lineNumberEnd) {
+			// method on one line
+			lineNumber = this.lineNumberStart;
+		} else {
+			// Check next line number if this is the one we are looking for
+			int[] lineSeparatorPositions2 = this.lineSeparatorPositions;
+			int length = lineSeparatorPositions2.length;
+			if (previousLineNumber == 1) {
+				if (sourcePos < lineSeparatorPositions2[0]) {
+					lineNumber = 1;
+					/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
+					   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
+					*/
+					if (startPC < this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+						int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+						if (insertionIndex != -1) {
+							// widen the existing entry
+							// we have to figure out if we need to move the last entry at another location to keep a sorted table
+							/* First we need to check if at the insertion position there is not an existing entry
+							 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
+							 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
+							 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
+							 */
+							if (!((insertionIndex > 1) && (this.pcToSourceMap[insertionIndex - 1] == lineNumber))) {
+								if ((this.pcToSourceMapSize > 4) && (this.pcToSourceMap[this.pcToSourceMapSize - 4] > startPC)) {
+									System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - 2 - insertionIndex);
+									this.pcToSourceMap[insertionIndex++] = startPC;
+									this.pcToSourceMap[insertionIndex] = lineNumber;
+								} else {
+									this.pcToSourceMap[this.pcToSourceMapSize - 2] = startPC;
+								}
+							}
+						}
+					}
+					this.lastEntryPC = this.position;
+					return;
+				} else if (length == 1 || sourcePos < lineSeparatorPositions2[1]) {
+					lineNumber = 2;
+					if (startPC <= this.lastEntryPC) {
+						// we forgot to add an entry.
+						// search if an existing entry exists for startPC
+						int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+						if (insertionIndex != -1) {
+							// there is no existing entry starting with startPC.
+							int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
+							/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
+								in this case it is relevant to widen this entry instead of creating a new one.
+								line1: this(a,
+								  b,
+								  c);
+								with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
+								aload0 bytecode. The first entry is the one for the argument a.
+								But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
+								So we widen the existing entry (if there is one) or we create a new entry with the startPC.
+							*/
+							if (existingEntryIndex != -1) {
+								// widen existing entry
+								this.pcToSourceMap[existingEntryIndex] = startPC;
+							} else if (insertionIndex < 1 || this.pcToSourceMap[insertionIndex - 1] != lineNumber) {
+								// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
+								System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - insertionIndex);
+								this.pcToSourceMap[insertionIndex++] = startPC;
+								this.pcToSourceMap[insertionIndex] = lineNumber;
+								this.pcToSourceMapSize += 2;
+							}
+						} else if (this.position != this.lastEntryPC) { // no bytecode since last entry pc
+							if (this.lastEntryPC == startPC || this.lastEntryPC == this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+								this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+							} else {
+								this.pcToSourceMap[this.pcToSourceMapSize++] = this.lastEntryPC;
+								this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+							}
+						} else if (this.pcToSourceMap[this.pcToSourceMapSize - 1] < lineNumber && widen) {
+							// see if we can widen the existing entry
+							this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+						}
+					} else {
+						// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
+						this.pcToSourceMap[this.pcToSourceMapSize++] = startPC;
+						this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+					}
+					this.lastEntryPC = this.position;
+					return;
+				} else {
+					// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
+					lineNumber = Util.getLineNumber(sourcePos, this.lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
+				}
+			} else if (previousLineNumber < length) {
+				if (lineSeparatorPositions2[previousLineNumber - 2] < sourcePos) {
+					if (sourcePos < lineSeparatorPositions2[previousLineNumber - 1]) {
+						lineNumber = previousLineNumber;
+						/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
+						   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
+						*/
+						if (startPC < this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+							int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+							if (insertionIndex != -1) {
+								// widen the existing entry
+								// we have to figure out if we need to move the last entry at another location to keep a sorted table
+								/* First we need to check if at the insertion position there is not an existing entry
+								 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
+								 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
+								 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
+								 */
+								if (!((insertionIndex > 1) && (this.pcToSourceMap[insertionIndex - 1] == lineNumber))) {
+									if ((this.pcToSourceMapSize > 4) && (this.pcToSourceMap[this.pcToSourceMapSize - 4] > startPC)) {
+										System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - 2 - insertionIndex);
+										this.pcToSourceMap[insertionIndex++] = startPC;
+										this.pcToSourceMap[insertionIndex] = lineNumber;
+									} else {
+										this.pcToSourceMap[this.pcToSourceMapSize - 2] = startPC;
+									}
+								}
+							}
+						}
+						this.lastEntryPC = this.position;
+						return;
+					} else if (sourcePos < lineSeparatorPositions2[previousLineNumber]) {
+						lineNumber = previousLineNumber + 1;
+						if (startPC <= this.lastEntryPC) {
+							// we forgot to add an entry.
+							// search if an existing entry exists for startPC
+							int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+							if (insertionIndex != -1) {
+								// there is no existing entry starting with startPC.
+								int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
+								/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
+									in this case it is relevant to widen this entry instead of creating a new one.
+									line1: this(a,
+									  b,
+									  c);
+									with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
+									aload0 bytecode. The first entry is the one for the argument a.
+									But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
+									So we widen the existing entry (if there is one) or we create a new entry with the startPC.
+								*/
+								if (existingEntryIndex != -1) {
+									// widen existing entry
+									this.pcToSourceMap[existingEntryIndex] = startPC;
+								} else if (insertionIndex < 1 || this.pcToSourceMap[insertionIndex - 1] != lineNumber) {
+									// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
+									System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - insertionIndex);
+									this.pcToSourceMap[insertionIndex++] = startPC;
+									this.pcToSourceMap[insertionIndex] = lineNumber;
+									this.pcToSourceMapSize += 2;
+								}
+							} else if (this.position != this.lastEntryPC) { // no bytecode since last entry pc
+								if (this.lastEntryPC == startPC || this.lastEntryPC == this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+									this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+								} else {
+									this.pcToSourceMap[this.pcToSourceMapSize++] = this.lastEntryPC;
+									this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+								}
+							} else if (this.pcToSourceMap[this.pcToSourceMapSize - 1] < lineNumber && widen) {
+								// see if we can widen the existing entry
+								this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+							}
+						} else {
+							// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
+							this.pcToSourceMap[this.pcToSourceMapSize++] = startPC;
+							this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+						}
+						this.lastEntryPC = this.position;
+						return;
+					} else {
+						// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
+						lineNumber = Util.getLineNumber(sourcePos, this.lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
+					}
+				} else {
+					// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
+					lineNumber = Util.getLineNumber(sourcePos, this.lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
+				}
+			} else if (lineSeparatorPositions2[length - 1] < sourcePos) {
+				lineNumber = length + 1;
+				if (startPC <= this.lastEntryPC) {
+					// we forgot to add an entry.
+					// search if an existing entry exists for startPC
+					int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+					if (insertionIndex != -1) {
+						// there is no existing entry starting with startPC.
+						int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
+						/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
+							in this case it is relevant to widen this entry instead of creating a new one.
+							line1: this(a,
+							  b,
+							  c);
+							with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
+							aload0 bytecode. The first entry is the one for the argument a.
+							But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
+							So we widen the existing entry (if there is one) or we create a new entry with the startPC.
+						*/
+						if (existingEntryIndex != -1) {
+							// widen existing entry
+							this.pcToSourceMap[existingEntryIndex] = startPC;
+						} else if (insertionIndex < 1 || this.pcToSourceMap[insertionIndex - 1] != lineNumber) {
+							// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
+							System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - insertionIndex);
+							this.pcToSourceMap[insertionIndex++] = startPC;
+							this.pcToSourceMap[insertionIndex] = lineNumber;
+							this.pcToSourceMapSize += 2;
+						}
+					} else if (this.position != this.lastEntryPC) { // no bytecode since last entry pc
+						if (this.lastEntryPC == startPC || this.lastEntryPC == this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+							this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+						} else {
+							this.pcToSourceMap[this.pcToSourceMapSize++] = this.lastEntryPC;
+							this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+						}
+					} else if (this.pcToSourceMap[this.pcToSourceMapSize - 1] < lineNumber && widen) {
+						// see if we can widen the existing entry
+						this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+					}
+				} else {
+					// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
+					this.pcToSourceMap[this.pcToSourceMapSize++] = startPC;
+					this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+				}
+				this.lastEntryPC = this.position;
+				return;
+			} else {
+				// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
+				lineNumber = Util.getLineNumber(sourcePos, this.lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
+			}
+		}
+		// in this case there is already an entry in the table
+		if (previousLineNumber != lineNumber) {
+			if (startPC <= this.lastEntryPC) {
+				// we forgot to add an entry.
+				// search if an existing entry exists for startPC
+				int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+				if (insertionIndex != -1) {
+					// there is no existing entry starting with startPC.
+					int existingEntryIndex = indexOfSameLineEntrySincePC(startPC, lineNumber); // index for PC
+					/* the existingEntryIndex corresponds to an entry with the same line and a PC >= startPC.
+						in this case it is relevant to widen this entry instead of creating a new one.
+						line1: this(a,
+						  b,
+						  c);
+						with this code we generate each argument. We generate a aload0 to invoke the constructor. There is no entry for this
+						aload0 bytecode. The first entry is the one for the argument a.
+						But we want the constructor call to start at the aload0 pc and not just at the pc of the first argument.
+						So we widen the existing entry (if there is one) or we create a new entry with the startPC.
+					*/
+					if (existingEntryIndex != -1) {
+						// widen existing entry
+						this.pcToSourceMap[existingEntryIndex] = startPC;
+					} else if (insertionIndex < 1 || this.pcToSourceMap[insertionIndex - 1] != lineNumber) {
+						// we have to add an entry that won't be sorted. So we sort the pcToSourceMap.
+						System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - insertionIndex);
+						this.pcToSourceMap[insertionIndex++] = startPC;
+						this.pcToSourceMap[insertionIndex] = lineNumber;
+						this.pcToSourceMapSize += 2;
+					}
+				} else if (this.position != this.lastEntryPC) { // no bytecode since last entry pc
+					if (this.lastEntryPC == startPC || this.lastEntryPC == this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+						this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+					} else {
+						this.pcToSourceMap[this.pcToSourceMapSize++] = this.lastEntryPC;
+						this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+					}
+				} else if (this.pcToSourceMap[this.pcToSourceMapSize - 1] < lineNumber && widen) {
+					// see if we can widen the existing entry
+					this.pcToSourceMap[this.pcToSourceMapSize - 1] = lineNumber;
+				}
+			} else {
+				// we can safely add the new entry. The endPC of the previous entry is not in conflit with the startPC of the new entry.
+				this.pcToSourceMap[this.pcToSourceMapSize++] = startPC;
+				this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+			}
+		} else {
+			/* the last recorded entry is on the same line. But it could be relevant to widen this entry.
+			   we want to extend this entry forward in case we generated some bytecode before the last entry that are not related to any statement
+			*/
+			if (startPC < this.pcToSourceMap[this.pcToSourceMapSize - 2]) {
+				int insertionIndex = insertionIndex(this.pcToSourceMap, this.pcToSourceMapSize, startPC);
+				if (insertionIndex != -1) {
+					// widen the existing entry
+					// we have to figure out if we need to move the last entry at another location to keep a sorted table
+					/* First we need to check if at the insertion position there is not an existing entry
+					 * that includes the one we want to insert. This is the case if pcToSourceMap[insertionIndex - 1] == newLine.
+					 * In this case we don't want to change the table. If not, we want to insert a new entry. Prior to insertion
+					 * we want to check if it is worth doing an arraycopy. If not we simply update the recorded pc.
+					 */
+					if (!((insertionIndex > 1) && (this.pcToSourceMap[insertionIndex - 1] == lineNumber))) {
+						if ((this.pcToSourceMapSize > 4) && (this.pcToSourceMap[this.pcToSourceMapSize - 4] > startPC)) {
+							System.arraycopy(this.pcToSourceMap, insertionIndex, this.pcToSourceMap, insertionIndex + 2, this.pcToSourceMapSize - 2 - insertionIndex);
+							this.pcToSourceMap[insertionIndex++] = startPC;
+							this.pcToSourceMap[insertionIndex] = lineNumber;
+						} else {
+							this.pcToSourceMap[this.pcToSourceMapSize - 2] = startPC;
+						}
+					}
+				}
+			}
+		}
+		this.lastEntryPC = this.position;
+	} else {
+		int lineNumber = 0;
+		if (this.lineNumberStart == this.lineNumberEnd) {
+			// method on one line
+			lineNumber = this.lineNumberStart;
+		} else {
+			// since lineSeparatorPositions is zero-based, we pass this.lineNumberStart - 1 and this.lineNumberEnd - 1
+			lineNumber = Util.getLineNumber(sourcePos, this.lineSeparatorPositions, this.lineNumberStart - 1, this.lineNumberEnd - 1);
+		}
+		// record the first entry
+		this.pcToSourceMap[this.pcToSourceMapSize++] = startPC;
+		this.pcToSourceMap[this.pcToSourceMapSize++] = lineNumber;
+		this.lastEntryPC = this.position;
+	}
+}
+
+/**
+ * @param anExceptionLabel org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel
+ */
+public void registerExceptionHandler(ExceptionLabel anExceptionLabel) {
+	int length;
+	if (this.exceptionLabelsCounter == (length = this.exceptionLabels.length)) {
+		// resize the exception handlers table
+		System.arraycopy(this.exceptionLabels, 0, this.exceptionLabels = new ExceptionLabel[length + LABELS_INCREMENT], 0, length);
+	}
+	// no need to resize. So just add the new exception label
+	this.exceptionLabels[this.exceptionLabelsCounter++] = anExceptionLabel;
+}
+
+public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+	// given some flow info, make sure we did not loose some variables initialization
+	// if this happens, then we must update their pc entries to reflect it in debug attributes
+	if ((this.generateAttributes & (ClassFileConstants.ATTR_VARS
+			| ClassFileConstants.ATTR_STACK_MAP_TABLE
+			| ClassFileConstants.ATTR_STACK_MAP)) == 0)
+		return;
+	for (int i = 0; i < this.visibleLocalsCount; i++) {
+		LocalVariableBinding localBinding = this.visibleLocals[i];
+		if (localBinding != null && !isDefinitelyAssigned(scope, initStateIndex, localBinding) && localBinding.initializationCount > 0) {
+			localBinding.recordInitializationEndPC(this.position);
+		}
+	}
+}
+
+/**
+ * Remove all entries in pcToSourceMap table that are beyond this.position
+ */
+public void removeUnusedPcToSourceMapEntries() {
+	if (this.pcToSourceMapSize != 0) {
+		while (this.pcToSourceMapSize >= 2 && this.pcToSourceMap[this.pcToSourceMapSize - 2] > this.position) {
+			this.pcToSourceMapSize -= 2;
+		}
+	}
+}
+public void removeVariable(LocalVariableBinding localBinding) {
+	if (localBinding == null) return;
+	if (localBinding.initializationCount > 0) {
+		localBinding.recordInitializationEndPC(this.position);
+	}
+	for (int i = this.visibleLocalsCount - 1; i >= 0; i--) {
+		LocalVariableBinding visibleLocal = this.visibleLocals[i];
+		if (visibleLocal == localBinding){
+			this.visibleLocals[i] = null; // this variable is no longer visible afterwards
+			return;
+		}
+	}
+}
+
+/**
+ * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration
+ * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+ */
+public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
+	init(targetClassFile);
+	this.methodDeclaration = referenceMethod;
+	this.lambdaExpression = null;
+	int[] lineSeparatorPositions2 = this.lineSeparatorPositions;
+	if (lineSeparatorPositions2 != null) {
+		int length = lineSeparatorPositions2.length;
+		int lineSeparatorPositionsEnd = length - 1;
+		if (referenceMethod.isClinit()
+				|| referenceMethod.isConstructor()) {
+			this.lineNumberStart = 1;
+			this.lineNumberEnd = length == 0 ? 1 : length;
+		} else {
+			int start = Util.getLineNumber(referenceMethod.bodyStart, lineSeparatorPositions2, 0, lineSeparatorPositionsEnd);
+			this.lineNumberStart = start;
+			if (start > lineSeparatorPositionsEnd) {
+				this.lineNumberEnd = start;
+			} else {
+				int end = Util.getLineNumber(referenceMethod.bodyEnd, lineSeparatorPositions2, start - 1, lineSeparatorPositionsEnd);
+				if (end >= lineSeparatorPositionsEnd) {
+					end = length;
+				}
+				this.lineNumberEnd = end == 0 ? 1 : end;
+			}
+		}
+	}
+	this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
+	initializeMaxLocals(referenceMethod.binding);
+}
+
+public void reset(LambdaExpression lambda, ClassFile targetClassFile) {
+	init(targetClassFile);
+	this.lambdaExpression = lambda;
+	this.methodDeclaration = null;
+	int[] lineSeparatorPositions2 = this.lineSeparatorPositions;
+	if (lineSeparatorPositions2 != null) {
+		int length = lineSeparatorPositions2.length;
+		int lineSeparatorPositionsEnd = length - 1;
+		int start = Util.getLineNumber(lambda.body.sourceStart, lineSeparatorPositions2, 0, lineSeparatorPositionsEnd);
+		this.lineNumberStart = start;
+		if (start > lineSeparatorPositionsEnd) {
+			this.lineNumberEnd = start;
+		} else {
+			int end = Util.getLineNumber(lambda.body.sourceEnd, lineSeparatorPositions2, start - 1, lineSeparatorPositionsEnd);
+			if (end >= lineSeparatorPositionsEnd) {
+				end = length;
+			}
+			this.lineNumberEnd = end == 0 ? 1 : end;
+		}
+
+	}
+	this.preserveUnusedLocals = lambda.scope.compilerOptions().preserveAllLocalVariables;
+	initializeMaxLocals(lambda.binding);
+}
+
+public void reset(ClassFile givenClassFile) {
+	this.targetLevel = givenClassFile.targetJDK;
+	int produceAttributes = givenClassFile.produceAttributes;
+	this.generateAttributes = produceAttributes;
+	if ((produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
+		this.lineSeparatorPositions = givenClassFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.getLineSeparatorPositions();
+	} else {
+		this.lineSeparatorPositions = null;
+	}
+}
+
+/**
+ * @param targetClassFile The given classfile to reset the code stream
+ */
+public void resetForProblemClinit(ClassFile targetClassFile) {
+	init(targetClassFile);
+	initializeMaxLocals(null);
+}
+
+public void resetInWideMode() {
+	this.wideMode = true;
+}
+public void resetForCodeGenUnusedLocals() {
+	// nothing to do in standard code stream
+}
+private final void resizeByteArray() {
+	int length = this.bCodeStream.length;
+	int requiredSize = length + length;
+	if (this.classFileOffset >= requiredSize) {
+		// must be sure to grow enough
+		requiredSize = this.classFileOffset + length;
+	}
+	System.arraycopy(this.bCodeStream, 0, this.bCodeStream = new byte[requiredSize], 0, length);
+}
+
+final public void ret(int index) {
+	this.countLabels = 0;
+	if (index > 255) { // Widen
+		if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_wide;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ret;
+		writeUnsignedShort(index);
+	} else { // Don't Widen
+		if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position += 2;
+		this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_ret;
+		this.bCodeStream[this.classFileOffset++] = (byte) index;
+	}
+}
+
+public void return_() {
+	this.countLabels = 0;
+	// the stackDepth should be equal to 0
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_return;
+	this.lastAbruptCompletion = this.position;
+}
+
+public void saload() {
+	this.countLabels = 0;
+	this.stackDepth--;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_saload;
+}
+
+public void sastore() {
+	this.countLabels = 0;
+	this.stackDepth -= 3;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_sastore;
+}
+
+/**
+ * @param operatorConstant int
+ * @param type_ID int
+ */
+public void sendOperator(int operatorConstant, int type_ID) {
+	switch (type_ID) {
+		case TypeIds.T_int :
+		case TypeIds.T_boolean :
+		case TypeIds.T_char :
+		case TypeIds.T_byte :
+		case TypeIds.T_short :
+			switch (operatorConstant) {
+				case OperatorIds.PLUS :
+					iadd();
+					break;
+				case OperatorIds.MINUS :
+					isub();
+					break;
+				case OperatorIds.MULTIPLY :
+					imul();
+					break;
+				case OperatorIds.DIVIDE :
+					idiv();
+					break;
+				case OperatorIds.REMAINDER :
+					irem();
+					break;
+				case OperatorIds.LEFT_SHIFT :
+					ishl();
+					break;
+				case OperatorIds.RIGHT_SHIFT :
+					ishr();
+					break;
+				case OperatorIds.UNSIGNED_RIGHT_SHIFT :
+					iushr();
+					break;
+				case OperatorIds.AND :
+					iand();
+					break;
+				case OperatorIds.OR :
+					ior();
+					break;
+				case OperatorIds.XOR :
+					ixor();
+					break;
+			}
+			break;
+		case TypeIds.T_long :
+			switch (operatorConstant) {
+				case OperatorIds.PLUS :
+					ladd();
+					break;
+				case OperatorIds.MINUS :
+					lsub();
+					break;
+				case OperatorIds.MULTIPLY :
+					lmul();
+					break;
+				case OperatorIds.DIVIDE :
+					ldiv();
+					break;
+				case OperatorIds.REMAINDER :
+					lrem();
+					break;
+				case OperatorIds.LEFT_SHIFT :
+					lshl();
+					break;
+				case OperatorIds.RIGHT_SHIFT :
+					lshr();
+					break;
+				case OperatorIds.UNSIGNED_RIGHT_SHIFT :
+					lushr();
+					break;
+				case OperatorIds.AND :
+					land();
+					break;
+				case OperatorIds.OR :
+					lor();
+					break;
+				case OperatorIds.XOR :
+					lxor();
+					break;
+			}
+			break;
+		case TypeIds.T_float :
+			switch (operatorConstant) {
+				case OperatorIds.PLUS :
+					fadd();
+					break;
+				case OperatorIds.MINUS :
+					fsub();
+					break;
+				case OperatorIds.MULTIPLY :
+					fmul();
+					break;
+				case OperatorIds.DIVIDE :
+					fdiv();
+					break;
+				case OperatorIds.REMAINDER :
+					frem();
+			}
+			break;
+		case TypeIds.T_double :
+			switch (operatorConstant) {
+				case OperatorIds.PLUS :
+					dadd();
+					break;
+				case OperatorIds.MINUS :
+					dsub();
+					break;
+				case OperatorIds.MULTIPLY :
+					dmul();
+					break;
+				case OperatorIds.DIVIDE :
+					ddiv();
+					break;
+				case OperatorIds.REMAINDER :
+					drem();
+			}
+	}
+}
+
+public void sipush(int s) {
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_sipush;
+	writeSignedShort(s);
+}
+
+public void store(LocalVariableBinding localBinding, boolean valueRequired) {
+	int localPosition = localBinding.resolvedPosition;
+	// Using dedicated int bytecode
+	switch(localBinding.type.id) {
+		case TypeIds.T_int :
+		case TypeIds.T_char :
+		case TypeIds.T_byte :
+		case TypeIds.T_short :
+		case TypeIds.T_boolean :
+			if (valueRequired)
+				dup();
+			switch (localPosition) {
+				case 0 :
+					istore_0();
+					break;
+				case 1 :
+					istore_1();
+					break;
+				case 2 :
+					istore_2();
+					break;
+				case 3 :
+					istore_3();
+					break;
+				//case -1 :
+				// internal failure: trying to store into variable not supposed to be generated
+				//	break;
+				default :
+					istore(localPosition);
+			}
+			break;
+		case TypeIds.T_float :
+			if (valueRequired)
+				dup();
+			switch (localPosition) {
+				case 0 :
+					fstore_0();
+					break;
+				case 1 :
+					fstore_1();
+					break;
+				case 2 :
+					fstore_2();
+					break;
+				case 3 :
+					fstore_3();
+					break;
+				default :
+					fstore(localPosition);
+			}
+			break;
+		case TypeIds.T_double :
+			if (valueRequired)
+				dup2();
+			switch (localPosition) {
+				case 0 :
+					dstore_0();
+					break;
+				case 1 :
+					dstore_1();
+					break;
+				case 2 :
+					dstore_2();
+					break;
+				case 3 :
+					dstore_3();
+					break;
+				default :
+					dstore(localPosition);
+			}
+			break;
+		case TypeIds.T_long :
+			if (valueRequired)
+				dup2();
+			switch (localPosition) {
+				case 0 :
+					lstore_0();
+					break;
+				case 1 :
+					lstore_1();
+					break;
+				case 2 :
+					lstore_2();
+					break;
+				case 3 :
+					lstore_3();
+					break;
+				default :
+					lstore(localPosition);
+			}
+			break;
+		default:
+			// Reference object
+			if (valueRequired)
+				dup();
+			switch (localPosition) {
+				case 0 :
+					astore_0();
+					break;
+				case 1 :
+					astore_1();
+					break;
+				case 2 :
+					astore_2();
+					break;
+				case 3 :
+					astore_3();
+					break;
+				default :
+					astore(localPosition);
+			}
+	}
+}
+
+public void swap() {
+	this.countLabels = 0;
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_swap;
+}
+
+public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
+	this.countLabels = 0;
+	this.stackDepth--;
+	int length = casesLabel.length;
+	int pos = this.position;
+	defaultLabel.placeInstruction();
+	for (int i = 0; i < length; i++)
+		casesLabel[i].placeInstruction();
+	if (this.classFileOffset >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_tableswitch;
+	// padding
+	for (int i = (3 - (pos & 3)); i > 0; i--) {
+		if (this.classFileOffset >= this.bCodeStream.length) {
+			resizeByteArray();
+		}
+		this.position++;
+		this.bCodeStream[this.classFileOffset++] = 0;
+	}
+	defaultLabel.branch();
+	writeSignedWord(low);
+	writeSignedWord(high);
+	int i = low, j = low;
+	// the index j is used to know if the index i is one of the missing entries in case of an
+	// optimized tableswitch
+	while (true) {
+		int index;
+		int key = keys[index = sortedIndexes[j - low]];
+		if (key == i) {
+			casesLabel[index].branch();
+			j++;
+			if (i == high) break; // if high is maxint, then avoids wrapping to minint.
+		} else {
+			defaultLabel.branch();
+		}
+		i++;
+	}
+}
+
+public void throwAnyException(LocalVariableBinding anyExceptionVariable) {
+	this.load(anyExceptionVariable);
+	athrow();
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer("( position:"); //$NON-NLS-1$
+	buffer.append(this.position);
+	buffer.append(",\nstackDepth:"); //$NON-NLS-1$
+	buffer.append(this.stackDepth);
+	buffer.append(",\nmaxStack:"); //$NON-NLS-1$
+	buffer.append(this.stackMax);
+	buffer.append(",\nmaxLocals:"); //$NON-NLS-1$
+	buffer.append(this.maxLocals);
+	buffer.append(")"); //$NON-NLS-1$
+	return buffer.toString();
+}
+protected void writePosition(BranchLabel label) {
+	int offset = label.position - this.position + 1;
+	if (Math.abs(offset) > 0x7FFF && !this.wideMode) {
+		throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
+	}
+	this.writeSignedShort(offset);
+	int[] forwardRefs = label.forwardReferences();
+	for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
+		this.writePosition(label, forwardRefs[i]);
+	}
+}
+
+protected void writePosition(BranchLabel label, int forwardReference) {
+	final int offset = label.position - forwardReference + 1;
+	if (Math.abs(offset) > 0x7FFF && !this.wideMode) {
+		throw new AbortMethod(CodeStream.RESTART_IN_WIDE_MODE, null);
+	}
+	if (this.wideMode) {
+		if ((label.tagBits & BranchLabel.WIDE) != 0) {
+			this.writeSignedWord(forwardReference, offset);
+		} else {
+			this.writeSignedShort(forwardReference, offset);
+		}
+	} else {
+		this.writeSignedShort(forwardReference, offset);
+	}
+}
+
+/**
+ * Write a signed 16 bits value into the byte array
+ * @param value the signed short
+ */
+private final void writeSignedShort(int value) {
+	// we keep the resize in here because it is used outside the code stream
+	if (this.classFileOffset + 1 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position += 2;
+	this.bCodeStream[this.classFileOffset++] = (byte) (value >> 8);
+	this.bCodeStream[this.classFileOffset++] = (byte) value;
+}
+
+private final void writeSignedShort(int pos, int value) {
+	int currentOffset = this.startingClassFileOffset + pos;
+	if (currentOffset + 1 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.bCodeStream[currentOffset] = (byte) (value >> 8);
+	this.bCodeStream[currentOffset + 1] = (byte) value;
+}
+
+protected final void writeSignedWord(int value) {
+	// we keep the resize in here because it is used outside the code stream
+	if (this.classFileOffset + 3 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position += 4;
+	this.bCodeStream[this.classFileOffset++] = (byte) ((value & 0xFF000000) >> 24);
+	this.bCodeStream[this.classFileOffset++] = (byte) ((value & 0xFF0000) >> 16);
+	this.bCodeStream[this.classFileOffset++] = (byte) ((value & 0xFF00) >> 8);
+	this.bCodeStream[this.classFileOffset++] = (byte) (value & 0xFF);
+}
+
+protected void writeSignedWord(int pos, int value) {
+	int currentOffset = this.startingClassFileOffset + pos;
+	if (currentOffset + 3 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.bCodeStream[currentOffset++] = (byte) ((value & 0xFF000000) >> 24);
+	this.bCodeStream[currentOffset++] = (byte) ((value & 0xFF0000) >> 16);
+	this.bCodeStream[currentOffset++] = (byte) ((value & 0xFF00) >> 8);
+	this.bCodeStream[currentOffset++] = (byte) (value & 0xFF);
+}
+
+/**
+ * Write a unsigned 16 bits value into the byte array
+ * @param value the unsigned short
+ */
+private final void writeUnsignedShort(int value) {
+	// no bound check since used only from within codestream where already checked
+	this.position += 2;
+	this.bCodeStream[this.classFileOffset++] = (byte) (value >>> 8);
+	this.bCodeStream[this.classFileOffset++] = (byte) value;
+}
+
+protected void writeWidePosition(BranchLabel label) {
+	int labelPos = label.position;
+	int offset = labelPos - this.position + 1;
+	this.writeSignedWord(offset);
+	int[] forwardRefs = label.forwardReferences();
+	for (int i = 0, max = label.forwardReferenceCount(); i < max; i++) {
+		int forward = forwardRefs[i];
+		offset = labelPos - forward + 1;
+		this.writeSignedWord(forward, offset);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
new file mode 100644
index 0000000..d9ef873
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -0,0 +1,1095 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335        
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.Util;
+/**
+ * This type is used to store all the constant pool entries.
+ */
+public class ConstantPool implements ClassFileConstants, TypeIds {
+	public static final int DOUBLE_INITIAL_SIZE = 5;
+	public static final int FLOAT_INITIAL_SIZE = 3;
+	public static final int INT_INITIAL_SIZE = 248;
+	public static final int LONG_INITIAL_SIZE = 5;
+	public static final int UTF8_INITIAL_SIZE = 778;
+	public static final int STRING_INITIAL_SIZE = 761;
+	public static final int METHODS_AND_FIELDS_INITIAL_SIZE = 450;
+	public static final int CLASS_INITIAL_SIZE = 86;
+	public static final int NAMEANDTYPE_INITIAL_SIZE = 272;
+	public static final int CONSTANTPOOL_INITIAL_SIZE = 2000;
+	public static final int CONSTANTPOOL_GROW_SIZE = 6000;
+	protected DoubleCache doubleCache;
+	protected FloatCache floatCache;
+	protected IntegerCache intCache;
+	protected LongCache longCache;
+	public CharArrayCache UTF8Cache;
+	protected CharArrayCache stringCache;
+	protected HashtableOfObject methodsAndFieldsCache;
+	protected CharArrayCache classCache;
+	protected HashtableOfObject nameAndTypeCacheForFieldsAndMethods;
+	public byte[] poolContent;
+	public int currentIndex = 1;
+	public int currentOffset;
+	public int[] offsets;
+
+	public ClassFile classFile;
+	public static final char[] Append = "append".toCharArray(); //$NON-NLS-1$
+	public static final char[] ARRAY_NEWINSTANCE_NAME = "newInstance".toCharArray(); //$NON-NLS-1$
+	public static final char[] ARRAY_NEWINSTANCE_SIGNATURE = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayCopy = "arraycopy".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayCopySignature = "(Ljava/lang/Object;ILjava/lang/Object;II)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] booleanBooleanSignature = "(Z)Ljava/lang/Boolean;".toCharArray(); //$NON-NLS-1$
+	public static final char[] BooleanConstrSignature = "(Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_NAME = "booleanValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE = "()Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] byteByteSignature = "(B)Ljava/lang/Byte;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ByteConstrSignature = "(B)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] BYTEVALUE_BYTE_METHOD_NAME = "byteValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] BYTEVALUE_BYTE_METHOD_SIGNATURE = "()B".toCharArray(); //$NON-NLS-1$
+	public static final char[] charCharacterSignature = "(C)Ljava/lang/Character;".toCharArray(); //$NON-NLS-1$
+	public static final char[] CharConstrSignature = "(C)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] CHARVALUE_CHARACTER_METHOD_NAME = "charValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] CHARVALUE_CHARACTER_METHOD_SIGNATURE = "()C".toCharArray(); //$NON-NLS-1$
+	public static final char[] Clinit = "<clinit>".toCharArray(); //$NON-NLS-1$
+	public static final char[] DefaultConstructorSignature = "()V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ClinitSignature = DefaultConstructorSignature;
+	public static final char[] Close = "close".toCharArray(); //$NON-NLS-1$
+	public static final char[] CloseSignature = "()V".toCharArray(); //$NON-NLS-1$
+	public static final char[] DesiredAssertionStatus = "desiredAssertionStatus".toCharArray(); //$NON-NLS-1$
+	public static final char[] DesiredAssertionStatusSignature = "()Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] DoubleConstrSignature = "(D)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] doubleDoubleSignature = "(D)Ljava/lang/Double;".toCharArray(); //$NON-NLS-1$
+	public static final char[] DOUBLEVALUE_DOUBLE_METHOD_NAME = "doubleValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE = "()D".toCharArray(); //$NON-NLS-1$
+	public static final char[] Exit = "exit".toCharArray(); //$NON-NLS-1$
+	public static final char[] ExitIntSignature = "(I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] FloatConstrSignature = "(F)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] floatFloatSignature = "(F)Ljava/lang/Float;".toCharArray(); //$NON-NLS-1$
+	public static final char[] FLOATVALUE_FLOAT_METHOD_NAME = "floatValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] FLOATVALUE_FLOAT_METHOD_SIGNATURE = "()F".toCharArray(); //$NON-NLS-1$
+	public static final char[] ForName = "forName".toCharArray(); //$NON-NLS-1$
+	public static final char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BOOLEAN_METHOD_NAME = "getBoolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BYTE_METHOD_NAME = "getByte".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;)B".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_CHAR_METHOD_NAME = "getChar".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;)C".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_DOUBLE_METHOD_NAME = "getDouble".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;)D".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_FLOAT_METHOD_NAME = "getFloat".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;)F".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_INT_METHOD_NAME = "getInt".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;)I".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_LONG_METHOD_NAME = "getLong".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;)J".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_OBJECT_METHOD_NAME = "get".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_SHORT_METHOD_NAME = "getShort".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;)S".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetClass = "getClass".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetClassSignature = "()Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetComponentType = "getComponentType".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetComponentTypeSignature = GetClassSignature;
+	public static final char[] GetConstructor = "getConstructor".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDCONSTRUCTOR_NAME = "getDeclaredConstructor".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDCONSTRUCTOR_SIGNATURE = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
+	// predefined methods constant names
+	public static final char[] GETDECLAREDFIELD_NAME = "getDeclaredField".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDFIELD_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/reflect/Field;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDMETHOD_NAME = "getDeclaredMethod".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDMETHOD_SIGNATURE = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetMessage = "getMessage".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetMessageSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] HasNext = "hasNext".toCharArray();//$NON-NLS-1$
+	public static final char[] HasNextSignature = "()Z".toCharArray();//$NON-NLS-1$
+	public static final char[] Init = "<init>".toCharArray(); //$NON-NLS-1$
+	public static final char[] IntConstrSignature = "(I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ITERATOR_NAME = "iterator".toCharArray(); //$NON-NLS-1$
+	public static final char[] ITERATOR_SIGNATURE = "()Ljava/util/Iterator;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Intern = "intern".toCharArray(); //$NON-NLS-1$
+	public static final char[] InternSignature = GetMessageSignature;
+	public static final char[] IntIntegerSignature = "(I)Ljava/lang/Integer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] INTVALUE_INTEGER_METHOD_NAME = "intValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] INTVALUE_INTEGER_METHOD_SIGNATURE = "()I".toCharArray(); //$NON-NLS-1$
+	public static final char[] INVOKE_METHOD_METHOD_NAME = "invoke".toCharArray(); //$NON-NLS-1$
+	public static final char[] INVOKE_METHOD_METHOD_SIGNATURE = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[][] JAVA_LANG_REFLECT_ACCESSIBLEOBJECT = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "AccessibleObject".toCharArray()}; //$NON-NLS-1$
+	public static final char[][] JAVA_LANG_REFLECT_ARRAY = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "Array".toCharArray()}; //$NON-NLS-1$
+	// predefined type constant names
+	public static final char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangAssertionErrorConstantPoolName = "java/lang/AssertionError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangByteConstantPoolName = "java/lang/Byte".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangCharacterConstantPoolName = "java/lang/Character".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassConstantPoolName = "java/lang/Class".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassSignature = "Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangReflectConstructorConstantPoolName = "java/lang/reflect/Constructor".toCharArray();   //$NON-NLS-1$
+	public static final char[] JavaLangReflectConstructorNewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTFIELD_CONSTANTPOOLNAME = "java/lang/reflect/Field".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME = "java/lang/reflect/Method".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangShortConstantPoolName = "java/lang/Short".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringBuilderConstantPoolName = "java/lang/StringBuilder".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringConstantPoolName = "java/lang/String".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringSignature = "Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangSystemConstantPoolName = "java/lang/System".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangVoidConstantPoolName = "java/lang/Void".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaUtilIteratorConstantPoolName = "java/util/Iterator".toCharArray(); //$NON-NLS-1$
+	public static final char[] LongConstrSignature = "(J)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] longLongSignature = "(J)Ljava/lang/Long;".toCharArray(); //$NON-NLS-1$
+	public static final char[] LONGVALUE_LONG_METHOD_NAME = "longValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] LONGVALUE_LONG_METHOD_SIGNATURE = "()J".toCharArray(); //$NON-NLS-1$
+	public static final char[] NewInstance = "newInstance".toCharArray(); //$NON-NLS-1$
+	public static final char[] NewInstanceSignature = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Next = "next".toCharArray();//$NON-NLS-1$
+	public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray();//$NON-NLS-1$
+	public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Ordinal = "ordinal".toCharArray(); //$NON-NLS-1$
+	public static final char[] OrdinalSignature = "()I".toCharArray(); //$NON-NLS-1$
+	public static final char[] Out = "out".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BOOLEAN_METHOD_NAME = "setBoolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BYTE_METHOD_NAME = "setByte".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;B)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_CHAR_METHOD_NAME = "setChar".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;C)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_DOUBLE_METHOD_NAME = "setDouble".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;D)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_FLOAT_METHOD_NAME = "setFloat".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;F)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_INT_METHOD_NAME = "setInt".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_LONG_METHOD_NAME = "setLong".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;J)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_OBJECT_METHOD_NAME = "set".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_SHORT_METHOD_NAME = "setShort".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;S)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SETACCESSIBLE_NAME = "setAccessible".toCharArray(); //$NON-NLS-1$
+	public static final char[] SETACCESSIBLE_SIGNATURE = "(Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ShortConstrSignature = "(S)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] shortShortSignature = "(S)Ljava/lang/Short;".toCharArray(); //$NON-NLS-1$
+	public static final char[] SHORTVALUE_SHORT_METHOD_NAME = "shortValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] SHORTVALUE_SHORT_METHOD_SIGNATURE = "()S".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendCharSignature = "(C)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendDoubleSignature = "(D)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendFloatSignature = "(F)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendIntSignature = "(I)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendLongSignature = "(J)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendBooleanSignature = "(Z)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendCharSignature = "(C)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendDoubleSignature = "(D)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendFloatSignature = "(F)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendIntSignature = "(I)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendLongSignature = "(J)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] This = "this".toCharArray(); //$NON-NLS-1$
+	public static final char[] ToString = "toString".toCharArray(); //$NON-NLS-1$
+	public static final char[] ToStringSignature = GetMessageSignature;
+	public static final char[] TYPE = "TYPE".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOf = "valueOf".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfCharSignature = "(C)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfFloatSignature = "(F)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfIntSignature = "(I)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfLongSignature = "(J)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfStringClassSignature = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_DOCUMENTED = "Ljava/lang/annotation/Documented;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = "Ljava/lang/annotation/ElementType;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_RETENTION = "Ljava/lang/annotation/Retention;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = "Ljava/lang/annotation/RetentionPolicy;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_TARGET = "Ljava/lang/annotation/Target;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_DEPRECATED = "Ljava/lang/Deprecated;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_INHERITED = "Ljava/lang/annotation/Inherited;".toCharArray(); //$NON-NLS-1$
+	// java 7  java.lang.SafeVarargs
+	public static final char[] JAVA_LANG_SAFEVARARGS = "Ljava/lang/SafeVarargs;".toCharArray(); //$NON-NLS-1$
+	// java 7 java.lang.invoke.MethodHandle.invokeExact(..)/invokeGeneric(..)
+	public static final char[] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = "Ljava/lang/invoke/MethodHandle$PolymorphicSignature;".toCharArray(); //$NON-NLS-1$
+	// Java 8 lambda support
+	public static final char[] METAFACTORY = "metaFactory".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;".toCharArray(); //$NON-NLS-1$
+
+	public static final char[] HashCode = "hashCode".toCharArray(); //$NON-NLS-1$
+	public static final char[] HashCodeSignature = "()I".toCharArray(); //$NON-NLS-1$; 
+	public static final char[] Equals = "equals".toCharArray(); //$NON-NLS-1$
+	public static final char[] EqualsSignature = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$; 
+	public static final char[] AddSuppressed = "addSuppressed".toCharArray(); //$NON-NLS-1$;
+	public static final char[] AddSuppressedSignature = "(Ljava/lang/Throwable;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] Clone = "clone".toCharArray(); //$NON-NLS-1$
+	public static final char[] CloneSignature = "()Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	
+	/**
+	 * ConstantPool constructor comment.
+	 */
+	public ConstantPool(ClassFile classFile) {
+		this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE);
+		this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE);
+		this.methodsAndFieldsCache = new HashtableOfObject(METHODS_AND_FIELDS_INITIAL_SIZE);
+		this.classCache = new CharArrayCache(CLASS_INITIAL_SIZE);
+		this.nameAndTypeCacheForFieldsAndMethods = new HashtableOfObject(NAMEANDTYPE_INITIAL_SIZE);
+		this.offsets = new int[5];
+		initialize(classFile);
+	}
+	public void initialize(ClassFile givenClassFile) {
+		this.poolContent = givenClassFile.header;
+		this.currentOffset = givenClassFile.headerOffset;
+		// currentOffset is initialized to 0 by default
+		this.currentIndex = 1;
+		this.classFile = givenClassFile;
+	}
+	/**
+	 * Return the content of the receiver
+	 */
+	public byte[] dumpBytes() {
+		System.arraycopy(this.poolContent, 0, (this.poolContent = new byte[this.currentOffset]), 0, this.currentOffset);
+		return this.poolContent;
+	}
+	public int literalIndex(byte[] utf8encoding, char[] stringCharArray) {
+		int index;
+		if ((index = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(Utf8Tag);
+			int utf8encodingLength = utf8encoding.length;
+			if (this.currentOffset + 2 + utf8encodingLength >= this.poolContent.length) {
+				// we need to resize the poolContent array because we won't have
+				// enough space to write the length
+				resizePoolContents(2 + utf8encodingLength);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (utf8encodingLength >> 8);
+			this.poolContent[this.currentOffset++] = (byte) utf8encodingLength;
+			// add in once the whole byte array
+			System.arraycopy(utf8encoding, 0, this.poolContent, this.currentOffset, utf8encodingLength);
+			this.currentOffset += utf8encodingLength;
+		}
+		return index;
+	}
+	public int literalIndex(TypeBinding binding) {
+		TypeBinding typeBinding = binding.leafComponentType();
+		if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, typeBinding);
+		}
+		return literalIndex(binding.signature());
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param utf8Constant char[]
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(char[] utf8Constant) {
+		int index;
+		if ((index = this.UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// The entry doesn't exit yet
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(Utf8Tag);
+			// Then the size of the stringName array
+			int savedCurrentOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				// we need to resize the poolContent array because we won't have
+				// enough space to write the length
+				resizePoolContents(2);
+			}
+			this.currentOffset += 2;
+			length = 0;
+			for (int i = 0; i < utf8Constant.length; i++) {
+				char current = utf8Constant[i];
+				if ((current >= 0x0001) && (current <= 0x007F)) {
+					// we only need one byte: ASCII table
+					writeU1(current);
+					length++;
+				} else {
+					if (current > 0x07FF) {
+						// we need 3 bytes
+						length += 3;
+						writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+						writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					} else {
+						// we can be 0 or between 0x0080 and 0x07FF
+						// In that case we only need 2 bytes
+						length += 2;
+						writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					}
+				}
+			}
+			if (length >= 65535) {
+				this.currentOffset = savedCurrentOffset - 1;
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType());
+			}
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Now we know the length that we have to write in the constant pool
+			// we use savedCurrentOffset to do that
+			this.poolContent[savedCurrentOffset] = (byte) (length >> 8);
+			this.poolContent[savedCurrentOffset + 1] = (byte) length;
+		}
+		return index;
+	}
+	public int literalIndex(char[] stringCharArray, byte[] utf8encoding) {
+		int index;
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+
+			final int stringIndex = literalIndex(utf8encoding, stringCharArray);
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the double
+	 * value. If the double is not already present into the pool, it is added. The
+	 * double cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>double</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(double key) {
+		//Retrieve the index from the cache
+		// The double constant takes two indexes into the constant pool, but we only store
+		// the first index into the long table
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.doubleCache == null) {
+			this.doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE);
+		}
+		if ((index = this.doubleCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex += 2; // a double needs an extra place into the constant pool
+			// Write the double into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(DoubleTag);
+			// Then add the 8 bytes representing the double
+			long temp = java.lang.Double.doubleToLongBits(key);
+			length = this.poolContent.length;
+			if (this.currentOffset + 8 >= length) {
+				resizePoolContents(8);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 56);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 48);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 40);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 32);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) temp;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the float
+	 * value. If the float is not already present into the pool, it is added. The
+	 * int cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>float</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(float key) {
+		//Retrieve the index from the cache
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.floatCache == null) {
+			this.floatCache = new FloatCache(FLOAT_INITIAL_SIZE);
+		}
+		if ((index = this.floatCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Write the float constant entry into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(FloatTag);
+			// Then add the 4 bytes representing the float
+			int temp = java.lang.Float.floatToIntBits(key);
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) temp;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the int
+	 * value. If the int is not already present into the pool, it is added. The
+	 * int cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>int</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(int key) {
+		//Retrieve the index from the cache
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.intCache == null) {
+			this.intCache = new IntegerCache(INT_INITIAL_SIZE);
+		}
+		if ((index = this.intCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the integer constant entry into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(IntegerTag);
+			// Then add the 4 bytes representing the int
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) key;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the long
+	 * value. If the long is not already present into the pool, it is added. The
+	 * long cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>long</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(long key) {
+		// Retrieve the index from the cache
+		// The long constant takes two indexes into the constant pool, but we only store
+		// the first index into the long table
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.longCache == null) {
+			this.longCache = new LongCache(LONG_INITIAL_SIZE);
+		}
+		if ((index = this.longCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex+= 2; // long value need an extra place into thwe constant pool
+			// Write the long into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(LongTag);
+			// Then add the 8 bytes representing the long
+			if (this.currentOffset + 8 >= this.poolContent.length) {
+				resizePoolContents(8);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 56);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 48);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 40);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 32);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) key;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param stringConstant java.lang.String
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(String stringConstant) {
+		int index;
+		char[] stringCharArray = stringConstant.toCharArray();
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index  = -index)> 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+			final int stringIndex = literalIndex(stringCharArray);
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	public int literalIndexForType(final char[] constantPoolName) {
+		int index;
+		if ((index = this.classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(ClassTag);
+
+			// Then the name index
+			int nameIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+			final int nameIndex = literalIndex(constantPoolName);
+			this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
+			this.poolContent[nameIndexOffset] = (byte) nameIndex;
+		}
+		return index;
+	}
+	/*
+	 * This method returns the index into the constantPool corresponding to the type descriptor
+	 * corresponding to a type constant pool name
+	 * binding must not be an array type.
+	 */
+	public int literalIndexForType(final TypeBinding binding) {
+		TypeBinding typeBinding = binding.leafComponentType();
+		if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, typeBinding);
+		}
+		return this.literalIndexForType(binding.constantPoolName());
+	}
+	public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) {
+		int index;
+		if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) {
+			// it doesn't exist yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the interface method ref constant into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag);
+
+			int classIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int classIndex = literalIndexForType(declaringClass);
+			final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature);
+
+			this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
+			this.poolContent[classIndexOffset++] = (byte) classIndex;
+			this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
+			this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
+		}
+		return index;
+	}
+	public int literalIndexForMethod(TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) {
+		if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, declaringClass);
+		}
+		return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface);
+	}
+	public int literalIndexForNameAndType(char[] name, char[] signature) {
+		int index;
+		if ((index = putInNameAndTypeCacheIfAbsent(name, signature, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(NameAndTypeTag);
+			int nameIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int nameIndex = literalIndex(name);
+			final int typeIndex = literalIndex(signature);
+			this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
+			this.poolContent[nameIndexOffset++] = (byte) nameIndex;
+			this.poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8);
+			this.poolContent[nameIndexOffset] = (byte) typeIndex;
+		}
+		return index;
+	}
+	public int literalIndexForMethodHandle(MethodBinding binding) {
+		boolean isInterface = binding.declaringClass.isInterface();
+		int referenceKind =
+			isInterface ? MethodHandleRefKindInvokeInterface
+			: binding.isConstructor() ? MethodHandleRefKindNewInvokeSpecial
+			: binding.isStatic() ? MethodHandleRefKindInvokeStatic
+			: MethodHandleRefKindInvokeVirtual;
+		
+		return literalIndexForMethodHandle(referenceKind, binding.declaringClass, binding.selector, binding.signature(), isInterface);
+	}
+	
+	public int literalIndexForMethodHandle(int referenceKind, TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) {
+		int indexForMethod = literalIndexForMethod(declaringClass, selector, signature, isInterface);
+
+		int index = this.currentIndex++;
+		int length = this.offsets.length;
+		if (length <= index) {
+			// resize
+			System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+		}
+		
+		this.offsets[index] = this.currentOffset;
+		writeU1(MethodHandleTag);
+		writeU1(referenceKind);
+		writeU2(indexForMethod);
+
+		return index;
+	}
+	public int literalIndexForMethodType(char[] descriptor) {
+		int signatureIndex = literalIndex(descriptor);
+
+		int index = this.currentIndex++;
+		
+		int length = this.offsets.length;
+		if (length <= index) {
+			// resize
+			System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+		}
+		this.offsets[index] = this.currentOffset;
+		writeU1(MethodTypeTag);
+		writeU2(signatureIndex);
+
+		return index;
+	}
+	public int literalIndexForInvokeDynamic(int bootStrapIndex, char[] selector, char[] descriptor) {
+		int nameAndTypeIndex = literalIndexForNameAndType(selector, descriptor);
+		int index = this.currentIndex++;
+		int length = this.offsets.length;
+		if (length <= index) {
+			// resize
+			System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+		}
+		this.offsets[index] = this.currentOffset;
+		writeU1(InvokeDynamicTag);
+		writeU2(bootStrapIndex);
+		writeU2(nameAndTypeIndex);
+		return index;
+	}
+	public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) {
+		int index;
+		if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) {
+			this.currentIndex++;
+			// doesn't exist yet
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the interface method ref constant into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(FieldRefTag);
+			int classIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int classIndex = literalIndexForType(declaringClass);
+			final int nameAndTypeIndex = literalIndexForNameAndType(name, signature);
+
+			this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
+			this.poolContent[classIndexOffset++] = (byte) classIndex;
+			this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
+			this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param stringCharArray char[]
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndexForLdc(char[] stringCharArray) {
+		int savedCurrentIndex = this.currentIndex;
+		int savedCurrentOffset = this.currentOffset;
+		int index;
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+
+			int stringIndex;
+			if ((stringIndex = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+				if ((stringIndex = -stringIndex)> 0xFFFF) {
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// The entry doesn't exit yet
+				this.currentIndex++;
+				// Write the tag first
+				length = this.offsets.length;
+				if (length <= stringIndex) {
+					// resize
+					System.arraycopy(this.offsets, 0, (this.offsets = new int[stringIndex * 2]), 0, length);
+				}
+				this.offsets[stringIndex] = this.currentOffset;
+				writeU1(Utf8Tag);
+				// Then the size of the stringName array
+				int lengthOffset = this.currentOffset;
+				if (this.currentOffset + 2 >= this.poolContent.length) {
+					// we need to resize the poolContent array because we won't have
+					// enough space to write the length
+					resizePoolContents(2);
+				}
+				this.currentOffset += 2;
+				length = 0;
+				for (int i = 0; i < stringCharArray.length; i++) {
+					char current = stringCharArray[i];
+					if ((current >= 0x0001) && (current <= 0x007F)) {
+						// we only need one byte: ASCII table
+						length++;
+						if (this.currentOffset + 1 >= this.poolContent.length) {
+							// we need to resize the poolContent array because we won't have
+							// enough space to write the length
+							resizePoolContents(1);
+						}
+						this.poolContent[this.currentOffset++] = (byte)(current);
+					} else
+						if (current > 0x07FF) {
+							// we need 3 bytes
+							length += 3;
+							if (this.currentOffset + 3 >= this.poolContent.length) {
+								// we need to resize the poolContent array because we won't have
+								// enough space to write the length
+								resizePoolContents(3);
+							}
+							this.poolContent[this.currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+						} else {
+							if (this.currentOffset + 2 >= this.poolContent.length) {
+								// we need to resize the poolContent array because we won't have
+								// enough space to write the length
+								resizePoolContents(2);
+							}
+							// we can be 0 or between 0x0080 and 0x07FF
+							// In that case we only need 2 bytes
+							length += 2;
+							this.poolContent[this.currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+						}
+				}
+				if (length >= 65535) {
+					this.currentOffset = savedCurrentOffset;
+					this.currentIndex = savedCurrentIndex;
+					this.stringCache.remove(stringCharArray);
+					this.UTF8Cache.remove(stringCharArray);
+					return 0;
+				}
+				this.poolContent[lengthOffset++] = (byte) (length >> 8);
+				this.poolContent[lengthOffset] = (byte) length;
+			}
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	/**
+	 * @param key1 the given name
+	 * @param key2 the given signature
+	 * @param value the given index
+	 * @return the new index
+	 */
+	private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) {
+		int index ;
+		Object key1Value = this.nameAndTypeCacheForFieldsAndMethods.get(key1);
+		if (key1Value == null) {
+			CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key2, value);
+			index = -value;
+			this.nameAndTypeCacheForFieldsAndMethods.put(key1, cachedIndexEntry);
+		} else if (key1Value instanceof CachedIndexEntry) {
+			// adding a second entry
+			CachedIndexEntry entry = (CachedIndexEntry) key1Value;
+			if (CharOperation.equals(key2, entry.signature)) {
+				index = entry.index;
+			} else {
+				CharArrayCache charArrayCache = new CharArrayCache();
+				charArrayCache.putIfAbsent(entry.signature, entry.index);
+				index = charArrayCache.putIfAbsent(key2, value);
+				this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache);
+			}
+		} else {
+			CharArrayCache charArrayCache = (CharArrayCache) key1Value;
+			index = charArrayCache.putIfAbsent(key2, value);
+		}
+		return index;
+	}
+	/**
+	 * @param key1 the given declaring class name
+	 * @param key2 the given field name or method selector
+	 * @param key3 the given signature
+	 * @param value the new index
+	 * @return the given index
+	 */
+	private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) {
+		int index;
+		HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1);
+		if (key1Value == null) {
+			key1Value = new HashtableOfObject();
+			this.methodsAndFieldsCache.put(key1, key1Value);
+			CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
+			index = -value;
+			key1Value.put(key2, cachedIndexEntry);
+		} else {
+			Object key2Value = key1Value.get(key2);
+			if (key2Value == null) {
+				CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
+				index = -value;
+				key1Value.put(key2, cachedIndexEntry);
+			} else if (key2Value instanceof CachedIndexEntry) {
+				// adding a second entry
+				CachedIndexEntry entry = (CachedIndexEntry) key2Value;
+				if (CharOperation.equals(key3, entry.signature)) {
+					index = entry.index;
+				} else {
+					CharArrayCache charArrayCache = new CharArrayCache();
+					charArrayCache.putIfAbsent(entry.signature, entry.index);
+					index = charArrayCache.putIfAbsent(key3, value);
+					key1Value.put(key2, charArrayCache);
+				}
+			} else {
+				CharArrayCache charArrayCache = (CharArrayCache) key2Value;
+				index = charArrayCache.putIfAbsent(key3, value);
+			}
+		}
+		return index;
+	}
+	/**
+	 * This method is used to clean the receiver in case of a clinit header is generated, but the
+	 * clinit has no code.
+	 * This implementation assumes that the clinit is the first method to be generated.
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration#addClinit()
+	 */
+	public void resetForClinit(int constantPoolIndex, int constantPoolOffset) {
+		this.currentIndex = constantPoolIndex;
+		this.currentOffset = constantPoolOffset;
+		if (this.UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) {
+			this.UTF8Cache.remove(AttributeNamesConstants.CodeName);
+		}
+		if (this.UTF8Cache.get(ConstantPool.ClinitSignature) >= constantPoolIndex) {
+			this.UTF8Cache.remove(ConstantPool.ClinitSignature);
+		}
+		if (this.UTF8Cache.get(ConstantPool.Clinit) >= constantPoolIndex) {
+			this.UTF8Cache.remove(ConstantPool.Clinit);
+		}
+	}
+
+	/**
+	 * Resize the pool contents
+	 */
+	private final void resizePoolContents(int minimalSize) {
+		int length = this.poolContent.length;
+		int toAdd = length;
+		if (toAdd < minimalSize)
+			toAdd = minimalSize;
+		System.arraycopy(this.poolContent, 0, this.poolContent = new byte[length + toAdd], 0, length);
+	}
+	/**
+	 * Write a unsigned byte into the byte array
+	 *
+	 * @param value <CODE>int</CODE> The value to write into the byte array
+	 */
+	protected final void writeU1(int value) {
+		if (this.currentOffset + 1 >= this.poolContent.length) {
+			resizePoolContents(1);
+		}
+		this.poolContent[this.currentOffset++] = (byte) value;
+	}
+	/**
+	 * Write a unsigned byte into the byte array
+	 *
+	 * @param value <CODE>int</CODE> The value to write into the byte array
+	 */
+	protected final void writeU2(int value) {
+		if (this.currentOffset + 2 >= this.poolContent.length) {
+			resizePoolContents(2);
+		}
+		this.poolContent[this.currentOffset++] = (byte) (value >>> 8);
+		this.poolContent[this.currentOffset++] = (byte) value;
+	}
+	public void reset() {
+		if (this.doubleCache != null) this.doubleCache.clear();
+		if (this.floatCache != null) this.floatCache.clear();
+		if (this.intCache != null) this.intCache.clear();
+		if (this.longCache != null) this.longCache.clear();
+		this.UTF8Cache.clear();
+		this.stringCache.clear();
+		this.methodsAndFieldsCache.clear();
+		this.classCache.clear();
+		this.nameAndTypeCacheForFieldsAndMethods.clear();
+		this.currentIndex = 1;
+		this.currentOffset = 0;
+	}
+	public void resetForAttributeName(char[] attributeName, int constantPoolIndex, int constantPoolOffset) {
+		this.currentIndex = constantPoolIndex;
+		this.currentOffset = constantPoolOffset;
+		if (this.UTF8Cache.get(attributeName) >= constantPoolIndex) {
+			this.UTF8Cache.remove(attributeName);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
new file mode 100644
index 0000000..4002d85
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class DoubleCache {
+	private double keyTable[];
+	private int valueTable[];
+	private int elementSize;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically
+ * grow when it gets full.
+ */
+public DoubleCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public DoubleCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.keyTable = new double[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = 0.0;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>double</CODE> the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(double key) {
+	if (key == 0.0) {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == 0.0) {
+				long value1 = Double.doubleToLongBits(key);
+				long value2 = Double.doubleToLongBits(this.keyTable[i]);
+				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
+					return true;
+				if (value1 == 0 && value2 == 0)
+					return true;
+			}
+		}
+	} else {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == key) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>double</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(double key, int value) {
+	if (this.elementSize == this.keyTable.length) {
+		// resize
+		System.arraycopy(this.keyTable, 0, (this.keyTable = new double[this.elementSize * 2]), 0, this.elementSize);
+		System.arraycopy(this.valueTable, 0, (this.valueTable = new int[this.elementSize * 2]), 0, this.elementSize);
+	}
+	this.keyTable[this.elementSize] = key;
+	this.valueTable[this.elementSize] = value;
+	this.elementSize++;
+	return value;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>double</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int putIfAbsent(double key, int value) {
+	if (key == 0.0) {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == 0.0) {
+				long value1 = Double.doubleToLongBits(key);
+				long value2 = Double.doubleToLongBits(this.keyTable[i]);
+				if (value1 == -9223372036854775808L && value2 == -9223372036854775808L)
+					return this.valueTable[i];
+				if (value1 == 0 && value2 == 0)
+					return this.valueTable[i];
+			}
+		}
+	} else {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == key) {
+				return this.valueTable[i];
+			}
+		}
+	}
+	if (this.elementSize == this.keyTable.length) {
+		// resize
+		System.arraycopy(this.keyTable, 0, (this.keyTable = new double[this.elementSize * 2]), 0, this.elementSize);
+		System.arraycopy(this.valueTable, 0, (this.valueTable = new int[this.elementSize * 2]), 0, this.elementSize);
+	}
+	this.keyTable[this.elementSize] = key;
+	this.valueTable[this.elementSize] = value;
+	this.elementSize++;
+	return -value; // negative when added, assumes value is > 0
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * @return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = this.elementSize;
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if ((this.keyTable[i] != 0) || ((this.keyTable[i] == 0) &&(this.valueTable[i] != 0))) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
new file mode 100644
index 0000000..e6e619d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class ExceptionLabel extends Label {
+
+	public int ranges[] = {POS_NOT_SET,POS_NOT_SET};
+	private int count = 0; // incremented each time placeStart or placeEnd is called
+	public TypeBinding exceptionType;
+	public TypeReference exceptionTypeReference;
+
+public ExceptionLabel(CodeStream codeStream, TypeBinding exceptionType, TypeReference exceptionTypeReference) {
+	super(codeStream);
+	this.exceptionType = exceptionType;
+	this.exceptionTypeReference = exceptionTypeReference;
+}
+
+public ExceptionLabel(CodeStream codeStream, TypeBinding exceptionType) {
+	super(codeStream);
+	this.exceptionType = exceptionType;
+}
+public int getCount() {
+	return this.count;
+}
+public void place() {
+	// register the handler inside the codeStream then normal place
+	this.codeStream.registerExceptionHandler(this);
+	this.position = this.codeStream.getPosition();
+}
+
+public void placeEnd() {
+	int endPosition = this.codeStream.position;
+	if (this.ranges[this.count-1] == endPosition) { // start == end ?
+		// discard empty exception handler
+		this.count--;
+	} else {
+		this.ranges[this.count++] = endPosition;
+	}
+}
+
+public void placeStart() {
+	int startPosition = this.codeStream.position;
+	if (this.count > 0 && this.ranges[this.count-1] == startPosition) { // start == previous end ?
+		// reopen current handler
+		this.count--;
+		return;
+	}
+	// only need to grow on even additions (i.e. placeStart only)
+	int length;
+	if (this.count == (length = this.ranges.length)) {
+		System.arraycopy(this.ranges, 0, this.ranges = new int[length*2], 0, length);
+	}
+	this.ranges[this.count++] = startPosition;
+}
+public String toString() {
+	String basic = getClass().getName();
+	basic = basic.substring(basic.lastIndexOf('.')+1);
+	StringBuffer buffer = new StringBuffer(basic);
+	buffer.append('@').append(Integer.toHexString(hashCode()));
+	buffer.append("(type=").append(this.exceptionType == null ? CharOperation.NO_CHAR : this.exceptionType.readableName()); //$NON-NLS-1$
+	buffer.append(", position=").append(this.position); //$NON-NLS-1$
+	buffer.append(", ranges = "); //$NON-NLS-1$
+	if (this.count == 0) {
+		buffer.append("[]"); //$NON-NLS-1$
+	} else {
+		for (int i = 0; i < this.count; i++) {
+			if ((i & 1) == 0) {
+				buffer.append("[").append(this.ranges[i]); //$NON-NLS-1$
+			} else {
+				buffer.append(",").append(this.ranges[i]).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		if ((this.count & 1) == 1) {
+			buffer.append(",?]"); //$NON-NLS-1$
+		}
+	}
+	buffer.append(')');
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
new file mode 100644
index 0000000..e95b2d9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class FloatCache {
+	private float keyTable[];
+	private int valueTable[];
+	private int elementSize;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically
+ * grow when it gets full.
+ */
+public FloatCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public FloatCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.keyTable = new float[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = 0.0f;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>float</CODE> the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(float key) {
+	if (key == 0.0f) {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == 0.0f) {
+				int value1 = Float.floatToIntBits(key);
+				int value2 = Float.floatToIntBits(this.keyTable[i]);
+				if (value1 == -2147483648 && value2 == -2147483648)
+					return true;
+				if (value1 == 0 && value2 == 0)
+					return true;
+			}
+		}
+	} else {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == key) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>float</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(float key, int value) {
+	if (this.elementSize == this.keyTable.length) {
+		// resize
+		System.arraycopy(this.keyTable, 0, (this.keyTable = new float[this.elementSize * 2]), 0, this.elementSize);
+		System.arraycopy(this.valueTable, 0, (this.valueTable = new int[this.elementSize * 2]), 0, this.elementSize);
+	}
+	this.keyTable[this.elementSize] = key;
+	this.valueTable[this.elementSize] = value;
+	this.elementSize++;
+	return value;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>float</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int putIfAbsent(float key, int value) {
+	if (key == 0.0f) {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == 0.0f) {
+				int value1 = Float.floatToIntBits(key);
+				int value2 = Float.floatToIntBits(this.keyTable[i]);
+				if (value1 == -2147483648 && value2 == -2147483648)
+					return this.valueTable[i];
+				if (value1 == 0 && value2 == 0)
+					return this.valueTable[i];
+			}
+		}
+	} else {
+		for (int i = 0, max = this.elementSize; i < max; i++) {
+			if (this.keyTable[i] == key) {
+				return this.valueTable[i];
+			}
+		}
+	}
+	if (this.elementSize == this.keyTable.length) {
+		// resize
+		System.arraycopy(this.keyTable, 0, (this.keyTable = new float[this.elementSize * 2]), 0, this.elementSize);
+		System.arraycopy(this.valueTable, 0, (this.valueTable = new int[this.elementSize * 2]), 0, this.elementSize);
+	}
+	this.keyTable[this.elementSize] = key;
+	this.valueTable[this.elementSize] = value;
+	this.elementSize++;
+	return -value; // negative when added, assumes value is > 0
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * @return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = this.elementSize;
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if ((this.keyTable[i] != 0) || ((this.keyTable[i] == 0) && (this.valueTable[i] != 0))) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
new file mode 100644
index 0000000..6b24f6f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class IntegerCache {
+	public int keyTable[];
+	public int valueTable[];
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically
+ * grow when it gets full.
+ */
+public IntegerCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public IntegerCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.threshold = (int) (initialCapacity * 0.66);
+	this.keyTable = new int[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = 0;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>double</CODE> the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(int key) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) &&(this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+/**
+ * Return a hashcode for the value of the key parameter.
+ * @param key int
+ * @return int the hash code corresponding to the key value
+ */
+public int hash(int key) {
+	return (key & 0x7FFFFFFF) % this.keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>int</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(int key, int value) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) && (this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) {
+		rehash();
+	}
+	return value;
+}
+/**
+ * Puts the specified element into the hashtable if absent, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>int</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int putIfAbsent(int key, int value) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) && (this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) {
+		rehash();
+	}
+	return -value; // negative when added, assumes value is > 0
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	IntegerCache newHashtable = new IntegerCache(this.keyTable.length * 2);
+	for (int i = this.keyTable.length; --i >= 0;) {
+		int key = this.keyTable[i];
+		int value = this.valueTable[i];
+		if ((key != 0) || ((key == 0) && (value != 0))) {
+			newHashtable.put(key, value);
+		}
+	}
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return this.elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * @return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if ((this.keyTable[i] != 0) || ((this.keyTable[i] == 0) && (this.valueTable[i] != 0))) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java
new file mode 100644
index 0000000..c8643bc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public abstract class Label {
+
+	public CodeStream codeStream;
+	public int position = POS_NOT_SET; // position=POS_NOT_SET Then it's pos is not set.
+
+	public final static int POS_NOT_SET = -1;
+
+public Label() {
+	// for creating labels ahead of code generation
+}
+
+public Label(CodeStream codeStream) {
+	this.codeStream = codeStream;
+}
+
+/*
+* Place the label target position.
+*/
+public abstract void place();
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
new file mode 100644
index 0000000..bd476eb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class LongCache {
+	public long keyTable[];
+	public int valueTable[];
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity and
+ * load factor is used. Note that the hashtable will automatically
+ * grow when it gets full.
+ */
+public LongCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public LongCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.threshold = (int) (initialCapacity * 0.66);
+	this.keyTable = new long[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = 0;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key <CODE>long</CODE> the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(long key) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) &&(this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+/**
+ * Return a hashcode for the value of the key parameter.
+ * @param key long
+ * @return int the hash code corresponding to the key value
+ */
+public int hash(long key) {
+	return ((int) key & 0x7FFFFFFF) % this.keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>long</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int put(long key, int value) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) && (this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) {
+		rehash();
+	}
+	return value;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ *
+ * @param key <CODE>long</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int value
+ */
+public int putIfAbsent(long key, int value) {
+	int index = hash(key), length = this.keyTable.length;
+	while ((this.keyTable[index] != 0) || ((this.keyTable[index] == 0) && (this.valueTable[index] != 0))) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) {
+		rehash();
+	}
+	return -value; // negative when added, assumes value is > 0
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	LongCache newHashtable = new LongCache(this.keyTable.length * 2);
+	for (int i = this.keyTable.length; --i >= 0;) {
+		long key = this.keyTable[i];
+		int value = this.valueTable[i];
+		if ((key != 0) || ((key == 0) && (value != 0))) {
+			newHashtable.put(key, value);
+		}
+	}
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return this.elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * @return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if ((this.keyTable[i] != 0) || ((this.keyTable[i] == 0) && (this.valueTable[i] != 0))) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
new file mode 100644
index 0000000..21fc79f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class MultiCatchExceptionLabel extends ExceptionLabel {
+
+	ExceptionLabel[] exceptionLabels;
+
+	public MultiCatchExceptionLabel(CodeStream codeStream, TypeBinding exceptionType) {
+		super(codeStream, exceptionType);
+	}
+	
+	public void initialize(UnionTypeReference typeReference) {
+		TypeReference[] typeReferences = typeReference.typeReferences;
+		int length = typeReferences.length;
+		this.exceptionLabels = new ExceptionLabel[length];
+		for (int i = 0; i < length; i++) {
+			this.exceptionLabels[i] = new ExceptionLabel(this.codeStream, typeReferences[i].resolvedType, typeReferences[i]);
+		}
+	}
+	public void place() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].place();
+		}
+	}
+	public void placeEnd() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].placeEnd();
+		}
+	}
+	public void placeStart() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].placeStart();
+		}
+	}
+	public int getCount() {
+		int temp = 0;
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			temp += this.exceptionLabels[i].getCount();
+		}
+		return temp;
+	}
+
+	public int getAllAnnotationContexts(int tableIndex, List allTypeAnnotationContexts) {
+		int localCount = 0;
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			ExceptionLabel exceptionLabel = this.exceptionLabels[i];
+			if (exceptionLabel.exceptionTypeReference != null) { // ignore those which cannot be annotated
+				exceptionLabel.exceptionTypeReference.getAllAnnotationContexts(AnnotationTargetTypeConstants.EXCEPTION_PARAMETER, tableIndex + localCount, allTypeAnnotationContexts);
+			}
+			tableIndex++;
+		}
+		return localCount;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
new file mode 100644
index 0000000..0c18f67
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public class ObjectCache {
+	public Object keyTable[];
+	public int valueTable[];
+	int elementSize;
+	int threshold;
+/**
+ * Constructs a new, empty hashtable. A default capacity is used.
+ * Note that the hashtable will automatically grow when it gets full.
+ */
+public ObjectCache() {
+	this(13);
+}
+/**
+ * Constructs a new, empty hashtable with the specified initial
+ * capacity.
+ * @param initialCapacity int
+ *  the initial number of buckets
+ */
+public ObjectCache(int initialCapacity) {
+	this.elementSize = 0;
+	this.threshold = (int) (initialCapacity * 0.66f);
+	this.keyTable = new Object[initialCapacity];
+	this.valueTable = new int[initialCapacity];
+}
+/**
+ * Clears the hash table so that it has no more elements in it.
+ */
+public void clear() {
+	for (int i = this.keyTable.length; --i >= 0;) {
+		this.keyTable[i] = null;
+		this.valueTable[i] = 0;
+	}
+	this.elementSize = 0;
+}
+/** Returns true if the collection contains an element for the key.
+ *
+ * @param key char[] the key that we are looking for
+ * @return boolean
+ */
+public boolean containsKey(Object key) {
+	int index = hashCode(key), length = this.keyTable.length;
+	while (this.keyTable[index] != null) {
+		if (this.keyTable[index] == key)
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+/** Gets the object associated with the specified key in the
+ * hashtable.
+ * @param key <CODE>char[]</CODE> the specified key
+ * @return int the element for the key or -1 if the key is not
+ *  defined in the hash table.
+ */
+public int get(Object key) {
+	int index = hashCode(key), length = this.keyTable.length;
+	while (this.keyTable[index] != null) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return -1;
+}
+/**
+ * Return the hashcode for the key parameter
+ *
+ * @param key org.eclipse.jdt.internal.compiler.lookup.MethodBinding
+ * @return int
+ */
+public int hashCode(Object key) {
+	return (key.hashCode() & 0x7FFFFFFF) % this.keyTable.length;
+}
+/**
+ * Puts the specified element into the hashtable, using the specified
+ * key.  The element may be retrieved by doing a get() with the same key.
+ * The key and the element cannot be null.
+ *
+ * @param key <CODE>Object</CODE> the specified key in the hashtable
+ * @param value <CODE>int</CODE> the specified element
+ * @return int the old value of the key, or -1 if it did not have one.
+ */
+public int put(Object key, int value) {
+	int index = hashCode(key), length = this.keyTable.length;
+	while (this.keyTable[index] != null) {
+		if (this.keyTable[index] == key)
+			return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+/**
+ * Rehashes the content of the table into a bigger table.
+ * This method is called automatically when the hashtable's
+ * size exceeds the threshold.
+ */
+private void rehash() {
+	ObjectCache newHashtable = new ObjectCache(this.keyTable.length * 2);
+	for (int i = this.keyTable.length; --i >= 0;)
+		if (this.keyTable[i] != null)
+			newHashtable.put(this.keyTable[i], this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+/**
+ * Returns the number of elements contained in the hashtable.
+ *
+ * @return <CODE>int</CODE> The size of the table
+ */
+public int size() {
+	return this.elementSize;
+}
+/**
+ * Converts to a rather lengthy String.
+ *
+ * @return String the ascii representation of the receiver
+ */
+public String toString() {
+	int max = size();
+	StringBuffer buf = new StringBuffer();
+	buf.append("{"); //$NON-NLS-1$
+	for (int i = 0; i < max; ++i) {
+		if (this.keyTable[i] != null) {
+			buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
+		}
+		if (i < max) {
+			buf.append(", "); //$NON-NLS-1$
+		}
+	}
+	buf.append("}"); //$NON-NLS-1$
+	return buf.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
new file mode 100644
index 0000000..a177713
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     
+ *     Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335    
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+public interface Opcodes {
+
+	public static final byte OPC_nop = 0;
+	public static final byte OPC_aconst_null = 1;
+	public static final byte OPC_iconst_m1 = 2;
+	public static final byte OPC_iconst_0 = 3;
+	public static final byte OPC_iconst_1 = 4;
+	public static final byte OPC_iconst_2 = 5;
+	public static final byte OPC_iconst_3 = 6;
+	public static final byte OPC_iconst_4 = 7;
+	public static final byte OPC_iconst_5 = 8;
+	public static final byte OPC_lconst_0 = 9;
+	public static final byte OPC_lconst_1 = 10;
+	public static final byte OPC_fconst_0 = 11;
+	public static final byte OPC_fconst_1 = 12;
+	public static final byte OPC_fconst_2 = 13;
+	public static final byte OPC_dconst_0 = 14;
+	public static final byte OPC_dconst_1 = 15;
+	public static final byte OPC_bipush = 16;
+	public static final byte OPC_sipush = 17;
+	public static final byte OPC_ldc = 18;
+	public static final byte OPC_ldc_w = 19;
+	public static final byte OPC_ldc2_w = 20;
+	public static final byte OPC_iload = 21;
+	public static final byte OPC_lload = 22;
+	public static final byte OPC_fload = 23;
+	public static final byte OPC_dload = 24;
+	public static final byte OPC_aload = 25;
+	public static final byte OPC_iload_0 = 26;
+	public static final byte OPC_iload_1 = 27;
+	public static final byte OPC_iload_2 = 28;
+	public static final byte OPC_iload_3 = 29;
+	public static final byte OPC_lload_0 = 30;
+	public static final byte OPC_lload_1 = 31;
+	public static final byte OPC_lload_2 = 32;
+	public static final byte OPC_lload_3 = 33;
+	public static final byte OPC_fload_0 = 34;
+	public static final byte OPC_fload_1 = 35;
+	public static final byte OPC_fload_2 = 36;
+	public static final byte OPC_fload_3 = 37;
+	public static final byte OPC_dload_0 = 38;
+	public static final byte OPC_dload_1 = 39;
+	public static final byte OPC_dload_2 = 40;
+	public static final byte OPC_dload_3 = 41;
+	public static final byte OPC_aload_0 = 42;
+	public static final byte OPC_aload_1 = 43;
+	public static final byte OPC_aload_2 = 44;
+	public static final byte OPC_aload_3 = 45;
+	public static final byte OPC_iaload = 46;
+	public static final byte OPC_laload = 47;
+	public static final byte OPC_faload = 48;
+	public static final byte OPC_daload = 49;
+	public static final byte OPC_aaload = 50;
+	public static final byte OPC_baload = 51;
+	public static final byte OPC_caload = 52;
+	public static final byte OPC_saload = 53;
+	public static final byte OPC_istore = 54;
+	public static final byte OPC_lstore = 55;
+	public static final byte OPC_fstore = 56;
+	public static final byte OPC_dstore = 57;
+	public static final byte OPC_astore = 58;
+	public static final byte OPC_istore_0 = 59;
+	public static final byte OPC_istore_1 = 60;
+	public static final byte OPC_istore_2 = 61;
+	public static final byte OPC_istore_3 = 62;
+	public static final byte OPC_lstore_0 = 63;
+	public static final byte OPC_lstore_1 = 64;
+	public static final byte OPC_lstore_2 = 65;
+	public static final byte OPC_lstore_3 = 66;
+	public static final byte OPC_fstore_0 = 67;
+	public static final byte OPC_fstore_1 = 68;
+	public static final byte OPC_fstore_2 = 69;
+	public static final byte OPC_fstore_3 = 70;
+	public static final byte OPC_dstore_0 = 71;
+	public static final byte OPC_dstore_1 = 72;
+	public static final byte OPC_dstore_2 = 73;
+	public static final byte OPC_dstore_3 = 74;
+	public static final byte OPC_astore_0 = 75;
+	public static final byte OPC_astore_1 = 76;
+	public static final byte OPC_astore_2 = 77;
+	public static final byte OPC_astore_3 = 78;
+	public static final byte OPC_iastore = 79;
+	public static final byte OPC_lastore = 80;
+	public static final byte OPC_fastore = 81;
+	public static final byte OPC_dastore = 82;
+	public static final byte OPC_aastore = 83;
+	public static final byte OPC_bastore = 84;
+	public static final byte OPC_castore = 85;
+	public static final byte OPC_sastore = 86;
+	public static final byte OPC_pop = 87;
+	public static final byte OPC_pop2 = 88;
+	public static final byte OPC_dup = 89;
+	public static final byte OPC_dup_x1 = 90;
+	public static final byte OPC_dup_x2 = 91;
+	public static final byte OPC_dup2 = 92;
+	public static final byte OPC_dup2_x1 = 93;
+	public static final byte OPC_dup2_x2 = 94;
+	public static final byte OPC_swap = 95;
+	public static final byte OPC_iadd = 96;
+	public static final byte OPC_ladd = 97;
+	public static final byte OPC_fadd = 98;
+	public static final byte OPC_dadd = 99;
+	public static final byte OPC_isub = 100;
+	public static final byte OPC_lsub = 101;
+	public static final byte OPC_fsub = 102;
+	public static final byte OPC_dsub = 103;
+	public static final byte OPC_imul = 104;
+	public static final byte OPC_lmul = 105;
+	public static final byte OPC_fmul = 106;
+	public static final byte OPC_dmul = 107;
+	public static final byte OPC_idiv = 108;
+	public static final byte OPC_ldiv = 109;
+	public static final byte OPC_fdiv = 110;
+	public static final byte OPC_ddiv = 111;
+	public static final byte OPC_irem = 112;
+	public static final byte OPC_lrem = 113;
+	public static final byte OPC_frem = 114;
+	public static final byte OPC_drem = 115;
+	public static final byte OPC_ineg = 116;
+	public static final byte OPC_lneg = 117;
+	public static final byte OPC_fneg = 118;
+	public static final byte OPC_dneg = 119;
+	public static final byte OPC_ishl = 120;
+	public static final byte OPC_lshl = 121;
+	public static final byte OPC_ishr = 122;
+	public static final byte OPC_lshr = 123;
+	public static final byte OPC_iushr = 124;
+	public static final byte OPC_lushr = 125;
+	public static final byte OPC_iand = 126;
+	public static final byte OPC_land = 127;
+	public static final byte OPC_ior = (byte) 128;
+	public static final byte OPC_lor = (byte) 129;
+	public static final byte OPC_ixor = (byte) 130;
+	public static final byte OPC_lxor = (byte) 131;
+	public static final byte OPC_iinc = (byte) 132;
+	public static final byte OPC_i2l = (byte) 133;
+	public static final byte OPC_i2f = (byte) 134;
+	public static final byte OPC_i2d = (byte) 135;
+	public static final byte OPC_l2i = (byte) 136;
+	public static final byte OPC_l2f = (byte) 137;
+	public static final byte OPC_l2d = (byte) 138;
+	public static final byte OPC_f2i = (byte) 139;
+	public static final byte OPC_f2l = (byte) 140;
+	public static final byte OPC_f2d = (byte) 141;
+	public static final byte OPC_d2i = (byte) 142;
+	public static final byte OPC_d2l = (byte) 143;
+	public static final byte OPC_d2f = (byte) 144;
+	public static final byte OPC_i2b = (byte) 145;
+	public static final byte OPC_i2c = (byte) 146;
+	public static final byte OPC_i2s = (byte) 147;
+	public static final byte OPC_lcmp = (byte) 148;
+	public static final byte OPC_fcmpl = (byte) 149;
+	public static final byte OPC_fcmpg = (byte) 150;
+	public static final byte OPC_dcmpl = (byte) 151;
+	public static final byte OPC_dcmpg = (byte) 152;
+	public static final byte OPC_ifeq = (byte) 153;
+	public static final byte OPC_ifne = (byte) 154;
+	public static final byte OPC_iflt = (byte) 155;
+	public static final byte OPC_ifge = (byte) 156;
+	public static final byte OPC_ifgt = (byte) 157;
+	public static final byte OPC_ifle = (byte) 158;
+	public static final byte OPC_if_icmpeq = (byte) 159;
+	public static final byte OPC_if_icmpne = (byte) 160;
+	public static final byte OPC_if_icmplt = (byte) 161;
+	public static final byte OPC_if_icmpge = (byte) 162;
+	public static final byte OPC_if_icmpgt = (byte) 163;
+	public static final byte OPC_if_icmple = (byte) 164;
+	public static final byte OPC_if_acmpeq = (byte) 165;
+	public static final byte OPC_if_acmpne = (byte) 166;
+	public static final byte OPC_goto = (byte) 167;
+	public static final byte OPC_jsr = (byte) 168;
+	public static final byte OPC_ret = (byte) 169;
+	public static final byte OPC_tableswitch = (byte) 170;
+	public static final byte OPC_lookupswitch = (byte) 171;
+	public static final byte OPC_ireturn = (byte) 172;
+	public static final byte OPC_lreturn = (byte) 173;
+	public static final byte OPC_freturn = (byte) 174;
+	public static final byte OPC_dreturn = (byte) 175;
+	public static final byte OPC_areturn = (byte) 176;
+	public static final byte OPC_return = (byte) 177;
+	public static final byte OPC_getstatic = (byte) 178;
+	public static final byte OPC_putstatic = (byte) 179;
+	public static final byte OPC_getfield = (byte) 180;
+	public static final byte OPC_putfield = (byte) 181;
+	public static final byte OPC_invokevirtual = (byte) 182;
+	public static final byte OPC_invokespecial = (byte) 183;
+	public static final byte OPC_invokestatic = (byte) 184;
+	public static final byte OPC_invokeinterface = (byte) 185;
+	public static final byte OPC_invokedynamic = (byte) 186;
+	public static final byte OPC_new = (byte) 187;
+	public static final byte OPC_newarray = (byte) 188;
+	public static final byte OPC_anewarray = (byte) 189;
+	public static final byte OPC_arraylength = (byte) 190;
+	public static final byte OPC_athrow = (byte) 191;
+	public static final byte OPC_checkcast = (byte) 192;
+	public static final byte OPC_instanceof = (byte) 193;
+	public static final byte OPC_monitorenter = (byte) 194;
+	public static final byte OPC_monitorexit = (byte) 195;
+	public static final byte OPC_wide = (byte) 196;
+	public static final byte OPC_multianewarray = (byte) 197;
+	public static final byte OPC_ifnull = (byte) 198;
+	public static final byte OPC_ifnonnull = (byte) 199;
+	public static final byte OPC_goto_w = (byte) 200;
+	public static final byte OPC_jsr_w = (byte) 201;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
new file mode 100644
index 0000000..add0dcb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class StackMapFrame {
+	public static final int USED = 1;
+	public static final int SAME_FRAME = 0;
+	public static final int CHOP_FRAME = 1;
+	public static final int APPEND_FRAME = 2;
+	public static final int SAME_FRAME_EXTENDED = 3;
+	public static final int FULL_FRAME = 4;
+	public static final int SAME_LOCALS_1_STACK_ITEMS = 5;
+	public static final int SAME_LOCALS_1_STACK_ITEMS_EXTENDED = 6;
+
+	public int pc;
+	public int numberOfStackItems;
+	private int numberOfLocals;
+	public int localIndex;
+	public VerificationTypeInfo[] locals;
+	public VerificationTypeInfo[] stackItems;
+	private int numberOfDifferentLocals = -1;
+	public int tagBits;
+
+public StackMapFrame(int initialLocalSize) {
+	this.locals = new VerificationTypeInfo[initialLocalSize];
+	this.numberOfLocals = -1;
+	this.numberOfDifferentLocals = -1;
+}
+public int getFrameType(StackMapFrame prevFrame) {
+	final int offsetDelta = getOffsetDelta(prevFrame);
+	switch(this.numberOfStackItems) {
+		case 0 :
+			switch(numberOfDifferentLocals(prevFrame)) {
+				case 0 :
+					return offsetDelta <= 63 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+				case 1 :
+				case 2 :
+				case 3 :
+					return APPEND_FRAME;
+				case -1 :
+				case -2 :
+				case -3 :
+					return CHOP_FRAME;
+			}
+			break;
+		case 1 :
+			switch(numberOfDifferentLocals(prevFrame)) {
+				case 0 :
+					return offsetDelta <= 63 ? SAME_LOCALS_1_STACK_ITEMS : SAME_LOCALS_1_STACK_ITEMS_EXTENDED;
+			}
+	}
+	return FULL_FRAME;
+}
+public void addLocal(int resolvedPosition, VerificationTypeInfo info) {
+	if (this.locals == null) {
+		this.locals = new VerificationTypeInfo[resolvedPosition + 1];
+		this.locals[resolvedPosition] = info;
+	} else {
+		final int length = this.locals.length;
+		if (resolvedPosition >= length) {
+			System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0, length);
+		}
+		this.locals[resolvedPosition] = info;
+	}
+}
+public void addStackItem(VerificationTypeInfo info) {
+	if (info == null) {
+		throw new IllegalArgumentException("info cannot be null"); //$NON-NLS-1$
+	}
+	if (this.stackItems == null) {
+		this.stackItems = new VerificationTypeInfo[1];
+		this.stackItems[0] = info;
+		this.numberOfStackItems = 1;
+	} else {
+		final int length = this.stackItems.length;
+		if (this.numberOfStackItems == length) {
+			System.arraycopy(this.stackItems, 0, this.stackItems = new VerificationTypeInfo[length + 1], 0, length);
+		}
+		this.stackItems[this.numberOfStackItems++] = info;
+	}
+}
+public void addStackItem(TypeBinding binding) {
+	if (this.stackItems == null) {
+		this.stackItems = new VerificationTypeInfo[1];
+		this.stackItems[0] = new VerificationTypeInfo(binding);
+		this.numberOfStackItems = 1;
+	} else {
+		final int length = this.stackItems.length;
+		if (this.numberOfStackItems == length) {
+			System.arraycopy(this.stackItems, 0, this.stackItems = new VerificationTypeInfo[length + 1], 0, length);
+		}
+		this.stackItems[this.numberOfStackItems++] = new VerificationTypeInfo(binding);
+	}
+}
+public StackMapFrame duplicate() {
+	int length = this.locals.length;
+	StackMapFrame result = new StackMapFrame(length);
+	result.numberOfLocals = -1;
+	result.numberOfDifferentLocals = -1;
+	result.pc = this.pc;
+	result.numberOfStackItems = this.numberOfStackItems;
+
+	if (length != 0) {
+		result.locals = new VerificationTypeInfo[length];
+		for (int i = 0; i < length; i++) {
+			final VerificationTypeInfo verificationTypeInfo = this.locals[i];
+			if (verificationTypeInfo != null) {
+				result.locals[i] = verificationTypeInfo.duplicate();
+			}
+		}
+	}
+	length = this.numberOfStackItems;
+	if (length != 0) {
+		result.stackItems = new VerificationTypeInfo[length];
+		for (int i = 0; i < length; i++) {
+			result.stackItems[i] = this.stackItems[i].duplicate();
+		}
+	}
+	return result;
+}
+public int numberOfDifferentLocals(StackMapFrame prevFrame) {
+	if (this.numberOfDifferentLocals != -1) return this.numberOfDifferentLocals;
+	if (prevFrame == null) {
+		this.numberOfDifferentLocals = 0;
+		return 0;
+	}
+	VerificationTypeInfo[] prevLocals = prevFrame.locals;
+	VerificationTypeInfo[] currentLocals = this.locals;
+	int prevLocalsLength = prevLocals == null ? 0 : prevLocals.length;
+	int currentLocalsLength = currentLocals == null ? 0 : currentLocals.length;
+	int prevNumberOfLocals = prevFrame.getNumberOfLocals();
+	int currentNumberOfLocals = getNumberOfLocals();
+
+	int result = 0;
+	if (prevNumberOfLocals == 0) {
+		if (currentNumberOfLocals != 0) {
+			// need to check if there is a hole in the locals
+			result = currentNumberOfLocals; // append if no hole and currentNumberOfLocals <= 3
+			int counter = 0;
+			for(int i = 0; i < currentLocalsLength && counter < currentNumberOfLocals; i++) {
+				if (currentLocals[i] != null) {
+					switch(currentLocals[i].id()) {
+						case TypeIds.T_double :
+						case TypeIds.T_long :
+							i++;
+					}
+					counter++;
+				} else {
+					result = Integer.MAX_VALUE;
+					this.numberOfDifferentLocals = result;
+					return result;
+				}
+			}
+		}
+	} else if (currentNumberOfLocals == 0) {
+		// need to check if there is a hole in the prev locals
+		int counter = 0;
+		result = -prevNumberOfLocals; // chop frame if no hole and prevNumberOfLocals <= 3
+		for(int i = 0; i < prevLocalsLength && counter < prevNumberOfLocals; i++) {
+			if (prevLocals[i] != null) {
+				switch(prevLocals[i].id()) {
+					case TypeIds.T_double :
+					case TypeIds.T_long :
+						i++;
+				}
+				counter++;
+			} else {
+				result = Integer.MAX_VALUE;
+				this.numberOfDifferentLocals = result;
+				return result;
+			}
+		}
+	} else {
+		// need to see if prevLocals matches with currentLocals
+		int indexInPrevLocals = 0;
+		int indexInCurrentLocals = 0;
+		int currentLocalsCounter = 0;
+		int prevLocalsCounter = 0;
+		currentLocalsLoop: for (;indexInCurrentLocals < currentLocalsLength && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
+			VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
+			if (currentLocal != null) {
+				currentLocalsCounter++;
+				switch(currentLocal.id()) {
+					case TypeIds.T_double :
+					case TypeIds.T_long :
+						indexInCurrentLocals++; // next entry  is null
+				}
+			}
+			if (indexInPrevLocals < prevLocalsLength && prevLocalsCounter < prevNumberOfLocals) {
+				VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
+				if (prevLocal != null) {
+					prevLocalsCounter++;
+					switch(prevLocal.id()) {
+						case TypeIds.T_double :
+						case TypeIds.T_long :
+							indexInPrevLocals++; // next entry  is null
+					}
+				}
+				// now we need to check if prevLocal matches with currentLocal
+				// the index must be the same
+				if (equals(prevLocal, currentLocal) && indexInPrevLocals == indexInCurrentLocals) {
+					if (result != 0) {
+						result = Integer.MAX_VALUE;
+						this.numberOfDifferentLocals = result;
+						return result;
+					}
+				} else {
+					// locals at the same location are not equals - this has to be a full frame
+					result = Integer.MAX_VALUE;
+					this.numberOfDifferentLocals = result;
+					return result;
+				}
+				indexInPrevLocals++;
+				continue currentLocalsLoop;
+			}
+			// process remaining current locals
+			if (currentLocal != null) {
+				result++;
+			} else {
+				result = Integer.MAX_VALUE;
+				this.numberOfDifferentLocals = result;
+				return result;
+			}
+			indexInCurrentLocals++;
+			break currentLocalsLoop;
+		}
+		if (currentLocalsCounter < currentNumberOfLocals) {
+			for(;indexInCurrentLocals < currentLocalsLength && currentLocalsCounter < currentNumberOfLocals; indexInCurrentLocals++) {
+				VerificationTypeInfo currentLocal = currentLocals[indexInCurrentLocals];
+				if (currentLocal == null) {
+					result = Integer.MAX_VALUE;
+					this.numberOfDifferentLocals = result;
+					return result;
+				}
+				result++;
+				currentLocalsCounter++;
+				switch(currentLocal.id()) {
+					case TypeIds.T_double :
+					case TypeIds.T_long :
+						indexInCurrentLocals++; // next entry  is null
+				}
+			}
+		} else if (prevLocalsCounter < prevNumberOfLocals) {
+			result = -result;
+			// process possible remaining prev locals
+			for(; indexInPrevLocals < prevLocalsLength && prevLocalsCounter < prevNumberOfLocals; indexInPrevLocals++) {
+				VerificationTypeInfo prevLocal = prevLocals[indexInPrevLocals];
+				if (prevLocal == null) {
+					result = Integer.MAX_VALUE;
+					this.numberOfDifferentLocals = result;
+					return result;
+				}
+				result--;
+				prevLocalsCounter++;
+				switch(prevLocal.id()) {
+					case TypeIds.T_double :
+					case TypeIds.T_long :
+						indexInPrevLocals++; // next entry  is null
+				}
+			}
+		}
+	}
+	this.numberOfDifferentLocals = result;
+	return result;
+}
+public int getNumberOfLocals() {
+	if (this.numberOfLocals != -1) {
+		return this.numberOfLocals;
+	}
+	int result = 0;
+	final int length = this.locals == null ? 0 : this.locals.length;
+	for(int i = 0; i < length; i++) {
+		if (this.locals[i] != null) {
+			switch(this.locals[i].id()) {
+				case TypeIds.T_double :
+				case TypeIds.T_long :
+					i++;
+			}
+			result++;
+		}
+	}
+	this.numberOfLocals = result;
+	return result;
+}
+public int getOffsetDelta(StackMapFrame prevFrame) {
+	if (prevFrame == null) return this.pc;
+	return prevFrame.pc == -1 ? this.pc : this.pc - prevFrame.pc - 1;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	printFrame(buffer, this);
+	return String.valueOf(buffer);
+}
+private void printFrame(StringBuffer buffer, StackMapFrame frame) {
+	String pattern = "[pc : {0} locals: {1} stack items: {2}\nlocals: {3}\nstack: {4}\n]"; //$NON-NLS-1$
+	int localsLength = frame.locals == null ? 0 : frame.locals.length;
+	buffer.append(MessageFormat.format(
+		pattern,
+		new String[] {
+			Integer.toString(frame.pc),
+			Integer.toString(frame.getNumberOfLocals()),
+			Integer.toString(frame.numberOfStackItems),
+			print(frame.locals, localsLength),
+			print(frame.stackItems, frame.numberOfStackItems)
+		}
+	));
+}
+private String print(VerificationTypeInfo[] infos, int length) {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append('[');
+	if (infos != null) {
+		for (int i = 0; i < length; i++) {
+			if (i != 0) buffer.append(',');
+			VerificationTypeInfo verificationTypeInfo = infos[i];
+			if (verificationTypeInfo == null) {
+				buffer.append("top"); //$NON-NLS-1$
+				continue;
+			}
+			buffer.append(verificationTypeInfo);
+		}
+	}
+	buffer.append(']');
+	return String.valueOf(buffer);
+}
+public void putLocal(int resolvedPosition, VerificationTypeInfo info) {
+	if (this.locals == null) {
+		this.locals = new VerificationTypeInfo[resolvedPosition + 1];
+		this.locals[resolvedPosition] = info;
+	} else {
+		final int length = this.locals.length;
+		if (resolvedPosition >= length) {
+			System.arraycopy(this.locals, 0, this.locals = new VerificationTypeInfo[resolvedPosition + 1], 0, length);
+		}
+		this.locals[resolvedPosition] = info;
+	}
+}
+public void replaceWithElementType() {
+	VerificationTypeInfo info = this.stackItems[this.numberOfStackItems - 1];
+	VerificationTypeInfo info2 = info.duplicate();
+	info2.replaceWithElementType();
+	this.stackItems[this.numberOfStackItems - 1] = info2;
+}
+public int getIndexOfDifferentLocals(int differentLocalsCount) {
+	for (int i = this.locals.length - 1; i >= 0; i--) {
+		VerificationTypeInfo currentLocal = this.locals[i];
+		if (currentLocal == null) {
+			// check the previous slot
+			continue;
+		} else {
+			differentLocalsCount--;
+		}
+		if (differentLocalsCount == 0) {
+			return i;
+		}
+	}
+	return 0;
+}
+private boolean equals(VerificationTypeInfo info, VerificationTypeInfo info2) {
+	if (info == null) {
+		return info2 == null;
+	}
+	if (info2 == null) return false;
+	return info.equals(info2);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
new file mode 100644
index 0000000..e61cde3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+
+public class StackMapFrameCodeStream extends CodeStream {
+	public static class ExceptionMarker implements Comparable {
+		public char[] constantPoolName;
+		public int pc;
+
+		public ExceptionMarker(int pc, char[] constantPoolName) {
+			this.pc = pc;
+			this.constantPoolName = constantPoolName;
+		}
+		public int compareTo(Object o) {
+			if (o instanceof ExceptionMarker) {
+				return this.pc - ((ExceptionMarker) o).pc;
+			}
+			return 0;
+		}
+		public boolean equals(Object obj) {
+			if (obj instanceof ExceptionMarker) {
+				ExceptionMarker marker = (ExceptionMarker) obj;
+				return this.pc == marker.pc && CharOperation.equals(this.constantPoolName, marker.constantPoolName);
+			}
+			return false;
+		}
+		public int hashCode() {
+			return this.pc + this.constantPoolName.hashCode();
+		}
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('(').append(this.pc).append(',').append(this.constantPoolName).append(')');
+			return String.valueOf(buffer);
+		}
+	}
+
+	public static class StackDepthMarker {
+		public int pc;
+		public int delta;
+		public TypeBinding typeBinding;
+
+		public StackDepthMarker(int pc, int delta, TypeBinding typeBinding) {
+			this.pc = pc;
+			this.typeBinding = typeBinding;
+			this.delta = delta;
+		}
+
+		public StackDepthMarker(int pc, int delta) {
+			this.pc = pc;
+			this.delta = delta;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('(').append(this.pc).append(',').append(this.delta);
+			if (this.typeBinding != null) {
+				buffer
+					.append(',')
+					.append(this.typeBinding.qualifiedPackageName())
+					.append(this.typeBinding.qualifiedSourceName());
+			}
+			buffer.append(')');
+			return String.valueOf(buffer);
+		}
+	}
+
+	public static class StackMarker {
+		public int pc;
+		public int destinationPC;
+		public VerificationTypeInfo[] infos;
+
+		public StackMarker(int pc, int destinationPC) {
+			this.pc = pc;
+			this.destinationPC = destinationPC;
+		}
+
+		public void setInfos(VerificationTypeInfo[] infos) {
+			this.infos = infos;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer
+				.append("[copy stack items from ") //$NON-NLS-1$
+				.append(this.pc)
+				.append(" to ") //$NON-NLS-1$
+				.append(this.destinationPC);
+			if (this.infos!= null) {
+				for (int i = 0, max = this.infos.length; i < max; i++) {
+					if (i > 0) buffer.append(',');
+					buffer.append(this.infos[i]);
+				}
+			}
+			buffer.append(']');
+			return String.valueOf(buffer);
+		}
+	}
+
+	static class FramePosition {
+		int counter;
+	}
+
+	public int[] stateIndexes;
+	public int stateIndexesCounter;
+	private HashMap framePositions;
+	public Set exceptionMarkers;
+	public ArrayList stackDepthMarkers;
+	public ArrayList stackMarkers;
+
+public StackMapFrameCodeStream(ClassFile givenClassFile) {
+	super(givenClassFile);
+	this.generateAttributes |= ClassFileConstants.ATTR_STACK_MAP;
+}
+public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+	// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
+	loop: for (int i = 0; i < this.visibleLocalsCount; i++) {
+		LocalVariableBinding localBinding = this.visibleLocals[i];
+		if (localBinding != null) {
+			// Check if the local is definitely assigned
+			boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
+			if (!isDefinitelyAssigned) {
+				if (this.stateIndexes != null) {
+					for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
+						if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
+							if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
+								/* There are two cases:
+								 * 1) there is no initialization interval opened ==> add an opened interval
+								 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
+								 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
+								 * is equals to -1.
+								 * initializationPCs is a collection of pairs of int:
+								 * 	first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
+								 * 	is not closed yet.
+								 */
+								localBinding.recordInitializationStartPC(this.position);
+							}
+							continue loop;
+						}
+					}
+				}
+			} else {
+				if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
+					/* There are two cases:
+					 * 1) there is no initialization interval opened ==> add an opened interval
+					 * 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
+					 * An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
+					 * is equals to -1.
+					 * initializationPCs is a collection of pairs of int:
+					 * 	first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
+					 * 	is not closed yet.
+					 */
+					localBinding.recordInitializationStartPC(this.position);
+				}
+			}
+		}
+	}
+}
+public void addExceptionMarker(int pc, TypeBinding typeBinding) {
+	if (this.exceptionMarkers == null) {
+		this.exceptionMarkers = new HashSet();
+	}
+	if (typeBinding == null) {
+		this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangThrowableConstantPoolName));
+	} else {
+		switch(typeBinding.id) {
+			case TypeIds.T_null :
+				this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName));
+				break;
+			case TypeIds.T_long :
+				this.exceptionMarkers.add(new ExceptionMarker(pc, ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName));
+				break;
+			default:
+				this.exceptionMarkers.add(new ExceptionMarker(pc, typeBinding.constantPoolName()));
+		}
+	}
+}
+public void addFramePosition(int pc) {
+	Integer newEntry = new Integer(pc);
+	FramePosition value;
+	if ((value = (FramePosition) this.framePositions.get(newEntry)) != null) {
+		value.counter++;
+	} else {
+		this.framePositions.put(newEntry, new FramePosition());
+	}
+}
+public void optimizeBranch(int oldPosition, BranchLabel lbl) {
+	super.optimizeBranch(oldPosition, lbl);
+	removeFramePosition(oldPosition);
+}
+public void removeFramePosition(int pc) {
+	Integer entry = new Integer(pc);
+	FramePosition value;
+	if ((value = (FramePosition) this.framePositions.get(entry)) != null) {
+		value.counter--;
+		if (value.counter <= 0) {
+			this.framePositions.remove(entry);
+		}
+	}
+}
+public void addVariable(LocalVariableBinding localBinding) {
+	if (localBinding.initializationPCs == null) {
+		record(localBinding);
+	}
+	localBinding.recordInitializationStartPC(this.position);
+}
+private void addStackMarker(int pc, int destinationPC) {
+	if (this.stackMarkers == null) {
+		this.stackMarkers = new ArrayList();
+		this.stackMarkers.add(new StackMarker(pc, destinationPC));
+	} else {
+		int size = this.stackMarkers.size();
+		if (size == 0 || ((StackMarker) this.stackMarkers.get(size - 1)).pc != this.position) {
+			this.stackMarkers.add(new StackMarker(pc, destinationPC));
+		}
+	}
+}
+private void addStackDepthMarker(int pc, int delta, TypeBinding typeBinding) {
+	if (this.stackDepthMarkers == null) {
+		this.stackDepthMarkers = new ArrayList();
+		this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
+	} else {
+		int size = this.stackDepthMarkers.size();
+		if (size == 0) {
+			this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
+		} else {
+			StackDepthMarker stackDepthMarker = (StackDepthMarker) this.stackDepthMarkers.get(size - 1);
+			if (stackDepthMarker.pc != this.position) {
+				this.stackDepthMarkers.add(new StackDepthMarker(pc, delta, typeBinding));
+			} else {
+				// We replace the recorded stack depth marker with a new value that contains the given typeBinding
+				// This case can happen when multiple conditional expression are nested see bug 362591
+				this.stackDepthMarkers.set(size - 1, new StackDepthMarker(pc, delta, typeBinding));
+			}
+		}
+	}
+}
+public void decrStackSize(int offset) {
+	super.decrStackSize(offset);
+	addStackDepthMarker(this.position, -1, null);
+}
+public void recordExpressionType(TypeBinding typeBinding) {
+	addStackDepthMarker(this.position, 0, typeBinding);
+}
+/**
+ * Macro for building a class descriptor object
+ */
+public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) {
+	if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) {
+		getTYPE(accessedType.id);
+		return;
+	}
+
+	if (this.targetLevel >= ClassFileConstants.JDK1_5) {
+		// generation using the new ldc_w bytecode
+		this.ldc(accessedType);
+	} else {
+		// use in CLDC mode
+		BranchLabel endLabel = new BranchLabel(this);
+		if (syntheticFieldBinding != null) { // non interface case
+			fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */);
+			dup();
+			ifnonnull(endLabel);
+			pop();
+		}
+
+		/* Macro for building a class descriptor object... using or not a field cache to store it into...
+		this sequence is responsible for building the actual class descriptor.
+
+		If the fieldCache is set, then it is supposed to be the body of a synthetic access method
+		factoring the actual descriptor creation out of the invocation site (saving space).
+		If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since
+		we have no way to get a hand on the field cache to do better. */
+
+
+		// Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError
+
+		ExceptionLabel classNotFoundExceptionHandler = new ExceptionLabel(this, TypeBinding.NULL /*represents ClassNotFoundException*/);
+		classNotFoundExceptionHandler.placeStart();
+		this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$
+		invokeClassForName();
+
+		/* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565
+		if (accessedType == BaseTypes.NullBinding) {
+			this.ldc("java.lang.Object"); //$NON-NLS-1$
+		} else if (accessedType.isArrayType()) {
+			this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.'));
+		} else {
+			// we make it an array type (to avoid class initialization)
+			this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		this.invokeClassForName();
+		if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class
+			this.invokeJavaLangClassGetComponentType();
+		}
+		*/
+		/* We need to protect the runtime code from binary inconsistencies
+		in case the accessedType is missing, the ClassNotFoundException has to be converted
+		into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */
+		classNotFoundExceptionHandler.placeEnd();
+
+		if (syntheticFieldBinding != null) { // non interface case
+			dup();
+			fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */);
+		}
+		int fromPC = this.position;
+		goto_(endLabel);
+		int savedStackDepth = this.stackDepth;
+		// Generate the body of the exception handler
+		/* ClassNotFoundException on stack -- the class literal could be doing more things
+		on the stack, which means that the stack may not be empty at this point in the
+		above code gen. So we save its state and restart it from 1. */
+
+		pushExceptionOnStack(TypeBinding.NULL);/*represents ClassNotFoundException*/
+		classNotFoundExceptionHandler.place();
+
+		// Transform the current exception, and repush and throw a
+		// NoClassDefFoundError(ClassNotFound.getMessage())
+
+		newNoClassDefFoundError();
+		dup_x1();
+		swap();
+
+		// Retrieve the message from the old exception
+		invokeThrowableGetMessage();
+
+		// Send the constructor taking a message string as an argument
+		invokeNoClassDefFoundErrorStringConstructor();
+		athrow();
+		endLabel.place();
+		addStackMarker(fromPC, this.position);
+		this.stackDepth = savedStackDepth;
+	}
+}
+public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
+	int currentPosition = this.position;
+	super.generateOuterAccess(mappingSequence, invocationSite, target, scope);
+	if (currentPosition == this.position) {
+		// no code has been generate during outer access => no enclosing instance is available
+		throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
+	}
+}
+public ExceptionMarker[] getExceptionMarkers() {
+	Set exceptionMarkerSet = this.exceptionMarkers;
+	if (this.exceptionMarkers == null) return null;
+	int size = exceptionMarkerSet.size();
+	ExceptionMarker[] markers = new ExceptionMarker[size];
+	int n = 0;
+	for (Iterator iterator = exceptionMarkerSet.iterator(); iterator.hasNext(); ) {
+		markers[n++] = (ExceptionMarker) iterator.next();
+	}
+	Arrays.sort(markers);
+//  System.out.print('[');
+//  for (int n = 0; n < size; n++) {
+//  	if (n != 0) System.out.print(',');
+//  	System.out.print(positions[n]);
+//  }
+//  System.out.println(']');
+	return markers;
+}
+public int[] getFramePositions() {
+	Set set = this.framePositions.keySet();
+	int size = set.size();
+	int[] positions = new int[size];
+	int n = 0;
+	for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
+		positions[n++] = ((Integer) iterator.next()).intValue();
+	}
+	Arrays.sort(positions);
+//  System.out.print('[');
+//  for (int n = 0; n < size; n++) {
+//  	if (n != 0) System.out.print(',');
+//  	System.out.print(positions[n]);
+//  }
+//  System.out.println(']');
+	return positions;
+}
+public StackDepthMarker[] getStackDepthMarkers() {
+	if (this.stackDepthMarkers == null) return null;
+	int length = this.stackDepthMarkers.size();
+	if (length == 0) return null;
+	StackDepthMarker[] result = new StackDepthMarker[length];
+	this.stackDepthMarkers.toArray(result);
+	return result;
+}
+public StackMarker[] getStackMarkers() {
+	if (this.stackMarkers == null) return null;
+	int length = this.stackMarkers.size();
+	if (length == 0) return null;
+	StackMarker[] result = new StackMarker[length];
+	this.stackMarkers.toArray(result);
+	return result;
+}
+public boolean hasFramePositions() {
+	return this.framePositions.size() != 0;
+}
+public void init(ClassFile targetClassFile) {
+	super.init(targetClassFile);
+	this.stateIndexesCounter = 0;
+	if (this.framePositions != null) {
+		this.framePositions.clear();
+	}
+	if (this.exceptionMarkers != null) {
+		this.exceptionMarkers.clear();
+	}
+	if (this.stackDepthMarkers != null) {
+		this.stackDepthMarkers.clear();
+	}
+	if (this.stackMarkers != null) {
+		this.stackMarkers.clear();
+	}
+}
+
+public void initializeMaxLocals(MethodBinding methodBinding) {
+	super.initializeMaxLocals(methodBinding);
+	if (this.framePositions == null) {
+		this.framePositions = new HashMap();
+	} else {
+		this.framePositions.clear();
+	}
+}
+public void popStateIndex() {
+	this.stateIndexesCounter--;
+}
+public void pushStateIndex(int naturalExitMergeInitStateIndex) {
+	if (this.stateIndexes == null) {
+		this.stateIndexes = new int[3];
+	}
+	int length = this.stateIndexes.length;
+	if (length == this.stateIndexesCounter) {
+		// resize
+		System.arraycopy(this.stateIndexes, 0, (this.stateIndexes = new int[length * 2]), 0, length);
+	}
+	this.stateIndexes[this.stateIndexesCounter++] = naturalExitMergeInitStateIndex;
+}
+public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
+	int index = this.visibleLocalsCount;
+	loop : for (int i = 0; i < index; i++) {
+		LocalVariableBinding localBinding = this.visibleLocals[i];
+		if (localBinding != null && localBinding.initializationCount > 0) {
+			boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
+			if (!isDefinitelyAssigned) {
+				if (this.stateIndexes != null) {
+					for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
+						if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
+							continue loop;
+						}
+					}
+				}
+				localBinding.recordInitializationEndPC(this.position);
+			}
+		}
+	}
+}
+public void reset(ClassFile givenClassFile) {
+	super.reset(givenClassFile);
+	this.stateIndexesCounter = 0;
+	if (this.framePositions != null) {
+		this.framePositions.clear();
+	}
+	if (this.exceptionMarkers != null) {
+		this.exceptionMarkers.clear();
+	}
+	if (this.stackDepthMarkers != null) {
+		this.stackDepthMarkers.clear();
+	}
+	if (this.stackMarkers != null) {
+		this.stackMarkers.clear();
+	}
+}
+protected void writePosition(BranchLabel label) {
+	super.writePosition(label);
+	addFramePosition(label.position);
+}
+protected void writePosition(BranchLabel label, int forwardReference) {
+	super.writePosition(label, forwardReference);
+	addFramePosition(label.position);
+}
+protected void writeSignedWord(int pos, int value) {
+	super.writeSignedWord(pos, value);
+	addFramePosition(this.position);
+}
+protected void writeWidePosition(BranchLabel label) {
+	super.writeWidePosition(label);
+	addFramePosition(label.position);
+}
+public void areturn() {
+	super.areturn();
+	addFramePosition(this.position);
+}
+public void ireturn() {
+	super.ireturn();
+	addFramePosition(this.position);
+}
+public void lreturn() {
+	super.lreturn();
+	addFramePosition(this.position);
+}
+public void freturn() {
+	super.freturn();
+	addFramePosition(this.position);
+}
+public void dreturn() {
+	super.dreturn();
+	addFramePosition(this.position);
+}
+public void return_() {
+	super.return_();
+	addFramePosition(this.position);
+}
+public void athrow() {
+	super.athrow();
+	addFramePosition(this.position);
+}
+public void pushOnStack(TypeBinding binding) {
+	super.pushOnStack(binding);
+	addStackDepthMarker(this.position, 1, binding);
+}
+public void pushExceptionOnStack(TypeBinding binding) {
+	super.pushExceptionOnStack(binding);
+	addExceptionMarker(this.position, binding);
+}
+public void goto_(BranchLabel label) {
+	super.goto_(label);
+	addFramePosition(this.position);
+}
+public void goto_w(BranchLabel label) {
+	super.goto_w(label);
+	addFramePosition(this.position);
+}
+public void resetInWideMode() {
+	this.resetSecretLocals();
+	super.resetInWideMode();
+}
+public void resetForCodeGenUnusedLocals() {
+	this.resetSecretLocals();
+	super.resetForCodeGenUnusedLocals();
+}
+public void resetSecretLocals() {
+	for (int i = 0, max = this.locals.length; i < max; i++) {
+		LocalVariableBinding localVariableBinding = this.locals[i];
+		if (localVariableBinding != null && localVariableBinding.isSecret()) {
+			// all other locals are reinitialized inside the computation of their resolved positions
+			localVariableBinding.resetInitializations();
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
new file mode 100644
index 0000000..e1fb841
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/TypeAnnotationCodeStream.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class TypeAnnotationCodeStream extends StackMapFrameCodeStream {
+	public List allTypeAnnotationContexts;
+
+	public TypeAnnotationCodeStream(ClassFile givenClassFile) {
+		super(givenClassFile);
+		this.generateAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
+		this.allTypeAnnotationContexts = new ArrayList();
+	}
+	
+	private void addAnnotationContext(TypeReference typeReference, int info, int targetType, Annotation[][] annotationsOnDimensions, int dimensions) {
+		typeReference.getAllAnnotationContexts(targetType, info, this.allTypeAnnotationContexts, annotationsOnDimensions, dimensions);
+	}
+	
+	private void addAnnotationContext(TypeReference typeReference, int info, int targetType) {
+		typeReference.getAllAnnotationContexts(targetType, info, this.allTypeAnnotationContexts);
+	}
+
+	private void addAnnotationContext(TypeReference typeReference, int info, int typeIndex, int targetType) {
+		typeReference.getAllAnnotationContexts(targetType, info, typeIndex, this.allTypeAnnotationContexts);
+	}
+	
+	public void instance_of(TypeReference typeReference, TypeBinding typeBinding) {
+		if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.INSTANCEOF);
+		}
+		super.instance_of(typeReference, typeBinding);
+	}
+	
+	public void multianewarray(
+			TypeReference typeReference,
+			TypeBinding typeBinding,
+			int dimensions,
+			Annotation [][] annotationsOnDimensions) {
+		if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW, annotationsOnDimensions, dimensions);
+		}
+		super.multianewarray(typeReference, typeBinding, dimensions, annotationsOnDimensions);
+	}
+
+	public void new_(TypeReference typeReference, TypeBinding typeBinding) {
+		if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW);
+		}
+		super.new_(typeReference, typeBinding);
+	}
+	
+	public void newArray(TypeReference typeReference, Annotation[][] annotationsOnDimensions, ArrayBinding arrayBinding) {
+		if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.NEW, annotationsOnDimensions, 1);
+		}
+		super.newArray(typeReference, annotationsOnDimensions, arrayBinding);
+	}
+	
+	public void checkcast(TypeReference typeReference, TypeBinding typeBinding) {
+		if (typeReference != null && (typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			addAnnotationContext(typeReference, this.position, AnnotationTargetTypeConstants.CAST);
+		}
+		super.checkcast(typeReference, typeBinding);
+	}
+	
+	public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass, TypeReference[] typeArguments) {
+		if (typeArguments != null) {
+			int targetType = methodBinding.isConstructor()
+					? AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+					: AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT;
+			for (int i = 0, max = typeArguments.length; i < max; i++) {
+				TypeReference typeArgument = typeArguments[i];
+				if ((typeArgument.bits & ASTNode.HasTypeAnnotations) != 0) { // TODO can check this at a higher level?
+					addAnnotationContext(typeArgument, this.position, i, targetType);
+				}
+			}
+		}
+		super.invoke(opcode, methodBinding, declaringClass, typeArguments);
+	}
+	
+	public void invokeDynamic(int bootStrapIndex, int argsSize, int returnTypeSize, char[] selector, char[] signature, 
+			boolean isConstructorReference, TypeReference lhsTypeReference, TypeReference [] typeArguments) {
+		if (lhsTypeReference != null && (lhsTypeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
+			if (isConstructorReference) {
+				addAnnotationContext(lhsTypeReference, this.position, 0, AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE);
+			} else {
+				addAnnotationContext(lhsTypeReference, this.position, 0, AnnotationTargetTypeConstants.METHOD_REFERENCE);
+			}
+		}
+		if (typeArguments != null) {
+			int targetType = 
+					isConstructorReference
+					? AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+					: AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT;
+			for (int i = 0, max = typeArguments.length; i < max; i++) {
+				TypeReference typeArgument = typeArguments[i];
+				if ((typeArgument.bits & ASTNode.HasTypeAnnotations) != 0) {
+					addAnnotationContext(typeArgument, this.position, i, targetType);
+				}
+			}
+		}
+		super.invokeDynamic(bootStrapIndex, argsSize, returnTypeSize, selector, signature, isConstructorReference, lhsTypeReference, typeArguments);
+	}
+
+	public void reset(ClassFile givenClassFile) {
+		super.reset(givenClassFile);
+		this.allTypeAnnotationContexts = new ArrayList();
+	}
+	
+	public void init(ClassFile targetClassFile) {
+		super.init(targetClassFile);
+		this.allTypeAnnotationContexts = new ArrayList();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
new file mode 100644
index 0000000..149ff61
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.codegen;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class VerificationTypeInfo {
+	/**
+	 * The tag value representing top variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_TOP = 0;
+	/**
+	 * The tag value representing integer variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_INTEGER = 1;
+	/**
+	 * The tag value representing float variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_FLOAT = 2;
+	/**
+	 * The tag value representing double variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_DOUBLE = 3;
+	/**
+	 * The tag value representing long variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_LONG = 4;
+	/**
+	 * The tag value representing null variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_NULL = 5;
+	/**
+	 * The tag value representing uninitialized this variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_UNINITIALIZED_THIS = 6;
+	/**
+	 * The tag value representing object variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_OBJECT = 7;
+	/**
+	 * The tag value representing uninitialized variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_UNINITIALIZED = 8;
+
+	public int tag;
+	private int id;
+	private char[] constantPoolName;
+	public int offset;
+
+private VerificationTypeInfo() {
+	// for duplication
+}
+public VerificationTypeInfo(int id, char[] constantPoolName) {
+	this(id, VerificationTypeInfo.ITEM_OBJECT, constantPoolName);
+}
+public VerificationTypeInfo(int id, int tag, char[] constantPoolName) {
+	this.id = id;
+	this.tag = tag;
+	this.constantPoolName = constantPoolName;
+}
+public VerificationTypeInfo(int tag, TypeBinding binding) {
+	this(binding);
+	this.tag = tag;
+}
+public VerificationTypeInfo(TypeBinding binding) {
+	this.id = binding.id;
+	switch(binding.id) {
+		case TypeIds.T_boolean :
+		case TypeIds.T_byte :
+		case TypeIds.T_char :
+		case TypeIds.T_int :
+		case TypeIds.T_short :
+			this.tag = VerificationTypeInfo.ITEM_INTEGER;
+			break;
+		case TypeIds.T_float :
+			this.tag = VerificationTypeInfo.ITEM_FLOAT;
+			break;
+		case TypeIds.T_long :
+			this.tag = VerificationTypeInfo.ITEM_LONG;
+			break;
+		case TypeIds.T_double :
+			this.tag = VerificationTypeInfo.ITEM_DOUBLE;
+			break;
+		case TypeIds.T_null :
+			this.tag = VerificationTypeInfo.ITEM_NULL;
+			break;
+		default:
+			this.tag =  VerificationTypeInfo.ITEM_OBJECT;
+			this.constantPoolName = binding.constantPoolName();
+	}
+}
+public void setBinding(TypeBinding binding) {
+	this.constantPoolName = binding.constantPoolName();
+	final int typeBindingId = binding.id;
+	this.id = typeBindingId;
+	switch(typeBindingId) {
+		case TypeIds.T_boolean :
+		case TypeIds.T_byte :
+		case TypeIds.T_char :
+		case TypeIds.T_int :
+		case TypeIds.T_short :
+			this.tag = VerificationTypeInfo.ITEM_INTEGER;
+			break;
+		case TypeIds.T_float :
+			this.tag = VerificationTypeInfo.ITEM_FLOAT;
+			break;
+		case TypeIds.T_long :
+			this.tag = VerificationTypeInfo.ITEM_LONG;
+			break;
+		case TypeIds.T_double :
+			this.tag = VerificationTypeInfo.ITEM_DOUBLE;
+			break;
+		case TypeIds.T_null :
+			this.tag = VerificationTypeInfo.ITEM_NULL;
+			break;
+		default:
+			this.tag =  VerificationTypeInfo.ITEM_OBJECT;
+	}
+}
+public int id() {
+	return this.id;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	switch(this.tag) {
+		case VerificationTypeInfo.ITEM_UNINITIALIZED_THIS :
+			buffer.append("uninitialized_this(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
+			break;
+		case VerificationTypeInfo.ITEM_UNINITIALIZED :
+			buffer.append("uninitialized(").append(readableName()).append(")"); //$NON-NLS-1$//$NON-NLS-2$
+			break;
+		case VerificationTypeInfo.ITEM_OBJECT :
+			buffer.append(readableName());
+			break;
+		case VerificationTypeInfo.ITEM_DOUBLE :
+			buffer.append('D');
+			break;
+		case VerificationTypeInfo.ITEM_FLOAT :
+			buffer.append('F');
+			break;
+		case VerificationTypeInfo.ITEM_INTEGER :
+			buffer.append('I');
+			break;
+		case VerificationTypeInfo.ITEM_LONG :
+			buffer.append('J');
+			break;
+		case VerificationTypeInfo.ITEM_NULL :
+			buffer.append("null"); //$NON-NLS-1$
+			break;
+		case VerificationTypeInfo.ITEM_TOP :
+			buffer.append("top"); //$NON-NLS-1$
+			break;
+	}
+	return String.valueOf(buffer);
+}
+public VerificationTypeInfo duplicate() {
+	final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo();
+	verificationTypeInfo.id = this.id;
+	verificationTypeInfo.tag = this.tag;
+	verificationTypeInfo.constantPoolName = this.constantPoolName;
+	verificationTypeInfo.offset = this.offset;
+	return verificationTypeInfo;
+}
+public boolean equals(Object obj) {
+	if (obj instanceof VerificationTypeInfo) {
+		VerificationTypeInfo info1 = (VerificationTypeInfo) obj;
+		return info1.tag == this.tag && CharOperation.equals(info1.constantPoolName(), constantPoolName());
+	}
+	return false;
+}
+public int hashCode() {
+	return this.tag + this.id + this.constantPoolName.length + this.offset;
+}
+public char[] constantPoolName() {
+	return this.constantPoolName;
+}
+public char[] readableName() {
+	return this.constantPoolName;
+}
+public void replaceWithElementType() {
+	if (this.constantPoolName[1] == 'L') {
+		this.constantPoolName = CharOperation.subarray(this.constantPoolName, 2,  this.constantPoolName.length - 1);
+	} else {
+		this.constantPoolName = CharOperation.subarray(this.constantPoolName, 1, this.constantPoolName.length);
+		if (this.constantPoolName.length == 1) {
+			switch(this.constantPoolName[0]) {
+				case 'I' :
+					this.id = TypeIds.T_int;
+					break;
+				case 'B' :
+					this.id = TypeIds.T_byte;
+					break;
+				case 'S' :
+					this.id = TypeIds.T_short;
+					break;
+				case 'C' :
+					this.id = TypeIds.T_char;
+					break;
+				case 'J' :
+					this.id = TypeIds.T_long;
+					break;
+				case 'F' :
+					this.id = TypeIds.T_float;
+					break;
+				case 'D' :
+					this.id = TypeIds.T_double;
+					break;
+				case 'Z' :
+					this.id = TypeIds.T_boolean;
+					break;
+				case 'N' :
+					this.id = TypeIds.T_null;
+					break;
+				case 'V' :
+					this.id = TypeIds.T_void;
+					break;
+			}
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java
new file mode 100644
index 0000000..c1b6b11
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public class AccessRestriction {
+
+	private AccessRule accessRule;
+	public byte classpathEntryType;
+	public static final byte
+		COMMAND_LINE = 0,
+		PROJECT = 1,
+		LIBRARY = 2;
+	public String classpathEntryName;
+
+	public AccessRestriction(AccessRule accessRule, byte classpathEntryType, String classpathEntryName) {
+		this.accessRule = accessRule;
+		this.classpathEntryName = classpathEntryName;
+		this.classpathEntryType = classpathEntryType;
+	}
+
+	public int getProblemId() {
+		return this.accessRule.getProblemId();
+	}
+
+	public boolean ignoreIfBetter() {
+		return this.accessRule.ignoreIfBetter();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java
new file mode 100644
index 0000000..627ee15
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+public class AccessRule {
+
+	public static final int IgnoreIfBetter = 0x02000000; // value must be greater than IProblem#ForbiddenReference and DiscouragedReference
+
+	public char[] pattern;
+	public int problemId;
+
+	public AccessRule(char[] pattern, int problemId) {
+		this(pattern, problemId, false);
+	}
+
+	public AccessRule(char[] pattern, int problemId, boolean keepLooking) {
+		this.pattern = pattern;
+		this.problemId = keepLooking ? problemId | IgnoreIfBetter : problemId;
+	}
+
+	public int hashCode() {
+		return this.problemId * 17 + CharOperation.hashCode(this.pattern);
+	}
+
+	public boolean equals(Object obj) {
+		if (!(obj instanceof AccessRule)) return false;
+		AccessRule other = (AccessRule) obj;
+		if (this.problemId != other.problemId) return false;
+		return CharOperation.equals(this.pattern, other.pattern);
+	}
+
+	public int getProblemId() {
+		return this.problemId & ~IgnoreIfBetter;
+	}
+
+	public boolean ignoreIfBetter() {
+		return (this.problemId & IgnoreIfBetter) != 0;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("pattern="); //$NON-NLS-1$
+		buffer.append(this.pattern);
+		switch (getProblemId()) {
+			case IProblem.ForbiddenReference:
+				buffer.append(" (NON ACCESSIBLE"); //$NON-NLS-1$
+				break;
+			case IProblem.DiscouragedReference:
+				buffer.append(" (DISCOURAGED"); //$NON-NLS-1$
+				break;
+			default:
+				buffer.append(" (ACCESSIBLE"); //$NON-NLS-1$
+				break;
+		}
+		if (ignoreIfBetter())
+			buffer.append(" | IGNORE IF BETTER"); //$NON-NLS-1$
+		buffer.append(')');
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
new file mode 100644
index 0000000..f9c29bf
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Definition of a set of access rules used to flag forbidden references to non API code.
+ */
+public class AccessRuleSet {
+
+	private AccessRule[] accessRules;
+	public byte classpathEntryType; // one of AccessRestriction#COMMAND_LINE, LIBRARY, PROJECT
+	public String classpathEntryName;
+
+/**
+ * Make a new set of access rules.
+ * @param accessRules the access rules to be contained by the new set
+ * @param classpathEntryType one of {@link AccessRestriction#COMMAND_LINE},
+ *        {@link AccessRestriction#LIBRARY}, {@link AccessRestriction#PROJECT}
+ *        that tells the access restrictions how to render the classpath entry
+ * @param classpathEntryName a user-readable name for the classpath entry
+ */
+public AccessRuleSet(AccessRule[] accessRules, byte classpathEntryType, String classpathEntryName) {
+	this.accessRules = accessRules;
+	this.classpathEntryType = classpathEntryType;
+	this.classpathEntryName = classpathEntryName;
+}
+
+/**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+public boolean equals(Object object) {
+	if (this == object)
+		return true;
+	if (!(object instanceof AccessRuleSet))
+		return false;
+	AccessRuleSet otherRuleSet = (AccessRuleSet) object;
+	if (this.classpathEntryType != otherRuleSet.classpathEntryType ||
+			this.classpathEntryName == null && otherRuleSet.classpathEntryName != null ||
+			! this.classpathEntryName.equals(otherRuleSet.classpathEntryName)) {
+		return false;
+	}
+	int rulesLength = this.accessRules.length;
+	if (rulesLength != otherRuleSet.accessRules.length) return false;
+	for (int i = 0; i < rulesLength; i++)
+		if (!this.accessRules[i].equals(otherRuleSet.accessRules[i]))
+			return false;
+	return true;
+}
+
+public AccessRule[] getAccessRules() {
+	return this.accessRules;
+}
+
+/**
+ * Select the first access rule which is violated when accessing a given type,
+ * or null if no 'non accessible' access rule applies.
+ * @param targetTypeFilePath the target type file path, formed as:
+ * "org/eclipse/jdt/core/JavaCore"
+ * @return the first access restriction that applies if any, null else
+ */
+public AccessRestriction getViolatedRestriction(char[] targetTypeFilePath) {
+	for (int i = 0, length = this.accessRules.length; i < length; i++) {
+		AccessRule accessRule = this.accessRules[i];
+		if (CharOperation.pathMatch(accessRule.pattern, targetTypeFilePath,
+				true/*case sensitive*/, '/')) {
+			switch (accessRule.getProblemId()) {
+				case IProblem.ForbiddenReference:
+				case IProblem.DiscouragedReference:
+					return new AccessRestriction(accessRule, this.classpathEntryType, this.classpathEntryName);
+				default:
+					return null;
+			}
+		}
+	}
+	return null;
+}
+
+public int hashCode() {
+	final int prime = 31;
+	int result = 1;
+	result = prime * result + hashCode(this.accessRules);
+	result = prime * result + ((this.classpathEntryName == null) ? 0 : this.classpathEntryName.hashCode());
+	result = prime * result + this.classpathEntryType;
+	return result;
+}
+
+private int hashCode(AccessRule[] rules) {
+	final int prime = 31;
+	if (rules == null)
+		return 0;
+	int result = 1;
+	for (int i = 0, length = rules.length; i < length; i++) {
+		result = prime * result + (rules[i] == null ? 0 : rules[i].hashCode());
+	}
+	return result;
+}
+
+public String toString() {
+	return toString(true/*wrap lines*/);
+}
+
+public String toString(boolean wrap) {
+	StringBuffer buffer = new StringBuffer(200);
+	buffer.append("AccessRuleSet {"); //$NON-NLS-1$
+	if (wrap)
+		buffer.append('\n');
+	for (int i = 0, length = this.accessRules.length; i < length; i++) {
+		if (wrap)
+			buffer.append('\t');
+		AccessRule accessRule = this.accessRules[i];
+		buffer.append(accessRule);
+		if (wrap)
+			buffer.append('\n');
+		else if (i < length-1)
+			buffer.append(", "); //$NON-NLS-1$
+	}
+	buffer.append("} [classpath entry: "); //$NON-NLS-1$
+	buffer.append(this.classpathEntryName);
+	buffer.append("]"); //$NON-NLS-1$
+	return buffer.toString();
+}
+
+}
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
new file mode 100644
index 0000000..f3e4685
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * 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.
+ */
+public class ClassSignature {
+
+	char[] className;
+
+public ClassSignature(final char[] className) {
+	this.className = className;
+}
+
+/**
+ * @return name of the type in the class file format
+ */
+public char[] getTypeName() {
+	return this.className;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(this.className);
+	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
new file mode 100644
index 0000000..437df94
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * 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.
+ */
+public class EnumConstantSignature {
+
+	char[] typeName;
+	char[] constName;
+
+public EnumConstantSignature(char[] typeName, char[] constName) {
+	this.typeName = typeName;
+	this.constName = constName;
+}
+
+/**
+ * @return name of the type in the class file format
+ */
+public char[] getTypeName() {
+	return this.typeName;
+}
+
+/**
+ * @return the name of the enum constant reference.
+ */
+public char[] getEnumConstantName() {
+	return this.constName;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(this.typeName);
+	buffer.append('.');
+	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/env/IBinaryAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java
new file mode 100644
index 0000000..7388428
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+/**
+ * This represents class file information about an annotation instance.
+ */
+public interface IBinaryAnnotation {
+
+/**
+ * @return the signature of the annotation type.
+ */
+char[] getTypeName();
+
+/**
+ * @return the list of element value pairs of the annotation
+ */
+IBinaryElementValuePair[] getElementValuePairs();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryElementValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryElementValuePair.java
new file mode 100644
index 0000000..6c7c6c9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryElementValuePair.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+/**
+ * This represents the class file information about a member value pair of an annotation.
+ */
+public interface IBinaryElementValuePair {
+
+/** @return the name of the member */
+char[] getName();
+
+/**
+ * Return {@link ClassSignature} for a Class {@link java.lang.Class}.
+ * Return {@link org.eclipse.jdt.internal.compiler.impl.Constant} for compile-time constant of primitive type, as well as String literals.
+ * Return {@link EnumConstantSignature} if value is an enum constant.
+ * Return {@link IBinaryAnnotation} for annotation type.
+ * Return {@link Object}[] for array type.
+ *
+ * @return the value of this member value pair
+ */
+Object getValue();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java
new file mode 100644
index 0000000..4e9b566
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public interface IBinaryField extends IGenericField {
+/**
+ * Answer the runtime visible and invisible annotations for this field or null if none.
+ */
+IBinaryAnnotation[] getAnnotations();
+
+/**
+ *
+ * @return org.eclipse.jdt.internal.compiler.Constant
+ */
+Constant getConstant();
+
+/**
+ * Answer the receiver's signature which describes the parameter &
+ * return types as specified in section 4.4.4 of the Java 2 VM spec.
+ */
+char[] getGenericSignature();
+
+/**
+ * Answer the name of the field.
+ */
+char[] getName();
+
+/**
+ * Answer the tagbits set according to the bits for annotations.
+ */
+long getTagBits();
+
+/**
+ * Answer the resolved name of the receiver's type in the
+ * class file format as specified in section 4.3.2 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - java.lang.String is Ljava/lang/String;
+ *   - an int is I
+ *   - a 2 dimensional array of strings is [[Ljava/lang/String;
+ *   - an array of floats is [F
+ */
+char[] getTypeName();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
new file mode 100644
index 0000000..177ae24
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+// clinit methods (synthetics too?) can be returned from IBinaryType>>getMethods()
+// BUT do not have to be... the compiler will ignore them when building the binding.
+// The synthetic argument of a member type's constructor (i.e. the first arg of a non-static
+// member type) is also ignored by the compiler, BUT in this case it must be included
+// in the constructor's signature.
+
+public interface IBinaryMethod extends IGenericMethod {
+
+/**
+ * Answer the runtime visible and invisible annotations for this method or null if none.
+ */
+IBinaryAnnotation[] getAnnotations();
+
+/**
+ * Return {@link ClassSignature} for a Class {@link java.lang.Class}.
+ * Return {@link org.eclipse.jdt.internal.compiler.impl.Constant} for compile-time constant of primitive type, as well as String literals.
+ * Return {@link EnumConstantSignature} if value is an enum constant.
+ * Return {@link IBinaryAnnotation} for annotation type.
+ * Return {@link Object}[] for array type.
+ *
+ * @return default value of this annotation method
+ */
+Object getDefaultValue();
+
+/**
+ * Answer the resolved names of the exception types in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+char[][] getExceptionTypeNames();
+
+/**
+ * Answer the receiver's signature which describes the parameter &
+ * return types as specified in section 4.4.4 of the Java 2 VM spec.
+ */
+char[] getGenericSignature();
+
+/**
+ * Answer the receiver's method descriptor which describes the parameter &
+ * return types as specified in section 4.4.3 of the Java 2 VM spec.
+ *
+ * For example:
+ *   - int foo(String) is (Ljava/lang/String;)I
+ *   - Object[] foo(int) is (I)[Ljava/lang/Object;
+ */
+char[] getMethodDescriptor();
+
+/**
+ * Answer the annotations on the <code>index</code>th parameter or null if none
+ * @param index the index of the parameter of interest
+ */
+IBinaryAnnotation[] getParameterAnnotations(int index);
+
+/**
+ * Answer the number of parameter annotations that can be retrieved
+ * using {@link #getParameterAnnotations(int)}.
+ * @return one beyond the highest legal argument to {@link #getParameterAnnotations(int)}.
+ */
+int getAnnotatedParametersCount();
+
+/**
+ * Answer the name of the method.
+ *
+ * For a constructor, answer <init> & <clinit> for a clinit method.
+ */
+char[] getSelector();
+
+/**
+ * Answer the tagbits set according to the bits for annotations.
+ */
+long getTagBits();
+
+/**
+ * Answer whether the receiver represents a class initializer method.
+ */
+boolean isClinit();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
new file mode 100644
index 0000000..babba7d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface IBinaryNestedType {
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getEnclosingTypeName();
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+int getModifiers();
+/**
+ * Answer the resolved name of the member type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, p1.p2.A.M is p1/p2/A$M.
+ */
+
+char[] getName();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
new file mode 100644
index 0000000..7424325
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public interface IBinaryType extends IGenericType {
+
+	char[][] NoInterface = CharOperation.NO_CHAR_CHAR;
+	IBinaryNestedType[] NoNestedType = new IBinaryNestedType[0];
+	IBinaryField[] NoField = new IBinaryField[0];
+	IBinaryMethod[] NoMethod = new IBinaryMethod[0];
+/**
+ * Answer the runtime visible and invisible annotations for this type or null if none.
+ */
+
+IBinaryAnnotation[] getAnnotations();
+/**
+ * Answer the enclosing method (including method selector and method descriptor), or
+ * null if none.
+ *
+ * For example, "foo()Ljava/lang/Object;V"
+ */
+
+char[] getEnclosingMethod();
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the receiver is a top level type.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getEnclosingTypeName();
+/**
+ * Answer the receiver's fields or null if the array is empty.
+ */
+
+IBinaryField[] getFields();
+/**
+ * Answer the receiver's signature which describes the parameter &
+ * return types as specified in section 4.4.4 of the Java 2 VM spec 3rd edition.
+ * Returns null if none.
+ *
+ * @return the receiver's signature, null if none
+ */
+char[] getGenericSignature();
+/**
+ * Answer the resolved names of the receiver's interfaces in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[][] getInterfaceNames();
+/**
+ * Answer the receiver's nested types or null if the array is empty.
+ *
+ * This nested type info is extracted from the inner class attributes.
+ * Ask the name environment to find a member type using its compound name.
+ */
+
+// NOTE: The compiler examines the nested type info & ignores the local types
+// so the local types do not have to be included.
+
+IBinaryNestedType[] getMemberTypes();
+/**
+ * Answer the receiver's methods or null if the array is empty.
+ */
+
+IBinaryMethod[] getMethods();
+
+/**
+ * Answer the list of missing type names which were referenced from
+ * the problem classfile. This list is encoded via an extra attribute.
+ */
+char[][][] getMissingTypeNames();
+
+/**
+ * Answer the resolved name of the type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+char[] getName();
+
+/**
+ * Answer the simple name of the type in the class file.
+ * For member A$B, will answer B.
+ * For anonymous will answer null.
+ */
+char[] getSourceName();
+
+/**
+ * Answer the resolved name of the receiver's superclass in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if it does not have one.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+
+char[] getSuperclassName();
+/**
+ * Answer the tagbits set according to the bits for annotations.
+ */
+long getTagBits();
+/**
+ * Answer true if the receiver is an anonymous class.
+ * false otherwise
+ */
+boolean isAnonymous();
+
+/**
+ * Answer true if the receiver is a local class.
+ * false otherwise
+ */
+boolean isLocal();
+
+/**
+ * Answer true if the receiver is a member class.
+ * false otherwise
+ */
+boolean isMember();
+
+/**
+ * Answer the source file attribute, or null if none.
+ *
+ * For example, "String.java"
+ */
+
+char[] sourceFileName();
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
new file mode 100644
index 0000000..bbe34a2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+/**
+ * This interface denotes a compilation unit, providing its name and content.
+ */
+public interface ICompilationUnit extends IDependent {
+/**
+ * Answer the contents of the compilation unit.
+ *
+ * In normal use, the contents are requested twice.
+ * Once during the initial lite parsing step, then again for the
+ * more detailed parsing step.
+ * Implementors must never return null - return an empty char[] instead,
+ * CharOperation.NO_CHAR being the candidate of choice.
+ */
+char[] getContents();
+/**
+ * Answer the name of the top level public type.
+ * For example, {Hashtable}.
+ */
+char[] getMainTypeName();
+/**
+ * Answer the name of the package according to the directory structure
+ * or null if package consistency checks should be ignored.
+ * For example, {java, lang}.
+ */
+char[][] getPackageName();
+/**
+* Answer if optional problems should be ignored for this compilation unit.
+* Implementors should return <code>false</code> if there is no preference.
+*/
+boolean ignoreOptionalProblems();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
new file mode 100644
index 0000000..3f5244f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+/**
+ * This represents the target file of a type dependency.
+ *
+ * All implementors of this interface are containers for types or types
+ * themselves which must be able to identify their source file name
+ * when file dependencies are collected.
+ */
+public interface IDependent {
+	char JAR_FILE_ENTRY_SEPARATOR = '|';
+/**
+ * Answer the file name which defines the type.
+ *
+ * The path part (optional) must be separated from the actual
+ * file proper name by a separator suitable for the type (java.io.File.separator for example),
+ * e.g.
+ *  "c:\\source\\com\\p\\X.java" or
+ *  "/com/p/Y.java".
+ *
+ * The path to the zip or jar file (optional) must be separated
+ * from the actual path part by JAR_FILE_ENTRY_SEPARATOR,
+ * e.g.
+ *  "c:\\lib\\some.jar|/com/p/X.class" or
+ *  "/lib/some.zip|/com/q/Y.class".
+ *
+ * The proper file name includes the suffix extension (e.g.&nbsp;".java")
+ * e.g.&nbsp;"c:/org/eclipse/jdt/internal/compileri/env/IDependent.java"
+ *
+ * Return null if no file defines the type.
+ */
+
+char[] getFileName();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
new file mode 100644
index 0000000..3bff96d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface IGenericField {
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+
+// We have added AccDeprecated & AccSynthetic.
+
+int getModifiers();
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
new file mode 100644
index 0000000..273f317
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface IGenericMethod {
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+// We have added AccDeprecated
+int getModifiers();
+
+boolean isConstructor();
+
+/**
+ * Answer the names of the argument
+ * or null if the argument names are not available.
+ */
+
+char[][] getArgumentNames();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
new file mode 100644
index 0000000..f9c03f5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface IGenericType extends IDependent {
+
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * NOTE 1: We have added AccDeprecated & AccSynthetic.
+ * NOTE 2: If the receiver represents a member type, the modifiers are extracted from its inner class attributes.
+ */
+int getModifiers();
+/**
+ * Answer whether the receiver contains the resolved binary form
+ * or the unresolved source form of the type.
+ */
+
+boolean isBinaryType();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
new file mode 100644
index 0000000..9a7a2e0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+/**
+ * The name environment provides a callback API that the compiler
+ * can use to look up types, compilation units, and packages in the
+ * current environment. The name environment is passed to the compiler
+ * on creation.
+ */
+public interface INameEnvironment {
+/**
+ * Find a type with the given compound name.
+ * Answer the binary form of the type if it is known to be consistent.
+ * Otherwise, answer the compilation unit which defines the type
+ * or null if the type does not exist.
+ * Types in the default package are specified as {{typeName}}.
+ *
+ * It is unknown whether the package containing the type actually exists.
+ *
+ * NOTE: This method can be used to find a member type using its
+ * internal name A$B, but the source file for A is answered if the binary
+ * file is inconsistent.
+ */
+
+NameEnvironmentAnswer findType(char[][] compoundTypeName);
+/**
+ * Find a type named <typeName> in the package <packageName>.
+ * Answer the binary form of the type if it is known to be consistent.
+ * Otherwise, answer the compilation unit which defines the type
+ * or null if the type does not exist.
+ * The default package is indicated by char[0][].
+ *
+ * It is known that the package containing the type exists.
+ *
+ * NOTE: This method can be used to find a member type using its
+ * internal name A$B, but the source file for A is answered if the binary
+ * file is inconsistent.
+ */
+
+NameEnvironmentAnswer findType(char[] typeName, char[][] packageName);
+/**
+ * Answer whether packageName is the name of a known subpackage inside
+ * the package parentPackageName. A top level package is found relative to null.
+ * The default package is always assumed to exist.
+ *
+ * For example:
+ *      isPackage({{java}, {awt}}, {event});
+ *      isPackage(null, {java});
+ */
+
+boolean isPackage(char[][] parentPackageName, char[] packageName);
+
+/**
+ * This method cleans the environment. It is responsible for releasing the memory
+ * and freeing resources. Passed that point, the name environment is no longer usable.
+ *
+ * A name environment can have a long life cycle, therefore it is the responsibility of
+ * the code which created it to decide when it is a good time to clean it up.
+ */
+void cleanup();
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
new file mode 100644
index 0000000..7862026
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface ISourceField extends IGenericField {
+/**
+ * Answer the source end position of the field's declaration.
+ */
+int getDeclarationSourceEnd();
+
+/**
+ * Answer the source start position of the field's declaration.
+ */
+int getDeclarationSourceStart();
+
+/**
+ * Answer the initialization source for this constant field.
+ * Answer null if the field is not a constant or if it has no initialization.
+ */
+char[] getInitializationSource();
+
+/**
+ * Answer the source end position of the field's name.
+ */
+int getNameSourceEnd();
+
+/**
+ * Answer the source start position of the field's name.
+ */
+int getNameSourceStart();
+
+/**
+ * Answer the type name of the field.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+char[] getTypeName();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java
new file mode 100644
index 0000000..a56cdd5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface ISourceImport {
+
+/**
+ * Answer the source end position of the import declaration.
+ */
+
+int getDeclarationSourceEnd();
+/**
+ * Answer the source start position of the import declaration.
+ */
+
+int getDeclarationSourceStart();
+
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ * Since Java 1.5, static imports can be defined.
+ */
+int getModifiers();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
new file mode 100644
index 0000000..4f5d029
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface ISourceMethod extends IGenericMethod {
+
+/**
+ * Answer the source end position of the method's declaration.
+ */
+
+int getDeclarationSourceEnd();
+/**
+ * Answer the source start position of the method's declaration.
+ */
+
+int getDeclarationSourceStart();
+/**
+ * Answer the unresolved names of the exception types
+ * or null if the array is empty.
+ *
+ * A name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[][] getExceptionTypeNames();
+/**
+ * Answer the source end position of the method's selector.
+ */
+
+int getNameSourceEnd();
+/**
+ * Answer the source start position of the method's selector.
+ */
+
+int getNameSourceStart();
+/**
+ * Answer the unresolved name of the return type
+ * or null if receiver is a constructor or clinit.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+
+char[] getReturnTypeName();
+/**
+ * Answer the names of the receiver's type parameters
+ * or null if the array is empty.
+ */
+char[][] getTypeParameterNames();
+/**
+ * Answer the array of bound names of the receiver's type parameters
+ * or null if the array is empty.
+ */
+char[][][] getTypeParameterBounds();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
new file mode 100644
index 0000000..f10a187
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public interface ISourceType extends IGenericType {
+
+/**
+ * Answer the source end position of the type's declaration.
+ */
+int getDeclarationSourceEnd();
+
+/**
+ * Answer the source start position of the type's declaration.
+ */
+int getDeclarationSourceStart();
+
+/**
+ * Answer the enclosing type
+ * or null if the receiver is a top level type.
+ */
+ISourceType getEnclosingType();
+
+/**
+ * Answer the receiver's fields.
+ *
+ * NOTE: Multiple fields with the same name can exist in the result.
+ */
+ISourceField[] getFields();
+
+/**
+ * Answer the unresolved names of the receiver's interfaces
+ * or null if the array is empty.
+ *
+ * A name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+char[][] getInterfaceNames();
+
+/**
+ * Answer the receiver's member types.
+ */
+ISourceType[] getMemberTypes();
+
+/**
+ * Answer the receiver's methods.
+ *
+ * NOTE: Multiple methods with the same name & parameter types can exist in the result.
+ */
+ISourceMethod[] getMethods();
+
+/**
+ * Answer the simple source name of the receiver.
+ */
+char[] getName();
+
+/**
+ * Answer the source end position of the type's name.
+ */
+int getNameSourceEnd();
+
+/**
+ * Answer the source start position of the type's name.
+ */
+int getNameSourceStart();
+
+/**
+ * Answer the unresolved name of the receiver's superclass
+ * or null if it does not have one.
+ *
+ * The name is a simple name or a qualified, dot separated name.
+ * For example, Hashtable or java.util.Hashtable.
+ */
+char[] getSuperclassName();
+/**
+ * Answer the array of bound names of the receiver's type parameters.
+ */
+char[][][] getTypeParameterBounds();
+/**
+ * Answer the names of the receiver's type parameters.
+ */
+char[][] getTypeParameterNames();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
new file mode 100644
index 0000000..f43f037
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+public class NameEnvironmentAnswer {
+
+	// only one of the three can be set
+	IBinaryType binaryType;
+	ICompilationUnit compilationUnit;
+	ISourceType[] sourceTypes;
+	AccessRestriction accessRestriction;
+
+	public NameEnvironmentAnswer(IBinaryType binaryType, AccessRestriction accessRestriction) {
+		this.binaryType = binaryType;
+		this.accessRestriction = accessRestriction;
+	}
+
+	public NameEnvironmentAnswer(ICompilationUnit compilationUnit, AccessRestriction accessRestriction) {
+		this.compilationUnit = compilationUnit;
+		this.accessRestriction = accessRestriction;
+	}
+
+	public NameEnvironmentAnswer(ISourceType[] sourceTypes, AccessRestriction accessRestriction) {
+		this.sourceTypes = sourceTypes;
+		this.accessRestriction = accessRestriction;
+	}
+	/**
+	 * Returns the associated access restriction, or null if none.
+	 */
+	public AccessRestriction getAccessRestriction() {
+		return this.accessRestriction;
+	}
+	/**
+	 * Answer the resolved binary form for the type or null if the
+	 * receiver represents a compilation unit or source type.
+	 */
+	public IBinaryType getBinaryType() {
+		return this.binaryType;
+	}
+
+	/**
+	 * Answer the compilation unit or null if the
+	 * receiver represents a binary or source type.
+	 */
+	public ICompilationUnit getCompilationUnit() {
+		return this.compilationUnit;
+	}
+
+	/**
+	 * Answer the unresolved source forms for the type or null if the
+	 * receiver represents a compilation unit or binary type.
+	 *
+	 * Multiple source forms can be answered in case the originating compilation unit did contain
+	 * several type at once. Then the first type is guaranteed to be the requested type.
+	 */
+	public ISourceType[] getSourceTypes() {
+		return this.sourceTypes;
+	}
+
+	/**
+	 * Answer whether the receiver contains the resolved binary form of the type.
+	 */
+	public boolean isBinaryType() {
+		return this.binaryType != null;
+	}
+
+	/**
+	 * Answer whether the receiver contains the compilation unit which defines the type.
+	 */
+	public boolean isCompilationUnit() {
+		return this.compilationUnit != null;
+	}
+
+	/**
+	 * Answer whether the receiver contains the unresolved source form of the type.
+	 */
+	public boolean isSourceType() {
+		return this.sourceTypes != null;
+	}
+
+	public boolean ignoreIfBetter() {
+		return this.accessRestriction != null && this.accessRestriction.ignoreIfBetter();
+	}
+
+	/*
+	 * Returns whether this answer is better than the other awswer.
+	 * (accessible is better than discouraged, which is better than
+	 * non-accessible)
+	 */
+	public boolean isBetter(NameEnvironmentAnswer otherAnswer) {
+		if (otherAnswer == null) return true;
+		if (this.accessRestriction == null) return true;
+		return otherAnswer.accessRestriction != null
+			&& this.accessRestriction.getProblemId() < otherAnswer.accessRestriction.getProblemId();
+	}
+}
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
new file mode 100644
index 0000000..288fb8f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 332637 - Dead Code detection removing code that isn't dead
+ *								bug 391517 - java.lang.VerifyError on code that runs correctly in Eclipse 3.7 and eclipse 3.6
+ *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+
+/**
+ * Record conditional initialization status during definite assignment analysis
+ *
+ */
+public class ConditionalFlowInfo extends FlowInfo {
+
+	public FlowInfo initsWhenTrue;
+	public FlowInfo initsWhenFalse;
+
+ConditionalFlowInfo(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
+
+	this.initsWhenTrue = initsWhenTrue;
+	this.initsWhenFalse = initsWhenFalse;
+	this.tagBits = initsWhenTrue.tagBits & initsWhenFalse.tagBits & UNREACHABLE;
+}
+
+public FlowInfo addInitializationsFrom(FlowInfo otherInits) {
+
+	this.initsWhenTrue.addInitializationsFrom(otherInits);
+	this.initsWhenFalse.addInitializationsFrom(otherInits);
+	return this;
+}
+
+public FlowInfo addNullInfoFrom(FlowInfo otherInits) {
+
+	this.initsWhenTrue.addNullInfoFrom(otherInits);
+	this.initsWhenFalse.addNullInfoFrom(otherInits);
+	return this;
+}
+
+public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits) {
+
+	this.initsWhenTrue.addPotentialInitializationsFrom(otherInits);
+	this.initsWhenFalse.addPotentialInitializationsFrom(otherInits);
+	return this;
+}
+
+public FlowInfo asNegatedCondition() {
+
+	FlowInfo extra = this.initsWhenTrue;
+	this.initsWhenTrue = this.initsWhenFalse;
+	this.initsWhenFalse = extra;
+	return this;
+}
+
+public FlowInfo copy() {
+
+	return new ConditionalFlowInfo(this.initsWhenTrue.copy(), this.initsWhenFalse.copy());
+}
+
+public FlowInfo initsWhenFalse() {
+
+	return this.initsWhenFalse;
+}
+
+public FlowInfo initsWhenTrue() {
+
+	return this.initsWhenTrue;
+}
+
+public boolean isDefinitelyAssigned(FieldBinding field) {
+
+	return this.initsWhenTrue.isDefinitelyAssigned(field)
+			&& this.initsWhenFalse.isDefinitelyAssigned(field);
+}
+
+public boolean isDefinitelyAssigned(LocalVariableBinding local) {
+
+	return this.initsWhenTrue.isDefinitelyAssigned(local)
+			&& this.initsWhenFalse.isDefinitelyAssigned(local);
+}
+
+public boolean isDefinitelyNonNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isDefinitelyNonNull(local)
+			&& this.initsWhenFalse.isDefinitelyNonNull(local);
+}
+
+public boolean isDefinitelyNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isDefinitelyNull(local)
+			&& this.initsWhenFalse.isDefinitelyNull(local);
+}
+
+public boolean isDefinitelyUnknown(LocalVariableBinding local) {
+	return this.initsWhenTrue.isDefinitelyUnknown(local)
+			&& this.initsWhenFalse.isDefinitelyUnknown(local);
+}
+
+public boolean hasNullInfoFor(LocalVariableBinding local) {
+	return this.initsWhenTrue.hasNullInfoFor(local) 
+			|| this.initsWhenFalse.hasNullInfoFor(local);
+}
+
+public boolean isPotentiallyAssigned(FieldBinding field) {
+	return this.initsWhenTrue.isPotentiallyAssigned(field)
+			|| this.initsWhenFalse.isPotentiallyAssigned(field);
+}
+
+public boolean isPotentiallyAssigned(LocalVariableBinding local) {
+	return this.initsWhenTrue.isPotentiallyAssigned(local)
+			|| this.initsWhenFalse.isPotentiallyAssigned(local);
+}
+
+public boolean isPotentiallyNonNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isPotentiallyNonNull(local)
+		|| this.initsWhenFalse.isPotentiallyNonNull(local);
+}
+
+public boolean isPotentiallyNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isPotentiallyNull(local)
+		|| this.initsWhenFalse.isPotentiallyNull(local);
+}
+
+public boolean isPotentiallyUnknown(LocalVariableBinding local) {
+	return this.initsWhenTrue.isPotentiallyUnknown(local)
+		|| this.initsWhenFalse.isPotentiallyUnknown(local);
+}
+
+public boolean isProtectedNonNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isProtectedNonNull(local)
+		&& this.initsWhenFalse.isProtectedNonNull(local);
+}
+
+public boolean isProtectedNull(LocalVariableBinding local) {
+	return this.initsWhenTrue.isProtectedNull(local)
+		&& this.initsWhenFalse.isProtectedNull(local);
+}
+
+public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
+	this.initsWhenTrue.markAsComparedEqualToNonNull(local);
+	this.initsWhenFalse.markAsComparedEqualToNonNull(local);
+}
+
+public void markAsComparedEqualToNull(LocalVariableBinding local) {
+	this.initsWhenTrue.markAsComparedEqualToNull(local);
+    this.initsWhenFalse.markAsComparedEqualToNull(local);
+}
+
+public void markAsDefinitelyAssigned(FieldBinding field) {
+	this.initsWhenTrue.markAsDefinitelyAssigned(field);
+	this.initsWhenFalse.markAsDefinitelyAssigned(field);
+}
+
+public void markAsDefinitelyAssigned(LocalVariableBinding local) {
+	this.initsWhenTrue.markAsDefinitelyAssigned(local);
+	this.initsWhenFalse.markAsDefinitelyAssigned(local);
+}
+
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
+	this.initsWhenTrue.markAsDefinitelyNonNull(local);
+	this.initsWhenFalse.markAsDefinitelyNonNull(local);
+}
+
+public void markAsDefinitelyNull(LocalVariableBinding local) {
+	this.initsWhenTrue.markAsDefinitelyNull(local);
+	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;
+	}
+	else {
+		this.tagBits |= reachMode;
+	}
+	this.initsWhenTrue.setReachMode(reachMode);
+	this.initsWhenFalse.setReachMode(reachMode);
+	return this;
+}
+
+public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
+	return unconditionalInits().mergedWith(otherInits);
+}
+
+public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
+	return unconditionalInitsWithoutSideEffect().
+		nullInfoLessUnconditionalCopy();
+}
+
+public String toString() {
+
+	return "FlowInfo<true: " + this.initsWhenTrue.toString() + ", false: " + this.initsWhenFalse.toString() + ">"; //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$
+}
+
+public FlowInfo safeInitsWhenTrue() {
+	return this.initsWhenTrue;
+}
+
+public UnconditionalFlowInfo unconditionalCopy() {
+	return this.initsWhenTrue.unconditionalCopy().
+			mergedWith(this.initsWhenFalse.unconditionalInits());
+}
+
+public UnconditionalFlowInfo unconditionalFieldLessCopy() {
+	return this.initsWhenTrue.unconditionalFieldLessCopy().
+		mergedWith(this.initsWhenFalse.unconditionalFieldLessCopy());
+	// should never happen, hence suboptimal does not hurt
+}
+
+public UnconditionalFlowInfo unconditionalInits() {
+	return this.initsWhenTrue.unconditionalInits().
+			mergedWith(this.initsWhenFalse.unconditionalInits());
+}
+
+public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() {
+	// cannot do better here than unconditionalCopy - but still a different
+	// operation for UnconditionalFlowInfo
+	return this.initsWhenTrue.unconditionalCopy().
+			mergedWith(this.initsWhenFalse.unconditionalInits());
+}
+
+public void resetAssignmentInfo(LocalVariableBinding local) {
+	this.initsWhenTrue.resetAssignmentInfo(local);
+	this.initsWhenFalse.resetAssignmentInfo(local);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
new file mode 100644
index 0000000..b5d6c7e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class ExceptionHandlingFlowContext extends FlowContext {
+
+	public final static int BitCacheSize = 32; // 32 bits per int
+
+	public ReferenceBinding[] handledExceptions;
+	int[] isReached;
+	int[] isNeeded;
+	// WARNING: This is an array that maps to catch blocks, not caught exceptions (which could be more than catch blocks in a multi-catch block)
+	UnconditionalFlowInfo[] initsOnExceptions; 
+	ObjectCache indexes = new ObjectCache();
+	boolean isMethodContext;
+
+	public UnconditionalFlowInfo initsOnReturn;
+	public FlowContext initializationParent; // special parent relationship only for initialization purpose
+	
+	// for dealing with anonymous constructor thrown exceptions
+	public ArrayList extendedExceptions;
+
+	private static final Argument[] NO_ARGUMENTS = new Argument[0];
+	public  Argument [] catchArguments;
+
+	private int[] exceptionToCatchBlockMap;
+
+public ExceptionHandlingFlowContext(
+			FlowContext parent,
+			ASTNode associatedNode,
+			ReferenceBinding[] handledExceptions,
+			FlowContext initializationParent,
+			BlockScope scope,
+			UnconditionalFlowInfo flowInfo) {
+	this(parent, associatedNode, handledExceptions, null, NO_ARGUMENTS, initializationParent, scope, flowInfo);
+}
+public ExceptionHandlingFlowContext(
+		FlowContext parent,
+		TryStatement tryStatement,
+		ReferenceBinding[] handledExceptions,
+		int [] exceptionToCatchBlockMap,
+		FlowContext initializationParent,
+		BlockScope scope,
+		FlowInfo flowInfo) {
+	this(parent, tryStatement, handledExceptions, exceptionToCatchBlockMap, 
+			tryStatement.catchArguments, initializationParent, scope, flowInfo.unconditionalInits());
+	this.initsOnFinally = flowInfo.unconditionalCopy();
+}
+ExceptionHandlingFlowContext(
+		FlowContext parent,
+		ASTNode associatedNode,
+		ReferenceBinding[] handledExceptions,
+		int [] exceptionToCatchBlockMap,
+		Argument [] catchArguments,
+		FlowContext initializationParent,
+		BlockScope scope,
+		UnconditionalFlowInfo flowInfo) {
+
+	super(parent, associatedNode);
+	this.isMethodContext = scope == scope.methodScope();
+	this.handledExceptions = handledExceptions;
+	this.catchArguments = catchArguments;
+	this.exceptionToCatchBlockMap = exceptionToCatchBlockMap;
+	int count = handledExceptions.length, cacheSize = (count / ExceptionHandlingFlowContext.BitCacheSize) + 1;
+	this.isReached = new int[cacheSize]; // none is reached by default
+	this.isNeeded = new int[cacheSize]; // none is needed by default
+	this.initsOnExceptions = new UnconditionalFlowInfo[count];
+	boolean markExceptionsAndThrowableAsReached =
+		!this.isMethodContext || scope.compilerOptions().reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable;
+	for (int i = 0; i < count; i++) {
+		ReferenceBinding handledException = handledExceptions[i];
+		int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[i] : i;
+		this.indexes.put(handledException, i); // key type  -> value index
+		if (handledException.isUncheckedException(true)) {
+			if (markExceptionsAndThrowableAsReached ||
+					handledException.id != TypeIds.T_JavaLangThrowable &&
+					handledException.id != TypeIds.T_JavaLangException) {
+				this.isReached[i / ExceptionHandlingFlowContext.BitCacheSize] |= 1 << (i % ExceptionHandlingFlowContext.BitCacheSize);
+			}
+			this.initsOnExceptions[catchBlock] = flowInfo.unconditionalCopy();
+		} else {
+			this.initsOnExceptions[catchBlock] = FlowInfo.DEAD_END;
+		}
+	}
+	if (!this.isMethodContext) {
+		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
+	}
+	this.initsOnReturn = FlowInfo.DEAD_END;
+	this.initializationParent = initializationParent;
+}
+
+public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) {
+	MethodScope scope = method.scope;
+	// can optionally skip overriding methods
+	if ((method.binding.modifiers & (ExtraCompilerModifiers.AccOverriding | ExtraCompilerModifiers.AccImplementing)) != 0
+	        && !scope.compilerOptions().reportUnusedDeclaredThrownExceptionWhenOverriding) {
+	    return;
+	}
+
+	// report errors for unreachable exception handlers
+	TypeBinding[] docCommentReferences = null;
+	int docCommentReferencesLength = 0;
+	if (scope.compilerOptions().
+				reportUnusedDeclaredThrownExceptionIncludeDocCommentReference &&
+			method.javadoc != null &&
+			method.javadoc.exceptionReferences != null &&
+			(docCommentReferencesLength = method.javadoc.exceptionReferences.length) > 0) {
+		docCommentReferences = new TypeBinding[docCommentReferencesLength];
+		for (int i = 0; i < docCommentReferencesLength; i++) {
+			docCommentReferences[i] = method.javadoc.exceptionReferences[i].resolvedType;
+		}
+	}
+	nextHandledException: for (int i = 0, count = this.handledExceptions.length; i < count; i++) {
+		int index = this.indexes.get(this.handledExceptions[i]);
+		if ((this.isReached[index / ExceptionHandlingFlowContext.BitCacheSize] & 1 << (index % ExceptionHandlingFlowContext.BitCacheSize)) == 0) {
+			for (int j = 0; j < docCommentReferencesLength; j++) {
+				if (docCommentReferences[j] == this.handledExceptions[i]) {
+					continue nextHandledException;
+				}
+			}
+			scope.problemReporter().unusedDeclaredThrownException(
+				this.handledExceptions[index],
+				method,
+				method.thrownExceptions[index]);
+		}
+	}
+}
+
+public void complainIfUnusedExceptionHandlers(BlockScope scope,TryStatement tryStatement) {
+	// report errors for unreachable exception handlers
+	for (int index = 0, count = this.handledExceptions.length; index < count; index++) {
+		int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize;
+		int bitMask = 1 << (index % ExceptionHandlingFlowContext.BitCacheSize);
+		if ((this.isReached[cacheIndex] & bitMask) == 0) {
+			scope.problemReporter().unreachableCatchBlock(
+				this.handledExceptions[index],
+				getExceptionType(index));
+		} else {
+			if ((this.isNeeded[cacheIndex] & bitMask) == 0) {
+				scope.problemReporter().hiddenCatchBlock(
+					this.handledExceptions[index],
+					getExceptionType(index));
+			}
+		}
+	}
+}
+
+private ASTNode getExceptionType(int index) {	
+	if (this.exceptionToCatchBlockMap == null) {
+		return this.catchArguments[index].type;
+	}
+	int catchBlock = this.exceptionToCatchBlockMap[index];
+	ASTNode node = this.catchArguments[catchBlock].type;
+	if (node instanceof UnionTypeReference) {
+		TypeReference[] typeRefs = ((UnionTypeReference)node).typeReferences;
+		for (int i = 0, len = typeRefs.length; i < len; i++) {
+			TypeReference typeRef = typeRefs[i];
+			if (typeRef.resolvedType == this.handledExceptions[index]) return typeRef;
+		}	
+	} 
+	return node;
+}
+
+
+
+public String individualToString() {
+	StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
+	int length = this.handledExceptions.length;
+	for (int i = 0; i < length; i++) {
+		int cacheIndex = i / ExceptionHandlingFlowContext.BitCacheSize;
+		int bitMask = 1 << (i % ExceptionHandlingFlowContext.BitCacheSize);
+		buffer.append('[').append(this.handledExceptions[i].readableName());
+		if ((this.isReached[cacheIndex] & bitMask) != 0) {
+			if ((this.isNeeded[cacheIndex] & bitMask) == 0) {
+				buffer.append("-masked"); //$NON-NLS-1$
+			} else {
+				buffer.append("-reached"); //$NON-NLS-1$
+			}
+		} else {
+			buffer.append("-not reached"); //$NON-NLS-1$
+		}
+		int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[i] : i;
+		buffer.append('-').append(this.initsOnExceptions[catchBlock].toString()).append(']');
+	}
+	buffer.append("[initsOnReturn -").append(this.initsOnReturn.toString()).append(']'); //$NON-NLS-1$
+	return buffer.toString();
+}
+
+// WARNING: index is the catch block index as in the program order, before any normalization is
+// applied for multi catch
+public UnconditionalFlowInfo initsOnException(int index) {
+	return this.initsOnExceptions[index];
+}
+
+public UnconditionalFlowInfo initsOnReturn(){
+	return this.initsOnReturn;
+}
+
+/*
+ * Compute a merged list of unhandled exception types (keeping only the most generic ones).
+ * This is necessary to add synthetic thrown exceptions for anonymous type constructors (JLS 8.6).
+ */
+public void mergeUnhandledException(TypeBinding newException){
+	if (this.extendedExceptions == null){
+		this.extendedExceptions = new ArrayList(5);
+		for (int i = 0; i < this.handledExceptions.length; i++){
+			this.extendedExceptions.add(this.handledExceptions[i]);
+		}
+	}
+	boolean isRedundant = false;
+
+	for(int i = this.extendedExceptions.size()-1; i >= 0; i--){
+		switch(Scope.compareTypes(newException, (TypeBinding)this.extendedExceptions.get(i))){
+			case Scope.MORE_GENERIC :
+				this.extendedExceptions.remove(i);
+				break;
+			case Scope.EQUAL_OR_MORE_SPECIFIC :
+				isRedundant = true;
+				break;
+			case Scope.NOT_RELATED :
+				break;
+		}
+	}
+	if (!isRedundant){
+		this.extendedExceptions.add(newException);
+	}
+}
+
+public void recordHandlingException(
+		ReferenceBinding exceptionType,
+		UnconditionalFlowInfo flowInfo,
+		TypeBinding raisedException,
+		TypeBinding caughtException,
+		ASTNode invocationSite,
+		boolean wasAlreadyDefinitelyCaught) {
+
+	int index = this.indexes.get(exceptionType);
+	int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize;
+	int bitMask = 1 << (index % ExceptionHandlingFlowContext.BitCacheSize);
+	if (!wasAlreadyDefinitelyCaught) {
+		this.isNeeded[cacheIndex] |= bitMask;
+	}
+	this.isReached[cacheIndex] |= bitMask;
+	int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[index] : index;
+	if (caughtException != null && this.catchArguments != null && this.catchArguments.length > 0 && !wasAlreadyDefinitelyCaught) {
+		CatchParameterBinding catchParameter = (CatchParameterBinding) this.catchArguments[catchBlock].binding;
+		catchParameter.setPreciseType(caughtException);
+	}
+	this.initsOnExceptions[catchBlock] =
+		(this.initsOnExceptions[catchBlock].tagBits & FlowInfo.UNREACHABLE) == 0 ?
+			this.initsOnExceptions[catchBlock].mergedWith(flowInfo):
+			flowInfo.unconditionalCopy();
+}
+
+public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		if ((this.initsOnReturn.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.initsOnReturn = this.initsOnReturn.mergedWith(flowInfo);
+		}
+		else {
+			this.initsOnReturn = (UnconditionalFlowInfo) flowInfo.copy();
+		}
+	}
+}
+
+/**
+ * Exception handlers (with no finally block) are also included with subroutine
+ * only once (in case parented with true InsideSubRoutineFlowContext).
+ * Standard management of subroutines need to also operate on intermediate
+ * exception handlers.
+ * @see org.eclipse.jdt.internal.compiler.flow.FlowContext#subroutine()
+ */
+public SubRoutineStatement subroutine() {
+	if (this.associatedNode instanceof SubRoutineStatement) {
+		// exception handler context may be child of InsideSubRoutineFlowContext, which maps to same handler
+		if (this.parent.subroutine() == this.associatedNode)
+			return null;
+		return (SubRoutineStatement) this.associatedNode;
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
new file mode 100644
index 0000000..d918879
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 385626 - @NonNull fails across loop boundaries
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+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.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class FinallyFlowContext extends TryFlowContext {
+
+	Reference[] finalAssignments;
+	VariableBinding[] finalVariables;
+	int assignCount;
+
+	// the following three arrays are in sync regarding their indices:
+	LocalVariableBinding[] nullLocals; // slots can be null for checkType == IN_UNBOXING
+	ASTNode[] nullReferences;	// Expressions for null checking, Statements for resource analysis
+								// cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
+	int[] nullCheckTypes;
+	int nullCount;
+	// see also the related field FlowContext#expectedTypes
+
+	// back reference to the flow context of the corresponding try statement
+	public FlowContext tryContext;
+
+	public FinallyFlowContext(FlowContext parent, ASTNode associatedNode, ExceptionHandlingFlowContext tryContext) {
+		super(parent, associatedNode);
+		this.tryContext = tryContext;
+	}
+
+/**
+ * Given some contextual initialization info (derived from a try block or a catch block), this
+ * code will check that the subroutine context does not also initialize a final variable potentially set
+ * redundantly.
+ */
+public void complainOnDeferredChecks(FlowInfo flowInfo, BlockScope scope) {
+
+	// check redundant final assignments
+	for (int i = 0; i < this.assignCount; i++) {
+		VariableBinding variable = this.finalVariables[i];
+		if (variable == null) continue;
+
+		boolean complained = false; // remember if have complained on this final assignment
+		if (variable instanceof FieldBinding) {
+			// final field
+			if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) {
+				complained = true;
+				scope.problemReporter().duplicateInitializationOfBlankFinalField((FieldBinding)variable, this.finalAssignments[i]);
+			}
+		} else {
+			// final local variable
+			if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) {
+				complained = true;
+				scope.problemReporter().duplicateInitializationOfFinalLocal(
+					(LocalVariableBinding) variable,
+					this.finalAssignments[i]);
+			}
+		}
+		// any reference reported at this level is removed from the parent context
+		// where it could also be reported again
+		if (complained) {
+			FlowContext currentContext = this.getLocalParent();
+			while (currentContext != null) {
+				//if (currentContext.isSubRoutine()) {
+				currentContext.removeFinalAssignmentIfAny(this.finalAssignments[i]);
+				//}
+				currentContext = currentContext.getLocalParent();
+			}
+		}
+	}
+
+	// check inconsistent null checks
+	if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
+		for (int i = 0; i < this.nullCount; i++) {
+			ASTNode location = this.nullReferences[i];
+			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
+				case ASSIGN_TO_NONNULL:
+					int nullStatus = flowInfo.nullStatus(this.nullLocals[i]);
+					if (nullStatus != FlowInfo.NON_NULL) {
+						this.parent.recordNullityMismatch(scope, (Expression) location,
+								this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus);
+					}
+					break;
+				case IN_UNBOXING:
+					checkUnboxing(scope, (Expression) location, flowInfo);
+					break;
+				default:
+					this.parent.recordUsingNullReference(scope, this.nullLocals[i],
+							this.nullReferences[i],	this.nullCheckTypes[i], flowInfo);
+			}
+
+		}
+	}
+	else { // no enclosing loop, be as precise as possible right now
+		for (int i = 0; i < this.nullCount; i++) {
+			ASTNode location = this.nullReferences[i];
+			// final local variable
+			LocalVariableBinding local = this.nullLocals[i];
+			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+					if (flowInfo.isDefinitelyNonNull(local)) {
+						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+								scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+							}
+						} else {
+							scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+						}
+						continue;
+					}
+					//$FALL-THROUGH$
+				case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+				case CAN_ONLY_NULL | IN_ASSIGNMENT:
+				case CAN_ONLY_NULL | IN_INSTANCEOF:
+					Expression expression = (Expression) location;
+					if (flowInfo.isDefinitelyNull(local)) {
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+									scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
+								}
+								continue;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
+								continue;
+							case FlowContext.IN_ASSIGNMENT:
+								scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
+								continue;
+							case FlowContext.IN_INSTANCEOF:
+								scope.problemReporter().localVariableNullInstanceof(local, expression);
+								continue;
+						}
+					} else if (flowInfo.isPotentiallyNull(local)) {
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+						}
+					}
+					break;
+				case MAY_NULL:
+					if (flowInfo.isDefinitelyNull(local)) {
+						scope.problemReporter().localVariableNullReference(local, location);
+						continue;
+					}
+					if (flowInfo.isPotentiallyNull(local)) {
+						scope.problemReporter().localVariablePotentialNullReference(local, location);
+					}
+					break;
+				case ASSIGN_TO_NONNULL:
+					int nullStatus = flowInfo.nullStatus(local);
+					if (nullStatus != FlowInfo.NON_NULL) {
+						char[][] annotationName = scope.environment().getNonNullAnnotationName();
+						scope.problemReporter().nullityMismatch((Expression) location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus, annotationName);
+					}
+					break;
+				case IN_UNBOXING:
+					checkUnboxing(scope, (Expression) location, flowInfo);	
+					break;
+				default:
+					// should not happen
+			}
+		}
+	}
+}
+
+	public String individualToString() {
+
+		StringBuffer buffer = new StringBuffer("Finally flow context"); //$NON-NLS-1$
+		buffer.append("[finalAssignments count - ").append(this.assignCount).append(']'); //$NON-NLS-1$
+		buffer.append("[nullReferences count - ").append(this.nullCount).append(']'); //$NON-NLS-1$
+		return buffer.toString();
+	}
+
+	public boolean isSubRoutine() {
+		return true;
+	}
+
+	protected boolean recordFinalAssignment(
+		VariableBinding binding,
+		Reference finalAssignment) {
+		if (this.assignCount == 0) {
+			this.finalAssignments = new Reference[5];
+			this.finalVariables = new VariableBinding[5];
+		} else {
+			if (this.assignCount == this.finalAssignments.length)
+				System.arraycopy(
+					this.finalAssignments,
+					0,
+					(this.finalAssignments = new Reference[this.assignCount * 2]),
+					0,
+					this.assignCount);
+			System.arraycopy(
+				this.finalVariables,
+				0,
+				(this.finalVariables = new VariableBinding[this.assignCount * 2]),
+				0,
+				this.assignCount);
+		}
+		this.finalAssignments[this.assignCount] = finalAssignment;
+		this.finalVariables[this.assignCount++] = binding;
+		return true;
+	}
+
+	public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+			ASTNode location, int checkType, FlowInfo flowInfo) {
+		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(local))	{
+			// if reference is being recorded inside an assert, we will not raise redundant null check warnings
+			checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
+			int checkTypeWithoutHideNullWarning = checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
+			if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
+				switch (checkTypeWithoutHideNullWarning) {
+					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+					case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+					case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+					case CAN_ONLY_NULL | IN_ASSIGNMENT:
+					case CAN_ONLY_NULL | IN_INSTANCEOF:
+						Expression reference = (Expression) location;
+						if (flowInfo.cannotBeNull(local)) {
+							if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+								if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
+								}
+								flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+							} else if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
+								scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
+								flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+							}
+							return;
+						}
+						if (flowInfo.canOnlyBeNull(local)) {
+							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+								case FlowContext.IN_COMPARISON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariableNullReference(local, reference);
+										return;
+									}
+									if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
+									}
+									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+									return;
+								case FlowContext.IN_COMPARISON_NON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariableNullReference(local, reference);
+										return;
+									}
+									scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
+									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+									return;
+								case FlowContext.IN_ASSIGNMENT:
+									scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
+									return;
+								case FlowContext.IN_INSTANCEOF:
+									scope.problemReporter().localVariableNullInstanceof(local, reference);
+									return;
+							}
+						} else if (flowInfo.isPotentiallyNull(local)) {
+							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+								case FlowContext.IN_COMPARISON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariablePotentialNullReference(local, reference);
+										return;
+									}
+									break;
+								case FlowContext.IN_COMPARISON_NON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariablePotentialNullReference(local, reference);
+										return;
+									}
+									break;
+							}
+						}
+						break;
+					case MAY_NULL :
+						if (flowInfo.cannotBeNull(local)) {
+							return;
+						}
+						if (flowInfo.canOnlyBeNull(local)) {
+							scope.problemReporter().localVariableNullReference(local, location);
+							return;
+						}
+						break;
+					default:
+						// never happens
+				}
+			}
+			else { // no enclosing loop, be as precise as possible right now
+				switch (checkTypeWithoutHideNullWarning) {
+					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+						if (flowInfo.isDefinitelyNonNull(local)) {
+							if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+								if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+								}
+								flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+							} else {
+								scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+								flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+							}
+							return;
+						}
+						//$FALL-THROUGH$
+					case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+					case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+					case CAN_ONLY_NULL | IN_ASSIGNMENT:
+					case CAN_ONLY_NULL | IN_INSTANCEOF:
+						Expression reference = (Expression) location;
+						if (flowInfo.isDefinitelyNull(local)) {
+							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+								case FlowContext.IN_COMPARISON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariableNullReference(local, reference);
+										return;
+									}
+									if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
+									}
+									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+									return;
+								case FlowContext.IN_COMPARISON_NON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariableNullReference(local, reference);
+										return;
+									}
+									scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
+									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+									return;
+								case FlowContext.IN_ASSIGNMENT:
+									scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
+									return;
+								case FlowContext.IN_INSTANCEOF:
+									scope.problemReporter().localVariableNullInstanceof(local, reference);
+									return;
+							}
+						} else if (flowInfo.isPotentiallyNull(local)) {
+							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+								case FlowContext.IN_COMPARISON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariablePotentialNullReference(local, reference);
+										return;
+									}
+									break;
+								case FlowContext.IN_COMPARISON_NON_NULL:
+									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+										scope.problemReporter().localVariablePotentialNullReference(local, reference);
+										return;
+									}
+									break;
+							}
+						}
+						break;
+					case MAY_NULL :
+						if (flowInfo.isDefinitelyNull(local)) {
+							scope.problemReporter().localVariableNullReference(local, location);
+							return;
+						}
+						if (flowInfo.isPotentiallyNull(local)) {
+							scope.problemReporter().localVariablePotentialNullReference(local, location);
+							return;
+						}
+						if (flowInfo.isDefinitelyNonNull(local)) {
+							return; // shortcut: cannot be null
+						}
+						break;
+					default:
+						// never happens
+				}
+			}
+			recordNullReference(local, location, checkType);
+			// prepare to re-check with try/catch flow info
+		}
+	}
+
+	void removeFinalAssignmentIfAny(Reference reference) {
+		for (int i = 0; i < this.assignCount; i++) {
+			if (this.finalAssignments[i] == reference) {
+				this.finalAssignments[i] = null;
+				this.finalVariables[i] = null;
+				return;
+			}
+		}
+	}
+
+protected void recordNullReference(LocalVariableBinding local,
+	ASTNode expression, int checkType) {
+	if (this.nullCount == 0) {
+		this.nullLocals = new LocalVariableBinding[5];
+		this.nullReferences = new ASTNode[5];
+		this.nullCheckTypes = new int[5];
+	}
+	else if (this.nullCount == this.nullLocals.length) {
+		int newLength = this.nullCount * 2;
+		System.arraycopy(this.nullLocals, 0,
+			this.nullLocals = new LocalVariableBinding[newLength], 0,
+			this.nullCount);
+		System.arraycopy(this.nullReferences, 0,
+			this.nullReferences = new ASTNode[newLength], 0,
+			this.nullCount);
+		System.arraycopy(this.nullCheckTypes, 0,
+			this.nullCheckTypes = new int[newLength], 0,
+			this.nullCount);
+	}
+	this.nullLocals[this.nullCount] = local;
+	this.nullReferences[this.nullCount] = expression;
+	this.nullCheckTypes[this.nullCount++] = checkType;
+}
+public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
+	if (nullStatus == FlowInfo.NULL)
+		super.recordUnboxing(scope, expression, nullStatus, flowInfo);
+	else // defer checking:
+		recordNullReference(null, expression, IN_UNBOXING);
+}
+protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+	// cf. decision structure inside FinallyFlowContext.recordUsingNullReference(..)
+	if (nullStatus == FlowInfo.UNKNOWN ||
+			((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0 && nullStatus != FlowInfo.NULL)) {
+		recordProvidedExpectedTypes(providedType, expectedType, this.nullCount);
+		recordNullReference(expression.localVariableBinding(), expression, checkType);
+		return true;
+	}
+	return false;
+}
+}
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
new file mode 100644
index 0000000..4804eec
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -0,0 +1,1009 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 358827 - [1.7] exception analysis for t-w-r spoils null analysis
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *								bug 402993 - [null] Follow up of bug 401088: Missing warning about redundant null check
+ *								bug 403086 - [compiler][null] include the effect of 'assert' in syntactic null analysis for fields
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *******************************************************************************/
+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.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
+import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
+import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class FlowContext implements TypeConstants {
+
+	// preempt marks looping contexts
+	public final static FlowContext NotContinuableContext = new FlowContext(null, null);
+	public ASTNode associatedNode;
+	public FlowContext parent;
+	public FlowInfo initsOnFinally;
+		// only used within try blocks; remembers upstream flow info mergedWith
+		// any null related operation happening within the try block
+	/** 
+	 * Used to record whether effects in a try block affect the finally-block
+	 * conditionally or unconditionally.
+	 * -1 means: no effect,
+	 * 0 means: unconditional effect,
+	 * > 0 means levels of nested conditional structures.
+	 */
+	public int conditionalLevel = -1;
+
+	public int tagBits;
+
+	// array to store the provided and expected types from the potential error location (for display in error messages):
+	public TypeBinding[][] providedExpectedTypes = null;
+
+	// record field references known to be non-null
+	//   this array will never shrink, only grow. reset happens by nulling the first cell
+	//   adding elements after reset ensures that the valid part of the array is always null-terminated
+	private Reference[] nullCheckedFieldReferences = null;
+	private int timeToLiveForNullCheckInfo = -1;
+
+	public static final int DEFER_NULL_DIAGNOSTIC = 0x1;
+	public static final int PREEMPT_NULL_DIAGNOSTIC = 0x2;
+	// inside an assertFalse or a not-expression checks for equality / inequality have reversed meaning for syntactic analysis for fields:
+	public static final int INSIDE_NEGATION = 0x4;
+	/**
+	 * used to hide null comparison related warnings inside assert statements 
+	 */
+	public static final int HIDE_NULL_COMPARISON_WARNING = 0x1000;
+	public static final int HIDE_NULL_COMPARISON_WARNING_MASK = 0xF000;
+
+public static final int CAN_ONLY_NULL_NON_NULL = 0x0000;
+//check against null and non null, with definite values -- comparisons
+public static final int CAN_ONLY_NULL = 0x0001;
+//check against null, with definite values -- comparisons
+public static final int CAN_ONLY_NON_NULL = 0x0002;
+//check against non null, with definite values -- comparisons
+public static final int MAY_NULL = 0x0003;
+//check binding a value to a @NonNull variable 
+public final static int ASSIGN_TO_NONNULL = 0x0080;
+//check against an unboxing conversion
+public static final int IN_UNBOXING = 0x0010;
+//check against unclosed resource at early exit:
+public static final int EXIT_RESOURCE = 0x0800;
+// check against null, with potential values -- NPE guard
+public static final int CHECK_MASK = 0x00FF;
+public static final int IN_COMPARISON_NULL = 0x0100;
+public static final int IN_COMPARISON_NON_NULL = 0x0200;
+// check happened in a comparison
+public static final int IN_ASSIGNMENT = 0x0300;
+// check happened in an assignment
+public static final int IN_INSTANCEOF = 0x0400;
+// check happened in an instanceof expression
+public static final int CONTEXT_MASK = ~CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK;
+
+public FlowContext(FlowContext parent, ASTNode associatedNode) {
+	this.parent = parent;
+	this.associatedNode = associatedNode;
+	if (parent != null) {
+		if ((parent.tagBits & (FlowContext.DEFER_NULL_DIAGNOSTIC | FlowContext.PREEMPT_NULL_DIAGNOSTIC)) != 0) {
+			this.tagBits |= FlowContext.DEFER_NULL_DIAGNOSTIC;
+		}
+		this.initsOnFinally = parent.initsOnFinally;
+		this.conditionalLevel = parent.conditionalLevel;
+		this.nullCheckedFieldReferences = parent.nullCheckedFieldReferences; // re-use list if there is one
+	}
+}
+
+/**
+ * Record that a reference to a field has been seen in a non-null state.
+ *
+ * @param reference Can be a SingleNameReference, a FieldReference or a QualifiedNameReference resolving to a field
+ * @param timeToLive control how many expire events are needed to expire this information
+ */
+public void recordNullCheckedFieldReference(Reference reference, int timeToLive) {
+	this.timeToLiveForNullCheckInfo = timeToLive;
+	if (this.nullCheckedFieldReferences == null) {
+		// first entry:
+		this.nullCheckedFieldReferences = new Reference[2];
+		this.nullCheckedFieldReferences[0] = reference;
+	} else {
+		int len = this.nullCheckedFieldReferences.length;
+		// insert into first empty slot:
+		for (int i=0; i<len; i++) {
+			if (this.nullCheckedFieldReferences[i] == null) {
+				this.nullCheckedFieldReferences[i] = reference;
+				if (i+1 < len) {
+					this.nullCheckedFieldReferences[i+1] = null; // lazily mark next as empty
+				}
+				return;
+			}
+		}
+		// grow array:
+		System.arraycopy(this.nullCheckedFieldReferences, 0, this.nullCheckedFieldReferences=new Reference[len+2], 0, len);
+		this.nullCheckedFieldReferences[len] = reference;
+	}
+}
+
+/** If a null checked field has been recorded recently, increase its time to live. */
+public void extendTimeToLiveForNullCheckedField(int t) {
+	if (this.timeToLiveForNullCheckInfo > 0)
+		this.timeToLiveForNullCheckInfo += t;
+}
+
+/**
+ * Forget any information about fields that were previously known to be non-null.
+ * 
+ * Will only cause any effect if CompilerOptions.enableSyntacticNullAnalysisForFields
+ * (implicitly by guards before calls to {@link #recordNullCheckedFieldReference(Reference, int)}).
+ */	 
+public void expireNullCheckedFieldInfo() {
+	if (this.nullCheckedFieldReferences != null) {
+		if (--this.timeToLiveForNullCheckInfo == 0) {
+			this.nullCheckedFieldReferences[0] = null; // lazily wipe
+		}
+	}
+}
+
+/** 
+ * Is the given field reference equivalent to a reference that is freshly known to be non-null?
+ * Can only return true if CompilerOptions.enableSyntacticNullAnalysisForFields
+ * (implicitly by guards before calls to {@link #recordNullCheckedFieldReference(Reference, int)}).
+ */
+public boolean isNullcheckedFieldAccess(Reference reference) {
+	if (this.nullCheckedFieldReferences == null)  // always null unless CompilerOptions.enableSyntacticNullAnalysisForFields
+		return false;
+	int len = this.nullCheckedFieldReferences.length;
+	for (int i=0; i<len; i++) {
+		Reference checked = this.nullCheckedFieldReferences[i];
+		if (checked == null) {
+			return false;
+		}
+		if (checked.isEquivalent(reference)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+public BranchLabel breakLabel() {
+	return null;
+}
+
+public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
+	checkExceptionHandlers(raisedException, location, flowInfo, scope, false);
+}
+/**
+ * @param isExceptionOnAutoClose This is for checking exception handlers for exceptions raised during the
+ * auto close of resources inside a try with resources statement. (Relevant for
+ * source levels 1.7 and above only)
+ */
+public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope, boolean isExceptionOnAutoClose) {
+	// LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS
+	// check that all the argument exception types are handled
+	// JDK Compatible implementation - when an exception type is thrown,
+	// 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;
+	if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7 && location instanceof ThrowStatement) {
+		Expression throwExpression = ((ThrowStatement)location).exception;
+		LocalVariableBinding throwArgBinding = throwExpression.localVariableBinding();
+		if (throwExpression instanceof SingleNameReference // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350361 
+				&& throwArgBinding instanceof CatchParameterBinding && throwArgBinding.isEffectivelyFinal()) {
+			CatchParameterBinding parameter = (CatchParameterBinding) throwArgBinding;
+			checkExceptionHandlers(parameter.getPreciseTypes(), location, flowInfo, scope);
+			return;
+		}
+	}
+	while (traversedContext != null) {
+		SubRoutineStatement sub;
+		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
+			// traversing a non-returning subroutine means that all unhandled
+			// exceptions will actually never get sent...
+			return;
+		}
+
+		// filter exceptions that are locally caught from the innermost enclosing
+		// try statement to the outermost ones.
+		if (traversedContext instanceof ExceptionHandlingFlowContext) {
+			ExceptionHandlingFlowContext exceptionContext =
+				(ExceptionHandlingFlowContext) traversedContext;
+			ReferenceBinding[] caughtExceptions;
+			if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
+				boolean definitelyCaught = false;
+				for (int caughtIndex = 0, caughtCount = caughtExceptions.length;
+					caughtIndex < caughtCount;
+					caughtIndex++) {
+					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
+				    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(
+								caughtException,
+								flowInfo.unconditionalInits(),
+								raisedException,
+								raisedException, // precise exception that will be caught
+								location,
+								definitelyCaught);
+							// was it already definitely caught ?
+							definitelyCaught = true;
+							break;
+						case Scope.MORE_GENERIC :
+							exceptionContext.recordHandlingException(
+								caughtException,
+								flowInfo.unconditionalInits(),
+								raisedException,
+								caughtException,
+								location,
+								false);
+							// was not caught already per construction
+					}
+				}
+				if (definitelyCaught)
+					return;
+			}
+			// method treatment for unchecked exceptions
+			if (exceptionContext.isMethodContext) {
+				if (raisedException.isUncheckedException(false))
+					return;
+
+				// anonymous constructors are allowed to throw any exceptions (their thrown exceptions
+				// clause will be fixed up later as per JLS 8.6).
+				if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){
+					AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode;
+					if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){
+
+						exceptionContext.mergeUnhandledException(raisedException);
+						return; // no need to complain, will fix up constructor exceptions
+					}
+				}
+				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());
+
+		if (!isExceptionOnAutoClose) {
+			if (traversedContext instanceof InsideSubRoutineFlowContext) {
+				ASTNode node = traversedContext.associatedNode;
+				if (node instanceof TryStatement) {
+					TryStatement tryStatement = (TryStatement) node;
+					flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
+				}
+			}
+		}
+		traversedContext = traversedContext.getLocalParent();
+	}
+	// if reaches this point, then there are some remaining unhandled exception types.
+	if (isExceptionOnAutoClose) {
+		scope.problemReporter().unhandledExceptionFromAutoClose(raisedException, location);
+	} else {
+		scope.problemReporter().unhandledException(raisedException, location);
+	}
+}
+
+public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
+	// check that all the argument exception types are handled
+	// JDK Compatible implementation - when an exception type is thrown,
+	// 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)
+	int remainingCount; // counting the number of remaining unhandled exceptions
+	int raisedCount; // total number of exceptions raised
+	if ((raisedExceptions == null)
+		|| ((raisedCount = raisedExceptions.length) == 0))
+		return;
+	remainingCount = raisedCount;
+
+	// duplicate the array of raised exceptions since it will be updated
+	// (null replaces any handled exception)
+	System.arraycopy(
+		raisedExceptions,
+		0,
+		(raisedExceptions = new TypeBinding[raisedCount]),
+		0,
+		raisedCount);
+	FlowContext traversedContext = this;
+
+	ArrayList abruptlyExitedLoops = null;
+	while (traversedContext != null) {
+		SubRoutineStatement sub;
+		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
+			// traversing a non-returning subroutine means that all unhandled
+			// exceptions will actually never get sent...
+			return;
+		}
+		// filter exceptions that are locally caught from the innermost enclosing
+		// try statement to the outermost ones.
+		if (traversedContext instanceof ExceptionHandlingFlowContext) {
+			ExceptionHandlingFlowContext exceptionContext =
+				(ExceptionHandlingFlowContext) traversedContext;
+			ReferenceBinding[] caughtExceptions;
+			if ((caughtExceptions = exceptionContext.handledExceptions) != Binding.NO_EXCEPTIONS) {
+				int caughtCount = caughtExceptions.length;
+				boolean[] locallyCaught = new boolean[raisedCount]; // at most
+
+				for (int caughtIndex = 0; caughtIndex < caughtCount; caughtIndex++) {
+					ReferenceBinding caughtException = caughtExceptions[caughtIndex];
+					for (int raisedIndex = 0; raisedIndex < raisedCount; raisedIndex++) {
+						TypeBinding raisedException;
+						if ((raisedException = raisedExceptions[raisedIndex]) != null) {
+						    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(
+										caughtException,
+										flowInfo.unconditionalInits(),
+										raisedException,
+										raisedException, // precise exception that will be caught
+										location,
+										locallyCaught[raisedIndex]);
+									// was already definitely caught ?
+									if (!locallyCaught[raisedIndex]) {
+										locallyCaught[raisedIndex] = true;
+										// remember that this exception has been definitely caught
+										remainingCount--;
+									}
+									break;
+								case Scope.MORE_GENERIC :
+									exceptionContext.recordHandlingException(
+										caughtException,
+										flowInfo.unconditionalInits(),
+										raisedException,
+										caughtException, 
+										location,
+										false);
+									// was not caught already per construction
+							}
+						}
+					}
+				}
+				// remove locally caught exceptions from the remaining ones
+				for (int i = 0; i < raisedCount; i++) {
+					if (locallyCaught[i]) {
+						raisedExceptions[i] = null; // removed from the remaining ones.
+					}
+				}
+			}
+			// method treatment for unchecked exceptions
+			if (exceptionContext.isMethodContext) {
+				for (int i = 0; i < raisedCount; i++) {
+					TypeBinding raisedException;
+					if ((raisedException = raisedExceptions[i]) != null) {
+						if (raisedException.isUncheckedException(false)) {
+							remainingCount--;
+							raisedExceptions[i] = null;
+						}
+					}
+				}
+				// anonymous constructors are allowed to throw any exceptions (their thrown exceptions
+				// clause will be fixed up later as per JLS 8.6).
+				if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){
+					AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode;
+					if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){
+
+						for (int i = 0; i < raisedCount; i++) {
+							TypeBinding raisedException;
+							if ((raisedException = raisedExceptions[i]) != null) {
+								exceptionContext.mergeUnhandledException(raisedException);
+							}
+						}
+						return; // no need to complain, will fix up constructor exceptions
+					}
+				}
+				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;
+
+		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
+
+		if (traversedContext instanceof InsideSubRoutineFlowContext) {
+			ASTNode node = traversedContext.associatedNode;
+			if (node instanceof TryStatement) {
+				TryStatement tryStatement = (TryStatement) node;
+				flowInfo.addInitializationsFrom(tryStatement.subRoutineInits); // collect inits
+			}
+		}
+		traversedContext = traversedContext.getLocalParent();
+	}
+	// if reaches this point, then there are some remaining unhandled exception types.
+	nextReport: for (int i = 0; i < raisedCount; i++) {
+		TypeBinding exception;
+		if ((exception = raisedExceptions[i]) != null) {
+			// only one complaint if same exception declared to be thrown more than once
+			for (int j = 0; j < i; j++) {
+				if (raisedExceptions[j] == exception) continue nextReport; // already reported
+			}
+			scope.problemReporter().unhandledException(exception, location);
+		}
+	}
+}
+
+public BranchLabel continueLabel() {
+	return null;
+}
+
+public FlowInfo getInitsForFinalBlankInitializationCheck(TypeBinding declaringType, FlowInfo flowInfo) {
+	FlowContext current = this;
+	FlowInfo inits = flowInfo;
+	do {
+		if (current instanceof InitializationFlowContext) {
+			InitializationFlowContext initializationContext = (InitializationFlowContext) current;
+			if (((TypeDeclaration)initializationContext.associatedNode).binding == declaringType) {
+				return inits;
+			}
+			inits = initializationContext.initsBeforeContext;
+			current = initializationContext.initializationParent;
+		} else if (current instanceof ExceptionHandlingFlowContext) {
+			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) current;
+			current = exceptionContext.initializationParent == null ? exceptionContext.getLocalParent() : exceptionContext.initializationParent;
+		} else {
+			current = current.getLocalParent();
+		}
+	} while (current != null);
+	// not found
+	return null;
+}
+
+/*
+ * lookup through break labels
+ */
+public FlowContext getTargetContextForBreakLabel(char[] labelName) {
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		char[] currentLabelName;
+		if (((currentLabelName = current.labelName()) != null)
+			&& CharOperation.equals(currentLabelName, labelName)) {
+			((LabeledStatement)current.associatedNode).bits |= ASTNode.LabelUsed;
+			if (lastNonReturningSubRoutine == null)
+				return current;
+			return lastNonReturningSubRoutine;
+		}
+		current = current.getLocalParent();
+	}
+	// not found
+	return null;
+}
+
+/*
+ * lookup through continue labels
+ */
+public FlowContext getTargetContextForContinueLabel(char[] labelName) {
+	FlowContext current = this;
+	FlowContext lastContinuable = null;
+	FlowContext lastNonReturningSubRoutine = null;
+
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		} else {
+			if (current.isContinuable()) {
+				lastContinuable = current;
+			}
+		}
+
+		char[] currentLabelName;
+		if ((currentLabelName = current.labelName()) != null && CharOperation.equals(currentLabelName, labelName)) {
+			((LabeledStatement)current.associatedNode).bits |= ASTNode.LabelUsed;
+
+			// matching label found
+			if ((lastContinuable != null)
+					&& (current.associatedNode.concreteStatement()	== lastContinuable.associatedNode)) {
+
+				if (lastNonReturningSubRoutine == null) return lastContinuable;
+				return lastNonReturningSubRoutine;
+			}
+			// label is found, but not a continuable location
+			return FlowContext.NotContinuableContext;
+		}
+		current = current.getLocalParent();
+	}
+	// not found
+	return null;
+}
+
+/*
+ * lookup a default break through breakable locations
+ */
+public FlowContext getTargetContextForDefaultBreak() {
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		if (current.isBreakable() && current.labelName() == null) {
+			if (lastNonReturningSubRoutine == null) return current;
+			return lastNonReturningSubRoutine;
+		}
+		current = current.getLocalParent();
+	}
+	// not found
+	return null;
+}
+
+/*
+ * lookup a default continue amongst continuable locations
+ */
+public FlowContext getTargetContextForDefaultContinue() {
+	FlowContext current = this, lastNonReturningSubRoutine = null;
+	while (current != null) {
+		if (current.isNonReturningContext()) {
+			lastNonReturningSubRoutine = current;
+		}
+		if (current.isContinuable()) {
+			if (lastNonReturningSubRoutine == null)
+				return current;
+			return lastNonReturningSubRoutine;
+		}
+		current = current.getLocalParent();
+	}
+	// not found
+	return null;
+}
+
+/** 
+ * Answer the parent flow context but be careful not to cross the boundary of a nested type,
+ * or null if no such parent exists. 
+ */
+public FlowContext getLocalParent() {
+	if (this.associatedNode instanceof AbstractMethodDeclaration || this.associatedNode instanceof TypeDeclaration || this.associatedNode instanceof LambdaExpression)
+		return null;
+	return this.parent;
+}
+
+public String individualToString() {
+	return "Flow context"; //$NON-NLS-1$
+}
+
+public FlowInfo initsOnBreak() {
+	return FlowInfo.DEAD_END;
+}
+
+public UnconditionalFlowInfo initsOnReturn() {
+	return FlowInfo.DEAD_END;
+}
+
+public boolean isBreakable() {
+	return false;
+}
+
+public boolean isContinuable() {
+	return false;
+}
+
+public boolean isNonReturningContext() {
+	return false;
+}
+
+public boolean isSubRoutine() {
+	return false;
+}
+
+public char[] labelName() {
+	return null;
+}
+
+/**
+ * Record a given null status of a given local variable as it will be seen in the finally block.
+ * @param local the local variable being observed
+ * @param nullStatus the null status of local at the current point in the flow
+ */
+public void markFinallyNullStatus(LocalVariableBinding local, int nullStatus) {
+	if (this.initsOnFinally == null) return;
+	if (this.conditionalLevel == -1) return;
+	if (this.conditionalLevel == 0) {
+		// node is unconditionally reached, take nullStatus as is:
+		this.initsOnFinally.markNullStatus(local, nullStatus);
+		return;
+	}
+	// node is reached only conditionally, weaken status to potentially_ and merge with previous
+	UnconditionalFlowInfo newInfo = this.initsOnFinally.unconditionalCopy();
+	newInfo.markNullStatus(local, nullStatus);
+	this.initsOnFinally = this.initsOnFinally.mergedWith(newInfo);
+}
+
+/**
+ * Merge the effect of a statement presumably contained in a try-block,
+ * i.e., record how the collected info will affect the corresponding finally-block.
+ * Precondition: caller has checked that initsOnFinally != null.
+ * @param flowInfo info after executing a statement of the try-block.
+ */
+public void mergeFinallyNullInfo(FlowInfo flowInfo) {
+	if (this.initsOnFinally == null) return;
+	if (this.conditionalLevel == -1) return;
+	if (this.conditionalLevel == 0) {
+		// node is unconditionally reached, take null info as is:
+		this.initsOnFinally.addNullInfoFrom(flowInfo);
+		return;
+	}
+	// node is reached only conditionally: merge flowInfo with existing since both paths are possible
+	this.initsOnFinally = this.initsOnFinally.mergedWith(flowInfo.unconditionalCopy());
+}
+
+/**
+ * Record the fact that an abrupt exit has been observed, one of:
+ * - potential exception (incl. unchecked exceptions)
+ * - break
+ * - continue
+ * - return
+ */
+public void recordAbruptExit() {
+	if (this.conditionalLevel > -1) {
+		this.conditionalLevel++;
+		// delegate up up-to the enclosing try-finally:
+		if (!(this instanceof ExceptionHandlingFlowContext) && this.parent != null) {
+			this.parent.recordAbruptExit();
+		}
+	}
+}
+
+public void recordBreakFrom(FlowInfo flowInfo) {
+	// default implementation: do nothing
+}
+
+public void recordBreakTo(FlowContext targetContext) {
+	// default implementation: do nothing
+}
+
+public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) {
+	// default implementation: do nothing
+}
+
+/** 
+ * Record that we found an early exit from a method while a resource is in scope.
+ * @param scope enclosing scope
+ * @param flowInfo flowInfo at the point of the early exit
+ * @param trackingVar representation of the resource
+ * @param reference the return or throw statement marking the early exit
+ * @return true if the situation has been handled by this flow context.
+ */
+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) {
+	return false; // not handled
+}
+
+protected void recordProvidedExpectedTypes(TypeBinding providedType, TypeBinding expectedType, int nullCount) {
+	if (nullCount == 0) {
+		this.providedExpectedTypes = new TypeBinding[5][];
+	} else if (this.providedExpectedTypes == null) {
+		int size = 5;
+		while (size <= nullCount) size *= 2;
+		this.providedExpectedTypes = new TypeBinding[size][];
+	}
+	else if (nullCount >= this.providedExpectedTypes.length) {
+		int oldLen = this.providedExpectedTypes.length;
+		System.arraycopy(this.providedExpectedTypes, 0,
+			this.providedExpectedTypes = new TypeBinding[nullCount * 2][], 0, oldLen);
+	}
+	this.providedExpectedTypes[nullCount] = new TypeBinding[]{providedType, expectedType};
+}
+
+protected boolean recordFinalAssignment(VariableBinding variable, Reference finalReference) {
+	return true; // keep going
+}
+
+/**
+ * Record a null reference for use by deferred checks. Only looping or
+ * finally contexts really record that information. Other contexts
+ * immediately check for unboxing.
+ * @param local the local variable involved in the check
+ * @param location the location triggering the analysis, for normal null dereference
+ *      this is an expression resolving to 'local', for resource leaks it is an
+ *      early exit statement.
+ * @param checkType the checkType against which the check must be performed; one of
+ * 		{@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
+ * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL},
+ *      {@link #CAN_ONLY_NON_NULL CAN_ONLY_NON_NULL}, potentially
+ *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
+ *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF}).
+ *      <br>
+ *      Alternatively, a {@link #IN_UNBOXING} check can e requested.
+ */
+protected void recordNullReference(LocalVariableBinding local,
+	ASTNode location, int checkType) {
+	// default implementation: do nothing
+}
+
+/**
+ * Either AST analysis or checking of a child flow context has encountered an unboxing situation.
+ * Record this fact for handling at an appropriate point in time.
+ * @param nullStatus the status as we know it so far.
+ */
+public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
+	// default: handle immediately:
+	checkUnboxing(scope, expression, flowInfo);
+}
+/** During deferred checking re-visit a previously recording unboxing situation. */
+protected void checkUnboxing(Scope scope, Expression expression, FlowInfo flowInfo) {
+	int status = expression.nullStatus(flowInfo, this);
+	if ((status & FlowInfo.NULL) != 0) {
+		scope.problemReporter().nullUnboxing(expression, expression.resolvedType);
+		return;
+	} else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) {
+		scope.problemReporter().potentialNullUnboxing(expression, expression.resolvedType);
+		return;
+	} else if ((status & FlowInfo.NON_NULL) != 0) {
+		return;
+	}
+	// not handled, perhaps our parent will eventually have something to say?
+	if (this.parent != null) {
+		this.parent.recordUnboxing(scope, expression, FlowInfo.UNKNOWN, flowInfo);
+	}
+}
+
+public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
+	// default implementation: do nothing
+}
+
+public void recordSettingFinal(VariableBinding variable, Reference finalReference, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+	// for initialization inside looping statement that effectively loops
+	FlowContext context = this;
+	while (context != null) {
+		if (!context.recordFinalAssignment(variable, finalReference)) {
+			break; // no need to keep going
+		}
+		context = context.getLocalParent();
+	}
+	}
+}
+
+/**
+ * Record a null reference for use by deferred checks. Only looping or
+ * finally contexts really record that information. The context may
+ * emit an error immediately depending on the status of local against
+ * flowInfo and its nature (only looping of finally contexts defer part
+ * of the checks; nonetheless, contexts that are nested into a looping or a
+ * finally context get affected and delegate some checks to their enclosing
+ * context).
+ * @param scope the scope into which the check is performed
+ * @param local the local variable involved in the check
+ * @param location the location triggering the analysis, for normal null dereference
+ *      this is an expression resolving to 'local', for resource leaks it is an
+ *      early exit statement.
+ * @param checkType the status against which the check must be performed; one
+ * 		of {@link #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL
+ * 		CAN_ONLY_NULL_NON_NULL}, {@link #MAY_NULL MAY_NULL}, potentially
+ *      combined with a context indicator (one of {@link #IN_COMPARISON_NULL},
+ *      {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link #IN_INSTANCEOF})
+ *      and a bit to indicate whether the reference is being recorded inside an assert, 
+ *      {@link #HIDE_NULL_COMPARISON_WARNING}
+ * @param flowInfo the flow info at the check point; deferring contexts will
+ *  	perform supplementary checks against flow info instances that cannot
+ *  	be known at the time of calling this method (they are influenced by
+ * 		code that follows the current point)
+ */
+public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+		ASTNode location, int checkType, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 ||
+			flowInfo.isDefinitelyUnknown(local)) {
+		return;
+	}
+	// if reference is being recorded inside an assert, we will not raise redundant null check warnings
+	checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
+	int checkTypeWithoutHideNullWarning = checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
+	switch (checkTypeWithoutHideNullWarning) {
+		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+			if (flowInfo.isDefinitelyNonNull(local)) {
+				if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+					if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+						scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+					}
+					flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				} else {
+					scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+					flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				}
+				return;
+			}
+			else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
+				return;
+			}
+			//$FALL-THROUGH$
+		case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+		case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+		case CAN_ONLY_NULL | IN_ASSIGNMENT:
+		case CAN_ONLY_NULL | IN_INSTANCEOF:
+			Expression reference = (Expression)location;
+			if (flowInfo.isDefinitelyNull(local)) {
+				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+					case FlowContext.IN_COMPARISON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariableNullReference(local, reference);
+							return;
+						}
+						if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
+							scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
+						}
+						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+						return;
+					case FlowContext.IN_COMPARISON_NON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariableNullReference(local, reference);
+							return;
+						}
+						scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
+						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+						return;
+					case FlowContext.IN_ASSIGNMENT:
+						scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
+						return;
+					case FlowContext.IN_INSTANCEOF:
+						scope.problemReporter().localVariableNullInstanceof(local, reference);
+						return;
+				}
+			} else if (flowInfo.isPotentiallyNull(local)) {
+				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+					case FlowContext.IN_COMPARISON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariablePotentialNullReference(local, reference);
+							return;
+						}
+						break;
+					case FlowContext.IN_COMPARISON_NON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariablePotentialNullReference(local, reference);
+							return;
+						}
+						break;
+				}
+			} else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
+				return;
+			}
+			break;
+		case MAY_NULL :
+			if (flowInfo.isDefinitelyNull(local)) {
+				scope.problemReporter().localVariableNullReference(local, location);
+				return;
+			}
+			if (flowInfo.isPotentiallyNull(local)) {
+				scope.problemReporter().localVariablePotentialNullReference(local, location);
+				return;
+			}
+			break;
+		default:
+			// never happens
+	}
+	if (this.parent != null) {
+		this.parent.recordUsingNullReference(scope, local, location, checkType,
+				flowInfo);
+	}
+}
+
+void removeFinalAssignmentIfAny(Reference reference) {
+	// default implementation: do nothing
+}
+
+public SubRoutineStatement subroutine() {
+	return null;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	FlowContext current = this;
+	int parentsCount = 0;
+	while ((current = current.parent) != null) {
+		parentsCount++;
+	}
+	FlowContext[] parents = new FlowContext[parentsCount + 1];
+	current = this;
+	int index = parentsCount;
+	while (index >= 0) {
+		parents[index--] = current;
+		current = current.parent;
+	}
+	for (int i = 0; i < parentsCount; i++) {
+		for (int j = 0; j < i; j++)
+			buffer.append('\t');
+		buffer.append(parents[i].individualToString()).append('\n');
+	}
+	buffer.append('*');
+	for (int j = 0; j < parentsCount + 1; j++)
+		buffer.append('\t');
+	buffer.append(individualToString()).append('\n');
+	return buffer.toString();
+}
+
+/**
+ * Record that a nullity mismatch was detected against an annotated type reference.
+ * @param currentScope scope for error reporting
+ * @param expression the expression violating the specification
+ * @param providedType the type of the provided value, i.e., either expression or an element thereof (in ForeachStatements)
+ * @param expectedType the declared type of the spec'ed variable, for error reporting.
+ * @param nullStatus the null status of expression at the current location
+ */
+public void recordNullityMismatch(BlockScope currentScope, Expression expression, TypeBinding providedType, TypeBinding expectedType, int nullStatus) {
+	if (providedType == null) {
+		return; // assume type error was already reported
+	}
+	if (expression.localVariableBinding() != null) { // flowContext cannot yet handle non-localvar expressions (e.g., fields)
+		// find the inner-most flowContext that might need deferred handling:
+		FlowContext currentContext = this;
+		while (currentContext != null) {
+			// some flow contexts implement deferred checking, should we participate in that?
+			int isInsideAssert = 0x0;
+			if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+				isInsideAssert = FlowContext.HIDE_NULL_COMPARISON_WARNING;
+			}
+			if (currentContext.internalRecordNullityMismatch(expression, providedType, nullStatus, expectedType, ASSIGN_TO_NONNULL | isInsideAssert))
+				return;
+			currentContext = currentContext.parent;
+		}
+	}
+	// no reason to defer, so report now:
+	char[][] annotationName = currentScope.environment().getNonNullAnnotationName();
+	currentScope.problemReporter().nullityMismatch(expression, providedType, expectedType, nullStatus, annotationName);
+}
+protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+	// nop, to be overridden in subclasses
+	return false; // not recorded
+}
+}
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
new file mode 100644
index 0000000..cb3fa8d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -0,0 +1,657 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *			     				bug 292478 - Report potentially null across variable assignment
+ *     							bug 332637 - Dead Code detection removing code that isn't dead
+ *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *******************************************************************************/
+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;
+
+public abstract class FlowInfo {
+
+	public int tagBits; // REACHABLE by default
+	public final static int REACHABLE = 0;
+	/* unreachable code 
+	 * eg. while (true);
+	 *     i++;  --> unreachable code 
+	 */
+	public final static int UNREACHABLE_OR_DEAD = 1;
+	/* unreachable code as inferred by null analysis
+	 * eg. str = null;
+	 *     if (str != null) {
+	 *        // dead code
+	 *     }
+	 */
+	public final static int UNREACHABLE_BY_NULLANALYSIS = 2;
+	/*
+	 * code unreachable in any fashion
+	 */
+	public final static int UNREACHABLE = UNREACHABLE_OR_DEAD | UNREACHABLE_BY_NULLANALYSIS;
+	public final static int NULL_FLAG_MASK = 4;
+	
+	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 {
+		DEAD_END = new UnconditionalFlowInfo();
+		DEAD_END.tagBits = UNREACHABLE;
+	}
+
+/**
+ * Add other inits to this flow info, then return this. The operation semantics
+ * are to match as closely as possible the application to this flow info of all
+ * the operations that resulted into otherInits.
+ * @param otherInits other inits to add to this
+ * @return this, modified according to otherInits information
+ */
+abstract public FlowInfo addInitializationsFrom(FlowInfo otherInits);
+
+/**
+ * Add all null information from otherInits to this flow info and return this.
+ * The operation models the effect of an unconditional sequence of this flow info
+ * and otherInits.
+ */
+abstract public FlowInfo addNullInfoFrom(FlowInfo otherInits);
+
+
+/**
+ * Compose other inits over this flow info, then return this. The operation
+ * semantics are to wave into this flow info the consequences of a possible
+ * path into the operations that resulted into otherInits. The fact that this
+ * path may be left unexecuted under peculiar conditions results into less
+ * specific results than {@link #addInitializationsFrom(FlowInfo)
+ * addInitializationsFrom}.
+ * @param otherInits other inits to compose over this
+ * @return this, modified according to otherInits information
+ */
+abstract public FlowInfo addPotentialInitializationsFrom(FlowInfo otherInits);
+
+	public FlowInfo asNegatedCondition() {
+
+		return this;
+	}
+
+	public static FlowInfo conditional(FlowInfo initsWhenTrue, FlowInfo initsWhenFalse){
+		if (initsWhenTrue == initsWhenFalse) return initsWhenTrue;
+		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
+		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
+	}
+
+/**
+ * Check whether a given local variable is known to be unable to gain a definite
+ * non null or definite null status by the use of an enclosing flow info. The
+ * semantics are that if the current flow info marks the variable as potentially
+ * unknown or else as being both potentially null and potentially non null,
+ * then it won't ever be promoted as definitely null or definitely non null. (It
+ * could still get promoted to definite unknown).
+ * @param local the variable to check
+ * @return true iff this flow info prevents local from being promoted to
+ *         definite non null or definite null against an enclosing flow info
+ */
+public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
+	return isPotentiallyUnknown(local) ||
+		isPotentiallyNonNull(local) && isPotentiallyNull(local);
+}
+
+/**
+ * Check whether a given local variable is known to be non null, either because
+ * it is definitely non null, or because is has been tested against non null.
+ * @param local the variable to ckeck
+ * @return true iff local cannot be null for this flow info
+ */
+public boolean cannotBeNull(LocalVariableBinding local) {
+	return isDefinitelyNonNull(local) || isProtectedNonNull(local);
+}
+
+/**
+ * Check whether a given local variable is known to be null, either because it
+ * is definitely null, or because is has been tested against null.
+ * @param local the variable to ckeck
+ * @return true iff local can only be null for this flow info
+ */
+public boolean canOnlyBeNull(LocalVariableBinding local) {
+	return isDefinitelyNull(local) || isProtectedNull(local);
+}
+
+/**
+ * Return a deep copy of the current instance.
+ * @return a deep copy of this flow info
+ */
+	abstract public FlowInfo copy();
+
+	public static UnconditionalFlowInfo initial(int maxFieldCount) {
+		UnconditionalFlowInfo info = new UnconditionalFlowInfo();
+		info.maxFieldCount = maxFieldCount;
+		return info;
+	}
+
+/**
+ * Return the flow info that would result from the path associated to the
+ * value false for the condition expression that generated this flow info.
+ * May be this flow info if it is not an instance of {@link
+ * ConditionalFlowInfo}. May have a side effect on subparts of this flow
+ * info (subtrees get merged).
+ * @return the flow info associated to the false branch of the condition
+ * 			that generated this flow info
+ */
+abstract public FlowInfo initsWhenFalse();
+
+/**
+ * Return the flow info that would result from the path associated to the
+ * value true for the condition expression that generated this flow info.
+ * May be this flow info if it is not an instance of {@link
+ * ConditionalFlowInfo}. May have a side effect on subparts of this flow
+ * info (subtrees get merged).
+ * @return the flow info associated to the true branch of the condition
+ * 			that generated this flow info
+ */
+	abstract public FlowInfo initsWhenTrue();
+
+	/**
+	 * Check status of definite assignment for a field.
+	 */
+	 abstract public boolean isDefinitelyAssigned(FieldBinding field);
+
+	/**
+	 * Check status of definite assignment for a local.
+	 */
+	public abstract boolean isDefinitelyAssigned(LocalVariableBinding local);
+
+/**
+ * Check status of definite non-null value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely non null for this flow info
+ */
+	public abstract boolean isDefinitelyNonNull(LocalVariableBinding local);
+
+/**
+ * Check status of definite null value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely null for this flow info
+ */
+public abstract boolean isDefinitelyNull(LocalVariableBinding local);
+
+/**
+ * Check status of definite unknown value for a given local variable.
+ * @param local the variable to ckeck
+ * @return true iff local is definitely unknown for this flow info
+ */
+public abstract boolean isDefinitelyUnknown(LocalVariableBinding local);
+
+/**
+ * Check if any null info has been recorded for a given local variable.
+ * Here even recording of 'UNKNOWN' is considered as null info.
+ */
+public abstract boolean hasNullInfoFor(LocalVariableBinding local);
+
+	/**
+	 * Check status of potential assignment for a field.
+	 */
+	 abstract public boolean isPotentiallyAssigned(FieldBinding field);
+
+	/**
+	 * Check status of potential assignment for a local variable.
+	 */
+
+	 abstract public boolean isPotentiallyAssigned(LocalVariableBinding field);
+
+/**
+ * Check status of potential null assignment for a local. Return true if there
+ * is a reasonable expectation that the variable be non null at this point.
+ * @param local LocalVariableBinding - the binding for the checked local
+ * @return true if there is a reasonable expectation that local be non null at
+ * this point
+ */
+public abstract boolean isPotentiallyNonNull(LocalVariableBinding local);
+
+/**
+ * Check status of potential null assignment for a local. Return true if there
+ * is a reasonable expectation that the variable be null at this point. This
+ * includes the protected null case, so as to augment diagnostics, but does not
+ * really check that someone deliberately assigned to null on any specific
+ * path
+ * @param local LocalVariableBinding - the binding for the checked local
+ * @return true if there is a reasonable expectation that local be null at
+ * this point
+ */
+public abstract boolean isPotentiallyNull(LocalVariableBinding local);
+
+/**
+ * Return true if the given local may have been assigned to an unknown value.
+ * @param local the local to check
+ * @return true if the given local may have been assigned to an unknown value
+ */
+public abstract boolean isPotentiallyUnknown(LocalVariableBinding local);
+
+/**
+ * Return true if the given local is protected by a test against a non null
+ * value.
+ * @param local the local to check
+ * @return true if the given local is protected by a test against a non null
+ */
+public abstract boolean isProtectedNonNull(LocalVariableBinding local);
+
+/**
+ * Return true if the given local is protected by a test against null.
+ * @param local the local to check
+ * @return true if the given local is protected by a test against null
+ */
+public abstract boolean isProtectedNull(LocalVariableBinding local);
+
+/**
+ * Record that a local variable got checked to be non null.
+ * @param local the checked local variable
+ */
+abstract public void markAsComparedEqualToNonNull(LocalVariableBinding local);
+
+/**
+ * Record that a local variable got checked to be null.
+ * @param local the checked local variable
+ */
+abstract public void markAsComparedEqualToNull(LocalVariableBinding local);
+
+	/**
+	 * Record a field got definitely assigned.
+	 */
+	abstract public void markAsDefinitelyAssigned(FieldBinding field);
+
+	/**
+	 * Record a local got definitely assigned to a non-null value.
+	 */
+	abstract public void markAsDefinitelyNonNull(LocalVariableBinding local);
+
+	/**
+	 * Record a local got definitely assigned to null.
+	 */
+	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);
+
+/**
+ * Record a local got definitely assigned to an unknown value.
+ */
+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 two single bits (NULL, NON_NULL, POTENTIALLY*..) into one.
+ * This method implements a simpler logic than the 4-bit encoding used in FlowInfo instances.
+ */
+public static int mergeNullStatus(int nullStatus1, int nullStatus2) {
+	boolean canBeNull = false;
+	boolean canBeNonNull = false;
+	switch (nullStatus1) {
+		case POTENTIALLY_NULL:
+			canBeNonNull = true;
+			//$FALL-THROUGH$
+		case NULL:
+			canBeNull = true;
+			break;
+		case POTENTIALLY_NON_NULL:
+			canBeNull = true;
+			//$FALL-THROUGH$
+		case NON_NULL:
+			canBeNonNull = true;
+			break;
+	}
+	switch (nullStatus2) {
+		case POTENTIALLY_NULL:
+			canBeNonNull = true;
+			//$FALL-THROUGH$
+		case NULL:
+			canBeNull = true;
+			break;
+		case POTENTIALLY_NON_NULL:
+			canBeNull = true;
+			//$FALL-THROUGH$
+		case NON_NULL:
+			canBeNonNull = true;
+			break;
+	}
+	if (canBeNull) {
+		if (canBeNonNull)
+			return POTENTIALLY_NULL;
+		else
+			return NULL;
+	} else {
+		if (canBeNonNull)
+			return NON_NULL;
+		else
+			return UNKNOWN;
+	}
+}
+
+/**
+ * Merge branches using optimized boolean conditions
+ */
+public static UnconditionalFlowInfo mergedOptimizedBranches(
+		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
+		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
+		boolean allowFakeDeadBranch) {
+	UnconditionalFlowInfo mergedInfo;
+	if (isOptimizedTrue){
+		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
+			mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
+				unconditionalInits();
+		}
+		else {
+			mergedInfo =
+				initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
+					nullInfoLessUnconditionalCopy()).
+				unconditionalInits();
+		}
+	}
+	else if (isOptimizedFalse) {
+		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
+			mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
+				unconditionalInits();
+		}
+		else {
+			mergedInfo =
+				initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
+					nullInfoLessUnconditionalCopy()).
+				unconditionalInits();
+		}
+	}
+	else {
+		mergedInfo = initsWhenTrue.
+			mergedWith(initsWhenFalse.unconditionalInits());
+	}
+	return mergedInfo;
+}
+
+/**
+ * Merge if-else branches using optimized boolean conditions
+ */
+public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
+		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
+		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
+		boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement,
+		boolean reportDeadCodeInKnownPattern) {
+	UnconditionalFlowInfo mergedInfo;
+	if (isOptimizedTrue){
+		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
+			if (!reportDeadCodeInKnownPattern) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
+				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
+				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
+				if (ifStatement.elseStatement == null) {
+					mergedInfo = flowInfo.unconditionalInits();
+				} else {
+					mergedInfo = initsWhenFalse.unconditionalInits();
+					if (initsWhenFalse != FlowInfo.DEAD_END) {
+						// let the definitely true status of known dead code pattern not affect the reachability
+						mergedInfo.setReachMode(flowInfo.reachMode());
+					}
+				}
+			} else {
+				mergedInfo = initsWhenFalse.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
+					unconditionalInits();
+			}
+		}
+		else {
+			mergedInfo =
+				initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
+					nullInfoLessUnconditionalCopy()).
+				unconditionalInits();
+		}
+	}
+	else if (isOptimizedFalse) {
+		if (initsWhenFalse == FlowInfo.DEAD_END && allowFakeDeadBranch) {
+			if (!reportDeadCodeInKnownPattern) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=256796
+				// do not report code even after if-else as dead as a consequence of analysis done in known dead code pattern
+				// when the CompilerOptions$reportDeadCodeInTrivialIfStatement option is disabled
+				if (ifStatement.thenStatement == null) {
+					mergedInfo = flowInfo.unconditionalInits();
+				} else {
+					mergedInfo = initsWhenTrue.unconditionalInits();
+					if (initsWhenTrue != FlowInfo.DEAD_END) {
+						// let the definitely false status of known dead code pattern not affect the reachability
+						mergedInfo.setReachMode(flowInfo.reachMode());
+					}
+				}
+			} else {
+				mergedInfo = initsWhenTrue.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD).
+					unconditionalInits();
+			}
+		}
+		else {
+			mergedInfo =
+				initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
+					nullInfoLessUnconditionalCopy()).
+				unconditionalInits();
+		}
+	}
+	else if ((flowInfo.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
+		// true or false (i.e if(true), etc) for sure
+		// We don't do this if both if and else branches themselves are in an unreachable code
+		// or if any of them is a DEAD_END (e.g. contains 'return' or 'throws')
+		mergedInfo =
+			initsWhenTrue.addPotentialInitializationsFrom(initsWhenFalse.
+				nullInfoLessUnconditionalCopy()).
+			unconditionalInits();
+		// if a variable is only initialized in one branch and not initialized in the other,
+		// then we need to cast a doubt on its initialization in the merged info
+		mergedInfo.definiteInits &= initsWhenFalse.unconditionalCopy().definiteInits;
+		
+	}
+	else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
+			(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
+		// We don't do this if both if and else branches themselves are in an unreachable code
+		// or if any of them is a DEAD_END (e.g. contains 'return' or 'throws')
+		mergedInfo = 
+			initsWhenFalse.addPotentialInitializationsFrom(initsWhenTrue.
+				nullInfoLessUnconditionalCopy()).
+			unconditionalInits();
+		// if a variable is only initialized in one branch and not initialized in the other,
+		// then we need to cast a doubt on its initialization in the merged info
+		mergedInfo.definiteInits &= initsWhenTrue.unconditionalCopy().definiteInits;
+	}
+	else {
+		mergedInfo = initsWhenTrue.
+			mergedWith(initsWhenFalse.unconditionalInits());
+	}
+	return mergedInfo;
+}
+
+/**
+ * Find out the reachability mode of this flowInfo.
+ * @return REACHABLE if this flow info is reachable, otherwise
+ *         either UNREACHABLE_OR_DEAD or UNREACHABLE_BY_NULLANALYSIS.
+ */
+public int reachMode() {
+	return this.tagBits & UNREACHABLE;
+}
+
+/**
+ * Return a flow info that carries the same information as the result of
+ * {@link #initsWhenTrue() initsWhenTrue}, but warrantied to be different
+ * from this.<br>
+ * Caveat: side effects on the result may affect components of this.
+ * @return the result of initsWhenTrue or a copy of it
+ */
+abstract public FlowInfo safeInitsWhenTrue();
+
+/**
+ * Set this flow info reach mode and return this.
+ * @param reachMode one of {@link #REACHABLE REACHABLE}, {@link #UNREACHABLE_OR_DEAD UNREACHABLE_OR_DEAD},
+ * {@link #UNREACHABLE_BY_NULLANALYSIS UNREACHABLE_BY_NULLANALYSIS} or {@link #UNREACHABLE UNREACHABLE}
+ * @return this, with the reach mode set to reachMode
+ */
+abstract public FlowInfo setReachMode(int reachMode);
+
+/**
+ * Return the intersection of this and otherInits, that is
+ * one of:<ul>
+ *   <li>the receiver updated in the following way:<ul>
+ *     <li>intersection of definitely assigned variables,
+ *     <li>union of potentially assigned variables,
+ *     <li>similar operations for null,</ul>
+ *   <li>or the receiver or otherInits if the other one is non
+ *       reachable.</ul>
+ * otherInits is not affected, and is not returned either (no
+ * need to protect the result).
+ * @param otherInits the flow info to merge with this
+ * @return the intersection of this and otherInits.
+ */
+abstract public UnconditionalFlowInfo mergedWith(
+		UnconditionalFlowInfo otherInits);
+
+/**
+ * Return a copy of this unconditional flow info, deprived from its null
+ * info. {@link #DEAD_END DEAD_END} is returned unmodified.
+ * @return a copy of this unconditional flow info deprived from its null info
+ */
+abstract public UnconditionalFlowInfo nullInfoLessUnconditionalCopy();
+
+	public String toString(){
+
+		if (this == DEAD_END){
+			return "FlowInfo.DEAD_END"; //$NON-NLS-1$
+		}
+		return super.toString();
+	}
+
+/**
+ * Return a new flow info that holds the same information as this would after
+ * a call to unconditionalInits, but leaving this info unaffected. Moreover,
+ * the result can be modified without affecting this.
+ * @return a new flow info carrying this unconditional flow info
+ */
+abstract public UnconditionalFlowInfo unconditionalCopy();
+
+/**
+ * Return a new flow info that holds the same information as this would after
+ * a call to {@link #unconditionalInits() unconditionalInits} followed by the
+ * erasure of fields specific information, but leaving this flow info unaffected.
+ * @return a new flow info carrying the unconditional flow info for local variables
+ */
+abstract public UnconditionalFlowInfo unconditionalFieldLessCopy();
+
+/**
+ * Return a flow info that merges the possible paths of execution described by
+ * this flow info. In case of an unconditional flow info, return this. In case
+ * of a conditional flow info, merge branches recursively. Caveat: this may
+ * be affected, and modifying the result may affect this.
+ * @return a flow info that merges the possible paths of execution described by
+ * 			this
+ */
+abstract public UnconditionalFlowInfo unconditionalInits();
+
+/**
+ * Return a new flow info that holds the same information as this would after
+ * a call to {@link #unconditionalInits() unconditionalInits}, but leaving
+ * this info unaffected. Side effects on the result might affect this though
+ * (consider it as read only).
+ * @return a flow info carrying this unconditional flow info
+ */
+abstract public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect();
+
+/**
+ * Resets the definite and potential initialization info for the given local variable
+ * @param local
+ */
+abstract public void resetAssignmentInfo(LocalVariableBinding local);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
new file mode 100644
index 0000000..9261ae1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class InitializationFlowContext extends ExceptionHandlingFlowContext {
+	public int exceptionCount;
+	public TypeBinding[] thrownExceptions = new TypeBinding[5];
+	public ASTNode[] exceptionThrowers = new ASTNode[5];
+	public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5];
+	public FlowInfo	initsBeforeContext;
+	
+	public InitializationFlowContext(FlowContext parent, ASTNode associatedNode, FlowInfo initsBeforeContext, FlowContext initializationParent, BlockScope scope) {
+		super(
+			parent,
+			associatedNode,
+			Binding.NO_EXCEPTIONS, // no exception allowed by default
+			initializationParent,
+			scope,
+			FlowInfo.DEAD_END);
+		this.initsBeforeContext = initsBeforeContext;
+	}
+
+	public void checkInitializerExceptions(
+		BlockScope currentScope,
+		FlowContext initializerContext,
+		FlowInfo flowInfo) {
+		for (int i = 0; i < this.exceptionCount; i++) {
+			initializerContext.checkExceptionHandlers(
+				this.thrownExceptions[i],
+				this.exceptionThrowers[i],
+				this.exceptionThrowerFlowInfos[i],
+				currentScope);
+		}
+	}
+
+	public String individualToString() {
+
+		StringBuffer buffer = new StringBuffer("Initialization flow context"); //$NON-NLS-1$
+		for (int i = 0; i < this.exceptionCount; i++) {
+			buffer.append('[').append(this.thrownExceptions[i].readableName());
+			buffer.append('-').append(this.exceptionThrowerFlowInfos[i].toString()).append(']');
+		}
+		return buffer.toString();
+	}
+
+	public void recordHandlingException(
+		ReferenceBinding exceptionType,
+		UnconditionalFlowInfo flowInfo,
+		TypeBinding raisedException,
+		TypeBinding caughtException,
+		ASTNode invocationSite,
+		boolean wasMasked) {
+
+		// even if unreachable code, need to perform unhandled exception diagnosis
+		int size = this.thrownExceptions.length;
+		if (this.exceptionCount == size) {
+			System.arraycopy(
+				this.thrownExceptions,
+				0,
+				(this.thrownExceptions = new TypeBinding[size * 2]),
+				0,
+				size);
+			System.arraycopy(
+				this.exceptionThrowers,
+				0,
+				(this.exceptionThrowers = new ASTNode[size * 2]),
+				0,
+				size);
+			System.arraycopy(
+				this.exceptionThrowerFlowInfos,
+				0,
+				(this.exceptionThrowerFlowInfos = new FlowInfo[size * 2]),
+				0,
+				size);
+		}
+		this.thrownExceptions[this.exceptionCount] = raisedException;
+		this.exceptionThrowers[this.exceptionCount] = invocationSite;
+		this.exceptionThrowerFlowInfos[this.exceptionCount++] = flowInfo.copy();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
new file mode 100644
index 0000000..915f0c0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class InsideSubRoutineFlowContext extends TryFlowContext {
+
+	public UnconditionalFlowInfo initsOnReturn;
+
+public InsideSubRoutineFlowContext(
+	FlowContext parent,
+	ASTNode associatedNode) {
+	super(parent, associatedNode);
+	this.initsOnReturn = FlowInfo.DEAD_END;
+}
+
+public String individualToString() {
+	StringBuffer buffer = new StringBuffer("Inside SubRoutine flow context"); //$NON-NLS-1$
+	buffer.append("[initsOnReturn -").append(this.initsOnReturn.toString()).append(']'); //$NON-NLS-1$
+	return buffer.toString();
+}
+
+public UnconditionalFlowInfo initsOnReturn(){
+	return this.initsOnReturn;
+}
+
+public boolean isNonReturningContext() {
+	return ((SubRoutineStatement) this.associatedNode).isSubRoutineEscaping();
+}
+
+public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+	if (this.initsOnReturn == FlowInfo.DEAD_END) {
+		this.initsOnReturn = (UnconditionalFlowInfo) flowInfo.copy();
+	} else {
+		this.initsOnReturn = this.initsOnReturn.mergedWith(flowInfo);
+	}
+	}
+}
+
+public SubRoutineStatement subroutine() {
+	return (SubRoutineStatement) this.associatedNode;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java
new file mode 100644
index 0000000..309eefc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class LabelFlowContext extends SwitchFlowContext {
+
+	public char[] labelName;
+
+public LabelFlowContext(FlowContext parent, ASTNode associatedNode, char[] labelName, BranchLabel breakLabel, BlockScope scope) {
+	super(parent, associatedNode, breakLabel, false);
+	this.labelName = labelName;
+	checkLabelValidity(scope);
+}
+
+void checkLabelValidity(BlockScope scope) {
+	// check if label was already defined above
+	FlowContext current = this.getLocalParent();
+	while (current != null) {
+		char[] currentLabelName;
+		if (((currentLabelName = current.labelName()) != null)
+			&& CharOperation.equals(currentLabelName, this.labelName)) {
+			scope.problemReporter().alreadyDefinedLabel(this.labelName, this.associatedNode);
+		}
+		current = current.getLocalParent();
+	}
+}
+
+public String individualToString() {
+	return "Label flow context [label:" + String.valueOf(this.labelName) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
+}
+
+public char[] labelName() {
+	return this.labelName;
+}
+}
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
new file mode 100644
index 0000000..2befb45
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
@@ -0,0 +1,742 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contributions for
+ *     							bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 385626 - @NonNull fails across loop boundaries
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *								bug 376263 - Bogus "Potential null pointer access" warning
+ *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
+ *								bug 406384 - Internal error with I20130413
+ *******************************************************************************/
+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.FakedTrackingVariable;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+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.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class LoopingFlowContext extends SwitchFlowContext {
+
+	public BranchLabel continueLabel;
+	public UnconditionalFlowInfo initsOnContinue = FlowInfo.DEAD_END;
+	private UnconditionalFlowInfo upstreamNullFlowInfo;
+	private LoopingFlowContext innerFlowContexts[] = null;
+	private UnconditionalFlowInfo innerFlowInfos[] = null;
+	private int innerFlowContextsCount = 0;
+	private LabelFlowContext breakTargetContexts[] = null;
+	private int breakTargetsCount = 0;
+
+	Reference finalAssignments[];
+	VariableBinding finalVariables[];
+	int assignCount = 0;
+
+	// the following three arrays are in sync regarding their indices:
+	LocalVariableBinding[] nullLocals; // slots can be null for checkType == IN_UNBOXING
+	ASTNode[] nullReferences;	// Expressions for null checking, Statements for resource analysis
+								// cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
+	int[] nullCheckTypes;
+	int nullCount;
+	// see also the related field FlowContext#expectedTypes
+
+	// 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, null, /* invocation site, irrelevant here */ true // we have no business altering the needed status.
+					);
+		}
+	}
+	private ArrayList escapingExceptionCatchSites = null;
+
+	Scope associatedScope;
+
+	public LoopingFlowContext(
+		FlowContext parent,
+		FlowInfo upstreamNullFlowInfo,
+		ASTNode associatedNode,
+		BranchLabel breakLabel,
+		BranchLabel continueLabel,
+		Scope associatedScope,
+		boolean isPreTest) {
+		super(parent, associatedNode, breakLabel, isPreTest);
+		this.tagBits |= FlowContext.PREEMPT_NULL_DIAGNOSTIC;
+			// children will defer to this, which may defer to its own parent
+		this.continueLabel = continueLabel;
+		this.associatedScope = associatedScope;
+		this.upstreamNullFlowInfo = upstreamNullFlowInfo.unconditionalCopy();
+	}
+
+/**
+ * Perform deferred checks relative to final variables duplicate initialization
+ * of lack of initialization.
+ * @param scope the scope to which this context is associated
+ * @param flowInfo the flow info against which checks must be performed
+ */
+public void complainOnDeferredFinalChecks(BlockScope scope, FlowInfo flowInfo) {
+	// complain on final assignments in loops
+	for (int i = 0; i < this.assignCount; i++) {
+		VariableBinding variable = this.finalVariables[i];
+		if (variable == null) continue;
+		boolean complained = false; // remember if have complained on this final assignment
+		if (variable instanceof FieldBinding) {
+			if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) {
+				complained = true;
+				scope.problemReporter().duplicateInitializationOfBlankFinalField(
+					(FieldBinding) variable,
+					this.finalAssignments[i]);
+			}
+		} else {
+			if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) {
+				complained = true;
+				scope.problemReporter().duplicateInitializationOfFinalLocal(
+					(LocalVariableBinding) variable,
+					this.finalAssignments[i]);
+			}
+		}
+		// any reference reported at this level is removed from the parent context where it
+		// could also be reported again
+		if (complained) {
+			FlowContext context = this.getLocalParent();
+			while (context != null) {
+				context.removeFinalAssignmentIfAny(this.finalAssignments[i]);
+				context = context.getLocalParent();
+			}
+		}
+	}
+}
+
+/**
+ * Perform deferred checks relative to the null status of local variables.
+ * @param scope the scope to which this context is associated
+ * @param callerFlowInfo the flow info against which checks must be performed
+ */
+public void complainOnDeferredNullChecks(BlockScope scope, FlowInfo callerFlowInfo) {
+	for (int i = 0 ; i < this.innerFlowContextsCount ; i++) {
+		this.upstreamNullFlowInfo.
+			addPotentialNullInfoFrom(
+				this.innerFlowContexts[i].upstreamNullFlowInfo).
+			addPotentialNullInfoFrom(this.innerFlowInfos[i]);
+	}
+	this.innerFlowContextsCount = 0;
+	FlowInfo upstreamCopy = this.upstreamNullFlowInfo.copy();
+	UnconditionalFlowInfo flowInfo = this.upstreamNullFlowInfo.
+		addPotentialNullInfoFrom(callerFlowInfo.unconditionalInitsWithoutSideEffect());
+	if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) {
+		// check only immutable null checks on innermost looping context
+		for (int i = 0; i < this.nullCount; i++) {
+			LocalVariableBinding local = this.nullLocals[i];
+			ASTNode location = this.nullReferences[i];
+			// final local variable
+			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
+				case CAN_ONLY_NON_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL:
+					if (flowInfo.isDefinitelyNonNull(local)) {
+						this.nullReferences[i] = null;
+						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL)) {
+							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+								scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+							}
+						} else {
+							scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+						}
+						continue;
+					}
+					break;
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+					if (flowInfo.isDefinitelyNonNull(local)) {
+						this.nullReferences[i] = null;
+						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+								scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+							}
+						} else {
+							scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+						}
+						continue;
+					}
+					if (flowInfo.isDefinitelyNull(local)) {
+						this.nullReferences[i] = null;
+						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
+							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+								scope.problemReporter().localVariableRedundantCheckOnNull(local, location);
+							}
+						} else {
+							scope.problemReporter().localVariableNullComparedToNonNull(local, location);
+						}
+						continue;
+					}
+					break;
+				case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+				case CAN_ONLY_NULL | IN_ASSIGNMENT:
+				case CAN_ONLY_NULL | IN_INSTANCEOF:
+					Expression expression = (Expression)location;
+					if (flowInfo.isDefinitelyNull(local)) {
+						this.nullReferences[i] = null;
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+									scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
+								}
+								continue;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
+								continue;
+							case FlowContext.IN_ASSIGNMENT:
+								scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
+								continue;
+							case FlowContext.IN_INSTANCEOF:
+								scope.problemReporter().localVariableNullInstanceof(local, expression);
+								continue;
+						}
+					} else if (flowInfo.isPotentiallyNull(local)) {
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+						}
+					}	
+					break;
+				case MAY_NULL:
+					if (flowInfo.isDefinitelyNull(local)) {
+						this.nullReferences[i] = null;
+						scope.problemReporter().localVariableNullReference(local, location);
+						continue;
+					}
+					break;
+				case ASSIGN_TO_NONNULL:
+					int nullStatus = flowInfo.nullStatus(local);
+					if (nullStatus != FlowInfo.NON_NULL) {
+						this.parent.recordNullityMismatch(scope, (Expression)location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus);
+					}
+					break;
+				case EXIT_RESOURCE:
+						FakedTrackingVariable trackingVar = local.closeTracker;
+						if (trackingVar != null) {
+							if (trackingVar.hasDefinitelyNoResource(flowInfo)) {
+								continue; // no resource - no warning.
+							}
+							if (trackingVar.isClosedInFinallyOfEnclosing(scope)) {
+								continue;
+							}
+							if (this.parent.recordExitAgainstResource(scope, flowInfo, trackingVar, location)) {
+								this.nullReferences[i] = null;
+								continue;
+							}
+						}
+					break;
+				case IN_UNBOXING:
+					checkUnboxing(scope, (Expression) location, flowInfo);
+					continue; // delegation to parent already handled in the above.
+				default:
+					// never happens
+			}
+			// https://bugs.eclipse.org/376263: avoid further deferring if the upstream info
+			// already has definite information (which might get lost for deferred checking).
+			if (!(this.nullCheckTypes[i] == MAY_NULL && upstreamCopy.isDefinitelyNonNull(local))) {
+				this.parent.recordUsingNullReference(scope, local, location,
+						this.nullCheckTypes[i], flowInfo);
+			}
+		}
+	}
+	else {
+		// check inconsistent null checks on outermost looping context
+		for (int i = 0; i < this.nullCount; i++) {
+			ASTNode location = this.nullReferences[i];
+			// final local variable
+			LocalVariableBinding local = this.nullLocals[i];
+			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+					if (flowInfo.isDefinitelyNonNull(local)) {
+						this.nullReferences[i] = null;
+						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+								scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
+							}
+						} else {
+							scope.problemReporter().localVariableNonNullComparedToNull(local, location);
+						}
+						continue;
+					}
+					//$FALL-THROUGH$
+				case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+				case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+				case CAN_ONLY_NULL | IN_ASSIGNMENT:
+				case CAN_ONLY_NULL | IN_INSTANCEOF:
+					Expression expression = (Expression) location;
+					if (flowInfo.isDefinitelyNull(local)) {
+						this.nullReferences[i] = null;
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
+									scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
+								}
+								continue;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariableNullReference(local, expression);
+									continue;
+								}
+								scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
+								continue;
+							case FlowContext.IN_ASSIGNMENT:
+								scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
+								continue;
+							case FlowContext.IN_INSTANCEOF:
+								scope.problemReporter().localVariableNullInstanceof(local, expression);
+								continue;
+						}
+					} else if (flowInfo.isPotentiallyNull(local)) {
+						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
+							case FlowContext.IN_COMPARISON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+							case FlowContext.IN_COMPARISON_NON_NULL:
+								this.nullReferences[i] = null;
+								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+									scope.problemReporter().localVariablePotentialNullReference(local, expression);
+									continue;
+								}
+								break;
+						}
+					}
+					break;
+				case MAY_NULL:
+					if (flowInfo.isDefinitelyNull(local)) {
+						this.nullReferences[i] = null;
+						scope.problemReporter().localVariableNullReference(local, location);
+						continue;
+					}
+					if (flowInfo.isPotentiallyNull(local)) {
+						this.nullReferences[i] = null;
+						scope.problemReporter().localVariablePotentialNullReference(local, location);
+						continue;
+					}
+					break;
+				case ASSIGN_TO_NONNULL:
+					int nullStatus = flowInfo.nullStatus(local);
+					if (nullStatus != FlowInfo.NON_NULL) {
+						char[][] annotationName = scope.environment().getNonNullAnnotationName();
+						scope.problemReporter().nullityMismatch((Expression) location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus, annotationName);
+					}
+					break;
+				case EXIT_RESOURCE:
+					nullStatus = flowInfo.nullStatus(local);
+					if (nullStatus != FlowInfo.NON_NULL) {
+						FakedTrackingVariable closeTracker = local.closeTracker;
+						if (closeTracker != null) {
+							if (closeTracker.hasDefinitelyNoResource(flowInfo)) {
+								continue; // no resource - no warning.
+							}
+							if (closeTracker.isClosedInFinallyOfEnclosing(scope)) {
+								continue;
+							}
+							nullStatus = closeTracker.findMostSpecificStatus(flowInfo, scope, null);
+							closeTracker.recordErrorLocation(this.nullReferences[i], nullStatus);
+							closeTracker.reportRecordedErrors(scope, nullStatus);
+							this.nullReferences[i] = null;
+							continue;
+						}
+					}
+					break;
+				case IN_UNBOXING:
+					checkUnboxing(scope, (Expression) location, flowInfo);
+					break;
+				default:
+					// never happens
+			}
+		}
+	}
+	// propagate breaks
+	this.initsOnBreak.addPotentialNullInfoFrom(flowInfo);
+	for (int i = 0; i < this.breakTargetsCount; i++) {
+		this.breakTargetContexts[i].initsOnBreak.addPotentialNullInfoFrom(flowInfo);
+	}
+}
+
+	public BranchLabel continueLabel() {
+		return this.continueLabel;
+	}
+
+	public String individualToString() {
+		StringBuffer buffer = new StringBuffer("Looping flow context"); //$NON-NLS-1$
+		buffer.append("[initsOnBreak - ").append(this.initsOnBreak.toString()).append(']'); //$NON-NLS-1$
+		buffer.append("[initsOnContinue - ").append(this.initsOnContinue.toString()).append(']'); //$NON-NLS-1$
+		buffer.append("[finalAssignments count - ").append(this.assignCount).append(']'); //$NON-NLS-1$
+		buffer.append("[nullReferences count - ").append(this.nullCount).append(']'); //$NON-NLS-1$
+		return buffer.toString();
+	}
+
+	public boolean isContinuable() {
+		return true;
+	}
+
+	public boolean isContinuedTo() {
+		return this.initsOnContinue != FlowInfo.DEAD_END;
+	}
+
+public void recordBreakTo(FlowContext targetContext) {
+	if (targetContext instanceof LabelFlowContext) {
+		int current;
+		if ((current = this.breakTargetsCount++) == 0) {
+			this.breakTargetContexts = new LabelFlowContext[2];
+		} else if (current == this.breakTargetContexts.length) {
+			System.arraycopy(this.breakTargetContexts, 0, this.breakTargetContexts = new LabelFlowContext[current + 2], 0, current);
+		}
+		this.breakTargetContexts[current] = (LabelFlowContext) targetContext;
+	}
+}
+
+public void recordContinueFrom(FlowContext innerFlowContext, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
+		if ((this.initsOnContinue.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+			this.initsOnContinue = this.initsOnContinue.
+					mergedWith(flowInfo.unconditionalInitsWithoutSideEffect());
+		}
+		else {
+			this.initsOnContinue = flowInfo.unconditionalCopy();
+		}
+		FlowContext inner = innerFlowContext;
+		while (inner != this && !(inner instanceof LoopingFlowContext)) {
+			inner = inner.parent;
+			// we know that inner is reachable from this without crossing a type boundary 
+		}
+		if (inner == this) {
+			this.upstreamNullFlowInfo.
+			addPotentialNullInfoFrom(
+					flowInfo.unconditionalInitsWithoutSideEffect());
+		}
+		else {
+			int length = 0;
+			if (this.innerFlowContexts == null) {
+				this.innerFlowContexts = new LoopingFlowContext[5];
+				this.innerFlowInfos = new UnconditionalFlowInfo[5];
+			}
+			else if (this.innerFlowContextsCount ==
+					(length = this.innerFlowContexts.length) - 1) {
+				System.arraycopy(this.innerFlowContexts, 0,
+						(this.innerFlowContexts = new LoopingFlowContext[length + 5]),
+						0, length);
+				System.arraycopy(this.innerFlowInfos, 0,
+						(this.innerFlowInfos= new UnconditionalFlowInfo[length + 5]),
+						0, length);
+			}
+			this.innerFlowContexts[this.innerFlowContextsCount] = (LoopingFlowContext) inner;
+			this.innerFlowInfos[this.innerFlowContextsCount++] =
+					flowInfo.unconditionalInitsWithoutSideEffect();
+		}
+	}
+}
+
+	protected boolean recordFinalAssignment(
+		VariableBinding binding,
+		Reference finalAssignment) {
+
+		// do not consider variables which are defined inside this loop
+		if (binding instanceof LocalVariableBinding) {
+			Scope scope = ((LocalVariableBinding) binding).declaringScope;
+			while ((scope = scope.parent) != null) {
+				if (scope == this.associatedScope)
+					return false;
+			}
+		}
+		if (this.assignCount == 0) {
+			this.finalAssignments = new Reference[5];
+			this.finalVariables = new VariableBinding[5];
+		} else {
+			if (this.assignCount == this.finalAssignments.length)
+				System.arraycopy(
+					this.finalAssignments,
+					0,
+					(this.finalAssignments = new Reference[this.assignCount * 2]),
+					0,
+					this.assignCount);
+			System.arraycopy(
+				this.finalVariables,
+				0,
+				(this.finalVariables = new VariableBinding[this.assignCount * 2]),
+				0,
+				this.assignCount);
+		}
+		this.finalAssignments[this.assignCount] = finalAssignment;
+		this.finalVariables[this.assignCount++] = binding;
+		return true;
+	}
+
+protected void recordNullReference(LocalVariableBinding local,
+	ASTNode expression, int checkType) {
+	if (this.nullCount == 0) {
+		this.nullLocals = new LocalVariableBinding[5];
+		this.nullReferences = new ASTNode[5];
+		this.nullCheckTypes = new int[5];
+	}
+	else if (this.nullCount == this.nullLocals.length) {
+		System.arraycopy(this.nullLocals, 0,
+			this.nullLocals = new LocalVariableBinding[this.nullCount * 2], 0, this.nullCount);
+		System.arraycopy(this.nullReferences, 0,
+			this.nullReferences = new ASTNode[this.nullCount * 2], 0, this.nullCount);
+		System.arraycopy(this.nullCheckTypes, 0,
+			this.nullCheckTypes = new int[this.nullCount * 2], 0, this.nullCount);
+	}
+	this.nullLocals[this.nullCount] = local;
+	this.nullReferences[this.nullCount] = expression;
+	this.nullCheckTypes[this.nullCount++] = checkType;
+}
+public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
+	if (nullStatus == FlowInfo.NULL)
+		super.recordUnboxing(scope, expression, nullStatus, flowInfo);
+	else // defer checking:
+		recordNullReference(null, expression, IN_UNBOXING);
+}
+
+/** Record the fact that we see an early exit (in 'reference') while 'trackingVar' is in scope and may be unclosed. */
+public boolean recordExitAgainstResource(BlockScope scope, FlowInfo flowInfo, FakedTrackingVariable trackingVar, ASTNode reference) {
+	LocalVariableBinding local = trackingVar.binding;
+	if (flowInfo.isDefinitelyNonNull(local)) {
+		return false;
+	}
+	if (flowInfo.isDefinitelyNull(local)) {
+		scope.problemReporter().unclosedCloseable(trackingVar, reference);
+		return true; // handled
+	}
+	if (flowInfo.isPotentiallyNull(local)) {
+		scope.problemReporter().potentiallyUnclosedCloseable(trackingVar, reference);
+		return true; // handled
+	}
+	recordNullReference(trackingVar.binding, reference, EXIT_RESOURCE);
+	return true; // handled
+}
+
+public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
+		ASTNode location, int checkType, FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 ||
+			flowInfo.isDefinitelyUnknown(local)) {
+		return;
+	}
+	// if reference is being recorded inside an assert, we will not raise redundant null check warnings
+	checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
+	int checkTypeWithoutHideNullWarning = checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
+	switch (checkTypeWithoutHideNullWarning) {
+		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
+		case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
+			Expression reference = (Expression)location;
+			if (flowInfo.isDefinitelyNonNull(local)) {
+				if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
+					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+						scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
+					}
+					flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				} else {
+					scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
+					flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				}
+			} else if (flowInfo.isDefinitelyNull(local)) {
+				if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
+					if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+						scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
+					}
+					flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				} else {
+					scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
+					flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+				}
+			} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291418
+				flowInfo.markAsDefinitelyNonNull(local);
+				recordNullReference(local, reference, checkType);
+			} else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
+				return; // no reason to complain, since there is definitely some uncertainty making the comparison relevant.
+			} else {
+					// note: pot non-null & pot null is already captured by cannotBeDefinitelyNullOrNonNull()
+					if (flowInfo.isPotentiallyNonNull(local)) {
+						// knowing 'local' can be non-null, we're only interested in seeing whether it can *only* be non-null
+						recordNullReference(local, reference, CAN_ONLY_NON_NULL | checkType & (CONTEXT_MASK|HIDE_NULL_COMPARISON_WARNING_MASK));
+					} else if (flowInfo.isPotentiallyNull(local)) {
+						// knowing 'local' can be null, we're only interested in seeing whether it can *only* be null
+						recordNullReference(local, reference, CAN_ONLY_NULL | checkType & (CONTEXT_MASK|HIDE_NULL_COMPARISON_WARNING_MASK));
+					} else {
+						recordNullReference(local, reference, checkType);
+					}
+			}
+			return;
+		case CAN_ONLY_NULL | IN_COMPARISON_NULL:
+		case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
+		case CAN_ONLY_NULL | IN_ASSIGNMENT:
+		case CAN_ONLY_NULL | IN_INSTANCEOF:
+			reference = (Expression)location;
+			if (flowInfo.isPotentiallyNonNull(local)
+					|| flowInfo.isPotentiallyUnknown(local)
+					|| flowInfo.isProtectedNonNull(local)) {
+				// if variable is not null, we are not interested in recording null reference for deferred checks.
+				// This is because CAN_ONLY_NULL means we're only interested in cases when variable can be null.
+				return;
+			}
+			if (flowInfo.isDefinitelyNull(local)) {
+				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+					case FlowContext.IN_COMPARISON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariableNullReference(local, reference);
+							return;
+						}
+						if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
+							scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
+						}
+						flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+						return;
+					case FlowContext.IN_COMPARISON_NON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariableNullReference(local, reference);
+							return;
+						}
+						scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
+						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
+						return;
+					case FlowContext.IN_ASSIGNMENT:
+						scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
+						return;
+					case FlowContext.IN_INSTANCEOF:
+						scope.problemReporter().localVariableNullInstanceof(local, reference);
+						return;
+				}
+			} else if (flowInfo.isPotentiallyNull(local)) {
+				switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
+					case FlowContext.IN_COMPARISON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariablePotentialNullReference(local, reference);
+							return;
+						}
+						break;
+					case FlowContext.IN_COMPARISON_NON_NULL:
+						if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
+							scope.problemReporter().localVariablePotentialNullReference(local, reference);
+							return;
+						}
+						break;
+				}
+			}
+			recordNullReference(local, reference, checkType);
+			return;
+		case MAY_NULL :
+			if (flowInfo.isDefinitelyNonNull(local)) {
+				return;
+			}
+			if (flowInfo.isDefinitelyNull(local)) {
+				scope.problemReporter().localVariableNullReference(local, location);
+				return;
+			}
+			if (flowInfo.isPotentiallyNull(local)) {
+				scope.problemReporter().localVariablePotentialNullReference(local, location);
+				return;
+			}
+			recordNullReference(local, location, checkType);
+			return;
+		default:
+			// never happens
+	}
+}
+
+	void removeFinalAssignmentIfAny(Reference reference) {
+		for (int i = 0; i < this.assignCount; i++) {
+			if (this.finalAssignments[i] == reference) {
+				this.finalAssignments[i] = null;
+				this.finalVariables[i] = null;
+				return;
+			}
+		}
+	}
+
+	/* 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;
+	}
+
+	protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, int nullStatus, TypeBinding expectedType, int checkType) {
+		recordProvidedExpectedTypes(providedType, expectedType, this.nullCount);
+		recordNullReference(expression.localVariableBinding(), expression, checkType);
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
new file mode 100644
index 0000000..279fff0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
+
+/**
+ * Reflects the context of code analysis, keeping track of enclosing
+ *	try statements, exception handlers, etc...
+ */
+public class SwitchFlowContext extends FlowContext {
+
+	public BranchLabel breakLabel;
+	public UnconditionalFlowInfo initsOnBreak = FlowInfo.DEAD_END;
+
+public SwitchFlowContext(FlowContext parent, ASTNode associatedNode, BranchLabel breakLabel, boolean isPreTest) {
+	super(parent, associatedNode);
+	this.breakLabel = breakLabel;
+	if (isPreTest && parent.conditionalLevel > -1) {
+		this.conditionalLevel++;
+	}
+}
+
+public BranchLabel breakLabel() {
+	return this.breakLabel;
+}
+
+public String individualToString() {
+	StringBuffer buffer = new StringBuffer("Switch flow context"); //$NON-NLS-1$
+	buffer.append("[initsOnBreak -").append(this.initsOnBreak.toString()).append(']'); //$NON-NLS-1$
+	return buffer.toString();
+}
+
+public boolean isBreakable() {
+	return true;
+}
+
+public void recordBreakFrom(FlowInfo flowInfo) {
+	if ((this.initsOnBreak.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		this.initsOnBreak = this.initsOnBreak.mergedWith(flowInfo.unconditionalInits());
+	}
+	else {
+		this.initsOnBreak = flowInfo.unconditionalCopy();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/TryFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/TryFlowContext.java
new file mode 100644
index 0000000..1623e51
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/TryFlowContext.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2013 GK Software AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+
+/**
+ * Shared implementation for try-statement-related flow contexts.
+ */
+public abstract class TryFlowContext extends FlowContext {
+
+	/**
+	 * For a try statement nested inside a finally block this reference
+	 * points to the flow context of the outer try block, for access to its initsOnFinally.
+	 */
+	public FlowContext outerTryContext;
+
+	public TryFlowContext(FlowContext parent, ASTNode associatedNode) {
+		super(parent, associatedNode);
+	}
+	
+	public void markFinallyNullStatus(LocalVariableBinding local, int nullStatus) {
+		if (this.outerTryContext != null) {
+			this.outerTryContext.markFinallyNullStatus(local, nullStatus);
+		}
+		super.markFinallyNullStatus(local, nullStatus);
+	}
+
+	public void mergeFinallyNullInfo(FlowInfo flowInfo) {
+		if (this.outerTryContext != null) {
+			this.outerTryContext.mergeFinallyNullInfo(flowInfo);
+		}
+		super.mergeFinallyNullInfo(flowInfo);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
new file mode 100644
index 0000000..4afcd8d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -0,0 +1,2100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     						bug 325755 - [compiler] wrong initialization state after conditional expression
+ *     						bug 320170 - [compiler] [null] Whitebox issues in null analysis
+ *     						bug 292478 - Report potentially null across variable assignment
+ *     						bug 332637 - Dead Code detection removing code that isn't dead
+ *     						bug 341499 - [compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo
+ *     						bug 349326 - [1.7] new warning for missing try-with-resources
+ *							bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ *							bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith()
+ *							bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.flow;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+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.TagBits;
+
+/**
+ * Record initialization status during definite assignment analysis
+ *
+ * No caching of pre-allocated instances.
+ */
+public class UnconditionalFlowInfo extends FlowInfo {
+	/**
+	 * Exception raised when unexpected behavior is detected.
+	 */
+	public static class AssertionFailedException extends RuntimeException {
+		private static final long serialVersionUID = 1827352841030089703L;
+
+	public AssertionFailedException(String message) {
+		super(message);
+	}
+	}
+
+	// Coverage tests need that the code be instrumented. The following flag
+	// controls whether the instrumented code is compiled in or not, and whether
+	// the coverage tests methods run or not.
+	public final static boolean COVERAGE_TEST_FLAG = false;
+	// never release with the coverageTestFlag set to true
+	public static int CoverageTestId;
+
+	// assignment bits - first segment
+	public long definiteInits;
+	public long potentialInits;
+
+	// null bits - first segment
+	public long
+		nullBit1,
+		nullBit2,
+		nullBit3,
+		nullBit4;
+/*
+		nullBit1
+		 nullBit2...
+		0000	start
+		0001	pot. unknown
+		0010	pot. non null
+		0011	pot. nn & pot. un
+		0100	pot. null
+		0101	pot. n & pot. un
+		0110	pot. n & pot. nn
+		0111    pot. n & pot. nn & pot. un
+		1001	def. unknown
+		1010	def. non null
+		1011	pot. nn & prot. nn
+		1100	def. null
+		1101	pot. n & prot. n
+		1110	prot. null
+		1111	prot. non null
+ */
+
+	// extra segments
+	public static final int extraLength = 6;
+	public long extra[][];
+		// extra bit fields for larger numbers of fields/variables
+		// extra[0] holds definiteInits values, extra[1] potentialInits, etc.
+		// lifecycle is extra == null or else all extra[]'s are allocated
+		// arrays which have the same size
+
+	public int maxFieldCount; // limit between fields and locals
+
+	// Constants
+	public static final int BitCacheSize = 64; // 64 bits in a long.
+
+public FlowInfo addInitializationsFrom(FlowInfo inits) {
+	return addInfoFrom(inits, true);
+}
+public FlowInfo addNullInfoFrom(FlowInfo inits) {
+	return addInfoFrom(inits, false);
+}
+private FlowInfo addInfoFrom(FlowInfo inits, boolean handleInits) {
+	if (this == DEAD_END)
+		return this;
+	if (inits == DEAD_END)
+		return this;
+	UnconditionalFlowInfo otherInits = inits.unconditionalInits();
+
+	if (handleInits) {
+		// union of definitely assigned variables,
+		this.definiteInits |= otherInits.definiteInits;
+		// union of potentially set ones
+		this.potentialInits |= otherInits.potentialInits;
+	}
+	
+	// combine null information
+	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
+		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0;
+	long
+		a1, a2, a3, a4,
+		na1, na2, na3, na4,
+		b1, b2, b3, b4,
+		nb1, nb2, nb3, nb4;
+	if (otherHasNulls) {
+		if (!thisHadNulls) {
+			this.nullBit1 = otherInits.nullBit1;
+			this.nullBit2 = otherInits.nullBit2;
+			this.nullBit3 = otherInits.nullBit3;
+			this.nullBit4 = otherInits.nullBit4;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 1) {
+				  this.nullBit4 = ~0;
+				}
+			}
+		}
+		else {
+			this.nullBit1 = (b1 = otherInits.nullBit1)
+                				| (a1 = this.nullBit1) & ((a3 = this.nullBit3)
+                					& (a4 = this.nullBit4) & (nb2 = ~(b2 = otherInits.nullBit2))
+                					& (nb4 = ~(b4 = otherInits.nullBit4))
+                        		| ((na4 = ~a4) | (na3 = ~a3))
+                        			& ((na2 = ~(a2 = this.nullBit2)) & nb2
+                        				| a2 & (nb3 = ~(b3 = otherInits.nullBit3)) & nb4));
+			this.nullBit2  = b2 & (nb4 | nb3)
+                    			| na3 & na4 & b2
+                    			| a2 & (nb3 & nb4
+                                			| (nb1 = ~b1) & (na3 | (na1 = ~a1))
+                                			| a1 & b2);
+			this.nullBit3 = b3 & (nb1 & (b2 | a2 | na1)
+                        			| b1 & (b4 | nb2 | a1 & a3)
+                         			| na1 & na2 & na4)
+                    			| a3 & nb2 & nb4
+                    			| nb1 & ((na2 & a4 | na1) & a3
+                                			| a1 & na2 & na4 & b2);
+			this.nullBit4 = nb1 & (a4 & (na3 & nb3	| (a3 | na2) & nb2)
+                      			| a1 & (a3 & nb2 & b4
+                              			| a2 & b2 & (b4	| a3 & na4 & nb3)))
+                      			| b1 & (a3 & a4 & b4
+                          			| na2 & na4 & nb3 & b4
+                          			| a2 & ((b3 | a4) & b4
+                                  				| na3 & a4 & b2 & b3)
+                          			| na1 & (b4	| (a4 | a2) & b2 & b3))
+                      			| (na1 & (na3 & nb3 | na2 & nb2)
+                      				| a1 & (nb2 & nb3 | a2 & a3)) & b4;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 2) {
+				  this.nullBit4 = ~0;
+				}
+			}
+		}
+		this.tagBits |= NULL_FLAG_MASK; // in all cases - avoid forgetting extras
+	}
+	// treating extra storage
+	if (this.extra != null || otherInits.extra != null) {
+		int mergeLimit = 0, copyLimit = 0;
+		if (this.extra != null) {
+			if (otherInits.extra != null) {
+				// both sides have extra storage
+				int length, otherLength;
+				if ((length = this.extra[0].length) <
+						(otherLength = otherInits.extra[0].length)) {
+					// current storage is shorter -> grow current
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[otherLength]), 0, length);
+					}
+					mergeLimit = length;
+					copyLimit = otherLength;
+					if (COVERAGE_TEST_FLAG) {
+						if (CoverageTestId == 3) {
+							throw new AssertionFailedException("COVERAGE 3"); //$NON-NLS-1$
+						}
+					}
+				} else {
+					// current storage is longer
+					mergeLimit = otherLength;
+					if (COVERAGE_TEST_FLAG) {
+						if (CoverageTestId == 4) {
+							throw new AssertionFailedException("COVERAGE 4"); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+		} else if (otherInits.extra != null) {
+			// no storage here, but other has extra storage.
+			// shortcut regular copy because array copy is better
+			int otherLength;
+			this.extra = new long[extraLength][];
+			System.arraycopy(otherInits.extra[0], 0,
+				(this.extra[0] = new long[otherLength =
+					otherInits.extra[0].length]), 0, otherLength);
+			System.arraycopy(otherInits.extra[1], 0,
+				(this.extra[1] = new long[otherLength]), 0, otherLength);
+			if (otherHasNulls) {
+				for (int j = 2; j < extraLength; j++) {
+					System.arraycopy(otherInits.extra[j], 0,
+						(this.extra[j] = new long[otherLength]), 0, otherLength);
+				}
+				if (COVERAGE_TEST_FLAG) {
+					if (CoverageTestId == 5) {
+						this.extra[5][otherLength - 1] = ~0;
+					}
+				}
+			}
+			else {
+				for (int j = 2; j < extraLength; j++) {
+					this.extra[j] = new long[otherLength];
+				}
+				if (COVERAGE_TEST_FLAG) {
+					if (CoverageTestId == 6) {
+						throw new AssertionFailedException("COVERAGE 6"); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		int i;
+		if (handleInits) {
+			// manage definite assignment info
+			for (i = 0; i < mergeLimit; i++) {
+				this.extra[0][i] |= otherInits.extra[0][i];
+				this.extra[1][i] |= otherInits.extra[1][i];
+			}
+			for (; i < copyLimit; i++) {
+				this.extra[0][i] = otherInits.extra[0][i];
+				this.extra[1][i] = otherInits.extra[1][i];
+			
+			}
+		}
+		// tweak limits for nulls
+		if (!thisHadNulls) {
+		    if (copyLimit < mergeLimit) {
+		      	copyLimit = mergeLimit;
+		    }
+		  	mergeLimit = 0;
+		}
+		if (!otherHasNulls) {
+		  	copyLimit = 0;
+		  	mergeLimit = 0;
+		}
+		for (i = 0; i < mergeLimit; i++) {
+			this.extra[1 + 1][i] = (b1 = otherInits.extra[1 + 1][i])
+                				| (a1 = this.extra[1 + 1][i]) & ((a3 = this.extra[3 + 1][i])
+                					& (a4 = this.extra[4 + 1][i]) & (nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
+                					& (nb4 = ~(b4 = otherInits.extra[4 + 1][i]))
+                        		| ((na4 = ~a4) | (na3 = ~a3))
+                        			& ((na2 = ~(a2 = this.extra[2 + 1][i])) & nb2
+                        				| a2 & (nb3 = ~(b3 = otherInits.extra[3 + 1][i])) & nb4));
+			this.extra[2 + 1][i]  = b2 & (nb4 | nb3)
+                    			| na3 & na4 & b2
+                    			| a2 & (nb3 & nb4
+                                			| (nb1 = ~b1) & (na3 | (na1 = ~a1))
+                                			| a1 & b2);
+			this.extra[3 + 1][i] = b3 & (nb1 & (b2 | a2 | na1)
+                        			| b1 & (b4 | nb2 | a1 & a3)
+                         			| na1 & na2 & na4)
+                    			| a3 & nb2 & nb4
+                    			| nb1 & ((na2 & a4 | na1) & a3
+                                			| a1 & na2 & na4 & b2);
+			this.extra[4 + 1][i] = nb1 & (a4 & (na3 & nb3	| (a3 | na2) & nb2)
+                      			| a1 & (a3 & nb2 & b4
+                              			| a2 & b2 & (b4	| a3 & na4 & nb3)))
+                      			| b1 & (a3 & a4 & b4
+                          			| na2 & na4 & nb3 & b4
+                          			| a2 & ((b3 | a4) & b4
+                                  				| na3 & a4 & b2 & b3)
+                          			| na1 & (b4	| (a4 | a2) & b2 & b3))
+                      			| (na1 & (na3 & nb3 | na2 & nb2)
+                      				| a1 & (nb2 & nb3 | a2 & a3)) & b4;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 7) {
+				  this.extra[5][i] = ~0;
+				}
+			}
+		}
+		for (; i < copyLimit; i++) {
+			for (int j = 2; j < extraLength; j++) {
+				this.extra[j][i] = otherInits.extra[j][i];
+			}
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 8) {
+				  this.extra[5][i] = ~0;
+				}
+			}
+		}
+	}
+	return this;
+}
+
+public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) {
+	if (this == DEAD_END){
+		return this;
+	}
+	if (inits == DEAD_END){
+		return this;
+	}
+	UnconditionalFlowInfo otherInits = inits.unconditionalInits();
+	// union of potentially set ones
+	this.potentialInits |= otherInits.potentialInits;
+	// treating extra storage
+	if (this.extra != null) {
+		if (otherInits.extra != null) {
+			// both sides have extra storage
+			int i = 0, length, otherLength;
+			if ((length = this.extra[0].length) < (otherLength = otherInits.extra[0].length)) {
+				// current storage is shorter -> grow current
+				for (int j = 0; j < extraLength; j++) {
+					System.arraycopy(this.extra[j], 0,
+						(this.extra[j] = new long[otherLength]), 0, length);
+				}
+				for (; i < length; i++) {
+					this.extra[1][i] |= otherInits.extra[1][i];
+				}
+				for (; i < otherLength; i++) {
+					this.extra[1][i] = otherInits.extra[1][i];
+				}
+			}
+			else {
+				// current storage is longer
+				for (; i < otherLength; i++) {
+					this.extra[1][i] |= otherInits.extra[1][i];
+				}
+			}
+		}
+	}
+	else if (otherInits.extra != null) {
+		// no storage here, but other has extra storage.
+		int otherLength = otherInits.extra[0].length;
+		this.extra = new long[extraLength][];
+		for (int j = 0; j < extraLength; j++) {
+			this.extra[j] = new long[otherLength];
+		}
+		System.arraycopy(otherInits.extra[1], 0, this.extra[1], 0,
+			otherLength);
+	}
+	addPotentialNullInfoFrom(otherInits);
+	return this;
+}
+
+/**
+ * Compose other inits over this flow info, then return this. The operation
+ * semantics are to wave into this flow info the consequences upon null
+ * information of a possible path into the operations that resulted into
+ * otherInits. The fact that this path may be left unexecuted under peculiar
+ * conditions results into less specific results than
+ * {@link #addInitializationsFrom(FlowInfo) addInitializationsFrom}; moreover,
+ * only the null information is affected.
+ * @param otherInits other null inits to compose over this
+ * @return this, modified according to otherInits information
+ */
+public UnconditionalFlowInfo addPotentialNullInfoFrom(
+		UnconditionalFlowInfo otherInits) {
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(otherInits.tagBits & UNREACHABLE) != 0 ||
+			(otherInits.tagBits & NULL_FLAG_MASK) == 0) {
+		return this;
+	}
+	// if we get here, otherInits has some null info
+	boolean thisHadNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
+		thisHasNulls = false;
+	long a1, a2, a3, a4,
+		na1, na2, na3, na4,
+		b1, b2, b3, b4,
+		nb1, nb2, nb3, nb4;
+	if (thisHadNulls) {
+		this.nullBit1  = (a1 = this.nullBit1)
+								& ((a3 = this.nullBit3) & (a4 = this.nullBit4)
+									& ((nb2 = ~(b2 = otherInits.nullBit2))
+										& (nb4 = ~(b4 = otherInits.nullBit4))
+											| (b1 = otherInits.nullBit1) & (b3 = otherInits.nullBit3))
+                			| (na2 = ~(a2 = this.nullBit2))
+                				& (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2)
+                			| a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2)));
+		this.nullBit2 = b2 & (nb3 | (nb1 = ~b1))
+    			| a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
+		this.nullBit3 = b3 & (nb1 & b2
+            		| a2 & (nb2	| a3)
+            		| na1 & nb2
+            		| a1 & na2 & na4 & b1)
+    			| a3 & (nb2 & nb4 | na2 & a4 | na1)
+    			| a1 & na2 & na4 & b2;
+		this.nullBit4 = na3 & (nb1 & nb3 & b4
+    				| a4 & (nb3 | b1 & b2))
+    			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
+    			| a3 & (a4 & (nb2 | b1 & b3)
+            			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
+		if (COVERAGE_TEST_FLAG) {
+			if (CoverageTestId == 9) {
+			  this.nullBit4 = ~0;
+			}
+		}
+		if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { //  bit1 is redundant
+		  	thisHasNulls = true;
+		}
+	} else {
+  		this.nullBit1 = 0;
+  		this.nullBit2 = (b2 = otherInits.nullBit2)
+  							& ((nb3 = ~(b3 = otherInits.nullBit3)) |
+  								(nb1 = ~(b1 = otherInits.nullBit1)));
+  		this.nullBit3 = b3 & (nb1 | (nb2 = ~b2));
+  		this.nullBit4 = ~b1 & ~b3 & (b4 = otherInits.nullBit4) | ~b2 & (b1 & ~b3 | ~b1 & b4);
+		if (COVERAGE_TEST_FLAG) {
+			if (CoverageTestId == 10) {
+			  this.nullBit4 = ~0;
+			}
+		}
+		if ((this.nullBit2 | this.nullBit3 | this.nullBit4) != 0) { //  bit1 is redundant
+		  	thisHasNulls = true;
+		}
+	}
+	// extra storage management
+	if (otherInits.extra != null) {
+		int mergeLimit = 0, copyLimit = otherInits.extra[0].length;
+		if (this.extra == null) {
+			this.extra = new long[extraLength][];
+			for (int j = 0; j < extraLength; j++) {
+				this.extra[j] = new long[copyLimit];
+			}
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 11) {
+					throw new AssertionFailedException("COVERAGE 11"); //$NON-NLS-1$
+				}
+			}
+		} else {
+			mergeLimit = copyLimit;
+			if (mergeLimit > this.extra[0].length) {
+				mergeLimit = this.extra[0].length;
+				for (int j = 0; j < extraLength; j++) {
+					System.arraycopy(this.extra[j], 0,
+							this.extra[j] = new long[copyLimit], 0,
+							mergeLimit);
+				}
+				if (! thisHadNulls) {
+    				mergeLimit = 0;
+    				// will do with a copy -- caveat: only valid because definite assignment bits copied above
+        			if (COVERAGE_TEST_FLAG) {
+        				if (CoverageTestId == 12) {
+							throw new AssertionFailedException("COVERAGE 12"); //$NON-NLS-1$
+        				}
+        			}
+				}
+			}
+		}
+		// PREMATURE skip operations for fields
+		int i;
+		for (i = 0 ; i < mergeLimit ; i++) {
+    		this.extra[1 + 1][i]  = (a1 = this.extra[1 + 1][i])
+    								& ((a3 = this.extra[3 + 1][i]) & (a4 = this.extra[4 + 1][i])
+    									& ((nb2 = ~(b2 = otherInits.extra[2 + 1][i]))
+    										& (nb4 = ~(b4 = otherInits.extra[4 + 1][i]))
+    											| (b1 = otherInits.extra[1 + 1][i]) & (b3 = otherInits.extra[3 + 1][i]))
+                    			| (na2 = ~(a2 = this.extra[2 + 1][i]))
+                    				& (b1 & b3 | ((na4 = ~a4) | (na3 = ~a3)) & nb2)
+                    			| a2 & ((na4 | na3) & ((nb3 = ~b3) & nb4 | b1 & b2)));
+    		this.extra[2 + 1][i] = b2 & (nb3 | (nb1 = ~b1))
+        			| a2 & (nb3 & nb4 | b2 | na3 | (na1 = ~a1));
+    		this.extra[3 + 1][i] = b3 & (nb1 & b2
+                		| a2 & (nb2	| a3)
+                		| na1 & nb2
+                		| a1 & na2 & na4 & b1)
+        			| a3 & (nb2 & nb4 | na2 & a4 | na1)
+        			| a1 & na2 & na4 & b2;
+    		this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
+        				| a4 & (nb3 | b1 & b2))
+        			| nb2 & (na3 & b1 & nb3	| na2 & (nb1 & b4 | b1 & nb3 | a4))
+        			| a3 & (a4 & (nb2 | b1 & b3)
+                			| a1 & a2 & (nb1 & b4 | na4 & (b2 | b1) & nb3));
+    		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
+    		  	thisHasNulls = true;
+    		}
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 13) {
+				  this.nullBit4 = ~0;
+				}
+			}
+		}
+		for (; i < copyLimit; i++) {
+    		this.extra[1 + 1][i] = 0;
+    		this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i])
+    							& ((nb3 = ~(b3 = otherInits.extra[3 + 1][i])) |
+    								(nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
+    		this.extra[3 + 1][i] = b3 & (nb1 | (nb2 = ~b2));
+    		this.extra[4 + 1][i] = ~b1 & ~b3 & (b4 = otherInits.extra[4 + 1][i]) | ~b2 & (b1 & ~b3 | ~b1 & b4);
+    		if ((this.extra[2 + 1][i] | this.extra[3 + 1][i] | this.extra[4 + 1][i]) != 0) { //  bit1 is redundant
+    		  	thisHasNulls = true;
+    		}
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 14) {
+				  this.extra[5][i] = ~0;
+				}
+			}
+		}
+	}
+	if (thisHasNulls) {
+		this.tagBits |= NULL_FLAG_MASK;
+	}
+	else {
+		this.tagBits &= NULL_FLAG_MASK;
+	}
+	return this;
+}
+
+final public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return (
+			(~this.nullBit1
+					& (this.nullBit2 & this.nullBit3 | this.nullBit4)
+				| ~this.nullBit2 & ~this.nullBit3 & this.nullBit4)
+			& (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	long a2, a3, a4;
+	return (
+			(~this.extra[2][vectorIndex]
+					& ((a2 = this.extra[3][vectorIndex]) & (a3 = this.extra[4][vectorIndex]) | (a4 = this.extra[5][vectorIndex]))
+				| ~a2 & ~a3 & a4)
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean cannotBeNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return (this.nullBit1 & this.nullBit3
+			& ((this.nullBit2 & this.nullBit4) | ~this.nullBit2)
+			& (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return (this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
+	        & ((this.extra[3][vectorIndex] & this.extra[5][vectorIndex]) |
+	        		~this.extra[3][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean canOnlyBeNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return (this.nullBit1 & this.nullBit2
+			& (~this.nullBit3 | ~this.nullBit4)
+			& (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
+	        & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+public FlowInfo copy() {
+	// do not clone the DeadEnd
+	if (this == DEAD_END) {
+		return this;
+	}
+	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
+	// copy slots
+	copy.definiteInits = this.definiteInits;
+	copy.potentialInits = this.potentialInits;
+	boolean hasNullInfo = (this.tagBits & NULL_FLAG_MASK) != 0;
+	if (hasNullInfo) {
+		copy.nullBit1 = this.nullBit1;
+		copy.nullBit2 = this.nullBit2;
+		copy.nullBit3 = this.nullBit3;
+		copy.nullBit4 = this.nullBit4;
+	}
+	copy.tagBits = this.tagBits;
+	copy.maxFieldCount = this.maxFieldCount;
+	if (this.extra != null) {
+		int length;
+		copy.extra = new long[extraLength][];
+		System.arraycopy(this.extra[0], 0,
+			(copy.extra[0] = new long[length = this.extra[0].length]), 0,
+			length);
+		System.arraycopy(this.extra[1], 0,
+			(copy.extra[1] = new long[length]), 0, length);
+		if (hasNullInfo) {
+			for (int j = 2; j < extraLength; j++) {
+				System.arraycopy(this.extra[j], 0,
+					(copy.extra[j] = new long[length]), 0, length);
+			}
+		}
+		else {
+			for (int j = 2; j < extraLength; j++) {
+				copy.extra[j] = new long[length];
+			}
+		}
+	}
+	return copy;
+}
+
+/**
+ * Discard definite inits and potential inits from this, then return this.
+ * The returned flow info only holds null related information.
+ * @return this flow info, minus definite inits and potential inits
+ */
+public UnconditionalFlowInfo discardInitializationInfo() {
+	if (this == DEAD_END) {
+		return this;
+	}
+	this.definiteInits =
+		this.potentialInits = 0;
+	if (this.extra != null) {
+		for (int i = 0, length = this.extra[0].length; i < length; i++) {
+			this.extra[0][i] = this.extra[1][i] = 0;
+		}
+	}
+	return this;
+}
+
+/**
+ * Remove local variables information from this flow info and return this.
+ * @return this, deprived from any local variable information
+ */
+public UnconditionalFlowInfo discardNonFieldInitializations() {
+	int limit = this.maxFieldCount;
+	if (limit < BitCacheSize) {
+		long mask = (1L << limit)-1;
+		this.definiteInits &= mask;
+		this.potentialInits &= mask;
+		this.nullBit1 &= mask;
+		this.nullBit2 &= mask;
+		this.nullBit3 &= mask;
+		this.nullBit4 &= mask;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return this; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex, length = this.extra[0].length;
+	if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) {
+		return this; // not enough room yet
+	}
+	if (vectorIndex >= 0) {
+		// else we only have complete non field array items left
+		long mask = (1L << (limit % BitCacheSize))-1;
+		for (int j = 0; j < extraLength; j++) {
+			this.extra[j][vectorIndex] &= mask;
+		}
+	}
+	for (int i = vectorIndex + 1; i < length; i++) {
+		for (int j = 0; j < extraLength; j++) {
+			this.extra[j][i] = 0;
+		}
+	}
+	return this;
+}
+
+public FlowInfo initsWhenFalse() {
+	return this;
+}
+
+public FlowInfo initsWhenTrue() {
+	return this;
+}
+
+/**
+ * Check status of definite assignment at a given position.
+ * It deals with the dual representation of the InitializationInfo2:
+ * bits for the first 64 entries, then an array of booleans.
+ */
+final private boolean isDefinitelyAssigned(int position) {
+	if (position < BitCacheSize) {
+		// use bits
+		return (this.definiteInits & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null)
+		return false; // if vector not yet allocated, then not initialized
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1)
+			>= this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[0][vectorIndex]) &
+				(1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isDefinitelyAssigned(FieldBinding field) {
+	// Mirrored in CodeStream.isDefinitelyAssigned(..)
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
+		return true;
+	}
+	return isDefinitelyAssigned(field.id);
+}
+
+final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
+	// do not want to complain in unreachable code if local declared in reachable code
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0 && (local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0) {
+		return true;
+	}
+	return isDefinitelyAssigned(local.id + this.maxFieldCount);
+}
+
+final public boolean isDefinitelyNonNull(LocalVariableBinding local) {
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(this.tagBits & NULL_FLAG_MASK) == 0) {
+		return false;
+	}
+	if ((local.type.tagBits & TagBits.IsBaseType) != 0 ||
+			local.constant() != Constant.NotAConstant) { // String instances
+		return true;
+	}
+	int position = local.id + this.maxFieldCount;
+	if (position < BitCacheSize) { // use bits
+		return ((this.nullBit1 & this.nullBit3 & (~this.nullBit2 | this.nullBit4))
+			    & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1)
+			>= this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[2][vectorIndex] & this.extra[4][vectorIndex]
+		        & (~this.extra[3][vectorIndex] | this.extra[5][vectorIndex]))
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isDefinitelyNull(LocalVariableBinding local) {
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position = local.id + this.maxFieldCount;
+	if (position < BitCacheSize) { // use bits
+		return ((this.nullBit1 & this.nullBit2
+			        & (~this.nullBit3 | ~this.nullBit4))
+			    & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
+		        & (~this.extra[4][vectorIndex] | ~this.extra[5][vectorIndex]))
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isDefinitelyUnknown(LocalVariableBinding local) {
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(this.tagBits & NULL_FLAG_MASK) == 0) {
+		return false;
+	}
+	int position = local.id + this.maxFieldCount;
+	if (position < BitCacheSize) { // use bits
+		return ((this.nullBit1 & this.nullBit4
+				& ~this.nullBit2 & ~this.nullBit3) & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[2][vectorIndex] & this.extra[5][vectorIndex]
+	    & ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean hasNullInfoFor(LocalVariableBinding local) {
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(this.tagBits & NULL_FLAG_MASK) == 0) {
+		return false;
+	}
+	int position = local.id + this.maxFieldCount;
+	if (position < BitCacheSize) { // use bits
+		return ((this.nullBit1 | this.nullBit2
+				| this.nullBit3 | this.nullBit4) & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[2][vectorIndex] | this.extra[3][vectorIndex]
+	    | this.extra[4][vectorIndex] | this.extra[5][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+/**
+ * Check status of potential assignment at a given position.
+ */
+final private boolean isPotentiallyAssigned(int position) {
+	// id is zero-based
+	if (position < BitCacheSize) {
+		// use bits
+		return (this.potentialInits & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1)
+			>= this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[1][vectorIndex]) &
+			(1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isPotentiallyAssigned(FieldBinding field) {
+	return isPotentiallyAssigned(field.id);
+}
+
+final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
+	// final constants are inlined, and thus considered as always initialized
+	if (local.constant() != Constant.NotAConstant) {
+		return true;
+	}
+	return isPotentiallyAssigned(local.id + this.maxFieldCount);
+}
+
+// TODO (Ayush) Check why this method does not return true for protected non null (1111)
+final public boolean isPotentiallyNonNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return ((this.nullBit3 & (~this.nullBit1 | ~this.nullBit2))
+			    & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[4][vectorIndex]
+		        & (~this.extra[2][vectorIndex] | ~this.extra[3][vectorIndex]))
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+// TODO (Ayush) Check why this method does not return true for protected null
+final public boolean isPotentiallyNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return ((this.nullBit2 & (~this.nullBit1 | ~this.nullBit3))
+			    & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return ((this.extra[3][vectorIndex]
+		        & (~this.extra[2][vectorIndex] | ~this.extra[4][vectorIndex]))
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isPotentiallyUnknown(LocalVariableBinding local) {
+	// do not want to complain in unreachable code
+	if ((this.tagBits & UNREACHABLE) != 0 ||
+			(this.tagBits & NULL_FLAG_MASK) == 0) {
+		return false;
+	}
+	int position = local.id + this.maxFieldCount;
+	if (position < BitCacheSize) { // use bits
+		return (this.nullBit4
+			& (~this.nullBit1 | ~this.nullBit2 & ~this.nullBit3)
+			& (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[2].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return (this.extra[5][vectorIndex]
+	        & (~this.extra[2][vectorIndex]
+	            | ~this.extra[3][vectorIndex] & ~this.extra[4][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isProtectedNonNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return (this.nullBit1 & this.nullBit3 & this.nullBit4 & (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+		this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return (this.extra[2][vectorIndex]
+	            & this.extra[4][vectorIndex]
+	            & this.extra[5][vectorIndex]
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+
+final public boolean isProtectedNull(LocalVariableBinding local) {
+	if ((this.tagBits & NULL_FLAG_MASK) == 0 ||
+			(local.type.tagBits & TagBits.IsBaseType) != 0) {
+		return false;
+	}
+	int position;
+	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+		// use bits
+		return (this.nullBit1 & this.nullBit2
+			& (this.nullBit3 ^ this.nullBit4)
+			& (1L << position)) != 0;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return false; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex;
+	if ((vectorIndex = (position / BitCacheSize) - 1) >=
+			this.extra[0].length) {
+		return false; // if not enough room in vector, then not initialized
+	}
+	return (this.extra[2][vectorIndex] & this.extra[3][vectorIndex]
+	        & (this.extra[4][vectorIndex] ^ this.extra[5][vectorIndex])
+		    & (1L << (position % BitCacheSize))) != 0;
+}
+/** Asserts that the given boolean is <code>true</code>. If this
+ * is not the case, some kind of unchecked exception is thrown.
+ * The given message is included in that exception, to aid debugging.
+ *
+ * @param expression the outcome of the check
+ * @param message the message to include in the exception
+ * @return <code>true</code> if the check passes (does not return
+ *    if the check fails)
+ */
+protected static boolean isTrue(boolean expression, String message) {
+	if (!expression)
+		throw new AssertionFailedException("assertion failed: " + message); //$NON-NLS-1$
+	return expression;
+}
+public void markAsComparedEqualToNonNull(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+		int position;
+		long mask;
+		long a1, a2, a3, a4, na2;
+		// position is zero-based
+		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+			// use bits
+			if (((mask = 1L << position)
+				& (a1 = this.nullBit1)
+				& (na2 = ~(a2 = this.nullBit2))
+				& ~(a3 = this.nullBit3)
+				& (a4 = this.nullBit4))
+					!= 0) {
+			  	this.nullBit4 &= ~mask;
+			} else if ((mask & a1 & na2 & a3) == 0) {
+			  	this.nullBit4 |= mask;
+			  	if ((mask & a1) == 0) {
+			  	  	if ((mask & a2 & (a3 ^ a4)) != 0) {
+			  	  	  	this.nullBit2 &= ~mask;
+			  	  	}
+			  	  	else if ((mask & (a2 | a3 | a4)) == 0) {
+			  	  	  	this.nullBit2 |= mask;
+			  	  	}
+			  	}
+			}
+			this.nullBit1 |= mask;
+			this.nullBit3 |= mask;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 15) {
+				  	this.nullBit4 = ~0;
+				}
+			}
+		}
+		else {
+			// use extra vector
+			int vectorIndex = (position / BitCacheSize) - 1;
+			if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+				if (COVERAGE_TEST_FLAG) {
+					if (CoverageTestId == 16) {
+						throw new AssertionFailedException("COVERAGE 16"); //$NON-NLS-1$
+					}
+				}
+			}
+			else {
+				int oldLength;
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					int newLength = vectorIndex + 1;
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[newLength]), 0,
+							oldLength);
+					}
+					if (COVERAGE_TEST_FLAG) {
+						if (CoverageTestId == 17) {
+							throw new AssertionFailedException("COVERAGE 17"); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+			// MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][vectorIndex]/gc
+			if (((mask = 1L << (position % BitCacheSize))
+  				& (a1 = this.extra[1 + 1][vectorIndex])
+  				& (na2 = ~(a2 = this.extra[2 + 1][vectorIndex]))
+  				& ~(a3 = this.extra[3 + 1][vectorIndex])
+  				& (a4 = this.extra[4 + 1][vectorIndex]))
+  					!= 0) {
+  			  	this.extra[4 + 1][vectorIndex] &= ~mask;
+  			} else if ((mask & a1 & na2 & a3) == 0) {
+  			  	this.extra[4 + 1][vectorIndex] |= mask;
+  			  	if ((mask & a1) == 0) {
+  			  	  	if ((mask & a2 & (a3 ^ a4)) != 0) {
+  			  	  	  	this.extra[2 + 1][vectorIndex] &= ~mask;
+  			  	  	}
+  			  	  	else if ((mask & (a2 | a3 | a4)) == 0) {
+  			  	  	  	this.extra[2 + 1][vectorIndex] |= mask;
+  			  	  	}
+  			  	}
+  			}
+  			this.extra[1 + 1][vectorIndex] |= mask;
+  			this.extra[3 + 1][vectorIndex] |= mask;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 18) {
+				  	this.extra[5][vectorIndex] = ~0;
+				}
+			}
+		}
+	}
+}
+
+public void markAsComparedEqualToNull(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+		int position;
+		long mask;
+		// position is zero-based
+		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+			// use bits
+			if (((mask = 1L << position) & this.nullBit1) != 0) {
+  			  	if ((mask
+  			  		& (~this.nullBit2 | this.nullBit3
+  			  			| ~this.nullBit4)) != 0) {
+  			  	  	this.nullBit4 &= ~mask;
+  			  	}
+			} else if ((mask & this.nullBit4) != 0) {
+			  	  this.nullBit3 &= ~mask;
+			} else {
+    			if ((mask & this.nullBit2) != 0) {
+    			  	this.nullBit3 &= ~mask;
+      			  	this.nullBit4 |= mask;
+    			} else {
+    			  	this.nullBit3 |= mask;
+    			}
+			}
+			this.nullBit1 |= mask;
+			this.nullBit2 |= mask;
+			if (COVERAGE_TEST_FLAG) {
+				if (CoverageTestId == 19) {
+				  	this.nullBit4 = ~0;
+				}
+			}
+		}
+		else {
+			// use extra vector
+			int vectorIndex = (position / BitCacheSize) - 1;
+			mask = 1L << (position % BitCacheSize);
+			if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length ];
+				}
+				if (COVERAGE_TEST_FLAG) {
+					if(CoverageTestId == 20) {
+						throw new AssertionFailedException("COVERAGE 20"); //$NON-NLS-1$
+					}
+				}
+			}
+			else {
+				int oldLength;
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					int newLength = vectorIndex + 1;
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[newLength]), 0,
+							oldLength);
+					}
+					if (COVERAGE_TEST_FLAG) {
+						if(CoverageTestId == 21) {
+							throw new AssertionFailedException("COVERAGE 21"); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+			if ((mask & this.extra[1 + 1][vectorIndex]) != 0) {
+  			  	if ((mask
+  			  		& (~this.extra[2 + 1][vectorIndex] | this.extra[3 + 1][vectorIndex]
+  			  			| ~this.extra[4 + 1][vectorIndex])) != 0) {
+  			  	  	this.extra[4 + 1][vectorIndex] &= ~mask;
+  			  	}
+			} else if ((mask & this.extra[4 + 1][vectorIndex]) != 0) {
+			  	  this.extra[3 + 1][vectorIndex] &= ~mask;
+			} else {
+    			if ((mask & this.extra[2 + 1][vectorIndex]) != 0) {
+    			  	this.extra[3 + 1][vectorIndex] &= ~mask;
+      			  	this.extra[4 + 1][vectorIndex] |= mask;
+    			} else {
+    			  	this.extra[3 + 1][vectorIndex] |= mask;
+    			}
+			}
+			this.extra[1 + 1][vectorIndex] |= mask;
+			this.extra[2 + 1][vectorIndex] |= mask;
+		}
+	}
+}
+
+/**
+ * Record a definite assignment at a given position.
+ */
+final private void markAsDefinitelyAssigned(int position) {
+
+	if (this != DEAD_END) {
+		// position is zero-based
+		if (position < BitCacheSize) {
+			// use bits
+			long mask;
+			this.definiteInits |= (mask = 1L << position);
+			this.potentialInits |= mask;
+		}
+		else {
+			// use extra vector
+			int vectorIndex = (position / BitCacheSize) - 1;
+			if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+			}
+			else {
+				int oldLength; // might need to grow the arrays
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[vectorIndex + 1]), 0,
+							oldLength);
+					}
+				}
+			}
+			long mask;
+			this.extra[0][vectorIndex] |=
+				(mask = 1L << (position % BitCacheSize));
+			this.extra[1][vectorIndex] |= mask;
+		}
+	}
+}
+
+public void markAsDefinitelyAssigned(FieldBinding field) {
+	if (this != DEAD_END)
+		markAsDefinitelyAssigned(field.id);
+}
+
+public void markAsDefinitelyAssigned(LocalVariableBinding local) {
+	if (this != DEAD_END)
+		markAsDefinitelyAssigned(local.id + this.maxFieldCount);
+}
+
+public void markAsDefinitelyNonNull(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+    	this.tagBits |= NULL_FLAG_MASK;
+    	long mask;
+    	int position;
+    	// position is zero-based
+    	if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
+    		// set assigned non null
+    		this.nullBit1 |= (mask = 1L << position);
+    		this.nullBit3 |= mask;
+    		// clear others
+    		this.nullBit2 &= (mask = ~mask);
+    		this.nullBit4 &= mask;
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 22) {
+	    		  	this.nullBit1 = 0;
+    			}
+    		}
+    	}
+    	else {
+    		// use extra vector
+    		int vectorIndex = (position / BitCacheSize) - 1;
+    		if (this.extra == null) {
+    			int length = vectorIndex + 1;
+    			this.extra = new long[extraLength][];
+    			for (int j = 0; j < extraLength; j++) {
+    				this.extra[j] = new long[length];
+    			}
+    		}
+    		else {
+    			int oldLength; // might need to grow the arrays
+    			if (vectorIndex >= (oldLength = this.extra[0].length)) {
+    				for (int j = 0; j < extraLength; j++) {
+    					System.arraycopy(this.extra[j], 0,
+    						(this.extra[j] = new long[vectorIndex + 1]), 0,
+    						oldLength);
+    				}
+    			}
+    		}
+    		this.extra[2][vectorIndex]
+    		    |= (mask = 1L << (position % BitCacheSize));
+    		this.extra[4][vectorIndex] |= mask;
+    		this.extra[3][vectorIndex] &= (mask = ~mask);
+    		this.extra[5][vectorIndex] &= mask;
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 23) {
+	    			this.extra[2][vectorIndex] = 0;
+    			}
+    		}
+    	}
+	}
+}
+
+public void markAsDefinitelyNull(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+    	this.tagBits |= NULL_FLAG_MASK;
+    	long mask;
+    	int position;
+    	// position is zero-based
+    	if ((position = local.id + this.maxFieldCount) < BitCacheSize) { // use bits
+    		// mark assigned null
+    		this.nullBit1 |= (mask = 1L << position);
+    		this.nullBit2 |= mask;
+    		// clear others
+    		this.nullBit3 &= (mask = ~mask);
+    		this.nullBit4 &= mask;
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 24) {
+	    		  	this.nullBit4 = ~0;
+    			}
+    		}
+    	}
+    	else {
+    		// use extra vector
+    		int vectorIndex = (position / BitCacheSize) - 1;
+    		if (this.extra == null) {
+    			int length = vectorIndex + 1;
+    			this.extra = new long[extraLength][];
+    			for (int j = 0; j < extraLength; j++) {
+    				this.extra[j] = new long[length];
+    			}
+    		}
+    		else {
+    			int oldLength; // might need to grow the arrays
+    			if (vectorIndex >= (oldLength = this.extra[0].length)) {
+    				for (int j = 0; j < extraLength; j++) {
+    					System.arraycopy(this.extra[j], 0,
+    						(this.extra[j] = new long[vectorIndex + 1]), 0,
+    						oldLength);
+    				}
+    			}
+    		}
+    		this.extra[2][vectorIndex]
+    		    |= (mask = 1L << (position % BitCacheSize));
+    		this.extra[3][vectorIndex] |= mask;
+    		this.extra[4][vectorIndex] &= (mask = ~mask);
+    		this.extra[5][vectorIndex] &= mask;
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 25) {
+	    			this.extra[5][vectorIndex] = ~0;
+    			}
+    		}
+    	}
+	}
+}
+
+/**
+ * Mark a local as having been assigned to an unknown value.
+ * @param local the local to mark
+ */
+// PREMATURE may try to get closer to markAsDefinitelyAssigned, but not
+//			 obvious
+public void markAsDefinitelyUnknown(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+		long mask;
+		int position;
+		// position is zero-based
+		if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+			// use bits
+			// mark assigned null
+			this.nullBit1 |= (mask = 1L << position);
+			this.nullBit4 |= mask;
+			// clear others
+			this.nullBit2 &= (mask = ~mask);
+			this.nullBit3 &= mask;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 26) {
+				  	this.nullBit4 = 0;
+				}
+			}
+		}
+		else {
+			// use extra vector
+			int vectorIndex = (position / BitCacheSize) - 1;
+			if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+			}
+			else {
+				int oldLength; // might need to grow the arrays
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[vectorIndex + 1]), 0,
+							oldLength);
+					}
+				}
+			}
+			this.extra[2][vectorIndex]
+			    |= (mask = 1L << (position % BitCacheSize));
+			this.extra[5][vectorIndex] |= mask;
+			this.extra[3][vectorIndex] &= (mask = ~mask);
+			this.extra[4][vectorIndex] &= mask;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 27) {
+					this.extra[5][vectorIndex] = 0;
+				}
+			}
+		}
+	}
+}
+
+public void resetNullInfo(LocalVariableBinding local) {
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+        int position;
+        long mask;
+        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+            // use bits
+            this.nullBit1 &= (mask = ~(1L << position));
+            this.nullBit2 &= mask;
+            this.nullBit3 &= mask;
+            this.nullBit4 &= mask;
+        } else {
+    		// use extra vector
+    		int vectorIndex = (position / BitCacheSize) - 1;
+    		if (this.extra == null || vectorIndex >= this.extra[2].length) {
+    			// in case we attempt to reset the null info of a variable that has not been encountered
+    			// before and for which no null bits exist.
+    			return;
+    		}
+    		this.extra[2][vectorIndex]
+    		    &= (mask = ~(1L << (position % BitCacheSize)));
+    		this.extra[3][vectorIndex] &= mask;
+    		this.extra[4][vectorIndex] &= mask;
+    		this.extra[5][vectorIndex] &= mask;
+    	}
+	}
+}
+
+/**
+ * Mark a local as potentially having been assigned to an unknown value.
+ * @param local the local to mark
+ */
+public void markPotentiallyUnknownBit(LocalVariableBinding local) {
+	// protected from non-object locals in calling methods
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+        int position;
+        long mask;
+        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+            // use bits
+        	mask = 1L << position;
+        	isTrue((this.nullBit1 & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
+            this.nullBit4 |= mask;
+            if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 44) {
+				  	this.nullBit4 = 0;
+				}
+			}
+        } else {
+    		// use extra vector
+    		int vectorIndex = (position / BitCacheSize) - 1;
+    		if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+			}
+			else {
+				int oldLength; // might need to grow the arrays
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[vectorIndex + 1]), 0,
+							oldLength);
+					}
+				}
+			}
+    		mask = 1L << (position % BitCacheSize);
+    		isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
+    		this.extra[5][vectorIndex] |= mask;
+    		if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 45) {
+					this.extra[2][vectorIndex] = ~0;
+					this.extra[3][vectorIndex] = ~0;
+					this.extra[4][vectorIndex] = 0;
+					this.extra[5][vectorIndex] = 0;
+				}
+			}
+    	}
+	}
+}
+
+public void markPotentiallyNullBit(LocalVariableBinding local) {
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+        int position;
+        long mask;
+        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+            // use bits
+        	mask = 1L << position;
+        	isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially null' mark in unexpected state"); //$NON-NLS-1$
+            this.nullBit2 |= mask;
+            if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 40) {
+				  	this.nullBit2 = 0;
+				}
+			}
+        } else {
+    		// use extra vector
+    		int vectorIndex = (position / BitCacheSize) - 1;
+    		if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+			}
+			else {
+				int oldLength; // might need to grow the arrays
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[vectorIndex + 1]), 0,
+							oldLength);
+					}
+				}
+			}
+    		mask = 1L << (position % BitCacheSize);
+    		this.extra[3][vectorIndex] |= mask;
+    		isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'potentially null' mark in unexpected state"); //$NON-NLS-1$
+    		if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 41) {
+					this.extra[3][vectorIndex] = 0;
+				}
+			}
+    	}
+	}
+}
+
+public void markPotentiallyNonNullBit(LocalVariableBinding local) {
+	if (this != DEAD_END) {
+		this.tagBits |= NULL_FLAG_MASK;
+        int position;
+        long mask;
+        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
+            // use bits
+        	mask = 1L << position;
+        	isTrue((this.nullBit1 & mask) == 0, "Adding 'potentially non-null' mark in unexpected state"); //$NON-NLS-1$
+            this.nullBit3 |= mask;
+            if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 42) {
+				  	this.nullBit1 = ~0;
+				  	this.nullBit2 = 0;
+				  	this.nullBit3 = ~0;
+				  	this.nullBit4 = 0;
+				}
+			}
+        } else {
+    		// use extra vector
+    		int vectorIndex  = (position / BitCacheSize) - 1;
+    		if (this.extra == null) {
+				int length = vectorIndex + 1;
+				this.extra = new long[extraLength][];
+				for (int j = 0; j < extraLength; j++) {
+					this.extra[j] = new long[length];
+				}
+			}
+			else {
+				int oldLength; // might need to grow the arrays
+				if (vectorIndex >= (oldLength = this.extra[0].length)) {
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[vectorIndex + 1]), 0,
+							oldLength);
+					}
+				}
+			}
+    		mask = 1L << (position % BitCacheSize);
+    		isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'potentially non-null' mark in unexpected state"); //$NON-NLS-1$
+    		this.extra[4][vectorIndex] |= mask;
+    		if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 43) {
+					this.extra[2][vectorIndex] = ~0;
+					this.extra[3][vectorIndex] = 0;
+					this.extra[4][vectorIndex] = ~0;
+					this.extra[5][vectorIndex] = 0;
+				}
+			}
+    	}
+	}
+}
+
+public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
+	if ((otherInits.tagBits & UNREACHABLE_OR_DEAD) != 0 && this != DEAD_END) {
+		if (COVERAGE_TEST_FLAG) {
+			if(CoverageTestId == 28) {
+				throw new AssertionFailedException("COVERAGE 28"); //$NON-NLS-1$
+			}
+		}
+		return this;
+	}
+	if ((this.tagBits & UNREACHABLE_OR_DEAD) != 0) {
+		if (COVERAGE_TEST_FLAG) {
+			if(CoverageTestId == 29) {
+				throw new AssertionFailedException("COVERAGE 29"); //$NON-NLS-1$
+			}
+		}
+		return (UnconditionalFlowInfo) otherInits.copy(); // make sure otherInits won't be affected
+	}
+
+	// intersection of definitely assigned variables,
+	this.definiteInits &= otherInits.definiteInits;
+	// union of potentially set ones
+	this.potentialInits |= otherInits.potentialInits;
+
+	// null combinations
+	boolean
+		thisHasNulls = (this.tagBits & NULL_FLAG_MASK) != 0,
+		otherHasNulls = (otherInits.tagBits & NULL_FLAG_MASK) != 0,
+		thisHadNulls = thisHasNulls;
+	long
+		a1, a2, a3, a4,
+		na1, na2, na3, na4,
+		nb1, nb2, nb3, nb4,
+		b1, b2, b3, b4;
+	if ((otherInits.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) {
+		otherHasNulls = false; // skip merging, otherInits is unreachable by null analysis
+	} else if ((this.tagBits & FlowInfo.UNREACHABLE_BY_NULLANALYSIS) != 0) { // directly copy if this is unreachable by null analysis
+		this.nullBit1 = otherInits.nullBit1;
+		this.nullBit2 = otherInits.nullBit2;
+		this.nullBit3 = otherInits.nullBit3;
+		this.nullBit4 = otherInits.nullBit4;
+		thisHadNulls = false;
+		thisHasNulls = otherHasNulls;
+		this.tagBits = otherInits.tagBits;
+	} else if (thisHadNulls) {
+    	if (otherHasNulls) {
+    		this.nullBit1 = (a1 = this.nullBit1) & (b1 = otherInits.nullBit1) & (
+    				((a2 = this.nullBit2) & (((b2 = otherInits.nullBit2) & 
+    											~(((a3=this.nullBit3) & (a4=this.nullBit4)) ^ ((b3=otherInits.nullBit3) & (b4=otherInits.nullBit4))))
+    										|(a3 & a4 & (nb2 = ~b2))))
+    				|((na2 = ~a2) & ((b2 & b3 & b4)
+    								|(nb2 & ((na3 = ~a3) ^ b3)))));
+    		this.nullBit2 = b2 & ((nb3 = ~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4 = ~b4))
+        			| a2 & (b2 | (na4 = ~a4) & b3 & (b4 | nb1) | na3 | na1);
+    		this.nullBit3 =   a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4))
+    						| b3 & (nb1 | b1 & nb2);
+    		this.nullBit4 = na3 & (nb1 & nb3 & b4
+              			| b1 & (nb2 & nb3 | a4 & b2 & nb4)
+              			| na1 & a4 & (nb3 | b1 & b2))
+        			| a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2)
+        			| na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
+        			| a1 & (na3 & (nb3 & b4
+                        			| b1 & b2 & b3 & nb4
+                        			| na2 & (nb3 | nb2))
+                			| na2 & b3 & b4
+                			| a2 & (nb1 & b4 | a3 & na4 & b1) & nb3)
+                	|nb1 & b2 & b3 & b4;
+
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 30) {
+	    		  	this.nullBit4 = ~0;
+    			}
+    		}
+    	} else { // other has no null info
+    		a1 = this.nullBit1;
+      		this.nullBit1 = 0;
+      		this.nullBit2 = (a2 = this.nullBit2) & (na3 = ~(a3 = this.nullBit3) | (na1 = ~a1));
+      		this.nullBit3 = a3 & ((na2 = ~a2) & (a4 = this.nullBit4) | na1) | a1 & na2 & ~a4;
+      		this.nullBit4 = (na3 | na2) & na1 & a4	| a1 & na3 & na2;
+    		if (COVERAGE_TEST_FLAG) {
+    			if(CoverageTestId == 31) {
+	    		  	this.nullBit4 = ~0;
+    			}
+    		}
+    	}
+	} else if (otherHasNulls) { // only other had nulls
+  		this.nullBit1 = 0;
+  		this.nullBit2 = (b2 = otherInits.nullBit2) & (nb3 = ~(b3 = otherInits.nullBit3) | (nb1 = ~(b1 = otherInits.nullBit1)));
+  		this.nullBit3 = b3 & ((nb2 = ~b2) & (b4 = otherInits.nullBit4) | nb1) | b1 & nb2 & ~b4;
+  		this.nullBit4 = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
+  		if (COVERAGE_TEST_FLAG) {
+  			if(CoverageTestId == 32) {
+	  		  	this.nullBit4 = ~0;
+  			}
+  		}
+    	thisHasNulls =
+    		// redundant with the three following ones
+    		this.nullBit2 != 0 ||
+    		this.nullBit3 != 0 ||
+    		this.nullBit4 != 0;
+	}
+
+	// treating extra storage
+	if (this.extra != null || otherInits.extra != null) {
+		int mergeLimit = 0, copyLimit = 0, resetLimit = 0;
+		int i;
+		if (this.extra != null) {
+			if (otherInits.extra != null) {
+				// both sides have extra storage
+				int length, otherLength;
+				if ((length = this.extra[0].length) <
+						(otherLength = otherInits.extra[0].length)) {
+					// current storage is shorter -> grow current
+					for (int j = 0; j < extraLength; j++) {
+						System.arraycopy(this.extra[j], 0,
+							(this.extra[j] = new long[otherLength]), 0, length);
+					}
+					mergeLimit = length;
+					copyLimit = otherLength;
+					if (COVERAGE_TEST_FLAG) {
+						if(CoverageTestId == 33) {
+							throw new AssertionFailedException("COVERAGE 33"); //$NON-NLS-1$
+						}
+					}
+				}
+				else {
+					// current storage is longer
+					mergeLimit = otherLength;
+					resetLimit = length;
+					if (COVERAGE_TEST_FLAG) {
+						if(CoverageTestId == 34) {
+							throw new AssertionFailedException("COVERAGE 34"); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+			else {
+				resetLimit = this.extra[0].length;
+				if (COVERAGE_TEST_FLAG) {
+					if(CoverageTestId == 35) {
+						throw new AssertionFailedException("COVERAGE 35"); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		else if (otherInits.extra != null) {
+			// no storage here, but other has extra storage.
+			int otherLength = otherInits.extra[0].length;
+			this.extra = new long[extraLength][];
+			for (int j = 0; j < extraLength; j++) {
+				this.extra[j] = new long[otherLength];
+			}
+			System.arraycopy(otherInits.extra[1], 0,
+				this.extra[1], 0, otherLength);
+			copyLimit = otherLength;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 36) {
+					throw new AssertionFailedException("COVERAGE 36"); //$NON-NLS-1$
+				}
+			}
+		}
+        // MACRO :'b,'es/nullBit\(.\)/extra[\1 + 1][i]/g
+		// manage definite assignment
+		for (i = 0; i < mergeLimit; i++) {
+	  		this.extra[0][i] &= otherInits.extra[0][i];
+	  		this.extra[1][i] |= otherInits.extra[1][i];
+		}
+		for (; i < copyLimit; i++) {
+		  	this.extra[1][i] = otherInits.extra[1][i];
+		}
+		for (; i < resetLimit; i++) {
+		  	this.extra[0][i] = 0;
+		}
+		// refine null bits requirements
+		if (!otherHasNulls) {
+		  if (resetLimit < mergeLimit) {
+			resetLimit = mergeLimit;
+		  }
+		  copyLimit = 0; // no need to carry inexisting nulls
+		  mergeLimit = 0;
+		}
+		if (!thisHadNulls) {
+		  resetLimit = 0; // no need to reset anything
+		}
+		// compose nulls
+		for (i = 0; i < mergeLimit; i++) {
+    		this.extra[1 + 1][i] = (a1=this.extra[1+1][i]) & (b1=otherInits.extra[1+1][i]) & (
+    				((a2=this.extra[2+1][i]) & (((b2=otherInits.extra[2+1][i]) & 
+    												~(((a3=this.extra[3+1][i]) & (a4=this.extra[4+1][i])) ^ ((b3=otherInits.extra[3+1][i]) & (b4=otherInits.extra[4+1][i]))))
+    											|(a3 & a4 & (nb2=~b2))))
+    				|((na2=~a2) & ((b2 & b3 & b4)
+    						|(nb2 & ((na3=~a3) ^ b3)))));
+    		this.extra[2 + 1][i] = b2 & ((nb3=~b3) | (nb1 = ~b1) | a3 & (a4 | (na1 = ~a1)) & (nb4=~b4))
+        			| a2 & (b2 | (na4=~a4) & b3 & (b4 | nb1) | na3 | na1);
+    		this.extra[3 + 1][i] =   a3 & (na1 | a1 & na2 | b3 & (na4 ^ b4))
+								   | b3 & (nb1 | b1 & nb2);
+    		this.extra[4 + 1][i] = na3 & (nb1 & nb3 & b4
+              			| b1 & (nb2 & nb3 | a4 & b2 & nb4)
+              			| na1 & a4 & (nb3 | b1 & b2))
+        			| a3 & a4 & (b3 & b4 | b1 & nb2 | na1 & a2)
+        			| na2 & (nb1 & b4 | b1 & nb3 | na1 & a4) & nb2
+        			| a1 & (na3 & (nb3 & b4
+                        			| b1 & b2 & b3 & nb4
+                        			| na2 & (nb3 | nb2))
+                			| na2 & b3 & b4
+                			| a2 & (nb1 & b4 | a3 & na4 & b1) & nb3)
+                	|nb1 & b2 & b3 & b4;
+			thisHasNulls = thisHasNulls ||
+				this.extra[3][i] != 0 ||
+				this.extra[4][i] != 0 ||
+				this.extra[5][i] != 0 ;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 37) {
+					this.extra[5][i] = ~0;
+				}
+			}
+		}
+		for (; i < copyLimit; i++) {
+    		this.extra[1 + 1][i] = 0;
+    		this.extra[2 + 1][i] = (b2 = otherInits.extra[2 + 1][i]) & (nb3 = ~(b3 = otherInits.extra[3 + 1][i]) | (nb1 = ~(b1 = otherInits.extra[1 + 1][i])));
+    		this.extra[3 + 1][i] = b3 & ((nb2 = ~b2) & (b4 = otherInits.extra[4 + 1][i]) | nb1) | b1 & nb2 & ~b4;
+    		this.extra[4 + 1][i] = (nb3 | nb2) & nb1 & b4	| b1 & nb3 & nb2;
+			thisHasNulls = thisHasNulls ||
+				this.extra[3][i] != 0 ||
+				this.extra[4][i] != 0 ||
+				this.extra[5][i] != 0;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 38) {
+					this.extra[5][i] = ~0;
+				}
+			}
+		}
+		for (; i < resetLimit; i++) {
+    		a1 = this.extra[1 + 1][i];
+      		this.extra[1 + 1][i] = 0;
+      		this.extra[2 + 1][i] = (a2 = this.extra[2 + 1][i]) & (na3 = ~(a3 = this.extra[3 + 1][i]) | (na1 = ~a1));
+      		this.extra[3 + 1][i] = a3 & ((na2 = ~a2) & (a4 = this.extra[4 + 1][i]) | na1) | a1 & na2 & ~a4;
+      		this.extra[4 + 1][i] = (na3 | na2) & na1 & a4	| a1 & na3 & na2;
+			thisHasNulls = thisHasNulls ||
+				this.extra[3][i] != 0 ||
+				this.extra[4][i] != 0 ||
+				this.extra[5][i] != 0;
+			if (COVERAGE_TEST_FLAG) {
+				if(CoverageTestId == 39) {
+					this.extra[5][i] = ~0;
+				}
+			}
+		}
+	}
+	if (thisHasNulls) {
+		this.tagBits |= NULL_FLAG_MASK;
+	}
+	else {
+		this.tagBits &= ~NULL_FLAG_MASK;
+	}
+	return this;
+}
+
+/*
+ * Answer the total number of fields in enclosing types of a given type
+ */
+static int numberOfEnclosingFields(ReferenceBinding type){
+	int count = 0;
+	type = type.enclosingType();
+	while(type != null) {
+		count += type.fieldCount();
+		type = type.enclosingType();
+	}
+	return count;
+}
+
+public UnconditionalFlowInfo nullInfoLessUnconditionalCopy() {
+	if (this == DEAD_END) {
+		return this;
+	}
+	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
+	copy.definiteInits = this.definiteInits;
+	copy.potentialInits = this.potentialInits;
+	copy.tagBits = this.tagBits & ~NULL_FLAG_MASK;
+	copy.maxFieldCount = this.maxFieldCount;
+	if (this.extra != null) {
+		int length;
+		copy.extra = new long[extraLength][];
+		System.arraycopy(this.extra[0], 0,
+			(copy.extra[0] =
+				new long[length = this.extra[0].length]), 0, length);
+		System.arraycopy(this.extra[1], 0,
+			(copy.extra[1] = new long[length]), 0, length);
+		for (int j = 2; j < extraLength; j++) {
+			copy.extra[j] = new long[length];
+		}
+	}
+	return copy;
+}
+
+public FlowInfo safeInitsWhenTrue() {
+	return copy();
+}
+
+public FlowInfo setReachMode(int reachMode) {
+	if (this == DEAD_END) {// cannot modify DEAD_END
+		return this;
+	}	
+	if (reachMode == REACHABLE ) {
+		this.tagBits &= ~UNREACHABLE;
+	} else if (reachMode == UNREACHABLE_BY_NULLANALYSIS ) {
+		this.tagBits |= UNREACHABLE_BY_NULLANALYSIS;	// do not interfere with definite assignment analysis
+	} else {
+		if ((this.tagBits & UNREACHABLE) == 0) {
+			// reset optional inits when becoming unreachable
+			// see InitializationTest#test090 (and others)
+			this.potentialInits = 0;
+			if (this.extra != null) {
+				for (int i = 0, length = this.extra[0].length;
+						i < length; i++) {
+					this.extra[1][i] = 0;
+				}
+			}
+		}
+		this.tagBits |= reachMode;
+	}
+	return this;
+}
+
+public String toString(){
+	// PREMATURE consider printing bit fields as 0001 0001 1000 0001...
+	if (this == DEAD_END){
+		return "FlowInfo.DEAD_END"; //$NON-NLS-1$
+	}
+	if ((this.tagBits & NULL_FLAG_MASK) != 0) {
+		if (this.extra == null) {
+			return "FlowInfo<def: " + this.definiteInits //$NON-NLS-1$
+				+", pot: " + this.potentialInits  //$NON-NLS-1$
+				+ ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
+				+", null: " + this.nullBit1 //$NON-NLS-1$
+					+ this.nullBit2 + this.nullBit3 + this.nullBit4
+				+">"; //$NON-NLS-1$
+		}
+		else {
+			String def = "FlowInfo<def:[" + this.definiteInits, //$NON-NLS-1$
+				pot = "], pot:[" + this.potentialInits, //$NON-NLS-1$
+				nullS = ", null:[" + this.nullBit1 //$NON-NLS-1$
+					+ this.nullBit2 + this.nullBit3 + this.nullBit4;
+			int i, ceil;
+			for (i = 0, ceil = this.extra[0].length > 3 ?
+								3 :
+								this.extra[0].length;
+				i < ceil; i++) {
+				def += "," + this.extra[0][i]; //$NON-NLS-1$
+				pot += "," + this.extra[1][i]; //$NON-NLS-1$
+				nullS += "," + this.extra[2][i] //$NON-NLS-1$
+				    + this.extra[3][i] + this.extra[4][i] + this.extra[5][i];
+			}
+			if (ceil < this.extra[0].length) {
+				def += ",..."; //$NON-NLS-1$
+				pot += ",..."; //$NON-NLS-1$
+				nullS += ",..."; //$NON-NLS-1$
+			}
+			return def + pot
+				+ "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
+				+ nullS
+				+ "]>"; //$NON-NLS-1$
+		}
+	}
+	else {
+		if (this.extra == null) {
+			return "FlowInfo<def: " + this.definiteInits //$NON-NLS-1$
+				+", pot: " + this.potentialInits  //$NON-NLS-1$
+				+ ", reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
+				+", no null info>"; //$NON-NLS-1$
+		}
+		else {
+			String def = "FlowInfo<def:[" + this.definiteInits, //$NON-NLS-1$
+				pot = "], pot:[" + this.potentialInits; //$NON-NLS-1$
+			int i, ceil;
+			for (i = 0, ceil = this.extra[0].length > 3 ?
+								3 :
+								this.extra[0].length;
+				i < ceil; i++) {
+				def += "," + this.extra[0][i]; //$NON-NLS-1$
+				pot += "," + this.extra[1][i]; //$NON-NLS-1$
+			}
+			if (ceil < this.extra[0].length) {
+				def += ",..."; //$NON-NLS-1$
+				pot += ",..."; //$NON-NLS-1$
+			}
+			return def + pot
+				+ "], reachable:" + ((this.tagBits & UNREACHABLE) == 0) //$NON-NLS-1$
+				+ ", no null info>"; //$NON-NLS-1$
+		}
+	}
+}
+
+public UnconditionalFlowInfo unconditionalCopy() {
+	return (UnconditionalFlowInfo) copy();
+}
+
+public UnconditionalFlowInfo unconditionalFieldLessCopy() {
+	// TODO (maxime) may consider leveraging null contribution verification as it is done in copy
+	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();
+	copy.tagBits = this.tagBits;
+	copy.maxFieldCount = this.maxFieldCount;
+	int limit = this.maxFieldCount;
+	if (limit < BitCacheSize) {
+		long mask;
+		copy.definiteInits = this.definiteInits & (mask = ~((1L << limit)-1));
+		copy.potentialInits = this.potentialInits & mask;
+		copy.nullBit1 = this.nullBit1 & mask;
+		copy.nullBit2 = this.nullBit2 & mask;
+		copy.nullBit3 = this.nullBit3 & mask;
+		copy.nullBit4 = this.nullBit4 & mask;
+	}
+	// use extra vector
+	if (this.extra == null) {
+		return copy; // if vector not yet allocated, then not initialized
+	}
+	int vectorIndex, length, copyStart;
+	if ((vectorIndex = (limit / BitCacheSize) - 1) >=
+			(length = this.extra[0].length)) {
+		return copy; // not enough room yet
+	}
+	long mask;
+	copy.extra = new long[extraLength][];
+	if ((copyStart = vectorIndex + 1) < length) {
+		int copyLength = length - copyStart;
+		for (int j = 0; j < extraLength; j++) {
+			System.arraycopy(this.extra[j], copyStart,
+				(copy.extra[j] = new long[length]), copyStart,
+				copyLength);
+		}
+	}
+	else if (vectorIndex >= 0) {
+		for (int j = 0; j < extraLength; j++) {
+			copy.extra[j] = new long[length];
+		}
+	}
+	if (vectorIndex >= 0) {
+		mask = ~((1L << (limit % BitCacheSize))-1);
+		for (int j = 0; j < extraLength; j++) {
+			copy.extra[j][vectorIndex] =
+				this.extra[j][vectorIndex] & mask;
+		}
+	}
+	return copy;
+}
+
+public UnconditionalFlowInfo unconditionalInits() {
+	// also see conditional inits, where it requests them to merge
+	return this;
+}
+
+public UnconditionalFlowInfo unconditionalInitsWithoutSideEffect() {
+	return this;
+}
+
+public void resetAssignmentInfo(LocalVariableBinding local) {
+	resetAssignmentInfo(local.id + this.maxFieldCount);
+}
+
+public void resetAssignmentInfo(int position) {
+	if (this != DEAD_END) {
+		// position is zero-based
+		if (position < BitCacheSize) {
+			// use bits
+			long mask;
+			this.definiteInits &= (mask = ~(1L << position));
+			this.potentialInits &= mask;
+		} else {
+			// use extra vector
+			int vectorIndex = (position / BitCacheSize) - 1;
+			if (this.extra == null || vectorIndex >= this.extra[0].length) return;	// variable doesnt exist in flow info
+			long mask;
+			this.extra[0][vectorIndex] &=
+				(mask = ~(1L << (position % BitCacheSize)));
+			this.extra[1][vectorIndex] &= mask;
+		}
+	}
+}
+}
+
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java
new file mode 100644
index 0000000..ab8d632
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class BooleanConstant extends Constant {
+
+	private boolean value;
+
+	private static final BooleanConstant TRUE = new BooleanConstant(true);
+	private static final BooleanConstant FALSE = new BooleanConstant(false);
+
+	public static Constant fromValue(boolean value) {
+		return value ? BooleanConstant.TRUE : BooleanConstant.FALSE;
+	}
+
+	private BooleanConstant(boolean value) {
+		this.value = value;
+	}
+
+	public boolean booleanValue() {
+		return this.value;
+	}
+
+	public String stringValue() {
+		// spec 15.17.11
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		return "(boolean)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_boolean;
+	}
+
+	public int hashCode() {
+		return this.value ? 1231 : 1237;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		// cannot be true anymore as the first test would have returned true
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java
new file mode 100644
index 0000000..f563962
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class ByteConstant extends Constant {
+
+	private byte value;
+
+	public static Constant fromValue(byte value) {
+		return new ByteConstant(value);
+	}
+
+	private ByteConstant(byte value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return this.value;
+	}
+
+	public char charValue() {
+		return (char) this.value;
+	}
+
+	public double doubleValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public float floatValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public int intValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public long longValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public short shortValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public String stringValue() {
+		// spec 15.17.11
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		return "(byte)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_byte;
+	}
+
+	public int hashCode() {
+		return this.value;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		ByteConstant other = (ByteConstant) obj;
+		return this.value == other.value;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java
new file mode 100644
index 0000000..6f740d6
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class CharConstant extends Constant {
+
+	private char value;
+
+	public static Constant fromValue(char value) {
+		return new CharConstant(value);
+	}
+
+	private CharConstant(char value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return (byte) this.value;
+	}
+
+	public char charValue() {
+		return this.value;
+	}
+
+	public double doubleValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public float floatValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public int intValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public long longValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public short shortValue() {
+		return (short) this.value;
+	}
+
+	public String stringValue() {
+		// spec 15.17.11
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		return "(char)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_char;
+	}
+
+	public int hashCode() {
+		return this.value;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		CharConstant other = (CharConstant) obj;
+		return this.value == other.value;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
new file mode 100644
index 0000000..c30f35d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -0,0 +1,1894 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Benjamin Muskalla - Contribution for bug 239066
+ *     Stephan Herrmann  - Contributions for
+ *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ *     							bug 295551 - Add option to automatically promote all warnings to errors
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 366063 - Compiler should not add synthetic @NonNull annotations
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ *								bug 383368 - [compiler][null] syntactic null analysis for field references
+ *     Jesper Steen Moller - Contributions for
+ *								bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CompilerOptions {
+
+	/**
+	 * Option IDs
+	 */
+	public static final String OPTION_LocalVariableAttribute = "org.eclipse.jdt.core.compiler.debug.localVariable"; //$NON-NLS-1$
+	public static final String OPTION_LineNumberAttribute = "org.eclipse.jdt.core.compiler.debug.lineNumber"; //$NON-NLS-1$
+	public static final String OPTION_SourceFileAttribute = "org.eclipse.jdt.core.compiler.debug.sourceFile"; //$NON-NLS-1$
+	public static final String OPTION_PreserveUnusedLocal = "org.eclipse.jdt.core.compiler.codegen.unusedLocal"; //$NON-NLS-1$
+	public static final String OPTION_DocCommentSupport= "org.eclipse.jdt.core.compiler.doc.comment.support"; //$NON-NLS-1$
+	public static final String OPTION_ReportMethodWithConstructorName = "org.eclipse.jdt.core.compiler.problem.methodWithConstructorName"; //$NON-NLS-1$
+	public static final String OPTION_ReportOverridingPackageDefaultMethod = "org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod"; //$NON-NLS-1$
+	public static final String OPTION_ReportDeprecation = "org.eclipse.jdt.core.compiler.problem.deprecation"; //$NON-NLS-1$
+	public static final String OPTION_ReportDeprecationInDeprecatedCode = "org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"; //$NON-NLS-1$
+	public static final String OPTION_ReportDeprecationWhenOverridingDeprecatedMethod = "org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod"; //$NON-NLS-1$
+	public static final String OPTION_ReportHiddenCatchBlock = "org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedLocal = "org.eclipse.jdt.core.compiler.problem.unusedLocal"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedParameter = "org.eclipse.jdt.core.compiler.problem.unusedParameter"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedParameterWhenImplementingAbstract = "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedParameterWhenOverridingConcrete = "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedParameterIncludeDocCommentReference = "org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedImport = "org.eclipse.jdt.core.compiler.problem.unusedImport"; //$NON-NLS-1$
+	public static final String OPTION_ReportSyntheticAccessEmulation = "org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation"; //$NON-NLS-1$
+	public static final String OPTION_ReportNoEffectAssignment = "org.eclipse.jdt.core.compiler.problem.noEffectAssignment"; //$NON-NLS-1$
+	public static final String OPTION_ReportLocalVariableHiding = "org.eclipse.jdt.core.compiler.problem.localVariableHiding"; //$NON-NLS-1$
+	public static final String OPTION_ReportSpecialParameterHidingField = "org.eclipse.jdt.core.compiler.problem.specialParameterHidingField"; //$NON-NLS-1$
+	public static final String OPTION_ReportFieldHiding = "org.eclipse.jdt.core.compiler.problem.fieldHiding"; //$NON-NLS-1$
+	public static final String OPTION_ReportTypeParameterHiding = "org.eclipse.jdt.core.compiler.problem.typeParameterHiding"; //$NON-NLS-1$
+	public static final String OPTION_ReportPossibleAccidentalBooleanAssignment = "org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment"; //$NON-NLS-1$
+	public static final String OPTION_ReportNonExternalizedStringLiteral = "org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$
+	public static final String OPTION_ReportIncompatibleNonInheritedInterfaceMethod = "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedPrivateMember = "org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"; //$NON-NLS-1$
+	public static final String OPTION_ReportNoImplicitStringConversion = "org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"; //$NON-NLS-1$
+	public static final String OPTION_ReportAssertIdentifier = "org.eclipse.jdt.core.compiler.problem.assertIdentifier"; //$NON-NLS-1$
+	public static final String OPTION_ReportEnumIdentifier = "org.eclipse.jdt.core.compiler.problem.enumIdentifier"; //$NON-NLS-1$
+	public static final String OPTION_ReportNonStaticAccessToStatic = "org.eclipse.jdt.core.compiler.problem.staticAccessReceiver"; //$NON-NLS-1$
+	public static final String OPTION_ReportIndirectStaticAccess = "org.eclipse.jdt.core.compiler.problem.indirectStaticAccess"; //$NON-NLS-1$
+	public static final String OPTION_ReportEmptyStatement = "org.eclipse.jdt.core.compiler.problem.emptyStatement"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnnecessaryTypeCheck = "org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnnecessaryElse = "org.eclipse.jdt.core.compiler.problem.unnecessaryElse"; //$NON-NLS-1$
+	public static final String OPTION_ReportUndocumentedEmptyBlock = "org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock"; //$NON-NLS-1$
+	public static final String OPTION_ReportInvalidJavadoc = "org.eclipse.jdt.core.compiler.problem.invalidJavadoc"; //$NON-NLS-1$
+	public static final String OPTION_ReportInvalidJavadocTags = "org.eclipse.jdt.core.compiler.problem.invalidJavadocTags"; //$NON-NLS-1$
+	public static final String OPTION_ReportInvalidJavadocTagsDeprecatedRef = "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef"; //$NON-NLS-1$
+	public static final String OPTION_ReportInvalidJavadocTagsNotVisibleRef = "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef"; //$NON-NLS-1$
+	public static final String OPTION_ReportInvalidJavadocTagsVisibility = "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocTags = "org.eclipse.jdt.core.compiler.problem.missingJavadocTags"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocTagsVisibility = "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocTagsOverriding = "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocTagsMethodTypeParameters = "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocComments = "org.eclipse.jdt.core.compiler.problem.missingJavadocComments"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocTagDescription = "org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocCommentsVisibility = "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingJavadocCommentsOverriding = "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding"; //$NON-NLS-1$
+	public static final String OPTION_ReportFinallyBlockNotCompletingNormally = "org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedDeclaredThrownException = "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding = "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference = "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnqualifiedFieldAccess = "org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnavoidableGenericTypeProblems = "org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems"; //$NON-NLS-1$
+	public static final String OPTION_ReportUncheckedTypeOperation = "org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation"; //$NON-NLS-1$
+	public static final String OPTION_ReportRawTypeReference =  "org.eclipse.jdt.core.compiler.problem.rawTypeReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportFinalParameterBound = "org.eclipse.jdt.core.compiler.problem.finalParameterBound"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingSerialVersion = "org.eclipse.jdt.core.compiler.problem.missingSerialVersion"; //$NON-NLS-1$
+	public static final String OPTION_ReportVarargsArgumentNeedCast = "org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedTypeArgumentsForMethodInvocation = "org.eclipse.jdt.core.compiler.problem.unusedTypeArgumentsForMethodInvocation"; //$NON-NLS-1$
+	public static final String OPTION_Source = "org.eclipse.jdt.core.compiler.source"; //$NON-NLS-1$
+	public static final String OPTION_TargetPlatform = "org.eclipse.jdt.core.compiler.codegen.targetPlatform"; //$NON-NLS-1$
+	public static final String OPTION_Compliance = "org.eclipse.jdt.core.compiler.compliance"; //$NON-NLS-1$
+	public static final String OPTION_Encoding = "org.eclipse.jdt.core.encoding"; //$NON-NLS-1$
+	public static final String OPTION_MaxProblemPerUnit = "org.eclipse.jdt.core.compiler.maxProblemPerUnit"; //$NON-NLS-1$
+	public static final String OPTION_TaskTags = "org.eclipse.jdt.core.compiler.taskTags"; //$NON-NLS-1$
+	public static final String OPTION_TaskPriorities = "org.eclipse.jdt.core.compiler.taskPriorities"; //$NON-NLS-1$
+	public static final String OPTION_TaskCaseSensitive = "org.eclipse.jdt.core.compiler.taskCaseSensitive"; //$NON-NLS-1$
+	public static final String OPTION_InlineJsr = "org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode"; //$NON-NLS-1$
+	public static final String OPTION_ShareCommonFinallyBlocks = "org.eclipse.jdt.core.compiler.codegen.shareCommonFinallyBlocks"; //$NON-NLS-1$
+	public static final String OPTION_ReportNullReference = "org.eclipse.jdt.core.compiler.problem.nullReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportPotentialNullReference = "org.eclipse.jdt.core.compiler.problem.potentialNullReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportRedundantNullCheck = "org.eclipse.jdt.core.compiler.problem.redundantNullCheck"; //$NON-NLS-1$
+	public static final String OPTION_ReportAutoboxing = "org.eclipse.jdt.core.compiler.problem.autoboxing"; //$NON-NLS-1$
+	public static final String OPTION_ReportAnnotationSuperInterface = "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingOverrideAnnotation = "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation = "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingDeprecatedAnnotation = "org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"; //$NON-NLS-1$
+	public static final String OPTION_ReportIncompleteEnumSwitch = "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingEnumCaseDespiteDefault = "org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingDefaultCase = "org.eclipse.jdt.core.compiler.problem.missingDefaultCase"; //$NON-NLS-1$
+	public static final String OPTION_ReportForbiddenReference =  "org.eclipse.jdt.core.compiler.problem.forbiddenReference"; //$NON-NLS-1$
+	public static final String OPTION_ReportDiscouragedReference =  "org.eclipse.jdt.core.compiler.problem.discouragedReference"; //$NON-NLS-1$
+	public static final String OPTION_SuppressWarnings =  "org.eclipse.jdt.core.compiler.problem.suppressWarnings"; //$NON-NLS-1$
+	public static final String OPTION_SuppressOptionalErrors = "org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnhandledWarningToken =  "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedTypeParameter =  "org.eclipse.jdt.core.compiler.problem.unusedTypeParameter"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedWarningToken =  "org.eclipse.jdt.core.compiler.problem.unusedWarningToken"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedLabel =  "org.eclipse.jdt.core.compiler.problem.unusedLabel"; //$NON-NLS-1$
+	public static final String OPTION_FatalOptionalError =  "org.eclipse.jdt.core.compiler.problem.fatalOptionalError"; //$NON-NLS-1$
+	public static final String OPTION_ReportParameterAssignment =  "org.eclipse.jdt.core.compiler.problem.parameterAssignment"; //$NON-NLS-1$
+	public static final String OPTION_ReportFallthroughCase =  "org.eclipse.jdt.core.compiler.problem.fallthroughCase"; //$NON-NLS-1$
+	public static final String OPTION_ReportOverridingMethodWithoutSuperInvocation =  "org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation"; //$NON-NLS-1$
+	public static final String OPTION_GenerateClassFiles = "org.eclipse.jdt.core.compiler.generateClassFiles"; //$NON-NLS-1$
+	public static final String OPTION_Process_Annotations = "org.eclipse.jdt.core.compiler.processAnnotations"; //$NON-NLS-1$
+	public static final String OPTION_ReportRedundantSuperinterface =  "org.eclipse.jdt.core.compiler.problem.redundantSuperinterface"; //$NON-NLS-1$
+	public static final String OPTION_ReportComparingIdentical =  "org.eclipse.jdt.core.compiler.problem.comparingIdentical"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingSynchronizedOnInheritedMethod =  "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingHashCodeMethod =  "org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod"; //$NON-NLS-1$
+	public static final String OPTION_ReportDeadCode =  "org.eclipse.jdt.core.compiler.problem.deadCode"; //$NON-NLS-1$
+	public static final String OPTION_ReportDeadCodeInTrivialIfStatement =  "org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement"; //$NON-NLS-1$
+	public static final String OPTION_ReportTasks = "org.eclipse.jdt.core.compiler.problem.tasks"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnusedObjectAllocation = "org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation";  //$NON-NLS-1$
+	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
+	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
+	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
+	public static final String OPTION_ReportRedundantSpecificationOfTypeArguments =  "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
+	public static final String OPTION_ReportUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.unclosedCloseable"; //$NON-NLS-1$
+	public static final String OPTION_ReportPotentiallyUnclosedCloseable = "org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
+	public static final String OPTION_ReportExplicitlyClosedAutoCloseable = "org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
+	public static final String OPTION_ReportNullSpecViolation = "org.eclipse.jdt.core.compiler.problem.nullSpecViolation";  //$NON-NLS-1$
+	public static final String OPTION_ReportNullAnnotationInferenceConflict = "org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict";  //$NON-NLS-1$
+	public static final String OPTION_ReportNullUncheckedConversion = "org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion";  //$NON-NLS-1$
+	public static final String OPTION_ReportRedundantNullAnnotation = "org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation";  //$NON-NLS-1$
+	public static final String OPTION_AnnotationBasedNullAnalysis = "org.eclipse.jdt.core.compiler.annotation.nullanalysis"; //$NON-NLS-1$
+	public static final String OPTION_NullableAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nullable"; //$NON-NLS-1$
+	public static final String OPTION_NonNullAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnull"; //$NON-NLS-1$
+	public static final String OPTION_NonNullByDefaultAnnotationName = "org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"; //$NON-NLS-1$
+	// defaults for the above:
+	static final char[][] DEFAULT_NULLABLE_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.Nullable".toCharArray()); //$NON-NLS-1$
+	static final char[][] DEFAULT_NONNULL_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNull".toCharArray()); //$NON-NLS-1$
+	static final char[][] DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME = CharOperation.splitOn('.', "org.eclipse.jdt.annotation.NonNullByDefault".toCharArray()); //$NON-NLS-1$
+	public static final String OPTION_ReportMissingNonNullByDefaultAnnotation = "org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation";  //$NON-NLS-1$
+	public static final String OPTION_SyntacticNullAnalysisForFields = "org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields"; //$NON-NLS-1$
+	public static final String OPTION_InheritNullAnnotations = "org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations";  //$NON-NLS-1$
+	public static final String OPTION_ReportNonnullParameterAnnotationDropped = "org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped";  //$NON-NLS-1$
+	/**
+	 * Possible values for configurable options
+	 */
+	public static final String GENERATE = "generate";//$NON-NLS-1$
+	public static final String DO_NOT_GENERATE = "do not generate"; //$NON-NLS-1$
+	public static final String PRESERVE = "preserve"; //$NON-NLS-1$
+	public static final String OPTIMIZE_OUT = "optimize out"; //$NON-NLS-1$
+	public static final String VERSION_1_1 = "1.1"; //$NON-NLS-1$
+	public static final String VERSION_1_2 = "1.2"; //$NON-NLS-1$
+	public static final String VERSION_1_3 = "1.3"; //$NON-NLS-1$
+	public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$
+	public static final String VERSION_JSR14 = "jsr14"; //$NON-NLS-1$
+	public static final String VERSION_CLDC1_1 = "cldc1.1"; //$NON-NLS-1$
+	public static final String VERSION_1_5 = "1.5"; //$NON-NLS-1$
+	public static final String VERSION_1_6 = "1.6"; //$NON-NLS-1$
+	public static final String VERSION_1_7 = "1.7"; //$NON-NLS-1$
+	public static final String VERSION_1_8 = "1.8"; //$NON-NLS-1$
+	public static final String ERROR = "error"; //$NON-NLS-1$
+	public static final String WARNING = "warning"; //$NON-NLS-1$
+	public static final String IGNORE = "ignore"; //$NON-NLS-1$
+	public static final String ENABLED = "enabled"; //$NON-NLS-1$
+	public static final String DISABLED = "disabled"; //$NON-NLS-1$
+	public static final String PUBLIC = "public";	//$NON-NLS-1$
+	public static final String PROTECTED = "protected";	//$NON-NLS-1$
+	public static final String DEFAULT = "default";	//$NON-NLS-1$
+	public static final String PRIVATE = "private";	//$NON-NLS-1$
+	public static final String RETURN_TAG = "return_tag";	//$NON-NLS-1$
+	public static final String NO_TAG = "no_tag";	//$NON-NLS-1$
+	public static final String ALL_STANDARD_TAGS = "all_standard_tags";	//$NON-NLS-1$
+
+	/**
+	 * Bit mask for configurable problems (error/warning threshold)
+	 * Note: bitmask assumes 3 highest bits to denote irritant group (to allow storing 8 groups of 29 bits each
+	 */
+	// group 0
+	public static final int MethodWithConstructorName = IrritantSet.GROUP0 | ASTNode.Bit1;
+	public static final int OverriddenPackageDefaultMethod = IrritantSet.GROUP0 | ASTNode.Bit2;
+	public static final int UsingDeprecatedAPI = IrritantSet.GROUP0 | ASTNode.Bit3;
+	public static final int MaskedCatchBlock = IrritantSet.GROUP0 | ASTNode.Bit4;
+	public static final int UnusedLocalVariable = IrritantSet.GROUP0 | ASTNode.Bit5;
+	public static final int UnusedArgument = IrritantSet.GROUP0 | ASTNode.Bit6;
+	public static final int NoImplicitStringConversion = IrritantSet.GROUP0 | ASTNode.Bit7;
+	public static final int AccessEmulation = IrritantSet.GROUP0 | ASTNode.Bit8;
+	public static final int NonExternalizedString = IrritantSet.GROUP0 | ASTNode.Bit9;
+	public static final int AssertUsedAsAnIdentifier = IrritantSet.GROUP0 | ASTNode.Bit10;
+	public static final int UnusedImport = IrritantSet.GROUP0 | ASTNode.Bit11;
+	public static final int NonStaticAccessToStatic = IrritantSet.GROUP0 | ASTNode.Bit12;
+	public static final int Task = IrritantSet.GROUP0 | ASTNode.Bit13;
+	public static final int NoEffectAssignment = IrritantSet.GROUP0 | ASTNode.Bit14;
+	public static final int IncompatibleNonInheritedInterfaceMethod = IrritantSet.GROUP0 | ASTNode.Bit15;
+	public static final int UnusedPrivateMember = IrritantSet.GROUP0 | ASTNode.Bit16;
+	public static final int LocalVariableHiding = IrritantSet.GROUP0 | ASTNode.Bit17;
+	public static final int FieldHiding = IrritantSet.GROUP0 | ASTNode.Bit18;
+	public static final int AccidentalBooleanAssign = IrritantSet.GROUP0 | ASTNode.Bit19;
+	public static final int EmptyStatement = IrritantSet.GROUP0 | ASTNode.Bit20;
+	public static final int MissingJavadocComments  = IrritantSet.GROUP0 | ASTNode.Bit21;
+	public static final int MissingJavadocTags = IrritantSet.GROUP0 | ASTNode.Bit22;
+	public static final int UnqualifiedFieldAccess = IrritantSet.GROUP0 | ASTNode.Bit23;
+	public static final int UnusedDeclaredThrownException = IrritantSet.GROUP0 | ASTNode.Bit24;
+	public static final int FinallyBlockNotCompleting = IrritantSet.GROUP0 | ASTNode.Bit25;
+	public static final int InvalidJavadoc = IrritantSet.GROUP0 | ASTNode.Bit26;
+	public static final int UnnecessaryTypeCheck = IrritantSet.GROUP0 | ASTNode.Bit27;
+	public static final int UndocumentedEmptyBlock = IrritantSet.GROUP0 | ASTNode.Bit28;
+	public static final int IndirectStaticAccess = IrritantSet.GROUP0 | ASTNode.Bit29;
+	
+	// group 1
+	public static final int UnnecessaryElse  = IrritantSet.GROUP1 | ASTNode.Bit1;
+	public static final int UncheckedTypeOperation = IrritantSet.GROUP1 | ASTNode.Bit2;
+	public static final int FinalParameterBound = IrritantSet.GROUP1 | ASTNode.Bit3;
+	public static final int MissingSerialVersion = IrritantSet.GROUP1 | ASTNode.Bit4;
+	public static final int EnumUsedAsAnIdentifier = IrritantSet.GROUP1 | ASTNode.Bit5;
+	public static final int ForbiddenReference = IrritantSet.GROUP1 | ASTNode.Bit6;
+	public static final int VarargsArgumentNeedCast = IrritantSet.GROUP1 | ASTNode.Bit7;
+	public static final int NullReference = IrritantSet.GROUP1 | ASTNode.Bit8;
+	public static final int AutoBoxing = IrritantSet.GROUP1 | ASTNode.Bit9;
+	public static final int AnnotationSuperInterface = IrritantSet.GROUP1 | ASTNode.Bit10;
+	public static final int TypeHiding = IrritantSet.GROUP1 | ASTNode.Bit11;
+	public static final int MissingOverrideAnnotation = IrritantSet.GROUP1 | ASTNode.Bit12;
+	public static final int MissingEnumConstantCase = IrritantSet.GROUP1 | ASTNode.Bit13;
+	public static final int MissingDeprecatedAnnotation = IrritantSet.GROUP1 | ASTNode.Bit14;
+	public static final int DiscouragedReference = IrritantSet.GROUP1 | ASTNode.Bit15;
+	public static final int UnhandledWarningToken = IrritantSet.GROUP1 | ASTNode.Bit16;
+	public static final int RawTypeReference = IrritantSet.GROUP1 | ASTNode.Bit17;
+	public static final int UnusedLabel = IrritantSet.GROUP1 | ASTNode.Bit18;
+	public static final int ParameterAssignment = IrritantSet.GROUP1 | ASTNode.Bit19;
+	public static final int FallthroughCase = IrritantSet.GROUP1 | ASTNode.Bit20;
+	public static final int OverridingMethodWithoutSuperInvocation = IrritantSet.GROUP1 | ASTNode.Bit21;
+	public static final int PotentialNullReference = IrritantSet.GROUP1 | ASTNode.Bit22;
+	public static final int RedundantNullCheck = IrritantSet.GROUP1 | ASTNode.Bit23;
+	public static final int MissingJavadocTagDescription = IrritantSet.GROUP1 | ASTNode.Bit24;
+	public static final int UnusedTypeArguments = IrritantSet.GROUP1 | ASTNode.Bit25;
+	public static final int UnusedWarningToken = IrritantSet.GROUP1 | ASTNode.Bit26;
+	public static final int RedundantSuperinterface = IrritantSet.GROUP1 | ASTNode.Bit27;
+	public static final int ComparingIdentical = IrritantSet.GROUP1 | ASTNode.Bit28;
+	public static final int MissingSynchronizedModifierInInheritedMethod= IrritantSet.GROUP1 | ASTNode.Bit29;
+
+	// group 2
+	public static final int ShouldImplementHashcode = IrritantSet.GROUP2 | ASTNode.Bit1;
+	public static final int DeadCode = IrritantSet.GROUP2 | ASTNode.Bit2;
+	public static final int Tasks = IrritantSet.GROUP2 | ASTNode.Bit3;
+	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
+	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
+	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
+	public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7;
+	public static final int UnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit8;
+	public static final int PotentiallyUnclosedCloseable = IrritantSet.GROUP2 | ASTNode.Bit9;
+	public static final int ExplicitlyClosedAutoCloseable = IrritantSet.GROUP2 | ASTNode.Bit10;
+	public static final int NullSpecViolation = IrritantSet.GROUP2 | ASTNode.Bit11;
+	public static final int NullAnnotationInferenceConflict = IrritantSet.GROUP2 | ASTNode.Bit12;
+	public static final int NullUncheckedConversion = IrritantSet.GROUP2 | ASTNode.Bit13;
+	public static final int RedundantNullAnnotation = IrritantSet.GROUP2 | ASTNode.Bit14;
+	public static final int MissingNonNullByDefaultAnnotation = IrritantSet.GROUP2 | ASTNode.Bit15;
+	public static final int MissingDefaultCase = IrritantSet.GROUP2 | ASTNode.Bit16;
+	public static final int UnusedTypeParameter = IrritantSet.GROUP2 | ASTNode.Bit17;
+	public static final int NonnullParameterAnnotationDropped = IrritantSet.GROUP2 | ASTNode.Bit18;
+
+	// Severity level for handlers
+	/** 
+	 * Defaults defined at {@link IrritantSet#COMPILER_DEFAULT_ERRORS} 
+	 * @see #resetDefaults()
+	 */
+	protected IrritantSet errorThreshold;
+	/** 
+	 * Defaults defined at {@link IrritantSet#COMPILER_DEFAULT_WARNINGS}
+	 * @see #resetDefaults()
+	 */
+	protected IrritantSet warningThreshold;
+	
+	/**
+	 * Default settings are to be defined in {@lnk CompilerOptions#resetDefaults()}
+	 */
+	
+	/** Classfile debug information, may contain source file name, line numbers, local variable tables, etc... */
+	public int produceDebugAttributes; 
+	/** Compliance level for the compiler, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} */
+	public long complianceLevel;
+	/** Original compliance level for the compiler, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4},
+	 *  Usually same as the field complianceLevel, though the latter could deviate to create temporary sandbox
+	 *  modes during reconcile operations. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633
+	 */
+	public long originalComplianceLevel;
+	/** Java source level, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} */
+	public long sourceLevel;
+	/** Original Java source level, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} 
+	 *  Usually same as the field sourceLevel, though the latter could deviate to create temporary sandbox
+	 *  modes during reconcile operations. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633
+	 * */
+	public long originalSourceLevel;
+	/** VM target level, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} */
+	public long targetJDK;
+	/** Source encoding format */
+	public String defaultEncoding;
+	/** Compiler trace verbosity */
+	public boolean verbose;
+	/** Indicates whether reference info is desired */
+	public boolean produceReferenceInfo;	
+	/** Indicates if unused/optimizable local variables need to be preserved (debugging purpose) */
+	public boolean preserveAllLocalVariables;
+	/** Indicates whether literal expressions are inlined at parse-time or not */
+	public boolean parseLiteralExpressionsAsConstants;
+	/** Max problems per compilation unit */
+	public int maxProblemsPerUnit;
+	/** Tags used to recognize tasks in comments */
+	public char[][] taskTags;
+	/** Respective priorities of recognized task tags */
+	public char[][] taskPriorities;
+	/** Indicate whether tag detection is case sensitive or not */
+	public boolean isTaskCaseSensitive;
+	/** Specify whether deprecation inside deprecated code is to be reported */
+	public boolean reportDeprecationInsideDeprecatedCode;
+	/** Specify whether override of deprecated method is to be reported */
+	public boolean reportDeprecationWhenOverridingDeprecatedMethod;
+	/** Specify if should report unused parameter when implementing abstract method */
+	public boolean reportUnusedParameterWhenImplementingAbstract;
+	/** Specify if should report unused parameter when overriding concrete method */
+	public boolean reportUnusedParameterWhenOverridingConcrete;
+	/** Specify if should report documented unused parameter (in javadoc) */
+	public boolean reportUnusedParameterIncludeDocCommentReference;
+	/** Specify if should reported unused declared thrown exception when overriding method */
+	public boolean reportUnusedDeclaredThrownExceptionWhenOverriding;
+	/** Specify if should reported unused declared thrown exception when documented in javadoc */
+	public boolean reportUnusedDeclaredThrownExceptionIncludeDocCommentReference;
+	/** Specify if should reported unused declared thrown exception when Exception or Throwable */
+	public boolean reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable;
+	/** Specify whether should report constructor/setter method parameter hiding */
+	public boolean reportSpecialParameterHidingField;
+	/** Specify whether trivial deadcode pattern is to be reported (e.g. if (DEBUG) ...) */
+	public boolean reportDeadCodeInTrivialIfStatement;
+	/** Master flag controlling whether doc comment should be processed */
+	public boolean docCommentSupport;
+	/** Specify if invalid javadoc shall be reported */
+	public boolean reportInvalidJavadocTags;
+	/** Only report invalid javadoc above a given level of visibility of associated construct */
+	public int reportInvalidJavadocTagsVisibility;
+	/** Specify if deprecated javadoc ref is allowed */
+	public boolean reportInvalidJavadocTagsDeprecatedRef;
+	/** Specify if non visible javadoc ref is allowed */
+	public boolean reportInvalidJavadocTagsNotVisibleRef;
+	/** Specify when to report missing javadoc tag description */
+	public String reportMissingJavadocTagDescription;
+	/** Only report missing javadoc tags above a given level of visibility of associated construct */
+	public int reportMissingJavadocTagsVisibility;
+	/** Specify if need to flag missing javadoc tags for overriding method */
+	public boolean reportMissingJavadocTagsOverriding;
+	/** Specify if need to flag missing javadoc tags for method type parameters (java 1.5 and above)*/
+	public boolean reportMissingJavadocTagsMethodTypeParameters;
+	/** Only report missing javadoc comment above a given level of visibility of associated construct */
+	public int reportMissingJavadocCommentsVisibility;
+	/** Specify if need to flag missing javadoc comment for overriding method */
+	public boolean reportMissingJavadocCommentsOverriding;
+	/** Indicate whether the JSR bytecode should be inlined to avoid its presence in classfile */
+	public boolean inlineJsrBytecode;
+	/** Indicate whether common escaping finally blocks should be shared */
+	public boolean shareCommonFinallyBlocks;
+	/** Indicate if @SuppressWarning annotations are activated */
+	public boolean suppressWarnings;
+	/** Indicate if @SuppressWarning annotations should also suppress optional errors */
+	public boolean suppressOptionalErrors;
+	/** Specify if should treat optional error as fatal or just like warning */
+	public boolean treatOptionalErrorAsFatal;
+	/** Specify if parser should perform structural recovery in methods */
+	public boolean performMethodsFullRecovery;
+	/** Specify if parser perform statements recovery */
+	public boolean performStatementsRecovery;
+	/** Control whether annotation processing is enabled */
+	public boolean processAnnotations;
+	/** Store annotations */
+	public boolean storeAnnotations;
+	/** Specify if need to report missing override annotation for a method implementing an interface method (java 1.6 and above)*/
+	public boolean reportMissingOverrideAnnotationForInterfaceMethodImplementation;
+	/** Indicate if annotation processing generates classfiles */
+	public boolean generateClassFiles;
+	/** Indicate if method bodies should be ignored */
+	public boolean ignoreMethodBodies;
+	/** Raise null related warnings for variables tainted inside an assert statement (java 1.4 and above)*/
+	public boolean includeNullInfoFromAsserts;
+	/** Controls whether forced generic type problems get reported  */
+	public boolean reportUnavoidableGenericTypeProblems;
+	/** Indicates that the 'ignore optional problems from source folder' option need to be ignored
+	 *  See https://bugs.eclipse.org/bugs/show_bug.cgi?id=372377
+	 */
+	public boolean ignoreSourceFolderWarningOption;
+
+	// === Support for Null Annotations: ===
+	/** Master switch for null analysis based on annotations: */
+	public boolean isAnnotationBasedNullAnalysisEnabled;
+	/** Fully qualified name of annotation to use as marker for nullable types. */
+	public char[][] nullableAnnotationName;
+	/** Fully qualified name of annotation to use as marker for nonnull types. */
+	public char[][] nonNullAnnotationName;
+	/** Fully qualified name of annotation to use as marker for default nonnull. */
+	public char[][] nonNullByDefaultAnnotationName;
+	/** TagBits-encoded default for non-annotated types. */
+	public long intendedDefaultNonNullness; // 0 or TagBits#AnnotationNonNull
+	/** Should resources (objects of type Closeable) be analysed for matching calls to close()? */
+	public boolean analyseResourceLeaks;
+	/** Should missing enum cases be reported even if a default case exists in the same switch? */
+	public boolean reportMissingEnumCaseDespiteDefault;
+	
+	/** Should the compiler tolerate illegal ambiguous varargs invocation in compliance < 1.7 
+	 * to be bug compatible with javac? (bug 383780) */
+	public static boolean tolerateIllegalAmbiguousVarargsInvocation;
+	
+	{
+		String tolerateIllegalAmbiguousVarargs = System.getProperty("tolerateIllegalAmbiguousVarargsInvocation"); //$NON-NLS-1$
+		tolerateIllegalAmbiguousVarargsInvocation = tolerateIllegalAmbiguousVarargs != null && tolerateIllegalAmbiguousVarargs.equalsIgnoreCase("true"); //$NON-NLS-1$
+	}
+	/** Should null annotations of overridden methods be inherited? */
+	public boolean inheritNullAnnotations;
+
+	/** Should immediate null-check for fields be considered during null analysis (syntactical match)? */
+	public boolean enableSyntacticNullAnalysisForFields;
+
+	// keep in sync with warningTokenToIrritant and warningTokenFromIrritant
+	public final static String[] warningTokens = {
+		"all", //$NON-NLS-1$
+		"boxing", //$NON-NLS-1$
+		"cast", //$NON-NLS-1$
+		"dep-ann", //$NON-NLS-1$
+		"deprecation", //$NON-NLS-1$
+		"fallthrough", //$NON-NLS-1$
+		"finally", //$NON-NLS-1$
+		"hiding", //$NON-NLS-1$
+		"incomplete-switch", //$NON-NLS-1$
+		"javadoc", //$NON-NLS-1$
+		"nls", //$NON-NLS-1$
+		"null", //$NON-NLS-1$
+		"rawtypes", //$NON-NLS-1$
+		"resource", //$NON-NLS-1$
+		"restriction", //$NON-NLS-1$		
+		"serial", //$NON-NLS-1$
+		"static-access", //$NON-NLS-1$
+		"static-method", //$NON-NLS-1$
+		"super", //$NON-NLS-1$
+		"synthetic-access", //$NON-NLS-1$
+		"sync-override",	//$NON-NLS-1$
+		"unchecked", //$NON-NLS-1$
+		"unqualified-field-access", //$NON-NLS-1$
+		"unused", //$NON-NLS-1$
+	};
+
+	/**
+	 * Initializing the compiler options with defaults
+	 */
+	public CompilerOptions(){
+		this(null); // use default options
+	}
+
+	/**
+	 * Initializing the compiler options with external settings
+	 * @param settings
+	 */
+	public CompilerOptions(Map settings){
+		resetDefaults();
+		if (settings != null) {
+			set(settings);
+		}
+	}
+
+	/**
+	 * @deprecated used to preserve 3.1 and 3.2M4 compatibility of some Compiler constructors
+	 */
+	public CompilerOptions(Map settings, boolean parseLiteralExpressionsAsConstants){
+		this(settings);
+		this.parseLiteralExpressionsAsConstants = parseLiteralExpressionsAsConstants;
+	}
+
+	/**
+	 * Return the most specific option key controlling this irritant. Note that in some case, some irritant is controlled by
+	 * other master options (e.g. javadoc, deprecation, etc.).
+	 * This information is intended for grouping purpose (several problems governed by a rule)
+	 */
+	public static String optionKeyFromIrritant(int irritant) {
+		// keep in sync with warningTokens and warningTokenToIrritant
+		switch (irritant) {
+			case MethodWithConstructorName :
+				return OPTION_ReportMethodWithConstructorName;
+			case OverriddenPackageDefaultMethod  :
+				return OPTION_ReportOverridingPackageDefaultMethod;
+			case UsingDeprecatedAPI :
+			case (InvalidJavadoc | UsingDeprecatedAPI) :
+				return OPTION_ReportDeprecation;
+			case MaskedCatchBlock  :
+				return OPTION_ReportHiddenCatchBlock;
+			case UnusedLocalVariable :
+				return OPTION_ReportUnusedLocal;
+			case UnusedArgument :
+				return OPTION_ReportUnusedParameter;
+			case NoImplicitStringConversion :
+				return OPTION_ReportNoImplicitStringConversion;
+			case AccessEmulation :
+				return OPTION_ReportSyntheticAccessEmulation;
+			case NonExternalizedString :
+				return OPTION_ReportNonExternalizedStringLiteral;
+			case AssertUsedAsAnIdentifier :
+				return OPTION_ReportAssertIdentifier;
+			case UnusedImport :
+				return OPTION_ReportUnusedImport;
+			case NonStaticAccessToStatic :
+				return OPTION_ReportNonStaticAccessToStatic;
+			case Task :
+				return OPTION_TaskTags;
+			case NoEffectAssignment :
+				return OPTION_ReportNoEffectAssignment;
+			case IncompatibleNonInheritedInterfaceMethod :
+				return OPTION_ReportIncompatibleNonInheritedInterfaceMethod;
+			case UnusedPrivateMember :
+				return OPTION_ReportUnusedPrivateMember;
+			case LocalVariableHiding :
+				return OPTION_ReportLocalVariableHiding;
+			case FieldHiding :
+				return OPTION_ReportFieldHiding;
+			case AccidentalBooleanAssign :
+				return OPTION_ReportPossibleAccidentalBooleanAssignment;
+			case EmptyStatement :
+				return OPTION_ReportEmptyStatement;
+			case MissingJavadocComments  :
+				return OPTION_ReportMissingJavadocComments;
+			case MissingJavadocTags :
+				return OPTION_ReportMissingJavadocTags;
+			case UnqualifiedFieldAccess :
+				return OPTION_ReportUnqualifiedFieldAccess;
+			case UnusedDeclaredThrownException :
+				return OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding;
+			case FinallyBlockNotCompleting :
+				return OPTION_ReportFinallyBlockNotCompletingNormally;
+			case InvalidJavadoc :
+				return OPTION_ReportInvalidJavadoc;
+			case UnnecessaryTypeCheck :
+				return OPTION_ReportUnnecessaryTypeCheck;
+			case UndocumentedEmptyBlock :
+				return OPTION_ReportUndocumentedEmptyBlock;
+			case IndirectStaticAccess :
+				return OPTION_ReportIndirectStaticAccess;
+			case UnnecessaryElse  :
+				return OPTION_ReportUnnecessaryElse;
+			case UncheckedTypeOperation :
+				return OPTION_ReportUncheckedTypeOperation;
+			case FinalParameterBound :
+				return OPTION_ReportFinalParameterBound;
+			case MissingSerialVersion :
+				return OPTION_ReportMissingSerialVersion ;
+			case EnumUsedAsAnIdentifier :
+				return OPTION_ReportEnumIdentifier;
+			case ForbiddenReference :
+				return OPTION_ReportForbiddenReference;
+			case VarargsArgumentNeedCast :
+				return OPTION_ReportVarargsArgumentNeedCast;
+			case NullReference :
+				return OPTION_ReportNullReference;
+			case PotentialNullReference :
+				return OPTION_ReportPotentialNullReference;
+			case RedundantNullCheck :
+				return OPTION_ReportRedundantNullCheck;
+			case AutoBoxing :
+				return OPTION_ReportAutoboxing;
+			case AnnotationSuperInterface :
+				return OPTION_ReportAnnotationSuperInterface;
+			case TypeHiding :
+				return OPTION_ReportTypeParameterHiding;
+			case MissingOverrideAnnotation :
+				return OPTION_ReportMissingOverrideAnnotation;
+			case MissingEnumConstantCase :
+				return OPTION_ReportIncompleteEnumSwitch;
+			case MissingDefaultCase :
+				return OPTION_ReportMissingDefaultCase;
+			case MissingDeprecatedAnnotation :
+				return OPTION_ReportMissingDeprecatedAnnotation;
+			case DiscouragedReference :
+				return OPTION_ReportDiscouragedReference;
+			case UnhandledWarningToken :
+				return OPTION_ReportUnhandledWarningToken;
+			case RawTypeReference :
+				return OPTION_ReportRawTypeReference;
+			case UnusedLabel :
+				return OPTION_ReportUnusedLabel;
+			case ParameterAssignment :
+				return OPTION_ReportParameterAssignment;
+			case FallthroughCase :
+				return OPTION_ReportFallthroughCase;
+			case OverridingMethodWithoutSuperInvocation :
+				return OPTION_ReportOverridingMethodWithoutSuperInvocation;
+			case MissingJavadocTagDescription :
+				return OPTION_ReportMissingJavadocTagDescription;
+			case UnusedTypeArguments :
+				return OPTION_ReportUnusedTypeArgumentsForMethodInvocation;
+			case UnusedTypeParameter:
+				return OPTION_ReportUnusedTypeParameter;
+			case UnusedWarningToken :
+				return OPTION_ReportUnusedWarningToken;
+			case RedundantSuperinterface :
+				return OPTION_ReportRedundantSuperinterface;
+			case ComparingIdentical :
+				return OPTION_ReportComparingIdentical;
+			case MissingSynchronizedModifierInInheritedMethod :
+				return OPTION_ReportMissingSynchronizedOnInheritedMethod;
+			case ShouldImplementHashcode :
+				return OPTION_ReportMissingHashCodeMethod;
+			case DeadCode :
+				return OPTION_ReportDeadCode;
+			case UnusedObjectAllocation:
+				return OPTION_ReportUnusedObjectAllocation;
+			case MethodCanBeStatic :
+				return OPTION_ReportMethodCanBeStatic;
+			case MethodCanBePotentiallyStatic :
+				return OPTION_ReportMethodCanBePotentiallyStatic;
+			case MissingNonNullByDefaultAnnotation :
+				return OPTION_ReportMissingNonNullByDefaultAnnotation;
+			case RedundantSpecificationOfTypeArguments :
+				return OPTION_ReportRedundantSpecificationOfTypeArguments;
+			case UnclosedCloseable :
+				return OPTION_ReportUnclosedCloseable;
+			case PotentiallyUnclosedCloseable :
+				return OPTION_ReportPotentiallyUnclosedCloseable;
+			case ExplicitlyClosedAutoCloseable :
+				return OPTION_ReportExplicitlyClosedAutoCloseable;
+			case NullSpecViolation :
+				return OPTION_ReportNullSpecViolation;
+			case NullAnnotationInferenceConflict :
+				return OPTION_ReportNullAnnotationInferenceConflict;
+			case NullUncheckedConversion :
+				return OPTION_ReportNullUncheckedConversion;
+			case RedundantNullAnnotation :
+				return OPTION_ReportRedundantNullAnnotation;
+			case NonnullParameterAnnotationDropped:
+				return OPTION_ReportNonnullParameterAnnotationDropped;
+		}
+		return null;
+	}
+
+	public static String versionFromJdkLevel(long jdkLevel) {
+		switch ((int)(jdkLevel>>16)) {
+			case ClassFileConstants.MAJOR_VERSION_1_1 :
+				if (jdkLevel == ClassFileConstants.JDK1_1)
+					return VERSION_1_1;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_2 :
+				if (jdkLevel == ClassFileConstants.JDK1_2)
+					return VERSION_1_2;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_3 :
+				if (jdkLevel == ClassFileConstants.JDK1_3)
+					return VERSION_1_3;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_4 :
+				if (jdkLevel == ClassFileConstants.JDK1_4)
+					return VERSION_1_4;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_5 :
+				if (jdkLevel == ClassFileConstants.JDK1_5)
+					return VERSION_1_5;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_6 :
+				if (jdkLevel == ClassFileConstants.JDK1_6)
+					return VERSION_1_6;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_7 :
+				if (jdkLevel == ClassFileConstants.JDK1_7)
+					return VERSION_1_7;
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_8 :
+				if (jdkLevel == ClassFileConstants.JDK1_8)
+					return VERSION_1_8;
+				break;
+		}
+		return Util.EMPTY_STRING; // unknown version
+	}
+
+	public static long versionToJdkLevel(Object versionID) {
+		if (versionID instanceof String) {
+			String version = (String) versionID;
+			// verification is optimized for all versions with same length and same "1." prefix
+			if (version.length() == 3 && version.charAt(0) == '1' && version.charAt(1) == '.') {
+				switch (version.charAt(2)) {
+					case '1':
+						return ClassFileConstants.JDK1_1;
+					case '2':
+						return ClassFileConstants.JDK1_2;
+					case '3':
+						return ClassFileConstants.JDK1_3;
+					case '4':
+						return ClassFileConstants.JDK1_4;
+					case '5':
+						return ClassFileConstants.JDK1_5;
+					case '6':
+						return ClassFileConstants.JDK1_6;
+					case '7':
+						return ClassFileConstants.JDK1_7;
+					case '8':
+						return ClassFileConstants.JDK1_8;
+					default:
+						return 0; // unknown
+				}
+			}
+			if (VERSION_JSR14.equals(versionID)) {
+				return ClassFileConstants.JDK1_4;
+			}
+			if (VERSION_CLDC1_1.equals(versionID)) {
+				return ClassFileConstants.CLDC_1_1;
+			}
+		}
+		return 0; // unknown
+	}
+
+	/**
+	 * Return all warning option names for use as keys in compiler options maps.
+	 * @return all warning option names
+	 */
+	public static String[] warningOptionNames() {
+		String[] result = {
+			OPTION_ReportAnnotationSuperInterface,
+			OPTION_ReportAssertIdentifier,
+			OPTION_ReportAutoboxing,
+			OPTION_ReportComparingIdentical,
+			OPTION_ReportDeadCode,
+			OPTION_ReportDeadCodeInTrivialIfStatement,
+			OPTION_ReportDeprecation,
+			OPTION_ReportDeprecationInDeprecatedCode,
+			OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
+			OPTION_ReportDiscouragedReference,
+			OPTION_ReportEmptyStatement,
+			OPTION_ReportEnumIdentifier,
+			OPTION_ReportFallthroughCase,
+			OPTION_ReportFieldHiding,
+			OPTION_ReportFinallyBlockNotCompletingNormally,
+			OPTION_ReportFinalParameterBound,
+			OPTION_ReportForbiddenReference,
+			OPTION_ReportHiddenCatchBlock,
+			OPTION_ReportIncompatibleNonInheritedInterfaceMethod,
+			OPTION_ReportMissingDefaultCase,
+			OPTION_ReportIncompleteEnumSwitch,
+			OPTION_ReportMissingEnumCaseDespiteDefault,
+			OPTION_ReportIndirectStaticAccess,
+			OPTION_ReportInvalidJavadoc,
+			OPTION_ReportInvalidJavadocTags,
+			OPTION_ReportInvalidJavadocTagsDeprecatedRef,
+			OPTION_ReportInvalidJavadocTagsNotVisibleRef,
+			OPTION_ReportInvalidJavadocTagsVisibility,
+			OPTION_ReportLocalVariableHiding,
+			OPTION_ReportMethodCanBePotentiallyStatic,
+			OPTION_ReportMethodCanBeStatic,
+			OPTION_ReportMethodWithConstructorName,
+			OPTION_ReportMissingDeprecatedAnnotation,
+			OPTION_ReportMissingHashCodeMethod,
+			OPTION_ReportMissingJavadocComments,
+			OPTION_ReportMissingJavadocCommentsOverriding,
+			OPTION_ReportMissingJavadocCommentsVisibility,
+			OPTION_ReportMissingJavadocTagDescription,
+			OPTION_ReportMissingJavadocTags,
+			OPTION_ReportMissingJavadocTagsMethodTypeParameters,
+			OPTION_ReportMissingJavadocTagsOverriding,
+			OPTION_ReportMissingJavadocTagsVisibility,
+			OPTION_ReportMissingOverrideAnnotation,
+			OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
+			OPTION_ReportMissingSerialVersion,
+			OPTION_ReportMissingSynchronizedOnInheritedMethod,
+			OPTION_ReportNoEffectAssignment,
+			OPTION_ReportNoImplicitStringConversion,
+			OPTION_ReportNonExternalizedStringLiteral,
+			OPTION_ReportNonStaticAccessToStatic,
+			OPTION_ReportNullReference,
+			OPTION_ReportOverridingMethodWithoutSuperInvocation,
+			OPTION_ReportOverridingPackageDefaultMethod,
+			OPTION_ReportParameterAssignment,
+			OPTION_ReportPossibleAccidentalBooleanAssignment,
+			OPTION_ReportPotentialNullReference,
+			OPTION_ReportRawTypeReference,
+			OPTION_ReportRedundantNullCheck,
+			OPTION_ReportRedundantSuperinterface,
+			OPTION_ReportRedundantSpecificationOfTypeArguments,
+			OPTION_ReportSpecialParameterHidingField,
+			OPTION_ReportSyntheticAccessEmulation,
+			OPTION_ReportTasks,
+			OPTION_ReportTypeParameterHiding,
+			OPTION_ReportUnavoidableGenericTypeProblems,
+			OPTION_ReportUncheckedTypeOperation,
+			OPTION_ReportUndocumentedEmptyBlock,
+			OPTION_ReportUnhandledWarningToken,
+			OPTION_ReportUnnecessaryElse,
+			OPTION_ReportUnnecessaryTypeCheck,
+			OPTION_ReportUnqualifiedFieldAccess,
+			OPTION_ReportUnusedDeclaredThrownException,
+			OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable,
+			OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
+			OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding,
+			OPTION_ReportUnusedImport,
+			OPTION_ReportUnusedLabel,
+			OPTION_ReportUnusedLocal,
+			OPTION_ReportUnusedObjectAllocation,
+			OPTION_ReportUnusedParameter,
+			OPTION_ReportUnusedParameterIncludeDocCommentReference,
+			OPTION_ReportUnusedParameterWhenImplementingAbstract,
+			OPTION_ReportUnusedParameterWhenOverridingConcrete,
+			OPTION_ReportUnusedPrivateMember,
+			OPTION_ReportUnusedTypeArgumentsForMethodInvocation,
+			OPTION_ReportUnusedWarningToken,
+			OPTION_ReportVarargsArgumentNeedCast,
+			OPTION_ReportUnclosedCloseable,
+			OPTION_ReportPotentiallyUnclosedCloseable,
+			OPTION_ReportExplicitlyClosedAutoCloseable,
+			OPTION_AnnotationBasedNullAnalysis,
+			OPTION_NonNullAnnotationName,
+			OPTION_NullableAnnotationName,
+			OPTION_NonNullByDefaultAnnotationName,
+			OPTION_ReportMissingNonNullByDefaultAnnotation,
+			OPTION_ReportNullSpecViolation,
+			OPTION_ReportNullAnnotationInferenceConflict,
+			OPTION_ReportNullUncheckedConversion,
+			OPTION_ReportRedundantNullAnnotation,
+			OPTION_SyntacticNullAnalysisForFields,
+			OPTION_ReportUnusedTypeParameter,
+			OPTION_InheritNullAnnotations,
+			OPTION_ReportNonnullParameterAnnotationDropped
+		};
+		return result;
+	}
+
+	/**
+	 * For suppressable warnings
+	 */
+	public static String warningTokenFromIrritant(int irritant) {
+		// keep in sync with warningTokens and warningTokenToIrritant
+		switch (irritant) {
+			case (InvalidJavadoc | UsingDeprecatedAPI) :
+			case UsingDeprecatedAPI :
+				return "deprecation"; //$NON-NLS-1$
+			case FinallyBlockNotCompleting :
+				return "finally"; //$NON-NLS-1$
+			case FieldHiding :
+			case LocalVariableHiding :
+			case MaskedCatchBlock :
+				return "hiding"; //$NON-NLS-1$
+			case NonExternalizedString :
+				return "nls"; //$NON-NLS-1$
+			case UnnecessaryTypeCheck :
+				return "cast"; //$NON-NLS-1$
+			case IndirectStaticAccess :
+			case NonStaticAccessToStatic :
+				return "static-access"; //$NON-NLS-1$
+			case AccessEmulation :
+				return "synthetic-access"; //$NON-NLS-1$
+			case UnqualifiedFieldAccess :
+				return "unqualified-field-access"; //$NON-NLS-1$
+			case UncheckedTypeOperation :
+				return "unchecked"; //$NON-NLS-1$
+			case MissingSerialVersion :
+				return "serial"; //$NON-NLS-1$
+			case AutoBoxing :
+				return "boxing"; //$NON-NLS-1$
+			case TypeHiding :
+				return "hiding"; //$NON-NLS-1$
+			case MissingEnumConstantCase :
+			case MissingDefaultCase :
+				return "incomplete-switch"; //$NON-NLS-1$
+			case MissingDeprecatedAnnotation :
+				return "dep-ann"; //$NON-NLS-1$
+			case RawTypeReference :
+				return "rawtypes"; //$NON-NLS-1$
+			case UnusedLabel :
+			case UnusedTypeArguments :
+			case RedundantSuperinterface :
+			case UnusedLocalVariable :
+			case UnusedArgument :
+			case UnusedImport :
+			case UnusedPrivateMember :
+			case UnusedDeclaredThrownException :
+			case DeadCode :
+			case UnusedObjectAllocation :
+			case RedundantSpecificationOfTypeArguments :
+			case UnusedTypeParameter:
+				return "unused"; //$NON-NLS-1$
+			case DiscouragedReference :
+			case ForbiddenReference :
+				return "restriction"; //$NON-NLS-1$
+			case NullReference :
+			case PotentialNullReference :
+			case RedundantNullCheck :
+			case NullSpecViolation :
+			case NullAnnotationInferenceConflict :
+			case NullUncheckedConversion :
+			case RedundantNullAnnotation :
+			case MissingNonNullByDefaultAnnotation:
+			case NonnullParameterAnnotationDropped:
+				return "null"; //$NON-NLS-1$
+			case FallthroughCase :
+				return "fallthrough"; //$NON-NLS-1$
+			case OverridingMethodWithoutSuperInvocation :
+				return "super"; //$NON-NLS-1$
+			case MethodCanBeStatic :
+			case MethodCanBePotentiallyStatic :
+				return "static-method"; //$NON-NLS-1$
+			case PotentiallyUnclosedCloseable:
+			case UnclosedCloseable:
+			case ExplicitlyClosedAutoCloseable:
+				return "resource"; //$NON-NLS-1$
+			case InvalidJavadoc :
+			case MissingJavadocComments :
+			case MissingJavadocTags:
+				return "javadoc"; //$NON-NLS-1$
+			case MissingSynchronizedModifierInInheritedMethod:
+				return "sync-override";	 //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	public static IrritantSet warningTokenToIrritants(String warningToken) {
+		// keep in sync with warningTokens and warningTokenFromIrritant
+		if (warningToken == null || warningToken.length() == 0) return null;
+		switch (warningToken.charAt(0)) {
+			case 'a' :
+				if ("all".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.ALL;
+				break;
+			case 'b' :
+				if ("boxing".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.BOXING;
+				break;
+			case 'c' :
+				if ("cast".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.CAST;
+				break;
+			case 'd' :
+				if ("deprecation".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.DEPRECATION;
+				if ("dep-ann".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.DEP_ANN;
+				break;
+			case 'f' :
+				if ("fallthrough".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.FALLTHROUGH;
+				if ("finally".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.FINALLY;
+				break;
+			case 'h' :
+				if ("hiding".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.HIDING;
+				break;
+			case 'i' :
+				if ("incomplete-switch".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.INCOMPLETE_SWITCH;
+				break;
+			case 'j' :
+				if ("javadoc".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.JAVADOC;
+				break;
+			case 'n' :
+				if ("nls".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.NLS;
+				if ("null".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.NULL;
+				break;
+			case 'r' :
+				if ("rawtypes".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.RAW;
+				if ("resource".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.RESOURCE;
+				if ("restriction".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.RESTRICTION;
+				break;
+			case 's' :
+				if ("serial".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.SERIAL;
+				if ("static-access".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.STATIC_ACCESS;
+				if ("static-method".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.STATIC_METHOD;
+				if ("synthetic-access".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.SYNTHETIC_ACCESS;
+				if ("super".equals(warningToken)) { //$NON-NLS-1$
+					return IrritantSet.SUPER;
+				}
+				if ("sync-override".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.SYNCHRONIZED;
+				break;
+			case 'u' :
+				if ("unused".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.UNUSED;
+				if ("unchecked".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.UNCHECKED;
+				if ("unqualified-field-access".equals(warningToken)) //$NON-NLS-1$
+					return IrritantSet.UNQUALIFIED_FIELD_ACCESS;
+				break;
+		}
+		return null;
+	}
+
+	
+	public Map getMap() {
+		Map optionsMap = new HashMap(30);
+		optionsMap.put(OPTION_LocalVariableAttribute, (this.produceDebugAttributes & ClassFileConstants.ATTR_VARS) != 0 ? GENERATE : DO_NOT_GENERATE);
+		optionsMap.put(OPTION_LineNumberAttribute, (this.produceDebugAttributes & ClassFileConstants.ATTR_LINES) != 0 ? GENERATE : DO_NOT_GENERATE);
+		optionsMap.put(OPTION_SourceFileAttribute, (this.produceDebugAttributes & ClassFileConstants.ATTR_SOURCE) != 0 ? GENERATE : DO_NOT_GENERATE);
+		optionsMap.put(OPTION_PreserveUnusedLocal, this.preserveAllLocalVariables ? PRESERVE : OPTIMIZE_OUT);
+		optionsMap.put(OPTION_DocCommentSupport, this.docCommentSupport ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMethodWithConstructorName, getSeverityString(MethodWithConstructorName));
+		optionsMap.put(OPTION_ReportOverridingPackageDefaultMethod, getSeverityString(OverriddenPackageDefaultMethod));
+		optionsMap.put(OPTION_ReportDeprecation, getSeverityString(UsingDeprecatedAPI));
+		optionsMap.put(OPTION_ReportDeprecationInDeprecatedCode, this.reportDeprecationInsideDeprecatedCode ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, this.reportDeprecationWhenOverridingDeprecatedMethod ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportHiddenCatchBlock, getSeverityString(MaskedCatchBlock));
+		optionsMap.put(OPTION_ReportUnusedLocal, getSeverityString(UnusedLocalVariable));
+		optionsMap.put(OPTION_ReportUnusedParameter, getSeverityString(UnusedArgument));
+		optionsMap.put(OPTION_ReportUnusedImport, getSeverityString(UnusedImport));
+		optionsMap.put(OPTION_ReportSyntheticAccessEmulation, getSeverityString(AccessEmulation));
+		optionsMap.put(OPTION_ReportNoEffectAssignment, getSeverityString(NoEffectAssignment));
+		optionsMap.put(OPTION_ReportNonExternalizedStringLiteral, getSeverityString(NonExternalizedString));
+		optionsMap.put(OPTION_ReportNoImplicitStringConversion, getSeverityString(NoImplicitStringConversion));
+		optionsMap.put(OPTION_ReportNonStaticAccessToStatic, getSeverityString(NonStaticAccessToStatic));
+		optionsMap.put(OPTION_ReportIndirectStaticAccess, getSeverityString(IndirectStaticAccess));
+		optionsMap.put(OPTION_ReportIncompatibleNonInheritedInterfaceMethod, getSeverityString(IncompatibleNonInheritedInterfaceMethod));
+		optionsMap.put(OPTION_ReportUnusedPrivateMember, getSeverityString(UnusedPrivateMember));
+		optionsMap.put(OPTION_ReportLocalVariableHiding, getSeverityString(LocalVariableHiding));
+		optionsMap.put(OPTION_ReportFieldHiding, getSeverityString(FieldHiding));
+		optionsMap.put(OPTION_ReportTypeParameterHiding, getSeverityString(TypeHiding));
+		optionsMap.put(OPTION_ReportPossibleAccidentalBooleanAssignment, getSeverityString(AccidentalBooleanAssign));
+		optionsMap.put(OPTION_ReportEmptyStatement, getSeverityString(EmptyStatement));
+		optionsMap.put(OPTION_ReportAssertIdentifier, getSeverityString(AssertUsedAsAnIdentifier));
+		optionsMap.put(OPTION_ReportEnumIdentifier, getSeverityString(EnumUsedAsAnIdentifier));
+		optionsMap.put(OPTION_ReportUndocumentedEmptyBlock, getSeverityString(UndocumentedEmptyBlock));
+		optionsMap.put(OPTION_ReportUnnecessaryTypeCheck, getSeverityString(UnnecessaryTypeCheck));
+		optionsMap.put(OPTION_ReportUnnecessaryElse, getSeverityString(UnnecessaryElse));
+		optionsMap.put(OPTION_ReportAutoboxing, getSeverityString(AutoBoxing));
+		optionsMap.put(OPTION_ReportAnnotationSuperInterface, getSeverityString(AnnotationSuperInterface));
+		optionsMap.put(OPTION_ReportIncompleteEnumSwitch, getSeverityString(MissingEnumConstantCase));
+		optionsMap.put(OPTION_ReportMissingEnumCaseDespiteDefault, this.reportMissingEnumCaseDespiteDefault ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMissingDefaultCase, getSeverityString(MissingDefaultCase));
+		optionsMap.put(OPTION_ReportInvalidJavadoc, getSeverityString(InvalidJavadoc));
+		optionsMap.put(OPTION_ReportInvalidJavadocTagsVisibility, getVisibilityString(this.reportInvalidJavadocTagsVisibility));
+		optionsMap.put(OPTION_ReportInvalidJavadocTags, this.reportInvalidJavadocTags ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportInvalidJavadocTagsDeprecatedRef, this.reportInvalidJavadocTagsDeprecatedRef ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportInvalidJavadocTagsNotVisibleRef, this.reportInvalidJavadocTagsNotVisibleRef ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMissingJavadocTags, getSeverityString(MissingJavadocTags));
+		optionsMap.put(OPTION_ReportMissingJavadocTagsVisibility, getVisibilityString(this.reportMissingJavadocTagsVisibility));
+		optionsMap.put(OPTION_ReportMissingJavadocTagsOverriding, this.reportMissingJavadocTagsOverriding ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMissingJavadocTagsMethodTypeParameters, this.reportMissingJavadocTagsMethodTypeParameters ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMissingJavadocComments, getSeverityString(MissingJavadocComments));
+		optionsMap.put(OPTION_ReportMissingJavadocTagDescription, this.reportMissingJavadocTagDescription);
+		optionsMap.put(OPTION_ReportMissingJavadocCommentsVisibility, getVisibilityString(this.reportMissingJavadocCommentsVisibility));
+		optionsMap.put(OPTION_ReportMissingJavadocCommentsOverriding, this.reportMissingJavadocCommentsOverriding ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportFinallyBlockNotCompletingNormally, getSeverityString(FinallyBlockNotCompleting));
+		optionsMap.put(OPTION_ReportUnusedDeclaredThrownException, getSeverityString(UnusedDeclaredThrownException));
+		optionsMap.put(OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, this.reportUnusedDeclaredThrownExceptionWhenOverriding ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference, this.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable, this.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnqualifiedFieldAccess, getSeverityString(UnqualifiedFieldAccess));
+		optionsMap.put(OPTION_ReportUnavoidableGenericTypeProblems, this.reportUnavoidableGenericTypeProblems ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUncheckedTypeOperation, getSeverityString(UncheckedTypeOperation));
+		optionsMap.put(OPTION_ReportRawTypeReference, getSeverityString(RawTypeReference));
+		optionsMap.put(OPTION_ReportFinalParameterBound, getSeverityString(FinalParameterBound));
+		optionsMap.put(OPTION_ReportMissingSerialVersion, getSeverityString(MissingSerialVersion));
+		optionsMap.put(OPTION_ReportForbiddenReference, getSeverityString(ForbiddenReference));
+		optionsMap.put(OPTION_ReportDiscouragedReference, getSeverityString(DiscouragedReference));
+		optionsMap.put(OPTION_ReportVarargsArgumentNeedCast, getSeverityString(VarargsArgumentNeedCast));
+		optionsMap.put(OPTION_ReportMissingOverrideAnnotation, getSeverityString(MissingOverrideAnnotation));
+		optionsMap.put(OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation, this.reportMissingOverrideAnnotationForInterfaceMethodImplementation ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMissingDeprecatedAnnotation, getSeverityString(MissingDeprecatedAnnotation));
+		optionsMap.put(OPTION_ReportUnusedLabel, getSeverityString(UnusedLabel));
+		optionsMap.put(OPTION_ReportUnusedTypeArgumentsForMethodInvocation, getSeverityString(UnusedTypeArguments));
+		optionsMap.put(OPTION_Compliance, versionFromJdkLevel(this.complianceLevel));
+		optionsMap.put(OPTION_Source, versionFromJdkLevel(this.sourceLevel));
+		optionsMap.put(OPTION_TargetPlatform, versionFromJdkLevel(this.targetJDK));
+		optionsMap.put(OPTION_FatalOptionalError, this.treatOptionalErrorAsFatal ? ENABLED : DISABLED);
+		if (this.defaultEncoding != null) {
+			optionsMap.put(OPTION_Encoding, this.defaultEncoding);
+		}
+		optionsMap.put(OPTION_TaskTags, this.taskTags == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.taskTags,',')));
+		optionsMap.put(OPTION_TaskPriorities, this.taskPriorities == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.taskPriorities,',')));
+		optionsMap.put(OPTION_TaskCaseSensitive, this.isTaskCaseSensitive ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnusedParameterWhenImplementingAbstract, this.reportUnusedParameterWhenImplementingAbstract ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnusedParameterWhenOverridingConcrete, this.reportUnusedParameterWhenOverridingConcrete ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnusedParameterIncludeDocCommentReference, this.reportUnusedParameterIncludeDocCommentReference ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportSpecialParameterHidingField, this.reportSpecialParameterHidingField ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_MaxProblemPerUnit, String.valueOf(this.maxProblemsPerUnit));
+		optionsMap.put(OPTION_InlineJsr, this.inlineJsrBytecode ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ShareCommonFinallyBlocks, this.shareCommonFinallyBlocks ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
+		optionsMap.put(OPTION_ReportPotentialNullReference, getSeverityString(PotentialNullReference));
+		optionsMap.put(OPTION_ReportRedundantNullCheck, getSeverityString(RedundantNullCheck));
+		optionsMap.put(OPTION_SuppressWarnings, this.suppressWarnings ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_SuppressOptionalErrors, this.suppressOptionalErrors ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportUnhandledWarningToken, getSeverityString(UnhandledWarningToken));
+		optionsMap.put(OPTION_ReportUnusedWarningToken, getSeverityString(UnusedWarningToken));
+		optionsMap.put(OPTION_ReportParameterAssignment, getSeverityString(ParameterAssignment));
+		optionsMap.put(OPTION_ReportFallthroughCase, getSeverityString(FallthroughCase));
+		optionsMap.put(OPTION_ReportOverridingMethodWithoutSuperInvocation, getSeverityString(OverridingMethodWithoutSuperInvocation));
+		optionsMap.put(OPTION_GenerateClassFiles, this.generateClassFiles ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_Process_Annotations, this.processAnnotations ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportRedundantSuperinterface, getSeverityString(RedundantSuperinterface));
+		optionsMap.put(OPTION_ReportComparingIdentical, getSeverityString(ComparingIdentical));
+		optionsMap.put(OPTION_ReportMissingSynchronizedOnInheritedMethod, getSeverityString(MissingSynchronizedModifierInInheritedMethod));
+		optionsMap.put(OPTION_ReportMissingHashCodeMethod, getSeverityString(ShouldImplementHashcode));
+		optionsMap.put(OPTION_ReportDeadCode, getSeverityString(DeadCode));
+		optionsMap.put(OPTION_ReportDeadCodeInTrivialIfStatement, this.reportDeadCodeInTrivialIfStatement ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportTasks, getSeverityString(Tasks));
+		optionsMap.put(OPTION_ReportUnusedObjectAllocation, getSeverityString(UnusedObjectAllocation));
+		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
+		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
+		optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
+		optionsMap.put(OPTION_ReportUnclosedCloseable, getSeverityString(UnclosedCloseable));
+		optionsMap.put(OPTION_ReportPotentiallyUnclosedCloseable, getSeverityString(PotentiallyUnclosedCloseable));
+		optionsMap.put(OPTION_ReportExplicitlyClosedAutoCloseable, getSeverityString(ExplicitlyClosedAutoCloseable));
+		optionsMap.put(OPTION_AnnotationBasedNullAnalysis, this.isAnnotationBasedNullAnalysisEnabled ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportNullSpecViolation, getSeverityString(NullSpecViolation));
+		optionsMap.put(OPTION_ReportNullAnnotationInferenceConflict, getSeverityString(NullAnnotationInferenceConflict));
+		optionsMap.put(OPTION_ReportNullUncheckedConversion, getSeverityString(NullUncheckedConversion));
+		optionsMap.put(OPTION_ReportRedundantNullAnnotation, getSeverityString(RedundantNullAnnotation));
+		optionsMap.put(OPTION_NullableAnnotationName, String.valueOf(CharOperation.concatWith(this.nullableAnnotationName, '.')));
+		optionsMap.put(OPTION_NonNullAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullAnnotationName, '.')));
+		optionsMap.put(OPTION_NonNullByDefaultAnnotationName, String.valueOf(CharOperation.concatWith(this.nonNullByDefaultAnnotationName, '.')));
+		optionsMap.put(OPTION_ReportMissingNonNullByDefaultAnnotation, getSeverityString(MissingNonNullByDefaultAnnotation));
+		optionsMap.put(OPTION_ReportUnusedTypeParameter, getSeverityString(UnusedTypeParameter));
+		optionsMap.put(OPTION_SyntacticNullAnalysisForFields, this.enableSyntacticNullAnalysisForFields ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_InheritNullAnnotations, this.inheritNullAnnotations ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportNonnullParameterAnnotationDropped, getSeverityString(NonnullParameterAnnotationDropped));
+		return optionsMap;
+	}
+
+	public int getSeverity(int irritant) {
+		if (this.errorThreshold.isSet(irritant)) {
+			if ((irritant & (IrritantSet.GROUP_MASK | UnusedWarningToken)) == UnusedWarningToken) {
+				return ProblemSeverities.Error | ProblemSeverities.Optional; // cannot be treated as fatal - codegen already occurred
+			}
+			return this.treatOptionalErrorAsFatal
+				? ProblemSeverities.Error | ProblemSeverities.Optional | ProblemSeverities.Fatal
+				: ProblemSeverities.Error | ProblemSeverities.Optional;
+		}
+		if (this.warningThreshold.isSet(irritant)) {
+			return ProblemSeverities.Warning | ProblemSeverities.Optional;
+		}
+		return ProblemSeverities.Ignore;
+	}
+
+	public String getSeverityString(int irritant) {
+		if(this.errorThreshold.isSet(irritant))
+			return ERROR;
+		if(this.warningThreshold.isSet(irritant))
+			return WARNING;
+		return IGNORE;
+	}
+	public String getVisibilityString(int level) {
+		switch (level & ExtraCompilerModifiers.AccVisibilityMASK) {
+			case ClassFileConstants.AccPublic:
+				return PUBLIC;
+			case ClassFileConstants.AccProtected:
+				return PROTECTED;
+			case ClassFileConstants.AccPrivate:
+				return PRIVATE;
+			default:
+				return DEFAULT;
+		}
+	}
+
+	public boolean isAnyEnabled(IrritantSet irritants) {
+		return this.warningThreshold.isAnySet(irritants) || this.errorThreshold.isAnySet(irritants);
+	}
+
+	protected void resetDefaults() {
+		// problem default severities defined on IrritantSet
+		this.errorThreshold = new IrritantSet(IrritantSet.COMPILER_DEFAULT_ERRORS);
+		this.warningThreshold = new IrritantSet(IrritantSet.COMPILER_DEFAULT_WARNINGS);
+		
+		// by default only lines and source attributes are generated.
+		this.produceDebugAttributes = ClassFileConstants.ATTR_SOURCE | ClassFileConstants.ATTR_LINES;
+		this.complianceLevel = this.originalComplianceLevel = ClassFileConstants.JDK1_4; // by default be compliant with 1.4
+		this.sourceLevel = this.originalSourceLevel = ClassFileConstants.JDK1_3; //1.3 source behavior by default
+		this.targetJDK = ClassFileConstants.JDK1_2; // default generates for JVM1.2
+
+		this.defaultEncoding = null; // will use the platform default encoding
+
+		// print what unit is being processed
+		this.verbose = Compiler.DEBUG;
+
+		this.produceReferenceInfo = false; // no reference info by default
+
+		// indicates if unused/optimizable local variables need to be preserved (debugging purpose)
+		this.preserveAllLocalVariables = false;
+
+		// indicates whether literal expressions are inlined at parse-time or not
+		this.parseLiteralExpressionsAsConstants = true;
+
+		// max problems per compilation unit
+		this.maxProblemsPerUnit = 100; // no more than 100 problems per default
+
+		// tags used to recognize tasks in comments
+		this.taskTags = null;
+		this.taskPriorities = null;
+		this.isTaskCaseSensitive = true;
+
+		// deprecation report
+		this.reportDeprecationInsideDeprecatedCode = false;
+		this.reportDeprecationWhenOverridingDeprecatedMethod = false;
+		
+		// unused parameters report
+		this.reportUnusedParameterWhenImplementingAbstract = false;
+		this.reportUnusedParameterWhenOverridingConcrete = false;
+		this.reportUnusedParameterIncludeDocCommentReference = true;
+		
+		// unused declaration of thrown exception
+		this.reportUnusedDeclaredThrownExceptionWhenOverriding = false;
+		this.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = true;
+		this.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = true;
+		
+		// constructor/setter parameter hiding
+		this.reportSpecialParameterHidingField = false;
+
+		this.reportUnavoidableGenericTypeProblems = true;
+
+		// check javadoc comments tags
+		this.reportInvalidJavadocTagsVisibility = ClassFileConstants.AccPublic;
+		this.reportInvalidJavadocTags = false;
+		this.reportInvalidJavadocTagsDeprecatedRef = false;
+		this.reportInvalidJavadocTagsNotVisibleRef = false;
+		this.reportMissingJavadocTagDescription = RETURN_TAG;
+		
+		// check missing javadoc tags
+		this.reportMissingJavadocTagsVisibility = ClassFileConstants.AccPublic;
+		this.reportMissingJavadocTagsOverriding = false;
+		this.reportMissingJavadocTagsMethodTypeParameters = false;
+
+		// check missing javadoc comments
+		this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccPublic;
+		this.reportMissingJavadocCommentsOverriding = false;
+		
+		// JSR bytecode inlining and sharing
+		this.inlineJsrBytecode = false;
+		this.shareCommonFinallyBlocks = false;
+
+		// javadoc comment support
+		this.docCommentSupport = false;
+
+		// suppress warning annotation
+		this.suppressWarnings = true;
+
+		// suppress also optional errors
+		this.suppressOptionalErrors = false;
+
+		// treat optional error as non fatal
+		this.treatOptionalErrorAsFatal = false;
+
+		// parser perform statements recovery
+		this.performMethodsFullRecovery = true;
+
+		// parser perform statements recovery
+		this.performStatementsRecovery = true;
+
+		// store annotations
+		this.storeAnnotations = false;
+
+		// annotation processing
+		this.generateClassFiles = true;
+
+		// enable annotation processing by default only in batch mode
+		this.processAnnotations = false;
+		
+		// disable missing override annotation reporting for interface method implementation
+		this.reportMissingOverrideAnnotationForInterfaceMethodImplementation = true;
+		
+		// dead code detection
+		this.reportDeadCodeInTrivialIfStatement = false;
+		
+		// ignore method bodies
+		this.ignoreMethodBodies = false;
+		
+		this.ignoreSourceFolderWarningOption = false;
+		
+		// allow null info from asserts to be considered downstream by default
+		this.includeNullInfoFromAsserts = false;
+		
+		this.isAnnotationBasedNullAnalysisEnabled = false;
+		this.nullableAnnotationName = DEFAULT_NULLABLE_ANNOTATION_NAME;
+		this.nonNullAnnotationName = DEFAULT_NONNULL_ANNOTATION_NAME;
+		this.nonNullByDefaultAnnotationName = DEFAULT_NONNULLBYDEFAULT_ANNOTATION_NAME;
+		this.intendedDefaultNonNullness = 0;
+		this.enableSyntacticNullAnalysisForFields = false;
+		this.inheritNullAnnotations = false;
+		
+		this.analyseResourceLeaks = true;
+
+		this.reportMissingEnumCaseDespiteDefault = false;
+	}
+
+	public void set(Map optionsMap) {
+		Object optionValue;
+		if ((optionValue = optionsMap.get(OPTION_LocalVariableAttribute)) != null) {
+			if (GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes |= ClassFileConstants.ATTR_VARS;
+			} else if (DO_NOT_GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes &= ~ClassFileConstants.ATTR_VARS;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_LineNumberAttribute)) != null) {
+			if (GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes |= ClassFileConstants.ATTR_LINES;
+			} else if (DO_NOT_GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes &= ~ClassFileConstants.ATTR_LINES;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_SourceFileAttribute)) != null) {
+			if (GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes |= ClassFileConstants.ATTR_SOURCE;
+			} else if (DO_NOT_GENERATE.equals(optionValue)) {
+				this.produceDebugAttributes &= ~ClassFileConstants.ATTR_SOURCE;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_PreserveUnusedLocal)) != null) {
+			if (PRESERVE.equals(optionValue)) {
+				this.preserveAllLocalVariables = true;
+			} else if (OPTIMIZE_OUT.equals(optionValue)) {
+				this.preserveAllLocalVariables = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportDeprecationInDeprecatedCode)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportDeprecationInsideDeprecatedCode = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportDeprecationInsideDeprecatedCode = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportDeprecationWhenOverridingDeprecatedMethod)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportDeprecationWhenOverridingDeprecatedMethod = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportDeprecationWhenOverridingDeprecatedMethod = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionWhenOverriding = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionWhenOverriding = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_Compliance)) != null) {
+			long level = versionToJdkLevel(optionValue);
+			if (level != 0) this.complianceLevel = this.originalComplianceLevel = level;
+		}
+		if ((optionValue = optionsMap.get(OPTION_Source)) != null) {
+			long level = versionToJdkLevel(optionValue);
+			if (level != 0) this.sourceLevel = this.originalSourceLevel = level;
+		}
+		if ((optionValue = optionsMap.get(OPTION_TargetPlatform)) != null) {
+			long level = versionToJdkLevel(optionValue);
+			if (level != 0) {
+				this.targetJDK = level;
+			}
+			if (this.targetJDK >= ClassFileConstants.JDK1_5) this.inlineJsrBytecode = true; // forced from 1.5 mode on
+		}
+		if ((optionValue = optionsMap.get(OPTION_Encoding)) != null) {
+			if (optionValue instanceof String) {
+				this.defaultEncoding = null;
+				String stringValue = (String) optionValue;
+				if (stringValue.length() > 0){
+					try {
+						new InputStreamReader(new ByteArrayInputStream(new byte[0]), stringValue);
+						this.defaultEncoding = stringValue;
+					} catch(UnsupportedEncodingException e){
+						// ignore unsupported encoding
+					}
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedParameterWhenImplementingAbstract)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedParameterWhenImplementingAbstract = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedParameterWhenImplementingAbstract = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedParameterWhenOverridingConcrete)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedParameterWhenOverridingConcrete = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedParameterWhenOverridingConcrete = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedParameterIncludeDocCommentReference)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnusedParameterIncludeDocCommentReference = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnusedParameterIncludeDocCommentReference = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportSpecialParameterHidingField)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportSpecialParameterHidingField = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportSpecialParameterHidingField = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportUnavoidableGenericTypeProblems)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportUnavoidableGenericTypeProblems = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportUnavoidableGenericTypeProblems = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportDeadCodeInTrivialIfStatement )) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportDeadCodeInTrivialIfStatement = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportDeadCodeInTrivialIfStatement = false;
+			}
+		}		
+		if ((optionValue = optionsMap.get(OPTION_MaxProblemPerUnit)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				try {
+					int val = Integer.parseInt(stringValue);
+					if (val >= 0) this.maxProblemsPerUnit = val;
+				} catch(NumberFormatException e){
+					// ignore ill-formatted limit
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_TaskTags)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() == 0) {
+					this.taskTags = null;
+				} else {
+					this.taskTags = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_TaskPriorities)) != null) {
+			if (optionValue instanceof String) {
+				String stringValue = (String) optionValue;
+				if (stringValue.length() == 0) {
+					this.taskPriorities = null;
+				} else {
+					this.taskPriorities = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_TaskCaseSensitive)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.isTaskCaseSensitive = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.isTaskCaseSensitive = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_InlineJsr)) != null) {
+			if (this.targetJDK < ClassFileConstants.JDK1_5) { // only optional if target < 1.5 (inlining on from 1.5 on)
+				if (ENABLED.equals(optionValue)) {
+					this.inlineJsrBytecode = true;
+				} else if (DISABLED.equals(optionValue)) {
+					this.inlineJsrBytecode = false;
+				}
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ShareCommonFinallyBlocks)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.shareCommonFinallyBlocks = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.shareCommonFinallyBlocks = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_SuppressWarnings)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.suppressWarnings = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.suppressWarnings = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_SuppressOptionalErrors)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.suppressOptionalErrors = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.suppressOptionalErrors = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_FatalOptionalError)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.treatOptionalErrorAsFatal = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.treatOptionalErrorAsFatal = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportMissingOverrideAnnotationForInterfaceMethodImplementation = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportMissingOverrideAnnotationForInterfaceMethodImplementation = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_IncludeNullInfoFromAsserts)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.includeNullInfoFromAsserts = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.includeNullInfoFromAsserts = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMethodWithConstructorName)) != null) updateSeverity(MethodWithConstructorName, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportOverridingPackageDefaultMethod)) != null) updateSeverity(OverriddenPackageDefaultMethod, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportDeprecation)) != null) updateSeverity(UsingDeprecatedAPI, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportHiddenCatchBlock)) != null) updateSeverity(MaskedCatchBlock, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedLocal)) != null) updateSeverity(UnusedLocalVariable, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedParameter)) != null) updateSeverity(UnusedArgument, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedImport)) != null) updateSeverity(UnusedImport, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedPrivateMember)) != null) updateSeverity(UnusedPrivateMember, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedDeclaredThrownException)) != null) updateSeverity(UnusedDeclaredThrownException, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportNoImplicitStringConversion)) != null) updateSeverity(NoImplicitStringConversion, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportSyntheticAccessEmulation)) != null) updateSeverity(AccessEmulation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportLocalVariableHiding)) != null) updateSeverity(LocalVariableHiding, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportFieldHiding)) != null) updateSeverity(FieldHiding, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportTypeParameterHiding)) != null) updateSeverity(TypeHiding, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportPossibleAccidentalBooleanAssignment)) != null) updateSeverity(AccidentalBooleanAssign, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportEmptyStatement)) != null) updateSeverity(EmptyStatement, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportNonExternalizedStringLiteral)) != null) updateSeverity(NonExternalizedString, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportAssertIdentifier)) != null) updateSeverity(AssertUsedAsAnIdentifier, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportEnumIdentifier)) != null) updateSeverity(EnumUsedAsAnIdentifier, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportNonStaticAccessToStatic)) != null) updateSeverity(NonStaticAccessToStatic, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportIndirectStaticAccess)) != null) updateSeverity(IndirectStaticAccess, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportIncompatibleNonInheritedInterfaceMethod)) != null) updateSeverity(IncompatibleNonInheritedInterfaceMethod, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUndocumentedEmptyBlock)) != null) updateSeverity(UndocumentedEmptyBlock, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnnecessaryTypeCheck)) != null) updateSeverity(UnnecessaryTypeCheck, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnnecessaryElse)) != null) updateSeverity(UnnecessaryElse, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportFinallyBlockNotCompletingNormally)) != null) updateSeverity(FinallyBlockNotCompleting, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnqualifiedFieldAccess)) != null) updateSeverity(UnqualifiedFieldAccess, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportNoEffectAssignment)) != null) updateSeverity(NoEffectAssignment, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUncheckedTypeOperation)) != null) updateSeverity(UncheckedTypeOperation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportRawTypeReference)) != null) updateSeverity(RawTypeReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportFinalParameterBound)) != null) updateSeverity(FinalParameterBound, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingSerialVersion)) != null) updateSeverity(MissingSerialVersion, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportForbiddenReference)) != null) updateSeverity(ForbiddenReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportDiscouragedReference)) != null) updateSeverity(DiscouragedReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportVarargsArgumentNeedCast)) != null) updateSeverity(VarargsArgumentNeedCast, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportNullReference)) != null) updateSeverity(NullReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportPotentialNullReference)) != null) updateSeverity(PotentialNullReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportRedundantNullCheck)) != null) updateSeverity(RedundantNullCheck, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportAutoboxing)) != null) updateSeverity(AutoBoxing, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportAnnotationSuperInterface)) != null) updateSeverity(AnnotationSuperInterface, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotation)) != null) updateSeverity(MissingOverrideAnnotation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingDeprecatedAnnotation)) != null) updateSeverity(MissingDeprecatedAnnotation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportIncompleteEnumSwitch)) != null) updateSeverity(MissingEnumConstantCase, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingEnumCaseDespiteDefault)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportMissingEnumCaseDespiteDefault = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportMissingEnumCaseDespiteDefault = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingDefaultCase)) != null) updateSeverity(MissingDefaultCase, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnhandledWarningToken)) != null) updateSeverity(UnhandledWarningToken, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedWarningToken)) != null) updateSeverity(UnusedWarningToken, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedLabel)) != null) updateSeverity(UnusedLabel, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportParameterAssignment)) != null) updateSeverity(ParameterAssignment, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportFallthroughCase)) != null) updateSeverity(FallthroughCase, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportOverridingMethodWithoutSuperInvocation)) != null) updateSeverity(OverridingMethodWithoutSuperInvocation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedTypeArgumentsForMethodInvocation)) != null) updateSeverity(UnusedTypeArguments, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportRedundantSuperinterface)) != null) updateSeverity(RedundantSuperinterface, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportComparingIdentical)) != null) updateSeverity(ComparingIdentical, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingSynchronizedOnInheritedMethod)) != null) updateSeverity(MissingSynchronizedModifierInInheritedMethod, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingHashCodeMethod)) != null) updateSeverity(ShouldImplementHashcode, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportDeadCode)) != null) updateSeverity(DeadCode, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportTasks)) != null) updateSeverity(Tasks, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedObjectAllocation)) != null) updateSeverity(UnusedObjectAllocation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnclosedCloseable)) != null) updateSeverity(UnclosedCloseable, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportPotentiallyUnclosedCloseable)) != null) updateSeverity(PotentiallyUnclosedCloseable, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportExplicitlyClosedAutoCloseable)) != null) updateSeverity(ExplicitlyClosedAutoCloseable, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportUnusedTypeParameter)) != null) updateSeverity(UnusedTypeParameter, optionValue);
+		if (getSeverity(UnclosedCloseable) == ProblemSeverities.Ignore
+				&& getSeverity(PotentiallyUnclosedCloseable) == ProblemSeverities.Ignore
+				&& getSeverity(ExplicitlyClosedAutoCloseable) == ProblemSeverities.Ignore) {
+			this.analyseResourceLeaks = false;
+		} else {
+			this.analyseResourceLeaks = true;
+		}
+		if ((optionValue = optionsMap.get(OPTION_AnnotationBasedNullAnalysis)) != null) {
+			this.isAnnotationBasedNullAnalysisEnabled = ENABLED.equals(optionValue);
+		}
+		if (this.isAnnotationBasedNullAnalysisEnabled) {
+			if ((optionValue = optionsMap.get(OPTION_ReportNullSpecViolation)) != null) {
+				if (ERROR.equals(optionValue)) {
+					this.errorThreshold.set(NullSpecViolation);
+					this.warningThreshold.clear(NullSpecViolation);
+				} else if (WARNING.equals(optionValue)) {
+					this.errorThreshold.clear(NullSpecViolation);
+					this.warningThreshold.set(NullSpecViolation);
+				}
+				// "ignore" is not valid for this option
+			}
+			if ((optionValue = optionsMap.get(OPTION_ReportNullAnnotationInferenceConflict)) != null) updateSeverity(NullAnnotationInferenceConflict, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_ReportNullUncheckedConversion)) != null) updateSeverity(NullUncheckedConversion, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_ReportRedundantNullAnnotation)) != null) updateSeverity(RedundantNullAnnotation, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_NullableAnnotationName)) != null) {
+				this.nullableAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
+			}
+			if ((optionValue = optionsMap.get(OPTION_NonNullAnnotationName)) != null) {
+				this.nonNullAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
+			}
+			if ((optionValue = optionsMap.get(OPTION_NonNullByDefaultAnnotationName)) != null) {
+				this.nonNullByDefaultAnnotationName = CharOperation.splitAndTrimOn('.', ((String)optionValue).toCharArray());
+			}
+			if ((optionValue = optionsMap.get(OPTION_ReportMissingNonNullByDefaultAnnotation)) != null) updateSeverity(MissingNonNullByDefaultAnnotation, optionValue);
+			if ((optionValue = optionsMap.get(OPTION_SyntacticNullAnalysisForFields)) != null) {
+				this.enableSyntacticNullAnalysisForFields = ENABLED.equals(optionValue);
+			}
+			if ((optionValue = optionsMap.get(OPTION_InheritNullAnnotations)) != null) {
+				this.inheritNullAnnotations = ENABLED.equals(optionValue);
+			}
+			if ((optionValue = optionsMap.get(OPTION_ReportNonnullParameterAnnotationDropped)) != null) updateSeverity(NonnullParameterAnnotationDropped, optionValue);
+		}
+
+		// Javadoc options
+		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.docCommentSupport = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.docCommentSupport = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadoc)) != null) {
+			updateSeverity(InvalidJavadoc, optionValue);
+		}
+		if ( (optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTagsVisibility)) != null) {
+			if (PUBLIC.equals(optionValue)) {
+				this.reportInvalidJavadocTagsVisibility = ClassFileConstants.AccPublic;
+			} else if (PROTECTED.equals(optionValue)) {
+				this.reportInvalidJavadocTagsVisibility = ClassFileConstants.AccProtected;
+			} else if (DEFAULT.equals(optionValue)) {
+				this.reportInvalidJavadocTagsVisibility = ClassFileConstants.AccDefault;
+			} else if (PRIVATE.equals(optionValue)) {
+				this.reportInvalidJavadocTagsVisibility = ClassFileConstants.AccPrivate;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTags)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTags = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTags = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTagsDeprecatedRef)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTagsDeprecatedRef = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTagsDeprecatedRef = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTagsNotVisibleRef)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTagsNotVisibleRef = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportInvalidJavadocTagsNotVisibleRef = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocTags)) != null) {
+			updateSeverity(MissingJavadocTags, optionValue);
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocTagsVisibility)) != null) {
+			if (PUBLIC.equals(optionValue)) {
+				this.reportMissingJavadocTagsVisibility = ClassFileConstants.AccPublic;
+			} else if (PROTECTED.equals(optionValue)) {
+				this.reportMissingJavadocTagsVisibility = ClassFileConstants.AccProtected;
+			} else if (DEFAULT.equals(optionValue)) {
+				this.reportMissingJavadocTagsVisibility = ClassFileConstants.AccDefault;
+			} else if (PRIVATE.equals(optionValue)) {
+				this.reportMissingJavadocTagsVisibility = ClassFileConstants.AccPrivate;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocTagsOverriding)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportMissingJavadocTagsOverriding = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportMissingJavadocTagsOverriding = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocTagsMethodTypeParameters)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportMissingJavadocTagsMethodTypeParameters = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportMissingJavadocTagsMethodTypeParameters = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocComments)) != null) {
+			updateSeverity(MissingJavadocComments, optionValue);
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocTagDescription)) != null) {
+			this.reportMissingJavadocTagDescription = (String) optionValue;
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocCommentsVisibility)) != null) {
+			if (PUBLIC.equals(optionValue)) {
+				this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccPublic;
+			} else if (PROTECTED.equals(optionValue)) {
+				this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccProtected;
+			} else if (DEFAULT.equals(optionValue)) {
+				this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccDefault;
+			} else if (PRIVATE.equals(optionValue)) {
+				this.reportMissingJavadocCommentsVisibility = ClassFileConstants.AccPrivate;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingJavadocCommentsOverriding)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.reportMissingJavadocCommentsOverriding = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.reportMissingJavadocCommentsOverriding = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_GenerateClassFiles)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.generateClassFiles = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.generateClassFiles = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_Process_Annotations)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.processAnnotations = true;
+				this.storeAnnotations = true; // annotation processing requires annotation to be stored
+			} else if (DISABLED.equals(optionValue)) {
+				this.processAnnotations = false;
+				this.storeAnnotations = false;
+			}
+		}
+	}
+	public String toString() {
+		StringBuffer buf = new StringBuffer("CompilerOptions:"); //$NON-NLS-1$
+		buf.append("\n\t- local variables debug attributes: ").append((this.produceDebugAttributes & ClassFileConstants.ATTR_VARS) != 0 ? "ON" : " OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- line number debug attributes: ").append((this.produceDebugAttributes & ClassFileConstants.ATTR_LINES) != 0 ? "ON" : " OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- source debug attributes: ").append((this.produceDebugAttributes & ClassFileConstants.ATTR_SOURCE) != 0 ? "ON" : " OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- preserve all local variables: ").append(this.preserveAllLocalVariables ? "ON" : " OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- method with constructor name: ").append(getSeverityString(MethodWithConstructorName)); //$NON-NLS-1$
+		buf.append("\n\t- overridden package default method: ").append(getSeverityString(OverriddenPackageDefaultMethod)); //$NON-NLS-1$
+		buf.append("\n\t- deprecation: ").append(getSeverityString(UsingDeprecatedAPI)); //$NON-NLS-1$
+		buf.append("\n\t- masked catch block: ").append(getSeverityString(MaskedCatchBlock)); //$NON-NLS-1$
+		buf.append("\n\t- unused local variable: ").append(getSeverityString(UnusedLocalVariable)); //$NON-NLS-1$
+		buf.append("\n\t- unused parameter: ").append(getSeverityString(UnusedArgument)); //$NON-NLS-1$
+		buf.append("\n\t- unused import: ").append(getSeverityString(UnusedImport)); //$NON-NLS-1$
+		buf.append("\n\t- synthetic access emulation: ").append(getSeverityString(AccessEmulation)); //$NON-NLS-1$
+		buf.append("\n\t- assignment with no effect: ").append(getSeverityString(NoEffectAssignment)); //$NON-NLS-1$
+		buf.append("\n\t- non externalized string: ").append(getSeverityString(NonExternalizedString)); //$NON-NLS-1$
+		buf.append("\n\t- static access receiver: ").append(getSeverityString(NonStaticAccessToStatic)); //$NON-NLS-1$
+		buf.append("\n\t- indirect static access: ").append(getSeverityString(IndirectStaticAccess)); //$NON-NLS-1$
+		buf.append("\n\t- incompatible non inherited interface method: ").append(getSeverityString(IncompatibleNonInheritedInterfaceMethod)); //$NON-NLS-1$
+		buf.append("\n\t- unused private member: ").append(getSeverityString(UnusedPrivateMember)); //$NON-NLS-1$
+		buf.append("\n\t- local variable hiding another variable: ").append(getSeverityString(LocalVariableHiding)); //$NON-NLS-1$
+		buf.append("\n\t- field hiding another variable: ").append(getSeverityString(FieldHiding)); //$NON-NLS-1$
+		buf.append("\n\t- type hiding another type: ").append(getSeverityString(TypeHiding)); //$NON-NLS-1$
+		buf.append("\n\t- possible accidental boolean assignment: ").append(getSeverityString(AccidentalBooleanAssign)); //$NON-NLS-1$
+		buf.append("\n\t- superfluous semicolon: ").append(getSeverityString(EmptyStatement)); //$NON-NLS-1$
+		buf.append("\n\t- uncommented empty block: ").append(getSeverityString(UndocumentedEmptyBlock)); //$NON-NLS-1$
+		buf.append("\n\t- unnecessary type check: ").append(getSeverityString(UnnecessaryTypeCheck)); //$NON-NLS-1$
+		buf.append("\n\t- javadoc comment support: ").append(this.docCommentSupport ? "ON" : " OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t\t+ invalid javadoc: ").append(getSeverityString(InvalidJavadoc)); //$NON-NLS-1$
+		buf.append("\n\t\t+ report invalid javadoc tags: ").append(this.reportInvalidJavadocTags ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t\t* deprecated references: ").append(this.reportInvalidJavadocTagsDeprecatedRef ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t\t* not visible references: ").append(this.reportInvalidJavadocTagsNotVisibleRef ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t+ visibility level to report invalid javadoc tags: ").append(getVisibilityString(this.reportInvalidJavadocTagsVisibility)); //$NON-NLS-1$
+		buf.append("\n\t\t+ missing javadoc tags: ").append(getSeverityString(MissingJavadocTags)); //$NON-NLS-1$
+		buf.append("\n\t\t+ visibility level to report missing javadoc tags: ").append(getVisibilityString(this.reportMissingJavadocTagsVisibility)); //$NON-NLS-1$
+		buf.append("\n\t\t+ report missing javadoc tags for method type parameters: ").append(this.reportMissingJavadocTagsMethodTypeParameters ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t+ report missing javadoc tags in overriding methods: ").append(this.reportMissingJavadocTagsOverriding ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t+ missing javadoc comments: ").append(getSeverityString(MissingJavadocComments)); //$NON-NLS-1$
+		buf.append("\n\t\t+ report missing tag description option: ").append(this.reportMissingJavadocTagDescription); //$NON-NLS-1$
+		buf.append("\n\t\t+ visibility level to report missing javadoc comments: ").append(getVisibilityString(this.reportMissingJavadocCommentsVisibility)); //$NON-NLS-1$
+		buf.append("\n\t\t+ report missing javadoc comments in overriding methods: ").append(this.reportMissingJavadocCommentsOverriding ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- finally block not completing normally: ").append(getSeverityString(FinallyBlockNotCompleting)); //$NON-NLS-1$
+		buf.append("\n\t- report unused declared thrown exception: ").append(getSeverityString(UnusedDeclaredThrownException)); //$NON-NLS-1$
+		buf.append("\n\t- report unused declared thrown exception when overriding: ").append(this.reportUnusedDeclaredThrownExceptionWhenOverriding ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unused declared thrown exception include doc comment reference: ").append(this.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unused declared thrown exception exempt exception and throwable: ").append(this.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- unnecessary else: ").append(getSeverityString(UnnecessaryElse)); //$NON-NLS-1$
+		buf.append("\n\t- JDK compliance level: "+ versionFromJdkLevel(this.complianceLevel)); //$NON-NLS-1$
+		buf.append("\n\t- JDK source level: "+ versionFromJdkLevel(this.sourceLevel)); //$NON-NLS-1$
+		buf.append("\n\t- JDK target level: "+ versionFromJdkLevel(this.targetJDK)); //$NON-NLS-1$
+		buf.append("\n\t- verbose : ").append(this.verbose ? "ON" : "OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- produce reference info : ").append(this.produceReferenceInfo ? "ON" : "OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- parse literal expressions as constants : ").append(this.parseLiteralExpressionsAsConstants ? "ON" : "OFF"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buf.append("\n\t- encoding : ").append(this.defaultEncoding == null ? "<default>" : this.defaultEncoding); //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("\n\t- task tags: ").append(this.taskTags == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.taskTags,',')));  //$NON-NLS-1$
+		buf.append("\n\t- task priorities : ").append(this.taskPriorities == null ? Util.EMPTY_STRING : new String(CharOperation.concatWith(this.taskPriorities,','))); //$NON-NLS-1$
+		buf.append("\n\t- report deprecation inside deprecated code : ").append(this.reportDeprecationInsideDeprecatedCode ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report deprecation when overriding deprecated method : ").append(this.reportDeprecationWhenOverridingDeprecatedMethod ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unused parameter when implementing abstract method : ").append(this.reportUnusedParameterWhenImplementingAbstract ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unused parameter when overriding concrete method : ").append(this.reportUnusedParameterWhenOverridingConcrete ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unused parameter include doc comment reference : ").append(this.reportUnusedParameterIncludeDocCommentReference ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report constructor/setter parameter hiding existing field : ").append(this.reportSpecialParameterHidingField ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- inline JSR bytecode : ").append(this.inlineJsrBytecode ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- share common finally blocks : ").append(this.shareCommonFinallyBlocks ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- report unavoidable generic type problems : ").append(this.reportUnavoidableGenericTypeProblems ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- unsafe type operation: ").append(getSeverityString(UncheckedTypeOperation)); //$NON-NLS-1$
+		buf.append("\n\t- unsafe raw type: ").append(getSeverityString(RawTypeReference)); //$NON-NLS-1$
+		buf.append("\n\t- final bound for type parameter: ").append(getSeverityString(FinalParameterBound)); //$NON-NLS-1$
+		buf.append("\n\t- missing serialVersionUID: ").append(getSeverityString(MissingSerialVersion)); //$NON-NLS-1$
+		buf.append("\n\t- varargs argument need cast: ").append(getSeverityString(VarargsArgumentNeedCast)); //$NON-NLS-1$
+		buf.append("\n\t- forbidden reference to type with access restriction: ").append(getSeverityString(ForbiddenReference)); //$NON-NLS-1$
+		buf.append("\n\t- discouraged reference to type with access restriction: ").append(getSeverityString(DiscouragedReference)); //$NON-NLS-1$
+		buf.append("\n\t- null reference: ").append(getSeverityString(NullReference)); //$NON-NLS-1$
+		buf.append("\n\t- potential null reference: ").append(getSeverityString(PotentialNullReference)); //$NON-NLS-1$
+		buf.append("\n\t- redundant null check: ").append(getSeverityString(RedundantNullCheck)); //$NON-NLS-1$
+		buf.append("\n\t- autoboxing: ").append(getSeverityString(AutoBoxing)); //$NON-NLS-1$
+		buf.append("\n\t- annotation super interface: ").append(getSeverityString(AnnotationSuperInterface)); //$NON-NLS-1$
+		buf.append("\n\t- missing @Override annotation: ").append(getSeverityString(MissingOverrideAnnotation)); //$NON-NLS-1$
+		buf.append("\n\t- missing @Override annotation for interface method implementation: ").append(this.reportMissingOverrideAnnotationForInterfaceMethodImplementation ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- missing @Deprecated annotation: ").append(getSeverityString(MissingDeprecatedAnnotation)); //$NON-NLS-1$
+		buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(MissingEnumConstantCase)); //$NON-NLS-1$
+		buf.append("\n\t- raise null related warnings for variables tainted in assert statements: ").append(this.includeNullInfoFromAsserts ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- suppress warnings: ").append(this.suppressWarnings ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- suppress optional errors: ").append(this.suppressOptionalErrors ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- unhandled warning token: ").append(getSeverityString(UnhandledWarningToken)); //$NON-NLS-1$
+		buf.append("\n\t- unused warning token: ").append(getSeverityString(UnusedWarningToken)); //$NON-NLS-1$
+		buf.append("\n\t- unused label: ").append(getSeverityString(UnusedLabel)); //$NON-NLS-1$
+		buf.append("\n\t- treat optional error as fatal: ").append(this.treatOptionalErrorAsFatal ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- parameter assignment: ").append(getSeverityString(ParameterAssignment)); //$NON-NLS-1$
+		buf.append("\n\t- generate class files: ").append(this.generateClassFiles ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- process annotations: ").append(this.processAnnotations ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- unused type arguments for method/constructor invocation: ").append(getSeverityString(UnusedTypeArguments)); //$NON-NLS-1$
+		buf.append("\n\t- redundant superinterface: ").append(getSeverityString(RedundantSuperinterface)); //$NON-NLS-1$
+		buf.append("\n\t- comparing identical expr: ").append(getSeverityString(ComparingIdentical)); //$NON-NLS-1$
+		buf.append("\n\t- missing synchronized on inherited method: ").append(getSeverityString(MissingSynchronizedModifierInInheritedMethod)); //$NON-NLS-1$
+		buf.append("\n\t- should implement hashCode() method: ").append(getSeverityString(ShouldImplementHashcode)); //$NON-NLS-1$
+		buf.append("\n\t- dead code: ").append(getSeverityString(DeadCode)); //$NON-NLS-1$
+		buf.append("\n\t- dead code in trivial if statement: ").append(this.reportDeadCodeInTrivialIfStatement ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t- tasks severity: ").append(getSeverityString(Tasks)); //$NON-NLS-1$
+		buf.append("\n\t- unused object allocation: ").append(getSeverityString(UnusedObjectAllocation)); //$NON-NLS-1$
+		buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$
+		buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$
+		buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$
+		buf.append("\n\t- resource is not closed: ").append(getSeverityString(UnclosedCloseable)); //$NON-NLS-1$
+		buf.append("\n\t- resource may not be closed: ").append(getSeverityString(PotentiallyUnclosedCloseable)); //$NON-NLS-1$
+		buf.append("\n\t- resource should be handled by try-with-resources: ").append(getSeverityString(ExplicitlyClosedAutoCloseable)); //$NON-NLS-1$
+		buf.append("\n\t- Unused Type Parameter: ").append(getSeverityString(UnusedTypeParameter)); //$NON-NLS-1$
+		return buf.toString();
+	}
+	
+	protected void updateSeverity(int irritant, Object severityString) {
+		if (ERROR.equals(severityString)) {
+			this.errorThreshold.set(irritant);
+			this.warningThreshold.clear(irritant);
+		} else if (WARNING.equals(severityString)) {
+			this.errorThreshold.clear(irritant);
+			this.warningThreshold.set(irritant);
+		} else if (IGNORE.equals(severityString)) {
+			this.errorThreshold.clear(irritant);
+			this.warningThreshold.clear(irritant);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerStats.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerStats.java
new file mode 100644
index 0000000..c21b4a4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerStats.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class CompilerStats implements Comparable {
+
+	// overall
+	public long startTime;
+	public long endTime;
+	public long lineCount;
+
+	// compile phases
+	public long parseTime;
+	public long resolveTime;
+	public long analyzeTime;
+	public long generateTime;
+
+/**
+ * Returns the total elapsed time (between start and end)
+ * @return the time spent between start and end
+ */
+public long elapsedTime() {
+	return this.endTime - this.startTime;
+}
+
+/**
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+public int compareTo(Object o) {
+	CompilerStats otherStats = (CompilerStats) o;
+	long time1 = elapsedTime();
+	long time2 = otherStats.elapsedTime();
+	return time1 < time2 ? -1 : (time1 == time2 ? 0 : 1);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
new file mode 100644
index 0000000..85d7d0e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
@@ -0,0 +1,1541 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+
+public abstract class Constant implements TypeIds, OperatorIds {
+
+	public static final Constant NotAConstant = DoubleConstant.fromValue(Double.NaN);
+	
+	public boolean booleanValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "boolean" })); //$NON-NLS-1$
+	}
+
+	public byte byteValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "byte" })); //$NON-NLS-1$
+	}
+
+	public final Constant castTo(int conversionToTargetType){
+		//the cast is an int of the form
+		// (castId<<4)+typeId (in order to follow the
+		//user written style (cast)expression ....
+
+		if (this == NotAConstant) return NotAConstant;
+		switch(conversionToTargetType){
+			case T_undefined : 						return this;
+	//            TARGET TYPE  <- FROM TYPE
+	//	    case (T_undefined<<4)+T_undefined  	 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_byte  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_long  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_short  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_String  	 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_Object  	 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_double  	 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_float  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_boolean 	 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_char  		 : return NotAConstant;
+	//	    case (T_undefined<<4)+T_int  		 : return NotAConstant;
+
+	//	    case (T_byte<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_byte<<4)+T_byte  		 : return this;
+		    case (T_byte<<4)+T_long  		 : return ByteConstant.fromValue((byte)longValue());
+		    case (T_byte<<4)+T_short  		 : return ByteConstant.fromValue((byte)shortValue());
+	//	    case (T_byte<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_byte<<4)+T_String  	 	 : return NotAConstant;
+	//	    case (T_byte<<4)+T_Object  	 	 : return NotAConstant;
+		    case (T_byte<<4)+T_double  	 	 : return ByteConstant.fromValue((byte)doubleValue());
+		    case (T_byte<<4)+T_float  		 : return ByteConstant.fromValue((byte)floatValue());
+	//	    case (T_byte<<4)+T_boolean  	 : return NotAConstant;
+		    case (T_byte<<4)+T_char  		 : return ByteConstant.fromValue((byte)charValue());
+		    case (T_byte<<4)+T_int  		 : return ByteConstant.fromValue((byte)intValue());
+
+	//	    case (T_long<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_long<<4)+T_byte  		 : return LongConstant.fromValue(byteValue());
+		    case (T_long<<4)+T_long  		 : return this;
+		    case (T_long<<4)+T_short  		 : return LongConstant.fromValue(shortValue());
+	//	    case (T_long<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_long<<4)+T_String  		 : return NotAConstant;
+	//	    case (T_long<<4)+T_Object  		 : return NotAConstant;
+		    case (T_long<<4)+T_double  		 : return LongConstant.fromValue((long)doubleValue());
+		    case (T_long<<4)+T_float  		 : return LongConstant.fromValue((long)floatValue());
+	//	    case (T_long<<4)+T_boolean  	 : return NotAConstant;
+		    case (T_long<<4)+T_char  		 : return LongConstant.fromValue(charValue());
+		    case (T_long<<4)+T_int  		 : return LongConstant.fromValue(intValue());
+
+	//	    case (T_short<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_short<<4)+T_byte  		 : return ShortConstant.fromValue(byteValue());
+		    case (T_short<<4)+T_long  		 : return ShortConstant.fromValue((short)longValue());
+		    case (T_short<<4)+T_short  		 : return this;
+	//	    case (T_short<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_short<<4)+T_String  	 : return NotAConstant;
+	//	    case (T_short<<4)+T_Object  	 : return NotAConstant;
+		    case (T_short<<4)+T_double  	 : return ShortConstant.fromValue((short)doubleValue());
+		    case (T_short<<4)+T_float  		 : return ShortConstant.fromValue((short)floatValue());
+	//	    case (T_short<<4)+T_boolean 	 : return NotAConstant;
+		    case (T_short<<4)+T_char  		 : return ShortConstant.fromValue((short)charValue());
+		    case (T_short<<4)+T_int  		 : return ShortConstant.fromValue((short)intValue());
+
+	//	    case (T_void<<4)+T_undefined  	 : return NotAConstant;
+	//	    case (T_void<<4)+T_byte  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_long  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_short  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_String  	 	 : return NotAConstant;
+	//	    case (T_void<<4)+T_Object  	 	 : return NotAConstant;
+	//	    case (T_void<<4)+T_double  	 	 : return NotAConstant;
+	//	    case (T_void<<4)+T_float  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_boolean  	 : return NotAConstant;
+	//	    case (T_void<<4)+T_char  		 : return NotAConstant;
+	//	    case (T_void<<4)+T_int  		 : return NotAConstant;
+
+	//	    case (T_String<<4)+T_undefined   : return NotAConstant;
+	//	    case (T_String<<4)+T_byte  		 : return NotAConstant;
+	//	    case (T_String<<4)+T_long  		 : return NotAConstant;
+	//	    case (T_String<<4)+T_short  	 : return NotAConstant;
+	//	    case (T_String<<4)+T_void  		 : return NotAConstant;
+		    case (T_JavaLangString<<4)+T_JavaLangString  	 : return this;
+	//	    case (T_String<<4)+T_Object  	 : return NotAConstant;
+	//	    case (T_String<<4)+T_double  	 : return NotAConstant;
+	//	    case (T_String<<4)+T_float  	 : return NotAConstant;
+	//	    case (T_String<<4)+T_boolean 	 : return NotAConstant;
+	//	    case (T_String<<4)+T_char  		 : return NotAConstant;
+	//	    case (T_String<<4)+T_int  		 : return NotAConstant;
+
+	//	    case (T_Object<<4)+T_undefined   	: return NotAConstant;
+	//	    case (T_Object<<4)+T_byte  		 	: return NotAConstant;
+	//	    case (T_Object<<4)+T_long  		 	: return NotAConstant;
+	//	    case (T_Object<<4)+T_short 		 	: return NotAConstant;
+	//	    case (T_Object<<4)+T_void  		 	: return NotAConstant;
+	//	    case (T_Object<<4)+T_String  		: return NotAConstant;
+	//	    case (T_Object<<4)+T_Object  		: return NotAConstant;
+	//	    case (T_Object<<4)+T_double  		: return NotAConstant;
+	//	    case (T_Object<<4)+T_float  		: return NotAConstant;
+	//	    case (T_Object<<4)+T_boolean 		: return NotAConstant;
+	//	    case (T_Object<<4)+T_char  		 	: return NotAConstant;
+	//	    case (T_Object<<4)+T_int  			: return NotAConstant;
+
+	//	    case (T_double<<4)+T_undefined  	: return NotAConstant;
+		    case (T_double<<4)+T_byte  		 	: return DoubleConstant.fromValue(byteValue());
+		    case (T_double<<4)+T_long  		 	: return DoubleConstant.fromValue(longValue());
+		    case (T_double<<4)+T_short  		: return DoubleConstant.fromValue(shortValue());
+	//	    case (T_double<<4)+T_void  		 	: return NotAConstant;
+	//	    case (T_double<<4)+T_String  		: return NotAConstant;
+	//	    case (T_double<<4)+T_Object  		: return NotAConstant;
+		    case (T_double<<4)+T_double  		: return this;
+		    case (T_double<<4)+T_float  		: return DoubleConstant.fromValue(floatValue());
+	//	    case (T_double<<4)+T_boolean  		: return NotAConstant;
+		    case (T_double<<4)+T_char  		 	: return DoubleConstant.fromValue(charValue());
+		    case (T_double<<4)+T_int  			: return DoubleConstant.fromValue(intValue());
+
+	//	    case (T_float<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_float<<4)+T_byte  		 : return FloatConstant.fromValue(byteValue());
+		    case (T_float<<4)+T_long  		 : return FloatConstant.fromValue(longValue());
+		    case (T_float<<4)+T_short  		 : return FloatConstant.fromValue(shortValue());
+	//	    case (T_float<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_float<<4)+T_String  	 : return NotAConstant;
+	//	    case (T_float<<4)+T_Object  	 : return NotAConstant;
+		    case (T_float<<4)+T_double  	 : return FloatConstant.fromValue((float)doubleValue());
+		    case (T_float<<4)+T_float  		 : return this;
+	//	    case (T_float<<4)+T_boolean 	 : return NotAConstant;
+		    case (T_float<<4)+T_char  		 : return FloatConstant.fromValue(charValue());
+		    case (T_float<<4)+T_int  		 : return FloatConstant.fromValue(intValue());
+
+	//	    case (T_boolean<<4)+T_undefined  		 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_byte  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_long  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_short  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_void  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_String  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_Object  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_double  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_float  			 : return NotAConstant;
+		    case (T_boolean<<4)+T_boolean  			 : return this;
+	//	    case (T_boolean<<4)+T_char  			 : return NotAConstant;
+	//	    case (T_boolean<<4)+T_int  				 : return NotAConstant;
+
+	//	    case (T_char<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_char<<4)+T_byte  		 : return CharConstant.fromValue((char)byteValue());
+		    case (T_char<<4)+T_long  		 : return CharConstant.fromValue((char)longValue());
+		    case (T_char<<4)+T_short  		 : return CharConstant.fromValue((char)shortValue());
+	//	    case (T_char<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_char<<4)+T_String  		 : return NotAConstant;
+	//	    case (T_char<<4)+T_Object  		 : return NotAConstant;
+		    case (T_char<<4)+T_double  		 : return CharConstant.fromValue((char)doubleValue());
+		    case (T_char<<4)+T_float  		 : return CharConstant.fromValue((char)floatValue());
+	//	    case (T_char<<4)+T_boolean  	 : return NotAConstant;
+		    case (T_char<<4)+T_char  		 : return this;
+		    case (T_char<<4)+T_int  		 : return CharConstant.fromValue((char)intValue());
+
+	//	    case (T_int<<4)+T_undefined  	 : return NotAConstant;
+		    case (T_int<<4)+T_byte  		 : return IntConstant.fromValue(byteValue());
+		    case (T_int<<4)+T_long  		 : return IntConstant.fromValue((int) longValue());
+		    case (T_int<<4)+T_short  		 : return IntConstant.fromValue(shortValue());
+	//	    case (T_int<<4)+T_void  		 : return NotAConstant;
+	//	    case (T_int<<4)+T_String  		 : return NotAConstant;
+	//	    case (T_int<<4)+T_Object  		 : return NotAConstant;
+		    case (T_int<<4)+T_double  		 : return IntConstant.fromValue((int) doubleValue());
+		    case (T_int<<4)+T_float  		 : return IntConstant.fromValue((int) floatValue());
+	//	    case (T_int<<4)+T_boolean  	 	 : return NotAConstant;
+		    case (T_int<<4)+T_char  		 : return IntConstant.fromValue(charValue());
+		    case (T_int<<4)+T_int  		 	 : return this;
+
+		}
+		return NotAConstant;
+	}
+
+	public char charValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "char" })); //$NON-NLS-1$
+	}
+
+	public static final Constant computeConstantOperation(Constant cst, int id, int operator) {
+		switch (operator) {
+			case NOT	:
+							return BooleanConstant.fromValue(!cst.booleanValue());
+			case PLUS	:
+							return computeConstantOperationPLUS(IntConstant.fromValue(0),T_int,cst,id);
+			case MINUS	:	//the two special -9223372036854775808L and -2147483648 are inlined at parseTime
+							switch (id){
+								case T_float  :	float f;
+												if ( (f= cst.floatValue()) == 0.0f)
+												{ //positive and negative 0....
+													if (Float.floatToIntBits(f) == 0)
+														return FloatConstant.fromValue(-0.0f);
+													else
+														return FloatConstant.fromValue(0.0f);}
+												break; //default case
+								case T_double : double d;
+												if ( (d= cst.doubleValue()) == 0.0d)
+												{ //positive and negative 0....
+													if (Double.doubleToLongBits(d) == 0)
+														return DoubleConstant.fromValue(-0.0d);
+													else
+														return DoubleConstant.fromValue(0.0d);}
+												break; //default case
+							}
+							return computeConstantOperationMINUS(IntConstant.fromValue(0),T_int,cst,id);
+			case TWIDDLE:
+				switch (id){
+					case T_char :	return IntConstant.fromValue(~ cst.charValue());
+					case T_byte:	return IntConstant.fromValue(~ cst.byteValue());
+					case T_short:	return IntConstant.fromValue(~ cst.shortValue());
+					case T_int:		return IntConstant.fromValue(~ cst.intValue());
+					case T_long:	return LongConstant.fromValue(~ cst.longValue());
+					default : return NotAConstant;
+				}
+			default : return NotAConstant;
+		}
+	}
+
+	public static final Constant computeConstantOperation(Constant left, int leftId, int operator, Constant right, int rightId) {
+		switch (operator) {
+			case AND		: return computeConstantOperationAND		(left,leftId,right,rightId);
+			case AND_AND	: return computeConstantOperationAND_AND	(left,leftId,right,rightId);
+			case DIVIDE 	: return computeConstantOperationDIVIDE		(left,leftId,right,rightId);
+			case GREATER	: return computeConstantOperationGREATER	(left,leftId,right,rightId);
+			case GREATER_EQUAL	: return computeConstantOperationGREATER_EQUAL(left,leftId,right,rightId);
+			case LEFT_SHIFT	: return computeConstantOperationLEFT_SHIFT	(left,leftId,right,rightId);
+			case LESS		: return computeConstantOperationLESS		(left,leftId,right,rightId);
+			case LESS_EQUAL	: return computeConstantOperationLESS_EQUAL	(left,leftId,right,rightId);
+			case MINUS		: return computeConstantOperationMINUS		(left,leftId,right,rightId);
+			case MULTIPLY	: return computeConstantOperationMULTIPLY	(left,leftId,right,rightId);
+			case OR			: return computeConstantOperationOR			(left,leftId,right,rightId);
+			case OR_OR		: return computeConstantOperationOR_OR		(left,leftId,right,rightId);
+			case PLUS		: return computeConstantOperationPLUS		(left,leftId,right,rightId);
+			case REMAINDER	: return computeConstantOperationREMAINDER	(left,leftId,right,rightId);
+			case RIGHT_SHIFT: return computeConstantOperationRIGHT_SHIFT(left,leftId,right,rightId);
+			case UNSIGNED_RIGHT_SHIFT: return computeConstantOperationUNSIGNED_RIGHT_SHIFT(left,leftId,right,rightId);
+			case XOR		: return computeConstantOperationXOR		(left,leftId,right,rightId);
+			default : return NotAConstant;
+		}
+	}
+
+	public static final Constant computeConstantOperationAND(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_boolean :		return BooleanConstant.fromValue(left.booleanValue() & right.booleanValue());
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() & right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() & right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() & right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() & right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() & right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() & right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() & right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() & right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() & right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() & right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() & right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() & right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() & right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() & right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() & right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() & right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() & right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() & right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() & right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() & right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() & right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() & right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() & right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() & right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() & right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationAND_AND(Constant left, int leftId, Constant right, int rightId) {
+		return BooleanConstant.fromValue(left.booleanValue() && right.booleanValue());
+	}
+
+	public static final Constant computeConstantOperationDIVIDE(Constant left, int leftId, Constant right, int rightId) {
+		// division by zero must be handled outside this method (error reporting)
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.charValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.charValue() / right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() / right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() / right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() / right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() / right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return FloatConstant.fromValue(left.floatValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.floatValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.floatValue() / right.doubleValue());
+					case T_byte:	return FloatConstant.fromValue(left.floatValue() / right.byteValue());
+					case T_short:	return FloatConstant.fromValue(left.floatValue() / right.shortValue());
+					case T_int:		return FloatConstant.fromValue(left.floatValue() / right.intValue());
+					case T_long:	return FloatConstant.fromValue(left.floatValue() / right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return DoubleConstant.fromValue(left.doubleValue() / right.charValue());
+					case T_float:	return DoubleConstant.fromValue(left.doubleValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.doubleValue() / right.doubleValue());
+					case T_byte:	return DoubleConstant.fromValue(left.doubleValue() / right.byteValue());
+					case T_short:	return DoubleConstant.fromValue(left.doubleValue() / right.shortValue());
+					case T_int:		return DoubleConstant.fromValue(left.doubleValue() / right.intValue());
+					case T_long:	return DoubleConstant.fromValue(left.doubleValue() / right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.byteValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.byteValue() / right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() / right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() / right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() / right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() / right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.shortValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.shortValue() / right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() / right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() / right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() / right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() / right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.intValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.intValue() / right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() / right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() / right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() / right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() / right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() / right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.longValue() / right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.longValue() / right.doubleValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() / right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() / right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() / right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() / right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationEQUAL_EQUAL(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_boolean :
+				if (rightId == T_boolean) {
+					return BooleanConstant.fromValue(left.booleanValue() == right.booleanValue());
+				}
+				break;
+			case T_char :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.charValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.charValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.charValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.charValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.charValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.charValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.charValue() == right.longValue());}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.floatValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.floatValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.floatValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.floatValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.floatValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.floatValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.floatValue() == right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.doubleValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.doubleValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.doubleValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.doubleValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.doubleValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.doubleValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.doubleValue() == right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.byteValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.byteValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.byteValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.byteValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.byteValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.byteValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.byteValue() == right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.shortValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.shortValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.shortValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.shortValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.shortValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.shortValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.shortValue() == right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.intValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.intValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.intValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.intValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.intValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.intValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.intValue() == right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.longValue() == right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.longValue() == right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.longValue() == right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.longValue() == right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.longValue() == right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.longValue() == right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.longValue() == right.longValue());
+				}
+				break;
+			case T_JavaLangString :
+				if (rightId == T_JavaLangString) {
+					//String are interned in th compiler==>thus if two string constant
+					//get to be compared, it is an equal on the vale which is done
+					return BooleanConstant.fromValue(((StringConstant)left).hasSameValue(right));
+				}
+				break;
+			case T_null :
+				if (rightId == T_JavaLangString) {
+					return BooleanConstant.fromValue(false);
+				} else {
+					if (rightId == T_null) {
+						return BooleanConstant.fromValue(true);
+					}
+				}
+		}
+		return BooleanConstant.fromValue(false);
+	}
+
+	public static final Constant computeConstantOperationGREATER(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.charValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.charValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.charValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.charValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.charValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.charValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.charValue() > right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.floatValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.floatValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.floatValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.floatValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.floatValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.floatValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.floatValue() > right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.doubleValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.doubleValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.doubleValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.doubleValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.doubleValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.doubleValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.doubleValue() > right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.byteValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.byteValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.byteValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.byteValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.byteValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.byteValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.byteValue() > right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.shortValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.shortValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.shortValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.shortValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.shortValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.shortValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.shortValue() > right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.intValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.intValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.intValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.intValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.intValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.intValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.intValue() > right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.longValue() > right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.longValue() > right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.longValue() > right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.longValue() > right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.longValue() > right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.longValue() > right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.longValue() > right.longValue());
+				}
+
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationGREATER_EQUAL(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.charValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.charValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.charValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.charValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.charValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.charValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.charValue() >= right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.floatValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.floatValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.floatValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.floatValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.floatValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.floatValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.floatValue() >= right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.doubleValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.doubleValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.doubleValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.doubleValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.doubleValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.doubleValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.doubleValue() >= right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.byteValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.byteValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.byteValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.byteValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.byteValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.byteValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.byteValue() >= right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.shortValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.shortValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.shortValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.shortValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.shortValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.shortValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.shortValue() >= right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.intValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.intValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.intValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.intValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.intValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.intValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.intValue() >= right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.longValue() >= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.longValue() >= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.longValue() >= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.longValue() >= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.longValue() >= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.longValue() >= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.longValue() >= right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationLEFT_SHIFT(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() << right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() << right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() << right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() << right.intValue());
+					case T_long:	return IntConstant.fromValue(left.charValue() << right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() << right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() << right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() << right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() << right.intValue());
+					case T_long:	return IntConstant.fromValue(left.byteValue() << right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() << right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() << right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() << right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() << right.intValue());
+					case T_long:	return IntConstant.fromValue(left.shortValue() << right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() << right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() << right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() << right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() << right.intValue());
+					case T_long:	return IntConstant.fromValue(left.intValue() << right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() << right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() << right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() << right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() << right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() << right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationLESS(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.charValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.charValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.charValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.charValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.charValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.charValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.charValue() < right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.floatValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.floatValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.floatValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.floatValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.floatValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.floatValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.floatValue() < right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.doubleValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.doubleValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.doubleValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.doubleValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.doubleValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.doubleValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.doubleValue() < right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.byteValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.byteValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.byteValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.byteValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.byteValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.byteValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.byteValue() < right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.shortValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.shortValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.shortValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.shortValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.shortValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.shortValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.shortValue() < right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.intValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.intValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.intValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.intValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.intValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.intValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.intValue() < right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.longValue() < right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.longValue() < right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.longValue() < right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.longValue() < right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.longValue() < right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.longValue() < right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.longValue() < right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationLESS_EQUAL(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.charValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.charValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.charValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.charValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.charValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.charValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.charValue() <= right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.floatValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.floatValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.floatValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.floatValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.floatValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.floatValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.floatValue() <= right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.doubleValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.doubleValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.doubleValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.doubleValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.doubleValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.doubleValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.doubleValue() <= right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.byteValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.byteValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.byteValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.byteValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.byteValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.byteValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.byteValue() <= right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.shortValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.shortValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.shortValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.shortValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.shortValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.shortValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.shortValue() <= right.longValue());
+				}
+			break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.intValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.intValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.intValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.intValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.intValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.intValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.intValue() <= right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return BooleanConstant.fromValue(left.longValue() <= right.charValue());
+					case T_float:	return BooleanConstant.fromValue(left.longValue() <= right.floatValue());
+					case T_double:	return BooleanConstant.fromValue(left.longValue() <= right.doubleValue());
+					case T_byte:	return BooleanConstant.fromValue(left.longValue() <= right.byteValue());
+					case T_short:	return BooleanConstant.fromValue(left.longValue() <= right.shortValue());
+					case T_int:		return BooleanConstant.fromValue(left.longValue() <= right.intValue());
+					case T_long:	return BooleanConstant.fromValue(left.longValue() <= right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationMINUS(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.charValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.charValue() - right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() - right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() - right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() - right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() - right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return FloatConstant.fromValue(left.floatValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.floatValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.floatValue() - right.doubleValue());
+					case T_byte:	return FloatConstant.fromValue(left.floatValue() - right.byteValue());
+					case T_short:	return FloatConstant.fromValue(left.floatValue() - right.shortValue());
+					case T_int:		return FloatConstant.fromValue(left.floatValue() - right.intValue());
+					case T_long:	return FloatConstant.fromValue(left.floatValue() - right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return DoubleConstant.fromValue(left.doubleValue() - right.charValue());
+					case T_float:	return DoubleConstant.fromValue(left.doubleValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.doubleValue() - right.doubleValue());
+					case T_byte:	return DoubleConstant.fromValue(left.doubleValue() - right.byteValue());
+					case T_short:	return DoubleConstant.fromValue(left.doubleValue() - right.shortValue());
+					case T_int:		return DoubleConstant.fromValue(left.doubleValue() - right.intValue());
+					case T_long:	return DoubleConstant.fromValue(left.doubleValue() - right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.byteValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.byteValue() - right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() - right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() - right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() - right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() - right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.shortValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.shortValue() - right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() - right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() - right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() - right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() - right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.intValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.intValue() - right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() - right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() - right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() - right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() - right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() - right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.longValue() - right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.longValue() - right.doubleValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() - right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() - right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() - right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() - right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationMULTIPLY(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.charValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.charValue() * right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() * right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() * right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() * right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() * right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return FloatConstant.fromValue(left.floatValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.floatValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.floatValue() * right.doubleValue());
+					case T_byte:	return FloatConstant.fromValue(left.floatValue() * right.byteValue());
+					case T_short:	return FloatConstant.fromValue(left.floatValue() * right.shortValue());
+					case T_int:		return FloatConstant.fromValue(left.floatValue() * right.intValue());
+					case T_long:	return FloatConstant.fromValue(left.floatValue() * right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return DoubleConstant.fromValue(left.doubleValue() * right.charValue());
+					case T_float:	return DoubleConstant.fromValue(left.doubleValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.doubleValue() * right.doubleValue());
+					case T_byte:	return DoubleConstant.fromValue(left.doubleValue() * right.byteValue());
+					case T_short:	return DoubleConstant.fromValue(left.doubleValue() * right.shortValue());
+					case T_int:		return DoubleConstant.fromValue(left.doubleValue() * right.intValue());
+					case T_long:	return DoubleConstant.fromValue(left.doubleValue() * right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.byteValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.byteValue() * right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() * right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() * right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() * right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() * right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.shortValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.shortValue() * right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() * right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() * right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() * right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() * right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.intValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.intValue() * right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() * right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() * right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() * right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() * right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() * right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.longValue() * right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.longValue() * right.doubleValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() * right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() * right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() * right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() * right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationOR(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_boolean :		return BooleanConstant.fromValue(left.booleanValue() | right.booleanValue());
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() | right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() | right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() | right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() | right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() | right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() | right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() | right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() | right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() | right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() | right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() | right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() | right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() | right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() | right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() | right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() | right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() | right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() | right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() | right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() | right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() | right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() | right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() | right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() | right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() | right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationOR_OR(Constant left, int leftId, Constant right, int rightId) {
+		return BooleanConstant.fromValue(left.booleanValue() || right.booleanValue());
+	}
+
+	public static final Constant computeConstantOperationPLUS(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_JavaLangObject :
+				if (rightId == T_JavaLangString) {
+					return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_boolean :
+				if (rightId == T_JavaLangString) {
+					return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.charValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.charValue() + right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() + right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() + right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() + right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return FloatConstant.fromValue(left.floatValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.floatValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.floatValue() + right.doubleValue());
+					case T_byte:	return FloatConstant.fromValue(left.floatValue() + right.byteValue());
+					case T_short:	return FloatConstant.fromValue(left.floatValue() + right.shortValue());
+					case T_int:		return FloatConstant.fromValue(left.floatValue() + right.intValue());
+					case T_long:	return FloatConstant.fromValue(left.floatValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return DoubleConstant.fromValue(left.doubleValue() + right.charValue());
+					case T_float:	return DoubleConstant.fromValue(left.doubleValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.doubleValue() + right.doubleValue());
+					case T_byte:	return DoubleConstant.fromValue(left.doubleValue() + right.byteValue());
+					case T_short:	return DoubleConstant.fromValue(left.doubleValue() + right.shortValue());
+					case T_int:		return DoubleConstant.fromValue(left.doubleValue() + right.intValue());
+					case T_long:	return DoubleConstant.fromValue(left.doubleValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.byteValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.byteValue() + right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() + right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() + right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() + right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.shortValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.shortValue() + right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() + right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() + right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() + right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.intValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.intValue() + right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() + right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() + right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() + right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() + right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.longValue() + right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.longValue() + right.doubleValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() + right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() + right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() + right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() + right.longValue());
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+				}
+				break;
+			case T_JavaLangString :
+				switch (rightId){
+					case T_char :	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.charValue()));
+					case T_float:	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.floatValue()));
+					case T_double:	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.doubleValue()));
+					case T_byte:	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.byteValue()));
+					case T_short:	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.shortValue()));
+					case T_int:		return StringConstant.fromValue(left.stringValue() + String.valueOf(right.intValue()));
+					case T_long:	return StringConstant.fromValue(left.stringValue() + String.valueOf(right.longValue()));
+					case T_JavaLangString:	return StringConstant.fromValue(left.stringValue() + right.stringValue());
+					case T_boolean:	return StringConstant.fromValue(left.stringValue() + right.booleanValue());
+				}
+				break;
+//			case T_null :
+//				switch (rightId){
+//					case T_char :	return Constant.fromValue(left.stringValue() + String.valueOf(right.charValue()));
+//					case T_float:	return Constant.fromValue(left.stringValue() + String.valueOf(right.floatValue()));
+//					case T_double:	return Constant.fromValue(left.stringValue() + String.valueOf(right.doubleValue()));
+//					case T_byte:	return Constant.fromValue(left.stringValue() + String.valueOf(right.byteValue()));
+//					case T_short:	return Constant.fromValue(left.stringValue() + String.valueOf(right.shortValue()));
+//					case T_int:		return Constant.fromValue(left.stringValue() + String.valueOf(right.intValue()));
+//					case T_long:	return Constant.fromValue(left.stringValue() + String.valueOf(right.longValue()));
+//					case T_JavaLangString:	return Constant.fromValue(left.stringValue() + right.stringValue());
+//					case T_boolean:	return Constant.fromValue(left.stringValue() + right.booleanValue());
+//				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationREMAINDER(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.charValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.charValue() % right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() % right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() % right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() % right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() % right.longValue());
+				}
+				break;
+			case T_float :
+				switch (rightId){
+					case T_char :	return FloatConstant.fromValue(left.floatValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.floatValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.floatValue() % right.doubleValue());
+					case T_byte:	return FloatConstant.fromValue(left.floatValue() % right.byteValue());
+					case T_short:	return FloatConstant.fromValue(left.floatValue() % right.shortValue());
+					case T_int:		return FloatConstant.fromValue(left.floatValue() % right.intValue());
+					case T_long:	return FloatConstant.fromValue(left.floatValue() % right.longValue());
+				}
+				break;
+			case T_double :
+				switch (rightId){
+					case T_char :	return DoubleConstant.fromValue(left.doubleValue() % right.charValue());
+					case T_float:	return DoubleConstant.fromValue(left.doubleValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.doubleValue() % right.doubleValue());
+					case T_byte:	return DoubleConstant.fromValue(left.doubleValue() % right.byteValue());
+					case T_short:	return DoubleConstant.fromValue(left.doubleValue() % right.shortValue());
+					case T_int:		return DoubleConstant.fromValue(left.doubleValue() % right.intValue());
+					case T_long:	return DoubleConstant.fromValue(left.doubleValue() % right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.byteValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.byteValue() % right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() % right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() % right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() % right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() % right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.shortValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.shortValue() % right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() % right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() % right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() % right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() % right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.intValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.intValue() % right.doubleValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() % right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() % right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() % right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() % right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() % right.charValue());
+					case T_float:	return FloatConstant.fromValue(left.longValue() % right.floatValue());
+					case T_double:	return DoubleConstant.fromValue(left.longValue() % right.doubleValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() % right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() % right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() % right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() % right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationRIGHT_SHIFT(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() >> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() >> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() >> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() >> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.charValue() >> right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() >> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() >> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() >> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() >> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.byteValue() >> right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() >> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() >> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() >> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() >> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.shortValue() >> right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() >> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() >> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() >> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() >> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.intValue() >> right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() >> right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() >> right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() >> right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() >> right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() >> right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationUNSIGNED_RIGHT_SHIFT(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() >>> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() >>> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() >>> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() >>> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.charValue() >>> right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() >>> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() >>> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() >>> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() >>> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.byteValue() >>> right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() >>> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() >>> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() >>> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() >>> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.shortValue() >>> right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() >>> right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() >>> right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() >>> right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() >>> right.intValue());
+					case T_long:	return IntConstant.fromValue(left.intValue() >>> right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() >>> right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() >>> right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() >>> right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() >>> right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() >>> right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public static final Constant computeConstantOperationXOR(Constant left, int leftId, Constant right, int rightId) {
+		switch (leftId){
+			case T_boolean :		return BooleanConstant.fromValue(left.booleanValue() ^ right.booleanValue());
+			case T_char :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.charValue() ^ right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.charValue() ^ right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.charValue() ^ right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.charValue() ^ right.intValue());
+					case T_long:	return LongConstant.fromValue(left.charValue() ^ right.longValue());
+				}
+				break;
+			case T_byte :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.byteValue() ^ right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.byteValue() ^ right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.byteValue() ^ right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.byteValue() ^ right.intValue());
+					case T_long:	return LongConstant.fromValue(left.byteValue() ^ right.longValue());
+				}
+				break;
+			case T_short :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.shortValue() ^ right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.shortValue() ^ right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.shortValue() ^ right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.shortValue() ^ right.intValue());
+					case T_long:	return LongConstant.fromValue(left.shortValue() ^ right.longValue());
+				}
+				break;
+			case T_int :
+				switch (rightId){
+					case T_char :	return IntConstant.fromValue(left.intValue() ^ right.charValue());
+					case T_byte:	return IntConstant.fromValue(left.intValue() ^ right.byteValue());
+					case T_short:	return IntConstant.fromValue(left.intValue() ^ right.shortValue());
+					case T_int:		return IntConstant.fromValue(left.intValue() ^ right.intValue());
+					case T_long:	return LongConstant.fromValue(left.intValue() ^ right.longValue());
+				}
+				break;
+			case T_long :
+				switch (rightId){
+					case T_char :	return LongConstant.fromValue(left.longValue() ^ right.charValue());
+					case T_byte:	return LongConstant.fromValue(left.longValue() ^ right.byteValue());
+					case T_short:	return LongConstant.fromValue(left.longValue() ^ right.shortValue());
+					case T_int:		return LongConstant.fromValue(left.longValue() ^ right.intValue());
+					case T_long:	return LongConstant.fromValue(left.longValue() ^ right.longValue());
+				}
+		}
+		return NotAConstant;
+	}
+
+	public double doubleValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "double" })); //$NON-NLS-1$
+	}
+
+	public float floatValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "float" })); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Returns true if both constants have the same type and the same actual value
+	 * @param otherConstant
+	 */
+	public boolean hasSameValue(Constant otherConstant) {
+		if (this == otherConstant)
+			return true;
+		int typeID;
+		if ((typeID = typeID()) != otherConstant.typeID())
+			return false;
+		switch (typeID) {
+			case TypeIds.T_boolean:
+				return booleanValue() == otherConstant.booleanValue();
+			case TypeIds.T_byte:
+				return byteValue() == otherConstant.byteValue();
+			case TypeIds.T_char:
+				return charValue() == otherConstant.charValue();
+			case TypeIds.T_double:
+				return doubleValue() == otherConstant.doubleValue();
+			case TypeIds.T_float:
+				return floatValue() == otherConstant.floatValue();
+			case TypeIds.T_int:
+				return intValue() == otherConstant.intValue();
+			case TypeIds.T_short:
+				return shortValue() == otherConstant.shortValue();
+			case TypeIds.T_long:
+				return longValue() == otherConstant.longValue();
+			case TypeIds.T_JavaLangString:
+				String value = stringValue();
+				return value == null
+					? otherConstant.stringValue() == null
+					: value.equals(otherConstant.stringValue());
+		}
+		return false;
+	}
+
+	public int intValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "int" })); //$NON-NLS-1$
+	}
+
+	public long longValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "long" })); //$NON-NLS-1$
+	}
+
+	public short shortValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotConvertedTo, new String[] { typeName(), "short" })); //$NON-NLS-1$
+	}
+
+	public String stringValue() {
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotConvertedTo, new String[] { typeName(), "String" })); //$NON-NLS-1$
+	}
+
+	public String toString(){
+		if (this == NotAConstant) return "(Constant) NotAConstant"; //$NON-NLS-1$
+		return super.toString(); }
+
+	public abstract int typeID();
+
+	public String typeName() {
+		switch (typeID()) {
+			case T_int : return "int"; //$NON-NLS-1$
+			case T_byte : return "byte"; //$NON-NLS-1$
+			case T_short : return "short"; //$NON-NLS-1$
+			case T_char : return "char"; //$NON-NLS-1$
+			case T_float : return "float"; //$NON-NLS-1$
+			case T_double : return "double"; //$NON-NLS-1$
+			case T_boolean : return "boolean"; //$NON-NLS-1$
+			case T_long : return "long";//$NON-NLS-1$
+			case T_JavaLangString : return "java.lang.String"; //$NON-NLS-1$
+			default: return "unknown"; //$NON-NLS-1$
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java
new file mode 100644
index 0000000..ef841cb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class DoubleConstant extends Constant {
+
+	private double value;
+
+	public static Constant fromValue(double value) {
+		return new DoubleConstant(value);
+	}
+
+	private DoubleConstant(double value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return (byte) this.value;
+	}
+
+	public char charValue() {
+		return (char) this.value;
+	}
+
+	public double doubleValue() {
+		return this.value;
+	}
+
+	public float floatValue() {
+		return (float) this.value;
+	}
+
+	public int intValue() {
+		return (int) this.value;
+	}
+
+	public long longValue() {
+		return (long) this.value;
+	}
+
+	public short shortValue() {
+		return (short) this.value;
+	}
+
+	public String stringValue() {
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		if (this == NotAConstant)
+			return "(Constant) NotAConstant"; //$NON-NLS-1$
+		return "(double)" + this.value;  //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_double;
+	}
+
+	public int hashCode() {
+		long temp = Double.doubleToLongBits(this.value);
+		return (int) (temp ^ (temp >>> 32));
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		DoubleConstant other = (DoubleConstant) obj;
+		return Double.doubleToLongBits(this.value) == Double.doubleToLongBits(other.value);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java
new file mode 100644
index 0000000..41ced2d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class FloatConstant extends Constant {
+
+	float value;
+
+	public static Constant fromValue(float value) {
+		return new FloatConstant(value);
+	}
+
+	private FloatConstant(float value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return (byte) this.value;
+	}
+
+	public char charValue() {
+		return (char) this.value;
+	}
+
+	public double doubleValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public float floatValue() {
+		return this.value;
+	}
+
+	public int intValue() {
+		return (int) this.value;
+	}
+
+	public long longValue() {
+		return (long) this.value;
+	}
+
+	public short shortValue() {
+		return (short) this.value;
+	}
+
+	public String stringValue() {
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		return "(float)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_float;
+	}
+
+	public int hashCode() {
+		return Float.floatToIntBits(this.value);
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		FloatConstant other = (FloatConstant) obj;
+		return Float.floatToIntBits(this.value) == Float.floatToIntBits(other.value);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java
new file mode 100644
index 0000000..52cf61a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+
+public interface ITypeRequestor {
+
+	/**
+	 * Accept the resolved binary form for the requested type.
+	 */
+	void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction);
+
+	/**
+	 * Accept the requested type's compilation unit.
+	 */
+	void accept(ICompilationUnit unit, AccessRestriction accessRestriction);
+
+	/**
+	 * Accept the unresolved source forms for the requested type.
+	 * Note that the multiple source forms can be answered, in case the target compilation unit
+	 * contains multiple types. The first one is then guaranteed to be the one corresponding to the
+	 * requested type.
+	 */
+	void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java
new file mode 100644
index 0000000..01fb04a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class IntConstant extends Constant {
+
+	int value;
+
+	private static final IntConstant MIN_VALUE = new IntConstant(Integer.MIN_VALUE);
+	private static final IntConstant MINUS_FOUR = new IntConstant(-4);
+	private static final IntConstant MINUS_THREE = new IntConstant(-3);
+	private static final IntConstant MINUS_TWO = new IntConstant(-2);
+	private static final IntConstant MINUS_ONE = new IntConstant(-1);
+	private static final IntConstant ZERO = new IntConstant(0);
+	private static final IntConstant ONE = new IntConstant(1);
+	private static final IntConstant TWO = new IntConstant(2);
+	private static final IntConstant THREE = new IntConstant(3);
+	private static final IntConstant FOUR = new IntConstant(4);
+	private static final IntConstant FIVE = new IntConstant(5);
+	private static final IntConstant SIX = new IntConstant(6);
+	private static final IntConstant SEVEN = new IntConstant(7);
+	private static final IntConstant EIGHT= new IntConstant(8);
+	private static final IntConstant NINE = new IntConstant(9);
+	private static final IntConstant TEN = new IntConstant(10);
+
+	public static Constant fromValue(int value) {
+		switch (value) {
+			case Integer.MIN_VALUE : return IntConstant.MIN_VALUE;
+			case -4 : return IntConstant.MINUS_FOUR;
+			case -3 : return IntConstant.MINUS_THREE;
+			case -2 : return IntConstant.MINUS_TWO;
+			case -1 : return IntConstant.MINUS_ONE;
+			case 0 : return IntConstant.ZERO;
+			case 1 : return IntConstant.ONE;
+			case 2 : return IntConstant.TWO;
+			case 3 : return IntConstant.THREE;
+			case 4 : return IntConstant.FOUR;
+			case 5 : return IntConstant.FIVE;
+			case 6 : return IntConstant.SIX;
+			case 7 : return IntConstant.SEVEN;
+			case 8 : return IntConstant.EIGHT;
+			case 9 : return IntConstant.NINE;
+			case 10 : return IntConstant.TEN;
+		}
+		return new IntConstant(value);
+	}
+
+	private IntConstant(int value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return (byte) this.value;
+	}
+
+	public char charValue() {
+		return (char) this.value;
+	}
+
+	public double doubleValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public float floatValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public int intValue() {
+		return this.value;
+	}
+
+	public long longValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public short shortValue() {
+		return (short) this.value;
+	}
+
+	public String stringValue() {
+		//spec 15.17.11
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+		return "(int)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_int;
+	}
+
+	public int hashCode() {
+		return this.value;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		IntConstant other = (IntConstant) obj;
+		return this.value == other.value;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
new file mode 100644
index 0000000..e0b8968
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 265744 - Enum switch should warn about missing default
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.impl;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+/**
+ * Represent a set of irritant flags. Irritants are organized in up to 8 group
+ * of 29, allowing for a maximum of 232 distinct irritants.
+ */
+public class IrritantSet {
+
+	// Reserve two high bits for selecting the right bit pattern
+	public final static int GROUP_MASK = ASTNode.Bit32 | ASTNode.Bit31 | ASTNode.Bit30;
+	public final static int GROUP_SHIFT = 29;
+	public final static int GROUP_MAX = 3; // can be increased up to 8
+
+	// Group prefix for irritants
+	public final static int GROUP0 = 0 << GROUP_SHIFT;
+	public final static int GROUP1 = 1 << GROUP_SHIFT;
+	public final static int GROUP2 = 2 << GROUP_SHIFT;
+	// reveal subsequent groups as needed
+	// public final static int GROUP3 = 3 << GROUP_SHIFT;
+	// public final static int GROUP4 = 4 << GROUP_SHIFT;
+	// public final static int GROUP5 = 5 << GROUP_SHIFT;
+	// public final static int GROUP6 = 6 << GROUP_SHIFT;
+	// public final static int GROUP7 = 7 << GROUP_SHIFT;
+
+	// Predefine sets of irritants matching warning tokens
+	public static final IrritantSet ALL = new IrritantSet(0xFFFFFFFF & ~GROUP_MASK);
+	public static final IrritantSet BOXING = new IrritantSet(CompilerOptions.AutoBoxing);
+	public static final IrritantSet CAST = new IrritantSet(CompilerOptions.UnnecessaryTypeCheck);
+	public static final IrritantSet DEPRECATION = new IrritantSet(CompilerOptions.UsingDeprecatedAPI);
+	public static final IrritantSet DEP_ANN = new IrritantSet(CompilerOptions.MissingDeprecatedAnnotation);
+	public static final IrritantSet FALLTHROUGH = new IrritantSet(CompilerOptions.FallthroughCase);
+	public static final IrritantSet FINALLY = new IrritantSet(CompilerOptions.FinallyBlockNotCompleting);
+	public static final IrritantSet HIDING = new IrritantSet(CompilerOptions.MaskedCatchBlock);
+	public static final IrritantSet INCOMPLETE_SWITCH = new IrritantSet(CompilerOptions.MissingEnumConstantCase);
+	public static final IrritantSet NLS = new IrritantSet(CompilerOptions.NonExternalizedString);
+	public static final IrritantSet NULL = new IrritantSet(CompilerOptions.NullReference);
+	public static final IrritantSet RAW = new IrritantSet(CompilerOptions.RawTypeReference);
+	public static final IrritantSet RESTRICTION = new IrritantSet(CompilerOptions.ForbiddenReference);
+	public static final IrritantSet SERIAL = new IrritantSet(CompilerOptions.MissingSerialVersion);
+	public static final IrritantSet STATIC_ACCESS = new IrritantSet(CompilerOptions.IndirectStaticAccess);
+	public static final IrritantSet STATIC_METHOD = new IrritantSet(CompilerOptions.MethodCanBeStatic);
+	public static final IrritantSet SYNTHETIC_ACCESS = new IrritantSet(CompilerOptions.AccessEmulation);
+	public static final IrritantSet SYNCHRONIZED = new IrritantSet(CompilerOptions.MissingSynchronizedModifierInInheritedMethod);
+	public static final IrritantSet SUPER = new IrritantSet(CompilerOptions.OverridingMethodWithoutSuperInvocation);
+	public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
+	public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
+	public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
+	public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
+
+	public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
+	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default	
+	public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
+	static {
+		COMPILER_DEFAULT_WARNINGS
+			// group-0 warnings enabled by default
+			.set(
+				CompilerOptions.MethodWithConstructorName
+				| CompilerOptions.OverriddenPackageDefaultMethod
+				| CompilerOptions.UsingDeprecatedAPI
+				| CompilerOptions.MaskedCatchBlock
+				| CompilerOptions.UnusedLocalVariable
+				| CompilerOptions.NoImplicitStringConversion
+				| CompilerOptions.AssertUsedAsAnIdentifier
+				| CompilerOptions.UnusedImport
+				| CompilerOptions.NonStaticAccessToStatic
+				| CompilerOptions.NoEffectAssignment
+				| CompilerOptions.IncompatibleNonInheritedInterfaceMethod
+				| CompilerOptions.UnusedPrivateMember
+				| CompilerOptions.FinallyBlockNotCompleting)
+			// group-1 warnings enabled by default
+			.set(
+				CompilerOptions.UncheckedTypeOperation
+				| CompilerOptions.FinalParameterBound
+				| CompilerOptions.MissingSerialVersion
+				| CompilerOptions.EnumUsedAsAnIdentifier
+				| CompilerOptions.ForbiddenReference
+				| CompilerOptions.VarargsArgumentNeedCast
+				| CompilerOptions.NullReference
+				| CompilerOptions.AnnotationSuperInterface
+				| CompilerOptions.TypeHiding
+				| CompilerOptions.DiscouragedReference
+				| CompilerOptions.UnhandledWarningToken
+				| CompilerOptions.RawTypeReference
+				| CompilerOptions.UnusedLabel
+				| CompilerOptions.UnusedTypeArguments
+				| CompilerOptions.UnusedWarningToken
+				| CompilerOptions.ComparingIdentical
+				| CompilerOptions.MissingEnumConstantCase)
+			// group-2 warnings enabled by default
+			.set(
+				CompilerOptions.DeadCode
+				|CompilerOptions.Tasks
+				|CompilerOptions.UnclosedCloseable
+				|CompilerOptions.NullUncheckedConversion
+				|CompilerOptions.RedundantNullAnnotation
+				|CompilerOptions.NonnullParameterAnnotationDropped);
+		// default errors IF AnnotationBasedNullAnalysis is enabled:
+		COMPILER_DEFAULT_ERRORS.set(
+				CompilerOptions.NullSpecViolation
+				|CompilerOptions.NullAnnotationInferenceConflict);
+
+		ALL.setAll();
+		HIDING
+			.set(CompilerOptions.FieldHiding)
+			.set(CompilerOptions.LocalVariableHiding)
+			.set(CompilerOptions.TypeHiding);
+		NULL
+			.set(CompilerOptions.PotentialNullReference)
+			.set(CompilerOptions.RedundantNullCheck)
+			.set(CompilerOptions.NullSpecViolation)
+			.set(CompilerOptions.NullAnnotationInferenceConflict)
+			.set(CompilerOptions.NullUncheckedConversion)
+			.set(CompilerOptions.RedundantNullAnnotation)
+			.set(CompilerOptions.NonnullParameterAnnotationDropped);
+
+		RESTRICTION.set(CompilerOptions.DiscouragedReference);
+		STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
+		UNUSED
+			.set(CompilerOptions.UnusedArgument)
+			.set(CompilerOptions.UnusedPrivateMember)
+			.set(CompilerOptions.UnusedDeclaredThrownException)
+			.set(CompilerOptions.UnusedLabel)
+			.set(CompilerOptions.UnusedImport)
+			.set(CompilerOptions.UnusedTypeArguments)
+			.set(CompilerOptions.RedundantSuperinterface)
+			.set(CompilerOptions.DeadCode)
+			.set(CompilerOptions.UnusedObjectAllocation)
+			.set(CompilerOptions.UnusedTypeParameter)
+			.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
+		STATIC_METHOD
+		    .set(CompilerOptions.MethodCanBePotentiallyStatic);
+		RESOURCE
+			.set(CompilerOptions.PotentiallyUnclosedCloseable)
+			.set(CompilerOptions.ExplicitlyClosedAutoCloseable);
+		INCOMPLETE_SWITCH.set(CompilerOptions.MissingDefaultCase);
+		String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
+		if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
+			UNCHECKED.set(CompilerOptions.RawTypeReference);
+		}
+		
+		JAVADOC
+			.set(CompilerOptions.MissingJavadocComments)
+			.set(CompilerOptions.MissingJavadocTags);
+	}
+
+	// Internal state
+	private int[] bits = new int[GROUP_MAX];
+
+	/**
+	 * Constructor with initial irritant set
+	 */
+	public IrritantSet(int singleGroupIrritants) {
+		initialize(singleGroupIrritants);
+	}
+
+	/**
+	 * Constructor with initial irritant set
+	 */
+	public IrritantSet(IrritantSet other) {
+		initialize(other);
+	}
+
+	public boolean areAllSet() {
+		for (int i = 0; i < GROUP_MAX; i++) {
+			if (this.bits[i] != (0xFFFFFFFF & ~GROUP_MASK))
+				return false;
+		}
+		return true;
+	}
+
+	public IrritantSet clear(int singleGroupIrritants) {
+		int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
+		this.bits[group] &= ~singleGroupIrritants;
+		return this;
+	}
+
+	public IrritantSet clearAll() {
+		for (int i = 0; i < GROUP_MAX; i++) {
+			this.bits[i] = 0;
+		}
+		return this;
+	}
+
+	/**
+	 * Initialize a set of irritants in one group
+	 * 
+	 * @param singleGroupIrritants
+	 */
+	public void initialize(int singleGroupIrritants) {
+		if (singleGroupIrritants == 0)
+			return;
+		int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
+		this.bits[group] = singleGroupIrritants & ~GROUP_MASK; // erase group information
+	}
+
+	public void initialize(IrritantSet other) {
+		if (other == null)
+			return;
+		System.arraycopy(other.bits, 0, this.bits = new int[GROUP_MAX], 0, GROUP_MAX);
+	}
+
+	/**
+	 * Returns true if any of the irritants in given other set is positionned in receiver
+	 * @param other
+	 */
+	public boolean isAnySet(IrritantSet other) {
+		if (other == null)
+			return false;
+		for (int i = 0; i < GROUP_MAX; i++) {
+			if ((this.bits[i] & other.bits[i]) != 0)
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns true if all of the irritants in the given irritant set are set in receiver
+	 * @param irritantSet the given irritant set
+	 */
+	public boolean hasSameIrritants(IrritantSet irritantSet) {
+		if (irritantSet == null)
+			return false;
+		for (int i = 0; i < GROUP_MAX; i++) {
+			if (this.bits[i] != irritantSet.bits[i])
+				return false;
+		}
+		return true;
+	}
+
+	public boolean isSet(int singleGroupIrritants) {
+		int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
+		return (this.bits[group] & singleGroupIrritants) != 0;
+	}
+
+	public IrritantSet set(int singleGroupIrritants) {
+		int group = (singleGroupIrritants & GROUP_MASK) >> GROUP_SHIFT;
+		this.bits[group] |= (singleGroupIrritants & ~GROUP_MASK); // erase the group bits
+		return this;
+	}
+
+	/**
+	 * Return updated irritantSet or null if it was a no-op
+	 * 
+	 * @param other
+	 */
+	public IrritantSet set(IrritantSet other) {
+		if (other == null)
+			return this;
+		boolean wasNoOp = true;
+		for (int i = 0; i < GROUP_MAX; i++) {
+			int otherIrritant = other.bits[i] & ~GROUP_MASK; // erase the
+																	// group
+																	// bits
+			if ((this.bits[i] & otherIrritant) != otherIrritant) {
+				wasNoOp = false;
+				this.bits[i] |= otherIrritant;
+			}
+		}
+		return wasNoOp ? null : this;
+	}
+	
+	public IrritantSet setAll() {
+		for (int i = 0; i < GROUP_MAX; i++) {
+			this.bits[i] |= 0xFFFFFFFF & ~GROUP_MASK; // erase the group
+															// bits;
+		}
+		return this;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java
new file mode 100644
index 0000000..99f9f8e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class LongConstant extends Constant {
+
+		private static final LongConstant ZERO = new LongConstant(0L);
+		private static final LongConstant MIN_VALUE = new LongConstant(Long.MIN_VALUE);
+		
+		private long value;
+
+public static Constant fromValue(long value) {
+	if (value == 0L) {
+		return ZERO;
+	} else if (value == Long.MIN_VALUE) {
+		return MIN_VALUE;
+	}
+	return new LongConstant(value);
+}
+
+private LongConstant(long value) {
+	this.value = value;
+}
+
+public byte byteValue() {
+	return (byte) this.value;
+}
+
+public char charValue() {
+	return (char) this.value;
+}
+
+public double doubleValue() {
+	return this.value; // implicit cast to return type
+}
+
+public float floatValue() {
+	return this.value; // implicit cast to return type
+}
+
+public int intValue() {
+	return (int) this.value;
+}
+
+public long longValue() {
+	return this.value;
+}
+
+public short shortValue() {
+	return (short) this.value;
+}
+
+public String stringValue() {
+	//spec 15.17.11
+	return String.valueOf(this.value);
+}
+
+public String toString(){
+
+	return "(long)" + this.value ; //$NON-NLS-1$
+}
+
+public int typeID() {
+	return T_long;
+}
+
+public int hashCode() {
+	return (int) (this.value ^ (this.value >>> 32));
+}
+
+public boolean equals(Object obj) {
+	if (this == obj) {
+		return true;
+	}
+	if (obj == null) {
+		return false;
+	}
+	if (getClass() != obj.getClass()) {
+		return false;
+	}
+	LongConstant other = (LongConstant) obj;
+	return this.value == other.value;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
new file mode 100644
index 0000000..3f3f037
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+/*
+ * Implementors are valid compilation contexts from which we can
+ * escape in case of error:
+ * For example: method, type, compilation unit or a lambda expression.
+ */
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+
+public interface ReferenceContext {
+
+	void abort(int abortLevel, CategorizedProblem problem);
+
+	CompilationResult compilationResult();
+
+	CompilationUnitDeclaration getCompilationUnitDeclaration();
+
+	boolean hasErrors();
+
+	void tagAsHavingErrors();
+	
+	void tagAsHavingIgnoredMandatoryErrors(int problemId);
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java
new file mode 100644
index 0000000..6f107ae
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class ShortConstant extends Constant {
+	
+	private short value;
+
+	public static Constant fromValue(short value) {
+		return new ShortConstant(value);
+	}
+
+	private ShortConstant(short value) {
+		this.value = value;
+	}
+
+	public byte byteValue() {
+		return (byte) this.value;
+	}
+
+	public char charValue() {
+		return (char) this.value;
+	}
+
+	public double doubleValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public float floatValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public int intValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public long longValue() {
+		return this.value; // implicit cast to return type
+	}
+
+	public short shortValue() {
+		return this.value;
+	}
+
+	public String stringValue() {
+		// spec 15.17.11
+		return String.valueOf(this.value);
+	}
+
+	public String toString() {
+
+		return "(short)" + this.value; //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_short;
+	}
+
+	public int hashCode() {
+		return this.value;
+	}
+
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		ShortConstant other = (ShortConstant) obj;
+		return this.value == other.value;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java
new file mode 100644
index 0000000..37d493f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.impl;
+
+public class StringConstant extends Constant {
+
+	private String value;
+
+	public static Constant fromValue(String value) {
+		return new StringConstant(value);
+	}
+
+	private StringConstant(String value) {
+		this.value = value;
+	}
+
+	public String stringValue() {
+		// spec 15.17.11
+
+		// the next line do not go into the toString() send....!
+		return this.value;
+		/*
+		 * String s = value.toString() ; if (s == null) return "null"; else return s;
+		 */
+	}
+
+	public String toString() {
+		return "(String)\"" + this.value + "\""; //$NON-NLS-2$ //$NON-NLS-1$
+	}
+
+	public int typeID() {
+		return T_JavaLangString;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		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;
+		}
+		StringConstant other = (StringConstant) obj;
+		if (this.value == null) {
+			return other.value == null;
+		} else {
+			return this.value.equals(other.value);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
new file mode 100644
index 0000000..038c5ad
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+
+/**
+ * Represents JSR 175 Annotation instances in the type-system.
+ */
+public class AnnotationBinding {
+	// do not access directly - use getters instead (UnresolvedAnnotationBinding
+	// resolves types for type and pair contents just in time)
+	ReferenceBinding type;
+	ElementValuePair[] pairs;
+
+/**
+ * Add the standard annotations encoded in the tag bits to the recorded annotations.
+ *
+ * @param recordedAnnotations existing annotations already created
+ * @param annotationTagBits
+ * @param env
+ * @return the combined list of annotations
+ */
+public static AnnotationBinding[] addStandardAnnotations(AnnotationBinding[] recordedAnnotations, long annotationTagBits, LookupEnvironment env) {
+	// NOTE: expect annotations to be requested just once so there is no need to store the standard annotations
+	// and all of the standard annotations created by this method are fully resolved since the sender is expected to use them immediately
+	if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) {
+		return recordedAnnotations;
+	}
+	int count = 0;
+	if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
+		count++;
+	if (count == 0) {
+		// this is possible if bits were set for null annotations
+		return recordedAnnotations;
+	}
+
+	int index = recordedAnnotations.length;
+	AnnotationBinding[] result = new AnnotationBinding[index + count];
+	System.arraycopy(recordedAnnotations, 0, result, 0, index);
+	if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0)
+		result[index++] = buildTargetAnnotation(annotationTagBits, env);
+	if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0)
+		result[index++] = buildRetentionAnnotation(annotationTagBits, env);
+	if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_DEPRECATED, env);
+	if ((annotationTagBits & TagBits.AnnotationDocumented) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, env);
+	if ((annotationTagBits & TagBits.AnnotationInherited) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, env);
+	if ((annotationTagBits & TagBits.AnnotationOverride) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, env);
+	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, env);
+	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
+		result[index++] = buildMarkerAnnotationForMemberType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, env);
+	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS, env);
+	return result;
+}
+
+private static AnnotationBinding buildMarkerAnnotationForMemberType(char[][] compoundName, LookupEnvironment env) {
+	ReferenceBinding type = env.getResolvedType(compoundName, null);
+	// since this is a member type name using '$' the return binding is a
+	// problem reference binding with reason ProblemReasons.InternalNameProvided
+	if (!type.isValidBinding()) {
+		type = ((ProblemReferenceBinding) type).closestMatch;
+	}
+	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
+}
+
+private static AnnotationBinding buildMarkerAnnotation(char[][] compoundName, LookupEnvironment env) {
+	ReferenceBinding type = env.getResolvedType(compoundName, null);
+	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
+}
+
+private static AnnotationBinding buildRetentionAnnotation(long bits, LookupEnvironment env) {
+	ReferenceBinding retentionPolicy =
+		env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY,
+			null);
+	Object value = null;
+	if ((bits & TagBits.AnnotationRuntimeRetention) == TagBits.AnnotationRuntimeRetention) {
+		value = retentionPolicy.getField(TypeConstants.UPPER_RUNTIME, true);
+	} else if ((bits & TagBits.AnnotationClassRetention) != 0) {
+		value = retentionPolicy.getField(TypeConstants.UPPER_CLASS, true);
+	} else if ((bits & TagBits.AnnotationSourceRetention) != 0) {
+		value = retentionPolicy.getField(TypeConstants.UPPER_SOURCE, true);
+	}
+	return env.createAnnotation(
+		env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, null),
+		new ElementValuePair[] {
+			new ElementValuePair(TypeConstants.VALUE, value, null)
+		});
+}
+
+private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironment env) {
+	ReferenceBinding target = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_TARGET, null);
+	if ((bits & TagBits.AnnotationTarget) != 0)
+		return new AnnotationBinding(target, Binding.NO_ELEMENT_VALUE_PAIRS);
+
+	int arraysize = 0;
+	if ((bits & TagBits.AnnotationForAnnotationType) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForConstructor) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForField) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForLocalVariable) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForMethod) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForPackage) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForParameter) != 0)
+		arraysize++;
+	if ((bits & TagBits.AnnotationForType) != 0)
+		arraysize++;
+	Object[] value = new Object[arraysize];
+	if (arraysize > 0) {
+		ReferenceBinding elementType = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, null);
+		int index = 0;
+		if ((bits & TagBits.AnnotationForAnnotationType) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_ANNOTATION_TYPE, true);
+		if ((bits & TagBits.AnnotationForConstructor) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_CONSTRUCTOR, true);
+		if ((bits & TagBits.AnnotationForField) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_FIELD, true);
+		if ((bits & TagBits.AnnotationForLocalVariable) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_LOCAL_VARIABLE, true);
+		if ((bits & TagBits.AnnotationForMethod) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_METHOD, true);
+		if ((bits & TagBits.AnnotationForPackage) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_PACKAGE, true);
+		if ((bits & TagBits.AnnotationForParameter) != 0)
+			value[index++] = elementType.getField(TypeConstants.UPPER_PARAMETER, true);
+		if ((bits & TagBits.AnnotationForType) != 0)
+			value[index++] = elementType.getField(TypeConstants.TYPE, true);
+	}
+	return env.createAnnotation(
+			target,
+			new ElementValuePair[] {
+				new ElementValuePair(TypeConstants.VALUE, value, null)
+			});
+}
+
+AnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs) {
+	this.type = type;
+	this.pairs = pairs;
+}
+
+AnnotationBinding(Annotation astAnnotation) {
+	this((ReferenceBinding) astAnnotation.resolvedType, astAnnotation.computeElementValuePairs());
+}
+
+/*
+ * Computes a key that uniquely identifies this binding, using the given recipient's unique key.
+ * recipientKey @ typeKey
+ * @MyAnnot void bar() --> Lp/X;.bar()V@Lp/MyAnnot;
+ */
+public char[] computeUniqueKey(char[] recipientKey) {
+	char[] typeKey = this.type.computeUniqueKey(false);
+	int recipientKeyLength = recipientKey.length;
+	char[] uniqueKey = new char[recipientKeyLength+1+typeKey.length];
+	System.arraycopy(recipientKey, 0, uniqueKey, 0, recipientKeyLength);
+	uniqueKey[recipientKeyLength] = '@';
+	System.arraycopy(typeKey, 0, uniqueKey, recipientKeyLength+1, typeKey.length);
+	return uniqueKey;
+}
+
+public ReferenceBinding getAnnotationType() {
+	return this.type;
+}
+
+public ElementValuePair[] getElementValuePairs() {
+	return this.pairs;
+}
+
+public static void setMethodBindings(ReferenceBinding type, ElementValuePair[] pairs) {
+	// set the method bindings of each element value pair
+	for (int i = pairs.length; --i >= 0;) {
+		ElementValuePair pair = pairs[i];
+		MethodBinding[] methods = type.getMethods(pair.getName());
+		// there should be exactly one since the type is an annotation type.
+		if (methods != null && methods.length == 1)
+			pair.setMethodBinding(methods[0]);
+	}
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer(5);
+	buffer.append('@').append(this.type.sourceName);
+	if (this.pairs != null && this.pairs.length > 0) {
+		buffer.append("{ "); //$NON-NLS-1$
+		for (int i = 0, max = this.pairs.length; i < max; i++) {
+			if (i > 0) buffer.append(", "); //$NON-NLS-1$
+			buffer.append(this.pairs[i]);
+		}
+		buffer.append('}');
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder.java
new file mode 100644
index 0000000..56f8d96
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class AnnotationHolder {
+	AnnotationBinding[] annotations;
+
+static AnnotationHolder storeAnnotations(AnnotationBinding[] annotations, AnnotationBinding[][] parameterAnnotations, Object defaultValue, LookupEnvironment optionalEnv) {
+	if (parameterAnnotations != null) {
+		boolean isEmpty = true;
+		for (int i = parameterAnnotations.length; isEmpty && --i >= 0;)
+			if (parameterAnnotations[i] != null && parameterAnnotations[i].length > 0)
+				isEmpty = false;
+		if (isEmpty)
+			parameterAnnotations = null; // does not have any
+	}
+
+	if (defaultValue != null)
+		return new AnnotationMethodHolder(annotations, parameterAnnotations, defaultValue, optionalEnv);
+	if (parameterAnnotations != null)
+		return new MethodHolder(annotations, parameterAnnotations);
+	return new AnnotationHolder().setAnnotations(annotations);
+}
+
+AnnotationBinding[] getAnnotations() {
+	return this.annotations;
+}
+Object getDefaultValue() {
+	return null;
+}
+public AnnotationBinding[][] getParameterAnnotations() {
+	return null;
+}
+AnnotationBinding[] getParameterAnnotations(int paramIndex) {
+	return Binding.NO_ANNOTATIONS;
+}
+AnnotationHolder setAnnotations(AnnotationBinding[] annotations) {
+	if (annotations == null || annotations.length == 0)
+		return null; // no longer needed
+
+	this.annotations = annotations;
+	return this;
+}
+
+static class MethodHolder extends AnnotationHolder {
+	AnnotationBinding[][] parameterAnnotations; // is null if empty
+
+MethodHolder(AnnotationBinding[] annotations, AnnotationBinding[][] parameterAnnotations) {
+	super();
+	setAnnotations(annotations);
+	this.parameterAnnotations = parameterAnnotations;
+}
+public AnnotationBinding[][] getParameterAnnotations() {
+	return this.parameterAnnotations;
+}
+AnnotationBinding[] getParameterAnnotations(int paramIndex) {
+	AnnotationBinding[] result = this.parameterAnnotations == null ? null : this.parameterAnnotations[paramIndex];
+	return result == null ? Binding.NO_ANNOTATIONS : result;
+}
+AnnotationHolder setAnnotations(AnnotationBinding[] annotations) {
+	this.annotations = annotations == null || annotations.length == 0 ? Binding.NO_ANNOTATIONS : annotations;
+	return this;
+}
+}
+
+static class AnnotationMethodHolder extends MethodHolder {
+	Object defaultValue;
+	LookupEnvironment env;
+
+AnnotationMethodHolder(AnnotationBinding[] annotations, AnnotationBinding[][] parameterAnnotations, Object defaultValue, LookupEnvironment optionalEnv) {
+	super(annotations, parameterAnnotations);
+	this.defaultValue = defaultValue;
+	this.env = optionalEnv;
+}
+Object getDefaultValue() {
+	if (this.defaultValue instanceof UnresolvedReferenceBinding) {
+		if (this.env == null)
+			throw new IllegalStateException();
+		this.defaultValue = ((UnresolvedReferenceBinding) this.defaultValue).resolve(this.env, false);
+	}
+	return this.defaultValue;
+}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
new file mode 100644
index 0000000..3034e79
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public final class ArrayBinding extends TypeBinding {
+	// creation and initialization of the length field
+	// the declaringClass of this field is intentionally set to null so it can be distinguished.
+	public static final FieldBinding ArrayLength = new FieldBinding(TypeConstants.LENGTH, TypeBinding.INT, ClassFileConstants.AccPublic | ClassFileConstants.AccFinal, null, Constant.NotAConstant);
+
+	public TypeBinding leafComponentType;
+	public int dimensions;
+	LookupEnvironment environment;
+	char[] constantPoolName;
+	char[] genericTypeSignature;
+
+	// One bitset for each dimension plus one more for the leaf component type at position 'dimensions',
+	// possible bits are TagBits.AnnotationNonNull and TagBits.AnnotationNullable
+	// (only ever set when CompilerOptions.isAnnotationBasedNullAnalysisEnabled == true):
+	public long[] nullTagBitsPerDimension;
+
+public ArrayBinding(TypeBinding type, int dimensions, LookupEnvironment environment) {
+	this(type, dimensions, environment, null);
+}
+public ArrayBinding(TypeBinding type, int dimensions, LookupEnvironment environment, long[] nullTagBitsPerDimension) {
+	this.tagBits |= TagBits.IsArrayType;
+	this.leafComponentType = type;
+	this.dimensions = dimensions;
+	this.environment = environment;
+	if (type instanceof UnresolvedReferenceBinding)
+		((UnresolvedReferenceBinding) type).addWrapper(this, environment);
+	else
+		this.tagBits |= type.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences);
+	
+	if (nullTagBitsPerDimension != null) {
+		this.tagBits |= nullTagBitsPerDimension[0]; // outer-most dimension
+		this.nullTagBitsPerDimension = nullTagBitsPerDimension;
+	}
+}
+
+public TypeBinding closestMatch() {
+	if (isValidBinding()) {
+		return this;
+	}
+	TypeBinding leafClosestMatch = this.leafComponentType.closestMatch();
+	if (leafClosestMatch == null) {
+		return null;
+	}
+	return this.environment.createArrayType(this.leafComponentType.closestMatch(), this.dimensions);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#collectMissingTypes(java.util.List)
+ */
+public List collectMissingTypes(List missingTypes) {
+	if ((this.tagBits & TagBits.HasMissingType) != 0) {
+		missingTypes = this.leafComponentType.collectMissingTypes(missingTypes);
+	}
+	return missingTypes;
+}
+
+/**
+ * Collect the substitutes into a map for certain type variables inside the receiver type
+ * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
+ * Constraints:
+ *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
+ *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
+ *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
+*/
+public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
+
+	if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
+	if (actualType == TypeBinding.NULL || actualType.kind() == POLY_TYPE) return;
+
+	switch(actualType.kind()) {
+		case Binding.ARRAY_TYPE :
+	        int actualDim = actualType.dimensions();
+	        if (actualDim == this.dimensions) {
+			    this.leafComponentType.collectSubstitutes(scope, actualType.leafComponentType(), inferenceContext, constraint);
+	        } else if (actualDim > this.dimensions) {
+	            ArrayBinding actualReducedType = this.environment.createArrayType(actualType.leafComponentType(), actualDim - this.dimensions);
+	            this.leafComponentType.collectSubstitutes(scope, actualReducedType, inferenceContext, constraint);
+	        }
+			break;
+		case Binding.TYPE_PARAMETER :
+			//TypeVariableBinding variable = (TypeVariableBinding) otherType;
+			// TODO (philippe) should consider array bounds, and recurse
+			break;
+	}
+}
+
+/*
+ * brakets leafUniqueKey
+ * p.X[][] --> [[Lp/X;
+ */
+public char[] computeUniqueKey(boolean isLeaf) {
+	char[] brackets = new char[this.dimensions];
+	for (int i = this.dimensions - 1; i >= 0; i--) brackets[i] = '[';
+	return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey(isLeaf));
+ }
+
+/**
+ * Answer the receiver's constant pool name.
+ * NOTE: This method should only be used during/after code gen.
+ * e.g. '[Ljava/lang/Object;'
+ */
+public char[] constantPoolName() {
+	if (this.constantPoolName != null)
+		return this.constantPoolName;
+
+	char[] brackets = new char[this.dimensions];
+	for (int i = this.dimensions - 1; i >= 0; i--) brackets[i] = '[';
+	return this.constantPoolName = CharOperation.concat(brackets, this.leafComponentType.signature());
+}
+public String debugName() {
+	StringBuffer brackets = new StringBuffer(this.dimensions * 2);
+	for (int i = this.dimensions; --i >= 0;)
+		brackets.append("[]"); //$NON-NLS-1$
+	return this.leafComponentType.debugName() + brackets.toString();
+}
+public int dimensions() {
+	return this.dimensions;
+}
+
+/* Answer an array whose dimension size is one less than the receiver.
+*
+* When the receiver's dimension size is one then answer the leaf component type.
+*/
+
+public TypeBinding elementsType() {
+	long[] nullTagBitsSub = null;
+	if (this.nullTagBitsPerDimension != null) {
+		int len = this.nullTagBitsPerDimension.length-1;
+		System.arraycopy(this.nullTagBitsPerDimension, 1, nullTagBitsSub = new long[len], 0, len);
+	}
+	if (this.dimensions == 1) {
+		if (nullTagBitsSub != null && nullTagBitsSub[0] != 0L && this.leafComponentType instanceof ReferenceBinding)
+			return this.environment.createParameterizedType((ReferenceBinding) this.leafComponentType, null, nullTagBitsSub[0], null);
+		return this.leafComponentType;
+	}
+	return this.environment.createArrayType(this.leafComponentType, this.dimensions - 1, nullTagBitsSub);
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
+ */
+public TypeBinding erasure() {
+    TypeBinding erasedType = this.leafComponentType.erasure();
+    if (this.leafComponentType != erasedType)
+        return this.environment.createArrayType(erasedType, this.dimensions);
+    return this;
+}
+public LookupEnvironment environment() {
+    return this.environment;
+}
+
+public char[] genericTypeSignature() {
+
+    if (this.genericTypeSignature == null) {
+		char[] brackets = new char[this.dimensions];
+		for (int i = this.dimensions - 1; i >= 0; i--) brackets[i] = '[';
+		this.genericTypeSignature = CharOperation.concat(brackets, this.leafComponentType.genericTypeSignature());
+    }
+    return this.genericTypeSignature;
+}
+
+public PackageBinding getPackage() {
+	return this.leafComponentType.getPackage();
+}
+
+public int hashCode() {
+	return this.leafComponentType == null ? super.hashCode() : this.leafComponentType.hashCode();
+}
+
+/* Answer true if the receiver type can be assigned to the argument type (right)
+*/
+public boolean isCompatibleWith(TypeBinding otherType, Scope captureScope) {
+	if (this == otherType)
+		return true;
+
+	switch (otherType.kind()) {
+		case Binding.ARRAY_TYPE :
+			ArrayBinding otherArray = (ArrayBinding) otherType;
+			if (otherArray.leafComponentType.isBaseType())
+				return false; // relying on the fact that all equal arrays are identical
+			if (this.dimensions == otherArray.dimensions)
+				return this.leafComponentType.isCompatibleWith(otherArray.leafComponentType);
+			if (this.dimensions < otherArray.dimensions)
+				return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
+			break;
+		case Binding.BASE_TYPE :
+			return false;
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+		    return ((WildcardBinding) otherType).boundCheck(this);
+
+		case Binding.TYPE_PARAMETER :
+			// check compatibility with capture of ? super X
+			if (otherType.isCapture()) {
+				CaptureBinding otherCapture = (CaptureBinding) otherType;
+				TypeBinding otherLowerBound;
+				if ((otherLowerBound = otherCapture.lowerBound) != null) {
+					if (!otherLowerBound.isArrayType()) return false;
+					return isCompatibleWith(otherLowerBound, captureScope);
+				}
+			}
+			return false;
+
+	}
+	//Check dimensions - Java does not support explicitly sized dimensions for types.
+	//However, if it did, the type checking support would go here.
+	switch (otherType.leafComponentType().id) {
+	    case TypeIds.T_JavaLangObject :
+	    case TypeIds.T_JavaLangCloneable :
+	    case TypeIds.T_JavaIoSerializable :
+	        return true;
+	}
+	return false;
+}
+
+public int kind() {
+	return ARRAY_TYPE;
+}
+
+public TypeBinding leafComponentType(){
+	return this.leafComponentType;
+}
+
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* java.lang.Object @o.e.j.a.NonNull[] */ {
+	if (this.nullTagBitsPerDimension == null)
+		return shortNames ? shortReadableName() : readableName();
+	char[][] brackets = new char[this.dimensions][];
+	for (int i = 0; i < this.dimensions; i++) {
+		if ((this.nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK) != 0) {
+			char[][] fqAnnotationName;
+			if ((this.nullTagBitsPerDimension[i] & TagBits.AnnotationNonNull) != 0)
+				fqAnnotationName = env.getNonNullAnnotationName();
+			else
+				fqAnnotationName = env.getNullableAnnotationName();
+			char[] annotationName = shortNames 
+										? fqAnnotationName[fqAnnotationName.length-1] 
+										: CharOperation.concatWith(fqAnnotationName, '.');
+			brackets[i] = new char[annotationName.length+3];
+			brackets[i][0] = '@';
+			System.arraycopy(annotationName, 0, brackets[i], 1, annotationName.length);
+			brackets[i][annotationName.length+1] = '[';
+			brackets[i][annotationName.length+2] = ']';
+		} else {
+			brackets[i] = new char[]{'[', ']'}; 
+		}
+	}
+	char[] leafTypeName = shortNames ? this.leafComponentType.shortReadableName() : this.leafComponentType.readableName();
+	return CharOperation.concat(leafTypeName, 
+								 CharOperation.concatWith(brackets, ' '),
+								 ' ');
+}
+
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+public int problemId() {
+	return this.leafComponentType.problemId();
+}
+/**
+* Answer the source name for the type.
+* In the case of member types, as the qualified name from its top level type.
+* For example, for a member type N defined inside M & A: "A.M.N".
+*/
+
+public char[] qualifiedSourceName() {
+	char[] brackets = new char[this.dimensions * 2];
+	for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+		brackets[i] = ']';
+		brackets[i - 1] = '[';
+	}
+	return CharOperation.concat(this.leafComponentType.qualifiedSourceName(), brackets);
+}
+public char[] readableName() /* java.lang.Object[] */ {
+	char[] brackets = new char[this.dimensions * 2];
+	for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+		brackets[i] = ']';
+		brackets[i - 1] = '[';
+	}
+	return CharOperation.concat(this.leafComponentType.readableName(), brackets);
+}
+public char[] shortReadableName(){
+	char[] brackets = new char[this.dimensions * 2];
+	for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+		brackets[i] = ']';
+		brackets[i - 1] = '[';
+	}
+	return CharOperation.concat(this.leafComponentType.shortReadableName(), brackets);
+}
+public char[] sourceName() {
+	char[] brackets = new char[this.dimensions * 2];
+	for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+		brackets[i] = ']';
+		brackets[i - 1] = '[';
+	}
+	return CharOperation.concat(this.leafComponentType.sourceName(), brackets);
+}
+public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
+	if (this.leafComponentType == unresolvedType) {
+		this.leafComponentType = env.convertUnresolvedBinaryToRawType(resolvedType);
+		this.tagBits |= this.leafComponentType.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType);
+	}
+}
+public String toString() {
+	return this.leafComponentType != null ? debugName() : "NULL TYPE ARRAY"; //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
new file mode 100644
index 0000000..65826fe
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public final class BaseTypeBinding extends TypeBinding {
+
+	public static final int[] CONVERSIONS;
+	public static final int IDENTITY = 1;
+	public static final int WIDENING = 2;
+	public static final int NARROWING = 4;
+	public static final int MAX_CONVERSIONS = 16*16; // well-known x well-known
+	
+	static {
+		CONVERSIONS	 = initializeConversions();
+	}
+	
+	public static final int[] initializeConversions(){
+		// fromType   destType --> conversion
+		//  0000   0000       				0000
+
+		int[] table  = new int[MAX_CONVERSIONS];
+		
+		table[TypeIds.Boolean2Boolean] = IDENTITY;
+
+		table[TypeIds.Byte2Byte] 		= IDENTITY;
+		table[TypeIds.Byte2Short] 		= WIDENING;
+		table[TypeIds.Byte2Char] 		= NARROWING;
+		table[TypeIds.Byte2Int] 			= WIDENING;
+		table[TypeIds.Byte2Long] 		= WIDENING;
+		table[TypeIds.Byte2Float] 		= WIDENING;
+		table[TypeIds.Byte2Double] 	= WIDENING;
+
+		table[TypeIds.Short2Byte] 		= NARROWING;
+		table[TypeIds.Short2Short] 		= IDENTITY;
+		table[TypeIds.Short2Char] 		= NARROWING;
+		table[TypeIds.Short2Int] 			= WIDENING;
+		table[TypeIds.Short2Long] 		= WIDENING;
+		table[TypeIds.Short2Float]	 	= WIDENING;
+		table[TypeIds.Short2Double] 	= WIDENING;
+
+		table[TypeIds.Char2Byte] 		= NARROWING;
+		table[TypeIds.Char2Short] 		= NARROWING;
+		table[TypeIds.Char2Char] 		= IDENTITY;
+		table[TypeIds.Char2Int] 			= WIDENING;
+		table[TypeIds.Char2Long] 		= WIDENING;
+		table[TypeIds.Char2Float] 		= WIDENING;
+		table[TypeIds.Char2Double] 	= WIDENING;
+
+		table[TypeIds.Int2Byte] 			= NARROWING;
+		table[TypeIds.Int2Short] 			= NARROWING;
+		table[TypeIds.Int2Char] 			= NARROWING;
+		table[TypeIds.Int2Int] 				= IDENTITY;
+		table[TypeIds.Int2Long] 			= WIDENING;
+		table[TypeIds.Int2Float] 			= WIDENING;
+		table[TypeIds.Int2Double] 		= WIDENING;
+
+		table[TypeIds.Long2Byte] 		= NARROWING;
+		table[TypeIds.Long2Short] 		= NARROWING;
+		table[TypeIds.Long2Char] 		= NARROWING;
+		table[TypeIds.Long2Int] 			= NARROWING;
+		table[TypeIds.Long2Long] 		= IDENTITY;
+		table[TypeIds.Long2Float] 		= WIDENING;
+		table[TypeIds.Long2Double] 	= WIDENING;
+
+		table[TypeIds.Float2Byte] 		= NARROWING;
+		table[TypeIds.Float2Short] 		= NARROWING;
+		table[TypeIds.Float2Char] 		= NARROWING;
+		table[TypeIds.Float2Int] 			= NARROWING;
+		table[TypeIds.Float2Long] 		= NARROWING;
+		table[TypeIds.Float2Float] 		= IDENTITY;
+		table[TypeIds.Float2Double] 	= WIDENING;
+
+		table[TypeIds.Double2Byte] 	= NARROWING;
+		table[TypeIds.Double2Short] 	= NARROWING;
+		table[TypeIds.Double2Char] 	= NARROWING;
+		table[TypeIds.Double2Int] 		= NARROWING;
+		table[TypeIds.Double2Long] 	= NARROWING;
+		table[TypeIds.Double2Float] 	= NARROWING;
+		table[TypeIds.Double2Double]= IDENTITY;
+		
+		return table;
+	}
+	/**
+	 * Predicate telling whether "left" can store a "right" using some narrowing conversion
+	 *(is left smaller than right)
+	 * @param left - the target type to convert to
+	 * @param right - the actual type
+	 * @return true if legal narrowing conversion
+	 */
+	public static final boolean isNarrowing(int left, int right) {
+		int right2left = right + (left<<4);
+		return right2left >= 0 
+						&& right2left < MAX_CONVERSIONS 
+						&& (CONVERSIONS[right2left] & (IDENTITY|NARROWING)) != 0;
+	}
+
+	/**
+	 * Predicate telling whether "left" can store a "right" using some widening conversion
+	 *(is left bigger than right)
+	 * @param left - the target type to convert to
+	 * @param right - the actual type
+	 * @return true if legal widening conversion
+	 */
+	public static final boolean isWidening(int left, int right) {
+		int right2left = right + (left<<4);
+		return right2left >= 0 
+						&& right2left < MAX_CONVERSIONS 
+						&& (CONVERSIONS[right2left] & (IDENTITY|WIDENING)) != 0;
+	}
+	
+	public char[] simpleName;
+
+	private char[] constantPoolName;
+
+	BaseTypeBinding(int id, char[] name, char[] constantPoolName) {
+		this.tagBits |= TagBits.IsBaseType;
+		this.id = id;
+		this.simpleName = name;
+		this.constantPoolName = constantPoolName;
+	}
+
+	/**
+	 * int -> I
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		return constantPoolName();
+	}
+
+	/* Answer the receiver's constant pool name.
+	*/
+	public char[] constantPoolName() {
+
+		return this.constantPoolName;
+	}
+
+	public PackageBinding getPackage() {
+
+		return null;
+	}
+	
+	/* Answer true if the receiver type can be assigned to the argument type (right)
+	*/
+	public final boolean isCompatibleWith(TypeBinding right, Scope captureScope) {
+		if (this == right)
+			return true;
+		int right2left = this.id + (right.id<<4);
+		if (right2left >= 0 
+				&& right2left < MAX_CONVERSIONS 
+				&& (CONVERSIONS[right2left] & (IDENTITY|WIDENING)) != 0)
+			return true;
+		return this == TypeBinding.NULL && !right.isBaseType();
+	}
+	
+	/**
+	 * T_null is acting as an unchecked exception
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
+	 */
+	public boolean isUncheckedException(boolean includeSupertype) {
+		return this == TypeBinding.NULL;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#kind()
+	 */
+	public int kind() {
+		return Binding.BASE_TYPE;
+	}
+	public char[] qualifiedSourceName() {
+		return this.simpleName;
+	}
+
+	public char[] readableName() {
+		return this.simpleName;
+	}
+
+	public char[] shortReadableName() {
+		return this.simpleName;
+	}
+
+	public char[] sourceName() {
+		return this.simpleName;
+	}
+
+	public String toString() {
+		return new String(this.constantPoolName) + " (id=" + this.id + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
new file mode 100644
index 0000000..1f58b71
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -0,0 +1,1508 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 364890 - BinaryTypeBinding should use char constants from Util
+ *								bug 365387 - [compiler][null] bug 186342: Issues to follow up post review and verification.
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 388800 - [1.8][compiler] detect default methods in class files
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/*
+Not all fields defined by this type are initialized when it is created.
+Some are initialized only when needed.
+
+Accessors have been provided for some public fields so all TypeBindings have the same API...
+but access public fields directly whenever possible.
+Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
+
+null is NOT a valid value for a non-public field... it just means the field is not initialized.
+*/
+
+public class BinaryTypeBinding extends ReferenceBinding {
+
+	// all of these fields are ONLY guaranteed to be initialized if accessed using their public accessor method
+	protected ReferenceBinding superclass;
+	protected ReferenceBinding enclosingType;
+	protected ReferenceBinding[] superInterfaces;
+	protected FieldBinding[] fields;
+	protected MethodBinding[] methods;
+	protected ReferenceBinding[] memberTypes;
+	protected TypeVariableBinding[] typeVariables;
+
+	// For the link with the principle structure
+	protected LookupEnvironment environment;
+
+	protected SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
+
+static Object convertMemberValue(Object binaryValue, LookupEnvironment env, char[][][] missingTypeNames) {
+	if (binaryValue == null) return null;
+	if (binaryValue instanceof Constant)
+		return binaryValue;
+	if (binaryValue instanceof ClassSignature)
+		return env.getTypeFromSignature(((ClassSignature) binaryValue).getTypeName(), 0, -1, false, null, missingTypeNames);
+	if (binaryValue instanceof IBinaryAnnotation)
+		return createAnnotation((IBinaryAnnotation) binaryValue, env, missingTypeNames);
+	if (binaryValue instanceof EnumConstantSignature) {
+		EnumConstantSignature ref = (EnumConstantSignature) binaryValue;
+		ReferenceBinding enumType = (ReferenceBinding) env.getTypeFromSignature(ref.getTypeName(), 0, -1, false, null, missingTypeNames);
+		enumType = (ReferenceBinding) resolveType(enumType, env, false /* no raw conversion */);
+		return enumType.getField(ref.getEnumConstantName(), false);
+	}
+	if (binaryValue instanceof Object[]) {
+		Object[] objects = (Object[]) binaryValue;
+		int length = objects.length;
+		if (length == 0) return objects;
+		Object[] values = new Object[length];
+		for (int i = 0; i < length; i++)
+			values[i] = convertMemberValue(objects[i], env, missingTypeNames);
+		return values;
+	}
+
+	// should never reach here.
+	throw new IllegalStateException();
+}
+
+static AnnotationBinding createAnnotation(IBinaryAnnotation annotationInfo, LookupEnvironment env, char[][][] missingTypeNames) {
+	IBinaryElementValuePair[] binaryPairs = annotationInfo.getElementValuePairs();
+	int length = binaryPairs == null ? 0 : binaryPairs.length;
+	ElementValuePair[] pairs = length == 0 ? Binding.NO_ELEMENT_VALUE_PAIRS : new ElementValuePair[length];
+	for (int i = 0; i < length; i++)
+		pairs[i] = new ElementValuePair(binaryPairs[i].getName(), convertMemberValue(binaryPairs[i].getValue(), env, missingTypeNames), null);
+
+	char[] typeName = annotationInfo.getTypeName();
+	ReferenceBinding annotationType = env.getTypeFromConstantPoolName(typeName, 1, typeName.length - 1, false, missingTypeNames);
+	return new UnresolvedAnnotationBinding(annotationType, pairs, env);
+}
+
+public static AnnotationBinding[] createAnnotations(IBinaryAnnotation[] annotationInfos, LookupEnvironment env, char[][][] missingTypeNames) {
+	int length = annotationInfos == null ? 0 : annotationInfos.length;
+	AnnotationBinding[] result = length == 0 ? Binding.NO_ANNOTATIONS : new AnnotationBinding[length];
+	for (int i = 0; i < length; i++)
+		result[i] = createAnnotation(annotationInfos[i], env, missingTypeNames);
+	return result;
+}
+
+public static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, boolean convertGenericToRawType) {
+	switch (type.kind()) {
+		case Binding.PARAMETERIZED_TYPE :
+			((ParameterizedTypeBinding) type).resolve();
+			break;
+
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+			return ((WildcardBinding) type).resolve();
+
+		case Binding.ARRAY_TYPE :
+			resolveType(((ArrayBinding) type).leafComponentType, environment, convertGenericToRawType);
+			break;
+
+		case Binding.TYPE_PARAMETER :
+			((TypeVariableBinding) type).resolve();
+			break;
+
+		case Binding.GENERIC_TYPE :
+			if (convertGenericToRawType) // raw reference to generic ?
+				return environment.convertUnresolvedBinaryToRawType(type);
+			break;
+
+		default:
+			if (type instanceof UnresolvedReferenceBinding)
+				return ((UnresolvedReferenceBinding) type).resolve(environment, convertGenericToRawType);
+			if (convertGenericToRawType) // raw reference to generic ?
+				return environment.convertUnresolvedBinaryToRawType(type);
+			break;
+	}
+	return type;
+}
+
+/**
+ * Default empty constructor for subclasses only.
+ */
+protected BinaryTypeBinding() {
+	// only for subclasses
+}
+
+/**
+ * Standard constructor for creating binary type bindings from binary models (classfiles)
+ * @param packageBinding
+ * @param binaryType
+ * @param environment
+ */
+public BinaryTypeBinding(PackageBinding packageBinding, IBinaryType binaryType, LookupEnvironment environment) {
+	this.compoundName = CharOperation.splitOn('/', binaryType.getName());
+	computeId();
+
+	this.tagBits |= TagBits.IsBinaryBinding;
+	this.environment = environment;
+	this.fPackage = packageBinding;
+	this.fileName = binaryType.getFileName();
+
+	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
+	   must internalize type variables and observe any parameterization of super class
+	   and/or super interfaces in order to be able to detect overriding in the presence
+	   of generics.
+	 */
+	char[] typeSignature = binaryType.getGenericSignature();
+	this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == Util.C_GENERIC_START
+		? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
+		: Binding.NO_TYPE_VARIABLES;
+
+	this.sourceName = binaryType.getSourceName();
+	this.modifiers = binaryType.getModifiers();
+
+	if ((binaryType.getTagBits() & TagBits.HierarchyHasProblems) != 0)
+		this.tagBits |= TagBits.HierarchyHasProblems;
+
+	if (binaryType.isAnonymous()) {
+		this.tagBits |= TagBits.AnonymousTypeMask;
+	} else if (binaryType.isLocal()) {
+		this.tagBits |= TagBits.LocalTypeMask;
+	} else if (binaryType.isMember()) {
+		this.tagBits |= TagBits.MemberTypeMask;
+	}
+	// need enclosing type to access type variables
+	char[] enclosingTypeName = binaryType.getEnclosingTypeName();
+	if (enclosingTypeName != null) {
+		// attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
+		this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true, null /* could not be missing */); // pretend parameterized to avoid raw
+		this.tagBits |= TagBits.MemberTypeMask;   // must be a member type not a top-level or local type
+		this.tagBits |= TagBits.HasUnresolvedEnclosingType;
+		if (enclosingType().isStrictfp())
+			this.modifiers |= ClassFileConstants.AccStrictfp;
+		if (enclosingType().isDeprecated())
+			this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
+ */
+public FieldBinding[] availableFields() {
+	if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+		return this.fields;
+
+	// lazily sort fields
+	if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+		int length = this.fields.length;
+		if (length > 1)
+			ReferenceBinding.sortFields(this.fields, 0, length);
+		this.tagBits |= TagBits.AreFieldsSorted;
+	}
+	FieldBinding[] availableFields = new FieldBinding[this.fields.length];
+	int count = 0;
+	for (int i = 0; i < this.fields.length; i++) {
+		try {
+			availableFields[count] = resolveTypeFor(this.fields[i]);
+			count++;
+		} catch (AbortCompilation a){
+			// silent abort
+		}
+	}
+	if (count < availableFields.length)
+		System.arraycopy(availableFields, 0, availableFields = new FieldBinding[count], 0, count);
+	return availableFields;
+}
+
+private TypeVariableBinding[] addMethodTypeVariables(TypeVariableBinding[] methodTypeVars) {
+	if (this.typeVariables == null || this.typeVariables == Binding.NO_TYPE_VARIABLES) {
+		return methodTypeVars;
+	} 
+	if (methodTypeVars == null || methodTypeVars == Binding.NO_TYPE_VARIABLES) {
+		return this.typeVariables;
+	}
+	// uniq-merge both the arrays
+	int total = this.typeVariables.length + methodTypeVars.length;
+	TypeVariableBinding[] combinedTypeVars = new TypeVariableBinding[total];
+	System.arraycopy(this.typeVariables, 0, combinedTypeVars, 0, this.typeVariables.length);
+	int size = this.typeVariables.length;
+	loop: for (int i = 0, len = methodTypeVars.length; i < len; i++) {
+		for (int j = this.typeVariables.length -1 ; j >= 0; j--) {
+			if (CharOperation.equals(methodTypeVars[i].sourceName, this.typeVariables[j].sourceName))
+				continue loop;
+		}
+		combinedTypeVars[size++] = methodTypeVars[i];
+	}
+	if (size != total) {
+		System.arraycopy(combinedTypeVars, 0, combinedTypeVars = new TypeVariableBinding[size], 0, size);
+	}
+	return combinedTypeVars;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#availableMethods()
+ */
+public MethodBinding[] availableMethods() {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+		return this.methods;
+
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	MethodBinding[] availableMethods = new MethodBinding[this.methods.length];
+	int count = 0;
+	for (int i = 0; i < this.methods.length; i++) {
+		try {
+			availableMethods[count] = resolveTypesFor(this.methods[i]);
+			count++;
+		} catch (AbortCompilation a){
+			// silent abort
+		}
+	}
+	if (count < availableMethods.length)
+		System.arraycopy(availableMethods, 0, availableMethods = new MethodBinding[count], 0, count);
+	return availableMethods;
+}
+
+void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) {
+	try {
+		// default initialization for super-interfaces early, in case some aborting compilation error occurs,
+		// and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
+		this.typeVariables = Binding.NO_TYPE_VARIABLES;
+		this.superInterfaces = Binding.NO_SUPERINTERFACES;
+
+		// must retrieve member types in case superclass/interfaces need them
+		this.memberTypes = Binding.NO_MEMBER_TYPES;
+		IBinaryNestedType[] memberTypeStructures = binaryType.getMemberTypes();
+		if (memberTypeStructures != null) {
+			int size = memberTypeStructures.length;
+			if (size > 0) {
+				this.memberTypes = new ReferenceBinding[size];
+				for (int i = 0; i < size; i++) {
+					// attempt to find each member type if it exists in the cache (otherwise - resolve it when requested)
+					this.memberTypes[i] = this.environment.getTypeFromConstantPoolName(memberTypeStructures[i].getName(), 0, -1, false, null /* could not be missing */);
+				}
+				this.tagBits |= TagBits.HasUnresolvedMemberTypes;
+			}
+		}
+
+		long sourceLevel = this.environment.globalOptions.originalSourceLevel;
+		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
+		   must internalize type variables and observe any parameterization of super class
+		   and/or super interfaces in order to be able to detect overriding in the presence
+		   of generics.
+		 */
+		char[] typeSignature = binaryType.getGenericSignature(); // use generic signature even in 1.4
+		this.tagBits |= binaryType.getTagBits();
+		
+		char[][][] missingTypeNames = binaryType.getMissingTypeNames();
+		SignatureWrapper wrapper = null;
+		if (typeSignature != null) {
+			// ClassSignature = ParameterPart(optional) super_TypeSignature interface_signature
+			wrapper = new SignatureWrapper(typeSignature);
+			if (wrapper.signature[wrapper.start] == Util.C_GENERIC_START) {
+				// ParameterPart = '<' ParameterSignature(s) '>'
+				wrapper.start++; // skip '<'
+				this.typeVariables = createTypeVariables(wrapper, true, missingTypeNames);
+				wrapper.start++; // skip '>'
+				this.tagBits |=  TagBits.HasUnresolvedTypeVariables;
+				this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+			}
+		}
+		TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
+		char[] methodDescriptor = binaryType.getEnclosingMethod();
+		if (methodDescriptor != null) {
+			MethodBinding enclosingMethod = findMethod(methodDescriptor, missingTypeNames);
+			if (enclosingMethod != null) {
+				typeVars = enclosingMethod.typeVariables;
+				this.typeVariables = addMethodTypeVariables(typeVars);			
+			}
+		}
+		if (typeSignature == null)  {
+			char[] superclassName = binaryType.getSuperclassName();
+			if (superclassName != null) {
+				// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
+				this.superclass = this.environment.getTypeFromConstantPoolName(superclassName, 0, -1, false, missingTypeNames);
+				this.tagBits |= TagBits.HasUnresolvedSuperclass;
+			}
+
+			this.superInterfaces = Binding.NO_SUPERINTERFACES;
+			char[][] interfaceNames = binaryType.getInterfaceNames();
+			if (interfaceNames != null) {
+				int size = interfaceNames.length;
+				if (size > 0) {
+					this.superInterfaces = new ReferenceBinding[size];
+					for (int i = 0; i < size; i++)
+						// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
+						this.superInterfaces[i] = this.environment.getTypeFromConstantPoolName(interfaceNames[i], 0, -1, false, missingTypeNames);
+					this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+				}
+			}
+		} else {
+			// attempt to find the superclass if it exists in the cache (otherwise - resolve it when requested)
+			this.superclass = (ReferenceBinding) this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames);
+			this.tagBits |= TagBits.HasUnresolvedSuperclass;
+
+			this.superInterfaces = Binding.NO_SUPERINTERFACES;
+			if (!wrapper.atEnd()) {
+				// attempt to find each superinterface if it exists in the cache (otherwise - resolve it when requested)
+				java.util.ArrayList types = new java.util.ArrayList(2);
+				do {
+					types.add(this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames));
+				} while (!wrapper.atEnd());
+				this.superInterfaces = new ReferenceBinding[types.size()];
+				types.toArray(this.superInterfaces);
+				this.tagBits |= TagBits.HasUnresolvedSuperinterfaces;
+			}
+		}
+
+		if (needFieldsAndMethods) {
+			createFields(binaryType.getFields(), sourceLevel, missingTypeNames);
+			createMethods(binaryType.getMethods(), sourceLevel, missingTypeNames);
+			boolean isViewedAsDeprecated = isViewedAsDeprecated();
+			if (isViewedAsDeprecated) {
+				for (int i = 0, max = this.fields.length; i < max; i++) {
+					FieldBinding field = this.fields[i];
+					if (!field.isDeprecated()) {
+						field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+					}
+				}
+				for (int i = 0, max = this.methods.length; i < max; i++) {
+					MethodBinding method = this.methods[i];
+					if (!method.isDeprecated()) {
+						method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+					}
+				}
+			}
+		}
+		if (this.environment.globalOptions.storeAnnotations)
+			setAnnotations(createAnnotations(binaryType.getAnnotations(), this.environment, missingTypeNames));
+	} finally {
+		// protect against incorrect use of the needFieldsAndMethods flag, see 48459
+		if (this.fields == null)
+			this.fields = Binding.NO_FIELDS;
+		if (this.methods == null)
+			this.methods = Binding.NO_METHODS;
+	}
+}
+
+private void createFields(IBinaryField[] iFields, long sourceLevel, char[][][] missingTypeNames) {
+	this.fields = Binding.NO_FIELDS;
+	if (iFields != null) {
+		int size = iFields.length;
+		if (size > 0) {
+			this.fields = new FieldBinding[size];
+			boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
+			boolean hasRestrictedAccess = hasRestrictedAccess();
+			int firstAnnotatedFieldIndex = -1;
+			for (int i = 0; i < size; i++) {
+				IBinaryField binaryField = iFields[i];
+				char[] fieldSignature = use15specifics ? binaryField.getGenericSignature() : null;
+				TypeBinding type = fieldSignature == null
+					? this.environment.getTypeFromSignature(binaryField.getTypeName(), 0, -1, false, this, missingTypeNames)
+					: this.environment.getTypeFromTypeSignature(new SignatureWrapper(fieldSignature), Binding.NO_TYPE_VARIABLES, this, missingTypeNames);
+				FieldBinding field =
+					new FieldBinding(
+						binaryField.getName(),
+						type,
+						binaryField.getModifiers() | ExtraCompilerModifiers.AccUnresolved,
+						this,
+						binaryField.getConstant());
+				if (firstAnnotatedFieldIndex < 0
+						&& this.environment.globalOptions.storeAnnotations
+						&& binaryField.getAnnotations() != null) {
+					firstAnnotatedFieldIndex = i;
+				}
+				field.id = i; // ordinal
+				if (use15specifics)
+					field.tagBits |= binaryField.getTagBits();
+				if (hasRestrictedAccess)
+					field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+				if (fieldSignature != null)
+					field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+				this.fields[i] = field;
+			}
+			// second pass for reifying annotations, since may refer to fields being constructed (147875)
+			if (firstAnnotatedFieldIndex >= 0) {
+				for (int i = firstAnnotatedFieldIndex; i <size; i++) {
+					IBinaryField binaryField = iFields[i];
+					this.fields[i].setAnnotations(createAnnotations(binaryField.getAnnotations(), this.environment, missingTypeNames));
+				}
+			}
+			if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+				for (int i = 0; i <size; i++) {
+					IBinaryField binaryField = iFields[i];
+					scanFieldForNullAnnotation(binaryField, this.fields[i]);
+				}
+			}
+		}
+	}
+}
+
+private MethodBinding createMethod(IBinaryMethod method, long sourceLevel, char[][][] missingTypeNames) {
+	int methodModifiers = method.getModifiers() | ExtraCompilerModifiers.AccUnresolved;
+	if (sourceLevel < ClassFileConstants.JDK1_5)
+		methodModifiers &= ~ClassFileConstants.AccVarargs; // vararg methods are not recognized until 1.5
+	if (isInterface() && (methodModifiers & ClassFileConstants.AccAbstract) == 0) {
+		// see https://bugs.eclipse.org/388954
+		if (sourceLevel >= ClassFileConstants.JDK1_8)
+			methodModifiers |= ExtraCompilerModifiers.AccDefaultMethod;
+		else
+			methodModifiers |= ClassFileConstants.AccAbstract;
+	}
+	ReferenceBinding[] exceptions = Binding.NO_EXCEPTIONS;
+	TypeBinding[] parameters = Binding.NO_PARAMETERS;
+	TypeVariableBinding[] typeVars = Binding.NO_TYPE_VARIABLES;
+	AnnotationBinding[][] paramAnnotations = null;
+	TypeBinding returnType = null;
+
+	final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
+	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Since a 1.4 project can have a 1.5
+	   type as a super type and the 1.5 type could be generic, we must internalize usages of type
+	   variables properly in order to be able to apply substitutions and thus be able to detect
+	   overriding in the presence of generics. Seeing the erased form is not good enough.
+	 */
+	char[] methodSignature = method.getGenericSignature(); // always use generic signature, even in 1.4
+	if (methodSignature == null) { // no generics
+		char[] methodDescriptor = method.getMethodDescriptor();   // of the form (I[Ljava/jang/String;)V
+		int numOfParams = 0;
+		char nextChar;
+		int index = 0; // first character is always '(' so skip it
+		while ((nextChar = methodDescriptor[++index]) != Util.C_PARAM_END) {
+			if (nextChar != Util.C_ARRAY) {
+				numOfParams++;
+				if (nextChar == Util.C_RESOLVED)
+					while ((nextChar = methodDescriptor[++index]) != Util.C_NAME_END){/*empty*/}
+			}
+		}
+
+		// Ignore synthetic argument for member types or enum types.
+		int startIndex = 0;
+		if (method.isConstructor()) {
+			if (isMemberType() && !isStatic()) {
+				// enclosing type
+				startIndex++;
+			}
+			if (isEnum()) {
+				// synthetic arguments (String, int)
+				startIndex += 2;
+			}
+		}
+		int size = numOfParams - startIndex;
+		if (size > 0) {
+			parameters = new TypeBinding[size];
+			if (this.environment.globalOptions.storeAnnotations)
+				paramAnnotations = new AnnotationBinding[size][];
+			index = 1;
+			int end = 0;   // first character is always '(' so skip it
+			for (int i = 0; i < numOfParams; i++) {
+				while ((nextChar = methodDescriptor[++end]) == Util.C_ARRAY){/*empty*/}
+				if (nextChar == Util.C_RESOLVED)
+					while ((nextChar = methodDescriptor[++end]) != Util.C_NAME_END){/*empty*/}
+
+				if (i >= startIndex) {   // skip the synthetic arg if necessary
+					parameters[i - startIndex] = this.environment.getTypeFromSignature(methodDescriptor, index, end, false, this, missingTypeNames);
+					// 'paramAnnotations' line up with 'parameters'
+					// int parameter to method.getParameterAnnotations() include the synthetic arg
+					if (paramAnnotations != null)
+						paramAnnotations[i - startIndex] = createAnnotations(method.getParameterAnnotations(i - startIndex), this.environment, missingTypeNames);
+				}
+				index = end + 1;
+			}
+		}
+
+		char[][] exceptionTypes = method.getExceptionTypeNames();
+		if (exceptionTypes != null) {
+			size = exceptionTypes.length;
+			if (size > 0) {
+				exceptions = new ReferenceBinding[size];
+				for (int i = 0; i < size; i++)
+					exceptions[i] = this.environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false, missingTypeNames);
+			}
+		}
+
+		if (!method.isConstructor())
+			returnType = this.environment.getTypeFromSignature(methodDescriptor, index + 1, -1, false, this, missingTypeNames);   // index is currently pointing at the ')'
+	} else {
+		methodModifiers |= ExtraCompilerModifiers.AccGenericSignature;
+		// MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
+		SignatureWrapper wrapper = new SignatureWrapper(methodSignature, use15specifics);
+		if (wrapper.signature[wrapper.start] == Util.C_GENERIC_START) {
+			// <A::Ljava/lang/annotation/Annotation;>(Ljava/lang/Class<TA;>;)TA;
+			// ParameterPart = '<' ParameterSignature(s) '>'
+			wrapper.start++; // skip '<'
+			typeVars = createTypeVariables(wrapper, false, missingTypeNames);
+			wrapper.start++; // skip '>'
+		}
+
+		if (wrapper.signature[wrapper.start] == Util.C_PARAM_START) {
+			wrapper.start++; // skip '('
+			if (wrapper.signature[wrapper.start] == Util.C_PARAM_END) {
+				wrapper.start++; // skip ')'
+			} else {
+				java.util.ArrayList types = new java.util.ArrayList(2);
+				while (wrapper.signature[wrapper.start] != Util.C_PARAM_END)
+					types.add(this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames));
+				wrapper.start++; // skip ')'
+				int numParam = types.size();
+				parameters = new TypeBinding[numParam];
+				types.toArray(parameters);
+				if (this.environment.globalOptions.storeAnnotations) {
+					paramAnnotations = new AnnotationBinding[numParam][];
+					for (int i = 0; i < numParam; i++)
+						paramAnnotations[i] = createAnnotations(method.getParameterAnnotations(i), this.environment, missingTypeNames);
+				}
+			}
+		}
+
+		// always retrieve return type (for constructors, its V for void - will be ignored)
+		returnType = this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames);
+
+		if (!wrapper.atEnd() && wrapper.signature[wrapper.start] == Util.C_EXCEPTION_START) {
+			// attempt to find each exception if it exists in the cache (otherwise - resolve it when requested)
+			java.util.ArrayList types = new java.util.ArrayList(2);
+			do {
+				wrapper.start++; // skip '^'
+				types.add(this.environment.getTypeFromTypeSignature(wrapper, typeVars, this, missingTypeNames));
+			} while (!wrapper.atEnd() && wrapper.signature[wrapper.start] == Util.C_EXCEPTION_START);
+			exceptions = new ReferenceBinding[types.size()];
+			types.toArray(exceptions);
+		} else { // get the exceptions the old way
+			char[][] exceptionTypes = method.getExceptionTypeNames();
+			if (exceptionTypes != null) {
+				int size = exceptionTypes.length;
+				if (size > 0) {
+					exceptions = new ReferenceBinding[size];
+					for (int i = 0; i < size; i++)
+						exceptions[i] = this.environment.getTypeFromConstantPoolName(exceptionTypes[i], 0, -1, false, missingTypeNames);
+				}
+			}
+		}
+	}
+
+	MethodBinding result = method.isConstructor()
+		? new MethodBinding(methodModifiers, parameters, exceptions, this)
+		: new MethodBinding(methodModifiers, method.getSelector(), returnType, parameters, exceptions, this);
+	if (this.environment.globalOptions.storeAnnotations)
+		result.setAnnotations(
+			createAnnotations(method.getAnnotations(), this.environment, missingTypeNames),
+			paramAnnotations,
+			isAnnotationType() ? convertMemberValue(method.getDefaultValue(), this.environment, missingTypeNames) : null,
+			this.environment);
+
+	if (use15specifics)
+		result.tagBits |= method.getTagBits();
+	result.typeVariables = typeVars;
+	// fixup the declaring element of the type variable
+	for (int i = 0, length = typeVars.length; i < length; i++)
+		typeVars[i].declaringElement = result;
+
+	scanMethodForNullAnnotation(method, result);
+
+	return result;
+}
+
+/**
+ * Create method bindings for binary type, filtering out <clinit> and synthetics
+ */
+private void createMethods(IBinaryMethod[] iMethods, long sourceLevel, char[][][] missingTypeNames) {
+	int total = 0, initialTotal = 0, iClinit = -1;
+	int[] toSkip = null;
+	if (iMethods != null) {
+		total = initialTotal = iMethods.length;
+		boolean keepBridgeMethods = sourceLevel < ClassFileConstants.JDK1_5; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=330347
+		for (int i = total; --i >= 0;) {
+			IBinaryMethod method = iMethods[i];
+			if ((method.getModifiers() & ClassFileConstants.AccSynthetic) != 0) {
+				if (keepBridgeMethods && (method.getModifiers() & ClassFileConstants.AccBridge) != 0)
+					continue; // want to see bridge methods as real methods
+				// discard synthetics methods
+				if (toSkip == null) toSkip = new int[iMethods.length];
+				toSkip[i] = -1;
+				total--;
+			} else if (iClinit == -1) {
+				char[] methodName = method.getSelector();
+				if (methodName.length == 8 && methodName[0] == Util.C_GENERIC_START) {
+					// discard <clinit>
+					iClinit = i;
+					total--;
+				}
+			}
+		}
+	}
+	if (total == 0) {
+		this.methods = Binding.NO_METHODS;
+		return;
+	}
+
+	boolean hasRestrictedAccess = hasRestrictedAccess();
+	this.methods = new MethodBinding[total];
+	if (total == initialTotal) {
+		for (int i = 0; i < initialTotal; i++) {
+			MethodBinding method = createMethod(iMethods[i], sourceLevel, missingTypeNames);
+			if (hasRestrictedAccess)
+				method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+			this.methods[i] = method;
+		}
+	} else {
+		for (int i = 0, index = 0; i < initialTotal; i++) {
+			if (iClinit != i && (toSkip == null || toSkip[i] != -1)) {
+				MethodBinding method = createMethod(iMethods[i], sourceLevel, missingTypeNames);
+				if (hasRestrictedAccess)
+					method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+				this.methods[index++] = method;
+			}
+		}
+	}
+}
+
+private TypeVariableBinding[] createTypeVariables(SignatureWrapper wrapper, boolean assignVariables, char[][][] missingTypeNames) {
+	// detect all type variables first
+	char[] typeSignature = wrapper.signature;
+	int depth = 0, length = typeSignature.length;
+	int rank = 0;
+	ArrayList variables = new ArrayList(1);
+	depth = 0;
+	boolean pendingVariable = true;
+	createVariables: {
+		for (int i = 1; i < length; i++) {
+			switch(typeSignature[i]) {
+				case Util.C_GENERIC_START :
+					depth++;
+					break;
+				case Util.C_GENERIC_END :
+					if (--depth < 0)
+						break createVariables;
+					break;
+				case Util.C_NAME_END :
+					if ((depth == 0) && (i +1 < length) && (typeSignature[i+1] != Util.C_COLON))
+						pendingVariable = true;
+					break;
+				default:
+					if (pendingVariable) {
+						pendingVariable = false;
+						int colon = CharOperation.indexOf(Util.C_COLON, typeSignature, i);
+						char[] variableName = CharOperation.subarray(typeSignature, i, colon);
+						variables.add(new TypeVariableBinding(variableName, this, rank++, this.environment));
+					}
+			}
+		}
+	}
+	// initialize type variable bounds - may refer to forward variables
+	TypeVariableBinding[] result;
+	variables.toArray(result = new TypeVariableBinding[rank]);
+	// when creating the type variables for a type, the type must remember them before initializing each variable
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=163680
+	if (assignVariables)
+		this.typeVariables = result;
+	for (int i = 0; i < rank; i++) {
+		initializeTypeVariable(result[i], result, wrapper, missingTypeNames);
+	}
+	return result;
+}
+
+/* Answer the receiver's enclosing type... null if the receiver is a top level type.
+*
+* NOTE: enclosingType of a binary type is resolved when needed
+*/
+public ReferenceBinding enclosingType() {
+	if ((this.tagBits & TagBits.HasUnresolvedEnclosingType) == 0)
+		return this.enclosingType;
+
+	// finish resolving the type
+	this.enclosingType = (ReferenceBinding) resolveType(this.enclosingType, this.environment, false /* no raw conversion */);
+	this.tagBits &= ~TagBits.HasUnresolvedEnclosingType;
+	return this.enclosingType;
+}
+// NOTE: the type of each field of a binary type is resolved when needed
+public FieldBinding[] fields() {
+	if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+		return this.fields;
+
+	// lazily sort fields
+	if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+		int length = this.fields.length;
+		if (length > 1)
+			ReferenceBinding.sortFields(this.fields, 0, length);
+		this.tagBits |= TagBits.AreFieldsSorted;
+	}
+	for (int i = this.fields.length; --i >= 0;)
+		resolveTypeFor(this.fields[i]);
+	this.tagBits |= TagBits.AreFieldsComplete;
+	return this.fields;
+}
+
+private MethodBinding findMethod(char[] methodDescriptor, char[][][] missingTypeNames) {
+	int index = -1;
+	while (methodDescriptor[++index] != Util.C_PARAM_START) {
+		// empty
+	}
+	char[] selector = new char[index];
+	System.arraycopy(methodDescriptor, 0, selector, 0, index);
+	TypeBinding[] parameters = Binding.NO_PARAMETERS;
+	int numOfParams = 0;
+	char nextChar;
+	int paramStart = index;
+	while ((nextChar = methodDescriptor[++index]) != Util.C_PARAM_END) {
+		if (nextChar != Util.C_ARRAY) {
+			numOfParams++;
+			if (nextChar == Util.C_RESOLVED)
+				while ((nextChar = methodDescriptor[++index]) != Util.C_NAME_END){/*empty*/}
+		}
+	}
+	if (numOfParams > 0) {
+		parameters = new TypeBinding[numOfParams];
+		index = paramStart + 1;
+		int end = paramStart; // first character is always '(' so skip it
+		for (int i = 0; i < numOfParams; i++) {
+			while ((nextChar = methodDescriptor[++end]) == Util.C_ARRAY){/*empty*/}
+			if (nextChar == Util.C_RESOLVED)
+				while ((nextChar = methodDescriptor[++end]) != Util.C_NAME_END){/*empty*/}
+
+			TypeBinding param = this.environment.getTypeFromSignature(methodDescriptor, index, end, false, this, missingTypeNames);
+			if (param instanceof UnresolvedReferenceBinding) {
+				param = resolveType(param, this.environment, true /* raw conversion */);
+			}
+			parameters[i] = param;
+			index = end + 1;
+		}
+	}
+
+	int parameterLength = parameters.length;
+	MethodBinding[] methods2 = this.enclosingType.getMethods(selector, parameterLength);
+	// find matching method using parameters
+	loop: for (int i = 0, max = methods2.length; i < max; i++) {
+		MethodBinding currentMethod = methods2[i];
+		TypeBinding[] parameters2 = currentMethod.parameters;
+		int currentMethodParameterLength = parameters2.length;
+		if (parameterLength == currentMethodParameterLength) {
+			for (int j = 0; j < currentMethodParameterLength; j++) {
+				if (parameters[j] != parameters2[j] && parameters[j].erasure() != parameters2[j].erasure()) {
+					continue loop;
+				}
+			}
+			return currentMethod;
+		}
+	}
+	return null;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
+ */
+public char[] genericTypeSignature() {
+	return computeGenericTypeSignature(this.typeVariables);
+}
+
+//NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
+public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
+
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	int argCount = argumentTypes.length;
+	long range;
+	if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
+		nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+			MethodBinding method = this.methods[imethod];
+			if (method.parameters.length == argCount) {
+				resolveTypesFor(method);
+				TypeBinding[] toMatch = method.parameters;
+				for (int iarg = 0; iarg < argCount; iarg++)
+					if (toMatch[iarg] != argumentTypes[iarg])
+						continue nextMethod;
+				return method;
+			}
+		}
+	}
+	return null;
+}
+
+//NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
+//searches up the hierarchy as long as no potential (but not exact) match was found.
+public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
+	// sender from refScope calls recordTypeReference(this)
+
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+
+	int argCount = argumentTypes.length;
+	boolean foundNothing = true;
+
+	long range;
+	if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+		nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+			MethodBinding method = this.methods[imethod];
+			foundNothing = false; // inner type lookups must know that a method with this name exists
+			if (method.parameters.length == argCount) {
+				resolveTypesFor(method);
+				TypeBinding[] toMatch = method.parameters;
+				for (int iarg = 0; iarg < argCount; iarg++)
+					if (toMatch[iarg] != argumentTypes[iarg])
+						continue nextMethod;
+				return method;
+			}
+		}
+	}
+	if (foundNothing) {
+		if (isInterface()) {
+			 if (superInterfaces().length == 1) { // ensure superinterfaces are resolved before checking
+				if (refScope != null)
+					refScope.recordTypeReference(this.superInterfaces[0]);
+				return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
+			 }
+		} else if (superclass() != null) { // ensure superclass is resolved before checking
+			if (refScope != null)
+				refScope.recordTypeReference(this.superclass);
+			return this.superclass.getExactMethod(selector, argumentTypes, refScope);
+		}
+	}
+	return null;
+}
+//NOTE: the type of a field of a binary type is resolved when needed
+public FieldBinding getField(char[] fieldName, boolean needResolve) {
+	// lazily sort fields
+	if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+		int length = this.fields.length;
+		if (length > 1)
+			ReferenceBinding.sortFields(this.fields, 0, length);
+		this.tagBits |= TagBits.AreFieldsSorted;
+	}
+	FieldBinding field = ReferenceBinding.binarySearch(fieldName, this.fields);
+	return needResolve && field != null ? resolveTypeFor(field) : field;
+}
+/**
+ *  Rewrite of default getMemberType to avoid resolving eagerly all member types when one is requested
+ */
+public ReferenceBinding getMemberType(char[] typeName) {
+	for (int i = this.memberTypes.length; --i >= 0;) {
+	    ReferenceBinding memberType = this.memberTypes[i];
+	    if (memberType instanceof UnresolvedReferenceBinding) {
+			char[] name = memberType.sourceName; // source name is qualified with enclosing type name
+			int prefixLength = this.compoundName[this.compoundName.length - 1].length + 1; // enclosing$
+			if (name.length == (prefixLength + typeName.length)) // enclosing $ typeName
+				if (CharOperation.fragmentEquals(typeName, name, prefixLength, true)) // only check trailing portion
+					return this.memberTypes[i] = (ReferenceBinding) resolveType(memberType, this.environment, false /* no raw conversion for now */);
+	    } else if (CharOperation.equals(typeName, memberType.sourceName)) {
+	        return memberType;
+	    }
+	}
+	return null;
+}
+// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
+public MethodBinding[] getMethods(char[] selector) {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+		long range;
+		if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+			int start = (int) range, end = (int) (range >> 32);
+			int length = end - start + 1;
+			if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+				// simply clone method subset
+				MethodBinding[] result;
+				System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
+				return result;
+			}
+		}
+		return Binding.NO_METHODS;
+	}
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	long range;
+	if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+		int start = (int) range, end = (int) (range >> 32);
+		int length = end - start + 1;
+		MethodBinding[] result = new MethodBinding[length];
+		// iterate methods to resolve them
+		for (int i = start, index = 0; i <= end; i++, index++)
+			result[index] = resolveTypesFor(this.methods[i]);
+		return result;
+	}
+	return Binding.NO_METHODS;
+}
+// Answer methods named selector, which take no more than the suggestedParameterLength.
+// The suggested parameter length is optional and may not be guaranteed by every type.
+public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+		return getMethods(selector);
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	long range;
+	if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+		int start = (int) range, end = (int) (range >> 32);
+		int length = end - start + 1;
+		int count = 0;
+		for (int i = start; i <= end; i++) {
+			int len = this.methods[i].parameters.length;
+			if (len <= suggestedParameterLength || (this.methods[i].isVarargs() && len == suggestedParameterLength + 1))
+				count++;
+		}
+		if (count == 0) {
+			MethodBinding[] result = new MethodBinding[length];
+			// iterate methods to resolve them
+			for (int i = start, index = 0; i <= end; i++)
+				result[index++] = resolveTypesFor(this.methods[i]);
+			return result;
+		} else {
+			MethodBinding[] result = new MethodBinding[count];
+			// iterate methods to resolve them
+			for (int i = start, index = 0; i <= end; i++) {
+				int len = this.methods[i].parameters.length;
+				if (len <= suggestedParameterLength || (this.methods[i].isVarargs() && len == suggestedParameterLength + 1))
+					result[index++] = resolveTypesFor(this.methods[i]);
+			}
+			return result;
+		}
+	}
+	return Binding.NO_METHODS;
+}
+public boolean hasMemberTypes() {
+    return this.memberTypes.length > 0;
+}
+// NOTE: member types of binary types are resolved when needed
+public TypeVariableBinding getTypeVariable(char[] variableName) {
+	TypeVariableBinding variable = super.getTypeVariable(variableName);
+	variable.resolve();
+	return variable;
+}
+public boolean hasTypeBit(int bit) {
+	// ensure hierarchy is resolved, which will propagate bits down to us
+	boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType;
+	this.environment.mayTolerateMissingType = true;
+	try {
+		superclass();
+		superInterfaces();
+	} finally {
+		this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations;
+	}
+	return (this.typeBits & bit) != 0;
+}
+private void initializeTypeVariable(TypeVariableBinding variable, TypeVariableBinding[] existingVariables, SignatureWrapper wrapper, char[][][] missingTypeNames) {
+	// ParameterSignature = Identifier ':' TypeSignature
+	//   or Identifier ':' TypeSignature(optional) InterfaceBound(s)
+	// InterfaceBound = ':' TypeSignature
+	int colon = CharOperation.indexOf(Util.C_COLON, wrapper.signature, wrapper.start);
+	wrapper.start = colon + 1; // skip name + ':'
+	ReferenceBinding type, firstBound = null;
+	if (wrapper.signature[wrapper.start] == Util.C_COLON) {
+		type = this.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+	} else {
+		TypeBinding typeFromTypeSignature = this.environment.getTypeFromTypeSignature(wrapper, existingVariables, this, missingTypeNames);
+		if (typeFromTypeSignature instanceof ReferenceBinding) {
+			type = (ReferenceBinding) typeFromTypeSignature;
+		} else {
+			// this should only happen if the signature is corrupted (332423)
+			type = this.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+		}
+		firstBound = type;
+	}
+
+	// variable is visible to its bounds
+	variable.modifiers |= ExtraCompilerModifiers.AccUnresolved;
+	variable.superclass = type;
+
+	ReferenceBinding[] bounds = null;
+	if (wrapper.signature[wrapper.start] == Util.C_COLON) {
+		java.util.ArrayList types = new java.util.ArrayList(2);
+		do {
+			wrapper.start++; // skip ':'
+			types.add(this.environment.getTypeFromTypeSignature(wrapper, existingVariables, this, missingTypeNames));
+		} while (wrapper.signature[wrapper.start] == Util.C_COLON);
+		bounds = new ReferenceBinding[types.size()];
+		types.toArray(bounds);
+	}
+
+	variable.superInterfaces = bounds == null ? Binding.NO_SUPERINTERFACES : bounds;
+	if (firstBound == null) {
+		firstBound = variable.superInterfaces.length == 0 ? null : variable.superInterfaces[0];
+	}
+	variable.firstBound = firstBound;
+}
+/**
+ * Returns true if a type is identical to another one,
+ * or for generic types, true if compared to its raw type.
+ */
+public boolean isEquivalentTo(TypeBinding otherType) {
+	if (this == otherType) return true;
+	if (otherType == null) return false;
+	switch(otherType.kind()) {
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+			return ((WildcardBinding) otherType).boundCheck(this);
+		case Binding.PARAMETERIZED_TYPE:
+		/* With the hybrid 1.4/1.5+ projects modes, while establishing type equivalence, we need to
+	       be prepared for a type such as Map appearing in one of three forms: As (a) a ParameterizedTypeBinding 
+	       e.g Map<String, String>, (b) as RawTypeBinding Map#RAW and finally (c) as a BinaryTypeBinding 
+	       When the usage of a type lacks type parameters, whether we land up with the raw form or not depends
+	       on whether the underlying type was "seen to be" a generic type in the particular build environment or
+	       not. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827 
+		*/ 
+		case Binding.RAW_TYPE :
+			return otherType.erasure() == this;
+	}
+	return false;
+}
+public boolean isGenericType() {
+    return this.typeVariables != Binding.NO_TYPE_VARIABLES;
+}
+public boolean isHierarchyConnected() {
+	return (this.tagBits & (TagBits.HasUnresolvedSuperclass | TagBits.HasUnresolvedSuperinterfaces)) == 0;
+}
+public int kind() {
+	if (this.typeVariables != Binding.NO_TYPE_VARIABLES)
+		return Binding.GENERIC_TYPE;
+	return Binding.TYPE;
+}
+// NOTE: member types of binary types are resolved when needed
+public ReferenceBinding[] memberTypes() {
+ 	if ((this.tagBits & TagBits.HasUnresolvedMemberTypes) == 0)
+		return this.memberTypes;
+
+	for (int i = this.memberTypes.length; --i >= 0;)
+		this.memberTypes[i] = (ReferenceBinding) resolveType(this.memberTypes[i], this.environment, false /* no raw conversion for now */);
+	this.tagBits &= ~TagBits.HasUnresolvedMemberTypes;
+	return this.memberTypes;
+}
+// NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
+public MethodBinding[] methods() {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+		return this.methods;
+
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	for (int i = this.methods.length; --i >= 0;)
+		resolveTypesFor(this.methods[i]);
+	this.tagBits |= TagBits.AreMethodsComplete;
+	return this.methods;
+}
+private FieldBinding resolveTypeFor(FieldBinding field) {
+	if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+		return field;
+
+	TypeBinding resolvedType = resolveType(field.type, this.environment, true /* raw conversion */);
+	field.type = resolvedType;
+	if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+		field.tagBits |= TagBits.HasMissingType;
+	}
+	field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+	return field;
+}
+MethodBinding resolveTypesFor(MethodBinding method) {
+	if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+		return method;
+
+	if (!method.isConstructor()) {
+		TypeBinding resolvedType = resolveType(method.returnType, this.environment, true /* raw conversion */);
+		method.returnType = resolvedType;
+		if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+			method.tagBits |= TagBits.HasMissingType;
+		}
+	}
+	for (int i = method.parameters.length; --i >= 0;) {
+		TypeBinding resolvedType = resolveType(method.parameters[i], this.environment, true /* raw conversion */);
+		method.parameters[i] = resolvedType;
+		if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+			method.tagBits |= TagBits.HasMissingType;
+		}
+	}
+	for (int i = method.thrownExceptions.length; --i >= 0;) {
+		ReferenceBinding resolvedType = (ReferenceBinding) resolveType(method.thrownExceptions[i], this.environment, true /* raw conversion */);
+		method.thrownExceptions[i] = resolvedType;
+		if ((resolvedType.tagBits & TagBits.HasMissingType) != 0) {
+			method.tagBits |= TagBits.HasMissingType;
+		}
+	}
+	for (int i = method.typeVariables.length; --i >= 0;) {
+		method.typeVariables[i].resolve();
+	}
+	method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+	return method;
+}
+AnnotationBinding[] retrieveAnnotations(Binding binding) {
+	return AnnotationBinding.addStandardAnnotations(super.retrieveAnnotations(binding), binding.getAnnotationTagBits(), this.environment);
+}
+SimpleLookupTable storedAnnotations(boolean forceInitialize) {
+	if (forceInitialize && this.storedAnnotations == null) {
+		if (!this.environment.globalOptions.storeAnnotations)
+			return null; // not supported during this compile
+		this.storedAnnotations = new SimpleLookupTable(3);
+	}
+	return this.storedAnnotations;
+}
+
+void scanFieldForNullAnnotation(IBinaryField field, FieldBinding fieldBinding) {
+	// global option is checked by caller
+	char[][] nullableAnnotationName = this.environment.getNullableAnnotationName();
+	char[][] nonNullAnnotationName = this.environment.getNonNullAnnotationName();
+	if (nullableAnnotationName == null || nonNullAnnotationName == null)
+		return; // not well-configured to use null annotations
+
+	if (fieldBinding.type == null || fieldBinding.type.isBaseType())
+		return; // null annotations are only applied to reference types
+
+	boolean explicitNullness = false;
+	IBinaryAnnotation[] annotations = field.getAnnotations();
+	if (annotations != null) {
+		for (int i = 0; i < annotations.length; i++) {
+			char[] annotationTypeName = annotations[i].getTypeName();
+			if (annotationTypeName[0] != Util.C_RESOLVED)
+				continue;
+			char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+			if (CharOperation.equals(typeName, nonNullAnnotationName)) {
+				fieldBinding.tagBits |= TagBits.AnnotationNonNull;
+				explicitNullness = true;
+				break;
+			}
+			if (CharOperation.equals(typeName, nullableAnnotationName)) {
+				fieldBinding.tagBits |= TagBits.AnnotationNullable;
+				explicitNullness = true;
+				break;
+			}
+		}
+	}
+	if (!explicitNullness && (this.tagBits & TagBits.AnnotationNonNullByDefault) != 0) {
+		fieldBinding.tagBits |= TagBits.AnnotationNonNull;
+	}
+}
+
+void scanMethodForNullAnnotation(IBinaryMethod method, MethodBinding methodBinding) {
+	if (!this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled)
+		return;
+	char[][] nullableAnnotationName = this.environment.getNullableAnnotationName();
+	char[][] nonNullAnnotationName = this.environment.getNonNullAnnotationName();
+	char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName();
+	if (nullableAnnotationName == null || nonNullAnnotationName == null || nonNullByDefaultAnnotationName == null)
+		return; // not well-configured to use null annotations
+
+	// return:
+	IBinaryAnnotation[] annotations = method.getAnnotations();
+	boolean explicitNullness = false;
+	if (annotations != null) {
+		for (int i = 0; i < annotations.length; i++) {
+			char[] annotationTypeName = annotations[i].getTypeName();
+			if (annotationTypeName[0] != Util.C_RESOLVED)
+				continue;
+			char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+			if (CharOperation.equals(typeName, nonNullByDefaultAnnotationName)) {
+				methodBinding.tagBits |= TagBits.AnnotationNonNullByDefault;
+			}
+			if (!explicitNullness && CharOperation.equals(typeName, nonNullAnnotationName)) {
+				methodBinding.tagBits |= TagBits.AnnotationNonNull;
+				explicitNullness = true;
+			}
+			if (!explicitNullness && CharOperation.equals(typeName, nullableAnnotationName)) {
+				methodBinding.tagBits |= TagBits.AnnotationNullable;
+				explicitNullness = true;
+			}
+		}
+	}
+
+	// parameters:
+	TypeBinding[] parameters = methodBinding.parameters;
+	int numVisibleParams = parameters.length;
+	int numParamAnnotations = method.getAnnotatedParametersCount();
+	if (numParamAnnotations > 0) {
+		for (int j = 0; j < numVisibleParams; j++) {
+			if (numParamAnnotations > 0) {
+				int startIndex = numParamAnnotations - numVisibleParams;
+				IBinaryAnnotation[] paramAnnotations = method.getParameterAnnotations(j+startIndex);
+				if (paramAnnotations != null) {
+					for (int i = 0; i < paramAnnotations.length; i++) {
+						char[] annotationTypeName = paramAnnotations[i].getTypeName();
+						if (annotationTypeName[0] != Util.C_RESOLVED)
+							continue;
+						char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+						if (CharOperation.equals(typeName, nonNullAnnotationName)) {
+							if (methodBinding.parameterNonNullness == null)
+								methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
+							methodBinding.parameterNonNullness[j] = Boolean.TRUE;
+							break;
+						} else if (CharOperation.equals(typeName, nullableAnnotationName)) {
+							if (methodBinding.parameterNonNullness == null)
+								methodBinding.parameterNonNullness = new Boolean[numVisibleParams];
+							methodBinding.parameterNonNullness[j] = Boolean.FALSE;
+							break;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+void scanTypeForNullDefaultAnnotation(IBinaryType binaryType, PackageBinding packageBinding, BinaryTypeBinding binaryBinding) {
+	char[][] nonNullByDefaultAnnotationName = this.environment.getNonNullByDefaultAnnotationName();
+	if (nonNullByDefaultAnnotationName == null)
+		return; // not well-configured to use null annotations
+
+	IBinaryAnnotation[] annotations = binaryType.getAnnotations();
+	boolean isPackageInfo = CharOperation.equals(binaryBinding.sourceName(), TypeConstants.PACKAGE_INFO_NAME);
+	if (annotations != null) {
+		long annotationBit = 0L;
+		int nullness = NO_NULL_DEFAULT;
+		int length = annotations.length;
+		for (int i = 0; i < length; i++) {
+			char[] annotationTypeName = annotations[i].getTypeName();
+			if (annotationTypeName[0] != Util.C_RESOLVED)
+				continue;
+			char[][] typeName = CharOperation.splitOn('/', annotationTypeName, 1, annotationTypeName.length-1); // cut of leading 'L' and trailing ';'
+			if (CharOperation.equals(typeName, nonNullByDefaultAnnotationName)) {
+				IBinaryElementValuePair[] elementValuePairs = annotations[i].getElementValuePairs();
+				if (elementValuePairs != null && elementValuePairs.length == 1) {
+					Object value = elementValuePairs[0].getValue();
+					if (value instanceof BooleanConstant
+						&& !((BooleanConstant)value).booleanValue())
+					{
+						// parameter is 'false': this means we cancel defaults from outer scopes:
+						annotationBit = TagBits.AnnotationNullUnspecifiedByDefault;
+						nullness = NULL_UNSPECIFIED_BY_DEFAULT;
+						break;
+					}
+				}
+				annotationBit = TagBits.AnnotationNonNullByDefault;
+				nullness = NONNULL_BY_DEFAULT;
+				break;
+			}
+		}
+		if (annotationBit != 0L) {
+			binaryBinding.tagBits |= annotationBit;
+			if (isPackageInfo)
+				packageBinding.defaultNullness = nullness;
+			return;
+		}
+	}
+	if (isPackageInfo) {
+		// no default annotations found in package-info
+		packageBinding.defaultNullness = Binding.NULL_UNSPECIFIED_BY_DEFAULT;
+		return;
+	}
+	ReferenceBinding enclosingTypeBinding = binaryBinding.enclosingType;
+	if (enclosingTypeBinding != null) {
+		if ((enclosingTypeBinding.tagBits & TagBits.AnnotationNonNullByDefault) != 0) {
+			binaryBinding.tagBits |= TagBits.AnnotationNonNullByDefault;
+			return;
+		} else if ((enclosingTypeBinding.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0) {
+			binaryBinding.tagBits |= TagBits.AnnotationNullUnspecifiedByDefault;
+			return;
+		}
+	}
+	// no annotation found on the type or its enclosing types
+	// check the package-info for default annotation if not already done before
+	if (packageBinding.defaultNullness == Binding.NO_NULL_DEFAULT && !isPackageInfo) {
+		// this will scan the annotations in package-info
+		ReferenceBinding packageInfo = packageBinding.getType(TypeConstants.PACKAGE_INFO_NAME);
+		if (packageInfo == null) {
+			packageBinding.defaultNullness = Binding.NULL_UNSPECIFIED_BY_DEFAULT;
+		}
+	}
+	// no @NonNullByDefault at type level, check containing package:
+	switch (packageBinding.defaultNullness) {
+		case Binding.NONNULL_BY_DEFAULT : 
+			binaryBinding.tagBits |= TagBits.AnnotationNonNullByDefault;
+			break;
+		case Binding.NULL_UNSPECIFIED_BY_DEFAULT :
+			binaryBinding.tagBits |= TagBits.AnnotationNullUnspecifiedByDefault;
+			break;
+	}
+}
+
+/* Answer the receiver's superclass... null if the receiver is Object or an interface.
+*
+* NOTE: superclass of a binary type is resolved when needed
+*/
+public ReferenceBinding superclass() {
+	if ((this.tagBits & TagBits.HasUnresolvedSuperclass) == 0)
+		return this.superclass;
+
+	// finish resolving the type
+	this.superclass = (ReferenceBinding) resolveType(this.superclass, this.environment, true /* raw conversion */);
+	this.tagBits &= ~TagBits.HasUnresolvedSuperclass;
+	if (this.superclass.problemId() == ProblemReasons.NotFound) {
+		this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
+	} else {
+		// make super-type resolving recursive for propagating typeBits downwards
+		boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType;
+		this.environment.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164
+		try {
+			this.superclass.superclass();
+			this.superclass.superInterfaces();
+		} finally {
+			this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations;
+		}
+	}
+	this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
+	if ((this.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0) // avoid the side-effects of hasTypeBit()! 
+		this.typeBits |= applyCloseableWhitelists();
+	return this.superclass;
+}
+// NOTE: superInterfaces of binary types are resolved when needed
+public ReferenceBinding[] superInterfaces() {
+	if ((this.tagBits & TagBits.HasUnresolvedSuperinterfaces) == 0)
+		return this.superInterfaces;
+
+	for (int i = this.superInterfaces.length; --i >= 0;) {
+		this.superInterfaces[i] = (ReferenceBinding) resolveType(this.superInterfaces[i], this.environment, true /* raw conversion */);
+		if (this.superInterfaces[i].problemId() == ProblemReasons.NotFound) {
+			this.tagBits |= TagBits.HierarchyHasProblems; // propagate type inconsistency
+		} else {
+			// make super-type resolving recursive for propagating typeBits downwards
+			boolean wasToleratingMissingTypeProcessingAnnotations = this.environment.mayTolerateMissingType;
+			this.environment.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=360164
+			try {
+				this.superInterfaces[i].superclass();
+				this.superInterfaces[i].superInterfaces();
+			} finally {
+				this.environment.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations;
+			}	
+		}
+		this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits);
+	}
+	this.tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
+	return this.superInterfaces;
+}
+public TypeVariableBinding[] typeVariables() {
+ 	if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
+		return this.typeVariables;
+
+ 	for (int i = this.typeVariables.length; --i >= 0;)
+		this.typeVariables[i].resolve();
+	this.tagBits &= ~TagBits.HasUnresolvedTypeVariables;
+	return this.typeVariables;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+
+	if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
+	if (isPublic()) buffer.append("public "); //$NON-NLS-1$
+	if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
+	if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
+	if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
+	if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
+	if (isFinal()) buffer.append("final "); //$NON-NLS-1$
+
+	if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+	else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+	else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+	else buffer.append("interface "); //$NON-NLS-1$
+	buffer.append((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
+
+	if (this.typeVariables == null) {
+		buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
+	} else if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
+		buffer.append("<"); //$NON-NLS-1$
+		for (int i = 0, length = this.typeVariables.length; i < length; i++) {
+			if (i  > 0) buffer.append(", "); //$NON-NLS-1$
+			if (this.typeVariables[i] == null) {
+				buffer.append("NULL TYPE VARIABLE"); //$NON-NLS-1$
+				continue;
+			}
+			char[] varChars = this.typeVariables[i].toString().toCharArray();
+			buffer.append(varChars, 1, varChars.length - 2);
+		}
+		buffer.append(">"); //$NON-NLS-1$
+	}
+	buffer.append("\n\textends "); //$NON-NLS-1$
+	buffer.append((this.superclass != null) ? this.superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
+
+	if (this.superInterfaces != null) {
+		if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
+			buffer.append("\n\timplements : "); //$NON-NLS-1$
+			for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+				if (i  > 0)
+					buffer.append(", "); //$NON-NLS-1$
+				buffer.append((this.superInterfaces[i] != null) ? this.superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
+			}
+		}
+	} else {
+		buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
+	}
+
+	if (this.enclosingType != null) {
+		buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
+		buffer.append(this.enclosingType.debugName());
+	}
+
+	if (this.fields != null) {
+		if (this.fields != Binding.NO_FIELDS) {
+			buffer.append("\n/*   fields   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.fields.length; i < length; i++)
+				buffer.append((this.fields[i] != null) ? "\n" + this.fields[i].toString() : "\nNULL FIELD"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	} else {
+		buffer.append("NULL FIELDS"); //$NON-NLS-1$
+	}
+
+	if (this.methods != null) {
+		if (this.methods != Binding.NO_METHODS) {
+			buffer.append("\n/*   methods   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.methods.length; i < length; i++)
+				buffer.append((this.methods[i] != null) ? "\n" + this.methods[i].toString() : "\nNULL METHOD"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	} else {
+		buffer.append("NULL METHODS"); //$NON-NLS-1$
+	}
+
+	if (this.memberTypes != null) {
+		if (this.memberTypes != Binding.NO_MEMBER_TYPES) {
+			buffer.append("\n/*   members   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.memberTypes.length; i < length; i++)
+				buffer.append((this.memberTypes[i] != null) ? "\n" + this.memberTypes[i].toString() : "\nNULL TYPE"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	} else {
+		buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
+	}
+
+	buffer.append("\n\n\n"); //$NON-NLS-1$
+	return buffer.toString();
+}
+MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
+	return this.methods;
+}
+
+public FieldBinding[] unResolvedFields() {
+	return this.fields;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
new file mode 100644
index 0000000..284b580
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+public abstract class Binding {
+
+	// binding kinds
+	public static final int FIELD = ASTNode.Bit1;
+	public static final int LOCAL = ASTNode.Bit2;
+	public static final int VARIABLE = FIELD | LOCAL;
+	public static final int TYPE = ASTNode.Bit3;
+	public static final int METHOD = ASTNode.Bit4;
+	public static final int PACKAGE = ASTNode.Bit5;
+	public static final int IMPORT = ASTNode.Bit6;
+	public static final int ARRAY_TYPE = TYPE | ASTNode.Bit7;
+	public static final int BASE_TYPE = TYPE | ASTNode.Bit8;
+	public static final int PARAMETERIZED_TYPE = TYPE | ASTNode.Bit9;
+	public static final int WILDCARD_TYPE = TYPE | ASTNode.Bit10;
+	public static final int RAW_TYPE = TYPE | ASTNode.Bit11;
+	public static final int GENERIC_TYPE = TYPE | ASTNode.Bit12;
+	public static final int TYPE_PARAMETER = TYPE | ASTNode.Bit13;
+	public static final int INTERSECTION_TYPE = TYPE | ASTNode.Bit14;
+	// jsr 308
+	public static final int TYPE_USE = TYPE | ASTNode.Bit15;
+	public static final int INTERSECTION_CAST_TYPE = TYPE | ASTNode.Bit16;
+	public static final int POLY_TYPE = TYPE | ASTNode.Bit17;
+	
+	// In the unlikely event you add a new type binding, remember to update TypeBindingVisitor and Scope.substitute methods. 
+
+	// Shared binding collections
+	public static final TypeBinding[] NO_TYPES = new TypeBinding[0];
+	public static final TypeBinding[] NO_PARAMETERS = new TypeBinding[0];
+	public static final ReferenceBinding[] NO_EXCEPTIONS = new ReferenceBinding[0];
+	public static final ReferenceBinding[] ANY_EXCEPTION = new ReferenceBinding[] { null }; // special handler for all exceptions
+	public static final FieldBinding[] NO_FIELDS = new FieldBinding[0];
+	public static final MethodBinding[] NO_METHODS = new MethodBinding[0];
+	public static final ReferenceBinding[] NO_SUPERINTERFACES = new ReferenceBinding[0];
+	public static final ReferenceBinding[] NO_MEMBER_TYPES = new ReferenceBinding[0];
+	public static final TypeVariableBinding[] NO_TYPE_VARIABLES = new TypeVariableBinding[0];
+	public static final AnnotationBinding[] NO_ANNOTATIONS = new AnnotationBinding[0];
+	public static final ElementValuePair[] NO_ELEMENT_VALUE_PAIRS = new ElementValuePair[0];
+
+	public static final FieldBinding[] UNINITIALIZED_FIELDS = new FieldBinding[0];
+	public static final MethodBinding[] UNINITIALIZED_METHODS = new MethodBinding[0];
+	public static final ReferenceBinding[] UNINITIALIZED_REFERENCE_TYPES = new ReferenceBinding[0];
+
+	// Nullness defaults:
+	public static final int NO_NULL_DEFAULT = 0;
+	public static final int NULL_UNSPECIFIED_BY_DEFAULT = 1;
+	public static final int NONNULL_BY_DEFAULT = 2;
+
+	/*
+	* Answer the receiver's binding type from Binding.BindingID.
+	*/
+	public abstract int kind();
+	/*
+	 * Computes a key that uniquely identifies this binding.
+	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
+	 */
+	public char[] computeUniqueKey() {
+		return computeUniqueKey(true/*leaf*/);
+	}
+	/*
+	 * Computes a key that uniquely identifies this binding. Optionally include access flags.
+	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		return null;
+	}
+
+	/**
+	 * Compute the tagbits for standard annotations. For source types, these could require
+	 * lazily resolving corresponding annotation nodes, in case of forward references.
+	 * @see org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding#getAnnotationTagBits()
+	 */
+	public long getAnnotationTagBits() {
+		return 0;
+	}
+
+	/**
+	 * Compute the tag bits for @Deprecated annotations, avoiding resolving
+	 * entire annotation if not necessary.
+	 * @see org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding#initializeDeprecatedAnnotationTagBits()
+	 */
+	public void initializeDeprecatedAnnotationTagBits() {
+		// empty block
+	}
+
+	/* API
+	* Answer true if the receiver is not a problem binding
+	*/
+	public final boolean isValidBinding() {
+		return problemId() == ProblemReasons.NoError;
+	}
+	public boolean isVolatile() {
+		return false;
+	}
+	public boolean isParameter() {
+		return false;
+	}
+	/* API
+	* Answer the problem id associated with the receiver.
+	* NoError if the receiver is a valid binding.
+	* Note: a parameterized type or an array type are always valid, but may be formed of invalid pieces.
+	*/
+	// TODO (philippe) should rename into problemReason()
+	public int problemId() {
+		return ProblemReasons.NoError;
+	}
+	/* Answer a printable representation of the receiver.
+	*/
+	public abstract char[] readableName();
+	/* Shorter printable representation of the receiver (no qualified type)
+	 */
+	public char[] shortReadableName(){
+		return readableName();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
new file mode 100644
index 0000000..83bed12
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -0,0 +1,1230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 359334 - Analysis for resource leak warnings does not consider exceptions as method exit points
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
+ *								bug 370639 - [compiler][resource] restore the default for resource leak warnings
+ *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
+ *								bug 379784 - [compiler] "Method can be static" is not getting reported
+ *								bug 394768 - [compiler][resource] Incorrect resource leak warning when creating stream in conditional
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *     Keigo Imai - Contribution for  bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+public class BlockScope extends Scope {
+
+	// Local variable management
+	public LocalVariableBinding[] locals;
+	public int localIndex; // position for next variable
+	public int startIndex;	// start position in this scope - for ordering scopes vs. variables
+	public int offset; // for variable allocation throughout scopes
+	public int maxOffset; // for variable allocation throughout scopes
+
+	// finally scopes must be shifted behind respective try&catch scope(s) so as to avoid
+	// collisions of secret variables (return address, save value).
+	public BlockScope[] shiftScopes;
+
+	public Scope[] subscopes = new Scope[1]; // need access from code assist
+	public int subscopeCount = 0; // need access from code assist
+	// record the current case statement being processed (for entire switch case block).
+	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
+
+	public final static VariableBinding[] EmulationPathToImplicitThis = {};
+	public final static VariableBinding[] NoEnclosingInstanceInConstructorCall = {};
+
+	public final static VariableBinding[] NoEnclosingInstanceInStaticContext = {};
+
+public BlockScope(BlockScope parent) {
+	this(parent, true);
+}
+
+public BlockScope(BlockScope parent, boolean addToParentScope) {
+	this(Scope.BLOCK_SCOPE, parent);
+	this.locals = new LocalVariableBinding[5];
+	if (addToParentScope) parent.addSubscope(this);
+	this.startIndex = parent.localIndex;
+}
+
+public BlockScope(BlockScope parent, int variableCount) {
+	this(Scope.BLOCK_SCOPE, parent);
+	this.locals = new LocalVariableBinding[variableCount];
+	parent.addSubscope(this);
+	this.startIndex = parent.localIndex;
+}
+
+protected BlockScope(int kind, Scope parent) {
+	super(kind, parent);
+}
+
+/* Create the class scope & binding for the anonymous type.
+ */
+public final void addAnonymousType(TypeDeclaration anonymousType, ReferenceBinding superBinding) {
+	ClassScope anonymousClassScope = new ClassScope(this, anonymousType);
+	anonymousClassScope.buildAnonymousTypeBinding(
+		enclosingSourceType(),
+		superBinding);
+	
+	/* Tag any enclosing lambdas as instance capturing. Strictly speaking they need not be, unless the local/anonymous type references enclosing instance state.
+	   but the types themselves track enclosing types regardless of whether the state is accessed or not. This creates a mismatch in expectations in code generation
+	   time, if we choose to make the lambda method static. To keep things simple and avoid a messy rollback, we force the lambda to be an instance method under 
+	   this situation. However if per source, the lambda occurs in a static context, we would generate a static synthetic method.
+	*/
+	MethodScope methodScope = methodScope();
+	while (methodScope != null && methodScope.referenceContext instanceof LambdaExpression) {
+		LambdaExpression lambda = (LambdaExpression) methodScope.referenceContext;
+		if (!lambda.scope.isStatic) {
+			lambda.shouldCaptureInstance = true;
+		}
+		methodScope = methodScope.enclosingMethodScope();
+	}
+}
+
+/* Create the class scope & binding for the local type.
+ */
+public final void addLocalType(TypeDeclaration localType) {
+	ClassScope localTypeScope = new ClassScope(this, localType);
+	addSubscope(localTypeScope);
+	localTypeScope.buildLocalTypeBinding(enclosingSourceType());
+	
+	// See comment in addAnonymousType.
+	MethodScope methodScope = methodScope();
+	while (methodScope != null && methodScope.referenceContext instanceof LambdaExpression) {
+		LambdaExpression lambda = (LambdaExpression) methodScope.referenceContext;
+		if (!lambda.scope.isStatic) {
+			lambda.shouldCaptureInstance = true;
+		}
+		methodScope = methodScope.enclosingMethodScope();
+	}
+}
+
+/* Insert a local variable into a given scope, updating its position
+ * and checking there are not too many locals or arguments allocated.
+ */
+public final void addLocalVariable(LocalVariableBinding binding) {
+	checkAndSetModifiersForVariable(binding);
+	// insert local in scope
+	if (this.localIndex == this.locals.length)
+		System.arraycopy(
+			this.locals,
+			0,
+			(this.locals = new LocalVariableBinding[this.localIndex * 2]),
+			0,
+			this.localIndex);
+	this.locals[this.localIndex++] = binding;
+
+	// update local variable binding
+	binding.declaringScope = this;
+	binding.id = outerMostMethodScope().analysisIndex++;
+	// share the outermost method scope analysisIndex
+}
+
+public void addSubscope(Scope childScope) {
+	if (this.subscopeCount == this.subscopes.length)
+		System.arraycopy(
+			this.subscopes,
+			0,
+			(this.subscopes = new Scope[this.subscopeCount * 2]),
+			0,
+			this.subscopeCount);
+	this.subscopes[this.subscopeCount++] = childScope;
+}
+
+/**
+ * Answer true if the receiver is suitable for assigning final blank fields.
+ * in other words, it is inside an initializer, a constructor or a clinit
+ */
+public final boolean allowBlankFinalFieldAssignment(FieldBinding binding) {
+	if (enclosingReceiverType() != binding.declaringClass)
+		return false;
+
+	MethodScope methodScope = methodScope();
+	if (methodScope.isStatic != binding.isStatic())
+		return false;
+	return methodScope.isInsideInitializer() // inside initializer
+			|| ((AbstractMethodDeclaration) methodScope.referenceContext).isInitializationMethod(); // inside constructor or clinit
+}
+
+String basicToString(int tab) {
+	String newLine = "\n"; //$NON-NLS-1$
+	for (int i = tab; --i >= 0;)
+		newLine += "\t"; //$NON-NLS-1$
+
+	String s = newLine + "--- Block Scope ---"; //$NON-NLS-1$
+	newLine += "\t"; //$NON-NLS-1$
+	s += newLine + "locals:"; //$NON-NLS-1$
+	for (int i = 0; i < this.localIndex; i++)
+		s += newLine + "\t" + this.locals[i].toString(); //$NON-NLS-1$
+	s += newLine + "startIndex = " + this.startIndex; //$NON-NLS-1$
+	return s;
+}
+
+private void checkAndSetModifiersForVariable(LocalVariableBinding varBinding) {
+	int modifiers = varBinding.modifiers;
+	if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0 && varBinding.declaration != null){
+		problemReporter().duplicateModifierForVariable(varBinding.declaration, this instanceof MethodScope);
+	}
+	int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+
+	int unexpectedModifiers = ~ClassFileConstants.AccFinal;
+	if ((realModifiers & unexpectedModifiers) != 0 && varBinding.declaration != null){
+		problemReporter().illegalModifierForVariable(varBinding.declaration, this instanceof MethodScope);
+	}
+	varBinding.modifiers = modifiers;
+}
+
+/* Compute variable positions in scopes given an initial position offset
+ * ignoring unused local variables.
+ *
+ * No argument is expected here (ilocal is the first non-argument local of the outermost scope)
+ * Arguments are managed by the MethodScope method
+ */
+void computeLocalVariablePositions(int ilocal, int initOffset, CodeStream codeStream) {
+	this.offset = initOffset;
+	this.maxOffset = initOffset;
+
+	// local variable init
+	int maxLocals = this.localIndex;
+	boolean hasMoreVariables = ilocal < maxLocals;
+
+	// scope init
+	int iscope = 0, maxScopes = this.subscopeCount;
+	boolean hasMoreScopes = maxScopes > 0;
+
+	// iterate scopes and variables in parallel
+	while (hasMoreVariables || hasMoreScopes) {
+		if (hasMoreScopes
+			&& (!hasMoreVariables || (this.subscopes[iscope].startIndex() <= ilocal))) {
+			// consider subscope first
+			if (this.subscopes[iscope] instanceof BlockScope) {
+				BlockScope subscope = (BlockScope) this.subscopes[iscope];
+				int subOffset = subscope.shiftScopes == null ? this.offset : subscope.maxShiftedOffset();
+				subscope.computeLocalVariablePositions(0, subOffset, codeStream);
+				if (subscope.maxOffset > this.maxOffset)
+					this.maxOffset = subscope.maxOffset;
+			}
+			hasMoreScopes = ++iscope < maxScopes;
+		} else {
+
+			// consider variable first
+			LocalVariableBinding local = this.locals[ilocal]; // if no local at all, will be locals[ilocal]==null
+
+			// check if variable is actually used, and may force it to be preserved
+			boolean generateCurrentLocalVar = (local.useFlag > LocalVariableBinding.UNUSED && local.constant() == Constant.NotAConstant);
+
+			// do not report fake used variable
+			if (local.useFlag == LocalVariableBinding.UNUSED
+				&& (local.declaration != null) // unused (and non secret) local
+				&& ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { // declaration is reachable
+
+				if (!(local.declaration instanceof Argument)) // do not report unused catch arguments
+					problemReporter().unusedLocalVariable(local.declaration);
+			}
+
+			// could be optimized out, but does need to preserve unread variables ?
+			if (!generateCurrentLocalVar) {
+				if (local.declaration != null && compilerOptions().preserveAllLocalVariables) {
+					generateCurrentLocalVar = true; // force it to be preserved in the generated code
+					if (local.useFlag == LocalVariableBinding.UNUSED)
+						local.useFlag = LocalVariableBinding.USED;
+				}
+			}
+
+			// allocate variable
+			if (generateCurrentLocalVar) {
+
+				if (local.declaration != null) {
+					codeStream.record(local); // record user-defined local variables for attribute generation
+				}
+				// assign variable position
+				local.resolvedPosition = this.offset;
+
+				if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) {
+					this.offset += 2;
+				} else {
+					this.offset++;
+				}
+				if (this.offset > 0xFFFF) { // no more than 65535 words of locals
+					problemReporter().noMoreAvailableSpaceForLocal(
+						local,
+						local.declaration == null ? (ASTNode)methodScope().referenceContext : local.declaration);
+				}
+			} else {
+				local.resolvedPosition = -1; // not generated
+			}
+			hasMoreVariables = ++ilocal < maxLocals;
+		}
+	}
+	if (this.offset > this.maxOffset)
+		this.maxOffset = this.offset;
+}
+
+/*
+ *	Record the suitable binding denoting a synthetic field or constructor argument,
+ * mapping to the actual outer local variable in the scope context.
+ * Note that this may not need any effect, in case the outer local variable does not
+ * need to be emulated and can directly be used as is (using its back pointer to its
+ * declaring scope).
+ */
+public void emulateOuterAccess(LocalVariableBinding outerLocalVariable) {
+	BlockScope outerVariableScope = outerLocalVariable.declaringScope;
+	if (outerVariableScope == null)
+		return; // no need to further emulate as already inserted (val$this$0)
+	
+	int depth = 0;
+	Scope scope = this;
+	while (outerVariableScope != scope) {
+		switch(scope.kind) {
+			case CLASS_SCOPE:
+				depth++;
+				break;
+			case METHOD_SCOPE: 
+				if (scope.isLambdaScope()) {
+					LambdaExpression lambdaExpression = (LambdaExpression) scope.referenceContext();
+					lambdaExpression.addSyntheticArgument(outerLocalVariable);
+				}
+				break;
+		}
+		scope = scope.parent;
+	}
+	if (depth == 0) 
+		return;
+	
+	MethodScope currentMethodScope = methodScope();
+	if (outerVariableScope.methodScope() != currentMethodScope) {
+		NestedTypeBinding currentType = (NestedTypeBinding) enclosingSourceType();
+
+		//do nothing for member types, pre emulation was performed already
+		if (!currentType.isLocalType()) {
+			return;
+		}
+		// must also add a synthetic field if we're not inside a constructor
+		if (!currentMethodScope.isInsideInitializerOrConstructor()) {
+			currentType.addSyntheticArgumentAndField(outerLocalVariable);
+		} else {
+			currentType.addSyntheticArgument(outerLocalVariable);
+		}
+	}
+}
+
+/* Note that it must never produce a direct access to the targetEnclosingType,
+ * but instead a field sequence (this$2.this$1.this$0) so as to handle such a test case:
+ *
+ * class XX {
+ *	void foo() {
+ *		class A {
+ *			class B {
+ *				class C {
+ *					boolean foo() {
+ *						return (Object) A.this == (Object) B.this;
+ *					}
+ *				}
+ *			}
+ *		}
+ *		new A().new B().new C();
+ *	}
+ * }
+ * where we only want to deal with ONE enclosing instance for C (could not figure out an A for C)
+ */
+public final ReferenceBinding findLocalType(char[] name) {
+	long compliance = compilerOptions().complianceLevel;
+	for (int i = this.subscopeCount-1; i >= 0; i--) {
+		if (this.subscopes[i] instanceof ClassScope) {
+			LocalTypeBinding sourceType = (LocalTypeBinding)((ClassScope) this.subscopes[i]).referenceContext.binding;
+			// from 1.4 on, local types should not be accessed across switch case blocks (52221)
+			if (compliance >= ClassFileConstants.JDK1_4 && sourceType.enclosingCase != null) {
+				if (!isInsideCase(sourceType.enclosingCase)) {
+					continue;
+				}
+			}
+			if (CharOperation.equals(sourceType.sourceName(), name))
+				return sourceType;
+		}
+	}
+	return null;
+}
+
+/**
+ * Returns all declarations of most specific locals containing a given position in their source range.
+ * This code does not recurse in nested types.
+ * Returned array may have null values at trailing indexes.
+ */
+public LocalDeclaration[] findLocalVariableDeclarations(int position) {
+	// local variable init
+	int ilocal = 0, maxLocals = this.localIndex;
+	boolean hasMoreVariables = maxLocals > 0;
+	LocalDeclaration[] localDeclarations = null;
+	int declPtr = 0;
+
+	// scope init
+	int iscope = 0, maxScopes = this.subscopeCount;
+	boolean hasMoreScopes = maxScopes > 0;
+
+	// iterate scopes and variables in parallel
+	while (hasMoreVariables || hasMoreScopes) {
+		if (hasMoreScopes
+			&& (!hasMoreVariables || (this.subscopes[iscope].startIndex() <= ilocal))) {
+			// consider subscope first
+			Scope subscope = this.subscopes[iscope];
+			if (subscope.kind == Scope.BLOCK_SCOPE) { // do not dive in nested types
+				localDeclarations = ((BlockScope)subscope).findLocalVariableDeclarations(position);
+				if (localDeclarations != null) {
+					return localDeclarations;
+				}
+			}
+			hasMoreScopes = ++iscope < maxScopes;
+		} else {
+			// consider variable first
+			LocalVariableBinding local = this.locals[ilocal]; // if no local at all, will be locals[ilocal]==null
+			if (local != null) {
+				LocalDeclaration localDecl = local.declaration;
+				if (localDecl != null) {
+					if (localDecl.declarationSourceStart <= position) {
+						if (position <= localDecl.declarationSourceEnd) {
+							if (localDeclarations == null) {
+								localDeclarations = new LocalDeclaration[maxLocals];
+							}
+							localDeclarations[declPtr++] = localDecl;
+						}
+					} else {
+						return localDeclarations;
+					}
+				}
+			}
+			hasMoreVariables = ++ilocal < maxLocals;
+			if (!hasMoreVariables && localDeclarations != null) {
+				return localDeclarations;
+			}
+		}
+	}
+	return null;
+}
+
+public LocalVariableBinding findVariable(char[] variableName) {
+	int varLength = variableName.length;
+	for (int i = this.localIndex-1; i >= 0; i--) { // lookup backward to reach latest additions first
+		LocalVariableBinding local;
+		char[] localName;
+		if ((localName = (local = this.locals[i]).name).length == varLength && CharOperation.equals(localName, variableName))
+			return local;
+	}
+	return null;
+}
+
+/* API
+ * flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE.
+ * Only bindings corresponding to the mask will be answered.
+ *
+ *	if the VARIABLE mask is set then
+ *		If the first name provided is a field (or local) then the field (or local) is answered
+ *		Otherwise, package names and type names are consumed until a field is found.
+ *		In this case, the field is answered.
+ *
+ *	if the TYPE mask is set,
+ *		package names and type names are consumed until the end of the input.
+ *		Only if all of the input is consumed is the type answered
+ *
+ *	All other conditions are errors, and a problem binding is returned.
+ *
+ *	NOTE: If a problem binding is returned, senders should extract the compound name
+ *	from the binding & not assume the problem applies to the entire compoundName.
+ *
+ *	The VARIABLE mask has precedence over the TYPE mask.
+ *
+ *	InvocationSite implements
+ *		isSuperAccess(); this is used to determine if the discovered field is visible.
+ *		setFieldIndex(int); this is used to record the number of names that were consumed.
+ *
+ *	For example, getBinding({"foo","y","q", VARIABLE, site) will answer
+ *	the binding for the field or local named "foo" (or an error binding if none exists).
+ *	In addition, setFieldIndex(1) will be sent to the invocation site.
+ *	If a type named "foo" exists, it will not be detected (and an error binding will be answered)
+ *
+ *	IMPORTANT NOTE: This method is written under the assumption that compoundName is longer than length 1.
+ */
+public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite, boolean needResolve) {
+	Binding binding = getBinding(compoundName[0], mask | Binding.TYPE | Binding.PACKAGE, invocationSite, needResolve);
+	invocationSite.setFieldIndex(1);
+	if (binding instanceof VariableBinding) return binding;
+	CompilationUnitScope unitScope = compilationUnitScope();
+	// in the problem case, we want to ensure we record the qualified dependency in case a type is added
+	// and we do not know that its package was also added (can happen with CompilationParticipants)
+	unitScope.recordQualifiedReference(compoundName);
+	if (!binding.isValidBinding()) return binding;
+
+	int length = compoundName.length;
+	int currentIndex = 1;
+	foundType : if (binding instanceof PackageBinding) {
+		PackageBinding packageBinding = (PackageBinding) binding;
+		while (currentIndex < length) {
+			unitScope.recordReference(packageBinding.compoundName, compoundName[currentIndex]);
+			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
+			invocationSite.setFieldIndex(currentIndex);
+			if (binding == null) {
+				if (currentIndex == length) {
+					// must be a type if its the last name, otherwise we have no idea if its a package or type
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						null,
+						ProblemReasons.NotFound);
+				}
+				return new ProblemBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					ProblemReasons.NotFound);
+			}
+			if (binding instanceof ReferenceBinding) {
+				if (!binding.isValidBinding())
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+						binding.problemId());
+				if (!((ReferenceBinding) binding).canBeSeenBy(this))
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						(ReferenceBinding) binding,
+						ProblemReasons.NotVisible);
+				break foundType;
+			}
+			packageBinding = (PackageBinding) binding;
+		}
+
+		// It is illegal to request a PACKAGE from this method.
+		return new ProblemReferenceBinding(
+			CharOperation.subarray(compoundName, 0, currentIndex),
+			null,
+			ProblemReasons.NotFound);
+	}
+
+	// know binding is now a ReferenceBinding
+	ReferenceBinding referenceBinding = (ReferenceBinding) binding;
+	binding = environment().convertToRawType(referenceBinding, false /*do not force conversion of enclosing types*/);
+	if (invocationSite instanceof ASTNode) {
+		ASTNode invocationNode = (ASTNode) invocationSite;
+		if (invocationNode.isTypeUseDeprecated(referenceBinding, this)) {
+			problemReporter().deprecatedType(referenceBinding, invocationNode);
+		}
+	}
+	Binding problemFieldBinding = null;
+	while (currentIndex < length) {
+		referenceBinding = (ReferenceBinding) binding;
+		char[] nextName = compoundName[currentIndex++];
+		invocationSite.setFieldIndex(currentIndex);
+		invocationSite.setActualReceiverType(referenceBinding);
+		if ((mask & Binding.FIELD) != 0 && (binding = findField(referenceBinding, nextName, invocationSite, true /*resolve*/)) != null) {
+			if (binding.isValidBinding()) {
+				break; // binding is now a field
+			}
+			problemFieldBinding = new ProblemFieldBinding(
+				((ProblemFieldBinding)binding).closestMatch,
+				((ProblemFieldBinding)binding).declaringClass,
+				CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+				binding.problemId()); 
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317858 : If field is inaccessible,
+			// don't give up yet, continue to look for a visible member type 
+			if (binding.problemId() != ProblemReasons.NotVisible) {  
+				return problemFieldBinding;
+			}
+		}
+		if ((binding = findMemberType(nextName, referenceBinding)) == null) {
+			if (problemFieldBinding != null) {
+				return problemFieldBinding;
+			}
+			if ((mask & Binding.FIELD) != 0) {
+				return new ProblemFieldBinding(
+						null,
+						referenceBinding,
+						nextName,
+						ProblemReasons.NotFound);
+			} else if ((mask & Binding.VARIABLE) != 0) {
+				return new ProblemBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					referenceBinding,
+					ProblemReasons.NotFound);
+			}
+			return new ProblemReferenceBinding(
+				CharOperation.subarray(compoundName, 0, currentIndex),
+				referenceBinding,
+				ProblemReasons.NotFound);
+		}
+		// binding is a ReferenceBinding
+		if (!binding.isValidBinding()) {
+			if (problemFieldBinding != null) {
+				return problemFieldBinding;
+			}
+			return new ProblemReferenceBinding(
+				CharOperation.subarray(compoundName, 0, currentIndex),
+				(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+				binding.problemId());
+		}
+		if (invocationSite instanceof ASTNode) {
+			referenceBinding = (ReferenceBinding) binding;
+			ASTNode invocationNode = (ASTNode) invocationSite;
+			if (invocationNode.isTypeUseDeprecated(referenceBinding, this)) {
+				problemReporter().deprecatedType(referenceBinding, invocationNode);
+			}
+		}
+	}
+	if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) {
+		// was looking for a field and found a field
+		FieldBinding field = (FieldBinding) binding;
+		if (!field.isStatic())
+			return new ProblemFieldBinding(
+				field,
+				field.declaringClass,
+				CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+				ProblemReasons.NonStaticReferenceInStaticContext);
+		// Since a qualified reference must be for a static member, it won't affect static-ness of the enclosing method, 
+		// so we don't have to call resetEnclosingMethodStaticFlag() in this case
+		return binding;
+	}
+	if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) {
+		// was looking for a type and found a type
+		return binding;
+	}
+
+	// handle the case when a field or type was asked for but we resolved the compoundName to a type or field
+	return new ProblemBinding(
+		CharOperation.subarray(compoundName, 0, currentIndex),
+		ProblemReasons.NotFound);
+}
+
+// Added for code assist... NOT Public API
+public final Binding getBinding(char[][] compoundName, InvocationSite invocationSite) {
+	int currentIndex = 0;
+	int length = compoundName.length;
+	Binding binding =
+		getBinding(
+			compoundName[currentIndex++],
+			Binding.VARIABLE | Binding.TYPE | Binding.PACKAGE,
+			invocationSite,
+			true /*resolve*/);
+	if (!binding.isValidBinding())
+		return binding;
+
+	foundType : if (binding instanceof PackageBinding) {
+		while (currentIndex < length) {
+			PackageBinding packageBinding = (PackageBinding) binding;
+			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
+			if (binding == null) {
+				if (currentIndex == length) {
+					// must be a type if its the last name, otherwise we have no idea if its a package or type
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						null,
+						ProblemReasons.NotFound);
+				}
+				return new ProblemBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					ProblemReasons.NotFound);
+			}
+			if (binding instanceof ReferenceBinding) {
+				if (!binding.isValidBinding())
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+						binding.problemId());
+				if (!((ReferenceBinding) binding).canBeSeenBy(this))
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						(ReferenceBinding) binding,
+						ProblemReasons.NotVisible);
+				break foundType;
+			}
+		}
+		return binding;
+	}
+
+	foundField : if (binding instanceof ReferenceBinding) {
+		while (currentIndex < length) {
+			ReferenceBinding typeBinding = (ReferenceBinding) binding;
+			char[] nextName = compoundName[currentIndex++];
+			TypeBinding receiverType = typeBinding.capture(this, invocationSite.sourceEnd());
+			if ((binding = findField(receiverType, nextName, invocationSite, true /*resolve*/)) != null) {
+				if (!binding.isValidBinding()) {
+					return new ProblemFieldBinding(
+						(FieldBinding) binding,
+						((FieldBinding) binding).declaringClass,
+						CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+						binding.problemId());
+				}
+				if (!((FieldBinding) binding).isStatic())
+					return new ProblemFieldBinding(
+						(FieldBinding) binding,
+						((FieldBinding) binding).declaringClass,
+						CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+						ProblemReasons.NonStaticReferenceInStaticContext);
+				break foundField; // binding is now a field
+			}
+			if ((binding = findMemberType(nextName, typeBinding)) == null) {
+				return new ProblemBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					typeBinding,
+					ProblemReasons.NotFound);
+			}
+			if (!binding.isValidBinding()) {
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+					binding.problemId());
+			}
+		}
+		return binding;
+	}
+
+	VariableBinding variableBinding = (VariableBinding) binding;
+	while (currentIndex < length) {
+		TypeBinding typeBinding = variableBinding.type;
+		if (typeBinding == null) {
+			return new ProblemFieldBinding(
+				null,
+				null,
+				CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+				ProblemReasons.NotFound);
+		}
+		TypeBinding receiverType = typeBinding.capture(this, invocationSite.sourceEnd());
+		variableBinding = findField(receiverType, compoundName[currentIndex++], invocationSite, true /*resolve*/);
+		if (variableBinding == null) {
+			return new ProblemFieldBinding(
+				null,
+				receiverType instanceof ReferenceBinding ? (ReferenceBinding) receiverType : null,
+				CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+				ProblemReasons.NotFound);
+		}
+		if (!variableBinding.isValidBinding())
+			return variableBinding;
+	}
+	return variableBinding;
+}
+
+/*
+ * This retrieves the argument that maps to an enclosing instance of the suitable type,
+ * 	if not found then answers nil -- do not create one
+ *
+ *		#implicitThis		  	 			: the implicit this will be ok
+ *		#((arg) this$n)						: available as a constructor arg
+ * 		#((arg) this$n ... this$p) 			: available as as a constructor arg + a sequence of fields
+ * 		#((fieldDescr) this$n ... this$p) 	: available as a sequence of fields
+ * 		nil 		 											: not found
+ *
+ * 	Note that this algorithm should answer the shortest possible sequence when
+ * 		shortcuts are available:
+ * 				this$0 . this$0 . this$0
+ * 		instead of
+ * 				this$2 . this$1 . this$0 . this$1 . this$0
+ * 		thus the code generation will be more compact and runtime faster
+ */
+public VariableBinding[] getEmulationPath(LocalVariableBinding outerLocalVariable) {
+	MethodScope currentMethodScope = methodScope();
+	SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType();
+
+	// identity check
+	BlockScope variableScope = outerLocalVariable.declaringScope;
+	if (variableScope == null /*val$this$0*/ || currentMethodScope == variableScope.methodScope()) {
+		return new VariableBinding[] { outerLocalVariable };
+		// implicit this is good enough
+	}
+	if (currentMethodScope.isLambdaScope()) {
+		LambdaExpression lambda = (LambdaExpression) currentMethodScope.referenceContext;
+		SyntheticArgumentBinding syntheticArgument;
+		if ((syntheticArgument = lambda.getSyntheticArgument(outerLocalVariable)) != null) {
+			return new VariableBinding[] { syntheticArgument };
+		}
+	}
+	// use synthetic constructor arguments if possible
+	if (currentMethodScope.isInsideInitializerOrConstructor()
+		&& (sourceType.isNestedType())) {
+		SyntheticArgumentBinding syntheticArg;
+		if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(outerLocalVariable)) != null) {
+			return new VariableBinding[] { syntheticArg };
+		}
+	}
+	// use a synthetic field then
+	if (!currentMethodScope.isStatic) {
+		FieldBinding syntheticField;
+		if ((syntheticField = sourceType.getSyntheticField(outerLocalVariable)) != null) {
+			return new VariableBinding[] { syntheticField };
+		}
+	}
+	return null;
+}
+
+/*
+ * This retrieves the argument that maps to an enclosing instance of the suitable type,
+ * 	if not found then answers nil -- do not create one
+ *
+ *		#implicitThis		  	 											:  the implicit this will be ok
+ *		#((arg) this$n)													: available as a constructor arg
+ * 	#((arg) this$n access$m... access$p) 		: available as as a constructor arg + a sequence of synthetic accessors to synthetic fields
+ * 	#((fieldDescr) this$n access#m... access$p)	: available as a first synthetic field + a sequence of synthetic accessors to synthetic fields
+ * 	null 		 															: not found
+ *	jls 15.9.2 + http://www.ergnosis.com/java-spec-report/java-language/jls-8.8.5.1-d.html
+ */
+public Object[] getEmulationPath(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean denyEnclosingArgInConstructorCall) {
+	MethodScope currentMethodScope = methodScope();
+	SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType();
+
+	// use 'this' if possible
+	if (!currentMethodScope.isStatic && !currentMethodScope.isConstructorCall) {
+		if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) {
+			return BlockScope.EmulationPathToImplicitThis; // implicit this is good enough
+		}
+	}
+	if (!sourceType.isNestedType() || sourceType.isStatic()) { // no emulation from within non-inner types
+		if (currentMethodScope.isConstructorCall) {
+			return BlockScope.NoEnclosingInstanceInConstructorCall;
+		} else if (currentMethodScope.isStatic){
+			return BlockScope.NoEnclosingInstanceInStaticContext;
+		}
+		return null;
+	}
+	boolean insideConstructor = currentMethodScope.isInsideInitializerOrConstructor();
+	// use synthetic constructor arguments if possible
+	if (insideConstructor) {
+		SyntheticArgumentBinding syntheticArg;
+		if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(targetEnclosingType, onlyExactMatch, currentMethodScope.isConstructorCall)) != null) {
+			boolean isAnonymousAndHasEnclosing = sourceType.isAnonymousType()
+				&& sourceType.scope.referenceContext.allocation.enclosingInstance != null;
+			// reject allocation and super constructor call
+			if (denyEnclosingArgInConstructorCall
+					&& currentMethodScope.isConstructorCall
+					&& !isAnonymousAndHasEnclosing
+					&& (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeOriginatingFrom(targetEnclosingType) != null))) {
+				return BlockScope.NoEnclosingInstanceInConstructorCall;
+			}
+			return new Object[] { syntheticArg };
+		}
+	}
+
+	// use a direct synthetic field then
+	if (currentMethodScope.isStatic) {
+		return BlockScope.NoEnclosingInstanceInStaticContext;
+	}
+	if (sourceType.isAnonymousType()) {
+		ReferenceBinding enclosingType = sourceType.enclosingType();
+		if (enclosingType.isNestedType()) {
+			NestedTypeBinding nestedEnclosingType = (NestedTypeBinding) enclosingType;
+			SyntheticArgumentBinding enclosingArgument = nestedEnclosingType.getSyntheticArgument(nestedEnclosingType.enclosingType(), onlyExactMatch, currentMethodScope.isConstructorCall);
+			if (enclosingArgument != null) {
+				FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument);
+				if (syntheticField != null) {
+					if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeOriginatingFrom(targetEnclosingType) != null))
+						return new Object[] { syntheticField };
+				}
+			}
+		}
+	}
+	FieldBinding syntheticField = sourceType.getSyntheticField(targetEnclosingType, onlyExactMatch);
+	if (syntheticField != null) {
+		if (currentMethodScope.isConstructorCall){
+			return BlockScope.NoEnclosingInstanceInConstructorCall;
+		}
+		return new Object[] { syntheticField };
+	}
+
+	// could be reached through a sequence of enclosing instance link (nested members)
+	Object[] path = new Object[2]; // probably at least 2 of them
+	ReferenceBinding currentType = sourceType.enclosingType();
+	if (insideConstructor) {
+		path[0] = ((NestedTypeBinding) sourceType).getSyntheticArgument(currentType, onlyExactMatch, currentMethodScope.isConstructorCall);
+	} else {
+		if (currentMethodScope.isConstructorCall){
+			return BlockScope.NoEnclosingInstanceInConstructorCall;
+		}
+		path[0] = sourceType.getSyntheticField(currentType, onlyExactMatch);
+	}
+	if (path[0] != null) { // keep accumulating
+
+		int count = 1;
+		ReferenceBinding currentEnclosingType;
+		while ((currentEnclosingType = currentType.enclosingType()) != null) {
+
+			//done?
+			if (currentType == targetEnclosingType
+				|| (!onlyExactMatch && currentType.findSuperTypeOriginatingFrom(targetEnclosingType) != null))	break;
+
+			if (currentMethodScope != null) {
+				currentMethodScope = currentMethodScope.enclosingMethodScope();
+				if (currentMethodScope != null && currentMethodScope.isConstructorCall){
+					return BlockScope.NoEnclosingInstanceInConstructorCall;
+				}
+				if (currentMethodScope != null && currentMethodScope.isStatic){
+					return BlockScope.NoEnclosingInstanceInStaticContext;
+				}
+			}
+
+			syntheticField = ((NestedTypeBinding) currentType).getSyntheticField(currentEnclosingType, onlyExactMatch);
+			if (syntheticField == null) break;
+
+			// append inside the path
+			if (count == path.length) {
+				System.arraycopy(path, 0, (path = new Object[count + 1]), 0, count);
+			}
+			// private access emulation is necessary since synthetic field is private
+			path[count++] = ((SourceTypeBinding) syntheticField.declaringClass).addSyntheticMethod(syntheticField, true/*read*/, false /*not super access*/);
+			currentType = currentEnclosingType;
+		}
+		if (currentType == targetEnclosingType
+			|| (!onlyExactMatch && currentType.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) {
+			return path;
+		}
+	}
+	return null;
+}
+
+/* Answer true if the variable name already exists within the receiver's scope.
+ */
+public final boolean isDuplicateLocalVariable(char[] name) {
+	BlockScope current = this;
+	while (true) {
+		for (int i = 0; i < this.localIndex; i++) {
+			if (CharOperation.equals(name, current.locals[i].name))
+				return true;
+		}
+		if (current.kind != Scope.BLOCK_SCOPE) return false;
+		current = (BlockScope)current.parent;
+	}
+}
+
+public int maxShiftedOffset() {
+	int max = -1;
+	if (this.shiftScopes != null){
+		for (int i = 0, length = this.shiftScopes.length; i < length; i++){
+			if (this.shiftScopes[i] != null) {
+				int subMaxOffset = this.shiftScopes[i].maxOffset;
+				if (subMaxOffset > max) max = subMaxOffset;
+			}
+		}
+	}
+	return max;
+}
+
+/**
+ * Returns true if the context requires to check initialization of final blank fields.
+ * in other words, it is inside an initializer, a constructor or a clinit
+ */
+public final boolean needBlankFinalFieldInitializationCheck(FieldBinding binding) {
+	boolean isStatic = binding.isStatic();
+	ReferenceBinding fieldDeclaringClass = binding.declaringClass;
+	// loop in enclosing context, until reaching the field declaring context
+	MethodScope methodScope = methodScope();
+	while (methodScope != null) {
+		if (methodScope.isStatic != isStatic)
+			return false;
+		if (!methodScope.isInsideInitializer() // inside initializer
+				&& !((AbstractMethodDeclaration) methodScope.referenceContext).isInitializationMethod()) { // inside constructor or clinit
+			return false; // found some non-initializer context
+		}
+		ReferenceBinding enclosingType = methodScope.enclosingReceiverType();
+		if (enclosingType == fieldDeclaringClass) {
+			return true; // found the field context, no need to check any further
+		}
+		if (!enclosingType.erasure().isAnonymousType()) {
+			return false; // only check inside anonymous type
+		}
+		methodScope = methodScope.enclosingMethodScope();
+	}
+	return false;
+}
+
+/* Answer the problem reporter to use for raising new problems.
+ *
+ * Note that as a side-effect, this updates the current reference context
+ * (unit, type or method) in case the problem handler decides it is necessary
+ * to abort.
+ */
+public ProblemReporter problemReporter() {
+	return methodScope().problemReporter();
+}
+
+/*
+ * Code responsible to request some more emulation work inside the invocation type, so as to supply
+ * correct synthetic arguments to any allocation of the target type.
+ */
+public void propagateInnerEmulation(ReferenceBinding targetType, boolean isEnclosingInstanceSupplied) {
+	// no need to propagate enclosing instances, they got eagerly allocated already.
+
+	SyntheticArgumentBinding[] syntheticArguments;
+	if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) {
+		for (int i = 0, max = syntheticArguments.length; i < max; i++) {
+			SyntheticArgumentBinding syntheticArg = syntheticArguments[i];
+			// need to filter out the one that could match a supplied enclosing instance
+			if (!(isEnclosingInstanceSupplied
+				&& (syntheticArg.type == targetType.enclosingType()))) {
+				emulateOuterAccess(syntheticArg.actualOuterLocalVariable);
+			}
+		}
+	}
+}
+
+/* Answer the reference type of this scope.
+ *
+ * It is the nearest enclosing type of this scope.
+ */
+public TypeDeclaration referenceType() {
+	return methodScope().referenceType();
+}
+
+/*
+ * Answer the index of this scope relatively to its parent.
+ * For method scope, answers -1 (not a classScope relative position)
+ */
+public int scopeIndex() {
+	if (this instanceof MethodScope) return -1;
+	BlockScope parentScope = (BlockScope)this.parent;
+	Scope[] parentSubscopes = parentScope.subscopes;
+	for (int i = 0, max = parentScope.subscopeCount; i < max; i++) {
+		if (parentSubscopes[i] == this) return i;
+	}
+	return -1;
+}
+
+// start position in this scope - for ordering scopes vs. variables
+int startIndex() {
+	return this.startIndex;
+}
+
+public String toString() {
+	return toString(0);
+}
+
+public String toString(int tab) {
+	String s = basicToString(tab);
+	for (int i = 0; i < this.subscopeCount; i++)
+		if (this.subscopes[i] instanceof BlockScope)
+			s += ((BlockScope) this.subscopes[i]).toString(tab + 1) + "\n"; //$NON-NLS-1$
+	return s;
+}
+
+private List trackingVariables; // can be null if no resources are tracked
+/** Used only during analyseCode and only for checking if a resource was closed in a finallyBlock. */
+public FlowInfo finallyInfo;
+/**
+ * Register a tracking variable and compute its id.
+ */
+public int registerTrackingVariable(FakedTrackingVariable fakedTrackingVariable) {
+	if (this.trackingVariables == null)
+		this.trackingVariables = new ArrayList(3);
+	this.trackingVariables.add(fakedTrackingVariable);
+	MethodScope outerMethodScope = outerMostMethodScope();
+	return outerMethodScope.analysisIndex++;
+}
+/** When are no longer interested in this tracking variable - remove it. */
+public void removeTrackingVar(FakedTrackingVariable trackingVariable) {
+	if (trackingVariable.innerTracker != null) {
+		removeTrackingVar(trackingVariable.innerTracker);
+		trackingVariable.innerTracker = null;
+	}
+	if (this.trackingVariables != null)
+		if (this.trackingVariables.remove(trackingVariable))
+			return;
+	if (this.parent instanceof BlockScope)
+		((BlockScope)this.parent).removeTrackingVar(trackingVariable);
+}
+/** Unregister a wrapper resource without affecting its inner. */
+public void pruneWrapperTrackingVar(FakedTrackingVariable trackingVariable) {
+	this.trackingVariables.remove(trackingVariable);
+}
+/**
+ * At the end of a block check the closing-status of all tracked closeables that are declared in this block.
+ * Also invoked when entering unreachable code.
+ */
+public void checkUnclosedCloseables(FlowInfo flowInfo, FlowContext flowContext, ASTNode location, BlockScope locationScope) {
+	if (!compilerOptions().analyseResourceLeaks) return;
+	if (this.trackingVariables == null) {
+		// at a method return we also consider enclosing scopes
+		if (location != null && this.parent instanceof BlockScope)
+			((BlockScope) this.parent).checkUnclosedCloseables(flowInfo, flowContext, location, locationScope);
+		return;
+	}
+	if (location != null && flowInfo.reachMode() != 0) return;
+
+	FakedTrackingVariable returnVar = (location instanceof ReturnStatement) ?
+			FakedTrackingVariable.getCloseTrackingVariable(((ReturnStatement)location).expression, flowInfo, flowContext) : null;
+
+	Set varSet = new HashSet(this.trackingVariables);
+	FakedTrackingVariable trackingVar;
+	// pick one outer-most variable from the set at a time
+	while ((trackingVar = FakedTrackingVariable.pickVarForReporting(varSet, this, location != null)) != null) {
+
+		if (returnVar != null && trackingVar.isResourceBeingReturned(returnVar)) {
+			continue;
+		}
+
+		if (location != null && trackingVar.hasDefinitelyNoResource(flowInfo)) {
+			continue; // reporting against a specific location, there is no resource at this flow, don't complain
+		}
+
+		if (location != null && flowContext != null && flowContext.recordExitAgainstResource(this, flowInfo, trackingVar, location)) {
+			continue; // handled by the flow context
+		}
+
+		// compute the most specific null status for this resource,
+		int status = trackingVar.findMostSpecificStatus(flowInfo, this, locationScope);
+		
+		if (status == FlowInfo.NULL) {
+			// definitely unclosed: highest priority
+			reportResourceLeak(trackingVar, location, status);
+			continue;
+		}
+		if (location == null) // at end of block and not definitely unclosed
+		{
+			// problems at specific locations: medium priority
+			if (trackingVar.reportRecordedErrors(this, status)) // ... report previously recorded errors
+				continue;
+		} 
+		if (status == FlowInfo.POTENTIALLY_NULL) {
+			// potentially unclosed: lower priority
+			reportResourceLeak(trackingVar, location, status);
+		} else if (status == FlowInfo.NON_NULL) {
+			// properly closed but not managed by t-w-r: lowest priority 
+			if (environment().globalOptions.complianceLevel >= ClassFileConstants.JDK1_7)
+				trackingVar.reportExplicitClosing(problemReporter());
+		}
+	}
+	if (location == null) {
+		// when leaving this block dispose off all tracking variables:
+		for (int i=0; i<this.localIndex; i++)
+			this.locals[i].closeTracker = null;		
+		this.trackingVariables = null;
+	} else {
+		int size = this.trackingVariables.size();
+		for (int i=0; i<size; i++) {
+			FakedTrackingVariable tracker = (FakedTrackingVariable) this.trackingVariables.get(i);
+			tracker.resetReportingBits();
+		}
+	}
+}
+
+private void reportResourceLeak(FakedTrackingVariable trackingVar, ASTNode location, int nullStatus) {
+	if (location != null)
+		trackingVar.recordErrorLocation(location, nullStatus);
+	else
+		trackingVar.reportError(problemReporter(), null, nullStatus);
+}
+
+/** 
+ * If one branch of an if-else closes any AutoCloseable resource, and if the same
+ * resource is known to be null on the other branch mark it as closed, too,
+ * so that merging both branches indicates that the resource is always closed.
+ * Example:
+ *	FileReader fr1 = null;
+ *	try {\n" +
+ *      fr1 = new FileReader(someFile);" + 
+ *		fr1.read(buf);\n" + 
+ *	} finally {\n" + 
+ *		if (fr1 != null)\n" +
+ *           try {\n" +
+ *               fr1.close();\n" +
+ *           } catch (IOException e) {
+ *              // do nothing 
+ *           }
+ *      // after this if statement fr1 is definitely not leaked 
+ *	}
+ */
+public void correlateTrackingVarsIfElse(FlowInfo thenFlowInfo, FlowInfo elseFlowInfo) {
+	if (this.trackingVariables != null) {
+		int trackVarCount = this.trackingVariables.size();
+		for (int i=0; i<trackVarCount; i++) {
+			FakedTrackingVariable trackingVar = (FakedTrackingVariable) this.trackingVariables.get(i);
+			if (trackingVar.originalBinding == null)
+				continue;
+			if (   thenFlowInfo.isDefinitelyNonNull(trackingVar.binding)			// closed in then branch
+				&& elseFlowInfo.isDefinitelyNull(trackingVar.originalBinding))		// null in else branch
+			{
+				elseFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
+			}
+			else if (   elseFlowInfo.isDefinitelyNonNull(trackingVar.binding)		// closed in else branch
+					 && thenFlowInfo.isDefinitelyNull(trackingVar.originalBinding))	// null in then branch
+			{
+				thenFlowInfo.markAsDefinitelyNonNull(trackingVar.binding);			// -> always closed
+			}
+			else {
+				if (thenFlowInfo == FlowInfo.DEAD_END || elseFlowInfo == FlowInfo.DEAD_END)
+					continue; // short cut
+
+				for (int j=i+1; j<trackVarCount; j++) {
+					FakedTrackingVariable var2 = ((FakedTrackingVariable) this.trackingVariables.get(j));
+					if (trackingVar.originalBinding == var2.originalBinding) {
+						// two tracking variables for the same original, merge info from both branches now:
+						boolean var1SeenInThen = thenFlowInfo.hasNullInfoFor(trackingVar.binding);
+						boolean var1SeenInElse = elseFlowInfo.hasNullInfoFor(trackingVar.binding);
+						boolean var2SeenInThen = thenFlowInfo.hasNullInfoFor(var2.binding);
+						boolean var2SeenInElse = elseFlowInfo.hasNullInfoFor(var2.binding);
+						int newStatus;
+						if (!var1SeenInThen && var1SeenInElse && var2SeenInThen && !var2SeenInElse) {
+							newStatus = FlowInfo.mergeNullStatus(thenFlowInfo.nullStatus(var2.binding), elseFlowInfo.nullStatus(trackingVar.binding));
+						} else if (var1SeenInThen && !var1SeenInElse && !var2SeenInThen && var2SeenInElse) {
+							newStatus = FlowInfo.mergeNullStatus(thenFlowInfo.nullStatus(trackingVar.binding), elseFlowInfo.nullStatus(var2.binding)); 
+						} else {
+							continue;
+						}
+						thenFlowInfo.markNullStatus(trackingVar.binding, newStatus);
+						elseFlowInfo.markNullStatus(trackingVar.binding, newStatus);
+						trackingVar.originalBinding.closeTracker = trackingVar; // avoid further use of var2
+						thenFlowInfo.markNullStatus(var2.binding, FlowInfo.NON_NULL);
+						elseFlowInfo.markNullStatus(var2.binding, FlowInfo.NON_NULL);
+					}
+				}
+			}
+		}
+	}
+	if (this.parent instanceof BlockScope)
+		((BlockScope) this.parent).correlateTrackingVarsIfElse(thenFlowInfo, elseFlowInfo);
+}
+
+/** 15.12.3 (Java 8) "Compile-Time Step 3: Is the Chosen Method Appropriate?" */
+public void checkAppropriateMethodAgainstSupers(char[] selector, MethodBinding compileTimeMethod,
+		TypeBinding[] parameters, InvocationSite site)
+{
+	ReferenceBinding enclosingType = enclosingReceiverType();
+	MethodBinding otherMethod = getMethod(enclosingType.superclass(), selector, parameters, site);
+	if (checkAppropriate(compileTimeMethod, otherMethod, site)) {
+		ReferenceBinding[] superInterfaces = enclosingType.superInterfaces();
+		if (superInterfaces != null) {
+			for (int i = 0; i < superInterfaces.length; i++) {
+				otherMethod = getMethod(superInterfaces[i], selector, parameters, site);
+				if (!checkAppropriate(compileTimeMethod, otherMethod, site))
+					break;
+			}
+		}
+	}
+}
+private boolean checkAppropriate(MethodBinding compileTimeDeclaration, MethodBinding otherMethod, InvocationSite location) {
+	if (otherMethod == null || !otherMethod.isValidBinding() || otherMethod == compileTimeDeclaration)
+		return true;
+	if (MethodVerifier.doesMethodOverride(otherMethod, compileTimeDeclaration, this.environment())) {
+		problemReporter().illegalSuperCallBypassingOverride(location, compileTimeDeclaration, otherMethod.declaringClass);
+		return false; 
+	}
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
new file mode 100644
index 0000000..61c6e69
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class CaptureBinding extends TypeVariableBinding {
+
+	public TypeBinding lowerBound;
+	public WildcardBinding wildcard;
+	public int captureID;
+
+	/* information to compute unique binding key */
+	public ReferenceBinding sourceType;
+	public int position;
+
+	public CaptureBinding(WildcardBinding wildcard, ReferenceBinding sourceType, int position, int captureID) {
+		super(TypeConstants.WILDCARD_CAPTURE_NAME_PREFIX, null, 0, wildcard.environment);
+		this.wildcard = wildcard;
+		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat capture as public
+		this.fPackage = wildcard.fPackage;
+		this.sourceType = sourceType;
+		this.position = position;
+		this.captureID = captureID;
+	}
+
+	/*
+	 * sourceTypeKey ! wildcardKey position semi-colon
+	 * p.X { capture of ? } --> !*123; (Lp/X; in declaring type except if leaf)
+	 * p.X { capture of ? extends p.Y } --> !+Lp/Y;123; (Lp/X; in declaring type except if leaf)
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		StringBuffer buffer = new StringBuffer();
+		if (isLeaf) {
+			buffer.append(this.sourceType.computeUniqueKey(false/*not a leaf*/));
+			buffer.append('&');
+		}
+		buffer.append(TypeConstants.WILDCARD_CAPTURE);
+		buffer.append(this.wildcard.computeUniqueKey(false/*not a leaf*/));
+		buffer.append(this.position);
+		buffer.append(';');
+		int length = buffer.length();
+		char[] uniqueKey = new char[length];
+		buffer.getChars(0, length, uniqueKey, 0);
+		return uniqueKey;
+	}
+
+	public String debugName() {
+
+		if (this.wildcard != null) {
+			StringBuffer buffer = new StringBuffer(10);
+			buffer
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_PREFIX)
+				.append(this.captureID)
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_SUFFIX)
+				.append(this.wildcard.debugName());
+			return buffer.toString();
+		}
+		return super.debugName();
+	}
+
+	public char[] genericTypeSignature() {
+		if (this.genericTypeSignature == null) {
+			this.genericTypeSignature = CharOperation.concat(TypeConstants.WILDCARD_CAPTURE, this.wildcard.genericTypeSignature());
+		}
+		return this.genericTypeSignature;
+	}
+
+	/**
+	 * Initialize capture bounds using substituted supertypes
+	 * e.g. given X<U, V extends X<U, V>>,     capture(X<E,?>) = X<E,capture>, where capture extends X<E,capture>
+	 */
+	public void initializeBounds(Scope scope, ParameterizedTypeBinding capturedParameterizedType) {
+		TypeVariableBinding wildcardVariable = this.wildcard.typeVariable();
+		if (wildcardVariable == null) {
+			// error resilience when capturing Zork<?>
+			// no substitution for wildcard bound (only formal bounds from type variables are to be substituted: 104082)
+			TypeBinding originalWildcardBound = this.wildcard.bound;
+			switch (this.wildcard.boundKind) {
+				case Wildcard.EXTENDS :
+					// still need to capture bound supertype as well so as not to expose wildcards to the outside (111208)
+					TypeBinding capturedWildcardBound = originalWildcardBound.capture(scope, this.position);
+					if (originalWildcardBound.isInterface()) {
+						this.superclass = scope.getJavaLangObject();
+						this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) capturedWildcardBound };
+					} else {
+						// the wildcard bound should be a subtype of variable superclass
+						// it may occur that the bound is less specific, then consider glb (202404)
+						if (capturedWildcardBound.isArrayType() || capturedWildcardBound == this) {
+							this.superclass = scope.getJavaLangObject();
+						} else {
+							this.superclass = (ReferenceBinding) capturedWildcardBound;
+						}
+						this.superInterfaces = Binding.NO_SUPERINTERFACES;
+					}
+					this.firstBound =  capturedWildcardBound;
+					if ((capturedWildcardBound.tagBits & TagBits.HasTypeVariable) == 0)
+						this.tagBits &= ~TagBits.HasTypeVariable;
+					break;
+				case Wildcard.UNBOUND :
+					this.superclass = scope.getJavaLangObject();
+					this.superInterfaces = Binding.NO_SUPERINTERFACES;
+					this.tagBits &= ~TagBits.HasTypeVariable;
+					break;
+				case Wildcard.SUPER :
+					this.superclass = scope.getJavaLangObject();
+					this.superInterfaces = Binding.NO_SUPERINTERFACES;
+					this.lowerBound = this.wildcard.bound;
+					if ((originalWildcardBound.tagBits & TagBits.HasTypeVariable) == 0)
+						this.tagBits &= ~TagBits.HasTypeVariable;
+					break;
+			}
+			return;
+		}
+		ReferenceBinding originalVariableSuperclass = wildcardVariable.superclass;
+		ReferenceBinding substitutedVariableSuperclass = (ReferenceBinding) Scope.substitute(capturedParameterizedType, originalVariableSuperclass);
+		// prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
+		if (substitutedVariableSuperclass == this) substitutedVariableSuperclass = originalVariableSuperclass;
+
+		ReferenceBinding[] originalVariableInterfaces = wildcardVariable.superInterfaces();
+		ReferenceBinding[] substitutedVariableInterfaces = Scope.substitute(capturedParameterizedType, originalVariableInterfaces);
+		if (substitutedVariableInterfaces != originalVariableInterfaces) {
+			// prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
+			for (int i = 0, length = substitutedVariableInterfaces.length; i < length; i++) {
+				if (substitutedVariableInterfaces[i] == this) substitutedVariableInterfaces[i] = originalVariableInterfaces[i];
+			}
+		}
+		// no substitution for wildcard bound (only formal bounds from type variables are to be substituted: 104082)
+		TypeBinding originalWildcardBound = this.wildcard.bound;
+
+		switch (this.wildcard.boundKind) {
+			case Wildcard.EXTENDS :
+				// still need to capture bound supertype as well so as not to expose wildcards to the outside (111208)
+				TypeBinding capturedWildcardBound = originalWildcardBound.capture(scope, this.position);
+				if (originalWildcardBound.isInterface()) {
+					this.superclass = substitutedVariableSuperclass;
+					// merge wildcard bound into variable superinterfaces using glb
+					if (substitutedVariableInterfaces == Binding.NO_SUPERINTERFACES) {
+						this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) capturedWildcardBound };
+					} else {
+						int length = substitutedVariableInterfaces.length;
+						System.arraycopy(substitutedVariableInterfaces, 0, substitutedVariableInterfaces = new ReferenceBinding[length+1], 1, length);
+						substitutedVariableInterfaces[0] =  (ReferenceBinding) capturedWildcardBound;
+						this.superInterfaces = Scope.greaterLowerBound(substitutedVariableInterfaces);
+					}
+				} else {
+					// the wildcard bound should be a subtype of variable superclass
+					// it may occur that the bound is less specific, then consider glb (202404)
+					if (capturedWildcardBound.isArrayType() || capturedWildcardBound == this) {
+						this.superclass = substitutedVariableSuperclass;
+					} else {
+						this.superclass = (ReferenceBinding) capturedWildcardBound;
+						if (this.superclass.isSuperclassOf(substitutedVariableSuperclass)) {
+							this.superclass = substitutedVariableSuperclass;
+						}
+					}
+					this.superInterfaces = substitutedVariableInterfaces;
+				}
+				this.firstBound =  capturedWildcardBound;
+				if ((capturedWildcardBound.tagBits & TagBits.HasTypeVariable) == 0)
+					this.tagBits &= ~TagBits.HasTypeVariable;
+				break;
+			case Wildcard.UNBOUND :
+				this.superclass = substitutedVariableSuperclass;
+				this.superInterfaces = substitutedVariableInterfaces;
+				this.tagBits &= ~TagBits.HasTypeVariable;
+				break;
+			case Wildcard.SUPER :
+				this.superclass = substitutedVariableSuperclass;
+				if (wildcardVariable.firstBound == substitutedVariableSuperclass || originalWildcardBound == substitutedVariableSuperclass) {
+					this.firstBound = substitutedVariableSuperclass;
+				}
+				this.superInterfaces = substitutedVariableInterfaces;
+				this.lowerBound = originalWildcardBound;
+				if ((originalWildcardBound.tagBits & TagBits.HasTypeVariable) == 0)
+					this.tagBits &= ~TagBits.HasTypeVariable;
+				break;
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isCapture()
+	 */
+	public boolean isCapture() {
+		return true;
+	}
+
+	/**
+	 * @see TypeBinding#isEquivalentTo(TypeBinding)
+	 */
+	public boolean isEquivalentTo(TypeBinding otherType) {
+	    if (this == otherType) return true;
+	    if (otherType == null) return false;
+		// capture of ? extends X[]
+		if (this.firstBound != null && this.firstBound.isArrayType()) {
+			if (this.firstBound.isCompatibleWith(otherType))
+				return true;
+		}
+		switch (otherType.kind()) {
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE :
+				return ((WildcardBinding) otherType).boundCheck(this);
+		}
+		return false;
+	}
+
+	public char[] readableName() {
+		if (this.wildcard != null) {
+			StringBuffer buffer = new StringBuffer(10);
+			buffer
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_PREFIX)
+				.append(this.captureID)
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_SUFFIX)
+				.append(this.wildcard.readableName());
+			int length = buffer.length();
+			char[] name = new char[length];
+			buffer.getChars(0, length, name, 0);
+			return name;
+		}
+		return super.readableName();
+	}
+
+	public char[] shortReadableName() {
+		if (this.wildcard != null) {
+			StringBuffer buffer = new StringBuffer(10);
+			buffer
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_PREFIX)
+				.append(this.captureID)
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_SUFFIX)
+				.append(this.wildcard.shortReadableName());
+			int length = buffer.length();
+			char[] name = new char[length];
+			buffer.getChars(0, length, name, 0);
+			return name;
+		}
+		return super.shortReadableName();
+	}
+
+	public String toString() {
+		if (this.wildcard != null) {
+			StringBuffer buffer = new StringBuffer(10);
+			buffer
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_PREFIX)
+				.append(this.captureID)
+				.append(TypeConstants.WILDCARD_CAPTURE_NAME_SUFFIX)
+				.append(this.wildcard);
+			return buffer.toString();
+		}
+		return super.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
new file mode 100644
index 0000000..fa8bcbd
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+
+public class CatchParameterBinding extends LocalVariableBinding {
+	
+	TypeBinding [] preciseTypes = Binding.NO_EXCEPTIONS;  // the catch block can be entered with the parameters set to these types.
+	
+	public CatchParameterBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) {
+		super(declaration, type, modifiers, isArgument);
+	}
+	
+	public TypeBinding [] getPreciseTypes() {
+		return this.preciseTypes;
+	}
+
+	public void setPreciseType(TypeBinding raisedException) {
+		int length = this.preciseTypes.length;
+		for (int i = 0; i < length; ++i) {
+			if (this.preciseTypes[i] == raisedException)
+				return;
+		}
+		System.arraycopy(this.preciseTypes, 0, this.preciseTypes = new TypeBinding [length + 1], 0, length);
+		this.preciseTypes[length] = raisedException;
+		return;
+	}
+	public boolean isCatchParameter() {
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
new file mode 100644
index 0000000..20dd8c1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -0,0 +1,1289 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *     						Bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ *     						Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
+ *     						Bug 354536 - compiling package-info.java still depends on the order of compilation units
+ *     						Bug 349326 - [1.7] new warning for missing try-with-resources
+ *     						Bug 358903 - Filter practically unimportant resource leak warnings
+ *							Bug 395977 - [compiler][resource] Resource leak warning behavior possibly incorrect for anonymous inner class
+ *							Bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+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.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+
+public class ClassScope extends Scope {
+
+	public TypeDeclaration referenceContext;
+	public TypeReference superTypeReference;
+	java.util.ArrayList deferredBoundChecks;
+
+	public ClassScope(Scope parent, TypeDeclaration context) {
+		super(Scope.CLASS_SCOPE, parent);
+		this.referenceContext = context;
+		this.deferredBoundChecks = null; // initialized if required
+	}
+
+	void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) {
+		LocalTypeBinding anonymousType = buildLocalType(enclosingType, enclosingType.fPackage);
+		anonymousType.modifiers |= ExtraCompilerModifiers.AccLocallyUsed; // tag all anonymous types as used locally
+		int inheritedBits = supertype.typeBits; // for anonymous class assume same properties as its super (as a closeable) ...
+		// ... unless it overrides close():
+		if ((inheritedBits & TypeIds.BitWrapperCloseable) != 0) {
+			AbstractMethodDeclaration[] methods = this.referenceContext.methods;
+			if (methods != null) {
+				for (int i=0; i<methods.length; i++) {
+					if (CharOperation.equals(TypeConstants.CLOSE, methods[i].selector) && methods[i].arguments == null) {
+						inheritedBits &= TypeIds.InheritableBits;
+						break;
+					}
+				}
+			}
+		}
+		anonymousType.typeBits |= inheritedBits;
+		if (supertype.isInterface()) {
+			anonymousType.superclass = getJavaLangObject();
+			anonymousType.superInterfaces = new ReferenceBinding[] { supertype };
+			TypeReference typeReference = this.referenceContext.allocation.type;
+			if (typeReference != null) {
+				if ((supertype.tagBits & TagBits.HasDirectWildcard) != 0) {
+					problemReporter().superTypeCannotUseWildcard(anonymousType, typeReference, supertype);
+					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
+					anonymousType.superInterfaces = Binding.NO_SUPERINTERFACES;
+				}
+			}
+		} else {
+			anonymousType.superclass = supertype;
+			anonymousType.superInterfaces = Binding.NO_SUPERINTERFACES;
+			TypeReference typeReference = this.referenceContext.allocation.type;
+			if (typeReference != null) { // no check for enum constant body
+				if (supertype.erasure().id == TypeIds.T_JavaLangEnum) {
+					problemReporter().cannotExtendEnum(anonymousType, typeReference, supertype);
+					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
+					anonymousType.superclass = getJavaLangObject();
+				} else if (supertype.isFinal()) {
+					problemReporter().anonymousClassCannotExtendFinalClass(typeReference, supertype);
+					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
+					anonymousType.superclass = getJavaLangObject();
+				} else if ((supertype.tagBits & TagBits.HasDirectWildcard) != 0) {
+					problemReporter().superTypeCannotUseWildcard(anonymousType, typeReference, supertype);
+					anonymousType.tagBits |= TagBits.HierarchyHasProblems;
+					anonymousType.superclass = getJavaLangObject();
+				}
+			}
+		}
+		connectMemberTypes();
+		buildFieldsAndMethods();
+		anonymousType.faultInTypesForFieldsAndMethods();
+		anonymousType.verifyMethods(environment().methodVerifier());
+	}
+
+	void buildFields() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if (sourceType.areFieldsInitialized()) return;
+		if (this.referenceContext.fields == null) {
+			sourceType.setFields(Binding.NO_FIELDS);
+			return;
+		}
+		// count the number of fields vs. initializers
+		FieldDeclaration[] fields = this.referenceContext.fields;
+		int size = fields.length;
+		int count = 0;
+		for (int i = 0; i < size; i++) {
+			switch (fields[i].getKind()) {
+				case AbstractVariableDeclaration.FIELD:
+				case AbstractVariableDeclaration.ENUM_CONSTANT:
+					count++;
+			}
+		}
+
+		// iterate the field declarations to create the bindings, lose all duplicates
+		FieldBinding[] fieldBindings = new FieldBinding[count];
+		HashtableOfObject knownFieldNames = new HashtableOfObject(count);
+		count = 0;
+		for (int i = 0; i < size; i++) {
+			FieldDeclaration field = fields[i];
+			if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
+				// We used to report an error for initializers declared inside interfaces, but
+				// now this error reporting is moved into the parser itself. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=212713
+			} else {
+				FieldBinding fieldBinding = new FieldBinding(field, null, field.modifiers | ExtraCompilerModifiers.AccUnresolved, sourceType);
+				fieldBinding.id = count;
+				// field's type will be resolved when needed for top level types
+				checkAndSetModifiersForField(fieldBinding, field);
+
+				if (knownFieldNames.containsKey(field.name)) {
+					FieldBinding previousBinding = (FieldBinding) knownFieldNames.get(field.name);
+					if (previousBinding != null) {
+						for (int f = 0; f < i; f++) {
+							FieldDeclaration previousField = fields[f];
+							if (previousField.binding == previousBinding) {
+								problemReporter().duplicateFieldInType(sourceType, previousField);
+								break;
+							}
+						}
+					}
+					knownFieldNames.put(field.name, null); // ensure that the duplicate field is found & removed
+					problemReporter().duplicateFieldInType(sourceType, field);
+					field.binding = null;
+				} else {
+					knownFieldNames.put(field.name, fieldBinding);
+					// remember that we have seen a field with this name
+					fieldBindings[count++] = fieldBinding;
+				}
+			}
+		}
+		// remove duplicate fields
+		if (count != fieldBindings.length)
+			System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count);
+		sourceType.tagBits &= ~(TagBits.AreFieldsSorted|TagBits.AreFieldsComplete); // in case some static imports reached already into this type
+		sourceType.setFields(fieldBindings);
+	}
+
+	void buildFieldsAndMethods() {
+		buildFields();
+		buildMethods();
+
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if (!sourceType.isPrivate() && sourceType.superclass instanceof SourceTypeBinding && sourceType.superclass.isPrivate())
+			((SourceTypeBinding) sourceType.superclass).tagIndirectlyAccessibleMembers();
+
+		if (sourceType.isMemberType() && !sourceType.isLocalType())
+			 ((MemberTypeBinding) sourceType).checkSyntheticArgsAndFields();
+
+		ReferenceBinding[] memberTypes = sourceType.memberTypes;
+		for (int i = 0, length = memberTypes.length; i < length; i++)
+			 ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods();
+	}
+
+	private LocalTypeBinding buildLocalType(SourceTypeBinding enclosingType, PackageBinding packageBinding) {
+
+		this.referenceContext.scope = this;
+		this.referenceContext.staticInitializerScope = new MethodScope(this, this.referenceContext, true);
+		this.referenceContext.initializerScope = new MethodScope(this, this.referenceContext, false);
+
+		// build the binding or the local type
+		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, innermostSwitchCase());
+		this.referenceContext.binding = localType;
+		checkAndSetModifiers();
+		buildTypeVariables();
+
+		// Look at member types
+		ReferenceBinding[] memberTypeBindings = Binding.NO_MEMBER_TYPES;
+		if (this.referenceContext.memberTypes != null) {
+			int size = this.referenceContext.memberTypes.length;
+			memberTypeBindings = new ReferenceBinding[size];
+			int count = 0;
+			nextMember : for (int i = 0; i < size; i++) {
+				TypeDeclaration memberContext = this.referenceContext.memberTypes[i];
+				switch(TypeDeclaration.kind(memberContext.modifiers)) {
+					case TypeDeclaration.INTERFACE_DECL :
+					case TypeDeclaration.ANNOTATION_TYPE_DECL :
+						problemReporter().illegalLocalTypeDeclaration(memberContext);
+						continue nextMember;
+				}
+				ReferenceBinding type = localType;
+				// check that the member does not conflict with an enclosing type
+				do {
+					if (CharOperation.equals(type.sourceName, memberContext.name)) {
+						problemReporter().typeCollidesWithEnclosingType(memberContext);
+						continue nextMember;
+					}
+					type = type.enclosingType();
+				} while (type != null);
+				// check the member type does not conflict with another sibling member type
+				for (int j = 0; j < i; j++) {
+					if (CharOperation.equals(this.referenceContext.memberTypes[j].name, memberContext.name)) {
+						problemReporter().duplicateNestedType(memberContext);
+						continue nextMember;
+					}
+				}
+				ClassScope memberScope = new ClassScope(this, this.referenceContext.memberTypes[i]);
+				LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, packageBinding);
+				memberBinding.setAsMemberType();
+				memberTypeBindings[count++] = memberBinding;
+			}
+			if (count != size)
+				System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count);
+		}
+		localType.memberTypes = memberTypeBindings;
+		return localType;
+	}
+
+	void buildLocalTypeBinding(SourceTypeBinding enclosingType) {
+
+		LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage);
+		connectTypeHierarchy();
+		if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+			checkParameterizedTypeBounds();
+			checkParameterizedSuperTypeCollisions();
+		}
+		buildFieldsAndMethods();
+		localType.faultInTypesForFieldsAndMethods();
+
+		this.referenceContext.binding.verifyMethods(environment().methodVerifier());
+	}
+
+	private void buildMemberTypes(AccessRestriction accessRestriction) {
+	    SourceTypeBinding sourceType = this.referenceContext.binding;
+		ReferenceBinding[] memberTypeBindings = Binding.NO_MEMBER_TYPES;
+		if (this.referenceContext.memberTypes != null) {
+			int length = this.referenceContext.memberTypes.length;
+			memberTypeBindings = new ReferenceBinding[length];
+			int count = 0;
+			nextMember : for (int i = 0; i < length; i++) {
+				TypeDeclaration memberContext = this.referenceContext.memberTypes[i];
+				switch(TypeDeclaration.kind(memberContext.modifiers)) {
+					case TypeDeclaration.INTERFACE_DECL :
+					case TypeDeclaration.ANNOTATION_TYPE_DECL :
+						if (sourceType.isNestedType()
+								&& sourceType.isClass() // no need to check for enum, since implicitly static
+								&& !sourceType.isStatic()) {
+							problemReporter().illegalLocalTypeDeclaration(memberContext);
+							continue nextMember;
+						}
+					break;
+				}
+				ReferenceBinding type = sourceType;
+				// check that the member does not conflict with an enclosing type
+				do {
+					if (CharOperation.equals(type.sourceName, memberContext.name)) {
+						problemReporter().typeCollidesWithEnclosingType(memberContext);
+						continue nextMember;
+					}
+					type = type.enclosingType();
+				} while (type != null);
+				// check that the member type does not conflict with another sibling member type
+				for (int j = 0; j < i; j++) {
+					if (CharOperation.equals(this.referenceContext.memberTypes[j].name, memberContext.name)) {
+						problemReporter().duplicateNestedType(memberContext);
+						continue nextMember;
+					}
+				}
+
+				ClassScope memberScope = new ClassScope(this, memberContext);
+				memberTypeBindings[count++] = memberScope.buildType(sourceType, sourceType.fPackage, accessRestriction);
+			}
+			if (count != length)
+				System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count);
+		}
+		sourceType.memberTypes = memberTypeBindings;
+	}
+
+	void buildMethods() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if (sourceType.areMethodsInitialized()) return;
+
+		boolean isEnum = TypeDeclaration.kind(this.referenceContext.modifiers) == TypeDeclaration.ENUM_DECL;
+		if (this.referenceContext.methods == null && !isEnum) {
+			this.referenceContext.binding.setMethods(Binding.NO_METHODS);
+			return;
+		}
+
+		// iterate the method declarations to create the bindings
+		AbstractMethodDeclaration[] methods = this.referenceContext.methods;
+		int size = methods == null ? 0 : methods.length;
+		// look for <clinit> method
+		int clinitIndex = -1;
+		for (int i = 0; i < size; i++) {
+			if (methods[i].isClinit()) {
+				clinitIndex = i;
+				break;
+			}
+		}
+
+		int count = isEnum ? 2 : 0; // reserve 2 slots for special enum methods: #values() and #valueOf(String)
+		MethodBinding[] methodBindings = new MethodBinding[(clinitIndex == -1 ? size : size - 1) + count];
+		// create special methods for enums
+		if (isEnum) {
+			methodBindings[0] = sourceType.addSyntheticEnumMethod(TypeConstants.VALUES); // add <EnumType>[] values()
+			methodBindings[1] = sourceType.addSyntheticEnumMethod(TypeConstants.VALUEOF); // add <EnumType> valueOf()
+		}
+		// create bindings for source methods
+		boolean hasNativeMethods = false;
+		if (sourceType.isAbstract()) {
+			for (int i = 0; i < size; i++) {
+				if (i != clinitIndex) {
+					MethodScope scope = new MethodScope(this, methods[i], false);
+					MethodBinding methodBinding = scope.createMethod(methods[i]);
+					if (methodBinding != null) { // is null if binding could not be created
+						methodBindings[count++] = methodBinding;
+						hasNativeMethods = hasNativeMethods || methodBinding.isNative();
+					}
+				}
+			}
+		} else {
+			boolean hasAbstractMethods = false;
+			for (int i = 0; i < size; i++) {
+				if (i != clinitIndex) {
+					MethodScope scope = new MethodScope(this, methods[i], false);
+					MethodBinding methodBinding = scope.createMethod(methods[i]);
+					if (methodBinding != null) { // is null if binding could not be created
+						methodBindings[count++] = methodBinding;
+						hasAbstractMethods = hasAbstractMethods || methodBinding.isAbstract();
+						hasNativeMethods = hasNativeMethods || methodBinding.isNative();
+					}
+				}
+			}
+			if (hasAbstractMethods)
+				problemReporter().abstractMethodInConcreteClass(sourceType);
+		}
+		if (count != methodBindings.length)
+			System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[count], 0, count);
+		sourceType.tagBits &= ~(TagBits.AreMethodsSorted|TagBits.AreMethodsComplete); // in case some static imports reached already into this type
+		sourceType.setMethods(methodBindings);
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=243917, conservatively tag all methods and fields as
+		// being in use if there is a native method in the class.
+		if (hasNativeMethods) {
+			for (int i = 0; i < methodBindings.length; i++) {
+				methodBindings[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+			}
+			FieldBinding[] fields = sourceType.unResolvedFields(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=301683
+			for (int i = 0; i < fields.length; i++) {
+				fields[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;	
+			}
+		}
+	}
+
+	SourceTypeBinding buildType(SourceTypeBinding enclosingType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		// provide the typeDeclaration with needed scopes
+		this.referenceContext.scope = this;
+		this.referenceContext.staticInitializerScope = new MethodScope(this, this.referenceContext, true);
+		this.referenceContext.initializerScope = new MethodScope(this, this.referenceContext, false);
+
+		if (enclosingType == null) {
+			char[][] className = CharOperation.arrayConcat(packageBinding.compoundName, this.referenceContext.name);
+			this.referenceContext.binding = new SourceTypeBinding(className, packageBinding, this);
+		} else {
+			char[][] className = CharOperation.deepCopy(enclosingType.compoundName);
+			className[className.length - 1] =
+				CharOperation.concat(className[className.length - 1], this.referenceContext.name, '$');
+			ReferenceBinding existingType = packageBinding.getType0(className[className.length - 1]);
+			if (existingType != null) {
+				if (existingType instanceof UnresolvedReferenceBinding) {
+					// its possible that a BinaryType referenced the member type before its enclosing source type was built
+					// so just replace the unresolved type with a new member type
+				} else {
+					// report the error against the parent - its still safe to answer the member type
+					this.parent.problemReporter().duplicateNestedType(this.referenceContext);
+				}
+			}
+			this.referenceContext.binding = new MemberTypeBinding(className, this, enclosingType);
+		}
+
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		environment().setAccessRestriction(sourceType, accessRestriction);
+		sourceType.fPackage.addType(sourceType);
+		checkAndSetModifiers();
+		buildTypeVariables();
+		buildMemberTypes(accessRestriction);
+		return sourceType;
+	}
+
+	private void buildTypeVariables() {
+
+	    SourceTypeBinding sourceType = this.referenceContext.binding;
+		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, If they exist at all, process type parameters irrespective of source level.
+		if (typeParameters == null || typeParameters.length == 0) {
+		    sourceType.typeVariables = Binding.NO_TYPE_VARIABLES;
+		    return;
+		}
+		sourceType.typeVariables = Binding.NO_TYPE_VARIABLES; // safety
+
+		if (sourceType.id == TypeIds.T_JavaLangObject) { // handle the case of redefining java.lang.Object up front
+			problemReporter().objectCannotBeGeneric(this.referenceContext);
+			return;
+		}
+		sourceType.typeVariables = createTypeVariables(typeParameters, sourceType);
+		sourceType.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+	}
+
+	private void checkAndSetModifiers() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		int modifiers = sourceType.modifiers;
+		if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
+			problemReporter().duplicateModifierForType(sourceType);
+		ReferenceBinding enclosingType = sourceType.enclosingType();
+		boolean isMemberType = sourceType.isMemberType();
+		if (isMemberType) {
+			modifiers |= (enclosingType.modifiers & (ExtraCompilerModifiers.AccGenericSignature|ClassFileConstants.AccStrictfp));
+			// checks for member types before local types to catch local members
+			if (enclosingType.isInterface())
+				modifiers |= ClassFileConstants.AccPublic;
+			if (sourceType.isEnum()) {
+				if (!enclosingType.isStatic())
+					problemReporter().nonStaticContextForEnumMemberType(sourceType);
+				else
+					modifiers |= ClassFileConstants.AccStatic;
+			}
+		} else if (sourceType.isLocalType()) {
+			if (sourceType.isEnum()) {
+				problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
+				sourceType.modifiers = 0;
+				return;
+			}
+			if (sourceType.isAnonymousType()) {
+			    modifiers |= ClassFileConstants.AccFinal;
+			    // set AccEnum flag for anonymous body of enum constants
+			    if (this.referenceContext.allocation.type == null)
+			    	modifiers |= ClassFileConstants.AccEnum;
+			}
+			Scope scope = this;
+			do {
+				switch (scope.kind) {
+					case METHOD_SCOPE :
+						MethodScope methodScope = (MethodScope) scope;
+						if (methodScope.isLambdaScope()) 
+							methodScope = methodScope.namedMethodScope();
+						if (methodScope.isInsideInitializer()) {
+							SourceTypeBinding type = ((TypeDeclaration) methodScope.referenceContext).binding;
+
+							// inside field declaration ? check field modifier to see if deprecated
+							if (methodScope.initializedField != null) {
+									// currently inside this field initialization
+								if (methodScope.initializedField.isViewedAsDeprecated() && !sourceType.isDeprecated())
+									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+							} else {
+								if (type.isStrictfp())
+									modifiers |= ClassFileConstants.AccStrictfp;
+								if (type.isViewedAsDeprecated() && !sourceType.isDeprecated())
+									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+							}
+						} else {
+							MethodBinding method = ((AbstractMethodDeclaration) methodScope.referenceContext).binding;
+							if (method != null) {
+								if (method.isStrictfp())
+									modifiers |= ClassFileConstants.AccStrictfp;
+								if (method.isViewedAsDeprecated() && !sourceType.isDeprecated())
+									modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+							}
+						}
+						break;
+					case CLASS_SCOPE :
+						// local member
+						if (enclosingType.isStrictfp())
+							modifiers |= ClassFileConstants.AccStrictfp;
+						if (enclosingType.isViewedAsDeprecated() && !sourceType.isDeprecated())
+							modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+						break;
+				}
+				scope = scope.parent;
+			} while (scope != null);
+		}
+
+		// after this point, tests on the 16 bits reserved.
+		int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+
+		if ((realModifiers & ClassFileConstants.AccInterface) != 0) { // interface and annotation type
+			// detect abnormal cases for interfaces
+			if (isMemberType) {
+				final int UNEXPECTED_MODIFIERS =
+					~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+					if ((realModifiers & ClassFileConstants.AccAnnotation) != 0)
+						problemReporter().illegalModifierForAnnotationMemberType(sourceType);
+					else
+						problemReporter().illegalModifierForMemberInterface(sourceType);
+				}
+				/*
+				} else if (sourceType.isLocalType()) { //interfaces cannot be defined inside a method
+					int unexpectedModifiers = ~(AccAbstract | AccInterface | AccStrictfp);
+					if ((realModifiers & unexpectedModifiers) != 0)
+						problemReporter().illegalModifierForLocalInterface(sourceType);
+				*/
+			} else {
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccStrictfp | ClassFileConstants.AccAnnotation);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+					if ((realModifiers & ClassFileConstants.AccAnnotation) != 0)
+						problemReporter().illegalModifierForAnnotationType(sourceType);
+					else
+						problemReporter().illegalModifierForInterface(sourceType);
+				}
+			}
+			/*
+			 * AccSynthetic must be set if the target is greater than 1.5. 1.5 VM don't support AccSynthetics flag.
+			 */
+			if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME && compilerOptions().targetJDK > ClassFileConstants.JDK1_5) {
+				modifiers |= ClassFileConstants.AccSynthetic;
+			}
+			modifiers |= ClassFileConstants.AccAbstract;
+		} else if ((realModifiers & ClassFileConstants.AccEnum) != 0) {
+			// detect abnormal cases for enums
+			if (isMemberType) { // includes member types defined inside local types
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+					problemReporter().illegalModifierForMemberEnum(sourceType);
+					modifiers &= ~ClassFileConstants.AccAbstract; // avoid leaking abstract modifier
+					realModifiers &= ~ClassFileConstants.AccAbstract;
+//					modifiers &= ~(realModifiers & UNEXPECTED_MODIFIERS);
+//					realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+				}
+			} else if (sourceType.isLocalType()) {
+				// each enum constant is an anonymous local type and its modifiers were already checked as an enum constant field
+			} else {
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccStrictfp | ClassFileConstants.AccEnum);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
+					problemReporter().illegalModifierForEnum(sourceType);
+			}
+			if (!sourceType.isAnonymousType()) {
+				checkAbstractEnum: {
+					// does define abstract methods ?
+					if ((this.referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
+						modifiers |= ClassFileConstants.AccAbstract;
+						break checkAbstractEnum;
+					}
+					// body of enum constant must implement any inherited abstract methods
+					// enum type needs to implement abstract methods if one of its constants does not supply a body
+					TypeDeclaration typeDeclaration = this.referenceContext;
+					FieldDeclaration[] fields = typeDeclaration.fields;
+					int fieldsLength = fields == null ? 0 : fields.length;
+					if (fieldsLength == 0) break checkAbstractEnum; // has no constants so must implement the method itself
+					AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+					int methodsLength = methods == null ? 0 : methods.length;
+					// TODO (kent) cannot tell that the superinterfaces are empty or that their methods are implemented
+					boolean definesAbstractMethod = typeDeclaration.superInterfaces != null;
+					for (int i = 0; i < methodsLength && !definesAbstractMethod; i++)
+						definesAbstractMethod = methods[i].isAbstract();
+					if (!definesAbstractMethod) break checkAbstractEnum; // all methods have bodies
+					boolean needAbstractBit = false;
+					for (int i = 0; i < fieldsLength; i++) {
+						FieldDeclaration fieldDecl = fields[i];
+						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+							if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
+								needAbstractBit = true;
+							} else {
+								break checkAbstractEnum;
+							}
+						}
+					}
+					// tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
+					// as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
+					if (needAbstractBit) {
+						modifiers |= ClassFileConstants.AccAbstract;
+					}
+				}
+				// final if no enum constant with anonymous body
+				checkFinalEnum: {
+					TypeDeclaration typeDeclaration = this.referenceContext;
+					FieldDeclaration[] fields = typeDeclaration.fields;
+					if (fields != null) {
+						for (int i = 0, fieldsLength = fields.length; i < fieldsLength; i++) {
+							FieldDeclaration fieldDecl = fields[i];
+							if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+								if (fieldDecl.initialization instanceof QualifiedAllocationExpression) {
+									break checkFinalEnum;
+								}
+							}
+						}
+					}
+					modifiers |= ClassFileConstants.AccFinal;
+				}
+			}
+		} else {
+			// detect abnormal cases for classes
+			if (isMemberType) { // includes member types defined inside local types
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
+					problemReporter().illegalModifierForMemberClass(sourceType);
+			} else if (sourceType.isLocalType()) {
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
+					problemReporter().illegalModifierForLocalClass(sourceType);
+			} else {
+				final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ClassFileConstants.AccFinal | ClassFileConstants.AccStrictfp);
+				if ((realModifiers & UNEXPECTED_MODIFIERS) != 0)
+					problemReporter().illegalModifierForClass(sourceType);
+			}
+
+			// check that Final and Abstract are not set together
+			if ((realModifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract)) == (ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract))
+				problemReporter().illegalModifierCombinationFinalAbstractForClass(sourceType);
+		}
+
+		if (isMemberType) {
+			// test visibility modifiers inconsistency, isolate the accessors bits
+			if (enclosingType.isInterface()) {
+				if ((realModifiers & (ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) != 0) {
+					problemReporter().illegalVisibilityModifierForInterfaceMemberType(sourceType);
+
+					// need to keep the less restrictive
+					if ((realModifiers & ClassFileConstants.AccProtected) != 0)
+						modifiers &= ~ClassFileConstants.AccProtected;
+					if ((realModifiers & ClassFileConstants.AccPrivate) != 0)
+						modifiers &= ~ClassFileConstants.AccPrivate;
+				}
+			} else {
+				int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
+				if ((accessorBits & (accessorBits - 1)) > 1) {
+					problemReporter().illegalVisibilityModifierCombinationForMemberType(sourceType);
+
+					// need to keep the less restrictive so disable Protected/Private as necessary
+					if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
+						if ((accessorBits & ClassFileConstants.AccProtected) != 0)
+							modifiers &= ~ClassFileConstants.AccProtected;
+						if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
+							modifiers &= ~ClassFileConstants.AccPrivate;
+					} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
+						modifiers &= ~ClassFileConstants.AccPrivate;
+					}
+				}
+			}
+
+			// static modifier test
+			if ((realModifiers & ClassFileConstants.AccStatic) == 0) {
+				if (enclosingType.isInterface())
+					modifiers |= ClassFileConstants.AccStatic;
+			} else if (!enclosingType.isStatic()) {
+				// error the enclosing type of a static field must be static or a top-level type
+				problemReporter().illegalStaticModifierForMemberType(sourceType);
+			}
+		}
+
+		sourceType.modifiers = modifiers;
+	}
+
+	/* This method checks the modifiers of a field.
+	*
+	* 9.3 & 8.3
+	* Need to integrate the check for the final modifiers for nested types
+	*
+	* Note : A scope is accessible by : fieldBinding.declaringClass.scope
+	*/
+	private void checkAndSetModifiersForField(FieldBinding fieldBinding, FieldDeclaration fieldDecl) {
+		int modifiers = fieldBinding.modifiers;
+		final ReferenceBinding declaringClass = fieldBinding.declaringClass;
+		if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
+			problemReporter().duplicateModifierForField(declaringClass, fieldDecl);
+
+		if (declaringClass.isInterface()) {
+			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
+			// set the modifiers
+			modifiers |= IMPLICIT_MODIFIERS;
+
+			// and then check that they are the only ones
+			if ((modifiers & ExtraCompilerModifiers.AccJustFlag) != IMPLICIT_MODIFIERS) {
+				if ((declaringClass.modifiers  & ClassFileConstants.AccAnnotation) != 0)
+					problemReporter().illegalModifierForAnnotationField(fieldDecl);
+				else
+					problemReporter().illegalModifierForInterfaceField(fieldDecl);
+			}
+			fieldBinding.modifiers = modifiers;
+			return;
+		} else if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+			// check that they are not modifiers in source
+			if ((modifiers & ExtraCompilerModifiers.AccJustFlag) != 0)
+				problemReporter().illegalModifierForEnumConstant(declaringClass, fieldDecl);
+
+			// set the modifiers
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=267670. Force all enumerators to be marked
+			// as used locally. We are unable to track the usage of these reliably as they could be used
+			// in non obvious ways via the synthesized methods values() and valueOf(String) or by using 
+			// Enum.valueOf(Class<T>, String).
+			final int IMPLICIT_MODIFIERS = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccEnum | ExtraCompilerModifiers.AccLocallyUsed;
+			fieldBinding.modifiers|= IMPLICIT_MODIFIERS;
+			return;
+		}
+
+		// after this point, tests on the 16 bits reserved.
+		int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+		final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccFinal | ClassFileConstants.AccStatic | ClassFileConstants.AccTransient | ClassFileConstants.AccVolatile);
+		if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+			problemReporter().illegalModifierForField(declaringClass, fieldDecl);
+			modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS;
+		}
+
+		int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
+		if ((accessorBits & (accessorBits - 1)) > 1) {
+			problemReporter().illegalVisibilityModifierCombinationForField(declaringClass, fieldDecl);
+
+			// need to keep the less restrictive so disable Protected/Private as necessary
+			if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
+				if ((accessorBits & ClassFileConstants.AccProtected) != 0)
+					modifiers &= ~ClassFileConstants.AccProtected;
+				if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
+					modifiers &= ~ClassFileConstants.AccPrivate;
+			} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
+				modifiers &= ~ClassFileConstants.AccPrivate;
+			}
+		}
+
+		if ((realModifiers & (ClassFileConstants.AccFinal | ClassFileConstants.AccVolatile)) == (ClassFileConstants.AccFinal | ClassFileConstants.AccVolatile))
+			problemReporter().illegalModifierCombinationFinalVolatileForField(declaringClass, fieldDecl);
+
+		if (fieldDecl.initialization == null && (modifiers & ClassFileConstants.AccFinal) != 0)
+			modifiers |= ExtraCompilerModifiers.AccBlankFinal;
+		fieldBinding.modifiers = modifiers;
+	}
+
+	public void checkParameterizedSuperTypeCollisions() {
+		// check for parameterized interface collisions (when different parameterizations occur)
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		ReferenceBinding[] interfaces = sourceType.superInterfaces;
+		Map invocations = new HashMap(2);
+		ReferenceBinding itsSuperclass = sourceType.isInterface() ? null : sourceType.superclass;
+		nextInterface: for (int i = 0, length = interfaces.length; i < length; i++) {
+			ReferenceBinding one =  interfaces[i];
+			if (one == null) continue nextInterface;
+			if (itsSuperclass != null && hasErasedCandidatesCollisions(itsSuperclass, one, invocations, sourceType, this.referenceContext))
+				continue nextInterface;
+			nextOtherInterface: for (int j = 0; j < i; j++) {
+				ReferenceBinding two = interfaces[j];
+				if (two == null) continue nextOtherInterface;
+				if (hasErasedCandidatesCollisions(one, two, invocations, sourceType, this.referenceContext))
+					continue nextInterface;
+			}
+		}
+
+		TypeParameter[] typeParameters = this.referenceContext.typeParameters;
+		nextVariable : for (int i = 0, paramLength = typeParameters == null ? 0 : typeParameters.length; i < paramLength; i++) {
+			TypeParameter typeParameter = typeParameters[i];
+			TypeVariableBinding typeVariable = typeParameter.binding;
+			if (typeVariable == null || !typeVariable.isValidBinding()) continue nextVariable;
+
+			TypeReference[] boundRefs = typeParameter.bounds;
+			if (boundRefs != null) {
+				boolean checkSuperclass = typeVariable.firstBound == typeVariable.superclass;
+				for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
+					TypeReference typeRef = boundRefs[j];
+					TypeBinding superType = typeRef.resolvedType;
+					if (superType == null || !superType.isValidBinding()) continue;
+
+					// check against superclass
+					if (checkSuperclass)
+						if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef))
+							continue nextVariable;
+					// check against superinterfaces
+					for (int index = typeVariable.superInterfaces.length; --index >= 0;)
+						if (hasErasedCandidatesCollisions(superType, typeVariable.superInterfaces[index], invocations, typeVariable, typeRef))
+							continue nextVariable;
+				}
+			}
+		}
+
+		ReferenceBinding[] memberTypes = this.referenceContext.binding.memberTypes;
+		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES)
+			for (int i = 0, size = memberTypes.length; i < size; i++)
+				 ((SourceTypeBinding) memberTypes[i]).scope.checkParameterizedSuperTypeCollisions();
+	}
+
+	private void checkForInheritedMemberTypes(SourceTypeBinding sourceType) {
+		// search up the hierarchy of the sourceType to see if any superType defines a member type
+		// when no member types are defined, tag the sourceType & each superType with the HasNoMemberTypes bit
+		// assumes super types have already been checked & tagged
+		ReferenceBinding currentType = sourceType;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		do {
+			if (currentType.hasMemberTypes()) // avoid resolving member types eagerly
+				return;
+
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			// in code assist cases when source types are added late, may not be finished connecting hierarchy
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		} while ((currentType = currentType.superclass()) != null && (currentType.tagBits & TagBits.HasNoMemberTypes) == 0);
+
+		if (interfacesToVisit != null) {
+			// contains the interfaces between the sourceType and any superclass, which was tagged as having no member types
+			boolean needToTag = false;
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				if ((anInterface.tagBits & TagBits.HasNoMemberTypes) == 0) { // skip interface if it already knows it has no member types
+					if (anInterface.hasMemberTypes()) // avoid resolving member types eagerly
+						return;
+
+					needToTag = true;
+					ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+					if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+						int itsLength = itsInterfaces.length;
+						if (nextPosition + itsLength >= interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+						nextInterface : for (int a = 0; a < itsLength; a++) {
+							ReferenceBinding next = itsInterfaces[a];
+							for (int b = 0; b < nextPosition; b++)
+								if (next == interfacesToVisit[b]) continue nextInterface;
+							interfacesToVisit[nextPosition++] = next;
+						}
+					}
+				}
+			}
+
+			if (needToTag) {
+				for (int i = 0; i < nextPosition; i++)
+					interfacesToVisit[i].tagBits |= TagBits.HasNoMemberTypes;
+			}
+		}
+
+		// tag the sourceType and all of its superclasses, unless they have already been tagged
+		currentType = sourceType;
+		do {
+			currentType.tagBits |= TagBits.HasNoMemberTypes;
+		} while ((currentType = currentType.superclass()) != null && (currentType.tagBits & TagBits.HasNoMemberTypes) == 0);
+	}
+
+	// Perform deferred bound checks for parameterized type references (only done after hierarchy is connected)
+	public void  checkParameterizedTypeBounds() {
+		for (int i = 0, l = this.deferredBoundChecks == null ? 0 : this.deferredBoundChecks.size(); i < l; i++)
+			((TypeReference) this.deferredBoundChecks.get(i)).checkBounds(this);
+		this.deferredBoundChecks = null;
+
+		ReferenceBinding[] memberTypes = this.referenceContext.binding.memberTypes;
+		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES)
+			for (int i = 0, size = memberTypes.length; i < size; i++)
+				 ((SourceTypeBinding) memberTypes[i]).scope.checkParameterizedTypeBounds();
+	}
+
+	private void connectMemberTypes() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		ReferenceBinding[] memberTypes = sourceType.memberTypes;
+		if (memberTypes != null && memberTypes != Binding.NO_MEMBER_TYPES) {
+			for (int i = 0, size = memberTypes.length; i < size; i++)
+				 ((SourceTypeBinding) memberTypes[i]).scope.connectTypeHierarchy();
+		}
+	}
+	/*
+		Our current belief based on available JCK tests is:
+			inherited member types are visible as a potential superclass.
+			inherited interfaces are not visible when defining a superinterface.
+
+		Error recovery story:
+			ensure the superclass is set to java.lang.Object if a problem is detected
+			resolving the superclass.
+
+		Answer false if an error was reported against the sourceType.
+	*/
+	private boolean connectSuperclass() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if (sourceType.id == TypeIds.T_JavaLangObject) { // handle the case of redefining java.lang.Object up front
+			sourceType.superclass = null;
+			sourceType.superInterfaces = Binding.NO_SUPERINTERFACES;
+			if (!sourceType.isClass())
+				problemReporter().objectMustBeClass(sourceType);
+			if (this.referenceContext.superclass != null || (this.referenceContext.superInterfaces != null && this.referenceContext.superInterfaces.length > 0))
+				problemReporter().objectCannotHaveSuperTypes(sourceType);
+			return true; // do not propagate Object's hierarchy problems down to every subtype
+		}
+		if (this.referenceContext.superclass == null) {
+			if (sourceType.isEnum() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) // do not connect if source < 1.5 as enum already got flagged as syntax error
+				return connectEnumSuperclass();
+			sourceType.superclass = getJavaLangObject();
+			return !detectHierarchyCycle(sourceType, sourceType.superclass, null);
+		}
+		TypeReference superclassRef = this.referenceContext.superclass;
+		ReferenceBinding superclass = findSupertype(superclassRef);
+		if (superclass != null) { // is null if a cycle was detected cycle or a problem
+			if (!superclass.isClass() && (superclass.tagBits & TagBits.HasMissingType) == 0) {
+				problemReporter().superclassMustBeAClass(sourceType, superclassRef, superclass);
+			} else if (superclass.isFinal()) {
+				problemReporter().classExtendFinalClass(sourceType, superclassRef, superclass);
+			} else if ((superclass.tagBits & TagBits.HasDirectWildcard) != 0) {
+				problemReporter().superTypeCannotUseWildcard(sourceType, superclassRef, superclass);
+			} else if (superclass.erasure().id == TypeIds.T_JavaLangEnum) {
+				problemReporter().cannotExtendEnum(sourceType, superclassRef, superclass);
+			} else if ((superclass.tagBits & TagBits.HierarchyHasProblems) != 0
+					|| !superclassRef.resolvedType.isValidBinding()) {
+				sourceType.superclass = superclass;
+				sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype
+				return superclassRef.resolvedType.isValidBinding(); // reported some error against the source type ?
+			} else {
+				// only want to reach here when no errors are reported
+				sourceType.superclass = superclass;
+				sourceType.typeBits |= (superclass.typeBits & TypeIds.InheritableBits);
+				// further analysis against white lists for the unlikely case we are compiling java.io.*:
+				if ((sourceType.typeBits & (TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) != 0)
+					sourceType.typeBits |= sourceType.applyCloseableWhitelists();
+				return true;
+			}
+		}
+		sourceType.tagBits |= TagBits.HierarchyHasProblems;
+		sourceType.superclass = getJavaLangObject();
+		if ((sourceType.superclass.tagBits & TagBits.BeginHierarchyCheck) == 0)
+			detectHierarchyCycle(sourceType, sourceType.superclass, null);
+		return false; // reported some error against the source type
+	}
+
+	/**
+	 *  enum X (implicitly) extends Enum<X>
+	 */
+	private boolean connectEnumSuperclass() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		ReferenceBinding rootEnumType = getJavaLangEnum();
+		if ((rootEnumType.tagBits & TagBits.HasMissingType) != 0) {
+			sourceType.tagBits |= TagBits.HierarchyHasProblems; // mark missing supertpye
+			sourceType.superclass = rootEnumType;
+			return false;
+		}
+		boolean foundCycle = detectHierarchyCycle(sourceType, rootEnumType, null);
+		// arity check for well-known Enum<E>
+		TypeVariableBinding[] refTypeVariables = rootEnumType.typeVariables();
+		if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic
+			problemReporter().nonGenericTypeCannotBeParameterized(0, null, rootEnumType, new TypeBinding[]{ sourceType });
+			return false; // cannot reach here as AbortCompilation is thrown
+		} else if (1 != refTypeVariables.length) { // check arity
+			problemReporter().incorrectArityForParameterizedType(null, rootEnumType, new TypeBinding[]{ sourceType });
+			return false; // cannot reach here as AbortCompilation is thrown
+		}
+		// check argument type compatibility
+		ParameterizedTypeBinding  superType = environment().createParameterizedType(
+			rootEnumType,
+			new TypeBinding[]{
+				environment().convertToRawType(sourceType, false /*do not force conversion of enclosing types*/),
+			} ,
+			null);
+		sourceType.tagBits |= (superType.tagBits & TagBits.HierarchyHasProblems); // propagate if missing supertpye
+		sourceType.superclass = superType;
+		// bound check (in case of bogus definition of Enum type)
+		if (refTypeVariables[0].boundCheck(superType, sourceType, this) != TypeConstants.OK) {
+			problemReporter().typeMismatchError(rootEnumType, refTypeVariables[0], sourceType, null);
+		}
+		return !foundCycle;
+	}
+
+	/*
+		Our current belief based on available JCK 1.3 tests is:
+			inherited member types are visible as a potential superclass.
+			inherited interfaces are visible when defining a superinterface.
+
+		Error recovery story:
+			ensure the superinterfaces contain only valid visible interfaces.
+
+		Answer false if an error was reported against the sourceType.
+	*/
+	private boolean connectSuperInterfaces() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		sourceType.superInterfaces = Binding.NO_SUPERINTERFACES;
+		if (this.referenceContext.superInterfaces == null) {
+			if (sourceType.isAnnotationType() && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) {
+				ReferenceBinding annotationType = getJavaLangAnnotationAnnotation();
+				boolean foundCycle = detectHierarchyCycle(sourceType, annotationType, null);
+				sourceType.superInterfaces = new ReferenceBinding[] { annotationType };
+				return !foundCycle;
+			}
+			return true;
+		}
+		if (sourceType.id == TypeIds.T_JavaLangObject) // already handled the case of redefining java.lang.Object
+			return true;
+
+		boolean noProblems = true;
+		int length = this.referenceContext.superInterfaces.length;
+		ReferenceBinding[] interfaceBindings = new ReferenceBinding[length];
+		int count = 0;
+		nextInterface : for (int i = 0; i < length; i++) {
+		    TypeReference superInterfaceRef = this.referenceContext.superInterfaces[i];
+			ReferenceBinding superInterface = findSupertype(superInterfaceRef);
+			if (superInterface == null) { // detected cycle
+				sourceType.tagBits |= TagBits.HierarchyHasProblems;
+				noProblems = false;
+				continue nextInterface;
+			}
+
+			// check for simple interface collisions
+			// Check for a duplicate interface once the name is resolved, otherwise we may be confused (i.e. a.b.I and c.d.I)
+			for (int j = 0; j < i; j++) {
+				if (interfaceBindings[j] == superInterface) {
+					problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface);
+					sourceType.tagBits |= TagBits.HierarchyHasProblems;
+					noProblems = false;
+					continue nextInterface;
+				}
+			}
+			if (!superInterface.isInterface() && (superInterface.tagBits & TagBits.HasMissingType) == 0) {
+				problemReporter().superinterfaceMustBeAnInterface(sourceType, superInterfaceRef, superInterface);
+				sourceType.tagBits |= TagBits.HierarchyHasProblems;
+				noProblems = false;
+				continue nextInterface;
+			} else if (superInterface.isAnnotationType()){
+				problemReporter().annotationTypeUsedAsSuperinterface(sourceType, superInterfaceRef, superInterface);
+			}
+			if ((superInterface.tagBits & TagBits.HasDirectWildcard) != 0) {
+				problemReporter().superTypeCannotUseWildcard(sourceType, superInterfaceRef, superInterface);
+				sourceType.tagBits |= TagBits.HierarchyHasProblems;
+				noProblems = false;
+				continue nextInterface;
+			}
+			if ((superInterface.tagBits & TagBits.HierarchyHasProblems) != 0
+					|| !superInterfaceRef.resolvedType.isValidBinding()) {
+				sourceType.tagBits |= TagBits.HierarchyHasProblems; // propagate if missing supertype
+				noProblems &= superInterfaceRef.resolvedType.isValidBinding();
+			}
+			// only want to reach here when no errors are reported
+			sourceType.typeBits |= (superInterface.typeBits & TypeIds.InheritableBits);
+			interfaceBindings[count++] = superInterface;
+		}
+		// hold onto all correctly resolved superinterfaces
+		if (count > 0) {
+			if (count != length)
+				System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count);
+			sourceType.superInterfaces = interfaceBindings;
+		}
+		return noProblems;
+	}
+
+	void connectTypeHierarchy() {
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
+			sourceType.tagBits |= TagBits.BeginHierarchyCheck;
+			environment().typesBeingConnected.add(sourceType);
+			boolean noProblems = connectSuperclass();
+			noProblems &= connectSuperInterfaces();
+			environment().typesBeingConnected.remove(sourceType);
+			sourceType.tagBits |= TagBits.EndHierarchyCheck;
+			noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
+			sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
+			if (noProblems && sourceType.isHierarchyInconsistent())
+				problemReporter().hierarchyHasProblems(sourceType);
+		}
+		connectMemberTypes();
+		LookupEnvironment env = environment();
+		try {
+			env.missingClassFileLocation = this.referenceContext;
+			checkForInheritedMemberTypes(sourceType);
+		} catch (AbortCompilation e) {
+			e.updateContext(this.referenceContext, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	private void connectTypeHierarchyWithoutMembers() {
+		// must ensure the imports are resolved
+		if (this.parent instanceof CompilationUnitScope) {
+			if (((CompilationUnitScope) this.parent).imports == null)
+				 ((CompilationUnitScope) this.parent).checkAndSetImports();
+		} else if (this.parent instanceof ClassScope) {
+			// ensure that the enclosing type has already been checked
+			 ((ClassScope) this.parent).connectTypeHierarchyWithoutMembers();
+		}
+
+		// double check that the hierarchy search has not already begun...
+		SourceTypeBinding sourceType = this.referenceContext.binding;
+		if ((sourceType.tagBits & TagBits.BeginHierarchyCheck) != 0)
+			return;
+
+		sourceType.tagBits |= TagBits.BeginHierarchyCheck;
+		environment().typesBeingConnected.add(sourceType);
+		boolean noProblems = connectSuperclass();
+		noProblems &= connectSuperInterfaces();
+		environment().typesBeingConnected.remove(sourceType);
+		sourceType.tagBits |= TagBits.EndHierarchyCheck;
+		noProblems &= connectTypeVariables(this.referenceContext.typeParameters, false);
+		sourceType.tagBits |= TagBits.TypeVariablesAreConnected;
+		if (noProblems && sourceType.isHierarchyInconsistent())
+			problemReporter().hierarchyHasProblems(sourceType);
+	}
+
+	public boolean detectHierarchyCycle(TypeBinding superType, TypeReference reference) {
+		if (!(superType instanceof ReferenceBinding)) return false;
+
+		if (reference == this.superTypeReference) { // see findSuperType()
+			if (superType.isTypeVariable())
+				return false; // error case caught in resolveSuperType()
+			// abstract class X<K,V> implements java.util.Map<K,V>
+			//    static abstract class M<K,V> implements Entry<K,V>
+			if (superType.isParameterizedType())
+				superType = ((ParameterizedTypeBinding) superType).genericType();
+			compilationUnitScope().recordSuperTypeReference(superType); // to record supertypes
+			return detectHierarchyCycle(this.referenceContext.binding, (ReferenceBinding) superType, reference);
+		}
+		// Reinstate the code deleted by the fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=205235
+		// For details, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057. 
+		if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0 && superType instanceof SourceTypeBinding)
+			// ensure if this is a source superclass that it has already been checked
+			((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();
+
+		return false;
+	}
+
+	// Answer whether a cycle was found between the sourceType & the superType
+	private boolean detectHierarchyCycle(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) {
+		if (superType.isRawType())
+			superType = ((RawTypeBinding) superType).genericType();
+		// by this point the superType must be a binary or source type
+
+		if (sourceType == superType) {
+			problemReporter().hierarchyCircularity(sourceType, superType, reference);
+			sourceType.tagBits |= TagBits.HierarchyHasProblems;
+			return true;
+		}
+
+		if (superType.isMemberType()) {
+			ReferenceBinding current = superType.enclosingType();
+			do {
+				if (current.isHierarchyBeingActivelyConnected() && current == sourceType) {
+					problemReporter().hierarchyCircularity(sourceType, current, reference);
+					sourceType.tagBits |= TagBits.HierarchyHasProblems;
+					current.tagBits |= TagBits.HierarchyHasProblems;
+					return true;
+				}
+			} while ((current = current.enclosingType()) != null);
+		}
+
+		if (superType.isBinaryBinding()) {
+			// force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of:
+			//		- a binary type... this case MUST be caught & reported here
+			//		- another source type... this case is reported against the other source type
+			boolean hasCycle = false;
+			ReferenceBinding parentType = superType.superclass();
+			if (parentType != null) {
+				if (sourceType == parentType) {
+					problemReporter().hierarchyCircularity(sourceType, superType, reference);
+					sourceType.tagBits |= TagBits.HierarchyHasProblems;
+					superType.tagBits |= TagBits.HierarchyHasProblems;
+					return true;
+				}
+				if (parentType.isParameterizedType())
+					parentType = ((ParameterizedTypeBinding) parentType).genericType();
+				hasCycle |= detectHierarchyCycle(sourceType, parentType, reference);
+				if ((parentType.tagBits & TagBits.HierarchyHasProblems) != 0) {
+					sourceType.tagBits |= TagBits.HierarchyHasProblems;
+					parentType.tagBits |= TagBits.HierarchyHasProblems; // propagate down the hierarchy
+				}
+			}
+
+			ReferenceBinding[] itsInterfaces = superType.superInterfaces();
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				for (int i = 0, length = itsInterfaces.length; i < length; i++) {
+					ReferenceBinding anInterface = itsInterfaces[i];
+					if (sourceType == anInterface) {
+						problemReporter().hierarchyCircularity(sourceType, superType, reference);
+						sourceType.tagBits |= TagBits.HierarchyHasProblems;
+						superType.tagBits |= TagBits.HierarchyHasProblems;
+						return true;
+					}
+					if (anInterface.isParameterizedType())
+						anInterface = ((ParameterizedTypeBinding) anInterface).genericType();
+					hasCycle |= detectHierarchyCycle(sourceType, anInterface, reference);
+					if ((anInterface.tagBits & TagBits.HierarchyHasProblems) != 0) {
+						sourceType.tagBits |= TagBits.HierarchyHasProblems;
+						superType.tagBits |= TagBits.HierarchyHasProblems;
+					}
+				}
+			}
+			return hasCycle;
+		}
+
+		if (superType.isHierarchyBeingActivelyConnected()) {
+			org.eclipse.jdt.internal.compiler.ast.TypeReference ref = ((SourceTypeBinding) superType).scope.superTypeReference;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133071
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=121734
+			if (ref != null && ref.resolvedType != null && ((ReferenceBinding) ref.resolvedType).isHierarchyBeingActivelyConnected()) {
+				problemReporter().hierarchyCircularity(sourceType, superType, reference);
+				sourceType.tagBits |= TagBits.HierarchyHasProblems;
+				superType.tagBits |= TagBits.HierarchyHasProblems;
+				return true;
+			}
+			if (ref != null && ref.resolvedType == null) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=319885 Don't cry foul prematurely.
+				// Check the edges traversed to see if there really is a cycle.
+				char [] referredName = ref.getLastToken(); 
+				for (Iterator iter = environment().typesBeingConnected.iterator(); iter.hasNext();) {
+					SourceTypeBinding type = (SourceTypeBinding) iter.next();
+					if (CharOperation.equals(referredName, type.sourceName())) {
+						problemReporter().hierarchyCircularity(sourceType, superType, reference);
+						sourceType.tagBits |= TagBits.HierarchyHasProblems;
+						superType.tagBits |= TagBits.HierarchyHasProblems;
+						return true;
+					}
+				}
+			}
+		}
+		if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0)
+			// ensure if this is a source superclass that it has already been checked
+			((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();
+		if ((superType.tagBits & TagBits.HierarchyHasProblems) != 0)
+			sourceType.tagBits |= TagBits.HierarchyHasProblems;
+		return false;
+	}
+
+	private ReferenceBinding findSupertype(TypeReference typeReference) {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		LookupEnvironment env = unitScope.environment;
+		try {
+			env.missingClassFileLocation = typeReference;
+			typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes
+			unitScope.recordQualifiedReference(typeReference.getTypeName());
+			this.superTypeReference = typeReference;
+			ReferenceBinding superType = (ReferenceBinding) typeReference.resolveSuperType(this);
+			return superType;
+		} catch (AbortCompilation e) {
+			SourceTypeBinding sourceType = this.referenceContext.binding;
+			if (sourceType.superInterfaces == null)  sourceType.superInterfaces = Binding.NO_SUPERINTERFACES; // be more resilient for hierarchies (144976)
+			e.updateContext(typeReference, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+			this.superTypeReference = null;
+		}
+	}
+
+	/* Answer the problem reporter to use for raising new problems.
+	*
+	* Note that as a side-effect, this updates the current reference context
+	* (unit, type or method) in case the problem handler decides it is necessary
+	* to abort.
+	*/
+	public ProblemReporter problemReporter() {
+		MethodScope outerMethodScope;
+		if ((outerMethodScope = outerMostMethodScope()) == null) {
+			ProblemReporter problemReporter = referenceCompilationUnit().problemReporter;
+			problemReporter.referenceContext = this.referenceContext;
+			return problemReporter;
+		}
+		return outerMethodScope.problemReporter();
+	}
+
+	/* Answer the reference type of this scope.
+	* It is the nearest enclosing type of this scope.
+	*/
+	public TypeDeclaration referenceType() {
+		return this.referenceContext;
+	}
+
+	public String toString() {
+		if (this.referenceContext != null)
+			return "--- Class Scope ---\n\n"  //$NON-NLS-1$
+							+ this.referenceContext.binding.toString();
+		return "--- Class Scope ---\n\n Binding not initialized" ; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
new file mode 100644
index 0000000..9d6fd3d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -0,0 +1,925 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Erling Ellingsen -  patch for bug 125570
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+public class CompilationUnitScope extends Scope {
+
+	public LookupEnvironment environment;
+	public CompilationUnitDeclaration referenceContext;
+	public char[][] currentPackageName;
+	public PackageBinding fPackage;
+	public ImportBinding[] imports;
+	public int importPtr;
+	public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage()
+
+	public SourceTypeBinding[] topLevelTypes;
+
+	private CompoundNameVector qualifiedReferences;
+	private SimpleNameVector simpleNameReferences;
+	private SimpleNameVector rootReferences;
+	private ObjectVector referencedTypes;
+	private ObjectVector referencedSuperTypes;
+
+	HashtableOfType constantPoolNameUsage;
+	private int captureID = 1;
+	
+	private ImportBinding[] tempImports;	// to keep a record of resolved imports while traversing all in faultInImports()
+	
+public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) {
+	super(COMPILATION_UNIT_SCOPE, null);
+	this.environment = environment;
+	this.referenceContext = unit;
+	unit.scope = this;
+	this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
+
+	if (compilerOptions().produceReferenceInfo) {
+		this.qualifiedReferences = new CompoundNameVector();
+		this.simpleNameReferences = new SimpleNameVector();
+		this.rootReferences = new SimpleNameVector();
+		this.referencedTypes = new ObjectVector();
+		this.referencedSuperTypes = new ObjectVector();
+	} else {
+		this.qualifiedReferences = null; // used to test if dependencies should be recorded
+		this.simpleNameReferences = null;
+		this.rootReferences = null;
+		this.referencedTypes = null;
+		this.referencedSuperTypes = null;
+	}
+}
+void buildFieldsAndMethods() {
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
+		this.topLevelTypes[i].scope.buildFieldsAndMethods();
+}
+void buildTypeBindings(AccessRestriction accessRestriction) {
+	this.topLevelTypes = new SourceTypeBinding[0]; // want it initialized if the package cannot be resolved
+	boolean firstIsSynthetic = false;
+	if (this.referenceContext.compilationResult.compilationUnit != null) {
+		char[][] expectedPackageName = this.referenceContext.compilationResult.compilationUnit.getPackageName();
+		if (expectedPackageName != null
+				&& !CharOperation.equals(this.currentPackageName, expectedPackageName)) {
+
+			// only report if the unit isn't structurally empty
+			if (this.referenceContext.currentPackage != null
+					|| this.referenceContext.types != null
+					|| this.referenceContext.imports != null) {
+				problemReporter().packageIsNotExpectedPackage(this.referenceContext);
+			}
+			this.currentPackageName = expectedPackageName.length == 0 ? CharOperation.NO_CHAR_CHAR : expectedPackageName;
+		}
+	}
+	if (this.currentPackageName == CharOperation.NO_CHAR_CHAR) {
+		// environment default package is never null
+		this.fPackage = this.environment.defaultPackage;
+	} else {
+		if ((this.fPackage = this.environment.createPackage(this.currentPackageName)) == null) {
+			if (this.referenceContext.currentPackage != null) {
+				problemReporter().packageCollidesWithType(this.referenceContext); // only report when the unit has a package statement
+			}
+			// ensure fPackage is not null
+			this.fPackage = this.environment.defaultPackage;
+			return;
+		} else if (this.referenceContext.isPackageInfo()) {
+			// resolve package annotations now if this is "package-info.java".
+			if (this.referenceContext.types == null || this.referenceContext.types.length == 0) {
+				this.referenceContext.types = new TypeDeclaration[1];
+				this.referenceContext.createPackageInfoType();
+				firstIsSynthetic = true;
+			}
+			// ensure the package annotations are copied over before resolution
+			if (this.referenceContext.currentPackage != null && this.referenceContext.currentPackage.annotations != null) {
+				this.referenceContext.types[0].annotations = this.referenceContext.currentPackage.annotations;
+			}
+		}
+		recordQualifiedReference(this.currentPackageName); // always dependent on your own package
+	}
+
+	// Skip typeDeclarations which know of previously reported errors
+	TypeDeclaration[] types = this.referenceContext.types;
+	int typeLength = (types == null) ? 0 : types.length;
+	this.topLevelTypes = new SourceTypeBinding[typeLength];
+	int count = 0;
+	nextType: for (int i = 0; i < typeLength; i++) {
+		TypeDeclaration typeDecl = types[i];
+		if (this.environment.isProcessingAnnotations && this.environment.isMissingType(typeDecl.name))
+			throw new SourceTypeCollisionException(); // resolved a type ref before APT generated the type
+		ReferenceBinding typeBinding = this.fPackage.getType0(typeDecl.name);
+		recordSimpleReference(typeDecl.name); // needed to detect collision cases
+		if (typeBinding != null && typeBinding.isValidBinding() && !(typeBinding instanceof UnresolvedReferenceBinding)) {
+			// if its an unresolved binding - its fixed up whenever its needed, see UnresolvedReferenceBinding.resolve()
+			if (this.environment.isProcessingAnnotations)
+				throw new SourceTypeCollisionException(); // resolved a type ref before APT generated the type
+			// if a type exists, check that its a valid type
+			// it can be a NotFound problem type if its a secondary type referenced before its primary type found in additional units
+			// and it can be an unresolved type which is now being defined
+			problemReporter().duplicateTypes(this.referenceContext, typeDecl);
+			continue nextType;
+		}
+		if (this.fPackage != this.environment.defaultPackage && this.fPackage.getPackage(typeDecl.name) != null) {
+			// if a package exists, it must be a valid package - cannot be a NotFound problem package
+			// this is now a warning since a package does not really 'exist' until it contains a type, see JLS v2, 7.4.3
+			problemReporter().typeCollidesWithPackage(this.referenceContext, typeDecl);
+		}
+
+		if ((typeDecl.modifiers & ClassFileConstants.AccPublic) != 0) {
+			char[] mainTypeName;
+			if ((mainTypeName = this.referenceContext.getMainTypeName()) != null // mainTypeName == null means that implementor of ICompilationUnit decided to return null
+					&& !CharOperation.equals(mainTypeName, typeDecl.name)) {
+				problemReporter().publicClassMustMatchFileName(this.referenceContext, typeDecl);
+				// tolerate faulty main type name (91091), allow to proceed into type construction
+			}
+		}
+
+		ClassScope child = new ClassScope(this, typeDecl);
+		SourceTypeBinding type = child.buildType(null, this.fPackage, accessRestriction);
+		if (firstIsSynthetic && i == 0)
+			type.modifiers |= ClassFileConstants.AccSynthetic;
+		if (type != null)
+			this.topLevelTypes[count++] = type;
+	}
+
+	// shrink topLevelTypes... only happens if an error was reported
+	if (count != this.topLevelTypes.length)
+		System.arraycopy(this.topLevelTypes, 0, this.topLevelTypes = new SourceTypeBinding[count], 0, count);
+}
+void checkAndSetImports() {
+	if (this.referenceContext.imports == null) {
+		this.imports = getDefaultImports();
+		return;
+	}
+
+	// allocate the import array, add java.lang.* by default
+	int numberOfStatements = this.referenceContext.imports.length;
+	int numberOfImports = numberOfStatements + 1;
+	for (int i = 0; i < numberOfStatements; i++) {
+		ImportReference importReference = this.referenceContext.imports[i];
+		if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
+			numberOfImports--;
+			break;
+		}
+	}
+	ImportBinding[] resolvedImports = new ImportBinding[numberOfImports];
+	resolvedImports[0] = getDefaultImports()[0];
+	int index = 1;
+
+	nextImport : for (int i = 0; i < numberOfStatements; i++) {
+		ImportReference importReference = this.referenceContext.imports[i];
+		char[][] compoundName = importReference.tokens;
+
+		// skip duplicates or imports of the current package
+		for (int j = 0; j < index; j++) {
+			ImportBinding resolved = resolvedImports[j];
+			if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic())
+				if (CharOperation.equals(compoundName, resolvedImports[j].compoundName))
+					continue nextImport;
+		}
+
+		if ((importReference.bits & ASTNode.OnDemand) != 0) {
+			if (CharOperation.equals(compoundName, this.currentPackageName))
+				continue nextImport;
+
+			Binding importBinding = findImport(compoundName, compoundName.length);
+			if (!importBinding.isValidBinding() || (importReference.isStatic() && importBinding instanceof PackageBinding))
+				continue nextImport;	// we report all problems in faultInImports()
+			resolvedImports[index++] = new ImportBinding(compoundName, true, importBinding, importReference);
+		} else {
+			// resolve single imports only when the last name matches
+			resolvedImports[index++] = new ImportBinding(compoundName, false, null, importReference);
+		}
+	}
+
+	// shrink resolvedImports... only happens if an error was reported
+	if (resolvedImports.length > index)
+		System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
+	this.imports = resolvedImports;
+}
+
+/**
+ * Perform deferred check specific to parameterized types: bound checks, supertype collisions
+ */
+void checkParameterizedTypes() {
+	if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return;
+
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++) {
+		ClassScope scope = this.topLevelTypes[i].scope;
+		scope.checkParameterizedTypeBounds();
+		scope.checkParameterizedSuperTypeCollisions();
+	}
+}
+/*
+ * INTERNAL USE-ONLY
+ * Innerclasses get their name computed as they are generated, since some may not
+ * be actually outputed if sitting inside unreachable code.
+ */
+public char[] computeConstantPoolName(LocalTypeBinding localType) {
+	if (localType.constantPoolName != null) {
+		return localType.constantPoolName;
+	}
+	// delegates to the outermost enclosing classfile, since it is the only one with a global vision of its innertypes.
+
+	if (this.constantPoolNameUsage == null)
+		this.constantPoolNameUsage = new HashtableOfType();
+
+	ReferenceBinding outerMostEnclosingType = localType.scope.outerMostClassScope().enclosingSourceType();
+
+	// ensure there is not already such a local type name defined by the user
+	int index = 0;
+	char[] candidateName;
+	boolean isCompliant15 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5;
+	while(true) {
+		if (localType.isMemberType()){
+			if (index == 0){
+				candidateName = CharOperation.concat(
+					localType.enclosingType().constantPoolName(),
+					localType.sourceName,
+					'$');
+			} else {
+				// in case of collision, then member name gets extra $1 inserted
+				// e.g. class X { { class L{} new X(){ class L{} } } }
+				candidateName = CharOperation.concat(
+					localType.enclosingType().constantPoolName(),
+					'$',
+					String.valueOf(index).toCharArray(),
+					'$',
+					localType.sourceName);
+			}
+		} else if (localType.isAnonymousType()){
+			if (isCompliant15) {
+				// from 1.5 on, use immediately enclosing type name
+				candidateName = CharOperation.concat(
+					localType.enclosingType.constantPoolName(),
+					String.valueOf(index+1).toCharArray(),
+					'$');
+			} else {
+				candidateName = CharOperation.concat(
+					outerMostEnclosingType.constantPoolName(),
+					String.valueOf(index+1).toCharArray(),
+					'$');
+			}
+		} else {
+			// local type
+			if (isCompliant15) {
+				candidateName = CharOperation.concat(
+					CharOperation.concat(
+						localType.enclosingType().constantPoolName(),
+						String.valueOf(index+1).toCharArray(),
+						'$'),
+					localType.sourceName);
+			} else {
+				candidateName = CharOperation.concat(
+					outerMostEnclosingType.constantPoolName(),
+					'$',
+					String.valueOf(index+1).toCharArray(),
+					'$',
+					localType.sourceName);
+			}
+		}
+		if (this.constantPoolNameUsage.get(candidateName) != null) {
+			index ++;
+		} else {
+			this.constantPoolNameUsage.put(candidateName, localType);
+			break;
+		}
+	}
+	return candidateName;
+}
+
+void connectTypeHierarchy() {
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
+		this.topLevelTypes[i].scope.connectTypeHierarchy();
+}
+void faultInImports() {
+	if (this.typeOrPackageCache != null)
+		return; // can be called when a field constant is resolved before static imports
+	if (this.referenceContext.imports == null) {
+		this.typeOrPackageCache = new HashtableOfObject(1);
+		return;
+	}
+
+	// collect the top level type names if a single type import exists
+	int numberOfStatements = this.referenceContext.imports.length;
+	HashtableOfType typesBySimpleNames = null;
+	for (int i = 0; i < numberOfStatements; i++) {
+		if ((this.referenceContext.imports[i].bits & ASTNode.OnDemand) == 0) {
+			typesBySimpleNames = new HashtableOfType(this.topLevelTypes.length + numberOfStatements);
+			for (int j = 0, length = this.topLevelTypes.length; j < length; j++)
+				typesBySimpleNames.put(this.topLevelTypes[j].sourceName, this.topLevelTypes[j]);
+			break;
+		}
+	}
+
+	// allocate the import array, add java.lang.* by default
+	int numberOfImports = numberOfStatements + 1;
+	for (int i = 0; i < numberOfStatements; i++) {
+		ImportReference importReference = this.referenceContext.imports[i];
+		if (((importReference.bits & ASTNode.OnDemand) != 0) && CharOperation.equals(TypeConstants.JAVA_LANG, importReference.tokens) && !importReference.isStatic()) {
+			numberOfImports--;
+			break;
+		}
+	}
+	this.tempImports = new ImportBinding[numberOfImports];
+	this.tempImports[0] = getDefaultImports()[0];
+	this.importPtr = 1;
+	
+	// keep static imports with normal imports until there is a reason to split them up
+	// on demand imports continue to be packages & types. need to check on demand type imports for fields/methods
+	// single imports change from being just types to types or fields
+	nextImport : for (int i = 0; i < numberOfStatements; i++) {
+		ImportReference importReference = this.referenceContext.imports[i];
+		char[][] compoundName = importReference.tokens;
+
+		// skip duplicates or imports of the current package
+		for (int j = 0; j < this.importPtr; j++) {
+			ImportBinding resolved = this.tempImports[j];
+			if (resolved.onDemand == ((importReference.bits & ASTNode.OnDemand) != 0) && resolved.isStatic() == importReference.isStatic()) {
+				if (CharOperation.equals(compoundName, resolved.compoundName)) {
+					problemReporter().unusedImport(importReference); // since skipped, must be reported now
+					continue nextImport;
+				}
+			}
+		}
+		if ((importReference.bits & ASTNode.OnDemand) != 0) {
+			if (CharOperation.equals(compoundName, this.currentPackageName)) {
+				problemReporter().unusedImport(importReference); // since skipped, must be reported now
+				continue nextImport;
+			}
+
+			Binding importBinding = findImport(compoundName, compoundName.length);
+			if (!importBinding.isValidBinding()) {
+				problemReporter().importProblem(importReference, importBinding);
+				continue nextImport;
+			}
+			if (importReference.isStatic() && importBinding instanceof PackageBinding) {
+				problemReporter().cannotImportPackage(importReference);
+				continue nextImport;
+			}
+			recordImportBinding(new ImportBinding(compoundName, true, importBinding, importReference));
+		} else {
+			Binding importBinding = findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, importReference.isStatic());
+			if (!importBinding.isValidBinding()) {
+				if (importBinding.problemId() == ProblemReasons.Ambiguous) {
+					// keep it unless a duplicate can be found below
+				} else {
+					problemReporter().importProblem(importReference, importBinding);
+					continue nextImport;
+				}
+			}
+			if (importBinding instanceof PackageBinding) {
+				problemReporter().cannotImportPackage(importReference);
+				continue nextImport;
+			}
+			// all the code here which checks for valid bindings have been moved to the method 
+			// checkAndRecordImportBinding() since bug 361327
+			if(checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName) == -1)
+				continue nextImport;
+			if (importReference.isStatic()) {
+				// look for more static bindings being imported by single static import(bug 361327).
+				// findSingleImport() finds fields first, followed by method and then type
+				// So if a type is found, no fields and methods are available anyway
+				// similarly when method is found, type may be available but no field available for sure
+				if (importBinding.kind() == Binding.FIELD) {
+					checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE | Binding.METHOD, importReference);		
+				} else if (importBinding.kind() == Binding.METHOD) {
+					checkMoreStaticBindings(compoundName, typesBySimpleNames, Binding.TYPE, importReference);
+				}
+			}
+		}
+	}
+
+	// shrink resolvedImports... only happens if an error was reported
+	if (this.tempImports.length > this.importPtr)
+		System.arraycopy(this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr);
+	this.imports = this.tempImports;
+	int length = this.imports.length;
+	this.typeOrPackageCache = new HashtableOfObject(length);
+	for (int i = 0; i < length; i++) {
+		ImportBinding binding = this.imports[i];
+		if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding || binding instanceof ImportConflictBinding)
+			this.typeOrPackageCache.put(binding.compoundName[binding.compoundName.length - 1], binding);
+	}
+}
+public void faultInTypes() {
+	faultInImports();
+
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
+		this.topLevelTypes[i].faultInTypesForFieldsAndMethods();
+}
+// this API is for code assist purpose
+public Binding findImport(char[][] compoundName, boolean findStaticImports, boolean onDemand) {
+	if(onDemand) {
+		return findImport(compoundName, compoundName.length);
+	} else {
+		return findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, findStaticImports);
+	}
+}
+private Binding findImport(char[][] compoundName, int length) {
+	recordQualifiedReference(compoundName);
+
+	Binding binding = this.environment.getTopLevelPackage(compoundName[0]);
+	int i = 1;
+	foundNothingOrType: if (binding != null) {
+		PackageBinding packageBinding = (PackageBinding) binding;
+		while (i < length) {
+			binding = packageBinding.getTypeOrPackage(compoundName[i++]);
+			if (binding == null || !binding.isValidBinding()) {
+				binding = null;
+				break foundNothingOrType;
+			}
+			if (!(binding instanceof PackageBinding))
+				break foundNothingOrType;
+
+			packageBinding = (PackageBinding) binding;
+		}
+		return packageBinding;
+	}
+
+	ReferenceBinding type;
+	if (binding == null) {
+		if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+			return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, ProblemReasons.NotFound);
+		type = findType(compoundName[0], this.environment.defaultPackage, this.environment.defaultPackage);
+		if (type == null || !type.isValidBinding())
+			return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, ProblemReasons.NotFound);
+		i = 1; // reset to look for member types inside the default package type
+	} else {
+		type = (ReferenceBinding) binding;
+	}
+
+	while (i < length) {
+		type = (ReferenceBinding)this.environment.convertToRawType(type, false /*do not force conversion of enclosing types*/); // type imports are necessarily raw for all except last
+		if (!type.canBeSeenBy(this.fPackage))
+			return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), type, ProblemReasons.NotVisible);
+
+		char[] name = compoundName[i++];
+		// does not look for inherited member types on purpose, only immediate members
+		type = type.getMemberType(name);
+		if (type == null)
+			return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, ProblemReasons.NotFound);
+	}
+	if (!type.canBeSeenBy(this.fPackage))
+		return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotVisible);
+	return type;
+}
+private Binding findSingleImport(char[][] compoundName, int mask, boolean findStaticImports) {
+	if (compoundName.length == 1) {
+		// findType records the reference
+		// the name cannot be a package
+		if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+			return new ProblemReferenceBinding(compoundName, null, ProblemReasons.NotFound);
+		ReferenceBinding typeBinding = findType(compoundName[0], this.environment.defaultPackage, this.fPackage);
+		if (typeBinding == null)
+			return new ProblemReferenceBinding(compoundName, null, ProblemReasons.NotFound);
+		return typeBinding;
+	}
+
+	if (findStaticImports)
+		return findSingleStaticImport(compoundName, mask);
+	return findImport(compoundName, compoundName.length);
+}
+private Binding findSingleStaticImport(char[][] compoundName, int mask) {
+	Binding binding = findImport(compoundName, compoundName.length - 1);
+	if (!binding.isValidBinding()) return binding;
+
+	char[] name = compoundName[compoundName.length - 1];
+	if (binding instanceof PackageBinding) {
+		Binding temp = ((PackageBinding) binding).getTypeOrPackage(name);
+		if (temp != null && temp instanceof ReferenceBinding) // must resolve to a member type or field, not a top level type
+			return new ProblemReferenceBinding(compoundName, (ReferenceBinding) temp, ProblemReasons.InvalidTypeForStaticImport);
+		return binding; // cannot be a package, error is caught in sender
+	}
+
+	// look to see if its a static field first
+	ReferenceBinding type = (ReferenceBinding) binding;
+	FieldBinding field = (mask & Binding.FIELD) != 0 ? findField(type, name, null, true) : null;
+	if (field != null) {
+		if (field.problemId() == ProblemReasons.Ambiguous && ((ProblemFieldBinding) field).closestMatch.isStatic())
+			return field; // keep the ambiguous field instead of a possible method match
+		if (field.isValidBinding() && field.isStatic() && field.canBeSeenBy(type, null, this))
+			return field;
+	}
+
+	// look to see if there is a static method with the same selector
+	MethodBinding method = (mask & Binding.METHOD) != 0 ? findStaticMethod(type, name) : null;
+	if (method != null) return method;
+
+	type = findMemberType(name, type);
+	if (type == null || !type.isStatic()) {
+		if (field != null && !field.isValidBinding() && field.problemId() != ProblemReasons.NotFound)
+			return field;
+		return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotFound);
+	}
+	if (type.isValidBinding() && !type.canBeSeenBy(this.fPackage))
+		return new ProblemReferenceBinding(compoundName, type, ProblemReasons.NotVisible);
+	if (type.problemId() == ProblemReasons.NotVisible) // ensure compoundName is correct
+		return new ProblemReferenceBinding(compoundName, ((ProblemReferenceBinding) type).closestMatch, ProblemReasons.NotVisible);
+	return type;
+}
+// helper method for findSingleStaticImport()
+private MethodBinding findStaticMethod(ReferenceBinding currentType, char[] selector) {
+	if (!currentType.canBeSeenBy(this))
+		return null;
+
+	do {
+		currentType.initializeForStaticImports();
+		MethodBinding[] methods = currentType.getMethods(selector);
+		if (methods != Binding.NO_METHODS) {
+			for (int i = methods.length; --i >= 0;) {
+				MethodBinding method = methods[i];
+				if (method.isStatic() && method.canBeSeenBy(this.fPackage))
+					return method;
+			}
+		}
+	} while ((currentType = currentType.superclass()) != null);
+	return null;
+}
+ImportBinding[] getDefaultImports() {
+	// initialize the default imports if necessary... share the default java.lang.* import
+	if (this.environment.defaultImports != null) return this.environment.defaultImports;
+
+	Binding importBinding = this.environment.getTopLevelPackage(TypeConstants.JAVA);
+	if (importBinding != null)
+		importBinding = ((PackageBinding) importBinding).getTypeOrPackage(TypeConstants.JAVA_LANG[1]);
+
+	if (importBinding == null || !importBinding.isValidBinding()) {
+		// create a proxy for the missing BinaryType
+		problemReporter().isClassPathCorrect(
+				TypeConstants.JAVA_LANG_OBJECT,
+			this.referenceContext,
+			this.environment.missingClassFileLocation);
+		BinaryTypeBinding missingObject = this.environment.createMissingType(null, TypeConstants.JAVA_LANG_OBJECT);
+		importBinding = missingObject.fPackage;
+	}
+
+	return this.environment.defaultImports = new ImportBinding[] {new ImportBinding(TypeConstants.JAVA_LANG, true, importBinding, null)};
+}
+// NOT Public API
+public final Binding getImport(char[][] compoundName, boolean onDemand, boolean isStaticImport) {
+	if (onDemand)
+		return findImport(compoundName, compoundName.length);
+	return findSingleImport(compoundName, Binding.TYPE | Binding.FIELD | Binding.METHOD, isStaticImport);
+}
+
+public int nextCaptureID() {
+	return this.captureID++;
+}
+
+/* Answer the problem reporter to use for raising new problems.
+*
+* Note that as a side-effect, this updates the current reference context
+* (unit, type or method) in case the problem handler decides it is necessary
+* to abort.
+*/
+public ProblemReporter problemReporter() {
+	ProblemReporter problemReporter = this.referenceContext.problemReporter;
+	problemReporter.referenceContext = this.referenceContext;
+	return problemReporter;
+}
+
+/*
+What do we hold onto:
+
+1. when we resolve 'a.b.c', say we keep only 'a.b.c'
+ & when we fail to resolve 'c' in 'a.b', lets keep 'a.b.c'
+THEN when we come across a new/changed/removed item named 'a.b.c',
+ we would find all references to 'a.b.c'
+-> This approach fails because every type is resolved in every onDemand import to
+ detect collision cases... so the references could be 10 times bigger than necessary.
+
+2. when we resolve 'a.b.c', lets keep 'a.b' & 'c'
+ & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'c'
+THEN when we come across a new/changed/removed item named 'a.b.c',
+ we would find all references to 'a.b' & 'c'
+-> This approach does not have a space problem but fails to handle collision cases.
+ What happens if a type is added named 'a.b'? We would search for 'a' & 'b' but
+ would not find a match.
+
+3. when we resolve 'a.b.c', lets keep 'a', 'a.b' & 'a', 'b', 'c'
+ & when we fail to resolve 'c' in 'a.b', lets keep 'a', 'a.b' & 'a', 'b', 'c'
+THEN when we come across a new/changed/removed item named 'a.b.c',
+ we would find all references to 'a.b' & 'c'
+OR 'a.b' -> 'a' & 'b'
+OR 'a' -> '' & 'a'
+-> As long as each single char[] is interned, we should not have a space problem
+ and can handle collision cases.
+
+4. when we resolve 'a.b.c', lets keep 'a.b' & 'a', 'b', 'c'
+ & when we fail to resolve 'c' in 'a.b', lets keep 'a.b' & 'a', 'b', 'c'
+THEN when we come across a new/changed/removed item named 'a.b.c',
+ we would find all references to 'a.b' & 'c'
+OR 'a.b' -> 'a' & 'b' in the simple name collection
+OR 'a' -> 'a' in the simple name collection
+-> As long as each single char[] is interned, we should not have a space problem
+ and can handle collision cases.
+*/
+void recordQualifiedReference(char[][] qualifiedName) {
+	if (this.qualifiedReferences == null) return; // not recording dependencies
+
+	int length = qualifiedName.length;
+	if (length > 1) {
+		recordRootReference(qualifiedName[0]);
+		while (!this.qualifiedReferences.contains(qualifiedName)) {
+			this.qualifiedReferences.add(qualifiedName);
+			if (length == 2) {
+				recordSimpleReference(qualifiedName[0]);
+				recordSimpleReference(qualifiedName[1]);
+				return;
+			}
+			length--;
+			recordSimpleReference(qualifiedName[length]);
+			System.arraycopy(qualifiedName, 0, qualifiedName = new char[length][], 0, length);
+		}
+	} else if (length == 1) {
+		recordRootReference(qualifiedName[0]);
+		recordSimpleReference(qualifiedName[0]);
+	}
+}
+void recordReference(char[][] qualifiedEnclosingName, char[] simpleName) {
+	recordQualifiedReference(qualifiedEnclosingName);
+	if (qualifiedEnclosingName.length == 0)
+		recordRootReference(simpleName);
+	recordSimpleReference(simpleName);
+}
+void recordReference(ReferenceBinding type, char[] simpleName) {
+	ReferenceBinding actualType = typeToRecord(type);
+	if (actualType != null)
+		recordReference(actualType.compoundName, simpleName);
+}
+void recordRootReference(char[] simpleName) {
+	if (this.rootReferences == null) return; // not recording dependencies
+
+	if (!this.rootReferences.contains(simpleName))
+		this.rootReferences.add(simpleName);
+}
+void recordSimpleReference(char[] simpleName) {
+	if (this.simpleNameReferences == null) return; // not recording dependencies
+
+	if (!this.simpleNameReferences.contains(simpleName))
+		this.simpleNameReferences.add(simpleName);
+}
+void recordSuperTypeReference(TypeBinding type) {
+	if (this.referencedSuperTypes == null) return; // not recording dependencies
+
+	ReferenceBinding actualType = typeToRecord(type);
+	if (actualType != null && !this.referencedSuperTypes.containsIdentical(actualType))
+		this.referencedSuperTypes.add(actualType);
+}
+public void recordTypeConversion(TypeBinding superType, TypeBinding subType) {
+	recordSuperTypeReference(subType); // must record the hierarchy of the subType that is converted to the superType
+}
+void recordTypeReference(TypeBinding type) {
+	if (this.referencedTypes == null) return; // not recording dependencies
+
+	ReferenceBinding actualType = typeToRecord(type);
+	if (actualType != null && !this.referencedTypes.containsIdentical(actualType))
+		this.referencedTypes.add(actualType);
+}
+void recordTypeReferences(TypeBinding[] types) {
+	if (this.referencedTypes == null) return; // not recording dependencies
+	if (types == null || types.length == 0) return;
+
+	for (int i = 0, max = types.length; i < max; i++) {
+		// No need to record supertypes of method arguments & thrown exceptions, just the compoundName
+		// If a field/method is retrieved from such a type then a separate call does the job
+		ReferenceBinding actualType = typeToRecord(types[i]);
+		if (actualType != null && !this.referencedTypes.containsIdentical(actualType))
+			this.referencedTypes.add(actualType);
+	}
+}
+Binding resolveSingleImport(ImportBinding importBinding, int mask) {
+	if (importBinding.resolvedImport == null) {
+		importBinding.resolvedImport = findSingleImport(importBinding.compoundName, mask, importBinding.isStatic());
+		if (!importBinding.resolvedImport.isValidBinding() || importBinding.resolvedImport instanceof PackageBinding) {
+			if (importBinding.resolvedImport.problemId() == ProblemReasons.Ambiguous)
+				return importBinding.resolvedImport;
+			if (this.imports != null) {
+				ImportBinding[] newImports = new ImportBinding[this.imports.length - 1];
+				for (int i = 0, n = 0, max = this.imports.length; i < max; i++)
+					if (this.imports[i] != importBinding)
+						newImports[n++] = this.imports[i];
+				this.imports = newImports;
+			}
+			return null;
+		}
+	}
+	return importBinding.resolvedImport;
+}
+public void storeDependencyInfo() {
+	// add the type hierarchy of each referenced supertype
+	// cannot do early since the hierarchy may not be fully resolved
+	for (int i = 0; i < this.referencedSuperTypes.size; i++) { // grows as more types are added
+		ReferenceBinding type = (ReferenceBinding) this.referencedSuperTypes.elementAt(i);
+		if (!this.referencedTypes.containsIdentical(type))
+			this.referencedTypes.add(type);
+
+		if (!type.isLocalType()) {
+			ReferenceBinding enclosing = type.enclosingType();
+			if (enclosing != null)
+				recordSuperTypeReference(enclosing);
+		}
+		ReferenceBinding superclass = type.superclass();
+		if (superclass != null)
+			recordSuperTypeReference(superclass);
+		ReferenceBinding[] interfaces = type.superInterfaces();
+		if (interfaces != null)
+			for (int j = 0, length = interfaces.length; j < length; j++)
+				recordSuperTypeReference(interfaces[j]);
+	}
+
+	for (int i = 0, l = this.referencedTypes.size; i < l; i++) {
+		ReferenceBinding type = (ReferenceBinding) this.referencedTypes.elementAt(i);
+		if (!type.isLocalType())
+			recordQualifiedReference(type.isMemberType()
+				? CharOperation.splitOn('.', type.readableName())
+				: type.compoundName);
+	}
+
+	int size = this.qualifiedReferences.size;
+	char[][][] qualifiedRefs = new char[size][][];
+	for (int i = 0; i < size; i++)
+		qualifiedRefs[i] = this.qualifiedReferences.elementAt(i);
+	this.referenceContext.compilationResult.qualifiedReferences = qualifiedRefs;
+
+	size = this.simpleNameReferences.size;
+	char[][] simpleRefs = new char[size][];
+	for (int i = 0; i < size; i++)
+		simpleRefs[i] = this.simpleNameReferences.elementAt(i);
+	this.referenceContext.compilationResult.simpleNameReferences = simpleRefs;
+
+	size = this.rootReferences.size;
+	char[][] rootRefs = new char[size][];
+	for (int i = 0; i < size; i++)
+		rootRefs[i] = this.rootReferences.elementAt(i);
+	this.referenceContext.compilationResult.rootReferences = rootRefs;
+}
+public String toString() {
+	return "--- CompilationUnit Scope : " + new String(this.referenceContext.getFileName()); //$NON-NLS-1$
+}
+private ReferenceBinding typeToRecord(TypeBinding type) {
+	if (type.isArrayType())
+		type = ((ArrayBinding) type).leafComponentType;
+
+	switch (type.kind()) {
+		case Binding.BASE_TYPE :
+		case Binding.TYPE_PARAMETER :
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+		case Binding.INTERSECTION_CAST_TYPE: // constituents would have been recorded.
+		case Binding.POLY_TYPE: // not a real type, will mutate into one, hopefully soon.
+			return null;
+		case Binding.PARAMETERIZED_TYPE :
+		case Binding.RAW_TYPE :
+			type = type.erasure();
+	}
+	ReferenceBinding refType = (ReferenceBinding) type;
+	if (refType.isLocalType()) return null;
+	return refType;
+}
+public void verifyMethods(MethodVerifier verifier) {
+	for (int i = 0, length = this.topLevelTypes.length; i < length; i++)
+		this.topLevelTypes[i].verifyMethods(verifier);
+}
+private void recordImportBinding(ImportBinding bindingToAdd) {
+	if (this.tempImports.length == this.importPtr) {
+		System.arraycopy(this.tempImports, 0, (this.tempImports = new ImportBinding[this.importPtr + 1]), 0, this.importPtr);
+	}
+	this.tempImports[this.importPtr++] = bindingToAdd;
+}
+/**
+ * Checks additional bindings (methods or types) imported from a single static import. 
+ * Method is tried first, followed by type. If found, records them.
+ * If in the process, import is flagged as duplicate, -1 is returned.
+ * @param compoundName
+ * @param typesBySimpleNames
+ * @param mask
+ * @param importReference
+ */
+private void checkMoreStaticBindings(
+		char[][] compoundName, 
+		HashtableOfType typesBySimpleNames, 
+		int mask,
+		ImportReference importReference) {
+	Binding importBinding = findSingleStaticImport(compoundName, mask);
+	if (!importBinding.isValidBinding()) {
+		// only continue if the same kind's ambiguous binding is returned
+		// may have found an ambiguous type when looking for field or method. Don't continue in that case
+		if (importBinding.problemId() == ProblemReasons.Ambiguous) {
+			// keep it unless a duplicate can be found below
+			checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName);
+		}
+	} else {
+		checkAndRecordImportBinding(importBinding, typesBySimpleNames, importReference, compoundName);
+	}
+	if (((mask & Binding.METHOD) != 0) && (importBinding.kind() == Binding.METHOD)) {
+		// found method
+		// type is left to be looked for
+		// reset METHOD bit to enable lookup for only type
+		mask &= ~Binding.METHOD;
+		// now search for a type binding
+		checkMoreStaticBindings(compoundName, typesBySimpleNames, mask, importReference);
+	}
+}
+/**
+ * Checks for duplicates. If all ok, records the importBinding
+ * returns -1 when this import is flagged as duplicate.
+ * @param importBinding
+ * @param typesBySimpleNames
+ * @param importReference
+ * @param compoundName
+ * @return -1 when this import is flagged as duplicate, importPtr otherwise.
+ */
+private int checkAndRecordImportBinding(
+		Binding importBinding, 
+		HashtableOfType typesBySimpleNames, 
+		ImportReference importReference,
+		char[][] compoundName) {
+	ReferenceBinding conflictingType = null;
+	if (importBinding instanceof MethodBinding) {
+		conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length);
+		if (!conflictingType.isValidBinding() || (importReference.isStatic() && !conflictingType.isStatic()))
+			conflictingType = null;
+	}
+	// collisions between an imported static field & a type should be checked according to spec... but currently not by javac
+	if (importBinding instanceof ReferenceBinding || conflictingType != null) {
+		ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType;
+		ReferenceBinding typeToCheck = referenceBinding.problemId() == ProblemReasons.Ambiguous
+			? ((ProblemReferenceBinding) referenceBinding).closestMatch
+			: referenceBinding;
+		if (importReference.isTypeUseDeprecated(typeToCheck, this))
+			problemReporter().deprecatedType(typeToCheck, importReference);
+
+		ReferenceBinding existingType = typesBySimpleNames.get(compoundName[compoundName.length - 1]);
+		if (existingType != null) {
+			// duplicate test above should have caught this case, but make sure
+			if (existingType == referenceBinding) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865
+				// Check all resolved imports to see if this import qualifies as a duplicate
+				for (int j = 0; j < this.importPtr; j++) {
+					ImportBinding resolved = this.tempImports[j];
+					if (resolved instanceof ImportConflictBinding) {
+						ImportConflictBinding importConflictBinding = (ImportConflictBinding) resolved;
+						if (importConflictBinding.conflictingTypeBinding == referenceBinding) {
+							if (!importReference.isStatic()) {
+								// resolved is implicitly static
+								problemReporter().duplicateImport(importReference);
+								recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
+							}
+						}
+					} else if (resolved.resolvedImport == referenceBinding) {
+						if (importReference.isStatic() != resolved.isStatic()) {
+							problemReporter().duplicateImport(importReference);
+							recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
+						}
+					}
+				}
+				return -1;
+			}
+			// either the type collides with a top level type or another imported type
+			for (int j = 0, length = this.topLevelTypes.length; j < length; j++) {
+				if (CharOperation.equals(this.topLevelTypes[j].sourceName, existingType.sourceName)) {
+					problemReporter().conflictingImport(importReference);
+					return -1;
+				}
+			}
+			problemReporter().duplicateImport(importReference);
+			return -1;
+		}
+		typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding);
+	} else if (importBinding instanceof FieldBinding) {
+		for (int j = 0; j < this.importPtr; j++) {
+			ImportBinding resolved = this.tempImports[j];
+			// find other static fields with the same name
+			if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) {
+				if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) {
+					problemReporter().duplicateImport(importReference);
+					return -1;
+				}
+			}
+		}
+	}
+	if (conflictingType == null) {
+		recordImportBinding(new ImportBinding(compoundName, false, importBinding, importReference));
+	} else {
+		recordImportBinding(new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference));
+	}
+	return this.importPtr;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java
new file mode 100644
index 0000000..5a469d6
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public class ElementValuePair {
+	char[] name;
+	public Object value;
+	public MethodBinding binding;
+
+public static Object getValue(Expression expression) {
+	if (expression == null)
+		return null;
+	Constant constant = expression.constant;
+	// literals would hit this case.
+	if (constant != null && constant != Constant.NotAConstant)
+		return constant;
+
+	if (expression instanceof Annotation)
+		return ((Annotation) expression).getCompilerAnnotation();
+	if (expression instanceof ArrayInitializer) {
+		Expression[] exprs = ((ArrayInitializer) expression).expressions;
+		int length = exprs == null ? 0 : exprs.length;
+		Object[] values = new Object[length];
+		for (int i = 0; i < length; i++)
+			values[i] = getValue(exprs[i]);
+		return values;
+	}
+	if (expression instanceof ClassLiteralAccess)
+		return ((ClassLiteralAccess) expression).targetType;
+	if (expression instanceof Reference) {
+		FieldBinding fieldBinding = null;
+		if (expression instanceof FieldReference) {
+			fieldBinding = ((FieldReference) expression).fieldBinding();
+		} else if (expression instanceof NameReference) {
+			Binding binding = ((NameReference) expression).binding;
+			if (binding != null && binding.kind() == Binding.FIELD)
+				fieldBinding = (FieldBinding) binding;
+		}
+		if (fieldBinding != null && (fieldBinding.modifiers & ClassFileConstants.AccEnum) > 0)
+			return fieldBinding;
+	}
+	// something that isn't a compile time constant.
+	return null;
+}
+
+public ElementValuePair(char[] name, Expression expression, MethodBinding binding) {
+	this(name, ElementValuePair.getValue(expression), binding);
+}
+
+public ElementValuePair(char[] name, Object value, MethodBinding binding) {
+	this.name = name;
+	this.value = value;
+	this.binding = binding;
+}
+
+/**
+ * @return the name of the element value pair.
+ */
+public char[] getName() {
+	return this.name;
+}
+
+/**
+ * @return the method binding that defined this member value pair or null if no such binding exists.
+ */
+public MethodBinding getMethodBinding() {
+	return this.binding;
+}
+
+/**
+ * Return {@link TypeBinding} for member value of type {@link java.lang.Class}
+ * Return {@link org.eclipse.jdt.internal.compiler.impl.Constant} for member of primitive type or String
+ * Return {@link FieldBinding} for enum constant
+ * Return {@link AnnotationBinding} for annotation instance
+ * Return <code>Object[]</code> for member value of array type.
+ * @return the value of this member value pair or null if the value is missing or is not a compile-time constant
+ */
+public Object getValue() {
+	return this.value;
+}
+
+void setMethodBinding(MethodBinding binding) {
+	// lazily set after annotation type was resolved
+	this.binding = binding;
+}
+
+void setValue(Object value) {
+	// can be modified after the initialization if holding an unresolved ref
+	this.value = value;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer(5);
+	buffer.append(this.name).append(" = "); //$NON-NLS-1$
+	buffer.append(this.value);
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java
new file mode 100644
index 0000000..644f517
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+// TODO (philippe) these should be moved to tagbits
+public interface ExtraCompilerModifiers { // modifier constant
+	/**
+	 * Bits that are depending upon ClassFileConstants (relying that classfiles only use the 16 lower bits).
+	 * <p>
+	 * Does <b>not</b> include {@link ClassFileConstants#AccDeprecated} and
+	 * {@link ClassFileConstants#AccAnnotationDefault}!
+	 * </p>
+	 */
+	final int AccJustFlag = 0xFFFF;// 16 lower bits
+
+	final int AccDefaultMethod = ASTNode.Bit17;
+	// bit18 - use by ClassFileConstants.AccAnnotationDefault
+	final int AccRestrictedAccess = ASTNode.Bit19;
+	final int AccFromClassFile = ASTNode.Bit20;
+	final int AccDefaultAbstract = ASTNode.Bit20;
+	// bit21 - use by ClassFileConstants.AccDeprecated
+	final int AccDeprecatedImplicitly = ASTNode.Bit22; // record whether deprecated itself or contained by a deprecated type
+	final int AccAlternateModifierProblem = ASTNode.Bit23;
+	final int AccModifierProblem = ASTNode.Bit24;
+	final int AccSemicolonBody = ASTNode.Bit25;
+	final int AccUnresolved = ASTNode.Bit26;
+	final int AccBlankFinal = ASTNode.Bit27; // for blank final variables
+	final int AccIsDefaultConstructor = ASTNode.Bit27; // for default constructor
+	final int AccLocallyUsed = ASTNode.Bit28; // used to diagnose unused (a) private/local members or (b) members of private classes
+											  // generally set when actual usage has been detected 
+											  // or, (b) when member of a private class is exposed via a non-private subclass
+											  //     see https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281
+	final int AccVisibilityMASK = ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate;
+
+	final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one
+	final int AccImplementing = ASTNode.Bit30; // record fact a method implements another one (it is concrete and overrides an abstract one)
+	final int AccGenericSignature = ASTNode.Bit31; // record fact a type/method/field involves generics in its signature (and need special signature attr)
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
new file mode 100644
index 0000000..8a609b7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
@@ -0,0 +1,402 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 185682 - Increment/decrement operators mark local variables as read
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public class FieldBinding extends VariableBinding {
+	public ReferenceBinding declaringClass;
+	public int compoundUseFlag = 0; // number or accesses via postIncrement or compoundAssignment
+	
+protected FieldBinding() {
+	super(null, null, 0, null);
+	// for creating problem field
+}
+public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) {
+	super(name, type, modifiers, constant);
+	this.declaringClass = declaringClass;
+}
+// special API used to change field declaring class for runtime visibility check
+public FieldBinding(FieldBinding initialFieldBinding, ReferenceBinding declaringClass) {
+	super(initialFieldBinding.name, initialFieldBinding.type, initialFieldBinding.modifiers, initialFieldBinding.constant());
+	this.declaringClass = declaringClass;
+	this.id = initialFieldBinding.id;
+	setAnnotations(initialFieldBinding.getAnnotations());
+}
+/* API
+* Answer the receiver's binding type from Binding.BindingID.
+*/
+public FieldBinding(FieldDeclaration field, TypeBinding type, int modifiers, ReferenceBinding declaringClass) {
+	this(field.name, type, modifiers, declaringClass, null);
+	field.binding = this; // record binding in declaration
+}
+
+public final boolean canBeSeenBy(PackageBinding invocationPackage) {
+	if (isPublic()) return true;
+	if (isPrivate()) return false;
+
+	// isProtected() or isDefault()
+	return invocationPackage == this.declaringClass.getPackage();
+}
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+
+public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+	if (isPublic()) return true;
+
+	SourceTypeBinding invocationType = scope.enclosingSourceType();
+	if (invocationType == this.declaringClass && invocationType == receiverType) return true;
+
+	if (invocationType == null) // static import call
+		return !isPrivate() && scope.getCurrentPackage() == this.declaringClass.fPackage;
+
+	if (isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the receiverType is the invocationType or its subclass
+		//    OR the method is a static method accessed directly through a type
+		//    OR previous assertions are true for one of the enclosing type
+		if (invocationType == this.declaringClass) return true;
+		if (invocationType.fPackage == this.declaringClass.fPackage) return true;
+
+		ReferenceBinding currentType = invocationType;
+		int depth = 0;
+		ReferenceBinding receiverErasure = (ReferenceBinding)receiverType.erasure();
+		ReferenceBinding declaringErasure = (ReferenceBinding) this.declaringClass.erasure();
+		do {
+			if (currentType.findSuperTypeOriginatingFrom(declaringErasure) != null) {
+				if (invocationSite.isSuperAccess())
+					return true;
+				// receiverType can be an array binding in one case... see if you can change it
+				if (receiverType instanceof ArrayBinding)
+					return false;
+				if (isStatic()) {
+					if (depth > 0) invocationSite.setDepth(depth);
+					return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
+				}
+				if (currentType == receiverErasure || receiverErasure.findSuperTypeOriginatingFrom(currentType) != null) {
+					if (depth > 0) invocationSite.setDepth(depth);
+					return true;
+				}
+			}
+			depth++;
+			currentType = currentType.enclosingType();
+		} while (currentType != null);
+		return false;
+	}
+
+	if (isPrivate()) {
+		// answer true if the receiverType is the declaringClass
+		// AND the invocationType and the declaringClass have a common enclosingType
+		receiverCheck: {
+			if (receiverType != this.declaringClass) {
+				// special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622
+				if (scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_6 && receiverType.isTypeVariable() && ((TypeVariableBinding) receiverType).isErasureBoundTo(this.declaringClass.erasure()))
+					break receiverCheck;
+				return false;
+			}
+		}
+
+		if (invocationType != this.declaringClass) {
+			ReferenceBinding outerInvocationType = invocationType;
+			ReferenceBinding temp = outerInvocationType.enclosingType();
+			while (temp != null) {
+				outerInvocationType = temp;
+				temp = temp.enclosingType();
+			}
+
+			ReferenceBinding outerDeclaringClass = (ReferenceBinding) this.declaringClass.erasure();
+			temp = outerDeclaringClass.enclosingType();
+			while (temp != null) {
+				outerDeclaringClass = temp;
+				temp = temp.enclosingType();
+			}
+			if (outerInvocationType != outerDeclaringClass) return false;
+		}
+		return true;
+	}
+
+	// isDefault()
+	PackageBinding declaringPackage = this.declaringClass.fPackage;
+	if (invocationType.fPackage != declaringPackage) return false;
+
+	// receiverType can be an array binding in one case... see if you can change it
+	if (receiverType instanceof ArrayBinding)
+		return false;
+	TypeBinding originalDeclaringClass = this.declaringClass.original();
+	ReferenceBinding currentType = (ReferenceBinding) receiverType;
+	do {
+		if (currentType.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
+			if (originalDeclaringClass == currentType.erasure().original()) return true;
+		} else {
+			if (originalDeclaringClass == currentType.original()) return true;
+		}
+		PackageBinding currentPackage = currentType.fPackage;
+		// package could be null for wildcards/intersection types, ignore and recurse in superclass
+		if (currentPackage != null && currentPackage != declaringPackage) return false;
+	} while ((currentType = currentType.superclass()) != null);
+	return false;
+}
+
+/*
+ * declaringUniqueKey dot fieldName ) returnTypeUniqueKey
+ * p.X { X<T> x} --> Lp/X;.x)p/X<TT;>;
+ */
+public char[] computeUniqueKey(boolean isLeaf) {
+	// declaring key
+	char[] declaringKey =
+		this.declaringClass == null /*case of length field for an array*/
+			? CharOperation.NO_CHAR
+			: this.declaringClass.computeUniqueKey(false/*not a leaf*/);
+	int declaringLength = declaringKey.length;
+
+	// name
+	int nameLength = this.name.length;
+
+	// return type
+	char[] returnTypeKey = this.type == null ? new char[] {'V'} : this.type.computeUniqueKey(false/*not a leaf*/);
+	int returnTypeLength = returnTypeKey.length;
+
+	char[] uniqueKey = new char[declaringLength + 1 + nameLength + 1 + returnTypeLength];
+	int index = 0;
+	System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+	index += declaringLength;
+	uniqueKey[index++] = '.';
+	System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
+	index += nameLength;
+	uniqueKey[index++] = ')';
+	System.arraycopy(returnTypeKey, 0, uniqueKey, index, returnTypeLength);
+	return uniqueKey;
+}
+public Constant constant() {
+	Constant fieldConstant = this.constant;
+	if (fieldConstant == null) {
+		if (isFinal()) {
+			//The field has not been yet type checked.
+			//It also means that the field is not coming from a class that
+			//has already been compiled. It can only be from a class within
+			//compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
+			FieldBinding originalField = original();
+			if (originalField.declaringClass instanceof SourceTypeBinding) {
+				SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass;
+				if (sourceType.scope != null) {
+					TypeDeclaration typeDecl = sourceType.scope.referenceContext;
+					FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
+					MethodScope initScope = originalField.isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope;
+					boolean old = initScope.insideTypeAnnotation;
+					try {
+						initScope.insideTypeAnnotation = false;
+						fieldDecl.resolve(initScope); //side effect on binding
+					} finally {
+						initScope.insideTypeAnnotation = old;
+					}
+					fieldConstant = originalField.constant == null ? Constant.NotAConstant : originalField.constant;
+				} else {
+					fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
+				}
+			} else {
+				fieldConstant = Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
+			}
+		} else {
+			fieldConstant = Constant.NotAConstant;
+		}
+		this.constant = fieldConstant;
+	}
+	return fieldConstant;
+}
+
+public void fillInDefaultNonNullness(FieldDeclaration sourceField, Scope scope) {
+	if (   this.type != null
+		&& !this.type.isBaseType()
+		&& (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
+	{
+		this.tagBits |= TagBits.AnnotationNonNull;
+	} else if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
+		scope.problemReporter().nullAnnotationIsRedundant(sourceField);
+	}
+}
+
+/**
+ * X<T> t   -->  LX<TT;>;
+ */
+public char[] genericSignature() {
+    if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) return null;
+    return this.type.genericTypeSignature();
+}
+public final int getAccessFlags() {
+	return this.modifiers & ExtraCompilerModifiers.AccJustFlag;
+}
+
+public AnnotationBinding[] getAnnotations() {
+	FieldBinding originalField = original();
+	ReferenceBinding declaringClassBinding = originalField.declaringClass;
+	if (declaringClassBinding == null) {
+		return Binding.NO_ANNOTATIONS;
+	}
+	return declaringClassBinding.retrieveAnnotations(originalField);
+}
+
+/**
+ * Compute the tagbits for standard annotations. For source types, these could require
+ * lazily resolving corresponding annotation nodes, in case of forward references.
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
+ */
+public long getAnnotationTagBits() {
+	FieldBinding originalField = original();
+	if ((originalField.tagBits & TagBits.AnnotationResolved) == 0 && originalField.declaringClass instanceof SourceTypeBinding) {
+		ClassScope scope = ((SourceTypeBinding) originalField.declaringClass).scope;
+		if (scope == null) { // synthetic fields do not have a scope nor any annotations
+			this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+			return 0;
+		}
+		TypeDeclaration typeDecl = scope.referenceContext;
+		FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
+		if (fieldDecl != null) {
+			MethodScope initializationScope = isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope;
+			FieldBinding previousField = initializationScope.initializedField;
+			int previousFieldID = initializationScope.lastVisibleFieldID;
+			try {
+				initializationScope.initializedField = originalField;
+				initializationScope.lastVisibleFieldID = originalField.id;
+				ASTNode.resolveAnnotations(initializationScope, fieldDecl.annotations, originalField);
+			} finally {
+				initializationScope.initializedField = previousField;
+				initializationScope.lastVisibleFieldID = previousFieldID;
+			}
+		}
+	}
+	return originalField.tagBits;
+}
+
+public final boolean isDefault() {
+	return !isPublic() && !isProtected() && !isPrivate();
+}
+/* Answer true if the receiver is a deprecated field
+*/
+
+/* Answer true if the receiver has default visibility
+*/
+
+public final boolean isDeprecated() {
+	return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
+}
+/* Answer true if the receiver has private visibility
+*/
+
+public final boolean isPrivate() {
+	return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
+}
+/* Answer true if the receiver has private visibility or is enclosed by a class that does.
+*/
+
+public final boolean isOrEnclosedByPrivateType() {
+	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
+		return true;
+	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
+}
+/* Answer true if the receiver has private visibility and is used locally
+*/
+
+public final boolean isProtected() {
+	return (this.modifiers & ClassFileConstants.AccProtected) != 0;
+}
+/* Answer true if the receiver has public visibility
+*/
+
+public final boolean isPublic() {
+	return (this.modifiers & ClassFileConstants.AccPublic) != 0;
+}
+/* Answer true if the receiver is a static field
+*/
+
+public final boolean isStatic() {
+	return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+}
+/* Answer true if the receiver is not defined in the source of the declaringClass
+*/
+
+public final boolean isSynthetic() {
+	return (this.modifiers & ClassFileConstants.AccSynthetic) != 0;
+}
+/* Answer true if the receiver is a transient field
+*/
+
+public final boolean isTransient() {
+	return (this.modifiers & ClassFileConstants.AccTransient) != 0;
+}
+/* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
+*/
+
+public final boolean isUsed() {
+	return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0 || this.compoundUseFlag > 0;
+}
+/* Answer true if the only use of this field is in compound assignment or post increment
+ */
+
+public final boolean isUsedOnlyInCompound() {
+	return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) == 0 && this.compoundUseFlag > 0;
+}
+/* Answer true if the receiver has protected visibility
+*/
+
+public final boolean isViewedAsDeprecated() {
+	return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0;
+}
+/* Answer true if the receiver is a volatile field
+*/
+
+public final boolean isVolatile() {
+	return (this.modifiers & ClassFileConstants.AccVolatile) != 0;
+}
+
+public final int kind() {
+	return FIELD;
+}
+/* Answer true if the receiver is visible to the invocationPackage.
+*/
+/**
+ * Returns the original field (as opposed to parameterized instances)
+ */
+public FieldBinding original() {
+	return this;
+}
+public void setAnnotations(AnnotationBinding[] annotations) {
+	this.declaringClass.storeAnnotations(this, annotations);
+}
+public FieldDeclaration sourceField() {
+	SourceTypeBinding sourceType;
+	try {
+		sourceType = (SourceTypeBinding) this.declaringClass;
+	} catch (ClassCastException e) {
+		return null;
+	}
+
+	FieldDeclaration[] fields = sourceType.scope.referenceContext.fields;
+	if (fields != null) {
+		for (int i = fields.length; --i >= 0;)
+			if (this == fields[i].binding)
+				return fields[i];
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java
new file mode 100644
index 0000000..273fda2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IQualifiedTypeResolutionListener.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+
+/**
+ * A listener, which gets notified when a type binding has been discovered.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ */
+public interface IQualifiedTypeResolutionListener {
+
+	/**
+	 * Notifies that the given resolution has been found for the given type reference. Some of the bindings are
+	 * intermediate types i.e. qualifying types.
+	 *
+	 * @param typeReference
+	 *            the type reference
+	 * @param resolution
+	 *            the resolution found
+	 */
+	public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
new file mode 100644
index 0000000..ca73e47
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImplicitNullAnnotationVerifier.java
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 GK Software AG, IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Stephan Herrmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * Extracted slice from MethodVerifier15, which is responsible only for implicit null annotations.
+ * First, if enabled, it detects overridden methods from which null annotations are inherited.
+ * Next, also default nullness is filled into remaining empty slots.
+ * After all implicit annotations have been filled in compatibility is checked and problems are complained.
+ */
+public class ImplicitNullAnnotationVerifier {
+
+	/**
+	 * Simple record to store nullness info for one argument or return type
+	 * while iterating over a set of overridden methods.
+	 */
+	static class InheritedNonNullnessInfo {
+		Boolean inheritedNonNullness;
+		MethodBinding annotationOrigin;
+		boolean complained;
+	}
+
+	// delegate which to ask for recursive analysis of super methods
+	// can be 'this', but is never a MethodVerifier (to avoid infinite recursion).
+	ImplicitNullAnnotationVerifier buddyImplicitNullAnnotationsVerifier;
+	private boolean inheritNullAnnotations;
+
+	public ImplicitNullAnnotationVerifier(boolean inheritNullAnnotations) {
+		this.buddyImplicitNullAnnotationsVerifier = this;
+		this.inheritNullAnnotations = inheritNullAnnotations;
+	}
+
+	// for sub-classes:
+	ImplicitNullAnnotationVerifier(CompilerOptions options) {
+		this.buddyImplicitNullAnnotationsVerifier = new ImplicitNullAnnotationVerifier(options.inheritNullAnnotations);
+		this.inheritNullAnnotations = options.inheritNullAnnotations;
+	}
+
+	/**
+	 * Check and fill in implicit annotations from overridden methods and from default.
+	 * Precondition: caller has checked whether annotation-based null analysis is enabled.
+	 */
+	public void checkImplicitNullAnnotations(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, boolean complain, Scope scope) {
+		// check inherited nullness from superclass and superInterfaces
+		try {
+			ReferenceBinding currentType = currentMethod.declaringClass;
+			if (currentType.id == TypeIds.T_JavaLangObject) {
+				return;
+			}
+			boolean needToApplyNonNullDefault = currentMethod.hasNonNullDefault();
+			// compatibility & inheritance do not consider constructors / static methods:
+			boolean isInstanceMethod = !currentMethod.isConstructor() && !currentMethod.isStatic();
+			complain &= isInstanceMethod;
+			if (!needToApplyNonNullDefault 
+					&& !complain 
+					&& !(this.inheritNullAnnotations && isInstanceMethod)) {
+				return; // short cut, no work to be done
+			}
+
+			if (isInstanceMethod) {
+				List superMethodList = new ArrayList();
+				
+				int paramLen = currentMethod.parameters.length;
+				findAllOverriddenMethods(currentMethod.original(), currentMethod.selector, paramLen,
+								currentType, new HashSet(), superMethodList);
+				
+				// prepare interim storage for nullness info so we don't pollute currentMethod before we know its conflict-free: 
+				InheritedNonNullnessInfo[] inheritedNonNullnessInfos = new InheritedNonNullnessInfo[paramLen+1]; // index 0 is for the return type
+				for (int i=0; i<paramLen+1; i++) inheritedNonNullnessInfos[i] = new InheritedNonNullnessInfo();
+
+				int length = superMethodList.size();
+				for (int i = length; --i >= 0;) {
+					MethodBinding currentSuper = (MethodBinding) superMethodList.get(i);
+					if ((currentSuper.tagBits & TagBits.IsNullnessKnown) == 0) {
+						// recurse to prepare currentSuper
+						checkImplicitNullAnnotations(currentSuper, null, false, scope); // TODO (stephan) complain=true if currentSuper is source method??
+					}
+					checkNullSpecInheritance(currentMethod, srcMethod, needToApplyNonNullDefault, complain, currentSuper, scope, inheritedNonNullnessInfos);
+					needToApplyNonNullDefault = false;
+				}
+				
+				// transfer collected information into currentMethod:
+				InheritedNonNullnessInfo info = inheritedNonNullnessInfos[0];
+				if (!info.complained) {
+					if (info.inheritedNonNullness == Boolean.TRUE) {
+						currentMethod.tagBits |= TagBits.AnnotationNonNull;
+					} else if (info.inheritedNonNullness == Boolean.FALSE) {
+						currentMethod.tagBits |= TagBits.AnnotationNullable;
+					}
+				}
+				for (int i=0; i<paramLen; i++) {
+					info = inheritedNonNullnessInfos[i+1];
+					if (!info.complained && info.inheritedNonNullness != null) {
+						Argument currentArg = srcMethod == null ? null : srcMethod.arguments[i];
+						recordArgNonNullness(currentMethod, paramLen, i, currentArg, info.inheritedNonNullness);
+					}
+				}
+
+			}
+			if (needToApplyNonNullDefault) {
+				currentMethod.fillInDefaultNonNullness(srcMethod);
+			}
+		} finally {			
+			currentMethod.tagBits |= TagBits.IsNullnessKnown;
+		}
+	}
+
+	/* 
+	 * Recursively traverse the tree of ancestors but whenever we find a matching method prune the super tree.
+	 * Collect all matching methods in 'result'.
+	 */
+	private void findAllOverriddenMethods(MethodBinding original, char[] selector, int suggestedParameterLength, 
+			ReferenceBinding currentType, Set ifcsSeen, List result) 
+	{
+		if (currentType.id == TypeIds.T_JavaLangObject)
+			return;
+
+		// superclass:
+		collectOverriddenMethods(original, selector, suggestedParameterLength, currentType.superclass(), ifcsSeen, result);
+
+		// superInterfaces:
+		ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+		int ifcLen = superInterfaces.length;
+		for (int i = 0; i < ifcLen; i++) {
+			ReferenceBinding currentIfc = superInterfaces[i];
+			if (ifcsSeen.add(currentIfc.original())) {	// process each interface at most once
+				collectOverriddenMethods(original, selector, suggestedParameterLength, currentIfc, ifcsSeen, result);
+			}
+		}
+	}
+
+	/* collect matching methods from one supertype. */
+	private void collectOverriddenMethods(MethodBinding original, char[] selector, int suggestedParameterLength,
+			ReferenceBinding superType, Set ifcsSeen, List result) 
+	{
+		MethodBinding [] ifcMethods = superType.getMethods(selector, suggestedParameterLength);
+		int length = ifcMethods.length;
+		for  (int i=0; i<length; i++) {
+			MethodBinding currentMethod = ifcMethods[i];
+			if (currentMethod.isStatic())
+				continue;
+			if (areParametersEqual(original, currentMethod)) {
+				result.add(currentMethod);
+				return; // at most one method is overridden from any supertype
+			}
+		}
+		findAllOverriddenMethods(original, selector, suggestedParameterLength, superType, ifcsSeen, result);
+	}
+
+	/**
+	 * The main algorithm in this class.
+	 * @param currentMethod focus method
+	 * @param srcMethod AST of 'currentMethod' if present
+	 * @param hasNonNullDefault is a @NonNull default applicable at the site of currentMethod?
+	 * @param shouldComplain should we report any errors found? 
+	 *   (see also comment about flows into this method, below).
+	 * @param inheritedMethod one overridden method from a super type
+	 * @param scope provides context for error reporting etc.
+	 * @param inheritedNonNullnessInfos if non-null, this array of non-null elements is used for
+	 * 	 interim recording of nullness information from inheritedMethod rather than prematurely updating currentMethod.
+	 *   Index position 0 is used for the return type, positions i+1 for argument i.
+	 */
+	void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
+			boolean hasNonNullDefault, boolean shouldComplain,
+			MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos) 
+	{
+		// Note that basically two different flows lead into this method:
+		// (1) during MethodVerifyer15.checkMethods() we want to report errors (against srcMethod or against the current type)
+		//     In this case this method is directly called from MethodVerifier15 (checkAgainstInheritedMethod / checkConcreteInheritedMethod)
+		// (2) during on-demand invocation we are mainly interested in the side effects of copying inherited null annotations
+		//     In this case this method is called via checkImplicitNullAnnotations from
+		//     - MessageSend.resolveType(..)
+		//     - SourceTypeBinding.createArgumentBindings(..)
+		//     - recursive calls within this class
+		//     Still we *might* want to complain about problems found (controlled by 'complain')
+
+		if ((inheritedMethod.tagBits & TagBits.IsNullnessKnown) == 0) {
+			// TODO (stephan): even here we may need to report problems? How to discriminate?
+			this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(inheritedMethod, null, false, scope);
+		}
+		long inheritedBits = inheritedMethod.tagBits;
+		long inheritedNullnessBits = inheritedBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable);
+		long currentBits = currentMethod.tagBits;
+		long currentNullnessBits = currentBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable);
+		
+		LookupEnvironment environment = scope.environment();
+		boolean shouldInherit = this.inheritNullAnnotations;
+
+		// return type:
+		returnType: {
+			if (currentMethod.returnType == null || currentMethod.returnType.isBaseType())
+				break returnType; // no nullness for primitive types
+			if (currentNullnessBits == 0) {
+				// unspecified, may fill in either from super or from default
+				if (shouldInherit) {
+					if (inheritedNullnessBits != 0) {
+						if (hasNonNullDefault) {
+							// both inheritance and default: check for conflict?
+							if (shouldComplain && inheritedNullnessBits == TagBits.AnnotationNullable)
+								scope.problemReporter().conflictingNullAnnotations(currentMethod, ((MethodDeclaration) srcMethod).returnType, inheritedMethod);
+							// 	still use the inherited bits to avoid incompatibility
+						}
+						if (inheritedNonNullnessInfos != null && srcMethod != null) {
+							recordDeferredInheritedNullness(scope, ((MethodDeclaration) srcMethod).returnType, 
+									inheritedMethod, Boolean.valueOf(inheritedNullnessBits == TagBits.AnnotationNonNull), inheritedNonNullnessInfos[0]);
+						} else {
+							// no need to defer, record this info now:
+							currentMethod.tagBits |= inheritedNullnessBits;
+						}	
+						break returnType; // compatible by construction, skip complain phase below
+					}
+				}
+				if (hasNonNullDefault) { // conflict with inheritance already checked
+					currentMethod.tagBits |= (currentNullnessBits = TagBits.AnnotationNonNull); 
+				}
+			}
+			if (shouldComplain) {
+				if ((inheritedNullnessBits & TagBits.AnnotationNonNull) != 0
+						&& currentNullnessBits != TagBits.AnnotationNonNull)
+				{
+					if (srcMethod != null) {
+						scope.problemReporter().illegalReturnRedefinition(srcMethod, inheritedMethod,
+																	environment.getNonNullAnnotationName());
+					} else {
+						scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod);
+						return;
+					}
+				}
+			}
+		}
+
+		// parameters:
+		Argument[] currentArguments = srcMethod == null ? null : srcMethod.arguments;
+
+		int length = 0;
+		if (currentArguments != null)
+			length = currentArguments.length;
+		else if (inheritedMethod.parameterNonNullness != null)
+			length = inheritedMethod.parameterNonNullness.length;
+		else if (currentMethod.parameterNonNullness != null)
+			length = currentMethod.parameterNonNullness.length;
+
+		for (int i = 0; i < length; i++) {
+			if (currentMethod.parameters[i].isBaseType()) continue;
+
+			Argument currentArgument = currentArguments == null 
+										? null : currentArguments[i];
+			Boolean inheritedNonNullNess = (inheritedMethod.parameterNonNullness == null)
+										? null : inheritedMethod.parameterNonNullness[i];
+			Boolean currentNonNullNess = (currentMethod.parameterNonNullness == null)
+										? null : currentMethod.parameterNonNullness[i];
+
+			if (currentNonNullNess == null) {
+				// unspecified, may fill in either from super or from default
+				if (inheritedNonNullNess != null) {
+					if (shouldInherit) {
+						if (hasNonNullDefault) {
+							// both inheritance and default: check for conflict?
+							if (shouldComplain
+									&& inheritedNonNullNess == Boolean.FALSE
+									&& currentArgument != null)
+							{
+								scope.problemReporter().conflictingNullAnnotations(currentMethod, currentArgument, inheritedMethod);
+							}
+							// 	still use the inherited info to avoid incompatibility
+						}
+						if (inheritedNonNullnessInfos != null && srcMethod != null) {
+							recordDeferredInheritedNullness(scope, srcMethod.arguments[i].type,
+									inheritedMethod, inheritedNonNullNess, inheritedNonNullnessInfos[i+1]);
+						} else {
+							// no need to defer, record this info now:
+							recordArgNonNullness(currentMethod, length, i, currentArgument, inheritedNonNullNess);
+						}
+						continue; // compatible by construction, skip complain phase below
+					}
+				}
+				if (hasNonNullDefault) { // conflict with inheritance already checked
+					currentNonNullNess = Boolean.TRUE;
+					recordArgNonNullness(currentMethod, length, i, currentArgument, Boolean.TRUE);
+				}
+			}
+			if (shouldComplain) {
+				char[][] annotationName;
+				if (inheritedNonNullNess == Boolean.TRUE) {
+					annotationName = environment.getNonNullAnnotationName();
+				} else {
+					annotationName = environment.getNullableAnnotationName();
+				}
+				if (inheritedNonNullNess != Boolean.TRUE		// super parameter is not restricted to @NonNull
+						&& currentNonNullNess == Boolean.TRUE)	// current parameter is restricted to @NonNull 
+				{
+					// incompatible
+					if (currentArgument != null) {
+						scope.problemReporter().illegalRedefinitionToNonNullParameter(
+								currentArgument,
+								inheritedMethod.declaringClass,
+								(inheritedNonNullNess == null) ? null : environment.getNullableAnnotationName());
+					} else {
+						scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod);
+					}
+				} else if (currentNonNullNess == null) 
+				{
+					// unannotated strictly conflicts only with inherited @Nullable
+					if (inheritedNonNullNess == Boolean.FALSE) { 
+						if (currentArgument != null) {
+							scope.problemReporter().parameterLackingNullableAnnotation(
+									currentArgument,
+									inheritedMethod.declaringClass,
+									annotationName);
+						} else {
+							scope.problemReporter().cannotImplementIncompatibleNullness(currentMethod, inheritedMethod);
+						}
+					} else if (inheritedNonNullNess == Boolean.TRUE) {
+						// not strictly a conflict, but a configurable warning is given anyway:
+						scope.problemReporter().parameterLackingNonnullAnnotation(
+								currentArgument,
+								inheritedMethod.declaringClass,
+								annotationName);
+					}
+				}
+			}
+		}
+	}
+
+	/* check for conflicting annotations and record here the info 'inheritedNonNullness' found in 'inheritedMethod'. */
+	protected void recordDeferredInheritedNullness(Scope scope, ASTNode location,
+			MethodBinding inheritedMethod, Boolean inheritedNonNullness, 
+			InheritedNonNullnessInfo nullnessInfo) 
+	{
+		if (nullnessInfo.inheritedNonNullness != null && nullnessInfo.inheritedNonNullness != inheritedNonNullness) {
+			scope.problemReporter().conflictingInheritedNullAnnotations(location, 
+					nullnessInfo.inheritedNonNullness.booleanValue(), nullnessInfo.annotationOrigin, 
+					inheritedNonNullness.booleanValue(), inheritedMethod);
+			nullnessInfo.complained = true;
+			// leave previous info intact, so subsequent errors are reported against the same first method
+		} else {
+			nullnessInfo.inheritedNonNullness = inheritedNonNullness;
+			nullnessInfo.annotationOrigin = inheritedMethod;
+		}
+	}
+
+	/* record declared nullness of a parameter into the method and into the argument (if present). */
+	void recordArgNonNullness(MethodBinding method, int paramCount, int paramIdx, Argument currentArgument, Boolean nonNullNess) {
+		if (method.parameterNonNullness == null)
+			method.parameterNonNullness = new Boolean[paramCount];
+		method.parameterNonNullness[paramIdx] = nonNullNess;
+		if (currentArgument != null) {
+			currentArgument.binding.tagBits |= nonNullNess.booleanValue() ?
+					TagBits.AnnotationNonNull : TagBits.AnnotationNullable;
+		}
+	}
+
+	// ==== minimal set of utility methods previously from MethodVerifier15: ====
+	
+	static boolean areParametersEqual(MethodBinding one, MethodBinding two) {
+		TypeBinding[] oneArgs = one.parameters;
+		TypeBinding[] twoArgs = two.parameters;
+		if (oneArgs == twoArgs) return true;
+
+		int length = oneArgs.length;
+		if (length != twoArgs.length) return false;
+
+		
+		// methods with raw parameters are considered equal to inherited methods
+		// with parameterized parameters for backwards compatibility, need a more complex check
+		int i;
+		foundRAW: for (i = 0; i < length; i++) {
+			if (!areTypesEqual(oneArgs[i], twoArgs[i])) {
+				if (oneArgs[i].leafComponentType().isRawType()) {
+					if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType())) {
+						// raw mode does not apply if the method defines its own type variables
+						if (one.typeVariables != Binding.NO_TYPE_VARIABLES)
+							return false;
+						// one parameter type is raw, hence all parameters types must be raw or non generic
+						// otherwise we have a mismatch check backwards
+						for (int j = 0; j < i; j++)
+							if (oneArgs[j].leafComponentType().isParameterizedTypeWithActualArguments())
+								return false;
+						// switch to all raw mode
+						break foundRAW;
+					}
+				}
+				return false;
+			}
+		}
+		// all raw mode for remaining parameters (if any)
+		for (i++; i < length; i++) {
+			if (!areTypesEqual(oneArgs[i], twoArgs[i])) {
+				if (oneArgs[i].leafComponentType().isRawType())
+					if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType()))
+						continue;
+				return false;
+			} else if (oneArgs[i].leafComponentType().isParameterizedTypeWithActualArguments()) {
+				return false; // no remaining parameter can be a Parameterized type (if one has been converted then all RAW types must be converted)
+			}
+		}
+		return true;
+	}
+	static boolean areTypesEqual(TypeBinding one, TypeBinding two) {
+		if (one == two) return true;
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=329584
+		switch(one.kind()) {
+			case Binding.TYPE:
+				switch (two.kind()) {
+					case Binding.PARAMETERIZED_TYPE:
+					case Binding.RAW_TYPE:
+						if (one == two.erasure())
+							return true;
+				}
+				break;
+			case Binding.RAW_TYPE:
+			case Binding.PARAMETERIZED_TYPE:
+				switch(two.kind()) {
+					case Binding.TYPE:
+						if (one.erasure() == two)
+							return true;
+				}
+		}
+
+		// need to consider X<?> and X<? extends Object> as the same 'type'
+		if (one.isParameterizedType() && two.isParameterizedType())
+			return one.isEquivalentTo(two) && two.isEquivalentTo(one);
+
+		// Can skip this since we resolved each method before comparing it, see computeSubstituteMethod()
+		//	if (one instanceof UnresolvedReferenceBinding)
+		//		return ((UnresolvedReferenceBinding) one).resolvedType == two;
+		//	if (two instanceof UnresolvedReferenceBinding)
+		//		return ((UnresolvedReferenceBinding) two).resolvedType == one;
+		return false; // all other type bindings are identical
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java
new file mode 100644
index 0000000..1d1073a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class ImportBinding extends Binding {
+	public char[][] compoundName;
+	public boolean onDemand;
+	public ImportReference reference;
+
+	public Binding resolvedImport; // must ensure the import is resolved
+
+public ImportBinding(char[][] compoundName, boolean isOnDemand, Binding binding, ImportReference reference) {
+	this.compoundName = compoundName;
+	this.onDemand = isOnDemand;
+	this.resolvedImport = binding;
+	this.reference = reference;
+}
+/* API
+* Answer the receiver's binding type from Binding.BindingID.
+*/
+
+public final int kind() {
+	return IMPORT;
+}
+public boolean isStatic() {
+	return this.reference != null && this.reference.isStatic();
+}
+public char[] readableName() {
+	if (this.onDemand)
+		return CharOperation.concat(CharOperation.concatWith(this.compoundName, '.'), ".*".toCharArray()); //$NON-NLS-1$
+	else
+		return CharOperation.concatWith(this.compoundName, '.');
+}
+public String toString() {
+	return "import : " + new String(readableName()); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java
new file mode 100644
index 0000000..21213a9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class ImportConflictBinding extends ImportBinding {
+public ReferenceBinding conflictingTypeBinding; // must ensure the import is resolved
+
+public ImportConflictBinding(char[][] compoundName, Binding methodBinding, ReferenceBinding conflictingTypeBinding, ImportReference reference) {
+	super(compoundName, false, methodBinding, reference);
+	this.conflictingTypeBinding = conflictingTypeBinding;
+}
+public char[] readableName() {
+	return CharOperation.concatWith(this.compoundName, '.');
+}
+public String toString() {
+	return "method import : " + new String(readableName()); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java
new file mode 100644
index 0000000..f0e03bf
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+/**
+ * Context used during type inference for a generic method invocation
+ */
+public class InferenceContext {
+
+	private TypeBinding[][][] collectedSubstitutes;
+	MethodBinding genericMethod;
+	int depth;
+	int status;
+	TypeBinding expectedType;
+	boolean hasExplicitExpectedType; // indicates whether the expectedType (if set) was explicit in code, or set by default
+    public boolean isUnchecked;
+	TypeBinding[] substitutes;
+	final static int FAILED = 1;
+
+public InferenceContext(MethodBinding genericMethod) {
+	this.genericMethod = genericMethod;
+	TypeVariableBinding[] typeVariables = genericMethod.typeVariables;
+	int varLength = typeVariables.length;
+	this.collectedSubstitutes = new TypeBinding[varLength][3][];
+	this.substitutes = new TypeBinding[varLength];
+}
+
+public TypeBinding[] getSubstitutes(TypeVariableBinding typeVariable, int constraint) {
+	return this.collectedSubstitutes[typeVariable.rank][constraint];
+}
+
+/**
+ * Returns true if any unresolved variable is detected, i.e. any variable is substituted with itself
+ */
+public boolean hasUnresolvedTypeArgument() {
+	for (int i = 0, varLength = this.substitutes.length; i <varLength; i++) {
+		if (this.substitutes[i] == null) {
+			return true;
+		}
+	}
+	return false;
+}
+
+public void recordSubstitute(TypeVariableBinding typeVariable, TypeBinding actualType, int constraint) {
+    TypeBinding[][] variableSubstitutes = this.collectedSubstitutes[typeVariable.rank];
+    insertLoop: {
+    	TypeBinding[] constraintSubstitutes = variableSubstitutes[constraint];
+    	int length;
+    	if (constraintSubstitutes == null) {
+    		length = 0;
+    		constraintSubstitutes = new TypeBinding[1];
+    	} else {
+    		length = constraintSubstitutes.length;
+	        for (int i = 0; i < length; i++) {
+	        	TypeBinding substitute = constraintSubstitutes[i];
+	            if (substitute == actualType) return; // already there
+	            if (substitute == null) {
+	                constraintSubstitutes[i] = actualType;
+	                break insertLoop;
+	            }
+	        }
+	        // no free spot found, need to grow by one
+	        System.arraycopy(constraintSubstitutes, 0, constraintSubstitutes = new TypeBinding[length+1], 0, length);
+    	}
+        constraintSubstitutes[length] = actualType;
+        variableSubstitutes[constraint] = constraintSubstitutes;
+    }
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer(20);
+	buffer.append("InferenceContex for ");//$NON-NLS-1$
+	for (int i = 0, length = this.genericMethod.typeVariables.length; i < length; i++) {
+		buffer.append(this.genericMethod.typeVariables[i]);
+	}
+	buffer.append(this.genericMethod);
+	buffer.append("\n\t[status=");//$NON-NLS-1$
+	switch(this.status) {
+		case 0 :
+			buffer.append("ok]");//$NON-NLS-1$
+			break;
+		case FAILED :
+			buffer.append("failed]");//$NON-NLS-1$
+			break;
+	}
+	if (this.expectedType == null) {
+		buffer.append(" [expectedType=null]"); //$NON-NLS-1$
+	} else {
+		buffer.append(" [expectedType=").append(this.expectedType.shortReadableName()).append(']'); //$NON-NLS-1$
+	}
+	buffer.append(" [depth=").append(this.depth).append(']'); //$NON-NLS-1$
+	buffer.append("\n\t[collected={");//$NON-NLS-1$
+	for (int i = 0, length = this.collectedSubstitutes == null ? 0 : this.collectedSubstitutes.length; i < length; i++) {
+		TypeBinding[][] collected = this.collectedSubstitutes[i];
+		for (int j = TypeConstants.CONSTRAINT_EQUAL; j <= TypeConstants.CONSTRAINT_SUPER; j++) {
+			TypeBinding[] constraintCollected = collected[j];
+			if (constraintCollected != null) {
+				for (int k = 0, clength = constraintCollected.length; k < clength; k++) {
+					buffer.append("\n\t\t").append(this.genericMethod.typeVariables[i].sourceName); //$NON-NLS-1$
+					switch (j) {
+						case TypeConstants.CONSTRAINT_EQUAL :
+							buffer.append("="); //$NON-NLS-1$
+							break;
+						case TypeConstants.CONSTRAINT_EXTENDS :
+							buffer.append("<:"); //$NON-NLS-1$
+							break;
+						case TypeConstants.CONSTRAINT_SUPER :
+							buffer.append(">:"); //$NON-NLS-1$
+							break;
+					}
+					if (constraintCollected[k] != null) {
+						buffer.append(constraintCollected[k].shortReadableName());
+					}
+				}
+			}
+		}
+	}
+	buffer.append("}]");//$NON-NLS-1$
+	buffer.append("\n\t[inferred=");//$NON-NLS-1$
+	int count = 0;
+	for (int i = 0, length = this.substitutes == null ? 0 : this.substitutes.length; i < length; i++) {
+		if (this.substitutes[i] == null) continue;
+		count++;
+		buffer.append('{').append(this.genericMethod.typeVariables[i].sourceName);
+		buffer.append("=").append(this.substitutes[i].shortReadableName()).append('}'); //$NON-NLS-1$
+	}
+	if (count == 0) buffer.append("{}"); //$NON-NLS-1$
+	buffer.append(']');
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java
new file mode 100644
index 0000000..9fa688a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class InnerEmulationDependency{
+
+	public BlockScope scope;
+	public boolean wasEnclosingInstanceSupplied;
+
+	public InnerEmulationDependency(BlockScope scope, boolean wasEnclosingInstanceSupplied) {
+		this.scope = scope;
+		this.wasEnclosingInstanceSupplied = wasEnclosingInstanceSupplied;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java
new file mode 100644
index 0000000..22d8c79
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/IntersectionCastTypeBinding.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class IntersectionCastTypeBinding extends ReferenceBinding {
+
+	public ReferenceBinding [] intersectingTypes;
+	private ReferenceBinding javaLangObject;
+	int length;
+	
+	public IntersectionCastTypeBinding(ReferenceBinding[] intersectingTypes, LookupEnvironment environment) {
+		this.intersectingTypes = intersectingTypes;
+		this.length = intersectingTypes.length;
+		if (!intersectingTypes[0].isClass()) {
+			this.javaLangObject = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+			this.modifiers |= ClassFileConstants.AccInterface;
+		}
+	}
+	
+	public MethodBinding getSingleAbstractMethod(Scope scope) {
+		if (this.singleAbstractMethod != null)
+			return this.singleAbstractMethod;
+		MethodBinding sam = samProblemBinding;  // guilty unless proven innocent !
+		for (int i = 0; i < this.length; i++) {
+			MethodBinding method = this.intersectingTypes[i].getSingleAbstractMethod(scope);
+			if (method != null) {
+				if (method.isValidBinding()) {
+					if (sam.isValidBinding())
+						return this.singleAbstractMethod = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.IntersectionHasMultipleFunctionalInterfaces);
+					else
+						sam = method;
+				}
+			}
+		}
+		return this.singleAbstractMethod = sam; // I don't see a value in building the notional interface described in 9.8 - it appears just pedantic/normative - perhaps it plays a role in wildcard parameterized types ?
+	}
+
+	public boolean hasTypeBit(int bit) { // Stephan ??
+		for (int i = 0; i < this.length; i++) {		
+			if (this.intersectingTypes[i].hasTypeBit(bit))
+				return true;
+		}
+		return false;
+	}
+
+	public char[] constantPoolName() {
+		return this.intersectingTypes[0].constantPoolName();
+	}
+
+	public PackageBinding getPackage() {
+		throw new UnsupportedOperationException(); // cannot be referred to
+	}
+	
+	public ReferenceBinding[] getIntersectingTypes() {
+		return this.intersectingTypes;
+	}
+
+	public ReferenceBinding superclass() {
+		return this.intersectingTypes[0].isClass() ? this.intersectingTypes[0] : this.javaLangObject; 
+	}
+	
+	public ReferenceBinding [] superInterfaces() {
+		if (this.intersectingTypes[0].isClass()) {
+			ReferenceBinding [] superInterfaces = new ReferenceBinding[this.length - 1];
+			System.arraycopy(this.intersectingTypes, 1, superInterfaces, 0, this.length - 1);
+			return superInterfaces;
+		}
+		return this.intersectingTypes;
+	}
+	/* Answer true if the receiver type can be assigned to the argument type (right)
+	 */
+	public boolean isCompatibleWith(TypeBinding right, Scope scope) {
+		for (int i = 0; i < this.length; i++) {		
+			if (this.intersectingTypes[i].isCompatibleWith(right, scope))
+				return true;
+		}
+		return false;
+	}
+
+	public char[] qualifiedSourceName() {
+		StringBuffer qualifiedSourceName = new StringBuffer(16);
+		for (int i = 0; i < this.length; i++) {		
+				qualifiedSourceName.append(this.intersectingTypes[i].qualifiedSourceName());
+				if (i != this.length - 1)
+					qualifiedSourceName.append(" & "); //$NON-NLS-1$
+		}
+		return qualifiedSourceName.toString().toCharArray();
+	}
+
+	public char[] sourceName() {
+		StringBuffer srcName = new StringBuffer(16);
+		for (int i = 0; i < this.length; i++) {		
+				srcName.append(this.intersectingTypes[i].sourceName());
+				if (i != this.length - 1)
+					srcName.append(" & "); //$NON-NLS-1$
+		}
+		return srcName.toString().toCharArray();
+	}
+
+	public char[] readableName() {
+		StringBuffer readableName = new StringBuffer(16);
+		for (int i = 0; i < this.length; i++) {		
+				readableName.append(this.intersectingTypes[i].readableName());
+				if (i != this.length - 1)
+					readableName.append(" & "); //$NON-NLS-1$
+		}
+		return readableName.toString().toCharArray();
+	}
+	public char[] shortReadableName() {
+		StringBuffer shortReadableName = new StringBuffer(16);
+		for (int i = 0; i < this.length; i++) {		
+				shortReadableName.append(this.intersectingTypes[i].shortReadableName());
+				if (i != this.length - 1)
+					shortReadableName.append(" & "); //$NON-NLS-1$
+		}
+		return shortReadableName.toString().toCharArray();
+	}
+	public boolean isIntersectionCastType() {
+		return true;
+	}
+	public int kind() {
+		return Binding.INTERSECTION_CAST_TYPE;
+	}
+	public String debugName() {
+		StringBuffer debugName = new StringBuffer(16);
+		for (int i = 0; i < this.length; i++) {		
+				debugName.append(this.intersectingTypes[i].debugName());
+				if (i != this.length - 1)
+					debugName.append(" & "); //$NON-NLS-1$
+		}
+		return debugName.toString();
+	}
+	public String toString() {
+	    return debugName();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
new file mode 100644
index 0000000..65897fc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 384380 - False positive on a « Potential null pointer access » after a continue
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+public interface InvocationSite {
+
+	TypeBinding[] genericTypeArguments();
+	boolean isSuperAccess();
+	boolean isTypeAccess();
+	// in case the receiver type does not match the actual receiver type
+	// e.g. pkg.Type.C (receiver type of C is type of source context,
+	//		but actual receiver type is pkg.Type)
+	// e.g2. in presence of implicit access to enclosing type
+	void setActualReceiverType(ReferenceBinding receiverType);
+	void setDepth(int depth);
+	void setFieldIndex(int depth);
+	int sourceEnd();
+	int sourceStart();
+	TypeBinding expectedType();
+	boolean receiverIsImplicitThis();
+	
+	static class EmptyWithAstNode implements InvocationSite {
+		ASTNode node;
+		public EmptyWithAstNode(ASTNode node) {
+			this.node = node;
+		}
+		public TypeBinding[] genericTypeArguments() { return null;}
+		public boolean isSuperAccess() {return false;}
+		public boolean isTypeAccess() {return false;}
+		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
+		public void setDepth(int depth) {/* empty */ }
+		public void setFieldIndex(int depth) {/* empty */ }
+		public int sourceEnd() {return this.node.sourceEnd; }
+		public int sourceStart() {return this.node.sourceStart; }
+		public TypeBinding expectedType() { return null; }
+		public boolean receiverIsImplicitThis() { return false; }
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
new file mode 100644
index 0000000..df18c6b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *								bug 401030 - [1.8][null] Null analysis support for lambda methods. 
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+
+public final class LocalTypeBinding extends NestedTypeBinding {
+	final static char[] LocalTypePrefix = { '$', 'L', 'o', 'c', 'a', 'l', '$' };
+
+	private InnerEmulationDependency[] dependents;
+	public ArrayBinding[] localArrayBindings; // used to cache array bindings of various dimensions for this local type
+	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
+	public int sourceStart; // used by computeUniqueKey to uniquely identify this binding
+	public MethodBinding enclosingMethod;
+
+public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase) {
+	super(
+		new char[][] {CharOperation.concat(LocalTypeBinding.LocalTypePrefix, scope.referenceContext.name)},
+		scope,
+		enclosingType);
+	TypeDeclaration typeDeclaration = scope.referenceContext;
+	if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+		this.tagBits |= TagBits.AnonymousTypeMask;
+	} else {
+		this.tagBits |= TagBits.LocalTypeMask;
+	}
+	this.enclosingCase = switchCase;
+	this.sourceStart = typeDeclaration.sourceStart;
+	MethodScope methodScope = scope.enclosingMethodScope();
+	MethodBinding methodBinding = methodScope.referenceMethodBinding();
+	if (methodBinding != null) {
+		this.enclosingMethod = methodBinding;
+	}
+}
+
+/* Record a dependency onto a source target type which may be altered
+* by the end of the innerclass emulation. Later on, we will revisit
+* all its dependents so as to update them (see updateInnerEmulationDependents()).
+*/
+public void addInnerEmulationDependent(BlockScope dependentScope, boolean wasEnclosingInstanceSupplied) {
+	int index;
+	if (this.dependents == null) {
+		index = 0;
+		this.dependents = new InnerEmulationDependency[1];
+	} else {
+		index = this.dependents.length;
+		for (int i = 0; i < index; i++)
+			if (this.dependents[i].scope == dependentScope)
+				return; // already stored
+		System.arraycopy(this.dependents, 0, (this.dependents = new InnerEmulationDependency[index + 1]), 0, index);
+	}
+	this.dependents[index] = new InnerEmulationDependency(dependentScope, wasEnclosingInstanceSupplied);
+	//  System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
+}
+
+/*
+ * Returns the anonymous original super type (in some error cases, superclass may get substituted with Object)
+ */
+public ReferenceBinding anonymousOriginalSuperType() {
+	if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
+		return this.superInterfaces[0];
+	}
+	if ((this.tagBits & TagBits.HierarchyHasProblems) == 0) {
+		return this.superclass;
+	}
+	if (this.scope != null) {
+		TypeReference typeReference = this.scope.referenceContext.allocation.type;
+		if (typeReference != null) {
+			return (ReferenceBinding) typeReference.resolvedType;
+		}
+	}
+	return this.superclass; // default answer
+}
+
+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
+	long outerDefault = this.enclosingMethod != null ? this.enclosingMethod.tagBits & ((TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault)) : 0;
+	if (outerDefault != 0) {
+		if (outerDefault == annotationTagBits) {
+			this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.enclosingMethod);
+		}
+		return;
+	}
+	super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits);
+}
+
+public char[] computeUniqueKey(boolean isLeaf) {
+	char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf);
+	int semicolon = CharOperation.lastIndexOf(';', outerKey);
+
+	StringBuffer sig = new StringBuffer();
+	sig.append(outerKey, 0, semicolon);
+
+	// insert $sourceStart
+	sig.append('$');
+	sig.append(String.valueOf(this.sourceStart));
+
+	// insert $LocalName if local
+	if (!isAnonymousType()) {
+		sig.append('$');
+		sig.append(this.sourceName);
+	}
+
+	// insert remaining from outer key
+	sig.append(outerKey, semicolon, outerKey.length-semicolon);
+
+	int sigLength = sig.length();
+	char[] uniqueKey = new char[sigLength];
+	sig.getChars(0, sigLength, uniqueKey, 0);
+	return uniqueKey;
+}
+
+public char[] constantPoolName() /* java/lang/Object */ {
+	if (this.constantPoolName == null && this.scope != null) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322154, we do have some
+		// cases where the left hand does not know what the right is doing.
+		this.constantPoolName = this.scope.compilationUnitScope().computeConstantPoolName(this);
+	}
+	return this.constantPoolName;	
+}
+
+ArrayBinding createArrayType(int dimensionCount, LookupEnvironment lookupEnvironment) {
+	if (this.localArrayBindings == null) {
+		this.localArrayBindings = new ArrayBinding[] {new ArrayBinding(this, dimensionCount, lookupEnvironment)};
+		return this.localArrayBindings[0];
+	}
+	// find the cached array binding for this dimensionCount (if any)
+	int length = this.localArrayBindings.length;
+	for (int i = 0; i < length; i++)
+		if (this.localArrayBindings[i].dimensions == dimensionCount)
+			return this.localArrayBindings[i];
+
+	// no matching array
+	System.arraycopy(this.localArrayBindings, 0, this.localArrayBindings = new ArrayBinding[length + 1], 0, length);
+	return this.localArrayBindings[length] = new ArrayBinding(this, dimensionCount, lookupEnvironment);
+}
+
+/*
+ * Overriden for code assist. In this case, the constantPoolName() has not been computed yet.
+ * Slam the source name so that the signature is syntactically correct.
+ * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=99686)
+ */
+public char[] genericTypeSignature() {
+	if (this.genericReferenceTypeSignature == null && this.constantPoolName == null) {
+		if (isAnonymousType())
+			setConstantPoolName(superclass().sourceName());
+		else
+			setConstantPoolName(sourceName());
+	}
+	return super.genericTypeSignature();
+}
+
+public char[] readableName() /*java.lang.Object,  p.X<T> */ {
+    char[] readableName;
+	if (isAnonymousType()) {
+		readableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().readableName(), TypeConstants.ANONYM_SUFFIX);
+	} else if (isMemberType()) {
+		readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
+	} else {
+		readableName = this.sourceName;
+	}
+	TypeVariableBinding[] typeVars;
+	if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+	    nameBuffer.append(readableName).append('<');
+	    for (int i = 0, length = typeVars.length; i < length; i++) {
+	        if (i > 0) nameBuffer.append(',');
+	        nameBuffer.append(typeVars[i].readableName());
+	    }
+	    nameBuffer.append('>');
+	    int nameLength = nameBuffer.length();
+		readableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, readableName, 0);
+	}
+	return readableName;
+}
+
+public char[] shortReadableName() /*Object*/ {
+    char[] shortReadableName;
+	if (isAnonymousType()) {
+		shortReadableName = CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().shortReadableName(), TypeConstants.ANONYM_SUFFIX);
+	} else if (isMemberType()) {
+		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.');
+	} else {
+		shortReadableName = this.sourceName;
+	}
+	TypeVariableBinding[] typeVars;
+	if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+	    nameBuffer.append(shortReadableName).append('<');
+	    for (int i = 0, length = typeVars.length; i < length; i++) {
+	        if (i > 0) nameBuffer.append(',');
+	        nameBuffer.append(typeVars[i].shortReadableName());
+	    }
+	    nameBuffer.append('>');
+		int nameLength = nameBuffer.length();
+		shortReadableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, shortReadableName, 0);
+	}
+	return shortReadableName;
+}
+
+// Record that the type is a local member type
+public void setAsMemberType() {
+	this.tagBits |= TagBits.MemberTypeMask;
+}
+
+public void setConstantPoolName(char[] computedConstantPoolName) /* java/lang/Object */ {
+	this.constantPoolName = computedConstantPoolName;
+}
+
+/*
+ * Overriden for code assist. In this case, the constantPoolName() has not been computed yet.
+ * Slam the source name so that the signature is syntactically correct.
+ * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=102284)
+ */
+public char[] signature() {
+	if (this.signature == null && this.constantPoolName == null) {
+		if (isAnonymousType())
+			setConstantPoolName(superclass().sourceName());
+		else
+			setConstantPoolName(sourceName());
+	}
+	return super.signature();
+}
+
+public char[] sourceName() {
+	if (isAnonymousType()) {
+		return CharOperation.concat(TypeConstants.ANONYM_PREFIX, anonymousOriginalSuperType().sourceName(), TypeConstants.ANONYM_SUFFIX);
+	} else
+		return this.sourceName;
+}
+
+public String toString() {
+	if (isAnonymousType())
+		return "Anonymous type : " + super.toString(); //$NON-NLS-1$
+	if (isMemberType())
+		return "Local member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
+	return "Local type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
+}
+
+/* Trigger the dependency mechanism forcing the innerclass emulation
+* to be propagated to all dependent source types.
+*/
+public void updateInnerEmulationDependents() {
+	if (this.dependents != null) {
+		for (int i = 0; i < this.dependents.length; i++) {
+			InnerEmulationDependency dependency = this.dependents[i];
+			// System.out.println("Updating " + new String(this.readableName()) + " --> " + new String(dependency.scope.enclosingType().readableName()));
+			dependency.scope.propagateInnerEmulation(this, dependency.wasEnclosingInstanceSupplied);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
new file mode 100644
index 0000000..12d7e33
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     							bug 185682 - Increment/decrement operators mark local variables as read
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+
+public class LocalVariableBinding extends VariableBinding {
+
+	public int resolvedPosition; // for code generation (position in method context)
+
+	public static final int UNUSED = 0;
+	public static final int USED = 1;
+	public static final int FAKE_USED = 2;
+	public int useFlag; // for flow analysis (default is UNUSED), values < 0 indicate the number of compound uses (postIncrement or compoundAssignment)
+
+	public BlockScope declaringScope; // back-pointer to its declaring scope
+	public LocalDeclaration declaration; // for source-positions
+
+	public int[] initializationPCs;
+	public int initializationCount = 0;
+
+	public FakedTrackingVariable closeTracker; // track closing of instances of type AutoCloseable, maybe null
+
+	// for synthetic local variables
+	// if declaration slot is not positionned, the variable will not be listed in attribute
+	// note that the name of a variable should be chosen so as not to conflict with user ones (usually starting with a space char is all needed)
+	public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) {
+		super(name, type, modifiers, isArgument ? Constant.NotAConstant : null);
+		if (isArgument) this.tagBits |= TagBits.IsArgument;
+		this.tagBits |= TagBits.IsEffectivelyFinal;
+	}
+
+	// regular local variable or argument
+	public LocalVariableBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) {
+
+		this(declaration.name, type, modifiers, isArgument);
+		this.declaration = declaration;
+		this.tagBits |= TagBits.IsEffectivelyFinal;
+	}
+
+	/* API
+	* Answer the receiver's binding type from Binding.BindingID.
+	*/
+	public final int kind() {
+		return LOCAL;
+	}
+
+	/*
+	 * declaringUniqueKey # scopeIndex(0-based) # varName [# occurrenceCount(0-based)]
+	 * p.X { void foo() { int local; int local;} } --> Lp/X;.foo()V#1#local#1
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		StringBuffer buffer = new StringBuffer();
+
+		// declaring method or type
+		BlockScope scope = this.declaringScope;
+		int occurenceCount = 0;
+		if (scope != null) {
+			// the scope can be null. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=185129
+			MethodScope methodScope = scope instanceof MethodScope ? (MethodScope) scope : scope.enclosingMethodScope();
+			ReferenceContext referenceContext = methodScope.referenceContext;
+			if (referenceContext instanceof AbstractMethodDeclaration) {
+				MethodBinding methodBinding = ((AbstractMethodDeclaration) referenceContext).binding;
+				if (methodBinding != null) {
+					buffer.append(methodBinding.computeUniqueKey(false/*not a leaf*/));
+				}
+			} else if (referenceContext instanceof TypeDeclaration) {
+				TypeBinding typeBinding = ((TypeDeclaration) referenceContext).binding;
+				if (typeBinding != null) {
+					buffer.append(typeBinding.computeUniqueKey(false/*not a leaf*/));
+				}
+			}
+
+			// scope index
+			getScopeKey(scope, buffer);
+
+			// find number of occurences of a variable with the same name in the scope
+			LocalVariableBinding[] locals = scope.locals;
+			for (int i = 0; i < scope.localIndex; i++) { // use linear search assuming the number of locals per scope is low
+				LocalVariableBinding local = locals[i];
+				if (CharOperation.equals(this.name, local.name)) {
+					if (this == local)
+						break;
+					occurenceCount++;
+				}
+			}
+		}
+		// variable name
+		buffer.append('#');
+		buffer.append(this.name);
+
+		// add occurence count to avoid same key for duplicate variables
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=149590)
+		if (occurenceCount > 0) {
+			buffer.append('#');
+			buffer.append(occurenceCount);
+		}
+
+		int length = buffer.length();
+		char[] uniqueKey = new char[length];
+		buffer.getChars(0, length, uniqueKey, 0);
+		return uniqueKey;
+	}
+
+	public AnnotationBinding[] getAnnotations() {
+		if (this.declaringScope == null) {
+			if ((this.tagBits & TagBits.AnnotationResolved) != 0) {
+				// annotation are already resolved
+				if (this.declaration == null) {
+					return Binding.NO_ANNOTATIONS;
+				}
+				Annotation[] annotations = this.declaration.annotations;
+				if (annotations != null) {
+					int length = annotations.length;
+					AnnotationBinding[] annotationBindings = new AnnotationBinding[length];
+					for (int i = 0; i < length; i++) {
+						AnnotationBinding compilerAnnotation = annotations[i].getCompilerAnnotation();
+						if (compilerAnnotation == null) {
+							return Binding.NO_ANNOTATIONS;
+						}
+						annotationBindings[i] = compilerAnnotation;
+					}
+					return annotationBindings;
+				}
+			}
+			return Binding.NO_ANNOTATIONS;
+		}
+		SourceTypeBinding sourceType = this.declaringScope.enclosingSourceType();
+		if (sourceType == null)
+			return Binding.NO_ANNOTATIONS;
+
+		AnnotationBinding[] annotations = sourceType.retrieveAnnotations(this);
+		if ((this.tagBits & TagBits.AnnotationResolved) == 0) {
+			if (((this.tagBits & TagBits.IsArgument) != 0) && this.declaration != null) {
+				Annotation[] annotationNodes = this.declaration.annotations;
+				if (annotationNodes != null) {
+					int length = annotationNodes.length;
+					ASTNode.resolveAnnotations(this.declaringScope, annotationNodes, this);
+					annotations = new AnnotationBinding[length];
+					for (int i = 0; i < length; i++)
+						annotations[i] = new AnnotationBinding(annotationNodes[i]);
+					setAnnotations(annotations, this.declaringScope);
+				}
+			}
+		}
+		return annotations;
+	}
+
+	private void getScopeKey(BlockScope scope, StringBuffer buffer) {
+		int scopeIndex = scope.scopeIndex();
+		if (scopeIndex != -1) {
+			getScopeKey((BlockScope)scope.parent, buffer);
+			buffer.append('#');
+			buffer.append(scopeIndex);
+		}
+	}
+
+	// Answer whether the variable binding is a secret variable added for code gen purposes
+	public boolean isSecret() {
+
+		return this.declaration == null && (this.tagBits & TagBits.IsArgument) == 0;
+	}
+
+	public void recordInitializationEndPC(int pc) {
+
+		if (this.initializationPCs[((this.initializationCount - 1) << 1) + 1] == -1)
+			this.initializationPCs[((this.initializationCount - 1) << 1) + 1] = pc;
+	}
+
+	public void recordInitializationStartPC(int pc) {
+
+		if (this.initializationPCs == null) {
+			return;
+		}
+		if (this.initializationCount > 0) {
+			int previousEndPC = this.initializationPCs[ ((this.initializationCount - 1) << 1) + 1];
+			 // interval still open, keep using it (108180)
+			if (previousEndPC == -1) {
+				return;
+			}
+			// optimize cases where reopening a contiguous interval
+			if (previousEndPC == pc) {
+				this.initializationPCs[ ((this.initializationCount - 1) << 1) + 1] = -1; // reuse previous interval (its range will be augmented)
+				return;
+			}
+		}
+		int index = this.initializationCount << 1;
+		if (index == this.initializationPCs.length) {
+			System.arraycopy(this.initializationPCs, 0, (this.initializationPCs = new int[this.initializationCount << 2]), 0, index);
+		}
+		this.initializationPCs[index] = pc;
+		this.initializationPCs[index + 1] = -1;
+		this.initializationCount++;
+	}
+
+	public void setAnnotations(AnnotationBinding[] annotations, Scope scope) {
+		// note: we don's use this.declaringScope because we might be called before Scope.addLocalVariable(this)
+		//       which is where this.declaringScope is set.
+		if (scope == null)
+			return;
+		SourceTypeBinding sourceType = scope.enclosingSourceType();
+		if (sourceType != null)
+			sourceType.storeAnnotations(this, annotations);
+	}
+
+	public void resetInitializations() {
+		this.initializationCount = 0;
+		this.initializationPCs = null;
+	}
+
+	public String toString() {
+
+		String s = super.toString();
+		switch (this.useFlag){
+			case USED:
+				s += "[pos: " + String.valueOf(this.resolvedPosition) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
+				break;
+			case UNUSED:
+				s += "[pos: unused]"; //$NON-NLS-1$
+				break;
+			case FAKE_USED:
+				s += "[pos: fake_used]"; //$NON-NLS-1$
+				break;
+		}
+		s += "[id:" + String.valueOf(this.id) + "]"; //$NON-NLS-2$ //$NON-NLS-1$
+		if (this.initializationCount > 0) {
+			s += "[pc: "; //$NON-NLS-1$
+			for (int i = 0; i < this.initializationCount; i++) {
+				if (i > 0)
+					s += ", "; //$NON-NLS-1$
+				s += String.valueOf(this.initializationPCs[i << 1]) + "-" + ((this.initializationPCs[(i << 1) + 1] == -1) ? "?" : String.valueOf(this.initializationPCs[(i<< 1) + 1])); //$NON-NLS-2$ //$NON-NLS-1$
+			}
+			s += "]"; //$NON-NLS-1$
+		}
+		return s;
+	}
+
+	public boolean isParameter() {
+		return ((this.tagBits & TagBits.IsArgument) != 0);
+	}
+	
+	public boolean isCatchParameter() {
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
new file mode 100644
index 0000000..b32ce84
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -0,0 +1,1605 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contributions for
+ *     							bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFilePool;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+public class LookupEnvironment implements ProblemReasons, TypeConstants {
+
+	/**
+	 * Map from typeBinding -> accessRestriction rule
+	 */
+	private Map accessRestrictions;
+	ImportBinding[] defaultImports;
+	public PackageBinding defaultPackage;
+	HashtableOfPackage knownPackages;
+	private int lastCompletedUnitIndex = -1;
+	private int lastUnitIndex = -1;
+
+	public INameEnvironment nameEnvironment;
+	public CompilerOptions globalOptions;
+
+	public ProblemReporter problemReporter;
+	public ClassFilePool classFilePool;
+	// indicate in which step on the compilation we are.
+	// step 1 : build the reference binding
+	// step 2 : conect the hierarchy (connect bindings)
+	// step 3 : build fields and method bindings.
+	private int stepCompleted;
+	public ITypeRequestor typeRequestor;
+
+	private ArrayBinding[][] uniqueArrayBindings;
+	private IntersectionCastTypeBinding[][] uniqueIntersectionCastTypeBindings;
+	private SimpleLookupTable uniqueParameterizedTypeBindings;
+	private SimpleLookupTable uniqueRawTypeBindings;
+	private SimpleLookupTable uniqueWildcardBindings;
+	private SimpleLookupTable uniqueParameterizedGenericMethodBindings;
+	
+	// key is a string with the method selector value is an array of method bindings
+	private SimpleLookupTable uniquePolymorphicMethodBindings;
+	private SimpleLookupTable uniqueGetClassMethodBinding; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734
+
+	public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
+	public Object missingClassFileLocation = null; // only set when resolving certain references, to help locating problems
+	private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
+	private MethodVerifier verifier;
+
+	public MethodBinding arrayClone;
+
+	private ArrayList missingTypes;
+	Set typesBeingConnected;
+	public boolean isProcessingAnnotations = false;
+	public boolean mayTolerateMissingType = false;
+
+	PackageBinding nullableAnnotationPackage;			// the package supposed to contain the Nullable annotation type
+	PackageBinding nonnullAnnotationPackage;			// the package supposed to contain the NonNull annotation type
+	PackageBinding nonnullByDefaultAnnotationPackage;	// the package supposed to contain the NonNullByDefault annotation type
+
+	final static int BUILD_FIELDS_AND_METHODS = 4;
+	final static int BUILD_TYPE_HIERARCHY = 1;
+	final static int CHECK_AND_SET_IMPORTS = 2;
+	final static int CONNECT_TYPE_HIERARCHY = 3;
+
+	static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
+	static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR_CHAR, null, NotFound);
+
+
+public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
+	this.typeRequestor = typeRequestor;
+	this.globalOptions = globalOptions;
+	this.problemReporter = problemReporter;
+	this.defaultPackage = new PackageBinding(this); // assume the default package always exists
+	this.defaultImports = null;
+	this.nameEnvironment = nameEnvironment;
+	this.knownPackages = new HashtableOfPackage();
+	this.uniqueArrayBindings = new ArrayBinding[5][];
+	this.uniqueArrayBindings[0] = new ArrayBinding[50]; // start off the most common 1 dimension array @ 50
+	this.uniqueIntersectionCastTypeBindings = new IntersectionCastTypeBinding[0][0];
+	this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
+	this.uniqueRawTypeBindings = new SimpleLookupTable(3);
+	this.uniqueWildcardBindings = new SimpleLookupTable(3);
+	this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
+	this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3);
+	this.missingTypes = null;
+	this.accessRestrictions = new HashMap(3);
+	this.classFilePool = ClassFilePool.newInstance();
+	this.typesBeingConnected = new HashSet();
+}
+
+/**
+ * Ask the name environment for a type which corresponds to the compoundName.
+ * Answer null if the name cannot be found.
+ */
+
+public ReferenceBinding askForType(char[][] compoundName) {
+	NameEnvironmentAnswer answer = this.nameEnvironment.findType(compoundName);
+	if (answer == null) return null;
+
+	if (answer.isBinaryType()) {
+		// the type was found as a .class file
+		this.typeRequestor.accept(answer.getBinaryType(), computePackageFrom(compoundName, false /* valid pkg */), answer.getAccessRestriction());
+	} else if (answer.isCompilationUnit()) {
+		// the type was found as a .java file, try to build it then search the cache
+		this.typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction());
+	} else if (answer.isSourceType()) {
+		// the type was found as a source model
+		this.typeRequestor.accept(answer.getSourceTypes(), computePackageFrom(compoundName, false /* valid pkg */), answer.getAccessRestriction());
+	}
+	return getCachedType(compoundName);
+}
+/* Ask the oracle for a type named name in the packageBinding.
+* Answer null if the name cannot be found.
+*/
+
+ReferenceBinding askForType(PackageBinding packageBinding, char[] name) {
+	if (packageBinding == null) {
+		packageBinding = this.defaultPackage;
+	}
+	NameEnvironmentAnswer answer = this.nameEnvironment.findType(name, packageBinding.compoundName);
+	if (answer == null)
+		return null;
+
+	if (answer.isBinaryType()) {
+		// the type was found as a .class file
+		this.typeRequestor.accept(answer.getBinaryType(), packageBinding, answer.getAccessRestriction());
+	} else if (answer.isCompilationUnit()) {
+		// the type was found as a .java file, try to build it then search the cache
+		try {
+			this.typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction());
+		} catch (AbortCompilation abort) {
+			if (CharOperation.equals(name, TypeConstants.PACKAGE_INFO_NAME))
+				return null; // silently, requestor may not be able to handle compilation units (HierarchyResolver)
+			throw abort;
+		}
+	} else if (answer.isSourceType()) {
+		// the type was found as a source model
+		this.typeRequestor.accept(answer.getSourceTypes(), packageBinding, answer.getAccessRestriction());
+	}
+	return packageBinding.getType0(name);
+}
+
+/* Create the initial type bindings for the compilation unit.
+*
+* See completeTypeBindings() for a description of the remaining steps
+*
+* NOTE: This method can be called multiple times as additional source files are needed
+*/
+public void buildTypeBindings(CompilationUnitDeclaration unit, AccessRestriction accessRestriction) {
+	CompilationUnitScope scope = new CompilationUnitScope(unit, this);
+	scope.buildTypeBindings(accessRestriction);
+	int unitsLength = this.units.length;
+	if (++this.lastUnitIndex >= unitsLength)
+		System.arraycopy(this.units, 0, this.units = new CompilationUnitDeclaration[2 * unitsLength], 0, unitsLength);
+	this.units[this.lastUnitIndex] = unit;
+}
+
+/* Cache the binary type since we know it is needed during this compile.
+*
+* Answer the created BinaryTypeBinding or null if the type is already in the cache.
+*/
+public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, AccessRestriction accessRestriction) {
+	return cacheBinaryType(binaryType, true, accessRestriction);
+}
+
+/* Cache the binary type since we know it is needed during this compile.
+*
+* Answer the created BinaryTypeBinding or null if the type is already in the cache.
+*/
+public BinaryTypeBinding cacheBinaryType(IBinaryType binaryType, boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
+	char[][] compoundName = CharOperation.splitOn('/', binaryType.getName());
+	ReferenceBinding existingType = getCachedType(compoundName);
+
+	if (existingType == null || existingType instanceof UnresolvedReferenceBinding)
+		// only add the binary type if its not already in the cache
+		return createBinaryTypeFrom(binaryType, computePackageFrom(compoundName, false /* valid pkg */), needFieldsAndMethods, accessRestriction);
+	return null; // the type already exists & can be retrieved from the cache
+}
+
+public void completeTypeBindings() {
+	this.stepCompleted = BUILD_TYPE_HIERARCHY;
+
+	for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
+	    (this.unitBeingCompleted = this.units[i]).scope.checkAndSetImports();
+	}
+	this.stepCompleted = CHECK_AND_SET_IMPORTS;
+
+	for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
+	    (this.unitBeingCompleted = this.units[i]).scope.connectTypeHierarchy();
+	}
+	this.stepCompleted = CONNECT_TYPE_HIERARCHY;
+
+	for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
+		CompilationUnitScope unitScope = (this.unitBeingCompleted = this.units[i]).scope;
+		unitScope.checkParameterizedTypes();
+		unitScope.buildFieldsAndMethods();
+		this.units[i] = null; // release unnecessary reference to the parsed unit
+	}
+	this.stepCompleted = BUILD_FIELDS_AND_METHODS;
+	this.lastCompletedUnitIndex = this.lastUnitIndex;
+	this.unitBeingCompleted = null;
+}
+
+/*
+* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
+* 2. Create the field bindings
+* 3. Create the method bindings
+*/
+
+/* We know each known compilationUnit is free of errors at this point...
+*
+* Each step will create additional bindings unless a problem is detected, in which
+* case either the faulty import/superinterface/field/method will be skipped or a
+* suitable replacement will be substituted (such as Object for a missing superclass)
+*/
+public void completeTypeBindings(CompilationUnitDeclaration parsedUnit) {
+	if (this.stepCompleted == BUILD_FIELDS_AND_METHODS) {
+		// This can only happen because the original set of units are completely built and
+		// are now being processed, so we want to treat all the additional units as a group
+		// until they too are completely processed.
+		completeTypeBindings();
+	} else {
+		if (parsedUnit.scope == null) return; // parsing errors were too severe
+
+		if (this.stepCompleted >= CHECK_AND_SET_IMPORTS)
+			(this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
+
+		if (this.stepCompleted >= CONNECT_TYPE_HIERARCHY)
+			(this.unitBeingCompleted = parsedUnit).scope.connectTypeHierarchy();
+
+		this.unitBeingCompleted = null;
+	}
+}
+
+/*
+* Used by other compiler tools which do not start by calling completeTypeBindings().
+*
+* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
+* 2. Create the field bindings
+* 3. Create the method bindings
+*/
+
+/*
+* Each step will create additional bindings unless a problem is detected, in which
+* case either the faulty import/superinterface/field/method will be skipped or a
+* suitable replacement will be substituted (such as Object for a missing superclass)
+*/
+public void completeTypeBindings(CompilationUnitDeclaration parsedUnit, boolean buildFieldsAndMethods) {
+	if (parsedUnit.scope == null) return; // parsing errors were too severe
+
+	(this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
+	parsedUnit.scope.connectTypeHierarchy();
+	parsedUnit.scope.checkParameterizedTypes();
+	if (buildFieldsAndMethods)
+		parsedUnit.scope.buildFieldsAndMethods();
+	this.unitBeingCompleted = null;
+}
+
+/*
+* Used by other compiler tools which do not start by calling completeTypeBindings()
+* and have more than 1 unit to complete.
+*
+* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
+* 2. Create the field bindings
+* 3. Create the method bindings
+*/
+public void completeTypeBindings(CompilationUnitDeclaration[] parsedUnits, boolean[] buildFieldsAndMethods, int unitCount) {
+	for (int i = 0; i < unitCount; i++) {
+		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
+		if (parsedUnit.scope != null)
+			(this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
+	}
+
+	for (int i = 0; i < unitCount; i++) {
+		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
+		if (parsedUnit.scope != null)
+			(this.unitBeingCompleted = parsedUnit).scope.connectTypeHierarchy();
+	}
+
+	for (int i = 0; i < unitCount; i++) {
+		CompilationUnitDeclaration parsedUnit = parsedUnits[i];
+		if (parsedUnit.scope != null) {
+			(this.unitBeingCompleted = parsedUnit).scope.checkParameterizedTypes();
+			if (buildFieldsAndMethods[i])
+				parsedUnit.scope.buildFieldsAndMethods();
+		}
+	}
+
+	this.unitBeingCompleted = null;
+}
+public MethodBinding computeArrayClone(MethodBinding objectClone) {
+	if (this.arrayClone == null) {
+		this.arrayClone = new MethodBinding(
+				(objectClone.modifiers & ~ClassFileConstants.AccProtected) | ClassFileConstants.AccPublic,
+				TypeConstants.CLONE,
+				objectClone.returnType,
+				Binding.NO_PARAMETERS,
+				Binding.NO_EXCEPTIONS, // no exception for array specific method
+				(ReferenceBinding)objectClone.returnType);
+	}
+	return this.arrayClone;
+	
+}
+public TypeBinding computeBoxingType(TypeBinding type) {
+	TypeBinding boxedType;
+	switch (type.id) {
+		case TypeIds.T_JavaLangBoolean :
+			return TypeBinding.BOOLEAN;
+		case TypeIds.T_JavaLangByte :
+			return TypeBinding.BYTE;
+		case TypeIds.T_JavaLangCharacter :
+			return TypeBinding.CHAR;
+		case TypeIds.T_JavaLangShort :
+			return TypeBinding.SHORT;
+		case TypeIds.T_JavaLangDouble :
+			return TypeBinding.DOUBLE;
+		case TypeIds.T_JavaLangFloat :
+			return TypeBinding.FLOAT;
+		case TypeIds.T_JavaLangInteger :
+			return TypeBinding.INT;
+		case TypeIds.T_JavaLangLong :
+			return TypeBinding.LONG;
+
+		case TypeIds.T_int :
+			boxedType = getType(JAVA_LANG_INTEGER);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_INTEGER, null, NotFound);
+		case TypeIds.T_byte :
+			boxedType = getType(JAVA_LANG_BYTE);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_BYTE, null, NotFound);
+		case TypeIds.T_short :
+			boxedType = getType(JAVA_LANG_SHORT);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_SHORT, null, NotFound);
+		case TypeIds.T_char :
+			boxedType = getType(JAVA_LANG_CHARACTER);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_CHARACTER, null, NotFound);
+		case TypeIds.T_long :
+			boxedType = getType(JAVA_LANG_LONG);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_LONG, null, NotFound);
+		case TypeIds.T_float :
+			boxedType = getType(JAVA_LANG_FLOAT);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_FLOAT, null, NotFound);
+		case TypeIds.T_double :
+			boxedType = getType(JAVA_LANG_DOUBLE);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_DOUBLE, null, NotFound);
+		case TypeIds.T_boolean :
+			boxedType = getType(JAVA_LANG_BOOLEAN);
+			if (boxedType != null) return boxedType;
+			return new ProblemReferenceBinding(JAVA_LANG_BOOLEAN, null, NotFound);
+//		case TypeIds.T_int :
+//			return getResolvedType(JAVA_LANG_INTEGER, null);
+//		case TypeIds.T_byte :
+//			return getResolvedType(JAVA_LANG_BYTE, null);
+//		case TypeIds.T_short :
+//			return getResolvedType(JAVA_LANG_SHORT, null);
+//		case TypeIds.T_char :
+//			return getResolvedType(JAVA_LANG_CHARACTER, null);
+//		case TypeIds.T_long :
+//			return getResolvedType(JAVA_LANG_LONG, null);
+//		case TypeIds.T_float :
+//			return getResolvedType(JAVA_LANG_FLOAT, null);
+//		case TypeIds.T_double :
+//			return getResolvedType(JAVA_LANG_DOUBLE, null);
+//		case TypeIds.T_boolean :
+//			return getResolvedType(JAVA_LANG_BOOLEAN, null);
+	}
+	// allow indirect unboxing conversion for wildcards and type parameters
+	switch (type.kind()) {
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+		case Binding.TYPE_PARAMETER :
+			switch (type.erasure().id) {
+				case TypeIds.T_JavaLangBoolean :
+					return TypeBinding.BOOLEAN;
+				case TypeIds.T_JavaLangByte :
+					return TypeBinding.BYTE;
+				case TypeIds.T_JavaLangCharacter :
+					return TypeBinding.CHAR;
+				case TypeIds.T_JavaLangShort :
+					return TypeBinding.SHORT;
+				case TypeIds.T_JavaLangDouble :
+					return TypeBinding.DOUBLE;
+				case TypeIds.T_JavaLangFloat :
+					return TypeBinding.FLOAT;
+				case TypeIds.T_JavaLangInteger :
+					return TypeBinding.INT;
+				case TypeIds.T_JavaLangLong :
+					return TypeBinding.LONG;
+			}
+	}
+	return type;
+}
+
+private PackageBinding computePackageFrom(char[][] constantPoolName, boolean isMissing) {
+	if (constantPoolName.length == 1)
+		return this.defaultPackage;
+
+	PackageBinding packageBinding = getPackage0(constantPoolName[0]);
+	if (packageBinding == null || packageBinding == TheNotFoundPackage) {
+		packageBinding = new PackageBinding(constantPoolName[0], this);
+		if (isMissing) packageBinding.tagBits |= TagBits.HasMissingType;
+		this.knownPackages.put(constantPoolName[0], packageBinding);
+	}
+
+	for (int i = 1, length = constantPoolName.length - 1; i < length; i++) {
+		PackageBinding parent = packageBinding;
+		if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) {
+			packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this);
+			if (isMissing) {
+				packageBinding.tagBits |= TagBits.HasMissingType;
+			}
+			parent.addPackage(packageBinding);
+		}
+	}
+	return packageBinding;
+}
+
+/**
+ * Convert a given source type into a parameterized form if generic.
+ * generic X<E> --> param X<E>
+ */
+public ReferenceBinding convertToParameterizedType(ReferenceBinding originalType) {
+	if (originalType != null) {
+		boolean isGeneric = originalType.isGenericType();
+		ReferenceBinding originalEnclosingType = originalType.enclosingType();
+		ReferenceBinding convertedEnclosingType = originalEnclosingType;
+		boolean needToConvert = isGeneric;
+		if (originalEnclosingType != null) {
+			convertedEnclosingType = originalType.isStatic()
+				? (ReferenceBinding) convertToRawType(originalEnclosingType, false /*do not force conversion of enclosing types*/)
+				: convertToParameterizedType(originalEnclosingType);
+			needToConvert |= originalEnclosingType != convertedEnclosingType;
+		}
+		if (needToConvert) {
+			return createParameterizedType(originalType, isGeneric ? originalType.typeVariables() : null, convertedEnclosingType);
+		}
+	}
+	return originalType;
+}
+
+/**
+ * Returns the given binding's raw type binding.
+ * @param type the TypeBinding to raw convert
+ * @param forceRawEnclosingType forces recursive raw conversion of enclosing types (used in Javadoc references only)
+ * @return TypeBinding the raw converted TypeBinding
+ */
+public TypeBinding convertToRawType(TypeBinding type, boolean forceRawEnclosingType) {
+	int dimension;
+	TypeBinding originalType;
+	switch(type.kind()) {
+		case Binding.BASE_TYPE :
+		case Binding.TYPE_PARAMETER:
+		case Binding.WILDCARD_TYPE:
+		case Binding.INTERSECTION_TYPE:
+		case Binding.RAW_TYPE:
+			return type;
+		case Binding.ARRAY_TYPE:
+			dimension = type.dimensions();
+			originalType = type.leafComponentType();
+			break;
+		default:
+			if (type.id == TypeIds.T_JavaLangObject)
+				return type; // Object is not generic
+			dimension = 0;
+			originalType = type;
+	}
+	boolean needToConvert;
+	switch (originalType.kind()) {
+		case Binding.BASE_TYPE :
+			return type;
+		case Binding.GENERIC_TYPE :
+			needToConvert = true;
+			break;
+		case Binding.PARAMETERIZED_TYPE :
+			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
+			needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
+			break;
+		default :
+			needToConvert = false;
+			break;
+	}
+	ReferenceBinding originalEnclosing = originalType.enclosingType();
+	TypeBinding convertedType;
+	if (originalEnclosing == null) {
+		convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
+	} else {
+		ReferenceBinding convertedEnclosing;
+		if (originalEnclosing.kind() == Binding.RAW_TYPE) {
+			needToConvert |= !((ReferenceBinding)originalType).isStatic();
+			convertedEnclosing = originalEnclosing;
+		} else if (forceRawEnclosingType && !needToConvert/*stop recursion when conversion occurs*/) {
+			convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing, forceRawEnclosingType);
+			needToConvert = originalEnclosing != convertedEnclosing; // only convert generic or parameterized types
+		} else if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
+			convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing, false);
+		} else {
+			convertedEnclosing = convertToParameterizedType(originalEnclosing);
+		}
+		if (needToConvert) {
+			convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
+		} else if (originalEnclosing != convertedEnclosing) {
+			convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
+		} else {
+			convertedType = originalType;
+		}
+	}
+	if (originalType != convertedType) {
+		return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
+	}
+	return type;
+}
+
+/**
+ * Convert an array of types in raw forms.
+ * Only allocate an array if anything is different.
+ */
+public ReferenceBinding[] convertToRawTypes(ReferenceBinding[] originalTypes, boolean forceErasure, boolean forceRawEnclosingType) {
+	if (originalTypes == null) return null;
+    ReferenceBinding[] convertedTypes = originalTypes;
+    for (int i = 0, length = originalTypes.length; i < length; i++) {
+        ReferenceBinding originalType = originalTypes[i];
+        ReferenceBinding convertedType = (ReferenceBinding) convertToRawType(forceErasure ? originalType.erasure() : originalType, forceRawEnclosingType);
+        if (convertedType != originalType) {        
+            if (convertedTypes == originalTypes) {
+                System.arraycopy(originalTypes, 0, convertedTypes = new ReferenceBinding[length], 0, i);
+            }
+            convertedTypes[i] = convertedType;
+        } else if (convertedTypes != originalTypes) {
+            convertedTypes[i] = originalType;
+        }
+    }
+    return convertedTypes;
+}
+
+// variation for unresolved types in binaries (consider generic type as raw)
+public TypeBinding convertUnresolvedBinaryToRawType(TypeBinding type) {
+	int dimension;
+	TypeBinding originalType;
+	switch(type.kind()) {
+		case Binding.BASE_TYPE :
+		case Binding.TYPE_PARAMETER:
+		case Binding.WILDCARD_TYPE:
+		case Binding.INTERSECTION_TYPE:
+		case Binding.RAW_TYPE:
+			return type;
+		case Binding.ARRAY_TYPE:
+			dimension = type.dimensions();
+			originalType = type.leafComponentType();
+			break;
+		default:
+			if (type.id == TypeIds.T_JavaLangObject)
+				return type; // Object is not generic
+			dimension = 0;
+			originalType = type;
+	}
+	boolean needToConvert;
+	switch (originalType.kind()) {
+		case Binding.BASE_TYPE :
+			return type;
+		case Binding.GENERIC_TYPE :
+			needToConvert = true;
+			break;
+		case Binding.PARAMETERIZED_TYPE :
+			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
+			needToConvert = paramType.genericType().isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
+			break;
+		default :
+			needToConvert = false;
+			break;
+	}
+	ReferenceBinding originalEnclosing = originalType.enclosingType();
+	TypeBinding convertedType;
+	if (originalEnclosing == null) {
+		convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
+	} else {
+		ReferenceBinding convertedEnclosing = (ReferenceBinding) convertUnresolvedBinaryToRawType(originalEnclosing);
+		if (convertedEnclosing != originalEnclosing) {
+			needToConvert |= !((ReferenceBinding)originalType).isStatic();
+		}
+		if (needToConvert) {
+			convertedType = createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
+		} else if (originalEnclosing != convertedEnclosing) {
+			convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
+		} else {
+			convertedType = originalType;
+		}
+	}
+	if (originalType != convertedType) {
+		return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
+	}
+	return type;
+}
+/*
+ *  Used to guarantee annotation identity.
+ */
+public AnnotationBinding createAnnotation(ReferenceBinding annotationType, ElementValuePair[] pairs) {
+	if (pairs.length != 0) {
+		AnnotationBinding.setMethodBindings(annotationType, pairs);
+	}
+	return new AnnotationBinding(annotationType, pairs);
+}
+
+/*
+ *  Used to guarantee array type identity.
+ */
+public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount) {
+	return createArrayType(leafComponentType, dimensionCount, null);
+}
+public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount, long[] nullTagBitsPerDimension) {
+	if (leafComponentType instanceof LocalTypeBinding) // cache local type arrays with the local type itself
+		return ((LocalTypeBinding) leafComponentType).createArrayType(dimensionCount, this);
+
+	// find the array binding cache for this dimension
+	int dimIndex = dimensionCount - 1;
+	int length = this.uniqueArrayBindings.length;
+	ArrayBinding[] arrayBindings;
+	if (dimIndex < length) {
+		if ((arrayBindings = this.uniqueArrayBindings[dimIndex]) == null)
+			this.uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
+	} else {
+		System.arraycopy(
+			this.uniqueArrayBindings, 0,
+			this.uniqueArrayBindings = new ArrayBinding[dimensionCount][], 0,
+			length);
+		this.uniqueArrayBindings[dimIndex] = arrayBindings = new ArrayBinding[10];
+	}
+
+	// find the cached array binding for this leaf component type (if any)
+	int index = -1;
+	length = arrayBindings.length;
+	while (++index < length) {
+		ArrayBinding currentBinding = arrayBindings[index];
+		if (currentBinding == null) // no matching array, but space left
+			return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this, nullTagBitsPerDimension);
+		if (currentBinding.leafComponentType == leafComponentType
+				&& (nullTagBitsPerDimension == null || Arrays.equals(currentBinding.nullTagBitsPerDimension, nullTagBitsPerDimension)))
+			return currentBinding;
+	}
+
+	// no matching array, no space left
+	System.arraycopy(
+		arrayBindings, 0,
+		(arrayBindings = new ArrayBinding[length * 2]), 0,
+		length);
+	this.uniqueArrayBindings[dimIndex] = arrayBindings;
+	return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this, nullTagBitsPerDimension);
+}
+public TypeBinding createIntersectionCastType(ReferenceBinding[] intersectingTypes) {
+	
+	// this is perhaps an overkill, but since what is worth doing is worth doing well ...
+	
+	int count = intersectingTypes.length;
+	int length = this.uniqueIntersectionCastTypeBindings.length;
+	IntersectionCastTypeBinding[] intersectionCastTypeBindings;
+
+	if (count < length) {
+		if ((intersectionCastTypeBindings = this.uniqueIntersectionCastTypeBindings[count]) == null)
+			this.uniqueIntersectionCastTypeBindings[count] = intersectionCastTypeBindings = new IntersectionCastTypeBinding[10];
+	} else {
+		System.arraycopy(
+			this.uniqueIntersectionCastTypeBindings, 0,
+			this.uniqueIntersectionCastTypeBindings = new IntersectionCastTypeBinding[count + 1][], 0,
+			length);
+		this.uniqueIntersectionCastTypeBindings[count] = intersectionCastTypeBindings = new IntersectionCastTypeBinding[10];
+	}
+
+	int index = -1;
+	length = intersectionCastTypeBindings.length;
+	next:while (++index < length) {
+		IntersectionCastTypeBinding priorBinding = intersectionCastTypeBindings[index];
+		if (priorBinding == null) // no matching intersection type, but space left
+			return intersectionCastTypeBindings[index] = new IntersectionCastTypeBinding(intersectingTypes, this);
+		ReferenceBinding [] priorIntersectingTypes = priorBinding.intersectingTypes;
+		for (int i = 0; i < count; i++) {
+			if (intersectingTypes[i] != priorIntersectingTypes[i])
+					continue next;
+		}	
+		return priorBinding;
+	}
+
+	// no matching cached binding & no space left
+	System.arraycopy(
+		intersectionCastTypeBindings, 0,
+		(intersectionCastTypeBindings = new IntersectionCastTypeBinding[length * 2]), 0,
+		length);
+	this.uniqueIntersectionCastTypeBindings[count] = intersectionCastTypeBindings;
+	return intersectionCastTypeBindings[length] = new IntersectionCastTypeBinding(intersectingTypes, this);
+}
+public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+	return createBinaryTypeFrom(binaryType, packageBinding, true, accessRestriction);
+}
+
+public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
+	BinaryTypeBinding binaryBinding = new BinaryTypeBinding(packageBinding, binaryType, this);
+
+	// resolve any array bindings which reference the unresolvedType
+	ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
+	if (cachedType != null) { // update reference to unresolved binding after having read classfile (knows whether generic for raw conversion)
+		if (cachedType instanceof UnresolvedReferenceBinding) {
+			((UnresolvedReferenceBinding) cachedType).setResolvedType(binaryBinding, this);
+		} else {
+			if (cachedType.isBinaryBinding()) // sanity check... at this point the cache should ONLY contain unresolved types
+				return (BinaryTypeBinding) cachedType;
+			// it is possible with a large number of source files (exceeding AbstractImageBuilder.MAX_AT_ONCE) that a member type can be in the cache as an UnresolvedType,
+			// but because its enclosingType is resolved while its created (call to BinaryTypeBinding constructor), its replaced with a source type
+			return null;
+		}
+	}
+	packageBinding.addType(binaryBinding);
+	setAccessRestriction(binaryBinding, accessRestriction);
+	// need type annotations before processing methods (for @NonNullByDefault)
+	if (this.globalOptions.isAnnotationBasedNullAnalysisEnabled)
+		binaryBinding.scanTypeForNullDefaultAnnotation(binaryType, packageBinding, binaryBinding);
+	binaryBinding.cachePartsFrom(binaryType, needFieldsAndMethods);
+	return binaryBinding;
+}
+
+/*
+ * Used to create types denoting missing types.
+ * If package is given, then reuse the package; if not then infer a package from compound name.
+ * If the package is existing, then install the missing type in type cache
+*/
+public MissingTypeBinding createMissingType(PackageBinding packageBinding, char[][] compoundName) {
+	// create a proxy for the missing BinaryType
+	if (packageBinding == null) {
+		packageBinding = computePackageFrom(compoundName, true /* missing */);
+		if (packageBinding == TheNotFoundPackage) packageBinding = this.defaultPackage;
+	}
+	MissingTypeBinding missingType = new MissingTypeBinding(packageBinding, compoundName, this);
+	if (missingType.id != TypeIds.T_JavaLangObject) {
+		// make Object be its superclass - it could in turn be missing as well
+		ReferenceBinding objectType = getType(TypeConstants.JAVA_LANG_OBJECT);
+		if (objectType == null) {
+			objectType = createMissingType(null, TypeConstants.JAVA_LANG_OBJECT);	// create a proxy for the missing Object type
+		}
+		missingType.setMissingSuperclass(objectType);
+	}
+	packageBinding.addType(missingType);
+	if (this.missingTypes == null)
+		this.missingTypes = new ArrayList(3);
+	this.missingTypes.add(missingType);
+	return missingType;
+}
+
+/*
+* 1. Connect the type hierarchy for the type bindings created for parsedUnits.
+* 2. Create the field bindings
+* 3. Create the method bindings
+*/
+public PackageBinding createPackage(char[][] compoundName) {
+	PackageBinding packageBinding = getPackage0(compoundName[0]);
+	if (packageBinding == null || packageBinding == TheNotFoundPackage) {
+		packageBinding = new PackageBinding(compoundName[0], this);
+		this.knownPackages.put(compoundName[0], packageBinding);
+	}
+
+	for (int i = 1, length = compoundName.length; i < length; i++) {
+		// check to see if it collides with a known type...
+		// this case can only happen if the package does not exist as a directory in the file system
+		// otherwise when the source type was defined, the correct error would have been reported
+		// unless its an unresolved type which is referenced from an inconsistent class file
+		// NOTE: empty packages are not packages according to changes in JLS v2, 7.4.3
+		// so not all types cause collision errors when they're created even though the package did exist
+		ReferenceBinding type = packageBinding.getType0(compoundName[i]);
+		if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding))
+			return null;
+
+		PackageBinding parent = packageBinding;
+		if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) {
+			// if the package is unknown, check to see if a type exists which would collide with the new package
+			// catches the case of a package statement of: package java.lang.Object;
+			// since the package can be added after a set of source files have already been compiled,
+			// we need to check whenever a package is created
+			if (this.nameEnvironment.findType(compoundName[i], parent.compoundName) != null)
+				return null;
+
+			packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this);
+			parent.addPackage(packageBinding);
+		}
+	}
+	return packageBinding;
+}
+
+public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, RawTypeBinding rawType) {
+	// cached info is array of already created parameterized types for this type
+	ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod);
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null){
+		nextCachedMethod :
+			// iterate existing parameterized for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++){
+				ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) break nextCachedMethod;
+				if (!cachedMethod.isRaw) continue nextCachedMethod;
+				if (cachedMethod.declaringClass != (rawType == null ? genericMethod.declaringClass : rawType)) continue nextCachedMethod;
+				return cachedMethod;
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new ParameterizedGenericMethodBinding[5];
+		this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length){
+		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
+		this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
+	}
+	// add new binding
+	ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, rawType, this);
+	cachedInfo[index] = parameterizedGenericMethod;
+	return parameterizedGenericMethod;
+}
+
+public ParameterizedGenericMethodBinding createParameterizedGenericMethod(MethodBinding genericMethod, TypeBinding[] typeArguments) {
+	// cached info is array of already created parameterized types for this type
+	ParameterizedGenericMethodBinding[] cachedInfo = (ParameterizedGenericMethodBinding[])this.uniqueParameterizedGenericMethodBindings.get(genericMethod);
+	int argLength = typeArguments == null ? 0: typeArguments.length;
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null){
+		nextCachedMethod :
+			// iterate existing parameterized for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++){
+				ParameterizedGenericMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) break nextCachedMethod;
+				if (cachedMethod.isRaw) continue nextCachedMethod;
+				TypeBinding[] cachedArguments = cachedMethod.typeArguments;
+				int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
+				if (argLength != cachedArgLength) continue nextCachedMethod;
+				for (int j = 0; j < cachedArgLength; j++){
+					if (typeArguments[j] != cachedArguments[j]) continue nextCachedMethod;
+				}
+				// all arguments match, reuse current
+				return cachedMethod;
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new ParameterizedGenericMethodBinding[5];
+		this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length){
+		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedGenericMethodBinding[length*2], 0, length);
+		this.uniqueParameterizedGenericMethodBindings.put(genericMethod, cachedInfo);
+	}
+	// add new binding
+	ParameterizedGenericMethodBinding parameterizedGenericMethod = new ParameterizedGenericMethodBinding(genericMethod, typeArguments, this);
+	cachedInfo[index] = parameterizedGenericMethod;
+	return parameterizedGenericMethod;
+}
+public PolymorphicMethodBinding createPolymorphicMethod(MethodBinding originalPolymorphicMethod, TypeBinding[] parameters) {
+	// cached info is array of already created polymorphic methods for this type
+	String key = new String(originalPolymorphicMethod.selector);
+	PolymorphicMethodBinding[] cachedInfo = (PolymorphicMethodBinding[]) this.uniquePolymorphicMethodBindings.get(key);
+	int parametersLength = parameters == null ? 0: parameters.length;
+	TypeBinding[] parametersTypeBinding = new TypeBinding[parametersLength]; 
+	for (int i = 0; i < parametersLength; i++) {
+		TypeBinding parameterTypeBinding = parameters[i];
+		if (parameterTypeBinding.id == TypeIds.T_null) {
+			parametersTypeBinding[i] = getType(JAVA_LANG_VOID);
+		} else {
+			parametersTypeBinding[i] = parameterTypeBinding.erasure();
+		}
+	}
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null) {
+		nextCachedMethod :
+			// iterate existing polymorphic method for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++) {
+				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) {
+					break nextCachedMethod;
+				}
+				if (cachedMethod.matches(parametersTypeBinding, originalPolymorphicMethod.returnType)) {
+					return cachedMethod;
+				}
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new PolymorphicMethodBinding[5];
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length) {
+		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// add new binding
+	PolymorphicMethodBinding polymorphicMethod = new PolymorphicMethodBinding(
+			originalPolymorphicMethod,
+			parametersTypeBinding);
+	cachedInfo[index] = polymorphicMethod;
+	return polymorphicMethod;
+}
+public MethodBinding updatePolymorphicMethodReturnType(PolymorphicMethodBinding binding, TypeBinding typeBinding) {
+	// update the return type to be the given return type, but reuse existing binding if one can match
+	String key = new String(binding.selector);
+	PolymorphicMethodBinding[] cachedInfo = (PolymorphicMethodBinding[]) this.uniquePolymorphicMethodBindings.get(key);
+	boolean needToGrow = false;
+	int index = 0;
+	TypeBinding[] parameters = binding.parameters;
+	if (cachedInfo != null) {
+		nextCachedMethod :
+			// iterate existing polymorphic method for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++) {
+				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) {
+					break nextCachedMethod;
+				}
+				if (cachedMethod.matches(parameters, typeBinding)) {
+					return cachedMethod;
+				}
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new PolymorphicMethodBinding[5];
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length) {
+		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// add new binding
+	PolymorphicMethodBinding polymorphicMethod = new PolymorphicMethodBinding(
+			binding.original(),
+			typeBinding,
+			parameters);
+	cachedInfo[index] = polymorphicMethod;
+	return polymorphicMethod;
+}
+public ParameterizedMethodBinding createGetClassMethod(TypeBinding receiverType, MethodBinding originalMethod, Scope scope) {
+	// see if we have already cached this method for the given receiver type.
+	ParameterizedMethodBinding retVal = null;
+	if (this.uniqueGetClassMethodBinding == null) {
+		this.uniqueGetClassMethodBinding = new SimpleLookupTable(3);
+	} else {
+		retVal = (ParameterizedMethodBinding)this.uniqueGetClassMethodBinding.get(receiverType);
+	}
+	if (retVal == null) {
+		retVal = ParameterizedMethodBinding.instantiateGetClass(receiverType, originalMethod, scope);
+		this.uniqueGetClassMethodBinding.put(receiverType, retVal);
+	}
+	return retVal;
+}
+
+public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType) {
+	return createParameterizedType(genericType, typeArguments, 0L, enclosingType);
+}
+/* Note: annotationBits are exactly those tagBits from annotations on type parameters that are interpreted by the compiler, currently: null annotations. */
+public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericType, TypeBinding[] typeArguments, long annotationBits, ReferenceBinding enclosingType) {
+	// cached info is array of already created parameterized types for this type
+	ParameterizedTypeBinding[] cachedInfo = (ParameterizedTypeBinding[])this.uniqueParameterizedTypeBindings.get(genericType);
+	int argLength = typeArguments == null ? 0: typeArguments.length;
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null){
+		nextCachedType :
+			// iterate existing parameterized for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++){
+			    ParameterizedTypeBinding cachedType = cachedInfo[index];
+			    if (cachedType == null) break nextCachedType;
+			    if (cachedType.actualType() != genericType) continue nextCachedType; // remain of unresolved type
+			    if (cachedType.enclosingType() != enclosingType) continue nextCachedType;
+			    if (annotationBits != 0 && ((cachedType.tagBits & annotationBits) != annotationBits)) continue nextCachedType;
+				TypeBinding[] cachedArguments = cachedType.arguments;
+				int cachedArgLength = cachedArguments == null ? 0 : cachedArguments.length;
+				if (argLength != cachedArgLength) continue nextCachedType; // would be an error situation (from unresolved binaries)
+				for (int j = 0; j < cachedArgLength; j++){
+					if (typeArguments[j] != cachedArguments[j]) continue nextCachedType;
+				}
+				// all arguments match, reuse current
+				return cachedType;
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new ParameterizedTypeBinding[5];
+		this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length){
+		System.arraycopy(cachedInfo, 0, cachedInfo = new ParameterizedTypeBinding[length*2], 0, length);
+		this.uniqueParameterizedTypeBindings.put(genericType, cachedInfo);
+	}
+	// add new binding
+	ParameterizedTypeBinding parameterizedType = new ParameterizedTypeBinding(genericType,typeArguments, enclosingType, this);
+	parameterizedType.tagBits |= annotationBits;
+	cachedInfo[index] = parameterizedType;
+	return parameterizedType;
+}
+
+public RawTypeBinding createRawType(ReferenceBinding genericType, ReferenceBinding enclosingType) {
+	// cached info is array of already created raw types for this type
+	RawTypeBinding[] cachedInfo = (RawTypeBinding[])this.uniqueRawTypeBindings.get(genericType);
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null){
+		nextCachedType :
+			// iterate existing parameterized for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++){
+			    RawTypeBinding cachedType = cachedInfo[index];
+			    if (cachedType == null) break nextCachedType;
+			    if (cachedType.actualType() != genericType) continue nextCachedType; // remain of unresolved type
+			    if (cachedType.enclosingType() != enclosingType) continue nextCachedType;
+				// all enclosing type match, reuse current
+				return cachedType;
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new RawTypeBinding[1];
+		this.uniqueRawTypeBindings.put(genericType, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length){
+		System.arraycopy(cachedInfo, 0, cachedInfo = new RawTypeBinding[length*2], 0, length);
+		this.uniqueRawTypeBindings.put(genericType, cachedInfo);
+	}
+	// add new binding
+	RawTypeBinding rawType = new RawTypeBinding(genericType, enclosingType, this);
+	cachedInfo[index] = rawType;
+	return rawType;
+
+}
+
+public WildcardBinding createWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind) {
+	// cached info is array of already created wildcard  types for this type
+	if (genericType == null) // pseudo wildcard denoting composite bounds for lub computation
+		genericType = ReferenceBinding.LUB_GENERIC;
+	WildcardBinding[] cachedInfo = (WildcardBinding[])this.uniqueWildcardBindings.get(genericType);
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null){
+		nextCachedType :
+			// iterate existing wildcards for reusing one with same information if any
+			for (int max = cachedInfo.length; index < max; index++){
+			    WildcardBinding cachedType = cachedInfo[index];
+			    if (cachedType == null) break nextCachedType;
+			    if (cachedType.genericType != genericType) continue nextCachedType; // remain of unresolved type
+			    if (cachedType.rank != rank) continue nextCachedType;
+			    if (cachedType.boundKind != boundKind) continue nextCachedType;
+			    if (cachedType.bound != bound) continue nextCachedType;
+			    if (cachedType.otherBounds != otherBounds) {
+			    	int cachedLength = cachedType.otherBounds == null ? 0 : cachedType.otherBounds.length;
+			    	int length = otherBounds == null ? 0 : otherBounds.length;
+			    	if (cachedLength != length) continue nextCachedType;
+			    	for (int j = 0; j < length; j++) {
+			    		if (cachedType.otherBounds[j] != otherBounds[j]) continue nextCachedType;
+			    	}
+			    }
+				// all match, reuse current
+				return cachedType;
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new WildcardBinding[10];
+		this.uniqueWildcardBindings.put(genericType, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length){
+		System.arraycopy(cachedInfo, 0, cachedInfo = new WildcardBinding[length*2], 0, length);
+		this.uniqueWildcardBindings.put(genericType, cachedInfo);
+	}
+	// add new binding
+	WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, otherBounds, boundKind, this);
+	cachedInfo[index] = wildcard;
+	return wildcard;
+}
+
+/**
+ * Returns the access restriction associated to a given type, or null if none
+ */
+public AccessRestriction getAccessRestriction(TypeBinding type) {
+	return (AccessRestriction) this.accessRestrictions.get(type);
+}
+
+/**
+ *  Answer the type for the compoundName if it exists in the cache.
+ * Answer theNotFoundType if it could not be resolved the first time
+ * it was looked up, otherwise answer null.
+ *
+ * NOTE: Do not use for nested types... the answer is NOT the same for a.b.C or a.b.C.D.E
+ * assuming C is a type in both cases. In the a.b.C.D.E case, null is the answer.
+ */
+public ReferenceBinding getCachedType(char[][] compoundName) {
+	if (compoundName.length == 1) {
+		return this.defaultPackage.getType0(compoundName[0]);
+	}
+	PackageBinding packageBinding = getPackage0(compoundName[0]);
+	if (packageBinding == null || packageBinding == TheNotFoundPackage)
+		return null;
+
+	for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++)
+		if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage)
+			return null;
+	return packageBinding.getType0(compoundName[compoundName.length - 1]);
+}
+
+public char[][] getNullableAnnotationName() {
+	return this.globalOptions.nullableAnnotationName;
+}
+
+public char[][] getNonNullAnnotationName() {
+	return this.globalOptions.nonNullAnnotationName;
+}
+
+public char[][] getNonNullByDefaultAnnotationName() {
+	return this.globalOptions.nonNullByDefaultAnnotationName;
+}
+
+/* Answer the top level package named name if it exists in the cache.
+* Answer theNotFoundPackage if it could not be resolved the first time
+* it was looked up, otherwise answer null.
+*
+* NOTE: Senders must convert theNotFoundPackage into a real problem
+* package if its to returned.
+*/
+PackageBinding getPackage0(char[] name) {
+	return this.knownPackages.get(name);
+}
+
+/* Answer the type corresponding to the compoundName.
+* Ask the name environment for the type if its not in the cache.
+* Fail with a classpath error if the type cannot be found.
+*/
+public ReferenceBinding getResolvedType(char[][] compoundName, Scope scope) {
+	ReferenceBinding type = getType(compoundName);
+	if (type != null) return type;
+
+	// create a proxy for the missing BinaryType
+	// report the missing class file first
+	this.problemReporter.isClassPathCorrect(
+		compoundName,
+		scope == null ? this.unitBeingCompleted : scope.referenceCompilationUnit(),
+		this.missingClassFileLocation);
+	return createMissingType(null, compoundName);
+}
+
+/* Answer the top level package named name.
+* Ask the oracle for the package if its not in the cache.
+* Answer null if the package cannot be found.
+*/
+PackageBinding getTopLevelPackage(char[] name) {
+	PackageBinding packageBinding = getPackage0(name);
+	if (packageBinding != null) {
+		if (packageBinding == TheNotFoundPackage)
+			return null;
+		return packageBinding;
+	}
+
+	if (this.nameEnvironment.isPackage(null, name)) {
+		this.knownPackages.put(name, packageBinding = new PackageBinding(name, this));
+		return packageBinding;
+	}
+
+	this.knownPackages.put(name, TheNotFoundPackage); // saves asking the oracle next time
+	return null;
+}
+
+/* Answer the type corresponding to the compoundName.
+* Ask the name environment for the type if its not in the cache.
+* Answer null if the type cannot be found.
+*/
+public ReferenceBinding getType(char[][] compoundName) {
+	ReferenceBinding referenceBinding;
+
+	if (compoundName.length == 1) {
+		if ((referenceBinding = this.defaultPackage.getType0(compoundName[0])) == null) {
+			PackageBinding packageBinding = getPackage0(compoundName[0]);
+			if (packageBinding != null && packageBinding != TheNotFoundPackage)
+				return null; // collides with a known package... should not call this method in such a case
+			referenceBinding = askForType(this.defaultPackage, compoundName[0]);
+		}
+	} else {
+		PackageBinding packageBinding = getPackage0(compoundName[0]);
+		if (packageBinding == TheNotFoundPackage)
+			return null;
+
+		if (packageBinding != null) {
+			for (int i = 1, packageLength = compoundName.length - 1; i < packageLength; i++) {
+				if ((packageBinding = packageBinding.getPackage0(compoundName[i])) == null)
+					break;
+				if (packageBinding == TheNotFoundPackage)
+					return null;
+			}
+		}
+
+		if (packageBinding == null)
+			referenceBinding = askForType(compoundName);
+		else if ((referenceBinding = packageBinding.getType0(compoundName[compoundName.length - 1])) == null)
+			referenceBinding = askForType(packageBinding, compoundName[compoundName.length - 1]);
+	}
+
+	if (referenceBinding == null || referenceBinding == TheNotFoundType)
+		return null;
+	referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this, false /* no raw conversion for now */);
+
+	// compoundName refers to a nested type incorrectly (for example, package1.A$B)
+	if (referenceBinding.isNestedType())
+		return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided);
+	return referenceBinding;
+}
+
+private TypeBinding[] getTypeArgumentsFromSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType, ReferenceBinding genericType, char[][][] missingTypeNames) {
+	java.util.ArrayList args = new java.util.ArrayList(2);
+	int rank = 0;
+	do {
+		args.add(getTypeFromVariantTypeSignature(wrapper, staticVariables, enclosingType, genericType, rank++, missingTypeNames));
+	} while (wrapper.signature[wrapper.start] != '>');
+	wrapper.start++; // skip '>'
+	TypeBinding[] typeArguments = new TypeBinding[args.size()];
+	args.toArray(typeArguments);
+	return typeArguments;
+}
+
+/* Answer the type corresponding to the compound name.
+* Does not ask the oracle for the type if its not found in the cache... instead an
+* unresolved type is returned which must be resolved before used.
+*
+* NOTE: Does NOT answer base types nor array types!
+*/
+private ReferenceBinding getTypeFromCompoundName(char[][] compoundName, boolean isParameterized, boolean wasMissingType) {
+	ReferenceBinding binding = getCachedType(compoundName);
+	if (binding == null) {
+		PackageBinding packageBinding = computePackageFrom(compoundName, false /* valid pkg */);
+		binding = new UnresolvedReferenceBinding(compoundName, packageBinding);
+		if (wasMissingType) {
+			binding.tagBits |= TagBits.HasMissingType; // record it was bound to a missing type
+		}
+		packageBinding.addType(binding);
+	} else if (binding == TheNotFoundType) {
+		// report the missing class file first
+		if (!wasMissingType) {
+			/* Since missing types have been already been complained against while producing binaries, there is no class path 
+			 * misconfiguration now that did not also exist in some equivalent form while producing the class files which encode 
+			 * these missing types. So no need to bark again. Note that wasMissingType == true signals a type referenced in a .class 
+			 * file which could not be found when the binary was produced. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 */
+			this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation);
+		}
+		// create a proxy for the missing BinaryType
+		binding = createMissingType(null, compoundName);
+	} else if (!isParameterized) {
+	    // check raw type, only for resolved types
+        binding = (ReferenceBinding) convertUnresolvedBinaryToRawType(binding);
+	}
+	return binding;
+}
+
+/* Answer the type corresponding to the name from the binary file.
+* Does not ask the oracle for the type if its not found in the cache... instead an
+* unresolved type is returned which must be resolved before used.
+*
+* NOTE: Does NOT answer base types nor array types!
+*/
+ReferenceBinding getTypeFromConstantPoolName(char[] signature, int start, int end, boolean isParameterized, char[][][] missingTypeNames) {
+	if (end == -1)
+		end = signature.length;
+	char[][] compoundName = CharOperation.splitOn('/', signature, start, end);
+	boolean wasMissingType = false;
+	if (missingTypeNames != null) {
+		for (int i = 0, max = missingTypeNames.length; i < max; i++) {
+			if (CharOperation.equals(compoundName, missingTypeNames[i])) {
+				wasMissingType = true;
+				break;
+			}
+		}
+	}
+	return getTypeFromCompoundName(compoundName, isParameterized, wasMissingType);
+}
+
+/* Answer the type corresponding to the signature from the binary file.
+* Does not ask the oracle for the type if its not found in the cache... instead an
+* unresolved type is returned which must be resolved before used.
+*
+* NOTE: Does answer base types & array types.
+*/
+TypeBinding getTypeFromSignature(char[] signature, int start, int end, boolean isParameterized, TypeBinding enclosingType, char[][][] missingTypeNames) {
+	int dimension = 0;
+	while (signature[start] == '[') {
+		start++;
+		dimension++;
+	}
+	if (end == -1)
+		end = signature.length - 1;
+
+	// Just switch on signature[start] - the L case is the else
+	TypeBinding binding = null;
+	if (start == end) {
+		switch (signature[start]) {
+			case 'I' :
+				binding = TypeBinding.INT;
+				break;
+			case 'Z' :
+				binding = TypeBinding.BOOLEAN;
+				break;
+			case 'V' :
+				binding = TypeBinding.VOID;
+				break;
+			case 'C' :
+				binding = TypeBinding.CHAR;
+				break;
+			case 'D' :
+				binding = TypeBinding.DOUBLE;
+				break;
+			case 'B' :
+				binding = TypeBinding.BYTE;
+				break;
+			case 'F' :
+				binding = TypeBinding.FLOAT;
+				break;
+			case 'J' :
+				binding = TypeBinding.LONG;
+				break;
+			case 'S' :
+				binding = TypeBinding.SHORT;
+				break;
+			default :
+				this.problemReporter.corruptedSignature(enclosingType, signature, start);
+				// will never reach here, since error will cause abort
+		}
+	} else {
+		binding = getTypeFromConstantPoolName(signature, start + 1, end, isParameterized, missingTypeNames); // skip leading 'L' or 'T'
+	}
+
+	if (dimension == 0)
+		return binding;
+	return createArrayType(binding, dimension);
+}
+
+public TypeBinding getTypeFromTypeSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType, char[][][] missingTypeNames) {
+	// TypeVariableSignature = 'T' Identifier ';'
+	// ArrayTypeSignature = '[' TypeSignature
+	// ClassTypeSignature = 'L' Identifier TypeArgs(optional) ';'
+	//   or ClassTypeSignature '.' 'L' Identifier TypeArgs(optional) ';'
+	// TypeArgs = '<' VariantTypeSignature VariantTypeSignatures '>'
+	int dimension = 0;
+	while (wrapper.signature[wrapper.start] == '[') {
+		wrapper.start++;
+		dimension++;
+	}
+	if (wrapper.signature[wrapper.start] == 'T') {
+	    int varStart = wrapper.start + 1;
+	    int varEnd = wrapper.computeEnd();
+		for (int i = staticVariables.length; --i >= 0;)
+			if (CharOperation.equals(staticVariables[i].sourceName, wrapper.signature, varStart, varEnd))
+				return dimension == 0 ? (TypeBinding) staticVariables[i] : createArrayType(staticVariables[i], dimension);
+	    ReferenceBinding initialType = enclosingType;
+		do {
+			TypeVariableBinding[] enclosingTypeVariables;
+			if (enclosingType instanceof BinaryTypeBinding) { // compiler normal case, no eager resolution of binary variables
+				enclosingTypeVariables = ((BinaryTypeBinding)enclosingType).typeVariables; // do not trigger resolution of variables
+			} else { // codepath only use by codeassist for decoding signatures
+				enclosingTypeVariables = enclosingType.typeVariables();
+			}
+			for (int i = enclosingTypeVariables.length; --i >= 0;)
+				if (CharOperation.equals(enclosingTypeVariables[i].sourceName, wrapper.signature, varStart, varEnd))
+					return dimension == 0 ? (TypeBinding) enclosingTypeVariables[i] : createArrayType(enclosingTypeVariables[i], dimension);
+		} while ((enclosingType = enclosingType.enclosingType()) != null);
+		this.problemReporter.undefinedTypeVariableSignature(CharOperation.subarray(wrapper.signature, varStart, varEnd), initialType);
+		return null; // cannot reach this, since previous problem will abort compilation
+	}
+	boolean isParameterized;
+	TypeBinding type = getTypeFromSignature(wrapper.signature, wrapper.start, wrapper.computeEnd(), isParameterized = (wrapper.end == wrapper.bracket), enclosingType, missingTypeNames);
+	if (!isParameterized)
+		return dimension == 0 ? type : createArrayType(type, dimension);
+
+	// type must be a ReferenceBinding at this point, cannot be a BaseTypeBinding or ArrayTypeBinding
+	ReferenceBinding actualType = (ReferenceBinding) type;
+	if (actualType instanceof UnresolvedReferenceBinding)
+		if (CharOperation.indexOf('$', actualType.compoundName[actualType.compoundName.length - 1]) > 0)
+			actualType = (ReferenceBinding) BinaryTypeBinding.resolveType(actualType, this, false /* no raw conversion */); // must resolve member types before asking for enclosingType
+	ReferenceBinding actualEnclosing = actualType.enclosingType();
+	if (actualEnclosing != null) { // convert needed if read some static member type
+		actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing, false /*do not force conversion of enclosing types*/);
+	}
+	TypeBinding[] typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, actualType, missingTypeNames);
+	ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, actualEnclosing);
+
+	while (wrapper.signature[wrapper.start] == '.') {
+		wrapper.start++; // skip '.'
+		int memberStart = wrapper.start;
+		char[] memberName = wrapper.nextWord();
+		BinaryTypeBinding.resolveType(parameterizedType, this, false);
+		ReferenceBinding memberType = parameterizedType.genericType().getMemberType(memberName);
+		// need to protect against the member type being null when the signature is invalid
+		if (memberType == null)
+			this.problemReporter.corruptedSignature(parameterizedType, wrapper.signature, memberStart); // aborts
+		if (wrapper.signature[wrapper.start] == '<') {
+			wrapper.start++; // skip '<'
+			typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, memberType, missingTypeNames);
+		} else {
+			typeArguments = null;
+		}
+		parameterizedType = createParameterizedType(memberType, typeArguments, parameterizedType);
+	}
+	wrapper.start++; // skip ';'
+	return dimension == 0 ? (TypeBinding) parameterizedType : createArrayType(parameterizedType, dimension);
+}
+
+TypeBinding getTypeFromVariantTypeSignature(
+		SignatureWrapper wrapper,
+		TypeVariableBinding[] staticVariables,
+		ReferenceBinding enclosingType,
+		ReferenceBinding genericType,
+		int rank,
+		char[][][] missingTypeNames) {
+	// VariantTypeSignature = '-' TypeSignature
+	//   or '+' TypeSignature
+	//   or TypeSignature
+	//   or '*'
+	switch (wrapper.signature[wrapper.start]) {
+		case '-' :
+			// ? super aType
+			wrapper.start++;
+			TypeBinding bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames);
+			return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.SUPER);
+		case '+' :
+			// ? extends aType
+			wrapper.start++;
+			bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames);
+			return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.EXTENDS);
+		case '*' :
+			// ?
+			wrapper.start++;
+			return createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+		default :
+			return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType, missingTypeNames);
+	}
+}
+
+boolean isMissingType(char[] typeName) {
+	for (int i = this.missingTypes == null ? 0 : this.missingTypes.size(); --i >= 0;) {
+		MissingTypeBinding missingType = (MissingTypeBinding) this.missingTypes.get(i);
+		if (CharOperation.equals(missingType.sourceName, typeName))
+			return true;
+	}
+	return false;
+}
+
+/* Ask the oracle if a package exists named name in the package named compoundName.
+*/
+boolean isPackage(char[][] compoundName, char[] name) {
+	if (compoundName == null || compoundName.length == 0)
+		return this.nameEnvironment.isPackage(null, name);
+	return this.nameEnvironment.isPackage(compoundName, name);
+}
+// The method verifier is lazily initialized to guarantee the receiver, the compiler & the oracle are ready.
+public MethodVerifier methodVerifier() {
+	if (this.verifier == null)
+		this.verifier = newMethodVerifier();
+	return this.verifier;
+}
+
+public MethodVerifier newMethodVerifier() {
+	/* Always use MethodVerifier15. Even in a 1.4 project, we must internalize type variables and
+	   observe any parameterization of super class and/or super interfaces in order to be able to
+	   detect overriding in the presence of generics.
+	   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850
+	 */
+	return new MethodVerifier15(this);
+}
+
+public void releaseClassFiles(org.eclipse.jdt.internal.compiler.ClassFile[] classFiles) {
+	for (int i = 0, fileCount = classFiles.length; i < fileCount; i++)
+		this.classFilePool.release(classFiles[i]);
+}
+
+public void reset() {
+	this.defaultPackage = new PackageBinding(this); // assume the default package always exists
+	this.defaultImports = null;
+	this.knownPackages = new HashtableOfPackage();
+	this.accessRestrictions = new HashMap(3);
+
+	this.verifier = null;
+	for (int i = this.uniqueArrayBindings.length; --i >= 0;) {
+		ArrayBinding[] arrayBindings = this.uniqueArrayBindings[i];
+		if (arrayBindings != null)
+			for (int j = arrayBindings.length; --j >= 0;)
+				arrayBindings[j] = null;
+	}
+	// NOTE: remember to fix #updateCaches(...) when adding unique binding caches
+	this.uniqueParameterizedTypeBindings = new SimpleLookupTable(3);
+	this.uniqueRawTypeBindings = new SimpleLookupTable(3);
+	this.uniqueWildcardBindings = new SimpleLookupTable(3);
+	this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
+	this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3);
+	this.uniqueGetClassMethodBinding = null;
+	this.missingTypes = null;
+	this.typesBeingConnected = new HashSet();
+
+	for (int i = this.units.length; --i >= 0;)
+		this.units[i] = null;
+	this.lastUnitIndex = -1;
+	this.lastCompletedUnitIndex = -1;
+	this.unitBeingCompleted = null; // in case AbortException occurred
+
+	this.classFilePool.reset();
+
+	// name environment has a longer life cycle, and must be reset in
+	// the code which created it.
+}
+
+/**
+ * Associate a given type with some access restriction
+ * (did not store the restriction directly into binding, since sparse information)
+ */
+public void setAccessRestriction(ReferenceBinding type, AccessRestriction accessRestriction) {
+	if (accessRestriction == null) return;
+	type.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+	this.accessRestrictions.put(type, accessRestriction);
+}
+
+void updateCaches(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType) {
+	// walk all the unique collections & replace the unresolvedType with the resolvedType
+	// must prevent 2 entries so == still works (1 containing the unresolvedType and the other containing the resolvedType)
+	if (this.uniqueParameterizedTypeBindings.get(unresolvedType) != null) { // update the key
+		Object[] keys = this.uniqueParameterizedTypeBindings.keyTable;
+		for (int i = 0, l = keys.length; i < l; i++) {
+			if (keys[i] == unresolvedType) {
+				keys[i] = resolvedType; // hashCode is based on compoundName so this works - cannot be raw since type of parameterized type
+				break;
+			}
+		}
+	}
+	if (this.uniqueRawTypeBindings.get(unresolvedType) != null) { // update the key
+		Object[] keys = this.uniqueRawTypeBindings.keyTable;
+		for (int i = 0, l = keys.length; i < l; i++) {
+			if (keys[i] == unresolvedType) {
+				keys[i] = resolvedType; // hashCode is based on compoundName so this works
+				break;
+			}
+		}
+	}
+	if (this.uniqueWildcardBindings.get(unresolvedType) != null) { // update the key
+		Object[] keys = this.uniqueWildcardBindings.keyTable;
+		for (int i = 0, l = keys.length; i < l; i++) {
+			if (keys[i] == unresolvedType) {
+				keys[i] = resolvedType; // hashCode is based on compoundName so this works
+				break;
+			}
+		}
+	}
+}
+
+public IQualifiedTypeResolutionListener[] resolutionListeners = new IQualifiedTypeResolutionListener[0];
+
+public void addResolutionListener(IQualifiedTypeResolutionListener resolutionListener) {
+	int length = this.resolutionListeners.length;
+	for (int i = 0; i < length; i++){
+		if (this.resolutionListeners[i].equals(resolutionListener))
+			return;
+	}
+	System.arraycopy(this.resolutionListeners, 0,
+			this.resolutionListeners = new IQualifiedTypeResolutionListener[length + 1], 0, length);
+	this.resolutionListeners[length] = resolutionListener;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
new file mode 100644
index 0000000..080cc5b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public final class MemberTypeBinding extends NestedTypeBinding {
+public MemberTypeBinding(char[][] compoundName, ClassScope scope, SourceTypeBinding enclosingType) {
+	super(compoundName, scope, enclosingType);
+	this.tagBits |= TagBits.MemberTypeMask;
+}
+void checkSyntheticArgsAndFields() {
+	if (isStatic()) return;
+	if (isInterface()) return;
+	this.addSyntheticArgumentAndField(this.enclosingType);
+}
+/* Answer the receiver's constant pool name.
+*
+* NOTE: This method should only be used during/after code gen.
+*/
+
+public char[] constantPoolName() /* java/lang/Object */ {
+	if (this.constantPoolName != null)
+		return this.constantPoolName;
+
+	return this.constantPoolName = CharOperation.concat(enclosingType().constantPoolName(), this.sourceName, '$');
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
+ */
+public void initializeDeprecatedAnnotationTagBits() {
+	if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
+		super.initializeDeprecatedAnnotationTagBits();
+		if ((this.tagBits & TagBits.AnnotationDeprecated) == 0) {
+			// check enclosing type
+			ReferenceBinding enclosing;
+			if (((enclosing = enclosingType()).tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
+				enclosing.initializeDeprecatedAnnotationTagBits();
+			}
+			if (enclosing.isViewedAsDeprecated()) {
+				this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+			}
+		}
+	}
+}
+public String toString() {
+	return "Member type : " + new String(sourceName()) + " " + super.toString(); //$NON-NLS-2$ //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
new file mode 100644
index 0000000..025b078
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -0,0 +1,1220 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 367203 - [compiler][null] detect assigning null to nonnull argument
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class MethodBinding extends Binding {
+
+	public int modifiers;
+	public char[] selector;
+	public TypeBinding returnType;
+	public TypeBinding[] parameters;
+	public TypeBinding receiver;  // JSR308 - explicit this parameter
+	public ReferenceBinding[] thrownExceptions;
+	public ReferenceBinding declaringClass;
+	public TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
+	char[] signature;
+	public long tagBits;
+
+	/** Store nullness information from annotation (incl. applicable default). */
+	public Boolean[] parameterNonNullness;  // TRUE means @NonNull declared, FALSE means @Nullable declared, null means nothing declared
+
+protected MethodBinding() {
+	// for creating problem or synthetic method
+}
+public MethodBinding(int modifiers, char[] selector, TypeBinding returnType, TypeBinding[] parameters, ReferenceBinding[] thrownExceptions, ReferenceBinding declaringClass) {
+	this.modifiers = modifiers;
+	this.selector = selector;
+	this.returnType = returnType;
+	this.parameters = (parameters == null || parameters.length == 0) ? Binding.NO_PARAMETERS : parameters;
+	this.thrownExceptions = (thrownExceptions == null || thrownExceptions.length == 0) ? Binding.NO_EXCEPTIONS : thrownExceptions;
+	this.declaringClass = declaringClass;
+
+	// propagate the strictfp & deprecated modifiers
+	if (this.declaringClass != null) {
+		if (this.declaringClass.isStrictfp())
+			if (!(isNative() || isAbstract()))
+				this.modifiers |= ClassFileConstants.AccStrictfp;
+	}
+}
+public MethodBinding(int modifiers, TypeBinding[] parameters, ReferenceBinding[] thrownExceptions, ReferenceBinding declaringClass) {
+	this(modifiers, TypeConstants.INIT, TypeBinding.VOID, parameters, thrownExceptions, declaringClass);
+}
+// special API used to change method declaring class for runtime visibility check
+public MethodBinding(MethodBinding initialMethodBinding, ReferenceBinding declaringClass) {
+	this.modifiers = initialMethodBinding.modifiers;
+	this.selector = initialMethodBinding.selector;
+	this.returnType = initialMethodBinding.returnType;
+	this.parameters = initialMethodBinding.parameters;
+	this.thrownExceptions = initialMethodBinding.thrownExceptions;
+	this.declaringClass = declaringClass;
+	declaringClass.storeAnnotationHolder(this, initialMethodBinding.declaringClass.retrieveAnnotationHolder(initialMethodBinding, true));
+}
+/* Answer true if the argument types & the receiver's parameters have the same erasure
+*/
+public final boolean areParameterErasuresEqual(MethodBinding method) {
+	TypeBinding[] args = method.parameters;
+	if (this.parameters == args)
+		return true;
+
+	int length = this.parameters.length;
+	if (length != args.length)
+		return false;
+
+	for (int i = 0; i < length; i++)
+		if (this.parameters[i] != args[i] && this.parameters[i].erasure() != args[i].erasure())
+			return false;
+	return true;
+}
+/*
+ * Returns true if given parameters are compatible with this method parameters.
+ * Callers to this method should first check that the number of TypeBindings
+ * passed as argument matches this MethodBinding number of parameters
+ */
+public final boolean areParametersCompatibleWith(TypeBinding[] arguments) {
+	int paramLength = this.parameters.length;
+	int argLength = arguments.length;
+	int lastIndex = argLength;
+	if (isVarargs()) {
+		lastIndex = paramLength - 1;
+		if (paramLength == argLength) { // accept X[] but not X or X[][]
+			TypeBinding varArgType = this.parameters[lastIndex]; // is an ArrayBinding by definition
+			TypeBinding lastArgument = arguments[lastIndex];
+			if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
+				return false;
+		} else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
+			TypeBinding varArgType = ((ArrayBinding) this.parameters[lastIndex]).elementsType();
+			for (int i = lastIndex; i < argLength; i++)
+				if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
+					return false;
+		} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
+			return false;
+		}
+		// now compare standard arguments from 0 to lastIndex
+	}
+	for (int i = 0; i < lastIndex; i++)
+		if (this.parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(this.parameters[i]))
+			return false;
+	return true;
+}
+/* Answer true if the argument types & the receiver's parameters are equal
+*/
+public final boolean areParametersEqual(MethodBinding method) {
+	TypeBinding[] args = method.parameters;
+	if (this.parameters == args)
+		return true;
+
+	int length = this.parameters.length;
+	if (length != args.length)
+		return false;
+
+	for (int i = 0; i < length; i++)
+		if (this.parameters[i] != args[i])
+			return false;
+	return true;
+}
+
+/* API
+* Answer the receiver's binding type from Binding.BindingID.
+*/
+
+/* Answer true if the type variables have the same erasure
+*/
+public final boolean areTypeVariableErasuresEqual(MethodBinding method) {
+	TypeVariableBinding[] vars = method.typeVariables;
+	if (this.typeVariables == vars)
+		return true;
+
+	int length = this.typeVariables.length;
+	if (length != vars.length)
+		return false;
+
+	for (int i = 0; i < length; i++)
+		if (this.typeVariables[i] != vars[i] && this.typeVariables[i].erasure() != vars[i].erasure())
+			return false;
+	return true;
+}
+MethodBinding asRawMethod(LookupEnvironment env) {
+	if (this.typeVariables == Binding.NO_TYPE_VARIABLES) return this;
+
+	// substitute type arguments with raw types
+	int length = this.typeVariables.length;
+	TypeBinding[] arguments = new TypeBinding[length];
+	for (int i = 0; i < length; i++) {
+		TypeVariableBinding var = this.typeVariables[i];
+		if (var.boundsCount() <= 1) {
+			arguments[i] = env.convertToRawType(var.upperBound(), false /*do not force conversion of enclosing types*/);
+		} else {
+			// use an intersection type to retain full bound information if more than 1 bound
+			TypeBinding[] itsSuperinterfaces = var.superInterfaces();
+			int superLength = itsSuperinterfaces.length;
+			TypeBinding rawFirstBound = null;
+			TypeBinding[] rawOtherBounds = null;
+			if (var.boundsCount() == superLength) {
+				rawFirstBound = env.convertToRawType(itsSuperinterfaces[0], false);
+				rawOtherBounds = new TypeBinding[superLength - 1];
+				for (int s = 1; s < superLength; s++)
+					rawOtherBounds[s - 1] = env.convertToRawType(itsSuperinterfaces[s], false);
+			} else {
+				rawFirstBound = env.convertToRawType(var.superclass(), false);
+				rawOtherBounds = new TypeBinding[superLength];
+				for (int s = 0; s < superLength; s++)
+					rawOtherBounds[s] = env.convertToRawType(itsSuperinterfaces[s], false);
+			}
+			arguments[i] = env.createWildcard(null, 0, rawFirstBound, rawOtherBounds, org.eclipse.jdt.internal.compiler.ast.Wildcard.EXTENDS);
+		}
+	}
+	return env.createParameterizedGenericMethod(this, arguments);
+}
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: This method should ONLY be sent if the receiver is a constructor.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+
+public final boolean canBeSeenBy(InvocationSite invocationSite, Scope scope) {
+	if (isPublic()) return true;
+
+	SourceTypeBinding invocationType = scope.enclosingSourceType();
+	if (invocationType == this.declaringClass) return true;
+
+	if (isProtected()) {
+		// answer true if the receiver is in the same package as the invocationType
+		if (invocationType.fPackage == this.declaringClass.fPackage) return true;
+		return invocationSite.isSuperAccess();
+	}
+
+	if (isPrivate()) {
+		// answer true if the invocationType and the declaringClass have a common enclosingType
+		// already know they are not the identical type
+		ReferenceBinding outerInvocationType = invocationType;
+		ReferenceBinding temp = outerInvocationType.enclosingType();
+		while (temp != null) {
+			outerInvocationType = temp;
+			temp = temp.enclosingType();
+		}
+
+		ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.declaringClass.erasure();
+		temp = outerDeclaringClass.enclosingType();
+		while (temp != null) {
+			outerDeclaringClass = temp;
+			temp = temp.enclosingType();
+		}
+		return outerInvocationType == outerDeclaringClass;
+	}
+
+	// isDefault()
+	return invocationType.fPackage == this.declaringClass.fPackage;
+}
+public final boolean canBeSeenBy(PackageBinding invocationPackage) {
+	if (isPublic()) return true;
+	if (isPrivate()) return false;
+
+	// isProtected() or isDefault()
+	return invocationPackage == this.declaringClass.getPackage();
+}
+
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+public final boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+
+	SourceTypeBinding invocationType = scope.enclosingSourceType();
+	if (this.declaringClass.isInterface() && isStatic()) {
+		// Static interface methods can be explicitly invoked only through the type reference of the declaring interface or implicitly in the interface itself.
+		if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8)
+			return false;
+		if (invocationSite.isTypeAccess() && receiverType == this.declaringClass)
+			return true;
+		if (invocationSite.receiverIsImplicitThis() && invocationType == this.declaringClass)
+			return true;
+		return false;
+	}
+	
+	if (isPublic()) return true;
+	
+
+	if (invocationType == this.declaringClass && invocationType == receiverType) return true;
+
+	if (invocationType == null) // static import call
+		return !isPrivate() && scope.getCurrentPackage() == this.declaringClass.fPackage;
+
+	if (isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the receiverType is the invocationType or its subclass
+		//    OR the method is a static method accessed directly through a type
+		//    OR previous assertions are true for one of the enclosing type
+		if (invocationType == this.declaringClass) return true;
+		if (invocationType.fPackage == this.declaringClass.fPackage) return true;
+
+		ReferenceBinding currentType = invocationType;
+		TypeBinding receiverErasure = receiverType.erasure();
+		ReferenceBinding declaringErasure = (ReferenceBinding) this.declaringClass.erasure();
+		int depth = 0;
+		do {
+			if (currentType.findSuperTypeOriginatingFrom(declaringErasure) != null) {
+				if (invocationSite.isSuperAccess())
+					return true;
+				// receiverType can be an array binding in one case... see if you can change it
+				if (receiverType instanceof ArrayBinding)
+					return false;
+				if (isStatic()) {
+					if (depth > 0) invocationSite.setDepth(depth);
+					return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
+				}
+				if (currentType == receiverErasure || receiverErasure.findSuperTypeOriginatingFrom(currentType) != null) {
+					if (depth > 0) invocationSite.setDepth(depth);
+					return true;
+				}
+			}
+			depth++;
+			currentType = currentType.enclosingType();
+		} while (currentType != null);
+		return false;
+	}
+
+	if (isPrivate()) {
+		// answer true if the receiverType is the declaringClass
+		// AND the invocationType and the declaringClass have a common enclosingType
+		receiverCheck: {
+			if (receiverType != this.declaringClass) {
+				// special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622
+				if (scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_6 && receiverType.isTypeVariable() && ((TypeVariableBinding) receiverType).isErasureBoundTo(this.declaringClass.erasure()))
+					break receiverCheck;
+				return false;
+			}
+		}
+
+		if (invocationType != this.declaringClass) {
+			ReferenceBinding outerInvocationType = invocationType;
+			ReferenceBinding temp = outerInvocationType.enclosingType();
+			while (temp != null) {
+				outerInvocationType = temp;
+				temp = temp.enclosingType();
+			}
+
+			ReferenceBinding outerDeclaringClass = (ReferenceBinding)this.declaringClass.erasure();
+			temp = outerDeclaringClass.enclosingType();
+			while (temp != null) {
+				outerDeclaringClass = temp;
+				temp = temp.enclosingType();
+			}
+			if (outerInvocationType != outerDeclaringClass) return false;
+		}
+		return true;
+	}
+
+	// isDefault()
+	PackageBinding declaringPackage = this.declaringClass.fPackage;
+	if (invocationType.fPackage != declaringPackage) return false;
+
+	// receiverType can be an array binding in one case... see if you can change it
+	if (receiverType instanceof ArrayBinding)
+		return false;
+	TypeBinding originalDeclaringClass = this.declaringClass.original();
+	ReferenceBinding currentType = (ReferenceBinding) (receiverType);
+	do {
+		if (currentType.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
+			if (originalDeclaringClass == currentType.erasure().original()) return true;
+		} else {
+			if (originalDeclaringClass == currentType.original()) return true;
+		}
+		PackageBinding currentPackage = currentType.fPackage;
+		// package could be null for wildcards/intersection types, ignore and recurse in superclass
+		if (currentPackage != null && currentPackage != declaringPackage) return false;
+	} while ((currentType = currentType.superclass()) != null);
+	return false;
+}
+
+public List collectMissingTypes(List missingTypes) {
+	if ((this.tagBits & TagBits.HasMissingType) != 0) {
+		missingTypes = this.returnType.collectMissingTypes(missingTypes);
+		for (int i = 0, max = this.parameters.length; i < max; i++) {
+			missingTypes = this.parameters[i].collectMissingTypes(missingTypes);
+		}
+		for (int i = 0, max = this.thrownExceptions.length; i < max; i++) {
+			missingTypes = this.thrownExceptions[i].collectMissingTypes(missingTypes);
+		}
+		for (int i = 0, max = this.typeVariables.length; i < max; i++) {
+			TypeVariableBinding variable = this.typeVariables[i];
+			missingTypes = variable.superclass().collectMissingTypes(missingTypes);
+			ReferenceBinding[] interfaces = variable.superInterfaces();
+			for (int j = 0, length = interfaces.length; j < length; j++) {
+				missingTypes = interfaces[j].collectMissingTypes(missingTypes);
+			}
+		}
+	}
+	return missingTypes;
+}
+
+MethodBinding computeSubstitutedMethod(MethodBinding method, LookupEnvironment env) {
+	int length = this.typeVariables.length;
+	TypeVariableBinding[] vars = method.typeVariables;
+	if (length != vars.length)
+		return null;
+
+	// must substitute to detect cases like:
+	//   <T1 extends X<T1>> void dup() {}
+	//   <T2 extends X<T2>> Object dup() {return null;}
+	ParameterizedGenericMethodBinding substitute =
+		env.createParameterizedGenericMethod(method, this.typeVariables);
+	for (int i = 0; i < length; i++)
+		if (!this.typeVariables[i].isInterchangeableWith(vars[i], substitute))
+			return null;
+	return substitute;
+}
+
+/*
+ * declaringUniqueKey dot selector genericSignature
+ * p.X { <T> void bar(X<T> t) } --> Lp/X;.bar<T:Ljava/lang/Object;>(LX<TT;>;)V
+ */
+public char[] computeUniqueKey(boolean isLeaf) {
+	// declaring class
+	char[] declaringKey = this.declaringClass.computeUniqueKey(false/*not a leaf*/);
+	int declaringLength = declaringKey.length;
+
+	// selector
+	int selectorLength = this.selector == TypeConstants.INIT ? 0 : this.selector.length;
+
+	// generic signature
+	char[] sig = genericSignature();
+	boolean isGeneric = sig != null;
+	if (!isGeneric) sig = signature();
+	int signatureLength = sig.length;
+
+	// thrown exceptions
+	int thrownExceptionsLength = this.thrownExceptions.length;
+	int thrownExceptionsSignatureLength = 0;
+	char[][] thrownExceptionsSignatures = null;
+	boolean addThrownExceptions = thrownExceptionsLength > 0 && (!isGeneric || CharOperation.lastIndexOf('^', sig) < 0);
+	if (addThrownExceptions) {
+		thrownExceptionsSignatures = new char[thrownExceptionsLength][];
+		for (int i = 0; i < thrownExceptionsLength; i++) {
+			if (this.thrownExceptions[i] != null) {
+				thrownExceptionsSignatures[i] = this.thrownExceptions[i].signature();
+				thrownExceptionsSignatureLength += thrownExceptionsSignatures[i].length + 1;	// add one char for separator
+			}
+		}
+	}
+
+	char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength + thrownExceptionsSignatureLength];
+	int index = 0;
+	System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+	index = declaringLength;
+	uniqueKey[index++] = '.';
+	System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
+	index += selectorLength;
+	System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
+	if (thrownExceptionsSignatureLength > 0) {
+		index += signatureLength;
+		for (int i = 0; i < thrownExceptionsLength; i++) {
+			char[] thrownExceptionSignature = thrownExceptionsSignatures[i];
+			if (thrownExceptionSignature != null) {
+				uniqueKey[index++] = '|';
+				int length = thrownExceptionSignature.length;
+				System.arraycopy(thrownExceptionSignature, 0, uniqueKey, index, length);
+				index += length;
+			}
+		}
+	}
+	return uniqueKey;
+}
+
+/* Answer the receiver's constant pool name.
+*
+* <init> for constructors
+* <clinit> for clinit methods
+* or the source name of the method
+*/
+public final char[] constantPoolName() {
+	return this.selector;
+}
+
+/**
+ * After method verifier has finished, fill in missing @NonNull specification from the applicable default.
+ */
+protected void fillInDefaultNonNullness(AbstractMethodDeclaration sourceMethod) {
+	if (this.parameterNonNullness == null)
+		this.parameterNonNullness = new Boolean[this.parameters.length];
+	boolean added = false;
+	int length = this.parameterNonNullness.length;
+	for (int i = 0; i < length; i++) {
+		if (this.parameters[i].isBaseType())
+			continue;
+		if (this.parameterNonNullness[i] == null) {
+			added = true;
+			this.parameterNonNullness[i] = Boolean.TRUE;
+			if (sourceMethod != null) {
+				sourceMethod.arguments[i].binding.tagBits |= TagBits.AnnotationNonNull;
+			}
+		} else if (sourceMethod != null && this.parameterNonNullness[i].booleanValue()) {
+			sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, i);
+		}
+	}
+	if (added)
+		this.tagBits |= TagBits.HasParameterAnnotations;
+	if (   this.returnType != null
+		&& !this.returnType.isBaseType()
+		&& (this.tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable)) == 0)
+	{
+		this.tagBits |= TagBits.AnnotationNonNull;
+	} else if (sourceMethod != null && (this.tagBits & TagBits.AnnotationNonNull) != 0) {
+		sourceMethod.scope.problemReporter().nullAnnotationIsRedundant(sourceMethod, -1/*signifies method return*/);
+	}
+}
+
+public MethodBinding findOriginalInheritedMethod(MethodBinding inheritedMethod) {
+	MethodBinding inheritedOriginal = inheritedMethod.original();
+	TypeBinding superType = this.declaringClass.findSuperTypeOriginatingFrom(inheritedOriginal.declaringClass);
+	if (superType == null || !(superType instanceof ReferenceBinding)) return null;
+
+	if (inheritedOriginal.declaringClass != superType) {
+		// must find inherited method with the same substituted variables
+		MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(inheritedOriginal.selector, inheritedOriginal.parameters.length);
+		for (int m = 0, l = superMethods.length; m < l; m++)
+			if (superMethods[m].original() == inheritedOriginal)
+				return superMethods[m];
+	}
+	return inheritedOriginal;
+}
+
+/**
+ * <pre>
+ *<typeParam1 ... typeParamM>(param1 ... paramN)returnType thrownException1 ... thrownExceptionP
+ * T foo(T t) throws X<T>   --->   (TT;)TT;LX<TT;>;
+ * void bar(X<T> t)   -->   (LX<TT;>;)V
+ * <T> void bar(X<T> t)   -->  <T:Ljava.lang.Object;>(LX<TT;>;)V
+ * </pre>
+ */
+public char[] genericSignature() {
+	if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) return null;
+	StringBuffer sig = new StringBuffer(10);
+	if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
+		sig.append('<');
+		for (int i = 0, length = this.typeVariables.length; i < length; i++) {
+			sig.append(this.typeVariables[i].genericSignature());
+		}
+		sig.append('>');
+	}
+	sig.append('(');
+	for (int i = 0, length = this.parameters.length; i < length; i++) {
+		sig.append(this.parameters[i].genericTypeSignature());
+	}
+	sig.append(')');
+	if (this.returnType != null)
+		sig.append(this.returnType.genericTypeSignature());
+
+	// only append thrown exceptions if any is generic/parameterized
+	boolean needExceptionSignatures = false;
+	int length = this.thrownExceptions.length;
+	for (int i = 0; i < length; i++) {
+		if((this.thrownExceptions[i].modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
+			needExceptionSignatures = true;
+			break;
+		}
+	}
+	if (needExceptionSignatures) {
+		for (int i = 0; i < length; i++) {
+			sig.append('^');
+			sig.append(this.thrownExceptions[i].genericTypeSignature());
+		}
+	}
+	int sigLength = sig.length();
+	char[] genericSignature = new char[sigLength];
+	sig.getChars(0, sigLength, genericSignature, 0);
+	return genericSignature;
+}
+
+public final int getAccessFlags() {
+	return this.modifiers & ExtraCompilerModifiers.AccJustFlag;
+}
+
+public AnnotationBinding[] getAnnotations() {
+	MethodBinding originalMethod = original();
+	return originalMethod.declaringClass.retrieveAnnotations(originalMethod);
+}
+
+/**
+ * Compute the tagbits for standard annotations. For source types, these could require
+ * lazily resolving corresponding annotation nodes, in case of forward references.
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
+ */
+public long getAnnotationTagBits() {
+	MethodBinding originalMethod = original();
+	if ((originalMethod.tagBits & TagBits.AnnotationResolved) == 0 && originalMethod.declaringClass instanceof SourceTypeBinding) {
+		ClassScope scope = ((SourceTypeBinding) originalMethod.declaringClass).scope;
+		if (scope != null) {
+			TypeDeclaration typeDecl = scope.referenceContext;
+			AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod);
+			if (methodDecl != null)
+				ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod);
+			long nullDefaultBits = this.tagBits & (TagBits.AnnotationNonNullByDefault|TagBits.AnnotationNullUnspecifiedByDefault);
+			if (nullDefaultBits != 0 && this.declaringClass instanceof SourceTypeBinding) {
+				SourceTypeBinding declaringSourceType = (SourceTypeBinding) this.declaringClass;
+				if (declaringSourceType.checkRedundantNullnessDefaultOne(methodDecl, methodDecl.annotations, nullDefaultBits)) {
+					declaringSourceType.checkRedundantNullnessDefaultRecurse(methodDecl, methodDecl.annotations, nullDefaultBits);
+				}
+			}
+		}
+	}
+	return originalMethod.tagBits;
+}
+
+/**
+ * @return the default value for this annotation method or <code>null</code> if there is no default value
+ */
+public Object getDefaultValue() {
+	MethodBinding originalMethod = original();
+	if ((originalMethod.tagBits & TagBits.DefaultValueResolved) == 0) {
+		//The method has not been resolved nor has its class been resolved.
+		//It can only be from a source type within compilation units to process.
+		if (originalMethod.declaringClass instanceof SourceTypeBinding) {
+			SourceTypeBinding sourceType = (SourceTypeBinding) originalMethod.declaringClass;
+			if (sourceType.scope != null) {
+				AbstractMethodDeclaration methodDeclaration = originalMethod.sourceMethod();
+				if (methodDeclaration != null && methodDeclaration.isAnnotationMethod()) {
+					methodDeclaration.resolve(sourceType.scope);
+				}
+			}
+		}
+		originalMethod.tagBits |= TagBits.DefaultValueResolved;
+	}
+	AnnotationHolder holder = originalMethod.declaringClass.retrieveAnnotationHolder(originalMethod, true);
+	return holder == null ? null : holder.getDefaultValue();
+}
+
+/**
+ * @return the annotations for each of the method parameters or <code>null></code>
+ * 	if there's no parameter or no annotation at all.
+ */
+public AnnotationBinding[][] getParameterAnnotations() {
+	int length;
+	if ((length = this.parameters.length) == 0) {
+		return null;
+	}
+	MethodBinding originalMethod = original();
+	AnnotationHolder holder = originalMethod.declaringClass.retrieveAnnotationHolder(originalMethod, true);
+	AnnotationBinding[][] allParameterAnnotations = holder == null ? null : holder.getParameterAnnotations();
+	if (allParameterAnnotations == null && (this.tagBits & TagBits.HasParameterAnnotations) != 0) {
+		allParameterAnnotations = new AnnotationBinding[length][];
+		// forward reference to method, where param annotations have not yet been associated to method
+		if (this.declaringClass instanceof SourceTypeBinding) {
+			SourceTypeBinding sourceType = (SourceTypeBinding) this.declaringClass;
+			if (sourceType.scope != null) {
+				AbstractMethodDeclaration methodDecl = sourceType.scope.referenceType().declarationOf(this);
+				for (int i = 0; i < length; i++) {
+					Argument argument = methodDecl.arguments[i];
+					if (argument.annotations != null) {
+						ASTNode.resolveAnnotations(methodDecl.scope, argument.annotations, argument.binding);
+						allParameterAnnotations[i] = argument.binding.getAnnotations();
+					} else {
+						allParameterAnnotations[i] = Binding.NO_ANNOTATIONS;
+					}
+				}
+			} else {
+				for (int i = 0; i < length; i++) {
+					allParameterAnnotations[i] = Binding.NO_ANNOTATIONS;
+				}
+			}
+		} else {
+			for (int i = 0; i < length; i++) {
+				allParameterAnnotations[i] = Binding.NO_ANNOTATIONS;
+			}
+		}
+		setParameterAnnotations(allParameterAnnotations);
+	}
+	return allParameterAnnotations;
+}
+
+public TypeVariableBinding getTypeVariable(char[] variableName) {
+	for (int i = this.typeVariables.length; --i >= 0;)
+		if (CharOperation.equals(this.typeVariables[i].sourceName, variableName))
+			return this.typeVariables[i];
+	return null;
+}
+
+/**
+ * Returns true if method got substituted parameter types
+ * (see ParameterizedMethodBinding)
+ */
+public boolean hasSubstitutedParameters() {
+	return false;
+}
+
+/* Answer true if the return type got substituted.
+ */
+public boolean hasSubstitutedReturnType() {
+	return false;
+}
+
+/* Answer true if the receiver is an abstract method
+*/
+public final boolean isAbstract() {
+	return (this.modifiers & ClassFileConstants.AccAbstract) != 0;
+}
+
+/* Answer true if the receiver is a bridge method
+*/
+public final boolean isBridge() {
+	return (this.modifiers & ClassFileConstants.AccBridge) != 0;
+}
+
+/* Answer true if the receiver is a constructor
+*/
+public final boolean isConstructor() {
+	return this.selector == TypeConstants.INIT;
+}
+
+/* Answer true if the receiver has default visibility
+*/
+public final boolean isDefault() {
+	return !isPublic() && !isProtected() && !isPrivate();
+}
+
+/* Answer true if the receiver is a system generated default abstract method
+*/
+public final boolean isDefaultAbstract() {
+	return (this.modifiers & ExtraCompilerModifiers.AccDefaultAbstract) != 0;
+}
+
+/* Answer true if the receiver is a default method (Java 8 feature) */
+public boolean isDefaultMethod() {
+	return (this.modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0;
+}
+
+/* Answer true if the receiver is a deprecated method
+*/
+public final boolean isDeprecated() {
+	return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
+}
+
+/* Answer true if the receiver is final and cannot be overridden
+*/
+public final boolean isFinal() {
+	return (this.modifiers & ClassFileConstants.AccFinal) != 0;
+}
+
+/* Answer true if the receiver is implementing another method
+ * in other words, it is overriding and concrete, and overriden method is abstract
+ * Only set for source methods
+*/
+public final boolean isImplementing() {
+	return (this.modifiers & ExtraCompilerModifiers.AccImplementing) != 0;
+}
+
+/*
+ * Answer true if the receiver is a "public static void main(String[])" method
+ */
+public final boolean isMain() {
+	if (this.selector.length == 4 && CharOperation.equals(this.selector, TypeConstants.MAIN)
+			&& ((this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccStatic)) != 0)
+			&& TypeBinding.VOID == this.returnType
+			&& this.parameters.length == 1) {
+		TypeBinding paramType = this.parameters[0];
+		if (paramType.dimensions() == 1 && paramType.leafComponentType().id == TypeIds.T_JavaLangString) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/* Answer true if the receiver is a native method
+*/
+public final boolean isNative() {
+	return (this.modifiers & ClassFileConstants.AccNative) != 0;
+}
+
+/* Answer true if the receiver is overriding another method
+ * Only set for source methods
+*/
+public final boolean isOverriding() {
+	return (this.modifiers & ExtraCompilerModifiers.AccOverriding) != 0;
+}
+/* Answer true if the receiver has private visibility
+*/
+public final boolean isPrivate() {
+	return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
+}
+
+/* Answer true if the receiver has private visibility or if any of its enclosing types do.
+*/
+public final boolean isOrEnclosedByPrivateType() {
+	if ((this.modifiers & ClassFileConstants.AccPrivate) != 0)
+		return true;
+	return this.declaringClass != null && this.declaringClass.isOrEnclosedByPrivateType();
+}
+
+/* Answer true if the receiver has protected visibility
+*/
+public final boolean isProtected() {
+	return (this.modifiers & ClassFileConstants.AccProtected) != 0;
+}
+
+/* Answer true if the receiver has public visibility
+*/
+public final boolean isPublic() {
+	return (this.modifiers & ClassFileConstants.AccPublic) != 0;
+}
+
+/* Answer true if the receiver is a static method
+*/
+public final boolean isStatic() {
+	return (this.modifiers & ClassFileConstants.AccStatic) != 0;
+}
+
+/* Answer true if all float operations must adher to IEEE 754 float/double rules
+*/
+public final boolean isStrictfp() {
+	return (this.modifiers & ClassFileConstants.AccStrictfp) != 0;
+}
+
+/* Answer true if the receiver is a synchronized method
+*/
+public final boolean isSynchronized() {
+	return (this.modifiers & ClassFileConstants.AccSynchronized) != 0;
+}
+
+/* Answer true if the receiver has public visibility
+*/
+public final boolean isSynthetic() {
+	return (this.modifiers & ClassFileConstants.AccSynthetic) != 0;
+}
+
+/* Answer true if the receiver has private visibility and is used locally
+*/
+public final boolean isUsed() {
+	return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0;
+}
+
+/* Answer true if the receiver method has varargs
+*/
+public boolean isVarargs() {
+	return (this.modifiers & ClassFileConstants.AccVarargs) != 0;
+}
+public boolean isPolymorphic() {
+	return false;
+}
+/* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
+*/
+public final boolean isViewedAsDeprecated() {
+	return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0;
+}
+
+public final int kind() {
+	return Binding.METHOD;
+}
+/* Answer true if the receiver is visible to the invocationPackage.
+*/
+
+/**
+ * Returns the original method (as opposed to parameterized/polymorphic instances)
+ */
+public MethodBinding original() {
+	return this;
+}
+
+public char[] readableName() /* foo(int, Thread) */ {
+	StringBuffer buffer = new StringBuffer(this.parameters.length + 1 * 20);
+	if (isConstructor())
+		buffer.append(this.declaringClass.sourceName());
+	else
+		buffer.append(this.selector);
+	buffer.append('(');
+	if (this.parameters != Binding.NO_PARAMETERS) {
+		for (int i = 0, length = this.parameters.length; i < length; i++) {
+			if (i > 0)
+				buffer.append(", "); //$NON-NLS-1$
+			buffer.append(this.parameters[i].sourceName());
+		}
+	}
+	buffer.append(')');
+	return buffer.toString().toCharArray();
+}
+public void setAnnotations(AnnotationBinding[] annotations) {
+	this.declaringClass.storeAnnotations(this, annotations);
+}
+public void setAnnotations(AnnotationBinding[] annotations, AnnotationBinding[][] parameterAnnotations, Object defaultValue, LookupEnvironment optionalEnv) {
+	this.declaringClass.storeAnnotationHolder(this,  AnnotationHolder.storeAnnotations(annotations, parameterAnnotations, defaultValue, optionalEnv));
+}
+public void setDefaultValue(Object defaultValue) {
+	MethodBinding originalMethod = original();
+	originalMethod.tagBits |= TagBits.DefaultValueResolved;
+
+	AnnotationHolder holder = this.declaringClass.retrieveAnnotationHolder(this, false);
+	if (holder == null)
+		setAnnotations(null, null, defaultValue, null);
+	else
+		setAnnotations(holder.getAnnotations(), holder.getParameterAnnotations(), defaultValue, null);
+}
+public void setParameterAnnotations(AnnotationBinding[][] parameterAnnotations) {
+	AnnotationHolder holder = this.declaringClass.retrieveAnnotationHolder(this, false);
+	if (holder == null)
+		setAnnotations(null, parameterAnnotations, null, null);
+	else
+		setAnnotations(holder.getAnnotations(), parameterAnnotations, holder.getDefaultValue(), null);
+}
+protected final void setSelector(char[] selector) {
+	this.selector = selector;
+	this.signature = null;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
+ */
+public char[] shortReadableName() {
+	StringBuffer buffer = new StringBuffer(this.parameters.length + 1 * 20);
+	if (isConstructor())
+		buffer.append(this.declaringClass.shortReadableName());
+	else
+		buffer.append(this.selector);
+	buffer.append('(');
+	if (this.parameters != Binding.NO_PARAMETERS) {
+		for (int i = 0, length = this.parameters.length; i < length; i++) {
+			if (i > 0)
+				buffer.append(", "); //$NON-NLS-1$
+			buffer.append(this.parameters[i].shortReadableName());
+		}
+	}
+	buffer.append(')');
+	int nameLength = buffer.length();
+	char[] shortReadableName = new char[nameLength];
+	buffer.getChars(0, nameLength, shortReadableName, 0);
+	return shortReadableName;
+}
+
+/* Answer the receiver's signature.
+*
+* NOTE: This method should only be used during/after code gen.
+* The signature is cached so if the signature of the return type or any parameter
+* type changes, the cached state is invalid.
+*/
+public final char[] signature() /* (ILjava/lang/Thread;)Ljava/lang/Object; */ {
+	if (this.signature != null)
+		return this.signature;
+
+	StringBuffer buffer = new StringBuffer(this.parameters.length + 1 * 20);
+	buffer.append('(');
+
+	TypeBinding[] targetParameters = this.parameters;
+	boolean isConstructor = isConstructor();
+	if (isConstructor && this.declaringClass.isEnum()) { // insert String name,int ordinal
+		buffer.append(ConstantPool.JavaLangStringSignature);
+		buffer.append(TypeBinding.INT.signature());
+	}
+	boolean needSynthetics = isConstructor && this.declaringClass.isNestedType();
+	if (needSynthetics) {
+		// take into account the synthetic argument type signatures as well
+		ReferenceBinding[] syntheticArgumentTypes = this.declaringClass.syntheticEnclosingInstanceTypes();
+		if (syntheticArgumentTypes != null) {
+			for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
+				buffer.append(syntheticArgumentTypes[i].signature());
+			}
+		}
+
+		if (this instanceof SyntheticMethodBinding) {
+			targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters;
+		}
+	}
+
+	if (targetParameters != Binding.NO_PARAMETERS) {
+		for (int i = 0; i < targetParameters.length; i++) {
+			buffer.append(targetParameters[i].signature());
+		}
+	}
+	if (needSynthetics) {
+		SyntheticArgumentBinding[] syntheticOuterArguments = this.declaringClass.syntheticOuterLocalVariables();
+		int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length;
+		for (int i = 0; i < count; i++) {
+			buffer.append(syntheticOuterArguments[i].type.signature());
+		}
+		// move the extra padding arguments of the synthetic constructor invocation to the end
+		for (int i = targetParameters.length, extraLength = this.parameters.length; i < extraLength; i++) {
+			buffer.append(this.parameters[i].signature());
+		}
+	}
+	buffer.append(')');
+	if (this.returnType != null)
+		buffer.append(this.returnType.signature());
+	int nameLength = buffer.length();
+	this.signature = new char[nameLength];
+	buffer.getChars(0, nameLength, this.signature, 0);
+
+	return this.signature;
+}
+/*
+ * This method is used to record references to nested types inside the method signature.
+ * This is the one that must be used during code generation.
+ *
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=171184
+ */
+public final char[] signature(ClassFile classFile) {
+	if (this.signature != null) {
+		if ((this.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			// we need to record inner classes references
+			boolean isConstructor = isConstructor();
+			TypeBinding[] targetParameters = this.parameters;
+			boolean needSynthetics = isConstructor && this.declaringClass.isNestedType();
+			if (needSynthetics) {
+				// take into account the synthetic argument type signatures as well
+				ReferenceBinding[] syntheticArgumentTypes = this.declaringClass.syntheticEnclosingInstanceTypes();
+				if (syntheticArgumentTypes != null) {
+					for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
+						ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i];
+						if ((syntheticArgumentType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+							Util.recordNestedType(classFile, syntheticArgumentType);
+						}
+					}
+				}
+				if (this instanceof SyntheticMethodBinding) {
+					targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters;
+				}
+			}
+
+			if (targetParameters != Binding.NO_PARAMETERS) {
+				for (int i = 0, max = targetParameters.length; i < max; i++) {
+					TypeBinding targetParameter = targetParameters[i];
+					TypeBinding leafTargetParameterType = targetParameter.leafComponentType();
+					if ((leafTargetParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+						Util.recordNestedType(classFile, leafTargetParameterType);
+					}
+				}
+			}
+			if (needSynthetics) {
+				// move the extra padding arguments of the synthetic constructor invocation to the end
+				for (int i = targetParameters.length, extraLength = this.parameters.length; i < extraLength; i++) {
+					TypeBinding parameter = this.parameters[i];
+					TypeBinding leafParameterType = parameter.leafComponentType();
+					if ((leafParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+						Util.recordNestedType(classFile, leafParameterType);
+					}
+				}
+			}
+			if (this.returnType != null) {
+				TypeBinding ret = this.returnType.leafComponentType();
+				if ((ret.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+					Util.recordNestedType(classFile, ret);
+				}
+			}
+		}
+		return this.signature;
+	}
+
+	StringBuffer buffer = new StringBuffer((this.parameters.length + 1) * 20);
+	buffer.append('(');
+
+	TypeBinding[] targetParameters = this.parameters;
+	boolean isConstructor = isConstructor();
+	if (isConstructor && this.declaringClass.isEnum()) { // insert String name,int ordinal
+		buffer.append(ConstantPool.JavaLangStringSignature);
+		buffer.append(TypeBinding.INT.signature());
+	}
+	boolean needSynthetics = isConstructor && this.declaringClass.isNestedType();
+	if (needSynthetics) {
+		// take into account the synthetic argument type signatures as well
+		ReferenceBinding[] syntheticArgumentTypes = this.declaringClass.syntheticEnclosingInstanceTypes();
+		if (syntheticArgumentTypes != null) {
+			for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) {
+				ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i];
+				if ((syntheticArgumentType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+					this.tagBits |= TagBits.ContainsNestedTypeReferences;
+					Util.recordNestedType(classFile, syntheticArgumentType);
+				}
+				buffer.append(syntheticArgumentType.signature());
+			}
+		}
+
+		if (this instanceof SyntheticMethodBinding) {
+			targetParameters = ((SyntheticMethodBinding)this).targetMethod.parameters;
+		}
+	}
+
+	if (targetParameters != Binding.NO_PARAMETERS) {
+		for (int i = 0, max = targetParameters.length; i < max; i++) {
+			TypeBinding targetParameter = targetParameters[i];
+			TypeBinding leafTargetParameterType = targetParameter.leafComponentType();
+			if ((leafTargetParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				this.tagBits |= TagBits.ContainsNestedTypeReferences;
+				Util.recordNestedType(classFile, leafTargetParameterType);
+			}
+			buffer.append(targetParameter.signature());
+		}
+	}
+	if (needSynthetics) {
+		SyntheticArgumentBinding[] syntheticOuterArguments = this.declaringClass.syntheticOuterLocalVariables();
+		int count = syntheticOuterArguments == null ? 0 : syntheticOuterArguments.length;
+		for (int i = 0; i < count; i++) {
+			buffer.append(syntheticOuterArguments[i].type.signature());
+		}
+		// move the extra padding arguments of the synthetic constructor invocation to the end
+		for (int i = targetParameters.length, extraLength = this.parameters.length; i < extraLength; i++) {
+			TypeBinding parameter = this.parameters[i];
+			TypeBinding leafParameterType = parameter.leafComponentType();
+			if ((leafParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				this.tagBits |= TagBits.ContainsNestedTypeReferences;
+				Util.recordNestedType(classFile, leafParameterType);
+			}
+			buffer.append(parameter.signature());
+		}
+	}
+	buffer.append(')');
+	if (this.returnType != null) {
+		TypeBinding ret = this.returnType.leafComponentType();
+		if ((ret.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			this.tagBits |= TagBits.ContainsNestedTypeReferences;
+			Util.recordNestedType(classFile, ret);
+		}
+		buffer.append(this.returnType.signature());
+	}
+	int nameLength = buffer.length();
+	this.signature = new char[nameLength];
+	buffer.getChars(0, nameLength, this.signature, 0);
+
+	return this.signature;
+}
+public final int sourceEnd() {
+	AbstractMethodDeclaration method = sourceMethod();
+	if (method == null) {
+		if (this.declaringClass instanceof SourceTypeBinding)
+			return ((SourceTypeBinding) this.declaringClass).sourceEnd();
+		return 0;
+	}
+	return method.sourceEnd;
+}
+public AbstractMethodDeclaration sourceMethod() {
+	if (isSynthetic()) {
+		return null;
+	}
+	SourceTypeBinding sourceType;
+	try {
+		sourceType = (SourceTypeBinding) this.declaringClass;
+	} catch (ClassCastException e) {
+		return null;
+	}
+
+	AbstractMethodDeclaration[] methods = sourceType.scope != null ? sourceType.scope.referenceContext.methods : null;
+	if (methods != null) {
+		for (int i = methods.length; --i >= 0;)
+			if (this == methods[i].binding)
+				return methods[i];
+	}
+	return null;
+}
+public LambdaExpression sourceLambda() {
+	return null;
+}
+public final int sourceStart() {
+	AbstractMethodDeclaration method = sourceMethod();
+	if (method == null) {
+		if (this.declaringClass instanceof SourceTypeBinding)
+			return ((SourceTypeBinding) this.declaringClass).sourceStart();
+		return 0;
+	}
+	return method.sourceStart;
+}
+
+/**
+ * Returns the method to use during tiebreak (usually the method itself).
+ * For generic method invocations, tiebreak needs to use generic method with erasure substitutes.
+ */
+public MethodBinding tiebreakMethod() {
+	return this;
+}
+public String toString() {
+	StringBuffer output = new StringBuffer(10);
+	if ((this.modifiers & ExtraCompilerModifiers.AccUnresolved) != 0) {
+		output.append("[unresolved] "); //$NON-NLS-1$
+	}
+	ASTNode.printModifiers(this.modifiers, output);
+	output.append(this.returnType != null ? this.returnType.debugName() : "<no type>"); //$NON-NLS-1$
+	output.append(" "); //$NON-NLS-1$
+	output.append(this.selector != null ? new String(this.selector) : "<no selector>"); //$NON-NLS-1$
+	output.append("("); //$NON-NLS-1$
+	if (this.parameters != null) {
+		if (this.parameters != Binding.NO_PARAMETERS) {
+			for (int i = 0, length = this.parameters.length; i < length; i++) {
+				if (i  > 0)
+					output.append(", "); //$NON-NLS-1$
+				output.append(this.parameters[i] != null ? this.parameters[i].debugName() : "<no argument type>"); //$NON-NLS-1$
+			}
+		}
+	} else {
+		output.append("<no argument types>"); //$NON-NLS-1$
+	}
+	output.append(") "); //$NON-NLS-1$
+
+	if (this.thrownExceptions != null) {
+		if (this.thrownExceptions != Binding.NO_EXCEPTIONS) {
+			output.append("throws "); //$NON-NLS-1$
+			for (int i = 0, length = this.thrownExceptions.length; i < length; i++) {
+				if (i  > 0)
+					output.append(", "); //$NON-NLS-1$
+				output.append((this.thrownExceptions[i] != null) ? this.thrownExceptions[i].debugName() : "<no exception type>"); //$NON-NLS-1$
+			}
+		}
+	} else {
+		output.append("<no exception types>"); //$NON-NLS-1$
+	}
+	return output.toString();
+}
+public TypeVariableBinding[] typeVariables() {
+	return this.typeVariables;
+}
+public boolean hasNonNullDefault() {
+	if ((this.tagBits & TagBits.AnnotationNonNullByDefault) != 0)
+		return true;
+	if ((this.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+		return false;
+	return this.declaringClass.hasNonNullDefault();
+}
+
+public boolean redeclaresPublicObjectMethod(Scope scope) {
+	ReferenceBinding javaLangObject = scope.getJavaLangObject();
+	MethodBinding [] methods = javaLangObject.getMethods(this.selector);
+	for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
+		final MethodBinding method = methods[i];
+		if (!method.isPublic() || method.isStatic() || method.parameters.length != this.parameters.length) 
+			continue;
+		if (MethodVerifier.doesMethodOverride(this, method, scope.environment())) 
+			return true;
+	}
+	return false;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
new file mode 100644
index 0000000..8439817
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -0,0 +1,561 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *								bug 382354 - [1.8][compiler] Compiler silent on conflicting modifier
+ *								bug 401030 - [1.8][null] Null analysis support for lambda methods. 
+ *     Jesper S Moller - Contributions for
+ *							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+/**
+ * Specific block scope used for methods, constructors or clinits, representing
+ * its outermost blockscope. Note also that such a scope will be provided to enclose
+ * field initializers subscopes as well.
+ */
+public class MethodScope extends BlockScope {
+
+	public ReferenceContext referenceContext;
+	public boolean isStatic; // method modifier or initializer one
+
+	//fields used during name resolution
+	public boolean isConstructorCall = false;
+	public FieldBinding initializedField; // the field being initialized
+	public int lastVisibleFieldID = -1; // the ID of the last field which got declared
+	// note that #initializedField can be null AND lastVisibleFieldID >= 0, when processing instance field initializers.
+
+	// flow analysis
+	public int analysisIndex; // for setting flow-analysis id
+	public boolean isPropagatingInnerClassEmulation;
+
+	// for local variables table attributes
+	public int lastIndex = 0;
+	public long[] definiteInits = new long[4];
+	public long[][] extraDefiniteInits = new long[4][];
+
+	// annotation support
+	public boolean insideTypeAnnotation = false;
+
+	// inner-emulation
+	public SyntheticArgumentBinding[] extraSyntheticArguments;
+
+	// remember suppressed warning re missing 'default:' to give hints on possibly related flow problems
+	public boolean hasMissingSwitchDefault; // TODO(stephan): combine flags to a bitset?
+
+public MethodScope(Scope parent, ReferenceContext context, boolean isStatic) {
+	super(METHOD_SCOPE, parent);
+	this.locals = new LocalVariableBinding[5];
+	this.referenceContext = context;
+	this.isStatic = isStatic;
+	this.startIndex = 0;
+}
+
+String basicToString(int tab) {
+	String newLine = "\n"; //$NON-NLS-1$
+	for (int i = tab; --i >= 0;)
+		newLine += "\t"; //$NON-NLS-1$
+
+	String s = newLine + "--- Method Scope ---"; //$NON-NLS-1$
+	newLine += "\t"; //$NON-NLS-1$
+	s += newLine + "locals:"; //$NON-NLS-1$
+	for (int i = 0; i < this.localIndex; i++)
+		s += newLine + "\t" + this.locals[i].toString(); //$NON-NLS-1$
+	s += newLine + "startIndex = " + this.startIndex; //$NON-NLS-1$
+	s += newLine + "isConstructorCall = " + this.isConstructorCall; //$NON-NLS-1$
+	s += newLine + "initializedField = " + this.initializedField; //$NON-NLS-1$
+	s += newLine + "lastVisibleFieldID = " + this.lastVisibleFieldID; //$NON-NLS-1$
+	s += newLine + "referenceContext = " + this.referenceContext; //$NON-NLS-1$
+	return s;
+}
+
+/**
+ * Spec : 8.4.3 & 9.4
+ */
+private void checkAndSetModifiersForConstructor(MethodBinding methodBinding) {
+	int modifiers = methodBinding.modifiers;
+	final ReferenceBinding declaringClass = methodBinding.declaringClass;
+	if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
+		problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+	if ((((ConstructorDeclaration) this.referenceContext).bits & ASTNode.IsDefaultConstructor) != 0) {
+		// certain flags are propagated from declaring class onto constructor
+		final int DECLARING_FLAGS = ClassFileConstants.AccEnum|ClassFileConstants.AccPublic|ClassFileConstants.AccProtected;
+		final int VISIBILITY_FLAGS = ClassFileConstants.AccPrivate|ClassFileConstants.AccPublic|ClassFileConstants.AccProtected;
+		int flags;
+		if ((flags = declaringClass.modifiers & DECLARING_FLAGS) != 0) {
+			if ((flags & ClassFileConstants.AccEnum) != 0) {
+				modifiers &= ~VISIBILITY_FLAGS;
+				modifiers |= ClassFileConstants.AccPrivate; // default constructor is implicitly private in enum
+			} else {
+				modifiers &= ~VISIBILITY_FLAGS;
+				modifiers |= flags; // propagate public/protected
+			}
+		}
+	}
+
+	// after this point, tests on the 16 bits reserved.
+	int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+
+	// check for abnormal modifiers
+	final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected | ClassFileConstants.AccStrictfp);
+	if (declaringClass.isEnum() && (((ConstructorDeclaration) this.referenceContext).bits & ASTNode.IsDefaultConstructor) == 0) {
+		final int UNEXPECTED_ENUM_CONSTR_MODIFIERS = ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccStrictfp);
+		if ((realModifiers & UNEXPECTED_ENUM_CONSTR_MODIFIERS) != 0) {
+			problemReporter().illegalModifierForEnumConstructor((AbstractMethodDeclaration) this.referenceContext);
+			modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_ENUM_CONSTR_MODIFIERS;
+		} else if ((((AbstractMethodDeclaration) this.referenceContext).modifiers & ClassFileConstants.AccStrictfp) != 0) {
+			// must check the parse node explicitly
+			problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) this.referenceContext);
+		}
+		modifiers |= ClassFileConstants.AccPrivate; // enum constructor is implicitly private
+	} else if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+		problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) this.referenceContext);
+		modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS;
+	} else if ((((AbstractMethodDeclaration) this.referenceContext).modifiers & ClassFileConstants.AccStrictfp) != 0) {
+		// must check the parse node explicitly
+		problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) this.referenceContext);
+	}
+
+	// check for incompatible modifiers in the visibility bits, isolate the visibility bits
+	int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
+	if ((accessorBits & (accessorBits - 1)) != 0) {
+		problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+		// need to keep the less restrictive so disable Protected/Private as necessary
+		if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
+			if ((accessorBits & ClassFileConstants.AccProtected) != 0)
+				modifiers &= ~ClassFileConstants.AccProtected;
+			if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
+				modifiers &= ~ClassFileConstants.AccPrivate;
+		} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
+			modifiers &= ~ClassFileConstants.AccPrivate;
+		}
+	}
+
+//		// if the receiver's declaring class is a private nested type, then make sure the receiver is not private (causes problems for inner type emulation)
+//		if (declaringClass.isPrivate() && (modifiers & ClassFileConstants.AccPrivate) != 0)
+//			modifiers &= ~ClassFileConstants.AccPrivate;
+
+	methodBinding.modifiers = modifiers;
+}
+
+/**
+ * Spec : 8.4.3 & 9.4
+ */
+private void checkAndSetModifiersForMethod(MethodBinding methodBinding) {
+	int modifiers = methodBinding.modifiers;
+	final ReferenceBinding declaringClass = methodBinding.declaringClass;
+	if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0)
+		problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+	// after this point, tests on the 16 bits reserved.
+	int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag;
+
+	// set the requested modifiers for a method in an interface/annotation
+	if (declaringClass.isInterface()) {
+		int expectedModifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
+		boolean isDefaultMethod = (modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0; // no need to check validity, is done by the parser
+		boolean reportIllegalModifierCombination = false;
+		boolean isJDK18orGreater = false;
+		if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8 && !declaringClass.isAnnotationType()) {
+			expectedModifiers |= ClassFileConstants.AccStrictfp
+					| ExtraCompilerModifiers.AccDefaultMethod | ClassFileConstants.AccStatic;
+			isJDK18orGreater = true;
+			if (!methodBinding.isAbstract()) {
+				reportIllegalModifierCombination = isDefaultMethod && methodBinding.isStatic();
+			} else {
+				reportIllegalModifierCombination = isDefaultMethod || methodBinding.isStatic();
+				if (methodBinding.isStrictfp()) {
+					problemReporter().illegalAbstractModifierCombinationForMethod((AbstractMethodDeclaration) this.referenceContext);
+				}
+			}
+			if (reportIllegalModifierCombination) {
+				problemReporter().illegalModifierCombinationForInterfaceMethod((AbstractMethodDeclaration) this.referenceContext);
+			}
+			// Kludge - The AccDefaultMethod bit is outside the lower 16 bits and got removed earlier. Putting it back.
+			if (isDefaultMethod) {
+				realModifiers |= ExtraCompilerModifiers.AccDefaultMethod;
+			}
+		}
+		if ((realModifiers & ~expectedModifiers) != 0) {
+			if ((declaringClass.modifiers & ClassFileConstants.AccAnnotation) != 0)
+				problemReporter().illegalModifierForAnnotationMember((AbstractMethodDeclaration) this.referenceContext);
+			else
+				problemReporter().illegalModifierForInterfaceMethod((AbstractMethodDeclaration) this.referenceContext, isJDK18orGreater);
+		}
+		return;
+	}
+
+	// check for abnormal modifiers
+	final int UNEXPECTED_MODIFIERS = ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected
+		| ClassFileConstants.AccAbstract | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccSynchronized | ClassFileConstants.AccNative | ClassFileConstants.AccStrictfp);
+	if ((realModifiers & UNEXPECTED_MODIFIERS) != 0) {
+		problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) this.referenceContext);
+		modifiers &= ~ExtraCompilerModifiers.AccJustFlag | ~UNEXPECTED_MODIFIERS;
+	}
+
+	// check for incompatible modifiers in the visibility bits, isolate the visibility bits
+	int accessorBits = realModifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate);
+	if ((accessorBits & (accessorBits - 1)) != 0) {
+		problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+		// need to keep the less restrictive so disable Protected/Private as necessary
+		if ((accessorBits & ClassFileConstants.AccPublic) != 0) {
+			if ((accessorBits & ClassFileConstants.AccProtected) != 0)
+				modifiers &= ~ClassFileConstants.AccProtected;
+			if ((accessorBits & ClassFileConstants.AccPrivate) != 0)
+				modifiers &= ~ClassFileConstants.AccPrivate;
+		} else if ((accessorBits & ClassFileConstants.AccProtected) != 0 && (accessorBits & ClassFileConstants.AccPrivate) != 0) {
+			modifiers &= ~ClassFileConstants.AccPrivate;
+		}
+	}
+
+	// check for modifiers incompatible with abstract modifier
+	if ((modifiers & ClassFileConstants.AccAbstract) != 0) {
+		int incompatibleWithAbstract = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal | ClassFileConstants.AccSynchronized | ClassFileConstants.AccNative | ClassFileConstants.AccStrictfp;
+		if ((modifiers & incompatibleWithAbstract) != 0)
+			problemReporter().illegalAbstractModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+		if (!methodBinding.declaringClass.isAbstract())
+			problemReporter().abstractMethodInAbstractClass((SourceTypeBinding) declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+	}
+
+	/* DISABLED for backward compatibility with javac (if enabled should also mark private methods as final)
+	// methods from a final class are final : 8.4.3.3
+	if (methodBinding.declaringClass.isFinal())
+		modifiers |= AccFinal;
+	*/
+	// native methods cannot also be tagged as strictfp
+	if ((modifiers & ClassFileConstants.AccNative) != 0 && (modifiers & ClassFileConstants.AccStrictfp) != 0)
+		problemReporter().nativeMethodsCannotBeStrictfp(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+	// static members are only authorized in a static member or top level type
+	if (((realModifiers & ClassFileConstants.AccStatic) != 0) && declaringClass.isNestedType() && !declaringClass.isStatic())
+		problemReporter().unexpectedStaticModifierForMethod(declaringClass, (AbstractMethodDeclaration) this.referenceContext);
+
+	methodBinding.modifiers = modifiers;
+}
+
+public void checkUnusedParameters(MethodBinding method) {
+	if (method.isAbstract()
+			|| (method.isImplementing() && !compilerOptions().reportUnusedParameterWhenImplementingAbstract)
+			|| (method.isOverriding() && !method.isImplementing() && !compilerOptions().reportUnusedParameterWhenOverridingConcrete)
+			|| method.isMain()) {
+		// do not want to check
+		return;
+	}
+	for (int i = 0, maxLocals = this.localIndex; i < maxLocals; i++) {
+		LocalVariableBinding local = this.locals[i];
+		if (local == null || ((local.tagBits & TagBits.IsArgument) == 0)) {
+			break; // done with arguments
+		}
+		if (local.useFlag == LocalVariableBinding.UNUSED &&
+				// do not report fake used variable
+				((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { // declaration is reachable
+			problemReporter().unusedArgument(local.declaration);
+		}
+	}
+}
+
+/**
+ * Compute variable positions in scopes given an initial position offset
+ * ignoring unused local variables.
+ *
+ * Deal with arguments here, locals and subscopes are processed in BlockScope method
+ */
+public void computeLocalVariablePositions(int initOffset, CodeStream codeStream) {
+	this.offset = initOffset;
+	this.maxOffset = initOffset;
+
+	// manage arguments
+	int ilocal = 0, maxLocals = this.localIndex;
+	while (ilocal < maxLocals) {
+		LocalVariableBinding local = this.locals[ilocal];
+		if (local == null || ((local.tagBits & TagBits.IsArgument) == 0)) break; // done with arguments
+
+		// record user-defined argument for attribute generation
+		codeStream.record(local);
+
+		// assign variable position
+		local.resolvedPosition = this.offset;
+
+		if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) {
+			this.offset += 2;
+		} else {
+			this.offset++;
+		}
+		// check for too many arguments/local variables
+		if (this.offset > 0xFF) { // no more than 255 words of arguments
+			problemReporter().noMoreAvailableSpaceForArgument(local, local.declaration);
+		}
+		ilocal++;
+	}
+
+	// sneak in extra argument before other local variables
+	if (this.extraSyntheticArguments != null) {
+		for (int iarg = 0, maxArguments = this.extraSyntheticArguments.length; iarg < maxArguments; iarg++){
+			SyntheticArgumentBinding argument = this.extraSyntheticArguments[iarg];
+			argument.resolvedPosition = this.offset;
+			if ((argument.type == TypeBinding.LONG) || (argument.type == TypeBinding.DOUBLE)){
+				this.offset += 2;
+			} else {
+				this.offset++;
+			}
+			if (this.offset > 0xFF) { // no more than 255 words of arguments
+				problemReporter().noMoreAvailableSpaceForArgument(argument, (ASTNode)this.referenceContext);
+			}
+		}
+	}
+	this.computeLocalVariablePositions(ilocal, this.offset, codeStream);
+}
+
+/**
+ * Error management:
+ * 		keep null for all the errors that prevent the method to be created
+ * 		otherwise return a correct method binding (but without the element
+ *		that caused the problem) : i.e. Incorrect thrown exception
+ */
+MethodBinding createMethod(AbstractMethodDeclaration method) {
+	// is necessary to ensure error reporting
+	this.referenceContext = method;
+	method.scope = this;
+	SourceTypeBinding declaringClass = referenceType().binding;
+	int modifiers = method.modifiers | ExtraCompilerModifiers.AccUnresolved;
+	if (method.isConstructor()) {
+		if (method.isDefaultConstructor())
+			modifiers |= ExtraCompilerModifiers.AccIsDefaultConstructor;
+		method.binding = new MethodBinding(modifiers, null, null, declaringClass);
+		checkAndSetModifiersForConstructor(method.binding);
+	} else {
+		if (declaringClass.isInterface()) {// interface or annotation type
+			if (method.isDefaultMethod() || method.isStatic()) {
+				modifiers |= ClassFileConstants.AccPublic; // default method is not abstract
+			} else {
+				modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
+			}
+		}
+		method.binding =
+			new MethodBinding(modifiers, method.selector, null, null, null, declaringClass);
+		checkAndSetModifiersForMethod(method.binding);
+	}
+	this.isStatic = method.binding.isStatic();
+
+	Argument[] argTypes = method.arguments;
+	int argLength = argTypes == null ? 0 : argTypes.length;
+	long sourceLevel = compilerOptions().sourceLevel;
+	if (argLength > 0) {
+		Argument argument = argTypes[--argLength];
+		if (argument.isVarArgs() && sourceLevel >= ClassFileConstants.JDK1_5)
+			method.binding.modifiers |= ClassFileConstants.AccVarargs;
+		if (CharOperation.equals(argument.name, ConstantPool.This)) {
+			problemReporter().illegalThisDeclaration(argument);
+		}
+		while (--argLength >= 0) {
+			argument = argTypes[argLength];
+			if (argument.isVarArgs() && sourceLevel >= ClassFileConstants.JDK1_5)
+				problemReporter().illegalVararg(argument, method);
+			if (CharOperation.equals(argument.name, ConstantPool.This)) {
+				problemReporter().illegalThisDeclaration(argument);
+			}
+		}
+	}
+	if (method.receiver != null) {
+		if (sourceLevel <= ClassFileConstants.JDK1_7) {
+			problemReporter().illegalSourceLevelForThis(method.receiver);
+		}
+		if (method.receiver.annotations != null) {
+			method.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+
+	TypeParameter[] typeParameters = method.typeParameters();
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, If they exist at all, process type parameters irrespective of source level.
+    if (typeParameters == null || typeParameters.length == 0) {
+	    method.binding.typeVariables = Binding.NO_TYPE_VARIABLES;
+	} else {
+		method.binding.typeVariables = createTypeVariables(typeParameters, method.binding);
+		method.binding.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+	}
+	return method.binding;
+}
+
+/**
+ * Overridden to detect the error case inside an explicit constructor call:
+class X {
+	int i;
+	X myX;
+	X(X x) {
+		this(i, myX.i, x.i); // same for super calls... only the first 2 field accesses are errors
+	}
+}
+ */
+public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite, boolean needResolve) {
+
+	FieldBinding field = super.findField(receiverType, fieldName, invocationSite, needResolve);
+	if (field == null)
+		return null;
+	if (!field.isValidBinding())
+		return field; // answer the error field
+	if (field.isStatic())
+		return field; // static fields are always accessible
+
+	if (!this.isConstructorCall || receiverType != enclosingSourceType())
+		return field;
+
+	if (invocationSite instanceof SingleNameReference)
+		return new ProblemFieldBinding(
+			field, // closest match
+			field.declaringClass,
+			fieldName,
+			ProblemReasons.NonStaticReferenceInConstructorInvocation);
+	if (invocationSite instanceof QualifiedNameReference) {
+		// look to see if the field is the first binding
+		QualifiedNameReference name = (QualifiedNameReference) invocationSite;
+		if (name.binding == null)
+			// only true when the field is the fieldbinding at the beginning of name's tokens
+			return new ProblemFieldBinding(
+				field, // closest match
+				field.declaringClass,
+				fieldName,
+				ProblemReasons.NonStaticReferenceInConstructorInvocation);
+	}
+	return field;
+}
+
+public boolean isInsideConstructor() {
+	return (this.referenceContext instanceof ConstructorDeclaration);
+}
+
+public boolean isInsideInitializer() {
+	return (this.referenceContext instanceof TypeDeclaration);
+}
+
+public boolean isLambdaScope() {
+	return this.referenceContext instanceof LambdaExpression;
+}
+
+public boolean isInsideInitializerOrConstructor() {
+	return (this.referenceContext instanceof TypeDeclaration)
+		|| (this.referenceContext instanceof ConstructorDeclaration);
+}
+
+/**
+ * Answer the problem reporter to use for raising new problems.
+ *
+ * Note that as a side-effect, this updates the current reference context
+ * (unit, type or method) in case the problem handler decides it is necessary
+ * to abort.
+ */
+public ProblemReporter problemReporter() {
+	ProblemReporter problemReporter = referenceCompilationUnit().problemReporter;
+	problemReporter.referenceContext = this.referenceContext;
+	return problemReporter;
+}
+
+public final int recordInitializationStates(FlowInfo flowInfo) {
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return -1;
+	UnconditionalFlowInfo unconditionalFlowInfo = flowInfo.unconditionalInitsWithoutSideEffect();
+	long[] extraInits = unconditionalFlowInfo.extra == null ?
+			null : unconditionalFlowInfo.extra[0];
+	long inits = unconditionalFlowInfo.definiteInits;
+	checkNextEntry : for (int i = this.lastIndex; --i >= 0;) {
+		if (this.definiteInits[i] == inits) {
+			long[] otherInits = this.extraDefiniteInits[i];
+			if ((extraInits != null) && (otherInits != null)) {
+				if (extraInits.length == otherInits.length) {
+					int j, max;
+					for (j = 0, max = extraInits.length; j < max; j++) {
+						if (extraInits[j] != otherInits[j]) {
+							continue checkNextEntry;
+						}
+					}
+					return i;
+				}
+			} else {
+				if ((extraInits == null) && (otherInits == null)) {
+					return i;
+				}
+			}
+		}
+	}
+
+	// add a new entry
+	if (this.definiteInits.length == this.lastIndex) {
+		// need a resize
+		System.arraycopy(
+			this.definiteInits,
+			0,
+			(this.definiteInits = new long[this.lastIndex + 20]),
+			0,
+			this.lastIndex);
+		System.arraycopy(
+			this.extraDefiniteInits,
+			0,
+			(this.extraDefiniteInits = new long[this.lastIndex + 20][]),
+			0,
+			this.lastIndex);
+	}
+	this.definiteInits[this.lastIndex] = inits;
+	if (extraInits != null) {
+		this.extraDefiniteInits[this.lastIndex] = new long[extraInits.length];
+		System.arraycopy(
+			extraInits,
+			0,
+			this.extraDefiniteInits[this.lastIndex],
+			0,
+			extraInits.length);
+	}
+	return this.lastIndex++;
+}
+
+/**
+ *  Answer the reference method of this scope, or null if initialization scope or lambda scope.
+ */
+public AbstractMethodDeclaration referenceMethod() {
+	if (this.referenceContext instanceof AbstractMethodDeclaration) return (AbstractMethodDeclaration) this.referenceContext;
+	return null;
+}
+
+/**
+ * Answers the binding of the reference method or reference lambda expression.
+ */
+public MethodBinding referenceMethodBinding() {
+	if (this.referenceContext instanceof LambdaExpression)
+		return ((LambdaExpression)this.referenceContext).binding;
+	if (this.referenceContext instanceof AbstractMethodDeclaration)
+		return ((AbstractMethodDeclaration)this.referenceContext).binding;
+	return null;
+}
+
+/**
+ *  Answer the reference type of this scope.
+ * It is the nearest enclosing type of this scope.
+ */
+public TypeDeclaration referenceType() {
+	ClassScope scope = enclosingClassScope();
+	return scope == null ? null : scope.referenceContext;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
new file mode 100644
index 0000000..212fcaa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -0,0 +1,1006 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Benjamin Muskalla - Contribution for bug 239066
+ *     Stephan Herrmann - Contribution for
+ *     								bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ *									bug 388954 - [1.8][compiler] detect default methods in class files
+ *									bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *									bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract
+ *									bug 390883 - [1.8][compiler] Unable to override default method
+ *									bug 401796 - [1.8][compiler] don't treat default methods as overriding an independent inherited abstract method
+ *									bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *									bug 395681 - [compiler] Improve simulation of javac6 behavior from bug 317719 after fixing bug 388795
+ *									bug 406928 - computation of inherited methods seems damaged (affecting @Overrides)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.Sorting;
+
+public abstract class MethodVerifier extends ImplicitNullAnnotationVerifier {
+	SourceTypeBinding type;
+	HashtableOfObject inheritedMethods;
+	HashtableOfObject currentMethods;
+	LookupEnvironment environment;
+	/*
+Binding creation is responsible for reporting all problems with types:
+	- all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final)
+		- plus invalid modifiers given the context (the verifier did not do this before)
+	- qualified name collisions between a type and a package (types in default packages are excluded)
+	- all type hierarchy problems:
+		- cycles in the superclass or superinterface hierarchy
+		- an ambiguous, invisible or missing superclass or superinterface
+		- extending a final class
+		- extending an interface instead of a class
+		- implementing a class instead of an interface
+		- implementing the same interface more than once (i.e. duplicate interfaces)
+	- with nested types:
+		- shadowing an enclosing type's source name
+		- defining a static class or interface inside a non-static nested class
+		- defining an interface as a local type (local types can only be classes)
+*/
+MethodVerifier(LookupEnvironment environment) {
+	super(environment.globalOptions);
+	this.type = null;  // Initialized with the public method verify(SourceTypeBinding)
+	this.inheritedMethods = null;
+	this.currentMethods = null;
+	this.environment = environment;
+}
+boolean areMethodsCompatible(MethodBinding one, MethodBinding two) {
+	return areMethodsCompatible(one, two, this.environment);
+}
+static boolean areMethodsCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) {
+	// use the original methods to test compatibility, but do not check visibility, etc
+	one = one.original();
+	two = one.findOriginalInheritedMethod(two);
+
+	if (two == null)
+		return false; // method's declaringClass does not inherit from inheritedMethod's
+
+	return isParameterSubsignature(one, two, environment);
+}
+boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) {
+	return areReturnTypesCompatible(one, two, this.type.scope.environment());
+}
+static boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two, LookupEnvironment environment) {
+	if (one.returnType == two.returnType) return true;
+	if (environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5) {
+		// short is compatible with int, but as far as covariance is concerned, its not
+		if (one.returnType.isBaseType()) return false;
+
+		if (!one.declaringClass.isInterface() && one.declaringClass.id == TypeIds.T_JavaLangObject)
+			return two.returnType.isCompatibleWith(one.returnType); // interface methods inherit from Object
+
+		return one.returnType.isCompatibleWith(two.returnType);
+	} else {
+		return areTypesEqual(one.returnType.erasure(), two.returnType.erasure());
+	}
+}
+boolean canSkipInheritedMethods() {
+	if (this.type.superclass() != null && this.type.superclass().isAbstract())
+		return false;
+	return this.type.superInterfaces() == Binding.NO_SUPERINTERFACES;
+}
+boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
+	return two == null // already know one is not null
+		|| one.declaringClass == two.declaringClass;
+}
+void checkAbstractMethod(MethodBinding abstractMethod) {
+	if (mustImplementAbstractMethod(abstractMethod.declaringClass)) {
+		TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
+		if (typeDeclaration != null) {
+			MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(abstractMethod);
+			missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, abstractMethod);
+		} else {
+			problemReporter().abstractMethodMustBeImplemented(this.type, abstractMethod);
+		}
+	}
+}
+void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] allInheritedMethods) {
+	if (this.type.isAnnotationType()) { // annotation cannot override any method
+		problemReporter().annotationCannotOverrideMethod(currentMethod, methods[length - 1]);
+		return; // do not repoort against subsequent inherited methods
+	}
+	CompilerOptions options = this.type.scope.compilerOptions();
+	// need to find the overridden methods to avoid blaming this type for issues which are already reported against a supertype
+	// but cannot ignore an overridden inherited method completely when it comes to checking for bridge methods
+	int[] overriddenInheritedMethods = length > 1 ? findOverriddenInheritedMethods(methods, length) : null;
+	nextMethod : for (int i = length; --i >= 0;) {
+		MethodBinding inheritedMethod = methods[i];
+		if (overriddenInheritedMethods == null || overriddenInheritedMethods[i] == 0) {
+			if (currentMethod.isStatic() != inheritedMethod.isStatic()) {  // Cannot override a static method or hide an instance method
+				problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod);
+				continue nextMethod;
+			}
+
+			// want to tag currentMethod even if return types are not equal
+			if (inheritedMethod.isAbstract()) {
+				if (inheritedMethod.declaringClass.isInterface()) {
+					currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing;
+				} else {
+					currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding;
+				}
+//			with the above change an abstract method is tagged as implementing the inherited abstract method
+//			if (!currentMethod.isAbstract() && inheritedMethod.isAbstract()) {
+//				if ((currentMethod.modifiers & CompilerModifiers.AccOverriding) == 0)
+//					currentMethod.modifiers |= CompilerModifiers.AccImplementing;
+			} else if (inheritedMethod.isPublic() || !this.type.isInterface()) {
+				// interface I { @Override Object clone(); } does not override Object#clone()
+				if (currentMethod.isDefaultMethod()
+						&& !inheritedMethod.isFinal() // overriding final is already reported, that's enough
+						&& inheritedMethod.declaringClass.id == TypeIds.T_JavaLangObject)
+				{
+					// JLS 9.4.3 (Java8): default method cannot override method from j.l.Object
+					problemReporter(currentMethod).defaultMethodOverridesObjectMethod(currentMethod);
+				} else {
+					// TODO (stephan) using AccImplementing for overrides of a default method works well
+					// for OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation
+					// but we should check if it has bad side effects elsewhere.
+					if (inheritedMethod.isDefaultMethod())
+						currentMethod.modifiers |= ExtraCompilerModifiers.AccImplementing;
+					else
+						currentMethod.modifiers |= ExtraCompilerModifiers.AccOverriding;
+				}
+			}
+
+			if (!areReturnTypesCompatible(currentMethod, inheritedMethod)
+					&& (currentMethod.returnType.tagBits & TagBits.HasMissingType) == 0) {
+				if (reportIncompatibleReturnTypeError(currentMethod, inheritedMethod))
+					continue nextMethod;
+			}
+			reportRawReferences(currentMethod, inheritedMethod); // if they were deferred, emit them now.
+			if (currentMethod.thrownExceptions != Binding.NO_EXCEPTIONS)
+				checkExceptions(currentMethod, inheritedMethod);
+			if (inheritedMethod.isFinal())
+				problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
+			if (!isAsVisible(currentMethod, inheritedMethod))
+				problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod);
+			if(inheritedMethod.isSynchronized() && !currentMethod.isSynchronized()) {
+				problemReporter(currentMethod).missingSynchronizedOnInheritedMethod(currentMethod, inheritedMethod);
+			}
+			if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) {
+				if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) {
+					// check against the other inherited methods to see if they hide this inheritedMethod
+					ReferenceBinding declaringClass = inheritedMethod.declaringClass;
+					if (declaringClass.isInterface())
+						for (int j = length; --j >= 0;)
+							if (i != j && methods[j].declaringClass.implementsInterface(declaringClass, false))
+								continue nextMethod;
+
+					problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod);
+				}
+			}
+		}
+		checkForBridgeMethod(currentMethod, inheritedMethod, allInheritedMethods);
+	}
+}
+
+public void reportRawReferences(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	// nothing to do here. Real action happens at 1.5+
+}
+void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	// Remember that interfaces can only define public instance methods
+	if (concreteMethod.isStatic())
+		// Cannot inherit a static method which is specified as an instance method by an interface
+		problemReporter().staticInheritedMethodConflicts(this.type, concreteMethod, abstractMethods);
+	if (!concreteMethod.isPublic()) {
+		int index = 0, length = abstractMethods.length;
+		if (concreteMethod.isProtected()) {
+			for (; index < length; index++)
+				if (abstractMethods[index].isPublic()) break;
+		} else if (concreteMethod.isDefault()) {
+			for (; index < length; index++)
+				if (!abstractMethods[index].isDefault()) break;
+		}
+		if (index < length)
+			problemReporter().inheritedMethodReducesVisibility(this.type, concreteMethod, abstractMethods);
+	}
+	if (concreteMethod.thrownExceptions != Binding.NO_EXCEPTIONS)
+		for (int i = abstractMethods.length; --i >= 0;)
+			checkExceptions(concreteMethod, abstractMethods[i]);
+
+	// A subclass inheriting this method and putting it up as the implementation to meet its own
+	// obligations should qualify as a use.
+	if (concreteMethod.isOrEnclosedByPrivateType())
+		concreteMethod.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+}
+
+/*
+"8.4.4"
+Verify that newExceptions are all included in inheritedExceptions.
+Assumes all exceptions are valid and throwable.
+Unchecked exceptions (compatible with runtime & error) are ignored (see the spec on pg. 203).
+*/
+void checkExceptions(MethodBinding newMethod, MethodBinding inheritedMethod) {
+	ReferenceBinding[] newExceptions = resolvedExceptionTypesFor(newMethod);
+	ReferenceBinding[] inheritedExceptions = resolvedExceptionTypesFor(inheritedMethod);
+	for (int i = newExceptions.length; --i >= 0;) {
+		ReferenceBinding newException = newExceptions[i];
+		int j = inheritedExceptions.length;
+		while (--j > -1 && !isSameClassOrSubclassOf(newException, inheritedExceptions[j])){/*empty*/}
+		if (j == -1)
+			if (!newException.isUncheckedException(false)
+					&& (newException.tagBits & TagBits.HasMissingType) == 0) {
+				problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
+			}
+	}
+}
+
+void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) {
+	// no op before 1.5
+}
+
+void checkForMissingHashCodeMethod() {
+	MethodBinding[] choices = this.type.getMethods(TypeConstants.EQUALS);
+	boolean overridesEquals = false;
+	for (int i = choices.length; !overridesEquals && --i >= 0;)
+		overridesEquals = choices[i].parameters.length == 1 && choices[i].parameters[0].id == TypeIds.T_JavaLangObject;
+	if (overridesEquals) {
+		MethodBinding hashCodeMethod = this.type.getExactMethod(TypeConstants.HASHCODE, Binding.NO_PARAMETERS, null);
+		if (hashCodeMethod != null && hashCodeMethod.declaringClass.id == TypeIds.T_JavaLangObject)
+			this.problemReporter().shouldImplementHashcode(this.type);
+	}
+}
+
+void checkForRedundantSuperinterfaces(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
+	if (superInterfaces == Binding.NO_SUPERINTERFACES) return;
+
+	SimpleSet interfacesToCheck = new SimpleSet(superInterfaces.length);
+	SimpleSet redundantInterfaces = null;  // bark but once.
+	for (int i = 0, l = superInterfaces.length; i < l; i++) {
+		ReferenceBinding toCheck = superInterfaces[i];
+		for (int j = 0; j < l; j++) {
+			ReferenceBinding implementedInterface = superInterfaces[j];
+			if (i != j && toCheck.implementsInterface(implementedInterface, true)) {
+				if (redundantInterfaces == null) {
+					redundantInterfaces = new SimpleSet(3);
+				} else if (redundantInterfaces.includes(implementedInterface)) {
+					continue;
+				}
+				redundantInterfaces.add(implementedInterface);
+				TypeReference[] refs = this.type.scope.referenceContext.superInterfaces;
+				for (int r = 0, rl = refs.length; r < rl; r++) {
+					if (refs[r].resolvedType == toCheck) {
+						problemReporter().redundantSuperInterface(this.type, refs[j], implementedInterface, toCheck);
+						break; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=320911
+					}
+				}
+			}
+		}
+		interfacesToCheck.add(toCheck);
+	}
+
+	ReferenceBinding[] itsInterfaces = null;
+	SimpleSet inheritedInterfaces = new SimpleSet(5);
+	ReferenceBinding superType = superclass;
+	while (superType != null && superType.isValidBinding()) {
+		if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+			for (int i = 0, l = itsInterfaces.length; i < l; i++) {
+				ReferenceBinding inheritedInterface = itsInterfaces[i];
+				if (!inheritedInterfaces.includes(inheritedInterface) && inheritedInterface.isValidBinding()) {
+					if (interfacesToCheck.includes(inheritedInterface)) {
+						if (redundantInterfaces == null) {
+							redundantInterfaces = new SimpleSet(3);
+						} else if (redundantInterfaces.includes(inheritedInterface)) {
+							continue;
+						}
+						redundantInterfaces.add(inheritedInterface);
+						TypeReference[] refs = this.type.scope.referenceContext.superInterfaces;
+						for (int r = 0, rl = refs.length; r < rl; r++) {
+							if (refs[r].resolvedType == inheritedInterface) {
+								problemReporter().redundantSuperInterface(this.type, refs[r], inheritedInterface, superType);
+								break;
+							}
+						}
+					} else {
+						inheritedInterfaces.add(inheritedInterface);
+					}
+				}
+			}
+		}
+		superType = superType.superclass();
+	}
+
+	int nextPosition = inheritedInterfaces.elementSize;
+	if (nextPosition == 0) return;
+	ReferenceBinding[] interfacesToVisit = new ReferenceBinding[nextPosition];
+	inheritedInterfaces.asArray(interfacesToVisit);
+	for (int i = 0; i < nextPosition; i++) {
+		superType = interfacesToVisit[i];
+		if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+			int itsLength = itsInterfaces.length;
+			if (nextPosition + itsLength >= interfacesToVisit.length)
+				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+			for (int a = 0; a < itsLength; a++) {
+				ReferenceBinding inheritedInterface = itsInterfaces[a];
+				if (!inheritedInterfaces.includes(inheritedInterface) && inheritedInterface.isValidBinding()) {
+					if (interfacesToCheck.includes(inheritedInterface)) {
+						if (redundantInterfaces == null) {
+							redundantInterfaces = new SimpleSet(3);
+						} else if (redundantInterfaces.includes(inheritedInterface)) {
+							continue;
+						}
+						redundantInterfaces.add(inheritedInterface);
+						TypeReference[] refs = this.type.scope.referenceContext.superInterfaces;
+						for (int r = 0, rl = refs.length; r < rl; r++) {
+							if (refs[r].resolvedType == inheritedInterface) {
+								problemReporter().redundantSuperInterface(this.type, refs[r], inheritedInterface, superType);
+								break;
+							}
+						}
+					} else {
+						inheritedInterfaces.add(inheritedInterface);
+						interfacesToVisit[nextPosition++] = inheritedInterface;
+					}
+				}
+			}
+		}
+	}
+}
+
+void checkInheritedMethods(MethodBinding[] methods, int length, boolean[] isOverridden) {
+	/*
+	1. find concrete method
+	2. if it doesn't exist then find first inherited abstract method whose return type is compatible with all others
+	   if no such method exists then report incompatible return type error
+	   otherwise report abstract method must be implemented
+	3. if concrete method exists, check to see if its return type is compatible with all others
+	   if it is then check concrete method against abstract methods
+	   if its not, then find most specific abstract method & report abstract method must be implemented since concrete method is insufficient
+	   if no most specific return type abstract method exists, then report incompatible return type with all inherited methods 
+	*/
+
+	MethodBinding concreteMethod = this.type.isInterface() || methods[0].isAbstract() ? null : methods[0];
+	if (concreteMethod == null) {
+		MethodBinding bestAbstractMethod = length == 1 ? methods[0] : findBestInheritedAbstractOrDefaultMethod(methods, length);
+		boolean noMatch = bestAbstractMethod == null;
+		if (noMatch)
+			bestAbstractMethod = methods[0];
+		if (mustImplementAbstractMethod(bestAbstractMethod.declaringClass)) {
+			TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
+			MethodBinding superclassAbstractMethod = methods[0];
+			if (superclassAbstractMethod == bestAbstractMethod || superclassAbstractMethod.declaringClass.isInterface()) {
+				if (typeDeclaration != null) {
+					MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(bestAbstractMethod);
+					missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod);
+				} else {
+					problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod);
+				}
+			} else {
+				if (typeDeclaration != null) {
+					MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(bestAbstractMethod);
+					missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod, superclassAbstractMethod);
+				} else {
+					problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod, superclassAbstractMethod);
+				}
+			}
+		} else if (noMatch) {
+			problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length, isOverridden);
+		}
+		return;
+	}
+	if (length < 2) return; // nothing else to check
+
+	int index = length;
+	while (--index > 0 && checkInheritedReturnTypes(concreteMethod, methods[index])) {/*empty*/}
+	if (index > 0) {
+		// concreteMethod is not the best match
+		MethodBinding bestAbstractMethod = findBestInheritedAbstractOrDefaultMethod(methods, length);
+		if (bestAbstractMethod == null)
+			problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length, isOverridden);
+		else // can only happen in >= 1.5 since return types must be equal prior to 1.5
+			problemReporter().abstractMethodMustBeImplemented(this.type, bestAbstractMethod, concreteMethod);
+		return;
+	}
+
+	MethodBinding[] abstractMethods = new MethodBinding[length - 1];
+	index = 0;
+	for (int i = 0; i < length; i++)
+		if (methods[i].isAbstract())
+			abstractMethods[index++] = methods[i];
+	if (index == 0) return; // can happen with methods that contain 'equal' Missing Types, see bug 257384
+	if (index < abstractMethods.length)
+		System.arraycopy(abstractMethods, 0, abstractMethods = new MethodBinding[index], 0, index);
+	checkConcreteInheritedMethod(concreteMethod, abstractMethods);
+}
+boolean checkInheritedReturnTypes(MethodBinding method, MethodBinding otherMethod) {
+	if (areReturnTypesCompatible(method, otherMethod)) return true;
+
+	if (!this.type.isInterface())
+		if (method.declaringClass.isClass() || !this.type.implementsInterface(method.declaringClass, false))
+			if (otherMethod.declaringClass.isClass() || !this.type.implementsInterface(otherMethod.declaringClass, false))
+				return true; // do not complain since the superclass already got blamed
+
+	return false;
+}
+
+/*
+For each inherited method identifier (message pattern - vm signature minus the return type)
+	if current method exists
+		if current's vm signature does not match an inherited signature then complain
+		else compare current's exceptions & visibility against each inherited method
+	else
+		if inherited methods = 1
+			if inherited is abstract && type is NOT an interface or abstract, complain
+		else
+			if vm signatures do not match complain
+			else
+				find the concrete implementation amongst the abstract methods (can only be 1)
+				if one exists then
+					it must be a public instance method
+					compare concrete's exceptions against each abstract method
+				else
+					complain about missing implementation only if type is NOT an interface or abstract
+*/
+abstract void checkMethods();
+void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) {
+	// check that the inherited abstract method (package private visibility) is implemented within the same package
+	PackageBinding necessaryPackage = abstractMethod.declaringClass.fPackage;
+	if (necessaryPackage == this.type.fPackage) return; // not a problem
+
+	ReferenceBinding superType = this.type.superclass();
+	char[] selector = abstractMethod.selector;
+	do {
+		if (!superType.isValidBinding()) return;
+		if (!superType.isAbstract()) return; // closer non abstract super type will be flagged instead
+
+		if (necessaryPackage == superType.fPackage) {
+			MethodBinding[] methods = superType.getMethods(selector);
+			nextMethod : for (int m = methods.length; --m >= 0;) {
+				MethodBinding method = methods[m];
+				if (method.isPrivate() || method.isConstructor() || method.isDefaultAbstract())
+					continue nextMethod;
+				if (areMethodsCompatible(method, abstractMethod))
+					return; // found concrete implementation of abstract method in same package
+			}
+		}
+	} while ((superType = superType.superclass()) != abstractMethod.declaringClass);
+
+	// non visible abstract methods cannot be overridden so the type must be defined abstract
+	problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
+}
+
+void computeInheritedMethods() {
+	ReferenceBinding superclass = this.type.isInterface()
+		? this.type.scope.getJavaLangObject() // check interface methods against Object
+		: this.type.superclass(); // class or enum
+	computeInheritedMethods(superclass, this.type.superInterfaces());
+	checkForRedundantSuperinterfaces(superclass, this.type.superInterfaces());
+}
+
+/*
+Binding creation is responsible for reporting:
+	- all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations)
+		- plus invalid modifiers given the context... examples:
+			- interface methods can only be public
+			- abstract methods can only be defined by abstract classes
+	- collisions... 2 methods with identical vmSelectors
+	- multiple methods with the same message pattern but different return types
+	- ambiguous, invisible or missing return/argument/exception types
+	- check the type of any array is not void
+	- check that each exception type is Throwable or a subclass of it
+*/
+void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
+	// only want to remember inheritedMethods that can have an impact on the current type
+	// if an inheritedMethod has been 'replaced' by a supertype's method then skip it, however
+    // see usage of canOverridingMethodDifferInErasure below.
+	this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type
+
+	ReferenceBinding superType = superclass;
+	HashtableOfObject nonVisibleDefaultMethods = new HashtableOfObject(3); // maps method selectors to an array of methods
+
+	while (superType != null && superType.isValidBinding()) {
+
+		MethodBinding[] methods = superType.unResolvedMethods();
+		nextMethod : for (int m = methods.length; --m >= 0;) {
+			MethodBinding inheritedMethod = methods[m];
+			if (inheritedMethod.isPrivate() || inheritedMethod.isConstructor() || inheritedMethod.isDefaultAbstract())
+				continue nextMethod;
+			MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(inheritedMethod.selector);
+			if (existingMethods != null) {
+				existing : for (int i = 0, length = existingMethods.length; i < length; i++) {
+					MethodBinding existingMethod = existingMethods[i];
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358, skip inherited method only if any overriding version
+					// in a subclass is guaranteed to have the same erasure as an existing method.
+					if (existingMethod.declaringClass != inheritedMethod.declaringClass && areMethodsCompatible(existingMethod, inheritedMethod) && !canOverridingMethodDifferInErasure(existingMethod, inheritedMethod)) {
+						if (inheritedMethod.isDefault()) {
+							if (inheritedMethod.isAbstract()) {
+								checkPackagePrivateAbstractMethod(inheritedMethod);
+							} else if (existingMethod.declaringClass.fPackage != inheritedMethod.declaringClass.fPackage) {
+								if (this.type.fPackage == inheritedMethod.declaringClass.fPackage && !areReturnTypesCompatible(inheritedMethod, existingMethod))
+									continue existing; // may need to record incompatible return type
+							}
+						}
+						continue nextMethod;
+					}
+				}
+			}
+
+			if (!inheritedMethod.isDefault() || inheritedMethod.declaringClass.fPackage == this.type.fPackage) {
+				if (existingMethods == null) {
+					existingMethods = new MethodBinding[] {inheritedMethod};
+				} else {
+					int length = existingMethods.length;
+					System.arraycopy(existingMethods, 0, existingMethods = new MethodBinding[length + 1], 0, length);
+					existingMethods[length] = inheritedMethod;
+				}
+				this.inheritedMethods.put(inheritedMethod.selector, existingMethods);
+			} else {
+				MethodBinding[] nonVisible = (MethodBinding[]) nonVisibleDefaultMethods.get(inheritedMethod.selector);
+				if (nonVisible != null)
+					for (int i = 0, l = nonVisible.length; i < l; i++)
+						if (areMethodsCompatible(nonVisible[i], inheritedMethod))
+							continue nextMethod;
+				if (nonVisible == null) {
+					nonVisible = new MethodBinding[] {inheritedMethod};
+				} else {
+					int length = nonVisible.length;
+					System.arraycopy(nonVisible, 0, nonVisible = new MethodBinding[length + 1], 0, length);
+					nonVisible[length] = inheritedMethod;
+				}
+				nonVisibleDefaultMethods.put(inheritedMethod.selector, nonVisible);
+
+				if (inheritedMethod.isAbstract() && !this.type.isAbstract()) // non visible abstract methods cannot be overridden so the type must be defined abstract
+					problemReporter().abstractMethodCannotBeOverridden(this.type, inheritedMethod);
+
+				MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(inheritedMethod.selector);
+				if (current != null && !inheritedMethod.isStatic()) { // non visible methods cannot be overridden so a warning is issued
+					foundMatch : for (int i = 0, length = current.length; i < length; i++) {
+						if (!current[i].isStatic() && areMethodsCompatible(current[i], inheritedMethod)) {
+							problemReporter().overridesPackageDefaultMethod(current[i], inheritedMethod);
+							break foundMatch;
+						}
+					}
+				}
+			}
+		}
+		superType = superType.superclass();
+	}
+
+	List superIfcList = new ArrayList();
+	HashSet seenTypes = new HashSet();
+	collectAllDistinctSuperInterfaces(superInterfaces, seenTypes, superIfcList);
+	ReferenceBinding currentSuper = superclass;
+	while (currentSuper != null && currentSuper.id != TypeIds.T_JavaLangObject) {
+		collectAllDistinctSuperInterfaces(currentSuper.superInterfaces(), seenTypes, superIfcList);
+		currentSuper = currentSuper.superclass();
+	}
+
+	if (superIfcList.size() == 0) return;
+	
+	if (superIfcList.size() == 1) {
+		superInterfaces = new ReferenceBinding[] { (ReferenceBinding) superIfcList.get(0) };
+	} else {
+		superInterfaces = (ReferenceBinding[]) superIfcList.toArray(new ReferenceBinding[superIfcList.size()]);
+		superInterfaces = Sorting.sortTypes(superInterfaces);
+	}
+	
+	SimpleSet skip = findSuperinterfaceCollisions(superclass, superInterfaces);
+	int len = superInterfaces.length;
+	for (int i = len-1; i >= 0; i--) {
+		superType = superInterfaces[i];
+		if (superType.isValidBinding()) {
+			if (skip != null && skip.includes(superType)) continue;
+
+			MethodBinding[] methods = superType.unResolvedMethods();
+			nextMethod : for (int m = methods.length; --m >= 0;) { // Interface methods are all abstract public
+				MethodBinding inheritedMethod = methods[m];
+				if (inheritedMethod.isStatic()) continue nextMethod;
+				MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(inheritedMethod.selector);
+				if (existingMethods == null) {
+					existingMethods = new MethodBinding[] {inheritedMethod};
+				} else {
+					int length = existingMethods.length;
+					// look to see if any of the existingMethods implement this inheritedMethod
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358, skip inherited method only if any overriding version
+					// in a subclass is guaranteed to have the same erasure as an existing method.
+					for (int e = 0; e < length; e++)
+						if (isInterfaceMethodImplemented(inheritedMethod, existingMethods[e], superType) && !canOverridingMethodDifferInErasure(existingMethods[e], inheritedMethod))
+							continue nextMethod; // skip interface method with the same signature if visible to its declaringClass
+					System.arraycopy(existingMethods, 0, existingMethods = new MethodBinding[length + 1], 0, length);
+					existingMethods[length] = inheritedMethod;
+				}
+				this.inheritedMethods.put(inheritedMethod.selector, existingMethods);
+			}
+		}
+	}
+}
+
+void collectAllDistinctSuperInterfaces(ReferenceBinding[] superInterfaces, Set seen, List result) {
+	// use 'seen' to avoid duplicates, use result to maintain stable order
+	int length = superInterfaces.length;
+	for (int i=0; i<length; i++) {
+		ReferenceBinding superInterface = superInterfaces[i];
+		if (seen.add(superInterface)) {
+			result.add(superInterface);
+			collectAllDistinctSuperInterfaces(superInterface.superInterfaces(), seen, result);
+		}
+	}
+}
+
+// Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that
+// differs in erasure from overridingMethod could override `inheritedMethod'
+protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) {
+	return false;   // the case for <= 1.4  (cannot differ)
+}
+void computeMethods() {
+	MethodBinding[] methods = this.type.methods();
+	int size = methods.length;
+	this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type
+	for (int m = size; --m >= 0;) {
+		MethodBinding method = methods[m];
+		if (!(method.isConstructor() || method.isDefaultAbstract())) { // keep all methods which are NOT constructors or default abstract
+			MethodBinding[] existingMethods = (MethodBinding[]) this.currentMethods.get(method.selector);
+			if (existingMethods == null)
+				existingMethods = new MethodBinding[1];
+			else
+				System.arraycopy(existingMethods, 0,
+					(existingMethods = new MethodBinding[existingMethods.length + 1]), 0, existingMethods.length - 1);
+			existingMethods[existingMethods.length - 1] = method;
+			this.currentMethods.put(method.selector, existingMethods);
+		}
+	}
+}
+
+MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
+	return computeSubstituteMethod(inheritedMethod, currentMethod, this.environment);
+}
+
+static MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod, LookupEnvironment environment) {
+	if (inheritedMethod == null) return null;
+	if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
+
+	// due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
+	if (currentMethod.declaringClass instanceof BinaryTypeBinding)
+		((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
+	if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
+		((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);
+
+	TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables;
+	int inheritedLength = inheritedTypeVariables.length;
+	if (inheritedLength == 0) return inheritedMethod; // no substitution needed
+	TypeVariableBinding[] typeVariables = currentMethod.typeVariables;
+	int length = typeVariables.length;
+	if (length == 0)
+		return inheritedMethod.asRawMethod(environment);
+	if (length != inheritedLength)
+		return inheritedMethod; // no match JLS 8.4.2
+
+	// interface I { <T> void foo(T t); }
+	// class X implements I { public <T extends I> void foo(T t) {} }
+	// for the above case, we do not want to answer the substitute method since its not a match
+	TypeBinding[] arguments = new TypeBinding[length];
+	System.arraycopy(typeVariables, 0, arguments, 0, length);
+	ParameterizedGenericMethodBinding substitute =
+		environment.createParameterizedGenericMethod(inheritedMethod, arguments);
+	for (int i = 0; i < inheritedLength; i++) {
+		TypeVariableBinding inheritedTypeVariable = inheritedTypeVariables[i];
+		TypeBinding argument = arguments[i];
+		if (argument instanceof TypeVariableBinding) {
+			TypeVariableBinding typeVariable = (TypeVariableBinding) argument;
+			if (typeVariable.firstBound == inheritedTypeVariable.firstBound) {
+				if (typeVariable.firstBound == null)
+					continue; // both are null
+			} else if (typeVariable.firstBound != null && inheritedTypeVariable.firstBound != null) {
+				if (typeVariable.firstBound.isClass() != inheritedTypeVariable.firstBound.isClass())
+					return inheritedMethod; // not a match
+			}
+			if (Scope.substitute(substitute, inheritedTypeVariable.superclass) != typeVariable.superclass)
+				return inheritedMethod; // not a match
+			int interfaceLength = inheritedTypeVariable.superInterfaces.length;
+			ReferenceBinding[] interfaces = typeVariable.superInterfaces;
+			if (interfaceLength != interfaces.length)
+				return inheritedMethod; // not a match
+			next : for (int j = 0; j < interfaceLength; j++) {
+				TypeBinding superType = Scope.substitute(substitute, inheritedTypeVariable.superInterfaces[j]);
+				for (int k = 0; k < interfaceLength; k++)
+					if (superType == interfaces[k])
+						continue next;
+				return inheritedMethod; // not a match
+			}
+		} else if (inheritedTypeVariable.boundCheck(substitute, argument, null) != TypeConstants.OK) {
+	    	return inheritedMethod;
+		}
+	}
+   return substitute;
+}
+
+static boolean couldMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
+	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
+		return false;
+	if (method == inheritedMethod || method.isStatic() || inheritedMethod.isStatic())
+		return false;
+	if (inheritedMethod.isPrivate())
+		return false;
+	if (inheritedMethod.isDefault() && method.declaringClass.getPackage() != inheritedMethod.declaringClass.getPackage())
+		return false;
+	if (!method.isPublic()) { // inheritedMethod is either public or protected & method is less than public
+		if (inheritedMethod.isPublic())
+			return false;
+		if (inheritedMethod.isProtected() && !method.isProtected())
+			return false;
+	}
+	return true;
+}
+
+// Answer whether the method overrides the inheritedMethod
+// Check the necessary visibility rules & inheritance from the inheritedMethod's declaringClass
+// See isMethodSubsignature() for parameter comparisons
+public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
+	return doesMethodOverride(method, inheritedMethod, this.environment);
+}
+public static boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod, LookupEnvironment environment) {
+	return couldMethodOverride(method, inheritedMethod) && areMethodsCompatible(method, inheritedMethod, environment);
+}
+SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
+	return null; // noop in 1.4
+}
+
+MethodBinding findBestInheritedAbstractOrDefaultMethod(MethodBinding[] methods, int length) {
+	findMethod : for (int i = 0; i < length; i++) {
+		MethodBinding method = methods[i];
+		if (!(method.isAbstract() || method.isDefaultMethod())) continue findMethod;
+		for (int j = 0; j < length; j++) {
+			if (i == j) continue;
+			if (!checkInheritedReturnTypes(method, methods[j])) {
+				if (this.type.isInterface() && methods[j].declaringClass.id == TypeIds.T_JavaLangObject)
+					return method; // do not complain since the super interface already got blamed
+				continue findMethod;
+			}
+		}
+		return method;
+	}
+	return null;
+}
+
+int[] findOverriddenInheritedMethods(MethodBinding[] methods, int length) {
+	// NOTE assumes length > 1
+	// inherited methods are added as we walk up the superclass hierarchy, then each superinterface
+	// so method[1] from a class can NOT override method[0], but methods from superinterfaces can
+	// since superinterfaces can be added from different superclasses or other superinterfaces
+	int[] toSkip = null;
+	int i = 0;
+	ReferenceBinding declaringClass = methods[i].declaringClass;
+	if (!declaringClass.isInterface()) {
+		// in the first pass, skip overridden methods from superclasses
+		// only keep methods from the closest superclass, all others from higher superclasses can be skipped
+		// NOTE: methods were added in order by walking up the superclass hierarchy
+		ReferenceBinding declaringClass2 = methods[++i].declaringClass;
+		while (declaringClass == declaringClass2) {
+			if (++i == length) return null;
+			declaringClass2 = methods[i].declaringClass;
+		}
+		if (!declaringClass2.isInterface()) {
+			// skip all methods from different superclasses
+			if (declaringClass.fPackage != declaringClass2.fPackage && methods[i].isDefault()) return null;
+			toSkip = new int[length];
+			do {
+				toSkip[i] = -1;
+				if (++i == length) return toSkip;
+				declaringClass2 = methods[i].declaringClass;
+			} while (!declaringClass2.isInterface());
+		}
+	}
+	// in the second pass, skip overridden methods from superinterfaces
+	// NOTE: superinterfaces can appear in 'random' order
+	nextMethod : for (; i < length; i++) {
+		if (toSkip != null && toSkip[i] == -1) continue nextMethod;
+		declaringClass = methods[i].declaringClass;
+		for (int j = i + 1; j < length; j++) {
+			if (toSkip != null && toSkip[j] == -1) continue;
+			ReferenceBinding declaringClass2 = methods[j].declaringClass;
+			if (declaringClass == declaringClass2) continue;
+			if (declaringClass.implementsInterface(declaringClass2, true)) {
+				if (toSkip == null)
+					toSkip = new int[length];
+				toSkip[j] = -1;
+			} else if (declaringClass2.implementsInterface(declaringClass, true)) {
+				if (toSkip == null)
+					toSkip = new int[length];
+				toSkip[i] = -1;
+				continue nextMethod;
+			}
+		}
+	}
+	return toSkip;
+}
+
+boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) {
+	if (inheritedMethod.modifiers == newMethod.modifiers) return true;
+
+	if (newMethod.isPublic()) return true;		// Covers everything
+	if (inheritedMethod.isPublic()) return false;
+
+	if (newMethod.isProtected()) return true;
+	if (inheritedMethod.isProtected()) return false;
+
+	return !newMethod.isPrivate();		// The inheritedMethod cannot be private since it would not be visible
+}
+
+boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
+	// skip interface method with the same signature if visible to its declaringClass
+	return areParametersEqual(existingMethod, inheritedMethod) && existingMethod.declaringClass.implementsInterface(superType, true);
+}
+
+public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
+	return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
+		&& isParameterSubsignature(method, inheritedMethod);
+}
+
+boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
+	return isParameterSubsignature(method, inheritedMethod, this.environment);
+}
+static boolean isParameterSubsignature(MethodBinding method, MethodBinding inheritedMethod, LookupEnvironment environment) {
+	MethodBinding substitute = computeSubstituteMethod(inheritedMethod, method, environment);
+	return substitute != null && isSubstituteParameterSubsignature(method, substitute, environment);
+}
+
+//if method "overrides" substituteMethod then we can skip over substituteMethod while resolving a message send
+//if it does not then a name clash error is likely
+boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod) {
+	return isSubstituteParameterSubsignature(method, substituteMethod, this.environment);
+}
+
+static boolean isSubstituteParameterSubsignature(MethodBinding method, MethodBinding substituteMethod, LookupEnvironment environment) {
+	if (!areParametersEqual(method, substituteMethod)) {
+		// method can still override substituteMethod in cases like :
+		// <U extends Number> void c(U u) {}
+		// @Override void c(Number n) {}
+		// but method cannot have a "generic-enabled" parameter type
+		if (substituteMethod.hasSubstitutedParameters() && method.areParameterErasuresEqual(substituteMethod))
+			return method.typeVariables == Binding.NO_TYPE_VARIABLES && !hasGenericParameter(method);
+
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836
+		if (method.declaringClass.isRawType() && substituteMethod.declaringClass.isRawType())
+			if (method.hasSubstitutedParameters() && substituteMethod.hasSubstitutedParameters())
+				return areMethodsCompatible(method, substituteMethod, environment);
+
+		return false;
+	}
+
+	if (substituteMethod instanceof ParameterizedGenericMethodBinding) {
+		if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
+			return !((ParameterizedGenericMethodBinding) substituteMethod).isRaw;
+		// since substituteMethod has substituted type variables, method cannot have a generic signature AND no variables -> its a name clash if it does
+		return !hasGenericParameter(method);
+	}
+
+	// if method has its own variables, then substituteMethod failed bounds check in computeSubstituteMethod()
+	return method.typeVariables == Binding.NO_TYPE_VARIABLES;
+}
+static boolean hasGenericParameter(MethodBinding method) {
+	if (method.genericSignature() == null) return false;
+
+	// may be only the return type that is generic, need to check parameters
+	TypeBinding[] params = method.parameters;
+	for (int i = 0, l = params.length; i < l; i++) {
+		TypeBinding param = params[i].leafComponentType();
+		if (param instanceof ReferenceBinding) {
+			int modifiers = ((ReferenceBinding) param).modifiers;
+			if ((modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+				return true;
+		}
+	}
+	return false;
+}
+
+boolean isSameClassOrSubclassOf(ReferenceBinding testClass, ReferenceBinding superclass) {
+	do {
+		if (testClass == superclass) return true;
+	} while ((testClass = testClass.superclass()) != null);
+	return false;
+}
+
+boolean mustImplementAbstractMethod(ReferenceBinding declaringClass) {
+	// if the type's superclass is an abstract class, then all abstract methods must be implemented
+	// otherwise, skip it if the type's superclass must implement any of the inherited methods
+	if (!mustImplementAbstractMethods()) return false;
+	ReferenceBinding superclass = this.type.superclass();
+	if (declaringClass.isClass()) {
+		while (superclass.isAbstract() && superclass != declaringClass)
+			superclass = superclass.superclass(); // find the first concrete superclass or the abstract declaringClass
+	} else {
+		if (this.type.implementsInterface(declaringClass, false))
+			if (!superclass.implementsInterface(declaringClass, true)) // only if a superclass does not also implement the interface
+				return true;
+		while (superclass.isAbstract() && !superclass.implementsInterface(declaringClass, false))
+			superclass = superclass.superclass(); // find the first concrete superclass or the superclass which implements the interface
+	}
+	return superclass.isAbstract();		// if it is a concrete class then we have already reported problem against it
+}
+
+boolean mustImplementAbstractMethods() {
+	return !this.type.isInterface() && !this.type.isAbstract();
+}
+
+ProblemReporter problemReporter() {
+	return this.type.scope.problemReporter();
+}
+
+ProblemReporter problemReporter(MethodBinding currentMethod) {
+	ProblemReporter reporter = problemReporter();
+	if (currentMethod.declaringClass == this.type && currentMethod.sourceMethod() != null)	// only report against the currentMethod if its implemented by the type
+		reporter.referenceContext = currentMethod.sourceMethod();
+	return reporter;
+}
+
+/**
+ * Return true and report an incompatibleReturnType error if currentMethod's
+ * return type is strictly incompatible with inheritedMethod's, else return
+ * false and report an unchecked conversion warning. Do not call when
+ * areReturnTypesCompatible(currentMethod, inheritedMethod) returns true.
+ * @param currentMethod the (potentially) inheriting method
+ * @param inheritedMethod the inherited method
+ * @return true if currentMethod's return type is strictly incompatible with
+ *         inheritedMethod's
+ */
+boolean reportIncompatibleReturnTypeError(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
+	return true;
+}
+
+ReferenceBinding[] resolvedExceptionTypesFor(MethodBinding method) {
+	ReferenceBinding[] exceptions = method.thrownExceptions;
+	if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+		return exceptions;
+
+	if (!(method.declaringClass instanceof BinaryTypeBinding))
+		return Binding.NO_EXCEPTIONS; // safety check
+
+	for (int i = exceptions.length; --i >= 0;)
+		exceptions[i] = (ReferenceBinding) BinaryTypeBinding.resolveType(exceptions[i], this.environment, true /* raw conversion */);
+	return exceptions;
+}
+
+void verify() {
+	computeMethods();
+	computeInheritedMethods();
+	checkMethods();
+	if (this.type.isClass())
+		checkForMissingHashCodeMethod();
+}
+
+void verify(SourceTypeBinding someType) {
+	if (this.type == null) {
+		try {
+			this.type = someType;
+			verify();
+		} finally {
+			this.type = null;
+		}
+	} else {
+		this.environment.newMethodVerifier().verify(someType);
+	}
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer(10);
+	buffer.append("MethodVerifier for type: "); //$NON-NLS-1$
+	buffer.append(this.type.readableName());
+	buffer.append('\n');
+	buffer.append("\t-inherited methods: "); //$NON-NLS-1$
+	buffer.append(this.inheritedMethods);
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
new file mode 100644
index 0000000..9eb9c68
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -0,0 +1,967 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 388795 - [compiler] detection of name clash depends on order of super interfaces
+ *								bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract
+ *								bug 390883 - [1.8][compiler] Unable to override default method
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 401246 - [1.8][compiler] abstract class method should now trump conflicting default methods
+ *								bug 401796 - [1.8][compiler] don't treat default methods as overriding an independent inherited abstract method
+ *								bug 403867 - [1.8][compiler] Suspect error about duplicate default methods
+ *								bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.Sorting;
+
+class MethodVerifier15 extends MethodVerifier {
+
+MethodVerifier15(LookupEnvironment environment) {
+	super(environment);
+}
+// Given `overridingMethod' which overrides `inheritedMethod' answer whether some subclass method that
+// differs in erasure from overridingMethod could override `inheritedMethod'
+protected boolean canOverridingMethodDifferInErasure(MethodBinding overridingMethod, MethodBinding inheritedMethod) {
+	if (overridingMethod.areParameterErasuresEqual(inheritedMethod))
+		return false;  // no further change in signature is possible due to parameterization.
+	if (overridingMethod.declaringClass.isRawType())
+		return false;  // no parameterization is happening anyways.
+	return true;
+}
+boolean canSkipInheritedMethods() {
+	if (this.type.superclass() != null)
+		if (this.type.superclass().isAbstract() || this.type.superclass().isParameterizedType())
+			return false;
+	return this.type.superInterfaces() == Binding.NO_SUPERINTERFACES;
+}
+boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
+	return two == null // already know one is not null
+		|| (one.declaringClass == two.declaringClass && !one.declaringClass.isParameterizedType());
+}
+void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	super.checkConcreteInheritedMethod(concreteMethod, abstractMethods);
+	boolean analyseNullAnnotations = this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled;
+	// TODO (stephan): unclear if this srcMethod is actually needed
+	AbstractMethodDeclaration srcMethod = null;
+	if (analyseNullAnnotations && this.type.equals(concreteMethod.declaringClass)) // is currentMethod from the current type?
+		srcMethod = concreteMethod.sourceMethod();
+	boolean hasNonNullDefault = concreteMethod.hasNonNullDefault();
+	for (int i = 0, l = abstractMethods.length; i < l; i++) {
+		MethodBinding abstractMethod = abstractMethods[i];
+		if (concreteMethod.isVarargs() != abstractMethod.isVarargs())
+			problemReporter().varargsConflict(concreteMethod, abstractMethod, this.type);
+
+		// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
+		MethodBinding originalInherited = abstractMethod.original();
+		if (originalInherited.returnType != concreteMethod.returnType)
+			if (!isAcceptableReturnTypeOverride(concreteMethod, abstractMethod))
+				problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type);
+
+		// check whether bridge method is already defined above for interface methods
+		// skip generation of bridge method for current class & method if an equivalent
+		// bridge will be/would have been generated in the context of the super class since
+		// the bridge itself will be inherited. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=298362
+		if (originalInherited.declaringClass.isInterface()) {
+			if ((concreteMethod.declaringClass == this.type.superclass && this.type.superclass.isParameterizedType() && !areMethodsCompatible(concreteMethod, originalInherited))
+				|| this.type.superclass.erasure().findSuperTypeOriginatingFrom(originalInherited.declaringClass) == null)
+					this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
+		}
+		if (analyseNullAnnotations && !concreteMethod.isStatic() && !abstractMethod.isStatic()) {
+			checkNullSpecInheritance(concreteMethod, srcMethod, hasNonNullDefault, true, abstractMethod, this.type.scope, null);
+		}
+	}
+}
+void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] allInheritedMethods) {
+	if (currentMethod.isVarargs() != inheritedMethod.isVarargs())
+		problemReporter(currentMethod).varargsConflict(currentMethod, inheritedMethod, this.type);
+
+	// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
+	MethodBinding originalInherited = inheritedMethod.original();
+	if (originalInherited.returnType != currentMethod.returnType)
+		if (!isAcceptableReturnTypeOverride(currentMethod, inheritedMethod))
+			problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type);
+
+	MethodBinding bridge = this.type.addSyntheticBridgeMethod(originalInherited, currentMethod.original());
+	if (bridge != null) {
+		for (int i = 0, l = allInheritedMethods == null ? 0 : allInheritedMethods.length; i < l; i++) {
+			if (allInheritedMethods[i] != null && detectInheritedNameClash(originalInherited, allInheritedMethods[i].original()))
+				return;
+		}
+		// See if the new bridge clashes with any of the user methods of the class. For this check
+		// we should check for "method descriptor clash" and not just "method signature clash". Really
+		// what we are checking is whether there is a contention for the method dispatch table slot.
+		// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615.
+		MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(bridge.selector);
+		for (int i = current.length - 1; i >= 0; --i) {
+			final MethodBinding thisMethod = current[i];
+			if (thisMethod.areParameterErasuresEqual(bridge) && thisMethod.returnType.erasure() == bridge.returnType.erasure()) {
+				// use inherited method for problem reporting.
+				problemReporter(thisMethod).methodNameClash(thisMethod, inheritedMethod.declaringClass.isRawType() ? inheritedMethod : inheritedMethod.original(), ProblemSeverities.Error);
+				return;	
+			}
+		}
+	}
+}
+void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	// sent from checkMethods() to compare a current method and an inherited method that are not 'equal'
+
+	// error cases:
+	//		abstract class AA<E extends Comparable> { abstract void test(E element); }
+	//		class A extends AA<Integer> { public void test(Integer i) {} }
+	//		public class B extends A { public void test(Comparable i) {} }
+	//		interface I<E extends Comparable> { void test(E element); }
+	//		class A implements I<Integer> { public void test(Integer i) {} }
+	//		public class B extends A { public void test(Comparable i) {} }
+
+	//		abstract class Y implements EqualityComparable<Integer>, Equivalent<String> {
+	//			public boolean equalTo(Integer other) { return true; }
+	//		}
+	//		interface Equivalent<T> { boolean equalTo(T other); }
+	//		interface EqualityComparable<T> { boolean equalTo(T other); }
+
+	//		class Y implements EqualityComparable, Equivalent<String>{
+	//			public boolean equalTo(String other) { return true; }
+	//			public boolean equalTo(Object other) { return true; }
+	//		}
+	//		interface Equivalent<T> { boolean equalTo(T other); }
+	//		interface EqualityComparable { boolean equalTo(Object other); }
+
+	//		class A<T extends Number> { void m(T t) {} }
+	//		class B<S extends Integer> extends A<S> { void m(S t) {}}
+	//		class D extends B<Integer> { void m(Number t) {}    void m(Integer t) {} }
+
+	//		inheritedMethods does not include I.test since A has a valid implementation
+	//		interface I<E extends Comparable<E>> { void test(E element); }
+	//		class A implements I<Integer> { public void test(Integer i) {} }
+	//		class B extends A { public void test(Comparable i) {} }
+
+	if (inheritedMethod.isStatic() || currentMethod.isStatic()) {
+		MethodBinding original = inheritedMethod.original(); // can be the same as inherited
+		if (this.type.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_7 && currentMethod.areParameterErasuresEqual(original)) {
+			problemReporter(currentMethod).methodNameClashHidden(currentMethod, inheritedMethod.declaringClass.isRawType() ? inheritedMethod : original);
+		}
+		return; // no chance of bridge method's clashing
+	}
+
+	if (!detectNameClash(currentMethod, inheritedMethod, false)) { // check up the hierarchy for skipped inherited methods
+		TypeBinding[] currentParams = currentMethod.parameters;
+		TypeBinding[] inheritedParams = inheritedMethod.parameters;
+		int length = currentParams.length;
+		if (length != inheritedParams.length) return; // no match
+
+		for (int i = 0; i < length; i++)
+			if (currentParams[i] != inheritedParams[i])
+				if (currentParams[i].isBaseType() != inheritedParams[i].isBaseType() || !inheritedParams[i].isCompatibleWith(currentParams[i]))
+					return; // no chance that another inherited method's bridge method can collide
+
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		ReferenceBinding superType = inheritedMethod.declaringClass;
+		ReferenceBinding[] itsInterfaces = superType.superInterfaces();
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			nextPosition = itsInterfaces.length;
+			interfacesToVisit = itsInterfaces;
+		}
+		superType = superType.superclass(); // now start with its superclass
+		while (superType != null && superType.isValidBinding()) {
+			MethodBinding[] methods = superType.getMethods(currentMethod.selector);
+			for (int m = 0, n = methods.length; m < n; m++) {
+				MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
+				if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute, true))
+					return;
+			}
+			if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+			superType = superType.superclass();
+		}
+
+		for (int i = 0; i < nextPosition; i++) {
+			superType = interfacesToVisit[i];
+			if (superType.isValidBinding()) {
+				MethodBinding[] methods = superType.getMethods(currentMethod.selector);
+				for (int m = 0, n = methods.length; m < n; m++){
+					MethodBinding substitute = computeSubstituteMethod(methods[m], currentMethod);
+					if (substitute != null && !isSubstituteParameterSubsignature(currentMethod, substitute) && detectNameClash(currentMethod, substitute, true))
+						return;
+				}
+				if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+}
+void checkInheritedMethods(MethodBinding inheritedMethod, MethodBinding otherInheritedMethod) {
+
+	// the 2 inherited methods clash because of a parameterized type overrides a raw type
+	//		interface I { void foo(A a); }
+	//		class Y { void foo(A<String> a) {} }
+	//		abstract class X extends Y implements I { }
+	//		class A<T> {}
+	// in this case the 2 inherited methods clash because of type variables
+	//		interface I { <T, S> void foo(T t); }
+	//		class Y { <T> void foo(T t) {} }
+	//		abstract class X extends Y implements I {}
+
+	if (inheritedMethod.isStatic()) return;
+	if (this.environment.globalOptions.complianceLevel < ClassFileConstants.JDK1_7 && inheritedMethod.declaringClass.isInterface())
+		return;  // JDK7 checks for name clashes in interface inheritance, while JDK6 and below don't. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=354229
+
+	detectInheritedNameClash(inheritedMethod.original(), otherInheritedMethod.original());
+}
+// 8.4.8.4
+void checkInheritedMethods(MethodBinding[] methods, int length, boolean[] isOverridden) {
+	boolean continueInvestigation = true;
+	MethodBinding concreteMethod = null;
+	MethodBinding abstractSuperClassMethod = null;
+	boolean playingTrump = false; // invariant: playingTrump => (concreteMethod == null)
+	for (int i = 0; i < length; i++) {
+		if (!methods[i].declaringClass.isInterface()
+				&& methods[i].declaringClass != this.type
+				&& methods[i].isAbstract())
+		{
+			abstractSuperClassMethod = methods[i];
+			break;
+		}
+	}
+	for (int i = 0; i < length; i++) {
+		if (!methods[i].isAbstract()) {
+			// 8.4.8.4 defines an exception for default methods if
+			// (a) there exists an abstract method declared in a superclass of C and inherited by C
+			// (b) that is override-equivalent with the two methods.
+			if (methods[i].isDefaultMethod()
+					&& abstractSuperClassMethod != null							// condition (a)
+					&& areParametersEqual(abstractSuperClassMethod, methods[i]) // condition (b)...
+					&& concreteMethod == null) {
+				// skip, class method trumps this default method (concreteMethod remains null)
+				playingTrump = true;
+			} else {
+				playingTrump = false;
+				if (concreteMethod != null) {
+					// re-checking compatibility is needed for https://bugs.eclipse.org/346029
+					if (isOverridden[i] && areMethodsCompatible(concreteMethod, methods[i])) {
+						continue;
+					} else {
+						problemReporter().duplicateInheritedMethods(this.type, concreteMethod, methods[i]);
+						continueInvestigation = false;
+					}
+				}
+				concreteMethod = methods[i];
+			}
+		}
+	}
+	if (continueInvestigation) {
+		if (playingTrump) {
+			// multiple abstract & default methods are OK on this branch, but then the class must be declared abstract:
+			if (!this.type.isAbstract()) {
+				problemReporter().abstractMethodMustBeImplemented(this.type, abstractSuperClassMethod);
+				return;
+			}
+		} else {
+			if (concreteMethod != null && concreteMethod.isDefaultMethod()) {
+				if (this.environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_8) {
+					if (!checkInheritedDefaultMethods(methods, length))
+						return;
+				}
+			}
+		}
+		super.checkInheritedMethods(methods, length, isOverridden);
+	}
+}
+boolean checkInheritedDefaultMethods(MethodBinding[] methods, int length) {
+	// JLS8  9.4.1 (interface) and  8.4.8.4 (class):
+	// default method clashes with other inherited method which is override-equivalent 
+	if (length < 2) return true;
+	boolean ok = true;
+	findDefaultMethod: for (int i=0; i<length; i++) {
+		if (methods[i].isDefaultMethod()) {
+			findEquivalent: for (int j=0; j<length; j++) {
+				if (j == i) continue findEquivalent;
+				if (isMethodSubsignature(methods[i], methods[j])) {
+					if (!doesMethodOverride(methods[i], methods[j]) && !doesMethodOverride(methods[j], methods[i])) { 
+						problemReporter().inheritedDefaultMethodConflictsWithOtherInherited(this.type, methods[i], methods[j]);
+						ok = false;
+					}
+					continue findDefaultMethod;
+				}
+			}
+		}
+	}
+	return ok;
+}
+boolean checkInheritedReturnTypes(MethodBinding method, MethodBinding otherMethod) {
+	if (areReturnTypesCompatible(method, otherMethod)) return true;
+
+	/* We used to have some checks here to see if we would have already blamed the super type and if so avoid blaming
+	   the current type again. I have gotten rid of them as they in fact short circuit error reporting in cases where
+	   they should not. This means that occasionally we would report the error twice - the diagnostics is valid however,
+	   albeit arguably redundant. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=334313. For an example of a test
+	   where we do this extra reporting see org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test159()
+	 */
+	// check to see if this is just a warning, if so report it & skip to next method
+	if (isUnsafeReturnTypeOverride(method, otherMethod)) {
+		if (!method.declaringClass.implementsInterface(otherMethod.declaringClass, false))
+			problemReporter(method).unsafeReturnTypeOverride(method, otherMethod, this.type);
+		return true;
+	}
+
+	return false;
+}
+void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] allInheritedMethods)
+{
+	super.checkAgainstInheritedMethods(currentMethod, methods, length, allInheritedMethods);
+	CompilerOptions options = this.environment.globalOptions;
+	if (options.isAnnotationBasedNullAnalysisEnabled 
+			&& (currentMethod.tagBits & TagBits.IsNullnessKnown) == 0)
+	{
+		// if annotations are inherited these have been checked during STB.resolveTypesFor() (for methods explicit in this.type)
+		AbstractMethodDeclaration srcMethod = null;
+		if (this.type.equals(currentMethod.declaringClass)) // is currentMethod from the current type?
+			srcMethod = currentMethod.sourceMethod();
+		boolean hasNonNullDefault = currentMethod.hasNonNullDefault();
+		for (int i = length; --i >= 0;)
+			if (!currentMethod.isStatic() && !methods[i].isStatic())
+				checkNullSpecInheritance(currentMethod, srcMethod, hasNonNullDefault, true, methods[i], this.type.scope, null);
+	}
+}
+
+void checkNullSpecInheritance(MethodBinding currentMethod, AbstractMethodDeclaration srcMethod, 
+		boolean hasNonNullDefault, boolean complain, MethodBinding inheritedMethod, Scope scope, InheritedNonNullnessInfo[] inheritedNonNullnessInfos)
+{
+	complain &= !currentMethod.isConstructor();
+	if (!hasNonNullDefault && !complain && !this.environment.globalOptions.inheritNullAnnotations) {
+		// nothing to be done, take the shortcut
+		currentMethod.tagBits |= TagBits.IsNullnessKnown;
+		return;
+	}
+	// in this context currentMethod can be inherited, too. Recurse if needed.
+	if (currentMethod.declaringClass != this.type 
+			&& (currentMethod.tagBits & TagBits.IsNullnessKnown) == 0) 
+	{
+		this.buddyImplicitNullAnnotationsVerifier.checkImplicitNullAnnotations(currentMethod, srcMethod, complain, this.type.scope);
+	}
+	super.checkNullSpecInheritance(currentMethod, srcMethod, hasNonNullDefault, complain, inheritedMethod, scope, inheritedNonNullnessInfos);
+}
+
+void reportRawReferences() {
+	CompilerOptions compilerOptions = this.type.scope.compilerOptions();
+	if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5 // shouldn't whine at all
+			|| compilerOptions.reportUnavoidableGenericTypeProblems) { // must have already whined 
+		return;
+	}
+	/* Code below is only for a method that does not override/implement a super type method. If it were to,
+	   it would have been handled in checkAgainstInheritedMethods.
+	*/
+	Object [] methodArray = this.currentMethods.valueTable;
+	for (int s = methodArray.length; --s >= 0;) {
+		if (methodArray[s] == null) continue;
+		MethodBinding[] current = (MethodBinding[]) methodArray[s];
+		for (int i = 0, length = current.length; i < length; i++) {
+			MethodBinding currentMethod = current[i];
+			if ((currentMethod.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) == 0) {
+				AbstractMethodDeclaration methodDecl = currentMethod.sourceMethod();
+				if (methodDecl == null) return;
+				TypeBinding [] parameterTypes = currentMethod.parameters;
+				Argument[] arguments = methodDecl.arguments;
+				for (int j = 0, size = currentMethod.parameters.length; j < size; j++) {
+					TypeBinding parameterType = parameterTypes[j];
+					Argument arg = arguments[j];
+					if (parameterType.leafComponentType().isRawType()
+						&& compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore
+			      		&& (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0) {
+						methodDecl.scope.problemReporter().rawTypeReference(arg.type, parameterType);
+			    	}
+				}
+				if (!methodDecl.isConstructor() && methodDecl instanceof MethodDeclaration) {
+					TypeReference returnType = ((MethodDeclaration) methodDecl).returnType;
+					TypeBinding methodType = currentMethod.returnType;
+					if (returnType != null) {
+						if (methodType.leafComponentType().isRawType()
+								&& compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore
+								&& (returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0) {
+							methodDecl.scope.problemReporter().rawTypeReference(returnType, methodType);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+public void reportRawReferences(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	CompilerOptions compilerOptions = this.type.scope.compilerOptions();
+	if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5 // shouldn't whine at all
+			|| compilerOptions.reportUnavoidableGenericTypeProblems) { // must have already whined 
+		return;
+	}
+	AbstractMethodDeclaration methodDecl = currentMethod.sourceMethod();
+	if (methodDecl == null) return;
+	TypeBinding [] parameterTypes = currentMethod.parameters;
+	TypeBinding [] inheritedParameterTypes = inheritedMethod.parameters;
+	Argument[] arguments = methodDecl.arguments;
+	for (int j = 0, size = currentMethod.parameters.length; j < size; j++) {
+		TypeBinding parameterType = parameterTypes[j];
+		TypeBinding inheritedParameterType = inheritedParameterTypes[j];
+		Argument arg = arguments[j];
+		if (parameterType.leafComponentType().isRawType()) {
+			if (inheritedParameterType.leafComponentType().isRawType()) {
+				arg.binding.tagBits |= TagBits.ForcedToBeRawType;
+			} else {
+				if (compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore
+						&& (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0) {
+					methodDecl.scope.problemReporter().rawTypeReference(arg.type, parameterType);
+				}
+			}
+    	}
+    }
+	TypeReference returnType = null;
+	if (!methodDecl.isConstructor() && methodDecl instanceof MethodDeclaration && (returnType = ((MethodDeclaration) methodDecl).returnType) != null) {
+		final TypeBinding inheritedMethodType = inheritedMethod.returnType;
+		final TypeBinding methodType = currentMethod.returnType;
+		if (methodType.leafComponentType().isRawType()) {
+			if (inheritedMethodType.leafComponentType().isRawType()) {
+				// 
+			} else {
+				if ((returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0
+						&& compilerOptions.getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore) {
+					methodDecl.scope.problemReporter().rawTypeReference(returnType, methodType);
+				}
+			}
+		}
+	}
+ }
+
+void checkMethods() {
+	boolean mustImplementAbstractMethods = mustImplementAbstractMethods();
+	boolean skipInheritedMethods = mustImplementAbstractMethods && canSkipInheritedMethods(); // have a single concrete superclass so only check overridden methods
+	boolean isOrEnclosedByPrivateType = this.type.isOrEnclosedByPrivateType();
+	char[][] methodSelectors = this.inheritedMethods.keyTable;
+	nextSelector : for (int s = methodSelectors.length; --s >= 0;) {
+		if (methodSelectors[s] == null) continue nextSelector;
+
+		MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(methodSelectors[s]);
+		MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s];
+		// ensure that if we have a concrete method this shows up at position [0]:
+		inherited = Sorting.concreteFirst(inherited, inherited.length);
+		
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
+		// inherited methods of super classes are too. current != null case handled below.
+		if (current == null && !isOrEnclosedByPrivateType) {
+			int length = inherited.length;
+			for (int i = 0; i < length; i++){
+				inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+			}
+		}
+		if (current == null && this.type.isPublic()) {
+			int length = inherited.length;
+			for (int i = 0; i < length; i++) {
+				MethodBinding inheritedMethod = inherited[i];
+				if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic())
+					this.type.addSyntheticBridgeMethod(inheritedMethod.original());
+			}
+		}
+
+		if (current == null && skipInheritedMethods)
+			continue nextSelector;
+
+		if (inherited.length == 1 && current == null) { // handle the common case
+			if (mustImplementAbstractMethods && inherited[0].isAbstract())
+				checkAbstractMethod(inherited[0]);
+			continue nextSelector;
+		}
+
+		int index = -1;
+		int inheritedLength = inherited.length;
+		MethodBinding[] matchingInherited = new MethodBinding[inheritedLength];
+		MethodBinding[] foundMatch = new MethodBinding[inheritedLength]; // null is no match, otherwise value is matching currentMethod
+
+		// skip tracks inherited methods which can be safely ignored for one of these reasons:
+		// - methods that have matched other inherited methods
+		// 		either because they match the same currentMethod or match each other
+		// - methods that are overridden by a current method
+		boolean[] skip = new boolean[inheritedLength];
+		boolean[] isOverridden = new boolean[inheritedLength];
+		if (current != null) {
+			for (int i = 0, length1 = current.length; i < length1; i++) {
+				MethodBinding currentMethod = current[i];
+				MethodBinding[] nonMatchingInherited = null;
+				for (int j = 0; j < inheritedLength; j++) {
+					MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
+					if (inheritedMethod != null) {
+						if (foundMatch[j] == null && isSubstituteParameterSubsignature(currentMethod, inheritedMethod)) {
+							// already checked compatibility, do visibility etc. also indicate overriding? If so ignore inheritedMethod further downstream
+							isOverridden[j] = skip[j] = couldMethodOverride(currentMethod, inheritedMethod);
+							matchingInherited[++index] = inheritedMethod;
+							foundMatch[j] = currentMethod;
+						} else {
+							// best place to check each currentMethod against each non-matching inheritedMethod
+							checkForNameClash(currentMethod, inheritedMethod);
+							if (inheritedLength > 1) {
+								if (nonMatchingInherited == null)
+									nonMatchingInherited = new MethodBinding[inheritedLength];
+								nonMatchingInherited[j] = inheritedMethod;
+							}
+						}
+					}
+				}
+				if (index >= 0) {
+					// see addtional comments in https://bugs.eclipse.org/bugs/show_bug.cgi?id=122881
+					// if (index > 0 && currentMethod.declaringClass.isInterface()) // only check when inherited methods are from interfaces
+					//	checkInheritedReturnTypes(matchingInherited, index + 1);
+					checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1, nonMatchingInherited); // pass in the length of matching
+					while (index >= 0) matchingInherited[index--] = null; // clear the contents of the matching methods
+				}
+			}
+		}
+		// first round: collect information into skip and isOverridden by comparing all pairs:
+		// (and perform some side effects : bridge methods & use flags)
+		for (int i = 0; i < inheritedLength; i++) {
+			MethodBinding matchMethod = foundMatch[i];
+			if (matchMethod == null && current != null && this.type.isPublic()) { // current == null case handled already.
+				MethodBinding inheritedMethod = inherited[i];
+				if (inheritedMethod.isPublic() && !inheritedMethod.declaringClass.isPublic()) {
+					this.type.addSyntheticBridgeMethod(inheritedMethod.original());
+				}
+			}
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660, if current type is exposed,
+			// inherited methods of super classes are too. current == null case handled already.
+			if (!isOrEnclosedByPrivateType && matchMethod == null && current != null) {
+				inherited[i].original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;	
+			}
+			MethodBinding inheritedMethod = inherited[i];
+			for (int j = i + 1; j < inheritedLength; j++) {
+				MethodBinding otherInheritedMethod = inherited[j];
+				if (matchMethod == foundMatch[j] && matchMethod != null)
+					continue; // both inherited methods matched the same currentMethod
+				if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
+					continue;
+				// Skip the otherInheritedMethod if it is completely replaced by inheritedMethod
+				// This elimination used to happen rather eagerly in computeInheritedMethods step
+				// itself earlier. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358)
+				if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass) {
+					// these method calls produce their effect as side-effects into skip and isOverridden:
+					if (isSkippableOrOverridden(inheritedMethod, otherInheritedMethod, skip, isOverridden, j))
+						continue;
+					if (isSkippableOrOverridden(otherInheritedMethod, inheritedMethod, skip, isOverridden, i))
+						continue;
+				}
+			}
+		}
+		// second round: collect and check matchingInherited, directly check methods with no replacing etc.
+		for (int i = 0; i < inheritedLength; i++) {
+			MethodBinding matchMethod = foundMatch[i];
+			if (skip[i]) continue;
+			MethodBinding inheritedMethod = inherited[i];
+			if (matchMethod == null)
+				matchingInherited[++index] = inheritedMethod;
+			for (int j = i + 1; j < inheritedLength; j++) {
+				if (foundMatch[j] == null) {
+					MethodBinding otherInheritedMethod = inherited[j];
+					if (matchMethod == foundMatch[j] && matchMethod != null)
+						continue; // both inherited methods matched the same currentMethod
+					if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
+						continue;
+
+					MethodBinding replaceMatch;
+					if ((replaceMatch = findReplacedMethod(inheritedMethod, otherInheritedMethod)) != null) {
+						matchingInherited[++index] = replaceMatch;
+						skip[j] = true;
+					} else if ((replaceMatch = findReplacedMethod(otherInheritedMethod, inheritedMethod)) != null) {
+						matchingInherited[++index] = replaceMatch;
+						skip[j] = true;						
+					} else if (matchMethod == null) {
+						// none replaced by the other, check these methods against each other now:
+						checkInheritedMethods(inheritedMethod, otherInheritedMethod);
+					}
+				}
+			}
+			if (index == -1) continue;
+
+			if (index > 0)
+				checkInheritedMethods(matchingInherited, index + 1, isOverridden); // pass in the length of matching
+			else if (mustImplementAbstractMethods && matchingInherited[0].isAbstract() && matchMethod == null)
+				checkAbstractMethod(matchingInherited[0]);
+			while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
+		}
+	}
+}
+/* mark as skippable
+ * - any interface method implemented by a class method
+ * - an x method (x in {class, interface}), for which another x method with a subsignature was found
+ * mark as isOverridden
+ * - any skippable method as defined above iff it is actually overridden by the specific method (disregarding visibility etc.)
+ * Note, that 'idx' corresponds to the position of 'general' in the arrays 'skip' and 'isOverridden'
+ */
+boolean isSkippableOrOverridden(MethodBinding specific, MethodBinding general, boolean[] skip, boolean[] isOverridden, int idx) {
+	boolean specificIsInterface = specific.declaringClass.isInterface();
+	boolean generalIsInterface = general.declaringClass.isInterface();
+	if (!specificIsInterface && generalIsInterface) {
+		if (isInterfaceMethodImplemented(general, specific, general.declaringClass)) {
+			skip[idx] = true;
+			isOverridden[idx] = true;
+			return true;
+		}
+	} else if (specificIsInterface == generalIsInterface) { 
+		if (isParameterSubsignature(specific, general)) {
+			skip[idx] = true;
+			isOverridden[idx] |= specific.declaringClass.isCompatibleWith(general.declaringClass);
+			return true;
+		}
+	}
+	return false;
+}
+/* 'general' is considered as replaced by 'specific' if
+ * - 'specific' is "at least as concrete as" 'general'
+ * - 'specific' has a signature that is a subsignature of the substituted signature of 'general' (as seen from specific's declaring class)  
+ */
+MethodBinding findReplacedMethod(MethodBinding specific, MethodBinding general) {
+	MethodBinding generalSubstitute = computeSubstituteMethod(general, specific);
+	if (generalSubstitute != null 
+			&& (!specific.isAbstract() || general.isAbstract())	// if (abstract(specific) => abstract(general)) check if 'specific' overrides 'general' 
+			&& isSubstituteParameterSubsignature(specific, generalSubstitute)) 
+	{
+		return generalSubstitute;
+	} 
+	return null;
+}
+void checkTypeVariableMethods(TypeParameter typeParameter) {
+	char[][] methodSelectors = this.inheritedMethods.keyTable;
+	nextSelector : for (int s = methodSelectors.length; --s >= 0;) {
+		if (methodSelectors[s] == null) continue nextSelector;
+		MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s];
+		if (inherited.length == 1) continue nextSelector;
+
+		int index = -1;
+		MethodBinding[] matchingInherited = new MethodBinding[inherited.length];
+		for (int i = 0, length = inherited.length; i < length; i++) {
+			while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
+			MethodBinding inheritedMethod = inherited[i];
+			if (inheritedMethod != null) {
+				matchingInherited[++index] = inheritedMethod;
+				for (int j = i + 1; j < length; j++) {
+					MethodBinding otherInheritedMethod = inherited[j];
+					if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
+						continue;
+					otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
+					if (otherInheritedMethod != null && isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
+						matchingInherited[++index] = otherInheritedMethod;
+						inherited[j] = null; // do not want to find it again
+					}
+				}
+			}
+			if (index > 0) {
+				MethodBinding first = matchingInherited[0];
+				int count = index + 1;
+				while (--count > 0) {
+					MethodBinding match = matchingInherited[count];
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=314556
+					MethodBinding interfaceMethod = null, implementation = null;
+					if (first.declaringClass.isInterface()) {
+						interfaceMethod = first;
+					} else if (first.declaringClass.isClass()) {
+						implementation = first;
+					}
+					if (match.declaringClass.isInterface()) {
+						interfaceMethod = match;
+					} else if (match.declaringClass.isClass()) {
+						implementation = match;
+					}
+					if (interfaceMethod != null && implementation != null && !isAsVisible(implementation, interfaceMethod))
+						problemReporter().inheritedMethodReducesVisibility(typeParameter, implementation, new MethodBinding [] {interfaceMethod});
+					
+					if (areReturnTypesCompatible(first, match)) continue;
+					// unrelated interfaces - check to see if return types are compatible
+					if (first.declaringClass.isInterface() && match.declaringClass.isInterface() && areReturnTypesCompatible(match, first))
+						continue;
+					break;
+				}
+				if (count > 0) {  // All inherited methods do NOT have the same vmSignature
+					problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(typeParameter, matchingInherited, index + 1);
+					continue nextSelector;
+				}
+			}
+		}
+	}
+}
+boolean detectInheritedNameClash(MethodBinding inherited, MethodBinding otherInherited) {
+	if (!inherited.areParameterErasuresEqual(otherInherited))
+		return false;
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322001
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323693
+	// When reporting a name clash between two inherited methods, we should not look for a
+	// signature clash, but instead should be looking for method descriptor clash. 
+	if (inherited.returnType.erasure() != otherInherited.returnType.erasure())
+		return false;
+	// skip it if otherInherited is defined by a subtype of inherited's declaringClass or vice versa.
+	// avoid being order sensitive and check with the roles reversed also.
+	if (inherited.declaringClass.erasure() != otherInherited.declaringClass.erasure()) {
+		if (inherited.declaringClass.findSuperTypeOriginatingFrom(otherInherited.declaringClass) != null)
+			return false;
+		if (otherInherited.declaringClass.findSuperTypeOriginatingFrom(inherited.declaringClass) != null)
+			return false;
+	}
+
+	problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited);
+	return true;
+}
+boolean detectNameClash(MethodBinding current, MethodBinding inherited, boolean treatAsSynthetic) {
+	MethodBinding methodToCheck = inherited;
+	MethodBinding original = methodToCheck.original(); // can be the same as inherited
+	if (!current.areParameterErasuresEqual(original))
+		return false;
+	int severity = ProblemSeverities.Error;
+	if (this.environment.globalOptions.complianceLevel == ClassFileConstants.JDK1_6) {
+		// for 1.6 return types also need to be checked
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719
+		if (current.returnType.erasure() != original.returnType.erasure())
+			severity = ProblemSeverities.Warning;
+	}
+	if (!treatAsSynthetic) {
+		// For a user method, see if current class overrides the inherited method. If it does,
+		// then any grievance we may have ought to be against the current class's method and
+		// NOT against any super implementations. https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615
+		
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=315978 : we now defer this rather expensive
+		// check to just before reporting (the incorrect) name clash. In the event there is no name
+		// clash to report to begin with (the common case), no penalty needs to be paid.  
+		MethodBinding[] currentNamesakes = (MethodBinding[]) this.currentMethods.get(inherited.selector);
+		if (currentNamesakes.length > 1) { // we know it ought to at least one and that current is NOT the override
+			for (int i = 0, length = currentNamesakes.length; i < length; i++) {
+				MethodBinding currentMethod = currentNamesakes[i];
+				if (currentMethod != current && doesMethodOverride(currentMethod, inherited)) {
+					methodToCheck = currentMethod;
+					break;
+				}
+			}
+		}
+	}
+	original = methodToCheck.original(); // can be the same as inherited
+	if (!current.areParameterErasuresEqual(original))
+		return false;
+	original = inherited.original();  // For error reporting use, inherited.original()
+	problemReporter(current).methodNameClash(current, inherited.declaringClass.isRawType() ? inherited : original, severity);
+	if (severity == ProblemSeverities.Warning) return false;
+	return true;
+}
+boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) {
+	// one has type variables and substituteTwo did not pass bounds check in computeSubstituteMethod()
+	return one.typeVariables != Binding.NO_TYPE_VARIABLES && !(substituteTwo instanceof ParameterizedGenericMethodBinding);
+}
+SimpleSet findSuperinterfaceCollisions(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
+	ReferenceBinding[] interfacesToVisit = null;
+	int nextPosition = 0;
+	ReferenceBinding[] itsInterfaces = superInterfaces;
+	if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+		nextPosition = itsInterfaces.length;
+		interfacesToVisit = itsInterfaces;
+	}
+
+	boolean isInconsistent = this.type.isHierarchyInconsistent();
+	ReferenceBinding superType = superclass;
+	while (superType != null && superType.isValidBinding()) {
+		isInconsistent |= superType.isHierarchyInconsistent();
+		if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+			if (interfacesToVisit == null) {
+				interfacesToVisit = itsInterfaces;
+				nextPosition = interfacesToVisit.length;
+			} else {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+		superType = superType.superclass();
+	}
+
+	for (int i = 0; i < nextPosition; i++) {
+		superType = interfacesToVisit[i];
+		if (superType.isValidBinding()) {
+			isInconsistent |= superType.isHierarchyInconsistent();
+			if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+	}
+
+	if (!isInconsistent) return null; // hierarchy is consistent so no collisions are possible
+	SimpleSet copy = null;
+	for (int i = 0; i < nextPosition; i++) {
+		ReferenceBinding current = interfacesToVisit[i];
+		if (current.isValidBinding()) {
+			TypeBinding erasure = current.erasure();
+			for (int j = i + 1; j < nextPosition; j++) {
+				ReferenceBinding next = interfacesToVisit[j];
+				if (next.isValidBinding() && next.erasure() == erasure) {
+					if (copy == null)
+						copy = new SimpleSet(nextPosition);
+					copy.add(interfacesToVisit[i]);
+					copy.add(interfacesToVisit[j]);
+				}
+			}
+		}
+	}
+	return copy;
+}
+boolean isAcceptableReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	// called when currentMethod's return type is compatible with inheritedMethod's return type
+
+	if (inheritedMethod.declaringClass.isRawType())
+		return true; // since the inheritedMethod comes from a raw type, the return type is always acceptable
+
+	MethodBinding originalInherited = inheritedMethod.original();
+	TypeBinding originalInheritedReturnType = originalInherited.returnType.leafComponentType();
+	if (originalInheritedReturnType.isParameterizedTypeWithActualArguments())
+		return !currentMethod.returnType.leafComponentType().isRawType(); // raw types issue a warning if inherited is parameterized
+
+	TypeBinding currentReturnType = currentMethod.returnType.leafComponentType();
+	switch (currentReturnType.kind()) {
+	   	case Binding.TYPE_PARAMETER :
+	   		if (currentReturnType == inheritedMethod.returnType.leafComponentType())
+	   			return true;
+	   		//$FALL-THROUGH$
+		default :
+			if (originalInheritedReturnType.isTypeVariable())
+				if (((TypeVariableBinding) originalInheritedReturnType).declaringElement == originalInherited)
+					return false;
+			return true;
+	}
+}
+// caveat: returns false if a method is implemented that needs a bridge method
+boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
+	if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface())
+		return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary
+
+	inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
+	return inheritedMethod != null
+		&& (inheritedMethod.returnType == existingMethod.returnType	// need to keep around to produce bridge methods? ...
+			|| (this.type != existingMethod.declaringClass 			// ... not if inheriting the bridge situation from a superclass
+					&& !existingMethod.declaringClass.isInterface()))
+		&& doesMethodOverride(existingMethod, inheritedMethod);
+}
+public boolean isMethodSubsignature(MethodBinding method, MethodBinding inheritedMethod) {
+	if (!org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector))
+		return false;
+
+	// need to switch back to the original if the method is from a ParameterizedType
+	if (method.declaringClass.isParameterizedType())
+		method = method.original();
+
+	MethodBinding inheritedOriginal = method.findOriginalInheritedMethod(inheritedMethod);
+	return isParameterSubsignature(method, inheritedOriginal == null ? inheritedMethod : inheritedOriginal);
+}
+boolean isUnsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	// called when currentMethod's return type is NOT compatible with inheritedMethod's return type
+
+	// JLS 3 �8.4.5: more are accepted, with an unchecked conversion
+	if (currentMethod.returnType == inheritedMethod.returnType.erasure()) {
+		TypeBinding[] currentParams = currentMethod.parameters;
+		TypeBinding[] inheritedParams = inheritedMethod.parameters;
+		for (int i = 0, l = currentParams.length; i < l; i++)
+			if (!areTypesEqual(currentParams[i], inheritedParams[i]))
+				return true;
+	}
+	if (currentMethod.typeVariables == Binding.NO_TYPE_VARIABLES
+		&& inheritedMethod.original().typeVariables != Binding.NO_TYPE_VARIABLES
+		&& currentMethod.returnType.erasure().findSuperTypeOriginatingFrom(inheritedMethod.returnType.erasure()) != null) {
+			return true;
+	}
+	return false;
+}
+boolean reportIncompatibleReturnTypeError(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	if (isUnsafeReturnTypeOverride(currentMethod, inheritedMethod)) {
+		problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, inheritedMethod, this.type);
+		return false;
+	}
+	return super.reportIncompatibleReturnTypeError(currentMethod, inheritedMethod);
+}
+void verify() {
+	if (this.type.isAnnotationType())
+		this.type.detectAnnotationCycle();
+
+	super.verify();
+	
+	reportRawReferences();
+
+	for (int i = this.type.typeVariables.length; --i >= 0;) {
+		TypeVariableBinding var = this.type.typeVariables[i];
+		// must verify bounds if the variable has more than 1
+		if (var.superInterfaces == Binding.NO_SUPERINTERFACES) continue;
+		if (var.superInterfaces.length == 1 && var.superclass.id == TypeIds.T_JavaLangObject) continue;
+
+		this.currentMethods = new HashtableOfObject(0);
+		ReferenceBinding superclass = var.superclass();
+		if (superclass.kind() == Binding.TYPE_PARAMETER)
+			superclass = (ReferenceBinding) superclass.erasure();
+		ReferenceBinding[] itsInterfaces = var.superInterfaces();
+		ReferenceBinding[] superInterfaces = new ReferenceBinding[itsInterfaces.length];
+		for (int j = itsInterfaces.length; --j >= 0;) {
+			superInterfaces[j] = itsInterfaces[j].kind() == Binding.TYPE_PARAMETER
+				? (ReferenceBinding) itsInterfaces[j].erasure()
+				: itsInterfaces[j];
+		}
+		computeInheritedMethods(superclass, superInterfaces);
+		checkTypeVariableMethods(this.type.scope.referenceContext.typeParameters[i]);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java
new file mode 100644
index 0000000..8b86d8c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MissingTypeBinding.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class MissingTypeBinding extends BinaryTypeBinding {
+
+/**
+ * Special constructor for constructing proxies of missing types (114349)
+ * @param packageBinding
+ * @param compoundName
+ * @param environment
+ */
+public MissingTypeBinding(PackageBinding packageBinding, char[][] compoundName, LookupEnvironment environment) {
+	this.compoundName = compoundName;
+	computeId();
+	this.tagBits |= TagBits.IsBinaryBinding | TagBits.HierarchyHasProblems | TagBits.HasMissingType;
+	this.environment = environment;
+	this.fPackage = packageBinding;
+	this.fileName = CharOperation.concatWith(compoundName, '/');
+	this.sourceName = compoundName[compoundName.length - 1]; // [java][util][Map$Entry]
+	this.modifiers = ClassFileConstants.AccPublic;
+	this.superclass = null; // will be fixed up using #setMissingSuperclass(...)
+	this.superInterfaces = Binding.NO_SUPERINTERFACES;
+	this.typeVariables = Binding.NO_TYPE_VARIABLES;
+	this.memberTypes = Binding.NO_MEMBER_TYPES;
+	this.fields = Binding.NO_FIELDS;
+	this.methods = Binding.NO_METHODS;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#collectMissingTypes(java.util.List)
+ */
+public List collectMissingTypes(List missingTypes) {
+	if (missingTypes == null) {
+		missingTypes = new ArrayList(5);
+	} else if (missingTypes.contains(this)) {
+		return missingTypes;
+	}
+	missingTypes.add(this);
+	return missingTypes;
+}
+
+/**
+ * Missing binary type will answer <code>false</code> to #isValidBinding()
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#problemId()
+ */
+public int problemId() {
+	return ProblemReasons.NotFound;
+}
+
+/**
+ * Only used to fixup the superclass hierarchy of proxy binary types
+ * @param missingSuperclass
+ * @see LookupEnvironment#createMissingType(PackageBinding, char[][])
+ */
+void setMissingSuperclass(ReferenceBinding missingSuperclass) {
+	this.superclass = missingSuperclass;
+}
+
+public String toString() {
+		return "[MISSING:" + new String(CharOperation.concatWith(this.compoundName, '.')) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java
new file mode 100644
index 0000000..37d0536
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MostSpecificExceptionMethodBinding.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+/**
+ * Pseudo method binding used to wrapper a real method, and expose less exceptions than original.
+ * For other protocols, it should delegate to original method
+ */
+public class MostSpecificExceptionMethodBinding  extends MethodBinding {
+
+	private MethodBinding originalMethod;
+	
+	public MostSpecificExceptionMethodBinding (MethodBinding originalMethod, ReferenceBinding[] mostSpecificExceptions) {
+		super(
+				originalMethod.modifiers, 
+				originalMethod.selector, 
+				originalMethod.returnType, 
+				originalMethod.parameters, 
+				mostSpecificExceptions, 
+				originalMethod.declaringClass);
+		this.originalMethod = originalMethod;
+		this.parameterNonNullness = originalMethod.parameterNonNullness;
+	}
+	
+	public MethodBinding original() {
+		return this.originalMethod.original();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
new file mode 100644
index 0000000..2e5b7c2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for  bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *     Keigo Imai - Contribution for  bug 388903 - Cannot extend inner class as an anonymous class when it extends the outer class
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+
+public class NestedTypeBinding extends SourceTypeBinding {
+
+	public SourceTypeBinding enclosingType;
+
+	public SyntheticArgumentBinding[] enclosingInstances;
+	private ReferenceBinding[] enclosingTypes = Binding.UNINITIALIZED_REFERENCE_TYPES;
+	public SyntheticArgumentBinding[] outerLocalVariables;
+	private int outerLocalVariablesSlotSize = -1; // amount of slots used by synthetic outer local variables
+
+public NestedTypeBinding(char[][] typeName, ClassScope scope, SourceTypeBinding enclosingType) {
+	super(typeName, enclosingType.fPackage, scope);
+	this.tagBits |= (TagBits.IsNestedType | TagBits.ContainsNestedTypeReferences);
+	this.enclosingType = enclosingType;
+}
+
+/* Add a new synthetic argument for <actualOuterLocalVariable>.
+* Answer the new argument or the existing argument if one already existed.
+*/
+public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
+	SyntheticArgumentBinding synthLocal = null;
+
+	if (this.outerLocalVariables == null) {
+		synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
+		this.outerLocalVariables = new SyntheticArgumentBinding[] {synthLocal};
+	} else {
+		int size = this.outerLocalVariables.length;
+		int newArgIndex = size;
+		for (int i = size; --i >= 0;) {		// must search backwards
+			if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
+				return this.outerLocalVariables[i];	// already exists
+			if (this.outerLocalVariables[i].id > actualOuterLocalVariable.id)
+				newArgIndex = i;
+		}
+		SyntheticArgumentBinding[] synthLocals = new SyntheticArgumentBinding[size + 1];
+		System.arraycopy(this.outerLocalVariables, 0, synthLocals, 0, newArgIndex);
+		synthLocals[newArgIndex] = synthLocal = new SyntheticArgumentBinding(actualOuterLocalVariable);
+		System.arraycopy(this.outerLocalVariables, newArgIndex, synthLocals, newArgIndex + 1, size - newArgIndex);
+		this.outerLocalVariables = synthLocals;
+	}
+	//System.out.println("Adding synth arg for local var: " + new String(actualOuterLocalVariable.name) + " to: " + new String(this.readableName()));
+	if (this.scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
+		updateInnerEmulationDependents();
+	return synthLocal;
+}
+
+/* Add a new synthetic argument for <enclosingType>.
+* Answer the new argument or the existing argument if one already existed.
+*/
+public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding targetEnclosingType) {
+	SyntheticArgumentBinding synthLocal = null;
+	if (this.enclosingInstances == null) {
+		synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
+		this.enclosingInstances = new SyntheticArgumentBinding[] {synthLocal};
+	} else {
+		int size = this.enclosingInstances.length;
+		int newArgIndex = size;
+		if (enclosingType() == targetEnclosingType)
+			newArgIndex = 0;
+		SyntheticArgumentBinding[] newInstances = new SyntheticArgumentBinding[size + 1];
+		System.arraycopy(this.enclosingInstances, 0, newInstances, newArgIndex == 0 ? 1 : 0, size);
+		newInstances[newArgIndex] = synthLocal = new SyntheticArgumentBinding(targetEnclosingType);
+		this.enclosingInstances = newInstances;
+	}
+	//System.out.println("Adding synth arg for enclosing type: " + new String(enclosingType.readableName()) + " to: " + new String(this.readableName()));
+	if (this.scope.referenceCompilationUnit().isPropagatingInnerClassEmulation)
+		updateInnerEmulationDependents();
+	return synthLocal;
+}
+
+/* Add a new synthetic argument and field for <actualOuterLocalVariable>.
+* Answer the new argument or the existing argument if one already existed.
+*/
+public SyntheticArgumentBinding addSyntheticArgumentAndField(LocalVariableBinding actualOuterLocalVariable) {
+	SyntheticArgumentBinding synthLocal = addSyntheticArgument(actualOuterLocalVariable);
+	if (synthLocal == null) return null;
+
+	if (synthLocal.matchingField == null)
+		synthLocal.matchingField = addSyntheticFieldForInnerclass(actualOuterLocalVariable);
+	return synthLocal;
+}
+
+/* Add a new synthetic argument and field for <enclosingType>.
+* Answer the new argument or the existing argument if one already existed.
+*/
+public SyntheticArgumentBinding addSyntheticArgumentAndField(ReferenceBinding targetEnclosingType) {
+	SyntheticArgumentBinding synthLocal = addSyntheticArgument(targetEnclosingType);
+	if (synthLocal == null) return null;
+
+	if (synthLocal.matchingField == null)
+		synthLocal.matchingField = addSyntheticFieldForInnerclass(targetEnclosingType);
+	return synthLocal;
+}
+
+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
+	ReferenceBinding currentType = this.enclosingType;
+	do {
+		if (!((SourceTypeBinding)currentType).checkRedundantNullnessDefaultOne(location, annotations, annotationTagBits)) {
+			return;
+		}
+		currentType = currentType.enclosingType();
+	} while (currentType instanceof SourceTypeBinding);
+	super.checkRedundantNullnessDefaultRecurse(location, annotations, annotationTagBits);
+}
+
+/* Answer the receiver's enclosing type... null if the receiver is a top level type.
+*/
+public ReferenceBinding enclosingType() {
+	return this.enclosingType;
+}
+
+/**
+ * @return the enclosingInstancesSlotSize
+ */
+public int getEnclosingInstancesSlotSize() {
+	return this.enclosingInstances == null ? 0 : this.enclosingInstances.length;
+}
+
+/**
+ * @return the outerLocalVariablesSlotSize
+ */
+public int getOuterLocalVariablesSlotSize() {
+	if (this.outerLocalVariablesSlotSize < 0) {
+		this.outerLocalVariablesSlotSize = 0;
+		int outerLocalsCount = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length;
+			for (int i = 0; i < outerLocalsCount; i++){
+			SyntheticArgumentBinding argument = this.outerLocalVariables[i];
+			switch (argument.type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					this.outerLocalVariablesSlotSize  += 2;
+					break;
+				default :
+					this.outerLocalVariablesSlotSize  ++;
+					break;
+			}		
+		}
+	}
+	return this.outerLocalVariablesSlotSize;
+}
+
+/* Answer the synthetic argument for <actualOuterLocalVariable> or null if one does not exist.
+*/
+public SyntheticArgumentBinding getSyntheticArgument(LocalVariableBinding actualOuterLocalVariable) {
+	if (this.outerLocalVariables == null) return null;		// is null if no outer local variables are known
+	for (int i = this.outerLocalVariables.length; --i >= 0;)
+		if (this.outerLocalVariables[i].actualOuterLocalVariable == actualOuterLocalVariable)
+			return this.outerLocalVariables[i];
+	return null;
+}
+
+/* Answer the synthetic argument for <targetEnclosingType> or null if one does not exist.
+*/
+public SyntheticArgumentBinding getSyntheticArgument(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean scopeIsConstructorCall) {
+	if (this.enclosingInstances == null) return null;		// is null if no enclosing instances are known
+	
+	// exact match
+	
+	// firstly, during allocation, check and use the leftmost one (if possible) 
+	// to handle cases involving two instances of same type, such as
+	// class X {
+	//   class Inner extends X {}
+	//   void f(){
+	//     new X().new Inner(){} 
+	//     // here the result of (new X()) is passed as the first (synthetic) arg for ctor of new Inner(){}
+	//     // (and (this) as the second, of course) 
+	//   }
+	// }
+	if (scopeIsConstructorCall && this.enclosingInstances.length > 0)
+		if (this.enclosingInstances[0].type == targetEnclosingType) 
+			if (this.enclosingInstances[0].actualOuterLocalVariable == null)
+				return this.enclosingInstances[0];
+	
+	// then check other possibility
+	for (int i = this.enclosingInstances.length; --i >= 0;)
+		if (this.enclosingInstances[i].type == targetEnclosingType)
+			if (this.enclosingInstances[i].actualOuterLocalVariable == null)
+				return this.enclosingInstances[i];
+
+	// type compatibility : to handle cases such as
+	// class T { class M{}}
+	// class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
+	if (!onlyExactMatch){
+		for (int i = this.enclosingInstances.length; --i >= 0;)
+			if (this.enclosingInstances[i].actualOuterLocalVariable == null)
+				if (this.enclosingInstances[i].type.findSuperTypeOriginatingFrom(targetEnclosingType) != null)
+					return this.enclosingInstances[i];
+	}
+	return null;
+}
+
+public SyntheticArgumentBinding[] syntheticEnclosingInstances() {
+	return this.enclosingInstances;		// is null if no enclosing instances are required
+}
+
+public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
+	if (this.enclosingTypes == UNINITIALIZED_REFERENCE_TYPES) {
+		if (this.enclosingInstances == null) {
+			this.enclosingTypes = null;
+		} else {
+			int length = this.enclosingInstances.length;
+			this.enclosingTypes = new ReferenceBinding[length];
+			for (int i = 0; i < length; i++) {
+				this.enclosingTypes[i] = (ReferenceBinding) this.enclosingInstances[i].type;
+			}
+		}
+	}
+	return this.enclosingTypes;
+}
+
+public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
+	return this.outerLocalVariables;		// is null if no outer locals are required
+}
+
+/*
+ * Trigger the dependency mechanism forcing the innerclass emulation
+ * to be propagated to all dependent source types.
+ */
+public void updateInnerEmulationDependents() {
+	// nothing to do in general, only local types are doing anything
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
new file mode 100644
index 0000000..f139509
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfType;
+
+public class PackageBinding extends Binding implements TypeConstants {
+	public long tagBits = 0; // See values in the interface TagBits below
+
+	public char[][] compoundName;
+	PackageBinding parent;
+	public LookupEnvironment environment;
+	HashtableOfType knownTypes;
+	HashtableOfPackage knownPackages;
+
+	// code representing the default that has been defined for this package (using @NonNullByDefault)
+	// one of Binding.{NO_NULL_DEFAULT,NULL_UNSPECIFIED_BY_DEFAULT,NONNULL_BY_DEFAULT}
+	protected int defaultNullness = NO_NULL_DEFAULT;
+
+protected PackageBinding() {
+	// for creating problem package
+}
+public PackageBinding(char[] topLevelPackageName, LookupEnvironment environment) {
+	this(new char[][] {topLevelPackageName}, null, environment);
+}
+/* Create the default package.
+*/
+public PackageBinding(char[][] compoundName, PackageBinding parent, LookupEnvironment environment) {
+	this.compoundName = compoundName;
+	this.parent = parent;
+	this.environment = environment;
+	this.knownTypes = null; // initialized if used... class counts can be very large 300-600
+	this.knownPackages = new HashtableOfPackage(3); // sub-package counts are typically 0-3
+	if (compoundName != CharOperation.NO_CHAR_CHAR)
+		checkIfNullAnnotationPackage();
+}
+
+public PackageBinding(LookupEnvironment environment) {
+	this(CharOperation.NO_CHAR_CHAR, null, environment);
+}
+private void addNotFoundPackage(char[] simpleName) {
+	this.knownPackages.put(simpleName, LookupEnvironment.TheNotFoundPackage);
+}
+private void addNotFoundType(char[] simpleName) {
+	if (this.knownTypes == null)
+		this.knownTypes = new HashtableOfType(25);
+	this.knownTypes.put(simpleName, LookupEnvironment.TheNotFoundType);
+}
+void addPackage(PackageBinding element) {
+	if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
+	this.knownPackages.put(element.compoundName[element.compoundName.length - 1], element);
+}
+void addType(ReferenceBinding element) {
+	if ((element.tagBits & TagBits.HasMissingType) == 0) clearMissingTagBit();
+	if (this.knownTypes == null)
+		this.knownTypes = new HashtableOfType(25);
+	this.knownTypes.put(element.compoundName[element.compoundName.length - 1], element);
+	if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled)
+		if (element.isAnnotationType() || element instanceof UnresolvedReferenceBinding) // unresolved types don't yet have the modifiers set
+			checkIfNullAnnotationType(element);
+}
+
+void clearMissingTagBit() {
+	PackageBinding current = this;
+	do {
+		current.tagBits &= ~TagBits.HasMissingType;
+	} while ((current = current.parent) != null);
+}
+/*
+ * slash separated name
+ * org.eclipse.jdt.core --> org/eclipse/jdt/core
+ */
+public char[] computeUniqueKey(boolean isLeaf) {
+	return CharOperation.concatWith(this.compoundName, '/');
+}
+private PackageBinding findPackage(char[] name) {
+	if (!this.environment.isPackage(this.compoundName, name))
+		return null;
+
+	char[][] subPkgCompoundName = CharOperation.arrayConcat(this.compoundName, name);
+	PackageBinding subPackageBinding = new PackageBinding(subPkgCompoundName, this, this.environment);
+	addPackage(subPackageBinding);
+	return subPackageBinding;
+}
+/* Answer the subpackage named name; ask the oracle for the package if its not in the cache.
+* Answer null if it could not be resolved.
+*
+* NOTE: This should only be used when we know there is NOT a type with the same name.
+*/
+PackageBinding getPackage(char[] name) {
+	PackageBinding binding = getPackage0(name);
+	if (binding != null) {
+		if (binding == LookupEnvironment.TheNotFoundPackage)
+			return null;
+		else
+			return binding;
+	}
+	if ((binding = findPackage(name)) != null)
+		return binding;
+
+	// not found so remember a problem package binding in the cache for future lookups
+	addNotFoundPackage(name);
+	return null;
+}
+/* Answer the subpackage named name if it exists in the cache.
+* Answer theNotFoundPackage if it could not be resolved the first time
+* it was looked up, otherwise answer null.
+*
+* NOTE: Senders must convert theNotFoundPackage into a real problem
+* package if its to returned.
+*/
+
+PackageBinding getPackage0(char[] name) {
+	return this.knownPackages.get(name);
+}
+/* Answer the type named name; ask the oracle for the type if its not in the cache.
+* Answer a NotVisible problem type if the type is not visible from the invocationPackage.
+* Answer null if it could not be resolved.
+*
+* NOTE: This should only be used by source types/scopes which know there is NOT a
+* package with the same name.
+*/
+
+ReferenceBinding getType(char[] name) {
+	ReferenceBinding referenceBinding = getType0(name);
+	if (referenceBinding == null) {
+		if ((referenceBinding = this.environment.askForType(this, name)) == null) {
+			// not found so remember a problem type binding in the cache for future lookups
+			addNotFoundType(name);
+			return null;
+		}
+	}
+
+	if (referenceBinding == LookupEnvironment.TheNotFoundType)
+		return null;
+
+	referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
+	if (referenceBinding.isNestedType())
+		return new ProblemReferenceBinding(new char[][]{ name }, referenceBinding, ProblemReasons.InternalNameProvided);
+	return referenceBinding;
+}
+/* Answer the type named name if it exists in the cache.
+* Answer theNotFoundType if it could not be resolved the first time
+* it was looked up, otherwise answer null.
+*
+* NOTE: Senders must convert theNotFoundType into a real problem
+* reference type if its to returned.
+*/
+
+ReferenceBinding getType0(char[] name) {
+	if (this.knownTypes == null)
+		return null;
+	return this.knownTypes.get(name);
+}
+/* Answer the package or type named name; ask the oracle if it is not in the cache.
+* Answer null if it could not be resolved.
+*
+* When collisions exist between a type name & a package name, answer the type.
+* Treat the package as if it does not exist... a problem was already reported when the type was defined.
+*
+* NOTE: no visibility checks are performed.
+* THIS SHOULD ONLY BE USED BY SOURCE TYPES/SCOPES.
+*/
+
+public Binding getTypeOrPackage(char[] name) {
+	ReferenceBinding referenceBinding = getType0(name);
+	if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
+		referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this.environment, false /* no raw conversion for now */);
+		if (referenceBinding.isNestedType()) {
+			return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
+		}
+		if ((referenceBinding.tagBits & TagBits.HasMissingType) == 0) {
+			return referenceBinding;
+		}
+		// referenceBinding is a MissingType, will return it if no package is found
+	}
+
+	PackageBinding packageBinding = getPackage0(name);
+	if (packageBinding != null && packageBinding != LookupEnvironment.TheNotFoundPackage) {
+		return packageBinding;
+	}
+	if (referenceBinding == null) { // have not looked for it before
+		if ((referenceBinding = this.environment.askForType(this, name)) != null) {
+			if (referenceBinding.isNestedType()) {
+				return new ProblemReferenceBinding(new char[][]{name}, referenceBinding, ProblemReasons.InternalNameProvided);
+			}
+			return referenceBinding;
+		}
+
+		// Since name could not be found, add a problem binding
+		// to the collections so it will be reported as an error next time.
+		addNotFoundType(name);
+	}
+
+	if (packageBinding == null) { // have not looked for it before
+		if ((packageBinding = findPackage(name)) != null) {
+			return packageBinding;
+		}
+		if (referenceBinding != null && referenceBinding != LookupEnvironment.TheNotFoundType) {
+			return referenceBinding; // found cached missing type - check if package conflict
+		}
+		addNotFoundPackage(name);
+	}
+
+	return null;
+}
+public final boolean isViewedAsDeprecated() {
+	if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
+		this.tagBits |= TagBits.DeprecatedAnnotationResolved;
+		if (this.compoundName != CharOperation.NO_CHAR_CHAR) {
+			ReferenceBinding packageInfo = this.getType(TypeConstants.PACKAGE_INFO_NAME);
+			if (packageInfo != null) {
+				packageInfo.initializeDeprecatedAnnotationTagBits();
+				this.tagBits |= packageInfo.tagBits & TagBits.AllStandardAnnotationsMask;
+			}
+		}
+	}
+	return (this.tagBits & TagBits.AnnotationDeprecated) != 0;
+}
+/* API
+* Answer the receiver's binding type from Binding.BindingID.
+*/
+public final int kind() {
+	return Binding.PACKAGE;
+}
+
+public int problemId() {
+	if ((this.tagBits & TagBits.HasMissingType) != 0)
+		return ProblemReasons.NotFound;
+	return ProblemReasons.NoError;
+}
+
+
+void checkIfNullAnnotationPackage() {
+	LookupEnvironment env = this.environment;
+	if (env.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNullableAnnotationName()))
+			env.nullableAnnotationPackage = this;
+		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullAnnotationName()))
+			env.nonnullAnnotationPackage = this;
+		if (isPackageOfQualifiedTypeName(this.compoundName, env.getNonNullByDefaultAnnotationName()))
+			env.nonnullByDefaultAnnotationPackage = this;
+	}
+}
+
+private boolean isPackageOfQualifiedTypeName(char[][] packageName, char[][] typeName) {
+	int length;
+	if (typeName == null || (length = packageName.length) != typeName.length -1)
+		return false;
+	for (int i=0; i<length; i++)
+		if (!CharOperation.equals(packageName[i], typeName[i]))
+			return false;
+	return true;
+}
+
+void checkIfNullAnnotationType(ReferenceBinding type) {
+	// check if type is one of the configured null annotation types
+	// if so mark as a well known type using the corresponding typeID:
+	if (this.environment.nullableAnnotationPackage == this
+			&& CharOperation.equals(type.compoundName, this.environment.getNullableAnnotationName())) {
+		type.id = TypeIds.T_ConfiguredAnnotationNullable;
+		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
+			this.environment.nullableAnnotationPackage = null; // don't check again
+	} else if (this.environment.nonnullAnnotationPackage == this
+			&& CharOperation.equals(type.compoundName, this.environment.getNonNullAnnotationName())) {
+		type.id = TypeIds.T_ConfiguredAnnotationNonNull;
+		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
+			this.environment.nonnullAnnotationPackage = null; // don't check again
+	} else if (this.environment.nonnullByDefaultAnnotationPackage == this
+			&& CharOperation.equals(type.compoundName, this.environment.getNonNullByDefaultAnnotationName())) {
+		type.id = TypeIds.T_ConfiguredAnnotationNonNullByDefault;
+		if (!(type instanceof UnresolvedReferenceBinding)) // unresolved will need to check back for the resolved type
+			this.environment.nonnullByDefaultAnnotationPackage = null; // don't check again
+	}
+}
+
+public char[] readableName() /*java.lang*/ {
+	return CharOperation.concatWith(this.compoundName, '.');
+}
+public String toString() {
+	String str;
+	if (this.compoundName == CharOperation.NO_CHAR_CHAR) {
+		str = "The Default Package"; //$NON-NLS-1$
+	} else {
+		str = "package " + ((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	if ((this.tagBits & TagBits.HasMissingType) != 0) {
+		str += "[MISSING]"; //$NON-NLS-1$
+	}
+	return str;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
new file mode 100644
index 0000000..4a963a3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+/**
+ * Binding denoting a field after type substitution got performed.
+ * On parameterized type bindings, all fields got substituted, regardless whether
+ * their signature did involve generics or not, so as to get the proper declaringClass for
+ * these fields.
+ */
+public class ParameterizedFieldBinding extends FieldBinding {
+
+    public FieldBinding originalField;
+
+public ParameterizedFieldBinding(ParameterizedTypeBinding parameterizedDeclaringClass, FieldBinding originalField) {
+    super (
+            originalField.name,
+            (originalField.modifiers & ClassFileConstants.AccEnum) != 0
+            	? parameterizedDeclaringClass // enum constant get paramType as its type
+       			: (originalField.modifiers & ClassFileConstants.AccStatic) != 0
+       					? originalField.type // no subst for static field
+       					: Scope.substitute(parameterizedDeclaringClass, originalField.type),
+            originalField.modifiers,
+            parameterizedDeclaringClass,
+            null);
+    this.originalField = originalField;
+    this.tagBits = originalField.tagBits;
+    this.id = originalField.id;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.VariableBinding#constant()
+ */
+public Constant constant() {
+	return this.originalField.constant();
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.FieldBinding#original()
+ */
+public FieldBinding original() {
+	return this.originalField.original();
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.VariableBinding#constant()
+ */
+public void setConstant(Constant constant) {
+	this.originalField.setConstant(constant);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
new file mode 100644
index 0000000..9ca94f4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -0,0 +1,572 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+/**
+ * Binding denoting a generic method after type parameter substitutions got performed.
+ * On parameterized type bindings, all methods got substituted, regardless whether
+ * their signature did involve generics or not, so as to get the proper declaringClass for
+ * these methods.
+ */
+public class ParameterizedGenericMethodBinding extends ParameterizedMethodBinding implements Substitution {
+
+    public TypeBinding[] typeArguments;
+    private LookupEnvironment environment;
+    public boolean inferredReturnType;
+    public boolean wasInferred; // only set to true for instances resulting from method invocation inferrence
+    public boolean isRaw; // set to true for method behaving as raw for substitution purpose
+    private MethodBinding tiebreakMethod;
+
+	/**
+	 * Perform inference of generic method type parameters and/or expected type
+	 */
+	public static MethodBinding computeCompatibleMethod(MethodBinding originalMethod, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite) {
+		ParameterizedGenericMethodBinding methodSubstitute;
+		TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
+		TypeBinding[] substitutes = invocationSite.genericTypeArguments();
+		InferenceContext inferenceContext = null;
+		TypeBinding[] uncheckedArguments = null;
+		computeSubstitutes: {
+			if (substitutes != null) {
+				// explicit type arguments got supplied
+				if (substitutes.length != typeVariables.length) {
+			        // incompatible due to wrong arity
+			        return new ProblemMethodBinding(originalMethod, originalMethod.selector, substitutes, ProblemReasons.TypeParameterArityMismatch);
+				}
+				methodSubstitute = scope.environment().createParameterizedGenericMethod(originalMethod, substitutes);
+				break computeSubstitutes;
+			}
+			// perform type argument inference (15.12.2.7)
+			// initializes the map of substitutes (var --> type[][]{ equal, extends, super}
+			TypeBinding[] parameters = originalMethod.parameters;
+			inferenceContext = new InferenceContext(originalMethod);
+			methodSubstitute = inferFromArgumentTypes(scope, originalMethod, arguments, parameters, inferenceContext);
+			if (methodSubstitute == null)
+				return null;
+			
+			// substitutes may hold null to denote unresolved vars, but null arguments got replaced with respective original variable in param method
+			// 15.12.2.8 - inferring unresolved type arguments
+			if (inferenceContext.hasUnresolvedTypeArgument()) {
+				if (inferenceContext.isUnchecked) { // only remember unchecked status post 15.12.2.7
+					int length = inferenceContext.substitutes.length;
+					System.arraycopy(inferenceContext.substitutes, 0, uncheckedArguments = new TypeBinding[length], 0, length);
+				}
+				if (methodSubstitute.returnType != TypeBinding.VOID) {
+					TypeBinding expectedType = invocationSite.expectedType();
+					if (expectedType != null) {
+						// record it was explicit from context, as opposed to assumed by default (see below)
+						inferenceContext.hasExplicitExpectedType = true;
+					} else {
+						expectedType = scope.getJavaLangObject(); // assume Object by default
+					}
+					inferenceContext.expectedType = expectedType;
+				}
+				methodSubstitute = methodSubstitute.inferFromExpectedType(scope, inferenceContext);
+				if (methodSubstitute == null)
+					return null;
+			}
+		}
+
+		/* bounds check: https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159, Inferred types may contain self reference
+		   in formal bounds. If "T extends I<T>" is a original type variable and T was inferred to be I<T> due possibly
+		   to under constraints and resultant glb application per 15.12.2.8, using this.typeArguments to drive the bounds
+		   check against itself is doomed to fail. For, the variable T would after substitution be I<I<T>> and would fail
+		   bounds check against I<T>. Use the inferred types from the context directly - see that there is one round of
+		   extra substitution that has taken place to properly substitute a remaining unresolved variable which also appears
+		   in a formal bound  (So we really have a bounds mismatch between I<I<T>> and I<I<I<T>>>, in the absence of a fix.)
+		*/
+		Substitution substitution = null;
+		if (inferenceContext != null) {
+			substitution = new LingeringTypeVariableEliminator(typeVariables, inferenceContext.substitutes, scope);
+		} else {
+			substitution = methodSubstitute;
+		}
+		for (int i = 0, length = typeVariables.length; i < length; i++) {
+		    TypeVariableBinding typeVariable = typeVariables[i];
+		    TypeBinding substitute = methodSubstitute.typeArguments[i]; // retain for diagnostics
+		    /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=375394, To avoid spurious bounds check failures due to circularity in formal bounds, 
+		       we should eliminate only the lingering embedded type variable references after substitution, not alien type variable references
+		       that constitute the inference per se.
+		     */ 
+		    TypeBinding substituteForChecks;
+		    if (substitute instanceof TypeVariableBinding) {
+		    	substituteForChecks = substitute;
+		    } else {
+		    	substituteForChecks = Scope.substitute(new LingeringTypeVariableEliminator(typeVariables, null, scope), substitute); // while using this for bounds check
+		    }
+		    
+		    if (uncheckedArguments != null && uncheckedArguments[i] == null) continue; // only bound check if inferred through 15.12.2.6
+			switch (typeVariable.boundCheck(substitution, substituteForChecks, scope)) {
+				case TypeConstants.MISMATCH :
+			        // incompatible due to bound check
+					int argLength = arguments.length;
+					TypeBinding[] augmentedArguments = new TypeBinding[argLength + 2]; // append offending substitute and typeVariable
+					System.arraycopy(arguments, 0, augmentedArguments, 0, argLength);
+					augmentedArguments[argLength] = substitute;
+					augmentedArguments[argLength+1] = typeVariable;
+			        return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, augmentedArguments, ProblemReasons.ParameterBoundMismatch);
+				case TypeConstants.UNCHECKED :
+					// tolerate unchecked bounds
+					methodSubstitute.tagBits |= TagBits.HasUncheckedTypeArgumentForBoundCheck;
+					break;
+			}
+		}
+		// check presence of unchecked argument conversion a posteriori (15.12.2.6)
+		return methodSubstitute;
+	}
+
+	/**
+	 * Collect argument type mapping, handling varargs
+	 */
+	private static ParameterizedGenericMethodBinding inferFromArgumentTypes(Scope scope, MethodBinding originalMethod, TypeBinding[] arguments, TypeBinding[] parameters, InferenceContext inferenceContext) {
+		if (originalMethod.isVarargs()) {
+			int paramLength = parameters.length;
+			int minArgLength = paramLength - 1;
+			int argLength = arguments.length;
+			// process mandatory arguments
+			for (int i = 0; i < minArgLength; i++) {
+				parameters[i].collectSubstitutes(scope, arguments[i], inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+				if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+			}
+			// process optional arguments
+			if (minArgLength < argLength) {
+				TypeBinding varargType = parameters[minArgLength]; // last arg type - as is ?
+				TypeBinding lastArgument = arguments[minArgLength];
+				checkVarargDimension: {
+					if (paramLength == argLength) {
+						if (lastArgument == TypeBinding.NULL) break checkVarargDimension;
+						switch (lastArgument.dimensions()) {
+							case 0 :
+								break; // will remove one dim
+							case 1 :
+								if (!lastArgument.leafComponentType().isBaseType()) break checkVarargDimension;
+								break; // will remove one dim
+							default :
+								break checkVarargDimension;
+						}
+					}
+					// eliminate one array dimension
+					varargType = ((ArrayBinding)varargType).elementsType();
+				}
+				for (int i = minArgLength; i < argLength; i++) {
+					varargType.collectSubstitutes(scope, arguments[i], inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+					if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+				}
+			}
+		} else {
+			int paramLength = parameters.length;
+			for (int i = 0; i < paramLength; i++) {
+				parameters[i].collectSubstitutes(scope, arguments[i], inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+				if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+			}
+		}
+		TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		if (!resolveSubstituteConstraints(scope, originalVariables , inferenceContext, false/*ignore Ti<:Uk*/))
+			return null; // impossible substitution
+
+		// apply inferred variable substitutions - replacing unresolved variable with original ones in param method
+		TypeBinding[] inferredSustitutes = inferenceContext.substitutes;
+		TypeBinding[] actualSubstitutes = inferredSustitutes;
+		for (int i = 0, varLength = originalVariables.length; i < varLength; i++) {
+			if (inferredSustitutes[i] == null) {
+				if (actualSubstitutes == inferredSustitutes) {
+					System.arraycopy(inferredSustitutes, 0, actualSubstitutes = new TypeBinding[varLength], 0, i); // clone to replace null with original variable in param method
+				}
+				actualSubstitutes[i] = originalVariables[i];
+			} else if (actualSubstitutes != inferredSustitutes) {
+				actualSubstitutes[i] = inferredSustitutes[i];
+			}
+		}
+		ParameterizedGenericMethodBinding paramMethod = scope.environment().createParameterizedGenericMethod(originalMethod, actualSubstitutes);
+		return paramMethod;
+	}
+
+	private static boolean resolveSubstituteConstraints(Scope scope, TypeVariableBinding[] typeVariables, InferenceContext inferenceContext, boolean considerEXTENDSConstraints) {
+		TypeBinding[] substitutes = inferenceContext.substitutes;
+		int varLength = typeVariables.length;
+		// check Tj=U constraints
+		nextTypeParameter:
+			for (int i = 0; i < varLength; i++) {
+				TypeVariableBinding current = typeVariables[i];
+				TypeBinding substitute = substitutes[i];
+				if (substitute != null) continue nextTypeParameter; // already inferred previously
+				TypeBinding [] equalSubstitutes = inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EQUAL);
+				if (equalSubstitutes != null) {
+					nextConstraint:
+						for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
+							TypeBinding equalSubstitute = equalSubstitutes[j];
+							if (equalSubstitute == null) continue nextConstraint;
+							if (equalSubstitute == current) {
+								// try to find a better different match if any in subsequent equal candidates
+								for (int k = j+1; k < equalLength; k++) {
+									equalSubstitute = equalSubstitutes[k];
+									if (equalSubstitute != current && equalSubstitute != null) {
+										substitutes[i] = equalSubstitute;
+										continue nextTypeParameter;
+									}
+								}
+								substitutes[i] = current;
+								continue nextTypeParameter;
+							}
+//							if (equalSubstitute.isTypeVariable()) {
+//								TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
+//								// substituted by a variable of the same method, ignore
+//								if (variable.rank < varLength && typeVariables[variable.rank] == variable) {
+//									// TODO (philippe) rewrite all other constraints to use current instead.
+//									continue nextConstraint;
+//								}
+//							}
+							substitutes[i] = equalSubstitute;
+							continue nextTypeParameter; // pick first match, applicability check will rule out invalid scenario where others were present
+						}
+				}
+			}
+		if (inferenceContext.hasUnresolvedTypeArgument()) {
+			// check Tj>:U constraints
+			nextTypeParameter:
+				for (int i = 0; i < varLength; i++) {
+					TypeVariableBinding current = typeVariables[i];
+					TypeBinding substitute = substitutes[i];
+					if (substitute != null) continue nextTypeParameter; // already inferred previously
+					TypeBinding [] bounds = inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_SUPER);
+					if (bounds == null) continue nextTypeParameter;
+					TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(bounds);
+					if (mostSpecificSubstitute == null) {
+						return false; // incompatible
+					}
+					if (mostSpecificSubstitute != TypeBinding.VOID) {
+						substitutes[i] = mostSpecificSubstitute;
+					}
+				}
+		}
+		if (considerEXTENDSConstraints && inferenceContext.hasUnresolvedTypeArgument()) {
+			// check Tj<:U constraints
+			nextTypeParameter:
+				for (int i = 0; i < varLength; i++) {
+					TypeVariableBinding current = typeVariables[i];
+					TypeBinding substitute = substitutes[i];
+					if (substitute != null) continue nextTypeParameter; // already inferred previously
+					TypeBinding [] bounds = inferenceContext.getSubstitutes(current, TypeConstants.CONSTRAINT_EXTENDS);
+					if (bounds == null) continue nextTypeParameter;
+					TypeBinding[] glb = Scope.greaterLowerBound(bounds, scope);
+					TypeBinding mostSpecificSubstitute = null;
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=341795 - Per 15.12.2.8, we should fully apply glb
+					if (glb != null) {
+						if (glb.length == 1) {
+							mostSpecificSubstitute = glb[0];
+						} else {
+							TypeBinding [] otherBounds = new TypeBinding[glb.length - 1];
+							System.arraycopy(glb, 1, otherBounds, 0, glb.length - 1);
+							mostSpecificSubstitute = scope.environment().createWildcard(null, 0, glb[0], otherBounds, Wildcard.EXTENDS);
+						}
+					}
+					if (mostSpecificSubstitute != null) {
+						substitutes[i] = mostSpecificSubstitute;
+					}
+				}
+		}
+		return true;
+	}
+
+	/**
+	 * Create raw generic method for raw type (double substitution from type vars with raw type arguments, and erasure of method variables)
+	 * Only invoked for non-static generic methods of raw type
+	 */
+	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, RawTypeBinding rawType, LookupEnvironment environment) {
+		TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		int length = originalVariables.length;
+		TypeBinding[] rawArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			rawArguments[i] =  environment.convertToRawType(originalVariables[i].erasure(), false /*do not force conversion of enclosing types*/);
+		}
+	    this.isRaw = true;
+	    this.tagBits = originalMethod.tagBits;
+	    this.environment = environment;
+		this.modifiers = originalMethod.modifiers;
+		this.selector = originalMethod.selector;
+		this.declaringClass = rawType == null ? originalMethod.declaringClass : rawType;
+	    this.typeVariables = Binding.NO_TYPE_VARIABLES;
+	    this.typeArguments = rawArguments;
+	    this.originalMethod = originalMethod;
+		boolean ignoreRawTypeSubstitution = rawType == null || originalMethod.isStatic();
+	    this.parameters = Scope.substitute(this, ignoreRawTypeSubstitution
+	    									? originalMethod.parameters // no substitution if original was static
+	    									: Scope.substitute(rawType, originalMethod.parameters));
+	    this.thrownExceptions = Scope.substitute(this, 	ignoreRawTypeSubstitution
+	    									? originalMethod.thrownExceptions // no substitution if original was static
+	    									: Scope.substitute(rawType, originalMethod.thrownExceptions));
+	    // error case where exception type variable would have been substituted by a non-reference type (207573)
+	    if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
+	    this.returnType = Scope.substitute(this, ignoreRawTypeSubstitution
+	    									? originalMethod.returnType // no substitution if original was static
+	    									: Scope.substitute(rawType, originalMethod.returnType));
+	    this.wasInferred = false; // not resulting from method invocation inferrence
+	    this.parameterNonNullness = originalMethod.parameterNonNullness;
+	}
+
+    /**
+     * Create method of parameterized type, substituting original parameters with type arguments.
+     */
+	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment) {
+	    this.environment = environment;
+		this.modifiers = originalMethod.modifiers;
+		this.selector = originalMethod.selector;
+		this.declaringClass = originalMethod.declaringClass;
+	    this.typeVariables = Binding.NO_TYPE_VARIABLES;
+	    this.typeArguments = typeArguments;
+	    this.isRaw = false;
+	    this.tagBits = originalMethod.tagBits;
+	    this.originalMethod = originalMethod;
+	    this.parameters = Scope.substitute(this, originalMethod.parameters);
+	    // error case where exception type variable would have been substituted by a non-reference type (207573)
+	    this.returnType = Scope.substitute(this, originalMethod.returnType);
+	    this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
+	    if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		checkMissingType: {
+			if ((this.tagBits & TagBits.HasMissingType) != 0)
+				break checkMissingType;
+			if ((this.returnType.tagBits & TagBits.HasMissingType) != 0) {
+				this.tagBits |=  TagBits.HasMissingType;
+				break checkMissingType;
+			}
+			for (int i = 0, max = this.parameters.length; i < max; i++) {
+				if ((this.parameters[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+			for (int i = 0, max = this.thrownExceptions.length; i < max; i++) {
+				if ((this.thrownExceptions[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+		}
+	    this.wasInferred = true;// resulting from method invocation inferrence
+	    this.parameterNonNullness = originalMethod.parameterNonNullness;
+	}
+
+	/*
+	 * parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature percent typeArguments
+	 * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;Ljava/lang/String;)V%<Lp/X;>
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(this.originalMethod.computeUniqueKey(false/*not a leaf*/));
+		buffer.append('%');
+		buffer.append('<');
+		if (!this.isRaw) {
+			int length = this.typeArguments.length;
+			for (int i = 0; i < length; i++) {
+				TypeBinding typeArgument = this.typeArguments[i];
+				buffer.append(typeArgument.computeUniqueKey(false/*not a leaf*/));
+			}
+		}
+		buffer.append('>');
+		int resultLength = buffer.length();
+		char[] result = new char[resultLength];
+		buffer.getChars(0, resultLength, result, 0);
+		return result;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#environment()
+	 */
+	public LookupEnvironment environment() {
+		return this.environment;
+	}
+	/**
+	 * Returns true if some parameters got substituted.
+	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
+	 */
+	public boolean hasSubstitutedParameters() {
+		// generic parameterized method can represent either an invocation or a raw generic method
+		if (this.wasInferred)
+			return this.originalMethod.hasSubstitutedParameters();
+		return super.hasSubstitutedParameters();
+	}
+	/**
+	 * Returns true if the return type got substituted.
+	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
+	 */
+	public boolean hasSubstitutedReturnType() {
+		if (this.inferredReturnType)
+			return this.originalMethod.hasSubstitutedReturnType();
+		return super.hasSubstitutedReturnType();
+	}
+	/**
+	 * Given some type expectation, and type variable bounds, perform some inference.
+	 * Returns true if still had unresolved type variable at the end of the operation
+	 */
+	private ParameterizedGenericMethodBinding inferFromExpectedType(Scope scope, InferenceContext inferenceContext) {
+	    TypeVariableBinding[] originalVariables = this.originalMethod.typeVariables; // immediate parent (could be a parameterized method)
+		int varLength = originalVariables.length;
+	    // infer from expected return type
+		if (inferenceContext.expectedType != null) {
+		    this.returnType.collectSubstitutes(scope, inferenceContext.expectedType, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+		    if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+		}
+	    // infer from bounds of type parameters
+		for (int i = 0; i < varLength; i++) {
+			TypeVariableBinding originalVariable = originalVariables[i];
+			TypeBinding argument = this.typeArguments[i];
+			boolean argAlreadyInferred = argument != originalVariable;
+			if (originalVariable.firstBound == originalVariable.superclass) {
+				TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superclass);
+				argument.collectSubstitutes(scope, substitutedBound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+				if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+				// JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference
+				// e.g. given: <E extends Object, S extends Collection<E>> S test1(S param)
+				//                   invocation: test1(new Vector<String>())    will infer: S=Vector<String>  and with code below: E=String
+				if (argAlreadyInferred) {
+					substitutedBound.collectSubstitutes(scope, argument, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+					if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+				}
+			}
+			for (int j = 0, max = originalVariable.superInterfaces.length; j < max; j++) {
+				TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superInterfaces[j]);
+				argument.collectSubstitutes(scope, substitutedBound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+				if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+				// JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference
+				if (argAlreadyInferred) {
+					substitutedBound.collectSubstitutes(scope, argument, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+					if (inferenceContext.status == InferenceContext.FAILED) return null; // impossible substitution
+				}
+			}
+		}
+		if (!resolveSubstituteConstraints(scope, originalVariables, inferenceContext, true/*consider Ti<:Uk*/))
+			return null; // incompatible
+		// this.typeArguments = substitutes; - no op since side effects got performed during #resolveSubstituteConstraints
+    	for (int i = 0; i < varLength; i++) {
+    		TypeBinding substitute = inferenceContext.substitutes[i];
+    		if (substitute != null) {
+    			this.typeArguments[i] = substitute;
+    		} else {
+    			// remaining unresolved variable are considered to be Object (or their bound actually)
+	    		this.typeArguments[i] = inferenceContext.substitutes[i] = originalVariables[i].upperBound();
+	    	}
+    	}
+		/* May still need an extra substitution at the end (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=121369)
+		   to properly substitute a remaining unresolved variable which also appear in a formal bound. See also
+		   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5021635. It is questionable though whether this extra
+		   substitution should take place when the invocation site offers no guidance whatsoever and the type variables
+		   are inferred to be the glb of the published bounds - as there can recursion in the formal bounds, the
+		   inferred bounds would no longer be glb.
+		*/
+		
+		this.typeArguments = Scope.substitute(this, this.typeArguments);
+
+    	// adjust method types to reflect latest inference
+		TypeBinding oldReturnType = this.returnType;
+		this.returnType = Scope.substitute(this, this.returnType);
+		this.inferredReturnType = inferenceContext.hasExplicitExpectedType && this.returnType != oldReturnType;
+	    this.parameters = Scope.substitute(this, this.parameters);
+	    this.thrownExceptions = Scope.substitute(this, this.thrownExceptions);
+	    // error case where exception type variable would have been substituted by a non-reference type (207573)
+	    if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		checkMissingType: {
+			if ((this.tagBits & TagBits.HasMissingType) != 0)
+				break checkMissingType;
+			if ((this.returnType.tagBits & TagBits.HasMissingType) != 0) {
+				this.tagBits |=  TagBits.HasMissingType;
+				break checkMissingType;
+			}
+			for (int i = 0, max = this.parameters.length; i < max; i++) {
+				if ((this.parameters[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+			for (int i = 0, max = this.thrownExceptions.length; i < max; i++) {
+				if ((this.thrownExceptions[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+		}
+	    return this;
+	}
+
+	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=347600 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159
+	   Sometimes due to recursion/circularity in formal bounds, even *published bounds* fail bound check. We need to
+	   break the circularity/self reference in order not to be overly strict during type equivalence checks.  
+	   See also http://bugs.sun.com/view_bug.do?bug_id=6932571
+	 */
+	private static class LingeringTypeVariableEliminator implements Substitution {
+
+		final private TypeVariableBinding [] variables;
+		final private TypeBinding [] substitutes; // when null, substitute type variables by unbounded wildcard
+		final private Scope scope;
+		
+		/**
+		 * @param variables
+		 * @param substitutes when null, substitute type variable by unbounded wildcard
+		 * @param scope
+		 */
+		public LingeringTypeVariableEliminator(TypeVariableBinding [] variables, TypeBinding [] substitutes, Scope scope) {
+			this.variables = variables;
+			this.substitutes = substitutes;
+			this.scope = scope;
+		}
+		// With T mapping to I<T>, answer of I<?>, when given T, having eliminated the circularity/self reference.
+		public TypeBinding substitute(TypeVariableBinding typeVariable) {
+			if (typeVariable.rank >= this.variables.length || this.variables[typeVariable.rank] != typeVariable) {   // not kosher, don't touch.
+				return typeVariable;
+			}
+			if (this.substitutes != null) {
+				return Scope.substitute(new LingeringTypeVariableEliminator(this.variables, null, this.scope), this.substitutes[typeVariable.rank]); 
+			}
+			ReferenceBinding genericType = (ReferenceBinding) (typeVariable.declaringElement instanceof ReferenceBinding ? typeVariable.declaringElement : null);
+			return this.scope.environment().createWildcard(genericType, typeVariable.rank, null, null, Wildcard.UNBOUND);
+		}
+
+		public LookupEnvironment environment() {
+			return this.scope.environment();
+		}
+
+		public boolean isRawSubstitution() {
+			return false;
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
+	 */
+	public boolean isRawSubstitution() {
+		return this.isRaw;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#substitute(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)
+	 */
+	public TypeBinding substitute(TypeVariableBinding originalVariable) {
+        TypeVariableBinding[] variables = this.originalMethod.typeVariables;
+        int length = variables.length;
+        // check this variable can be substituted given parameterized type
+        if (originalVariable.rank < length && variables[originalVariable.rank] == originalVariable) {
+			return this.typeArguments[originalVariable.rank];
+        }
+	    return originalVariable;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.MethodBinding#tiebreakMethod()
+	 */
+	public MethodBinding tiebreakMethod() {
+		if (this.tiebreakMethod == null)
+			this.tiebreakMethod = this.originalMethod.asRawMethod(this.environment);
+		return this.tiebreakMethod;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
new file mode 100644
index 0000000..ae8d8cb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+/**
+ * Binding denoting a method after type parameter substitutions got performed.
+ * On parameterized type bindings, all methods got substituted, regardless whether
+ * their signature did involve generics or not, so as to get the proper declaringClass for
+ * these methods.
+ */
+public class ParameterizedMethodBinding extends MethodBinding {
+
+	protected MethodBinding originalMethod;
+
+	/**
+	 * Create method of parameterized type, substituting original parameters/exception/return type with type arguments.
+	 */
+	public ParameterizedMethodBinding(final ParameterizedTypeBinding parameterizedDeclaringClass, MethodBinding originalMethod) {
+		super(
+				originalMethod.modifiers,
+				originalMethod.selector,
+				originalMethod.returnType,
+				originalMethod.parameters,
+				originalMethod.thrownExceptions,
+				parameterizedDeclaringClass);
+		this.originalMethod = originalMethod;
+		/* missing type bit cannot be copied as is it might come from the return type or a parameter type that
+		 * is substituted by a raw type.
+		 */
+		this.tagBits = originalMethod.tagBits & ~TagBits.HasMissingType;
+		this.parameterNonNullness = originalMethod.parameterNonNullness;
+
+		final TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		Substitution substitution = null;
+		final int length = originalVariables.length;
+		final boolean isStatic = originalMethod.isStatic();
+		if (length == 0) {
+			this.typeVariables = Binding.NO_TYPE_VARIABLES;
+			if (!isStatic) substitution = parameterizedDeclaringClass;
+		} else {
+			// at least fix up the declaringElement binding + bound substitution if non static
+			final TypeVariableBinding[] substitutedVariables = new TypeVariableBinding[length];
+			for (int i = 0; i < length; i++) { // copy original type variable to relocate
+				TypeVariableBinding originalVariable = originalVariables[i];
+				substitutedVariables[i] = new TypeVariableBinding(originalVariable.sourceName, this, originalVariable.rank, parameterizedDeclaringClass.environment);
+			}
+			this.typeVariables = substitutedVariables;
+
+			// need to substitute old var refs with new ones (double substitution: declaringClass + new type variables)
+			substitution = new Substitution() {
+				public LookupEnvironment environment() {
+					return parameterizedDeclaringClass.environment;
+				}
+				public boolean isRawSubstitution() {
+					return !isStatic && parameterizedDeclaringClass.isRawSubstitution();
+				}
+				public TypeBinding substitute(TypeVariableBinding typeVariable) {
+					// check this variable can be substituted given copied variables
+					if (typeVariable.rank < length && originalVariables[typeVariable.rank] == typeVariable) {
+						return substitutedVariables[typeVariable.rank];
+					}
+					if (!isStatic)
+						return parameterizedDeclaringClass.substitute(typeVariable);
+					return typeVariable;
+				}
+			};
+
+			// initialize new variable bounds
+			for (int i = 0; i < length; i++) {
+				TypeVariableBinding originalVariable = originalVariables[i];
+				TypeVariableBinding substitutedVariable = substitutedVariables[i];
+				TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
+				ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
+				if (originalVariable.firstBound != null) {
+					substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
+						? substitutedSuperclass // could be array type or interface
+						: substitutedInterfaces[0];
+				}
+				switch (substitutedSuperclass.kind()) {
+					case Binding.ARRAY_TYPE :
+						substitutedVariable.superclass = parameterizedDeclaringClass.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+						substitutedVariable.superInterfaces = substitutedInterfaces;
+						break;
+					default:
+						if (substitutedSuperclass.isInterface()) {
+							substitutedVariable.superclass = parameterizedDeclaringClass.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+							int interfaceCount = substitutedInterfaces.length;
+							System.arraycopy(substitutedInterfaces, 0, substitutedInterfaces = new ReferenceBinding[interfaceCount+1], 1, interfaceCount);
+							substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass;
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+						} else {
+							substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+						}
+				}
+			}
+		}
+		if (substitution != null) {
+			this.returnType = Scope.substitute(substitution, this.returnType);
+			this.parameters = Scope.substitute(substitution, this.parameters);
+			this.thrownExceptions = Scope.substitute(substitution, this.thrownExceptions);
+			// error case where exception type variable would have been substituted by a non-reference type (207573)
+			if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
+
+			// after substitution transfer nullness information from type annotations:
+			if (parameterizedDeclaringClass.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+				long returnNullBits = this.returnType.tagBits & TagBits.AnnotationNullMASK;
+				if (returnNullBits != 0L) {
+					this.tagBits &= ~TagBits.AnnotationNullMASK;
+					this.tagBits |= returnNullBits;
+				}
+				int parametersLen = this.parameters.length;
+				for (int i=0; i<parametersLen; i++) {
+					long paramTagBits = this.parameters[i].tagBits & TagBits.AnnotationNullMASK;
+					if (paramTagBits != 0) {
+						if (this.parameterNonNullness == null)
+							this.parameterNonNullness = new Boolean[parametersLen];
+						this.parameterNonNullness[i] = Boolean.valueOf(paramTagBits == TagBits.AnnotationNonNull);
+					}
+				}
+			}
+		}
+		checkMissingType: {
+			if ((this.tagBits & TagBits.HasMissingType) != 0)
+				break checkMissingType;
+			if ((this.returnType.tagBits & TagBits.HasMissingType) != 0) {
+				this.tagBits |=  TagBits.HasMissingType;
+				break checkMissingType;
+			}
+			for (int i = 0, max = this.parameters.length; i < max; i++) {
+				if ((this.parameters[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+			for (int i = 0, max = this.thrownExceptions.length; i < max; i++) {
+				if ((this.thrownExceptions[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Create method of parameterized type, substituting original parameters/exception/return type with type arguments.
+	 * This is a CODE ASSIST method ONLY.
+	 */
+	public ParameterizedMethodBinding(final ReferenceBinding declaringClass, MethodBinding originalMethod, char[][] alternateParamaterNames, final LookupEnvironment environment) {
+		super(
+				originalMethod.modifiers,
+				originalMethod.selector,
+				 originalMethod.returnType,
+				originalMethod.parameters,
+				originalMethod.thrownExceptions,
+				declaringClass);
+		this.originalMethod = originalMethod;
+		/* missing type bit cannot be copied as is it might come from the return type or a parameter type that
+		 * is substituted by a raw type.
+		 */
+		this.tagBits = originalMethod.tagBits & ~TagBits.HasMissingType;
+		this.parameterNonNullness = originalMethod.parameterNonNullness;
+
+		final TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		Substitution substitution = null;
+		final int length = originalVariables.length;
+		if (length == 0) {
+			this.typeVariables = Binding.NO_TYPE_VARIABLES;
+		} else {
+			// at least fix up the declaringElement binding + bound substitution if non static
+			final TypeVariableBinding[] substitutedVariables = new TypeVariableBinding[length];
+			for (int i = 0; i < length; i++) { // copy original type variable to relocate
+				TypeVariableBinding originalVariable = originalVariables[i];
+				substitutedVariables[i] = new TypeVariableBinding(
+						alternateParamaterNames == null ?
+								originalVariable.sourceName :
+								alternateParamaterNames[i],
+							this,
+							originalVariable.rank,
+							environment);
+			}
+			this.typeVariables = substitutedVariables;
+
+			// need to substitute old var refs with new ones (double substitution: declaringClass + new type variables)
+			substitution = new Substitution() {
+				public LookupEnvironment environment() {
+					return environment;
+				}
+				public boolean isRawSubstitution() {
+					return false;
+				}
+				public TypeBinding substitute(TypeVariableBinding typeVariable) {
+			        // check this variable can be substituted given copied variables
+			        if (typeVariable.rank < length && originalVariables[typeVariable.rank] == typeVariable) {
+						return substitutedVariables[typeVariable.rank];
+			        }
+			        return typeVariable;
+				}
+			};
+
+			// initialize new variable bounds
+			for (int i = 0; i < length; i++) {
+				TypeVariableBinding originalVariable = originalVariables[i];
+				TypeVariableBinding substitutedVariable = substitutedVariables[i];
+				TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
+				ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
+				if (originalVariable.firstBound != null) {
+					substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
+						? substitutedSuperclass // could be array type or interface
+						: substitutedInterfaces[0];
+				}
+				switch (substitutedSuperclass.kind()) {
+					case Binding.ARRAY_TYPE :
+						substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+						substitutedVariable.superInterfaces = substitutedInterfaces;
+						break;
+					default:
+						if (substitutedSuperclass.isInterface()) {
+							substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+							int interfaceCount = substitutedInterfaces.length;
+							System.arraycopy(substitutedInterfaces, 0, substitutedInterfaces = new ReferenceBinding[interfaceCount+1], 1, interfaceCount);
+							substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass;
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+						} else {
+							substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+						}
+				}
+			}
+		}
+		if (substitution != null) {
+			this.returnType = Scope.substitute(substitution, this.returnType);
+			this.parameters = Scope.substitute(substitution, this.parameters);
+			this.thrownExceptions = Scope.substitute(substitution, this.thrownExceptions);
+		    // error case where exception type variable would have been substituted by a non-reference type (207573)
+		    if (this.thrownExceptions == null) this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		}
+		checkMissingType: {
+			if ((this.tagBits & TagBits.HasMissingType) != 0)
+				break checkMissingType;
+			if ((this.returnType.tagBits & TagBits.HasMissingType) != 0) {
+				this.tagBits |=  TagBits.HasMissingType;
+				break checkMissingType;
+			}
+			for (int i = 0, max = this.parameters.length; i < max; i++) {
+				if ((this.parameters[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+			for (int i = 0, max = this.thrownExceptions.length; i < max; i++) {
+				if ((this.thrownExceptions[i].tagBits & TagBits.HasMissingType) != 0) {
+					this.tagBits |=  TagBits.HasMissingType;
+					break checkMissingType;
+				}
+			}
+		}
+	}
+
+	public ParameterizedMethodBinding() {
+		// no init
+	}
+
+	/**
+	 * The type of x.getClass() is substituted from 'Class<? extends Object>' into: 'Class<? extends raw(X)>
+	 */
+	public static ParameterizedMethodBinding instantiateGetClass(TypeBinding receiverType, MethodBinding originalMethod, Scope scope) {
+		ParameterizedMethodBinding method = new ParameterizedMethodBinding();
+		method.modifiers = originalMethod.modifiers;
+		method.selector = originalMethod.selector;
+		method.declaringClass = originalMethod.declaringClass;
+		method.typeVariables = Binding.NO_TYPE_VARIABLES;
+		method.originalMethod = originalMethod;
+		method.parameters = originalMethod.parameters;
+		method.thrownExceptions = originalMethod.thrownExceptions;
+		method.tagBits = originalMethod.tagBits;
+		ReferenceBinding genericClassType = scope.getJavaLangClass();
+		LookupEnvironment environment = scope.environment();
+		TypeBinding rawType = environment.convertToRawType(receiverType.erasure(), false /*do not force conversion of enclosing types*/);
+		method.returnType = environment.createParameterizedType(
+			genericClassType,
+			new TypeBinding[] {  environment.createWildcard(genericClassType, 0, rawType, null /*no extra bound*/, Wildcard.EXTENDS) },
+			null);
+		if ((method.returnType.tagBits & TagBits.HasMissingType) != 0) {
+			method.tagBits |=  TagBits.HasMissingType;
+		}
+		return method;
+	}
+
+	/**
+	 * Returns true if some parameters got substituted.
+	 */
+	public boolean hasSubstitutedParameters() {
+		return this.parameters != this.originalMethod.parameters;
+	}
+
+	/**
+	 * Returns true if the return type got substituted.
+	 */
+	public boolean hasSubstitutedReturnType() {
+		return this.returnType != this.originalMethod.returnType;
+	}
+
+	/**
+	 * Returns the original method (as opposed to parameterized instances)
+	 */
+	public MethodBinding original() {
+		return this.originalMethod.original();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
new file mode 100644
index 0000000..8af5782
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -0,0 +1,1218 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+/**
+ * A parameterized type encapsulates a type with type arguments,
+ */
+public class ParameterizedTypeBinding extends ReferenceBinding implements Substitution {
+
+	private ReferenceBinding type; // must ensure the type is resolved
+	public TypeBinding[] arguments;
+	public LookupEnvironment environment;
+	public char[] genericTypeSignature;
+	public ReferenceBinding superclass;
+	public ReferenceBinding[] superInterfaces;
+	public FieldBinding[] fields;
+	public ReferenceBinding[] memberTypes;
+	public MethodBinding[] methods;
+	private ReferenceBinding enclosingType;
+
+	public ParameterizedTypeBinding(ReferenceBinding type, TypeBinding[] arguments,  ReferenceBinding enclosingType, LookupEnvironment environment){
+		this.environment = environment;
+		this.enclosingType = enclosingType; // never unresolved, never lazy per construction
+//		if (enclosingType != null && enclosingType.isGenericType()) {
+//			RuntimeException e = new RuntimeException("PARAM TYPE with GENERIC ENCLOSING");
+//			e.printStackTrace();
+//			throw e;
+//		}
+//		if (!(type instanceof UnresolvedReferenceBinding) && type.typeVariables() == Binding.NO_TYPE_VARIABLES) {
+//			System.out.println();
+//		}
+		initialize(type, arguments);
+		if (type instanceof UnresolvedReferenceBinding)
+			((UnresolvedReferenceBinding) type).addWrapper(this, environment);
+		if (arguments != null) {
+			for (int i = 0, l = arguments.length; i < l; i++)
+				if (arguments[i] instanceof UnresolvedReferenceBinding)
+					((UnresolvedReferenceBinding) arguments[i]).addWrapper(this, environment);
+		}
+		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
+	}
+
+	/**
+	 * May return an UnresolvedReferenceBinding.
+	 * @see ParameterizedTypeBinding#genericType()
+	 */
+	protected ReferenceBinding actualType() {
+		return this.type;
+	}
+
+	/**
+	 * Iterate type arguments, and validate them according to corresponding variable bounds.
+	 */
+	public void boundCheck(Scope scope, TypeReference[] argumentReferences) {
+		if ((this.tagBits & TagBits.PassedBoundCheck) == 0) {
+			boolean hasErrors = false;
+			TypeVariableBinding[] typeVariables = this.type.typeVariables();
+			if (this.arguments != null && typeVariables != null) { // arguments may be null in error cases
+				for (int i = 0, length = typeVariables.length; i < length; i++) {
+				    if (typeVariables[i].boundCheck(this, this.arguments[i], scope)  != TypeConstants.OK) {
+				    	hasErrors = true;
+				    	if ((this.arguments[i].tagBits & TagBits.HasMissingType) == 0) {
+				    		// do not report secondary error, if type reference already got complained against
+							scope.problemReporter().typeMismatchError(this.arguments[i], typeVariables[i], this.type, argumentReferences[i]);
+				    	}
+				    }
+				}
+			}
+			if (!hasErrors) this.tagBits |= TagBits.PassedBoundCheck; // no need to recheck it in the future
+		}
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
+	 */
+	public boolean canBeInstantiated() {
+		return ((this.tagBits & TagBits.HasDirectWildcard) == 0) && super.canBeInstantiated(); // cannot instantiate param type with wildcard arguments
+	}
+	/**
+	 * Perform capture conversion for a parameterized type with wildcard arguments
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture(Scope,int)
+	 */
+	public TypeBinding capture(Scope scope, int position) {
+		if ((this.tagBits & TagBits.HasDirectWildcard) == 0)
+			return this;
+
+		TypeBinding[] originalArguments = this.arguments;
+		int length = originalArguments.length;
+		TypeBinding[] capturedArguments = new TypeBinding[length];
+
+		// Retrieve the type context for capture bindingKey
+		ReferenceBinding contextType = scope.enclosingSourceType();
+		if (contextType != null) contextType = contextType.outermostEnclosingType(); // maybe null when used programmatically by DOM
+
+		for (int i = 0; i < length; i++) {
+			TypeBinding argument = originalArguments[i];
+			if (argument.kind() == Binding.WILDCARD_TYPE) { // no capture for intersection types
+				capturedArguments[i] = new CaptureBinding((WildcardBinding) argument, contextType, position, scope.compilationUnitScope().nextCaptureID());
+			} else {
+				capturedArguments[i] = argument;
+			}
+		}
+		ParameterizedTypeBinding capturedParameterizedType = this.environment.createParameterizedType(this.type, capturedArguments, enclosingType());
+		for (int i = 0; i < length; i++) {
+			TypeBinding argument = capturedArguments[i];
+			if (argument.isCapture()) {
+				((CaptureBinding)argument).initializeBounds(scope, capturedParameterizedType);
+			}
+		}
+		return capturedParameterizedType;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#collectMissingTypes(java.util.List)
+	 */
+	public List collectMissingTypes(List missingTypes) {
+		if ((this.tagBits & TagBits.HasMissingType) != 0) {
+			if (this.enclosingType != null) {
+				missingTypes = this.enclosingType.collectMissingTypes(missingTypes);
+			}
+			missingTypes = genericType().collectMissingTypes(missingTypes);
+			if (this.arguments != null) {
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					missingTypes = this.arguments[i].collectMissingTypes(missingTypes);
+				}
+			}
+		}
+		return missingTypes;
+	}
+
+	/**
+	 * Collect the substitutes into a map for certain type variables inside the receiver type
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
+	 * Constraints:
+	 *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
+	 *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
+	 *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
+	 */
+	public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
+		if ((this.tagBits & TagBits.HasTypeVariable) == 0) {
+			TypeBinding actualEquivalent = actualType.findSuperTypeOriginatingFrom(this.type);
+			if (actualEquivalent != null && actualEquivalent.isRawType()) {
+				inferenceContext.isUnchecked = true;
+			}
+			return;
+		}
+		if (actualType == TypeBinding.NULL || actualType.kind() == POLY_TYPE) return;
+
+		if (!(actualType instanceof ReferenceBinding)) return;
+		TypeBinding formalEquivalent, actualEquivalent;
+		switch (constraint) {
+			case TypeConstants.CONSTRAINT_EQUAL :
+			case TypeConstants.CONSTRAINT_EXTENDS :
+				formalEquivalent = this;
+		        actualEquivalent = actualType.findSuperTypeOriginatingFrom(this.type);
+		        if (actualEquivalent == null) return;
+		        break;
+			case TypeConstants.CONSTRAINT_SUPER :
+	        default:
+		        formalEquivalent = this.findSuperTypeOriginatingFrom(actualType);
+		        if (formalEquivalent == null) return;
+		        actualEquivalent = actualType;
+		        break;
+		}
+		// collect through enclosing type
+		ReferenceBinding formalEnclosingType = formalEquivalent.enclosingType();
+		if (formalEnclosingType != null) {
+			formalEnclosingType.collectSubstitutes(scope, actualEquivalent.enclosingType(), inferenceContext, constraint);
+		}
+		// collect through type arguments
+		if (this.arguments == null) return;
+        TypeBinding[] formalArguments;
+        switch (formalEquivalent.kind()) {
+        	case Binding.GENERIC_TYPE :
+        		formalArguments = formalEquivalent.typeVariables();
+        		break;
+        	case Binding.PARAMETERIZED_TYPE :
+        		formalArguments = ((ParameterizedTypeBinding)formalEquivalent).arguments;
+        		break;
+        	case Binding.RAW_TYPE :
+        		if (inferenceContext.depth > 0) {
+	           		inferenceContext.status = InferenceContext.FAILED; // marker for impossible inference
+        		}
+        		return;
+        	default :
+        		return;
+        }
+        TypeBinding[] actualArguments;
+        switch (actualEquivalent.kind()) {
+        	case Binding.GENERIC_TYPE :
+        		actualArguments = actualEquivalent.typeVariables();
+        		break;
+        	case Binding.PARAMETERIZED_TYPE :
+        		actualArguments = ((ParameterizedTypeBinding)actualEquivalent).arguments;
+        		break;
+        	case Binding.RAW_TYPE :
+        		if (inferenceContext.depth > 0) {
+	           		inferenceContext.status = InferenceContext.FAILED; // marker for impossible inference
+        		} else {
+	        		inferenceContext.isUnchecked = true;
+        		}
+        		return;
+        	default :
+        		return;
+        }
+        inferenceContext.depth++;
+        for (int i = 0, length = formalArguments.length; i < length; i++) {
+        	TypeBinding formalArgument = formalArguments[i];
+        	TypeBinding actualArgument = actualArguments[i];
+        	if (formalArgument.isWildcard()) {
+                formalArgument.collectSubstitutes(scope, actualArgument, inferenceContext, constraint);
+                continue;
+        	} else if (actualArgument.isWildcard()){
+    			WildcardBinding actualWildcardArgument = (WildcardBinding) actualArgument;
+    			if (actualWildcardArgument.otherBounds == null) {
+    				if (constraint == TypeConstants.CONSTRAINT_SUPER) { // JLS 15.12.7, p.459
+						switch(actualWildcardArgument.boundKind) {
+		    				case Wildcard.EXTENDS :
+		    					formalArgument.collectSubstitutes(scope, actualWildcardArgument.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+		    					continue;
+		    				case Wildcard.SUPER :
+		    					formalArgument.collectSubstitutes(scope, actualWildcardArgument.bound, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+		    					continue;
+		    				default :
+		    					continue; // cannot infer anything further from unbound wildcard
+		    			}
+    				} else {
+    					continue; // cannot infer anything further from wildcard
+    				}
+    			}
+        	}
+        	// by default, use EQUAL constraint
+            formalArgument.collectSubstitutes(scope, actualArgument, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+        }
+        inferenceContext.depth--;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#computeId()
+	 */
+	public void computeId() {
+		this.id = TypeIds.NoId;
+	}
+
+	public char[] computeUniqueKey(boolean isLeaf) {
+	    StringBuffer sig = new StringBuffer(10);
+	    ReferenceBinding enclosing;
+		if (isMemberType() && ((enclosing = enclosingType()).isParameterizedType() || enclosing.isRawType())) {
+		    char[] typeSig = enclosing.computeUniqueKey(false/*not a leaf*/);
+		    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+		    sig.append('.').append(sourceName());
+		} else if(this.type.isLocalType()){
+			LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.type;
+			enclosing = localTypeBinding.enclosingType();
+			ReferenceBinding temp;
+			while ((temp = enclosing.enclosingType()) != null)
+				enclosing = temp;
+			char[] typeSig = enclosing.computeUniqueKey(false/*not a leaf*/);
+		    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+			sig.append('$');
+			sig.append(localTypeBinding.sourceStart);
+		} else {
+		    char[] typeSig = this.type.computeUniqueKey(false/*not a leaf*/);
+		    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+		}
+		ReferenceBinding captureSourceType = null;
+		if (this.arguments != null) {
+		    sig.append('<');
+		    for (int i = 0, length = this.arguments.length; i < length; i++) {
+		    	TypeBinding typeBinding = this.arguments[i];
+		        sig.append(typeBinding.computeUniqueKey(false/*not a leaf*/));
+		        if (typeBinding instanceof CaptureBinding)
+		        	captureSourceType = ((CaptureBinding) typeBinding).sourceType;
+		    }
+		    sig.append('>');
+		}
+		sig.append(';');
+		if (captureSourceType != null && captureSourceType != this.type) {
+			// contains a capture binding
+			sig.insert(0, "&"); //$NON-NLS-1$
+			sig.insert(0, captureSourceType.computeUniqueKey(false/*not a leaf*/));
+		}
+
+		int sigLength = sig.length();
+		char[] uniqueKey = new char[sigLength];
+		sig.getChars(0, sigLength, uniqueKey, 0);
+		return uniqueKey;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#constantPoolName()
+	 */
+	public char[] constantPoolName() {
+		return this.type.constantPoolName(); // erasure
+	}
+
+	public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) {
+		return new ParameterizedMethodBinding(this, originalMethod);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
+	 */
+	public String debugName() {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+	    if (this.environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+	    	// restore applied null annotation from tagBits:
+		    if ((this.tagBits & TagBits.AnnotationNonNull) != 0) {
+		    	char[][] nonNullAnnotationName = environment().getNonNullAnnotationName();
+				nameBuffer.append('@').append(nonNullAnnotationName[nonNullAnnotationName.length-1]).append(' ');
+		    } else if ((this.tagBits & TagBits.AnnotationNullable) != 0) {
+		    	char[][] nullableAnnotationName = environment().getNullableAnnotationName();
+				nameBuffer.append('@').append(nullableAnnotationName[nullableAnnotationName.length-1]).append(' ');
+		    }
+	    }
+	    if (this.type instanceof UnresolvedReferenceBinding) {
+	    	nameBuffer.append(this.type);
+	    } else {
+			nameBuffer.append(this.type.sourceName());
+	    }
+		if (this.arguments != null && this.arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
+			nameBuffer.append('<');
+		    for (int i = 0, length = this.arguments.length; i < length; i++) {
+		        if (i > 0) nameBuffer.append(',');
+		        nameBuffer.append(this.arguments[i].debugName());
+		    }
+		    nameBuffer.append('>');
+		}
+	    return nameBuffer.toString();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#enclosingType()
+	 */
+	public ReferenceBinding enclosingType() {
+	    return this.enclosingType;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#environment()
+	 */
+	public LookupEnvironment environment() {
+		return this.environment;
+	}
+
+	/**
+     * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
+     */
+    public TypeBinding erasure() {
+        return this.type.erasure(); // erasure
+    }
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#fieldCount()
+	 */
+	public int fieldCount() {
+		return this.type.fieldCount(); // same as erasure (lazy)
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#fields()
+	 */
+	public FieldBinding[] fields() {
+		if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+			return this.fields;
+
+		try {
+			FieldBinding[] originalFields = this.type.fields();
+			int length = originalFields.length;
+			FieldBinding[] parameterizedFields = new FieldBinding[length];
+			for (int i = 0; i < length; i++)
+				// substitute all fields, so as to get updated declaring class at least
+				parameterizedFields[i] = new ParameterizedFieldBinding(this, originalFields[i]);
+			this.fields = parameterizedFields;
+		} finally {
+			// if the original fields cannot be retrieved (ex. AbortCompilation), then assume we do not have any fields
+			if (this.fields == null)
+				this.fields = Binding.NO_FIELDS;
+			this.tagBits |= TagBits.AreFieldsComplete;
+		}
+		return this.fields;
+	}
+
+	/**
+	 * Return the original generic type from which the parameterized type got instantiated from.
+	 * This will perform lazy resolution automatically if needed.
+	 * @see ParameterizedTypeBinding#actualType() if no resolution is required (unlikely)
+	 */
+	public ReferenceBinding genericType() {
+		if (this.type instanceof UnresolvedReferenceBinding)
+			((UnresolvedReferenceBinding) this.type).resolve(this.environment, false);
+		return this.type;
+	}
+
+	/**
+	 * Ltype<param1 ... paramN>;
+	 * LY<TT;>;
+	 */
+	public char[] genericTypeSignature() {
+		if (this.genericTypeSignature == null) {
+			if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) {
+		    	this.genericTypeSignature = this.type.signature();
+			} else {
+			    StringBuffer sig = new StringBuffer(10);
+			    if (isMemberType()) {
+			    	ReferenceBinding enclosing = enclosingType();
+					char[] typeSig = enclosing.genericTypeSignature();
+					sig.append(typeSig, 0, typeSig.length-1);// copy all but trailing semicolon
+			    	if ((enclosing.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
+			    		sig.append('.');
+			    	} else {
+			    		sig.append('$');
+			    	}
+			    	sig.append(sourceName());
+			    } else {
+			    	char[] typeSig = this.type.signature();
+					sig.append(typeSig, 0, typeSig.length-1);// copy all but trailing semicolon
+		    	}
+				if (this.arguments != null) {
+				    sig.append('<');
+				    for (int i = 0, length = this.arguments.length; i < length; i++) {
+				        sig.append(this.arguments[i].genericTypeSignature());
+				    }
+				    sig.append('>');
+				}
+				sig.append(';');
+				int sigLength = sig.length();
+				this.genericTypeSignature = new char[sigLength];
+				sig.getChars(0, sigLength, this.genericTypeSignature, 0);
+			}
+		}
+		return this.genericTypeSignature;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getAnnotationTagBits()
+	 */
+	public long getAnnotationTagBits() {
+		return this.type.getAnnotationTagBits();
+	}
+
+	public int getEnclosingInstancesSlotSize() {
+		return genericType().getEnclosingInstancesSlotSize();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getExactConstructor(TypeBinding[])
+	 */
+	public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
+		int argCount = argumentTypes.length;
+		MethodBinding match = null;
+
+		if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
+			long range;
+			if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
+				nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+					MethodBinding method = this.methods[imethod];
+					if (method.parameters.length == argCount) {
+						TypeBinding[] toMatch = method.parameters;
+						for (int iarg = 0; iarg < argCount; iarg++)
+							if (toMatch[iarg] != argumentTypes[iarg])
+								continue nextMethod;
+						if (match != null) return null; // collision case
+						match = method;
+					}
+				}
+			}
+		} else {
+			MethodBinding[] matchingMethods = getMethods(TypeConstants.INIT); // takes care of duplicates & default abstract methods
+			nextMethod : for (int m = matchingMethods.length; --m >= 0;) {
+				MethodBinding method = matchingMethods[m];
+				TypeBinding[] toMatch = method.parameters;
+				if (toMatch.length == argCount) {
+					for (int p = 0; p < argCount; p++)
+						if (toMatch[p] != argumentTypes[p])
+							continue nextMethod;
+						if (match != null) return null; // collision case
+						match = method;
+				}
+			}
+		}
+		return match;
+	}
+	
+	 /**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getExactMethod(char[], TypeBinding[],CompilationUnitScope)
+	 */
+	public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
+		// sender from refScope calls recordTypeReference(this)
+		int argCount = argumentTypes.length;
+		boolean foundNothing = true;
+		MethodBinding match = null;
+
+		if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
+			long range;
+			if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+				nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+					MethodBinding method = this.methods[imethod];
+					foundNothing = false; // inner type lookups must know that a method with this name exists
+					if (method.parameters.length == argCount) {
+						TypeBinding[] toMatch = method.parameters;
+						for (int iarg = 0; iarg < argCount; iarg++)
+							if (toMatch[iarg] != argumentTypes[iarg])
+								continue nextMethod;
+						if (match != null) return null; // collision case
+						match = method;
+					}
+				}
+			}
+		} else {
+			MethodBinding[] matchingMethods = getMethods(selector); // takes care of duplicates & default abstract methods
+			foundNothing = matchingMethods == Binding.NO_METHODS;
+			nextMethod : for (int m = matchingMethods.length; --m >= 0;) {
+				MethodBinding method = matchingMethods[m];
+				TypeBinding[] toMatch = method.parameters;
+				if (toMatch.length == argCount) {
+					for (int p = 0; p < argCount; p++)
+						if (toMatch[p] != argumentTypes[p])
+							continue nextMethod;
+						if (match != null) return null; // collision case
+						match = method;
+				}
+			}
+		}
+		if (match != null) {
+			// cannot be picked up as an exact match if its a possible anonymous case, such as:
+			// class A<T extends Number> { public void id(T t) {} }
+			// class B<TT> extends A<Integer> { public <ZZ> void id(Integer i) {} }
+			if (match.hasSubstitutedParameters()) return null;
+			return match;
+		}
+
+		if (foundNothing && (this.arguments == null || this.arguments.length <= 1)) {
+			if (isInterface()) {
+				 if (superInterfaces().length == 1) {
+					if (refScope != null)
+						refScope.recordTypeReference(this.superInterfaces[0]);
+					return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
+				 }
+			} else if (superclass() != null) {
+				if (refScope != null)
+					refScope.recordTypeReference(this.superclass);
+				return this.superclass.getExactMethod(selector, argumentTypes, refScope);
+			}
+		}
+		return null;
+	}
+
+	 /**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getField(char[], boolean)
+	 */
+	public FieldBinding getField(char[] fieldName, boolean needResolve) {
+		fields(); // ensure fields have been initialized... must create all at once unlike methods
+		return ReferenceBinding.binarySearch(fieldName, this.fields);
+	}
+	 
+ 	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getMemberType(char[])
+	 */
+	public ReferenceBinding getMemberType(char[] typeName) {
+		memberTypes(); // ensure memberTypes have been initialized... must create all at once unlike methods
+		int typeLength = typeName.length;
+		for (int i = this.memberTypes.length; --i >= 0;) {
+			ReferenceBinding memberType = this.memberTypes[i];
+			if (memberType.sourceName.length == typeLength && CharOperation.equals(memberType.sourceName, typeName))
+				return memberType;
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getMethods(char[])
+	 */
+	public MethodBinding[] getMethods(char[] selector) {
+		if (this.methods != null) {
+			long range;
+			if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+				int start = (int) range;
+				int length = (int) (range >> 32) - start + 1;
+				// cannot optimize since some clients rely on clone array
+				// if (start == 0 && length == this.methods.length)
+				//	return this.methods; // current set is already interesting subset
+				MethodBinding[] result;
+				System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
+				return result;
+			}
+		}
+		if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+			return Binding.NO_METHODS; // have created all the methods and there are no matches
+
+		MethodBinding[] parameterizedMethods = null;
+		try {
+		    MethodBinding[] originalMethods = this.type.getMethods(selector);
+		    int length = originalMethods.length;
+		    if (length == 0) return Binding.NO_METHODS;
+
+		    parameterizedMethods = new MethodBinding[length];
+		    for (int i = 0; i < length; i++)
+		    	// substitute methods, so as to get updated declaring class at least
+	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
+		    if (this.methods == null) {
+				MethodBinding[] temp = new MethodBinding[length];
+				System.arraycopy(parameterizedMethods, 0, temp, 0, length);
+				this.methods = temp; // must be a copy of parameterizedMethods since it will be returned below
+		    } else {
+				int total = length + this.methods.length;
+				MethodBinding[] temp = new MethodBinding[total];
+				System.arraycopy(parameterizedMethods, 0, temp, 0, length);
+				System.arraycopy(this.methods, 0, temp, length, this.methods.length);
+				if (total > 1)
+					ReferenceBinding.sortMethods(temp, 0, total); // resort to ensure order is good
+				this.methods = temp;
+			}
+		    return parameterizedMethods;
+		} finally {
+			// if the original methods cannot be retrieved (ex. AbortCompilation), then assume we do not have any methods
+		    if (parameterizedMethods == null)
+		        this.methods = parameterizedMethods = Binding.NO_METHODS;
+		}
+	}
+
+	public int getOuterLocalVariablesSlotSize() {
+		return genericType().getOuterLocalVariablesSlotSize();
+	}
+
+	public boolean hasMemberTypes() {
+	    return this.type.hasMemberTypes();
+	}
+
+	public boolean hasTypeBit(int bit) {
+		TypeBinding erasure = erasure();
+		if (erasure instanceof ReferenceBinding)
+			return ((ReferenceBinding) erasure).hasTypeBit(bit);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#implementsMethod(MethodBinding)
+	 */
+	public boolean implementsMethod(MethodBinding method) {
+		return this.type.implementsMethod(method); // erasure
+	}
+
+	void initialize(ReferenceBinding someType, TypeBinding[] someArguments) {
+		this.type = someType;
+		this.sourceName = someType.sourceName;
+		this.compoundName = someType.compoundName;
+		this.fPackage = someType.fPackage;
+		this.fileName = someType.fileName;
+		// should not be set yet
+		// this.superclass = null;
+		// this.superInterfaces = null;
+		// this.fields = null;
+		// this.methods = null;
+		this.modifiers = someType.modifiers & ~ExtraCompilerModifiers.AccGenericSignature; // discard generic signature, will compute later
+		// only set AccGenericSignature if parameterized or have enclosing type required signature
+		if (someArguments != null) {
+			this.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+		} else if (this.enclosingType != null) {
+			this.modifiers |= (this.enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
+			this.tagBits |= this.enclosingType.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType);
+		}
+		if (someArguments != null) {
+			this.arguments = someArguments;
+			for (int i = 0, length = someArguments.length; i < length; i++) {
+				TypeBinding someArgument = someArguments[i];
+				switch (someArgument.kind()) {
+					case Binding.WILDCARD_TYPE :
+						this.tagBits |= TagBits.HasDirectWildcard;
+						if (((WildcardBinding) someArgument).boundKind != Wildcard.UNBOUND) {
+							this.tagBits |= TagBits.IsBoundParameterizedType;
+						}
+						break;
+					case Binding.INTERSECTION_TYPE :
+						this.tagBits |= TagBits.HasDirectWildcard | TagBits.IsBoundParameterizedType; // Surely NOT X<?,?>, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366131
+						break;
+					default :
+						this.tagBits |= TagBits.IsBoundParameterizedType;
+						break;
+				}
+				this.tagBits |= someArgument.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences);
+			}
+		}
+		this.tagBits |= someType.tagBits & (TagBits.IsLocalType| TagBits.IsMemberType | TagBits.IsNestedType | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences | TagBits.AnnotationNullMASK);
+		this.tagBits &= ~(TagBits.AreFieldsComplete|TagBits.AreMethodsComplete);
+	}
+
+	protected void initializeArguments() {
+	    // do nothing for true parameterized types (only for raw types)
+	}
+
+	void initializeForStaticImports() {
+		this.type.initializeForStaticImports();
+	}
+
+	public boolean isEquivalentTo(TypeBinding otherType) {
+		if (this == otherType)
+		    return true;
+	    if (otherType == null)
+	        return false;
+	    switch(otherType.kind()) {
+
+	    	case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+	        	return ((WildcardBinding) otherType).boundCheck(this);
+
+	    	case Binding.PARAMETERIZED_TYPE :
+	            ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+	            if (this.type != otherParamType.type)
+	                return false;
+	            if (!isStatic()) { // static member types do not compare their enclosing
+	            	ReferenceBinding enclosing = enclosingType();
+	            	if (enclosing != null) {
+	            		ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+	            		if (otherEnclosing == null) return false;
+	            		if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
+							if (enclosing != otherEnclosing) return false;
+	            		} else {
+	            			if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+	            		}
+	            	}
+	            }
+	            if (this.arguments == null) {
+	            	return otherParamType.arguments == null;
+	            }
+	            int length = this.arguments.length;
+	            TypeBinding[] otherArguments = otherParamType.arguments;
+	            if (otherArguments == null || otherArguments.length != length) return false;
+	            for (int i = 0; i < length; i++) {
+	            	if (!this.arguments[i].isTypeArgumentContainedBy(otherArguments[i]))
+	            		return false;
+	            }
+	            return true;
+
+	    	case Binding.RAW_TYPE :
+	            return erasure() == otherType.erasure();
+	    }
+	    /* With the hybrid 1.4/1.5+ projects modes, while establishing type equivalence, we need to
+	       be prepared for a type such as Map appearing in one of three forms: As (a) a ParameterizedTypeBinding 
+	       e.g Map<String, String>, (b) as RawTypeBinding Map#RAW and finally (c) as a BinaryTypeBinding 
+	       When the usage of a type lacks type parameters, whether we land up with the raw form or not depends
+	       on whether the underlying type was "seen to be" a generic type in the particular build environment or
+	       not. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827 
+	     */
+	    if (erasure() == otherType) {
+	    	return true;
+	    }
+	    return false;
+	}
+
+	public boolean isHierarchyConnected() {
+		return this.superclass != null && this.superInterfaces != null;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
+	 */
+	public boolean isRawSubstitution() {
+		return isRawType();
+	}
+
+	public int kind() {
+		return PARAMETERIZED_TYPE;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#memberTypes()
+	 */
+	public ReferenceBinding[] memberTypes() {
+		if (this.memberTypes == null) {
+			try {
+				ReferenceBinding[] originalMemberTypes = this.type.memberTypes();
+				int length = originalMemberTypes.length;
+				ReferenceBinding[] parameterizedMemberTypes = new ReferenceBinding[length];
+				// boolean isRaw = this.isRawType();
+				for (int i = 0; i < length; i++)
+					// substitute all member types, so as to get updated enclosing types
+					parameterizedMemberTypes[i] = /*isRaw && originalMemberTypes[i].isGenericType()
+						? this.environment.createRawType(originalMemberTypes[i], this)
+						: */ this.environment.createParameterizedType(originalMemberTypes[i], null, this);
+				this.memberTypes = parameterizedMemberTypes;
+			} finally {
+				// if the original fields cannot be retrieved (ex. AbortCompilation), then assume we do not have any fields
+				if (this.memberTypes == null)
+					this.memberTypes = Binding.NO_MEMBER_TYPES;
+			}
+		}
+		return this.memberTypes;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#methods()
+	 */
+	public MethodBinding[] methods() {
+		if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+			return this.methods;
+
+		try {
+		    MethodBinding[] originalMethods = this.type.methods();
+		    int length = originalMethods.length;
+		    MethodBinding[] parameterizedMethods = new MethodBinding[length];
+		    for (int i = 0; i < length; i++)
+		    	// substitute all methods, so as to get updated declaring class at least
+	            parameterizedMethods[i] = createParameterizedMethod(originalMethods[i]);
+		    this.methods = parameterizedMethods;
+		} finally {
+			// if the original methods cannot be retrieved (ex. AbortCompilation), then assume we do not have any methods
+		    if (this.methods == null)
+		        this.methods = Binding.NO_METHODS;
+
+			this.tagBits |=  TagBits.AreMethodsComplete;
+		}
+		return this.methods;
+	}
+	/**
+	 * Define to be able to get the computeId() for the inner type binding.
+	 *
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#problemId()
+	 */
+	public int problemId() {
+		return this.type.problemId();
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#qualifiedPackageName()
+	 */
+	public char[] qualifiedPackageName() {
+		return this.type.qualifiedPackageName();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#qualifiedSourceName()
+	 */
+	public char[] qualifiedSourceName() {
+		return this.type.qualifiedSourceName();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
+	 */
+	public char[] readableName() {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+		if (isMemberType()) {
+			nameBuffer.append(CharOperation.concat(enclosingType().readableName(), this.sourceName, '.'));
+		} else {
+			nameBuffer.append(CharOperation.concatWith(this.type.compoundName, '.'));
+		}
+		if (this.arguments != null && this.arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
+			nameBuffer.append('<');
+		    for (int i = 0, length = this.arguments.length; i < length; i++) {
+		        if (i > 0) nameBuffer.append(',');
+		        nameBuffer.append(this.arguments[i].readableName());
+		    }
+		    nameBuffer.append('>');
+		}
+		int nameLength = nameBuffer.length();
+		char[] readableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, readableName, 0);
+	    return readableName;
+	}
+
+	ReferenceBinding resolve() {
+		if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
+			return this;
+
+		this.tagBits &= ~TagBits.HasUnresolvedTypeVariables; // can be recursive so only want to call once
+		ReferenceBinding resolvedType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.type, this.environment, false /* no raw conversion */); // still part of parameterized type ref
+		this.tagBits |= resolvedType.tagBits & TagBits.ContainsNestedTypeReferences;
+		if (this.arguments != null) {
+			int argLength = this.arguments.length;
+			for (int i = 0; i < argLength; i++) {
+				TypeBinding resolveType = BinaryTypeBinding.resolveType(this.arguments[i], this.environment, true /* raw conversion */);
+				this.arguments[i] = resolveType;
+				this.tagBits |= resolvedType.tagBits & TagBits.ContainsNestedTypeReferences;
+			}
+			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565, Removed generic check
+			   and arity check since we are dealing with binary types here and the fact that
+			   the compiler produced class files for these types at all is proof positive that
+			   the generic check and the arity check passed in the build environment that produced
+			   these class files. Otherwise we don't handle mixed 1.5 and 1.4 projects correctly.
+			   Just as with bounds check below, incremental build will propagate the change and
+			   detect problems in source.
+			 */
+			
+//			// arity check
+//			TypeVariableBinding[] refTypeVariables = resolvedType.typeVariables();
+//			if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic
+//				// Below 1.5, we should have already complained about the use of type parameters.
+//				boolean isCompliant15 = this.environment.globalOptions.originalSourceLevel >= ClassFileConstants.JDK1_5;
+//				if (isCompliant15 && (resolvedType.tagBits & TagBits.HasMissingType) == 0) {
+//					this.environment.problemReporter.nonGenericTypeCannotBeParameterized(0, null, resolvedType, this.arguments);
+//				}
+//				return this;
+//			} else if (argLength != refTypeVariables.length) { // check arity
+//				this.environment.problemReporter.incorrectArityForParameterizedType(null, resolvedType, this.arguments);
+//				return this; // cannot reach here as AbortCompilation is thrown
+//			}
+			// check argument type compatibility... REMOVED for now since incremental build will propagate change & detect in source
+//			for (int i = 0; i < argLength; i++) {
+//			    TypeBinding resolvedArgument = this.arguments[i];
+//				if (refTypeVariables[i].boundCheck(this, resolvedArgument) != TypeConstants.OK) {
+//					this.environment.problemReporter.typeMismatchError(resolvedArgument, refTypeVariables[i], resolvedType, null);
+//			    }
+//			}
+		}
+		return this;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
+	 */
+	public char[] shortReadableName() {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+		if (isMemberType()) {
+			nameBuffer.append(CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.'));
+		} else {
+			nameBuffer.append(this.type.sourceName);
+		}
+		if (this.arguments != null && this.arguments.length > 0) { // empty arguments array happens when PTB has been created just to capture type annotations
+			nameBuffer.append('<');
+		    for (int i = 0, length = this.arguments.length; i < length; i++) {
+		        if (i > 0) nameBuffer.append(',');
+		        nameBuffer.append(this.arguments[i].shortReadableName());
+		    }
+		    nameBuffer.append('>');
+		}
+		int nameLength = nameBuffer.length();
+		char[] shortReadableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, shortReadableName, 0);
+	    return shortReadableName;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
+	 */
+	public char[] signature() {
+	    if (this.signature == null) {
+	        this.signature = this.type.signature();  // erasure
+	    }
+		return this.signature;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#sourceName()
+	 */
+	public char[] sourceName() {
+		return this.type.sourceName();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#substitute(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)
+	 */
+	public TypeBinding substitute(TypeVariableBinding originalVariable) {
+
+		ParameterizedTypeBinding currentType = this;
+		while (true) {
+			TypeVariableBinding[] typeVariables = currentType.type.typeVariables();
+			int length = typeVariables.length;
+			// check this variable can be substituted given parameterized type
+			if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) {
+			    // lazy init, since cannot do so during binding creation if during supertype connection
+			    if (currentType.arguments == null)
+					currentType.initializeArguments(); // only for raw types
+			    if (currentType.arguments != null) {
+			    	 if (currentType.arguments.length == 0) { // diamond type
+					    	return originalVariable;
+					    }
+			    	 return currentType.arguments[originalVariable.rank];
+			    }	
+			}
+			// recurse on enclosing type, as it may hold more substitutions to perform
+			if (currentType.isStatic()) break;
+			ReferenceBinding enclosing = currentType.enclosingType();
+			if (!(enclosing instanceof ParameterizedTypeBinding))
+				break;
+			currentType = (ParameterizedTypeBinding) enclosing;
+		}
+		return originalVariable;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#superclass()
+	 */
+	public ReferenceBinding superclass() {
+	    if (this.superclass == null) {
+	        // note: Object cannot be generic
+	        ReferenceBinding genericSuperclass = this.type.superclass();
+	        if (genericSuperclass == null) return null; // e.g. interfaces
+		    this.superclass = (ReferenceBinding) Scope.substitute(this, genericSuperclass);
+	    }
+		return this.superclass;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#superInterfaces()
+	 */
+	public ReferenceBinding[] superInterfaces() {
+	    if (this.superInterfaces == null) {
+	    		if (this.type.isHierarchyBeingConnected())
+	    			return Binding.NO_SUPERINTERFACES; // prevent superinterfaces from being assigned before they are connected
+	    		this.superInterfaces = Scope.substitute(this, this.type.superInterfaces());
+	    }
+		return this.superInterfaces;
+	}
+
+	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
+		boolean update = false;
+		if (this.type == unresolvedType) {
+			this.type = resolvedType; // cannot be raw since being parameterized below
+			update = true;
+			ReferenceBinding enclosing = resolvedType.enclosingType();
+			if (enclosing != null) {
+				this.enclosingType = (ReferenceBinding) env.convertUnresolvedBinaryToRawType(enclosing); // needed when binding unresolved member type
+			}
+		}
+		if (this.arguments != null) {
+			for (int i = 0, l = this.arguments.length; i < l; i++) {
+				if (this.arguments[i] == unresolvedType) {
+					this.arguments[i] = env.convertUnresolvedBinaryToRawType(resolvedType);
+					update = true;
+				}
+			}
+		}
+		if (update)
+			initialize(this.type, this.arguments);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#syntheticEnclosingInstanceTypes()
+	 */
+	public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
+		return genericType().syntheticEnclosingInstanceTypes();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#syntheticOuterLocalVariables()
+	 */
+	public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
+		return genericType().syntheticOuterLocalVariables();
+	}
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+	    StringBuffer buffer = new StringBuffer(30);
+	    if (this.type instanceof UnresolvedReferenceBinding) {
+	    	buffer.append(debugName());
+	    } else {
+			if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
+			if (isPublic()) buffer.append("public "); //$NON-NLS-1$
+			if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
+			if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
+			if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
+			if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
+			if (isFinal()) buffer.append("final "); //$NON-NLS-1$
+
+			if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+			else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+			else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+			else buffer.append("interface "); //$NON-NLS-1$
+			buffer.append(debugName());
+
+			buffer.append("\n\textends "); //$NON-NLS-1$
+			buffer.append((this.superclass != null) ? this.superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
+
+			if (this.superInterfaces != null) {
+				if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
+					buffer.append("\n\timplements : "); //$NON-NLS-1$
+					for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+						if (i  > 0)
+							buffer.append(", "); //$NON-NLS-1$
+						buffer.append((this.superInterfaces[i] != null) ? this.superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
+					}
+				}
+			} else {
+				buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
+			}
+
+			if (enclosingType() != null) {
+				buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
+				buffer.append(enclosingType().debugName());
+			}
+
+			if (this.fields != null) {
+				if (this.fields != Binding.NO_FIELDS) {
+					buffer.append("\n/*   fields   */"); //$NON-NLS-1$
+					for (int i = 0, length = this.fields.length; i < length; i++)
+					    buffer.append('\n').append((this.fields[i] != null) ? this.fields[i].toString() : "NULL FIELD"); //$NON-NLS-1$
+				}
+			} else {
+				buffer.append("NULL FIELDS"); //$NON-NLS-1$
+			}
+
+			if (this.methods != null) {
+				if (this.methods != Binding.NO_METHODS) {
+					buffer.append("\n/*   methods   */"); //$NON-NLS-1$
+					for (int i = 0, length = this.methods.length; i < length; i++)
+						buffer.append('\n').append((this.methods[i] != null) ? this.methods[i].toString() : "NULL METHOD"); //$NON-NLS-1$
+				}
+			} else {
+				buffer.append("NULL METHODS"); //$NON-NLS-1$
+			}
+
+	//		if (memberTypes != null) {
+	//			if (memberTypes != NoMemberTypes) {
+	//				buffer.append("\n/*   members   */");
+	//				for (int i = 0, length = memberTypes.length; i < length; i++)
+	//					buffer.append('\n').append((memberTypes[i] != null) ? memberTypes[i].toString() : "NULL TYPE");
+	//			}
+	//		} else {
+	//			buffer.append("NULL MEMBER TYPES");
+	//		}
+
+			buffer.append("\n\n"); //$NON-NLS-1$
+	    }
+		return buffer.toString();
+
+	}
+
+	public TypeVariableBinding[] typeVariables() {
+		if (this.arguments == null) {
+			// retain original type variables if not substituted (member type of parameterized type)
+			return this.type.typeVariables();
+		}
+		return Binding.NO_TYPE_VARIABLES;
+	}
+	
+	public FieldBinding[] unResolvedFields() {
+		return this.fields;
+	}
+	public MethodBinding getSingleAbstractMethod(final Scope scope) {
+		if (this.singleAbstractMethod != null) {
+			return this.singleAbstractMethod;
+		}
+		final ReferenceBinding genericType = genericType();
+		MethodBinding theAbstractMethod = genericType.getSingleAbstractMethod(scope);
+		if (theAbstractMethod == null || !theAbstractMethod.isValidBinding())
+			return this.singleAbstractMethod = theAbstractMethod;
+		
+		TypeBinding [] typeArguments = this.arguments; // A1 ... An 
+		TypeVariableBinding [] typeParameters = genericType.typeVariables(); // P1 ... Pn
+		TypeBinding [] types = new TypeBinding[typeArguments.length];  // T1 ... Tn
+		for (int i = 0, length = typeArguments.length; i < length; i++) {
+			TypeBinding typeArgument = typeArguments[i];
+			switch (typeArgument.kind()) {
+				case Binding.WILDCARD_TYPE :
+					WildcardBinding wildcard = (WildcardBinding) typeArgument;
+					switch(wildcard.boundKind) {
+	    				case Wildcard.EXTENDS :
+	    				case Wildcard.SUPER :
+	    					types[i] = wildcard.bound;
+	    					break;
+	    				case Wildcard.UNBOUND :
+	    					// if Pi has upper bound Bi that mentions none of P1...Pn, then Ti = Bi; otherwise, Ti = Object
+	    					final TypeBinding upperBound = typeParameters[i].firstBound;
+							if (upperBound == null || typeParametersMentioned(upperBound)) {
+	    						types[i] = scope.getJavaLangObject();
+	    					} else {
+	    						types[i] = upperBound;
+	    					}
+	    					break;
+					}
+					break;
+				default :
+					types[i] = typeArgument;
+					break;
+			}
+			if (typeParameters[i].boundCheck(null, types[i], scope) != TypeConstants.OK)
+				return this.singleAbstractMethod = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NotAWellFormedParameterizedType);
+		}
+		ReferenceBinding declaringType = scope.environment().createParameterizedType(genericType, types, genericType.enclosingType());
+		declaringType = (ReferenceBinding) declaringType.findSuperTypeOriginatingFrom(theAbstractMethod.declaringClass);
+		MethodBinding [] choices = declaringType.getMethods(theAbstractMethod.selector);
+		for (int i = 0, length = choices.length; i < length; i++) {
+			MethodBinding method = choices[i];
+			if (!method.isAbstract() || method.redeclaresPublicObjectMethod(scope)) continue; // (re)skip statics, defaults, public object methods ...
+			this.singleAbstractMethod = method;
+			break;
+		}
+		return this.singleAbstractMethod;
+	}
+
+	private boolean typeParametersMentioned(TypeBinding upperBound) {
+		class MentionListener extends TypeBindingVisitor {
+			private boolean typeParametersMentioned = false;
+			public boolean visit(TypeVariableBinding typeVariable) {
+				this.typeParametersMentioned = true;
+				return false;
+			}
+			public boolean typeParametersMentioned() {
+				return this.typeParametersMentioned;
+			}
+		}
+		MentionListener mentionListener = new MentionListener();
+		TypeBindingVisitor.visit(mentionListener, upperBound);
+		return mentionListener.typeParametersMentioned();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
new file mode 100644
index 0000000..f48bb45
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolyTypeBinding.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+
+public class PolyTypeBinding extends TypeBinding {
+
+	Expression expression;
+	
+	public PolyTypeBinding(Expression expression) {
+		this.expression = expression;
+	}
+	
+	public char[] constantPoolName() {
+		throw new UnsupportedOperationException();  // should never reach code generation
+	}
+
+	public PackageBinding getPackage() {
+		throw new UnsupportedOperationException();  // nobody should be asking this question.
+	}
+
+	public boolean isCompatibleWith(TypeBinding left, Scope scope) {
+		return this.expression.isCompatibleWith(left, scope);
+	}
+
+	public char[] qualifiedSourceName() {
+		return readableName();
+	}
+
+	public char[] sourceName() {
+		return readableName();
+	}
+
+	public char[] readableName() {
+		return this.expression.printExpression(0,  new StringBuffer()).toString().toCharArray();
+	}
+	
+	public String toString() {
+		StringBuffer buffer = new StringBuffer("PolyTypeBinding for: "); //$NON-NLS-1$
+		return this.expression.printExpression(0,  buffer).toString();
+	}
+	
+	public int kind() {
+		return Binding.POLY_TYPE;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
new file mode 100644
index 0000000..c41e93a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+/**
+ * Binding denoting a polymorphic method
+ */
+public class PolymorphicMethodBinding extends MethodBinding {
+
+	protected MethodBinding polymorphicMethod;
+
+	public PolymorphicMethodBinding(MethodBinding polymorphicMethod, TypeBinding[] parameterTypes) {
+		super(
+				polymorphicMethod.modifiers,
+				polymorphicMethod.selector,
+				polymorphicMethod.returnType,
+				parameterTypes,
+				polymorphicMethod.thrownExceptions,
+				polymorphicMethod.declaringClass);
+		this.polymorphicMethod = polymorphicMethod;
+		this.tagBits = polymorphicMethod.tagBits;
+	}
+	
+	public PolymorphicMethodBinding(MethodBinding polymorphicMethod, TypeBinding returnType, TypeBinding[] parameterTypes) {
+		super(
+				polymorphicMethod.modifiers,
+				polymorphicMethod.selector,
+				returnType,
+				parameterTypes,
+				polymorphicMethod.thrownExceptions,
+				polymorphicMethod.declaringClass);
+		this.polymorphicMethod = polymorphicMethod;
+		this.tagBits = polymorphicMethod.tagBits;
+	}
+
+	public MethodBinding original() {
+		return this.polymorphicMethod;
+	}
+	
+	public boolean isPolymorphic() {
+		return true;
+	}
+
+	public boolean matches(TypeBinding[] matchingParameters, TypeBinding matchingReturnType) {
+		int cachedParametersLength = this.parameters == null ? 0 : this.parameters.length;
+		int matchingParametersLength = matchingParameters == null ? 0 : matchingParameters.length;
+		if (matchingParametersLength != cachedParametersLength) {
+			return false;
+		}
+		for (int j = 0; j < cachedParametersLength; j++){
+			if (this.parameters[j] != matchingParameters[j]) {
+				return false;
+			}
+		}
+		TypeBinding cachedReturnType = this.returnType;
+		if (matchingReturnType == null) {
+			if (cachedReturnType != null) {
+				return false;
+			}
+		} else if (cachedReturnType == null) {
+			return false;
+		} else if (matchingReturnType != cachedReturnType) {
+			return false;
+		}
+		// all arguments match
+		return true;
+	}
+	
+	/*
+	 * Even if polymorphic methods are varargs method, we don't want them to be treated as varargs method
+	 */
+	public boolean isVarargs() {
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java
new file mode 100644
index 0000000..fa80547
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class ProblemBinding extends Binding {
+	public char[] name;
+	public ReferenceBinding searchType;
+	private int problemId;
+// NOTE: must only answer the subset of the name related to the problem
+
+public ProblemBinding(char[][] compoundName, int problemId) {
+	this(CharOperation.concatWith(compoundName, '.'), problemId);
+}
+// NOTE: must only answer the subset of the name related to the problem
+
+public ProblemBinding(char[][] compoundName, ReferenceBinding searchType, int problemId) {
+	this(CharOperation.concatWith(compoundName, '.'), searchType, problemId);
+}
+ProblemBinding(char[] name, int problemId) {
+	this.name = name;
+	this.problemId = problemId;
+}
+ProblemBinding(char[] name, ReferenceBinding searchType, int problemId) {
+	this(name, problemId);
+	this.searchType = searchType;
+}
+/* API
+* Answer the receiver's binding type from Binding.BindingID.
+*/
+
+public final int kind() {
+	return VARIABLE | TYPE;
+}
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+
+public final int problemId() {
+	return this.problemId;
+}
+public char[] readableName() {
+	return this.name;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
new file mode 100644
index 0000000..883d0a7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class ProblemFieldBinding extends FieldBinding {
+	private int problemId;
+	public FieldBinding closestMatch;
+
+// NOTE: must only answer the subset of the name related to the problem
+
+public ProblemFieldBinding(ReferenceBinding declaringClass, char[] name, int problemId) {
+	this(null, declaringClass, name, problemId);
+}
+public ProblemFieldBinding(FieldBinding closestMatch, ReferenceBinding declaringClass, char[] name, int problemId) {
+	this.closestMatch = closestMatch;
+	this.declaringClass = declaringClass;
+	this.name = name;
+	this.problemId = problemId;
+}
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+
+public final int problemId() {
+	return this.problemId;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java
new file mode 100644
index 0000000..16ebebf
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class ProblemMethodBinding extends MethodBinding {
+
+	private int problemReason;
+	public MethodBinding closestMatch; // TODO (philippe) should rename into #alternateMatch
+
+public ProblemMethodBinding(char[] selector, TypeBinding[] args, int problemReason) {
+	this.selector = selector;
+	this.parameters = (args == null || args.length == 0) ? Binding.NO_PARAMETERS : args;
+	this.problemReason = problemReason;
+	this.thrownExceptions = Binding.NO_EXCEPTIONS;
+}
+public ProblemMethodBinding(char[] selector, TypeBinding[] args, ReferenceBinding declaringClass, int problemReason) {
+	this.selector = selector;
+	this.parameters = (args == null || args.length == 0) ? Binding.NO_PARAMETERS : args;
+	this.declaringClass = declaringClass;
+	this.problemReason = problemReason;
+	this.thrownExceptions = Binding.NO_EXCEPTIONS;
+}
+public ProblemMethodBinding(MethodBinding closestMatch, char[] selector, TypeBinding[] args, int problemReason) {
+	this(selector, args, problemReason);
+	this.closestMatch = closestMatch;
+	if (closestMatch != null && problemReason != ProblemReasons.Ambiguous) this.declaringClass = closestMatch.declaringClass;
+}
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+
+public final int problemId() {
+	return this.problemReason;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java
new file mode 100644
index 0000000..382e01d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class ProblemPackageBinding extends PackageBinding {
+	private int problemId;
+// NOTE: must only answer the subset of the name related to the problem
+
+ProblemPackageBinding(char[][] compoundName, int problemId) {
+	this.compoundName = compoundName;
+	this.problemId = problemId;
+}
+ProblemPackageBinding(char[] name, int problemId) {
+	this(new char[][] {name}, problemId);
+}
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+
+public final int problemId() {
+	return this.problemId;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java
new file mode 100644
index 0000000..fa11b45
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *	   Stephan Herrmann - Contribution for
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public interface ProblemReasons {
+	final int NoError = 0;
+	final int NotFound = 1;
+	final int NotVisible = 2;
+	final int Ambiguous = 3;
+	final int InternalNameProvided = 4; // used if an internal name is used in source
+	final int InheritedNameHidesEnclosingName = 5;
+	final int NonStaticReferenceInConstructorInvocation = 6;
+	final int NonStaticReferenceInStaticContext = 7;
+	final int ReceiverTypeNotVisible = 8;
+	final int IllegalSuperTypeVariable = 9;
+	final int ParameterBoundMismatch = 10; // for generic method
+	final int TypeParameterArityMismatch = 11; // for generic method
+	final int ParameterizedMethodTypeMismatch = 12; // for generic method
+	final int TypeArgumentsForRawGenericMethod = 13; // for generic method
+	final int InvalidTypeForStaticImport = 14;
+	final int InvalidTypeForAutoManagedResource = 15;
+	final int VarargsElementTypeNotVisible = 16;
+	final int NoSuchSingleAbstractMethod = 17;
+	final int NotAWellFormedParameterizedType = 18;
+	final int IntersectionHasMultipleFunctionalInterfaces = 19;
+	final int NonStaticOrAlienTypeReceiver = 20;
+	final int AttemptToBypassDirectSuper = 21; // super access within default method
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
new file mode 100644
index 0000000..da3bd82
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class ProblemReferenceBinding extends ReferenceBinding {
+	ReferenceBinding closestMatch;
+	private int problemReason;
+
+// NOTE: must only answer the subset of the name related to the problem
+
+public ProblemReferenceBinding(char[][] compoundName, ReferenceBinding closestMatch, int problemReason) {
+	this.compoundName = compoundName;
+	this.closestMatch = closestMatch;
+	this.problemReason = problemReason;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#closestMatch()
+ */
+public TypeBinding closestMatch() {
+	return this.closestMatch;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#closestMatch()
+ */
+public ReferenceBinding closestReferenceMatch() {
+	return this.closestMatch;
+}
+
+public boolean hasTypeBit(int bit) {
+	if (this.closestMatch != null)
+		return this.closestMatch.hasTypeBit(bit);
+	return false;
+}
+
+/* API
+* Answer the problem id associated with the receiver.
+* NoError if the receiver is a valid binding.
+*/
+public int problemId() {
+	return this.problemReason;
+}
+
+public static String problemReasonString(int problemReason) {
+	try {
+		Class reasons = ProblemReasons.class;
+		String simpleName = reasons.getName();
+		int lastDot = simpleName.lastIndexOf('.');
+		if (lastDot >= 0) {
+			simpleName = simpleName.substring(lastDot+1);
+		}
+		Field[] fields = reasons.getFields();
+		for (int i = 0, length = fields.length; i < length; i++) {
+			Field field = fields[i];
+			if (!field.getType().equals(int.class)) continue;
+			if (field.getInt(reasons) == problemReason) {
+				return simpleName + '.' + field.getName();
+			}
+		}
+	} catch (IllegalAccessException e) {
+		// do nothing
+	}
+	return "unknown"; //$NON-NLS-1$
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#shortReadableName()
+ */
+public char[] shortReadableName() {
+	return readableName();
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer(10);
+	buffer.append("ProblemType:[compoundName="); //$NON-NLS-1$
+	buffer.append(this.compoundName == null ? "<null>" : new String(CharOperation.concatWith(this.compoundName,'.'))); //$NON-NLS-1$
+	buffer.append("][problemID=").append(problemReasonString(this.problemReason)); //$NON-NLS-1$
+	buffer.append("][closestMatch="); //$NON-NLS-1$
+	buffer.append(this.closestMatch == null ? "<null>" : this.closestMatch.toString()); //$NON-NLS-1$
+	buffer.append("]"); //$NON-NLS-1$
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
new file mode 100644
index 0000000..66390e3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * Denote a raw type, i.e. a generic type referenced without any type arguments.
+ * e.g. X<T extends Exception> can be used a raw type 'X', in which case it
+ * 	will behave as X<Exception>
+ */
+public class RawTypeBinding extends ParameterizedTypeBinding {
+
+    /**
+     * Raw type arguments are erasure of respective parameter bounds. But we may not have resolved
+     * these bounds yet if creating raw types while supertype hierarchies are being connected.
+     * Therefore, use 'null' instead, and access these in a lazy way later on (when substituting).
+     */
+	public RawTypeBinding(ReferenceBinding type, ReferenceBinding enclosingType, LookupEnvironment environment){
+		super(type, null, enclosingType, environment);
+		this.tagBits &= ~TagBits.HasMissingType;
+		if ((type.tagBits & TagBits.HasMissingType) != 0) {
+			if (type instanceof MissingTypeBinding) {
+				this.tagBits |= TagBits.HasMissingType;
+			} else if (type instanceof ParameterizedTypeBinding) {
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) type;
+				if (parameterizedTypeBinding.genericType() instanceof MissingTypeBinding) {
+					this.tagBits |= TagBits.HasMissingType;
+				}
+			}
+		}
+		if (enclosingType != null && (enclosingType.tagBits & TagBits.HasMissingType) != 0) {
+			if (enclosingType instanceof MissingTypeBinding) {
+				this.tagBits |= TagBits.HasMissingType;
+			} else if (enclosingType instanceof ParameterizedTypeBinding) {
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) enclosingType;
+				if (parameterizedTypeBinding.genericType() instanceof MissingTypeBinding) {
+					this.tagBits |= TagBits.HasMissingType;
+				}
+			}
+		}
+		if (enclosingType == null || (enclosingType.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) {
+			this.modifiers &= ~ExtraCompilerModifiers.AccGenericSignature; // only need signature if enclosing needs one
+		}
+	}
+
+	public char[] computeUniqueKey(boolean isLeaf) {
+	    StringBuffer sig = new StringBuffer(10);
+		if (isMemberType() && enclosingType().isParameterizedType()) {
+		    char[] typeSig = enclosingType().computeUniqueKey(false/*not a leaf*/);
+		    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+		    sig.append('.').append(sourceName()).append('<').append('>').append(';');
+		} else {
+		     sig.append(genericType().computeUniqueKey(false/*not a leaf*/));
+		     sig.insert(sig.length()-1, "<>"); //$NON-NLS-1$
+		}
+
+		int sigLength = sig.length();
+		char[] uniqueKey = new char[sigLength];
+		sig.getChars(0, sigLength, uniqueKey, 0);
+		return uniqueKey;
+   	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
+	 */
+	public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) {
+		if (originalMethod.typeVariables == Binding.NO_TYPE_VARIABLES || originalMethod.isStatic()) {
+			return super.createParameterizedMethod(originalMethod);
+		}
+		return this.environment.createParameterizedGenericMethod(originalMethod, this);
+	}
+
+	public int kind() {
+		return RAW_TYPE;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
+	 */
+	public String debugName() {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+		nameBuffer.append(actualType().sourceName()).append("#RAW"); //$NON-NLS-1$
+	    return nameBuffer.toString();
+	}
+
+	/**
+	 * Ltype<param1 ... paramN>;
+	 * LY<TT;>;
+	 */
+	public char[] genericTypeSignature() {
+		if (this.genericTypeSignature == null) {
+			if ((this.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0) {
+		    	this.genericTypeSignature = genericType().signature();
+			} else {
+			    StringBuffer sig = new StringBuffer(10);
+			    if (isMemberType()) {
+			    	ReferenceBinding enclosing = enclosingType();
+					char[] typeSig = enclosing.genericTypeSignature();
+					sig.append(typeSig, 0, typeSig.length-1);// copy all but trailing semicolon
+			    	if ((enclosing.modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
+			    		sig.append('.');
+			    	} else {
+			    		sig.append('$');
+			    	}
+			    	sig.append(sourceName());
+			    } else {
+			    	char[] typeSig = genericType().signature();
+					sig.append(typeSig, 0, typeSig.length-1);// copy all but trailing semicolon
+		    	}
+				sig.append(';');
+				int sigLength = sig.length();
+				this.genericTypeSignature = new char[sigLength];
+				sig.getChars(0, sigLength, this.genericTypeSignature, 0);
+			}
+		}
+		return this.genericTypeSignature;
+	}
+
+    public boolean isEquivalentTo(TypeBinding otherType) {
+		if (this == otherType || erasure() == otherType)
+		    return true;
+	    if (otherType == null)
+	        return false;
+	    switch(otherType.kind()) {
+
+	    	case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+	        	return ((WildcardBinding) otherType).boundCheck(this);
+
+	    	case Binding.GENERIC_TYPE :
+	    	case Binding.PARAMETERIZED_TYPE :
+	    	case Binding.RAW_TYPE :
+	            return erasure() == otherType.erasure();
+	    }
+        return false;
+	}
+
+    public boolean isProvablyDistinct(TypeBinding otherType) {
+		if (this == otherType || erasure() == otherType) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+		    return false;
+	    if (otherType == null)
+	        return true;
+	    switch(otherType.kind()) {
+
+	    	case Binding.GENERIC_TYPE :
+	    	case Binding.PARAMETERIZED_TYPE :
+	    	case Binding.RAW_TYPE :
+	            return erasure() != otherType.erasure();
+	    }
+        return true;
+	}
+
+	protected void initializeArguments() {
+		TypeVariableBinding[] typeVariables = genericType().typeVariables();
+		int length = typeVariables.length;
+		TypeBinding[] typeArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			// perform raw conversion on variable upper bound - could cause infinite regression if arguments were initialized lazily
+		    typeArguments[i] = this.environment.convertToRawType(typeVariables[i].erasure(), false /*do not force conversion of enclosing types*/);
+		}
+		this.arguments = typeArguments;
+	}
+	
+	public MethodBinding getSingleAbstractMethod(Scope scope) {
+		if (this.singleAbstractMethod != null) {
+			return this.singleAbstractMethod;
+		}
+		final ReferenceBinding genericType = genericType();
+		MethodBinding theAbstractMethod = genericType.getSingleAbstractMethod(scope);
+		if (theAbstractMethod == null || !theAbstractMethod.isValidBinding())
+			return this.singleAbstractMethod = theAbstractMethod;
+		
+		ReferenceBinding declaringType = (ReferenceBinding) scope.environment().convertToRawType(genericType, true);
+		declaringType = (ReferenceBinding) declaringType.findSuperTypeOriginatingFrom(theAbstractMethod.declaringClass);
+		MethodBinding [] choices = declaringType.getMethods(theAbstractMethod.selector);
+		for (int i = 0, length = choices.length; i < length; i++) {
+			MethodBinding method = choices[i];
+			if (!method.isAbstract() || method.redeclaresPublicObjectMethod(scope)) continue; // (re)skip statics, defaults, public object methods ...
+			this.singleAbstractMethod = method;
+			break;
+		}
+		return this.singleAbstractMethod;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
+	 */
+	public char[] readableName() /*java.lang.Object,  p.X<T> */ {
+	    char[] readableName;
+		if (isMemberType()) {
+			readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
+		} else {
+			readableName = CharOperation.concatWith(actualType().compoundName, '.');
+		}
+		return readableName;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
+	 */
+	public char[] shortReadableName() /*Object*/ {
+	    char[] shortReadableName;
+		if (isMemberType()) {
+			shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.');
+		} else {
+			shortReadableName = actualType().sourceName;
+		}
+		return shortReadableName;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
new file mode 100644
index 0000000..041bcee
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -0,0 +1,1833 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
+ *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *      Jesper S Moller - Contributions for
+ *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+/*
+Not all fields defined by this type (& its subclasses) are initialized when it is created.
+Some are initialized only when needed.
+
+Accessors have been provided for some public fields so all TypeBindings have the same API...
+but access public fields directly whenever possible.
+Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
+
+null is NOT a valid value for a non-public field... it just means the field is not initialized.
+*/
+
+abstract public class ReferenceBinding extends TypeBinding {
+
+	public char[][] compoundName;
+	public char[] sourceName;
+	public int modifiers;
+	public PackageBinding fPackage;
+	char[] fileName;
+	char[] constantPoolName;
+	char[] signature;
+
+	private SimpleLookupTable compatibleCache;
+
+	int typeBits; // additional bits characterizing this type
+	protected MethodBinding singleAbstractMethod;
+
+	public static final ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */
+		public boolean hasTypeBit(int bit) { return false; }
+	};
+
+	private static final Comparator FIELD_COMPARATOR = new Comparator() {
+		public int compare(Object o1, Object o2) {
+			char[] n1 = ((FieldBinding) o1).name;
+			char[] n2 = ((FieldBinding) o2).name;
+			return ReferenceBinding.compare(n1, n2, n1.length, n2.length);
+		}
+	};
+	private static final Comparator METHOD_COMPARATOR = new Comparator() {
+		public int compare(Object o1, Object o2) {
+			MethodBinding m1 = (MethodBinding) o1;
+			MethodBinding m2 = (MethodBinding) o2;
+			char[] s1 = m1.selector;
+			char[] s2 = m2.selector;
+			int c = ReferenceBinding.compare(s1, s2, s1.length, s2.length);
+			return c == 0 ? m1.parameters.length - m2.parameters.length : c;
+		}
+	};
+	static protected ProblemMethodBinding samProblemBinding = new ProblemMethodBinding(TypeConstants.ANONYMOUS_METHOD, null, ProblemReasons.NoSuchSingleAbstractMethod);
+
+public static FieldBinding binarySearch(char[] name, FieldBinding[] sortedFields) {
+	if (sortedFields == null)
+		return null;
+	int max = sortedFields.length;
+	if (max == 0)
+		return null;
+	int left = 0, right = max - 1, nameLength = name.length;
+	int mid = 0;
+	char[] midName;
+	while (left <= right) {
+		mid = left + (right - left) /2;
+		int compare = compare(name, midName = sortedFields[mid].name, nameLength, midName.length);
+		if (compare < 0) {
+			right = mid-1;
+		} else if (compare > 0) {
+			left = mid+1;
+		} else {
+			return sortedFields[mid];
+		}
+	}
+	return null;
+}
+
+/**
+ * Returns a combined range value representing: (start + (end<<32)), where start is the index of the first matching method
+ * (remember methods are sorted alphabetically on selectors), and end is the index of last contiguous methods with same
+ * selector.
+ * -1 means no method got found
+ * @param selector
+ * @param sortedMethods
+ * @return (start + (end<<32)) or -1 if no method found
+ */
+public static long binarySearch(char[] selector, MethodBinding[] sortedMethods) {
+	if (sortedMethods == null)
+		return -1;
+	int max = sortedMethods.length;
+	if (max == 0)
+		return -1;
+	int left = 0, right = max - 1, selectorLength = selector.length;
+	int mid = 0;
+	char[] midSelector;
+	while (left <= right) {
+		mid = left + (right - left) /2;
+		int compare = compare(selector, midSelector = sortedMethods[mid].selector, selectorLength, midSelector.length);
+		if (compare < 0) {
+			right = mid-1;
+		} else if (compare > 0) {
+			left = mid+1;
+		} else {
+			int start = mid, end = mid;
+			// find first method with same selector
+			while (start > left && CharOperation.equals(sortedMethods[start-1].selector, selector)){ start--; }
+			// find last method with same selector
+			while (end < right && CharOperation.equals(sortedMethods[end+1].selector, selector)){ end++; }
+			return start + ((long)end<< 32);
+		}
+	}
+	return -1;
+}
+
+/**
+ * Compares two strings lexicographically.
+ * The comparison is based on the Unicode value of each character in
+ * the strings.
+ *
+ * @return  the value <code>0</code> if the str1 is equal to str2;
+ *          a value less than <code>0</code> if str1
+ *          is lexicographically less than str2;
+ *          and a value greater than <code>0</code> if str1 is
+ *          lexicographically greater than str2.
+ */
+static int compare(char[] str1, char[] str2, int len1, int len2) {
+	int n= Math.min(len1, len2);
+	int i= 0;
+	while (n-- != 0) {
+		char c1= str1[i];
+		char c2= str2[i++];
+		if (c1 != c2) {
+			return c1 - c2;
+		}
+	}
+	return len1 - len2;
+}
+
+/**
+ * Sort the field array using a quicksort
+ */
+public static void sortFields(FieldBinding[] sortedFields, int left, int right) {
+	Arrays.sort(sortedFields, left, right, FIELD_COMPARATOR);
+}
+
+/**
+ * Sort the field array using a quicksort
+ */
+public static void sortMethods(MethodBinding[] sortedMethods, int left, int right) {
+	Arrays.sort(sortedMethods, left, right, METHOD_COMPARATOR);
+}
+
+/**
+ * Return the array of resolvable fields (resilience)
+ */
+public FieldBinding[] availableFields() {
+	return fields();
+}
+
+/**
+ * Return the array of resolvable methods (resilience)
+ */
+public MethodBinding[] availableMethods() {
+	return methods();
+}
+
+/**
+ * Answer true if the receiver can be instantiated
+ */
+public boolean canBeInstantiated() {
+	return (this.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation)) == 0;
+}
+
+/**
+ * Answer true if the receiver is visible to the invocationPackage.
+ */
+public final boolean canBeSeenBy(PackageBinding invocationPackage) {
+	if (isPublic()) return true;
+	if (isPrivate()) return false;
+
+	// isProtected() or isDefault()
+	return invocationPackage == this.fPackage;
+}
+
+/**
+ * Answer true if the receiver is visible to the receiverType and the invocationType.
+ */
+public final boolean canBeSeenBy(ReferenceBinding receiverType, ReferenceBinding invocationType) {
+	if (isPublic()) return true;
+
+	if (invocationType == this && invocationType == receiverType) return true;
+
+	if (isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the invocationType is the invocationType or its subclass
+		//    OR the type is a static method accessed directly through a type
+		//    OR previous assertions are true for one of the enclosing type
+		if (invocationType == this) return true;
+		if (invocationType.fPackage == this.fPackage) return true;
+
+		TypeBinding currentType = invocationType.erasure();
+		TypeBinding declaringClass = enclosingType().erasure(); // protected types always have an enclosing one
+		if (declaringClass == invocationType) return true;
+		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
+		//int depth = 0;
+		do {
+			if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
+			//depth++;
+			currentType = currentType.enclosingType();
+		} while (currentType != null);
+		return false;
+	}
+
+	if (isPrivate()) {
+		// answer true if the receiverType is the receiver or its enclosingType
+		// AND the invocationType and the receiver have a common enclosingType
+		receiverCheck: {
+			if (!(receiverType == this || receiverType == enclosingType())) {
+				// special tolerance for type variable direct bounds, but only if compliance <= 1.6, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622
+				if (receiverType.isTypeVariable()) {
+					TypeVariableBinding typeVariable = (TypeVariableBinding) receiverType;
+					if (typeVariable.environment.globalOptions.complianceLevel <= ClassFileConstants.JDK1_6 && (typeVariable.isErasureBoundTo(erasure()) || typeVariable.isErasureBoundTo(enclosingType().erasure())))
+						break receiverCheck;
+				}
+				return false;
+			}
+		}
+
+		if (invocationType != this) {
+			ReferenceBinding outerInvocationType = invocationType;
+			ReferenceBinding temp = outerInvocationType.enclosingType();
+			while (temp != null) {
+				outerInvocationType = temp;
+				temp = temp.enclosingType();
+			}
+
+			ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
+			temp = outerDeclaringClass.enclosingType();
+			while (temp != null) {
+				outerDeclaringClass = temp;
+				temp = temp.enclosingType();
+			}
+			if (outerInvocationType != outerDeclaringClass) return false;
+		}
+		return true;
+	}
+
+	// isDefault()
+	if (invocationType.fPackage != this.fPackage) return false;
+
+	ReferenceBinding currentType = receiverType;
+	TypeBinding originalDeclaringClass = (enclosingType() == null ? this : enclosingType()).original();
+	do {
+		if (currentType.isCapture()) {  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
+			if (originalDeclaringClass == currentType.erasure().original()) return true;
+		} else { 
+			if (originalDeclaringClass == currentType.original()) return true;
+		}
+		PackageBinding currentPackage = currentType.fPackage;
+		// package could be null for wildcards/intersection types, ignore and recurse in superclass
+		if (currentPackage != null && currentPackage != this.fPackage) return false;
+	} while ((currentType = currentType.superclass()) != null);
+	return false;
+}
+
+/**
+ * Answer true if the receiver is visible to the type provided by the scope.
+ */
+public final boolean canBeSeenBy(Scope scope) {
+	if (isPublic()) return true;
+
+	SourceTypeBinding invocationType = scope.enclosingSourceType();
+	if (invocationType == this) return true;
+
+	if (invocationType == null) // static import call
+		return !isPrivate() && scope.getCurrentPackage() == this.fPackage;
+
+	if (isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the invocationType is the invocationType or its subclass
+		//    OR the type is a static method accessed directly through a type
+		//    OR previous assertions are true for one of the enclosing type
+		if (invocationType.fPackage == this.fPackage) return true;
+
+		TypeBinding declaringClass = enclosingType(); // protected types always have an enclosing one
+		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
+		declaringClass = declaringClass.erasure();// erasure cannot be null
+		TypeBinding currentType = invocationType.erasure();
+		// int depth = 0;
+		do {
+			if (declaringClass == invocationType) return true;
+			if (currentType.findSuperTypeOriginatingFrom(declaringClass) != null) return true;
+			// depth++;
+			currentType = currentType.enclosingType();
+		} while (currentType != null);
+		return false;
+	}
+	if (isPrivate()) {
+		// answer true if the receiver and the invocationType have a common enclosingType
+		// already know they are not the identical type
+		ReferenceBinding outerInvocationType = invocationType;
+		ReferenceBinding temp = outerInvocationType.enclosingType();
+		while (temp != null) {
+			outerInvocationType = temp;
+			temp = temp.enclosingType();
+		}
+
+		ReferenceBinding outerDeclaringClass = (ReferenceBinding)erasure();
+		temp = outerDeclaringClass.enclosingType();
+		while (temp != null) {
+			outerDeclaringClass = temp;
+			temp = temp.enclosingType();
+		}
+		return outerInvocationType == outerDeclaringClass;
+	}
+
+	// isDefault()
+	return invocationType.fPackage == this.fPackage;
+}
+
+public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
+
+	boolean isMemberOfGeneric = isMemberType() && (enclosingType().modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0;
+	if (typeVariables == Binding.NO_TYPE_VARIABLES && !isMemberOfGeneric) {
+		return signature();
+	}
+	StringBuffer sig = new StringBuffer(10);
+	if (isMemberOfGeneric) {
+	    char[] typeSig = enclosingType().genericTypeSignature();
+	    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+	    sig.append('.'); // NOTE: cannot override trailing ';' with '.' in enclosing signature, since shared char[]
+	    sig.append(this.sourceName);
+	}	else {
+	    char[] typeSig = signature();
+	    sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+	}
+	if (typeVariables == Binding.NO_TYPE_VARIABLES) {
+	    sig.append(';');
+	} else {
+	    sig.append('<');
+	    for (int i = 0, length = typeVariables.length; i < length; i++) {
+	        sig.append(typeVariables[i].genericTypeSignature());
+	    }
+	    sig.append(">;"); //$NON-NLS-1$
+	}
+	int sigLength = sig.length();
+	char[] result = new char[sigLength];
+	sig.getChars(0, sigLength, result, 0);
+	return result;
+}
+
+public void computeId() {
+	// note that more (configurable) ids are assigned from PackageBinding#checkIfNullAnnotationType() 
+
+	// try to avoid multiple checks against a package/type name
+	switch (this.compoundName.length) {
+
+		case 3 :
+			char[] packageName = this.compoundName[0];
+			// expect only java.*.* and javax.*.* and junit.*.* and org.junit.*
+			switch (packageName.length) {
+				case 3: // only one type in this group, yet:
+					if (CharOperation.equals(TypeConstants.ORG_JUNIT_ASSERT, this.compoundName))
+						this.id = TypeIds.T_OrgJunitAssert;
+					return;						
+				case 4:
+					if (!CharOperation.equals(TypeConstants.JAVA, packageName))
+						return;
+					break; // continue below ...
+				case 5:
+					switch (packageName[1]) {
+						case 'a':
+							if (CharOperation.equals(TypeConstants.JAVAX_ANNOTATION_INJECT_INJECT, this.compoundName))
+								this.id = TypeIds.T_JavaxInjectInject;
+							return;
+						case 'u':
+							if (CharOperation.equals(TypeConstants.JUNIT_FRAMEWORK_ASSERT, this.compoundName))
+								this.id = TypeIds.T_JunitFrameworkAssert;
+							return;
+					}
+					return;
+				default: return;
+			}
+			// ... at this point we know it's java.*.*
+			
+			packageName = this.compoundName[1];
+			if (packageName.length == 0) return; // just to be safe
+			char[] typeName = this.compoundName[2];
+			if (typeName.length == 0) return; // just to be safe
+			// remaining types MUST be in java.*.*
+			if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1])) {
+				switch (packageName[0]) {
+					case 'i' :
+						if (CharOperation.equals(packageName, TypeConstants.IO)) {
+							switch (typeName[0]) {
+								case 'C' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_CLOSEABLE[2]))
+										this.typeBits |= TypeIds.BitCloseable; // don't assign id, only typeBit (for analysis of resource leaks) 
+									return;
+								case 'E' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_EXTERNALIZABLE[2]))
+										this.id = TypeIds.T_JavaIoExternalizable;
+									return;
+								case 'I' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_IOEXCEPTION[2]))
+										this.id = TypeIds.T_JavaIoException;
+									return;
+								case 'O' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_OBJECTSTREAMEXCEPTION[2]))
+										this.id = TypeIds.T_JavaIoObjectStreamException;
+									return;
+								case 'P' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_PRINTSTREAM[2]))
+										this.id = TypeIds.T_JavaIoPrintStream;
+									return;
+								case 'S' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_IO_SERIALIZABLE[2]))
+										this.id = TypeIds.T_JavaIoSerializable;
+									return;
+							}
+						}
+						return;
+					case 'u' :
+						if (CharOperation.equals(packageName, TypeConstants.UTIL)) {
+							switch (typeName[0]) {
+								case 'C' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_COLLECTION[2]))
+										this.id = TypeIds.T_JavaUtilCollection;
+									return;
+								case 'I' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_ITERATOR[2]))
+										this.id = TypeIds.T_JavaUtilIterator;
+									return;
+								case 'O' :
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_UTIL_OBJECTS[2]))
+										this.id = TypeIds.T_JavaUtilObjects;
+									return;
+							}
+						}
+						return;
+				}
+				return;
+			}
+
+			// remaining types MUST be in java.lang.*
+			switch (typeName[0]) {
+				case 'A' :
+					switch(typeName.length) {
+						case 13 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2])) {
+								this.id = TypeIds.T_JavaLangAutoCloseable;
+								this.typeBits |= TypeIds.BitAutoCloseable; 
+							}
+							return;
+						case 14:
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
+								this.id = TypeIds.T_JavaLangAssertionError;
+							return;
+					}
+					return;
+				case 'B' :
+					switch (typeName.length) {
+						case 4 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BYTE[2]))
+								this.id = TypeIds.T_JavaLangByte;
+							return;
+						case 7 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_BOOLEAN[2]))
+								this.id = TypeIds.T_JavaLangBoolean;
+							return;
+					}
+					return;
+				case 'C' :
+					switch (typeName.length) {
+						case 5 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASS[2]))
+								this.id = TypeIds.T_JavaLangClass;
+							return;
+						case 9 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CHARACTER[2]))
+								this.id = TypeIds.T_JavaLangCharacter;
+							else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLONEABLE[2]))
+							    this.id = TypeIds.T_JavaLangCloneable;
+							return;
+						case 22 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_CLASSNOTFOUNDEXCEPTION[2]))
+								this.id = TypeIds.T_JavaLangClassNotFoundException;
+							return;
+					}
+					return;
+				case 'D' :
+					switch (typeName.length) {
+						case 6 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DOUBLE[2]))
+								this.id = TypeIds.T_JavaLangDouble;
+							return;
+						case 10 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_DEPRECATED[2]))
+								this.id = TypeIds.T_JavaLangDeprecated;
+							return;
+					}
+					return;
+				case 'E' :
+					switch (typeName.length) {
+						case 4 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ENUM[2]))
+								this.id = TypeIds.T_JavaLangEnum;
+							return;
+						case 5 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ERROR[2]))
+								this.id = TypeIds.T_JavaLangError;
+							return;
+						case 9 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_EXCEPTION[2]))
+								this.id = TypeIds.T_JavaLangException;
+							return;
+					}
+					return;
+				case 'F' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FLOAT[2]))
+						this.id = TypeIds.T_JavaLangFloat;
+					else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_FUNCTIONAL_INTERFACE[2]))
+						this.id = TypeIds.T_JavaLangFunctionalInterface;
+					return;
+				case 'I' :
+					switch (typeName.length) {
+						case 7 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INTEGER[2]))
+								this.id = TypeIds.T_JavaLangInteger;
+							return;
+						case 8 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ITERABLE[2]))
+								this.id = TypeIds.T_JavaLangIterable;
+							return;
+						case 24 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ILLEGALARGUMENTEXCEPTION[2]))
+								this.id = TypeIds.T_JavaLangIllegalArgumentException;
+							return;
+					}
+					return;
+				case 'L' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_LONG[2]))
+						this.id = TypeIds.T_JavaLangLong;
+					return;
+				case 'N' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_NOCLASSDEFERROR[2]))
+						this.id = TypeIds.T_JavaLangNoClassDefError;
+					return;
+				case 'O' :
+					switch (typeName.length) {
+						case 6 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OBJECT[2]))
+								this.id = TypeIds.T_JavaLangObject;
+							return;
+						case 8 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_OVERRIDE[2]))
+								this.id = TypeIds.T_JavaLangOverride;
+							return;
+					}
+					return;
+				case 'R' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2]))
+						this.id = 	TypeIds.T_JavaLangRuntimeException;
+					break;
+				case 'S' :
+					switch (typeName.length) {
+						case 5 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SHORT[2]))
+								this.id = TypeIds.T_JavaLangShort;
+							return;
+						case 6 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRING[2]))
+								this.id = TypeIds.T_JavaLangString;
+							else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2]))
+								this.id = TypeIds.T_JavaLangSystem;
+							return;
+						case 11 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SAFEVARARGS[2]))
+								this.id = TypeIds.T_JavaLangSafeVarargs;
+							return;
+						case 12 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2]))
+								this.id = TypeIds.T_JavaLangStringBuffer;
+							return;
+						case 13 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUILDER[2]))
+								this.id = TypeIds.T_JavaLangStringBuilder;
+							return;
+						case 16 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS[2]))
+								this.id = TypeIds.T_JavaLangSuppressWarnings;
+							return;
+					}
+					return;
+				case 'T' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_THROWABLE[2]))
+						this.id = TypeIds.T_JavaLangThrowable;
+					return;
+				case 'V' :
+					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_VOID[2]))
+						this.id = TypeIds.T_JavaLangVoid;
+					return;
+			}
+		break;
+
+		case 4:
+			// expect one type from com.*.*.*:
+			if (CharOperation.equals(TypeConstants.COM_GOOGLE_INJECT_INJECT, this.compoundName)) {
+				this.id = TypeIds.T_ComGoogleInjectInject;
+				return;
+			}
+			// otherwise only expect java.*.*.*
+			if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
+				return;
+			packageName = this.compoundName[1];
+			if (packageName.length == 0) return; // just to be safe
+
+			packageName = this.compoundName[2];
+			if (packageName.length == 0) return; // just to be safe
+			typeName = this.compoundName[3];
+			if (typeName.length == 0) return; // just to be safe
+			switch (packageName[0]) {
+				case 'a' :
+					if (CharOperation.equals(packageName, TypeConstants.ANNOTATION)) {
+						switch (typeName[0]) {
+							case 'A' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION[3]))
+									this.id = TypeIds.T_JavaLangAnnotationAnnotation;
+								return;
+							case 'D' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED[3]))
+									this.id = TypeIds.T_JavaLangAnnotationDocumented;
+								return;
+							case 'E' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE[3]))
+									this.id = TypeIds.T_JavaLangAnnotationElementType;
+								return;
+							case 'I' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED[3]))
+									this.id = TypeIds.T_JavaLangAnnotationInherited;
+								return;
+							case 'R' :
+								switch (typeName.length) {
+									case 9 :
+										if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION[3]))
+											this.id = TypeIds.T_JavaLangAnnotationRetention;
+										return;
+									case 15 :
+										if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY[3]))
+											this.id = TypeIds.T_JavaLangAnnotationRetentionPolicy;
+										return;
+								}
+								return;
+							case 'T' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET[3]))
+									this.id = TypeIds.T_JavaLangAnnotationTarget;
+								return;
+						}
+					}
+					return;
+				case 'i':
+					if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
+						if (typeName.length == 0) return; // just to be safe
+						switch (typeName[0]) {
+							case 'M' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE[3]))
+									this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
+								return;
+						}
+					}
+					return;
+				case 'r' :
+					if (CharOperation.equals(packageName, TypeConstants.REFLECT)) {
+						switch (typeName[0]) {
+							case 'C' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_CONSTRUCTOR[2]))
+									this.id = TypeIds.T_JavaLangReflectConstructor;
+								return;
+							case 'F' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_FIELD[2]))
+									this.id = TypeIds.T_JavaLangReflectField;
+								return;
+							case 'M' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_REFLECT_METHOD[2]))
+									this.id = TypeIds.T_JavaLangReflectMethod;
+								return;
+						}
+					}
+					return;
+			}
+			break;
+		case 5 :
+			packageName = this.compoundName[0];
+			switch (packageName[0]) {
+				case 'j' :
+					if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
+						return;
+					packageName = this.compoundName[1];
+					if (packageName.length == 0) return; // just to be safe
+					
+					if (CharOperation.equals(TypeConstants.LANG, packageName)) {
+						packageName = this.compoundName[2];
+						if (packageName.length == 0) return; // just to be safe
+						switch (packageName[0]) {
+							case 'i' :
+								if (CharOperation.equals(packageName, TypeConstants.INVOKE)) { 
+									typeName = this.compoundName[3];
+									if (typeName.length == 0) return; // just to be safe
+									switch (typeName[0]) {
+										case 'M' :
+											char[] memberTypeName = this.compoundName[4];
+											if (memberTypeName.length == 0) return; // just to be safe
+											if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[3])
+													&& CharOperation.equals(memberTypeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[4]))
+												this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
+											return;
+									}
+								}
+								return;
+						}
+						return;
+					}
+					return;
+				case 'o':
+					if (!CharOperation.equals(TypeConstants.ORG, this.compoundName[0]))
+						return;
+					packageName = this.compoundName[1];
+					if (packageName.length == 0) return; // just to be safe
+
+					switch (packageName[0]) {
+						case 'e':
+							if (CharOperation.equals(TypeConstants.ECLIPSE, packageName)) {
+								packageName = this.compoundName[2];
+								if (packageName.length == 0) return; // just to be safe
+								switch (packageName[0]) {
+									case 'c' :
+										if (CharOperation.equals(packageName, TypeConstants.CORE)) { 
+											typeName = this.compoundName[3];
+											if (typeName.length == 0) return; // just to be safe
+											switch (typeName[0]) {
+												case 'r' :
+													char[] memberTypeName = this.compoundName[4];
+													if (memberTypeName.length == 0) return; // just to be safe
+													if (CharOperation.equals(typeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[3])
+															&& CharOperation.equals(memberTypeName, TypeConstants.ORG_ECLIPSE_CORE_RUNTIME_ASSERT[4]))
+														this.id = TypeIds.T_OrgEclipseCoreRuntimeAssert;
+													return;
+											}
+										}
+										return;
+								}
+								return;
+							}
+							return;
+						case 'a':
+							if (CharOperation.equals(TypeConstants.APACHE, packageName)) {
+								if (CharOperation.equals(TypeConstants.COMMONS, this.compoundName[2])) {
+									if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG_VALIDATE, this.compoundName))
+										this.id = TypeIds.T_OrgApacheCommonsLangValidate;
+									else if (CharOperation.equals(TypeConstants.ORG_APACHE_COMMONS_LANG3_VALIDATE, this.compoundName))
+										this.id = TypeIds.T_OrgApacheCommonsLang3Validate;
+								}
+							}
+							return;
+					}
+					return;
+				case 'c':
+					if (!CharOperation.equals(TypeConstants.COM, this.compoundName[0]))
+						return;
+					if (CharOperation.equals(TypeConstants.COM_GOOGLE_COMMON_BASE_PRECONDITIONS, this.compoundName))
+						this.id = TypeIds.T_ComGoogleCommonBasePreconditions;
+					return;
+			}
+			break;
+	}
+}
+
+/**
+ * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;
+ */
+public char[] computeUniqueKey(boolean isLeaf) {
+	if (!isLeaf) return signature();
+	return genericTypeSignature();
+}
+
+/**
+ * Answer the receiver's constant pool name.
+ *
+ * NOTE: This method should only be used during/after code gen.
+ */
+public char[] constantPoolName() /* java/lang/Object */ {
+	if (this.constantPoolName != null) return this.constantPoolName;
+	return this.constantPoolName = CharOperation.concatWith(this.compoundName, '/');
+}
+
+public String debugName() {
+	return (this.compoundName != null) ? new String(readableName()) : "UNNAMED TYPE"; //$NON-NLS-1$
+}
+
+public final int depth() {
+	int depth = 0;
+	ReferenceBinding current = this;
+	while ((current = current.enclosingType()) != null)
+		depth++;
+	return depth;
+}
+
+public boolean detectAnnotationCycle() {
+	if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false; // already checked
+	if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true; // in the middle of checking its methods
+
+	this.tagBits |= TagBits.BeginAnnotationCheck;
+	MethodBinding[] currentMethods = methods();
+	boolean inCycle = false; // check each method before failing
+	for (int i = 0, l = currentMethods.length; i < l; i++) {
+		TypeBinding returnType = currentMethods[i].returnType.leafComponentType().erasure();
+		if (this == returnType) {
+			if (this instanceof SourceTypeBinding) {
+				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
+				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, this, decl != null ? decl.returnType : null);
+			}
+		} else if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) {
+			if (this instanceof SourceTypeBinding) {
+				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
+				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null);
+			}
+			inCycle = true;
+		}
+	}
+	if (inCycle)
+		return true;
+	this.tagBits |= TagBits.EndAnnotationCheck;
+	return false;
+}
+
+public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
+	ReferenceBinding current = this;
+	while (relativeDepth-- > 0 && current != null)
+		current = current.enclosingType();
+	return current;
+}
+
+public int enumConstantCount() {
+	int count = 0;
+	FieldBinding[] fields = fields();
+	for (int i = 0, length = fields.length; i < length; i++) {
+		if ((fields[i].modifiers & ClassFileConstants.AccEnum) != 0) count++;
+	}
+	return count;
+}
+
+public int fieldCount() {
+	return fields().length;
+}
+
+public FieldBinding[] fields() {
+	return Binding.NO_FIELDS;
+}
+
+public final int getAccessFlags() {
+	return this.modifiers & ExtraCompilerModifiers.AccJustFlag;
+}
+
+/**
+ * @return the JSR 175 annotations for this type.
+ */
+public AnnotationBinding[] getAnnotations() {
+	return retrieveAnnotations(this);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
+ */
+public long getAnnotationTagBits() {
+	return this.tagBits;
+}
+
+/**
+ * @return the enclosingInstancesSlotSize
+ */
+public int getEnclosingInstancesSlotSize() {
+	if (isStatic()) return 0;
+	return enclosingType() == null ? 0 : 1;
+}
+
+public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
+	return null;
+}
+
+public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
+	return null;
+}
+public FieldBinding getField(char[] fieldName, boolean needResolve) {
+	return null;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.fileName;
+}
+
+public ReferenceBinding getMemberType(char[] typeName) {
+	ReferenceBinding[] memberTypes = memberTypes();
+	for (int i = memberTypes.length; --i >= 0;)
+		if (CharOperation.equals(memberTypes[i].sourceName, typeName))
+			return memberTypes[i];
+	return null;
+}
+
+public MethodBinding[] getMethods(char[] selector) {
+	return Binding.NO_METHODS;
+}
+
+// Answer methods named selector, which take no more than the suggestedParameterLength.
+// The suggested parameter length is optional and may not be guaranteed by every type.
+public MethodBinding[] getMethods(char[] selector, int suggestedParameterLength) {
+	return getMethods(selector);
+}
+
+/**
+ * @return the outerLocalVariablesSlotSize
+ */
+public int getOuterLocalVariablesSlotSize() {
+	return 0;
+}
+
+public PackageBinding getPackage() {
+	return this.fPackage;
+}
+
+public TypeVariableBinding getTypeVariable(char[] variableName) {
+	TypeVariableBinding[] typeVariables = typeVariables();
+	for (int i = typeVariables.length; --i >= 0;)
+		if (CharOperation.equals(typeVariables[i].sourceName, variableName))
+			return typeVariables[i];
+	return null;
+}
+
+public int hashCode() {
+	// ensure ReferenceBindings hash to the same position as UnresolvedReferenceBindings so they can be replaced without rehashing
+	// ALL ReferenceBindings are unique when created so equals() is the same as ==
+	return (this.compoundName == null || this.compoundName.length == 0)
+		? super.hashCode()
+		: CharOperation.hashCode(this.compoundName[this.compoundName.length - 1]);
+}
+
+/**
+ * Returns true if the two types have an incompatible common supertype,
+ * e.g. List<String> and List<Integer>
+ */
+public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {
+
+    if (this == otherType) return false;
+
+	ReferenceBinding[] interfacesToVisit = null;
+	int nextPosition = 0;
+    ReferenceBinding currentType = this;
+	TypeBinding match;
+	do {
+		match = otherType.findSuperTypeOriginatingFrom(currentType);
+		if (match != null && match.isProvablyDistinct(currentType))
+			return true;
+
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			if (interfacesToVisit == null) {
+				interfacesToVisit = itsInterfaces;
+				nextPosition = interfacesToVisit.length;
+			} else {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+	} while ((currentType = currentType.superclass()) != null);
+
+	for (int i = 0; i < nextPosition; i++) {
+		currentType = interfacesToVisit[i];
+		if (currentType == otherType) return false;
+		match = otherType.findSuperTypeOriginatingFrom(currentType);
+		if (match != null && match.isProvablyDistinct(currentType))
+			return true;
+
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			int itsLength = itsInterfaces.length;
+			if (nextPosition + itsLength >= interfacesToVisit.length)
+				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+			nextInterface : for (int a = 0; a < itsLength; a++) {
+				ReferenceBinding next = itsInterfaces[a];
+				for (int b = 0; b < nextPosition; b++)
+					if (next == interfacesToVisit[b]) continue nextInterface;
+				interfacesToVisit[nextPosition++] = next;
+			}
+		}
+	}
+	return false;
+}
+
+public boolean hasMemberTypes() {
+    return false;
+}
+
+/**
+ * Answer whether a @NonNullByDefault is applicable at the given method binding.
+ */
+boolean hasNonNullDefault() {
+	// Note, STB overrides for correctly handling local types
+	ReferenceBinding currentType = this;
+	while (currentType != null) {
+		if ((currentType.tagBits & TagBits.AnnotationNonNullByDefault) != 0)
+			return true;
+		if ((currentType.tagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+			return false;
+		currentType = currentType.enclosingType();
+	}
+	// package
+	return this.getPackage().defaultNullness == NONNULL_BY_DEFAULT;
+}
+
+public final boolean hasRestrictedAccess() {
+	return (this.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0;
+}
+/** Answer an additional bit characterizing this type, like {@link TypeIds#BitAutoCloseable}. */
+abstract public boolean hasTypeBit(int bit);
+
+/** Answer true if the receiver implements anInterface or is identical to anInterface.
+* If searchHierarchy is true, then also search the receiver's superclasses.
+*
+* NOTE: Assume that anInterface is an interface.
+*/
+public boolean implementsInterface(ReferenceBinding anInterface, boolean searchHierarchy) {
+	if (this == anInterface)
+		return true;
+
+	ReferenceBinding[] interfacesToVisit = null;
+	int nextPosition = 0;
+	ReferenceBinding currentType = this;
+	do {
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
+			if (interfacesToVisit == null) {
+				interfacesToVisit = itsInterfaces;
+				nextPosition = interfacesToVisit.length;
+			} else {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+	} while (searchHierarchy && (currentType = currentType.superclass()) != null);
+
+	for (int i = 0; i < nextPosition; i++) {
+		currentType = interfacesToVisit[i];
+		if (currentType.isEquivalentTo(anInterface))
+			return true;
+
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { // in code assist cases when source types are added late, may not be finished connecting hierarchy
+			int itsLength = itsInterfaces.length;
+			if (nextPosition + itsLength >= interfacesToVisit.length)
+				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+			nextInterface : for (int a = 0; a < itsLength; a++) {
+				ReferenceBinding next = itsInterfaces[a];
+				for (int b = 0; b < nextPosition; b++)
+					if (next == interfacesToVisit[b]) continue nextInterface;
+				interfacesToVisit[nextPosition++] = next;
+			}
+		}
+	}
+	return false;
+}
+
+// Internal method... assume its only sent to classes NOT interfaces
+boolean implementsMethod(MethodBinding method) {
+	char[] selector = method.selector;
+	ReferenceBinding type = this;
+	while (type != null) {
+		MethodBinding[] methods = type.methods();
+		long range;
+		if ((range = ReferenceBinding.binarySearch(selector, methods)) >= 0) {
+			int start = (int) range, end = (int) (range >> 32);
+			for (int i = start; i <= end; i++) {
+				if (methods[i].areParametersEqual(method))
+					return true;
+			}
+		}
+		type = type.superclass();
+	}
+	return false;
+}
+
+/**
+ * Answer true if the receiver is an abstract type
+*/
+public final boolean isAbstract() {
+	return (this.modifiers & ClassFileConstants.AccAbstract) != 0;
+}
+
+public boolean isAnnotationType() {
+	return (this.modifiers & ClassFileConstants.AccAnnotation) != 0;
+}
+
+public final boolean isBinaryBinding() {
+	return (this.tagBits & TagBits.IsBinaryBinding) != 0;
+}
+
+public boolean isClass() {
+	return (this.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) == 0;
+}
+
+/**
+ * Answer true if the receiver type can be assigned to the argument type (right)
+ * In addition to improving performance, caching also ensures there is no infinite regression
+ * since per nature, the compatibility check is recursive through parameterized type arguments (122775)
+ */
+public boolean isCompatibleWith(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
+	if (otherType == this)
+		return true;
+	if (otherType.id == TypeIds.T_JavaLangObject)
+		return true;
+	Object result;
+	if (this.compatibleCache == null) {
+		this.compatibleCache = new SimpleLookupTable(3);
+		result = null;
+	} else {
+		result = this.compatibleCache.get(otherType); // [dbg reset] this.compatibleCache.put(otherType,null)
+		if (result != null) {
+			return result == Boolean.TRUE;
+		}
+	}
+	this.compatibleCache.put(otherType, Boolean.FALSE); // protect from recursive call
+	if (isCompatibleWith0(otherType, captureScope)) {
+		this.compatibleCache.put(otherType, Boolean.TRUE);
+		return true;
+	}
+	if (captureScope == null 
+			&& this instanceof TypeVariableBinding 
+			&& ((TypeVariableBinding)this).firstBound instanceof ParameterizedTypeBinding) {
+		// see https://bugs.eclipse.org/395002#c9
+		// in this case a subsequent check with captureScope != null may actually get
+		// a better result, reset this info to ensure we're not blocking that re-check.
+		this.compatibleCache.put(otherType, null);
+	}
+	return false;
+}
+
+/**
+ * Answer true if the receiver type can be assigned to the argument type (right)
+ */
+private boolean isCompatibleWith0(TypeBinding otherType, /*@Nullable*/ Scope captureScope) {
+	if (otherType == this)
+		return true;
+	if (otherType.id == TypeIds.T_JavaLangObject)
+		return true;
+	// equivalence may allow compatibility with array type through wildcard
+	// bound
+	if (isEquivalentTo(otherType))
+		return true;
+	switch (otherType.kind()) {
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE:
+			return false; // should have passed equivalence check above if
+							// wildcard
+		case Binding.TYPE_PARAMETER :
+			// check compatibility with capture of ? super X
+			if (otherType.isCapture()) {
+				CaptureBinding otherCapture = (CaptureBinding) otherType;
+				TypeBinding otherLowerBound;
+				if ((otherLowerBound = otherCapture.lowerBound) != null) {
+					if (otherLowerBound.isArrayType()) return false;
+					return isCompatibleWith(otherLowerBound);
+				}
+			}
+			//$FALL-THROUGH$
+		case Binding.GENERIC_TYPE :
+		case Binding.TYPE :
+		case Binding.PARAMETERIZED_TYPE :
+		case Binding.RAW_TYPE :
+			switch (kind()) {
+				case Binding.GENERIC_TYPE :
+				case Binding.PARAMETERIZED_TYPE :
+				case Binding.RAW_TYPE :
+					if (erasure() == otherType.erasure())
+						return false; // should have passed equivalence check
+										// above if same erasure
+			}
+			ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
+			if (otherReferenceType.isInterface()) { // could be annotation type
+				if (implementsInterface(otherReferenceType, true))
+					return true;
+				if (this instanceof TypeVariableBinding && captureScope != null) {
+					TypeVariableBinding typeVariable = (TypeVariableBinding) this;
+					if (typeVariable.firstBound instanceof ParameterizedTypeBinding) {
+						TypeBinding bound = typeVariable.firstBound.capture(captureScope, -1); // no position needed as this capture will never escape this context
+						return bound.isCompatibleWith(otherReferenceType);
+					}
+				}
+			}
+			if (isInterface())  // Explicit conversion from an interface
+										// to a class is not allowed
+				return false;
+			return otherReferenceType.isSuperclassOf(this);
+		default :
+			return false;
+	}
+}
+
+/**
+ * Answer true if the receiver has default visibility
+ */
+public final boolean isDefault() {
+	return (this.modifiers & (ClassFileConstants.AccPublic | ClassFileConstants.AccProtected | ClassFileConstants.AccPrivate)) == 0;
+}
+
+/**
+ * Answer true if the receiver is a deprecated type
+ */
+public final boolean isDeprecated() {
+	return (this.modifiers & ClassFileConstants.AccDeprecated) != 0;
+}
+
+public boolean isEnum() {
+	return (this.modifiers & ClassFileConstants.AccEnum) != 0;
+}
+
+/**
+ * Answer true if the receiver is final and cannot be subclassed
+ */
+public final boolean isFinal() {
+	return (this.modifiers & ClassFileConstants.AccFinal) != 0;
+}
+
+/**
+ * Returns true if the type hierarchy is being connected
+ */
+public boolean isHierarchyBeingConnected() {
+	return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0;
+}
+/**
+ * Returns true if the type hierarchy is being connected "actively" i.e not paused momentatrily, 
+ * while resolving type arguments. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057
+ */
+public boolean isHierarchyBeingActivelyConnected() {
+	return (this.tagBits & TagBits.EndHierarchyCheck) == 0 && (this.tagBits & TagBits.BeginHierarchyCheck) != 0 && (this.tagBits & TagBits.PauseHierarchyCheck) == 0;
+}
+
+/**
+ * Returns true if the type hierarchy is connected
+ */
+public boolean isHierarchyConnected() {
+	return true;
+}
+
+public boolean isInterface() {
+	// consider strict interfaces and annotation types
+	return (this.modifiers & ClassFileConstants.AccInterface) != 0;
+}
+
+public boolean isFunctionalInterface(Scope scope) {
+	MethodBinding method;
+	return isInterface() && (method = getSingleAbstractMethod(scope)) != null && method.isValidBinding();
+}
+
+/**
+ * Answer true if the receiver has private visibility
+ */
+public final boolean isPrivate() {
+	return (this.modifiers & ClassFileConstants.AccPrivate) != 0;
+}
+
+/**
+ * Answer true if the receiver or any of its enclosing types have private visibility
+ */
+public final boolean isOrEnclosedByPrivateType() {
+	if (isLocalType()) return true; // catch all local types
+	ReferenceBinding type = this;
+	while (type != null) {
+		if ((type.modifiers & ClassFileConstants.AccPrivate) != 0)
+			return true;
+		type = type.enclosingType();
+	}
+	return false;
+}
+
+/**
+ * Answer true if the receiver has protected visibility
+ */
+public final boolean isProtected() {
+	return (this.modifiers & ClassFileConstants.AccProtected) != 0;
+}
+
+/**
+ * Answer true if the receiver has public visibility
+ */
+public final boolean isPublic() {
+	return (this.modifiers & ClassFileConstants.AccPublic) != 0;
+}
+
+/**
+ * Answer true if the receiver is a static member type (or toplevel)
+ */
+public final boolean isStatic() {
+	return (this.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface)) != 0 || (this.tagBits & TagBits.IsNestedType) == 0;
+}
+
+/**
+ * Answer true if all float operations must adher to IEEE 754 float/double rules
+ */
+public final boolean isStrictfp() {
+	return (this.modifiers & ClassFileConstants.AccStrictfp) != 0;
+}
+
+/**
+ * Answer true if the receiver is in the superclass hierarchy of aType
+ * NOTE: Object.isSuperclassOf(Object) -> false
+ */
+public boolean isSuperclassOf(ReferenceBinding otherType) {
+	while ((otherType = otherType.superclass()) != null) {
+		if (otherType.isEquivalentTo(this)) return true;
+	}
+	return false;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isThrowable()
+ */
+public boolean isThrowable() {
+	ReferenceBinding current = this;
+	do {
+		switch (current.id) {
+			case TypeIds.T_JavaLangThrowable :
+			case TypeIds.T_JavaLangError :
+			case TypeIds.T_JavaLangRuntimeException :
+			case TypeIds.T_JavaLangException :
+				return true;
+		}
+	} while ((current = current.superclass()) != null);
+	return false;
+}
+
+/**
+ * JLS 11.5 ensures that Throwable, Exception, RuntimeException and Error are directly connected.
+ * (Throwable<- Exception <- RumtimeException, Throwable <- Error). Thus no need to check #isCompatibleWith
+ * but rather check in type IDs so as to avoid some eager class loading for JCL writers.
+ * When 'includeSupertype' is true, answers true if the given type can be a supertype of some unchecked exception
+ * type (i.e. Throwable or Exception).
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
+ */
+public boolean isUncheckedException(boolean includeSupertype) {
+	switch (this.id) {
+			case TypeIds.T_JavaLangError :
+			case TypeIds.T_JavaLangRuntimeException :
+				return true;
+			case TypeIds.T_JavaLangThrowable :
+			case TypeIds.T_JavaLangException :
+				return includeSupertype;
+	}
+	ReferenceBinding current = this;
+	while ((current = current.superclass()) != null) {
+		switch (current.id) {
+			case TypeIds.T_JavaLangError :
+			case TypeIds.T_JavaLangRuntimeException :
+				return true;
+			case TypeIds.T_JavaLangThrowable :
+			case TypeIds.T_JavaLangException :
+				return false;
+		}
+	}
+	return false;
+}
+
+/**
+ * Answer true if the receiver has private visibility and is used locally
+ */
+public final boolean isUsed() {
+	return (this.modifiers & ExtraCompilerModifiers.AccLocallyUsed) != 0;
+}
+
+/**
+ * Answer true if the receiver is deprecated (or any of its enclosing types)
+ */
+public final boolean isViewedAsDeprecated() {
+	return (this.modifiers & (ClassFileConstants.AccDeprecated | ExtraCompilerModifiers.AccDeprecatedImplicitly)) != 0
+			|| getPackage().isViewedAsDeprecated();
+}
+
+public ReferenceBinding[] memberTypes() {
+	return Binding.NO_MEMBER_TYPES;
+}
+
+public MethodBinding[] methods() {
+	return Binding.NO_METHODS;
+}
+
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* java.lang.Object @o.e.j.a.NonNull[] */ {
+	char[] typeName = shortNames ? shortReadableName() : readableName();
+	if ((this.tagBits & TagBits.AnnotationNullMASK) == 0)
+		return typeName;
+	char[][] fqAnnotationName;
+	if ((this.tagBits & TagBits.AnnotationNonNull) != 0)
+		fqAnnotationName = env.getNonNullAnnotationName();
+	else
+		fqAnnotationName = env.getNullableAnnotationName();
+	char[] annotationName = shortNames
+								? fqAnnotationName[fqAnnotationName.length-1]
+								: CharOperation.concatWith(fqAnnotationName, '.');				
+	char[] prefix = new char[annotationName.length+1];
+	prefix[0] = '@';
+	System.arraycopy(annotationName, 0, prefix, 1, annotationName.length);
+	return CharOperation.concat(prefix, typeName, ' ');
+}
+
+public final ReferenceBinding outermostEnclosingType() {
+	ReferenceBinding current = this;
+	while (true) {
+		ReferenceBinding last = current;
+		if ((current = current.enclosingType()) == null)
+			return last;
+	}
+}
+
+/**
+ * Answer the source name for the type.
+ * In the case of member types, as the qualified name from its top level type.
+ * For example, for a member type N defined inside M & A: "A.M.N".
+ */
+public char[] qualifiedSourceName() {
+	if (isMemberType())
+		return CharOperation.concat(enclosingType().qualifiedSourceName(), sourceName(), '.');
+	return sourceName();
+}
+
+/**
+ * Answer the receiver's signature.
+ *
+ * NOTE: This method should only be used during/after code gen.
+ */
+public char[] readableName() /*java.lang.Object,  p.X<T> */ {
+    char[] readableName;
+	if (isMemberType()) {
+		readableName = CharOperation.concat(enclosingType().readableName(), this.sourceName, '.');
+	} else {
+		readableName = CharOperation.concatWith(this.compoundName, '.');
+	}
+	TypeVariableBinding[] typeVars;
+	if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+	    nameBuffer.append(readableName).append('<');
+	    for (int i = 0, length = typeVars.length; i < length; i++) {
+	        if (i > 0) nameBuffer.append(',');
+	        nameBuffer.append(typeVars[i].readableName());
+	    }
+	    nameBuffer.append('>');
+		int nameLength = nameBuffer.length();
+		readableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, readableName, 0);
+	}
+	return readableName;
+}
+
+public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
+	SimpleLookupTable store = storedAnnotations(forceInitialization);
+	return store == null ? null : (AnnotationHolder) store.get(binding);
+}
+
+AnnotationBinding[] retrieveAnnotations(Binding binding) {
+	AnnotationHolder holder = retrieveAnnotationHolder(binding, true);
+	return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations();
+}
+
+public void setAnnotations(AnnotationBinding[] annotations) {
+	storeAnnotations(this, annotations);
+}
+
+public char[] shortReadableName() /*Object*/ {
+	char[] shortReadableName;
+	if (isMemberType()) {
+		shortReadableName = CharOperation.concat(enclosingType().shortReadableName(), this.sourceName, '.');
+	} else {
+		shortReadableName = this.sourceName;
+	}
+	TypeVariableBinding[] typeVars;
+	if ((typeVars = typeVariables()) != Binding.NO_TYPE_VARIABLES) {
+	    StringBuffer nameBuffer = new StringBuffer(10);
+	    nameBuffer.append(shortReadableName).append('<');
+	    for (int i = 0, length = typeVars.length; i < length; i++) {
+	        if (i > 0) nameBuffer.append(',');
+	        nameBuffer.append(typeVars[i].shortReadableName());
+	    }
+	    nameBuffer.append('>');
+		int nameLength = nameBuffer.length();
+		shortReadableName = new char[nameLength];
+		nameBuffer.getChars(0, nameLength, shortReadableName, 0);
+	}
+	return shortReadableName;
+}
+
+public char[] signature() /* Ljava/lang/Object; */ {
+	if (this.signature != null)
+		return this.signature;
+
+	return this.signature = CharOperation.concat('L', constantPoolName(), ';');
+}
+
+public char[] sourceName() {
+	return this.sourceName;
+}
+
+void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
+	if (holder == null) {
+		SimpleLookupTable store = storedAnnotations(false);
+		if (store != null)
+			store.removeKey(binding);
+	} else {
+		SimpleLookupTable store = storedAnnotations(true);
+		if (store != null)
+			store.put(binding, holder);
+	}
+}
+
+void storeAnnotations(Binding binding, AnnotationBinding[] annotations) {
+	AnnotationHolder holder = null;
+	if (annotations == null || annotations.length == 0) {
+		SimpleLookupTable store = storedAnnotations(false);
+		if (store != null)
+			holder = (AnnotationHolder) store.get(binding);
+		if (holder == null) return; // nothing to delete
+	} else {
+		SimpleLookupTable store = storedAnnotations(true);
+		if (store == null) return; // not supported
+		holder = (AnnotationHolder) store.get(binding);
+		if (holder == null)
+			holder = new AnnotationHolder();
+	}
+	storeAnnotationHolder(binding, holder.setAnnotations(annotations));
+}
+
+SimpleLookupTable storedAnnotations(boolean forceInitialize) {
+	return null; // overrride if interested in storing annotations for the receiver, its fields and methods
+}
+
+public ReferenceBinding superclass() {
+	return null;
+}
+
+public ReferenceBinding[] superInterfaces() {
+	return Binding.NO_SUPERINTERFACES;
+}
+
+public ReferenceBinding[] syntheticEnclosingInstanceTypes() {
+	if (isStatic()) return null;
+	ReferenceBinding enclosingType = enclosingType();
+	if (enclosingType == null)
+		return null;
+	return new ReferenceBinding[] {enclosingType};
+}
+public SyntheticArgumentBinding[] syntheticOuterLocalVariables() {
+	return null;		// is null if no enclosing instances are required
+}
+
+MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
+	return methods();
+}
+
+public FieldBinding[] unResolvedFields() {
+	return Binding.NO_FIELDS;
+}
+
+/*
+ * If a type - known to be a Closeable - is mentioned in one of our white lists
+ * answer the typeBit for the white list (BitWrapperCloseable or BitResourceFreeCloseable).
+ */
+protected int applyCloseableWhitelists() {
+	switch (this.compoundName.length) {
+		case 3:
+			if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
+				if (CharOperation.equals(TypeConstants.IO, this.compoundName[1])) {
+					char[] simpleName = this.compoundName[2];
+					int l = TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES.length;
+					for (int i = 0; i < l; i++) {
+						if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_WRAPPER_CLOSEABLES[i]))
+							return TypeIds.BitWrapperCloseable;
+					}
+					l = TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES.length;
+					for (int i = 0; i < l; i++) {
+						if (CharOperation.equals(simpleName, TypeConstants.JAVA_IO_RESOURCE_FREE_CLOSEABLES[i]))
+							return TypeIds.BitResourceFreeCloseable;
+					}
+				}
+			}
+			break;
+		case 4:
+			if (CharOperation.equals(TypeConstants.JAVA, this.compoundName[0])) {
+				if (CharOperation.equals(TypeConstants.UTIL, this.compoundName[1])) {
+					if (CharOperation.equals(TypeConstants.ZIP, this.compoundName[2])) {
+						char[] simpleName = this.compoundName[3];
+						int l = TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES.length;
+						for (int i = 0; i < l; i++) {
+							if (CharOperation.equals(simpleName, TypeConstants.JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES[i]))
+								return TypeIds.BitWrapperCloseable;
+						}
+					}
+				}
+			}
+			break;
+	}
+	int l = TypeConstants.OTHER_WRAPPER_CLOSEABLES.length;
+	for (int i = 0; i < l; i++) {
+		if (CharOperation.equals(this.compoundName, TypeConstants.OTHER_WRAPPER_CLOSEABLES[i]))
+			return TypeIds.BitWrapperCloseable;
+	}	
+	return 0;
+}
+
+
+private MethodBinding [] getInterfaceAbstractContracts(Scope scope) throws InvalidInputException {
+	
+	if (!isInterface() || !isValidBinding()) {
+		throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
+	}
+	
+	MethodBinding [] methods = methods();
+	MethodBinding [] contracts = new MethodBinding[0];
+	int contractsCount = 0;
+	int contractsLength = 0;
+	MethodBinding aContract = null;
+	int contractParameterLength = 0;
+	char [] contractSelector = null;
+	
+	for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++) {
+		final MethodBinding method = methods[i];
+		if (!method.isAbstract() || method.redeclaresPublicObjectMethod(scope)) continue; // skips statics, defaults, public object methods ...
+		final boolean validBinding = method.isValidBinding();
+		if (aContract == null && validBinding) {
+			aContract = method;
+			contractParameterLength = aContract.parameters.length;
+			contractSelector = aContract.selector;
+		} else {
+			if (!validBinding || method.parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, method.selector)) {
+				throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
+			}
+		}
+		if (contractsCount == contractsLength) {
+			System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength += 16], 0, contractsCount);
+		}
+		contracts[contractsCount++] = method;
+	}
+	ReferenceBinding [] superInterfaces = superInterfaces();
+	for (int i = 0, length = superInterfaces.length; i < length; i++) {
+		MethodBinding [] superInterfaceContracts = superInterfaces[i].getInterfaceAbstractContracts(scope);
+		final int superInterfaceContractsLength = superInterfaceContracts == null  ? 0 : superInterfaceContracts.length;
+		
+		if (superInterfaceContractsLength == 0) continue;
+		if (aContract == null) {
+			aContract = superInterfaceContracts[0];
+			contractParameterLength = aContract.parameters.length;
+			contractSelector = aContract.selector;
+			contracts = superInterfaceContracts;
+			contractsCount = contractsLength = superInterfaceContractsLength;
+		} else {
+			if (superInterfaceContracts[0].parameters.length != contractParameterLength || !CharOperation.equals(contractSelector, superInterfaceContracts[0].selector)) {
+				throw new InvalidInputException("Not a functional interface"); //$NON-NLS-1$
+			}
+			if (contractsLength < contractsCount + superInterfaceContractsLength) {
+				System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsLength = contractsCount + superInterfaceContractsLength], 0, contractsCount);
+			}
+			System.arraycopy(superInterfaceContracts, 0, contracts, contractsCount,	superInterfaceContractsLength);
+			contractsCount += superInterfaceContractsLength;
+		}
+	}
+	if (contractsCount < contractsLength) {
+		System.arraycopy(contracts, 0, contracts = new MethodBinding[contractsCount], 0, contractsCount);
+	}
+	return contracts;
+}
+public MethodBinding getSingleAbstractMethod(Scope scope) {
+	
+	if (this.singleAbstractMethod != null) {
+		return this.singleAbstractMethod;
+	}
+
+	MethodBinding[] methods = null;
+	try {
+		methods = getInterfaceAbstractContracts(scope);
+	} catch (InvalidInputException e) {
+		return this.singleAbstractMethod = samProblemBinding;
+	}
+	if (methods != null && methods.length == 1)
+		return this.singleAbstractMethod = methods[0];
+	
+	final LookupEnvironment environment = scope.environment();
+	boolean genericMethodSeen = false;
+	next:for (int i = 0, length = methods.length; i < length; i++) {
+		MethodBinding method = methods[i], otherMethod = null;
+		if (method.typeVariables != Binding.NO_TYPE_VARIABLES)
+			genericMethodSeen = true;
+		for (int j = 0; j < length; j++) {
+			if (i == j) continue;
+			otherMethod = methods[j];
+			if (otherMethod.typeVariables != Binding.NO_TYPE_VARIABLES)
+				genericMethodSeen = true;
+			
+			if (genericMethodSeen) { // adapt type parameters.
+				otherMethod = MethodVerifier.computeSubstituteMethod(otherMethod, method, environment);
+				if (otherMethod == null)
+					continue next;
+			}
+			if (!MethodVerifier.isSubstituteParameterSubsignature(method, otherMethod, environment) || !MethodVerifier.areReturnTypesCompatible(method, otherMethod, environment)) 
+				continue next; 
+		}
+		// If we reach here, we found a method that is override equivalent with every other method and is also return type substitutable. Compute kosher exceptions now ...
+		ReferenceBinding [] exceptions = new ReferenceBinding[0];
+		int exceptionsCount = 0, exceptionsLength = 0;
+		final MethodBinding theAbstractMethod = method;
+		boolean shouldEraseThrows = theAbstractMethod.typeVariables == Binding.NO_TYPE_VARIABLES && genericMethodSeen;
+		boolean shouldAdaptThrows = theAbstractMethod.typeVariables != Binding.NO_TYPE_VARIABLES;
+		final int typeVariableLength = theAbstractMethod.typeVariables.length;
+		
+		none:for (i = 0; i < length; i++) {
+			method = methods[i];
+			ReferenceBinding[] methodThrownExceptions = method.thrownExceptions;
+			int methodExceptionsLength = methodThrownExceptions == null ? 0: methodThrownExceptions.length;
+			if (methodExceptionsLength == 0) break none;
+			if (shouldAdaptThrows && method != theAbstractMethod) {
+				System.arraycopy(methodThrownExceptions, 0, methodThrownExceptions = new ReferenceBinding[methodExceptionsLength], 0, methodExceptionsLength);
+				for (int tv = 0; tv < typeVariableLength; tv++) {
+					if (methodThrownExceptions[tv] instanceof TypeVariableBinding) {
+						methodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
+					}
+				}
+			}
+			nextException: for (int j = 0; j < methodExceptionsLength; j++) {
+				ReferenceBinding methodException = methodThrownExceptions[j];
+				if (shouldEraseThrows)
+					methodException = (ReferenceBinding) methodException.erasure();
+				nextMethod: for (int k = 0; k < length; k++) {
+					if (i == k) continue;
+					otherMethod = methods[k];
+					ReferenceBinding[] otherMethodThrownExceptions = otherMethod.thrownExceptions;
+					int otherMethodExceptionsLength =  otherMethodThrownExceptions == null ? 0 : otherMethodThrownExceptions.length;
+					if (otherMethodExceptionsLength == 0) break none;
+					if (shouldAdaptThrows && otherMethod != theAbstractMethod) {
+						System.arraycopy(otherMethodThrownExceptions, 
+								0, 
+								otherMethodThrownExceptions = new ReferenceBinding[otherMethodExceptionsLength], 
+								0, 
+								otherMethodExceptionsLength);
+						for (int tv = 0; tv < typeVariableLength; tv++) {
+							if (otherMethodThrownExceptions[tv] instanceof TypeVariableBinding) {
+								otherMethodThrownExceptions[tv] = theAbstractMethod.typeVariables[tv];
+							}
+						}
+					}
+					for (int l = 0; l < otherMethodExceptionsLength; l++) {
+						ReferenceBinding otherException = otherMethodThrownExceptions[l];
+						if (shouldEraseThrows)
+							otherException = (ReferenceBinding) otherException.erasure();
+						if (methodException.isCompatibleWith(otherException))
+							continue nextMethod;
+					}
+					continue nextException;
+				}
+				// If we reach here, method exception or its super type is covered by every throws clause.
+				if (exceptionsCount == exceptionsLength) {
+					System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsLength += 16], 0, exceptionsCount);
+				}
+				exceptions[exceptionsCount++] = methodException;
+			}
+		}
+		if (exceptionsCount != exceptionsLength) {
+			System.arraycopy(exceptions, 0, exceptions = new ReferenceBinding[exceptionsCount], 0, exceptionsCount);
+		}
+		this.singleAbstractMethod = new MethodBinding(theAbstractMethod.modifiers, 
+				theAbstractMethod.selector, 
+				theAbstractMethod.returnType, 
+				theAbstractMethod.parameters, 
+				exceptions, 
+				theAbstractMethod.declaringClass);
+	    this.singleAbstractMethod.typeVariables = theAbstractMethod.typeVariables;
+		return this.singleAbstractMethod;
+	}
+	return this.singleAbstractMethod = samProblemBinding;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
new file mode 100644
index 0000000..b399feb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -0,0 +1,4502 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *	 							bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 387612 - Unreachable catch block...exception is never thrown from the try
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 401456 - Code compiles from javac/intellij, but fails from eclipse
+ *								bug 401271 - StackOverflowError when searching for a methods references
+ *								bug 405706 - Eclipse compiler fails to give compiler error when return type is a inferred generic
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *  							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public abstract class Scope {
+
+	/* Scope kinds */
+	public final static int BLOCK_SCOPE = 1;
+	public final static int CLASS_SCOPE = 3;
+	public final static int COMPILATION_UNIT_SCOPE = 4;
+	public final static int METHOD_SCOPE = 2;
+
+	/* Argument Compatibilities */
+	public final static int NOT_COMPATIBLE = -1;
+	public final static int COMPATIBLE = 0;
+	public final static int AUTOBOX_COMPATIBLE = 1;
+	public final static int VARARGS_COMPATIBLE = 2;
+
+	/* Type Compatibilities */
+	public static final int EQUAL_OR_MORE_SPECIFIC = -1;
+	public static final int NOT_RELATED = 0;
+	public static final int MORE_GENERIC = 1;
+
+	public int kind;
+	public Scope parent;
+
+	protected Scope(int kind, Scope parent) {
+		this.kind = kind;
+		this.parent = parent;
+	}
+
+	/* Answer an int describing the relationship between the given types.
+	*
+	* 		NOT_RELATED
+	* 		EQUAL_OR_MORE_SPECIFIC : left is compatible with right
+	* 		MORE_GENERIC : right is compatible with left
+	*/
+	public static int compareTypes(TypeBinding left, TypeBinding right) {
+		if (left.isCompatibleWith(right))
+			return Scope.EQUAL_OR_MORE_SPECIFIC;
+		if (right.isCompatibleWith(left))
+			return Scope.MORE_GENERIC;
+		return Scope.NOT_RELATED;
+	}
+
+	/**
+	 * Returns a type where either all variables or specific ones got discarded.
+	 * e.g. List<E> (discarding <E extends Enum<E>) will return:  List<? extends Enum<?>>
+	 */
+	public static TypeBinding convertEliminatingTypeVariables(TypeBinding originalType, ReferenceBinding genericType, int rank, Set eliminatedVariables) {
+		if ((originalType.tagBits & TagBits.HasTypeVariable) != 0) {
+			switch (originalType.kind()) {
+				case Binding.ARRAY_TYPE :
+					ArrayBinding originalArrayType = (ArrayBinding) originalType;
+					TypeBinding originalLeafComponentType = originalArrayType.leafComponentType;
+					TypeBinding substitute = convertEliminatingTypeVariables(originalLeafComponentType, genericType, rank, eliminatedVariables); // substitute could itself be array type
+					if (substitute != originalLeafComponentType) {
+						return originalArrayType.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalArrayType.dimensions());
+					}
+					break;
+				case Binding.PARAMETERIZED_TYPE :
+					ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
+					ReferenceBinding originalEnclosing = paramType.enclosingType();
+					ReferenceBinding substitutedEnclosing = originalEnclosing;
+					if (originalEnclosing != null) {
+						substitutedEnclosing = (ReferenceBinding) convertEliminatingTypeVariables(originalEnclosing, genericType, rank, eliminatedVariables);
+					}
+					TypeBinding[] originalArguments = paramType.arguments;
+					TypeBinding[] substitutedArguments = originalArguments;
+					for (int i = 0, length = originalArguments == null ? 0 : originalArguments.length; i < length; i++) {
+						TypeBinding originalArgument = originalArguments[i];
+						TypeBinding substitutedArgument = convertEliminatingTypeVariables(originalArgument, paramType.genericType(), i, eliminatedVariables);
+						if (substitutedArgument != originalArgument) {
+							if (substitutedArguments == originalArguments) {
+								System.arraycopy(originalArguments, 0, substitutedArguments = new TypeBinding[length], 0, i);
+							}
+							substitutedArguments[i] = substitutedArgument;
+						} else 	if (substitutedArguments != originalArguments) {
+							substitutedArguments[i] = originalArgument;
+						}
+					}
+					if (originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments) {
+						return paramType.environment.createParameterizedType(paramType.genericType(), substitutedArguments, substitutedEnclosing);
+					}
+					break;
+				case Binding.TYPE_PARAMETER :
+					if (genericType == null) {
+						break;
+					}
+					TypeVariableBinding originalVariable = (TypeVariableBinding) originalType;
+					if (eliminatedVariables != null && eliminatedVariables.contains(originalType)) {
+						return originalVariable.environment.createWildcard(genericType, rank, null, null, Wildcard.UNBOUND);
+					}
+					TypeBinding originalUpperBound = originalVariable.upperBound();
+					if (eliminatedVariables == null) {
+						eliminatedVariables = new HashSet(2);
+					}
+					eliminatedVariables.add(originalVariable);
+					TypeBinding substitutedUpperBound = convertEliminatingTypeVariables(originalUpperBound, genericType, rank, eliminatedVariables);
+					eliminatedVariables.remove(originalVariable);
+					return originalVariable.environment.createWildcard(genericType, rank, substitutedUpperBound, null, Wildcard.EXTENDS);
+				case Binding.RAW_TYPE :
+					break;
+				case Binding.GENERIC_TYPE :
+					ReferenceBinding currentType = (ReferenceBinding) originalType;
+					originalEnclosing = currentType.enclosingType();
+					substitutedEnclosing = originalEnclosing;
+					if (originalEnclosing != null) {
+						substitutedEnclosing = (ReferenceBinding) convertEliminatingTypeVariables(originalEnclosing, genericType, rank, eliminatedVariables);
+					}
+					originalArguments = currentType.typeVariables();
+					substitutedArguments = originalArguments;
+					for (int i = 0, length = originalArguments == null ? 0 : originalArguments.length; i < length; i++) {
+						TypeBinding originalArgument = originalArguments[i];
+						TypeBinding substitutedArgument = convertEliminatingTypeVariables(originalArgument, currentType, i, eliminatedVariables);
+						if (substitutedArgument != originalArgument) {
+							if (substitutedArguments == originalArguments) {
+								System.arraycopy(originalArguments, 0, substitutedArguments = new TypeBinding[length], 0, i);
+							}
+							substitutedArguments[i] = substitutedArgument;
+						} else 	if (substitutedArguments != originalArguments) {
+							substitutedArguments[i] = originalArgument;
+						}
+					}
+					if (originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments) {
+						return ((TypeVariableBinding)originalArguments[0]).environment.createParameterizedType(genericType, substitutedArguments, substitutedEnclosing);
+					}
+					break;
+				case Binding.WILDCARD_TYPE :
+					WildcardBinding wildcard = (WildcardBinding) originalType;
+					TypeBinding originalBound = wildcard.bound;
+					TypeBinding substitutedBound = originalBound;
+					if (originalBound != null) {
+						substitutedBound = convertEliminatingTypeVariables(originalBound, genericType, rank, eliminatedVariables);
+						if (substitutedBound != originalBound) {
+							return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, null, wildcard.boundKind);
+						}
+					}
+					break;
+				case Binding.INTERSECTION_TYPE :
+					WildcardBinding intersection = (WildcardBinding) originalType;
+					originalBound = intersection.bound;
+					substitutedBound = originalBound;
+					if (originalBound != null) {
+						substitutedBound = convertEliminatingTypeVariables(originalBound, genericType, rank, eliminatedVariables);
+					}
+					TypeBinding[] originalOtherBounds = intersection.otherBounds;
+					TypeBinding[] substitutedOtherBounds = originalOtherBounds;
+					for (int i = 0, length = originalOtherBounds == null ? 0 : originalOtherBounds.length; i < length; i++) {
+						TypeBinding originalOtherBound = originalOtherBounds[i];
+						TypeBinding substitutedOtherBound = convertEliminatingTypeVariables(originalOtherBound, genericType, rank, eliminatedVariables);
+						if (substitutedOtherBound != originalOtherBound) {
+							if (substitutedOtherBounds == originalOtherBounds) {
+								System.arraycopy(originalOtherBounds, 0, substitutedOtherBounds = new TypeBinding[length], 0, i);
+							}
+							substitutedOtherBounds[i] = substitutedOtherBound;
+						} else 	if (substitutedOtherBounds != originalOtherBounds) {
+							substitutedOtherBounds[i] = originalOtherBound;
+						}
+					}
+					if (substitutedBound != originalBound || substitutedOtherBounds != originalOtherBounds) {
+						return intersection.environment.createWildcard(intersection.genericType, intersection.rank, substitutedBound, substitutedOtherBounds, intersection.boundKind);
+					}
+					break;
+				}
+		}
+		return originalType;
+	}	
+
+   public static TypeBinding getBaseType(char[] name) {
+		// list should be optimized (with most often used first)
+		int length = name.length;
+		if (length > 2 && length < 8) {
+			switch (name[0]) {
+				case 'i' :
+					if (length == 3 && name[1] == 'n' && name[2] == 't')
+						return TypeBinding.INT;
+					break;
+				case 'v' :
+					if (length == 4 && name[1] == 'o' && name[2] == 'i' && name[3] == 'd')
+						return TypeBinding.VOID;
+					break;
+				case 'b' :
+					if (length == 7
+						&& name[1] == 'o'
+						&& name[2] == 'o'
+						&& name[3] == 'l'
+						&& name[4] == 'e'
+						&& name[5] == 'a'
+						&& name[6] == 'n')
+						return TypeBinding.BOOLEAN;
+					if (length == 4 && name[1] == 'y' && name[2] == 't' && name[3] == 'e')
+						return TypeBinding.BYTE;
+					break;
+				case 'c' :
+					if (length == 4 && name[1] == 'h' && name[2] == 'a' && name[3] == 'r')
+						return TypeBinding.CHAR;
+					break;
+				case 'd' :
+					if (length == 6
+						&& name[1] == 'o'
+						&& name[2] == 'u'
+						&& name[3] == 'b'
+						&& name[4] == 'l'
+						&& name[5] == 'e')
+						return TypeBinding.DOUBLE;
+					break;
+				case 'f' :
+					if (length == 5
+						&& name[1] == 'l'
+						&& name[2] == 'o'
+						&& name[3] == 'a'
+						&& name[4] == 't')
+						return TypeBinding.FLOAT;
+					break;
+				case 'l' :
+					if (length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g')
+						return TypeBinding.LONG;
+					break;
+				case 's' :
+					if (length == 5
+						&& name[1] == 'h'
+						&& name[2] == 'o'
+						&& name[3] == 'r'
+						&& name[4] == 't')
+						return TypeBinding.SHORT;
+			}
+		}
+		return null;
+	}
+
+	// 5.1.10
+	public static ReferenceBinding[] greaterLowerBound(ReferenceBinding[] types) {
+		if (types == null) return null;
+		int length = types.length;
+		if (length == 0) return null;
+		ReferenceBinding[] result = types;
+		int removed = 0;
+		for (int i = 0; i < length; i++) {
+			ReferenceBinding iType = result[i];
+			if (iType == null) continue;
+			for (int j = 0; j < length; j++) {
+				if (i == j) continue;
+				ReferenceBinding jType = result[j];
+				if (jType == null) continue;
+				if (iType.isCompatibleWith(jType)) { // if Vi <: Vj, Vj is removed
+					if (result == types) { // defensive copy
+						System.arraycopy(result, 0, result = new ReferenceBinding[length], 0, length);
+					}
+					result[j] = null;
+					removed ++;
+				}
+			}
+		}
+		if (removed == 0) return result;
+		if (length == removed) return null;
+		ReferenceBinding[] trimmedResult = new ReferenceBinding[length - removed];
+		for (int i = 0, index = 0; i < length; i++) {
+			ReferenceBinding iType = result[i];
+			if (iType != null) {
+				trimmedResult[index++] = iType;
+			}
+		}
+		return trimmedResult;
+	}
+
+	// 5.1.10
+	public static TypeBinding[] greaterLowerBound(TypeBinding[] types, /*@Nullable*/ Scope scope) {
+		if (types == null) return null;
+		int length = types.length;
+		if (length == 0) return null;
+		TypeBinding[] result = types;
+		int removed = 0;
+		for (int i = 0; i < length; i++) {
+			TypeBinding iType = result[i];
+			if (iType == null) continue;
+			for (int j = 0; j < length; j++) {
+				if (i == j) continue;
+				TypeBinding jType = result[j];
+				if (jType == null) continue;
+				if (iType.isCompatibleWith(jType, scope)) { // if Vi <: Vj, Vj is removed
+					if (result == types) { // defensive copy
+						System.arraycopy(result, 0, result = new TypeBinding[length], 0, length);
+					}
+					result[j] = null;
+					removed ++;
+				} else if (!jType.isCompatibleWith(iType, scope)) {
+					// avoid creating unsatisfiable intersection types (see https://bugs.eclipse.org/405706):
+					if (iType.isParameterizedType() && jType.isParameterizedType()) {
+						if (iType.original().isCompatibleWith(jType.original(), scope)
+								|| jType.original().isCompatibleWith(iType.original(), scope)) 
+						{
+							// parameterized types are incompatible due to incompatible type arguments => unsatisfiable
+							return null;
+						}
+					}
+				}
+			}
+		}
+		if (removed == 0) return result;
+		if (length == removed) return null; // how is this possible ???
+		TypeBinding[] trimmedResult = new TypeBinding[length - removed];
+		for (int i = 0, index = 0; i < length; i++) {
+			TypeBinding iType = result[i];
+			if (iType != null) {
+				trimmedResult[index++] = iType;
+			}
+		}
+		return trimmedResult;
+	}
+
+	/**
+	 * Returns an array of types, where original types got substituted given a substitution.
+	 * Only allocate an array if anything is different.
+	 */
+	public static ReferenceBinding[] substitute(Substitution substitution, ReferenceBinding[] originalTypes) {
+		if (originalTypes == null) return null;
+	    ReferenceBinding[] substitutedTypes = originalTypes;
+	    for (int i = 0, length = originalTypes.length; i < length; i++) {
+	        ReferenceBinding originalType = originalTypes[i];
+	        TypeBinding substitutedType = substitute(substitution, originalType);
+	        if (!(substitutedType instanceof ReferenceBinding)) {
+	        	return null; // impossible substitution
+	        }
+	        if (substitutedType != originalType) {
+	            if (substitutedTypes == originalTypes) {
+	                System.arraycopy(originalTypes, 0, substitutedTypes = new ReferenceBinding[length], 0, i);
+	            }
+	            substitutedTypes[i] = (ReferenceBinding)substitutedType;
+	        } else if (substitutedTypes != originalTypes) {
+	            substitutedTypes[i] = originalType;
+	        }
+	    }
+	    return substitutedTypes;
+	}
+
+	/**
+	 * Returns a type, where original type was substituted using the receiver
+	 * parameterized type.
+	 * In raw mode (see {@link Substitution#isRawSubstitution()}),
+	 * all parameterized types are converted to raw types.
+	 * Cf. 4.8: "The type of a constructor (8.8), instance method (8.4, 9.4),
+	 *  or non-static field (8.3) M of a raw type C that is not inherited from its 
+	 *  superclasses or superinterfaces is the raw type that corresponds to the erasure
+	 *  of its type in the generic declaration corresponding to C." 
+	 */
+	public static TypeBinding substitute(Substitution substitution, TypeBinding originalType) {
+		if (originalType == null) return null;
+		switch (originalType.kind()) {
+
+			case Binding.TYPE_PARAMETER:
+				return substitution.substitute((TypeVariableBinding) originalType);
+
+			case Binding.PARAMETERIZED_TYPE:
+				ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
+				ReferenceBinding originalEnclosing = originalType.enclosingType();
+				ReferenceBinding substitutedEnclosing = originalEnclosing;
+				if (originalEnclosing != null) {
+					substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
+					if (isMemberTypeOfRaw(originalType, substitutedEnclosing))
+						return originalParameterizedType.environment.createRawType(
+								originalParameterizedType.genericType(), substitutedEnclosing);
+				}
+				TypeBinding[] originalArguments = originalParameterizedType.arguments;
+				TypeBinding[] substitutedArguments = originalArguments;
+				if (originalArguments != null) {
+					if (substitution.isRawSubstitution()) {
+						return originalParameterizedType.environment.createRawType(originalParameterizedType.genericType(), substitutedEnclosing);
+					}
+					substitutedArguments = substitute(substitution, originalArguments);
+				}
+				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
+					return originalParameterizedType.environment.createParameterizedType(
+							originalParameterizedType.genericType(), substitutedArguments, substitutedEnclosing);
+				}
+				break;
+
+			case Binding.ARRAY_TYPE:
+				ArrayBinding originalArrayType = (ArrayBinding) originalType;
+				TypeBinding originalLeafComponentType = originalArrayType.leafComponentType;
+				TypeBinding substitute = substitute(substitution, originalLeafComponentType); // substitute could itself be array type
+				if (substitute != originalLeafComponentType) {
+					return originalArrayType.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
+				}
+				break;
+
+			case Binding.WILDCARD_TYPE:
+			case Binding.INTERSECTION_TYPE:
+		        WildcardBinding wildcard = (WildcardBinding) originalType;
+		        if (wildcard.boundKind != Wildcard.UNBOUND) {
+			        TypeBinding originalBound = wildcard.bound;
+			        TypeBinding substitutedBound = substitute(substitution, originalBound);
+			        TypeBinding[] originalOtherBounds = wildcard.otherBounds;
+			        TypeBinding[] substitutedOtherBounds = substitute(substitution, originalOtherBounds);
+			        if (substitutedBound != originalBound || originalOtherBounds != substitutedOtherBounds) {
+			        	if (originalOtherBounds != null) {
+			        		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=347145: the constituent intersecting types have changed
+			        		   in the last round of substitution. Reevaluate the composite intersection type, as there is a possibility
+			        		   of the intersection collapsing into one of the constituents, the other being fully subsumed.
+			        		*/
+			    			TypeBinding [] bounds = new TypeBinding[1 + substitutedOtherBounds.length];
+			    			bounds[0] = substitutedBound;
+			    			System.arraycopy(substitutedOtherBounds, 0, bounds, 1, substitutedOtherBounds.length);
+			    			TypeBinding[] glb = Scope.greaterLowerBound(bounds, null); // re-evaluate
+			    			if (glb != null && glb != bounds) {
+			    				substitutedBound = glb[0];
+		    					if (glb.length == 1) {
+			    					substitutedOtherBounds = null;
+			    				} else {
+			    					System.arraycopy(glb, 1, substitutedOtherBounds = new TypeBinding[glb.length - 1], 0, glb.length - 1);
+			    				}
+			    			}
+			        	}
+		        		return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, substitutedOtherBounds, wildcard.boundKind);
+			        }
+		        }
+				break;
+
+			case Binding.TYPE:
+				if (!originalType.isMemberType()) break;
+				ReferenceBinding originalReferenceType = (ReferenceBinding) originalType;
+				originalEnclosing = originalType.enclosingType();
+				substitutedEnclosing = originalEnclosing;
+				if (originalEnclosing != null) {
+					substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
+					if (isMemberTypeOfRaw(originalType, substitutedEnclosing))
+						return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing);
+				}
+
+			    // treat as if parameterized with its type variables (non generic type gets 'null' arguments)
+				if (substitutedEnclosing != originalEnclosing) {
+					return substitution.isRawSubstitution()
+						? substitution.environment().createRawType(originalReferenceType, substitutedEnclosing)
+						:  substitution.environment().createParameterizedType(originalReferenceType, null, substitutedEnclosing);
+				}
+				break;
+			case Binding.GENERIC_TYPE:
+				originalReferenceType = (ReferenceBinding) originalType;
+				originalEnclosing = originalType.enclosingType();
+				substitutedEnclosing = originalEnclosing;
+				if (originalEnclosing != null) {
+					substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
+					if (isMemberTypeOfRaw(originalType, substitutedEnclosing))
+						return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing);
+				}
+
+				if (substitution.isRawSubstitution()) {
+					return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing);
+				}
+			    // treat as if parameterized with its type variables (non generic type gets 'null' arguments)
+				originalArguments = originalReferenceType.typeVariables();
+				substitutedArguments = substitute(substitution, originalArguments);
+				return substitution.environment().createParameterizedType(originalReferenceType, substitutedArguments, substitutedEnclosing);
+		}
+		return originalType;
+	}
+
+	private static boolean isMemberTypeOfRaw(TypeBinding originalType, ReferenceBinding substitutedEnclosing) {
+		// 4.8:
+		// "a raw type is defined to be one of:
+		// ...
+	    // * A non-static member type of a raw type R that is not 
+		//   inherited from a superclass or superinterface of R."
+
+		// Due to staticness, e.g., Map.Entry<String,Object> is *not* considered as a raw type
+
+		return (substitutedEnclosing != null && substitutedEnclosing.isRawType()) 
+				&& ((originalType instanceof ReferenceBinding) && !((ReferenceBinding)originalType).isStatic());
+	}
+
+	/**
+	 * Returns an array of types, where original types got substituted given a substitution.
+	 * Only allocate an array if anything is different.
+	 */
+	public static TypeBinding[] substitute(Substitution substitution, TypeBinding[] originalTypes) {
+		if (originalTypes == null) return null;
+	    TypeBinding[] substitutedTypes = originalTypes;
+	    for (int i = 0, length = originalTypes.length; i < length; i++) {
+	        TypeBinding originalType = originalTypes[i];
+	        TypeBinding substitutedParameter = substitute(substitution, originalType);
+	        if (substitutedParameter != originalType) {
+	            if (substitutedTypes == originalTypes) {
+	                System.arraycopy(originalTypes, 0, substitutedTypes = new TypeBinding[length], 0, i);
+	            }
+	            substitutedTypes[i] = substitutedParameter;
+	        } else if (substitutedTypes != originalTypes) {
+	            substitutedTypes[i] = originalType;
+	        }
+	    }
+	    return substitutedTypes;
+	}
+
+	/*
+	 * Boxing primitive
+	 */
+	public TypeBinding boxing(TypeBinding type) {
+		if (type.isBaseType())
+			return environment().computeBoxingType(type);
+		return type;
+	}
+
+	public final ClassScope classScope() {
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope)
+				return (ClassScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+
+	public final CompilationUnitScope compilationUnitScope() {
+		Scope lastScope = null;
+		Scope scope = this;
+		do {
+			lastScope = scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return (CompilationUnitScope) lastScope;
+	}
+	
+	public boolean isLambdaScope() {
+		return false;
+	}
+	
+	public boolean isLambdaSubscope() {
+		for (Scope scope = this; scope != null; scope = scope.parent) {
+			switch (scope.kind) {
+				case BLOCK_SCOPE:
+			        continue;
+				case METHOD_SCOPE:
+					return scope.isLambdaScope();
+				default:
+					return false;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Finds the most specific compiler options
+	 */
+	public final CompilerOptions compilerOptions() {
+
+		return compilationUnitScope().environment.globalOptions;
+	}
+
+	/**
+	 * Internal use only
+	 * Given a method, returns null if arguments cannot be converted to parameters.
+	 * Will answer a substituted method in case the method was generic and type inference got triggered;
+	 * in case the method was originally compatible, then simply answer it back.
+	 */
+	protected final MethodBinding computeCompatibleMethod(MethodBinding method, TypeBinding[] arguments, InvocationSite invocationSite) {
+		return computeCompatibleMethod(method, arguments, invocationSite, false);
+	}	
+	/**
+	 * Internal use only
+	 * Given a method, returns null if arguments cannot be converted to parameters.
+	 * Will answer a substituted method in case the method was generic and type inference got triggered;
+	 * in case the method was originally compatible, then simply answer it back.
+	 */
+	protected final MethodBinding computeCompatibleMethod(MethodBinding method, TypeBinding[] arguments, InvocationSite invocationSite, boolean tiebreakingVarargsMethods) {
+		TypeBinding[] genericTypeArguments = invocationSite.genericTypeArguments();
+		TypeBinding[] parameters = method.parameters;
+		TypeVariableBinding[] typeVariables = method.typeVariables;
+		if (parameters == arguments
+			&& (method.returnType.tagBits & TagBits.HasTypeVariable) == 0
+			&& genericTypeArguments == null
+			&& typeVariables == Binding.NO_TYPE_VARIABLES)
+				return method;
+
+		int argLength = arguments.length;
+		int paramLength = parameters.length;
+		boolean isVarArgs = method.isVarargs();
+		if (argLength != paramLength)
+			if (!isVarArgs || argLength < paramLength - 1)
+				return null; // incompatible
+		CompilerOptions compilerOptions = this.compilerOptions();
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=330435, inference should kick in only at source 1.5+
+		if (typeVariables != Binding.NO_TYPE_VARIABLES && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5) { // generic method
+			TypeBinding[] newArgs = null;
+			for (int i = 0; i < argLength; i++) {
+				TypeBinding param = i < paramLength ? parameters[i] : parameters[paramLength - 1];
+				if (arguments[i].isBaseType() != param.isBaseType()) {
+					if (newArgs == null) {
+						newArgs = new TypeBinding[argLength];
+						System.arraycopy(arguments, 0, newArgs, 0, argLength);
+					}
+					newArgs[i] = environment().computeBoxingType(arguments[i]);
+				}
+			}
+			if (newArgs != null)
+				arguments = newArgs;
+			method = ParameterizedGenericMethodBinding.computeCompatibleMethod(method, arguments, this, invocationSite);
+			if (method == null) return null; // incompatible
+			if (!method.isValidBinding()) return method; // bound check issue is taking precedence
+		} else if (genericTypeArguments != null && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7) {
+			if (method instanceof ParameterizedGenericMethodBinding) {
+				if (!((ParameterizedGenericMethodBinding) method).wasInferred)
+					// attempt to invoke generic method of raw type with type hints <String>foo()
+					return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.TypeArgumentsForRawGenericMethod);
+			} else if (!method.isOverriding() || !isOverriddenMethodGeneric(method)) {
+				return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.TypeParameterArityMismatch);
+			}
+		}
+
+		int compatibilityLevel;
+		if (tiebreakingVarargsMethods) {
+			if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7)
+				tiebreakingVarargsMethods = false;
+		}
+		if ((compatibilityLevel = parameterCompatibilityLevel(method, arguments, tiebreakingVarargsMethods)) > NOT_COMPATIBLE) {
+			if (compatibilityLevel == VARARGS_COMPATIBLE) {
+				TypeBinding varargsElementType = method.parameters[method.parameters.length - 1].leafComponentType();
+				if (varargsElementType instanceof ReferenceBinding) {
+					if (!((ReferenceBinding) varargsElementType).canBeSeenBy(this)) {
+						return new ProblemMethodBinding(method, method.selector, genericTypeArguments, ProblemReasons.VarargsElementTypeNotVisible);
+					}
+				}
+			}
+			if ((method.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+				// generate polymorphic method
+				return this.environment().createPolymorphicMethod(method, arguments);
+			}
+			return method;
+		}
+		// if method is generic and type arguments have been supplied, only then answer a problem 
+		// of ParameterizedMethodTypeMismatch, else a non-generic method was invoked using type arguments
+		// in which case this problem category will be bogus
+		if (genericTypeArguments != null && typeVariables != Binding.NO_TYPE_VARIABLES)
+			return new ProblemMethodBinding(method, method.selector, arguments, ProblemReasons.ParameterizedMethodTypeMismatch);
+		return null; // incompatible
+	}
+
+	/**
+	 * Connect type variable supertypes, and returns true if no problem was detected
+	 * @param typeParameters
+	 * @param checkForErasedCandidateCollisions
+	 */
+	protected boolean connectTypeVariables(TypeParameter[] typeParameters, boolean checkForErasedCandidateCollisions) {
+		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 - We used to not bother with connecting
+		   type variables if source level is < 1.5. This creates problems in the reconciler if a 1.4
+		   project references the generified API of a 1.5 project. The "current" project's source
+		   level cannot decide this question for some other project. Now, if we see type parameters
+		   at all, we assume that the concerned java element has some legitimate business with them.
+		 */
+		if (typeParameters == null || typeParameters.length == 0) return true;
+		Map invocations = new HashMap(2);
+		boolean noProblems = true;
+		// preinitializing each type variable
+		for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
+			TypeParameter typeParameter = typeParameters[i];
+			TypeVariableBinding typeVariable = typeParameter.binding;
+			if (typeVariable == null) return false;
+
+			typeVariable.superclass = getJavaLangObject();
+			typeVariable.superInterfaces = Binding.NO_SUPERINTERFACES;
+			// set firstBound to the binding of the first explicit bound in parameter declaration
+			typeVariable.firstBound = null; // first bound used to compute erasure
+		}
+		nextVariable: for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
+			TypeParameter typeParameter = typeParameters[i];
+			TypeVariableBinding typeVariable = typeParameter.binding;
+			TypeReference typeRef = typeParameter.type;
+			if (typeRef == null)
+				continue nextVariable;
+			boolean isFirstBoundTypeVariable = false;
+			TypeBinding superType = this.kind == METHOD_SCOPE
+				? typeRef.resolveType((BlockScope)this, false/*no bound check*/)
+				: typeRef.resolveType((ClassScope)this);
+			if (superType == null) {
+				typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+			} else {
+				typeRef.resolvedType = superType; // hold onto the problem type
+				firstBound: {
+					switch (superType.kind()) {
+						case Binding.ARRAY_TYPE :
+							problemReporter().boundCannotBeArray(typeRef, superType);
+							typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+							break firstBound; // do not keep first bound
+						case Binding.TYPE_PARAMETER :
+							isFirstBoundTypeVariable = true;
+							TypeVariableBinding varSuperType = (TypeVariableBinding) superType;
+							if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) {
+								if (compilerOptions().complianceLevel <= ClassFileConstants.JDK1_6) {
+									problemReporter().forwardTypeVariableReference(typeParameter, varSuperType);
+									typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+									break firstBound; // do not keep first bound
+								}
+							}
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335751
+							if (compilerOptions().complianceLevel > ClassFileConstants.JDK1_6) {
+								if (typeVariable.rank >= varSuperType.rank && varSuperType.declaringElement == typeVariable.declaringElement) {
+									SimpleSet set = new SimpleSet(typeParameters.length);
+									set.add(typeVariable);
+									ReferenceBinding superBinding = varSuperType;
+									while (superBinding instanceof TypeVariableBinding) {
+										if (set.includes(superBinding)) {
+											problemReporter().hierarchyCircularity(typeVariable, varSuperType, typeRef);
+											typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+											break firstBound; // do not keep first bound
+										} else {
+											set.add(superBinding);
+											superBinding = ((TypeVariableBinding)superBinding).superclass;
+										}
+									}
+								}
+							}
+							break;
+						default :
+							if (((ReferenceBinding) superType).isFinal()) {
+								problemReporter().finalVariableBound(typeVariable, typeRef);
+							}
+							break;
+					}
+					ReferenceBinding superRefType = (ReferenceBinding) superType;
+					if (!superType.isInterface()) {
+						typeVariable.superclass = superRefType;
+					} else {
+						typeVariable.superInterfaces = new ReferenceBinding[] {superRefType};
+					}
+					typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences;
+					typeVariable.firstBound = superRefType; // first bound used to compute erasure
+				}
+			}
+			TypeReference[] boundRefs = typeParameter.bounds;
+			if (boundRefs != null) {
+				nextBound: for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
+					typeRef = boundRefs[j];
+					superType = this.kind == METHOD_SCOPE
+						? typeRef.resolveType((BlockScope)this, false)
+						: typeRef.resolveType((ClassScope)this);
+					if (superType == null) {
+						typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+						continue nextBound;
+					} else {
+						typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences;
+						boolean didAlreadyComplain = !typeRef.resolvedType.isValidBinding();
+						if (isFirstBoundTypeVariable && j == 0) {
+							problemReporter().noAdditionalBoundAfterTypeVariable(typeRef);
+							typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+							didAlreadyComplain = true;
+							//continue nextBound; - keep these bounds to minimize secondary errors
+						} else if (superType.isArrayType()) {
+							if (!didAlreadyComplain) {
+								problemReporter().boundCannotBeArray(typeRef, superType);
+								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+							}
+							continue nextBound;
+						} else {
+							if (!superType.isInterface()) {
+								if (!didAlreadyComplain) {
+									problemReporter().boundMustBeAnInterface(typeRef, superType);
+									typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+								}
+								continue nextBound;
+							}
+						}
+						// check against superclass
+						if (checkForErasedCandidateCollisions && typeVariable.firstBound == typeVariable.superclass) {
+							if (hasErasedCandidatesCollisions(superType, typeVariable.superclass, invocations, typeVariable, typeRef)) {
+								continue nextBound;
+							}
+						}
+						// check against superinterfaces
+						ReferenceBinding superRefType = (ReferenceBinding) superType;
+						for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
+							ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
+							if (previousInterface == superRefType) {
+								problemReporter().duplicateBounds(typeRef, superType);
+								typeVariable.tagBits |= TagBits.HierarchyHasProblems;
+								continue nextBound;
+							}
+							if (checkForErasedCandidateCollisions) {
+								if (hasErasedCandidatesCollisions(superType, previousInterface, invocations, typeVariable, typeRef)) {
+									continue nextBound;
+								}
+							}
+						}
+						int size = typeVariable.superInterfaces.length;
+						System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
+						typeVariable.superInterfaces[size] = superRefType;
+					}
+				}
+			}
+			noProblems &= (typeVariable.tagBits & TagBits.HierarchyHasProblems) == 0;
+		}
+		return noProblems;
+	}
+
+	public ArrayBinding createArrayType(TypeBinding type, int dimension) {
+		if (type.isValidBinding())
+			return environment().createArrayType(type, dimension);
+		// do not cache obvious invalid types
+		return new ArrayBinding(type, dimension, environment());
+	}
+
+	public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, If they exist at all, process type parameters irrespective of source level.
+		if (typeParameters == null || typeParameters.length == 0)
+			return Binding.NO_TYPE_VARIABLES;
+
+		PackageBinding unitPackage = compilationUnitScope().fPackage;
+		int length = typeParameters.length;
+		TypeVariableBinding[] typeVariableBindings = new TypeVariableBinding[length];
+		int count = 0;
+		for (int i = 0; i < length; i++) {
+			TypeParameter typeParameter = typeParameters[i];
+			TypeVariableBinding parameterBinding = new TypeVariableBinding(typeParameter.name, declaringElement, i, environment());
+			parameterBinding.fPackage = unitPackage;
+			typeParameter.binding = parameterBinding;
+
+			if ((typeParameter.bits & ASTNode.HasTypeAnnotations) != 0) {
+				switch(declaringElement.kind()) {
+					case Binding.METHOD :
+						MethodBinding methodBinding = (MethodBinding) declaringElement;
+						AbstractMethodDeclaration sourceMethod = methodBinding.sourceMethod();
+						if (sourceMethod != null) {
+							sourceMethod.bits |= ASTNode.HasTypeAnnotations;
+						}
+						break;
+					case Binding.TYPE :
+						if (declaringElement instanceof SourceTypeBinding) {
+							SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) declaringElement;
+							TypeDeclaration typeDeclaration = sourceTypeBinding.scope.referenceContext;
+							if (typeDeclaration != null) {
+								typeDeclaration.bits |= ASTNode.HasTypeAnnotations;
+							}
+						}
+				}
+			}
+			// detect duplicates, but keep each variable to reduce secondary errors with instantiating this generic type (assume number of variables is correct)
+			for (int j = 0; j < count; j++) {
+				TypeVariableBinding knownVar = typeVariableBindings[j];
+				if (CharOperation.equals(knownVar.sourceName, typeParameter.name))
+					problemReporter().duplicateTypeParameterInType(typeParameter);
+			}
+			typeVariableBindings[count++] = parameterBinding;
+//				TODO should offer warnings to inform about hiding declaring, enclosing or member types
+//				ReferenceBinding type = sourceType;
+//				// check that the member does not conflict with an enclosing type
+//				do {
+//					if (CharOperation.equals(type.sourceName, memberContext.name)) {
+//						problemReporter().hidingEnclosingType(memberContext);
+//						continue nextParameter;
+//					}
+//					type = type.enclosingType();
+//				} while (type != null);
+//				// check that the member type does not conflict with another sibling member type
+//				for (int j = 0; j < i; j++) {
+//					if (CharOperation.equals(referenceContext.memberTypes[j].name, memberContext.name)) {
+//						problemReporter().duplicateNestedType(memberContext);
+//						continue nextParameter;
+//					}
+//				}
+		}
+		if (count != length)
+			System.arraycopy(typeVariableBindings, 0, typeVariableBindings = new TypeVariableBinding[count], 0, count);
+		return typeVariableBindings;
+	}
+
+	public final ClassScope enclosingClassScope() {
+		Scope scope = this;
+		while ((scope = scope.parent) != null) {
+			if (scope instanceof ClassScope) return (ClassScope) scope;
+		}
+		return null; // may answer null if no type around
+	}
+
+	public final MethodScope enclosingMethodScope() {
+		Scope scope = this;
+		while ((scope = scope.parent) != null) {
+			if (scope instanceof MethodScope) return (MethodScope) scope;
+		}
+		return null; // may answer null if no method around
+	}
+
+	/* Answer the scope receiver type (could be parameterized)
+	*/
+	public final ReferenceBinding enclosingReceiverType() {
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope) {
+				return environment().convertToParameterizedType(((ClassScope) scope).referenceContext.binding);
+			}
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+	/**
+	 * Returns the immediately enclosing reference context, starting from current scope parent.
+	 * If starting on a class, it will skip current class. If starting on unitScope, returns null.
+	 */
+	public ReferenceContext enclosingReferenceContext() {
+		Scope current = this;
+		while ((current = current.parent) != null) {
+			switch(current.kind) {
+				case METHOD_SCOPE :
+					return ((MethodScope) current).referenceContext;
+				case CLASS_SCOPE :
+					return ((ClassScope) current).referenceContext;
+				case COMPILATION_UNIT_SCOPE :
+					return ((CompilationUnitScope) current).referenceContext;
+			}
+		}
+		return null;
+	}
+
+	/* Answer the scope enclosing source type (could be generic)
+	*/
+	public final SourceTypeBinding enclosingSourceType() {
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope)
+				return ((ClassScope) scope).referenceContext.binding;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+
+	public final LookupEnvironment environment() {
+		Scope scope, unitScope = this;
+		while ((scope = unitScope.parent) != null)
+			unitScope = scope;
+		return ((CompilationUnitScope) unitScope).environment;
+	}
+
+	// abstract method lookup lookup (since maybe missing default abstract methods)
+	protected MethodBinding findDefaultAbstractMethod(
+		ReferenceBinding receiverType,
+		char[] selector,
+		TypeBinding[] argumentTypes,
+		InvocationSite invocationSite,
+		ReferenceBinding classHierarchyStart,
+		ObjectVector found,
+		MethodBinding concreteMatch) {
+
+		int startFoundSize = found.size;
+		ReferenceBinding currentType = classHierarchyStart;
+		while (currentType != null) {
+			findMethodInSuperInterfaces(currentType, selector, found, invocationSite);
+			currentType = currentType.superclass();
+		}
+		MethodBinding[] candidates = null;
+		int candidatesCount = 0;
+		MethodBinding problemMethod = null;
+		int foundSize = found.size;
+		if (foundSize > startFoundSize) {
+			// argument type compatibility check
+			for (int i = startFoundSize; i < foundSize; i++) {
+				MethodBinding methodBinding = (MethodBinding) found.elementAt(i);
+				MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
+				if (compatibleMethod != null) {
+					if (compatibleMethod.isValidBinding()) {
+						if (concreteMatch != null && environment().methodVerifier().areMethodsCompatible(concreteMatch, compatibleMethod))
+							continue; // can skip this method since concreteMatch overrides it
+						if (candidatesCount == 0) {
+							candidates = new MethodBinding[foundSize - startFoundSize + 1];
+							if (concreteMatch != null)
+								candidates[candidatesCount++] = concreteMatch;
+						}
+						candidates[candidatesCount++] = compatibleMethod;
+					} else if (problemMethod == null) {
+						problemMethod = compatibleMethod;
+					}
+				}
+			}
+		}
+
+		if (candidatesCount < 2) {
+			if (concreteMatch == null) {
+				if (candidatesCount == 0)
+					return problemMethod; // can be null
+				concreteMatch = candidates[0];
+			}
+			compilationUnitScope().recordTypeReferences(concreteMatch.thrownExceptions);
+			return concreteMatch;
+		}
+		// no need to check for visibility - interface methods are public
+		if (compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+			return mostSpecificMethodBinding(candidates, candidatesCount, argumentTypes, invocationSite, receiverType);
+		return mostSpecificInterfaceMethodBinding(candidates, candidatesCount, invocationSite);
+	}
+
+	// Internal use only
+	public ReferenceBinding findDirectMemberType(char[] typeName, ReferenceBinding enclosingType) {
+		if ((enclosingType.tagBits & TagBits.HasNoMemberTypes) != 0)
+			return null; // know it has no member types (nor inherited member types)
+
+		ReferenceBinding enclosingReceiverType = enclosingReceiverType();
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordReference(enclosingType, typeName);
+		ReferenceBinding memberType = enclosingType.getMemberType(typeName);
+		if (memberType != null) {
+			unitScope.recordTypeReference(memberType);
+			if (enclosingReceiverType == null) {
+				if (memberType.canBeSeenBy(getCurrentPackage())) {
+					return memberType;
+				}
+				// maybe some type in the compilation unit is extending some class in some package
+				// and the selection is for some protected inner class of that superclass
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=235658
+				if (this instanceof CompilationUnitScope) {
+					TypeDeclaration[] types = ((CompilationUnitScope)this).referenceContext.types;
+					if (types != null) {
+						for (int i = 0, max = types.length; i < max; i++) {
+							if (memberType.canBeSeenBy(enclosingType, types[i].binding)) {
+								return memberType;
+							}
+						}
+					}
+				}
+			} else if (memberType.canBeSeenBy(enclosingType, enclosingReceiverType)) {
+				return memberType;
+			}
+			return new ProblemReferenceBinding(new char[][]{typeName}, memberType, ProblemReasons.NotVisible);
+		}
+		return null;
+	}
+
+	// Internal use only
+	public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordTypeReferences(argumentTypes);
+		MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, unitScope);
+		if (exactMethod != null && exactMethod.typeVariables == Binding.NO_TYPE_VARIABLES && !exactMethod.isBridge()) {
+			// in >= 1.5 mode, ensure the exactMatch did not match raw types
+			if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5)
+				for (int i = argumentTypes.length; --i >= 0;)
+					if (isPossibleSubtypeOfRawType(argumentTypes[i]))
+						return null;
+			// must find both methods for this case: <S extends A> void foo() {}  and  <N extends B> N foo() { return null; }
+			// or find an inherited method when the exact match is to a bridge method
+			unitScope.recordTypeReferences(exactMethod.thrownExceptions);
+			if (exactMethod.isAbstract() && exactMethod.thrownExceptions != Binding.NO_EXCEPTIONS)
+				return null; // may need to merge exceptions with interface method
+			// special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
+			if (exactMethod.canBeSeenBy(receiverType, invocationSite, this)) {
+				if (argumentTypes == Binding.NO_PARAMETERS
+				    && CharOperation.equals(selector, TypeConstants.GETCLASS)
+				    && exactMethod.returnType.isParameterizedType()/*1.5*/) {
+						return environment().createGetClassMethod(receiverType, exactMethod, this);
+			    }
+				// targeting a generic method could find an exact match with variable return type
+				if (invocationSite.genericTypeArguments() != null) {
+					// computeCompatibleMethod(..) will return a PolymorphicMethodBinding if needed
+					exactMethod = computeCompatibleMethod(exactMethod, argumentTypes, invocationSite);
+				} else if ((exactMethod.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+					// generate polymorphic method
+					return this.environment().createPolymorphicMethod(exactMethod, argumentTypes);
+				}
+				return exactMethod;
+			}
+		}
+		return null;
+	}
+	// Internal use only
+	/*	Answer the field binding that corresponds to fieldName.
+		Start the lookup at the receiverType.
+		InvocationSite implements
+			isSuperAccess(); this is used to determine if the discovered field is visible.
+		Only fields defined by the receiverType or its supertypes are answered;
+		a field of an enclosing type will not be found using this API.
+    	If no visible field is discovered, null is answered.
+	 */
+	public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite, boolean needResolve) {
+		return findField(receiverType, fieldName, invocationSite, needResolve, false);
+	}
+	// Internal use only
+	/*	Answer the field binding that corresponds to fieldName.
+		Start the lookup at the receiverType.
+		InvocationSite implements
+			isSuperAccess(); this is used to determine if the discovered field is visible.
+		Only fields defined by the receiverType or its supertypes are answered;
+		a field of an enclosing type will not be found using this API.
+        If the parameter invisibleFieldsOk is true, visibility checks have not been run on
+        any returned fields. The caller needs to apply these checks as needed. Otherwise,
+		If no visible field is discovered, null is answered.
+	*/
+	public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite, boolean needResolve, boolean invisibleFieldsOk) {
+
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordTypeReference(receiverType);
+
+		checkArrayField: {
+			TypeBinding leafType;
+			switch (receiverType.kind()) {
+				case Binding.BASE_TYPE :
+					return null;
+				case Binding.WILDCARD_TYPE :
+				case Binding.INTERSECTION_TYPE:
+				case Binding.TYPE_PARAMETER : // capture
+					TypeBinding receiverErasure = receiverType.erasure();
+					if (!receiverErasure.isArrayType())
+						break checkArrayField;
+					leafType = receiverErasure.leafComponentType();
+					break;
+				case Binding.ARRAY_TYPE :
+					leafType = receiverType.leafComponentType();
+					break;
+				default:
+					break checkArrayField;
+			}
+			if (leafType instanceof ReferenceBinding)
+				if (!((ReferenceBinding) leafType).canBeSeenBy(this))
+					return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
+			if (CharOperation.equals(fieldName, TypeConstants.LENGTH)) {
+				if ((leafType.tagBits & TagBits.HasMissingType) != 0) {
+					return new ProblemFieldBinding(ArrayBinding.ArrayLength, null, fieldName, ProblemReasons.NotFound);
+				}
+				return ArrayBinding.ArrayLength;
+			}
+			return null;
+		}
+
+		ReferenceBinding currentType = (ReferenceBinding) receiverType;
+		if (!currentType.canBeSeenBy(this))
+			return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
+
+		currentType.initializeForStaticImports();
+		FieldBinding field = currentType.getField(fieldName, needResolve);
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=316456
+		boolean insideTypeAnnotations = this instanceof MethodScope && ((MethodScope) this).insideTypeAnnotation;
+		if (field != null) {
+			if (invisibleFieldsOk) {
+				return field;
+			}
+			if (invocationSite == null || insideTypeAnnotations
+				? field.canBeSeenBy(getCurrentPackage())
+				: field.canBeSeenBy(currentType, invocationSite, this))
+					return field;
+			return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, ProblemReasons.NotVisible);
+		}
+		// collect all superinterfaces of receiverType until the field is found in a supertype
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		FieldBinding visibleField = null;
+		boolean keepLooking = true;
+		FieldBinding notVisibleField = null;
+		// we could hold onto the not visible field for extra error reporting
+		while (keepLooking) {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+			if ((currentType = currentType.superclass()) == null)
+				break;
+
+			unitScope.recordTypeReference(currentType);
+			currentType.initializeForStaticImports();
+			currentType = (ReferenceBinding) currentType.capture(this, invocationSite == null ? 0 : invocationSite.sourceEnd());
+			if ((field = currentType.getField(fieldName, needResolve)) != null) {
+				if (invisibleFieldsOk) {
+					return field;
+				}
+				keepLooking = false;
+				if (field.canBeSeenBy(receiverType, invocationSite, this)) {
+					if (visibleField == null)
+						visibleField = field;
+					else
+						return new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
+				} else {
+					if (notVisibleField == null)
+						notVisibleField = field;
+				}
+			}
+		}
+
+		// walk all visible interfaces to find ambiguous references
+		if (interfacesToVisit != null) {
+			ProblemFieldBinding ambiguous = null;
+			done : for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				unitScope.recordTypeReference(anInterface);
+				// no need to capture rcv interface, since member field is going to be static anyway
+				if ((field = anInterface.getField(fieldName, true /*resolve*/)) != null) {
+					if (invisibleFieldsOk) {
+						return field;
+					}
+					if (visibleField == null) {
+						visibleField = field;
+					} else {
+						ambiguous = new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
+						break done;
+					}
+				} else {
+					ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+					if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+						int itsLength = itsInterfaces.length;
+						if (nextPosition + itsLength >= interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+						nextInterface : for (int a = 0; a < itsLength; a++) {
+							ReferenceBinding next = itsInterfaces[a];
+							for (int b = 0; b < nextPosition; b++)
+								if (next == interfacesToVisit[b]) continue nextInterface;
+							interfacesToVisit[nextPosition++] = next;
+						}
+					}
+				}
+			}
+			if (ambiguous != null)
+				return ambiguous;
+		}
+
+		if (visibleField != null)
+			return visibleField;
+		if (notVisibleField != null) {
+			return new ProblemFieldBinding(notVisibleField, currentType, fieldName, ProblemReasons.NotVisible);
+		}
+		return null;
+	}
+
+	// Internal use only
+	public ReferenceBinding findMemberType(char[] typeName, ReferenceBinding enclosingType) {
+		if ((enclosingType.tagBits & TagBits.HasNoMemberTypes) != 0)
+			return null; // know it has no member types (nor inherited member types)
+
+		ReferenceBinding enclosingSourceType = enclosingSourceType();
+		PackageBinding currentPackage = getCurrentPackage();
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordReference(enclosingType, typeName);
+		ReferenceBinding memberType = enclosingType.getMemberType(typeName);
+		if (memberType != null) {
+			unitScope.recordTypeReference(memberType);
+			if (enclosingSourceType == null || (this.parent == unitScope && (enclosingSourceType.tagBits & TagBits.TypeVariablesAreConnected) == 0)
+				? memberType.canBeSeenBy(currentPackage)
+				: memberType.canBeSeenBy(enclosingType, enclosingSourceType))
+					return memberType;
+			return new ProblemReferenceBinding(new char[][]{typeName}, memberType, ProblemReasons.NotVisible);
+		}
+
+		// collect all superinterfaces of receiverType until the memberType is found in a supertype
+		ReferenceBinding currentType = enclosingType;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		ReferenceBinding visibleMemberType = null;
+		boolean keepLooking = true;
+		ReferenceBinding notVisible = null;
+		// we could hold onto the not visible field for extra error reporting
+		while (keepLooking) {
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces == null) { // needed for statically imported types which don't know their hierarchy yet
+				ReferenceBinding sourceType = currentType.isParameterizedType()
+					? ((ParameterizedTypeBinding) currentType).genericType()
+					: currentType;
+				if (sourceType.isHierarchyBeingConnected())
+					return null; // looking for an undefined member type in its own superclass ref
+				((SourceTypeBinding) sourceType).scope.connectTypeHierarchy();
+				itsInterfaces = currentType.superInterfaces();
+			}
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+			if ((currentType = currentType.superclass()) == null)
+				break;
+
+			unitScope.recordReference(currentType, typeName);
+			if ((memberType = currentType.getMemberType(typeName)) != null) {
+				unitScope.recordTypeReference(memberType);
+				keepLooking = false;
+				if (enclosingSourceType == null
+					? memberType.canBeSeenBy(currentPackage)
+					: memberType.canBeSeenBy(enclosingType, enclosingSourceType)) {
+						if (visibleMemberType == null)
+							visibleMemberType = memberType;
+						else
+							return new ProblemReferenceBinding(new char[][]{typeName}, visibleMemberType, ProblemReasons.Ambiguous);
+				} else {
+					notVisible = memberType;
+				}
+			}
+		}
+		// walk all visible interfaces to find ambiguous references
+		if (interfacesToVisit != null) {
+			ProblemReferenceBinding ambiguous = null;
+			done : for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding anInterface = interfacesToVisit[i];
+				unitScope.recordReference(anInterface, typeName);
+				if ((memberType = anInterface.getMemberType(typeName)) != null) {
+					unitScope.recordTypeReference(memberType);
+					if (visibleMemberType == null) {
+						visibleMemberType = memberType;
+					} else {
+						ambiguous = new ProblemReferenceBinding(new char[][]{typeName}, visibleMemberType, ProblemReasons.Ambiguous);
+						break done;
+					}
+				} else {
+					ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+					if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+						int itsLength = itsInterfaces.length;
+						if (nextPosition + itsLength >= interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+						nextInterface : for (int a = 0; a < itsLength; a++) {
+							ReferenceBinding next = itsInterfaces[a];
+							for (int b = 0; b < nextPosition; b++)
+								if (next == interfacesToVisit[b]) continue nextInterface;
+							interfacesToVisit[nextPosition++] = next;
+						}
+					}
+				}
+			}
+			if (ambiguous != null)
+				return ambiguous;
+		}
+		if (visibleMemberType != null)
+			return visibleMemberType;
+		if (notVisible != null)
+			return new ProblemReferenceBinding(new char[][]{typeName}, notVisible, ProblemReasons.NotVisible);
+		return null;
+	}
+
+	// Internal use only - use findMethod()
+	public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+		return findMethod(receiverType, selector, argumentTypes, invocationSite, false);
+	}
+
+	// Internal use only - use findMethod()
+	public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite, boolean inStaticContext) {
+		ReferenceBinding currentType = receiverType;
+		boolean receiverTypeIsInterface = receiverType.isInterface();
+		ObjectVector found = new ObjectVector(3);
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordTypeReferences(argumentTypes);
+
+		if (receiverTypeIsInterface) {
+			unitScope.recordTypeReference(receiverType);
+			MethodBinding[] receiverMethods = receiverType.getMethods(selector, argumentTypes.length);
+			if (receiverMethods.length > 0)
+				found.addAll(receiverMethods);
+			findMethodInSuperInterfaces(receiverType, selector, found, invocationSite);
+			currentType = getJavaLangObject();
+		}
+
+		// superclass lookup
+		long complianceLevel = compilerOptions().complianceLevel;
+		boolean isCompliant14 = complianceLevel >= ClassFileConstants.JDK1_4;
+		boolean isCompliant15 = complianceLevel >= ClassFileConstants.JDK1_5;
+		ReferenceBinding classHierarchyStart = currentType;
+		MethodVerifier verifier = environment().methodVerifier();
+		while (currentType != null) {
+			unitScope.recordTypeReference(currentType);
+			currentType = (ReferenceBinding) currentType.capture(this, invocationSite == null ? 0 : invocationSite.sourceEnd());
+			MethodBinding[] currentMethods = currentType.getMethods(selector, argumentTypes.length);
+			int currentLength = currentMethods.length;
+			if (currentLength > 0) {
+				if (isCompliant14 && (receiverTypeIsInterface || found.size > 0)) {
+					nextMethod: for (int i = 0, l = currentLength; i < l; i++) { // currentLength can be modified inside the loop
+						MethodBinding currentMethod = currentMethods[i];
+						if (currentMethod == null) continue nextMethod;
+						if (receiverTypeIsInterface && !currentMethod.isPublic()) { // only public methods from Object are visible to interface receiverTypes
+							currentLength--;
+							currentMethods[i] = null;
+							continue nextMethod;
+						}
+
+						// if 1.4 compliant, must filter out redundant protected methods from superclasses
+						// protected method need to be checked only - default access is already dealt with in #canBeSeen implementation
+						// when checking that p.C -> q.B -> p.A cannot see default access members from A through B.
+						// if ((currentMethod.modifiers & AccProtected) == 0) continue nextMethod;
+						// BUT we can also ignore any overridden method since we already know the better match (fixes 80028)
+						for (int j = 0, max = found.size; j < max; j++) {
+							MethodBinding matchingMethod = (MethodBinding) found.elementAt(j);
+							MethodBinding matchingOriginal = matchingMethod.original();
+							MethodBinding currentOriginal = matchingOriginal.findOriginalInheritedMethod(currentMethod);
+							if (currentOriginal != null && verifier.isParameterSubsignature(matchingOriginal, currentOriginal)) {
+								if (isCompliant15) {
+									if (matchingMethod.isBridge() && !currentMethod.isBridge())
+										continue nextMethod; // keep inherited methods to find concrete method over a bridge method
+								}
+								currentLength--;
+								currentMethods[i] = null;
+								continue nextMethod;
+							}
+						}
+					}
+				}
+
+				if (currentLength > 0) {
+					// append currentMethods, filtering out null entries
+					if (currentMethods.length == currentLength) {
+						found.addAll(currentMethods);
+					} else {
+						for (int i = 0, max = currentMethods.length; i < max; i++) {
+							MethodBinding currentMethod = currentMethods[i];
+							if (currentMethod != null)
+								found.add(currentMethod);
+						}
+					}
+				}
+			}
+			currentType = currentType.superclass();
+		}
+
+		// if found several candidates, then eliminate those not matching argument types
+		int foundSize = found.size;
+		MethodBinding[] candidates = null;
+		int candidatesCount = 0;
+		MethodBinding problemMethod = null;
+		boolean searchForDefaultAbstractMethod = isCompliant14 && ! receiverTypeIsInterface && (receiverType.isAbstract() || receiverType.isTypeVariable());
+		if (foundSize > 0) {
+			// argument type compatibility check
+			for (int i = 0; i < foundSize; i++) {
+				MethodBinding methodBinding = (MethodBinding) found.elementAt(i);
+				MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
+				if (compatibleMethod != null) {
+					if (compatibleMethod.isValidBinding()) {
+						if (foundSize == 1 && compatibleMethod.canBeSeenBy(receiverType, invocationSite, this)) {
+							// return the single visible match now
+							if (searchForDefaultAbstractMethod)
+								return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, compatibleMethod);
+							unitScope.recordTypeReferences(compatibleMethod.thrownExceptions);
+							return compatibleMethod;
+						}
+						if (candidatesCount == 0)
+							candidates = new MethodBinding[foundSize];
+						candidates[candidatesCount++] = compatibleMethod;
+					} else if (problemMethod == null) {
+						problemMethod = compatibleMethod;
+					}
+				}
+			}
+		}
+
+		// no match was found
+		if (candidatesCount == 0) {
+			if (problemMethod != null) {
+				switch (problemMethod.problemId()) {
+					case ProblemReasons.TypeArgumentsForRawGenericMethod :
+					case ProblemReasons.TypeParameterArityMismatch :
+						return problemMethod;
+				}
+			}
+			// abstract classes may get a match in interfaces; for non abstract
+			// classes, reduces secondary errors since missing interface method
+			// error is already reported
+			MethodBinding interfaceMethod =
+				findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null);
+			if (interfaceMethod != null) return interfaceMethod;
+			if (found.size == 0) return null;
+			if (problemMethod != null) return problemMethod;
+
+			// still no match; try to find a close match when the parameter
+			// order is wrong or missing some parameters
+
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=69471
+			// bad guesses are foo(), when argument types have been supplied
+			// and foo(X, Y), when the argument types are (int, float, Y)
+			// so answer the method with the most argType matches and least parameter type mismatches
+			int bestArgMatches = -1;
+			MethodBinding bestGuess = (MethodBinding) found.elementAt(0); // if no good match so just use the first one found
+			int argLength = argumentTypes.length;
+			foundSize = found.size;
+			nextMethod : for (int i = 0; i < foundSize; i++) {
+				MethodBinding methodBinding = (MethodBinding) found.elementAt(i);
+				TypeBinding[] params = methodBinding.parameters;
+				int paramLength = params.length;
+				int argMatches = 0;
+				next: for (int a = 0; a < argLength; a++) {
+					TypeBinding arg = argumentTypes[a];
+					for (int p = a == 0 ? 0 : a - 1; p < paramLength && p < a + 1; p++) { // look one slot before & after to see if the type matches
+						if (params[p] == arg) {
+							argMatches++;
+							continue next;
+						}
+					}
+				}
+				if (argMatches < bestArgMatches)
+					continue nextMethod;
+				if (argMatches == bestArgMatches) {
+					int diff1 = paramLength < argLength ? 2 * (argLength - paramLength) : paramLength - argLength;
+					int bestLength = bestGuess.parameters.length;
+					int diff2 = bestLength < argLength ? 2 * (argLength - bestLength) : bestLength - argLength;
+					if (diff1 >= diff2)
+						continue nextMethod;
+				}
+				bestArgMatches = argMatches;
+				bestGuess = methodBinding;
+			}
+			return new ProblemMethodBinding(bestGuess, bestGuess.selector, argumentTypes, ProblemReasons.NotFound);
+		}
+
+		// tiebreak using visibility check
+		int visiblesCount = 0;
+		for (int i = 0; i < candidatesCount; i++) {
+			MethodBinding methodBinding = candidates[i];
+			if (methodBinding.canBeSeenBy(receiverType, invocationSite, this)) {
+				if (visiblesCount != i) {
+					candidates[i] = null;
+					candidates[visiblesCount] = methodBinding;
+				}
+				visiblesCount++;
+			}
+		}
+		switch (visiblesCount) {
+			case 0 :
+				MethodBinding interfaceMethod =
+				findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null);
+				if (interfaceMethod != null) return interfaceMethod;
+				MethodBinding candidate = candidates[0];
+				return new ProblemMethodBinding(candidates[0], candidates[0].selector, candidates[0].parameters, 
+						candidate.isStatic() && candidate.declaringClass.isInterface() ? ProblemReasons.NonStaticOrAlienTypeReceiver : ProblemReasons.NotVisible);
+			case 1 :
+				if (searchForDefaultAbstractMethod)
+					return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, candidates[0]);
+				unitScope.recordTypeReferences(candidates[0].thrownExceptions);
+				return candidates[0];
+			default :
+				break;
+		}
+
+		if (complianceLevel <= ClassFileConstants.JDK1_3) {
+			ReferenceBinding declaringClass = candidates[0].declaringClass;
+			return !declaringClass.isInterface()
+				? mostSpecificClassMethodBinding(candidates, visiblesCount, invocationSite)
+				: mostSpecificInterfaceMethodBinding(candidates, visiblesCount, invocationSite);
+		}
+
+		// check for duplicate parameterized methods
+		if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+			for (int i = 0; i < visiblesCount; i++) {
+				MethodBinding candidate = candidates[i];
+				if (candidate instanceof ParameterizedGenericMethodBinding)
+					candidate = ((ParameterizedGenericMethodBinding) candidate).originalMethod;
+				if (candidate.hasSubstitutedParameters()) {
+					for (int j = i + 1; j < visiblesCount; j++) {
+						MethodBinding otherCandidate = candidates[j];
+						if (otherCandidate.hasSubstitutedParameters()) {
+							if (otherCandidate == candidate
+									|| (candidate.declaringClass == otherCandidate.declaringClass && candidate.areParametersEqual(otherCandidate))) {
+								return new ProblemMethodBinding(candidates[i], candidates[i].selector, candidates[i].parameters, ProblemReasons.Ambiguous);
+							}
+						}
+					}
+				}
+			}
+		}
+		if (inStaticContext) {
+			MethodBinding[] staticCandidates = new MethodBinding[visiblesCount];
+			int staticCount = 0;
+			for (int i = 0; i < visiblesCount; i++)
+				if (candidates[i].isStatic())
+					staticCandidates[staticCount++] = candidates[i];
+			if (staticCount == 1)
+				return staticCandidates[0];
+			if (staticCount > 1)
+				return mostSpecificMethodBinding(staticCandidates, staticCount, argumentTypes, invocationSite, receiverType);
+		}
+
+		MethodBinding mostSpecificMethod = mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite, receiverType);
+		if (searchForDefaultAbstractMethod) { // search interfaces for a better match
+			if (mostSpecificMethod.isValidBinding())
+				// see if there is a better match in the interfaces - see AutoBoxingTest 99, LookupTest#81
+				return findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, mostSpecificMethod);
+			// see if there is a match in the interfaces - see LookupTest#84
+			MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, found, null);
+			if (interfaceMethod != null && interfaceMethod.isValidBinding() /* else return the same error as before */)
+				return interfaceMethod;
+		}
+		return mostSpecificMethod;
+	}
+
+	// Internal use only
+	public MethodBinding findMethodForArray(
+		ArrayBinding receiverType,
+		char[] selector,
+		TypeBinding[] argumentTypes,
+		InvocationSite invocationSite) {
+
+		TypeBinding leafType = receiverType.leafComponentType();
+		if (leafType instanceof ReferenceBinding) {
+			if (!((ReferenceBinding) leafType).canBeSeenBy(this))
+				return new ProblemMethodBinding(selector, Binding.NO_PARAMETERS, (ReferenceBinding)leafType, ProblemReasons.ReceiverTypeNotVisible);
+		}
+
+		ReferenceBinding object = getJavaLangObject();
+		MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null);
+		if (methodBinding != null) {
+			// handle the method clone() specially... cannot be protected or throw exceptions
+			if (argumentTypes == Binding.NO_PARAMETERS) {
+			    switch (selector[0]) {
+			        case 'c':
+			            if (CharOperation.equals(selector, TypeConstants.CLONE)) {
+			            	return environment().computeArrayClone(methodBinding);
+			            }
+			            break;
+			        case 'g':
+			            if (CharOperation.equals(selector, TypeConstants.GETCLASS) && methodBinding.returnType.isParameterizedType()/*1.5*/) {
+							return environment().createGetClassMethod(receiverType, methodBinding, this);
+			            }
+			            break;
+			    }
+			}
+			if (methodBinding.canBeSeenBy(receiverType, invocationSite, this))
+				return methodBinding;
+		}
+		methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+		if (methodBinding == null)
+			return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+		return methodBinding;
+	}
+
+	protected void findMethodInSuperInterfaces(ReferenceBinding receiverType, char[] selector, ObjectVector found, InvocationSite invocationSite) {
+		ReferenceBinding currentType = receiverType;
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+			for (int i = 0; i < nextPosition; i++) {
+				currentType = interfacesToVisit[i];
+				compilationUnitScope().recordTypeReference(currentType);
+				currentType = (ReferenceBinding) currentType.capture(this, invocationSite == null ? 0 : invocationSite.sourceEnd());
+				MethodBinding[] currentMethods = currentType.getMethods(selector);
+				if (currentMethods.length > 0) {
+					int foundSize = found.size;
+					next : for (int c = 0, l = currentMethods.length; c < l; c++) {
+						MethodBinding current = currentMethods[c];
+						if (!current.canBeSeenBy(receiverType, invocationSite, this)) continue next;
+
+						if (foundSize > 0) {
+							// its possible to walk the same superinterface from different classes in the hierarchy
+							for (int f = 0; f < foundSize; f++)
+								if (current == found.elementAt(f)) continue next;
+						}
+						found.add(current);
+					}
+				}
+				if ((itsInterfaces = currentType.superInterfaces()) != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		}
+	}
+
+	// Internal use only
+	public ReferenceBinding findType(
+		char[] typeName,
+		PackageBinding declarationPackage,
+		PackageBinding invocationPackage) {
+
+		compilationUnitScope().recordReference(declarationPackage.compoundName, typeName);
+		ReferenceBinding typeBinding = declarationPackage.getType(typeName);
+		if (typeBinding == null)
+			return null;
+
+		if (typeBinding.isValidBinding()) {
+			if (declarationPackage != invocationPackage && !typeBinding.canBeSeenBy(invocationPackage))
+				return new ProblemReferenceBinding(new char[][]{typeName}, typeBinding, ProblemReasons.NotVisible);
+		}
+		return typeBinding;
+	}
+
+	public LocalVariableBinding findVariable(char[] variable) {
+
+		return null;
+	}
+
+	/* API
+	 *
+	 *	Answer the binding that corresponds to the argument name.
+	 *	flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE, PACKAGE.
+	 *	Only bindings corresponding to the mask can be answered.
+	 *
+	 *	For example, getBinding("foo", VARIABLE, site) will answer
+	 *	the binding for the field or local named "foo" (or an error binding if none exists).
+	 *	If a type named "foo" exists, it will not be detected (and an error binding will be answered)
+	 *
+	 *	The VARIABLE mask has precedence over the TYPE mask.
+	 *
+	 *	If the VARIABLE mask is not set, neither fields nor locals will be looked for.
+	 *
+	 *	InvocationSite implements:
+	 *		isSuperAccess(); this is used to determine if the discovered field is visible.
+	 *
+	 *	Limitations: cannot request FIELD independently of LOCAL, or vice versa
+	 */
+	public Binding getBinding(char[] name, int mask, InvocationSite invocationSite, boolean needResolve) {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		LookupEnvironment env = unitScope.environment;
+		try {
+			env.missingClassFileLocation = invocationSite;
+			Binding binding = null;
+			FieldBinding problemField = null;
+			if ((mask & Binding.VARIABLE) != 0) {
+				boolean insideStaticContext = false;
+				boolean insideConstructorCall = false;
+				boolean insideTypeAnnotation = false;
+
+				FieldBinding foundField = null;
+				// can be a problem field which is answered if a valid field is not found
+				ProblemFieldBinding foundInsideProblem = null;
+				// inside Constructor call or inside static context
+				Scope scope = this;
+				MethodScope methodScope = null;
+				int depth = 0;
+				int foundDepth = 0;
+				boolean shouldTrackOuterLocals = false;
+				ReferenceBinding foundActualReceiverType = null;
+				done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+					switch (scope.kind) {
+						case METHOD_SCOPE :
+							methodScope = (MethodScope) scope;
+							insideStaticContext |= methodScope.isStatic;
+							insideConstructorCall |= methodScope.isConstructorCall;
+							insideTypeAnnotation = methodScope.insideTypeAnnotation;
+
+							//$FALL-THROUGH$ could duplicate the code below to save a cast - questionable optimization
+						case BLOCK_SCOPE :
+							LocalVariableBinding variableBinding = scope.findVariable(name);
+							// looks in this scope only
+							if (variableBinding != null) {
+								if (foundField != null && foundField.isValidBinding())
+									return new ProblemFieldBinding(
+										foundField, // closest match
+										foundField.declaringClass,
+										name,
+										ProblemReasons.InheritedNameHidesEnclosingName);
+								if (depth > 0)
+									invocationSite.setDepth(depth);
+								if (shouldTrackOuterLocals) {
+									if (invocationSite instanceof NameReference) {
+										NameReference nameReference = (NameReference) invocationSite;
+										nameReference.bits |= ASTNode.IsCapturedOuterLocal;
+									} else if (invocationSite instanceof AbstractVariableDeclaration) {
+										AbstractVariableDeclaration variableDeclaration = (AbstractVariableDeclaration) invocationSite;
+										variableDeclaration.bits |= ASTNode.ShadowsOuterLocal;
+									}
+								}
+								return variableBinding;
+							}
+							break;
+						case CLASS_SCOPE :
+							ClassScope classScope = (ClassScope) scope;
+							ReferenceBinding receiverType = classScope.enclosingReceiverType();
+							if (!insideTypeAnnotation) {
+								FieldBinding fieldBinding = classScope.findField(receiverType, name, invocationSite, needResolve);
+								// Use next line instead if willing to enable protected access accross inner types
+								// FieldBinding fieldBinding = findField(enclosingType, name, invocationSite);
+
+								if (fieldBinding != null) { // skip it if we did not find anything
+									if (fieldBinding.problemId() == ProblemReasons.Ambiguous) {
+										if (foundField == null || foundField.problemId() == ProblemReasons.NotVisible)
+											// supercedes any potential InheritedNameHidesEnclosingName problem
+											return fieldBinding;
+										// make the user qualify the field, likely wants the first inherited field (javac generates an ambiguous error instead)
+										return new ProblemFieldBinding(
+											foundField, // closest match
+											foundField.declaringClass,
+											name,
+											ProblemReasons.InheritedNameHidesEnclosingName);
+									}
+
+									ProblemFieldBinding insideProblem = null;
+									if (fieldBinding.isValidBinding()) {
+										if (!fieldBinding.isStatic()) {
+											if (insideConstructorCall) {
+												insideProblem =
+													new ProblemFieldBinding(
+														fieldBinding, // closest match
+														fieldBinding.declaringClass,
+														name,
+														ProblemReasons.NonStaticReferenceInConstructorInvocation);
+											} else if (insideStaticContext) {
+												insideProblem =
+													new ProblemFieldBinding(
+														fieldBinding, // closest match
+														fieldBinding.declaringClass,
+														name,
+														ProblemReasons.NonStaticReferenceInStaticContext);
+											}
+										}
+										if (receiverType == fieldBinding.declaringClass || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
+											// found a valid field in the 'immediate' scope (i.e. not inherited)
+											// OR in 1.4 mode (inherited shadows enclosing)
+											if (foundField == null) {
+												if (depth > 0){
+													invocationSite.setDepth(depth);
+													invocationSite.setActualReceiverType(receiverType);
+												}
+												// return the fieldBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
+												return insideProblem == null ? fieldBinding : insideProblem;
+											}
+											if (foundField.isValidBinding())
+												// if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
+												// but only if "valid field" was inherited in the first place.
+												if (foundField.declaringClass != fieldBinding.declaringClass &&
+												    foundField.declaringClass != foundActualReceiverType) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316956
+													// i.e. have we found the same field - do not trust field identity yet
+													return new ProblemFieldBinding(
+														foundField, // closest match
+														foundField.declaringClass,
+														name,
+														ProblemReasons.InheritedNameHidesEnclosingName);
+										}
+									}
+
+									if (foundField == null || (foundField.problemId() == ProblemReasons.NotVisible && fieldBinding.problemId() != ProblemReasons.NotVisible)) {
+										// only remember the fieldBinding if its the first one found or the previous one was not visible & fieldBinding is...
+										foundDepth = depth;
+										foundActualReceiverType = receiverType;
+										foundInsideProblem = insideProblem;
+										foundField = fieldBinding;
+									}
+								}
+							}
+							insideTypeAnnotation = false;
+							depth++;
+							shouldTrackOuterLocals = true;
+							insideStaticContext |= receiverType.isStatic();
+							// 1EX5I8Z - accessing outer fields within a constructor call is permitted
+							// in order to do so, we change the flag as we exit from the type, not the method
+							// itself, because the class scope is used to retrieve the fields.
+							MethodScope enclosingMethodScope = scope.methodScope();
+							insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
+							break;
+						case COMPILATION_UNIT_SCOPE :
+							break done;
+					}
+					if (scope.isLambdaScope()) // Not in Kansas anymore ...
+						shouldTrackOuterLocals = true;
+					scope = scope.parent;
+				}
+
+				if (foundInsideProblem != null)
+					return foundInsideProblem;
+				if (foundField != null) {
+					if (foundField.isValidBinding()) {
+						if (foundDepth > 0) {
+							invocationSite.setDepth(foundDepth);
+							invocationSite.setActualReceiverType(foundActualReceiverType);
+						}
+						return foundField;
+					}
+					problemField = foundField;
+					foundField = null;
+				}
+
+				if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+					// at this point the scope is a compilation unit scope & need to check for imported static fields
+					unitScope.faultInImports(); // ensure static imports are resolved
+					ImportBinding[] imports = unitScope.imports;
+					if (imports != null) {
+						// check single static imports
+						for (int i = 0, length = imports.length; i < length; i++) {
+							ImportBinding importBinding = imports[i];
+							if (importBinding.isStatic() && !importBinding.onDemand) {
+								if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
+									if (unitScope.resolveSingleImport(importBinding, Binding.TYPE | Binding.FIELD | Binding.METHOD) != null && importBinding.resolvedImport instanceof FieldBinding) {
+										foundField = (FieldBinding) importBinding.resolvedImport;
+										ImportReference importReference = importBinding.reference;
+										if (importReference != null && needResolve) {
+											importReference.bits |= ASTNode.Used;
+										}
+										invocationSite.setActualReceiverType(foundField.declaringClass);
+										if (foundField.isValidBinding()) {
+											return foundField;
+										}
+										if (problemField == null)
+											problemField = foundField;
+									}
+								}
+							}
+						}
+						// check on demand imports
+						boolean foundInImport = false;
+						for (int i = 0, length = imports.length; i < length; i++) {
+							ImportBinding importBinding = imports[i];
+							if (importBinding.isStatic() && importBinding.onDemand) {
+								Binding resolvedImport = importBinding.resolvedImport;
+								if (resolvedImport instanceof ReferenceBinding) {
+									FieldBinding temp = findField((ReferenceBinding) resolvedImport, name, invocationSite, needResolve);
+									if (temp != null) {
+										if (!temp.isValidBinding()) {
+											if (problemField == null)
+												problemField = temp;
+										} else if (temp.isStatic()) {
+											if (foundField == temp) continue;
+											ImportReference importReference = importBinding.reference;
+											if (importReference != null && needResolve) {
+												importReference.bits |= ASTNode.Used;
+											}
+											if (foundInImport)
+												// Answer error binding -- import on demand conflict; name found in two import on demand packages.
+												return new ProblemFieldBinding(
+														foundField, // closest match
+														foundField.declaringClass,
+														name,
+														ProblemReasons.Ambiguous);
+											foundField = temp;
+											foundInImport = true;
+										}
+									}
+								}
+							}
+						}
+						if (foundField != null) {
+							invocationSite.setActualReceiverType(foundField.declaringClass);
+							return foundField;
+						}
+					}
+				}
+			}
+
+			// We did not find a local or instance variable.
+			if ((mask & Binding.TYPE) != 0) {
+				if ((binding = getBaseType(name)) != null)
+					return binding;
+				binding = getTypeOrPackage(name, (mask & Binding.PACKAGE) == 0 ? Binding.TYPE : Binding.TYPE | Binding.PACKAGE, needResolve);
+				if (binding.isValidBinding() || mask == Binding.TYPE)
+					return binding;
+				// answer the problem type binding if we are only looking for a type
+			} else if ((mask & Binding.PACKAGE) != 0) {
+				unitScope.recordSimpleReference(name);
+				if ((binding = env.getTopLevelPackage(name)) != null)
+					return binding;
+			}
+			if (problemField != null) return problemField;
+			if (binding != null && binding.problemId() != ProblemReasons.NotFound)
+				return binding; // answer the better problem binding
+			return new ProblemBinding(name, enclosingSourceType(), ProblemReasons.NotFound);
+		} catch (AbortCompilation e) {
+			e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		LookupEnvironment env = unitScope.environment;
+		try {
+			env.missingClassFileLocation = invocationSite;
+			unitScope.recordTypeReference(receiverType);
+			unitScope.recordTypeReferences(argumentTypes);
+			MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes);
+			if (methodBinding != null && methodBinding.canBeSeenBy(invocationSite, this)) {
+			    // targeting a non generic constructor with type arguments ?
+			    if (invocationSite.genericTypeArguments() != null)
+			    	methodBinding = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
+				return methodBinding;
+			}
+			MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT, argumentTypes.length);
+			if (methods == Binding.NO_METHODS)
+				return new ProblemMethodBinding(
+					TypeConstants.INIT,
+					argumentTypes,
+					ProblemReasons.NotFound);
+
+			MethodBinding[] compatible = new MethodBinding[methods.length];
+			int compatibleIndex = 0;
+			MethodBinding problemMethod = null;
+			for (int i = 0, length = methods.length; i < length; i++) {
+				MethodBinding compatibleMethod = computeCompatibleMethod(methods[i], argumentTypes, invocationSite);
+				if (compatibleMethod != null) {
+					if (compatibleMethod.isValidBinding())
+						compatible[compatibleIndex++] = compatibleMethod;
+					else if (problemMethod == null)
+						problemMethod = compatibleMethod;
+				}
+			}
+			if (compatibleIndex == 0) {
+				if (problemMethod == null)
+					return new ProblemMethodBinding(methods[0], TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound);
+				return problemMethod;
+			}
+			// need a more descriptive error... cannot convert from X to Y
+
+			MethodBinding[] visible = new MethodBinding[compatibleIndex];
+			int visibleIndex = 0;
+			for (int i = 0; i < compatibleIndex; i++) {
+				MethodBinding method = compatible[i];
+				if (method.canBeSeenBy(invocationSite, this))
+					visible[visibleIndex++] = method;
+			}
+			if (visibleIndex == 1) return visible[0];
+			if (visibleIndex == 0)
+				return new ProblemMethodBinding(
+					compatible[0],
+					TypeConstants.INIT,
+					compatible[0].parameters,
+					ProblemReasons.NotVisible);
+			// all of visible are from the same declaringClass, even before 1.4 we can call this method instead of mostSpecificClassMethodBinding
+			return mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, invocationSite, receiverType);
+		} catch (AbortCompilation e) {
+			e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	public final PackageBinding getCurrentPackage() {
+		Scope scope, unitScope = this;
+		while ((scope = unitScope.parent) != null)
+			unitScope = scope;
+		return ((CompilationUnitScope) unitScope).fPackage;
+	}
+
+	/**
+	 * Returns the modifiers of the innermost enclosing declaration.
+	 * @return modifiers
+	 */
+	public int getDeclarationModifiers(){
+		switch(this.kind){
+			case Scope.BLOCK_SCOPE :
+			case Scope.METHOD_SCOPE :
+				MethodScope methodScope = methodScope();
+				if (!methodScope.isInsideInitializer()){
+					// check method modifiers to see if deprecated
+					MethodBinding context = ((AbstractMethodDeclaration)methodScope.referenceContext).binding;
+					if (context != null)
+						return context.modifiers;
+				} else {
+					SourceTypeBinding type = ((BlockScope) this).referenceType().binding;
+
+					// inside field declaration ? check field modifier to see if deprecated
+					if (methodScope.initializedField != null)
+						return methodScope.initializedField.modifiers;
+					if (type != null)
+						return type.modifiers;
+				}
+				break;
+			case Scope.CLASS_SCOPE :
+				ReferenceBinding context = ((ClassScope)this).referenceType().binding;
+				if (context != null)
+					return context.modifiers;
+				break;
+		}
+		return -1;
+	}
+
+	public FieldBinding getField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) {
+		LookupEnvironment env = environment();
+		try {
+			env.missingClassFileLocation = invocationSite;
+			FieldBinding field = findField(receiverType, fieldName, invocationSite, true /*resolve*/);
+			if (field != null) return field;
+
+			return new ProblemFieldBinding(
+				receiverType instanceof ReferenceBinding ? (ReferenceBinding) receiverType : null,
+				fieldName,
+				ProblemReasons.NotFound);
+		} catch (AbortCompilation e) {
+			e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	/* API
+	 *
+	 *	Answer the method binding that corresponds to selector, argumentTypes.
+	 *	Start the lookup at the enclosing type of the receiver.
+	 *	InvocationSite implements
+	 *		isSuperAccess(); this is used to determine if the discovered method is visible.
+	 *		setDepth(int); this is used to record the depth of the discovered method
+	 *			relative to the enclosing type of the receiver. (If the method is defined
+	 *			in the enclosing type of the receiver, the depth is 0; in the next enclosing
+	 *			type, the depth is 1; and so on
+	 *
+	 *	If no visible method is discovered, an error binding is answered.
+	 */
+	public MethodBinding getImplicitMethod(char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+
+		boolean insideStaticContext = false;
+		boolean insideConstructorCall = false;
+		boolean insideTypeAnnotation = false;
+		MethodBinding foundMethod = null;
+		MethodBinding foundProblem = null;
+		boolean foundProblemVisible = false;
+		Scope scope = this;
+		MethodScope methodScope = null;
+		int depth = 0;
+		// in 1.4 mode (inherited visible shadows enclosing)
+		CompilerOptions options;
+		boolean inheritedHasPrecedence = (options = compilerOptions()).complianceLevel >= ClassFileConstants.JDK1_4;
+
+		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+			switch (scope.kind) {
+				case METHOD_SCOPE :
+					methodScope = (MethodScope) scope;
+					insideStaticContext |= methodScope.isStatic;
+					insideConstructorCall |= methodScope.isConstructorCall;
+					insideTypeAnnotation = methodScope.insideTypeAnnotation;
+					break;
+				case CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) scope;
+					ReferenceBinding receiverType = classScope.enclosingReceiverType();
+					if (!insideTypeAnnotation) {
+						// retrieve an exact visible match (if possible)
+						// compilationUnitScope().recordTypeReference(receiverType);   not needed since receiver is the source type
+						MethodBinding methodBinding = classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite);
+						if (methodBinding == null)
+							methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite);
+						if (methodBinding != null) { // skip it if we did not find anything
+							if (foundMethod == null) {
+								if (methodBinding.isValidBinding()) {
+									if (!methodBinding.isStatic() && (insideConstructorCall || insideStaticContext)) {
+										if (foundProblem != null && foundProblem.problemId() != ProblemReasons.NotVisible)
+											return foundProblem; // takes precedence
+										return new ProblemMethodBinding(
+											methodBinding, // closest match
+											methodBinding.selector,
+											methodBinding.parameters,
+											insideConstructorCall
+												? ProblemReasons.NonStaticReferenceInConstructorInvocation
+												: ProblemReasons.NonStaticReferenceInStaticContext);
+									} else if (!methodBinding.isStatic() && methodScope != null) {
+										tagAsAccessingEnclosingInstanceStateOf(receiverType, false /* type variable access */);
+									}
+									if (inheritedHasPrecedence
+											|| receiverType == methodBinding.declaringClass
+											|| (receiverType.getMethods(selector)) != Binding.NO_METHODS) {
+										// found a valid method in the 'immediate' scope (i.e. not inherited)
+										// OR in 1.4 mode (inherited visible shadows enclosing)
+										// OR the receiverType implemented a method with the correct name
+										// return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
+										if (foundProblemVisible) {
+											return foundProblem;
+										}
+										if (depth > 0) {
+											invocationSite.setDepth(depth);
+											invocationSite.setActualReceiverType(receiverType);
+										}
+										// special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
+										if (argumentTypes == Binding.NO_PARAMETERS
+										    && CharOperation.equals(selector, TypeConstants.GETCLASS)
+										    && methodBinding.returnType.isParameterizedType()/*1.5*/) {
+												return environment().createGetClassMethod(receiverType, methodBinding, this);
+										}
+										return methodBinding;
+									}
+
+									if (foundProblem == null || foundProblem.problemId() == ProblemReasons.NotVisible) {
+										if (foundProblem != null) foundProblem = null;
+										// only remember the methodBinding if its the first one found
+										// remember that private methods are visible if defined directly by an enclosing class
+										if (depth > 0) {
+											invocationSite.setDepth(depth);
+											invocationSite.setActualReceiverType(receiverType);
+										}
+										foundMethod = methodBinding;
+									}
+								} else { // methodBinding is a problem method
+									if (methodBinding.problemId() != ProblemReasons.NotVisible && methodBinding.problemId() != ProblemReasons.NotFound)
+										return methodBinding; // return the error now
+									if (foundProblem == null) {
+										foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible
+									}
+									if (! foundProblemVisible && methodBinding.problemId() == ProblemReasons.NotFound) {
+										MethodBinding closestMatch = ((ProblemMethodBinding) methodBinding).closestMatch;
+										if (closestMatch != null && closestMatch.canBeSeenBy(receiverType, invocationSite, this)) {
+											foundProblem = methodBinding; // hold onto the first not visible/found error and keep the second not found if first is not visible
+											foundProblemVisible = true;
+										}
+									}
+								}
+							} else { // found a valid method so check to see if this is a hiding case
+								if (methodBinding.problemId() == ProblemReasons.Ambiguous
+									|| (foundMethod.declaringClass != methodBinding.declaringClass
+										&& (receiverType == methodBinding.declaringClass || receiverType.getMethods(selector) != Binding.NO_METHODS)))
+									// ambiguous case -> must qualify the method (javac generates an ambiguous error instead)
+									// otherwise if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
+									// NOTE: Unlike fields, a non visible method hides a visible method
+									return new ProblemMethodBinding(
+										methodBinding, // closest match
+										selector,
+										argumentTypes,
+										ProblemReasons.InheritedNameHidesEnclosingName);
+							}
+						}
+					}
+					insideTypeAnnotation = false;
+					depth++;
+					insideStaticContext |= receiverType.isStatic();
+					// 1EX5I8Z - accessing outer fields within a constructor call is permitted
+					// in order to do so, we change the flag as we exit from the type, not the method
+					// itself, because the class scope is used to retrieve the fields.
+					MethodScope enclosingMethodScope = scope.methodScope();
+					insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
+					break;
+				case COMPILATION_UNIT_SCOPE :
+					break done;
+			}
+			scope = scope.parent;
+		}
+
+		if (insideStaticContext && options.sourceLevel >= ClassFileConstants.JDK1_5) {
+			if (foundProblem != null) {
+				if (foundProblem.declaringClass != null && foundProblem.declaringClass.id == TypeIds.T_JavaLangObject)
+					return foundProblem; // static imports lose to methods from Object
+				if (foundProblem.problemId() == ProblemReasons.NotFound && foundProblemVisible) {
+					return foundProblem; // visible method selectors take precedence
+				}
+			}
+
+			// at this point the scope is a compilation unit scope & need to check for imported static methods
+			CompilationUnitScope unitScope = (CompilationUnitScope) scope;
+			unitScope.faultInImports(); // field constants can cause static imports to be accessed before they're resolved
+			ImportBinding[] imports = unitScope.imports;
+			if (imports != null) {
+				ObjectVector visible = null;
+				boolean skipOnDemand = false; // set to true when matched static import of method name so stop looking for on demand methods
+				for (int i = 0, length = imports.length; i < length; i++) {
+					ImportBinding importBinding = imports[i];
+					if (importBinding.isStatic()) {
+						Binding resolvedImport = importBinding.resolvedImport;
+						MethodBinding possible = null;
+						if (importBinding.onDemand) {
+							if (!skipOnDemand && resolvedImport instanceof ReferenceBinding)
+								// answers closest approximation, may not check argumentTypes or visibility
+								possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite, true);
+						} else {
+							if (resolvedImport instanceof MethodBinding) {
+								MethodBinding staticMethod = (MethodBinding) resolvedImport;
+								if (CharOperation.equals(staticMethod.selector, selector))
+									// answers closest approximation, may not check argumentTypes or visibility
+									possible = findMethod(staticMethod.declaringClass, selector, argumentTypes, invocationSite, true);
+							} else if (resolvedImport instanceof FieldBinding) {
+								// check to see if there are also methods with the same name
+								FieldBinding staticField = (FieldBinding) resolvedImport;
+								if (CharOperation.equals(staticField.name, selector)) {
+									// must find the importRef's type again since the field can be from an inherited type
+									char[][] importName = importBinding.reference.tokens;
+									TypeBinding referencedType = getType(importName, importName.length - 1);
+									if (referencedType != null)
+										// answers closest approximation, may not check argumentTypes or visibility
+										possible = findMethod((ReferenceBinding) referencedType, selector, argumentTypes, invocationSite, true);
+								}
+							}
+						}
+						if (possible != null && possible != foundProblem) {
+							if (!possible.isValidBinding()) {
+								if (foundProblem == null)
+									foundProblem = possible; // answer as error case match
+							} else if (possible.isStatic()) {
+								MethodBinding compatibleMethod = computeCompatibleMethod(possible, argumentTypes, invocationSite);
+								if (compatibleMethod != null) {
+									if (compatibleMethod.isValidBinding()) {
+										if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) {
+											if (visible == null || !visible.contains(compatibleMethod)) {
+												ImportReference importReference = importBinding.reference;
+												if (importReference != null) {
+													importReference.bits |= ASTNode.Used;
+												}
+												if (!skipOnDemand && !importBinding.onDemand) {
+													visible = null; // forget previous matches from on demand imports
+													skipOnDemand = true;
+												}
+												if (visible == null)
+													visible = new ObjectVector(3);
+												visible.add(compatibleMethod);
+											}
+										} else if (foundProblem == null) {
+											foundProblem = new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, ProblemReasons.NotVisible);
+										}
+									} else if (foundProblem == null) {
+										foundProblem = compatibleMethod;
+									}
+								} else if (foundProblem == null) {
+									foundProblem = new ProblemMethodBinding(possible, selector, argumentTypes, ProblemReasons.NotFound);
+								}
+							}
+						}
+					}
+				}
+				if (visible != null) {
+					MethodBinding[] temp = new MethodBinding[visible.size];
+					visible.copyInto(temp);
+					foundMethod = mostSpecificMethodBinding(temp, temp.length, argumentTypes, invocationSite, null);
+				}
+			}
+		}
+
+		if (foundMethod != null) {
+			invocationSite.setActualReceiverType(foundMethod.declaringClass);
+			return foundMethod;
+		}
+		if (foundProblem != null)
+			return foundProblem;
+
+		return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+	}
+
+	public final ReferenceBinding getJavaIoSerializable() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_IO_SERIALIZABLE);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_IO_SERIALIZABLE, this);
+	}
+
+	public final ReferenceBinding getJavaLangAnnotationAnnotation() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION, this);
+	}
+
+	public final ReferenceBinding getJavaLangAssertionError() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_ASSERTIONERROR);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_ASSERTIONERROR, this);
+	}
+
+	public final ReferenceBinding getJavaLangClass() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_CLASS);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_CLASS, this);
+	}
+
+	public final ReferenceBinding getJavaLangCloneable() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_CLONEABLE);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_CLONEABLE, this);
+	}
+	public final ReferenceBinding getJavaLangEnum() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_ENUM);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_ENUM, this);
+	}
+
+	public final ReferenceBinding getJavaLangInvokeLambdaMetafactory() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY, this);
+	}
+
+	public final ReferenceBinding getJavaLangInvokeMethodHandlesLookup() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLES);
+		ReferenceBinding outerType = unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLES, this);
+		return findDirectMemberType("Lookup".toCharArray(), outerType); //$NON-NLS-1$
+	}
+
+	public final ReferenceBinding getJavaLangIterable() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_ITERABLE);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_ITERABLE, this);
+	}
+	public final ReferenceBinding getJavaLangObject() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_OBJECT);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, this);
+	}
+
+	public final ReferenceBinding getJavaLangString() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_STRING);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_STRING, this);
+	}
+
+	public final ReferenceBinding getJavaLangThrowable() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_LANG_THROWABLE);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_LANG_THROWABLE, this);
+	}
+	public final ReferenceBinding getJavaUtilIterator() {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(TypeConstants.JAVA_UTIL_ITERATOR);
+		return unitScope.environment.getResolvedType(TypeConstants.JAVA_UTIL_ITERATOR, this);
+	}
+
+	/* Answer the type binding corresponding to the typeName argument, relative to the enclosingType.
+	*/
+	public final ReferenceBinding getMemberType(char[] typeName, ReferenceBinding enclosingType) {
+		ReferenceBinding memberType = findMemberType(typeName, enclosingType);
+		if (memberType != null) return memberType;
+		char[][] compoundName = new char[][] { typeName };
+		return new ProblemReferenceBinding(compoundName, null, ProblemReasons.NotFound);
+	}
+
+	public MethodBinding getMethod(TypeBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+		CompilationUnitScope unitScope = compilationUnitScope();
+		LookupEnvironment env = unitScope.environment;
+		try {
+			env.missingClassFileLocation = invocationSite;
+			switch (receiverType.kind()) {
+				case Binding.BASE_TYPE :
+					return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+				case Binding.ARRAY_TYPE :
+					unitScope.recordTypeReference(receiverType);
+					return findMethodForArray((ArrayBinding) receiverType, selector, argumentTypes, invocationSite);
+			}
+			unitScope.recordTypeReference(receiverType);
+
+			ReferenceBinding currentType = (ReferenceBinding) receiverType;
+			if (!currentType.canBeSeenBy(this))
+				return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.ReceiverTypeNotVisible);
+
+			// retrieve an exact visible match (if possible)
+			MethodBinding methodBinding = findExactMethod(currentType, selector, argumentTypes, invocationSite);
+			if (methodBinding != null) return methodBinding;
+
+			methodBinding = findMethod(currentType, selector, argumentTypes, invocationSite);
+			if (methodBinding == null)
+				return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+			if (!methodBinding.isValidBinding())
+				return methodBinding;
+
+			// special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
+			if (argumentTypes == Binding.NO_PARAMETERS
+			    && CharOperation.equals(selector, TypeConstants.GETCLASS)
+			    && methodBinding.returnType.isParameterizedType()/*1.5*/) {
+					return environment().createGetClassMethod(receiverType, methodBinding, this);
+		    }
+			return methodBinding;
+		} catch (AbortCompilation e) {
+			e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
+			throw e;
+		} finally {
+			env.missingClassFileLocation = null;
+		}
+	}
+
+	/* Answer the package from the compoundName or null if it begins with a type.
+	* Intended to be used while resolving a qualified type name.
+	*
+	* NOTE: If a problem binding is returned, senders should extract the compound name
+	* from the binding & not assume the problem applies to the entire compoundName.
+	*/
+	public final Binding getPackage(char[][] compoundName) {
+ 		compilationUnitScope().recordQualifiedReference(compoundName);
+		Binding binding = getTypeOrPackage(compoundName[0], Binding.TYPE | Binding.PACKAGE, true);
+		if (binding == null) {
+			char[][] qName = new char[][] { compoundName[0] };
+			return new ProblemReferenceBinding(qName, environment().createMissingType(null, compoundName), ProblemReasons.NotFound);
+		}
+		if (!binding.isValidBinding()) {
+			if (binding instanceof PackageBinding) { /* missing package */
+				char[][] qName = new char[][] { compoundName[0] };
+				return new ProblemReferenceBinding(qName, null /* no closest match since search for pkg*/, ProblemReasons.NotFound);
+			}
+			return binding;
+		}
+		if (!(binding instanceof PackageBinding)) return null; // compoundName does not start with a package
+
+		int currentIndex = 1, length = compoundName.length;
+		PackageBinding packageBinding = (PackageBinding) binding;
+		while (currentIndex < length) {
+			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
+			if (binding == null) {
+				return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null /* no closest match since search for pkg*/, ProblemReasons.NotFound);
+			}
+			if (!binding.isValidBinding())
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null,
+					binding.problemId());
+			if (!(binding instanceof PackageBinding))
+				return packageBinding;
+			packageBinding = (PackageBinding) binding;
+		}
+		return new ProblemReferenceBinding(compoundName, null /* no closest match since search for pkg*/, ProblemReasons.NotFound);
+	}
+
+	/* Answer the package from the compoundName or null if it begins with a type.
+	* Intended to be used while resolving a package name only.
+	* 
+	* Internal use only
+	*/
+	public final Binding getOnlyPackage(char[][] compoundName) {
+ 		compilationUnitScope().recordQualifiedReference(compoundName);
+		Binding binding = getTypeOrPackage(compoundName[0], Binding.PACKAGE, true);
+		if (binding == null || !binding.isValidBinding()) {
+			char[][] qName = new char[][] { compoundName[0] };
+			return new ProblemReferenceBinding(qName, null /* no closest match since search for pkg*/, ProblemReasons.NotFound);
+		}
+		if (!(binding instanceof PackageBinding)) {
+			return null; // compoundName does not start with a package
+		}
+
+		int currentIndex = 1, length = compoundName.length;
+		PackageBinding packageBinding = (PackageBinding) binding;
+		while (currentIndex < length) {
+			binding = packageBinding.getPackage(compoundName[currentIndex++]);
+			if (binding == null) {
+				return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null /* no closest match since search for pkg*/, ProblemReasons.NotFound);
+			}
+			if (!binding.isValidBinding()) {
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null,
+					binding.problemId());
+			}
+			packageBinding = (PackageBinding) binding;
+		}
+		return packageBinding;
+	}
+
+	/* Answer the type binding that corresponds the given name, starting the lookup in the receiver.
+	* The name provided is a simple source name (e.g., "Object" , "Point", ...)
+	*/
+	// The return type of this method could be ReferenceBinding if we did not answer base types.
+	// NOTE: We could support looking for Base Types last in the search, however any code using
+	// this feature would be extraordinarily slow. Therefore we don't do this.
+	public final TypeBinding getType(char[] name) {
+		// Would like to remove this test and require senders to specially handle base types
+		TypeBinding binding = getBaseType(name);
+		if (binding != null) return binding;
+		return (ReferenceBinding) getTypeOrPackage(name, Binding.TYPE, true);
+	}
+
+	/* Answer the type binding that corresponds to the given name, starting the lookup in the receiver
+	* or the packageBinding if provided.
+	* The name provided is a simple source name (e.g., "Object" , "Point", ...)
+	*/
+	public final TypeBinding getType(char[] name, PackageBinding packageBinding) {
+		if (packageBinding == null)
+			return getType(name);
+
+		Binding binding = packageBinding.getTypeOrPackage(name);
+		if (binding == null) {
+			return new ProblemReferenceBinding(
+				CharOperation.arrayConcat(packageBinding.compoundName, name),
+				null,
+				ProblemReasons.NotFound);
+		}
+		if (!binding.isValidBinding()) {
+				return new ProblemReferenceBinding(
+						binding instanceof ReferenceBinding ? ((ReferenceBinding)binding).compoundName : CharOperation.arrayConcat(packageBinding.compoundName, name),
+						binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null,
+						binding.problemId());
+		}
+		ReferenceBinding typeBinding = (ReferenceBinding) binding;
+		if (!typeBinding.canBeSeenBy(this))
+			return new ProblemReferenceBinding(
+				typeBinding.compoundName,
+				typeBinding,
+				ProblemReasons.NotVisible);
+		return typeBinding;
+	}
+
+	/* Answer the type binding corresponding to the compoundName.
+	*
+	* NOTE: If a problem binding is returned, senders should extract the compound name
+	* from the binding & not assume the problem applies to the entire compoundName.
+	*/
+	public final TypeBinding getType(char[][] compoundName, int typeNameLength) {
+		if (typeNameLength == 1) {
+			// Would like to remove this test and require senders to specially handle base types
+			TypeBinding binding = getBaseType(compoundName[0]);
+			if (binding != null) return binding;
+		}
+
+		CompilationUnitScope unitScope = compilationUnitScope();
+		unitScope.recordQualifiedReference(compoundName);
+		Binding binding = getTypeOrPackage(compoundName[0], typeNameLength == 1 ? Binding.TYPE : Binding.TYPE | Binding.PACKAGE, true);
+		if (binding == null) {
+			char[][] qName = new char[][] { compoundName[0] };
+			return new ProblemReferenceBinding(qName, environment().createMissingType(compilationUnitScope().getCurrentPackage(), qName), ProblemReasons.NotFound);
+		}
+		if (!binding.isValidBinding()) {
+			if (binding instanceof PackageBinding) {
+				char[][] qName = new char[][] { compoundName[0] };
+				return new ProblemReferenceBinding(
+						qName,
+						environment().createMissingType(null, qName),
+						ProblemReasons.NotFound);
+			}
+			return (ReferenceBinding) binding;
+		}
+		int currentIndex = 1;
+		boolean checkVisibility = false;
+		if (binding instanceof PackageBinding) {
+			PackageBinding packageBinding = (PackageBinding) binding;
+			while (currentIndex < typeNameLength) {
+				binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); // does not check visibility
+				if (binding == null) {
+					char[][] qName = CharOperation.subarray(compoundName, 0, currentIndex);
+					return new ProblemReferenceBinding(
+						qName,
+						environment().createMissingType(packageBinding, qName),
+						ProblemReasons.NotFound);
+				}
+				if (!binding.isValidBinding())
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null,
+						binding.problemId());
+				if (!(binding instanceof PackageBinding))
+					break;
+				packageBinding = (PackageBinding) binding;
+			}
+			if (binding instanceof PackageBinding) {
+				char[][] qName = CharOperation.subarray(compoundName, 0, currentIndex);
+				return new ProblemReferenceBinding(
+					qName,
+					environment().createMissingType(null, qName),
+					ProblemReasons.NotFound);
+			}
+			checkVisibility = true;
+		}
+
+		// binding is now a ReferenceBinding
+		ReferenceBinding typeBinding = (ReferenceBinding) binding;
+		unitScope.recordTypeReference(typeBinding);
+		if (checkVisibility) // handles the fall through case
+			if (!typeBinding.canBeSeenBy(this))
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					typeBinding,
+					ProblemReasons.NotVisible);
+
+		while (currentIndex < typeNameLength) {
+			typeBinding = getMemberType(compoundName[currentIndex++], typeBinding);
+			if (!typeBinding.isValidBinding()) {
+				if (typeBinding instanceof ProblemReferenceBinding) {
+					ProblemReferenceBinding problemBinding = (ProblemReferenceBinding) typeBinding;
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						problemBinding.closestReferenceMatch(),
+						typeBinding.problemId());
+				}
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+					typeBinding.problemId());
+			}
+		}
+		return typeBinding;
+	}
+
+	/* Internal use only
+	*/
+	final Binding getTypeOrPackage(char[] name, int mask, boolean needResolve) {
+		Scope scope = this;
+		MethodScope methodScope = null;
+		ReferenceBinding foundType = null;
+		boolean insideStaticContext = false;
+		boolean insideTypeAnnotation = false;
+		if ((mask & Binding.TYPE) == 0) {
+			Scope next = scope;
+			while ((next = scope.parent) != null)
+				scope = next;
+		} else {
+			boolean inheritedHasPrecedence = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
+			done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+				switch (scope.kind) {
+					case METHOD_SCOPE :
+						methodScope = (MethodScope) scope;
+						AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
+						if (methodDecl != null) {
+							if (methodDecl.binding != null) {
+								TypeVariableBinding typeVariable = methodDecl.binding.getTypeVariable(name);
+								if (typeVariable != null)
+									return typeVariable;
+							} else {
+								// use the methodDecl's typeParameters to handle problem cases when the method binding doesn't exist
+								TypeParameter[] params = methodDecl.typeParameters();
+								for (int i = params == null ? 0 : params.length; --i >= 0;)
+									if (CharOperation.equals(params[i].name, name))
+										if (params[i].binding != null && params[i].binding.isValidBinding())
+											return params[i].binding;
+							}
+						}
+						insideStaticContext |= methodScope.isStatic;
+						insideTypeAnnotation = methodScope.insideTypeAnnotation;
+						//$FALL-THROUGH$
+					case BLOCK_SCOPE :
+						ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only
+						if (localType != null) {
+							if (foundType != null && foundType != localType)
+								return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
+							return localType;
+						}
+						break;
+					case CLASS_SCOPE :
+						SourceTypeBinding sourceType = ((ClassScope) scope).referenceContext.binding;
+						if (scope == this && (sourceType.tagBits & TagBits.TypeVariablesAreConnected) == 0) {
+							// type variables take precedence over the source type, ex. class X <X> extends X == class X <Y> extends Y
+							// but not when we step out to the enclosing type
+							TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
+							if (typeVariable != null)
+								return typeVariable;
+							if (CharOperation.equals(name, sourceType.sourceName))
+								return sourceType;
+							insideStaticContext |= sourceType.isStatic();
+							break;
+						}
+						// member types take precedence over type variables
+						if (!insideTypeAnnotation) {
+							// 6.5.5.1 - member types have precedence over top-level type in same unit
+							ReferenceBinding memberType = findMemberType(name, sourceType);
+							if (memberType != null) { // skip it if we did not find anything
+								if (memberType.problemId() == ProblemReasons.Ambiguous) {
+									if (foundType == null || foundType.problemId() == ProblemReasons.NotVisible)
+										// supercedes any potential InheritedNameHidesEnclosingName problem
+										return memberType;
+									// make the user qualify the type, likely wants the first inherited type
+									return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
+								}
+								if (memberType.isValidBinding()) {
+									if (sourceType == memberType.enclosingType() || inheritedHasPrecedence) {
+										if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType())
+											return new ProblemReferenceBinding(new char[][]{name}, memberType, ProblemReasons.NonStaticReferenceInStaticContext);
+										// found a valid type in the 'immediate' scope (i.e. not inherited)
+										// OR in 1.4 mode (inherited visible shadows enclosing)
+										if (foundType == null || (inheritedHasPrecedence && foundType.problemId() == ProblemReasons.NotVisible))
+											return memberType;
+										// if a valid type was found, complain when another is found in an 'immediate' enclosing type (i.e. not inherited)
+										if (foundType.isValidBinding() && foundType != memberType)
+											return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
+									}
+								}
+								if (foundType == null || (foundType.problemId() == ProblemReasons.NotVisible && memberType.problemId() != ProblemReasons.NotVisible))
+									// only remember the memberType if its the first one found or the previous one was not visible & memberType is...
+									foundType = memberType;
+							}
+						}
+						TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
+						if (typeVariable != null) {
+							if (insideStaticContext) // do not consider this type modifiers: access is legite within same type
+								return new ProblemReferenceBinding(new char[][]{name}, typeVariable, ProblemReasons.NonStaticReferenceInStaticContext);
+							return typeVariable;
+						}
+						insideStaticContext |= sourceType.isStatic();
+						insideTypeAnnotation = false;
+						if (CharOperation.equals(sourceType.sourceName, name)) {
+							if (foundType != null && foundType != sourceType && foundType.problemId() != ProblemReasons.NotVisible)
+								return new ProblemReferenceBinding(new char[][]{name}, foundType, ProblemReasons.InheritedNameHidesEnclosingName);
+							return sourceType;
+						}
+						break;
+					case COMPILATION_UNIT_SCOPE :
+						break done;
+				}
+				scope = scope.parent;
+			}
+			if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible)
+				return foundType;
+		}
+
+		// at this point the scope is a compilation unit scope
+		CompilationUnitScope unitScope = (CompilationUnitScope) scope;
+		HashtableOfObject typeOrPackageCache = unitScope.typeOrPackageCache;
+		if (typeOrPackageCache != null) {
+			Binding cachedBinding = (Binding) typeOrPackageCache.get(name);
+			if (cachedBinding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found
+				if (cachedBinding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type
+					ImportReference importReference = ((ImportBinding) cachedBinding).reference;
+					if (importReference != null) {
+						importReference.bits |= ASTNode.Used;
+					}
+					if (cachedBinding instanceof ImportConflictBinding)
+						typeOrPackageCache.put(name, cachedBinding = ((ImportConflictBinding) cachedBinding).conflictingTypeBinding); // already know its visible
+					else
+						typeOrPackageCache.put(name, cachedBinding = ((ImportBinding) cachedBinding).resolvedImport); // already know its visible
+				}
+				if ((mask & Binding.TYPE) != 0) {
+					if (foundType != null && foundType.problemId() != ProblemReasons.NotVisible && cachedBinding.problemId() != ProblemReasons.Ambiguous)
+						return foundType; // problem type from above supercedes NotFound type but not Ambiguous import case
+					if (cachedBinding instanceof ReferenceBinding)
+						return cachedBinding; // cached type found in previous walk below
+				}
+				if ((mask & Binding.PACKAGE) != 0 && cachedBinding instanceof PackageBinding)
+					return cachedBinding; // cached package found in previous walk below
+			}
+		}
+
+		// ask for the imports + name
+		if ((mask & Binding.TYPE) != 0) {
+			ImportBinding[] imports = unitScope.imports;
+			if (imports != null && typeOrPackageCache == null) { // walk single type imports since faultInImports() has not run yet
+				nextImport : for (int i = 0, length = imports.length; i < length; i++) {
+					ImportBinding importBinding = imports[i];
+					if (!importBinding.onDemand) {
+						if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
+							Binding resolvedImport = unitScope.resolveSingleImport(importBinding, Binding.TYPE);
+							if (resolvedImport == null) continue nextImport;
+							if (resolvedImport instanceof TypeBinding) {
+								ImportReference importReference = importBinding.reference;
+								if (importReference != null)
+									importReference.bits |= ASTNode.Used;
+								return resolvedImport; // already know its visible
+							}
+						}
+					}
+				}
+			}
+			// In this location we had a fix for 
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401
+			// However, as of today (4.3M6 candidate) this fix seems unnecessary, while causing StackOverflowError in
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=401271
+
+			// check if the name is in the current package, skip it if its a sub-package
+			PackageBinding currentPackage = unitScope.fPackage;
+			unitScope.recordReference(currentPackage.compoundName, name);
+			Binding binding = currentPackage.getTypeOrPackage(name);
+			if (binding instanceof ReferenceBinding) {
+				ReferenceBinding referenceType = (ReferenceBinding) binding;
+				if ((referenceType.tagBits & TagBits.HasMissingType) == 0) {
+					if (typeOrPackageCache != null)
+						typeOrPackageCache.put(name, referenceType);
+					return referenceType; // type is always visible to its own package
+				}
+			}
+
+			// check on demand imports
+			if (imports != null) {
+				boolean foundInImport = false;
+				ReferenceBinding type = null;
+				for (int i = 0, length = imports.length; i < length; i++) {
+					ImportBinding someImport = imports[i];
+					if (someImport.onDemand) {
+						Binding resolvedImport = someImport.resolvedImport;
+						ReferenceBinding temp = null;
+						if (resolvedImport instanceof PackageBinding) {
+							temp = findType(name, (PackageBinding) resolvedImport, currentPackage);
+						} else if (someImport.isStatic()) {
+							temp = findMemberType(name, (ReferenceBinding) resolvedImport); // static imports are allowed to see inherited member types
+							if (temp != null && !temp.isStatic())
+								temp = null;
+						} else {
+							temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport);
+						}
+						if (temp != type && temp != null) {
+							if (temp.isValidBinding()) {
+								ImportReference importReference = someImport.reference;
+								if (importReference != null) {
+									importReference.bits |= ASTNode.Used;
+								}
+								if (foundInImport) {
+									// Answer error binding -- import on demand conflict; name found in two import on demand packages.
+									temp = new ProblemReferenceBinding(new char[][]{name}, type, ProblemReasons.Ambiguous);
+									if (typeOrPackageCache != null)
+										typeOrPackageCache.put(name, temp);
+									return temp;
+								}
+								type = temp;
+								foundInImport = true;
+							} else if (foundType == null) {
+								foundType = temp;
+							}
+						}
+					}
+				}
+				if (type != null) {
+					if (typeOrPackageCache != null)
+						typeOrPackageCache.put(name, type);
+					return type;
+				}
+			}
+		}
+
+		unitScope.recordSimpleReference(name);
+		if ((mask & Binding.PACKAGE) != 0) {
+			PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
+			if (packageBinding != null) {
+				if (typeOrPackageCache != null)
+					typeOrPackageCache.put(name, packageBinding);
+				return packageBinding;
+			}
+		}
+
+		// Answer error binding -- could not find name
+		if (foundType == null) {
+			char[][] qName = new char[][] { name };
+			ReferenceBinding closestMatch = null;
+			if ((mask & Binding.PACKAGE) != 0) {
+				if (needResolve) {
+					closestMatch = environment().createMissingType(unitScope.fPackage, qName);
+				}
+			} else {
+				PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
+				if (packageBinding == null || !packageBinding.isValidBinding()) {
+					if (needResolve) {
+						closestMatch = environment().createMissingType(unitScope.fPackage, qName);
+					}
+				}
+			}
+			foundType = new ProblemReferenceBinding(qName, closestMatch, ProblemReasons.NotFound);
+			if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) { // only put NotFound type in cache if you know its not a package
+				typeOrPackageCache.put(name, foundType);
+			}
+		} else if ((foundType.tagBits & TagBits.HasMissingType) != 0) {
+			char[][] qName = new char[][] { name };
+			foundType = new ProblemReferenceBinding(qName, foundType, ProblemReasons.NotFound);
+			if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) // only put NotFound type in cache if you know its not a package
+				typeOrPackageCache.put(name, foundType);
+		}
+		return foundType;
+	}
+
+	// Added for code assist... NOT Public API
+	// DO NOT USE to resolve import references since this method assumes 'A.B' is relative to a single type import of 'p1.A'
+	// when it may actually mean the type B in the package A
+	// use CompilationUnitScope.getImport(char[][]) instead
+	public final Binding getTypeOrPackage(char[][] compoundName) {
+		int nameLength = compoundName.length;
+		if (nameLength == 1) {
+			TypeBinding binding = getBaseType(compoundName[0]);
+			if (binding != null) return binding;
+		}
+		Binding binding = getTypeOrPackage(compoundName[0], Binding.TYPE | Binding.PACKAGE, true);
+		if (!binding.isValidBinding()) return binding;
+
+		int currentIndex = 1;
+		boolean checkVisibility = false;
+		if (binding instanceof PackageBinding) {
+			PackageBinding packageBinding = (PackageBinding) binding;
+
+			while (currentIndex < nameLength) {
+				binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
+				if (binding == null)
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						null,
+						ProblemReasons.NotFound);
+				if (!binding.isValidBinding())
+					return new ProblemReferenceBinding(
+						CharOperation.subarray(compoundName, 0, currentIndex),
+						binding instanceof ReferenceBinding ? (ReferenceBinding)((ReferenceBinding)binding).closestMatch() : null,
+						binding.problemId());
+				if (!(binding instanceof PackageBinding))
+					break;
+				packageBinding = (PackageBinding) binding;
+			}
+			if (binding instanceof PackageBinding) return binding;
+			checkVisibility = true;
+		}
+		// binding is now a ReferenceBinding
+		ReferenceBinding typeBinding = (ReferenceBinding) binding;
+		ReferenceBinding qualifiedType = (ReferenceBinding) environment().convertToRawType(typeBinding, false /*do not force conversion of enclosing types*/);
+
+		if (checkVisibility) // handles the fall through case
+			if (!typeBinding.canBeSeenBy(this))
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					typeBinding,
+					ProblemReasons.NotVisible);
+
+		while (currentIndex < nameLength) {
+			typeBinding = getMemberType(compoundName[currentIndex++], typeBinding);
+			// checks visibility
+			if (!typeBinding.isValidBinding())
+				return new ProblemReferenceBinding(
+					CharOperation.subarray(compoundName, 0, currentIndex),
+					(ReferenceBinding)typeBinding.closestMatch(),
+					typeBinding.problemId());
+
+			if (typeBinding.isGenericType()) {
+				qualifiedType = environment().createRawType(typeBinding, qualifiedType);
+			} else {
+				qualifiedType = (qualifiedType != null && (qualifiedType.isRawType() || qualifiedType.isParameterizedType()))
+					? environment().createParameterizedType(typeBinding, null, qualifiedType)
+					: typeBinding;
+			}
+		}
+		return qualifiedType;
+	}
+
+	protected boolean hasErasedCandidatesCollisions(TypeBinding one, TypeBinding two, Map invocations, ReferenceBinding type, ASTNode typeRef) {
+		invocations.clear();
+		TypeBinding[] mecs = minimalErasedCandidates(new TypeBinding[] {one, two}, invocations);
+		if (mecs != null) {
+			nextCandidate: for (int k = 0, max = mecs.length; k < max; k++) {
+				TypeBinding mec = mecs[k];
+				if (mec == null) continue nextCandidate;
+				Object value = invocations.get(mec);
+				if (value instanceof TypeBinding[]) {
+					TypeBinding[] invalidInvocations = (TypeBinding[]) value;
+					problemReporter().superinterfacesCollide(invalidInvocations[0].erasure(), typeRef, invalidInvocations[0], invalidInvocations[1]);
+					type.tagBits |= TagBits.HierarchyHasProblems;
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the immediately enclosing switchCase statement (carried by closest blockScope),
+	 */
+	public CaseStatement innermostSwitchCase() {
+		Scope scope = this;
+		do {
+			if (scope instanceof BlockScope)
+				return ((BlockScope) scope).enclosingCase;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+
+	// Tie break IS running to determine the most specific method binding.
+	protected boolean isAcceptableMethod(MethodBinding one, MethodBinding two) {
+		TypeBinding[] oneParams = one.parameters;
+		TypeBinding[] twoParams = two.parameters;
+		int oneParamsLength = oneParams.length;
+		int twoParamsLength = twoParams.length;
+		if (oneParamsLength == twoParamsLength) {
+			/* Below 1.5, discard any generics we have left in for the method verifier's benefit, (so it
+			   can detect method overriding properly in the presence of generic super types.) This is so
+			   as to allow us to determine whether we have been handed an acceptable method in 1.4 terms
+			   without all the 1.5isms below kicking in and spoiling the party.
+			   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446
+			*/
+			boolean applyErasure =  environment().globalOptions.sourceLevel < ClassFileConstants.JDK1_5;
+			next : for (int i = 0; i < oneParamsLength; i++) {
+				TypeBinding oneParam = applyErasure ? oneParams[i].erasure() : oneParams[i];
+				TypeBinding twoParam = applyErasure ? twoParams[i].erasure() : twoParams[i];
+				if (oneParam == twoParam || oneParam.isCompatibleWith(twoParam)) {
+					if (two.declaringClass.isRawType()) continue next;
+
+					TypeBinding leafComponentType = two.original().parameters[i].leafComponentType();
+					TypeBinding originalTwoParam = applyErasure ? leafComponentType.erasure() : leafComponentType; 
+					switch (originalTwoParam.kind()) {
+					   	case Binding.TYPE_PARAMETER :
+					   		if (((TypeVariableBinding) originalTwoParam).hasOnlyRawBounds())
+						   		continue next;
+					   		//$FALL-THROUGH$
+					   	case Binding.WILDCARD_TYPE :
+					   	case Binding.INTERSECTION_TYPE:
+					   	case Binding.PARAMETERIZED_TYPE :
+							TypeBinding originalOneParam = one.original().parameters[i].leafComponentType();
+							switch (originalOneParam.kind()) {
+							   	case Binding.TYPE :
+							   	case Binding.GENERIC_TYPE :
+									TypeBinding inheritedTwoParam = oneParam.findSuperTypeOriginatingFrom(twoParam);
+									if (inheritedTwoParam == null || !inheritedTwoParam.leafComponentType().isRawType()) break;
+							   		return false;
+							   	case Binding.TYPE_PARAMETER :
+							   		if (!((TypeVariableBinding) originalOneParam).upperBound().isRawType()) break;
+							   		return false;
+							   	case Binding.RAW_TYPE:
+							   		// originalOneParam is RAW so it cannot be more specific than a wildcard or parameterized type
+							   		return false;
+							}
+					}
+				} else {
+					if (i == oneParamsLength - 1 && one.isVarargs() && two.isVarargs()) {
+						TypeBinding oType = ((ArrayBinding) oneParam).elementsType();
+						TypeBinding eType = ((ArrayBinding) twoParam).elementsType();
+						if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && this.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7) {
+							if (oneParam == eType || oneParam.isCompatibleWith(eType))
+								return true; // special case to choose between 2 varargs methods when the last arg is Object[]
+						} else {
+							if (oType == eType || oType.isCompatibleWith(eType))
+								return true; // special case to choose between 2 varargs methods when the last arg is Object[]
+						}
+					}
+					return false;
+				}
+			}
+			return true;
+		}
+
+		if (one.isVarargs() && two.isVarargs()) {
+			if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && this.compilerOptions().complianceLevel < ClassFileConstants.JDK1_7 && 
+					oneParamsLength > twoParamsLength) {
+				// special case when autoboxing makes (int, int...) better than (Object...) but not (int...) or (Integer, int...)
+				if (((ArrayBinding) twoParams[twoParamsLength - 1]).elementsType().id != TypeIds.T_JavaLangObject)
+					return false;
+			}
+			// check that each parameter before the vararg parameters are compatible (no autoboxing allowed here)
+			for (int i = (oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength) - 2; i >= 0; i--)
+				if (oneParams[i] != twoParams[i] && !oneParams[i].isCompatibleWith(twoParams[i]))
+					return false;
+			if (parameterCompatibilityLevel(one, twoParams, true) == NOT_COMPATIBLE
+					&& parameterCompatibilityLevel(two, oneParams, true) == VARARGS_COMPATIBLE)
+				return true;
+		}
+		return false;
+	}
+	
+	public boolean isBoxingCompatibleWith(TypeBinding expressionType, TypeBinding targetType) {
+		LookupEnvironment environment = environment();
+		if (environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5 || expressionType.isBaseType() == targetType.isBaseType())
+			return false;
+
+		// check if autoboxed type is compatible
+		TypeBinding convertedType = environment.computeBoxingType(expressionType);
+		return convertedType == targetType || convertedType.isCompatibleWith(targetType);
+	}
+
+	/* Answer true if the scope is nested inside a given field declaration.
+	 * Note: it works as long as the scope.fieldDeclarationIndex is reflecting the field being traversed
+	 * e.g. during name resolution.
+	*/
+	public final boolean isDefinedInField(FieldBinding field) {
+		Scope scope = this;
+		do {
+			if (scope instanceof MethodScope) {
+				MethodScope methodScope = (MethodScope) scope;
+				if (methodScope.initializedField == field) return true;
+			}
+			scope = scope.parent;
+		} while (scope != null);
+		return false;
+	}
+
+	/* Answer true if the scope is nested inside a given method declaration
+	*/
+	public final boolean isDefinedInMethod(MethodBinding method) {
+		method = method.original(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350738
+		Scope scope = this;
+		do {
+			if (scope instanceof MethodScope) {
+				ReferenceContext refContext = ((MethodScope) scope).referenceContext;
+				if (refContext instanceof AbstractMethodDeclaration)
+					if (((AbstractMethodDeclaration) refContext).binding == method)
+						return true;
+			}
+			scope = scope.parent;
+		} while (scope != null);
+		return false;
+	}
+
+	/* Answer whether the type is defined in the same compilation unit as the receiver
+	*/
+	public final boolean isDefinedInSameUnit(ReferenceBinding type) {
+		// find the outer most enclosing type
+		ReferenceBinding enclosingType = type;
+		while ((type = enclosingType.enclosingType()) != null)
+			enclosingType = type;
+
+		// find the compilation unit scope
+		Scope scope, unitScope = this;
+		while ((scope = unitScope.parent) != null)
+			unitScope = scope;
+
+		// test that the enclosingType is not part of the compilation unit
+		SourceTypeBinding[] topLevelTypes = ((CompilationUnitScope) unitScope).topLevelTypes;
+		for (int i = topLevelTypes.length; --i >= 0;)
+			if (topLevelTypes[i] == enclosingType.original())
+				return true;
+		return false;
+	}
+
+	/* Answer true if the scope is nested inside a given type declaration
+	*/
+	public final boolean isDefinedInType(ReferenceBinding type) {
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope)
+				if (((ClassScope) scope).referenceContext.binding == type)
+					return true;
+			scope = scope.parent;
+		} while (scope != null);
+		return false;
+	}
+
+	/**
+	 * Returns true if the scope or one of its parent is associated to a given caseStatement, denoting
+	 * being part of a given switch case statement.
+	 */
+	public boolean isInsideCase(CaseStatement caseStatement) {
+		Scope scope = this;
+		do {
+			switch (scope.kind) {
+				case Scope.BLOCK_SCOPE :
+					if (((BlockScope) scope).enclosingCase == caseStatement) {
+						return true;
+					}
+			}
+			scope = scope.parent;
+		} while (scope != null);
+		return false;
+	}
+
+	public boolean isInsideDeprecatedCode(){
+		switch(this.kind){
+			case Scope.BLOCK_SCOPE :
+			case Scope.METHOD_SCOPE :
+				MethodScope methodScope = methodScope();
+				if (!methodScope.isInsideInitializer()){
+					// check method modifiers to see if deprecated
+					ReferenceContext referenceContext = methodScope.referenceContext;
+					MethodBinding context = referenceContext instanceof AbstractMethodDeclaration ?
+							((AbstractMethodDeclaration)referenceContext).binding : ((LambdaExpression)referenceContext).binding;
+					if (context != null && context.isViewedAsDeprecated())
+						return true;
+				} else if (methodScope.initializedField != null && methodScope.initializedField.isViewedAsDeprecated()) {
+					// inside field declaration ? check field modifier to see if deprecated
+					return true;
+				}
+				SourceTypeBinding declaringType = ((BlockScope)this).referenceType().binding;
+				if (declaringType != null) {
+					declaringType.initializeDeprecatedAnnotationTagBits(); // may not have been resolved until then
+					if (declaringType.isViewedAsDeprecated())
+						return true;
+				}
+				break;
+			case Scope.CLASS_SCOPE :
+				ReferenceBinding context = ((ClassScope)this).referenceType().binding;
+				if (context != null) {
+					context.initializeDeprecatedAnnotationTagBits(); // may not have been resolved until then
+					if (context.isViewedAsDeprecated())
+						return true;
+				}
+				break;
+			case Scope.COMPILATION_UNIT_SCOPE :
+				// consider import as being deprecated if first type is itself deprecated (123522)
+				CompilationUnitDeclaration unit = referenceCompilationUnit();
+				if (unit.types != null && unit.types.length > 0) {
+					SourceTypeBinding type = unit.types[0].binding;
+					if (type != null) {
+						type.initializeDeprecatedAnnotationTagBits(); // may not have been resolved until then
+						if (type.isViewedAsDeprecated())
+							return true;
+					}
+				}
+		}
+		return false;
+	}
+
+	private boolean isOverriddenMethodGeneric(MethodBinding method) {
+		MethodVerifier verifier = environment().methodVerifier();
+		ReferenceBinding currentType = method.declaringClass.superclass();
+		while (currentType != null) {
+			MethodBinding[] currentMethods = currentType.getMethods(method.selector);
+			for (int i = 0, l = currentMethods.length; i < l; i++) {
+				MethodBinding currentMethod = currentMethods[i];
+				if (currentMethod != null && currentMethod.original().typeVariables != Binding.NO_TYPE_VARIABLES)
+					if (verifier.doesMethodOverride(method, currentMethod))
+						return true;
+			}
+			currentType = currentType.superclass();
+		}
+		return false;
+	}
+
+	public boolean isPossibleSubtypeOfRawType(TypeBinding paramType) {
+		TypeBinding t = paramType.leafComponentType();
+		if (t.isBaseType()) return false;
+
+		ReferenceBinding currentType = (ReferenceBinding) t;
+		ReferenceBinding[] interfacesToVisit = null;
+		int nextPosition = 0;
+		do {
+			if (currentType.isRawType()) return true;
+			if (!currentType.isHierarchyConnected()) return true; // do not fault in super types right now, so assume one is a raw type
+	
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				if (interfacesToVisit == null) {
+					interfacesToVisit = itsInterfaces;
+					nextPosition = interfacesToVisit.length;
+				} else {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+		} while ((currentType = currentType.superclass()) != null);
+
+		for (int i = 0; i < nextPosition; i++) {
+			currentType = interfacesToVisit[i];
+			if (currentType.isRawType()) return true;
+
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+		return false;
+	}
+
+	private TypeBinding leastContainingInvocation(TypeBinding mec, Object invocationData, List lubStack) {
+		if (invocationData == null) return mec; // no alternate invocation
+		if (invocationData instanceof TypeBinding) { // only one invocation, simply return it (array only allocated if more than one)
+			return (TypeBinding) invocationData;
+		}
+		TypeBinding[] invocations = (TypeBinding[]) invocationData;
+
+		// if mec is an array type, intersect invocation leaf component types, then promote back to array
+		int dim = mec.dimensions();
+		mec = mec.leafComponentType();
+
+		int argLength = mec.typeVariables().length;
+		if (argLength == 0) return mec; // should be caught by no invocation check
+
+		// infer proper parameterized type from invocations
+		TypeBinding[] bestArguments = new TypeBinding[argLength];
+		for (int i = 0, length = invocations.length; i < length; i++) {
+			TypeBinding invocation = invocations[i].leafComponentType();
+			switch (invocation.kind()) {
+				case Binding.GENERIC_TYPE :
+					TypeVariableBinding[] invocationVariables = invocation.typeVariables();
+					for (int j = 0; j < argLength; j++) {
+						TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[j], invocationVariables[j], (ReferenceBinding) mec, j, lubStack);
+						if (bestArgument == null) return null;
+						bestArguments[j] = bestArgument;
+					}
+					break;
+				case Binding.PARAMETERIZED_TYPE :
+					ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding)invocation;
+					for (int j = 0; j < argLength; j++) {
+						TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[j], parameterizedType.arguments[j], (ReferenceBinding) mec, j, lubStack);
+						if (bestArgument == null) return null;
+						bestArguments[j] = bestArgument;
+					}
+					break;
+				case Binding.RAW_TYPE :
+					return dim == 0 ? invocation : environment().createArrayType(invocation, dim); // raw type is taking precedence
+			}
+		}
+		TypeBinding least = environment().createParameterizedType((ReferenceBinding) mec.erasure(), bestArguments, mec.enclosingType());
+		return dim == 0 ? least : environment().createArrayType(least, dim);
+	}
+
+	// JLS 15.12.2
+	private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank, List lubStack) {
+		if (u == null) return v;
+		if (u == v) return u;
+		if (v.isWildcard()) {
+			WildcardBinding wildV = (WildcardBinding) v;
+			if (u.isWildcard()) {
+				WildcardBinding wildU = (WildcardBinding) u;
+				switch (wildU.boundKind) {
+					// ? extends U
+					case Wildcard.EXTENDS :
+						switch(wildV.boundKind) {
+							// ? extends U, ? extends V
+							case Wildcard.EXTENDS :
+								TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound,wildV.bound}, lubStack);
+								if (lub == null) return null;
+								// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+								if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+								return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
+							// ? extends U, ? SUPER V
+							case Wildcard.SUPER :
+								if (wildU.bound == wildV.bound) return wildU.bound;
+								return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+						}
+						break;
+						// ? super U
+					case Wildcard.SUPER :
+						// ? super U, ? super V
+						if (wildU.boundKind == Wildcard.SUPER) {
+							TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{wildU.bound,wildV.bound}, this);
+							if (glb == null) return null;
+							return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
+						}
+				}
+			} else {
+				switch (wildV.boundKind) {
+					// U, ? extends V
+					case Wildcard.EXTENDS :
+						TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,wildV.bound}, lubStack);
+						if (lub == null) return null;
+						// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+						if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+						return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
+					// U, ? super V
+					case Wildcard.SUPER :
+						TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{u,wildV.bound}, this);
+						if (glb == null) return null;
+						return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
+					case Wildcard.UNBOUND :
+				}
+			}
+		} else if (u.isWildcard()) {
+			WildcardBinding wildU = (WildcardBinding) u;
+			switch (wildU.boundKind) {
+				// U, ? extends V
+				case Wildcard.EXTENDS :
+					TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound, v}, lubStack);
+					if (lub == null) return null;
+					// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+					if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+					return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
+				// U, ? super V
+				case Wildcard.SUPER :
+					TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{wildU.bound, v}, this);
+					if (glb == null) return null;
+					return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds
+				case Wildcard.UNBOUND :
+			}
+		}
+		TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,v}, lubStack);
+		if (lub == null) return null;
+		// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+		if (lub == TypeBinding.INT) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+		return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
+	}
+
+	// 15.12.2
+	/**
+	 * Returns VoidBinding if types have no intersection (e.g. 2 unrelated interfaces), or null if
+	 * no common supertype (e.g. List<String> and List<Exception>), or the intersection type if possible
+	 */
+	public TypeBinding lowerUpperBound(TypeBinding[] types) {
+		int typeLength = types.length;
+		if (typeLength == 1) {
+			TypeBinding type = types[0];
+			return type == null ? TypeBinding.VOID : type;
+		}
+		return lowerUpperBound(types, new ArrayList(1));
+	}
+
+	// 15.12.2
+	private TypeBinding lowerUpperBound(TypeBinding[] types, List lubStack) {
+
+		int typeLength = types.length;
+		if (typeLength == 1) {
+			TypeBinding type = types[0];
+			return type == null ? TypeBinding.VOID : type;
+		}
+		// cycle detection
+		int stackLength = lubStack.size();
+		nextLubCheck: for (int i = 0; i < stackLength; i++) {
+			TypeBinding[] lubTypes = (TypeBinding[])lubStack.get(i);
+			int lubTypeLength = lubTypes.length;
+			if (lubTypeLength < typeLength) continue nextLubCheck;
+			nextTypeCheck:	for (int j = 0; j < typeLength; j++) {
+				TypeBinding type = types[j];
+				if (type == null) continue nextTypeCheck; // ignore
+				for (int k = 0; k < lubTypeLength; k++) {
+					TypeBinding lubType = lubTypes[k];
+					if (lubType == null) continue; // ignore
+					if (lubType == type || lubType.isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one
+				}
+				continue nextLubCheck; // type not found in current lubTypes
+			}
+			// all types are included in some lub, cycle detected - stop recursion by answering special value (int)
+			return TypeBinding.INT;
+		}
+
+		lubStack.add(types);
+		Map invocations = new HashMap(1);
+		TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+		if (mecs == null) return null;
+		int length = mecs.length;
+		if (length == 0) return TypeBinding.VOID;
+		int count = 0;
+		TypeBinding firstBound = null;
+		int commonDim = -1;
+		for (int i = 0; i < length; i++) {
+			TypeBinding mec = mecs[i];
+			if (mec == null) continue;
+			mec = leastContainingInvocation(mec, invocations.get(mec), lubStack);
+			if (mec == null) return null;
+			int dim = mec.dimensions();
+			if (commonDim == -1) {
+				commonDim = dim;
+			} else if (dim != commonDim) { // not all types have same dimension
+				return null;
+			}
+			if (firstBound == null && !mec.leafComponentType().isInterface()) firstBound = mec.leafComponentType();
+			mecs[count++] = mec; // recompact them to the front
+		}
+		switch (count) {
+			case 0 : return TypeBinding.VOID;
+			case 1 : return mecs[0];
+			case 2 :
+				if ((commonDim == 0 ? mecs[1].id : mecs[1].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[0];
+				if ((commonDim == 0 ? mecs[0].id : mecs[0].leafComponentType().id) == TypeIds.T_JavaLangObject) return mecs[1];
+		}
+		TypeBinding[] otherBounds = new TypeBinding[count - 1];
+		int rank = 0;
+		for (int i = 0; i < count; i++) {
+			TypeBinding mec = commonDim == 0 ? mecs[i] : mecs[i].leafComponentType();
+			if (mec.isInterface()) {
+				otherBounds[rank++] = mec;
+			}
+		}
+		TypeBinding intersectionType = environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS);
+		return commonDim == 0 ? intersectionType : environment().createArrayType(intersectionType, commonDim);
+	}
+
+	public final MethodScope methodScope() {
+		Scope scope = this;
+		do {
+			if (scope instanceof MethodScope)
+				return (MethodScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+	
+	public final MethodScope namedMethodScope() {
+		Scope scope = this;
+		do {
+			if (scope instanceof MethodScope && !scope.isLambdaScope())
+				return (MethodScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
+
+	/**
+	 * Returns the most specific set of types compatible with all given types.
+	 * (i.e. most specific common super types)
+	 * If no types is given, will return an empty array. If not compatible
+	 * reference type is found, returns null. In other cases, will return an array
+	 * of minimal erased types, where some nulls may appear (and must simply be
+	 * ignored).
+	 */
+	protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) {
+		int length = types.length;
+		int indexOfFirst = -1, actualLength = 0;
+		for (int i = 0; i < length; i++) {
+			TypeBinding type = types[i];
+			if (type == null) continue;
+			if (type.isBaseType()) return null;
+			if (indexOfFirst < 0) indexOfFirst = i;
+			actualLength ++;
+		}
+		switch (actualLength) {
+			case 0: return Binding.NO_TYPES;
+			case 1: return types;
+		}
+		TypeBinding firstType = types[indexOfFirst];
+		if (firstType.isBaseType()) return null;
+
+		// record all supertypes of type
+		// intersect with all supertypes of otherType
+		ArrayList typesToVisit = new ArrayList(5);
+
+		int dim = firstType.dimensions();
+		TypeBinding leafType = firstType.leafComponentType();
+	    // do not allow type variables/intersection types to match with erasures for free
+		TypeBinding firstErasure;
+		switch(leafType.kind()) {
+			case Binding.PARAMETERIZED_TYPE :
+			case Binding.RAW_TYPE :
+			case Binding.ARRAY_TYPE :
+				firstErasure = firstType.erasure();
+				break;
+			default :
+				firstErasure = firstType;
+				break;
+		}
+		if (firstErasure != firstType) {
+			allInvocations.put(firstErasure, firstType);
+		}
+		typesToVisit.add(firstType);
+		int max = 1;
+		ReferenceBinding currentType;
+		for (int i = 0; i < max; i++) {
+			TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i);
+			dim = typeToVisit.dimensions();
+			if (dim > 0) {
+				leafType = typeToVisit.leafComponentType();
+				switch(leafType.id) {
+					case TypeIds.T_JavaLangObject:
+						if (dim > 1) { // Object[][] supertype is Object[]
+							TypeBinding elementType = ((ArrayBinding)typeToVisit).elementsType();
+							if (!typesToVisit.contains(elementType)) {
+								typesToVisit.add(elementType);
+								max++;
+							}
+							continue;
+						}
+						//$FALL-THROUGH$
+					case TypeIds.T_byte:
+					case TypeIds.T_short:
+					case TypeIds.T_char:
+					case TypeIds.T_boolean:
+					case TypeIds.T_int:
+					case TypeIds.T_long:
+					case TypeIds.T_float:
+					case TypeIds.T_double:
+						TypeBinding superType = getJavaIoSerializable();
+						if (!typesToVisit.contains(superType)) {
+							typesToVisit.add(superType);
+							max++;
+						}
+						superType = getJavaLangCloneable();
+						if (!typesToVisit.contains(superType)) {
+							typesToVisit.add(superType);
+							max++;
+						}
+						superType = getJavaLangObject();
+						if (!typesToVisit.contains(superType)) {
+							typesToVisit.add(superType);
+							max++;
+						}
+						continue;
+
+					default:
+				}
+				typeToVisit = leafType;
+			}
+			currentType = (ReferenceBinding) typeToVisit;
+			if (currentType.isCapture()) {
+				TypeBinding firstBound = ((CaptureBinding) currentType).firstBound;
+				if (firstBound != null && firstBound.isArrayType()) {
+					TypeBinding superType = dim == 0 ? firstBound : (TypeBinding)environment().createArrayType(firstBound, dim); // recreate array if needed
+					if (!typesToVisit.contains(superType)) {
+						typesToVisit.add(superType);
+						max++;
+						TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure();
+						if (superTypeErasure != superType) {
+							allInvocations.put(superTypeErasure, superType);
+						}
+					}
+					continue;
+				}
+			}
+			// inject super interfaces prior to superclass
+			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+			if (itsInterfaces != null) { // can be null during code assist operations that use LookupEnvironment.completeTypeBindings(parsedUnit, buildFieldsAndMethods)
+				for (int j = 0, count = itsInterfaces.length; j < count; j++) {
+					TypeBinding itsInterface = itsInterfaces[j];
+					TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding)environment().createArrayType(itsInterface, dim); // recreate array if needed
+					if (!typesToVisit.contains(superType)) {
+						typesToVisit.add(superType);
+						max++;
+						TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure();
+						if (superTypeErasure != superType) {
+							allInvocations.put(superTypeErasure, superType);
+						}
+					}
+				}
+			}
+			TypeBinding itsSuperclass = currentType.superclass();
+			if (itsSuperclass != null) {
+				TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding)environment().createArrayType(itsSuperclass, dim); // recreate array if needed
+				if (!typesToVisit.contains(superType)) {
+					typesToVisit.add(superType);
+					max++;
+					TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure();
+					if (superTypeErasure != superType) {
+						allInvocations.put(superTypeErasure, superType);
+					}
+				}
+			}
+		}
+		int superLength = typesToVisit.size();
+		TypeBinding[] erasedSuperTypes = new TypeBinding[superLength];
+		int rank = 0;
+		for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) {
+			TypeBinding type = (TypeBinding)iter.next();
+			leafType = type.leafComponentType();
+			erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure();
+		}
+		// intersecting first type supertypes with other types' ones, nullifying non matching supertypes
+		int remaining = superLength;
+		nextOtherType: for (int i = indexOfFirst+1; i < length; i++) {
+			TypeBinding otherType = types[i];
+			if (otherType == null) continue nextOtherType;
+			if (otherType.isArrayType()) {
+				nextSuperType: for (int j = 0; j < superLength; j++) {
+					TypeBinding erasedSuperType = erasedSuperTypes[j];
+					if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType;
+					TypeBinding match;
+					if ((match = otherType.findSuperTypeOriginatingFrom(erasedSuperType)) == null) {
+						erasedSuperTypes[j] = null;
+						if (--remaining == 0) return null;
+						continue nextSuperType;
+					}
+					// record invocation
+					Object invocationData = allInvocations.get(erasedSuperType);
+					if (invocationData == null) {
+						allInvocations.put(erasedSuperType, match); // no array for singleton
+					} else if (invocationData instanceof TypeBinding) {
+						if (match != invocationData) {
+							// using an array to record invocations in order (188103)
+							TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, };
+							allInvocations.put(erasedSuperType, someInvocations);
+						}
+					} else { // using an array to record invocations in order (188103)
+						TypeBinding[] someInvocations = (TypeBinding[]) invocationData;
+						checkExisting: {
+							int invocLength = someInvocations.length;
+							for (int k = 0; k < invocLength; k++) {
+								if (someInvocations[k] == match) break checkExisting;
+							}
+							System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength+1], 0, invocLength);
+							allInvocations.put(erasedSuperType, someInvocations);
+							someInvocations[invocLength] = match;
+						}
+					}
+				}
+				continue nextOtherType;
+			}
+			nextSuperType: for (int j = 0; j < superLength; j++) {
+				TypeBinding erasedSuperType = erasedSuperTypes[j];
+				if (erasedSuperType == null) continue nextSuperType;
+				TypeBinding match;
+				if (erasedSuperType == otherType || erasedSuperType.id == TypeIds.T_JavaLangObject && otherType.isInterface()) {
+					match = erasedSuperType;
+				} else {
+					if (erasedSuperType.isArrayType()) {
+						match = null;
+					} else {
+						match = otherType.findSuperTypeOriginatingFrom(erasedSuperType);
+					}
+					if (match == null) { // incompatible super type
+						erasedSuperTypes[j] = null;
+						if (--remaining == 0) return null;
+						continue nextSuperType;
+					}
+				}
+				// record invocation
+				Object invocationData = allInvocations.get(erasedSuperType);
+				if (invocationData == null) {
+					allInvocations.put(erasedSuperType, match); // no array for singleton
+				} else if (invocationData instanceof TypeBinding) {
+					if (match != invocationData) {
+						// using an array to record invocations in order (188103)
+						TypeBinding[] someInvocations = { (TypeBinding) invocationData, match, };
+						allInvocations.put(erasedSuperType, someInvocations);
+					}
+				} else { // using an array to record invocations in order (188103)
+					TypeBinding[] someInvocations = (TypeBinding[]) invocationData;
+					checkExisting: {
+						int invocLength = someInvocations.length;
+						for (int k = 0; k < invocLength; k++) {
+							if (someInvocations[k] == match) break checkExisting;
+						}
+						System.arraycopy(someInvocations, 0, someInvocations = new TypeBinding[invocLength+1], 0, invocLength);
+						allInvocations.put(erasedSuperType, someInvocations);
+						someInvocations[invocLength] = match;
+					}
+				}
+			}
+		}
+		// eliminate non minimal super types
+		if (remaining > 1) {
+			nextType: for (int i = 0; i < superLength; i++) {
+				TypeBinding erasedSuperType = erasedSuperTypes[i];
+				if (erasedSuperType == null) continue nextType;
+				nextOtherType: for (int j = 0; j < superLength; j++) {
+					if (i == j) continue nextOtherType;
+					TypeBinding otherType = erasedSuperTypes[j];
+					if (otherType == null) continue nextOtherType;
+					if (erasedSuperType instanceof ReferenceBinding) {
+						if (otherType.id == TypeIds.T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface
+						if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) {
+							erasedSuperTypes[j] = null; // discard non minimal supertype
+							remaining--;
+						}
+					} else if (erasedSuperType.isArrayType()) {
+					if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions)
+							&& otherType.leafComponentType().id == TypeIds.T_JavaLangObject
+							&& otherType.dimensions() == erasedSuperType.dimensions()
+							&& erasedSuperType.leafComponentType().isInterface()) continue nextOtherType;
+						if (erasedSuperType.findSuperTypeOriginatingFrom(otherType) != null) {
+							erasedSuperTypes[j] = null; // discard non minimal supertype
+							remaining--;
+						}
+					}
+				}
+			}
+		}
+		return erasedSuperTypes;
+	}
+
+	// Internal use only
+	/* All methods in visible are acceptable matches for the method in question...
+	* The methods defined by the receiver type appear before those defined by its
+	* superclass and so on. We want to find the one which matches best.
+	*
+	* Since the receiver type is a class, we know each method's declaring class is
+	* either the receiver type or one of its superclasses. It is an error if the best match
+	* is defined by a superclass, when a lesser match is defined by the receiver type
+	* or a closer superclass.
+	*/
+	protected final MethodBinding mostSpecificClassMethodBinding(MethodBinding[] visible, int visibleSize, InvocationSite invocationSite) {
+		MethodBinding previous = null;
+		nextVisible : for (int i = 0; i < visibleSize; i++) {
+			MethodBinding method = visible[i];
+			if (previous != null && method.declaringClass != previous.declaringClass)
+				break; // cannot answer a method farther up the hierarchy than the first method found
+
+			if (!method.isStatic()) previous = method; // no ambiguity for static methods
+			for (int j = 0; j < visibleSize; j++) {
+				if (i == j) continue;
+				if (!visible[j].areParametersCompatibleWith(method.parameters))
+					continue nextVisible;
+			}
+			compilationUnitScope().recordTypeReferences(method.thrownExceptions);
+			return method;
+		}
+		return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
+	}
+
+	// Internal use only
+	/* All methods in visible are acceptable matches for the method in question...
+	* Since the receiver type is an interface, we ignore the possibility that 2 inherited
+	* but unrelated superinterfaces may define the same method in acceptable but
+	* not identical ways... we just take the best match that we find since any class which
+	* implements the receiver interface MUST implement all signatures for the method...
+	* in which case the best match is correct.
+	*
+	* NOTE: This is different than javac... in the following example, the message send of
+	* bar(X) in class Y is supposed to be ambiguous. But any class which implements the
+	* interface I MUST implement both signatures for bar. If this class was the receiver of
+	* the message send instead of the interface I, then no problem would be reported.
+	*
+	interface I1 {
+		void bar(J j);
+	}
+	interface I2 {
+	//	void bar(J j);
+		void bar(Object o);
+	}
+	interface I extends I1, I2 {}
+	interface J {}
+
+	class X implements J {}
+
+	class Y extends X {
+		public void foo(I i, X x) { i.bar(x); }
+	}
+	*/
+	protected final MethodBinding mostSpecificInterfaceMethodBinding(MethodBinding[] visible, int visibleSize, InvocationSite invocationSite) {
+		nextVisible : for (int i = 0; i < visibleSize; i++) {
+			MethodBinding method = visible[i];
+			for (int j = 0; j < visibleSize; j++) {
+				if (i == j) continue;
+				if (!visible[j].areParametersCompatibleWith(method.parameters))
+					continue nextVisible;
+			}
+			compilationUnitScope().recordTypeReferences(method.thrownExceptions);
+			return method;
+		}
+		return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
+	}
+
+	// caveat: this is not a direct implementation of JLS
+	protected final MethodBinding mostSpecificMethodBinding(MethodBinding[] visible, int visibleSize, TypeBinding[] argumentTypes, final InvocationSite invocationSite, ReferenceBinding receiverType) {
+		int[] compatibilityLevels = new int[visibleSize];
+		for (int i = 0; i < visibleSize; i++)
+			compatibilityLevels[i] = parameterCompatibilityLevel(visible[i], argumentTypes);
+
+		InvocationSite tieBreakInvocationSite = new InvocationSite() {
+			public TypeBinding[] genericTypeArguments() { return null; } // ignore genericTypeArgs
+			public boolean isSuperAccess() { return invocationSite.isSuperAccess(); }
+			public boolean isTypeAccess() { return invocationSite.isTypeAccess(); }
+			public void setActualReceiverType(ReferenceBinding actualReceiverType) { /* ignore */}
+			public void setDepth(int depth) { /* ignore */}
+			public void setFieldIndex(int depth) { /* ignore */}
+			public int sourceStart() { return invocationSite.sourceStart(); }
+			public int sourceEnd() { return invocationSite.sourceStart(); }
+			public TypeBinding expectedType() { return invocationSite.expectedType(); }
+			public boolean receiverIsImplicitThis() { return invocationSite.receiverIsImplicitThis();}
+		};
+		MethodBinding[] moreSpecific = new MethodBinding[visibleSize];
+		int count = 0;
+		for (int level = 0, max = VARARGS_COMPATIBLE; level <= max; level++) {
+			nextVisible : for (int i = 0; i < visibleSize; i++) {
+				if (compatibilityLevels[i] != level) continue nextVisible;
+				max = level; // do not examine further categories, will either return mostSpecific or report ambiguous case
+				MethodBinding current = visible[i];
+				MethodBinding original = current.original();
+				MethodBinding tiebreakMethod = current.tiebreakMethod();
+				for (int j = 0; j < visibleSize; j++) {
+					if (i == j || compatibilityLevels[j] != level) continue;
+					MethodBinding next = visible[j];
+					if (original == next.original()) {
+						// parameterized superclasses & interfaces may be walked twice from different paths so skip next from now on
+						compatibilityLevels[j] = -1;
+						continue;
+					}
+
+					MethodBinding methodToTest = next;
+					if (next instanceof ParameterizedGenericMethodBinding) {
+						ParameterizedGenericMethodBinding pNext = (ParameterizedGenericMethodBinding) next;
+						if (pNext.isRaw && !pNext.isStatic()) {
+							// hold onto the raw substituted method
+						} else {
+							methodToTest = pNext.originalMethod;
+						}
+					}
+					MethodBinding acceptable = computeCompatibleMethod(methodToTest, tiebreakMethod.parameters, tieBreakInvocationSite, level == VARARGS_COMPATIBLE);
+					/* There are 4 choices to consider with current & next :
+					 foo(B) & foo(A) where B extends A
+					 1. the 2 methods are equal (both accept each others parameters) -> want to continue
+					 2. current has more specific parameters than next (so acceptable is a valid method) -> want to continue
+					 3. current has less specific parameters than next (so acceptable is null) -> go on to next
+					 4. current and next are not compatible with each other (so acceptable is null) -> go on to next
+					 */
+					if (acceptable == null || !acceptable.isValidBinding())
+						continue nextVisible;
+					if (!isAcceptableMethod(tiebreakMethod, acceptable))
+						continue nextVisible;
+					// pick a concrete method over a bridge method when parameters are equal since the return type of the concrete method is more specific
+					if (current.isBridge() && !next.isBridge())
+						if (tiebreakMethod.areParametersEqual(acceptable))
+							continue nextVisible; // skip current so acceptable wins over this bridge method
+				}
+				moreSpecific[i] = current;
+				count++;
+			}
+		}
+		if (count == 1) {
+			for (int i = 0; i < visibleSize; i++) {
+				if (moreSpecific[i] != null) {
+					compilationUnitScope().recordTypeReferences(visible[i].thrownExceptions);
+					return visible[i];
+				}
+			}
+		} else if (count == 0) {
+			return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
+		}
+
+		// found several methods that are mutually acceptable -> must be equal
+		// so now with the first acceptable method, find the 'correct' inherited method for each other acceptable method AND
+		// see if they are equal after substitution of type variables (do the type variables have to be equal to be considered an override???)
+		if (receiverType != null)
+			receiverType = receiverType instanceof CaptureBinding ? receiverType : (ReferenceBinding) receiverType.erasure();
+		nextSpecific : for (int i = 0; i < visibleSize; i++) {
+			MethodBinding current = moreSpecific[i];
+			if (current != null) {
+				ReferenceBinding[] mostSpecificExceptions = null;
+				MethodBinding original = current.original();
+				boolean shouldIntersectExceptions = original.declaringClass.isAbstract() && original.thrownExceptions != Binding.NO_EXCEPTIONS; // only needed when selecting from interface methods
+				for (int j = 0; j < visibleSize; j++) {
+					MethodBinding next = moreSpecific[j];
+					if (next == null || i == j) continue;
+					MethodBinding original2 = next.original();
+					if (original.declaringClass == original2.declaringClass)
+						break nextSpecific; // duplicates thru substitution
+
+					if (!original.isAbstract()) {
+						if (original2.isAbstract())
+							continue; // only compare current against other concrete methods
+
+						original2 = original.findOriginalInheritedMethod(original2);
+						if (original2 == null)
+							continue nextSpecific; // current's declaringClass is not a subtype of next's declaringClass
+						if (current.hasSubstitutedParameters() || original.typeVariables != Binding.NO_TYPE_VARIABLES) {
+							if (!environment().methodVerifier().isParameterSubsignature(original, original2))
+								continue nextSpecific; // current does not override next
+						}
+					} else if (receiverType != null) { // should not be null if original isAbstract, but be safe
+						TypeBinding superType = receiverType.findSuperTypeOriginatingFrom(original.declaringClass.erasure());
+						if (original.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
+							// keep original
+						} else {
+							// must find inherited method with the same substituted variables
+							MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(original.selector, argumentTypes.length);
+							for (int m = 0, l = superMethods.length; m < l; m++) {
+								if (superMethods[m].original() == original) {
+									original = superMethods[m];
+									break;
+								}
+							}
+						}
+						superType = receiverType.findSuperTypeOriginatingFrom(original2.declaringClass.erasure());
+						if (original2.declaringClass == superType || !(superType instanceof ReferenceBinding)) {
+							// keep original2
+						} else {
+							// must find inherited method with the same substituted variables
+							MethodBinding[] superMethods = ((ReferenceBinding) superType).getMethods(original2.selector, argumentTypes.length);
+							for (int m = 0, l = superMethods.length; m < l; m++) {
+								if (superMethods[m].original() == original2) {
+									original2 = superMethods[m];
+									break;
+								}
+							}
+						}
+						if (original.typeVariables != Binding.NO_TYPE_VARIABLES)
+							original2 = original.computeSubstitutedMethod(original2, environment());
+						if (original2 == null || !original.areParameterErasuresEqual(original2))
+							continue nextSpecific; // current does not override next
+						if (original.returnType != original2.returnType) {
+							if (next.original().typeVariables != Binding.NO_TYPE_VARIABLES) {
+								if (original.returnType.erasure().findSuperTypeOriginatingFrom(original2.returnType.erasure()) == null)
+									continue nextSpecific;
+							} else if (!current.returnType.isCompatibleWith(next.returnType)) { 
+								continue nextSpecific;
+							}
+							// continue with original 15.12.2.5
+						}
+						if (shouldIntersectExceptions && original2.declaringClass.isInterface()) {
+							if (current.thrownExceptions != next.thrownExceptions) {
+								if (next.thrownExceptions == Binding.NO_EXCEPTIONS) {
+									mostSpecificExceptions = Binding.NO_EXCEPTIONS;
+								} else {
+									if (mostSpecificExceptions == null) {
+										mostSpecificExceptions = current.thrownExceptions;
+									}
+									int mostSpecificLength = mostSpecificExceptions.length;
+									ReferenceBinding[] nextExceptions = getFilteredExceptions(next);
+									int nextLength = nextExceptions.length;
+									SimpleSet temp = new SimpleSet(mostSpecificLength);
+									boolean changed = false;
+									nextException : for (int t = 0; t < mostSpecificLength; t++) {
+										ReferenceBinding exception = mostSpecificExceptions[t];
+										for (int s = 0; s < nextLength; s++) {
+											ReferenceBinding nextException = nextExceptions[s];
+											if (exception.isCompatibleWith(nextException)) {
+												temp.add(exception);
+												continue nextException;
+											} else if (nextException.isCompatibleWith(exception)) {
+												temp.add(nextException);
+												changed = true;
+												continue nextException;
+											} else {
+												changed = true;
+											}
+										}
+									}
+									if (changed) {
+										mostSpecificExceptions = temp.elementSize == 0 ? Binding.NO_EXCEPTIONS : new ReferenceBinding[temp.elementSize];
+										temp.asArray(mostSpecificExceptions);
+									}
+								}
+							}
+						}
+					}
+				}
+				if (mostSpecificExceptions != null && mostSpecificExceptions != current.thrownExceptions) {
+					return new MostSpecificExceptionMethodBinding(current, mostSpecificExceptions);
+				}
+				return current;
+			}
+		}
+
+		// if all moreSpecific methods are equal then see if duplicates exist because of substitution
+		return new ProblemMethodBinding(visible[0], visible[0].selector, visible[0].parameters, ProblemReasons.Ambiguous);
+	}
+
+	private ReferenceBinding[] getFilteredExceptions(MethodBinding method) {
+		// http://bugs.eclipse.org/387612 - Unreachable catch block...exception is never thrown from the try
+		// Need to filter redundant exceptions within the same throws clause.
+		// In this filtering the *most general* exception wins in order to capture all possible exceptions
+		// that could be thrown by the given method.
+		ReferenceBinding[] allExceptions = method.thrownExceptions;
+		int length = allExceptions.length;
+		if (length < 2) return allExceptions;
+		ReferenceBinding[] filteredExceptions = new ReferenceBinding[length];
+		int count = 0;
+		currents: for (int i = 0; i < length; i++) {
+			ReferenceBinding currentException = allExceptions[i];
+			for (int j = 0; j < length; j++) {
+				if (i == j) continue;
+				if (currentException == allExceptions[j]) {
+					// duplicate same exception
+					if (i < j) 
+						break; // take only the first occurrence
+					else
+						continue currents; // skip
+				}
+				if (currentException.isCompatibleWith(allExceptions[j])) {
+					continue currents; // skip
+				}
+			}
+			filteredExceptions[count++] = currentException;
+		}
+		if (count != length) {
+			ReferenceBinding[] tmp = new ReferenceBinding[count];
+			System.arraycopy(filteredExceptions, 0, tmp,  0, count);
+			return tmp;
+		}
+		return allExceptions;
+	}
+
+	public final ClassScope outerMostClassScope() {
+		ClassScope lastClassScope = null;
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope)
+				lastClassScope = (ClassScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return lastClassScope; // may answer null if no class around
+	}
+
+	public final MethodScope outerMostMethodScope() {
+		MethodScope lastMethodScope = null;
+		Scope scope = this;
+		do {
+			if (scope instanceof MethodScope)
+				lastMethodScope = (MethodScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return lastMethodScope; // may answer null if no method around
+	}
+
+	public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments) {
+		return parameterCompatibilityLevel(method, arguments, false);
+	}	
+	public int parameterCompatibilityLevel(MethodBinding method, TypeBinding[] arguments, boolean tiebreakingVarargsMethods) {
+		TypeBinding[] parameters = method.parameters;
+		int paramLength = parameters.length;
+		int argLength = arguments.length;
+
+		CompilerOptions compilerOptions = compilerOptions();
+		if (compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) {
+			if (paramLength != argLength)
+				return NOT_COMPATIBLE;
+			for (int i = 0; i < argLength; i++) {
+				TypeBinding param = parameters[i];
+				TypeBinding arg = arguments[i];
+				//https://bugs.eclipse.org/bugs/show_bug.cgi?id=330445
+				if (arg != param && !arg.isCompatibleWith(param.erasure(), this))
+					return NOT_COMPATIBLE;
+			}
+			return COMPATIBLE;
+		}
+	    if (tiebreakingVarargsMethods) {
+	        if (CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation && compilerOptions.complianceLevel < ClassFileConstants.JDK1_7) {
+	            tiebreakingVarargsMethods = false;
+	        }
+	    }
+		int level = COMPATIBLE; // no autoboxing or varargs support needed
+		int lastIndex = argLength;
+		LookupEnvironment env = environment();
+		if (method.isVarargs()) {
+			lastIndex = paramLength - 1;
+			if (paramLength == argLength) { // accept X or X[] but not X[][]
+				TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
+				TypeBinding arg = arguments[lastIndex];
+				if (param != arg) {
+					level = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods);
+					if (level == NOT_COMPATIBLE) {
+						// expect X[], is it called with X
+						param = ((ArrayBinding) param).elementsType();
+						if (tiebreakingVarargsMethods) {
+							arg = ((ArrayBinding) arg).elementsType();
+						}
+						if (parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
+							return NOT_COMPATIBLE;
+						level = VARARGS_COMPATIBLE; // varargs support needed
+					}
+				}
+			} else {
+				if (paramLength < argLength) { // all remaining argument types must be compatible with the elementsType of varArgType
+					TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
+					for (int i = lastIndex; i < argLength; i++) {
+						TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i];
+						if (param != arg && parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods) == NOT_COMPATIBLE)
+							return NOT_COMPATIBLE;
+					}
+				}  else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
+					return NOT_COMPATIBLE;
+				}
+				level = VARARGS_COMPATIBLE; // varargs support needed
+			}
+		} else if (paramLength != argLength) {
+			return NOT_COMPATIBLE;
+		}
+		// now compare standard arguments from 0 to lastIndex
+		for (int i = 0; i < lastIndex; i++) {
+			TypeBinding param = parameters[i];
+			TypeBinding arg = (tiebreakingVarargsMethods && (i == (argLength - 1))) ? ((ArrayBinding)arguments[i]).elementsType() : arguments[i];
+			if (arg != param) {
+				int newLevel = parameterCompatibilityLevel(arg, param, env, tiebreakingVarargsMethods);
+				if (newLevel == NOT_COMPATIBLE)
+					return NOT_COMPATIBLE;
+				if (newLevel > level)
+					level = newLevel;
+			}
+		}
+		return level;
+	}
+
+	public int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param) {
+		if (arg.isCompatibleWith(param))
+			return COMPATIBLE;
+		
+		if (arg.isBaseType() != param.isBaseType()) {
+			TypeBinding convertedType = environment().computeBoxingType(arg);
+			if (convertedType == param || convertedType.isCompatibleWith(param))
+				return AUTOBOX_COMPATIBLE;
+		}
+		return NOT_COMPATIBLE;
+	}
+	
+	private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env, boolean tieBreakingVarargsMethods) {
+		// only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5
+		if (arg.isCompatibleWith(param, this))
+			return COMPATIBLE;
+		if (tieBreakingVarargsMethods && (this.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_7 || !CompilerOptions.tolerateIllegalAmbiguousVarargsInvocation)) {
+			/* 15.12.2.5 Choosing the Most Specific Method, ... One variable arity member method named m is more specific than
+			   another variable arity member method of the same name if either ... Only subtypes relationship should be used.
+			   Actually this is true even for fixed arity methods, but in practice is not an issue since we run the algorithm
+			   multiple times for each compatibility level.
+			   https://bugs.eclipse.org/bugs/show_bug.cgi?id=346038, https://bugs.eclipse.org/bugs/show_bug.cgi?id=346039.
+			*/
+			return NOT_COMPATIBLE;
+		}
+		if (arg.isBaseType() != param.isBaseType()) {
+			TypeBinding convertedType = env.computeBoxingType(arg);
+			if (convertedType == param || convertedType.isCompatibleWith(param))
+				return AUTOBOX_COMPATIBLE;
+		}
+		return NOT_COMPATIBLE;
+	}
+
+	public abstract ProblemReporter problemReporter();
+
+	public final CompilationUnitDeclaration referenceCompilationUnit() {
+		Scope scope, unitScope = this;
+		while ((scope = unitScope.parent) != null)
+			unitScope = scope;
+		return ((CompilationUnitScope) unitScope).referenceContext;
+	}
+
+	/**
+	 * Returns the nearest reference context, starting from current scope.
+	 * If starting on a class, it will return current class. If starting on unitScope, returns unit.
+	 */
+	public ReferenceContext referenceContext() {
+		Scope current = this;
+		do {
+			switch(current.kind) {
+				case METHOD_SCOPE :
+					return ((MethodScope) current).referenceContext;
+				case CLASS_SCOPE :
+					return ((ClassScope) current).referenceContext;
+				case COMPILATION_UNIT_SCOPE :
+					return ((CompilationUnitScope) current).referenceContext;
+			}
+		} while ((current = current.parent) != null);
+		return null;
+	}
+
+	public void deferBoundCheck(TypeReference typeRef) {
+		if (this.kind == CLASS_SCOPE) {
+			ClassScope classScope = (ClassScope) this;
+			if (classScope.deferredBoundChecks == null) {
+				classScope.deferredBoundChecks = new ArrayList(3);
+				classScope.deferredBoundChecks.add(typeRef);
+			} else if (!classScope.deferredBoundChecks.contains(typeRef)) {
+				classScope.deferredBoundChecks.add(typeRef);
+			}
+		}
+	}
+
+	// start position in this scope - for ordering scopes vs. variables
+	int startIndex() {
+		return 0;
+	}
+	/* Given an allocation type and arguments at the allocation site, answer a synthetic generic static factory method
+	   that could instead be invoked with identical results. Return null if no compatible, visible, most specific method
+	   could be found. This method is modeled after Scope.getConstructor and Scope.getMethod.
+	 */
+	public MethodBinding getStaticFactory (ReferenceBinding allocationType, ReferenceBinding originalEnclosingType, TypeBinding[] argumentTypes, final InvocationSite allocationSite) {
+		TypeVariableBinding[] classTypeVariables = allocationType.typeVariables();
+		int classTypeVariablesArity = classTypeVariables.length;
+		MethodBinding[] methods = allocationType.getMethods(TypeConstants.INIT, argumentTypes.length);
+		MethodBinding [] staticFactories = new MethodBinding[methods.length];
+		int sfi = 0;
+		for (int i = 0, length = methods.length; i < length; i++) {
+			MethodBinding method = methods[i];
+			int paramLength = method.parameters.length;
+			boolean isVarArgs = method.isVarargs();
+			if (argumentTypes.length != paramLength)
+				if (!isVarArgs || argumentTypes.length < paramLength - 1)
+					continue; // incompatible
+			TypeVariableBinding[] methodTypeVariables = method.typeVariables();
+			int methodTypeVariablesArity = methodTypeVariables.length;
+	        
+			MethodBinding staticFactory = new MethodBinding(method.modifiers | ClassFileConstants.AccStatic, TypeConstants.SYNTHETIC_STATIC_FACTORY,
+																		null, null, null, method.declaringClass);
+			staticFactory.typeVariables = new TypeVariableBinding[classTypeVariablesArity + methodTypeVariablesArity];
+			final SimpleLookupTable map = new SimpleLookupTable(classTypeVariablesArity + methodTypeVariablesArity);
+			// Rename each type variable T of the type to T'
+			final LookupEnvironment environment = environment();
+			for (int j = 0; j < classTypeVariablesArity; j++) {
+				map.put(classTypeVariables[j], staticFactory.typeVariables[j] = new TypeVariableBinding(CharOperation.concat(classTypeVariables[j].sourceName, "'".toCharArray()), //$NON-NLS-1$
+																			staticFactory, j, environment));
+			}
+			// Rename each type variable U of method U to U''.
+			for (int j = classTypeVariablesArity, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) {
+				map.put(methodTypeVariables[j - classTypeVariablesArity], 
+						(staticFactory.typeVariables[j] = new TypeVariableBinding(CharOperation.concat(methodTypeVariables[j - classTypeVariablesArity].sourceName, "''".toCharArray()), //$NON-NLS-1$
+																			staticFactory, j, environment)));
+			}
+			ReferenceBinding enclosingType = originalEnclosingType;
+			while (enclosingType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968
+				if (enclosingType.kind() == Binding.PARAMETERIZED_TYPE) {
+					final ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) enclosingType;
+					final ReferenceBinding genericType = parameterizedType.genericType();
+					TypeVariableBinding[] enclosingClassTypeVariables = genericType.typeVariables();
+					int enclosingClassTypeVariablesArity = enclosingClassTypeVariables.length;
+					for (int j = 0; j < enclosingClassTypeVariablesArity; j++) {
+						map.put(enclosingClassTypeVariables[j], parameterizedType.arguments[j]);
+					}
+				}
+				enclosingType = enclosingType.enclosingType();
+			}
+			final Scope scope = this;
+			Substitution substitution = new Substitution() {
+					public LookupEnvironment environment() {
+						return scope.environment();
+					}
+					public boolean isRawSubstitution() {
+						return false;
+					}
+					public TypeBinding substitute(TypeVariableBinding typeVariable) {
+						TypeBinding retVal = (TypeBinding) map.get(typeVariable);
+						return retVal != null ? retVal : typeVariable;
+					}
+				};
+
+			// initialize new variable bounds
+			for (int j = 0, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) {
+				TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables[j] : methodTypeVariables[j - classTypeVariablesArity];
+				TypeBinding substitutedType = (TypeBinding) map.get(originalVariable);
+				if (substitutedType instanceof TypeVariableBinding) {
+					TypeVariableBinding substitutedVariable = (TypeVariableBinding) substitutedType;
+					TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
+					ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
+					if (originalVariable.firstBound != null) {
+						substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
+								? substitutedSuperclass // could be array type or interface
+										: substitutedInterfaces[0];
+					}
+					switch (substitutedSuperclass.kind()) {
+						case Binding.ARRAY_TYPE :
+							substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+							break;
+						default:
+							if (substitutedSuperclass.isInterface()) {
+								substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+								int interfaceCount = substitutedInterfaces.length;
+								System.arraycopy(substitutedInterfaces, 0, substitutedInterfaces = new ReferenceBinding[interfaceCount+1], 1, interfaceCount);
+								substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass;
+								substitutedVariable.superInterfaces = substitutedInterfaces;
+							} else {
+								substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface
+								substitutedVariable.superInterfaces = substitutedInterfaces;
+							}
+					}
+				}
+			}
+		    TypeVariableBinding[] returnTypeParameters = new TypeVariableBinding[classTypeVariablesArity];
+			for (int j = 0; j < classTypeVariablesArity; j++) {
+				returnTypeParameters[j] = (TypeVariableBinding) map.get(classTypeVariables[j]);
+			}
+			staticFactory.returnType = environment.createParameterizedType(allocationType, returnTypeParameters, allocationType.enclosingType());
+			staticFactory.parameters = Scope.substitute(substitution, method.parameters);
+			staticFactory.thrownExceptions = Scope.substitute(substitution, method.thrownExceptions);
+			if (staticFactory.thrownExceptions == null) { 
+				staticFactory.thrownExceptions = Binding.NO_EXCEPTIONS;
+			}
+			staticFactories[sfi++] = new ParameterizedMethodBinding((ParameterizedTypeBinding) environment.convertToParameterizedType(staticFactory.declaringClass),
+																												staticFactory);
+		}
+		if (sfi == 0)
+			return null;
+		if (sfi != methods.length) {
+			System.arraycopy(staticFactories, 0, staticFactories = new MethodBinding[sfi], 0, sfi);
+		}
+		MethodBinding[] compatible = new MethodBinding[sfi];
+		int compatibleIndex = 0;
+		for (int i = 0; i < sfi; i++) {
+			MethodBinding compatibleMethod = computeCompatibleMethod(staticFactories[i], argumentTypes, allocationSite);
+			if (compatibleMethod != null) {
+				if (compatibleMethod.isValidBinding())
+					compatible[compatibleIndex++] = compatibleMethod;
+			}
+		}
+
+		if (compatibleIndex == 0) {
+			return null;
+		}
+		MethodBinding[] visible = new MethodBinding[compatibleIndex];
+		int visibleIndex = 0;
+		for (int i = 0; i < compatibleIndex; i++) {
+			MethodBinding method = compatible[i];
+			if (method.canBeSeenBy(allocationSite, this))
+				visible[visibleIndex++] = method;
+		}
+		if (visibleIndex == 0) {
+			return null;
+		}
+		return visibleIndex == 1 ? visible[0] : mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, allocationSite, allocationType);
+	}
+
+	public void validateNullAnnotation(long tagBits, TypeReference typeRef, Annotation[] annotations) {
+		long nullAnnotationTagBit = tagBits & (TagBits.AnnotationNonNull|TagBits.AnnotationNullable);
+		if (nullAnnotationTagBit != 0) {
+			TypeBinding type = typeRef.resolvedType;
+			if (type != null && type.isBaseType()) {
+				char[][] annotationName = (nullAnnotationTagBit == TagBits.AnnotationNonNull)
+						? environment().getNonNullAnnotationName()
+						: environment().getNullableAnnotationName();
+				problemReporter().illegalAnnotationForBaseType(typeRef, annotations,
+						annotationName[annotationName.length-1], nullAnnotationTagBit);
+			}
+		}
+	}
+	public static BlockScope typeAnnotationsResolutionScope(Scope scope) {
+		BlockScope resolutionScope = null;
+		switch(scope.kind) {
+			case Scope.CLASS_SCOPE:
+				resolutionScope = ((ClassScope) scope).referenceContext.staticInitializerScope;
+				break;
+			case Scope.BLOCK_SCOPE :
+			case Scope.METHOD_SCOPE :
+				resolutionScope = (BlockScope) scope;
+				break;
+		}
+		return resolutionScope;
+	}
+	// Some entity in the receiver scope is referencing instance data of enclosing type. Tag all intervening methods as instance methods. 
+	public void tagAsAccessingEnclosingInstanceStateOf(ReferenceBinding enclosingType, boolean typeVariableAccess) {
+		MethodScope methodScope = methodScope();
+		if (methodScope != null && methodScope.referenceContext instanceof TypeDeclaration) {
+			if (!methodScope.enclosingReceiverType().isCompatibleWith(enclosingType)) { // unless invoking a method of the local type ...
+				// anonymous type, find enclosing method
+				methodScope = methodScope.enclosingMethodScope();
+			}
+		}
+		while (methodScope != null) {
+			while (methodScope != null && methodScope.referenceContext instanceof LambdaExpression) {
+				LambdaExpression lambda = (LambdaExpression) methodScope.referenceContext;
+				if (!typeVariableAccess)
+					lambda.shouldCaptureInstance = true;  // lambda can still be static, only when `this' is touched (implicitly or otherwise) it cannot be.
+				methodScope = methodScope.enclosingMethodScope();
+			}
+			if (methodScope != null) {
+				if (methodScope.referenceContext instanceof MethodDeclaration) {
+					MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
+					methodDeclaration.bits &= ~ASTNode.CanBeStatic;
+				}
+				ClassScope enclosingClassScope = methodScope.enclosingClassScope();
+				if (enclosingClassScope != null) {
+					TypeDeclaration type = enclosingClassScope.referenceContext;
+					if (type != null && type.binding != null && enclosingType != null && !type.binding.isCompatibleWith(enclosingType.original())) {
+						methodScope = enclosingClassScope.enclosingMethodScope();
+						continue;
+					}
+				}
+				break;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java
new file mode 100644
index 0000000..5df44ca
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class SignatureWrapper {
+	public char[] signature;
+	public int start;
+	public int end;
+	public int bracket;
+	private boolean use15specifics;
+
+	public SignatureWrapper(char[] signature, boolean use15specifics) {
+		this.signature = signature;
+		this.start = 0;
+		this.end = this.bracket = -1;
+		this.use15specifics = use15specifics;
+	}
+	public SignatureWrapper(char [] signature) {
+		this(signature, true);
+	}
+	public boolean atEnd() {
+		return this.start < 0 || this.start >= this.signature.length;
+	}
+	public int computeEnd() {
+		int index = this.start;
+		while (this.signature[index] == '[')
+			index++;
+		switch (this.signature[index]) {
+			case 'L' :
+			case 'T' :
+				this.end = CharOperation.indexOf(';', this.signature, this.start);
+				if (this.bracket <= this.start) // already know it if its > start
+					this.bracket = CharOperation.indexOf('<', this.signature, this.start);
+
+				if (this.bracket > this.start && this.bracket < this.end)
+					this.end = this.bracket;
+				else if (this.end == -1)
+					this.end = this.signature.length + 1;
+				break;
+			default :
+				this.end = this.start;
+		}
+
+		if (this.use15specifics || this.end != this.bracket) {
+			this.start = this.end + 1; // skip ';'
+		} else {
+			this.start = skipAngleContents(this.end) + 1;  // skip <<>*>;
+			this.bracket = -1;
+		}
+		return this.end;
+	}
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, do not expose generics if we shouldn't
+	public int skipAngleContents(int i) {
+		if (this.signature[i] != '<') {
+			return i;
+		}
+		int depth = 0, length = this.signature.length;
+		for (++i; i < length; i++) {
+			switch(this.signature[i]) {
+				case '<' :
+					depth++;
+					break;
+				case '>' :
+					if (--depth < 0)
+						return i + 1;
+					break;
+			}
+		}
+		return i;
+	}
+	public char[] nextWord() {
+		this.end = CharOperation.indexOf(';', this.signature, this.start);
+		if (this.bracket <= this.start) // already know it if its > start
+			this.bracket = CharOperation.indexOf('<', this.signature, this.start);
+		int dot = CharOperation.indexOf('.', this.signature, this.start);
+
+		if (this.bracket > this.start && this.bracket < this.end)
+			this.end = this.bracket;
+		if (dot > this.start && dot < this.end)
+			this.end = dot;
+
+		return CharOperation.subarray(this.signature, this.start, this.start = this.end); // skip word
+	}
+	public String toString() {
+		return new String(this.signature) + " @ " + this.start; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
new file mode 100644
index 0000000..10ca0ba
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -0,0 +1,2064 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *								bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365836 - [compiler][null] Incomplete propagation of null defaults.
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 366063 - Compiler should not add synthetic @NonNull annotations
+ *								bug 384663 - Package Based Annotation Compilation Error in JDT 3.8/4.2 (works in 3.7.2)
+ *								bug 386356 - Type mismatch error with annotations and generics
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 380896 - [compiler][null] Enum constants not recognised as being NonNull.
+ *								bug 391376 - [1.8] check interaction of default methods with bridge methods and generics
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+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.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class SourceTypeBinding extends ReferenceBinding {
+	public ReferenceBinding superclass;
+	public ReferenceBinding[] superInterfaces;
+	private FieldBinding[] fields;
+	private MethodBinding[] methods;
+	public ReferenceBinding[] memberTypes;
+	public TypeVariableBinding[] typeVariables;
+
+	public ClassScope scope;
+
+	// Synthetics are separated into 4 categories: methods, super methods, fields, class literals and bridge methods
+	// if a new category is added, also increment MAX_SYNTHETICS
+	private final static int METHOD_EMUL = 0;
+	private final static int FIELD_EMUL = 1;
+	private final static int CLASS_LITERAL_EMUL = 2;
+
+	private final static int MAX_SYNTHETICS = 3;
+
+	HashMap[] synthetics;
+	char[] genericReferenceTypeSignature;
+
+	private SimpleLookupTable storedAnnotations = null; // keys are this ReferenceBinding & its fields and methods, value is an AnnotationHolder
+
+	private int defaultNullness;
+	private int nullnessDefaultInitialized = 0; // 0: nothing; 1: type; 2: package
+	private int lambdaOrdinal = 0;
+	
+public SourceTypeBinding(char[][] compoundName, PackageBinding fPackage, ClassScope scope) {
+	this.compoundName = compoundName;
+	this.fPackage = fPackage;
+	this.fileName = scope.referenceCompilationUnit().getFileName();
+	this.modifiers = scope.referenceContext.modifiers;
+	this.sourceName = scope.referenceContext.name;
+	this.scope = scope;
+
+	// expect the fields & methods to be initialized correctly later
+	this.fields = Binding.UNINITIALIZED_FIELDS;
+	this.methods = Binding.UNINITIALIZED_METHODS;
+
+	computeId();
+}
+
+private void addDefaultAbstractMethods() {
+	if ((this.tagBits & TagBits.KnowsDefaultAbstractMethods) != 0) return;
+
+	this.tagBits |= TagBits.KnowsDefaultAbstractMethods;
+	if (isClass() && isAbstract()) {
+		if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
+			return; // no longer added for post 1.2 targets
+
+		ReferenceBinding[] itsInterfaces = superInterfaces();
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			MethodBinding[] defaultAbstracts = null;
+			int defaultAbstractsCount = 0;
+			ReferenceBinding[] interfacesToVisit = itsInterfaces;
+			int nextPosition = interfacesToVisit.length;
+			for (int i = 0; i < nextPosition; i++) {
+				ReferenceBinding superType = interfacesToVisit[i];
+				if (superType.isValidBinding()) {
+					MethodBinding[] superMethods = superType.methods();
+					nextAbstractMethod: for (int m = superMethods.length; --m >= 0;) {
+						MethodBinding method = superMethods[m];
+						// explicitly implemented ?
+						if (implementsMethod(method))
+							continue nextAbstractMethod;
+						if (defaultAbstractsCount == 0) {
+							defaultAbstracts = new MethodBinding[5];
+						} else {
+							// already added as default abstract ?
+							for (int k = 0; k < defaultAbstractsCount; k++) {
+								MethodBinding alreadyAdded = defaultAbstracts[k];
+								if (CharOperation.equals(alreadyAdded.selector, method.selector) && alreadyAdded.areParametersEqual(method))
+									continue nextAbstractMethod;
+							}
+						}
+						MethodBinding defaultAbstract = new MethodBinding(
+								method.modifiers | ExtraCompilerModifiers.AccDefaultAbstract | ClassFileConstants.AccSynthetic,
+								method.selector,
+								method.returnType,
+								method.parameters,
+								method.thrownExceptions,
+								this);
+						if (defaultAbstractsCount == defaultAbstracts.length)
+							System.arraycopy(defaultAbstracts, 0, defaultAbstracts = new MethodBinding[2 * defaultAbstractsCount], 0, defaultAbstractsCount);
+						defaultAbstracts[defaultAbstractsCount++] = defaultAbstract;
+					}
+
+					if ((itsInterfaces = superType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+						int itsLength = itsInterfaces.length;
+						if (nextPosition + itsLength >= interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+						nextInterface : for (int a = 0; a < itsLength; a++) {
+							ReferenceBinding next = itsInterfaces[a];
+							for (int b = 0; b < nextPosition; b++)
+								if (next == interfacesToVisit[b]) continue nextInterface;
+							interfacesToVisit[nextPosition++] = next;
+						}
+					}
+				}
+			}
+			if (defaultAbstractsCount > 0) {
+				int length = this.methods.length;
+				System.arraycopy(this.methods, 0, this.methods = new MethodBinding[length + defaultAbstractsCount], 0, length);
+				System.arraycopy(defaultAbstracts, 0, this.methods, length, defaultAbstractsCount);
+				// re-sort methods
+				length = length + defaultAbstractsCount;
+				if (length > 1)
+					ReferenceBinding.sortMethods(this.methods, 0, length);
+				// this.tagBits |= TagBits.AreMethodsSorted; -- already set in #methods()
+			}
+		}
+	}
+}
+/* Add a new synthetic field for <actualOuterLocalVariable>.
+*	Answer the new field or the existing field if one already existed.
+*/
+public FieldBinding addSyntheticFieldForInnerclass(LocalVariableBinding actualOuterLocalVariable) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5);
+
+	FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			CharOperation.concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX, actualOuterLocalVariable.name),
+			actualOuterLocalVariable.type,
+			ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
+		this.synthetics[SourceTypeBinding.FIELD_EMUL].put(actualOuterLocalVariable, synthField);
+	}
+
+	// ensure there is not already such a field defined by the user
+	boolean needRecheck;
+	int index = 1;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			FieldDeclaration[] fieldDeclarations = typeDecl.fields;
+			int max = fieldDeclarations == null ? 0 : fieldDeclarations.length;
+			for (int i = 0; i < max; i++) {
+				FieldDeclaration fieldDecl = fieldDeclarations[i];
+				if (fieldDecl.binding == existingField) {
+					synthField.name = CharOperation.concat(
+						TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX,
+						actualOuterLocalVariable.name,
+						("$" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
+					needRecheck = true;
+					break;
+				}
+			}
+		}
+	} while (needRecheck);
+	return synthField;
+}
+/* Add a new synthetic field for <enclosingType>.
+*	Answer the new field or the existing field if one already existed.
+*/
+public FieldBinding addSyntheticFieldForInnerclass(ReferenceBinding enclosingType) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5);
+
+	FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(enclosingType);
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			CharOperation.concat(
+				TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
+				String.valueOf(enclosingType.depth()).toCharArray()),
+			enclosingType,
+			ClassFileConstants.AccDefault | ClassFileConstants.AccFinal | ClassFileConstants.AccSynthetic,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
+		this.synthetics[SourceTypeBinding.FIELD_EMUL].put(enclosingType, synthField);
+	}
+	// ensure there is not already such a field defined by the user
+	boolean needRecheck;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			FieldDeclaration[] fieldDeclarations = typeDecl.fields;
+			int max = fieldDeclarations == null ? 0 : fieldDeclarations.length;
+			for (int i = 0; i < max; i++) {
+				FieldDeclaration fieldDecl = fieldDeclarations[i];
+				if (fieldDecl.binding == existingField) {
+					if (this.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
+						synthField.name = CharOperation.concat(
+							synthField.name,
+							"$".toCharArray()); //$NON-NLS-1$
+						needRecheck = true;
+					} else {
+						this.scope.problemReporter().duplicateFieldInType(this, fieldDecl);
+					}
+					break;
+				}
+			}
+		}
+	} while (needRecheck);
+	return synthField;
+}
+/* Add a new synthetic field for a class literal access.
+*	Answer the new field or the existing field if one already existed.
+*/
+public FieldBinding addSyntheticFieldForClassLiteral(TypeBinding targetType, BlockScope blockScope) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null)
+		this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] = new HashMap(5);
+
+	// use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
+	FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].get(targetType);
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			CharOperation.concat(
+				TypeConstants.SYNTHETIC_CLASS,
+				String.valueOf(this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size()).toCharArray()),
+			blockScope.getJavaLangClass(),
+			ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size());
+		this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].put(targetType, synthField);
+	}
+	// ensure there is not already such a field defined by the user
+	FieldBinding existingField;
+	if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+		TypeDeclaration typeDecl = blockScope.referenceType();
+		FieldDeclaration[] typeDeclarationFields = typeDecl.fields;
+		int max = typeDeclarationFields == null ? 0 : typeDeclarationFields.length;
+		for (int i = 0; i < max; i++) {
+			FieldDeclaration fieldDecl = typeDeclarationFields[i];
+			if (fieldDecl.binding == existingField) {
+				blockScope.problemReporter().duplicateFieldInType(this, fieldDecl);
+				break;
+			}
+		}
+	}
+	return synthField;
+}
+/* Add a new synthetic field for the emulation of the assert statement.
+*	Answer the new field or the existing field if one already existed.
+*/
+public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5);
+
+	FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("assertionEmulation"); //$NON-NLS-1$
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			TypeConstants.SYNTHETIC_ASSERT_DISABLED,
+			TypeBinding.BOOLEAN,
+			ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
+		this.synthetics[SourceTypeBinding.FIELD_EMUL].put("assertionEmulation", synthField); //$NON-NLS-1$
+	}
+	// ensure there is not already such a field defined by the user
+	// ensure there is not already such a field defined by the user
+	boolean needRecheck;
+	int index = 0;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			int max = (typeDecl.fields == null) ? 0 : typeDecl.fields.length;
+			for (int i = 0; i < max; i++) {
+				FieldDeclaration fieldDecl = typeDecl.fields[i];
+				if (fieldDecl.binding == existingField) {
+					synthField.name = CharOperation.concat(
+						TypeConstants.SYNTHETIC_ASSERT_DISABLED,
+						("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
+					needRecheck = true;
+					break;
+				}
+			}
+		}
+	} while (needRecheck);
+	return synthField;
+}
+/* Add a new synthetic field for recording all enum constant values
+*	Answer the new field or the existing field if one already existed.
+*/
+public FieldBinding addSyntheticFieldForEnumValues() {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5);
+
+	FieldBinding synthField = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get("enumConstantValues"); //$NON-NLS-1$
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			TypeConstants.SYNTHETIC_ENUM_VALUES,
+			this.scope.createArrayType(this,1),
+			ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic | ClassFileConstants.AccFinal,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
+		this.synthetics[SourceTypeBinding.FIELD_EMUL].put("enumConstantValues", synthField); //$NON-NLS-1$
+	}
+	// ensure there is not already such a field defined by the user
+	// ensure there is not already such a field defined by the user
+	boolean needRecheck;
+	int index = 0;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			FieldDeclaration[] fieldDeclarations = typeDecl.fields;
+			int max = fieldDeclarations == null ? 0 : fieldDeclarations.length;
+			for (int i = 0; i < max; i++) {
+				FieldDeclaration fieldDecl = fieldDeclarations[i];
+				if (fieldDecl.binding == existingField) {
+					synthField.name = CharOperation.concat(
+						TypeConstants.SYNTHETIC_ENUM_VALUES,
+						("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
+					needRecheck = true;
+					break;
+				}
+			}
+		}
+	} while (needRecheck);
+	return synthField;
+}
+/* Add a new synthetic access method for read/write access to <targetField>.
+	Answer the new method or the existing method if one already existed.
+*/
+public SyntheticMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess, boolean isSuperAccess) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding accessMethod = null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetField);
+	if (accessors == null) {
+		accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, isSuperAccess, this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetField, accessors = new SyntheticMethodBinding[2]);
+		accessors[isReadAccess ? 0 : 1] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[isReadAccess ? 0 : 1]) == null) {
+			accessMethod = new SyntheticMethodBinding(targetField, isReadAccess, isSuperAccess, this);
+			accessors[isReadAccess ? 0 : 1] = accessMethod;
+		}
+	}
+	return accessMethod;
+}
+/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
+ * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
+*/
+public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding accessMethod = null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(selector);
+	if (accessors == null) {
+		accessMethod = new SyntheticMethodBinding(this, selector);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, accessors = new SyntheticMethodBinding[2]);
+		accessors[0] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[0]) == null) {
+			accessMethod = new SyntheticMethodBinding(this, selector);
+			accessors[0] = accessMethod;
+		}
+	}
+	return accessMethod;
+}
+/*
+ * Add a synthetic field to handle the cache of the switch translation table for the corresponding enum type
+ */
+public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.FIELD_EMUL] = new HashMap(5);
+
+	SyntheticFieldBinding synthField = (SyntheticFieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(key);
+	if (synthField == null) {
+		synthField = new SyntheticFieldBinding(
+			fieldName,
+			this.scope.createArrayType(TypeBinding.INT,1),
+			ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic,
+			this,
+			Constant.NotAConstant,
+			this.synthetics[SourceTypeBinding.FIELD_EMUL].size());
+		this.synthetics[SourceTypeBinding.FIELD_EMUL].put(key, synthField);
+	}
+	// ensure there is not already such a field defined by the user
+	boolean needRecheck;
+	int index = 0;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			FieldDeclaration[] fieldDeclarations = typeDecl.fields;
+			int max = fieldDeclarations == null ? 0 : fieldDeclarations.length;
+			for (int i = 0; i < max; i++) {
+				FieldDeclaration fieldDecl = fieldDeclarations[i];
+				if (fieldDecl.binding == existingField) {
+					synthField.name = CharOperation.concat(
+						fieldName,
+						("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
+					needRecheck = true;
+					break;
+				}
+			}
+		}
+	} while (needRecheck);
+	return synthField;
+}
+/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
+ * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
+*/
+public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding enumBinding) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding accessMethod = null;
+	char[] selector = CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding.constantPoolName());
+	CharOperation.replace(selector, '/', '$');
+	final String key = new String(selector);
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(key);
+	// first add the corresponding synthetic field
+	if (accessors == null) {
+		// then create the synthetic method
+		final SyntheticFieldBinding fieldBinding = addSyntheticFieldForSwitchEnum(selector, key);
+		accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(key, accessors = new SyntheticMethodBinding[2]);
+		accessors[0] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[0]) == null) {
+			final SyntheticFieldBinding fieldBinding = addSyntheticFieldForSwitchEnum(selector, key);
+			accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
+			accessors[0] = accessMethod;
+		}
+	}
+	return accessMethod;
+}
+public SyntheticMethodBinding addSyntheticMethodForEnumInitialization(int begin, int end) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding accessMethod = new SyntheticMethodBinding(this, begin, end);
+	SyntheticMethodBinding[] accessors = new SyntheticMethodBinding[2]; 
+	this.synthetics[SourceTypeBinding.METHOD_EMUL].put(accessMethod.selector, accessors);
+	accessors[0] = accessMethod;
+	return accessMethod;
+}
+public SyntheticMethodBinding addSyntheticMethod(LambdaExpression lambda) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+	
+	SyntheticMethodBinding lambdaMethod = null;
+	SyntheticMethodBinding[] lambdaMethods = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(lambda);
+	if (lambdaMethods == null) {
+		lambdaMethod = new SyntheticMethodBinding(lambda, CharOperation.concat(TypeConstants.ANONYMOUS_METHOD, Integer.toString(this.lambdaOrdinal++).toCharArray()), this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(lambda, lambdaMethods = new SyntheticMethodBinding[1]);
+		lambdaMethods[0] = lambdaMethod;
+	} else {
+		lambdaMethod = lambdaMethods[0];
+	}
+	return lambdaMethod;
+}
+
+/* Add a new synthetic access method for access to <targetMethod>.
+ * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
+	Answer the new method or the existing method if one already existed.
+*/
+public SyntheticMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding accessMethod = null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(targetMethod);
+	if (accessors == null) {
+		accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(targetMethod, accessors = new SyntheticMethodBinding[2]);
+		accessors[isSuperAccess ? 0 : 1] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[isSuperAccess ? 0 : 1]) == null) {
+			accessMethod = new SyntheticMethodBinding(targetMethod, isSuperAccess, this);
+			accessors[isSuperAccess ? 0 : 1] = accessMethod;
+		}
+	}
+	if (targetMethod.declaringClass.isStatic()) {
+		if ((targetMethod.isConstructor() && targetMethod.parameters.length >= 0xFE)
+				|| targetMethod.parameters.length >= 0xFF) {
+			this.scope.problemReporter().tooManyParametersForSyntheticMethod(targetMethod.sourceMethod());
+		}
+	} else if ((targetMethod.isConstructor() && targetMethod.parameters.length >= 0xFD)
+			|| targetMethod.parameters.length >= 0xFE) {
+		this.scope.problemReporter().tooManyParametersForSyntheticMethod(targetMethod.sourceMethod());
+	}
+	return accessMethod;
+}
+public SyntheticMethodBinding addSyntheticArrayMethod(ArrayBinding arrayType, int purpose) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	SyntheticMethodBinding arrayMethod = null;
+	SyntheticMethodBinding[] arrayMethods = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(arrayType);
+	if (arrayMethods == null) {
+		char [] selector = CharOperation.concat(TypeConstants.ANONYMOUS_METHOD, Integer.toString(this.lambdaOrdinal++).toCharArray());
+		arrayMethod = new SyntheticMethodBinding(purpose, arrayType, selector, this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(arrayType, arrayMethods = new SyntheticMethodBinding[2]);
+		arrayMethods[purpose == SyntheticMethodBinding.ArrayConstructor ? 0 : 1] = arrayMethod;
+	} else {
+		if ((arrayMethod = arrayMethods[purpose == SyntheticMethodBinding.ArrayConstructor ? 0 : 1]) == null) {
+			char [] selector = CharOperation.concat(TypeConstants.ANONYMOUS_METHOD, Integer.toString(this.lambdaOrdinal++).toCharArray());
+			arrayMethod = new SyntheticMethodBinding(purpose, arrayType, selector, this);
+			arrayMethods[purpose == SyntheticMethodBinding.ArrayConstructor ? 0 : 1] = arrayMethod;
+		}
+	}
+	return arrayMethod;
+}
+public SyntheticMethodBinding addSyntheticFactoryMethod(MethodBinding privateConstructor, MethodBinding publicConstructor, TypeBinding [] enclosingInstances) {
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null)
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+
+	char [] selector = CharOperation.concat(TypeConstants.ANONYMOUS_METHOD, Integer.toString(this.lambdaOrdinal++).toCharArray());
+	SyntheticMethodBinding factory = new SyntheticMethodBinding(privateConstructor, publicConstructor, selector, enclosingInstances, this);
+	this.synthetics[SourceTypeBinding.METHOD_EMUL].put(selector, new SyntheticMethodBinding[] { factory });
+	return factory;
+}
+/*
+ * Record the fact that bridge methods need to be generated to override certain inherited methods
+ */
+public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding targetMethod) {
+	if (isInterface()) return null; // only classes & enums get bridge methods
+	// targetMethod may be inherited
+	if (inheritedMethodToBridge.returnType.erasure() == targetMethod.returnType.erasure()
+		&& inheritedMethodToBridge.areParameterErasuresEqual(targetMethod)) {
+			return null; // do not need bridge method
+	}
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) {
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+	} else {
+		// check to see if there is another equivalent inheritedMethod already added
+		Iterator synthMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
+		while (synthMethods.hasNext()) {
+			Object synthetic = synthMethods.next();
+			if (synthetic instanceof MethodBinding) {
+				MethodBinding method = (MethodBinding) synthetic;
+				if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector)
+					&& inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure()
+					&& inheritedMethodToBridge.areParameterErasuresEqual(method)) {
+						return null;
+				}
+			}
+		}
+	}
+
+	SyntheticMethodBinding accessMethod = null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
+	if (accessors == null) {
+		accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]);
+		accessors[1] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[1]) == null) {
+			accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
+			accessors[1] = accessMethod;
+		}
+	}
+	return accessMethod;
+}
+/*
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658. Generate a bridge method if a public method is inherited
+ * from a non-public class into a public class (only in 1.6 or greater)
+ */
+public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
+	if (this.scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_5) {
+		return null;
+	}
+	if (isInterface() && !inheritedMethodToBridge.isDefaultMethod()) return null;
+	if (inheritedMethodToBridge.isAbstract() || inheritedMethodToBridge.isFinal() || inheritedMethodToBridge.isStatic()) {
+		return null;
+	}
+	if (this.synthetics == null)
+		this.synthetics = new HashMap[MAX_SYNTHETICS];
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) {
+		this.synthetics[SourceTypeBinding.METHOD_EMUL] = new HashMap(5);
+	} else {
+		// check to see if there is another equivalent inheritedMethod already added
+		Iterator synthMethods = this.synthetics[SourceTypeBinding.METHOD_EMUL].keySet().iterator();
+		while (synthMethods.hasNext()) {
+			Object synthetic = synthMethods.next();
+			if (synthetic instanceof MethodBinding) {
+				MethodBinding method = (MethodBinding) synthetic;
+				if (CharOperation.equals(inheritedMethodToBridge.selector, method.selector)
+					&& inheritedMethodToBridge.returnType.erasure() == method.returnType.erasure()
+					&& inheritedMethodToBridge.areParameterErasuresEqual(method)) {
+						return null;
+				}
+			}
+		}
+	}
+
+	SyntheticMethodBinding accessMethod = null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
+	if (accessors == null) {
+		accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, this);
+		this.synthetics[SourceTypeBinding.METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]);
+		accessors[0] = accessMethod;
+	} else {
+		if ((accessMethod = accessors[0]) == null) {
+			accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, this);
+			accessors[0] = accessMethod;
+		}
+	}
+	return accessMethod;
+}
+boolean areFieldsInitialized() {
+	return this.fields != Binding.UNINITIALIZED_FIELDS;
+}
+boolean areMethodsInitialized() {
+	return this.methods != Binding.UNINITIALIZED_METHODS;
+}
+public int kind() {
+	if (this.typeVariables != Binding.NO_TYPE_VARIABLES) return Binding.GENERIC_TYPE;
+	return Binding.TYPE;
+}
+
+public char[] computeUniqueKey(boolean isLeaf) {
+	char[] uniqueKey = super.computeUniqueKey(isLeaf);
+	if (uniqueKey.length == 2) return uniqueKey; // problem type's unique key is "L;"
+	if (Util.isClassFileName(this.fileName)) return uniqueKey; // no need to insert compilation unit name for a .class file
+
+	// insert compilation unit name if the type name is not the main type name
+	int end = CharOperation.lastIndexOf('.', this.fileName);
+	if (end != -1) {
+		int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
+		char[] mainTypeName = CharOperation.subarray(this.fileName, start, end);
+		start = CharOperation.lastIndexOf('/', uniqueKey) + 1;
+		if (start == 0)
+			start = 1; // start after L
+		if (this.isMemberType()) {
+			end = CharOperation.indexOf('$', uniqueKey, start);
+		} else {
+			// '$' is part of the type name
+			end = -1;
+		}
+		if (end == -1)
+			end = CharOperation.indexOf('<', uniqueKey, start);
+		if (end == -1)
+			end = CharOperation.indexOf(';', uniqueKey, start);
+		char[] topLevelType = CharOperation.subarray(uniqueKey, start, end);
+		if (!CharOperation.equals(topLevelType, mainTypeName)) {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(uniqueKey, 0, start);
+			buffer.append(mainTypeName);
+			buffer.append('~');
+			buffer.append(topLevelType);
+			buffer.append(uniqueKey, end, uniqueKey.length - end);
+			int length = buffer.length();
+			uniqueKey = new char[length];
+			buffer.getChars(0, length, uniqueKey, 0);
+			return uniqueKey;
+		}
+	}
+	return uniqueKey;
+}
+
+void faultInTypesForFieldsAndMethods() {
+	// check @Deprecated annotation
+	getAnnotationTagBits(); // marks as deprecated by side effect
+	ReferenceBinding enclosingType = enclosingType();
+	if (enclosingType != null && enclosingType.isViewedAsDeprecated() && !isDeprecated())
+		this.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+	fields();
+	methods();
+
+	for (int i = 0, length = this.memberTypes.length; i < length; i++)
+		((SourceTypeBinding) this.memberTypes[i]).faultInTypesForFieldsAndMethods();
+}
+// NOTE: the type of each field of a source type is resolved when needed
+public FieldBinding[] fields() {
+	if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+		return this.fields;
+
+	int failed = 0;
+	FieldBinding[] resolvedFields = this.fields;
+	try {
+		// lazily sort fields
+		if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+			int length = this.fields.length;
+			if (length > 1)
+				ReferenceBinding.sortFields(this.fields, 0, length);
+			this.tagBits |= TagBits.AreFieldsSorted;
+		}
+		for (int i = 0, length = this.fields.length; i < length; i++) {
+			if (resolveTypeFor(this.fields[i]) == null) {
+				// do not alter original field array until resolution is over, due to reentrance (143259)
+				if (resolvedFields == this.fields) {
+					System.arraycopy(this.fields, 0, resolvedFields = new FieldBinding[length], 0, length);
+				}
+				resolvedFields[i] = null;
+				failed++;
+			}
+		}
+	} finally {
+		if (failed > 0) {
+			// ensure fields are consistent reqardless of the error
+			int newSize = resolvedFields.length - failed;
+			if (newSize == 0)
+				return this.fields = Binding.NO_FIELDS;
+
+			FieldBinding[] newFields = new FieldBinding[newSize];
+			for (int i = 0, j = 0, length = resolvedFields.length; i < length; i++) {
+				if (resolvedFields[i] != null)
+					newFields[j++] = resolvedFields[i];
+			}
+			this.fields = newFields;
+		}
+	}
+	this.tagBits |= TagBits.AreFieldsComplete;
+	return this.fields;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
+ */
+public char[] genericTypeSignature() {
+    if (this.genericReferenceTypeSignature == null)
+    	this.genericReferenceTypeSignature = computeGenericTypeSignature(this.typeVariables);
+    return this.genericReferenceTypeSignature;
+}
+/**
+ * <param1 ... paramN>superclass superinterface1 ... superinterfaceN
+ * <T:LY<TT;>;U:Ljava/lang/Object;V::Ljava/lang/Runnable;:Ljava/lang/Cloneable;:Ljava/util/Map;>Ljava/lang/Exception;Ljava/lang/Runnable;
+ */
+public char[] genericSignature() {
+    StringBuffer sig = null;
+	if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
+	    sig = new StringBuffer(10);
+	    sig.append('<');
+	    for (int i = 0, length = this.typeVariables.length; i < length; i++)
+	        sig.append(this.typeVariables[i].genericSignature());
+	    sig.append('>');
+	} else {
+	    // could still need a signature if any of supertypes is parameterized
+	    noSignature: if (this.superclass == null || !this.superclass.isParameterizedType()) {
+		    for (int i = 0, length = this.superInterfaces.length; i < length; i++)
+		        if (this.superInterfaces[i].isParameterizedType())
+					break noSignature;
+	        return null;
+	    }
+	    sig = new StringBuffer(10);
+	}
+	if (this.superclass != null)
+		sig.append(this.superclass.genericTypeSignature());
+	else // interface scenario only (as Object cannot be generic) - 65953
+		sig.append(this.scope.getJavaLangObject().genericTypeSignature());
+    for (int i = 0, length = this.superInterfaces.length; i < length; i++)
+        sig.append(this.superInterfaces[i].genericTypeSignature());
+	return sig.toString().toCharArray();
+}
+
+/**
+ * Compute the tagbits for standard annotations. For source types, these could require
+ * lazily resolving corresponding annotation nodes, in case of forward references.
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#getAnnotationTagBits()
+ */
+public long getAnnotationTagBits() {
+	if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope != null) {
+		TypeDeclaration typeDecl = this.scope.referenceContext;
+		boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
+		try {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = true;
+			ASTNode.resolveAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
+		} finally {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = old;
+		}
+		if ((this.tagBits & TagBits.AnnotationDeprecated) != 0)
+			this.modifiers |= ClassFileConstants.AccDeprecated;
+		evaluateNullAnnotations(this.tagBits);
+	}
+	return this.tagBits;
+}
+public MethodBinding[] getDefaultAbstractMethods() {
+	int count = 0;
+	for (int i = this.methods.length; --i >= 0;)
+		if (this.methods[i].isDefaultAbstract())
+			count++;
+	if (count == 0) return Binding.NO_METHODS;
+
+	MethodBinding[] result = new MethodBinding[count];
+	count = 0;
+	for (int i = this.methods.length; --i >= 0;)
+		if (this.methods[i].isDefaultAbstract())
+			result[count++] = this.methods[i];
+	return result;
+}
+// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
+public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
+	int argCount = argumentTypes.length;
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
+		long range;
+		if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
+			nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+				MethodBinding method = this.methods[imethod];
+				if (method.parameters.length == argCount) {
+					TypeBinding[] toMatch = method.parameters;
+					for (int iarg = 0; iarg < argCount; iarg++)
+						if (toMatch[iarg] != argumentTypes[iarg])
+							continue nextMethod;
+					return method;
+				}
+			}
+		}
+	} else {
+		// lazily sort methods
+		if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+			int length = this.methods.length;
+			if (length > 1)
+				ReferenceBinding.sortMethods(this.methods, 0, length);
+			this.tagBits |= TagBits.AreMethodsSorted;
+		}
+		long range;
+		if ((range = ReferenceBinding.binarySearch(TypeConstants.INIT, this.methods)) >= 0) {
+			nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+				MethodBinding method = this.methods[imethod];
+				if (resolveTypesFor(method) == null || method.returnType == null) {
+					methods();
+					return getExactConstructor(argumentTypes);  // try again since the problem methods have been removed
+				}
+				if (method.parameters.length == argCount) {
+					TypeBinding[] toMatch = method.parameters;
+					for (int iarg = 0; iarg < argCount; iarg++)
+						if (toMatch[iarg] != argumentTypes[iarg])
+							continue nextMethod;
+					return method;
+				}
+			}
+		}
+	}
+	return null;
+}
+
+//NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
+//searches up the hierarchy as long as no potential (but not exact) match was found.
+public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
+	// sender from refScope calls recordTypeReference(this)
+	int argCount = argumentTypes.length;
+	boolean foundNothing = true;
+
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
+		long range;
+		if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+			nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+				MethodBinding method = this.methods[imethod];
+				foundNothing = false; // inner type lookups must know that a method with this name exists
+				if (method.parameters.length == argCount) {
+					TypeBinding[] toMatch = method.parameters;
+					for (int iarg = 0; iarg < argCount; iarg++)
+						if (toMatch[iarg] != argumentTypes[iarg])
+							continue nextMethod;
+					return method;
+				}
+			}
+		}
+	} else {
+		// lazily sort methods
+		if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+			int length = this.methods.length;
+			if (length > 1)
+				ReferenceBinding.sortMethods(this.methods, 0, length);
+			this.tagBits |= TagBits.AreMethodsSorted;
+		}
+
+		long range;
+		if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+			// check unresolved method
+			int start = (int) range, end = (int) (range >> 32);
+			for (int imethod = start; imethod <= end; imethod++) {
+				MethodBinding method = this.methods[imethod];
+				if (resolveTypesFor(method) == null || method.returnType == null) {
+					methods();
+					return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
+				}
+			}
+			// check dup collisions
+			boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+			for (int i = start; i <= end; i++) {
+				MethodBinding method1 = this.methods[i];
+				for (int j = end; j > i; j--) {
+					MethodBinding method2 = this.methods[j];
+					boolean paramsMatch = isSource15
+						? method1.areParameterErasuresEqual(method2)
+						: method1.areParametersEqual(method2);
+					if (paramsMatch) {
+						methods();
+						return getExactMethod(selector, argumentTypes, refScope); // try again since the problem methods have been removed
+					}
+				}
+			}
+			nextMethod: for (int imethod = start; imethod <= end; imethod++) {
+				MethodBinding method = this.methods[imethod];
+				TypeBinding[] toMatch = method.parameters;
+				if (toMatch.length == argCount) {
+					for (int iarg = 0; iarg < argCount; iarg++)
+						if (toMatch[iarg] != argumentTypes[iarg])
+							continue nextMethod;
+					return method;
+				}
+			}
+		}
+	}
+
+	if (foundNothing) {
+		if (isInterface()) {
+			 if (this.superInterfaces.length == 1) {
+				if (refScope != null)
+					refScope.recordTypeReference(this.superInterfaces[0]);
+				return this.superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
+			 }
+		} else if (this.superclass != null) {
+			if (refScope != null)
+				refScope.recordTypeReference(this.superclass);
+			return this.superclass.getExactMethod(selector, argumentTypes, refScope);
+		}
+	}
+	return null;
+}
+
+//NOTE: the type of a field of a source type is resolved when needed
+public FieldBinding getField(char[] fieldName, boolean needResolve) {
+
+	if ((this.tagBits & TagBits.AreFieldsComplete) != 0)
+		return ReferenceBinding.binarySearch(fieldName, this.fields);
+
+	// lazily sort fields
+	if ((this.tagBits & TagBits.AreFieldsSorted) == 0) {
+		int length = this.fields.length;
+		if (length > 1)
+			ReferenceBinding.sortFields(this.fields, 0, length);
+		this.tagBits |= TagBits.AreFieldsSorted;
+	}
+	// always resolve anyway on source types
+	FieldBinding field = ReferenceBinding.binarySearch(fieldName, this.fields);
+	if (field != null) {
+		FieldBinding result = null;
+		try {
+			result = resolveTypeFor(field);
+			return result;
+		} finally {
+			if (result == null) {
+				// ensure fields are consistent reqardless of the error
+				int newSize = this.fields.length - 1;
+				if (newSize == 0) {
+					this.fields = Binding.NO_FIELDS;
+				} else {
+					FieldBinding[] newFields = new FieldBinding[newSize];
+					int index = 0;
+					for (int i = 0, length = this.fields.length; i < length; i++) {
+						FieldBinding f = this.fields[i];
+						if (f == field) continue;
+						newFields[index++] = f;
+					}
+					this.fields = newFields;
+				}
+			}
+		}
+	}
+	return null;
+}
+
+// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
+public MethodBinding[] getMethods(char[] selector) {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+		long range;
+		if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+			int start = (int) range, end = (int) (range >> 32);
+			int length = end - start + 1;
+			MethodBinding[] result;
+			System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
+			return result;
+		} else {
+			return Binding.NO_METHODS;
+		}
+	}
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+	MethodBinding[] result;
+	long range;
+	if ((range = ReferenceBinding.binarySearch(selector, this.methods)) >= 0) {
+		int start = (int) range, end = (int) (range >> 32);
+		for (int i = start; i <= end; i++) {
+			MethodBinding method = this.methods[i];
+			if (resolveTypesFor(method) == null || method.returnType == null) {
+				methods();
+				return getMethods(selector); // try again since the problem methods have been removed
+			}
+		}
+		int length = end - start + 1;
+		System.arraycopy(this.methods, start, result = new MethodBinding[length], 0, length);
+	} else {
+		return Binding.NO_METHODS;
+	}
+	boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+	for (int i = 0, length = result.length - 1; i < length; i++) {
+		MethodBinding method = result[i];
+		for (int j = length; j > i; j--) {
+			boolean paramsMatch = isSource15
+				? method.areParameterErasuresEqual(result[j])
+				: method.areParametersEqual(result[j]);
+			if (paramsMatch) {
+				methods();
+				return getMethods(selector); // try again since the duplicate methods have been removed
+			}
+		}
+	}
+	return result;
+}
+/* Answer the synthetic field for <actualOuterLocalVariable>
+*	or null if one does not exist.
+*/
+public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
+	if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
+	return (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(actualOuterLocalVariable);
+}
+/* Answer the synthetic field for <targetEnclosingType>
+*	or null if one does not exist.
+*/
+public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
+
+	if (this.synthetics == null || this.synthetics[SourceTypeBinding.FIELD_EMUL] == null) return null;
+	FieldBinding field = (FieldBinding) this.synthetics[SourceTypeBinding.FIELD_EMUL].get(targetEnclosingType);
+	if (field != null) return field;
+
+	// type compatibility : to handle cases such as
+	// class T { class M{}}
+	// class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
+	if (!onlyExactMatch){
+		Iterator accessFields = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
+		while (accessFields.hasNext()) {
+			field = (FieldBinding) accessFields.next();
+			if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name)
+				&& field.type.findSuperTypeOriginatingFrom(targetEnclosingType) != null)
+					return field;
+		}
+	}
+	return null;
+}
+/*
+ * Answer the bridge method associated for an  inherited methods or null if one does not exist
+ */
+public SyntheticMethodBinding getSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
+	if (this.synthetics == null) return null;
+	if (this.synthetics[SourceTypeBinding.METHOD_EMUL] == null) return null;
+	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) this.synthetics[SourceTypeBinding.METHOD_EMUL].get(inheritedMethodToBridge);
+	if (accessors == null) return null;
+	return accessors[1];
+}
+
+public boolean hasTypeBit(int bit) {
+	// source types initialize type bits during connectSuperclass/interfaces()
+	return (this.typeBits & bit) != 0;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#initializeDeprecatedAnnotationTagBits()
+ */
+public void initializeDeprecatedAnnotationTagBits() {
+	if ((this.tagBits & TagBits.DeprecatedAnnotationResolved) == 0) {
+		TypeDeclaration typeDecl = this.scope.referenceContext;
+		boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
+		try {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = true;
+			ASTNode.resolveDeprecatedAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
+			this.tagBits |= TagBits.DeprecatedAnnotationResolved;
+		} finally {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = old;
+		}
+		if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) {
+			this.modifiers |= ClassFileConstants.AccDeprecated;
+		}
+	}
+}
+
+// ensure the receiver knows its hierarchy & fields/methods so static imports can be resolved correctly
+// see bug 230026
+void initializeForStaticImports() {
+	if (this.scope == null) return; // already initialized
+
+	if (this.superInterfaces == null)
+		this.scope.connectTypeHierarchy();
+	this.scope.buildFields();
+	this.scope.buildMethods();
+}
+
+private void initializeNullDefault() {
+	// ensure nullness defaults are initialized at all enclosing levels:
+	switch (this.nullnessDefaultInitialized) {
+	case 0:
+		getAnnotationTagBits(); // initialize
+		//$FALL-THROUGH$
+	case 1:
+		getPackage().isViewedAsDeprecated(); // initialize annotations
+		this.nullnessDefaultInitialized = 2;
+	}
+}
+
+/**
+ * Returns true if a type is identical to another one,
+ * or for generic types, true if compared to its raw type.
+ */
+public boolean isEquivalentTo(TypeBinding otherType) {
+
+	if (this == otherType) return true;
+	if (otherType == null) return false;
+	switch(otherType.kind()) {
+
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE:
+			return ((WildcardBinding) otherType).boundCheck(this);
+
+		case Binding.PARAMETERIZED_TYPE :
+			if ((otherType.tagBits & TagBits.HasDirectWildcard) == 0 && (!isMemberType() || !otherType.isMemberType()))
+				return false; // should have been identical
+			ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+			if (this != otherParamType.genericType())
+				return false;
+			if (!isStatic()) { // static member types do not compare their enclosing
+            	ReferenceBinding enclosing = enclosingType();
+            	if (enclosing != null) {
+            		ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+            		if (otherEnclosing == null) return false;
+            		if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
+						if (enclosing != otherEnclosing) return false;
+            		} else {
+            			if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+            		}
+            	}
+			}
+			int length = this.typeVariables == null ? 0 : this.typeVariables.length;
+			TypeBinding[] otherArguments = otherParamType.arguments;
+			int otherLength = otherArguments == null ? 0 : otherArguments.length;
+			if (otherLength != length)
+				return false;
+			for (int i = 0; i < length; i++)
+				if (!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i]))
+					return false;
+			return true;
+
+		case Binding.RAW_TYPE :
+	        return otherType.erasure() == this;
+	}
+	return false;
+}
+public boolean isGenericType() {
+    return this.typeVariables != Binding.NO_TYPE_VARIABLES;
+}
+public boolean isHierarchyConnected() {
+	return (this.tagBits & TagBits.EndHierarchyCheck) != 0;
+}
+public ReferenceBinding[] memberTypes() {
+	return this.memberTypes;
+}
+
+public boolean hasMemberTypes() {
+    return this.memberTypes.length > 0;
+}
+
+// NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
+public MethodBinding[] methods() {
+	if ((this.tagBits & TagBits.AreMethodsComplete) != 0)
+		return this.methods;
+
+	if (!areMethodsInitialized()) { // https://bugs.eclipse.org/384663
+		this.scope.buildMethods();
+	}
+
+	// lazily sort methods
+	if ((this.tagBits & TagBits.AreMethodsSorted) == 0) {
+		int length = this.methods.length;
+		if (length > 1)
+			ReferenceBinding.sortMethods(this.methods, 0, length);
+		this.tagBits |= TagBits.AreMethodsSorted;
+	}
+
+	int failed = 0;
+	MethodBinding[] resolvedMethods = this.methods;
+	try {
+		for (int i = 0, length = this.methods.length; i < length; i++) {
+			if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+				// recursive call to methods() from resolveTypesFor(..) resolved the methods
+				return this.methods;
+			}
+
+			if (resolveTypesFor(this.methods[i]) == null) {
+				// do not alter original method array until resolution is over, due to reentrance (143259)
+				if (resolvedMethods == this.methods) {
+					System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
+				}
+				resolvedMethods[i] = null; // unable to resolve parameters
+				failed++;
+			}
+		}
+
+		// find & report collision cases
+		boolean complyTo15OrAbove = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
+		boolean compliance16 = this.scope.compilerOptions().complianceLevel == ClassFileConstants.JDK1_6;
+		
+		for (int i = 0, length = this.methods.length; i < length; i++) {
+			int severity = ProblemSeverities.Error;
+			MethodBinding method = resolvedMethods[i];
+			if (method == null)
+				continue;
+			char[] selector = method.selector;
+			AbstractMethodDeclaration methodDecl = null;
+			nextSibling: for (int j = i + 1; j < length; j++) {
+				MethodBinding method2 = resolvedMethods[j];
+				if (method2 == null)
+					continue nextSibling;
+				if (!CharOperation.equals(selector, method2.selector))
+					break nextSibling; // methods with same selector are contiguous
+
+				if (complyTo15OrAbove) {
+					if (method.areParameterErasuresEqual(method2)) {
+						// we now ignore return types in 1.7 when detecting duplicates, just as we did before 1.5 
+						// Only in 1.6, we have to make sure even return types are different
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317719
+						if (compliance16 && method.returnType != null && method2.returnType != null) {
+							if (method.returnType.erasure() != method2.returnType.erasure()) {
+								// check to see if the erasure of either method is equal to the other
+								// if not, then change severity to WARNING
+								TypeBinding[] params1 = method.parameters;
+								TypeBinding[] params2 = method2.parameters;
+								int pLength = params1.length;
+								TypeVariableBinding[] vars = method.typeVariables;
+								TypeVariableBinding[] vars2 = method2.typeVariables;
+								boolean equalTypeVars = vars == vars2;
+								MethodBinding subMethod = method2;
+								if (!equalTypeVars) {
+									MethodBinding temp = method.computeSubstitutedMethod(method2, this.scope.environment());
+									if (temp != null) {
+										equalTypeVars = true;
+										subMethod = temp;
+									}
+								}
+								boolean equalParams = method.areParametersEqual(subMethod);
+								if (equalParams && equalTypeVars) {
+									// duplicates regardless of return types
+								} else if (vars != Binding.NO_TYPE_VARIABLES && vars2 != Binding.NO_TYPE_VARIABLES) {
+									// both have type arguments. Erasure of signature of one cannot be equal to signature of other
+									severity = ProblemSeverities.Warning;
+								} else if (pLength > 0) {
+									int index = pLength;
+									// is erasure of signature of m2 same as signature of m1?
+									for (; --index >= 0;) {
+										if (params1[index] != params2[index].erasure()) {
+											// If one of them is a raw type
+											if (params1[index] instanceof RawTypeBinding) {
+												if (params2[index].erasure() != ((RawTypeBinding)params1[index]).actualType()) {
+													break;
+												}
+											} else  {
+												break;
+											}
+										}
+										if (params1[index] == params2[index]) {
+											TypeBinding type = params1[index].leafComponentType();
+											if (type instanceof SourceTypeBinding && type.typeVariables() != Binding.NO_TYPE_VARIABLES) {
+												index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
+												break;
+											}
+										}
+									}
+									if (index >= 0 && index < pLength) {
+										// is erasure of signature of m1 same as signature of m2?
+										for (index = pLength; --index >= 0;)
+											if (params1[index].erasure() != params2[index]) {
+												// If one of them is a raw type
+												if (params2[index] instanceof RawTypeBinding) {
+													if (params1[index].erasure() != ((RawTypeBinding)params2[index]).actualType()) {
+														break;
+													}
+												} else  {
+													break;
+												}
+											}
+										
+									}
+									if (index >= 0) {
+										// erasure of neither is equal to signature of other
+										severity = ProblemSeverities.Warning;
+									}
+								} else if (pLength != 0){
+									severity = ProblemSeverities.Warning;
+								} // pLength = 0 automatically makes erasure of arguments one equal to arguments of other.
+							}
+							// else return types also equal. All conditions satisfied
+							// to give error in 1.6 compliance as well.
+						}
+					} else {
+						continue nextSibling;
+					}
+				} else if (!method.areParametersEqual(method2)) {
+					// prior to 1.5, parameters identical meant a collision case
+					continue nextSibling;
+				}
+				// otherwise duplicates / name clash
+				boolean isEnumSpecialMethod = isEnum() && (CharOperation.equals(selector,TypeConstants.VALUEOF) || CharOperation.equals(selector,TypeConstants.VALUES));
+				// report duplicate
+				boolean removeMethod2 = (severity == ProblemSeverities.Error) ? true : false; // do not remove if in 1.6 and just a warning given
+				if (methodDecl == null) {
+					methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
+					if (methodDecl != null && methodDecl.binding != null) { // ensure its a valid user defined method
+						boolean removeMethod = method.returnType == null && method2.returnType != null;
+						if (isEnumSpecialMethod) {
+							this.scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl);
+							// remove user defined methods & keep the synthetic
+							removeMethod = true;
+						} else {
+							this.scope.problemReporter().duplicateMethodInType(this, methodDecl, method.areParametersEqual(method2), severity);
+						}
+						if (removeMethod) {
+							removeMethod2 = false;
+							methodDecl.binding = null;
+							// do not alter original method array until resolution is over, due to reentrance (143259)
+							if (resolvedMethods == this.methods)
+								System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
+							resolvedMethods[i] = null;
+							failed++;
+						}
+					}
+				}
+				AbstractMethodDeclaration method2Decl = method2.sourceMethod();
+				if (method2Decl != null && method2Decl.binding != null) { // ensure its a valid user defined method
+					if (isEnumSpecialMethod) {
+						this.scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl);
+						removeMethod2 = true;
+					} else {
+						this.scope.problemReporter().duplicateMethodInType(this, method2Decl, method.areParametersEqual(method2), severity);
+					}
+					if (removeMethod2) {
+						method2Decl.binding = null;
+						// do not alter original method array until resolution is over, due to reentrance (143259)
+						if (resolvedMethods == this.methods)
+							System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
+						resolvedMethods[j] = null;
+						failed++;
+					}
+				}
+			}
+			if (method.returnType == null && resolvedMethods[i] != null) { // forget method with invalid return type... was kept to detect possible collisions
+				methodDecl = method.sourceMethod();
+				if (methodDecl != null)
+					methodDecl.binding = null;
+				// do not alter original method array until resolution is over, due to reentrance (143259)
+				if (resolvedMethods == this.methods)
+					System.arraycopy(this.methods, 0, resolvedMethods = new MethodBinding[length], 0, length);
+				resolvedMethods[i] = null;
+				failed++;
+			}
+		}
+	} finally {
+		if ((this.tagBits & TagBits.AreMethodsComplete) != 0) {
+			// recursive call to methods() from resolveTypesFor(..) resolved the methods
+			return this.methods;
+		}
+		if (failed > 0) {
+			int newSize = resolvedMethods.length - failed;
+			if (newSize == 0) {
+				this.methods = Binding.NO_METHODS;
+			} else {
+				MethodBinding[] newMethods = new MethodBinding[newSize];
+				for (int i = 0, j = 0, length = resolvedMethods.length; i < length; i++)
+					if (resolvedMethods[i] != null)
+						newMethods[j++] = resolvedMethods[i];
+				this.methods = newMethods;
+			}
+		}
+
+		// handle forward references to potential default abstract methods
+		addDefaultAbstractMethods();
+		this.tagBits |= TagBits.AreMethodsComplete;
+	}
+	return this.methods;
+}
+public FieldBinding resolveTypeFor(FieldBinding field) {
+	if ((field.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+		return field;
+
+	if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+		if ((field.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
+			field.modifiers |= ClassFileConstants.AccDeprecated;
+	}
+	if (isViewedAsDeprecated() && !field.isDeprecated())
+		field.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+	if (hasRestrictedAccess())
+		field.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+	FieldDeclaration[] fieldDecls = this.scope.referenceContext.fields;
+	int length = fieldDecls == null ? 0 : fieldDecls.length;
+	for (int f = 0; f < length; f++) {
+		if (fieldDecls[f].binding != field)
+			continue;
+
+		MethodScope initializationScope = field.isStatic()
+			? this.scope.referenceContext.staticInitializerScope
+			: this.scope.referenceContext.initializerScope;
+		FieldBinding previousField = initializationScope.initializedField;
+		try {
+			initializationScope.initializedField = field;
+			FieldDeclaration fieldDecl = fieldDecls[f];
+			TypeBinding fieldType =
+				fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT
+					? initializationScope.environment().convertToRawType(this, false /*do not force conversion of enclosing types*/) // enum constant is implicitly of declaring enum type
+					: fieldDecl.type.resolveType(initializationScope, true /* check bounds*/);
+			field.type = fieldType;
+			field.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+			if (fieldType == null) {
+				fieldDecl.binding = null;
+				return null;
+			}
+			if (fieldType == TypeBinding.VOID) {
+				this.scope.problemReporter().variableTypeCannotBeVoid(fieldDecl);
+				fieldDecl.binding = null;
+				return null;
+			}
+			if (fieldType.isArrayType() && ((ArrayBinding) fieldType).leafComponentType == TypeBinding.VOID) {
+				this.scope.problemReporter().variableTypeCannotBeVoidArray(fieldDecl);
+				fieldDecl.binding = null;
+				return null;
+			}
+			if ((fieldType.tagBits & TagBits.HasMissingType) != 0) {
+				field.tagBits |= TagBits.HasMissingType;
+			}
+			TypeBinding leafType = fieldType.leafComponentType();
+			if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0) {
+				field.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+			}
+
+			// apply null default:
+			LookupEnvironment environment = this.scope.environment();
+			if (environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
+				if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+					// enum constants neither have a type declaration nor can they be null
+					field.tagBits |= TagBits.AnnotationNonNull;
+				} else {
+					initializeNullDefault();
+					if (hasNonNullDefault()) {
+						field.fillInDefaultNonNullness(fieldDecl, initializationScope);
+					}
+					// validate null annotation:
+					this.scope.validateNullAnnotation(field.tagBits, fieldDecl.type, fieldDecl.annotations);
+				}
+			}
+		} finally {
+		    initializationScope.initializedField = previousField;
+		}
+		return field;
+	}
+	return null; // should never reach this point
+}
+public MethodBinding resolveTypesFor(MethodBinding method) {
+	if ((method.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+		return method;
+
+	if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+		if ((method.getAnnotationTagBits() & TagBits.AnnotationDeprecated) != 0)
+			method.modifiers |= ClassFileConstants.AccDeprecated;
+	}
+	if (isViewedAsDeprecated() && !method.isDeprecated())
+		method.modifiers |= ExtraCompilerModifiers.AccDeprecatedImplicitly;
+	if (hasRestrictedAccess())
+		method.modifiers |= ExtraCompilerModifiers.AccRestrictedAccess;
+
+	AbstractMethodDeclaration methodDecl = method.sourceMethod();
+	if (methodDecl == null) return null; // method could not be resolved in previous iteration
+
+
+	TypeParameter[] typeParameters = methodDecl.typeParameters();
+	if (typeParameters != null) {
+		methodDecl.scope.connectTypeVariables(typeParameters, true);
+		// Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
+		for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
+			typeParameters[i].checkBounds(methodDecl.scope);
+	}
+	TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
+	if (exceptionTypes != null) {
+		int size = exceptionTypes.length;
+		method.thrownExceptions = new ReferenceBinding[size];
+		int count = 0;
+		ReferenceBinding resolvedExceptionType;
+		for (int i = 0; i < size; i++) {
+			resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/);
+			if (resolvedExceptionType == null)
+				continue;
+			if (resolvedExceptionType.isBoundParameterizedType()) {
+				methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]);
+				continue;
+			}
+			if (resolvedExceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
+				if (resolvedExceptionType.isValidBinding()) {
+					methodDecl.scope.problemReporter().cannotThrowType(exceptionTypes[i], resolvedExceptionType);
+					continue;
+				}
+			}
+			if ((resolvedExceptionType.tagBits & TagBits.HasMissingType) != 0) {
+				method.tagBits |= TagBits.HasMissingType;
+			}
+			method.modifiers |= (resolvedExceptionType.modifiers & ExtraCompilerModifiers.AccGenericSignature);
+			method.thrownExceptions[count++] = resolvedExceptionType;
+		}
+		if (count < size)
+			System.arraycopy(method.thrownExceptions, 0, method.thrownExceptions = new ReferenceBinding[count], 0, count);
+	}
+	
+	if (methodDecl.receiver != null) {
+		method.receiver = methodDecl.receiver.type.resolveType(methodDecl.scope, true /* check bounds*/);
+	}
+	final boolean reportUnavoidableGenericTypeProblems = this.scope.compilerOptions().reportUnavoidableGenericTypeProblems;
+	boolean foundArgProblem = false;
+	Argument[] arguments = methodDecl.arguments;
+	if (arguments != null) {
+		int size = arguments.length;
+		method.parameters = Binding.NO_PARAMETERS;
+		TypeBinding[] newParameters = new TypeBinding[size];
+		for (int i = 0; i < size; i++) {
+			Argument arg = arguments[i];
+			if (arg.annotations != null) {
+				method.tagBits |= TagBits.HasParameterAnnotations;
+			}
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
+			boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && !method.isConstructor() && (arg.type.bits & ASTNode.IgnoreRawTypeCheck) == 0;
+			TypeBinding parameterType;
+			if (deferRawTypeCheck) {
+				arg.type.bits |= ASTNode.IgnoreRawTypeCheck;
+			}
+			try {
+				parameterType = arg.type.resolveType(methodDecl.scope, true /* check bounds*/);
+			} finally {
+				if (deferRawTypeCheck) { 
+					arg.type.bits &= ~ASTNode.IgnoreRawTypeCheck;
+				}
+			}
+		
+			if (parameterType == null) {
+				foundArgProblem = true;
+			} else if (parameterType == TypeBinding.VOID) {
+				methodDecl.scope.problemReporter().argumentTypeCannotBeVoid(methodDecl, arg);
+				foundArgProblem = true;
+			} else {
+				if ((parameterType.tagBits & TagBits.HasMissingType) != 0) {
+					method.tagBits |= TagBits.HasMissingType;
+				}
+				TypeBinding leafType = parameterType.leafComponentType();
+				if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+					method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+				newParameters[i] = parameterType;
+				arg.binding = new LocalVariableBinding(arg, parameterType, arg.modifiers, true /*isArgument*/);
+			}
+		}
+		// only assign parameters if no problems are found
+		if (!foundArgProblem) {
+			method.parameters = newParameters;
+		}
+	}
+
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799
+	if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7) {
+		if ((method.tagBits & TagBits.AnnotationSafeVarargs) != 0) {
+			if (!method.isVarargs()) {
+				methodDecl.scope.problemReporter().safeVarargsOnFixedArityMethod(method);
+			} else if (!method.isStatic() && !method.isFinal() && !method.isConstructor()) {
+				methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
+			}
+		} else if (method.parameters != null && method.parameters.length > 0 && method.isVarargs()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795
+			if (!method.parameters[method.parameters.length - 1].isReifiable()) {
+				methodDecl.scope.problemReporter().possibleHeapPollutionFromVararg(methodDecl.arguments[methodDecl.arguments.length - 1]);
+			}
+		}
+	}
+
+	boolean foundReturnTypeProblem = false;
+	if (!method.isConstructor()) {
+		TypeReference returnType = methodDecl instanceof MethodDeclaration
+			? ((MethodDeclaration) methodDecl).returnType
+			: null;
+		if (returnType == null) {
+			methodDecl.scope.problemReporter().missingReturnType(methodDecl);
+			method.returnType = null;
+			foundReturnTypeProblem = true;
+		} else {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817
+			boolean deferRawTypeCheck = !reportUnavoidableGenericTypeProblems && (returnType.bits & ASTNode.IgnoreRawTypeCheck) == 0;
+			TypeBinding methodType;
+			if (deferRawTypeCheck) {
+				returnType.bits |= ASTNode.IgnoreRawTypeCheck;
+			}
+			try {
+				methodType = returnType.resolveType(methodDecl.scope, true /* check bounds*/);
+			} finally {
+				if (deferRawTypeCheck) { 
+					returnType.bits &= ~ASTNode.IgnoreRawTypeCheck;
+				}
+			}
+			if (methodType == null) {
+				foundReturnTypeProblem = true;
+			} else {
+				if ((methodType.tagBits & TagBits.HasMissingType) != 0) {
+					method.tagBits |= TagBits.HasMissingType;
+				}
+				method.returnType = methodType;
+				TypeBinding leafType = methodType.leafComponentType();
+				if (leafType instanceof ReferenceBinding && (((ReferenceBinding) leafType).modifiers & ExtraCompilerModifiers.AccGenericSignature) != 0)
+					method.modifiers |= ExtraCompilerModifiers.AccGenericSignature;
+				else if (leafType == TypeBinding.VOID && methodDecl.annotations != null)
+					rejectTypeAnnotatedVoidMethod(methodDecl);
+			}
+		}
+	}
+	if (foundArgProblem) {
+		methodDecl.binding = null;
+		method.parameters = Binding.NO_PARAMETERS; // see 107004
+		// nullify type parameter bindings as well as they have a backpointer to the method binding
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=81134)
+		if (typeParameters != null)
+			for (int i = 0, length = typeParameters.length; i < length; i++)
+				typeParameters[i].binding = null;
+		return null;
+	}
+	CompilerOptions compilerOptions = this.scope.compilerOptions();
+	if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+		createArgumentBindings(method, compilerOptions); // need annotations resolved already at this point
+	}
+	if (foundReturnTypeProblem)
+		return method; // but its still unresolved with a null return type & is still connected to its method declaration
+
+	method.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+	return method;
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391108
+private void rejectTypeAnnotatedVoidMethod(AbstractMethodDeclaration methodDecl) {
+	Annotation[] annotations = methodDecl.annotations;
+	int length = annotations == null ? 0 : annotations.length;
+	for (int i = 0; i < length; i++) {
+		ReferenceBinding binding = (ReferenceBinding) annotations[i].resolvedType;
+		if (binding != null
+				&& (binding.tagBits & TagBits.AnnotationForTypeUse) != 0
+				&& (binding.tagBits & TagBits.AnnotationForMethod) == 0) {
+			methodDecl.scope.problemReporter().illegalUsageOfTypeAnnotations(annotations[i]);
+		}
+	}
+}
+private void createArgumentBindings(MethodBinding method, CompilerOptions compilerOptions) {
+	initializeNullDefault();
+	AbstractMethodDeclaration methodDecl = method.sourceMethod();
+	if (methodDecl != null) {
+		// while creating argument bindings we also collect explicit null annotations:
+		if (method.parameters != Binding.NO_PARAMETERS)
+			methodDecl.createArgumentBindings();
+		// add implicit annotations (inherited(?) & default):
+		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
+			new ImplicitNullAnnotationVerifier(compilerOptions.inheritNullAnnotations).checkImplicitNullAnnotations(method, methodDecl, true, this.scope);
+		}
+	}
+}
+private void evaluateNullAnnotations(long annotationTagBits) {
+	if (this.nullnessDefaultInitialized > 0 || !this.scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
+		return;
+	boolean isPackageInfo = CharOperation.equals(this.sourceName, TypeConstants.PACKAGE_INFO_NAME);
+	PackageBinding pkg = getPackage();
+	boolean isInDefaultPkg = (pkg.compoundName == CharOperation.NO_CHAR_CHAR);
+	if (!isPackageInfo) {
+		boolean isInNullnessAnnotationPackage = 
+				pkg == this.scope.environment().nonnullAnnotationPackage
+				|| pkg == this.scope.environment().nullableAnnotationPackage
+				|| pkg == this.scope.environment().nonnullByDefaultAnnotationPackage;
+		if (pkg.defaultNullness == NO_NULL_DEFAULT && !isInDefaultPkg && !isInNullnessAnnotationPackage && !(this instanceof NestedTypeBinding)) {
+			ReferenceBinding packageInfo = pkg.getType(TypeConstants.PACKAGE_INFO_NAME);
+			if (packageInfo == null) {
+				// no pkgInfo - complain
+				this.scope.problemReporter().missingNonNullByDefaultAnnotation(this.scope.referenceContext);
+				pkg.defaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
+			} else {
+				// if pkgInfo has no default annot. - complain
+				packageInfo.getAnnotationTagBits();
+			}
+		}
+	}
+	this.nullnessDefaultInitialized = 1;
+	// transfer nullness info from tagBits to this.nullnessDefaultAnnotation
+	int newDefaultNullness = NO_NULL_DEFAULT;
+	if ((annotationTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+		newDefaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
+	else if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0)
+		newDefaultNullness = NONNULL_BY_DEFAULT;
+	if (newDefaultNullness != NO_NULL_DEFAULT) {
+		if (isPackageInfo) {
+			pkg.defaultNullness = newDefaultNullness;
+		} else {
+			this.defaultNullness = newDefaultNullness;
+			TypeDeclaration typeDecl = this.scope.referenceContext;
+			long nullDefaultBits = annotationTagBits & (TagBits.AnnotationNullUnspecifiedByDefault|TagBits.AnnotationNonNullByDefault);
+			checkRedundantNullnessDefaultRecurse(typeDecl, typeDecl.annotations, nullDefaultBits);
+		}
+	} else if (isPackageInfo || (isInDefaultPkg && !(this instanceof NestedTypeBinding))) {
+		this.scope.problemReporter().missingNonNullByDefaultAnnotation(this.scope.referenceContext);
+		if (!isInDefaultPkg)
+			pkg.defaultNullness = NULL_UNSPECIFIED_BY_DEFAULT;
+	}
+}
+
+protected void checkRedundantNullnessDefaultRecurse(ASTNode location, Annotation[] annotations, long annotationTagBits) {
+	if (this.fPackage.defaultNullness != NO_NULL_DEFAULT) {
+		if ((this.fPackage.defaultNullness == NONNULL_BY_DEFAULT
+				&& ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0))) {
+			this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this.fPackage);
+		}
+		return;
+	}
+}
+
+// return: should caller continue searching?
+protected boolean checkRedundantNullnessDefaultOne(ASTNode location, Annotation[] annotations, long annotationTagBits) {
+	int thisDefault = this.defaultNullness;
+	if (thisDefault == NONNULL_BY_DEFAULT) {
+		if ((annotationTagBits & TagBits.AnnotationNonNullByDefault) != 0) {
+			this.scope.problemReporter().nullDefaultAnnotationIsRedundant(location, annotations, this);
+		}
+		return false; // different default means inner default is not redundant -> we're done
+	}
+	return true;
+}
+
+boolean hasNonNullDefault() {
+	// find the applicable default inside->out:
+
+	SourceTypeBinding currentType = null;
+	Scope currentScope = this.scope;
+	while (currentScope != null) {
+		switch (currentScope.kind) {
+			case Scope.METHOD_SCOPE:
+				AbstractMethodDeclaration referenceMethod = ((MethodScope)currentScope).referenceMethod();
+				if (referenceMethod != null && referenceMethod.binding != null) {
+					long methodTagBits = referenceMethod.binding.tagBits;
+					if ((methodTagBits & TagBits.AnnotationNonNullByDefault) != 0)
+						return true;
+					if ((methodTagBits & TagBits.AnnotationNullUnspecifiedByDefault) != 0)
+						return false;
+				}
+				break;
+			case Scope.CLASS_SCOPE:
+				currentType = ((ClassScope)currentScope).referenceContext.binding;
+				if (currentType != null) {
+					int foundDefaultNullness = currentType.defaultNullness;
+					if (foundDefaultNullness != NO_NULL_DEFAULT) {
+						return foundDefaultNullness == NONNULL_BY_DEFAULT;
+					}
+				}
+				break;
+		}
+		currentScope = currentScope.parent;
+	}
+
+	// package
+	if (currentType != null) {
+		return currentType.getPackage().defaultNullness == NONNULL_BY_DEFAULT;
+	}
+
+	return false;
+}
+
+public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
+	if (forceInitialization)
+		binding.getAnnotationTagBits(); // ensure annotations are up to date
+	return super.retrieveAnnotationHolder(binding, false);
+}
+public void setFields(FieldBinding[] fields) {
+	this.fields = fields;
+}
+public void setMethods(MethodBinding[] methods) {
+	this.methods = methods;
+}
+public final int sourceEnd() {
+	return this.scope.referenceContext.sourceEnd;
+}
+public final int sourceStart() {
+	return this.scope.referenceContext.sourceStart;
+}
+SimpleLookupTable storedAnnotations(boolean forceInitialize) {
+	if (forceInitialize && this.storedAnnotations == null && this.scope != null) { // scope null when no annotation cached, and type got processed fully (159631)
+		this.scope.referenceCompilationUnit().compilationResult.hasAnnotations = true;
+		if (!this.scope.environment().globalOptions.storeAnnotations)
+			return null; // not supported during this compile
+		this.storedAnnotations = new SimpleLookupTable(3);
+	}
+	return this.storedAnnotations;
+}
+public ReferenceBinding superclass() {
+	return this.superclass;
+}
+public ReferenceBinding[] superInterfaces() {
+	return this.superInterfaces;
+}
+public SyntheticMethodBinding[] syntheticMethods() {
+	if (this.synthetics == null 
+			|| this.synthetics[SourceTypeBinding.METHOD_EMUL] == null 
+			|| this.synthetics[SourceTypeBinding.METHOD_EMUL].size() == 0) {
+		return null;
+	}
+	// difficult to compute size up front because of the embedded arrays so assume there is only 1
+	int index = 0;
+	SyntheticMethodBinding[] bindings = new SyntheticMethodBinding[1];
+	Iterator methodArrayIterator = this.synthetics[SourceTypeBinding.METHOD_EMUL].values().iterator();
+	while (methodArrayIterator.hasNext()) {
+		SyntheticMethodBinding[] methodAccessors = (SyntheticMethodBinding[]) methodArrayIterator.next();
+		for (int i = 0, max = methodAccessors.length; i < max; i++) {
+			if (methodAccessors[i] != null) {
+				if (index+1 > bindings.length) {
+					System.arraycopy(bindings, 0, (bindings = new SyntheticMethodBinding[index + 1]), 0, index);
+				}
+				bindings[index++] = methodAccessors[i]; 
+			}
+		}
+	}
+	// sort them in according to their own indexes
+	int length;
+	SyntheticMethodBinding[] sortedBindings = new SyntheticMethodBinding[length = bindings.length];
+	for (int i = 0; i < length; i++){
+		SyntheticMethodBinding binding = bindings[i];
+		sortedBindings[binding.index] = binding;
+	}
+	return sortedBindings;
+}
+/**
+ * Answer the collection of synthetic fields to append into the classfile
+ */
+public FieldBinding[] syntheticFields() {
+	if (this.synthetics == null) return null;
+	int fieldSize = this.synthetics[SourceTypeBinding.FIELD_EMUL] == null ? 0 : this.synthetics[SourceTypeBinding.FIELD_EMUL].size();
+	int literalSize = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] == null ? 0 :this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].size();
+	int totalSize = fieldSize + literalSize;
+	if (totalSize == 0) return null;
+	FieldBinding[] bindings = new FieldBinding[totalSize];
+
+	// add innerclass synthetics
+	if (this.synthetics[SourceTypeBinding.FIELD_EMUL] != null){
+		Iterator elements = this.synthetics[SourceTypeBinding.FIELD_EMUL].values().iterator();
+		for (int i = 0; i < fieldSize; i++) {
+			SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next();
+			bindings[synthBinding.index] = synthBinding;
+		}
+	}
+	// add class literal synthetics
+	if (this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL] != null){
+		Iterator elements = this.synthetics[SourceTypeBinding.CLASS_LITERAL_EMUL].values().iterator();
+		for (int i = 0; i < literalSize; i++) {
+			SyntheticFieldBinding synthBinding = (SyntheticFieldBinding) elements.next();
+			bindings[fieldSize+synthBinding.index] = synthBinding;
+		}
+	}
+	return bindings;
+}
+public String toString() {
+    StringBuffer buffer = new StringBuffer(30);
+    buffer.append("(id="); //$NON-NLS-1$
+    if (this.id == TypeIds.NoId)
+        buffer.append("NoId"); //$NON-NLS-1$
+    else
+        buffer.append(this.id);
+    buffer.append(")\n"); //$NON-NLS-1$
+	if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
+	if (isPublic()) buffer.append("public "); //$NON-NLS-1$
+	if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
+	if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
+	if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
+	if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
+	if (isFinal()) buffer.append("final "); //$NON-NLS-1$
+
+	if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+	else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+	else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+	else buffer.append("interface "); //$NON-NLS-1$
+	buffer.append((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
+
+	if (this.typeVariables == null) {
+		buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
+	} else if (this.typeVariables != Binding.NO_TYPE_VARIABLES) {
+		buffer.append("<"); //$NON-NLS-1$
+		for (int i = 0, length = this.typeVariables.length; i < length; i++) {
+			if (i  > 0) buffer.append(", "); //$NON-NLS-1$
+			if (this.typeVariables[i] == null) {
+				buffer.append("NULL TYPE VARIABLE"); //$NON-NLS-1$
+				continue;
+			}
+			char[] varChars = this.typeVariables[i].toString().toCharArray();
+			buffer.append(varChars, 1, varChars.length - 2);
+		}
+		buffer.append(">"); //$NON-NLS-1$
+	}
+	buffer.append("\n\textends "); //$NON-NLS-1$
+	buffer.append((this.superclass != null) ? this.superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
+
+	if (this.superInterfaces != null) {
+		if (this.superInterfaces != Binding.NO_SUPERINTERFACES) {
+			buffer.append("\n\timplements : "); //$NON-NLS-1$
+			for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+				if (i  > 0)
+					buffer.append(", "); //$NON-NLS-1$
+				buffer.append((this.superInterfaces[i] != null) ? this.superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
+			}
+		}
+	} else {
+		buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
+	}
+
+	if (enclosingType() != null) {
+		buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
+		buffer.append(enclosingType().debugName());
+	}
+
+	if (this.fields != null) {
+		if (this.fields != Binding.NO_FIELDS) {
+			buffer.append("\n/*   fields   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.fields.length; i < length; i++)
+			    buffer.append('\n').append((this.fields[i] != null) ? this.fields[i].toString() : "NULL FIELD"); //$NON-NLS-1$
+		}
+	} else {
+		buffer.append("NULL FIELDS"); //$NON-NLS-1$
+	}
+
+	if (this.methods != null) {
+		if (this.methods != Binding.NO_METHODS) {
+			buffer.append("\n/*   methods   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.methods.length; i < length; i++)
+				buffer.append('\n').append((this.methods[i] != null) ? this.methods[i].toString() : "NULL METHOD"); //$NON-NLS-1$
+		}
+	} else {
+		buffer.append("NULL METHODS"); //$NON-NLS-1$
+	}
+
+	if (this.memberTypes != null) {
+		if (this.memberTypes != Binding.NO_MEMBER_TYPES) {
+			buffer.append("\n/*   members   */"); //$NON-NLS-1$
+			for (int i = 0, length = this.memberTypes.length; i < length; i++)
+				buffer.append('\n').append((this.memberTypes[i] != null) ? this.memberTypes[i].toString() : "NULL TYPE"); //$NON-NLS-1$
+		}
+	} else {
+		buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
+	}
+
+	buffer.append("\n\n"); //$NON-NLS-1$
+	return buffer.toString();
+}
+public TypeVariableBinding[] typeVariables() {
+	return this.typeVariables != null ? this.typeVariables : Binding.NO_TYPE_VARIABLES;
+}
+void verifyMethods(MethodVerifier verifier) {
+	verifier.verify(this);
+
+	for (int i = this.memberTypes.length; --i >= 0;)
+		 ((SourceTypeBinding) this.memberTypes[i]).verifyMethods(verifier);
+}
+
+public FieldBinding[] unResolvedFields() {
+	return this.fields;
+}
+
+public void tagIndirectlyAccessibleMembers() {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=328281
+	for (int i = 0; i < this.fields.length; i++) {
+		if (!this.fields[i].isPrivate())
+			this.fields[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+	}
+	for (int i = 0; i < this.memberTypes.length; i++) {
+		if (!this.memberTypes[i].isPrivate())
+			this.memberTypes[i].modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
+	}
+	if (this.superclass.isPrivate()) 
+		if (this.superclass instanceof SourceTypeBinding)  // should always be true because private super type can only be accessed in same CU
+			((SourceTypeBinding) this.superclass).tagIndirectlyAccessibleMembers();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeCollisionException.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeCollisionException.java
new file mode 100644
index 0000000..615ea93
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeCollisionException.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+
+public class SourceTypeCollisionException extends RuntimeException {
+	private static final long serialVersionUID = 4798247636899127380L;
+
+	public ICompilationUnit[] newAnnotationProcessorUnits;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java
new file mode 100644
index 0000000..bdd7cb9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+/*
+ * Encapsulates aspects related to type variable substitution
+ */
+public interface Substitution {
+
+	/**
+	 * Returns the type substitute for a given type variable, or itself
+	 * if no substitution got performed.
+	 */
+	TypeBinding substitute(TypeVariableBinding typeVariable);
+
+	/**
+	 * Returns the lookup environment
+	 */
+	LookupEnvironment environment();
+
+	/**
+	 * Returns true for raw substitution
+	 */
+	boolean isRawSubstitution();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java
new file mode 100644
index 0000000..44c0bbe
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+/**
+ * Specific local variable location used to:
+ * - either provide emulation for outer local variables used from within innerclass constructs,
+ * - or provide emulation to enclosing instances.
+ * When it is mapping to an outer local variable, this actual outer local is accessible through
+ * the public field #actualOuterLocalVariable.
+ *
+ * Such a synthetic argument binding will be inserted in all constructors of local innertypes before
+ * the user arguments.
+ */
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class SyntheticArgumentBinding extends LocalVariableBinding {
+
+	{
+		this.tagBits |= TagBits.IsArgument;
+		this.useFlag = USED;
+	}
+
+	// if the argument is mapping to an outer local variable, this denotes the outer actual variable
+	public LocalVariableBinding actualOuterLocalVariable;
+	// if the argument has a matching synthetic field
+	public FieldBinding matchingField;
+
+	public SyntheticArgumentBinding(LocalVariableBinding actualOuterLocalVariable) {
+
+		super(
+			CharOperation.concat(TypeConstants.SYNTHETIC_OUTER_LOCAL_PREFIX, actualOuterLocalVariable.name),
+			actualOuterLocalVariable.type,
+			ClassFileConstants.AccFinal,
+			true);
+		this.actualOuterLocalVariable = actualOuterLocalVariable;
+	}
+
+	public SyntheticArgumentBinding(ReferenceBinding enclosingType) {
+
+		super(
+			CharOperation.concat(
+				TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX,
+				String.valueOf(enclosingType.depth()).toCharArray()),
+			enclosingType,
+			ClassFileConstants.AccFinal,
+			true);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java
new file mode 100644
index 0000000..5983ba2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public class SyntheticFieldBinding extends FieldBinding {
+
+	public int index;
+
+	public SyntheticFieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant, int index) {
+		super(name, type, modifiers, declaringClass, constant);
+		this.index = index;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
new file mode 100644
index 0000000..14f1a88
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -0,0 +1,534 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *		IBM Corporation - initial API and implementation
+ *		Stephan Herrmann - Contribution for
+ *								bug 400710 - [1.8][compiler] synthetic access to default method generates wrong code
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class SyntheticMethodBinding extends MethodBinding {
+
+	public FieldBinding targetReadField;		// read access to a field
+	public FieldBinding targetWriteField;		// write access to a field
+	public MethodBinding targetMethod;			// method or constructor
+	public TypeBinding targetEnumType; 			// enum type
+	public LambdaExpression lambda;
+	
+	public int purpose;
+
+	// fields used to generate enum constants when too many
+	public int startIndex;
+	public int endIndex;
+
+	public final static int FieldReadAccess = 1; 		// field read
+	public final static int FieldWriteAccess = 2; 		// field write
+	public final static int SuperFieldReadAccess = 3; // super field read
+	public final static int SuperFieldWriteAccess = 4; // super field write
+	public final static int MethodAccess = 5; 		// normal method
+	public final static int ConstructorAccess = 6; 	// constructor
+	public final static int SuperMethodAccess = 7; // super method
+	public final static int BridgeMethod = 8; // bridge method
+	public final static int EnumValues = 9; // enum #values()
+	public final static int EnumValueOf = 10; // enum #valueOf(String)
+	public final static int SwitchTable = 11; // switch table method
+	public final static int TooManyEnumsConstants = 12; // too many enum constants
+	public static final int LambdaMethod = 13; // Lambda body emitted as a method.
+	public final static int ArrayConstructor = 14; // X[]::new
+	public static final int ArrayClone = 15; // X[]::clone
+    public static final int FactoryMethod = 16; // for indy call to private constructor.
+    
+	public int sourceStart = 0; // start position of the matching declaration
+	public int index; // used for sorting access methods in the class file
+	public int fakePaddedParameters = 0; // added in synthetic constructor to avoid name clash.
+
+	public SyntheticMethodBinding(FieldBinding targetField, boolean isReadAccess, boolean isSuperAccess, ReferenceBinding declaringClass) {
+
+		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
+		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+		this.selector = CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(methodId).toCharArray());
+		if (isReadAccess) {
+			this.returnType = targetField.type;
+			if (targetField.isStatic()) {
+				this.parameters = Binding.NO_PARAMETERS;
+			} else {
+				this.parameters = new TypeBinding[1];
+				this.parameters[0] = declaringSourceType;
+			}
+			this.targetReadField = targetField;
+			this.purpose = isSuperAccess ? SyntheticMethodBinding.SuperFieldReadAccess : SyntheticMethodBinding.FieldReadAccess;
+		} else {
+			this.returnType = TypeBinding.VOID;
+			if (targetField.isStatic()) {
+				this.parameters = new TypeBinding[1];
+				this.parameters[0] = targetField.type;
+			} else {
+				this.parameters = new TypeBinding[2];
+				this.parameters[0] = declaringSourceType;
+				this.parameters[1] = targetField.type;
+			}
+			this.targetWriteField = targetField;
+			this.purpose = isSuperAccess ? SyntheticMethodBinding.SuperFieldWriteAccess : SyntheticMethodBinding.FieldWriteAccess;
+		}
+		this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		this.declaringClass = declaringSourceType;
+
+		// check for method collision
+		boolean needRename;
+		do {
+			check : {
+				needRename = false;
+				// check for collision with known methods
+				long range;
+				MethodBinding[] methods = declaringSourceType.methods();
+				if ((range = ReferenceBinding.binarySearch(this.selector, methods)) >= 0) {
+					int paramCount = this.parameters.length;
+					nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+						MethodBinding method = methods[imethod];
+						if (method.parameters.length == paramCount) {
+							TypeBinding[] toMatch = method.parameters;
+							for (int i = 0; i < paramCount; i++) {
+								if (toMatch[i] != this.parameters[i]) {
+									continue nextMethod;
+								}
+							}
+							needRename = true;
+							break check;
+						}
+					}
+				}
+				// check for collision with synthetic accessors
+				if (knownAccessMethods != null) {
+					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
+						if (knownAccessMethods[i] == null) continue;
+						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && areParametersEqual(methods[i])) {
+							needRename = true;
+							break check;
+						}
+					}
+				}
+			}
+			if (needRename) { // retry with a selector postfixed by a growing methodId
+				setSelector(CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(++methodId).toCharArray()));
+			}
+		} while (needRename);
+
+		// retrieve sourceStart position for the target field for line number attributes
+		FieldDeclaration[] fieldDecls = declaringSourceType.scope.referenceContext.fields;
+		if (fieldDecls != null) {
+			for (int i = 0, max = fieldDecls.length; i < max; i++) {
+				if (fieldDecls[i].binding == targetField) {
+					this.sourceStart = fieldDecls[i].sourceStart;
+					return;
+				}
+			}
+		}
+
+	/* did not find the target field declaration - it is a synthetic one
+		public class A {
+			public class B {
+				public class C {
+					void foo() {
+						System.out.println("A.this = " + A.this);
+					}
+				}
+			}
+			public static void main(String args[]) {
+				new A().new B().new C().foo();
+			}
+		}
+	*/
+		// We now at this point - per construction - it is for sure an enclosing instance, we are going to
+		// show the target field type declaration location.
+		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
+	}
+
+	public SyntheticMethodBinding(FieldBinding targetField, ReferenceBinding declaringClass, TypeBinding enumBinding, char[] selector) {
+		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
+		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+		this.selector = selector;
+		this.returnType = declaringSourceType.scope.createArrayType(TypeBinding.INT, 1);
+		this.parameters = Binding.NO_PARAMETERS;
+		this.targetReadField = targetField;
+		this.targetEnumType = enumBinding;
+		this.purpose = SyntheticMethodBinding.SwitchTable;
+		this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		this.declaringClass = declaringSourceType;
+
+		if (declaringSourceType.isStrictfp()) {
+			this.modifiers |= ClassFileConstants.AccStrictfp;
+		}
+		// check for method collision
+		boolean needRename;
+		do {
+			check : {
+				needRename = false;
+				// check for collision with known methods
+				long range;
+				MethodBinding[] methods = declaringSourceType.methods();
+				if ((range = ReferenceBinding.binarySearch(this.selector, methods)) >= 0) {
+					int paramCount = this.parameters.length;
+					nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
+						MethodBinding method = methods[imethod];
+						if (method.parameters.length == paramCount) {
+							TypeBinding[] toMatch = method.parameters;
+							for (int i = 0; i < paramCount; i++) {
+								if (toMatch[i] != this.parameters[i]) {
+									continue nextMethod;
+								}
+							}
+							needRename = true;
+							break check;
+						}
+					}
+				}
+				// check for collision with synthetic accessors
+				if (knownAccessMethods != null) {
+					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
+						if (knownAccessMethods[i] == null) continue;
+						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && areParametersEqual(methods[i])) {
+							needRename = true;
+							break check;
+						}
+					}
+				}
+			}
+			if (needRename) { // retry with a selector postfixed by a growing methodId
+				setSelector(CharOperation.concat(selector, String.valueOf(++methodId).toCharArray()));
+			}
+		} while (needRename);
+
+		// We now at this point - per construction - it is for sure an enclosing instance, we are going to
+		// show the target field type declaration location.
+		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
+	}
+
+	public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding declaringClass) {
+
+		if (targetMethod.isConstructor()) {
+			initializeConstructorAccessor(targetMethod);
+		} else {
+			initializeMethodAccessor(targetMethod, isSuperAccess, declaringClass);
+		}
+	}
+
+	/**
+	 * Construct a bridge method
+	 */
+	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, MethodBinding targetMethod, SourceTypeBinding declaringClass) {
+
+	    this.declaringClass = declaringClass;
+	    this.selector = overridenMethodToBridge.selector;
+	    // amongst other, clear the AccGenericSignature, so as to ensure no remains of original inherited persist (101794)
+	    // also use the modifiers from the target method, as opposed to inherited one (147690)
+	    this.modifiers = (targetMethod.modifiers | ClassFileConstants.AccBridge | ClassFileConstants.AccSynthetic) & ~(ClassFileConstants.AccSynchronized | ClassFileConstants.AccAbstract | ClassFileConstants.AccNative  | ClassFileConstants.AccFinal | ExtraCompilerModifiers.AccGenericSignature);
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+	    this.returnType = overridenMethodToBridge.returnType;
+	    this.parameters = overridenMethodToBridge.parameters;
+	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
+	    this.targetMethod = targetMethod;
+	    this.purpose = SyntheticMethodBinding.BridgeMethod;
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+	}
+
+	/**
+	 * Construct enum special methods: values or valueOf methods
+	 */
+	public SyntheticMethodBinding(SourceTypeBinding declaringEnum, char[] selector) {
+	    this.declaringClass = declaringEnum;
+	    this.selector = selector;
+	    this.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		LookupEnvironment environment = declaringEnum.scope.environment();
+	    this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		if (selector == TypeConstants.VALUES) {
+		    this.returnType = environment.createArrayType(environment.convertToParameterizedType(declaringEnum), 1);
+		    this.parameters = Binding.NO_PARAMETERS;
+		    this.purpose = SyntheticMethodBinding.EnumValues;
+		} else if (selector == TypeConstants.VALUEOF) {
+		    this.returnType = environment.convertToParameterizedType(declaringEnum);
+		    this.parameters = new TypeBinding[]{ declaringEnum.scope.getJavaLangString() };
+		    this.purpose = SyntheticMethodBinding.EnumValueOf;
+		}
+		SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+		if (declaringEnum.isStrictfp()) {
+			this.modifiers |= ClassFileConstants.AccStrictfp;
+		}
+	}
+	
+	/**
+	 * Construct enum special methods: values or valueOf methods
+	 */
+	public SyntheticMethodBinding(SourceTypeBinding declaringEnum, int startIndex, int endIndex) {
+		this.declaringClass = declaringEnum;
+		SyntheticMethodBinding[] knownAccessMethods = declaringEnum.syntheticMethods();
+		this.index = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(TypeConstants.SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX).append(this.index);
+		this.selector = String.valueOf(buffer).toCharArray(); 
+		this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		this.purpose = SyntheticMethodBinding.TooManyEnumsConstants;
+		this.thrownExceptions = Binding.NO_EXCEPTIONS;
+		this.returnType = TypeBinding.VOID;
+		this.parameters = Binding.NO_PARAMETERS;
+		this.startIndex = startIndex;
+		this.endIndex = endIndex;
+	}
+
+	// Create a synthetic method that will simply call the super classes method.
+	// Used when a public method is inherited from a non-public class into a public class.
+	// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658
+	// Also applies for inherited default methods with the same visibility issue.
+	// See https://bugs.eclipse.org/400710
+	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, SourceTypeBinding declaringClass) {
+
+	    this.declaringClass = declaringClass;
+	    this.selector = overridenMethodToBridge.selector;
+	    // amongst other, clear the AccGenericSignature, so as to ensure no remains of original inherited persist (101794)
+	    this.modifiers = (overridenMethodToBridge.modifiers | ClassFileConstants.AccBridge | ClassFileConstants.AccSynthetic) & ~(ClassFileConstants.AccSynchronized | ClassFileConstants.AccAbstract | ClassFileConstants.AccNative  | ClassFileConstants.AccFinal | ExtraCompilerModifiers.AccGenericSignature);
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+	    this.returnType = overridenMethodToBridge.returnType;
+	    this.parameters = overridenMethodToBridge.parameters;
+	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
+	    this.targetMethod = overridenMethodToBridge;
+	    this.purpose = SyntheticMethodBinding.SuperMethodAccess;
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+	}
+
+	public SyntheticMethodBinding(int purpose, ArrayBinding arrayType, char [] selector, SourceTypeBinding declaringClass) {
+	    this.declaringClass = declaringClass;
+	    this.selector = selector;
+	    this.modifiers = ClassFileConstants.AccSynthetic | ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+	    this.returnType = arrayType;
+	    this.parameters = new TypeBinding[] { purpose == SyntheticMethodBinding.ArrayConstructor ? TypeBinding.INT : (TypeBinding) arrayType};
+	    this.thrownExceptions = Binding.NO_EXCEPTIONS;
+	    this.purpose = purpose;
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+	}
+
+	public SyntheticMethodBinding(LambdaExpression lambda, char [] lambdaName, SourceTypeBinding declaringClass) {
+		this.lambda = lambda;
+	    this.declaringClass = declaringClass;
+	    this.selector = lambdaName;
+	    this.modifiers = lambda.binding.modifiers;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved) | (lambda.binding.tagBits & TagBits.HasParameterAnnotations);
+	    this.returnType = lambda.binding.returnType;
+	    this.parameters = lambda.binding.parameters;
+	    this.thrownExceptions = lambda.binding.thrownExceptions;
+	    this.purpose = SyntheticMethodBinding.LambdaMethod;
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+	}
+
+	public SyntheticMethodBinding(MethodBinding privateConstructor, MethodBinding publicConstructor, char[] selector, TypeBinding[] enclosingInstances, SourceTypeBinding declaringClass) {
+	    this.declaringClass = declaringClass;
+	    this.selector = selector;
+	    this.modifiers = ClassFileConstants.AccSynthetic | ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+	    this.returnType = publicConstructor.declaringClass;
+	
+	    int realParametersLength = privateConstructor.parameters.length;
+	    int enclosingInstancesLength = enclosingInstances.length;
+	    int parametersLength =  enclosingInstancesLength + realParametersLength;
+	    this.parameters = new TypeBinding[parametersLength];
+	    System.arraycopy(enclosingInstances, 0, this.parameters, 0, enclosingInstancesLength);
+	    System.arraycopy(privateConstructor.parameters, 0, this.parameters, enclosingInstancesLength, realParametersLength);
+	    this.fakePaddedParameters = publicConstructor.parameters.length - realParametersLength;
+	    
+	    this.thrownExceptions = publicConstructor.thrownExceptions;
+	    this.purpose = SyntheticMethodBinding.FactoryMethod;
+	    this.targetMethod = publicConstructor;
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+	}
+
+	/**
+	 * An constructor accessor is a constructor with an extra argument (declaringClass), in case of
+	 * collision with an existing constructor, then add again an extra argument (declaringClass again).
+	 */
+	 public void initializeConstructorAccessor(MethodBinding accessedConstructor) {
+
+		this.targetMethod = accessedConstructor;
+		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccSynthetic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		SourceTypeBinding sourceType = (SourceTypeBinding) accessedConstructor.declaringClass;
+		SyntheticMethodBinding[] knownSyntheticMethods = sourceType.syntheticMethods();
+		this.index = knownSyntheticMethods == null ? 0 : knownSyntheticMethods.length;
+
+		this.selector = accessedConstructor.selector;
+		this.returnType = accessedConstructor.returnType;
+		this.purpose = SyntheticMethodBinding.ConstructorAccess;
+		final int parametersLength = accessedConstructor.parameters.length;
+		this.parameters = new TypeBinding[parametersLength + 1];
+		System.arraycopy(
+			accessedConstructor.parameters,
+			0,
+			this.parameters,
+			0,
+			parametersLength);
+		this.parameters[parametersLength] =
+			accessedConstructor.declaringClass;
+		this.thrownExceptions = accessedConstructor.thrownExceptions;
+		this.declaringClass = sourceType;
+
+		// check for method collision
+		boolean needRename;
+		do {
+			check : {
+				needRename = false;
+				// check for collision with known methods
+				MethodBinding[] methods = sourceType.methods();
+				for (int i = 0, length = methods.length; i < length; i++) {
+					if (CharOperation.equals(this.selector, methods[i].selector) && areParameterErasuresEqual(methods[i])) {
+						needRename = true;
+						break check;
+					}
+				}
+				// check for collision with synthetic accessors
+				if (knownSyntheticMethods != null) {
+					for (int i = 0, length = knownSyntheticMethods.length; i < length; i++) {
+						if (knownSyntheticMethods[i] == null)
+							continue;
+						if (CharOperation.equals(this.selector, knownSyntheticMethods[i].selector) && areParameterErasuresEqual(knownSyntheticMethods[i])) {
+							needRename = true;
+							break check;
+						}
+					}
+				}
+			}
+			if (needRename) { // retry with a new extra argument
+				int length = this.parameters.length;
+				System.arraycopy(
+					this.parameters,
+					0,
+					this.parameters = new TypeBinding[length + 1],
+					0,
+					length);
+				this.parameters[length] = this.declaringClass;
+			}
+		} while (needRename);
+
+		// retrieve sourceStart position for the target method for line number attributes
+		AbstractMethodDeclaration[] methodDecls =
+			sourceType.scope.referenceContext.methods;
+		if (methodDecls != null) {
+			for (int i = 0, length = methodDecls.length; i < length; i++) {
+				if (methodDecls[i].binding == accessedConstructor) {
+					this.sourceStart = methodDecls[i].sourceStart;
+					return;
+				}
+			}
+		}
+	}
+
+	/**
+	 * An method accessor is a method with an access$N selector, where N is incremented in case of collisions.
+	 */
+	public void initializeMethodAccessor(MethodBinding accessedMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
+
+		this.targetMethod = accessedMethod;
+		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
+		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+		SourceTypeBinding declaringSourceType = (SourceTypeBinding) receiverType;
+		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;
+
+		this.selector = CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(methodId).toCharArray());
+		this.returnType = accessedMethod.returnType;
+		this.purpose = isSuperAccess ? SyntheticMethodBinding.SuperMethodAccess : SyntheticMethodBinding.MethodAccess;
+
+		if (accessedMethod.isStatic()) {
+			this.parameters = accessedMethod.parameters;
+		} else {
+			this.parameters = new TypeBinding[accessedMethod.parameters.length + 1];
+			this.parameters[0] = declaringSourceType;
+			System.arraycopy(accessedMethod.parameters, 0, this.parameters, 1, accessedMethod.parameters.length);
+		}
+		this.thrownExceptions = accessedMethod.thrownExceptions;
+		this.declaringClass = declaringSourceType;
+
+		// check for method collision
+		boolean needRename;
+		do {
+			check : {
+				needRename = false;
+				// check for collision with known methods
+				MethodBinding[] methods = declaringSourceType.methods();
+				for (int i = 0, length = methods.length; i < length; i++) {
+					if (CharOperation.equals(this.selector, methods[i].selector) && areParameterErasuresEqual(methods[i])) {
+						needRename = true;
+						break check;
+					}
+				}
+				// check for collision with synthetic accessors
+				if (knownAccessMethods != null) {
+					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
+						if (knownAccessMethods[i] == null) continue;
+						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && areParameterErasuresEqual(knownAccessMethods[i])) {
+							needRename = true;
+							break check;
+						}
+					}
+				}
+			}
+			if (needRename) { // retry with a selector & a growing methodId
+				setSelector(CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(++methodId).toCharArray()));
+			}
+		} while (needRename);
+
+		// retrieve sourceStart position for the target method for line number attributes
+		AbstractMethodDeclaration[] methodDecls = declaringSourceType.scope.referenceContext.methods;
+		if (methodDecls != null) {
+			for (int i = 0, length = methodDecls.length; i < length; i++) {
+				if (methodDecls[i].binding == accessedMethod) {
+					this.sourceStart = methodDecls[i].sourceStart;
+					return;
+				}
+			}
+		}
+	}
+
+	protected boolean isConstructorRelated() {
+		return this.purpose == SyntheticMethodBinding.ConstructorAccess;
+	}
+	
+	public LambdaExpression sourceLambda() {
+		return this.lambda;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
new file mode 100644
index 0000000..20d3d7e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 392099 - [1.8][compiler][null] Apply null annotation on types for null analysis
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+
+public interface TagBits {
+
+	// Tag bits in the tagBits int of every TypeBinding
+	long IsArrayType = ASTNode.Bit1;
+	long IsBaseType = ASTNode.Bit2;
+	long IsNestedType = ASTNode.Bit3;
+	long IsMemberType = ASTNode.Bit4;
+	long ContainsNestedTypeReferences = ASTNode.Bit12; // method/parameterized type binding
+	long MemberTypeMask = IsNestedType | IsMemberType | ContainsNestedTypeReferences;
+	long IsLocalType = ASTNode.Bit5;
+	long LocalTypeMask = IsNestedType | IsLocalType | ContainsNestedTypeReferences;
+	long IsAnonymousType = ASTNode.Bit6;
+	long AnonymousTypeMask = LocalTypeMask | IsAnonymousType | ContainsNestedTypeReferences;
+	long IsBinaryBinding = ASTNode.Bit7;
+
+	// set for all bindings either representing a missing type (type), or directly referencing a missing type (field/method/variable)
+	long HasMissingType = ASTNode.Bit8;
+
+	// for method
+	long HasUncheckedTypeArgumentForBoundCheck = ASTNode.Bit9;
+	
+	// local variable
+	long NotInitialized = ASTNode.Bit9;
+	
+	// local variable
+	long ForcedToBeRawType = ASTNode.Bit10;
+
+	// set when method has argument(s) that couldn't be resolved
+	long HasUnresolvedArguments = ASTNode.Bit10;
+	
+	// for the type cycle hierarchy check used by ClassScope
+	long BeginHierarchyCheck = ASTNode.Bit9;  // type
+	long EndHierarchyCheck = ASTNode.Bit10; // type
+	long PauseHierarchyCheck = ASTNode.Bit20; // type
+	long HasParameterAnnotations = ASTNode.Bit11; // method/constructor
+
+
+	// test bit to see if default abstract methods were computed
+	long KnowsDefaultAbstractMethods = ASTNode.Bit11; // type
+
+	long IsArgument = ASTNode.Bit11; // local
+	long ClearPrivateModifier = ASTNode.Bit10; // constructor binding
+	
+	// for java 7
+	long IsEffectivelyFinal = ASTNode.Bit12; // local
+	long MultiCatchParameter = ASTNode.Bit13; // local
+	long IsResource = ASTNode.Bit14; // local
+
+	// have implicit null annotations been collected (inherited(?) & default)?
+	long IsNullnessKnown = ASTNode.Bit13; // method
+
+	// test bits to see if parts of binary types are faulted
+	long AreFieldsSorted = ASTNode.Bit13;
+	long AreFieldsComplete = ASTNode.Bit14; // sorted and all resolved
+	long AreMethodsSorted = ASTNode.Bit15;
+	long AreMethodsComplete = ASTNode.Bit16; // sorted and all resolved
+
+	// test bit to avoid asking a type for a member type (includes inherited member types)
+	long HasNoMemberTypes = ASTNode.Bit17;
+
+	// test bit to identify if the type's hierarchy is inconsistent
+	long HierarchyHasProblems = ASTNode.Bit18;
+
+	// test bit to identify if the type's type variables have been connected
+	long TypeVariablesAreConnected = ASTNode.Bit19;
+
+	// set for parameterized type with successful bound check
+	long PassedBoundCheck = ASTNode.Bit23;
+
+	// set for parameterized type NOT of the form X<?,?>
+	long IsBoundParameterizedType = ASTNode.Bit24;
+
+	// used by BinaryTypeBinding
+	long HasUnresolvedTypeVariables = ASTNode.Bit25;
+	long HasUnresolvedSuperclass = ASTNode.Bit26;
+	long HasUnresolvedSuperinterfaces = ASTNode.Bit27;
+	long HasUnresolvedEnclosingType = ASTNode.Bit28;
+	long HasUnresolvedMemberTypes = ASTNode.Bit29;
+
+	long HasTypeVariable = ASTNode.Bit30; // set either for type variables (direct) or parameterized types indirectly referencing type variables
+	long HasDirectWildcard = ASTNode.Bit31; // set for parameterized types directly referencing wildcards
+
+	// for the annotation cycle hierarchy check used by ClassScope
+	long BeginAnnotationCheck = ASTNode.Bit32L;
+	long EndAnnotationCheck = ASTNode.Bit33L;
+
+	// standard annotations
+	// 9-bits for targets
+	long AnnotationResolved = ASTNode.Bit34L;
+	long DeprecatedAnnotationResolved = ASTNode.Bit35L;
+	long AnnotationTarget = ASTNode.Bit36L; // @Target({}) only sets this bit
+	long AnnotationForType = ASTNode.Bit37L;
+	long AnnotationForField = ASTNode.Bit38L;
+	long AnnotationForMethod = ASTNode.Bit39L;
+	long AnnotationForParameter = ASTNode.Bit40L;
+	long AnnotationForConstructor = ASTNode.Bit41L;
+	long AnnotationForLocalVariable = ASTNode.Bit42L;
+	long AnnotationForAnnotationType = ASTNode.Bit43L;
+	long AnnotationForPackage = ASTNode.Bit44L;
+	long AnnotationForTypeUse = ASTNode.Bit54L;
+	long AnnotationForTypeParameter = ASTNode.Bit55L;
+	long SE7AnnotationTargetMASK = AnnotationForType | AnnotationForField | AnnotationForMethod
+				| AnnotationForParameter | AnnotationForConstructor | AnnotationForLocalVariable
+				| AnnotationForAnnotationType | AnnotationForPackage;
+	long AnnotationTargetMASK = SE7AnnotationTargetMASK | AnnotationTarget
+				| AnnotationForTypeUse | AnnotationForTypeParameter;
+	// 2-bits for retention (should check (tagBits & RetentionMask) == RuntimeRetention
+	long AnnotationSourceRetention = ASTNode.Bit45L;
+	long AnnotationClassRetention = ASTNode.Bit46L;
+	long AnnotationRuntimeRetention = AnnotationSourceRetention | AnnotationClassRetention;
+	long AnnotationRetentionMASK = AnnotationSourceRetention | AnnotationClassRetention | AnnotationRuntimeRetention;
+	// marker annotations
+	long AnnotationDeprecated = ASTNode.Bit47L;
+	long AnnotationDocumented = ASTNode.Bit48L;
+	long AnnotationInherited = ASTNode.Bit49L;
+	long AnnotationOverride = ASTNode.Bit50L;
+	long AnnotationSuppressWarnings = ASTNode.Bit51L;
+	/** @since 3.7 - java 7 safe vargs invocation */
+	long AnnotationSafeVarargs = ASTNode.Bit52L;
+	/** @since 3.7 - java 7 MethodHandle.invokeExact(..)/invokeGeneric(..)*/
+	long AnnotationPolymorphicSignature = ASTNode.Bit53L;
+	/** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */
+	long AnnotationNullable = ASTNode.Bit56L;
+	/** @since 3.8 null annotation for MethodBinding or LocalVariableBinding (argument): */
+	long AnnotationNonNull = ASTNode.Bit57L;
+	/** @since 3.8 null-default annotation for PackageBinding or TypeBinding or MethodBinding: */
+	long AnnotationNonNullByDefault = ASTNode.Bit58L;
+	/** @since 3.8 canceling null-default annotation for PackageBinding or TypeBinding or MethodBinding: */
+	long AnnotationNullUnspecifiedByDefault = ASTNode.Bit59L;
+	/** From Java 8 */
+	long AnnotationFunctionalInterface = ASTNode.Bit60L;
+
+
+	long AllStandardAnnotationsMask =
+				  AnnotationTargetMASK
+				| AnnotationRetentionMASK
+				| AnnotationDeprecated
+				| AnnotationDocumented
+				| AnnotationInherited
+				| AnnotationOverride
+				| AnnotationSuppressWarnings
+				| AnnotationSafeVarargs
+				| AnnotationPolymorphicSignature
+				| AnnotationNullable
+				| AnnotationNonNull
+				| AnnotationNonNullByDefault
+				| AnnotationNullUnspecifiedByDefault;
+	long AnnotationNullMASK = AnnotationNullable | AnnotationNonNull;
+
+	long DefaultValueResolved = ASTNode.Bit60L;
+
+	// set when type contains non-private constructor(s)
+	long HasNonPrivateConstructor = ASTNode.Bit61L;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
new file mode 100644
index 0000000..0cc0c81
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -0,0 +1,1278 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *      Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for
+ *								bug 317046 - Exception during debugging when hover mouse over a field
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *      Jesper S Moller <jesper@selskabet.org> -  Contributions for
+ *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+/*
+ * Not all fields defined by this type (& its subclasses) are initialized when it is created.
+ * Some are initialized only when needed.
+ *
+ * Accessors have been provided for some public fields so all TypeBindings have the same API...
+ * but access public fields directly whenever possible.
+ * Non-public fields have accessors which should be used everywhere you expect the field to be initialized.
+ *
+ * null is NOT a valid value for a non-public field... it just means the field is not initialized.
+ */
+abstract public class TypeBinding extends Binding {
+
+	public int id = TypeIds.NoId;
+	public long tagBits = 0; // See values in the interface TagBits below
+
+
+	/** Base type definitions */
+	public final static BaseTypeBinding INT = new BaseTypeBinding(
+			TypeIds.T_int, TypeConstants.INT, new char[] { 'I' });
+
+	public final static BaseTypeBinding BYTE = new BaseTypeBinding(
+			TypeIds.T_byte, TypeConstants.BYTE, new char[] { 'B' });
+
+	public final static BaseTypeBinding SHORT = new BaseTypeBinding(
+			TypeIds.T_short, TypeConstants.SHORT, new char[] { 'S' });
+
+	public final static BaseTypeBinding CHAR = new BaseTypeBinding(
+			TypeIds.T_char, TypeConstants.CHAR, new char[] { 'C' });
+
+	public final static BaseTypeBinding LONG = new BaseTypeBinding(
+			TypeIds.T_long, TypeConstants.LONG, new char[] { 'J' });
+
+	public final static BaseTypeBinding FLOAT = new BaseTypeBinding(
+			TypeIds.T_float, TypeConstants.FLOAT, new char[] { 'F' });
+
+	public final static BaseTypeBinding DOUBLE = new BaseTypeBinding(
+			TypeIds.T_double, TypeConstants.DOUBLE, new char[] { 'D' });
+
+	public final static BaseTypeBinding BOOLEAN = new BaseTypeBinding(
+			TypeIds.T_boolean, TypeConstants.BOOLEAN, new char[] { 'Z' });
+
+	public final static BaseTypeBinding NULL = new BaseTypeBinding(
+			TypeIds.T_null, TypeConstants.NULL, new char[] { 'N' }); //N stands for null even if it is never internally used
+
+	public final static BaseTypeBinding VOID = new BaseTypeBinding(
+			TypeIds.T_void, TypeConstants.VOID, new char[] { 'V' });
+
+/**
+ * Match a well-known type id to its binding
+ */
+public static final TypeBinding wellKnownType(Scope scope, int id) {
+	switch (id) {
+	case TypeIds.T_boolean:
+		return TypeBinding.BOOLEAN;
+	case TypeIds.T_byte:
+		return TypeBinding.BYTE;
+	case TypeIds.T_char:
+		return TypeBinding.CHAR;
+	case TypeIds.T_short:
+		return TypeBinding.SHORT;
+	case TypeIds.T_double:
+		return TypeBinding.DOUBLE;
+	case TypeIds.T_float:
+		return TypeBinding.FLOAT;
+	case TypeIds.T_int:
+		return TypeBinding.INT;
+	case TypeIds.T_long:
+		return TypeBinding.LONG;
+	case TypeIds.T_JavaLangObject:
+		return scope.getJavaLangObject();
+	case TypeIds.T_JavaLangString:
+		return scope.getJavaLangString();
+	default:
+		return null;
+	}
+}
+
+/* Answer true if the receiver can be instantiated
+ */
+public boolean canBeInstantiated() {
+	return !isBaseType();
+}
+
+/**
+ * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
+ */
+public TypeBinding capture(Scope scope, int position) {
+	return this;
+}
+
+/**
+ * In case of problems, returns the closest match found. It may not be perfect match, but the
+ * result of a best effort to improve fault-tolerance.
+ */
+public TypeBinding closestMatch() {
+	return this; // by default no better type
+}
+
+/**
+ * Iterate through the type components to collect instances of leaf missing types
+ * @param missingTypes
+ * @return missing types
+ */
+public List collectMissingTypes(List missingTypes) {
+	return missingTypes;
+}
+
+/**
+ * Collect the substitutes into a map for certain type variables inside the receiver type
+ * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+ * Constraints:
+ *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
+ *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
+ *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
+ */
+public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
+	// no substitute by default
+}
+
+/**
+ *  Answer the receiver's constant pool name.
+ *  NOTE: This method should only be used during/after code gen.
+ *  e.g. 'java/lang/Object'
+ */
+public abstract char[] constantPoolName();
+
+public String debugName() {
+	return new String(readableName());
+}
+
+/*
+ * Answer the receiver's dimensions - 0 for non-array types
+ */
+public int dimensions() {
+	return 0;
+}
+
+/* Answer the receiver's enclosing type... null if the receiver is a top level type.
+ */
+public ReferenceBinding enclosingType() {
+	return null;
+}
+
+public TypeBinding erasure() {
+	return this;
+}
+
+/**
+ * Find supertype which originates from a given well-known type, or null if not found
+ * (using id avoids triggering the load of well-known type: 73740)
+ * NOTE: only works for erasures of well-known types, as random other types may share
+ * same id though being distincts.
+ * @see TypeIds
+ */
+public ReferenceBinding findSuperTypeOriginatingFrom(int wellKnownOriginalID, boolean originalIsClass) {
+
+	if (!(this instanceof ReferenceBinding)) return null;
+	ReferenceBinding reference = (ReferenceBinding) this;
+
+    // do not allow type variables to match with erasures for free
+    if (reference.id == wellKnownOriginalID || (original().id == wellKnownOriginalID)) return reference;
+
+    ReferenceBinding currentType = reference;
+    // iterate superclass to avoid recording interfaces if searched supertype is class
+    if (originalIsClass) {
+		while ((currentType = currentType.superclass()) != null) {
+			if (currentType.id == wellKnownOriginalID)
+				return currentType;
+			if (currentType.original().id == wellKnownOriginalID)
+				return currentType;
+		}
+		return null;
+    }
+	ReferenceBinding[] interfacesToVisit = null;
+	int nextPosition = 0;
+	do {
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			if (interfacesToVisit == null) {
+				interfacesToVisit = itsInterfaces;
+				nextPosition = interfacesToVisit.length;
+			} else {
+				int itsLength = itsInterfaces.length;
+				if (nextPosition + itsLength >= interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+				nextInterface : for (int a = 0; a < itsLength; a++) {
+					ReferenceBinding next = itsInterfaces[a];
+					for (int b = 0; b < nextPosition; b++)
+						if (next == interfacesToVisit[b]) continue nextInterface;
+					interfacesToVisit[nextPosition++] = next;
+				}
+			}
+		}
+	} while ((currentType = currentType.superclass()) != null);
+
+	for (int i = 0; i < nextPosition; i++) {
+		currentType = interfacesToVisit[i];
+		if (currentType.id == wellKnownOriginalID)
+			return currentType;
+		if (currentType.original().id == wellKnownOriginalID)
+			return currentType;
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			int itsLength = itsInterfaces.length;
+			if (nextPosition + itsLength >= interfacesToVisit.length)
+				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+			nextInterface : for (int a = 0; a < itsLength; a++) {
+				ReferenceBinding next = itsInterfaces[a];
+				for (int b = 0; b < nextPosition; b++)
+					if (next == interfacesToVisit[b]) continue nextInterface;
+				interfacesToVisit[nextPosition++] = next;
+			}
+		}
+	}
+	return null;
+}
+
+/**
+ * Find supertype which originates from a given type, or null if not found
+ */
+public TypeBinding findSuperTypeOriginatingFrom(TypeBinding otherType) {
+	if (this == otherType) return this;
+	if (otherType == null) return null;
+	switch(kind()) {
+		case Binding.ARRAY_TYPE :
+			ArrayBinding arrayType = (ArrayBinding) this;
+			int otherDim = otherType.dimensions();
+			if (arrayType.dimensions != otherDim) {
+				switch(otherType.id) {
+					case TypeIds.T_JavaLangObject :
+					case TypeIds.T_JavaIoSerializable :
+					case TypeIds.T_JavaLangCloneable :
+						return otherType;
+				}
+				if (otherDim < arrayType.dimensions && otherType.leafComponentType().id == TypeIds.T_JavaLangObject) {
+					return otherType; // X[][] has Object[] as an implicit supertype
+				}
+				return null;
+			}
+			if (!(arrayType.leafComponentType instanceof ReferenceBinding)) return null;
+			TypeBinding leafSuperType = arrayType.leafComponentType.findSuperTypeOriginatingFrom(otherType.leafComponentType());
+			if (leafSuperType == null) return null;
+			return arrayType.environment().createArrayType(leafSuperType, arrayType.dimensions);
+
+		case Binding.TYPE_PARAMETER :
+		    if (isCapture()) {
+		    	CaptureBinding capture = (CaptureBinding) this;
+		    	TypeBinding captureBound = capture.firstBound;
+		    	if (captureBound instanceof ArrayBinding) {
+		    		TypeBinding match = captureBound.findSuperTypeOriginatingFrom(otherType);
+		    		if (match != null) return match;
+		    	}
+		    }
+			//$FALL-THROUGH$
+		case Binding.TYPE :
+		case Binding.PARAMETERIZED_TYPE :
+		case Binding.GENERIC_TYPE :
+		case Binding.RAW_TYPE :
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE:
+		    // do not allow type variables/intersection types to match with erasures for free
+			otherType = otherType.original();
+		    if (this == otherType)
+		    	return this;
+		    if (original() == otherType)
+		    	return this;
+		    ReferenceBinding currentType = (ReferenceBinding)this;
+		    if (!otherType.isInterface()) {
+				while ((currentType = currentType.superclass()) != null) {
+					if (currentType == otherType)
+						return currentType;
+					if (currentType.original() == otherType)
+						return currentType;
+				}
+				return null;
+		    }
+			ReferenceBinding[] interfacesToVisit = null;
+			int nextPosition = 0;
+			do {
+				ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					if (interfacesToVisit == null) {
+						interfacesToVisit = itsInterfaces;
+						nextPosition = interfacesToVisit.length;
+					} else {
+						int itsLength = itsInterfaces.length;
+						if (nextPosition + itsLength >= interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+						nextInterface : for (int a = 0; a < itsLength; a++) {
+							ReferenceBinding next = itsInterfaces[a];
+							for (int b = 0; b < nextPosition; b++)
+								if (next == interfacesToVisit[b]) continue nextInterface;
+							interfacesToVisit[nextPosition++] = next;
+						}
+					}
+				}
+			} while ((currentType = currentType.superclass()) != null);
+
+			for (int i = 0; i < nextPosition; i++) {
+				currentType = interfacesToVisit[i];
+				if (currentType == otherType)
+					return currentType;
+				if (currentType.original() == otherType)
+					return currentType;
+				ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+					int itsLength = itsInterfaces.length;
+					if (nextPosition + itsLength >= interfacesToVisit.length)
+						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+					nextInterface : for (int a = 0; a < itsLength; a++) {
+						ReferenceBinding next = itsInterfaces[a];
+						for (int b = 0; b < nextPosition; b++)
+							if (next == interfacesToVisit[b]) continue nextInterface;
+						interfacesToVisit[nextPosition++] = next;
+					}
+				}
+			}
+	}
+	return null;
+}
+
+/**
+ * Returns the type to use for generic cast, or null if none required
+ */
+public TypeBinding genericCast(TypeBinding targetType) {
+	if (this == targetType) 
+		return null;
+	TypeBinding targetErasure = targetType.erasure();
+	// type var get replaced by upper bound
+	if (erasure().findSuperTypeOriginatingFrom(targetErasure) != null) 
+		return null;
+	return targetErasure;
+}
+
+/**
+ * Answer the receiver classfile signature.
+ * Arrays & base types do not distinguish between signature() & constantPoolName().
+ * NOTE: This method should only be used during/after code gen.
+ */
+public char[] genericTypeSignature() {
+	return signature();
+}
+
+/**
+ * Return the supertype which would erase as a subtype of a given declaring class.
+ * If the receiver is already erasure compatible, then it will returned. If not, then will return the alternate lowest
+ * upper bound compatible with declaring class.
+ * NOTE: the declaringClass is already know to be compatible with the receiver
+ * @param declaringClass to look for
+ * @return the lowest erasure compatible type (considering alternate bounds)
+ */
+public TypeBinding getErasureCompatibleType(TypeBinding declaringClass) {
+	switch(kind()) {
+		case Binding.TYPE_PARAMETER :
+			TypeVariableBinding variable = (TypeVariableBinding) this;
+			if (variable.erasure().findSuperTypeOriginatingFrom(declaringClass) != null) {
+				return this; // no need for alternate receiver type
+			}
+			if (variable.superclass != null && variable.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
+				return variable.superclass.getErasureCompatibleType(declaringClass);
+			}
+			for (int i = 0, otherLength = variable.superInterfaces.length; i < otherLength; i++) {
+				ReferenceBinding superInterface = variable.superInterfaces[i];
+				if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
+					return superInterface.getErasureCompatibleType(declaringClass);
+				}
+			}
+			return this; // only occur if passed null declaringClass for arraylength
+		case Binding.INTERSECTION_TYPE :
+			WildcardBinding intersection = (WildcardBinding) this;
+			if (intersection.erasure().findSuperTypeOriginatingFrom(declaringClass) != null) {
+				return this; // no need for alternate receiver type
+			}
+			if (intersection.superclass != null && intersection.superclass.findSuperTypeOriginatingFrom(declaringClass) != null) {
+				return intersection.superclass.getErasureCompatibleType(declaringClass);
+			}
+			for (int i = 0, otherLength = intersection.superInterfaces.length; i < otherLength; i++) {
+				ReferenceBinding superInterface = intersection.superInterfaces[i];
+				if (superInterface.findSuperTypeOriginatingFrom(declaringClass) != null) {
+					return superInterface.getErasureCompatibleType(declaringClass);
+				}
+			}
+			return this; // only occur if passed null declaringClass for arraylength
+		default :
+			return this;
+	}
+}
+
+public abstract PackageBinding getPackage();
+
+void initializeForStaticImports() {
+	// only applicable to source types
+}
+
+public boolean isAnnotationType() {
+	return false;
+}
+
+public final boolean isAnonymousType() {
+	return (this.tagBits & TagBits.IsAnonymousType) != 0;
+}
+
+/* Answer true if the receiver is an array
+ */
+public final boolean isArrayType() {
+	return (this.tagBits & TagBits.IsArrayType) != 0;
+}
+
+/* Answer true if the receiver is a base type
+ */
+public final boolean isBaseType() {
+	return (this.tagBits & TagBits.IsBaseType) != 0;
+}
+
+/* Answer true if the receiver is a primitive type or a boxed primitive type
+ */
+public final boolean isPrimitiveOrBoxedPrimitiveType() {
+	if ((this.tagBits & TagBits.IsBaseType) != 0)
+		return true;
+	switch (this.id) {
+		case TypeIds.T_JavaLangBoolean :
+		case TypeIds.T_JavaLangByte :
+		case TypeIds.T_JavaLangCharacter :
+		case TypeIds.T_JavaLangShort :
+		case TypeIds.T_JavaLangDouble :
+		case TypeIds.T_JavaLangFloat :
+		case TypeIds.T_JavaLangInteger :
+		case TypeIds.T_JavaLangLong :
+			return true;
+		default: 
+			return false;
+	}
+}
+
+/**
+ *  Returns true if parameterized type AND not of the form List<?>
+ */
+public boolean isBoundParameterizedType() {
+	return (this.tagBits & TagBits.IsBoundParameterizedType) != 0;
+}
+
+/**
+ * Returns true if the type is the capture of some wildcard
+ */
+public boolean isCapture() {
+	return false;
+}
+
+public boolean isClass() {
+	return false;
+}
+
+/* Answer true if the receiver type can be assigned to the argument type (right)
+ */
+public boolean isCompatibleWith(TypeBinding right) {
+	return isCompatibleWith(right, null); // delegate from the old signature to the new implementation:
+}
+// version that allows to capture a type bound using 'scope':
+public abstract boolean isCompatibleWith(TypeBinding right, /*@Nullable*/ Scope scope);
+
+public boolean isEnum() {
+	return false;
+}
+
+/**
+ * Returns true if a type is identical to another one,
+ * or for generic types, true if compared to its raw type.
+ */
+public boolean isEquivalentTo(TypeBinding otherType) {
+	if (this == otherType)
+		return true;
+	if (otherType == null)
+		return false;
+	switch (otherType.kind()) {
+		case Binding.WILDCARD_TYPE :
+		case Binding.INTERSECTION_TYPE :
+			return ((WildcardBinding) otherType).boundCheck(this);
+	}
+	return false;
+}
+
+public boolean isGenericType() {
+	return false;
+}
+
+/* Answer true if the receiver's hierarchy has problems (always false for arrays & base types)
+ */
+public final boolean isHierarchyInconsistent() {
+	return (this.tagBits & TagBits.HierarchyHasProblems) != 0;
+}
+
+public boolean isInterface() {
+	return false;
+}
+
+public boolean isFunctionalInterface() {
+	return false;
+}
+
+/**
+ * Returns true if the current type denotes an intersection type: Number & Comparable<?>
+ */
+public boolean isIntersectionType() {
+	return false;
+}
+
+public final boolean isLocalType() {
+	return (this.tagBits & TagBits.IsLocalType) != 0;
+}
+
+public final boolean isMemberType() {
+	return (this.tagBits & TagBits.IsMemberType) != 0;
+}
+
+public final boolean isNestedType() {
+	return (this.tagBits & TagBits.IsNestedType) != 0;
+}
+
+public final boolean isNumericType() {
+	switch (this.id) {
+	case TypeIds.T_int:
+	case TypeIds.T_float:
+	case TypeIds.T_double:
+	case TypeIds.T_short:
+	case TypeIds.T_byte:
+	case TypeIds.T_long:
+	case TypeIds.T_char:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * Returns true if the type is parameterized, e.g. List<String>.
+ * Note that some instances of ParameterizedTypeBinding have no arguments, like for non-generic members 
+ * of a parameterized type. Use {@link #isParameterizedTypeWithActualArguments()} instead to find out.
+ */
+public final boolean isParameterizedType() {
+	return kind() == Binding.PARAMETERIZED_TYPE;
+}
+
+public boolean isIntersectionCastType() {
+	return false;
+}
+
+/**
+ * Returns true if the type is parameterized, e.g. List<String>
+ * Note that some instances of ParameterizedTypeBinding do answer false to {@link #isParameterizedType()}
+ * in case they have no arguments, like for non-generic members of a parameterized type.
+ * i.e. {@link #isParameterizedType()} is not equivalent to testing <code>type.kind() == Binding.PARAMETERIZED_TYPE</code>
+ */
+public final boolean isParameterizedTypeWithActualArguments() {
+	return (kind() == Binding.PARAMETERIZED_TYPE) 
+					&& ((ParameterizedTypeBinding) this).arguments != null;
+}
+
+/**
+ * Returns true if the type is parameterized using its own type variables as arguments
+ */
+public boolean isParameterizedWithOwnVariables() {
+	if (kind() != Binding.PARAMETERIZED_TYPE)
+		return false;
+	ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
+	if (paramType.arguments == null)
+		return false;
+	TypeVariableBinding[] variables = erasure().typeVariables();
+	for (int i = 0, length = variables.length; i < length; i++) {
+		if (variables[i] != paramType.arguments[i])
+			return false;
+	}
+	ReferenceBinding enclosing = paramType.enclosingType();
+	if (enclosing != null && enclosing.erasure().isGenericType()
+			&& !enclosing.isParameterizedWithOwnVariables()) {
+		return false;
+	}
+	return true;
+}
+
+private boolean isProvableDistinctSubType(TypeBinding otherType) {
+	if (otherType.isInterface()) {
+		if (isInterface())
+			return false;
+		if (isArrayType()
+				|| ((this instanceof ReferenceBinding) && ((ReferenceBinding) this).isFinal())
+				|| (isTypeVariable() && ((TypeVariableBinding)this).superclass().isFinal())) {
+			return !isCompatibleWith(otherType);
+		}
+		return false;
+	} else {
+		if (isInterface()) {
+			if (otherType.isArrayType()
+					|| ((otherType instanceof ReferenceBinding) && ((ReferenceBinding) otherType).isFinal())
+					|| (otherType.isTypeVariable() && ((TypeVariableBinding)otherType).superclass().isFinal())) {
+				return !isCompatibleWith(otherType);
+			}
+		} else {
+			if (!isTypeVariable() && !otherType.isTypeVariable()) {
+				return !isCompatibleWith(otherType);
+			}
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns true if a type is provably distinct from another one,
+ */
+public boolean isProvablyDistinct(TypeBinding otherType) {
+
+	/* With the hybrid 1.4/1.5+ projects modes, while establishing type equivalence, we need to
+	   be prepared for a type such as Map appearing in one of three forms: As (a) a ParameterizedTypeBinding 
+	   e.g Map<String, String>, (b) as RawTypeBinding Map#RAW and finally (c) as a BinaryTypeBinding 
+	   When the usage of a type lacks type parameters, whether we land up with the raw form or not depends
+	   on whether the underlying type was "seen to be" a generic type in the particular build environment or
+	   not. See:
+	    https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565
+        https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827 
+        https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+	 */ 
+
+	if (this == otherType)
+	    return false;
+    if (otherType == null)
+        return true;
+
+    switch (kind()) {
+
+		case Binding.PARAMETERIZED_TYPE :
+		    ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
+		    switch(otherType.kind()) {
+		    	case Binding.PARAMETERIZED_TYPE :
+		            ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+		            if (paramType.genericType() != otherParamType.genericType())
+		                return true;
+		            if (!paramType.isStatic()) { // static member types do not compare their enclosing
+		            	ReferenceBinding enclosing = enclosingType();
+		            	if (enclosing != null) {
+		            		ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+		            		if (otherEnclosing == null) return true;
+		            		if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
+		            			if (enclosing.isProvablyDistinct(otherEnclosing)) return true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=302919
+		            		} else {
+		            			if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return true;
+		            		}
+		            	}
+		            }
+		            int length = paramType.arguments == null ? 0 : paramType.arguments.length;
+		            TypeBinding[] otherArguments = otherParamType.arguments;
+		            int otherLength = otherArguments == null ? 0 : otherArguments.length;
+		            if (otherLength != length)
+		                return true;
+		            for (int i = 0; i < length; i++) {
+		            	if (paramType.arguments[i].isProvablyDistinctTypeArgument(otherArguments[i], paramType, i))
+		            		return true;
+		            }
+		            return false;
+
+		    	case Binding.GENERIC_TYPE :
+		            if (paramType.genericType() != otherType)
+		                return true;
+		            if (!paramType.isStatic()) { // static member types do not compare their enclosing
+		            	ReferenceBinding enclosing = enclosingType();
+		            	if (enclosing != null) {
+		            		ReferenceBinding otherEnclosing = otherType.enclosingType();
+		            		if (otherEnclosing == null) return true;
+		            		if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
+								if (enclosing != otherEnclosing) return true;
+		            		} else {
+		            			if (!enclosing.isEquivalentTo(otherType.enclosingType())) return true;
+		            		}
+		            	}
+		            }
+		            length = paramType.arguments == null ? 0 : paramType.arguments.length;
+		            otherArguments = otherType.typeVariables();
+		            otherLength = otherArguments == null ? 0 : otherArguments.length;
+		            if (otherLength != length)
+		                return true;
+		            for (int i = 0; i < length; i++) {
+		            	if (paramType.arguments[i].isProvablyDistinctTypeArgument(otherArguments[i], paramType, i))
+		            		return true;
+		            }
+		            return false;
+
+		    	case Binding.RAW_TYPE :
+		            return erasure() != otherType.erasure();
+		    	case Binding.TYPE:  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+		    		return erasure() != otherType;
+		    }
+	        return true;
+
+		case Binding.RAW_TYPE : // dead code ??
+
+		    switch(otherType.kind()) {
+
+		    	case Binding.GENERIC_TYPE :
+		    	case Binding.PARAMETERIZED_TYPE :
+		    	case Binding.RAW_TYPE :
+		    	case Binding.TYPE:  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+		            return erasure() != otherType.erasure();
+		    }
+	        return true;
+
+		case Binding.TYPE: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
+		    switch(otherType.kind()) {
+		    	case Binding.PARAMETERIZED_TYPE :
+		    	case Binding.RAW_TYPE :
+		            return this != otherType.erasure();
+		    }
+		    break;
+
+		default :
+			break;
+	}
+    return true;
+}
+
+/**
+ * Returns false if two given types could not intersect as argument types:
+ * List<Throwable> & List<Runnable> --> false
+ * List<? extends Throwable> & List<? extends Runnable> --> true
+ * List<? extends String> & List<? extends Runnable> --> false
+ */
+private boolean isProvablyDistinctTypeArgument(TypeBinding otherArgument, final ParameterizedTypeBinding paramType, final int rank) {
+	if (this == otherArgument)
+		return false;
+
+	TypeBinding upperBound1 = null;
+	TypeBinding lowerBound1 = null;
+	ReferenceBinding genericType = paramType.genericType();
+	switch (kind()) {
+		case Binding.WILDCARD_TYPE :
+			WildcardBinding wildcard = (WildcardBinding) this;
+			switch (wildcard.boundKind) {
+				case Wildcard.EXTENDS:
+					upperBound1 = wildcard.bound;
+					break;
+				case Wildcard.SUPER:
+					lowerBound1 = wildcard.bound;
+					break;
+				case Wildcard.UNBOUND:
+					return false;
+			}
+			break;
+		case Binding.INTERSECTION_TYPE :
+			break;
+		case Binding.TYPE_PARAMETER :
+			final TypeVariableBinding variable = (TypeVariableBinding) this;
+			if (variable.isCapture()) {
+				CaptureBinding capture = (CaptureBinding) variable;
+				switch (capture.wildcard.boundKind) {
+					case Wildcard.EXTENDS:
+						upperBound1 = capture.wildcard.bound;
+						break;
+					case Wildcard.SUPER:
+						lowerBound1 = capture.wildcard.bound;
+						break;
+					case Wildcard.UNBOUND:
+						return false;
+				}
+				break;
+			}
+			if (variable.firstBound == null) // unbound variable
+				return false;
+			TypeBinding eliminatedType = Scope.convertEliminatingTypeVariables(variable, genericType, rank, null);
+			switch (eliminatedType.kind()) {
+				case Binding.WILDCARD_TYPE :
+				case Binding.INTERSECTION_TYPE :
+					wildcard = (WildcardBinding) eliminatedType;
+					switch (wildcard.boundKind) {
+						case Wildcard.EXTENDS:
+							upperBound1 = wildcard.bound;
+							break;
+						case Wildcard.SUPER:
+							lowerBound1 = wildcard.bound;
+							break;
+						case Wildcard.UNBOUND:
+							return false;
+					}
+					break;
+			}
+			break;
+	}
+	TypeBinding upperBound2 = null;
+	TypeBinding lowerBound2 = null;
+	switch (otherArgument.kind()) {
+		case Binding.WILDCARD_TYPE :
+			WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
+			switch (otherWildcard.boundKind) {
+				case Wildcard.EXTENDS:
+					upperBound2 = otherWildcard.bound;
+					break;
+				case Wildcard.SUPER:
+					lowerBound2 = otherWildcard.bound;
+					break;
+				case Wildcard.UNBOUND:
+					return false;
+			}
+			break;
+		case Binding.INTERSECTION_TYPE :
+			break;
+		case Binding.TYPE_PARAMETER :
+			TypeVariableBinding otherVariable = (TypeVariableBinding) otherArgument;
+			if (otherVariable.isCapture()) {
+				CaptureBinding otherCapture = (CaptureBinding) otherVariable;
+				switch (otherCapture.wildcard.boundKind) {
+					case Wildcard.EXTENDS:
+						upperBound2 = otherCapture.wildcard.bound;
+						break;
+					case Wildcard.SUPER:
+						lowerBound2 = otherCapture.wildcard.bound;
+						break;
+					case Wildcard.UNBOUND:
+						return false;
+				}
+				break;
+			}
+			if (otherVariable.firstBound == null) // unbound variable
+				return false;
+			TypeBinding otherEliminatedType = Scope.convertEliminatingTypeVariables(otherVariable, genericType, rank, null);
+			switch (otherEliminatedType.kind()) {
+				case Binding.WILDCARD_TYPE :
+				case Binding.INTERSECTION_TYPE :
+					otherWildcard = (WildcardBinding) otherEliminatedType;
+					switch (otherWildcard.boundKind) {
+						case Wildcard.EXTENDS:
+							upperBound2 = otherWildcard.bound;
+							break;
+						case Wildcard.SUPER:
+							lowerBound2 = otherWildcard.bound;
+							break;
+						case Wildcard.UNBOUND:
+							return false;
+					}
+					break;
+			}			break;
+	}
+	if (lowerBound1 != null) {
+		if (lowerBound2 != null) {
+			return false; // Object could always be a candidate
+
+		} else if (upperBound2 != null) {
+			if (lowerBound1.isTypeVariable() || upperBound2.isTypeVariable()) {
+				return false;
+			}
+			return !lowerBound1.isCompatibleWith(upperBound2);
+		} else {
+			if (lowerBound1.isTypeVariable() || otherArgument.isTypeVariable()) {
+				return false;
+			}
+			return !lowerBound1.isCompatibleWith(otherArgument);
+		}
+	} else if (upperBound1 != null) {
+		if (lowerBound2 != null) {
+			return !lowerBound2.isCompatibleWith(upperBound1);
+		} else if (upperBound2 != null) {
+			return upperBound1.isProvableDistinctSubType(upperBound2)
+							&& upperBound2.isProvableDistinctSubType(upperBound1);
+		} else {
+			return otherArgument.isProvableDistinctSubType(upperBound1);
+		}
+	} else {
+		if (lowerBound2 != null) {
+			if (lowerBound2.isTypeVariable() || isTypeVariable()) {
+				return false;
+			}
+			return !lowerBound2.isCompatibleWith(this);
+		} else if (upperBound2 != null) {
+			return isProvableDistinctSubType(upperBound2);
+		} else {
+			return true; // ground types should have been the same
+		}
+	}
+}
+
+public final boolean isRawType() {
+	return kind() == Binding.RAW_TYPE;
+}
+/**
+ * JLS(3) 4.7.
+ * Note: Foo<?>.Bar is also reifiable
+ */
+public boolean isReifiable() {
+	TypeBinding leafType = leafComponentType();
+	if (!(leafType instanceof ReferenceBinding))
+		return true;
+	ReferenceBinding current = (ReferenceBinding) leafType;
+	do {
+		switch (current.kind()) {
+			case Binding.TYPE_PARAMETER:
+			case Binding.WILDCARD_TYPE:
+			case Binding.INTERSECTION_TYPE:
+			case Binding.GENERIC_TYPE:
+				return false;
+			case Binding.PARAMETERIZED_TYPE:
+				if (current.isBoundParameterizedType())
+					return false;
+				break;
+			case Binding.RAW_TYPE:
+				return true;
+		}
+		if (current.isStatic()) {
+			return true;
+		}
+		if (current.isLocalType()) {
+			LocalTypeBinding localTypeBinding = (LocalTypeBinding) current.erasure();
+			MethodBinding enclosingMethod = localTypeBinding.enclosingMethod;
+			if (enclosingMethod != null && enclosingMethod.isStatic()) {
+				return true;
+			}
+		}
+	} while ((current = current.enclosingType()) != null);
+	return true;
+}
+
+/**
+ * Returns true if a given type may be thrown
+ */
+public boolean isThrowable() {
+	return false;
+}
+// JLS3: 4.5.1.1
+public boolean isTypeArgumentContainedBy(TypeBinding otherType) {
+	if (this == otherType)
+		return true;
+	switch (otherType.kind()) {
+		// handle captured wildcards.
+		case Binding.TYPE_PARAMETER: {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=347426
+			if (!isParameterizedType() || !otherType.isCapture()) {
+				return false;
+			}
+			CaptureBinding capture = (CaptureBinding) otherType;
+			WildcardBinding wildcard = capture.wildcard;
+			TypeBinding upperBound = null;
+			TypeBinding [] otherBounds = null;
+			switch (wildcard.boundKind) {
+				case Wildcard.SUPER:
+					return false; // T super syntax isn't allowed, impossible capture.
+				case Wildcard.UNBOUND:
+					TypeVariableBinding variable = wildcard.genericType.typeVariables()[wildcard.rank];
+					upperBound = variable.upperBound();
+					otherBounds = variable.boundsCount() > 1 ? variable.otherUpperBounds() : null;
+					break;
+				case Wildcard.EXTENDS:
+					upperBound = wildcard.bound;
+					otherBounds = wildcard.otherBounds;
+					break;
+			}
+			// Given class A<T extends B<?>>, A<?> cannot be the universe of all parameterizations of A
+			if (upperBound.id == TypeIds.T_JavaLangObject && otherBounds == null) {
+				return false; // but given class A<T>, A<?> stays an unbounded wildcard, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=348956
+			}
+			otherType = capture.environment.createWildcard(null, 0, upperBound, otherBounds, Wildcard.EXTENDS);
+			return isTypeArgumentContainedBy(otherType);
+		}
+		// allow wildcard containment
+		case Binding.WILDCARD_TYPE:
+		case Binding.INTERSECTION_TYPE:
+
+			TypeBinding lowerBound = this;
+			TypeBinding upperBound = this;
+			switch (kind()) {
+				case Binding.WILDCARD_TYPE:
+				case Binding.INTERSECTION_TYPE:
+					WildcardBinding wildcard = (WildcardBinding) this;
+					switch (wildcard.boundKind) {
+						case Wildcard.EXTENDS:
+							if (wildcard.otherBounds != null) // intersection type
+								break;
+							upperBound = wildcard.bound;
+							lowerBound = null;
+							break;
+						case Wildcard.SUPER:
+							upperBound = wildcard;
+							lowerBound = wildcard.bound;
+							break;
+						case Wildcard.UNBOUND:
+							upperBound = wildcard;
+							lowerBound = null;
+					}
+					break;
+				case Binding.TYPE_PARAMETER:
+					if (isCapture()) {
+						CaptureBinding capture = (CaptureBinding) this;
+						if (capture.lowerBound != null)
+							lowerBound = capture.lowerBound;
+					}
+			}
+			WildcardBinding otherWildcard = (WildcardBinding) otherType;
+			if (otherWildcard.otherBounds != null)
+				return false; // not a true wildcard (intersection type)
+			TypeBinding otherBound = otherWildcard.bound;
+			switch (otherWildcard.boundKind) {
+				case Wildcard.EXTENDS:
+					if (otherBound == this)
+						return true; // ? extends T  <=  ? extends ? extends T
+					if (upperBound == null)
+						return false;
+					TypeBinding match = upperBound.findSuperTypeOriginatingFrom(otherBound);
+					if (match != null && (match = match.leafComponentType()).isRawType()) {
+						return match == otherBound.leafComponentType(); // forbide: Collection <=  ? extends Collection<?>
+																												// forbide: Collection[] <=  ? extends Collection<?>[]
+					}
+					return upperBound.isCompatibleWith(otherBound);
+
+				case Wildcard.SUPER:
+					if (otherBound == this)
+						return true; // ? super T  <=  ? super ? super T
+					if (lowerBound == null)
+						return false;
+					match = otherBound.findSuperTypeOriginatingFrom(lowerBound);
+					if (match != null && (match = match.leafComponentType()).isRawType()) {
+						return match == lowerBound.leafComponentType(); // forbide: Collection <=  ? super Collection<?>
+																												// forbide: Collection[] <=  ? super Collection<?>[]
+					}
+					return otherBound.isCompatibleWith(lowerBound);
+
+				case Wildcard.UNBOUND:
+				default:
+					return true;
+			}
+			// allow List<?> to match List<? extends Object> (and reciprocally)
+		case Binding.PARAMETERIZED_TYPE:
+			if (!isParameterizedType())
+				return false;
+			ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
+			ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+			if (paramType.actualType() != otherParamType.actualType())
+				return false;
+			if (!paramType.isStatic()) { // static member types do not compare their enclosing
+				ReferenceBinding enclosing = enclosingType();
+				if (enclosing != null) {
+					ReferenceBinding otherEnclosing = otherParamType	.enclosingType();
+					if (otherEnclosing == null)
+						return false;
+					if ((otherEnclosing.tagBits & TagBits.HasDirectWildcard) == 0) {
+						if (enclosing != otherEnclosing)
+							return false;
+					} else {
+						if (!enclosing.isEquivalentTo(otherParamType.enclosingType()))
+							return false;
+					}
+				}
+			}
+			int length = paramType.arguments == null ? 0 : paramType.arguments.length;
+			TypeBinding[] otherArguments = otherParamType.arguments;
+			int otherLength = otherArguments == null ? 0 : otherArguments.length;
+			if (otherLength != length)
+				return false;
+			nextArgument: for (int i = 0; i < length; i++) {
+				TypeBinding argument = paramType.arguments[i];
+				TypeBinding otherArgument = otherArguments[i];
+				if (argument == otherArgument)
+					continue nextArgument;
+				int kind = argument.kind();
+				if (otherArgument.kind() != kind)
+					return false;
+				switch (kind) {
+					case Binding.PARAMETERIZED_TYPE:
+						if (argument.isTypeArgumentContainedBy(otherArgument)) // recurse
+							continue nextArgument;
+						break;
+					case Binding.WILDCARD_TYPE:
+					case Binding.INTERSECTION_TYPE:
+						WildcardBinding wildcard = (WildcardBinding) argument;
+						otherWildcard = (WildcardBinding) otherArgument;
+						switch (wildcard.boundKind) {
+						case Wildcard.EXTENDS:
+							// match "? extends <upperBound>" with "?"
+							if (otherWildcard.boundKind == Wildcard.UNBOUND
+									&& wildcard.bound == wildcard.typeVariable().upperBound())
+								continue nextArgument;
+							break;
+						case Wildcard.SUPER:
+							break;
+						case Wildcard.UNBOUND:
+							// match "?" with "? extends <upperBound>"
+							if (otherWildcard.boundKind == Wildcard.EXTENDS
+									&& otherWildcard.bound == otherWildcard.typeVariable().upperBound())
+								continue nextArgument;
+							break;
+						}
+						break;
+				}
+				return false;
+			}
+			return true;
+	}
+	// (? super Object) <= Object
+	if (otherType.id == TypeIds.T_JavaLangObject) {
+		switch (kind()) {
+			case Binding.WILDCARD_TYPE:
+				WildcardBinding wildcard = (WildcardBinding) this;
+				if (wildcard.boundKind == Wildcard.SUPER && wildcard.bound.id == TypeIds.T_JavaLangObject) {
+					return true;
+				}
+				break;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns true if the type was declared as a type variable
+ */
+public boolean isTypeVariable() {
+	return false;
+}
+
+/**
+ * Returns true if wildcard type of the form '?' (no bound)
+ */
+public boolean isUnboundWildcard() {
+	return false;
+}
+
+/**
+ * Returns true if the type is a subclass of java.lang.Error or java.lang.RuntimeException
+ */
+public boolean isUncheckedException(boolean includeSupertype) {
+	return false;
+}
+
+/**
+ * Returns true if the type is a wildcard
+ */
+public boolean isWildcard() {
+	return false;
+}
+
+/* API
+ * Answer the receiver's binding type from Binding.BindingID.
+ */
+public int kind() {
+	return Binding.TYPE;
+}
+
+public TypeBinding leafComponentType() {
+	return this;
+}
+
+/**
+ * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
+ */
+public boolean needsUncheckedConversion(TypeBinding targetType) {
+
+	if (this == targetType)
+		return false;
+	targetType = targetType.leafComponentType();
+	if (!(targetType instanceof ReferenceBinding))
+		return false;
+
+	TypeBinding currentType = leafComponentType();
+	TypeBinding match = currentType.findSuperTypeOriginatingFrom(targetType);
+	if (!(match instanceof ReferenceBinding))
+		return false;
+	ReferenceBinding compatible = (ReferenceBinding) match;
+	while (compatible.isRawType()) {
+		if (targetType.isBoundParameterizedType())
+			return true;
+		if (compatible.isStatic())
+			break;
+		if ((compatible = compatible.enclosingType()) == null)
+			break;
+		if ((targetType = targetType.enclosingType()) == null)
+			break;
+	}
+	return false;
+}
+
+/** Answer a readable name (for error reporting) that includes nullness type annotations. */
+public char[] nullAnnotatedReadableName(LookupEnvironment env, boolean shortNames) /* e.g.: java.lang.Object @o.e.j.a.NonNull[] */ {
+	if (shortNames)
+		return shortReadableName();
+	else
+		return readableName();
+}
+
+/**
+ * Returns the orignal generic type instantiated by the receiver type, or itself if not.
+ * This is similar to erasure process, except it doesn't erase type variable, wildcard, intersection types etc...
+ */
+public TypeBinding original() {
+	switch(kind()) {
+		case Binding.PARAMETERIZED_TYPE :
+		case Binding.RAW_TYPE :
+		case Binding.ARRAY_TYPE :
+			return erasure();
+		default :
+			return this;
+	}
+}
+
+/**
+ * Answer the qualified name of the receiver's package separated by periods
+ * or an empty string if its the default package.
+ *
+ * For example, {java.util}.
+ */
+
+public char[] qualifiedPackageName() {
+	PackageBinding packageBinding = getPackage();
+	return packageBinding == null
+			|| packageBinding.compoundName == CharOperation.NO_CHAR_CHAR ? CharOperation.NO_CHAR
+			: packageBinding.readableName();
+}
+
+/**
+ * Answer the source name for the type.
+ * In the case of member types, as the qualified name from its top level type.
+ * For example, for a member type N defined inside M & A: "A.M.N".
+ */
+
+public abstract char[] qualifiedSourceName();
+
+/**
+ * Answer the receiver classfile signature.
+ * Arrays & base types do not distinguish between signature() & constantPoolName().
+ * NOTE: This method should only be used during/after code gen.
+ */
+public char[] signature() {
+	return constantPoolName();
+}
+
+public abstract char[] sourceName();
+
+public void swapUnresolved(UnresolvedReferenceBinding unresolvedType,
+		ReferenceBinding resolvedType, LookupEnvironment environment) {
+	// subclasses must override if they wrap another type binding
+}
+
+public TypeVariableBinding[] typeVariables() {
+	return Binding.NO_TYPE_VARIABLES;
+}
+
+/**
+ * Return the single abstract method of a functional interface, or null, if the receiver is not a functional interface as defined in JLS 9.8.
+ * @param scope scope
+ *  
+ * @return The single abstract method of a functional interface, or null, if the receiver is not a functional interface. 
+ */
+public MethodBinding getSingleAbstractMethod(Scope scope) {
+	return null;
+}
+
+public ReferenceBinding[] getIntersectingTypes() {
+	return null;
+}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java
new file mode 100644
index 0000000..2f54acb
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBindingVisitor.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.ast.Annotation.TypeUseBinding;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+
+public class TypeBindingVisitor {
+
+	private SimpleLookupTable visitedCache;
+
+	public boolean visit(BaseTypeBinding baseTypeBinding)  {
+		return true;  // continue traversal.
+	}
+
+	public boolean visit(ArrayBinding arrayBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(TypeVariableBinding typeVariable) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(ReferenceBinding referenceBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(WildcardBinding wildcardBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(ParameterizedTypeBinding parameterizedTypeBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(IntersectionCastTypeBinding intersectionCastTypeBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(TypeUseBinding typeUseBinding) {
+		return true;  // continue traversal.
+	}
+	
+	public boolean visit(RawTypeBinding rawTypeBinding) {
+		return true;  // continue traversal.
+	}
+
+	public static void visit(TypeBindingVisitor visitor, ReferenceBinding[] types) {
+		for (int i = 0, length = types == null ? 0 : types.length; i < length; i++) {
+	        visit(visitor, types[i]);
+	    }
+	}
+
+	public static void visit(TypeBindingVisitor visitor, TypeBinding type) {
+
+		if (type == null) 
+			return;
+		
+		SimpleLookupTable visitedCache = visitor.visitedCache;
+		if (visitedCache == null) {
+			visitor.visitedCache = new SimpleLookupTable(3);
+			visitedCache = visitor.visitedCache;
+		}
+
+		Object result = visitedCache.get(type);
+		if (result == Boolean.TRUE)
+			return;
+		visitedCache.put(type, Boolean.TRUE);
+		switch (type.kind()) {
+			
+			case Binding.TYPE_PARAMETER:
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) type;
+				if (visitor.visit(typeVariableBinding)) {
+					visit(visitor, typeVariableBinding.firstBound);
+					visit(visitor, typeVariableBinding.superclass);
+					visit(visitor, typeVariableBinding.superInterfaces);
+				}
+	            break;
+	            
+			case Binding.PARAMETERIZED_TYPE:
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) type;
+				if (visitor.visit(parameterizedTypeBinding)) {
+					visit(visitor, parameterizedTypeBinding.enclosingType());
+					visit(visitor, parameterizedTypeBinding.arguments);
+				}
+				break;
+
+			case Binding.ARRAY_TYPE:
+				ArrayBinding arrayBinding = (ArrayBinding) type;
+				if (visitor.visit(arrayBinding))
+					visit(visitor, arrayBinding.leafComponentType);
+				break;
+
+			case Binding.WILDCARD_TYPE:
+			case Binding.INTERSECTION_TYPE:
+		        WildcardBinding wildcard = (WildcardBinding) type;
+		        if (visitor.visit(wildcard)) {
+		        	if (wildcard.boundKind != Wildcard.UNBOUND) {
+		        		visit(visitor, wildcard.bound);
+		        		visit(visitor, wildcard.otherBounds);
+		        	}
+		        }
+				break;
+			
+			case Binding.BASE_TYPE:
+				visitor.visit((BaseTypeBinding) type);
+				break;
+			
+			case Binding.RAW_TYPE:
+				visitor.visit((RawTypeBinding) type);
+				break;
+				
+			case Binding.TYPE:
+			case Binding.GENERIC_TYPE:
+				ReferenceBinding referenceBinding = (ReferenceBinding) type;
+				if (visitor.visit(referenceBinding)) {
+					visit(visitor, referenceBinding.enclosingType());
+					visit(visitor, referenceBinding.typeVariables());
+				}
+				break;
+			
+			case Binding.INTERSECTION_CAST_TYPE:
+				IntersectionCastTypeBinding intersectionCastTypeBinding = (IntersectionCastTypeBinding) type;
+				if (visitor.visit(intersectionCastTypeBinding))
+					visit(visitor, intersectionCastTypeBinding.intersectingTypes);
+				break;
+				
+			case Binding.TYPE_USE:
+				visitor.visit((TypeUseBinding) type);
+				break;
+				
+			default:
+				throw new InternalError("Unexpected binding type"); //$NON-NLS-1$
+		}
+	}
+
+	public static void visit(TypeBindingVisitor visitor, TypeBinding[] types) {
+		for (int i = 0, length = types == null ? 0 : types.length; i < length; i++) {
+	        visit(visitor, types[i]);
+	    }
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
new file mode 100644
index 0000000..2d44194
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 381445 - [compiler][resource] Can the resource leak check be made aware of Closeables.closeQuietly?
+ *								bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
+ *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *
+ *    Jesper S Moller - Contributions for
+ *							Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+// TODO should rename into TypeNames (once extracted last non name constants)
+public interface TypeConstants {
+
+	char[] JAVA = "java".toCharArray(); //$NON-NLS-1$
+	char[] JAVAX = "javax".toCharArray(); //$NON-NLS-1$
+	char[] LANG = "lang".toCharArray(); //$NON-NLS-1$
+	char[] IO = "io".toCharArray(); //$NON-NLS-1$
+	char[] UTIL = "util".toCharArray(); //$NON-NLS-1$
+	char[] ZIP = "zip".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION = "annotation".toCharArray(); //$NON-NLS-1$
+	char[] REFLECT = "reflect".toCharArray(); //$NON-NLS-1$
+	char[] LENGTH = "length".toCharArray(); //$NON-NLS-1$
+	char[] CLONE = "clone".toCharArray(); //$NON-NLS-1$
+	char[] EQUALS = "equals".toCharArray(); //$NON-NLS-1$
+	char[] GETCLASS = "getClass".toCharArray(); //$NON-NLS-1$
+	char[] HASHCODE = "hashCode".toCharArray(); //$NON-NLS-1$
+	char[] OBJECT = "Object".toCharArray(); //$NON-NLS-1$
+	char[] MAIN = "main".toCharArray(); //$NON-NLS-1$
+	char[] SERIALVERSIONUID = "serialVersionUID".toCharArray(); //$NON-NLS-1$
+	char[] SERIALPERSISTENTFIELDS = "serialPersistentFields".toCharArray(); //$NON-NLS-1$
+	char[] READRESOLVE = "readResolve".toCharArray(); //$NON-NLS-1$
+	char[] WRITEREPLACE = "writeReplace".toCharArray(); //$NON-NLS-1$
+	char[] READOBJECT = "readObject".toCharArray(); //$NON-NLS-1$
+	char[] WRITEOBJECT = "writeObject".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_LANG_OBJECT = "java.lang.Object".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_LANG_ENUM = "java.lang.Enum".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_LANG_ANNOTATION_ANNOTATION = "java.lang.annotation.Annotation".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_IO_OBJECTINPUTSTREAM = "java.io.ObjectInputStream".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_IO_OBJECTOUTPUTSTREAM = "java.io.ObjectOutputStream".toCharArray(); //$NON-NLS-1$
+	char[] CharArray_JAVA_IO_OBJECTSTREAMFIELD = "java.io.ObjectStreamField".toCharArray(); //$NON-NLS-1$
+	char[] ANONYM_PREFIX = "new ".toCharArray(); //$NON-NLS-1$
+	char[] ANONYM_SUFFIX = "(){}".toCharArray(); //$NON-NLS-1$
+    char[] WILDCARD_NAME = { '?' };
+    char[] WILDCARD_SUPER = " super ".toCharArray(); //$NON-NLS-1$
+    char[] WILDCARD_EXTENDS = " extends ".toCharArray(); //$NON-NLS-1$
+    char[] WILDCARD_MINUS = { '-' };
+    char[] WILDCARD_STAR = { '*' };
+    char[] WILDCARD_PLUS = { '+' };
+    char[] WILDCARD_CAPTURE_NAME_PREFIX = "capture#".toCharArray(); //$NON-NLS-1$
+    char[] WILDCARD_CAPTURE_NAME_SUFFIX = "-of ".toCharArray(); //$NON-NLS-1$
+	char[] WILDCARD_CAPTURE = { '!' };
+	char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
+	char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
+	char[] INT = "int".toCharArray(); //$NON-NLS-1$
+	char[] LONG = "long".toCharArray(); //$NON-NLS-1$
+	char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
+	char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
+	char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
+	char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
+	char[] NULL = "null".toCharArray(); //$NON-NLS-1$
+	char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+    char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
+    char[] VALUES = "values".toCharArray(); //$NON-NLS-1$
+    char[] VALUEOF = "valueOf".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_SOURCE = "SOURCE".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_CLASS = "CLASS".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_RUNTIME = "RUNTIME".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION_PREFIX = "@".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION_SUFFIX = "()".toCharArray(); //$NON-NLS-1$
+    char[] TYPE = "TYPE".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_FIELD = "FIELD".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_METHOD = "METHOD".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_PARAMETER = "PARAMETER".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_CONSTRUCTOR = "CONSTRUCTOR".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_LOCAL_VARIABLE = "LOCAL_VARIABLE".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_ANNOTATION_TYPE = "ANNOTATION_TYPE".toCharArray(); //$NON-NLS-1$
+    char[] UPPER_PACKAGE = "PACKAGE".toCharArray(); //$NON-NLS-1$
+    char[] ANONYMOUS_METHOD = "lambda$".toCharArray(); //$NON-NLS-1$
+    
+	// jsr308
+	char[] TYPE_USE_TARGET  = "TYPE_USE".toCharArray(); //$NON-NLS-1$
+	char[] TYPE_PARAMETER_TARGET = "TYPE_PARAMETER".toCharArray(); //$NON-NLS-1$
+    
+    // common 3rd party package components:
+    char[] ORG = "org".toCharArray(); //$NON-NLS-1$
+    char[] ECLIPSE = "eclipse".toCharArray(); //$NON-NLS-1$
+    char[] CORE = "core".toCharArray(); //$NON-NLS-1$
+    char[] RUNTIME = "runtime".toCharArray(); //$NON-NLS-1$
+    char[] APACHE = "apache".toCharArray(); //$NON-NLS-1$
+    char[] COMMONS = "commons".toCharArray(); //$NON-NLS-1$
+    char[] LANG3 = "lang3".toCharArray(); //$NON-NLS-1$
+    char[] COM = "com".toCharArray(); //$NON-NLS-1$
+    char[] GOOGLE = "google".toCharArray(); //$NON-NLS-1$
+
+	// Constant compound names
+	char[][] JAVA_LANG = {JAVA, LANG};
+	char[][] JAVA_IO = {JAVA, IO};
+	char[][] JAVA_LANG_ANNOTATION_ANNOTATION = {JAVA, LANG, ANNOTATION, "Annotation".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ASSERTIONERROR = {JAVA, LANG, "AssertionError".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_CLASS = {JAVA, LANG, "Class".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_CLASSNOTFOUNDEXCEPTION = {JAVA, LANG, "ClassNotFoundException".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_CLONEABLE = {JAVA, LANG, "Cloneable".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ENUM = {JAVA, LANG, "Enum".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_EXCEPTION = {JAVA, LANG, "Exception".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ERROR = {JAVA, LANG, "Error".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ILLEGALARGUMENTEXCEPTION = {JAVA, LANG, "IllegalArgumentException".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ITERABLE = {JAVA, LANG, "Iterable".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_NOCLASSDEFERROR = {JAVA, LANG, "NoClassDefError".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_OBJECT = {JAVA, LANG, OBJECT};
+	char[][] JAVA_LANG_STRING = {JAVA, LANG, "String".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_STRINGBUFFER = {JAVA, LANG, "StringBuffer".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_STRINGBUILDER = {JAVA, LANG, "StringBuilder".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_SYSTEM = {JAVA, LANG, "System".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_RUNTIMEEXCEPTION = {JAVA, LANG, "RuntimeException".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_THROWABLE = {JAVA, LANG, "Throwable".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_REFLECT_CONSTRUCTOR = {JAVA, LANG, REFLECT, "Constructor".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_IO_PRINTSTREAM = {JAVA, IO, "PrintStream".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_IO_SERIALIZABLE = {JAVA, IO, "Serializable".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_BYTE = {JAVA, LANG, "Byte".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_SHORT = {JAVA, LANG, "Short".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_CHARACTER = {JAVA, LANG, "Character".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_INTEGER = {JAVA, LANG, "Integer".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_LONG = {JAVA, LANG, "Long".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_FLOAT = {JAVA, LANG, "Float".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_DOUBLE = {JAVA, LANG, "Double".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_BOOLEAN = {JAVA, LANG, "Boolean".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_VOID = {JAVA, LANG, "Void".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_UTIL_COLLECTION = {JAVA, UTIL, "Collection".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_UTIL_ITERATOR = {JAVA, UTIL, "Iterator".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_UTIL_OBJECTS = {JAVA, UTIL, "Objects".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_DEPRECATED = {JAVA, LANG, "Deprecated".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_DOCUMENTED = {JAVA, LANG, ANNOTATION, "Documented".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_INHERITED = {JAVA, LANG, ANNOTATION, "Inherited".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_OVERRIDE = {JAVA, LANG, "Override".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_FUNCTIONAL_INTERFACE = {JAVA, LANG, "FunctionalInterface".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_RETENTION = {JAVA, LANG, ANNOTATION, "Retention".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_SUPPRESSWARNINGS = {JAVA, LANG, "SuppressWarnings".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_TARGET = {JAVA, LANG, ANNOTATION, "Target".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = {JAVA, LANG, ANNOTATION, "RetentionPolicy".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_ANNOTATION_ELEMENTTYPE = {JAVA, LANG, ANNOTATION, "ElementType".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_REFLECT_FIELD = new char[][] {JAVA, LANG, REFLECT, "Field".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_REFLECT_METHOD = new char[][] {JAVA, LANG, REFLECT, "Method".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_IO_CLOSEABLE = new char[][] { JAVA, IO, "Closeable".toCharArray()};//$NON-NLS-1$
+	char[][] JAVA_IO_OBJECTSTREAMEXCEPTION = new char[][] { JAVA, IO, "ObjectStreamException".toCharArray()};//$NON-NLS-1$
+	char[][] JAVA_IO_EXTERNALIZABLE = {JAVA, IO, "Externalizable".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_IO_IOEXCEPTION = new char[][] { JAVA, IO, "IOException".toCharArray()};//$NON-NLS-1$
+	char[][] JAVA_IO_OBJECTOUTPUTSTREAM = new char[][] { JAVA, IO, "ObjectOutputStream".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_IO_OBJECTINPUTSTREAM = new char[][] { JAVA, IO, "ObjectInputStream".toCharArray()}; //$NON-NLS-1$
+	// javax.rmi.CORBA.Stub
+	char[][] JAVAX_RMI_CORBA_STUB = new char[][] {
+			JAVAX,
+			"rmi".toCharArray(), //$NON-NLS-1$
+			"CORBA".toCharArray(), //$NON-NLS-1$
+			"Stub".toCharArray(), //$NON-NLS-1$
+	};
+	char[][] JAVA_LANG_SAFEVARARGS =  {JAVA, LANG, "SafeVarargs".toCharArray()}; //$NON-NLS-1$
+	char[] INVOKE = "invoke".toCharArray(); //$NON-NLS-1$
+	char[][] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = { // Signature while parsing binary file
+			JAVA,
+			LANG,
+			INVOKE,
+			"MethodHandle".toCharArray(), //$NON-NLS-1$
+			"PolymorphicSignature".toCharArray() //$NON-NLS-1$
+	};
+	char[][] JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE = { // Signature while parsing source file
+			JAVA,
+			LANG,
+			INVOKE,
+			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
+	};
+	char[][] JAVA_LANG_INVOKE_LAMBDAMETAFACTORY = {JAVA, LANG, INVOKE, "LambdaMetafactory".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_INVOKE_METHODHANDLES = {JAVA, LANG, INVOKE, "MethodHandles".toCharArray()}; //$NON-NLS-1$
+	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-1$
+	char[] CLOSE = "close".toCharArray(); //$NON-NLS-1$
+	// known helper functions for closing a Closeable (all receive a Closeable as their first argument):
+	public static class CloseMethodRecord {
+		public char[][] typeName;
+		public char[] selector;
+		public CloseMethodRecord(char[][] typeName, char[] selector) {
+			this.typeName = typeName;
+			this.selector = selector;
+		}
+	}
+	char[][] GUAVA_CLOSEABLES = { COM, GOOGLE, "common".toCharArray(), IO, "Closeables".toCharArray() }; //$NON-NLS-1$ //$NON-NLS-2$
+	char[][] APACHE_IOUTILS = { ORG, APACHE, COMMONS, IO, "IOUtils".toCharArray() }; //$NON-NLS-1$
+	char[] CLOSE_QUIETLY = "closeQuietly".toCharArray(); //$NON-NLS-1$
+	CloseMethodRecord[] closeMethods = new CloseMethodRecord[] {
+		new CloseMethodRecord(GUAVA_CLOSEABLES, CLOSE_QUIETLY),
+		new CloseMethodRecord(GUAVA_CLOSEABLES, CLOSE),
+		new CloseMethodRecord(APACHE_IOUTILS, CLOSE_QUIETLY)
+	};
+	// white lists of closeables:
+	char[][] JAVA_IO_WRAPPER_CLOSEABLES = new char[][] {
+		"BufferedInputStream".toCharArray(), //$NON-NLS-1$
+		"BufferedOutputStream".toCharArray(), //$NON-NLS-1$
+		"BufferedReader".toCharArray(), //$NON-NLS-1$
+		"BufferedWriter".toCharArray(), //$NON-NLS-1$
+		"InputStreamReader".toCharArray(), //$NON-NLS-1$
+		"PrintWriter".toCharArray(),  //$NON-NLS-1$
+		"LineNumberReader".toCharArray(), //$NON-NLS-1$
+		"DataInputStream".toCharArray(), //$NON-NLS-1$
+		"DataOutputStream".toCharArray(), //$NON-NLS-1$
+		"ObjectInputStream".toCharArray(), //$NON-NLS-1$
+		"ObjectOutputStream".toCharArray(), //$NON-NLS-1$
+		"FilterInputStream".toCharArray(), //$NON-NLS-1$
+		"FilterOutputStream".toCharArray(), //$NON-NLS-1$
+		"DataInputStream".toCharArray(), //$NON-NLS-1$
+		"DataOutputStream".toCharArray(), //$NON-NLS-1$
+		"PushbackInputStream".toCharArray(), //$NON-NLS-1$
+		"SequenceInputStream".toCharArray(), //$NON-NLS-1$
+		"PrintStream".toCharArray(), //$NON-NLS-1$
+		"PushbackReader".toCharArray(), //$NON-NLS-1$
+		"OutputStreamWriter".toCharArray(), //$NON-NLS-1$
+	};
+	char[][] JAVA_UTIL_ZIP_WRAPPER_CLOSEABLES = new char[][] {
+		"GZIPInputStream".toCharArray(), //$NON-NLS-1$
+		"InflaterInputStream".toCharArray(), //$NON-NLS-1$
+		"DeflaterInputStream".toCharArray(), //$NON-NLS-1$
+		"CheckedInputStream".toCharArray(), //$NON-NLS-1$
+		"ZipInputStream".toCharArray(), //$NON-NLS-1$
+		"JarInputStream".toCharArray(), //$NON-NLS-1$
+		"GZIPOutputStream".toCharArray(), //$NON-NLS-1$
+		"InflaterOutputStream".toCharArray(), //$NON-NLS-1$
+		"DeflaterOutputStream".toCharArray(), //$NON-NLS-1$
+		"CheckedOutputStream".toCharArray(), //$NON-NLS-1$
+		"ZipOutputStream".toCharArray(), //$NON-NLS-1$
+		"JarOutputStream".toCharArray(), //$NON-NLS-1$
+	};
+	char[][][] OTHER_WRAPPER_CLOSEABLES = new char[][][] {
+		{JAVA, "security".toCharArray(), "DigestInputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
+		{JAVA, "security".toCharArray(), "DigestOutputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
+		{JAVA, "beans".toCharArray(), "XMLEncoder".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
+		{JAVA, "beans".toCharArray(), "XMLDecoder".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$
+		{JAVAX, "sound".toCharArray(), "sampled".toCharArray(), "AudioInputStream".toCharArray()}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	};
+	char[][] JAVA_IO_RESOURCE_FREE_CLOSEABLES = new char[][] {			
+		"StringReader".toCharArray(), //$NON-NLS-1$
+		"StringWriter".toCharArray(), //$NON-NLS-1$
+		"ByteArrayInputStream".toCharArray(), //$NON-NLS-1$
+		"ByteArrayOutputStream".toCharArray(), //$NON-NLS-1$
+		"CharArrayReader".toCharArray(), //$NON-NLS-1$
+		"CharArrayWriter".toCharArray(), //$NON-NLS-1$
+		"StringBufferInputStream".toCharArray(), //$NON-NLS-1$
+	};
+	
+	// different assertion utilities:
+	char[] ASSERT_CLASS = "Assert".toCharArray(); //$NON-NLS-1$
+	char[][] ORG_ECLIPSE_CORE_RUNTIME_ASSERT = new char[][] { ORG, ECLIPSE, CORE, RUNTIME, ASSERT_CLASS };
+	// ... methods:
+	char[] IS_NOTNULL = "isNotNull".toCharArray(); //$NON-NLS-1$
+	
+	char[] JUNIT = "junit".toCharArray(); //$NON-NLS-1$
+	char[] FRAMEWORK = "framework".toCharArray(); //$NON-NLS-1$
+	char[][] JUNIT_FRAMEWORK_ASSERT = new char[][] { JUNIT, FRAMEWORK, ASSERT_CLASS };
+	char[][] ORG_JUNIT_ASSERT = new char[][] { ORG, JUNIT, ASSERT_CLASS };
+	// ... methods:
+	char[] ASSERT_NULL = "assertNull".toCharArray(); //$NON-NLS-1$
+	char[] ASSERT_NOTNULL = "assertNotNull".toCharArray(); //$NON-NLS-1$
+	char[] ASSERT_TRUE = "assertTrue".toCharArray(); //$NON-NLS-1$
+	char[] ASSERT_FALSE = "assertFalse".toCharArray(); //$NON-NLS-1$
+	
+	char[] VALIDATE_CLASS = "Validate".toCharArray(); //$NON-NLS-1$
+	char[][] ORG_APACHE_COMMONS_LANG_VALIDATE = new char[][] { ORG, APACHE, COMMONS, LANG, VALIDATE_CLASS };
+	char[][] ORG_APACHE_COMMONS_LANG3_VALIDATE = new char[][] { ORG, APACHE, COMMONS, LANG3, VALIDATE_CLASS };
+	// ... methods:
+	char[] IS_TRUE = "isTrue".toCharArray(); //$NON-NLS-1$
+	char[] NOT_NULL = "notNull".toCharArray(); //$NON-NLS-1$
+	
+	char[][] COM_GOOGLE_COMMON_BASE_PRECONDITIONS = new char[][] { 
+			COM, GOOGLE, "common".toCharArray(), "base".toCharArray(), "Preconditions".toCharArray() }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	// ... methods:
+	char[] CHECK_NOT_NULL = "checkNotNull".toCharArray(); //$NON-NLS-1$
+	char[] CHECK_ARGUMENT = "checkArgument".toCharArray(); //$NON-NLS-1$
+	char[] CHECK_STATE = "checkState".toCharArray(); //$NON-NLS-1$
+
+	// ... methods in java.util.Objects:
+	char[] REQUIRE_NON_NULL = "requireNonNull".toCharArray(); //$NON-NLS-1$
+	
+	// different @Inject annotations are relevant for @NonNull fields
+	char[] INJECT_PACKAGE = "inject".toCharArray(); //$NON-NLS-1$
+	char[] INJECT_TYPE = "Inject".toCharArray(); //$NON-NLS-1$
+	char[][] JAVAX_ANNOTATION_INJECT_INJECT = new char[][] { JAVAX, INJECT_PACKAGE, INJECT_TYPE };
+	char[][] COM_GOOGLE_INJECT_INJECT = new char[][] {COM, GOOGLE, INJECT_PACKAGE, INJECT_TYPE };
+	//    detail for the above:
+	char[] OPTIONAL = "optional".toCharArray(); //$NON-NLS-1$
+
+	// Constraints for generic type argument inference
+	int CONSTRAINT_EQUAL = 0;		// Actual = Formal
+	int CONSTRAINT_EXTENDS = 1;	// Actual << Formal
+	int CONSTRAINT_SUPER = 2;		// Actual >> Formal
+
+	// Constants used to perform bound checks
+	int OK = 0;
+	int UNCHECKED = 1;
+	int MISMATCH = 2;
+
+	// Synthetics
+	char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
+	char[] CLINIT = "<clinit>".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_SWITCH_ENUM_TABLE = "$SWITCH_TABLE$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_ENUM_VALUES = "ENUM$VALUES".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_ASSERT_DISABLED = "$assertionsDisabled".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_CLASS = "class$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_OUTER_LOCAL_PREFIX = "val$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_ENCLOSING_INSTANCE_PREFIX = "this$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_ACCESS_METHOD_PREFIX =  "access$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX =  " enum constant initialization$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_STATIC_FACTORY =  "<factory>".toCharArray(); //$NON-NLS-1$
+
+	// synthetic package-info name
+	public static final char[] PACKAGE_INFO_NAME = "package-info".toCharArray(); //$NON-NLS-1$
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
new file mode 100644
index 0000000..f8d0413
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *     							bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 400421 - [compiler] Null analysis for fields does not take @com.google.inject.Inject into account
+ *								bug 382069 - [null] Make the null analysis consider JUnit's assertNotNull similarly to assertions
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public interface TypeIds {
+
+    //base type void null undefined Object String
+	//should have an id that is 0<= id <= 15
+    // The IDs below must be representable using 4 bits so as to fit in operator signatures.
+	final int T_undefined = 0; // should not be changed
+	final int T_JavaLangObject = 1;
+	final int T_char = 2;
+	final int T_byte = 3;
+	final int T_short = 4;
+	final int T_boolean = 5;
+	final int T_void = 6;
+	final int T_long = 7;
+	final int T_double = 8;
+	final int T_float = 9;
+	final int T_int = 10;
+	final int T_JavaLangString = 11;
+	final int T_null = 12;
+
+	//=========end of 4 bits constraint===========
+
+	// well-known exception types
+	final int T_JavaLangClass = 16;
+	final int T_JavaLangStringBuffer = 17;
+	final int T_JavaLangSystem = 18;
+	final int T_JavaLangError = 19;
+	final int T_JavaLangReflectConstructor = 20;
+	final int T_JavaLangThrowable = 21;
+	final int T_JavaLangNoClassDefError = 22;
+	final int T_JavaLangClassNotFoundException = 23;
+	final int T_JavaLangRuntimeException = 24;
+	final int T_JavaLangException = 25;
+
+	// wrapper types
+	final int T_JavaLangByte = 26;
+	final int T_JavaLangShort = 27;
+	final int T_JavaLangCharacter = 28;
+	final int T_JavaLangInteger = 29;
+	final int T_JavaLangLong = 30;
+	final int T_JavaLangFloat = 31;
+	final int T_JavaLangDouble = 32;
+	final int T_JavaLangBoolean = 33;
+	final int T_JavaLangVoid = 34;
+
+	// 1.4 features
+	final int T_JavaLangAssertionError = 35;
+
+	// array interfaces
+	final int T_JavaLangCloneable = 36;
+	final int T_JavaIoSerializable = 37;
+
+	// 1.5 features
+	final int T_JavaLangIterable = 38;
+	final int T_JavaUtilIterator = 39;
+	final int T_JavaLangStringBuilder = 40;
+	final int T_JavaLangEnum = 41;
+	final int T_JavaLangIllegalArgumentException = 42;
+	final int T_JavaLangAnnotationAnnotation = 43;
+	final int T_JavaLangDeprecated = 44;
+	final int T_JavaLangAnnotationDocumented = 45;
+	final int T_JavaLangAnnotationInherited = 46;
+	final int T_JavaLangOverride = 47;
+	final int T_JavaLangAnnotationRetention = 48;
+	final int T_JavaLangSuppressWarnings = 49;
+	final int T_JavaLangAnnotationTarget = 50;
+	final int T_JavaLangAnnotationRetentionPolicy = 51;
+	final int T_JavaLangAnnotationElementType = 52;
+
+	final int T_JavaIoPrintStream = 53;
+
+	final int T_JavaLangReflectField = 54;
+	final int T_JavaLangReflectMethod = 55;
+
+	final int T_JavaIoExternalizable = 56;
+	final int T_JavaIoObjectStreamException = 57;
+	final int T_JavaIoException = 58;
+	
+	final int T_JavaUtilCollection = 59;
+	
+	// java 7
+	final int T_JavaLangSafeVarargs = 60;
+	
+	final int T_JavaLangInvokeMethodHandlePolymorphicSignature = 61;
+
+	// java 7 java.lang.AutoCloseable
+	final int T_JavaLangAutoCloseable = 62;
+	
+	// new in 3.8 for null annotations:
+	final int T_ConfiguredAnnotationNullable = 65;
+	final int T_ConfiguredAnnotationNonNull = 66;
+	final int T_ConfiguredAnnotationNonNullByDefault = 67;
+	
+	// new in 3.8 to identify org.eclipse.core.runtime.Assert
+	final int T_OrgEclipseCoreRuntimeAssert = 68;
+	// new in 3.9 to identify more assertion utilities:
+	final int T_JunitFrameworkAssert = 69;
+	final int T_OrgJunitAssert = 70;
+	final int T_OrgApacheCommonsLangValidate = 71;
+	final int T_OrgApacheCommonsLang3Validate = 72;
+	final int T_ComGoogleCommonBasePreconditions = 73;
+	final int T_JavaUtilObjects = 74;
+
+	// java 8
+	final int T_JavaLangFunctionalInterface = 69;
+
+	// new in 3.9 to identify known @Inject annotations
+	final int T_JavaxInjectInject = 80;
+	final int T_ComGoogleInjectInject = 81;
+
+
+	final int NoId = Integer.MAX_VALUE;
+
+	public static final int IMPLICIT_CONVERSION_MASK = 0xFF;
+	public static final int COMPILE_TYPE_MASK = 0xF;
+
+	// implicit conversions: <compileType> to <runtimeType>  (note: booleans are integers at runtime)
+	final int Boolean2Int = T_boolean + (T_int << 4);
+	final int Boolean2String = T_boolean + (T_JavaLangString << 4);
+	final int Boolean2Boolean = T_boolean + (T_boolean << 4);
+	final int Byte2Byte = T_byte + (T_byte << 4);
+	final int Byte2Short = T_byte + (T_short << 4);
+	final int Byte2Char = T_byte + (T_char << 4);
+	final int Byte2Int = T_byte + (T_int << 4);
+	final int Byte2Long = T_byte + (T_long << 4);
+	final int Byte2Float = T_byte + (T_float << 4);
+	final int Byte2Double = T_byte + (T_double << 4);
+	final int Byte2String = T_byte + (T_JavaLangString << 4);
+	final int Short2Byte = T_short + (T_byte << 4);
+	final int Short2Short = T_short + (T_short << 4);
+	final int Short2Char = T_short + (T_char << 4);
+	final int Short2Int = T_short + (T_int << 4);
+	final int Short2Long = T_short + (T_long << 4);
+	final int Short2Float = T_short + (T_float << 4);
+	final int Short2Double = T_short + (T_double << 4);
+	final int Short2String = T_short + (T_JavaLangString << 4);
+	final int Char2Byte = T_char + (T_byte << 4);
+	final int Char2Short = T_char + (T_short << 4);
+	final int Char2Char = T_char + (T_char << 4);
+	final int Char2Int = T_char + (T_int << 4);
+	final int Char2Long = T_char + (T_long << 4);
+	final int Char2Float = T_char + (T_float << 4);
+	final int Char2Double = T_char + (T_double << 4);
+	final int Char2String = T_char + (T_JavaLangString << 4);
+	final int Int2Byte = T_int + (T_byte << 4);
+	final int Int2Short = T_int + (T_short << 4);
+	final int Int2Char = T_int + (T_char << 4);
+	final int Int2Int = T_int + (T_int << 4);
+	final int Int2Long = T_int + (T_long << 4);
+	final int Int2Float = T_int + (T_float << 4);
+	final int Int2Double = T_int + (T_double << 4);
+	final int Int2String = T_int + (T_JavaLangString << 4);
+	final int Long2Byte = T_long + (T_byte << 4);
+	final int Long2Short = T_long + (T_short << 4);
+	final int Long2Char = T_long + (T_char << 4);
+	final int Long2Int = T_long + (T_int << 4);
+	final int Long2Long = T_long + (T_long << 4);
+	final int Long2Float = T_long + (T_float << 4);
+	final int Long2Double = T_long + (T_double << 4);
+	final int Long2String = T_long + (T_JavaLangString << 4);
+	final int Float2Byte = T_float + (T_byte << 4);
+	final int Float2Short = T_float + (T_short << 4);
+	final int Float2Char = T_float + (T_char << 4);
+	final int Float2Int = T_float + (T_int << 4);
+	final int Float2Long = T_float + (T_long << 4);
+	final int Float2Float = T_float + (T_float << 4);
+	final int Float2Double = T_float + (T_double << 4);
+	final int Float2String = T_float + (T_JavaLangString << 4);
+	final int Double2Byte = T_double + (T_byte << 4);
+	final int Double2Short = T_double + (T_short << 4);
+	final int Double2Char = T_double + (T_char << 4);
+	final int Double2Int = T_double + (T_int << 4);
+	final int Double2Long = T_double + (T_long << 4);
+	final int Double2Float = T_double + (T_float << 4);
+	final int Double2Double = T_double + (T_double << 4);
+	final int Double2String = T_double + (T_JavaLangString << 4);
+	final int String2String = T_JavaLangString + (T_JavaLangString << 4);
+	final int Object2String = T_JavaLangObject + (T_JavaLangString << 4);
+	final int Null2Null = T_null + (T_null << 4);
+	final int Null2String = T_null + (T_JavaLangString << 4);
+	final int Object2Object = T_JavaLangObject + (T_JavaLangObject << 4);
+	final int Object2byte = T_JavaLangObject + (T_byte << 4);
+	final int Object2short = T_JavaLangObject + (T_short << 4);
+	final int Object2char = T_JavaLangObject + (T_char << 4);
+	final int Object2int = T_JavaLangObject + (T_int << 4);
+	final int Object2long = T_JavaLangObject + (T_long << 4);
+	final int Object2float = T_JavaLangObject + (T_float << 4);
+	final int Object2double = T_JavaLangObject + (T_double << 4);
+	final int Object2boolean = T_JavaLangObject + (T_boolean << 4);
+	final int BOXING = 0x200;
+	final int UNBOXING = 0x400;
+
+	/**
+	 * Marks a type whose type bits have not yet been initialized.
+	 * @see ReferenceBinding#hasTypeBit(int)
+	 */
+	final int BitUninitialized = 0x8000000;
+	/** 
+	 * Marks all sub-types of java.lang.AutoCloseable.
+	 * @see ReferenceBinding#hasTypeBit(int)
+	 */
+	final int BitAutoCloseable = 1;
+	/** 
+	 * Marks all sub-types of java.io.Closeable.
+	 * @see ReferenceBinding#hasTypeBit(int)
+	 */
+	final int BitCloseable = 2;
+	/**
+	 * Bit for members of a white list:
+	 * Subtypes of Closeable that wrap another resource without directly holding any OS resources. 
+	 */
+	final int BitWrapperCloseable = 4;
+	/**
+	 * Bit for members of a white list:
+	 * Subtypes of Closeable that do not hold an OS resource that needs to be released.
+	 */
+	final int BitResourceFreeCloseable = 8;
+	
+	/**
+	 * Set of type bits that should be inherited by any sub types.
+	 */
+	final int InheritableBits = BitAutoCloseable | BitCloseable;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
new file mode 100644
index 0000000..8103f9e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -0,0 +1,520 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     							bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *     							bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *								bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+/**
+ * Binding for a type parameter, held by source/binary type or method.
+ */
+public class TypeVariableBinding extends ReferenceBinding {
+
+	public Binding declaringElement; // binding of declaring type or method
+	public int rank; // declaration rank, can be used to match variable in parameterized type
+
+	/**
+	 * Denote the first explicit (binding) bound amongst the supertypes (from declaration in source)
+	 * If no superclass was specified, then it denotes the first superinterface, or null if none was specified.
+	 */
+	public TypeBinding firstBound;
+
+	// actual resolved variable supertypes (if no superclass bound, then associated to Object)
+	public ReferenceBinding superclass;
+	public ReferenceBinding[] superInterfaces;
+	public char[] genericTypeSignature;
+	LookupEnvironment environment;
+	
+	public TypeVariableBinding(char[] sourceName, Binding declaringElement, int rank, LookupEnvironment environment) {
+		this.sourceName = sourceName;
+		this.declaringElement = declaringElement;
+		this.rank = rank;
+		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat type var as public
+		this.tagBits |= TagBits.HasTypeVariable;
+		this.environment = environment;
+		this.typeBits = TypeIds.BitUninitialized;
+	}
+
+	/**
+	 * Returns true if the argument type satisfies all bounds of the type parameter
+	 */
+	public int boundCheck(Substitution substitution, TypeBinding argumentType, Scope scope) {
+		int code = internalBoundCheck(substitution, argumentType, scope);
+		if (code == TypeConstants.MISMATCH) {
+			if (argumentType instanceof TypeVariableBinding && scope != null) {
+				TypeBinding bound = ((TypeVariableBinding)argumentType).firstBound;
+				if (bound instanceof ParameterizedTypeBinding) {
+					int code2 = boundCheck(substitution, bound.capture(scope, -1), scope); // no position needed as this capture will never escape this context
+					return Math.min(code, code2);
+				}
+			}
+		}
+		return code;
+	}
+	private int internalBoundCheck(Substitution substitution, TypeBinding argumentType, Scope scope) {
+		if (argumentType == TypeBinding.NULL || argumentType == this) {
+			return TypeConstants.OK;
+		}
+		boolean hasSubstitution = substitution != null;
+		if (!(argumentType instanceof ReferenceBinding || argumentType.isArrayType()))
+			return TypeConstants.MISMATCH;
+		// special case for re-entrant source types (selection, code assist, etc)...
+		// can request additional types during hierarchy walk that are found as source types that also 'need' to connect their hierarchy
+		if (this.superclass == null)
+			return TypeConstants.OK;
+
+		if (argumentType.kind() == Binding.WILDCARD_TYPE) {
+			WildcardBinding wildcard = (WildcardBinding) argumentType;
+			switch(wildcard.boundKind) {
+				case Wildcard.EXTENDS :
+					TypeBinding wildcardBound = wildcard.bound;
+					if (wildcardBound == this)
+						return TypeConstants.OK;
+					boolean isArrayBound = wildcardBound.isArrayType();
+					if (!wildcardBound.isInterface()) {
+						TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superclass) : this.superclass;
+						if (substitutedSuperType.id != TypeIds.T_JavaLangObject) {
+							if (isArrayBound) {
+								if (!wildcardBound.isCompatibleWith(substitutedSuperType, scope))
+									return TypeConstants.MISMATCH;
+							} else {
+								TypeBinding match = wildcardBound.findSuperTypeOriginatingFrom(substitutedSuperType);
+								if (match != null) {
+									if (substitutedSuperType.isProvablyDistinct(match)) {
+										return TypeConstants.MISMATCH;
+									}
+								} else {
+									match =  substitutedSuperType.findSuperTypeOriginatingFrom(wildcardBound);
+									if (match != null) {
+										if (match.isProvablyDistinct(wildcardBound)) {
+											return TypeConstants.MISMATCH;
+										}
+									} else {
+										if (!wildcardBound.isTypeVariable() && !substitutedSuperType.isTypeVariable()) {
+											return TypeConstants.MISMATCH;
+										}
+									}
+								}
+							}
+						}
+					}
+					boolean mustImplement = isArrayBound || ((ReferenceBinding)wildcardBound).isFinal();
+					for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+						TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces[i]) : this.superInterfaces[i];
+						if (isArrayBound) {
+							if (!wildcardBound.isCompatibleWith(substitutedSuperType, scope))
+									return TypeConstants.MISMATCH;
+						} else {
+							TypeBinding match = wildcardBound.findSuperTypeOriginatingFrom(substitutedSuperType);
+							if (match != null) {
+								if (substitutedSuperType.isProvablyDistinct(match)) {
+									return TypeConstants.MISMATCH;
+								}
+							} else if (mustImplement) {
+									return TypeConstants.MISMATCH; // cannot be extended further to satisfy missing bounds
+							}
+						}
+
+					}
+					break;
+
+				case Wildcard.SUPER :
+					// if the wildcard is lower-bounded by a type variable that has no relevant upper bound there's nothing to check here (bug 282152):
+					if (wildcard.bound.isTypeVariable() && ((TypeVariableBinding)wildcard.bound).superclass.id == TypeIds.T_JavaLangObject)
+						break;
+					return boundCheck(substitution, wildcard.bound, scope);
+
+				case Wildcard.UNBOUND :
+					break;
+			}
+			return TypeConstants.OK;
+		}
+		boolean unchecked = false;
+		if (this.superclass.id != TypeIds.T_JavaLangObject) {
+			TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superclass) : this.superclass;
+	    	if (substitutedSuperType != argumentType) {
+				if (!argumentType.isCompatibleWith(substitutedSuperType, scope)) {
+				    return TypeConstants.MISMATCH;
+				}
+				TypeBinding match = argumentType.findSuperTypeOriginatingFrom(substitutedSuperType);
+				if (match != null){
+					// Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+					if (match.isRawType() && substitutedSuperType.isBoundParameterizedType())
+						unchecked = true;
+				}
+	    	}
+		}
+	    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+			TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces[i]) : this.superInterfaces[i];
+	    	if (substitutedSuperType != argumentType) {
+				if (!argumentType.isCompatibleWith(substitutedSuperType, scope)) {
+				    return TypeConstants.MISMATCH;
+				}
+				TypeBinding match = argumentType.findSuperTypeOriginatingFrom(substitutedSuperType);
+				if (match != null){
+					// Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+					if (match.isRawType() && substitutedSuperType.isBoundParameterizedType())
+						unchecked = true;
+				}
+	    	}
+	    }
+	    return unchecked ? TypeConstants.UNCHECKED : TypeConstants.OK;
+	}
+
+	public int boundsCount() {
+		if (this.firstBound == null) {
+			return 0;
+		} else if (this.firstBound == this.superclass) {
+			return this.superInterfaces.length + 1;
+		} else {
+			return this.superInterfaces.length;
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
+	 */
+	public boolean canBeInstantiated() {
+		return false;
+	}
+	/**
+	 * Collect the substitutes into a map for certain type variables inside the receiver type
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
+	 * Constraints:
+	 *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
+	 *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
+	 *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
+	 */
+	public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
+
+		//	only infer for type params of the generic method
+		if (this.declaringElement != inferenceContext.genericMethod) return;
+
+		// cannot infer anything from a null type
+		switch (actualType.kind()) {
+			case Binding.BASE_TYPE :
+				if (actualType == TypeBinding.NULL) return;
+				TypeBinding boxedType = scope.environment().computeBoxingType(actualType);
+				if (boxedType == actualType) return;
+				actualType = boxedType;
+				break;
+			case Binding.POLY_TYPE: // cannot steer inference, only learn from it.
+			case Binding.WILDCARD_TYPE :
+				return; // wildcards are not true type expressions (JLS 15.12.2.7, p.453 2nd discussion)
+		}
+
+		// reverse constraint, to reflect variable on rhs:   A << T --> T >: A
+		int variableConstraint;
+		switch(constraint) {
+			case TypeConstants.CONSTRAINT_EQUAL :
+				variableConstraint = TypeConstants.CONSTRAINT_EQUAL;
+				break;
+			case TypeConstants.CONSTRAINT_EXTENDS :
+				variableConstraint = TypeConstants.CONSTRAINT_SUPER;
+				break;
+			default:
+			//case CONSTRAINT_SUPER :
+				variableConstraint =TypeConstants.CONSTRAINT_EXTENDS;
+				break;
+		}
+		inferenceContext.recordSubstitute(this, actualType, variableConstraint);
+	}
+
+	/*
+	 * declaringUniqueKey : genericTypeSignature
+	 * p.X<T> { ... } --> Lp/X;:TT;
+	 * p.X { <T> void foo() {...} } --> Lp/X;.foo()V:TT;
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		StringBuffer buffer = new StringBuffer();
+		Binding declaring = this.declaringElement;
+		if (!isLeaf && declaring.kind() == Binding.METHOD) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=97902
+			MethodBinding methodBinding = (MethodBinding) declaring;
+			ReferenceBinding declaringClass = methodBinding.declaringClass;
+			buffer.append(declaringClass.computeUniqueKey(false/*not a leaf*/));
+			buffer.append(':');
+			MethodBinding[] methods = declaringClass.methods();
+			if (methods != null)
+				for (int i = 0, length = methods.length; i < length; i++) {
+					MethodBinding binding = methods[i];
+					if (binding == methodBinding) {
+						buffer.append(i);
+						break;
+					}
+				}
+		} else {
+			buffer.append(declaring.computeUniqueKey(false/*not a leaf*/));
+			buffer.append(':');
+		}
+		buffer.append(genericTypeSignature());
+		int length = buffer.length();
+		char[] uniqueKey = new char[length];
+		buffer.getChars(0, length, uniqueKey, 0);
+		return uniqueKey;
+	}
+	public char[] constantPoolName() { /* java/lang/Object */
+	    if (this.firstBound != null) {
+			return this.firstBound.constantPoolName();
+	    }
+	    return this.superclass.constantPoolName(); // java/lang/Object
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
+	 */
+	public String debugName() {
+	    return new String(this.sourceName);
+	}
+	public TypeBinding erasure() {
+	    if (this.firstBound != null) {
+			return this.firstBound.erasure();
+	    }
+	    return this.superclass; // java/lang/Object
+	}
+	/**
+	 * T::Ljava/util/Map;:Ljava/io/Serializable;
+	 * T:LY<TT;>
+	 */
+	public char[] genericSignature() {
+	    StringBuffer sig = new StringBuffer(10);
+	    sig.append(this.sourceName).append(':');
+	   	int interfaceLength = this.superInterfaces == null ? 0 : this.superInterfaces.length;
+	    if (interfaceLength == 0 || this.firstBound == this.superclass) {
+	    	if (this.superclass != null)
+		        sig.append(this.superclass.genericTypeSignature());
+	    }
+		for (int i = 0; i < interfaceLength; i++) {
+		    sig.append(':').append(this.superInterfaces[i].genericTypeSignature());
+		}
+		int sigLength = sig.length();
+		char[] genericSignature = new char[sigLength];
+		sig.getChars(0, sigLength, genericSignature, 0);
+		return genericSignature;
+	}
+	/**
+	 * T::Ljava/util/Map;:Ljava/io/Serializable;
+	 * T:LY<TT;>
+	 */
+	public char[] genericTypeSignature() {
+	    if (this.genericTypeSignature != null) return this.genericTypeSignature;
+		return this.genericTypeSignature = CharOperation.concat('T', this.sourceName, ';');
+	}
+
+	boolean hasOnlyRawBounds() {
+		if (this.superclass != null && this.firstBound == this.superclass)
+			if (!this.superclass.isRawType())
+				return false;
+
+		if (this.superInterfaces != null)
+			for (int i = 0, l = this.superInterfaces.length; i < l; i++)
+		   		if (!this.superInterfaces[i].isRawType())
+		   			return false;
+
+		return true;
+	}
+
+	public boolean hasTypeBit(int bit) {
+		if (this.typeBits == TypeIds.BitUninitialized) {
+			// initialize from bounds
+			this.typeBits = 0;
+			if (this.superclass != null && this.superclass.hasTypeBit(~TypeIds.BitUninitialized))
+				this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
+			if (this.superInterfaces != null)
+				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
+					if (this.superInterfaces[i].hasTypeBit(~TypeIds.BitUninitialized))
+						this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits);
+		}
+		return (this.typeBits & bit) != 0;
+	}
+
+	/**
+	 * Returns true if the type variable is directly bound to a given type
+	 */
+	public boolean isErasureBoundTo(TypeBinding type) {
+		if (this.superclass.erasure() == type)
+			return true;
+		for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+			if (this.superInterfaces[i].erasure() == type)
+				return true;
+		}
+		return false;
+	}
+
+	public boolean isHierarchyConnected() {
+		return (this.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0;
+	}
+
+	/**
+	 * Returns true if the 2 variables are playing exact same role: they have
+	 * the same bounds, providing one is substituted with the other: <T1 extends
+	 * List<T1>> is interchangeable with <T2 extends List<T2>>.
+	 */
+	public boolean isInterchangeableWith(TypeVariableBinding otherVariable, Substitution substitute) {
+		if (this == otherVariable)
+			return true;
+		int length = this.superInterfaces.length;
+		if (length != otherVariable.superInterfaces.length)
+			return false;
+
+		if (this.superclass != Scope.substitute(substitute, otherVariable.superclass))
+			return false;
+
+		next : for (int i = 0; i < length; i++) {
+			TypeBinding superType = Scope.substitute(substitute, otherVariable.superInterfaces[i]);
+			for (int j = 0; j < length; j++)
+				if (superType == this.superInterfaces[j])
+					continue next;
+			return false; // not a match
+		}
+		return true;
+	}
+
+	/**
+	 * Returns true if the type was declared as a type variable
+	 */
+	public boolean isTypeVariable() {
+	    return true;
+	}
+
+//	/**
+//	 * Returns the original type variable for a given variable.
+//	 * Only different from receiver for type variables of generic methods of parameterized types
+//	 * e.g. X<U> {   <V1 extends U> U foo(V1)   } --> X<String> { <V2 extends String> String foo(V2)  }
+//	 *         and V2.original() --> V1
+//	 */
+//	public TypeVariableBinding original() {
+//		if (this.declaringElement.kind() == Binding.METHOD) {
+//			MethodBinding originalMethod = ((MethodBinding)this.declaringElement).original();
+//			if (originalMethod != this.declaringElement) {
+//				return originalMethod.typeVariables[this.rank];
+//			}
+//		} else {
+//			ReferenceBinding originalType = (ReferenceBinding)((ReferenceBinding)this.declaringElement).erasure();
+//			if (originalType != this.declaringElement) {
+//				return originalType.typeVariables()[this.rank];
+//			}
+//		}
+//		return this;
+//	}
+
+	public int kind() {
+		return Binding.TYPE_PARAMETER;
+	}
+
+	public TypeBinding[] otherUpperBounds() {
+		if (this.firstBound == null)
+			return Binding.NO_TYPES;
+		if (this.firstBound == this.superclass)
+			return this.superInterfaces;
+		int otherLength = this.superInterfaces.length - 1;
+		if (otherLength > 0) {
+			TypeBinding[] otherBounds;
+			System.arraycopy(this.superInterfaces, 1, otherBounds = new TypeBinding[otherLength], 0, otherLength);
+			return otherBounds;
+		}
+		return Binding.NO_TYPES;
+	}
+
+	/**
+     * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#readableName()
+     */
+    public char[] readableName() {
+        return this.sourceName;
+    }
+	ReferenceBinding resolve() {
+		if ((this.modifiers & ExtraCompilerModifiers.AccUnresolved) == 0)
+			return this;
+
+		TypeBinding oldSuperclass = this.superclass, oldFirstInterface = null;
+		if (this.superclass != null) {
+			ReferenceBinding resolveType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.superclass, this.environment, true /* raw conversion */);
+			this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences;
+			this.superclass = resolveType;
+		}
+		ReferenceBinding[] interfaces = this.superInterfaces;
+		int length;
+		if ((length = interfaces.length) != 0) {
+			oldFirstInterface = interfaces[0];
+			for (int i = length; --i >= 0;) {
+				ReferenceBinding resolveType = (ReferenceBinding) BinaryTypeBinding.resolveType(interfaces[i], this.environment, true /* raw conversion */);
+				this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences;
+				interfaces[i] = resolveType;
+			}
+		}
+		// refresh the firstBound in case it changed
+		if (this.firstBound != null) {
+			if (this.firstBound == oldSuperclass) {
+				this.firstBound = this.superclass;
+			} else if (this.firstBound == oldFirstInterface) {
+				this.firstBound = interfaces[0];
+			}
+		}
+		this.modifiers &= ~ExtraCompilerModifiers.AccUnresolved;
+		return this;
+	}
+	/**
+     * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#shortReadableName()
+     */
+    public char[] shortReadableName() {
+        return readableName();
+    }
+	public ReferenceBinding superclass() {
+		return this.superclass;
+	}
+	
+	public ReferenceBinding[] superInterfaces() {
+		return this.superInterfaces;
+	}
+	
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer(10);
+		buffer.append('<').append(this.sourceName);//.append('[').append(this.rank).append(']');
+		if (this.superclass != null && this.firstBound == this.superclass) {
+		    buffer.append(" extends ").append(this.superclass.debugName()); //$NON-NLS-1$
+		}
+		if (this.superInterfaces != null && this.superInterfaces != Binding.NO_SUPERINTERFACES) {
+		   if (this.firstBound != this.superclass) {
+		        buffer.append(" extends "); //$NON-NLS-1$
+	        }
+		    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+		        if (i > 0 || this.firstBound == this.superclass) {
+		            buffer.append(" & "); //$NON-NLS-1$
+		        }
+				buffer.append(this.superInterfaces[i].debugName());
+			}
+		}
+		buffer.append('>');
+		return buffer.toString();
+	}
+
+	/**
+	 * Upper bound doesn't perform erasure
+	 */
+	public TypeBinding upperBound() {
+		if (this.firstBound != null) {
+			return this.firstBound;
+		}
+		return this.superclass; // java/lang/Object
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java
new file mode 100644
index 0000000..57952ea
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+public class UnresolvedAnnotationBinding extends AnnotationBinding {
+	private LookupEnvironment env;
+	private boolean typeUnresolved = true;
+
+UnresolvedAnnotationBinding(ReferenceBinding type, ElementValuePair[] pairs, LookupEnvironment env) {
+	super(type, pairs);
+	this.env = env;
+}
+
+public ReferenceBinding getAnnotationType() {
+	if (this.typeUnresolved) { // the type is resolved when requested
+		boolean wasToleratingMissingTypeProcessingAnnotations = this.env.mayTolerateMissingType;
+		this.env.mayTolerateMissingType = true; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=388042
+		try {
+			this.type = (ReferenceBinding) BinaryTypeBinding.resolveType(this.type, this.env, false /* no raw conversion for now */);
+				// annotation types are never parameterized
+		} finally {
+			this.env.mayTolerateMissingType = wasToleratingMissingTypeProcessingAnnotations;
+		}
+		this.typeUnresolved = false;
+	}
+	return this.type;
+}
+
+public ElementValuePair[] getElementValuePairs() {
+	if (this.env != null) {
+		if (this.typeUnresolved) {
+			getAnnotationType(); // resolve the annotation type
+		}
+		// resolve method binding and value type (if unresolved) for each pair
+		for (int i = this.pairs.length; --i >= 0;) {
+			ElementValuePair pair = this.pairs[i];
+			MethodBinding[] methods = this.type.getMethods(pair.getName());
+			// there should be exactly one since the type is an annotation type.
+			if (methods != null && methods.length == 1) {
+				pair.setMethodBinding(methods[0]);
+			} // else silently leave a null there
+			Object value = pair.getValue();
+			if (value instanceof UnresolvedReferenceBinding) {
+				pair.setValue(((UnresolvedReferenceBinding) value).
+						resolve(this.env, false));
+							// no parameterized types in annotation values
+			} // do nothing for UnresolvedAnnotationBinding-s, since their
+			  // content is only accessed through get* methods
+		}
+		this.env = null;
+	}
+	return this.pairs;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
new file mode 100644
index 0000000..2da4984
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 349326 - [1.7] new warning for missing try-with-resources
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class UnresolvedReferenceBinding extends ReferenceBinding {
+
+ReferenceBinding resolvedType;
+TypeBinding[] wrappers;
+
+UnresolvedReferenceBinding(char[][] compoundName, PackageBinding packageBinding) {
+	this.compoundName = compoundName;
+	this.sourceName = compoundName[compoundName.length - 1]; // reasonable guess
+	this.fPackage = packageBinding;
+	this.wrappers = null;
+}
+void addWrapper(TypeBinding wrapper, LookupEnvironment environment) {
+	if (this.resolvedType != null) {
+		// the type reference B<B<T>.M> means a signature of <T:Ljava/lang/Object;>LB<LB<TT;>.M;>;
+		// when the ParameterizedType for Unresolved B is created with args B<T>.M, the Unresolved B is resolved before the wrapper is added
+		wrapper.swapUnresolved(this, this.resolvedType, environment);
+		return;
+	}
+	if (this.wrappers == null) {
+		this.wrappers = new TypeBinding[] {wrapper};
+	} else {
+		int length = this.wrappers.length;
+		System.arraycopy(this.wrappers, 0, this.wrappers = new TypeBinding[length + 1], 0, length);
+		this.wrappers[length] = wrapper;
+	}
+}
+public String debugName() {
+	return toString();
+}
+public boolean hasTypeBit(int bit) {
+	// shouldn't happen since we are not called before analyseCode(), but play safe:
+	return false;
+}
+ReferenceBinding resolve(LookupEnvironment environment, boolean convertGenericToRawType) {
+    ReferenceBinding targetType = this.resolvedType;
+	if (targetType == null) {
+		targetType = this.fPackage.getType0(this.compoundName[this.compoundName.length - 1]);
+		if (targetType == this) {
+			targetType = environment.askForType(this.compoundName);
+		}
+		if (targetType == null || targetType == this) { // could not resolve any better, error was already reported against it
+			// report the missing class file first - only if not resolving a previously missing type
+			if ((this.tagBits & TagBits.HasMissingType) == 0 && !environment.mayTolerateMissingType) {
+				environment.problemReporter.isClassPathCorrect(
+					this.compoundName,
+					environment.unitBeingCompleted,
+					environment.missingClassFileLocation);
+			}
+			// create a proxy for the missing BinaryType
+			targetType = environment.createMissingType(null, this.compoundName);
+		}
+		setResolvedType(targetType, environment);
+	}
+	if (convertGenericToRawType) {
+		targetType = (ReferenceBinding) environment.convertUnresolvedBinaryToRawType(targetType);
+	}
+	return targetType;
+}
+void setResolvedType(ReferenceBinding targetType, LookupEnvironment environment) {
+	if (this.resolvedType == targetType) return; // already resolved
+
+	// targetType may be a source or binary type
+	this.resolvedType = targetType;
+	// must ensure to update any other type bindings that can contain the resolved type
+	// otherwise we could create 2 : 1 for this unresolved type & 1 for the resolved type
+	if (this.wrappers != null)
+		for (int i = 0, l = this.wrappers.length; i < l; i++)
+			this.wrappers[i].swapUnresolved(this, targetType, environment);
+	environment.updateCaches(this, targetType);
+}
+public String toString() {
+	return "Unresolved type " + ((this.compoundName != null) ? CharOperation.toString(this.compoundName) : "UNNAMED"); //$NON-NLS-1$ //$NON-NLS-2$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
new file mode 100644
index 0000000..ea28e59
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+
+public abstract class VariableBinding extends Binding {
+
+	public int modifiers;
+	public TypeBinding type;
+	public char[] name;
+	protected Constant constant;
+	public int id; // for flow-analysis (position in flowInfo bit vector)
+	public long tagBits;
+
+	public VariableBinding(char[] name, TypeBinding type, int modifiers, Constant constant) {
+		this.name = name;
+		this.type = type;
+		this.modifiers = modifiers;
+		this.constant = constant;
+		if (type != null) {
+			this.tagBits |= (type.tagBits & TagBits.HasMissingType);
+		}
+	}
+
+	public Constant constant() {
+		return this.constant;
+	}
+
+	public abstract AnnotationBinding[] getAnnotations();
+
+	public final boolean isBlankFinal(){
+		return (this.modifiers & ExtraCompilerModifiers.AccBlankFinal) != 0;
+	}
+	/* Answer true if the receiver is final and cannot be changed
+	*/
+
+	public final boolean isFinal() {
+		return (this.modifiers & ClassFileConstants.AccFinal) != 0;
+	}
+	
+	public final boolean isEffectivelyFinal() {
+		return (this.tagBits & TagBits.IsEffectivelyFinal) != 0;
+	}
+
+	/** Answer true if null annotations are enabled and this field is specified @NonNull */
+	public boolean isNonNull() {
+		return (this.tagBits & TagBits.AnnotationNonNull) != 0;
+	}
+
+	/** Answer true if null annotations are enabled and this field is specified @Nullable */
+	public boolean isNullable() {
+		return (this.tagBits & TagBits.AnnotationNullable) != 0;
+	}
+
+	public char[] readableName() {
+		return this.name;
+	}
+	public void setConstant(Constant constant) {
+		this.constant = constant;
+	}
+	public String toString() {
+		StringBuffer output = new StringBuffer(10);
+		ASTNode.printModifiers(this.modifiers, output);
+		if ((this.modifiers & ExtraCompilerModifiers.AccUnresolved) != 0) {
+			output.append("[unresolved] "); //$NON-NLS-1$
+		}
+		output.append(this.type != null ? this.type.debugName() : "<no type>"); //$NON-NLS-1$
+		output.append(" "); //$NON-NLS-1$
+		output.append((this.name != null) ? new String(this.name) : "<no name>"); //$NON-NLS-1$
+		return output.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
new file mode 100644
index 0000000..bdbf393
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -0,0 +1,712 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *     							bug 349326 - [1.7] new warning for missing try-with-resources
+ *     							bug 359362 - FUP of bug 349326: Resource leak on non-Closeable resource
+ *								bug 358903 - Filter practically unimportant resource leak warnings
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+/*
+ * A wildcard acts as an argument for parameterized types, allowing to
+ * abstract parameterized types, e.g. List<String> is not compatible with List<Object>,
+ * but compatible with List<?>.
+ */
+public class WildcardBinding extends ReferenceBinding {
+
+	public ReferenceBinding genericType;
+	public int rank;
+    public TypeBinding bound; // when unbound denotes the corresponding type variable (so as to retrieve its bound lazily)
+    public TypeBinding[] otherBounds; // only positionned by lub computations (if so, #bound is also set) and associated to EXTENDS mode
+	char[] genericSignature;
+	public int boundKind;
+	ReferenceBinding superclass;
+	ReferenceBinding[] superInterfaces;
+	TypeVariableBinding typeVariable; // corresponding variable
+	LookupEnvironment environment;
+
+	/**
+	 * When unbound, the bound denotes the corresponding type variable (so as to retrieve its bound lazily)
+	 */
+	public WildcardBinding(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind, LookupEnvironment environment) {
+		this.rank = rank;
+	    this.boundKind = boundKind;
+		this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat wildcard as public
+		this.environment = environment;
+		initialize(genericType, bound, otherBounds);
+
+//		if (!genericType.isGenericType() && !(genericType instanceof UnresolvedReferenceBinding)) {
+//			RuntimeException e = new RuntimeException("WILDCARD with NON GENERIC");
+//			e.printStackTrace();
+//			throw e;
+//		}
+		if (genericType instanceof UnresolvedReferenceBinding)
+			((UnresolvedReferenceBinding) genericType).addWrapper(this, environment);
+		if (bound instanceof UnresolvedReferenceBinding)
+			((UnresolvedReferenceBinding) bound).addWrapper(this, environment);
+		this.tagBits |=  TagBits.HasUnresolvedTypeVariables; // cleared in resolve()
+		this.typeBits = TypeIds.BitUninitialized;
+	}
+
+	public int kind() {
+		return this.otherBounds == null ? Binding.WILDCARD_TYPE : Binding.INTERSECTION_TYPE;
+	}
+
+	/**
+	 * Returns true if the argument type satisfies the wildcard bound(s)
+	 */
+	public boolean boundCheck(TypeBinding argumentType) {
+	    switch (this.boundKind) {
+	        case Wildcard.UNBOUND :
+	            return true;
+	        case Wildcard.EXTENDS :
+	            if (!argumentType.isCompatibleWith(this.bound)) return false;
+	            // check other bounds (lub scenario)
+            	for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) {
+            		if (!argumentType.isCompatibleWith(this.otherBounds[i])) return false;
+            	}
+            	return true;
+	        default: // SUPER
+	        	// ? super Exception   ok for:  IOException, since it would be ok for (Exception)ioException
+	            return argumentType.isCompatibleWith(this.bound);
+	    }
+    }
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
+	 */
+	public boolean canBeInstantiated() {
+		// cannot be asked per construction
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#collectMissingTypes(java.util.List)
+	 */
+	public List collectMissingTypes(List missingTypes) {
+		if ((this.tagBits & TagBits.HasMissingType) != 0) {
+			missingTypes = this.bound.collectMissingTypes(missingTypes);
+		}
+		return missingTypes;
+	}
+
+	/**
+	 * Collect the substitutes into a map for certain type variables inside the receiver type
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
+	 * Constraints:
+	 *   A << F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_EXTENDS (1))
+	 *   A = F   corresponds to:      F.collectSubstitutes(..., A, ..., CONSTRAINT_EQUAL (0))
+	 *   A >> F   corresponds to:   F.collectSubstitutes(..., A, ..., CONSTRAINT_SUPER (2))
+	 */
+	public void collectSubstitutes(Scope scope, TypeBinding actualType, InferenceContext inferenceContext, int constraint) {
+
+		if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
+		if (actualType == TypeBinding.NULL || actualType.kind() == POLY_TYPE) return;
+
+		if (actualType.isCapture()) {
+			CaptureBinding capture = (CaptureBinding) actualType;
+			actualType = capture.wildcard;
+		}
+
+		switch (constraint) {
+			case TypeConstants.CONSTRAINT_EXTENDS : // A << F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						switch (actualType.kind()) {
+//						case Binding.WILDCARD_TYPE :
+//							WildcardBinding actualWildcard = (WildcardBinding) actualType;
+//							switch(actualWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} << F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} << F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} << F={?} ---> 0
+//									break;
+//							}
+//							break;
+//						case Binding.INTERSECTION_TYPE :// A={? extends V1&...&Vn} << F={?} ---> 0
+//							break;
+//						default :// A=V << F={?} ---> 0
+//							break;
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						switch(actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} << F={? extends U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} << F={? extends U} ---> V << U
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+										break;
+									case Wildcard.SUPER: // A={? super V} << F={? extends U} ---> 0
+										break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE : // A={? extends V1&...&Vn} << F={? extends U} ---> V1 << U, ..., Vn << U
+								WildcardBinding actualIntersection = (WildcardBinding) actualType;
+								this.bound.collectSubstitutes(scope, actualIntersection.bound, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+					        	for (int i = 0, length = actualIntersection.otherBounds.length; i < length; i++) {
+									this.bound.collectSubstitutes(scope, actualIntersection.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+					        	}
+								break;
+							default : // A=V << F={? extends U} ---> V << U
+								this.bound.collectSubstitutes(scope, actualType, inferenceContext, TypeConstants.CONSTRAINT_EXTENDS);
+								break;
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						switch (actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} << F={? super U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} << F={? super U} ---> 0
+										break;
+									case Wildcard.SUPER: // A={? super V} << F={? super U} ---> 0
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
+											this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	}
+										break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE : // A={? extends V1&...&Vn} << F={? super U} ---> 0
+								break;
+							default :// A=V << F={? super U} ---> V >> U
+								this.bound.collectSubstitutes(scope, actualType, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+								break;
+						}
+						break;
+				}
+				break;
+			case TypeConstants.CONSTRAINT_EQUAL : // A == F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						switch (actualType.kind()) {
+//						case Binding.WILDCARD_TYPE :
+//							WildcardBinding actualWildcard = (WildcardBinding) actualType;
+//							switch(actualWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} == F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} == F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} == F={?} ---> 0
+//									break;
+//							}
+//							break;
+//						case Binding.INTERSECTION_TYPE :// A={? extends V1&...&Vn} == F={?} ---> 0
+//							break;
+//						default :// A=V == F={?} ---> 0
+//							break;
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						switch (actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} == F={? extends U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} == F={? extends U} ---> V == U
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+							        	for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
+											this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+							        	}
+										break;
+									case Wildcard.SUPER: // A={? super V} == F={? extends U} ---> 0
+										break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE : // A={? extends V1&...&Vn} == F={? extends U} ---> V1 == U, ..., Vn == U
+								WildcardBinding actuaIntersection = (WildcardBinding) actualType;
+								this.bound.collectSubstitutes(scope, actuaIntersection.bound, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+					        	for (int i = 0, length = actuaIntersection.otherBounds == null ? 0 : actuaIntersection.otherBounds.length; i < length; i++) {
+									this.bound.collectSubstitutes(scope, actuaIntersection.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+					        	}
+								break;
+							default : // A=V == F={? extends U} ---> 0
+								break;
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						switch (actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} == F={? super U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} == F={? super U} ---> 0
+										break;
+									case Wildcard.SUPER: // A={? super V} == F={? super U} ---> 0
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+							        	for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
+											this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_EQUAL);
+							        	}
+							        	break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE :  // A={? extends V1&...&Vn} == F={? super U} ---> 0
+								break;
+							default : // A=V == F={? super U} ---> 0
+								break;
+						}
+						break;
+				}
+				break;
+			case TypeConstants.CONSTRAINT_SUPER : // A >> F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						switch (actualType.kind()) {
+//						case Binding.WILDCARD_TYPE :
+//							WildcardBinding actualWildcard = (WildcardBinding) actualType;
+//							switch(actualWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} >> F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} >> F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} >> F={?} ---> 0
+//									break;
+//							}
+//							break;
+//						case Binding.INTERSECTION_TYPE :// A={? extends V1&...&Vn} >> F={?} ---> 0
+//							break;
+//						default :// A=V >> F={?} ---> 0
+//							break;
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						switch (actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} >> F={? extends U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} >> F={? extends U} ---> V >> U
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
+											this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	}
+										break;
+									case Wildcard.SUPER: // A={? super V} >> F={? extends U} ---> 0
+										break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE : // A={? extends V1&...&Vn} >> F={? extends U} ---> V1 >> U, ..., Vn >> U
+								WildcardBinding actualIntersection = (WildcardBinding) actualType;
+								this.bound.collectSubstitutes(scope, actualIntersection.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+					        	for (int i = 0, length = actualIntersection.otherBounds == null ? 0 : actualIntersection.otherBounds.length; i < length; i++) {
+									this.bound.collectSubstitutes(scope, actualIntersection.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+					        	}
+								break;
+							default : // A=V == F={? extends U} ---> 0
+								break;
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						switch (actualType.kind()) {
+							case Binding.WILDCARD_TYPE :
+								WildcardBinding actualWildcard = (WildcardBinding) actualType;
+								switch(actualWildcard.boundKind) {
+									case Wildcard.UNBOUND: // A={?} >> F={? super U}  --> 0
+										break;
+									case Wildcard.EXTENDS: // A={? extends V} >> F={? super U} ---> 0
+										break;
+									case Wildcard.SUPER: // A={? super V} >> F={? super U} ---> V >> U
+										this.bound.collectSubstitutes(scope, actualWildcard.bound, inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	for (int i = 0, length = actualWildcard.otherBounds == null ? 0 : actualWildcard.otherBounds.length; i < length; i++) {
+											this.bound.collectSubstitutes(scope, actualWildcard.otherBounds[i], inferenceContext, TypeConstants.CONSTRAINT_SUPER);
+							        	}
+							        	break;
+								}
+								break;
+							case Binding.INTERSECTION_TYPE :  // A={? extends V1&...&Vn} >> F={? super U} ---> 0
+								break;
+							default : // A=V >> F={? super U} ---> 0
+								break;
+						}
+						break;
+				}
+				break;
+		}
+	}
+
+	/*
+	 * genericTypeKey {rank}*|+|- [boundKey]
+	 * p.X<T> { X<?> ... } --> Lp/X<TT;>;{0}*
+	 */
+	public char[] computeUniqueKey(boolean isLeaf) {
+		char[] genericTypeKey = this.genericType.computeUniqueKey(false/*not a leaf*/);
+		char[] wildCardKey;
+		// We now encode the rank also in the binding key - https://bugs.eclipse.org/bugs/show_bug.cgi?id=234609
+		char[] rankComponent = ('{' + String.valueOf(this.rank) + '}').toCharArray();
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND :
+                wildCardKey = TypeConstants.WILDCARD_STAR;
+                break;
+            case Wildcard.EXTENDS :
+                wildCardKey = CharOperation.concat(TypeConstants.WILDCARD_PLUS, this.bound.computeUniqueKey(false/*not a leaf*/));
+                break;
+			default: // SUPER
+			    wildCardKey = CharOperation.concat(TypeConstants.WILDCARD_MINUS, this.bound.computeUniqueKey(false/*not a leaf*/));
+				break;
+        }
+		return CharOperation.concat(genericTypeKey, rankComponent, wildCardKey);
+    }
+
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#constantPoolName()
+	 */
+	public char[] constantPoolName() {
+		return erasure().constantPoolName();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
+	 */
+	public String debugName() {
+	    return toString();
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
+     */
+    public TypeBinding erasure() {
+    	if (this.otherBounds == null) {
+	    	if (this.boundKind == Wildcard.EXTENDS)
+		        return this.bound.erasure();
+			TypeVariableBinding var = typeVariable();
+			if (var != null)
+				return var.erasure();
+		    return this.genericType; // if typeVariable() == null, then its inconsistent & return this.genericType to avoid NPE case
+    	}
+    	// intersection type
+    	return this.bound.id == TypeIds.T_JavaLangObject
+    		? this.otherBounds[0].erasure()  // use first explicit bound to improve stackmap
+    		: this.bound.erasure();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
+     */
+    public char[] genericTypeSignature() {
+        if (this.genericSignature == null) {
+            switch (this.boundKind) {
+                case Wildcard.UNBOUND :
+                    this.genericSignature = TypeConstants.WILDCARD_STAR;
+                    break;
+                case Wildcard.EXTENDS :
+                    this.genericSignature = CharOperation.concat(TypeConstants.WILDCARD_PLUS, this.bound.genericTypeSignature());
+					break;
+				default: // SUPER
+				    this.genericSignature = CharOperation.concat(TypeConstants.WILDCARD_MINUS, this.bound.genericTypeSignature());
+            }
+        }
+        return this.genericSignature;
+    }
+
+	public int hashCode() {
+		return this.genericType.hashCode();
+	}
+
+	public boolean hasTypeBit(int bit) {
+		if (this.typeBits == TypeIds.BitUninitialized) {
+			// initialize from upper bounds
+			this.typeBits = 0;
+			if (this.superclass != null && this.superclass.hasTypeBit(~TypeIds.BitUninitialized))
+				this.typeBits |= (this.superclass.typeBits & TypeIds.InheritableBits);
+			if (this.superInterfaces != null)
+				for (int i = 0, l = this.superInterfaces.length; i < l; i++)
+					if (this.superInterfaces[i].hasTypeBit(~TypeIds.BitUninitialized))
+						this.typeBits |= (this.superInterfaces[i].typeBits & TypeIds.InheritableBits);
+		}
+		return (this.typeBits & bit) != 0;
+	}
+
+	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
+		this.genericType = someGenericType;
+		this.bound = someBound;
+		this.otherBounds = someOtherBounds;
+		if (someGenericType != null) {
+			this.fPackage = someGenericType.getPackage();
+		}
+		if (someBound != null) {
+			this.tagBits |= someBound.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences);
+		}
+		if (someOtherBounds != null) {
+			for (int i = 0, max = someOtherBounds.length; i < max; i++) {
+				TypeBinding someOtherBound = someOtherBounds[i];
+				this.tagBits |= someOtherBound.tagBits & TagBits.ContainsNestedTypeReferences;
+			}
+		}
+	}
+
+	/**
+     * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#isSuperclassOf(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
+     */
+    public boolean isSuperclassOf(ReferenceBinding otherType) {
+        if (this.boundKind == Wildcard.SUPER) {
+            if (this.bound instanceof ReferenceBinding) {
+                return ((ReferenceBinding) this.bound).isSuperclassOf(otherType);
+            } else { // array bound
+                return otherType.id == TypeIds.T_JavaLangObject;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the current type denotes an intersection type: Number & Comparable<?>
+     */
+    public boolean isIntersectionType() {
+    	return this.otherBounds != null;
+    }
+
+	public boolean isHierarchyConnected() {
+		return this.superclass != null && this.superInterfaces != null;
+	}
+
+    /**
+	 * Returns true if the type is a wildcard
+	 */
+	public boolean isUnboundWildcard() {
+	    return this.boundKind == Wildcard.UNBOUND;
+	}
+
+    /**
+	 * Returns true if the type is a wildcard
+	 */
+	public boolean isWildcard() {
+	    return true;
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
+     */
+    public char[] readableName() {
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND :
+                return TypeConstants.WILDCARD_NAME;
+            case Wildcard.EXTENDS :
+            	if (this.otherBounds == null)
+	                return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.readableName());
+            	StringBuffer buffer = new StringBuffer(10);
+            	buffer.append(this.bound.readableName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].readableName());
+            	}
+            	int length;
+				char[] result = new char[length = buffer.length()];
+				buffer.getChars(0, length, result, 0);
+				return result;
+			default: // SUPER
+			    return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.readableName());
+        }
+    }
+
+	ReferenceBinding resolve() {
+		if ((this.tagBits & TagBits.HasUnresolvedTypeVariables) == 0)
+			return this;
+
+		this.tagBits &= ~TagBits.HasUnresolvedTypeVariables;
+		BinaryTypeBinding.resolveType(this.genericType, this.environment, false /* no raw conversion */);
+		switch(this.boundKind) {
+			case Wildcard.EXTENDS :
+				TypeBinding resolveType = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */);
+				this.bound = resolveType;
+				this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences;
+				for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) {
+					resolveType = BinaryTypeBinding.resolveType(this.otherBounds[i], this.environment, true /* raw conversion */);
+					this.otherBounds[i]= resolveType;
+					this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences;
+				}
+				break;
+			case Wildcard.SUPER :
+				resolveType = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */);
+				this.bound = resolveType;
+				this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences;
+				break;
+			case Wildcard.UNBOUND :
+		}
+		return this;
+	}
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
+     */
+    public char[] shortReadableName() {
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND :
+                return TypeConstants.WILDCARD_NAME;
+            case Wildcard.EXTENDS :
+            	if (this.otherBounds == null)
+	                return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.shortReadableName());
+            	StringBuffer buffer = new StringBuffer(10);
+            	buffer.append(this.bound.shortReadableName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].shortReadableName());
+            	}
+            	int length;
+				char[] result = new char[length = buffer.length()];
+				buffer.getChars(0, length, result, 0);
+				return result;
+			default: // SUPER
+			    return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.shortReadableName());
+        }
+    }
+
+    /**
+     * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
+     */
+    public char[] signature() {
+     	// should not be called directly on a wildcard; signature should only be asked on
+    	// original methods or type erasures (which cannot denote wildcards at first level)
+		if (this.signature == null) {
+	        switch (this.boundKind) {
+	            case Wildcard.EXTENDS :
+	                return this.bound.signature();
+				default: // SUPER | UNBOUND
+				    return typeVariable().signature();
+	        }
+		}
+		return this.signature;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#sourceName()
+     */
+    public char[] sourceName() {
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND :
+                return TypeConstants.WILDCARD_NAME;
+            case Wildcard.EXTENDS :
+                return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.sourceName());
+			default: // SUPER
+			    return CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.sourceName());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding#superclass()
+     */
+    public ReferenceBinding superclass() {
+		if (this.superclass == null) {
+			TypeBinding superType = null;
+			if (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface()) {
+				superType = this.bound;
+			} else {
+				TypeVariableBinding variable = typeVariable();
+				if (variable != null) superType = variable.firstBound;
+			}
+			this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
+				? (ReferenceBinding) superType
+				: this.environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+		}
+
+		return this.superclass;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#superInterfaces()
+     */
+    public ReferenceBinding[] superInterfaces() {
+        if (this.superInterfaces == null) {
+        	if (typeVariable() != null) {
+        		this.superInterfaces = this.typeVariable.superInterfaces();
+        	} else {
+        		this.superInterfaces = Binding.NO_SUPERINTERFACES;
+        	}
+			if (this.boundKind == Wildcard.EXTENDS) {
+				if (this.bound.isInterface()) {
+					// augment super interfaces with the wildcard bound
+					int length = this.superInterfaces.length;
+					System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+1], 1, length);
+					this.superInterfaces[0] = (ReferenceBinding) this.bound; // make bound first
+				}
+				if (this.otherBounds != null) {
+					// augment super interfaces with the wildcard otherBounds (interfaces per construction)
+					int length = this.superInterfaces.length;
+					int otherLength = this.otherBounds.length;
+					System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+otherLength], 0, length);
+					for (int i = 0; i < otherLength; i++) {
+						this.superInterfaces[length+i] = (ReferenceBinding) this.otherBounds[i];
+					}
+				}
+			}
+        }
+        return this.superInterfaces;
+    }
+
+	public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
+		boolean affected = false;
+		if (this.genericType == unresolvedType) {
+			this.genericType = resolvedType; // no raw conversion
+			affected = true;
+		}
+		if (this.bound == unresolvedType) {
+			this.bound = env.convertUnresolvedBinaryToRawType(resolvedType);
+			affected = true;
+		}
+		if (this.otherBounds != null) {
+			for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+				if (this.otherBounds[i] == unresolvedType) {
+					this.otherBounds[i] = env.convertUnresolvedBinaryToRawType(resolvedType);
+					affected = true;
+				}
+			}
+		}
+		if (affected)
+			initialize(this.genericType, this.bound, this.otherBounds);
+	}
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND :
+                return new String(TypeConstants.WILDCARD_NAME);
+            case Wildcard.EXTENDS :
+            	if (this.otherBounds == null)
+                	return new String(CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_EXTENDS, this.bound.debugName().toCharArray()));
+            	StringBuffer buffer = new StringBuffer(this.bound.debugName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].debugName());
+            	}
+            	return buffer.toString();
+			default: // SUPER
+			    return new String(CharOperation.concat(TypeConstants.WILDCARD_NAME, TypeConstants.WILDCARD_SUPER, this.bound.debugName().toCharArray()));
+        }
+	}
+	/**
+	 * Returns associated type variable, or null in case of inconsistency
+	 */
+	public TypeVariableBinding typeVariable() {
+		if (this.typeVariable == null) {
+			TypeVariableBinding[] typeVariables = this.genericType.typeVariables();
+			if (this.rank < typeVariables.length)
+				this.typeVariable = typeVariables[this.rank];
+		}
+		return this.typeVariable;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/messages.properties
new file mode 100644
index 0000000..614d5ac
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/messages.properties
@@ -0,0 +1,63 @@
+###############################################################################
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+### compiler messages.
+
+### compilation
+compilation_unresolvedProblem =  Unresolved compilation problem: \n
+compilation_unresolvedProblems = Unresolved compilation problems: \n
+compilation_request    = [parsing    {2} - #{0}/{1}]
+compilation_loadBinary = [reading    {0}.class]
+compilation_process    = [analyzing  {2} - #{0}/{1}]
+compilation_write      = [writing    {1} - #{0}]
+compilation_done       = [completed  {2} - #{0}/{1}]
+compilation_units      = [{0} units compiled]
+compilation_unit       = [{0} unit compiled]
+compilation_internalError = Internal compiler error: {0}
+compilation_beginningToCompile=Beginning to compile
+compilation_processing=Processing {0}
+
+### output
+output_isFile =  Regular file {0} cannot be used as output directory
+output_notValidAll =  Could not create output directory {0}
+output_notValid = Could not create subdirectory {0} into output directory {1}
+
+### problem
+problem_noSourceInformation =
+problem_atLine = (at line {0})
+
+### abort
+abort_invalidAttribute = SANITY CHECK: Invalid attribute for local variable {0}
+abort_invalidExceptionAttribute = SANITY CHECK: Invalid attribute for exception attribute for {0}
+abort_missingCode = Missing code implementation in the compiler
+abort_againstSourceModel = Cannot compile against source model {0} issued from {1}
+abort_invalidOpcode = SANITY CHECK: Invalid opcode {0} at pc {1} for stackmap table attribute for method {2}
+
+### accept
+accept_cannot = Cannot accept the compilation unit:
+
+### parser
+parser_incorrectPath = The path for the javadcl.java file is incorrect
+parser_moveFiles = MOVE FILES IN THE Runtime DIRECTORY OF Parser.class
+parser_syntaxRecovery = SYNTAX RECOVERY
+parser_regularParse = REGULAR PARSE
+parser_missingFile = missing file {0}
+parser_corruptedFile = corrupted file {0}
+parser_endOfFile = end of file
+parser_endOfConstructor = end of constructor
+parser_endOfMethod = end of method
+parser_endOfInitializer = end of initializer
+
+### ast
+ast_missingCode = Missing code gen implementation
+
+### constant
+constant_cannotCastedInto =  {0} constant cannot be casted into {1}
+constant_cannotConvertedTo = {0} constant cannot be converted to {1}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
new file mode 100644
index 0000000..3930516
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -0,0 +1,1752 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Parser specialized for decoding javadoc comments
+ */
+public abstract class AbstractCommentParser implements JavadocTagConstants {
+
+	// Kind of comment parser
+	public final static int COMPIL_PARSER = 0x0001;
+	public final static int DOM_PARSER = 0x0002;
+	public final static int SELECTION_PARSER = 0x0004;
+	public final static int COMPLETION_PARSER = 0x0008;
+	public final static int SOURCE_PARSER = 0x0010;
+	public final static int FORMATTER_COMMENT_PARSER = 0x0020;
+	protected final static int PARSER_KIND = 0x00FF;
+	protected final static int TEXT_PARSE = 0x0100; // flag saying that text must be stored
+	protected final static int TEXT_VERIF = 0x0200; // flag saying that text must be verified
+
+	// Parser recovery states
+	protected final static int QUALIFIED_NAME_RECOVERY = 1;
+	protected final static int ARGUMENT_RECOVERY= 2;
+	protected final static int ARGUMENT_TYPE_RECOVERY = 3;
+	protected final static int EMPTY_ARGUMENT_RECOVERY = 4;
+
+	// Parse infos
+	public Scanner scanner;
+	public char[] source;
+	protected Parser sourceParser;
+	private int currentTokenType = -1;
+
+	// Options
+	public boolean checkDocComment = false;
+	public boolean setJavadocPositions = false;
+	public boolean reportProblems;
+	protected long complianceLevel;
+	protected long sourceLevel;
+	
+	// Support for {@inheritDoc}
+	protected long [] inheritedPositions;
+	protected int inheritedPositionsPtr;
+	private final static int INHERITED_POSITIONS_ARRAY_INCREMENT = 4;
+
+	// Results
+	protected boolean deprecated;
+	protected Object returnStatement;
+
+	// Positions
+	protected int javadocStart, javadocEnd;
+	protected int javadocTextStart, javadocTextEnd = -1;
+	protected int firstTagPosition;
+	protected int index, lineEnd;
+	protected int tokenPreviousPosition, lastIdentifierEndPosition, starPosition;
+	protected int textStart, memberStart;
+	protected int tagSourceStart, tagSourceEnd;
+	protected int inlineTagStart;
+	protected int[] lineEnds;
+
+	// Flags
+	protected boolean lineStarted = false;
+	protected boolean inlineTagStarted = false;
+	protected boolean abort = false;
+	protected int kind;
+	protected int tagValue = NO_TAG_VALUE;
+	protected int lastBlockTagValue = NO_TAG_VALUE;
+
+	// Line pointers
+	private int linePtr, lastLinePtr;
+
+	// Identifier stack
+	protected int identifierPtr;
+	protected char[][] identifierStack;
+	protected int identifierLengthPtr;
+	protected int[] identifierLengthStack;
+	protected long[] identifierPositionStack;
+
+	// Ast stack
+	protected final static int AST_STACK_INCREMENT = 10;
+	protected int astPtr;
+	protected Object[] astStack;
+	protected int astLengthPtr;
+	protected int[] astLengthStack;
+
+
+	protected AbstractCommentParser(Parser sourceParser) {
+		this.sourceParser = sourceParser;
+		this.scanner = new Scanner(false, false, false, ClassFileConstants.JDK1_3, null, null, true/*taskCaseSensitive*/);
+		this.identifierStack = new char[20][];
+		this.identifierPositionStack = new long[20];
+		this.identifierLengthStack = new int[10];
+		this.astStack = new Object[30];
+		this.astLengthStack = new int[20];
+		this.reportProblems = sourceParser != null;
+		if (sourceParser != null) {
+			this.checkDocComment = this.sourceParser.options.docCommentSupport;
+			this.sourceLevel = this.sourceParser.options.sourceLevel;
+			this.scanner.sourceLevel = this.sourceLevel;
+			this.complianceLevel = this.sourceParser.options.complianceLevel;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * Returns true if tag @deprecated is present in javadoc comment.
+	 *
+	 * If javadoc checking is enabled, will also construct an Javadoc node,
+	 * which will be stored into Parser.javadoc slot for being consumed later on.
+	 */
+	protected boolean commentParse() {
+
+		boolean validComment = true;
+		try {
+			// Init local variables
+			this.astLengthPtr = -1;
+			this.astPtr = -1;
+			this.identifierPtr = -1;
+			this.currentTokenType = -1;
+			setInlineTagStarted(false);
+			this.inlineTagStart = -1;
+			this.lineStarted = false;
+			this.returnStatement = null;
+			this.inheritedPositions = null;
+			this.lastBlockTagValue = NO_TAG_VALUE;
+			this.deprecated = false;
+			this.lastLinePtr = getLineNumber(this.javadocEnd);
+			this.textStart = -1;
+			this.abort = false;
+			char previousChar = 0;
+			int invalidTagLineEnd = -1;
+			int invalidInlineTagLineEnd = -1;
+			boolean lineHasStar = true;
+			boolean verifText = (this.kind & TEXT_VERIF) != 0;
+			boolean isDomParser = (this.kind & DOM_PARSER) != 0;
+			boolean isFormatterParser = (this.kind & FORMATTER_COMMENT_PARSER) != 0;
+			int lastStarPosition = -1;
+
+			// Init scanner position
+			this.linePtr = getLineNumber(this.firstTagPosition);
+			int realStart = this.linePtr==1 ? this.javadocStart : this.scanner.getLineEnd(this.linePtr-1)+1;
+			if (realStart < this.javadocStart) realStart = this.javadocStart;
+			this.scanner.resetTo(realStart, this.javadocEnd);
+			this.index = realStart;
+			if (realStart == this.javadocStart) {
+				readChar(); // starting '/'
+				readChar(); // first '*'
+			}
+			int previousPosition = this.index;
+			char nextCharacter = 0;
+			if (realStart == this.javadocStart) {
+				nextCharacter = readChar(); // second '*'
+				while (peekChar() == '*') {
+					nextCharacter = readChar(); // read all contiguous '*'
+				}
+				this.javadocTextStart = this.index;
+			}
+			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.javadocEnd: this.scanner.getLineEnd(this.linePtr) - 1;
+			this.javadocTextEnd = this.javadocEnd - 2; // supposed text end, it will be refined later...
+
+			// Loop on each comment character
+			int textEndPosition = -1;
+			while (!this.abort && this.index < this.javadocEnd) {
+
+				// Store previous position and char
+				previousPosition = this.index;
+				previousChar = nextCharacter;
+
+				// Calculate line end (cannot use this.scanner.linePtr as scanner does not parse line ends again)
+				if (this.index > (this.lineEnd+1)) {
+					updateLineEnd();
+				}
+
+				// Read next char only if token was consumed
+				if (this.currentTokenType < 0) {
+					nextCharacter = readChar(); // consider unicodes
+				} else {
+					previousPosition = this.scanner.getCurrentTokenStartPosition();
+					switch (this.currentTokenType) {
+						case TerminalTokens.TokenNameRBRACE:
+							nextCharacter = '}';
+							break;
+						case TerminalTokens.TokenNameMULTIPLY:
+							nextCharacter = '*';
+							break;
+					default:
+							nextCharacter = this.scanner.currentCharacter;
+					}
+					consumeToken();
+				}
+
+				// Consume rules depending on the read character
+				switch (nextCharacter) {
+					case '@' :
+						// Start tag parsing only if we are on line beginning or at inline tag beginning
+						if ((!this.lineStarted || previousChar == '{')) {
+							if (this.inlineTagStarted) {
+								setInlineTagStarted(false);
+								// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+								// Cannot have @ inside inline comment
+								if (this.reportProblems) {
+									int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
+									this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+								}
+								validComment = false;
+								if (this.textStart != -1 && this.textStart < textEndPosition) {
+									pushText(this.textStart, textEndPosition);
+								}
+								if (isDomParser || isFormatterParser) {
+									refreshInlineTagPosition(textEndPosition);
+								}
+							}
+							if (previousChar == '{') {
+								if (this.textStart != -1) {
+									if (this.textStart < textEndPosition) {
+										pushText(this.textStart, textEndPosition);
+									}
+								}
+								setInlineTagStarted(true);
+								invalidInlineTagLineEnd = this.lineEnd;
+							} else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) {
+								pushText(this.textStart, invalidTagLineEnd);
+							}
+							this.scanner.resetTo(this.index, this.javadocEnd);
+							this.currentTokenType = -1; // flush token cache at line begin
+							try {
+								if (!parseTag(previousPosition)) {
+									// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+									// do not stop the inline tag when error is encountered to get text after
+									validComment = false;
+									// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+									// for DOM AST node, store tag as text in case of invalid syntax
+									if (isDomParser) {
+										createTag();
+									}
+									this.textStart = this.tagSourceEnd+1;
+									invalidTagLineEnd  = this.lineEnd;
+									textEndPosition = this.index;
+								}
+							} catch (InvalidInputException e) {
+								consumeToken();
+							}
+						} else {
+							textEndPosition = this.index;
+							if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+								refreshReturnStatement();
+							} else if (isFormatterParser) {
+								if (this.textStart == -1) this.textStart = previousPosition;
+							}
+						}
+						this.lineStarted = true;
+						break;
+					case '\r':
+					case '\n':
+						if (this.lineStarted) {
+							if (isFormatterParser && !ScannerHelper.isWhitespace(previousChar)) {
+								textEndPosition = previousPosition;
+							}
+							if (this.textStart != -1 && this.textStart < textEndPosition) {
+								pushText(this.textStart, textEndPosition);
+							}
+						}
+						this.lineStarted = false;
+						lineHasStar = false;
+						// Fix bug 51650
+						this.textStart = -1;
+						break;
+					case '}' :
+						if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
+						if (this.inlineTagStarted) {
+							textEndPosition = this.index - 1;
+							if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
+								pushText(this.textStart, textEndPosition);
+							}
+							refreshInlineTagPosition(previousPosition);
+							if (!isFormatterParser) this.textStart = this.index;
+							setInlineTagStarted(false);
+						} else {
+							if (!this.lineStarted) {
+								this.textStart = previousPosition;
+							}
+						}
+						this.lineStarted = true;
+						textEndPosition = this.index;
+						break;
+					case '{' :
+						if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
+						if (this.inlineTagStarted) {
+							setInlineTagStarted(false);
+							// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+							// Cannot have opening brace in inline comment
+							if (this.reportProblems) {
+								int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
+								this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+							}
+							if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
+								pushText(this.textStart, textEndPosition);
+							}
+							refreshInlineTagPosition(textEndPosition);
+							textEndPosition = this.index;
+						} else if (peekChar() != '@') {
+							if (this.textStart == -1) this.textStart = previousPosition;
+							textEndPosition = this.index;
+						}
+						if (!this.lineStarted) {
+							this.textStart = previousPosition;
+						}
+						this.lineStarted = true;
+						this.inlineTagStart = previousPosition;
+						break;
+					case '*' :
+						// Store the star position as text start while formatting
+						lastStarPosition = previousPosition;
+						if (previousChar != '*') {
+							this.starPosition = previousPosition;
+							if (isDomParser || isFormatterParser) {
+								if (lineHasStar) {
+									this.lineStarted = true;
+									if (this.textStart == -1) {
+										this.textStart = previousPosition;
+										if (this.index <= this.javadocTextEnd) textEndPosition = this.index;
+									}
+								}
+								if (!this.lineStarted) {
+									lineHasStar = true;
+								}
+							}
+						}
+						break;
+					case '\u000c' :	/* FORM FEED               */
+					case ' ' :			/* SPACE                   */
+					case '\t' :			/* HORIZONTAL TABULATION   */
+						// Do not include trailing spaces in text while formatting
+						if (isFormatterParser) {
+							if (!ScannerHelper.isWhitespace(previousChar)) {
+								textEndPosition = previousPosition;
+							}
+						} else if (this.lineStarted && isDomParser) {
+							textEndPosition = this.index;
+						}
+						break;
+					case '/':
+						if (previousChar == '*') {
+							// End of javadoc
+							break;
+						}
+						// $FALL-THROUGH$ - fall through default case
+					default :
+						if (isFormatterParser && nextCharacter == '<') {
+							// html tags are meaningful for formatter parser
+							int initialIndex = this.index;
+							this.scanner.resetTo(this.index, this.javadocEnd);
+							if (!ScannerHelper.isWhitespace(previousChar)) {
+								textEndPosition = previousPosition;
+							}
+							if (parseHtmlTag(previousPosition, textEndPosition)) {
+								break;
+							}
+							if (this.abort) return false;
+							// Wrong html syntax continue to process character normally
+							this.scanner.currentPosition = initialIndex;
+							this.index = initialIndex;
+						}
+						if (verifText && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
+						if (!this.lineStarted || this.textStart == -1) {
+							this.textStart = previousPosition;
+						}
+						this.lineStarted = true;
+						textEndPosition = this.index;
+						break;
+				}
+			}
+			this.javadocTextEnd = this.starPosition-1;
+
+			// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+			// Cannot leave comment inside inline comment
+			if (this.inlineTagStarted) {
+				if (this.reportProblems) {
+					int end = this.javadocTextEnd<invalidInlineTagLineEnd ? this.javadocTextEnd : invalidInlineTagLineEnd;
+					if (this.index >= this.javadocEnd) end = invalidInlineTagLineEnd;
+					this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+				}
+				if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) {
+					pushText(this.textStart, textEndPosition);
+				}
+				refreshInlineTagPosition(textEndPosition);
+				setInlineTagStarted(false);
+			} else if (this.lineStarted && this.textStart != -1 && this.textStart <= textEndPosition && (this.textStart < this.starPosition || this.starPosition == lastStarPosition)) {
+				pushText(this.textStart, textEndPosition);
+			}
+			updateDocComment();
+		} catch (Exception ex) {
+			validComment = false;
+		}
+		return validComment;
+	}
+
+	protected void consumeToken() {
+		this.currentTokenType = -1; // flush token cache
+		updateLineEnd();
+	}
+
+	protected abstract Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
+	protected boolean createFakeReference(int start) {
+		// Do nothing by default
+		return true;
+	}
+	protected abstract Object createFieldReference(Object receiver) throws InvalidInputException;
+	protected abstract Object createMethodReference(Object receiver, List arguments) throws InvalidInputException;
+	protected Object createReturnStatement() { return null; }
+	protected abstract void createTag();
+	protected abstract Object createTypeReference(int primitiveToken);
+
+	private int getIndexPosition() {
+		if (this.index > this.lineEnd) {
+			return this.lineEnd;
+		} else {
+			return this.index-1;
+		}
+	}
+
+	/**
+	 * Search the line number corresponding to a specific position.
+	 * Warning: returned position is 1-based index!
+	 * @see Scanner#getLineNumber(int) We cannot directly use this method
+	 * when linePtr field is not initialized.
+	 */
+	private int getLineNumber(int position) {
+
+		if (this.scanner.linePtr != -1) {
+			return Util.getLineNumber(position, this.scanner.lineEnds, 0, this.scanner.linePtr);
+		}
+		if (this.lineEnds == null)
+			return 1;
+		return Util.getLineNumber(position, this.lineEnds, 0, this.lineEnds.length-1);
+	}
+
+	private int getTokenEndPosition() {
+		if (this.scanner.getCurrentTokenEndPosition() > this.lineEnd) {
+			return this.lineEnd;
+		} else {
+			return this.scanner.getCurrentTokenEndPosition();
+		}
+	}
+
+	/**
+	 * @return Returns the currentTokenType.
+	 */
+	protected int getCurrentTokenType() {
+		return this.currentTokenType;
+	}
+
+	/*
+	 * Parse argument in @see tag method reference
+	 */
+	protected Object parseArguments(Object receiver) throws InvalidInputException {
+
+		// Init
+		int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type arg,Type arg,...)
+		int iToken = 0;
+		char[] argName = null;
+		List arguments = new ArrayList(10);
+		int start = this.scanner.getCurrentTokenStartPosition();
+		Object typeRef = null;
+		int dim = 0;
+		boolean isVarargs = false;
+		long[] dimPositions = new long[20]; // assume that there won't be more than 20 dimensions...
+		char[] name = null;
+		long argNamePos = -1;
+
+		// Parse arguments declaration if method reference
+		nextArg : while (this.index < this.scanner.eofPosition) {
+
+			// Read argument type reference
+			try {
+				typeRef = parseQualifiedName(false);
+				if (this.abort) return null; // May be aborted by specialized parser
+			} catch (InvalidInputException e) {
+				break nextArg;
+			}
+			boolean firstArg = modulo == 0;
+			if (firstArg) { // verify position
+				if (iToken != 0)
+					break nextArg;
+			} else if ((iToken % modulo) != 0) {
+					break nextArg;
+			}
+			if (typeRef == null) {
+				if (firstArg && this.currentTokenType == TerminalTokens.TokenNameRPAREN) {
+					// verify characters after arguments declaration (expecting white space or end comment)
+					if (!verifySpaceOrEndComment()) {
+						int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
+						if (this.source[end]=='\n') end--;
+						if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+						return null;
+					}
+					this.lineStarted = true;
+					return createMethodReference(receiver, null);
+				}
+				break nextArg;
+			}
+			iToken++;
+
+			// Read possible additional type info
+			dim = 0;
+			isVarargs = false;
+			if (readToken() == TerminalTokens.TokenNameLBRACKET) {
+				// array declaration
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				while (readToken() == TerminalTokens.TokenNameLBRACKET) {
+					consumeToken();
+					if (readToken() != TerminalTokens.TokenNameRBRACKET) {
+						break nextArg;
+					}
+					consumeToken();
+					dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				}
+			} else if (readToken() == TerminalTokens.TokenNameELLIPSIS) {
+				// ellipsis declaration
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				consumeToken();
+				isVarargs = true;
+			}
+
+			// Read argument name
+			argNamePos = -1;
+			if (readToken() == TerminalTokens.TokenNameIdentifier) {
+				consumeToken();
+				if (firstArg) { // verify position
+					if (iToken != 1)
+						break nextArg;
+				} else if ((iToken % modulo) != 1) {
+						break nextArg;
+				}
+				if (argName == null) { // verify that all arguments name are declared
+					if (!firstArg) {
+						break nextArg;
+					}
+				}
+				argName = this.scanner.getCurrentIdentifierSource();
+				argNamePos = (((long)this.scanner.getCurrentTokenStartPosition())<<32)+this.scanner.getCurrentTokenEndPosition();
+				iToken++;
+			} else if (argName != null) { // verify that no argument name is declared
+				break nextArg;
+			}
+
+			// Verify token position
+			if (firstArg) {
+				modulo = iToken + 1;
+			} else {
+				if ((iToken % modulo) != (modulo - 1)) {
+					break nextArg;
+				}
+			}
+
+			// Read separator or end arguments declaration
+			int token = readToken();
+			name = argName == null ? CharOperation.NO_CHAR : argName;
+			if (token == TerminalTokens.TokenNameCOMMA) {
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
+				arguments.add(argument);
+				consumeToken();
+				iToken++;
+			} else if (token == TerminalTokens.TokenNameRPAREN) {
+				// verify characters after arguments declaration (expecting white space or end comment)
+				if (!verifySpaceOrEndComment()) {
+					int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
+					if (this.source[end]=='\n') end--;
+					if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+					return null;
+				}
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
+				arguments.add(argument);
+				consumeToken();
+				return createMethodReference(receiver, arguments);
+			} else {
+				break nextArg;
+			}
+		}
+
+		// Something wrong happened => Invalid input
+		throw new InvalidInputException();
+	}
+
+	/**
+	 * Parse a possible HTML tag like:
+	 * <ul>
+	 * 	<li>&lt;code&gt;
+	 * 	<li>&lt;br&gt;
+	 * 	<li>&lt;h?&gt;
+	 * </ul>
+	 *
+	 * Note that the default is to do nothing!
+	 *
+	 * @param previousPosition The position of the '<' character on which the tag might start
+	 * @param endTextPosition The position of the end of the previous text
+	 * @return <code>true</code> if a valid html tag has been parsed, <code>false</code>
+	 * 	otherwise
+	 * @throws InvalidInputException If any problem happens during the parse in this area
+	 */
+	protected boolean parseHtmlTag(int previousPosition, int endTextPosition) throws InvalidInputException {
+		return false;
+	}
+
+	/*
+	 * Parse an URL link reference in @see tag
+	 */
+	protected boolean parseHref() throws InvalidInputException {
+		boolean skipComments = this.scanner.skipComments;
+		this.scanner.skipComments = true;
+		try {
+			int start = this.scanner.getCurrentTokenStartPosition();
+			char currentChar = readChar();
+			if (currentChar == 'a' || currentChar == 'A') {
+				this.scanner.currentPosition = this.index;
+				if (readToken() == TerminalTokens.TokenNameIdentifier) {
+					consumeToken();
+					try {
+						if (CharOperation.equals(this.scanner.getCurrentIdentifierSource(), HREF_TAG, false) &&
+							readToken() == TerminalTokens.TokenNameEQUAL) {
+							consumeToken();
+							if (readToken() == TerminalTokens.TokenNameStringLiteral) {
+								consumeToken();
+								while (this.index < this.javadocEnd) { // main loop to search for the </a> pattern
+									// Skip all characters after string literal until closing '>' (see bug 68726)
+									while (readToken() != TerminalTokens.TokenNameGREATER) {
+										if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@' ||
+												(this.inlineTagStarted && this.scanner.currentCharacter == '}')) {
+											// Reset position: we want to rescan last token
+											this.index = this.tokenPreviousPosition;
+											this.scanner.currentPosition = this.tokenPreviousPosition;
+											this.currentTokenType = -1;
+											// Signal syntax error
+											if (this.tagValue != TAG_VALUE_VALUE) { // do not report error for @value tag, this will be done after...
+												if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
+											}
+											return false;
+										}
+										this.currentTokenType = -1; // consume token without updating line end
+									}
+									consumeToken(); // update line end as new lines are allowed in URL description
+									while (readToken() != TerminalTokens.TokenNameLESS) {
+										if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@' ||
+												(this.inlineTagStarted && this.scanner.currentCharacter == '}')) {
+											// Reset position: we want to rescan last token
+											this.index = this.tokenPreviousPosition;
+											this.scanner.currentPosition = this.tokenPreviousPosition;
+											this.currentTokenType = -1;
+											// Signal syntax error
+											if (this.tagValue != TAG_VALUE_VALUE) { // do not report error for @value tag, this will be done after...
+												if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
+											}
+											return false;
+										}
+										consumeToken();
+									}
+									consumeToken();
+									start = this.scanner.getCurrentTokenStartPosition();
+									currentChar = readChar();
+									// search for the </a> pattern and store last char read
+									if (currentChar == '/') {
+										currentChar = readChar();
+										if (currentChar == 'a' || currentChar =='A') {
+											currentChar = readChar();
+											if (currentChar == '>') {
+												return true; // valid href
+											}
+										}
+									}
+									// search for invalid char in tags
+									if (currentChar == '\r' || currentChar == '\n' || currentChar == '\t' || currentChar == ' ') {
+										break;
+									}
+								}
+							}
+						}
+					} catch (InvalidInputException ex) {
+						// Do nothing as we want to keep positions for error message
+					}
+				}
+			}
+			// Reset position: we want to rescan last token
+			this.index = this.tokenPreviousPosition;
+			this.scanner.currentPosition = this.tokenPreviousPosition;
+			this.currentTokenType = -1;
+			// Signal syntax error
+			if (this.tagValue != TAG_VALUE_VALUE) { // do not report error for @value tag, this will be done after...
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeHref(start, this.lineEnd);
+			}
+		}
+		finally {
+			this.scanner.skipComments = skipComments;
+		}
+		return false;
+	}
+
+	/*
+	 * Parse tag followed by an identifier
+	 */
+	protected boolean parseIdentifierTag(boolean report) {
+		int token = readTokenSafely();
+		switch (token) {
+			case TerminalTokens.TokenNameIdentifier:
+				pushIdentifier(true, false);
+				return true;
+		}
+		if (report) {
+			this.sourceParser.problemReporter().javadocMissingIdentifier(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+		}
+		return false;
+	}
+
+	/*
+	 * Parse a method reference in @see tag
+	 */
+	protected Object parseMember(Object receiver) throws InvalidInputException {
+		// Init
+		this.identifierPtr = -1;
+		this.identifierLengthPtr = -1;
+		int start = this.scanner.getCurrentTokenStartPosition();
+		this.memberStart = start;
+
+		// Get member identifier
+		if (readToken() == TerminalTokens.TokenNameIdentifier) {
+			if (this.scanner.currentCharacter == '.') { // member name may be qualified (inner class constructor reference)
+				parseQualifiedName(true);
+			} else {
+				consumeToken();
+				pushIdentifier(true, false);
+			}
+			// Look for next token to know whether it's a field or method reference
+			int previousPosition = this.index;
+			if (readToken() == TerminalTokens.TokenNameLPAREN) {
+				consumeToken();
+				start = this.scanner.getCurrentTokenStartPosition();
+				try {
+					return parseArguments(receiver);
+				} catch (InvalidInputException e) {
+					int end = this.scanner.getCurrentTokenEndPosition() < this.lineEnd ?
+							this.scanner.getCurrentTokenEndPosition() :
+							this.scanner.getCurrentTokenStartPosition();
+					end = end < this.lineEnd ? end : this.lineEnd;
+					if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidSeeReferenceArgs(start, end);
+				}
+				return null;
+			}
+
+			// Reset position: we want to rescan last token
+			this.index = previousPosition;
+			this.scanner.currentPosition = previousPosition;
+			this.currentTokenType = -1;
+
+			// Verify character(s) after identifier (expecting space or end comment)
+			if (!verifySpaceOrEndComment()) {
+				int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
+				if (this.source[end]=='\n') end--;
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, end);
+				return null;
+			}
+			return createFieldReference(receiver);
+		}
+		int end = getTokenEndPosition() - 1;
+		end = start > end ? start : end;
+		if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(start, end);
+		// Reset position: we want to rescan last token
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		return null;
+	}
+
+	/*
+	 * Parse @param tag declaration
+	 */
+	protected boolean parseParam() throws InvalidInputException {
+
+		// Store current state
+		int start = this.tagSourceStart;
+		int end = this.tagSourceEnd;
+		boolean tokenWhiteSpace = this.scanner.tokenizeWhiteSpace;
+		this.scanner.tokenizeWhiteSpace = true;
+
+		try {
+			// Verify that there are whitespaces after tag
+			boolean isCompletionParser = (this.kind & COMPLETION_PARSER) != 0;
+			if (this.scanner.currentCharacter != ' ' && !ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(start, this.scanner.getCurrentTokenEndPosition());
+				if (!isCompletionParser) {
+					this.scanner.currentPosition = start;
+					this.index = start;
+				}
+				this.currentTokenType = -1;
+				return false;
+			}
+
+			// Get first non whitespace token
+			this.identifierPtr = -1;
+			this.identifierLengthPtr = -1;
+			boolean hasMultiLines = this.scanner.currentPosition > (this.lineEnd+1);
+			boolean isTypeParam = false;
+			boolean valid = true, empty = true;
+			boolean mayBeGeneric = this.sourceLevel >= ClassFileConstants.JDK1_5;
+			int token = -1;
+			nextToken: while (true) {
+				this.currentTokenType = -1;
+				try {
+					token = readToken();
+				} catch (InvalidInputException e) {
+					valid = false;
+				}
+				switch (token) {
+					case TerminalTokens.TokenNameIdentifier :
+						if (valid) {
+							// store param name id
+							pushIdentifier(true, false);
+							start = this.scanner.getCurrentTokenStartPosition();
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							break nextToken;
+						}
+						// $FALL-THROUGH$ - fall through next case to report error
+					case TerminalTokens.TokenNameLESS:
+						if (valid && mayBeGeneric) {
+							// store '<' in identifiers stack as we need to add it to tag element (bug 79809)
+							pushIdentifier(true, true);
+							start = this.scanner.getCurrentTokenStartPosition();
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							isTypeParam = true;
+							break nextToken;
+						}
+						// $FALL-THROUGH$ - fall through next case to report error
+					default:
+						if (token == TerminalTokens.TokenNameLEFT_SHIFT) isTypeParam = true;
+						if (valid && !hasMultiLines) start = this.scanner.getCurrentTokenStartPosition();
+						valid = false;
+						if (!hasMultiLines) {
+							empty = false;
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							break;
+						}
+						end = this.lineEnd;
+						// $FALL-THROUGH$ - when several lines, fall through next case to report problem immediately
+					case TerminalTokens.TokenNameWHITESPACE:
+						if (this.scanner.currentPosition > (this.lineEnd+1)) hasMultiLines = true;
+						if (valid) break;
+						// $FALL-THROUGH$ - if not valid fall through next case to report error
+					case TerminalTokens.TokenNameEOF:
+						if (this.reportProblems)
+							if (empty)
+								this.sourceParser.problemReporter().javadocMissingParamName(start, end, this.sourceParser.modifiers);
+							else if (mayBeGeneric && isTypeParam)
+								this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
+							else
+								this.sourceParser.problemReporter().javadocInvalidParamTagName(start, end);
+						if (!isCompletionParser) {
+							this.scanner.currentPosition = start;
+							this.index = start;
+						}
+						this.currentTokenType = -1;
+						return false;
+				}
+			}
+
+			// Scan more tokens for type parameter declaration
+			if (isTypeParam && mayBeGeneric) {
+				// Get type parameter name
+				nextToken: while (true) {
+					this.currentTokenType = -1;
+					try {
+						token = readToken();
+					} catch (InvalidInputException e) {
+						valid = false;
+					}
+					switch (token) {
+						case TerminalTokens.TokenNameWHITESPACE:
+							if (valid && this.scanner.currentPosition <= (this.lineEnd+1)) {
+								break;
+							}
+							// $FALL-THROUGH$ - if not valid fall through next case to report error
+						case TerminalTokens.TokenNameEOF:
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
+							if (!isCompletionParser) {
+								this.scanner.currentPosition = start;
+								this.index = start;
+							}
+							this.currentTokenType = -1;
+							return false;
+						case TerminalTokens.TokenNameIdentifier :
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							if (valid) {
+								// store param name id
+								pushIdentifier(false, false);
+								break nextToken;
+							}
+							break;
+						default:
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							valid = false;
+							break;
+					}
+				}
+
+				// Get last character of type parameter declaration
+				boolean spaces = false;
+				nextToken: while (true) {
+					this.currentTokenType = -1;
+					try {
+						token = readToken();
+					} catch (InvalidInputException e) {
+						valid = false;
+					}
+					switch (token) {
+						case TerminalTokens.TokenNameWHITESPACE:
+							if (this.scanner.currentPosition > (this.lineEnd+1)) {
+								// do not accept type parameter declaration on several lines
+								hasMultiLines = true;
+								valid = false;
+							}
+							spaces = true;
+							if (valid) break;
+							// $FALL-THROUGH$ - if not valid fall through next case to report error
+						case TerminalTokens.TokenNameEOF:
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
+							if (!isCompletionParser) {
+								this.scanner.currentPosition = start;
+								this.index = start;
+							}
+							this.currentTokenType = -1;
+							return false;
+						case TerminalTokens.TokenNameGREATER:
+							end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							if (valid) {
+								// store '>' in identifiers stack as we need to add it to tag element (bug 79809)
+								pushIdentifier(false, true);
+								break nextToken;
+							}
+							break;
+						default:
+							if (!spaces) end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+							valid = false;
+							break;
+					}
+				}
+			}
+
+			// Verify that tag name is well followed by white spaces
+			if (valid) {
+				this.currentTokenType = -1;
+				int restart = this.scanner.currentPosition;
+				try {
+					token = readTokenAndConsume();
+				} catch (InvalidInputException e) {
+					valid = false;
+				}
+				if (token == TerminalTokens.TokenNameWHITESPACE) {
+					this.scanner.resetTo(restart, this.javadocEnd);
+					this.index = restart;
+					return pushParamName(isTypeParam);
+				}
+			}
+			// Report problem
+			this.currentTokenType = -1;
+			if (isCompletionParser) return false;
+			if (this.reportProblems) {
+				// we only need end if we report problems
+				end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+				try {
+					while ((token=readToken()) != TerminalTokens.TokenNameWHITESPACE && token != TerminalTokens.TokenNameEOF) {
+						this.currentTokenType = -1;
+						end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
+					}
+				} catch (InvalidInputException e) {
+					end = this.lineEnd;
+				}
+				if (mayBeGeneric && isTypeParam)
+					this.sourceParser.problemReporter().javadocInvalidParamTypeParameter(start, end);
+				else
+					this.sourceParser.problemReporter().javadocInvalidParamTagName(start, end);
+			}
+			this.scanner.currentPosition = start;
+			this.index = start;
+			this.currentTokenType = -1;
+			return false;
+		} finally {
+			// we have to make sure that this is reset to the previous value even if an exception occurs
+			this.scanner.tokenizeWhiteSpace = tokenWhiteSpace;
+		}
+	}
+
+	/*
+	 * Parse a qualified name and built a type reference if the syntax is valid.
+	 */
+	protected Object parseQualifiedName(boolean reset) throws InvalidInputException {
+
+		// Reset identifier stack if requested
+		if (reset) {
+			this.identifierPtr = -1;
+			this.identifierLengthPtr = -1;
+		}
+
+		// Scan tokens
+		int primitiveToken = -1;
+		int parserKind = this.kind & PARSER_KIND;
+		nextToken : for (int iToken = 0; ; iToken++) {
+			int token = readTokenSafely();
+			switch (token) {
+				case TerminalTokens.TokenNameIdentifier :
+					if (((iToken & 1) != 0)) { // identifiers must be odd tokens
+						break nextToken;
+					}
+					pushIdentifier(iToken == 0, false);
+					consumeToken();
+					break;
+
+				case TerminalTokens.TokenNameDOT :
+					if ((iToken & 1) == 0) { // dots must be even tokens
+						throw new InvalidInputException();
+					}
+					consumeToken();
+					break;
+
+				case TerminalTokens.TokenNameabstract:
+				case TerminalTokens.TokenNameassert:
+				case TerminalTokens.TokenNameboolean:
+				case TerminalTokens.TokenNamebreak:
+				case TerminalTokens.TokenNamebyte:
+				case TerminalTokens.TokenNamecase:
+				case TerminalTokens.TokenNamecatch:
+				case TerminalTokens.TokenNamechar:
+				case TerminalTokens.TokenNameclass:
+				case TerminalTokens.TokenNamecontinue:
+				case TerminalTokens.TokenNamedefault:
+				case TerminalTokens.TokenNamedo:
+				case TerminalTokens.TokenNamedouble:
+				case TerminalTokens.TokenNameelse:
+				case TerminalTokens.TokenNameextends:
+				case TerminalTokens.TokenNamefalse:
+				case TerminalTokens.TokenNamefinal:
+				case TerminalTokens.TokenNamefinally:
+				case TerminalTokens.TokenNamefloat:
+				case TerminalTokens.TokenNamefor:
+				case TerminalTokens.TokenNameif:
+				case TerminalTokens.TokenNameimplements:
+				case TerminalTokens.TokenNameimport:
+				case TerminalTokens.TokenNameinstanceof:
+				case TerminalTokens.TokenNameint:
+				case TerminalTokens.TokenNameinterface:
+				case TerminalTokens.TokenNamelong:
+				case TerminalTokens.TokenNamenative:
+				case TerminalTokens.TokenNamenew:
+				case TerminalTokens.TokenNamenull:
+				case TerminalTokens.TokenNamepackage:
+				case TerminalTokens.TokenNameprivate:
+				case TerminalTokens.TokenNameprotected:
+				case TerminalTokens.TokenNamepublic:
+				case TerminalTokens.TokenNameshort:
+				case TerminalTokens.TokenNamestatic:
+				case TerminalTokens.TokenNamestrictfp:
+				case TerminalTokens.TokenNamesuper:
+				case TerminalTokens.TokenNameswitch:
+				case TerminalTokens.TokenNamesynchronized:
+				case TerminalTokens.TokenNamethis:
+				case TerminalTokens.TokenNamethrow:
+				case TerminalTokens.TokenNametransient:
+				case TerminalTokens.TokenNametrue:
+				case TerminalTokens.TokenNametry:
+				case TerminalTokens.TokenNamevoid:
+				case TerminalTokens.TokenNamevolatile:
+				case TerminalTokens.TokenNamewhile:
+					if (iToken == 0) {
+						pushIdentifier(true, true);
+						primitiveToken = token;
+						consumeToken();
+						break nextToken;
+					}
+					// Fall through default case to verify that we do not leave on a dot
+					//$FALL-THROUGH$
+				default :
+					if (iToken == 0) {
+						if (this.identifierPtr>=0) {
+							this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
+						}
+						return null;
+					}
+					if ((iToken & 1) == 0) { // cannot leave on a dot
+						switch (parserKind) {
+							case COMPLETION_PARSER:
+								if (this.identifierPtr>=0) {
+									this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
+								}
+								return syntaxRecoverQualifiedName(primitiveToken);
+							case DOM_PARSER:
+								if (this.currentTokenType != -1) {
+									// Reset position: we want to rescan last token
+									this.index = this.tokenPreviousPosition;
+									this.scanner.currentPosition = this.tokenPreviousPosition;
+									this.currentTokenType = -1;
+								}
+								// $FALL-THROUGH$ - fall through default case to raise exception
+							default:
+								throw new InvalidInputException();
+						}
+					}
+					break nextToken;
+			}
+		}
+		// Reset position: we want to rescan last token
+		if (parserKind != COMPLETION_PARSER && this.currentTokenType != -1) {
+			this.index = this.tokenPreviousPosition;
+			this.scanner.currentPosition = this.tokenPreviousPosition;
+			this.currentTokenType = -1;
+		}
+		if (this.identifierPtr>=0) {
+			this.lastIdentifierEndPosition = (int) this.identifierPositionStack[this.identifierPtr];
+		}
+		return createTypeReference(primitiveToken);
+	}
+
+	/*
+	 * Parse a reference in @see tag
+	 */
+	protected boolean parseReference() throws InvalidInputException {
+		int currentPosition = this.scanner.currentPosition;
+		try {
+			Object typeRef = null;
+			Object reference = null;
+			int previousPosition = -1;
+			int typeRefStartPosition = -1;
+
+			// Get reference tokens
+			nextToken : while (this.index < this.scanner.eofPosition) {
+				previousPosition = this.index;
+				int token = readTokenSafely();
+				switch (token) {
+					case TerminalTokens.TokenNameStringLiteral : // @see "string"
+						// If typeRef != null we may raise a warning here to let user know there's an unused reference...
+						// Currently as javadoc 1.4.2 ignore it, we do the same (see bug 69302)
+						if (typeRef != null) break nextToken;
+						consumeToken();
+						int start = this.scanner.getCurrentTokenStartPosition();
+						if (this.tagValue == TAG_VALUE_VALUE) {
+							// String reference are not allowed for @value tag
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getTokenEndPosition(), this.sourceParser.modifiers);
+							return false;
+						}
+
+						// verify end line
+						if (verifyEndLine(previousPosition)) {
+							return createFakeReference(start);
+						}
+						if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedText(this.scanner.currentPosition, this.lineEnd);
+						return false;
+					case TerminalTokens.TokenNameLESS : // @see <a href="URL#Value">label</a>
+						// If typeRef != null we may raise a warning here to let user know there's an unused reference...
+						// Currently as javadoc 1.4.2 ignore it, we do the same (see bug 69302)
+						if (typeRef != null) break nextToken;
+						consumeToken();
+						start = this.scanner.getCurrentTokenStartPosition();
+						if (parseHref()) {
+							consumeToken();
+							if (this.tagValue == TAG_VALUE_VALUE) {
+								// String reference are not allowed for @value tag
+								if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getIndexPosition(), this.sourceParser.modifiers);
+								return false;
+							}
+							// verify end line
+							if (verifyEndLine(previousPosition)) {
+								return createFakeReference(start);
+							}
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedText(this.scanner.currentPosition, this.lineEnd);
+						}
+						else if (this.tagValue == TAG_VALUE_VALUE) {
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidValueReference(start, getIndexPosition(), this.sourceParser.modifiers);
+						}
+						return false;
+					case TerminalTokens.TokenNameERROR :
+						consumeToken();
+						if (this.scanner.currentCharacter == '#') { // @see ...#member
+							reference = parseMember(typeRef);
+							if (reference != null) {
+								return pushSeeRef(reference);
+							}
+							return false;
+						}
+						char[] currentError = this.scanner.getCurrentIdentifierSource();
+						if (currentError.length>0 && currentError[0] == '"') {
+							if (this.reportProblems) {
+								boolean isUrlRef = false;
+								if (this.tagValue == TAG_SEE_VALUE) {
+									int length=currentError.length, i=1 /* first char is " */;
+									while (i<length && ScannerHelper.isLetter(currentError[i])) {
+										i++;
+									}
+									if (i<(length-2) && currentError[i] == ':' && currentError[i+1] == '/' && currentError[i+2] == '/') {
+										isUrlRef = true;
+									}
+								}
+								if (isUrlRef) {
+									// https://bugs.eclipse.org/bugs/show_bug.cgi?id=207765
+									// handle invalid URL references in javadoc with dedicated message
+									this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(this.scanner.getCurrentTokenStartPosition(), getTokenEndPosition());
+								} else {
+									this.sourceParser.problemReporter().javadocInvalidReference(this.scanner.getCurrentTokenStartPosition(), getTokenEndPosition());
+								}
+							}
+							return false;
+						}
+						break nextToken;
+					case TerminalTokens.TokenNameIdentifier :
+						if (typeRef == null) {
+							typeRefStartPosition = this.scanner.getCurrentTokenStartPosition();
+							typeRef = parseQualifiedName(true);
+							if (this.abort) return false; // May be aborted by specialized parser
+							break;
+						}
+						break nextToken;
+					default :
+						break nextToken;
+				}
+			}
+
+			// Verify that we got a reference
+			if (reference == null) reference = typeRef;
+			if (reference == null) {
+				this.index = this.tokenPreviousPosition;
+				this.scanner.currentPosition = this.tokenPreviousPosition;
+				this.currentTokenType = -1;
+				if (this.tagValue == TAG_VALUE_VALUE) {
+					if ((this.kind & DOM_PARSER) != 0) createTag();
+					return true;
+				}
+				if (this.reportProblems) {
+					this.sourceParser.problemReporter().javadocMissingReference(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+				}
+				return false;
+			}
+
+			// Reset position at the end of type reference
+			if (this.lastIdentifierEndPosition > this.javadocStart) {
+				this.index = this.lastIdentifierEndPosition+1;
+				this.scanner.currentPosition = this.index;
+			}
+			this.currentTokenType = -1;
+
+			// In case of @value, we have an invalid reference (only static field refs are valid for this tag)
+			if (this.tagValue == TAG_VALUE_VALUE) {
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(typeRefStartPosition, this.lineEnd);
+				return false;
+			}
+
+			int currentIndex = this.index; // store current index
+			char ch = readChar();
+			switch (ch) {
+				// Verify that line end does not start with an open parenthese (which could be a constructor reference wrongly written...)
+				// See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=47215
+				case '(' :
+					if (this.reportProblems) this.sourceParser.problemReporter().javadocMissingHashCharacter(typeRefStartPosition, this.lineEnd, String.valueOf(this.source, typeRefStartPosition, this.lineEnd-typeRefStartPosition+1));
+					return false;
+				// Search for the :// URL pattern
+				// See bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=168849
+				case ':' :
+					ch = readChar();
+					if (ch == '/' && ch == readChar()) {
+						if (this.reportProblems) {
+							this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(typeRefStartPosition, this.lineEnd);
+							return false;
+						}
+					}
+			}
+			// revert to last stored index
+			this.index = currentIndex;
+
+			// Verify that we get white space after reference
+			if (!verifySpaceOrEndComment()) {
+				this.index = this.tokenPreviousPosition;
+				this.scanner.currentPosition = this.tokenPreviousPosition;
+				this.currentTokenType = -1;
+				int end = this.starPosition == -1 ? this.lineEnd : this.starPosition;
+				if (this.source[end]=='\n') end--;
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocMalformedSeeReference(typeRefStartPosition, end);
+				return false;
+			}
+
+			// Everything is OK, store reference
+			return pushSeeRef(reference);
+		}
+		catch (InvalidInputException ex) {
+			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(currentPosition, getTokenEndPosition());
+		}
+		// Reset position to avoid missing tokens when new line was encountered
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		return false;
+	}
+
+	/*
+	 * Parse tag declaration
+	 */
+	protected abstract boolean parseTag(int previousPosition) throws InvalidInputException;
+
+	/*
+	 * Parse @throws tag declaration
+	 */
+	protected boolean parseThrows() {
+		int start = this.scanner.currentPosition;
+		try {
+			Object typeRef = parseQualifiedName(true);
+			if (this.abort) return false; // May be aborted by specialized parser
+			if (typeRef == null) {
+				if (this.reportProblems)
+					this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+			} else {
+				return pushThrowName(typeRef);
+			}
+		} catch (InvalidInputException ex) {
+			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidThrowsClass(start, getTokenEndPosition());
+		}
+		return false;
+	}
+
+	/*
+	 * Return current character without move index position.
+	 */
+	protected char peekChar() {
+		int idx = this.index;
+		char c = this.source[idx++];
+		if (c == '\\' && this.source[idx] == 'u') {
+			int c1, c2, c3, c4;
+			idx++;
+			while (this.source[idx] == 'u')
+				idx++;
+			if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c1 < 0)
+					|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c2 < 0)
+					|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c3 < 0)
+					|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[idx++])) > 15 || c4 < 0))) {
+				c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			}
+		}
+		return c;
+	}
+
+	/*
+	 * push the consumeToken on the identifier stack. Increase the total number of identifier in the stack.
+	 */
+	protected void pushIdentifier(boolean newLength, boolean isToken) {
+
+		int stackLength = this.identifierStack.length;
+		if (++this.identifierPtr >= stackLength) {
+			System.arraycopy(
+				this.identifierStack, 0,
+				this.identifierStack = new char[stackLength + 10][], 0,
+				stackLength);
+			System.arraycopy(
+				this.identifierPositionStack, 0,
+				this.identifierPositionStack = new long[stackLength + 10], 0,
+				stackLength);
+		}
+		this.identifierStack[this.identifierPtr] = isToken ? this.scanner.getCurrentTokenSource() : this.scanner.getCurrentIdentifierSource();
+		this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1);
+
+		if (newLength) {
+			stackLength = this.identifierLengthStack.length;
+			if (++this.identifierLengthPtr >= stackLength) {
+				System.arraycopy(
+					this.identifierLengthStack, 0,
+					this.identifierLengthStack = new int[stackLength + 10], 0,
+					stackLength);
+			}
+			this.identifierLengthStack[this.identifierLengthPtr] = 1;
+		} else {
+			this.identifierLengthStack[this.identifierLengthPtr]++;
+		}
+	}
+
+	/*
+	 * Add a new obj on top of the ast stack.
+	 * If new length is required, then add also a new length in length stack.
+	 */
+	protected void pushOnAstStack(Object node, boolean newLength) {
+
+		if (node == null) {
+			int stackLength = this.astLengthStack.length;
+			if (++this.astLengthPtr >= stackLength) {
+				System.arraycopy(
+					this.astLengthStack, 0,
+					this.astLengthStack = new int[stackLength + AST_STACK_INCREMENT], 0,
+					stackLength);
+			}
+			this.astLengthStack[this.astLengthPtr] = 0;
+			return;
+		}
+
+		int stackLength = this.astStack.length;
+		if (++this.astPtr >= stackLength) {
+			System.arraycopy(
+				this.astStack, 0,
+				this.astStack = new Object[stackLength + AST_STACK_INCREMENT], 0,
+				stackLength);
+			this.astPtr = stackLength;
+		}
+		this.astStack[this.astPtr] = node;
+
+		if (newLength) {
+			stackLength = this.astLengthStack.length;
+			if (++this.astLengthPtr >= stackLength) {
+				System.arraycopy(
+					this.astLengthStack, 0,
+					this.astLengthStack = new int[stackLength + AST_STACK_INCREMENT], 0,
+					stackLength);
+			}
+			this.astLengthStack[this.astLengthPtr] = 1;
+		} else {
+			this.astLengthStack[this.astLengthPtr]++;
+		}
+	}
+
+	/*
+	 * Push a param name in ast node stack.
+	 */
+	protected abstract boolean pushParamName(boolean isTypeParam);
+
+	/*
+	 * Push a reference statement in ast node stack.
+	 */
+	protected abstract boolean pushSeeRef(Object statement);
+
+	/*
+	 * Push a text element in ast node stack
+	 */
+	protected void pushText(int start, int end) {
+		// do not store text by default
+	}
+
+	/*
+	 * Push a throws type ref in ast node stack.
+	 */
+	protected abstract boolean pushThrowName(Object typeRef);
+
+	/*
+	 * Read current character and move index position.
+	 * Warning: scanner position is unchanged using this method!
+	 */
+	protected char readChar() {
+
+		char c = this.source[this.index++];
+		if (c == '\\' && this.source[this.index] == 'u') {
+			int c1, c2, c3, c4;
+			int pos = this.index;
+			this.index++;
+			while (this.source[this.index] == 'u')
+				this.index++;
+			if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0)
+					|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0)
+					|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0)
+					|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) {
+				c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			} else {
+				// TODO (frederic) currently reset to previous position, perhaps signal a syntax error would be more appropriate
+				this.index = pos;
+			}
+		}
+		return c;
+	}
+
+	/*
+	 * Read token only if previous was consumed
+	 */
+	protected int readToken() throws InvalidInputException {
+		if (this.currentTokenType < 0) {
+			this.tokenPreviousPosition = this.scanner.currentPosition;
+			this.currentTokenType = this.scanner.getNextToken();
+			if (this.scanner.currentPosition > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+				this.lineStarted = false;
+				while (this.currentTokenType == TerminalTokens.TokenNameMULTIPLY) {
+					this.currentTokenType = this.scanner.getNextToken();
+				}
+			}
+			this.index = this.scanner.currentPosition;
+			this.lineStarted = true; // after having read a token, line is obviously started...
+		}
+		return this.currentTokenType;
+	}
+
+	protected int readTokenAndConsume() throws InvalidInputException {
+		int token = readToken();
+		consumeToken();
+		return token;
+	}
+
+	/*
+	 * Read token without throwing any InvalidInputException exception.
+	 * Returns TerminalTokens.TokenNameERROR instead.
+	 */
+	protected int readTokenSafely() {
+		int token = TerminalTokens.TokenNameERROR;
+		try {
+			token = readToken();
+		}
+		catch (InvalidInputException iie) {
+			// token is already set to error
+		}
+		return token;
+	}
+
+	protected void recordInheritedPosition(long position) {
+		if (this.inheritedPositions == null) {
+			this.inheritedPositions = new long[INHERITED_POSITIONS_ARRAY_INCREMENT];
+			this.inheritedPositionsPtr = 0;
+		} else {
+			if (this.inheritedPositionsPtr == this.inheritedPositions.length) {
+				System.arraycopy(
+						this.inheritedPositions, 0,
+						this.inheritedPositions = new long[this.inheritedPositionsPtr + INHERITED_POSITIONS_ARRAY_INCREMENT], 0,
+						this.inheritedPositionsPtr);
+			}
+		}
+		this.inheritedPositions[this.inheritedPositionsPtr++] = position;
+	}
+	
+	/*
+	 * Refresh start position and length of an inline tag.
+	 */
+	protected void refreshInlineTagPosition(int previousPosition) {
+		// do nothing by default
+	}
+
+	/*
+	 * Refresh return statement
+	 */
+	protected void refreshReturnStatement() {
+		// do nothing by default
+	}
+
+	/**
+	 * @param started the inlineTagStarted to set
+	 */
+	protected void setInlineTagStarted(boolean started) {
+		this.inlineTagStarted = started;
+	}
+
+	/*
+	 * Entry point for recovery on invalid syntax
+	 */
+	protected Object syntaxRecoverQualifiedName(int primitiveToken) throws InvalidInputException {
+		// do nothing, just an entry point for recovery
+		return null;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		int startPos = this.scanner.currentPosition<this.index ? this.scanner.currentPosition : this.index;
+		int endPos = this.scanner.currentPosition<this.index ? this.index : this.scanner.currentPosition;
+		if (startPos == this.source.length)
+			return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
+		if (endPos > this.source.length)
+			return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
+
+		char front[] = new char[startPos];
+		System.arraycopy(this.source, 0, front, 0, startPos);
+
+		int middleLength = (endPos - 1) - startPos + 1;
+		char middle[];
+		if (middleLength > -1) {
+			middle = new char[middleLength];
+			System.arraycopy(
+				this.source,
+				startPos,
+				middle,
+				0,
+				middleLength);
+		} else {
+			middle = CharOperation.NO_CHAR;
+		}
+
+		char end[] = new char[this.source.length - (endPos - 1)];
+		System.arraycopy(
+			this.source,
+			(endPos - 1) + 1,
+			end,
+			0,
+			this.source.length - (endPos - 1) - 1);
+
+		buffer.append(front);
+		if (this.scanner.currentPosition<this.index) {
+			buffer.append("\n===============================\nScanner current position here -->"); //$NON-NLS-1$
+		} else {
+			buffer.append("\n===============================\nParser index here -->"); //$NON-NLS-1$
+		}
+		buffer.append(middle);
+		if (this.scanner.currentPosition<this.index) {
+			buffer.append("<-- Parser index here\n===============================\n"); //$NON-NLS-1$
+		} else {
+			buffer.append("<-- Scanner current position here\n===============================\n"); //$NON-NLS-1$
+		}
+		buffer.append(end);
+
+		return buffer.toString();
+	}
+
+	/*
+	 * Update
+	 */
+	protected abstract void updateDocComment();
+
+	/*
+	 * Update line end
+	 */
+	protected void updateLineEnd() {
+		while (this.index > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+			if (this.linePtr < this.lastLinePtr) {
+				this.lineEnd = this.scanner.getLineEnd(++this.linePtr) - 1;
+			} else {
+				this.lineEnd = this.javadocEnd;
+				return;
+			}
+		}
+	}
+
+	/*
+	 * Verify that end of the line only contains space characters or end of comment.
+	 * Note that end of comment may be preceding by several contiguous '*' chars.
+	 */
+	protected boolean verifyEndLine(int textPosition) {
+		boolean domParser = (this.kind & DOM_PARSER) != 0;
+		// Special case for inline tag
+		if (this.inlineTagStarted) {
+			// expecting closing brace
+			if (peekChar() == '}') {
+				if (domParser) {
+					createTag();
+					pushText(textPosition, this.index);
+				}
+				return true;
+			}
+			return false;
+		}
+
+		int startPosition = this.index;
+		int previousPosition = this.index;
+		this.starPosition = -1;
+		char ch = readChar();
+		nextChar: while (true) {
+			switch (ch) {
+				case '\r':
+				case '\n':
+					if (domParser) {
+						createTag();
+						pushText(textPosition, previousPosition);
+					}
+					this.index = previousPosition;
+					return true;
+				case '\u000c' :	/* FORM FEED               */
+				case ' ' :			/* SPACE                   */
+				case '\t' :			/* HORIZONTAL TABULATION   */
+					if (this.starPosition >= 0) break nextChar;
+					break;
+				case '*':
+					this.starPosition = previousPosition;
+					break;
+				case '/':
+					if (this.starPosition >= textPosition) { // valid only if a star was the previous character
+						if (domParser) {
+							createTag();
+							pushText(textPosition, this.starPosition);
+						}
+						return true;
+					}
+					break nextChar;
+				default :
+					// leave loop
+					break nextChar;
+
+			}
+			previousPosition = this.index;
+			ch = readChar();
+		}
+		this.index = startPosition;
+		return false;
+	}
+
+	/*
+	 * Verify characters after a name matches one of following conditions:
+	 * 	1- first character is a white space
+	 * 	2- first character is a closing brace *and* we're currently parsing an inline tag
+	 * 	3- are the end of comment (several contiguous star ('*') characters may be
+	 * 	    found before the last slash ('/') character).
+	 */
+	protected boolean verifySpaceOrEndComment() {
+		this.starPosition = -1;
+		int startPosition = this.index;
+		// Whitespace or inline tag closing brace
+		char ch = peekChar();
+		switch (ch) {
+			case '}':
+				return this.inlineTagStarted;
+			default:
+				if (ScannerHelper.isWhitespace(ch)) {
+					return true;
+				}
+		}
+		// End of comment
+		int previousPosition = this.index;
+		ch = readChar();
+		while (this.index<this.source.length) {
+			switch (ch) {
+				case '*':
+					// valid whatever the number of star before last '/'
+					this.starPosition = previousPosition;
+					break;
+				case '/':
+					if (this.starPosition >= startPosition) { // valid only if a star was the previous character
+						return true;
+					}
+					// $FALL-THROUGH$ - fall through to invalid case
+				default :
+					// invalid whatever other character, even white spaces
+					this.index = startPosition;
+					return false;
+
+			}
+			previousPosition = this.index;
+			ch = readChar();
+		}
+		this.index = startPosition;
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ConflictedParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ConflictedParser.java
new file mode 100644
index 0000000..6ee4085
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ConflictedParser.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+public interface ConflictedParser {
+	
+	/* Return true if at the configuration the parser finds itself in, token would need to be disambiguated.
+	   At Java SE 8 time, we have three tokens that need to clarified: the use of '( and that of '<' and finally
+	   whether an @ begins a SE8 style type annotation or a SE5 declaration annotation. Where they can co-exist,
+	   we treat the type annotation as a declarative annotation.
+	*/
+	boolean atConflictScenario(int token);
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
new file mode 100644
index 0000000..90044ae
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -0,0 +1,979 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Parser specialized for decoding javadoc comments
+ */
+public class JavadocParser extends AbstractCommentParser {
+
+	// Public fields
+	public Javadoc docComment;
+
+	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+	// Store param references for tag with invalid syntax
+	private int invalidParamReferencesPtr = -1;
+	private ASTNode[] invalidParamReferencesStack;
+
+	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399
+	// Store value tag positions
+	private long validValuePositions, invalidValuePositions;
+
+	// returns whether this JavadocParser should report errors or not (overrides reportProblems)
+	// see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=192449"
+	public boolean shouldReportProblems = true;
+	
+	// flag to let the parser know that the current tag is waiting for a description
+	// see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=222900"
+	private int tagWaitingForDescription;
+
+	public JavadocParser(Parser sourceParser) {
+		super(sourceParser);
+		this.kind = COMPIL_PARSER | TEXT_VERIF;
+		if (sourceParser != null && sourceParser.options != null) {
+			this.setJavadocPositions = sourceParser.options.processAnnotations;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * Returns true if tag @deprecated is present in javadoc comment.
+	 *
+	 * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
+	 * slot for being consumed later on.
+	 */
+	public boolean checkDeprecation(int commentPtr) {
+
+		// Store javadoc positions
+		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
+		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1;
+		this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr];
+		this.validValuePositions = -1;
+		this.invalidValuePositions = -1;
+		this.tagWaitingForDescription = NO_TAG_VALUE;
+
+		// Init javadoc if necessary
+		if (this.checkDocComment) {
+			this.docComment = new Javadoc(this.javadocStart, this.javadocEnd);
+		} else if (this.setJavadocPositions) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=189459
+			// if annotation processors are there, javadoc object is required but
+			// they need not be resolved
+			this.docComment = new Javadoc(this.javadocStart, this.javadocEnd);
+			this.docComment.bits &= ~ASTNode.ResolveJavadoc;
+		} else {
+			this.docComment = null;
+		}
+
+		// If there's no tag in javadoc, return without parsing it
+		if (this.firstTagPosition == 0) {
+			switch (this.kind & PARSER_KIND) {
+				case COMPIL_PARSER:
+				case SOURCE_PARSER:
+					return false;
+			}
+		}
+
+		// Parse
+		try {
+			this.source = this.sourceParser.scanner.source;
+			this.scanner.setSource(this.source); // updating source in scanner
+			if (this.checkDocComment) {
+				// Initialization
+				this.scanner.lineEnds = this.sourceParser.scanner.lineEnds;
+				this.scanner.linePtr = this.sourceParser.scanner.linePtr;
+				this.lineEnds = this.scanner.lineEnds;
+				commentParse();
+			} else {
+
+				// Parse comment
+				Scanner sourceScanner = this.sourceParser.scanner;
+				int firstLineNumber = Util.getLineNumber(this.javadocStart, sourceScanner.lineEnds, 0, sourceScanner.linePtr);
+				int lastLineNumber = Util.getLineNumber(this.javadocEnd, sourceScanner.lineEnds, 0, sourceScanner.linePtr);
+				this.index = this.javadocStart +3;
+
+				// scan line per line, since tags must be at beginning of lines only
+				this.deprecated = false;
+				nextLine : for (int line = firstLineNumber; line <= lastLineNumber; line++) {
+					int lineStart = line == firstLineNumber
+							? this.javadocStart + 3 // skip leading /**
+							: this.sourceParser.scanner.getLineStart(line);
+					this.index = lineStart;
+					this.lineEnd = line == lastLineNumber
+							? this.javadocEnd - 2 // remove trailing * /
+							: this.sourceParser.scanner.getLineEnd(line);
+					nextCharacter : while (this.index < this.lineEnd) {
+						char c = readChar(); // consider unicodes
+						switch (c) {
+							case '*' :
+							case '\u000c' :	/* FORM FEED               */
+							case ' ' :			/* SPACE                   */
+							case '\t' :			/* HORIZONTAL TABULATION   */
+							case '\n' :			/* LINE FEED   */
+							case '\r' :			/* CR */
+								// do nothing for space or '*' characters
+						        continue nextCharacter;
+						    case '@' :
+						    	parseSimpleTag();
+						    	if (this.tagValue == TAG_DEPRECATED_VALUE) {
+						    		if (this.abort) break nextCharacter;
+						    	}
+						}
+			        	continue nextLine;
+					}
+				}
+				return this.deprecated;
+			}
+		} finally {
+			this.source = null; // release source as soon as finished
+			this.scanner.setSource((char[]) null); //release source in scanner
+		}
+		return this.deprecated;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createArgumentReference(char[], java.lang.Object, int)
+	 */
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+		try {
+			TypeReference argTypeRef = (TypeReference) typeRef;
+			if (dim > 0) {
+				long pos = (((long) argTypeRef.sourceStart) << 32) + argTypeRef.sourceEnd;
+				if (typeRef instanceof JavadocSingleTypeReference) {
+					JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
+					argTypeRef = new JavadocArraySingleTypeReference(singleRef.token, dim, pos);
+				} else {
+					JavadocQualifiedTypeReference qualifRef = (JavadocQualifiedTypeReference) typeRef;
+					argTypeRef = new JavadocArrayQualifiedTypeReference(qualifRef, dim);
+				}
+			}
+			int argEnd = argTypeRef.sourceEnd;
+			if (dim > 0) {
+				argEnd = (int) dimPositions[dim-1];
+				if (isVarargs) {
+					argTypeRef.bits |= ASTNode.IsVarArgs; // set isVarArgs
+				}
+			}
+			if (argNamePos >= 0) argEnd = (int) argNamePos;
+			return new JavadocArgumentExpression(name, argTypeRef.sourceStart, argEnd, argTypeRef);
+		}
+		catch (ClassCastException ex) {
+			throw new InvalidInputException();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createFieldReference()
+	 */
+	protected Object createFieldReference(Object receiver) throws InvalidInputException {
+		try {
+			// Get receiver type
+			TypeReference typeRef = (TypeReference) receiver;
+			if (typeRef == null) {
+				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
+				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
+			}
+			// Create field
+			JavadocFieldReference field = new JavadocFieldReference(this.identifierStack[0], this.identifierPositionStack[0]);
+			field.receiver = typeRef;
+			field.tagSourceStart = this.tagSourceStart;
+			field.tagSourceEnd = this.tagSourceEnd;
+			field.tagValue = this.tagValue;
+			return field;
+		}
+		catch (ClassCastException ex) {
+			throw new InvalidInputException();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createMethodReference(java.lang.Object[])
+	 */
+	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+		try {
+			// Get receiver type
+			TypeReference typeRef = (TypeReference) receiver;
+			// Decide whether we have a constructor or not
+			boolean isConstructor = false;
+			int length = this.identifierLengthStack[0];	// may be > 1 for member class constructor reference
+			if (typeRef == null) {
+				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
+				TypeDeclaration typeDecl = getParsedTypeDeclaration();
+				if (typeDecl != null) {
+					name = typeDecl.name;
+				}
+				isConstructor = CharOperation.equals(this.identifierStack[length-1], name);
+				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
+			} else {
+				if (typeRef instanceof JavadocSingleTypeReference) {
+					char[] name = ((JavadocSingleTypeReference)typeRef).token;
+					isConstructor = CharOperation.equals(this.identifierStack[length-1], name);
+				} else if (typeRef instanceof JavadocQualifiedTypeReference) {
+					char[][] tokens = ((JavadocQualifiedTypeReference)typeRef).tokens;
+					int last = tokens.length-1;
+					isConstructor = CharOperation.equals(this.identifierStack[length-1], tokens[last]);
+					if (isConstructor) {
+						boolean valid = true;
+						if (valid) {
+							for (int i=0; i<length-1 && valid; i++) {
+								valid = CharOperation.equals(this.identifierStack[i], tokens[i]);
+							}
+						}
+						if (!valid) {
+							if (this.reportProblems) {
+								this.sourceParser.problemReporter().javadocInvalidMemberTypeQualification((int)(this.identifierPositionStack[0]>>>32), (int)this.identifierPositionStack[length-1], -1);
+							}
+							return null;
+						}
+					}
+				} else {
+					throw new InvalidInputException();
+				}
+			}
+			// Create node
+			if (arguments == null) {
+				if (isConstructor) {
+					JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]);
+					allocation.type = typeRef;
+					allocation.tagValue = this.tagValue;
+					allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition();
+					if (length == 1) {
+						allocation.qualification = new char[][] { this.identifierStack[0] };
+					} else {
+						System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length);
+						allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32);
+					}
+					allocation.memberStart = this.memberStart;
+					return allocation;
+				} else {
+					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1]);
+					msg.receiver = typeRef;
+					msg.tagValue = this.tagValue;
+					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
+					return msg;
+				}
+			} else {
+				JavadocArgumentExpression[] expressions = new JavadocArgumentExpression[arguments.size()];
+				arguments.toArray(expressions);
+				if (isConstructor) {
+					JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]);
+					allocation.arguments = expressions;
+					allocation.type = typeRef;
+					allocation.tagValue = this.tagValue;
+					allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition();
+					if (length == 1) {
+						allocation.qualification = new char[][] { this.identifierStack[0] };
+					} else {
+						System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length);
+						allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32);
+					}
+					allocation.memberStart = this.memberStart;
+					return allocation;
+				} else {
+					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1], expressions);
+					msg.receiver = typeRef;
+					msg.tagValue = this.tagValue;
+					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
+					return msg;
+				}
+			}
+		}
+		catch (ClassCastException ex) {
+			throw new InvalidInputException();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createReturnStatement()
+	 */
+	protected Object createReturnStatement() {
+		return new JavadocReturnStatement(this.scanner.getCurrentTokenStartPosition(),
+					this.scanner.getCurrentTokenEndPosition());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseTagName()
+	 */
+	protected void createTag() {
+		this.tagValue = TAG_OTHERS_VALUE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createTypeReference()
+	 */
+	protected Object createTypeReference(int primitiveToken) {
+		TypeReference typeRef = null;
+		int size = this.identifierLengthStack[this.identifierLengthPtr];
+		if (size == 1) { // Single Type ref
+			typeRef = new JavadocSingleTypeReference(
+						this.identifierStack[this.identifierPtr],
+						this.identifierPositionStack[this.identifierPtr],
+						this.tagSourceStart,
+						this.tagSourceEnd);
+		} else if (size > 1) { // Qualified Type ref
+			char[][] tokens = new char[size][];
+			System.arraycopy(this.identifierStack, this.identifierPtr - size + 1, tokens, 0, size);
+			long[] positions = new long[size];
+			System.arraycopy(this.identifierPositionStack, this.identifierPtr - size + 1, positions, 0, size);
+			typeRef = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd);
+		}
+		return typeRef;
+	}
+
+	/*
+	 * Get current parsed type declaration.
+	 */
+	protected TypeDeclaration getParsedTypeDeclaration() {
+		int ptr = this.sourceParser.astPtr;
+		while (ptr >= 0) {
+			Object node = this.sourceParser.astStack[ptr];
+			if (node instanceof TypeDeclaration) {
+				TypeDeclaration typeDecl = (TypeDeclaration) node;
+				if (typeDecl.bodyEnd == 0) { // type declaration currenly parsed
+					return typeDecl;
+				}
+			}
+			ptr--;
+		}
+		return null;
+	}
+
+	/*
+	 * Parse @throws tag declaration and flag missing description if corresponding option is enabled
+	 */
+	protected boolean parseThrows() {
+		boolean valid = super.parseThrows();
+		this.tagWaitingForDescription = valid && this.reportProblems ? TAG_THROWS_VALUE : NO_TAG_VALUE;
+		return valid;
+	}
+
+	/*
+	 * Parse @return tag declaration
+	 */
+	protected boolean parseReturn() {
+		if (this.returnStatement == null) {
+			this.returnStatement = createReturnStatement();
+			return true;
+		}
+		if (this.reportProblems) {
+			this.sourceParser.problemReporter().javadocDuplicatedReturnTag(
+				this.scanner.getCurrentTokenStartPosition(),
+				this.scanner.getCurrentTokenEndPosition());
+		}
+		return false;
+	}
+
+
+	protected void parseSimpleTag() {
+
+		// Read first char
+		// readChar() code is inlined to balance additional method call in checkDeprectation(int)
+		char first = this.source[this.index++];
+		if (first == '\\' && this.source[this.index] == 'u') {
+			int c1, c2, c3, c4;
+			int pos = this.index;
+			this.index++;
+			while (this.source[this.index] == 'u')
+				this.index++;
+			if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0)
+					|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0)
+					|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0)
+					|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) {
+				first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			} else {
+				this.index = pos;
+			}
+		}
+
+		// switch on first tag char
+		switch (first) {
+			case 'd':
+		        if ((readChar() == 'e') &&
+						(readChar() == 'p') && (readChar() == 'r') &&
+						(readChar() == 'e') && (readChar() == 'c') &&
+						(readChar() == 'a') && (readChar() == 't') &&
+						(readChar() == 'e') && (readChar() == 'd')) {
+					// ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
+					char c = readChar();
+					if (ScannerHelper.isWhitespace(c) || c == '*') {
+						this.abort = true;
+			    		this.deprecated = true;
+						this.tagValue = TAG_DEPRECATED_VALUE;
+					}
+		        }
+				break;
+		}
+	}
+
+	protected boolean parseTag(int previousPosition) throws InvalidInputException {
+
+		// Complain when tag is missing a description
+		// Note that if the parse of an inline tag has already started, consider it
+		// as the expected description, hence do not report any warning
+		switch (this.tagWaitingForDescription) {
+			case TAG_PARAM_VALUE:
+			case TAG_THROWS_VALUE:
+				if (!this.inlineTagStarted) {
+					int start = (int) (this.identifierPositionStack[0] >>> 32);
+					int end = (int) this.identifierPositionStack[this.identifierPtr];
+					this.sourceParser.problemReporter().javadocMissingTagDescriptionAfterReference(start, end, this.sourceParser.modifiers);
+				}
+				break;
+			case NO_TAG_VALUE:
+				break;
+			default:
+				if (!this.inlineTagStarted) {
+					this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+				}
+				break;
+		}
+		this.tagWaitingForDescription = NO_TAG_VALUE;
+
+		// Verify first character
+		this.tagSourceStart = this.index;
+		this.tagSourceEnd = previousPosition;
+		this.scanner.startPosition = this.index;
+		int currentPosition = this.index;
+		char firstChar = readChar();
+		switch (firstChar) {
+			case ' ':
+			case '*':
+			case '}':
+			case '#':
+				// the first character is not valid, hence report invalid empty tag
+				if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(previousPosition, currentPosition);
+				if (this.textStart == -1) this.textStart = currentPosition;
+				this.scanner.currentCharacter = firstChar;
+				return false;
+			default:
+				if (ScannerHelper.isWhitespace(firstChar)) {
+					// the first character is not valid, hence report invalid empty tag
+					if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(previousPosition, currentPosition);
+					if (this.textStart == -1) this.textStart = currentPosition;
+					this.scanner.currentCharacter = firstChar;
+					return false;
+				}
+				break;
+		}
+		
+		// Read tag name
+		char[] tagName = new char[32];
+		int length = 0;
+		char currentChar = firstChar;
+		int tagNameLength = tagName.length;
+		boolean validTag = true;
+		tagLoop: while (true) {
+			if (length == tagNameLength) {
+				System.arraycopy(tagName, 0, tagName = new char[tagNameLength+32], 0, tagNameLength);
+				tagNameLength = tagName.length;
+			}
+			tagName[length++] = currentChar;
+			currentPosition = this.index;
+			currentChar = readChar();
+			switch (currentChar) {
+				case ' ':
+				case '*':
+				case '}':
+					// these characters mark the end of the tag reading
+					break tagLoop;
+				case '#':
+					// invalid tag character, mark the tag as invalid but continue until the end of the tag
+					validTag = false;
+					break;
+				default:
+					if (ScannerHelper.isWhitespace(currentChar)) {
+						// whitespace characters mark the end of the tag reading
+						break tagLoop;
+					}
+					break;
+			}
+		}
+
+		// Init positions
+		this.tagSourceEnd = currentPosition - 1;
+		this.scanner.currentCharacter = currentChar;
+		this.scanner.currentPosition = currentPosition;
+		this.index = this.tagSourceEnd+1;
+
+		// Return if the tag is not valid
+		if (!validTag) {
+			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd);
+			if (this.textStart == -1) this.textStart = this.index;
+			this.scanner.currentCharacter = currentChar;
+			return false;
+		}
+
+		// Decide which parse to perform depending on tag name
+		this.tagValue = TAG_OTHERS_VALUE;
+		boolean valid = false;
+		switch (firstChar) {
+			case 'a':
+				if (length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName, 0, length)) {
+					this.tagValue = TAG_AUTHOR_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				}
+				break;
+			case 'c':
+				if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName, 0, length)) {
+					this.tagValue = TAG_CATEGORY_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec
+					}
+				} else if (length == TAG_CODE_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_CODE, tagName, 0, length)) {
+					this.tagValue = TAG_CODE_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				}
+				break;
+			case 'd':
+				if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName, 0, length)) {
+					this.deprecated = true;
+					valid = true;
+					this.tagValue = TAG_DEPRECATED_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				} else if (length == TAG_DOC_ROOT_LENGTH && CharOperation.equals(TAG_DOC_ROOT, tagName, 0, length)) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227730
+					// identify @docRoot tag as a base tag that does not expect any argument
+					valid = true;
+					this.tagValue = TAG_DOC_ROOT_VALUE;
+				}
+				break;
+			case 'e':
+				if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName, 0, length)) {
+					this.tagValue = TAG_EXCEPTION_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseThrows();
+					}
+				}
+				break;
+			case 'i':
+				if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName, 0, length)) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=247037, @inheritDoc usage is illegal
+					// outside of few block tags and the main description.
+					switch (this.lastBlockTagValue) {
+						case TAG_RETURN_VALUE:
+						case TAG_THROWS_VALUE:
+						case TAG_EXCEPTION_VALUE:
+						case TAG_PARAM_VALUE:
+						case NO_TAG_VALUE:     // Still in main description
+							valid = true;
+							if (this.reportProblems) {
+								recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
+							}
+							if (this.inlineTagStarted) {
+								// parse a 'valid' inheritDoc tag
+								parseInheritDocTag();
+							}
+							break;
+						default:
+							valid = false;
+							if (this.reportProblems) {
+								this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart,
+										this.tagSourceEnd);
+							}
+					}
+					this.tagValue = TAG_INHERITDOC_VALUE;
+				}
+				break;
+			case 'l':
+				if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName, 0, length)) {
+					this.tagValue = TAG_LINK_VALUE;
+					if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
+						valid= parseReference();
+					}
+				} else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName, 0, length)) {
+					this.tagValue = TAG_LINKPLAIN_VALUE;
+					if (this.inlineTagStarted) {
+						valid = parseReference();
+					} 
+				} else if (length == TAG_LITERAL_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_LITERAL, tagName, 0, length)) {
+					this.tagValue = TAG_LITERAL_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				}
+				break;
+			case 'p':
+				if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName, 0, length)) {
+					this.tagValue = TAG_PARAM_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseParam();
+					}
+				}
+				break;
+			case 'r':
+				if (length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName, 0, length)) {
+					this.tagValue = TAG_RETURN_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseReturn();
+					}
+				}
+				break;
+			case 's':
+				if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName, 0, length)) {
+					this.tagValue = TAG_SEE_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseReference();
+					}
+				} else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName, 0, length)) {
+					this.tagValue = TAG_SERIAL_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				} else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName, 0, length)) {
+					this.tagValue = TAG_SERIAL_DATA_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				} else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName, 0, length)) {
+					this.tagValue = TAG_SERIAL_FIELD_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				} else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) {
+					this.tagValue = TAG_SINCE_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				}					
+				break;
+			case 't':
+				if (length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName, 0, length)) {
+					this.tagValue = TAG_THROWS_VALUE;
+					if (!this.inlineTagStarted) {
+						valid = parseThrows();
+					}
+				}
+				break;
+			case 'v':
+				if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName, 0, length)) {
+					this.tagValue = TAG_VALUE_VALUE;
+					if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+						if (this.inlineTagStarted) {
+							valid = parseReference();
+						}
+					} else {
+						if (this.validValuePositions == -1) {
+							if (this.invalidValuePositions != -1) {
+								if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag((int) (this.invalidValuePositions>>>32), (int) this.invalidValuePositions);
+							}
+							if (valid) {
+								this.validValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+								this.invalidValuePositions = -1;
+							} else {
+								this.invalidValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+							}
+						} else {
+							if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+						}
+					}
+				} else if (length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName, 0, length)) {
+					this.tagValue = TAG_VERSION_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
+				} else {
+					createTag();
+				}
+				break;
+			default:
+				createTag();
+				break;
+		}
+		this.textStart = this.index;
+		if (this.tagValue != TAG_OTHERS_VALUE) {
+			if (!this.inlineTagStarted) {
+				this.lastBlockTagValue = this.tagValue;
+			}
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=267833
+			// Report a problem if a block tag is being used in the context of an inline tag and vice versa.
+			if ((this.inlineTagStarted && JAVADOC_TAG_TYPE[this.tagValue] == TAG_TYPE_BLOCK)
+					|| (!this.inlineTagStarted && JAVADOC_TAG_TYPE[this.tagValue] == TAG_TYPE_INLINE)) {
+				valid = false;
+				this.tagValue = TAG_OTHERS_VALUE;
+				this.tagWaitingForDescription = NO_TAG_VALUE;
+				if (this.reportProblems) {
+					this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+				}
+			}
+		}
+		return valid;
+	}
+
+	protected void parseInheritDocTag() {
+		// do nothing
+	}
+
+	/*
+	 * Parse @param tag declaration and flag missing description if corresponding option is enabled
+	 */
+	protected boolean parseParam() throws InvalidInputException {
+		boolean valid = super.parseParam();
+		this.tagWaitingForDescription = valid && this.reportProblems ? TAG_PARAM_VALUE : NO_TAG_VALUE;
+		return valid;
+	}
+
+	/*
+	 * Push a param name in ast node stack.
+	 */
+	protected boolean pushParamName(boolean isTypeParam) {
+		// Create param reference
+		ASTNode nameRef = null;
+		if (isTypeParam) {
+			JavadocSingleTypeReference ref = new JavadocSingleTypeReference(this.identifierStack[1],
+				this.identifierPositionStack[1],
+				this.tagSourceStart,
+				this.tagSourceEnd);
+			nameRef = ref;
+		} else {
+			JavadocSingleNameReference ref = new JavadocSingleNameReference(this.identifierStack[0],
+				this.identifierPositionStack[0],
+				this.tagSourceStart,
+				this.tagSourceEnd);
+			nameRef = ref;
+		}
+		// Push ref on stack
+		if (this.astLengthPtr == -1) { // First push
+			pushOnAstStack(nameRef, true);
+		} else {
+			// Verify that no @throws has been declared before
+			if (!isTypeParam) { // do not verify for type parameters as @throws may be invalid tag (when declared in class)
+				for (int i=THROWS_TAG_EXPECTED_ORDER; i<=this.astLengthPtr; i+=ORDERED_TAGS_NUMBER) {
+					if (this.astLengthStack[i] != 0) {
+						if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+						// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+						// store invalid param references in specific array
+						if (this.invalidParamReferencesPtr == -1l) {
+							this.invalidParamReferencesStack = new JavadocSingleNameReference[10];
+						}
+						int stackLength = this.invalidParamReferencesStack.length;
+						if (++this.invalidParamReferencesPtr >= stackLength) {
+							System.arraycopy(
+								this.invalidParamReferencesStack, 0,
+								this.invalidParamReferencesStack = new JavadocSingleNameReference[stackLength + AST_STACK_INCREMENT], 0,
+								stackLength);
+						}
+						this.invalidParamReferencesStack[this.invalidParamReferencesPtr] = nameRef;
+						return false;
+					}
+				}
+			}
+			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
+				case PARAM_TAG_EXPECTED_ORDER :
+					// previous push was a @param tag => push another param name
+					pushOnAstStack(nameRef, false);
+					break;
+				case SEE_TAG_EXPECTED_ORDER :
+					// previous push was a @see tag => push new param name
+					pushOnAstStack(nameRef, true);
+					break;
+				default:
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/*
+	 * Push a reference statement in ast node stack.
+	 */
+	protected boolean pushSeeRef(Object statement) {
+		if (this.astLengthPtr == -1) { // First push
+			pushOnAstStack(null, true);
+			pushOnAstStack(null, true);
+			pushOnAstStack(statement, true);
+		} else {
+			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
+				case PARAM_TAG_EXPECTED_ORDER :
+					// previous push was a @param tag => push empty @throws tag and new @see tag
+					pushOnAstStack(null, true);
+					pushOnAstStack(statement, true);
+					break;
+				case THROWS_TAG_EXPECTED_ORDER :
+					// previous push was a @throws tag => push new @see tag
+					pushOnAstStack(statement, true);
+					break;
+				case SEE_TAG_EXPECTED_ORDER :
+					// previous push was a @see tag => push another @see tag
+					pushOnAstStack(statement, false);
+					break;
+				default:
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
+	 */
+	protected void pushText(int start, int end) {
+		// The tag gets its description => clear the flag
+		this.tagWaitingForDescription = NO_TAG_VALUE;
+	}
+
+	/*
+	 * Push a throws type ref in ast node stack.
+	 */
+	protected boolean pushThrowName(Object typeRef) {
+		if (this.astLengthPtr == -1) { // First push
+			pushOnAstStack(null, true);
+			pushOnAstStack(typeRef, true);
+		} else {
+			switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) {
+				case PARAM_TAG_EXPECTED_ORDER :
+					// previous push was a @param tag => push new @throws tag
+					pushOnAstStack(typeRef, true);
+					break;
+				case THROWS_TAG_EXPECTED_ORDER :
+					// previous push was a @throws tag => push another @throws tag
+					pushOnAstStack(typeRef, false);
+					break;
+				case SEE_TAG_EXPECTED_ORDER :
+					// previous push was a @see tag => push empty @param and new @throws tags
+					pushOnAstStack(null, true);
+					pushOnAstStack(typeRef, true);
+					break;
+				default:
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#refreshInlineTagPosition(int)
+	 */
+	protected void refreshInlineTagPosition(int previousPosition) {
+
+		// Signal tag missing description if necessary
+		if (this.tagWaitingForDescription!= NO_TAG_VALUE) {
+			this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+			this.tagWaitingForDescription = NO_TAG_VALUE;
+		}
+	}
+
+	/*
+	 * Refresh return statement
+	 */
+	protected void refreshReturnStatement() {
+		((JavadocReturnStatement) this.returnStatement).bits &= ~ASTNode.Empty;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("check javadoc: ").append(this.checkDocComment).append("\n");	//$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append("javadoc: ").append(this.docComment).append("\n");	//$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append(super.toString());
+		return buffer.toString();
+	}
+
+	/*
+	 * Fill associated comment fields with ast nodes information stored in stack.
+	 */
+	protected void updateDocComment() {
+
+		// Complain when tag is missing a description
+		// Note that if the parse of an inline tag has already started, consider it
+		// as the expected description, hence do not report any warning
+		switch (this.tagWaitingForDescription) {
+			case TAG_PARAM_VALUE:
+			case TAG_THROWS_VALUE:
+				if (!this.inlineTagStarted) {
+					int start = (int) (this.identifierPositionStack[0] >>> 32);
+					int end = (int) this.identifierPositionStack[this.identifierPtr];
+					this.sourceParser.problemReporter().javadocMissingTagDescriptionAfterReference(start, end, this.sourceParser.modifiers);
+				}
+				break;
+			case NO_TAG_VALUE:
+				break;
+			default:
+				if (!this.inlineTagStarted) {
+					this.sourceParser.problemReporter().javadocMissingTagDescription(TAG_NAMES[this.tagWaitingForDescription], this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
+				}
+				break;
+		}
+		this.tagWaitingForDescription = NO_TAG_VALUE;
+
+		// Set positions
+		if (this.inheritedPositions != null && this.inheritedPositionsPtr != this.inheritedPositions.length) {
+			// Compact array by shrinking.
+			System.arraycopy(this.inheritedPositions, 0, 
+					this.inheritedPositions = new long[this.inheritedPositionsPtr], 0, this.inheritedPositionsPtr);
+		}
+		this.docComment.inheritedPositions = this.inheritedPositions;
+		this.docComment.valuePositions = this.validValuePositions != -1 ? this.validValuePositions : this.invalidValuePositions;
+
+		// Set return node if present
+		if (this.returnStatement != null) {
+			this.docComment.returnStatement = (JavadocReturnStatement) this.returnStatement;
+		}
+
+		// Copy array of invalid syntax param tags
+		if (this.invalidParamReferencesPtr >= 0) {
+			this.docComment.invalidParameters = new JavadocSingleNameReference[this.invalidParamReferencesPtr+1];
+			System.arraycopy(this.invalidParamReferencesStack, 0, this.docComment.invalidParameters, 0, this.invalidParamReferencesPtr+1);
+		}
+
+		// If no nodes stored return
+		if (this.astLengthPtr == -1) {
+			return;
+		}
+
+		// Initialize arrays
+		int[] sizes = new int[ORDERED_TAGS_NUMBER];
+		for (int i=0; i<=this.astLengthPtr; i++) {
+			sizes[i%ORDERED_TAGS_NUMBER] += this.astLengthStack[i];
+		}
+		this.docComment.seeReferences = new Expression[sizes[SEE_TAG_EXPECTED_ORDER]];
+		this.docComment.exceptionReferences = new TypeReference[sizes[THROWS_TAG_EXPECTED_ORDER]];
+		int paramRefPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
+		this.docComment.paramReferences = new JavadocSingleNameReference[paramRefPtr];
+		int paramTypeParamPtr = sizes[PARAM_TAG_EXPECTED_ORDER];
+		this.docComment.paramTypeParameters = new JavadocSingleTypeReference[paramTypeParamPtr];
+
+		// Store nodes in arrays
+		while (this.astLengthPtr >= 0) {
+			int ptr = this.astLengthPtr % ORDERED_TAGS_NUMBER;
+			// Starting with the stack top, so get references (Expression) coming from @see declarations
+			switch(ptr) {
+				case SEE_TAG_EXPECTED_ORDER:
+					int size = this.astLengthStack[this.astLengthPtr--];
+					for (int i=0; i<size; i++) {
+						this.docComment.seeReferences[--sizes[ptr]] = (Expression) this.astStack[this.astPtr--];
+					}
+					break;
+
+				// Then continuing with class names (TypeReference) coming from @throw/@exception declarations
+				case THROWS_TAG_EXPECTED_ORDER:
+					size = this.astLengthStack[this.astLengthPtr--];
+					for (int i=0; i<size; i++) {
+						this.docComment.exceptionReferences[--sizes[ptr]] = (TypeReference) this.astStack[this.astPtr--];
+					}
+					break;
+
+				// Finally, finishing with parameters names (Argument) coming from @param declaration
+				case PARAM_TAG_EXPECTED_ORDER:
+					size = this.astLengthStack[this.astLengthPtr--];
+					for (int i=0; i<size; i++) {
+						Expression reference = (Expression) this.astStack[this.astPtr--];
+						if (reference instanceof JavadocSingleNameReference)
+							this.docComment.paramReferences[--paramRefPtr] = (JavadocSingleNameReference) reference;
+						else if (reference instanceof JavadocSingleTypeReference)
+							this.docComment.paramTypeParameters[--paramTypeParamPtr] = (JavadocSingleTypeReference) reference;
+					}
+					break;
+			}
+		}
+
+		// Resize param tag references arrays
+		if (paramRefPtr == 0) { // there's no type parameters references
+			this.docComment.paramTypeParameters = null;
+		} else if (paramTypeParamPtr == 0) { // there's no names references
+			this.docComment.paramReferences = null;
+		} else { // there both of references => resize arrays
+			int size = sizes[PARAM_TAG_EXPECTED_ORDER];
+			System.arraycopy(this.docComment.paramReferences, paramRefPtr, this.docComment.paramReferences = new JavadocSingleNameReference[size - paramRefPtr], 0, size - paramRefPtr);
+			System.arraycopy(this.docComment.paramTypeParameters, paramTypeParamPtr, this.docComment.paramTypeParameters = new JavadocSingleTypeReference[size - paramTypeParamPtr], 0, size - paramTypeParamPtr);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java
new file mode 100644
index 0000000..aa8e183
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.parser;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * Javadoc tag constants.
+ *
+ * @since 3.2
+ */
+public interface JavadocTagConstants {
+
+	// recognized tags
+	public static final char[] TAG_DEPRECATED = "deprecated".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_PARAM = "param".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_RETURN = "return".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_THROWS = "throws".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_EXCEPTION = "exception".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SEE = "see".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_LINK = "link".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_LINKPLAIN = "linkplain".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_INHERITDOC = "inheritDoc".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_VALUE = "value".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_AUTHOR = "author".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_CODE = "code".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_DOC_ROOT = "docRoot".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_LITERAL = "literal".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SERIAL = "serial".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SERIAL_DATA = "serialData".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SERIAL_FIELD = "serialField".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SINCE = "since".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_VERSION = "version".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_CATEGORY = "category".toCharArray(); //$NON-NLS-1$
+
+	// tags lengthes
+	public static final int TAG_DEPRECATED_LENGTH = TAG_DEPRECATED.length;
+	public static final int TAG_PARAM_LENGTH = TAG_PARAM.length;
+	public static final int TAG_RETURN_LENGTH = TAG_RETURN.length;
+	public static final int TAG_THROWS_LENGTH = TAG_THROWS.length;
+	public static final int TAG_EXCEPTION_LENGTH = TAG_EXCEPTION.length;
+	public static final int TAG_SEE_LENGTH = TAG_SEE.length;
+	public static final int TAG_LINK_LENGTH = TAG_LINK.length;
+	public static final int TAG_LINKPLAIN_LENGTH = TAG_LINKPLAIN.length;
+	public static final int TAG_INHERITDOC_LENGTH = TAG_INHERITDOC.length;
+	public static final int TAG_VALUE_LENGTH = TAG_VALUE.length;
+	public static final int TAG_CATEGORY_LENGTH = TAG_CATEGORY.length;
+	public static final int TAG_AUTHOR_LENGTH = TAG_AUTHOR.length;
+	public static final int TAG_SERIAL_LENGTH = TAG_SERIAL.length;
+	public static final int TAG_SERIAL_DATA_LENGTH = TAG_SERIAL_DATA.length;
+	public static final int TAG_SERIAL_FIELD_LENGTH = TAG_SERIAL_FIELD.length;
+	public static final int TAG_SINCE_LENGTH = TAG_SINCE.length;
+	public static final int TAG_VERSION_LENGTH = TAG_VERSION.length;
+	public static final int TAG_CODE_LENGTH = TAG_CODE.length;
+	public static final int TAG_LITERAL_LENGTH = TAG_LITERAL.length;
+	public static final int TAG_DOC_ROOT_LENGTH = TAG_DOC_ROOT.length;
+
+	// tags value
+	public static final int NO_TAG_VALUE = 0;
+	public static final int TAG_DEPRECATED_VALUE = 1;
+	public static final int TAG_PARAM_VALUE = 2;
+	public static final int TAG_RETURN_VALUE = 3;
+	public static final int TAG_THROWS_VALUE = 4;
+	public static final int TAG_EXCEPTION_VALUE = 5;
+	public static final int TAG_SEE_VALUE = 6;
+	public static final int TAG_LINK_VALUE = 7;
+	public static final int TAG_LINKPLAIN_VALUE = 8;
+	public static final int TAG_INHERITDOC_VALUE = 9;
+	public static final int TAG_VALUE_VALUE = 10;
+	public static final int TAG_CATEGORY_VALUE = 11;
+	public static final int TAG_AUTHOR_VALUE = 12;
+	public static final int TAG_SERIAL_VALUE = 13;
+	public static final int TAG_SERIAL_DATA_VALUE = 14;
+	public static final int TAG_SERIAL_FIELD_VALUE = 15;
+	public static final int TAG_SINCE_VALUE = 16;
+	public static final int TAG_VERSION_VALUE = 17;
+	public static final int TAG_CODE_VALUE = 18;
+	public static final int TAG_LITERAL_VALUE = 19;
+	public static final int TAG_DOC_ROOT_VALUE = 20;
+	public static final int TAG_OTHERS_VALUE = 100;
+	
+	// Tag names array
+	public static final char[][] TAG_NAMES = {
+		CharOperation.NO_CHAR,
+		TAG_DEPRECATED,		/* 1 */
+		TAG_PARAM,				/* 2 */
+		TAG_RETURN,				/* 3 */
+		TAG_THROWS,				/* 4 */
+		TAG_EXCEPTION,			/* 5 */
+		TAG_SEE,						/* 6 */
+		TAG_LINK,						/* 7 */
+		TAG_LINKPLAIN,			/* 8 */
+		TAG_INHERITDOC,		/* 9 */
+		TAG_VALUE,					/* 10 */
+		TAG_CATEGORY,			/* 11 */
+		TAG_AUTHOR,				/* 12 */
+		TAG_SERIAL,				/* 13 */
+		TAG_SERIAL_DATA,	/* 14 */
+		TAG_SERIAL_FIELD,	/* 15 */
+		TAG_SINCE,					/* 16 */
+		TAG_VERSION,				/* 17 */
+		TAG_CODE,					/* 18 */
+		TAG_LITERAL,				/* 19 */
+		TAG_DOC_ROOT,			/* 20 */
+	};
+
+	// tags expected positions
+	public final static int ORDERED_TAGS_NUMBER = 3;
+	public final static int PARAM_TAG_EXPECTED_ORDER = 0;
+	public final static int THROWS_TAG_EXPECTED_ORDER = 1;
+	public final static int SEE_TAG_EXPECTED_ORDER = 2;
+
+	/*
+	 * Tag kinds indexes
+	 */
+	public final static int BLOCK_IDX = 0;
+	public final static int INLINE_IDX = 1;
+
+	// href tag
+	public final static char[] HREF_TAG = {'h', 'r', 'e', 'f'};
+	/*
+	 * Tags versions
+	 */
+	public static final char[][][] BLOCK_TAGS = {
+		// since 1.0
+		{ TAG_AUTHOR, TAG_DEPRECATED, TAG_EXCEPTION, TAG_PARAM, TAG_RETURN, TAG_SEE, TAG_VERSION, TAG_CATEGORY /* 1.6 tag but put here as we support it for all compliances */ },
+		// since 1.1
+		{ TAG_SINCE },
+		// since 1.2
+		{ TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD , TAG_THROWS },
+		// since 1.3
+		{},
+		// since 1.4
+		{},
+		// since 1.5
+		{},
+		// since 1.6
+		{},
+		// since 1.7
+		{},
+		// since 1.8
+		{}
+	};
+	public static final char[][][] INLINE_TAGS = {
+		// since 1.0
+		{},
+		// since 1.1
+		{},
+		// since 1.2
+		{ TAG_LINK },
+		// since 1.3
+		{ TAG_DOC_ROOT },
+		// since 1.4
+		{ TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE },
+		// since 1.5
+		{ TAG_CODE, TAG_LITERAL },
+		// since 1.6
+		{},
+		// since 1.7
+		{},
+		// since 1.8
+		{}
+	};
+	public final static int INLINE_TAGS_LENGTH = INLINE_TAGS.length;
+	public final static int BLOCK_TAGS_LENGTH = BLOCK_TAGS.length;
+	public final static int ALL_TAGS_LENGTH = BLOCK_TAGS_LENGTH+INLINE_TAGS_LENGTH;
+
+	public final static short TAG_TYPE_NONE = 0;
+	public final static short TAG_TYPE_INLINE = 1;
+	public final static short TAG_TYPE_BLOCK = 2;
+	
+	public static final short[] JAVADOC_TAG_TYPE = {
+		TAG_TYPE_NONE, 		// NO_TAG_VALUE = 0;
+		TAG_TYPE_BLOCK,		// TAG_DEPRECATED_VALUE = 1;
+		TAG_TYPE_BLOCK,		// TAG_PARAM_VALUE = 2;
+		TAG_TYPE_BLOCK,		// TAG_RETURN_VALUE = 3;
+		TAG_TYPE_BLOCK,		// TAG_THROWS_VALUE = 4;
+		TAG_TYPE_BLOCK,		// TAG_EXCEPTION_VALUE = 5;
+		TAG_TYPE_BLOCK,		// TAG_SEE_VALUE = 6;
+		TAG_TYPE_INLINE,	// TAG_LINK_VALUE = 7;
+		TAG_TYPE_INLINE,	// TAG_LINKPLAIN_VALUE = 8;
+		TAG_TYPE_INLINE,	// TAG_INHERITDOC_VALUE = 9;
+		TAG_TYPE_INLINE,	// TAG_VALUE_VALUE = 10;
+		TAG_TYPE_BLOCK,		// TAG_CATEGORY_VALUE = 11;
+		TAG_TYPE_BLOCK,		// TAG_AUTHOR_VALUE = 12;
+		TAG_TYPE_BLOCK,		// TAG_SERIAL_VALUE = 13;
+		TAG_TYPE_BLOCK,		// TAG_SERIAL_DATA_VALUE = 14;
+		TAG_TYPE_BLOCK,		// TAG_SERIAL_FIELD_VALUE = 15;
+		TAG_TYPE_BLOCK,		// TAG_SINCE_VALUE = 16;
+		TAG_TYPE_BLOCK,		// TAG_VERSION_VALUE = 17;
+		TAG_TYPE_INLINE,	// TAG_CODE_VALUE = 18;
+		TAG_TYPE_INLINE,	// TAG_LITERAL_VALUE = 19;
+		TAG_TYPE_INLINE		// TAG_DOC_ROOT_VALUE = 20;
+	};
+	/*
+	 * Tags usage
+	 */
+	public static final char[][] PACKAGE_TAGS = {
+		TAG_SEE,
+		TAG_SINCE,
+		TAG_SERIAL,
+		TAG_AUTHOR,
+		TAG_VERSION,
+		TAG_CATEGORY,
+		TAG_LINK,
+		TAG_LINKPLAIN,
+		TAG_DOC_ROOT,
+		TAG_VALUE,
+	};
+	public static final char[][] COMPILATION_UNIT_TAGS = {};
+	public static final char[][] CLASS_TAGS = {
+		TAG_SEE,
+		TAG_SINCE,
+		TAG_DEPRECATED,
+		TAG_SERIAL,
+		TAG_AUTHOR,
+		TAG_VERSION,
+		TAG_PARAM,
+		TAG_CATEGORY,
+		TAG_LINK,
+		TAG_LINKPLAIN,
+		TAG_DOC_ROOT,
+		TAG_VALUE,
+		TAG_CODE,
+		TAG_LITERAL
+	};
+	public static final char[][] FIELD_TAGS = {
+		TAG_SEE,
+		TAG_SINCE,
+		TAG_DEPRECATED,
+		TAG_SERIAL,
+		TAG_SERIAL_FIELD,
+		TAG_CATEGORY,
+		TAG_LINK,
+		TAG_LINKPLAIN,
+		TAG_DOC_ROOT,
+		TAG_VALUE,
+		TAG_CODE,
+		TAG_LITERAL
+	};
+	public static final char[][] METHOD_TAGS = {
+		TAG_SEE,
+		TAG_SINCE,
+		TAG_DEPRECATED,
+		TAG_PARAM,
+		TAG_RETURN,
+		TAG_THROWS,
+		TAG_EXCEPTION,
+		TAG_SERIAL_DATA,
+		TAG_CATEGORY,
+		TAG_LINK,
+		TAG_LINKPLAIN,
+		TAG_INHERITDOC,
+		TAG_DOC_ROOT,
+		TAG_VALUE,
+		TAG_CODE,
+		TAG_LITERAL
+	};
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSTag.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSTag.java
new file mode 100644
index 0000000..85bed5e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSTag.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+public class NLSTag {
+
+	public int start;
+	public int end;
+	public int lineNumber;
+	public int index;
+
+	public NLSTag(int start, int end, int lineNumber, int index) {
+		this.start = start;
+		this.end = end;
+		this.lineNumber = lineNumber;
+		this.index = index;
+	}
+
+	public String toString() {
+		return "NLSTag(" + this.start + "," + this.end + "," + this.lineNumber + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
new file mode 100644
index 0000000..82ba6fa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -0,0 +1,12318 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196
+ *     Stephan Herrmann - Contributions for 
+ *								bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 393719 - [compiler] inconsistent warnings on iteration variables
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *								bug 383973 - [1.8][compiler] syntax recovery in the presence of default methods
+ *								bug 401035 - [1.8] A few tests have started failing recently
+ *     Jesper S Moller - Contributions for
+ *							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *							bug 399695 - [1.8][compiler] [1.8][compiler] migrate parser to other syntax for default methods
+ *							bug 384567 - [1.5][compiler] Compiler accepts illegal modifiers on package declaration
+ *									bug 393192 - Incomplete type hierarchy with > 10 annotations
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
+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.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
+import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ContinueStatement;
+import org.eclipse.jdt.internal.compiler.ast.DoStatement;
+import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
+import org.eclipse.jdt.internal.compiler.ast.EmptyStatement;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.FloatLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ForStatement;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Javadoc;
+import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LongLiteral;
+import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
+import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
+import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
+import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class Parser implements ConflictedParser, ParserBasicInformation, TerminalTokens, OperatorIds, TypeIds {
+	
+	protected static final int THIS_CALL = ExplicitConstructorCall.This;
+	protected static final int SUPER_CALL = ExplicitConstructorCall.Super;
+	public static final char[] FALL_THROUGH_TAG = "$FALL-THROUGH$".toCharArray(); //$NON-NLS-1$
+	public static final char[] CASES_OMITTED_TAG = "$CASES-OMITTED$".toCharArray(); //$NON-NLS-1$
+	
+	public static char asb[] = null;
+	public static char asr[] = null;
+	//ast stack
+	protected final static int AstStackIncrement = 100;
+	public static char base_action[] = null;
+	public static final int BracketKinds = 3;
+
+	public static short check_table[] = null;
+	public static final int CurlyBracket = 2;
+	private static final boolean DEBUG = false;
+	private static final boolean DEBUG_AUTOMATON = false;
+	private static final String EOF_TOKEN = "$eof" ; //$NON-NLS-1$
+	private static final String ERROR_TOKEN = "$error" ; //$NON-NLS-1$
+	//expression stack
+	protected final static int ExpressionStackIncrement = 100;
+
+	protected final static int GenericsStackIncrement = 10;
+
+	private final static String FILEPREFIX = "parser"; //$NON-NLS-1$
+    public static char in_symb[] = null;
+	private static final String INVALID_CHARACTER = "Invalid Character" ; //$NON-NLS-1$
+	public static char lhs[] =  null;
+
+	public static String name[] = null;
+	public static char nasb[] = null;
+	public static char nasr[] = null;
+	public static char non_terminal_index[] = null;
+	private final static String READABLE_NAMES_FILE = "readableNames"; //$NON-NLS-1$
+
+	public static String readableName[] = null;
+
+	public static byte rhs[] = null;
+
+	public static int[] reverse_index = null;
+	public static char[] recovery_templates_index = null;
+	public static char[] recovery_templates = null;
+	public static char[] statements_recovery_filter = null;
+
+	public static long rules_compliance[] =  null;
+
+	public static final int RoundBracket = 0;
+
+    public static byte scope_la[] = null;
+    public static char scope_lhs[] = null;
+
+	public static char scope_prefix[] = null;
+    public static char scope_rhs[] = null;
+    public static char scope_state[] = null;
+
+    public static char scope_state_set[] = null;
+    public static char scope_suffix[] = null;
+	public static final int SquareBracket = 1;
+
+	//internal data for the automat
+	protected final static int StackIncrement = 255;
+
+	public static char term_action[] = null;
+	public static byte term_check[] = null;
+
+	public static char terminal_index[] = null;
+
+	private static final String UNEXPECTED_EOF = "Unexpected End Of File" ; //$NON-NLS-1$
+	public static boolean VERBOSE_RECOVERY = false;
+
+	static {
+		try{
+			initTables();
+		} catch(java.io.IOException ex){
+			throw new ExceptionInInitializerError(ex.getMessage());
+		}
+	}
+	public static int asi(int state) {
+	
+		return asb[original_state(state)];
+	}
+	public final static short base_check(int i) {
+		return check_table[i - (NUM_RULES + 1)];
+	}
+	private final static void buildFile(String filename, List listToDump) {
+		BufferedWriter writer = null;
+		try {
+			writer = new BufferedWriter(new FileWriter(filename));
+	    	for (Iterator iterator = listToDump.iterator(); iterator.hasNext(); ) {
+	    		writer.write(String.valueOf(iterator.next()));
+	    	}
+	    	writer.flush();
+		} catch(IOException e) {
+			// ignore
+		} finally {
+			if (writer != null) {
+	        	try {
+					writer.close();
+				} catch (IOException e1) {
+					// ignore
+				}
+			}
+		}
+		System.out.println(filename + " creation complete"); //$NON-NLS-1$
+	}
+	private static void buildFileForCompliance(
+			String file,
+			int length,
+			String[] tokens) {
+	
+			byte[] result = new byte[length * 8];
+	
+			for (int i = 0; i < tokens.length; i = i + 3) {
+				if("2".equals(tokens[i])) { //$NON-NLS-1$
+					int index = Integer.parseInt(tokens[i + 1]);
+					String token = tokens[i + 2].trim();
+					long compliance = 0;
+					if("1.4".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK1_4;
+					} else if("1.5".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK1_5;
+					} else if("1.6".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK1_6;
+					} else if("1.7".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK1_7;
+					} else if("1.8".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK1_8;
+					} else if("recovery".equals(token)) { //$NON-NLS-1$
+						compliance = ClassFileConstants.JDK_DEFERRED;
+					}
+	
+					int j = index * 8;
+					result[j] = 	(byte)(compliance >>> 56);
+					result[j + 1] = (byte)(compliance >>> 48);
+					result[j + 2] = (byte)(compliance >>> 40);
+					result[j + 3] = (byte)(compliance >>> 32);
+					result[j + 4] = (byte)(compliance >>> 24);
+					result[j + 5] = (byte)(compliance >>> 16);
+					result[j + 6] = (byte)(compliance >>> 8);
+					result[j + 7] = (byte)(compliance);
+				}
+			}
+	
+			buildFileForTable(file, result);
+		}
+	private final static String[] buildFileForName(String filename, String contents) {
+		String[] result = new String[contents.length()];
+		result[0] = null;
+		int resultCount = 1;
+	
+		StringBuffer buffer = new StringBuffer();
+	
+		int start = contents.indexOf("name[]"); //$NON-NLS-1$
+		start = contents.indexOf('\"', start);
+		int end = contents.indexOf("};", start); //$NON-NLS-1$
+	
+		contents = contents.substring(start, end);
+	
+		boolean addLineSeparator = false;
+		int tokenStart = -1;
+		StringBuffer currentToken = new StringBuffer();
+		for (int i = 0; i < contents.length(); i++) {
+			char c = contents.charAt(i);
+			if(c == '\"') {
+				if(tokenStart == -1) {
+					tokenStart = i + 1;
+				} else {
+					if(addLineSeparator) {
+						buffer.append('\n');
+						result[resultCount++] = currentToken.toString();
+						currentToken = new StringBuffer();
+					}
+					String token = contents.substring(tokenStart, i);
+					if(token.equals(ERROR_TOKEN)){
+						token = INVALID_CHARACTER;
+					} else if(token.equals(EOF_TOKEN)) {
+						token = UNEXPECTED_EOF;
+					}
+					buffer.append(token);
+					currentToken.append(token);
+					addLineSeparator = true;
+					tokenStart = -1;
+				}
+			}
+			if(tokenStart == -1 && c == '+'){
+				addLineSeparator = false;
+			}
+		}
+		if(currentToken.length() > 0) {
+			result[resultCount++] = currentToken.toString();
+		}
+	
+		buildFileForTable(filename, buffer.toString().toCharArray());
+	
+		System.arraycopy(result, 0, result = new String[resultCount], 0, resultCount);
+		return result;
+	}
+	private static void buildFileForReadableName(
+		String file,
+		char[] newLhs,
+		char[] newNonTerminalIndex,
+		String[] newName,
+		String[] tokens) {
+	
+		ArrayList entries = new ArrayList();
+	
+		boolean[] alreadyAdded = new boolean[newName.length];
+	
+		for (int i = 0; i < tokens.length; i = i + 3) {
+			if("1".equals(tokens[i])) { //$NON-NLS-1$
+				int index = newNonTerminalIndex[newLhs[Integer.parseInt(tokens[i + 1])]];
+				StringBuffer buffer = new StringBuffer();
+				if(!alreadyAdded[index]) {
+					alreadyAdded[index] = true;
+					buffer.append(newName[index]);
+					buffer.append('=');
+					buffer.append(tokens[i+2].trim());
+					buffer.append('\n');
+					entries.add(String.valueOf(buffer));
+				}
+			}
+		}
+		int i = 1;
+		while(!INVALID_CHARACTER.equals(newName[i])) i++;
+		i++;
+		for (; i < alreadyAdded.length; i++) {
+			if(!alreadyAdded[i]) {
+				System.out.println(newName[i] + " has no readable name"); //$NON-NLS-1$
+			}
+		}
+		Collections.sort(entries);
+		buildFile(file, entries);
+	}
+	private final static void buildFileForTable(String filename, byte[] bytes) {
+		java.io.FileOutputStream stream = null;
+		try {
+			stream = new java.io.FileOutputStream(filename);
+			stream.write(bytes);
+		} catch(IOException e) {
+			// ignore
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+		System.out.println(filename + " creation complete"); //$NON-NLS-1$
+	}
+	private final static void buildFileForTable(String filename, char[] chars) {
+		byte[] bytes = new byte[chars.length * 2];
+		for (int i = 0; i < chars.length; i++) {
+			bytes[2 * i] = (byte) (chars[i] >>> 8);
+			bytes[2 * i + 1] = (byte) (chars[i] & 0xFF);
+		}
+	
+		java.io.FileOutputStream stream = null;
+		try {
+			stream = new java.io.FileOutputStream(filename);
+			stream.write(bytes);
+		} catch(IOException e) {
+			// ignore
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+		System.out.println(filename + " creation complete"); //$NON-NLS-1$
+	}
+	private final static byte[] buildFileOfByteFor(String filename, String tag, String[] tokens) {
+	
+		//transform the String tokens into chars before dumping then into file
+	
+		int i = 0;
+		//read upto the tag
+		while (!tokens[i++].equals(tag)){/*empty*/}
+		//read upto the }
+	
+		byte[] bytes = new byte[tokens.length]; //can't be bigger
+		int ic = 0;
+		String token;
+		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
+			int c = Integer.parseInt(token);
+			bytes[ic++] = (byte) c;
+		}
+	
+		//resize
+		System.arraycopy(bytes, 0, bytes = new byte[ic], 0, ic);
+	
+		buildFileForTable(filename, bytes);
+		return bytes;
+	}
+	private final static char[] buildFileOfIntFor(String filename, String tag, String[] tokens) {
+	
+		//transform the String tokens into chars before dumping then into file
+	
+		int i = 0;
+		//read upto the tag
+		while (!tokens[i++].equals(tag)){/*empty*/}
+		//read upto the }
+	
+		char[] chars = new char[tokens.length]; //can't be bigger
+		int ic = 0;
+		String token;
+		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
+			int c = Integer.parseInt(token);
+			chars[ic++] = (char) c;
+		}
+	
+		//resize
+		System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
+	
+		buildFileForTable(filename, chars);
+		return chars;
+	}
+	private final static void buildFileOfShortFor(String filename, String tag, String[] tokens) {
+	
+		//transform the String tokens into chars before dumping then into file
+	
+		int i = 0;
+		//read upto the tag
+		while (!tokens[i++].equals(tag)){/*empty*/}
+		//read upto the }
+	
+		char[] chars = new char[tokens.length]; //can't be bigger
+		int ic = 0;
+		String token;
+		while (!(token = tokens[i++]).equals("}")) { //$NON-NLS-1$
+			int c = Integer.parseInt(token);
+			chars[ic++] = (char) (c + 32768);
+		}
+	
+		//resize
+		System.arraycopy(chars, 0, chars = new char[ic], 0, ic);
+	
+		buildFileForTable(filename, chars);
+	}
+	private static void buildFilesForRecoveryTemplates(
+		String indexFilename,
+		String templatesFilename,
+		char[] newTerminalIndex,
+		char[] newNonTerminalIndex,
+		String[] newName,
+		char[] newLhs,
+		String[] tokens) {
+	
+		int[] newReverse = computeReverseTable(newTerminalIndex, newNonTerminalIndex, newName);
+	
+		char[] newRecoveyTemplatesIndex = new char[newNonTerminalIndex.length];
+		char[] newRecoveyTemplates = new char[newNonTerminalIndex.length];
+		int newRecoveyTemplatesPtr = 0;
+	
+		for (int i = 0; i < tokens.length; i = i + 3) {
+			if("3".equals(tokens[i])) { //$NON-NLS-1$
+				int length = newRecoveyTemplates.length;
+				if(length == newRecoveyTemplatesPtr + 1) {
+					System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
+				}
+				newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
+	
+				int index = newLhs[Integer.parseInt(tokens[i + 1])];
+	
+				newRecoveyTemplatesIndex[index] = (char)newRecoveyTemplatesPtr;
+	
+				String token = tokens[i + 2].trim();
+				java.util.StringTokenizer st = new java.util.StringTokenizer(token, " ");  //$NON-NLS-1$
+				String[] terminalNames = new String[st.countTokens()];
+				int t = 0;
+				while (st.hasMoreTokens()) {
+					terminalNames[t++] = st.nextToken();
+				}
+	
+				for (int j = 0; j < terminalNames.length; j++) {
+					int symbol = getSymbol(terminalNames[j], newName, newReverse);
+					if(symbol > -1) {
+						length = newRecoveyTemplates.length;
+						if(length == newRecoveyTemplatesPtr + 1) {
+							System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[length * 2], 0, length);
+						}
+						newRecoveyTemplates[newRecoveyTemplatesPtr++] = (char)symbol;
+					}
+				}
+			}
+		}
+		newRecoveyTemplates[newRecoveyTemplatesPtr++] = 0;
+		System.arraycopy(newRecoveyTemplates, 0, newRecoveyTemplates = new char[newRecoveyTemplatesPtr], 0, newRecoveyTemplatesPtr);
+	
+		buildFileForTable(indexFilename, newRecoveyTemplatesIndex);
+		buildFileForTable(templatesFilename, newRecoveyTemplates);
+	}
+	private static void buildFilesForStatementsRecoveryFilter(
+			String filename,
+			char[] newNonTerminalIndex,
+			char[] newLhs,
+			String[] tokens) {
+	
+			char[] newStatementsRecoveryFilter = new char[newNonTerminalIndex.length];
+	
+			for (int i = 0; i < tokens.length; i = i + 3) {
+				if("4".equals(tokens[i])) { //$NON-NLS-1$
+					int index = newLhs[Integer.parseInt(tokens[i + 1])];
+	
+					newStatementsRecoveryFilter[index] = 1;
+				}
+			}
+			buildFileForTable(filename, newStatementsRecoveryFilter);
+		}
+	public final static void buildFilesFromLPG(String dataFilename, String dataFilename2) {
+	
+		//RUN THIS METHOD TO GENERATE PARSER*.RSC FILES
+	
+		//build from the lpg javadcl.java files that represents the parser tables
+		//lhs check_table asb asr symbol_index
+	
+		//[org.eclipse.jdt.internal.compiler.parser.Parser.buildFilesFromLPG("d:/leapfrog/grammar/javadcl.java")]
+		char[] contents = CharOperation.NO_CHAR;
+		try {
+			contents = Util.getFileCharContent(new File(dataFilename), null);
+		} catch (IOException ex) {
+			System.out.println(Messages.parser_incorrectPath);
+			return;
+		}
+		java.util.StringTokenizer st =
+			new java.util.StringTokenizer(new String(contents), " \t\n\r[]={,;");  //$NON-NLS-1$
+		String[] tokens = new String[st.countTokens()];
+		int j = 0;
+		while (st.hasMoreTokens()) {
+			tokens[j++] = st.nextToken();
+		}
+		final String prefix = FILEPREFIX;
+		int i = 0;
+	
+		char[] newLhs = buildFileOfIntFor(prefix + (++i) + ".rsc", "lhs", tokens); //$NON-NLS-1$ //$NON-NLS-2$
+		buildFileOfShortFor(prefix + (++i) + ".rsc", "check_table", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "asb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "asr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "nasb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "nasr", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		char[] newTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "terminal_index", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		char[] newNonTerminalIndex = buildFileOfIntFor(prefix + (++i) + ".rsc", "non_terminal_index", tokens); //$NON-NLS-1$ //$NON-NLS-2$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "term_action", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+	
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_prefix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_suffix", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_lhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state_set", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "scope_state", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfIntFor(prefix + (++i) + ".rsc", "in_symb", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+	
+		byte[] newRhs = buildFileOfByteFor(prefix + (++i) + ".rsc", "rhs", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfByteFor(prefix + (++i) + ".rsc", "term_check", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+		buildFileOfByteFor(prefix + (++i) + ".rsc", "scope_la", tokens); //$NON-NLS-2$ //$NON-NLS-1$
+	
+		String[] newName = buildFileForName(prefix + (++i) + ".rsc", new String(contents)); //$NON-NLS-1$
+	
+		contents = CharOperation.NO_CHAR;
+		try {
+			contents = Util.getFileCharContent(new File(dataFilename2), null);
+		} catch (IOException ex) {
+			System.out.println(Messages.parser_incorrectPath);
+			return;
+		}
+		st = new java.util.StringTokenizer(new String(contents), "\t\n\r#");  //$NON-NLS-1$
+		tokens = new String[st.countTokens()];
+		j = 0;
+		while (st.hasMoreTokens()) {
+			tokens[j++] = st.nextToken();
+		}
+	
+		buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
+		buildFileForReadableName(READABLE_NAMES_FILE+".props", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
+	
+		buildFilesForRecoveryTemplates(
+				prefix + (++i) + ".rsc", //$NON-NLS-1$
+				prefix + (++i) + ".rsc", //$NON-NLS-1$
+				newTerminalIndex,
+				newNonTerminalIndex,
+				newName,
+				newLhs,
+				tokens);
+	
+		buildFilesForStatementsRecoveryFilter(
+				prefix + (++i) + ".rsc", //$NON-NLS-1$
+				newNonTerminalIndex,
+				newLhs,
+				tokens);
+	
+	
+		System.out.println(Messages.parser_moveFiles);
+	}
+	protected static int[] computeReverseTable(char[] newTerminalIndex, char[] newNonTerminalIndex, String[] newName) {
+		int[] newReverseTable = new int[newName.length];
+		for (int j = 0; j < newName.length; j++) {
+			found : {
+				for (int k = 0; k < newTerminalIndex.length; k++) {
+					if(newTerminalIndex[k] == j) {
+						newReverseTable[j] = k;
+						break found;
+					}
+				}
+				for (int k = 0; k < newNonTerminalIndex.length; k++) {
+					if(newNonTerminalIndex[k] == j) {
+						newReverseTable[j] = -k;
+						break found;
+					}
+				}
+			}
+		}
+		return newReverseTable;
+	}
+
+	private static int getSymbol(String terminalName, String[] newName, int[] newReverse) {
+		for (int j = 0; j < newName.length; j++) {
+			if(terminalName.equals(newName[j])) {
+				return newReverse[j];
+			}
+		}
+		return -1;
+	}
+	public static int in_symbol(int state) {
+		return in_symb[original_state(state)];
+	}
+	public final static void initTables() throws java.io.IOException {
+	
+		final String prefix = FILEPREFIX;
+		int i = 0;
+		lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		char[] chars = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		check_table = new short[chars.length];
+		for (int c = chars.length; c-- > 0;) {
+			check_table[c] = (short) (chars[c] - 32768);
+		}
+		asb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		asr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		nasb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		nasr = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		non_terminal_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		term_action = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		scope_prefix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_suffix = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_lhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_state_set = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_rhs = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_state = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		in_symb = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		rhs = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		term_check = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		scope_la = readByteTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		name = readNameTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		rules_compliance = readLongTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		readableName = readReadableNameTable(READABLE_NAMES_FILE + ".props"); //$NON-NLS-1$
+	
+		reverse_index = computeReverseTable(terminal_index, non_terminal_index, name);
+	
+		recovery_templates_index = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+		recovery_templates = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		statements_recovery_filter = readTable(prefix + (++i) + ".rsc"); //$NON-NLS-1$
+	
+		base_action = lhs;
+	}
+	public static int nasi(int state) {
+		return nasb[original_state(state)];
+	}
+	public static int ntAction(int state, int sym) {
+		return base_action[state + sym];
+	}
+	protected static int original_state(int state) {
+		return -base_check(state);
+	}
+
+	protected static byte[] readByteTable(String filename) throws java.io.IOException {
+	
+		//files are located at Parser.class directory
+	
+		InputStream stream = Parser.class.getResourceAsStream(filename);
+		if (stream == null) {
+			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
+		}
+		byte[] bytes = null;
+		try {
+			stream = new BufferedInputStream(stream);
+			bytes = Util.getInputStreamAsByteArray(stream, -1);
+		} finally {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+		return bytes;
+	}
+	protected static long[] readLongTable(String filename) throws java.io.IOException {
+	
+		//files are located at Parser.class directory
+	
+		InputStream stream = Parser.class.getResourceAsStream(filename);
+		if (stream == null) {
+			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
+		}
+		byte[] bytes = null;
+		try {
+			stream = new BufferedInputStream(stream);
+			bytes = Util.getInputStreamAsByteArray(stream, -1);
+		} finally {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	
+		//minimal integrity check (even size expected)
+		int length = bytes.length;
+		if (length % 8 != 0)
+			throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
+	
+		// convert bytes into longs
+		long[] longs = new long[length / 8];
+		int i = 0;
+		int longIndex = 0;
+	
+		while (true) {
+			longs[longIndex++] =
+			  (((long) (bytes[i++] & 0xFF)) << 56)
+			+ (((long) (bytes[i++] & 0xFF)) << 48)
+			+ (((long) (bytes[i++] & 0xFF)) << 40)
+			+ (((long) (bytes[i++] & 0xFF)) << 32)
+			+ (((long) (bytes[i++] & 0xFF)) << 24)
+			+ (((long) (bytes[i++] & 0xFF)) << 16)
+			+ (((long) (bytes[i++] & 0xFF)) << 8)
+			+ (bytes[i++] & 0xFF);
+	
+			if (i == length)
+				break;
+		}
+		return longs;
+	}
+
+	protected static String[] readNameTable(String filename) throws java.io.IOException {
+		char[] contents = readTable(filename);
+		char[][] nameAsChar = CharOperation.splitOn('\n', contents);
+	
+		String[] result = new String[nameAsChar.length + 1];
+		result[0] = null;
+		for (int i = 0; i < nameAsChar.length; i++) {
+			result[i + 1] = new String(nameAsChar[i]);
+		}
+	
+		return result;
+	}
+	protected static String[] readReadableNameTable(String filename){
+		String[] result = new String[name.length];
+		
+		InputStream is = Parser.class.getResourceAsStream(filename);
+		Properties props = new Properties();
+		try {
+			props.load(is);
+		} catch (IOException e) {
+			result = name;
+			return result;
+		}
+		for (int i = 0; i < NT_OFFSET + 1; i++) {
+			result[i] = name[i];
+		}
+		for (int i = NT_OFFSET; i < name.length; i++) {
+			String n = props.getProperty(name[i]);
+			if (n != null && n.length() > 0) {
+				result[i] = n;
+			} else {
+				result[i] = name[i];
+			}
+		}
+		return result;
+	}
+	protected static char[] readTable(String filename) throws java.io.IOException {
+	
+		//files are located at Parser.class directory
+	
+		InputStream stream = Parser.class.getResourceAsStream(filename);
+		if (stream == null) {
+			throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename));
+		}
+		byte[] bytes = null;
+		try {
+			stream = new BufferedInputStream(stream);
+			bytes = Util.getInputStreamAsByteArray(stream, -1);
+		} finally {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	
+		//minimal integrity check (even size expected)
+		int length = bytes.length;
+		if ((length & 1) != 0)
+			throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename));
+	
+		// convert bytes into chars
+		char[] chars = new char[length / 2];
+		int i = 0;
+		int charIndex = 0;
+	
+		while (true) {
+			chars[charIndex++] = (char) (((bytes[i++] & 0xFF) << 8) + (bytes[i++] & 0xFF));
+			if (i == length)
+				break;
+		}
+		return chars;
+	}
+	public static int tAction(int state, int sym) {
+		return term_action[term_check[base_action[state]+sym] == sym ? base_action[state] + sym : base_action[state]];
+	}
+	protected int astLengthPtr;
+
+	protected int[] astLengthStack;
+	protected int astPtr;
+	protected ASTNode[] astStack = new ASTNode[AstStackIncrement];
+	public CompilationUnitDeclaration compilationUnit; /*the result from parse()*/
+
+	protected RecoveredElement currentElement;
+	public int currentToken;
+	protected boolean diet = false; //tells the scanner to jump over some parts of the code/expressions like method bodies
+	protected int dietInt = 0; // if > 0 force the none-diet-parsing mode (even if diet if requested) [field parsing with anonymous inner classes...]
+	protected int endPosition; //accurate only when used ! (the start position is pushed into intStack while the end the current one)
+	protected int endStatementPosition;
+	protected int expressionLengthPtr;
+	protected int[] expressionLengthStack;
+	protected int expressionPtr;
+	protected Expression[] expressionStack = new Expression[ExpressionStackIncrement];
+	public int firstToken ; // handle for multiple parsing goals
+	
+	/* jsr308 -- Type annotation management, we now maintain type annotations in a separate stack
+	   as otherwise they get interspersed with other expressions and some of the code is not prepared
+	   to handle such interleaving and will look ugly if changed. 
+	   
+	   See consumeArrayCreationExpressionWithoutInitializer for example. 
+
+	   Where SE8 annotations occur in a place SE5 annotations are legal, the SE8 annotations end up in
+	   the expression stack as we have no way of distinguishing between the two.
+	*/  
+	protected int typeAnnotationPtr;
+	protected int typeAnnotationLengthPtr;
+	protected Annotation [] typeAnnotationStack = new Annotation[TypeAnnotationStackIncrement];
+	protected int [] typeAnnotationLengthStack;
+	// annotation stack
+	protected final static int TypeAnnotationStackIncrement = 100;
+	
+	// generics management
+	protected int genericsIdentifiersLengthPtr;
+	protected int[] genericsIdentifiersLengthStack = new int[GenericsStackIncrement];
+	protected int genericsLengthPtr;
+	protected int[] genericsLengthStack = new int[GenericsStackIncrement];
+	protected int genericsPtr;
+	protected ASTNode[] genericsStack = new ASTNode[GenericsStackIncrement];
+	protected boolean hasError;
+	protected boolean hasReportedError;
+	//identifiers stacks
+	protected int identifierLengthPtr;
+	protected int[] identifierLengthStack;
+	protected long[] identifierPositionStack;
+	protected int identifierPtr;
+	protected char[][] identifierStack;
+	protected boolean ignoreNextOpeningBrace;
+
+	//positions , dimensions , .... (int stacks)
+	protected int intPtr;
+
+	protected int[] intStack;
+	public int lastAct ; //handle for multiple parsing goals
+	//error recovery management
+	protected int lastCheckPoint;
+	protected int lastErrorEndPosition;
+	protected int lastErrorEndPositionBeforeRecovery = -1;
+	protected int lastIgnoredToken, nextIgnoredToken;
+
+	protected int listLength; // for recovering some incomplete list (interfaces, throws or parameters)
+
+	protected int listTypeParameterLength; // for recovering some incomplete list (type parameters)
+	protected int lParenPos,rParenPos; //accurate only when used !
+	protected int modifiers;
+	protected int modifiersSourceStart;
+	protected int[] nestedMethod; //the ptr is nestedType
+
+	protected int nestedType, dimensions;
+	ASTNode [] noAstNodes = new ASTNode[AstStackIncrement];
+
+	Expression [] noExpressions = new Expression[ExpressionStackIncrement];
+	//modifiers dimensions nestedType etc.......
+	protected boolean optimizeStringLiterals =true;
+	protected CompilerOptions options;
+
+	protected ProblemReporter problemReporter;
+
+	protected int rBraceStart, rBraceEnd, rBraceSuccessorStart; //accurate only when used !
+protected int realBlockPtr;
+protected int[] realBlockStack;
+protected int recoveredStaticInitializerStart;
+public ReferenceContext referenceContext;
+public boolean reportOnlyOneSyntaxError = false;
+public boolean reportSyntaxErrorIsRequired = true;
+protected boolean restartRecovery;
+protected boolean annotationRecoveryActivated = true;
+protected int lastPosistion;
+// statement recovery
+public boolean methodRecoveryActivated = false;
+protected boolean statementRecoveryActivated = false;
+protected TypeDeclaration[] recoveredTypes;
+protected int recoveredTypePtr;
+protected int nextTypeStart;
+protected TypeDeclaration pendingRecoveredType;
+public RecoveryScanner recoveryScanner;
+//scanner token
+public Scanner scanner;
+protected int[] stack = new int[StackIncrement];
+protected int stateStackTop;
+protected int synchronizedBlockSourceStart;
+
+protected int[] variablesCounter;
+
+protected boolean checkExternalizeStrings;
+
+protected boolean recordStringLiterals;
+// javadoc
+public Javadoc javadoc;
+public JavadocParser javadocParser;
+// used for recovery
+protected int lastJavadocEnd;
+public org.eclipse.jdt.internal.compiler.ReadManager readManager;
+private boolean shouldDeferRecovery = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040
+private int valueLambdaNestDepth = -1;
+private int stateStackLengthStack[] = new int[0];
+private boolean parsingJava8Plus;
+protected int unstackedAct = ERROR_ACTION;
+private boolean haltOnSyntaxError = false;
+
+protected Parser () {
+	// Caveat Emptor: For inheritance purposes and then only in very special needs. Only minimal state is initialized !
+}
+public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
+
+	this.problemReporter = problemReporter;
+	this.options = problemReporter.options;
+	this.optimizeStringLiterals = optimizeStringLiterals;
+	initializeScanner();
+	this.parsingJava8Plus = this.options.sourceLevel >= ClassFileConstants.JDK1_8;
+	this.astLengthStack = new int[50];
+	this.expressionLengthStack = new int[30];
+	this.typeAnnotationLengthStack = new int[30];
+	this.intStack = new int[50];
+	this.identifierStack = new char[30][];
+	this.identifierLengthStack = new int[30];
+	this.nestedMethod = new int[30];
+	this.realBlockStack = new int[30];
+	this.identifierPositionStack = new long[30];
+	this.variablesCounter = new int[30];
+
+	// javadoc support
+	this.javadocParser = createJavadocParser();
+}
+protected void annotationRecoveryCheckPoint(int start, int end) {
+	if(this.lastCheckPoint < end) {
+		this.lastCheckPoint = end + 1;
+	}
+}
+public void arrayInitializer(int length) {
+	//length is the size of the array Initializer
+	//expressionPtr points on the last elt of the arrayInitializer,
+	// in other words, it has not been decremented yet.
+
+	ArrayInitializer ai = new ArrayInitializer();
+	if (length != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(this.expressionStack, this.expressionPtr + 1, ai.expressions = new Expression[length], 0, length);
+	}
+	pushOnExpressionStack(ai);
+	//positionning
+	ai.sourceEnd = this.endStatementPosition;
+	ai.sourceStart = this.intStack[this.intPtr--];
+}
+protected void blockReal() {
+	// See consumeLocalVariableDeclarationStatement in case of change: duplicated code
+	// increment the amount of declared variables for this block
+	this.realBlockStack[this.realBlockPtr]++;
+}
+/*
+ * Build initial recovery state.
+ * Recovery state is inferred from the current state of the parser (reduced node stack).
+ */
+public RecoveredElement buildInitialRecoveryState(){
+
+	/* initialize recovery by retrieving available reduced nodes
+	 * also rebuild bracket balance
+	 */
+	this.lastCheckPoint = 0;
+	this.lastErrorEndPositionBeforeRecovery = this.scanner.currentPosition;
+
+	RecoveredElement element = null;
+	if (this.referenceContext instanceof CompilationUnitDeclaration){
+		element = new RecoveredUnit(this.compilationUnit, 0, this);
+
+		/* ignore current stack state, since restarting from the beginnning
+		   since could not trust simple brace count */
+		// restart recovery from scratch
+		this.compilationUnit.currentPackage = null;
+		this.compilationUnit.imports = null;
+		this.compilationUnit.types = null;
+		this.currentToken = 0;
+		this.listLength = 0;
+		this.listTypeParameterLength = 0;
+		this.endPosition = 0;
+		this.endStatementPosition = 0;
+		return element;
+	} else {
+		if (this.referenceContext instanceof AbstractMethodDeclaration){
+			element = new RecoveredMethod((AbstractMethodDeclaration) this.referenceContext, null, 0, this);
+			this.lastCheckPoint = ((AbstractMethodDeclaration) this.referenceContext).bodyStart;
+			if(this.statementRecoveryActivated) {
+				element = element.add(new Block(0), 0);
+			}
+		} else {
+			/* Initializer bodies are parsed in the context of the type declaration, we must thus search it inside */
+			if (this.referenceContext instanceof TypeDeclaration){
+				TypeDeclaration type = (TypeDeclaration) this.referenceContext;
+				FieldDeclaration[] fieldDeclarations = type.fields;
+				int length = fieldDeclarations == null ? 0 : fieldDeclarations.length;
+				for (int i = 0; i < length; i++){
+					FieldDeclaration field = fieldDeclarations[i];
+					if (field != null
+						&& field.getKind() == AbstractVariableDeclaration.INITIALIZER
+						&& ((Initializer) field).block != null
+						&& field.declarationSourceStart <= this.scanner.initialPosition
+						&& this.scanner.initialPosition <= field.declarationSourceEnd
+						&& this.scanner.eofPosition <= field.declarationSourceEnd+1){
+						element = new RecoveredInitializer(field, null, 1, this);
+						this.lastCheckPoint = field.declarationSourceStart;
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	if (element == null) return element;
+
+	for(int i = 0; i <= this.astPtr; i++){
+		ASTNode node = this.astStack[i];
+		if (node instanceof AbstractMethodDeclaration){
+			AbstractMethodDeclaration method = (AbstractMethodDeclaration) node;
+			if (method.declarationSourceEnd == 0){
+				element = element.add(method, 0);
+				this.lastCheckPoint = method.bodyStart;
+			} else {
+				element = element.add(method, 0);
+				this.lastCheckPoint = method.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof Initializer){
+			Initializer initializer = (Initializer) node;
+			// ignore initializer with no block
+			if (initializer.block == null) continue;
+			if (initializer.declarationSourceEnd == 0){
+				element = element.add(initializer, 1);
+				this.lastCheckPoint = initializer.sourceStart;
+			} else {
+				element = element.add(initializer, 0);
+				this.lastCheckPoint = initializer.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof FieldDeclaration){
+			FieldDeclaration field = (FieldDeclaration) node;
+			if (field.declarationSourceEnd == 0){
+				element = element.add(field, 0);
+				if (field.initialization == null){
+					this.lastCheckPoint = field.sourceEnd + 1;
+				} else {
+					this.lastCheckPoint = field.initialization.sourceEnd + 1;
+				}
+			} else {
+				element = element.add(field, 0);
+				this.lastCheckPoint = field.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof TypeDeclaration){
+			TypeDeclaration type = (TypeDeclaration) node;
+			if ((type.modifiers & ClassFileConstants.AccEnum) != 0) {
+				// do not allow enums to be build as recovery types
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=340691
+				continue;
+			}
+			if (type.declarationSourceEnd == 0){
+				element = element.add(type, 0);
+				this.lastCheckPoint = type.bodyStart;
+			} else {
+				element = element.add(type, 0);
+				this.lastCheckPoint = type.declarationSourceEnd + 1;
+			}
+			continue;
+		}
+		if (node instanceof ImportReference){
+			ImportReference importRef = (ImportReference) node;
+			element = element.add(importRef, 0);
+			this.lastCheckPoint = importRef.declarationSourceEnd + 1;
+		}
+		if(this.statementRecoveryActivated) {
+			if(node instanceof Block) {
+				Block block = (Block) node;
+				element = element.add(block, 0);
+				this.lastCheckPoint = block.sourceEnd + 1;
+			} else if(node instanceof LocalDeclaration) {
+				LocalDeclaration statement = (LocalDeclaration) node;
+				element = element.add(statement, 0);
+				this.lastCheckPoint = statement.sourceEnd + 1;
+			} else if(node instanceof Expression) {
+				if(node instanceof Assignment ||
+						node instanceof PrefixExpression ||
+						node instanceof PostfixExpression ||
+						node instanceof MessageSend ||
+						node instanceof AllocationExpression) {
+					// recover only specific expressions
+					Expression statement = (Expression) node;
+					element = element.add(statement, 0);
+					if(statement.statementEnd != -1) {
+						this.lastCheckPoint = statement.statementEnd + 1;
+					} else {
+						this.lastCheckPoint = statement.sourceEnd + 1;
+					}
+				}
+			} else if(node instanceof Statement) {
+				Statement statement = (Statement) node;
+				element = element.add(statement, 0);
+				this.lastCheckPoint = statement.sourceEnd + 1;
+			}
+		}
+	}
+
+	if (this.statementRecoveryActivated) {
+		if (this.pendingRecoveredType != null &&
+				this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) {
+			// Add the pending type to the AST if this type isn't already added in the AST.
+			element = element.add(this.pendingRecoveredType, 0);
+			this.lastCheckPoint = this.pendingRecoveredType.declarationSourceEnd + 1;
+			this.pendingRecoveredType = null;
+		}
+	}
+	return element;
+}
+
+protected void checkAndSetModifiers(int flag){
+	/*modify the current modifiers buffer.
+	When the startPosition of the modifiers is 0
+	it means that the modifier being parsed is the first
+	of a list of several modifiers. The startPosition
+	is zeroed when a copy of modifiers-buffer is push
+	onto the this.astStack. */
+
+	if ((this.modifiers & flag) != 0){ // duplicate modifier
+		this.modifiers |= ExtraCompilerModifiers.AccAlternateModifierProblem;
+	}
+	this.modifiers |= flag;
+
+	if (this.modifiersSourceStart < 0) this.modifiersSourceStart = this.scanner.startPosition;
+
+	if (this.currentElement != null) {
+		this.currentElement.addModifier(flag, this.modifiersSourceStart);
+	}
+}
+public void checkComment() {
+
+	// discard obsolete comments while inside methods or fields initializer (see bug 74369)
+	if (!(this.diet && this.dietInt==0) && this.scanner.commentPtr >= 0) {
+		flushCommentsDefinedPriorTo(this.endStatementPosition);
+	}
+
+	int lastComment = this.scanner.commentPtr;
+
+	if (this.modifiersSourceStart >= 0) {
+		// eliminate comments located after modifierSourceStart if positioned
+		while (lastComment >= 0) {
+			int commentSourceStart = this.scanner.commentStarts[lastComment];
+			if (commentSourceStart < 0) commentSourceStart = -commentSourceStart;
+			if (commentSourceStart <= this.modifiersSourceStart) break;
+			lastComment--;
+		}
+	}
+	if (lastComment >= 0) {
+		// consider all remaining leading comments to be part of current declaration
+		this.modifiersSourceStart = this.scanner.commentStarts[0];
+		if (this.modifiersSourceStart < 0) this.modifiersSourceStart = -this.modifiersSourceStart;
+
+		// check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)
+		while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
+		if (lastComment >= 0 && this.javadocParser != null) {
+			int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over,
+			// do not report problem before last parsed comment while recovering code...
+			if (this.javadocParser.shouldReportProblems) {
+				this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
+			} else {
+				this.javadocParser.reportProblems = false;
+			}
+			if (this.javadocParser.checkDeprecation(lastComment)) {
+				checkAndSetModifiers(ClassFileConstants.AccDeprecated);
+			}
+			this.javadoc = this.javadocParser.docComment;	// null if check javadoc is not activated
+			if (this.currentElement == null) this.lastJavadocEnd = commentEnd;
+		}
+	}
+}
+protected void checkNonNLSAfterBodyEnd(int declarationEnd){
+	if(this.scanner.currentPosition - 1 <= declarationEnd) {
+		this.scanner.eofPosition = declarationEnd < Integer.MAX_VALUE ? declarationEnd + 1 : declarationEnd;
+		try {
+			while(this.scanner.getNextToken() != TokenNameEOF){/*empty*/}
+		} catch (InvalidInputException e) {
+			// Nothing to do
+		}
+	}
+}
+protected void classInstanceCreation(boolean isQualified) {
+	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+
+	// ClassBodyopt produces a null item on the astStak if it produces NO class body
+	// An empty class body produces a 0 on the length stack.....
+
+	AllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+		//NO ClassBody
+		this.astPtr--;
+		if (isQualified) {
+			alloc = new QualifiedAllocationExpression();
+		} else {
+			alloc = new AllocationExpression();
+		}
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+	} else {
+		dispatchDeclarationInto(length);
+		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
+		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
+		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
+		if (anonymousTypeDeclaration.allocation != null) {
+			anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
+			checkForDiamond(anonymousTypeDeclaration.allocation.type);
+		}
+		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
+			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+		this.astPtr--;
+		this.astLengthPtr--;
+	}
+}
+protected void checkForDiamond(TypeReference allocType) {
+	if (allocType instanceof ParameterizedSingleTypeReference) {
+		ParameterizedSingleTypeReference type = (ParameterizedSingleTypeReference) allocType;
+		if (type.typeArguments == TypeReference.NO_TYPE_ARGUMENTS) {
+			if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+				problemReporter().diamondNotBelow17(allocType);
+			}
+			if (this.options.sourceLevel > ClassFileConstants.JDK1_4) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965
+				type.bits |= ASTNode.IsDiamond;
+			} // else don't even bother to recognize this as <>
+		}
+	} 
+	else if (allocType instanceof ParameterizedQualifiedTypeReference) {
+		ParameterizedQualifiedTypeReference type = (ParameterizedQualifiedTypeReference) allocType;
+		if (type.typeArguments[type.typeArguments.length - 1] == TypeReference.NO_TYPE_ARGUMENTS) { // Don't care for X<>.Y<> and X<>.Y<String>
+			if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+				problemReporter().diamondNotBelow17(allocType, type.typeArguments.length - 1);
+			}
+			if (this.options.sourceLevel > ClassFileConstants.JDK1_4) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965
+				type.bits |= ASTNode.IsDiamond;
+			} // else don't even bother to recognize this as <>
+		}
+	}
+}
+protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim, Annotation [][] annotationsOnDimensions) {
+	int nameSize = this.identifierLengthStack[this.identifierLengthPtr];
+	int tokensSize = nameSize;
+	if (rightSide instanceof ParameterizedSingleTypeReference) {
+		tokensSize ++;
+	} else if (rightSide instanceof SingleTypeReference) {
+		tokensSize ++;
+	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
+		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
+	} else if (rightSide instanceof QualifiedTypeReference) {
+		tokensSize += ((QualifiedTypeReference) rightSide).tokens.length;
+	}
+	TypeReference[][] typeArguments = new TypeReference[tokensSize][];
+	char[][] tokens = new char[tokensSize][];
+	long[] positions = new long[tokensSize];
+	Annotation [][] typeAnnotations = null;
+	if (rightSide instanceof ParameterizedSingleTypeReference) {
+		ParameterizedSingleTypeReference singleParameterizedTypeReference = (ParameterizedSingleTypeReference) rightSide;
+		tokens[nameSize] = singleParameterizedTypeReference.token;
+		positions[nameSize] = (((long) singleParameterizedTypeReference.sourceStart) << 32) + singleParameterizedTypeReference.sourceEnd;
+		typeArguments[nameSize] = singleParameterizedTypeReference.typeArguments;
+		if (singleParameterizedTypeReference.annotations != null) {
+			typeAnnotations = new Annotation[tokensSize][];
+		    typeAnnotations[nameSize] = singleParameterizedTypeReference.annotations[0];
+		}
+	} else if (rightSide instanceof SingleTypeReference) {
+		SingleTypeReference singleTypeReference = (SingleTypeReference) rightSide;
+		tokens[nameSize] = singleTypeReference.token;
+		positions[nameSize] = (((long) singleTypeReference.sourceStart) << 32) + singleTypeReference.sourceEnd;
+		if (singleTypeReference.annotations != null) {
+			typeAnnotations = new Annotation[tokensSize][];
+			typeAnnotations[nameSize] =  singleTypeReference.annotations[0];
+		}
+	} else if (rightSide instanceof ParameterizedQualifiedTypeReference) {
+		ParameterizedQualifiedTypeReference parameterizedTypeReference = (ParameterizedQualifiedTypeReference) rightSide;
+		TypeReference[][] rightSideTypeArguments = parameterizedTypeReference.typeArguments;
+		System.arraycopy(rightSideTypeArguments, 0, typeArguments, nameSize, rightSideTypeArguments.length);
+		char[][] rightSideTokens = parameterizedTypeReference.tokens;
+		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
+		long[] rightSidePositions = parameterizedTypeReference.sourcePositions;
+		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
+		Annotation [][] rightSideAnnotations = parameterizedTypeReference.annotations;
+		if (rightSideAnnotations != null) {
+			typeAnnotations = new Annotation[tokensSize][];
+			System.arraycopy(rightSideAnnotations, 0, typeAnnotations, nameSize, rightSideAnnotations.length);
+		}
+	} else if (rightSide instanceof QualifiedTypeReference) {
+		QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) rightSide;
+		char[][] rightSideTokens = qualifiedTypeReference.tokens;
+		System.arraycopy(rightSideTokens, 0, tokens, nameSize, rightSideTokens.length);
+		long[] rightSidePositions = qualifiedTypeReference.sourcePositions;
+		System.arraycopy(rightSidePositions, 0, positions, nameSize, rightSidePositions.length);
+		Annotation [][] rightSideAnnotations = qualifiedTypeReference.annotations;
+		if (rightSideAnnotations != null) {
+			typeAnnotations = new Annotation[tokensSize][];
+			System.arraycopy(rightSideAnnotations, 0, typeAnnotations, nameSize, rightSideAnnotations.length);
+		}
+	}
+
+	int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	TypeReference[] currentTypeArguments = new TypeReference[currentTypeArgumentsLength];
+	this.genericsPtr -= currentTypeArgumentsLength;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, currentTypeArguments, 0, currentTypeArgumentsLength);
+
+	if (nameSize == 1) {
+		tokens[0] = this.identifierStack[this.identifierPtr];
+		positions[0] = this.identifierPositionStack[this.identifierPtr--];
+		typeArguments[0] = currentTypeArguments;
+	} else {
+		this.identifierPtr -= nameSize;
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, nameSize);
+		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, nameSize);
+		typeArguments[nameSize - 1] = currentTypeArguments;
+	}
+	this.identifierLengthPtr--;
+	ParameterizedQualifiedTypeReference typeRef = new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, annotationsOnDimensions, positions);
+
+	while (nameSize > 0) {
+		int length;
+		if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+			if (typeAnnotations == null)
+				typeAnnotations = new Annotation[tokensSize][];
+			System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					typeAnnotations[nameSize - 1] = new Annotation[length],
+					0,
+					length);
+			if (nameSize == 1) {
+				typeRef.sourceStart = typeAnnotations[0][0].sourceStart;
+			}
+		}
+		nameSize--;
+	}
+	
+	if ((typeRef.annotations = typeAnnotations) != null) {
+		typeRef.bits |= ASTNode.HasTypeAnnotations;
+	}
+	return typeRef;
+}
+protected void concatExpressionLists() {
+	this.expressionLengthStack[--this.expressionLengthPtr]++;
+}
+protected void concatGenericsLists() {
+	this.genericsLengthStack[this.genericsLengthPtr - 1] += this.genericsLengthStack[this.genericsLengthPtr--];
+}
+protected void concatNodeLists() {
+	/*
+	 * This is a case where you have two sublists into the this.astStack that you want
+	 * to merge in one list. There is no action required on the this.astStack. The only
+	 * thing you need to do is merge the two lengths specified on the astStackLength.
+	 * The top two length are for example:
+	 * ... p   n
+	 * and you want to result in a list like:
+	 * ... n+p
+	 * This means that the p could be equals to 0 in case there is no astNode pushed
+	 * on the this.astStack.
+	 * Look at the InterfaceMemberDeclarations for an example.
+	 */
+
+	this.astLengthStack[this.astLengthPtr - 1] += this.astLengthStack[this.astLengthPtr--];
+}
+protected void consumeAdditionalBound() {
+	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeAdditionalBound1() {
+	// nothing to be done.
+	// The reference type1 is consumed by consumeReferenceType1 method.
+}
+protected void consumeAdditionalBoundList() {
+	concatGenericsLists();
+}
+protected void consumeAdditionalBoundList1() {
+	concatGenericsLists();
+}
+protected void consumeAllocationHeader() {
+	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+
+	// ClassBodyopt produces a null item on the astStak if it produces NO class body
+	// An empty class body produces a 0 on the length stack.....
+
+	if (this.currentElement == null){
+		return; // should never occur, this consumeRule is only used in recovery mode
+	}
+	if (this.currentToken == TokenNameLBRACE){
+		// beginning of an anonymous type
+		TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
+		anonymousType.name = CharOperation.NO_CHAR;
+		anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
+		anonymousType.sourceStart = this.intStack[this.intPtr--];
+		anonymousType.declarationSourceStart = anonymousType.sourceStart;
+		anonymousType.sourceEnd = this.rParenPos; // closing parenthesis
+		QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
+		alloc.type = getTypeReference(0);
+		alloc.sourceStart = anonymousType.sourceStart;
+		alloc.sourceEnd = anonymousType.sourceEnd ;
+		this.lastCheckPoint = anonymousType.bodyStart = this.scanner.currentPosition;
+		this.currentElement = this.currentElement.add(anonymousType, 0);
+		this.lastIgnoredToken = -1;
+		this.currentToken = 0; // opening brace already taken into account
+		return;
+	}
+	this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
+	this.restartRecovery = true; // request to restart from here on
+}
+protected void consumeAnnotationAsModifier() {
+	Expression expression = this.expressionStack[this.expressionPtr];
+	int sourceStart = expression.sourceStart;
+	if (this.modifiersSourceStart < 0) {
+		this.modifiersSourceStart = sourceStart;
+	}
+}
+protected void consumeAnnotationName() {
+	if(this.currentElement != null) {
+		int start = this.intStack[this.intPtr];
+		int end = (int) (this.identifierPositionStack[this.identifierPtr] & 0x00000000FFFFFFFFL);
+		annotationRecoveryCheckPoint(start, end);
+
+		if (this.annotationRecoveryActivated) {
+			this.currentElement = this.currentElement.addAnnotationName(this.identifierPtr, this.identifierLengthPtr, start, 0);
+		}
+	}
+	this.recordStringLiterals = false;
+}
+protected void consumeAnnotationTypeDeclaration() {
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		//there are length declarations
+		//dispatch according to the type of the declarations
+		dispatchDeclarationInto(length);
+	}
+
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+
+	//convert constructor that do not have the type's name into methods
+	typeDecl.checkConstructors(this);
+
+	//always add <clinit> (will be remove at code gen time if empty)
+	if (this.scanner.containsAssertKeyword) {
+		typeDecl.bits |= ASTNode.ContainsAssertion;
+	}
+	typeDecl.addClinit();
+	typeDecl.bodyEnd = this.endStatementPosition;
+	if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
+		typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+	typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeAnnotationTypeDeclarationHeader() {
+	TypeDeclaration annotationTypeDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
+	if (this.currentToken == TokenNameLBRACE) {
+		annotationTypeDeclaration.bodyStart = this.scanner.currentPosition;
+	}
+	if (this.currentElement != null) {
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	// flush the comments related to the annotation type header
+	this.scanner.commentPtr = -1;
+}
+protected void consumeAnnotationTypeDeclarationHeaderName() {
+	// consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier
+	// consumeAnnotationTypeDeclarationHeader ::= '@' PushModifiers interface Identifier
+	TypeDeclaration annotationTypeDeclaration = new TypeDeclaration(this.compilationUnit.compilationResult);
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			annotationTypeDeclaration.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		annotationTypeDeclaration.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	annotationTypeDeclaration.sourceEnd = (int) pos;
+	annotationTypeDeclaration.sourceStart = (int) (pos >>> 32);
+	annotationTypeDeclaration.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	this.intPtr--; // remove the start position of the interface token
+	this.intPtr--; // remove the end position of the interface token
+
+	annotationTypeDeclaration.modifiersSourceStart = this.intStack[this.intPtr--];
+	annotationTypeDeclaration.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface;
+	if (annotationTypeDeclaration.modifiersSourceStart >= 0) {
+		annotationTypeDeclaration.declarationSourceStart = annotationTypeDeclaration.modifiersSourceStart;
+		this.intPtr--; // remove the position of the '@' token as we have modifiers
+	} else {
+		int atPosition = this.intStack[this.intPtr--];
+		// remove the position of the '@' token as we don't have modifiers
+		annotationTypeDeclaration.declarationSourceStart = atPosition;
+	}
+
+	// Store secondary info
+	if ((annotationTypeDeclaration.bits & ASTNode.IsMemberType) == 0 && (annotationTypeDeclaration.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(annotationTypeDeclaration.name, this.compilationUnit.getMainTypeName())) {
+			annotationTypeDeclaration.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			annotationTypeDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	annotationTypeDeclaration.bodyStart = annotationTypeDeclaration.sourceEnd + 1;
+
+	// javadoc
+	annotationTypeDeclaration.javadoc = this.javadoc;
+	this.javadoc = null;
+	pushOnAstStack(annotationTypeDeclaration);
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = annotationTypeDeclaration.bodyStart;
+		this.currentElement = this.currentElement.add(annotationTypeDeclaration, 0);
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() {
+	// consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier TypeParameters
+	// consumeAnnotationTypeDeclarationHeader ::= '@' PushModifiers interface Identifier TypeParameters
+	TypeDeclaration annotationTypeDeclaration = new TypeDeclaration(this.compilationUnit.compilationResult);
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, annotationTypeDeclaration.typeParameters = new TypeParameter[length], 0, length);
+
+	problemReporter().invalidUsageOfTypeParametersForAnnotationDeclaration(annotationTypeDeclaration);
+
+	annotationTypeDeclaration.bodyStart = annotationTypeDeclaration.typeParameters[length-1].declarationSourceEnd + 1;
+
+//	annotationTypeDeclaration.typeParameters = null;
+
+	this.listTypeParameterLength = 0;
+
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			annotationTypeDeclaration.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		annotationTypeDeclaration.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	annotationTypeDeclaration.sourceEnd = (int) pos;
+	annotationTypeDeclaration.sourceStart = (int) (pos >>> 32);
+	annotationTypeDeclaration.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	this.intPtr--; // remove the start position of the interface token
+	this.intPtr--; // remove the end position of the interface token
+
+	annotationTypeDeclaration.modifiersSourceStart = this.intStack[this.intPtr--];
+	annotationTypeDeclaration.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface;
+	if (annotationTypeDeclaration.modifiersSourceStart >= 0) {
+		annotationTypeDeclaration.declarationSourceStart = annotationTypeDeclaration.modifiersSourceStart;
+		this.intPtr--; // remove the position of the '@' token as we have modifiers
+	} else {
+		int atPosition = this.intStack[this.intPtr--];
+		// remove the position of the '@' token as we don't have modifiers
+		annotationTypeDeclaration.declarationSourceStart = atPosition;
+	}
+
+	// Store secondary info
+	if ((annotationTypeDeclaration.bits & ASTNode.IsMemberType) == 0 && (annotationTypeDeclaration.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(annotationTypeDeclaration.name, this.compilationUnit.getMainTypeName())) {
+			annotationTypeDeclaration.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			annotationTypeDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	annotationTypeDeclaration.javadoc = this.javadoc;
+	this.javadoc = null;
+	pushOnAstStack(annotationTypeDeclaration);
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfAnnotationDeclarations(annotationTypeDeclaration);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = annotationTypeDeclaration.bodyStart;
+		this.currentElement = this.currentElement.add(annotationTypeDeclaration, 0);
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeAnnotationTypeMemberDeclaration() {
+	// AnnotationTypeMemberDeclaration ::= AnnotationTypeMemberDeclarationHeader AnnotationTypeMemberHeaderExtendedDims DefaultValueopt ';'
+	AnnotationMethodDeclaration annotationTypeMemberDeclaration = (AnnotationMethodDeclaration) this.astStack[this.astPtr];
+	annotationTypeMemberDeclaration.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+	// store the this.endPosition (position just before the '}') in case there is
+	// a trailing comment behind the end of the method
+	int declarationEndPosition = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	annotationTypeMemberDeclaration.bodyStart = this.endStatementPosition;
+	annotationTypeMemberDeclaration.bodyEnd = declarationEndPosition;
+	annotationTypeMemberDeclaration.declarationSourceEnd = declarationEndPosition;
+}
+protected void consumeAnnotationTypeMemberDeclarations() {
+	// AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration
+	concatNodeLists();
+}
+protected void consumeAnnotationTypeMemberDeclarationsopt() {
+	this.nestedType-- ;
+}
+protected void consumeArgumentList() {
+	// ArgumentList ::= ArgumentList ',' Expression
+	concatExpressionLists();
+}
+protected void consumeArguments() {
+	// Arguments ::= '(' ArgumentListopt ')'
+	// nothing to do, the expression stack is already updated
+	pushOnIntStack(this.rParenPos);
+}
+protected void consumeArrayAccess(boolean unspecifiedReference) {
+	// ArrayAccess ::= Name '[' Expression ']' ==> true
+	// ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' ==> false
+
+
+	//optimize push/pop
+	Expression exp;
+	if (unspecifiedReference) {
+		exp =
+			this.expressionStack[this.expressionPtr] =
+				new ArrayReference(
+					getUnspecifiedReferenceOptimized(),
+					this.expressionStack[this.expressionPtr]);
+	} else {
+		this.expressionPtr--;
+		this.expressionLengthPtr--;
+		exp =
+			this.expressionStack[this.expressionPtr] =
+				new ArrayReference(
+					this.expressionStack[this.expressionPtr],
+					this.expressionStack[this.expressionPtr + 1]);
+	}
+	exp.sourceEnd = this.endStatementPosition;
+}
+protected void consumeArrayCreationExpressionWithInitializer() {
+	// ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer
+	// ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
+
+	int length;
+	ArrayAllocationExpression arrayAllocation = new ArrayAllocationExpression();
+	this.expressionLengthPtr -- ;
+	arrayAllocation.initializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
+
+	length = (this.expressionLengthStack[this.expressionLengthPtr--]);
+	this.expressionPtr -= length ;
+	System.arraycopy(
+		this.expressionStack,
+		this.expressionPtr+1,
+		arrayAllocation.dimensions = new Expression[length],
+		0,
+		length);
+	Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions(length);
+	arrayAllocation.annotationsOnDimensions = annotationsOnDimensions;
+
+	arrayAllocation.type = getTypeReference(0);
+	arrayAllocation.type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
+	if (annotationsOnDimensions != null) {
+		arrayAllocation.bits |= ASTNode.HasTypeAnnotations;
+		arrayAllocation.type.bits |= ASTNode.HasTypeAnnotations;
+	}
+
+	arrayAllocation.sourceStart = this.intStack[this.intPtr--];
+	if (arrayAllocation.initializer == null) {
+		arrayAllocation.sourceEnd = this.endStatementPosition;
+	} else {
+		arrayAllocation.sourceEnd = arrayAllocation.initializer.sourceEnd ;
+	}
+	pushOnExpressionStack(arrayAllocation);
+}
+protected void consumeArrayCreationExpressionWithoutInitializer() {
+	// ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
+	// ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
+
+	int length;
+	ArrayAllocationExpression arrayAllocation = new ArrayAllocationExpression();
+	length = (this.expressionLengthStack[this.expressionLengthPtr--]);
+	this.expressionPtr -= length ;
+	System.arraycopy(
+		this.expressionStack,
+		this.expressionPtr+1,
+		arrayAllocation.dimensions = new Expression[length],
+		0,
+		length);
+	Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions(length);
+	arrayAllocation.annotationsOnDimensions = annotationsOnDimensions;
+	arrayAllocation.type = getTypeReference(0);
+	arrayAllocation.type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
+	if (annotationsOnDimensions != null) {
+		arrayAllocation.bits |= ASTNode.HasTypeAnnotations;
+		arrayAllocation.type.bits |= ASTNode.HasTypeAnnotations;
+	}
+	arrayAllocation.sourceStart = this.intStack[this.intPtr--];
+	if (arrayAllocation.initializer == null) {
+		arrayAllocation.sourceEnd = this.endStatementPosition;
+	} else {
+		arrayAllocation.sourceEnd = arrayAllocation.initializer.sourceEnd ;
+	}
+	pushOnExpressionStack(arrayAllocation);
+}
+protected void consumeArrayCreationHeader() {
+	// nothing to do
+}
+protected void consumeArrayInitializer() {
+	// ArrayInitializer ::= '{' VariableInitializers '}'
+	// ArrayInitializer ::= '{' VariableInitializers , '}'
+
+	arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
+}
+protected void consumeArrayTypeWithTypeArgumentsName() {
+	this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] += this.identifierLengthStack[this.identifierLengthPtr];
+	pushOnGenericsLengthStack(0); // handle type arguments
+}
+protected void consumeAssertStatement() {
+	// AssertStatement ::= 'assert' Expression ':' Expression ';'
+	this.expressionLengthPtr-=2;
+	pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
+}
+protected void consumeAssignment() {
+	// Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression
+	//optimize the push/pop
+
+	int op = this.intStack[this.intPtr--] ; //<--the encoded operator
+
+	this.expressionPtr -- ; this.expressionLengthPtr -- ;
+	Expression expression = this.expressionStack[this.expressionPtr+1];
+	this.expressionStack[this.expressionPtr] =
+		(op != EQUAL ) ?
+			new CompoundAssignment(
+				this.expressionStack[this.expressionPtr] ,
+				expression,
+				op,
+				expression.sourceEnd):
+			new Assignment(
+				this.expressionStack[this.expressionPtr] ,
+				expression,
+				expression.sourceEnd);
+
+	if (this.pendingRecoveredType != null) {
+		// Used only in statements recovery.
+		// This is not a real assignment but a placeholder for an existing anonymous type.
+		// The assignment must be replace by the anonymous type.
+		if (this.pendingRecoveredType.allocation != null &&
+				this.scanner.startPosition - 1 <= this.pendingRecoveredType.declarationSourceEnd) {
+			this.expressionStack[this.expressionPtr] = this.pendingRecoveredType.allocation;
+			this.pendingRecoveredType = null;
+			return;
+		}
+		this.pendingRecoveredType = null;
+	}
+}
+protected void consumeAssignmentOperator(int pos) {
+	// AssignmentOperator ::= '='
+	// AssignmentOperator ::= '*='
+	// AssignmentOperator ::= '/='
+	// AssignmentOperator ::= '%='
+	// AssignmentOperator ::= '+='
+	// AssignmentOperator ::= '-='
+	// AssignmentOperator ::= '<<='
+	// AssignmentOperator ::= '>>='
+	// AssignmentOperator ::= '>>>='
+	// AssignmentOperator ::= '&='
+	// AssignmentOperator ::= '^='
+	// AssignmentOperator ::= '|='
+
+	pushOnIntStack(pos);
+}
+protected void consumeBinaryExpression(int op) {
+	// MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
+	// MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
+	// MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
+	// AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
+	// AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
+	// ShiftExpression ::= ShiftExpression '<<'  AdditiveExpression
+	// ShiftExpression ::= ShiftExpression '>>'  AdditiveExpression
+	// ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
+	// RelationalExpression ::= RelationalExpression '<'  ShiftExpression
+	// RelationalExpression ::= RelationalExpression '>'  ShiftExpression
+	// RelationalExpression ::= RelationalExpression '<=' ShiftExpression
+	// RelationalExpression ::= RelationalExpression '>=' ShiftExpression
+	// AndExpression ::= AndExpression '&' EqualityExpression
+	// ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
+	// InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
+	// ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
+	// ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
+
+	//optimize the push/pop
+
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	Expression expr1 = this.expressionStack[this.expressionPtr];
+	Expression expr2 = this.expressionStack[this.expressionPtr + 1];
+	switch(op) {
+		case OR_OR :
+			this.expressionStack[this.expressionPtr] =
+				new OR_OR_Expression(
+					expr1,
+					expr2,
+					op);
+			break;
+		case AND_AND :
+			this.expressionStack[this.expressionPtr] =
+				new AND_AND_Expression(
+					expr1,
+					expr2,
+					op);
+			break;
+		case PLUS :
+			// look for "string1" + "string2"
+			if (this.optimizeStringLiterals) {
+				if (expr1 instanceof StringLiteral) {
+					if (((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) {
+						if (expr2 instanceof CharLiteral) { // string+char
+							this.expressionStack[this.expressionPtr] =
+								((StringLiteral) expr1).extendWith((CharLiteral) expr2);
+						} else if (expr2 instanceof StringLiteral) { //string+string
+							this.expressionStack[this.expressionPtr] =
+								((StringLiteral) expr1).extendWith((StringLiteral) expr2);
+						} else {
+							this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+						}
+					} else {
+						this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+					}
+				} else if (expr1 instanceof CombinedBinaryExpression) {
+					CombinedBinaryExpression cursor;
+					// left branch is comprised of PLUS BEs
+					// cursor is shifted upwards, while needed BEs are added
+					// on demand; past the arityMax-th
+					// consecutive BE, a CBE is inserted that holds a
+					// full-fledged references table
+					if ((cursor = (CombinedBinaryExpression)expr1).arity < cursor.arityMax) {
+						cursor.left = new BinaryExpression(cursor);
+						cursor.arity++;
+					} else {
+						cursor.left = new CombinedBinaryExpression(cursor);
+						cursor.arity = 0;
+						cursor.tuneArityMax();
+					}
+					cursor.right = expr2;
+					cursor.sourceEnd = expr2.sourceEnd;
+					this.expressionStack[this.expressionPtr] = cursor;
+					// BE_INSTRUMENTATION: neutralized in the released code
+//					cursor.depthTracker = ((BinaryExpression)cursor.left).
+//						depthTracker + 1;
+				} else if (expr1 instanceof BinaryExpression &&
+							// single out the a + b case, which is a BE
+							// instead of a CBE (slightly more than a half of
+							// strings concatenation are one-deep binary
+							// expressions)
+						((expr1.bits & ASTNode.OperatorMASK) >>
+							ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
+					this.expressionStack[this.expressionPtr] =
+						new CombinedBinaryExpression(expr1, expr2, PLUS, 1);
+				} else {
+					this.expressionStack[this.expressionPtr] =
+						new BinaryExpression(expr1, expr2, PLUS);
+				}
+			} else if (expr1 instanceof StringLiteral) {
+				if (expr2 instanceof StringLiteral
+						&& ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) {
+					// string + string
+					this.expressionStack[this.expressionPtr] =
+						((StringLiteral) expr1).extendsWith((StringLiteral) expr2);
+				} else {
+					// single out the a + b case
+					this.expressionStack[this.expressionPtr] =
+						new BinaryExpression(expr1, expr2, PLUS);
+				}
+			} else if (expr1 instanceof CombinedBinaryExpression) {
+					CombinedBinaryExpression cursor;
+					// shift cursor; create BE/CBE as needed
+					if ((cursor = (CombinedBinaryExpression)expr1).arity < cursor.arityMax) {
+						cursor.left = new BinaryExpression(cursor);
+						// clear the bits on cursor
+						cursor.bits &= ~ASTNode.ParenthesizedMASK;
+						cursor.arity++;
+					} else {
+						cursor.left = new CombinedBinaryExpression(cursor);
+						// clear the bits on cursor
+						cursor.bits &= ~ASTNode.ParenthesizedMASK;
+						cursor.arity = 0;
+						cursor.tuneArityMax();
+					}
+					cursor.right = expr2;
+					cursor.sourceEnd = expr2.sourceEnd;
+					// BE_INSTRUMENTATION: neutralized in the released code
+//					cursor.depthTracker = ((BinaryExpression)cursor.left).
+//						depthTracker + 1;
+					this.expressionStack[this.expressionPtr] = cursor;
+			} else if (expr1 instanceof BinaryExpression
+					&& ((expr1.bits & ASTNode.OperatorMASK) >>
+							ASTNode.OperatorSHIFT) == OperatorIds.PLUS) {
+				// single out the a + b case
+				this.expressionStack[this.expressionPtr] =
+					new CombinedBinaryExpression(expr1, expr2, PLUS, 1);
+			} else {
+				this.expressionStack[this.expressionPtr] =
+					new BinaryExpression(expr1, expr2, PLUS);
+			}
+			break;
+		case LESS :
+		case MULTIPLY :
+			this.intPtr--; // star end position or starting position of angle bracket
+			this.expressionStack[this.expressionPtr] =
+				new BinaryExpression(
+					expr1,
+					expr2,
+					op);
+			break;
+		default :
+			this.expressionStack[this.expressionPtr] =
+				new BinaryExpression(
+					expr1,
+					expr2,
+					op);
+	}
+}
+/**
+ * @param op binary operator
+ */
+protected void consumeBinaryExpressionWithName(int op) {
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	/*
+	if (op == OR_OR) {
+		this.expressionStack[this.expressionPtr] =
+			new OR_OR_Expression(
+				this.expressionStack[this.expressionPtr + 1],
+				this.expressionStack[this.expressionPtr],
+				op);
+	} else {
+		if (op == AND_AND) {
+			this.expressionStack[this.expressionPtr] =
+				new AND_AND_Expression(
+					this.expressionStack[this.expressionPtr + 1],
+					this.expressionStack[this.expressionPtr],
+					op);
+		} else {
+			// look for "string1" + "string2"
+			if ((op == PLUS) && this.optimizeStringLiterals) {
+				Expression expr1, expr2;
+				expr1 = this.expressionStack[this.expressionPtr + 1];
+				expr2 = this.expressionStack[this.expressionPtr];
+				if (expr1 instanceof StringLiteral) {
+					if (expr2 instanceof CharLiteral) { // string+char
+						this.expressionStack[this.expressionPtr] =
+							((StringLiteral) expr1).extendWith((CharLiteral) expr2);
+					} else if (expr2 instanceof StringLiteral) { //string+string
+						this.expressionStack[this.expressionPtr] =
+							((StringLiteral) expr1).extendWith((StringLiteral) expr2);
+					} else {
+						this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+					}
+				} else {
+					this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+				}
+			} else {
+				this.expressionStack[this.expressionPtr] =
+					new BinaryExpression(
+						this.expressionStack[this.expressionPtr + 1],
+						this.expressionStack[this.expressionPtr],
+						op);
+			}
+		}
+	}
+	*/
+	Expression expr1 = this.expressionStack[this.expressionPtr + 1];
+	Expression expr2 = this.expressionStack[this.expressionPtr];
+	// Note: we do not attempt to promote BinaryExpression-s to
+	//       IndexedBinaryExpression-s here since expr1 always holds a name
+	switch(op) {
+		case OR_OR :
+			this.expressionStack[this.expressionPtr] =
+				new OR_OR_Expression(
+					expr1,
+					expr2,
+					op);
+			break;
+		case AND_AND :
+			this.expressionStack[this.expressionPtr] =
+				new AND_AND_Expression(
+					expr1,
+					expr2,
+					op);
+			break;
+		case PLUS :
+			// look for "string1" + "string2"
+			if (this.optimizeStringLiterals) {
+				if (expr1 instanceof StringLiteral
+						&& ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) {
+					if (expr2 instanceof CharLiteral) { // string+char
+						this.expressionStack[this.expressionPtr] =
+							((StringLiteral) expr1).extendWith((CharLiteral) expr2);
+					} else if (expr2 instanceof StringLiteral) { //string+string
+						this.expressionStack[this.expressionPtr] =
+							((StringLiteral) expr1).extendWith((StringLiteral) expr2);
+					} else {
+						this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+					}
+				} else {
+					this.expressionStack[this.expressionPtr] = new BinaryExpression(expr1, expr2, PLUS);
+				}
+			} else if (expr1 instanceof StringLiteral) {
+				if (expr2 instanceof StringLiteral
+						&& ((expr1.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) {
+					// string + string
+					this.expressionStack[this.expressionPtr] =
+						((StringLiteral) expr1).extendsWith((StringLiteral) expr2);
+				} else {
+					this.expressionStack[this.expressionPtr] =
+						new BinaryExpression(
+							expr1,
+							expr2,
+							op);
+				}
+			} else {
+				this.expressionStack[this.expressionPtr] =
+					new BinaryExpression(
+						expr1,
+						expr2,
+						op);
+			}
+			break;
+		case LESS :
+		case MULTIPLY :
+			this.intPtr--; // star end position or starting position of angle bracket
+			this.expressionStack[this.expressionPtr] =
+				new BinaryExpression(
+					expr1,
+					expr2,
+					op);
+			break;
+		default :
+			this.expressionStack[this.expressionPtr] =
+				new BinaryExpression(
+					expr1,
+					expr2,
+					op);
+	}
+}
+protected void consumeBlock() {
+	// Block ::= OpenBlock '{' BlockStatementsopt '}'
+	// LambdaBody ::= NestedType NestedMethod  '{' BlockStatementsopt '}'
+	// simpler action for empty blocks
+
+	int statementsLength = this.astLengthStack[this.astLengthPtr--];
+	Block block;
+	if (statementsLength == 0) { // empty block
+		block = new Block(0);
+		block.sourceStart = this.intStack[this.intPtr--];
+		block.sourceEnd = this.endStatementPosition;
+		// check whether this block at least contains some comment in it
+		if (!containsComment(block.sourceStart, block.sourceEnd)) {
+			block.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+		this.realBlockPtr--; // still need to pop the block variable counter
+	} else {
+		block = new Block(this.realBlockStack[this.realBlockPtr--]);
+		this.astPtr -= statementsLength;
+		System.arraycopy(
+			this.astStack,
+			this.astPtr + 1,
+			block.statements = new Statement[statementsLength],
+			0,
+			statementsLength);
+		block.sourceStart = this.intStack[this.intPtr--];
+		block.sourceEnd = this.endStatementPosition;
+	}
+	pushOnAstStack(block);
+}
+protected void consumeBlockStatements() {
+	// BlockStatements ::= BlockStatements BlockStatement
+	concatNodeLists();
+}
+protected void consumeCaseLabel() {
+	// SwitchLabel ::= 'case' ConstantExpression ':'
+	this.expressionLengthPtr--;
+	Expression expression = this.expressionStack[this.expressionPtr--];
+	CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]);
+	// Look for $fall-through$ tag in leading comment for case statement
+	if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) {
+		caseStatement.bits |= ASTNode.DocumentedFallthrough;
+	}
+	pushOnAstStack(caseStatement);
+}
+protected void consumeCastExpressionLL1() {
+	//CastExpression ::= '(' Name ')' InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
+	
+
+	//optimize push/pop
+
+	Expression cast;
+	Expression exp;
+	this.expressionPtr--;
+	this.expressionStack[this.expressionPtr] =
+		cast = new CastExpression(
+			exp=this.expressionStack[this.expressionPtr+1] ,
+			(TypeReference) this.expressionStack[this.expressionPtr]);
+	this.expressionLengthPtr -- ;
+	updateSourcePosition(cast);
+	cast.sourceEnd=exp.sourceEnd;
+}
+public IntersectionCastTypeReference createIntersectionCastTypeReference(TypeReference[] typeReferences) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_8) {
+		problemReporter().intersectionCastNotBelow18(typeReferences);
+	}
+	return new IntersectionCastTypeReference(typeReferences);
+}
+protected void consumeCastExpressionLL1WithBounds() {
+	//CastExpression ::= '(' Name AdditionalBoundsList ')' UnaryExpressionNotPlusMinus
+	Expression cast;
+	Expression exp;
+	
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	TypeReference[] bounds = new TypeReference[additionalBoundsLength + 1];
+	this.genericsPtr -= additionalBoundsLength;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+
+	pushOnGenericsLengthStack(0); // handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	bounds[0] = getTypeReference(0);
+ 
+	this.expressionStack[this.expressionPtr] =
+		cast = new CastExpression(
+			exp=this.expressionStack[this.expressionPtr] ,
+			createIntersectionCastTypeReference(bounds));
+	updateSourcePosition(cast);
+	cast.sourceEnd=exp.sourceEnd;
+}
+protected void consumeCastExpressionWithGenericsArray() {
+	// CastExpression ::= PushLPAREN Name TypeArguments Dimsopt AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+	
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	int end = this.intStack[this.intPtr--];
+
+	int dim = this.intStack[this.intPtr--];
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	if (additionalBoundsLength > 0) {
+		bounds[0] = getTypeReference(dim);
+		castType = createIntersectionCastTypeReference(bounds); 
+	} else {
+		castType = getTypeReference(dim);
+	}
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType);
+	this.intPtr--;  // pop position of '<'
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionWithNameArray() {
+	// CastExpression ::= PushLPAREN Name Dims AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	int end = this.intStack[this.intPtr--];
+
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+	// handle type arguments
+	pushOnGenericsLengthStack(0);
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	
+	if (additionalBoundsLength > 0) {
+		bounds[0] = getTypeReference(this.intStack[this.intPtr--]);
+		castType = createIntersectionCastTypeReference(bounds);
+	} else {
+		castType = getTypeReference(this.intStack[this.intPtr--]);
+	}
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType);
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionWithPrimitiveType() {
+	// CastExpression ::= PushLPAREN PrimitiveType Dimsopt AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpression
+
+	//this.intStack : posOfLeftParen dim posOfRightParen
+
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+	
+	//optimize the push/pop
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	int end = this.intStack[this.intPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds[0] = getTypeReference(this.intStack[this.intPtr--]);
+		castType = createIntersectionCastTypeReference(bounds); 
+	} else {
+		castType = getTypeReference(this.intStack[this.intPtr--]);
+	}
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType);
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCastExpressionWithQualifiedGenericsArray() {
+	// CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dimsopt AdditionalBoundsOpt PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+
+	TypeReference[] bounds = null;
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (additionalBoundsLength > 0) {
+		bounds = new TypeReference[additionalBoundsLength + 1];
+		this.genericsPtr -= additionalBoundsLength;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 1, additionalBoundsLength);
+	}
+
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
+	int end = this.intStack[this.intPtr--];
+	int dim = this.intStack[this.intPtr--];
+	Annotation [][] annotationsOnDimensions = dim == 0 ? null : getAnnotationsOnDimensions(dim);
+	TypeReference rightSide = getTypeReference(0);
+    castType = computeQualifiedGenericsFromRightSide(rightSide, dim, annotationsOnDimensions);
+
+    if (additionalBoundsLength > 0) {
+		bounds[0] = castType;
+		castType = createIntersectionCastTypeReference(bounds); 
+	}
+    
+    this.intPtr--;
+	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType);
+	castType.sourceEnd = end - 1;
+	castType.sourceStart = (cast.sourceStart = this.intStack[this.intPtr--]) + 1;
+	cast.sourceEnd = exp.sourceEnd;
+}
+protected void consumeCatches() {
+	// Catches ::= Catches CatchClause
+	optimizedConcatNodeLists();
+}
+protected void consumeCatchFormalParameter() {
+	// CatchFormalParameter ::= Modifiersopt CatchType VariableDeclaratorId
+	this.identifierLengthPtr--;
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+	int extendedDimensions = this.intStack[this.intPtr--]; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=348369
+	TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+	if (extendedDimensions > 0) {
+		type = type.copyDims(type.dimensions() + extendedDimensions);
+		type.sourceEnd = this.endPosition;
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391092
+		if (type instanceof UnionTypeReference) {
+			this.problemReporter().illegalArrayOfUnionType(identifierName, type);		
+		}
+	}
+	this.astLengthPtr--;
+	int modifierPositions = this.intStack[this.intPtr--];
+	this.intPtr--;
+	Argument arg =
+		new Argument(
+			identifierName,
+			namePositions,
+			type,
+			this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+	arg.bits &= ~ASTNode.IsArgument;
+	arg.declarationSourceStart = modifierPositions;
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			arg.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	pushOnAstStack(arg);
+	/* if incomplete method header, this.listLength counter will not have been reset,
+		indicating that some arguments are available on the stack */
+	this.listLength++;
+}
+protected void consumeCatchHeader() {
+	// CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
+
+	if (this.currentElement == null){
+		return; // should never occur, this consumeRule is only used in recovery mode
+	}
+	// current element should be a block due to the presence of the opening brace
+	if (!(this.currentElement instanceof RecoveredBlock)){
+		if(!(this.currentElement instanceof RecoveredMethod)) {
+			return;
+		}
+		RecoveredMethod rMethod = (RecoveredMethod) this.currentElement;
+		if(!(rMethod.methodBody == null && rMethod.bracketBalance > 0)) {
+			return;
+		}
+	}
+
+	Argument arg = (Argument)this.astStack[this.astPtr--];
+	// convert argument to local variable
+	LocalDeclaration localDeclaration = new LocalDeclaration(arg.name, arg.sourceStart, arg.sourceEnd);
+	localDeclaration.type = arg.type;
+	localDeclaration.declarationSourceStart = arg.declarationSourceStart;
+	localDeclaration.declarationSourceEnd = arg.declarationSourceEnd;
+
+	this.currentElement = this.currentElement.add(localDeclaration, 0);
+	this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
+	this.restartRecovery = true; // request to restart from here on
+	this.lastIgnoredToken = -1;
+}
+protected void consumeCatchType() {
+	// CatchType ::= UnionType
+	int length = this.astLengthStack[this.astLengthPtr--];
+	if (length != 1) {
+		TypeReference[] typeReferences;
+		System.arraycopy(
+				this.astStack,
+				(this.astPtr -= length) + 1,
+				(typeReferences = new TypeReference[length]),
+				0,
+				length);
+		UnionTypeReference typeReference = new UnionTypeReference(typeReferences);
+		pushOnAstStack(typeReference);
+		if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+			problemReporter().multiCatchNotBelow17(typeReference);
+		}
+	} else {
+		// push back the type reference
+		pushOnAstLengthStack(1);
+	}
+}
+protected void consumeClassBodyDeclaration() {
+	// ClassBodyDeclaration ::= Diet NestedMethod CreateInitializer Block
+	//push an Initializer
+	//optimize the push/pop
+	this.nestedMethod[this.nestedType]--;
+	Block block = (Block) this.astStack[this.astPtr--];
+	this.astLengthPtr--;
+	if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlock; // clear bit since was diet
+	Initializer initializer = (Initializer) this.astStack[this.astPtr];
+	initializer.declarationSourceStart = initializer.sourceStart = block.sourceStart;
+	initializer.block = block;
+	this.intPtr--; // pop sourcestart left on the stack by consumeNestedMethod.
+	initializer.bodyStart = this.intStack[this.intPtr--];
+	this.realBlockPtr--; // pop the block variable counter left on the stack by consumeNestedMethod
+	int javadocCommentStart = this.intStack[this.intPtr--];
+	if (javadocCommentStart != -1) {
+		initializer.declarationSourceStart = javadocCommentStart;
+		initializer.javadoc = this.javadoc;
+		this.javadoc = null;
+	}
+	initializer.bodyEnd = this.endPosition;
+	initializer.sourceEnd = this.endStatementPosition;
+	initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeClassBodyDeclarations() {
+	// ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
+	concatNodeLists();
+}
+protected void consumeClassBodyDeclarationsopt() {
+	// ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
+	this.nestedType-- ;
+}
+protected void consumeClassBodyopt() {
+	// ClassBodyopt ::= $empty
+	pushOnAstStack(null);
+	this.endPosition = this.rParenPos;
+	this.shouldDeferRecovery = false;
+}
+protected void consumeClassDeclaration() {
+	// ClassDeclaration ::= ClassHeader ClassBody
+
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		//there are length declarations
+		//dispatch according to the type of the declarations
+		dispatchDeclarationInto(length);
+	}
+
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+
+	//convert constructor that do not have the type's name into methods
+	boolean hasConstructor = typeDecl.checkConstructors(this);
+
+	//add the default constructor when needed (interface don't have it)
+	if (!hasConstructor) {
+		switch(TypeDeclaration.kind(typeDecl.modifiers)) {
+			case TypeDeclaration.CLASS_DECL :
+			case TypeDeclaration.ENUM_DECL :
+				boolean insideFieldInitializer = false;
+				if (this.diet) {
+					for (int i = this.nestedType; i > 0; i--){
+						if (this.variablesCounter[i] > 0) {
+							insideFieldInitializer = true;
+							break;
+						}
+					}
+				}
+				typeDecl.createDefaultConstructor(!this.diet || insideFieldInitializer, true);
+		}
+	}
+	//always add <clinit> (will be remove at code gen time if empty)
+	if (this.scanner.containsAssertKeyword) {
+		typeDecl.bits |= ASTNode.ContainsAssertion;
+	}
+	typeDecl.addClinit();
+	typeDecl.bodyEnd = this.endStatementPosition;
+	if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
+		typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+
+	typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeClassHeader() {
+	// ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
+
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if (this.currentToken == TokenNameLBRACE) {
+		typeDecl.bodyStart = this.scanner.currentPosition;
+	}
+	if (this.currentElement != null) {
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	// flush the comments related to the class header
+	this.scanner.commentPtr = -1;
+}
+protected void consumeClassHeaderExtends() {
+	// ClassHeaderExtends ::= 'extends' ClassType
+	//superclass
+	TypeReference superClass = getTypeReference(0);
+	// There is a class declaration on the top of stack
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	typeDecl.bits |= (superClass.bits & ASTNode.HasTypeAnnotations);
+	typeDecl.superclass = superClass;
+	superClass.bits |= ASTNode.IsSuperType;
+	typeDecl.bodyStart = typeDecl.superclass.sourceEnd + 1;
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = typeDecl.bodyStart;
+	}
+}
+protected void consumeClassHeaderImplements() {
+	// ClassHeaderImplements ::= 'implements' InterfaceTypeList
+	int length = this.astLengthStack[this.astLengthPtr--];
+	//super interfaces
+	this.astPtr -= length;
+	// There is a class declaration on the top of stack
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	System.arraycopy(
+		this.astStack,
+		this.astPtr + 1,
+		typeDecl.superInterfaces = new TypeReference[length],
+		0,
+		length);
+	TypeReference[] superinterfaces = typeDecl.superInterfaces;
+	for (int i = 0, max = superinterfaces.length; i < max; i++) {
+		TypeReference typeReference = superinterfaces[i];
+		typeDecl.bits |= (typeReference.bits & ASTNode.HasTypeAnnotations);
+		typeReference.bits |= ASTNode.IsSuperType;
+	}
+	typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
+	this.listLength = 0; // reset after having read super-interfaces
+	// recovery
+	if (this.currentElement != null) { // is recovering
+		this.lastCheckPoint = typeDecl.bodyStart;
+	}
+}
+protected void consumeClassHeaderName1() {
+	// ClassHeaderName1 ::= Modifiersopt 'class' 'Identifier'
+	TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			typeDecl.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		typeDecl.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	typeDecl.sourceEnd = (int) pos;
+	typeDecl.sourceStart = (int) (pos >>> 32);
+	typeDecl.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--; // remove the end position of the class token
+
+	typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiers = this.intStack[this.intPtr--];
+	if (typeDecl.modifiersSourceStart >= 0) {
+		typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
+	}
+
+	// Store secondary info
+	if ((typeDecl.bits & ASTNode.IsMemberType) == 0 && (typeDecl.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(typeDecl.name, this.compilationUnit.getMainTypeName())) {
+			typeDecl.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			typeDecl.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
+	pushOnAstStack(typeDecl);
+
+	this.listLength = 0; // will be updated when reading super-interfaces
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = typeDecl.bodyStart;
+		this.currentElement = this.currentElement.add(typeDecl, 0);
+		this.lastIgnoredToken = -1;
+	}
+	// javadoc
+	typeDecl.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeClassInstanceCreationExpression() {
+	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+	classInstanceCreation(false);
+}
+protected void consumeClassInstanceCreationExpressionName() {
+	// ClassInstanceCreationExpressionName ::= Name '.'
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+}
+protected void consumeClassInstanceCreationExpressionQualified() {
+	// ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	classInstanceCreation(true);
+
+	QualifiedAllocationExpression qae =
+		(QualifiedAllocationExpression) this.expressionStack[this.expressionPtr];
+	
+	if (qae.anonymousType == null) {
+		this.expressionLengthPtr--;
+		this.expressionPtr--;
+		qae.enclosingInstance = this.expressionStack[this.expressionPtr];
+		this.expressionStack[this.expressionPtr] = qae;
+	}
+	qae.sourceStart = qae.enclosingInstance.sourceStart;
+}
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	// ClassInstanceCreationExpression ::= Primary '.' 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
+	// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
+
+	QualifiedAllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1) && (this.astStack[this.astPtr] == null)) {
+		//NO ClassBody
+		this.astPtr--;
+		alloc = new QualifiedAllocationExpression();
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
+		length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+	} else {
+		dispatchDeclarationInto(length);
+		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
+		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
+		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
+		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
+			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+		this.astPtr--;
+		this.astLengthPtr--;
+
+		QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
+		if (allocationExpression != null) {
+			allocationExpression.sourceEnd = this.endStatementPosition;
+			// handle type arguments
+			length = this.genericsLengthStack[this.genericsLengthPtr--];
+			this.genericsPtr -= length;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
+			allocationExpression.sourceStart = this.intStack[this.intPtr--];
+			checkForDiamond(allocationExpression.type);
+		}
+		rejectIllegalLeadingTypeAnnotations(allocationExpression.type);
+	}
+	
+	QualifiedAllocationExpression qae =
+		(QualifiedAllocationExpression) this.expressionStack[this.expressionPtr];
+	
+	if (qae.anonymousType == null) {
+		this.expressionLengthPtr--;
+		this.expressionPtr--;
+		qae.enclosingInstance = this.expressionStack[this.expressionPtr];
+		this.expressionStack[this.expressionPtr] = qae;
+	}
+	qae.sourceStart = qae.enclosingInstance.sourceStart;
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	// ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt
+	AllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+		//NO ClassBody
+		this.astPtr--;
+		alloc = new AllocationExpression();
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
+
+		length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+	} else {
+		dispatchDeclarationInto(length);
+		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
+		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
+		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
+		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
+			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+		this.astPtr--;
+		this.astLengthPtr--;
+
+		QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
+		if (allocationExpression != null) {
+			allocationExpression.sourceEnd = this.endStatementPosition;
+			// handle type arguments
+			length = this.genericsLengthStack[this.genericsLengthPtr--];
+			this.genericsPtr -= length;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
+			allocationExpression.sourceStart = this.intStack[this.intPtr--];
+			checkForDiamond(allocationExpression.type);
+		}
+		rejectIllegalLeadingTypeAnnotations(allocationExpression.type);
+	}
+}
+protected void consumeClassOrInterface() {
+	this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] += this.identifierLengthStack[this.identifierLengthPtr];
+	pushOnGenericsLengthStack(0); // handle type arguments
+}
+protected void consumeClassOrInterfaceName() {
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0); // handle type arguments
+}
+protected void consumeClassTypeElt() {
+	// ClassTypeElt ::= ClassType
+	pushOnAstStack(getTypeReference(0));
+	/* if incomplete thrown exception list, this.listLength counter will not have been reset,
+		indicating that some items are available on the stack */
+	this.listLength++;
+}
+protected void consumeClassTypeList() {
+	// ClassTypeList ::= ClassTypeList ',' ClassTypeElt
+	optimizedConcatNodeLists();
+}
+protected void consumeCompilationUnit() {
+	// CompilationUnit ::= EnterCompilationUnit InternalCompilationUnit
+	// do nothing by default
+}
+protected void consumeConditionalExpression(int op) {
+	// ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
+	//optimize the push/pop
+	this.intPtr -= 2;//consume position of the question mark
+	this.expressionPtr -= 2;
+	this.expressionLengthPtr -= 2;
+	this.expressionStack[this.expressionPtr] =
+		new ConditionalExpression(
+			this.expressionStack[this.expressionPtr],
+			this.expressionStack[this.expressionPtr + 1],
+			this.expressionStack[this.expressionPtr + 2]);
+}
+/**
+ * @param op
+ */
+protected void consumeConditionalExpressionWithName(int op) {
+	// ConditionalExpression ::= Name '?' Expression ':' ConditionalExpression
+	this.intPtr -= 2;//consume position of the question mark
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	this.expressionPtr -= 2;
+	this.expressionLengthPtr -= 2;
+	this.expressionStack[this.expressionPtr] =
+		new ConditionalExpression(
+			this.expressionStack[this.expressionPtr + 2],
+			this.expressionStack[this.expressionPtr],
+			this.expressionStack[this.expressionPtr + 1]);
+}
+protected void consumeConstructorBlockStatements() {
+	// ConstructorBody ::= NestedMethod '{' ExplicitConstructorInvocation BlockStatements '}'
+	concatNodeLists(); // explictly add the first statement into the list of statements
+}
+protected void consumeConstructorBody() {
+	// ConstructorBody ::= NestedMethod  '{' BlockStatementsopt '}'
+	// ConstructorBody ::= NestedMethod  '{' ExplicitConstructorInvocation '}'
+	this.nestedMethod[this.nestedType] --;
+}
+protected void consumeConstructorDeclaration() {
+	// ConstructorDeclaration ::= ConstructorHeader ConstructorBody
+
+	/*
+	this.astStack : MethodDeclaration statements
+	this.identifierStack : name
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	*/
+
+	//must provide a default constructor call when needed
+
+	int length;
+
+	// pop the position of the {  (body of the method) pushed in block decl
+	this.intPtr--;
+	this.intPtr--;
+
+	//statements
+	this.realBlockPtr--;
+	ExplicitConstructorCall constructorCall = null;
+	Statement[] statements = null;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+		if (!this.options.ignoreMethodBodies) {
+			if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall) {
+				//avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
+				System.arraycopy(
+					this.astStack,
+					this.astPtr + 2,
+					statements = new Statement[length - 1],
+					0,
+					length - 1);
+				constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
+			} else { //need to add explicitly the super();
+				System.arraycopy(
+					this.astStack,
+					this.astPtr + 1,
+					statements = new Statement[length],
+					0,
+					length);
+				constructorCall = SuperReference.implicitSuperConstructorCall();
+			}
+		}
+	} else {
+		boolean insideFieldInitializer = false;
+		if (this.diet) {
+			for (int i = this.nestedType; i > 0; i--){
+				if (this.variablesCounter[i] > 0) {
+					insideFieldInitializer = true;
+					break;
+				}
+			}
+		}
+
+		if (!this.options.ignoreMethodBodies) {
+			if (!this.diet || insideFieldInitializer){
+				// add it only in non-diet mode, if diet_bodies, then constructor call will be added elsewhere.
+				constructorCall = SuperReference.implicitSuperConstructorCall();
+			}
+		}
+	}
+
+	// now we know that the top of stack is a constructorDeclaration
+	ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
+	cd.constructorCall = constructorCall;
+	cd.statements = statements;
+
+	//highlight of the implicit call on the method name
+	if (constructorCall != null && cd.constructorCall.sourceEnd == 0) {
+		cd.constructorCall.sourceEnd = cd.sourceEnd;
+		cd.constructorCall.sourceStart = cd.sourceStart;
+	}
+
+	if (!(this.diet && this.dietInt == 0)
+			&& statements == null
+			&& (constructorCall == null || constructorCall.isImplicitSuper())
+			&& !containsComment(cd.bodyStart, this.endPosition)) {
+		cd.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+
+	//watch for } that could be given as a unicode ! ( u007D is '}' )
+	// store the this.endPosition (position just before the '}') in case there is
+	// a trailing comment behind the end of the method
+	cd.bodyEnd = this.endPosition;
+	cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeConstructorHeader() {
+	// ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
+
+	AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
+
+	if (this.currentToken == TokenNameLBRACE){
+		method.bodyStart = this.scanner.currentPosition;
+	}
+	// recovery
+	if (this.currentElement != null){
+		if (this.currentToken == TokenNameSEMICOLON){ // for invalid constructors
+			method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+			method.declarationSourceEnd = this.scanner.currentPosition-1;
+			method.bodyEnd = this.scanner.currentPosition-1;
+			if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
+				this.currentElement = this.currentElement.parent;
+			}
+		}
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeConstructorHeaderName() {
+
+	/* recovering - might be an empty message send */
+	if (this.currentElement != null){
+		if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
+			this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
+			this.restartRecovery = true;
+			return;
+		}
+	}
+
+	// ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
+	ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
+
+	//name -- this is not really revelant but we do .....
+	cd.selector = this.identifierStack[this.identifierPtr];
+	long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//modifiers
+	cd.declarationSourceStart = this.intStack[this.intPtr--];
+	cd.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			cd.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	cd.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at the selector starts
+	cd.sourceStart = (int) (selectorSource >>> 32);
+	pushOnAstStack(cd);
+	cd.sourceEnd = this.lParenPos;
+	cd.bodyStart = this.lParenPos+1;
+	this.listLength = 0; // initialize this.listLength before reading parameters/throws
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = cd.bodyStart;
+		if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
+			|| cd.modifiers != 0){
+			this.currentElement = this.currentElement.add(cd, 0);
+			this.lastIgnoredToken = -1;
+		}
+	}
+}
+protected void consumeConstructorHeaderNameWithTypeParameters() {
+
+	/* recovering - might be an empty message send */
+	if (this.currentElement != null){
+		if (this.lastIgnoredToken == TokenNamenew){ // was an allocation expression
+			this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
+			this.restartRecovery = true;
+			return;
+		}
+	}
+
+	// ConstructorHeaderName ::=  Modifiersopt TypeParameters 'Identifier' '('
+	ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
+
+	//name -- this is not really revelant but we do .....
+	cd.selector = this.identifierStack[this.identifierPtr];
+	long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, cd.typeParameters = new TypeParameter[length], 0, length);
+
+	//modifiers
+	cd.declarationSourceStart = this.intStack[this.intPtr--];
+	cd.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			cd.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	cd.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at the selector starts
+	cd.sourceStart = (int) (selectorSource >>> 32);
+	pushOnAstStack(cd);
+	cd.sourceEnd = this.lParenPos;
+	cd.bodyStart = this.lParenPos+1;
+	this.listLength = 0; // initialize this.listLength before reading parameters/throws
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = cd.bodyStart;
+		if ((this.currentElement instanceof RecoveredType && this.lastIgnoredToken != TokenNameDOT)
+			|| cd.modifiers != 0){
+			this.currentElement = this.currentElement.add(cd, 0);
+			this.lastIgnoredToken = -1;
+		}
+	}
+}
+protected void consumeCreateInitializer() {
+	pushOnAstStack(new Initializer(null, 0));
+}
+protected void consumeDefaultLabel() {
+	// SwitchLabel ::= 'default' ':'
+	CaseStatement defaultStatement = new CaseStatement(null, this.intStack[this.intPtr--], this.intStack[this.intPtr--]);
+	// Look for $fall-through$ and $CASES-OMITTED$ tags in leading comment for case statement
+	if (hasLeadingTagComment(FALL_THROUGH_TAG, defaultStatement.sourceStart)) {
+		defaultStatement.bits |= ASTNode.DocumentedFallthrough;
+	}
+	if (hasLeadingTagComment(CASES_OMITTED_TAG, defaultStatement.sourceStart)) {
+		defaultStatement.bits |= ASTNode.DocumentedCasesOmitted;
+	}
+	pushOnAstStack(defaultStatement);
+}
+protected void consumeDefaultModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(
+		this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
+	resetModifiers();
+	pushOnExpressionStackLengthStack(0); // no annotation
+}
+protected void consumeDiet() {
+	// Diet ::= $empty
+	checkComment();
+	pushOnIntStack(this.modifiersSourceStart); // push the start position of a javadoc comment if there is one
+	resetModifiers();
+	jumpOverMethodBody();
+}
+protected void consumeDims() {
+	// Dims ::= DimsLoop
+	pushOnIntStack(this.dimensions);
+	this.dimensions = 0;
+}
+protected void consumeDimWithOrWithOutExpr() {
+	// DimWithOrWithOutExpr ::= TypeAnnotationsopt '[' ']'
+	// DimWithOrWithOutExpr ::= TypeAnnotationsopt '[' Expression ']'
+	pushOnExpressionStack(null);
+
+	if(this.currentElement != null && this.currentToken == TokenNameLBRACE) {
+		this.ignoreNextOpeningBrace = true;
+		this.currentElement.bracketBalance++;
+	}
+}
+protected void consumeDimWithOrWithOutExprs() {
+	// DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
+	concatExpressionLists();
+}
+protected void consumeUnionType() {
+	// UnionType ::= UnionType '|' Type
+	pushOnAstStack(getTypeReference(this.intStack[this.intPtr--]));
+	optimizedConcatNodeLists();
+}
+protected void consumeUnionTypeAsClassType() {
+	// UnionType ::= Type
+	pushOnAstStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeEmptyAnnotationTypeMemberDeclarationsopt() {
+	// AnnotationTypeMemberDeclarationsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyArgumentListopt() {
+	// ArgumentListopt ::= $empty
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeEmptyArguments() {
+	// Argumentsopt ::= $empty
+	final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
+	pushOnIntStack(fieldDeclaration.sourceEnd);
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeEmptyArrayInitializer() {
+	// ArrayInitializer ::= '{' ,opt '}'
+	arrayInitializer(0);
+}
+protected void consumeEmptyArrayInitializeropt() {
+	// ArrayInitializeropt ::= $empty
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeEmptyBlockStatementsopt() {
+	// BlockStatementsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyCatchesopt() {
+	// Catchesopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyClassBodyDeclarationsopt() {
+	// ClassBodyDeclarationsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyDimsopt() {
+	// Dimsopt ::= $empty
+	pushOnIntStack(0);
+}
+protected void consumeEmptyEnumDeclarations() {
+	// EnumBodyDeclarationsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyExpression() {
+	// Expressionopt ::= $empty
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeEmptyForInitopt() {
+	// ForInitopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyForUpdateopt() {
+	// ForUpdateopt ::= $empty
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeEmptyInterfaceMemberDeclarationsopt() {
+	// InterfaceMemberDeclarationsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyInternalCompilationUnit() {
+	// InternalCompilationUnit ::= $empty
+	// nothing to do by default
+	if (this.compilationUnit.isPackageInfo()) {
+		this.compilationUnit.types = new TypeDeclaration[1];
+		this.compilationUnit.createPackageInfoType();
+	}
+}
+protected void consumeEmptyMemberValueArrayInitializer() {
+	// MemberValueArrayInitializer ::= '{' ',' '}'
+	// MemberValueArrayInitializer ::= '{' '}'
+	arrayInitializer(0);
+}
+protected void consumeEmptyMemberValuePairsopt() {
+	// MemberValuePairsopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyMethodHeaderDefaultValue() {
+	// DefaultValueopt ::= $empty
+	AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
+	if(method.isAnnotationMethod()) { //'method' can be a MethodDeclaration when recovery is started
+		pushOnExpressionStackLengthStack(0);
+	}
+	this.recordStringLiterals = true;
+}
+protected void consumeEmptyStatement() {
+	// EmptyStatement ::= ';'
+	char[] source = this.scanner.source;
+	if (source[this.endStatementPosition] == ';') {
+		pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition));
+	} else {
+		if(source.length > 5) {
+			int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
+			int pos = this.endStatementPosition - 4;
+			while (source[pos] == 'u') {
+				pos--;
+			}
+			if (source[pos] == '\\' &&
+					!((c1 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 3])) > 15
+						|| c1 < 0
+						|| (c2 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 2])) > 15
+						|| c2 < 0
+						|| (c3 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition - 1])) > 15
+						|| c3 < 0
+						|| (c4 = ScannerHelper.getHexadecimalValue(source[this.endStatementPosition])) > 15
+						|| c4 < 0) &&
+					((char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4)) == ';'){
+				// we have a Unicode for the ';' (/u003B)
+				pushOnAstStack(new EmptyStatement(pos, this.endStatementPosition));
+				return;
+			}
+		}
+		pushOnAstStack(new EmptyStatement(this.endPosition + 1, this.endStatementPosition));
+	}
+}
+protected void consumeEmptySwitchBlock() {
+	// SwitchBlock ::= '{' '}'
+	pushOnAstLengthStack(0);
+}
+protected void consumeEmptyTypeDeclaration() {
+	// ClassMemberDeclaration ::= ';'
+	// InterfaceMemberDeclaration ::= ';'
+	// TypeDeclaration ::= ';'
+	pushOnAstLengthStack(0);
+	if(!this.statementRecoveryActivated) problemReporter().superfluousSemicolon(this.endPosition+1, this.endStatementPosition);
+	flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeEnhancedForStatement() {
+	// EnhancedForStatement ::= EnhancedForStatementHeader Statement
+	// EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf
+
+	//statements
+	this.astLengthPtr--;
+	Statement statement = (Statement) this.astStack[this.astPtr--];
+
+	// foreach statement is on the ast stack
+	ForeachStatement foreachStatement = (ForeachStatement) this.astStack[this.astPtr];
+	foreachStatement.action = statement;
+	// remember useful empty statement
+	if (statement instanceof EmptyStatement) statement.bits |= ASTNode.IsUsefulEmptyStatement;
+
+	foreachStatement.sourceEnd = this.endStatementPosition;
+}
+protected void consumeEnhancedForStatementHeader(){
+	// EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
+	final ForeachStatement statement = (ForeachStatement) this.astStack[this.astPtr];
+	//updates are on the expression stack
+	this.expressionLengthPtr--;
+	final Expression collection = this.expressionStack[this.expressionPtr--];
+	statement.collection = collection;
+	// https://bugs.eclipse.org/393719 - [compiler] inconsistent warnings on iteration variables
+	// let declaration(Source)End include the collection to achieve that @SuppressWarnings affects this part, too:
+	statement.elementVariable.declarationSourceEnd = collection.sourceEnd;
+	statement.elementVariable.declarationEnd = collection.sourceEnd;
+	statement.sourceEnd = this.rParenPos;
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfForeachStatements(statement.elementVariable, collection);
+	}
+}
+protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
+	TypeReference type;
+
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePosition = this.identifierPositionStack[this.identifierPtr];
+
+	LocalDeclaration localDeclaration = createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
+	localDeclaration.declarationSourceEnd = localDeclaration.declarationEnd;
+	localDeclaration.bits |= ASTNode.IsForeachElementVariable;
+
+	int extraDims = this.intStack[this.intPtr--];
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+	// remove fake modifiers/modifiers start
+	int declarationSourceStart = 0;
+	int modifiersValue  = 0;
+	if (hasModifiers) {
+		declarationSourceStart = this.intStack[this.intPtr--];
+		modifiersValue = this.intStack[this.intPtr--];
+	} else {
+		this.intPtr-=2;
+	}
+
+	type = getTypeReference(this.intStack[this.intPtr--] + extraDims); // type dimension
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--])!= 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			localDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+		localDeclaration.bits |= ASTNode.HasTypeAnnotations;
+	}
+	if (hasModifiers) {
+		localDeclaration.declarationSourceStart = declarationSourceStart;
+		localDeclaration.modifiers = modifiersValue;
+	} else {
+		localDeclaration.declarationSourceStart = type.sourceStart;
+	}
+	localDeclaration.type = type;
+	localDeclaration.bits |= (type.bits & ASTNode.HasTypeAnnotations);
+
+	ForeachStatement iteratorForStatement =
+		new ForeachStatement(
+			localDeclaration,
+			this.intStack[this.intPtr--]);
+	pushOnAstStack(iteratorForStatement);
+
+	iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
+}
+protected void consumeEnterAnonymousClassBody(boolean qualified) {
+	this.shouldDeferRecovery = false;
+	// EnterAnonymousClassBody ::= $empty
+	TypeReference typeReference = getTypeReference(0);
+
+	TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
+	anonymousType.name = CharOperation.NO_CHAR;
+	anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
+	QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType);
+	markEnclosingMemberWithLocalType();
+	pushOnAstStack(anonymousType);
+
+	alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
+	int argumentLength;
+	if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= argumentLength;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			alloc.arguments = new Expression[argumentLength],
+			0,
+			argumentLength);
+	}
+	
+	if (qualified) {
+		this.expressionLengthPtr--;
+		alloc.enclosingInstance = this.expressionStack[this.expressionPtr--];
+	}
+	
+	alloc.type = typeReference;
+
+	anonymousType.sourceEnd = alloc.sourceEnd;
+	//position at the type while it impacts the anonymous declaration
+	anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
+	alloc.sourceStart = this.intStack[this.intPtr--];
+	pushOnExpressionStack(alloc);
+
+	anonymousType.bodyStart = this.scanner.currentPosition;
+	this.listLength = 0; // will be updated when reading super-interfaces
+
+	// flush the comments related to the anonymous
+	this.scanner.commentPtr = -1;
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = anonymousType.bodyStart;
+		this.currentElement = this.currentElement.add(anonymousType, 0);
+		if (!(this.currentElement instanceof RecoveredAnnotation)) {
+			this.currentToken = 0; // opening brace already taken into account
+		} else {
+			this.ignoreNextOpeningBrace = true;
+			this.currentElement.bracketBalance++;
+		}
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeEnterCompilationUnit() {
+	// EnterCompilationUnit ::= $empty
+	// do nothing by default
+}
+protected void consumeEnterMemberValue() {
+	// EnterMemberValue ::= $empty
+	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+		RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation)this.currentElement;
+		recoveredAnnotation.hasPendingMemberValueName = true;
+	}
+}
+protected void consumeEnterMemberValueArrayInitializer() {
+	// EnterMemberValueArrayInitializer ::= $empty
+	if(this.currentElement != null) {
+		this.ignoreNextOpeningBrace = true;
+		this.currentElement.bracketBalance++;
+	}
+}
+protected void consumeEnterVariable() {
+	// EnterVariable ::= $empty
+	// do nothing by default
+
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePosition = this.identifierPositionStack[this.identifierPtr];
+	int extendedDimension = this.intStack[this.intPtr--];
+	// pop any annotations on extended dimensions now, so they don't pollute the base dimensions.
+	Annotation [][] annotationsOnExtendedDimensions = extendedDimension == 0 ? null : getAnnotationsOnDimensions(extendedDimension);
+	AbstractVariableDeclaration declaration;
+	// create the ast node
+	boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
+	if (isLocalDeclaration) {
+		// create the local variable declarations
+		declaration =
+			createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
+	} else {
+		// create the field declaration
+		declaration =
+			createFieldDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
+	}
+
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+	TypeReference type;
+	int variableIndex = this.variablesCounter[this.nestedType];
+	int typeDim = 0;
+	if (variableIndex == 0) {
+		// first variable of the declaration (FieldDeclaration or LocalDeclaration)
+		if (isLocalDeclaration) {
+			declaration.declarationSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiers = this.intStack[this.intPtr--];
+			// consume annotations
+			int length;
+			if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+				System.arraycopy(
+					this.expressionStack,
+					(this.expressionPtr -= length) + 1,
+					declaration.annotations = new Annotation[length],
+					0,
+					length);
+				declaration.bits |= ASTNode.HasTypeAnnotations;
+			}
+			type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
+			if (declaration.declarationSourceStart == -1) {
+				// this is true if there is no modifiers for the local variable declaration
+				declaration.declarationSourceStart = type.sourceStart;
+			}
+			pushOnAstStack(type);
+		} else {
+			type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
+			pushOnAstStack(type);
+			declaration.declarationSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiers = this.intStack[this.intPtr--];
+			// consume annotations
+			int length;
+			if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+				System.arraycopy(
+					this.expressionStack,
+					(this.expressionPtr -= length) + 1,
+					declaration.annotations = new Annotation[length],
+					0,
+					length);
+				declaration.bits |= ASTNode.HasTypeAnnotations;
+			}
+			// Store javadoc only on first declaration as it is the same for all ones
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) declaration;
+			fieldDeclaration.javadoc = this.javadoc;
+		}
+		this.javadoc = null;
+	} else {
+		type = (TypeReference) this.astStack[this.astPtr - variableIndex];
+		typeDim = type.dimensions();
+		AbstractVariableDeclaration previousVariable =
+			(AbstractVariableDeclaration) this.astStack[this.astPtr];
+		declaration.declarationSourceStart = previousVariable.declarationSourceStart;
+		declaration.modifiers = previousVariable.modifiers;
+		final Annotation[] annotations = previousVariable.annotations;
+		if (annotations != null) {
+			final int annotationsLength = annotations.length;
+			System.arraycopy(annotations, 0, declaration.annotations = new Annotation[annotationsLength], 0, annotationsLength);
+			declaration.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+
+	if (extendedDimension == 0) {
+		declaration.type = type;
+		declaration.bits |= (type.bits & ASTNode.HasTypeAnnotations);
+	} else {
+		int dimension = typeDim + extendedDimension;
+		Annotation [][] annotationsOnAllDimensions = null;
+		Annotation[][] annotationsOnDimensions = type.getAnnotationsOnDimensions();
+		if (annotationsOnDimensions != null || annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(typeDim, annotationsOnDimensions, extendedDimension, annotationsOnExtendedDimensions); 
+			declaration.bits |= (type.bits & ASTNode.HasTypeAnnotations);
+		}
+		declaration.type = copyDims(type, dimension, annotationsOnAllDimensions);
+	}
+	this.variablesCounter[this.nestedType]++;
+	pushOnAstStack(declaration);
+	// recovery
+	if (this.currentElement != null) {
+		if (!(this.currentElement instanceof RecoveredType)
+			&& (this.currentToken == TokenNameDOT
+				//|| declaration.modifiers != 0
+				|| (Util.getLineNumber(declaration.type.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						!= Util.getLineNumber((int) (namePosition >>> 32), this.scanner.lineEnds, 0, this.scanner.linePtr)))){
+			this.lastCheckPoint = (int) (namePosition >>> 32);
+			this.restartRecovery = true;
+			return;
+		}
+		if (isLocalDeclaration){
+			LocalDeclaration localDecl = (LocalDeclaration) this.astStack[this.astPtr];
+			this.lastCheckPoint = localDecl.sourceEnd + 1;
+			this.currentElement = this.currentElement.add(localDecl, 0);
+		} else {
+			FieldDeclaration fieldDecl = (FieldDeclaration) this.astStack[this.astPtr];
+			this.lastCheckPoint = fieldDecl.sourceEnd + 1;
+			this.currentElement = this.currentElement.add(fieldDecl, 0);
+		}
+		this.lastIgnoredToken = -1;
+	}
+}
+protected Annotation[][] getMergedAnnotationsOnDimensions(int dims, Annotation[][] annotationsOnDimensions,
+		int extendedDims, Annotation[][] annotationsOnExtendedDimensions) {
+
+	if (annotationsOnDimensions == null && annotationsOnExtendedDimensions == null)
+		return null;
+
+	Annotation [][] mergedAnnotations = new Annotation[dims + extendedDims][];
+	
+	if (annotationsOnDimensions != null) {
+		for (int i = 0; i < dims; i++) {
+			mergedAnnotations[i] = annotationsOnDimensions[i];
+		} 
+	}
+	if (annotationsOnExtendedDimensions != null) {
+		for (int i = dims, j = 0; i < dims + extendedDims; i++, j++) {
+			mergedAnnotations[i] = annotationsOnExtendedDimensions[j];
+		}
+	}
+
+	return mergedAnnotations;
+}
+protected void consumeEnumBodyNoConstants() {
+	// nothing to do
+	// The 0 on the astLengthStack has been pushed by EnumBodyDeclarationsopt
+}
+protected void consumeEnumBodyWithConstants() {
+	// merge the constants values with the class body
+	concatNodeLists();
+}
+protected void consumeEnumConstantHeader() {
+   FieldDeclaration enumConstant = (FieldDeclaration) this.astStack[this.astPtr];
+   boolean foundOpeningBrace = this.currentToken == TokenNameLBRACE;
+   if (foundOpeningBrace){
+      // qualified allocation expression
+      TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult);
+      anonymousType.name = CharOperation.NO_CHAR;
+      anonymousType.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
+      final int start = this.scanner.startPosition;
+      anonymousType.declarationSourceStart = start;
+      anonymousType.sourceStart = start;
+      anonymousType.sourceEnd = start; // closing parenthesis
+      anonymousType.modifiers = 0;
+      anonymousType.bodyStart = this.scanner.currentPosition;
+      markEnclosingMemberWithLocalType();
+      consumeNestedType();
+      this.variablesCounter[this.nestedType]++;
+      pushOnAstStack(anonymousType);
+      QualifiedAllocationExpression allocationExpression = new QualifiedAllocationExpression(anonymousType);
+      allocationExpression.enumConstant = enumConstant;
+
+      // fill arguments if needed
+      int length;
+      if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+         this.expressionPtr -= length;
+         System.arraycopy(
+               this.expressionStack,
+               this.expressionPtr + 1,
+               allocationExpression.arguments = new Expression[length],
+               0,
+               length);
+      }
+      enumConstant.initialization = allocationExpression;
+   } else {
+      AllocationExpression allocationExpression = new AllocationExpression();
+      allocationExpression.enumConstant = enumConstant;
+      // fill arguments if needed
+      int length;
+      if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+         this.expressionPtr -= length;
+         System.arraycopy(
+               this.expressionStack,
+               this.expressionPtr + 1,
+               allocationExpression.arguments = new Expression[length],
+               0,
+               length);
+      }
+      enumConstant.initialization = allocationExpression;
+   }
+   // initialize the starting position of the allocation expression
+   enumConstant.initialization.sourceStart = enumConstant.declarationSourceStart;
+
+   // recovery
+   if (this.currentElement != null) {
+	  if(foundOpeningBrace) {
+	  	TypeDeclaration anonymousType = (TypeDeclaration) this.astStack[this.astPtr];
+	  	this.currentElement = this.currentElement.add(anonymousType, 0);
+      	this.lastCheckPoint = anonymousType.bodyStart;
+        this.lastIgnoredToken = -1;
+        this.currentToken = 0; // opening brace already taken into account
+	  } else {
+	  	  if(this.currentToken == TokenNameSEMICOLON) {
+		  	RecoveredType currentType = currentRecoveryType();
+			if(currentType != null) {
+				currentType.insideEnumConstantPart = false;
+			}
+		  }
+		  this.lastCheckPoint = this.scanner.startPosition; // force to restart at this exact position
+	      this.lastIgnoredToken = -1;
+	      this.restartRecovery = true;
+	  }
+   }
+}
+protected void consumeEnumConstantHeaderName() {
+	if (this.currentElement != null) {
+		if (!(this.currentElement instanceof RecoveredType
+					|| (this.currentElement instanceof RecoveredField && ((RecoveredField)this.currentElement).fieldDeclaration.type == null))
+				|| (this.lastIgnoredToken == TokenNameDOT)) {
+			this.lastCheckPoint = this.scanner.startPosition;
+			this.restartRecovery = true;
+			return;
+		}
+	}
+   long namePosition = this.identifierPositionStack[this.identifierPtr];
+   char[] constantName = this.identifierStack[this.identifierPtr];
+   final int sourceEnd = (int) namePosition;
+   FieldDeclaration enumConstant = createFieldDeclaration(constantName, (int) (namePosition >>> 32), sourceEnd);
+   this.identifierPtr--;
+   this.identifierLengthPtr--;
+   enumConstant.modifiersSourceStart = this.intStack[this.intPtr--];
+   enumConstant.modifiers = this.intStack[this.intPtr--];
+   enumConstant.declarationSourceStart = enumConstant.modifiersSourceStart;
+
+	// consume annotations
+   int length;
+   if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+      System.arraycopy(
+         this.expressionStack,
+         (this.expressionPtr -= length) + 1,
+         enumConstant.annotations = new Annotation[length],
+         0,
+         length);
+		enumConstant.bits |= ASTNode.HasTypeAnnotations;
+   }
+   pushOnAstStack(enumConstant);
+	if (this.currentElement != null){
+		this.lastCheckPoint = enumConstant.sourceEnd + 1;
+		this.currentElement = this.currentElement.add(enumConstant, 0);
+	}
+	// javadoc
+	enumConstant.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeEnumConstantNoClassBody() {
+	// set declarationEnd and declarationSourceEnd
+	int endOfEnumConstant = this.intStack[this.intPtr--];
+	final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
+	fieldDeclaration.declarationEnd = endOfEnumConstant;
+	fieldDeclaration.declarationSourceEnd = endOfEnumConstant;
+	// initialize the starting position of the allocation expression
+	ASTNode initialization = fieldDeclaration.initialization;
+	if (initialization != null) {
+		initialization.sourceEnd = endOfEnumConstant;
+	}
+}
+protected void consumeEnumConstants() {
+	concatNodeLists();
+}
+protected void consumeEnumConstantWithClassBody() {
+	dispatchDeclarationInto(this.astLengthStack[this.astLengthPtr--]);
+	TypeDeclaration anonymousType = (TypeDeclaration) this.astStack[this.astPtr--]; // pop type
+	this.astLengthPtr--;
+	anonymousType.bodyEnd = this.endPosition;
+	anonymousType.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	final FieldDeclaration fieldDeclaration = ((FieldDeclaration) this.astStack[this.astPtr]);
+	fieldDeclaration.declarationEnd = this.endStatementPosition;
+	int declarationSourceEnd = anonymousType.declarationSourceEnd;
+	fieldDeclaration.declarationSourceEnd = declarationSourceEnd;
+	this.intPtr --; // remove end position of the arguments
+	this.variablesCounter[this.nestedType] = 0;
+	this.nestedType--;
+	ASTNode initialization = fieldDeclaration.initialization;
+	if (initialization != null) {
+		initialization.sourceEnd = declarationSourceEnd;
+	}
+}
+protected void consumeEnumDeclaration() {
+	// EnumDeclaration ::= EnumHeader ClassHeaderImplementsopt EnumBody
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		//there are length declarations
+		//dispatch according to the type of the declarations
+		dispatchDeclarationIntoEnumDeclaration(length);
+	}
+
+	TypeDeclaration enumDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
+
+	//convert constructor that do not have the type's name into methods
+	boolean hasConstructor = enumDeclaration.checkConstructors(this);
+
+	//add the default constructor when needed
+	if (!hasConstructor) {
+		boolean insideFieldInitializer = false;
+		if (this.diet) {
+			for (int i = this.nestedType; i > 0; i--){
+				if (this.variablesCounter[i] > 0) {
+					insideFieldInitializer = true;
+					break;
+				}
+			}
+		}
+		enumDeclaration.createDefaultConstructor(!this.diet || insideFieldInitializer, true);
+	}
+
+	//always add <clinit> (will be remove at code gen time if empty)
+	if (this.scanner.containsAssertKeyword) {
+		enumDeclaration.bits |= ASTNode.ContainsAssertion;
+	}
+	enumDeclaration.addClinit();
+	enumDeclaration.bodyEnd = this.endStatementPosition;
+	if (length == 0 && !containsComment(enumDeclaration.bodyStart, enumDeclaration.bodyEnd)) {
+		enumDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+
+	enumDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeEnumDeclarations() {
+	// Do nothing by default
+}
+protected void consumeEnumHeader() {
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if (this.currentToken == TokenNameLBRACE) {
+		typeDecl.bodyStart = this.scanner.currentPosition;
+	}
+
+	if (this.currentElement != null) {
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+
+	// flush the comments related to the enum header
+	this.scanner.commentPtr = -1;
+}
+protected void consumeEnumHeaderName() {
+	// EnumHeaderName ::= Modifiersopt 'enum' Identifier
+	TypeDeclaration enumDeclaration = new TypeDeclaration(this.compilationUnit.compilationResult);
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			enumDeclaration.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+//		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	enumDeclaration.sourceEnd = (int) pos;
+	enumDeclaration.sourceStart = (int) (pos >>> 32);
+	enumDeclaration.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	enumDeclaration.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--; // remove the end position of the class token
+
+	enumDeclaration.modifiersSourceStart = this.intStack[this.intPtr--];
+	enumDeclaration.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccEnum;
+	if (enumDeclaration.modifiersSourceStart >= 0) {
+		enumDeclaration.declarationSourceStart = enumDeclaration.modifiersSourceStart;
+	}
+
+	// Store secondary info
+	if ((enumDeclaration.bits & ASTNode.IsMemberType) == 0 && (enumDeclaration.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(enumDeclaration.name, this.compilationUnit.getMainTypeName())) {
+			enumDeclaration.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			enumDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+	}
+//	if (this.currentToken == TokenNameLBRACE) {
+//		enumDeclaration.bodyStart = this.scanner.currentPosition;
+//	}
+	enumDeclaration.bodyStart = enumDeclaration.sourceEnd + 1;
+	pushOnAstStack(enumDeclaration);
+
+	this.listLength = 0; // will be updated when reading super-interfaces
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		//TODO this code will be never run while 'enum' is an identifier in 1.3 scanner
+		problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = enumDeclaration.bodyStart;
+		this.currentElement = this.currentElement.add(enumDeclaration, 0);
+		this.lastIgnoredToken = -1;
+	}
+	// javadoc
+	enumDeclaration.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeEnumHeaderNameWithTypeParameters() {
+	// EnumHeaderNameWithTypeParameters ::= Modifiersopt 'enum' Identifier TypeParameters
+	TypeDeclaration enumDeclaration = new TypeDeclaration(this.compilationUnit.compilationResult);
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, enumDeclaration.typeParameters = new TypeParameter[length], 0, length);
+
+	problemReporter().invalidUsageOfTypeParametersForEnumDeclaration(enumDeclaration);
+
+	enumDeclaration.bodyStart = enumDeclaration.typeParameters[length-1].declarationSourceEnd + 1;
+
+//	enumDeclaration.typeParameters = null;
+
+	this.listTypeParameterLength = 0;
+
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			enumDeclaration.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+//		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	enumDeclaration.sourceEnd = (int) pos;
+	enumDeclaration.sourceStart = (int) (pos >>> 32);
+	enumDeclaration.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	enumDeclaration.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--; // remove the end position of the class token
+
+	enumDeclaration.modifiersSourceStart = this.intStack[this.intPtr--];
+	enumDeclaration.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccEnum;
+	if (enumDeclaration.modifiersSourceStart >= 0) {
+		enumDeclaration.declarationSourceStart = enumDeclaration.modifiersSourceStart;
+	}
+
+	// Store secondary info
+	if ((enumDeclaration.bits & ASTNode.IsMemberType) == 0 && (enumDeclaration.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(enumDeclaration.name, this.compilationUnit.getMainTypeName())) {
+			enumDeclaration.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			enumDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+	}
+//	if (this.currentToken == TokenNameLBRACE) {
+//		enumDeclaration.bodyStart = this.scanner.currentPosition;
+//	}
+	enumDeclaration.bodyStart = enumDeclaration.sourceEnd + 1;
+	pushOnAstStack(enumDeclaration);
+
+	this.listLength = 0; // will be updated when reading super-interfaces
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		//TODO this code will be never run while 'enum' is an identifier in 1.3 scanner
+		problemReporter().invalidUsageOfEnumDeclarations(enumDeclaration);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = enumDeclaration.bodyStart;
+		this.currentElement = this.currentElement.add(enumDeclaration, 0);
+		this.lastIgnoredToken = -1;
+	}
+	// javadoc
+	enumDeclaration.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeEqualityExpression(int op) {
+	// EqualityExpression ::= EqualityExpression '==' RelationalExpression
+	// EqualityExpression ::= EqualityExpression '!=' RelationalExpression
+
+	//optimize the push/pop
+
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] =
+		new EqualExpression(
+			this.expressionStack[this.expressionPtr],
+			this.expressionStack[this.expressionPtr + 1],
+			op);
+}
+/*
+ * @param op
+ */
+protected void consumeEqualityExpressionWithName(int op) {
+	// EqualityExpression ::= Name '==' RelationalExpression
+	// EqualityExpression ::= Name '!=' RelationalExpression
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+	this.expressionStack[this.expressionPtr] =
+		new EqualExpression(
+			this.expressionStack[this.expressionPtr + 1],
+			this.expressionStack[this.expressionPtr],
+			op);
+}
+protected void consumeExitMemberValue() {
+	// ExitMemberValue ::= $empty
+	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+		RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation)this.currentElement;
+		recoveredAnnotation.hasPendingMemberValueName = false;
+		recoveredAnnotation.memberValuPairEqualEnd = -1;
+	}
+}
+protected void consumeExitTryBlock() {
+	//ExitTryBlock ::= $empty
+	if(this.currentElement != null) {
+		this.restartRecovery = true;
+	}
+}
+protected void consumeExitVariableWithInitialization() {
+	// ExitVariableWithInitialization ::= $empty
+	// do nothing by default
+	this.expressionLengthPtr--;
+	AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
+	variableDecl.initialization = this.expressionStack[this.expressionPtr--];
+	// we need to update the declarationSourceEnd of the local variable declaration to the
+	// source end position of the initialization expression
+	variableDecl.declarationSourceEnd = variableDecl.initialization.sourceEnd;
+	variableDecl.declarationEnd = variableDecl.initialization.sourceEnd;
+
+	recoveryExitFromVariable();
+}
+protected void consumeExitVariableWithoutInitialization() {
+	// ExitVariableWithoutInitialization ::= $empty
+	// do nothing by default
+
+	AbstractVariableDeclaration variableDecl = (AbstractVariableDeclaration) this.astStack[this.astPtr];
+	variableDecl.declarationSourceEnd = variableDecl.declarationEnd;
+	if(this.currentElement != null && this.currentElement instanceof RecoveredField) {
+		if(this.endStatementPosition > variableDecl.sourceEnd) {
+			this.currentElement.updateSourceEndIfNecessary(this.endStatementPosition);
+		}
+	}
+	recoveryExitFromVariable();
+}
+protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
+
+	/* flag allows to distinguish 3 cases :
+	(0) :
+	ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
+	(1) :
+	ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
+	(2) :
+	ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
+	*/
+	int startPosition = this.intStack[this.intPtr--];
+	ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
+	}
+	switch (flag) {
+		case 0 :
+			ecc.sourceStart = startPosition;
+			break;
+		case 1 :
+			this.expressionLengthPtr--;
+			ecc.sourceStart = (ecc.qualification = this.expressionStack[this.expressionPtr--]).sourceStart;
+			break;
+		case 2 :
+			ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
+			break;
+	}
+	pushOnAstStack(ecc);
+	ecc.sourceEnd = this.endStatementPosition;
+}
+protected void consumeExplicitConstructorInvocationWithTypeArguments(int flag, int recFlag) {
+
+	/* flag allows to distinguish 3 cases :
+	(0) :
+	ExplicitConstructorInvocation ::= TypeArguments 'this' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= TypeArguments 'super' '(' ArgumentListopt ')' ';'
+	(1) :
+	ExplicitConstructorInvocation ::= Primary '.' TypeArguments 'super' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= Primary '.' TypeArguments 'this' '(' ArgumentListopt ')' ';'
+	(2) :
+	ExplicitConstructorInvocation ::= Name '.' TypeArguments 'super' '(' ArgumentListopt ')' ';'
+	ExplicitConstructorInvocation ::= Name '.' TypeArguments 'this' '(' ArgumentListopt ')' ';'
+	*/
+	int startPosition = this.intStack[this.intPtr--];
+	ExplicitConstructorCall ecc = new ExplicitConstructorCall(recFlag);
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(this.expressionStack, this.expressionPtr + 1, ecc.arguments = new Expression[length], 0, length);
+	}
+	length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, ecc.typeArguments = new TypeReference[length], 0, length);
+	ecc.typeArgumentsSourceStart = this.intStack[this.intPtr--];
+
+	switch (flag) {
+		case 0 :
+			ecc.sourceStart = startPosition;
+			break;
+		case 1 :
+			this.expressionLengthPtr--;
+			ecc.sourceStart = (ecc.qualification = this.expressionStack[this.expressionPtr--]).sourceStart;
+			break;
+		case 2 :
+			ecc.sourceStart = (ecc.qualification = getUnspecifiedReferenceOptimized()).sourceStart;
+			break;
+	}
+
+	pushOnAstStack(ecc);
+	ecc.sourceEnd = this.endStatementPosition;
+}
+protected void consumeExpressionStatement() {
+	// ExpressionStatement ::= StatementExpression ';'
+	this.expressionLengthPtr--;
+	Expression expression = this.expressionStack[this.expressionPtr--];
+	expression.statementEnd = this.endStatementPosition;
+	expression.bits |= ASTNode.InsideExpressionStatement;
+	pushOnAstStack(expression);
+}
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	// FieldAccess ::= Primary '.' 'Identifier'
+	// FieldAccess ::= 'super' '.' 'Identifier'
+
+	FieldReference fr =
+		new FieldReference(
+			this.identifierStack[this.identifierPtr],
+			this.identifierPositionStack[this.identifierPtr--]);
+	this.identifierLengthPtr--;
+	if (isSuperAccess) {
+		//considers the fieldReference beginning at the 'super' ....
+		fr.sourceStart = this.intStack[this.intPtr--];
+		fr.receiver = new SuperReference(fr.sourceStart, this.endPosition);
+		pushOnExpressionStack(fr);
+	} else {
+		//optimize push/pop
+		fr.receiver = this.expressionStack[this.expressionPtr];
+		//field reference begins at the receiver
+		fr.sourceStart = fr.receiver.sourceStart;
+		this.expressionStack[this.expressionPtr] = fr;
+	}
+}
+protected void consumeFieldDeclaration() {
+	// See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
+	// FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
+
+	/*
+	this.astStack :
+	this.expressionStack: Expression Expression ...... Expression
+	this.identifierStack : type  identifier identifier ...... identifier
+	this.intStack : typeDim      dim        dim               dim
+	 ==>
+	this.astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
+	this.expressionStack :
+	this.identifierStack :
+	this.intStack :
+
+	*/
+	int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
+
+	for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
+		FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
+		fieldDeclaration.declarationSourceEnd = this.endStatementPosition;
+		fieldDeclaration.declarationEnd = this.endStatementPosition;	// semi-colon included
+	}
+
+	updateSourceDeclarationParts(variableDeclaratorsCounter);
+	int endPos = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	if (endPos != this.endStatementPosition) {
+		for (int i = 0; i < variableDeclaratorsCounter; i++) {
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr - i];
+			fieldDeclaration.declarationSourceEnd = endPos;
+		}
+	}
+	// update the this.astStack, this.astPtr and this.astLengthStack
+	int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
+	System.arraycopy(
+		this.astStack,
+		startIndex,
+		this.astStack,
+		startIndex - 1,
+		variableDeclaratorsCounter);
+	this.astPtr--; // remove the type reference
+	this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
+
+	// recovery
+	if (this.currentElement != null) {
+		this.lastCheckPoint = endPos + 1;
+		if (this.currentElement.parent != null && this.currentElement instanceof RecoveredField){
+			if (!(this.currentElement instanceof RecoveredInitializer)) {
+				this.currentElement = this.currentElement.parent;
+			}
+		}
+		this.restartRecovery = true;
+	}
+	this.variablesCounter[this.nestedType] = 0;
+}
+protected void consumeForceNoDiet() {
+	// ForceNoDiet ::= $empty
+	this.dietInt++;
+}
+protected void consumeForInit() {
+	// ForInit ::= StatementExpressionList
+	pushOnAstLengthStack(-1);
+}
+protected void consumeFormalParameter(boolean isVarArgs) {
+	// FormalParameter ::= Modifiersopt Type VariableDeclaratorIdOrThis
+	// FormalParameter ::= Modifiersopt Type PushZeroTypeAnnotations '...' VariableDeclaratorIdOrThis
+	// FormalParameter ::= Modifiersopt Type @308... TypeAnnotations '...' VariableDeclaratorIdOrThis
+	/*
+	this.astStack :
+	this.identifierStack : type identifier
+	this.intStack : dim dim 1||0  // 1 => normal parameter, 0 => this parameter
+	 ==>
+	this.astStack : Argument
+	this.identifierStack :
+	this.intStack :
+	*/
+	NameReference qualifyingNameReference = null;
+    boolean isReceiver = this.intStack[this.intPtr--] == 0;  // flag pushed in consumeExplicitThisParameter -> 0, consumeVariableDeclaratorIdParameter -> 1
+    if (isReceiver) {
+    	qualifyingNameReference = (NameReference) this.expressionStack[this.expressionPtr--];
+    	this.expressionLengthPtr --;
+    }
+	this.identifierLengthPtr--;
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+	int extendedDimensions = this.intStack[this.intPtr--];
+	Annotation [][] annotationsOnExtendedDimensions = extendedDimensions == 0 ? null : getAnnotationsOnDimensions(extendedDimensions);
+	Annotation [] varArgsAnnotations = null;
+	int endOfEllipsis = 0;
+	int length;
+	if (isVarArgs) {
+		endOfEllipsis = this.intStack[this.intPtr--];
+		if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.typeAnnotationStack,
+				(this.typeAnnotationPtr -= length) + 1,
+				varArgsAnnotations = new Annotation[length],
+				0,
+				length);
+		} 
+	}
+	int firstDimensions = this.intStack[this.intPtr--];
+	TypeReference type = getTypeReference(firstDimensions);
+	final int typeDimensions = firstDimensions + extendedDimensions + (isVarArgs ? 1 : 0);
+
+	if (typeDimensions != firstDimensions) {
+		// jsr308 type annotations management
+		Annotation [][] annotationsOnFirstDimensions = firstDimensions == 0 ? null : type.getAnnotationsOnDimensions();
+		Annotation [][] annotationsOnAllDimensions = annotationsOnFirstDimensions;
+		if (annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions, annotationsOnFirstDimensions, extendedDimensions, annotationsOnExtendedDimensions);
+		}
+		if (varArgsAnnotations != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions + extendedDimensions, annotationsOnAllDimensions, 1, new Annotation[][]{varArgsAnnotations});
+		}
+		type = copyDims(type, typeDimensions, annotationsOnAllDimensions);
+		type.sourceEnd = type.isParameterizedTypeReference() ? this.endStatementPosition : this.endPosition;
+	}
+	if (isVarArgs) {
+		if (extendedDimensions == 0) {
+			type.sourceEnd = endOfEllipsis;
+		}
+		type.bits |= ASTNode.IsVarArgs; // set isVarArgs
+	}
+	int modifierPositions = this.intStack[this.intPtr--];
+	Argument arg;
+	if (isReceiver) {
+		arg = new Receiver(
+				identifierName, 
+				namePositions, 
+				type,
+				qualifyingNameReference,
+				this.intStack[this.intPtr--] & ~ClassFileConstants.AccDeprecated);
+	} else {
+		arg = new Argument(
+			identifierName,
+			namePositions,
+			type,
+			this.intStack[this.intPtr--] & ~ClassFileConstants.AccDeprecated); // modifiers
+	}
+	arg.declarationSourceStart = modifierPositions;
+	arg.bits |= (type.bits & ASTNode.HasTypeAnnotations);
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			arg.annotations = new Annotation[length],
+			0,
+			length);
+		arg.bits |= ASTNode.HasTypeAnnotations;
+		RecoveredType currentRecoveryType = this.currentRecoveryType();
+		if (currentRecoveryType != null)
+			currentRecoveryType.annotationsConsumed(arg.annotations);
+	}
+	pushOnAstStack(arg);
+
+	/* if incomplete method header, this.listLength counter will not have been reset,
+		indicating that some arguments are available on the stack */
+	this.listLength++;
+
+	if(isVarArgs) {
+		if (!this.statementRecoveryActivated &&
+				this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+				this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+				problemReporter().invalidUsageOfVarargs(arg);
+		} else if (!this.statementRecoveryActivated &&
+				extendedDimensions > 0) {
+			problemReporter().illegalExtendedDimensions(arg);
+		}
+	}
+}
+protected Annotation[][] getAnnotationsOnDimensions(int dimensionsCount) {
+	Annotation [][] dimensionsAnnotations = null;
+	if (dimensionsCount > 0) {
+		for (int i = 0; i < dimensionsCount; i++) {
+			Annotation [] annotations = null;
+			int length;
+			if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+				System.arraycopy(
+						this.typeAnnotationStack,
+						(this.typeAnnotationPtr -= length) + 1,
+						annotations = new Annotation[length],
+						0,
+						length);
+				if (dimensionsAnnotations == null) {
+					dimensionsAnnotations = new Annotation[dimensionsCount][];
+				}
+				dimensionsAnnotations[dimensionsCount - i - 1] = annotations;
+			}
+		}
+	}
+	return dimensionsAnnotations;
+}
+protected void consumeFormalParameterList() {
+	// FormalParameterList ::= FormalParameterList ',' FormalParameter
+	// TypeElidedFormalParameterList ::= TypeElidedFormalParameterList ',' TypeElidedFormalParameter
+	optimizedConcatNodeLists();
+}
+protected void consumeFormalParameterListopt() {
+	// FormalParameterListopt ::= $empty
+	pushOnAstLengthStack(0);
+}
+protected void consumeGenericType() {
+	// GenericType ::= ClassOrInterface TypeArguments
+	// nothing to do
+	// Will be consume by a getTypeReference call
+}
+protected void consumeGenericTypeArrayType() {
+	// nothing to do
+	// Will be consume by a getTypeReference call
+}
+protected void consumeGenericTypeNameArrayType() {
+	// nothing to do
+	// Will be consume by a getTypeReference call
+}
+protected void consumeGenericTypeWithDiamond() {
+	// GenericType ::= ClassOrInterface '<' '>'
+	// zero type arguments == <>
+	pushOnGenericsLengthStack(-1);
+	concatGenericsLists();
+	this.intPtr--;	// pop the null dimension pushed in by consumeReferenceType, as we have no type between <>, getTypeReference won't kick in 
+}
+protected void consumeImportDeclaration() {
+	// SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
+	ImportReference impt = (ImportReference) this.astStack[this.astPtr];
+	// flush annotations defined prior to import statements
+	impt.declarationEnd = this.endStatementPosition;
+	impt.declarationSourceEnd =
+		flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
+
+	// recovery
+	if (this.currentElement != null) {
+		this.lastCheckPoint = impt.declarationSourceEnd + 1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true;
+		// used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeImportDeclarations() {
+	// ImportDeclarations ::= ImportDeclarations ImportDeclaration
+	optimizedConcatNodeLists();
+}
+protected void consumeInsideCastExpression() {
+	// InsideCastExpression ::= $empty
+}
+protected void consumeInsideCastExpressionLL1() {
+	// InsideCastExpressionLL1 ::= $empty
+	pushOnGenericsLengthStack(0); // handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnExpressionStack(getTypeReference(0));
+}
+protected void consumeInsideCastExpressionLL1WithBounds() {
+	// InsideCastExpressionLL1WithBounds ::= $empty
+}
+protected void consumeInsideCastExpressionWithQualifiedGenerics() {
+	// InsideCastExpressionWithQualifiedGenerics ::= $empty
+}
+protected void consumeInstanceOfExpression() {
+	// RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType
+	//optimize the push/pop
+
+	//by construction, no base type may be used in getTypeReference
+	Expression exp;
+	this.expressionStack[this.expressionPtr] = exp =
+		new InstanceOfExpression(
+			this.expressionStack[this.expressionPtr],
+			getTypeReference(this.intStack[this.intPtr--]));
+	if (exp.sourceEnd == 0) {
+		//array on base type....
+		exp.sourceEnd = this.scanner.startPosition - 1;
+	}
+	//the scanner is on the next token already....
+}
+protected void consumeInstanceOfExpressionWithName() {
+	// RelationalExpression_NotName ::= Name instanceof ReferenceType
+	//optimize the push/pop
+
+	//by construction, no base type may be used in getTypeReference
+	TypeReference reference = getTypeReference(this.intStack[this.intPtr--]);
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	Expression exp;
+	this.expressionStack[this.expressionPtr] = exp =
+		new InstanceOfExpression(
+			this.expressionStack[this.expressionPtr],
+			reference);
+	if (exp.sourceEnd == 0) {
+		//array on base type....
+		exp.sourceEnd = this.scanner.startPosition - 1;
+	}
+	//the scanner is on the next token already....
+}
+protected void consumeInterfaceDeclaration() {
+	// see consumeClassDeclaration in case of changes: duplicated code
+	// InterfaceDeclaration ::= InterfaceHeader InterfaceBody
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		//there are length declarations
+		//dispatch.....according to the type of the declarations
+		dispatchDeclarationInto(length);
+	}
+
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+
+	//convert constructor that do not have the type's name into methods
+	typeDecl.checkConstructors(this);
+	
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=212713, 
+	// reject initializers that have been tolerated by the grammar.
+	FieldDeclaration [] fields = typeDecl.fields;
+	int fieldCount = fields == null ? 0 : fields.length;
+	for (int i = 0; i < fieldCount; i++) {
+		FieldDeclaration field = fields[i];
+		if (field instanceof Initializer) {
+			problemReporter().interfaceCannotHaveInitializers(typeDecl.name, field);
+		}
+	}
+
+	//always add <clinit> (will be remove at code gen time if empty)
+	if (this.scanner.containsAssertKeyword) {
+		typeDecl.bits |= ASTNode.ContainsAssertion;
+	}
+	typeDecl.addClinit();
+	typeDecl.bodyEnd = this.endStatementPosition;
+	if (length == 0 && !containsComment(typeDecl.bodyStart, typeDecl.bodyEnd)) {
+		typeDecl.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+	typeDecl.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeInterfaceHeader() {
+	// InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
+
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if (this.currentToken == TokenNameLBRACE){
+		typeDecl.bodyStart = this.scanner.currentPosition;
+	}
+	if (this.currentElement != null){
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	// flush the comments related to the interface header
+	this.scanner.commentPtr = -1;
+}
+protected void consumeInterfaceHeaderExtends() {
+	// InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
+	int length = this.astLengthStack[this.astLengthPtr--];
+	//super interfaces
+	this.astPtr -= length;
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	System.arraycopy(
+		this.astStack,
+		this.astPtr + 1,
+		typeDecl.superInterfaces = new TypeReference[length],
+		0,
+		length);
+	TypeReference[] superinterfaces = typeDecl.superInterfaces;
+	for (int i = 0, max = superinterfaces.length; i < max; i++) {
+		TypeReference typeReference = superinterfaces[i];
+		typeDecl.bits |= (typeReference.bits & ASTNode.HasTypeAnnotations);
+		typeReference.bits |= ASTNode.IsSuperType;
+	}
+	typeDecl.bodyStart = typeDecl.superInterfaces[length-1].sourceEnd + 1;
+	this.listLength = 0; // reset after having read super-interfaces
+	// recovery
+	if (this.currentElement != null) {
+		this.lastCheckPoint = typeDecl.bodyStart;
+	}
+}
+protected void consumeInterfaceHeaderName1() {
+	// InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
+	TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			typeDecl.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		typeDecl.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	typeDecl.sourceEnd = (int) pos;
+	typeDecl.sourceStart = (int) (pos >>> 32);
+	typeDecl.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push two int positions: the beginning of the class token and its end.
+	// we want to keep the beginning position but get rid of the end position
+	// it is only used for the ClassLiteralAccess positions.
+	typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--; // remove the end position of the class token
+	typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccInterface;
+	if (typeDecl.modifiersSourceStart >= 0) {
+		typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
+	}
+
+	// Store secondary info
+	if ((typeDecl.bits & ASTNode.IsMemberType) == 0 && (typeDecl.bits & ASTNode.IsLocalType) == 0) {
+		if (this.compilationUnit != null && !CharOperation.equals(typeDecl.name, this.compilationUnit.getMainTypeName())) {
+			typeDecl.bits |= ASTNode.IsSecondaryType;
+		}
+	}
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			typeDecl.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
+	pushOnAstStack(typeDecl);
+	this.listLength = 0; // will be updated when reading super-interfaces
+	// recovery
+	if (this.currentElement != null){ // is recovering
+		this.lastCheckPoint = typeDecl.bodyStart;
+		this.currentElement = this.currentElement.add(typeDecl, 0);
+		this.lastIgnoredToken = -1;
+	}
+	// javadoc
+	typeDecl.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeInterfaceMemberDeclarations() {
+	// InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
+	concatNodeLists();
+}
+protected void consumeInterfaceMemberDeclarationsopt() {
+	// InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
+	this.nestedType--;
+}
+protected void consumeInterfaceType() {
+	// InterfaceType ::= ClassOrInterfaceType
+	pushOnAstStack(getTypeReference(0));
+	/* if incomplete type header, this.listLength counter will not have been reset,
+		indicating that some interfaces are available on the stack */
+	this.listLength++;
+}
+protected void consumeInterfaceTypeList() {
+	// InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
+	optimizedConcatNodeLists();
+}
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+	if (this.compilationUnit.isPackageInfo()) {
+		this.compilationUnit.types = new TypeDeclaration[1];
+		this.compilationUnit.createPackageInfoType();
+	}
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		if (this.compilationUnit.isPackageInfo()) {
+			this.compilationUnit.types = new TypeDeclaration[length + 1];
+			this.astPtr -= length;
+			System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 1, length);
+			this.compilationUnit.createPackageInfoType();
+		} else {
+			this.compilationUnit.types = new TypeDeclaration[length];
+			this.astPtr -= length;
+			System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+		}
+	}
+}
+protected void consumeInvalidAnnotationTypeDeclaration() {
+	// BlockStatement ::= AnnotationTypeDeclaration
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
+protected void consumeInvalidConstructorDeclaration() {
+	// ConstructorDeclaration ::= ConstructorHeader ';'
+	// now we know that the top of stack is a constructorDeclaration
+	ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
+
+	cd.bodyEnd = this.endPosition; // position just before the trailing semi-colon
+	cd.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	// report the problem and continue the parsing - narrowing the problem onto the method
+
+	cd.modifiers |= ExtraCompilerModifiers.AccSemicolonBody; // remember semi-colon body
+}
+protected void consumeInvalidConstructorDeclaration(boolean hasBody) {
+	// InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
+	// InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
+
+	/*
+	this.astStack : modifiers arguments throws statements
+	this.identifierStack : name
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	*/
+	if (hasBody) {
+		// pop the position of the {  (body of the method) pushed in block decl
+		this.intPtr--;
+	}
+
+	//statements
+	if (hasBody) {
+		this.realBlockPtr--;
+	}
+
+	int length;
+	if (hasBody && ((length = this.astLengthStack[this.astLengthPtr--]) != 0)) {
+		this.astPtr -= length;
+	}
+	ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) this.astStack[this.astPtr];
+	constructorDeclaration.bodyEnd = this.endStatementPosition;
+	constructorDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	if (!hasBody) {
+		constructorDeclaration.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+	}
+}
+protected void consumeInvalidEnumDeclaration() {
+	// BlockStatement ::= EnumDeclaration
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
+protected void consumeInvalidInterfaceDeclaration() {
+	// BlockStatement ::= InvalidInterfaceDeclaration
+	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
+protected void consumeInterfaceMethodDeclaration(boolean hasSemicolonBody) {
+	// InterfaceMemberDeclaration ::= DefaultMethodHeader MethodBody
+	// InterfaceMemberDeclaration ::= MethodHeader MethodBody
+	// -- the next rule is illegal but allows to give a more canonical error message from inside consumeInterfaceMethodDeclaration(): 
+	// InterfaceMemberDeclaration ::= DefaultMethodHeader ';'
+
+
+	/*
+	this.astStack : modifiers arguments throws statements
+	this.identifierStack : type name
+	this.intStack : dim dim dim
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	this.intStack :
+	*/
+
+	if (!hasSemicolonBody) {
+		// pop the position of the {  (body of the method) pushed in block decl
+		this.intPtr--;
+		// retrieve end position of method declarator
+
+		//statements
+		this.realBlockPtr--;
+		int length;
+		if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+			this.astPtr -= length;
+		}
+	}
+
+	//watch for } that could be given as a unicode ! ( u007D is '}' )
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	md.bodyEnd = this.endPosition;
+	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	
+	boolean isDefault = (md.modifiers & ExtraCompilerModifiers.AccDefaultMethod) != 0;
+	boolean isStatic = (md.modifiers & ClassFileConstants.AccStatic) != 0;
+	boolean bodyAllowed = isDefault || isStatic;
+	if (this.parsingJava8Plus) {
+		if (bodyAllowed && hasSemicolonBody) {
+			md.modifiers |= ExtraCompilerModifiers.AccSemicolonBody; // avoid complaints regarding undocumented empty body
+		}
+	} else {
+		if (isDefault) problemReporter().defaultMethodsNotBelow18(md);
+		if (isStatic) problemReporter().staticInterfaceMethodsNotBelow18(md);
+	}
+	if (!bodyAllowed && !this.statementRecoveryActivated && !hasSemicolonBody) {
+		problemReporter().abstractMethodNeedingNoBody(md);
+	}
+}
+protected void consumeLabel() {
+	// Do nothing
+}
+protected void consumeLeftParen() {
+	// PushLPAREN ::= '('
+	pushOnIntStack(this.lParenPos);
+}
+protected void consumeLocalVariableDeclaration() {
+	// LocalVariableDeclaration ::= Modifiers Type VariableDeclarators ';'
+
+	/*
+	this.astStack :
+	this.expressionStack: Expression Expression ...... Expression
+	this.identifierStack : type  identifier identifier ...... identifier
+	this.intStack : typeDim      dim        dim               dim
+	 ==>
+	this.astStack : FieldDeclaration FieldDeclaration ...... FieldDeclaration
+	this.expressionStack :
+	this.identifierStack :
+	this.intStack :
+
+	*/
+	int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
+
+	// update the this.astStack, this.astPtr and this.astLengthStack
+	int startIndex = this.astPtr - this.variablesCounter[this.nestedType] + 1;
+	System.arraycopy(
+		this.astStack,
+		startIndex,
+		this.astStack,
+		startIndex - 1,
+		variableDeclaratorsCounter);
+	this.astPtr--; // remove the type reference
+	this.astLengthStack[--this.astLengthPtr] = variableDeclaratorsCounter;
+	this.variablesCounter[this.nestedType] = 0;
+}
+protected void consumeLocalVariableDeclarationStatement() {
+	// LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
+	// see blockReal in case of change: duplicated code
+	// increment the amount of declared variables for this block
+	this.realBlockStack[this.realBlockPtr]++;
+
+	// update source end to include the semi-colon
+	int variableDeclaratorsCounter = this.astLengthStack[this.astLengthPtr];
+	for (int i = variableDeclaratorsCounter - 1; i >= 0; i--) {
+		LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr - i];
+		localDeclaration.declarationSourceEnd = this.endStatementPosition;
+		localDeclaration.declarationEnd = this.endStatementPosition;	// semi-colon included
+	}
+
+}
+protected void consumeMarkerAnnotation(boolean isTypeAnnotation) {
+	// MarkerAnnotation ::= AnnotationName
+	// MarkerTypeAnnotation ::= TypeAnnotationName
+	MarkerAnnotation markerAnnotation = null;
+
+	int oldIndex = this.identifierPtr;
+
+	TypeReference typeReference = getAnnotationType();
+	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
+	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(markerAnnotation);
+	} else {
+		pushOnExpressionStack(markerAnnotation);
+	}
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfAnnotation(markerAnnotation);
+	}
+	this.recordStringLiterals = true;
+
+	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+		this.currentElement = ((RecoveredAnnotation)this.currentElement).addAnnotation(markerAnnotation, oldIndex);
+	}
+}
+protected void consumeMemberValueArrayInitializer() {
+	// MemberValueArrayInitializer ::= '{' MemberValues ',' '}'
+	// MemberValueArrayInitializer ::= '{' MemberValues '}'
+	arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
+}
+protected void consumeMemberValueAsName() {
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+}
+protected void consumeMemberValuePair() {
+	// MemberValuePair ::= SimpleName '=' MemberValue
+	char[] simpleName = this.identifierStack[this.identifierPtr];
+	long position = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	int end = (int) position;
+	int start = (int) (position >>> 32);
+	Expression value = this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr--;
+	MemberValuePair memberValuePair = new MemberValuePair(simpleName, start, end, value);
+	pushOnAstStack(memberValuePair);
+
+	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+		RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation) this.currentElement;
+
+		recoveredAnnotation.setKind(RecoveredAnnotation.NORMAL);
+	}
+}
+protected void consumeMemberValuePairs() {
+	// MemberValuePairs ::= MemberValuePairs ',' MemberValuePair
+	concatNodeLists();
+}
+protected void consumeMemberValues() {
+	// MemberValues ::= MemberValues ',' MemberValue
+	concatExpressionLists();
+}
+protected void consumeMethodBody() {
+	// MethodBody ::= NestedMethod '{' BlockStatementsopt '}'
+	this.nestedMethod[this.nestedType] --;
+}
+protected void consumeMethodDeclaration(boolean isNotAbstract) {
+	// MethodDeclaration ::= MethodHeader MethodBody
+	// AbstractMethodDeclaration ::= MethodHeader ';'
+
+	/*
+	this.astStack : modifiers arguments throws statements
+	this.identifierStack : type name
+	this.intStack : dim dim dim
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	this.intStack :
+	*/
+
+	int length;
+	if (isNotAbstract) {
+		// pop the position of the {  (body of the method) pushed in block decl
+		this.intPtr--;
+		this.intPtr--;
+	}
+
+	int explicitDeclarations = 0;
+	Statement[] statements = null;
+	if (isNotAbstract) {
+		//statements
+		explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+		if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+			if (this.options.ignoreMethodBodies) {
+				this.astPtr -= length;
+			} else {
+				System.arraycopy(
+					this.astStack,
+					(this.astPtr -= length) + 1,
+					statements = new Statement[length],
+					0,
+					length);
+			}
+		}
+	}
+
+	// now we know that we have a method declaration at the top of the ast stack
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	md.statements = statements;
+	md.explicitDeclarations = explicitDeclarations;
+
+	// cannot be done in consumeMethodHeader because we have no idea whether or not there
+	// is a body when we reduce the method header
+	if (!isNotAbstract) { //remember the fact that the method has a semicolon body
+		md.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+	} else if (!(this.diet && this.dietInt == 0) && statements == null && !containsComment(md.bodyStart, this.endPosition)) {
+		md.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+	// store the this.endPosition (position just before the '}') in case there is
+	// a trailing comment behind the end of the method
+	md.bodyEnd = this.endPosition;
+	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+}
+protected void consumeMethodHeader() {
+	// MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
+	// AnnotationMethodHeader ::= AnnotationMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt
+	// RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt
+	// RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims MethodHeaderThrowsClause
+
+	// retrieve end position of method declarator
+	AbstractMethodDeclaration method = (AbstractMethodDeclaration)this.astStack[this.astPtr];
+
+	if (this.currentToken == TokenNameLBRACE){
+		method.bodyStart = this.scanner.currentPosition;
+	}
+	// recovery
+	if (this.currentElement != null){
+//		if(method.isAnnotationMethod()) {
+//			method.modifiers |= AccSemicolonBody;
+//			method.declarationSourceEnd = this.scanner.currentPosition-1;
+//			method.bodyEnd = this.scanner.currentPosition-1;
+//			this.currentElement = this.currentElement.parent;
+//		} else
+		if (this.currentToken == TokenNameSEMICOLON /*&& !method.isAnnotationMethod()*/){
+			method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+			method.declarationSourceEnd = this.scanner.currentPosition-1;
+			method.bodyEnd = this.scanner.currentPosition-1;
+			if (this.currentElement.parseTree() == method && this.currentElement.parent != null) {
+				this.currentElement = this.currentElement.parent;
+			}
+		} else if(this.currentToken == TokenNameLBRACE) {
+			if (this.currentElement instanceof RecoveredMethod &&
+					((RecoveredMethod)this.currentElement).methodDeclaration != method) {
+				this.ignoreNextOpeningBrace = true;
+				this.currentElement.bracketBalance++;
+			}
+		}
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeMethodHeaderDefaultValue() {
+	// MethodHeaderDefaultValue ::= DefaultValue
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+
+
+	int length = this.expressionLengthStack[this.expressionLengthPtr--];
+	if (length == 1) {
+		this.intPtr--; // we get rid of the position of the default keyword
+		this.intPtr--; // we get rid of the position of the default keyword
+		if(md.isAnnotationMethod()) {
+			((AnnotationMethodDeclaration)md).defaultValue = this.expressionStack[this.expressionPtr];
+			md.modifiers |=  ClassFileConstants.AccAnnotationDefault;
+		}
+		this.expressionPtr--;
+		this.recordStringLiterals = true;
+	}
+
+	if(this.currentElement != null) {
+		if(md.isAnnotationMethod()) {
+			this.currentElement.updateSourceEndIfNecessary(((AnnotationMethodDeclaration)md).defaultValue.sourceEnd);
+		}
+	}
+}
+protected void consumeMethodHeaderExtendedDims() {
+	// MethodHeaderExtendedDims ::= Dimsopt
+	// now we update the returnType of the method
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	int extendedDims = this.intStack[this.intPtr--];
+	if(md.isAnnotationMethod()) {
+		((AnnotationMethodDeclaration)md).extendedDimensions = extendedDims;
+	}
+	if (extendedDims != 0) {
+		TypeReference returnType = md.returnType;
+		md.sourceEnd = this.endPosition;
+		int dims = returnType.dimensions() + extendedDims;
+		Annotation [][] annotationsOnDimensions = returnType.getAnnotationsOnDimensions();
+		Annotation [][] annotationsOnExtendedDimensions = getAnnotationsOnDimensions(extendedDims);
+		Annotation [][] annotationsOnAllDimensions = null;
+		if (annotationsOnDimensions != null || annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(returnType.dimensions(), annotationsOnDimensions, extendedDims, annotationsOnExtendedDimensions);
+		}
+		md.returnType = copyDims(returnType, dims, annotationsOnAllDimensions);
+		if (this.currentToken == TokenNameLBRACE){
+			md.bodyStart = this.endPosition + 1;
+		}
+		// recovery
+		if (this.currentElement != null){
+			this.lastCheckPoint = md.bodyStart;
+		}
+	}
+}
+protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
+	// MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+	// AnnotationMethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+	// RecoveryMethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+	MethodDeclaration md = null;
+	if(isAnnotationMethod) {
+		md = new AnnotationMethodDeclaration(this.compilationUnit.compilationResult);
+		this.recordStringLiterals = false;
+	} else {
+		md = new MethodDeclaration(this.compilationUnit.compilationResult);
+	}
+
+	//name
+	md.selector = this.identifierStack[this.identifierPtr];
+	long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	//type
+	md.returnType = getTypeReference(this.intStack[this.intPtr--]);
+	//modifiers
+	md.declarationSourceStart = this.intStack[this.intPtr--];
+	md.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			md.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	md.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at selector start
+	md.sourceStart = (int) (selectorSource >>> 32);
+	pushOnAstStack(md);
+	md.sourceEnd = this.lParenPos;
+	md.bodyStart = this.lParenPos+1;
+	this.listLength = 0; // initialize this.listLength before reading parameters/throws
+
+	// recovery
+	if (this.currentElement != null){
+		if (this.currentElement instanceof RecoveredType
+			//|| md.modifiers != 0
+			|| (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+			this.lastCheckPoint = md.bodyStart;
+			this.currentElement = this.currentElement.add(md, 0);
+			this.lastIgnoredToken = -1;
+		} else {
+			this.lastCheckPoint = md.sourceStart;
+			this.restartRecovery = true;
+		}
+	}
+}
+protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) {
+	// MethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	// AnnotationMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	// RecoveryMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	MethodDeclaration md = null;
+	if(isAnnotationMethod) {
+		md = new AnnotationMethodDeclaration(this.compilationUnit.compilationResult);
+		this.recordStringLiterals = false;
+	} else {
+		md = new MethodDeclaration(this.compilationUnit.compilationResult);
+	}
+
+	//name
+	md.selector = this.identifierStack[this.identifierPtr];
+	long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	//type
+	TypeReference returnType = getTypeReference(this.intStack[this.intPtr--]);
+	rejectIllegalLeadingTypeAnnotations(returnType);
+	md.returnType = returnType;
+	md.bits |= (returnType.bits & ASTNode.HasTypeAnnotations);
+
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, md.typeParameters = new TypeParameter[length], 0, length);
+
+	//modifiers
+	md.declarationSourceStart = this.intStack[this.intPtr--];
+	md.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			md.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	md.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at selector start
+	md.sourceStart = (int) (selectorSource >>> 32);
+	pushOnAstStack(md);
+	md.sourceEnd = this.lParenPos;
+	md.bodyStart = this.lParenPos+1;
+	this.listLength = 0; // initialize this.listLength before reading parameters/throws
+
+	// recovery
+	if (this.currentElement != null){
+		boolean isType;
+		if ((isType = this.currentElement instanceof RecoveredType)
+			//|| md.modifiers != 0
+			|| (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+			if(isType) {
+				((RecoveredType) this.currentElement).pendingTypeParameters = null;
+			}
+			this.lastCheckPoint = md.bodyStart;
+			this.currentElement = this.currentElement.add(md, 0);
+			this.lastIgnoredToken = -1;
+		} else {
+			this.lastCheckPoint = md.sourceStart;
+			this.restartRecovery = true;
+		}
+	}
+}
+protected void consumeMethodHeaderRightParen() {
+	// MethodHeaderParameters ::= FormalParameterListopt ')'
+	int length = this.astLengthStack[this.astLengthPtr--];
+	this.astPtr -= length;
+	AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
+	md.sourceEnd = 	this.rParenPos;
+	//arguments
+	if (length != 0) {
+		Argument arg = (Argument) this.astStack[this.astPtr + 1];
+		if (arg.isReceiver()) {
+			md.receiver = (Receiver) arg;
+			if (length > 1) {
+				System.arraycopy(
+					this.astStack,
+					this.astPtr + 2,
+					md.arguments = new Argument[length - 1],
+					0,
+					length - 1);
+			}
+			// Receiver annotations can only be type annotations; move to the type
+			Annotation[] annotations = arg.annotations;
+			if (annotations != null && annotations.length > 0) {
+				// The code assumes that receiver.type.annotations[0] will be null/empty
+				TypeReference type = arg.type;
+				if (type.annotations == null) {
+					type.bits |= ASTNode.HasTypeAnnotations;
+					type.annotations = new Annotation[type.getAnnotatableLevels()][];
+					md.bits |= ASTNode.HasTypeAnnotations;
+				}
+				type.annotations[0] = annotations;
+				int annotationSourceStart = annotations[0].sourceStart;
+				if (type.sourceStart > annotationSourceStart)
+					type.sourceStart = annotationSourceStart;
+				arg.annotations = null;
+			}
+			md.bits |= (arg.type.bits & ASTNode.HasTypeAnnotations);
+		} else {
+			System.arraycopy(
+					this.astStack,
+					this.astPtr + 1,
+					md.arguments = new Argument[length],
+					0,
+					length);
+			for (int i = 0, max = md.arguments.length; i < max; i++) {
+				if ((md.arguments[i].bits & ASTNode.HasTypeAnnotations) != 0) {
+					md.bits |= ASTNode.HasTypeAnnotations;
+					break;
+				}
+			}
+		}
+	}
+	md.bodyStart = this.rParenPos+1;
+	this.listLength = 0; // reset this.listLength after having read all parameters
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = md.bodyStart;
+		if (this.currentElement.parseTree() == md) return;
+
+		// might not have been attached yet - in some constructor scenarii
+		if (md.isConstructor()){
+			if ((length != 0)
+				|| (this.currentToken == TokenNameLBRACE)
+				|| (this.currentToken == TokenNamethrows)){
+				this.currentElement = this.currentElement.add(md, 0);
+				this.lastIgnoredToken = -1;
+			}
+		}
+	}
+}
+protected void consumeMethodHeaderThrowsClause() {
+	// MethodHeaderThrowsClause ::= 'throws' ClassTypeList
+	int length = this.astLengthStack[this.astLengthPtr--];
+	this.astPtr -= length;
+	AbstractMethodDeclaration md = (AbstractMethodDeclaration) this.astStack[this.astPtr];
+	System.arraycopy(
+		this.astStack,
+		this.astPtr + 1,
+		md.thrownExceptions = new TypeReference[length],
+		0,
+		length);
+	md.sourceEnd = md.thrownExceptions[length-1].sourceEnd;
+	md.bodyStart = md.thrownExceptions[length-1].sourceEnd + 1;
+	this.listLength = 0; // reset this.listLength after having read all thrown exceptions
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = md.bodyStart;
+	}
+}
+protected void consumeMethodInvocationName() {
+	// MethodInvocation ::= Name '(' ArgumentListopt ')'
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+
+	MessageSend m = newMessageSend();
+	m.sourceEnd = this.rParenPos;
+	m.sourceStart =
+		(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+	m.selector = this.identifierStack[this.identifierPtr--];
+	if (this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+		m.receiver = ThisReference.implicitThis();
+		this.identifierLengthPtr--;
+	} else {
+		this.identifierLengthStack[this.identifierLengthPtr]--;
+		m.receiver = getUnspecifiedReference();
+		m.sourceStart = m.receiver.sourceStart;
+	}
+	int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--];
+	Annotation [] typeAnnotations;
+	if (length != 0) {
+		System.arraycopy(
+				this.typeAnnotationStack,
+				(this.typeAnnotationPtr -= length) + 1,
+				typeAnnotations = new Annotation[length],
+				0,
+				length);
+		problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]);
+	}
+	pushOnExpressionStack(m);
+}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	// MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+
+	MessageSend m = newMessageSendWithTypeArguments();
+	m.sourceEnd = this.rParenPos;
+	m.sourceStart =
+		(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	// handle type arguments
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+	this.intPtr--;  // consume position of '<'
+
+	m.receiver = getUnspecifiedReference();
+	m.sourceStart = m.receiver.sourceStart;
+	pushOnExpressionStack(m);
+}
+protected void consumeMethodInvocationPrimary() {
+	//optimize the push/pop
+	//MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSend();
+	m.sourceStart =
+		(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	m.receiver = this.expressionStack[this.expressionPtr];
+	m.sourceStart = m.receiver.sourceStart;
+	m.sourceEnd = this.rParenPos;
+	this.expressionStack[this.expressionPtr] = m;
+}
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+	//optimize the push/pop
+	//MethodInvocation ::= Primary '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSendWithTypeArguments();
+	m.sourceStart =
+		(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	// handle type arguments
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+	this.intPtr--; // consume position of '<'
+
+	m.receiver = this.expressionStack[this.expressionPtr];
+	m.sourceStart = m.receiver.sourceStart;
+	m.sourceEnd = this.rParenPos;
+	this.expressionStack[this.expressionPtr] = m;
+}
+protected void consumeMethodInvocationSuper() {
+	// MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSend();
+	m.sourceStart = this.intStack[this.intPtr--]; // start position of the super keyword
+	m.sourceEnd = this.rParenPos;
+	m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	m.receiver = new SuperReference(m.sourceStart, this.endPosition);
+	pushOnExpressionStack(m);
+}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	// MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSendWithTypeArguments();
+	this.intPtr--; // start position of the typeArguments
+	m.sourceEnd = this.rParenPos;
+	m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	// handle type arguments
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+	m.sourceStart = this.intStack[this.intPtr--]; // start position of the super keyword
+
+	m.receiver = new SuperReference(m.sourceStart, this.endPosition);
+	pushOnExpressionStack(m);
+}
+protected void consumeModifiers() {
+	int savedModifiersSourceStart = this.modifiersSourceStart;
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	if (this.modifiersSourceStart >= savedModifiersSourceStart) {
+		this.modifiersSourceStart = savedModifiersSourceStart;
+	}
+	pushOnIntStack(this.modifiersSourceStart);
+	resetModifiers();
+}
+protected void consumeModifiers2() {
+	this.expressionLengthStack[this.expressionLengthPtr - 1] += this.expressionLengthStack[this.expressionLengthPtr--];
+}
+protected void consumeMultipleResources() {
+	// Resources ::= Resources ';' Resource
+	concatNodeLists();
+}
+protected void consumeTypeAnnotation() {
+	// TypeAnnotation ::= NormalTypeAnnotation
+	// TypeAnnotation ::= MarkerTypeAnnotation
+	// TypeAnnotation ::= SingleMemberTypeAnnotation
+	
+	if (!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_8 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		Annotation annotation = this.typeAnnotationStack[this.typeAnnotationPtr];
+		problemReporter().invalidUsageOfTypeAnnotations(annotation);
+	}
+}
+protected void consumeOneMoreTypeAnnotation() {
+	// TypeAnnotations ::= TypeAnnotations TypeAnnotation
+	this.typeAnnotationLengthStack[--this.typeAnnotationLengthPtr]++;
+}
+protected void consumeNameArrayType() {
+	pushOnGenericsLengthStack(0); // handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+}
+protected void consumeNestedMethod() {
+	// NestedMethod ::= $empty
+	jumpOverMethodBody();
+	this.nestedMethod[this.nestedType] ++;
+	pushOnIntStack(this.scanner.currentPosition);
+	consumeOpenBlock();
+}
+protected void consumeNestedType() {
+	// NestedType ::= $empty
+	int length = this.nestedMethod.length;
+	if (++this.nestedType >= length) {
+		System.arraycopy(
+			this.nestedMethod, 0,
+			this.nestedMethod = new int[length + 30], 0,
+			length);
+		// increase the size of the variablesCounter as well. It has to be consistent with the size of the nestedMethod collection
+		System.arraycopy(
+			this.variablesCounter, 0,
+			this.variablesCounter = new int[length + 30], 0,
+			length);
+	}
+	this.nestedMethod[this.nestedType] = 0;
+	this.variablesCounter[this.nestedType] = 0;
+}
+protected void consumeNormalAnnotation(boolean isTypeAnnotation) {
+	// NormalTypeAnnotation ::= TypeAnnotationName '(' MemberValuePairsopt ')'
+	// NormalAnnotation ::= AnnotationName '(' MemberValuePairsopt ')'
+	NormalAnnotation normalAnnotation = null;
+
+	int oldIndex = this.identifierPtr;
+
+	TypeReference typeReference = getAnnotationType();
+	normalAnnotation = new NormalAnnotation(typeReference, this.intStack[this.intPtr--]);
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.astStack,
+			(this.astPtr -= length) + 1,
+			normalAnnotation.memberValuePairs = new MemberValuePair[length],
+			0,
+			length);
+	}
+	normalAnnotation.declarationSourceEnd = this.rParenPos;
+	
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(normalAnnotation);
+	} else {
+		pushOnExpressionStack(normalAnnotation);
+	}
+
+	if(this.currentElement != null) {
+		annotationRecoveryCheckPoint(normalAnnotation.sourceStart, normalAnnotation.declarationSourceEnd);
+
+		if (this.currentElement instanceof RecoveredAnnotation) {
+			this.currentElement = ((RecoveredAnnotation)this.currentElement).addAnnotation(normalAnnotation, oldIndex);
+		}
+	}
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfAnnotation(normalAnnotation);
+	}
+	this.recordStringLiterals = true;
+}
+protected void consumeOneDimLoop(boolean isAnnotated) {
+	// OneDimLoop ::= '[' ']'
+	// OneDimLoop ::= TypeAnnotations '[' ']'
+	this.dimensions++;
+	if (!isAnnotated) {
+		pushOnTypeAnnotationLengthStack(0); // signal no annotations for the current dimension.
+	}
+}
+protected void consumeOnlySynchronized() {
+	// OnlySynchronized ::= 'synchronized'
+	pushOnIntStack(this.synchronizedBlockSourceStart);
+	resetModifiers();
+	this.expressionLengthPtr--;
+}
+protected void consumeOnlyTypeArguments() {
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		problemReporter().invalidUsageOfTypeArguments(
+			(TypeReference)this.genericsStack[this.genericsPtr - length + 1],
+			(TypeReference)this.genericsStack[this.genericsPtr]);
+	}
+}
+protected void consumeOnlyTypeArgumentsForCastExpression() {
+	// OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments
+}
+protected void consumeOpenBlock() {
+	// OpenBlock ::= $empty
+
+	pushOnIntStack(this.scanner.startPosition);
+	int stackLength = this.realBlockStack.length;
+	if (++this.realBlockPtr >= stackLength) {
+		System.arraycopy(
+			this.realBlockStack, 0,
+			this.realBlockStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.realBlockStack[this.realBlockPtr] = 0;
+}
+protected void consumePackageComment() {
+	// get possible comment for syntax since 1.5
+	if(this.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+		checkComment();
+		resetModifiers();
+	}
+}
+protected void consumePackageDeclaration() {
+	// PackageDeclaration ::= 'package' Name ';'
+	/* build an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt = this.compilationUnit.currentPackage;
+	this.compilationUnit.javadoc = this.javadoc;
+	this.javadoc = null;
+	// flush comments defined prior to import statements
+	impt.declarationEnd = this.endStatementPosition;
+	impt.declarationSourceEnd = flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
+}
+protected void consumePackageDeclarationName() {
+	// PackageDeclarationName ::= PackageComment 'package' Name RejectTypeAnnotations
+	/* build an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens =
+		new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length);
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr--,
+		positions,
+		0,
+		length);
+
+	impt = new ImportReference(tokens, positions, false, ClassFileConstants.AccDefault);
+	this.compilationUnit.currentPackage = impt;
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	// get possible comment source start
+	if(this.javadoc != null) {
+		impt.declarationSourceStart = this.javadoc.sourceStart;
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumePackageDeclarationNameWithModifiers() {
+	// PackageDeclarationName ::= Modifiers 'package' PushRealModifiers Name RejectTypeAnnotations
+	/* build an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens =
+		new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, ++this.identifierPtr, tokens, 0, length);
+	System.arraycopy(
+		this.identifierPositionStack,
+		this.identifierPtr--,
+		positions,
+		0,
+		length);
+
+	int packageModifiersSourceStart = this.intStack[this.intPtr--];
+	int packageModifiersSourceEnd = packageModifiersSourceStart; // Unless there were any
+	int packageModifiers = this.intStack[this.intPtr--];
+
+	impt = new ImportReference(tokens, positions, false, packageModifiers);
+	this.compilationUnit.currentPackage = impt;
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			impt.annotations = new Annotation[length],
+			0,
+			length);
+		impt.declarationSourceStart = packageModifiersSourceStart;
+		packageModifiersSourceEnd = this.intStack[this.intPtr--] - 2; // we don't need the position of the 'package keyword
+	} else {
+		impt.declarationSourceStart = this.intStack[this.intPtr--];
+		packageModifiersSourceEnd = impt.declarationSourceStart - 2;
+		// get possible comment source start
+		if (this.javadoc != null) {
+			impt.declarationSourceStart = this.javadoc.sourceStart;
+		}
+	}
+
+	if (packageModifiers != 0) {
+		problemReporter().illegalModifiers(packageModifiersSourceStart, packageModifiersSourceEnd);
+	}
+	
+	
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumePostfixExpression() {
+	// PostfixExpression ::= Name
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+}
+protected void consumePrimaryNoNewArray() {
+	// PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN
+	final Expression parenthesizedExpression = this.expressionStack[this.expressionPtr];
+	updateSourcePosition(parenthesizedExpression);
+	int numberOfParenthesis = (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+	parenthesizedExpression.bits &= ~ASTNode.ParenthesizedMASK;
+	parenthesizedExpression.bits |= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT;
+}
+protected void consumePrimaryNoNewArrayArrayType() {
+	// PrimaryNoNewArray ::= Name Dims '.' 'class'
+	this.intPtr--; // remove the class start position
+
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0);
+	ClassLiteralAccess cla;
+	pushOnExpressionStack(
+		cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--])));
+	rejectIllegalTypeAnnotations(cla.type);
+}
+protected void consumePrimaryNoNewArrayName() {
+	// PrimaryNoNewArray ::= Name '.' 'class'
+	this.intPtr--; // remove the class start position
+
+	// handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0);
+	TypeReference typeReference = getTypeReference(0);
+	
+	rejectIllegalTypeAnnotations(typeReference);
+
+	pushOnExpressionStack(
+		new ClassLiteralAccess(this.intStack[this.intPtr--], typeReference));
+}
+protected void rejectIllegalLeadingTypeAnnotations(TypeReference typeReference) {
+	// Reject misplaced annotations prefixed to a type reference; Used when the grammar is permissive enough to allow them in the first place.
+	Annotation [][]  annotations = typeReference.annotations;
+	if (annotations != null && annotations[0] != null) {
+		problemReporter().misplacedTypeAnnotations(annotations[0][0], annotations[0][annotations[0].length - 1]);
+		annotations[0] = null;  // don't complain further.
+	}
+}
+private void rejectIllegalTypeAnnotations(TypeReference typeReference) {
+	// Reject misplaced annotations on type reference; Used when grammar is permissive enough to allow them in the first place.
+	Annotation [][]  annotations = typeReference.annotations;
+	Annotation[] misplacedAnnotations;
+	for (int i = 0, length = annotations == null ? 0 : annotations.length; i < length; i++) {
+		misplacedAnnotations =  annotations[i];
+		if (misplacedAnnotations != null) {
+			problemReporter().misplacedTypeAnnotations(misplacedAnnotations[0], misplacedAnnotations[misplacedAnnotations.length - 1]);
+		}
+	}
+	annotations = typeReference.getAnnotationsOnDimensions();
+	for (int i = 0, length = annotations == null ? 0 : annotations.length; i < length; i++) {
+		misplacedAnnotations = annotations[i];
+		if (misplacedAnnotations != null) {
+			problemReporter().misplacedTypeAnnotations(misplacedAnnotations[0], misplacedAnnotations[misplacedAnnotations.length - 1]);
+		}
+	}
+	typeReference.annotations = null;
+	typeReference.setAnnotationsOnDimensions(null);
+	typeReference.bits &= ~ASTNode.HasTypeAnnotations;
+}
+protected void consumePrimaryNoNewArrayNameSuper() {
+	// PrimaryNoNewArray ::= Name '.' 'super'
+	// handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0);
+	// javac does not accept annotations here anywhere ...
+	TypeReference typeReference = getTypeReference(0);
+	rejectIllegalTypeAnnotations(typeReference);
+	pushOnExpressionStack(
+		new QualifiedSuperReference(
+			typeReference,
+			this.intStack[this.intPtr--],
+			this.endPosition));
+}
+protected void consumePrimaryNoNewArrayNameThis() {
+	// PrimaryNoNewArray ::= Name '.' 'this'
+	// handle type arguments
+	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+	pushOnGenericsLengthStack(0); // handle type arguments
+	// javac does not accept annotations here anywhere ...
+	TypeReference typeReference = getTypeReference(0);
+	rejectIllegalTypeAnnotations(typeReference);
+	pushOnExpressionStack(
+		new QualifiedThisReference(
+			typeReference,
+			this.intStack[this.intPtr--],
+			this.endPosition));
+}
+protected void consumePrimaryNoNewArrayPrimitiveArrayType() {
+	// PrimaryNoNewArray ::= PrimitiveType Dims '.' 'class'
+	this.intPtr--; // remove the class start position
+	ClassLiteralAccess cla;
+	pushOnExpressionStack(
+		cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(this.intStack[this.intPtr--])));
+	rejectIllegalTypeAnnotations(cla.type);
+}
+protected void consumePrimaryNoNewArrayPrimitiveType() {
+	// PrimaryNoNewArray ::= PrimitiveType '.' 'class'
+	this.intPtr--; // remove the class start position
+	ClassLiteralAccess cla;
+	pushOnExpressionStack(
+		cla = new ClassLiteralAccess(this.intStack[this.intPtr--], getTypeReference(0)));
+	rejectIllegalTypeAnnotations(cla.type);
+}
+protected void consumePrimaryNoNewArrayThis() {
+	// PrimaryNoNewArray ::= 'this'
+	pushOnExpressionStack(new ThisReference(this.intStack[this.intPtr--], this.endPosition));
+}
+protected void consumePrimaryNoNewArrayWithName() {
+	// PrimaryNoNewArray ::=  PushLPAREN Name PushRPAREN
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	final Expression parenthesizedExpression = this.expressionStack[this.expressionPtr];
+	updateSourcePosition(parenthesizedExpression);
+	int numberOfParenthesis = (parenthesizedExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+	parenthesizedExpression.bits &= ~ASTNode.ParenthesizedMASK;
+	parenthesizedExpression.bits |= (numberOfParenthesis + 1) << ASTNode.ParenthesizedSHIFT;
+}
+protected void consumePrimitiveArrayType() {
+	// nothing to do
+	// Will be consume by a getTypeRefence call
+}
+protected void consumePrimitiveType() {
+	// Type ::= PrimitiveType
+	pushOnIntStack(0);
+}
+protected void consumePushLeftBrace() {
+	pushOnIntStack(this.endPosition); // modifiers
+}
+protected void consumePushModifiers() {
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(this.modifiersSourceStart);
+	resetModifiers();
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumePushCombineModifiers() {
+	// ModifiersWithDefault ::= Modifiersopt 'default' Modifiersopt'
+	// int stack on entry : ... Modifiers, ModifiersSourceStart, defaultSourceStart, defaultSourceEnd, Modifiers', Modifiers'SourceStart <<--- intPtr
+	// int stack on exit : ... combinedModifiers, combinedModifiersSourceStart <<--- intPtr
+	
+	this.intPtr--; // pop modifiers'SourceStart, real location is with earlier block
+	int newModifiers = this.intStack[this.intPtr--] | ExtraCompilerModifiers.AccDefaultMethod; // pop modifiers
+	this.intPtr -= 2; // pop location of 'default' keyword
+	
+	if ((this.intStack[this.intPtr - 1] & newModifiers) != 0) { // duplicate modifier(s) ?
+		newModifiers |= ExtraCompilerModifiers.AccAlternateModifierProblem;
+	}
+	this.intStack[this.intPtr - 1] |= newModifiers; // merge them in place
+	// Also fix number of annotations-modifiers:
+	this.expressionLengthStack[this.expressionLengthPtr - 1] += this.expressionLengthStack[this.expressionLengthPtr--];
+	if (this.currentElement != null) {
+		this.currentElement.addModifier(newModifiers, this.intStack[this.intPtr]);
+	}
+}
+protected void consumePushModifiersForHeader() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(this.modifiersSourceStart);
+	resetModifiers();
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumePushPosition() {
+	// for source managment purpose
+	// PushPosition ::= $empty
+	pushOnIntStack(this.endPosition);
+}
+protected void consumePushRealModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(this.modifiersSourceStart);
+	resetModifiers();
+}
+protected void consumeQualifiedName(boolean qualifiedNameIsAnnotated) {
+	// QualifiedName ::= Name '.' SimpleName
+	// QualifiedName ::= Name '.' TypeAnnotations SimpleName 
+	/*back from the recursive loop of QualifiedName.
+	Updates identifier length into the length stack*/
+
+	this.identifierLengthStack[--this.identifierLengthPtr]++;
+	if (!qualifiedNameIsAnnotated) {
+		pushOnTypeAnnotationLengthStack(0);
+	}
+}
+protected void consumeUnannotatableQualifiedName() {
+	// UnannotatableName ::= UnannotatableName '.' SimpleName
+	this.identifierLengthStack[--this.identifierLengthPtr]++;
+}
+protected void consumeRecoveryMethodHeaderName() {
+	// this method is call only inside recovery
+	boolean isAnnotationMethod = false;
+	if(this.currentElement instanceof RecoveredType) {
+		isAnnotationMethod = (((RecoveredType)this.currentElement).typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0;
+	} else {
+		RecoveredType recoveredType = this.currentElement.enclosingType();
+		if(recoveredType != null) {
+			isAnnotationMethod = (recoveredType.typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0;
+		}
+	}
+	consumeMethodHeaderName(isAnnotationMethod);
+}
+protected void consumeRecoveryMethodHeaderNameWithTypeParameters() {
+	// this method is call only inside recovery
+	boolean isAnnotationMethod = false;
+	if(this.currentElement instanceof RecoveredType) {
+		isAnnotationMethod = (((RecoveredType)this.currentElement).typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0;
+	} else {
+		RecoveredType recoveredType = this.currentElement.enclosingType();
+		if(recoveredType != null) {
+			isAnnotationMethod = (recoveredType.typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0;
+		}
+	}
+	consumeMethodHeaderNameWithTypeParameters(isAnnotationMethod);
+}
+protected void consumeReduceImports() {
+	// Consume imports
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+		System.arraycopy(
+			this.astStack,
+			this.astPtr + 1,
+			this.compilationUnit.imports = new ImportReference[length],
+			0,
+			length);
+	}
+}
+protected void consumeReferenceType() {
+	pushOnIntStack(0); // handle array type
+}
+protected void consumeReferenceType1() {
+	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeReferenceType2() {
+	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeReferenceType3() {
+	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeResourceAsLocalVariableDeclaration() {
+	// Resource ::= Type PushModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+	// Resource ::= Modifiers Type PushRealModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+	consumeLocalVariableDeclaration();
+}
+protected void consumeResourceSpecification() {
+	// ResourceSpecification ::= '(' Resources ')'
+}
+protected void consumeResourceOptionalTrailingSemiColon(boolean punctuated) {
+	// TrailingSemiColon ::= ';'
+	LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
+	if (punctuated) {
+		localDeclaration.declarationSourceEnd = this.endStatementPosition;
+	}
+}
+protected void consumeRestoreDiet() {
+	// RestoreDiet ::= $empty
+	this.dietInt--;
+}
+protected void consumeRightParen() {
+	// PushRPAREN ::= ')'
+	pushOnIntStack(this.rParenPos);
+}
+protected void consumeNonTypeUseName() { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=383596
+	// RejectTypeAnnotations ::= $empty
+	// We can get here with type annotation stack empty, because completion parser manipulates the identifier stacks even without rule reduction. See completionIdentifierCheck
+	for (int i = this.identifierLengthStack[this.identifierLengthPtr]; i > 0 && this.typeAnnotationLengthPtr >= 0; --i) {
+		int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--];
+		Annotation [] typeAnnotations;
+		if (length != 0) {
+			System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					typeAnnotations = new Annotation[length],
+					0,
+					length);
+			problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]);
+		}
+	}
+}
+protected void consumeZeroTypeAnnotations() {
+	// PushZeroTypeAnnotations ::= $empty
+	// Name ::= SimpleName
+	// TypeAnnotationsopt ::= $empty
+	pushOnTypeAnnotationLengthStack(0); // signal absence of @308 annotations.
+}
+// This method is part of an automatic generation : do NOT edit-modify
+protected void consumeRule(int act) {
+  switch ( act ) {
+    case 34 : if (DEBUG) { System.out.println("Type ::= PrimitiveType"); }  //$NON-NLS-1$
+		    consumePrimitiveType();  
+			break;
+ 
+    case 48 : if (DEBUG) { System.out.println("ReferenceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
+		    consumeReferenceType();  
+			break;
+ 
+    case 52 : if (DEBUG) { System.out.println("ClassOrInterface ::= Name"); }  //$NON-NLS-1$
+		    consumeClassOrInterfaceName();  
+			break;
+ 
+    case 53 : if (DEBUG) { System.out.println("ClassOrInterface ::= GenericType DOT Name"); }  //$NON-NLS-1$
+		    consumeClassOrInterface();  
+			break;
+ 
+    case 54 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface TypeArguments"); }  //$NON-NLS-1$
+		    consumeGenericType();  
+			break;
+ 
+    case 55 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface LESS GREATER"); }  //$NON-NLS-1$
+		    consumeGenericTypeWithDiamond();  
+			break;
+ 
+    case 56 : if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name"); }  //$NON-NLS-1$
+		    consumeArrayTypeWithTypeArgumentsName();  
+			break;
+ 
+    case 57 : if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims"); }  //$NON-NLS-1$
+		    consumePrimitiveArrayType();  
+			break;
+ 
+    case 58 : if (DEBUG) { System.out.println("ArrayType ::= Name Dims"); }  //$NON-NLS-1$
+		    consumeNameArrayType();  
+			break;
+ 
+    case 59 : if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims"); }  //$NON-NLS-1$
+		    consumeGenericTypeNameArrayType();  
+			break;
+ 
+    case 60 : if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims"); }  //$NON-NLS-1$
+		    consumeGenericTypeArrayType();  
+			break;
+ 
+    case 62 : if (DEBUG) { System.out.println("Name ::= SimpleName"); }  //$NON-NLS-1$
+		    consumeZeroTypeAnnotations();  
+			break;
+ 
+    case 67 : if (DEBUG) { System.out.println("UnannotatableName ::= UnannotatableName DOT SimpleName"); }  //$NON-NLS-1$
+		    consumeUnannotatableQualifiedName();  
+			break;
+ 
+    case 68 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName"); }  //$NON-NLS-1$
+		    consumeQualifiedName(false);  
+			break;
+ 
+    case 69 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT TypeAnnotations SimpleName"); }  //$NON-NLS-1$
+		    consumeQualifiedName(true);  
+			break;
+ 
+    case 70 : if (DEBUG) { System.out.println("TypeAnnotationsopt ::="); }  //$NON-NLS-1$
+		    consumeZeroTypeAnnotations();  
+			break;
+ 
+     case 74 : if (DEBUG) { System.out.println("TypeAnnotations0 ::= TypeAnnotations0 TypeAnnotation"); }  //$NON-NLS-1$
+		    consumeOneMoreTypeAnnotation();  
+			break;
+ 
+     case 75 : if (DEBUG) { System.out.println("TypeAnnotation ::= NormalTypeAnnotation"); }  //$NON-NLS-1$
+		    consumeTypeAnnotation();  
+			break;
+ 
+     case 76 : if (DEBUG) { System.out.println("TypeAnnotation ::= MarkerTypeAnnotation"); }  //$NON-NLS-1$
+		    consumeTypeAnnotation();  
+			break;
+ 
+     case 77 : if (DEBUG) { System.out.println("TypeAnnotation ::= SingleMemberTypeAnnotation"); }  //$NON-NLS-1$
+		    consumeTypeAnnotation();  
+			break;
+ 
+    case 78 : if (DEBUG) { System.out.println("TypeAnnotationName ::= AT308 UnannotatableName"); }  //$NON-NLS-1$
+		    consumeAnnotationName() ;  
+			break;
+ 
+    case 79 : if (DEBUG) { System.out.println("NormalTypeAnnotation ::= TypeAnnotationName LPAREN..."); }  //$NON-NLS-1$
+		    consumeNormalAnnotation(true) ;  
+			break;
+ 
+    case 80 : if (DEBUG) { System.out.println("MarkerTypeAnnotation ::= TypeAnnotationName"); }  //$NON-NLS-1$
+		    consumeMarkerAnnotation(true) ;  
+			break;
+ 
+    case 81 : if (DEBUG) { System.out.println("SingleMemberTypeAnnotation ::= TypeAnnotationName LPAREN"); }  //$NON-NLS-1$
+		    consumeSingleMemberAnnotation(true) ;  
+			break;
+ 
+    case 82 : if (DEBUG) { System.out.println("RejectTypeAnnotations ::="); }  //$NON-NLS-1$
+		    consumeNonTypeUseName();  
+			break;
+ 
+    case 83 : if (DEBUG) { System.out.println("PushZeroTypeAnnotations ::="); }  //$NON-NLS-1$
+		    consumeZeroTypeAnnotations();  
+			break;
+ 
+    case 84 : if (DEBUG) { System.out.println("VariableDeclaratorIdOrThis ::= this"); }  //$NON-NLS-1$
+		    consumeExplicitThisParameter(false);  
+			break;
+ 
+    case 85 : if (DEBUG) { System.out.println("VariableDeclaratorIdOrThis ::= UnannotatableName DOT this"); }  //$NON-NLS-1$
+		    consumeExplicitThisParameter(true);  
+			break;
+ 
+    case 86 : if (DEBUG) { System.out.println("VariableDeclaratorIdOrThis ::= VariableDeclaratorId"); }  //$NON-NLS-1$
+		    consumeVariableDeclaratorIdParameter();  
+			break;
+ 
+    case 87 : if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit..."); }  //$NON-NLS-1$
+		    consumeCompilationUnit();  
+			break;
+ 
+    case 88 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration"); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnit();  
+			break;
+ 
+    case 89 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnit();  
+			break;
+ 
+    case 90 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnitWithTypes();  
+			break;
+ 
+    case 91 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnitWithTypes();  
+			break;
+ 
+    case 92 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnit();  
+			break;
+ 
+    case 93 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations"); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnitWithTypes();  
+			break;
+ 
+    case 94 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnitWithTypes();  
+			break;
+ 
+    case 95 : if (DEBUG) { System.out.println("InternalCompilationUnit ::="); }  //$NON-NLS-1$
+		    consumeEmptyInternalCompilationUnit();  
+			break;
+ 
+    case 96 : if (DEBUG) { System.out.println("ReduceImports ::="); }  //$NON-NLS-1$
+		    consumeReduceImports();  
+			break;
+ 
+    case 97 : if (DEBUG) { System.out.println("EnterCompilationUnit ::="); }  //$NON-NLS-1$
+		    consumeEnterCompilationUnit();  
+			break;
+ 
+    case 113 : if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
+		    consumeCatchHeader();  
+			break;
+ 
+    case 115 : if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations..."); }  //$NON-NLS-1$
+		    consumeImportDeclarations();  
+			break;
+ 
+    case 117 : if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); }  //$NON-NLS-1$
+		    consumeTypeDeclarations();  
+			break;
+ 
+    case 118 : if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); }  //$NON-NLS-1$
+		    consumePackageDeclaration();  
+			break;
+ 
+    case 119 : if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package..."); }  //$NON-NLS-1$
+		    consumePackageDeclarationNameWithModifiers();  
+			break;
+ 
+    case 120 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); }  //$NON-NLS-1$
+		    consumePackageDeclarationName();  
+			break;
+ 
+    case 121 : if (DEBUG) { System.out.println("PackageComment ::="); }  //$NON-NLS-1$
+		    consumePackageComment();  
+			break;
+ 
+    case 126 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeImportDeclaration();  
+			break;
+ 
+    case 127 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name..."); }  //$NON-NLS-1$
+		    consumeSingleTypeImportDeclarationName();  
+			break;
+ 
+    case 128 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeImportDeclaration();  
+			break;
+ 
+    case 129 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); }  //$NON-NLS-1$
+		    consumeTypeImportOnDemandDeclarationName();  
+			break;
+ 
+     case 132 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeEmptyTypeDeclaration();  
+			break;
+ 
+    case 136 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); }  //$NON-NLS-1$
+		    consumeModifiers2();  
+			break;
+ 
+    case 148 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); }  //$NON-NLS-1$
+		    consumeAnnotationAsModifier();  
+			break;
+ 
+    case 149 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); }  //$NON-NLS-1$
+		    consumeClassDeclaration();  
+			break;
+ 
+    case 150 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); }  //$NON-NLS-1$
+		    consumeClassHeader();  
+			break;
+ 
+    case 151 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); }  //$NON-NLS-1$
+		    consumeTypeHeaderNameWithTypeParameters();  
+			break;
+ 
+    case 153 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); }  //$NON-NLS-1$
+		    consumeClassHeaderName1();  
+			break;
+ 
+    case 154 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); }  //$NON-NLS-1$
+		    consumeClassHeaderExtends();  
+			break;
+ 
+    case 155 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); }  //$NON-NLS-1$
+		    consumeClassHeaderImplements();  
+			break;
+ 
+    case 157 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); }  //$NON-NLS-1$
+		    consumeInterfaceTypeList();  
+			break;
+ 
+    case 158 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
+		    consumeInterfaceType();  
+			break;
+ 
+    case 161 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); }  //$NON-NLS-1$
+		    consumeClassBodyDeclarations();  
+			break;
+ 
+    case 165 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod..."); }  //$NON-NLS-1$
+		    consumeClassBodyDeclaration();  
+			break;
+ 
+    case 166 : if (DEBUG) { System.out.println("Diet ::="); }  //$NON-NLS-1$
+		    consumeDiet();  
+			break;
+
+    case 167 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer..."); }  //$NON-NLS-1$
+		    consumeClassBodyDeclaration();  
+			break;
+ 
+    case 168 : if (DEBUG) { System.out.println("CreateInitializer ::="); }  //$NON-NLS-1$
+		    consumeCreateInitializer();  
+			break;
+
+    case 175 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeEmptyTypeDeclaration();  
+			break;
+
+    case 178 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+		    consumeFieldDeclaration();  
+			break;
+ 
+    case 180 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); }  //$NON-NLS-1$
+		    consumeVariableDeclarators();  
+			break;
+ 
+    case 183 : if (DEBUG) { System.out.println("EnterVariable ::="); }  //$NON-NLS-1$
+		    consumeEnterVariable();  
+			break;
+ 
+    case 184 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); }  //$NON-NLS-1$
+		    consumeExitVariableWithInitialization();  
+			break;
+ 
+    case 185 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); }  //$NON-NLS-1$
+		    consumeExitVariableWithoutInitialization();  
+			break;
+ 
+    case 186 : if (DEBUG) { System.out.println("ForceNoDiet ::="); }  //$NON-NLS-1$
+		    consumeForceNoDiet();  
+			break;
+ 
+    case 187 : if (DEBUG) { System.out.println("RestoreDiet ::="); }  //$NON-NLS-1$
+		    consumeRestoreDiet();  
+			break;
+ 
+    case 192 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+		    // set to true to consume a method with a body
+ consumeMethodDeclaration(true);  
+			break;
+ 
+    case 193 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); }  //$NON-NLS-1$
+		    // set to false to consume a method without body
+ consumeMethodDeclaration(false);  
+			break;
+ 
+    case 194 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); }  //$NON-NLS-1$
+		    consumeMethodHeader();  
+			break;
+ 
+    case 195 : if (DEBUG) { System.out.println("DefaultMethodHeader ::= DefaultMethodHeaderName..."); }  //$NON-NLS-1$
+		    consumeMethodHeader();  
+			break;
+ 
+    case 196 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); }  //$NON-NLS-1$
+		    consumeMethodHeaderNameWithTypeParameters(false);  
+			break;
+ 
+    case 197 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); }  //$NON-NLS-1$
+		    consumeMethodHeaderName(false);  
+			break;
+ 
+    case 198 : if (DEBUG) { System.out.println("DefaultMethodHeaderName ::= ModifiersWithDefault..."); }  //$NON-NLS-1$
+		    consumeMethodHeaderNameWithTypeParameters(false);  
+			break;
+ 
+    case 199 : if (DEBUG) { System.out.println("DefaultMethodHeaderName ::= ModifiersWithDefault Type..."); }  //$NON-NLS-1$
+		    consumeMethodHeaderName(false);  
+			break;
+ 
+    case 200 : if (DEBUG) { System.out.println("ModifiersWithDefault ::= Modifiersopt default..."); }  //$NON-NLS-1$
+		    consumePushCombineModifiers();  
+			break;
+ 
+    case 201 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); }  //$NON-NLS-1$
+		    consumeMethodHeaderRightParen();  
+			break;
+ 
+    case 202 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); }  //$NON-NLS-1$
+		    consumeMethodHeaderExtendedDims();  
+			break;
+ 
+    case 203 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); }  //$NON-NLS-1$
+		    consumeMethodHeaderThrowsClause();  
+			break;
+ 
+    case 204 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
+		    consumeConstructorHeader();  
+			break;
+ 
+    case 205 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); }  //$NON-NLS-1$
+		    consumeConstructorHeaderNameWithTypeParameters();  
+			break;
+ 
+    case 206 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); }  //$NON-NLS-1$
+		    consumeConstructorHeaderName();  
+			break;
+ 
+    case 208 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); }  //$NON-NLS-1$
+		    consumeFormalParameterList();  
+			break;
+ 
+    case 209 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+		    consumeFormalParameter(false);  
+			break;
+ 
+    case 210 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+		    consumeFormalParameter(true);  
+			break;
+ 
+    case 211 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type AT308DOTDOTDOT..."); }  //$NON-NLS-1$
+		    consumeFormalParameter(true);  
+			break;
+ 
+    case 212 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt CatchType..."); }  //$NON-NLS-1$
+		    consumeCatchFormalParameter();  
+			break;
+ 
+    case 213 : if (DEBUG) { System.out.println("CatchType ::= UnionType"); }  //$NON-NLS-1$
+		    consumeCatchType();  
+			break;
+ 
+    case 214 : if (DEBUG) { System.out.println("UnionType ::= Type"); }  //$NON-NLS-1$
+		    consumeUnionTypeAsClassType();  
+			break;
+ 
+    case 215 : if (DEBUG) { System.out.println("UnionType ::= UnionType OR Type"); }  //$NON-NLS-1$
+		    consumeUnionType();  
+			break;
+ 
+    case 217 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); }  //$NON-NLS-1$
+		    consumeClassTypeList();  
+			break;
+ 
+    case 218 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); }  //$NON-NLS-1$
+		    consumeClassTypeElt();  
+			break;
+ 
+    case 219 : if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt..."); }  //$NON-NLS-1$
+		    consumeMethodBody();  
+			break;
+ 
+    case 220 : if (DEBUG) { System.out.println("NestedMethod ::="); }  //$NON-NLS-1$
+		    consumeNestedMethod();  
+			break;
+ 
+    case 221 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); }  //$NON-NLS-1$
+		    consumeStaticInitializer();  
+			break;
+
+    case 222 : if (DEBUG) { System.out.println("StaticOnly ::= static"); }  //$NON-NLS-1$
+		    consumeStaticOnly();  
+			break;
+ 
+    case 223 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); }  //$NON-NLS-1$
+		    consumeConstructorDeclaration() ;  
+			break;
+ 
+    case 224 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration() ;  
+			break;
+ 
+    case 225 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(0, THIS_CALL);  
+			break;
+ 
+    case 226 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL);  
+			break;
+ 
+    case 227 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(0,SUPER_CALL);  
+			break;
+ 
+    case 228 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL);  
+			break;
+ 
+    case 229 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(1, SUPER_CALL);  
+			break;
+ 
+    case 230 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL);  
+			break;
+ 
+    case 231 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(2, SUPER_CALL);  
+			break;
+ 
+    case 232 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL);  
+			break;
+ 
+    case 233 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(1, THIS_CALL);  
+			break;
+ 
+    case 234 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL);  
+			break;
+ 
+    case 235 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocation(2, THIS_CALL);  
+			break;
+ 
+    case 236 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+		    consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL);  
+			break;
+ 
+    case 237 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); }  //$NON-NLS-1$
+		    consumeInterfaceDeclaration();  
+			break;
+ 
+    case 238 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); }  //$NON-NLS-1$
+		    consumeInterfaceHeader();  
+			break;
+ 
+    case 239 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); }  //$NON-NLS-1$
+		    consumeTypeHeaderNameWithTypeParameters();  
+			break;
+ 
+    case 241 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); }  //$NON-NLS-1$
+		    consumeInterfaceHeaderName1();  
+			break;
+ 
+    case 242 : if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); }  //$NON-NLS-1$
+		    consumeInterfaceHeaderExtends();  
+			break;
+ 
+    case 245 : if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=..."); }  //$NON-NLS-1$
+		    consumeInterfaceMemberDeclarations();  
+			break;
+ 
+    case 246 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeEmptyTypeDeclaration();  
+			break;
+ 
+    case 248 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= DefaultMethodHeader..."); }  //$NON-NLS-1$
+		    consumeInterfaceMethodDeclaration(false);  
+			break;
+ 
+    case 249 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+		    consumeInterfaceMethodDeclaration(false);  
+			break;
+ 
+    case 250 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= DefaultMethodHeader..."); }  //$NON-NLS-1$
+		    consumeInterfaceMethodDeclaration(true);  
+			break;
+ 
+    case 251 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration(true);  
+			break;
+ 
+    case 252 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration(false);  
+			break;
+ 
+    case 263 : if (DEBUG) { System.out.println("PushLeftBrace ::="); }  //$NON-NLS-1$
+		    consumePushLeftBrace();  
+			break;
+ 
+    case 264 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); }  //$NON-NLS-1$
+		    consumeEmptyArrayInitializer();  
+			break;
+ 
+    case 265 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
+		    consumeArrayInitializer();  
+			break;
+ 
+    case 266 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
+		    consumeArrayInitializer();  
+			break;
+ 
+    case 268 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); }  //$NON-NLS-1$
+		    consumeVariableInitializers();  
+			break;
+ 
+    case 269 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); }  //$NON-NLS-1$
+		    consumeBlock();  
+			break;
+ 
+    case 270 : if (DEBUG) { System.out.println("OpenBlock ::="); }  //$NON-NLS-1$
+		    consumeOpenBlock() ;  
+			break;
+ 
+    case 272 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); }  //$NON-NLS-1$
+		    consumeBlockStatements() ;  
+			break;
+ 
+    case 276 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidInterfaceDeclaration();  
+			break;
+ 
+    case 277 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidAnnotationTypeDeclaration();  
+			break;
+ 
+    case 278 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidEnumDeclaration();  
+			break;
+ 
+    case 279 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); }  //$NON-NLS-1$
+		    consumeLocalVariableDeclarationStatement();  
+			break;
+ 
+    case 280 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); }  //$NON-NLS-1$
+		    consumeLocalVariableDeclaration();  
+			break;
+ 
+    case 281 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); }  //$NON-NLS-1$
+		    consumeLocalVariableDeclaration();  
+			break;
+ 
+    case 282 : if (DEBUG) { System.out.println("PushModifiers ::="); }  //$NON-NLS-1$
+		    consumePushModifiers();  
+			break;
+ 
+    case 283 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); }  //$NON-NLS-1$
+		    consumePushModifiersForHeader();  
+			break;
+ 
+    case 284 : if (DEBUG) { System.out.println("PushRealModifiers ::="); }  //$NON-NLS-1$
+		    consumePushRealModifiers();  
+			break;
+ 
+    case 311 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeEmptyStatement();  
+			break;
+ 
+    case 312 : if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement"); }  //$NON-NLS-1$
+		    consumeStatementLabel() ;  
+			break;
+ 
+    case 313 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON..."); }  //$NON-NLS-1$
+		    consumeStatementLabel() ;  
+			break;
+ 
+    case 314 : if (DEBUG) { System.out.println("Label ::= Identifier"); }  //$NON-NLS-1$
+		    consumeLabel() ;  
+			break;
+ 
+     case 315 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); }  //$NON-NLS-1$
+		    consumeExpressionStatement();  
+			break;
+ 
+    case 324 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+		    consumeStatementIfNoElse();  
+			break;
+ 
+    case 325 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+		    consumeStatementIfWithElse();  
+			break;
+ 
+    case 326 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); }  //$NON-NLS-1$
+		    consumeStatementIfWithElse();  
+			break;
+ 
+    case 327 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+		    consumeStatementSwitch() ;  
+			break;
+ 
+    case 328 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); }  //$NON-NLS-1$
+		    consumeEmptySwitchBlock() ;  
+			break;
+ 
+    case 331 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); }  //$NON-NLS-1$
+		    consumeSwitchBlock() ;  
+			break;
+ 
+    case 333 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); }  //$NON-NLS-1$
+		    consumeSwitchBlockStatements() ;  
+			break;
+ 
+    case 334 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
+		    consumeSwitchBlockStatement() ;  
+			break;
+ 
+    case 336 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
+		    consumeSwitchLabels() ;  
+			break;
+ 
+     case 337 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
+		    consumeCaseLabel();  
+			break;
+ 
+     case 338 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
+		    consumeDefaultLabel();  
+			break;
+ 
+    case 339 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+		    consumeStatementWhile() ;  
+			break;
+ 
+    case 340 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
+		    consumeStatementWhile() ;  
+			break;
+ 
+    case 341 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
+		    consumeStatementDo() ;  
+			break;
+ 
+    case 342 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
+		    consumeStatementFor() ;  
+			break;
+ 
+    case 343 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
+		    consumeStatementFor() ;  
+			break;
+ 
+    case 344 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
+		    consumeForInit() ;  
+			break;
+ 
+    case 348 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
+		    consumeStatementExpressionList() ;  
+			break;
+ 
+    case 349 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
+		    consumeSimpleAssertStatement() ;  
+			break;
+ 
+    case 350 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
+		    consumeAssertStatement() ;  
+			break;
+ 
+    case 351 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementBreak() ;  
+			break;
+ 
+    case 352 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementBreakWithLabel() ;  
+			break;
+ 
+    case 353 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementContinue() ;  
+			break;
+ 
+    case 354 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementContinueWithLabel() ;  
+			break;
+ 
+    case 355 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementReturn() ;  
+			break;
+ 
+    case 356 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
+		    consumeStatementThrow();  
+			break;
+ 
+    case 357 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
+		    consumeStatementSynchronized();  
+			break;
+ 
+    case 358 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
+		    consumeOnlySynchronized();  
+			break;
+ 
+    case 359 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
+		    consumeStatementTry(false, false);  
+			break;
+ 
+    case 360 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
+		    consumeStatementTry(true, false);  
+			break;
+ 
+    case 361 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+		    consumeStatementTry(false, true);  
+			break;
+ 
+    case 362 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+		    consumeStatementTry(true, true);  
+			break;
+ 
+    case 363 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); }  //$NON-NLS-1$
+		    consumeResourceSpecification();  
+			break;
+ 
+    case 364 : if (DEBUG) { System.out.println(";opt ::="); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(false);  
+			break;
+ 
+    case 365 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(true);  
+			break;
+ 
+    case 366 : if (DEBUG) { System.out.println("Resources ::= Resource"); }  //$NON-NLS-1$
+		    consumeSingleResource();  
+			break;
+ 
+    case 367 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); }  //$NON-NLS-1$
+		    consumeMultipleResources();  
+			break;
+ 
+    case 368 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(true);  
+			break;
+ 
+    case 369 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); }  //$NON-NLS-1$
+		    consumeResourceAsLocalVariableDeclaration();  
+			break;
+ 
+    case 370 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); }  //$NON-NLS-1$
+		    consumeResourceAsLocalVariableDeclaration();  
+			break;
+ 
+    case 372 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
+		    consumeExitTryBlock();  
+			break;
+ 
+    case 374 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
+		    consumeCatches();  
+			break;
+ 
+    case 375 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
+		    consumeStatementCatch() ;  
+			break;
+ 
+    case 377 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
+		    consumeLeftParen();  
+			break;
+ 
+    case 378 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
+		    consumeRightParen();  
+			break;
+ 
+    case 383 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayThis();  
+			break;
+ 
+    case 384 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArray();  
+			break;
+ 
+    case 385 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayWithName();  
+			break;
+ 
+    case 388 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayNameThis();  
+			break;
+ 
+    case 389 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayNameSuper();  
+			break;
+ 
+    case 390 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayName();  
+			break;
+ 
+    case 391 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayArrayType();  
+			break;
+ 
+    case 392 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayPrimitiveArrayType();  
+			break;
+ 
+    case 393 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
+		    consumePrimaryNoNewArrayPrimitiveType();  
+			break;
+ 
+    case 399 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionTypeArgumentsAndTrunk(false);  
+			break;
+ 
+    case 400 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionTypeArgumentsAndTrunk(true);  
+			break;
+ 
+    case 401 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); }  //$NON-NLS-1$
+		    consumeReferenceExpressionTypeForm(true);  
+			break;
+ 
+    case 402 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionTypeForm(false);  
+			break;
+ 
+    case 403 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionGenericTypeForm();  
+			break;
+ 
+    case 404 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionPrimaryForm();  
+			break;
+ 
+    case 405 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); }  //$NON-NLS-1$
+		    consumeReferenceExpressionSuperForm();  
+			break;
+ 
+    case 406 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyTypeArguments();  
+			break;
+ 
+    case 408 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); }  //$NON-NLS-1$
+		    consumeIdentifierOrNew(false);  
+			break;
+ 
+    case 409 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); }  //$NON-NLS-1$
+		    consumeIdentifierOrNew(true);  
+			break;
+ 
+    case 410 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); }  //$NON-NLS-1$
+		    consumeLambdaExpression();  
+			break;
+ 
+    case 411 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier"); }  //$NON-NLS-1$
+		    consumeTypeElidedLambdaParameter(false);  
+			break;
+ 
+    case 417 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); }  //$NON-NLS-1$
+		    consumeFormalParameterList();  
+			break;
+ 
+    case 418 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+		    consumeTypeElidedLambdaParameter(true);  
+			break;
+ 
+    case 420 : if (DEBUG) { System.out.println("LambdaBody ::= NestedType NestedMethod LBRACE..."); }  //$NON-NLS-1$
+		    consumeBlock();  
+			break;
+ 
+    case 421 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); }  //$NON-NLS-1$
+		    consumeElidedLeftBraceAndReturn();  
+			break;
+ 
+    case 422 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
+		    consumeAllocationHeader();  
+			break;
+ 
+    case 423 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionWithTypeArguments();  
+			break;
+ 
+    case 424 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpression();  
+			break;
+ 
+    case 425 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
+			break;
+ 
+    case 426 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionQualified() ;  
+			break;
+ 
+    case 427 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionQualified() ;  
+			break;
+ 
+    case 428 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
+			break;
+ 
+    case 429 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); }  //$NON-NLS-1$
+		    consumeEnterInstanceCreationArgumentList();  
+			break;
+ 
+    case 430 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionName() ;  
+			break;
+ 
+    case 431 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+		    consumeClassBodyopt();  
+			break;
+ 
+    case 433 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+		    consumeEnterAnonymousClassBody(false);  
+			break;
+ 
+    case 434 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+		    consumeClassBodyopt();  
+			break;
+ 
+    case 436 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+		    consumeEnterAnonymousClassBody(true);  
+			break;
+ 
+    case 438 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
+		    consumeArgumentList();  
+			break;
+ 
+    case 439 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
+		    consumeArrayCreationHeader();  
+			break;
+ 
+    case 440 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
+		    consumeArrayCreationHeader();  
+			break;
+ 
+    case 441 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithoutInitializer();  
+			break;
+ 
+    case 442 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithInitializer();  
+			break;
+ 
+    case 443 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithoutInitializer();  
+			break;
+ 
+    case 444 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithInitializer();  
+			break;
+ 
+    case 446 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
+		    consumeDimWithOrWithOutExprs();  
+			break;
+ 
+     case 448 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); }  //$NON-NLS-1$
+		    consumeDimWithOrWithOutExpr();  
+			break;
+ 
+     case 449 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
+		    consumeDims();  
+			break;
+ 
+     case 452 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+		    consumeOneDimLoop(false);  
+			break;
+ 
+     case 453 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); }  //$NON-NLS-1$
+		    consumeOneDimLoop(true);  
+			break;
+ 
+    case 454 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
+		    consumeFieldAccess(false);  
+			break;
+ 
+    case 455 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
+		    consumeFieldAccess(true);  
+			break;
+ 
+    case 456 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+		    consumeMethodInvocationName();  
+			break;
+ 
+    case 457 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+		    consumeMethodInvocationNameWithTypeArguments();  
+			break;
+ 
+    case 458 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+		    consumeMethodInvocationPrimaryWithTypeArguments();  
+			break;
+ 
+    case 459 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+		    consumeMethodInvocationPrimary();  
+			break;
+ 
+    case 460 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+		    consumeMethodInvocationSuperWithTypeArguments();  
+			break;
+ 
+    case 461 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+		    consumeMethodInvocationSuper();  
+			break;
+ 
+    case 462 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
+		    consumeArrayAccess(true);  
+			break;
+ 
+    case 463 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
+		    consumeArrayAccess(false);  
+			break;
+ 
+    case 464 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
+		    consumeArrayAccess(false);  
+			break;
+ 
+    case 466 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
+		    consumePostfixExpression();  
+			break;
+ 
+    case 469 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.PLUS,true);  
+			break;
+ 
+    case 470 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.MINUS,true);  
+			break;
+ 
+    case 471 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
+		    consumePushPosition();  
+			break;
+ 
+    case 474 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.PLUS);  
+			break;
+ 
+    case 475 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.MINUS);  
+			break;
+ 
+    case 477 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.PLUS,false);  
+			break;
+ 
+    case 478 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.MINUS,false);  
+			break;
+ 
+    case 480 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
+			break;
+ 
+    case 481 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.NOT);  
+			break;
+ 
+    case 483 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
+		    consumeCastExpressionWithPrimitiveType();  
+			break;
+ 
+    case 484 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+		    consumeCastExpressionWithGenericsArray();  
+			break;
+ 
+    case 485 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+		    consumeCastExpressionWithQualifiedGenericsArray();  
+			break;
+ 
+    case 486 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
+		    consumeCastExpressionLL1();  
+			break;
+ 
+    case 487 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); }  //$NON-NLS-1$
+		    consumeCastExpressionLL1WithBounds();  
+			break;
+ 
+    case 488 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); }  //$NON-NLS-1$
+		    consumeCastExpressionWithNameArray();  
+			break;
+ 
+    case 489 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); }  //$NON-NLS-1$
+		    consumeZeroAdditionalBounds();  
+			break;
+ 
+    case 493 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
+		    consumeOnlyTypeArgumentsForCastExpression();  
+			break;
+ 
+    case 494 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
+		    consumeInsideCastExpression();  
+			break;
+ 
+    case 495 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
+		    consumeInsideCastExpressionLL1();  
+			break;
+ 
+    case 496 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); }  //$NON-NLS-1$
+		    consumeInsideCastExpressionLL1WithBounds ();  
+			break;
+ 
+    case 497 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
+		    consumeInsideCastExpressionWithQualifiedGenerics();  
+			break;
+ 
+    case 499 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
+			break;
+ 
+    case 500 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.DIVIDE);  
+			break;
+ 
+    case 501 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.REMAINDER);  
+			break;
+ 
+    case 503 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.PLUS);  
+			break;
+ 
+    case 504 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.MINUS);  
+			break;
+ 
+    case 506 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
+			break;
+ 
+    case 507 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
+			break;
+ 
+    case 508 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
+			break;
+ 
+    case 510 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LESS);  
+			break;
+ 
+    case 511 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.GREATER);  
+			break;
+ 
+    case 512 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
+			break;
+ 
+    case 513 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
+			break;
+ 
+    case 515 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
+		    consumeInstanceOfExpression();  
+			break;
+ 
+    case 517 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
+		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
+			break;
+ 
+    case 518 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
+		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
+			break;
+ 
+    case 520 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.AND);  
+			break;
+ 
+    case 522 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.XOR);  
+			break;
+ 
+    case 524 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.OR);  
+			break;
+ 
+    case 526 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.AND_AND);  
+			break;
+ 
+    case 528 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.OR_OR);  
+			break;
+ 
+    case 530 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
+			break;
+ 
+    case 533 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
+		    consumeAssignment();  
+			break;
+ 
+    case 535 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
+		    ignoreExpressionAssignment(); 
+			break;
+ 
+    case 536 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(EQUAL);  
+			break;
+ 
+    case 537 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(MULTIPLY);  
+			break;
+ 
+    case 538 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(DIVIDE);  
+			break;
+ 
+    case 539 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(REMAINDER);  
+			break;
+ 
+    case 540 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(PLUS);  
+			break;
+ 
+    case 541 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(MINUS);  
+			break;
+ 
+    case 542 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(LEFT_SHIFT);  
+			break;
+ 
+    case 543 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(RIGHT_SHIFT);  
+			break;
+ 
+    case 544 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
+			break;
+ 
+    case 545 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(AND);  
+			break;
+ 
+    case 546 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(XOR);  
+			break;
+ 
+    case 547 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
+		    consumeAssignmentOperator(OR);  
+			break;
+ 
+    case 548 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); }  //$NON-NLS-1$
+		    consumeExpression();  
+			break;
+ 
+    case 551 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyExpression();  
+			break;
+ 
+    case 556 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyClassBodyDeclarationsopt();  
+			break;
+ 
+    case 557 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+		    consumeClassBodyDeclarationsopt();  
+			break;
+ 
+     case 558 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
+		    consumeDefaultModifiers();  
+			break;
+ 
+    case 559 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
+		    consumeModifiers();  
+			break;
+ 
+    case 560 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyBlockStatementsopt();  
+			break;
+ 
+     case 562 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyDimsopt();  
+			break;
+ 
+     case 564 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyArgumentListopt();  
+			break;
+ 
+    case 568 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
+		    consumeFormalParameterListopt();  
+			break;
+ 
+     case 572 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyInterfaceMemberDeclarationsopt();  
+			break;
+ 
+     case 573 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+		    consumeInterfaceMemberDeclarationsopt();  
+			break;
+ 
+    case 574 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
+		    consumeNestedType();  
+			break;
+
+     case 575 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyForInitopt();  
+			break;
+ 
+     case 577 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyForUpdateopt();  
+			break;
+ 
+     case 581 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyCatchesopt();  
+			break;
+ 
+     case 583 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
+		    consumeEnumDeclaration();  
+			break;
+ 
+     case 584 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
+		    consumeEnumHeader();  
+			break;
+ 
+     case 585 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
+		    consumeEnumHeaderName();  
+			break;
+ 
+     case 586 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); }  //$NON-NLS-1$
+		    consumeEnumHeaderNameWithTypeParameters();  
+			break;
+ 
+     case 587 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
+		    consumeEnumBodyNoConstants();  
+			break;
+ 
+     case 588 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
+		    consumeEnumBodyNoConstants();  
+			break;
+ 
+     case 589 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
+		    consumeEnumBodyWithConstants();  
+			break;
+ 
+     case 590 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
+		    consumeEnumBodyWithConstants();  
+			break;
+ 
+    case 592 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
+		    consumeEnumConstants();  
+			break;
+ 
+    case 593 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+		    consumeEnumConstantHeaderName();  
+			break;
+ 
+    case 594 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
+		    consumeEnumConstantHeader();  
+			break;
+ 
+    case 595 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
+		    consumeEnumConstantWithClassBody();  
+			break;
+ 
+    case 596 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
+		    consumeEnumConstantNoClassBody();  
+			break;
+ 
+    case 597 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+		    consumeArguments();  
+			break;
+ 
+    case 598 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyArguments();  
+			break;
+ 
+    case 600 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
+		    consumeEnumDeclarations();  
+			break;
+ 
+    case 601 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyEnumDeclarations();  
+			break;
+ 
+    case 603 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
+		    consumeEnhancedForStatement();  
+			break;
+ 
+    case 604 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
+		    consumeEnhancedForStatement();  
+			break;
+ 
+    case 605 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); }  //$NON-NLS-1$
+		    consumeEnhancedForStatementHeaderInit(false);  
+			break;
+ 
+    case 606 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); }  //$NON-NLS-1$
+		    consumeEnhancedForStatementHeaderInit(true);  
+			break;
+ 
+    case 607 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); }  //$NON-NLS-1$
+		    consumeEnhancedForStatementHeader();  
+			break;
+ 
+    case 608 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeImportDeclaration();  
+			break;
+ 
+    case 609 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); }  //$NON-NLS-1$
+		    consumeSingleStaticImportDeclarationName();  
+			break;
+ 
+    case 610 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeImportDeclaration();  
+			break;
+ 
+    case 611 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); }  //$NON-NLS-1$
+		    consumeStaticImportOnDemandDeclarationName();  
+			break;
+ 
+    case 612 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+		    consumeTypeArguments();  
+			break;
+ 
+    case 613 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+		    consumeOnlyTypeArguments();  
+			break;
+ 
+    case 615 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+		    consumeTypeArgumentList1();  
+			break;
+ 
+    case 617 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); }  //$NON-NLS-1$
+		    consumeTypeArgumentList();  
+			break;
+ 
+    case 618 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); }  //$NON-NLS-1$
+		    consumeTypeArgument();  
+			break;
+ 
+    case 622 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); }  //$NON-NLS-1$
+		    consumeReferenceType1();  
+			break;
+ 
+    case 623 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+		    consumeTypeArgumentReferenceType1();  
+			break;
+ 
+    case 625 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+		    consumeTypeArgumentList2();  
+			break;
+ 
+    case 628 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); }  //$NON-NLS-1$
+		    consumeReferenceType2();  
+			break;
+ 
+    case 629 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+		    consumeTypeArgumentReferenceType2();  
+			break;
+ 
+    case 631 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+		    consumeTypeArgumentList3();  
+			break;
+ 
+    case 634 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+		    consumeReferenceType3();  
+			break;
+ 
+    case 635 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); }  //$NON-NLS-1$
+		    consumeWildcard();  
+			break;
+ 
+    case 636 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); }  //$NON-NLS-1$
+		    consumeWildcardWithBounds();  
+			break;
+ 
+    case 637 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); }  //$NON-NLS-1$
+		    consumeWildcardBoundsExtends();  
+			break;
+ 
+    case 638 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); }  //$NON-NLS-1$
+		    consumeWildcardBoundsSuper();  
+			break;
+ 
+    case 639 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); }  //$NON-NLS-1$
+		    consumeWildcard1();  
+			break;
+ 
+    case 640 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+		    consumeWildcard1WithBounds();  
+			break;
+ 
+    case 641 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); }  //$NON-NLS-1$
+		    consumeWildcardBounds1Extends();  
+			break;
+ 
+    case 642 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); }  //$NON-NLS-1$
+		    consumeWildcardBounds1Super();  
+			break;
+ 
+    case 643 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); }  //$NON-NLS-1$
+		    consumeWildcard2();  
+			break;
+ 
+    case 644 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+		    consumeWildcard2WithBounds();  
+			break;
+ 
+    case 645 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); }  //$NON-NLS-1$
+		    consumeWildcardBounds2Extends();  
+			break;
+ 
+    case 646 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); }  //$NON-NLS-1$
+		    consumeWildcardBounds2Super();  
+			break;
+ 
+    case 647 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+		    consumeWildcard3();  
+			break;
+ 
+    case 648 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+		    consumeWildcard3WithBounds();  
+			break;
+ 
+    case 649 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); }  //$NON-NLS-1$
+		    consumeWildcardBounds3Extends();  
+			break;
+ 
+    case 650 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); }  //$NON-NLS-1$
+		    consumeWildcardBounds3Super();  
+			break;
+ 
+    case 651 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); }  //$NON-NLS-1$
+		    consumeTypeParameterHeader();  
+			break;
+ 
+    case 652 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); }  //$NON-NLS-1$
+		    consumeTypeParameters();  
+			break;
+ 
+    case 654 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+		    consumeTypeParameterList();  
+			break;
+ 
+    case 656 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+		    consumeTypeParameterWithExtends();  
+			break;
+ 
+    case 657 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+		    consumeTypeParameterWithExtendsAndBounds();  
+			break;
+ 
+    case 659 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+		    consumeAdditionalBoundList();  
+			break;
+ 
+    case 660 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); }  //$NON-NLS-1$
+		    consumeAdditionalBound();  
+			break;
+ 
+    case 662 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+		    consumeTypeParameterList1();  
+			break;
+ 
+    case 663 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); }  //$NON-NLS-1$
+		    consumeTypeParameter1();  
+			break;
+ 
+    case 664 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+		    consumeTypeParameter1WithExtends();  
+			break;
+ 
+    case 665 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+		    consumeTypeParameter1WithExtendsAndBounds();  
+			break;
+ 
+    case 667 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+		    consumeAdditionalBoundList1();  
+			break;
+ 
+    case 668 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); }  //$NON-NLS-1$
+		    consumeAdditionalBound1();  
+			break;
+ 
+    case 674 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.PLUS);  
+			break;
+ 
+    case 675 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.MINUS);  
+			break;
+ 
+    case 678 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
+			break;
+ 
+    case 679 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); }  //$NON-NLS-1$
+		    consumeUnaryExpression(OperatorIds.NOT);  
+			break;
+ 
+    case 682 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
+			break;
+ 
+    case 683 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.MULTIPLY);  
+			break;
+ 
+    case 684 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.DIVIDE);  
+			break;
+ 
+    case 685 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.DIVIDE);  
+			break;
+ 
+    case 686 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.REMAINDER);  
+			break;
+ 
+    case 687 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.REMAINDER);  
+			break;
+ 
+    case 689 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.PLUS);  
+			break;
+ 
+    case 690 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.PLUS);  
+			break;
+ 
+    case 691 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.MINUS);  
+			break;
+ 
+    case 692 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.MINUS);  
+			break;
+ 
+    case 694 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
+			break;
+ 
+    case 695 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT);  
+			break;
+ 
+    case 696 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
+			break;
+ 
+    case 697 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT);  
+			break;
+ 
+    case 698 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
+			break;
+ 
+    case 699 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
+			break;
+ 
+    case 701 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LESS);  
+			break;
+ 
+    case 702 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.LESS);  
+			break;
+ 
+    case 703 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.GREATER);  
+			break;
+ 
+    case 704 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.GREATER);  
+			break;
+ 
+    case 705 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
+			break;
+ 
+    case 706 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL);  
+			break;
+ 
+    case 707 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
+			break;
+ 
+    case 708 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL);  
+			break;
+ 
+    case 710 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); }  //$NON-NLS-1$
+		    consumeInstanceOfExpressionWithName();  
+			break;
+ 
+    case 711 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeInstanceOfExpression();  
+			break;
+ 
+    case 713 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
+			break;
+ 
+    case 714 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); }  //$NON-NLS-1$
+		    consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL);  
+			break;
+ 
+    case 715 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
+			break;
+ 
+    case 716 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); }  //$NON-NLS-1$
+		    consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL);  
+			break;
+ 
+    case 718 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.AND);  
+			break;
+ 
+    case 719 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.AND);  
+			break;
+ 
+    case 721 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.XOR);  
+			break;
+ 
+    case 722 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.XOR);  
+			break;
+ 
+    case 724 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.OR);  
+			break;
+ 
+    case 725 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.OR);  
+			break;
+ 
+    case 727 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.AND_AND);  
+			break;
+ 
+    case 728 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.AND_AND);  
+			break;
+ 
+    case 730 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeBinaryExpression(OperatorIds.OR_OR);  
+			break;
+ 
+    case 731 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); }  //$NON-NLS-1$
+		    consumeBinaryExpressionWithName(OperatorIds.OR_OR);  
+			break;
+ 
+    case 733 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); }  //$NON-NLS-1$
+		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
+			break;
+ 
+    case 734 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); }  //$NON-NLS-1$
+		    consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ;  
+			break;
+ 
+    case 738 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclarationHeaderName() ;  
+			break;
+ 
+    case 739 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ;  
+			break;
+ 
+    case 740 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ;  
+			break;
+ 
+    case 741 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclarationHeaderName() ;  
+			break;
+ 
+    case 742 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclarationHeader() ;  
+			break;
+ 
+    case 743 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeDeclaration() ;  
+			break;
+ 
+    case 745 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyAnnotationTypeMemberDeclarationsopt() ;  
+			break;
+ 
+    case 746 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeMemberDeclarationsopt() ;  
+			break;
+ 
+    case 748 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeMemberDeclarations() ;  
+			break;
+ 
+    case 749 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); }  //$NON-NLS-1$
+		    consumeMethodHeaderNameWithTypeParameters(true);  
+			break;
+ 
+    case 750 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+		    consumeMethodHeaderName(true);  
+			break;
+ 
+    case 751 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyMethodHeaderDefaultValue() ;  
+			break;
+ 
+    case 752 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); }  //$NON-NLS-1$
+		    consumeMethodHeaderDefaultValue();  
+			break;
+ 
+    case 753 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); }  //$NON-NLS-1$
+		    consumeMethodHeader();  
+			break;
+ 
+    case 754 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); }  //$NON-NLS-1$
+		    consumeAnnotationTypeMemberDeclaration() ;  
+			break;
+ 
+    case 762 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); }  //$NON-NLS-1$
+		    consumeAnnotationName() ;  
+			break;
+ 
+    case 763 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
+		    consumeNormalAnnotation(false) ;  
+			break;
+ 
+    case 764 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); }  //$NON-NLS-1$
+		    consumeEmptyMemberValuePairsopt() ;  
+			break;
+ 
+    case 767 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); }  //$NON-NLS-1$
+		    consumeMemberValuePairs() ;  
+			break;
+ 
+    case 768 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); }  //$NON-NLS-1$
+		    consumeMemberValuePair() ;  
+			break;
+ 
+    case 769 : if (DEBUG) { System.out.println("EnterMemberValue ::="); }  //$NON-NLS-1$
+		    consumeEnterMemberValue() ;  
+			break;
+ 
+    case 770 : if (DEBUG) { System.out.println("ExitMemberValue ::="); }  //$NON-NLS-1$
+		    consumeExitMemberValue() ;  
+			break;
+ 
+    case 772 : if (DEBUG) { System.out.println("MemberValue ::= Name"); }  //$NON-NLS-1$
+		    consumeMemberValueAsName() ;  
+			break;
+ 
+    case 775 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+		    consumeMemberValueArrayInitializer() ;  
+			break;
+ 
+    case 776 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+		    consumeMemberValueArrayInitializer() ;  
+			break;
+ 
+    case 777 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+		    consumeEmptyMemberValueArrayInitializer() ;  
+			break;
+ 
+    case 778 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+		    consumeEmptyMemberValueArrayInitializer() ;  
+			break;
+ 
+    case 779 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); }  //$NON-NLS-1$
+		    consumeEnterMemberValueArrayInitializer() ;  
+			break;
+ 
+    case 781 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); }  //$NON-NLS-1$
+		    consumeMemberValues() ;  
+			break;
+ 
+    case 782 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); }  //$NON-NLS-1$
+		    consumeMarkerAnnotation(false) ;  
+			break;
+ 
+    case 783 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); }  //$NON-NLS-1$
+		    consumeSingleMemberAnnotationMemberValue() ;  
+			break;
+ 
+    case 784 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
+		    consumeSingleMemberAnnotation(false) ;  
+			break;
+ 
+    case 785 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); }  //$NON-NLS-1$
+		    consumeRecoveryMethodHeaderNameWithTypeParameters();  
+			break;
+ 
+    case 786 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+		    consumeRecoveryMethodHeaderName();  
+			break;
+ 
+    case 787 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); }  //$NON-NLS-1$
+		    consumeRecoveryMethodHeaderNameWithTypeParameters();  
+			break;
+ 
+    case 788 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); }  //$NON-NLS-1$
+		    consumeRecoveryMethodHeaderName();  
+			break;
+ 
+    case 789 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
+		    consumeMethodHeader();  
+			break;
+ 
+    case 790 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
+		    consumeMethodHeader();  
+			break;
+ 
+	}
+}
+protected void consumeVariableDeclaratorIdParameter () {
+	pushOnIntStack(1);  // signal "normal" variable declarator id parameter.
+}
+protected void consumeExplicitThisParameter(boolean isQualified) {
+	// VariableDeclaratorIdOrThis ::= 'this'
+	// VariableDeclaratorIdOrThis ::= UnannotatableName '.' 'this'
+	// VariableDeclaratorIdOrThis ::= VariableDeclaratorId
+
+	NameReference qualifyingNameReference = null;
+	if (isQualified) {
+		qualifyingNameReference = getUnspecifiedReference(false); // By construction the qualified name is unannotated here, so we should not meddle with the type annotation stack
+	}
+	pushOnExpressionStack(qualifyingNameReference);
+	int thisStart = this.intStack[this.intPtr--];
+	pushIdentifier(ConstantPool.This, (((long) thisStart << 32)) + (thisStart + 3));
+	pushOnIntStack(0);  // extended dimensions ...
+	pushOnIntStack(0);  // signal explicit this
+}
+protected void consumeLambdaExpression() {
+	
+	// LambdaExpression ::= LambdaParameters '->' LambdaBody
+
+	this.astLengthPtr--; 	// pop length for LambdaBody (always 1)
+	Statement body = (Statement) this.astStack[this.astPtr--];
+	if (body instanceof Block) {
+		this.nestedType--; 	// matching NestedType in "LambdaBody ::= NestedType NestedMethod  '{' BlockStatementsopt '}'"
+		this.intPtr--; 		// position after '{' pushed during consumeNestedMethod()
+		if (this.options.ignoreMethodBodies) {
+			body = new Block(0);
+		}
+	}
+	Argument [] arguments = null;
+	int length = this.astLengthStack[this.astLengthPtr--];
+	this.astPtr -= length;
+	//arguments
+	if (length != 0) {
+		System.arraycopy(
+			this.astStack,
+			this.astPtr + 1,
+			arguments = new Argument[length],
+			0,
+			length);
+	}
+	for (int i = 0; i < length; i++) {
+		if (arguments[i].isReceiver()) {
+			problemReporter().illegalThis(arguments[i]);
+		}
+	}
+	LambdaExpression lexp = new LambdaExpression(this.compilationUnit.compilationResult, arguments, body);
+	this.intPtr--;  // ')' position, discard for now.
+	lexp.sourceStart = this.intStack[this.intPtr--]; // '(' position or identifier position.
+	lexp.sourceEnd = body.sourceEnd;
+	lexp.hasParentheses = (this.scanner.getSource()[lexp.sourceStart] == '(');
+	if (body instanceof Expression) {
+		Expression expression = (Expression) body;
+		expression.statementEnd = body.sourceEnd;
+	}
+	pushOnExpressionStack(lexp);
+	if (!this.parsingJava8Plus) {
+		problemReporter().lambdaExpressionsNotBelow18(lexp);
+	}
+	this.listLength = 0; // reset this.listLength after having read all parameters
+}
+
+protected void consumeTypeElidedLambdaParameter(boolean parenthesized) {
+
+	// LambdaParameters ::= Identifier
+	// TypeElidedFormalParameter ::= Modifiersopt Identifier
+	
+	int modifier = ClassFileConstants.AccDefault;
+	int annotationLength = 0;
+	int modifiersStart = 0;
+	if (parenthesized) { // The grammar is permissive enough to allow optional modifiers for the parenthesized version, they should be rejected if present. 
+		modifiersStart = this.intStack[this.intPtr--];
+		modifier = this.intStack[this.intPtr--];
+		// pop annotations
+		annotationLength = this.expressionLengthStack[this.expressionLengthPtr--];
+		this.expressionPtr -= annotationLength;
+	}
+	
+	this.identifierLengthPtr--;
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+
+	Argument arg =
+		new Argument(
+			identifierName,
+			namePositions,
+			null, // elided type
+			ClassFileConstants.AccDefault,
+			true);
+	arg.declarationSourceStart = (int) (namePositions >>> 32);
+	if (modifier != ClassFileConstants.AccDefault || annotationLength != 0) {
+		problemReporter().illegalModifiersForElidedType(arg);
+		arg.declarationSourceStart = modifiersStart;
+	} 
+	pushOnAstStack(arg);
+	if (!parenthesized) { // in the absence of '(' and ')', record positions.
+		pushOnIntStack(arg.declarationSourceStart);
+		pushOnIntStack(arg.declarationSourceEnd);
+	}
+	/* if incomplete method header, this.listLength counter will not have been reset,
+		indicating that some arguments are available on the stack */
+	this.listLength++;
+}
+protected void consumeElidedLeftBraceAndReturn() {
+	/* ElidedLeftBraceAndReturn ::= $empty
+	   Alert ! Sleight of hand - Part I : Record stack depth now that we are at the state with the kernel item
+	   ElidedLeftBraceAndReturn .Expression ElidedSemicolonAndRightBrace
+	*/
+	int stackLength = this.stateStackLengthStack.length;
+	if (++this.valueLambdaNestDepth >= stackLength) {
+		System.arraycopy(
+			this.stateStackLengthStack, 0,
+			this.stateStackLengthStack = new int[stackLength + 4], 0,
+			stackLength);
+	}
+	this.stateStackLengthStack[this.valueLambdaNestDepth] = this.stateStackTop;  
+}
+protected void consumeExpression() {
+	/* Expression ::= AssignmentExpression
+	   Alert ! Sleight of hand - Part II: See if we are at the state with the item: "ElidedLeftBraceAndReturn Expression .ElidedSemicolonAndRightBrace"
+       If so, push back the current token into the lexer stream, materialize the synthetic terminal marker symbol, switch and continue.
+    */   
+	if (this.valueLambdaNestDepth >= 0 && this.stateStackLengthStack[this.valueLambdaNestDepth] == this.stateStackTop - 1) {
+		this.valueLambdaNestDepth--;
+		this.scanner.ungetToken(this.currentToken);
+		this.currentToken = TokenNameElidedSemicolonAndRightBrace; // conjure a rabbit out of the hat ...
+		Expression exp = this.expressionStack[this.expressionPtr--];
+		this.expressionLengthPtr--;
+		pushOnAstStack(exp);
+	}
+}
+protected void consumeIdentifierOrNew(boolean newForm) {
+	// IdentifierOrNew ::= 'Identifier'
+	// IdentifierOrNew ::= 'new'
+	if (newForm) {
+		int newStart = this.intStack[this.intPtr--];
+		pushIdentifier(ConstantPool.Init, (((long) newStart << 32)) + (newStart + 2));
+	}
+}
+protected void consumeEmptyTypeArguments() {
+	// NonWildTypeArgumentsopt ::= $empty
+	pushOnGenericsLengthStack(0); // signal absence of type arguments.
+}
+protected void consumeReferenceExpressionTypeForm(boolean isPrimitive) { // actually Name or Type form.
+	
+	// ReferenceExpression ::= PrimitiveType Dims '::' NonWildTypeArgumentsopt IdentifierOrNew
+	// ReferenceExpression ::= Name Dimsopt '::' NonWildTypeArgumentsopt IdentifierOrNew
+
+	ReferenceExpression referenceExpression;
+	TypeReference [] typeArguments = null;
+	char [] selector;
+	int sourceEnd;
+
+	sourceEnd = (int) this.identifierPositionStack[this.identifierPtr];
+	selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (length > 0) {
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;  // pop type arguments source start.
+	}
+	
+	int dimension = this.intStack[this.intPtr--];
+	boolean typeAnnotatedName = false;
+	for (int i = this.identifierLengthStack[this.identifierLengthPtr], j = 0; i > 0 && this.typeAnnotationLengthPtr >= 0; --i, j++) {
+		length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr - j];
+		if (length != 0) {
+			typeAnnotatedName = true;
+			break;
+		}
+	}
+	
+	if (dimension > 0 || typeAnnotatedName) {
+		if (!isPrimitive) {
+			pushOnGenericsLengthStack(0);
+			pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+		}
+		referenceExpression = new ReferenceExpression(this.compilationUnit.compilationResult, getTypeReference(dimension), typeArguments, selector, sourceEnd);
+	} else {
+		referenceExpression = new ReferenceExpression(this.compilationUnit.compilationResult, getUnspecifiedReference(), typeArguments, selector, sourceEnd);
+	}
+	pushOnExpressionStack(referenceExpression);
+
+	if (!this.parsingJava8Plus) {
+		problemReporter().referenceExpressionsNotBelow18(referenceExpression);
+	}
+}
+protected void consumeReferenceExpressionPrimaryForm() {
+	// ReferenceExpression ::= Primary '::' NonWildTypeArgumentsopt Identifier
+
+	ReferenceExpression referenceExpression;
+	TypeReference [] typeArguments = null;
+	char [] selector;
+	int sourceEnd;
+
+	sourceEnd = (int) this.identifierPositionStack[this.identifierPtr];
+	selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (length > 0) {
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;  // pop type arguments source start.
+	}
+	
+	Expression primary = this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr--;
+	referenceExpression = new ReferenceExpression(this.compilationUnit.compilationResult, primary, typeArguments, selector, sourceEnd);
+	pushOnExpressionStack(referenceExpression);
+	if (!this.parsingJava8Plus) {
+		problemReporter().referenceExpressionsNotBelow18(referenceExpression);
+	}
+}
+protected void consumeReferenceExpressionSuperForm() {
+	// ReferenceExpression ::= 'super' '::' NonWildTypeArgumentsopt Identifier
+
+	ReferenceExpression referenceExpression;
+	TypeReference [] typeArguments = null;
+	char [] selector;
+	int sourceEnd;
+
+	sourceEnd = (int) this.identifierPositionStack[this.identifierPtr];
+	selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (length > 0) {
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;  // pop type arguments source start.
+	}
+	
+	SuperReference superReference = new SuperReference(this.intStack[this.intPtr--], this.endPosition);
+	referenceExpression = new ReferenceExpression(this.compilationUnit.compilationResult, superReference, typeArguments, selector, sourceEnd);
+	pushOnExpressionStack(referenceExpression);
+	if (!this.parsingJava8Plus) {
+		problemReporter().referenceExpressionsNotBelow18(referenceExpression);
+	}
+}
+protected void consumeReferenceExpressionTypeArgumentsAndTrunk(boolean qualified) {
+	// ReferenceExpressionTypeArgumentsAndTrunk ::= OnlyTypeArguments Dimsopt ==> qualified == false
+	// ReferenceExpressionTypeArgumentsAndTrunk ::= OnlyTypeArguments '.' ClassOrInterfaceType Dimsopt ==> qualified == true
+	pushOnIntStack(qualified ? 1 : 0);
+	pushOnIntStack(this.scanner.startPosition - 1); // mark position of :: as the end of type
+}
+protected void consumeReferenceExpressionGenericTypeForm() {
+
+	// ReferenceExpression ::= Name BeginTypeArguments ReferenceExpressionTypeArgumentsAndTrunk '::' NonWildTypeArgumentsopt IdentifierOrNew
+	
+	ReferenceExpression referenceExpression;
+	TypeReference type;
+	TypeReference [] typeArguments = null;
+	char [] selector;
+	int sourceEnd;
+
+	sourceEnd = (int) this.identifierPositionStack[this.identifierPtr];
+	selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	if (length > 0) {
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;  // pop type arguments source start.
+	}
+	
+	int typeSourceEnd = this.intStack[this.intPtr--];
+	boolean qualified = this.intStack[this.intPtr--] != 0;
+	int dims = this.intStack[this.intPtr--];
+	if (qualified) {
+		Annotation [][] annotationsOnDimensions = dims == 0 ? null : getAnnotationsOnDimensions(dims);
+		TypeReference rightSide = getTypeReference(0);
+		type = computeQualifiedGenericsFromRightSide(rightSide, dims, annotationsOnDimensions);
+	} else {		
+		pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+		type = getTypeReference(dims);
+	}
+	this.intPtr--; // pop '<' position
+	type.sourceEnd = typeSourceEnd;
+	
+	referenceExpression = new ReferenceExpression(this.compilationUnit.compilationResult, type, typeArguments, selector, sourceEnd);
+
+	pushOnExpressionStack(referenceExpression);
+	if (!this.parsingJava8Plus) {
+		problemReporter().referenceExpressionsNotBelow18(referenceExpression);
+	}
+}
+protected void consumeEnterInstanceCreationArgumentList() {
+	this.shouldDeferRecovery = true;
+}
+protected void consumeSimpleAssertStatement() {
+	// AssertStatement ::= 'assert' Expression ';'
+	this.expressionLengthPtr--;
+	pushOnAstStack(new AssertStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--]));
+}
+protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) {
+	// SingleMemberTypeAnnotation ::= TypeAnnotationName '(' SingleMemberAnnotationMemberValue ')'
+	// SingleMemberAnnotation ::= AnnotationName '(' SingleMemberAnnotationMemberValue ')'
+	SingleMemberAnnotation singleMemberAnnotation = null;
+
+	int oldIndex = this.identifierPtr;
+
+	TypeReference typeReference = getAnnotationType();
+	singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.intStack[this.intPtr--]);
+	singleMemberAnnotation.memberValue = this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr--;
+	singleMemberAnnotation.declarationSourceEnd = this.rParenPos;
+	
+	if (isTypeAnnotation) {
+		pushOnTypeAnnotationStack(singleMemberAnnotation);
+	} else {
+		pushOnExpressionStack(singleMemberAnnotation);
+	}
+
+	if(this.currentElement != null) {
+		annotationRecoveryCheckPoint(singleMemberAnnotation.sourceStart, singleMemberAnnotation.declarationSourceEnd);
+
+		if (this.currentElement instanceof RecoveredAnnotation) {
+			this.currentElement = ((RecoveredAnnotation)this.currentElement).addAnnotation(singleMemberAnnotation, oldIndex);
+		}
+	}
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		problemReporter().invalidUsageOfAnnotation(singleMemberAnnotation);
+	}
+	this.recordStringLiterals = true;
+}
+protected void consumeSingleMemberAnnotationMemberValue() {
+	// this rule is used for syntax recovery only
+	if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+		RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation) this.currentElement;
+
+		recoveredAnnotation.setKind(RecoveredAnnotation.SINGLE_MEMBER);
+	}
+
+}
+protected void consumeSingleResource() {
+	// Resources ::= Resource
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' Name RejectTypeAnnotations
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, false, ClassFileConstants.AccStatic));
+
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
+		problemReporter().invalidUsageOfStaticImports(impt);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeSingleTypeImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' Name
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, false, ClassFileConstants.AccDefault));
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeStatementBreak() {
+	// BreakStatement ::= 'break' ';'
+	// break pushes a position on this.intStack in case there is no label
+
+	pushOnAstStack(new BreakStatement(null, this.intStack[this.intPtr--], this.endStatementPosition));
+
+	if (this.pendingRecoveredType != null) {
+		// Used only in statements recovery.
+		// This is not a real break statement but a placeholder for an existing local type.
+		// The break statement must be replace by the local type.
+		if (this.pendingRecoveredType.allocation == null &&
+				this.endPosition <= this.pendingRecoveredType.declarationSourceEnd) {
+			this.astStack[this.astPtr] = this.pendingRecoveredType;
+			this.pendingRecoveredType = null;
+			return;
+		}
+		this.pendingRecoveredType = null;
+	}
+}
+protected void consumeStatementBreakWithLabel() {
+	// BreakStatement ::= 'break' Identifier ';'
+	// break pushs a position on this.intStack in case there is no label
+
+	pushOnAstStack(
+		new BreakStatement(
+			this.identifierStack[this.identifierPtr--],
+			this.intStack[this.intPtr--],
+			this.endStatementPosition));
+	this.identifierLengthPtr--;
+}
+protected void consumeStatementCatch() {
+	// CatchClause ::= 'catch' '(' FormalParameter ')'    Block
+
+	//catch are stored directly into the Try
+	//has they always comes two by two....
+	//we remove one entry from the astlengthPtr.
+	//The construction of the try statement must
+	//then fetch the catches using  2*i and 2*i + 1
+
+	this.astLengthPtr--;
+	this.listLength = 0; // reset formalParameter counter (incremented for catch variable)
+}
+protected void consumeStatementContinue() {
+	// ContinueStatement ::= 'continue' ';'
+	// continue pushs a position on this.intStack in case there is no label
+
+	pushOnAstStack(
+		new ContinueStatement(
+			null,
+			this.intStack[this.intPtr--],
+			this.endStatementPosition));
+}
+protected void consumeStatementContinueWithLabel() {
+	// ContinueStatement ::= 'continue' Identifier ';'
+	// continue pushs a position on this.intStack in case there is no label
+
+	pushOnAstStack(
+		new ContinueStatement(
+			this.identifierStack[this.identifierPtr--],
+			this.intStack[this.intPtr--],
+			this.endStatementPosition));
+	this.identifierLengthPtr--;
+}
+protected void consumeStatementDo() {
+	// DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
+
+	//the 'while' pushes a value on this.intStack that we need to remove
+	this.intPtr--;
+
+	Statement statement = (Statement) this.astStack[this.astPtr];
+	this.expressionLengthPtr--;
+	this.astStack[this.astPtr] =
+		new DoStatement(
+			this.expressionStack[this.expressionPtr--],
+			statement,
+			this.intStack[this.intPtr--],
+			this.endStatementPosition);
+}
+protected void consumeStatementExpressionList() {
+	// StatementExpressionList ::= StatementExpressionList ',' StatementExpression
+	concatExpressionLists();
+}
+protected void consumeStatementFor() {
+	// ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
+	// ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
+
+	int length;
+	Expression cond = null;
+	Statement[] inits, updates;
+	boolean scope = true;
+
+	//statements
+	this.astLengthPtr--;
+	Statement statement = (Statement) this.astStack[this.astPtr--];
+
+	//updates are on the expresion stack
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) == 0) {
+		updates = null;
+	} else {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			updates = new Statement[length],
+			0,
+			length);
+	}
+
+	if (this.expressionLengthStack[this.expressionLengthPtr--] != 0)
+		cond = this.expressionStack[this.expressionPtr--];
+
+	//inits may be on two different stacks
+	if ((length = this.astLengthStack[this.astLengthPtr--]) == 0) {
+		inits = null;
+		scope = false;
+	} else {
+		if (length == -1) { //on this.expressionStack
+			scope = false;
+			length = this.expressionLengthStack[this.expressionLengthPtr--];
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				inits = new Statement[length],
+				0,
+				length);
+		} else { //on this.astStack
+			this.astPtr -= length;
+			System.arraycopy(
+				this.astStack,
+				this.astPtr + 1,
+				inits = new Statement[length],
+				0,
+				length);
+		}
+	}
+	pushOnAstStack(
+		new ForStatement(
+			inits,
+			cond,
+			updates,
+			statement,
+			scope,
+			this.intStack[this.intPtr--],
+			this.endStatementPosition));
+}
+protected void consumeStatementIfNoElse() {
+	// IfThenStatement ::=  'if' '(' Expression ')' Statement
+
+	//optimize the push/pop
+	this.expressionLengthPtr--;
+	Statement thenStatement = (Statement) this.astStack[this.astPtr];
+	this.astStack[this.astPtr] =
+		new IfStatement(
+			this.expressionStack[this.expressionPtr--],
+			thenStatement,
+			this.intStack[this.intPtr--],
+			this.endStatementPosition);
+}
+protected void consumeStatementIfWithElse() {
+	// IfThenElseStatement ::=  'if' '(' Expression ')' StatementNoShortIf 'else' Statement
+	// IfThenElseStatementNoShortIf ::=  'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
+
+	this.expressionLengthPtr--;
+
+	// optimized {..., Then, Else } ==> {..., If }
+	this.astLengthPtr--;
+
+	//optimize the push/pop
+	this.astStack[--this.astPtr] =
+		new IfStatement(
+			this.expressionStack[this.expressionPtr--],
+			(Statement) this.astStack[this.astPtr],
+			(Statement) this.astStack[this.astPtr + 1],
+			this.intStack[this.intPtr--],
+			this.endStatementPosition);
+}
+protected void consumeStatementLabel() {
+	// LabeledStatement ::= 'Identifier' ':' Statement
+	// LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf
+
+	//optimize push/pop
+	Statement statement = (Statement) this.astStack[this.astPtr];
+	this.astStack[this.astPtr] =
+		new LabeledStatement(
+			this.identifierStack[this.identifierPtr],
+			statement,
+			this.identifierPositionStack[this.identifierPtr--],
+			this.endStatementPosition);
+	this.identifierLengthPtr--;
+}
+protected void consumeStatementReturn() {
+	// ReturnStatement ::= 'return' Expressionopt ';'
+	// return pushs a position on this.intStack in case there is no expression
+
+	if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) {
+		pushOnAstStack(
+			new ReturnStatement(
+				this.expressionStack[this.expressionPtr--],
+				this.intStack[this.intPtr--],
+				this.endStatementPosition)
+		);
+	} else {
+		pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endStatementPosition));
+	}
+}
+protected void consumeStatementSwitch() {
+	// SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
+
+	//OpenBlock just makes the semantic action blockStart()
+	//the block is inlined but a scope need to be created
+	//if some declaration occurs.
+
+	int length;
+	SwitchStatement switchStatement = new SwitchStatement();
+	this.expressionLengthPtr--;
+	switchStatement.expression = this.expressionStack[this.expressionPtr--];
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+		System.arraycopy(
+			this.astStack,
+			this.astPtr + 1,
+			switchStatement.statements = new Statement[length],
+			0,
+			length);
+	}
+	switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	pushOnAstStack(switchStatement);
+	switchStatement.blockStart = this.intStack[this.intPtr--];
+	switchStatement.sourceStart = this.intStack[this.intPtr--];
+	switchStatement.sourceEnd = this.endStatementPosition;
+	if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) {
+		switchStatement.bits |= ASTNode.UndocumentedEmptyBlock;
+	}
+}
+protected void consumeStatementSynchronized() {
+	// SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
+	//optimize the push/pop
+
+	if (this.astLengthStack[this.astLengthPtr] == 0) {
+		this.astLengthStack[this.astLengthPtr] = 1;
+		this.expressionLengthPtr--;
+		this.astStack[++this.astPtr] =
+			new SynchronizedStatement(
+				this.expressionStack[this.expressionPtr--],
+				null,
+				this.intStack[this.intPtr--],
+				this.endStatementPosition);
+	} else {
+		this.expressionLengthPtr--;
+		this.astStack[this.astPtr] =
+			new SynchronizedStatement(
+				this.expressionStack[this.expressionPtr--],
+				(Block) this.astStack[this.astPtr],
+				this.intStack[this.intPtr--],
+				this.endStatementPosition);
+	}
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+}
+protected void consumeStatementThrow() {
+	// ThrowStatement ::= 'throw' Expression ';'
+	this.expressionLengthPtr--;
+	pushOnAstStack(new ThrowStatement(this.expressionStack[this.expressionPtr--], this.intStack[this.intPtr--], this.endStatementPosition));
+}
+protected void consumeStatementTry(boolean withFinally, boolean hasResources) {
+	// TryStatement ::= 'try'  Block Catches
+	// TryStatement ::= 'try'  Block Catchesopt Finally
+	// TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt
+	// TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt Finally
+	
+	int length;
+	TryStatement tryStmt = new TryStatement();
+	//finally
+	if (withFinally) {
+		this.astLengthPtr--;
+		tryStmt.finallyBlock = (Block) this.astStack[this.astPtr--];
+	}
+	//catches are handle by two <argument-block> [see statementCatch]
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		if (length == 1) {
+			tryStmt.catchBlocks = new Block[] {(Block) this.astStack[this.astPtr--]};
+			tryStmt.catchArguments = new Argument[] {(Argument) this.astStack[this.astPtr--]};
+		} else {
+			Block[] bks = (tryStmt.catchBlocks = new Block[length]);
+			Argument[] args = (tryStmt.catchArguments = new Argument[length]);
+			while (length-- > 0) {
+				bks[length] = (Block) this.astStack[this.astPtr--];
+				args[length] = (Argument) this.astStack[this.astPtr--];
+			}
+		}
+	}
+	//try
+	this.astLengthPtr--;
+	tryStmt.tryBlock = (Block) this.astStack[this.astPtr--];
+
+	if (hasResources) {
+		// get the resources
+		length = this.astLengthStack[this.astLengthPtr--];
+		LocalDeclaration[] resources = new LocalDeclaration[length];
+		System.arraycopy(
+				this.astStack,
+				(this.astPtr -= length) + 1,
+				resources,
+				0,
+				length);
+		tryStmt.resources = resources;
+		if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+			problemReporter().autoManagedResourcesNotBelow17(resources);
+		}
+	}
+	//positions
+	tryStmt.sourceEnd = this.endStatementPosition;
+	tryStmt.sourceStart = this.intStack[this.intPtr--];
+	pushOnAstStack(tryStmt);
+}
+protected void consumeStatementWhile() {
+	// WhileStatement ::= 'while' '(' Expression ')' Statement
+	// WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
+
+	this.expressionLengthPtr--;
+	Statement statement = (Statement) this.astStack[this.astPtr];
+	this.astStack[this.astPtr] =
+		new WhileStatement(
+			this.expressionStack[this.expressionPtr--],
+			statement,
+			this.intStack[this.intPtr--],
+			this.endStatementPosition);
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	// StaticImportOnDemandDeclarationName ::= 'import' 'static' Name '.' RejectTypeAnnotations '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccStatic));
+
+	// star end position
+	impt.trailingStarPosition = this.intStack[this.intPtr--];
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
+		problemReporter().invalidUsageOfStaticImports(impt);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeStaticInitializer() {
+	// StaticInitializer ::=  StaticOnly Block
+	//push an Initializer
+	//optimize the push/pop
+	Block block = (Block) this.astStack[this.astPtr];
+	if (this.diet) block.bits &= ~ASTNode.UndocumentedEmptyBlock; // clear bit set since was diet
+	Initializer initializer = new Initializer(block, ClassFileConstants.AccStatic);
+	this.astStack[this.astPtr] = initializer;
+	initializer.sourceEnd = this.endStatementPosition;
+	initializer.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	this.nestedMethod[this.nestedType] --;
+	initializer.declarationSourceStart = this.intStack[this.intPtr--];
+	initializer.bodyStart = this.intStack[this.intPtr--];
+	initializer.bodyEnd = this.endPosition;
+	// doc comment
+	initializer.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = initializer.declarationSourceEnd;
+		this.currentElement = this.currentElement.add(initializer, 0);
+		this.lastIgnoredToken = -1;
+	}
+}
+protected void consumeStaticOnly() {
+	// StaticOnly ::= 'static'
+	int savedModifiersSourceStart = this.modifiersSourceStart;
+	checkComment(); // might update declaration source start
+	if (this.modifiersSourceStart >= savedModifiersSourceStart) {
+		this.modifiersSourceStart = savedModifiersSourceStart;
+	}
+	pushOnIntStack(this.scanner.currentPosition);
+	pushOnIntStack(
+		this.modifiersSourceStart >= 0 ? this.modifiersSourceStart : this.scanner.startPosition);
+	jumpOverMethodBody();
+	this.nestedMethod[this.nestedType]++;
+	resetModifiers();
+	this.expressionLengthPtr--; // remove the 0 pushed in consumeToken() for the static modifier
+
+	// recovery
+	if (this.currentElement != null){
+		this.recoveredStaticInitializerStart = this.intStack[this.intPtr]; // remember start position only for static initializers
+	}
+}
+protected void consumeSwitchBlock() {
+	// SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
+	concatNodeLists();
+}
+protected void consumeSwitchBlockStatement() {
+	// SwitchBlockStatement ::= SwitchLabels BlockStatements
+	concatNodeLists();
+}
+protected void consumeSwitchBlockStatements() {
+	// SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
+	concatNodeLists();
+}
+protected void consumeSwitchLabels() {
+	// SwitchLabels ::= SwitchLabels SwitchLabel
+	optimizedConcatNodeLists();
+}
+protected void consumeToken(int type) {
+	/* remember the last consumed value */
+	/* try to minimize the number of build values */
+//	// clear the commentPtr of the scanner in case we read something different from a modifier
+//	switch(type) {
+//		case TokenNameabstract :
+//		case TokenNamestrictfp :
+//		case TokenNamefinal :
+//		case TokenNamenative :
+//		case TokenNameprivate :
+//		case TokenNameprotected :
+//		case TokenNamepublic :
+//		case TokenNametransient :
+//		case TokenNamevolatile :
+//		case TokenNamestatic :
+//		case TokenNamesynchronized :
+//			break;
+//		default:
+//			this.scanner.commentPtr = -1;
+//	}
+	//System.out.println(this.scanner.toStringAction(type));
+	switch (type) {
+		case TokenNameIdentifier :
+			pushIdentifier();
+			if (this.scanner.useAssertAsAnIndentifier  &&
+					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+				long positions = this.identifierPositionStack[this.identifierPtr];
+				if(!this.statementRecoveryActivated) problemReporter().useAssertAsAnIdentifier((int) (positions >>> 32), (int) positions);
+			}
+			if (this.scanner.useEnumAsAnIndentifier  &&
+					this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+				long positions = this.identifierPositionStack[this.identifierPtr];
+				if(!this.statementRecoveryActivated) problemReporter().useEnumAsAnIdentifier((int) (positions >>> 32), (int) positions);
+			}
+			break;
+		case TokenNameinterface :
+			//'class' is pushing two int (positions) on the stack ==> 'interface' needs to do it too....
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameabstract :
+			checkAndSetModifiers(ClassFileConstants.AccAbstract);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamestrictfp :
+			checkAndSetModifiers(ClassFileConstants.AccStrictfp);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamefinal :
+			checkAndSetModifiers(ClassFileConstants.AccFinal);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamenative :
+			checkAndSetModifiers(ClassFileConstants.AccNative);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNameprivate :
+			checkAndSetModifiers(ClassFileConstants.AccPrivate);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNameprotected :
+			checkAndSetModifiers(ClassFileConstants.AccProtected);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamepublic :
+			checkAndSetModifiers(ClassFileConstants.AccPublic);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNametransient :
+			checkAndSetModifiers(ClassFileConstants.AccTransient);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamevolatile :
+			checkAndSetModifiers(ClassFileConstants.AccVolatile);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamestatic :
+			checkAndSetModifiers(ClassFileConstants.AccStatic);
+			pushOnExpressionStackLengthStack(0);
+			break;
+		case TokenNamesynchronized :
+			this.synchronizedBlockSourceStart = this.scanner.startPosition;
+			checkAndSetModifiers(ClassFileConstants.AccSynchronized);
+			pushOnExpressionStackLengthStack(0);
+			break;
+			//==============================
+		case TokenNamevoid :
+			pushIdentifier(-T_void);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+			//push a default dimension while void is not part of the primitive
+			//declaration baseType and so takes the place of a type without getting into
+			//regular type parsing that generates a dimension on this.intStack
+		case TokenNameboolean :
+			pushIdentifier(-T_boolean);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamebyte :
+			pushIdentifier(-T_byte);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamechar :
+			pushIdentifier(-T_char);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamedouble :
+			pushIdentifier(-T_double);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamefloat :
+			pushIdentifier(-T_float);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameint :
+			pushIdentifier(-T_int);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamelong :
+			pushIdentifier(-T_long);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameshort :
+			pushIdentifier(-T_short);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+			//==============================
+		case TokenNameIntegerLiteral :
+			pushOnExpressionStack(
+				IntLiteral.buildIntLiteral(
+					this.scanner.getCurrentTokenSource(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1));
+			break;
+		case TokenNameLongLiteral :
+			pushOnExpressionStack(
+				LongLiteral.buildLongLiteral(
+					this.scanner.getCurrentTokenSource(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1));
+			break;
+		case TokenNameFloatingPointLiteral :
+			pushOnExpressionStack(
+				new FloatLiteral(
+					this.scanner.getCurrentTokenSource(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1));
+			break;
+		case TokenNameDoubleLiteral :
+			pushOnExpressionStack(
+				new DoubleLiteral(
+					this.scanner.getCurrentTokenSource(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1));
+			break;
+		case TokenNameCharacterLiteral :
+			pushOnExpressionStack(
+				new CharLiteral(
+					this.scanner.getCurrentTokenSource(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1));
+			break;
+		case TokenNameStringLiteral :
+			StringLiteral stringLiteral;
+			if (this.recordStringLiterals &&
+					this.checkExternalizeStrings &&
+					this.lastPosistion < this.scanner.currentPosition &&
+					!this.statementRecoveryActivated) {
+				stringLiteral = createStringLiteral(
+					this.scanner.getCurrentTokenSourceString(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1,
+					Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr));
+				this.compilationUnit.recordStringLiteral(stringLiteral, this.currentElement != null);
+			} else {
+				stringLiteral = createStringLiteral(
+					this.scanner.getCurrentTokenSourceString(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1,
+					0);
+			}
+			pushOnExpressionStack(stringLiteral);
+			break;
+		case TokenNamefalse :
+			pushOnExpressionStack(
+				new FalseLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
+			break;
+		case TokenNametrue :
+			pushOnExpressionStack(
+				new TrueLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
+			break;
+		case TokenNamenull :
+			pushOnExpressionStack(
+				new NullLiteral(this.scanner.startPosition, this.scanner.currentPosition - 1));
+			break;
+			//============================
+		case TokenNamesuper :
+		case TokenNamethis :
+			this.endPosition = this.scanner.currentPosition - 1;
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameassert :
+		case TokenNameimport :
+		case TokenNamepackage :
+		case TokenNamethrow :
+		case TokenNamedo :
+		case TokenNameif :
+		case TokenNamefor :
+		case TokenNameswitch :
+		case TokenNametry :
+		case TokenNamewhile :
+		case TokenNamebreak :
+		case TokenNamecontinue :
+		case TokenNamereturn :
+		case TokenNamecase :
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamenew :
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954
+			resetModifiers();
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameclass :
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameenum :
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNamedefault :
+			pushOnIntStack(this.scanner.startPosition);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			break;
+			//let extra semantic action decide when to push
+		case TokenNameRBRACKET :
+			this.endPosition = this.scanner.startPosition;
+			this.endStatementPosition = this.scanner.currentPosition - 1;
+			break;
+		case TokenNameLBRACE :
+			this.endStatementPosition = this.scanner.currentPosition - 1;
+			//$FALL-THROUGH$
+		case TokenNamePLUS :
+		case TokenNameMINUS :
+		case TokenNameNOT :
+		case TokenNameTWIDDLE :
+			this.endPosition = this.scanner.startPosition;
+			break;
+		case TokenNamePLUS_PLUS :
+		case TokenNameMINUS_MINUS :
+			this.endPosition = this.scanner.startPosition;
+			this.endStatementPosition = this.scanner.currentPosition - 1;
+			break;
+		case TokenNameRBRACE:
+		case TokenNameSEMICOLON :
+			this.endStatementPosition = this.scanner.currentPosition - 1;
+			this.endPosition = this.scanner.startPosition - 1;
+			//the item is not part of the potential futur expression/statement
+			break;
+		case TokenNameRPAREN :
+			// in order to handle ( expression) ////// (cast)expression///// foo(x)
+			this.rParenPos = this.scanner.currentPosition - 1; // position of the end of right parenthesis (in case of unicode \u0029) lex00101
+			break;
+		case TokenNameLPAREN :
+			this.lParenPos = this.scanner.startPosition;
+			break;
+		case TokenNameAT308:
+		case TokenNameAT :
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameQUESTION  :
+			pushOnIntStack(this.scanner.startPosition);
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			break;
+		case TokenNameLESS :
+			pushOnIntStack(this.scanner.startPosition);
+			break;
+		case TokenNameELLIPSIS :
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			break;
+		case TokenNameEQUAL  :
+			if (this.currentElement != null && this.currentElement instanceof RecoveredAnnotation) {
+				RecoveredAnnotation recoveredAnnotation = (RecoveredAnnotation) this.currentElement;
+				if (recoveredAnnotation.memberValuPairEqualEnd == -1) {
+					recoveredAnnotation.memberValuPairEqualEnd = this.scanner.currentPosition - 1;
+				}
+			}
+			break;
+		case TokenNameMULTIPLY :
+			// star end position
+			pushOnIntStack(this.scanner.currentPosition - 1);
+			break;
+			//  case TokenNameCOMMA :
+			//  case TokenNameCOLON  :
+			//  case TokenNameLBRACKET  :
+			//  case TokenNameDOT :
+			//  case TokenNameERROR :
+			//  case TokenNameEOF  :
+			//  case TokenNamecase  :
+			//  case TokenNamecatch  :
+			//  case TokenNameelse  :
+			//  case TokenNameextends  :
+			//  case TokenNamefinally  :
+			//  case TokenNameimplements  :
+			//  case TokenNamethrows  :
+			//  case TokenNameinstanceof  :
+			//  case TokenNameEQUAL_EQUAL  :
+			//  case TokenNameLESS_EQUAL  :
+			//  case TokenNameGREATER_EQUAL  :
+			//  case TokenNameNOT_EQUAL  :
+			//  case TokenNameLEFT_SHIFT  :
+			//  case TokenNameRIGHT_SHIFT  :
+			//  case TokenNameUNSIGNED_RIGHT_SHIFT :
+			//  case TokenNamePLUS_EQUAL  :
+			//  case TokenNameMINUS_EQUAL  :
+			//  case TokenNameMULTIPLY_EQUAL  :
+			//  case TokenNameDIVIDE_EQUAL  :
+			//  case TokenNameAND_EQUAL  :
+			//  case TokenNameOR_EQUAL  :
+			//  case TokenNameXOR_EQUAL  :
+			//  case TokenNameREMAINDER_EQUAL  :
+			//  case TokenNameLEFT_SHIFT_EQUAL  :
+			//  case TokenNameRIGHT_SHIFT_EQUAL  :
+			//  case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL  :
+			//  case TokenNameOR_OR  :
+			//  case TokenNameAND_AND  :
+			//  case TokenNameREMAINDER :
+			//  case TokenNameXOR  :
+			//  case TokenNameAND  :
+			//  case TokenNameMULTIPLY :
+			//  case TokenNameOR  :
+			//  case TokenNameDIVIDE :
+			//  case TokenNameGREATER  :
+	}
+}
+protected void consumeTypeArgument() {
+	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
+}
+protected void consumeTypeArgumentList() {
+	concatGenericsLists();
+}
+protected void consumeTypeArgumentList1() {
+	concatGenericsLists();
+}
+protected void consumeTypeArgumentList2() {
+	concatGenericsLists();
+}
+protected void consumeTypeArgumentList3() {
+	concatGenericsLists();
+}
+protected void consumeTypeArgumentReferenceType1() {
+	concatGenericsLists();
+	pushOnGenericsStack(getTypeReference(0));
+	this.intPtr--; // pop '<' position.
+}
+protected void consumeTypeArgumentReferenceType2() {
+	concatGenericsLists();
+	pushOnGenericsStack(getTypeReference(0));
+	this.intPtr--;
+}
+protected void consumeTypeArguments() {
+	concatGenericsLists();
+	this.intPtr--;
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		problemReporter().invalidUsageOfTypeArguments(
+			(TypeReference)this.genericsStack[this.genericsPtr - length + 1],
+			(TypeReference)this.genericsStack[this.genericsPtr]);
+	}
+}
+protected void consumeTypeDeclarations() {
+	// TypeDeclarations ::= TypeDeclarations TypeDeclaration
+	concatNodeLists();
+}
+protected void consumeTypeHeaderNameWithTypeParameters() {
+	// ClassHeaderName ::= ClassHeaderName1 TypeParameters
+	// InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters
+	TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
+
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
+
+	typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
+
+	this.listTypeParameterLength = 0;
+
+	if (this.currentElement != null) {
+		// is recovering
+		if (this.currentElement instanceof RecoveredType) {
+			RecoveredType recoveredType = (RecoveredType) this.currentElement;
+			recoveredType.pendingTypeParameters = null;
+			this.lastCheckPoint = typeDecl.bodyStart;
+		} else {
+			this.lastCheckPoint = typeDecl.bodyStart;
+			this.currentElement = this.currentElement.add(typeDecl, 0);
+			this.lastIgnoredToken = -1;
+		}
+	}
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' RejectTypeAnnotations '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccDefault));
+
+	// star end position
+	impt.trailingStarPosition = this.intStack[this.intPtr--];
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+}
+protected void consumeTypeParameter1() {
+	// nothing to do
+}
+protected void consumeTypeParameter1WithExtends() {
+	//TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType1
+	TypeReference superType = (TypeReference) this.genericsStack[this.genericsPtr--];
+	this.genericsLengthPtr--;
+	TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+	typeParameter.declarationSourceEnd = superType.sourceEnd;
+	typeParameter.type = superType;
+	superType.bits |= ASTNode.IsSuperType;
+	typeParameter.bits |= (superType.bits & ASTNode.HasTypeAnnotations);
+	this.genericsStack[this.genericsPtr] = typeParameter;
+}
+protected void consumeTypeParameter1WithExtendsAndBounds() {
+	//TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList1
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	TypeReference[] bounds = new TypeReference[additionalBoundsLength];
+	this.genericsPtr -= additionalBoundsLength;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 0, additionalBoundsLength);
+	TypeReference superType = getTypeReference(this.intStack[this.intPtr--]);
+	TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+	typeParameter.declarationSourceEnd = bounds[additionalBoundsLength - 1].sourceEnd;
+	typeParameter.type = superType;
+	typeParameter.bits |= (superType.bits & ASTNode.HasTypeAnnotations);
+	superType.bits |= ASTNode.IsSuperType;
+	typeParameter.bounds = bounds;
+	for (int i = 0, max = bounds.length; i < max; i++) {
+		TypeReference bound = bounds[i];
+		bound.bits |= ASTNode.IsSuperType;
+		typeParameter.bits |= (bound.bits & ASTNode.HasTypeAnnotations);
+	}
+}
+protected void consumeTypeParameterHeader() {
+	//TypeParameterHeader ::= TypeAnnotationsopt Identifier
+	TypeParameter typeParameter = new TypeParameter();
+	int length;
+	if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+		System.arraycopy(
+				this.typeAnnotationStack,
+				(this.typeAnnotationPtr -= length) + 1,
+				typeParameter.annotations = new Annotation[length],
+				0,
+				length);
+		typeParameter.bits |= ASTNode.HasTypeAnnotations;
+	}
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	final int end = (int) pos;
+	typeParameter.declarationSourceEnd = end;
+	typeParameter.sourceEnd = end;
+	final int start = (int) (pos >>> 32);
+	typeParameter.declarationSourceStart = start;
+	typeParameter.sourceStart = start;
+	typeParameter.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	pushOnGenericsStack(typeParameter);
+
+	this.listTypeParameterLength++;
+}
+protected void consumeTypeParameterList() {
+	//TypeParameterList ::= TypeParameterList ',' TypeParameter
+	concatGenericsLists();
+}
+protected void consumeTypeParameterList1() {
+	//TypeParameterList1 ::= TypeParameterList ',' TypeParameter1
+	concatGenericsLists();
+}
+protected void consumeTypeParameters() {
+	int startPos = this.intStack[this.intPtr--];
+
+	if(this.currentElement != null) {
+		if(this.currentElement instanceof RecoveredType) {
+			RecoveredType recoveredType =(RecoveredType) this.currentElement;
+			int length = this.genericsLengthStack[this.genericsLengthPtr];
+			TypeParameter[] typeParameters = new TypeParameter[length];
+			System.arraycopy(this.genericsStack, this.genericsPtr - length + 1, typeParameters, 0, length);
+
+			recoveredType.add(typeParameters, startPos);
+		}
+	}
+
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5&&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		problemReporter().invalidUsageOfTypeParameters(
+			(TypeParameter) this.genericsStack[this.genericsPtr - length + 1],
+			(TypeParameter) this.genericsStack[this.genericsPtr]);
+	}
+}
+protected void consumeTypeParameterWithExtends() {
+	//TypeParameter ::= TypeParameterHeader 'extends' ReferenceType
+	TypeReference superType = getTypeReference(this.intStack[this.intPtr--]);
+	TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+	typeParameter.declarationSourceEnd = superType.sourceEnd;
+	typeParameter.type = superType;
+	typeParameter.bits |= (superType.bits & ASTNode.HasTypeAnnotations);
+	superType.bits |= ASTNode.IsSuperType;
+}
+protected void consumeTypeParameterWithExtendsAndBounds() {
+	//TypeParameter ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList
+	int additionalBoundsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+	TypeReference[] bounds = new TypeReference[additionalBoundsLength];
+	this.genericsPtr -= additionalBoundsLength;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, bounds, 0, additionalBoundsLength);
+	TypeReference superType = getTypeReference(this.intStack[this.intPtr--]);
+	TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+	typeParameter.type = superType;
+	typeParameter.bits |= (superType.bits & ASTNode.HasTypeAnnotations);
+	superType.bits |= ASTNode.IsSuperType;
+	typeParameter.bounds = bounds;
+	typeParameter.declarationSourceEnd = bounds[additionalBoundsLength - 1].sourceEnd;
+	for (int i = 0, max = bounds.length; i < max; i++) {
+		TypeReference bound = bounds[i];
+		bound.bits |= ASTNode.IsSuperType;
+		typeParameter.bits |= (bound.bits & ASTNode.HasTypeAnnotations);
+	}
+}
+protected void consumeZeroAdditionalBounds() {
+	if (this.currentToken == TokenNameRPAREN)  // Signal zero additional bounds - do this only when the cast type is fully seen (i.e not in error path)
+		pushOnGenericsLengthStack(0);          // Not all stacks are adjusted - this is not meant to be popped by getTypeReference
+}
+protected void consumeUnaryExpression(int op) {
+	// UnaryExpression ::= '+' PushPosition UnaryExpression
+	// UnaryExpression ::= '-' PushPosition UnaryExpression
+	// UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
+	// UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
+
+	//optimize the push/pop
+
+	//handle manually the -2147483648 while it is not a real
+	//computation of an - and 2147483648 (notice that 2147483648
+	//is Integer.MAX_VALUE+1.....)
+	//Same for -9223372036854775808L ............
+
+	//this.intStack have the position of the operator
+
+	Expression r, exp = this.expressionStack[this.expressionPtr];
+	if (op == MINUS) {
+		if (exp instanceof IntLiteral) {
+			IntLiteral intLiteral = (IntLiteral) exp;
+			IntLiteral convertToMinValue = intLiteral.convertToMinValue();
+			if (convertToMinValue ==  intLiteral) {
+				// not a min value literal so we convert it to an unary expression
+				r = new UnaryExpression(exp, op);
+			} else {
+				r = convertToMinValue;
+			}
+		} else if (exp instanceof LongLiteral) {
+			LongLiteral longLiteral = (LongLiteral) exp;
+			LongLiteral convertToMinValue = longLiteral.convertToMinValue();
+			if (convertToMinValue ==  longLiteral) {
+				// not a min value literal so we convert it to an unary expression
+				r = new UnaryExpression(exp, op);
+			} else {
+				r = convertToMinValue;
+			}
+		} else {
+			r = new UnaryExpression(exp, op);
+		}
+	} else {
+		r = new UnaryExpression(exp, op);
+	}
+	r.sourceStart = this.intStack[this.intPtr--];
+	r.sourceEnd = exp.sourceEnd;
+	this.expressionStack[this.expressionPtr] = r;
+}
+protected void consumeUnaryExpression(int op, boolean post) {
+	// PreIncrementExpression ::= '++' PushPosition UnaryExpression
+	// PreDecrementExpression ::= '--' PushPosition UnaryExpression
+
+	// ++ and -- operators
+	//optimize the push/pop
+
+	//this.intStack has the position of the operator when prefix
+
+	Expression leftHandSide = this.expressionStack[this.expressionPtr];
+	if (leftHandSide instanceof Reference) {
+		// ++foo()++ is unvalid
+		if (post) {
+			this.expressionStack[this.expressionPtr] =
+				new PostfixExpression(
+					leftHandSide,
+					IntLiteral.One,
+					op,
+					this.endStatementPosition);
+		} else {
+			this.expressionStack[this.expressionPtr] =
+				new PrefixExpression(
+					leftHandSide,
+					IntLiteral.One,
+					op,
+					this.intStack[this.intPtr--]);
+		}
+	} else {
+		//the ++ or the -- is NOT taken into account if code gen proceeds
+		if (!post) {
+			this.intPtr--;
+		}
+		if(!this.statementRecoveryActivated) problemReporter().invalidUnaryExpression(leftHandSide);
+	}
+}
+protected void consumeVariableDeclarators() {
+	// VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
+	optimizedConcatNodeLists();
+}
+protected void consumeVariableInitializers() {
+	// VariableInitializers ::= VariableInitializers ',' VariableInitializer
+	concatExpressionLists();
+}
+protected void consumeWildcard() {
+	final Wildcard wildcard = new Wildcard(Wildcard.UNBOUND);
+	wildcard.sourceEnd = this.intStack[this.intPtr--];
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcard1() {
+	final Wildcard wildcard = new Wildcard(Wildcard.UNBOUND);
+	wildcard.sourceEnd = this.intStack[this.intPtr--];
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcard1WithBounds() {
+	// Nothing to do
+	// The wildcard is created by the consumeWildcardBounds1Extends or by consumeWildcardBounds1Super
+}
+protected void consumeWildcard2() {
+	final Wildcard wildcard = new Wildcard(Wildcard.UNBOUND);
+	wildcard.sourceEnd = this.intStack[this.intPtr--];
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcard2WithBounds() {
+	// Nothing to do
+	// The wildcard is created by the consumeWildcardBounds2Extends or by consumeWildcardBounds2Super
+}
+protected void consumeWildcard3() {
+	final Wildcard wildcard = new Wildcard(Wildcard.UNBOUND);
+	wildcard.sourceEnd = this.intStack[this.intPtr--];
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcard3WithBounds() {
+	// Nothing to do
+	// The wildcard is created by the consumeWildcardBounds3Extends or by consumeWildcardBounds3Super
+}
+protected void consumeWildcardBounds1Extends() {
+	Wildcard wildcard = new Wildcard(Wildcard.EXTENDS);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBounds1Super() {
+	Wildcard wildcard = new Wildcard(Wildcard.SUPER);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	this.intPtr--; // remove the starting position of the super keyword
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBounds2Extends() {
+	Wildcard wildcard = new Wildcard(Wildcard.EXTENDS);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBounds2Super() {
+	Wildcard wildcard = new Wildcard(Wildcard.SUPER);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	this.intPtr--; // remove the starting position of the super keyword
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBounds3Extends() {
+	Wildcard wildcard = new Wildcard(Wildcard.EXTENDS);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBounds3Super() {
+	Wildcard wildcard = new Wildcard(Wildcard.SUPER);
+	wildcard.bound = (TypeReference) this.genericsStack[this.genericsPtr];
+	this.intPtr--; // remove the starting position of the super keyword
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	this.genericsStack[this.genericsPtr] = wildcard;
+}
+protected void consumeWildcardBoundsExtends() {
+	Wildcard wildcard = new Wildcard(Wildcard.EXTENDS);
+	wildcard.bound = getTypeReference(this.intStack[this.intPtr--]);
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcardBoundsSuper() {
+	Wildcard wildcard = new Wildcard(Wildcard.SUPER);
+	wildcard.bound = getTypeReference(this.intStack[this.intPtr--]);
+	this.intPtr--; // remove the starting position of the super keyword
+	wildcard.sourceEnd = wildcard.bound.sourceEnd;
+	this.intPtr--; // remove end position of the '?'
+	wildcard.sourceStart = this.intStack[this.intPtr--];
+	annotateTypeReference(wildcard);
+	pushOnGenericsStack(wildcard);
+}
+protected void consumeWildcardWithBounds() {
+	// Nothing to do
+	// The wildcard is created by the consumeWildcardBoundsExtends or by consumeWildcardBoundsSuper
+}
+/**
+ * Given the current comment stack, answer whether some comment is available in a certain exclusive range
+ *
+ * @param sourceStart int
+ * @param sourceEnd int
+ * @return boolean
+ */
+public boolean containsComment(int sourceStart, int sourceEnd) {
+	int iComment = this.scanner.commentPtr;
+	for (; iComment >= 0; iComment--) {
+		int commentStart = this.scanner.commentStarts[iComment];
+		if (commentStart < 0) commentStart = -commentStart;
+		// ignore comments before start
+		if (commentStart < sourceStart) continue;
+		// ignore comments after end
+		if (commentStart > sourceEnd) continue;
+		return true;
+	}
+	return false;
+}
+
+public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
+	MethodDeclaration m = new MethodDeclaration(compilationResult);
+	m.typeParameters = c.typeParameters;
+	m.sourceStart = c.sourceStart;
+	m.sourceEnd = c.sourceEnd;
+	m.bodyStart = c.bodyStart;
+	m.bodyEnd = c.bodyEnd;
+	m.declarationSourceEnd = c.declarationSourceEnd;
+	m.declarationSourceStart = c.declarationSourceStart;
+	m.selector = c.selector;
+	m.statements = c.statements;
+	m.modifiers = c.modifiers;
+	m.annotations = c.annotations;
+	m.arguments = c.arguments;
+	m.thrownExceptions = c.thrownExceptions;
+	m.explicitDeclarations = c.explicitDeclarations;
+	m.returnType = null;
+	m.javadoc = c.javadoc;
+	m.bits = c.bits;
+	return m;
+}
+
+protected TypeReference copyDims(TypeReference typeRef, int dim) {
+	return typeRef.copyDims(dim);
+}
+
+protected TypeReference copyDims(TypeReference typeRef, int dim, Annotation[][]annotationsOnDimensions) {
+	return typeRef.copyDims(dim, annotationsOnDimensions);
+}
+
+protected FieldDeclaration createFieldDeclaration(char[] fieldDeclarationName, int sourceStart, int sourceEnd) {
+	return new FieldDeclaration(fieldDeclarationName, sourceStart, sourceEnd);
+}
+protected JavadocParser createJavadocParser() {
+	return new JavadocParser(this);
+}
+protected LocalDeclaration createLocalDeclaration(char[] localDeclarationName, int sourceStart, int sourceEnd) {
+	return new LocalDeclaration(localDeclarationName, sourceStart, sourceEnd);
+}
+protected StringLiteral createStringLiteral(char[] token, int start, int end, int lineNumber) {
+	return new StringLiteral(token, start, end, lineNumber);
+}
+protected RecoveredType currentRecoveryType() {
+	if(this.currentElement != null) {
+		if(this.currentElement instanceof RecoveredType) {
+			return (RecoveredType) this.currentElement;
+		} else {
+			return this.currentElement.enclosingType();
+		}
+	}
+	return null;
+}
+public CompilationUnitDeclaration dietParse(ICompilationUnit sourceUnit, CompilationResult compilationResult) {
+
+	CompilationUnitDeclaration parsedUnit;
+	boolean old = this.diet;
+	try {
+		this.diet = true;
+		parsedUnit = parse(sourceUnit, compilationResult);
+	} finally {
+		this.diet = old;
+	}
+	return parsedUnit;
+}
+protected void dispatchDeclarationInto(int length) {
+	/* they are length on this.astStack that should go into
+	   methods fields constructors lists of the typeDecl
+
+	   Return if there is a constructor declaration in the methods declaration */
+
+
+	// Looks for the size of each array .
+
+	if (length == 0)
+		return;
+	int[] flag = new int[length + 1]; //plus one -- see <HERE>
+	int size1 = 0, size2 = 0, size3 = 0;
+	boolean hasAbstractMethods = false;
+	for (int i = length - 1; i >= 0; i--) {
+		ASTNode astNode = this.astStack[this.astPtr--];
+		if (astNode instanceof AbstractMethodDeclaration) {
+			//methods and constructors have been regrouped into one single list
+			flag[i] = 2;
+			size2++;
+			if (((AbstractMethodDeclaration) astNode).isAbstract()) {
+				hasAbstractMethods = true;
+			}
+		} else if (astNode instanceof TypeDeclaration) {
+			flag[i] = 3;
+			size3++;
+		} else {
+			//field
+			flag[i] = 1;
+			size1++;
+		}
+	}
+
+	//arrays creation
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	if (size1 != 0) {
+		typeDecl.fields = new FieldDeclaration[size1];
+	}
+	if (size2 != 0) {
+		typeDecl.methods = new AbstractMethodDeclaration[size2];
+		if (hasAbstractMethods) typeDecl.bits |= ASTNode.HasAbstractMethods;
+	}
+	if (size3 != 0) {
+		typeDecl.memberTypes = new TypeDeclaration[size3];
+	}
+
+	//arrays fill up
+	size1 = size2 = size3 = 0;
+	int flagI = flag[0], start = 0;
+	int length2;
+	for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
+		{
+		if (flagI != flag[end]) //treat the last element as a ended flag.....
+			{ //array copy
+			switch (flagI) {
+				case 1 :
+					size1 += (length2 = end - start);
+					System.arraycopy(
+						this.astStack,
+						this.astPtr + start + 1,
+						typeDecl.fields,
+						size1 - length2,
+						length2);
+					break;
+				case 2 :
+					size2 += (length2 = end - start);
+					System.arraycopy(
+						this.astStack,
+						this.astPtr + start + 1,
+						typeDecl.methods,
+						size2 - length2,
+						length2);
+					break;
+				case 3 :
+					size3 += (length2 = end - start);
+					System.arraycopy(
+						this.astStack,
+						this.astPtr + start + 1,
+						typeDecl.memberTypes,
+						size3 - length2,
+						length2);
+					break;
+			}
+			flagI = flag[start = end];
+		}
+	}
+
+	if (typeDecl.memberTypes != null) {
+		for (int i = typeDecl.memberTypes.length - 1; i >= 0; i--) {
+			typeDecl.memberTypes[i].enclosingType = typeDecl;
+		}
+	}
+}
+protected void dispatchDeclarationIntoEnumDeclaration(int length) {
+
+	if (length == 0)
+		return;
+	int[] flag = new int[length + 1]; //plus one -- see <HERE>
+	int size1 = 0, size2 = 0, size3 = 0;
+	TypeDeclaration enumDeclaration = (TypeDeclaration) this.astStack[this.astPtr - length];
+	boolean hasAbstractMethods = false;
+	int enumConstantsCounter = 0;
+	for (int i = length - 1; i >= 0; i--) {
+		ASTNode astNode = this.astStack[this.astPtr--];
+		if (astNode instanceof AbstractMethodDeclaration) {
+			//methods and constructors have been regrouped into one single list
+			flag[i] = 2;
+			size2++;
+			if (((AbstractMethodDeclaration) astNode).isAbstract()) {
+				hasAbstractMethods = true;
+			}
+		} else if (astNode instanceof TypeDeclaration) {
+			flag[i] = 3;
+			size3++;
+		} else if (astNode instanceof FieldDeclaration) {
+			flag[i] = 1;
+			size1++;
+			if (((FieldDeclaration) astNode).getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+				enumConstantsCounter++;
+			}
+		}
+	}
+
+	//arrays creation
+	if (size1 != 0) {
+		enumDeclaration.fields = new FieldDeclaration[size1];
+	}
+	if (size2 != 0) {
+		enumDeclaration.methods = new AbstractMethodDeclaration[size2];
+		if (hasAbstractMethods) enumDeclaration.bits |= ASTNode.HasAbstractMethods;
+	}
+	if (size3 != 0) {
+		enumDeclaration.memberTypes = new TypeDeclaration[size3];
+	}
+
+	//arrays fill up
+	size1 = size2 = size3 = 0;
+	int flagI = flag[0], start = 0;
+	int length2;
+	for (int end = 0; end <= length; end++) //<HERE> the plus one allows to
+	{
+		if (flagI != flag[end]) //treat the last element as a ended flag.....
+		{ //array copy
+			switch (flagI) {
+				case 1 :
+					size1 += (length2 = end - start);
+					System.arraycopy(
+							this.astStack,
+							this.astPtr + start + 1,
+							enumDeclaration.fields,
+							size1 - length2,
+							length2);
+					break;
+				case 2 :
+					size2 += (length2 = end - start);
+					System.arraycopy(
+							this.astStack,
+							this.astPtr + start + 1,
+							enumDeclaration.methods,
+							size2 - length2,
+							length2);
+					break;
+				case 3 :
+					size3 += (length2 = end - start);
+					System.arraycopy(
+							this.astStack,
+							this.astPtr + start + 1,
+							enumDeclaration.memberTypes,
+							size3 - length2,
+							length2);
+					break;
+			}
+			flagI = flag[start = end];
+		}
+	}
+
+	if (enumDeclaration.memberTypes != null) {
+		for (int i = enumDeclaration.memberTypes.length - 1; i >= 0; i--) {
+			enumDeclaration.memberTypes[i].enclosingType = enumDeclaration;
+		}
+	}
+	enumDeclaration.enumConstantsCounter = enumConstantsCounter;
+}
+protected CompilationUnitDeclaration endParse(int act) {
+
+	this.lastAct = act;
+
+	if(this.statementRecoveryActivated) {
+		RecoveredElement recoveredElement = buildInitialRecoveryState();
+
+		if (recoveredElement != null) {
+			recoveredElement.topElement().updateParseTree();
+		}
+
+		if(this.hasError) resetStacks();
+	} else if (this.currentElement != null){
+		if (VERBOSE_RECOVERY){
+			System.out.print(Messages.parser_syntaxRecovery);
+			System.out.println("--------------------------");		 //$NON-NLS-1$
+			System.out.println(this.compilationUnit);
+			System.out.println("----------------------------------"); //$NON-NLS-1$
+		}
+		this.currentElement.topElement().updateParseTree();
+	} else {
+		if (this.diet & VERBOSE_RECOVERY){
+			System.out.print(Messages.parser_regularParse);
+			System.out.println("--------------------------");	 //$NON-NLS-1$
+			System.out.println(this.compilationUnit);
+			System.out.println("----------------------------------"); //$NON-NLS-1$
+		}
+	}
+	persistLineSeparatorPositions();
+	for (int i = 0; i < this.scanner.foundTaskCount; i++){
+		if(!this.statementRecoveryActivated) problemReporter().task(
+			new String(this.scanner.foundTaskTags[i]),
+			new String(this.scanner.foundTaskMessages[i]),
+			this.scanner.foundTaskPriorities[i] == null ? null : new String(this.scanner.foundTaskPriorities[i]),
+			this.scanner.foundTaskPositions[i][0],
+			this.scanner.foundTaskPositions[i][1]);
+	}
+	this.javadoc = null;
+	return this.compilationUnit;
+}
+/*
+ * Flush comments defined prior to a given positions.
+ *
+ * Note: comments are stacked in syntactical order
+ *
+ * Either answer given <position>, or the end position of a comment line
+ * immediately following the <position> (same line)
+ *
+ * e.g.
+ * void foo(){
+ * } // end of method foo
+ */
+public int flushCommentsDefinedPriorTo(int position) {
+
+	int lastCommentIndex = this.scanner.commentPtr;
+	if (lastCommentIndex < 0) return position; // no comment
+
+	// compute the index of the first obsolete comment
+	int index = lastCommentIndex;
+	int validCount = 0;
+	while (index >= 0){
+		int commentEnd = this.scanner.commentStops[index];
+		if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
+		if (commentEnd <= position){
+			break;
+		}
+		index--;
+		validCount++;
+	}
+	// if the source at <position> is immediately followed by a line comment, then
+	// flush this comment and shift <position> to the comment end.
+	if (validCount > 0){
+		int immediateCommentEnd = -this.scanner.commentStops[index+1]; //non-javadoc comment end positions are negative
+		if (immediateCommentEnd > 0){ // only tolerating non-javadoc comments
+			// is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
+			immediateCommentEnd--; // comment end in one char too far
+			if (Util.getLineNumber(position, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(immediateCommentEnd, this.scanner.lineEnds, 0, this.scanner.linePtr)){
+				position = immediateCommentEnd;
+				validCount--; // flush this comment
+				index++;
+			}
+		}
+	}
+
+	if (index < 0) return position; // no obsolete comment
+
+	switch (validCount) {
+		case 0:
+			// do nothing
+			break;
+		// move valid comment infos, overriding obsolete comment infos
+		case 2:
+			this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+			this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+			this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+			this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2];
+			this.scanner.commentStops[1] = this.scanner.commentStops[index+2];
+			this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2];
+			break;
+		case 1:
+			this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+			this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+			this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+			break;
+		default:
+			System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
+			System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);
+			System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount);
+	}
+	this.scanner.commentPtr = validCount - 1;
+	return position;
+}
+
+protected TypeReference getAnnotationType() {
+	int length = this.identifierLengthStack[this.identifierLengthPtr--];
+	if (length == 1) {
+		return new SingleTypeReference(
+				this.identifierStack[this.identifierPtr],
+				this.identifierPositionStack[this.identifierPtr--]);
+	} else {
+		char[][] tokens = new char[length][];
+		this.identifierPtr -= length;
+		long[] positions = new long[length];
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+		System.arraycopy(
+			this.identifierPositionStack,
+			this.identifierPtr + 1,
+			positions,
+			0,
+			length);
+		return new QualifiedTypeReference(tokens, positions);
+	}
+}
+public int getFirstToken() {
+	// the first token is a virtual token that
+	// allows the parser to parse several goals
+	// even if they aren't LALR(1)....
+	// Goal ::= '++' CompilationUnit
+	// Goal ::= '--' MethodBody
+	// Goal ::= '==' ConstructorBody
+	// -- Initializer
+	// Goal ::= '>>' StaticInitializer
+	// Goal ::= '>>' Block
+	// -- error recovery
+	// Goal ::= '>>>' Headers
+	// Goal ::= '*' BlockStatements
+	// Goal ::= '*' MethodPushModifiersHeader
+	// -- JDOM
+	// Goal ::= '&&' FieldDeclaration
+	// Goal ::= '||' ImportDeclaration
+	// Goal ::= '?' PackageDeclaration
+	// Goal ::= '+' TypeDeclaration
+	// Goal ::= '/' GenericMethodDeclaration
+	// Goal ::= '&' ClassBodyDeclaration
+	// -- code snippet
+	// Goal ::= '%' Expression
+	// -- completion parser
+	// Goal ::= '!' ConstructorBlockStatementsopt
+	// Goal ::= '~' BlockStatementsopt
+
+	return this.firstToken;
+}
+/*
+ * Answer back an array of sourceStart/sourceEnd positions of the available JavaDoc comments.
+ * The array is a flattened structure: 2*n entries with consecutives start and end positions.
+ *
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ *
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ */
+public int[] getJavaDocPositions() {
+
+	int javadocCount = 0;
+	int max = this.scanner.commentPtr;
+	for (int i = 0; i <= max; i++){
+		// javadoc only (non javadoc comment have negative start and/or end positions.)
+		if (this.scanner.commentStarts[i] >= 0 && this.scanner.commentStops[i] > 0) {
+			javadocCount++;
+		}
+	}
+	if (javadocCount == 0) return null;
+
+	int[] positions = new int[2*javadocCount];
+	int index = 0;
+	for (int i = 0; i <= max; i++){
+		// javadoc only (non javadoc comment have negative start and/or end positions.)
+		int commentStart = this.scanner.commentStarts[i];
+		if (commentStart >= 0) {
+			int commentStop = this.scanner.commentStops[i];
+			if (commentStop > 0){
+				positions[index++] = commentStart;
+				positions[index++] = commentStop-1; //stop is one over
+			}
+		}
+	}
+	return positions;
+}
+public void getMethodBodies(CompilationUnitDeclaration unit) {
+	//fill the methods bodies in order for the code to be generated
+
+	if (unit == null) return;
+
+	if (unit.ignoreMethodBodies) {
+		unit.ignoreFurtherInvestigation = true;
+		return;
+		// if initial diet parse did not work, no need to dig into method bodies.
+	}
+
+	if ((unit.bits & ASTNode.HasAllMethodBodies) != 0)
+		return; //work already done ...
+
+	// save existing values to restore them at the end of the parsing process
+	// see bug 47079 for more details
+	int[] oldLineEnds = this.scanner.lineEnds;
+	int oldLinePtr = this.scanner.linePtr;
+
+	//real parse of the method....
+	CompilationResult compilationResult = unit.compilationResult;
+	char[] contents = this.readManager != null
+		? this.readManager.getContents(compilationResult.compilationUnit)
+		: compilationResult.compilationUnit.getContents();
+	this.scanner.setSource(contents, compilationResult);
+
+	if (this.javadocParser != null && this.javadocParser.checkDocComment) {
+		this.javadocParser.scanner.setSource(contents);
+	}
+	if (unit.types != null) {
+		for (int i = 0, length = unit.types.length; i < length; i++)
+			unit.types[i].parseMethods(this, unit);
+	}
+
+	// tag unit has having read bodies
+	unit.bits |= ASTNode.HasAllMethodBodies;
+
+	// this is done to prevent any side effects on the compilation unit result
+	// line separator positions array.
+	this.scanner.lineEnds = oldLineEnds;
+	this.scanner.linePtr = oldLinePtr;
+}
+	protected char getNextCharacter(char[] comment, int[] index) {
+		char nextCharacter = comment[index[0]++];
+		switch(nextCharacter) {
+			case '\\' :
+				int c1, c2, c3, c4;
+				index[0]++;
+				while (comment[index[0]] == 'u') index[0]++;
+				if (!(((c1 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15
+					|| c1 < 0)
+					|| ((c2 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c2 < 0)
+					|| ((c3 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c3 < 0)
+					|| ((c4 = ScannerHelper.getHexadecimalValue(comment[index[0]++])) > 15 || c4 < 0))) {
+						nextCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+				}
+				break;
+		}
+		return nextCharacter;
+	}
+protected Expression getTypeReference(Expression exp) {
+
+	exp.bits &= ~ASTNode.RestrictiveFlagMASK;
+	exp.bits |= Binding.TYPE;
+	return exp;
+}
+protected void annotateTypeReference(Wildcard ref) {
+	int length;
+	if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+		if (ref.annotations == null)
+			ref.annotations = new Annotation[ref.getAnnotatableLevels()][];
+		System.arraycopy(
+				this.typeAnnotationStack,
+				(this.typeAnnotationPtr -= length) + 1,
+				ref.annotations[0] = new Annotation[length],
+				0,
+				length);
+		if (ref.sourceStart > ref.annotations[0][0].sourceStart) {
+			ref.sourceStart = ref.annotations[0][0].sourceStart;
+		}
+		ref.bits |= ASTNode.HasTypeAnnotations;
+	}
+	if (ref.bound != null) {
+		ref.bits |= (ref.bound.bits & ASTNode.HasTypeAnnotations);
+	}
+}
+protected TypeReference getTypeReference(int dim) {
+	/* build a Reference on a variable that may be qualified or not
+	 This variable is a type reference and dim will be its dimensions*/
+
+	TypeReference ref;
+	Annotation [][] annotationsOnDimensions = null;
+	int length = this.identifierLengthStack[this.identifierLengthPtr--];
+	if (length < 0) { //flag for precompiled type reference on base types
+		if (dim > 0) {
+			annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+		}
+		ref = TypeReference.baseTypeReference(-length, dim, annotationsOnDimensions);
+		ref.sourceStart = this.intStack[this.intPtr--];
+		if (dim == 0) {
+			ref.sourceEnd = this.intStack[this.intPtr--];
+		} else {
+			this.intPtr--;
+			ref.sourceEnd = this.endPosition;
+		}
+	} else {
+		int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--];
+		if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
+			// generic type
+			ref = getTypeReferenceForGenericType(dim, length, numberOfIdentifiers);
+		} else if (length == 1) {
+			// single type reference
+			this.genericsLengthPtr--; // pop the 0
+			if (dim == 0) {
+				ref =
+					new SingleTypeReference(
+						this.identifierStack[this.identifierPtr],
+						this.identifierPositionStack[this.identifierPtr--]);
+			} else {
+				annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+				ref =
+					new ArrayTypeReference(
+						this.identifierStack[this.identifierPtr],
+						dim,
+						annotationsOnDimensions,
+						this.identifierPositionStack[this.identifierPtr--]);
+				ref.sourceEnd = this.endPosition;
+				if (annotationsOnDimensions != null) {
+					ref.bits |= ASTNode.HasTypeAnnotations;
+				}
+			}
+		} else {
+			this.genericsLengthPtr--;
+			//Qualified type reference
+			char[][] tokens = new char[length][];
+			this.identifierPtr -= length;
+			long[] positions = new long[length];
+			System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+			System.arraycopy(
+				this.identifierPositionStack,
+				this.identifierPtr + 1,
+				positions,
+				0,
+				length);
+			if (dim == 0) {
+				ref = new QualifiedTypeReference(tokens, positions);
+			} else {
+				annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+				ref = new ArrayQualifiedTypeReference(tokens, dim, annotationsOnDimensions, positions);
+				ref.sourceEnd = this.endPosition;
+				if (annotationsOnDimensions != null) {
+					ref.bits |= ASTNode.HasTypeAnnotations;
+				}
+			}
+		}
+	}
+	int levels = ref.getAnnotatableLevels();
+	for (int i = levels - 1; i >= 0; i--) {
+		if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+			if (ref.annotations == null)
+				ref.annotations = new Annotation[levels][];
+			System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					ref.annotations[i] = new Annotation[length],
+					0,
+					length);
+			if (i == 0) {
+				ref.sourceStart = ref.annotations[0][0].sourceStart;
+			}
+			ref.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+	return ref;
+}
+protected TypeReference getTypeReferenceForGenericType(int dim, int identifierLength, int numberOfIdentifiers) {
+	Annotation[][] annotationsOnDimensions = dim == 0 ? null : getAnnotationsOnDimensions(dim);
+	if (identifierLength == 1 && numberOfIdentifiers == 1) {
+		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+		TypeReference[] typeArguments = null;
+		if (currentTypeArgumentsLength < 0) {
+			typeArguments = TypeReference.NO_TYPE_ARGUMENTS;
+		} else {
+			typeArguments = new TypeReference[currentTypeArgumentsLength];
+			this.genericsPtr -= currentTypeArgumentsLength;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength);
+		}
+		ParameterizedSingleTypeReference parameterizedSingleTypeReference = new ParameterizedSingleTypeReference(this.identifierStack[this.identifierPtr], typeArguments, dim, annotationsOnDimensions, this.identifierPositionStack[this.identifierPtr--]);
+		if (dim != 0) {
+			parameterizedSingleTypeReference.sourceEnd = this.endStatementPosition;
+		}
+		/* We used to eagerly mark the PSTR as constituting diamond usage if we encountered <>, but that is too eager and
+		   complicates error handling by making it hard to distinguish legitimate use cases from ill formed ones. We are
+		   more discriminating now and tag a type as being diamond only where <> can legally occur. 
+		   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=339478#c11
+		*/
+		return parameterizedSingleTypeReference;
+	} else {
+		TypeReference[][] typeArguments = new TypeReference[numberOfIdentifiers][];
+		char[][] tokens = new char[numberOfIdentifiers][];
+		long[] positions = new long[numberOfIdentifiers];
+		int index = numberOfIdentifiers;
+		int currentIdentifiersLength = identifierLength;
+		while (index > 0) {
+			int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
+			if (currentTypeArgumentsLength > 0) {
+				this.genericsPtr -= currentTypeArgumentsLength;
+				System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
+			} else if (currentTypeArgumentsLength < 0) {
+				// diamond case for qualified type reference (java.util.ArrayList<>)
+				typeArguments[index - 1] = TypeReference.NO_TYPE_ARGUMENTS;
+			}
+			switch(currentIdentifiersLength) {
+				case 1 :
+					// we are in a case A<B>.C<D> or A<B>.C<D>
+					tokens[index - 1] = this.identifierStack[this.identifierPtr];
+					positions[index - 1] = this.identifierPositionStack[this.identifierPtr--];
+					break;
+				default:
+					// we are in a case A.B.C<B>.C<D> or A.B.C<B>...
+					this.identifierPtr -= currentIdentifiersLength;
+					System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, index - currentIdentifiersLength, currentIdentifiersLength);
+					System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, index - currentIdentifiersLength, currentIdentifiersLength);
+			}
+			index -= currentIdentifiersLength;
+			if (index > 0) {
+				currentIdentifiersLength = this.identifierLengthStack[this.identifierLengthPtr--];
+			}
+		}
+		ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = new ParameterizedQualifiedTypeReference(tokens, typeArguments, dim, annotationsOnDimensions, positions);
+		if (dim != 0) {
+			parameterizedQualifiedTypeReference.sourceEnd = this.endStatementPosition;
+		}
+		/* We used to eagerly mark the PQTR as constituting diamond usage if we encountered <>, but that is too eager and
+		   complicates error handling by making it hard to distinguish legitimate use cases from ill formed ones. We are
+		   more discriminating now and tag a type as being diamond only where <> can legally occur. 
+		   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=339478#c11
+		*/
+		return parameterizedQualifiedTypeReference;
+	}
+}
+protected NameReference getUnspecifiedReference() {
+	return getUnspecifiedReference(true);
+}
+protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	/* build a (unspecified) NameReference which may be qualified*/
+	if (rejectTypeAnnotations) { // Compensate for overpermissive grammar.
+		consumeNonTypeUseName();
+	}
+	int length;
+	NameReference ref;
+	if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1)
+		// single variable reference
+		ref =
+			new SingleNameReference(
+				this.identifierStack[this.identifierPtr],
+				this.identifierPositionStack[this.identifierPtr--]);
+	else
+		//Qualified variable reference
+		{
+		char[][] tokens = new char[length][];
+		this.identifierPtr -= length;
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+		long[] positions = new long[length];
+		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+		ref =
+			new QualifiedNameReference(tokens,
+				positions,
+				(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+				(int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
+	}
+	return ref;
+}
+protected NameReference getUnspecifiedReferenceOptimized() {
+	/* build a (unspecified) NameReference which may be qualified
+	The optimization occurs for qualified reference while we are
+	certain in this case the last item of the qualified name is
+	a field access. This optimization is IMPORTANT while it results
+	that when a NameReference is build, the type checker should always
+	look for that it is not a type reference */
+	consumeNonTypeUseName();
+	int length;
+	NameReference ref;
+	if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+		// single variable reference
+		ref =
+			new SingleNameReference(
+				this.identifierStack[this.identifierPtr],
+				this.identifierPositionStack[this.identifierPtr--]);
+		ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+		ref.bits |= Binding.LOCAL | Binding.FIELD;
+		return ref;
+	}
+
+	//Qualified-variable-reference
+	//In fact it is variable-reference DOT field-ref , but it would result in a type
+	//conflict tha can be only reduce by making a superclass (or inetrface ) between
+	//nameReference and FiledReference or putting FieldReference under NameReference
+	//or else..........This optimisation is not really relevant so just leave as it is
+
+	char[][] tokens = new char[length][];
+	this.identifierPtr -= length;
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	ref = new QualifiedNameReference(
+			tokens,
+			positions,
+			(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+			(int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
+	ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+	ref.bits |= Binding.LOCAL | Binding.FIELD;
+	return ref;
+}
+public void goForBlockStatementsopt() {
+	//tells the scanner to go for block statements opt parsing
+
+	this.firstToken = TokenNameTWIDDLE;
+	this.scanner.recordLineSeparator = false;
+}
+public void goForBlockStatementsOrCatchHeader() {
+	//tells the scanner to go for block statements or method headers parsing
+
+	this.firstToken = TokenNameMULTIPLY;
+	this.scanner.recordLineSeparator = false;
+}
+public void goForClassBodyDeclarations() {
+	//tells the scanner to go for any body declarations parsing
+
+	this.firstToken = TokenNameAND;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForCompilationUnit(){
+	//tells the scanner to go for compilation unit parsing
+
+	this.firstToken = TokenNamePLUS_PLUS ;
+	this.scanner.foundTaskCount = 0;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForExpression(boolean recordLineSeparator) {
+	//tells the scanner to go for an expression parsing
+
+	this.firstToken = TokenNameREMAINDER;
+	this.scanner.recordLineSeparator = recordLineSeparator; // recovery goals must record line separators
+}
+public void goForFieldDeclaration(){
+	//tells the scanner to go for field declaration parsing
+
+	this.firstToken = TokenNameAND_AND ;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForGenericMethodDeclaration(){
+	//tells the scanner to go for generic method declarations parsing
+
+	this.firstToken = TokenNameDIVIDE;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForHeaders(){
+	//tells the scanner to go for headers only parsing
+	RecoveredType currentType = currentRecoveryType();
+	if(currentType != null && currentType.insideEnumConstantPart) {
+		this.firstToken = TokenNameNOT;
+	} else {
+		this.firstToken = TokenNameUNSIGNED_RIGHT_SHIFT;
+	}
+	this.scanner.recordLineSeparator = true; // recovery goals must record line separators
+}
+public void goForImportDeclaration(){
+	//tells the scanner to go for import declaration parsing
+
+	this.firstToken = TokenNameOR_OR ;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForInitializer(){
+	//tells the scanner to go for initializer parsing
+
+	this.firstToken = TokenNameRIGHT_SHIFT ;
+	this.scanner.recordLineSeparator = false;
+}
+public void goForMemberValue() {
+	//tells the scanner to go for a member value parsing
+
+	this.firstToken = TokenNameOR_OR;
+	this.scanner.recordLineSeparator = true; // recovery goals must record line separators
+}
+public void goForMethodBody(){
+	//tells the scanner to go for method body parsing
+
+	this.firstToken = TokenNameMINUS_MINUS ;
+	this.scanner.recordLineSeparator = false;
+}
+public void goForPackageDeclaration() {
+	//tells the scanner to go for package declaration parsing
+
+	this.firstToken = TokenNameQUESTION;
+	this.scanner.recordLineSeparator = true;
+}
+public void goForTypeDeclaration() {
+	//tells the scanner to go for type (interface or class) declaration parsing
+
+	this.firstToken = TokenNamePLUS;
+	this.scanner.recordLineSeparator = true;
+}
+/**
+ * Look for a specific tag comment leading a given source range (comment located after any statement in astStack)
+ * @param rangeEnd int
+ * @return boolean
+ */
+public boolean hasLeadingTagComment(char[] commentPrefixTag, int rangeEnd) {
+	int iComment = this.scanner.commentPtr;
+	if (iComment < 0) return false; // no comment available
+	int iStatement = this.astLengthPtr;
+	if (iStatement < 0 || this.astLengthStack[iStatement] <= 1) return false; // no statement available
+	// Fallthrough comment must be located after the previous statement
+	ASTNode lastNode = this.astStack[this.astPtr];
+	int rangeStart = lastNode.sourceEnd;
+	previousComment: for (; iComment >= 0; iComment--) {
+		int commentStart = this.scanner.commentStarts[iComment];
+		if (commentStart < 0) commentStart = -commentStart; // line comments have negative start positions
+		// ignore comments before start
+		if (commentStart < rangeStart) return false; // no more comments in range
+		// ignore comments after end
+		if (commentStart > rangeEnd) continue previousComment;
+		// found last comment in range - only check the last comment in range
+		char[] source = this.scanner.source;
+		int charPos = commentStart+2; // skip // or /*
+		// tag can be leaded by optional spaces
+		for (; charPos < rangeEnd; charPos++) {
+			char c = source[charPos];
+			if (c >= ScannerHelper.MAX_OBVIOUS || (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) == 0) {
+				break;
+			}
+		}
+		for (int iTag = 0, length = commentPrefixTag.length; iTag < length; iTag++, charPos++) {
+			if (charPos >= rangeEnd // comment is too small to host tag
+					|| source[charPos] != commentPrefixTag[iTag]) {
+				if (iTag == 0) {
+					return false; // didn't even match leading '$' -> not a tag comment
+				} else {
+					continue previousComment; // accept as tag comment -> skip it and keep searching backwards
+				}
+			}
+		}
+		return true;
+	}
+	return false;
+}
+protected void ignoreExpressionAssignment() {
+	// Assignment ::= InvalidArrayInitializerAssignement
+	// encoded operator would be: this.intStack[this.intPtr]
+	this.intPtr--;
+	ArrayInitializer arrayInitializer = (ArrayInitializer) this.expressionStack[this.expressionPtr--];
+	this.expressionLengthPtr -- ;
+	// report a syntax error and abort parsing
+	if(!this.statementRecoveryActivated) problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd);
+}
+public void initialize() {
+	this.initialize(false);
+}
+public void initialize(boolean initializeNLS) {
+	//positioning the parser for a new compilation unit
+	//avoiding stack reallocation and all that....
+	this.javadoc = null;
+	this.astPtr = -1;
+	this.astLengthPtr = -1;
+	this.expressionPtr = -1;
+	this.expressionLengthPtr = -1;
+	this.typeAnnotationLengthPtr = -1;
+	this.typeAnnotationPtr = -1;
+	this.identifierPtr = -1;
+	this.identifierLengthPtr	= -1;
+	this.intPtr = -1;
+	this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
+	this.variablesCounter[this.nestedType] = 0;
+	this.dimensions = 0 ;
+	this.realBlockPtr = -1;
+	this.compilationUnit = null;
+	this.referenceContext = null;
+	this.endStatementPosition = 0;
+	this.valueLambdaNestDepth = -1;
+
+	//remove objects from stack too, while the same parser/compiler couple is
+	//re-used between two compilations ....
+
+	int astLength = this.astStack.length;
+	if (this.noAstNodes.length < astLength){
+		this.noAstNodes = new ASTNode[astLength];
+		//System.out.println("Resized AST stacks : "+ astLength);
+
+	}
+	System.arraycopy(this.noAstNodes, 0, this.astStack, 0, astLength);
+
+	int expressionLength = this.expressionStack.length;
+	if (this.noExpressions.length < expressionLength){
+		this.noExpressions = new Expression[expressionLength];
+		//System.out.println("Resized EXPR stacks : "+ expressionLength);
+	}
+	System.arraycopy(this.noExpressions, 0, this.expressionStack, 0, expressionLength);
+
+	// reset this.scanner state
+	this.scanner.commentPtr = -1;
+	this.scanner.foundTaskCount = 0;
+	this.scanner.eofPosition = Integer.MAX_VALUE;
+	this.recordStringLiterals = true;
+	final boolean checkNLS = this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore;
+	this.checkExternalizeStrings = checkNLS;
+	this.scanner.checkNonExternalizedStringLiterals = initializeNLS && checkNLS;
+	this.scanner.lastPosition = -1;
+
+	resetModifiers();
+
+	// recovery
+	this.lastCheckPoint = -1;
+	this.currentElement = null;
+	this.restartRecovery = false;
+	this.hasReportedError = false;
+	this.recoveredStaticInitializerStart = 0;
+	this.lastIgnoredToken = -1;
+	this.lastErrorEndPosition = -1;
+	this.lastErrorEndPositionBeforeRecovery = -1;
+	this.lastJavadocEnd = -1;
+	this.listLength = 0;
+	this.listTypeParameterLength = 0;
+	this.lastPosistion = -1;
+
+	this.rBraceStart = 0;
+	this.rBraceEnd = 0;
+	this.rBraceSuccessorStart = 0;
+
+	this.genericsIdentifiersLengthPtr = -1;
+	this.genericsLengthPtr = -1;
+	this.genericsPtr = -1;
+}
+public void initializeScanner(){
+	this.scanner = new Scanner(
+		false /*comment*/,
+		false /*whitespace*/,
+		false, /* will be set in initialize(boolean) */
+		this.options.sourceLevel /*sourceLevel*/,
+		this.options.complianceLevel /*complianceLevel*/,
+		this.options.taskTags/*taskTags*/,
+		this.options.taskPriorities/*taskPriorities*/,
+		this.options.isTaskCaseSensitive/*taskCaseSensitive*/);
+}
+public void jumpOverMethodBody() {
+	//on diet parsing.....do not buffer method statements
+
+	//the scanner.diet is reinitialized to false
+	//automatically by the scanner once it has jumped over
+	//the statements
+
+	if (this.diet && (this.dietInt == 0))
+		this.scanner.diet = true;
+}
+private void jumpOverType(){
+	if (this.recoveredTypes != null && this.nextTypeStart > -1 && this.nextTypeStart < this.scanner.currentPosition) {
+
+		if (DEBUG_AUTOMATON) {
+			System.out.println("Jump         -"); //$NON-NLS-1$
+		}
+
+		TypeDeclaration typeDeclaration = this.recoveredTypes[this.recoveredTypePtr];
+		boolean isAnonymous = typeDeclaration.allocation != null;
+
+		this.scanner.startPosition = typeDeclaration.declarationSourceEnd + 1;
+		this.scanner.currentPosition = typeDeclaration.declarationSourceEnd + 1;
+		this.scanner.diet = false; // quit jumping over method bodies
+
+		if(!isAnonymous) {
+			((RecoveryScanner)this.scanner).setPendingTokens(new int[]{TokenNameSEMICOLON, TokenNamebreak});
+		} else {
+			((RecoveryScanner)this.scanner).setPendingTokens(new int[]{TokenNameIdentifier, TokenNameEQUAL, TokenNameIdentifier});
+		}
+
+		this.pendingRecoveredType = typeDeclaration;
+
+		try {
+			this.currentToken = this.scanner.getNextToken();
+		} catch(InvalidInputException e){
+			// it's impossible because we added pending tokens before
+		}
+
+		if(++this.recoveredTypePtr < this.recoveredTypes.length) {
+			TypeDeclaration nextTypeDeclaration = this.recoveredTypes[this.recoveredTypePtr];
+			this.nextTypeStart =
+				nextTypeDeclaration.allocation == null
+					? nextTypeDeclaration.declarationSourceStart
+							: nextTypeDeclaration.allocation.sourceStart;
+		} else {
+			this.nextTypeStart = Integer.MAX_VALUE;
+		}
+	}
+}
+protected void markEnclosingMemberWithLocalType() {
+	if (this.currentElement != null) return; // this is already done in the recovery code
+	for (int i = this.astPtr; i >= 0; i--) {
+		ASTNode node = this.astStack[i];
+		if (node instanceof AbstractMethodDeclaration
+				|| node instanceof FieldDeclaration
+				|| (node instanceof TypeDeclaration // mark type for now: all initializers will be marked when added to this type
+						// and enclosing type must not be closed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=147485)
+						&& ((TypeDeclaration) node).declarationSourceEnd == 0)) {
+			node.bits |= ASTNode.HasLocalType;
+			return;
+		}
+	}
+	// default to reference context (case of parse method body)
+	if (this.referenceContext instanceof AbstractMethodDeclaration
+			|| this.referenceContext instanceof TypeDeclaration) {
+		((ASTNode)this.referenceContext).bits |= ASTNode.HasLocalType;
+	}
+}
+
+/*
+ * Move checkpoint location (current implementation is moving it by one token)
+ *
+ * Answers true if successfully moved checkpoint (in other words, it did not attempt to move it
+ * beyond end of file).
+ */
+protected boolean moveRecoveryCheckpoint() {
+
+	int pos = this.lastCheckPoint;
+	/* reset this.scanner, and move checkpoint by one token */
+	this.scanner.startPosition = pos;
+	this.scanner.currentPosition = pos;
+	this.scanner.diet = false; // quit jumping over method bodies
+
+	/* if about to restart, then no need to shift token */
+	if (this.restartRecovery){
+		this.lastIgnoredToken = -1;
+		this.scanner.insideRecovery = true;
+		return true;
+	}
+
+	/* protect against shifting on an invalid token */
+	this.lastIgnoredToken = this.nextIgnoredToken;
+	this.nextIgnoredToken = -1;
+	do {
+		try {
+			this.scanner.lookBack[0] = this.scanner.lookBack[1] = TokenNameNotAToken; // stay clear of the voodoo in the present method
+			this.nextIgnoredToken = this.scanner.getNextToken();
+			if(this.scanner.currentPosition == this.scanner.startPosition){
+				this.scanner.currentPosition++; // on fake completion identifier
+				this.nextIgnoredToken = -1;
+			}
+
+		} catch(InvalidInputException e){
+			pos = this.scanner.currentPosition;
+		} finally {
+			this.scanner.lookBack[0] = this.scanner.lookBack[1] = TokenNameNotAToken; // steer clear of the voodoo in the present method
+		}
+	} while (this.nextIgnoredToken < 0);
+
+	if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
+		if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
+			return false;
+		}
+	}
+	this.lastCheckPoint = this.scanner.currentPosition;
+
+	/* reset this.scanner again to previous checkpoint location*/
+	this.scanner.startPosition = pos;
+	this.scanner.currentPosition = pos;
+	this.scanner.commentPtr = -1;
+	this.scanner.foundTaskCount = 0;
+	return true;
+
+/*
+ 	The following implementation moves the checkpoint location by one line:
+
+	int pos = this.lastCheckPoint;
+	// reset this.scanner, and move checkpoint by one token
+	this.scanner.startPosition = pos;
+	this.scanner.currentPosition = pos;
+	this.scanner.diet = false; // quit jumping over method bodies
+
+	// if about to restart, then no need to shift token
+	if (this.restartRecovery){
+		this.lastIgnoredToken = -1;
+		return true;
+	}
+
+	// protect against shifting on an invalid token
+	this.lastIgnoredToken = this.nextIgnoredToken;
+	this.nextIgnoredToken = -1;
+
+	boolean wasTokenizingWhiteSpace = this.scanner.tokenizeWhiteSpace;
+	this.scanner.tokenizeWhiteSpace = true;
+	checkpointMove:
+		do {
+			try {
+				this.nextIgnoredToken = this.scanner.getNextToken();
+				switch(this.nextIgnoredToken){
+					case Scanner.TokenNameWHITESPACE :
+						if(this.scanner.getLineNumber(this.scanner.startPosition)
+							== this.scanner.getLineNumber(this.scanner.currentPosition)){
+							this.nextIgnoredToken = -1;
+							}
+						break;
+					case TokenNameSEMICOLON :
+					case TokenNameLBRACE :
+					case TokenNameRBRACE :
+						break;
+					case TokenNameIdentifier :
+						if(this.scanner.currentPosition == this.scanner.startPosition){
+							this.scanner.currentPosition++; // on fake completion identifier
+						}
+					default:
+						this.nextIgnoredToken = -1;
+						break;
+					case TokenNameEOF :
+						break checkpointMove;
+				}
+			} catch(InvalidInputException e){
+				pos = this.scanner.currentPosition;
+			}
+		} while (this.nextIgnoredToken < 0);
+	this.scanner.tokenizeWhiteSpace = wasTokenizingWhiteSpace;
+
+	if (this.nextIgnoredToken == TokenNameEOF) { // no more recovery after this point
+		if (this.currentToken == TokenNameEOF) { // already tried one iteration on EOF
+			return false;
+		}
+	}
+	this.lastCheckPoint = this.scanner.currentPosition;
+
+	// reset this.scanner again to previous checkpoint location
+	this.scanner.startPosition = pos;
+	this.scanner.currentPosition = pos;
+	this.scanner.commentPtr = -1;
+
+	return true;
+*/
+}
+protected MessageSend newMessageSend() {
+	// '(' ArgumentListopt ')'
+	// the arguments are on the expression stack
+
+	MessageSend m = new MessageSend();
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			m.arguments = new Expression[length],
+			0,
+			length);
+	}
+	return m;
+}
+protected MessageSend newMessageSendWithTypeArguments() {
+	MessageSend m = new MessageSend();
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			m.arguments = new Expression[length],
+			0,
+			length);
+	}
+	return m;
+}
+protected void optimizedConcatNodeLists() {
+	/*back from a recursive loop. Virtualy group the
+	astNode into an array using this.astLengthStack*/
+
+	/*
+	 * This is a case where you have two sublists into the this.astStack that you want
+	 * to merge in one list. There is no action required on the this.astStack. The only
+	 * thing you need to do is merge the two lengths specified on the astStackLength.
+	 * The top two length are for example:
+	 * ... p   n
+	 * and you want to result in a list like:
+	 * ... n+p
+	 * This means that the p could be equals to 0 in case there is no astNode pushed
+	 * on the this.astStack.
+	 * Look at the InterfaceMemberDeclarations for an example.
+	 * This case optimizes the fact that p == 1.
+	 */
+
+	this.astLengthStack[--this.astLengthPtr]++;
+}
+public boolean atConflictScenario(int token) {
+	
+	/* Answer true if the parser is at a configuration where the scanner must look ahead and help disambiguate between (a) '<' as an operator and '<' as the
+	   start of <type argument> and (b) the use of '(' in '(' expression ')' and '( type ')' and '(' lambda formal parameters ')'. (c) whether the token @
+	   begins a Java SE5 style declaration annotation or if it begins a SE8 style type annotation. When requested thus, the scanner helps by fabricating 
+	   synthetic tokens and injecting them into the stream ahead of the tokens that trigger conflicts in the absence of these artificial tokens. These 
+	   manufactured token help transform the grammar into LALR(1) by splitting the states so that they have unambigious prefixes.
+	   
+	   We do this by claiming to the automaton that the next token seen is the (suitable) synthetic token and observing the response of the state machine. 
+	   Error signals we are NOT at a conflict site, while shift or shift/reduce signals that we are. Accept is impossible, while there may be intermediate
+	   reductions that are called for -- It is axiomatic of the push down automaton that corresponds to the LALR grammar that it will never shift on invalid
+	   input.
+	   
+	   Obviously, the dry runs should not alter the parser state in any way or otherwise cause side effects. Proof by argument that this is the case:
+	   
+	       - The only pieces of state needed to answer the question are: this.stack, this.stateStackTop and the last action variable `act`. None of the various
+	         and sundry stacks used in the AST constructions process are touched here.
+	       - As we reduce, we DON'T call the semantic action functions i.e the consume* method calls are skipped.
+	       - Lexer stream is left untouched.
+	       - this.stateStackTop and the last action variable `act` of the automaton are readily cloned, these being primitives and changes are to the replicas.
+	       - We never remove elements from the state stack here (or elsewhere for that matter). Pops are implemented by mere adjustments of the stack pointer.
+	       - During this algorithm, either the stack pointer monotonically decreases or stays fixed. (The only way for the stack pointer to increase would call
+	         for a shift or a shift/reduce at which point the algorithm is ready to terminate already.) This means that we don't have to replicate the stack. 
+	         Pushes can be mimiced by writing to a local stackTopState variable, leaving the original stack untouched.
+	         
+	    Though this code looks complex, we should exit early in most situations.     
+	 */
+	int lastAction = this.unstackedAct;
+	if (lastAction == ERROR_ACTION) { // automaton is not running.
+		return false;
+	}
+	int stackTop = this.stateStackTop;        // local copy of stack pointer
+	int stackTopState = this.stack[stackTop]; // single cell non write through "alternate stack" - the automaton's stack pointer either stays fixed during this manoeuvre or monotonically decreases.
+	int highWaterMark = stackTop;
+	
+	if (token != TokenNameAT) {
+		token = token == TokenNameLPAREN ? TokenNameBeginLambda : TokenNameBeginTypeArguments;
+	}
+	
+	// A rotated version of the automaton - cf. parse()'s for(;;)
+	for (;;) {  
+		if (lastAction > ERROR_ACTION) {  
+			lastAction -= ERROR_ACTION;    /* shift-reduce on loop entry from above, reduce on loop back */
+			do { /* reduce */
+				stackTop -= rhs[lastAction] - 1;
+				if (stackTop < highWaterMark) {
+					stackTopState = this.stack[highWaterMark = stackTop];
+				} // else stackTopState is upto date already.
+				lastAction = ntAction(stackTopState, lhs[lastAction]);
+			} while (lastAction <= NUM_RULES);
+		}
+		highWaterMark = ++stackTop;
+		stackTopState = lastAction; // "push"
+		lastAction = tAction(lastAction, token); // can be looked up from a precomputed cache.
+		if (lastAction <= NUM_RULES) {
+			stackTop --; 
+		    lastAction += ERROR_ACTION;
+			continue;
+		}
+		// Error => false, Shift, Shift/Reduce => true, Accept => impossible. 
+		return lastAction != ERROR_ACTION;
+	}
+}
+/*main loop of the automat
+When a rule is reduced, the method consumeRule(int) is called with the number
+of the consumed rule. When a terminal is consumed, the method consumeToken(int) is
+called in order to remember (when needed) the consumed token */
+// (int)asr[asi(act)]
+// name[symbol_index[currentKind]]
+protected void parse() {
+	if (DEBUG) System.out.println("-- ENTER INSIDE PARSE METHOD --");  //$NON-NLS-1$
+
+	if (DEBUG_AUTOMATON) {
+		System.out.println("- Start --------------------------------");  //$NON-NLS-1$
+	}
+
+	boolean isDietParse = this.diet;
+	int oldFirstToken = getFirstToken();
+	this.hasError = false;
+
+	this.hasReportedError = false;
+	int act = START_STATE;
+	this.stateStackTop = -1;
+	this.currentToken = getFirstToken();
+	
+try {
+	this.scanner.setActiveParser(this);
+	ProcessTerminals : for (;;) {
+		int stackLength = this.stack.length;
+		if (++this.stateStackTop >= stackLength) {
+			System.arraycopy(
+				this.stack, 0,
+				this.stack = new int[stackLength + StackIncrement], 0,
+				stackLength);
+		}
+		this.stack[this.stateStackTop] = act;
+
+		act = tAction(act, this.currentToken);
+		if (act == ERROR_ACTION || (this.restartRecovery && !this.shouldDeferRecovery)) {
+			this.shouldDeferRecovery = false;
+			if (DEBUG_AUTOMATON) {
+				if (this.restartRecovery) {
+					System.out.println("Restart      - "); //$NON-NLS-1$
+				} else {
+					System.out.println("Error        - "); //$NON-NLS-1$
+				}
+			}
+
+			int errorPos = this.scanner.currentPosition - 1;
+			if (!this.hasReportedError) {
+				this.hasError = true;
+			}
+			int previousToken = this.currentToken;
+			if (resumeOnSyntaxError()) {
+				if (act == ERROR_ACTION && previousToken != 0) this.lastErrorEndPosition = errorPos;
+				act = START_STATE;
+				this.stateStackTop = -1;
+				this.currentToken = getFirstToken();
+				continue ProcessTerminals;
+			}
+			act = ERROR_ACTION;
+			break ProcessTerminals;
+		}
+		if (act <= NUM_RULES) {
+			this.stateStackTop--;
+
+			if (DEBUG_AUTOMATON) {
+				System.out.print("Reduce       - "); //$NON-NLS-1$
+			}
+
+		} else if (act > ERROR_ACTION) { /* shift-reduce */
+			consumeToken(this.currentToken);
+			if (this.currentElement != null) {
+				boolean oldValue = this.recordStringLiterals;
+				this.recordStringLiterals = false;
+				recoveryTokenCheck();
+				this.recordStringLiterals = oldValue;
+			}
+			try {
+				this.unstackedAct = act;
+				this.currentToken = this.scanner.getNextToken();
+			} catch(InvalidInputException e){
+				if (!this.hasReportedError){
+					problemReporter().scannerError(this, e.getMessage());
+					this.hasReportedError = true;
+				}
+				this.lastCheckPoint = this.scanner.currentPosition;
+				this.currentToken = 0;
+				this.restartRecovery = true;
+			} finally {
+				this.unstackedAct = ERROR_ACTION;
+			}
+			if(this.statementRecoveryActivated) {
+				jumpOverType();
+			}
+			act -= ERROR_ACTION;
+
+			if (DEBUG_AUTOMATON) {
+				System.out.print("Shift/Reduce - (" + name[terminal_index[this.currentToken]]+") ");  //$NON-NLS-1$  //$NON-NLS-2$
+			}
+
+		} else {
+		    if (act < ACCEPT_ACTION) { /* shift */
+				consumeToken(this.currentToken);
+				if (this.currentElement != null) {
+					boolean oldValue = this.recordStringLiterals;
+					this.recordStringLiterals = false;
+					recoveryTokenCheck();
+					this.recordStringLiterals = oldValue;
+				}
+				try{
+					this.unstackedAct = act;
+					this.currentToken = this.scanner.getNextToken();
+				} catch(InvalidInputException e){
+					if (!this.hasReportedError){
+						problemReporter().scannerError(this, e.getMessage());
+						this.hasReportedError = true;
+					}
+					this.lastCheckPoint = this.scanner.currentPosition;
+					this.currentToken = 0;
+					this.restartRecovery = true;
+				} finally {
+					this.unstackedAct = ERROR_ACTION;
+				}
+				if(this.statementRecoveryActivated) {
+					jumpOverType();
+				}
+				if (DEBUG_AUTOMATON) {
+					System.out.println("Shift        - (" + name[terminal_index[this.currentToken]]+")");  //$NON-NLS-1$  //$NON-NLS-2$
+				}
+				continue ProcessTerminals;
+			}
+			break ProcessTerminals;
+		}
+
+		// ProcessNonTerminals :
+		do { /* reduce */
+
+			if (DEBUG_AUTOMATON) {
+				System.out.println(name[non_terminal_index[lhs[act]]]);
+			}
+
+			this.stateStackTop -= (rhs[act] - 1);
+			consumeRule(act);
+			act = ntAction(this.stack[this.stateStackTop], lhs[act]);
+
+			if (DEBUG_AUTOMATON) {
+				if (act <= NUM_RULES) {
+					System.out.print("             - ");  //$NON-NLS-1$
+				}
+			}
+
+		} while (act <= NUM_RULES);
+
+		if (DEBUG_AUTOMATON) {
+			System.out.println("----------------------------------------");  //$NON-NLS-1$
+		}
+	}
+} finally {
+	this.scanner.setActiveParser(null);
+}
+
+	if (DEBUG_AUTOMATON) {
+		System.out.println("- End ----------------------------------");  //$NON-NLS-1$
+	}
+
+	endParse(act);
+	// record all nls tags in the corresponding compilation unit
+	final NLSTag[] tags = this.scanner.getNLSTags();
+	if (tags != null) {
+		this.compilationUnit.nlsTags = tags;
+	}
+
+	this.scanner.checkNonExternalizedStringLiterals = false;
+	if (this.reportSyntaxErrorIsRequired && this.hasError && !this.statementRecoveryActivated) {
+		if(!this.options.performStatementsRecovery) {
+			reportSyntaxErrors(isDietParse, oldFirstToken);
+		} else {
+			RecoveryScannerData data = this.referenceContext.compilationResult().recoveryScannerData;
+
+			if(this.recoveryScanner == null) {
+				this.recoveryScanner = new RecoveryScanner(this.scanner, data);
+			} else {
+				this.recoveryScanner.setData(data);
+			}
+
+			this.recoveryScanner.setSource(this.scanner.source);
+			this.recoveryScanner.lineEnds = this.scanner.lineEnds;
+			this.recoveryScanner.linePtr = this.scanner.linePtr;
+
+			reportSyntaxErrors(isDietParse, oldFirstToken);
+
+			if(data == null) {
+				this.referenceContext.compilationResult().recoveryScannerData =
+					this.recoveryScanner.getData();
+			}
+
+			if (this.methodRecoveryActivated && this.options.performStatementsRecovery) {
+				this.methodRecoveryActivated = false;
+				recoverStatements();
+				this.methodRecoveryActivated = true;
+
+				this.lastAct = ERROR_ACTION;
+			}
+		}
+	}
+	this.problemReporter.referenceContext = null; // Null this so we won't escalate problems needlessly (bug 393192)
+	if (DEBUG) System.out.println("-- EXIT FROM PARSE METHOD --");  //$NON-NLS-1$
+}
+public void parse(ConstructorDeclaration cd, CompilationUnitDeclaration unit, boolean recordLineSeparator) {
+	//only parse the method body of cd
+	//fill out its statements
+
+	//convert bugs into parse error
+
+	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
+	if(this.options.performMethodsFullRecovery) {
+		this.methodRecoveryActivated = true;
+		// we should not relocate bodyStart if there is a block within the statements
+		this.ignoreNextOpeningBrace = true;
+	}
+
+	initialize();
+	goForBlockStatementsopt();
+	if (recordLineSeparator) {
+		this.scanner.recordLineSeparator = true;
+	}
+	this.nestedMethod[this.nestedType]++;
+	pushOnRealBlockStack(0);
+
+	this.referenceContext = cd;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(cd.bodyStart, cd.bodyEnd);
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+		if(this.options.performStatementsRecovery) {
+			this.methodRecoveryActivated = oldMethodRecoveryActivated;
+		}
+	}
+
+	checkNonNLSAfterBodyEnd(cd.declarationSourceEnd);
+
+	if (this.lastAct == ERROR_ACTION) {
+		cd.bits |= ASTNode.HasSyntaxErrors;
+		initialize();
+		return;
+	}
+
+	//statements
+	cd.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+		if (!this.options.ignoreMethodBodies) {
+			if (this.astStack[this.astPtr + 1] instanceof ExplicitConstructorCall)
+				//avoid a isSomeThing that would only be used here BUT what is faster between two alternatives ?
+				{
+				System.arraycopy(
+					this.astStack,
+					this.astPtr + 2,
+					cd.statements = new Statement[length - 1],
+					0,
+					length - 1);
+				cd.constructorCall = (ExplicitConstructorCall) this.astStack[this.astPtr + 1];
+			} else { //need to add explicitly the super();
+				System.arraycopy(
+					this.astStack,
+					this.astPtr + 1,
+					cd.statements = new Statement[length],
+					0,
+					length);
+				cd.constructorCall = SuperReference.implicitSuperConstructorCall();
+			}
+		}
+	} else {
+		if (!this.options.ignoreMethodBodies) {
+			cd.constructorCall = SuperReference.implicitSuperConstructorCall();
+		}
+		if (!containsComment(cd.bodyStart, cd.bodyEnd)) {
+			cd.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+
+	ExplicitConstructorCall explicitConstructorCall = cd.constructorCall;
+	if (explicitConstructorCall != null && explicitConstructorCall.sourceEnd == 0) {
+		explicitConstructorCall.sourceEnd = cd.sourceEnd;
+		explicitConstructorCall.sourceStart = cd.sourceStart;
+	}
+}
+// A P I
+
+public void parse(
+	FieldDeclaration field,
+	TypeDeclaration type,
+	CompilationUnitDeclaration unit,
+	char[] initializationSource) {
+	//only parse the initializationSource of the given field
+
+	//convert bugs into parse error
+
+	initialize();
+	goForExpression(true /* record line separators */);
+	this.nestedMethod[this.nestedType]++;
+
+	this.referenceContext = type;
+	this.compilationUnit = unit;
+
+	this.scanner.setSource(initializationSource);
+	this.scanner.resetTo(0, initializationSource.length-1);
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		field.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	field.initialization = this.expressionStack[this.expressionPtr];
+
+	// mark field with local type if one was found during parsing
+	if ((type.bits & ASTNode.HasLocalType) != 0) {
+		field.bits |= ASTNode.HasLocalType;
+	}
+}
+// A P I
+
+public CompilationUnitDeclaration parse(
+	ICompilationUnit sourceUnit,
+	CompilationResult compilationResult) {
+	// parses a compilation unit and manages error handling (even bugs....)
+
+	return parse(sourceUnit, compilationResult, -1, -1/*parse without reseting the scanner*/);
+}
+// A P I
+
+public CompilationUnitDeclaration parse(
+	ICompilationUnit sourceUnit,
+	CompilationResult compilationResult,
+	int start,
+	int end) {
+	// parses a compilation unit and manages error handling (even bugs....)
+
+	CompilationUnitDeclaration unit;
+	try {
+		/* automaton initialization */
+		initialize(true);
+		goForCompilationUnit();
+
+		/* unit creation */
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					this.problemReporter,
+					compilationResult,
+					0);
+
+		/* scanners initialization */
+		char[] contents;
+		try {
+			contents = this.readManager != null ? this.readManager.getContents(sourceUnit) : sourceUnit.getContents();
+		} catch(AbortCompilationUnit abortException) {
+			problemReporter().cannotReadSource(this.compilationUnit, abortException, this.options.verbose);
+			contents = CharOperation.NO_CHAR; // pretend empty from thereon
+		}
+		this.scanner.setSource(contents);
+		this.compilationUnit.sourceEnd = this.scanner.source.length - 1;
+		if (end != -1) this.scanner.resetTo(start, end);
+		if (this.javadocParser != null && this.javadocParser.checkDocComment) {
+			this.javadocParser.scanner.setSource(contents);
+			if (end != -1) {
+				this.javadocParser.scanner.resetTo(start, end);
+			}
+		}
+		/* run automaton */
+		parse();
+	} finally {
+		unit = this.compilationUnit;
+		this.compilationUnit = null; // reset parser
+		// tag unit has having read bodies
+		if (!this.diet) unit.bits |= ASTNode.HasAllMethodBodies;
+	}
+	return unit;
+}
+// A P I
+
+public void parse(
+	Initializer initializer,
+	TypeDeclaration type,
+	CompilationUnitDeclaration unit) {
+	//only parse the method body of md
+	//fill out method statements
+
+	//convert bugs into parse error
+
+	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
+	if(this.options.performMethodsFullRecovery) {
+		this.methodRecoveryActivated = true;
+	}
+
+	initialize();
+	goForBlockStatementsopt();
+	this.nestedMethod[this.nestedType]++;
+	pushOnRealBlockStack(0);
+
+	this.referenceContext = type;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(initializer.bodyStart, initializer.bodyEnd); // just on the beginning {
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+		if(this.options.performStatementsRecovery) {
+			this.methodRecoveryActivated = oldMethodRecoveryActivated;
+		}
+	}
+
+	checkNonNLSAfterBodyEnd(initializer.declarationSourceEnd);
+
+	if (this.lastAct == ERROR_ACTION) {
+		initializer.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	//refill statements
+	initializer.block.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > 0) {
+		System.arraycopy(this.astStack, (this.astPtr -= length) + 1, initializer.block.statements = new Statement[length], 0, length);
+	} else {
+		// check whether this block at least contains some comment in it
+		if (!containsComment(initializer.block.sourceStart, initializer.block.sourceEnd)) {
+			initializer.block.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+
+	// mark initializer with local type if one was found during parsing
+	if ((type.bits & ASTNode.HasLocalType) != 0) {
+		initializer.bits |= ASTNode.HasLocalType;
+	}
+}
+// A P I
+public void parse(MethodDeclaration md, CompilationUnitDeclaration unit) {
+	//only parse the method body of md
+	//fill out method statements
+
+	//convert bugs into parse error
+
+	if (md.isAbstract())
+		return;
+	if (md.isNative())
+		return;
+	if ((md.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0)
+		return;
+
+	boolean oldMethodRecoveryActivated = this.methodRecoveryActivated;
+	if(this.options.performMethodsFullRecovery) {
+		// we should not relocate bodyStart if there is a block within the statements
+		this.ignoreNextOpeningBrace = true;
+		this.methodRecoveryActivated = true;
+		this.rParenPos = md.sourceEnd;
+	}
+	initialize();
+	goForBlockStatementsopt();
+	this.nestedMethod[this.nestedType]++;
+	pushOnRealBlockStack(0);
+
+	this.referenceContext = md;
+	this.compilationUnit = unit;
+
+	this.scanner.resetTo(md.bodyStart, md.bodyEnd);
+	// reset the scanner to parser from { down to }
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+		if(this.options.performStatementsRecovery) {
+			this.methodRecoveryActivated = oldMethodRecoveryActivated;
+		}
+	}
+
+	checkNonNLSAfterBodyEnd(md.declarationSourceEnd);
+
+	if (this.lastAct == ERROR_ACTION) {
+		md.bits |= ASTNode.HasSyntaxErrors;
+		return;
+	}
+
+	//refill statements
+	md.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
+	int length;
+	if (this.astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		if (this.options.ignoreMethodBodies) {
+			// ignore statements
+			this.astPtr -= length;
+		} else {
+			System.arraycopy(
+				this.astStack,
+				(this.astPtr -= length) + 1,
+				md.statements = new Statement[length],
+				0,
+				length);
+		}
+	} else {
+		if (!containsComment(md.bodyStart, md.bodyEnd)) {
+			md.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+	}
+}
+public ASTNode[] parseClassBodyDeclarations(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
+	boolean oldDiet = this.diet;
+	/* automaton initialization */
+	initialize();
+	goForClassBodyDeclarations();
+	/* scanner initialization */
+	this.scanner.setSource(source);
+	this.scanner.resetTo(offset, offset + length - 1);
+	if (this.javadocParser != null && this.javadocParser.checkDocComment) {
+		this.javadocParser.scanner.setSource(source);
+		this.javadocParser.scanner.resetTo(offset, offset + length - 1);
+	}
+
+	/* type declaration should be parsed as member type declaration */
+	this.nestedType = 1;
+
+	/* unit creation */
+	TypeDeclaration referenceContextTypeDeclaration = new TypeDeclaration(unit.compilationResult);
+	referenceContextTypeDeclaration.name = Util.EMPTY_STRING.toCharArray();
+	referenceContextTypeDeclaration.fields = new FieldDeclaration[0];
+	this.compilationUnit = unit;
+	unit.types = new TypeDeclaration[1];
+	unit.types[0] = referenceContextTypeDeclaration;
+	this.referenceContext = unit;
+
+	/* run automaton */
+	try {
+		this.diet = true;
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.diet = oldDiet;
+	}
+
+	ASTNode[] result = null;
+	if (this.lastAct == ERROR_ACTION) {
+		if (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery) {
+			return null;
+		}
+		// collect all body declaration inside the compilation unit except the default constructor
+		final List bodyDeclarations = new ArrayList();
+		ASTVisitor visitor = new ASTVisitor() {
+			public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+				if (!methodDeclaration.isDefaultConstructor()) {
+					bodyDeclarations.add(methodDeclaration);
+				}
+				return false;
+			}
+			public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+				bodyDeclarations.add(fieldDeclaration);
+				return false;
+			}
+			public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+				bodyDeclarations.add(memberTypeDeclaration);
+				return false;
+			}
+		};
+		unit.ignoreFurtherInvestigation = false;
+		unit.traverse(visitor, unit.scope);
+		unit.ignoreFurtherInvestigation = true;
+		result = (ASTNode[]) bodyDeclarations.toArray(new ASTNode[bodyDeclarations.size()]);
+	} else {
+		int astLength;
+		if (this.astLengthPtr > -1 && (astLength = this.astLengthStack[this.astLengthPtr--]) != 0) {
+			result = new ASTNode[astLength];
+			this.astPtr -= astLength;
+			System.arraycopy(this.astStack, this.astPtr + 1, result, 0, astLength);
+		} else {
+			// empty class body declaration (like ';' see https://bugs.eclipse.org/bugs/show_bug.cgi?id=280079).
+			result = new ASTNode[0];
+		}
+	}
+	boolean containsInitializers = false;
+	TypeDeclaration typeDeclaration = null;
+	for (int i = 0, max = result.length; i < max; i++) {
+		// parse each class body declaration
+		ASTNode node = result[i];
+		if (node instanceof TypeDeclaration) {
+			((TypeDeclaration) node).parseMethods(this, unit);
+		} else if (node instanceof AbstractMethodDeclaration) {
+			((AbstractMethodDeclaration) node).parseStatements(this, unit);
+		} else if (node instanceof FieldDeclaration) {
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
+			switch(fieldDeclaration.getKind()) {
+				case AbstractVariableDeclaration.INITIALIZER:
+					containsInitializers = true;
+					if (typeDeclaration == null) {
+						typeDeclaration = referenceContextTypeDeclaration;
+					}
+					if (typeDeclaration.fields == null) {
+						typeDeclaration.fields = new FieldDeclaration[1];
+						typeDeclaration.fields[0] = fieldDeclaration;
+					} else {
+						int length2 = typeDeclaration.fields.length;
+						FieldDeclaration[] temp = new FieldDeclaration[length2 + 1];
+						System.arraycopy(typeDeclaration.fields, 0, temp, 0, length2);
+						temp[length2] = fieldDeclaration;
+						typeDeclaration.fields = temp;
+					}
+					break;
+			}
+		}
+		if (((node.bits & ASTNode.HasSyntaxErrors) != 0) && (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery)) {
+			return null;
+		}
+	}
+	if (containsInitializers) {
+		FieldDeclaration[] fieldDeclarations = typeDeclaration.fields;
+		for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
+			Initializer initializer = (Initializer) fieldDeclarations[i];
+			initializer.parseStatements(this, typeDeclaration , unit);
+			if (((initializer.bits & ASTNode.HasSyntaxErrors) != 0) && (!this.options.performMethodsFullRecovery && !this.options.performStatementsRecovery)) {
+				return null;
+			}
+		}
+	}
+	return result;
+}
+
+public Expression parseLambdaExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit, boolean recordLineSeparators) {
+	this.haltOnSyntaxError = true; // unexposed/unshared object, no threading concerns.
+	return parseExpression(source, offset, length, unit, recordLineSeparators);
+}
+
+public Expression parseExpression(char[] source, int offset, int length, CompilationUnitDeclaration unit, boolean recordLineSeparators) {
+
+	initialize();
+	goForExpression(recordLineSeparators);
+	this.nestedMethod[this.nestedType]++;
+
+	this.referenceContext = unit;
+	this.compilationUnit = unit;
+
+	this.scanner.setSource(source);
+	this.scanner.resetTo(offset, offset + length - 1);
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		return null;
+	}
+
+	return this.expressionStack[this.expressionPtr];
+}
+public Expression parseMemberValue(char[] source, int offset, int length, CompilationUnitDeclaration unit) {
+
+	initialize();
+	goForMemberValue();
+	this.nestedMethod[this.nestedType]++;
+
+	this.referenceContext = unit;
+	this.compilationUnit = unit;
+
+	this.scanner.setSource(source);
+	this.scanner.resetTo(offset, offset + length - 1);
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+	}
+
+	if (this.lastAct == ERROR_ACTION) {
+		return null;
+	}
+
+	return this.expressionStack[this.expressionPtr];
+}
+public void parseStatements(ReferenceContext rc, int start, int end, TypeDeclaration[] types, CompilationUnitDeclaration unit) {
+	boolean oldStatementRecoveryEnabled = this.statementRecoveryActivated;
+	this.statementRecoveryActivated = true;
+
+	initialize();
+
+	goForBlockStatementsopt();
+	this.nestedMethod[this.nestedType]++;
+	pushOnRealBlockStack(0);
+
+	pushOnAstLengthStack(0);
+
+	this.referenceContext = rc;
+	this.compilationUnit = unit;
+
+	this.pendingRecoveredType = null;
+
+	if(types != null && types.length > 0) {
+		this.recoveredTypes = types;
+		this.recoveredTypePtr = 0;
+		this.nextTypeStart =
+			this.recoveredTypes[0].allocation == null
+				? this.recoveredTypes[0].declarationSourceStart
+						: this.recoveredTypes[0].allocation.sourceStart;
+	} else {
+		this.recoveredTypes = null;
+		this.recoveredTypePtr = -1;
+		this.nextTypeStart = -1;
+	}
+
+	this.scanner.resetTo(start, end);
+	// reset the scanner to parser from { down to }
+
+	this.lastCheckPoint = this.scanner.initialPosition;
+
+
+	this.stateStackTop = -1;
+
+	try {
+		parse();
+	} catch (AbortCompilation ex) {
+		this.lastAct = ERROR_ACTION;
+	} finally {
+		this.nestedMethod[this.nestedType]--;
+		this.recoveredTypes = null;
+		this.statementRecoveryActivated = oldStatementRecoveryEnabled;
+	}
+
+	checkNonNLSAfterBodyEnd(end);
+}
+public void persistLineSeparatorPositions() {
+	if (this.scanner.recordLineSeparator) {
+		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
+	}
+}
+/*
+ * Prepares the state of the parser to go for BlockStatements.
+ */
+protected void prepareForBlockStatements() {
+	this.nestedMethod[this.nestedType = 0] = 1;
+	this.variablesCounter[this.nestedType] = 0;
+	this.realBlockStack[this.realBlockPtr = 1] = 0;
+}
+/**
+ * Returns this parser's problem reporter initialized with its reference context.
+ * Also it is assumed that a problem is going to be reported, so initializes
+ * the compilation result's line positions.
+ *
+ * @return ProblemReporter
+ */
+public ProblemReporter problemReporter(){
+	if (this.scanner.recordLineSeparator) {
+		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
+	}
+	this.problemReporter.referenceContext = this.referenceContext;
+	return this.problemReporter;
+}
+protected void pushIdentifier(char [] identifier, long position) {
+	int stackLength = this.identifierStack.length;
+	if (++this.identifierPtr >= stackLength) {
+		System.arraycopy(
+			this.identifierStack, 0,
+			this.identifierStack = new char[stackLength + 20][], 0,
+			stackLength);
+		System.arraycopy(
+			this.identifierPositionStack, 0,
+			this.identifierPositionStack = new long[stackLength + 20], 0,
+			stackLength);
+	}
+	this.identifierStack[this.identifierPtr] = identifier;
+	this.identifierPositionStack[this.identifierPtr] = position;
+
+	stackLength = this.identifierLengthStack.length;
+	if (++this.identifierLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.identifierLengthStack, 0,
+			this.identifierLengthStack = new int[stackLength + 10], 0,
+			stackLength);
+	}
+	this.identifierLengthStack[this.identifierLengthPtr] = 1;
+	if (this.parsingJava8Plus && identifier.length == 1 && identifier[0] == '_') {
+		problemReporter().illegalUseOfUnderscoreAsAnIdentifier((int) (position >>> 32), (int) position);
+	}
+}
+protected void pushIdentifier() {
+	/*push the consumeToken on the identifier stack.
+	Increase the total number of identifier in the stack.
+	identifierPtr points on the next top */
+
+	pushIdentifier(this.scanner.getCurrentIdentifierSource(), (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1));
+}
+protected void pushIdentifier(int flag) {
+	/*push a special flag on the stack :
+	-zero stands for optional Name
+	-negative number for direct ref to base types.
+	identifierLengthPtr points on the top */
+
+	int stackLength = this.identifierLengthStack.length;
+	if (++this.identifierLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.identifierLengthStack, 0,
+			this.identifierLengthStack = new int[stackLength + 10], 0,
+			stackLength);
+	}
+	this.identifierLengthStack[this.identifierLengthPtr] = flag;
+}
+protected void pushOnAstLengthStack(int pos) {
+
+	int stackLength = this.astLengthStack.length;
+	if (++this.astLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.astLengthStack, 0,
+			this.astLengthStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.astLengthStack[this.astLengthPtr] = pos;
+}
+protected void pushOnAstStack(ASTNode node) {
+	/*add a new obj on top of the ast stack
+	astPtr points on the top*/
+
+	int stackLength = this.astStack.length;
+	if (++this.astPtr >= stackLength) {
+		System.arraycopy(
+			this.astStack, 0,
+			this.astStack = new ASTNode[stackLength + AstStackIncrement], 0,
+			stackLength);
+		this.astPtr = stackLength;
+	}
+	this.astStack[this.astPtr] = node;
+
+	stackLength = this.astLengthStack.length;
+	if (++this.astLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.astLengthStack, 0,
+			this.astLengthStack = new int[stackLength + AstStackIncrement], 0,
+			stackLength);
+	}
+	this.astLengthStack[this.astLengthPtr] = 1;
+}
+protected void pushOnTypeAnnotationStack(Annotation annotation) {
+
+	int stackLength = this.typeAnnotationStack.length;
+	if (++this.typeAnnotationPtr >= stackLength) {
+		System.arraycopy(
+			this.typeAnnotationStack, 0,
+			this.typeAnnotationStack = new Annotation[stackLength + TypeAnnotationStackIncrement], 0,
+			stackLength);
+	}
+	this.typeAnnotationStack[this.typeAnnotationPtr] = annotation;
+
+	stackLength = this.typeAnnotationLengthStack.length;
+	if (++this.typeAnnotationLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.typeAnnotationLengthStack, 0,
+			this.typeAnnotationLengthStack = new int[stackLength + TypeAnnotationStackIncrement], 0,
+			stackLength);
+	}
+	this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr] = 1;
+}
+protected void pushOnTypeAnnotationLengthStack(int pos) {
+
+	int stackLength = this.typeAnnotationLengthStack.length;
+	if (++this.typeAnnotationLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.typeAnnotationLengthStack, 0,
+			this.typeAnnotationLengthStack = new int[stackLength + TypeAnnotationStackIncrement], 0,
+			stackLength);
+	}
+	this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr] = pos;
+}
+protected void pushOnExpressionStack(Expression expr) {
+
+	int stackLength = this.expressionStack.length;
+	if (++this.expressionPtr >= stackLength) {
+		System.arraycopy(
+			this.expressionStack, 0,
+			this.expressionStack = new Expression[stackLength + ExpressionStackIncrement], 0,
+			stackLength);
+	}
+	this.expressionStack[this.expressionPtr] = expr;
+
+	stackLength = this.expressionLengthStack.length;
+	if (++this.expressionLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.expressionLengthStack, 0,
+			this.expressionLengthStack = new int[stackLength + ExpressionStackIncrement], 0,
+			stackLength);
+	}
+	this.expressionLengthStack[this.expressionLengthPtr] = 1;
+}
+protected void pushOnExpressionStackLengthStack(int pos) {
+
+	int stackLength = this.expressionLengthStack.length;
+	if (++this.expressionLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.expressionLengthStack, 0,
+			this.expressionLengthStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.expressionLengthStack[this.expressionLengthPtr] = pos;
+}
+protected void pushOnGenericsIdentifiersLengthStack(int pos) {
+	int stackLength = this.genericsIdentifiersLengthStack.length;
+	if (++this.genericsIdentifiersLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.genericsIdentifiersLengthStack, 0,
+			this.genericsIdentifiersLengthStack = new int[stackLength + GenericsStackIncrement], 0,
+			stackLength);
+	}
+	this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] = pos;
+}
+protected void pushOnGenericsLengthStack(int pos) {
+	int stackLength = this.genericsLengthStack.length;
+	if (++this.genericsLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.genericsLengthStack, 0,
+			this.genericsLengthStack = new int[stackLength + GenericsStackIncrement], 0,
+			stackLength);
+	}
+	this.genericsLengthStack[this.genericsLengthPtr] = pos;
+}
+protected void pushOnGenericsStack(ASTNode node) {
+	/*add a new obj on top of the generics stack
+	genericsPtr points on the top*/
+
+	int stackLength = this.genericsStack.length;
+	if (++this.genericsPtr >= stackLength) {
+		System.arraycopy(
+			this.genericsStack, 0,
+			this.genericsStack = new ASTNode[stackLength + GenericsStackIncrement], 0,
+			stackLength);
+	}
+	this.genericsStack[this.genericsPtr] = node;
+
+	stackLength = this.genericsLengthStack.length;
+	if (++this.genericsLengthPtr >= stackLength) {
+		System.arraycopy(
+			this.genericsLengthStack, 0,
+			this.genericsLengthStack = new int[stackLength + GenericsStackIncrement], 0,
+			stackLength);
+	}
+	this.genericsLengthStack[this.genericsLengthPtr] = 1;
+}
+protected void pushOnIntStack(int pos) {
+
+	int stackLength = this.intStack.length;
+	if (++this.intPtr >= stackLength) {
+		System.arraycopy(
+			this.intStack, 0,
+			this.intStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.intStack[this.intPtr] = pos;
+}
+protected void pushOnRealBlockStack(int i){
+
+	int stackLength = this.realBlockStack.length;
+	if (++this.realBlockPtr >= stackLength) {
+		System.arraycopy(
+			this.realBlockStack, 0,
+			this.realBlockStack = new int[stackLength + StackIncrement], 0,
+			stackLength);
+	}
+	this.realBlockStack[this.realBlockPtr] = i;
+}
+protected void recoverStatements() {
+	class MethodVisitor extends ASTVisitor {
+		public ASTVisitor typeVisitor;
+
+		TypeDeclaration enclosingType; // used only for initializer
+
+		TypeDeclaration[] types = new TypeDeclaration[0];
+		int typePtr = -1;
+		public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+			endVisitMethod(constructorDeclaration, scope);
+		}
+		public void endVisit(Initializer initializer, MethodScope scope) {
+			if (initializer.block == null) return;
+			TypeDeclaration[] foundTypes = null;
+			int length = 0;
+			if(this.typePtr > -1) {
+				length = this.typePtr + 1;
+				foundTypes = new TypeDeclaration[length];
+				System.arraycopy(this.types, 0, foundTypes, 0, length);
+			}
+			ReferenceContext oldContext = Parser.this.referenceContext;
+			Parser.this.recoveryScanner.resetTo(initializer.bodyStart, initializer.bodyEnd);
+			Scanner oldScanner = Parser.this.scanner;
+			Parser.this.scanner = Parser.this.recoveryScanner;
+			parseStatements(
+					this.enclosingType,
+					initializer.bodyStart,
+					initializer.bodyEnd,
+					foundTypes,
+					Parser.this.compilationUnit);
+			Parser.this.scanner = oldScanner;
+			Parser.this.referenceContext = oldContext;
+
+			for (int i = 0; i < length; i++) {
+				foundTypes[i].traverse(this.typeVisitor, scope);
+			}
+		}
+		public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
+			endVisitMethod(methodDeclaration, scope);
+		}
+		private void endVisitMethod(AbstractMethodDeclaration methodDeclaration, ClassScope scope) {
+			TypeDeclaration[] foundTypes = null;
+			int length = 0;
+			if(this.typePtr > -1) {
+				length = this.typePtr + 1;
+				foundTypes = new TypeDeclaration[length];
+				System.arraycopy(this.types, 0, foundTypes, 0, length);
+			}
+			ReferenceContext oldContext = Parser.this.referenceContext;
+			Parser.this.recoveryScanner.resetTo(methodDeclaration.bodyStart, methodDeclaration.bodyEnd);
+			Scanner oldScanner = Parser.this.scanner;
+			Parser.this.scanner = Parser.this.recoveryScanner;
+			parseStatements(
+					methodDeclaration,
+					methodDeclaration.bodyStart,
+					methodDeclaration.bodyEnd,
+					foundTypes,
+					Parser.this.compilationUnit);
+			Parser.this.scanner = oldScanner;
+			Parser.this.referenceContext = oldContext;
+
+			for (int i = 0; i < length; i++) {
+				foundTypes[i].traverse(this.typeVisitor, scope);
+			}
+		}
+		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+			this.typePtr = -1;
+			return true;
+		}
+		public boolean visit(Initializer initializer, MethodScope scope) {
+			this.typePtr = -1;
+			if (initializer.block == null) return false;
+			return true;
+		}
+		public boolean visit(MethodDeclaration methodDeclaration,ClassScope scope) {
+			this.typePtr = -1;
+			return true;
+		}
+		private boolean visit(TypeDeclaration typeDeclaration) {
+			if(this.types.length <= ++this.typePtr) {
+				int length = this.typePtr;
+				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
+			}
+			this.types[this.typePtr] = typeDeclaration;
+			return false;
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+			return this.visit(typeDeclaration);
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
+			return this.visit(typeDeclaration);
+		}
+	}
+	class TypeVisitor extends ASTVisitor {
+		public MethodVisitor methodVisitor;
+
+		TypeDeclaration[] types = new TypeDeclaration[0];
+		int typePtr = -1;
+
+		public void endVisit(TypeDeclaration typeDeclaration, BlockScope scope) {
+			endVisitType();
+		}
+		public void endVisit(TypeDeclaration typeDeclaration, ClassScope scope) {
+			endVisitType();
+		}
+		private void endVisitType() {
+			this.typePtr--;
+		}
+		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+			if(constructorDeclaration.isDefaultConstructor()) return false;
+
+			constructorDeclaration.traverse(this.methodVisitor, scope);
+			return false;
+		}
+		public boolean visit(Initializer initializer, MethodScope scope) {
+			if (initializer.block == null) return false;
+			this.methodVisitor.enclosingType = this.types[this.typePtr];
+			initializer.traverse(this.methodVisitor, scope);
+			return false;
+		}
+		public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+			methodDeclaration.traverse(this.methodVisitor, scope);
+			return false;
+		}
+		private boolean visit(TypeDeclaration typeDeclaration) {
+			if(this.types.length <= ++this.typePtr) {
+				int length = this.typePtr;
+				System.arraycopy(this.types, 0, this.types = new TypeDeclaration[length * 2 + 1], 0, length);
+			}
+			this.types[this.typePtr] = typeDeclaration;
+			return true;
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+			return this.visit(typeDeclaration);
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
+			return this.visit(typeDeclaration);
+		}
+	}
+
+	MethodVisitor methodVisitor = new MethodVisitor();
+	TypeVisitor typeVisitor = new TypeVisitor();
+	methodVisitor.typeVisitor = typeVisitor;
+	typeVisitor.methodVisitor = methodVisitor;
+
+	if(this.referenceContext instanceof AbstractMethodDeclaration) {
+		((AbstractMethodDeclaration)this.referenceContext).traverse(methodVisitor, (ClassScope)null);
+	} else if(this.referenceContext instanceof TypeDeclaration) {
+		TypeDeclaration typeContext = (TypeDeclaration)this.referenceContext;
+
+		int length = typeContext.fields.length;
+		for (int i = 0; i < length; i++) {
+			final FieldDeclaration fieldDeclaration = typeContext.fields[i];
+			switch(fieldDeclaration.getKind()) {
+				case AbstractVariableDeclaration.INITIALIZER:
+					Initializer initializer = (Initializer) fieldDeclaration;
+					if (initializer.block == null) break;
+					methodVisitor.enclosingType = typeContext;
+					initializer.traverse(methodVisitor, (MethodScope)null);
+					break;
+			}
+		}
+	}
+}
+
+public void recoveryExitFromVariable() {
+	if(this.currentElement != null && this.currentElement.parent != null) {
+		if(this.currentElement instanceof RecoveredLocalVariable) {
+
+			int end = ((RecoveredLocalVariable)this.currentElement).localDeclaration.sourceEnd;
+			this.currentElement.updateSourceEndIfNecessary(end);
+			this.currentElement = this.currentElement.parent;
+		} else if(this.currentElement instanceof RecoveredField
+			&& !(this.currentElement instanceof RecoveredInitializer)) {
+			// Do not move focus to parent if we are still inside an array initializer
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 
+			if (this.currentElement.bracketBalance <= 0) {
+				int end = ((RecoveredField)this.currentElement).fieldDeclaration.sourceEnd;
+				this.currentElement.updateSourceEndIfNecessary(end);
+				this.currentElement = this.currentElement.parent;
+			}
+		}
+	}
+}
+/* Token check performed on every token shift once having entered
+ * recovery mode.
+ */
+public void recoveryTokenCheck() {
+	switch (this.currentToken) {
+		case TokenNameStringLiteral :
+			if (this.recordStringLiterals &&
+					this.checkExternalizeStrings &&
+					this.lastPosistion < this.scanner.currentPosition &&
+					!this.statementRecoveryActivated) {
+				StringLiteral stringLiteral = createStringLiteral(
+					this.scanner.getCurrentTokenSourceString(),
+					this.scanner.startPosition,
+					this.scanner.currentPosition - 1,
+					Util.getLineNumber(this.scanner.startPosition, this.scanner.lineEnds, 0, this.scanner.linePtr));
+				this.compilationUnit.recordStringLiteral(stringLiteral, this.currentElement != null);
+			}
+			break;
+		case TokenNameLBRACE :
+			RecoveredElement newElement = null;
+			if(!this.ignoreNextOpeningBrace) {
+				newElement = this.currentElement.updateOnOpeningBrace(this.scanner.startPosition - 1, this.scanner.currentPosition - 1);
+			}
+			this.lastCheckPoint = this.scanner.currentPosition;
+			if (newElement != null){ // null means nothing happened
+				this.restartRecovery = true; // opening brace detected
+				this.currentElement = newElement;
+			}
+			break;
+
+		case TokenNameRBRACE :
+			this.rBraceStart = this.scanner.startPosition - 1;
+			this.rBraceEnd = this.scanner.currentPosition - 1;
+			this.endPosition = flushCommentsDefinedPriorTo(this.rBraceEnd);
+			newElement =
+				this.currentElement.updateOnClosingBrace(this.scanner.startPosition, this.rBraceEnd);
+				this.lastCheckPoint = this.scanner.currentPosition;
+			if (newElement != this.currentElement){
+				this.currentElement = newElement;
+//				if (newElement instanceof RecoveredField && this.dietInt <= 0) {
+//					if (((RecoveredField)newElement).fieldDeclaration.type == null) { // enum constant
+//						this.isInsideEnumConstantPart = true; // restore status
+//					}
+//				}
+			}
+			break;
+		case TokenNameSEMICOLON :
+			this.endStatementPosition = this.scanner.currentPosition - 1;
+			this.endPosition = this.scanner.startPosition - 1;
+			RecoveredType currentType = currentRecoveryType();
+			if(currentType != null) {
+				currentType.insideEnumConstantPart = false;
+			}
+			//$FALL-THROUGH$
+		default : {
+			if (this.rBraceEnd > this.rBraceSuccessorStart && this.scanner.currentPosition != this.scanner.startPosition){
+				this.rBraceSuccessorStart = this.scanner.startPosition;
+			}
+			break;
+		}
+	}
+	this.ignoreNextOpeningBrace = false;
+}
+// A P I
+protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) {
+	if(this.referenceContext instanceof MethodDeclaration) {
+		MethodDeclaration methodDeclaration = (MethodDeclaration) this.referenceContext;
+		if((methodDeclaration.bits & ASTNode.ErrorInSignature) != 0){
+			return;
+		}
+	}
+	this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
+	this.scanner.recordLineSeparator = false;
+
+	int start = this.scanner.initialPosition;
+	int end = this.scanner.eofPosition == Integer.MAX_VALUE ? this.scanner.eofPosition : this.scanner.eofPosition - 1;
+	if(isDietParse) {
+		TypeDeclaration[] types = this.compilationUnit.types;
+		int[][] intervalToSkip = org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil.computeDietRange(types);
+		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, intervalToSkip[0], intervalToSkip[1], intervalToSkip[2], this.options);
+		diagnoseParser.diagnoseParse(false);
+
+		reportSyntaxErrorsForSkippedMethod(types);
+		this.scanner.resetTo(start, end);
+	} else {
+		DiagnoseParser diagnoseParser = new DiagnoseParser(this, oldFirstToken, start, end, this.options);
+		diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
+	}
+}
+private void reportSyntaxErrorsForSkippedMethod(TypeDeclaration[] types){
+	if(types != null) {
+		for (int i = 0; i < types.length; i++) {
+			TypeDeclaration[] memberTypes = types[i].memberTypes;
+			if(memberTypes != null) {
+				reportSyntaxErrorsForSkippedMethod(memberTypes);
+			}
+
+			AbstractMethodDeclaration[] methods = types[i].methods;
+			if(methods != null) {
+				for (int j = 0; j < methods.length; j++) {
+					AbstractMethodDeclaration method = methods[j];
+					if((method.bits & ASTNode.ErrorInSignature) != 0) {
+						if(method.isAnnotationMethod()) {
+							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameQUESTION, method.declarationSourceStart, method.declarationSourceEnd, this.options);
+							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
+						} else {
+							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameDIVIDE, method.declarationSourceStart, method.declarationSourceEnd, this.options);
+							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
+						}
+
+					}
+				}
+			}
+
+			FieldDeclaration[] fields = types[i].fields;
+			if (fields != null) {
+				int length = fields.length;
+				for (int j = 0; j < length; j++) {
+					if (fields[j] instanceof Initializer) {
+						Initializer initializer = (Initializer)fields[j];
+						if((initializer.bits & ASTNode.ErrorInSignature) != 0){
+							DiagnoseParser diagnoseParser = new DiagnoseParser(this, TokenNameRIGHT_SHIFT, initializer.declarationSourceStart, initializer.declarationSourceEnd, this.options);
+							diagnoseParser.diagnoseParse(this.options.performStatementsRecovery);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+/**
+ * Reset modifiers buffer and comment stack. Should be call only for nodes that claim both.
+ */
+protected void resetModifiers() {
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+	this.scanner.commentPtr = -1;
+}
+/*
+ * Reset context so as to resume to regular parse loop
+ */
+protected void resetStacks() {
+
+	this.astPtr = -1;
+	this.astLengthPtr = -1;
+	this.expressionPtr = -1;
+	this.expressionLengthPtr = -1;
+	this.typeAnnotationLengthPtr = -1;
+	this.typeAnnotationPtr = -1;
+	this.identifierPtr = -1;
+	this.identifierLengthPtr	= -1;
+	this.intPtr = -1;
+	this.nestedMethod[this.nestedType = 0] = 0; // need to reset for further reuse
+	this.variablesCounter[this.nestedType] = 0;
+	this.dimensions = 0 ;
+	this.realBlockStack[this.realBlockPtr = 0] = 0;
+	this.recoveredStaticInitializerStart = 0;
+	this.listLength = 0;
+	this.listTypeParameterLength = 0;
+
+	this.genericsIdentifiersLengthPtr = -1;
+	this.genericsLengthPtr = -1;
+	this.genericsPtr = -1;
+	this.valueLambdaNestDepth = -1;
+}
+/*
+ * Reset context so as to resume to regular parse loop
+ * If unable to reset for resuming, answers false.
+ *
+ * Move checkpoint location, reset internal stacks and
+ * decide which grammar goal is activated.
+ */
+protected boolean resumeAfterRecovery() {
+	if(!this.methodRecoveryActivated && !this.statementRecoveryActivated) {
+
+		// reset internal stacks
+		resetStacks();
+		resetModifiers();
+
+		/* attempt to move checkpoint location */
+		if (!moveRecoveryCheckpoint()) {
+			return false;
+		}
+
+		// only look for headers
+		if (this.referenceContext instanceof CompilationUnitDeclaration){
+			goForHeaders();
+			this.diet = true; // passed this point, will not consider method bodies
+			return true;
+		}
+
+		// does not know how to restart
+		return false;
+	} else if(!this.statementRecoveryActivated) {
+
+		// reset internal stacks
+		resetStacks();
+		resetModifiers();
+
+		/* attempt to move checkpoint location */
+		if (!moveRecoveryCheckpoint()) {
+			return false;
+		}
+
+		// only look for headers
+		goForHeaders();
+		return true;
+	} else {
+		return false;
+	}
+}
+protected boolean resumeOnSyntaxError() {
+	if (this.haltOnSyntaxError)
+		return false;
+	/* request recovery initialization */
+	if (this.currentElement == null){
+		// Reset javadoc before restart parsing after recovery
+		this.javadoc = null;
+
+		// do not investigate deeper in statement recovery
+		if (this.statementRecoveryActivated) return false;
+
+		// build some recovered elements
+		this.currentElement = buildInitialRecoveryState();
+	}
+	/* do not investigate deeper in recovery when no recovered element */
+	if (this.currentElement == null) return false;
+
+	/* manual forced recovery restart - after headers */
+	if (this.restartRecovery){
+		this.restartRecovery = false;
+	}
+	/* update recovery state with current error state of the parser */
+	updateRecoveryState();
+	if (getFirstToken() == TokenNameAND) {
+		if (this.referenceContext instanceof CompilationUnitDeclaration) {
+			TypeDeclaration typeDeclaration = new TypeDeclaration(this.referenceContext.compilationResult());
+			typeDeclaration.name = Util.EMPTY_STRING.toCharArray();
+			this.currentElement = this.currentElement.add(typeDeclaration, 0);
+		}
+	}
+
+	if (this.lastPosistion < this.scanner.currentPosition) {
+		this.lastPosistion = this.scanner.currentPosition;
+		this.scanner.lastPosition = this.scanner.currentPosition;
+	}
+
+	/* attempt to reset state in order to resume to parse loop */
+	return resumeAfterRecovery();
+}
+public void setMethodsFullRecovery(boolean enabled) {
+	this.options.performMethodsFullRecovery = enabled;
+}
+public void setStatementsRecovery(boolean enabled) {
+	if(enabled) this.options.performMethodsFullRecovery = true;
+	this.options.performStatementsRecovery = enabled;
+}
+public String toString() {
+
+
+	String s = "lastCheckpoint : int = " + String.valueOf(this.lastCheckPoint) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+	s = s + "identifierStack : char["+(this.identifierPtr + 1)+"][] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.identifierPtr; i++) {
+		s = s + "\"" + String.valueOf(this.identifierStack[i]) + "\","; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "identifierLengthStack : int["+(this.identifierLengthPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.identifierLengthPtr; i++) {
+		s = s + this.identifierLengthStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "astLengthStack : int["+(this.astLengthPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.astLengthPtr; i++) {
+		s = s + this.astLengthStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+	s = s + "astPtr : int = " + String.valueOf(this.astPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+
+	s = s + "intStack : int["+(this.intPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.intPtr; i++) {
+		s = s + this.intStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "expressionLengthStack : int["+(this.expressionLengthPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.expressionLengthPtr; i++) {
+		s = s + this.expressionLengthStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "expressionPtr : int = " + String.valueOf(this.expressionPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+
+	s = s + "genericsIdentifiersLengthStack : int["+(this.genericsIdentifiersLengthPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.genericsIdentifiersLengthPtr; i++) {
+		s = s + this.genericsIdentifiersLengthStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "genericsLengthStack : int["+(this.genericsLengthPtr + 1)+"] = {"; //$NON-NLS-1$ //$NON-NLS-2$
+	for (int i = 0; i <= this.genericsLengthPtr; i++) {
+		s = s + this.genericsLengthStack[i] + ","; //$NON-NLS-1$
+	}
+	s = s + "}\n"; //$NON-NLS-1$
+
+	s = s + "genericsPtr : int = " + String.valueOf(this.genericsPtr) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
+
+	s = s + "\n\n\n----------------Scanner--------------\n" + this.scanner.toString(); //$NON-NLS-1$
+	return s;
+
+}
+/*
+ * Update recovery state based on current parser/scanner state
+ */
+protected void updateRecoveryState() {
+
+	/* expose parser state to recovery state */
+	this.currentElement.updateFromParserState();
+
+	/* check and update recovered state based on current token,
+		this action is also performed when shifting token after recovery
+		got activated once.
+	*/
+	recoveryTokenCheck();
+}
+protected void updateSourceDeclarationParts(int variableDeclaratorsCounter) {
+	//fields is a definition of fields that are grouped together like in
+	//public int[] a, b[], c
+	//which results into 3 fields.
+
+	FieldDeclaration field;
+	int endTypeDeclarationPosition =
+		-1 + this.astStack[this.astPtr - variableDeclaratorsCounter + 1].sourceStart;
+	for (int i = 0; i < variableDeclaratorsCounter - 1; i++) {
+		//last one is special(see below)
+		field = (FieldDeclaration) this.astStack[this.astPtr - i - 1];
+		field.endPart1Position = endTypeDeclarationPosition;
+		field.endPart2Position = -1 + this.astStack[this.astPtr - i].sourceStart;
+	}
+	//last one
+	(field = (FieldDeclaration) this.astStack[this.astPtr]).endPart1Position =
+		endTypeDeclarationPosition;
+	field.endPart2Position = field.declarationSourceEnd;
+
+}
+protected void updateSourcePosition(Expression exp) {
+	//update the source Position of the expression
+
+	//this.intStack : int int
+	//-->
+	//this.intStack :
+
+	exp.sourceEnd = this.intStack[this.intPtr--];
+	exp.sourceStart = this.intStack[this.intPtr--];
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
new file mode 100644
index 0000000..2941580
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *  
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/*An interface that contains static declarations for some basic information
+ about the parser such as the number of rules in the grammar, the starting state, etc...*/
+public interface ParserBasicInformation {
+
+    int ERROR_SYMBOL    = 118,
+      MAX_NAME_LENGTH   = 41,
+      NUM_STATES        = 1093,
+
+      NT_OFFSET         = 118,
+      SCOPE_UBOUND      = 283,
+      SCOPE_SIZE        = 284,
+      LA_STATE_OFFSET   = 15935,
+      MAX_LA            = 1,
+      NUM_RULES         = 790,
+      NUM_TERMINALS     = 118,
+      NUM_NON_TERMINALS = 356,
+      NUM_SYMBOLS       = 474,
+      START_STATE       = 1022,
+      EOFT_SYMBOL       = 60,
+      EOLT_SYMBOL       = 60,
+      ACCEPT_ACTION     = 15934,
+      ERROR_ACTION      = 15935;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java
new file mode 100644
index 0000000..05edc47
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredAnnotation.java
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+
+public class RecoveredAnnotation extends RecoveredElement {
+	public static final int MARKER = 0;
+	public static final int NORMAL = 1;
+	public static final int SINGLE_MEMBER = 2;
+
+	private int kind;
+	private int identifierPtr;
+	private int identifierLengthPtr;
+	private int sourceStart;
+	public boolean hasPendingMemberValueName;
+	public int memberValuPairEqualEnd = -1;
+	public Annotation annotation;
+
+	public RecoveredAnnotation(int identifierPtr, int identifierLengthPtr, int sourceStart, RecoveredElement parent, int bracketBalance) {
+		super(parent, bracketBalance);
+		this.kind = MARKER;
+		this.identifierPtr = identifierPtr;
+		this.identifierLengthPtr = identifierLengthPtr;
+		this.sourceStart = sourceStart;
+	}
+
+	public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+		if (this.annotation == null && (typeDeclaration.bits & ASTNode.IsAnonymousType) != 0){
+			// ignore anonymous type in annotations when annotation isn't fully recovered
+			return this;
+		}
+		return super.add(typeDeclaration, bracketBalanceValue);
+	}
+
+	public RecoveredElement addAnnotationName(int identPtr, int identLengthPtr, int annotationStart, int bracketBalanceValue) {
+
+		RecoveredAnnotation element = new RecoveredAnnotation(identPtr, identLengthPtr, annotationStart, this, bracketBalanceValue);
+
+		return element;
+	}
+
+	public RecoveredElement addAnnotation(Annotation annot, int index) {
+		this.annotation = annot;
+
+		if (this.parent != null) return this.parent;
+		return this;
+	}
+
+	public void updateFromParserState() {
+		Parser parser = parser();
+
+		if (this.annotation == null && this.identifierPtr <= parser.identifierPtr) {
+			Annotation annot = null;
+
+			boolean needUpdateRParenPos = false;
+
+			MemberValuePair pendingMemberValueName = null;
+			if (this.hasPendingMemberValueName && this.identifierPtr < parser.identifierPtr) {
+				char[] memberValueName = parser.identifierStack[this.identifierPtr + 1];
+
+				long pos = parser.identifierPositionStack[this.identifierPtr + 1];
+				int start = (int) (pos >>> 32);
+				int end = (int)pos;
+				int valueEnd = this.memberValuPairEqualEnd > -1 ? this.memberValuPairEqualEnd : end;
+
+				SingleNameReference fakeExpression = new SingleNameReference(RecoveryScanner.FAKE_IDENTIFIER, (((long) valueEnd + 1) << 32) + (valueEnd));
+				pendingMemberValueName = new MemberValuePair(memberValueName, start, end, fakeExpression);
+			}
+			parser.identifierPtr = this.identifierPtr;
+			parser.identifierLengthPtr = this.identifierLengthPtr;
+			TypeReference typeReference = parser.getAnnotationType();
+
+			switch (this.kind) {
+				case NORMAL:
+					if (parser.astPtr > -1 && parser.astStack[parser.astPtr] instanceof MemberValuePair) {
+						MemberValuePair[] memberValuePairs = null;
+
+						int argLength = parser.astLengthStack[parser.astLengthPtr];
+						int argStart = parser.astPtr - argLength + 1;
+
+						if (argLength > 0) {
+							int annotationEnd;
+							if (pendingMemberValueName != null) {
+								memberValuePairs = new MemberValuePair[argLength + 1];
+
+								System.arraycopy(parser.astStack, argStart, memberValuePairs, 0, argLength);
+								parser.astLengthPtr--;
+								parser.astPtr -= argLength;
+
+								memberValuePairs[argLength] = pendingMemberValueName;
+
+								annotationEnd = pendingMemberValueName.sourceEnd;
+							} else {
+								memberValuePairs = new MemberValuePair[argLength];
+
+								System.arraycopy(parser.astStack, argStart, memberValuePairs, 0, argLength);
+								parser.astLengthPtr--;
+								parser.astPtr -= argLength;
+
+								MemberValuePair lastMemberValuePair = memberValuePairs[memberValuePairs.length - 1];
+
+								annotationEnd =
+									lastMemberValuePair.value != null
+										? lastMemberValuePair.value instanceof Annotation
+												? ((Annotation)lastMemberValuePair.value).declarationSourceEnd
+												: lastMemberValuePair.value.sourceEnd
+										: lastMemberValuePair.sourceEnd;
+							}
+
+							NormalAnnotation normalAnnotation = new NormalAnnotation(typeReference, this.sourceStart);
+							normalAnnotation.memberValuePairs = memberValuePairs;
+							normalAnnotation.declarationSourceEnd = annotationEnd;
+							normalAnnotation.bits |= ASTNode.IsRecovered;
+
+							annot = normalAnnotation;
+
+							needUpdateRParenPos = true;
+						}
+					}
+
+
+					break;
+				case SINGLE_MEMBER:
+					if (parser.expressionPtr > -1) {
+						Expression memberValue = parser.expressionStack[parser.expressionPtr--];
+
+						SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.sourceStart);
+						singleMemberAnnotation.memberValue = memberValue;
+						singleMemberAnnotation.declarationSourceEnd = memberValue.sourceEnd;
+						singleMemberAnnotation.bits |= ASTNode.IsRecovered;
+
+						annot = singleMemberAnnotation;
+
+						needUpdateRParenPos = true;
+					}
+					break;
+			}
+
+			if (!needUpdateRParenPos) {
+				if (pendingMemberValueName != null) {
+					NormalAnnotation normalAnnotation = new NormalAnnotation(typeReference, this.sourceStart);
+					normalAnnotation.memberValuePairs = new MemberValuePair[]{pendingMemberValueName};
+					normalAnnotation.declarationSourceEnd = pendingMemberValueName.value.sourceEnd;
+					normalAnnotation.bits |= ASTNode.IsRecovered;
+
+					annot = normalAnnotation;
+				} else {
+					MarkerAnnotation markerAnnotation = new MarkerAnnotation(typeReference, this.sourceStart);
+					markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
+					markerAnnotation.bits |= ASTNode.IsRecovered;
+
+					annot = markerAnnotation;
+				}
+			}
+
+			parser.currentElement = addAnnotation(annot, this.identifierPtr);
+			parser.annotationRecoveryCheckPoint(annot.sourceStart, annot.declarationSourceEnd);
+			if (this.parent != null) {
+
+				this.parent.updateFromParserState();
+			}
+		}
+	}
+
+	public ASTNode parseTree() {
+		return this.annotation;
+	}
+
+	public void resetPendingModifiers() {
+		if (this.parent != null) this.parent.resetPendingModifiers();
+	}
+
+	public void setKind(int kind) {
+		this.kind = kind;
+	}
+
+	public int sourceEnd() {
+		if (this.annotation == null) {
+			Parser parser = parser();
+			if (this.identifierPtr < parser.identifierPositionStack.length) {
+				return (int) parser.identifierPositionStack[this.identifierPtr];
+			} else {
+				return this.sourceStart;
+			}
+		}
+		return this.annotation.declarationSourceEnd;
+	}
+
+	public String toString(int tab) {
+		if (this.annotation != null) {
+			return tabString(tab) + "Recovered annotation:\n" + this.annotation.print(tab + 1, new StringBuffer(10)); //$NON-NLS-1$
+		} else {
+			return tabString(tab) + "Recovered annotation: identiferPtr=" + this.identifierPtr + " identiferlengthPtr=" + this.identifierLengthPtr + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+
+	public Annotation updatedAnnotationReference() {
+		return this.annotation;
+	}
+
+	public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+		if (this.bracketBalance > 0){ // was an member value array initializer
+			this.bracketBalance--;
+			return this;
+		}
+		if (this.parent != null){
+			return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+		}
+		return this;
+	}
+
+	public void updateParseTree() {
+		updatedAnnotationReference();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
new file mode 100644
index 0000000..1d74fe8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
@@ -0,0 +1,474 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class RecoveredBlock extends RecoveredStatement implements TerminalTokens {
+
+	public Block blockDeclaration;
+	public RecoveredStatement[] statements;
+	public int statementCount;
+	public boolean preserveContent = false;
+	public RecoveredLocalVariable pendingArgument;
+
+	int pendingModifiers;
+	int pendingModifersSourceStart = -1;
+	RecoveredAnnotation[] pendingAnnotations;
+	int pendingAnnotationCount;
+
+public RecoveredBlock(Block block, RecoveredElement parent, int bracketBalance){
+	super(block, parent, bracketBalance);
+	this.blockDeclaration = block;
+	this.foundOpeningBrace = true;
+
+	this.preserveContent = parser().methodRecoveryActivated || parser().statementRecoveryActivated;
+}
+public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
+	if (this.parent != null && this.parent instanceof RecoveredMethod) {
+		RecoveredMethod enclosingRecoveredMethod = (RecoveredMethod) this.parent;
+		if (enclosingRecoveredMethod.methodBody == this && enclosingRecoveredMethod.parent == null) {
+			resetPendingModifiers();
+			// the element cannot be added because we are in the body of a top level method
+			return this; // ignore this element
+		}
+	}
+	return super.add(methodDeclaration, bracketBalanceValue);
+}
+/*
+ * Record a nested block declaration
+ */
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* do not consider a nested block starting passed the block end (if set)
+		it must be belonging to an enclosing block */
+	if (this.blockDeclaration.sourceEnd != 0
+		&& nestedBlockDeclaration.sourceStart > this.blockDeclaration.sourceEnd){
+		return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+	}
+
+	RecoveredBlock element = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
+
+	// if we have a pending Argument, promote it into the new block
+	if (this.pendingArgument != null){
+		element.attach(this.pendingArgument);
+		this.pendingArgument = null;
+	}
+	if(parser().statementRecoveryActivated) {
+		addBlockStatement(element);
+	}
+	attach(element);
+	if (nestedBlockDeclaration.sourceEnd == 0) return element;
+	return this;
+}
+/*
+ * Record a local declaration
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+	return this.add(localDeclaration, bracketBalanceValue, false);
+}
+/*
+ * Record a local declaration
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue, boolean delegatedByParent) {
+
+	/* local variables inside method can only be final and non void */
+/*
+	char[][] localTypeName;
+	if ((localDeclaration.modifiers & ~AccFinal) != 0 // local var can only be final
+		|| (localDeclaration.type == null) // initializer
+		|| ((localTypeName = localDeclaration.type.getTypeName()).length == 1 // non void
+			&& CharOperation.equals(localTypeName[0], VoidBinding.sourceName()))){
+
+		if (delegatedByParent){
+			return this; //ignore
+		} else {
+			this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
+			return this.parent.add(localDeclaration, bracketBalance);
+		}
+	}
+*/
+		/* do not consider a local variable starting passed the block end (if set)
+		it must be belonging to an enclosing block */
+	if (this.blockDeclaration.sourceEnd != 0
+			&& localDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){
+		resetPendingModifiers();
+		if (delegatedByParent) return this; //ignore
+		return this.parent.add(localDeclaration, bracketBalanceValue);
+	}
+
+	RecoveredLocalVariable element = new RecoveredLocalVariable(localDeclaration, this, bracketBalanceValue);
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	if (localDeclaration instanceof Argument){
+		this.pendingArgument = element;
+		return this;
+	}
+
+	attach(element);
+	if (localDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+/*
+ * Record a statement declaration
+ */
+public RecoveredElement add(Statement stmt, int bracketBalanceValue) {
+	return this.add(stmt, bracketBalanceValue, false);
+}
+
+/*
+ * Record a statement declaration
+ */
+public RecoveredElement add(Statement stmt, int bracketBalanceValue, boolean delegatedByParent) {
+	resetPendingModifiers();
+
+	/* do not consider a nested block starting passed the block end (if set)
+		it must be belonging to an enclosing block */
+	if (this.blockDeclaration.sourceEnd != 0
+			&& stmt.sourceStart > this.blockDeclaration.sourceEnd){
+		if (delegatedByParent) return this; //ignore
+		return this.parent.add(stmt, bracketBalanceValue);
+	}
+
+	RecoveredStatement element = new RecoveredStatement(stmt, this, bracketBalanceValue);
+	attach(element);
+	if (stmt.sourceEnd == 0) return element;
+	return this;
+}
+/*
+ * Addition of a type to an initializer (act like inside method body)
+ */
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+	return this.add(typeDeclaration, bracketBalanceValue, false);
+}
+/*
+ * Addition of a type to an initializer (act like inside method body)
+ */
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue, boolean delegatedByParent) {
+
+	/* do not consider a type starting passed the block end (if set)
+		it must be belonging to an enclosing block */
+	if (this.blockDeclaration.sourceEnd != 0
+			&& typeDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){
+		resetPendingModifiers();
+		if (delegatedByParent) return this; //ignore
+		return this.parent.add(typeDeclaration, bracketBalanceValue);
+	}
+
+	RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+	attach(element);
+	if (typeDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	if (this.pendingAnnotations == null) {
+		this.pendingAnnotations = new RecoveredAnnotation[5];
+		this.pendingAnnotationCount = 0;
+	} else {
+		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
+			System.arraycopy(
+				this.pendingAnnotations,
+				0,
+				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
+				0,
+				this.pendingAnnotationCount);
+		}
+	}
+
+	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);
+
+	this.pendingAnnotations[this.pendingAnnotationCount++] = element;
+
+	return element;
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	this.pendingModifiers |= flag;
+
+	if (this.pendingModifersSourceStart < 0) {
+		this.pendingModifersSourceStart = modifiersSourceStart;
+	}
+}
+/*
+ * Attach a recovered statement
+ */
+void attach(RecoveredStatement recoveredStatement) {
+
+	if (this.statements == null) {
+		this.statements = new RecoveredStatement[5];
+		this.statementCount = 0;
+	} else {
+		if (this.statementCount == this.statements.length) {
+			System.arraycopy(
+				this.statements,
+				0,
+				(this.statements = new RecoveredStatement[2 * this.statementCount]),
+				0,
+				this.statementCount);
+		}
+	}
+	this.statements[this.statementCount++] = recoveredStatement;
+}
+void attachPendingModifiers(RecoveredAnnotation[] pendingAnnots, int pendingAnnotCount, int pendingMods, int pendingModsSourceStart) {
+	this.pendingAnnotations = pendingAnnots;
+	this.pendingAnnotationCount = pendingAnnotCount;
+	this.pendingModifiers = pendingMods;
+	this.pendingModifersSourceStart = pendingModsSourceStart;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.blockDeclaration;
+}
+public void resetPendingModifiers() {
+	this.pendingAnnotations = null;
+	this.pendingAnnotationCount = 0;
+	this.pendingModifiers = 0;
+	this.pendingModifersSourceStart = -1;
+}
+public String toString(int tab) {
+	StringBuffer result = new StringBuffer(tabString(tab));
+	result.append("Recovered block:\n"); //$NON-NLS-1$
+	this.blockDeclaration.print(tab + 1, result);
+	if (this.statements != null) {
+		for (int i = 0; i < this.statementCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.statements[i].toString(tab + 1));
+		}
+	}
+	return result.toString();
+}
+/*
+ * Rebuild a block from the nested structure which is in scope
+ */
+public Block updatedBlock(int depth, Set knownTypes){
+
+	// if block was not marked to be preserved or empty, then ignore it
+	if (!this.preserveContent || this.statementCount == 0) return null;
+
+	Statement[] updatedStatements = new Statement[this.statementCount];
+	int updatedCount = 0;
+
+
+	// may need to update the end of the last statement
+	RecoveredStatement lastStatement = this.statements[this.statementCount - 1];
+	RecoveredMethod enclosingMethod = enclosingMethod();
+	RecoveredInitializer enclosingIntializer = enclosingInitializer();
+	int bodyEndValue = 0;
+	if(enclosingMethod != null) {
+		bodyEndValue = enclosingMethod.methodDeclaration.bodyEnd;
+		if(enclosingIntializer != null && enclosingMethod.methodDeclaration.sourceStart < enclosingIntializer.fieldDeclaration.sourceStart) {
+			bodyEndValue = enclosingIntializer.fieldDeclaration.declarationSourceEnd;
+		}
+	} else if(enclosingIntializer != null) {
+		bodyEndValue = enclosingIntializer.fieldDeclaration.declarationSourceEnd;
+	} else {
+		bodyEndValue = this.blockDeclaration.sourceEnd - 1;
+	}
+
+	if(lastStatement instanceof RecoveredLocalVariable) {
+		RecoveredLocalVariable lastLocalVariable = (RecoveredLocalVariable) lastStatement;
+		if(lastLocalVariable.localDeclaration.declarationSourceEnd == 0) {
+			lastLocalVariable.localDeclaration.declarationSourceEnd = bodyEndValue;
+			lastLocalVariable.localDeclaration.declarationEnd = bodyEndValue;
+		}
+	} else if(lastStatement instanceof RecoveredBlock) {
+		RecoveredBlock lastBlock = (RecoveredBlock) lastStatement;
+		if(lastBlock.blockDeclaration.sourceEnd == 0) {
+			lastBlock.blockDeclaration.sourceEnd = bodyEndValue;
+		}
+	} else if(!(lastStatement instanceof RecoveredType)){
+		if(lastStatement.statement.sourceEnd == 0) {
+			lastStatement.statement.sourceEnd = bodyEndValue;
+		}
+	}
+
+	int lastEnd = this.blockDeclaration.sourceStart;
+
+	// only collect the non-null updated statements
+	for (int i = 0; i < this.statementCount; i++){
+		Statement updatedStatement = this.statements[i].updatedStatement(depth, knownTypes);
+		if (updatedStatement != null){
+			updatedStatements[updatedCount++] = updatedStatement;
+
+			if (updatedStatement instanceof LocalDeclaration) {
+				LocalDeclaration localDeclaration = (LocalDeclaration) updatedStatement;
+				if(localDeclaration.declarationSourceEnd > lastEnd) {
+					lastEnd = localDeclaration.declarationSourceEnd;
+				}
+			} else if (updatedStatement instanceof TypeDeclaration) {
+				TypeDeclaration typeDeclaration = (TypeDeclaration) updatedStatement;
+				if(typeDeclaration.declarationSourceEnd > lastEnd) {
+					lastEnd = typeDeclaration.declarationSourceEnd;
+				}
+			} else {
+				if (updatedStatement.sourceEnd > lastEnd) {
+					lastEnd = updatedStatement.sourceEnd;
+				}
+			}
+		}
+	}
+	if (updatedCount == 0) return null; // not interesting block
+
+	// resize statement collection if necessary
+	if (updatedCount != this.statementCount){
+		this.blockDeclaration.statements = new Statement[updatedCount];
+		System.arraycopy(updatedStatements, 0, this.blockDeclaration.statements, 0, updatedCount);
+	} else {
+		this.blockDeclaration.statements = updatedStatements;
+	}
+
+	if (this.blockDeclaration.sourceEnd == 0) {
+		if(lastEnd < bodyEndValue) {
+			this.blockDeclaration.sourceEnd = bodyEndValue;
+		} else {
+			this.blockDeclaration.sourceEnd = lastEnd;
+		}
+	}
+
+	return this.blockDeclaration;
+}
+/*
+ * Rebuild a statement from the nested structure which is in scope
+ */
+public Statement updatedStatement(int depth, Set knownTypes){
+
+	return updatedBlock(depth, knownTypes);
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if ((--this.bracketBalance <= 0) && (this.parent != null)){
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+
+		/* if the block is the method body, then it closes the method too */
+		RecoveredMethod method = enclosingMethod();
+		if (method != null && method.methodBody == this){
+			return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+		}
+		RecoveredInitializer initializer = enclosingInitializer();
+		if (initializer != null && initializer.initializerBody == this){
+			return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+		}
+		return this.parent;
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+
+	// create a nested block
+	Block block = new Block(0);
+	block.sourceStart = parser().scanner.startPosition;
+	return this.add(block, 1);
+}
+/*
+ * Final update the corresponding parse node
+ */
+public void updateParseTree(){
+
+	updatedBlock(0, new HashSet());
+}
+/*
+ * Rebuild a flattened block from the nested structure which is in scope
+ */
+public Statement updateStatement(int depth, Set knownTypes){
+
+	// if block was closed or empty, then ignore it
+	if (this.blockDeclaration.sourceEnd != 0 || this.statementCount == 0) return null;
+
+	Statement[] updatedStatements = new Statement[this.statementCount];
+	int updatedCount = 0;
+
+	// only collect the non-null updated statements
+	for (int i = 0; i < this.statementCount; i++){
+		Statement updatedStatement = this.statements[i].updatedStatement(depth, knownTypes);
+		if (updatedStatement != null){
+			updatedStatements[updatedCount++] = updatedStatement;
+		}
+	}
+	if (updatedCount == 0) return null; // not interesting block
+
+	// resize statement collection if necessary
+	if (updatedCount != this.statementCount){
+		this.blockDeclaration.statements = new Statement[updatedCount];
+		System.arraycopy(updatedStatements, 0, this.blockDeclaration.statements, 0, updatedCount);
+	} else {
+		this.blockDeclaration.statements = updatedStatements;
+	}
+
+	return this.blockDeclaration;
+}
+
+/*
+ * Record a field declaration
+ */
+public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* local variables inside method can only be final and non void */
+	char[][] fieldTypeName;
+	if ((fieldDeclaration.modifiers & ~ClassFileConstants.AccFinal) != 0 // local var can only be final
+		|| (fieldDeclaration.type == null) // initializer
+		|| ((fieldTypeName = fieldDeclaration.type.getTypeName()).length == 1 // non void
+			&& CharOperation.equals(fieldTypeName[0], TypeBinding.VOID.sourceName()))){
+		this.updateSourceEndIfNecessary(previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
+		return this.parent.add(fieldDeclaration, bracketBalanceValue);
+	}
+
+	/* do not consider a local variable starting passed the block end (if set)
+		it must be belonging to an enclosing block */
+	if (this.blockDeclaration.sourceEnd != 0
+		&& fieldDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){
+		return this.parent.add(fieldDeclaration, bracketBalanceValue);
+	}
+
+	// ignore the added field, since indicates a local variable behind recovery point
+	// which thus got parsed as a field reference. This can happen if restarting after
+	// having reduced an assistNode to get the following context (see 1GEK7SG)
+	return this;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
new file mode 100644
index 0000000..4833bf7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal structure for parsing recovery
+ */
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class RecoveredElement {
+
+	public RecoveredElement parent;
+	public int bracketBalance;
+	public boolean foundOpeningBrace;
+	protected Parser recoveringParser;
+public RecoveredElement(RecoveredElement parent, int bracketBalance){
+	this(parent, bracketBalance, null);
+}
+public RecoveredElement(RecoveredElement parent, int bracketBalance, Parser parser){
+	this.parent = parent;
+	this.bracketBalance = bracketBalance;
+	this.recoveringParser = parser;
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(annotationStart - 1));
+	return this.parent.addAnnotationName(identifierPtr, identifierLengthPtr, annotationStart, bracketBalanceValue);
+}
+/*
+ *	Record a method declaration
+ */
+public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(methodDeclaration.declarationSourceStart - 1));
+	return this.parent.add(methodDeclaration, bracketBalanceValue);
+}
+/*
+ * Record a nested block declaration
+ */
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(nestedBlockDeclaration.sourceStart - 1));
+	return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+}
+/*
+ * Record a field declaration
+ */
+public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
+	return this.parent.add(fieldDeclaration, bracketBalanceValue);
+}
+/*
+ *	Record an import reference
+ */
+public RecoveredElement add(ImportReference importReference, int bracketBalanceValue){
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(importReference.declarationSourceStart - 1));
+	return this.parent.add(importReference, bracketBalanceValue);
+}
+/*
+ * Record a local declaration
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
+	return this.parent.add(localDeclaration, bracketBalanceValue);
+}
+/*
+ * Record a statement
+ */
+public RecoveredElement add(Statement statement, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	if (this instanceof RecoveredType) {
+		TypeDeclaration typeDeclaration = ((RecoveredType) this).typeDeclaration;
+		if (typeDeclaration != null && (typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) { 
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291040, new X(<SelectOnMessageSend:zoo()>) { ???
+			if (statement.sourceStart > typeDeclaration.sourceStart && statement.sourceEnd < typeDeclaration.sourceEnd) {
+				return this;
+			}
+		}
+	}
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(statement.sourceStart - 1));
+	return this.parent.add(statement, bracketBalanceValue);
+}
+/*
+ *	Record a type declaration
+ */
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue){
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	this.updateSourceEndIfNecessary(previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));
+	return this.parent.add(typeDeclaration, bracketBalanceValue);
+}
+protected void addBlockStatement(RecoveredBlock recoveredBlock) {
+	Block block = recoveredBlock.blockDeclaration;
+	if(block.statements != null) {
+		Statement[] statements = block.statements;
+		for (int i = 0; i < statements.length; i++) {
+			recoveredBlock.add(statements[i], 0);
+		}
+	}
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	// default implementation: do nothing
+}
+/*
+ * Answer the depth of this element, considering the parent link.
+ */
+public int depth(){
+	int depth = 0;
+	RecoveredElement current = this;
+	while ((current = current.parent) != null) depth++;
+	return depth;
+}
+/*
+ * Answer the enclosing method node, or null if none
+ */
+public RecoveredInitializer enclosingInitializer(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current instanceof RecoveredInitializer){
+			return (RecoveredInitializer) current;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+/*
+ * Answer the enclosing method node, or null if none
+ */
+public RecoveredMethod enclosingMethod(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current instanceof RecoveredMethod){
+			return (RecoveredMethod) current;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+/*
+ * Answer the enclosing type node, or null if none
+ */
+public RecoveredType enclosingType(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current instanceof RecoveredType){
+			return (RecoveredType) current;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+/*
+ * Answer the closest specified parser
+ */
+public Parser parser(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current.recoveringParser != null){
+			return current.recoveringParser;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return null;
+}
+public void resetPendingModifiers() {
+	// default implementation: do nothing
+	// recovered elements which have pending modifiers must override this method
+}
+/*
+ * Iterate the enclosing blocks and tag them so as to preserve their content
+ */
+public void preserveEnclosingBlocks(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current instanceof RecoveredBlock){
+			((RecoveredBlock)current).preserveContent = true;
+		}
+		if (current instanceof RecoveredType){ // for anonymous types
+			((RecoveredType)current).preserveContent = true;
+		}
+		current = current.parent;
+	}
+}
+/*
+ * Answer the position of the previous line end if
+ * there is nothing but spaces in between it and the
+ * line end. Used to trim spaces on unclosed elements.
+ */
+public int previousAvailableLineEnd(int position){
+
+	Parser parser = parser();
+	if (parser == null) return position;
+
+	Scanner scanner = parser.scanner;
+	if (scanner.lineEnds == null) return position;
+
+	int index = Util.getLineNumber(position, scanner.lineEnds, 0, scanner.linePtr);
+	if (index < 2) return position;
+	int previousLineEnd = scanner.lineEnds[index-2];
+
+	char[] source = scanner.source;
+	for (int i = previousLineEnd+1; i < position; i++){
+		if (!(source[i] == ' ' || source[i] == '\t')) return position;
+	}
+	return previousLineEnd;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return 0;
+}
+protected String tabString(int tab) {
+	StringBuffer result = new StringBuffer();
+	for (int i = tab; i > 0; i--) {
+		result.append("  "); //$NON-NLS-1$
+	}
+	return result.toString();
+}
+/*
+ * Answer the top node
+ */
+public RecoveredElement topElement(){
+	RecoveredElement current = this;
+	while (current.parent != null){
+		current = current.parent;
+	}
+	return current;
+}
+public String toString() {
+	return toString(0);
+}
+public String toString(int tab) {
+	return super.toString();
+}
+/*
+ * Answer the enclosing type node, or null if none
+ */
+public RecoveredType type(){
+	RecoveredElement current = this;
+	while (current != null){
+		if (current instanceof RecoveredType){
+			return (RecoveredType) current;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+/*
+ * Update the bodyStart of the corresponding parse node
+ */
+public void updateBodyStart(int bodyStart){
+	this.foundOpeningBrace = true;
+}
+/*
+ * Update the corresponding parse node from parser state which
+ * is about to disappear because of restarting recovery
+ */
+public void updateFromParserState(){
+	// default implementation: do nothing
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if ((--this.bracketBalance <= 0) && (this.parent != null)){
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+		return this.parent;
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+/*public RecoveredElement updateOnOpeningBrace(int braceEnd){return null;}*/
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+
+	if (this.bracketBalance++ == 0){
+		updateBodyStart(braceEnd + 1);
+		return this;
+	}
+	return null; // no update is necessary
+}
+/*
+ * Final update the corresponding parse node
+ */
+public void updateParseTree(){
+	// default implementation: do nothing
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
+	// default implementation: do nothing
+}
+public void updateSourceEndIfNecessary(int sourceEnd){
+	this.updateSourceEndIfNecessary(sourceEnd + 1, sourceEnd);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
new file mode 100644
index 0000000..b4423aa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal field structure for parsing recovery
+ */
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+
+public class RecoveredField extends RecoveredElement {
+
+	public FieldDeclaration fieldDeclaration;
+	boolean alreadyCompletedFieldInitialization;
+
+	public RecoveredAnnotation[] annotations;
+	public int annotationCount;
+
+	public int modifiers;
+	public int modifiersStart;
+
+	public RecoveredType[] anonymousTypes;
+	public int anonymousTypeCount;
+public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
+	this(fieldDeclaration, parent, bracketBalance, null);
+}
+public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
+	super(parent, bracketBalance, parser);
+	this.fieldDeclaration = fieldDeclaration;
+	this.alreadyCompletedFieldInitialization = fieldDeclaration.initialization != null;
+}
+/*
+ * Record a field declaration
+ */
+public RecoveredElement add(FieldDeclaration addedfieldDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any */
+	resetPendingModifiers();
+	if (this.parent == null) return this; // ignore
+	
+	if (this.fieldDeclaration.declarationSourceStart == addedfieldDeclaration.declarationSourceStart) {
+		if (this.fieldDeclaration.initialization != null) {
+			this.updateSourceEndIfNecessary(this.fieldDeclaration.initialization.sourceEnd);
+		} else {
+			this.updateSourceEndIfNecessary(this.fieldDeclaration.sourceEnd);
+		}
+	} else {
+		this.updateSourceEndIfNecessary(previousAvailableLineEnd(addedfieldDeclaration.declarationSourceStart - 1));
+	}
+	return this.parent.add(addedfieldDeclaration, bracketBalanceValue);
+}
+/*
+ * Record an expression statement if field is expecting an initialization expression,
+ * used for completion inside field initializers.
+ */
+public RecoveredElement add(Statement statement, int bracketBalanceValue) {
+
+	if (this.alreadyCompletedFieldInitialization || !(statement instanceof Expression)) {
+		return super.add(statement, bracketBalanceValue);
+	} else {
+		if (statement.sourceEnd > 0)
+				this.alreadyCompletedFieldInitialization = true;
+		// else we may still be inside the initialization, having parsed only a part of it yet
+		this.fieldDeclaration.initialization = (Expression)statement;
+		this.fieldDeclaration.declarationSourceEnd = statement.sourceEnd;
+		this.fieldDeclaration.declarationEnd = statement.sourceEnd;
+		return this;
+	}
+}
+/*
+ * Record a type declaration if this field is expecting an initialization expression
+ * and the type is an anonymous type.
+ * Used for completion inside field initializers.
+ */
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+
+	if (this.alreadyCompletedFieldInitialization
+			|| ((typeDeclaration.bits & ASTNode.IsAnonymousType) == 0)
+			|| (this.fieldDeclaration.declarationSourceEnd != 0 && typeDeclaration.sourceStart > this.fieldDeclaration.declarationSourceEnd)) {
+		return super.add(typeDeclaration, bracketBalanceValue);
+	} else {
+		// Prepare anonymous type list
+		if (this.anonymousTypes == null) {
+			this.anonymousTypes = new RecoveredType[5];
+			this.anonymousTypeCount = 0;
+		} else {
+			if (this.anonymousTypeCount == this.anonymousTypes.length) {
+				System.arraycopy(
+					this.anonymousTypes,
+					0,
+					(this.anonymousTypes = new RecoveredType[2 * this.anonymousTypeCount]),
+					0,
+					this.anonymousTypeCount);
+			}
+		}
+		// Store type declaration as an anonymous type
+		RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+		this.anonymousTypes[this.anonymousTypeCount++] = element;
+		return element;
+	}
+}
+public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
+	if (annotCount > 0) {
+		Annotation[] existingAnnotations = this.fieldDeclaration.annotations;
+		if (existingAnnotations != null) {
+			this.annotations = new RecoveredAnnotation[annotCount];
+			this.annotationCount = 0;
+			next : for (int i = 0; i < annotCount; i++) {
+				for (int j = 0; j < existingAnnotations.length; j++) {
+					if (annots[i].annotation == existingAnnotations[j]) continue next;
+				}
+				this.annotations[this.annotationCount++] = annots[i];
+			}
+		} else {
+			this.annotations = annots;
+			this.annotationCount = annotCount;
+		}
+	}
+
+	if (mods != 0) {
+		this.modifiers = mods;
+		this.modifiersStart = modsSourceStart;
+	}
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.fieldDeclaration;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.fieldDeclaration.declarationSourceEnd;
+}
+public String toString(int tab){
+	StringBuffer buffer = new StringBuffer(tabString(tab));
+	buffer.append("Recovered field:\n"); //$NON-NLS-1$
+	this.fieldDeclaration.print(tab + 1, buffer);
+	if (this.annotations != null) {
+		for (int i = 0; i < this.annotationCount; i++) {
+			buffer.append("\n"); //$NON-NLS-1$
+			buffer.append(this.annotations[i].toString(tab + 1));
+		}
+	}
+	if (this.anonymousTypes != null) {
+		for (int i = 0; i < this.anonymousTypeCount; i++){
+			buffer.append("\n"); //$NON-NLS-1$
+			buffer.append(this.anonymousTypes[i].toString(tab + 1));
+		}
+	}
+	return buffer.toString();
+}
+public FieldDeclaration updatedFieldDeclaration(int depth, Set knownTypes){
+	/* update annotations */
+	if (this.modifiers != 0) {
+		this.fieldDeclaration.modifiers |= this.modifiers;
+		if (this.modifiersStart < this.fieldDeclaration.declarationSourceStart) {
+			this.fieldDeclaration.declarationSourceStart = this.modifiersStart;
+		}
+	}
+	/* update annotations */
+	if (this.annotationCount > 0){
+		int existingCount = this.fieldDeclaration.annotations == null ? 0 : this.fieldDeclaration.annotations.length;
+		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
+		if (existingCount > 0){
+			System.arraycopy(this.fieldDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
+		}
+		for (int i = 0; i < this.annotationCount; i++){
+			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
+		}
+		this.fieldDeclaration.annotations = annotationReferences;
+
+		int start = this.annotations[0].annotation.sourceStart;
+		if (start < this.fieldDeclaration.declarationSourceStart) {
+			this.fieldDeclaration.declarationSourceStart = start;
+		}
+	}
+
+	if (this.anonymousTypes != null) {
+		if(this.fieldDeclaration.initialization == null) {
+			ArrayInitializer recoveredInitializers = null;
+			int recoveredInitializersCount = 0;
+			if (this.anonymousTypeCount > 1) {
+				recoveredInitializers = new ArrayInitializer();
+				recoveredInitializers.expressions = new Expression[this.anonymousTypeCount];
+			}
+			for (int i = 0; i < this.anonymousTypeCount; i++){
+				RecoveredType recoveredType = this.anonymousTypes[i];
+				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
+				if(typeDeclaration.declarationSourceEnd == 0) {
+					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
+					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
+				}
+				if (recoveredType.preserveContent){
+					TypeDeclaration anonymousType = recoveredType.updatedTypeDeclaration(depth + 1, knownTypes);
+					if (anonymousType != null) {
+						if (this.anonymousTypeCount > 1) {
+							if (recoveredInitializersCount == 0) {
+								this.fieldDeclaration.initialization = recoveredInitializers;
+							}
+							recoveredInitializers.expressions[recoveredInitializersCount++] = anonymousType.allocation;
+						}
+						else {
+							this.fieldDeclaration.initialization = anonymousType.allocation;							
+						}
+						int end = anonymousType.declarationSourceEnd;
+						if (end > this.fieldDeclaration.declarationSourceEnd) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=307337
+							this.fieldDeclaration.declarationSourceEnd = end;
+							this.fieldDeclaration.declarationEnd = end;
+						}
+					}
+				}
+			}
+			if (this.anonymousTypeCount > 0) this.fieldDeclaration.bits |= ASTNode.HasLocalType;
+		} else if(this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+			// fieldDeclaration is an enum constant
+			for (int i = 0; i < this.anonymousTypeCount; i++){
+				RecoveredType recoveredType = this.anonymousTypes[i];
+				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
+				if(typeDeclaration.declarationSourceEnd == 0) {
+					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
+					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
+				}
+				// if the enum is recovered then enum constants must be recovered too.
+				// depth is considered as the same as the depth of the enum
+				recoveredType.updatedTypeDeclaration(depth, knownTypes);
+			}
+		}
+	}
+	return this.fieldDeclaration;
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited.
+ *
+ * Fields have no associated braces, thus if matches, then update parent.
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if (this.bracketBalance > 0){ // was an array initializer
+		this.bracketBalance--;
+		if (this.bracketBalance == 0) {
+			if(this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+				updateSourceEndIfNecessary(braceEnd - 1);
+				return this.parent;
+			} else {
+				if (this.fieldDeclaration.declarationSourceEnd > 0)
+					this.alreadyCompletedFieldInitialization = true;
+			}
+		}
+		return this;
+	} else if (this.bracketBalance == 0) {
+		this.alreadyCompletedFieldInitialization = true;
+		updateSourceEndIfNecessary(braceEnd - 1);
+	}
+	if (this.parent != null){
+		return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+	if (this.fieldDeclaration.declarationSourceEnd == 0) {
+		if (this.fieldDeclaration.type instanceof ArrayTypeReference || this.fieldDeclaration.type instanceof ArrayQualifiedTypeReference) {
+			if (!this.alreadyCompletedFieldInitialization) {
+				this.bracketBalance++;
+				return null; // no update is necessary	(array initializer)
+			}
+		} else {  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=308980
+			// in case an initializer bracket is opened in a non-array field
+			// e.g. int field = {..
+			this.bracketBalance++;
+			return null; // no update is necessary	(array initializer)
+		}
+	}
+	if (this.fieldDeclaration.declarationSourceEnd == 0
+		&& this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT){
+		this.bracketBalance++;
+		return null; // no update is necessary	(enum constant)
+	}
+	// might be an array initializer
+	this.updateSourceEndIfNecessary(braceStart - 1, braceEnd - 1);
+	return this.parent.updateOnOpeningBrace(braceStart, braceEnd);
+}
+public void updateParseTree(){
+	updatedFieldDeclaration(0, new HashSet());
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
+	if (this.fieldDeclaration.declarationSourceEnd == 0) {
+		this.fieldDeclaration.declarationSourceEnd = bodyEnd;
+		this.fieldDeclaration.declarationEnd = bodyEnd;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java
new file mode 100644
index 0000000..3e1aad9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal import structure for parsing recovery
+ */
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class RecoveredImport extends RecoveredElement {
+
+	public ImportReference importReference;
+public RecoveredImport(ImportReference importReference, RecoveredElement parent, int bracketBalance){
+	super(parent, bracketBalance);
+	this.importReference = importReference;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.importReference;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.importReference.declarationSourceEnd;
+}
+public String toString(int tab) {
+	return tabString(tab) + "Recovered import: " + this.importReference.toString(); //$NON-NLS-1$
+}
+public ImportReference updatedImportReference(){
+
+	return this.importReference;
+}
+public void updateParseTree(){
+	updatedImportReference();
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
+	if (this.importReference.declarationSourceEnd == 0) {
+		this.importReference.declarationSourceEnd = bodyEnd;
+		this.importReference.declarationEnd = bodyEnd;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
new file mode 100644
index 0000000..13a6dfc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class RecoveredInitializer extends RecoveredField implements TerminalTokens {
+
+	public RecoveredType[] localTypes;
+	public int localTypeCount;
+
+	public RecoveredBlock initializerBody;
+
+	int pendingModifiers;
+	int pendingModifersSourceStart = -1;
+	RecoveredAnnotation[] pendingAnnotations;
+	int pendingAnnotationCount;
+
+public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
+	this(fieldDeclaration, parent, bracketBalance, null);
+}
+public RecoveredInitializer(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
+	super(fieldDeclaration, parent, bracketBalance, parser);
+	this.foundOpeningBrace = true;
+}
+/*
+ * Record a nested block declaration
+ */
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+
+	/* default behavior is to delegate recording to parent if any,
+	do not consider elements passed the known end (if set)
+	it must be belonging to an enclosing element
+	*/
+	if (this.fieldDeclaration.declarationSourceEnd > 0
+			&& nestedBlockDeclaration.sourceStart > this.fieldDeclaration.declarationSourceEnd){
+		resetPendingModifiers();
+		if (this.parent == null) return this; // ignore
+		return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+	}
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	this.initializerBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
+	if (nestedBlockDeclaration.sourceEnd == 0) return this.initializerBody;
+	return this;
+}
+/*
+ * Record a field declaration (act like inside method body)
+ */
+public RecoveredElement add(FieldDeclaration newFieldDeclaration, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* local variables inside initializer can only be final and non void */
+	char[][] fieldTypeName;
+	if ((newFieldDeclaration.modifiers & ~ClassFileConstants.AccFinal) != 0 /* local var can only be final */
+			|| (newFieldDeclaration.type == null) // initializer
+			|| ((fieldTypeName = newFieldDeclaration.type.getTypeName()).length == 1 // non void
+				&& CharOperation.equals(fieldTypeName[0], TypeBinding.VOID.sourceName()))){
+		if (this.parent == null) return this; // ignore
+		this.updateSourceEndIfNecessary(previousAvailableLineEnd(newFieldDeclaration.declarationSourceStart - 1));
+		return this.parent.add(newFieldDeclaration, bracketBalanceValue);
+	}
+
+	/* default behavior is to delegate recording to parent if any,
+	do not consider elements passed the known end (if set)
+	it must be belonging to an enclosing element
+	*/
+	if (this.fieldDeclaration.declarationSourceEnd > 0
+			&& newFieldDeclaration.declarationSourceStart > this.fieldDeclaration.declarationSourceEnd){
+		if (this.parent == null) return this; // ignore
+		return this.parent.add(newFieldDeclaration, bracketBalanceValue);
+	}
+	// still inside initializer, treat as local variable
+	return this; // ignore
+}
+/*
+ * Record a local declaration - regular method should have been created a block body
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.fieldDeclaration.declarationSourceEnd != 0
+			&& localDeclaration.declarationSourceStart > this.fieldDeclaration.declarationSourceEnd){
+		resetPendingModifiers();
+		if (this.parent == null) return this; // ignore
+		return this.parent.add(localDeclaration, bracketBalanceValue);
+	}
+	/* method body should have been created */
+	Block block = new Block(0);
+	block.sourceStart = ((Initializer)this.fieldDeclaration).sourceStart;
+	RecoveredElement element = this.add(block, 1);
+	if (this.initializerBody != null) {
+		this.initializerBody.attachPendingModifiers(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+	return element.add(localDeclaration, bracketBalanceValue);
+}
+/*
+ * Record a statement - regular method should have been created a block body
+ */
+public RecoveredElement add(Statement statement, int bracketBalanceValue) {
+
+	/* do not consider a statement starting passed the initializer end (if set)
+		it must be belonging to an enclosing type */
+	if (this.fieldDeclaration.declarationSourceEnd != 0
+			&& statement.sourceStart > this.fieldDeclaration.declarationSourceEnd){
+		resetPendingModifiers();
+		if (this.parent == null) return this; // ignore
+		return this.parent.add(statement, bracketBalanceValue);
+	}
+	/* initializer body should have been created */
+	Block block = new Block(0);
+	block.sourceStart = ((Initializer)this.fieldDeclaration).sourceStart;
+	RecoveredElement element = this.add(block, 1);
+
+	if (this.initializerBody != null) {
+		this.initializerBody.attachPendingModifiers(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	return element.add(statement, bracketBalanceValue);
+}
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.fieldDeclaration.declarationSourceEnd != 0
+			&& typeDeclaration.declarationSourceStart > this.fieldDeclaration.declarationSourceEnd){
+		resetPendingModifiers();
+		if (this.parent == null) return this; // ignore
+		return this.parent.add(typeDeclaration, bracketBalanceValue);
+	}
+	if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0  || parser().methodRecoveryActivated || parser().statementRecoveryActivated){
+		/* method body should have been created */
+		Block block = new Block(0);
+		block.sourceStart = ((Initializer)this.fieldDeclaration).sourceStart;
+		RecoveredElement element = this.add(block, 1);
+		if (this.initializerBody != null) {
+			this.initializerBody.attachPendingModifiers(
+					this.pendingAnnotations,
+					this.pendingAnnotationCount,
+					this.pendingModifiers,
+					this.pendingModifersSourceStart);
+		}
+		resetPendingModifiers();
+		return element.add(typeDeclaration, bracketBalanceValue);
+	}
+	if (this.localTypes == null) {
+		this.localTypes = new RecoveredType[5];
+		this.localTypeCount = 0;
+	} else {
+		if (this.localTypeCount == this.localTypes.length) {
+			System.arraycopy(
+				this.localTypes,
+				0,
+				(this.localTypes = new RecoveredType[2 * this.localTypeCount]),
+				0,
+				this.localTypeCount);
+		}
+	}
+	RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+	this.localTypes[this.localTypeCount++] = element;
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	return element;
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	if (this.pendingAnnotations == null) {
+		this.pendingAnnotations = new RecoveredAnnotation[5];
+		this.pendingAnnotationCount = 0;
+	} else {
+		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
+			System.arraycopy(
+				this.pendingAnnotations,
+				0,
+				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
+				0,
+				this.pendingAnnotationCount);
+		}
+	}
+
+	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);
+
+	this.pendingAnnotations[this.pendingAnnotationCount++] = element;
+
+	return element;
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	this.pendingModifiers |= flag;
+
+	if (this.pendingModifersSourceStart < 0) {
+		this.pendingModifersSourceStart = modifiersSourceStart;
+	}
+}
+public void resetPendingModifiers() {
+	this.pendingAnnotations = null;
+	this.pendingAnnotationCount = 0;
+	this.pendingModifiers = 0;
+	this.pendingModifersSourceStart = -1;
+}
+public String toString(int tab) {
+	StringBuffer result = new StringBuffer(tabString(tab));
+	result.append("Recovered initializer:\n"); //$NON-NLS-1$
+	this.fieldDeclaration.print(tab + 1, result);
+	if (this.annotations != null) {
+		for (int i = 0; i < this.annotationCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.annotations[i].toString(tab + 1));
+		}
+	}
+	if (this.initializerBody != null) {
+		result.append("\n"); //$NON-NLS-1$
+		result.append(this.initializerBody.toString(tab + 1));
+	}
+	return result.toString();
+}
+public FieldDeclaration updatedFieldDeclaration(int depth, Set knownTypes){
+
+	if (this.initializerBody != null){
+		Block block = this.initializerBody.updatedBlock(depth, knownTypes);
+		if (block != null){
+			Initializer initializer = (Initializer) this.fieldDeclaration;
+			initializer.block = block;
+
+			if (initializer.declarationSourceEnd == 0) {
+				initializer.declarationSourceEnd = block.sourceEnd;
+				initializer.bodyEnd = block.sourceEnd;
+			}
+		}
+		if (this.localTypeCount > 0) this.fieldDeclaration.bits |= ASTNode.HasLocalType;
+
+	}
+	if (this.fieldDeclaration.sourceEnd == 0){
+		this.fieldDeclaration.sourceEnd = this.fieldDeclaration.declarationSourceEnd;
+	}
+	return this.fieldDeclaration;
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if ((--this.bracketBalance <= 0) && (this.parent != null)){
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+		return this.parent;
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+	this.bracketBalance++;
+	return this; // request to restart
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
+	if (this.fieldDeclaration.declarationSourceEnd == 0) {
+		Initializer initializer = (Initializer)this.fieldDeclaration;
+		if(parser().rBraceSuccessorStart >= braceEnd) {
+			if (initializer.bodyStart < parser().rBraceEnd) {
+				initializer.declarationSourceEnd = parser().rBraceEnd;
+			} else {
+				initializer.declarationSourceEnd = initializer.bodyStart;
+			}
+			if (initializer.bodyStart < parser().rBraceStart) {
+				initializer.bodyEnd = parser().rBraceStart;
+			} else {
+				initializer.bodyEnd = initializer.bodyStart;
+			}
+		} else {
+			initializer.declarationSourceEnd = braceEnd;
+			initializer.bodyEnd  = braceStart - 1;
+		}
+		if(initializer.block != null) {
+			initializer.block.sourceEnd = initializer.declarationSourceEnd;
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
new file mode 100644
index 0000000..98dba36
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal local variable structure for parsing recovery
+ */
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+
+public class RecoveredLocalVariable extends RecoveredStatement {
+
+	public RecoveredAnnotation[] annotations;
+	public int annotationCount;
+
+	public int modifiers;
+	public int modifiersStart;
+
+	public LocalDeclaration localDeclaration;
+	boolean alreadyCompletedLocalInitialization;
+public RecoveredLocalVariable(LocalDeclaration localDeclaration, RecoveredElement parent, int bracketBalance){
+	super(localDeclaration, parent, bracketBalance);
+	this.localDeclaration = localDeclaration;
+	this.alreadyCompletedLocalInitialization = localDeclaration.initialization != null;
+}
+/*
+ * Record an expression statement if local variable is expecting an initialization expression.
+ */
+public RecoveredElement add(Statement stmt, int bracketBalanceValue) {
+
+	if (this.alreadyCompletedLocalInitialization || !(stmt instanceof Expression)) {
+		return super.add(stmt, bracketBalanceValue);
+	} else {
+		this.alreadyCompletedLocalInitialization = true;
+		this.localDeclaration.initialization = (Expression)stmt;
+		this.localDeclaration.declarationSourceEnd = stmt.sourceEnd;
+		this.localDeclaration.declarationEnd = stmt.sourceEnd;
+		return this;
+	}
+}
+public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
+	if (annotCount > 0) {
+		Annotation[] existingAnnotations = this.localDeclaration.annotations;
+		if (existingAnnotations != null) {
+			this.annotations = new RecoveredAnnotation[annotCount];
+			this.annotationCount = 0;
+			next : for (int i = 0; i < annotCount; i++) {
+				for (int j = 0; j < existingAnnotations.length; j++) {
+					if (annots[i].annotation == existingAnnotations[j]) continue next;
+				}
+				this.annotations[this.annotationCount++] = annots[i];
+			}
+		} else {
+			this.annotations = annots;
+			this.annotationCount = annotCount;
+		}
+	}
+
+	if (mods != 0) {
+		this.modifiers = mods;
+		this.modifiersStart = modsSourceStart;
+	}
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.localDeclaration;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.localDeclaration.declarationSourceEnd;
+}
+public String toString(int tab) {
+	return tabString(tab) + "Recovered local variable:\n" + this.localDeclaration.print(tab + 1, new StringBuffer(10)); //$NON-NLS-1$
+}
+public Statement updatedStatement(int depth, Set knownTypes){
+	/* update annotations */
+	if (this.modifiers != 0) {
+		this.localDeclaration.modifiers |= this.modifiers;
+		if (this.modifiersStart < this.localDeclaration.declarationSourceStart) {
+			this.localDeclaration.declarationSourceStart = this.modifiersStart;
+		}
+	}
+	/* update annotations */
+	if (this.annotationCount > 0){
+		int existingCount = this.localDeclaration.annotations == null ? 0 : this.localDeclaration.annotations.length;
+		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
+		if (existingCount > 0){
+			System.arraycopy(this.localDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
+		}
+		for (int i = 0; i < this.annotationCount; i++){
+			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
+		}
+		this.localDeclaration.annotations = annotationReferences;
+
+		int start = this.annotations[0].annotation.sourceStart;
+		if (start < this.localDeclaration.declarationSourceStart) {
+			this.localDeclaration.declarationSourceStart = start;
+		}
+	}
+	return this.localDeclaration;
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited.
+ *
+ * Fields have no associated braces, thus if matches, then update parent.
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if (this.bracketBalance > 0){ // was an array initializer
+		this.bracketBalance--;
+		if (this.bracketBalance == 0) this.alreadyCompletedLocalInitialization = true;
+		return this;
+	}
+	if (this.parent != null){
+		return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+	if (this.localDeclaration.declarationSourceEnd == 0
+		&& (this.localDeclaration.type instanceof ArrayTypeReference || this.localDeclaration.type instanceof ArrayQualifiedTypeReference)
+		&& !this.alreadyCompletedLocalInitialization){
+		this.bracketBalance++;
+		return null; // no update is necessary	(array initializer)
+	}
+	// might be an array initializer
+	this.updateSourceEndIfNecessary(braceStart - 1, braceEnd - 1);
+	return this.parent.updateOnOpeningBrace(braceStart, braceEnd);
+}
+public void updateParseTree(){
+	updatedStatement(0, new HashSet());
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
+	if (this.localDeclaration.declarationSourceEnd == 0) {
+		this.localDeclaration.declarationSourceEnd = bodyEnd;
+		this.localDeclaration.declarationEnd = bodyEnd;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
new file mode 100644
index 0000000..c7f8c80
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
@@ -0,0 +1,668 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Bug 392671
+ *          NPE with a method with explicit this and a following incomplete parameter
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Internal method structure for parsing recovery
+ */
+
+public class RecoveredMethod extends RecoveredElement implements TerminalTokens {
+
+	public AbstractMethodDeclaration methodDeclaration;
+
+	public RecoveredAnnotation[] annotations;
+	public int annotationCount;
+
+	public int modifiers;
+	public int modifiersStart;
+
+	public RecoveredType[] localTypes;
+	public int localTypeCount;
+
+	public RecoveredBlock methodBody;
+	public boolean discardBody = true;
+
+	int pendingModifiers;
+	int pendingModifersSourceStart = -1;
+	RecoveredAnnotation[] pendingAnnotations;
+	int pendingAnnotationCount;
+
+public RecoveredMethod(AbstractMethodDeclaration methodDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
+	super(parent, bracketBalance, parser);
+	this.methodDeclaration = methodDeclaration;
+	this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
+	if(this.foundOpeningBrace) {
+		this.bracketBalance++;
+	}
+}
+/*
+ * Record a nested block declaration
+ */
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+	/* default behavior is to delegate recording to parent if any,
+	do not consider elements passed the known end (if set)
+	it must be belonging to an enclosing element
+	*/
+	if (this.methodDeclaration.declarationSourceEnd > 0
+		&& nestedBlockDeclaration.sourceStart
+			> this.methodDeclaration.declarationSourceEnd){
+				resetPendingModifiers();
+				if (this.parent == null){
+					return this; // ignore
+				} else {
+					return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+				}
+	}
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+
+	this.methodBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
+	if (nestedBlockDeclaration.sourceEnd == 0) return this.methodBody;
+	return this;
+}
+/*
+ * Record a field declaration
+ */
+public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* local variables inside method can only be final and non void */
+	char[][] fieldTypeName;
+	if ((fieldDeclaration.modifiers & ~ClassFileConstants.AccFinal) != 0 // local var can only be final
+		|| (fieldDeclaration.type == null) // initializer
+		|| ((fieldTypeName = fieldDeclaration.type.getTypeName()).length == 1 // non void
+			&& CharOperation.equals(fieldTypeName[0], TypeBinding.VOID.sourceName()))){
+		if (this.parent == null){
+			return this; // ignore
+		} else {
+			this.updateSourceEndIfNecessary(previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
+			return this.parent.add(fieldDeclaration, bracketBalanceValue);
+		}
+	}
+	/* default behavior is to delegate recording to parent if any,
+	do not consider elements passed the known end (if set)
+	it must be belonging to an enclosing element
+	*/
+	if (this.methodDeclaration.declarationSourceEnd > 0
+		&& fieldDeclaration.declarationSourceStart
+			> this.methodDeclaration.declarationSourceEnd){
+		if (this.parent == null){
+			return this; // ignore
+		} else {
+			return this.parent.add(fieldDeclaration, bracketBalanceValue);
+		}
+	}
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	// still inside method, treat as local variable
+	return this; // ignore
+}
+/*
+ * Record a local declaration - regular method should have been created a block body
+ */
+public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* local variables inside method can only be final and non void */
+/*
+	char[][] localTypeName;
+	if ((localDeclaration.modifiers & ~AccFinal) != 0 // local var can only be final
+		|| (localDeclaration.type == null) // initializer
+		|| ((localTypeName = localDeclaration.type.getTypeName()).length == 1 // non void
+			&& CharOperation.equals(localTypeName[0], VoidBinding.sourceName()))){
+
+		if (this.parent == null){
+			return this; // ignore
+		} else {
+			this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
+			return this.parent.add(localDeclaration, bracketBalance);
+		}
+	}
+*/
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.methodDeclaration.declarationSourceEnd != 0
+		&& localDeclaration.declarationSourceStart > this.methodDeclaration.declarationSourceEnd){
+
+		if (this.parent == null) {
+			return this; // ignore
+		} else {
+			return this.parent.add(localDeclaration, bracketBalanceValue);
+		}
+	}
+	if (this.methodBody == null){
+		Block block = new Block(0);
+		block.sourceStart = this.methodDeclaration.bodyStart;
+		RecoveredElement currentBlock = this.add(block, 1);
+		if (this.bracketBalance > 0){
+			for (int i = 0; i < this.bracketBalance - 1; i++){
+				currentBlock = currentBlock.add(new Block(0), 1);
+			}
+			this.bracketBalance = 1;
+		}
+		return currentBlock.add(localDeclaration, bracketBalanceValue);
+	}
+	return this.methodBody.add(localDeclaration, bracketBalanceValue, true);
+}
+/*
+ * Record a statement - regular method should have been created a block body
+ */
+public RecoveredElement add(Statement statement, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.methodDeclaration.declarationSourceEnd != 0
+		&& statement.sourceStart > this.methodDeclaration.declarationSourceEnd){
+
+		if (this.parent == null) {
+			return this; // ignore
+		} else {
+			return this.parent.add(statement, bracketBalanceValue);
+		}
+	}
+	if (this.methodBody == null){
+		Block block = new Block(0);
+		block.sourceStart = this.methodDeclaration.bodyStart;
+		RecoveredElement currentBlock = this.add(block, 1);
+		if (this.bracketBalance > 0){
+			for (int i = 0; i < this.bracketBalance - 1; i++){
+				currentBlock = currentBlock.add(new Block(0), 1);
+			}
+			this.bracketBalance = 1;
+		}
+		return currentBlock.add(statement, bracketBalanceValue);
+	}
+	return this.methodBody.add(statement, bracketBalanceValue, true);
+}
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.methodDeclaration.declarationSourceEnd != 0
+		&& typeDeclaration.declarationSourceStart > this.methodDeclaration.declarationSourceEnd){
+
+		if (this.parent == null) {
+			return this; // ignore
+		}
+		return this.parent.add(typeDeclaration, bracketBalanceValue);
+	}
+	if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0 || parser().methodRecoveryActivated || parser().statementRecoveryActivated){
+		if (this.methodBody == null){
+			Block block = new Block(0);
+			block.sourceStart = this.methodDeclaration.bodyStart;
+			this.add(block, 1);
+		}
+		this.methodBody.attachPendingModifiers(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+		resetPendingModifiers();
+		return this.methodBody.add(typeDeclaration, bracketBalanceValue, true);
+	}
+	switch (TypeDeclaration.kind(typeDeclaration.modifiers)) {
+		case TypeDeclaration.INTERFACE_DECL :
+		case TypeDeclaration.ANNOTATION_TYPE_DECL :
+			resetPendingModifiers();
+			this.updateSourceEndIfNecessary(previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));
+			if (this.parent == null) {
+				return this; // ignore
+			}
+			// close the constructor
+			return this.parent.add(typeDeclaration, bracketBalanceValue);
+	}
+	if (this.localTypes == null) {
+		this.localTypes = new RecoveredType[5];
+		this.localTypeCount = 0;
+	} else {
+		if (this.localTypeCount == this.localTypes.length) {
+			System.arraycopy(
+				this.localTypes,
+				0,
+				(this.localTypes = new RecoveredType[2 * this.localTypeCount]),
+				0,
+				this.localTypeCount);
+		}
+	}
+	RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+	this.localTypes[this.localTypeCount++] = element;
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	return element;
+}
+public boolean bodyStartsAtHeaderEnd(){
+	return this.methodDeclaration.bodyStart == this.methodDeclaration.sourceEnd+1;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.methodDeclaration;
+}
+public void resetPendingModifiers() {
+	this.pendingAnnotations = null;
+	this.pendingAnnotationCount = 0;
+	this.pendingModifiers = 0;
+	this.pendingModifersSourceStart = -1;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.methodDeclaration.declarationSourceEnd;
+}
+public String toString(int tab) {
+	StringBuffer result = new StringBuffer(tabString(tab));
+	result.append("Recovered method:\n"); //$NON-NLS-1$
+	this.methodDeclaration.print(tab + 1, result);
+	if (this.annotations != null) {
+		for (int i = 0; i < this.annotationCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.annotations[i].toString(tab + 1));
+		}
+	}
+	if (this.localTypes != null) {
+		for (int i = 0; i < this.localTypeCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.localTypes[i].toString(tab + 1));
+		}
+	}
+	if (this.methodBody != null) {
+		result.append("\n"); //$NON-NLS-1$
+		result.append(this.methodBody.toString(tab + 1));
+	}
+	return result.toString();
+}
+/*
+ * Update the bodyStart of the corresponding parse node
+ */
+public void updateBodyStart(int bodyStart){
+	this.foundOpeningBrace = true;
+	this.methodDeclaration.bodyStart = bodyStart;
+}
+public AbstractMethodDeclaration updatedMethodDeclaration(int depth, Set knownTypes){
+	/* update annotations */
+	if (this.modifiers != 0) {
+		this.methodDeclaration.modifiers |= this.modifiers;
+		if (this.modifiersStart < this.methodDeclaration.declarationSourceStart) {
+			this.methodDeclaration.declarationSourceStart = this.modifiersStart;
+		}
+	}
+	/* update annotations */
+	if (this.annotationCount > 0){
+		int existingCount = this.methodDeclaration.annotations == null ? 0 : this.methodDeclaration.annotations.length;
+		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
+		if (existingCount > 0){
+			System.arraycopy(this.methodDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
+		}
+		for (int i = 0; i < this.annotationCount; i++){
+			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
+		}
+		this.methodDeclaration.annotations = annotationReferences;
+
+		int start = this.annotations[0].annotation.sourceStart;
+		if (start < this.methodDeclaration.declarationSourceStart) {
+			this.methodDeclaration.declarationSourceStart = start;
+		}
+	}
+
+	if (this.methodBody != null){
+		Block block = this.methodBody.updatedBlock(depth, knownTypes);
+		if (block != null){
+			this.methodDeclaration.statements = block.statements;
+
+			if (this.methodDeclaration.declarationSourceEnd == 0) {
+				this.methodDeclaration.declarationSourceEnd = block.sourceEnd;
+				this.methodDeclaration.bodyEnd = block.sourceEnd;
+			}
+
+			/* first statement might be an explict constructor call destinated to a special slot */
+			if (this.methodDeclaration.isConstructor()) {
+				ConstructorDeclaration constructor = (ConstructorDeclaration)this.methodDeclaration;
+				if (this.methodDeclaration.statements != null
+					&& this.methodDeclaration.statements[0] instanceof ExplicitConstructorCall){
+					constructor.constructorCall = (ExplicitConstructorCall)this.methodDeclaration.statements[0];
+					int length = this.methodDeclaration.statements.length;
+					System.arraycopy(
+						this.methodDeclaration.statements,
+						1,
+						(this.methodDeclaration.statements = new Statement[length-1]),
+						0,
+						length-1);
+					}
+					if (constructor.constructorCall == null){ // add implicit constructor call
+						constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
+					}
+			}
+		}
+	} else {
+		if (this.methodDeclaration.declarationSourceEnd == 0) {
+			if (this.methodDeclaration.sourceEnd + 1 == this.methodDeclaration.bodyStart) {
+				// right brace is missing
+				this.methodDeclaration.declarationSourceEnd = this.methodDeclaration.sourceEnd;
+				this.methodDeclaration.bodyStart = this.methodDeclaration.sourceEnd;
+				this.methodDeclaration.bodyEnd = this.methodDeclaration.sourceEnd;
+			} else {
+				this.methodDeclaration.declarationSourceEnd = this.methodDeclaration.bodyStart;
+				this.methodDeclaration.bodyEnd = this.methodDeclaration.bodyStart;
+			}
+		}
+	}
+	if (this.localTypeCount > 0) this.methodDeclaration.bits |= ASTNode.HasLocalType;
+	return this.methodDeclaration;
+}
+/*
+ * Update the corresponding parse node from parser state which
+ * is about to disappear because of restarting recovery
+ */
+public void updateFromParserState(){
+	// if parent is null then recovery already occured in diet parser.
+	if(bodyStartsAtHeaderEnd() && this.parent != null){
+		Parser parser = parser();
+		/* might want to recover arguments or thrown exceptions */
+		if (parser.listLength > 0 && parser.astLengthPtr > 0){ // awaiting interface type references
+			/* has consumed the arguments - listed elements must be thrown exceptions */
+			if (this.methodDeclaration.sourceEnd == parser.rParenPos) {
+
+				// protection for bugs 15142
+				int length = parser.astLengthStack[parser.astLengthPtr];
+				int astPtr = parser.astPtr - length;
+				boolean canConsume = astPtr >= 0;
+				if(canConsume) {
+					if((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) {
+						canConsume = false;
+					}
+					for (int i = 1, max = length + 1; i < max; i++) {
+						if(!(parser.astStack[astPtr + i ] instanceof TypeReference)) {
+							canConsume = false;
+						}
+					}
+				}
+				if (canConsume){
+					parser.consumeMethodHeaderThrowsClause();
+					// will reset typeListLength to zero
+					// thus this check will only be performed on first errorCheck after void foo() throws X, Y,
+				} else {
+					parser.listLength = 0;
+				}
+			} else {
+				/* has not consumed arguments yet, listed elements must be arguments */
+				if (parser.currentToken == TokenNameLPAREN || parser.currentToken == TokenNameSEMICOLON){
+					/* if currentToken is parenthesis this last argument is a method/field signature */
+					parser.astLengthStack[parser.astLengthPtr] --;
+					parser.astPtr --;
+					parser.listLength --;
+					parser.currentToken = 0;
+				}
+				int argLength = parser.astLengthStack[parser.astLengthPtr];
+				int argStart = parser.astPtr - argLength + 1;
+				boolean needUpdateRParenPos = parser.rParenPos < parser.lParenPos; // 12387 : rParenPos will be used
+
+				// remove unfinished annotation nodes
+				MemberValuePair[] memberValuePairs = null;
+				while (argLength > 0 && parser.astStack[parser.astPtr] instanceof MemberValuePair) {
+					System.arraycopy(parser.astStack, argStart, memberValuePairs = new MemberValuePair[argLength], 0, argLength);
+					parser.astLengthPtr--;
+					parser.astPtr -= argLength;
+
+					argLength = parser.astLengthStack[parser.astLengthPtr];
+					argStart = parser.astPtr - argLength + 1;
+					needUpdateRParenPos = true;
+				}
+
+				// to compute bodyStart, and thus used to set next checkpoint.
+				int count;
+				for (count = 0; count < argLength; count++){
+					ASTNode aNode = parser.astStack[argStart+count];
+					if(aNode instanceof Argument) {
+						Argument argument = (Argument)aNode;
+						/* cannot be an argument if non final */
+						char[][] argTypeName = argument.type.getTypeName();
+						if ((argument.modifiers & ~ClassFileConstants.AccFinal) != 0
+							|| (argTypeName.length == 1
+								&& CharOperation.equals(argTypeName[0], TypeBinding.VOID.sourceName()))){
+							parser.astLengthStack[parser.astLengthPtr] = count;
+							parser.astPtr = argStart+count-1;
+							parser.listLength = count;
+							parser.currentToken = 0;
+							break;
+						}
+						if (needUpdateRParenPos) parser.rParenPos = argument.sourceEnd + 1;
+					} else {
+						parser.astLengthStack[parser.astLengthPtr] = count;
+						parser.astPtr = argStart+count-1;
+						parser.listLength = count;
+						parser.currentToken = 0;
+						break;
+					}
+				}
+				if (parser.listLength > 0 && parser.astLengthPtr > 0){
+
+					// protection for bugs 15142
+					int length = parser.astLengthStack[parser.astLengthPtr];
+					int astPtr = parser.astPtr - length;
+					boolean canConsume = astPtr >= 0;
+					if(canConsume) {
+						if((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) {
+							canConsume = false;
+						}
+						for (int i = 1, max = length + 1; i < max; i++) {
+							if(!(parser.astStack[astPtr + i ] instanceof Argument)) {
+								canConsume = false;
+							}
+						}
+					}
+					if(canConsume) {
+						parser.consumeMethodHeaderRightParen();
+						/* fix-up positions, given they were updated against rParenPos, which did not get set */
+						if (parser.currentElement == this){ // parameter addition might have added an awaiting (no return type) method - see 1FVXQZ4 */
+							if (this.methodDeclaration.arguments != null) {
+								this.methodDeclaration.sourceEnd = this.methodDeclaration.arguments[this.methodDeclaration.arguments.length-1].sourceEnd;
+							} else {
+								this.methodDeclaration.sourceEnd = this.methodDeclaration.receiver.sourceEnd;
+							}
+							this.methodDeclaration.bodyStart = this.methodDeclaration.sourceEnd+1;
+							parser.lastCheckPoint = this.methodDeclaration.bodyStart;
+						}
+					}
+				}
+
+				if(memberValuePairs != null) {
+					System.arraycopy(memberValuePairs, 0, parser.astStack, parser.astPtr + 1, memberValuePairs.length);
+					parser.astPtr += memberValuePairs.length;
+					parser.astLengthStack[++parser.astLengthPtr] = memberValuePairs.length;
+				}
+			}
+		}
+	}
+}
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if(this.methodDeclaration.isAnnotationMethod()) {
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+		if(!this.foundOpeningBrace && this.parent != null) {
+			return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+		}
+		return this;
+	}
+	if(this.parent != null && this.parent instanceof RecoveredType) {
+		int mods = ((RecoveredType)this.parent).typeDeclaration.modifiers;
+		if (TypeDeclaration.kind(mods) == TypeDeclaration.INTERFACE_DECL) {
+			if (!this.foundOpeningBrace) {
+				this.updateSourceEndIfNecessary(braceStart - 1, braceStart - 1);
+				return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+			}
+		}
+	}
+	return super.updateOnClosingBrace(braceStart, braceEnd);
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+
+	/* in case the opening brace is close enough to the signature */
+	if (this.bracketBalance == 0){
+		/*
+			if (parser.scanner.searchLineNumber(methodDeclaration.sourceEnd)
+				!= parser.scanner.searchLineNumber(braceEnd)){
+		 */
+		switch(parser().lastIgnoredToken){
+			case -1 :
+			case TokenNamethrows :
+				break;
+			default:
+				this.foundOpeningBrace = true;
+				this.bracketBalance = 1; // pretend the brace was already there
+		}
+	}
+	return super.updateOnOpeningBrace(braceStart, braceEnd);
+}
+public void updateParseTree(){
+	updatedMethodDeclaration(0, new HashSet());
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
+	if (this.methodDeclaration.declarationSourceEnd == 0) {
+		if(parser().rBraceSuccessorStart >= braceEnd) {
+			this.methodDeclaration.declarationSourceEnd = parser().rBraceEnd;
+			this.methodDeclaration.bodyEnd = parser().rBraceStart;
+		} else {
+			this.methodDeclaration.declarationSourceEnd = braceEnd;
+			this.methodDeclaration.bodyEnd  = braceStart - 1;
+		}
+	}
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	if (this.pendingAnnotations == null) {
+		this.pendingAnnotations = new RecoveredAnnotation[5];
+		this.pendingAnnotationCount = 0;
+	} else {
+		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
+			System.arraycopy(
+				this.pendingAnnotations,
+				0,
+				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
+				0,
+				this.pendingAnnotationCount);
+		}
+	}
+
+	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);
+
+	this.pendingAnnotations[this.pendingAnnotationCount++] = element;
+
+	return element;
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	this.pendingModifiers |= flag;
+
+	if (this.pendingModifersSourceStart < 0) {
+		this.pendingModifersSourceStart = modifiersSourceStart;
+	}
+}
+void attach(TypeParameter[] parameters, int startPos) {
+	if(this.methodDeclaration.modifiers != ClassFileConstants.AccDefault) return;
+
+	int lastParameterEnd = parameters[parameters.length - 1].sourceEnd;
+
+	Parser parser = parser();
+	Scanner scanner = parser.scanner;
+	if(Util.getLineNumber(this.methodDeclaration.declarationSourceStart, scanner.lineEnds, 0, scanner.linePtr)
+			!= Util.getLineNumber(lastParameterEnd, scanner.lineEnds, 0, scanner.linePtr)) return;
+
+	if(parser.modifiersSourceStart > lastParameterEnd
+			&& parser.modifiersSourceStart < this.methodDeclaration.declarationSourceStart) return;
+
+	if (this.methodDeclaration instanceof MethodDeclaration) {
+		((MethodDeclaration)this.methodDeclaration).typeParameters = parameters;
+		this.methodDeclaration.declarationSourceStart = startPos;
+	} else if (this.methodDeclaration instanceof ConstructorDeclaration){
+		((ConstructorDeclaration)this.methodDeclaration).typeParameters = parameters;
+		this.methodDeclaration.declarationSourceStart = startPos;
+	}
+}
+public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
+	if (annotCount > 0) {
+		Annotation[] existingAnnotations = this.methodDeclaration.annotations;
+		if (existingAnnotations != null) {
+			this.annotations = new RecoveredAnnotation[annotCount];
+			this.annotationCount = 0;
+			next : for (int i = 0; i < annotCount; i++) {
+				for (int j = 0; j < existingAnnotations.length; j++) {
+					if (annots[i].annotation == existingAnnotations[j]) continue next;
+				}
+				this.annotations[this.annotationCount++] = annots[i];
+			}
+		} else {
+			this.annotations = annots;
+			this.annotationCount = annotCount;
+		}
+	}
+
+	if (mods != 0) {
+		this.modifiers = mods;
+		this.modifiersStart = modsSourceStart;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
new file mode 100644
index 0000000..5d3f653
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal statement structure for parsing recovery
+ */
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+
+public class RecoveredStatement extends RecoveredElement {
+
+	public Statement statement;
+public RecoveredStatement(Statement statement, RecoveredElement parent, int bracketBalance){
+	super(parent, bracketBalance);
+	this.statement = statement;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.statement;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.statement.sourceEnd;
+}
+public String toString(int tab){
+	return tabString(tab) + "Recovered statement:\n" + this.statement.print(tab + 1, new StringBuffer(10)); //$NON-NLS-1$
+}
+public Statement updatedStatement(int depth, Set knownTypes){
+	return this.statement;
+}
+public void updateParseTree(){
+	updatedStatement(0, new HashSet());
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
+	if (this.statement.sourceEnd == 0)
+		this.statement.sourceEnd = bodyEnd;
+}
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if ((--this.bracketBalance <= 0) && (this.parent != null)){
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+		return this.parent.updateOnClosingBrace(braceStart, braceEnd);
+	}
+	return this;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
new file mode 100644
index 0000000..9c2c3aa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
@@ -0,0 +1,802 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for
+ *								bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
+ *								bug 383973 - [1.8][compiler] syntax recovery in the presence of default methods
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+/**
+ * Internal type structure for parsing recovery
+ */
+
+public class RecoveredType extends RecoveredStatement implements TerminalTokens {
+	public static final int MAX_TYPE_DEPTH = 256;
+	
+	public TypeDeclaration typeDeclaration;
+
+	public RecoveredAnnotation[] annotations;
+	public int annotationCount;
+
+	public int modifiers;
+	public int modifiersStart;
+
+	public RecoveredType[] memberTypes;
+	public int memberTypeCount;
+	public RecoveredField[] fields;
+	public int fieldCount;
+	public RecoveredMethod[] methods;
+	public int methodCount;
+
+	public boolean preserveContent = false;	// only used for anonymous types
+	public int bodyEnd;
+
+	public boolean insideEnumConstantPart = false;
+
+	public TypeParameter[] pendingTypeParameters;
+	public int pendingTypeParametersStart;
+
+	int pendingModifiers;
+	int pendingModifersSourceStart = -1;
+	RecoveredAnnotation[] pendingAnnotations;
+	int pendingAnnotationCount;
+
+public RecoveredType(TypeDeclaration typeDeclaration, RecoveredElement parent, int bracketBalance){
+	super(typeDeclaration, parent, bracketBalance);
+	this.typeDeclaration = typeDeclaration;
+	if(typeDeclaration.allocation != null && typeDeclaration.allocation.type == null) {
+		// an enum constant body can not exist if there is no opening brace
+		this.foundOpeningBrace = true;
+	} else {
+		this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
+	}
+	this.insideEnumConstantPart = TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL;
+	if(this.foundOpeningBrace) {
+		this.bracketBalance++;
+	}
+
+	this.preserveContent = parser().methodRecoveryActivated || parser().statementRecoveryActivated;
+}
+public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
+
+	/* do not consider a method starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.typeDeclaration.declarationSourceEnd != 0
+		&& methodDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd){
+		this.pendingTypeParameters = null;
+		resetPendingModifiers();
+
+		return this.parent.add(methodDeclaration, bracketBalanceValue);
+	}
+
+	if (this.methods == null) {
+		this.methods = new RecoveredMethod[5];
+		this.methodCount = 0;
+	} else {
+		if (this.methodCount == this.methods.length) {
+			System.arraycopy(
+				this.methods,
+				0,
+				(this.methods = new RecoveredMethod[2 * this.methodCount]),
+				0,
+				this.methodCount);
+		}
+	}
+	RecoveredMethod element = new RecoveredMethod(methodDeclaration, this, bracketBalanceValue, this.recoveringParser);
+	this.methods[this.methodCount++] = element;
+
+	if(this.pendingTypeParameters != null) {
+		element.attach(this.pendingTypeParameters, this.pendingTypeParametersStart);
+		this.pendingTypeParameters = null;
+	}
+
+	if(this.pendingAnnotationCount > 0 || this.pendingModifiers != 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	this.insideEnumConstantPart = false;
+
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	/* if method not finished, then method becomes current */
+	if (methodDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+public RecoveredElement add(Block nestedBlockDeclaration,int bracketBalanceValue) {
+	this.pendingTypeParameters = null;
+	resetPendingModifiers();
+
+	int mods = ClassFileConstants.AccDefault;
+	if(parser().recoveredStaticInitializerStart != 0) {
+		mods = ClassFileConstants.AccStatic;
+	}
+	return this.add(new Initializer(nestedBlockDeclaration, mods), bracketBalanceValue);
+}
+public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
+	this.pendingTypeParameters = null;
+
+	/* do not consider a field starting passed the type end (if set)
+	it must be belonging to an enclosing type */
+	if (this.typeDeclaration.declarationSourceEnd != 0
+		&& fieldDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd) {
+
+		resetPendingModifiers();
+
+		return this.parent.add(fieldDeclaration, bracketBalanceValue);
+	}
+	if (this.fields == null) {
+		this.fields = new RecoveredField[5];
+		this.fieldCount = 0;
+	} else {
+		if (this.fieldCount == this.fields.length) {
+			System.arraycopy(
+				this.fields,
+				0,
+				(this.fields = new RecoveredField[2 * this.fieldCount]),
+				0,
+				this.fieldCount);
+		}
+	}
+	RecoveredField element;
+	switch (fieldDeclaration.getKind()) {
+		case AbstractVariableDeclaration.FIELD:
+		case AbstractVariableDeclaration.ENUM_CONSTANT:
+			element = new RecoveredField(fieldDeclaration, this, bracketBalanceValue);
+			break;
+		case AbstractVariableDeclaration.INITIALIZER:
+			element = new RecoveredInitializer(fieldDeclaration, this, bracketBalanceValue);
+			break;
+		default:
+			// never happens, as field is always identified
+			return this;
+	}
+	this.fields[this.fieldCount++] = element;
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	/* if field not finished, then field becomes current */
+	if (fieldDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+public RecoveredElement add(TypeDeclaration memberTypeDeclaration, int bracketBalanceValue) {
+	this.pendingTypeParameters = null;
+
+	/* do not consider a type starting passed the type end (if set)
+		it must be belonging to an enclosing type */
+	if (this.typeDeclaration.declarationSourceEnd != 0
+		&& memberTypeDeclaration.declarationSourceStart > this.typeDeclaration.declarationSourceEnd){
+
+		resetPendingModifiers();
+
+		return this.parent.add(memberTypeDeclaration, bracketBalanceValue);
+	}
+
+	this.insideEnumConstantPart = false;
+
+	if ((memberTypeDeclaration.bits & ASTNode.IsAnonymousType) != 0){
+		if (this.methodCount > 0) {
+			// add it to the last method body
+			RecoveredMethod lastMethod = this.methods[this.methodCount-1];
+			lastMethod.methodDeclaration.bodyEnd = 0; // reopen method
+			lastMethod.methodDeclaration.declarationSourceEnd = 0; // reopen method
+			lastMethod.bracketBalance++; // expect one closing brace
+
+			resetPendingModifiers();
+
+			return lastMethod.add(memberTypeDeclaration, bracketBalanceValue);
+		} else {
+			// ignore
+			return this;
+		}
+	}
+
+	if (this.memberTypes == null) {
+		this.memberTypes = new RecoveredType[5];
+		this.memberTypeCount = 0;
+	} else {
+		if (this.memberTypeCount == this.memberTypes.length) {
+			System.arraycopy(
+				this.memberTypes,
+				0,
+				(this.memberTypes = new RecoveredType[2 * this.memberTypeCount]),
+				0,
+				this.memberTypeCount);
+		}
+	}
+	RecoveredType element = new RecoveredType(memberTypeDeclaration, this, bracketBalanceValue);
+	this.memberTypes[this.memberTypeCount++] = element;
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	/* consider that if the opening brace was not found, it is there */
+	if (!this.foundOpeningBrace){
+		this.foundOpeningBrace = true;
+		this.bracketBalance++;
+	}
+	/* if member type not finished, then member type becomes current */
+	if (memberTypeDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+public void add(TypeParameter[] parameters, int startPos) {
+	this.pendingTypeParameters = parameters;
+	this.pendingTypeParametersStart = startPos;
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	if (this.pendingAnnotations == null) {
+		this.pendingAnnotations = new RecoveredAnnotation[5];
+		this.pendingAnnotationCount = 0;
+	} else {
+		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
+			System.arraycopy(
+				this.pendingAnnotations,
+				0,
+				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
+				0,
+				this.pendingAnnotationCount);
+		}
+	}
+
+	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);
+
+	this.pendingAnnotations[this.pendingAnnotationCount++] = element;
+
+	return element;
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	this.pendingModifiers |= flag;
+
+	if (this.pendingModifersSourceStart < 0) {
+		this.pendingModifersSourceStart = modifiersSourceStart;
+	}
+}
+public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
+	if (annotCount > 0) {
+		Annotation[] existingAnnotations = this.typeDeclaration.annotations;
+		if (existingAnnotations != null) {
+			this.annotations = new RecoveredAnnotation[annotCount];
+			this.annotationCount = 0;
+			next : for (int i = 0; i < annotCount; i++) {
+				for (int j = 0; j < existingAnnotations.length; j++) {
+					if (annots[i].annotation == existingAnnotations[j]) continue next;
+				}
+				this.annotations[this.annotationCount++] = annots[i];
+			}
+		} else {
+			this.annotations = annots;
+			this.annotationCount = annotCount;
+		}
+	}
+
+	if (mods != 0) {
+		this.modifiers = mods;
+		this.modifiersStart = modsSourceStart;
+	}
+}
+/*
+ * Answer the body end of the corresponding parse node
+ */
+public int bodyEnd(){
+	if (this.bodyEnd == 0) return this.typeDeclaration.declarationSourceEnd;
+	return this.bodyEnd;
+}
+public boolean bodyStartsAtHeaderEnd(){
+	if (this.typeDeclaration.superInterfaces == null){
+		if (this.typeDeclaration.superclass == null){
+			if(this.typeDeclaration.typeParameters == null) {
+				return this.typeDeclaration.bodyStart == this.typeDeclaration.sourceEnd+1;
+			} else {
+				return this.typeDeclaration.bodyStart == this.typeDeclaration.typeParameters[this.typeDeclaration.typeParameters.length-1].sourceEnd+1;
+			}
+		} else {
+			return this.typeDeclaration.bodyStart == this.typeDeclaration.superclass.sourceEnd+1;
+		}
+	} else {
+		return this.typeDeclaration.bodyStart
+				== this.typeDeclaration.superInterfaces[this.typeDeclaration.superInterfaces.length-1].sourceEnd+1;
+	}
+}
+/*
+ * Answer the enclosing type node, or null if none
+ */
+public RecoveredType enclosingType(){
+	RecoveredElement current = this.parent;
+	while (current != null){
+		if (current instanceof RecoveredType){
+			return (RecoveredType) current;
+		}
+		current = current.parent;
+	}
+	return null;
+}
+public int lastMemberEnd() {
+	int lastMemberEnd = this.typeDeclaration.bodyStart;
+
+	if (this.fieldCount > 0) {
+		FieldDeclaration lastField = this.fields[this.fieldCount - 1].fieldDeclaration;
+		if (lastMemberEnd < lastField.declarationSourceEnd && lastField.declarationSourceEnd != 0) {
+			lastMemberEnd = lastField.declarationSourceEnd;
+		}
+	}
+
+	if (this.methodCount > 0) {
+		AbstractMethodDeclaration lastMethod = this.methods[this.methodCount - 1].methodDeclaration;
+		if (lastMemberEnd < lastMethod.declarationSourceEnd && lastMethod.declarationSourceEnd != 0) {
+			lastMemberEnd = lastMethod.declarationSourceEnd;
+		}
+	}
+
+	if (this.memberTypeCount > 0) {
+		TypeDeclaration lastType = this.memberTypes[this.memberTypeCount - 1].typeDeclaration;
+		if (lastMemberEnd < lastType.declarationSourceEnd && lastType.declarationSourceEnd != 0) {
+			lastMemberEnd = lastType.declarationSourceEnd;
+		}
+	}
+
+	return lastMemberEnd;
+}
+public char[] name(){
+	return this.typeDeclaration.name;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.typeDeclaration;
+}
+public void resetPendingModifiers() {
+	this.pendingAnnotations = null;
+	this.pendingAnnotationCount = 0;
+	this.pendingModifiers = 0;
+	this.pendingModifersSourceStart = -1;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.typeDeclaration.declarationSourceEnd;
+}
+public String toString(int tab) {
+	StringBuffer result = new StringBuffer(tabString(tab));
+	result.append("Recovered type:\n"); //$NON-NLS-1$
+	if ((this.typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+		result.append(tabString(tab));
+		result.append(" "); //$NON-NLS-1$
+	}
+	this.typeDeclaration.print(tab + 1, result);
+	if (this.annotations != null) {
+		for (int i = 0; i < this.annotationCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.annotations[i].toString(tab + 1));
+		}
+	}
+	if (this.memberTypes != null) {
+		for (int i = 0; i < this.memberTypeCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.memberTypes[i].toString(tab + 1));
+		}
+	}
+	if (this.fields != null) {
+		for (int i = 0; i < this.fieldCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.fields[i].toString(tab + 1));
+		}
+	}
+	if (this.methods != null) {
+		for (int i = 0; i < this.methodCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.methods[i].toString(tab + 1));
+		}
+	}
+	return result.toString();
+}
+/*
+ * Update the bodyStart of the corresponding parse node
+ */
+public void updateBodyStart(int bodyStart){
+	this.foundOpeningBrace = true;
+	this.typeDeclaration.bodyStart = bodyStart;
+}
+public Statement updatedStatement(int depth, Set knownTypes){
+
+	// ignore closed anonymous type
+	if ((this.typeDeclaration.bits & ASTNode.IsAnonymousType) != 0 && !this.preserveContent){
+		return null;
+	}
+
+	TypeDeclaration updatedType = updatedTypeDeclaration(depth + 1, knownTypes);
+	if (updatedType != null && (updatedType.bits & ASTNode.IsAnonymousType) != 0){
+		/* in presence of an anonymous type, we want the full allocation expression */
+		QualifiedAllocationExpression allocation = updatedType.allocation;
+
+		if (allocation.statementEnd == -1) {
+			allocation.statementEnd = updatedType.declarationSourceEnd;
+		}
+		return allocation;
+	}
+	return updatedType;
+}
+public TypeDeclaration updatedTypeDeclaration(int depth, Set knownTypes){
+	if (depth >= MAX_TYPE_DEPTH) return null;
+
+	if(knownTypes.contains(this.typeDeclaration)) return null;
+	knownTypes.add(this.typeDeclaration);
+	
+	int lastEnd = this.typeDeclaration.bodyStart;
+	/* update annotations */
+	if (this.modifiers != 0) {
+		this.typeDeclaration.modifiers |= this.modifiers;
+		if (this.modifiersStart < this.typeDeclaration.declarationSourceStart) {
+			this.typeDeclaration.declarationSourceStart = this.modifiersStart;
+		}
+	}
+	/* update annotations */
+	if (this.annotationCount > 0){
+		int existingCount = this.typeDeclaration.annotations == null ? 0 : this.typeDeclaration.annotations.length;
+		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
+		if (existingCount > 0){
+			System.arraycopy(this.typeDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
+		}
+		for (int i = 0; i < this.annotationCount; i++){
+			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
+		}
+		this.typeDeclaration.annotations = annotationReferences;
+
+		int start = this.annotations[0].annotation.sourceStart;
+		if (start < this.typeDeclaration.declarationSourceStart) {
+			this.typeDeclaration.declarationSourceStart = start;
+		}
+	}
+	/* update member types */
+	if (this.memberTypeCount > 0){
+		int existingCount = this.typeDeclaration.memberTypes == null ? 0 : this.typeDeclaration.memberTypes.length;
+		TypeDeclaration[] memberTypeDeclarations = new TypeDeclaration[existingCount + this.memberTypeCount];
+		if (existingCount > 0){
+			System.arraycopy(this.typeDeclaration.memberTypes, 0, memberTypeDeclarations, 0, existingCount);
+		}
+		// may need to update the declarationSourceEnd of the last type
+		if (this.memberTypes[this.memberTypeCount - 1].typeDeclaration.declarationSourceEnd == 0){
+			int bodyEndValue = bodyEnd();
+			this.memberTypes[this.memberTypeCount - 1].typeDeclaration.declarationSourceEnd = bodyEndValue;
+			this.memberTypes[this.memberTypeCount - 1].typeDeclaration.bodyEnd =  bodyEndValue;
+		}
+		
+		int updatedCount = 0;
+		for (int i = 0; i < this.memberTypeCount; i++){
+			TypeDeclaration updatedTypeDeclaration = this.memberTypes[i].updatedTypeDeclaration(depth + 1, knownTypes);
+			if (updatedTypeDeclaration != null) {
+				memberTypeDeclarations[existingCount + (updatedCount++)] = updatedTypeDeclaration;
+			}
+		}
+		if (updatedCount < this.memberTypeCount) {
+			int length = existingCount + updatedCount;
+			System.arraycopy(memberTypeDeclarations, 0, memberTypeDeclarations = new TypeDeclaration[length], 0, length);
+		}
+		
+		if (memberTypeDeclarations.length > 0) { 
+			this.typeDeclaration.memberTypes = memberTypeDeclarations;
+			if(memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd > lastEnd) {
+				lastEnd = memberTypeDeclarations[memberTypeDeclarations.length - 1].declarationSourceEnd;
+			}
+		}
+	}
+	/* update fields */
+	if (this.fieldCount > 0){
+		int existingCount = this.typeDeclaration.fields == null ? 0 : this.typeDeclaration.fields.length;
+		FieldDeclaration[] fieldDeclarations = new FieldDeclaration[existingCount + this.fieldCount];
+		if (existingCount > 0){
+			System.arraycopy(this.typeDeclaration.fields, 0, fieldDeclarations, 0, existingCount);
+		}
+		// may need to update the declarationSourceEnd of the last field
+		if (this.fields[this.fieldCount - 1].fieldDeclaration.declarationSourceEnd == 0){
+			int temp = bodyEnd();
+			this.fields[this.fieldCount - 1].fieldDeclaration.declarationSourceEnd = temp;
+			this.fields[this.fieldCount - 1].fieldDeclaration.declarationEnd = temp;
+		}
+		for (int i = 0; i < this.fieldCount; i++){
+			fieldDeclarations[existingCount + i] = this.fields[i].updatedFieldDeclaration(depth, knownTypes);
+		}
+		
+		for (int i = this.fieldCount - 1; 0 < i; i--) {
+			if (fieldDeclarations[existingCount + i - 1].declarationSourceStart == fieldDeclarations[existingCount + i].declarationSourceStart) {
+				fieldDeclarations[existingCount + i - 1].declarationSourceEnd = fieldDeclarations[existingCount + i].declarationSourceEnd;
+				fieldDeclarations[existingCount + i - 1].declarationEnd = fieldDeclarations[existingCount + i].declarationEnd;
+			}
+		}
+		
+		this.typeDeclaration.fields = fieldDeclarations;
+		if(fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd > lastEnd) {
+			lastEnd = fieldDeclarations[fieldDeclarations.length - 1].declarationSourceEnd;
+		}
+	}
+	/* update methods */
+	int existingCount = this.typeDeclaration.methods == null ? 0 : this.typeDeclaration.methods.length;
+	boolean hasConstructor = false, hasRecoveredConstructor = false;
+	boolean hasAbstractMethods = false;
+	int defaultConstructorIndex = -1;
+	if (this.methodCount > 0){
+		AbstractMethodDeclaration[] methodDeclarations = new AbstractMethodDeclaration[existingCount + this.methodCount];
+		for (int i = 0; i < existingCount; i++){
+			AbstractMethodDeclaration m = this.typeDeclaration.methods[i];
+			if (m.isDefaultConstructor()) defaultConstructorIndex = i;
+			if (m.isAbstract()) hasAbstractMethods = true;
+			methodDeclarations[i] = m;
+		}
+		// may need to update the declarationSourceEnd of the last method
+		if (this.methods[this.methodCount - 1].methodDeclaration.declarationSourceEnd == 0){
+			int bodyEndValue = bodyEnd();
+			this.methods[this.methodCount - 1].methodDeclaration.declarationSourceEnd = bodyEndValue;
+			this.methods[this.methodCount - 1].methodDeclaration.bodyEnd = bodyEndValue;
+		}
+		for (int i = 0; i < this.methodCount; i++){
+			AbstractMethodDeclaration updatedMethod = this.methods[i].updatedMethodDeclaration(depth, knownTypes);
+			if (updatedMethod.isConstructor()) hasRecoveredConstructor = true;
+			if (updatedMethod.isAbstract()) hasAbstractMethods = true;
+			methodDeclarations[existingCount + i] = updatedMethod;
+		}
+		this.typeDeclaration.methods = methodDeclarations;
+		if(methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd > lastEnd) {
+			lastEnd = methodDeclarations[methodDeclarations.length - 1].declarationSourceEnd;
+		}
+		if (hasAbstractMethods) this.typeDeclaration.bits |= ASTNode.HasAbstractMethods;
+		hasConstructor = this.typeDeclaration.checkConstructors(parser());
+	} else {
+		for (int i = 0; i < existingCount; i++){
+			if (this.typeDeclaration.methods[i].isConstructor()) hasConstructor = true;
+		}
+	}
+	/* add clinit ? */
+	if (this.typeDeclaration.needClassInitMethod()){
+		boolean alreadyHasClinit = false;
+		for (int i = 0; i < existingCount; i++){
+			if (this.typeDeclaration.methods[i].isClinit()){
+				alreadyHasClinit = true;
+				break;
+			}
+		}
+		if (!alreadyHasClinit) this.typeDeclaration.addClinit();
+	}
+	/* add default constructor ? */
+	if (defaultConstructorIndex >= 0 && hasRecoveredConstructor){
+		/* should discard previous default construtor */
+		AbstractMethodDeclaration[] methodDeclarations = new AbstractMethodDeclaration[this.typeDeclaration.methods.length - 1];
+		if (defaultConstructorIndex != 0){
+			System.arraycopy(this.typeDeclaration.methods, 0, methodDeclarations, 0, defaultConstructorIndex);
+		}
+		if (defaultConstructorIndex != this.typeDeclaration.methods.length-1){
+			System.arraycopy(
+				this.typeDeclaration.methods,
+				defaultConstructorIndex+1,
+				methodDeclarations,
+				defaultConstructorIndex,
+				this.typeDeclaration.methods.length - defaultConstructorIndex - 1);
+		}
+		this.typeDeclaration.methods = methodDeclarations;
+	} else {
+		int kind = TypeDeclaration.kind(this.typeDeclaration.modifiers);
+		if (!hasConstructor &&
+				kind != TypeDeclaration.INTERFACE_DECL &&
+				kind != TypeDeclaration.ANNOTATION_TYPE_DECL &&
+				this.typeDeclaration.allocation == null) {// if was already reduced, then constructor
+			boolean insideFieldInitializer = false;
+			RecoveredElement parentElement = this.parent;
+			while (parentElement != null){
+				if (parentElement instanceof RecoveredField){
+						insideFieldInitializer = true;
+						break;
+				}
+				parentElement = parentElement.parent;
+			}
+			this.typeDeclaration.createDefaultConstructor(!parser().diet || insideFieldInitializer, true);
+		}
+	}
+	if (this.parent instanceof RecoveredType){
+		this.typeDeclaration.bits |= ASTNode.IsMemberType;
+	} else if (this.parent instanceof RecoveredMethod){
+		this.typeDeclaration.bits |= ASTNode.IsLocalType;
+	}
+	if(this.typeDeclaration.declarationSourceEnd == 0) {
+		this.typeDeclaration.declarationSourceEnd = lastEnd;
+		this.typeDeclaration.bodyEnd = lastEnd;
+	}
+	return this.typeDeclaration;
+}
+/*
+ * Update the corresponding parse node from parser state which
+ * is about to disappear because of restarting recovery
+ */
+public void updateFromParserState(){
+
+	// anymous type and enum constant doesn't need to be updated
+	if(bodyStartsAtHeaderEnd() && this.typeDeclaration.allocation == null){
+		Parser parser = parser();
+		/* might want to recover implemented interfaces */
+		// protection for bugs 15142
+		if (parser.listLength > 0 && parser.astLengthPtr > 0){ // awaiting interface type references
+			int length = parser.astLengthStack[parser.astLengthPtr];
+			int astPtr = parser.astPtr - length;
+			boolean canConsume = astPtr >= 0;
+			if(canConsume) {
+				if((!(parser.astStack[astPtr] instanceof TypeDeclaration))) {
+					canConsume = false;
+				}
+				for (int i = 1, max = length + 1; i < max; i++) {
+					if(!(parser.astStack[astPtr + i ] instanceof TypeReference)) {
+						canConsume = false;
+					}
+				}
+			}
+			if(canConsume) {
+				parser.consumeClassHeaderImplements();
+				// will reset typeListLength to zero
+				// thus this check will only be performed on first errorCheck after class X implements Y,Z,
+			}
+		} else if (parser.listTypeParameterLength > 0) {
+			int length = parser.listTypeParameterLength;
+			int genericsPtr = parser.genericsPtr;
+			boolean canConsume = genericsPtr + 1 >= length && parser.astPtr > -1;
+			if(canConsume) {
+				if (!(parser.astStack[parser.astPtr] instanceof TypeDeclaration)) {
+					canConsume = false;
+				}
+				while(genericsPtr + 1 > length && !(parser.genericsStack[genericsPtr] instanceof TypeParameter)) {
+					genericsPtr--;
+				}
+				for (int i = 0; i < length; i++) {
+					if(!(parser.genericsStack[genericsPtr - i] instanceof TypeParameter)) {
+						canConsume = false;
+					}
+				}
+			}
+			if(canConsume) {
+				TypeDeclaration typeDecl = (TypeDeclaration)parser.astStack[parser.astPtr];
+				System.arraycopy(parser.genericsStack, genericsPtr - length + 1, typeDecl.typeParameters = new TypeParameter[length], 0, length);
+				typeDecl.bodyStart = typeDecl.typeParameters[length-1].declarationSourceEnd + 1;
+				parser.listTypeParameterLength = 0;
+				parser.lastCheckPoint = typeDecl.bodyStart;
+			}
+		}
+	}
+}
+/*
+ * A closing brace got consumed, might have closed the current element,
+ * in which case both the currentElement is exited
+ */
+public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
+	if ((--this.bracketBalance <= 0) && (this.parent != null)){
+		this.updateSourceEndIfNecessary(braceStart, braceEnd);
+		this.bodyEnd = braceStart - 1;
+		return this.parent;
+	}
+	return this;
+}
+/*
+ * An opening brace got consumed, might be the expected opening one of the current element,
+ * in which case the bodyStart is updated.
+ */
+public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
+	/* in case the opening brace is not close enough to the signature, ignore it */
+	if (this.bracketBalance == 0){
+		/*
+			if (parser.scanner.searchLineNumber(typeDeclaration.sourceEnd)
+				!= parser.scanner.searchLineNumber(braceEnd)){
+		 */
+		Parser parser = parser();
+		switch(parser.lastIgnoredToken){
+			case -1 :
+			case TokenNameextends :
+			case TokenNameimplements :
+			case TokenNameGREATER :
+			case TokenNameRIGHT_SHIFT :
+			case TokenNameUNSIGNED_RIGHT_SHIFT :
+				if (parser.recoveredStaticInitializerStart == 0) break;
+			//$FALL-THROUGH$
+			default:
+				this.foundOpeningBrace = true;
+				this.bracketBalance = 1; // pretend the brace was already there
+		}
+	}
+	// might be an initializer
+	if (this.bracketBalance == 1){
+		Block block = new Block(0);
+		Parser parser = parser();
+		block.sourceStart = parser.scanner.startPosition;
+		Initializer init;
+		if (parser.recoveredStaticInitializerStart == 0){
+			init = new Initializer(block, ClassFileConstants.AccDefault);
+		} else {
+			init = new Initializer(block, ClassFileConstants.AccStatic);
+			init.declarationSourceStart = parser.recoveredStaticInitializerStart;
+		}
+		init.bodyStart = parser.scanner.currentPosition;
+		return this.add(init, 1);
+	}
+	return super.updateOnOpeningBrace(braceStart, braceEnd);
+}
+public void updateParseTree(){
+	updatedTypeDeclaration(0, new HashSet());
+}
+/*
+ * Update the declarationSourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int start, int end){
+	if (this.typeDeclaration.declarationSourceEnd == 0){
+		this.bodyEnd = 0;
+		this.typeDeclaration.declarationSourceEnd = end;
+		this.typeDeclaration.bodyEnd = end;
+	}
+}
+public void annotationsConsumed(Annotation[] consumedAnnotations) {
+	RecoveredAnnotation[] keep = new RecoveredAnnotation[this.pendingAnnotationCount];
+	int numKeep = 0;
+	int pendingCount = this.pendingAnnotationCount;
+	int consumedLength = consumedAnnotations.length;
+	outerLoop:
+	for (int i = 0; i < pendingCount; i++) {
+		Annotation pendingAnnotationAST = this.pendingAnnotations[i].annotation;
+		for (int j = 0; j < consumedLength; j++) {
+			if (consumedAnnotations[j] == pendingAnnotationAST)
+				continue outerLoop;
+		}
+		keep[numKeep++] = this.pendingAnnotations[i];
+	}
+	if (numKeep != this.pendingAnnotationCount) {
+		this.pendingAnnotations = keep;
+		this.pendingAnnotationCount = numKeep;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java
new file mode 100644
index 0000000..c4c1681
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Internal field structure for parsing recovery
+ */
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+
+public class RecoveredUnit extends RecoveredElement {
+
+	public CompilationUnitDeclaration unitDeclaration;
+
+	public RecoveredImport[] imports;
+	public int importCount;
+	public RecoveredType[] types;
+	public int typeCount;
+
+	int pendingModifiers;
+	int pendingModifersSourceStart = -1;
+	RecoveredAnnotation[] pendingAnnotations;
+	int pendingAnnotationCount;
+
+public RecoveredUnit(CompilationUnitDeclaration unitDeclaration, int bracketBalance, Parser parser){
+	super(null, bracketBalance, parser);
+	this.unitDeclaration = unitDeclaration;
+}
+public RecoveredElement addAnnotationName(int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) {
+	if (this.pendingAnnotations == null) {
+		this.pendingAnnotations = new RecoveredAnnotation[5];
+		this.pendingAnnotationCount = 0;
+	} else {
+		if (this.pendingAnnotationCount == this.pendingAnnotations.length) {
+			System.arraycopy(
+				this.pendingAnnotations,
+				0,
+				(this.pendingAnnotations = new RecoveredAnnotation[2 * this.pendingAnnotationCount]),
+				0,
+				this.pendingAnnotationCount);
+		}
+	}
+
+	RecoveredAnnotation element = new RecoveredAnnotation(identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue);
+
+	this.pendingAnnotations[this.pendingAnnotationCount++] = element;
+
+	return element;
+}
+public void addModifier(int flag, int modifiersSourceStart) {
+	this.pendingModifiers |= flag;
+
+	if (this.pendingModifersSourceStart < 0) {
+		this.pendingModifersSourceStart = modifiersSourceStart;
+	}
+}
+/*
+ *	Record a method declaration: should be attached to last type
+ */
+public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) {
+
+	/* attach it to last type - if any */
+	if (this.typeCount > 0){
+		RecoveredType type = this.types[this.typeCount -1];
+		int start = type.bodyEnd;
+		int end = type.typeDeclaration.bodyEnd;
+		type.bodyEnd = 0; // reset position
+		type.typeDeclaration.declarationSourceEnd = 0; // reset position
+		type.typeDeclaration.bodyEnd = 0;
+
+		int kind = TypeDeclaration.kind(type.typeDeclaration.modifiers);
+		if(start > 0 &&
+				start < end &&
+				kind != TypeDeclaration.INTERFACE_DECL &&
+				kind != TypeDeclaration.ANNOTATION_TYPE_DECL) {
+			// the } of the last type can be considered as the end of an initializer
+			Initializer initializer = new Initializer(new Block(0), 0);
+			initializer.bodyStart = end;
+			initializer.bodyEnd = end;
+			initializer.declarationSourceStart = end;
+			initializer.declarationSourceEnd = end;
+			initializer.sourceStart = end;
+			initializer.sourceEnd = end;
+			type.add(initializer, bracketBalanceValue);
+		}
+
+		resetPendingModifiers();
+
+		return type.add(methodDeclaration, bracketBalanceValue);
+	}
+	return this; // ignore
+}
+/*
+ *	Record a field declaration: should be attached to last type
+ */
+public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
+
+	/* attach it to last type - if any */
+	if (this.typeCount > 0){
+		RecoveredType type = this.types[this.typeCount -1];
+		type.bodyEnd = 0; // reset position
+		type.typeDeclaration.declarationSourceEnd = 0; // reset position
+		type.typeDeclaration.bodyEnd = 0;
+
+		resetPendingModifiers();
+
+		return type.add(fieldDeclaration, bracketBalanceValue);
+	}
+	return this; // ignore
+}
+public RecoveredElement add(ImportReference importReference, int bracketBalanceValue) {
+	resetPendingModifiers();
+
+	if (this.imports == null) {
+		this.imports = new RecoveredImport[5];
+		this.importCount = 0;
+	} else {
+		if (this.importCount == this.imports.length) {
+			System.arraycopy(
+				this.imports,
+				0,
+				(this.imports = new RecoveredImport[2 * this.importCount]),
+				0,
+				this.importCount);
+		}
+	}
+	RecoveredImport element = new RecoveredImport(importReference, this, bracketBalanceValue);
+	this.imports[this.importCount++] = element;
+
+	/* if import not finished, then import becomes current */
+	if (importReference.declarationSourceEnd == 0) return element;
+	return this;
+}
+public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
+
+	if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0){
+		if (this.typeCount > 0) {
+			// add it to the last type
+			RecoveredType lastType = this.types[this.typeCount-1];
+			lastType.bodyEnd = 0; // reopen type
+			lastType.typeDeclaration.bodyEnd = 0; // reopen type
+			lastType.typeDeclaration.declarationSourceEnd = 0; // reopen type
+			lastType.bracketBalance++; // expect one closing brace
+
+			resetPendingModifiers();
+
+			return lastType.add(typeDeclaration, bracketBalanceValue);
+		}
+	}
+	if (this.types == null) {
+		this.types = new RecoveredType[5];
+		this.typeCount = 0;
+	} else {
+		if (this.typeCount == this.types.length) {
+			System.arraycopy(
+				this.types,
+				0,
+				(this.types = new RecoveredType[2 * this.typeCount]),
+				0,
+				this.typeCount);
+		}
+	}
+	RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
+	this.types[this.typeCount++] = element;
+
+	if(this.pendingAnnotationCount > 0) {
+		element.attach(
+				this.pendingAnnotations,
+				this.pendingAnnotationCount,
+				this.pendingModifiers,
+				this.pendingModifersSourceStart);
+	}
+	resetPendingModifiers();
+
+	/* if type not finished, then type becomes current */
+	if (typeDeclaration.declarationSourceEnd == 0) return element;
+	return this;
+}
+/*
+ * Answer the associated parsed structure
+ */
+public ASTNode parseTree(){
+	return this.unitDeclaration;
+}
+public void resetPendingModifiers() {
+	this.pendingAnnotations = null;
+	this.pendingAnnotationCount = 0;
+	this.pendingModifiers = 0;
+	this.pendingModifersSourceStart = -1;
+}
+/*
+ * Answer the very source end of the corresponding parse node
+ */
+public int sourceEnd(){
+	return this.unitDeclaration.sourceEnd;
+}
+public String toString(int tab) {
+	StringBuffer result = new StringBuffer(tabString(tab));
+	result.append("Recovered unit: [\n"); //$NON-NLS-1$
+	this.unitDeclaration.print(tab + 1, result);
+	result.append(tabString(tab + 1));
+	result.append("]"); //$NON-NLS-1$
+	if (this.imports != null) {
+		for (int i = 0; i < this.importCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.imports[i].toString(tab + 1));
+		}
+	}
+	if (this.types != null) {
+		for (int i = 0; i < this.typeCount; i++) {
+			result.append("\n"); //$NON-NLS-1$
+			result.append(this.types[i].toString(tab + 1));
+		}
+	}
+	return result.toString();
+}
+public CompilationUnitDeclaration updatedCompilationUnitDeclaration(){
+
+	/* update imports */
+	if (this.importCount > 0){
+		ImportReference[] importRefences = new ImportReference[this.importCount];
+		for (int i = 0; i < this.importCount; i++){
+			importRefences[i] = this.imports[i].updatedImportReference();
+		}
+		this.unitDeclaration.imports = importRefences;
+	}
+	/* update types */
+	if (this.typeCount > 0){
+		int existingCount = this.unitDeclaration.types == null ? 0 : this.unitDeclaration.types.length;
+		TypeDeclaration[] typeDeclarations = new TypeDeclaration[existingCount + this.typeCount];
+		if (existingCount > 0){
+			System.arraycopy(this.unitDeclaration.types, 0, typeDeclarations, 0, existingCount);
+		}
+		// may need to update the declarationSourceEnd of the last type
+		if (this.types[this.typeCount - 1].typeDeclaration.declarationSourceEnd == 0){
+			this.types[this.typeCount - 1].typeDeclaration.declarationSourceEnd = this.unitDeclaration.sourceEnd;
+			this.types[this.typeCount - 1].typeDeclaration.bodyEnd = this.unitDeclaration.sourceEnd;
+		}
+		
+		Set knownTypes = new HashSet();
+		int actualCount = existingCount;
+		for (int i = 0; i < this.typeCount; i++){
+			TypeDeclaration typeDecl = this.types[i].updatedTypeDeclaration(0, knownTypes);
+			// filter out local types (12454)
+			if (typeDecl != null && (typeDecl.bits & ASTNode.IsLocalType) == 0){
+				typeDeclarations[actualCount++] = typeDecl;
+			}
+		}
+		if (actualCount != this.typeCount){
+			System.arraycopy(
+				typeDeclarations,
+				0,
+				typeDeclarations = new TypeDeclaration[existingCount+actualCount],
+				0,
+				existingCount+actualCount);
+		}
+		this.unitDeclaration.types = typeDeclarations;
+	}
+	return this.unitDeclaration;
+}
+public void updateParseTree(){
+	updatedCompilationUnitDeclaration();
+}
+/*
+ * Update the sourceEnd of the corresponding parse node
+ */
+public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
+	if (this.unitDeclaration.sourceEnd == 0)
+		this.unitDeclaration.sourceEnd = bodyEnd;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java
new file mode 100644
index 0000000..8fe5d13
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.parser;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+
+public class RecoveryScanner extends Scanner {
+	public static final char[] FAKE_IDENTIFIER = "$missing$".toCharArray(); //$NON-NLS-1$
+
+	private RecoveryScannerData data;
+
+	private int[] pendingTokens;
+	private int pendingTokensPtr = -1;
+	private char[] fakeTokenSource = null;
+	private boolean isInserted = true;
+	private boolean precededByRemoved = false;
+	private int skipNextInsertedTokens = -1;
+
+	public boolean record = true;
+
+	public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
+		super(false,
+				scanner.tokenizeWhiteSpace,
+				scanner.checkNonExternalizedStringLiterals,
+				scanner.sourceLevel,
+				scanner.complianceLevel,
+				scanner.taskTags,
+				scanner.taskPriorities,
+				scanner.isTaskCaseSensitive);
+		setData(data);
+	}
+	
+	public RecoveryScanner(
+			boolean tokenizeWhiteSpace,
+			boolean checkNonExternalizedStringLiterals,
+			long sourceLevel,
+			long complianceLevel,
+			char[][] taskTags,
+			char[][] taskPriorities,
+			boolean isTaskCaseSensitive,
+			RecoveryScannerData data) {
+		super(false,
+				tokenizeWhiteSpace,
+				checkNonExternalizedStringLiterals,
+				sourceLevel,
+				complianceLevel,
+				taskTags,
+				taskPriorities,
+				isTaskCaseSensitive);
+		setData(data);
+	}
+
+	public void insertToken(int token, int completedToken, int position) {
+		insertTokens(new int []{token}, completedToken, position);
+	}
+
+	private int[] reverse(int[] tokens) {
+		int length = tokens.length;
+		for(int i = 0, max = length / 2; i < max; i++) {
+			int tmp = tokens[i];
+			tokens[i] = tokens[length - i - 1];
+			tokens[length - i - 1] = tmp;
+		}
+		return tokens;
+	}
+	public void insertTokens(int[] tokens, int completedToken, int position) {
+		if(!this.record) return;
+
+		if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;
+
+		this.data.insertedTokensPtr++;
+		if(this.data.insertedTokens == null) {
+			this.data.insertedTokens = new int[10][];
+			this.data.insertedTokensPosition = new int[10];
+			this.data.insertedTokenUsed = new boolean[10];
+		} else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
+			int length = this.data.insertedTokens.length;
+			System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
+			System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
+			System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
+		}
+		this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
+		this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
+		this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
+	}
+
+	public void replaceTokens(int token, int start, int end) {
+		replaceTokens(new int []{token}, start, end);
+	}
+
+	public void replaceTokens(int[] tokens, int start, int end) {
+		if(!this.record) return;
+		this.data.replacedTokensPtr++;
+		if(this.data.replacedTokensStart == null) {
+			this.data.replacedTokens = new int[10][];
+			this.data.replacedTokensStart = new int[10];
+			this.data.replacedTokensEnd = new int[10];
+			this.data.replacedTokenUsed= new boolean[10];
+		} else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
+			int length = this.data.replacedTokensStart.length;
+			System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
+			System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
+			System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
+			System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
+		}
+		this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
+		this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
+		this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
+		this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
+	}
+
+	public void removeTokens(int start, int end) {
+		if(!this.record) return;
+		this.data.removedTokensPtr++;
+		if(this.data.removedTokensStart == null) {
+			this.data.removedTokensStart = new int[10];
+			this.data.removedTokensEnd = new int[10];
+			this.data.removedTokenUsed = new boolean[10];
+		} else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
+			int length = this.data.removedTokensStart.length;
+			System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
+			System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
+			System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
+		}
+		this.data.removedTokensStart[this.data.removedTokensPtr] = start;
+		this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
+		this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
+	}
+
+	protected int getNextToken0() throws InvalidInputException {
+		if(this.pendingTokensPtr > -1) {
+			int nextToken = this.pendingTokens[this.pendingTokensPtr--];
+			if(nextToken == TerminalTokens.TokenNameIdentifier){
+				this.fakeTokenSource = FAKE_IDENTIFIER;
+			} else {
+				this.fakeTokenSource = CharOperation.NO_CHAR;
+			}
+			return nextToken;
+		}
+
+		this.fakeTokenSource = null;
+		this.precededByRemoved = false;
+
+		if(this.data.insertedTokens != null) {
+			for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
+				if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > this.skipNextInsertedTokens) {
+					this.data.insertedTokenUsed[i] = true;
+					this.pendingTokens = this.data.insertedTokens[i];
+					this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
+					this.isInserted = true;
+					this.startPosition = this.currentPosition;
+					this.skipNextInsertedTokens = i;
+					int nextToken = this.pendingTokens[this.pendingTokensPtr--];
+					if(nextToken == TerminalTokens.TokenNameIdentifier){
+						this.fakeTokenSource = FAKE_IDENTIFIER;
+					} else {
+						this.fakeTokenSource = CharOperation.NO_CHAR;
+					}
+					return nextToken;
+				}
+			}
+			this.skipNextInsertedTokens = -1;
+		}
+
+		int previousLocation = this.currentPosition;
+		int currentToken = super.getNextToken0();
+
+		if(this.data.replacedTokens != null) {
+			for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
+				if(this.data.replacedTokensStart[i] >= previousLocation &&
+						this.data.replacedTokensStart[i] <= this.startPosition &&
+						this.data.replacedTokensEnd[i] >= this.currentPosition - 1) {
+					this.data.replacedTokenUsed[i] = true;
+					this.pendingTokens = this.data.replacedTokens[i];
+					this.pendingTokensPtr = this.data.replacedTokens[i].length - 1;
+					this.fakeTokenSource = FAKE_IDENTIFIER;
+					this.isInserted = false;
+					this.currentPosition = this.data.replacedTokensEnd[i] + 1;
+					int nextToken = this.pendingTokens[this.pendingTokensPtr--];
+					if(nextToken == TerminalTokens.TokenNameIdentifier){
+						this.fakeTokenSource = FAKE_IDENTIFIER;
+					} else {
+						this.fakeTokenSource = CharOperation.NO_CHAR;
+					}
+					return nextToken;
+				}
+			}
+		}
+		if(this.data.removedTokensStart != null) {
+			for (int i = 0; i <= this.data.removedTokensPtr; i++) {
+				if(this.data.removedTokensStart[i] >= previousLocation &&
+						this.data.removedTokensStart[i] <= this.startPosition &&
+						this.data.removedTokensEnd[i] >= this.currentPosition - 1) {
+					this.data.removedTokenUsed[i] = true;
+					this.currentPosition = this.data.removedTokensEnd[i] + 1;
+					this.precededByRemoved = false;
+					return getNextToken0();
+				}
+			}
+		}
+		return currentToken;
+	}
+
+	public char[] getCurrentIdentifierSource() {
+		if(this.fakeTokenSource != null) return this.fakeTokenSource;
+		return super.getCurrentIdentifierSource();
+	}
+
+	public char[] getCurrentTokenSourceString() {
+		if(this.fakeTokenSource != null) return this.fakeTokenSource;
+		return super.getCurrentTokenSourceString();
+	}
+
+	public char[] getCurrentTokenSource() {
+		if(this.fakeTokenSource != null) return this.fakeTokenSource;
+		return super.getCurrentTokenSource();
+	}
+
+	public RecoveryScannerData getData() {
+		return this.data;
+	}
+
+	public boolean isFakeToken() {
+		return this.fakeTokenSource != null;
+	}
+
+	public boolean isInsertedToken() {
+		return this.fakeTokenSource != null && this.isInserted;
+	}
+
+	public boolean isReplacedToken() {
+		return this.fakeTokenSource != null && !this.isInserted;
+	}
+
+	public boolean isPrecededByRemovedToken() {
+		return this.precededByRemoved;
+	}
+
+	public void setData(RecoveryScannerData data) {
+		if(data == null) {
+			this.data = new RecoveryScannerData();
+		} else {
+			this.data = data;
+		}
+	}
+
+	public void setPendingTokens(int[] pendingTokens) {
+		this.pendingTokens = pendingTokens;
+		this.pendingTokensPtr = pendingTokens.length - 1;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.java
new file mode 100644
index 0000000..844cd6f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.compiler.parser;
+
+public class RecoveryScannerData {
+	public int insertedTokensPtr = -1;
+	public int[][] insertedTokens;
+	public int[] insertedTokensPosition;
+	public boolean[] insertedTokenUsed;
+
+	public int replacedTokensPtr = -1;
+	public int[][] replacedTokens;
+	public int[] replacedTokensStart;
+	public int[] replacedTokensEnd;
+	public boolean[] replacedTokenUsed;
+
+	public int removedTokensPtr = -1;
+	public int[] removedTokensStart;
+	public int[] removedTokensEnd;
+	public boolean[] removedTokenUsed;
+
+	public RecoveryScannerData removeUnused() {
+		if(this.insertedTokens != null) {
+			int newInsertedTokensPtr = -1;
+			for (int i = 0; i <= this.insertedTokensPtr; i++) {
+				if(this.insertedTokenUsed[i]) {
+					newInsertedTokensPtr++;
+					this.insertedTokens[newInsertedTokensPtr] = this.insertedTokens[i];
+					this.insertedTokensPosition[newInsertedTokensPtr] = this.insertedTokensPosition[i];
+					this.insertedTokenUsed[newInsertedTokensPtr] = this.insertedTokenUsed[i];
+				}
+			}
+			this.insertedTokensPtr = newInsertedTokensPtr;
+		}
+
+		if(this.replacedTokens != null) {
+			int newReplacedTokensPtr = -1;
+			for (int i = 0; i <= this.replacedTokensPtr; i++) {
+				if(this.replacedTokenUsed[i]) {
+					newReplacedTokensPtr++;
+					this.replacedTokens[newReplacedTokensPtr] = this.replacedTokens[i];
+					this.replacedTokensStart[newReplacedTokensPtr] = this.replacedTokensStart[i];
+					this.replacedTokensEnd[newReplacedTokensPtr] = this.replacedTokensEnd[i];
+					this.replacedTokenUsed[newReplacedTokensPtr] = this.replacedTokenUsed[i];
+				}
+			}
+			this.replacedTokensPtr = newReplacedTokensPtr;
+		}
+		if(this.removedTokensStart != null) {
+			int newRemovedTokensPtr = -1;
+			for (int i = 0; i <= this.removedTokensPtr; i++) {
+				if(this.removedTokenUsed[i]) {
+					newRemovedTokensPtr++;
+					this.removedTokensStart[newRemovedTokensPtr] = this.removedTokensStart[i];
+					this.removedTokensEnd[newRemovedTokensPtr] = this.removedTokensEnd[i];
+					this.removedTokenUsed[newRemovedTokensPtr] = this.removedTokenUsed[i];
+				}
+			}
+			this.removedTokensPtr = newRemovedTokensPtr;
+		}
+
+		return this;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
new file mode 100644
index 0000000..afa8495
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -0,0 +1,4465 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *     Jesper S Moller  -. Contribution for bug 400830: [1.8][formatter] Code formatter for Java 8
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * IMPORTANT NOTE: Internal Scanner implementation. It is mirrored in
+ * org.eclipse.jdt.core.compiler public package where it is API.
+ * The mirror implementation is using the backward compatible ITerminalSymbols constant
+ * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens
+ * which constant values reflect the latest parser generation state.
+ */
+public class Scanner implements TerminalTokens {
+
+	//public int newIdentCount = 0;
+
+	/* APIs ares
+	 - getNextToken() which return the current type of the token
+	   (this value is not memorized by the scanner)
+	 - getCurrentTokenSource() which provides with the token "REAL" source
+	   (aka all unicode have been transformed into a correct char)
+	 - sourceStart gives the position into the stream
+	 - currentPosition-1 gives the sourceEnd position into the stream
+	*/
+	public long sourceLevel;
+	public long complianceLevel;
+
+	// 1.4 feature
+	public boolean useAssertAsAnIndentifier = false;
+	//flag indicating if processed source contains occurrences of keyword assert
+	public boolean containsAssertKeyword = false;
+
+	// 1.5 feature
+	public boolean useEnumAsAnIndentifier = false;
+
+	public boolean recordLineSeparator = false;
+	public char currentCharacter;
+	public int startPosition;
+	public int currentPosition;
+	public int initialPosition, eofPosition;
+	// after this position eof are generated instead of real token from the source
+
+	public boolean skipComments = false;
+	public boolean tokenizeComments = false;
+	public boolean tokenizeWhiteSpace = false;
+
+	//source should be viewed as a window (aka a part)
+	//of a entire very large stream
+	public char source[];
+
+	//unicode support
+	public char[] withoutUnicodeBuffer;
+	public int withoutUnicodePtr; //when == 0 ==> no unicode in the current token
+	public boolean unicodeAsBackSlash = false;
+
+	public boolean scanningFloatLiteral = false;
+
+	//support for /** comments
+	public final static int COMMENT_ARRAYS_SIZE = 30;
+	public int[] commentStops = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int commentPtr = -1; // no comment test with commentPtr value -1
+	protected int lastCommentLinePosition = -1;
+
+	// task tag support
+	public char[][] foundTaskTags = null;
+	public char[][] foundTaskMessages;
+	public char[][] foundTaskPriorities = null;
+	public int[][] foundTaskPositions;
+	public int foundTaskCount = 0;
+	public char[][] taskTags = null;
+	public char[][] taskPriorities = null;
+	public boolean isTaskCaseSensitive = true;
+
+	//diet parsing support - jump over some method body when requested
+	public boolean diet = false;
+
+	//support for the  poor-line-debuggers ....
+	//remember the position of the cr/lf
+	public int[] lineEnds = new int[250];
+	public int linePtr = -1;
+	public boolean wasAcr = false;
+
+	public static final String END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$
+
+	public static final String INVALID_HEXA = "Invalid_Hexa_Literal"; //$NON-NLS-1$
+	public static final String INVALID_OCTAL = "Invalid_Octal_Literal"; //$NON-NLS-1$
+	public static final String INVALID_CHARACTER_CONSTANT = "Invalid_Character_Constant";  //$NON-NLS-1$
+	public static final String INVALID_ESCAPE = "Invalid_Escape"; //$NON-NLS-1$
+	public static final String INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
+	public static final String INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
+	public static final String INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
+	public static final String INVALID_LOW_SURROGATE = "Invalid_Low_Surrogate"; //$NON-NLS-1$
+	public static final String INVALID_HIGH_SURROGATE = "Invalid_High_Surrogate"; //$NON-NLS-1$
+
+	public static final String NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
+	public static final String UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
+	public static final String UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
+	public static final String INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
+	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$
+	private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
+
+	public static final String INVALID_BINARY = "Invalid_Binary_Literal"; //$NON-NLS-1$
+	public static final String BINARY_LITERAL_NOT_BELOW_17 = "Binary_Literal_Not_Below_17"; //$NON-NLS-1$
+	public static final String ILLEGAL_HEXA_LITERAL = "Illegal_Hexa_Literal"; //$NON-NLS-1$
+	public static final String INVALID_UNDERSCORE = "Invalid_Underscore"; //$NON-NLS-1$
+	public static final String UNDERSCORES_IN_LITERALS_NOT_BELOW_17 = "Underscores_In_Literals_Not_Below_17"; //$NON-NLS-1$`
+
+	//----------------optimized identifier managment------------------
+	static final char[] charArray_a = new char[] {'a'},
+		charArray_b = new char[] {'b'},
+		charArray_c = new char[] {'c'},
+		charArray_d = new char[] {'d'},
+		charArray_e = new char[] {'e'},
+		charArray_f = new char[] {'f'},
+		charArray_g = new char[] {'g'},
+		charArray_h = new char[] {'h'},
+		charArray_i = new char[] {'i'},
+		charArray_j = new char[] {'j'},
+		charArray_k = new char[] {'k'},
+		charArray_l = new char[] {'l'},
+		charArray_m = new char[] {'m'},
+		charArray_n = new char[] {'n'},
+		charArray_o = new char[] {'o'},
+		charArray_p = new char[] {'p'},
+		charArray_q = new char[] {'q'},
+		charArray_r = new char[] {'r'},
+		charArray_s = new char[] {'s'},
+		charArray_t = new char[] {'t'},
+		charArray_u = new char[] {'u'},
+		charArray_v = new char[] {'v'},
+		charArray_w = new char[] {'w'},
+		charArray_x = new char[] {'x'},
+		charArray_y = new char[] {'y'},
+		charArray_z = new char[] {'z'};
+
+	static final char[] initCharArray =
+		new char[] {'\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000'};
+	static final int TableSize = 30, InternalTableSize = 6; //30*6 =210 entries
+
+	public static final int OptimizedLength = 7;
+	public /*static*/ final char[][][][] charArray_length =
+		new char[OptimizedLength][TableSize][InternalTableSize][];
+	// support for detecting non-externalized string literals
+	public static final char[] TAG_PREFIX= "//$NON-NLS-".toCharArray(); //$NON-NLS-1$
+	public static final int TAG_PREFIX_LENGTH= TAG_PREFIX.length;
+	public static final char TAG_POSTFIX= '$';
+	public static final int TAG_POSTFIX_LENGTH= 1;
+	private NLSTag[] nlsTags = null;
+	protected int nlsTagsPtr;
+	public boolean checkNonExternalizedStringLiterals;
+
+	protected int lastPosition;
+
+	// generic support
+	public boolean returnOnlyGreater = false;
+
+	/*static*/ {
+		for (int i = 0; i < 6; i++) {
+			for (int j = 0; j < TableSize; j++) {
+				for (int k = 0; k < InternalTableSize; k++) {
+					this.charArray_length[i][j][k] = initCharArray;
+				}
+			}
+		}
+	}
+	/*static*/ int newEntry2 = 0,
+		newEntry3 = 0,
+		newEntry4 = 0,
+		newEntry5 = 0,
+		newEntry6 = 0;
+	public boolean insideRecovery = false;
+	int lookBack[] = new int[2]; // fall back to spring forward.
+	private int nextToken = TokenNameNotAToken; // allows for one token push back, only the most recent token can be reliably ungotten.
+	private VanguardScanner vanguardScanner;
+	private VanguardParser vanguardParser;
+	private ConflictedParser activeParser = null;
+	
+	public static final int RoundBracket = 0;
+	public static final int SquareBracket = 1;
+	public static final int CurlyBracket = 2;
+	public static final int BracketKinds = 3;
+
+	// extended unicode support
+	public static final int LOW_SURROGATE_MIN_VALUE = 0xDC00;
+	public static final int HIGH_SURROGATE_MIN_VALUE = 0xD800;
+	public static final int HIGH_SURROGATE_MAX_VALUE = 0xDBFF;
+	public static final int LOW_SURROGATE_MAX_VALUE = 0xDFFF;
+
+public Scanner() {
+	this(false /*comment*/, false /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
+}
+
+public Scanner(
+		boolean tokenizeComments,
+		boolean tokenizeWhiteSpace,
+		boolean checkNonExternalizedStringLiterals,
+		long sourceLevel,
+		long complianceLevel,
+		char[][] taskTags,
+		char[][] taskPriorities,
+		boolean isTaskCaseSensitive) {
+
+	this.eofPosition = Integer.MAX_VALUE;
+	this.tokenizeComments = tokenizeComments;
+	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
+	this.sourceLevel = sourceLevel;
+	this.lookBack[0] = this.lookBack[1] = this.nextToken = TokenNameNotAToken;
+	this.complianceLevel = complianceLevel;
+	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
+	if (taskTags != null) {
+		int taskTagsLength = taskTags.length;
+		int length = taskTagsLength;
+		if (taskPriorities != null) {
+			int taskPrioritiesLength = taskPriorities.length;
+			if (taskPrioritiesLength != taskTagsLength) {
+				if (taskPrioritiesLength > taskTagsLength) {
+					System.arraycopy(taskPriorities, 0, (taskPriorities = new char[taskTagsLength][]), 0, taskTagsLength);
+				} else {
+					System.arraycopy(taskTags, 0, (taskTags = new char[taskPrioritiesLength][]), 0, taskPrioritiesLength);
+					length = taskPrioritiesLength;
+				}
+			}
+			int[] initialIndexes = new int[length];
+			for (int i = 0; i < length; i++) {
+				initialIndexes[i] = i;
+			}
+			Util.reverseQuickSort(taskTags, 0, length - 1, initialIndexes);
+			char[][] temp = new char[length][];
+			for (int i = 0; i < length; i++) {
+				temp[i] = taskPriorities[initialIndexes[i]];
+			}
+			this.taskPriorities = temp;
+		} else {
+			Util.reverseQuickSort(taskTags, 0, length - 1);
+		}
+		this.taskTags = taskTags;
+		this.isTaskCaseSensitive = isTaskCaseSensitive;
+	}
+}
+
+public Scanner(
+		boolean tokenizeComments,
+		boolean tokenizeWhiteSpace,
+		boolean checkNonExternalizedStringLiterals,
+		long sourceLevel,
+		char[][] taskTags,
+		char[][] taskPriorities,
+		boolean isTaskCaseSensitive) {
+
+	this(
+		tokenizeComments,
+		tokenizeWhiteSpace,
+		checkNonExternalizedStringLiterals,
+		sourceLevel,
+		sourceLevel,
+		taskTags,
+		taskPriorities,
+		isTaskCaseSensitive);
+}
+
+public final boolean atEnd() {
+	// This code is not relevant if source is
+	// Only a part of the real stream input
+
+	return this.eofPosition <= this.currentPosition;
+}
+
+// chech presence of task: tags
+// TODO (frederic) see if we need to take unicode characters into account...
+public void checkTaskTag(int commentStart, int commentEnd) throws InvalidInputException {
+	char[] src = this.source;
+
+	// only look for newer task: tags
+	if (this.foundTaskCount > 0
+		&& this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) {
+		return;
+	}
+	int foundTaskIndex = this.foundTaskCount;
+	char previous = src[commentStart+1]; // should be '*' or '/'
+	for (
+		int i = commentStart + 2; i < commentEnd && i < this.eofPosition; i++) {
+		char[] tag = null;
+		char[] priority = null;
+		// check for tag occurrence only if not ambiguous with javadoc tag
+		if (previous != '@') {
+			nextTag : for (int itag = 0; itag < this.taskTags.length; itag++) {
+				tag = this.taskTags[itag];
+				int tagLength = tag.length;
+				if (tagLength == 0) continue nextTag;
+
+				// ensure tag is not leaded with letter if tag starts with a letter
+				if (ScannerHelper.isJavaIdentifierStart(this.complianceLevel, tag[0])) {
+					if (ScannerHelper.isJavaIdentifierPart(this.complianceLevel, previous)) {
+						continue nextTag;
+					}
+				}
+
+				for (int t = 0; t < tagLength; t++) {
+					char sc, tc;
+					int x = i+t;
+					if (x >= this.eofPosition || x >= commentEnd) continue nextTag;
+					// case sensitive check
+					if ((sc = src[i + t]) != (tc = tag[t])) {
+						// case insensitive check
+						if (this.isTaskCaseSensitive || (ScannerHelper.toLowerCase(sc) != ScannerHelper.toLowerCase(tc))) {
+							continue nextTag;
+						}
+					}
+				}
+				// ensure tag is not followed with letter if tag finishes with a letter
+				if (i+tagLength < commentEnd && ScannerHelper.isJavaIdentifierPart(this.complianceLevel, src[i+tagLength-1])) {
+					if (ScannerHelper.isJavaIdentifierPart(this.complianceLevel, src[i + tagLength]))
+						continue nextTag;
+				}
+				if (this.foundTaskTags == null) {
+					this.foundTaskTags = new char[5][];
+					this.foundTaskMessages = new char[5][];
+					this.foundTaskPriorities = new char[5][];
+					this.foundTaskPositions = new int[5][];
+				} else if (this.foundTaskCount == this.foundTaskTags.length) {
+					System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+				}
+
+				priority = this.taskPriorities != null && itag < this.taskPriorities.length
+							? this.taskPriorities[itag]
+							: null;
+
+				this.foundTaskTags[this.foundTaskCount] = tag;
+				this.foundTaskPriorities[this.foundTaskCount] = priority;
+				this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 };
+				this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR;
+				this.foundTaskCount++;
+				i += tagLength - 1; // will be incremented when looping
+				break nextTag;
+			}
+		}
+		previous = src[i];
+	}
+	boolean containsEmptyTask = false;
+	for (int i = foundTaskIndex; i < this.foundTaskCount; i++) {
+		// retrieve message start and end positions
+		int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length;
+		int max_value = i + 1 < this.foundTaskCount
+				? this.foundTaskPositions[i + 1][0] - 1
+				: commentEnd - 1;
+		// at most beginning of next task
+		if (max_value < msgStart) {
+			max_value = msgStart; // would only occur if tag is before EOF.
+		}
+		int end = -1;
+		char c;
+		for (int j = msgStart; j < max_value; j++) {
+			if ((c = src[j]) == '\n' || c == '\r') {
+				end = j - 1;
+				break;
+			}
+		}
+		if (end == -1) {
+			for (int j = max_value; j > msgStart; j--) {
+				if ((c = src[j]) == '*') {
+					end = j - 1;
+					break;
+				}
+			}
+			if (end == -1)
+				end = max_value;
+		}
+		if (msgStart == end) {
+			// if the description is empty, we might want to see if two tags are not sharing the same message
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=110797
+			containsEmptyTask = true;
+			continue;
+		}
+		// trim the message
+		// we don't trim the beginning of the message to be able to show it after the task tag
+		while (CharOperation.isWhitespace(src[end]) && msgStart <= end)
+			end--;
+		// update the end position of the task
+		this.foundTaskPositions[i][1] = end;
+		// get the message source
+		final int messageLength = end - msgStart + 1;
+		char[] message = new char[messageLength];
+		System.arraycopy(src, msgStart, message, 0, messageLength);
+		this.foundTaskMessages[i] = message;
+	}
+	if (containsEmptyTask) {
+		for (int i = foundTaskIndex, max = this.foundTaskCount; i < max; i++) {
+			if (this.foundTaskMessages[i].length == 0) {
+				loop: for (int j = i + 1; j < max; j++) {
+					if (this.foundTaskMessages[j].length != 0) {
+						this.foundTaskMessages[i] = this.foundTaskMessages[j];
+						this.foundTaskPositions[i][1] = this.foundTaskPositions[j][1];
+						break loop;
+					}
+				}
+			}
+		}
+	}
+}
+
+public char[] getCurrentIdentifierSource() {
+	//return the token REAL source (aka unicodes are precomputed)
+	if (this.withoutUnicodePtr != 0) {
+		//0 is used as a fast test flag so the real first char is in position 1
+		char[] result = new char[this.withoutUnicodePtr];
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			result,
+			0,
+			this.withoutUnicodePtr);
+		return result;
+	}
+	int length = this.currentPosition - this.startPosition;
+	if (length == this.eofPosition) return this.source;
+	switch (length) { // see OptimizedLength
+		case 1 :
+			return optimizedCurrentTokenSource1();
+		case 2 :
+			return optimizedCurrentTokenSource2();
+		case 3 :
+			return optimizedCurrentTokenSource3();
+		case 4 :
+			return optimizedCurrentTokenSource4();
+		case 5 :
+			return optimizedCurrentTokenSource5();
+		case 6 :
+			return optimizedCurrentTokenSource6();
+	}
+	char[] result = new char[length];
+	System.arraycopy(this.source, this.startPosition, result, 0, length);
+	return result;
+}
+public int getCurrentTokenEndPosition(){
+	return this.currentPosition - 1;
+}
+public char[] getCurrentTokenSource() {
+	// Return the token REAL source (aka unicodes are precomputed)
+
+	char[] result;
+	if (this.withoutUnicodePtr != 0)
+		// 0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			result = new char[this.withoutUnicodePtr],
+			0,
+			this.withoutUnicodePtr);
+	else {
+		int length;
+		System.arraycopy(
+			this.source,
+			this.startPosition,
+			result = new char[length = this.currentPosition - this.startPosition],
+			0,
+			length);
+	}
+	return result;
+}
+public final String getCurrentTokenString() {
+	// Return current token as a string
+
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		return new String(
+			this.withoutUnicodeBuffer,
+			1,
+			this.withoutUnicodePtr);
+	}
+	return new String(
+		this.source,
+		this.startPosition,
+		this.currentPosition - this.startPosition);
+}
+public char[] getCurrentTokenSourceString() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
+
+	char[] result;
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(this.withoutUnicodeBuffer, 2,
+		//2 is 1 (real start) + 1 (to jump over the ")
+		result = new char[this.withoutUnicodePtr - 2], 0, this.withoutUnicodePtr - 2);
+	else {
+		int length;
+		System.arraycopy(
+			this.source,
+			this.startPosition + 1,
+			result = new char[length = this.currentPosition - this.startPosition - 2],
+			0,
+			length);
+	}
+	return result;
+}
+public final String getCurrentStringLiteral() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
+
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		//2 is 1 (real start) + 1 (to jump over the ")
+		return new String(this.withoutUnicodeBuffer, 2, this.withoutUnicodePtr - 2);
+	else {
+		return new String(this.source, this.startPosition + 1, this.currentPosition - this.startPosition - 2);
+	}
+}
+public final char[] getRawTokenSource() {
+	int length = this.currentPosition - this.startPosition;
+	char[] tokenSource = new char[length];
+	System.arraycopy(this.source, this.startPosition, tokenSource, 0, length);
+	return tokenSource;
+}
+
+public final char[] getRawTokenSourceEnd() {
+	int length = this.eofPosition - this.currentPosition - 1;
+	char[] sourceEnd = new char[length];
+	System.arraycopy(this.source, this.currentPosition, sourceEnd, 0, length);
+	return sourceEnd;
+}
+
+public int getCurrentTokenStartPosition(){
+	return this.startPosition;
+}
+/*
+ * Search the source position corresponding to the end of a given line number
+ *
+ * Line numbers are 1-based, and relative to the scanner initialPosition.
+ * Character positions are 0-based.
+ *
+ * In case the given line number is inconsistent, answers -1.
+ */
+public final int getLineEnd(int lineNumber) {
+
+	if (this.lineEnds == null || this.linePtr == -1)
+		return -1;
+	if (lineNumber > this.lineEnds.length+1)
+		return -1;
+	if (lineNumber <= 0)
+		return -1;
+	if (lineNumber == this.lineEnds.length + 1)
+		return this.eofPosition;
+	return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
+}
+
+public final int[] getLineEnds() {
+	//return a bounded copy of this.lineEnds
+	if (this.linePtr == -1) {
+		return EMPTY_LINE_ENDS;
+	}
+	int[] copy;
+	System.arraycopy(this.lineEnds, 0, copy = new int[this.linePtr + 1], 0, this.linePtr + 1);
+	return copy;
+}
+
+/**
+ * Search the source position corresponding to the beginning of a given line number
+ *
+ * Line numbers are 1-based, and relative to the scanner initialPosition.
+ * Character positions are 0-based.
+ *
+ * e.g.	getLineStart(1) --> 0	indicates that the first line starts at character 0.
+ *
+ * In case the given line number is inconsistent, answers -1.
+ *
+ * @param lineNumber int
+ * @return int
+ */
+public final int getLineStart(int lineNumber) {
+
+	if (this.lineEnds == null || this.linePtr == -1)
+		return -1;
+	if (lineNumber > this.lineEnds.length + 1)
+		return -1;
+	if (lineNumber <= 0)
+		return -1;
+
+	if (lineNumber == 1)
+		return this.initialPosition;
+	return this.lineEnds[lineNumber-2]+1; // next line start one character behind the lineEnd of the previous line
+}
+public final int getNextChar() {
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+				getNextUnicodeChar();
+		} else {
+			this.unicodeAsBackSlash = false;
+			if (this.withoutUnicodePtr != 0) {
+			    unicodeStore();
+			}
+		}
+		return this.currentCharacter;
+	} catch (IndexOutOfBoundsException e) {
+		return -1;
+	} catch(InvalidInputException e) {
+		return -1;
+	}
+}
+public final int getNextCharWithBoundChecks() {
+	if (this.currentPosition >= this.eofPosition) {
+		return -1;
+	}
+	this.currentCharacter = this.source[this.currentPosition++];
+	if (this.currentPosition >= this.eofPosition) {
+		this.unicodeAsBackSlash = false;
+		if (this.withoutUnicodePtr != 0) {
+		    unicodeStore();
+		}
+		return this.currentCharacter;
+	}
+	if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
+		try {
+			getNextUnicodeChar();
+		} catch (InvalidInputException e) {
+			return -1;
+		}
+	} else {
+		this.unicodeAsBackSlash = false;
+		if (this.withoutUnicodePtr != 0) {
+		    unicodeStore();
+		}
+	}
+	return this.currentCharacter;
+}
+public final boolean getNextChar(char testedChar) {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is == to the testedChar
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+
+	if (this.currentPosition >= this.eofPosition) { // handle the obvious case upfront
+		this.unicodeAsBackSlash = false;
+		return false;
+	}
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (this.currentCharacter != testedChar) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} //-------------end unicode traitement--------------
+		else {
+			if (this.currentCharacter != testedChar) {
+				this.currentPosition = temp;
+				return false;
+			}
+			this.unicodeAsBackSlash = false;
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public final int getNextChar(char testedChar1, char testedChar2) {
+	//INT 0 : testChar1 \\\\///\\\\ 1 : testedChar2 \\\\///\\\\ -1 : others
+	//test can be done with (x==0) for the first and (x>0) for the second
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is == to the testedChar1/2
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return -1;
+
+	int temp = this.currentPosition;
+	try {
+		int result;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				result = -1;
+			}
+			return result;
+		} else {
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				return -1;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return result;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return -1;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return -1;
+	}
+}
+/*
+ * This method consumes digits as well as underscores if underscores are located between digits
+ * @throws InvalidInputException if underscores are not located between digits or if underscores are used in source < 1.7 
+ */
+private final void consumeDigits(int radix) throws InvalidInputException {
+	consumeDigits(radix, false);
+}
+/*
+ * This method consumes digits as well as underscores if underscores are located between digits
+ * @throws InvalidInputException if underscores are not located between digits or if underscores are used in source < 1.7 
+ */
+private final void consumeDigits(int radix, boolean expectingDigitFirst) throws InvalidInputException {
+	final int USING_UNDERSCORE = 1;
+	final int INVALID_POSITION = 2;
+	switch(consumeDigits0(radix, USING_UNDERSCORE, INVALID_POSITION, expectingDigitFirst)) {
+		case USING_UNDERSCORE :
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(UNDERSCORES_IN_LITERALS_NOT_BELOW_17);
+			}
+			break;
+		case INVALID_POSITION :
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(UNDERSCORES_IN_LITERALS_NOT_BELOW_17);
+			}
+			throw new InvalidInputException(INVALID_UNDERSCORE);
+	}
+}
+private final int consumeDigits0(int radix, int usingUnderscore, int invalidPosition, boolean expectingDigitFirst) throws InvalidInputException {
+	int kind = 0;
+	if (getNextChar('_')) {
+		if (expectingDigitFirst) {
+			return invalidPosition;
+		}
+		kind = usingUnderscore;
+		while (getNextChar('_')) {/*empty */}
+	}
+	if (getNextCharAsDigit(radix)) {
+		// continue to read digits or underscore
+		while (getNextCharAsDigit(radix)) {/*empty */}
+		int kind2 = consumeDigits0(radix, usingUnderscore, invalidPosition, false);
+		if (kind2 == 0) {
+			return kind;
+		}
+		return kind2;
+	}
+	if (kind == usingUnderscore) return invalidPosition;
+	return kind;
+}
+public final boolean getNextCharAsDigit() throws InvalidInputException {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a digit
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (!ScannerHelper.isDigit(this.currentCharacter)) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} else {
+			if (!ScannerHelper.isDigit(this.currentCharacter)) {
+				this.currentPosition = temp;
+				return false;
+			}
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public final boolean getNextCharAsDigit(int radix) {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a digit base on radix
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} else {
+			if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
+				this.currentPosition = temp;
+				return false;
+			}
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public boolean getNextCharAsJavaIdentifierPartWithBoundCheck() {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int pos = this.currentPosition;
+	if (pos >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp2 = this.withoutUnicodePtr;
+	try {
+		boolean unicode = false;
+		this.currentCharacter = this.source[this.currentPosition++];
+		if (this.currentPosition < this.eofPosition) {
+			if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
+				getNextUnicodeChar();
+				unicode = true;
+			}
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			// Unicode 4 detection
+			char low = (char) getNextCharWithBoundChecks();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			return true;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				return false;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+			    unicodeStore();
+			return true;
+		}
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	}
+}
+public boolean getNextCharAsJavaIdentifierPart() {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int pos;
+	if ((pos = this.currentPosition) >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp2 = this.withoutUnicodePtr;
+	try {
+		boolean unicode = false;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			unicode = true;
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			// Unicode 4 detection
+			char low = (char) getNextChar();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			return true;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				return false;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+			    unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	}
+}
+/*
+ * External API in JavaConventions.
+ * This is used to optimize the case where the scanner is used to scan a single identifier.
+ * In this case, the AIOOBE is slower to handle than a bound check
+ */
+public int scanIdentifier() throws InvalidInputException {
+	int whiteStart = 0;
+	while (true) { //loop for jumping over comments
+		this.withoutUnicodePtr = 0;
+		//start with a new token (even comment written with unicode )
+		// ---------Consume white space and handles startPosition---------
+		whiteStart = this.currentPosition;
+		boolean isWhiteSpace, hasWhiteSpaces = false;
+		int offset;
+		int unicodePtr;
+		boolean checkIfUnicode = false;
+		do {
+			unicodePtr = this.withoutUnicodePtr;
+			offset = this.currentPosition;
+			this.startPosition = this.currentPosition;
+			if (this.currentPosition < this.eofPosition) {
+				this.currentCharacter = this.source[this.currentPosition++];
+				checkIfUnicode = this.currentPosition < this.eofPosition
+						&& this.currentCharacter == '\\'
+						&& this.source[this.currentPosition] == 'u';
+			} else if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+				// reposition scanner in case we are interested by spaces as tokens
+				this.currentPosition--;
+				this.startPosition = whiteStart;
+				return TokenNameWHITESPACE;
+			} else {
+				return TokenNameEOF;
+			}
+			if (checkIfUnicode) {
+				isWhiteSpace = jumpOverUnicodeWhiteSpace();
+				offset = this.currentPosition - offset;
+			} else {
+				offset = this.currentPosition - offset;
+				// inline version of:
+				//isWhiteSpace =
+				//	(this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
+				switch (this.currentCharacter) {
+					case 10 : /* \ u000a: LINE FEED               */
+					case 12 : /* \ u000c: FORM FEED               */
+					case 13 : /* \ u000d: CARRIAGE RETURN         */
+					case 32 : /* \ u0020: SPACE                   */
+					case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+						isWhiteSpace = true;
+						break;
+					default :
+						isWhiteSpace = false;
+				}
+			}
+			if (isWhiteSpace) {
+				hasWhiteSpaces = true;
+			}
+		} while (isWhiteSpace);
+		if (hasWhiteSpaces) {
+			if (this.tokenizeWhiteSpace) {
+				// reposition scanner in case we are interested by spaces as tokens
+				this.currentPosition-=offset;
+				this.startPosition = whiteStart;
+				if (checkIfUnicode) {
+					this.withoutUnicodePtr = unicodePtr;
+				}
+				return TokenNameWHITESPACE;
+			} else if (checkIfUnicode) {
+				this.withoutUnicodePtr = 0;
+				unicodeStore();
+			} else {
+				this.withoutUnicodePtr = 0;
+			}
+		}
+		char c = this.currentCharacter;
+		if (c < ScannerHelper.MAX_OBVIOUS) {
+			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+				return scanIdentifierOrKeywordWithBoundCheck();
+			}
+			return TokenNameERROR;
+		}
+		boolean isJavaIdStart;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			// Unicode 4 detection
+			char low = (char) getNextCharWithBoundChecks();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				throw new InvalidInputException(INVALID_LOW_SURROGATE);
+			}
+			isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+		} else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+		} else {
+			// optimized case already checked
+			isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+		}
+		if (isJavaIdStart)
+			return scanIdentifierOrKeywordWithBoundCheck();
+		return TokenNameERROR;
+	}
+}
+public void ungetToken(int unambiguousToken) {
+	if (this.nextToken != TokenNameNotAToken) {
+		throw new ArrayIndexOutOfBoundsException("Single cell array overflow"); //$NON-NLS-1$
+	}
+	this.nextToken = unambiguousToken;
+}
+
+public int getNextToken() throws InvalidInputException {
+	
+	int token;
+	if (this.nextToken != TokenNameNotAToken) {
+		token = this.nextToken;
+		this.nextToken = TokenNameNotAToken;
+		return token; // presumed to be unambiguous.
+	}
+	token = getNextToken0();
+	if (this.activeParser == null) { // anybody interested in the grammatical structure of the program should have registered.
+		return token;
+	}
+	if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT) {
+		token = disambiguatedToken(token);
+	}
+	this.lookBack[0] = this.lookBack[1];
+	this.lookBack[1] = token;
+	return token;
+}
+protected int getNextToken0() throws InvalidInputException {
+	this.wasAcr = false;
+	if (this.diet) {
+		jumpOverMethodBody();
+		this.diet = false;
+		return this.currentPosition > this.eofPosition ? TokenNameEOF : TokenNameRBRACE;
+	}
+	int whiteStart = 0;
+	try {
+		while (true) { //loop for jumping over comments
+			this.withoutUnicodePtr = 0;
+			//start with a new token (even comment written with unicode )
+
+			// ---------Consume white space and handles startPosition---------
+			whiteStart = this.currentPosition;
+			boolean isWhiteSpace, hasWhiteSpaces = false;
+			int offset;
+			int unicodePtr;
+			boolean checkIfUnicode = false;
+			do {
+				unicodePtr = this.withoutUnicodePtr;
+				offset = this.currentPosition;
+				this.startPosition = this.currentPosition;
+				try {
+					checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+						&& (this.source[this.currentPosition] == 'u');
+				} catch(IndexOutOfBoundsException e) {
+					if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+						// reposition scanner in case we are interested by spaces as tokens
+						this.currentPosition--;
+						this.startPosition = whiteStart;
+						return TokenNameWHITESPACE;
+					}
+					if (this.currentPosition > this.eofPosition)
+						return TokenNameEOF;
+				}
+				if (this.currentPosition > this.eofPosition) {
+					if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+						this.currentPosition--;
+						// reposition scanner in case we are interested by spaces as tokens
+						this.startPosition = whiteStart;
+						return TokenNameWHITESPACE;
+					}
+					return TokenNameEOF;
+				}
+				if (checkIfUnicode) {
+					isWhiteSpace = jumpOverUnicodeWhiteSpace();
+					offset = this.currentPosition - offset;
+				} else {
+					offset = this.currentPosition - offset;
+					if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+						if (this.recordLineSeparator) {
+							pushLineSeparator();
+						}
+					}
+					// inline version of:
+					//isWhiteSpace =
+					//	(this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
+					switch (this.currentCharacter) {
+						case 10 : /* \ u000a: LINE FEED               */
+						case 12 : /* \ u000c: FORM FEED               */
+						case 13 : /* \ u000d: CARRIAGE RETURN         */
+						case 32 : /* \ u0020: SPACE                   */
+						case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+							isWhiteSpace = true;
+							break;
+						default :
+							isWhiteSpace = false;
+					}
+				}
+				if (isWhiteSpace) {
+					hasWhiteSpaces = true;
+				}
+			} while (isWhiteSpace);
+			if (hasWhiteSpaces) {
+				if (this.tokenizeWhiteSpace) {
+					// reposition scanner in case we are interested by spaces as tokens
+					this.currentPosition-=offset;
+					this.startPosition = whiteStart;
+					if (checkIfUnicode) {
+						this.withoutUnicodePtr = unicodePtr;
+					}
+					return TokenNameWHITESPACE;
+				} else if (checkIfUnicode) {
+					this.withoutUnicodePtr = 0;
+					unicodeStore();
+				} else {
+					this.withoutUnicodePtr = 0;
+				}
+			}
+			// ---------Identify the next token-------------
+			switch (this.currentCharacter) {
+				case '@' :
+/*					if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+						return TokenNameAT;
+					} else {
+						return TokenNameERROR;
+					}*/
+					return TokenNameAT;
+				case '(' :
+					return TokenNameLPAREN;
+				case ')' :
+					return TokenNameRPAREN;
+				case '{' :
+					return TokenNameLBRACE;
+				case '}' :
+					return TokenNameRBRACE;
+				case '[' :
+					return TokenNameLBRACKET;
+				case ']' :
+					return TokenNameRBRACKET;
+				case ';' :
+					return TokenNameSEMICOLON;
+				case ',' :
+					return TokenNameCOMMA;
+				case '.' :
+					if (getNextCharAsDigit()) {
+						return scanNumber(true);
+					}
+					int temp = this.currentPosition;
+					if (getNextChar('.')) {
+						if (getNextChar('.')) {
+							return TokenNameELLIPSIS;
+						} else {
+							this.currentPosition = temp;
+							return TokenNameDOT;
+						}
+					} else {
+						this.currentPosition = temp;
+						return TokenNameDOT;
+					}
+				case '+' :
+					{
+						int test;
+						if ((test = getNextChar('+', '=')) == 0)
+							return TokenNamePLUS_PLUS;
+						if (test > 0)
+							return TokenNamePLUS_EQUAL;
+						return TokenNamePLUS;
+					}
+				case '-' :
+					{
+						int test;
+						if ((test = getNextChar('-', '=')) == 0)
+							return TokenNameMINUS_MINUS;
+						if (test > 0)
+							return TokenNameMINUS_EQUAL;
+						if (getNextChar('>'))
+							return TokenNameARROW;
+						return TokenNameMINUS;
+					}
+				case '~' :
+					return TokenNameTWIDDLE;
+				case '!' :
+					if (getNextChar('='))
+						return TokenNameNOT_EQUAL;
+					return TokenNameNOT;
+				case '*' :
+					if (getNextChar('='))
+						return TokenNameMULTIPLY_EQUAL;
+					return TokenNameMULTIPLY;
+				case '%' :
+					if (getNextChar('='))
+						return TokenNameREMAINDER_EQUAL;
+					return TokenNameREMAINDER;
+				case '<' :
+					{
+						int test;
+						if ((test = getNextChar('=', '<')) == 0)
+							return TokenNameLESS_EQUAL;
+						if (test > 0) {
+							if (getNextChar('='))
+								return TokenNameLEFT_SHIFT_EQUAL;
+							return TokenNameLEFT_SHIFT;
+						}
+						return TokenNameLESS;
+					}
+				case '>' :
+					{
+						int test;
+						if (this.returnOnlyGreater) {
+							return TokenNameGREATER;
+						}
+						if ((test = getNextChar('=', '>')) == 0)
+							return TokenNameGREATER_EQUAL;
+						if (test > 0) {
+							if ((test = getNextChar('=', '>')) == 0)
+								return TokenNameRIGHT_SHIFT_EQUAL;
+							if (test > 0) {
+								if (getNextChar('='))
+									return TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL;
+								return TokenNameUNSIGNED_RIGHT_SHIFT;
+							}
+							return TokenNameRIGHT_SHIFT;
+						}
+						return TokenNameGREATER;
+					}
+				case '=' :
+					if (getNextChar('='))
+						return TokenNameEQUAL_EQUAL;
+					return TokenNameEQUAL;
+				case '&' :
+					{
+						int test;
+						if ((test = getNextChar('&', '=')) == 0)
+							return TokenNameAND_AND;
+						if (test > 0)
+							return TokenNameAND_EQUAL;
+						return TokenNameAND;
+					}
+				case '|' :
+					{
+						int test;
+						if ((test = getNextChar('|', '=')) == 0)
+							return TokenNameOR_OR;
+						if (test > 0)
+							return TokenNameOR_EQUAL;
+						return TokenNameOR;
+					}
+				case '^' :
+					if (getNextChar('='))
+						return TokenNameXOR_EQUAL;
+					return TokenNameXOR;
+				case '?' :
+					return TokenNameQUESTION;
+				case ':' :
+					if (getNextChar(':'))
+						return TokenNameCOLON_COLON;
+					return TokenNameCOLON;
+				case '\'' :
+					{
+						int test;
+						if ((test = getNextChar('\n', '\r')) == 0) {
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (test > 0) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\'') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+					}
+					if (getNextChar('\'')) {
+						// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+						for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+							if (this.currentPosition + lookAhead == this.eofPosition)
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\n')
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\'') {
+								this.currentPosition += lookAhead + 1;
+								break;
+							}
+						}
+						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+					}
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
+						scanEscapeCharacter();
+					} else { // consume next character
+						this.unicodeAsBackSlash = false;
+						checkIfUnicode = false;
+						try {
+							checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u');
+						} catch(IndexOutOfBoundsException e) {
+							this.currentPosition--;
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (checkIfUnicode) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (getNextChar('\''))
+						return TokenNameCharacterLiteral;
+					// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+					for (int lookAhead = 0; lookAhead < 20; lookAhead++) {
+						if (this.currentPosition + lookAhead == this.eofPosition)
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\n')
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\'') {
+							this.currentPosition += lookAhead + 1;
+							break;
+						}
+					}
+					throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+				case '"' :
+					try {
+						// consume next character
+						this.unicodeAsBackSlash = false;
+						boolean isUnicode = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+							isUnicode = true;
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+
+						while (this.currentCharacter != '"') {
+							if (this.currentPosition >= this.eofPosition) {
+								throw new InvalidInputException(UNTERMINATED_STRING);
+							}
+							/**** \r and \n are not valid in string literals ****/
+							if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) {
+								// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+								if (isUnicode) {
+									int start = this.currentPosition;
+									for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+										if (this.currentPosition >= this.eofPosition) {
+											this.currentPosition = start;
+											break;
+										}
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											isUnicode = true;
+											getNextUnicodeChar();
+										} else {
+											isUnicode = false;
+										}
+										if (!isUnicode && this.currentCharacter == '\n') {
+											this.currentPosition--; // set current position on new line character
+											break;
+										}
+										if (this.currentCharacter == '\"') {
+											throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+										}
+									}
+								} else {
+									this.currentPosition--; // set current position on new line character
+								}
+								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+							}
+							if (this.currentCharacter == '\\') {
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+										this.withoutUnicodePtr--;
+									} else {
+										isUnicode = false;
+									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+								isUnicode = true;
+							} else {
+								isUnicode = false;
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+
+						}
+					} catch (IndexOutOfBoundsException e) {
+						this.currentPosition--;
+						throw new InvalidInputException(UNTERMINATED_STRING);
+					} catch (InvalidInputException e) {
+						if (e.getMessage().equals(INVALID_ESCAPE)) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\"') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+
+						}
+						throw e; // rethrow
+					}
+					return TokenNameStringLiteral;
+				case '/' :
+					if (!this.skipComments) {
+						int test = getNextChar('/', '*');
+						if (test == 0) { //line comment
+							this.lastCommentLinePosition = this.currentPosition;
+							try { //get the next char
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								}
+
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								boolean isUnicode = false;
+								while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
+									if (this.currentPosition >= this.eofPosition) {
+										this.lastCommentLinePosition = this.currentPosition;
+										this.currentPosition ++;
+										// this avoids duplicating the code in the catch(IndexOutOfBoundsException e)
+										throw new IndexOutOfBoundsException();
+									}
+									this.lastCommentLinePosition = this.currentPosition;
+									//get the next char
+									isUnicode = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								/*
+								 * We need to completely consume the line break
+								 */
+								if (this.currentCharacter == '\r'
+										&& this.eofPosition > this.currentPosition) {
+									if (this.source[this.currentPosition] == '\n') {
+										this.currentPosition++;
+										this.currentCharacter = '\n';
+									} else if ((this.source[this.currentPosition] == '\\')
+										&& (this.source[this.currentPosition + 1] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									}
+								}
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.checkNonExternalizedStringLiterals &&
+											this.lastPosition < this.currentPosition) {
+										parseTags();
+									}
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.checkNonExternalizedStringLiterals &&
+										this.lastPosition < this.currentPosition) {
+									parseTags();
+								}
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								} else {
+									this.currentPosition++;
+								}
+							}
+							break;
+						}
+						if (test > 0) { //traditional and javadoc comment
+							try { //get the next char
+								boolean isJavadoc = false, star = false;
+								boolean isUnicode = false;
+								int previous;
+								// consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+
+								if (this.currentCharacter == '*') {
+									isJavadoc = true;
+									star = true;
+								}
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								isUnicode = false;
+								previous = this.currentPosition;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									//-------------unicode traitement ------------
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++; //jump over the \\
+								}
+								// empty comment is not a javadoc /**/
+								if (this.currentCharacter == '/') {
+									isJavadoc = false;
+								}
+								//loop until end of comment */
+								int firstTag = 0;
+								while ((this.currentCharacter != '/') || (!star)) {
+									if (this.currentPosition >= this.eofPosition) {
+										throw new InvalidInputException(UNTERMINATED_COMMENT);
+									}
+									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0 && this.isFirstTag()) {
+												firstTag = previous;
+											}
+											//$FALL-THROUGH$ default case to set star to false
+										default:
+											star = false;
+									}
+									//get next char
+									previous = this.currentPosition;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+										//-------------unicode traitement ------------
+										getNextUnicodeChar();
+										isUnicode = true;
+									} else {
+										isUnicode = false;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
+								recordComment(token);
+								this.commentTagStarts[this.commentPtr] = firstTag;
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.tokenizeComments) {
+									/*
+									if (isJavadoc)
+										return TokenNameCOMMENT_JAVADOC;
+									return TokenNameCOMMENT_BLOCK;
+									*/
+									return token;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								throw new InvalidInputException(UNTERMINATED_COMMENT);
+							}
+							break;
+						}
+					}
+					if (getNextChar('='))
+						return TokenNameDIVIDE_EQUAL;
+					return TokenNameDIVIDE;
+				case '\u001a' :
+					if (atEnd())
+						return TokenNameEOF;
+					//the atEnd may not be <currentPosition == source.length> if source is only some part of a real (external) stream
+					throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
+				default :
+					char c = this.currentCharacter;
+					if (c < ScannerHelper.MAX_OBVIOUS) {
+						if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+							return scanIdentifierOrKeyword();
+						} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
+								return scanNumber(false);
+						} else {
+							return TokenNameERROR;
+						}
+					}
+					boolean isJavaIdStart;
+					if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						// Unicode 4 detection
+						char low = (char) getNextChar();
+						if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+							// illegal low surrogate
+							throw new InvalidInputException(INVALID_LOW_SURROGATE);
+						}
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+					}
+					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+					} else {
+						// optimized case already checked
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+					}
+					if (isJavaIdStart)
+						return scanIdentifierOrKeyword();
+					if (ScannerHelper.isDigit(this.currentCharacter)) {
+						return scanNumber(false);
+					}
+					return TokenNameERROR;
+			}
+		}
+	} //-----------------end switch while try--------------------
+	catch (IndexOutOfBoundsException e) {
+		if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+			// reposition scanner in case we are interested by spaces as tokens
+			this.currentPosition--;
+			this.startPosition = whiteStart;
+			return TokenNameWHITESPACE;
+		}
+	}
+	return TokenNameEOF;
+}
+public void getNextUnicodeChar()
+	throws InvalidInputException {
+	//VOID
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int c1 = 0, c2 = 0, c3 = 0, c4 = 0, unicodeSize = 6;
+	this.currentPosition++;
+	if (this.currentPosition < this.eofPosition) {
+		while (this.source[this.currentPosition] == 'u') {
+			this.currentPosition++;
+			if (this.currentPosition >= this.eofPosition) {
+				this.currentPosition--;
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			unicodeSize++;
+		}
+	} else {
+		this.currentPosition--;
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+
+	if ((this.currentPosition + 4) > this.eofPosition) {
+		this.currentPosition += (this.eofPosition - this.currentPosition);
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+	if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c1 < 0
+    		|| (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c2 < 0
+    		|| (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c3 < 0
+    		|| (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c4 < 0){
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+	this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+	//need the unicode buffer
+	if (this.withoutUnicodePtr == 0) {
+		//buffer all the entries that have been left aside....
+		unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+	}
+	//fill the buffer with the char
+	unicodeStore();
+	this.unicodeAsBackSlash = this.currentCharacter == '\\';
+}
+public NLSTag[] getNLSTags() {
+	final int length = this.nlsTagsPtr;
+	if (length != 0) {
+		NLSTag[] result = new NLSTag[length];
+		System.arraycopy(this.nlsTags, 0, result, 0, length);
+		this.nlsTagsPtr = 0;
+		return result;
+	}
+	return null;
+}
+public char[] getSource(){
+	return this.source;
+}
+protected boolean isFirstTag() {
+	return true;
+}
+public final void jumpOverMethodBody() {
+
+	this.wasAcr = false;
+	int found = 1;
+	try {
+		while (true) { //loop for jumping over comments
+			this.withoutUnicodePtr = 0;
+			// ---------Consume white space and handles startPosition---------
+			boolean isWhiteSpace;
+			do {
+				this.startPosition = this.currentPosition;
+				if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+					&& (this.source[this.currentPosition] == 'u')) {
+					isWhiteSpace = jumpOverUnicodeWhiteSpace();
+				} else {
+					if (this.recordLineSeparator
+							&& ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
+						pushLineSeparator();
+					}
+					isWhiteSpace = CharOperation.isWhitespace(this.currentCharacter);
+				}
+			} while (isWhiteSpace);
+
+			// -------consume token until } is found---------
+			NextToken: switch (this.currentCharacter) {
+				case '{' :
+					found++;
+					break NextToken;
+				case '}' :
+					found--;
+					if (found == 0)
+						return;
+					break NextToken;
+				case '\'' :
+					{
+						boolean test;
+						test = getNextChar('\\');
+						if (test) {
+							try {
+								if (this.unicodeAsBackSlash) {
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+									} else {
+										if (this.withoutUnicodePtr != 0) {
+											unicodeStore();
+										}
+									}
+								} else {
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								scanEscapeCharacter();
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						} else {
+							try { // consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								} else {
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						}
+						getNextChar('\'');
+						break NextToken;
+					}
+				case '"' :
+					try {
+						try { // consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} catch (InvalidInputException ex) {
+								// ignore
+						}
+						while (this.currentCharacter != '"') {
+							if (this.currentPosition >= this.eofPosition) {
+								return;
+							}
+							if (this.currentCharacter == '\r'){
+								if (this.source[this.currentPosition] == '\n') this.currentPosition++;
+								break NextToken; // the string cannot go further that the line
+							}
+							if (this.currentCharacter == '\n'){
+								break; // the string cannot go further that the line
+							}
+							if (this.currentCharacter == '\\') {
+								try {
+									if (this.unicodeAsBackSlash) {
+										// consume next character
+										this.unicodeAsBackSlash = false;
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											getNextUnicodeChar();
+										} else {
+											if (this.withoutUnicodePtr != 0) {
+												unicodeStore();
+											}
+										}
+									} else {
+										this.currentCharacter = this.source[this.currentPosition++];
+									}
+									scanEscapeCharacter();
+								} catch (InvalidInputException ex) {
+									// ignore
+								}
+							}
+							try { // consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								} else {
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						}
+					} catch (IndexOutOfBoundsException e) {
+						return;
+					}
+					break NextToken;
+				case '/' :
+					{
+						int test;
+						if ((test = getNextChar('/', '*')) == 0) { //line comment
+							try {
+								this.lastCommentLinePosition = this.currentPosition;
+								//get the next char
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								boolean isUnicode = false;
+								while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
+									if (this.currentPosition >= this.eofPosition) {
+										this.lastCommentLinePosition = this.currentPosition;
+										this.currentPosition ++;
+										// this avoids duplicating the code inside the catch(IndexOutOfBoundsException e) below
+										throw new IndexOutOfBoundsException();
+									}
+									this.lastCommentLinePosition = this.currentPosition;
+									//get the next char
+									isUnicode = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										isUnicode = true;
+										getNextUnicodeChar();
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								/*
+								 * We need to completely consume the line break
+								 */
+								if (this.currentCharacter == '\r'
+										&& this.eofPosition > this.currentPosition) {
+									if (this.source[this.currentPosition] == '\n') {
+										this.currentPosition++;
+										this.currentCharacter = '\n';
+									} else if ((this.source[this.currentPosition] == '\\')
+											&& (this.source[this.currentPosition + 1] == 'u')) {
+										isUnicode = true;
+										getNextUnicodeChar();
+									}
+								}
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.recordLineSeparator
+									&& ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
+										if (this.checkNonExternalizedStringLiterals &&
+												this.lastPosition < this.currentPosition) {
+											parseTags();
+										}
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+							} catch (IndexOutOfBoundsException e) {
+								 //an eof will then be generated
+								this.currentPosition--;
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.checkNonExternalizedStringLiterals &&
+										this.lastPosition < this.currentPosition) {
+									parseTags();
+								}
+								if (!this.tokenizeComments) {
+									this.currentPosition++;
+								}
+							}
+							break NextToken;
+						}
+						if (test > 0) { //traditional and javadoc comment
+							boolean isJavadoc = false;
+							try { //get the next char
+								boolean star = false;
+								int previous;
+								boolean isUnicode = false;
+								// consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+
+								if (this.currentCharacter == '*') {
+									isJavadoc = true;
+									star = true;
+								}
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								isUnicode = false;
+								previous = this.currentPosition;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++; //jump over the \\
+								}
+								// empty comment is not a javadoc /**/
+								if (this.currentCharacter == '/') {
+									isJavadoc = false;
+								}
+								//loop until end of comment */
+								int firstTag = 0;
+								while ((this.currentCharacter != '/') || (!star)) {
+									if (this.currentPosition >= this.eofPosition) {
+										return;
+									}
+									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0 && this.isFirstTag()) {
+												firstTag = previous;
+											}
+											//$FALL-THROUGH$ default case to set star to false
+										default:
+											star = false;
+									}
+									//get next char
+									previous = this.currentPosition;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									} else {
+										isUnicode = false;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								recordComment(isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK);
+								this.commentTagStarts[this.commentPtr] = firstTag;
+							} catch (IndexOutOfBoundsException e) {
+								return;
+							}
+							break NextToken;
+						}
+						break NextToken;
+					}
+
+				default :
+					try {
+						char c = this.currentCharacter;
+						if (c < ScannerHelper.MAX_OBVIOUS) {
+							if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+								scanIdentifierOrKeyword();
+								break NextToken;
+							} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
+								scanNumber(false);
+								break NextToken;
+							} else {
+								break NextToken;
+							}
+						}
+						boolean isJavaIdStart;
+						if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							// Unicode 4 detection
+							char low = (char) getNextChar();
+							if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+								// illegal low surrogate
+								break NextToken;
+							}
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+						} else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+							break NextToken;
+						} else {
+							// optimized case already checked
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+						}
+						if (isJavaIdStart) {
+							scanIdentifierOrKeyword();
+							break NextToken;
+						}
+//						if (ScannerHelper.isDigit(this.currentCharacter)) {
+//							scanNumber(false);
+//							break NextToken;
+//						}
+					} catch (InvalidInputException ex) {
+						// ignore
+					}
+			}
+		}
+		//-----------------end switch while try--------------------
+	} catch (IndexOutOfBoundsException e) {
+		// ignore
+	} catch (InvalidInputException e) {
+		// ignore
+	}
+	return;
+}
+public final boolean jumpOverUnicodeWhiteSpace() throws InvalidInputException {
+	//BOOLEAN
+	//handle the case of unicode. Jump over the next whiteSpace
+	//making startPosition pointing on the next available char
+	//On false, the currentCharacter is filled up with a potential
+	//correct char
+
+	this.wasAcr = false;
+	getNextUnicodeChar();
+	return CharOperation.isWhitespace(this.currentCharacter);
+}
+
+final char[] optimizedCurrentTokenSource1() {
+	//return always the same char[] build only once
+
+	//optimization at no speed cost of 99.5 % of the singleCharIdentifier
+	char charOne = this.source[this.startPosition];
+	switch (charOne) {
+		case 'a' :
+			return charArray_a;
+		case 'b' :
+			return charArray_b;
+		case 'c' :
+			return charArray_c;
+		case 'd' :
+			return charArray_d;
+		case 'e' :
+			return charArray_e;
+		case 'f' :
+			return charArray_f;
+		case 'g' :
+			return charArray_g;
+		case 'h' :
+			return charArray_h;
+		case 'i' :
+			return charArray_i;
+		case 'j' :
+			return charArray_j;
+		case 'k' :
+			return charArray_k;
+		case 'l' :
+			return charArray_l;
+		case 'm' :
+			return charArray_m;
+		case 'n' :
+			return charArray_n;
+		case 'o' :
+			return charArray_o;
+		case 'p' :
+			return charArray_p;
+		case 'q' :
+			return charArray_q;
+		case 'r' :
+			return charArray_r;
+		case 's' :
+			return charArray_s;
+		case 't' :
+			return charArray_t;
+		case 'u' :
+			return charArray_u;
+		case 'v' :
+			return charArray_v;
+		case 'w' :
+			return charArray_w;
+		case 'x' :
+			return charArray_x;
+		case 'y' :
+			return charArray_y;
+		case 'z' :
+			return charArray_z;
+		default :
+			return new char[] {charOne};
+	}
+}
+final char[] optimizedCurrentTokenSource2() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0 , c1;
+	int hash = (((c0=src[start]) << 6) + (c1=src[start+1])) % TableSize;
+	char[][] table = this.charArray_length[0][hash];
+	int i = this.newEntry2;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry2;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[2], 0, 2);
+	//newIdentCount++;
+	return table[this.newEntry2 = max] = r; //(r = new char[] {c0, c1});
+}
+final char[] optimizedCurrentTokenSource3() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1=src[start+1], c2;
+	int hash = (((c0=src[start])<< 6) + (c2=src[start+2])) % TableSize;
+//	int hash = ((c0 << 12) + (c1<< 6) + c2) % TableSize;
+	char[][] table = this.charArray_length[1][hash];
+	int i = this.newEntry3;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry3;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[3], 0, 3);
+	//newIdentCount++;
+	return table[this.newEntry3 = max] = r; //(r = new char[] {c0, c1, c2});
+}
+final char[] optimizedCurrentTokenSource4() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3];
+	int hash = (((c0=src[start]) << 6) + (c2=src[start+2])) % TableSize;
+//	int hash = (int) (((((long) c0) << 18) + (c1 << 12) + (c2 << 6) + c3) % TableSize);
+	char[][] table = this.charArray_length[2][hash];
+	int i = this.newEntry4;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry4;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[4], 0, 4);
+	//newIdentCount++;
+	return table[this.newEntry4 = max] = r; //(r = new char[] {c0, c1, c2, c3});
+}
+final char[] optimizedCurrentTokenSource5() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4;
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int) (((((long) c0) << 24) + (((long) c1) << 18) + (c2 << 12) + (c3 << 6) + c4) % TableSize);
+	char[][] table = this.charArray_length[3][hash];
+	int i = this.newEntry5;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry5;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[5], 0, 5);
+	//newIdentCount++;
+	return table[this.newEntry5 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4});
+}
+final char[] optimizedCurrentTokenSource6() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4, c5 = src[start+5];
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int)(((((long) c0) << 32) + (((long) c1) << 24) + (((long) c2) << 18) + (c3 << 12) + (c4 << 6) + c5) % TableSize);
+	char[][] table = this.charArray_length[4][hash];
+	int i = this.newEntry6;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4])
+			&& (c5 == charArray[5]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry6;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4])
+			&& (c5 == charArray[5]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[6], 0, 6);
+	//newIdentCount++;
+	return table[this.newEntry6 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4, c5});
+}
+
+private void parseTags() {
+	int position = 0;
+	final int currentStartPosition = this.startPosition;
+	final int currentLinePtr = this.linePtr;
+	if (currentLinePtr >= 0) {
+		position = this.lineEnds[currentLinePtr] + 1;
+	}
+	while (ScannerHelper.isWhitespace(this.source[position])) {
+		position++;
+	}
+	if (currentStartPosition == position) {
+		// the whole line is commented out
+		return;
+	}
+	char[] s = null;
+	int sourceEnd = this.currentPosition;
+	int sourceStart = currentStartPosition;
+	int sourceDelta = 0;
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			s = new char[this.withoutUnicodePtr],
+			0,
+			this.withoutUnicodePtr);
+		sourceEnd = this.withoutUnicodePtr;
+		sourceStart = 1;
+		sourceDelta = currentStartPosition;
+	} else {
+		s = this.source;
+	}
+	int pos = CharOperation.indexOf(TAG_PREFIX, s, true, sourceStart, sourceEnd);
+	if (pos != -1) {
+		if (this.nlsTags == null) {
+			this.nlsTags = new NLSTag[10];
+			this.nlsTagsPtr = 0;
+		}
+		while (pos != -1) {
+			int start = pos + TAG_PREFIX_LENGTH;
+			int end = CharOperation.indexOf(TAG_POSTFIX, s, start, sourceEnd);
+			if (end != -1) {
+				NLSTag currentTag = null;
+				final int currentLine = currentLinePtr + 1;
+				try {
+					currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, extractInt(s, start, end));
+				} catch (NumberFormatException e) {
+					currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, -1);
+				}
+				if (this.nlsTagsPtr == this.nlsTags.length) {
+					// resize
+					System.arraycopy(this.nlsTags, 0, (this.nlsTags = new NLSTag[this.nlsTagsPtr + 10]), 0, this.nlsTagsPtr);
+				}
+				this.nlsTags[this.nlsTagsPtr++] = currentTag;
+			} else {
+				end = start;
+			}
+			pos = CharOperation.indexOf(TAG_PREFIX, s, true, end, sourceEnd);
+		}
+	}
+}
+private int extractInt(char[] array, int start, int end) {
+	int value = 0;
+	for (int i = start; i < end; i++) {
+		final char currentChar = array[i];
+		int digit = 0;
+		switch(currentChar) {
+			case '0' :
+				digit = 0;
+				break;
+			case '1' :
+				digit = 1;
+				break;
+			case '2' :
+				digit = 2;
+				break;
+			case '3' :
+				digit = 3;
+				break;
+			case '4' :
+				digit = 4;
+				break;
+			case '5' :
+				digit = 5;
+				break;
+			case '6' :
+				digit = 6;
+				break;
+			case '7' :
+				digit = 7;
+				break;
+			case '8' :
+				digit = 8;
+				break;
+			case '9' :
+				digit = 9;
+				break;
+			default :
+				throw new NumberFormatException();
+		}
+		value *= 10;
+		if (digit < 0) throw new NumberFormatException();
+		value += digit;
+	}
+	return value;
+}
+public final void pushLineSeparator() {
+	//see comment on isLineDelimiter(char) for the use of '\n' and '\r'
+	final int INCREMENT = 250;
+	//currentCharacter is at position currentPosition-1
+	// cr 000D
+	if (this.currentCharacter == '\r') {
+		int separatorPos = this.currentPosition - 1;
+		if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
+		int length = this.lineEnds.length;
+		if (++this.linePtr >=  length)
+			System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
+		this.lineEnds[this.linePtr] = separatorPos;
+		// look-ahead for merged cr+lf
+		try {
+			if (this.source[this.currentPosition] == '\n') {
+				//System.out.println("look-ahead LF-" + this.currentPosition);
+				this.lineEnds[this.linePtr] = this.currentPosition;
+				this.currentPosition++;
+				this.wasAcr = false;
+			} else {
+				this.wasAcr = true;
+			}
+		} catch(IndexOutOfBoundsException e) {
+			this.wasAcr = true;
+		}
+	} else {
+		// lf 000A
+		if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
+			if (this.wasAcr && (this.lineEnds[this.linePtr] == (this.currentPosition - 2))) {
+				//System.out.println("merge LF-" + (this.currentPosition - 1));
+				this.lineEnds[this.linePtr] = this.currentPosition - 1;
+			} else {
+				int separatorPos = this.currentPosition - 1;
+				if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
+				int length = this.lineEnds.length;
+				if (++this.linePtr >=  length)
+					System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
+				this.lineEnds[this.linePtr] = separatorPos;
+			}
+			this.wasAcr = false;
+		}
+	}
+}
+public final void pushUnicodeLineSeparator() {
+	// cr 000D
+	if (this.currentCharacter == '\r') {
+		if (this.source[this.currentPosition] == '\n') {
+			this.wasAcr = false;
+		} else {
+			this.wasAcr = true;
+		}
+	} else {
+		// lf 000A
+		if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
+			this.wasAcr = false;
+		}
+	}
+}
+
+public void recordComment(int token) {
+	// compute position
+	int commentStart = this.startPosition;
+	int stopPosition = this.currentPosition;
+	switch (token) {
+		case TokenNameCOMMENT_LINE:
+			// both positions are negative
+			commentStart = -this.startPosition;
+			stopPosition = -this.lastCommentLinePosition;
+			break;
+		case TokenNameCOMMENT_BLOCK:
+			// only end position is negative
+			stopPosition = -this.currentPosition;
+			break;
+	}
+
+	// a new comment is recorded
+	int length = this.commentStops.length;
+	if (++this.commentPtr >=  length) {
+		int newLength = length + COMMENT_ARRAYS_SIZE*10;
+		System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length);
+		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length);
+		System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length);
+	}
+	this.commentStops[this.commentPtr] = stopPosition;
+	this.commentStarts[this.commentPtr] = commentStart;
+}
+
+/**
+ * Reposition the scanner on some portion of the original source. The given endPosition is the last valid position.
+ * Beyond this position, the scanner will answer EOF tokens (<code>ITerminalSymbols.TokenNameEOF</code>).
+ *
+ * @param begin the given start position
+ * @param end the given end position
+ */
+public void resetTo(int begin, int end) {
+	//reset the scanner to a given position where it may rescan again
+
+	this.diet = false;
+	this.initialPosition = this.startPosition = this.currentPosition = begin;
+	if (this.source != null && this.source.length < end) {
+		this.eofPosition = this.source.length;
+	} else {
+		this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	}
+	this.commentPtr = -1; // reset comment stack
+	this.foundTaskCount = 0;
+	this.lookBack[0] = this.lookBack[1] = this.nextToken = TokenNameNotAToken;
+}
+
+protected final void scanEscapeCharacter() throws InvalidInputException {
+	// the string with "\\u" is a legal string of two chars \ and u
+	//thus we use a direct access to the source (for regular cases).
+	switch (this.currentCharacter) {
+		case 'b' :
+			this.currentCharacter = '\b';
+			break;
+		case 't' :
+			this.currentCharacter = '\t';
+			break;
+		case 'n' :
+			this.currentCharacter = '\n';
+			break;
+		case 'f' :
+			this.currentCharacter = '\f';
+			break;
+		case 'r' :
+			this.currentCharacter = '\r';
+			break;
+		case '\"' :
+			this.currentCharacter = '\"';
+			break;
+		case '\'' :
+			this.currentCharacter = '\'';
+			break;
+		case '\\' :
+			this.currentCharacter = '\\';
+			break;
+		default :
+			// -----------octal escape--------------
+			// OctalDigit
+			// OctalDigit OctalDigit
+			// ZeroToThree OctalDigit OctalDigit
+
+			int number = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+			if (number >= 0 && number <= 7) {
+				boolean zeroToThreeNot = number > 3;
+				if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
+					int digit = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+					if (digit >= 0 && digit <= 7) {
+						number = (number * 8) + digit;
+						if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
+							if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character
+								this.currentPosition--;
+							} else {
+								digit = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+								if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit
+									number = (number * 8) + digit;
+								} else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character
+									this.currentPosition--;
+								}
+							}
+						} else { // has read \OctalDigit NonDigit--> ignore last character
+							this.currentPosition--;
+						}
+					} else { // has read \OctalDigit NonOctalDigit--> ignore last character
+						this.currentPosition--;
+					}
+				} else { // has read \OctalDigit --> ignore last character
+					this.currentPosition--;
+				}
+				if (number > 255)
+					throw new InvalidInputException(INVALID_ESCAPE);
+				this.currentCharacter = (char) number;
+			} else
+				throw new InvalidInputException(INVALID_ESCAPE);
+	}
+}
+public int scanIdentifierOrKeywordWithBoundCheck() {
+	//test keywords
+
+	//first dispatch on the first char.
+	//then the length. If there are several
+	//keywors with the same length AND the same first char, then do another
+	//dispatch on the second char
+	this.useAssertAsAnIndentifier = false;
+	this.useEnumAsAnIndentifier = false;
+
+	char[] src = this.source;
+	identLoop: {
+		int pos;
+		int srcLength = this.eofPosition;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < ScannerHelper.MAX_OBVIOUS) {
+				if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
+						(ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
+					if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+				} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
+						this.currentCharacter = c;
+						break identLoop;
+				} else {
+					//System.out.println("slow<=128:  "+ c);
+					while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
+					break identLoop;
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);
+				while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
+				break identLoop;
+			}
+		}
+	}
+
+	int index, length;
+	char[] data;
+	if (this.withoutUnicodePtr == 0) {
+		//quick test on length == 1 but not on length > 12 while most identifier
+		//have a length which is <= 12...but there are lots of identifier with
+		//only one char....
+		if ((length = this.currentPosition - this.startPosition) == 1) {
+			return TokenNameIdentifier;
+		}
+		data = this.source;
+		index = this.startPosition;
+	} else {
+		if ((length = this.withoutUnicodePtr) == 1)
+			return TokenNameIdentifier;
+		data = this.withoutUnicodeBuffer;
+		index = 1;
+	}
+
+	return internalScanIdentifierOrKeyword(index, length, data);
+}
+public int scanIdentifierOrKeyword() {
+	//test keywords
+
+	//first dispatch on the first char.
+	//then the length. If there are several
+	//keywords with the same length AND the same first char, then do another
+	//dispatch on the second char
+	this.useAssertAsAnIndentifier = false;
+	this.useEnumAsAnIndentifier = false;
+
+	char[] src = this.source;
+	identLoop: {
+		int pos;
+		int srcLength = this.eofPosition;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < ScannerHelper.MAX_OBVIOUS) {
+				if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
+						(ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
+					if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+				} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
+						this.currentCharacter = c;
+						break identLoop;
+				} else {
+					//System.out.println("slow<=128:  "+ c);
+					while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+					break identLoop;
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);
+				while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+				break identLoop;
+			}
+		}
+	}
+
+	int index, length;
+	char[] data;
+	if (this.withoutUnicodePtr == 0) {
+		//quick test on length == 1 but not on length > 12 while most identifier
+		//have a length which is <= 12...but there are lots of identifier with
+		//only one char....
+		if ((length = this.currentPosition - this.startPosition) == 1) {
+			return TokenNameIdentifier;
+		}
+		data = this.source;
+		index = this.startPosition;
+	} else {
+		if ((length = this.withoutUnicodePtr) == 1)
+			return TokenNameIdentifier;
+		data = this.withoutUnicodeBuffer;
+		index = 1;
+	}
+
+	return internalScanIdentifierOrKeyword(index, length, data);
+}
+private int internalScanIdentifierOrKeyword(int index, int length, char[] data) {
+	switch (data[index]) {
+		case 'a' :
+			switch(length) {
+				case 8: //abstract
+					if ((data[++index] == 'b')
+						&& (data[++index] == 's')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')) {
+							return TokenNameabstract;
+						} else {
+							return TokenNameIdentifier;
+						}
+				case 6: // assert
+					if ((data[++index] == 's')
+						&& (data[++index] == 's')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 't')) {
+							if (this.sourceLevel >= ClassFileConstants.JDK1_4) {
+								this.containsAssertKeyword = true;
+								return TokenNameassert;
+							} else {
+								this.useAssertAsAnIndentifier = true;
+								return TokenNameIdentifier;
+							}
+						} else {
+							return TokenNameIdentifier;
+						}
+				default:
+					return TokenNameIdentifier;
+			}
+		case 'b' : //boolean break byte
+			switch (length) {
+				case 4 :
+					if ((data[++index] == 'y') && (data[++index] == 't') && (data[++index] == 'e'))
+						return TokenNamebyte;
+					else
+						return TokenNameIdentifier;
+				case 5 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'k'))
+						return TokenNamebreak;
+					else
+						return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'n'))
+						return TokenNameboolean;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'c' : //case char catch const class continue
+			switch (length) {
+				case 4 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 's') && (data[++index] == 'e'))
+							return TokenNamecase;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'h') && (data[++index] == 'a') && (data[++index] == 'r'))
+							return TokenNamechar;
+						else
+							return TokenNameIdentifier;
+				case 5 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
+							return TokenNamecatch;
+						else
+							return TokenNameIdentifier;
+					else
+						if (data[index] == 'l')
+							if ((data[++index] == 'a')
+								&& (data[++index] == 's')
+								&& (data[++index] == 's'))
+								return TokenNameclass;
+							else
+								return TokenNameIdentifier;
+						else if ((data[index] == 'o')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 's')
+							&& (data[++index] == 't'))
+							return TokenNameconst; //const is not used in java ???????
+						else
+							return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'e'))
+						return TokenNamecontinue;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'd' : //default do double
+			switch (length) {
+				case 2 :
+					if ((data[++index] == 'o'))
+						return TokenNamedo;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'b')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e'))
+						return TokenNamedouble;
+					else
+						return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'e')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 't'))
+						return TokenNamedefault;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+		case 'e' : //else extends
+			switch (length) {
+				case 4 :
+					if (data[++index] == 'l') {
+						if ((data[++index] == 's') && (data[++index] == 'e')) {
+							return TokenNameelse;
+						} else {
+							return TokenNameIdentifier;
+						}
+					} else if ((data[index] == 'n')
+							&& (data[++index] == 'u')
+							&& (data[++index] == 'm')) {
+						if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+							return TokenNameenum;
+						} else {
+							this.useEnumAsAnIndentifier = true;
+							return TokenNameIdentifier;
+						}
+					}
+					return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'x')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'd')
+						&& (data[++index] == 's'))
+						return TokenNameextends;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'f' : //final finally float for false
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'o') && (data[++index] == 'r'))
+						return TokenNamefor;
+					else
+						return TokenNameIdentifier;
+				case 5 :
+					if (data[++index] == 'i')
+						if ((data[++index] == 'n')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'l')) {
+							return TokenNamefinal;
+						} else
+							return TokenNameIdentifier;
+					else
+						if (data[index] == 'l')
+							if ((data[++index] == 'o')
+								&& (data[++index] == 'a')
+								&& (data[++index] == 't'))
+								return TokenNamefloat;
+							else
+								return TokenNameIdentifier;
+						else
+							if ((data[index] == 'a')
+								&& (data[++index] == 'l')
+								&& (data[++index] == 's')
+								&& (data[++index] == 'e'))
+								return TokenNamefalse;
+							else
+								return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'i')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'y'))
+						return TokenNamefinally;
+					else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+		case 'g' : //goto
+			if (length == 4) {
+				if ((data[++index] == 'o')
+					&& (data[++index] == 't')
+					&& (data[++index] == 'o')) {
+					return TokenNamegoto;
+				}
+			} //no goto in java are allowed, so why java removes this keyword ???
+			return TokenNameIdentifier;
+
+		case 'i' : //if implements import instanceof int interface
+			switch (length) {
+				case 2 :
+					if (data[++index] == 'f')
+						return TokenNameif;
+					else
+						return TokenNameIdentifier;
+				case 3 :
+					if ((data[++index] == 'n') && (data[++index] == 't'))
+						return TokenNameint;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'm')
+						&& (data[++index] == 'p')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 't'))
+						return TokenNameimport;
+					else
+						return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'n')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 'e'))
+						return TokenNameinterface;
+					else
+						return TokenNameIdentifier;
+				case 10 :
+					if (data[++index] == 'm')
+						if ((data[++index] == 'p')
+							&& (data[++index] == 'l')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'm')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 't')
+							&& (data[++index] == 's'))
+							return TokenNameimplements;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'n')
+							&& (data[++index] == 's')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 'c')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'o')
+							&& (data[++index] == 'f'))
+							return TokenNameinstanceof;
+						else
+							return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'l' : //long
+			if (length == 4) {
+				if ((data[++index] == 'o')
+					&& (data[++index] == 'n')
+					&& (data[++index] == 'g')) {
+					return TokenNamelong;
+				}
+			}
+			return TokenNameIdentifier;
+
+		case 'n' : //native new null
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'e') && (data[++index] == 'w'))
+						return TokenNamenew;
+					else
+						return TokenNameIdentifier;
+				case 4 :
+					if ((data[++index] == 'u') && (data[++index] == 'l') && (data[++index] == 'l'))
+						return TokenNamenull;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'a')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'v')
+						&& (data[++index] == 'e')) {
+						return TokenNamenative;
+					} else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'p' : //package private protected public
+			switch (length) {
+				case 6 :
+					if ((data[++index] == 'u')
+						&& (data[++index] == 'b')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'c')) {
+						return TokenNamepublic;
+					} else
+						return TokenNameIdentifier;
+				case 7 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 'c')
+							&& (data[++index] == 'k')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'g')
+							&& (data[++index] == 'e'))
+							return TokenNamepackage;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'r')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 'v')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'e')) {
+							return TokenNameprivate;
+						} else
+							return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'd')) {
+						return TokenNameprotected;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'r' : //return
+			if (length == 6) {
+				if ((data[++index] == 'e')
+					&& (data[++index] == 't')
+					&& (data[++index] == 'u')
+					&& (data[++index] == 'r')
+					&& (data[++index] == 'n')) {
+					return TokenNamereturn;
+				}
+			}
+			return TokenNameIdentifier;
+
+		case 's' : //short static super switch synchronized strictfp
+			switch (length) {
+				case 5 :
+					if (data[++index] == 'h')
+						if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 't'))
+							return TokenNameshort;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'u')
+							&& (data[++index] == 'p')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'r'))
+							return TokenNamesuper;
+						else
+							return TokenNameIdentifier;
+
+				case 6 :
+					if (data[++index] == 't')
+						if ((data[++index] == 'a')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 'c')) {
+							return TokenNamestatic;
+						} else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'w')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'c')
+							&& (data[++index] == 'h'))
+							return TokenNameswitch;
+						else
+							return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 't')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'p'))
+						return TokenNamestrictfp;
+					else
+						return TokenNameIdentifier;
+				case 12 :
+					if ((data[++index] == 'y')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'z')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'd')) {
+						return TokenNamesynchronized;
+					} else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 't' : //try throw throws transient this true
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'r') && (data[++index] == 'y'))
+						return TokenNametry;
+					else
+						return TokenNameIdentifier;
+				case 4 :
+					if (data[++index] == 'h')
+						if ((data[++index] == 'i') && (data[++index] == 's'))
+							return TokenNamethis;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'r') && (data[++index] == 'u') && (data[++index] == 'e'))
+							return TokenNametrue;
+						else
+							return TokenNameIdentifier;
+				case 5 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'w'))
+						return TokenNamethrow;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'w')
+						&& (data[++index] == 's'))
+						return TokenNamethrows;
+					else
+						return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 's')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 't')) {
+						return TokenNametransient;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'v' : //void volatile
+			switch (length) {
+				case 4 :
+					if ((data[++index] == 'o') && (data[++index] == 'i') && (data[++index] == 'd'))
+						return TokenNamevoid;
+					else
+						return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e')) {
+						return TokenNamevolatile;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'w' : //while widefp
+			switch (length) {
+				case 5 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e'))
+						return TokenNamewhile;
+					else
+						return TokenNameIdentifier;
+					//case 6:if ( (data[++index] =='i') && (data[++index]=='d') && (data[++index]=='e') && (data[++index]=='f')&& (data[++index]=='p'))
+					//return TokenNamewidefp ;
+					//else
+					//return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		default :
+			return TokenNameIdentifier;
+	}
+}
+
+
+public int scanNumber(boolean dotPrefix) throws InvalidInputException {
+
+	//when entering this method the currentCharacter is the first
+	//digit of the number. It may be preceeded by a '.' when
+	//dotPrefix is true
+
+	boolean floating = dotPrefix;
+	if (!dotPrefix && (this.currentCharacter == '0')) {
+		if (getNextChar('x', 'X') >= 0) { //----------hexa-----------------
+			int start = this.currentPosition;
+			consumeDigits(16, true);
+			int end = this.currentPosition;
+			if (getNextChar('l', 'L') >= 0) {
+				if (end == start) {
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+				return TokenNameLongLiteral;
+			} else if (getNextChar('.')) {
+				// hexadecimal floating point literal
+				// read decimal part
+				boolean hasNoDigitsBeforeDot = end == start;
+				start = this.currentPosition;
+				consumeDigits(16, true);
+				end = this.currentPosition;
+				if (hasNoDigitsBeforeDot && end == start) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+
+				if (getNextChar('p', 'P') >= 0) { // consume next character
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+
+					if ((this.currentCharacter == '-')
+							|| (this.currentCharacter == '+')) { // consume next character
+						this.unicodeAsBackSlash = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (!ScannerHelper.isDigit(this.currentCharacter)) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						if (this.currentCharacter == '_') {
+							// wrongly place '_'
+							consumeDigits(10);
+							throw new InvalidInputException(INVALID_UNDERSCORE);
+						}
+						throw new InvalidInputException(INVALID_HEXA);
+					}
+					consumeDigits(10);
+					if (getNextChar('f', 'F') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						return TokenNameFloatingPointLiteral;
+					}
+					if (getNextChar('d', 'D') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						return TokenNameDoubleLiteral;
+					}
+					if (getNextChar('l', 'L') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						throw new InvalidInputException(INVALID_HEXA);
+					}
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameDoubleLiteral;
+				} else {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+			} else if (getNextChar('p', 'P') >= 0) { // consume next character
+				this.unicodeAsBackSlash = false;
+				if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+						&& (this.source[this.currentPosition] == 'u')) {
+					getNextUnicodeChar();
+				} else {
+					if (this.withoutUnicodePtr != 0) {
+						unicodeStore();
+					}
+				}
+
+				if ((this.currentCharacter == '-')
+						|| (this.currentCharacter == '+')) { // consume next character
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+				}
+				if (!ScannerHelper.isDigit(this.currentCharacter)) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					if (this.currentCharacter == '_') {
+						// wrongly place '_'
+						consumeDigits(10);
+						throw new InvalidInputException(INVALID_UNDERSCORE);
+					}
+					throw new InvalidInputException(INVALID_FLOAT);
+				}
+				consumeDigits(10);
+				if (getNextChar('f', 'F') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameFloatingPointLiteral;
+				}
+				if (getNextChar('d', 'D') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameDoubleLiteral;
+				}
+				if (getNextChar('l', 'L') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+				if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+					throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+				}
+				return TokenNameDoubleLiteral;
+			} else {
+				if (end == start)
+					throw new InvalidInputException(INVALID_HEXA);
+				return TokenNameIntegerLiteral;
+			}
+		} else if (getNextChar('b', 'B') >= 0) { //----------binary-----------------
+			int start = this.currentPosition;
+			consumeDigits(2, true);
+			int end = this.currentPosition;
+			if (end == start) {
+				if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+					throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+				}
+				throw new InvalidInputException(INVALID_BINARY);
+			}
+			if (getNextChar('l', 'L') >= 0) {
+				if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+					throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+				}
+				return TokenNameLongLiteral;
+			}
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+			}
+			return TokenNameIntegerLiteral;
+		}
+
+		//there is no x or X nor b or B in the number
+		//potential octal
+		if (getNextCharAsDigit()) { //-------------potential octal-----------------
+			consumeDigits(10);
+
+			if (getNextChar('l', 'L') >= 0) {
+				return TokenNameLongLiteral;
+			}
+
+			if (getNextChar('f', 'F') >= 0) {
+				return TokenNameFloatingPointLiteral;
+			}
+
+			if (getNextChar('d', 'D') >= 0) {
+				return TokenNameDoubleLiteral;
+			} else { //make the distinction between octal and float ....
+				boolean isInteger = true;
+				if (getNextChar('.')) {
+					isInteger = false;
+					consumeDigits(10);
+				}
+				if (getNextChar('e', 'E') >= 0) { // consume next character
+					isInteger = false;
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+
+					if ((this.currentCharacter == '-')
+							|| (this.currentCharacter == '+')) { // consume next character
+						this.unicodeAsBackSlash = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (!ScannerHelper.isDigit(this.currentCharacter)) {
+						if (this.currentCharacter == '_') {
+							// wrongly place '_'
+							consumeDigits(10);
+							throw new InvalidInputException(INVALID_UNDERSCORE);
+						}
+						throw new InvalidInputException(INVALID_FLOAT);
+					}
+					consumeDigits(10);
+				}
+				if (getNextChar('f', 'F') >= 0)
+					return TokenNameFloatingPointLiteral;
+				if (getNextChar('d', 'D') >= 0 || !isInteger)
+					return TokenNameDoubleLiteral;
+				return TokenNameIntegerLiteral;
+			}
+		} else {
+			/* carry on */
+		}
+	}
+
+	consumeDigits(10);
+
+	if ((!dotPrefix) && (getNextChar('l', 'L') >= 0))
+		return TokenNameLongLiteral;
+
+	if ((!dotPrefix) && (getNextChar('.'))) { //decimal part that can be empty
+		consumeDigits(10, true);
+		floating = true;
+	}
+
+	//if floating is true both exponant and suffix may be optional
+
+	if (getNextChar('e', 'E') >= 0) {
+		floating = true;
+		// consume next character
+		this.unicodeAsBackSlash = false;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+				&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+		} else {
+			if (this.withoutUnicodePtr != 0) {
+				unicodeStore();
+			}
+		}
+
+		if ((this.currentCharacter == '-')
+				|| (this.currentCharacter == '+')) { // consume next character
+			this.unicodeAsBackSlash = false;
+			if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+					&& (this.source[this.currentPosition] == 'u')) {
+				getNextUnicodeChar();
+			} else {
+				if (this.withoutUnicodePtr != 0) {
+					unicodeStore();
+				}
+			}
+		}
+		if (!ScannerHelper.isDigit(this.currentCharacter)) {
+			if (this.currentCharacter == '_') {
+				// wrongly place '_'
+				consumeDigits(10);
+				throw new InvalidInputException(INVALID_UNDERSCORE);
+			}
+			throw new InvalidInputException(INVALID_FLOAT);
+		}
+		// current character is a digit so we expect no digit first (the next character could be an underscore)
+		consumeDigits(10);
+	}
+
+	if (getNextChar('d', 'D') >= 0)
+		return TokenNameDoubleLiteral;
+	if (getNextChar('f', 'F') >= 0)
+		return TokenNameFloatingPointLiteral;
+
+	//the long flag has been tested before
+
+	return floating ? TokenNameDoubleLiteral : TokenNameIntegerLiteral;
+}
+
+/**
+ * Search the line number corresponding to a specific position
+ * @param position int
+ * @return int
+ */
+public final int getLineNumber(int position) {
+	return Util.getLineNumber(position, this.lineEnds, 0, this.linePtr);
+}
+public final void setSource(char[] sourceString){
+	//the source-buffer is set to sourceString
+
+	int sourceLength;
+	if (sourceString == null) {
+		this.source = CharOperation.NO_CHAR;
+		sourceLength = 0;
+	} else {
+		this.source = sourceString;
+		sourceLength = sourceString.length;
+	}
+	this.startPosition = -1;
+	this.eofPosition = sourceLength;
+	this.initialPosition = this.currentPosition = 0;
+	this.containsAssertKeyword = false;
+	this.linePtr = -1;
+}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(char[] contents, CompilationResult compilationResult) {
+	if (contents == null) {
+		char[] cuContents = compilationResult.compilationUnit.getContents();
+		setSource(cuContents);
+	} else {
+		setSource(contents);
+	}
+	int[] lineSeparatorPositions = compilationResult.lineSeparatorPositions;
+	if (lineSeparatorPositions != null) {
+		this.lineEnds = lineSeparatorPositions;
+		this.linePtr = lineSeparatorPositions.length - 1;
+	}
+}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(CompilationResult compilationResult) {
+	setSource(null, compilationResult);
+}
+public String toString() {
+	if (this.startPosition == this.eofPosition)
+		return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
+	if (this.currentPosition > this.eofPosition)
+		return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
+	if (this.currentPosition <= 0)
+		return "NOT started!\n\n"+ (this.source != null ? new String(this.source) : ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+	StringBuffer buffer = new StringBuffer();
+	if (this.startPosition < 1000) {
+		buffer.append(this.source, 0, this.startPosition);
+	} else {
+		buffer.append("<source beginning>\n...\n"); //$NON-NLS-1$
+		int line = Util.getLineNumber(this.startPosition-1000, this.lineEnds, 0, this.linePtr);
+		int lineStart = getLineStart(line);
+		buffer.append(this.source, lineStart, this.startPosition-lineStart);
+	}
+
+	buffer.append("\n===============================\nStarts here -->"); //$NON-NLS-1$
+	int middleLength = (this.currentPosition - 1) - this.startPosition + 1;
+	if (middleLength > -1) {
+		buffer.append(this.source, this.startPosition, middleLength);
+	}
+	if (this.nextToken != TerminalTokens.TokenNameNotAToken) {
+		buffer.append("<-- Ends here [in pipeline " + toStringAction(this.nextToken) + "]\n===============================\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	} else {
+		buffer.append("<-- Ends here\n===============================\n"); //$NON-NLS-1$
+	}
+
+	buffer.append(this.source, (this.currentPosition - 1) + 1, this.eofPosition - (this.currentPosition - 1) - 1);
+
+	return buffer.toString();
+}
+public String toStringAction(int act) {
+	switch (act) {
+		case TokenNameIdentifier :
+			return "Identifier(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameabstract :
+			return "abstract"; //$NON-NLS-1$
+		case TokenNameboolean :
+			return "boolean"; //$NON-NLS-1$
+		case TokenNamebreak :
+			return "break"; //$NON-NLS-1$
+		case TokenNamebyte :
+			return "byte"; //$NON-NLS-1$
+		case TokenNamecase :
+			return "case"; //$NON-NLS-1$
+		case TokenNamecatch :
+			return "catch"; //$NON-NLS-1$
+		case TokenNamechar :
+			return "char"; //$NON-NLS-1$
+		case TokenNameclass :
+			return "class"; //$NON-NLS-1$
+		case TokenNamecontinue :
+			return "continue"; //$NON-NLS-1$
+		case TokenNamedefault :
+			return "default"; //$NON-NLS-1$
+		case TokenNamedo :
+			return "do"; //$NON-NLS-1$
+		case TokenNamedouble :
+			return "double"; //$NON-NLS-1$
+		case TokenNameelse :
+			return "else"; //$NON-NLS-1$
+		case TokenNameextends :
+			return "extends"; //$NON-NLS-1$
+		case TokenNamefalse :
+			return "false"; //$NON-NLS-1$
+		case TokenNamefinal :
+			return "final"; //$NON-NLS-1$
+		case TokenNamefinally :
+			return "finally"; //$NON-NLS-1$
+		case TokenNamefloat :
+			return "float"; //$NON-NLS-1$
+		case TokenNamefor :
+			return "for"; //$NON-NLS-1$
+		case TokenNameif :
+			return "if"; //$NON-NLS-1$
+		case TokenNameimplements :
+			return "implements"; //$NON-NLS-1$
+		case TokenNameimport :
+			return "import"; //$NON-NLS-1$
+		case TokenNameinstanceof :
+			return "instanceof"; //$NON-NLS-1$
+		case TokenNameint :
+			return "int"; //$NON-NLS-1$
+		case TokenNameinterface :
+			return "interface"; //$NON-NLS-1$
+		case TokenNamelong :
+			return "long"; //$NON-NLS-1$
+		case TokenNamenative :
+			return "native"; //$NON-NLS-1$
+		case TokenNamenew :
+			return "new"; //$NON-NLS-1$
+		case TokenNamenull :
+			return "null"; //$NON-NLS-1$
+		case TokenNamepackage :
+			return "package"; //$NON-NLS-1$
+		case TokenNameprivate :
+			return "private"; //$NON-NLS-1$
+		case TokenNameprotected :
+			return "protected"; //$NON-NLS-1$
+		case TokenNamepublic :
+			return "public"; //$NON-NLS-1$
+		case TokenNamereturn :
+			return "return"; //$NON-NLS-1$
+		case TokenNameshort :
+			return "short"; //$NON-NLS-1$
+		case TokenNamestatic :
+			return "static"; //$NON-NLS-1$
+		case TokenNamesuper :
+			return "super"; //$NON-NLS-1$
+		case TokenNameswitch :
+			return "switch"; //$NON-NLS-1$
+		case TokenNamesynchronized :
+			return "synchronized"; //$NON-NLS-1$
+		case TokenNamethis :
+			return "this"; //$NON-NLS-1$
+		case TokenNamethrow :
+			return "throw"; //$NON-NLS-1$
+		case TokenNamethrows :
+			return "throws"; //$NON-NLS-1$
+		case TokenNametransient :
+			return "transient"; //$NON-NLS-1$
+		case TokenNametrue :
+			return "true"; //$NON-NLS-1$
+		case TokenNametry :
+			return "try"; //$NON-NLS-1$
+		case TokenNamevoid :
+			return "void"; //$NON-NLS-1$
+		case TokenNamevolatile :
+			return "volatile"; //$NON-NLS-1$
+		case TokenNamewhile :
+			return "while"; //$NON-NLS-1$
+
+		case TokenNameIntegerLiteral :
+			return "Integer(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameLongLiteral :
+			return "Long(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameFloatingPointLiteral :
+			return "Float(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameDoubleLiteral :
+			return "Double(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameCharacterLiteral :
+			return "Char(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameStringLiteral :
+			return "String(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+
+		case TokenNamePLUS_PLUS :
+			return "++"; //$NON-NLS-1$
+		case TokenNameMINUS_MINUS :
+			return "--"; //$NON-NLS-1$
+		case TokenNameEQUAL_EQUAL :
+			return "=="; //$NON-NLS-1$
+		case TokenNameLESS_EQUAL :
+			return "<="; //$NON-NLS-1$
+		case TokenNameGREATER_EQUAL :
+			return ">="; //$NON-NLS-1$
+		case TokenNameNOT_EQUAL :
+			return "!="; //$NON-NLS-1$
+		case TokenNameLEFT_SHIFT :
+			return "<<"; //$NON-NLS-1$
+		case TokenNameRIGHT_SHIFT :
+			return ">>"; //$NON-NLS-1$
+		case TokenNameUNSIGNED_RIGHT_SHIFT :
+			return ">>>"; //$NON-NLS-1$
+		case TokenNamePLUS_EQUAL :
+			return "+="; //$NON-NLS-1$
+		case TokenNameMINUS_EQUAL :
+			return "-="; //$NON-NLS-1$
+		case TokenNameARROW :
+			return "->"; //$NON-NLS-1$
+		case TokenNameMULTIPLY_EQUAL :
+			return "*="; //$NON-NLS-1$
+		case TokenNameDIVIDE_EQUAL :
+			return "/="; //$NON-NLS-1$
+		case TokenNameAND_EQUAL :
+			return "&="; //$NON-NLS-1$
+		case TokenNameOR_EQUAL :
+			return "|="; //$NON-NLS-1$
+		case TokenNameXOR_EQUAL :
+			return "^="; //$NON-NLS-1$
+		case TokenNameREMAINDER_EQUAL :
+			return "%="; //$NON-NLS-1$
+		case TokenNameLEFT_SHIFT_EQUAL :
+			return "<<="; //$NON-NLS-1$
+		case TokenNameRIGHT_SHIFT_EQUAL :
+			return ">>="; //$NON-NLS-1$
+		case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
+			return ">>>="; //$NON-NLS-1$
+		case TokenNameOR_OR :
+			return "||"; //$NON-NLS-1$
+		case TokenNameAND_AND :
+			return "&&"; //$NON-NLS-1$
+		case TokenNamePLUS :
+			return "+"; //$NON-NLS-1$
+		case TokenNameMINUS :
+			return "-"; //$NON-NLS-1$
+		case TokenNameNOT :
+			return "!"; //$NON-NLS-1$
+		case TokenNameREMAINDER :
+			return "%"; //$NON-NLS-1$
+		case TokenNameXOR :
+			return "^"; //$NON-NLS-1$
+		case TokenNameAND :
+			return "&"; //$NON-NLS-1$
+		case TokenNameMULTIPLY :
+			return "*"; //$NON-NLS-1$
+		case TokenNameOR :
+			return "|"; //$NON-NLS-1$
+		case TokenNameTWIDDLE :
+			return "~"; //$NON-NLS-1$
+		case TokenNameDIVIDE :
+			return "/"; //$NON-NLS-1$
+		case TokenNameGREATER :
+			return ">"; //$NON-NLS-1$
+		case TokenNameLESS :
+			return "<"; //$NON-NLS-1$
+		case TokenNameLPAREN :
+			return "("; //$NON-NLS-1$
+		case TokenNameRPAREN :
+			return ")"; //$NON-NLS-1$
+		case TokenNameLBRACE :
+			return "{"; //$NON-NLS-1$
+		case TokenNameRBRACE :
+			return "}"; //$NON-NLS-1$
+		case TokenNameLBRACKET :
+			return "["; //$NON-NLS-1$
+		case TokenNameRBRACKET :
+			return "]"; //$NON-NLS-1$
+		case TokenNameSEMICOLON :
+			return ";"; //$NON-NLS-1$
+		case TokenNameQUESTION :
+			return "?"; //$NON-NLS-1$
+		case TokenNameCOLON :
+			return ":"; //$NON-NLS-1$
+		case TokenNameCOLON_COLON :
+			return "::"; //$NON-NLS-1$
+		case TokenNameCOMMA :
+			return ","; //$NON-NLS-1$
+		case TokenNameDOT :
+			return "."; //$NON-NLS-1$
+		case TokenNameEQUAL :
+			return "="; //$NON-NLS-1$
+		case TokenNameEOF :
+			return "EOF"; //$NON-NLS-1$
+		case TokenNameWHITESPACE :
+			return "white_space(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		default :
+			return "not-a-token"; //$NON-NLS-1$
+	}
+}
+public void unicodeInitializeBuffer(int length) {
+	this.withoutUnicodePtr = length;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[length+(1+10)];
+	int bLength = this.withoutUnicodeBuffer.length;
+	if (1+length >= bLength) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length + (1+10)], 0, bLength);
+	}
+	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);
+}
+public void unicodeStore() {
+	int pos = ++this.withoutUnicodePtr;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+	int length = this.withoutUnicodeBuffer.length;
+	if (pos == length) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+	}
+	this.withoutUnicodeBuffer[pos] = this.currentCharacter;
+}
+public void unicodeStore(char character) {
+	int pos = ++this.withoutUnicodePtr;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+	int length = this.withoutUnicodeBuffer.length;
+	if (pos == length) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+	}
+	this.withoutUnicodeBuffer[pos] = character;
+}
+
+public static boolean isIdentifier(int token) {
+	return token == TerminalTokens.TokenNameIdentifier;
+}
+
+public static boolean isLiteral(int token) {
+	switch(token) {
+		case TerminalTokens.TokenNameIntegerLiteral:
+		case TerminalTokens.TokenNameLongLiteral:
+		case TerminalTokens.TokenNameFloatingPointLiteral:
+		case TerminalTokens.TokenNameDoubleLiteral:
+		case TerminalTokens.TokenNameStringLiteral:
+		case TerminalTokens.TokenNameCharacterLiteral:
+			return true;
+		default:
+			return false;
+	}
+}
+
+public static boolean isKeyword(int token) {
+	switch(token) {
+		case TerminalTokens.TokenNameabstract:
+		case TerminalTokens.TokenNameassert:
+		case TerminalTokens.TokenNamebyte:
+		case TerminalTokens.TokenNamebreak:
+		case TerminalTokens.TokenNameboolean:
+		case TerminalTokens.TokenNamecase:
+		case TerminalTokens.TokenNamechar:
+		case TerminalTokens.TokenNamecatch:
+		case TerminalTokens.TokenNameclass:
+		case TerminalTokens.TokenNamecontinue:
+		case TerminalTokens.TokenNamedo:
+		case TerminalTokens.TokenNamedouble:
+		case TerminalTokens.TokenNamedefault:
+		case TerminalTokens.TokenNameelse:
+		case TerminalTokens.TokenNameextends:
+		case TerminalTokens.TokenNamefor:
+		case TerminalTokens.TokenNamefinal:
+		case TerminalTokens.TokenNamefloat:
+		case TerminalTokens.TokenNamefalse:
+		case TerminalTokens.TokenNamefinally:
+		case TerminalTokens.TokenNameif:
+		case TerminalTokens.TokenNameint:
+		case TerminalTokens.TokenNameimport:
+		case TerminalTokens.TokenNameinterface:
+		case TerminalTokens.TokenNameimplements:
+		case TerminalTokens.TokenNameinstanceof:
+		case TerminalTokens.TokenNamelong:
+		case TerminalTokens.TokenNamenew:
+		case TerminalTokens.TokenNamenull:
+		case TerminalTokens.TokenNamenative:
+		case TerminalTokens.TokenNamepublic:
+		case TerminalTokens.TokenNamepackage:
+		case TerminalTokens.TokenNameprivate:
+		case TerminalTokens.TokenNameprotected:
+		case TerminalTokens.TokenNamereturn:
+		case TerminalTokens.TokenNameshort:
+		case TerminalTokens.TokenNamesuper:
+		case TerminalTokens.TokenNamestatic:
+		case TerminalTokens.TokenNameswitch:
+		case TerminalTokens.TokenNamestrictfp:
+		case TerminalTokens.TokenNamesynchronized:
+		case TerminalTokens.TokenNametry:
+		case TerminalTokens.TokenNamethis:
+		case TerminalTokens.TokenNametrue:
+		case TerminalTokens.TokenNamethrow:
+		case TerminalTokens.TokenNamethrows:
+		case TerminalTokens.TokenNametransient:
+		case TerminalTokens.TokenNamevoid:
+		case TerminalTokens.TokenNamevolatile:
+		case TerminalTokens.TokenNamewhile:
+			return true;
+		default:
+			return false;
+	}
+}
+
+// Vanguard Scanner - A Private utility helper class for the scanner.
+private static final class VanguardScanner extends Scanner {
+	
+	public VanguardScanner(long sourceLevel, long complianceLevel) {
+		super (false /*comment*/, false /*whitespace*/, false /*nls*/, sourceLevel, complianceLevel, null/*taskTag*/, null/*taskPriorities*/, false /*taskCaseSensitive*/);
+	}
+	
+	public int getNextToken() throws InvalidInputException {
+		int token = getNextToken0();
+		if (token == TokenNameAT && atTypeAnnotation()) {
+			token = TokenNameAT308;
+		}
+		return token == TokenNameEOF ? TokenNameNotAToken : token; 
+	}
+}
+
+private static final class Goal {
+	
+	int first;      // steer the parser towards a single minded pursuit.
+	int [] follow;  // the definite terminal symbols that signal the successful reduction to goal.
+	int rule;
+
+	static int LambdaParameterListRule = 0;
+	static int IntersectionCastRule = 0;
+	static int ReferenceExpressionRule = 0;
+	static int VarargTypeAnnotationsRule  = 0;
+	
+	static Goal LambdaParameterListGoal;
+	static Goal IntersectionCastGoal;
+	static Goal VarargTypeAnnotationGoal;
+	static Goal ReferenceExpressionGoal;
+	
+	static {
+		
+		for (int i = 1; i <= ParserBasicInformation.NUM_RULES; i++) {  // 0 == $acc
+			if ("ParenthesizedLambdaParameterList".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
+				LambdaParameterListRule = i;
+			else 
+			if ("ParenthesizedCastNameAndBounds".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
+				IntersectionCastRule = i;
+			else 
+			if ("ReferenceExpressionTypeArgumentsAndTrunk".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
+				ReferenceExpressionRule = i;
+			else 
+			if ("TypeAnnotations".equals(Parser.name[Parser.non_terminal_index[Parser.lhs[i]]])) //$NON-NLS-1$
+				VarargTypeAnnotationsRule = i;
+		}
+		
+		LambdaParameterListGoal =  new Goal(TokenNameARROW, new int[] { TokenNameARROW }, LambdaParameterListRule);
+		IntersectionCastGoal =     new Goal(TokenNameLPAREN, followSetOfCast(), IntersectionCastRule);
+		VarargTypeAnnotationGoal = new Goal(TokenNameAT, new int[] { TokenNameELLIPSIS }, VarargTypeAnnotationsRule);
+		ReferenceExpressionGoal =  new Goal(TokenNameLESS, new int[] { TokenNameCOLON_COLON }, ReferenceExpressionRule);
+	}
+
+
+	Goal(int first, int [] follow, int rule) {
+		this.first = first;
+		this.follow = follow;
+		this.rule = rule;
+	}
+	
+	boolean hasBeenReached(int act, int token) {
+		/*
+		System.out.println("[Goal = " + Parser.name[Parser.non_terminal_index[Parser.lhs[this.rule]]] + "]  " + "Saw: " + Parser.name[Parser.non_terminal_index[Parser.lhs[act]]] + "::" +  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+				Parser.name[Parser.terminal_index[token]]);
+		*/
+		if (act == this.rule) {
+			for (int i = 0, length = this.follow.length; i < length; i++)
+				if (this.follow[i] == token)
+					return true;
+		}
+		return false;
+	}
+	
+	private static int [] followSetOfCast() {
+		return new int [] { TokenNameIdentifier, TokenNamenew, TokenNamesuper, TokenNamethis,
+				TokenNamefalse, TokenNametrue, TokenNamenull, 
+				TokenNameIntegerLiteral, TokenNameLongLiteral, TokenNameFloatingPointLiteral, TokenNameDoubleLiteral, TokenNameCharacterLiteral, TokenNameStringLiteral, 
+				TokenNameNOT, TokenNameTWIDDLE, TokenNameLPAREN
+		};
+	}
+}
+// Vanguard Parser - A Private utility helper class for the scanner.
+private static final class VanguardParser extends Parser {
+	
+	public static final boolean SUCCESS = true;
+	public static final boolean FAILURE = false;
+	
+	public VanguardParser(VanguardScanner scanner) {
+		this.scanner = scanner;
+	}
+	
+	// Canonical LALR pushdown automaton identical to Parser.parse() minus side effects of any kind, returns the rule reduced.
+	protected boolean parse(Goal goal) {
+		try {
+			int act = START_STATE;
+			this.stateStackTop = -1;
+			this.currentToken = goal.first; 
+			ProcessTerminals : for (;;) {
+				int stackLength = this.stack.length;
+				if (++this.stateStackTop >= stackLength) {
+					System.arraycopy(
+						this.stack, 0,
+						this.stack = new int[stackLength + StackIncrement], 0,
+						stackLength);
+				}
+				this.stack[this.stateStackTop] = act;
+
+				act = Parser.tAction(act, this.currentToken);
+				if (act == ERROR_ACTION) {
+					return FAILURE;
+				}
+				if (act <= NUM_RULES) {
+					this.stateStackTop--;
+				} else if (act > ERROR_ACTION) { /* shift-reduce */
+					this.unstackedAct = act;
+					try {
+						this.currentToken = this.scanner.getNextToken();
+					} finally {
+						this.unstackedAct = ERROR_ACTION;
+					}
+					act -= ERROR_ACTION;
+				} else {
+				    if (act < ACCEPT_ACTION) { /* shift */
+				    	this.unstackedAct = act;
+						try {
+							this.currentToken = this.scanner.getNextToken();
+						} finally {
+							this.unstackedAct = ERROR_ACTION;
+						}
+						continue ProcessTerminals;
+					}
+				    return FAILURE; // accept - we should never reach this state, we accept at reduce with a right member of follow set below.
+				}
+
+				// ProcessNonTerminals :
+				do { /* reduce */
+					if (goal.hasBeenReached(act, this.currentToken))
+						return SUCCESS;
+					this.stateStackTop -= (Parser.rhs[act] - 1);
+					act = Parser.ntAction(this.stack[this.stateStackTop], Parser.lhs[act]);
+				} while (act <= NUM_RULES);
+			}
+		} catch (Exception e) {
+			return FAILURE;
+		}
+	}
+	public String toString() {
+		return "\n\n\n----------------Scanner--------------\n" + this.scanner.toString(); //$NON-NLS-1$;
+	}
+}
+
+private VanguardParser getVanguardParser() {
+	if (this.vanguardParser == null) {
+		this.vanguardScanner = new VanguardScanner(this.sourceLevel, this.complianceLevel);
+		this.vanguardParser = new VanguardParser(this.vanguardScanner);
+		this.vanguardScanner.setActiveParser(this.vanguardParser);
+	}
+	this.vanguardScanner.setSource(this.source);
+	this.vanguardScanner.resetTo(this.startPosition, this.eofPosition - 1);
+	return this.vanguardParser;
+}
+
+protected final boolean maybeAtLambdaOrCast() { // Could the '(' we saw just now herald a lambda parameter list or a cast expression ? (the possible locations for both are identical.)
+
+	switch (this.lookBack[1]) {
+		case TokenNameIdentifier:
+		case TokenNamecatch:
+		case TokenNamethis:
+		case TokenNamesuper:
+		case TokenNameif:
+		case TokenNameswitch:
+		case TokenNamewhile:
+		case TokenNamefor:
+		case TokenNamesynchronized:
+		case TokenNametry:
+			return false; // not a viable prefix for cast or lambda.
+		default:
+			return this.activeParser.atConflictScenario(TokenNameLPAREN);
+	}
+}
+		
+
+protected final boolean maybeAtReferenceExpression() { // Did the '<' we saw just now herald a reference expression's type arguments and trunk ?
+	switch (this.lookBack[1]) {
+		case TokenNameIdentifier:
+			switch (this.lookBack[0]) {
+				case TokenNameSEMICOLON:  // for (int i = 0; i < 10; i++);
+				case TokenNameRBRACE:     // class X { void foo() {} X<String> x = null; }
+				case TokenNameclass:      // class X<T> {}
+				case TokenNameinterface:  // interface I<T> {}
+				case TokenNameenum:       // enum E<T> {}
+				case TokenNamefinal:      // final Collection<String>
+				case TokenNameLESS:       // Collection<IScalarData<AbstractData>>
+				case TokenNameGREATER:    // public <T> List<T> foo() { /* */ }
+				case TokenNameRIGHT_SHIFT:// static <T extends SelfType<T>> List<T> makeSingletonList(T t) { /* */ }
+				case TokenNamenew:        // new ArrayList<String>();
+				case TokenNamepublic:     // public List<String> foo() {}
+				case TokenNameabstract:   // abstract List<String> foo() {}
+				case TokenNameprivate:    // private List<String> foo() {}
+				case TokenNameprotected:  // protected List<String> foo() {}
+				case TokenNamestatic:     // public static List<String> foo() {}
+				case TokenNameextends:    // <T extends Y<Z>>
+				case TokenNamesuper:      // ? super Context<N>
+				case TokenNameAND:        // T extends Object & Comparable<? super T>
+				case TokenNameimplements: // class A implements I<Z>
+				case TokenNamethrows:     // throws Y<Z>
+				case TokenNameAT:         // @Deprecated <T> void foo() {} 
+				case TokenNameinstanceof: // if (o instanceof List<E>[])  
+					return false;
+				default:
+					break;
+			}
+			break;
+		case TokenNameNotAToken: // Not kosher, don't touch.
+			break;
+		default:
+			return false;
+	}
+	return this.activeParser.atConflictScenario(TokenNameLESS);
+}
+protected final boolean maybeAtEllipsisAnnotation() { // Did the '@' we saw just now herald a type annotation on a ... ? Presumed to be at type annotation already.
+	switch (this.lookBack[1]) {
+		case TokenNamenew:
+		case TokenNameCOMMA:
+		case TokenNameextends:
+		case TokenNamesuper:
+		case TokenNameimplements:
+		case TokenNameDOT:
+		case TokenNameLBRACE:
+		case TokenNameinstanceof:
+		case TokenNameLESS:
+		case TokenNameAND:
+		case TokenNamethrows:
+			return false;
+		default:
+			return true;
+	}
+}
+protected final boolean atTypeAnnotation() { // Did the '@' we saw just now herald a type annotation ? We should not ask the parser whether it would shift @308 !
+	return !this.activeParser.atConflictScenario(TokenNameAT);
+}
+
+public void setActiveParser(ConflictedParser parser) {
+	this.activeParser  = parser;
+	this.lookBack[0] = this.lookBack[1] = TokenNameNotAToken;  // no hand me downs please.
+}
+private int disambiguatedToken(int token) {
+	final VanguardParser parser = getVanguardParser();
+	if (token == TokenNameLPAREN  && maybeAtLambdaOrCast()) {
+		if (parser.parse(Goal.LambdaParameterListGoal) == VanguardParser.SUCCESS) {
+			this.nextToken = TokenNameLPAREN;
+			return TokenNameBeginLambda;
+		}
+		this.vanguardScanner.resetTo(this.startPosition, this.eofPosition - 1);
+		if (parser.parse(Goal.IntersectionCastGoal) == VanguardParser.SUCCESS) {
+			this.nextToken = TokenNameLPAREN;
+			return TokenNameBeginIntersectionCast;
+		}
+	} else if (token == TokenNameLESS && maybeAtReferenceExpression()) {
+		if (parser.parse(Goal.ReferenceExpressionGoal) == VanguardParser.SUCCESS) {
+			this.nextToken = TokenNameLESS;
+			return TokenNameBeginTypeArguments;
+		}
+	} else if (token == TokenNameAT && atTypeAnnotation()) {
+		token = TokenNameAT308;
+		if (maybeAtEllipsisAnnotation()) {
+			if (parser.parse(Goal.VarargTypeAnnotationGoal) == VanguardParser.SUCCESS) {
+				this.nextToken = TokenNameAT308;
+				return TokenNameAT308DOTDOTDOT;
+			}
+		}
+	}
+	return token;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
new file mode 100644
index 0000000..4ee486e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
@@ -0,0 +1,577 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     David Foerster - patch for toUpperCase as described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=153125
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class ScannerHelper {
+
+	public final static long[] Bits = {
+		ASTNode.Bit1, ASTNode.Bit2, ASTNode.Bit3, ASTNode.Bit4, ASTNode.Bit5, ASTNode.Bit6,
+		ASTNode.Bit7, ASTNode.Bit8, ASTNode.Bit9, ASTNode.Bit10, ASTNode.Bit11, ASTNode.Bit12,
+		ASTNode.Bit13, ASTNode.Bit14, ASTNode.Bit15, ASTNode.Bit16, ASTNode.Bit17, ASTNode.Bit18,
+		ASTNode.Bit19, ASTNode.Bit20, ASTNode.Bit21, ASTNode.Bit22, ASTNode.Bit23, ASTNode.Bit24,
+		ASTNode.Bit25, ASTNode.Bit26, ASTNode.Bit27, ASTNode.Bit28, ASTNode.Bit29, ASTNode.Bit30,
+		ASTNode.Bit31, ASTNode.Bit32, ASTNode.Bit33L, ASTNode.Bit34L, ASTNode.Bit35L, ASTNode.Bit36L,
+		ASTNode.Bit37L, ASTNode.Bit38L, ASTNode.Bit39L, ASTNode.Bit40L, ASTNode.Bit41L, ASTNode.Bit42L,
+		ASTNode.Bit43L, ASTNode.Bit44L, ASTNode.Bit45L, ASTNode.Bit46L, ASTNode.Bit47L, ASTNode.Bit48L,
+		ASTNode.Bit49L, ASTNode.Bit50L, ASTNode.Bit51L, ASTNode.Bit52L, ASTNode.Bit53L, ASTNode.Bit54L,
+		ASTNode.Bit55L, ASTNode.Bit56L, ASTNode.Bit57L, ASTNode.Bit58L, ASTNode.Bit59L, ASTNode.Bit60L,
+		ASTNode.Bit61L, ASTNode.Bit62L, ASTNode.Bit63L, ASTNode.Bit64L,
+	};
+
+	private static final int START_INDEX = 0;
+	private static final int PART_INDEX = 1;
+
+	private static long[][][] Tables;
+	private static long[][][] Tables7;
+
+	public final static int MAX_OBVIOUS = 128;
+	public final static int[] OBVIOUS_IDENT_CHAR_NATURES = new int[MAX_OBVIOUS];
+
+	public final static int C_JLS_SPACE = ASTNode.Bit9;
+	public final static int C_SPECIAL = ASTNode.Bit8;
+	public final static int C_IDENT_START = ASTNode.Bit7;
+	public final static int C_UPPER_LETTER = ASTNode.Bit6;
+	public final static int C_LOWER_LETTER = ASTNode.Bit5;
+	public final static int C_IDENT_PART = ASTNode.Bit4;
+	public final static int C_DIGIT = ASTNode.Bit3;
+	public final static int C_SEPARATOR = ASTNode.Bit2;
+	public final static int C_SPACE = ASTNode.Bit1;
+
+	static {
+		OBVIOUS_IDENT_CHAR_NATURES[0] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[1] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[2] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[3] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[4] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[5] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[6] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[7] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[8] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[14] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[15] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[16] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[17] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[18] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[19] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[20] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[21] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[22] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[23] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[24] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[25] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[26] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[27] = C_IDENT_PART;
+		OBVIOUS_IDENT_CHAR_NATURES[127] = C_IDENT_PART;
+
+		for (int i = '0'; i <= '9'; i++)
+			OBVIOUS_IDENT_CHAR_NATURES[i] = C_DIGIT | C_IDENT_PART;
+
+		for (int i = 'a'; i <= 'z'; i++)
+			OBVIOUS_IDENT_CHAR_NATURES[i] = C_LOWER_LETTER | C_IDENT_PART | C_IDENT_START;
+		for (int i = 'A'; i <= 'Z'; i++)
+			OBVIOUS_IDENT_CHAR_NATURES[i] = C_UPPER_LETTER | C_IDENT_PART | C_IDENT_START;
+
+		OBVIOUS_IDENT_CHAR_NATURES['_'] = C_SPECIAL | C_IDENT_PART | C_IDENT_START;
+		OBVIOUS_IDENT_CHAR_NATURES['$'] = C_SPECIAL | C_IDENT_PART | C_IDENT_START;
+
+		OBVIOUS_IDENT_CHAR_NATURES[9] = C_SPACE | C_JLS_SPACE; // \ u0009: HORIZONTAL TABULATION
+		OBVIOUS_IDENT_CHAR_NATURES[10] = C_SPACE | C_JLS_SPACE; // \ u000a: LINE FEED
+		OBVIOUS_IDENT_CHAR_NATURES[11] = C_SPACE;
+		OBVIOUS_IDENT_CHAR_NATURES[12] = C_SPACE | C_JLS_SPACE; // \ u000c: FORM FEED
+		OBVIOUS_IDENT_CHAR_NATURES[13] = C_SPACE | C_JLS_SPACE; //  \ u000d: CARRIAGE RETURN
+		OBVIOUS_IDENT_CHAR_NATURES[28] = C_SPACE;
+		OBVIOUS_IDENT_CHAR_NATURES[29] = C_SPACE;
+		OBVIOUS_IDENT_CHAR_NATURES[30] = C_SPACE;
+		OBVIOUS_IDENT_CHAR_NATURES[31] = C_SPACE;
+		OBVIOUS_IDENT_CHAR_NATURES[32] = C_SPACE | C_JLS_SPACE; //  \ u0020: SPACE
+
+		OBVIOUS_IDENT_CHAR_NATURES['.'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES[':'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES[';'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES[','] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['['] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES[']'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['('] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES[')'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['{'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['}'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['+'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['-'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['*'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['/'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['='] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['&'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['|'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['?'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['<'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['>'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['!'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['%'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['^'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['~'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['"'] = C_SEPARATOR;
+		OBVIOUS_IDENT_CHAR_NATURES['\''] = C_SEPARATOR;
+	}
+
+static void initializeTable() {
+	Tables = new long[2][][];
+	Tables[START_INDEX] = new long[3][];
+	Tables[PART_INDEX] = new long[4][];
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/start0.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[START_INDEX][0] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/start1.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[START_INDEX][1] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/start2.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[START_INDEX][2] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/part0.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[PART_INDEX][0] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/part1.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[PART_INDEX][1] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/part2.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[PART_INDEX][2] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode/part14.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables[PART_INDEX][3] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+}
+static void initializeTable17() {
+	Tables7 = new long[2][][];
+	Tables7[START_INDEX] = new long[3][];
+	Tables7[PART_INDEX] = new long[4][];
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/start0.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[START_INDEX][0] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/start1.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[START_INDEX][1] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/start2.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[START_INDEX][2] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/part0.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[PART_INDEX][0] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/part1.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[PART_INDEX][1] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/part2.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[PART_INDEX][2] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+	try {
+		DataInputStream inputStream = new DataInputStream(new BufferedInputStream(ScannerHelper.class.getResourceAsStream("unicode6/part14.rsc"))); //$NON-NLS-1$
+		long[] readValues = new long[1024];
+		for (int i = 0; i < 1024; i++) {
+			readValues[i] = inputStream.readLong();
+		}
+		inputStream.close();
+		Tables7[PART_INDEX][3] = readValues;
+	} catch (FileNotFoundException e) {
+		e.printStackTrace();
+	} catch (IOException e) {
+		e.printStackTrace();
+	}
+}
+private final static boolean isBitSet(long[] values, int i) {
+	try {
+		return (values[i / 64] & Bits[i % 64]) != 0;
+	} catch (NullPointerException e) {
+		return false;
+	}
+}
+public static boolean isJavaIdentifierPart(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_PART) != 0;
+	}
+	return Character.isJavaIdentifierPart(c);
+}
+public static boolean isJavaIdentifierPart(long complianceLevel, char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_PART) != 0;
+	}
+	return isJavaIdentifierPart(complianceLevel, (int) c);
+}
+public static boolean isJavaIdentifierPart(long complianceLevel, int codePoint) {
+	if (complianceLevel <= ClassFileConstants.JDK1_6) {
+		if (Tables == null) {
+			initializeTable();
+		}
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return isBitSet(Tables[PART_INDEX][0], codePoint & 0xFFFF);
+			case 1 :
+				return isBitSet(Tables[PART_INDEX][1], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables[PART_INDEX][2], codePoint & 0xFFFF);
+			case 14 :
+				return isBitSet(Tables[PART_INDEX][3], codePoint & 0xFFFF);
+		}
+	} else {
+		// java 7 supports Unicode 6
+		if (Tables7 == null) {
+			initializeTable17();
+		}
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return isBitSet(Tables7[PART_INDEX][0], codePoint & 0xFFFF);
+			case 1 :
+				return isBitSet(Tables7[PART_INDEX][1], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables7[PART_INDEX][2], codePoint & 0xFFFF);
+			case 14 :
+				return isBitSet(Tables7[PART_INDEX][3], codePoint & 0xFFFF);
+		}
+	}
+	return false;
+}
+public static boolean isJavaIdentifierPart(long complianceLevel, char high, char low) {
+	return isJavaIdentifierPart(complianceLevel, toCodePoint(high, low));
+}
+public static boolean isJavaIdentifierStart(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0;
+	}
+	return Character.isJavaIdentifierStart(c);
+}
+public static boolean isJavaIdentifierStart(long complianceLevel, char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0;
+	}
+	return ScannerHelper.isJavaIdentifierStart(complianceLevel, (int) c);
+}
+public static boolean isJavaIdentifierStart(long complianceLevel, char high, char low) {
+	return isJavaIdentifierStart(complianceLevel, toCodePoint(high, low));
+}
+public static boolean isJavaIdentifierStart(long complianceLevel, int codePoint) {
+	if (complianceLevel <= ClassFileConstants.JDK1_6) {
+		if (Tables == null) {
+			initializeTable();
+		}
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return isBitSet(Tables[START_INDEX][0], codePoint & 0xFFFF);
+			case 1 :
+				return isBitSet(Tables[START_INDEX][1], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables[START_INDEX][2], codePoint & 0xFFFF);
+		}
+	} else {
+		// java 7 supports Unicode 6
+		if (Tables7 == null) {
+			initializeTable17();
+		}
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return isBitSet(Tables7[START_INDEX][0], codePoint & 0xFFFF);
+			case 1 :
+				return isBitSet(Tables7[START_INDEX][1], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables7[START_INDEX][2], codePoint & 0xFFFF);
+		}
+	}
+	return false;
+}
+private static int toCodePoint(char high, char low) {
+	return (high - Scanner.HIGH_SURROGATE_MIN_VALUE) * 0x400 + (low - Scanner.LOW_SURROGATE_MIN_VALUE) + 0x10000;
+}
+public static boolean isDigit(char c) throws InvalidInputException {
+	if(c < ScannerHelper.MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0;
+	}
+	if (Character.isDigit(c)) {
+		throw new InvalidInputException(Scanner.INVALID_DIGIT);
+	}
+	return false;
+}
+public static int digit(char c, int radix) {
+	if (c < ScannerHelper.MAX_OBVIOUS) {
+		switch(radix) {
+			case 8 :
+				if (c >= 48 && c <= 55) {
+					return c - 48;
+				}
+				return -1;
+			case 10 :
+				if (c >= 48 && c <= 57) {
+					return c - 48;
+				}
+				return -1;
+			case 16 :
+				if (c >= 48 && c <= 57) {
+					return c - 48;
+				}
+				if (c >= 65 && c <= 70) {
+					return c - 65 + 10;
+				}
+				if (c >= 97 && c <= 102) {
+					return c - 97 + 10;
+				}
+				return -1;
+		}
+	}
+	return Character.digit(c, radix);
+}
+public static int getNumericValue(char c) {
+	if (c < ScannerHelper.MAX_OBVIOUS) {
+		switch(ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c]) {
+			case C_DIGIT :
+				return c - '0';
+			case C_LOWER_LETTER :
+				return 10 + c - 'a';
+			case C_UPPER_LETTER :
+				return 10 + c - 'A';
+		}
+	}
+	return Character.getNumericValue(c);
+}
+public static int getHexadecimalValue(char c) {
+	switch(c) {
+		case '0' :
+			return 0;
+		case '1' :
+			return 1;
+		case '2' :
+			return 2;
+		case '3' :
+			return 3;
+		case '4' :
+			return 4;
+		case '5' :
+			return 5;
+		case '6' :
+			return 6;
+		case '7' :
+			return 7;
+		case '8' :
+			return 8;
+		case '9' :
+			return 9;
+		case 'A' :
+		case 'a' :
+			return 10;
+		case 'B' :
+		case 'b' :
+			return 11;
+		case 'C' :
+		case 'c' :
+			return 12;
+		case 'D' :
+		case 'd' :
+			return 13;
+		case 'E' :
+		case 'e' :
+			return 14;
+		case 'F' :
+		case 'f' :
+			return 15;
+		default:
+			return -1;
+	}
+}
+public static char toUpperCase(char c) {
+	if (c < MAX_OBVIOUS) {
+		if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0) {
+			return c;
+		} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0) {
+			return (char) (c - 32);
+		}
+	}
+	return Character.toUpperCase(c);
+}
+public static char toLowerCase(char c) {
+	if (c < MAX_OBVIOUS) {
+		if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0) {
+			return c;
+		} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0) {
+			return (char) (32 + c);
+		}
+	}
+	return Character.toLowerCase(c);
+}
+public static boolean isLowerCase(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_LOWER_LETTER) != 0;
+	}
+	return Character.isLowerCase(c);
+}
+public static boolean isUpperCase(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_UPPER_LETTER) != 0;
+	}
+	return Character.isUpperCase(c);
+}
+/**
+ * Include also non JLS whitespaces.
+ *
+ * return true if Character.isWhitespace(c) would return true
+ */
+public static boolean isWhitespace(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_SPACE) != 0;
+	}
+	return Character.isWhitespace(c);
+}
+public static boolean isLetter(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER)) != 0;
+	}
+	return Character.isLetter(c);
+}
+public static boolean isLetterOrDigit(char c) {
+	if (c < MAX_OBVIOUS) {
+		return (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_DIGIT)) != 0;
+	}
+	return Character.isLetterOrDigit(c);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
new file mode 100644
index 0000000..456e94d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * IMPORTANT NOTE: These constants are dedicated to the internal Scanner implementation.
+ * It is mirrored in org.eclipse.jdt.core.compiler public package where it is API.
+ * The mirror implementation is using the backward compatible ITerminalSymbols constant
+ * definitions (stable with 2.0), whereas the internal implementation uses TerminalTokens
+ * which constant values reflect the latest parser generation state.
+ */
+/**
+ * Maps each terminal symbol in the java-grammar into a unique integer.
+ * This integer is used to represent the terminal when computing a parsing action.
+ *
+ * Disclaimer : These constant values are generated automatically using a Java
+ * grammar, therefore their actual values are subject to change if new keywords
+ * were added to the language (for instance, 'assert' is a keyword in 1.4).
+ */
+public interface TerminalTokens {
+
+	// special tokens not part of grammar - not autogenerated
+	int TokenNameNotAToken = 0,
+		TokenNameWHITESPACE = 1000,
+		TokenNameCOMMENT_LINE = 1001,
+		TokenNameCOMMENT_BLOCK = 1002,
+		TokenNameCOMMENT_JAVADOC = 1003;
+
+	int TokenNameIdentifier = 22,
+      TokenNameabstract = 51,
+      TokenNameassert = 72,
+      TokenNameboolean = 97,
+      TokenNamebreak = 73,
+      TokenNamebyte = 98,
+      TokenNamecase = 99,
+      TokenNamecatch = 100,
+      TokenNamechar = 101,
+      TokenNameclass = 67,
+      TokenNamecontinue = 74,
+      TokenNameconst = 116,
+      TokenNamedefault = 75,
+      TokenNamedo = 76,
+      TokenNamedouble = 102,
+      TokenNameelse = 111,
+      TokenNameenum = 69,
+      TokenNameextends = 96,
+      TokenNamefalse = 38,
+      TokenNamefinal = 52,
+      TokenNamefinally = 109,
+      TokenNamefloat = 103,
+      TokenNamefor = 77,
+      TokenNamegoto = 117,
+      TokenNameif = 78,
+      TokenNameimplements = 114,
+      TokenNameimport = 104,
+      TokenNameinstanceof = 17,
+      TokenNameint = 105,
+      TokenNameinterface = 68,
+      TokenNamelong = 106,
+      TokenNamenative = 53,
+      TokenNamenew = 36,
+      TokenNamenull = 39,
+      TokenNamepackage = 95,
+      TokenNameprivate = 54,
+      TokenNameprotected = 55,
+      TokenNamepublic = 56,
+      TokenNamereturn = 79,
+      TokenNameshort = 107,
+      TokenNamestatic = 40,
+      TokenNamestrictfp = 57,
+      TokenNamesuper = 34,
+      TokenNameswitch = 80,
+      TokenNamesynchronized = 41,
+      TokenNamethis = 35,
+      TokenNamethrow = 81,
+      TokenNamethrows = 112,
+      TokenNametransient = 58,
+      TokenNametrue = 42,
+      TokenNametry = 82,
+      TokenNamevoid = 108,
+      TokenNamevolatile = 59,
+      TokenNamewhile = 71,
+      TokenNameIntegerLiteral = 43,
+      TokenNameLongLiteral = 44,
+      TokenNameFloatingPointLiteral = 45,
+      TokenNameDoubleLiteral = 46,
+      TokenNameCharacterLiteral = 47,
+      TokenNameStringLiteral = 48,
+      TokenNamePLUS_PLUS = 1,
+      TokenNameMINUS_MINUS = 2,
+      TokenNameEQUAL_EQUAL = 19,
+      TokenNameLESS_EQUAL = 12,
+      TokenNameGREATER_EQUAL = 13,
+      TokenNameNOT_EQUAL = 20,
+      TokenNameLEFT_SHIFT = 18,
+      TokenNameRIGHT_SHIFT = 14,
+      TokenNameUNSIGNED_RIGHT_SHIFT = 16,
+      TokenNamePLUS_EQUAL = 84,
+      TokenNameMINUS_EQUAL = 85,
+      TokenNameMULTIPLY_EQUAL = 86,
+      TokenNameDIVIDE_EQUAL = 87,
+      TokenNameAND_EQUAL = 88,
+      TokenNameOR_EQUAL = 89,
+      TokenNameXOR_EQUAL = 90,
+      TokenNameREMAINDER_EQUAL = 91,
+      TokenNameLEFT_SHIFT_EQUAL = 92,
+      TokenNameRIGHT_SHIFT_EQUAL = 93,
+      TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 94,
+      TokenNameOR_OR = 31,
+      TokenNameAND_AND = 30,
+      TokenNamePLUS = 4,
+      TokenNameMINUS = 5,
+      TokenNameNOT = 62,
+      TokenNameREMAINDER = 7,
+      TokenNameXOR = 23,
+      TokenNameAND = 21,
+      TokenNameMULTIPLY = 6,
+      TokenNameOR = 25,
+      TokenNameTWIDDLE = 63,
+      TokenNameDIVIDE = 8,
+      TokenNameGREATER = 15,
+      TokenNameLESS = 11,
+      TokenNameLPAREN = 24,
+      TokenNameRPAREN = 26,
+      TokenNameLBRACE = 49,
+      TokenNameRBRACE = 32,
+      TokenNameLBRACKET = 10,
+      TokenNameRBRACKET = 64,
+      TokenNameSEMICOLON = 28,
+      TokenNameQUESTION = 29,
+      TokenNameCOLON = 61,
+      TokenNameCOMMA = 33,
+      TokenNameDOT = 3,
+      TokenNameEQUAL = 70,
+      TokenNameAT = 37,
+      TokenNameELLIPSIS = 113,
+      TokenNameARROW = 110,
+      TokenNameCOLON_COLON = 9,
+      TokenNameBeginLambda = 50,
+      TokenNameBeginIntersectionCast = 65,
+      TokenNameBeginTypeArguments = 83,
+      TokenNameElidedSemicolonAndRightBrace = 66,
+      TokenNameAT308 = 27,
+      TokenNameAT308DOTDOTDOT = 115,
+      TokenNameEOF = 60,
+      TokenNameERROR = 118;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
new file mode 100644
index 0000000..5fddbf7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
@@ -0,0 +1,2591 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser.diagnose;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.ConflictedParser;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class DiagnoseParser implements ParserBasicInformation, TerminalTokens, ConflictedParser {
+	private static final boolean DEBUG = false;
+	private boolean DEBUG_PARSECHECK = false;
+
+	private static final int STACK_INCREMENT = 256;
+
+//	private static final int ERROR_CODE = 1;
+	private static final int BEFORE_CODE = 2;
+	private static final int INSERTION_CODE = 3;
+	private static final int INVALID_CODE = 4;
+	private static final int SUBSTITUTION_CODE = 5;
+	private static final int DELETION_CODE = 6;
+	private static final int MERGE_CODE = 7;
+	private static final int MISPLACED_CODE = 8;
+	private static final int SCOPE_CODE = 9;
+	private static final int SECONDARY_CODE = 10;
+	private static final int EOF_CODE = 11;
+
+	private static final int BUFF_UBOUND  = 31;
+	private static final int BUFF_SIZE    = 32;
+	private static final int MAX_DISTANCE = 30;
+	private static final int MIN_DISTANCE = 3;
+
+	private CompilerOptions options;
+
+	private LexStream lexStream;
+	private int errorToken;
+	private int errorTokenStart;
+
+	private int currentToken = 0;
+
+	private int stackLength;
+	private int stateStackTop;
+	private int[] stack;
+
+	private int[] locationStack;
+	private int[] locationStartStack;
+
+	private int tempStackTop;
+	private int[] tempStack;
+
+	private int prevStackTop;
+	private int[] prevStack;
+	private int nextStackTop;
+	private int[] nextStack;
+
+	private int scopeStackTop;
+    private int[] scopeIndex;
+    private int[] scopePosition;
+
+	int[] list = new int[NUM_SYMBOLS + 1];
+	int[] buffer = new int[BUFF_SIZE];
+
+	private static final int NIL = -1;
+	int[] stateSeen;
+
+	int statePoolTop;
+	StateInfo[] statePool;
+
+	private Parser parser;
+
+	private RecoveryScanner recoveryScanner;
+
+	private boolean reportProblem;
+
+	private static class RepairCandidate {
+		public int symbol;
+		public int location;
+
+		public RepairCandidate(){
+			this.symbol = 0;
+			this.location = 0;
+		}
+	}
+
+	private static class PrimaryRepairInfo {
+		public int distance;
+		public int misspellIndex;
+		public int code;
+		public int bufferPosition;
+		public int symbol;
+
+		public PrimaryRepairInfo(){
+			this.distance = 0;
+			this.misspellIndex = 0;
+			this.code = 0;
+			this.bufferPosition = 0;
+			this.symbol = 0;
+		}
+
+		public PrimaryRepairInfo copy(){
+			PrimaryRepairInfo c = new PrimaryRepairInfo();
+			c.distance = this.distance;
+			c.misspellIndex = this.misspellIndex;
+			c.code = this.code;
+			c.bufferPosition = this .bufferPosition;
+			c.symbol = this.symbol;
+			return c;
+
+		}
+	}
+
+	static class SecondaryRepairInfo {
+		public int code;
+		public int distance;
+		public int bufferPosition;
+		public int stackPosition;
+		public int numDeletions;
+		public int symbol;
+
+		boolean recoveryOnNextStack;
+	}
+
+	private static class StateInfo {
+	    int state;
+	    int next;
+
+	    public StateInfo(int state, int next){
+	    	this.state = state;
+	    	this.next = next;
+	    }
+	}
+
+	public DiagnoseParser(Parser parser, int firstToken, int start, int end, CompilerOptions options) {
+		this(parser, firstToken, start, end, Util.EMPTY_INT_ARRAY, Util.EMPTY_INT_ARRAY, Util.EMPTY_INT_ARRAY, options);
+	}
+
+	public DiagnoseParser(Parser parser, int firstToken, int start, int end, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, CompilerOptions options) {
+		this.parser = parser;
+		this.options = options;
+		this.lexStream = new LexStream(BUFF_SIZE, parser.scanner, intervalStartToSkip, intervalEndToSkip, intervalFlagsToSkip, firstToken, start, end);
+		this.recoveryScanner = parser.recoveryScanner;
+	}
+
+	private ProblemReporter problemReporter(){
+		return this.parser.problemReporter();
+	}
+
+	private void reallocateStacks()	{
+		int old_stack_length = this.stackLength;
+
+		this.stackLength += STACK_INCREMENT;
+
+		if(old_stack_length == 0){
+			this.stack = new int[this.stackLength];
+			this.locationStack = new int[this.stackLength];
+			this.locationStartStack = new int[this.stackLength];
+			this.tempStack = new int[this.stackLength];
+			this.prevStack = new int[this.stackLength];
+			this.nextStack = new int[this.stackLength];
+			this.scopeIndex = new int[this.stackLength];
+			this.scopePosition = new int[this.stackLength];
+		} else {
+			System.arraycopy(this.stack, 0, this.stack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.locationStack, 0, this.locationStack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.locationStartStack, 0, this.locationStartStack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.tempStack, 0, this.tempStack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.prevStack, 0, this.prevStack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.nextStack, 0, this.nextStack = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.scopeIndex, 0, this.scopeIndex = new int[this.stackLength], 0, old_stack_length);
+			System.arraycopy(this.scopePosition, 0, this.scopePosition = new int[this.stackLength], 0, old_stack_length);
+		}
+		return;
+	}
+
+
+	public void diagnoseParse(boolean record) {
+		this.reportProblem = true;
+		boolean oldRecord = false;
+		if(this.recoveryScanner != null) {
+			oldRecord = this.recoveryScanner.record;
+			this.recoveryScanner.record = record;
+		}
+		this.parser.scanner.setActiveParser(this);
+		try {
+			this.lexStream.reset();
+
+			this.currentToken = this.lexStream.getToken();
+
+			int prev_pos;
+			int pos;
+			int next_pos;
+			int act = START_STATE;
+
+			reallocateStacks();
+
+			//
+			// Start parsing
+			//
+			this.stateStackTop = 0;
+			this.stack[this.stateStackTop] = act;
+
+			int tok = this.lexStream.kind(this.currentToken);
+			this.locationStack[this.stateStackTop] = this.currentToken;
+			this.locationStartStack[this.stateStackTop] = this.lexStream.start(this.currentToken);
+
+			boolean forceRecoveryAfterLBracketMissing = false;
+	//		int forceRecoveryToken = -1;
+
+			//
+			// Process a terminal
+			//
+			do {
+				//
+				// Synchronize state stacks and update the location stack
+				//
+				prev_pos = -1;
+				this.prevStackTop = -1;
+
+				next_pos = -1;
+				this.nextStackTop = -1;
+
+				pos = this.stateStackTop;
+				this.tempStackTop = this.stateStackTop - 1;
+				for (int i = 0; i <= this.stateStackTop; i++)
+					this.tempStack[i] = this.stack[i];
+
+				act = Parser.tAction(act, tok);
+				//
+				// When a reduce action is encountered, we compute all REDUCE
+				// and associated goto actions induced by the current token.
+				// Eventually, a SHIFT, SHIFT-REDUCE, ACCEPT or ERROR action is
+				// computed...
+				//
+				while (act <= NUM_RULES) {
+					do {
+						this.tempStackTop -= (Parser.rhs[act]-1);
+						act = Parser.ntAction(this.tempStack[this.tempStackTop], Parser.lhs[act]);
+					} while(act <= NUM_RULES);
+					//
+					// ... Update the maximum useful position of the
+					// (STATE_)STACK, push goto state into stack, and
+					// compute next action on current symbol ...
+					//
+					if (this.tempStackTop + 1 >= this.stackLength)
+						reallocateStacks();
+					pos = pos < this.tempStackTop ? pos : this.tempStackTop;
+					this.tempStack[this.tempStackTop + 1] = act;
+					act = Parser.tAction(act, tok);
+				}
+
+				//
+				// At this point, we have a shift, shift-reduce, accept or error
+				// action.  STACK contains the configuration of the state stack
+				// prior to executing any action on curtok. next_stack contains
+				// the configuration of the state stack after executing all
+				// reduce actions induced by curtok.  The variable pos indicates
+				// the highest position in STACK that is still useful after the
+				// reductions are executed.
+				//
+				while(act > ERROR_ACTION || act < ACCEPT_ACTION) { // SHIFT-REDUCE action or SHIFT action ?
+					this.nextStackTop = this.tempStackTop + 1;
+					for (int i = next_pos + 1; i <= this.nextStackTop; i++)
+						this.nextStack[i] = this.tempStack[i];
+
+					for (int i = pos + 1; i <= this.nextStackTop; i++) {
+						this.locationStack[i] = this.locationStack[this.stateStackTop];
+						this.locationStartStack[i] = this.locationStartStack[this.stateStackTop];
+					}
+
+					//
+					// If we have a shift-reduce, process it as well as
+					// the goto-reduce actions that follow it.
+					//
+					if (act > ERROR_ACTION) {
+						act -= ERROR_ACTION;
+						do {
+							this.nextStackTop -= (Parser.rhs[act]-1);
+							act = Parser.ntAction(this.nextStack[this.nextStackTop], Parser.lhs[act]);
+						} while(act <= NUM_RULES);
+						pos = pos < this.nextStackTop ? pos : this.nextStackTop;
+					}
+
+					if (this.nextStackTop + 1 >= this.stackLength)
+						reallocateStacks();
+
+					this.tempStackTop = this.nextStackTop;
+					this.nextStack[++this.nextStackTop] = act;
+					next_pos = this.nextStackTop;
+
+					//
+					// Simulate the parser through the next token without
+					// destroying STACK or next_stack.
+					//
+					this.currentToken = this.lexStream.getToken();
+					tok = this.lexStream.kind(this.currentToken);
+					act = Parser.tAction(act, tok);
+					while(act <= NUM_RULES) {
+						//
+						// ... Process all goto-reduce actions following
+						// reduction, until a goto action is computed ...
+						//
+						do {
+							int lhs_symbol = Parser.lhs[act];
+							if(DEBUG) {
+								System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
+							}
+							this.tempStackTop -= (Parser.rhs[act]-1);
+							act = (this.tempStackTop > next_pos
+									   ? this.tempStack[this.tempStackTop]
+									   : this.nextStack[this.tempStackTop]);
+							act = Parser.ntAction(act, lhs_symbol);
+						}   while(act <= NUM_RULES);
+
+						//
+						// ... Update the maximum useful position of the
+						// (STATE_)STACK, push GOTO state into stack, and
+						// compute next action on current symbol ...
+						//
+						if (this.tempStackTop + 1 >= this.stackLength)
+							reallocateStacks();
+
+						next_pos = next_pos < this.tempStackTop ? next_pos : this.tempStackTop;
+						this.tempStack[this.tempStackTop + 1] = act;
+						act = Parser.tAction(act, tok);
+					}
+
+	//				if((tok != TokenNameRBRACE || (forceRecoveryToken != currentToken && (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0))
+	//					&& (lexStream.flags(currentToken) & LexStream.IS_AFTER_JUMP) !=0) {
+	//					act = ERROR_ACTION;
+	//					if(forceRecoveryToken != currentToken
+	//						&& (lexStream.flags(currentToken) & LexStream.LBRACE_MISSING) != 0) {
+	//						forceRecoveryAfterLBracketMissing = true;
+	//						forceRecoveryToken = currentToken;
+	//					}
+	//				}
+
+					//
+					// No error was detected, Read next token into
+					// PREVTOK element, advance CURTOK pointer and
+					// update stacks.
+					//
+					if (act != ERROR_ACTION) {
+						this.prevStackTop = this.stateStackTop;
+						for (int i = prev_pos + 1; i <= this.prevStackTop; i++)
+							this.prevStack[i] = this.stack[i];
+						prev_pos = pos;
+
+						this.stateStackTop = this.nextStackTop;
+						for (int i = pos + 1; i <= this.stateStackTop; i++)
+							this.stack[i] = this.nextStack[i];
+						this.locationStack[this.stateStackTop] = this.currentToken;
+						this.locationStartStack[this.stateStackTop] = this.lexStream.start(this.currentToken);
+						pos = next_pos;
+					}
+				}
+
+				//
+				// At this stage, either we have an ACCEPT or an ERROR
+				// action.
+				//
+				if (act == ERROR_ACTION) {
+					//
+					// An error was detected.
+					//
+					RepairCandidate candidate = errorRecovery(this.currentToken, forceRecoveryAfterLBracketMissing);
+
+					forceRecoveryAfterLBracketMissing = false;
+
+					if(this.parser.reportOnlyOneSyntaxError) {
+						return;
+					}
+
+					if(this.parser.problemReporter().options.maxProblemsPerUnit < this.parser.compilationUnit.compilationResult.problemCount) {
+						if(this.recoveryScanner == null || !this.recoveryScanner.record) return;
+						this.reportProblem = false;
+					}
+
+					act = this.stack[this.stateStackTop];
+
+					//
+					// If the recovery was successful on a nonterminal candidate,
+					// parse through that candidate and "read" the next token.
+					//
+					if (candidate.symbol == 0) {
+						break;
+					} else if (candidate.symbol > NT_OFFSET) {
+						int lhs_symbol = candidate.symbol - NT_OFFSET;
+						if(DEBUG) {
+							System.out.println(Parser.name[Parser.non_terminal_index[lhs_symbol]]);
+						}
+						act = Parser.ntAction(act, lhs_symbol);
+						while(act <= NUM_RULES) {
+							this.stateStackTop -= (Parser.rhs[act]-1);
+							act = Parser.ntAction(this.stack[this.stateStackTop], Parser.lhs[act]);
+						}
+						this.stack[++this.stateStackTop] = act;
+						this.currentToken = this.lexStream.getToken();
+						tok = this.lexStream.kind(this.currentToken);
+						this.locationStack[this.stateStackTop] = this.currentToken;
+						this.locationStartStack[this.stateStackTop] = this.lexStream.start(this.currentToken);
+					} else {
+						tok = candidate.symbol;
+						this.locationStack[this.stateStackTop] = candidate.location;
+						this.locationStartStack[this.stateStackTop] = this.lexStream.start(candidate.location);
+					}
+				}
+			} while (act != ACCEPT_ACTION);
+		} finally {
+			if(this.recoveryScanner != null) {
+				this.recoveryScanner.record = oldRecord;
+			}
+			this.parser.scanner.setActiveParser(null);
+		}
+		return;
+	}
+
+	private static char[] displayEscapeCharacters(char[] tokenSource, int start, int end) {
+		StringBuffer tokenSourceBuffer = new StringBuffer();
+		for (int i = 0; i < start; i++) {
+			tokenSourceBuffer.append(tokenSource[i]);
+		}
+		for (int i = start; i < end; i++) {
+			char c = tokenSource[i];
+
+			switch (c) {
+                case '\r' :
+                    tokenSourceBuffer.append("\\r"); //$NON-NLS-1$
+                    break;
+                case '\n' :
+                    tokenSourceBuffer.append("\\n"); //$NON-NLS-1$
+                    break;
+                case '\b' :
+                    tokenSourceBuffer.append("\\b"); //$NON-NLS-1$
+                    break;
+                case '\t' :
+                    tokenSourceBuffer.append("\t"); //$NON-NLS-1$
+                    break;
+                case '\f' :
+                    tokenSourceBuffer.append("\\f"); //$NON-NLS-1$
+                    break;
+                case '\"' :
+                    tokenSourceBuffer.append("\\\""); //$NON-NLS-1$
+                    break;
+                case '\'' :
+                    tokenSourceBuffer.append("\\'"); //$NON-NLS-1$
+                    break;
+                case '\\' :
+                    tokenSourceBuffer.append("\\\\"); //$NON-NLS-1$
+                    break;
+                default :
+                    tokenSourceBuffer.append(c);
+            }
+		}
+		for (int i = end; i < tokenSource.length; i++) {
+			tokenSourceBuffer.append(tokenSource[i]);
+		}
+		return tokenSourceBuffer.toString().toCharArray();
+	}
+
+	//
+//		This routine is invoked when an error is encountered.  It
+//	   tries to diagnose the error and recover from it.  If it is
+//	   successful, the state stack, the current token and the buffer
+//	   are readjusted; i.e., after a successful recovery,
+//	   state_stack_top points to the location in the state stack
+//	   that contains the state on which to recover; curtok
+//	   identifies the symbol on which to recover.
+//
+//	   Up to three configurations may be available when this routine
+//	   is invoked. PREV_STACK may contain the sequence of states
+//	   preceding any action on prevtok, STACK always contains the
+//	   sequence of states preceding any action on curtok, and
+//	   NEXT_STACK may contain the sequence of states preceding any
+//	   action on the successor of curtok.
+//
+	private RepairCandidate errorRecovery(int error_token, boolean forcedError) {
+		this.errorToken = error_token;
+		this.errorTokenStart = this.lexStream.start(error_token);
+
+		int prevtok = this.lexStream.previous(error_token);
+		int prevtokKind = this.lexStream.kind(prevtok);
+
+		if(forcedError) {
+			int name_index = Parser.terminal_index[TokenNameLBRACE];
+
+			reportError(INSERTION_CODE, name_index, prevtok, prevtok);
+
+			RepairCandidate candidate = new RepairCandidate();
+			candidate.symbol = TokenNameLBRACE;
+			candidate.location = error_token;
+			this.lexStream.reset(error_token);
+
+			this.stateStackTop = this.nextStackTop;
+			for (int j = 0; j <= this.stateStackTop; j++) {
+				this.stack[j] = this.nextStack[j];
+			}
+			this.locationStack[this.stateStackTop] = error_token;
+			this.locationStartStack[this.stateStackTop] = this.lexStream.start(error_token);
+
+			return candidate;
+		}
+
+		//
+		// Try primary phase recoveries. If not successful, try secondary
+		// phase recoveries.  If not successful and we are at end of the
+		// file, we issue the end-of-file error and quit. Otherwise, ...
+		//
+		RepairCandidate candidate = primaryPhase(error_token);
+		if (candidate.symbol != 0) {
+			return candidate;
+		}
+
+		candidate = secondaryPhase(error_token);
+		if (candidate.symbol != 0) {
+			return candidate;
+		}
+
+		if (this.lexStream.kind(error_token) == EOFT_SYMBOL) {
+			reportError(EOF_CODE,
+						Parser.terminal_index[EOFT_SYMBOL],
+						prevtok,
+						prevtok);
+			candidate.symbol = 0;
+			candidate.location = error_token;
+			return candidate;
+		}
+
+		//
+		// At this point, primary and (initial attempt at) secondary
+		// recovery did not work.  We will now get into "panic mode" and
+		// keep trying secondary phase recoveries until we either find
+		// a successful recovery or have consumed the remaining input
+		// tokens.
+		//
+		while(this.lexStream.kind(this.buffer[BUFF_UBOUND]) != EOFT_SYMBOL) {
+			candidate = secondaryPhase(this.buffer[MAX_DISTANCE - MIN_DISTANCE + 2]);
+			if (candidate.symbol != 0) {
+				return candidate;
+			}
+		}
+
+		//
+		// We reached the end of the file while panicking. Delete all
+		// remaining tokens in the input.
+		//
+		int i;
+		for (i = BUFF_UBOUND; this.lexStream.kind(this.buffer[i]) == EOFT_SYMBOL; i--){/*empty*/}
+
+		reportError(DELETION_CODE,
+					Parser.terminal_index[prevtokKind],//Parser.terminal_index[lexStream.kind(prevtok)],
+					error_token,
+					this.buffer[i]);
+
+		candidate.symbol = 0;
+		candidate.location = this.buffer[i];
+
+		return candidate;
+	}
+
+//
+//	   This function tries primary and scope recovery on each
+//	   available configuration.  If a successful recovery is found
+//	   and no secondary phase recovery can do better, a diagnosis is
+//	   issued, the configuration is updated and the function returns
+//	   "true".  Otherwise, it returns "false".
+//
+	private RepairCandidate primaryPhase(int error_token) {
+		PrimaryRepairInfo repair = new PrimaryRepairInfo();
+		RepairCandidate candidate = new RepairCandidate();
+
+		//
+		// Initialize the buffer.
+		//
+		int i = (this.nextStackTop >= 0 ? 3 : 2);
+		this.buffer[i] = error_token;
+
+		for (int j = i; j > 0; j--)
+			this.buffer[j - 1] = this.lexStream.previous(this.buffer[j]);
+
+		for (int k = i + 1; k < BUFF_SIZE; k++)
+			this.buffer[k] = this.lexStream.next(this.buffer[k - 1]);
+
+		//
+		// If NEXT_STACK_TOP > 0 then the parse was successful on CURTOK
+		// and the error was detected on the successor of CURTOK. In
+		// that case, first check whether or not primary recovery is
+		// possible on next_stack ...
+		//
+		if (this.nextStackTop >= 0) {
+			repair.bufferPosition = 3;
+			repair = checkPrimaryDistance(this.nextStack, this.nextStackTop, repair);
+		}
+
+		//
+		// ... Next, try primary recovery on the current token...
+		//
+		PrimaryRepairInfo new_repair = repair.copy();
+
+		new_repair.bufferPosition = 2;
+		new_repair = checkPrimaryDistance(this.stack, this.stateStackTop, new_repair);
+		if (new_repair.distance > repair.distance || new_repair.misspellIndex > repair.misspellIndex) {
+			repair = new_repair;
+		}
+
+		//
+		// Finally, if prev_stack_top >= 0 then try primary recovery on
+		// the prev_stack configuration.
+		//
+
+		if (this.prevStackTop >= 0) {
+			new_repair = repair.copy();
+			new_repair.bufferPosition = 1;
+			new_repair = checkPrimaryDistance(this.prevStack,this.prevStackTop, new_repair);
+			if (new_repair.distance > repair.distance || new_repair.misspellIndex > repair.misspellIndex) {
+				repair = new_repair;
+			}
+		}
+
+		//
+		// Before accepting the best primary phase recovery obtained,
+		// ensure that we cannot do better with a similar secondary
+		// phase recovery.
+		//
+		if (this.nextStackTop >= 0) {// next_stack available
+			if (secondaryCheck(this.nextStack,this.nextStackTop,3,repair.distance)) {
+				return candidate;
+			}
+		}
+		else if (secondaryCheck(this.stack, this.stateStackTop, 2, repair.distance)) {
+			return candidate;
+		}
+
+		//
+		// First, adjust distance if the recovery is on the error token;
+		// it is important that the adjustment be made here and not at
+		// each primary trial to prevent the distance tests from being
+		// biased in favor of deferred recoveries which have access to
+		// more input tokens...
+		//
+		repair.distance = repair.distance - repair.bufferPosition + 1;
+
+		//
+		// ...Next, adjust the distance if the recovery is a deletion or
+		// (some form of) substitution...
+		//
+		if (repair.code == INVALID_CODE      ||
+			repair.code == DELETION_CODE     ||
+			repair.code == SUBSTITUTION_CODE ||
+			repair.code == MERGE_CODE) {
+			 repair.distance--;
+		}
+
+		//
+		// ... After adjustment, check if the most successful primary
+		// recovery can be applied.  If not, continue with more radical
+		// recoveries...
+		//
+		if (repair.distance < MIN_DISTANCE) {
+			return candidate;
+		}
+
+		//
+		// When processing an insertion error, if the token preceeding
+		// the error token is not available, we change the repair code
+		// into a BEFORE_CODE to instruct the reporting routine that it
+		// indicates that the repair symbol should be inserted before
+		// the error token.
+		//
+		if (repair.code == INSERTION_CODE) {
+			if (this.buffer[repair.bufferPosition - 1] == 0) {
+				repair.code = BEFORE_CODE;
+			}
+		}
+
+		//
+		// Select the proper sequence of states on which to recover,
+		// update stack accordingly and call diagnostic routine.
+		//
+		if (repair.bufferPosition == 1) {
+			this.stateStackTop = this.prevStackTop;
+			for (int j = 0; j <= this.stateStackTop; j++) {
+				this.stack[j] = this.prevStack[j];
+			}
+		} else if (this.nextStackTop >= 0 && repair.bufferPosition >= 3) {
+			this.stateStackTop = this.nextStackTop;
+			for (int j = 0; j <= this.stateStackTop; j++) {
+				this.stack[j] = this.nextStack[j];
+			}
+			this.locationStack[this.stateStackTop] = this.buffer[3];
+			this.locationStartStack[this.stateStackTop] = this.lexStream.start(this.buffer[3]);
+		}
+
+		return primaryDiagnosis(repair);
+	}
+
+
+//
+//		   This function checks whether or not a given state has a
+//	   candidate, whose string representaion is a merging of the two
+//	   tokens at positions buffer_position and buffer_position+1 in
+//	   the buffer.  If so, it returns the candidate in question;
+//	   otherwise it returns 0.
+//
+	private int mergeCandidate(int state, int buffer_position) {
+		char[] name1 = this.lexStream.name(this.buffer[buffer_position]);
+		char[] name2 = this.lexStream.name(this.buffer[buffer_position + 1]);
+
+		int len  = name1.length + name2.length;
+
+		char[] str = CharOperation.concat(name1, name2);
+
+		for (int k = Parser.asi(state); Parser.asr[k] != 0; k++) {
+			int l = Parser.terminal_index[Parser.asr[k]];
+
+			if (len == Parser.name[l].length()) {
+				char[] name = Parser.name[l].toCharArray();
+
+				if (CharOperation.equals(str, name, false)) {
+					return Parser.asr[k];
+				}
+			}
+		}
+
+		return 0;
+	}
+
+
+//
+//	   This procedure takes as arguments a parsing configuration
+//	   consisting of a state stack (stack and stack_top) and a fixed
+//	   number of input tokens (starting at buffer_position) in the
+//	   input BUFFER; and some reference arguments: repair_code,
+//	   distance, misspell_index, candidate, and stack_position
+//	   which it sets based on the best possible recovery that it
+//	   finds in the given configuration.  The effectiveness of a
+//	   a repair is judged based on two criteria:
+//
+//		 1) the number of tokens that can be parsed after the repair
+//			is applied: distance.
+//		 2) how close to perfection is the candidate that is chosen:
+//			misspell_index.
+//	   When this procedure is entered, distance, misspell_index and
+//	   repair_code are assumed to be initialized.
+//
+	private PrimaryRepairInfo checkPrimaryDistance(int stck[], int stack_top, PrimaryRepairInfo repair) {
+		int i, j, k, next_state, max_pos, act, root, symbol, tok;
+
+		//
+	    //  First, try scope and manual recovery.
+	    //
+	    PrimaryRepairInfo scope_repair = scopeTrial(stck, stack_top, repair.copy());
+	    if (scope_repair.distance > repair.distance)
+	        repair = scope_repair;
+
+		//
+		//  Next, try merging the error token with its successor.
+		//
+	    if(this.buffer[repair.bufferPosition] != 0 && this.buffer[repair.bufferPosition + 1] != 0) {// do not merge the first token
+			symbol = mergeCandidate(stck[stack_top], repair.bufferPosition);
+			if (symbol != 0) {
+				j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+2);
+				if ((j > repair.distance) || (j == repair.distance && repair.misspellIndex < 10)) {
+					repair.misspellIndex = 10;
+					repair.symbol = symbol;
+					repair.distance = j;
+					repair.code = MERGE_CODE;
+				}
+			}
+	    }
+
+		//
+		// Next, try deletion of the error token.
+		//
+		j = parseCheck(
+				stck,
+				stack_top,
+				this.lexStream.kind(this.buffer[repair.bufferPosition + 1]),
+				repair.bufferPosition + 2);
+		if (this.lexStream.kind(this.buffer[repair.bufferPosition]) == EOLT_SYMBOL &&
+			this.lexStream.afterEol(this.buffer[repair.bufferPosition+1])) {
+			 k = 10;
+		} else {
+			k = 0;
+		}
+		if (j > repair.distance || (j == repair.distance && k > repair.misspellIndex)) {
+			repair.misspellIndex = k;
+			repair.code = DELETION_CODE;
+			repair.distance = j;
+		}
+
+		//
+		// Update the error configuration by simulating all reduce and
+		// goto actions induced by the error token. Then assign the top
+		// most state of the new configuration to next_state.
+		//
+		next_state = stck[stack_top];
+		max_pos = stack_top;
+		this.tempStackTop = stack_top - 1;
+
+		tok = this.lexStream.kind(this.buffer[repair.bufferPosition]);
+		this.lexStream.reset(this.buffer[repair.bufferPosition + 1]);
+		act = Parser.tAction(next_state, tok);
+		while(act <= NUM_RULES) {
+			do {
+				this.tempStackTop -= (Parser.rhs[act]-1);
+				symbol = Parser.lhs[act];
+				act = (this.tempStackTop > max_pos
+									  ? this.tempStack[this.tempStackTop]
+									  : stck[this.tempStackTop]);
+				act = Parser.ntAction(act, symbol);
+			} while(act <= NUM_RULES);
+			max_pos = max_pos < this.tempStackTop ? max_pos : this.tempStackTop;
+			this.tempStack[this.tempStackTop + 1] = act;
+			next_state = act;
+			act = Parser.tAction(next_state, tok);
+		}
+
+		//
+		//  Next, place the list of candidates in proper order.
+		//
+		root = 0;
+		for (i = Parser.asi(next_state); Parser.asr[i] != 0; i++) {
+			symbol = Parser.asr[i];
+			if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL) {
+				if (root == 0) {
+					this.list[symbol] = symbol;
+				} else {
+					this.list[symbol] = this.list[root];
+					this.list[root] = symbol;
+				}
+				root = symbol;
+			}
+		}
+
+		if (stck[stack_top] != next_state) {
+			for (i = Parser.asi(stck[stack_top]); Parser.asr[i] != 0; i++) {
+				symbol = Parser.asr[i];
+				if (symbol != EOFT_SYMBOL && symbol != ERROR_SYMBOL && this.list[symbol] == 0) {
+					if (root == 0) {
+						this.list[symbol] = symbol;
+					} else {
+						this.list[symbol] = this.list[root];
+						this.list[root] = symbol;
+					}
+					root = symbol;
+				}
+			}
+		}
+
+		i = this.list[root];
+		this.list[root] = 0;
+		root = i;
+
+		//
+		//  Next, try insertion for each possible candidate available in
+		// the current state, except EOFT and ERROR_SYMBOL.
+		//
+		symbol = root;
+		while(symbol != 0) {
+			if (symbol == EOLT_SYMBOL && this.lexStream.afterEol(this.buffer[repair.bufferPosition])) {
+				k = 10;
+			} else {
+				k = 0;
+			}
+			j = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
+			if (j > repair.distance) {
+				repair.misspellIndex = k;
+				repair.distance = j;
+				repair.symbol = symbol;
+				repair.code = INSERTION_CODE;
+			} else if (j == repair.distance && k > repair.misspellIndex) {
+				repair.misspellIndex = k;
+				repair.distance = j;
+				repair.symbol = symbol;
+				repair.code = INSERTION_CODE;
+			}
+
+			symbol = this.list[symbol];
+		}
+
+		//
+		//  Next, Try substitution for each possible candidate available
+		// in the current state, except EOFT and ERROR_SYMBOL.
+		//
+		symbol = root;
+
+		if(this.buffer[repair.bufferPosition] != 0) {// do not replace the first token
+			while(symbol != 0) {
+				if (symbol == EOLT_SYMBOL && this.lexStream.afterEol(this.buffer[repair.bufferPosition+1])) {
+					k = 10;
+				} else {
+					k = misspell(symbol, this.buffer[repair.bufferPosition]);
+				}
+				j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+1);
+				if (j > repair.distance) {
+					repair.misspellIndex = k;
+					repair.distance = j;
+					repair.symbol = symbol;
+					repair.code = SUBSTITUTION_CODE;
+				} else if (j == repair.distance && k > repair.misspellIndex) {
+					repair.misspellIndex = k;
+					repair.symbol = symbol;
+					repair.code = SUBSTITUTION_CODE;
+				}
+				i = symbol;
+				symbol = this.list[symbol];
+				this.list[i] = 0;                             // reset element
+			}
+		}
+
+
+		//
+		// Next, we try to insert a nonterminal candidate in front of the
+		// error token, or substituting a nonterminal candidate for the
+		// error token. Precedence is given to insertion.
+		//
+		 for (i = Parser.nasi(stck[stack_top]); Parser.nasr[i] != 0; i++) {
+			 symbol = Parser.nasr[i] + NT_OFFSET;
+			 j = parseCheck(stck, stack_top, symbol, repair.bufferPosition+1);
+			 if (j > repair.distance) {
+				 repair.misspellIndex = 0;
+				 repair.distance = j;
+				 repair.symbol = symbol;
+				 repair.code = INVALID_CODE;
+			 }
+
+			 j = parseCheck(stck, stack_top, symbol, repair.bufferPosition);
+			 if ((j > repair.distance) || (j == repair.distance && repair.code == INVALID_CODE)) {
+				 repair.misspellIndex = 0;
+				 repair.distance = j;
+				 repair.symbol = symbol;
+				 repair.code = INSERTION_CODE;
+			 }
+		 }
+
+		return repair;
+	}
+
+
+//
+//	   This procedure is invoked to issue a diagnostic message and
+//	   adjust the input buffer.  The recovery in question is either
+//	   the insertion of one or more scopes, the merging of the error
+//	   token with its successor, the deletion of the error token,
+//	   the insertion of a single token in front of the error token
+//	   or the substitution of another token for the error token.
+//
+	private RepairCandidate primaryDiagnosis(PrimaryRepairInfo repair) {
+		int name_index;
+
+		//
+		//  Issue diagnostic.
+		//
+		int prevtok = this.buffer[repair.bufferPosition - 1];
+		int	curtok  = this.buffer[repair.bufferPosition];
+
+		switch(repair.code) {
+			case INSERTION_CODE:
+			case BEFORE_CODE: {
+				if (repair.symbol > NT_OFFSET)
+					 name_index = getNtermIndex(this.stack[this.stateStackTop],
+												repair.symbol,
+												repair.bufferPosition);
+				else name_index = getTermIndex(this.stack,
+											   this.stateStackTop,
+											   repair.symbol,
+											   repair.bufferPosition);
+
+				int t = (repair.code == INSERTION_CODE ? prevtok : curtok);
+				reportError(repair.code, name_index, t, t);
+				break;
+			}
+			case INVALID_CODE: {
+				name_index = getNtermIndex(this.stack[this.stateStackTop],
+										   repair.symbol,
+										   repair.bufferPosition + 1);
+				reportError(repair.code, name_index, curtok, curtok);
+				break;
+			}
+			case SUBSTITUTION_CODE: {
+				if (repair.misspellIndex >= 6)
+					name_index = Parser.terminal_index[repair.symbol];
+				else
+				{
+					name_index = getTermIndex(this.stack, this.stateStackTop,
+											  repair.symbol,
+											  repair.bufferPosition + 1);
+					if (name_index != Parser.terminal_index[repair.symbol])
+						repair.code = INVALID_CODE;
+				}
+				reportError(repair.code, name_index, curtok, curtok);
+				break;
+			}
+			case MERGE_CODE: {
+				reportError(repair.code,
+							 Parser.terminal_index[repair.symbol],
+							 curtok,
+							 this.lexStream.next(curtok));
+				break;
+			}
+			case SCOPE_CODE: {
+	            for (int i = 0; i < this.scopeStackTop; i++) {
+	                reportError(repair.code,
+	                            -this.scopeIndex[i],
+	                            this.locationStack[this.scopePosition[i]],
+	                            prevtok,
+	                            Parser.non_terminal_index[Parser.scope_lhs[this.scopeIndex[i]]]);
+	            }
+
+	            repair.symbol = Parser.scope_lhs[this.scopeIndex[this.scopeStackTop]] + NT_OFFSET;
+	            this.stateStackTop = this.scopePosition[this.scopeStackTop];
+	            reportError(repair.code,
+	                        -this.scopeIndex[this.scopeStackTop],
+	                        this.locationStack[this.scopePosition[this.scopeStackTop]],
+	                        prevtok,
+	                        getNtermIndex(this.stack[this.stateStackTop],
+	                                      repair.symbol,
+	                                      repair.bufferPosition)
+	                       );
+	            break;
+	        }
+			default: {// deletion
+				reportError(repair.code, Parser.terminal_index[ERROR_SYMBOL], curtok, curtok);
+			}
+		}
+
+		//
+		//  Update buffer.
+		//
+		RepairCandidate candidate = new RepairCandidate();
+		switch (repair.code) {
+			case INSERTION_CODE:
+			case BEFORE_CODE:
+			case SCOPE_CODE: {
+				candidate.symbol = repair.symbol;
+				candidate.location = this.buffer[repair.bufferPosition];
+				this.lexStream.reset(this.buffer[repair.bufferPosition]);
+				break;
+			}
+			case INVALID_CODE:
+			case SUBSTITUTION_CODE: {
+				candidate.symbol = repair.symbol;
+				candidate.location = this.buffer[repair.bufferPosition];
+				this.lexStream.reset(this.buffer[repair.bufferPosition + 1]);
+				break;
+			}
+			case MERGE_CODE: {
+				candidate.symbol = repair.symbol;
+				candidate.location = this.buffer[repair.bufferPosition];
+				this.lexStream.reset(this.buffer[repair.bufferPosition + 2]);
+				break;
+			}
+			default: {// deletion
+				candidate.location = this.buffer[repair.bufferPosition + 1];
+				candidate.symbol =
+						  this.lexStream.kind(this.buffer[repair.bufferPosition + 1]);
+				this.lexStream.reset(this.buffer[repair.bufferPosition + 2]);
+				break;
+			}
+		}
+
+		return candidate;
+	}
+
+
+//
+//	   This function takes as parameter an integer STACK_TOP that
+//	   points to a STACK element containing the state on which a
+//	   primary recovery will be made; the terminal candidate on which
+//	   to recover; and an integer: buffer_position, which points to
+//	   the position of the next input token in the BUFFER.  The
+//	   parser is simulated until a shift (or shift-reduce) action
+//	   is computed on the candidate.  Then we proceed to compute the
+//	   the name index of the highest level nonterminal that can
+//	   directly or indirectly produce the candidate.
+//
+	private int getTermIndex(int stck[], int stack_top, int tok, int buffer_position) {
+		//
+		// Initialize stack index of temp_stack and initialize maximum
+		// position of state stack that is still useful.
+		//
+		int act = stck[stack_top],
+			max_pos = stack_top,
+			highest_symbol = tok;
+
+		this.tempStackTop = stack_top - 1;
+
+		//
+		// Compute all reduce and associated actions induced by the
+		// candidate until a SHIFT or SHIFT-REDUCE is computed. ERROR
+		// and ACCEPT actions cannot be computed on the candidate in
+		// this context, since we know that it is suitable for recovery.
+		//
+		this.lexStream.reset(this.buffer[buffer_position]);
+		act = Parser.tAction(act, tok);
+		while(act <= NUM_RULES) {
+			//
+			// Process all goto-reduce actions following reduction,
+			// until a goto action is computed ...
+			//
+			do {
+				this.tempStackTop -= (Parser.rhs[act]-1);
+				int lhs_symbol = Parser.lhs[act];
+				act = (this.tempStackTop > max_pos
+									  ? this.tempStack[this.tempStackTop]
+									  : stck[this.tempStackTop]);
+				act = Parser.ntAction(act, lhs_symbol);
+			} while(act <= NUM_RULES);
+
+			//
+			// Compute new maximum useful position of (STATE_)stack,
+			// push goto state into the stack, and compute next
+			// action on candidate ...
+			//
+			max_pos = max_pos < this.tempStackTop ? max_pos : this.tempStackTop;
+			this.tempStack[this.tempStackTop + 1] = act;
+			act = Parser.tAction(act, tok);
+		}
+
+		//
+		// At this stage, we have simulated all actions induced by the
+		// candidate and we are ready to shift or shift-reduce it. First,
+		// set tok and next_ptr appropriately and identify the candidate
+		// as the initial highest_symbol. If a shift action was computed
+		// on the candidate, update the stack and compute the next
+		// action. Next, simulate all actions possible on the next input
+		// token until we either have to shift it or are about to reduce
+		// below the initial starting point in the stack (indicated by
+		// max_pos as computed in the previous loop).  At that point,
+		// return the highest_symbol computed.
+		//
+		this.tempStackTop++; // adjust top of stack to reflect last goto
+						  // next move is shift or shift-reduce.
+		int threshold = this.tempStackTop;
+
+		tok = this.lexStream.kind(this.buffer[buffer_position]);
+		this.lexStream.reset(this.buffer[buffer_position + 1]);
+
+		if (act > ERROR_ACTION) {  // shift-reduce on candidate?
+			act -= ERROR_ACTION;
+		} else {
+			this.tempStack[this.tempStackTop + 1] = act;
+			act = Parser.tAction(act, tok);
+		}
+
+		while(act <= NUM_RULES) {
+			//
+			// Process all goto-reduce actions following reduction,
+			// until a goto action is computed ...
+			//
+			do {
+				this.tempStackTop -= (Parser.rhs[act]-1);
+
+				if (this.tempStackTop < threshold) {
+					return (highest_symbol > NT_OFFSET
+						 ? Parser.non_terminal_index[highest_symbol - NT_OFFSET]
+						 : Parser.terminal_index[highest_symbol]);
+				}
+
+				int lhs_symbol = Parser.lhs[act];
+				if (this.tempStackTop == threshold)
+					highest_symbol = lhs_symbol + NT_OFFSET;
+				act = (this.tempStackTop > max_pos
+									  ? this.tempStack[this.tempStackTop]
+									  : stck[this.tempStackTop]);
+				act = Parser.ntAction(act, lhs_symbol);
+			} while(act <= NUM_RULES);
+
+			this.tempStack[this.tempStackTop + 1] = act;
+			act = Parser.tAction(act, tok);
+		}
+
+		return (highest_symbol > NT_OFFSET
+							 ? Parser.non_terminal_index[highest_symbol - NT_OFFSET]
+							 : Parser.terminal_index[highest_symbol]);
+	}
+
+//
+//	   This function takes as parameter a starting state number:
+//	   start, a nonterminal symbol, A (candidate), and an integer,
+//	   buffer_position,  which points to the position of the next
+//	   input token in the BUFFER.
+//	   It returns the highest level non-terminal B such that
+//	   B =>*rm A.  I.e., there does not exists a nonterminal C such
+//	   that C =>+rm B. (Recall that for an LALR(k) grammar if
+//	   C =>+rm B, it cannot be the case that B =>+rm C)
+//
+	private int getNtermIndex(int start, int sym, int buffer_position) {
+		int highest_symbol = sym - NT_OFFSET,
+			tok = this.lexStream.kind(this.buffer[buffer_position]);
+		this.lexStream.reset(this.buffer[buffer_position + 1]);
+
+		//
+		// Initialize stack index of temp_stack and initialize maximum
+		// position of state stack that is still useful.
+		//
+		this.tempStackTop = 0;
+		this.tempStack[this.tempStackTop] = start;
+
+		int act = Parser.ntAction(start, highest_symbol);
+		if (act > NUM_RULES) { // goto action?
+			this.tempStack[this.tempStackTop + 1] = act;
+			act = Parser.tAction(act, tok);
+		}
+
+		while(act <= NUM_RULES) {
+			//
+			// Process all goto-reduce actions following reduction,
+			// until a goto action is computed ...
+			//
+			do {
+				this.tempStackTop -= (Parser.rhs[act]-1);
+				if (this.tempStackTop < 0)
+					return Parser.non_terminal_index[highest_symbol];
+				if (this.tempStackTop == 0)
+					highest_symbol = Parser.lhs[act];
+				act = Parser.ntAction(this.tempStack[this.tempStackTop], Parser.lhs[act]);
+			} while(act <= NUM_RULES);
+			this.tempStack[this.tempStackTop + 1] = act;
+			act = Parser.tAction(act, tok);
+		}
+
+		return Parser.non_terminal_index[highest_symbol];
+	}
+
+//
+//		   Check whether or not there is a high probability that a
+//	   given string is a misspelling of another.
+//	   Certain singleton symbols (such as ":" and ";") are also
+//	   considered to be misspelling of each other.
+//
+	private int misspell(int sym, int tok) {
+
+
+		//
+		//
+		//
+		char[] name = Parser.name[Parser.terminal_index[sym]].toCharArray();
+		int n = name.length;
+		char[] s1 = new char[n + 1];
+		for (int k = 0; k < n; k++) {
+			char c = name[k];
+			s1[k] = ScannerHelper.toLowerCase(c);
+		}
+		s1[n] = '\0';
+
+		//
+		//
+		//
+		char[] tokenName = this.lexStream.name(tok);
+		int len = tokenName.length;
+		int m = len < MAX_NAME_LENGTH ? len : MAX_NAME_LENGTH;
+		char[] s2 = new char[m + 1];
+		for (int k = 0; k < m; k++) {
+			char c = tokenName[k];
+			s2[k] = ScannerHelper.toLowerCase(c);
+		}
+		s2[m] = '\0';
+
+		//
+		//  Singleton mispellings:
+		//
+		//  ;      <---->     ,
+		//
+		//  ;      <---->     :
+		//
+		//  .      <---->     ,
+		//
+		//  '      <---->     "
+		//
+		//
+		if (n == 1  &&  m == 1) {
+			if ((s1[0] == ';'  &&  s2[0] == ',')  ||
+				(s1[0] == ','  &&  s2[0] == ';')  ||
+				(s1[0] == ';'  &&  s2[0] == ':')  ||
+				(s1[0] == ':'  &&  s2[0] == ';')  ||
+				(s1[0] == '.'  &&  s2[0] == ',')  ||
+				(s1[0] == ','  &&  s2[0] == '.')  ||
+				(s1[0] == '\'' &&  s2[0] == '\"')  ||
+				(s1[0] == '\"'  &&  s2[0] == '\'')) {
+					return 3;
+			}
+		}
+
+		//
+		// Scan the two strings. Increment "match" count for each match.
+		// When a transposition is encountered, increase "match" count
+		// by two but count it as an error. When a typo is found, skip
+		// it and count it as an error. Otherwise we have a mismatch; if
+		// one of the strings is longer, increment its index, otherwise,
+		// increment both indices and continue.
+		//
+		// This algorithm is an adaptation of a boolean misspelling
+		// algorithm proposed by Juergen Uhl.
+		//
+		int count = 0;
+		int prefix_length = 0;
+		int num_errors = 0;
+
+		int i = 0;
+		int j = 0;
+		while ((i < n)  &&  (j < m)) {
+			if (s1[i] == s2[j]) {
+				count++;
+				i++;
+				j++;
+				if (num_errors == 0) {
+					prefix_length++;
+				}
+			} else if (s1[i+1] == s2[j]  &&  s1[i] == s2[j+1]) {
+				count += 2;
+				i += 2;
+				j += 2;
+				num_errors++;
+			} else if (s1[i+1] == s2[j+1]) {
+				i++;
+				j++;
+				num_errors++;
+			} else {
+				if ((n - i) > (m - j)) {
+					 i++;
+				} else if ((m - j) > (n - i)) {
+					 j++;
+				} else {
+					i++;
+					j++;
+				}
+				num_errors++;
+			}
+		}
+
+		if (i < n  ||  j < m)
+			num_errors++;
+
+		if (num_errors > ((n < m ? n : m) / 6 + 1))
+			 count = prefix_length;
+
+		return(count * 10 / ((n < len ? len : n) + num_errors));
+	}
+
+	private PrimaryRepairInfo scopeTrial(int stck[], int stack_top, PrimaryRepairInfo repair) {
+	    this.stateSeen = new int[this.stackLength];
+	    for (int i = 0; i < this.stackLength; i++)
+	        this.stateSeen[i] = NIL;
+
+	    this.statePoolTop = 0;
+	    this.statePool = new StateInfo[this.stackLength];
+
+	    scopeTrialCheck(stck, stack_top, repair, 0);
+
+	    this.stateSeen = null;
+	    this.statePoolTop = 0;
+
+	    repair.code = SCOPE_CODE;
+	    repair.misspellIndex = 10;
+
+	    return repair;
+	}
+
+	private void scopeTrialCheck(int stck[], int stack_top, PrimaryRepairInfo repair, int indx) {
+		if(indx > 20) return; // avoid too much recursive call to improve performance
+
+		int act = stck[stack_top];
+
+	    for (int i = this.stateSeen[stack_top]; i != NIL; i = this.statePool[i].next) {
+	        if (this.statePool[i].state == act) return;
+	    }
+
+	    int old_state_pool_top = this.statePoolTop++;
+	    if(this.statePoolTop >= this.statePool.length) {
+	    	System.arraycopy(this.statePool, 0, this.statePool = new StateInfo[this.statePoolTop * 2], 0, this.statePoolTop);
+	    }
+
+	    this.statePool[old_state_pool_top] = new StateInfo(act, this.stateSeen[stack_top]);
+	    this.stateSeen[stack_top] = old_state_pool_top;
+
+	    next : for (int i = 0; i < SCOPE_SIZE; i++) {
+	        //
+	        // Use the scope lookahead symbol to force all reductions
+	        // inducible by that symbol.
+	        //
+	        act = stck[stack_top];
+	        this.tempStackTop = stack_top - 1;
+	        int max_pos = stack_top;
+	        int tok = Parser.scope_la[i];
+	        this.lexStream.reset(this.buffer[repair.bufferPosition]);
+	        act = Parser.tAction(act, tok);
+	        while(act <= NUM_RULES) {
+	            //
+	            // ... Process all goto-reduce actions following
+	            // reduction, until a goto action is computed ...
+	            //
+	            do  {
+	                this.tempStackTop -= (Parser.rhs[act]-1);
+	                int lhs_symbol = Parser.lhs[act];
+	                act =  (this.tempStackTop > max_pos
+	                            ?  this.tempStack[this.tempStackTop]
+	                            :  stck[this.tempStackTop]);
+	                act = Parser.ntAction(act, lhs_symbol);
+	            }  while(act <= NUM_RULES);
+	            if (this.tempStackTop + 1 >= this.stackLength)
+	                return;
+	            max_pos = max_pos < this.tempStackTop ? max_pos : this.tempStackTop;
+	            this.tempStack[this.tempStackTop + 1] = act;
+	            act = Parser.tAction(act, tok);
+	        }
+
+	        //
+	        // If the lookahead symbol is parsable, then we check
+	        // whether or not we have a match between the scope
+	        // prefix and the transition symbols corresponding to
+	        // the states on top of the stack.
+	        //
+	        if (act != ERROR_ACTION) {
+	        	int j, k;
+	            k = Parser.scope_prefix[i];
+	            for (j = this.tempStackTop + 1;
+	                 j >= (max_pos + 1) &&
+	                 Parser.in_symbol(this.tempStack[j]) == Parser.scope_rhs[k]; j--) {
+	                 k++;
+	            }
+	            if (j == max_pos) {
+	                for (j = max_pos;
+	                     j >= 1 && Parser.in_symbol(stck[j]) == Parser.scope_rhs[k];
+	                     j--) {
+	                    k++;
+	                }
+	            }
+	            //
+	            // If the prefix matches, check whether the state
+	            // newly exposed on top of the stack, (after the
+	            // corresponding prefix states are popped from the
+	            // stack), is in the set of "source states" for the
+	            // scope in question and that it is at a position
+	            // below the threshold indicated by MARKED_POS.
+	            //
+	            int marked_pos = (max_pos < stack_top ? max_pos + 1 : stack_top);
+	            if (Parser.scope_rhs[k] == 0 && j < marked_pos) { // match?
+	                int stack_position = j;
+	                for (j = Parser.scope_state_set[i];
+	                     stck[stack_position] != Parser.scope_state[j] &&
+	                     Parser.scope_state[j] != 0;
+	                     j++){/*empty*/}
+	                //
+	                // If the top state is valid for scope recovery,
+	                // the left-hand side of the scope is used as
+	                // starting symbol and we calculate how far the
+	                // parser can advance within the forward context
+	                // after parsing the left-hand symbol.
+	                //
+	                if (Parser.scope_state[j] != 0) {     // state was found
+	                    int previous_distance = repair.distance;
+	                    int distance = parseCheck(stck,
+	                                          stack_position,
+	                                          Parser.scope_lhs[i]+NT_OFFSET,
+	                                          repair.bufferPosition);
+	                    //
+	                    // if the recovery is not successful, we
+	                    // update the stack with all actions induced
+	                    // by the left-hand symbol, and recursively
+	                    // call SCOPE_TRIAL_CHECK to try again.
+	                    // Otherwise, the recovery is successful. If
+	                    // the new distance is greater than the
+	                    // initial SCOPE_DISTANCE, we update
+	                    // SCOPE_DISTANCE and set scope_stack_top to INDX
+	                    // to indicate the number of scopes that are
+	                    // to be applied for a succesful  recovery.
+	                    // NOTE that this procedure cannot get into
+	                    // an infinite loop, since each prefix match
+	                    // is guaranteed to take us to a lower point
+	                    // within the stack.
+	                    //
+	                    if ((distance - repair.bufferPosition + 1) < MIN_DISTANCE) {
+	                        int top = stack_position;
+	                        act = Parser.ntAction(stck[top], Parser.scope_lhs[i]);
+	                        while(act <= NUM_RULES) {
+	                        	if(Parser.rules_compliance[act] > this.options.sourceLevel) {
+								 	continue next;
+								}
+	                            top -= (Parser.rhs[act]-1);
+	                            act = Parser.ntAction(stck[top], Parser.lhs[act]);
+	                        }
+	                        top++;
+
+	                        j = act;
+	                        act = stck[top];  // save
+	                        stck[top] = j;    // swap
+	                        scopeTrialCheck(stck, top, repair, indx+1);
+	                        stck[top] = act; // restore
+	                    } else if (distance > repair.distance) {
+	                        this.scopeStackTop = indx;
+	                        repair.distance = distance;
+	                    }
+
+	                    if (this.lexStream.kind(this.buffer[repair.bufferPosition]) == EOFT_SYMBOL &&
+	                        repair.distance == previous_distance) {
+	                        this.scopeStackTop = indx;
+	                        repair.distance = MAX_DISTANCE;
+	                    }
+
+	                    //
+	                    // If this scope recovery has beaten the
+	                    // previous distance, then we have found a
+	                    // better recovery (or this recovery is one
+	                    // of a list of scope recoveries). Record
+	                    // its information at the proper location
+	                    // (INDX) in SCOPE_INDEX and SCOPE_STACK.
+	                    //
+	                    if (repair.distance > previous_distance) {
+	                        this.scopeIndex[indx] = i;
+	                        this.scopePosition[indx] = stack_position;
+	                        return;
+	                    }
+	                }
+	            }
+	        }
+	    }
+	}
+//
+//	   This function computes the ParseCheck distance for the best
+//	   possible secondary recovery for a given configuration that
+//	   either deletes none or only one symbol in the forward context.
+//	   If the recovery found is more effective than the best primary
+//	   recovery previously computed, then the function returns true.
+//	   Only misplacement, scope and manual recoveries are attempted;
+//	   simple insertion or substitution of a nonterminal are tried
+//	   in CHECK_PRIMARY_DISTANCE as part of primary recovery.
+//
+	private boolean secondaryCheck(int stck[], int stack_top, int buffer_position, int distance) {
+		int top, j;
+
+		for (top = stack_top - 1; top >= 0; top--) {
+			j = parseCheck(stck, top,
+						   this.lexStream.kind(this.buffer[buffer_position]),
+						   buffer_position + 1);
+			if (((j - buffer_position + 1) > MIN_DISTANCE) && (j > distance))
+				return true;
+		}
+
+		PrimaryRepairInfo repair = new PrimaryRepairInfo();
+	    repair.bufferPosition = buffer_position + 1;
+	    repair.distance = distance;
+	    repair = scopeTrial(stck, stack_top, repair);
+	    if ((repair.distance - buffer_position) > MIN_DISTANCE && repair.distance > distance)
+	         return true;
+		return false;
+	}
+
+
+//
+//	   Secondary_phase is a boolean function that checks whether or
+//	   not some form of secondary recovery is applicable to one of
+//	   the error configurations. First, if "next_stack" is available,
+//	   misplacement and secondary recoveries are attempted on it.
+//	   Then, in any case, these recoveries are attempted on "stack".
+//	   If a successful recovery is found, a diagnosis is issued, the
+//	   configuration is updated and the function returns "true".
+//	   Otherwise, the function returns false.
+//
+	private RepairCandidate secondaryPhase(int error_token) {
+		SecondaryRepairInfo repair = new SecondaryRepairInfo();
+		SecondaryRepairInfo misplaced = new SecondaryRepairInfo();
+
+		RepairCandidate candidate = new RepairCandidate();
+
+		int i, j, k, top;
+		int	next_last_index = 0;
+		int	last_index;
+
+		candidate.symbol = 0;
+
+		repair.code = 0;
+		repair.distance = 0;
+		repair.recoveryOnNextStack = false;
+
+		misplaced.distance = 0;
+		misplaced.recoveryOnNextStack = false;
+
+		//
+		// If the next_stack is available, try misplaced and secondary
+		// recovery on it first.
+		//
+		if (this.nextStackTop >= 0) {
+			int  save_location;
+
+			this.buffer[2] = error_token;
+			this.buffer[1] = this.lexStream.previous(this.buffer[2]);
+			this.buffer[0] = this.lexStream.previous(this.buffer[1]);
+
+			for (k = 3; k < BUFF_UBOUND; k++)
+				this.buffer[k] = this.lexStream.next(this.buffer[k - 1]);
+
+			this.buffer[BUFF_UBOUND] = this.lexStream.badtoken();// elmt not available
+
+			//
+			// If we are at the end of the input stream, compute the
+			// index position of the first EOFT symbol (last useful
+			// index).
+			//
+			for (next_last_index = MAX_DISTANCE - 1;
+				 next_last_index >= 1 &&
+				 this.lexStream.kind(this.buffer[next_last_index]) == EOFT_SYMBOL;
+				 next_last_index--){/*empty*/}
+			next_last_index = next_last_index + 1;
+
+			save_location = this.locationStack[this.nextStackTop];
+			int save_location_start = this.locationStartStack[this.nextStackTop];
+			this.locationStack[this.nextStackTop] = this.buffer[2];
+			this.locationStartStack[this.nextStackTop] = this.lexStream.start(this.buffer[2]);
+			misplaced.numDeletions = this.nextStackTop;
+			misplaced = misplacementRecovery(this.nextStack, this.nextStackTop,
+											 next_last_index,
+											 misplaced, true);
+			if (misplaced.recoveryOnNextStack)
+				misplaced.distance++;
+
+			repair.numDeletions = this.nextStackTop + BUFF_UBOUND;
+			repair = secondaryRecovery(this.nextStack, this.nextStackTop,
+									   next_last_index,
+									   repair, true);
+			if (repair.recoveryOnNextStack)
+				repair.distance++;
+
+			this.locationStack[this.nextStackTop] = save_location;
+			this.locationStartStack[this.nextStackTop] = save_location_start;
+		} else {            // next_stack not available, initialize ...
+			misplaced.numDeletions = this.stateStackTop;
+			repair.numDeletions = this.stateStackTop + BUFF_UBOUND;
+		}
+
+		//
+		// Try secondary recovery on the "stack" configuration.
+		//
+		this.buffer[3] = error_token;
+
+		this.buffer[2] = this.lexStream.previous(this.buffer[3]);
+		this.buffer[1] = this.lexStream.previous(this.buffer[2]);
+		this.buffer[0] = this.lexStream.previous(this.buffer[1]);
+
+		for (k = 4; k < BUFF_SIZE; k++)
+			this.buffer[k] = this.lexStream.next(this.buffer[k - 1]);
+
+		for (last_index = MAX_DISTANCE - 1;
+			 last_index >= 1 && this.lexStream.kind(this.buffer[last_index]) == EOFT_SYMBOL;
+			 last_index--){/*empty*/}
+		last_index++;
+
+		misplaced = misplacementRecovery(this.stack, this.stateStackTop,
+										 last_index,
+										 misplaced, false);
+
+		repair = secondaryRecovery(this.stack, this.stateStackTop,
+								   last_index, repair, false);
+
+		//
+		// If a successful misplaced recovery was found, compare it with
+		// the most successful secondary recovery.  If the misplaced
+		// recovery either deletes fewer symbols or parse-checks further
+		// then it is chosen.
+		//
+		if (misplaced.distance > MIN_DISTANCE) {
+			if (misplaced.numDeletions <= repair.numDeletions ||
+			   (misplaced.distance - misplaced.numDeletions) >=
+			   (repair.distance - repair.numDeletions)) {
+				repair.code = MISPLACED_CODE;
+				repair.stackPosition = misplaced.stackPosition;
+				repair.bufferPosition = 2;
+				repair.numDeletions = misplaced.numDeletions;
+				repair.distance = misplaced.distance;
+				repair.recoveryOnNextStack = misplaced.recoveryOnNextStack;
+			}
+		}
+
+		//
+		// If the successful recovery was on next_stack, update: stack,
+		// buffer, location_stack and last_index.
+		//
+		if (repair.recoveryOnNextStack) {
+			this.stateStackTop = this.nextStackTop;
+			for (i = 0; i <= this.stateStackTop; i++)
+				this.stack[i] = this.nextStack[i];
+
+			this.buffer[2] = error_token;
+			this.buffer[1] = this.lexStream.previous(this.buffer[2]);
+			this.buffer[0] = this.lexStream.previous(this.buffer[1]);
+
+			for (k = 3; k < BUFF_UBOUND; k++)
+				this.buffer[k] = this.lexStream.next(this.buffer[k - 1]);
+
+			this.buffer[BUFF_UBOUND] = this.lexStream.badtoken();// elmt not available
+
+			this.locationStack[this.nextStackTop] = this.buffer[2];
+			this.locationStartStack[this.nextStackTop] = this.lexStream.start(this.buffer[2]);
+			last_index = next_last_index;
+		}
+
+	    //
+	    // Next, try scope recoveries after deletion of one, two, three,
+	    // four ... buffer_position tokens from the input stream.
+	    //
+	    if (repair.code == SECONDARY_CODE || repair.code == DELETION_CODE) {
+	        PrimaryRepairInfo scope_repair = new PrimaryRepairInfo();
+
+	        scope_repair.distance = 0;
+	        for (scope_repair.bufferPosition = 2;
+	             scope_repair.bufferPosition <= repair.bufferPosition &&
+	             repair.code != SCOPE_CODE; scope_repair.bufferPosition++) {
+	            scope_repair = scopeTrial(this.stack, this.stateStackTop, scope_repair);
+	            j = (scope_repair.distance == MAX_DISTANCE
+	                                        ? last_index
+	                                        : scope_repair.distance);
+	            k = scope_repair.bufferPosition - 1;
+	            if ((j - k) > MIN_DISTANCE && (j - k) > (repair.distance - repair.numDeletions)) {
+	                repair.code = SCOPE_CODE;
+	                i = this.scopeIndex[this.scopeStackTop];       // upper bound
+	                repair.symbol = Parser.scope_lhs[i] + NT_OFFSET;
+	                repair.stackPosition = this.stateStackTop;
+	                repair.bufferPosition = scope_repair.bufferPosition;
+	            }
+	        }
+	    }
+
+	    //
+	    // If no successful recovery is found and we have reached the
+	    // end of the file, check whether or not scope recovery is
+	    // applicable at the end of the file after discarding some
+	    // states.
+	    //
+	    if (repair.code == 0 && this.lexStream.kind(this.buffer[last_index]) == EOFT_SYMBOL) {
+	        PrimaryRepairInfo scope_repair = new PrimaryRepairInfo();
+
+	        scope_repair.bufferPosition = last_index;
+	        scope_repair.distance = 0;
+	        for (top = this.stateStackTop;
+	             top >= 0 && repair.code == 0; top--)
+	        {
+	            scope_repair = scopeTrial(this.stack, top, scope_repair);
+	            if (scope_repair.distance > 0)
+	            {
+	                repair.code = SCOPE_CODE;
+	                i = this.scopeIndex[this.scopeStackTop];    // upper bound
+	                repair.symbol = Parser.scope_lhs[i] + NT_OFFSET;
+	                repair.stackPosition = top;
+	                repair.bufferPosition = scope_repair.bufferPosition;
+	            }
+	        }
+	    }
+
+		//
+		// If a successful repair was not found, quit!  Otherwise, issue
+		// diagnosis and adjust configuration...
+		//
+		if (repair.code == 0)
+			return candidate;
+
+		secondaryDiagnosis(repair);
+
+		//
+		// Update buffer based on number of elements that are deleted.
+		//
+		switch(repair.code) {
+			case MISPLACED_CODE:
+				 candidate.location = this.buffer[2];
+				 candidate.symbol = this.lexStream.kind(this.buffer[2]);
+				 this.lexStream.reset(this.lexStream.next(this.buffer[2]));
+
+				 break;
+
+			case DELETION_CODE:
+				 candidate.location = this.buffer[repair.bufferPosition];
+				 candidate.symbol =
+						   this.lexStream.kind(this.buffer[repair.bufferPosition]);
+				 this.lexStream.reset(this.lexStream.next(this.buffer[repair.bufferPosition]));
+
+				 break;
+
+		default: // SCOPE_CODE || SECONDARY_CODE
+				 candidate.symbol = repair.symbol;
+				 candidate.location = this.buffer[repair.bufferPosition];
+				 this.lexStream.reset(this.buffer[repair.bufferPosition]);
+
+				 break;
+		}
+
+		return candidate;
+	}
+
+
+//
+//	   This boolean function checks whether or not a given
+//	   configuration yields a better misplacement recovery than
+//	   the best misplacement recovery computed previously.
+//
+	private SecondaryRepairInfo misplacementRecovery(int stck[], int stack_top, int last_index, SecondaryRepairInfo repair, boolean stack_flag) {
+		int  previous_loc = this.buffer[2];
+		int stack_deletions = 0;
+
+		for (int top = stack_top - 1; top >= 0; top--) {
+			if (this.locationStack[top] < previous_loc) {
+				stack_deletions++;
+			}
+			previous_loc = this.locationStack[top];
+
+			int j = parseCheck(stck, top, this.lexStream.kind(this.buffer[2]), 3);
+			if (j == MAX_DISTANCE) {
+				 j = last_index;
+			}
+			if ((j > MIN_DISTANCE) && (j - stack_deletions) > (repair.distance - repair.numDeletions)) {
+				repair.stackPosition = top;
+				repair.distance = j;
+				repair.numDeletions = stack_deletions;
+				repair.recoveryOnNextStack = stack_flag;
+			}
+		}
+
+		return repair;
+	}
+
+
+//
+//	   This boolean function checks whether or not a given
+//	   configuration yields a better secondary recovery than the
+//	   best misplacement recovery computed previously.
+//
+	private SecondaryRepairInfo secondaryRecovery(int stck[],int stack_top, int last_index, SecondaryRepairInfo repair, boolean stack_flag) {
+		int previous_loc;
+		int stack_deletions = 0;
+
+		previous_loc = this.buffer[2];
+		for (int top = stack_top; top >= 0 && repair.numDeletions >= stack_deletions; top--) {
+			if (this.locationStack[top] < previous_loc) {
+				stack_deletions++;
+			}
+			previous_loc = this.locationStack[top];
+
+			for (int i = 2;
+				 i <= (last_index - MIN_DISTANCE + 1) &&
+				 (repair.numDeletions >= (stack_deletions + i - 1)); i++) {
+				int j = parseCheck(stck, top, this.lexStream.kind(this.buffer[i]), i + 1);
+
+				if (j == MAX_DISTANCE) {
+					 j = last_index;
+				}
+				if ((j - i + 1) > MIN_DISTANCE) {
+					int k = stack_deletions + i - 1;
+					if ((k < repair.numDeletions) ||
+						(j - k) > (repair.distance - repair.numDeletions) ||
+						((repair.code == SECONDARY_CODE) && (j - k) == (repair.distance - repair.numDeletions))) {
+						repair.code = DELETION_CODE;
+						repair.distance = j;
+						repair.stackPosition = top;
+						repair.bufferPosition = i;
+						repair.numDeletions = k;
+						repair.recoveryOnNextStack = stack_flag;
+					}
+				}
+
+				for (int l = Parser.nasi(stck[top]); l >= 0 && Parser.nasr[l] != 0; l++) {
+					int symbol = Parser.nasr[l] + NT_OFFSET;
+					j = parseCheck(stck, top, symbol, i);
+					if (j == MAX_DISTANCE) {
+						 j = last_index;
+					}
+					if ((j - i + 1) > MIN_DISTANCE) {
+						int k = stack_deletions + i - 1;
+						if (k < repair.numDeletions || (j - k) > (repair.distance - repair.numDeletions)) {
+							repair.code = SECONDARY_CODE;
+							repair.symbol = symbol;
+							repair.distance = j;
+							repair.stackPosition = top;
+							repair.bufferPosition = i;
+							repair.numDeletions = k;
+							repair.recoveryOnNextStack = stack_flag;
+						}
+					}
+				}
+			}
+		}
+
+		return repair;
+	}
+
+
+//
+//	   This procedure is invoked to issue a secondary diagnosis and
+//	   adjust the input buffer.  The recovery in question is either
+//	   an automatic scope recovery, a manual scope recovery, a
+//	   secondary substitution or a secondary deletion.
+//
+	private void secondaryDiagnosis(SecondaryRepairInfo repair) {
+		switch(repair.code) {
+			case SCOPE_CODE: {
+	            if (repair.stackPosition < this.stateStackTop) {
+	                reportError(DELETION_CODE,
+	                            Parser.terminal_index[ERROR_SYMBOL],
+	                            this.locationStack[repair.stackPosition],
+	                            this.buffer[1]);
+	            }
+	            for (int i = 0; i < this.scopeStackTop; i++) {
+	                reportError(SCOPE_CODE,
+	                            -this.scopeIndex[i],
+	                            this.locationStack[this.scopePosition[i]],
+	                            this.buffer[1],
+	                            Parser.non_terminal_index[Parser.scope_lhs[this.scopeIndex[i]]]);
+	            }
+
+	            repair.symbol = Parser.scope_lhs[this.scopeIndex[this.scopeStackTop]] + NT_OFFSET;
+	            this.stateStackTop = this.scopePosition[this.scopeStackTop];
+	            reportError(SCOPE_CODE,
+	                        -this.scopeIndex[this.scopeStackTop],
+	                        this.locationStack[this.scopePosition[this.scopeStackTop]],
+	                        this.buffer[1],
+	                        getNtermIndex(this.stack[this.stateStackTop],
+	                                      repair.symbol,
+	                                      repair.bufferPosition)
+	                       );
+	            break;
+	        }
+			default: {
+				reportError(repair.code,
+							(repair.code == SECONDARY_CODE
+										  ? getNtermIndex(this.stack[repair.stackPosition],
+														  repair.symbol,
+														  repair.bufferPosition)
+										  : Parser.terminal_index[ERROR_SYMBOL]),
+							this.locationStack[repair.stackPosition],
+							this.buffer[repair.bufferPosition - 1]);
+				this.stateStackTop = repair.stackPosition;
+			}
+		}
+	}
+
+
+
+
+//
+//	   Try to parse until first_token and all tokens in BUFFER have
+//	   been consumed, or an error is encountered. Return the number
+//	   of tokens that were expended before the parse blocked.
+//
+	private int parseCheck(int stck[], int stack_top, int first_token, int buffer_position) {
+		int max_pos;
+		int indx;
+		int ct;
+		int act;
+
+		//
+		// Initialize pointer for temp_stack and initialize maximum
+		// position of state stack that is still useful.
+		//
+		act = stck[stack_top];
+		if (first_token > NT_OFFSET) {
+			this.tempStackTop = stack_top;
+			if(this.DEBUG_PARSECHECK) {
+				System.out.println(this.tempStackTop);
+			}
+			max_pos = stack_top;
+			indx = buffer_position;
+			ct = this.lexStream.kind(this.buffer[indx]);
+			this.lexStream.reset(this.lexStream.next(this.buffer[indx]));
+			int lhs_symbol = first_token - NT_OFFSET;
+			act = Parser.ntAction(act, lhs_symbol);
+			if (act <= NUM_RULES) {
+				// same loop as 'process_non_terminal'
+				do {
+					this.tempStackTop -= (Parser.rhs[act]-1);
+
+					if(this.DEBUG_PARSECHECK) {
+						System.out.print(this.tempStackTop);
+						System.out.print(" ("); //$NON-NLS-1$
+						System.out.print(-(Parser.rhs[act]-1));
+						System.out.print(") [max:"); //$NON-NLS-1$
+						System.out.print(max_pos);
+						System.out.print("]\tprocess_non_terminal\t"); //$NON-NLS-1$
+						System.out.print(act);
+						System.out.print("\t"); //$NON-NLS-1$
+						System.out.print(Parser.name[Parser.non_terminal_index[Parser.lhs[act]]]);
+						System.out.println();
+					}
+
+					if(Parser.rules_compliance[act] > this.options.sourceLevel) {
+					 	return 0;
+					}
+					lhs_symbol = Parser.lhs[act];
+					act = (this.tempStackTop > max_pos
+										  ? this.tempStack[this.tempStackTop]
+										  : stck[this.tempStackTop]);
+					act = Parser.ntAction(act, lhs_symbol);
+				} while(act <= NUM_RULES);
+
+				max_pos = max_pos < this.tempStackTop ? max_pos : this.tempStackTop;
+			}
+		} else {
+			this.tempStackTop = stack_top - 1;
+
+			if(this.DEBUG_PARSECHECK) {
+				System.out.println(this.tempStackTop);
+			}
+
+			max_pos = this.tempStackTop;
+			indx = buffer_position - 1;
+			ct = first_token;
+			this.lexStream.reset(this.buffer[buffer_position]);
+		}
+
+		process_terminal: for (;;) {
+			if(this.DEBUG_PARSECHECK) {
+				System.out.print(this.tempStackTop + 1);
+				System.out.print(" (+1) [max:"); //$NON-NLS-1$
+				System.out.print(max_pos);
+				System.out.print("]\tprocess_terminal    \t"); //$NON-NLS-1$
+				System.out.print(ct);
+				System.out.print("\t"); //$NON-NLS-1$
+				System.out.print(Parser.name[Parser.terminal_index[ct]]);
+				System.out.println();
+			}
+
+			if (++this.tempStackTop >= this.stackLength)  // Stack overflow!!!
+				return indx;
+			this.tempStack[this.tempStackTop] = act;
+
+			act = Parser.tAction(act, ct);
+
+			if (act <= NUM_RULES) {               // reduce action
+				this.tempStackTop--;
+
+				if(this.DEBUG_PARSECHECK) {
+					System.out.print(this.tempStackTop);
+					System.out.print(" (-1) [max:"); //$NON-NLS-1$
+					System.out.print(max_pos);
+					System.out.print("]\treduce"); //$NON-NLS-1$
+					System.out.println();
+				}
+			} else if (act < ACCEPT_ACTION ||     // shift action
+					 act > ERROR_ACTION) {        // shift-reduce action
+				if (indx == MAX_DISTANCE)
+					return indx;
+				indx++;
+				ct = this.lexStream.kind(this.buffer[indx]);
+				this.lexStream.reset(this.lexStream.next(this.buffer[indx]));
+				if (act > ERROR_ACTION) {
+					act -= ERROR_ACTION;
+
+					if(this.DEBUG_PARSECHECK) {
+						System.out.print(this.tempStackTop);
+						System.out.print("\tshift reduce"); //$NON-NLS-1$
+						System.out.println();
+					}
+				} else {
+					if(this.DEBUG_PARSECHECK) {
+						System.out.println("\tshift"); //$NON-NLS-1$
+					}
+					continue process_terminal;
+				}
+			} else if (act == ACCEPT_ACTION) {           // accept action
+				 return MAX_DISTANCE;
+			} else {
+				return indx;                         // error action
+			}
+
+			// same loop as first token initialization
+			// process_non_terminal:
+			do {
+				this.tempStackTop -= (Parser.rhs[act]-1);
+
+				if(this.DEBUG_PARSECHECK) {
+					System.out.print(this.tempStackTop);
+					System.out.print(" ("); //$NON-NLS-1$
+					System.out.print(-(Parser.rhs[act]-1));
+					System.out.print(") [max:"); //$NON-NLS-1$
+					System.out.print(max_pos);
+					System.out.print("]\tprocess_non_terminal\t"); //$NON-NLS-1$
+					System.out.print(act);
+					System.out.print("\t"); //$NON-NLS-1$
+					System.out.print(Parser.name[Parser.non_terminal_index[Parser.lhs[act]]]);
+					System.out.println();
+				}
+
+				if(act <= NUM_RULES) {
+					if(Parser.rules_compliance[act] > this.options.sourceLevel) {
+					 	return 0;
+					}
+				}
+				int lhs_symbol = Parser.lhs[act];
+				act = (this.tempStackTop > max_pos
+									  ? this.tempStack[this.tempStackTop]
+									  : stck[this.tempStackTop]);
+				act = Parser.ntAction(act, lhs_symbol);
+			} while(act <= NUM_RULES);
+
+			max_pos = max_pos < this.tempStackTop ? max_pos : this.tempStackTop;
+		} // process_terminal;
+	}
+	private void reportError(int msgCode, int nameIndex, int leftToken, int rightToken) {
+		reportError(msgCode, nameIndex, leftToken, rightToken, 0);
+	}
+
+	private void reportError(int msgCode, int nameIndex, int leftToken, int rightToken, int scopeNameIndex) {
+		int lToken = (leftToken > rightToken ? rightToken : leftToken);
+
+		if (lToken < rightToken) {
+			reportSecondaryError(msgCode, nameIndex, lToken, rightToken, scopeNameIndex);
+		} else {
+			reportPrimaryError(msgCode, nameIndex, rightToken, scopeNameIndex);
+		}
+	}
+
+	private void reportPrimaryError(int msgCode, int nameIndex, int token, int scopeNameIndex) {
+		String name;
+		if (nameIndex >= 0) {
+			name = Parser.readableName[nameIndex];
+		} else {
+			name = Util.EMPTY_STRING;
+		}
+
+		int errorStart = this.lexStream.start(token);
+		int errorEnd = this.lexStream.end(token);
+		int currentKind = this.lexStream.kind(token);
+		String errorTokenName = Parser.name[Parser.terminal_index[this.lexStream.kind(token)]];
+		char[] errorTokenSource = this.lexStream.name(token);
+		if (currentKind == TerminalTokens.TokenNameStringLiteral) {
+			errorTokenSource = displayEscapeCharacters(errorTokenSource, 1, errorTokenSource.length - 1);
+		}
+
+		int addedToken = -1;
+		if(this.recoveryScanner != null) {
+			if (nameIndex >= 0) {
+				addedToken = Parser.reverse_index[nameIndex];
+			}
+		}
+		switch(msgCode) {
+			case BEFORE_CODE:
+				if(this.recoveryScanner != null) {
+					if(addedToken > -1) {
+						this.recoveryScanner.insertToken(addedToken, -1, errorStart);
+					} else {
+						int[] template = getNTermTemplate(-addedToken);
+						if(template != null) {
+							this.recoveryScanner.insertTokens(template, -1, errorStart);
+						}
+					}
+				}
+				if(this.reportProblem) problemReporter().parseErrorInsertBeforeToken(
+					errorStart,
+					errorEnd,
+					currentKind,
+					errorTokenSource,
+					errorTokenName,
+					name);
+				 break;
+			case INSERTION_CODE:
+				if(this.recoveryScanner != null) {
+					if(addedToken > -1) {
+						this.recoveryScanner.insertToken(addedToken, -1, errorEnd);
+					} else {
+						int[] template = getNTermTemplate(-addedToken);
+						if(template != null) {
+							this.recoveryScanner.insertTokens(template, -1, errorEnd);
+						}
+					}
+				}
+				if(this.reportProblem) problemReporter().parseErrorInsertAfterToken(
+					errorStart,
+					errorEnd,
+					currentKind,
+					errorTokenSource,
+					errorTokenName,
+					name);
+				 break;
+			case DELETION_CODE:
+				if(this.recoveryScanner != null) {
+					this.recoveryScanner.removeTokens(errorStart, errorEnd);
+				}
+				if(this.reportProblem) problemReporter().parseErrorDeleteToken(
+					errorStart,
+					errorEnd,
+					currentKind,
+					errorTokenSource,
+					errorTokenName);
+				break;
+			case INVALID_CODE:
+				if (name.length() == 0) {
+					if(this.recoveryScanner != null) {
+						this.recoveryScanner.removeTokens(errorStart, errorEnd);
+					}
+					if(this.reportProblem) problemReporter().parseErrorReplaceToken(
+						errorStart,
+						errorEnd,
+						currentKind,
+						errorTokenSource,
+						errorTokenName,
+						name);
+				} else {
+					if(this.recoveryScanner != null) {
+						if(addedToken > -1) {
+							this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+						} else {
+							int[] template = getNTermTemplate(-addedToken);
+							if(template != null) {
+								this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+							}
+						}
+					}
+					if(this.reportProblem) problemReporter().parseErrorInvalidToken(
+						errorStart,
+						errorEnd,
+						currentKind,
+						errorTokenSource,
+						errorTokenName,
+						name);
+				}
+				break;
+			case SUBSTITUTION_CODE:
+				if(this.recoveryScanner != null) {
+					if(addedToken > -1) {
+						this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+					} else {
+						int[] template = getNTermTemplate(-addedToken);
+						if(template != null) {
+							this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+						}
+					}
+				}
+				if(this.reportProblem) problemReporter().parseErrorReplaceToken(
+					errorStart,
+					errorEnd,
+					currentKind,
+					errorTokenSource,
+					errorTokenName,
+					name);
+				 break;
+			case SCOPE_CODE:
+				StringBuffer buf = new StringBuffer();
+
+				int[] addedTokens = null;
+	            int addedTokenCount = 0;
+	            if(this.recoveryScanner != null) {
+	            	addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]];
+	            }
+
+	            int insertedToken = TokenNameNotAToken;
+				for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
+					buf.append(Parser.readableName[Parser.scope_rhs[i]]);
+					if (Parser.scope_rhs[i + 1] != 0) // any more symbols to print?
+						buf.append(' ');
+					else
+						insertedToken = Parser.reverse_index[Parser.scope_rhs[i]];
+
+					if(addedTokens != null) {
+	                	int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]];
+		                if (tmpAddedToken > -1) {
+		                	int length = addedTokens.length;
+		                	if(addedTokenCount == length) {
+		                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
+		                	}
+		                	addedTokens[addedTokenCount++] = tmpAddedToken;
+		                } else {
+		                	int[] template = getNTermTemplate(-tmpAddedToken);
+		                	if(template != null) {
+			                	for (int j = 0; j < template.length; j++) {
+									int length = addedTokens.length;
+		                			if(addedTokenCount == length) {
+				                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
+				                	}
+		                			addedTokens[addedTokenCount++] = template[j];
+								}
+		                	} else {
+			                	addedTokenCount = 0;
+			                	addedTokens = null;
+		                	}
+		                }
+	                }
+				}
+
+				if(addedTokenCount > 0) {
+	            	System.arraycopy(addedTokens, 0, addedTokens = new int[addedTokenCount], 0, addedTokenCount);
+
+	            	int completedToken = -1;
+	            	if(scopeNameIndex != 0) {
+	            		completedToken = -Parser.reverse_index[scopeNameIndex];
+	            	}
+	            	this.recoveryScanner.insertTokens(addedTokens, completedToken, errorEnd);
+	            }
+
+				if (scopeNameIndex != 0) {
+					if (insertedToken == TokenNameElidedSemicolonAndRightBrace) {
+						/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=383046, we should never ever report the diagnostic, "Syntax error, insert ElidedSemicolonAndRightBraceto complete LambdaBody"
+						   as it is a synthetic token. Instead we should simply repair and move on. See how the regular Parser behaves at Parser.consumeElidedLeftBraceAndReturn and Parser.consumeExpression.
+						   See also: point (4) in https://bugs.eclipse.org/bugs/show_bug.cgi?id=380194#c15
+						*/
+						break;
+					}
+					if(this.reportProblem) problemReporter().parseErrorInsertToComplete(
+						errorStart,
+						errorEnd,
+						buf.toString(),
+						Parser.readableName[scopeNameIndex]);
+				} else {
+					if(this.reportProblem) problemReporter().parseErrorInsertToCompleteScope(
+						errorStart,
+						errorEnd,
+						buf.toString());
+				}
+
+				break;
+			case EOF_CODE:
+				if(this.reportProblem) problemReporter().parseErrorUnexpectedEnd(
+					errorStart,
+					errorEnd);
+				break;
+			case MERGE_CODE:
+				if(this.recoveryScanner != null) {
+					if(addedToken > -1) {
+						this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+					} else {
+						int[] template = getNTermTemplate(-addedToken);
+						if(template != null) {
+							this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+						}
+					}
+				}
+				if(this.reportProblem) problemReporter().parseErrorMergeTokens(
+					errorStart,
+					errorEnd,
+					name);
+				break;
+			case MISPLACED_CODE:
+				if(this.recoveryScanner != null) {
+					this.recoveryScanner.removeTokens(errorStart, errorEnd);
+				}
+				if(this.reportProblem) problemReporter().parseErrorMisplacedConstruct(
+					errorStart,
+					errorEnd);
+				break;
+			default:
+				if (name.length() == 0) {
+					if(this.recoveryScanner != null) {
+						this.recoveryScanner.removeTokens(errorStart, errorEnd);
+					}
+					if(this.reportProblem) problemReporter().parseErrorNoSuggestion(
+						errorStart,
+						errorEnd,
+						currentKind,
+						errorTokenSource,
+						errorTokenName);
+				} else {
+					if(this.recoveryScanner != null) {
+						if(addedToken > -1) {
+							this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+						} else {
+							int[] template = getNTermTemplate(-addedToken);
+							if(template != null) {
+								this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+							}
+						}
+					}
+					if(this.reportProblem) problemReporter().parseErrorReplaceToken(
+						errorStart,
+						errorEnd,
+						currentKind,
+						errorTokenSource,
+						errorTokenName,
+						name);
+				}
+				break;
+		}
+	}
+
+	private void reportSecondaryError(int msgCode,	int nameIndex,	int leftToken,	int rightToken, int scopeNameIndex) {
+		String name;
+		if (nameIndex >= 0) {
+			name = Parser.readableName[nameIndex];
+		} else {
+			name = Util.EMPTY_STRING;
+		}
+
+		int errorStart = -1;
+		if(this.lexStream.isInsideStream(leftToken)) {
+			if(leftToken == 0) {
+				errorStart = this.lexStream.start(leftToken + 1);
+			} else {
+				errorStart = this.lexStream.start(leftToken);
+			}
+		} else {
+			if(leftToken == this.errorToken) {
+				errorStart = this.errorTokenStart;
+			} else {
+				for (int i = 0; i <= this.stateStackTop; i++) {
+					if(this.locationStack[i] == leftToken) {
+						errorStart = this.locationStartStack[i];
+					}
+				}
+			}
+			if(errorStart == -1) {
+				errorStart = this.lexStream.start(rightToken);
+			}
+		}
+		int errorEnd = this.lexStream.end(rightToken);
+
+		int addedToken = -1;
+		if(this.recoveryScanner != null) {
+			if (nameIndex >= 0) {
+				addedToken = Parser.reverse_index[nameIndex];
+			}
+		}
+
+		switch(msgCode) {
+			case MISPLACED_CODE:
+				if(this.recoveryScanner != null) {
+					this.recoveryScanner.removeTokens(errorStart, errorEnd);
+				}
+				if(this.reportProblem) problemReporter().parseErrorMisplacedConstruct(
+					errorStart,
+					errorEnd);
+				break;
+			case SCOPE_CODE:
+				// error start is on the last token start
+				errorStart = this.lexStream.start(rightToken);
+
+	            StringBuffer buf = new StringBuffer();
+
+	            int[] addedTokens = null;
+	            int addedTokenCount = 0;
+	            if(this.recoveryScanner != null) {
+	            	addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]];
+	            }
+	            int insertedToken = TokenNameNotAToken;
+	            for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) {
+
+	                buf.append(Parser.readableName[Parser.scope_rhs[i]]);
+	                if (Parser.scope_rhs[i+1] != 0)
+	                     buf.append(' ');
+	                else
+	                	insertedToken = Parser.reverse_index[Parser.scope_rhs[i]];
+
+	                if(addedTokens != null) {
+	                	int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]];
+		                if (tmpAddedToken > -1) {
+		                	int length = addedTokens.length;
+		                	if(addedTokenCount == length) {
+		                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
+		                	}
+		                	addedTokens[addedTokenCount++] = tmpAddedToken;
+		                } else {
+		                	int[] template = getNTermTemplate(-tmpAddedToken);
+		                	if(template != null) {
+			                	for (int j = 0; j < template.length; j++) {
+									int length = addedTokens.length;
+		                			if(addedTokenCount == length) {
+				                		System.arraycopy(addedTokens, 0, addedTokens = new int[length * 2], 0, length);
+				                	}
+		                			addedTokens[addedTokenCount++] = template[j];
+								}
+		                	} else {
+			                	addedTokenCount = 0;
+			                	addedTokens = null;
+		                	}
+		                }
+	                }
+	            }
+	            if(addedTokenCount > 0) {
+	            	System.arraycopy(addedTokens, 0, addedTokens = new int[addedTokenCount], 0, addedTokenCount);
+	            	int completedToken = -1;
+	            	if(scopeNameIndex != 0) {
+	            		completedToken = -Parser.reverse_index[scopeNameIndex];
+	            	}
+	            	this.recoveryScanner.insertTokens(addedTokens, completedToken, errorEnd);
+	            }
+	            if (scopeNameIndex != 0) {
+	            	if (insertedToken == TokenNameElidedSemicolonAndRightBrace) {
+						/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=383046, we should never ever report the diagnostic, "Syntax error, insert ElidedSemicolonAndRightBraceto complete LambdaBody"
+						   as it is a synthetic token. Instead we should simply repair and move on. See how the regular Parser behaves at Parser.consumeElidedLeftBraceAndReturn and Parser.consumeExpression.
+						   See also: point (4) in https://bugs.eclipse.org/bugs/show_bug.cgi?id=380194#c15
+						*/
+						break;
+					}
+	                if(this.reportProblem) problemReporter().parseErrorInsertToComplete(
+						errorStart,
+						errorEnd,
+						buf.toString(),
+						Parser.readableName[scopeNameIndex]);
+	            } else {
+	            	if(this.reportProblem) problemReporter().parseErrorInsertToCompletePhrase(
+						errorStart,
+						errorEnd,
+						buf.toString());
+	            }
+	            break;
+			case MERGE_CODE:
+				if(this.recoveryScanner != null) {
+					if(addedToken > -1) {
+						this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+					} else {
+						int[] template = getNTermTemplate(-addedToken);
+						if(template != null) {
+							this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+						}
+					}
+				}
+				if(this.reportProblem) problemReporter().parseErrorMergeTokens(
+					errorStart,
+					errorEnd,
+					name);
+				break;
+			case DELETION_CODE:
+				if(this.recoveryScanner != null) {
+					this.recoveryScanner.removeTokens(errorStart, errorEnd);
+				}
+				if(this.reportProblem) problemReporter().parseErrorDeleteTokens(
+					errorStart,
+					errorEnd);
+				break;
+			default:
+				if (name.length() == 0) {
+					if(this.recoveryScanner != null) {
+						this.recoveryScanner.removeTokens(errorStart, errorEnd);
+					}
+					if(this.reportProblem) problemReporter().parseErrorNoSuggestionForTokens(
+						errorStart,
+						errorEnd);
+				} else {
+					if(this.recoveryScanner != null) {
+						if(addedToken > -1) {
+							this.recoveryScanner.replaceTokens(addedToken, errorStart, errorEnd);
+						} else {
+							int[] template = getNTermTemplate(-addedToken);
+							if(template != null) {
+								this.recoveryScanner.replaceTokens(template, errorStart, errorEnd);
+							}
+						}
+					}
+					if(this.reportProblem) problemReporter().parseErrorReplaceTokens(
+						errorStart,
+						errorEnd,
+						name);
+				}
+		}
+		return;
+	}
+
+	private int[] getNTermTemplate(int sym) {
+		int templateIndex = Parser.recovery_templates_index[sym];
+    	if(templateIndex > 0) {
+    		int[] result = new int[Parser.recovery_templates.length];
+    		int count = 0;
+    		for(int j = templateIndex; Parser.recovery_templates[j] != 0; j++) {
+    			result[count++] = Parser.recovery_templates[j];
+    		}
+    		System.arraycopy(result, 0, result = new int[count], 0, count);
+    		return result;
+    	} else {
+        	return null;
+    	}
+	}
+
+	public String toString() {
+		StringBuffer res = new StringBuffer();
+
+		res.append(this.lexStream.toString());
+
+		return res.toString();
+	}
+
+	public boolean atConflictScenario(int token) {
+		/* There is too much voodoo that goes on here in DiagnoseParser (multiple machines, lexer stream reset etc.)
+		   So we take a simple minded view that we will always ask for disambiguation, except there is one scenario 
+		   that needs special handling, we let the lexer stream deal with that: In X<String>.Y<Integer>:: the second
+		   '<' should not be tagged for disambiguation. If a synthetic token gets injected there, there will be syntax
+		   error. See that this is not a problem for the regular/normal parser.
+		*/ 
+		return (token == TokenNameLPAREN || token == TokenNameAT || (token == TokenNameLESS && !this.lexStream.awaitingColonColon()));
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java
new file mode 100644
index 0000000..601308f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser.diagnose;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class LexStream implements TerminalTokens {
+	public static final int IS_AFTER_JUMP = 1;
+	public static final int LBRACE_MISSING = 2;
+
+	public static class Token{
+		int kind;
+		char[] name;
+		int start;
+		int end;
+		int line;
+		int flags;
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(this.name).append('[').append(this.kind).append(']');
+			buffer.append('{').append(this.start).append(',').append(this.end).append('}').append(this.line);
+			return buffer.toString();
+		}
+
+	}
+
+	private int tokenCacheIndex;
+	private int tokenCacheEOFIndex;
+	private Token[] tokenCache;
+
+	private int currentIndex = -1;
+
+	private Scanner scanner;
+	private int[] intervalStartToSkip;
+	private int[] intervalEndToSkip;
+	private int[] intervalFlagsToSkip;
+
+	private int previousInterval = -1;
+	private int currentInterval = -1;
+	private boolean awaitingColonColon;
+
+	public LexStream(int size, Scanner scanner, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, int firstToken, int init, int eof) {
+		this.tokenCache = new Token[size];
+		this.tokenCacheIndex = 0;
+		this.tokenCacheEOFIndex = Integer.MAX_VALUE;
+		this.tokenCache[0] = new Token();
+		this.tokenCache[0].kind = firstToken;
+		this.tokenCache[0].name = CharOperation.NO_CHAR;
+		this.tokenCache[0].start = init;
+		this.tokenCache[0].end = init;
+		this.tokenCache[0].line = 0;
+
+		this.intervalStartToSkip = intervalStartToSkip;
+		this.intervalEndToSkip = intervalEndToSkip;
+		this.intervalFlagsToSkip = intervalFlagsToSkip;
+		this.awaitingColonColon = false;
+		scanner.resetTo(init, eof);
+		this.scanner = scanner;
+	}
+
+	private void readTokenFromScanner(){
+		int length = this.tokenCache.length;
+		boolean tokenNotFound = true;
+
+		while(tokenNotFound) {
+			try {
+				int tokenKind =  this.scanner.getNextToken();
+				if (tokenKind == TokenNameBeginTypeArguments) {
+					this.awaitingColonColon = true;
+				} else if (tokenKind == TokenNameCOLON_COLON) {
+					this.awaitingColonColon = false;
+				}
+				if(tokenKind != TokenNameEOF) {
+					int start = this.scanner.getCurrentTokenStartPosition();
+					int end = this.scanner.getCurrentTokenEndPosition();
+
+					int nextInterval = this.currentInterval + 1;
+					if(this.intervalStartToSkip.length == 0 ||
+							nextInterval >= this.intervalStartToSkip.length ||
+							start < this.intervalStartToSkip[nextInterval]) {
+						Token token = new Token();
+						token.kind = tokenKind;
+						token.name = this.scanner.getCurrentTokenSource();
+						token.start = start;
+						token.end = end;
+						token.line = Util.getLineNumber(end, this.scanner.lineEnds, 0, this.scanner.linePtr);
+
+						if(this.currentInterval != this.previousInterval && (this.intervalFlagsToSkip[this.currentInterval] & RangeUtil.IGNORE) == 0){
+							token.flags = IS_AFTER_JUMP;
+							if((this.intervalFlagsToSkip[this.currentInterval] & RangeUtil.LBRACE_MISSING) != 0){
+								token.flags |= LBRACE_MISSING;
+							}
+						}
+						this.previousInterval = this.currentInterval;
+
+						this.tokenCache[++this.tokenCacheIndex % length] = token;
+
+						tokenNotFound = false;
+					} else {
+						this.scanner.resetTo(this.intervalEndToSkip[++this.currentInterval] + 1, this.scanner.eofPosition - 1);
+					}
+				} else {
+					int start = this.scanner.getCurrentTokenStartPosition();
+					int end = this.scanner.getCurrentTokenEndPosition();
+					Token token = new Token();
+					token.kind = tokenKind;
+					token.name = CharOperation.NO_CHAR;
+					token.start = start;
+					token.end = end;
+					token.line = Util.getLineNumber(end, this.scanner.lineEnds, 0, this.scanner.linePtr);
+
+					this.tokenCache[++this.tokenCacheIndex % length] = token;
+
+					this.tokenCacheEOFIndex = this.tokenCacheIndex;
+					tokenNotFound = false;
+				}
+			} catch (InvalidInputException e) {
+				// return next token
+			}
+		}
+	}
+
+	public Token token(int index) {
+		if(index < 0) {
+			Token eofToken = new Token();
+			eofToken.kind = TokenNameEOF;
+			eofToken.name = CharOperation.NO_CHAR;
+			return eofToken;
+		}
+		if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
+			return token(this.tokenCacheEOFIndex);
+		}
+		int length = this.tokenCache.length;
+		if(index > this.tokenCacheIndex) {
+			int tokensToRead = index - this.tokenCacheIndex;
+			while(tokensToRead-- != 0) {
+				readTokenFromScanner();
+			}
+		} else if(this.tokenCacheIndex - length >= index) {
+			return null;
+		}
+
+		return this.tokenCache[index % length];
+	}
+
+
+
+	public int getToken() {
+		return this.currentIndex = next(this.currentIndex);
+	}
+
+	public int previous(int tokenIndex) {
+		return tokenIndex > 0 ? tokenIndex - 1 : 0;
+	}
+
+	public int next(int tokenIndex) {
+		return tokenIndex < this.tokenCacheEOFIndex ? tokenIndex + 1 : this.tokenCacheEOFIndex;
+	}
+
+	public boolean afterEol(int i) {
+		return i < 1 ? true : line(i - 1) < line(i);
+	}
+
+	public void reset() {
+		this.currentIndex = -1;
+	}
+
+	public void reset(int i) {
+		this.currentIndex = previous(i);
+	}
+
+	public int badtoken() {
+		return 0;
+	}
+
+	public int kind(int tokenIndex) {
+		return token(tokenIndex).kind;
+	}
+
+	public char[] name(int tokenIndex) {
+		return token(tokenIndex).name;
+	}
+
+	public int line(int tokenIndex) {
+		return token(tokenIndex).line;
+	}
+
+	public int start(int tokenIndex) {
+		return token(tokenIndex).start;
+	}
+
+	public int end(int tokenIndex) {
+		return token(tokenIndex).end;
+	}
+
+	public int flags(int tokenIndex) {
+		return token(tokenIndex).flags;
+	}
+
+	public boolean isInsideStream(int index) {
+		if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
+			return false;
+		} else if(index > this.tokenCacheIndex) {
+			return true;
+		} else if(this.tokenCacheIndex - this.tokenCache.length >= index) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer res = new StringBuffer();
+
+		String source = new String(this.scanner.source);
+		if(this.currentIndex < 0) {
+			int previousEnd = -1;
+			for (int i = 0; i < this.intervalStartToSkip.length; i++) {
+				int intervalStart = this.intervalStartToSkip[i];
+				int intervalEnd = this.intervalEndToSkip[i];
+
+				res.append(source.substring(previousEnd + 1, intervalStart));
+				res.append('<');
+				res.append('@');
+				res.append(source.substring(intervalStart, intervalEnd + 1));
+				res.append('@');
+				res.append('>');
+
+				previousEnd = intervalEnd;
+			}
+			res.append(source.substring(previousEnd + 1));
+		} else {
+			Token token = token(this.currentIndex);
+			int curtokKind = token.kind;
+			int curtokStart = token.start;
+			int curtokEnd = token.end;
+
+			int previousEnd = -1;
+			for (int i = 0; i < this.intervalStartToSkip.length; i++) {
+				int intervalStart = this.intervalStartToSkip[i];
+				int intervalEnd = this.intervalEndToSkip[i];
+
+				if(curtokStart >= previousEnd && curtokEnd <= intervalStart) {
+					res.append(source.substring(previousEnd + 1, curtokStart));
+					res.append('<');
+					res.append('#');
+					res.append(source.substring(curtokStart, curtokEnd + 1));
+					res.append('#');
+					res.append('>');
+					res.append(source.substring(curtokEnd+1, intervalStart));
+				} else {
+					res.append(source.substring(previousEnd + 1, intervalStart));
+				}
+				res.append('<');
+				res.append('@');
+				res.append(source.substring(intervalStart, intervalEnd + 1));
+				res.append('@');
+				res.append('>');
+
+				previousEnd = intervalEnd;
+			}
+			if(curtokStart >= previousEnd) {
+				res.append(source.substring(previousEnd + 1, curtokStart));
+				res.append('<');
+				res.append('#');
+				if(curtokKind == TokenNameEOF) {
+					res.append("EOF#>"); //$NON-NLS-1$
+				} else {
+					res.append(source.substring(curtokStart, curtokEnd + 1));
+					res.append('#');
+					res.append('>');
+					res.append(source.substring(curtokEnd+1));
+				}
+			} else {
+				res.append(source.substring(previousEnd + 1));
+			}
+		}
+
+		return res.toString();
+	}
+
+	public boolean awaitingColonColon() {
+		return this.awaitingColonColon;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
new file mode 100644
index 0000000..d12633c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser.diagnose;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+
+public class RangeUtil {
+
+	// flags
+	public static final int NO_FLAG = 0;
+	public static final int LBRACE_MISSING = 1;
+	public static final int IGNORE = 2;
+
+	static class RangeResult {
+		private static final int INITIAL_SIZE = 10;
+		int pos;
+		int[] intervalStarts;
+		int[] intervalEnds;
+		int[] intervalFlags;
+
+		RangeResult() {
+			this.pos = 0;
+			this.intervalStarts = new int[INITIAL_SIZE];
+			this.intervalEnds = new int[INITIAL_SIZE];
+			this.intervalFlags = new int[INITIAL_SIZE];
+		}
+
+		void addInterval(int start, int end){
+			addInterval(start, end, NO_FLAG);
+		}
+
+		void addInterval(int start, int end, int flags){
+			if(this.pos >= this.intervalStarts.length) {
+				System.arraycopy(this.intervalStarts, 0, this.intervalStarts = new int[this.pos * 2], 0, this.pos);
+				System.arraycopy(this.intervalEnds, 0, this.intervalEnds = new int[this.pos * 2], 0, this.pos);
+				System.arraycopy(this.intervalFlags, 0, this.intervalFlags = new int[this.pos * 2], 0, this.pos);
+			}
+			this.intervalStarts[this.pos] = start;
+			this.intervalEnds[this.pos] = end;
+			this.intervalFlags[this.pos] = flags;
+			this.pos++;
+		}
+
+		int[][] getRanges() {
+			int[] resultStarts = new int[this.pos];
+			int[] resultEnds = new int[this.pos];
+			int[] resultFlags = new int[this.pos];
+
+			System.arraycopy(this.intervalStarts, 0, resultStarts, 0, this.pos);
+			System.arraycopy(this.intervalEnds, 0, resultEnds, 0, this.pos);
+			System.arraycopy(this.intervalFlags, 0, resultFlags, 0, this.pos);
+
+			if (resultStarts.length > 1) {
+				quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1);
+			}
+			return new int[][]{resultStarts, resultEnds, resultFlags};
+		}
+
+		private void quickSort(int[] list, int[] list2, int[] list3, int left, int right) {
+			int original_left= left;
+			int original_right= right;
+			int mid= list[left + (right - left) / 2];
+			do {
+				while (compare(list[left], mid) < 0) {
+					left++;
+				}
+				while (compare(mid, list[right]) < 0) {
+					right--;
+				}
+				if (left <= right) {
+					int tmp= list[left];
+					list[left]= list[right];
+					list[right]= tmp;
+
+					tmp = list2[left];
+					list2[left]= list2[right];
+					list2[right]= tmp;
+
+					tmp = list3[left];
+					list3[left]= list3[right];
+					list3[right]= tmp;
+
+					left++;
+					right--;
+				}
+			} while (left <= right);
+
+			if (original_left < right) {
+				quickSort(list, list2, list3, original_left, right);
+			}
+			if (left < original_right) {
+				quickSort(list, list2, list3, left, original_right);
+			}
+		}
+
+		private int compare(int i1, int i2) {
+			return i1 - i2;
+		}
+	}
+
+
+
+	public static boolean containsErrorInSignature(AbstractMethodDeclaration method){
+		return method.sourceEnd + 1 == method.bodyStart	|| method.bodyEnd == method.declarationSourceEnd;
+	}
+
+	public static int[][] computeDietRange(TypeDeclaration[] types) {
+		if(types == null || types.length == 0) {
+			return new int[3][0];
+		} else {
+			RangeResult result = new RangeResult();
+			computeDietRange0(types, result);
+			return result.getRanges();
+		}
+	}
+
+	private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) {
+		for (int j = 0; j < types.length; j++) {
+			//members
+			TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes;
+			if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) {
+				computeDietRange0(types[j].memberTypes, result);
+			}
+			//methods
+			AbstractMethodDeclaration[] methods = types[j].methods;
+			if (methods != null) {
+				int length = methods.length;
+				for (int i = 0; i < length; i++) {
+					AbstractMethodDeclaration method = methods[i];
+					if(containsIgnoredBody(method)) {
+						if(containsErrorInSignature(method)) {
+							method.bits |= ASTNode.ErrorInSignature;
+							result.addInterval(method.declarationSourceStart, method.declarationSourceEnd, IGNORE);
+						} else {
+							int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG;
+							result.addInterval(method.bodyStart, method.bodyEnd, flags);
+						}
+					}
+				}
+			}
+
+			//initializers
+			FieldDeclaration[] fields = types[j].fields;
+			if (fields != null) {
+				int length = fields.length;
+				for (int i = 0; i < length; i++) {
+					if (fields[i] instanceof Initializer) {
+						Initializer initializer = (Initializer)fields[i];
+						if(initializer.declarationSourceEnd == initializer.bodyEnd && initializer.declarationSourceStart != initializer.declarationSourceEnd){
+							initializer.bits |= ASTNode.ErrorInSignature;
+							result.addInterval(initializer.declarationSourceStart, initializer.declarationSourceEnd, IGNORE);
+						} else {
+							result.addInterval(initializer.bodyStart, initializer.bodyEnd);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	public static boolean containsIgnoredBody(AbstractMethodDeclaration method){
+		return !method.isDefaultConstructor()
+			&& !method.isClinit()
+			&& (method.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
new file mode 100644
index 0000000..212d306
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
new file mode 100644
index 0000000..7ffac87
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
new file mode 100644
index 0000000..1c4e40a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
new file mode 100644
index 0000000..f031c44
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
new file mode 100644
index 0000000..ba36431
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
new file mode 100644
index 0000000..ea13e23
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
new file mode 100644
index 0000000..22ed5e2
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
new file mode 100644
index 0000000..9bfecc3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
new file mode 100644
index 0000000..54fac52
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
new file mode 100644
index 0000000..181a981
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
new file mode 100644
index 0000000..8a6288e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
new file mode 100644
index 0000000..db1329b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
new file mode 100644
index 0000000..e11a480
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
new file mode 100644
index 0000000..4ae1fb3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc
new file mode 100644
index 0000000..2f4f817
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
new file mode 100644
index 0000000..2202064
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc
new file mode 100644
index 0000000..09da2b5
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
new file mode 100644
index 0000000..b8d394d
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
new file mode 100644
index 0000000..971374e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
new file mode 100644
index 0000000..2f03241
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
new file mode 100644
index 0000000..17ead58
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
new file mode 100644
index 0000000..5bd187c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
new file mode 100644
index 0000000..b86bce4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
new file mode 100644
index 0000000..c8c651e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props
new file mode 100644
index 0000000..27b12e1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props
@@ -0,0 +1,369 @@
+###############################################################################
+# Copyright (c) 2013 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# This is an implementation of an early-draft specification developed under the Java
+# Community Process (JCP) and is made available for testing and evaluation purposes
+# only. The code is not compatible with any specification of the JCP.
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+,opt=,
+;opt=;
+AbstractMethodDeclaration=MethodDeclaration
+AdditionalBound1=AdditionalBound1
+AdditionalBound=AdditionalBound
+AdditionalBoundList1=AdditionalBoundList1
+AdditionalBoundList=AdditionalBoundList
+AdditionalBoundsListOpt=AdditionalBoundsListOpt
+AdditiveExpression=Expression
+AdditiveExpression_NotName=Expression
+AllocationHeader=AllocationHeader
+AndExpression=Expression
+AndExpression_NotName=Expression
+Annotation=Annotation
+AnnotationMethodHeader=AnnotationMethodHeader
+AnnotationMethodHeaderDefaultValueopt=MethodHeaderDefaultValue
+AnnotationMethodHeaderName=MethodHeaderName
+AnnotationName=AnnotationName
+AnnotationTypeBody=AnnotationTypeBody
+AnnotationTypeDeclaration=AnnotationTypeDeclaration
+AnnotationTypeDeclarationHeader=AnnotationTypeDeclarationHeader
+AnnotationTypeDeclarationHeaderName=AnnotationTypeDeclarationHeaderName
+AnnotationTypeMemberDeclaration=AnnotationTypeMemberDeclaration
+AnnotationTypeMemberDeclarations=AnnotationTypeMemberDeclarations
+AnnotationTypeMemberDeclarationsopt=AnnotationTypeMemberDeclarations
+ArgumentList=ArgumentList
+ArgumentListopt=ArgumentList
+Arguments=Arguments
+Argumentsopt=Argumentsopt
+ArrayAccess=ArrayAccess
+ArrayCreationHeader=ArrayCreationHeader
+ArrayCreationWithArrayInitializer=ArrayCreationWithArrayInitializer
+ArrayCreationWithoutArrayInitializer=ArrayCreationWithoutArrayInitializer
+ArrayInitializer=ArrayInitializer
+ArrayType=ArrayType
+ArrayTypeWithTypeArgumentsName=ArrayTypeWithTypeArgumentsName
+AssertStatement=AssertStatement
+Assignment=Assignment
+AssignmentExpression=Expression
+AssignmentExpression_NotName=Expression
+AssignmentOperator=AssignmentOperator
+Block=Block
+BlockStatement=BlockStatement
+BlockStatements=BlockStatements
+BlockStatementsopt=BlockStatements
+BooleanLiteral=BooleanLiteral
+BreakStatement=BreakStatement
+CastExpression=CastExpression
+CastNameAndBounds=CastNameAndBounds
+CatchClause=CatchClause
+CatchFormalParameter=FormalParameter
+CatchHeader=CatchHeader
+CatchType=CatchType
+Catches=Catches
+Catchesopt=Catches
+ClassBody=ClassBody
+ClassBodyDeclaration=ClassBodyDeclaration
+ClassBodyDeclarations=ClassBodyDeclarations
+ClassBodyDeclarationsopt=ClassBodyDeclarations
+ClassDeclaration=ClassDeclaration
+ClassHeader=ClassHeader
+ClassHeaderExtends=ClassHeaderExtends
+ClassHeaderExtendsopt=ClassHeaderExtends
+ClassHeaderImplements=ClassHeaderImplements
+ClassHeaderImplementsopt=ClassHeaderImplements
+ClassHeaderName1=ClassHeaderName
+ClassHeaderName=ClassHeaderName
+ClassInstanceCreationExpression=ClassInstanceCreationExpression
+ClassInstanceCreationExpressionName=ClassInstanceCreationExpressionName
+ClassMemberDeclaration=ClassMemberDeclaration
+ClassOrInterface=Type
+ClassOrInterfaceType=Type
+ClassType=ClassType
+ClassTypeElt=ClassType
+ClassTypeList=ClassTypeList
+CompilationUnit=CompilationUnit
+ConditionalAndExpression=Expression
+ConditionalAndExpression_NotName=Expression
+ConditionalExpression=Expression
+ConditionalExpression_NotName=Expression
+ConditionalOrExpression=Expression
+ConditionalOrExpression_NotName=Expression
+ConstantDeclaration=ConstantDeclaration
+ConstantExpression=ConstantExpression
+ConstructorDeclaration=ConstructorDeclaration
+ConstructorHeader=ConstructorDeclaration
+ConstructorHeaderName=ConstructorHeaderName
+ContinueStatement=ContinueStatement
+CreateInitializer=CreateInitializer
+DefaultMethodHeader=MethodDeclaration
+DefaultMethodHeaderName=MethodHeaderName
+DefaultValue=DefaultValue
+Diet=Diet
+DimWithOrWithOutExpr=Dimension
+DimWithOrWithOutExprs=Dimensions
+Dims=Dimensions
+DimsLoop=Dimensions
+Dimsopt=Dimensions
+DoStatement=DoStatement
+ElidedLeftBraceAndReturn=ElidedLeftBraceAndReturn
+EmptyStatement=EmptyStatement
+EnhancedForStatement=EnhancedForStatement
+EnhancedForStatementHeader=EnhancedForStatementHeader
+EnhancedForStatementHeaderInit=EnhancedForStatementHeaderInit
+EnhancedForStatementNoShortIf=EnhancedForStatementNoShortIf
+EnterCompilationUnit=EnterCompilationUnit
+EnterInstanceCreationArgumentList=EnterInstanceCreationArgumentList
+EnterMemberValue=EnterMemberValue
+EnterMemberValueArrayInitializer=EnterMemberValueArrayInitializer
+EnterVariable=EnterVariable
+EnumBody=EnumBody
+EnumBodyDeclarationsopt=EnumBodyDeclarationsopt
+EnumConstant=EnumConstant
+EnumConstantHeader=EnumConstantHeader
+EnumConstantHeaderName=EnumConstantHeaderName
+EnumConstants=EnumConstants
+EnumDeclaration=EnumDeclaration
+EnumDeclarations=EnumDeclarations
+EnumHeader=EnumHeader
+EnumHeaderName=EnumHeaderName
+EqualityExpression=Expression
+EqualityExpression_NotName=Expression
+ExclusiveOrExpression=Expression
+ExclusiveOrExpression_NotName=Expression
+ExitMemberValue=ExitMemberValue
+ExitTryBlock=ExitTryBlock
+ExitVariableWithInitialization=ExitVariableWithInitialization
+ExitVariableWithoutInitialization=ExitVariableWithoutInitialization
+ExplicitConstructorInvocation=ExplicitConstructorInvocation
+Expression=Expression
+ExpressionStatement=Statement
+Expression_NotName=Expression
+Expressionopt=Expression
+FieldAccess=FieldAccess
+FieldDeclaration=FieldDeclaration
+Finally=Finally
+FloatingPointType=FloatingPointType
+ForInit=ForInit
+ForInitopt=ForInit
+ForStatement=ForStatement
+ForStatementNoShortIf=ForStatement
+ForUpdate=ForUpdate
+ForUpdateopt=ForUpdate
+ForceNoDiet=ForceNoDiet
+FormalParameter=FormalParameter
+FormalParameterList=FormalParameterList
+FormalParameterListopt=FormalParameterList
+GenericMethodDeclaration=GenericMethodDeclaration
+GenericType=GenericType
+Goal=Goal
+Header1=Header1
+Header2=Header2
+Header=Header
+IdentifierOrNew=IdentifierOrNew
+IfThenElseStatement=IfStatement
+IfThenElseStatementNoShortIf=IfStatement
+IfThenStatement=IfStatement
+ImportDeclaration=ImportDeclaration
+ImportDeclarations=ImportDeclarations
+InclusiveOrExpression=Expression
+InclusiveOrExpression_NotName=Expression
+Initializer=Initializer
+InsideCastExpression=InsideCastExpression
+InsideCastExpressionLL1=InsideCastExpression
+InsideCastExpressionLL1WithBounds=InsideCastExpression
+InsideCastExpressionWithQualifiedGenerics=InsideCastExpression
+InstanceofExpression=Expression
+InstanceofExpression_NotName=Expression
+IntegralType=IntegralType
+InterfaceBody=InterfaceBody
+InterfaceDeclaration=InterfaceDeclaration
+InterfaceHeader=InterfaceHeader
+InterfaceHeaderExtends=InterfaceHeaderExtends
+InterfaceHeaderExtendsopt=InterfaceHeaderExtends
+InterfaceHeaderName1=InterfaceHeaderName
+InterfaceHeaderName=InterfaceHeaderName
+InterfaceMemberDeclaration=InterfaceMemberDeclaration
+InterfaceMemberDeclarations=InterfaceMemberDeclarations
+InterfaceMemberDeclarationsopt=InterfaceMemberDeclarations
+InterfaceType=InterfaceType
+InterfaceTypeList=InterfaceTypeList
+InternalCompilationUnit=CompilationUnit
+InvalidArrayInitializerAssignement=ArrayInitializerAssignment
+InvalidConstructorDeclaration=InvalidConstructorDeclaration
+InvalidInitializer=InvalidInitializer
+Label=Label
+LabeledStatement=LabeledStatement
+LabeledStatementNoShortIf=LabeledStatement
+LambdaBody=LambdaBody
+LambdaExpression=LambdaExpression
+LambdaParameterList=LambdaParameterList
+LambdaParameters=TypeElidedFormalParameter
+Literal=Literal
+LocalVariableDeclaration=LocalVariableDeclaration
+LocalVariableDeclarationStatement=LocalVariableDeclarationStatement
+MarkerAnnotation=MarkerAnnotation
+MarkerTypeAnnotation=MarkerAnnotation
+MemberValue=MemberValue
+MemberValueArrayInitializer=MemberValueArrayInitializer
+MemberValuePair=MemberValuePair
+MemberValuePairs=MemberValuePairs
+MemberValuePairsopt=MemberValuePairsopt
+MemberValues=MemberValues
+MethodBody=MethodBody
+MethodDeclaration=MethodDeclaration
+MethodHeader=MethodDeclaration
+MethodHeaderExtendedDims=MethodHeaderExtendedDims
+MethodHeaderName=MethodHeaderName
+MethodHeaderRightParen=)
+MethodHeaderThrowsClause=MethodHeaderThrowsClause
+MethodHeaderThrowsClauseopt=MethodHeaderThrowsClause
+MethodInvocation=MethodInvocation
+Modifier=Modifier
+Modifiers=Modifiers
+ModifiersWithDefault=Modifiers
+Modifiersopt=Modifiers
+MultiplicativeExpression=Expression
+MultiplicativeExpression_NotName=Expression
+Name=Name
+NestedMethod=NestedMethod
+NestedType=NestedType
+NonWildTypeArgumentsopt=NonWildTypeArgumentsopt
+NormalAnnotation=NormalAnnotation
+NormalTypeAnnotation=NormalAnnotation
+NumericType=NumericType
+OneDimLoop=Dimension
+OnlySynchronized=OnlySynchronized
+OnlyTypeArguments=TypeArguments
+OnlyTypeArgumentsForCastExpression=TypeArguments
+OpenBlock=OpenBlock
+PackageComment=PackageComment
+PackageDeclaration=PackageDeclaration
+PackageDeclarationName=PackageDeclarationName
+ParenthesizedCastNameAndBounds=ParenthesizedCastNameAndBounds
+ParenthesizedLambdaParameterList=ParenthesizedLambdaParameterList
+PostDecrementExpression=PostDecrementExpression
+PostIncrementExpression=PostIncrementExpression
+PostfixExpression=Expression
+PostfixExpression_NotName=Expression
+PreDecrementExpression=PreDecrementExpression
+PreIncrementExpression=PreIncrementExpression
+Primary=Expression
+PrimaryNoNewArray=Expression
+PrimitiveType=PrimitiveType
+PushLPAREN=(
+PushLeftBrace=PushLeftBrace
+PushModifiers=PushModifiers
+PushModifiersForHeader=PushModifiersForHeader
+PushPosition=PushPosition
+PushRPAREN=)
+PushRealModifiers=PushRealModifiers
+PushZeroTypeAnnotations=ZeroTypeAnnotations
+QualifiedClassBodyopt=ClassBody
+QualifiedEnterAnonymousClassBody=EnterAnonymousClassBody
+QualifiedName=QualifiedName
+RecoveryMethodHeader=MethodHeader
+RecoveryMethodHeaderName=MethodHeaderName
+ReduceImports=ReduceImports
+ReferenceExpression=ReferenceExpression
+ReferenceExpressionTypeArgumentsAndTrunk0=ReferenceExpressionTypeArgumentsAndTrunk
+ReferenceExpressionTypeArgumentsAndTrunk=ReferenceExpressionTypeArgumentsAndTrunk
+ReferenceType1=ReferenceType1
+ReferenceType2=ReferenceType2
+ReferenceType3=ReferenceType3
+ReferenceType=ReferenceType
+RejectTypeAnnotations=RejectTypeAnnotations
+RelationalExpression=Expression
+RelationalExpression_NotName=Expression
+Resource=Resource
+ResourceSpecification=ResourceSpecification
+Resources=Resources
+RestoreDiet=RestoreDiet
+ReturnStatement=ReturnStatement
+ShiftExpression=Expression
+ShiftExpression_NotName=Expression
+SimpleName=SimpleName
+SingleMemberAnnotation=SingleMemberAnnotation
+SingleMemberAnnotationMemberValue=MemberValue
+SingleMemberTypeAnnotation=SingleMemberAnnotation
+SingleStaticImportDeclaration=SingleStaticImportDeclaration
+SingleStaticImportDeclarationName=SingleStaticImportDeclarationName
+SingleTypeImportDeclaration=SingleTypeImportDeclaration
+SingleTypeImportDeclarationName=SingleTypeImportDeclarationName
+Statement=Statement
+StatementExpression=Expression
+StatementExpressionList=StatementExpressionList
+StatementNoShortIf=Statement
+StatementWithoutTrailingSubstatement=Statement
+StaticImportOnDemandDeclaration=StaticImportOnDemandDeclaration
+StaticImportOnDemandDeclarationName=StaticImportOnDemandDeclarationName
+StaticInitializer=StaticInitializer
+StaticOnly=StaticOnly
+SwitchBlock=SwitchBlock
+SwitchBlockStatement=SwitchBlockStatement
+SwitchBlockStatements=SwitchBlockStatements
+SwitchLabel=SwitchLabel
+SwitchLabels=SwitchLabels
+SwitchStatement=SwitchStatement
+SynchronizedStatement=SynchronizedStatement
+ThrowStatement=ThrowStatement
+TrailingSemiColon=;
+TryBlock=Block
+TryStatement=TryStatement
+TryStatementWithResources=TryStatementWithResources
+Type=Type
+TypeAnnotation=TypeAnnotation
+TypeAnnotationName=AnnotationName
+TypeAnnotations0=TypeAnnotations
+TypeAnnotations=TypeAnnotations
+TypeAnnotationsopt=TypeAnnotationsopt
+TypeArgument1=TypeArgument1
+TypeArgument2=TypeArgument2
+TypeArgument3=TypeArgument3
+TypeArgument=TypeArgument
+TypeArgumentList1=TypeArgumentList1
+TypeArgumentList2=TypeArgumentList2
+TypeArgumentList3=TypeArgumentList3
+TypeArgumentList=TypeArgumentList
+TypeArguments=TypeArguments
+TypeDeclaration=TypeDeclaration
+TypeDeclarations=TypeDeclarations
+TypeElidedFormalParameter=TypeElidedFormalParameter
+TypeElidedFormalParameterList=TypeElidedFormalParameterList
+TypeImportOnDemandDeclaration=TypeImportOnDemandDeclaration
+TypeImportOnDemandDeclarationName=TypeImportOnDemandDeclarationName
+TypeParameter1=TypeParameter1
+TypeParameter=TypeParameter
+TypeParameterHeader=TypeParameter
+TypeParameterList1=TypeParameterList1
+TypeParameterList=TypeParameterList
+TypeParameters=TypeParameters
+UnannotatableName=UnannotatableQualifiedName
+UnaryExpression=Expression
+UnaryExpressionNotPlusMinus=Expression
+UnaryExpressionNotPlusMinus_NotName=Expression
+UnaryExpression_NotName=Expression
+UnionType=UnionType
+UnqualifiedClassBodyopt=ClassBody
+UnqualifiedEnterAnonymousClassBody=EnterAnonymousClassBody
+VariableDeclarator=VariableDeclarator
+VariableDeclaratorId=VariableDeclaratorId
+VariableDeclaratorIdOrThis=VariableDeclaratorId
+VariableDeclarators=VariableDeclarators
+VariableInitializer=VariableInitializer
+VariableInitializers=VariableInitializers
+WhileStatement=WhileStatement
+WhileStatementNoShortIf=WhileStatement
+Wildcard1=Wildcard1
+Wildcard2=Wildcard2
+Wildcard3=Wildcard3
+Wildcard=Wildcard
+WildcardBounds1=WildcardBounds1
+WildcardBounds2=WildcardBounds2
+WildcardBounds3=WildcardBound3
+WildcardBounds=WildcardBounds
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part0.rsc
new file mode 100644
index 0000000..894d859
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part1.rsc
new file mode 100644
index 0000000..af00aa9
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part14.rsc
new file mode 100644
index 0000000..c8241e8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part2.rsc
new file mode 100644
index 0000000..e37032a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/part2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start0.rsc
new file mode 100644
index 0000000..f85b964
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start1.rsc
new file mode 100644
index 0000000..48c7021
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start2.rsc
new file mode 100644
index 0000000..e37032a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode/start2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part0.rsc
new file mode 100644
index 0000000..0e09f8a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part1.rsc
new file mode 100644
index 0000000..6cb88cd
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part14.rsc
new file mode 100644
index 0000000..c8241e8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part2.rsc
new file mode 100644
index 0000000..f89f581
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/part2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start0.rsc
new file mode 100644
index 0000000..5cf9811
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start1.rsc
new file mode 100644
index 0000000..1de3213
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start2.rsc
new file mode 100644
index 0000000..f89f581
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode6/start2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java
new file mode 100644
index 0000000..098456f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/*
+ * Special unchecked exception type used
+ * to abort from the compilation process
+ *
+ * should only be thrown from within problem handlers.
+ */
+public class AbortCompilation extends RuntimeException {
+
+	public CompilationResult compilationResult;
+	public Throwable exception;
+	public CategorizedProblem problem;
+
+	/* special fields used to abort silently (e.g. when canceling build process) */
+	public boolean isSilent;
+	public RuntimeException silentException;
+
+	private static final long serialVersionUID = -2047226595083244852L; // backward compatible
+
+	public AbortCompilation() {
+		// empty
+	}
+
+	public AbortCompilation(CompilationResult compilationResult, CategorizedProblem problem) {
+		this();
+		this.compilationResult = compilationResult;
+		this.problem = problem;
+	}
+
+	public AbortCompilation(CompilationResult compilationResult, Throwable exception) {
+		this();
+		this.compilationResult = compilationResult;
+		this.exception = exception;
+	}
+
+	public AbortCompilation(boolean isSilent, RuntimeException silentException) {
+		this();
+		this.isSilent = isSilent;
+		this.silentException = silentException;
+	}
+	public String getMessage() {
+		String message = super.getMessage();
+		StringBuffer buffer = new StringBuffer(message == null ? Util.EMPTY_STRING : message);
+		if (this.problem != null) {
+			buffer.append(this.problem);
+		} else if (this.exception != null) {
+			message = this.exception.getMessage();
+			buffer.append(message == null ? Util.EMPTY_STRING : message);
+		} else if (this.silentException != null) {
+			message = this.silentException.getMessage();
+			buffer.append(message == null ? Util.EMPTY_STRING : message);
+		}
+		return String.valueOf(buffer);
+	}
+	public void updateContext(InvocationSite invocationSite, CompilationResult unitResult) {
+		if (this.problem == null) return;
+		if (this.problem.getSourceStart() != 0 || this.problem.getSourceEnd() != 0) return;
+		this.problem.setSourceStart(invocationSite.sourceStart());
+		this.problem.setSourceEnd(invocationSite.sourceEnd());
+		int[] lineEnds = unitResult.getLineSeparatorPositions();
+		this.problem.setSourceLineNumber(Util.getLineNumber(invocationSite.sourceStart(), lineEnds, 0, lineEnds.length-1));
+		this.compilationResult = unitResult;
+	}
+
+	public void updateContext(ASTNode astNode, CompilationResult unitResult) {
+		if (this.problem == null) return;
+		if (this.problem.getSourceStart() != 0 || this.problem.getSourceEnd() != 0) return;
+		this.problem.setSourceStart(astNode.sourceStart());
+		this.problem.setSourceEnd(astNode.sourceEnd());
+		int[] lineEnds = unitResult.getLineSeparatorPositions();
+		this.problem.setSourceLineNumber(Util.getLineNumber(astNode.sourceStart(), lineEnds, 0, lineEnds.length-1));
+		this.compilationResult = unitResult;
+	}
+
+	public String getKey() {
+		StringBuffer buffer = new StringBuffer();
+		if (this.problem != null) {
+			buffer.append(this.problem);
+		}
+		return String.valueOf(buffer);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java
new file mode 100644
index 0000000..fd862b1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+
+/*
+ * Special unchecked exception type used
+ * to abort from the compilation process
+ *
+ * should only be thrown from within problem handlers.
+ */
+public class AbortCompilationUnit extends AbortCompilation {
+
+	private static final long serialVersionUID = -4253893529982226734L; // backward compatible
+
+	public String encoding;
+
+public AbortCompilationUnit(CompilationResult compilationResult, CategorizedProblem problem) {
+	super(compilationResult, problem);
+}
+
+/**
+ * Used to surface encoding issues when reading sources
+ */
+public AbortCompilationUnit(CompilationResult compilationResult, IOException exception, String encoding) {
+	super(compilationResult, exception);
+	this.encoding = encoding;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java
new file mode 100644
index 0000000..8da26c3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+
+/*
+ * Special unchecked exception type used
+ * to abort from the compilation process
+ *
+ * should only be thrown from within problem handlers.
+ */
+public class AbortMethod extends AbortType {
+
+	private static final long serialVersionUID = -1480267398969840003L; // backward compatible
+
+public AbortMethod(CompilationResult compilationResult, CategorizedProblem problem) {
+	super(compilationResult, problem);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java
new file mode 100644
index 0000000..ad6a4da
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+
+/*
+ * Special unchecked exception type used
+ * to abort from the compilation process
+ *
+ * should only be thrown from within problem handlers.
+ */
+public class AbortType extends AbortCompilationUnit {
+
+	private static final long serialVersionUID = -5882417089349134385L; // backward compatible
+
+public AbortType(CompilationResult compilationResult, CategorizedProblem problem) {
+	super(compilationResult, problem);
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
new file mode 100644
index 0000000..77f2bbf
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class DefaultProblem extends CategorizedProblem {
+	private char[] fileName;
+	private int id;
+	private int startPosition;
+	private int endPosition;
+	private int line;
+	public int column;
+	private int severity;
+	private String[] arguments;
+	private String message;
+
+	// cannot directly point to IJavaModelMarker constants from within batch compiler
+	private static final String MARKER_TYPE_PROBLEM = "org.eclipse.jdt.core.problem"; //$NON-NLS-1$
+	private static final String MARKER_TYPE_TASK = "org.eclipse.jdt.core.task"; //$NON-NLS-1$
+
+	public static final Object[] EMPTY_VALUES = {};
+
+public DefaultProblem(
+	char[] originatingFileName,
+	String message,
+	int id,
+	String[] stringArguments,
+	int severity,
+	int startPosition,
+	int endPosition,
+	int line,
+	int column) {
+
+	this.fileName = originatingFileName;
+	this.message = message;
+	this.id = id;
+	this.arguments = stringArguments;
+	this.severity = severity;
+	this.startPosition = startPosition;
+	this.endPosition = endPosition;
+	this.line = line;
+	this.column = column;
+}
+
+public String errorReportSource(char[] unitSource) {
+	//extra from the source the innacurate     token
+	//and "highlight" it using some underneath ^^^^^
+	//put some context around too.
+
+	//this code assumes that the font used in the console is fixed size
+
+	//sanity .....
+	if ((this.startPosition > this.endPosition)
+		|| ((this.startPosition < 0) && (this.endPosition < 0))
+		|| unitSource.length == 0)
+		return Messages.problem_noSourceInformation;
+
+	StringBuffer errorBuffer = new StringBuffer();
+	errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(this.line)));
+	errorBuffer.append(Util.LINE_SEPARATOR);
+	errorBuffer.append('\t');
+
+	char c;
+	final char SPACE = '\u0020';
+	final char MARK = '^';
+	final char TAB = '\t';
+	//the next code tries to underline the token.....
+	//it assumes (for a good display) that token source does not
+	//contain any \r \n. This is false on statements !
+	//(the code still works but the display is not optimal !)
+
+	// expand to line limits
+	int length = unitSource.length, begin, end;
+	for (begin = this.startPosition >= length ? length - 1 : this.startPosition; begin > 0; begin--) {
+		if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+	}
+	for (end = this.endPosition >= length ? length - 1 : this.endPosition ; end+1 < length; end++) {
+		if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+	}
+
+	// trim left and right spaces/tabs
+	while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+	//while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated
+
+	// copy source
+	errorBuffer.append(unitSource, begin, end-begin+1);
+	errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
+
+	// compute underline
+	for (int i = begin; i <this.startPosition; i++) {
+		errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
+	}
+	for (int i = this.startPosition; i <= (this.endPosition >= length ? length - 1 : this.endPosition); i++) {
+		errorBuffer.append(MARK);
+	}
+	return errorBuffer.toString();
+}
+/**
+ * Answer back the original arguments recorded into the problem.
+ * @return java.lang.String[]
+ */
+public String[] getArguments() {
+	return this.arguments;
+}
+/**
+ * @see org.eclipse.jdt.core.compiler.CategorizedProblem#getCategoryID()
+ */
+public int getCategoryID() {
+	return ProblemReporter.getProblemCategory(this.severity, this.id);
+}
+
+/**
+ * Answer the type of problem.
+ * @see org.eclipse.jdt.core.compiler.IProblem#getID()
+ * @return int
+ */
+public int getID() {
+	return this.id;
+}
+
+/**
+ * Answers a readable name for the category which this problem belongs to,
+ * or null if none could be found.
+ * FOR TESTING PURPOSE
+ * @return java.lang.String
+ */
+public String getInternalCategoryMessage() {
+	switch(getCategoryID()) {
+		case CAT_UNSPECIFIED:
+			return "unspecified"; //$NON-NLS-1$
+		case CAT_BUILDPATH:
+			return "buildpath"; //$NON-NLS-1$
+		case CAT_SYNTAX:
+			return "syntax"; //$NON-NLS-1$
+		case CAT_IMPORT:
+			return "import"; //$NON-NLS-1$
+		case CAT_TYPE:
+			return "type"; //$NON-NLS-1$
+		case CAT_MEMBER:
+			return "member"; //$NON-NLS-1$
+		case CAT_INTERNAL:
+			return "internal"; //$NON-NLS-1$
+		case CAT_JAVADOC:
+			return "javadoc"; //$NON-NLS-1$
+		case CAT_CODE_STYLE:
+			return "code style"; //$NON-NLS-1$
+		case CAT_POTENTIAL_PROGRAMMING_PROBLEM:
+			return "potential programming problem"; //$NON-NLS-1$
+		case CAT_NAME_SHADOWING_CONFLICT:
+			return "name shadowing conflict"; //$NON-NLS-1$
+		case CAT_DEPRECATION:
+			return "deprecation"; //$NON-NLS-1$
+		case CAT_UNNECESSARY_CODE:
+			return "unnecessary code"; //$NON-NLS-1$
+		case CAT_UNCHECKED_RAW:
+			return "unchecked/raw"; //$NON-NLS-1$
+		case CAT_NLS:
+			return "nls"; //$NON-NLS-1$
+		case CAT_RESTRICTION:
+			return "restriction"; //$NON-NLS-1$
+	}
+	return null;
+}
+
+/**
+ * Returns the marker type associated to this problem.
+ * @see org.eclipse.jdt.core.compiler.CategorizedProblem#getMarkerType()
+ */
+public String getMarkerType() {
+	return this.id == IProblem.Task
+		? MARKER_TYPE_TASK
+		: MARKER_TYPE_PROBLEM;
+}
+
+/**
+ * Answer a localized, human-readable message string which describes the problem.
+ * @return java.lang.String
+ */
+public String getMessage() {
+	return this.message;
+}
+
+/**
+ * Answer the file name in which the problem was found.
+ * @return char[]
+ */
+public char[] getOriginatingFileName() {
+	return this.fileName;
+}
+
+/**
+ * Answer the end position of the problem (inclusive), or -1 if unknown.
+ * @return int
+ */
+public int getSourceEnd() {
+	return this.endPosition;
+}
+/**
+ * Answer the line number in source where the problem begins.
+ * @return int
+ */
+public int getSourceColumnNumber() {
+	return this.column;
+}
+/**
+ * Answer the line number in source where the problem begins.
+ * @return int
+ */
+public int getSourceLineNumber() {
+	return this.line;
+}
+/**
+ * Answer the start position of the problem (inclusive), or -1 if unknown.
+ * @return int
+ */
+public int getSourceStart() {
+	return this.startPosition;
+}
+
+/*
+ * Helper method: checks the severity to see if the Error bit is set.
+ * @return boolean
+ */
+public boolean isError() {
+	return (this.severity & ProblemSeverities.Error) != 0;
+}
+
+/*
+ * Helper method: checks the severity to see if the Error bit is not set.
+ * @return boolean
+ */
+public boolean isWarning() {
+	return (this.severity & ProblemSeverities.Error) == 0;
+}
+
+public void setOriginatingFileName(char[] fileName) {
+	this.fileName = fileName;
+}
+
+/**
+ * Set the end position of the problem (inclusive), or -1 if unknown.
+ *
+ * Used for shifting problem positions.
+ * @param sourceEnd the new value of the sourceEnd of the receiver
+ */
+public void setSourceEnd(int sourceEnd) {
+	this.endPosition = sourceEnd;
+}
+
+/**
+ * Set the line number in source where the problem begins.
+ * @param lineNumber the new value of the line number of the receiver
+ */
+public void setSourceLineNumber(int lineNumber) {
+
+	this.line = lineNumber;
+}
+
+/**
+ * Set the start position of the problem (inclusive), or -1 if unknown.
+ *
+ * Used for shifting problem positions.
+ * @param sourceStart the new value of the source start position of the receiver
+ */
+public void setSourceStart(int sourceStart) {
+	this.startPosition = sourceStart;
+}
+
+public String toString() {
+	String s = "Pb(" + (this.id & IProblem.IgnoreCategoriesMask) + ") "; //$NON-NLS-1$ //$NON-NLS-2$
+	if (this.message != null) {
+		s += this.message;
+	} else {
+		if (this.arguments != null)
+			for (int i = 0; i < this.arguments.length; i++)
+				s += " " + this.arguments[i]; //$NON-NLS-1$
+	}
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
new file mode 100644
index 0000000..72adebc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class DefaultProblemFactory implements IProblemFactory {
+
+	public HashtableOfInt messageTemplates;
+	private Locale locale;
+	private static HashtableOfInt DEFAULT_LOCALE_TEMPLATES;
+	private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
+	private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
+	private final static char[] FIRST_ARGUMENT = "{0}".toCharArray(); //$NON-NLS-1$
+
+public DefaultProblemFactory() {
+	this(Locale.getDefault());
+}
+/**
+ * @param loc the locale used to get the right message
+ */
+public DefaultProblemFactory(Locale loc) {
+	setLocale(loc);
+}
+/**
+ * Answer a new IProblem created according to the parameters value
+ * <ul>
+ * <li>originatingFileName the name of the file name from which the problem is originated
+ * <li>problemId the problem id
+ * <li>problemArguments the fully qualified arguments recorded inside the problem
+ * <li>messageArguments the arguments needed to set the error message (shorter names than problemArguments ones)
+ * <li>severity the severity of the problem
+ * <li>startPosition the starting position of the problem
+ * <li>endPosition the end position of the problem
+ * <li>lineNumber the line on which the problem occured
+ * </ul>
+ * @param originatingFileName char[]
+ * @param problemId int
+ * @param problemArguments String[]
+ * @param messageArguments String[]
+ * @param severity int
+ * @param startPosition int
+ * @param endPosition int
+ * @param lineNumber int
+ * @return CategorizedProblem
+ */
+public CategorizedProblem createProblem(
+	char[] originatingFileName,
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int severity,
+	int startPosition,
+	int endPosition,
+	int lineNumber,
+	int columnNumber) {
+
+	return new DefaultProblem(
+		originatingFileName,
+		this.getLocalizedMessage(problemId, messageArguments),
+		problemId,
+		problemArguments,
+		severity,
+		startPosition,
+		endPosition,
+		lineNumber,
+		columnNumber);
+}
+public CategorizedProblem createProblem(
+	char[] originatingFileName,
+	int problemId,
+	String[] problemArguments,
+	int elaborationId,
+	String[] messageArguments,
+	int severity,
+	int startPosition,
+	int endPosition,
+	int lineNumber,
+	int columnNumber) {
+	return new DefaultProblem(
+		originatingFileName,
+		this.getLocalizedMessage(problemId, elaborationId, messageArguments),
+		problemId,
+		problemArguments,
+		severity,
+		startPosition,
+		endPosition,
+		lineNumber,
+		columnNumber);
+}
+private final static int keyFromID(int id) {
+    return id + 1; // keys are offsetted by one in table, since it cannot handle 0 key
+}
+/**
+ * Answer the locale used to retrieve the error messages
+ * @return java.util.Locale
+ */
+public Locale getLocale() {
+	return this.locale;
+}
+public void setLocale(Locale locale) {
+	if (locale == this.locale) return;
+	this.locale = locale;
+	if (Locale.getDefault().equals(locale)){
+		if (DEFAULT_LOCALE_TEMPLATES == null){
+			DEFAULT_LOCALE_TEMPLATES = loadMessageTemplates(locale);
+		}
+		this.messageTemplates = DEFAULT_LOCALE_TEMPLATES;
+	} else {
+		this.messageTemplates = loadMessageTemplates(locale);
+	}
+}
+public final String getLocalizedMessage(int id, String[] problemArguments) {
+	return getLocalizedMessage(id, 0, problemArguments);
+}
+public final String getLocalizedMessage(int id, int elaborationId, String[] problemArguments) {
+	String rawMessage = (String) this.messageTemplates.get(keyFromID(id & IProblem.IgnoreCategoriesMask));
+	if (rawMessage == null) {
+		return "Unable to retrieve the error message for problem id: " //$NON-NLS-1$
+			+ (id & IProblem.IgnoreCategoriesMask) + ". Check compiler resources.";  //$NON-NLS-1$
+	}
+	char[] message = rawMessage.toCharArray();
+	if (elaborationId != 0) {
+		String elaboration = (String) this.messageTemplates.get(keyFromID(elaborationId));
+		if (elaboration == null) {
+			return "Unable to retrieve the error message elaboration for elaboration id: " //$NON-NLS-1$
+				+ elaborationId + ". Check compiler resources.";  //$NON-NLS-1$
+		}
+		message = CharOperation.replace(message, FIRST_ARGUMENT, elaboration.toCharArray());
+	}
+
+	// for compatibility with MessageFormat which eliminates double quotes in original message
+	message = CharOperation.replace(message, DOUBLE_QUOTES, SINGLE_QUOTE);
+
+	if (problemArguments == null) {
+		return new String(message);
+	}
+
+	int length = message.length;
+	int start = 0;
+	int end = length;
+	StringBuffer output = null;
+	if ((id & IProblem.Javadoc) != 0) {
+		output = new StringBuffer(10+length+problemArguments.length*20);
+		output.append((String) this.messageTemplates.get(keyFromID(IProblem.JavadocMessagePrefix & IProblem.IgnoreCategoriesMask)));
+	}
+	while (true) {
+		if ((end = CharOperation.indexOf('{', message, start)) > -1) {
+			if (output == null) output = new StringBuffer(length+problemArguments.length*20);
+			output.append(message, start, end - start);
+			if ((start = CharOperation.indexOf('}', message, end + 1)) > -1) {
+				try {
+					output.append(problemArguments[CharOperation.parseInt(message, end + 1, start - end - 1)]);
+				} catch (NumberFormatException nfe) {
+					output.append(message, end + 1, start - end);
+				} catch (ArrayIndexOutOfBoundsException e) {
+					return "Cannot bind message for problem (id: " //$NON-NLS-1$
+						+ (id & IProblem.IgnoreCategoriesMask)
+						+ ") \""  //$NON-NLS-1$
+						+ new String(message)
+						+ "\" with arguments: {" //$NON-NLS-1$
+						+ Util.toString(problemArguments)
+						+"}"; //$NON-NLS-1$
+				}
+				start++;
+			} else {
+				output.append(message, end, length);
+				break;
+			}
+		} else {
+			if (output == null) {
+				return new String(message);
+			}
+			output.append(message, start, length - start);
+			break;
+		}
+	}
+
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=120410
+	return new String(output.toString());
+}
+/**
+ * @param problem CategorizedProblem
+ * @return String
+ */
+public final String localizedMessage(CategorizedProblem problem) {
+	return getLocalizedMessage(problem.getID(), problem.getArguments());
+}
+
+/**
+ * This method initializes the MessageTemplates class variable according
+ * to the current Locale.
+ * @param loc Locale
+ * @return HashtableOfInt
+ */
+public static HashtableOfInt loadMessageTemplates(Locale loc) {
+	ResourceBundle bundle = null;
+	String bundleName = "org.eclipse.jdt.internal.compiler.problem.messages"; //$NON-NLS-1$
+	try {
+		bundle = ResourceBundle.getBundle(bundleName, loc);
+	} catch(MissingResourceException e) {
+		System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + loc); //$NON-NLS-1$//$NON-NLS-2$
+		throw e;
+	}
+	HashtableOfInt templates = new HashtableOfInt(700);
+	Enumeration keys = bundle.getKeys();
+	while (keys.hasMoreElements()) {
+	    String key = (String)keys.nextElement();
+	    try {
+	        int messageID = Integer.parseInt(key);
+			templates.put(keyFromID(messageID), bundle.getString(key));
+	    } catch(NumberFormatException e) {
+	        // key ill-formed
+		} catch (MissingResourceException e) {
+			// available ID
+	    }
+	}
+	return templates;
+}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
new file mode 100644
index 0000000..a8a2fcc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/*
+ * Compiler error handler, responsible to determine whether
+ * a problem is actually a warning or an error; also will
+ * decide whether the compilation task can be processed further or not.
+ *
+ * Behavior : will request its current policy if need to stop on
+ *	first error, and if should proceed (persist) with problems.
+ */
+
+public class ProblemHandler {
+
+	public final static String[] NoArgument = CharOperation.NO_STRINGS;
+
+	public IErrorHandlingPolicy policy;
+	public final IProblemFactory problemFactory;
+	public final CompilerOptions options;
+/*
+ * Problem handler can be supplied with a policy to specify
+ * its behavior in error handling. Also see static methods for
+ * built-in policies.
+ *
+ */
+public ProblemHandler(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
+	this.policy = policy;
+	this.problemFactory = problemFactory;
+	this.options = options;
+}
+/*
+ * Given the current configuration, answers which category the problem
+ * falls into:
+ *		Error | Warning | Ignore
+ */
+public int computeSeverity(int problemId){
+
+	return ProblemSeverities.Error; // by default all problems are errors
+}
+public CategorizedProblem createProblem(
+	char[] fileName,
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int severity,
+	int problemStartPosition,
+	int problemEndPosition,
+	int lineNumber,
+	int columnNumber) {
+
+	return this.problemFactory.createProblem(
+		fileName,
+		problemId,
+		problemArguments,
+		messageArguments,
+		severity,
+		problemStartPosition,
+		problemEndPosition,
+		lineNumber,
+		columnNumber);
+}
+public CategorizedProblem createProblem(
+		char[] fileName,
+		int problemId,
+		String[] problemArguments,
+		int elaborationId,
+		String[] messageArguments,
+		int severity,
+		int problemStartPosition,
+		int problemEndPosition,
+		int lineNumber,
+		int columnNumber) {
+	return this.problemFactory.createProblem(
+		fileName,
+		problemId,
+		problemArguments,
+		elaborationId,
+		messageArguments,
+		severity,
+		problemStartPosition,
+		problemEndPosition,
+		lineNumber,
+		columnNumber);
+}
+public void handle(
+	int problemId,
+	String[] problemArguments,
+	int elaborationId,
+	String[] messageArguments,
+	int severity,
+	int problemStartPosition,
+	int problemEndPosition,
+	ReferenceContext referenceContext,
+	CompilationResult unitResult) {
+
+	if (severity == ProblemSeverities.Ignore)
+		return;
+
+	 boolean mandatory = (severity & (ProblemSeverities.Error | ProblemSeverities.Optional)) == ProblemSeverities.Error;
+	 if (this.policy.ignoreAllErrors()) { 
+		 // Error is not to be exposed, but clients may need still notification as to whether there are silently-ignored-errors.
+		 if (mandatory)
+			 referenceContext.tagAsHavingIgnoredMandatoryErrors(problemId);
+		 return;
+	 }
+
+	if ((severity & ProblemSeverities.Optional) != 0 && problemId != IProblem.Task  && !this.options.ignoreSourceFolderWarningOption) {
+		ICompilationUnit cu = unitResult.getCompilationUnit();
+		try{
+			if (cu != null && cu.ignoreOptionalProblems())
+				return;
+		// workaround for illegal implementation of ICompilationUnit, see https://bugs.eclipse.org/372351
+		} catch (AbstractMethodError ex) {
+			// continue
+		}
+	}
+
+	// if no reference context, we need to abort from the current compilation process
+	if (referenceContext == null) {
+		if ((severity & ProblemSeverities.Error) != 0) { // non reportable error is fatal
+			CategorizedProblem problem = this.createProblem(null, problemId, problemArguments, elaborationId, messageArguments, severity, 0, 0, 0, 0);
+			throw new AbortCompilation(null, problem);
+		} else {
+			return; // ignore non reportable warning
+		}
+	}
+
+	int[] lineEnds;
+	int lineNumber = problemStartPosition >= 0
+			? Util.getLineNumber(problemStartPosition, lineEnds = unitResult.getLineSeparatorPositions(), 0, lineEnds.length-1)
+			: 0;
+	int columnNumber = problemStartPosition >= 0
+			? Util.searchColumnNumber(unitResult.getLineSeparatorPositions(), lineNumber, problemStartPosition)
+			: 0;
+	CategorizedProblem problem =
+		this.createProblem(
+			unitResult.getFileName(),
+			problemId,
+			problemArguments,
+			elaborationId,
+			messageArguments,
+			severity,
+			problemStartPosition,
+			problemEndPosition,
+			lineNumber,
+			columnNumber);
+
+	if (problem == null) return; // problem couldn't be created, ignore
+
+	switch (severity & ProblemSeverities.Error) {
+		case ProblemSeverities.Error :
+			record(problem, unitResult, referenceContext, mandatory);
+			if ((severity & ProblemSeverities.Fatal) != 0) {
+				// don't abort or tag as error if the error is suppressed
+				if (!referenceContext.hasErrors() && !mandatory && this.options.suppressOptionalErrors) {
+					CompilationUnitDeclaration unitDecl = referenceContext.getCompilationUnitDeclaration();
+					if (unitDecl != null && unitDecl.isSuppressed(problem)) {
+						return;
+					}
+				}
+				referenceContext.tagAsHavingErrors();
+				// should abort ?
+				int abortLevel;
+				if ((abortLevel = this.policy.stopOnFirstError() ? ProblemSeverities.AbortCompilation : severity & ProblemSeverities.Abort) != 0) {
+					referenceContext.abort(abortLevel, problem);
+				}
+			}
+			break;
+		case ProblemSeverities.Warning :
+			record(problem, unitResult, referenceContext, false);
+			break;
+	}
+}
+/**
+ * Standard problem handling API, the actual severity (warning/error/ignore) is deducted
+ * from the problem ID and the current compiler options.
+ */
+public void handle(
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int problemStartPosition,
+	int problemEndPosition,
+	ReferenceContext referenceContext,
+	CompilationResult unitResult) {
+
+	this.handle(
+		problemId,
+		problemArguments,
+		0, // no message elaboration
+		messageArguments,
+		computeSeverity(problemId), // severity inferred using the ID
+		problemStartPosition,
+		problemEndPosition,
+		referenceContext,
+		unitResult);
+}
+public void record(CategorizedProblem problem, CompilationResult unitResult, ReferenceContext referenceContext, boolean mandatoryError) {
+	unitResult.record(problem, referenceContext, mandatoryError);
+}
+/** @return old policy. */
+public IErrorHandlingPolicy switchErrorHandlingPolicy(IErrorHandlingPolicy newPolicy) {
+	IErrorHandlingPolicy presentPolicy = this.policy;
+	this.policy = newPolicy;
+	return presentPolicy;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
new file mode 100644
index 0000000..94b4946
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -0,0 +1,9556 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Benjamin Muskalla - Contribution for bug 239066
+ *     Stephan Herrmann  - Contributions for
+ *	     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ *  	   						bug 338303 - Warning about Redundant assignment conflicts with definite assignment
+ *								bug 349326 - [1.7] new warning for missing try-with-resources
+ *								bug 186342 - [compiler][null] Using annotations for null checking
+ *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
+ *								bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+ *								bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+ *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+ *								bug 374605 - Unreasonable warning for enum-based switch statements
+ *								bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+ *								bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+ *								bug 388281 - [compiler][null] inheritance of null annotations as an option
+ *								bug 376053 - [compiler][resource] Strange potential resource leak problems
+ *								bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ *								bug 393719 - [compiler] inconsistent warnings on iteration variables
+ *								bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+ *								bug 388739 - [1.8][compiler] consider default methods when detecting whether a class needs to be declared abstract
+ *								bug 331649 - [compiler][null] consider null annotations for fields
+ *								bug 382789 - [compiler][null] warn when syntactically-nonnull expression is compared against null
+ *								bug 376590 - Private fields with @Inject are ignored by unused field validation
+ *								bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+ *								bug 402028 - [1.8][compiler] null analysis for reference expressions 
+ *								bug 401796 - [1.8][compiler] don't treat default methods as overriding an independent inherited abstract method
+ *								bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+ *      Jesper S Moller <jesper@selskabet.org> -  Contributions for
+ *								bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+ *								bug 382721 - [1.8][compiler] Effectively final variables needs special treatment
+ *								bug 384567 - [1.5][compiler] Compiler accepts illegal modifiers on package declaration
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+import java.io.CharConversionException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+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.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
+import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FakedTrackingVariable;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
+import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.Literal;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+
+public class ProblemReporter extends ProblemHandler {
+
+	public ReferenceContext referenceContext;
+	private Scanner positionScanner;
+	private final static byte
+	  // TYPE_ACCESS = 0x0,
+	  FIELD_ACCESS = 0x4,
+	  CONSTRUCTOR_ACCESS = 0x8,
+	  METHOD_ACCESS = 0xC;
+
+public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
+	super(policy, options, problemFactory);
+}
+
+private static int getElaborationId (int leadProblemId, byte elaborationVariant) {
+	return leadProblemId << 8 | elaborationVariant; // leadProblemId comes into the higher order bytes
+}
+public static int getIrritant(int problemID) {
+	switch(problemID){
+
+		case IProblem.MaskedCatch :
+			return CompilerOptions.MaskedCatchBlock;
+
+		case IProblem.UnusedImport :
+			return CompilerOptions.UnusedImport;
+
+		case IProblem.MethodButWithConstructorName :
+			return CompilerOptions.MethodWithConstructorName;
+
+		case IProblem.OverridingNonVisibleMethod :
+			return CompilerOptions.OverriddenPackageDefaultMethod;
+
+		case IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod :
+		case IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod :
+			return CompilerOptions.IncompatibleNonInheritedInterfaceMethod;
+
+		case IProblem.OverridingDeprecatedMethod :
+		case IProblem.UsingDeprecatedType :
+		case IProblem.UsingDeprecatedMethod :
+		case IProblem.UsingDeprecatedConstructor :
+		case IProblem.UsingDeprecatedField :
+			return CompilerOptions.UsingDeprecatedAPI;
+
+		case IProblem.LocalVariableIsNeverUsed :
+			return CompilerOptions.UnusedLocalVariable;
+
+		case IProblem.ArgumentIsNeverUsed :
+			return CompilerOptions.UnusedArgument;
+
+		case IProblem.NoImplicitStringConversionForCharArrayExpression :
+			return CompilerOptions.NoImplicitStringConversion;
+
+		case IProblem.NeedToEmulateFieldReadAccess :
+		case IProblem.NeedToEmulateFieldWriteAccess :
+		case IProblem.NeedToEmulateMethodAccess :
+		case IProblem.NeedToEmulateConstructorAccess :
+			return CompilerOptions.AccessEmulation;
+
+		case IProblem.NonExternalizedStringLiteral :
+		case IProblem.UnnecessaryNLSTag :
+			return CompilerOptions.NonExternalizedString;
+
+		case IProblem.UseAssertAsAnIdentifier :
+			return CompilerOptions.AssertUsedAsAnIdentifier;
+
+		case IProblem.UseEnumAsAnIdentifier :
+			return CompilerOptions.EnumUsedAsAnIdentifier;
+
+		case IProblem.NonStaticAccessToStaticMethod :
+		case IProblem.NonStaticAccessToStaticField :
+			return CompilerOptions.NonStaticAccessToStatic;
+
+		case IProblem.IndirectAccessToStaticMethod :
+		case IProblem.IndirectAccessToStaticField :
+		case IProblem.IndirectAccessToStaticType :
+			return CompilerOptions.IndirectStaticAccess;
+
+		case IProblem.AssignmentHasNoEffect:
+			return CompilerOptions.NoEffectAssignment;
+
+		case IProblem.UnusedPrivateConstructor:
+		case IProblem.UnusedPrivateMethod:
+		case IProblem.UnusedPrivateField:
+		case IProblem.UnusedPrivateType:
+			return CompilerOptions.UnusedPrivateMember;
+
+		case IProblem.LocalVariableHidingLocalVariable:
+		case IProblem.LocalVariableHidingField:
+		case IProblem.ArgumentHidingLocalVariable:
+		case IProblem.ArgumentHidingField:
+			return CompilerOptions.LocalVariableHiding;
+
+		case IProblem.FieldHidingLocalVariable:
+		case IProblem.FieldHidingField:
+			return CompilerOptions.FieldHiding;
+
+		case IProblem.TypeParameterHidingType:
+		case IProblem.TypeHidingTypeParameterFromType:
+		case IProblem.TypeHidingTypeParameterFromMethod:
+		case IProblem.TypeHidingType:
+			return CompilerOptions.TypeHiding;
+
+		case IProblem.PossibleAccidentalBooleanAssignment:
+			return CompilerOptions.AccidentalBooleanAssign;
+
+		case IProblem.SuperfluousSemicolon:
+		case IProblem.EmptyControlFlowStatement:
+			return CompilerOptions.EmptyStatement;
+
+		case IProblem.UndocumentedEmptyBlock:
+			return CompilerOptions.UndocumentedEmptyBlock;
+
+		case IProblem.UnnecessaryCast:
+		case IProblem.UnnecessaryInstanceof:
+			return CompilerOptions.UnnecessaryTypeCheck;
+
+		case IProblem.FinallyMustCompleteNormally:
+			return CompilerOptions.FinallyBlockNotCompleting;
+
+		case IProblem.UnusedMethodDeclaredThrownException:
+		case IProblem.UnusedConstructorDeclaredThrownException:
+			return CompilerOptions.UnusedDeclaredThrownException;
+
+		case IProblem.UnqualifiedFieldAccess:
+			return CompilerOptions.UnqualifiedFieldAccess;
+
+		case IProblem.UnnecessaryElse:
+			return CompilerOptions.UnnecessaryElse;
+
+		case IProblem.UnsafeRawConstructorInvocation:
+		case IProblem.UnsafeRawMethodInvocation:
+		case IProblem.UnsafeTypeConversion:
+		case IProblem.UnsafeElementTypeConversion:
+		case IProblem.UnsafeRawFieldAssignment:
+		case IProblem.UnsafeGenericCast:
+		case IProblem.UnsafeReturnTypeOverride:
+		case IProblem.UnsafeRawGenericMethodInvocation:
+		case IProblem.UnsafeRawGenericConstructorInvocation:
+		case IProblem.UnsafeGenericArrayForVarargs:
+		case IProblem.PotentialHeapPollutionFromVararg:
+			return CompilerOptions.UncheckedTypeOperation;
+
+		case IProblem.RawTypeReference:
+			return CompilerOptions.RawTypeReference;
+
+		case IProblem.MissingOverrideAnnotation:
+		case IProblem.MissingOverrideAnnotationForInterfaceMethodImplementation:
+			return CompilerOptions.MissingOverrideAnnotation;
+
+		case IProblem.FieldMissingDeprecatedAnnotation:
+		case IProblem.MethodMissingDeprecatedAnnotation:
+		case IProblem.TypeMissingDeprecatedAnnotation:
+			return CompilerOptions.MissingDeprecatedAnnotation;
+
+		case IProblem.FinalBoundForTypeVariable:
+		    return CompilerOptions.FinalParameterBound;
+
+		case IProblem.MissingSerialVersion:
+			return CompilerOptions.MissingSerialVersion;
+
+		case IProblem.ForbiddenReference:
+			return CompilerOptions.ForbiddenReference;
+
+		case IProblem.DiscouragedReference:
+			return CompilerOptions.DiscouragedReference;
+
+		case IProblem.MethodVarargsArgumentNeedCast :
+		case IProblem.ConstructorVarargsArgumentNeedCast :
+			return CompilerOptions.VarargsArgumentNeedCast;
+
+		case IProblem.NullLocalVariableReference:
+		case IProblem.NullableFieldReference:
+		case IProblem.NullExpressionReference:
+		case IProblem.NullUnboxing:
+			return CompilerOptions.NullReference;
+
+		case IProblem.PotentialNullLocalVariableReference:
+		case IProblem.PotentialNullMessageSendReference:
+		case IProblem.ArrayReferencePotentialNullReference:
+		case IProblem.DereferencingNullableExpression:
+		case IProblem.PotentialNullExpressionReference:
+		case IProblem.PotentialNullUnboxing:
+			return CompilerOptions.PotentialNullReference;
+
+		case IProblem.RedundantLocalVariableNullAssignment:
+		case IProblem.RedundantNullCheckOnNonNullLocalVariable:
+		case IProblem.RedundantNullCheckOnNullLocalVariable:
+		case IProblem.NonNullLocalVariableComparisonYieldsFalse:
+		case IProblem.NullLocalVariableComparisonYieldsFalse:
+		case IProblem.NullLocalVariableInstanceofYieldsFalse:
+		case IProblem.RedundantNullCheckOnNonNullExpression:
+		case IProblem.NonNullExpressionComparisonYieldsFalse:
+		case IProblem.RedundantNullCheckOnNonNullMessageSend:
+		case IProblem.RedundantNullCheckOnSpecdNonNullLocalVariable:
+		case IProblem.SpecdNonNullLocalVariableComparisonYieldsFalse:
+		case IProblem.NonNullMessageSendComparisonYieldsFalse:
+		case IProblem.RedundantNullCheckOnNonNullSpecdField:
+		case IProblem.NonNullSpecdFieldComparisonYieldsFalse:
+			return CompilerOptions.RedundantNullCheck;
+
+		case IProblem.RequiredNonNullButProvidedNull:
+		case IProblem.RequiredNonNullButProvidedSpecdNullable:
+		case IProblem.IllegalReturnNullityRedefinition:
+		case IProblem.IllegalRedefinitionToNonNullParameter:
+		case IProblem.IllegalDefinitionToNonNullParameter:
+		case IProblem.ParameterLackingNullableAnnotation:
+		case IProblem.CannotImplementIncompatibleNullness:
+		case IProblem.ConflictingNullAnnotations:
+		case IProblem.ConflictingInheritedNullAnnotations:
+		case IProblem.NullityMismatchingTypeAnnotation:
+		case IProblem.UninitializedNonNullField:
+		case IProblem.UninitializedNonNullFieldHintMissingDefault:
+		case IProblem.ReferenceExpressionParameterMismatchPromisedNullable:
+		case IProblem.ReferenceExpressionReturnNullRedef:
+			return CompilerOptions.NullSpecViolation;
+
+		case IProblem.ParameterLackingNonNullAnnotation:
+			return CompilerOptions.NonnullParameterAnnotationDropped;
+
+		case IProblem.RequiredNonNullButProvidedPotentialNull:
+			return CompilerOptions.NullAnnotationInferenceConflict;
+		case IProblem.RequiredNonNullButProvidedUnknown:
+		case IProblem.NullityMismatchingTypeAnnotationUnchecked:
+		case IProblem.ReferenceExpressionParameterRequiredNonnullUnchecked:
+		case IProblem.ReferenceExpressionReturnNullRedefUnchecked:
+			return CompilerOptions.NullUncheckedConversion;
+		case IProblem.RedundantNullAnnotation:
+		case IProblem.RedundantNullDefaultAnnotation:
+		case IProblem.RedundantNullDefaultAnnotationPackage:
+		case IProblem.RedundantNullDefaultAnnotationType:
+		case IProblem.RedundantNullDefaultAnnotationMethod:
+			return CompilerOptions.RedundantNullAnnotation;
+
+		case IProblem.BoxingConversion :
+		case IProblem.UnboxingConversion :
+			return CompilerOptions.AutoBoxing;
+
+		case IProblem.MissingEnumConstantCase :
+		case IProblem.MissingEnumConstantCaseDespiteDefault :	// this one is further protected by CompilerOptions.reportMissingEnumCaseDespiteDefault
+			return CompilerOptions.MissingEnumConstantCase;
+
+		case IProblem.MissingDefaultCase :
+		case IProblem.MissingEnumDefaultCase :
+			return CompilerOptions.MissingDefaultCase;
+
+		case IProblem.AnnotationTypeUsedAsSuperInterface :
+			return CompilerOptions.AnnotationSuperInterface;
+
+		case IProblem.UnhandledWarningToken :
+			return CompilerOptions.UnhandledWarningToken;
+
+		case IProblem.UnusedWarningToken :
+			return CompilerOptions.UnusedWarningToken;
+
+		case IProblem.UnusedLabel :
+			return CompilerOptions.UnusedLabel;
+
+		case IProblem.JavadocUnexpectedTag:
+		case IProblem.JavadocDuplicateTag:
+		case IProblem.JavadocDuplicateReturnTag:
+		case IProblem.JavadocInvalidThrowsClass:
+		case IProblem.JavadocInvalidSeeReference:
+		case IProblem.JavadocInvalidParamTagName:
+		case IProblem.JavadocInvalidParamTagTypeParameter:
+		case IProblem.JavadocMalformedSeeReference:
+		case IProblem.JavadocInvalidSeeHref:
+		case IProblem.JavadocInvalidSeeArgs:
+		case IProblem.JavadocInvalidTag:
+		case IProblem.JavadocUnterminatedInlineTag:
+		case IProblem.JavadocMissingHashCharacter:
+		case IProblem.JavadocEmptyReturnTag:
+		case IProblem.JavadocUnexpectedText:
+		case IProblem.JavadocInvalidParamName:
+		case IProblem.JavadocDuplicateParamName:
+		case IProblem.JavadocMissingParamName:
+		case IProblem.JavadocMissingIdentifier:
+		case IProblem.JavadocInvalidMemberTypeQualification:
+		case IProblem.JavadocInvalidThrowsClassName:
+		case IProblem.JavadocDuplicateThrowsClassName:
+		case IProblem.JavadocMissingThrowsClassName:
+		case IProblem.JavadocMissingSeeReference:
+		case IProblem.JavadocInvalidValueReference:
+		case IProblem.JavadocUndefinedField:
+		case IProblem.JavadocAmbiguousField:
+		case IProblem.JavadocUndefinedConstructor:
+		case IProblem.JavadocAmbiguousConstructor:
+		case IProblem.JavadocUndefinedMethod:
+		case IProblem.JavadocAmbiguousMethod:
+		case IProblem.JavadocAmbiguousMethodReference:
+		case IProblem.JavadocParameterMismatch:
+		case IProblem.JavadocUndefinedType:
+		case IProblem.JavadocAmbiguousType:
+		case IProblem.JavadocInternalTypeNameProvided:
+		case IProblem.JavadocNoMessageSendOnArrayType:
+		case IProblem.JavadocNoMessageSendOnBaseType:
+		case IProblem.JavadocInheritedMethodHidesEnclosingName:
+		case IProblem.JavadocInheritedFieldHidesEnclosingName:
+		case IProblem.JavadocInheritedNameHidesEnclosingTypeName:
+		case IProblem.JavadocNonStaticTypeFromStaticInvocation:
+		case IProblem.JavadocGenericMethodTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericMethod:
+		case IProblem.JavadocIncorrectArityForParameterizedMethod:
+		case IProblem.JavadocParameterizedMethodArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericMethod:
+		case IProblem.JavadocGenericConstructorTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericConstructor:
+		case IProblem.JavadocIncorrectArityForParameterizedConstructor:
+		case IProblem.JavadocParameterizedConstructorArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericConstructor:
+		case IProblem.JavadocNotVisibleField:
+		case IProblem.JavadocNotVisibleConstructor:
+		case IProblem.JavadocNotVisibleMethod:
+		case IProblem.JavadocNotVisibleType:
+		case IProblem.JavadocUsingDeprecatedField:
+		case IProblem.JavadocUsingDeprecatedConstructor:
+		case IProblem.JavadocUsingDeprecatedMethod:
+		case IProblem.JavadocUsingDeprecatedType:
+		case IProblem.JavadocHiddenReference:
+		case IProblem.JavadocMissingTagDescription:
+		case IProblem.JavadocInvalidSeeUrlReference:
+			return CompilerOptions.InvalidJavadoc;
+
+		case IProblem.JavadocMissingParamTag:
+		case IProblem.JavadocMissingReturnTag:
+		case IProblem.JavadocMissingThrowsTag:
+			return CompilerOptions.MissingJavadocTags;
+
+		case IProblem.JavadocMissing:
+			return CompilerOptions.MissingJavadocComments;
+
+		case IProblem.ParameterAssignment:
+			return CompilerOptions.ParameterAssignment;
+
+		case IProblem.FallthroughCase:
+			return CompilerOptions.FallthroughCase;
+
+		case IProblem.OverridingMethodWithoutSuperInvocation:
+			return CompilerOptions.OverridingMethodWithoutSuperInvocation;
+
+		case IProblem.UnusedTypeArgumentsForMethodInvocation:
+		case IProblem.UnusedTypeArgumentsForConstructorInvocation:
+			return CompilerOptions.UnusedTypeArguments;
+
+		case IProblem.RedundantSuperinterface:
+			return CompilerOptions.RedundantSuperinterface;
+
+		case IProblem.ComparingIdentical:
+			return CompilerOptions.ComparingIdentical;
+			
+		case IProblem.MissingSynchronizedModifierInInheritedMethod:
+			return CompilerOptions.MissingSynchronizedModifierInInheritedMethod;
+
+		case IProblem.ShouldImplementHashcode:
+			return CompilerOptions.ShouldImplementHashcode;
+			
+		case IProblem.DeadCode:
+			return CompilerOptions.DeadCode;
+			
+		case IProblem.Task :
+			return CompilerOptions.Tasks;
+
+		case IProblem.UnusedObjectAllocation:
+			return CompilerOptions.UnusedObjectAllocation;
+			
+		case IProblem.MethodCanBeStatic:
+			return CompilerOptions.MethodCanBeStatic;
+			
+		case IProblem.MethodCanBePotentiallyStatic:
+			return CompilerOptions.MethodCanBePotentiallyStatic;
+
+		case IProblem.UnclosedCloseable:
+		case IProblem.UnclosedCloseableAtExit:
+			return CompilerOptions.UnclosedCloseable;
+		case IProblem.PotentiallyUnclosedCloseable:
+		case IProblem.PotentiallyUnclosedCloseableAtExit:
+			return CompilerOptions.PotentiallyUnclosedCloseable;
+		case IProblem.ExplicitlyClosedAutoCloseable:
+			return CompilerOptions.ExplicitlyClosedAutoCloseable;
+				
+		case IProblem.RedundantSpecificationOfTypeArguments:
+			return CompilerOptions.RedundantSpecificationOfTypeArguments;
+			
+		case IProblem.MissingNonNullByDefaultAnnotationOnPackage:
+		case IProblem.MissingNonNullByDefaultAnnotationOnType:
+			return CompilerOptions.MissingNonNullByDefaultAnnotation;
+			
+		case IProblem.UnusedTypeParameter:
+			return CompilerOptions.UnusedTypeParameter;
+	}
+	return 0;
+}
+/**
+ * Compute problem category ID based on problem ID
+ * @param problemID
+ * @return a category ID
+ * @see CategorizedProblem
+ */
+public static int getProblemCategory(int severity, int problemID) {
+	categorizeOnIrritant: {
+		// fatal problems even if optional are all falling into same category (not irritant based)
+		if ((severity & ProblemSeverities.Fatal) != 0)
+			break categorizeOnIrritant;
+		int irritant = getIrritant(problemID);
+		switch (irritant) {
+			case CompilerOptions.MethodWithConstructorName :
+			case CompilerOptions.AccessEmulation :
+			case CompilerOptions.AssertUsedAsAnIdentifier :
+			case CompilerOptions.NonStaticAccessToStatic :
+			case CompilerOptions.UnqualifiedFieldAccess :
+			case CompilerOptions.UndocumentedEmptyBlock :
+			case CompilerOptions.IndirectStaticAccess :
+			case CompilerOptions.FinalParameterBound :
+			case CompilerOptions.EnumUsedAsAnIdentifier :
+			case CompilerOptions.AnnotationSuperInterface :
+			case CompilerOptions.AutoBoxing :
+			case CompilerOptions.MissingOverrideAnnotation :
+			case CompilerOptions.MissingDeprecatedAnnotation :
+			case CompilerOptions.ParameterAssignment :
+			case CompilerOptions.MethodCanBeStatic :
+			case CompilerOptions.MethodCanBePotentiallyStatic :
+			case CompilerOptions.ExplicitlyClosedAutoCloseable :
+				return CategorizedProblem.CAT_CODE_STYLE;
+
+			case CompilerOptions.MaskedCatchBlock :
+			case CompilerOptions.NoImplicitStringConversion :
+			case CompilerOptions.NoEffectAssignment :
+			case CompilerOptions.AccidentalBooleanAssign :
+			case CompilerOptions.EmptyStatement :
+			case CompilerOptions.FinallyBlockNotCompleting :
+			case CompilerOptions.MissingSerialVersion :
+			case CompilerOptions.VarargsArgumentNeedCast :
+			case CompilerOptions.NullReference :
+			case CompilerOptions.PotentialNullReference :
+			case CompilerOptions.RedundantNullCheck :
+			case CompilerOptions.MissingEnumConstantCase :
+			case CompilerOptions.MissingDefaultCase :
+			case CompilerOptions.FallthroughCase :
+			case CompilerOptions.OverridingMethodWithoutSuperInvocation :
+			case CompilerOptions.ComparingIdentical :
+			case CompilerOptions.MissingSynchronizedModifierInInheritedMethod :
+			case CompilerOptions.ShouldImplementHashcode :
+			case CompilerOptions.DeadCode :
+			case CompilerOptions.UnusedObjectAllocation :
+			case CompilerOptions.UnclosedCloseable :
+			case CompilerOptions.PotentiallyUnclosedCloseable :
+				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
+			
+			case CompilerOptions.OverriddenPackageDefaultMethod :
+			case CompilerOptions.IncompatibleNonInheritedInterfaceMethod :
+			case CompilerOptions.LocalVariableHiding :
+			case CompilerOptions.FieldHiding :
+			case CompilerOptions.TypeHiding :
+				return CategorizedProblem.CAT_NAME_SHADOWING_CONFLICT;
+
+			case CompilerOptions.UnusedLocalVariable :
+			case CompilerOptions.UnusedArgument :
+			case CompilerOptions.UnusedImport :
+			case CompilerOptions.UnusedPrivateMember :
+			case CompilerOptions.UnusedDeclaredThrownException :
+			case CompilerOptions.UnnecessaryTypeCheck :
+			case CompilerOptions.UnnecessaryElse :
+			case CompilerOptions.UnhandledWarningToken :
+			case CompilerOptions.UnusedWarningToken :
+			case CompilerOptions.UnusedLabel :
+			case CompilerOptions.RedundantSuperinterface :
+			case CompilerOptions.RedundantSpecificationOfTypeArguments :
+			case CompilerOptions.UnusedTypeParameter:
+				return CategorizedProblem.CAT_UNNECESSARY_CODE;
+
+			case CompilerOptions.UsingDeprecatedAPI :
+				return CategorizedProblem.CAT_DEPRECATION;
+
+			case CompilerOptions.NonExternalizedString :
+				return CategorizedProblem.CAT_NLS;
+
+			case CompilerOptions.Task :
+				return CategorizedProblem.CAT_UNSPECIFIED; // TODO may want to improve
+			
+			case CompilerOptions.MissingJavadocComments :
+			case CompilerOptions.MissingJavadocTags :
+			case CompilerOptions.InvalidJavadoc :
+			case CompilerOptions.InvalidJavadoc|CompilerOptions.UsingDeprecatedAPI :
+				return CategorizedProblem.CAT_JAVADOC;
+
+			case CompilerOptions.UncheckedTypeOperation :
+			case CompilerOptions.RawTypeReference :
+				return CategorizedProblem.CAT_UNCHECKED_RAW;
+			
+			case CompilerOptions.ForbiddenReference :
+			case CompilerOptions.DiscouragedReference :
+				return CategorizedProblem.CAT_RESTRICTION;
+
+			case CompilerOptions.NullSpecViolation :
+			case CompilerOptions.NullAnnotationInferenceConflict :
+			case CompilerOptions.NullUncheckedConversion :
+			case CompilerOptions.MissingNonNullByDefaultAnnotation:
+			case CompilerOptions.NonnullParameterAnnotationDropped:
+				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
+			case CompilerOptions.RedundantNullAnnotation :
+				return CategorizedProblem.CAT_UNNECESSARY_CODE;
+
+			default:
+				break categorizeOnIrritant;
+		}
+	}
+	// categorize fatal problems per ID
+	switch (problemID) {
+		case IProblem.IsClassPathCorrect :
+		case IProblem.CorruptedSignature :
+			return CategorizedProblem.CAT_BUILDPATH;
+
+		default :
+			if ((problemID & IProblem.Syntax) != 0)
+				return CategorizedProblem.CAT_SYNTAX;
+			if ((problemID & IProblem.ImportRelated) != 0)
+				return CategorizedProblem.CAT_IMPORT;
+			if ((problemID & IProblem.TypeRelated) != 0)
+				return CategorizedProblem.CAT_TYPE;
+			if ((problemID & (IProblem.FieldRelated|IProblem.MethodRelated|IProblem.ConstructorRelated)) != 0)
+				return CategorizedProblem.CAT_MEMBER;
+	}
+	return CategorizedProblem.CAT_INTERNAL;
+}
+public void abortDueToInternalError(String errorMessage) {
+	this.abortDueToInternalError(errorMessage, null);
+}
+public void abortDueToInternalError(String errorMessage, ASTNode location) {
+	String[] arguments = new String[] {errorMessage};
+	this.handle(
+		IProblem.Unclassified,
+		arguments,
+		arguments,
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		location == null ? 0 : location.sourceStart,
+		location == null ? 0 : location.sourceEnd);
+}
+public void abstractMethodCannotBeOverridden(SourceTypeBinding type, MethodBinding concreteMethod) {
+
+	this.handle(
+		// %1 must be abstract since it cannot override the inherited package-private abstract method %2
+		IProblem.AbstractMethodCannotBeOverridden,
+		new String[] {
+			new String(type.sourceName()),
+			new String(
+					CharOperation.concat(
+						concreteMethod.declaringClass.readableName(),
+						concreteMethod.readableName(),
+						'.'))},
+		new String[] {
+			new String(type.sourceName()),
+			new String(
+					CharOperation.concat(
+						concreteMethod.declaringClass.shortReadableName(),
+						concreteMethod.shortReadableName(),
+						'.'))},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
+	if (type.isEnum() && type.isLocalType()) {
+		FieldBinding field = type.scope.enclosingMethodScope().initializedField;
+		FieldDeclaration decl = field.sourceField();
+		String[] arguments = new String[] {new String(decl.name), new String(methodDecl.selector)};
+		this.handle(
+			IProblem.AbstractMethodInEnum,
+			arguments,
+			arguments,
+			methodDecl.sourceStart,
+			methodDecl.sourceEnd);
+	} else {
+		String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)};
+		this.handle(
+			IProblem.AbstractMethodInAbstractClass,
+			arguments,
+			arguments,
+			methodDecl.sourceStart,
+			methodDecl.sourceEnd);
+	}
+}
+public void abstractMethodInConcreteClass(SourceTypeBinding type) {
+	if (type.isEnum() && type.isLocalType()) {
+		FieldBinding field = type.scope.enclosingMethodScope().initializedField;
+		FieldDeclaration decl = field.sourceField();
+		String[] arguments = new String[] {new String(decl.name)};
+		this.handle(
+			IProblem.EnumConstantCannotDefineAbstractMethod,
+			arguments,
+			arguments,
+			decl.sourceStart(),
+			decl.sourceEnd());
+	} else {
+		String[] arguments = new String[] {new String(type.sourceName())};
+		this.handle(
+			IProblem.AbstractMethodsInConcreteClass,
+			arguments,
+			arguments,
+			type.sourceStart(),
+			type.sourceEnd());
+	}
+}
+public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
+	if (type.isEnum() && type.isLocalType()) {
+		FieldBinding field = type.scope.enclosingMethodScope().initializedField;
+		FieldDeclaration decl = field.sourceField();
+		this.handle(
+			// Must implement the inherited abstract method %1
+			// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
+			IProblem.EnumConstantMustImplementAbstractMethod,
+			new String[] {
+			        new String(abstractMethod.selector),
+			        typesAsString(abstractMethod, false),
+			        new String(decl.name),
+			},
+			new String[] {
+			        new String(abstractMethod.selector),
+			        typesAsString(abstractMethod, true),
+			        new String(decl.name),
+			},
+			decl.sourceStart(),
+			decl.sourceEnd());
+	} else {
+		this.handle(
+			// Must implement the inherited abstract method %1
+			// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
+			IProblem.AbstractMethodMustBeImplemented,
+			new String[] {
+			        new String(abstractMethod.selector),
+			        typesAsString(abstractMethod, false),
+			        new String(abstractMethod.declaringClass.readableName()),
+			        new String(type.readableName()),
+			},
+			new String[] {
+			        new String(abstractMethod.selector),
+			        typesAsString(abstractMethod, true),
+			        new String(abstractMethod.declaringClass.shortReadableName()),
+			        new String(type.shortReadableName()),
+			},
+			type.sourceStart(),
+			type.sourceEnd());
+	}
+}
+public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod, MethodBinding concreteMethod) {
+	this.handle(
+		// Must implement the inherited abstract method %1
+		// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
+		IProblem.AbstractMethodMustBeImplementedOverConcreteMethod,
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, false),
+		        new String(abstractMethod.declaringClass.readableName()),
+		        new String(type.readableName()),
+		        new String(concreteMethod.selector),
+		        typesAsString(concreteMethod, false),
+		        new String(concreteMethod.declaringClass.readableName()),
+		},
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, true),
+		        new String(abstractMethod.declaringClass.shortReadableName()),
+		        new String(type.shortReadableName()),
+		        new String(concreteMethod.selector),
+		        typesAsString(concreteMethod, true),
+		        new String(concreteMethod.declaringClass.shortReadableName()),
+		},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void abstractMethodNeedingNoBody(AbstractMethodDeclaration method) {
+	this.handle(
+		IProblem.BodyForAbstractMethod,
+		NoArgument,
+		NoArgument,
+		method.sourceStart,
+		method.sourceEnd,
+		method,
+		method.compilationResult());
+}
+public void alreadyDefinedLabel(char[] labelName, ASTNode location) {
+	String[] arguments = new String[] {new String(labelName)};
+	this.handle(
+		IProblem.DuplicateLabel,
+		arguments,
+		arguments,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void annotationCannotOverrideMethod(MethodBinding overrideMethod, MethodBinding inheritedMethod) {
+	ASTNode location = overrideMethod.sourceMethod();
+	this.handle(
+		IProblem.AnnotationCannotOverrideMethod,
+		new String[] {
+				new String(overrideMethod.declaringClass.readableName()),
+				new String(inheritedMethod.declaringClass.readableName()),
+				new String(inheritedMethod.selector),
+				typesAsString(inheritedMethod, false)},
+		new String[] {
+				new String(overrideMethod.declaringClass.shortReadableName()),
+				new String(inheritedMethod.declaringClass.shortReadableName()),
+				new String(inheritedMethod.selector),
+				typesAsString(inheritedMethod, true)},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void annotationCircularity(TypeBinding sourceType, TypeBinding otherType, TypeReference reference) {
+	if (sourceType == otherType)
+		this.handle(
+			IProblem.AnnotationCircularitySelfReference,
+			new String[] {new String(sourceType.readableName())},
+			new String[] {new String(sourceType.shortReadableName())},
+			reference.sourceStart,
+			reference.sourceEnd);
+	else
+		this.handle(
+			IProblem.AnnotationCircularity,
+			new String[] {new String(sourceType.readableName()), new String(otherType.readableName())},
+			new String[] {new String(sourceType.shortReadableName()), new String(otherType.shortReadableName())},
+			reference.sourceStart,
+			reference.sourceEnd);
+}
+public void annotationMembersCannotHaveParameters(AnnotationMethodDeclaration annotationMethodDeclaration) {
+	this.handle(
+		IProblem.AnnotationMembersCannotHaveParameters,
+		NoArgument,
+		NoArgument,
+		annotationMethodDeclaration.sourceStart,
+		annotationMethodDeclaration.sourceEnd);
+}
+public void annotationMembersCannotHaveTypeParameters(AnnotationMethodDeclaration annotationMethodDeclaration) {
+	this.handle(
+		IProblem.AnnotationMembersCannotHaveTypeParameters,
+		NoArgument,
+		NoArgument,
+		annotationMethodDeclaration.sourceStart,
+		annotationMethodDeclaration.sourceEnd);
+}
+public void annotationTypeDeclarationCannotHaveConstructor(ConstructorDeclaration constructorDeclaration) {
+	this.handle(
+		IProblem.AnnotationTypeDeclarationCannotHaveConstructor,
+		NoArgument,
+		NoArgument,
+		constructorDeclaration.sourceStart,
+		constructorDeclaration.sourceEnd);
+}
+public void annotationTypeDeclarationCannotHaveSuperclass(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.AnnotationTypeDeclarationCannotHaveSuperclass,
+		NoArgument,
+		NoArgument,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+public void annotationTypeDeclarationCannotHaveSuperinterfaces(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.AnnotationTypeDeclarationCannotHaveSuperinterfaces,
+		NoArgument,
+		NoArgument,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+public void annotationTypeUsedAsSuperinterface(SourceTypeBinding type, TypeReference superInterfaceRef, ReferenceBinding superType) {
+	this.handle(
+		IProblem.AnnotationTypeUsedAsSuperInterface,
+		new String[] {new String(superType.readableName()), new String(type.sourceName())},
+		new String[] {new String(superType.shortReadableName()), new String(type.sourceName())},
+		superInterfaceRef.sourceStart,
+		superInterfaceRef.sourceEnd);
+}
+public void annotationValueMustBeAnnotation(TypeBinding annotationType, char[] name, Expression value, TypeBinding expectedType) {
+	String str = new String(name);
+	this.handle(
+		IProblem.AnnotationValueMustBeAnnotation,
+		new String[] { new String(annotationType.readableName()), str, new String(expectedType.readableName()),  },
+		new String[] { new String(annotationType.shortReadableName()), str, new String(expectedType.readableName()), },
+		value.sourceStart,
+		value.sourceEnd);
+}
+public void annotationValueMustBeArrayInitializer(TypeBinding annotationType, char[] name, Expression value) {
+	String str = new String(name);
+	this.handle(
+    	IProblem.AnnotationValueMustBeArrayInitializer,
+		new String[] { new String(annotationType.readableName()), str },
+		new String[] { new String(annotationType.shortReadableName()), str},
+    	value.sourceStart,
+    	value.sourceEnd);
+}
+public void annotationValueMustBeClassLiteral(TypeBinding annotationType, char[] name, Expression value) {
+	String str = new String(name);
+	this.handle(
+		IProblem.AnnotationValueMustBeClassLiteral,
+		new String[] { new String(annotationType.readableName()), str },
+		new String[] { new String(annotationType.shortReadableName()), str},
+		value.sourceStart,
+		value.sourceEnd);
+}
+public void annotationValueMustBeConstant(TypeBinding annotationType, char[] name, Expression value, boolean isEnum) {
+	String str = new String(name);
+	if (isEnum) {
+    	this.handle(
+    		IProblem.AnnotationValueMustBeAnEnumConstant,
+    		new String[] { new String(annotationType.readableName()), str },
+    		new String[] { new String(annotationType.shortReadableName()), str},
+    		value.sourceStart,
+    		value.sourceEnd);
+	} else {
+    	this.handle(
+    		IProblem.AnnotationValueMustBeConstant,
+    		new String[] { new String(annotationType.readableName()), str },
+    		new String[] { new String(annotationType.shortReadableName()), str},
+    		value.sourceStart,
+    		value.sourceEnd);
+    }
+}
+public void anonymousClassCannotExtendFinalClass(TypeReference reference, TypeBinding type) {
+	this.handle(
+		IProblem.AnonymousClassCannotExtendFinalClass,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void argumentTypeCannotBeVoid(ASTNode methodDecl, Argument arg) {
+	String[] arguments = new String[] { new String(arg.name) };
+	this.handle(
+		IProblem.ArgumentTypeCannotBeVoid,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void argumentTypeCannotBeVoidArray(Argument arg) {
+	this.handle(
+		IProblem.CannotAllocateVoidArray,
+		NoArgument,
+		NoArgument,
+		arg.type.sourceStart,
+		arg.type.sourceEnd);
+}
+public void arrayConstantsOnlyInArrayInitializers(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.ArrayConstantsOnlyInArrayInitializers,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void assignmentHasNoEffect(AbstractVariableDeclaration location, char[] name){
+	int severity = computeSeverity(IProblem.AssignmentHasNoEffect);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] { new String(name) };
+	int start = location.sourceStart;
+	int end = location.sourceEnd;
+	if (location.initialization != null) {
+		end = location.initialization.sourceEnd;
+	}
+	this.handle(
+			IProblem.AssignmentHasNoEffect,
+			arguments,
+			arguments,
+			severity,
+			start,
+			end);
+}
+public void assignmentHasNoEffect(Assignment location, char[] name){
+	int severity = computeSeverity(IProblem.AssignmentHasNoEffect);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] { new String(name) };
+	this.handle(
+			IProblem.AssignmentHasNoEffect,
+			arguments,
+			arguments,
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+}
+
+public void attemptToReturnNonVoidExpression(ReturnStatement returnStatement, TypeBinding expectedType) {
+	this.handle(
+		IProblem.VoidMethodReturnsValue,
+		new String[] {new String(expectedType.readableName())},
+		new String[] {new String(expectedType.shortReadableName())},
+		returnStatement.sourceStart,
+		returnStatement.sourceEnd);
+}
+
+
+public void attemptToReturnVoidValue(ReturnStatement returnStatement) {
+	this.handle(
+		IProblem.MethodReturnsVoid,
+		NoArgument,
+		NoArgument,
+		returnStatement.sourceStart,
+		returnStatement.sourceEnd);
+}
+public void autoboxing(Expression expression, TypeBinding originalType, TypeBinding convertedType) {
+	if (this.options.getSeverity(CompilerOptions.AutoBoxing) == ProblemSeverities.Ignore) return;
+	this.handle(
+		originalType.isBaseType() ? IProblem.BoxingConversion : IProblem.UnboxingConversion,
+		new String[] { new String(originalType.readableName()), new String(convertedType.readableName()), },
+		new String[] { new String(originalType.shortReadableName()), new String(convertedType.shortReadableName()), },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void boundCannotBeArray(ASTNode location, TypeBinding type) {
+	this.handle(
+		IProblem.BoundCannotBeArray,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void boundMustBeAnInterface(ASTNode location, TypeBinding type) {
+	this.handle(
+		IProblem.BoundMustBeAnInterface,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void bytecodeExceeds64KLimit(AbstractMethodDeclaration location) {
+	MethodBinding method = location.binding;
+	if (location.isConstructor()) {
+		this.handle(
+			IProblem.BytecodeExceeds64KLimitForConstructor,
+			new String[] {new String(location.selector), typesAsString(method, false)},
+			new String[] {new String(location.selector), typesAsString(method, true)},
+			ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+			location.sourceStart,
+			location.sourceEnd);
+	} else {
+		this.handle(
+			IProblem.BytecodeExceeds64KLimit,
+			new String[] {new String(location.selector), typesAsString(method, false)},
+			new String[] {new String(location.selector), typesAsString(method, true)},
+			ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void bytecodeExceeds64KLimit(LambdaExpression location) {
+	MethodBinding method = location.binding;
+		this.handle(
+			IProblem.BytecodeExceeds64KLimit,
+			new String[] {new String(method.selector), typesAsString(method, false)},
+			new String[] {new String(method.selector), typesAsString(method, true)},
+			ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+			location.sourceStart,
+			location.sourceEnd);
+}
+public void bytecodeExceeds64KLimit(TypeDeclaration location) {
+	this.handle(
+		IProblem.BytecodeExceeds64KLimitForClinit,
+		NoArgument,
+		NoArgument,
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void cannotAllocateVoidArray(Expression expression) {
+	this.handle(
+		IProblem.CannotAllocateVoidArray,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void cannotAssignToFinalField(FieldBinding field, ASTNode location) {
+	this.handle(
+		IProblem.FinalFieldAssignment,
+		new String[] {
+			(field.declaringClass == null ? "array" : new String(field.declaringClass.readableName())), //$NON-NLS-1$
+			new String(field.readableName())},
+		new String[] {
+			(field.declaringClass == null ? "array" : new String(field.declaringClass.shortReadableName())), //$NON-NLS-1$
+			new String(field.shortReadableName())},
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void cannotAssignToFinalLocal(LocalVariableBinding local, ASTNode location) {
+	int problemId = 0;
+	if ((local.tagBits & TagBits.MultiCatchParameter) != 0) {
+		problemId = IProblem.AssignmentToMultiCatchParameter;
+	} else if ((local.tagBits & TagBits.IsResource) != 0) {
+		problemId = IProblem.AssignmentToResource;
+	} else {
+		problemId = IProblem.NonBlankFinalLocalAssignment;
+	}
+	String[] arguments = new String[] { new String(local.readableName())};
+	this.handle(
+		problemId,
+		arguments,
+		arguments,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void cannotAssignToFinalOuterLocal(LocalVariableBinding local, ASTNode location) {
+	String[] arguments = new String[] {new String(local.readableName())};
+	this.handle(
+		IProblem.FinalOuterLocalAssignment,
+		arguments,
+		arguments,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void cannotDefineDimensionsAndInitializer(ArrayAllocationExpression expresssion) {
+	this.handle(
+		IProblem.CannotDefineDimensionExpressionsWithInit,
+		NoArgument,
+		NoArgument,
+		expresssion.sourceStart,
+		expresssion.sourceEnd);
+}
+public void cannotDireclyInvokeAbstractMethod(ASTNode invocationSite, MethodBinding method) {
+	this.handle(
+		IProblem.DirectInvocationOfAbstractMethod,
+		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+		new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+		invocationSite.sourceStart,
+		invocationSite.sourceEnd);
+}
+public void cannotExtendEnum(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) {
+	String name = new String(type.sourceName());
+	String superTypeFullName = new String(superTypeBinding.readableName());
+	String superTypeShortName = new String(superTypeBinding.shortReadableName());
+	if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName;
+	this.handle(
+		IProblem.CannotExtendEnum,
+		new String[] {superTypeFullName, name},
+		new String[] {superTypeShortName, name},
+		superclass.sourceStart,
+		superclass.sourceEnd);
+}
+public void cannotImportPackage(ImportReference importRef) {
+	String[] arguments = new String[] {CharOperation.toString(importRef.tokens)};
+	this.handle(
+		IProblem.CannotImportPackage,
+		arguments,
+		arguments,
+		importRef.sourceStart,
+		importRef.sourceEnd);
+}
+public void cannotInstantiate(Expression typeRef, TypeBinding type) {
+	this.handle(
+		IProblem.InvalidClassInstantiation,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		typeRef.sourceStart,
+		typeRef.sourceEnd);
+}
+public void cannotInvokeSuperConstructorInEnum(ExplicitConstructorCall constructorCall, MethodBinding enumConstructor) {
+	this.handle(
+		IProblem.CannotInvokeSuperConstructorInEnum,
+		new String[] {
+		        new String(enumConstructor.declaringClass.sourceName()),
+		        typesAsString(enumConstructor, false),
+		 },
+		new String[] {
+		        new String(enumConstructor.declaringClass.sourceName()),
+		        typesAsString(enumConstructor, true),
+		 },
+		constructorCall.sourceStart,
+		constructorCall.sourceEnd);
+}
+public void cannotReadSource(CompilationUnitDeclaration unit, AbortCompilationUnit abortException, boolean verbose) {
+	String fileName = new String(unit.compilationResult.fileName);
+	if (abortException.exception instanceof CharConversionException) {
+		// specific encoding issue
+		String encoding = abortException.encoding;
+		if (encoding == null) {
+			encoding = System.getProperty("file.encoding"); //$NON-NLS-1$
+		}
+		String[] arguments = new String[]{ fileName, encoding };
+		this.handle(
+				IProblem.InvalidEncoding,
+				arguments,
+				arguments,
+				0,
+				0);
+		return;
+	}
+	StringWriter stringWriter = new StringWriter();
+	PrintWriter writer = new PrintWriter(stringWriter);
+	if (verbose) {
+		abortException.exception.printStackTrace(writer);
+		System.err.println(stringWriter.toString());
+		stringWriter = new StringWriter();
+		writer = new PrintWriter(stringWriter);
+	}
+	writer.print(abortException.exception.getClass().getName());
+	writer.print(':');
+	writer.print(abortException.exception.getMessage());
+	String exceptionTrace = stringWriter.toString();
+	String[] arguments = new String[]{ fileName, exceptionTrace };
+	this.handle(
+			IProblem.CannotReadSource,
+			arguments,
+			arguments,
+			0,
+			0);
+}
+public void cannotReferToNonFinalOuterLocal(LocalVariableBinding local, ASTNode location) {
+	String[] arguments =new String[]{ new String(local.readableName())};
+	this.handle(
+		IProblem.OuterLocalMustBeFinal,
+		arguments,
+		arguments,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void cannotReferToNonEffectivelyFinalOuterLocal(LocalVariableBinding local, ASTNode location) {
+	String[] arguments = new String[] { new String(local.readableName()) };
+	this.handle(
+		IProblem.OuterLocalMustBeEffectivelyFinal, 
+		arguments,
+		arguments,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void cannotReturnInInitializer(ASTNode location) {
+	this.handle(
+		IProblem.CannotReturnInInitializer,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void cannotThrowNull(ASTNode expression) {
+	this.handle(
+		IProblem.CannotThrowNull,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void cannotThrowType(ASTNode exception, TypeBinding expectedType) {
+	this.handle(
+		IProblem.CannotThrowType,
+		new String[] {new String(expectedType.readableName())},
+		new String[] {new String(expectedType.shortReadableName())},
+		exception.sourceStart,
+		exception.sourceEnd);
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391092
+public void illegalArrayOfUnionType(char[] identifierName, TypeReference typeReference) {
+		this.handle(
+		IProblem.IllegalArrayOfUnionType,
+		NoArgument,
+		NoArgument,
+		typeReference.sourceStart,
+		typeReference.sourceEnd);
+}
+public void cannotUseQualifiedEnumConstantInCaseLabel(Reference location, FieldBinding field) {
+	this.handle(
+		IProblem.IllegalQualifiedEnumConstantLabel,
+		new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
+		new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
+		location.sourceStart(),
+		location.sourceEnd());
+}
+public void cannotUseSuperInCodeSnippet(int start, int end) {
+	this.handle(
+		IProblem.CannotUseSuperInCodeSnippet,
+		NoArgument,
+		NoArgument,
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		start,
+		end);
+}
+public void cannotUseSuperInJavaLangObject(ASTNode reference) {
+	this.handle(
+		IProblem.ObjectHasNoSuperclass,
+		NoArgument,
+		NoArgument,
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void targetTypeIsNotAFunctionalInterface(FunctionalExpression target) {
+	this.handle(
+		IProblem.TargetTypeNotAFunctionalInterface,
+		NoArgument,
+		NoArgument,
+		target.sourceStart,
+		target.sourceEnd);
+}
+public void illFormedParameterizationOfFunctionalInterface(FunctionalExpression target) {
+	this.handle(
+		IProblem.illFormedParameterizationOfFunctionalInterface,
+		NoArgument,
+		NoArgument,
+		target.sourceStart,
+		target.sourceEnd);
+}
+public void lambdaSignatureMismatched(LambdaExpression target) {
+	this.handle(
+		IProblem.lambdaSignatureMismatched,
+		NoArgument,
+		NoArgument,
+		target.sourceStart,
+		target.sourceEnd);
+}
+
+public void lambdaParameterTypeMismatched(Argument argument, TypeReference type, TypeBinding expectedParameterType) {
+	String name = new String(argument.name);
+	String expectedTypeFullName = new String(expectedParameterType.readableName());
+	String expectedTypeShortName = new String(expectedParameterType.shortReadableName());
+	this.handle(
+			expectedParameterType.isTypeVariable() ? IProblem.IncompatibleLambdaParameterType : IProblem.lambdaParameterTypeMismatched,
+			new String[] { name, expectedTypeFullName },
+			new String[] { name, expectedTypeShortName },
+			type.sourceStart,
+			type.sourceEnd);
+}
+public void lambdaExpressionCannotImplementGenericMethod(LambdaExpression lambda, MethodBinding sam) {
+	final String selector = new String(sam.selector);
+	this.handle(
+			IProblem.NoGenericLambda, 
+			new String[] { selector, new String(sam.declaringClass.readableName())},
+			new String[] { selector, new String(sam.declaringClass.shortReadableName())},
+			lambda.sourceStart,
+			lambda.sourceEnd);
+}
+public void caseExpressionMustBeConstant(Expression expression) {
+	this.handle(
+		IProblem.NonConstantExpression,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void classExtendFinalClass(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) {
+	String name = new String(type.sourceName());
+	String superTypeFullName = new String(superTypeBinding.readableName());
+	String superTypeShortName = new String(superTypeBinding.shortReadableName());
+	if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName;
+	this.handle(
+		IProblem.ClassExtendFinalClass,
+		new String[] {superTypeFullName, name},
+		new String[] {superTypeShortName, name},
+		superclass.sourceStart,
+		superclass.sourceEnd);
+}
+public void codeSnippetMissingClass(String missing, int start, int end) {
+	String[] arguments = new String[]{missing};
+	this.handle(
+		IProblem.CodeSnippetMissingClass,
+		arguments,
+		arguments,
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		start,
+		end);
+}
+public void codeSnippetMissingMethod(String className, String missingMethod, String argumentTypes, int start, int end) {
+	String[] arguments = new String[]{ className, missingMethod, argumentTypes };
+	this.handle(
+		IProblem.CodeSnippetMissingMethod,
+		arguments,
+		arguments,
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		start,
+		end);
+}
+public void comparingIdenticalExpressions(Expression comparison){
+	int severity = computeSeverity(IProblem.ComparingIdentical);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+			IProblem.ComparingIdentical,
+			NoArgument,
+			NoArgument,
+			severity,
+			comparison.sourceStart,
+			comparison.sourceEnd);
+}
+/*
+ * Given the current configuration, answers which category the problem
+ * falls into:
+ *		ProblemSeverities.Error | ProblemSeverities.Warning | ProblemSeverities.Ignore
+ * when different from Ignore, severity can be coupled with ProblemSeverities.Optional
+ * to indicate that this problem is configurable through options
+ */
+public int computeSeverity(int problemID){
+
+	switch (problemID) {
+		case IProblem.VarargsConflict :
+			return ProblemSeverities.Warning;
+ 		case IProblem.TypeCollidesWithPackage :
+			return ProblemSeverities.Warning;
+
+		/*
+		 * Javadoc tags resolved references errors
+		 */
+		case IProblem.JavadocInvalidParamName:
+		case IProblem.JavadocDuplicateParamName:
+		case IProblem.JavadocMissingParamName:
+		case IProblem.JavadocInvalidMemberTypeQualification:
+		case IProblem.JavadocInvalidThrowsClassName:
+		case IProblem.JavadocDuplicateThrowsClassName:
+		case IProblem.JavadocMissingThrowsClassName:
+		case IProblem.JavadocMissingSeeReference:
+		case IProblem.JavadocInvalidValueReference:
+		case IProblem.JavadocUndefinedField:
+		case IProblem.JavadocAmbiguousField:
+		case IProblem.JavadocUndefinedConstructor:
+		case IProblem.JavadocAmbiguousConstructor:
+		case IProblem.JavadocUndefinedMethod:
+		case IProblem.JavadocAmbiguousMethod:
+		case IProblem.JavadocAmbiguousMethodReference:
+		case IProblem.JavadocParameterMismatch:
+		case IProblem.JavadocUndefinedType:
+		case IProblem.JavadocAmbiguousType:
+		case IProblem.JavadocInternalTypeNameProvided:
+		case IProblem.JavadocNoMessageSendOnArrayType:
+		case IProblem.JavadocNoMessageSendOnBaseType:
+		case IProblem.JavadocInheritedMethodHidesEnclosingName:
+		case IProblem.JavadocInheritedFieldHidesEnclosingName:
+		case IProblem.JavadocInheritedNameHidesEnclosingTypeName:
+		case IProblem.JavadocNonStaticTypeFromStaticInvocation:
+		case IProblem.JavadocGenericMethodTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericMethod:
+		case IProblem.JavadocIncorrectArityForParameterizedMethod:
+		case IProblem.JavadocParameterizedMethodArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericMethod:
+		case IProblem.JavadocGenericConstructorTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericConstructor:
+		case IProblem.JavadocIncorrectArityForParameterizedConstructor:
+		case IProblem.JavadocParameterizedConstructorArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericConstructor:
+			if (!this.options.reportInvalidJavadocTags) {
+				return ProblemSeverities.Ignore;
+			}
+			break;
+		/*
+		 * Javadoc invalid tags due to deprecated references
+		 */
+		case IProblem.JavadocUsingDeprecatedField:
+		case IProblem.JavadocUsingDeprecatedConstructor:
+		case IProblem.JavadocUsingDeprecatedMethod:
+		case IProblem.JavadocUsingDeprecatedType:
+			if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsDeprecatedRef)) {
+				return ProblemSeverities.Ignore;
+			}
+			break;
+		/*
+		 * Javadoc invalid tags due to non-visible references
+		 */
+		case IProblem.JavadocNotVisibleField:
+		case IProblem.JavadocNotVisibleConstructor:
+		case IProblem.JavadocNotVisibleMethod:
+		case IProblem.JavadocNotVisibleType:
+		case IProblem.JavadocHiddenReference:
+			if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsNotVisibleRef)) {
+				return ProblemSeverities.Ignore;
+			}
+			break;
+		/*
+		 * Javadoc missing tag descriptions
+		 */
+		case IProblem.JavadocEmptyReturnTag:
+			if (CompilerOptions.NO_TAG.equals(this.options.reportMissingJavadocTagDescription)) {
+				return ProblemSeverities.Ignore;
+			}
+			break;
+		case IProblem.JavadocMissingTagDescription:
+			if (! CompilerOptions.ALL_STANDARD_TAGS.equals(this.options.reportMissingJavadocTagDescription)) {
+				return ProblemSeverities.Ignore;
+			}
+			break;
+	}
+	int irritant = getIrritant(problemID);
+	if (irritant != 0) {
+		if ((problemID & IProblem.Javadoc) != 0 && !this.options.docCommentSupport)
+			return ProblemSeverities.Ignore;
+		return this.options.getSeverity(irritant);
+	}
+	return ProblemSeverities.Error | ProblemSeverities.Fatal;
+}
+public void conditionalArgumentsIncompatibleTypes(ConditionalExpression expression, TypeBinding trueType, TypeBinding falseType) {
+	this.handle(
+		IProblem.IncompatibleTypesInConditionalOperator,
+		new String[] {new String(trueType.readableName()), new String(falseType.readableName())},
+		new String[] {new String(trueType.sourceName()), new String(falseType.sourceName())},
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void conflictingImport(ImportReference importRef) {
+	String[] arguments = new String[] {CharOperation.toString(importRef.tokens)};
+	this.handle(
+		IProblem.ConflictingImport,
+		arguments,
+		arguments,
+		importRef.sourceStart,
+		importRef.sourceEnd);
+}
+public void constantOutOfRange(Literal literal, TypeBinding literalType) {
+	String[] arguments = new String[] {new String(literalType.readableName()), new String(literal.source())};
+	this.handle(
+		IProblem.NumericValueOutOfRange,
+		arguments,
+		arguments,
+		literal.sourceStart,
+		literal.sourceEnd);
+}
+public void corruptedSignature(TypeBinding enclosingType, char[] signature, int position) {
+	this.handle(
+		IProblem.CorruptedSignature,
+		new String[] { new String(enclosingType.readableName()), new String(signature), String.valueOf(position) },
+		new String[] { new String(enclosingType.shortReadableName()), new String(signature), String.valueOf(position) },
+		ProblemSeverities.Error | ProblemSeverities.Abort | ProblemSeverities.Fatal,
+		0,
+		0);
+}
+public void defaultMethodOverridesObjectMethod(MethodBinding currentMethod) {
+	// Java 8 feature
+	AbstractMethodDeclaration method = currentMethod.sourceMethod();
+	int sourceStart = 0;
+	int sourceEnd = 0;
+	if (method != null) {
+		sourceStart = method.sourceStart;
+		sourceEnd = method.sourceEnd;
+	}
+	this.handle(
+		IProblem.DefaultMethodOverridesObjectMethod,
+		NoArgument, NoArgument,
+		sourceStart, sourceEnd);
+}
+
+public void deprecatedField(FieldBinding field, ASTNode location) {
+	int severity = computeSeverity(IProblem.UsingDeprecatedField);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.UsingDeprecatedField,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		severity,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+
+public void deprecatedMethod(MethodBinding method, ASTNode location) {
+	boolean isConstructor = method.isConstructor();
+	int severity = computeSeverity(isConstructor ? IProblem.UsingDeprecatedConstructor : IProblem.UsingDeprecatedMethod);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (isConstructor) {
+		int start = -1;
+		if(location instanceof AllocationExpression) {
+			// omit the new keyword from the warning marker
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=300031
+			AllocationExpression allocationExpression = (AllocationExpression) location;
+			if (allocationExpression.enumConstant != null) {
+				start = allocationExpression.enumConstant.sourceStart;
+			}
+			start = allocationExpression.type.sourceStart;
+		}
+		this.handle(
+			IProblem.UsingDeprecatedConstructor,
+			new String[] {new String(method.declaringClass.readableName()), typesAsString(method, false)},
+			new String[] {new String(method.declaringClass.shortReadableName()), typesAsString(method, true)},
+			severity,
+			(start == -1) ? location.sourceStart : start,
+			location.sourceEnd);
+	} else {
+		int start = -1;
+		if (location instanceof MessageSend) {
+			// start the warning marker from the location where the name of the method starts
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=300031
+			start = (int) (((MessageSend)location).nameSourcePosition >>> 32);
+		}
+		this.handle(
+			IProblem.UsingDeprecatedMethod,
+			new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+			new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+			severity,
+			(start == -1) ? location.sourceStart : start,
+			location.sourceEnd);
+	}
+}
+public void deprecatedType(TypeBinding type, ASTNode location) {
+	deprecatedType(type, location, Integer.MAX_VALUE);
+}
+// The argument 'index' makes sure that we demarcate partial types correctly while marking off
+// a deprecated type in a qualified reference (see bug 292510)
+public void deprecatedType(TypeBinding type, ASTNode location, int index) {
+	if (location == null) return; // 1G828DN - no type ref for synthetic arguments
+	int severity = computeSeverity(IProblem.UsingDeprecatedType);
+	if (severity == ProblemSeverities.Ignore) return;
+	type = type.leafComponentType();
+	int sourceStart = -1;
+	if (location instanceof QualifiedTypeReference) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300031
+		QualifiedTypeReference ref = (QualifiedTypeReference) location;
+		if (index < Integer.MAX_VALUE) {
+			sourceStart = (int) (ref.sourcePositions[index] >> 32);
+		}
+	}
+	this.handle(
+		IProblem.UsingDeprecatedType,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		severity,
+		(sourceStart == -1) ? location.sourceStart : sourceStart,
+		nodeSourceEnd(null, location, index));
+}
+public void disallowedTargetForAnnotation(Annotation annotation) {
+	this.handle(
+		IProblem.DisallowedTargetForAnnotation,
+		new String[] {new String(annotation.resolvedType.readableName())},
+		new String[] {new String(annotation.resolvedType.shortReadableName())},
+		annotation.sourceStart,
+		annotation.sourceEnd);
+}
+public void explitAnnotationTargetRequired(Annotation annotation) {
+	this.handle(IProblem.ExplicitAnnotationTargetRequired,
+			NoArgument,
+			NoArgument,
+			annotation.sourceStart,
+			annotation.sourceEnd);
+}
+public void polymorphicMethodNotBelow17(ASTNode node) {
+	this.handle(
+			IProblem.PolymorphicMethodNotBelow17,
+			NoArgument,
+			NoArgument,
+			node.sourceStart,
+			node.sourceEnd);
+}
+public void multiCatchNotBelow17(ASTNode node) {
+	this.handle(
+			IProblem.MultiCatchNotBelow17,
+			NoArgument,
+			NoArgument,
+			node.sourceStart,
+			node.sourceEnd);
+}
+public void duplicateAnnotation(Annotation annotation) {
+	this.handle(
+		IProblem.DuplicateAnnotation,
+		new String[] {new String(annotation.resolvedType.readableName())},
+		new String[] {new String(annotation.resolvedType.shortReadableName())},
+		annotation.sourceStart,
+		annotation.sourceEnd);
+}
+public void duplicateAnnotationValue(TypeBinding annotationType, MemberValuePair memberValuePair) {
+	String name = 	new String(memberValuePair.name);
+	this.handle(
+		IProblem.DuplicateAnnotationMember,
+		new String[] { name, new String(annotationType.readableName())},
+		new String[] {	name, new String(annotationType.shortReadableName())},
+		memberValuePair.sourceStart,
+		memberValuePair.sourceEnd);
+}
+public void duplicateBounds(ASTNode location, TypeBinding type) {
+	this.handle(
+		IProblem.DuplicateBounds,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void duplicateCase(CaseStatement caseStatement) {
+	this.handle(
+		IProblem.DuplicateCase,
+		NoArgument,
+		NoArgument,
+		caseStatement.sourceStart,
+		caseStatement.sourceEnd);
+}
+public void duplicateDefaultCase(ASTNode statement) {
+	this.handle(
+		IProblem.DuplicateDefaultCase,
+		NoArgument,
+		NoArgument,
+		statement.sourceStart,
+		statement.sourceEnd);
+}
+public void duplicateEnumSpecialMethod(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
+    MethodBinding method = methodDecl.binding;
+	this.handle(
+		IProblem.CannotDeclareEnumSpecialMethod,
+		new String[] {
+	        new String(methodDecl.selector),
+			new String(method.declaringClass.readableName()),
+			typesAsString(method, false)},
+		new String[] {
+			new String(methodDecl.selector),
+			new String(method.declaringClass.shortReadableName()),
+			typesAsString(method, true)},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) {
+	this.handle(
+		IProblem.DuplicateField,
+		new String[] {new String(type.sourceName()), new String(fieldDecl.name)},
+		new String[] {new String(type.shortReadableName()), new String(fieldDecl.name)},
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void duplicateImport(ImportReference importRef) {
+	String[] arguments = new String[] {CharOperation.toString(importRef.tokens)};
+	this.handle(
+		IProblem.DuplicateImport,
+		arguments,
+		arguments,
+		importRef.sourceStart,
+		importRef.sourceEnd);
+}
+
+public void duplicateInheritedMethods(SourceTypeBinding type, MethodBinding inheritedMethod1, MethodBinding inheritedMethod2) {
+	if (inheritedMethod1.declaringClass != inheritedMethod2.declaringClass) {
+		int problemID = (inheritedMethod1.isDefaultMethod() && inheritedMethod2.isDefaultMethod())
+				? IProblem.DuplicateInheritedDefaultMethods
+				: IProblem.DuplicateInheritedMethods;
+		this.handle(
+			problemID,
+			new String[] {
+		        new String(inheritedMethod1.selector),
+				typesAsString(inheritedMethod1, inheritedMethod1.original().parameters, false),
+				typesAsString(inheritedMethod2, inheritedMethod2.original().parameters, false),
+				new String(inheritedMethod1.declaringClass.readableName()),
+				new String(inheritedMethod2.declaringClass.readableName()),
+			},
+			new String[] {
+				new String(inheritedMethod1.selector),
+				typesAsString(inheritedMethod1, inheritedMethod1.original().parameters, true),
+				typesAsString(inheritedMethod2, inheritedMethod2.original().parameters, true),
+				new String(inheritedMethod1.declaringClass.shortReadableName()),
+				new String(inheritedMethod2.declaringClass.shortReadableName()),
+			},
+			type.sourceStart(),
+			type.sourceEnd());
+		return;
+	}
+	// Handle duplicates from same class.
+	this.handle(
+		IProblem.DuplicateParameterizedMethods,
+		new String[] {
+	        new String(inheritedMethod1.selector),
+			new String(inheritedMethod1.declaringClass.readableName()),
+			typesAsString(inheritedMethod1, inheritedMethod1.original().parameters, false),
+			typesAsString(inheritedMethod2, inheritedMethod2.original().parameters, false)},
+		new String[] {
+			new String(inheritedMethod1.selector),
+			new String(inheritedMethod1.declaringClass.shortReadableName()),
+			typesAsString(inheritedMethod1, inheritedMethod1.original().parameters, true),
+			typesAsString(inheritedMethod2, inheritedMethod2.original().parameters, true)},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void duplicateInitializationOfBlankFinalField(FieldBinding field, Reference reference) {
+	String[] arguments = new String[]{ new String(field.readableName())};
+	this.handle(
+		IProblem.DuplicateBlankFinalFieldInitialization,
+		arguments,
+		arguments,
+		nodeSourceStart(field, reference),
+		nodeSourceEnd(field, reference));
+}
+public void duplicateInitializationOfFinalLocal(LocalVariableBinding local, ASTNode location) {
+	String[] arguments = new String[] { new String(local.readableName())};
+	this.handle(
+		IProblem.DuplicateFinalLocalInitialization,
+		arguments,
+		arguments,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, boolean equalParameters, int severity) {
+    MethodBinding method = methodDecl.binding;
+    if (equalParameters) {
+		this.handle(
+			IProblem.DuplicateMethod,
+			new String[] {
+		        new String(methodDecl.selector),
+				new String(method.declaringClass.readableName()),
+				typesAsString(method, false)},
+			new String[] {
+				new String(methodDecl.selector),
+				new String(method.declaringClass.shortReadableName()),
+				typesAsString(method, true)},
+			severity,
+			methodDecl.sourceStart,
+			methodDecl.sourceEnd);
+    } else {
+        int length = method.parameters.length;
+        TypeBinding[] erasures = new TypeBinding[length];
+        for (int i = 0; i < length; i++)  {
+            erasures[i] = method.parameters[i].erasure();
+        }
+		this.handle(
+			IProblem.DuplicateMethodErasure,
+			new String[] {
+		        new String(methodDecl.selector),
+				new String(method.declaringClass.readableName()),
+				typesAsString(method, false),
+				typesAsString(method, erasures, false) } ,
+			new String[] {
+				new String(methodDecl.selector),
+				new String(method.declaringClass.shortReadableName()),
+				typesAsString(method, true),
+				typesAsString(method, erasures, true) },
+			severity,
+			methodDecl.sourceStart,
+			methodDecl.sourceEnd);
+    }
+}
+
+public void duplicateModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
+/* to highlight modifiers use:
+	this.handle(
+		new Problem(
+			DuplicateModifierForField,
+			new String[] {new String(fieldDecl.name)},
+			fieldDecl.modifiers.sourceStart,
+			fieldDecl.modifiers.sourceEnd));
+*/
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+	this.handle(
+		IProblem.DuplicateModifierForField,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void duplicateModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.DuplicateModifierForMethod,
+		new String[] {new String(type.sourceName()), new String(methodDecl.selector)},
+		new String[] {new String(type.shortReadableName()), new String(methodDecl.selector)},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void duplicateModifierForType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.DuplicateModifierForType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void duplicateModifierForVariable(LocalDeclaration localDecl, boolean complainForArgument) {
+	String[] arguments = new String[] {new String(localDecl.name)};
+	this.handle(
+		complainForArgument
+			? IProblem.DuplicateModifierForArgument
+			: IProblem.DuplicateModifierForVariable,
+		arguments,
+		arguments,
+		localDecl.sourceStart,
+		localDecl.sourceEnd);
+}
+public void duplicateNestedType(TypeDeclaration typeDecl) {
+	String[] arguments = new String[] {new String(typeDecl.name)};
+	this.handle(
+		IProblem.DuplicateNestedType,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd);
+}
+public void duplicateSuperinterface(SourceTypeBinding type, TypeReference reference, ReferenceBinding superType) {
+	this.handle(
+		IProblem.DuplicateSuperInterface,
+		new String[] {
+			new String(superType.readableName()),
+			new String(type.sourceName())},
+		new String[] {
+			new String(superType.shortReadableName()),
+			new String(type.sourceName())},
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void duplicateTargetInTargetAnnotation(TypeBinding annotationType, NameReference reference) {
+	FieldBinding field = reference.fieldBinding();
+	String name = 	new String(field.name);
+	this.handle(
+		IProblem.DuplicateTargetInTargetAnnotation,
+		new String[] { name, new String(annotationType.readableName())},
+		new String[] {	name, new String(annotationType.shortReadableName())},
+		nodeSourceStart(field, reference),
+		nodeSourceEnd(field, reference));
+}
+public void duplicateTypeParameterInType(TypeParameter typeParameter) {
+	this.handle(
+		IProblem.DuplicateTypeVariable,
+		new String[] { new String(typeParameter.name)},
+		new String[] { new String(typeParameter.name)},
+		typeParameter.sourceStart,
+		typeParameter.sourceEnd);
+}
+public void duplicateTypes(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
+	String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)};
+	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
+	int end = typeDecl.sourceEnd;
+	if (end <= 0) {
+		end = -1;
+	}
+	this.handle(
+		IProblem.DuplicateTypes,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		end,
+		compUnitDecl.compilationResult);
+}
+public void emptyControlFlowStatement(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.EmptyControlFlowStatement,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void enumAbstractMethodMustBeImplemented(AbstractMethodDeclaration method) {
+	MethodBinding abstractMethod = method.binding;
+	this.handle(
+		// Must implement the inherited abstract method %1
+		// 8.4.3 - Every non-abstract subclass of an abstract type, A, must provide a concrete implementation of all of A's methods.
+		IProblem.EnumAbstractMethodMustBeImplemented,
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, false),
+		        new String(abstractMethod.declaringClass.readableName()),
+		},
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, true),
+		        new String(abstractMethod.declaringClass.shortReadableName()),
+		},
+		method.sourceStart(),
+		method.sourceEnd());
+}
+public void enumConstantMustImplementAbstractMethod(AbstractMethodDeclaration method, FieldDeclaration field) {
+	MethodBinding abstractMethod = method.binding;
+	this.handle(
+		IProblem.EnumConstantMustImplementAbstractMethod,
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, false),
+		        new String(field.name),
+		},
+		new String[] {
+		        new String(abstractMethod.selector),
+		        typesAsString(abstractMethod, true),
+		        new String(field.name),
+		},
+		field.sourceStart(),
+		field.sourceEnd());
+}
+public void enumConstantsCannotBeSurroundedByParenthesis(Expression expression) {
+	this.handle(
+		IProblem.EnumConstantsCannotBeSurroundedByParenthesis,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void enumStaticFieldUsedDuringInitialization(FieldBinding field, ASTNode location) {
+	this.handle(
+		IProblem.EnumStaticFieldInInInitializerContext,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void enumSwitchCannotTargetField(Reference reference, FieldBinding field) {
+	this.handle(
+			IProblem.EnumSwitchCannotTargetField,
+			new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
+			new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
+			nodeSourceStart(field, reference),
+			nodeSourceEnd(field, reference));
+}
+public void errorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params) {
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	for (int i = 0, length = params.length; i < length; i++) {
+		if (i != 0){
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(params[i].readableName()));
+		shortBuffer.append(new String(params[i].shortReadableName()));
+	}
+
+	int id = recType.isArrayType() ? IProblem.NoMessageSendOnArrayType : IProblem.NoMessageSendOnBaseType;
+	this.handle(
+		id,
+		new String[] {new String(recType.readableName()), new String(messageSend.selector), buffer.toString()},
+		new String[] {new String(recType.shortReadableName()), new String(messageSend.selector), shortBuffer.toString()},
+		messageSend.sourceStart,
+		messageSend.sourceEnd);
+}
+public void errorNoMethodFor(Expression expression, TypeBinding recType, char [] selector, TypeBinding[] params) {
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	for (int i = 0, length = params.length; i < length; i++) {
+		if (i != 0){
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(params[i].readableName()));
+		shortBuffer.append(new String(params[i].shortReadableName()));
+	}
+
+	int id = recType.isArrayType() ? IProblem.NoMessageSendOnArrayType : IProblem.NoMessageSendOnBaseType;
+	this.handle(
+		id,
+		new String[] { new String(recType.readableName()), new String(selector), buffer.toString() },
+		new String[] { new String(recType.shortReadableName()), new String(selector), shortBuffer.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void errorThisSuperInStatic(ASTNode reference) {
+	String[] arguments = new String[] {reference.isSuper() ? "super" : "this"}; //$NON-NLS-2$ //$NON-NLS-1$
+	this.handle(
+		IProblem.ThisInStaticContext,
+		arguments,
+		arguments,
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void expressionShouldBeAVariable(Expression expression) {
+	this.handle(
+		IProblem.ExpressionShouldBeAVariable,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void fakeReachable(ASTNode location) {
+	int sourceStart = location.sourceStart;
+	int sourceEnd = location.sourceEnd;
+	if (location instanceof LocalDeclaration) {
+		LocalDeclaration declaration = (LocalDeclaration) location;
+		sourceStart = declaration.declarationSourceStart;
+		sourceEnd = declaration.declarationSourceEnd;
+	}	
+	this.handle(
+		IProblem.DeadCode,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void fieldHiding(FieldDeclaration fieldDecl, Binding hiddenVariable) {
+	FieldBinding field = fieldDecl.binding;
+	if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name)
+			&& field.isStatic()
+			&& field.isPrivate()
+			&& field.isFinal()
+			&& TypeBinding.LONG == field.type) {
+		ReferenceBinding referenceBinding = field.declaringClass;
+		if (referenceBinding != null) {
+			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
+				return; // do not report field hiding for serialVersionUID field for class that implements Serializable
+			}
+		}
+	}
+	if (CharOperation.equals(TypeConstants.SERIALPERSISTENTFIELDS, field.name)
+			&& field.isStatic()
+			&& field.isPrivate()
+			&& field.isFinal()
+			&& field.type.dimensions() == 1
+			&& CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTSTREAMFIELD, field.type.leafComponentType().readableName())) {
+		ReferenceBinding referenceBinding = field.declaringClass;
+		if (referenceBinding != null) {
+			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
+				return; // do not report field hiding for serialPersistenFields field for class that implements Serializable
+			}
+		}
+	}
+	boolean isLocal = hiddenVariable instanceof LocalVariableBinding;
+	int severity = computeSeverity(isLocal ? IProblem.FieldHidingLocalVariable : IProblem.FieldHidingField);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (isLocal) {
+		this.handle(
+			IProblem.FieldHidingLocalVariable,
+			new String[] {new String(field.declaringClass.readableName()), new String(field.name) },
+			new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name) },
+			severity,
+			nodeSourceStart(hiddenVariable, fieldDecl),
+			nodeSourceEnd(hiddenVariable, fieldDecl));
+	} else if (hiddenVariable instanceof FieldBinding) {
+		FieldBinding hiddenField = (FieldBinding) hiddenVariable;
+		this.handle(
+			IProblem.FieldHidingField,
+			new String[] {new String(field.declaringClass.readableName()), new String(field.name) , new String(hiddenField.declaringClass.readableName())  },
+			new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name) , new String(hiddenField.declaringClass.shortReadableName()) },
+			severity,
+			nodeSourceStart(hiddenField, fieldDecl),
+			nodeSourceEnd(hiddenField, fieldDecl));
+	}
+}
+public void fieldsOrThisBeforeConstructorInvocation(ThisReference reference) {
+	this.handle(
+		IProblem.ThisSuperDuringConstructorInvocation,
+		NoArgument,
+		NoArgument,
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void finallyMustCompleteNormally(Block finallyBlock) {
+	this.handle(
+		IProblem.FinallyMustCompleteNormally,
+		NoArgument,
+		NoArgument,
+		finallyBlock.sourceStart,
+		finallyBlock.sourceEnd);
+}
+public void finalMethodCannotBeOverridden(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	this.handle(
+		// Cannot override the final method from %1
+		// 8.4.3.3 - Final methods cannot be overridden or hidden.
+		IProblem.FinalMethodCannotBeOverridden,
+		new String[] {new String(inheritedMethod.declaringClass.readableName())},
+		new String[] {new String(inheritedMethod.declaringClass.shortReadableName())},
+		currentMethod.sourceStart(),
+		currentMethod.sourceEnd());
+}
+public void finalVariableBound(TypeVariableBinding typeVariable, TypeReference typeRef) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return;
+	int severity = computeSeverity(IProblem.FinalBoundForTypeVariable);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.FinalBoundForTypeVariable,
+		new String[] { new String(typeVariable.sourceName), new String(typeRef.resolvedType.readableName())},
+		new String[] { new String(typeVariable.sourceName), new String(typeRef.resolvedType.shortReadableName())},
+		severity,
+		typeRef.sourceStart,
+		typeRef.sourceEnd);
+}
+/** @param classpathEntryType one of {@link AccessRestriction#COMMAND_LINE},
+ * {@link AccessRestriction#LIBRARY}, {@link AccessRestriction#PROJECT} */
+public void forbiddenReference(FieldBinding field, ASTNode location,
+		 byte classpathEntryType, String classpathEntryName, int problemId) {
+	int severity = computeSeverity(problemId);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		problemId,
+		new String[] { new String(field.readableName()) }, // distinct from msg arg for quickfix purpose
+		getElaborationId(IProblem.ForbiddenReference, (byte) (FIELD_ACCESS | classpathEntryType)),
+		new String[] {
+			classpathEntryName,
+			new String(field.shortReadableName()),
+	        new String(field.declaringClass.shortReadableName())},
+	    severity,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+/** @param classpathEntryType one of {@link AccessRestriction#COMMAND_LINE},
+ * {@link AccessRestriction#LIBRARY}, {@link AccessRestriction#PROJECT} */
+public void forbiddenReference(MethodBinding method, ASTNode location,
+		byte classpathEntryType, String classpathEntryName, int problemId) {
+	int severity = computeSeverity(problemId);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (method.isConstructor())
+		this.handle(
+			problemId,
+			new String[] { new String(method.readableName()) }, // distinct from msg arg for quickfix purpose
+			getElaborationId(IProblem.ForbiddenReference, (byte) (CONSTRUCTOR_ACCESS | classpathEntryType)),
+			new String[] {
+				classpathEntryName,
+				new String(method.shortReadableName())},
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+	else
+		this.handle(
+			problemId,
+			new String[] { new String(method.readableName()) }, // distinct from msg arg for quickfix purpose
+			getElaborationId(IProblem.ForbiddenReference, (byte) (METHOD_ACCESS | classpathEntryType)),
+			new String[] {
+				classpathEntryName,
+				new String(method.shortReadableName()),
+		        new String(method.declaringClass.shortReadableName())},
+		    severity,
+			location.sourceStart,
+			location.sourceEnd);
+}
+/** @param classpathEntryType one of {@link AccessRestriction#COMMAND_LINE},
+ * {@link AccessRestriction#LIBRARY}, {@link AccessRestriction#PROJECT} */
+public void forbiddenReference(TypeBinding type, ASTNode location,
+		byte classpathEntryType, String classpathEntryName, int problemId) {
+	if (location == null) return;
+	int severity = computeSeverity(problemId);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		problemId,
+		new String[] { new String(type.readableName()) }, // distinct from msg arg for quickfix purpose
+		getElaborationId(IProblem.ForbiddenReference, /* TYPE_ACCESS | */ classpathEntryType), // TYPE_ACCESS values to 0
+		new String[] {
+			classpathEntryName,
+			new String(type.shortReadableName())},
+		severity,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void forwardReference(Reference reference, int indexInQualification, FieldBinding field) {
+	this.handle(
+		IProblem.ReferenceToForwardField,
+		NoArgument,
+		NoArgument,
+		nodeSourceStart(field, reference, indexInQualification),
+		nodeSourceEnd(field, reference, indexInQualification));
+}
+public void forwardTypeVariableReference(ASTNode location, TypeVariableBinding type) {
+	this.handle(
+		IProblem.ReferenceToForwardTypeVariable,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void genericTypeCannotExtendThrowable(TypeDeclaration typeDecl) {
+	ASTNode location = typeDecl.binding.isAnonymousType() ? typeDecl.allocation.type : typeDecl.superclass;
+	this.handle(
+		IProblem.GenericTypeCannotExtendThrowable,
+		new String[]{ new String(typeDecl.binding.readableName()) },
+		new String[]{ new String(typeDecl.binding.shortReadableName()) },
+		location.sourceStart,
+		location.sourceEnd);
+}
+// use this private API when the compilation unit result can be found through the
+// reference context. Otherwise, use the other API taking a problem and a compilation result
+// as arguments
+private void handle(
+		int problemId,
+		String[] problemArguments,
+		int elaborationId,
+		String[] messageArguments,
+		int severity,
+		int problemStartPosition,
+		int problemEndPosition){
+	this.handle(
+			problemId,
+			problemArguments,
+			elaborationId,
+			messageArguments,
+			severity,
+			problemStartPosition,
+			problemEndPosition,
+			this.referenceContext,
+			this.referenceContext == null ? null : this.referenceContext.compilationResult());
+	this.referenceContext = null;
+}
+// use this private API when the compilation unit result can be found through the
+// reference context. Otherwise, use the other API taking a problem and a compilation result
+// as arguments
+private void handle(
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int problemStartPosition,
+	int problemEndPosition){
+
+	this.handle(
+			problemId,
+			problemArguments,
+			messageArguments,
+			problemStartPosition,
+			problemEndPosition,
+			this.referenceContext,
+			this.referenceContext == null ? null : this.referenceContext.compilationResult());
+	this.referenceContext = null;
+}
+// use this private API when the compilation unit result cannot be found through the
+// reference context.
+private void handle(
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int problemStartPosition,
+	int problemEndPosition,
+	CompilationResult unitResult){
+
+	this.handle(
+			problemId,
+			problemArguments,
+			messageArguments,
+			problemStartPosition,
+			problemEndPosition,
+			this.referenceContext,
+			unitResult);
+	this.referenceContext = null;
+}
+// use this private API when the compilation unit result can be found through the
+// reference context. Otherwise, use the other API taking a problem and a compilation result
+// as arguments
+private void handle(
+	int problemId,
+	String[] problemArguments,
+	String[] messageArguments,
+	int severity,
+	int problemStartPosition,
+	int problemEndPosition){
+
+	this.handle(
+			problemId,
+			problemArguments,
+			0, // no elaboration
+			messageArguments,
+			severity,
+			problemStartPosition,
+			problemEndPosition);
+}
+
+public void hiddenCatchBlock(ReferenceBinding exceptionType, ASTNode location) {
+	this.handle(
+		IProblem.MaskedCatch,
+		new String[] {
+			new String(exceptionType.readableName()),
+		 },
+		new String[] {
+			new String(exceptionType.shortReadableName()),
+		 },
+		location.sourceStart,
+		location.sourceEnd);
+}
+
+public void hierarchyCircularity(SourceTypeBinding sourceType, ReferenceBinding superType, TypeReference reference) {
+	int start = 0;
+	int end = 0;
+
+	if (reference == null) {	// can only happen when java.lang.Object is busted
+		start = sourceType.sourceStart();
+		end = sourceType.sourceEnd();
+	} else {
+		start = reference.sourceStart;
+		end = reference.sourceEnd;
+	}
+
+	if (sourceType == superType)
+		this.handle(
+			IProblem.HierarchyCircularitySelfReference,
+			new String[] {new String(sourceType.readableName()) },
+			new String[] {new String(sourceType.shortReadableName()) },
+			start,
+			end);
+	else
+		this.handle(
+			IProblem.HierarchyCircularity,
+			new String[] {new String(sourceType.readableName()), new String(superType.readableName())},
+			new String[] {new String(sourceType.shortReadableName()), new String(superType.shortReadableName())},
+			start,
+			end);
+}
+
+public void hierarchyCircularity(TypeVariableBinding type, ReferenceBinding superType, TypeReference reference) {
+	int start = 0;
+	int end = 0;
+
+	start = reference.sourceStart;
+	end = reference.sourceEnd;
+
+	if (type == superType)
+		this.handle(
+			IProblem.HierarchyCircularitySelfReference,
+			new String[] {new String(type.readableName()) },
+			new String[] {new String(type.shortReadableName()) },
+			start,
+			end);
+	else
+		this.handle(
+			IProblem.HierarchyCircularity,
+			new String[] {new String(type.readableName()), new String(superType.readableName())},
+			new String[] {new String(type.shortReadableName()), new String(superType.shortReadableName())},
+			start,
+			end);
+}
+
+public void hierarchyHasProblems(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.HierarchyHasProblems,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalAbstractModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)};
+	this.handle(
+		IProblem.IllegalAbstractModifierCombinationForMethod,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalAbstractModifierCombinationForMethod(AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(methodDecl.selector)};
+	this.handle(
+		IProblem.IllegalStrictfpForAbstractInterfaceMethod,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalAccessFromTypeVariable(TypeVariableBinding variable, ASTNode location) {
+	if ((location.bits & ASTNode.InsideJavadoc)!= 0) {
+		javadocInvalidReference(location.sourceStart, location.sourceEnd);
+	} else {
+		String[] arguments = new String[] { new String(variable.sourceName) };
+		this.handle(
+				IProblem.IllegalAccessFromTypeVariable,
+				arguments,
+				arguments,
+				location.sourceStart,
+				location.sourceEnd);
+	}
+}
+public void illegalClassLiteralForTypeVariable(TypeVariableBinding variable, ASTNode location) {
+	String[] arguments = new String[] { new String(variable.sourceName) };
+	this.handle(
+		IProblem.IllegalClassLiteralForTypeVariable,
+		arguments,
+		arguments,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void illegalExtendedDimensions(AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
+	this.handle(
+		IProblem.IllegalExtendedDimensions,
+		NoArgument,
+		NoArgument,
+		annotationTypeMemberDeclaration.sourceStart,
+		annotationTypeMemberDeclaration.sourceEnd);
+}
+public void illegalExtendedDimensions(Argument argument) {
+	this.handle(
+		IProblem.IllegalExtendedDimensionsForVarArgs,
+		NoArgument,
+		NoArgument,
+		argument.sourceStart,
+		argument.sourceEnd);
+}
+public void illegalGenericArray(TypeBinding leafComponentType, ASTNode location) {
+	this.handle(
+		IProblem.IllegalGenericArray,
+		new String[]{ new String(leafComponentType.readableName())},
+		new String[]{ new String(leafComponentType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void illegalInstanceOfGenericType(TypeBinding checkedType, ASTNode location) {
+	TypeBinding erasedType = checkedType.leafComponentType().erasure();
+	StringBuffer recommendedFormBuffer = new StringBuffer(10);
+	if (erasedType instanceof ReferenceBinding) {
+		ReferenceBinding referenceBinding = (ReferenceBinding) erasedType;
+		recommendedFormBuffer.append(referenceBinding.qualifiedSourceName());
+	} else {
+		recommendedFormBuffer.append(erasedType.sourceName());
+	}
+	int count = erasedType.typeVariables().length;
+	if (count > 0) {
+		recommendedFormBuffer.append('<');
+		for (int i = 0; i < count; i++) {
+			if (i > 0) {
+				recommendedFormBuffer.append(',');
+			}
+			recommendedFormBuffer.append('?');
+		}
+		recommendedFormBuffer.append('>');
+	}
+	for (int i = 0, dim = checkedType.dimensions(); i < dim; i++) {
+		recommendedFormBuffer.append("[]"); //$NON-NLS-1$
+	}
+	String recommendedForm = recommendedFormBuffer.toString();
+	if (checkedType.leafComponentType().isTypeVariable()) {
+		this.handle(
+			IProblem.IllegalInstanceofTypeParameter,
+			new String[] { new String(checkedType.readableName()), recommendedForm, },
+			new String[] { new String(checkedType.shortReadableName()), recommendedForm, },
+				location.sourceStart,
+				location.sourceEnd);
+		return;
+	}
+	this.handle(
+		IProblem.IllegalInstanceofParameterizedType,
+		new String[] { new String(checkedType.readableName()), recommendedForm, },
+		new String[] { new String(checkedType.shortReadableName()), recommendedForm, },
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void illegalLocalTypeDeclaration(TypeDeclaration typeDeclaration) {
+	if (isRecoveredName(typeDeclaration.name)) return;
+
+	int problemID = 0;
+	if ((typeDeclaration.modifiers & ClassFileConstants.AccEnum) != 0) {
+		problemID = IProblem.CannotDefineEnumInLocalType;
+	} else if ((typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0) {
+		problemID = IProblem.CannotDefineAnnotationInLocalType;
+	} else if ((typeDeclaration.modifiers & ClassFileConstants.AccInterface) != 0) {
+		problemID = IProblem.CannotDefineInterfaceInLocalType;
+	}
+	if (problemID != 0) {
+		String[] arguments = new String[] {new String(typeDeclaration.name)};
+		this.handle(
+			problemID,
+			arguments,
+			arguments,
+			typeDeclaration.sourceStart,
+			typeDeclaration.sourceEnd);
+	}
+}
+public void illegalModifierCombinationFinalAbstractForClass(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierCombinationFinalAbstractForClass,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierCombinationFinalVolatileForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+
+	this.handle(
+		IProblem.IllegalModifierCombinationFinalVolatileForField,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void illegalModifierCombinationForInterfaceMethod(AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(methodDecl.selector)};
+	this.handle(
+		IProblem.IllegalModifierCombinationForInterfaceMethod,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void illegalModifierForAnnotationField(FieldDeclaration fieldDecl) {
+	String name = new String(fieldDecl.name);
+	this.handle(
+		IProblem.IllegalModifierForAnnotationField,
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.readableName()),
+			name,
+		},
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.shortReadableName()),
+			name,
+		},
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void illegalModifierForAnnotationMember(AbstractMethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.IllegalModifierForAnnotationMethod,
+		new String[] {
+			new String(methodDecl.binding.declaringClass.readableName()),
+			new String(methodDecl.selector),
+		},
+		new String[] {
+			new String(methodDecl.binding.declaringClass.shortReadableName()),
+			new String(methodDecl.selector),
+		},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalModifierForAnnotationMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForAnnotationMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForAnnotationType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForAnnotationType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForClass(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForClass,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForEnum(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForEnum,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForEnumConstant(ReferenceBinding type, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+	this.handle(
+		IProblem.IllegalModifierForEnumConstant,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+
+public void illegalModifierForEnumConstructor(AbstractMethodDeclaration constructor) {
+	this.handle(
+		IProblem.IllegalModifierForEnumConstructor,
+		NoArgument,
+		NoArgument,
+		constructor.sourceStart,
+		constructor.sourceEnd);
+}
+public void illegalModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+	this.handle(
+		IProblem.IllegalModifierForField,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void illegalModifierForInterface(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForInterface,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+
+public void illegalModifierForInterfaceField(FieldDeclaration fieldDecl) {
+	String name = new String(fieldDecl.name);
+	this.handle(
+		IProblem.IllegalModifierForInterfaceField,
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.readableName()),
+			name,
+		},
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.shortReadableName()),
+			name,
+		},
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void illegalModifierForInterfaceMethod(AbstractMethodDeclaration methodDecl, boolean isJDK18orGreater) {
+	// cannot include parameter types since they are not resolved yet
+	// and the error message would be too long
+	this.handle(
+		isJDK18orGreater 
+			? IProblem.IllegalModifierForInterfaceMethod18 
+			: IProblem.IllegalModifierForInterfaceMethod,
+		new String[] {
+			new String(methodDecl.selector)
+		},
+		new String[] {
+			new String(methodDecl.selector)
+		},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalModifierForLocalClass(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForLocalClass,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForMemberClass(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForMemberClass,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForMemberEnum(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForMemberEnum,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForMemberInterface(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForMemberInterface,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForMethod(AbstractMethodDeclaration methodDecl) {
+	// cannot include parameter types since they are not resolved yet
+	// and the error message would be too long
+	this.handle(
+		methodDecl.isConstructor() ? IProblem.IllegalModifierForConstructor : IProblem.IllegalModifierForMethod,
+		new String[] {
+			new String(methodDecl.selector)
+		},
+		new String[] {
+			new String(methodDecl.selector)
+		},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalModifierForVariable(LocalDeclaration localDecl, boolean complainAsArgument) {
+	String[] arguments = new String[] {new String(localDecl.name)};
+	this.handle(
+		complainAsArgument
+			? IProblem.IllegalModifierForArgument
+			: IProblem.IllegalModifierForVariable,
+		arguments,
+		arguments,
+		localDecl.sourceStart,
+		localDecl.sourceEnd);
+}
+public void illegalPrimitiveOrArrayTypeForEnclosingInstance(TypeBinding enclosingType, ASTNode location) {
+	this.handle(
+		IProblem.IllegalPrimitiveOrArrayTypeForEnclosingInstance,
+		new String[] {new String(enclosingType.readableName())},
+		new String[] {new String(enclosingType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void illegalQualifiedParameterizedTypeAllocation(TypeReference qualifiedTypeReference, TypeBinding allocatedType) {
+	this.handle(
+		IProblem.IllegalQualifiedParameterizedTypeAllocation,
+		new String[] { new String(allocatedType.readableName()), new String(allocatedType.enclosingType().readableName()), },
+		new String[] { new String(allocatedType.shortReadableName()), new String(allocatedType.enclosingType().shortReadableName()), },
+		qualifiedTypeReference.sourceStart,
+		qualifiedTypeReference.sourceEnd);
+}
+public void illegalStaticModifierForMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalStaticModifierForMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalUsageOfQualifiedTypeReference(QualifiedTypeReference qualifiedTypeReference) {
+	StringBuffer buffer = new StringBuffer();
+	char[][] tokens = qualifiedTypeReference.tokens;
+	for (int i = 0; i < tokens.length; i++) {
+		if (i > 0) buffer.append('.');
+		buffer.append(tokens[i]);
+	}
+	String[] arguments = new String[] { String.valueOf(buffer)};
+	this.handle(
+		IProblem.IllegalUsageOfQualifiedTypeReference,
+		arguments,
+		arguments,
+		qualifiedTypeReference.sourceStart,
+		qualifiedTypeReference.sourceEnd);
+}
+public void illegalUsageOfWildcard(TypeReference wildcard) {
+	this.handle(
+		IProblem.InvalidUsageOfWildcard,
+		NoArgument,
+		NoArgument,
+		wildcard.sourceStart,
+		wildcard.sourceEnd);
+}
+public void illegalVararg(Argument argType, AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {CharOperation.toString(argType.type.getTypeName()), new String(methodDecl.selector)};
+	this.handle(
+		IProblem.IllegalVararg,
+		arguments,
+		arguments,
+		argType.sourceStart,
+		argType.sourceEnd);
+}
+public void illegalVarargInLambda(Argument argType) {
+	String[] arguments = new String[] { CharOperation.toString(argType.type.getTypeName())};
+	this.handle(
+		IProblem.IllegalVarargInLambda,
+		arguments,
+		arguments,
+		argType.sourceStart,
+		argType.sourceEnd);
+}
+public void illegalThisDeclaration(Argument argument) {
+	String[] arguments = NoArgument;
+	this.handle(
+		IProblem.IllegalDeclarationOfThisParameter,
+		arguments,
+		arguments,
+		argument.sourceStart,
+		argument.sourceEnd);
+}
+public void illegalSourceLevelForThis(Argument argument) {
+	String[] arguments = NoArgument;
+	this.handle(
+		IProblem.ExplicitThisParameterNotBelow18,
+		arguments,
+		arguments,
+		argument.sourceStart,
+		argument.sourceEnd);
+}
+public void disallowedThisParameter(Receiver receiver) {
+	String[] arguments = NoArgument;
+	this.handle(
+		IProblem.DisallowedExplicitThisParameter,
+		arguments,
+		arguments,
+		receiver.sourceStart,
+		receiver.sourceEnd);
+}
+public void illegalQualifierForExplicitThis(Receiver receiver, TypeBinding expectedType) {
+	String[] problemArguments = new String[] { new String(expectedType.sourceName())};
+	this.handle(
+		IProblem.IllegalQualifierForExplicitThis,
+		problemArguments,
+		problemArguments,
+		(receiver.qualifyingName == null) ? receiver.sourceStart : receiver.qualifyingName.sourceStart,
+		receiver.sourceEnd);
+}
+public void illegalQualifierForExplicitThis2(Receiver receiver) {
+	this.handle(
+		IProblem.IllegalQualifierForExplicitThis2,
+		NoArgument,
+		NoArgument,
+		receiver.qualifyingName.sourceStart,
+		receiver.sourceEnd);
+}
+public void illegalTypeForExplicitThis(Receiver receiver, TypeBinding expectedType) {
+	this.handle(
+		IProblem.IllegalTypeForExplicitThis,
+		new String[] { new String(expectedType.readableName())},
+		new String[] { new String(expectedType.shortReadableName())},
+		receiver.type.sourceStart,
+		receiver.type.sourceEnd);
+}
+public void illegalThis(Argument argument) {
+	String[] arguments = NoArgument;
+	this.handle(
+		IProblem.ExplicitThisParameterNotInLambda,
+		arguments,
+		arguments,
+		argument.sourceStart,
+		argument.sourceEnd);
+}
+public void defaultMethodsNotBelow18(MethodDeclaration md) {
+	this.handle(
+			IProblem.DefaultMethodNotBelow18,
+			NoArgument,
+			NoArgument,
+			md.bodyStart,
+			md.bodyEnd);
+}
+public void staticInterfaceMethodsNotBelow18(MethodDeclaration md) {
+	this.handle(
+			IProblem.StaticInterfaceMethodNotBelow18,
+			NoArgument,
+			NoArgument,
+			md.bodyStart,
+			md.bodyEnd);
+}
+public void referenceExpressionsNotBelow18(ReferenceExpression rexp) {
+	this.handle(
+			rexp.isMethodReference() ? IProblem.MethodReferenceNotBelow18 : IProblem.ConstructorReferenceNotBelow18,
+			NoArgument,
+			NoArgument,
+			rexp.sourceStart,
+			rexp.sourceEnd);
+}
+public void lambdaExpressionsNotBelow18(LambdaExpression lexp) {
+	this.handle(
+			IProblem.LambdaExpressionNotBelow18,
+			NoArgument,
+			NoArgument,
+			lexp.sourceStart,
+			lexp.sourceEnd);
+}
+public void illegalVisibilityModifierCombinationForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+	this.handle(
+		IProblem.IllegalVisibilityModifierCombinationForField,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void illegalVisibilityModifierCombinationForMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalVisibilityModifierCombinationForMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalVisibilityModifierCombinationForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)};
+	this.handle(
+		IProblem.IllegalVisibilityModifierCombinationForMethod,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalVisibilityModifierForInterfaceMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalVisibilityModifierForInterfaceMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalVoidExpression(ASTNode location) {
+	this.handle(
+		IProblem.InvalidVoidExpression,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void importProblem(ImportReference importRef, Binding expectedImport) {
+	if (expectedImport instanceof FieldBinding) {
+		int id = IProblem.UndefinedField;
+		FieldBinding field = (FieldBinding) expectedImport;
+		String[] readableArguments = null;
+		String[] shortArguments = null;
+		switch (expectedImport.problemId()) {
+			case ProblemReasons.NotVisible :
+				id = IProblem.NotVisibleField;
+				readableArguments = new String[] {CharOperation.toString(importRef.tokens), new String(field.declaringClass.readableName())};
+				shortArguments = new String[] {CharOperation.toString(importRef.tokens), new String(field.declaringClass.shortReadableName())};
+				break;
+			case ProblemReasons.Ambiguous :
+				id = IProblem.AmbiguousField;
+				readableArguments = new String[] {new String(field.readableName())};
+				shortArguments = new String[] {new String(field.readableName())};
+				break;
+			case ProblemReasons.ReceiverTypeNotVisible :
+				id = IProblem.NotVisibleType;
+				readableArguments = new String[] {new String(field.declaringClass.leafComponentType().readableName())};
+				shortArguments = new String[] {new String(field.declaringClass.leafComponentType().shortReadableName())};
+				break;
+		}
+		this.handle(
+			id,
+			readableArguments,
+			shortArguments,
+			nodeSourceStart(field, importRef),
+			nodeSourceEnd(field, importRef));
+		return;
+	}
+
+	if (expectedImport.problemId() == ProblemReasons.NotFound) {
+		char[][] tokens = expectedImport instanceof ProblemReferenceBinding
+			? ((ProblemReferenceBinding) expectedImport).compoundName
+			: importRef.tokens;
+		String[] arguments = new String[]{CharOperation.toString(tokens)};
+		this.handle(
+		        IProblem.ImportNotFound,
+		        arguments,
+		        arguments,
+		        importRef.sourceStart,
+		        (int) importRef.sourcePositions[tokens.length - 1]);
+		return;
+	}
+	if (expectedImport.problemId() == ProblemReasons.InvalidTypeForStaticImport) {
+		char[][] tokens = importRef.tokens;
+		String[] arguments = new String[]{CharOperation.toString(tokens)};
+		this.handle(
+		        IProblem.InvalidTypeForStaticImport,
+		        arguments,
+		        arguments,
+		        importRef.sourceStart,
+		        (int) importRef.sourcePositions[tokens.length - 1]);
+		return;
+	}
+	invalidType(importRef, (TypeBinding)expectedImport);
+}
+public void incompatibleExceptionInThrowsClause(SourceTypeBinding type, MethodBinding currentMethod, MethodBinding inheritedMethod, ReferenceBinding exceptionType) {
+	if (type == currentMethod.declaringClass) {
+		int id;
+		if (currentMethod.declaringClass.isInterface()
+				&& !inheritedMethod.isPublic()){ // interface inheriting Object protected method
+			id = IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod;
+		} else {
+			id = IProblem.IncompatibleExceptionInThrowsClause;
+		}
+		this.handle(
+			// Exception %1 is not compatible with throws clause in %2
+			// 9.4.4 - The type of exception in the throws clause is incompatible.
+			id,
+			new String[] {
+				new String(exceptionType.sourceName()),
+				new String(
+					CharOperation.concat(
+						inheritedMethod.declaringClass.readableName(),
+						inheritedMethod.readableName(),
+						'.'))},
+			new String[] {
+				new String(exceptionType.sourceName()),
+				new String(
+					CharOperation.concat(
+						inheritedMethod.declaringClass.shortReadableName(),
+						inheritedMethod.shortReadableName(),
+						'.'))},
+			currentMethod.sourceStart(),
+			currentMethod.sourceEnd());
+	} else
+		this.handle(
+			// Exception %1 in throws clause of %2 is not compatible with %3
+			// 9.4.4 - The type of exception in the throws clause is incompatible.
+			IProblem.IncompatibleExceptionInInheritedMethodThrowsClause,
+			new String[] {
+				new String(exceptionType.sourceName()),
+				new String(
+					CharOperation.concat(
+						currentMethod.declaringClass.sourceName(),
+						currentMethod.readableName(),
+						'.')),
+				new String(
+					CharOperation.concat(
+						inheritedMethod.declaringClass.readableName(),
+						inheritedMethod.readableName(),
+						'.'))},
+			new String[] {
+				new String(exceptionType.sourceName()),
+				new String(
+					CharOperation.concat(
+						currentMethod.declaringClass.sourceName(),
+						currentMethod.shortReadableName(),
+						'.')),
+				new String(
+					CharOperation.concat(
+						inheritedMethod.declaringClass.shortReadableName(),
+						inheritedMethod.shortReadableName(),
+						'.'))},
+			type.sourceStart(),
+			type.sourceEnd());
+}
+public void incompatibleReturnType(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	StringBuffer methodSignature = new StringBuffer();
+	methodSignature
+		.append(inheritedMethod.declaringClass.readableName())
+		.append('.')
+		.append(inheritedMethod.readableName());
+
+	StringBuffer shortSignature = new StringBuffer();
+	shortSignature
+		.append(inheritedMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(inheritedMethod.shortReadableName());
+
+	int id;
+	final ReferenceBinding declaringClass = currentMethod.declaringClass;
+	if (declaringClass.isInterface()
+			&& !inheritedMethod.isPublic()){ // interface inheriting Object protected method
+		id = IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod;
+	} else {
+		id = IProblem.IncompatibleReturnType;
+	}
+	AbstractMethodDeclaration method = currentMethod.sourceMethod();
+	int sourceStart = 0;
+	int sourceEnd = 0;
+	if (method == null) {
+		if (declaringClass instanceof SourceTypeBinding) {
+			SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) declaringClass;
+			sourceStart = sourceTypeBinding.sourceStart();
+			sourceEnd = sourceTypeBinding.sourceEnd();
+		}
+	} else if (method.isConstructor()){
+		sourceStart = method.sourceStart;
+		sourceEnd = method.sourceEnd;
+	} else {
+		TypeReference returnType = ((MethodDeclaration) method).returnType;
+		sourceStart = returnType.sourceStart;
+		if (returnType instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference typeReference = (ParameterizedSingleTypeReference) returnType;
+			TypeReference[] typeArguments = typeReference.typeArguments;
+			if (typeArguments[typeArguments.length - 1].sourceEnd > typeReference.sourceEnd) {
+				sourceEnd = retrieveClosingAngleBracketPosition(typeReference.sourceEnd);
+			} else {
+				sourceEnd = returnType.sourceEnd;
+			}
+		} else if (returnType instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference typeReference = (ParameterizedQualifiedTypeReference) returnType;
+			sourceEnd = retrieveClosingAngleBracketPosition(typeReference.sourceEnd);
+		} else {
+			sourceEnd = returnType.sourceEnd;
+		}
+	}
+	this.handle(
+		id,
+		new String[] {methodSignature.toString()},
+		new String[] {shortSignature.toString()},
+		sourceStart,
+		sourceEnd);
+}
+public void incorrectArityForParameterizedType(ASTNode location, TypeBinding type, TypeBinding[] argumentTypes) {
+	incorrectArityForParameterizedType(location, type, argumentTypes, Integer.MAX_VALUE);
+}
+public void incorrectArityForParameterizedType(ASTNode location, TypeBinding type, TypeBinding[] argumentTypes, int index) {
+    if (location == null) {
+		this.handle(
+			IProblem.IncorrectArityForParameterizedType,
+			new String[] {new String(type.readableName()), typesAsString(argumentTypes, false)},
+			new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true)},
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+		return; // not reached since aborted above
+    }
+	this.handle(
+		IProblem.IncorrectArityForParameterizedType,
+		new String[] {new String(type.readableName()), typesAsString(argumentTypes, false)},
+		new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true)},
+		location.sourceStart,
+		nodeSourceEnd(null, location, index));
+}
+public void diamondNotBelow17(ASTNode location) {
+	diamondNotBelow17(location, Integer.MAX_VALUE);
+}
+public void diamondNotBelow17(ASTNode location, int index) {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348493
+    if (location == null) {
+		this.handle(
+			IProblem.DiamondNotBelow17,
+			NoArgument,
+			NoArgument,
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+		return; // not reached since aborted above
+    }
+	this.handle(
+		IProblem.DiamondNotBelow17,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		nodeSourceEnd(null, location, index));
+}
+public void incorrectLocationForNonEmptyDimension(ArrayAllocationExpression expression, int index) {
+	this.handle(
+		IProblem.IllegalDimension,
+		NoArgument,
+		NoArgument,
+		expression.dimensions[index].sourceStart,
+		expression.dimensions[index].sourceEnd);
+}
+public void incorrectSwitchType(Expression expression, TypeBinding testType) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+		if (testType.id == TypeIds.T_JavaLangString) {
+			this.handle(
+					IProblem.SwitchOnStringsNotBelow17,
+					new String[] {new String(testType.readableName())},
+					new String[] {new String(testType.shortReadableName())},
+					expression.sourceStart,
+					expression.sourceEnd);
+		} else {
+			if (this.options.sourceLevel < ClassFileConstants.JDK1_5 && testType.isEnum()) {
+				this.handle(
+						IProblem.SwitchOnEnumNotBelow15,
+						new String[] {new String(testType.readableName())},
+						new String[] {new String(testType.shortReadableName())},
+						expression.sourceStart,
+						expression.sourceEnd);
+			} else {
+				this.handle(
+						IProblem.IncorrectSwitchType,
+						new String[] {new String(testType.readableName())},
+						new String[] {new String(testType.shortReadableName())},
+						expression.sourceStart,
+						expression.sourceEnd);
+			}
+		}
+	} else {
+		this.handle(
+				IProblem.IncorrectSwitchType17,
+				new String[] {new String(testType.readableName())},
+				new String[] {new String(testType.shortReadableName())},
+				expression.sourceStart,
+				expression.sourceEnd);
+	}
+}
+public void indirectAccessToStaticField(ASTNode location, FieldBinding field){
+	int severity = computeSeverity(IProblem.IndirectAccessToStaticField);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.IndirectAccessToStaticField,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		severity,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void indirectAccessToStaticMethod(ASTNode location, MethodBinding method) {
+	int severity = computeSeverity(IProblem.IndirectAccessToStaticMethod);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.IndirectAccessToStaticMethod,
+		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+		new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+		severity,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void inheritedDefaultMethodConflictsWithOtherInherited(SourceTypeBinding type, MethodBinding defaultMethod, MethodBinding otherMethod) {
+	TypeDeclaration typeDecl = type.scope.referenceContext;
+	String[] problemArguments = new String[] { 
+			String.valueOf(defaultMethod.readableName()), 
+			String.valueOf(defaultMethod.declaringClass.readableName()), 
+			String.valueOf(otherMethod.declaringClass.readableName()) };
+	String[] messageArguments = new String[] { 
+			String.valueOf(defaultMethod.shortReadableName()), 
+			String.valueOf(defaultMethod.declaringClass.shortReadableName()), 
+			String.valueOf(otherMethod.declaringClass.shortReadableName()) };	
+	this.handle(IProblem.InheritedDefaultMethodConflictsWithOtherInherited,
+			problemArguments,
+			messageArguments,
+			typeDecl.sourceStart,
+			typeDecl.sourceEnd);
+}
+private void inheritedMethodReducesVisibility(int sourceStart, int sourceEnd, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	StringBuffer concreteSignature = new StringBuffer();
+	concreteSignature
+		.append(concreteMethod.declaringClass.readableName())
+		.append('.')
+		.append(concreteMethod.readableName());
+	StringBuffer shortSignature = new StringBuffer();
+	shortSignature
+		.append(concreteMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(concreteMethod.shortReadableName());
+	this.handle(
+		// The inherited method %1 cannot hide the public abstract method in %2
+		IProblem.InheritedMethodReducesVisibility,
+		new String[] {
+			concreteSignature.toString(),
+			new String(abstractMethods[0].declaringClass.readableName())},
+		new String[] {
+			shortSignature.toString(),
+			new String(abstractMethods[0].declaringClass.shortReadableName())},
+		sourceStart,
+		sourceEnd);
+}
+public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	inheritedMethodReducesVisibility(type.sourceStart(), type.sourceEnd(), concreteMethod, abstractMethods);
+}
+public void inheritedMethodReducesVisibility(TypeParameter typeParameter, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	inheritedMethodReducesVisibility(typeParameter.sourceStart(), typeParameter.sourceEnd(), concreteMethod, abstractMethods);
+}
+public void inheritedMethodsHaveIncompatibleReturnTypes(ASTNode location, MethodBinding[] inheritedMethods, int length) {
+	StringBuffer methodSignatures = new StringBuffer();
+	StringBuffer shortSignatures = new StringBuffer();
+	for (int i = length; --i >= 0;) {
+		methodSignatures
+			.append(inheritedMethods[i].declaringClass.readableName())
+			.append('.')
+			.append(inheritedMethods[i].readableName());
+		shortSignatures
+			.append(inheritedMethods[i].declaringClass.shortReadableName())
+			.append('.')
+			.append(inheritedMethods[i].shortReadableName());
+		if (i != 0){
+			methodSignatures.append(", "); //$NON-NLS-1$
+			shortSignatures.append(", "); //$NON-NLS-1$
+		}
+	}
+
+	this.handle(
+		// Return type is incompatible with %1
+		// 9.4.2 - The return type from the method is incompatible with the declaration.
+		IProblem.InheritedIncompatibleReturnType,
+		new String[] {methodSignatures.toString()},
+		new String[] {shortSignatures.toString()},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void inheritedMethodsHaveIncompatibleReturnTypes(SourceTypeBinding type, MethodBinding[] inheritedMethods, int length, boolean[] isOverridden) {
+	StringBuffer methodSignatures = new StringBuffer();
+	StringBuffer shortSignatures = new StringBuffer();
+	for (int i = length; --i >= 0;) {
+		if (isOverridden[i]) continue;
+		methodSignatures
+			.append(inheritedMethods[i].declaringClass.readableName())
+			.append('.')
+			.append(inheritedMethods[i].readableName());
+		shortSignatures
+			.append(inheritedMethods[i].declaringClass.shortReadableName())
+			.append('.')
+			.append(inheritedMethods[i].shortReadableName());
+		if (i != 0){
+			methodSignatures.append(", "); //$NON-NLS-1$
+			shortSignatures.append(", "); //$NON-NLS-1$
+		}
+	}
+
+	this.handle(
+		// Return type is incompatible with %1
+		// 9.4.2 - The return type from the method is incompatible with the declaration.
+		IProblem.InheritedIncompatibleReturnType,
+		new String[] {methodSignatures.toString()},
+		new String[] {shortSignatures.toString()},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void inheritedMethodsHaveNameClash(SourceTypeBinding type, MethodBinding oneMethod, MethodBinding twoMethod) {
+	this.handle(
+		IProblem.MethodNameClash,
+		new String[] {
+			new String(oneMethod.selector),
+			typesAsString(oneMethod.original(), false),
+			new String(oneMethod.declaringClass.readableName()),
+			typesAsString(twoMethod.original(), false),
+			new String(twoMethod.declaringClass.readableName()),
+		 },
+		new String[] {
+			new String(oneMethod.selector),
+			typesAsString(oneMethod.original(), true),
+			new String(oneMethod.declaringClass.shortReadableName()),
+			typesAsString(twoMethod.original(), true),
+			new String(twoMethod.declaringClass.shortReadableName()),
+		 },
+		 type.sourceStart(),
+		 type.sourceEnd());
+}
+public void initializerMustCompleteNormally(FieldDeclaration fieldDecl) {
+	this.handle(
+		IProblem.InitializerMustCompleteNormally,
+		NoArgument,
+		NoArgument,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void innerTypesCannotDeclareStaticInitializers(ReferenceBinding innerType, Initializer initializer) {
+	this.handle(
+		IProblem.CannotDefineStaticInitializerInLocalType,
+		new String[] {new String(innerType.readableName())},
+		new String[] {new String(innerType.shortReadableName())},
+		initializer.sourceStart,
+		initializer.sourceStart);
+}
+public void interfaceCannotHaveConstructors(ConstructorDeclaration constructor) {
+	this.handle(
+		IProblem.InterfaceCannotHaveConstructors,
+		NoArgument,
+		NoArgument,
+		constructor.sourceStart,
+		constructor.sourceEnd,
+		constructor,
+		constructor.compilationResult());
+}
+public void interfaceCannotHaveInitializers(char [] sourceName, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(sourceName)};
+
+	this.handle(
+		IProblem.InterfaceCannotHaveInitializers,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void invalidAnnotationMemberType(MethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.InvalidAnnotationMemberType,
+		new String[] {
+			new String(methodDecl.binding.returnType.readableName()),
+			new String(methodDecl.selector),
+			new String(methodDecl.binding.declaringClass.readableName()),
+		},
+		new String[] {
+			new String(methodDecl.binding.returnType.shortReadableName()),
+			new String(methodDecl.selector),
+			new String(methodDecl.binding.declaringClass.shortReadableName()),
+		},
+		methodDecl.returnType.sourceStart,
+		methodDecl.returnType.sourceEnd);
+
+}
+public void invalidBreak(ASTNode location) {
+	this.handle(
+		IProblem.InvalidBreak,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void invalidConstructor(Statement statement, MethodBinding targetConstructor) {
+	boolean insideDefaultConstructor =
+		(this.referenceContext instanceof ConstructorDeclaration)
+			&& ((ConstructorDeclaration)this.referenceContext).isDefaultConstructor();
+	boolean insideImplicitConstructorCall =
+		(statement instanceof ExplicitConstructorCall)
+			&& (((ExplicitConstructorCall) statement).accessMode == ExplicitConstructorCall.ImplicitSuper);
+
+	int sourceStart = statement.sourceStart;
+	int sourceEnd = statement.sourceEnd;
+	if (statement instanceof AllocationExpression) {
+		AllocationExpression allocation = (AllocationExpression)statement;
+		if (allocation.enumConstant != null) {
+			sourceStart = allocation.enumConstant.sourceStart;
+			sourceEnd = allocation.enumConstant.sourceEnd;
+		}
+	}
+
+	int id = IProblem.UndefinedConstructor; //default...
+    MethodBinding shownConstructor = targetConstructor;
+	switch (targetConstructor.problemId()) {
+		case ProblemReasons.NotFound :
+			ProblemMethodBinding problemConstructor = (ProblemMethodBinding) targetConstructor;
+			if (problemConstructor.closestMatch != null) {
+		    	if ((problemConstructor.closestMatch.tagBits & TagBits.HasMissingType) != 0) {
+					missingTypeInConstructor(statement, problemConstructor.closestMatch);
+					return;
+		    	}
+		    }
+
+			if (insideDefaultConstructor){
+				id = IProblem.UndefinedConstructorInDefaultConstructor;
+			} else if (insideImplicitConstructorCall){
+				id = IProblem.UndefinedConstructorInImplicitConstructorCall;
+			} else {
+				id = IProblem.UndefinedConstructor;
+			}
+			break;
+		case ProblemReasons.NotVisible :
+			if (insideDefaultConstructor){
+				id = IProblem.NotVisibleConstructorInDefaultConstructor;
+			} else if (insideImplicitConstructorCall){
+				id = IProblem.NotVisibleConstructorInImplicitConstructorCall;
+			} else {
+				id = IProblem.NotVisibleConstructor;
+			}
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			if (problemConstructor.closestMatch != null) {
+			    shownConstructor = problemConstructor.closestMatch.original();
+		    }
+			break;
+		case ProblemReasons.Ambiguous :
+			if (insideDefaultConstructor){
+				id = IProblem.AmbiguousConstructorInDefaultConstructor;
+			} else if (insideImplicitConstructorCall){
+				id = IProblem.AmbiguousConstructorInImplicitConstructorCall;
+			} else {
+				id = IProblem.AmbiguousConstructor;
+			}
+			break;
+		case ProblemReasons.ParameterBoundMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
+			shownConstructor = substitutedConstructor.original();
+			int augmentedLength = problemConstructor.parameters.length;
+			TypeBinding inferredTypeArgument = problemConstructor.parameters[augmentedLength-2];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) problemConstructor.parameters[augmentedLength-1];
+			TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+			System.arraycopy(problemConstructor.parameters, 0, invocationArguments, 0, augmentedLength-2);
+			this.handle(
+				IProblem.GenericConstructorTypeArgumentMismatch,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+				        typesAsString(invocationArguments, false),
+				        new String(inferredTypeArgument.readableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+				        typesAsString(invocationArguments, true),
+				        new String(inferredTypeArgument.shortReadableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, true) },
+				sourceStart,
+				sourceEnd);
+			return;
+
+		case ProblemReasons.TypeParameterArityMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			if (shownConstructor.typeVariables == Binding.NO_TYPE_VARIABLES) {
+				this.handle(
+					IProblem.NonGenericConstructor,
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, false),
+					        new String(shownConstructor.declaringClass.readableName()),
+					        typesAsString(targetConstructor, false) },
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, true),
+					        new String(shownConstructor.declaringClass.shortReadableName()),
+					        typesAsString(targetConstructor, true) },
+					sourceStart,
+					sourceEnd);
+			} else {
+				this.handle(
+					IProblem.IncorrectArityForParameterizedConstructor  ,
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, false),
+					        new String(shownConstructor.declaringClass.readableName()),
+							typesAsString(shownConstructor.typeVariables, false),
+					        typesAsString(targetConstructor, false) },
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, true),
+					        new String(shownConstructor.declaringClass.shortReadableName()),
+							typesAsString(shownConstructor.typeVariables, true),
+					        typesAsString(targetConstructor, true) },
+					sourceStart,
+					sourceEnd);
+			}
+			return;
+		case ProblemReasons.ParameterizedMethodTypeMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.ParameterizedConstructorArgumentTypeMismatch,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, false),
+				        typesAsString(targetConstructor, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, true),
+				        typesAsString(targetConstructor, true) },
+				sourceStart,
+				sourceEnd);
+			return;
+		case ProblemReasons.TypeArgumentsForRawGenericMethod :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.TypeArgumentsForRawGenericConstructor,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+				        typesAsString(targetConstructor, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+				        typesAsString(targetConstructor, true) },
+				sourceStart,
+				sourceEnd);
+			return;
+		case ProblemReasons.VarargsElementTypeNotVisible :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			TypeBinding varargsElementType = shownConstructor.parameters[shownConstructor.parameters.length - 1].leafComponentType();
+			this.handle(
+				IProblem.VarargsElementTypeNotVisibleForConstructor,
+				new String[] {
+						new String(shownConstructor.declaringClass.sourceName()),
+						typesAsString(shownConstructor, false),
+						new String(shownConstructor.declaringClass.readableName()),
+						new String(varargsElementType.readableName())
+				},
+				new String[] {
+						new String(shownConstructor.declaringClass.sourceName()),
+						typesAsString(shownConstructor, true),
+						new String(shownConstructor.declaringClass.shortReadableName()),
+						new String(varargsElementType.shortReadableName())
+				},
+				sourceStart,
+				sourceEnd);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(statement); // want to fail to see why we were here...
+			break;
+	}
+
+	this.handle(
+		id,
+		new String[] {new String(targetConstructor.declaringClass.readableName()), typesAsString(shownConstructor, false)},
+		new String[] {new String(targetConstructor.declaringClass.shortReadableName()), typesAsString(shownConstructor, true)},
+		sourceStart,
+		sourceEnd);
+}
+public void invalidContinue(ASTNode location) {
+	this.handle(
+		IProblem.InvalidContinue,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void invalidEnclosingType(Expression expression, TypeBinding type, ReferenceBinding enclosingType) {
+
+	if (enclosingType.isAnonymousType()) enclosingType = enclosingType.superclass();
+	if (enclosingType.sourceName != null && enclosingType.sourceName.length == 0) return;
+
+	int flag = IProblem.UndefinedType; // default
+	switch (type.problemId()) {
+		case ProblemReasons.NotFound : // 1
+			flag = IProblem.UndefinedType;
+			break;
+		case ProblemReasons.NotVisible : // 2
+			flag = IProblem.NotVisibleType;
+			break;
+		case ProblemReasons.Ambiguous : // 3
+			flag = IProblem.AmbiguousType;
+			break;
+		case ProblemReasons.InternalNameProvided :
+			flag = IProblem.InternalTypeNameProvided;
+			break;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(expression); // want to fail to see why we were here...
+			break;
+	}
+
+	this.handle(
+		flag,
+		new String[] {new String(enclosingType.readableName()) + "." + new String(type.readableName())}, //$NON-NLS-1$
+		new String[] {new String(enclosingType.shortReadableName()) + "." + new String(type.shortReadableName())}, //$NON-NLS-1$
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidExplicitConstructorCall(ASTNode location) {
+
+	this.handle(
+		IProblem.InvalidExplicitConstructorCall,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void invalidExpressionAsStatement(Expression expression){
+	this.handle(
+		IProblem.InvalidExpressionAsStatement,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidField(FieldReference fieldRef, TypeBinding searchedType) {
+	if(isRecoveredName(fieldRef.token)) return;
+
+	int id = IProblem.UndefinedField;
+	FieldBinding field = fieldRef.binding;
+	switch (field.problemId()) {
+		case ProblemReasons.NotFound :
+			if ((searchedType.tagBits & TagBits.HasMissingType) != 0) {
+				this.handle(
+						IProblem.UndefinedType,
+						new String[] {new String(searchedType.leafComponentType().readableName())},
+						new String[] {new String(searchedType.leafComponentType().shortReadableName())},
+						fieldRef.receiver.sourceStart,
+						fieldRef.receiver.sourceEnd);
+					return;
+			}
+			id = IProblem.UndefinedField;
+/* also need to check that the searchedType is the receiver type
+			if (searchedType.isHierarchyInconsistent())
+				severity = SecondaryError;
+*/
+			break;
+		case ProblemReasons.NotVisible :
+			this.handle(
+				IProblem.NotVisibleField,
+				new String[] {new String(fieldRef.token), new String(field.declaringClass.readableName())},
+				new String[] {new String(fieldRef.token), new String(field.declaringClass.shortReadableName())},
+				nodeSourceStart(field, fieldRef),
+				nodeSourceEnd(field, fieldRef));
+			return;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.AmbiguousField;
+			break;
+		case ProblemReasons.NonStaticReferenceInStaticContext :
+			id = IProblem.NonStaticFieldFromStaticInvocation;
+			break;
+		case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+			id = IProblem.InstanceFieldDuringConstructorInvocation;
+			break;
+		case ProblemReasons.InheritedNameHidesEnclosingName :
+			id = IProblem.InheritedFieldHidesEnclosingName;
+			break;
+		case ProblemReasons.ReceiverTypeNotVisible :
+			this.handle(
+				IProblem.NotVisibleType, // cannot occur in javadoc comments
+				new String[] {new String(searchedType.leafComponentType().readableName())},
+				new String[] {new String(searchedType.leafComponentType().shortReadableName())},
+				fieldRef.receiver.sourceStart,
+				fieldRef.receiver.sourceEnd);
+			return;
+
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(fieldRef); // want to fail to see why we were here...
+			break;
+	}
+
+	String[] arguments = new String[] {new String(field.readableName())};
+	this.handle(
+		id,
+		arguments,
+		arguments,
+		nodeSourceStart(field, fieldRef),
+		nodeSourceEnd(field, fieldRef));
+}
+public void invalidField(NameReference nameRef, FieldBinding field) {
+	if (nameRef instanceof QualifiedNameReference) {
+		QualifiedNameReference ref = (QualifiedNameReference) nameRef;
+		if (isRecoveredName(ref.tokens)) return;
+	} else {
+		SingleNameReference ref = (SingleNameReference) nameRef;
+		if (isRecoveredName(ref.token)) return;
+	}
+	int id = IProblem.UndefinedField;
+	switch (field.problemId()) {
+		case ProblemReasons.NotFound :
+			TypeBinding declaringClass = field.declaringClass;
+			if (declaringClass != null && (declaringClass.tagBits & TagBits.HasMissingType) != 0) {
+				this.handle(
+						IProblem.UndefinedType,
+						new String[] {new String(field.declaringClass.readableName())},
+						new String[] {new String(field.declaringClass.shortReadableName())},
+						nameRef.sourceStart,
+						nameRef.sourceEnd);
+					return;
+			}
+			String[] arguments = new String[] {new String(field.readableName())};
+			this.handle(
+					id,
+					arguments,
+					arguments,
+					nodeSourceStart(field, nameRef),
+					nodeSourceEnd(field, nameRef));
+			return;
+		case ProblemReasons.NotVisible :
+			char[] name = field.readableName();
+			name = CharOperation.lastSegment(name, '.');
+			this.handle(
+				IProblem.NotVisibleField,
+				new String[] {new String(name), new String(field.declaringClass.readableName())},
+				new String[] {new String(name), new String(field.declaringClass.shortReadableName())},
+				nodeSourceStart(field, nameRef),
+				nodeSourceEnd(field, nameRef));
+			return;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.AmbiguousField;
+			break;
+		case ProblemReasons.NonStaticReferenceInStaticContext :
+			id = IProblem.NonStaticFieldFromStaticInvocation;
+			break;
+		case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+			id = IProblem.InstanceFieldDuringConstructorInvocation;
+			break;
+		case ProblemReasons.InheritedNameHidesEnclosingName :
+			id = IProblem.InheritedFieldHidesEnclosingName;
+			break;
+		case ProblemReasons.ReceiverTypeNotVisible :
+			this.handle(
+				IProblem.NotVisibleType,
+				new String[] {new String(field.declaringClass.readableName())},
+				new String[] {new String(field.declaringClass.shortReadableName())},
+				nameRef.sourceStart,
+				nameRef.sourceEnd);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(nameRef); // want to fail to see why we were here...
+			break;
+	}
+	String[] arguments = new String[] {new String(field.readableName())};
+	this.handle(
+		id,
+		arguments,
+		arguments,
+		nameRef.sourceStart,
+		nameRef.sourceEnd);
+}
+public void invalidField(QualifiedNameReference nameRef, FieldBinding field, int index, TypeBinding searchedType) {
+	//the resolution of the index-th field of qname failed
+	//qname.otherBindings[index] is the binding that has produced the error
+
+	//The different targetted errors should be :
+	//UndefinedField
+	//NotVisibleField
+	//AmbiguousField
+
+	if (isRecoveredName(nameRef.tokens)) return;
+
+	if (searchedType.isBaseType()) {
+		this.handle(
+			IProblem.NoFieldOnBaseType,
+			new String[] {
+				new String(searchedType.readableName()),
+				CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)),
+				new String(nameRef.tokens[index])},
+			new String[] {
+				new String(searchedType.sourceName()),
+				CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index)),
+				new String(nameRef.tokens[index])},
+			nameRef.sourceStart,
+			(int) nameRef.sourcePositions[index]);
+		return;
+	}
+
+	int id = IProblem.UndefinedField;
+	switch (field.problemId()) {
+		case ProblemReasons.NotFound :
+			if ((searchedType.tagBits & TagBits.HasMissingType) != 0) {
+				this.handle(
+						IProblem.UndefinedType,
+						new String[] {new String(searchedType.leafComponentType().readableName())},
+						new String[] {new String(searchedType.leafComponentType().shortReadableName())},
+						nameRef.sourceStart,
+						(int) nameRef.sourcePositions[index-1]);
+					return;
+			}
+			String fieldName = new String(nameRef.tokens[index]);
+			String[] arguments = new String[] {fieldName };
+			this.handle(
+					id,
+					arguments,
+					arguments,
+					nodeSourceStart(field, nameRef),
+					nodeSourceEnd(field, nameRef));
+			return;
+		case ProblemReasons.NotVisible :
+			fieldName = new String(nameRef.tokens[index]);
+			this.handle(
+				IProblem.NotVisibleField,
+				new String[] {fieldName, new String(field.declaringClass.readableName())},
+				new String[] {fieldName, new String(field.declaringClass.shortReadableName())},
+				nodeSourceStart(field, nameRef),
+				nodeSourceEnd(field, nameRef));
+			return;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.AmbiguousField;
+			break;
+		case ProblemReasons.NonStaticReferenceInStaticContext :
+			id = IProblem.NonStaticFieldFromStaticInvocation;
+			break;
+		case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+			id = IProblem.InstanceFieldDuringConstructorInvocation;
+			break;
+		case ProblemReasons.InheritedNameHidesEnclosingName :
+			id = IProblem.InheritedFieldHidesEnclosingName;
+			break;
+		case ProblemReasons.ReceiverTypeNotVisible :
+			this.handle(
+				IProblem.NotVisibleType,
+				new String[] {new String(searchedType.leafComponentType().readableName())},
+				new String[] {new String(searchedType.leafComponentType().shortReadableName())},
+				nameRef.sourceStart,
+				(int) nameRef.sourcePositions[index-1]);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(nameRef); // want to fail to see why we were here...
+			break;
+	}
+	String[] arguments = new String[] {CharOperation.toString(CharOperation.subarray(nameRef.tokens, 0, index + 1))};
+	this.handle(
+		id,
+		arguments,
+		arguments,
+		nameRef.sourceStart,
+		(int) nameRef.sourcePositions[index]);
+}
+
+public void invalidFileNameForPackageAnnotations(Annotation annotation) {
+	this.handle(
+			IProblem.InvalidFileNameForPackageAnnotations,
+			NoArgument,
+			NoArgument,
+			annotation.sourceStart,
+			annotation.sourceEnd);
+}
+
+public void invalidMethod(MessageSend messageSend, MethodBinding method) {
+	if (isRecoveredName(messageSend.selector)) return;
+
+	int id = IProblem.UndefinedMethod; //default...
+    MethodBinding shownMethod = method;
+	switch (method.problemId()) {
+		case ProblemReasons.NotFound :
+			if ((method.declaringClass.tagBits & TagBits.HasMissingType) != 0) {
+				this.handle(
+						IProblem.UndefinedType,
+						new String[] {new String(method.declaringClass.readableName())},
+						new String[] {new String(method.declaringClass.shortReadableName())},
+						messageSend.receiver.sourceStart,
+						messageSend.receiver.sourceEnd);
+					return;
+			}
+			id = IProblem.UndefinedMethod;
+			ProblemMethodBinding problemMethod = (ProblemMethodBinding) method;
+			if (problemMethod.closestMatch != null) {
+			    	shownMethod = problemMethod.closestMatch;
+			    	if ((shownMethod.tagBits & TagBits.HasMissingType) != 0) {
+						missingTypeInMethod(messageSend, shownMethod);
+						return;
+			    	}
+					String closestParameterTypeNames = typesAsString(shownMethod, false);
+					String parameterTypeNames = typesAsString(problemMethod.parameters, false);
+					String closestParameterTypeShortNames = typesAsString(shownMethod, true);
+					String parameterTypeShortNames = typesAsString(problemMethod.parameters, true);
+					if (closestParameterTypeShortNames.equals(parameterTypeShortNames)) {
+						closestParameterTypeShortNames = closestParameterTypeNames;
+						parameterTypeShortNames = parameterTypeNames;
+					}
+					this.handle(
+						IProblem.ParameterMismatch,
+						new String[] {
+							new String(shownMethod.declaringClass.readableName()),
+							new String(shownMethod.selector),
+							closestParameterTypeNames,
+							parameterTypeNames
+						},
+						new String[] {
+							new String(shownMethod.declaringClass.shortReadableName()),
+							new String(shownMethod.selector),
+							closestParameterTypeShortNames,
+							parameterTypeShortNames
+						},
+						(int) (messageSend.nameSourcePosition >>> 32),
+						(int) messageSend.nameSourcePosition);
+					return;
+			}
+			break;
+		case ProblemReasons.NotVisible :
+			id = IProblem.NotVisibleMethod;
+			problemMethod = (ProblemMethodBinding) method;
+			if (problemMethod.closestMatch != null) {
+			    shownMethod = problemMethod.closestMatch.original();
+		    }
+			break;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.AmbiguousMethod;
+			break;
+		case ProblemReasons.InheritedNameHidesEnclosingName :
+			id = IProblem.InheritedMethodHidesEnclosingName;
+			break;
+		case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+			id = IProblem.InstanceMethodDuringConstructorInvocation;
+			break;
+		case ProblemReasons.NonStaticReferenceInStaticContext :
+			id = IProblem.StaticMethodRequested;
+			break;
+		case ProblemReasons.NonStaticOrAlienTypeReceiver:
+			this.handle(
+					IProblem.NonStaticOrAlienTypeReceiver,
+					new String[] {
+							new String(method.declaringClass.readableName()),
+					        new String(method.selector),
+					},
+					new String[] {
+							new String(method.declaringClass.shortReadableName()),
+					        new String(method.selector),
+					},
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.ReceiverTypeNotVisible :
+			this.handle(
+				IProblem.NotVisibleType,	// cannot occur in javadoc comments
+				new String[] {new String(method.declaringClass.readableName())},
+				new String[] {new String(method.declaringClass.shortReadableName())},
+				messageSend.receiver.sourceStart,
+				messageSend.receiver.sourceEnd);
+			return;
+		case ProblemReasons.ParameterBoundMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
+			shownMethod = substitutedMethod.original();
+			int augmentedLength = problemMethod.parameters.length;
+			TypeBinding inferredTypeArgument = problemMethod.parameters[augmentedLength-2];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) problemMethod.parameters[augmentedLength-1];
+			TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+			System.arraycopy(problemMethod.parameters, 0, invocationArguments, 0, augmentedLength-2);
+			this.handle(
+				IProblem.GenericMethodTypeArgumentMismatch,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+				        typesAsString(invocationArguments, false),
+				        new String(inferredTypeArgument.readableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+				        typesAsString(invocationArguments, true),
+				        new String(inferredTypeArgument.shortReadableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.TypeParameterArityMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			if (shownMethod.typeVariables == Binding.NO_TYPE_VARIABLES) {
+				this.handle(
+					IProblem.NonGenericMethod ,
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, false),
+					        new String(shownMethod.declaringClass.readableName()),
+					        typesAsString(method, false) },
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, true),
+					        new String(shownMethod.declaringClass.shortReadableName()),
+					        typesAsString(method, true) },
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+			} else {
+				this.handle(
+					IProblem.IncorrectArityForParameterizedMethod  ,
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, false),
+					        new String(shownMethod.declaringClass.readableName()),
+							typesAsString(shownMethod.typeVariables, false),
+					        typesAsString(method, false) },
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, true),
+					        new String(shownMethod.declaringClass.shortReadableName()),
+							typesAsString(shownMethod.typeVariables, true),
+					        typesAsString(method, true) },
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+			}
+			return;
+		case ProblemReasons.ParameterizedMethodTypeMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.ParameterizedMethodArgumentTypeMismatch,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownMethod).typeArguments, false),
+				        typesAsString(method, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownMethod).typeArguments, true),
+				        typesAsString(method, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.TypeArgumentsForRawGenericMethod :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.TypeArgumentsForRawGenericMethod ,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+				        typesAsString(method, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+				        typesAsString(method, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.VarargsElementTypeNotVisible: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=346042
+			problemMethod = (ProblemMethodBinding) method;
+			if (problemMethod.closestMatch != null) {
+			    shownMethod = problemMethod.closestMatch.original();
+		    }
+			TypeBinding varargsElementType = shownMethod.parameters[shownMethod.parameters.length - 1].leafComponentType();
+			this.handle(
+				IProblem.VarargsElementTypeNotVisible,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+				        new String(varargsElementType.readableName())
+				},
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+				        new String(varargsElementType.shortReadableName())
+				},
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(messageSend); // want to fail to see why we were here...
+			break;
+	}
+	this.handle(
+		id,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(shownMethod.selector), typesAsString(shownMethod, false)},
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(shownMethod.selector), typesAsString(shownMethod, true)},
+		(int) (messageSend.nameSourcePosition >>> 32),
+		(int) messageSend.nameSourcePosition);
+}
+public void invalidNullToSynchronize(Expression expression) {
+	this.handle(
+		IProblem.InvalidNullToSynchronized,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidOperator(BinaryExpression expression, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.InvalidOperator,
+		new String[] {
+			expression.operatorToString(),
+			leftName + ", " + rightName}, //$NON-NLS-1$
+		new String[] {
+			expression.operatorToString(),
+			leftShortName + ", " + rightShortName}, //$NON-NLS-1$
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidOperator(CompoundAssignment assign, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.InvalidOperator,
+		new String[] {
+			assign.operatorToString(),
+			leftName + ", " + rightName}, //$NON-NLS-1$
+		new String[] {
+			assign.operatorToString(),
+			leftShortName + ", " + rightShortName}, //$NON-NLS-1$
+		assign.sourceStart,
+		assign.sourceEnd);
+}
+public void invalidOperator(UnaryExpression expression, TypeBinding type) {
+	this.handle(
+		IProblem.InvalidOperator,
+		new String[] {expression.operatorToString(), new String(type.readableName())},
+		new String[] {expression.operatorToString(), new String(type.shortReadableName())},
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidParameterizedExceptionType(TypeBinding exceptionType, ASTNode location) {
+	this.handle(
+		IProblem.InvalidParameterizedExceptionType,
+		new String[] {new String(exceptionType.readableName())},
+		new String[] {new String(exceptionType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void invalidParenthesizedExpression(ASTNode reference) {
+	this.handle(
+		IProblem.InvalidParenthesizedExpression,
+		NoArgument,
+		NoArgument,
+		reference.sourceStart,
+		reference.sourceEnd);
+}
+public void invalidType(ASTNode location, TypeBinding type) {
+	if (type instanceof ReferenceBinding) {
+		if (isRecoveredName(((ReferenceBinding)type).compoundName)) return;
+	}
+	else if (type instanceof ArrayBinding) {
+		TypeBinding leafType = ((ArrayBinding)type).leafComponentType;
+		if (leafType instanceof ReferenceBinding) {
+			if (isRecoveredName(((ReferenceBinding)leafType).compoundName)) return;
+		}
+	}
+
+	if (type.isParameterizedType()) {
+		List missingTypes = type.collectMissingTypes(null);
+		if (missingTypes != null) {
+			ReferenceContext savedContext = this.referenceContext;
+			for (Iterator iterator = missingTypes.iterator(); iterator.hasNext(); ) {
+				try {
+					invalidType(location, (TypeBinding) iterator.next());
+				} finally {
+					this.referenceContext = savedContext;
+				}
+			}
+			return;
+		}
+	}
+	int id = IProblem.UndefinedType; // default
+	switch (type.problemId()) {
+		case ProblemReasons.NotFound :
+			id = IProblem.UndefinedType;
+			break;
+		case ProblemReasons.NotVisible :
+			id = IProblem.NotVisibleType;
+			break;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.AmbiguousType;
+			break;
+		case ProblemReasons.InternalNameProvided :
+			id = IProblem.InternalTypeNameProvided;
+			break;
+		case ProblemReasons.InheritedNameHidesEnclosingName :
+			id = IProblem.InheritedTypeHidesEnclosingName;
+			break;
+		case ProblemReasons.NonStaticReferenceInStaticContext :
+			id = IProblem.NonStaticTypeFromStaticInvocation;
+			break;
+		case ProblemReasons.IllegalSuperTypeVariable :
+			id = IProblem.IllegalTypeVariableSuperReference;
+			break;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(location); // want to fail to see why we were here...
+			break;
+	}
+
+	int end = location.sourceEnd;
+	if (location instanceof QualifiedNameReference) {
+		QualifiedNameReference ref = (QualifiedNameReference) location;
+		if (isRecoveredName(ref.tokens)) return;
+		if (ref.indexOfFirstFieldBinding >= 1)
+			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
+	} else if (location instanceof ParameterizedQualifiedTypeReference) {
+		// must be before instanceof ArrayQualifiedTypeReference
+		ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) location;
+		if (isRecoveredName(ref.tokens)) return;
+		if (type instanceof ReferenceBinding) {
+			char[][] name = ((ReferenceBinding) type).compoundName;
+			end = (int) ref.sourcePositions[name.length - 1];
+		}
+	} else if (location instanceof ArrayQualifiedTypeReference) {
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location;
+		if (isRecoveredName(arrayQualifiedTypeReference.tokens)) return;
+		TypeBinding leafType = type.leafComponentType();
+		if (leafType instanceof ReferenceBinding) {
+			char[][] name = ((ReferenceBinding) leafType).compoundName; // problem type will tell how much got resolved
+			end = (int) arrayQualifiedTypeReference.sourcePositions[name.length-1];
+		} else {
+			long[] positions = arrayQualifiedTypeReference.sourcePositions;
+			end = (int) positions[positions.length - 1];
+		}
+	} else if (location instanceof QualifiedTypeReference) {
+		QualifiedTypeReference ref = (QualifiedTypeReference) location;
+		if (isRecoveredName(ref.tokens)) return;
+		if (type instanceof ReferenceBinding) {
+			char[][] name = ((ReferenceBinding) type).compoundName;
+			if (name.length <= ref.sourcePositions.length)
+				end = (int) ref.sourcePositions[name.length - 1];
+		}
+	} else if (location instanceof ImportReference) {
+		ImportReference ref = (ImportReference) location;
+		if (isRecoveredName(ref.tokens)) return;
+		if (type instanceof ReferenceBinding) {
+			char[][] name = ((ReferenceBinding) type).compoundName;
+			end = (int) ref.sourcePositions[name.length - 1];
+		}
+	} else if (location instanceof ArrayTypeReference) {
+		ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
+		if (isRecoveredName(arrayTypeReference.token)) return;
+		end = arrayTypeReference.originalSourceEnd;
+	}
+	this.handle(
+		id,
+		new String[] {new String(type.leafComponentType().readableName()) },
+		new String[] {new String(type.leafComponentType().shortReadableName())},
+		location.sourceStart,
+		end);
+}
+public void invalidTypeForCollection(Expression expression) {
+	this.handle(
+			IProblem.InvalidTypeForCollection,
+			NoArgument,
+			NoArgument,
+			expression.sourceStart,
+			expression.sourceEnd);
+}
+public void invalidTypeForCollectionTarget14(Expression expression) {
+	this.handle(
+			IProblem.InvalidTypeForCollectionTarget14,
+			NoArgument,
+			NoArgument,
+			expression.sourceStart,
+			expression.sourceEnd);
+}
+public void invalidTypeToSynchronize(Expression expression, TypeBinding type) {
+	this.handle(
+		IProblem.InvalidTypeToSynchronized,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidTypeVariableAsException(TypeBinding exceptionType, ASTNode location) {
+	this.handle(
+		IProblem.InvalidTypeVariableExceptionType,
+		new String[] {new String(exceptionType.readableName())},
+		new String[] {new String(exceptionType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void invalidUnaryExpression(Expression expression) {
+	this.handle(
+		IProblem.InvalidUnaryExpression,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void invalidUsageOfAnnotation(Annotation annotation) {
+	this.handle(
+		IProblem.InvalidUsageOfAnnotations,
+		NoArgument,
+		NoArgument,
+		annotation.sourceStart,
+		annotation.sourceEnd);
+}
+public void invalidUsageOfAnnotationDeclarations(TypeDeclaration annotationTypeDeclaration) {
+	this.handle(
+		IProblem.InvalidUsageOfAnnotationDeclarations,
+		NoArgument,
+		NoArgument,
+		annotationTypeDeclaration.sourceStart,
+		annotationTypeDeclaration.sourceEnd);
+}
+public void invalidUsageOfEnumDeclarations(TypeDeclaration enumDeclaration) {
+	this.handle(
+		IProblem.InvalidUsageOfEnumDeclarations,
+		NoArgument,
+		NoArgument,
+		enumDeclaration.sourceStart,
+		enumDeclaration.sourceEnd);
+}
+public void invalidUsageOfForeachStatements(LocalDeclaration elementVariable, Expression collection) {
+	this.handle(
+		IProblem.InvalidUsageOfForeachStatements,
+		NoArgument,
+		NoArgument,
+		elementVariable.declarationSourceStart,
+		collection.sourceEnd);
+}
+public void invalidUsageOfStaticImports(ImportReference staticImport) {
+	this.handle(
+		IProblem.InvalidUsageOfStaticImports,
+		NoArgument,
+		NoArgument,
+		staticImport.declarationSourceStart,
+		staticImport.declarationSourceEnd);
+}
+public void invalidUsageOfTypeArguments(TypeReference firstTypeReference, TypeReference lastTypeReference) {
+	this.handle(
+		IProblem.InvalidUsageOfTypeArguments,
+		NoArgument,
+		NoArgument,
+		firstTypeReference.sourceStart,
+		lastTypeReference.sourceEnd);
+}
+public void invalidUsageOfTypeParameters(TypeParameter firstTypeParameter, TypeParameter lastTypeParameter) {
+	this.handle(
+		IProblem.InvalidUsageOfTypeParameters,
+		NoArgument,
+		NoArgument,
+		firstTypeParameter.declarationSourceStart,
+		lastTypeParameter.declarationSourceEnd);
+}
+public void invalidUsageOfTypeParametersForAnnotationDeclaration(TypeDeclaration annotationTypeDeclaration) {
+	TypeParameter[] parameters = annotationTypeDeclaration.typeParameters;
+	int length = parameters.length;
+	this.handle(
+			IProblem.InvalidUsageOfTypeParametersForAnnotationDeclaration,
+			NoArgument,
+			NoArgument,
+			parameters[0].declarationSourceStart,
+			parameters[length - 1].declarationSourceEnd);
+}
+public void invalidUsageOfTypeParametersForEnumDeclaration(TypeDeclaration annotationTypeDeclaration) {
+	TypeParameter[] parameters = annotationTypeDeclaration.typeParameters;
+	int length = parameters.length;
+	this.handle(
+			IProblem.InvalidUsageOfTypeParametersForEnumDeclaration,
+			NoArgument,
+			NoArgument,
+			parameters[0].declarationSourceStart,
+			parameters[length - 1].declarationSourceEnd);
+}
+public void invalidUsageOfVarargs(Argument argument) {
+	this.handle(
+		IProblem.InvalidUsageOfVarargs,
+		NoArgument,
+		NoArgument,
+		argument.type.sourceStart,
+		argument.sourceEnd);
+}
+
+public void invalidUsageOfTypeAnnotations(Annotation annotation) {
+	this.handle(
+			IProblem.InvalidUsageOfTypeAnnotations,
+			NoArgument,
+			NoArgument,
+			annotation.sourceStart,
+			annotation.sourceEnd);
+}
+
+public void misplacedTypeAnnotations(Annotation first, Annotation last) {
+	this.handle(
+			IProblem.MisplacedTypeAnnotations,
+			NoArgument,
+			NoArgument,
+			first.sourceStart,
+			last.sourceEnd);	
+}
+public void illegalUsageOfTypeAnnotations(Annotation annotation) {
+	this.handle(
+			IProblem.IllegalUsageOfTypeAnnotations,
+			NoArgument,
+			NoArgument,
+			annotation.sourceStart,
+			annotation.sourceEnd);	
+}
+public void illegalTypeAnnotationsInStaticMemberAccess(Annotation first, Annotation last) {
+	this.handle(
+			IProblem.IllegalTypeAnnotationsInStaticMemberAccess,
+			NoArgument,
+			NoArgument,
+			first.sourceStart,
+			last.sourceEnd);
+}
+public void isClassPathCorrect(char[][] wellKnownTypeName, CompilationUnitDeclaration compUnitDecl, Object location) {
+	this.referenceContext = compUnitDecl;
+	String[] arguments = new String[] {CharOperation.toString(wellKnownTypeName)};
+	int start = 0, end = 0;
+	if (location != null) {
+		if (location instanceof InvocationSite) {
+			InvocationSite site = (InvocationSite) location;
+			start = site.sourceStart();
+			end = site.sourceEnd();
+		} else if (location instanceof ASTNode) {
+			ASTNode node = (ASTNode) location;
+			start = node.sourceStart();
+			end = node.sourceEnd();
+		}
+	}
+	this.handle(
+		IProblem.IsClassPathCorrect,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+private boolean isIdentifier(int token) {
+	return token == TerminalTokens.TokenNameIdentifier;
+}
+private boolean isKeyword(int token) {
+	switch(token) {
+		case TerminalTokens.TokenNameabstract:
+		case TerminalTokens.TokenNameassert:
+		case TerminalTokens.TokenNamebyte:
+		case TerminalTokens.TokenNamebreak:
+		case TerminalTokens.TokenNameboolean:
+		case TerminalTokens.TokenNamecase:
+		case TerminalTokens.TokenNamechar:
+		case TerminalTokens.TokenNamecatch:
+		case TerminalTokens.TokenNameclass:
+		case TerminalTokens.TokenNamecontinue:
+		case TerminalTokens.TokenNamedo:
+		case TerminalTokens.TokenNamedouble:
+		case TerminalTokens.TokenNamedefault:
+		case TerminalTokens.TokenNameelse:
+		case TerminalTokens.TokenNameextends:
+		case TerminalTokens.TokenNamefor:
+		case TerminalTokens.TokenNamefinal:
+		case TerminalTokens.TokenNamefloat:
+		case TerminalTokens.TokenNamefalse:
+		case TerminalTokens.TokenNamefinally:
+		case TerminalTokens.TokenNameif:
+		case TerminalTokens.TokenNameint:
+		case TerminalTokens.TokenNameimport:
+		case TerminalTokens.TokenNameinterface:
+		case TerminalTokens.TokenNameimplements:
+		case TerminalTokens.TokenNameinstanceof:
+		case TerminalTokens.TokenNamelong:
+		case TerminalTokens.TokenNamenew:
+		case TerminalTokens.TokenNamenull:
+		case TerminalTokens.TokenNamenative:
+		case TerminalTokens.TokenNamepublic:
+		case TerminalTokens.TokenNamepackage:
+		case TerminalTokens.TokenNameprivate:
+		case TerminalTokens.TokenNameprotected:
+		case TerminalTokens.TokenNamereturn:
+		case TerminalTokens.TokenNameshort:
+		case TerminalTokens.TokenNamesuper:
+		case TerminalTokens.TokenNamestatic:
+		case TerminalTokens.TokenNameswitch:
+		case TerminalTokens.TokenNamestrictfp:
+		case TerminalTokens.TokenNamesynchronized:
+		case TerminalTokens.TokenNametry:
+		case TerminalTokens.TokenNamethis:
+		case TerminalTokens.TokenNametrue:
+		case TerminalTokens.TokenNamethrow:
+		case TerminalTokens.TokenNamethrows:
+		case TerminalTokens.TokenNametransient:
+		case TerminalTokens.TokenNamevoid:
+		case TerminalTokens.TokenNamevolatile:
+		case TerminalTokens.TokenNamewhile:
+			return true;
+		default:
+			return false;
+	}
+}
+private boolean isLiteral(int token) {
+	return Scanner.isLiteral(token);
+}
+
+private boolean isRecoveredName(char[] simpleName) {
+	return simpleName == RecoveryScanner.FAKE_IDENTIFIER;
+}
+
+private boolean isRecoveredName(char[][] qualifiedName) {
+	if(qualifiedName == null) return false;
+	for (int i = 0; i < qualifiedName.length; i++) {
+		if(qualifiedName[i] == RecoveryScanner.FAKE_IDENTIFIER) return true;
+	}
+	return false;
+}
+
+public void javadocAmbiguousMethodReference(int sourceStart, int sourceEnd, Binding fieldBinding, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocAmbiguousMethodReference);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {new String(fieldBinding.readableName())};
+		handle(
+			IProblem.JavadocAmbiguousMethodReference,
+			arguments,
+			arguments,
+			severity,
+			sourceStart,
+			sourceEnd);
+	}
+}
+
+public void javadocDeprecatedField(FieldBinding field, ASTNode location, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocUsingDeprecatedField);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		this.handle(
+			IProblem.JavadocUsingDeprecatedField,
+			new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+			new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+			severity,
+			nodeSourceStart(field, location),
+			nodeSourceEnd(field, location));
+	}
+}
+
+public void javadocDeprecatedMethod(MethodBinding method, ASTNode location, int modifiers) {
+	boolean isConstructor = method.isConstructor();
+	int severity = computeSeverity(isConstructor ? IProblem.JavadocUsingDeprecatedConstructor : IProblem.JavadocUsingDeprecatedMethod);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		if (isConstructor) {
+			this.handle(
+				IProblem.JavadocUsingDeprecatedConstructor,
+				new String[] {new String(method.declaringClass.readableName()), typesAsString(method, false)},
+				new String[] {new String(method.declaringClass.shortReadableName()), typesAsString(method, true)},
+				severity,
+				location.sourceStart,
+				location.sourceEnd);
+		} else {
+			this.handle(
+				IProblem.JavadocUsingDeprecatedMethod,
+				new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+				new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+				severity,
+				location.sourceStart,
+				location.sourceEnd);
+		}
+	}
+}
+public void javadocDeprecatedType(TypeBinding type, ASTNode location, int modifiers) {
+	javadocDeprecatedType(type, location, modifiers, Integer.MAX_VALUE);
+}
+public void javadocDeprecatedType(TypeBinding type, ASTNode location, int modifiers, int index) {
+	if (location == null) return; // 1G828DN - no type ref for synthetic arguments
+	int severity = computeSeverity(IProblem.JavadocUsingDeprecatedType);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		if (type.isMemberType() && type instanceof ReferenceBinding && !javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, ((ReferenceBinding)type).modifiers)) {
+			this.handle(IProblem.JavadocHiddenReference, NoArgument, NoArgument, location.sourceStart, location.sourceEnd);
+		} else {
+			this.handle(
+				IProblem.JavadocUsingDeprecatedType,
+				new String[] {new String(type.readableName())},
+				new String[] {new String(type.shortReadableName())},
+				severity,
+				location.sourceStart,
+				nodeSourceEnd(null, location, index));
+		}
+	}
+}
+public void javadocDuplicatedParamTag(char[] token, int sourceStart, int sourceEnd, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocDuplicateParamName);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {String.valueOf(token)};
+		this.handle(
+			IProblem.JavadocDuplicateParamName,
+			arguments,
+			arguments,
+			severity,
+			sourceStart,
+			sourceEnd);
+	}
+}
+public void javadocDuplicatedReturnTag(int sourceStart, int sourceEnd){
+	this.handle(IProblem.JavadocDuplicateReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocDuplicatedTag(char[] tagName, int sourceStart, int sourceEnd){
+	String[] arguments = new String[] { new String(tagName) };
+	this.handle(
+		IProblem.JavadocDuplicateTag,
+		arguments,
+		arguments,
+		sourceStart,
+		sourceEnd);
+}
+public void javadocDuplicatedThrowsClassName(TypeReference typeReference, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocDuplicateThrowsClassName);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+		this.handle(
+			IProblem.JavadocDuplicateThrowsClassName,
+			arguments,
+			arguments,
+			severity,
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+	}
+}
+public void javadocEmptyReturnTag(int sourceStart, int sourceEnd, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocEmptyReturnTag);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] { new String(JavadocTagConstants.TAG_RETURN) };
+		this.handle(IProblem.JavadocEmptyReturnTag, arguments, arguments, sourceStart, sourceEnd);
+	}
+}
+public void javadocErrorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params, int modifiers) {
+	int id = recType.isArrayType() ? IProblem.JavadocNoMessageSendOnArrayType : IProblem.JavadocNoMessageSendOnBaseType;
+	int severity = computeSeverity(id);
+	if (severity == ProblemSeverities.Ignore) return;
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	for (int i = 0, length = params.length; i < length; i++) {
+		if (i != 0){
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(params[i].readableName()));
+		shortBuffer.append(new String(params[i].shortReadableName()));
+	}
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		this.handle(
+			id,
+			new String[] {new String(recType.readableName()), new String(messageSend.selector), buffer.toString()},
+			new String[] {new String(recType.shortReadableName()), new String(messageSend.selector), shortBuffer.toString()},
+			severity,
+			messageSend.sourceStart,
+			messageSend.sourceEnd);
+	}
+}
+public void javadocHiddenReference(int sourceStart, int sourceEnd, Scope scope, int modifiers) {
+	Scope currentScope = scope;
+	while (currentScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE ) {
+		if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, currentScope.getDeclarationModifiers())) {
+			return;
+		}
+		currentScope = currentScope.parent;
+	}
+	String[] arguments = new String[] { this.options.getVisibilityString(this.options.reportInvalidJavadocTagsVisibility), this.options.getVisibilityString(modifiers) };
+	this.handle(IProblem.JavadocHiddenReference, arguments, arguments, sourceStart, sourceEnd);
+}
+public void javadocInvalidConstructor(Statement statement, MethodBinding targetConstructor, int modifiers) {
+
+	if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return;
+	int sourceStart = statement.sourceStart;
+	int sourceEnd = statement.sourceEnd;
+	if (statement instanceof AllocationExpression) {
+		AllocationExpression allocation = (AllocationExpression)statement;
+		if (allocation.enumConstant != null) {
+			sourceStart = allocation.enumConstant.sourceStart;
+			sourceEnd = allocation.enumConstant.sourceEnd;
+		}
+	}
+	int id = IProblem.JavadocUndefinedConstructor; //default...
+	ProblemMethodBinding problemConstructor = null;
+	MethodBinding shownConstructor = null;
+	switch (targetConstructor.problemId()) {
+		case ProblemReasons.NotFound :
+			id = IProblem.JavadocUndefinedConstructor;
+			break;
+		case ProblemReasons.NotVisible :
+			id = IProblem.JavadocNotVisibleConstructor;
+			break;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.JavadocAmbiguousConstructor;
+			break;
+		case ProblemReasons.ParameterBoundMismatch :
+			int severity = computeSeverity(IProblem.JavadocGenericConstructorTypeArgumentMismatch);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
+			shownConstructor = substitutedConstructor.original();
+
+			int augmentedLength = problemConstructor.parameters.length;
+			TypeBinding inferredTypeArgument = problemConstructor.parameters[augmentedLength-2];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) problemConstructor.parameters[augmentedLength-1];
+			TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+			System.arraycopy(problemConstructor.parameters, 0, invocationArguments, 0, augmentedLength-2);
+
+			this.handle(
+				IProblem.JavadocGenericConstructorTypeArgumentMismatch,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+				        typesAsString(invocationArguments, false),
+				        new String(inferredTypeArgument.readableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+				        typesAsString(invocationArguments, true),
+				        new String(inferredTypeArgument.shortReadableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, true) },
+				severity,
+				sourceStart,
+				sourceEnd);
+			return;
+
+		case ProblemReasons.TypeParameterArityMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			boolean noTypeVariables = shownConstructor.typeVariables == Binding.NO_TYPE_VARIABLES;
+			severity = computeSeverity(noTypeVariables ? IProblem.JavadocNonGenericConstructor : IProblem.JavadocIncorrectArityForParameterizedConstructor);
+			if (severity == ProblemSeverities.Ignore) return;
+			if (noTypeVariables) {
+				this.handle(
+					IProblem.JavadocNonGenericConstructor,
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, false),
+					        new String(shownConstructor.declaringClass.readableName()),
+					        typesAsString(targetConstructor, false) },
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, true),
+					        new String(shownConstructor.declaringClass.shortReadableName()),
+					        typesAsString(targetConstructor, true) },
+					severity,
+					sourceStart,
+					sourceEnd);
+			} else {
+				this.handle(
+					IProblem.JavadocIncorrectArityForParameterizedConstructor,
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, false),
+					        new String(shownConstructor.declaringClass.readableName()),
+							typesAsString(shownConstructor.typeVariables, false),
+					        typesAsString(targetConstructor, false) },
+					new String[] {
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor, true),
+					        new String(shownConstructor.declaringClass.shortReadableName()),
+							typesAsString(shownConstructor.typeVariables, true),
+					        typesAsString(targetConstructor, true) },
+					severity,
+					sourceStart,
+					sourceEnd);
+			}
+			return;
+		case ProblemReasons.ParameterizedMethodTypeMismatch :
+			severity = computeSeverity(IProblem.JavadocParameterizedConstructorArgumentTypeMismatch);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.JavadocParameterizedConstructorArgumentTypeMismatch,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, false),
+				        typesAsString(targetConstructor, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, true),
+				        typesAsString(targetConstructor, true) },
+				severity,
+				sourceStart,
+				sourceEnd);
+			return;
+		case ProblemReasons.TypeArgumentsForRawGenericMethod :
+			severity = computeSeverity(IProblem.JavadocTypeArgumentsForRawGenericConstructor);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.JavadocTypeArgumentsForRawGenericConstructor,
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, false),
+				        new String(shownConstructor.declaringClass.readableName()),
+				        typesAsString(targetConstructor, false) },
+				new String[] {
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor, true),
+				        new String(shownConstructor.declaringClass.shortReadableName()),
+				        typesAsString(targetConstructor, true) },
+				severity,
+				sourceStart,
+				sourceEnd);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(statement); // want to fail to see why we were here...
+			break;
+	}
+	int severity = computeSeverity(id);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		id,
+		new String[] {new String(targetConstructor.declaringClass.readableName()), typesAsString(targetConstructor, false)},
+		new String[] {new String(targetConstructor.declaringClass.shortReadableName()), typesAsString(targetConstructor, true)},
+		severity,
+		statement.sourceStart,
+		statement.sourceEnd);
+}
+/*
+ * Similar implementation than invalidField(FieldReference...)
+ * Note that following problem id cannot occur for Javadoc:
+ * 	- NonStaticReferenceInStaticContext :
+ * 	- NonStaticReferenceInConstructorInvocation :
+ * 	- ReceiverTypeNotVisible :
+ */
+public void javadocInvalidField(FieldReference fieldRef, Binding fieldBinding, TypeBinding searchedType, int modifiers) {
+	int id = IProblem.JavadocUndefinedField;
+	switch (fieldBinding.problemId()) {
+		case ProblemReasons.NotFound :
+			id = IProblem.JavadocUndefinedField;
+			break;
+		case ProblemReasons.NotVisible :
+			id = IProblem.JavadocNotVisibleField;
+			break;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.JavadocAmbiguousField;
+			break;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(fieldRef); // want to fail to see why we were here...
+			break;
+	}
+	int severity = computeSeverity(id);
+	if (severity == ProblemSeverities.Ignore) return;
+	// report issue
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {new String(fieldBinding.readableName())};
+		handle(
+			id,
+			arguments,
+			arguments,
+			severity,
+			fieldRef.sourceStart,
+			fieldRef.sourceEnd);
+	}
+}
+public void javadocInvalidMemberTypeQualification(int sourceStart, int sourceEnd, int modifiers){
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		this.handle(IProblem.JavadocInvalidMemberTypeQualification, NoArgument, NoArgument, sourceStart, sourceEnd);
+	}
+}
+/*
+ * Similar implementation than invalidMethod(MessageSend...)
+ * Note that following problem id cannot occur for Javadoc:
+ * 	- NonStaticReferenceInStaticContext :
+ * 	- NonStaticReferenceInConstructorInvocation :
+ * 	- ReceiverTypeNotVisible :
+ */
+public void javadocInvalidMethod(MessageSend messageSend, MethodBinding method, int modifiers) {
+	if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return;
+	// set problem id
+	ProblemMethodBinding problemMethod = null;
+	MethodBinding shownMethod = null;
+	int id = IProblem.JavadocUndefinedMethod; //default...
+	switch (method.problemId()) {
+		case ProblemReasons.NotFound :
+			id = IProblem.JavadocUndefinedMethod;
+			problemMethod = (ProblemMethodBinding) method;
+			if (problemMethod.closestMatch != null) {
+				int severity = computeSeverity(IProblem.JavadocParameterMismatch);
+				if (severity == ProblemSeverities.Ignore) return;
+				String closestParameterTypeNames = typesAsString(problemMethod.closestMatch, false);
+				String parameterTypeNames = typesAsString(method, false);
+				String closestParameterTypeShortNames = typesAsString(problemMethod.closestMatch, true);
+				String parameterTypeShortNames = typesAsString(method, true);
+				if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){
+					closestParameterTypeShortNames = closestParameterTypeNames;
+					parameterTypeShortNames = parameterTypeNames;
+				}
+				this.handle(
+					IProblem.JavadocParameterMismatch,
+					new String[] {
+						new String(problemMethod.closestMatch.declaringClass.readableName()),
+						new String(problemMethod.closestMatch.selector),
+						closestParameterTypeNames,
+						parameterTypeNames
+					},
+					new String[] {
+						new String(problemMethod.closestMatch.declaringClass.shortReadableName()),
+						new String(problemMethod.closestMatch.selector),
+						closestParameterTypeShortNames,
+						parameterTypeShortNames
+					},
+					severity,
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+				return;
+			}
+			break;
+		case ProblemReasons.NotVisible :
+			id = IProblem.JavadocNotVisibleMethod;
+			break;
+		case ProblemReasons.Ambiguous :
+			id = IProblem.JavadocAmbiguousMethod;
+			break;
+		case ProblemReasons.ParameterBoundMismatch :
+			int severity = computeSeverity(IProblem.JavadocGenericMethodTypeArgumentMismatch);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemMethod = (ProblemMethodBinding) method;
+			ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
+			shownMethod = substitutedMethod.original();
+			int augmentedLength = problemMethod.parameters.length;
+			TypeBinding inferredTypeArgument = problemMethod.parameters[augmentedLength-2];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) problemMethod.parameters[augmentedLength-1];
+			TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+			System.arraycopy(problemMethod.parameters, 0, invocationArguments, 0, augmentedLength-2);
+			this.handle(
+				IProblem.JavadocGenericMethodTypeArgumentMismatch,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+				        typesAsString(invocationArguments, false),
+				        new String(inferredTypeArgument.readableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+				        typesAsString(invocationArguments, true),
+				        new String(inferredTypeArgument.shortReadableName()),
+				        new String(typeParameter.sourceName),
+				        parameterBoundAsString(typeParameter, true) },
+				severity,
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.TypeParameterArityMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			boolean noTypeVariables = shownMethod.typeVariables == Binding.NO_TYPE_VARIABLES;
+			severity = computeSeverity(noTypeVariables ? IProblem.JavadocNonGenericMethod : IProblem.JavadocIncorrectArityForParameterizedMethod);
+			if (severity == ProblemSeverities.Ignore) return;
+			if (noTypeVariables) {
+				this.handle(
+					IProblem.JavadocNonGenericMethod,
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, false),
+					        new String(shownMethod.declaringClass.readableName()),
+					        typesAsString(method, false) },
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, true),
+					        new String(shownMethod.declaringClass.shortReadableName()),
+					        typesAsString(method, true) },
+					severity,
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+			} else {
+				this.handle(
+					IProblem.JavadocIncorrectArityForParameterizedMethod,
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, false),
+					        new String(shownMethod.declaringClass.readableName()),
+							typesAsString(shownMethod.typeVariables, false),
+					        typesAsString(method, false) },
+					new String[] {
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod, true),
+					        new String(shownMethod.declaringClass.shortReadableName()),
+							typesAsString(shownMethod.typeVariables, true),
+					        typesAsString(method, true) },
+					severity,
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);
+			}
+			return;
+		case ProblemReasons.ParameterizedMethodTypeMismatch :
+			severity = computeSeverity(IProblem.JavadocParameterizedMethodArgumentTypeMismatch);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.JavadocParameterizedMethodArgumentTypeMismatch,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownMethod).typeArguments, false),
+				        typesAsString(method, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+						typesAsString(((ParameterizedGenericMethodBinding)shownMethod).typeArguments, true),
+				        typesAsString(method, true) },
+				severity,
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.TypeArgumentsForRawGenericMethod :
+			severity = computeSeverity(IProblem.JavadocTypeArgumentsForRawGenericMethod);
+			if (severity == ProblemSeverities.Ignore) return;
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.JavadocTypeArgumentsForRawGenericMethod,
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, false),
+				        new String(shownMethod.declaringClass.readableName()),
+				        typesAsString(method, false) },
+				new String[] {
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod, true),
+				        new String(shownMethod.declaringClass.shortReadableName()),
+				        typesAsString(method, true) },
+				severity,
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);
+			return;
+		case ProblemReasons.NoError : // 0
+		default :
+			needImplementation(messageSend); // want to fail to see why we were here...
+			break;
+	}
+	int severity = computeSeverity(id);
+	if (severity == ProblemSeverities.Ignore) return;
+	// report issue
+	this.handle(
+		id,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(method.selector), typesAsString(method, false)},
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(method.selector), typesAsString(method, true)},
+		severity,
+		(int) (messageSend.nameSourcePosition >>> 32),
+		(int) messageSend.nameSourcePosition);
+}
+public void javadocInvalidParamTagName(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidParamTagName, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidParamTypeParameter(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidParamTagTypeParameter, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidReference(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+/**
+ * Report an invalid reference that does not conform to the href syntax.
+ * Valid syntax example: @see IProblem.JavadocInvalidSeeHref
+ */
+public void javadocInvalidSeeHref(int sourceStart, int sourceEnd) {
+this.handle(IProblem.JavadocInvalidSeeHref, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidSeeReferenceArgs(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidSeeArgs, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+/**
+ * Report a problem on an invalid URL reference.
+ * Valid syntax example: @see IProblem.JavadocInvalidSeeUrlReference
+ */
+public void javadocInvalidSeeUrlReference(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidSeeUrlReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidTag(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidThrowsClass(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocInvalidThrowsClass, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocInvalidThrowsClassName(TypeReference typeReference, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocInvalidThrowsClassName);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {String.valueOf(typeReference.resolvedType.sourceName())};
+		this.handle(
+			IProblem.JavadocInvalidThrowsClassName,
+			arguments,
+			arguments,
+			severity,
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+	}
+}
+public void javadocInvalidType(ASTNode location, TypeBinding type, int modifiers) {
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		int id = IProblem.JavadocUndefinedType; // default
+		switch (type.problemId()) {
+			case ProblemReasons.NotFound :
+				id = IProblem.JavadocUndefinedType;
+				break;
+			case ProblemReasons.NotVisible :
+				id = IProblem.JavadocNotVisibleType;
+				break;
+			case ProblemReasons.Ambiguous :
+				id = IProblem.JavadocAmbiguousType;
+				break;
+			case ProblemReasons.InternalNameProvided :
+				id = IProblem.JavadocInternalTypeNameProvided;
+				break;
+			case ProblemReasons.InheritedNameHidesEnclosingName :
+				id = IProblem.JavadocInheritedNameHidesEnclosingTypeName;
+				break;
+			case ProblemReasons.NonStaticReferenceInStaticContext :
+				id = IProblem.JavadocNonStaticTypeFromStaticInvocation;
+			    break;
+			case ProblemReasons.NoError : // 0
+			default :
+				needImplementation(location); // want to fail to see why we were here...
+				break;
+		}
+		int severity = computeSeverity(id);
+		if (severity == ProblemSeverities.Ignore) return;
+		this.handle(
+			id,
+			new String[] {new String(type.readableName())},
+			new String[] {new String(type.shortReadableName())},
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void javadocInvalidValueReference(int sourceStart, int sourceEnd, int modifiers) {
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
+		this.handle(IProblem.JavadocInvalidValueReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMalformedSeeReference(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocMalformedSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissing(int sourceStart, int sourceEnd, int modifiers){
+	int severity = computeSeverity(IProblem.JavadocMissing);
+	this.javadocMissing(sourceStart, sourceEnd, severity, modifiers);
+}
+public void javadocMissing(int sourceStart, int sourceEnd, int severity, int modifiers){
+	if (severity == ProblemSeverities.Ignore) return;
+	boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0;
+	boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocComments) != ProblemSeverities.Ignore)
+					&& (!overriding || this.options.reportMissingJavadocCommentsOverriding);
+	if (report) {
+		String arg = javadocVisibilityArgument(this.options.reportMissingJavadocCommentsVisibility, modifiers);
+		if (arg != null) {
+			String[] arguments = new String[] { arg };
+			this.handle(
+				IProblem.JavadocMissing,
+				arguments,
+				arguments,
+				severity,
+				sourceStart,
+				sourceEnd);
+		}
+	}
+}
+public void javadocMissingHashCharacter(int sourceStart, int sourceEnd, String ref){
+	int severity = computeSeverity(IProblem.JavadocMissingHashCharacter);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] { ref };
+	this.handle(
+		IProblem.JavadocMissingHashCharacter,
+		arguments,
+		arguments,
+		severity,
+		sourceStart,
+		sourceEnd);
+}
+public void javadocMissingIdentifier(int sourceStart, int sourceEnd, int modifiers){
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
+		this.handle(IProblem.JavadocMissingIdentifier, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingParamName(int sourceStart, int sourceEnd, int modifiers){
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
+		this.handle(IProblem.JavadocMissingParamName, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocMissingParamTag);
+	if (severity == ProblemSeverities.Ignore) return;
+	boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0;
+	boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+					&& (!overriding || this.options.reportMissingJavadocTagsOverriding);
+	if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] { String.valueOf(name) };
+		this.handle(
+			IProblem.JavadocMissingParamTag,
+			arguments,
+			arguments,
+			severity,
+			sourceStart,
+			sourceEnd);
+	}
+}
+public void javadocMissingReference(int sourceStart, int sourceEnd, int modifiers){
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
+		this.handle(IProblem.JavadocMissingSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+public void javadocMissingReturnTag(int sourceStart, int sourceEnd, int modifiers){
+	boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0;
+	boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+					&& (!overriding || this.options.reportMissingJavadocTagsOverriding);
+	if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+		this.handle(IProblem.JavadocMissingReturnTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+	}
+}
+public void javadocMissingTagDescription(char[] tokenName, int sourceStart, int sourceEnd, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocMissingTagDescription);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] { new String(tokenName) };
+		// use IProblem.JavadocEmptyReturnTag for all identified tags
+		this.handle(IProblem.JavadocEmptyReturnTag, arguments, arguments, sourceStart, sourceEnd);
+	}
+}
+public void javadocMissingTagDescriptionAfterReference(int sourceStart, int sourceEnd, int modifiers){
+	int severity = computeSeverity(IProblem.JavadocMissingTagDescription);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		this.handle(IProblem.JavadocMissingTagDescription, NoArgument, NoArgument, severity, sourceStart, sourceEnd);
+	}
+}
+public void javadocMissingThrowsClassName(int sourceStart, int sourceEnd, int modifiers){
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		this.handle(IProblem.JavadocMissingThrowsClassName, NoArgument, NoArgument, sourceStart, sourceEnd);
+	}
+}
+public void javadocMissingThrowsTag(TypeReference typeRef, int modifiers){
+	int severity = computeSeverity(IProblem.JavadocMissingThrowsTag);
+	if (severity == ProblemSeverities.Ignore) return;
+	boolean overriding = (modifiers & (ExtraCompilerModifiers.AccImplementing|ExtraCompilerModifiers.AccOverriding)) != 0;
+	boolean report = (this.options.getSeverity(CompilerOptions.MissingJavadocTags) != ProblemSeverities.Ignore)
+					&& (!overriding || this.options.reportMissingJavadocTagsOverriding);
+	if (report && javadocVisibility(this.options.reportMissingJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] { String.valueOf(typeRef.resolvedType.sourceName()) };
+		this.handle(
+			IProblem.JavadocMissingThrowsTag,
+			arguments,
+			arguments,
+			severity,
+			typeRef.sourceStart,
+			typeRef.sourceEnd);
+	}
+}
+public void javadocUndeclaredParamTagName(char[] token, int sourceStart, int sourceEnd, int modifiers) {
+	int severity = computeSeverity(IProblem.JavadocInvalidParamName);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
+		String[] arguments = new String[] {String.valueOf(token)};
+		this.handle(
+			IProblem.JavadocInvalidParamName,
+			arguments,
+			arguments,
+			severity,
+			sourceStart,
+			sourceEnd);
+	}
+}
+
+public void javadocUnexpectedTag(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocUnexpectedTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+
+public void javadocUnexpectedText(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocUnexpectedText, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+
+public void javadocUnterminatedInlineTag(int sourceStart, int sourceEnd) {
+	this.handle(IProblem.JavadocUnterminatedInlineTag, NoArgument, NoArgument, sourceStart, sourceEnd);
+}
+
+private boolean javadocVisibility(int visibility, int modifiers) {
+	if (modifiers < 0) return true;
+	switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) {
+		case ClassFileConstants.AccPublic :
+			return true;
+		case ClassFileConstants.AccProtected:
+			return (visibility != ClassFileConstants.AccPublic);
+		case ClassFileConstants.AccDefault:
+			return (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate);
+		case ClassFileConstants.AccPrivate:
+			return (visibility == ClassFileConstants.AccPrivate);
+	}
+	return true;
+}
+
+private String javadocVisibilityArgument(int visibility, int modifiers) {
+	String argument = null;
+	switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) {
+		case ClassFileConstants.AccPublic :
+			argument = CompilerOptions.PUBLIC;
+			break;
+		case ClassFileConstants.AccProtected:
+			if (visibility != ClassFileConstants.AccPublic) {
+				argument = CompilerOptions.PROTECTED;
+			}
+			break;
+		case ClassFileConstants.AccDefault:
+			if (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate) {
+				argument = CompilerOptions.DEFAULT;
+			}
+			break;
+		case ClassFileConstants.AccPrivate:
+			if (visibility == ClassFileConstants.AccPrivate) {
+				argument = CompilerOptions.PRIVATE;
+			}
+			break;
+	}
+	return argument;
+}
+
+public void localVariableHiding(LocalDeclaration local, Binding hiddenVariable, boolean  isSpecialArgHidingField) {
+	if (hiddenVariable instanceof LocalVariableBinding) {
+		int id = (local instanceof Argument)
+				? IProblem.ArgumentHidingLocalVariable
+				: IProblem.LocalVariableHidingLocalVariable;
+		int severity = computeSeverity(id);
+		if (severity == ProblemSeverities.Ignore) return;
+		String[] arguments = new String[] {new String(local.name)  };
+		this.handle(
+			id,
+			arguments,
+			arguments,
+			severity,
+			nodeSourceStart(hiddenVariable, local),
+			nodeSourceEnd(hiddenVariable, local));
+	} else if (hiddenVariable instanceof FieldBinding) {
+		if (isSpecialArgHidingField && !this.options.reportSpecialParameterHidingField){
+			return;
+		}
+		int id = (local instanceof Argument)
+				? IProblem.ArgumentHidingField
+				: IProblem.LocalVariableHidingField;
+		int severity = computeSeverity(id);
+		if (severity == ProblemSeverities.Ignore) return;
+		FieldBinding field = (FieldBinding) hiddenVariable;
+		this.handle(
+			id,
+			new String[] {new String(local.name) , new String(field.declaringClass.readableName()) },
+			new String[] {new String(local.name), new String(field.declaringClass.shortReadableName()) },
+			severity,
+			local.sourceStart,
+			local.sourceEnd);
+	}
+}
+
+public void localVariableNonNullComparedToNull(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.NonNullLocalVariableComparisonYieldsFalse);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments;
+	int problemId;
+	if (local.isNonNull()) {
+		char[][] annotationName = this.options.nonNullAnnotationName; // cannot be null if local is declared @NonNull
+		arguments = new String[] {new String(local.name), new String(annotationName[annotationName.length-1])  };
+		problemId = IProblem.SpecdNonNullLocalVariableComparisonYieldsFalse;
+	} else {
+		arguments = new String[] {new String(local.name)  };
+		problemId = IProblem.NonNullLocalVariableComparisonYieldsFalse; 
+	}
+	this.handle(
+		problemId,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void localVariableNullComparedToNonNull(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.NullLocalVariableComparisonYieldsFalse);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)  };
+	this.handle(
+		IProblem.NullLocalVariableComparisonYieldsFalse,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+/**
+ * @param expr expression being compared for null or nonnull
+ * @param checkForNull true if checking for null, false if checking for nonnull 
+ */
+public boolean expressionNonNullComparison(Expression expr, boolean checkForNull) {
+	int problemId = 0;
+	Binding binding = null;
+	String[] arguments = null;
+	int start = 0, end = 0;
+
+	Expression location = expr;
+	// unwrap uninteresting nodes:
+	while (true) {
+		if (expr instanceof Assignment)
+			return false; // don't report against the assignment, but the variable
+		else if (expr instanceof CastExpression)
+			expr = ((CastExpression) expr).expression;
+		else
+			break;
+	}
+	// check all those kinds of expressions that can possible answer NON_NULL from nullStatus():
+	if (expr instanceof MessageSend) {
+		problemId = checkForNull 
+				? IProblem.NonNullMessageSendComparisonYieldsFalse
+				: IProblem.RedundantNullCheckOnNonNullMessageSend;
+		MethodBinding method = ((MessageSend)expr).binding;
+		binding = method;
+		arguments = new String[] { new String(method.shortReadableName()) };
+		start = location.sourceStart;
+		end = location.sourceEnd;
+	} else if (expr instanceof Reference && !(expr instanceof ThisReference) && !(expr instanceof ArrayReference)) {
+		FieldBinding field = ((Reference)expr).lastFieldBinding();
+		if (field == null) {
+			return false;
+		}
+		if (field.isNonNull()) {
+			problemId = checkForNull
+					? IProblem.NonNullSpecdFieldComparisonYieldsFalse
+					: IProblem.RedundantNullCheckOnNonNullSpecdField;
+			char[][] nonNullName = this.options.nonNullAnnotationName;
+			arguments = new String[] { new String(field.name), 
+									   new String(nonNullName[nonNullName.length-1]) };
+		}
+		binding = field;
+		start = nodeSourceStart(binding, location);
+		end = nodeSourceEnd(binding, location);
+	} else if (expr instanceof AllocationExpression 
+			|| expr instanceof ArrayAllocationExpression 
+			|| expr instanceof ArrayInitializer
+			|| expr instanceof ClassLiteralAccess
+			|| expr instanceof ThisReference) {
+		// fall through to bottom
+	} else if (expr instanceof Literal
+				|| expr instanceof ConditionalExpression) {
+		if (expr instanceof NullLiteral) {
+			needImplementation(location); // reported as nonnull??
+			return false;
+		}
+		if (expr.resolvedType != null && expr.resolvedType.isBaseType()) {
+			// false alarm, auto(un)boxing is involved
+			return false;
+		}
+		// fall through to bottom
+	} else if (expr instanceof BinaryExpression) {
+		if ((expr.bits & ASTNode.ReturnTypeIDMASK) != TypeIds.T_JavaLangString) {
+			// false alarm, primitive types involved, must be auto(un)boxing?
+			return false;
+		}
+		// fall through to bottom
+	} else {
+		needImplementation(expr); // want to see if we get here
+		return false;
+	}
+	if (problemId == 0) {
+		// standard case, fill in details now
+		problemId = checkForNull 
+				? IProblem.NonNullExpressionComparisonYieldsFalse
+				: IProblem.RedundantNullCheckOnNonNullExpression;
+		start = location.sourceStart;
+		end = location.sourceEnd;
+		arguments = NoArgument;
+	}
+	this.handle(problemId, arguments, arguments, start, end);
+	return true;
+}
+
+public void localVariableNullInstanceof(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.NullLocalVariableInstanceofYieldsFalse);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)  };
+	this.handle(
+		IProblem.NullLocalVariableInstanceofYieldsFalse,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void localVariableNullReference(LocalVariableBinding local, ASTNode location) {
+	if (location instanceof Expression && (((Expression)location).implicitConversion & TypeIds.UNBOXING) != 0) {
+		nullUnboxing(location, local.type);
+		return;
+	}
+	int severity = computeSeverity(IProblem.NullLocalVariableReference);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)  };
+	this.handle(
+		IProblem.NullLocalVariableReference,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void localVariablePotentialNullReference(LocalVariableBinding local, ASTNode location) {
+	if (location instanceof Expression && (((Expression)location).implicitConversion & TypeIds.UNBOXING) != 0) {
+		potentialNullUnboxing(location, local.type);
+		return;
+	}
+	int severity = computeSeverity(IProblem.PotentialNullLocalVariableReference);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)};
+	this.handle(
+		IProblem.PotentialNullLocalVariableReference,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void potentialNullUnboxing(ASTNode expression, TypeBinding boxType) {
+	String[] arguments = new String[] { String.valueOf(boxType.readableName()) };
+	String[] argumentsShort = new String[] { String.valueOf(boxType.shortReadableName()) };
+	this.handle(IProblem.PotentialNullUnboxing, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void nullUnboxing(ASTNode expression, TypeBinding boxType) {
+	String[] arguments = new String[] { String.valueOf(boxType.readableName()) };
+	String[] argumentsShort = new String[] { String.valueOf(boxType.shortReadableName()) };
+	this.handle(IProblem.NullUnboxing, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void nullableFieldDereference(VariableBinding variable, long position) {
+	String[] arguments = new String[] {new String(variable.name)};
+	char[][] nullableName = this.options.nullableAnnotationName;
+		arguments = new String[] {new String(variable.name), new String(nullableName[nullableName.length-1])};
+	this.handle(
+		IProblem.NullableFieldReference,
+		arguments,
+		arguments,
+		(int)(position >>> 32),
+		(int)(position));
+}
+
+public void localVariableRedundantCheckOnNonNull(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.RedundantNullCheckOnNonNullLocalVariable);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments;
+	int problemId;
+	if (local.isNonNull()) {
+		char[][] annotationName = this.options.nonNullAnnotationName; // cannot be null if local is declared @NonNull
+		arguments = new String[] {new String(local.name), new String(annotationName[annotationName.length-1])  };
+		problemId = IProblem.RedundantNullCheckOnSpecdNonNullLocalVariable;
+	} else {
+		arguments = new String[] {new String(local.name)  };
+		problemId = IProblem.RedundantNullCheckOnNonNullLocalVariable; 
+	}
+	this.handle(
+		problemId, 
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void localVariableRedundantCheckOnNull(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.RedundantNullCheckOnNullLocalVariable);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)  };
+	this.handle(
+		IProblem.RedundantNullCheckOnNullLocalVariable,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void localVariableRedundantNullAssignment(LocalVariableBinding local, ASTNode location) {
+	if ((location.bits & ASTNode.FirstAssignmentToLocal) != 0) // https://bugs.eclipse.org/338303 - Warning about Redundant assignment conflicts with definite assignment
+		return;
+	int severity = computeSeverity(IProblem.RedundantLocalVariableNullAssignment);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(local.name)  };
+	this.handle(
+		IProblem.RedundantLocalVariableNullAssignment,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+
+public void methodMustOverride(AbstractMethodDeclaration method, long complianceLevel) {
+	MethodBinding binding = method.binding;
+	this.handle(
+		complianceLevel == ClassFileConstants.JDK1_5 ? IProblem.MethodMustOverride : IProblem.MethodMustOverrideOrImplement,
+		new String[] {new String(binding.selector), typesAsString(binding, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding, true), new String(binding.declaringClass.shortReadableName()),},
+		method.sourceStart,
+		method.sourceEnd);
+}
+
+public void methodNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod, int severity) {
+	this.handle(
+		IProblem.MethodNameClash,
+		new String[] {
+			new String(currentMethod.selector),
+			typesAsString(currentMethod, false),
+			new String(currentMethod.declaringClass.readableName()),
+			typesAsString(inheritedMethod, false),
+			new String(inheritedMethod.declaringClass.readableName()),
+		 },
+		new String[] {
+			new String(currentMethod.selector),
+			typesAsString(currentMethod, true),
+			new String(currentMethod.declaringClass.shortReadableName()),
+			typesAsString(inheritedMethod, true),
+			new String(inheritedMethod.declaringClass.shortReadableName()),
+		 },
+		severity,
+		currentMethod.sourceStart(),
+		currentMethod.sourceEnd());
+}
+
+public void methodNameClashHidden(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	this.handle(
+		IProblem.MethodNameClashHidden,
+		new String[] {
+			new String(currentMethod.selector),
+			typesAsString(currentMethod, currentMethod.parameters, false),
+			new String(currentMethod.declaringClass.readableName()),
+			typesAsString(inheritedMethod, inheritedMethod.parameters, false),
+			new String(inheritedMethod.declaringClass.readableName()),
+		 },
+		new String[] {
+			new String(currentMethod.selector),
+			typesAsString(currentMethod, currentMethod.parameters, true),
+			new String(currentMethod.declaringClass.shortReadableName()),
+			typesAsString(inheritedMethod, inheritedMethod.parameters, true),
+			new String(inheritedMethod.declaringClass.shortReadableName()),
+		 },
+		currentMethod.sourceStart(),
+		currentMethod.sourceEnd());
+}
+
+public void methodNeedBody(AbstractMethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.MethodRequiresBody,
+		NoArgument,
+		NoArgument,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void methodNeedingNoBody(MethodDeclaration methodDecl) {
+	this.handle(
+		((methodDecl.modifiers & ClassFileConstants.AccNative) != 0) ? IProblem.BodyForNativeMethod : IProblem.BodyForAbstractMethod,
+		NoArgument,
+		NoArgument,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void methodWithConstructorName(MethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.MethodButWithConstructorName,
+		NoArgument,
+		NoArgument,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void methodCanBeDeclaredStatic(MethodDeclaration methodDecl) {
+	int severity = computeSeverity(IProblem.MethodCanBeStatic);
+	if (severity == ProblemSeverities.Ignore) return;
+	MethodBinding method = methodDecl.binding;
+	this.handle(
+			IProblem.MethodCanBeStatic,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(method.selector),
+			typesAsString(method, false)
+		 },
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(method.selector),
+			typesAsString(method, true)
+		 },
+		severity,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void methodCanBePotentiallyDeclaredStatic(MethodDeclaration methodDecl) {
+	int severity = computeSeverity(IProblem.MethodCanBePotentiallyStatic);
+	if (severity == ProblemSeverities.Ignore) return;
+	MethodBinding method = methodDecl.binding;
+	this.handle(
+			IProblem.MethodCanBePotentiallyStatic,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(method.selector),
+			typesAsString(method, false)
+		 },
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(method.selector),
+			typesAsString(method, true)
+		 },
+		severity,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+public void missingDeprecatedAnnotationForField(FieldDeclaration field) {
+	int severity = computeSeverity(IProblem.FieldMissingDeprecatedAnnotation);
+	if (severity == ProblemSeverities.Ignore) return;
+	FieldBinding binding = field.binding;
+	this.handle(
+		IProblem.FieldMissingDeprecatedAnnotation,
+		new String[] {new String(binding.declaringClass.readableName()), new String(binding.name), },
+		new String[] {new String(binding.declaringClass.shortReadableName()), new String(binding.name), },
+		severity,
+		nodeSourceStart(binding, field),
+		nodeSourceEnd(binding, field));
+}
+
+public void missingDeprecatedAnnotationForMethod(AbstractMethodDeclaration method) {
+	int severity = computeSeverity(IProblem.MethodMissingDeprecatedAnnotation);
+	if (severity == ProblemSeverities.Ignore) return;
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MethodMissingDeprecatedAnnotation,
+		new String[] {new String(binding.selector), typesAsString(binding, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding, true), new String(binding.declaringClass.shortReadableName()),},
+		severity,
+		method.sourceStart,
+		method.sourceEnd);
+}
+
+public void missingDeprecatedAnnotationForType(TypeDeclaration type) {
+	int severity = computeSeverity(IProblem.TypeMissingDeprecatedAnnotation);
+	if (severity == ProblemSeverities.Ignore) return;
+	TypeBinding binding = type.binding;
+	this.handle(
+		IProblem.TypeMissingDeprecatedAnnotation,
+		new String[] {new String(binding.readableName()), },
+		new String[] {new String(binding.shortReadableName()),},
+		severity,
+		type.sourceStart,
+		type.sourceEnd);
+}
+public void notAFunctionalInterface(TypeDeclaration type) {
+	TypeBinding binding = type.binding;
+	this.handle(
+		IProblem.InterfaceNotFunctionalInterface,
+		new String[] {new String(binding.readableName()), },
+		new String[] {new String(binding.shortReadableName()),},
+		type.sourceStart,
+		type.sourceEnd);
+}
+public void missingEnumConstantCase(SwitchStatement switchStatement, FieldBinding enumConstant) {
+	this.handle(
+		switchStatement.defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault,
+		new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) },
+		new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) },
+		switchStatement.expression.sourceStart,
+		switchStatement.expression.sourceEnd);
+}
+public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSwitch, TypeBinding expressionType) {
+	if (isEnumSwitch) {
+		this.handle(
+				IProblem.MissingEnumDefaultCase,
+				new String[] {new String(expressionType.readableName())},
+				new String[] {new String(expressionType.shortReadableName())},
+				switchStatement.expression.sourceStart,
+				switchStatement.expression.sourceEnd);
+	} else {
+		this.handle(
+				IProblem.MissingDefaultCase,
+				NoArgument,
+				NoArgument,
+				switchStatement.expression.sourceStart,
+				switchStatement.expression.sourceEnd);
+	}
+}
+public void missingOverrideAnnotation(AbstractMethodDeclaration method) {
+	int severity = computeSeverity(IProblem.MissingOverrideAnnotation);
+	if (severity == ProblemSeverities.Ignore) return;
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MissingOverrideAnnotation,
+		new String[] {new String(binding.selector), typesAsString(binding, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding, true), new String(binding.declaringClass.shortReadableName()),},
+		severity,
+		method.sourceStart,
+		method.sourceEnd);
+}
+public void missingOverrideAnnotationForInterfaceMethodImplementation(AbstractMethodDeclaration method) {
+	int severity = computeSeverity(IProblem.MissingOverrideAnnotationForInterfaceMethodImplementation);
+	if (severity == ProblemSeverities.Ignore) return;
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MissingOverrideAnnotationForInterfaceMethodImplementation,
+		new String[] {new String(binding.selector), typesAsString(binding, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding, true), new String(binding.declaringClass.shortReadableName()),},
+		severity,
+		method.sourceStart,
+		method.sourceEnd);
+}
+public void missingReturnType(AbstractMethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.MissingReturnType,
+		NoArgument,
+		NoArgument,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void missingSemiColon(Expression expression){
+	this.handle(
+		IProblem.MissingSemiColon,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void missingSerialVersion(TypeDeclaration typeDecl) {
+	String[] arguments = new String[] {new String(typeDecl.name)};
+	this.handle(
+		IProblem.MissingSerialVersion,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd);
+}
+public void missingSynchronizedOnInheritedMethod(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	this.handle(
+			IProblem.MissingSynchronizedModifierInInheritedMethod,
+			new String[] {
+					new String(currentMethod.declaringClass.readableName()),
+					new String(currentMethod.selector),
+					typesAsString(currentMethod, false),
+			},
+			new String[] {
+					new String(currentMethod.declaringClass.shortReadableName()),
+					new String(currentMethod.selector),
+					typesAsString(currentMethod, true),
+			},
+			currentMethod.sourceStart(),
+			currentMethod.sourceEnd());
+}
+public void missingTypeInConstructor(ASTNode location, MethodBinding constructor) {
+	List missingTypes = constructor.collectMissingTypes(null);
+	if (missingTypes == null) {
+		System.err.println("The constructor " + constructor + " is wrongly tagged as containing missing types"); //$NON-NLS-1$ //$NON-NLS-2$
+		return;
+	}
+	TypeBinding missingType = (TypeBinding) missingTypes.get(0);
+	int start = location.sourceStart;
+	int end = location.sourceEnd;
+	if (location instanceof QualifiedAllocationExpression) {
+		QualifiedAllocationExpression qualifiedAllocation = (QualifiedAllocationExpression) location;
+		if (qualifiedAllocation.anonymousType != null) {
+			start = qualifiedAllocation.anonymousType.sourceStart;
+			end = qualifiedAllocation.anonymousType.sourceEnd;
+		}
+	}
+	this.handle(
+			IProblem.MissingTypeInConstructor,
+			new String[] {
+			        new String(constructor.declaringClass.readableName()),
+			        typesAsString(constructor, false),
+			       	new String(missingType.readableName()),
+			},
+			new String[] {
+			        new String(constructor.declaringClass.shortReadableName()),
+			        typesAsString(constructor, true),
+			       	new String(missingType.shortReadableName()),
+			},
+			start,
+			end);
+}
+
+public void missingTypeInMethod(ASTNode astNode, MethodBinding method) {
+	int nameSourceStart, nameSourceEnd;
+	if (astNode instanceof MessageSend) {
+		MessageSend messageSend = astNode instanceof MessageSend ? (MessageSend) (astNode) : null;
+		nameSourceStart = (int) (messageSend.nameSourcePosition >>> 32);
+		nameSourceEnd = (int) messageSend.nameSourcePosition;
+	} else {
+		nameSourceStart = astNode.sourceStart;
+		nameSourceEnd = astNode.sourceEnd;
+	}
+	List missingTypes = method.collectMissingTypes(null);
+	if (missingTypes == null) {
+		System.err.println("The method " + method + " is wrongly tagged as containing missing types"); //$NON-NLS-1$ //$NON-NLS-2$
+		return;
+	}
+	TypeBinding missingType = (TypeBinding) missingTypes.get(0);
+	this.handle(
+			IProblem.MissingTypeInMethod,
+			new String[] {
+			        new String(method.declaringClass.readableName()),
+			        new String(method.selector),
+			        typesAsString(method, false),
+			       	new String(missingType.readableName()),
+			},
+			new String[] {
+			        new String(method.declaringClass.shortReadableName()),
+			        new String(method.selector),
+			        typesAsString(method, true),
+			       	new String(missingType.shortReadableName()),
+			},
+			nameSourceStart,
+			nameSourceEnd);
+}
+public void missingValueForAnnotationMember(Annotation annotation, char[] memberName) {
+	String memberString = new String(memberName);
+	this.handle(
+		IProblem.MissingValueForAnnotationMember,
+		new String[] {new String(annotation.resolvedType.readableName()), memberString },
+		new String[] {new String(annotation.resolvedType.shortReadableName()), memberString},
+		annotation.sourceStart,
+		annotation.sourceEnd);
+}
+public void mustDefineDimensionsOrInitializer(ArrayAllocationExpression expression) {
+	this.handle(
+		IProblem.MustDefineEitherDimensionExpressionsOrInitializer,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void mustUseAStaticMethod(MessageSend messageSend, MethodBinding method) {
+	this.handle(
+		IProblem.StaticMethodRequested,
+		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+		new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+		messageSend.sourceStart,
+		messageSend.sourceEnd);
+}
+public void nativeMethodsCannotBeStrictfp(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)};
+	this.handle(
+		IProblem.NativeMethodsCannotBeStrictfp,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void needImplementation(ASTNode location) {
+	this.abortDueToInternalError(Messages.abort_missingCode, location);
+}
+
+public void needToEmulateFieldAccess(FieldBinding field, ASTNode location, boolean isReadAccess) {
+	int id = isReadAccess
+			? IProblem.NeedToEmulateFieldReadAccess
+			: IProblem.NeedToEmulateFieldWriteAccess;
+	int severity = computeSeverity(id);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		id,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		severity,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void needToEmulateMethodAccess(
+	MethodBinding method,
+	ASTNode location) {
+
+	if (method.isConstructor()) {
+		int severity = computeSeverity(IProblem.NeedToEmulateConstructorAccess);
+		if (severity == ProblemSeverities.Ignore) return;
+		if (method.declaringClass.isEnum())
+			return; // tolerate emulation for enum constructors, which can only be made private
+		this.handle(
+			IProblem.NeedToEmulateConstructorAccess,
+			new String[] {
+				new String(method.declaringClass.readableName()),
+				typesAsString(method, false)
+			 },
+			new String[] {
+				new String(method.declaringClass.shortReadableName()),
+				typesAsString(method, true)
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+		return;
+	}
+	int severity = computeSeverity(IProblem.NeedToEmulateMethodAccess);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.NeedToEmulateMethodAccess,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(method.selector),
+			typesAsString(method, false)
+		 },
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(method.selector),
+			typesAsString(method, true)
+		 },
+		 severity,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void noAdditionalBoundAfterTypeVariable(TypeReference boundReference) {
+	this.handle(
+		IProblem.NoAdditionalBoundAfterTypeVariable,
+		new String[] { new String(boundReference.resolvedType.readableName()) },
+		new String[] { new String(boundReference.resolvedType.shortReadableName()) },
+		boundReference.sourceStart,
+		boundReference.sourceEnd);
+}
+private int nodeSourceEnd(Binding field, ASTNode node) {
+	return nodeSourceEnd(field, node, 0);
+}
+private int nodeSourceEnd(Binding field, ASTNode node, int index) {
+	if (node instanceof ArrayTypeReference) {
+		return ((ArrayTypeReference) node).originalSourceEnd;
+	} else if (node instanceof QualifiedNameReference) {
+		QualifiedNameReference ref = (QualifiedNameReference) node;
+		if (ref.binding == field) {
+			if (index == 0) {
+				return (int) (ref.sourcePositions[ref.indexOfFirstFieldBinding-1]);
+			} else {
+				int length = ref.sourcePositions.length;
+				if (index < length) {
+					return (int) (ref.sourcePositions[index]);
+				}
+				return (int) (ref.sourcePositions[0]);
+			}
+		}
+		FieldBinding[] otherFields = ref.otherBindings;
+		if (otherFields != null) {
+			int offset = ref.indexOfFirstFieldBinding;
+			if (index != 0) {
+				for (int i = 0, length = otherFields.length; i < length; i++) {
+					if ((otherFields[i] == field) && (i + offset == index)) {
+						return (int) (ref.sourcePositions[i + offset]);
+					}
+				}
+			} else {
+				for (int i = 0, length = otherFields.length; i < length; i++) {
+					if (otherFields[i] == field)
+						return (int) (ref.sourcePositions[i + offset]);
+				}
+			}
+		}
+	} else if (node instanceof ParameterizedQualifiedTypeReference) {
+		ParameterizedQualifiedTypeReference reference = (ParameterizedQualifiedTypeReference) node;
+		if (index < reference.sourcePositions.length) {
+			return (int) reference.sourcePositions[index];
+		}
+	} else if (node instanceof ArrayQualifiedTypeReference) {
+		ArrayQualifiedTypeReference reference = (ArrayQualifiedTypeReference) node;
+		int length = reference.sourcePositions.length;
+		if (index < length) {
+			return (int) reference.sourcePositions[index];
+		}
+		return (int) reference.sourcePositions[length - 1];
+	} else if (node instanceof QualifiedTypeReference) {
+		QualifiedTypeReference reference = (QualifiedTypeReference) node;
+		int length = reference.sourcePositions.length;
+		if (index < length) {
+			return (int) reference.sourcePositions[index];
+		}
+	}
+	return node.sourceEnd;
+}
+private int nodeSourceStart(Binding field, ASTNode node) {
+	return nodeSourceStart(field, node, 0);
+}
+private int nodeSourceStart(Binding field, ASTNode node, int index) {
+	if (node instanceof FieldReference) {
+		FieldReference fieldReference = (FieldReference) node;
+		return (int) (fieldReference.nameSourcePosition >> 32);
+	} else 	if (node instanceof QualifiedNameReference) {
+		QualifiedNameReference ref = (QualifiedNameReference) node;
+		if (ref.binding == field) {
+			if (index == 0) {
+				return (int) (ref.sourcePositions[ref.indexOfFirstFieldBinding-1] >> 32);
+			} else {
+				return (int) (ref.sourcePositions[index] >> 32);
+			}
+		}
+		FieldBinding[] otherFields = ref.otherBindings;
+		if (otherFields != null) {
+			int offset = ref.indexOfFirstFieldBinding;
+			if (index != 0) {
+				for (int i = 0, length = otherFields.length; i < length; i++) {
+					if ((otherFields[i] == field) && (i + offset == index)) {
+						return (int) (ref.sourcePositions[i + offset] >> 32);
+					}
+				}
+			} else {
+				for (int i = 0, length = otherFields.length; i < length; i++) {
+					if (otherFields[i] == field) {
+						return (int) (ref.sourcePositions[i + offset] >> 32);
+					}
+				}
+			}
+		}
+	} else if (node instanceof ParameterizedQualifiedTypeReference) {
+		ParameterizedQualifiedTypeReference reference = (ParameterizedQualifiedTypeReference) node;
+		return (int) (reference.sourcePositions[0]>>>32);
+	}
+	return node.sourceStart;
+}
+public void noMoreAvailableSpaceForArgument(LocalVariableBinding local, ASTNode location) {
+	String[] arguments = new String[]{ new String(local.name) };
+	this.handle(
+		local instanceof SyntheticArgumentBinding
+			? IProblem.TooManySyntheticArgumentSlots
+			: IProblem.TooManyArgumentSlots,
+		arguments,
+		arguments,
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void noMoreAvailableSpaceForConstant(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.TooManyBytesForStringConstant,
+		new String[]{ new String(typeDeclaration.binding.readableName())},
+		new String[]{ new String(typeDeclaration.binding.shortReadableName())},
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+
+public void noMoreAvailableSpaceForLocal(LocalVariableBinding local, ASTNode location) {
+	String[] arguments = new String[]{ new String(local.name) };
+	this.handle(
+		IProblem.TooManyLocalVariableSlots,
+		arguments,
+		arguments,
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location));
+}
+public void noMoreAvailableSpaceInConstantPool(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.TooManyConstantsInConstantPool,
+		new String[]{ new String(typeDeclaration.binding.readableName())},
+		new String[]{ new String(typeDeclaration.binding.shortReadableName())},
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+
+public void nonExternalizedStringLiteral(ASTNode location) {
+	this.handle(
+		IProblem.NonExternalizedStringLiteral,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+
+public void nonGenericTypeCannotBeParameterized(int index, ASTNode location, TypeBinding type, TypeBinding[] argumentTypes) {
+	if (location == null) { // binary case
+	    this.handle(
+			IProblem.NonGenericType,
+			new String[] {new String(type.readableName()), typesAsString(argumentTypes, false)},
+			new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true)},
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+	    return;
+	}
+    this.handle(
+		IProblem.NonGenericType,
+		new String[] {new String(type.readableName()), typesAsString(argumentTypes, false)},
+		new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true)},
+		nodeSourceStart(null, location),
+		nodeSourceEnd(null, location, index));
+}
+public void nonStaticAccessToStaticField(ASTNode location, FieldBinding field) {
+	nonStaticAccessToStaticField(location, field, -1);
+}
+public void nonStaticAccessToStaticField(ASTNode location, FieldBinding field, int index) {
+	int severity = computeSeverity(IProblem.NonStaticAccessToStaticField);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.NonStaticAccessToStaticField,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		severity,
+		nodeSourceStart(field, location, index),
+		nodeSourceEnd(field, location, index));
+}
+public void nonStaticAccessToStaticMethod(ASTNode location, MethodBinding method) {
+	this.handle(
+		IProblem.NonStaticAccessToStaticMethod,
+		new String[] {new String(method.declaringClass.readableName()), new String(method.selector), typesAsString(method, false)},
+		new String[] {new String(method.declaringClass.shortReadableName()), new String(method.selector), typesAsString(method, true)},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void nonStaticContextForEnumMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.NonStaticContextForEnumMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void noSuchEnclosingInstance(TypeBinding targetType, ASTNode location, boolean isConstructorCall) {
+
+	int id;
+
+	if (isConstructorCall) {
+		//28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation
+		id = IProblem.EnclosingInstanceInConstructorCall;
+	} else if ((location instanceof ExplicitConstructorCall)
+				&& ((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper) {
+		//20 = No enclosing instance of type {0} is accessible to invoke the super constructor. Must define a constructor and explicitly qualify its super constructor invocation with an instance of {0} (e.g. x.super() where x is an instance of {0}).
+		id = IProblem.MissingEnclosingInstanceForConstructorCall;
+	} else if (location instanceof AllocationExpression
+				&& (((AllocationExpression) location).binding.declaringClass.isMemberType()
+					|| (((AllocationExpression) location).binding.declaringClass.isAnonymousType()
+						&& ((AllocationExpression) location).binding.declaringClass.superclass().isMemberType()))) {
+		//21 = No enclosing instance of type {0} is accessible. Must qualify the allocation with an enclosing instance of type {0} (e.g. x.new A() where x is an instance of {0}).
+		id = IProblem.MissingEnclosingInstance;
+	} else { // default
+		//22 = No enclosing instance of the type {0} is accessible in scope
+		id = IProblem.IncorrectEnclosingInstanceReference;
+	}
+
+	this.handle(
+		id,
+		new String[] { new String(targetType.readableName())},
+		new String[] { new String(targetType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void notCompatibleTypesError(EqualExpression expression, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.IncompatibleTypesInEqualityOperator,
+		new String[] {leftName, rightName },
+		new String[] {leftShortName, rightShortName },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void notCompatibleTypesError(InstanceOfExpression expression, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.IncompatibleTypesInConditionalOperator,
+		new String[] {leftName, rightName },
+		new String[] {leftShortName, rightShortName },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void notCompatibleTypesErrorInForeach(Expression expression, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.IncompatibleTypesInForeach,
+		new String[] {leftName, rightName },
+		new String[] {leftShortName, rightShortName },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void objectCannotBeGeneric(TypeDeclaration typeDecl) {
+	this.handle(
+		IProblem.ObjectCannotBeGeneric,
+		NoArgument,
+		NoArgument,
+		typeDecl.typeParameters[0].sourceStart,
+		typeDecl.typeParameters[typeDecl.typeParameters.length-1].sourceEnd);
+}
+public void objectCannotHaveSuperTypes(SourceTypeBinding type) {
+	this.handle(
+		IProblem.ObjectCannotHaveSuperTypes,
+		NoArgument,
+		NoArgument,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void objectMustBeClass(SourceTypeBinding type) {
+	this.handle(
+		IProblem.ObjectMustBeClass,
+		NoArgument,
+		NoArgument,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void operatorOnlyValidOnNumericType(CompoundAssignment  assignment, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.TypeMismatch,
+		new String[] {leftName, rightName },
+		new String[] {leftShortName, rightShortName },
+		assignment.sourceStart,
+		assignment.sourceEnd);
+}
+public void overridesDeprecatedMethod(MethodBinding localMethod, MethodBinding inheritedMethod) {
+	this.handle(
+		IProblem.OverridingDeprecatedMethod,
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.readableName(),
+						localMethod.readableName(),
+						'.')),
+			new String(inheritedMethod.declaringClass.readableName())},
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.shortReadableName(),
+						localMethod.shortReadableName(),
+						'.')),
+			new String(inheritedMethod.declaringClass.shortReadableName())},
+		localMethod.sourceStart(),
+		localMethod.sourceEnd());
+}
+public void overridesMethodWithoutSuperInvocation(MethodBinding localMethod) {
+	this.handle(
+		IProblem.OverridingMethodWithoutSuperInvocation,
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.readableName(),
+						localMethod.readableName(),
+						'.'))
+			},
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.shortReadableName(),
+						localMethod.shortReadableName(),
+						'.'))
+			},
+		localMethod.sourceStart(),
+		localMethod.sourceEnd());
+}
+public void overridesPackageDefaultMethod(MethodBinding localMethod, MethodBinding inheritedMethod) {
+	this.handle(
+		IProblem.OverridingNonVisibleMethod,
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.readableName(),
+						localMethod.readableName(),
+						'.')),
+			new String(inheritedMethod.declaringClass.readableName())},
+		new String[] {
+			new String(
+					CharOperation.concat(
+						localMethod.declaringClass.shortReadableName(),
+						localMethod.shortReadableName(),
+						'.')),
+			new String(inheritedMethod.declaringClass.shortReadableName())},
+		localMethod.sourceStart(),
+		localMethod.sourceEnd());
+}
+public void packageCollidesWithType(CompilationUnitDeclaration compUnitDecl) {
+	String[] arguments = new String[] {CharOperation.toString(compUnitDecl.currentPackage.tokens)};
+	this.handle(
+		IProblem.PackageCollidesWithType,
+		arguments,
+		arguments,
+		compUnitDecl.currentPackage.sourceStart,
+		compUnitDecl.currentPackage.sourceEnd);
+}
+public void packageIsNotExpectedPackage(CompilationUnitDeclaration compUnitDecl) {
+	boolean hasPackageDeclaration = compUnitDecl.currentPackage == null;
+	String[] arguments = new String[] {
+		CharOperation.toString(compUnitDecl.compilationResult.compilationUnit.getPackageName()),
+		hasPackageDeclaration ? "" : CharOperation.toString(compUnitDecl.currentPackage.tokens), //$NON-NLS-1$
+	};
+	int end;
+	if (compUnitDecl.sourceEnd <= 0) {
+		end = -1;
+	} else {
+		end = hasPackageDeclaration ? 0 : compUnitDecl.currentPackage.sourceEnd;
+	}	
+	this.handle(
+		IProblem.PackageIsNotExpectedPackage,
+		arguments,
+		arguments,
+		hasPackageDeclaration ? 0 : compUnitDecl.currentPackage.sourceStart,
+		end);
+}
+public void parameterAssignment(LocalVariableBinding local, ASTNode location) {
+	int severity = computeSeverity(IProblem.ParameterAssignment);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] { new String(local.readableName())};
+	this.handle(
+		IProblem.ParameterAssignment,
+		arguments,
+		arguments,
+		severity,
+		nodeSourceStart(local, location),
+		nodeSourceEnd(local, location)); // should never be a qualified name reference
+}
+private String parameterBoundAsString(TypeVariableBinding typeVariable, boolean makeShort) {
+    StringBuffer nameBuffer = new StringBuffer(10);
+    if (typeVariable.firstBound == typeVariable.superclass) {
+        nameBuffer.append(makeShort ? typeVariable.superclass.shortReadableName() : typeVariable.superclass.readableName());
+    }
+    int length;
+    if ((length = typeVariable.superInterfaces.length) > 0) {
+	    for (int i = 0; i < length; i++) {
+	        if (i > 0 || typeVariable.firstBound == typeVariable.superclass) nameBuffer.append(" & "); //$NON-NLS-1$
+	        nameBuffer.append(makeShort ? typeVariable.superInterfaces[i].shortReadableName() : typeVariable.superInterfaces[i].readableName());
+	    }
+	}
+	return nameBuffer.toString();
+}
+public void parameterizedMemberTypeMissingArguments(ASTNode location, TypeBinding type, int index) {
+	if (location == null) { // binary case
+	    this.handle(
+			IProblem.MissingArgumentsForParameterizedMemberType,
+			new String[] {new String(type.readableName())},
+			new String[] {new String(type.shortReadableName())},
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+	    return;
+	}
+    this.handle(
+		IProblem.MissingArgumentsForParameterizedMemberType,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		nodeSourceEnd(null, location, index));
+}
+public void parseError(
+	int startPosition,
+	int endPosition,
+	int currentToken,
+	char[] currentTokenSource,
+	String errorTokenName,
+	String[] possibleTokens) {
+
+	if (possibleTokens.length == 0) { //no suggestion available
+		if (isKeyword(currentToken)) {
+			String[] arguments = new String[] {new String(currentTokenSource)};
+			this.handle(
+				IProblem.ParsingErrorOnKeywordNoSuggestion,
+				arguments,
+				arguments,
+				// this is the current -invalid- token position
+				startPosition,
+				endPosition);
+			return;
+		} else {
+			String[] arguments = new String[] {errorTokenName};
+			this.handle(
+				IProblem.ParsingErrorNoSuggestion,
+				arguments,
+				arguments,
+				// this is the current -invalid- token position
+				startPosition,
+				endPosition);
+			return;
+		}
+	}
+
+	//build a list of probable right tokens
+	StringBuffer list = new StringBuffer(20);
+	for (int i = 0, max = possibleTokens.length; i < max; i++) {
+		if (i > 0)
+			list.append(", "); //$NON-NLS-1$
+		list.append('"');
+		list.append(possibleTokens[i]);
+		list.append('"');
+	}
+
+	if (isKeyword(currentToken)) {
+		String[] arguments = new String[] {new String(currentTokenSource), list.toString()};
+		this.handle(
+			IProblem.ParsingErrorOnKeyword,
+			arguments,
+			arguments,
+			// this is the current -invalid- token position
+			startPosition,
+			endPosition);
+		return;
+	}
+	//extract the literal when it's a literal
+	if (isLiteral(currentToken) ||
+		isIdentifier(currentToken)) {
+			errorTokenName = new String(currentTokenSource);
+	}
+
+	String[] arguments = new String[] {errorTokenName, list.toString()};
+	this.handle(
+		IProblem.ParsingError,
+		arguments,
+		arguments,
+		// this is the current -invalid- token position
+		startPosition,
+		endPosition);
+}
+public void parseErrorDeleteToken(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName){
+	syntaxError(
+		IProblem.ParsingErrorDeleteToken,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		null);
+}
+
+public void parseErrorDeleteTokens(
+	int start,
+	int end){
+	this.handle(
+		IProblem.ParsingErrorDeleteTokens,
+		NoArgument,
+		NoArgument,
+		start,
+		end);
+}
+public void parseErrorInsertAfterToken(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName,
+	String expectedToken){
+	syntaxError(
+		IProblem.ParsingErrorInsertTokenAfter,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		expectedToken);
+}
+public void parseErrorInsertBeforeToken(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName,
+	String expectedToken){
+	syntaxError(
+		IProblem.ParsingErrorInsertTokenBefore,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		expectedToken);
+}
+public void parseErrorInsertToComplete(
+	int start,
+	int end,
+	String inserted,
+	String completed){
+	String[] arguments = new String[] {inserted, completed};
+	this.handle(
+		IProblem.ParsingErrorInsertToComplete,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+
+public void parseErrorInsertToCompletePhrase(
+	int start,
+	int end,
+	String inserted){
+	String[] arguments = new String[] {inserted};
+	this.handle(
+		IProblem.ParsingErrorInsertToCompletePhrase,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+public void parseErrorInsertToCompleteScope(
+	int start,
+	int end,
+	String inserted){
+	String[] arguments = new String[] {inserted};
+	this.handle(
+		IProblem.ParsingErrorInsertToCompleteScope,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+public void parseErrorInvalidToken(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName,
+	String expectedToken){
+	syntaxError(
+		IProblem.ParsingErrorInvalidToken,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		expectedToken);
+}
+public void parseErrorMergeTokens(
+	int start,
+	int end,
+	String expectedToken){
+	String[] arguments = new String[] {expectedToken};
+	this.handle(
+		IProblem.ParsingErrorMergeTokens,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+public void parseErrorMisplacedConstruct(
+	int start,
+	int end){
+	this.handle(
+		IProblem.ParsingErrorMisplacedConstruct,
+		NoArgument,
+		NoArgument,
+		start,
+		end);
+}
+public void parseErrorNoSuggestion(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName){
+	syntaxError(
+		IProblem.ParsingErrorNoSuggestion,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		null);
+}
+public void parseErrorNoSuggestionForTokens(
+	int start,
+	int end){
+	this.handle(
+		IProblem.ParsingErrorNoSuggestionForTokens,
+		NoArgument,
+		NoArgument,
+		start,
+		end);
+}
+public void parseErrorReplaceToken(
+	int start,
+	int end,
+	int currentKind,
+	char[] errorTokenSource,
+	String errorTokenName,
+	String expectedToken){
+	syntaxError(
+		IProblem.ParsingError,
+		start,
+		end,
+		currentKind,
+		errorTokenSource,
+		errorTokenName,
+		expectedToken);
+}
+public void parseErrorReplaceTokens(
+	int start,
+	int end,
+	String expectedToken){
+	String[] arguments = new String[] {expectedToken};
+	this.handle(
+		IProblem.ParsingErrorReplaceTokens,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+public void parseErrorUnexpectedEnd(
+	int start,
+	int end){
+
+	String[] arguments;
+	if(this.referenceContext instanceof ConstructorDeclaration) {
+		arguments = new String[] {Messages.parser_endOfConstructor};
+	} else if(this.referenceContext instanceof MethodDeclaration) {
+		arguments = new String[] {Messages.parser_endOfMethod};
+	} else if(this.referenceContext instanceof TypeDeclaration) {
+		arguments = new String[] {Messages.parser_endOfInitializer};
+	} else {
+		arguments = new String[] {Messages.parser_endOfFile};
+	}
+	this.handle(
+		IProblem.ParsingErrorUnexpectedEOF,
+		arguments,
+		arguments,
+		start,
+		end);
+}
+public void possibleAccidentalBooleanAssignment(Assignment assignment) {
+	this.handle(
+		IProblem.PossibleAccidentalBooleanAssignment,
+		NoArgument,
+		NoArgument,
+		assignment.sourceStart,
+		assignment.sourceEnd);
+}
+public void possibleFallThroughCase(CaseStatement caseStatement) {
+	// as long as we consider fake reachable as reachable, better keep 'possible' in the name
+	this.handle(
+		IProblem.FallthroughCase,
+		NoArgument,
+		NoArgument,
+		caseStatement.sourceStart,
+		caseStatement.sourceEnd);
+}
+public void publicClassMustMatchFileName(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
+	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
+	String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)};
+	this.handle(
+		IProblem.PublicClassMustMatchFileName,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd,
+		compUnitDecl.compilationResult);
+}
+public void rawMemberTypeCannotBeParameterized(ASTNode location, ReferenceBinding type, TypeBinding[] argumentTypes) {
+	if (location == null) { // binary case
+	    this.handle(
+			IProblem.RawMemberTypeCannotBeParameterized,
+			new String[] {new String(type.readableName()), typesAsString(argumentTypes, false), new String(type.enclosingType().readableName())},
+			new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true), new String(type.enclosingType().shortReadableName())},
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+	    return;
+	}
+    this.handle(
+		IProblem.RawMemberTypeCannotBeParameterized,
+		new String[] {new String(type.readableName()), typesAsString(argumentTypes, false), new String(type.enclosingType().readableName())},
+		new String[] {new String(type.shortReadableName()), typesAsString(argumentTypes, true), new String(type.enclosingType().shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void rawTypeReference(ASTNode location, TypeBinding type) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	type = type.leafComponentType();
+    this.handle(
+		IProblem.RawTypeReference,
+		new String[] {new String(type.readableName()), new String(type.erasure().readableName()), },
+		new String[] {new String(type.shortReadableName()),new String(type.erasure().shortReadableName()),},
+		location.sourceStart,
+		nodeSourceEnd(null, location, Integer.MAX_VALUE));
+}
+public void recursiveConstructorInvocation(ExplicitConstructorCall constructorCall) {
+	this.handle(
+		IProblem.RecursiveConstructorInvocation,
+		new String[] {
+			new String(constructorCall.binding.declaringClass.readableName()),
+			typesAsString(constructorCall.binding, false)
+		},
+		new String[] {
+			new String(constructorCall.binding.declaringClass.shortReadableName()),
+			typesAsString(constructorCall.binding, true)
+		},
+		constructorCall.sourceStart,
+		constructorCall.sourceEnd);
+}
+public void redefineArgument(Argument arg) {
+	String[] arguments = new String[] {new String(arg.name)};
+	this.handle(
+		IProblem.RedefinedArgument,
+		arguments,
+		arguments,
+		arg.sourceStart,
+		arg.sourceEnd);
+}
+public void redefineLocal(LocalDeclaration localDecl) {
+	String[] arguments = new String[] {new String(localDecl.name)};
+	this.handle(
+		IProblem.RedefinedLocal,
+		arguments,
+		arguments,
+		localDecl.sourceStart,
+		localDecl.sourceEnd);
+}
+public void redundantSuperInterface(SourceTypeBinding type, TypeReference reference, ReferenceBinding superinterface, ReferenceBinding declaringType) {
+	int severity = computeSeverity(IProblem.RedundantSuperinterface);
+	if (severity != ProblemSeverities.Ignore) {
+		this.handle(
+			IProblem.RedundantSuperinterface,
+			new String[] {
+				new String(superinterface.readableName()),
+				new String(type.readableName()),
+				new String(declaringType.readableName())},
+			new String[] {
+				new String(superinterface.shortReadableName()),
+				new String(type.shortReadableName()),
+				new String(declaringType.shortReadableName())},
+			severity,
+			reference.sourceStart,
+			reference.sourceEnd);
+	}
+}
+public void referenceMustBeArrayTypeAt(TypeBinding arrayType, ArrayReference arrayRef) {
+	this.handle(
+		IProblem.ArrayReferenceRequired,
+		new String[] {new String(arrayType.readableName())},
+		new String[] {new String(arrayType.shortReadableName())},
+		arrayRef.sourceStart,
+		arrayRef.sourceEnd);
+}
+public void reset() {
+	this.positionScanner = null;
+}
+public void resourceHasToImplementAutoCloseable(TypeBinding binding, TypeReference typeReference) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+		return; // Not supported in 1.7 would have been reported. Hence another not required
+	}
+	this.handle(
+			IProblem.ResourceHasToImplementAutoCloseable,
+			new String[] {new String(binding.readableName())},
+			new String[] {new String(binding.shortReadableName())},
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+}
+private int retrieveClosingAngleBracketPosition(int start) {
+	if (this.referenceContext == null) return start;
+	CompilationResult compilationResult = this.referenceContext.compilationResult();
+	if (compilationResult == null) return start;
+	ICompilationUnit compilationUnit = compilationResult.getCompilationUnit();
+	if (compilationUnit == null) return start;
+	char[] contents = compilationUnit.getContents();
+	if (contents.length == 0) return start;
+	if (this.positionScanner == null) {
+		this.positionScanner = new Scanner(false, false, false, this.options.sourceLevel, this.options.complianceLevel, null, null, false);
+		this.positionScanner.returnOnlyGreater = true;
+	}
+	this.positionScanner.setSource(contents);
+	this.positionScanner.resetTo(start, contents.length);
+	int end = start;
+	int count = 0;
+	try {
+		int token;
+		loop: while ((token = this.positionScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+			switch(token) {
+				case TerminalTokens.TokenNameLESS:
+					count++;
+					break;
+				case TerminalTokens.TokenNameGREATER:
+					count--;
+					if (count == 0) {
+						end = this.positionScanner.currentPosition - 1;
+						break loop;
+					}
+					break;
+				case TerminalTokens.TokenNameLBRACE :
+					break loop;
+			}
+		}
+	} catch(InvalidInputException e) {
+		// ignore
+	}
+	return end;
+}
+private int retrieveEndingPositionAfterOpeningParenthesis(int sourceStart, int sourceEnd, int numberOfParen) {
+	if (this.referenceContext == null) return sourceEnd;
+	CompilationResult compilationResult = this.referenceContext.compilationResult();
+	if (compilationResult == null) return sourceEnd;
+	ICompilationUnit compilationUnit = compilationResult.getCompilationUnit();
+	if (compilationUnit == null) return sourceEnd;
+	char[] contents = compilationUnit.getContents();
+	if (contents.length == 0) return sourceEnd;
+	if (this.positionScanner == null) {
+		this.positionScanner = new Scanner(false, false, false, this.options.sourceLevel, this.options.complianceLevel, null, null, false);
+	}
+	this.positionScanner.setSource(contents);
+	this.positionScanner.resetTo(sourceStart, sourceEnd);
+	try {
+		int token;
+		int previousSourceEnd = sourceEnd;
+		while ((token = this.positionScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+			switch(token) {
+				case TerminalTokens.TokenNameRPAREN:
+					return previousSourceEnd;
+				default :
+					previousSourceEnd = this.positionScanner.currentPosition - 1;
+			}
+		}
+	} catch(InvalidInputException e) {
+		// ignore
+	}
+	return sourceEnd;
+}
+private int retrieveStartingPositionAfterOpeningParenthesis(int sourceStart, int sourceEnd, int numberOfParen) {
+	if (this.referenceContext == null) return sourceStart;
+	CompilationResult compilationResult = this.referenceContext.compilationResult();
+	if (compilationResult == null) return sourceStart;
+	ICompilationUnit compilationUnit = compilationResult.getCompilationUnit();
+	if (compilationUnit == null) return sourceStart;
+	char[] contents = compilationUnit.getContents();
+	if (contents.length == 0) return sourceStart;
+	if (this.positionScanner == null) {
+		this.positionScanner = new Scanner(false, false, false, this.options.sourceLevel, this.options.complianceLevel, null, null, false);
+	}
+	this.positionScanner.setSource(contents);
+	this.positionScanner.resetTo(sourceStart, sourceEnd);
+	int count = 0;
+	try {
+		int token;
+		while ((token = this.positionScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+			switch(token) {
+				case TerminalTokens.TokenNameLPAREN:
+					count++;
+					if (count == numberOfParen) {
+						this.positionScanner.getNextToken();
+						return this.positionScanner.startPosition;
+					}
+			}
+		}
+	} catch(InvalidInputException e) {
+		// ignore
+	}
+	return sourceStart;
+}
+public void scannerError(Parser parser, String errorTokenName) {
+	Scanner scanner = parser.scanner;
+
+	int flag = IProblem.ParsingErrorNoSuggestion;
+	int startPos = scanner.startPosition;
+	int endPos = scanner.currentPosition - 1;
+
+	//special treatment for recognized errors....
+	if (errorTokenName.equals(Scanner.END_OF_SOURCE))
+		flag = IProblem.EndOfSource;
+	else if (errorTokenName.equals(Scanner.INVALID_HEXA))
+		flag = IProblem.InvalidHexa;
+	else if (errorTokenName.equals(Scanner.ILLEGAL_HEXA_LITERAL))
+		flag = IProblem.IllegalHexaLiteral;
+	else if (errorTokenName.equals(Scanner.INVALID_OCTAL))
+		flag = IProblem.InvalidOctal;
+	else if (errorTokenName.equals(Scanner.INVALID_CHARACTER_CONSTANT))
+		flag = IProblem.InvalidCharacterConstant;
+	else if (errorTokenName.equals(Scanner.INVALID_ESCAPE))
+		flag = IProblem.InvalidEscape;
+	else if (errorTokenName.equals(Scanner.INVALID_UNICODE_ESCAPE)){
+		flag = IProblem.InvalidUnicodeEscape;
+		// better locate the error message
+		char[] source = scanner.source;
+		int checkPos = scanner.currentPosition - 1;
+		if (checkPos >= source.length) checkPos = source.length - 1;
+		while (checkPos >= startPos){
+			if (source[checkPos] == '\\') break;
+			checkPos --;
+		}
+		startPos = checkPos;
+	} else if (errorTokenName.equals(Scanner.INVALID_LOW_SURROGATE)) {
+		flag = IProblem.InvalidLowSurrogate;
+	} else if (errorTokenName.equals(Scanner.INVALID_HIGH_SURROGATE)) {
+		flag = IProblem.InvalidHighSurrogate;
+		// better locate the error message
+		char[] source = scanner.source;
+		int checkPos = scanner.startPosition + 1;
+		while (checkPos <= endPos){
+			if (source[checkPos] == '\\') break;
+			checkPos ++;
+		}
+		endPos = checkPos - 1;
+	} else if (errorTokenName.equals(Scanner.INVALID_FLOAT))
+		flag = IProblem.InvalidFloat;
+	else if (errorTokenName.equals(Scanner.UNTERMINATED_STRING))
+		flag = IProblem.UnterminatedString;
+	else if (errorTokenName.equals(Scanner.UNTERMINATED_COMMENT))
+		flag = IProblem.UnterminatedComment;
+	else if (errorTokenName.equals(Scanner.INVALID_CHAR_IN_STRING))
+		flag = IProblem.UnterminatedString;
+	else if (errorTokenName.equals(Scanner.INVALID_DIGIT))
+		flag = IProblem.InvalidDigit;
+	else if (errorTokenName.equals(Scanner.INVALID_BINARY))
+		flag = IProblem.InvalidBinary;
+	else if (errorTokenName.equals(Scanner.BINARY_LITERAL_NOT_BELOW_17))
+		flag = IProblem.BinaryLiteralNotBelow17;
+	else if (errorTokenName.equals(Scanner.INVALID_UNDERSCORE))
+		flag = IProblem.IllegalUnderscorePosition;
+	else if (errorTokenName.equals(Scanner.UNDERSCORES_IN_LITERALS_NOT_BELOW_17))
+		flag = IProblem.UnderscoresInLiteralsNotBelow17;
+
+	String[] arguments = flag == IProblem.ParsingErrorNoSuggestion
+			? new String[] {errorTokenName}
+			: NoArgument;
+	this.handle(
+		flag,
+		arguments,
+		arguments,
+		// this is the current -invalid- token position
+		startPos,
+		endPos,
+		parser.compilationUnit.compilationResult);
+}
+public void shouldImplementHashcode(SourceTypeBinding type) {	
+	this.handle(
+		IProblem.ShouldImplementHashcode,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void shouldReturn(TypeBinding returnType, ASTNode location) {
+	this.handle(
+		methodHasMissingSwitchDefault() ? IProblem.ShouldReturnValueHintMissingDefault : IProblem.ShouldReturnValue,
+		new String[] { new String (returnType.readableName())},
+		new String[] { new String (returnType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+
+public void signalNoImplicitStringConversionForCharArrayExpression(Expression expression) {
+	this.handle(
+		IProblem.NoImplicitStringConversionForCharArrayExpression,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	if (currentMethod.isStatic())
+		this.handle(
+			// This static method cannot hide the instance method from %1
+			// 8.4.6.4 - If a class inherits more than one method with the same signature a static (non-abstract) method cannot hide an instance method.
+			IProblem.CannotHideAnInstanceMethodWithAStaticMethod,
+			new String[] {new String(inheritedMethod.declaringClass.readableName())},
+			new String[] {new String(inheritedMethod.declaringClass.shortReadableName())},
+			currentMethod.sourceStart(),
+			currentMethod.sourceEnd());
+	else
+		this.handle(
+			// This instance method cannot override the static method from %1
+			// 8.4.6.4 - If a class inherits more than one method with the same signature an instance (non-abstract) method cannot override a static method.
+			IProblem.CannotOverrideAStaticMethodWithAnInstanceMethod,
+			new String[] {new String(inheritedMethod.declaringClass.readableName())},
+			new String[] {new String(inheritedMethod.declaringClass.shortReadableName())},
+			currentMethod.sourceStart(),
+			currentMethod.sourceEnd());
+}
+public void staticFieldAccessToNonStaticVariable(ASTNode location, FieldBinding field) {
+	String[] arguments = new String[] {new String(field.readableName())};
+	this.handle(
+		IProblem.NonStaticFieldFromStaticInvocation,
+		arguments,
+		arguments,
+		nodeSourceStart(field,location),
+		nodeSourceEnd(field, location));
+}
+public void staticInheritedMethodConflicts(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	this.handle(
+		// The static method %1 conflicts with the abstract method in %2
+		// 8.4.6.4 - If a class inherits more than one method with the same signature it is an error for one to be static (non-abstract) and the other abstract.
+		IProblem.StaticInheritedMethodConflicts,
+		new String[] {
+			new String(concreteMethod.readableName()),
+			new String(abstractMethods[0].declaringClass.readableName())},
+		new String[] {
+			new String(concreteMethod.readableName()),
+			new String(abstractMethods[0].declaringClass.shortReadableName())},
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void staticMemberOfParameterizedType(ASTNode location, ReferenceBinding type, int index) {
+	if (location == null) { // binary case
+	    this.handle(
+			IProblem.StaticMemberOfParameterizedType,
+			new String[] {new String(type.readableName()), new String(type.enclosingType().readableName()), },
+			new String[] {new String(type.shortReadableName()), new String(type.enclosingType().shortReadableName()), },
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+	    return;
+	}
+	/*if (location instanceof ArrayTypeReference) {
+		ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
+		if (arrayTypeReference.token != null && arrayTypeReference.token.length == 0) return;
+		end = arrayTypeReference.originalSourceEnd;
+	}*/
+    this.handle(
+		IProblem.StaticMemberOfParameterizedType,
+		new String[] {new String(type.readableName()), new String(type.enclosingType().readableName()), },
+		new String[] {new String(type.shortReadableName()), new String(type.enclosingType().shortReadableName()), },
+		location.sourceStart,
+		nodeSourceEnd(null, location, index));
+}
+public void stringConstantIsExceedingUtf8Limit(ASTNode location) {
+	this.handle(
+		IProblem.StringConstantIsExceedingUtf8Limit,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void superclassMustBeAClass(SourceTypeBinding type, TypeReference superclassRef, ReferenceBinding superType) {
+	this.handle(
+		IProblem.SuperclassMustBeAClass,
+		new String[] {new String(superType.readableName()), new String(type.sourceName())},
+		new String[] {new String(superType.shortReadableName()), new String(type.sourceName())},
+		superclassRef.sourceStart,
+		superclassRef.sourceEnd);
+}
+public void superfluousSemicolon(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.SuperfluousSemicolon,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void superinterfaceMustBeAnInterface(SourceTypeBinding type, TypeReference superInterfaceRef, ReferenceBinding superType) {
+	this.handle(
+		IProblem.SuperInterfaceMustBeAnInterface,
+		new String[] {new String(superType.readableName()), new String(type.sourceName())},
+		new String[] {new String(superType.shortReadableName()), new String(type.sourceName())},
+		superInterfaceRef.sourceStart,
+		superInterfaceRef.sourceEnd);
+}
+public void superinterfacesCollide(TypeBinding type, ASTNode decl, TypeBinding superType, TypeBinding inheritedSuperType) {
+	this.handle(
+		IProblem.SuperInterfacesCollide,
+		new String[] {new String(superType.readableName()), new String(inheritedSuperType.readableName()), new String(type.sourceName())},
+		new String[] {new String(superType.shortReadableName()), new String(inheritedSuperType.shortReadableName()), new String(type.sourceName())},
+		decl.sourceStart,
+		decl.sourceEnd);
+}
+public void superTypeCannotUseWildcard(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) {
+	String name = new String(type.sourceName());
+	String superTypeFullName = new String(superTypeBinding.readableName());
+	String superTypeShortName = new String(superTypeBinding.shortReadableName());
+	if (superTypeShortName.equals(name)) superTypeShortName = superTypeFullName;
+	this.handle(
+		IProblem.SuperTypeUsingWildcard,
+		new String[] {superTypeFullName, name},
+		new String[] {superTypeShortName, name},
+		superclass.sourceStart,
+		superclass.sourceEnd);
+}
+private void syntaxError(
+	int id,
+	int startPosition,
+	int endPosition,
+	int currentKind,
+	char[] currentTokenSource,
+	String errorTokenName,
+	String expectedToken) {
+
+	if (currentKind == TerminalTokens.TokenNameAT && expectedToken != null && expectedToken.equals("@")) { //$NON-NLS-1$
+		// In the diagnose parser case, we don't have the wherewithal to discriminate when we should hand out @308 vs @. So we always answer @.
+		// We should silently recover so swallow the message.
+		return;
+	}
+	String eTokenName;
+	if (isKeyword(currentKind) ||
+		isLiteral(currentKind) ||
+		isIdentifier(currentKind)) {
+			eTokenName = new String(currentTokenSource);
+	} else {
+		eTokenName = errorTokenName;
+	}
+
+	String[] arguments;
+	if(expectedToken != null) {
+		expectedToken = replaceIfSynthetic(expectedToken);
+		arguments = new String[] {eTokenName, expectedToken};
+	} else {
+		arguments = new String[] {eTokenName};
+	}
+	this.handle(
+		id,
+		arguments,
+		arguments,
+		startPosition,
+		endPosition);
+}
+private String replaceIfSynthetic(String token) {
+	/* Java 8 grammar changes use some synthetic tokens to make the grammar LALR(1). These tokens should not be exposed in messages
+	   as it would make no sense to the programmer whatsoever. Replace such artificial tokens with some "suitable"  alternative. At
+	   the moment, there are two synthetic tokens that need such massaging viz : "BeginLambda" and "BeginTypeArguments". There is a
+	   third synthetic token "ElidedSemicolonAndRightBrace" that we don't expect to show up in messages since it is manufactured by
+	   the parser automatically.
+	*/
+	if (token.equals("BeginTypeArguments")) //$NON-NLS-1$
+		return "."; //$NON-NLS-1$
+	if (token.equals("BeginLambda")) //$NON-NLS-1$
+		return "("; //$NON-NLS-1$
+	return token;
+}
+public void task(String tag, String message, String priority, int start, int end){
+	this.handle(
+		IProblem.Task,
+		new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/},
+		new String[] { tag, message, priority/*secret argument that is not surfaced in getMessage()*/},
+		start,
+		end);
+}
+
+public void tooManyDimensions(ASTNode expression) {
+	this.handle(
+		IProblem.TooManyArrayDimensions,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void tooManyFields(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.TooManyFields,
+		new String[]{ new String(typeDeclaration.binding.readableName())},
+		new String[]{ new String(typeDeclaration.binding.shortReadableName())},
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+public void tooManyMethods(TypeDeclaration typeDeclaration) {
+	this.handle(
+		IProblem.TooManyMethods,
+		new String[]{ new String(typeDeclaration.binding.readableName())},
+		new String[]{ new String(typeDeclaration.binding.shortReadableName())},
+		ProblemSeverities.Abort | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		typeDeclaration.sourceStart,
+		typeDeclaration.sourceEnd);
+}
+public void tooManyParametersForSyntheticMethod(AbstractMethodDeclaration method) {
+	MethodBinding binding = method.binding;
+	String selector = null;
+	if (binding.isConstructor()) {
+		selector = new String(binding.declaringClass.sourceName());
+	} else {
+		selector = new String(method.selector);
+	}
+	this.handle(
+		IProblem.TooManyParametersForSyntheticMethod,
+		new String[] {selector, typesAsString(binding, false), new String(binding.declaringClass.readableName()), },
+		new String[] {selector, typesAsString(binding, true), new String(binding.declaringClass.shortReadableName()),},
+		ProblemSeverities.AbortMethod | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		method.sourceStart,
+		method.sourceEnd);
+}
+public void typeCastError(CastExpression expression, TypeBinding leftType, TypeBinding rightType) {
+	String leftName = new String(leftType.readableName());
+	String rightName = new String(rightType.readableName());
+	String leftShortName = new String(leftType.shortReadableName());
+	String rightShortName = new String(rightType.shortReadableName());
+	if (leftShortName.equals(rightShortName)){
+		leftShortName = leftName;
+		rightShortName = rightName;
+	}
+	this.handle(
+		IProblem.IllegalCast,
+		new String[] { rightName, leftName },
+		new String[] { rightShortName, leftShortName },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void typeCollidesWithEnclosingType(TypeDeclaration typeDecl) {
+	String[] arguments = new String[] {new String(typeDecl.name)};
+	this.handle(
+		IProblem.HidingEnclosingType,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd);
+}
+public void typeCollidesWithPackage(CompilationUnitDeclaration compUnitDecl, TypeDeclaration typeDecl) {
+	this.referenceContext = typeDecl; // report the problem against the type not the entire compilation unit
+	String[] arguments = new String[] {new String(compUnitDecl.getFileName()), new String(typeDecl.name)};
+	this.handle(
+		IProblem.TypeCollidesWithPackage,
+		arguments,
+		arguments,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd,
+		compUnitDecl.compilationResult);
+}
+public void typeHiding(TypeDeclaration typeDecl, TypeBinding hiddenType) {
+	int severity = computeSeverity(IProblem.TypeHidingType);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.TypeHidingType,
+		new String[] { new String(typeDecl.name) , new String(hiddenType.shortReadableName()) },
+		new String[] { new String(typeDecl.name) , new String(hiddenType.readableName()) },
+		severity,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd);
+}
+public void typeHiding(TypeDeclaration typeDecl, TypeVariableBinding hiddenTypeParameter) {
+	int severity = computeSeverity(IProblem.TypeHidingTypeParameterFromType);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (hiddenTypeParameter.declaringElement instanceof TypeBinding) {
+		TypeBinding declaringType = (TypeBinding) hiddenTypeParameter.declaringElement;
+		this.handle(
+			IProblem.TypeHidingTypeParameterFromType,
+			new String[] { new String(typeDecl.name) , new String(hiddenTypeParameter.readableName()), new String(declaringType.readableName())  },
+			new String[] { new String(typeDecl.name) , new String(hiddenTypeParameter.shortReadableName()), new String(declaringType.shortReadableName()) },
+			severity,
+			typeDecl.sourceStart,
+			typeDecl.sourceEnd);
+	} else {
+		// type parameter of generic method
+		MethodBinding declaringMethod = (MethodBinding) hiddenTypeParameter.declaringElement;
+		this.handle(
+				IProblem.TypeHidingTypeParameterFromMethod,
+				new String[] {
+						new String(typeDecl.name),
+						new String(hiddenTypeParameter.readableName()),
+						new String(declaringMethod.selector),
+						typesAsString(declaringMethod, false),
+						new String(declaringMethod.declaringClass.readableName()),
+				},
+				new String[] {
+						new String(typeDecl.name),
+						new String(hiddenTypeParameter.shortReadableName()),
+						new String(declaringMethod.selector),
+						typesAsString(declaringMethod, true),
+						new String(declaringMethod.declaringClass.shortReadableName()),
+				},
+				severity,
+				typeDecl.sourceStart,
+				typeDecl.sourceEnd);
+	}
+}
+public void typeHiding(TypeParameter typeParam, Binding hidden) {
+	int severity = computeSeverity(IProblem.TypeParameterHidingType);
+	if (severity == ProblemSeverities.Ignore) return;
+	TypeBinding hiddenType = (TypeBinding) hidden;
+	this.handle(
+		IProblem.TypeParameterHidingType,
+		new String[] { new String(typeParam.name) , new String(hiddenType.readableName())  },
+		new String[] { new String(typeParam.name) , new String(hiddenType.shortReadableName()) },
+		severity,
+		typeParam.sourceStart,
+		typeParam.sourceEnd);
+}
+public void typeMismatchError(TypeBinding actualType, TypeBinding expectedType, ASTNode location, ASTNode expectingLocation) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) { // don't expose type variable names, complain on erased types
+		if (actualType instanceof TypeVariableBinding)
+			actualType = actualType.erasure();
+		if (expectedType instanceof TypeVariableBinding)
+			expectedType = expectedType.erasure();
+	}
+	if (actualType != null && (actualType.tagBits & TagBits.HasMissingType) != 0) { // improve secondary error
+		this.handle(
+				IProblem.UndefinedType,
+				new String[] {new String(actualType.leafComponentType().readableName())},
+				new String[] {new String(actualType.leafComponentType().shortReadableName())},
+				location.sourceStart,
+				location.sourceEnd);
+			return;
+	}
+	if (expectingLocation != null && (expectedType.tagBits & TagBits.HasMissingType) != 0) { // improve secondary error
+		this.handle(
+				IProblem.UndefinedType,
+				new String[] {new String(expectedType.leafComponentType().readableName())},
+				new String[] {new String(expectedType.leafComponentType().shortReadableName())},
+				expectingLocation.sourceStart,
+				expectingLocation.sourceEnd);
+			return;
+	}
+	char[] actualShortReadableName = actualType.shortReadableName();
+	char[] expectedShortReadableName = expectedType.shortReadableName();
+	if (CharOperation.equals(actualShortReadableName, expectedShortReadableName)) {
+		actualShortReadableName = actualType.readableName();
+		expectedShortReadableName = expectedType.readableName();
+	}
+	this.handle(
+		IProblem.TypeMismatch,
+		new String[] {new String(actualType.readableName()), new String(expectedType.readableName())},
+		new String[] {new String(actualShortReadableName), new String(expectedShortReadableName)},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void typeMismatchError(TypeBinding typeArgument, TypeVariableBinding typeParameter, ReferenceBinding genericType, ASTNode location) {
+	if (location == null) { // binary case
+		this.handle(
+			IProblem.TypeArgumentMismatch,
+			new String[] { new String(typeArgument.readableName()), new String(genericType.readableName()), new String(typeParameter.sourceName), parameterBoundAsString(typeParameter, false) },
+			new String[] { new String(typeArgument.shortReadableName()), new String(genericType.shortReadableName()), new String(typeParameter.sourceName), parameterBoundAsString(typeParameter, true) },
+			ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+			0,
+			0);
+        return;
+    }
+	this.handle(
+		IProblem.TypeArgumentMismatch,
+		new String[] { new String(typeArgument.readableName()), new String(genericType.readableName()), new String(typeParameter.sourceName), parameterBoundAsString(typeParameter, false) },
+		new String[] { new String(typeArgument.shortReadableName()), new String(genericType.shortReadableName()), new String(typeParameter.sourceName), parameterBoundAsString(typeParameter, true) },
+		location.sourceStart,
+		location.sourceEnd);
+}
+private String typesAsString(MethodBinding methodBinding, boolean makeShort) {
+	return typesAsString(methodBinding, methodBinding.parameters, makeShort);
+}
+private String typesAsString(MethodBinding methodBinding, TypeBinding[] parameters, boolean makeShort) {
+	if (methodBinding.isPolymorphic()) {
+		// get the original polymorphicMethod method
+		TypeBinding[] types = methodBinding.original().parameters;
+		StringBuffer buffer = new StringBuffer(10);
+		for (int i = 0, length = types.length; i < length; i++) {
+			if (i != 0) {
+				buffer.append(", "); //$NON-NLS-1$
+			}
+			TypeBinding type = types[i];
+			boolean isVarargType = i == length-1;
+			if (isVarargType) {
+				type = ((ArrayBinding)type).elementsType();
+			}
+			buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
+			if (isVarargType) {
+				buffer.append("..."); //$NON-NLS-1$
+			}
+		}
+		return buffer.toString();
+	}
+	StringBuffer buffer = new StringBuffer(10);
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0) {
+			buffer.append(", "); //$NON-NLS-1$
+		}
+		TypeBinding type = parameters[i];
+		boolean isVarargType = methodBinding.isVarargs() && i == length-1;
+		if (isVarargType) {
+			type = ((ArrayBinding)type).elementsType();
+		}
+		buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
+		if (isVarargType) {
+			buffer.append("..."); //$NON-NLS-1$
+		}
+	}
+	return buffer.toString();
+}
+private String typesAsString(TypeBinding[] types, boolean makeShort) {
+	StringBuffer buffer = new StringBuffer(10);
+	for (int i = 0, length = types.length; i < length; i++) {
+		if (i != 0) {
+			buffer.append(", "); //$NON-NLS-1$
+		}
+		TypeBinding type = types[i];
+		buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
+	}
+	return buffer.toString();
+}
+
+public void undefinedAnnotationValue(TypeBinding annotationType, MemberValuePair memberValuePair) {
+	if (isRecoveredName(memberValuePair.name)) return;
+	String name = 	new String(memberValuePair.name);
+	this.handle(
+		IProblem.UndefinedAnnotationMember,
+		new String[] { name, new String(annotationType.readableName())},
+		new String[] {	name, new String(annotationType.shortReadableName())},
+		memberValuePair.sourceStart,
+		memberValuePair.sourceEnd);
+}
+public void undefinedLabel(BranchStatement statement) {
+	if (isRecoveredName(statement.label)) return;
+	String[] arguments = new String[] {new String(statement.label)};
+	this.handle(
+		IProblem.UndefinedLabel,
+		arguments,
+		arguments,
+		statement.sourceStart,
+		statement.sourceEnd);
+}
+// can only occur inside binaries
+public void undefinedTypeVariableSignature(char[] variableName, ReferenceBinding binaryType) {
+	this.handle(
+		IProblem.UndefinedTypeVariable,
+		new String[] {new String(variableName), new String(binaryType.readableName()) },
+		new String[] {new String(variableName), new String(binaryType.shortReadableName())},
+		ProblemSeverities.AbortCompilation | ProblemSeverities.Error | ProblemSeverities.Fatal,
+		0,
+		0);
+}
+public void undocumentedEmptyBlock(int blockStart, int blockEnd) {
+	this.handle(
+		IProblem.UndocumentedEmptyBlock,
+		NoArgument,
+		NoArgument,
+		blockStart,
+		blockEnd);
+}
+public void unexpectedStaticModifierForField(SourceTypeBinding type, FieldDeclaration fieldDecl) {
+	String[] arguments = new String[] {new String(fieldDecl.name)};
+	this.handle(
+		IProblem.UnexpectedStaticModifierForField,
+		arguments,
+		arguments,
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+public void unexpectedStaticModifierForMethod(ReferenceBinding type, AbstractMethodDeclaration methodDecl) {
+	String[] arguments = new String[] {new String(type.sourceName()), new String(methodDecl.selector)};
+	this.handle(
+		IProblem.UnexpectedStaticModifierForMethod,
+		arguments,
+		arguments,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void unhandledException(TypeBinding exceptionType, ASTNode location) {
+
+	boolean insideDefaultConstructor =
+		(this.referenceContext instanceof ConstructorDeclaration)
+			&& ((ConstructorDeclaration)this.referenceContext).isDefaultConstructor();
+	boolean insideImplicitConstructorCall =
+		(location instanceof ExplicitConstructorCall)
+			&& (((ExplicitConstructorCall) location).accessMode == ExplicitConstructorCall.ImplicitSuper);
+
+	int sourceEnd = location.sourceEnd;
+	if (location instanceof LocalDeclaration) {
+		sourceEnd = ((LocalDeclaration) location).declarationEnd;
+	}
+	this.handle(
+		insideDefaultConstructor
+			? IProblem.UnhandledExceptionInDefaultConstructor
+			: (insideImplicitConstructorCall
+					? IProblem.UndefinedConstructorInImplicitConstructorCall
+					: IProblem.UnhandledException),
+		new String[] {new String(exceptionType.readableName())},
+		new String[] {new String(exceptionType.shortReadableName())},
+		location.sourceStart,
+		sourceEnd);
+}
+public void unhandledExceptionFromAutoClose (TypeBinding exceptionType, ASTNode location) {
+	LocalVariableBinding localBinding = ((LocalDeclaration)location).binding;
+	if (localBinding != null) {
+		this.handle(
+			IProblem.UnhandledExceptionOnAutoClose,
+			new String[] {
+					new String(exceptionType.readableName()),
+					new String(localBinding.readableName())},
+			new String[] {
+					new String(exceptionType.shortReadableName()),
+					new String(localBinding.shortReadableName())},
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void unhandledWarningToken(Expression token) {
+	String[] arguments = new String[] { token.constant.stringValue() };
+	this.handle(
+		IProblem.UnhandledWarningToken,
+		arguments,
+		arguments,
+		token.sourceStart,
+		token.sourceEnd);
+}
+public void uninitializedBlankFinalField(FieldBinding field, ASTNode location) {
+	String[] arguments = new String[] {new String(field.readableName())};
+	this.handle(
+		methodHasMissingSwitchDefault() ? IProblem.UninitializedBlankFinalFieldHintMissingDefault : IProblem.UninitializedBlankFinalField,
+		arguments,
+		arguments,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void uninitializedNonNullField(FieldBinding field, ASTNode location) {
+	char[][] nonNullAnnotationName = this.options.nonNullAnnotationName;
+	String[] arguments = new String[] {
+			new String(nonNullAnnotationName[nonNullAnnotationName.length-1]),
+			new String(field.readableName())
+	};
+	this.handle(
+		methodHasMissingSwitchDefault() ? IProblem.UninitializedNonNullFieldHintMissingDefault : IProblem.UninitializedNonNullField,
+		arguments,
+		arguments,
+		nodeSourceStart(field, location),
+		nodeSourceEnd(field, location));
+}
+public void uninitializedLocalVariable(LocalVariableBinding binding, ASTNode location) {
+	binding.tagBits |= TagBits.NotInitialized;
+	String[] arguments = new String[] {new String(binding.readableName())};
+	this.handle(
+		methodHasMissingSwitchDefault() ? IProblem.UninitializedLocalVariableHintMissingDefault : IProblem.UninitializedLocalVariable,
+		arguments,
+		arguments,
+		nodeSourceStart(binding, location),
+		nodeSourceEnd(binding, location));
+}
+private boolean methodHasMissingSwitchDefault() {
+	MethodScope methodScope = null;
+	if (this.referenceContext instanceof Block) {
+		methodScope = ((Block)this.referenceContext).scope.methodScope();
+	} else if (this.referenceContext instanceof AbstractMethodDeclaration) {
+		methodScope = ((AbstractMethodDeclaration)this.referenceContext).scope;
+	}
+	return methodScope != null && methodScope.hasMissingSwitchDefault;	
+}
+public void unmatchedBracket(int position, ReferenceContext context, CompilationResult compilationResult) {
+	this.handle(
+		IProblem.UnmatchedBracket,
+		NoArgument,
+		NoArgument,
+		position,
+		position,
+		context,
+		compilationResult);
+}
+public void unnecessaryCast(CastExpression castExpression) {
+	int severity = computeSeverity(IProblem.UnnecessaryCast);
+	if (severity == ProblemSeverities.Ignore) return;
+	TypeBinding castedExpressionType = castExpression.expression.resolvedType;
+	this.handle(
+		IProblem.UnnecessaryCast,
+		new String[]{ new String(castedExpressionType.readableName()), new String(castExpression.type.resolvedType.readableName())},
+		new String[]{ new String(castedExpressionType.shortReadableName()), new String(castExpression.type.resolvedType.shortReadableName())},
+		severity,
+		castExpression.sourceStart,
+		castExpression.sourceEnd);
+}
+public void unnecessaryElse(ASTNode location) {
+	this.handle(
+		IProblem.UnnecessaryElse,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void unnecessaryEnclosingInstanceSpecification(Expression expression, ReferenceBinding targetType) {
+	this.handle(
+		IProblem.IllegalEnclosingInstanceSpecification,
+		new String[]{ new String(targetType.readableName())},
+		new String[]{ new String(targetType.shortReadableName())},
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void unnecessaryInstanceof(InstanceOfExpression instanceofExpression, TypeBinding checkType) {
+	int severity = computeSeverity(IProblem.UnnecessaryInstanceof);
+	if (severity == ProblemSeverities.Ignore) return;
+	TypeBinding expressionType = instanceofExpression.expression.resolvedType;
+	this.handle(
+		IProblem.UnnecessaryInstanceof,
+		new String[]{ new String(expressionType.readableName()), new String(checkType.readableName())},
+		new String[]{ new String(expressionType.shortReadableName()), new String(checkType.shortReadableName())},
+		severity,
+		instanceofExpression.sourceStart,
+		instanceofExpression.sourceEnd);
+}
+public void unnecessaryNLSTags(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.UnnecessaryNLSTag,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void unnecessaryTypeArgumentsForMethodInvocation(MethodBinding method, TypeBinding[] genericTypeArguments, TypeReference[] typeArguments) {
+	String methodName = method.isConstructor()
+		? new String(method.declaringClass.shortReadableName())
+		: new String(method.selector);
+	this.handle(
+			method.isConstructor()
+				? IProblem.UnusedTypeArgumentsForConstructorInvocation
+				: IProblem.UnusedTypeArgumentsForMethodInvocation,
+		new String[] {
+				methodName,
+		        typesAsString(method, false),
+		        new String(method.declaringClass.readableName()),
+		        typesAsString(genericTypeArguments, false) },
+		new String[] {
+				methodName,
+		        typesAsString(method, true),
+		        new String(method.declaringClass.shortReadableName()),
+		        typesAsString(genericTypeArguments, true) },
+		typeArguments[0].sourceStart,
+		typeArguments[typeArguments.length-1].sourceEnd);
+}
+public void unqualifiedFieldAccess(NameReference reference, FieldBinding field) {
+	int sourceStart = reference.sourceStart;
+	int sourceEnd = reference.sourceEnd;
+	if (reference instanceof SingleNameReference) {
+		int numberOfParens = (reference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens != 0) {
+			sourceStart = retrieveStartingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens);
+			sourceEnd = retrieveEndingPositionAfterOpeningParenthesis(sourceStart, sourceEnd, numberOfParens);
+		} else {
+			sourceStart = nodeSourceStart(field, reference);
+			sourceEnd = nodeSourceEnd(field, reference);
+		}
+	} else {
+		sourceStart = nodeSourceStart(field, reference);
+		sourceEnd = nodeSourceEnd(field, reference);
+	}
+	this.handle(
+		IProblem.UnqualifiedFieldAccess,
+		new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+		new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+		sourceStart,
+		sourceEnd);
+}
+public void unreachableCatchBlock(ReferenceBinding exceptionType, ASTNode location) {
+	this.handle(
+		IProblem.UnreachableCatch,
+		new String[] {
+			new String(exceptionType.readableName()),
+		 },
+		new String[] {
+			new String(exceptionType.shortReadableName()),
+		 },
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void unreachableCode(Statement statement) {
+	int sourceStart = statement.sourceStart;
+	int sourceEnd = statement.sourceEnd;
+	if (statement instanceof LocalDeclaration) {
+		LocalDeclaration declaration = (LocalDeclaration) statement;
+		sourceStart = declaration.declarationSourceStart;
+		sourceEnd = declaration.declarationSourceEnd;
+	} else if (statement instanceof Expression) {
+		int statemendEnd = ((Expression) statement).statementEnd;
+		if (statemendEnd != -1) sourceEnd = statemendEnd;
+	}
+	this.handle(
+		IProblem.CodeCannotBeReached,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void unresolvableReference(NameReference nameRef, Binding binding) {
+/* also need to check that the searchedType is the receiver type
+	if (binding instanceof ProblemBinding) {
+		ProblemBinding problem = (ProblemBinding) binding;
+		if (problem.searchType != null && problem.searchType.isHierarchyInconsistent())
+			severity = SecondaryError;
+	}
+*/
+	String[] arguments = new String[] {new String(binding.readableName())};
+	int end = nameRef.sourceEnd;
+	int sourceStart = nameRef.sourceStart;
+	if (nameRef instanceof QualifiedNameReference) {
+		QualifiedNameReference ref = (QualifiedNameReference) nameRef;
+		if (isRecoveredName(ref.tokens)) return;
+		if (ref.indexOfFirstFieldBinding >= 1)
+			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
+	} else {
+		SingleNameReference ref = (SingleNameReference) nameRef;
+		if (isRecoveredName(ref.token)) return;
+		int numberOfParens = (ref.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens != 0) {
+			sourceStart = retrieveStartingPositionAfterOpeningParenthesis(sourceStart, end, numberOfParens);
+			end = retrieveEndingPositionAfterOpeningParenthesis(sourceStart, end, numberOfParens);
+		}
+	}
+	int problemId = (nameRef.bits & Binding.VARIABLE) != 0 && (nameRef.bits & Binding.TYPE) == 0
+		? IProblem.UnresolvedVariable
+		: IProblem.UndefinedName;
+	this.handle(
+		problemId,
+		arguments,
+		arguments,
+		sourceStart,
+		end);
+}
+public void unsafeCast(CastExpression castExpression, Scope scope) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	int severity = computeSeverity(IProblem.UnsafeGenericCast);
+	if (severity == ProblemSeverities.Ignore) return;
+	TypeBinding castedExpressionType = castExpression.expression.resolvedType;
+	TypeBinding castExpressionResolvedType = castExpression.resolvedType;
+	this.handle(
+		IProblem.UnsafeGenericCast,
+		new String[]{
+			new String(castedExpressionType.readableName()),
+			new String(castExpressionResolvedType.readableName())
+		},
+		new String[]{
+			new String(castedExpressionType.shortReadableName()),
+			new String(castExpressionResolvedType.shortReadableName())
+		},
+		severity,
+		castExpression.sourceStart,
+		castExpression.sourceEnd);
+}
+public void unsafeGenericArrayForVarargs(TypeBinding leafComponentType, ASTNode location) {
+	int severity = computeSeverity(IProblem.UnsafeGenericArrayForVarargs);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.UnsafeGenericArrayForVarargs,
+		new String[]{ new String(leafComponentType.readableName())},
+		new String[]{ new String(leafComponentType.shortReadableName())},
+		severity,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void unsafeRawFieldAssignment(FieldBinding field, TypeBinding expressionType, ASTNode location) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	int severity = computeSeverity(IProblem.UnsafeRawFieldAssignment);
+	if (severity == ProblemSeverities.Ignore) return;
+	this.handle(
+		IProblem.UnsafeRawFieldAssignment,
+		new String[] {
+		        new String(expressionType.readableName()), new String(field.name), new String(field.declaringClass.readableName()), new String(field.declaringClass.erasure().readableName()) },
+		new String[] {
+		        new String(expressionType.shortReadableName()), new String(field.name), new String(field.declaringClass.shortReadableName()), new String(field.declaringClass.erasure().shortReadableName()) },
+		severity,
+		nodeSourceStart(field,location),
+		nodeSourceEnd(field, location));
+}
+public void unsafeRawGenericMethodInvocation(ASTNode location, MethodBinding rawMethod, TypeBinding[] argumentTypes) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	boolean isConstructor = rawMethod.isConstructor();
+	int severity = computeSeverity(isConstructor ? IProblem.UnsafeRawGenericConstructorInvocation : IProblem.UnsafeRawGenericMethodInvocation);
+	if (severity == ProblemSeverities.Ignore) return;
+    if (isConstructor) {
+		this.handle(
+			IProblem.UnsafeRawGenericConstructorInvocation, // The generic constructor {0}({1}) of type {2} is applied to non-parameterized type arguments ({3})
+			new String[] {
+				new String(rawMethod.declaringClass.sourceName()),
+				typesAsString(rawMethod.original(), false),
+				new String(rawMethod.declaringClass.readableName()),
+				typesAsString(argumentTypes, false),
+			 },
+			new String[] {
+				new String(rawMethod.declaringClass.sourceName()),
+				typesAsString(rawMethod.original(), true),
+				new String(rawMethod.declaringClass.shortReadableName()),
+				typesAsString(argumentTypes, true),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+    } else {
+		this.handle(
+			IProblem.UnsafeRawGenericMethodInvocation,
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original(), false),
+				new String(rawMethod.declaringClass.readableName()),
+				typesAsString(argumentTypes, false),
+			 },
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original(), true),
+				new String(rawMethod.declaringClass.shortReadableName()),
+				typesAsString(argumentTypes, true),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+    }
+}
+public void unsafeRawInvocation(ASTNode location, MethodBinding rawMethod) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	boolean isConstructor = rawMethod.isConstructor();
+	int severity = computeSeverity(isConstructor ? IProblem.UnsafeRawConstructorInvocation : IProblem.UnsafeRawMethodInvocation);
+	if (severity == ProblemSeverities.Ignore) return;
+    if (isConstructor) {
+		this.handle(
+			IProblem.UnsafeRawConstructorInvocation,
+			new String[] {
+				new String(rawMethod.declaringClass.readableName()),
+				typesAsString(rawMethod.original(), rawMethod.parameters, false),
+				new String(rawMethod.declaringClass.erasure().readableName()),
+			 },
+			new String[] {
+				new String(rawMethod.declaringClass.shortReadableName()),
+				typesAsString(rawMethod.original(), rawMethod.parameters, true),
+				new String(rawMethod.declaringClass.erasure().shortReadableName()),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+    } else {
+		this.handle(
+			IProblem.UnsafeRawMethodInvocation,
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original(), rawMethod.parameters, false),
+				new String(rawMethod.declaringClass.readableName()),
+				new String(rawMethod.declaringClass.erasure().readableName()),
+			 },
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original(), rawMethod.parameters, true),
+				new String(rawMethod.declaringClass.shortReadableName()),
+				new String(rawMethod.declaringClass.erasure().shortReadableName()),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+    }
+}
+public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, SourceTypeBinding type) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) {
+		return;
+	}
+	int severity = computeSeverity(IProblem.UnsafeReturnTypeOverride);
+	if (severity == ProblemSeverities.Ignore) return;
+	int start = type.sourceStart();
+	int end = type.sourceEnd();
+	if (currentMethod.declaringClass == type) {
+		ASTNode location = ((MethodDeclaration) currentMethod.sourceMethod()).returnType;
+		start = location.sourceStart();
+		end = location.sourceEnd();
+	}
+	this.handle(
+			IProblem.UnsafeReturnTypeOverride,
+			new String[] {
+				new String(currentMethod.returnType.readableName()),
+				new String(currentMethod.selector),
+				typesAsString(currentMethod.original(), false),
+				new String(currentMethod.declaringClass.readableName()),
+				new String(inheritedMethod.returnType.readableName()),
+				new String(inheritedMethod.declaringClass.readableName()),
+				//new String(inheritedMethod.returnType.erasure().readableName()),
+			 },
+			new String[] {
+				new String(currentMethod.returnType.shortReadableName()),
+				new String(currentMethod.selector),
+				typesAsString(currentMethod.original(), true),
+				new String(currentMethod.declaringClass.shortReadableName()),
+				new String(inheritedMethod.returnType.shortReadableName()),
+				new String(inheritedMethod.declaringClass.shortReadableName()),
+				//new String(inheritedMethod.returnType.erasure().shortReadableName()),
+			 },
+			severity,
+			start,
+			end);
+}
+public void unsafeTypeConversion(Expression expression, TypeBinding expressionType, TypeBinding expectedType) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	int severity = computeSeverity(IProblem.UnsafeTypeConversion);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (!this.options.reportUnavoidableGenericTypeProblems && expression.forcedToBeRaw(this.referenceContext)) {
+		return;
+	}
+	this.handle(
+		IProblem.UnsafeTypeConversion,
+		new String[] { new String(expressionType.readableName()), new String(expectedType.readableName()), new String(expectedType.erasure().readableName()) },
+		new String[] { new String(expressionType.shortReadableName()), new String(expectedType.shortReadableName()), new String(expectedType.erasure().shortReadableName()) },
+		severity,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void unsafeElementTypeConversion(Expression expression, TypeBinding expressionType, TypeBinding expectedType) {
+	if (this.options.sourceLevel < ClassFileConstants.JDK1_5) return; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259
+	int severity = computeSeverity(IProblem.UnsafeElementTypeConversion);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (!this.options.reportUnavoidableGenericTypeProblems && expression.forcedToBeRaw(this.referenceContext)) {
+		return;
+	}
+	this.handle(
+		IProblem.UnsafeElementTypeConversion,
+		new String[] { new String(expressionType.readableName()), new String(expectedType.readableName()), new String(expectedType.erasure().readableName()) },
+		new String[] { new String(expressionType.shortReadableName()), new String(expectedType.shortReadableName()), new String(expectedType.erasure().shortReadableName()) },
+		severity,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void unusedArgument(LocalDeclaration localDecl) {
+	int severity = computeSeverity(IProblem.ArgumentIsNeverUsed);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(localDecl.name)};
+	this.handle(
+		IProblem.ArgumentIsNeverUsed,
+		arguments,
+		arguments,
+		severity,
+		localDecl.sourceStart,
+		localDecl.sourceEnd);
+}
+public void unusedDeclaredThrownException(ReferenceBinding exceptionType, AbstractMethodDeclaration method, ASTNode location) {
+	boolean isConstructor = method.isConstructor();
+	int severity = computeSeverity(isConstructor ? IProblem.UnusedConstructorDeclaredThrownException : IProblem.UnusedMethodDeclaredThrownException);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (isConstructor) {
+		this.handle(
+			IProblem.UnusedConstructorDeclaredThrownException,
+			new String[] {
+				new String(method.binding.declaringClass.readableName()),
+				typesAsString(method.binding, false),
+				new String(exceptionType.readableName()),
+			 },
+			new String[] {
+				new String(method.binding.declaringClass.shortReadableName()),
+				typesAsString(method.binding, true),
+				new String(exceptionType.shortReadableName()),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+	} else {
+		this.handle(
+			IProblem.UnusedMethodDeclaredThrownException,
+			new String[] {
+				new String(method.binding.declaringClass.readableName()),
+				new String(method.selector),
+				typesAsString(method.binding, false),
+				new String(exceptionType.readableName()),
+			 },
+			new String[] {
+				new String(method.binding.declaringClass.shortReadableName()),
+				new String(method.selector),
+				typesAsString(method.binding, true),
+				new String(exceptionType.shortReadableName()),
+			 },
+			severity,
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void unusedImport(ImportReference importRef) {
+	int severity = computeSeverity(IProblem.UnusedImport);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] { CharOperation.toString(importRef.tokens) };
+	this.handle(
+		IProblem.UnusedImport,
+		arguments,
+		arguments,
+		severity,
+		importRef.sourceStart,
+		importRef.sourceEnd);
+}
+public void unusedLabel(LabeledStatement statement) {
+	int severity = computeSeverity(IProblem.UnusedLabel);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(statement.label)};
+	this.handle(
+		IProblem.UnusedLabel,
+		arguments,
+		arguments,
+		severity,
+		statement.sourceStart,
+		statement.labelEnd);
+}
+public void unusedLocalVariable(LocalDeclaration localDecl) {
+	int severity = computeSeverity(IProblem.LocalVariableIsNeverUsed);
+	if (severity == ProblemSeverities.Ignore) return;
+	String[] arguments = new String[] {new String(localDecl.name)};
+	this.handle(
+		IProblem.LocalVariableIsNeverUsed,
+		arguments,
+		arguments,
+		severity,
+		localDecl.sourceStart,
+		localDecl.sourceEnd);
+}
+public void unusedObjectAllocation(AllocationExpression allocationExpression) {
+	this.handle(
+		IProblem.UnusedObjectAllocation, 
+		NoArgument, 
+		NoArgument, 
+		allocationExpression.sourceStart, 
+		allocationExpression.sourceEnd);
+}
+public void unusedPrivateConstructor(ConstructorDeclaration constructorDecl) {
+
+	int severity = computeSeverity(IProblem.UnusedPrivateConstructor);
+	if (severity == ProblemSeverities.Ignore) return;
+	
+	if (excludeDueToAnnotation(constructorDecl.annotations, IProblem.UnusedPrivateConstructor)) return;
+	
+	MethodBinding constructor = constructorDecl.binding;
+	this.handle(
+			IProblem.UnusedPrivateConstructor,
+		new String[] {
+			new String(constructor.declaringClass.readableName()),
+			typesAsString(constructor, false)
+		 },
+		new String[] {
+			new String(constructor.declaringClass.shortReadableName()),
+			typesAsString(constructor, true)
+		 },
+		severity,
+		constructorDecl.sourceStart,
+		constructorDecl.sourceEnd);
+}
+public void unusedPrivateField(FieldDeclaration fieldDecl) {
+
+	int severity = computeSeverity(IProblem.UnusedPrivateField);
+	if (severity == ProblemSeverities.Ignore) return;
+
+	FieldBinding field = fieldDecl.binding;
+
+	if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name)
+			&& field.isStatic()
+			&& field.isFinal()
+			&& TypeBinding.LONG == field.type) {
+		ReferenceBinding referenceBinding = field.declaringClass;
+		if (referenceBinding != null) {
+			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
+				return; // do not report unused serialVersionUID field for class that implements Serializable
+			}
+		}
+	}
+	if (CharOperation.equals(TypeConstants.SERIALPERSISTENTFIELDS, field.name)
+			&& field.isStatic()
+			&& field.isFinal()
+			&& field.type.dimensions() == 1
+			&& CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTSTREAMFIELD, field.type.leafComponentType().readableName())) {
+		ReferenceBinding referenceBinding = field.declaringClass;
+		if (referenceBinding != null) {
+			if (referenceBinding.findSuperTypeOriginatingFrom(TypeIds.T_JavaIoSerializable, false /*Serializable is not a class*/) != null) {
+				return; // do not report unused serialVersionUID field for class that implements Serializable
+			}
+		}
+	}
+	if (excludeDueToAnnotation(fieldDecl.annotations, IProblem.UnusedPrivateField)) return;
+	this.handle(
+			IProblem.UnusedPrivateField,
+		new String[] {
+			new String(field.declaringClass.readableName()),
+			new String(field.name),
+		 },
+		new String[] {
+			new String(field.declaringClass.shortReadableName()),
+			new String(field.name),
+		 },
+		severity,
+		nodeSourceStart(field, fieldDecl),
+		nodeSourceEnd(field, fieldDecl));
+}
+public void unusedPrivateMethod(AbstractMethodDeclaration methodDecl) {
+
+	int severity = computeSeverity(IProblem.UnusedPrivateMethod);
+	if (severity == ProblemSeverities.Ignore) return;
+
+	MethodBinding method = methodDecl.binding;
+
+	// no report for serialization support 'void readObject(ObjectInputStream)'
+	if (!method.isStatic()
+			&& TypeBinding.VOID == method.returnType
+			&& method.parameters.length == 1
+			&& method.parameters[0].dimensions() == 0
+			&& CharOperation.equals(method.selector, TypeConstants.READOBJECT)
+			&& CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTINPUTSTREAM, method.parameters[0].readableName())) {
+		return;
+	}
+	// no report for serialization support 'void writeObject(ObjectOutputStream)'
+	if (!method.isStatic()
+			&& TypeBinding.VOID == method.returnType
+			&& method.parameters.length == 1
+			&& method.parameters[0].dimensions() == 0
+			&& CharOperation.equals(method.selector, TypeConstants.WRITEOBJECT)
+			&& CharOperation.equals(TypeConstants.CharArray_JAVA_IO_OBJECTOUTPUTSTREAM, method.parameters[0].readableName())) {
+		return;
+	}
+	// no report for serialization support 'Object readResolve()'
+	if (!method.isStatic()
+			&& TypeIds.T_JavaLangObject == method.returnType.id
+			&& method.parameters.length == 0
+			&& CharOperation.equals(method.selector, TypeConstants.READRESOLVE)) {
+		return;
+	}
+	// no report for serialization support 'Object writeReplace()'
+	if (!method.isStatic()
+			&& TypeIds.T_JavaLangObject == method.returnType.id
+			&& method.parameters.length == 0
+			&& CharOperation.equals(method.selector, TypeConstants.WRITEREPLACE)) {
+		return;
+	}
+	if (excludeDueToAnnotation(methodDecl.annotations, IProblem.UnusedPrivateMethod)) return;
+	
+	this.handle(
+			IProblem.UnusedPrivateMethod,
+		new String[] {
+			new String(method.declaringClass.readableName()),
+			new String(method.selector),
+			typesAsString(method, false)
+		 },
+		new String[] {
+			new String(method.declaringClass.shortReadableName()),
+			new String(method.selector),
+			typesAsString(method, true)
+		 },
+		severity,
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+
+/**
+ * Returns true if a private member should not be warned as unused if
+ * annotated with a non-standard annotation.
+ * https://bugs.eclipse.org/365437
+ * https://bugs.eclipse.org/376590
+ */
+private boolean excludeDueToAnnotation(Annotation[] annotations, int problemId) {
+	int annotationsLen = 0;
+	if (annotations != null) {
+		annotationsLen = annotations.length;
+	} else {
+		return false;
+	}
+	if (annotationsLen == 0) return false;
+	for (int i = 0; i < annotationsLen; i++) {
+		TypeBinding resolvedType = annotations[i].resolvedType;
+		if (resolvedType != null) {
+			switch (resolvedType.id) {
+				case TypeIds.T_JavaLangSuppressWarnings:
+				case TypeIds.T_JavaLangDeprecated:
+				case TypeIds.T_JavaLangSafeVarargs:
+				case TypeIds.T_ConfiguredAnnotationNonNull:
+				case TypeIds.T_ConfiguredAnnotationNullable:
+				case TypeIds.T_ConfiguredAnnotationNonNullByDefault:
+					break;
+				case TypeIds.T_JavaxInjectInject:
+				case TypeIds.T_ComGoogleInjectInject:
+					if (problemId != IProblem.UnusedPrivateField)
+						return true; // @Inject on method/ctor does constitute a relevant use, just on fields it doesn't
+					break;
+				default:
+					// non-standard annotation found, don't warn
+					return true;
+			}
+		}
+	}
+	return false;
+}
+public void unusedPrivateType(TypeDeclaration typeDecl) {
+	int severity = computeSeverity(IProblem.UnusedPrivateType);
+	if (severity == ProblemSeverities.Ignore) return;
+	if (excludeDueToAnnotation(typeDecl.annotations, IProblem.UnusedPrivateType)) return;
+	ReferenceBinding type = typeDecl.binding;
+	this.handle(
+			IProblem.UnusedPrivateType,
+		new String[] {
+			new String(type.readableName()),
+		 },
+		new String[] {
+			new String(type.shortReadableName()),
+		 },
+		severity,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd);
+}
+public void unusedTypeParameter(TypeParameter typeParameter) {
+	int severity = computeSeverity(IProblem.UnusedTypeParameter);
+	if (severity == ProblemSeverities.Ignore) return;
+	String [] arguments = new String[] {new String(typeParameter.name)};
+	this.handle(
+			IProblem.UnusedTypeParameter,
+			arguments,
+			arguments,
+			typeParameter.sourceStart,
+			typeParameter.sourceEnd);
+}
+public void unusedWarningToken(Expression token) {
+	String[] arguments = new String[] { token.constant.stringValue() };
+	this.handle(
+		IProblem.UnusedWarningToken,
+		arguments,
+		arguments,
+		token.sourceStart,
+		token.sourceEnd);
+}
+public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.UseAssertAsAnIdentifier,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void useEnumAsAnIdentifier(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.UseEnumAsAnIdentifier,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void illegalUseOfUnderscoreAsAnIdentifier(int sourceStart, int sourceEnd) {
+	this.handle(
+		IProblem.IllegalUseOfUnderscoreAsAnIdentifier,
+		NoArgument,
+		NoArgument,
+		sourceStart,
+		sourceEnd);
+}
+public void varargsArgumentNeedCast(MethodBinding method, TypeBinding argumentType, InvocationSite location) {
+	int severity = this.options.getSeverity(CompilerOptions.VarargsArgumentNeedCast);
+	if (severity == ProblemSeverities.Ignore) return;
+	ArrayBinding varargsType = (ArrayBinding)method.parameters[method.parameters.length-1];
+	if (method.isConstructor()) {
+		this.handle(
+			IProblem.ConstructorVarargsArgumentNeedCast,
+			new String[] {
+					new String(argumentType.readableName()),
+					new String(varargsType.readableName()),
+					new String(method.declaringClass.readableName()),
+					typesAsString(method, false),
+					new String(varargsType.elementsType().readableName()),
+			},
+			new String[] {
+					new String(argumentType.shortReadableName()),
+					new String(varargsType.shortReadableName()),
+					new String(method.declaringClass.shortReadableName()),
+					typesAsString(method, true),
+					new String(varargsType.elementsType().shortReadableName()),
+			},
+			severity,
+			location.sourceStart(),
+			location.sourceEnd());
+	} else {
+		this.handle(
+			IProblem.MethodVarargsArgumentNeedCast,
+			new String[] {
+					new String(argumentType.readableName()),
+					new String(varargsType.readableName()),
+					new String(method.selector),
+					typesAsString(method, false),
+					new String(method.declaringClass.readableName()),
+					new String(varargsType.elementsType().readableName()),
+			},
+			new String[] {
+					new String(argumentType.shortReadableName()),
+					new String(varargsType.shortReadableName()),
+					new String(method.selector), typesAsString(method, true),
+					new String(method.declaringClass.shortReadableName()),
+					new String(varargsType.elementsType().shortReadableName()),
+			},
+			severity,
+			location.sourceStart(),
+			location.sourceEnd());
+	}
+}
+public void varargsConflict(MethodBinding method1, MethodBinding method2, SourceTypeBinding type) {
+	this.handle(
+		IProblem.VarargsConflict,
+		new String[] {
+		        new String(method1.selector),
+		        typesAsString(method1, false),
+		        new String(method1.declaringClass.readableName()),
+		        typesAsString(method2, false),
+		        new String(method2.declaringClass.readableName())
+		},
+		new String[] {
+		        new String(method1.selector),
+		        typesAsString(method1, true),
+		        new String(method1.declaringClass.shortReadableName()),
+		        typesAsString(method2, true),
+		        new String(method2.declaringClass.shortReadableName())
+		},
+		method1.declaringClass == type ? method1.sourceStart() : type.sourceStart(),
+		method1.declaringClass == type ? method1.sourceEnd() : type.sourceEnd());
+}
+public void safeVarargsOnFixedArityMethod(MethodBinding method) {
+	String [] arguments = new String[] { new String(method.isConstructor() ? method.declaringClass.shortReadableName() : method.selector)}; 
+	this.handle(
+		IProblem.SafeVarargsOnFixedArityMethod,
+		arguments,
+		arguments,
+		method.sourceStart(),
+		method.sourceEnd());
+}
+public void safeVarargsOnNonFinalInstanceMethod(MethodBinding method) {
+	String [] arguments = new String[] { new String(method.isConstructor() ? method.declaringClass.shortReadableName() : method.selector)}; 
+	this.handle(
+		IProblem.SafeVarargsOnNonFinalInstanceMethod,
+		arguments,
+		arguments,
+		method.sourceStart(),
+		method.sourceEnd());
+}
+public void possibleHeapPollutionFromVararg(AbstractVariableDeclaration vararg) {
+	String[] arguments = new String[] {new String(vararg.name)};
+	this.handle(
+		IProblem.PotentialHeapPollutionFromVararg,
+		arguments,
+		arguments,
+		vararg.sourceStart,
+		vararg.sourceEnd);
+}
+public void variableTypeCannotBeVoid(AbstractVariableDeclaration varDecl) {
+	String[] arguments = new String[] {new String(varDecl.name)};
+	this.handle(
+		IProblem.VariableTypeCannotBeVoid,
+		arguments,
+		arguments,
+		varDecl.sourceStart,
+		varDecl.sourceEnd);
+}
+public void variableTypeCannotBeVoidArray(AbstractVariableDeclaration varDecl) {
+	this.handle(
+		IProblem.CannotAllocateVoidArray,
+		NoArgument,
+		NoArgument,
+		varDecl.type.sourceStart,
+		varDecl.type.sourceEnd);
+}
+public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	this.handle(
+		//	Cannot reduce the visibility of the inherited method from %1
+		// 8.4.6.3 - The access modifier of an hiding method must provide at least as much access as the hidden method.
+		// 8.4.6.3 - The access modifier of an overiding method must provide at least as much access as the overriden method.
+		IProblem.MethodReducesVisibility,
+		new String[] {new String(inheritedMethod.declaringClass.readableName())},
+		new String[] {new String(inheritedMethod.declaringClass.shortReadableName())},
+		currentMethod.sourceStart(),
+		currentMethod.sourceEnd());
+}
+public void wildcardAssignment(TypeBinding variableType, TypeBinding expressionType, ASTNode location) {
+	this.handle(
+		IProblem.WildcardFieldAssignment,
+		new String[] {
+		        new String(expressionType.readableName()), new String(variableType.readableName()) },
+		new String[] {
+		        new String(expressionType.shortReadableName()), new String(variableType.shortReadableName()) },
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void wildcardInvocation(ASTNode location, TypeBinding receiverType, MethodBinding method, TypeBinding[] arguments) {
+	TypeBinding offendingArgument = null;
+	TypeBinding offendingParameter = null;
+	for (int i = 0, length = method.parameters.length; i < length; i++) {
+		TypeBinding parameter = method.parameters[i];
+		if (parameter.isWildcard() && (((WildcardBinding) parameter).boundKind != Wildcard.SUPER)) {
+			offendingParameter = parameter;
+			offendingArgument = arguments[i];
+			break;
+		}
+	}
+
+	if (method.isConstructor()) {
+		this.handle(
+			IProblem.WildcardConstructorInvocation,
+			new String[] {
+				new String(receiverType.sourceName()),
+				typesAsString(method, false),
+				new String(receiverType.readableName()),
+				typesAsString(arguments, false),
+				new String(offendingArgument.readableName()),
+				new String(offendingParameter.readableName()),
+			 },
+			new String[] {
+				new String(receiverType.sourceName()),
+				typesAsString(method, true),
+				new String(receiverType.shortReadableName()),
+				typesAsString(arguments, true),
+				new String(offendingArgument.shortReadableName()),
+				new String(offendingParameter.shortReadableName()),
+			 },
+			location.sourceStart,
+			location.sourceEnd);
+    } else {
+		this.handle(
+			IProblem.WildcardMethodInvocation,
+			new String[] {
+				new String(method.selector),
+				typesAsString(method, false),
+				new String(receiverType.readableName()),
+				typesAsString(arguments, false),
+				new String(offendingArgument.readableName()),
+				new String(offendingParameter.readableName()),
+			 },
+			new String[] {
+				new String(method.selector),
+				typesAsString(method, true),
+				new String(receiverType.shortReadableName()),
+				typesAsString(arguments, true),
+				new String(offendingArgument.shortReadableName()),
+				new String(offendingParameter.shortReadableName()),
+			 },
+			location.sourceStart,
+			location.sourceEnd);
+    }
+}
+public void wrongSequenceOfExceptionTypesError(TypeReference typeRef, TypeBinding exceptionType, TypeBinding hidingExceptionType) {
+	//the two catch block under and upper are in an incorrect order.
+	//under should be define BEFORE upper in the source
+
+	this.handle(
+		IProblem.InvalidCatchBlockSequence,
+		new String[] {
+			new String(exceptionType.readableName()),
+			new String(hidingExceptionType.readableName()),
+		 },
+		new String[] {
+			new String(exceptionType.shortReadableName()),
+			new String(hidingExceptionType.shortReadableName()),
+		 },
+		typeRef.sourceStart,
+		typeRef.sourceEnd);
+}
+public void wrongSequenceOfExceptionTypes(TypeReference typeRef, TypeBinding exceptionType, TypeBinding hidingExceptionType) {
+	// type references inside a multi-catch block are not of union type
+	this.handle(
+		IProblem.InvalidUnionTypeReferenceSequence,
+		new String[] {
+			new String(exceptionType.readableName()),
+			new String(hidingExceptionType.readableName()),
+		 },
+		new String[] {
+			new String(exceptionType.shortReadableName()),
+			new String(hidingExceptionType.shortReadableName()),
+		 },
+		typeRef.sourceStart,
+		typeRef.sourceEnd);
+}
+
+public void autoManagedResourcesNotBelow17(LocalDeclaration[] resources) {
+	this.handle(
+			IProblem.AutoManagedResourceNotBelow17,
+			NoArgument,
+			NoArgument,
+			resources[0].declarationSourceStart,
+			resources[resources.length - 1].declarationSourceEnd);
+}
+public void cannotInferElidedTypes(AllocationExpression allocationExpression) {
+	String arguments [] = new String [] { allocationExpression.type.toString() };
+	this.handle(
+			IProblem.CannotInferElidedTypes,
+			arguments,
+			arguments,
+			allocationExpression.sourceStart, 
+			allocationExpression.sourceEnd);
+}
+public void diamondNotWithExplicitTypeArguments(TypeReference[] typeArguments) {
+	this.handle(
+			IProblem.CannotUseDiamondWithExplicitTypeArguments,
+			NoArgument,
+			NoArgument,
+			typeArguments[0].sourceStart, 
+			typeArguments[typeArguments.length - 1].sourceEnd);
+}
+public void diamondNotWithAnoymousClasses(TypeReference type) {
+	this.handle(
+			IProblem.CannotUseDiamondWithAnonymousClasses,
+			NoArgument,
+			NoArgument,
+			type.sourceStart, 
+			type.sourceEnd);
+}
+public void redundantSpecificationOfTypeArguments(ASTNode location, TypeBinding[] argumentTypes) {
+	int severity = computeSeverity(IProblem.RedundantSpecificationOfTypeArguments);
+	if (severity != ProblemSeverities.Ignore) {
+		int sourceStart = -1;
+		if (location instanceof QualifiedTypeReference) {
+			QualifiedTypeReference ref = (QualifiedTypeReference)location;
+			sourceStart = (int) (ref.sourcePositions[ref.sourcePositions.length - 1] >> 32);
+		} else {
+			sourceStart = location.sourceStart;
+		}
+		this.handle(
+			IProblem.RedundantSpecificationOfTypeArguments,
+			new String[] {typesAsString(argumentTypes, false)},
+			new String[] {typesAsString(argumentTypes, true)},
+			severity,
+			sourceStart,
+			location.sourceEnd);
+    }
+}
+public void potentiallyUnclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
+	String[] args = { trackVar.nameForReporting(location, this.referenceContext) };
+	if (location == null) {
+		this.handle(
+			IProblem.PotentiallyUnclosedCloseable,
+			args,
+			args,
+			trackVar.sourceStart,
+			trackVar.sourceEnd);
+	} else {
+		this.handle(
+			IProblem.PotentiallyUnclosedCloseableAtExit,
+			args,
+			args,
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void unclosedCloseable(FakedTrackingVariable trackVar, ASTNode location) {
+	String[] args = { String.valueOf(trackVar.name) };
+	if (location == null) {
+		this.handle(
+			IProblem.UnclosedCloseable,
+			args,
+			args,
+			trackVar.sourceStart,
+			trackVar.sourceEnd);
+	} else {
+		this.handle(
+			IProblem.UnclosedCloseableAtExit,
+			args,
+			args,
+			location.sourceStart,
+			location.sourceEnd);
+	}
+}
+public void explicitlyClosedAutoCloseable(FakedTrackingVariable trackVar) {
+	String[] args = { String.valueOf(trackVar.name) };
+	this.handle(
+		IProblem.ExplicitlyClosedAutoCloseable,
+		args,
+		args,
+		trackVar.sourceStart,
+		trackVar.sourceEnd);	
+}
+
+public void nullityMismatch(Expression expression, TypeBinding providedType, TypeBinding requiredType, int nullStatus, char[][] annotationName) {
+	if ((nullStatus & FlowInfo.NULL) != 0) {
+		nullityMismatchIsNull(expression, requiredType, annotationName);
+		return;
+	}
+	if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0) {
+		VariableBinding var = expression.localVariableBinding();
+		if (var == null && expression instanceof Reference) {
+			var = ((Reference)expression).lastFieldBinding();
+		}
+		if (var != null && var.isNullable()) {
+			nullityMismatchSpecdNullable(expression, requiredType, annotationName);
+			return;
+		}
+		nullityMismatchPotentiallyNull(expression, requiredType, annotationName);
+		return;
+	}
+	nullityMismatchIsUnknown(expression, providedType, requiredType, annotationName);
+}
+public void nullityMismatchIsNull(Expression expression, TypeBinding requiredType, char[][] annotationName) {
+	int problemId = IProblem.RequiredNonNullButProvidedNull;
+	String[] arguments = new String[] {
+			annotatedTypeName(requiredType, annotationName)
+	};
+	String[] argumentsShort = new String[] {
+			shortAnnotatedTypeName(requiredType, annotationName)
+	};
+	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void nullityMismatchSpecdNullable(Expression expression, TypeBinding requiredType, char[][] annotationName) {
+	int problemId = IProblem.RequiredNonNullButProvidedSpecdNullable;
+	char[][] nullableName = this.options.nullableAnnotationName;
+	String[] arguments = new String[] {
+			annotatedTypeName(requiredType, annotationName),
+			String.valueOf(CharOperation.concatWith(nullableName, '.'))
+	};
+	String[] argumentsShort = new String[] {
+			shortAnnotatedTypeName(requiredType, annotationName),
+			String.valueOf(nullableName[nullableName.length-1])
+	};
+	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void nullityMismatchPotentiallyNull(Expression expression, TypeBinding requiredType, char[][] annotationName) {
+	int problemId = IProblem.RequiredNonNullButProvidedPotentialNull;
+	char[][] nullableName = this.options.nullableAnnotationName;
+	String[] arguments = new String[] {
+			annotatedTypeName(requiredType, annotationName),
+			String.valueOf(CharOperation.concatWith(nullableName, '.'))
+	};
+	String[] argumentsShort = new String[] {
+			shortAnnotatedTypeName(requiredType, annotationName),
+			String.valueOf(nullableName[nullableName.length-1])
+	};
+	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void nullityMismatchIsUnknown(Expression expression, TypeBinding providedType, TypeBinding requiredType, char[][] annotationName) {
+	int problemId = IProblem.RequiredNonNullButProvidedUnknown;
+	String[] arguments = new String[] {
+			String.valueOf(providedType.readableName()),
+			annotatedTypeName(requiredType, annotationName)
+	};
+	String[] argumentsShort = new String[] {
+			String.valueOf(providedType.shortReadableName()),
+			shortAnnotatedTypeName(requiredType, annotationName)
+	};
+	this.handle(problemId, arguments, argumentsShort, expression.sourceStart, expression.sourceEnd);
+}
+public void illegalRedefinitionToNonNullParameter(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
+	int sourceStart = argument.type.sourceStart;
+	if (argument.annotations != null) {
+		for (int i=0; i<argument.annotations.length; i++) {
+			Annotation annotation = argument.annotations[i];
+			if (   annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNullable
+				|| annotation.resolvedType.id == TypeIds.T_ConfiguredAnnotationNonNull)
+			{
+				sourceStart = annotation.sourceStart;
+				break;
+			}
+		}
+	}
+	if (inheritedAnnotationName == null) {
+		this.handle(
+			IProblem.IllegalDefinitionToNonNullParameter, 
+			new String[] { new String(argument.name), new String(declaringClass.readableName()) },
+			new String[] { new String(argument.name), new String(declaringClass.shortReadableName()) },
+			sourceStart,
+			argument.type.sourceEnd);
+	} else {
+		this.handle(
+			IProblem.IllegalRedefinitionToNonNullParameter, 
+			new String[] { new String(argument.name), new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
+			new String[] { new String(argument.name), new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
+			sourceStart,
+			argument.type.sourceEnd);
+	}
+}
+public void parameterLackingNullableAnnotation(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
+	this.handle(
+		IProblem.ParameterLackingNullableAnnotation, 
+		new String[] { new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
+		new String[] { new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
+		argument.type.sourceStart,
+		argument.type.sourceEnd);
+}
+public void parameterLackingNonnullAnnotation(Argument argument, ReferenceBinding declaringClass, char[][] inheritedAnnotationName) {
+	int sourceStart = 0, sourceEnd = 0;
+	if (argument != null) {
+		sourceStart = argument.type.sourceStart;
+		sourceEnd = argument.type.sourceEnd;
+	} else if (this.referenceContext instanceof TypeDeclaration) {
+		sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart;
+		sourceEnd =   ((TypeDeclaration) this.referenceContext).sourceEnd;
+	}
+	this.handle(
+		IProblem.ParameterLackingNonNullAnnotation, 
+		new String[] { new String(declaringClass.readableName()), CharOperation.toString(inheritedAnnotationName)},
+		new String[] { new String(declaringClass.shortReadableName()), new String(inheritedAnnotationName[inheritedAnnotationName.length-1])},
+		sourceStart,
+		sourceEnd);
+}
+public void illegalReturnRedefinition(AbstractMethodDeclaration abstractMethodDecl, MethodBinding inheritedMethod, char[][] nonNullAnnotationName) {
+	MethodDeclaration methodDecl = (MethodDeclaration) abstractMethodDecl;
+	StringBuffer methodSignature = new StringBuffer();
+	methodSignature
+		.append(inheritedMethod.declaringClass.readableName())
+		.append('.')
+		.append(inheritedMethod.readableName());
+
+	StringBuffer shortSignature = new StringBuffer();
+	shortSignature
+		.append(inheritedMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(inheritedMethod.shortReadableName());
+	int sourceStart = methodDecl.returnType.sourceStart;
+	Annotation[] annotations = methodDecl.annotations;
+	Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNullable);
+	if (annotation != null) {
+		sourceStart = annotation.sourceStart;
+	}
+	this.handle(
+		IProblem.IllegalReturnNullityRedefinition, 
+		new String[] { methodSignature.toString(), CharOperation.toString(nonNullAnnotationName)},
+		new String[] { shortSignature.toString(), new String(nonNullAnnotationName[nonNullAnnotationName.length-1])},
+		sourceStart,
+		methodDecl.returnType.sourceEnd);
+}
+public void parameterLackingNullableAnnotation(ReferenceExpression location, MethodBinding descriptorMethod, int idx,
+				char[][] providedAnnotationName, char/*@Nullable*/[][] requiredAnnotationName, TypeBinding requiredType) {
+	StringBuffer requiredPrefix = new StringBuffer(); 
+	StringBuffer requiredShortPrefix = new StringBuffer(); 
+	if (requiredAnnotationName != null) {
+		requiredPrefix.append('@').append(CharOperation.toString(requiredAnnotationName)).append(' ');
+		requiredShortPrefix.append('@').append(requiredAnnotationName[requiredAnnotationName.length-1]).append(' ');
+	}
+	TypeBinding provided = descriptorMethod.parameters[idx];
+	StringBuffer methodSignature = new StringBuffer();
+	methodSignature
+		.append(descriptorMethod.declaringClass.readableName())
+		.append('.')
+		.append(descriptorMethod.readableName());
+	StringBuffer shortSignature = new StringBuffer();
+	shortSignature
+		.append(descriptorMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(descriptorMethod.shortReadableName());
+	this.handle(
+			IProblem.ReferenceExpressionParameterMismatchPromisedNullable, 
+			new String[] { String.valueOf(idx+1), 
+							requiredPrefix.toString(), String.valueOf(requiredType.readableName()),
+							CharOperation.toString(providedAnnotationName), String.valueOf(provided.readableName()),
+							methodSignature.toString() },
+			new String[] { String.valueOf(idx+1), 
+							requiredShortPrefix.toString(), String.valueOf(requiredType.shortReadableName()),
+							String.valueOf(providedAnnotationName[providedAnnotationName.length-1]), String.valueOf(provided.shortReadableName()),
+							shortSignature.toString() },
+			location.sourceStart,
+			location.sourceEnd);
+}
+public void parameterRequiresNonnull(ReferenceExpression location, MethodBinding descriptorMethod, int idx,
+				char[][] nonNullAnnotationName, TypeBinding requiredType) {
+	StringBuffer methodSignature = new StringBuffer();
+	methodSignature
+		.append(descriptorMethod.declaringClass.readableName())
+		.append('.')
+		.append(descriptorMethod.readableName());
+
+	StringBuffer shortSignature = new StringBuffer();
+	shortSignature
+		.append(descriptorMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(descriptorMethod.shortReadableName());
+	this.handle(
+		IProblem.ReferenceExpressionParameterRequiredNonnullUnchecked, 
+		new String[] { String.valueOf(idx+1),
+					methodSignature.toString(),
+					CharOperation.toString(nonNullAnnotationName), String.valueOf(requiredType.readableName()) },
+		new String[] { String.valueOf(idx+1),
+					shortSignature.toString(),
+					String.valueOf(nonNullAnnotationName[nonNullAnnotationName.length-1]), String.valueOf(requiredType.shortReadableName()) },
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void illegalReturnRedefinition(ASTNode location, MethodBinding descriptorMethod,
+			char[][] nonNullAnnotationName, 
+			char/*@Nullable*/[][] providedAnnotationName, TypeBinding providedType) {
+	StringBuffer methodSignature = new StringBuffer()
+		.append(descriptorMethod.declaringClass.readableName())
+		.append('.')
+		.append(descriptorMethod.readableName());
+	StringBuffer shortSignature = new StringBuffer()
+		.append(descriptorMethod.declaringClass.shortReadableName())
+		.append('.')
+		.append(descriptorMethod.shortReadableName());
+	StringBuffer providedPrefix = new StringBuffer(); 
+	StringBuffer providedShortPrefix = new StringBuffer(); 
+	if (providedAnnotationName != null) {
+		providedPrefix.append('@').append(CharOperation.toString(providedAnnotationName)).append(' ');
+		providedShortPrefix.append('@').append(providedAnnotationName[providedAnnotationName.length-1]).append(' ');
+	}
+	this.handle(
+		providedAnnotationName == null
+			? IProblem.ReferenceExpressionReturnNullRedefUnchecked
+			: IProblem.ReferenceExpressionReturnNullRedef,
+		new String[] { methodSignature.toString(),
+						CharOperation.toString(nonNullAnnotationName), String.valueOf(descriptorMethod.returnType.readableName()),
+						providedPrefix.toString(), String.valueOf(providedType.readableName())},
+		new String[] { shortSignature.toString(),
+						String.valueOf(nonNullAnnotationName[nonNullAnnotationName.length-1]), String.valueOf(descriptorMethod.returnType.shortReadableName()),
+						providedShortPrefix.toString(), String.valueOf(providedType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void messageSendPotentialNullReference(MethodBinding method, ASTNode location) {
+	String[] arguments = new String[] {new String(method.readableName())};
+	this.handle(
+		IProblem.PotentialNullMessageSendReference,
+		arguments,
+		arguments,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void messageSendRedundantCheckOnNonNull(MethodBinding method, ASTNode location) {
+	String[] arguments = new String[] {new String(method.readableName())  };
+	this.handle(
+		IProblem.RedundantNullCheckOnNonNullMessageSend,
+		arguments,
+		arguments,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void expressionNullReference(ASTNode location) {
+	this.handle(
+		IProblem.NullExpressionReference,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+public void expressionPotentialNullReference(ASTNode location) {
+	this.handle(
+		IProblem.PotentialNullExpressionReference,
+		NoArgument,
+		NoArgument,
+		location.sourceStart,
+		location.sourceEnd);
+}
+
+public void cannotImplementIncompatibleNullness(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	int sourceStart = 0, sourceEnd = 0;
+	if (this.referenceContext instanceof TypeDeclaration) {
+		sourceStart = ((TypeDeclaration) this.referenceContext).sourceStart;
+		sourceEnd =   ((TypeDeclaration) this.referenceContext).sourceEnd;
+	}
+	String[] problemArguments = {
+			new String(currentMethod.readableName()),
+			new String(currentMethod.declaringClass.readableName()),
+			new String(inheritedMethod.declaringClass.readableName())
+		};
+	String[] messageArguments = {
+			new String(currentMethod.shortReadableName()),
+			new String(currentMethod.declaringClass.shortReadableName()),
+			new String(inheritedMethod.declaringClass.shortReadableName())
+		};
+	this.handle(
+			IProblem.CannotImplementIncompatibleNullness,
+			problemArguments,
+			messageArguments,
+			sourceStart,
+			sourceEnd);
+}
+
+public void nullAnnotationIsRedundant(AbstractMethodDeclaration sourceMethod, int i) {
+	int sourceStart, sourceEnd;
+	if (i == -1) {
+		MethodDeclaration methodDecl = (MethodDeclaration) sourceMethod;
+		Annotation annotation = findAnnotation(methodDecl.annotations, TypeIds.T_ConfiguredAnnotationNonNull);
+		sourceStart = annotation != null ? annotation.sourceStart : methodDecl.returnType.sourceStart;
+		sourceEnd = methodDecl.returnType.sourceEnd;
+	} else {
+		Argument arg = sourceMethod.arguments[i];
+		sourceStart = arg.declarationSourceStart;
+		sourceEnd = arg.sourceEnd;
+	}
+	this.handle(IProblem.RedundantNullAnnotation, ProblemHandler.NoArgument, ProblemHandler.NoArgument, sourceStart, sourceEnd);
+}
+
+public void nullAnnotationIsRedundant(FieldDeclaration sourceField) {
+	Annotation annotation = findAnnotation(sourceField.annotations, TypeIds.T_ConfiguredAnnotationNonNull);
+	int sourceStart = annotation != null ? annotation.sourceStart : sourceField.type.sourceStart;
+	int sourceEnd = sourceField.type.sourceEnd;
+	this.handle(IProblem.RedundantNullAnnotation, ProblemHandler.NoArgument, ProblemHandler.NoArgument, sourceStart, sourceEnd);
+}
+
+public void nullDefaultAnnotationIsRedundant(ASTNode location, Annotation[] annotations, Binding outer) {
+	Annotation annotation = findAnnotation(annotations, TypeIds.T_ConfiguredAnnotationNonNullByDefault);
+	int start = annotation != null ? annotation.sourceStart : location.sourceStart;
+	int end = annotation != null ? annotation.sourceEnd : location.sourceStart;
+	String[] args = NoArgument;
+	String[] shortArgs = NoArgument;
+	if (outer != null) {
+		args = new String[] { new String(outer.readableName()) };
+		shortArgs = new String[] { new String(outer.shortReadableName()) };
+	}
+	int problemId = IProblem.RedundantNullDefaultAnnotation;
+	if (outer instanceof PackageBinding) {
+		problemId = IProblem.RedundantNullDefaultAnnotationPackage;
+	} else if (outer instanceof ReferenceBinding) {
+		problemId = IProblem.RedundantNullDefaultAnnotationType;
+	} else if (outer instanceof MethodBinding) {
+		problemId = IProblem.RedundantNullDefaultAnnotationMethod;
+	}
+	this.handle(problemId, args, shortArgs, start, end);
+}
+
+public void contradictoryNullAnnotations(Annotation annotation) {
+	// when this error is triggered we can safely assume that both annotations have been configured
+	char[][] nonNullAnnotationName = this.options.nonNullAnnotationName;
+	char[][] nullableAnnotationName = this.options.nullableAnnotationName;
+	String[] arguments = {
+		new String(CharOperation.concatWith(nonNullAnnotationName, '.')),
+		new String(CharOperation.concatWith(nullableAnnotationName, '.'))
+	};
+	String[] shortArguments = {
+			new String(nonNullAnnotationName[nonNullAnnotationName.length-1]),
+			new String(nullableAnnotationName[nullableAnnotationName.length-1])
+		};
+	this.handle(IProblem.ContradictoryNullAnnotations, arguments, shortArguments, annotation.sourceStart, annotation.sourceEnd);
+}
+
+// conflict default <-> inherited
+public void conflictingNullAnnotations(MethodBinding currentMethod, ASTNode location, MethodBinding inheritedMethod)
+{
+	char[][] nonNullAnnotationName = this.options.nonNullAnnotationName;
+	char[][] nullableAnnotationName = this.options.nullableAnnotationName;
+	String[] arguments = {
+		new String(CharOperation.concatWith(nonNullAnnotationName, '.')),
+		new String(CharOperation.concatWith(nullableAnnotationName, '.')),
+		new String(inheritedMethod.declaringClass.readableName())
+	};
+	String[] shortArguments = {
+			new String(nonNullAnnotationName[nonNullAnnotationName.length-1]),
+			new String(nullableAnnotationName[nullableAnnotationName.length-1]),
+			new String(inheritedMethod.declaringClass.shortReadableName())
+		};
+	this.handle(IProblem.ConflictingNullAnnotations, arguments, shortArguments, location.sourceStart, location.sourceEnd);
+}
+
+// conflict between different inheriteds
+public void conflictingInheritedNullAnnotations(ASTNode location, boolean previousIsNonNull, MethodBinding previousInherited, boolean isNonNull, MethodBinding inheritedMethod)
+{
+	char[][] previousAnnotationName = previousIsNonNull ? this.options.nonNullAnnotationName : this.options.nullableAnnotationName;
+	char[][] annotationName = isNonNull ? this.options.nonNullAnnotationName : this.options.nullableAnnotationName;
+	String[] arguments = {
+		new String(CharOperation.concatWith(previousAnnotationName, '.')),
+		new String(previousInherited.declaringClass.readableName()),
+		new String(CharOperation.concatWith(annotationName, '.')),
+		new String(inheritedMethod.declaringClass.readableName())
+	};
+	String[] shortArguments = {
+			new String(previousAnnotationName[previousAnnotationName.length-1]),
+			new String(previousInherited.declaringClass.shortReadableName()),
+			new String(annotationName[annotationName.length-1]),
+			new String(inheritedMethod.declaringClass.shortReadableName())
+		};
+	this.handle(IProblem.ConflictingInheritedNullAnnotations, arguments, shortArguments, location.sourceStart, location.sourceEnd);
+}
+
+public void illegalAnnotationForBaseType(TypeReference type, Annotation[] annotations, char[] annotationName, long nullAnnotationTagBit)
+{
+	int typeId = (nullAnnotationTagBit == TagBits.AnnotationNullable) 
+			? TypeIds.T_ConfiguredAnnotationNullable : TypeIds.T_ConfiguredAnnotationNonNull;
+	String[] args = new String[] { new String(annotationName), new String(type.getLastToken()) };
+	Annotation annotation = findAnnotation(annotations, typeId);
+	int start = annotation != null ? annotation.sourceStart : type.sourceStart;
+	this.handle(IProblem.IllegalAnnotationForBaseType,
+			args,
+			args,
+			start,
+			type.sourceEnd);
+}
+
+private String annotatedTypeName(TypeBinding type, char[][] annotationName) {
+	int dims = 0;
+	if (type instanceof ArrayBinding && ((ArrayBinding)type).nullTagBitsPerDimension != null) {
+		dims = type.dimensions();
+		type = type.leafComponentType();
+	}
+	char[] typeName = type.readableName();
+	char[] annotationDisplayName = CharOperation.concatWith(annotationName, '.');
+	return internalAnnotatedTypeName(annotationDisplayName, typeName, dims);
+}
+private String shortAnnotatedTypeName(TypeBinding type, char[][] annotationName) {
+	int dims = 0;
+	if (type instanceof ArrayBinding && ((ArrayBinding)type).nullTagBitsPerDimension != null) {
+		// if type has annotations on dimensions show the annotation on the outer most dimension:
+		dims = type.dimensions();
+		type = type.leafComponentType();
+	}
+	char[] typeName = type.shortReadableName();
+	char[] annotationDisplayName = annotationName[annotationName.length-1];
+	return internalAnnotatedTypeName(annotationDisplayName, typeName, dims);
+}
+
+String internalAnnotatedTypeName(char[] annotationName, char[] typeName, int dims) {
+	char[] fullName;
+	if (dims > 0) {
+		int plainLen = annotationName.length+typeName.length+2; // adding '@' and ' ' ...
+		fullName = new char[plainLen+(2*dims)]; // ... and []* 
+		System.arraycopy(typeName, 0, fullName, 0, typeName.length);
+		fullName[typeName.length] = ' ';
+		fullName[typeName.length+1] = '@';
+		System.arraycopy(annotationName, 0, fullName, typeName.length+2, annotationName.length);
+		for (int i=0; i<dims; i++) {
+			fullName[plainLen+i] = '[';
+			fullName[plainLen+i+1] = ']';
+		}
+	} else {
+		fullName = new char[annotationName.length+typeName.length+2]; // adding '@' and ' ' 
+		fullName[0] = '@';
+		System.arraycopy(annotationName, 0, fullName, 1, annotationName.length);
+		fullName[annotationName.length+1] = ' ';
+		System.arraycopy(typeName, 0, fullName, annotationName.length+2, typeName.length);
+	}
+	return String.valueOf(fullName);
+}
+private Annotation findAnnotation(Annotation[] annotations, int typeId) {
+	if (annotations != null) {
+		// should have a @NonNull/@Nullable annotation, search for it:
+		int length = annotations.length;
+		for (int j=0; j<length; j++) {
+			if (annotations[j].resolvedType != null && annotations[j].resolvedType.id == typeId) {
+				return annotations[j];
+			}
+		}
+	}
+	return null;
+}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012
+public void missingNonNullByDefaultAnnotation(TypeDeclaration type) {
+	int severity;
+	CompilationUnitDeclaration compUnitDecl = type.getCompilationUnitDeclaration();
+	String[] arguments;
+	if (compUnitDecl.currentPackage == null) {
+		severity = computeSeverity(IProblem.MissingNonNullByDefaultAnnotationOnType);
+		if (severity == ProblemSeverities.Ignore) return;
+		// Default package
+		TypeBinding binding = type.binding;
+		this.handle(
+				IProblem.MissingNonNullByDefaultAnnotationOnType,
+				new String[] {new String(binding.readableName()), },
+				new String[] {new String(binding.shortReadableName()),},
+				severity,
+				type.sourceStart,
+				type.sourceEnd);
+	} else {
+		severity = computeSeverity(IProblem.MissingNonNullByDefaultAnnotationOnPackage);
+		if (severity == ProblemSeverities.Ignore) return;
+		arguments = new String[] {CharOperation.toString(compUnitDecl.currentPackage.tokens)};
+		this.handle(
+			IProblem.MissingNonNullByDefaultAnnotationOnPackage,
+			arguments,
+			arguments,
+			severity,
+			compUnitDecl.currentPackage.sourceStart,
+			compUnitDecl.currentPackage.sourceEnd);
+	}
+}
+
+public void illegalModifiersForElidedType(Argument argument) {
+	String[] arg = new String[] {new String(argument.name)};
+	this.handle(
+			IProblem.IllegalModifiersForElidedType,
+			arg,
+			arg,
+			argument.declarationSourceStart,
+			argument.declarationSourceEnd);
+}
+
+public void illegalModifiers(int modifierSourceStart, int modifiersSourceEnd) {
+	this.handle(
+			IProblem.IllegalModifiers,
+			NoArgument,
+			NoArgument,
+			modifierSourceStart,
+			modifiersSourceEnd);
+}
+
+public void arrayReferencePotentialNullReference(ArrayReference arrayReference) {
+	// TODO(stephan): merge with other expressions
+	this.handle(IProblem.ArrayReferencePotentialNullReference, NoArgument, NoArgument, arrayReference.sourceStart, arrayReference.sourceEnd);
+	
+}
+public void nullityMismatchingTypeAnnotation(Expression expression, TypeBinding providedType, TypeBinding requiredType, 
+		boolean uncheckedConversion, LookupEnvironment env) 
+{
+	String[] arguments = new String[] {
+		String.valueOf(requiredType.nullAnnotatedReadableName(env, false)),
+		String.valueOf(providedType.nullAnnotatedReadableName(env, false))
+	};
+	String[] shortArguments = new String[] {
+		String.valueOf(requiredType.nullAnnotatedReadableName(env, true)),
+		String.valueOf(providedType.nullAnnotatedReadableName(env, true))
+	};
+	this.handle(
+			uncheckedConversion ? IProblem.NullityMismatchingTypeAnnotationUnchecked : IProblem.NullityMismatchingTypeAnnotation,
+			arguments, shortArguments, expression.sourceStart, expression.sourceEnd);
+}
+public void dereferencingNullableExpression(Expression expression, LookupEnvironment env) {
+	if (expression instanceof MessageSend) {
+		MessageSend send = (MessageSend) expression;
+		messageSendPotentialNullReference(send.binding, send);
+		return;
+	}
+	char[][] nullableName = env.getNullableAnnotationName();
+	char[] nullableShort = nullableName[nullableName.length-1];
+	String[] arguments = { String.valueOf(nullableShort) };
+	// TODO(stephan): more sophisticated handling for various kinds of expressions
+	this.handle(IProblem.DereferencingNullableExpression, arguments, arguments, expression.sourceStart, expression.sourceEnd);
+	
+}
+public void onlyReferenceTypesInIntersectionCast(TypeReference typeReference) {
+	this.handle(
+			IProblem.IllegalBasetypeInIntersectionCast,
+			NoArgument,
+			NoArgument,
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+}
+public void illegalArrayTypeInIntersectionCast(TypeReference typeReference) {
+	this.handle(
+			IProblem.IllegalArrayTypeInIntersectionCast,
+			NoArgument,
+			NoArgument,
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+}
+public void intersectionCastNotBelow18(TypeReference[] typeReferences) {
+	int length = typeReferences.length;
+	this.handle(
+			IProblem.IntersectionCastNotBelow18,
+			NoArgument,
+			NoArgument,
+			typeReferences[0].sourceStart,
+			typeReferences[length -1].sourceEnd);
+}
+
+public void duplicateBoundInIntersectionCast(TypeReference typeReference) {
+	this.handle(
+			IProblem.DuplicateBoundInIntersectionCast,
+			NoArgument,
+			NoArgument,
+			typeReference.sourceStart,
+			typeReference.sourceEnd);
+}
+
+public void multipleFunctionalInterfaces(FunctionalExpression functionalExpression) {
+	this.handle(
+			IProblem.MultipleFunctionalInterfaces,
+			NoArgument,
+			NoArgument,
+			functionalExpression.sourceStart,
+			functionalExpression.sourceEnd);
+}
+public void lambdaRedeclaresArgument(Argument argument) {
+	String[] arguments = new String[] {new String(argument.name)};
+	this.handle(
+		IProblem.LambdaRedeclaresArgument,
+		arguments,
+		arguments,
+		argument.sourceStart,
+		argument.sourceEnd);
+}
+public void lambdaRedeclaresLocal(LocalDeclaration local) {
+	String[] arguments = new String[] {new String(local.name)};
+	this.handle(
+		IProblem.LambdaRedeclaresLocal,
+		arguments,
+		arguments,
+		local.sourceStart,
+		local.sourceEnd);
+}
+
+public void descriptorHasInvisibleType(FunctionalExpression expression, ReferenceBinding referenceBinding) {
+	this.handle(
+		IProblem.LambdaDescriptorMentionsUnmentionable,
+		new String[] { new String(referenceBinding.readableName()) },
+		new String[] { new String(referenceBinding.shortReadableName()) },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void methodReferenceSwingsBothWays(ReferenceExpression expression, MethodBinding instanceMethod, MethodBinding nonInstanceMethod) {
+	char [] selector = instanceMethod.selector;
+	TypeBinding receiverType = instanceMethod.declaringClass;
+	StringBuffer buffer1 = new StringBuffer();
+	StringBuffer shortBuffer1 = new StringBuffer();
+	TypeBinding [] parameters = instanceMethod.parameters;
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0){
+			buffer1.append(", "); //$NON-NLS-1$
+			shortBuffer1.append(", "); //$NON-NLS-1$
+		}
+		buffer1.append(new String(parameters[i].readableName()));
+		shortBuffer1.append(new String(parameters[i].shortReadableName()));
+	}
+	StringBuffer buffer2 = new StringBuffer();
+	StringBuffer shortBuffer2 = new StringBuffer();
+	parameters = nonInstanceMethod.parameters;
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0){
+			buffer2.append(", "); //$NON-NLS-1$
+			shortBuffer2.append(", "); //$NON-NLS-1$
+		}
+		buffer2.append(new String(parameters[i].readableName()));
+		shortBuffer2.append(new String(parameters[i].shortReadableName()));
+	}
+
+	int id = IProblem.MethodReferenceSwingsBothWays;
+	this.handle(
+		id,
+		new String[] { new String(receiverType.readableName()), new String(selector), buffer1.toString(), new String(selector), buffer2.toString() },
+		new String[] { new String(receiverType.shortReadableName()), new String(selector), shortBuffer1.toString(), new String(selector), shortBuffer2.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void methodMustBeAccessedStatically(ReferenceExpression expression, MethodBinding nonInstanceMethod) {
+	TypeBinding receiverType = nonInstanceMethod.declaringClass;
+	char [] selector = nonInstanceMethod.selector;
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	TypeBinding [] parameters = nonInstanceMethod.parameters;
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0){
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(parameters[i].readableName()));
+		shortBuffer.append(new String(parameters[i].shortReadableName()));
+	}
+	int id = IProblem.StaticMethodShouldBeAccessedStatically;
+	this.handle(
+		id,
+		new String[] { new String(receiverType.readableName()), new String(selector), buffer.toString() },
+		new String[] { new String(receiverType.shortReadableName()), new String(selector), shortBuffer.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void methodMustBeAccessedWithInstance(ReferenceExpression expression, MethodBinding instanceMethod) {
+	TypeBinding receiverType = instanceMethod.declaringClass;
+	char [] selector = instanceMethod.selector;
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	TypeBinding [] parameters = instanceMethod.parameters;
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0) {
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(parameters[i].readableName()));
+		shortBuffer.append(new String(parameters[i].shortReadableName()));
+	}
+	int id = IProblem.StaticMethodRequested;
+	this.handle(
+		id,
+		new String[] { new String(receiverType.readableName()), new String(selector), buffer.toString() },
+		new String[] { new String(receiverType.shortReadableName()), new String(selector), shortBuffer.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void invalidArrayConstructorReference(ReferenceExpression expression, TypeBinding lhsType, TypeBinding[] parameters) {
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0) {
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(parameters[i].readableName()));
+		shortBuffer.append(new String(parameters[i].shortReadableName()));
+	}
+	int id = IProblem.InvalidArrayConstructorReference;
+	this.handle(
+		id,
+		new String[] { new String(lhsType.readableName()), buffer.toString() },
+		new String[] { new String(lhsType.shortReadableName()), shortBuffer.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+
+public void constructedArrayIncompatible(ReferenceExpression expression, TypeBinding receiverType, TypeBinding returnType) {
+	this.handle(
+			IProblem.ConstructedArrayIncompatible,
+			new String[] { new String(receiverType.readableName()), new String(returnType.readableName()) },
+			new String[] { new String(receiverType.shortReadableName()), new String(returnType.shortReadableName()) },
+			expression.sourceStart,
+			expression.sourceEnd);
+}
+
+public void danglingReference(ReferenceExpression expression, TypeBinding receiverType, char[] selector, TypeBinding[] descriptorParameters) {
+	StringBuffer buffer = new StringBuffer();
+	StringBuffer shortBuffer = new StringBuffer();
+	TypeBinding [] parameters = descriptorParameters;
+	for (int i = 0, length = parameters.length; i < length; i++) {
+		if (i != 0) {
+			buffer.append(", "); //$NON-NLS-1$
+			shortBuffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append(new String(parameters[i].readableName()));
+		shortBuffer.append(new String(parameters[i].shortReadableName()));
+	}
+	
+	int id = IProblem.DanglingReference;
+	this.handle(
+		id,
+		new String[] { new String(receiverType.readableName()), new String(selector), buffer.toString() },
+		new String[] { new String(receiverType.shortReadableName()), new String(selector), shortBuffer.toString() },
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void unhandledException(TypeBinding exceptionType, ReferenceExpression location) {
+	this.handle(IProblem.UnhandledException,
+		new String[] {new String(exceptionType.readableName())},
+		new String[] {new String(exceptionType.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
+
+public void incompatibleReturnType(ReferenceExpression expression, MethodBinding method, TypeBinding returnType) {
+	if (method.isConstructor()) {
+		this.handle(IProblem.ConstructionTypeMismatch,
+				new String[] { new String(method.declaringClass.readableName()), new String(returnType.readableName())},
+				new String[] { new String(method.declaringClass.shortReadableName()), new String(returnType.shortReadableName())},
+				expression.sourceStart,
+				expression.sourceEnd);
+		
+	} else {
+		StringBuffer buffer = new StringBuffer();
+		StringBuffer shortBuffer = new StringBuffer();
+		TypeBinding [] parameters = method.parameters;
+		for (int i = 0, length = parameters.length; i < length; i++) {
+			if (i != 0) {
+				buffer.append(", "); //$NON-NLS-1$
+				shortBuffer.append(", "); //$NON-NLS-1$
+			}
+			buffer.append(new String(parameters[i].readableName()));
+			shortBuffer.append(new String(parameters[i].shortReadableName()));
+		}
+		String selector = new String(method.selector);
+		this.handle(IProblem.IncompatibleMethodReference,
+				new String[] { selector, buffer.toString(), new String(method.declaringClass.readableName()), new String(method.returnType.readableName()), new String(returnType.readableName())},
+				new String[] { selector, shortBuffer.toString(), new String(method.declaringClass.shortReadableName()), new String(method.returnType.shortReadableName()), new String(returnType.shortReadableName())},
+				expression.sourceStart,
+				expression.sourceEnd);
+	}
+}
+
+public void illegalSuperAccess(TypeBinding superType, TypeBinding directSuperType, ASTNode location) {
+	if (directSuperType.problemId() != ProblemReasons.AttemptToBypassDirectSuper)
+		needImplementation(location);
+	handle(IProblem.SuperAccessCannotBypassDirectSuper, 
+			new String[] { String.valueOf(superType.readableName()), String.valueOf(directSuperType.readableName()) },
+			new String[] { String.valueOf(superType.shortReadableName()), String.valueOf(directSuperType.shortReadableName()) },
+			location.sourceStart,
+			location.sourceEnd);
+}
+public void illegalSuperCallBypassingOverride(InvocationSite location, MethodBinding targetMethod, ReferenceBinding overrider) {
+	this.handle(IProblem.SuperCallCannotBypassOverride,
+			new String[] { 	String.valueOf(targetMethod.readableName()),
+							String.valueOf(targetMethod.declaringClass.readableName()),
+							String.valueOf(overrider.readableName()) },
+			new String[] { 	String.valueOf(targetMethod.shortReadableName()),
+							String.valueOf(targetMethod.declaringClass.shortReadableName()),
+							String.valueOf(overrider.shortReadableName()) },
+			location.sourceStart(),
+			location.sourceEnd());
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java
new file mode 100644
index 0000000..5676163
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+public interface ProblemSeverities {
+
+	final int Ignore = 256; // during handling only
+	final int Warning = 0; // during handling only
+
+	final int Error = 1; // when bit is set: problem is error, if not it is a warning
+	final int AbortCompilation = 2;
+	final int AbortCompilationUnit = 4;
+	final int AbortType = 8;
+	final int AbortMethod = 16;
+	final int Abort = 30; // 2r11110
+	final int Optional = 32; // when bit is set: problem was configurable
+	final int SecondaryError = 64;
+	final int Fatal = 128; // when bit is set: problem was either a mandatory error, or an optional+treatOptionalErrorAsFatal
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java
new file mode 100644
index 0000000..8e0e743
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.problem;
+
+/*
+ * Special unchecked exception type used
+ * to denote implementation that should never be reached.
+ *
+ *	(internal only)
+ */
+public class ShouldNotImplement extends RuntimeException {
+	private static final long serialVersionUID = 2669970476264283736L; // backward compatible
+	public ShouldNotImplement(String message) {
+		super(message);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
new file mode 100644
index 0000000..82801b4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -0,0 +1,812 @@
+###############################################################################
+# Copyright (c) 2000, 2013 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# This is an implementation of an early-draft specification developed under the Java
+# Community Process (JCP) and is made available for testing and evaluation purposes
+# only. The code is not compatible with any specification of the JCP.
+#
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+#		Benjamin Muskalla - Contribution for bug 239066
+#		Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+#							bug 185682 - Increment/decrement operators mark local variables as read
+#							bug 349326 - [1.7] new warning for missing try-with-resources
+#							bug 186342 - [compiler][null] Using annotations for null checking
+#							bug 365662 - [compiler][null] warn on contradictory and redundant null annotations
+#							bug 365531 - [compiler][null] investigate alternative strategy for internally encoding nullness defaults
+#							bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
+#							bug 374605 - Unreasonable warning for enum-based switch statements
+#							bug 382353 - [1.8][compiler] Implementation property modifiers should be accepted on default methods.
+#							bug 382347 - [1.8][compiler] Compiler accepts incorrect default method inheritance
+#							bug 388281 - [compiler][null] inheritance of null annotations as an option
+#							bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+#							bug 393719 - [compiler] inconsistent warnings on iteration variables
+#							bug 392862 - [1.8][compiler][null] Evaluate null annotations on array types
+#							bug 382789 - [compiler][null] warn when syntactically-nonnull expression is compared against null
+#							bug 400761 - [compiler][null] null may be return as boolean without a diagnostic
+#							bug 402028 - [1.8][compiler] null analysis for reference expressions
+#							bug 401796 - [1.8][compiler] don't treat default methods as overriding an independent inherited abstract method
+#							bug 404649 - [1.8][compiler] detect illegal reference to indirect or redundant super
+#		Jesper S Moller <jesper@selskabet.org> - Contributions for
+#							bug 382701 - [1.8][compiler] Implement semantic analysis of Lambda expressions & Reference expression
+#							bug 384567 - [1.5][compiler] Compiler accepts illegal modifiers on package declaration
+###############################################################################
+0 = {0}
+1 = super cannot be used in java.lang.Object
+2 = {0} cannot be resolved to a type
+3 = The type {0} is not visible
+4 = The type {0} is ambiguous
+5 = The type {0} is deprecated
+6 = The nested type {0} cannot be referenced using its binary name
+7 = The type {0} is never used locally
+
+15 = Incompatible operand types {0} and {1}
+16 = Incompatible conditional operand types {0} and {1}
+17 = Type mismatch: cannot convert from {0} to {1}
+18 = The static member type {0}.{1} should be accessed directly
+
+20 = No enclosing instance of type {0} is accessible to invoke the super constructor. Must define a constructor and explicitly qualify its super constructor invocation with an instance of {0} (e.g. x.super() where x is an instance of {0}).
+21 = No enclosing instance of type {0} is accessible. Must qualify the allocation with an enclosing instance of type {0} (e.g. x.new A() where x is an instance of {0}).
+22 = No enclosing instance of the type {0} is accessible in scope
+23 = Illegal enclosing instance specification for type {0}
+24 = Cannot define static initializer in inner type {0}
+25 = Cannot refer to the non-final variable {0} in a different method inside an inner class
+26 = The member interface {0} can only be defined inside a top-level class or interface
+27 = Cannot use an expression of the type {0} as a valid enclosing instance
+28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation
+29 = An anonymous class cannot subclass the final class {0}
+30 = The member annotation {0} can only be defined inside a top-level class or interface
+31 = The member enum {0} can only be defined inside a top-level class or interface
+32 = The member enum {0} must be defined inside a static member type
+33 = The type {0} is hiding the type {1}
+
+50 = {0} cannot be resolved
+51 = The local variable {0} may not have been initialized
+52 = void is an invalid type for the variable {0}
+###[obsolete] 53 = An array of void is an invalid type for the variable {0}
+54 = void[] is an invalid type
+55 = Duplicate local variable {0}
+56 = Duplicate parameter {0}
+57 = The final local variable {0} may already have been assigned
+58 = The final local variable {0} cannot be assigned. It must be blank and not using a compound assignment
+59 = The parameter {0} should not be assigned
+60 = The final local variable {0} cannot be assigned, since it is defined in an enclosing type
+61 = The value of the local variable {0} is not used
+62 = The value of the parameter {0} is not used
+63 = The code of method {0}({1}) is exceeding the 65535 bytes limit
+64 = The code for the static initializer is exceeding the 65535 bytes limit
+65 = Too many parameters, parameter {0} is exceeding the limit of 255 words eligible for method parameters
+66 = Too many local variables, local variable {0} is exceeding the limit of 65535 words eligible for method local variables
+67 = Too many synthetic parameters, emulated parameter {0} is exceeding the limit of 255 words eligible for method parameters
+68 = Too many array dimensions. Maximum is 255
+69 = The code of constructor {0}({1}) is exceeding the 65535 bytes limit
+70 = {0} cannot be resolved or is not a field
+71 = The field {1}.{0} is not visible
+72 = The field {0} is ambiguous
+73 = The field {0}.{1} is deprecated
+74 = Cannot make a static reference to the non-static field {0}
+75 = Cannot reference a field before it is defined
+76 = The static field {0}.{1} should be accessed in a static way
+77 = The value of the field {0}.{1} is not used
+78 = The static field {0}.{1} should be accessed directly
+79 = Unqualified access to the field {0}.{1} 
+80 = The final field {0}.{1} cannot be assigned
+81 = The blank final field {0} may not have been initialized
+82 = The final field {0} may already have been assigned
+83 = {0} cannot be resolved to a variable
+84 = This static method of interface {0} can only be accessed as {0}.{1}
+
+90 = The local variable {0} is hiding another local variable defined in an enclosing scope
+91 = The local variable {0} is hiding a field from type {1}
+92 = The field {0}.{1} is hiding another local variable defined in an enclosing scope
+93 = The field {0}.{1} is hiding a field from type {2}
+94 = The parameter {0} is hiding another local variable defined in an enclosing scope
+95 = The parameter {0} is hiding a field from type {1}
+96 = The serializable class {0} does not declare a static final serialVersionUID field of type long
+97 = Lambda expression's parameter {0} cannot redeclare another local variable defined in an enclosing scope. 
+98 = Lambda expression's local variable {0} cannot redeclare another local variable defined in an enclosing scope. 
+99 = The type {0} from the descriptor computed for the target context is not visible here.  
+100 = The method {1}({2}) is undefined for the type {0}
+101 = The method {1}({2}) from the type {0} is not visible
+102 = The method {1}({2}) is ambiguous for the type {0}
+103 = The method {1}({2}) from the type {0} is deprecated
+104 = Cannot directly invoke the abstract method {1}({2}) for the type {0}
+105 = Void methods cannot return a value
+106 = Cannot return a void result
+107 = This method requires a body instead of a semicolon
+108 = This method must return a result of type {0}
+
+110 = This method has a constructor name
+111 = Return type for the method is missing
+112 = Native methods do not specify a body
+113 = Abstract methods do not specify a body
+114 = Cannot invoke {1}({2}) on the primitive type {0}
+115 = The method {1}({2}) in the type {0} is not applicable for the arguments ({3})
+116 = Cannot invoke {1}({2}) on the array type {0}
+117 = The static method {1}({2}) from the type {0} should be accessed in a static way
+118 = The method {1}({2}) from the type {0} is never used locally
+119 = The static method {1}({2}) from the type {0} should be accessed directly 
+120 = The method {1}({2}) from the type {0} refers to the missing type {3}
+121 = The method {1}({2}) from the type {0} can be declared as static
+122 = The method {1}({2}) from the type {0} can potentially be declared as static
+123 = Ambiguous method reference: both {1}({2}) and {3}({4}) from the type {0} are eligible
+124 = The method {1}({2}) from the type {0} should be accessed in a static way 
+125 = Incompatible parameter list for array constructor. Expected (int), but found ({1})
+126 = Constructed array {0} cannot be assigned to {1} as required in the interface descriptor  
+127 = The type {0} does not define {1}({2}) that is applicable here
+128 = The type of {0}({1}) from the type {2} is {3}, this is incompatible with the descriptor's return type: {4}
+129 = The constructor {0}({1}) refers to the missing type {2}
+130 = The constructor {0}({1}) is undefined
+131 = The constructor {0}({1}) is not visible
+132 = The constructor {0}({1}) is ambiguous
+133 = The constructor {0}({1}) is deprecated
+134 = The constructor {0}({1}) is never used locally
+135 = Cannot refer to an instance field {0} while explicitly invoking a constructor
+136 = Cannot refer to an instance method while explicitly invoking a constructor
+137 = Recursive constructor invocation {0}({1})
+138 = Cannot refer to 'this' nor 'super' while explicitly invoking a constructor
+139 = Constructor call must be the first statement in a constructor
+140 = Implicit super constructor {0}({1}) is undefined for default constructor. Must define an explicit constructor
+141 = Implicit super constructor {0}({1}) is not visible for default constructor. Must define an explicit constructor
+142 = Implicit super constructor {0}({1}) is ambiguous for default constructor. Must define an explicit constructor
+143 = Implicit super constructor {0}({1}) is undefined. Must explicitly invoke another constructor
+144 = Implicit super constructor {0}({1}) is not visible. Must explicitly invoke another constructor
+145 = Implicit super constructor {0}({1}) is ambiguous. Must explicitly invoke another constructor
+146 = Default constructor cannot handle exception type {0} thrown by implicit super constructor. Must define an explicit constructor
+147 = Unhandled exception type {0} thrown by implicit super constructor
+
+
+148 = The allocated object is never used
+149 = Dead code
+150 = The type of the expression must be an array type but it resolved to {0}
+151 = Must explicitly convert the char[] to a String
+152 = String constant is exceeding the limit of 65535 bytes of UTF8 encoding
+153 = case expressions must be constant expressions
+154 = The literal {1} of type {0} is out of range 
+156 = Cannot cast from {0} to {1}
+157 = Cannot instantiate the type {0}
+158 = Cannot define dimension expressions when an array initializer is provided
+159 = Variable must provide either dimension expressions or an array initializer
+160 = The operator {0} is undefined for the argument type(s) {1}
+161 = Unreachable code
+162 = Cannot return from within an initializer
+163 = Initializer does not complete normally
+164 = Expression must return a value
+165 = Unreachable catch block for {0}. Only more specific exceptions are thrown and they are handled by previous catch block(s).
+166 = The default case is already defined
+167 = Unreachable catch block for {0}. This exception is never thrown from the try statement body
+168 = Unhandled exception type {0}
+169 = Cannot switch on a value of type {0}. Only convertible int values or enum variables are permitted
+170 = Duplicate case
+171 = Duplicate label {0}
+172 = break cannot be used outside of a loop or a switch
+173 = continue cannot be used outside of a loop
+174 = The label {0} is missing
+175 = {0} is not a valid type''s argument for the synchronized statement
+176 = null is not a valid argument for the synchronized statement
+177 = Cannot throw null as an exception
+178 = The assignment to variable {0} has no effect
+179 = Possible accidental assignment in place of a comparison. A condition expression should not be reduced to an assignment
+180 = Unnecessary semicolon
+181 = Unnecessary cast from {0} to {1}
+182 = Unnecessary cast from {0} to {1}. It is already compatible with the argument type {2}
+183 = The expression of type {0} is already an instance of type {1}
+184 = finally block does not complete normally
+185 = The declared exception {3} is not actually thrown by the method {1}({2}) from type {0}
+186 = The declared exception {2} is not actually thrown by the constructor {0}({1})
+187 = Unreachable catch block for {0}. It is already handled by the catch block for {1}
+188 = Empty control-flow statement
+189 = Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally
+190 = Read access to enclosing field {0}.{1} is emulated by a synthetic accessor method
+191 = Write access to enclosing field {0}.{1} is emulated by a synthetic accessor method
+192 = Access to enclosing method {1}({2}) from the type {0} is emulated by a synthetic accessor method
+193 = Access to enclosing constructor {0}({1}) is emulated by a synthetic accessor method
+194 = Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above
+195 = The method {1} is defined in an inherited type and an enclosing scope
+196 = The field {0} is defined in an inherited type and an enclosing scope 
+197 = The type {0} is defined in an inherited type and an enclosing scope
+198 = Cannot allocate the member type {0} using its compound name when qualified by an enclosing instance. The member type name is resolved relatively to the qualifying instance type
+199 = The label {0} is never explicitly referenced
+200 = Cannot use {0} in a static context
+201 = Cannot make a static reference to the non-static method {1}({2}) from the type {0}
+202 = Cannot specify an array dimension after an empty dimension
+#203 = Invalid cast expression
+204 = Syntax error on token "{0}", {1} expected
+205 = Syntax error on token "{0}", no accurate correction available
+206 = Invalid argument to operation ++/--
+207 = Interfaces cannot have constructors
+208 = Array constants can only be used in initializers
+209 = Syntax error on keyword "{0}"; {1} expected
+210 = Syntax error on keyword "{0}", no accurate correction available
+211 = Comparing identical expressions
+
+220 = Unmatched bracket
+221 = The primitive type {0} of {1} does not have a field {2}
+222 = Invalid expression as statement
+223 = The left-hand side of an assignment must be a variable
+224 = Missing semicolon
+225 = Invalid parenthesized expression
+
+230 = Syntax error on token "{0}", {1} expected before this token
+231 = Syntax error on token "{0}", {1} expected after this token
+232 = Syntax error on token "{0}", delete this token
+233 = Syntax error on tokens, delete these tokens
+234 = Syntax error on tokens, they can be merged to form {0}
+235 = Syntax error on token "{0}", invalid {1}
+236 = Syntax error on token(s), misplaced construct(s)
+237 = Syntax error on tokens, {0} expected instead
+238 = Syntax error on tokens, no accurate correction available
+239 = Syntax error, unexpected {0}
+240 = Syntax error, insert "{0}" to complete {1}
+241 = Syntax error, insert "{0}" to complete scope
+242 = Syntax error, insert "{0}" to complete phrase
+
+250 = Unexpected end of file
+251 = Invalid hex literal number
+252 = Invalid octal literal number
+253 = Invalid character constant
+254 = Invalid escape sequence (valid ones are  \\b  \\t  \\n  \\f  \\r  \\"  \\'  \\\\ )
+255 = Invalid input
+256 = Invalid unicode
+257 = Invalid float literal number
+258 = Null source string
+259 = String literal is not properly closed by a double-quote
+260 = Unexpected end of comment
+261 = Non-externalized string literal; it should be followed by //$NON-NLS-<n>$
+262 = Invalid digit (valid ones are 0..9)
+263 = Invalid low surrogate: must be within 0xDC00 and 0xDFFF
+264 = Invalid high surrogate: must be within 0xD800 and 0xDBFF
+265 = Unnecessary $NON-NLS$ tag
+266 = Invalid binary literal number (only '0' and '1' are expected)
+267 = Binary literals can only be used with source level 1.7 or greater
+268 = Underscores have to be located within digits
+269 = Underscores can only be used with source level 1.7 or greater
+
+280 = Discouraged access: {0}
+
+300 = The interface {0} cannot define an initializer
+301 = Duplicate modifier for the type {0}
+302 = Illegal modifier for the class {0}; only public, abstract & final are permitted
+303 = Illegal modifier for the interface {0}; only public & abstract are permitted
+304 = Illegal modifier for the member class {0}; only public, protected, private, abstract, static & final are permitted
+305 = Illegal modifier for the member interface {0}; only public, protected, private, abstract & static are permitted
+306 = Illegal modifier for the local class {0}; only abstract or final is permitted
+307 = Access restriction: {0}
+308 = The class {0} can be either abstract or final, not both
+309 = The interface member type {0} can only be public
+310 = The member type {0} can only set one of public / protected / private
+311 = The member type {0} cannot be declared static; static types can only be declared in static or top level types
+312 = The type {0} cannot be the superclass of {1}; a superclass must be a class
+313 = The type {1} cannot subclass the final class {0}
+314 = Duplicate interface {0} for the type {1}
+315 = The type {0} cannot be a superinterface of {1}; a superinterface must be an interface
+316 = Cycle detected: the type {0} cannot extend/implement itself or one of its own member types
+317 = Cycle detected: a cycle exists in the type hierarchy between {0} and {1}
+318 = The nested type {0} cannot hide an enclosing type
+319 = Duplicate nested type {0}
+320 = No exception of type {0} can be thrown; an exception type must be a subclass of Throwable
+321 = The package {0} collides with a type
+322 = The type {1} collides with a package
+323 = The type {1} is already defined
+324 = The type {0} cannot be resolved. It is indirectly referenced from required .class files
+325 = The public type {1} must be defined in its own file
+###[obsolete] 326 = A package must be specified in {0} or a default package created
+327 = The hierarchy of the type {0} is inconsistent
+328 = The declared package "{1}" does not match the expected package "{0}"
+329 = The type java.lang.Object cannot have a superclass or superinterfaces
+330 = The type java.lang.Object must be a class
+331 = Redundant superinterface {0} for the type {1}, already defined by {2}
+332 = The type {0} should also implement hashCode() since it overrides Object.equals()
+333 = The type {0} must be an abstract class to define abstract methods
+
+###[obsolete] 330 = {0} cannot be resolved or is not a valid superclass
+###[obsolete] 331 = Superclass {0} is not visible
+###[obsolete] 332 = Superclass {0} is ambiguous
+###[obsolete] 333 = Superclass {0} cannot be referenced using its binary name
+###[obsolete] 334 = Superclass {0} is defined in an inherited type and an enclosing scope
+###[obsolete] 335 = {0} cannot be resolved or is not a valid superinterface
+###[obsolete] 336 = Superinterface {0} is not visible
+###[obsolete] 337 = Superinterface {0} is ambiguous
+###[obsolete] 338 = Superinterface {0} cannot be referenced using its binary name
+###[obsolete] 339 = Superinterface {0} is defined in an inherited type and an enclosing scope
+
+340 = Duplicate field {0}.{1}
+341 = Duplicate modifier for the field {0}
+342 = Illegal modifier for the field {0}; only public, protected, private, static, final, transient & volatile are permitted
+343 = Illegal modifier for the interface field {0}.{1}; only public, static & final are permitted
+344 = The field {0} can only set one of public / protected / private
+345 = The field {0} can be either final or volatile, not both
+346 = The field {0} cannot be declared static in a non-static inner type, unless initialized with a constant expression
+
+###[obsolete] 350 = {2} cannot be resolved (or is not a valid type) for the field {1}.{0}
+###[obsolete] 351 = The type {2} is not visible for the field {1}.{0}
+###[obsolete] 352 = The type {2} is ambiguous for the field {1}.{0}
+###[obsolete] 353 = The field type {2} cannot be referenced using its binary name
+###[obsolete] 354 = The field type {2} is defined in an inherited type and an enclosing scope
+
+355 = Duplicate method {0}({2}) in type {1}
+356 = Illegal modifier for parameter {0}; only final is permitted
+357 = Duplicate modifier for the method {1} in type {0}
+358 = Illegal modifier for the method {0}; only public, protected, private, abstract, static, final, synchronized, native & strictfp are permitted
+359 = Illegal modifier for the interface method {0}; only public & abstract are permitted
+360 = The method {1} in type {0} can only set one of public / protected / private
+361 = The method {1} cannot be declared static; static methods can only be declared in a static or top level type
+362 = The abstract method {1} in type {0} can only set a visibility modifier, one of public or protected
+363 = The abstract method {1} in type {0} can only be defined by an abstract class
+364 = void is an invalid type for the parameter {1} of a method
+###[obsolete] 365 = An array of void is an invalid type for the parameter {1} of the method {0}
+###[obsolete] 366 = An array of void is an invalid return type for the method {0}
+367 = The native method {1} cannot also be declared strictfp
+368 = Duplicate modifier for parameter {0}
+369 = Illegal modifier for the constructor in type {0}; only public, protected & private are permitted
+
+###[obsolete] 370 = {2} cannot be resolved (or is not a valid type) for the parameter {1} of the method {0}
+###[obsolete] 371 = The type {2} is not visible for the parameter {1} of the method {0}
+###[obsolete] 372 = The type {2} is ambiguous for the parameter {1} of the method {0}
+###[obsolete] 373 = The parameter type {2} cannot be referenced using its binary name
+###[obsolete] 374 = The parameter type {2} is defined in an inherited type and an enclosing scope
+###[obsolete] 375 = {1} cannot be resolved (or is not an exception type) for the method {0}
+###[obsolete] 376 = The exception type {1} is not visible for the method {0}
+###[obsolete] 377 = The exception type {1} is ambiguous for the method {0}
+###[obsolete] 378 = The exception type {1} cannot be referenced using its binary name
+###[obsolete] 379 = The exception type {1} is defined in an inherited type and an enclosing scope
+###[obsolete] 380 = {1} cannot be resolved (or is not a valid return type) for the method {0}
+###[obsolete] 381 = The return type {1} is not visible for the method {0}
+###[obsolete] 382 = The return type {1} is ambiguous for the method {0}
+###[obsolete] 383 = The return type {1} cannot be referenced using its binary name
+###[obsolete] 384 = The return type {1} is defined in an inherited type and an enclosing scope
+
+385 = The import {0} conflicts with a type defined in the same file
+386 = The import {0} collides with another import statement
+387 = Only a type can be imported. {0} resolves to a package
+388 = The import {0} is never used
+390 = The import {0} cannot be resolved
+
+###[obsolete] 391 = The imported type {0} is not visible
+###[obsolete] 392 = The imported type {0} is ambiguous
+###[obsolete] 393 = The imported type {0} cannot be referenced using its binary name
+###[obsolete] 394 = The imported type {0} is defined in an inherited type and an enclosing scope
+
+391 = The static import {0} must be a field or member type
+
+395 = Duplicate modifier for the variable {0}
+396 = Illegal modifier for the variable {0}; only final is permitted
+###[obsolete] 397 = Redundant null check: The variable {0} cannot be null at this location
+###[obsolete] 398 = Null pointer access: The variable {0} can only be null at this location
+###[obsolete] 399 = Potential null pointer access: The variable {0} may be null at this location
+	
+400 = The type {3} must implement the inherited abstract method {2}.{0}({1})
+401 = Cannot override the final method from {0}
+402 = Exception {0} is not compatible with throws clause in {1}
+403 = Exception {0} in throws clause of {1} is not compatible with {2}
+404 = The return type is incompatible with {0}
+405 = The inherited method {0} cannot hide the public abstract method in {1}
+406 = This instance method cannot override the static method from {0}
+407 = This static method cannot hide the instance method from {0}
+408 = The static method {0} conflicts with the abstract method in {1}
+409 = Cannot reduce the visibility of the inherited method from {0}
+410 = The method {0} does not override the inherited method from {1} since it is private to a different package
+411 = This class must implement the inherited abstract method {1}, but cannot override it since it is not visible from {0}. Either make the type abstract or make the inherited method visible
+412 = The method {0} overrides a deprecated method from {1}
+413 = The return type is incompatible with {0}, thus this interface cannot be implemented
+414 = Exception {0} is not compatible with throws clause in {1}, thus this interface cannot be implemented
+415 = The variable argument type {0} of the method {1} must be the last parameter
+416 = The method {0} is overriding a method without making a super invocation
+417 = The method {0}.{1}({2}) is overriding a synchronized method without being synchronized
+418 = The type {3} must implement the inherited abstract method {2}.{0}({1}) to override {6}.{4}({5})
+419 = The return types are incompatible for the inherited methods {0}
+
+420 = Code snippet support cannot find the class {0}
+421 = Code snippet support cannot find the method {0}.{1}({2}) 
+422 = super cannot be used in the code snippet code
+
+430 = Too many constants, the constant pool for {0} would exceed 65536 entries
+431 = The type generates a string that requires more than 65535 bytes to encode in Utf8 format in the constant pool
+
+432 = Too many fields for type {0}. Maximum is 65535
+433 = Too many methods for type {0}. Maximum is 65535
+434 = The synthetic method created to access {0}({1}) of type {2} has too many parameters
+
+440 = 'assert' should not be used as an identifier, since it is a reserved keyword from source level 1.4 on
+441 = 'enum' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on
+442 = Enum constants cannot be surrounded by parenthesis
+443 = '_' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on
+
+450 = {0}{1}
+
+451 = Null pointer access: The variable {0} can only be null at this location
+452 = Potential null pointer access: The variable {0} may be null at this location
+453 = Redundant null check: The variable {0} can only be null at this location
+454 = Null comparison always yields false: The variable {0} can only be null at this location
+455 = Redundant assignment: The variable {0} can only be null at this location
+456 = instanceof always yields false: The variable {0} can only be null at this location
+457 = Redundant null check: The variable {0} cannot be null at this location
+458 = Null comparison always yields false: The variable {0} cannot be null at this location
+459 = Potential null pointer access: This expression of type {0} may be null but requires auto-unboxing
+461 = Null pointer access: This expression of type {0} is null but requires auto-unboxing
+460 = Empty block should be documented
+
+### DOC
+462 = Invalid URL reference. Double quote the reference or use the href syntax
+463 = Description expected after this reference
+464 = Unexpected duplicated tag @{0}
+465 = ''{0}'' visibility for malformed doc comments hides this ''{1}'' reference
+466 = Invalid member type qualification
+467 = Missing identifier
+468 = Cannot make a static reference to the non-static type variable {0}
+469 = Invalid param tag type parameter name
+470 = Unexpected tag
+471 = Missing tag for parameter {0}
+472 = Missing parameter name
+473 = Duplicate tag for parameter
+474 = Parameter {0} is not declared
+475 = Missing tag for return type
+476 = Duplicate tag for return type
+477 = Missing tag for declared exception {0}
+478 = Missing class name
+479 = Invalid class name
+480 = Duplicate tag for thrown exception
+481 = Exception {0} is not declared
+482 = Missing reference
+483 = Invalid reference
+484 = Malformed link reference
+485 = Invalid parameters declaration
+486 = Missing comment for {0} declaration
+487 = Invalid tag
+488 = {0} cannot be resolved or is not a field
+489 = The field {0} is not visible
+490 = The field {0} is ambiguous
+491 = The field {0}.{1} is deprecated
+492 = The constructor {0}({1}) is undefined
+493 = The constructor {0}({1}) is not visible
+494 = The constructor {0}({1}) is ambiguous
+495 = The constructor {0}({1}) is deprecated
+496 = The method {1}({2}) is undefined for the type {0}
+497 = The method {1}({2}) from the type {0} is not visible
+498 = The method {1}({2}) is ambiguous for the type {0}
+499 = The method {1}({2}) from the type {0} is deprecated
+500 = Cannot invoke {1}({2}) on the primitive type {0}
+501 = The method {1}({2}) in the type {0} is not applicable for the arguments ({3})
+502 = Cannot invoke {1}({2}) on the array type {0}
+503 = {0} cannot be resolved to a type
+504 = The type {0} is not visible
+505 = The type {0} is ambiguous
+506 = The type {0} is deprecated
+507 = The nested type {0} cannot be referenced using its binary name
+508 = The method {1} is defined in an inherited type and an enclosing scope
+509 = The field {0} is defined in an inherited type and an enclosing scope 
+510 = The type {0} is defined in an inherited type and an enclosing scope
+511 = {0} is an ambiguous method reference or is not a field
+512 = Missing closing brace for inline tag
+513 = Malformed reference (missing end space separator)
+514 = Javadoc: 
+515 = Missing #: "{0}"
+516 = Description expected after @{0}
+517 = Only static field reference is allowed for @value tag
+518 = Unexpected text
+519 = Invalid param tag name
+
+### GENERICS
+520 = Duplicate type parameter {0}
+521 = Cannot refer to the type parameter {0} as a supertype
+522 = Cannot make a static reference to the non-static type {0}
+523 = The type java.lang.Object cannot be declared as a generic
+524 = The type {0} is not generic; it cannot be parameterized with arguments <{1}>
+525 = Incorrect number of arguments for type {0}; it cannot be parameterized with arguments <{1}>
+526 = Bound mismatch: The type {0} is not a valid substitute for the bounded parameter <{2} extends {3}> of the type {1}
+527 = Method {0}({2}) has the same erasure {0}({3}) as another method in type {1}
+528 = Illegal forward reference to type parameter {0}
+529 = The type {0} is not an interface; it cannot be specified as a bounded parameter
+530 = Type safety: The constructor {0}({1}) belongs to the raw type {0}. References to generic type {2} should be parameterized
+531 = Type safety: The method {0}({1}) belongs to the raw type {2}. References to generic type {3} should be parameterized
+532 = Type safety: The expression of type {0} needs unchecked conversion to conform to {1}
+533 = Cannot use the type parameter {0} in a catch block
+534 = Cannot use the parameterized type {0} either in catch block or throws clause
+535 = Cannot create a generic array of {0}
+536 = Type safety: The field {1} from the raw type {2} is assigned a value of type {0}. References to generic type {3} should be parameterized
+537 = The type parameter {0} should not be bounded by the final type {1}. Final types cannot be further extended
+538 = Inconsistent classfile encountered: The undefined type parameter {0} is referenced from within {1}
+539 = The interface {2} cannot be implemented more than once with different arguments: {0} and {1}
+540 = Bound mismatch: The constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The wildcard parameter {5} has no lower bound, and may actually be more restrictive than argument {4}
+541 = Bound mismatch: The method {0}({1}) of type {2} is not applicable for the arguments ({3}). The wildcard parameter {5} has no lower bound, and may actually be more restrictive than argument {4}
+542 = Bound mismatch: Cannot assign expression of type {0} to wildcard type {1}. The wildcard type has no lower bound, and may actually be more restrictive than expression type
+543 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+544 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+545 = Type safety: Unchecked cast from {0} to {1}
+546 = Cannot perform instanceof check against parameterized type {0}. Use the form {1} instead since further generic type information will be erased at runtime
+547 = Cannot perform instanceof check against type parameter {0}. Use its erasure {1} instead since further generic type information will be erased at runtime
+548 = The method {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+549 = Incorrect number of type arguments for generic method <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+550 = The parameterized method <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+551 = The constructor {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+552 = Incorrect number of type arguments for generic constructor <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+553 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+554 = The method {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
+555 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
+556 = The type {1} cannot extend or implement {0}. A supertype may not specify any wildcard
+557 = The generic class {0} may not subclass java.lang.Throwable
+558 = Illegal class literal for the type parameter {0}
+559 = Type safety: The return type {0} for {1}({2}) from the type {3} needs unchecked conversion to conform to {4} from the type {5}
+560 = Name clash: The method {0}({1}) of type {2} has the same erasure as {0}({3}) of type {4} but does not override it
+561 = The member type {0}<{1}> must be qualified with a parameterized type, since it is not static
+562 = The member type {0} must be parameterized, since it is qualified with a parameterized type
+563 = The member type {0} cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type {1}
+###[obsolete] 564 = Bound conflict: {0} is inherited with conflicting arguments
+565 = Duplicate methods named {0} with the parameters ({2}) and ({3}) are defined by the type {1}
+566 = Cannot allocate the member type {0} using a parameterized compound name; use its simple name and an enclosing instance of type {1}
+567 = Duplicate bound {0}
+568 = The array type {0} cannot be used as a type parameter bound
+569 = Type safety: Unchecked invocation {0}({3}) of the generic constructor {0}({1}) of type {2}
+570 = Type safety: Unchecked invocation {0}({3}) of the generic method {0}({1}) of type {2}
+571 = The type parameter {0} is hiding the type {1}
+572 = {0} is a raw type. References to generic type {1} should be parameterized
+573 = Cannot specify any additional bound {0} when first bound is a type parameter
+574 = Type safety: A generic array of {0} is created for a varargs parameter
+575 = Illegal qualified access from the type parameter {0}
+576 = The nested type {0} is hiding the type parameter {1} of type {2}
+577 = The nested type {0} is hiding the type parameter {1} of the generic method {2}({3}) of type {4}
+578 = Wildcard is not allowed at this location
+579 = Unused type arguments for the non generic method {0}({1}) of type {2}; it should not be parameterized with arguments <{3}>
+583 = Duplicate methods named {0} with the parameters ({1}) and ({2}) are inherited from the types {3} and {4}
+584 = Name clash: The method {0}({1}) of type {2} has the same erasure as {0}({3}) of type {4} but does not hide it
+
+### FOREACH
+580 = Type mismatch: cannot convert from element type {0} to {1}
+581 = Can only iterate over an array or an instance of java.lang.Iterable
+582 = Can only iterate over an array or an instance of java.util.Collection
+585 = Type safety: Elements of type {0} need unchecked conversion to conform to {1}
+
+### SOURCE LEVEL
+590 = Syntax error, type parameters are only available if source level is 1.5 or greater
+591 = Syntax error, static imports are only available if source level is 1.5 or greater
+592 = Syntax error, 'for each' statements are only available if source level is 1.5 or greater
+593 = Syntax error, parameterized types are only available if source level is 1.5 or greater
+594 = Syntax error, enum declarations are only available if source level is 1.5 or greater
+595 = Syntax error, varargs are only available if source level is 1.5 or greater
+596 = Syntax error, annotations are only available if source level is 1.5 or greater
+597 = Syntax error, annotation declarations are only available if source level is 1.5 or greater
+598 = Syntax error, annotation declaration cannot have type parameters
+599 = Syntax error, enum declaration cannot have type parameters
+
+### ANNOTATIONS
+600 = Illegal modifier for the annotation attribute {0}.{1}; only public & abstract are permitted
+601 = Extended dimensions are illegal in an annotation attribute declaration
+602 = Package annotations must be in file package-info.java
+603 = Illegal modifier for the annotation type {0}; only public & abstract are permitted
+604 = Illegal modifier for the member annotation type {0}; only public, protected, private, abstract & static are permitted
+605 = Invalid type {0} for the annotation attribute {2}.{1}; only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
+606 = Cycle detected: the annotation type {0} cannot contain attributes of the annotation type itself
+607 = Cycle detected: a cycle exists between annotation attributes of {0} and {1}
+608 = Duplicate annotation @{0}
+609 = The annotation @{0} must define the attribute {1}
+610 = Duplicate attribute {0} in annotation @{1}
+611 = The attribute {0} is undefined for the annotation type {1}
+612 = The value for annotation attribute {0}.{1} must be a class literal
+613 = The value for annotation attribute {0}.{1} must be a constant expression
+###[obsolete] 614 = The annotation field {0}.{1} must be initialized with a constant expression
+615 = Illegal modifier for the annotation field {0}.{1}; only public, static & final are permitted
+616 = The annotation type {0} cannot override the method {1}.{2}({3})
+617 = Annotation attributes cannot have parameters
+618 = Annotation attributes cannot be generic
+619 = Annotation type declaration cannot have an explicit superclass
+620 = Annotation type declaration cannot have explicit superinterfaces
+621 = Duplicate element {0} specified in annotation @{1}
+622 = The annotation @{0} is disallowed for this location
+623 = The method {0}({1}) of type {2} must override a superclass method
+624 = Annotation type declaration cannot have a constructor
+625 = The value for annotation attribute {0}.{1} must be some @{2} annotation 
+626 = The annotation type {0} should not be used as a superinterface for {1}
+627 = The method {0}({1}) of type {2} should be tagged with @Override since it actually overrides a superclass method
+628 = The deprecated field {0}.{1} should be annotated with @Deprecated
+629 = The deprecated method {0}({1}) of type {2} should be annotated with @Deprecated
+630 = The deprecated type {0} should be annotated with @Deprecated
+631 = Unsupported @SuppressWarnings("{0}")
+632 = The value for annotation attribute {0}.{1} must be an array initializer
+633 = The value for annotation attribute {0}.{1} must be an enum constant expression
+634 = The method {0}({1}) of type {2} must override or implement a supertype method
+635 = Unnecessary @SuppressWarnings("{0}")
+636 = The method {0}({1}) of type {2} should be tagged with @Override since it actually overrides a superinterface method
+637 = Syntax error, type annotations are available only when source level is at least 1.8
+638 = Explicit ''this'' parameter is allowed only in instance methods of non-anonymous classes and inner class constructors
+639 = Syntax error, type annotations are illegal here
+640 = Type annotations are not allowed on type names used to access static members
+641 = Type annotation is illegal for a method that returns void
+642 = Only the first formal parameter may be declared explicitly as ''this''
+643 = Explicit declaration of ''this'' parameter is allowed only at source level 1.8 or above
+644 = Default methods are allowed only at source level 1.8 or above
+645 = Lambda expressions are allowed only at source level 1.8 or above
+646 = Method references are allowed only at source level 1.8 or above
+647 = Constructor references are allowed only at source level 1.8 or above
+648 = Lambda expressions cannot declare a this parameter
+649 = Annotation types that do not specify explicit target element types cannot be applied here
+650 = The declared type of the explicit ''this'' parameter is expected to be {0}
+651 = The explicit ''this'' parameter is expected to be qualified with {0}
+652 = The explicit ''this'' parameter for a method cannot have a qualifying name
+653 = The target type of this expression must be a functional interface
+654 = The variable argument type {0} of the lambda expression must be the last parameter
+655 = The target type of this expression is not a well formed parameterized type due to bound(s) mismatch
+656 = Lambda expression's signature does not match the signature of the functional interface method
+657 = Lambda expression's parameter {0} is expected to be of type {1}
+658 = Incompatible type specified for lambda expression's parameter {0}
+659 = Illegal lambda expression: Method {0} of type {1} is generic 
+### MORE GENERICS
+660 = Unused type arguments for the non generic constructor {0}({1}) of type {2}; it should not be parameterized with arguments <{3}>
+661 = Unused type parameter {0}
+
+### MORE TYPE RELATED
+662 = Illegal attempt to create arrays of union types
+663 = Variable {0} is required to be final or effectively final
+664 = Invalid '@FunctionalInterface' annotation; {0} is not a functional interface
+665 = The constructed object of type {0} is incompatible with the descriptor's return type: {1}
+
+### NULL ANALYSIS FOR OTHER EXPRESSIONS
+670 = Null comparison always yields false: this expression cannot be null
+671 = Redundant null check: this expression cannot be null
+672 = Null pointer access: This expression can only be null
+673 = Potential null pointer access: This expression may be null
+
+### CORRUPTED BINARIES
+700 = The class file {0} contains a signature ''{1}'' ill-formed at position {2}
+
+### CORRUPTED SOURCES
+701 = Cannot read the source from {0}; either the file uses a different encoding than {1} or it is corrupted
+702 = Cannot read the source from {0} due to internal exception {1}
+
+### AUTOBOXING
+720 = The expression of type {0} is boxed into {1}
+721 = The expression of type {0} is unboxed into {1}
+
+### ENUMS
+750 = Illegal modifier for the enum {0}; only public is permitted
+751 = Illegal modifier for the enum constant {0}; no modifier is allowed
+###[obsolete] 752 = Illegal modifier for the local enum {0}; only abstract is permitted
+753 = Illegal modifier for the member enum {0}; only public, protected, private & static are permitted
+754 = The enum {1} already defines the method {0}({2}) implicitly
+755 = The qualified case label {0}.{1} must be replaced with the unqualified enum constant {1}
+756 = The type {1} may not subclass {0} explicitly
+757 = Cannot invoke super constructor from enum constructor {0}({1})
+758 = The enum {2} can only define the abstract method {0}({1}) if it also defines enum constants with corresponding implementations
+759 = The field {0}.{1} cannot be referenced from an enum case label; only enum constants can be used in enum switch
+760 = Illegal modifier for the enum constructor; only private is permitted.
+761 = The enum constant {1} needs a corresponding case label in this enum switch on {0}
+762 = Cannot refer to the static enum field {0}.{1} within an initializer
+763 = The enum constant {2} must implement the abstract method {0}({1})
+764 = The enum constant {0} cannot define abstract methods
+765 = The method {1} cannot be abstract in the enum constant {0}
+766 = The switch over the enum type {0} should have a default case
+767 = The switch statement should have a default case
+768 = The enum constant {1} should have a corresponding case label in this enum switch on {0}. To suppress this problem, add a comment //$CASES-OMITTED$ on the line above the ''default:''
+769 = The local variable {0} may not have been initialized. Note that a problem regarding missing ''default:'' on ''switch'' has been suppressed, which is perhaps related to this problem
+770 = The blank final field {0} may not have been initialized. Note that a problem regarding missing ''default:'' on ''switch'' has been suppressed, which is perhaps related to this problem
+771 = This method must return a result of type {0}. Note that a problem regarding missing ''default:'' on ''switch'' has been suppressed, which is perhaps related to this problem
+
+### VARARGS
+800 = Extended dimensions are illegal for a variable argument
+801 = The argument of type {0} should explicitly be cast to {1} for the invocation of the varargs method {2}({3}) from type {4}. It could alternatively be cast to {5} for a varargs invocation
+802 = The argument of type {0} should explicitly be cast to {1} for the invocation of the varargs constructor {2}({3}). It could alternatively be cast to {4} for a varargs invocation
+803 = Varargs methods should only override or be overridden by other varargs methods unlike {2}.{0}({1}) and {4}.{0}({3})
+804 = @SafeVarargs annotation cannot be applied to fixed arity method {0}
+805 = @SafeVarargs annotation cannot be applied to non-final instance method {0}
+806 = Type safety: Potential heap pollution via varargs parameter {0}
+807 = The method {0}({1}) of type {2} is not applicable as the formal varargs element type {3} is not accessible here
+808 = The constructor {0}({1}) of type {2} is not applicable as the formal varargs element type {3} is not accessible here
+
+### GENERIC JAVADOC
+850 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+851 = The method {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+852 = Incorrect number of type arguments for generic method <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+853 = The parameterized method <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+854 = The method {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
+855 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+856 = The constructor {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+857 = Incorrect number of type arguments for generic constructor <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+859 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
+
+### Java 7
+870 = The parameter {0} of a multi-catch block cannot be assigned
+871 = The resource type {0} does not implement java.lang.AutoCloseable
+872 = The resource {0} of a try-with-resources statement cannot be assigned
+873 = The exception {0} is already caught by the alternative {1}
+874 = Resource specification not allowed here for source level below 1.7
+875 = Multi-catch parameters are not allowed for source level below 1.7
+876 = Invocation of polymorphic methods not allowed for source level below 1.7
+877 = Cannot switch on a value of type {0}. Only convertible int values, strings or enum variables are permitted
+878 = Cannot infer type arguments for {0}
+879 = Explicit type arguments cannot be used with '<>' in an allocation expression
+880 = '<>' cannot be used with anonymous classes
+881 = Cannot switch on a value of type String for source level below 1.7. Only convertible int values or enum variables are permitted
+882 = Unhandled exception type {0} thrown by automatic close() invocation on {1}
+883 = '<>' operator is not allowed for source level below 1.7
+884 = Redundant specification of type arguments <{0}>
+885 = Potential resource leak: ''{0}'' may not be closed
+886 = Potential resource leak: ''{0}'' may not be closed at this location
+887 = Resource leak: ''{0}'' is never closed
+888 = Resource leak: ''{0}'' is not closed at this location
+889 = Resource ''{0}'' should be managed by try-with-resource
+890 = Cannot switch on an enum value for source level below 1.5. Only convertible int values are permitted
+
+#### Java 8
+891 = Additional bounds are not allowed in cast operator at source levels below 1.8
+892 = Base types are not allowed in intersection cast operator
+893 = Arrays are not allowed in intersection cast operator
+894 = Duplicate type in intersection cast operator
+895 = The target type of this expression is not a functional interface: more than one of the intersecting interfaces are functional
+896 = Static methods are allowed in interfaces only at source level 1.8 or above
+
+### NULL ANNOTATIONS
+910 = Null type mismatch: required ''{0}'' but the provided value is null
+911 = Null type mismatch: required ''{0}'' but the provided value is inferred as @{1}
+912 = Null type safety: The expression of type {0} needs unchecked conversion to conform to ''{1}''
+913 = A default nullness annotation has not been specified for the package {0}
+914 = The return type is incompatible with the @{1} return from {0}
+915 = Illegal redefinition of parameter {0}, inherited method from {1} declares this parameter as @{2}
+916 = Illegal redefinition of parameter {0}, inherited method from {1} does not constrain this parameter
+917 = Missing non-null annotation: inherited method from {0} declares this parameter as @{1}
+918 = Missing nullable annotation: inherited method from {0} declares this parameter as @{1}
+919 = Potential null pointer access: The method {0} may return null
+920 = Redundant null check: The method {0} cannot return null
+921 = The method {0} from {1} cannot implement the corresponding method from {2} due to incompatible nullness constraints
+922 = The nullness annotation is redundant with a default that applies to this location
+923 = The nullness annotation @{0} is not applicable for the primitive type {1}
+924 = Potential null pointer access: The field {0} is declared as @{1}
+925 = Nullness default is redundant with the global default
+926 = Nullness default is redundant with a default specified for the enclosing package {0}
+927 = Nullness default is redundant with a default specified for the enclosing type {0}
+928 = Nullness default is redundant with a default specified for the enclosing method {0}
+929 = Contradictory null specification; only one of @{0} and @{1} can be specified at any location
+930 = A default nullness annotation has not been specified for the type {0}
+931 = Redundant null check: The variable {0} is specified as @{1}
+932 = Null comparison always yields false: The variable {0} is specified as @{1}
+933 = Null type mismatch: required ''{0}'' but the provided value is specified as @{1}
+934 = The @{0} field {1} may not have been initialized
+935 = The @{0} field {1} may not have been initialized. Note that a problem regarding missing ''default:'' on ''switch'' has been suppressed, which is perhaps related to this problem
+936 = Null comparison always yields false: The method {0} cannot return null
+937 = Redundant null check: The field {0} is declared as @{1}
+938 = Null comparison always yields false: The field {0} is declared as @{1}
+939 = The default ''@{0}'' conflicts with the inherited ''@{1}'' annotation in the overridden method from {2} 
+940 = Conflict between inherited null annotations ''@{0}'' declared in {1} versus ''@{2}'' declared in {3} 
+
+951 = Potential null pointer access: array element may be null
+952 = Potential null pointer access: this expression has a ''@{0}'' type
+953 = Null type mismatch (type annotations): required ''{0}'' but this expression has type ''{1}''
+954 = Null type mismatch (type annotations): the expression of type ''{1}'' needs unchecked conversion to conform to ''{0}''
+955 = Null type mismatch at parameter {0}: required ''{1}{2}'' but provided ''@{3} {4}'' via method descriptor {5}
+956 = Null type safety: parameter {0} provided via method descriptor {1} needs unchecked conversion to conform to ''@{2} {3}''
+957 = Null type mismatch at method return type: Method descriptor {0} promises ''@{1} {2}'' but referenced method provides ''{3}{4}''
+958 = Null type safety at method return type: Method descriptor {0} promises ''@{1} {2}'' but referenced method provides ''{3}{4}''
+
+# Java 8
+1001 = Syntax error, modifiers and annotations are not allowed for the lambda parameter {0} as its type is elided
+1002 = Syntax error, modifiers are not allowed here
+
+# Default methods:
+# variant of 359: 
+1050 = Illegal modifier for the interface method {0}; only public, abstract, default, static and strictfp are permitted
+1051 = A default method cannot override a method from java.lang.Object 
+1052 = The default method {0} inherited from {1} conflicts with another method inherited from {2}
+1053 = Duplicate default methods named {0} with the parameters ({1}) and ({2}) are inherited from the types {3} and {4}
+1054 = Illegal reference to super type {0}, cannot bypass the more specific direct super type {1}
+1055 = Illegal reference to super method {0} from type {1}, cannot bypass the more specific override from type {2}
+1056 = Illegal combination of modifiers for the interface method {0}; only one of abstract, default, or static permitted
+1057 = strictfp is not permitted for abstract interface method {0}
+
+### ELABORATIONS
+## Access restrictions
+78592 = The type {1} is not accessible due to restriction on classpath entry {0}
+78593 = The type {1} is not accessible due to restriction on required project {0}
+78594 = The type {1} is not accessible due to restriction on required library {0}
+78596 = The field {1} from the type {2} is not accessible due to restriction on classpath entry {0}
+78597 = The field {1} from the type {2} is not accessible due to restriction on required project {0}
+78598 = The field {1} from the type {2} is not accessible due to restriction on required library {0}
+78600 = The constructor {1} is not accessible due to restriction on classpath entry {0}
+78601 = The constructor {1} is not accessible due to restriction on required project {0}
+78602 = The constructor {1} is not accessible due to restriction on required library {0}
+78604 = The method {1} from the type {2} is not accessible due to restriction on classpath entry {0}
+78606 = The method {1} from the type {2} is not accessible due to restriction on required library {0}
+78605 = The method {1} from the type {2} is not accessible due to restriction on required project {0}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java
new file mode 100644
index 0000000..2579f9c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public final class CompoundNameVector {
+	static int INITIAL_SIZE = 10;
+
+	public int size;
+	int maxSize;
+	char[][][] elements;
+public CompoundNameVector() {
+	this.maxSize = INITIAL_SIZE;
+	this.size = 0;
+	this.elements = new char[this.maxSize][][];
+}
+public void add(char[][] newElement) {
+	if (this.size == this.maxSize)    // knows that size starts <= maxSize
+		System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize *= 2][][]), 0, this.size);
+	this.elements[this.size++] = newElement;
+}
+public void addAll(char[][][] newElements) {
+	if (this.size + newElements.length >= this.maxSize) {
+		this.maxSize = this.size + newElements.length;    // assume no more elements will be added
+		System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize][][]), 0, this.size);
+	}
+	System.arraycopy(newElements, 0, this.elements, this.size, newElements.length);
+	this.size += newElements.length;
+}
+public boolean contains(char[][] element) {
+	for (int i = this.size; --i >= 0;)
+		if (CharOperation.equals(element, this.elements[i]))
+			return true;
+	return false;
+}
+public char[][] elementAt(int index) {
+	return this.elements[index];
+}
+public char[][] remove(char[][] element) {
+	// assumes only one occurrence of the element exists
+	for (int i = this.size; --i >= 0;)
+		if (element == this.elements[i]) {
+			// shift the remaining elements down one spot
+			System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i);
+			this.elements[this.size] = null;
+			return element;
+		}
+	return null;
+}
+public void removeAll() {
+	for (int i = this.size; --i >= 0;)
+		this.elements[i] = null;
+	this.size = 0;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	for (int i = 0; i < this.size; i++) {
+		buffer.append(CharOperation.toString(this.elements[i])).append("\n"); //$NON-NLS-1$
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java
new file mode 100644
index 0000000..afd0a2f
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java
@@ -0,0 +1,421 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * Internal utility for declaring with hexadecimal double and float literals.
+ *
+ * @since 3.1
+ */
+public class FloatUtil {
+
+	private static final int DOUBLE_FRACTION_WIDTH = 52;
+
+	private static final int DOUBLE_PRECISION = 53;
+
+	private static final int MAX_DOUBLE_EXPONENT = +1023;
+
+	private static final int MIN_NORMALIZED_DOUBLE_EXPONENT = -1022;
+
+	private static final int MIN_UNNORMALIZED_DOUBLE_EXPONENT = MIN_NORMALIZED_DOUBLE_EXPONENT
+			- DOUBLE_PRECISION;
+
+	private static final int DOUBLE_EXPONENT_BIAS = +1023;
+
+	private static final int DOUBLE_EXPONENT_SHIFT = 52;
+
+	private static final int SINGLE_FRACTION_WIDTH = 23;
+
+	private static final int SINGLE_PRECISION = 24;
+
+	private static final int MAX_SINGLE_EXPONENT = +127;
+
+	private static final int MIN_NORMALIZED_SINGLE_EXPONENT = -126;
+
+	private static final int MIN_UNNORMALIZED_SINGLE_EXPONENT = MIN_NORMALIZED_SINGLE_EXPONENT
+			- SINGLE_PRECISION;
+
+	private static final int SINGLE_EXPONENT_BIAS = +127;
+
+	private static final int SINGLE_EXPONENT_SHIFT = 23;
+
+	/**
+	 * Returns the float value corresponding to the given
+	 * hexadecimal floating-point single precision literal.
+	 * The literal must be syntactically correct, and must be
+	 * a float literal (end in a 'f' or 'F'). It must not
+	 * include either leading or trailing whitespace or
+	 * a sign.
+	 * <p>
+	 * This method returns the same answer as
+	 * Float.parseFloat(new String(source)) does in JDK 1.5,
+	 * except that this method returns Floal.NaN if it
+	 * would underflow to 0 (parseFloat just returns 0).
+	 * The method handles all the tricky cases, including
+	 * fraction rounding to 24 bits and gradual underflow.
+	 * </p>
+	 *
+	 * @param source source string containing single precision
+	 * hexadecimal floating-point literal
+	 * @return the float value, including Float.POSITIVE_INFINITY
+	 * if the non-zero value is too large to be represented, and
+	 * Float.NaN if the non-zero value is too small to be represented
+	 */
+	public static float valueOfHexFloatLiteral(char[] source) {
+		long bits = convertHexFloatingPointLiteralToBits(source);
+		return Float.intBitsToFloat((int) bits);
+	}
+
+	/**
+	 * Returns the double value corresponding to the given
+	 * hexadecimal floating-point double precision literal.
+	 * The literal must be syntactially correct, and must be
+	 * a double literal (end in an optional 'd' or 'D').
+	 * It must not include either leading or trailing whitespace or
+	 * a sign.
+	 * <p>
+	 * This method returns the same answer as
+	 * Double.parseDouble(new String(source)) does in JDK 1.5,
+	 * except that this method throw NumberFormatException in
+	 * the case of overflow to infinity or underflow to 0.
+	 * The method handles all the tricky cases, including
+	 * fraction rounding to 53 bits and gradual underflow.
+	 * </p>
+	 *
+	 * @param source source string containing double precision
+	 * hexadecimal floating-point literal
+	 * @return the double value, including Double.POSITIVE_INFINITY
+	 * if the non-zero value is too large to be represented, and
+	 * Double.NaN if the non-zero value is too small to be represented
+	 */
+	public static double valueOfHexDoubleLiteral(char[] source) {
+		long bits = convertHexFloatingPointLiteralToBits(source);
+		return Double.longBitsToDouble(bits);
+	}
+
+	/**
+	 * Returns the given hexadecimal floating-point literal as
+	 * the bits for a single-precision  (float) or a
+	 * double-precision (double) IEEE floating point number.
+	 * The literal must be syntactically correct.  It must not
+	 * include either leading or trailing whitespace or a sign.
+	 *
+	 * @param source source string containing hexadecimal floating-point literal
+	 * @return for double precision literals, bits suitable
+	 * for passing to Double.longBitsToDouble; for single precision literals,
+	 * bits suitable for passing to Single.intBitsToDouble in the bottom
+	 * 32 bits of the result
+	 * @throws NumberFormatException if the number cannot be parsed
+	 */
+	private static long convertHexFloatingPointLiteralToBits(char[] source) {
+		int length = source.length;
+		long mantissa = 0;
+
+		// Step 1: process the '0x' lead-in
+		int next = 0;
+		char nextChar = source[next];
+		nextChar = source[next];
+		if (nextChar == '0') {
+			next++;
+		} else {
+			throw new NumberFormatException();
+		}
+		nextChar = source[next];
+		if (nextChar == 'X' || nextChar == 'x') {
+			next++;
+		} else {
+			throw new NumberFormatException();
+		}
+
+		// Step 2: process leading '0's either before or after the '.'
+		int binaryPointPosition = -1;
+		loop: while (true) {
+			nextChar = source[next];
+			switch (nextChar) {
+			case '0':
+				next++;
+				continue loop;
+			case '.':
+				binaryPointPosition = next;
+				next++;
+				continue loop;
+			default:
+				break loop;
+			}
+		}
+
+		// Step 3: process the mantissa
+		// leading zeros have been trimmed
+		int mantissaBits = 0;
+		int leadingDigitPosition = -1;
+		loop: while (true) {
+			nextChar = source[next];
+			int hexdigit;
+			switch (nextChar) {
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				hexdigit = nextChar - '0';
+				break;
+			case 'a':
+			case 'b':
+			case 'c':
+			case 'd':
+			case 'e':
+			case 'f':
+				hexdigit = (nextChar - 'a') + 10;
+				break;
+			case 'A':
+			case 'B':
+			case 'C':
+			case 'D':
+			case 'E':
+			case 'F':
+				hexdigit = (nextChar - 'A') + 10;
+				break;
+			case '.':
+				binaryPointPosition = next;
+				next++;
+				continue loop;
+			default:
+				if (binaryPointPosition < 0) {
+					// record virtual '.' as being to right of all digits
+					binaryPointPosition = next;
+				}
+				break loop;
+			}
+			if (mantissaBits == 0) {
+				// this is the first non-zero hex digit
+				// ignore leading binary 0's in hex digit
+				leadingDigitPosition = next;
+				mantissa = hexdigit;
+				mantissaBits = 4;
+			} else if (mantissaBits < 60) {
+				// middle hex digits
+				mantissa <<= 4;
+				mantissa |= hexdigit;
+				mantissaBits += 4;
+			} else {
+				// more mantissa bits than we can handle
+				// drop this hex digit on the ground
+			}
+			next++;
+			continue loop;
+		}
+
+		// Step 4: process the 'P'
+		nextChar = source[next];
+		if (nextChar == 'P' || nextChar == 'p') {
+			next++;
+		} else {
+			throw new NumberFormatException();
+		}
+
+		// Step 5: process the exponent
+		int exponent = 0;
+		int exponentSign = +1;
+		loop: while (next < length) {
+			nextChar = source[next];
+			switch (nextChar) {
+			case '+':
+				exponentSign = +1;
+				next++;
+				continue loop;
+			case '-':
+				exponentSign = -1;
+				next++;
+				continue loop;
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				int digit = nextChar - '0';
+				exponent = (exponent * 10) + digit;
+				next++;
+				continue loop;
+			default:
+				break loop;
+			}
+		}
+
+		// Step 6: process the optional 'f' or 'd'
+		boolean doublePrecision = true;
+		if (next < length) {
+			nextChar = source[next];
+			switch (nextChar) {
+			case 'f':
+			case 'F':
+				doublePrecision = false;
+				next++;
+				break;
+			case 'd':
+			case 'D':
+				doublePrecision = true;
+				next++;
+				break;
+			default:
+				throw new NumberFormatException();
+			}
+		}
+
+		// at this point, all the parsing is done
+		// Step 7: handle mantissa of zero
+		if (mantissa == 0) {
+			return 0L;
+		}
+
+		// Step 8: normalize non-zero mantissa
+		// mantissa is in right-hand mantissaBits
+		// ensure that top bit (as opposed to hex digit) is 1
+		int scaleFactorCompensation = 0;
+		long top = (mantissa >>> (mantissaBits - 4));
+		if ((top & 0x8) == 0) {
+			mantissaBits--;
+			scaleFactorCompensation++;
+			if ((top & 0x4) == 0) {
+				mantissaBits--;
+				scaleFactorCompensation++;
+				if ((top & 0x2) == 0) {
+					mantissaBits--;
+					scaleFactorCompensation++;
+				}
+			}
+		}
+
+		// Step 9: convert double literals to IEEE double
+		long result = 0L;
+		if (doublePrecision) {
+			long fraction;
+			if (mantissaBits > DOUBLE_PRECISION) {
+				// more bits than we can keep
+				int extraBits = mantissaBits - DOUBLE_PRECISION;
+				// round to DOUBLE_PRECISION bits
+				fraction = mantissa >>> (extraBits - 1);
+				long lowBit = fraction & 0x1;
+				fraction += lowBit;
+				fraction = fraction >>> 1;
+				if ((fraction & (1L << DOUBLE_PRECISION)) != 0) {
+					fraction = fraction >>> 1;
+					scaleFactorCompensation -= 1;
+				}
+			} else {
+				// less bits than the faction can hold - pad on right with 0s
+				fraction = mantissa << (DOUBLE_PRECISION - mantissaBits);
+			}
+
+			int scaleFactor = 0; // how many bits to move '.' to before leading hex digit
+			if (mantissaBits > 0) {
+				if (leadingDigitPosition < binaryPointPosition) {
+					// e.g., 0x80.0p0 has scaleFactor == +8
+					scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition);
+					// e.g., 0x10.0p0 has scaleFactorCompensation == +3
+					scaleFactor -= scaleFactorCompensation;
+				} else {
+					// e.g., 0x0.08p0 has scaleFactor == -4
+					scaleFactor = -4
+							* (leadingDigitPosition - binaryPointPosition - 1);
+					// e.g., 0x0.01p0 has scaleFactorCompensation == +3
+					scaleFactor -= scaleFactorCompensation;
+				}
+			}
+
+			int e = (exponentSign * exponent) + scaleFactor;
+			if (e - 1 > MAX_DOUBLE_EXPONENT) {
+				// overflow to +infinity
+				result = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
+			} else if (e - 1 >= MIN_NORMALIZED_DOUBLE_EXPONENT) {
+				// can be represented as a normalized double
+				// the left most bit must be discarded (it's always a 1)
+				long biasedExponent = e - 1 + DOUBLE_EXPONENT_BIAS;
+				result = fraction & ~(1L << DOUBLE_FRACTION_WIDTH);
+				result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT);
+			} else if (e - 1 > MIN_UNNORMALIZED_DOUBLE_EXPONENT) {
+				// can be represented as an unnormalized double
+				long biasedExponent = 0;
+				result = fraction >>> (MIN_NORMALIZED_DOUBLE_EXPONENT - e + 1);
+				result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT);
+			} else {
+				// underflow - return Double.NaN
+				result = Double.doubleToLongBits(Double.NaN);
+			}
+			return result;
+		}
+
+		// Step 10: convert float literals to IEEE single
+		long fraction;
+		if (mantissaBits > SINGLE_PRECISION) {
+			// more bits than we can keep
+			int extraBits = mantissaBits - SINGLE_PRECISION;
+			// round to DOUBLE_PRECISION bits
+			fraction = mantissa >>> (extraBits - 1);
+			long lowBit = fraction & 0x1;
+			fraction += lowBit;
+			fraction = fraction >>> 1;
+			if ((fraction & (1L << SINGLE_PRECISION)) != 0) {
+				fraction = fraction >>> 1;
+				scaleFactorCompensation -= 1;
+			}
+		} else {
+			// less bits than the faction can hold - pad on right with 0s
+			fraction = mantissa << (SINGLE_PRECISION - mantissaBits);
+		}
+
+		int scaleFactor = 0; // how many bits to move '.' to before leading hex digit
+		if (mantissaBits > 0) {
+			if (leadingDigitPosition < binaryPointPosition) {
+				// e.g., 0x80.0p0 has scaleFactor == +8
+				scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition);
+				// e.g., 0x10.0p0 has scaleFactorCompensation == +3
+				scaleFactor -= scaleFactorCompensation;
+			} else {
+				// e.g., 0x0.08p0 has scaleFactor == -4
+				scaleFactor = -4
+						* (leadingDigitPosition - binaryPointPosition - 1);
+				// e.g., 0x0.01p0 has scaleFactorCompensation == +3
+				scaleFactor -= scaleFactorCompensation;
+			}
+		}
+
+		int e = (exponentSign * exponent) + scaleFactor;
+		if (e - 1 > MAX_SINGLE_EXPONENT) {
+			// overflow to +infinity
+			result = Float.floatToIntBits(Float.POSITIVE_INFINITY);
+		} else if (e - 1 >= MIN_NORMALIZED_SINGLE_EXPONENT) {
+			// can be represented as a normalized single
+			// the left most bit must be discarded (it's always a 1)
+			long biasedExponent = e - 1 + SINGLE_EXPONENT_BIAS;
+			result = fraction & ~(1L << SINGLE_FRACTION_WIDTH);
+			result |= (biasedExponent << SINGLE_EXPONENT_SHIFT);
+		} else if (e - 1 > MIN_UNNORMALIZED_SINGLE_EXPONENT) {
+			// can be represented as an unnormalized single
+			long biasedExponent = 0;
+			result = fraction >>> (MIN_NORMALIZED_SINGLE_EXPONENT - e + 1);
+			result |= (biasedExponent << SINGLE_EXPONENT_SHIFT);
+		} else {
+			// underflow - return Float.NaN
+			result = Float.floatToIntBits(Float.NaN);
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/GenericXMLWriter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/GenericXMLWriter.java
new file mode 100644
index 0000000..e5b8983
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/GenericXMLWriter.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GenericXMLWriter extends PrintWriter {
+	/* constants */
+	private static final String XML_VERSION= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$
+	private static void appendEscapedChar(StringBuffer buffer, char c) {
+		String replacement= getReplacement(c);
+		if (replacement != null) {
+			buffer.append('&');
+			buffer.append(replacement);
+			buffer.append(';');
+		} else {
+			buffer.append(c);
+		}
+	}
+	private static String getEscaped(String s) {
+		StringBuffer result= new StringBuffer(s.length() + 10);
+		for (int i= 0; i < s.length(); ++i)
+			appendEscapedChar(result, s.charAt(i));
+		return result.toString();
+	}
+	private static String getReplacement(char c) {
+		// Encode special XML characters into the equivalent character references.
+		// These five are defined by default for all XML documents.
+		switch (c) {
+			case '<' :
+				return "lt"; //$NON-NLS-1$
+			case '>' :
+				return "gt"; //$NON-NLS-1$
+			case '"' :
+				return "quot"; //$NON-NLS-1$
+			case '\'' :
+				return "apos"; //$NON-NLS-1$
+			case '&' :
+				return "amp"; //$NON-NLS-1$
+		}
+		return null;
+	}
+	private String lineSeparator;
+	private int tab;
+	public GenericXMLWriter(OutputStream stream, String lineSeparator, boolean printXmlVersion) {
+		this(new PrintWriter(stream), lineSeparator, printXmlVersion);
+	}
+	public GenericXMLWriter(Writer writer, String lineSeparator, boolean printXmlVersion) {
+		super(writer);
+		this.tab= 0;
+		this.lineSeparator = lineSeparator;
+		if (printXmlVersion) {
+			print(XML_VERSION);
+			print(this.lineSeparator);
+		}
+	}
+	public void endTag(String name, boolean insertTab, boolean insertNewLine) {
+		this.tab --;
+		printTag('/' + name, null/*no parameters*/, insertTab, insertNewLine, false/*don't close tag*/);
+	}
+	/*
+	 * External API
+	 */
+	public void printString(String string, boolean insertTab, boolean insertNewLine) {
+		if (insertTab) {
+			printTabulation();
+		}
+		print(string);
+		if (insertNewLine) {
+			print(this.lineSeparator);
+		}
+	}
+	private void printTabulation() {
+		for (int i= 0; i < this.tab; i++) this.print('\t');
+	}
+	public void printTag(String name, HashMap parameters, boolean insertTab, boolean insertNewLine, boolean closeTag) {
+		if (insertTab) {
+			printTabulation();
+		}
+		this.print('<');
+		this.print(name);
+		if (parameters != null) {
+			int length = parameters.size();
+			Map.Entry[] entries = new Map.Entry[length];
+			parameters.entrySet().toArray(entries);
+			Arrays.sort(entries, new Comparator() {
+				public int compare(Object o1, Object o2) {
+					Map.Entry entry1 = (Map.Entry) o1;
+					Map.Entry entry2 = (Map.Entry) o2;
+					return ((String) entry1.getKey()).compareTo((String) entry2.getKey());
+				}
+			});
+			for (int i = 0; i < length; i++) {
+				this.print(' ');
+				this.print(entries[i].getKey());
+				this.print("=\""); //$NON-NLS-1$
+				this.print(getEscaped(String.valueOf(entries[i].getValue())));
+				this.print('\"');
+			}
+		}
+		if (closeTag) {
+			this.print("/>"); //$NON-NLS-1$
+		} else {
+			this.print(">"); //$NON-NLS-1$
+		}
+		if (insertNewLine) {
+			print(this.lineSeparator);
+		}
+		if (parameters != null && !closeTag)
+			this.tab++;
+
+	}
+	public void startTag(String name, boolean insertTab) {
+		printTag(name, null/*no parameters*/, insertTab, true/*insert new line*/, false/*don't close tag*/);
+		this.tab++;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashSetOfInt.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashSetOfInt.java
new file mode 100644
index 0000000..61ae2dd
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashSetOfInt.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * HashSet of Object[]
+ */
+public final class HashSetOfInt implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public int[] set;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashSetOfInt() {
+		this(13);
+	}
+
+	public HashSetOfInt(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.set = new int[extraRoom];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashSetOfInt result = (HashSetOfInt) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.set.length;
+		result.set = new int[length];
+		System.arraycopy(this.set, 0, result.set, 0, length);
+
+		return result;
+	}
+
+	public boolean contains(int element) {
+		int length = this.set.length;
+		int index = element % length;
+		int currentElement;
+		while ((currentElement = this.set[index]) != 0) {
+			if (currentElement == element)
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public int add(int element) {
+		int length = this.set.length;
+		int index = element % length;
+		int currentElement;
+		while ((currentElement = this.set[index]) != 0) {
+			if (currentElement == element)
+				return this.set[index] = element;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.set[index] = element;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return element;
+	}
+
+	public int remove(int element) {
+		int length = this.set.length;
+		int index = element % length;
+		int currentElement;
+		while ((currentElement = this.set[index]) != 0) {
+			if (currentElement == element) {
+				int existing = this.set[index];
+				this.elementSize--;
+				this.set[index] = 0;
+				rehash();
+				return existing;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return 0;
+	}
+
+	private void rehash() {
+
+		HashSetOfInt newHashSet = new HashSetOfInt(this.elementSize * 2);		// double the number of expected elements
+		int currentElement;
+		for (int i = this.set.length; --i >= 0;)
+			if ((currentElement = this.set[i]) != 0)
+				newHashSet.add(currentElement);
+
+		this.set = newHashSet.set;
+		this.threshold = newHashSet.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		int element;
+		for (int i = 0, length = this.set.length; i < length; i++)
+			if ((element = this.set[i]) != 0) {
+				buffer.append(element);
+				if (i != length-1)
+					buffer.append('\n');
+			}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java
new file mode 100644
index 0000000..911fbbc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+ /**
+  *	Hashtable for non-zero int keys.
+  */
+
+public final class HashtableOfInt {
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public int[] keyTable;
+	public Object[] valueTable;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+public HashtableOfInt() {
+	this(13);
+}
+public HashtableOfInt(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.keyTable = new int[extraRoom];
+	this.valueTable = new Object[extraRoom];
+}
+public boolean containsKey(int key) {
+	int length = this.keyTable.length, index = key % length;
+	int currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+public Object get(int key) {
+	int length = this.keyTable.length, index = key % length;
+	int currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)  return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return null;
+}
+public Object put(int key, Object value) {
+	int length = this.keyTable.length, index = key % length;
+	int currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)  return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+private void rehash() {
+	HashtableOfInt newHashtable = new HashtableOfInt(this.elementSize * 2); // double the number of expected elements
+	int currentKey;
+	for (int i = this.keyTable.length; --i >= 0;)
+		if ((currentKey = this.keyTable[i]) != 0)
+			newHashtable.put(currentKey, this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+public int size() {
+	return this.elementSize;
+}
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	Object object;
+	for (int i = 0, length = this.valueTable.length; i < length; i++)
+		if ((object = this.valueTable[i]) != null)
+			s += this.keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java
new file mode 100644
index 0000000..5e743b0
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * Hashtable of {char[] --> int}
+ */
+public final class HashtableOfIntValues implements Cloneable {
+
+	public static final int NO_VALUE = Integer.MIN_VALUE;
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[] keyTable[];
+	public int valueTable[];
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashtableOfIntValues() {
+		this(13);
+	}
+
+	public HashtableOfIntValues(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.keyTable = new char[extraRoom][];
+		this.valueTable = new int[extraRoom];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashtableOfIntValues result = (HashtableOfIntValues) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.keyTable.length;
+		result.keyTable = new char[length][];
+		System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+		length = this.valueTable.length;
+		result.valueTable = new int[length];
+		System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+		return result;
+	}
+
+	public boolean containsKey(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public int get(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return this.valueTable[index];
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return NO_VALUE;
+	}
+
+	public int put(char[] key, int value) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return this.valueTable[index] = value;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return value;
+	}
+
+	public int removeKey(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key)) {
+				int value = this.valueTable[index];
+				this.elementSize--;
+				this.keyTable[index] = null;
+				this.valueTable[index] = NO_VALUE;
+				rehash();
+				return value;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return NO_VALUE;
+	}
+
+	private void rehash() {
+
+		HashtableOfIntValues newHashtable = new HashtableOfIntValues(this.elementSize * 2);		// double the number of expected elements
+		char[] currentKey;
+		for (int i = this.keyTable.length; --i >= 0;)
+			if ((currentKey = this.keyTable[i]) != null)
+				newHashtable.put(currentKey, this.valueTable[i]);
+
+		this.keyTable = newHashtable.keyTable;
+		this.valueTable = newHashtable.valueTable;
+		this.threshold = newHashtable.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		String s = ""; //$NON-NLS-1$
+		char[] key;
+		for (int i = 0, length = this.valueTable.length; i < length; i++)
+			if ((key = this.keyTable[i]) != null)
+				s += new String(key) + " -> " + this.valueTable[i] + "\n"; 	//$NON-NLS-2$ //$NON-NLS-1$
+		return s;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java
new file mode 100644
index 0000000..9315733
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+ /**
+  *	Hashtable for non-zero long keys.
+  */
+
+public final class HashtableOfLong {
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public long[] keyTable;
+	public Object[] valueTable;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+public HashtableOfLong() {
+	this(13);
+}
+public HashtableOfLong(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.keyTable = new long[extraRoom];
+	this.valueTable = new Object[extraRoom];
+}
+public boolean containsKey(long key) {
+	int length = this.keyTable.length,
+		index = ((int)(key >>> 32)) % length;
+	long currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+public Object get(long key) {
+	int length = this.keyTable.length,
+		index = ((int)(key >>> 32)) % length;
+	long currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)  return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return null;
+}
+public Object put(long key, Object value) {
+	int length = this.keyTable.length,
+		index = ((int)(key >>> 32)) % length;
+	long currentKey;
+	while ((currentKey = this.keyTable[index]) != 0) {
+		if (currentKey == key)  return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+private void rehash() {
+	HashtableOfLong newHashtable = new HashtableOfLong(this.elementSize * 2); // double the number of expected elements
+	long currentKey;
+	for (int i = this.keyTable.length; --i >= 0;)
+		if ((currentKey = this.keyTable[i]) != 0)
+			newHashtable.put(currentKey, this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+public int size() {
+	return this.elementSize;
+}
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	Object object;
+	for (int i = 0, length = this.valueTable.length; i < length; i++)
+		if ((object = this.valueTable[i]) != null)
+			s += this.keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java
new file mode 100644
index 0000000..48912ab
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * Hashtable of {char[] --> Object }
+ */
+public final class HashtableOfObject implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[] keyTable[];
+	public Object valueTable[];
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashtableOfObject() {
+		this(13);
+	}
+
+	public HashtableOfObject(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.keyTable = new char[extraRoom][];
+		this.valueTable = new Object[extraRoom];
+	}
+
+	public void clear() {
+		for (int i = this.keyTable.length; --i >= 0;) {
+			this.keyTable[i] = null;
+			this.valueTable[i] = null;
+		}
+		this.elementSize = 0;
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashtableOfObject result = (HashtableOfObject) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.keyTable.length;
+		result.keyTable = new char[length][];
+		System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+		length = this.valueTable.length;
+		result.valueTable = new Object[length];
+		System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+		return result;
+	}
+
+	public boolean containsKey(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public Object get(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return this.valueTable[index];
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	public Object put(char[] key, Object value) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+				return this.valueTable[index] = value;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return value;
+	}
+
+	/**
+	 * Put a value at the index of the given using the local hash code computation.
+	 * <p>
+	 * Note that this is an unsafe put as there's no prior verification whether
+	 * the given key already exists in the table or not.
+	 * </p>
+	 * @param key The key of the table entry
+	 * @param value The value of the table entry
+	 */
+	public void putUnsafely(char[] key, Object value) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		while (this.keyTable[index] != null) {
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+	
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold) {
+			rehash();
+		}
+	}
+
+	public Object removeKey(char[] key) {
+		int length = this.keyTable.length,
+			index = CharOperation.hashCode(key) % length;
+		int keyLength = key.length;
+		char[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && CharOperation.equals(currentKey, key)) {
+				Object value = this.valueTable[index];
+				this.elementSize--;
+				this.keyTable[index] = null;
+				this.valueTable[index] = null;
+				rehash();
+				return value;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+
+		HashtableOfObject newHashtable = new HashtableOfObject(this.elementSize * 2);		// double the number of expected elements
+		char[] currentKey;
+		for (int i = this.keyTable.length; --i >= 0;)
+			if ((currentKey = this.keyTable[i]) != null)
+				newHashtable.putUnsafely(currentKey, this.valueTable[i]);
+
+		this.keyTable = newHashtable.keyTable;
+		this.valueTable = newHashtable.valueTable;
+		this.threshold = newHashtable.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		String s = ""; //$NON-NLS-1$
+		Object object;
+		for (int i = 0, length = this.valueTable.length; i < length; i++)
+			if ((object = this.valueTable[i]) != null)
+				s += new String(this.keyTable[i]) + " -> " + object.toString() + "\n"; 	//$NON-NLS-2$ //$NON-NLS-1$
+		return s;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java
new file mode 100644
index 0000000..214325a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * Hashtable of {Object --> int }
+ */
+public final class HashtableOfObjectToInt implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public Object[] keyTable;
+	public int[] valueTable;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashtableOfObjectToInt() {
+		this(13);
+	}
+
+	public HashtableOfObjectToInt(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.keyTable = new Object[extraRoom];
+		this.valueTable = new int[extraRoom];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashtableOfObjectToInt result = (HashtableOfObjectToInt) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.keyTable.length;
+		result.keyTable = new Object[length];
+		System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+		length = this.valueTable.length;
+		result.valueTable = new int[length];
+		System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+		return result;
+	}
+
+	public boolean containsKey(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public int get(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return this.valueTable[index];
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return -1;
+	}
+
+	public void keysToArray(Object[] array) {
+		int index = 0;
+		for (int i=0, length=this.keyTable.length; i<length; i++) {
+			if (this.keyTable[i] != null)
+				array[index++] = this.keyTable[i];
+		}
+	}
+
+	public int put(Object key, int value) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return this.valueTable[index] = value;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return value;
+	}
+
+	public int removeKey(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key)) {
+				int value = this.valueTable[index];
+				this.elementSize--;
+				this.keyTable[index] = null;
+				rehash();
+				return value;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return -1;
+	}
+
+	private void rehash() {
+
+		HashtableOfObjectToInt newHashtable = new HashtableOfObjectToInt(this.elementSize * 2);		// double the number of expected elements
+		Object currentKey;
+		for (int i = this.keyTable.length; --i >= 0;)
+			if ((currentKey = this.keyTable[i]) != null)
+				newHashtable.put(currentKey, this.valueTable[i]);
+
+		this.keyTable = newHashtable.keyTable;
+		this.valueTable = newHashtable.valueTable;
+		this.threshold = newHashtable.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		String s = ""; //$NON-NLS-1$
+		Object key;
+		for (int i = 0, length = this.keyTable.length; i < length; i++)
+			if ((key = this.keyTable[i]) != null)
+				s += key + " -> " + this.valueTable[i] + "\n"; 	//$NON-NLS-2$ //$NON-NLS-1$
+		return s;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java
new file mode 100644
index 0000000..624542b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * Hashtable of {Object --> int[] }
+ */
+public final class HashtableOfObjectToIntArray implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public Object[] keyTable;
+	public int[][] valueTable;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashtableOfObjectToIntArray() {
+		this(13);
+	}
+
+	public HashtableOfObjectToIntArray(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.keyTable = new Object[extraRoom];
+		this.valueTable = new int[extraRoom][];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashtableOfObjectToIntArray result = (HashtableOfObjectToIntArray) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.keyTable.length;
+		result.keyTable = new Object[length];
+		System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+		length = this.valueTable.length;
+		result.valueTable = new int[length][];
+		System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+		return result;
+	}
+
+	public boolean containsKey(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public int[] get(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return this.valueTable[index];
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	public void keysToArray(Object[] array) {
+		int index = 0;
+		for (int i=0, length=this.keyTable.length; i<length; i++) {
+			if (this.keyTable[i] != null)
+				array[index++] = this.keyTable[i];
+		}
+	}
+
+	public int[] put(Object key, int[] value) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key))
+				return this.valueTable[index] = value;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return value;
+	}
+
+	public int[] removeKey(Object key) {
+		int length = this.keyTable.length,
+			index = (key.hashCode()& 0x7FFFFFFF) % length;
+		Object currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.equals(key)) {
+				int[] value = this.valueTable[index];
+				this.elementSize--;
+				this.keyTable[index] = null;
+				rehash();
+				return value;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+
+		HashtableOfObjectToIntArray newHashtable = new HashtableOfObjectToIntArray(this.elementSize * 2);		// double the number of expected elements
+		Object currentKey;
+		for (int i = this.keyTable.length; --i >= 0;)
+			if ((currentKey = this.keyTable[i]) != null)
+				newHashtable.put(currentKey, this.valueTable[i]);
+
+		this.keyTable = newHashtable.keyTable;
+		this.valueTable = newHashtable.valueTable;
+		this.threshold = newHashtable.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		Object key;
+		for (int i = 0, length = this.keyTable.length; i < length; i++) {
+			if ((key = this.keyTable[i]) != null) {
+				buffer.append(key).append(" -> "); //$NON-NLS-1$
+				int[] ints = this.valueTable[i];
+				buffer.append('[');
+				if (ints != null) {
+					for (int j = 0, max = ints.length; j < max; j++) {
+						if (j > 0) {
+							buffer.append(',');
+						}
+						buffer.append(ints[j]);
+					}
+				}
+				buffer.append("]\n"); //$NON-NLS-1$
+			}
+		}
+		return String.valueOf(buffer);
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java
new file mode 100644
index 0000000..1ef7dae
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+
+public final class HashtableOfPackage {
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[] keyTable[];
+	public PackageBinding valueTable[];
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+public HashtableOfPackage() {
+	this(3); // usually not very large
+}
+public HashtableOfPackage(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.keyTable = new char[extraRoom][];
+	this.valueTable = new PackageBinding[extraRoom];
+}
+public boolean containsKey(char[] key) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+public PackageBinding get(char[] key) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return null;
+}
+public PackageBinding put(char[] key, PackageBinding value) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+private void rehash() {
+	HashtableOfPackage newHashtable = new HashtableOfPackage(this.elementSize * 2); // double the number of expected elements
+	char[] currentKey;
+	for (int i = this.keyTable.length; --i >= 0;)
+		if ((currentKey = this.keyTable[i]) != null)
+			newHashtable.put(currentKey, this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+public int size() {
+	return this.elementSize;
+}
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	PackageBinding pkg;
+	for (int i = 0, length = this.valueTable.length; i < length; i++)
+		if ((pkg = this.valueTable[i]) != null)
+			s += pkg.toString() + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java
new file mode 100644
index 0000000..7931e51
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+
+public final class HashtableOfType {
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[] keyTable[];
+	public ReferenceBinding valueTable[];
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+public HashtableOfType() {
+	this(3);
+}
+public HashtableOfType(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.keyTable = new char[extraRoom][];
+	this.valueTable = new ReferenceBinding[extraRoom];
+}
+public boolean containsKey(char[] key) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return true;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return false;
+}
+public ReferenceBinding get(char[] key) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return this.valueTable[index];
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return null;
+}
+public ReferenceBinding put(char[] key, ReferenceBinding value) {
+	int length = this.keyTable.length,
+		index = CharOperation.hashCode(key) % length;
+	int keyLength = key.length;
+	char[] currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.length == keyLength && CharOperation.equals(currentKey, key))
+			return this.valueTable[index] = value;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold)
+		rehash();
+	return value;
+}
+private void rehash() {
+	HashtableOfType newHashtable = new HashtableOfType(this.elementSize < 100 ? 100 : this.elementSize * 2); // double the number of expected elements
+	char[] currentKey;
+	for (int i = this.keyTable.length; --i >= 0;)
+		if ((currentKey = this.keyTable[i]) != null)
+			newHashtable.put(currentKey, this.valueTable[i]);
+
+	this.keyTable = newHashtable.keyTable;
+	this.valueTable = newHashtable.valueTable;
+	this.threshold = newHashtable.threshold;
+}
+public int size() {
+	return this.elementSize;
+}
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	ReferenceBinding type;
+	for (int i = 0, length = this.valueTable.length; i < length; i++)
+		if ((type = this.valueTable[i]) != null)
+			s += type.toString() + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ManifestAnalyzer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ManifestAnalyzer.java
new file mode 100644
index 0000000..a1e42a6
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ManifestAnalyzer.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ManifestAnalyzer {
+	private static final int
+		START = 0,
+		IN_CLASSPATH_HEADER = 1, // multistate
+		PAST_CLASSPATH_HEADER = 2,
+		SKIPPING_WHITESPACE = 3,
+		READING_JAR = 4,
+		CONTINUING = 5,
+		SKIP_LINE = 6;
+	private static final char[] CLASSPATH_HEADER_TOKEN =
+		"Class-Path:".toCharArray(); //$NON-NLS-1$
+	private int classpathSectionsCount;
+	private ArrayList calledFilesNames;
+	
+	/**
+	 * Analyze the manifest contents. The given input stream is read using a UTF-8 encoded reader.
+	 * If the contents of the input stream is not encoded using a UTF-8 encoding, the analysis will fail.
+	 * 
+	 * @param inputStream the given input stream.
+	 * 
+	 * @return <code>true</code> if the analysis is successful, <code>false</code> otherwise.
+	 * @throws IOException if an exception occurs while analyzing the file
+	 */
+	public boolean analyzeManifestContents(InputStream inputStream) throws IOException {
+		char[] chars = Util.getInputStreamAsCharArray(inputStream, -1, Util.UTF_8);
+		int state = START, substate = 0;
+		StringBuffer currentJarToken = new StringBuffer();
+		int currentChar;
+		this.classpathSectionsCount = 0;
+		this.calledFilesNames = null;
+		for (int i = 0, max = chars.length; i < max;) {
+			currentChar = chars[i++];
+			if (currentChar == '\r') {
+				// skip \r, will consider \n later (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=251079 )
+				if (i < max) {
+					currentChar = chars[i++];
+				}
+			}
+			switch (state) {
+				case START:
+					if (currentChar == CLASSPATH_HEADER_TOKEN[0]) {
+						state = IN_CLASSPATH_HEADER;
+						substate = 1;
+					} else {
+						state = SKIP_LINE;
+					}
+					break;
+				case IN_CLASSPATH_HEADER:
+					if (currentChar == '\n') {
+						state = START;
+					} else if (currentChar != CLASSPATH_HEADER_TOKEN[substate++]) {
+						state = SKIP_LINE;
+					} else if (substate == CLASSPATH_HEADER_TOKEN.length) {
+						state = PAST_CLASSPATH_HEADER;
+					}
+					break;
+				case PAST_CLASSPATH_HEADER:
+					if (currentChar == ' ') {
+						state = SKIPPING_WHITESPACE;
+						this.classpathSectionsCount++;
+					} else {
+						return false;
+					}
+					break;
+				case SKIPPING_WHITESPACE:
+					if (currentChar == '\n') {
+						state = CONTINUING;
+					} else if (currentChar != ' ') {
+						currentJarToken.append((char) currentChar);
+						state = READING_JAR;
+					} else {
+						// >>>>>>>>>>>>>>>>>> Add the latest jar read
+						addCurrentTokenJarWhenNecessary(currentJarToken);
+					}
+					break;
+				case CONTINUING:
+					if (currentChar == '\n') {
+						addCurrentTokenJarWhenNecessary(currentJarToken);
+						state = START;
+					} else if (currentChar == ' ') {
+						state = SKIPPING_WHITESPACE;
+					} else if (currentChar == CLASSPATH_HEADER_TOKEN[0]) {
+						addCurrentTokenJarWhenNecessary(currentJarToken);
+						state = IN_CLASSPATH_HEADER;
+						substate = 1;
+					} else if (this.calledFilesNames == null) {
+						// >>>>>>>>>>>>>>>>>> Add the latest jar read
+						addCurrentTokenJarWhenNecessary(currentJarToken);
+						state = START;
+					} else {
+						// >>>>>>>>>>>>>>>>>> Add the latest jar read
+						addCurrentTokenJarWhenNecessary(currentJarToken);
+						state = SKIP_LINE;
+					}
+					break;
+				case SKIP_LINE:
+					if (currentChar == '\n') {
+						state = START;
+					}
+					break;
+				case READING_JAR:
+					if (currentChar == '\n') {
+						// appends token below
+						state = CONTINUING;
+						// >>>>>>>>>>> Add a break to not add the jar yet as it can continue on the next line
+						break;
+					} else if (currentChar == ' ') {
+						// appends token below
+						state = SKIPPING_WHITESPACE;
+					} else {
+						currentJarToken.append((char) currentChar);
+						break;
+					}
+					addCurrentTokenJarWhenNecessary(currentJarToken);
+					break;
+			}
+		}
+		switch (state) {
+			case START:
+				return true;
+			case IN_CLASSPATH_HEADER:
+				return true;
+			case PAST_CLASSPATH_HEADER:
+				return false;
+			case SKIPPING_WHITESPACE:
+				// >>>>>>>>>>>>>>>>>> Add the latest jar read
+				addCurrentTokenJarWhenNecessary(currentJarToken);
+				return true;
+			case CONTINUING:
+				// >>>>>>>>>>>>>>>>>> Add the latest jar read
+				addCurrentTokenJarWhenNecessary(currentJarToken);
+				return true;
+			case SKIP_LINE:
+				if (this.classpathSectionsCount != 0) {
+					if (this.calledFilesNames == null) {
+						return false;
+					}
+				}
+				return true;
+			case READING_JAR:
+				// >>>>>>>>>>>>>>>>>> Add the latest jar read
+				return false;
+		}
+		return true;
+	}
+
+	// >>>>>>>>>>>>>>>> Method Extracted from analyzeManifestContents in the READING_JAR Block
+	private boolean addCurrentTokenJarWhenNecessary(StringBuffer currentJarToken) {
+		if (currentJarToken != null && currentJarToken.length() > 0) {
+			if (this.calledFilesNames == null) {
+				this.calledFilesNames = new ArrayList();
+			}
+			this.calledFilesNames.add(currentJarToken.toString());
+			currentJarToken.setLength(0);
+			return true;
+		}
+		return false;
+	}
+	// <<<<<<<<<<<<<<<<<<<<<<
+
+
+	public int getClasspathSectionsCount() {
+		return this.classpathSectionsCount;
+	}
+	public List getCalledFileNames() {
+		return this.calledFilesNames;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
new file mode 100644
index 0000000..6e4b2bc
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
@@ -0,0 +1,245 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+public final class Messages {
+	private static class MessagesProperties extends Properties {
+
+		private static final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
+		private static final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
+		private static final long serialVersionUID = 1L;
+
+		private final Map fields;
+
+		public MessagesProperties(Field[] fieldArray, String bundleName) {
+			super();
+			final int len = fieldArray.length;
+			this.fields = new HashMap(len * 2);
+			for (int i = 0; i < len; i++) {
+				this.fields.put(fieldArray[i].getName(), fieldArray[i]);
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object)
+		 */
+		public synchronized Object put(Object key, Object value) {
+			try {
+				Field field = (Field) this.fields.get(key);
+				if (field == null) {
+					return null;
+				}
+				//can only set value of public static non-final fields
+				if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
+					return null;
+				// Set the value into the field. We should never get an exception here because
+				// we know we have a public static non-final field. If we do get an exception, silently
+				// log it and continue. This means that the field will (most likely) be un-initialized and
+				// will fail later in the code and if so then we will see both the NPE and this error.
+				try {
+					field.set(null, value);
+				} catch (Exception e) {
+					// ignore
+				}
+			} catch (SecurityException e) {
+				// ignore
+			}
+			return null;
+		}
+	}
+
+
+	private static String[] nlSuffixes;
+	private static final String EXTENSION = ".properties"; //$NON-NLS-1$
+
+	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.compiler.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String compilation_unresolvedProblem;
+	public static String compilation_unresolvedProblems;
+	public static String compilation_request;
+	public static String compilation_loadBinary;
+	public static String compilation_process;
+	public static String compilation_write;
+	public static String compilation_done;
+	public static String compilation_units;
+	public static String compilation_unit;
+	public static String compilation_internalError;
+	public static String compilation_beginningToCompile;
+	public static String compilation_processing;
+	public static String output_isFile;
+	public static String output_notValidAll;
+	public static String output_notValid;
+	public static String problem_noSourceInformation;
+	public static String problem_atLine;
+	public static String abort_invalidAttribute;
+	public static String abort_invalidExceptionAttribute;
+	public static String abort_invalidOpcode;
+	public static String abort_missingCode;
+	public static String abort_againstSourceModel;
+	public static String accept_cannot;
+	public static String parser_incorrectPath;
+	public static String parser_moveFiles;
+	public static String parser_syntaxRecovery;
+	public static String parser_regularParse;
+	public static String parser_missingFile;
+	public static String parser_corruptedFile;
+	public static String parser_endOfFile;
+	public static String parser_endOfConstructor;
+	public static String parser_endOfMethod;
+	public static String parser_endOfInitializer;
+	public static String ast_missingCode;
+	public static String constant_cannotCastedInto;
+	public static String constant_cannotConvertedTo;
+
+	static {
+		initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @return the manipulated String
+	 */
+	public static String bind(String message) {
+		return bind(message, null);
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param binding the object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding) {
+		return bind(message, new Object[] {binding});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param binding1 An object to be inserted into the message
+	 * @param binding2 A second object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding1, Object binding2) {
+		return bind(message, new Object[] {binding1, binding2});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param bindings An array of objects to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object[] bindings) {
+		return MessageFormat.format(message, bindings);
+	}
+
+	/*
+	 * Build an array of directories to search
+	 */
+	private static String[] buildVariants(String root) {
+		if (nlSuffixes == null) {
+			//build list of suffixes for loading resource bundles
+			String nl = Locale.getDefault().toString();
+			ArrayList result = new ArrayList(4);
+			int lastSeparator;
+			while (true) {
+				result.add('_' + nl + EXTENSION);
+				lastSeparator = nl.lastIndexOf('_');
+				if (lastSeparator == -1)
+					break;
+				nl = nl.substring(0, lastSeparator);
+			}
+			//add the empty suffix last (most general)
+			result.add(EXTENSION);
+			nlSuffixes = (String[]) result.toArray(new String[result.size()]);
+		}
+		root = root.replace('.', '/');
+		String[] variants = new String[nlSuffixes.length];
+		for (int i = 0; i < variants.length; i++)
+			variants[i] = root + nlSuffixes[i];
+		return variants;
+	}
+	public static void initializeMessages(String bundleName, Class clazz) {
+		// load the resource bundle and set the fields
+		final Field[] fields = clazz.getDeclaredFields();
+		load(bundleName, clazz.getClassLoader(), fields);
+
+		// iterate over the fields in the class to make sure that there aren't any empty ones
+		final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
+		final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
+		final int numFields = fields.length;
+		for (int i = 0; i < numFields; i++) {
+			Field field = fields[i];
+			if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
+				continue;
+			try {
+				// Set the value into the field if its empty. We should never get an exception here because
+				// we know we have a public static non-final field. If we do get an exception, silently
+				// log it and continue. This means that the field will (most likely) be un-initialized and
+				// will fail later in the code and if so then we will see both the NPE and this error.
+				if (field.get(clazz) == null) {
+					String value = "Missing message: " + field.getName() + " in: " + bundleName; //$NON-NLS-1$ //$NON-NLS-2$
+					field.set(null, value);
+				}
+			} catch (IllegalArgumentException e) {
+				// ignore
+			} catch (IllegalAccessException e) {
+				// ignore
+			}
+		}
+	}
+	/**
+	 * Load the given resource bundle using the specified class loader.
+	 */
+	public static void load(final String bundleName, final ClassLoader loader, final Field[] fields) {
+		final String[] variants = buildVariants(bundleName);
+		// search the dirs in reverse order so the cascading defaults is set correctly
+		for (int i = variants.length; --i >= 0;) {
+			InputStream input = (loader == null)
+				? ClassLoader.getSystemResourceAsStream(variants[i])
+				: loader.getResourceAsStream(variants[i]);
+			if (input == null) continue;
+			try {
+				final MessagesProperties properties = new MessagesProperties(fields, bundleName);
+				properties.load(input);
+			} catch (IOException e) {
+				// ignore
+			} finally {
+				try {
+					input.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java
new file mode 100644
index 0000000..07dbfba
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+public final class ObjectVector {
+
+	static int INITIAL_SIZE = 10;
+
+	public int size;
+	int maxSize;
+	Object[] elements;
+
+	public ObjectVector() {
+		this(INITIAL_SIZE);
+	}
+
+	public ObjectVector(int initialSize) {
+		this.maxSize = initialSize > 0 ? initialSize : INITIAL_SIZE;
+		this.size = 0;
+		this.elements = new Object[this.maxSize];
+	}
+
+	public void add(Object newElement) {
+
+		if (this.size == this.maxSize) // knows that size starts <= maxSize
+			System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize *= 2]), 0, this.size);
+		this.elements[this.size++] = newElement;
+	}
+
+	public void addAll(Object[] newElements) {
+
+		if (this.size + newElements.length >= this.maxSize) {
+			this.maxSize = this.size + newElements.length; // assume no more elements will be added
+			System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize]), 0, this.size);
+		}
+		System.arraycopy(newElements, 0, this.elements, this.size, newElements.length);
+		this.size += newElements.length;
+	}
+
+	public void addAll(ObjectVector newVector) {
+
+		if (this.size + newVector.size >= this.maxSize) {
+			this.maxSize = this.size + newVector.size; // assume no more elements will be added
+			System.arraycopy(this.elements, 0, (this.elements = new Object[this.maxSize]), 0, this.size);
+		}
+		System.arraycopy(newVector.elements, 0, this.elements, this.size, newVector.size);
+		this.size += newVector.size;
+	}
+
+	/**
+	 * Identity check
+	 */
+	public boolean containsIdentical(Object element) {
+
+		for (int i = this.size; --i >= 0;)
+			if (element == this.elements[i])
+				return true;
+		return false;
+	}
+
+	/**
+	 * Equality check
+	 */
+	public boolean contains(Object element) {
+
+		for (int i = this.size; --i >= 0;)
+			if (element.equals(this.elements[i]))
+				return true;
+		return false;
+	}
+
+	public void copyInto(Object[] targetArray){
+
+		this.copyInto(targetArray, 0);
+	}
+
+	public void copyInto(Object[] targetArray, int index){
+
+		System.arraycopy(this.elements, 0, targetArray, index, this.size);
+	}
+
+	public Object elementAt(int index) {
+
+		return this.elements[index];
+	}
+
+	public Object find(Object element) {
+
+		for (int i = this.size; --i >= 0;)
+			if (element.equals(this.elements[i]))
+				return this.elements[i];
+		return null;
+	}
+
+	public Object remove(Object element) {
+
+		// assumes only one occurrence of the element exists
+		for (int i = this.size; --i >= 0;)
+			if (element.equals(this.elements[i])) {
+				// shift the remaining elements down one spot
+				System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i);
+				this.elements[this.size] = null;
+				return element;
+			}
+		return null;
+	}
+
+	public void removeAll() {
+
+		for (int i = this.size; --i >= 0;)
+			this.elements[i] = null;
+		this.size = 0;
+	}
+
+	public int size(){
+
+		return this.size;
+	}
+
+	public String toString() {
+
+		String s = ""; //$NON-NLS-1$
+		for (int i = 0; i < this.size; i++)
+			s += this.elements[i].toString() + "\n"; //$NON-NLS-1$
+		return s;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java
new file mode 100644
index 0000000..c263ca4
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * A simple lookup table is a non-synchronized Hashtable, whose keys
+ * and values are Objects. It also uses linear probing to resolve collisions
+ * rather than a linked list of hash table entries.
+ */
+public final class SimpleLookupTable implements Cloneable {
+
+// to avoid using Enumerations, walk the individual tables skipping nulls
+public Object[] keyTable;
+public Object[] valueTable;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public SimpleLookupTable() {
+	this(13);
+}
+
+public SimpleLookupTable(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.keyTable = new Object[extraRoom];
+	this.valueTable = new Object[extraRoom];
+}
+
+public Object clone() throws CloneNotSupportedException {
+	SimpleLookupTable result = (SimpleLookupTable) super.clone();
+	result.elementSize = this.elementSize;
+	result.threshold = this.threshold;
+
+	int length = this.keyTable.length;
+	result.keyTable = new Object[length];
+	System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+	length = this.valueTable.length;
+	result.valueTable = new Object[length];
+	System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+	return result;
+}
+
+public boolean containsKey(Object key) {
+	int length = this.keyTable.length;
+	int index = (key.hashCode() & 0x7FFFFFFF) % length;
+	Object currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.equals(key)) return true;
+		if (++index == length) index = 0;
+	}
+	return false;
+}
+
+public Object get(Object key) {
+	int length = this.keyTable.length;
+	int index = (key.hashCode() & 0x7FFFFFFF) % length;
+	Object currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.equals(key)) return this.valueTable[index];
+		if (++index == length) index = 0;
+	}
+	return null;
+}
+
+public Object getKey(Object key) {
+	int length = this.keyTable.length;
+	int index = (key.hashCode() & 0x7FFFFFFF) % length;
+	Object currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.equals(key)) return currentKey;
+		if (++index == length) index = 0;
+	}
+	return key;
+}
+
+public Object keyForValue(Object valueToMatch) {
+	if (valueToMatch != null)
+		for (int i = 0, l = this.keyTable.length; i < l; i++)
+			if (this.keyTable[i] != null && valueToMatch.equals(this.valueTable[i]))
+				return this.keyTable[i];
+	return null;
+}
+
+public Object put(Object key, Object value) {
+	int length = this.keyTable.length;
+	int index = (key.hashCode() & 0x7FFFFFFF) % length;
+	Object currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.equals(key)) return this.valueTable[index] = value;
+		if (++index == length) index = 0;
+	}
+	this.keyTable[index] = key;
+	this.valueTable[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return value;
+}
+
+public Object removeKey(Object key) {
+	int length = this.keyTable.length;
+	int index = (key.hashCode() & 0x7FFFFFFF) % length;
+	Object currentKey;
+	while ((currentKey = this.keyTable[index]) != null) {
+		if (currentKey.equals(key)) {
+			this.elementSize--;
+			Object oldValue = this.valueTable[index];
+			this.keyTable[index] = null;
+			this.valueTable[index] = null;
+			if (this.keyTable[index + 1 == length ? 0 : index + 1] != null)
+				rehash(); // only needed if a possible collision existed
+			return oldValue;
+		}
+		if (++index == length) index = 0;
+	}
+	return null;
+}
+
+public void removeValue(Object valueToRemove) {
+	boolean rehash = false;
+	for (int i = 0, l = this.valueTable.length; i < l; i++) {
+		Object value = this.valueTable[i];
+		if (value != null && value.equals(valueToRemove)) {
+			this.elementSize--;
+			this.keyTable[i] = null;
+			this.valueTable[i] = null;
+			if (!rehash && this.keyTable[i + 1 == l ? 0 : i + 1] != null)
+				rehash = true; // only needed if a possible collision existed
+		}
+	}
+	if (rehash) rehash();
+}
+
+private void rehash() {
+	SimpleLookupTable newLookupTable = new SimpleLookupTable(this.elementSize * 2); // double the number of expected elements
+	Object currentKey;
+	for (int i = this.keyTable.length; --i >= 0;)
+		if ((currentKey = this.keyTable[i]) != null)
+			newLookupTable.put(currentKey, this.valueTable[i]);
+
+	this.keyTable = newLookupTable.keyTable;
+	this.valueTable = newLookupTable.valueTable;
+	this.elementSize = newLookupTable.elementSize;
+	this.threshold = newLookupTable.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	Object object;
+	for (int i = 0, l = this.valueTable.length; i < l; i++)
+		if ((object = this.valueTable[i]) != null)
+			s += this.keyTable[i].toString() + " -> " + object.toString() + "\n"; 	//$NON-NLS-2$ //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java
new file mode 100644
index 0000000..1dfdd02
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public final class SimpleNameVector {
+
+	static int INITIAL_SIZE = 10;
+
+	public int size;
+	int maxSize;
+	char[][] elements;
+
+	public SimpleNameVector() {
+
+		this.maxSize = INITIAL_SIZE;
+		this.size = 0;
+		this.elements = new char[this.maxSize][];
+	}
+
+	public void add(char[] newElement) {
+
+		if (this.size == this.maxSize) // knows that size starts <= maxSize
+			System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize *= 2][]), 0, this.size);
+		this.elements[this.size++] = newElement;
+	}
+
+	public void addAll(char[][] newElements) {
+
+		if (this.size + newElements.length >= this.maxSize) {
+			this.maxSize = this.size + newElements.length; // assume no more elements will be added
+			System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize][]), 0, this.size);
+		}
+		System.arraycopy(newElements, 0, this.elements, this.size, newElements.length);
+		this.size += newElements.length;
+	}
+
+	public void copyInto(Object[] targetArray){
+
+		System.arraycopy(this.elements, 0, targetArray, 0, this.size);
+	}
+
+	public boolean contains(char[] element) {
+
+		for (int i = this.size; --i >= 0;)
+			if (CharOperation.equals(element, this.elements[i]))
+				return true;
+		return false;
+	}
+
+	public char[] elementAt(int index) {
+		return this.elements[index];
+	}
+
+	public char[] remove(char[] element) {
+
+		// assumes only one occurrence of the element exists
+		for (int i = this.size; --i >= 0;)
+			if (element == this.elements[i]) {
+				// shift the remaining elements down one spot
+				System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i);
+				this.elements[this.size] = null;
+				return element;
+			}
+		return null;
+	}
+
+	public void removeAll() {
+
+		for (int i = this.size; --i >= 0;)
+			this.elements[i] = null;
+		this.size = 0;
+	}
+
+	public int size(){
+
+		return this.size;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0; i < this.size; i++) {
+			buffer.append(this.elements[i]).append("\n"); //$NON-NLS-1$
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSet.java
new file mode 100644
index 0000000..2339b1b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSet.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+/**
+ * A simple lookup table is a non-synchronized Hashtable, whose keys
+ * and values are Objects. It also uses linear probing to resolve collisions
+ * rather than a linked list of hash table entries.
+ */
+public final class SimpleSet implements Cloneable {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public Object[] values;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public SimpleSet() {
+	this(13);
+}
+
+public SimpleSet(int size) {
+	if (size < 3) size = 3;
+	this.elementSize = 0;
+	this.threshold = size + 1; // size is the expected number of elements
+	this.values = new Object[2 * size + 1];
+}
+
+public Object add(Object object) {
+	int length = this.values.length;
+	int index = (object.hashCode() & 0x7FFFFFFF) % length;
+	Object current;
+	while ((current = this.values[index]) != null) {
+		if (current.equals(object)) return this.values[index] = object;
+		if (++index == length) index = 0;
+	}
+	this.values[index] = object;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return object;
+}
+
+public Object addIfNotIncluded(Object object) {
+	int length = this.values.length;
+	int index = (object.hashCode() & 0x7FFFFFFF) % length;
+	Object current;
+	while ((current = this.values[index]) != null) {
+		if (current.equals(object)) return null; // already existed
+		if (++index == length) index = 0;
+	}
+	this.values[index] = object;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return object;
+}
+
+public void asArray(Object[] copy) {
+	if (this.elementSize != copy.length)
+		throw new IllegalArgumentException();
+	int index = this.elementSize;
+	for (int i = 0, l = this.values.length; i < l && index > 0; i++)
+		if (this.values[i] != null)
+			copy[--index] = this.values[i];
+}
+
+public void clear() {
+	for (int i = this.values.length; --i >= 0;)
+		this.values[i] = null;
+	this.elementSize = 0;
+}
+
+public Object clone() throws CloneNotSupportedException {
+	SimpleSet result = (SimpleSet) super.clone();
+	result.elementSize = this.elementSize;
+	result.threshold = this.threshold;
+
+	int length = this.values.length;
+	result.values = new Object[length];
+	System.arraycopy(this.values, 0, result.values, 0, length);
+	return result;
+}
+
+public boolean includes(Object object) {
+	int length = this.values.length;
+	int index = (object.hashCode() & 0x7FFFFFFF) % length;
+	Object current;
+	while ((current = this.values[index]) != null) {
+		if (current.equals(object)) return true;
+		if (++index == length) index = 0;
+	}
+	return false;
+}
+
+public Object remove(Object object) {
+	int length = this.values.length;
+	int index = (object.hashCode() & 0x7FFFFFFF) % length;
+	Object current;
+	while ((current = this.values[index]) != null) {
+		if (current.equals(object)) {
+			this.elementSize--;
+			Object oldValue = this.values[index];
+			this.values[index] = null;
+			if (this.values[index + 1 == length ? 0 : index + 1] != null)
+				rehash(); // only needed if a possible collision existed
+			return oldValue;
+		}
+		if (++index == length) index = 0;
+	}
+	return null;
+}
+
+private void rehash() {
+	SimpleSet newSet = new SimpleSet(this.elementSize * 2); // double the number of expected elements
+	Object current;
+	for (int i = this.values.length; --i >= 0;)
+		if ((current = this.values[i]) != null)
+			newSet.add(current);
+
+	this.values = newSet.values;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	Object object;
+	for (int i = 0, l = this.values.length; i < l; i++)
+		if ((object = this.values[i]) != null)
+			s += object.toString() + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java
new file mode 100644
index 0000000..c39d6e1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * A simple lookup table is a non-synchronized Hashtable, whose keys
+ * and values are char[]. It also uses linear probing to resolve collisions
+ * rather than a linked list of hash table entries.
+ */
+public final class SimpleSetOfCharArray implements Cloneable {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public char[][] values;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public SimpleSetOfCharArray() {
+	this(13);
+}
+
+public SimpleSetOfCharArray(int size) {
+	if (size < 3) size = 3;
+	this.elementSize = 0;
+	this.threshold = size + 1; // size is the expected number of elements
+	this.values = new char[2 * size + 1][];
+}
+
+public Object add(char[] object) {
+	int length = this.values.length;
+	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
+	char[] current;
+	while ((current = this.values[index]) != null) {
+		if (CharOperation.equals(current, object)) return this.values[index] = object;
+		if (++index == length) index = 0;
+	}
+	this.values[index] = object;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return object;
+}
+
+public void asArray(Object[] copy) {
+	if (this.elementSize != copy.length)
+		throw new IllegalArgumentException();
+	int index = this.elementSize;
+	for (int i = 0, l = this.values.length; i < l && index > 0; i++)
+		if (this.values[i] != null)
+			copy[--index] = this.values[i];
+}
+
+public void clear() {
+	for (int i = this.values.length; --i >= 0;)
+		this.values[i] = null;
+	this.elementSize = 0;
+}
+
+public Object clone() throws CloneNotSupportedException {
+	SimpleSetOfCharArray result = (SimpleSetOfCharArray) super.clone();
+	result.elementSize = this.elementSize;
+	result.threshold = this.threshold;
+
+	int length = this.values.length;
+	result.values = new char[length][];
+	System.arraycopy(this.values, 0, result.values, 0, length);
+	return result;
+}
+
+public char[] get(char[] object) {
+	int length = this.values.length;
+	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
+	char[] current;
+	while ((current = this.values[index]) != null) {
+		if (CharOperation.equals(current, object)) return current;
+		if (++index == length) index = 0;
+	}
+	this.values[index] = object;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return object;
+}
+
+public boolean includes(char[] object) {
+	int length = this.values.length;
+	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
+	char[] current;
+	while ((current = this.values[index]) != null) {
+		if (CharOperation.equals(current, object)) return true;
+		if (++index == length) index = 0;
+	}
+	return false;
+}
+
+public char[] remove(char[] object) {
+	int length = this.values.length;
+	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
+	char[] current;
+	while ((current = this.values[index]) != null) {
+		if (CharOperation.equals(current, object)) {
+			this.elementSize--;
+			char[] oldValue = this.values[index];
+			this.values[index] = null;
+			if (this.values[index + 1 == length ? 0 : index + 1] != null)
+				rehash(); // only needed if a possible collision existed
+			return oldValue;
+		}
+		if (++index == length) index = 0;
+	}
+	return null;
+}
+
+private void rehash() {
+	SimpleSetOfCharArray newSet = new SimpleSetOfCharArray(this.elementSize * 2); // double the number of expected elements
+	char[] current;
+	for (int i = this.values.length; --i >= 0;)
+		if ((current = this.values[i]) != null)
+			newSet.add(current);
+
+	this.values = newSet.values;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	char[] object;
+	for (int i = 0, l = this.values.length; i < l; i++)
+		if ((object = this.values[i]) != null)
+			s += new String(object) + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java
new file mode 100644
index 0000000..ac30193
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Sorting.java
@@ -0,0 +1,110 @@
+/**********************************************************************
+ * Copyright 2008, 2012 Technical University Berlin, Germany and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *		Stephan Herrmann - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * Sorting utilities.
+ * Originally developed for the <a href="http://www.eclipse.org/objectteams">Object Teams project</a>.
+ */
+public class Sorting {
+
+	/**
+	 * Topological sort for types
+	 * Guarantee: supertypes come before subtypes.
+	 */
+	public static ReferenceBinding[] sortTypes(ReferenceBinding[] types) {
+		int len = types.length;
+
+		ReferenceBinding[] unsorted = new ReferenceBinding[len];
+		ReferenceBinding[] sorted = new ReferenceBinding[len];
+		System.arraycopy(types, 0, unsorted, 0, len);
+		
+		int o = 0;
+		for(int i=0; i<len; i++)
+			o = sort(unsorted, i, sorted, o);
+
+		return sorted;
+	}
+	// Transfer input[i] and all its supers into output[o] ff.
+	private static int sort(ReferenceBinding[] input, int i,
+							ReferenceBinding[] output, int o)
+	{
+		if (input[i] == null)
+			return o;
+
+		ReferenceBinding superclass = input[i].superclass();
+		o = sortSuper(superclass, input, output, o);
+
+		ReferenceBinding[] superInterfaces = input[i].superInterfaces();
+		for (int j=0; j<superInterfaces.length; j++) {
+			o = sortSuper(superInterfaces[j], input, output, o);
+		}
+
+		// done with supers, now input[i] can safely be transferred:
+		output[o++] = input[i];
+		input[i] = null;
+
+		return o;
+	}
+	// if superclass is within the set of types to sort,
+	// transfer it and all its supers to output[o] ff.
+	private static int sortSuper(ReferenceBinding superclass,
+						  		 ReferenceBinding[] input,
+						  		 ReferenceBinding[] output, int o)
+	{
+		if (superclass.id != TypeIds.T_JavaLangObject) {
+			// search superclass within input:
+			int j = 0;
+			for(j=0; j<input.length; j++)
+				if (input[j] == superclass)
+					break;
+			if (j < input.length)
+				// depth first traversal:
+				o = sort(input, j, output, o);
+			// otherwise assume super was already transferred.
+		}
+		return o;
+	}
+	public static MethodBinding[] concreteFirst(MethodBinding[] methods, int length) {
+		if (length == 0 || (length > 0 && !methods[0].isAbstract()))
+			return methods;
+		MethodBinding[] copy = new MethodBinding[length];
+		int idx = 0;
+		for (int i=0; i<length; i++)
+			if (!methods[i].isAbstract())
+				copy[idx++] = methods[i];
+		for (int i=0; i<length; i++)
+			if (methods[i].isAbstract())
+				copy[idx++] = methods[i];
+		return copy;
+	}
+	public static MethodBinding[] abstractFirst(MethodBinding[] methods, int length) {
+		if (length == 0 || (length > 0 && methods[0].isAbstract()))
+			return methods;
+		MethodBinding[] copy = new MethodBinding[length];
+		int idx = 0;
+		for (int i=0; i<length; i++)
+			if (methods[i].isAbstract())
+				copy[idx++] = methods[i];
+		for (int i=0; i<length; i++)
+			if (!methods[i].isAbstract())
+				copy[idx++] = methods[i];
+		return copy;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
new file mode 100644
index 0000000..61b919b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+public interface SuffixConstants {
+	public final static String EXTENSION_class = "class"; //$NON-NLS-1$
+	public final static String EXTENSION_CLASS = "CLASS"; //$NON-NLS-1$
+	public final static String EXTENSION_java = "java"; //$NON-NLS-1$
+	public final static String EXTENSION_JAVA = "JAVA"; //$NON-NLS-1$
+
+	public final static String SUFFIX_STRING_class = "." + EXTENSION_class; //$NON-NLS-1$
+	public final static String SUFFIX_STRING_CLASS = "." + EXTENSION_CLASS; //$NON-NLS-1$
+	public final static String SUFFIX_STRING_java = "." + EXTENSION_java; //$NON-NLS-1$
+	public final static String SUFFIX_STRING_JAVA = "." + EXTENSION_JAVA; //$NON-NLS-1$
+
+	public final static char[] SUFFIX_class = SUFFIX_STRING_class.toCharArray();
+	public final static char[] SUFFIX_CLASS = SUFFIX_STRING_CLASS.toCharArray();
+	public final static char[] SUFFIX_java = SUFFIX_STRING_java.toCharArray();
+	public final static char[] SUFFIX_JAVA = SUFFIX_STRING_JAVA.toCharArray();
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
new file mode 100644
index 0000000..7625765
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -0,0 +1,1559 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     daolaf@gmail.com - Contribution for bug 3292227
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+
+public class Util implements SuffixConstants {
+
+	/**
+	 * Character constant indicating the primitive type boolean in a signature.
+	 * Value is <code>'Z'</code>.
+	 */
+	public static final char C_BOOLEAN 		= 'Z';
+
+	/**
+	 * Character constant indicating the primitive type byte in a signature.
+	 * Value is <code>'B'</code>.
+	 */
+	public static final char C_BYTE 		= 'B';
+
+	/**
+	 * Character constant indicating the primitive type char in a signature.
+	 * Value is <code>'C'</code>.
+	 */
+	public static final char C_CHAR 		= 'C';
+
+	/**
+	 * Character constant indicating the primitive type double in a signature.
+	 * Value is <code>'D'</code>.
+	 */
+	public static final char C_DOUBLE 		= 'D';
+
+	/**
+	 * Character constant indicating the primitive type float in a signature.
+	 * Value is <code>'F'</code>.
+	 */
+	public static final char C_FLOAT 		= 'F';
+
+	/**
+	 * Character constant indicating the primitive type int in a signature.
+	 * Value is <code>'I'</code>.
+	 */
+	public static final char C_INT 			= 'I';
+
+	/**
+	 * Character constant indicating the semicolon in a signature.
+	 * Value is <code>';'</code>.
+	 */
+	public static final char C_SEMICOLON 			= ';';
+
+	/**
+	 * Character constant indicating the colon in a signature.
+	 * Value is <code>':'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_COLON 			= ':';
+
+	/**
+	 * Character constant indicating the primitive type long in a signature.
+	 * Value is <code>'J'</code>.
+	 */
+	public static final char C_LONG			= 'J';
+
+	/**
+	 * Character constant indicating the primitive type short in a signature.
+	 * Value is <code>'S'</code>.
+	 */
+	public static final char C_SHORT		= 'S';
+
+	/**
+	 * Character constant indicating result type void in a signature.
+	 * Value is <code>'V'</code>.
+	 */
+	public static final char C_VOID			= 'V';
+
+	/**
+	 * Character constant indicating the start of a resolved type variable in a
+	 * signature. Value is <code>'T'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_TYPE_VARIABLE	= 'T';
+
+	/**
+	 * Character constant indicating an unbound wildcard type argument
+	 * in a signature.
+	 * Value is <code>'*'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_STAR	= '*';
+
+	/**
+	 * Character constant indicating an exception in a signature.
+	 * Value is <code>'^'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_EXCEPTION_START	= '^';
+
+	/**
+	 * Character constant indicating a bound wildcard type argument
+	 * in a signature with extends clause.
+	 * Value is <code>'+'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_EXTENDS	= '+';
+
+	/**
+	 * Character constant indicating a bound wildcard type argument
+	 * in a signature with super clause.
+	 * Value is <code>'-'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_SUPER	= '-';
+
+	/**
+	 * Character constant indicating the dot in a signature.
+	 * Value is <code>'.'</code>.
+	 */
+	public static final char C_DOT			= '.';
+
+	/**
+	 * Character constant indicating the dollar in a signature.
+	 * Value is <code>'$'</code>.
+	 */
+	public static final char C_DOLLAR			= '$';
+
+	/**
+	 * Character constant indicating an array type in a signature.
+	 * Value is <code>'['</code>.
+	 */
+	public static final char C_ARRAY		= '[';
+
+	/**
+	 * Character constant indicating the start of a resolved, named type in a
+	 * signature. Value is <code>'L'</code>.
+	 */
+	public static final char C_RESOLVED		= 'L';
+
+	/**
+	 * Character constant indicating the start of an unresolved, named type in a
+	 * signature. Value is <code>'Q'</code>.
+	 */
+	public static final char C_UNRESOLVED	= 'Q';
+
+	/**
+	 * Character constant indicating the end of a named type in a signature.
+	 * Value is <code>';'</code>.
+	 */
+	public static final char C_NAME_END		= ';';
+
+	/**
+	 * Character constant indicating the start of a parameter type list in a
+	 * signature. Value is <code>'('</code>.
+	 */
+	public static final char C_PARAM_START	= '(';
+
+	/**
+	 * Character constant indicating the end of a parameter type list in a
+	 * signature. Value is <code>')'</code>.
+	 */
+	public static final char C_PARAM_END	= ')';
+
+	/**
+	 * Character constant indicating the start of a formal type parameter
+	 * (or type argument) list in a signature. Value is <code>'&lt;'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_GENERIC_START	= '<';
+
+	/**
+	 * Character constant indicating the end of a generic type list in a
+	 * signature. Value is <code>'&gt;'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_GENERIC_END	= '>';
+
+	/**
+	 * Character constant indicating a capture of a wildcard type in a
+	 * signature. Value is <code>'!'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_CAPTURE	= '!';
+
+	public interface Displayable {
+		String displayString(Object o);
+	}
+
+	private static final int DEFAULT_READING_SIZE = 8192;
+	private static final int DEFAULT_WRITING_SIZE = 1024;
+	public final static String UTF_8 = "UTF-8";	//$NON-NLS-1$
+	public static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+
+	public static final String EMPTY_STRING = new String(CharOperation.NO_CHAR);
+	public static final int[] EMPTY_INT_ARRAY= new int[0];
+
+	/**
+	 * Build all the directories and subdirectories corresponding to the packages names
+	 * into the directory specified in parameters.
+	 *
+	 * outputPath is formed like:
+	 *	   c:\temp\ the last character is a file separator
+	 * relativeFileName is formed like:
+	 *     java\lang\String.class *
+	 *
+	 * @param outputPath java.lang.String
+	 * @param relativeFileName java.lang.String
+	 * @return java.lang.String
+	 */
+	public static String buildAllDirectoriesInto(String outputPath, String relativeFileName) throws IOException {
+		char fileSeparatorChar = File.separatorChar;
+		String fileSeparator = File.separator;
+		File f;
+		outputPath = outputPath.replace('/', fileSeparatorChar);
+			// these could be optimized out if we normalized paths once and for
+			// all
+		relativeFileName = relativeFileName.replace('/', fileSeparatorChar);
+		String outputDirPath, fileName;
+		int separatorIndex = relativeFileName.lastIndexOf(fileSeparatorChar);
+		if (separatorIndex == -1) {
+			if (outputPath.endsWith(fileSeparator)) {
+				outputDirPath = outputPath.substring(0, outputPath.length() - 1);
+				fileName = outputPath + relativeFileName;
+			} else {
+				outputDirPath = outputPath;
+				fileName = outputPath + fileSeparator + relativeFileName;
+			}
+		} else {
+			if (outputPath.endsWith(fileSeparator)) {
+				outputDirPath = outputPath +
+					relativeFileName.substring(0, separatorIndex);
+				fileName = outputPath + relativeFileName;
+			} else {
+				outputDirPath = outputPath + fileSeparator +
+					relativeFileName.substring(0, separatorIndex);
+				fileName = outputPath + fileSeparator + relativeFileName;
+			}
+		}
+		f = new File(outputDirPath);
+		f.mkdirs();
+		if (f.isDirectory()) {
+			return fileName;
+		} else {
+			// the directory creation failed for some reason - retry using
+			// a slower algorithm so as to refine the diagnostic
+			if (outputPath.endsWith(fileSeparator)) {
+				outputPath = outputPath.substring(0, outputPath.length() - 1);
+			}
+			f = new File(outputPath);
+			boolean checkFileType = false;
+			if (f.exists()) {
+				  checkFileType = true; // pre-existed
+			} else {
+				// we have to create that directory
+				if (!f.mkdirs()) {
+					  if (f.exists()) {
+							// someone else created f -- need to check its type
+							checkFileType = true;
+					  } else {
+							// no one could create f -- complain
+						throw new IOException(Messages.bind(
+							Messages.output_notValidAll, f.getAbsolutePath()));
+					  }
+				}
+			}
+			if (checkFileType) {
+				  if (!f.isDirectory()) {
+					throw new IOException(Messages.bind(
+						Messages.output_isFile, f.getAbsolutePath()));
+				  }
+			}
+			StringBuffer outDir = new StringBuffer(outputPath);
+			outDir.append(fileSeparator);
+			StringTokenizer tokenizer =
+				new StringTokenizer(relativeFileName, fileSeparator);
+			String token = tokenizer.nextToken();
+			while (tokenizer.hasMoreTokens()) {
+				f = new File(outDir.append(token).append(fileSeparator).toString());
+				  checkFileType = false; // reset
+				if (f.exists()) {
+					  checkFileType = true; // this is suboptimal, but it catches corner cases
+											// in which a regular file pre-exists
+				} else {
+				// we have to create that directory
+					if (!f.mkdir()) {
+						  if (f.exists()) {
+								// someone else created f -- need to check its type
+								checkFileType = true;
+						  } else {
+								// no one could create f -- complain
+							throw new IOException(Messages.bind(
+								Messages.output_notValid,
+									outDir.substring(outputPath.length() + 1,
+										outDir.length() - 1),
+									outputPath));
+						  }
+					}
+				}
+				if (checkFileType) {
+					  if (!f.isDirectory()) {
+						throw new IOException(Messages.bind(
+							Messages.output_isFile, f.getAbsolutePath()));
+					  }
+				}
+				token = tokenizer.nextToken();
+			}
+			// token contains the last one
+			return outDir.append(token).toString();
+		}
+	}
+
+	/**
+	 * Returns the given bytes as a char array using a given encoding (null means platform default).
+	 */
+	public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException {
+
+		return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.length, encoding);
+
+	}
+
+	/**
+	 * Returns the outer most enclosing type's visibility for the given TypeDeclaration
+	 * and visibility based on compiler options.
+	 */
+	public static int computeOuterMostVisibility(TypeDeclaration typeDeclaration, int visibility) {
+		while (typeDeclaration != null) {
+			switch (typeDeclaration.modifiers & ExtraCompilerModifiers.AccVisibilityMASK) {
+				case ClassFileConstants.AccPrivate:
+					visibility = ClassFileConstants.AccPrivate;
+					break;
+				case ClassFileConstants.AccDefault:
+					if (visibility != ClassFileConstants.AccPrivate) {
+						visibility = ClassFileConstants.AccDefault;
+					}
+					break;
+				case ClassFileConstants.AccProtected:
+					if (visibility == ClassFileConstants.AccPublic) {
+						visibility = ClassFileConstants.AccProtected;
+					}
+					break;
+			}
+			typeDeclaration = typeDeclaration.enclosingType;
+		}
+		return visibility;
+	}
+	/**
+	 * Returns the contents of the given file as a byte array.
+	 * @throws IOException if a problem occured reading the file.
+	 */
+	public static byte[] getFileByteContent(File file) throws IOException {
+		InputStream stream = null;
+		try {
+			stream = new BufferedInputStream(new FileInputStream(file));
+			return getInputStreamAsByteArray(stream, (int) file.length());
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+	}
+	/**
+	 * Returns the contents of the given file as a char array.
+	 * When encoding is null, then the platform default one is used
+	 * @throws IOException if a problem occured reading the file.
+	 */
+	public static char[] getFileCharContent(File file, String encoding) throws IOException {
+		InputStream stream = null;
+		try {
+			stream = new FileInputStream(file);
+			return getInputStreamAsCharArray(stream, (int) file.length(), encoding);
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+	}
+	private static FileOutputStream getFileOutputStream(boolean generatePackagesStructure, String outputPath, String relativeFileName) throws IOException {
+		if (generatePackagesStructure) {
+			return new FileOutputStream(new File(buildAllDirectoriesInto(outputPath, relativeFileName)));
+		} else {
+			String fileName = null;
+			char fileSeparatorChar = File.separatorChar;
+			String fileSeparator = File.separator;
+			// First we ensure that the outputPath exists
+			outputPath = outputPath.replace('/', fileSeparatorChar);
+			// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+			int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
+			if (indexOfPackageSeparator == -1) {
+				if (outputPath.endsWith(fileSeparator)) {
+					fileName = outputPath + relativeFileName;
+				} else {
+					fileName = outputPath + fileSeparator + relativeFileName;
+				}
+			} else {
+				int length = relativeFileName.length();
+				if (outputPath.endsWith(fileSeparator)) {
+					fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+				} else {
+					fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+				}
+			}
+			return new FileOutputStream(new File(fileName));
+		}
+	}
+
+	/*
+	 * NIO support to get input stream as byte array.
+	 * Not used as with JDK 1.4.2 this support is slower than standard IO one...
+	 * Keep it as comment for future in case of next JDK versions improve performance
+	 * in this area...
+	 *
+	public static byte[] getInputStreamAsByteArray(FileInputStream stream, int length)
+		throws IOException {
+
+		FileChannel channel = stream.getChannel();
+		int size = (int)channel.size();
+		if (length >= 0 && length < size) size = length;
+		byte[] contents = new byte[size];
+		ByteBuffer buffer = ByteBuffer.wrap(contents);
+		channel.read(buffer);
+		return contents;
+	}
+	*/
+	/**
+	 * Returns the given input stream's contents as a byte array.
+	 * If a length is specified (i.e. if length != -1), only length bytes
+	 * are returned. Otherwise all bytes in the stream are returned.
+	 * Note this doesn't close the stream.
+	 * @throws IOException if a problem occured reading the stream.
+	 */
+	public static byte[] getInputStreamAsByteArray(InputStream stream, int length)
+			throws IOException {
+		byte[] contents;
+		if (length == -1) {
+			contents = new byte[0];
+			int contentsLength = 0;
+			int amountRead = -1;
+			do {
+				int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
+
+				// resize contents if needed
+				if (contentsLength + amountRequested > contents.length) {
+					System.arraycopy(
+						contents,
+						0,
+						contents = new byte[contentsLength + amountRequested],
+						0,
+						contentsLength);
+				}
+
+				// read as many bytes as possible
+				amountRead = stream.read(contents, contentsLength, amountRequested);
+
+				if (amountRead > 0) {
+					// remember length of contents
+					contentsLength += amountRead;
+				}
+			} while (amountRead != -1);
+
+			// resize contents if necessary
+			if (contentsLength < contents.length) {
+				System.arraycopy(
+					contents,
+					0,
+					contents = new byte[contentsLength],
+					0,
+					contentsLength);
+			}
+		} else {
+			contents = new byte[length];
+			int len = 0;
+			int readSize = 0;
+			while ((readSize != -1) && (len != length)) {
+				// See PR 1FMS89U
+				// We record first the read size. In this case len is the actual read size.
+				len += readSize;
+				readSize = stream.read(contents, len, length - len);
+			}
+		}
+
+		return contents;
+	}
+
+	/*
+	 * NIO support to get input stream as char array.
+	 * Not used as with JDK 1.4.2 this support is slower than standard IO one...
+	 * Keep it as comment for future in case of next JDK versions improve performance
+	 * in this area...
+	public static char[] getInputStreamAsCharArray(FileInputStream stream, int length, String encoding)
+		throws IOException {
+
+		FileChannel channel = stream.getChannel();
+		int size = (int)channel.size();
+		if (length >= 0 && length < size) size = length;
+		Charset charset = encoding==null?systemCharset:Charset.forName(encoding);
+		if (charset != null) {
+			MappedByteBuffer bbuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
+		    CharsetDecoder decoder = charset.newDecoder();
+		    CharBuffer buffer = decoder.decode(bbuffer);
+		    char[] contents = new char[buffer.limit()];
+		    buffer.get(contents);
+		    return contents;
+		}
+		throw new UnsupportedCharsetException(SYSTEM_FILE_ENCODING);
+	}
+	*/
+	/**
+	 * Returns the given input stream's contents as a character array.
+	 * If a length is specified (i.e. if length != -1), this represents the number of bytes in the stream.
+	 * Note this doesn't close the stream.
+	 * @throws IOException if a problem occured reading the stream.
+	 */
+	public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding)
+			throws IOException {
+		BufferedReader reader = null;
+		try {
+			reader = encoding == null
+						? new BufferedReader(new InputStreamReader(stream))
+						: new BufferedReader(new InputStreamReader(stream, encoding));
+		} catch (UnsupportedEncodingException e) {
+			// encoding is not supported
+			reader =  new BufferedReader(new InputStreamReader(stream));
+		}
+		char[] contents;
+		int totalRead = 0;
+		if (length == -1) {
+			contents = CharOperation.NO_CHAR;
+		} else {
+			// length is a good guess when the encoding produces less or the same amount of characters than the file length
+			contents = new char[length]; // best guess
+		}
+
+		while (true) {
+			int amountRequested;
+			if (totalRead < length) {
+				// until known length is met, reuse same array sized eagerly
+				amountRequested = length - totalRead;
+			} else {
+				// reading beyond known length
+				int current = reader.read();
+				if (current < 0) break;
+
+				amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE);  // read at least 8K
+
+				// resize contents if needed
+				if (totalRead + 1 + amountRequested > contents.length)
+					System.arraycopy(contents, 	0, 	contents = new char[totalRead + 1 + amountRequested], 0, totalRead);
+
+				// add current character
+				contents[totalRead++] = (char) current; // coming from totalRead==length
+			}
+			// read as many chars as possible
+			int amountRead = reader.read(contents, totalRead, amountRequested);
+			if (amountRead < 0) break;
+			totalRead += amountRead;
+		}
+
+		// Do not keep first character for UTF-8 BOM encoding
+		int start = 0;
+		if (totalRead > 0 && UTF_8.equals(encoding)) {
+			if (contents[0] == 0xFEFF) { // if BOM char then skip
+				totalRead--;
+				start = 1;
+			}
+		}
+
+		// resize contents if necessary
+		if (totalRead < contents.length)
+			System.arraycopy(contents, start, contents = new char[totalRead], 	0, 	totalRead);
+
+		return contents;
+	}
+
+	/**
+	 * Returns a one line summary for an exception (extracted from its stacktrace: name + first frame)
+	 * @param exception
+	 * @return one line summary for an exception
+	 */
+	public static String getExceptionSummary(Throwable exception) {
+		StringWriter stringWriter = new StringWriter();
+		exception.printStackTrace(new PrintWriter(stringWriter));
+		StringBuffer buffer = stringWriter.getBuffer();		
+		StringBuffer exceptionBuffer = new StringBuffer(50);
+		exceptionBuffer.append(exception.toString());
+		// only keep leading frame portion of the trace (i.e. line no. 2 from the stacktrace)
+		lookupLine2: for (int i = 0, lineSep = 0, max = buffer.length(), line2Start = 0; i < max; i++) {
+			switch (buffer.charAt(i)) {
+				case '\n':
+				case '\r' :
+					if (line2Start > 0) {
+						exceptionBuffer.append(' ').append(buffer.substring(line2Start, i));
+						break lookupLine2;
+					}						
+					lineSep++;
+					break;
+				case ' ' :
+				case '\t' :
+					break;
+				default :
+					if (lineSep > 0) {
+						line2Start = i;
+						lineSep = 0;
+					}
+					break;
+			}
+		}
+		return exceptionBuffer.toString();
+	}
+	
+	public static int getLineNumber(int position, int[] lineEnds, int g, int d) {
+		if (lineEnds == null)
+			return 1;
+		if (d == -1)
+			return 1;
+		int m = g, start;
+		while (g <= d) {
+			m = g + (d - g) /2;
+			if (position < (start = lineEnds[m])) {
+				d = m-1;
+			} else if (position > start) {
+				g = m+1;
+			} else {
+				return m + 1;
+			}
+		}
+		if (position < lineEnds[m]) {
+			return m+1;
+		}
+		return m+2;
+	}
+	/**
+	 * Returns the contents of the given zip entry as a byte array.
+	 * @throws IOException if a problem occured reading the zip entry.
+	 */
+	public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip)
+		throws IOException {
+
+		InputStream stream = null;
+		try {
+			InputStream inputStream = zip.getInputStream(ze);
+			if (inputStream == null) throw new IOException("Invalid zip entry name : " + ze.getName()); //$NON-NLS-1$
+			stream = new BufferedInputStream(inputStream);
+			return getInputStreamAsByteArray(stream, (int) ze.getSize());
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+		}
+	}
+	public static int hashCode(Object[] array) {
+		int prime = 31;
+		if (array == null) {
+			return 0;
+		}
+		int result = 1;
+		for (int index = 0; index < array.length; index++) {
+			result = prime * result + (array[index] == null ? 0 : array[index].hashCode());
+		}
+		return result;
+	}
+	/**
+	 * Returns whether the given name is potentially a zip archive file name
+	 * (it has a file extension and it is not ".java" nor ".class")
+	 */
+	public final static boolean isPotentialZipArchive(String name) {
+		int lastDot = name.lastIndexOf('.');
+		if (lastDot == -1)
+			return false; // no file extension, it cannot be a zip archive name
+		if (name.lastIndexOf(File.separatorChar) > lastDot)
+			return false; // dot was before the last file separator, it cannot be a zip archive name
+		int length = name.length();
+		int extensionLength = length - lastDot - 1;
+		if (extensionLength == EXTENSION_java.length()) {
+			for (int i = extensionLength-1; i >=0; i--) {
+				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != EXTENSION_java.charAt(i)) {
+					break; // not a ".java" file, check ".class" file case below
+				}
+				if (i == 0) {
+					return false; // it is a ".java" file, it cannot be a zip archive name
+				}
+			}
+		}
+		if (extensionLength == EXTENSION_class.length()) {
+			for (int i = extensionLength-1; i >=0; i--) {
+				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != EXTENSION_class.charAt(i)) {
+					return true; // not a ".class" file, so this is a potential archive name
+				}
+			}
+			return false; // it is a ".class" file, it cannot be a zip archive name
+		}
+		return true; // it is neither a ".java" file nor a ".class" file, so this is a potential archive name
+	}
+
+	/**
+	 * Returns true iff str.toLowerCase().endsWith(".class")
+	 * implementation is not creating extra strings.
+	 */
+	public final static boolean isClassFileName(char[] name) {
+		int nameLength = name == null ? 0 : name.length;
+		int suffixLength = SUFFIX_CLASS.length;
+		if (nameLength < suffixLength) return false;
+
+		for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) {
+			char c = name[offset + i];
+			if (c != SUFFIX_class[i] && c != SUFFIX_CLASS[i]) return false;
+		}
+		return true;
+	}
+	/**
+	 * Returns true iff str.toLowerCase().endsWith(".class")
+	 * implementation is not creating extra strings.
+	 */
+	public final static boolean isClassFileName(String name) {
+		int nameLength = name == null ? 0 : name.length();
+		int suffixLength = SUFFIX_CLASS.length;
+		if (nameLength < suffixLength) return false;
+
+		for (int i = 0; i < suffixLength; i++) {
+			char c = name.charAt(nameLength - i - 1);
+			int suffixIndex = suffixLength - i - 1;
+			if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex]) return false;
+		}
+		return true;
+	}
+	/* TODO (philippe) should consider promoting it to CharOperation
+	 * Returns whether the given resource path matches one of the inclusion/exclusion
+	 * patterns.
+	 * NOTE: should not be asked directly using pkg root pathes
+	 * @see IClasspathEntry#getInclusionPatterns
+	 * @see IClasspathEntry#getExclusionPatterns
+	 */
+	public final static boolean isExcluded(char[] path, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean isFolderPath) {
+		if (inclusionPatterns == null && exclusionPatterns == null) return false;
+
+		inclusionCheck: if (inclusionPatterns != null) {
+			for (int i = 0, length = inclusionPatterns.length; i < length; i++) {
+				char[] pattern = inclusionPatterns[i];
+				char[] folderPattern = pattern;
+				if (isFolderPath) {
+					int lastSlash = CharOperation.lastIndexOf('/', pattern);
+					if (lastSlash != -1 && lastSlash != pattern.length-1){ // trailing slash -> adds '**' for free (see http://ant.apache.org/manual/dirtasks.html)
+						int star = CharOperation.indexOf('*', pattern, lastSlash);
+						if ((star == -1
+								|| star >= pattern.length-1
+								|| pattern[star+1] != '*')) {
+							folderPattern = CharOperation.subarray(pattern, 0, lastSlash);
+						}
+					}
+				}
+				if (CharOperation.pathMatch(folderPattern, path, true, '/')) {
+					break inclusionCheck;
+				}
+			}
+			return true; // never included
+		}
+		if (isFolderPath) {
+			path = CharOperation.concat(path, new char[] {'*'}, '/');
+		}
+		if (exclusionPatterns != null) {
+			for (int i = 0, length = exclusionPatterns.length; i < length; i++) {
+				if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/')) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns true iff str.toLowerCase().endsWith(".java")
+	 * implementation is not creating extra strings.
+	 */
+	public final static boolean isJavaFileName(char[] name) {
+		int nameLength = name == null ? 0 : name.length;
+		int suffixLength = SUFFIX_JAVA.length;
+		if (nameLength < suffixLength) return false;
+
+		for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) {
+			char c = name[offset + i];
+			if (c != SUFFIX_java[i] && c != SUFFIX_JAVA[i]) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns true iff str.toLowerCase().endsWith(".java")
+	 * implementation is not creating extra strings.
+	 */
+	public final static boolean isJavaFileName(String name) {
+		int nameLength = name == null ? 0 : name.length();
+		int suffixLength = SUFFIX_JAVA.length;
+		if (nameLength < suffixLength) return false;
+
+		for (int i = 0; i < suffixLength; i++) {
+			char c = name.charAt(nameLength - i - 1);
+			int suffixIndex = suffixLength - i - 1;
+			if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;
+		}
+		return true;
+	}
+
+	public static void reverseQuickSort(char[][] list, int left, int right) {
+		int original_left= left;
+		int original_right= right;
+		char[] mid= list[left + ((right-left)/2)];
+		do {
+			while (CharOperation.compareTo(list[left], mid) > 0) {
+				left++;
+			}
+			while (CharOperation.compareTo(mid, list[right]) > 0) {
+				right--;
+			}
+			if (left <= right) {
+				char[] tmp= list[left];
+				list[left]= list[right];
+				list[right]= tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			reverseQuickSort(list, original_left, right);
+		}
+		if (left < original_right) {
+			reverseQuickSort(list, left, original_right);
+		}
+	}
+	public static void reverseQuickSort(char[][] list, int left, int right, int[] result) {
+		int original_left= left;
+		int original_right= right;
+		char[] mid= list[left + ((right-left)/2)];
+		do {
+			while (CharOperation.compareTo(list[left], mid) > 0) {
+				left++;
+			}
+			while (CharOperation.compareTo(mid, list[right]) > 0) {
+				right--;
+			}
+			if (left <= right) {
+				char[] tmp= list[left];
+				list[left]= list[right];
+				list[right]= tmp;
+				int temp = result[left];
+				result[left] = result[right];
+				result[right] = temp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			reverseQuickSort(list, original_left, right, result);
+		}
+		if (left < original_right) {
+			reverseQuickSort(list, left, original_right, result);
+		}
+	}
+	/**
+	 * INTERNAL USE-ONLY
+	 * Search the column number corresponding to a specific position
+	 */
+	public static final int searchColumnNumber(int[] startLineIndexes, int lineNumber, int position) {
+		switch(lineNumber) {
+			case 1 :
+				return position + 1;
+			case 2:
+				return position - startLineIndexes[0];
+			default:
+				int line = lineNumber - 2;
+	    		int length = startLineIndexes.length;
+	    		if (line >= length) {
+	    			return position - startLineIndexes[length - 1];
+	    		}
+	    		return position - startLineIndexes[line];
+		}
+	}
+
+	/**
+	 * Converts a boolean value into Boolean.
+	 * @param bool The boolean to convert
+	 * @return The corresponding Boolean object (TRUE or FALSE).
+	 */
+	public static Boolean toBoolean(boolean bool) {
+		if (bool) {
+			return Boolean.TRUE;
+		} else {
+			return Boolean.FALSE;
+		}
+	}
+	/**
+	 * Converts an array of Objects into String.
+	 */
+	public static String toString(Object[] objects) {
+		return toString(objects,
+			new Displayable(){
+				public String displayString(Object o) {
+					if (o == null) return "null"; //$NON-NLS-1$
+					return o.toString();
+				}
+			});
+	}
+
+	/**
+	 * Converts an array of Objects into String.
+	 */
+	public static String toString(Object[] objects, Displayable renderer) {
+		if (objects == null) return ""; //$NON-NLS-1$
+		StringBuffer buffer = new StringBuffer(10);
+		for (int i = 0; i < objects.length; i++){
+			if (i > 0) buffer.append(", "); //$NON-NLS-1$
+			buffer.append(renderer.displayString(objects[i]));
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * outputPath is formed like:
+	 *	   c:\temp\ the last character is a file separator
+	 * relativeFileName is formed like:
+	 *     java\lang\String.class
+	 * @param generatePackagesStructure a flag to know if the packages structure has to be generated.
+	 * @param outputPath the given output directory
+	 * @param relativeFileName the given relative file name
+	 * @param classFile the given classFile to write
+	 *
+	 */
+	public static void writeToDisk(boolean generatePackagesStructure, String outputPath, String relativeFileName, ClassFile classFile) throws IOException {
+		FileOutputStream file = getFileOutputStream(generatePackagesStructure, outputPath, relativeFileName);
+		/* use java.nio to write
+		if (true) {
+			FileChannel ch = file.getChannel();
+			try {
+				ByteBuffer buffer = ByteBuffer.allocate(classFile.headerOffset + classFile.contentsOffset);
+				buffer.put(classFile.header, 0, classFile.headerOffset);
+				buffer.put(classFile.contents, 0, classFile.contentsOffset);
+				buffer.flip();
+				while (true) {
+					if (ch.write(buffer) == 0) break;
+				}
+			} finally {
+				ch.close();
+			}
+			return;
+		}
+		*/
+		BufferedOutputStream output = new BufferedOutputStream(file, DEFAULT_WRITING_SIZE);
+//		BufferedOutputStream output = new BufferedOutputStream(file);
+		try {
+			// if no IOException occured, output cannot be null
+			output.write(classFile.header, 0, classFile.headerOffset);
+			output.write(classFile.contents, 0, classFile.contentsOffset);
+			output.flush();
+		} catch(IOException e) {
+			throw e;
+		} finally {
+			output.close();
+		}
+	}
+	public static void recordNestedType(ClassFile classFile, TypeBinding typeBinding) {
+		if (classFile.visitedTypes == null) {
+			classFile.visitedTypes = new HashSet(3);
+		} else if (classFile.visitedTypes.contains(typeBinding)) {
+			// type is already visited
+			return;
+		}
+		classFile.visitedTypes.add(typeBinding);
+		if (typeBinding.isParameterizedType()
+				&& ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) {
+			ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding;
+			ReferenceBinding genericType = parameterizedTypeBinding.genericType();
+			if ((genericType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				recordNestedType(classFile, genericType);
+			}
+			TypeBinding[] arguments = parameterizedTypeBinding.arguments;
+			if (arguments != null) {
+				for (int j = 0, max2 = arguments.length; j < max2; j++) {
+					TypeBinding argument = arguments[j];
+					if (argument.isWildcard()) {
+						WildcardBinding wildcardBinding = (WildcardBinding) argument;
+						TypeBinding bound = wildcardBinding.bound;
+						if (bound != null
+								&& ((bound.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) {
+							recordNestedType(classFile, bound);
+						}
+						ReferenceBinding superclass = wildcardBinding.superclass();
+						if (superclass != null
+								&& ((superclass.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) {
+							recordNestedType(classFile, superclass);
+						}
+						ReferenceBinding[] superInterfaces = wildcardBinding.superInterfaces();
+						if (superInterfaces != null) {
+							for (int k = 0, max3 =  superInterfaces.length; k < max3; k++) {
+								ReferenceBinding superInterface = superInterfaces[k];
+								if ((superInterface.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+									recordNestedType(classFile, superInterface);
+								}
+							}
+						}
+					} else if ((argument.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+						recordNestedType(classFile, argument);
+					}
+				}
+			}
+		} else if (typeBinding.isTypeVariable()
+				&& ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding;
+			TypeBinding upperBound = typeVariableBinding.upperBound();
+			if (upperBound != null && ((upperBound.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) {
+				recordNestedType(classFile, upperBound);
+			}
+			TypeBinding[] upperBounds = typeVariableBinding.otherUpperBounds();
+			if (upperBounds != null) {
+				for (int k = 0, max3 =  upperBounds.length; k < max3; k++) {
+					TypeBinding otherUpperBound = upperBounds[k];
+					if ((otherUpperBound.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+						recordNestedType(classFile, otherUpperBound);
+					}
+				}
+			}
+		} else if (typeBinding.isNestedType()) {
+			classFile.recordInnerClasses(typeBinding);
+		}
+	}
+	/*
+	 * External API
+	 */
+	public static File getJavaHome() {
+		String javaHome = System.getProperty("java.home");//$NON-NLS-1$
+		if (javaHome != null) {
+			File javaHomeFile = new File(javaHome);
+			if (javaHomeFile.exists()) {
+				return javaHomeFile;
+			}
+		}
+		return null;
+	}
+
+	public static void collectRunningVMBootclasspath(List bootclasspaths) {
+		/* no bootclasspath specified
+		 * we can try to retrieve the default librairies of the VM used to run
+		 * the batch compiler
+		 */
+		String javaversion = System.getProperty("java.version");//$NON-NLS-1$
+		if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
+			throw new IllegalStateException();
+		}
+
+		/*
+		 * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath
+		 */
+		// check bootclasspath properties for Sun, JRockit and Harmony VMs
+		String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
+		if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
+			// IBM J9 VMs
+			bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$
+			if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
+				// Harmony using IBM VME
+				bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$
+			}
+		}
+		if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) {
+			StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator);
+			String token;
+			while (tokenizer.hasMoreTokens()) {
+				token = tokenizer.nextToken();
+				FileSystem.Classpath currentClasspath = FileSystem.getClasspath(token, null, null);
+				if (currentClasspath != null) {
+					bootclasspaths.add(currentClasspath);
+				}
+			}
+		} else {
+			// try to get all jars inside the lib folder of the java home
+			final File javaHome = getJavaHome();
+			if (javaHome != null) {
+				File[] directoriesToCheck = null;
+				if (System.getProperty("os.name").startsWith("Mac")) {//$NON-NLS-1$//$NON-NLS-2$
+					directoriesToCheck = new File[] {
+						new File(javaHome, "../Classes"), //$NON-NLS-1$
+					};
+				} else {
+					// fall back to try to retrieve them out of the lib directory
+					directoriesToCheck = new File[] {
+						new File(javaHome, "lib") //$NON-NLS-1$
+					};
+				}
+				File[][] systemLibrariesJars = Main.getLibrariesFiles(directoriesToCheck);
+				if (systemLibrariesJars != null) {
+					for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
+						File[] current = systemLibrariesJars[i];
+						if (current != null) {
+							for (int j = 0, max2 = current.length; j < max2; j++) {
+								FileSystem.Classpath classpath =
+									FileSystem.getClasspath(current[j].getAbsolutePath(),
+										null, false, null, null);
+								if (classpath != null) {
+									bootclasspaths.add(classpath);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	public static int getParameterCount(char[] methodSignature) {
+		try {
+			int count = 0;
+			int i = CharOperation.indexOf(C_PARAM_START, methodSignature);
+			if (i < 0) {
+				throw new IllegalArgumentException();
+			} else {
+				i++;
+			}
+			for (;;) {
+				if (methodSignature[i] == C_PARAM_END) {
+					return count;
+				}
+				int e= Util.scanTypeSignature(methodSignature, i);
+				if (e < 0) {
+					throw new IllegalArgumentException();
+				} else {
+					i = e + 1;
+				}
+				count++;
+			}
+		} catch (ArrayIndexOutOfBoundsException e) {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for a type signature starting at the given index
+	 * and returns the index of the last character.
+	 * <pre>
+	 * TypeSignature:
+	 *  |  BaseTypeSignature
+	 *  |  ArrayTypeSignature
+	 *  |  ClassTypeSignature
+	 *  |  TypeVariableSignature
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type signature
+	 */
+	public static int scanTypeSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case C_ARRAY :
+				return scanArrayTypeSignature(string, start);
+			case C_RESOLVED :
+			case C_UNRESOLVED :
+				return scanClassTypeSignature(string, start);
+			case C_TYPE_VARIABLE :
+				return scanTypeVariableSignature(string, start);
+			case C_BOOLEAN :
+			case C_BYTE :
+			case C_CHAR :
+			case C_DOUBLE :
+			case C_FLOAT :
+			case C_INT :
+			case C_LONG :
+			case C_SHORT :
+			case C_VOID :
+				return scanBaseTypeSignature(string, start);
+			case C_CAPTURE :
+				return scanCaptureTypeSignature(string, start);
+			case C_EXTENDS:
+			case C_SUPER:
+			case C_STAR:
+				return scanTypeBoundSignature(string, start);
+			default :
+				throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for a base type signature starting at the given index
+	 * and returns the index of the last character.
+	 * <pre>
+	 * BaseTypeSignature:
+	 *     <b>B</b> | <b>C</b> | <b>D</b> | <b>F</b> | <b>I</b>
+	 *   | <b>J</b> | <b>S</b> | <b>V</b> | <b>Z</b>
+	 * </pre>
+	 * Note that although the base type "V" is only allowed in method return types,
+	 * there is no syntactic ambiguity. This method will accept them anywhere
+	 * without complaint.
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a base type signature
+	 */
+	public static int scanBaseTypeSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if ("BCDFIJSVZ".indexOf(c) >= 0) { //$NON-NLS-1$
+			return start;
+		} else {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for an array type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * ArrayTypeSignature:
+	 *     <b>[</b> TypeSignature
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not an array type signature
+	 */
+	public static int scanArrayTypeSignature(char[] string, int start) {
+		int length = string.length;
+		// need a minimum 2 char
+		if (start >= length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != C_ARRAY) {
+			throw new IllegalArgumentException();
+		}
+	
+		c = string[++start];
+		while(c == C_ARRAY) {
+			// need a minimum 2 char
+			if (start >= length - 1) {
+				throw new IllegalArgumentException();
+			}
+			c = string[++start];
+		}
+		return scanTypeSignature(string, start);
+	}
+
+	/**
+	 * Scans the given string for a capture of a wildcard type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * CaptureTypeSignature:
+	 *     <b>!</b> TypeBoundSignature
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a capture type signature
+	 */
+	public static int scanCaptureTypeSignature(char[] string, int start) {
+		// need a minimum 2 char
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != C_CAPTURE) {
+			throw new IllegalArgumentException();
+		}
+		return scanTypeBoundSignature(string, start + 1);
+	}
+
+	/**
+	 * Scans the given string for a type variable signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeVariableSignature:
+	 *     <b>T</b> Identifier <b>;</b>
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type variable signature
+	 */
+	public static int scanTypeVariableSignature(char[] string, int start) {
+		// need a minimum 3 chars "Tx;"
+		if (start >= string.length - 2) {
+			throw new IllegalArgumentException();
+		}
+		// must start in "T"
+		char c = string[start];
+		if (c != C_TYPE_VARIABLE) {
+			throw new IllegalArgumentException();
+		}
+		int id = scanIdentifier(string, start + 1);
+		c = string[id + 1];
+		if (c == C_SEMICOLON) {
+			return id + 1;
+		} else {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for an identifier starting at the given
+	 * index and returns the index of the last character.
+	 * Stop characters are: ";", ":", "&lt;", "&gt;", "/", ".".
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not an identifier
+	 */
+	public static int scanIdentifier(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		int p = start;
+		while (true) {
+			char c = string[p];
+			if (c == '<' || c == '>' || c == ':' || c == ';' || c == '.' || c == '/') {
+				return p - 1;
+			}
+			p++;
+			if (p == string.length) {
+				return p - 1;
+			}
+		}
+	}
+
+	/**
+	 * Scans the given string for a class type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * ClassTypeSignature:
+	 *     { <b>L</b> | <b>Q</b> } Identifier
+	 *           { { <b>/</b> | <b>.</b> Identifier [ <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b> ] }
+	 *           <b>;</b>
+	 * </pre>
+	 * Note that although all "/"-identifiers most come before "."-identifiers,
+	 * there is no syntactic ambiguity. This method will accept them without
+	 * complaint.
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a class type signature
+	 */
+	public static int scanClassTypeSignature(char[] string, int start) {
+		// need a minimum 3 chars "Lx;"
+		if (start >= string.length - 2) {
+			throw new IllegalArgumentException();
+		}
+		// must start in "L" or "Q"
+		char c = string[start];
+		if (c != C_RESOLVED && c != C_UNRESOLVED) {
+			return -1;
+		}
+		int p = start + 1;
+		while (true) {
+			if (p >= string.length) {
+				throw new IllegalArgumentException();
+			}
+			c = string[p];
+			if (c == C_SEMICOLON) {
+				// all done
+				return p;
+			} else if (c == C_GENERIC_START) {
+				int e = scanTypeArgumentSignatures(string, p);
+				p = e;
+			} else if (c == C_DOT || c == '/') {
+				int id = scanIdentifier(string, p + 1);
+				p = id;
+			}
+			p++;
+		}
+	}
+
+	/**
+	 * Scans the given string for a type bound signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeBoundSignature:
+	 *     <b>[-+]</b> TypeSignature <b>;</b>
+	 *     <b>*</b></b>
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type variable signature
+	 */
+	public static int scanTypeBoundSignature(char[] string, int start) {
+		// need a minimum 1 char for wildcard
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case C_STAR :
+				return start;
+			case C_SUPER :
+			case C_EXTENDS :
+				// need a minimum 3 chars "+[I"
+				if (start >= string.length - 2) {
+					throw new IllegalArgumentException();
+				}
+				break;
+			default :
+				// must start in "+/-"
+					throw new IllegalArgumentException();
+	
+		}
+		c = string[++start];
+		switch (c) {
+			case C_CAPTURE :
+				return scanCaptureTypeSignature(string, start);
+			case C_SUPER :
+			case C_EXTENDS :
+				return scanTypeBoundSignature(string, start);
+			case C_RESOLVED :
+			case C_UNRESOLVED :
+				return scanClassTypeSignature(string, start);
+			case C_TYPE_VARIABLE :
+				return scanTypeVariableSignature(string, start);
+			case C_ARRAY :
+				return scanArrayTypeSignature(string, start);
+			case C_STAR:
+				return start;
+			default:
+				throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for a list of type argument signatures starting at
+	 * the given index and returns the index of the last character.
+	 * <pre>
+	 * TypeArgumentSignatures:
+	 *     <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b>
+	 * </pre>
+	 * Note that although there is supposed to be at least one type argument, there
+	 * is no syntactic ambiguity if there are none. This method will accept zero
+	 * type argument signatures without complaint.
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a list of type arguments
+	 * signatures
+	 */
+	public static int scanTypeArgumentSignatures(char[] string, int start) {
+		// need a minimum 2 char "<>"
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != C_GENERIC_START) {
+			throw new IllegalArgumentException();
+		}
+		int p = start + 1;
+		while (true) {
+			if (p >= string.length) {
+				throw new IllegalArgumentException();
+			}
+			c = string[p];
+			if (c == C_GENERIC_END) {
+				return p;
+			}
+			int e = scanTypeArgumentSignature(string, p);
+			p = e + 1;
+		}
+	}
+
+	/**
+	 * Scans the given string for a type argument signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeArgumentSignature:
+	 *     <b>&#42;</b>
+	 *  |  <b>+</b> TypeSignature
+	 *  |  <b>-</b> TypeSignature
+	 *  |  TypeSignature
+	 * </pre>
+	 * Note that although base types are not allowed in type arguments, there is
+	 * no syntactic ambiguity. This method will accept them without complaint.
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type argument signature
+	 */
+	public static int scanTypeArgumentSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case C_STAR :
+				return start;
+			case C_EXTENDS :
+			case C_SUPER :
+				return scanTypeBoundSignature(string, start);
+			default :
+				return scanTypeSignature(string, start);
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/component.xml b/org.eclipse.jdt.core/component.xml
new file mode 100644
index 0000000..6199452
--- /dev/null
+++ b/org.eclipse.jdt.core/component.xml
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2005, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<component xmlns="http://eclipse.org/component"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://eclipse.org/component ../component.xsd "
+   name="org.eclipse.jdt.core">
+ <plugin id="org.eclipse.jdt.core" />
+
+ <package name="org.eclipse.jdt.core.compiler.batch">
+   <type name="BatchCompiler" subclass="false" instantiate="false" /> 
+ </package>
+ <package name="org.eclipse.jdt.core">
+   <type name="BindingKey" subclass="false" />
+   <type name="BufferChangedEvent" subclass="false" instantiate="false"/>
+   <type name="ClasspathContainerInitializer" instantiate="false"/>
+   <type name="ClasspathVariableInitializer" instantiate="false"/>
+   <type name="CompletionContext" subclass="false" instantiate="false"/>
+   <type name="CompletionProposal" subclass="false" instantiate="false"/>
+   <type name="CompletionRequestor" instantiate="false"/>
+   <type name="CompletionRequestorAdapter"/>
+   <type name="CorrectionEngine" subclass="false"/>
+   <type name="ElementChangedEvent" subclass="false" instantiate="false"/>
+   <type name="Flags" subclass="false" instantiate="false"/>
+   <type name="IAccessRule"/>
+   <type name="IBuffer"/>
+   <type name="IBufferChangedListener"/>
+   <type name="IBufferFactory"/>
+   <type name="IClassFile" implement="false"/>
+   <type name="IClasspathAttribute" implement="false"/>
+   <type name="IClasspathContainer"/>
+   <type name="IClasspathEntry" implement="false"/>
+   <type name="ICodeAssist" implement="false"/>
+   <type name="ICodeCompletionRequestor"/>
+   <type name="ICodeFormatter"/>
+   <type name="ICompilationUnit" implement="false"/>
+   <type name="ICompletionRequestor"/>
+   <type name="ICorrectionRequestor"/>
+   <type name="IElementChangedListener"/>
+   <type name="IField" implement="false"/>
+   <type name="IImportContainer" implement="false"/>
+   <type name="IImportDeclaration" implement="false"/>
+   <type name="IInitializer" implement="false"/>
+   <type name="IJavaElement" implement="false"/>
+   <type name="IJavaElementDelta" implement="false"/>
+   <type name="IJavaModel" implement="false"/>
+   <type name="IJavaModelMarker" implement="false"/>
+   <type name="IJavaModelStatus" implement="false"/>
+   <type name="IJavaModelStatusConstants" implement="false"/>
+   <type name="IJavaProject" implement="false"/>
+   <type name="ILocalVariable" implement="false"/>
+   <type name="IMember" implement="false"/>
+   <type name="IMethod" implement="false"/>
+   <type name="IOpenable" implement="false"/>
+   <type name="IPackageDeclaration" implement="false"/>
+   <type name="IPackageFragment" implement="false"/>
+   <type name="IPackageFragmentRoot" implement="false"/>
+   <type name="IParent" implement="false"/>
+   <type name="IProblemRequestor"/>
+   <type name="IRegion" implement="false"/>
+   <type name="ISourceManipulation" implement="false"/>
+   <type name="ISourceRange" implement="false"/>
+   <type name="ISourceReference" implement="false"/>
+   <type name="IType" implement="false"/>
+   <type name="ITypeHierarchy" implement="false"/>
+   <type name="ITypeHierarchyChangedListener"/>
+   <type name="ITypeParameter" implement="false"/>
+   <type name="IWorkingCopy" implement="false"/>
+   <type name="JavaConventions" subclass="false" instantiate="false"/>
+   <type name="JavaCore" subclass="false" instantiate="false"/>
+   <type name="JavaModelException" subclass="false" instantiate="false"/>
+   <type name="NamingConventions" subclass="false" instantiate="false"/>
+   <type name="Signature" subclass="false" instantiate="false"/>
+   <type name="ToolFactory" subclass="false" instantiate="false"/>
+   <type name="WorkingCopyOwner" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.compiler">
+   <type name="BuildContext" subclass="false" instantiate="false"/>
+   <type name="CategorizedProblem" instantiate="false"/>
+   <type name="CharOperation" subclass="false" instantiate="false"/>
+   <type name="CompilationParticipant" instantiate="false"/>
+   <type name="InvalidInputException" subclass="false" instantiate="false"/>
+   <type name="IProblem" implement="false"/>
+   <type name="IScanner" implement="false"/>
+   <type name="ITerminalSymbols" implement="false"/>
+   <type name="ReconcileContext" subclass="false" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.dom">
+   <type name="AbstractTypeDeclaration" instantiate="false"/>
+   <type name="Annotation" instantiate="false"/>
+   <type name="AnnotationBinding" reference="false"/>
+   <type name="AnnotationTypeDeclaration" instantiate="false"/>
+   <type name="AnnotationTypeMemberDeclaration" instantiate="false"/>
+   <type name="AnonymousClassDeclaration" instantiate="false"/>
+   <type name="ArrayAccess" instantiate="false"/>
+   <type name="ArrayCreation" instantiate="false"/>
+   <type name="ArrayInitializer" instantiate="false"/>
+   <type name="ArrayType" instantiate="false"/>
+   <type name="AssertStatement" instantiate="false"/>
+   <type name="Assignment" instantiate="false"/>
+   <type name="AST" subclass="false" instantiate="false"/>
+   <type name="ASTConverter" reference="false"/>
+   <type name="ASTMatcher"/>
+   <type name="ASTNode" subclass="false" instantiate="false"/>
+   <type name="ASTParser" instantiate="false"/>
+   <type name="ASTRecoveryPropagator" reference="false"/>  
+   <type name="ASTRequestor" instantiate="false"/>
+   <type name="ASTSyntaxErrorPropagator" reference="false"/>
+   <type name="ASTVisitor"/>
+   <type name="BindingComparator" reference="false"/>
+   <type name="BindingResolver" reference="false"/>
+   <type name="Block" instantiate="false"/>
+   <type name="BlockComment" subclass="false" instantiate="false"/>
+   <type name="BodyDeclaration" instantiate="false"/>
+   <type name="BooleanLiteral" instantiate="false"/>
+   <type name="BreakStatement" instantiate="false"/>
+   <type name="CastExpression" instantiate="false"/>
+   <type name="CatchClause" instantiate="false"/>
+   <type name="CharacterLiteral" instantiate="false"/>
+   <type name="ChildListPropertyDescriptor" subclass="false" instantiate="false"/>
+   <type name="ChildPropertyDescriptor" subclass="false" instantiate="false"/>
+   <type name="ClassInstanceCreation" instantiate="false"/>
+   <type name="Comment" instantiate="false"/>
+   <type name="CompilationUnit" instantiate="false"/>
+   <type name="CompilationUnitResolver" reference="false"/>
+   <type name="ConditionalExpression" instantiate="false"/>
+   <type name="ConstructorInvocation" instantiate="false"/>
+   <type name="ContinueStatement" instantiate="false"/>
+   <type name="DefaultASTVisitor" reference="false"/>
+   <type name="DefaultBindingResolver" reference="false"/>
+   <type name="DefaultCommentMapper" reference="false"/>
+   <type name="DefaultValuePairBinding" reference="false"/>
+   <type name="DocCommentParser" reference="false"/>
+   <type name="DoStatement" instantiate="false"/>
+   <type name="EmptyStatement" instantiate="false"/>
+   <type name="EnhancedForStatement" instantiate="false"/>
+   <type name="EnumConstantDeclaration" instantiate="false"/>
+   <type name="EnumDeclaration" instantiate="false"/>
+   <type name="Expression" instantiate="false"/>
+   <type name="ExpressionStatement" instantiate="false"/>
+   <type name="FieldAccess" instantiate="false"/>
+   <type name="FieldDeclaration" instantiate="false"/>
+   <type name="ForStatement" instantiate="false"/>
+   <type name="IAnnotationBinding" instantiate="false" implement="false"/>
+   <type name="IBinding" instantiate="false" implement="false"/>
+   <type name="IDocElement" reference="false"/>
+   <type name="IExtendedModifier" instantiate="false"/>
+   <type name="IfStatement" instantiate="false"/>
+   <type name="IMemberValuePairBinding" instantiate="false" implement="false"/>
+   <type name="IMethodBinding" instantiate="false" implement="false"/>
+   <type name="ImportDeclaration" instantiate="false"/>
+   <type name="InfixExpression" instantiate="false"/>
+   <type name="Initializer" instantiate="false"/>
+   <type name="InstanceofExpression" instantiate="false"/>
+   <type name="InternalASTRewrite" reference="false"/>
+   <type name="IPackageBinding" implement="false"/>
+   <type name="ITypeBinding" implement="false"/>
+   <type name="IVariableBinding" implement="false"/>
+   <type name="Javadoc" instantiate="false"/>
+   <type name="LabeledStatement" instantiate="false"/>
+   <type name="LineComment" instantiate="false" subclass="false"/>
+   <type name="MarkerAnnotation" instantiate="false"/>
+   <type name="MemberRef" instantiate="false"/>
+   <type name="MemberValuePair" instantiate="false"/>
+   <type name="MemberValuePairBinding" reference="false"/>
+   <type name="Message"/>
+   <type name="MethodBinding" reference="false"/>
+   <type name="MethodDeclaration" instantiate="false"/>
+   <type name="MethodInvocation" instantiate="false"/>
+   <type name="MethodRef" instantiate="false"/>
+   <type name="MethodRefParameter" instantiate="false"/>
+   <type name="Modifier" instantiate="false" subclass="false"/>
+   <type name="Name" instantiate="false" subclass="false"/>
+   <type name="NodeEventHandler" reference="false"/>
+   <type name="NodeSearcher" reference="false"/>
+   <type name="NormalAnnotation" instantiate="false"/>
+   <type name="NullLiteral" instantiate="false"/>
+   <type name="NumberLiteral" instantiate="false"/>
+   <type name="PackageBinding" reference="false"/>
+   <type name="PackageDeclaration" instantiate="false"/>
+   <type name="ParameterizedType" instantiate="false"/>
+   <type name="ParenthesizedExpression" instantiate="false"/>
+   <type name="PostfixExpression" instantiate="false"/>
+   <type name="PrefixExpression" instantiate="false"/>
+   <type name="PrimitiveType" instantiate="false"/>
+   <type name="QualifiedName" instantiate="false"/>
+   <type name="QualifiedType" instantiate="false"/>
+   <type name="ReturnStatement" instantiate="false"/>
+   <type name="SimpleName" instantiate="false"/>
+   <type name="SimplePropertyDescriptor" subclass="false" instantiate="false"/>
+   <type name="SimpleType" instantiate="false"/>
+   <type name="SingleMemberAnnotation" instantiate="false"/>
+   <type name="SingleVariableDeclaration" instantiate="false"/>
+   <type name="Statement" instantiate="false"/>
+   <type name="StringLiteral" instantiate="false"/>
+   <type name="StructuralPropertyDescriptor" subclass="false" instantiate="false"/>
+   <type name="SuperConstructorInvocation" instantiate="false"/>
+   <type name="SuperFieldAccess" instantiate="false"/>
+   <type name="SuperMethodInvocation" instantiate="false"/>
+   <type name="SwitchCase" instantiate="false"/>
+   <type name="SwitchStatement" instantiate="false"/>
+   <type name="SynchronizedStatement" instantiate="false"/>
+   <type name="TagElement" instantiate="false" subclass="false"/>
+   <type name="TextElement" instantiate="false" subclass="false"/>
+   <type name="ThisExpression" instantiate="false"/>
+   <type name="ThrowStatement" instantiate="false"/>
+   <type name="TryStatement" instantiate="false"/>
+   <type name="Type" instantiate="false"/>
+   <type name="TypeBinding" reference="false"/>
+   <type name="TypeDeclaration" instantiate="false"/>
+   <type name="TypeDeclarationStatement" instantiate="false"/>
+   <type name="TypeLiteral" instantiate="false"/>
+   <type name="TypeParameter" instantiate="false"/>
+   <type name="VariableBinding" reference="false"/>
+   <type name="VariableDeclaration" instantiate="false"/>
+   <type name="VariableDeclarationExpression" instantiate="false"/>
+   <type name="VariableDeclarationFragment" instantiate="false"/>
+   <type name="VariableDeclarationStatement" instantiate="false"/>
+   <type name="WhileStatement" instantiate="false"/>
+   <type name="WildcardType" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.dom.rewrite">
+   <type name="ASTRewrite" subclass="false" instantiate="false"/>
+   <type name="ImportRewrite" subclass="false"/>
+   <type name="ITrackedNodePosition" implement="false"/>
+   <type name="ListRewrite" subclass="false"/>
+   <type name="TargetSourceRangeComputer"/> 
+ </package>
+ <package name="org.eclipse.jdt.core.eval">
+   <type name="ICodeSnippetRequestor"/>
+   <type name="IEvaluationContext" implement="false"/>
+   <type name="IGlobalVariable" implement="false"/>   
+ </package>
+ <package name="org.eclipse.jdt.core.formatter">
+   <type name="CodeFormatter" subclass="false" instantiate="false"/>
+   <type name="CodeFormatterApplication" subclass="false" instantiate="false"/>
+   <type name="DefaultCodeFormatterConstants" subclass="false" instantiate="false"/>
+   <type name="IndentManipulation" subclass="false" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.jdom">
+   <type name="DOMException"/>
+   <type name="DOMFactory" subclass="false"/>
+   <type name="IDOMCompilationUnit" implement="false"/>
+   <type name="IDOMFactory" implement="false"/>
+   <type name="IDOMField" implement="false"/>
+   <type name="IDOMImport" implement="false"/>
+   <type name="IDOMInitializer" implement="false"/>
+   <type name="IDOMMember" implement="false"/>
+   <type name="IDOMMethod" implement="false"/>
+   <type name="IDOMNode" implement="false"/>
+   <type name="IDOMPackage" implement="false"/>
+   <type name="IDOMType" implement="false"/> 
+ </package>
+ <package name="org.eclipse.jdt.core.search">
+   <type name="FieldDeclarationMatch"/>
+   <type name="FieldReferenceMatch"/>
+   <type name="IJavaSearchConstants" implement="false"/>
+   <type name="IJavaSearchResultCollector"/>
+   <type name="IJavaSearchScope"/>
+   <type name="ISearchPattern"/>
+   <type name="ITypeNameRequestor"/>
+   <type name="LocalVariableDeclarationMatch"/>
+   <type name="LocalVariableReferenceMatch"/>
+   <type name="MethodDeclarationMatch"/>
+   <type name="MethodReferenceMatch"/>
+   <type name="PackageDeclarationMatch"/>
+   <type name="PackageReferenceMatch"/>
+   <type name="SearchDocument" instantiate="false"/>
+   <type name="SearchEngine" subclass="false"/>
+   <type name="SearchMatch"/>
+   <type name="SearchParticipant" instantiate="false"/>
+   <type name="SearchPattern" instantiate="false"/>
+   <type name="SearchRequestor" instantiate="false"/>
+   <type name="TypeDeclarationMatch"/>
+   <type name="TypeNameRequestor" instantiate="false"/>
+   <type name="TypeParameterDeclarationMatch"/>
+   <type name="TypeParameterReferenceMatch"/>
+   <type name="TypeReferenceMatch"/>
+ </package>
+ <package name="org.eclipse.jdt.core.util">
+   <type name="ByteCodeVisitorAdapter"/>
+   <type name="ClassFileBytesDisassembler"/>
+   <type name="ClassFormatException"/>
+   <type name="CompilationUnitSorter" subclass="false" instantiate="false"/>
+   <type name="IAnnotation"/>
+   <type name="IAnnotationComponent"/>
+   <type name="IAnnotationComponentValue"/>
+   <type name="IAnnotationDefaultAttribute"/>
+   <type name="IAttributeNamesConstants" implement="false"/>
+   <type name="IBytecodeVisitor" implement="false"/>
+   <type name="IClassFileAttribute"/>
+   <type name="IClassFileDisassembler"/>
+   <type name="IClassFileReader"/>
+   <type name="ICodeAttribute"/>
+   <type name="IConstantPool"/>
+   <type name="IConstantPoolConstant" implement="false"/>
+   <type name="IConstantPoolEntry"/>
+   <type name="IConstantValueAttribute"/>
+   <type name="IEnclosingMethodAttribute"/>
+   <type name="IExceptionAttribute"/>
+   <type name="IExceptionTableEntry"/>
+   <type name="IFieldInfo"/>
+   <type name="IInnerClassesAttribute"/>
+   <type name="IInnerClassesAttributeEntry"/>
+   <type name="ILineNumberAttribute"/>
+   <type name="ILocalVariableAttribute"/>
+   <type name="ILocalVariableTableEntry"/>
+   <type name="ILocalVariableTypeTableAttribute"/>
+   <type name="ILocalVariableTypeTableEntry"/>
+   <type name="IMethodInfo"/>
+   <type name="IModifierConstants" implement="false"/>
+   <type name="IOpcodeMnemonics" implement="false"/>
+   <type name="IParameterAnnotation"/>
+   <type name="IRuntimeInvisibleAnnotationsAttribute"/>
+   <type name="IRuntimeInvisibleParameterAnnotationsAttribute"/>
+   <type name="IRuntimeVisibleAnnotationsAttribute"/>
+   <type name="IRuntimeVisibleParameterAnnotationsAttribute"/>
+   <type name="ISignatureAttribute"/>
+   <type name="ISourceAttribute"/>
+   <type name="IStackMapAttribute"/>
+   <type name="IStackMapFrame"/>
+   <type name="IStackMapTableAttribute"/>
+   <type name="IVerificationTypeInfo"/>
+   <type name="OpcodeStringValues" subclass="false" instantiate="false"/>
+ </package>
+ 
+<component-depends unrestricted="true"/>
+</component>
diff --git a/org.eclipse.jdt.core/customBuildCallbacks.xml b/org.eclipse.jdt.core/customBuildCallbacks.xml
new file mode 100644
index 0000000..44361d0
--- /dev/null
+++ b/org.eclipse.jdt.core/customBuildCallbacks.xml
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2006, 2011 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<!-- ===================================================================== -->
+<!-- Custom targets called from a project's generated build.xml            -->
+<!-- Set customBuildCallbacks=<path/to/this/file> in your build.properties.-->
+<!-- ===================================================================== -->
+<project name="Build specific targets and properties" default="noDefault">
+
+	<!-- ===================================================================== -->
+	<!-- Default target                                                        -->
+	<!-- ===================================================================== -->
+	<target name="noDefault">
+		<echo message="This file must be called with explicit targets" />
+	</target>
+	
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target build.jars                              -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder to contain the build results           -->
+	<!-- ===================================================================== -->
+	<target name="pre.build.jars">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target build.jars                               -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder to contain the build results           -->
+	<!-- ===================================================================== -->
+	<target name="post.build.jars">
+		<property name="buildLabel" value="global" />
+		<property name="build.result.folder" value="${basedir}" />
+		<property name="postingDirectory" value="${build.result.folder}/ecj" />
+		<property name="dest" value="${postingDirectory}/${buildLabel}" />
+		<ant antfile="${basedir}/scripts/export-ecj.xml" target="export"/>
+	</target>
+	
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target build.sources                           -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder to contain the build results           -->
+	<!-- ===================================================================== -->
+	<target name="pre.build.sources">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target build.sources                            -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder to contain the build results           -->
+	<!-- ===================================================================== -->
+	<target name="post.build.sources">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the compilation target <name>                      -->
+	<!-- Substitute "name" with the name of the compilation target, eg @dot    -->
+	<!-- Available parameters :                                                -->
+	<!--   source.foldern : n = 1 ... N, the source folders                    -->
+	<!--   target.folder  : where the results of the compilation go            -->
+	<!--   <name>.classpath : name = name of the compilation target. A         -->
+	<!--                      reference to the classpath structure.            -->
+	<!-- ===================================================================== -->
+	<target name="pre.name">
+	</target>
+
+	<target name="pre.@dot">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do during the compilation target <name>, after the compile   -->
+	<!-- but before jaring.  Substitute "name" with the name of the compilation-->
+	<!-- target, eg @dot                                                       -->
+	<!-- Available parameters :                                                -->
+	<!--   source.foldern : n = 1 ... N, the source folders                    -->
+	<!--   target.folder  : where the results of the compilation go            -->
+	<!--   <name>.classpath : name = name of the compilation target. A         -->
+	<!--                      reference to the classpath structure.            -->
+	<!-- ===================================================================== -->
+	<target name="post.compile.name">
+	</target>
+
+	<target name="post.compile.@dot">
+		<ant antfile="${basedir}/scripts/export-ecj.xml" target="extract-batch-compiler"/>
+	</target>
+	
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the compilation target <name>                       -->
+	<!-- Substitute "name" with the name of the compilation target, eg @dot    -->
+	<!-- Available parameters :                                                -->
+	<!--   jar.location - the location of the compilation results              -->
+	<!--   <name>.classpath : name = name of the compilation target. A         -->
+	<!--                      reference to the classpath structure.            -->
+	<!-- ===================================================================== -->
+	<target name="post.name">
+	</target>
+
+	<target name="post.@dot">
+	</target>
+	
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target gather.bin.parts                         -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder containing the build results           -->
+	<!--   target.folder - destination folder                                  -->
+	<!-- ===================================================================== -->
+	<target name="pre.gather.bin.parts">
+	</target>
+		
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target gather.bin.parts                         -->
+	<!-- Available parameters :                                                -->
+	<!--   build.result.folder - folder containing the build results           -->
+	<!--   target.folder - destination folder                                  -->
+	<!-- ===================================================================== -->
+	<target name="post.gather.bin.parts">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target gather.sources                          -->
+	<!-- Available parameters :                                                -->
+	<!--   destination.temp.folder - destination folder                        -->
+	<!-- ===================================================================== -->
+	<target name="pre.gather.sources">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target gather.sources                           -->
+	<!-- Available parameters :                                                -->
+	<!--   destination.temp.folder - destination folder                        -->
+	<!-- ===================================================================== -->
+	<target name="post.gather.sources">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target gather.logs                             -->
+	<!-- Available parameters :                                                -->
+	<!--   destination.temp.folder - destination folder                        -->
+	<!-- ===================================================================== -->
+	<target name="pre.gather.logs">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target gather.logs                              -->
+	<!-- Available parameters :                                                -->
+	<!--   destination.temp.folder - destination folder                        -->
+	<!-- ===================================================================== -->
+	<target name="post.gather.logs">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target clean                                   -->
+	<!-- Available parameters :                                                -->
+	<!--   destination.temp.folder - destination folder                        -->
+	<!-- ===================================================================== -->
+	<target name="pre.clean">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target clean                                    -->
+	<!-- Available parameters :                                                -->
+	<!--   plugin.destination - final destination of the build                 -->
+	<!--   build.result.folder - results of the compilation                    -->
+	<!--   temp.folder - temporary folder                                      -->
+	<!-- ===================================================================== -->
+	<target name="post.clean">
+	</target>
+	
+	<!-- ===================================================================== -->
+	<!-- Steps to do before the target jdtCompilerAdapter.jar                  -->
+	<!-- ===================================================================== -->
+	<target name="pre.jdtCompilerAdapter.jar">
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target compile.jdtCompilerAdapter.jar           -->
+	<!-- ===================================================================== -->
+	<!-- Steps to do during the compilation target <name>, after the compile   -->
+	<!-- but before jaring.  Substitute "name" with the name of the compilation-->
+	<!-- target, eg @dot                                                       -->
+	<!-- Available parameters :                                                -->
+	<!--   source.foldern : n = 1 ... N, the source folders                    -->
+	<!--   target.folder  : where the results of the compilation go            -->
+	<!--   <name>.classpath : name = name of the compilation target. A         -->
+	<!--                      reference to the classpath structure.            -->
+	<!-- ===================================================================== -->
+	<target name="post.compile.jdtCompilerAdapter.jar">
+		<ant antfile="${basedir}/scripts/export-ecj.xml" target="extract-ant-adapter-compiler"/>
+		<copy todir="${target.folder}">
+			<fileset dir="${basedir}/scripts/antadapter">
+				<include name="plugin.properties"/>
+				<include name="plugin.xml"/>
+			</fileset>
+		</copy>	
+	</target>
+
+	<!-- ===================================================================== -->
+	<!-- Steps to do after the target jdtCompilerAdapter.jar                   -->
+	<!--   jar.Location : the location of the file jdtCompilerAdapter.jar      -->
+	<!-- ===================================================================== -->
+	<target name="post.jdtCompilerAdapter.jar">
+		<property name="unjarDestBin" value="${basedir}/tempbin"/>
+		<mkdir dir="${unjarDestBin}"/>
+		<unjar src="${jar.Location}" dest="${unjarDestBin}"/>
+		<delete file="${jar.Location}" />
+		<delete file="${unjarDestBin}/META-INF/MANIFEST.MF" failonerror="false"/>
+		<copy file="${basedir}/scripts/antadapter/META-INF/MANIFEST.MF" todir="${unjarDestBin}/META-INF"/>
+		<eclipse.versionReplacer path="${unjarDestBin}" version="${bundleVersion}"/>
+		<zip destfile="${jar.Location}">
+			<fileset dir="${unjarDestBin}" includes="META-INF/MANIFEST.MF"/>
+			<fileset dir="${unjarDestBin}">
+				<include name="**/*"/>
+				<exclude name="META-INF/MANIFEST.MF"/>
+			</fileset>
+		</zip>
+		<delete dir="${unjarDestBin}" failonerror="false"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
new file mode 100644
index 0000000..78f89cf
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -0,0 +1,3117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Umbrella owner and abstract syntax tree node factory.
+ * An <code>AST</code> instance serves as the common owner of any number of
+ * AST nodes, and as the factory for creating new AST nodes owned by that
+ * instance.
+ * <p>
+ * Abstract syntax trees may be hand constructed by clients, using the
+ * <code>new<i>TYPE</i></code> factory methods to create new nodes, and the
+ * various <code>set<i>CHILD</i></code> methods
+ * (see {@link org.eclipse.jdt.core.dom.ASTNode ASTNode} and its subclasses)
+ * to connect them together.
+ * </p>
+ * <p>
+ * Each AST node belongs to a unique AST instance, called the owning AST.
+ * The children of an AST node always have the same owner as their parent node.
+ * If a node from one AST is to be added to a different AST, the subtree must
+ * be cloned first to ensures that the added nodes have the correct owning AST.
+ * </p>
+ * <p>
+ * There can be any number of AST nodes owned by a single AST instance that are
+ * unparented. Each of these nodes is the root of a separate little tree of nodes.
+ * The method <code>ASTNode.getRoot()</code> navigates from any node to the root
+ * of the tree that it is contained in. Ordinarily, an AST instance has one main
+ * tree (rooted at a <code>CompilationUnit</code>), with newly-created nodes appearing
+ * as additional roots until they are parented somewhere under the main tree.
+ * One can navigate from any node to its AST instance, but not conversely.
+ * </p>
+ * <p>
+ * The class {@link ASTParser} parses a string
+ * containing a Java source code and returns an abstract syntax tree
+ * for it. The resulting nodes carry source ranges relating the node back to
+ * the original source characters.
+ * </p>
+ * <p>
+ * Compilation units created by <code>ASTParser</code> from a
+ * source document can be serialized after arbitrary modifications
+ * with minimal loss of original formatting. Here is an example:
+ * <pre>
+ * Document doc = new Document("import java.util.List;\nclass X {}\n");
+ * ASTParser parser = ASTParser.newParser(AST.JLS3);
+ * parser.setSource(doc.get().toCharArray());
+ * CompilationUnit cu = (CompilationUnit) parser.createAST(null);
+ * cu.recordModifications();
+ * AST ast = cu.getAST();
+ * ImportDeclaration id = ast.newImportDeclaration();
+ * id.setName(ast.newName(new String[] {"java", "util", "Set"});
+ * cu.imports().add(id); // add import declaration at end
+ * TextEdit edits = cu.rewrite(document, null);
+ * UndoEdit undo = edits.apply(document);
+ * </pre>
+ * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
+ * an alternative way to describe and serialize changes to a
+ * read-only AST.
+ * </p>
+ * <p>
+ * Clients may create instances of this class using {@link #newAST(int)},
+ * but this class is not intended to be subclassed.
+ * </p>
+ *
+ * @see ASTParser
+ * @see ASTNode
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class AST {
+	/**
+	 * new Class[] {AST.class}
+	 * @since 3.0
+	 */
+	private static final Class[] AST_CLASS = new Class[] {AST.class};
+
+	/**
+	 * Constant for indicating the AST API that handles JLS2.
+	 * <p>
+	 * This API is capable of handling all constructs
+	 * in the Java language as described in the Java Language
+     * Specification, Second Edition (JLS2).
+     * JLS2 is a superset of all earlier versions of the
+     * Java language, and the JLS2 API can be used to manipulate
+     * programs written in all versions of the Java language
+     * up to and including J2SE 1.4.
+     * </p>
+     *
+	 * @since 3.0
+	 * @deprecated Clients should use the {@link #JLS8} AST API instead.
+	 */
+	public static final int JLS2 = 2;
+
+	/**
+	 * Internal synonym for {@link #JLS2}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ static final int JLS2_INTERNAL = JLS2;
+	
+	/**
+	 * Constant for indicating the AST API that handles JLS3.
+	 * <p>
+	 * This API is capable of handling all constructs in the
+	 * Java language as described in the Java Language
+	 * Specification, Third Edition (JLS3).
+     * JLS3 is a superset of all earlier versions of the
+     * Java language, and the JLS3 API can be used to manipulate
+     * programs written in all versions of the Java language
+     * up to and including J2SE 5 (aka JDK 1.5).
+     * </p>
+     *
+	 * @since 3.1
+	 * @deprecated Clients should use the {@link #JLS8} AST API instead.
+	 */
+	public static final int JLS3 = 3;
+	
+	/**
+	 * Internal synonym for {@link #JLS3}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.8
+	 */
+	/*package*/ static final int JLS3_INTERNAL = JLS3;
+
+	/**
+	 * Constant for indicating the AST API that handles JLS4 (aka JLS7).
+	 * <p>
+	 * This API is capable of handling all constructs in the
+	 * Java language as described in the Java Language
+	 * Specification, Java SE 7 Edition (JLS7) as specified by JSR336.
+	 * JLS4 is a superset of all earlier versions of the
+	 * Java language, and the JLS4 API can be used to manipulate
+	 * programs written in all versions of the Java language
+	 * up to and including Java SE 7 (aka JDK 1.7).
+	 * </p>
+	 *
+	 * @since 3.7.1
+	 * @deprecated Clients should use the {@link #JLS8} AST API instead.
+	 */
+	public static final int JLS4 = 4;
+	
+	/**
+	 * Internal synonym for {@link #JLS4}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	/*package*/ static final int JLS4_INTERNAL = JLS4;
+	
+	/**
+	 * Constant for indicating the AST API that handles JLS8.
+	 * <p>
+	 * This API is capable of handling all constructs in the
+	 * Java language as described in the Java Language
+	 * Specification, Java SE 8 Edition (JLS8) as specified by JSR337.
+	 * JLS8 is a superset of all earlier versions of the
+	 * Java language, and the JLS8 API can be used to manipulate
+	 * programs written in all versions of the Java language
+	 * up to and including Java SE 8 (aka JDK 1.8).
+	 * </p>
+	 *
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int JLS8 = 8;
+
+	/*
+	 * Must not collide with a value for ICompilationUnit constants
+	 */
+	static final int RESOLVED_BINDINGS = 0x80000000;
+
+	/**
+	 * Internal method.
+	 * <p>
+	 * This method converts the given internal compiler AST for the given source string
+	 * into a compilation unit. This method is not intended to be called by clients.
+	 * </p>
+	 *
+ 	 * @param level the API level; one of the <code>JLS*</code> level constants
+	 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
+	 * @param source the string of the Java compilation unit
+	 * @param options compiler options
+	 * @param workingCopy the working copy that the AST is created from
+	 * @param monitor the progress monitor used to report progress and request cancellation,
+	 *     or <code>null</code> if none
+	 * @param isResolved whether the given compilation unit declaration is resolved
+	 * @return the compilation unit node
+	 * @deprecated Use org.eclipse.jdt.core.dom.AST.convertCompilationUnit(int, CompilationUnitDeclaration, Map, boolean, CompilationUnit, int, IProgressMonitor) instead
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public static CompilationUnit convertCompilationUnit(
+			int level,
+			org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
+			char[] source,
+			Map options,
+			boolean isResolved,
+			org.eclipse.jdt.internal.core.CompilationUnit workingCopy,
+			int reconcileFlags,
+			IProgressMonitor monitor) {
+		return null;
+	}
+
+	/**
+	 * Internal method.
+	 * <p>
+	 * This method converts the given internal compiler AST for the given source string
+	 * into a compilation unit. This method is not intended to be called by clients.
+	 * </p>
+	 *
+ 	 * @param level the API level; one of the <code>JLS*</code> level constants
+	 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
+	 * @param options compiler options
+	 * @param workingCopy the working copy that the AST is created from
+	 * @param monitor the progress monitor used to report progress and request cancellation,
+	 *     or <code>null</code> if none
+	 * @param isResolved whether the given compilation unit declaration is resolved
+	 * @return the compilation unit node
+	 * @since 3.4
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public static CompilationUnit convertCompilationUnit(
+		int level,
+		org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
+		Map options,
+		boolean isResolved,
+		org.eclipse.jdt.internal.core.CompilationUnit workingCopy,
+		int reconcileFlags,
+		IProgressMonitor monitor) {
+
+		ASTConverter converter = new ASTConverter(options, isResolved, monitor);
+		AST ast = AST.newAST(level);
+		int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
+		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+		BindingResolver resolver = null;
+		if (isResolved) {
+			resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables(), false, true);
+			((DefaultBindingResolver) resolver).isRecoveringBindings = (reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
+			ast.setFlag(AST.RESOLVED_BINDINGS);
+		} else {
+			resolver = new BindingResolver();
+		}
+		ast.setFlag(reconcileFlags);
+		ast.setBindingResolver(resolver);
+		converter.setAST(ast);
+
+		CompilationUnit unit = converter.convert(compilationUnitDeclaration, workingCopy.getContents());
+		unit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions());
+		unit.setTypeRoot(workingCopy.originalFromClone());
+		ast.setDefaultNodeFlag(savedDefaultNodeFlag);
+		return unit;
+	}
+
+	/**
+	 * Creates a new Java abstract syntax tree
+     * (AST) following the specified set of API rules.
+     * <p>
+     * Clients should use this method specifying {@link #JLS8} as the
+     * AST level in all cases, even when dealing with source of earlier JDK versions like 1.3 or 1.4.
+     * </p>
+     *
+ 	 * @param level the API level; one of the <code>JLS*</code> level constants
+	 * @return new AST instance following the specified set of API rules.
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the API level is not one of the <code>JLS*</code> level constants</li>
+	 * </ul>
+     * @since 3.0
+	 */
+	public static AST newAST(int level) {
+		return new AST(level);
+	}
+
+	/**
+	 * Parses the given string as a Java compilation unit and creates and
+	 * returns a corresponding abstract syntax tree.
+	 * <p>
+	 * The returned compilation unit node is the root node of a new AST.
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the given source string (the given source string itself
+	 * is not remembered with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * If a syntax error is detected while parsing, the relevant node(s) of the
+	 * tree will be flagged as <code>MALFORMED</code>.
+	 * </p>
+	 * <p>
+	 * This method does not compute binding information; all <code>resolveBinding</code>
+	 * methods applied to nodes of the resulting AST return <code>null</code>.
+	 * </p>
+	 *
+	 * @param source the string to be parsed as a Java compilation unit
+	 * @return the compilation unit node
+	 * @see ASTNode#getFlags()
+	 * @see ASTNode#MALFORMED
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @since 2.0
+	 * @deprecated Use {@link ASTParser} instead.
+	 */
+	public static CompilationUnit parseCompilationUnit(char[] source) {
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTParser c = ASTParser.newParser(AST.JLS2);
+		c.setSource(source);
+		ASTNode result = c.createAST(null);
+		return (CompilationUnit) result;
+	}
+
+	/**
+	 * Parses the given string as the hypothetical contents of the named
+	 * compilation unit and creates and returns a corresponding abstract syntax tree.
+	 * <p>
+	 * The returned compilation unit node is the root node of a new AST.
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the given source string (the given source string itself
+	 * is not remembered with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * If a syntax error is detected while parsing, the relevant node(s) of the
+	 * tree will be flagged as <code>MALFORMED</code>.
+	 * </p>
+	 * <p>
+	 * If the given project is not <code>null</code>, the various names
+	 * and types appearing in the compilation unit can be resolved to "bindings"
+	 * by calling the <code>resolveBinding</code> methods. These bindings
+	 * draw connections between the different parts of a program, and
+	 * generally afford a more powerful vantage point for clients who wish to
+	 * analyze a program's structure more deeply. These bindings come at a
+	 * considerable cost in both time and space, however, and should not be
+	 * requested frivolously. The additional space is not reclaimed until the
+	 * AST, all its nodes, and all its bindings become garbage. So it is very
+	 * important to not retain any of these objects longer than absolutely
+	 * necessary. Bindings are resolved at the time the AST is created. Subsequent
+	 * modifications to the AST do not affect the bindings returned by
+	 * <code>resolveBinding</code> methods in any way; these methods return the
+	 * same binding as before the AST was modified (including modifications
+	 * that rearrange subtrees by reparenting nodes).
+	 * If the given project is <code>null</code>, the analysis
+	 * does not go beyond parsing and building the tree, and all
+	 * <code>resolveBinding</code> methods return <code>null</code> from the
+	 * outset.
+	 * </p>
+	 * <p>
+	 * The name of the compilation unit must be supplied for resolving bindings.
+	 * This name should be suffixed by a dot ('.') followed by one of the
+	 * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
+	 * and match the name of the main
+	 * (public) class or interface declared in the source. For example, if the source
+	 * declares a public class named "Foo", the name of the compilation can be
+	 * "Foo.java". For the purposes of resolving bindings, types declared in the
+	 * source string hide types by the same name available through the classpath
+	 * of the given project.
+	 * </p>
+	 *
+	 * @param source the string to be parsed as a Java compilation unit
+	 * @param unitName the name of the compilation unit that would contain the source
+	 *    string, or <code>null</code> if <code>javaProject</code> is also <code>null</code>
+	 * @param project the Java project used to resolve names, or
+	 *    <code>null</code> if bindings are not resolved
+	 * @return the compilation unit node
+	 * @see ASTNode#getFlags()
+	 * @see ASTNode#MALFORMED
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @since 2.0
+	 * @deprecated Use {@link ASTParser} instead.
+	 */
+	public static CompilationUnit parseCompilationUnit(
+		char[] source,
+		String unitName,
+		IJavaProject project) {
+
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTParser astParser = ASTParser.newParser(AST.JLS2);
+		astParser.setSource(source);
+		astParser.setUnitName(unitName);
+		astParser.setProject(project);
+		astParser.setResolveBindings(project != null);
+		ASTNode result = astParser.createAST(null);
+		return (CompilationUnit) result;
+	}
+
+	/**
+	 * Parses the source string corresponding to the given Java class file
+	 * element and creates and returns a corresponding abstract syntax tree.
+	 * The source string is obtained from the Java model element using
+	 * <code>IClassFile.getSource()</code>, and is only available for a class
+	 * files with attached source.
+	 * <p>
+	 * The returned compilation unit node is the root node of a new AST.
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the source string (the source string is not remembered
+	 * with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * If a syntax error is detected while parsing, the relevant node(s) of the
+	 * tree will be flagged as <code>MALFORMED</code>.
+	 * </p>
+	 * <p>
+	 * If <code>resolveBindings</code> is <code>true</code>, the various names
+	 * and types appearing in the compilation unit can be resolved to "bindings"
+	 * by calling the <code>resolveBinding</code> methods. These bindings
+	 * draw connections between the different parts of a program, and
+	 * generally afford a more powerful vantage point for clients who wish to
+	 * analyze a program's structure more deeply. These bindings come at a
+	 * considerable cost in both time and space, however, and should not be
+	 * requested frivolously. The additional space is not reclaimed until the
+	 * AST, all its nodes, and all its bindings become garbage. So it is very
+	 * important to not retain any of these objects longer than absolutely
+	 * necessary. Bindings are resolved at the time the AST is created. Subsequent
+	 * modifications to the AST do not affect the bindings returned by
+	 * <code>resolveBinding</code> methods in any way; these methods return the
+	 * same binding as before the AST was modified (including modifications
+	 * that rearrange subtrees by reparenting nodes).
+	 * If <code>resolveBindings</code> is <code>false</code>, the analysis
+	 * does not go beyond parsing and building the tree, and all
+	 * <code>resolveBinding</code> methods return <code>null</code> from the
+	 * outset.
+	 * </p>
+	 *
+	 * @param classFile the Java model class file whose corresponding source code is to be parsed
+	 * @param resolveBindings <code>true</code> if bindings are wanted,
+	 *   and <code>false</code> if bindings are not of interest
+	 * @return the compilation unit node
+	 * @exception IllegalArgumentException if the given Java element does not
+	 * exist or if its source string cannot be obtained
+	 * @see ASTNode#getFlags()
+	 * @see ASTNode#MALFORMED
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @since 2.1
+	 * @deprecated Use {@link ASTParser} instead.
+	 */
+	public static CompilationUnit parseCompilationUnit(
+		IClassFile classFile,
+		boolean resolveBindings) {
+
+		if (classFile == null) {
+			throw new IllegalArgumentException();
+		}
+		try {
+			ASTParser c = ASTParser.newParser(AST.JLS2);
+			c.setSource(classFile);
+			c.setResolveBindings(resolveBindings);
+			ASTNode result = c.createAST(null);
+			return (CompilationUnit) result;
+		} catch (IllegalStateException e) {
+			// convert ASTParser's complaints into old form
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Parses the source string of the given Java model compilation unit element
+	 * and creates and returns a corresponding abstract syntax tree. The source
+	 * string is obtained from the Java model element using
+	 * <code>ICompilationUnit.getSource()</code>.
+	 * <p>
+	 * The returned compilation unit node is the root node of a new AST.
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the source string (the source string is not remembered
+	 * with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * If a syntax error is detected while parsing, the relevant node(s) of the
+	 * tree will be flagged as <code>MALFORMED</code>.
+	 * </p>
+	 * <p>
+	 * If <code>resolveBindings</code> is <code>true</code>, the various names
+	 * and types appearing in the compilation unit can be resolved to "bindings"
+	 * by calling the <code>resolveBinding</code> methods. These bindings
+	 * draw connections between the different parts of a program, and
+	 * generally afford a more powerful vantage point for clients who wish to
+	 * analyze a program's structure more deeply. These bindings come at a
+	 * considerable cost in both time and space, however, and should not be
+	 * requested frivolously. The additional space is not reclaimed until the
+	 * AST, all its nodes, and all its bindings become garbage. So it is very
+	 * important to not retain any of these objects longer than absolutely
+	 * necessary. Bindings are resolved at the time the AST is created. Subsequent
+	 * modifications to the AST do not affect the bindings returned by
+	 * <code>resolveBinding</code> methods in any way; these methods return the
+	 * same binding as before the AST was modified (including modifications
+	 * that rearrange subtrees by reparenting nodes).
+	 * If <code>resolveBindings</code> is <code>false</code>, the analysis
+	 * does not go beyond parsing and building the tree, and all
+	 * <code>resolveBinding</code> methods return <code>null</code> from the
+	 * outset.
+	 * </p>
+	 *
+	 * @param unit the Java model compilation unit whose source code is to be parsed
+	 * @param resolveBindings <code>true</code> if bindings are wanted,
+	 *   and <code>false</code> if bindings are not of interest
+	 * @return the compilation unit node
+	 * @exception IllegalArgumentException if the given Java element does not
+	 * exist or if its source string cannot be obtained
+	 * @see ASTNode#getFlags()
+	 * @see ASTNode#MALFORMED
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @since 2.0
+	 * @deprecated Use {@link ASTParser} instead.
+	 */
+	public static CompilationUnit parseCompilationUnit(
+		ICompilationUnit unit,
+		boolean resolveBindings) {
+
+		try {
+			ASTParser c = ASTParser.newParser(AST.JLS2);
+			c.setSource(unit);
+			c.setResolveBindings(resolveBindings);
+			ASTNode result = c.createAST(null);
+			return (CompilationUnit) result;
+		} catch (IllegalStateException e) {
+			// convert ASTParser's complaints into old form
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Level of AST API supported by this AST.
+	 * @since 3.0
+	 */
+	int apiLevel;
+
+	/**
+	 * Tag bit value. This represents internal state of the tree.
+	 */
+	private int bits;
+
+	/**
+	 * Default value of <code>flag<code> when a new node is created.
+	 */
+	private int defaultNodeFlag = 0;
+
+	/**
+	 * When disableEvents > 0, events are not reported and
+	 * the modification count stays fixed.
+	 * <p>
+	 * This mechanism is used in lazy initialization of a node
+	 * to prevent events from being reported for the modification
+	 * of the node as well as for the creation of the missing child.
+	 * </p>
+	 * @since 3.0
+	 */
+	private int disableEvents = 0;
+
+	/**
+	 * The event handler for this AST.
+	 * Initially an event handler that does not nothing.
+	 * @since 3.0
+	 */
+	private NodeEventHandler eventHandler = new NodeEventHandler();
+
+	/**
+	 * Internal object unique to the AST instance. Readers must synchronize on
+	 * this object when the modifying instance fields.
+	 * @since 3.0
+	 */
+	private final Object internalASTLock = new Object();
+
+	/**
+	 * Internal modification count; initially 0; increases monotonically
+	 * <b>by one or more</b> as the AST is successively modified.
+	 */
+	private long modificationCount = 0;
+
+	/**
+	 * Internal original modification count; value is equals to <code>
+	 * modificationCount</code> at the end of the parse (<code>ASTParser
+	 * </code>). If this ast is not created with a parser then value is 0.
+	 * @since 3.0
+	 */
+	private long originalModificationCount = 0;
+
+	/**
+	 * The binding resolver for this AST. Initially a binding resolver that
+	 * does not resolve names at all.
+	 */
+	private BindingResolver resolver = new BindingResolver();
+
+	/**
+	 * Internal ast rewriter used to record ast modification when record mode is enabled.
+	 */
+	InternalASTRewrite rewriter;
+
+	/**
+	 * Java Scanner used to validate preconditions for the creation of specific nodes
+	 * like CharacterLiteral, NumberLiteral, StringLiteral or SimpleName.
+	 */
+	Scanner scanner;
+
+	/**
+	 * new Object[] {this}
+	 * @since 3.0
+	 */
+	private final Object[] THIS_AST= new Object[] {this};
+
+	/**
+	 * Creates a new, empty abstract syntax tree using default options.
+	 *
+	 * @see JavaCore#getDefaultOptions()
+	 * @deprecated Clients should port their code to use the new JLS4 AST API and call
+	 *    {@link #newAST(int) AST.newAST(AST.JLS4)} instead of using this constructor.
+	 */
+	public AST() {
+		this(JavaCore.getDefaultOptions());
+	}
+
+	/**
+	 * Creates a new Java abstract syntax tree
+     * (AST) following the specified set of API rules.
+     *
+ 	 * @param level the API level; one of the <code>JLS*</code> level constants
+     * @since 3.0
+	 */
+	private AST(int level) {
+		switch(level) {
+			case JLS2_INTERNAL :
+			case JLS3_INTERNAL :
+				this.apiLevel = level;
+				// initialize a scanner
+				this.scanner = new Scanner(
+						true /*comment*/,
+						true /*whitespace*/,
+						false /*nls*/,
+						ClassFileConstants.JDK1_3 /*sourceLevel*/,
+						ClassFileConstants.JDK1_5 /*complianceLevel*/,
+						null/*taskTag*/,
+						null/*taskPriorities*/,
+						true/*taskCaseSensitive*/);
+				break;
+			case JLS4_INTERNAL :
+				this.apiLevel = level;
+				// initialize a scanner
+				this.scanner = new Scanner(
+						true /*comment*/,
+						true /*whitespace*/,
+						false /*nls*/,
+						ClassFileConstants.JDK1_7 /*sourceLevel*/,
+						ClassFileConstants.JDK1_7 /*complianceLevel*/,
+						null/*taskTag*/,
+						null/*taskPriorities*/,
+						true/*taskCaseSensitive*/);
+				break;
+			case JLS8 :
+				this.apiLevel = level;
+				// initialize a scanner
+				this.scanner = new Scanner(
+						true /*comment*/,
+						true /*whitespace*/,
+						false /*nls*/,
+						ClassFileConstants.JDK1_8 /*sourceLevel*/,
+						ClassFileConstants.JDK1_8 /*complianceLevel*/,
+						null/*taskTag*/,
+						null/*taskPriorities*/,
+						true/*taskCaseSensitive*/);
+				break;	
+			default:
+				throw new IllegalArgumentException("Unsupported JLS level"); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Creates a new, empty abstract syntax tree using the given options.
+	 * <p>
+	 * Following option keys are significant:
+	 * <ul>
+	 * <li><code>"org.eclipse.jdt.core.compiler.source"</code> -
+	 *    indicates source compatibility mode (as per <code>JavaCore</code>);
+	 *    <code>"1.3"</code> means the source code is as per JDK 1.3;
+	 *    <code>"1.4"</code> means the source code is as per JDK 1.4
+	 *    (<code>"assert"</code> is now a keyword);
+	 *    <code>"1.5"</code> means the source code is as per JDK 1.5
+	 *    (<code>"enum"</code> is now a keyword);
+	 *    <code>"1.7"</code> means the source code is as per JDK 1.7;
+	 *    additional legal values may be added later. </li>
+	 * </ul>
+	 * Options other than the above are ignored.
+	 * </p>
+	 *
+	 * @param options the table of options (key type: <code>String</code>;
+	 *    value type: <code>String</code>)
+	 * @see JavaCore#getDefaultOptions()
+	 * @deprecated Clients should port their code to use the new JLS4 AST API and call
+	 *    {@link #newAST(int) AST.newAST(AST.JLS4)} instead of using this constructor.
+	 */
+	public AST(Map options) {
+		this(JLS2);
+		Object sourceLevelOption = options.get(JavaCore.COMPILER_SOURCE);
+		long sourceLevel = ClassFileConstants.JDK1_3;
+		if (JavaCore.VERSION_1_4.equals(sourceLevelOption)) {
+			sourceLevel = ClassFileConstants.JDK1_4;
+		} else if (JavaCore.VERSION_1_5.equals(sourceLevelOption)) {
+			sourceLevel = ClassFileConstants.JDK1_5;
+		} else if (JavaCore.VERSION_1_7.equals(sourceLevelOption)) {
+			sourceLevel = ClassFileConstants.JDK1_7;
+		}
+		Object complianceLevelOption = options.get(JavaCore.COMPILER_COMPLIANCE);
+		long complianceLevel = ClassFileConstants.JDK1_3;
+		if (JavaCore.VERSION_1_4.equals(complianceLevelOption)) {
+			complianceLevel = ClassFileConstants.JDK1_4;
+		} else if (JavaCore.VERSION_1_5.equals(complianceLevelOption)) {
+			complianceLevel = ClassFileConstants.JDK1_5;
+		} else if (JavaCore.VERSION_1_7.equals(complianceLevelOption)) {
+			complianceLevel = ClassFileConstants.JDK1_7;
+		}
+		// override scanner if 1.4 or 1.5 asked for
+		this.scanner = new Scanner(
+			true /*comment*/,
+			true /*whitespace*/,
+			false /*nls*/,
+			sourceLevel /*sourceLevel*/,
+			complianceLevel /*complianceLevel*/,
+			null/*taskTag*/,
+			null/*taskPriorities*/,
+			true/*taskCaseSensitive*/);
+	}
+
+	/**
+	 * Return the API level supported by this AST.
+	 *
+	 * @return level the API level; one of the <code>JLS*</code> level constants
+     * declared on <code>AST</code>; assume this set is open-ended
+     * @since 3.0
+	 */
+	public int apiLevel() {
+		return this.apiLevel;
+	}
+
+	/**
+	 * Creates an unparented node of the given node class
+	 * (non-abstract subclass of {@link ASTNode}).
+	 *
+	 * @param nodeClass AST node class
+	 * @return a new unparented node owned by this AST
+	 * @exception IllegalArgumentException if <code>nodeClass</code> is
+	 * <code>null</code> or is not a concrete node type class
+	 * or is not supported for this AST's API level
+	 * @since 3.0
+	 */
+	public ASTNode createInstance(Class nodeClass) {
+		if (nodeClass == null) {
+			throw new IllegalArgumentException();
+		}
+		try {
+			// invoke constructor with signature Foo(AST)
+			Constructor c = nodeClass.getDeclaredConstructor(AST_CLASS);
+			Object result = c.newInstance(this.THIS_AST);
+			return (ASTNode) result;
+		} catch (NoSuchMethodException e) {
+			// all AST node classes have a Foo(AST) constructor
+			// therefore nodeClass is not legit
+			throw new IllegalArgumentException();
+		} catch (InstantiationException e) {
+			// all concrete AST node classes can be instantiated
+			// therefore nodeClass is not legit
+			throw new IllegalArgumentException();
+		} catch (IllegalAccessException e) {
+			// all AST node classes have an accessible Foo(AST) constructor
+			// therefore nodeClass is not legit
+			throw new IllegalArgumentException();
+		} catch (InvocationTargetException e) {
+			// concrete AST node classes do not die in the constructor
+			// therefore nodeClass is not legit
+			IllegalArgumentException iae = new IllegalArgumentException();
+			iae.initCause(e.getCause());
+			throw iae;
+		}
+	}
+
+	/**
+	 * Creates an unparented node of the given node type.
+	 * This convenience method is equivalent to:
+	 * <pre>
+	 * createInstance(ASTNode.nodeClassForType(nodeType))
+	 * </pre>
+	 *
+	 * @param nodeType AST node type, one of the node type
+	 * constants declared on {@link ASTNode}
+	 * @return a new unparented node owned by this AST
+	 * @exception IllegalArgumentException if <code>nodeType</code> is
+	 * not a legal AST node type or if it's not supported for this AST's API level
+	 * @since 3.0
+	 */
+	public ASTNode createInstance(int nodeType) {
+		// nodeClassForType throws IllegalArgumentException if nodeType is bogus
+		Class nodeClass = ASTNode.nodeClassForType(nodeType);
+		return createInstance(nodeClass);
+	}
+
+	/**
+     * Disable events.
+	 * This method is thread-safe for AST readers.
+	 *
+	 * @see #reenableEvents()
+     * @since 3.0
+     */
+	final void disableEvents() {
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by another reader
+			this.disableEvents++;
+		}
+		// while disableEvents > 0 no events will be reported, and mod count will stay fixed
+	}
+
+	/**
+	 * Returns the binding resolver for this AST.
+	 *
+	 * @return the binding resolver for this AST
+	 */
+	BindingResolver getBindingResolver() {
+		return this.resolver;
+	}
+
+	/**
+	 * Returns default node flags of new nodes of this AST.
+	 *
+	 * @return the default node flags of new nodes of this AST
+	 * @since 3.0
+	 */
+	int getDefaultNodeFlag() {
+		return this.defaultNodeFlag;
+	}
+
+	/**
+	 * Returns the event handler for this AST.
+	 *
+	 * @return the event handler for this AST
+	 * @since 3.0
+	 */
+	NodeEventHandler getEventHandler() {
+		return this.eventHandler;
+	}
+
+	/**
+	 * Returns true if the ast tree was created with bindings recovery, false otherwise
+	 *
+	 * @return true if the ast tree was created with bindings recovery, false otherwise
+	 * @since 3.3
+	 */
+	public boolean hasBindingsRecovery() {
+		return (this.bits & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0;
+	}
+
+	/**
+	 * Returns true if the ast tree was created with bindings, false otherwise
+	 *
+	 * @return true if the ast tree was created with bindings, false otherwise
+	 * @since 3.3
+	 */
+	public boolean hasResolvedBindings() {
+		return (this.bits & RESOLVED_BINDINGS) != 0;
+	}
+
+	/**
+	 * Returns true if the ast tree was created with statements recovery, false otherwise
+	 *
+	 * @return true if the ast tree was created with statements recovery, false otherwise
+	 * @since 3.3
+	 */
+	public boolean hasStatementsRecovery() {
+		return (this.bits & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0;
+	}
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setName(String[]) that doesn't do any validation.
+	 */
+	Name internalNewName(String[] identifiers) {
+		int count = identifiers.length;
+		if (count == 0) {
+			throw new IllegalArgumentException();
+		}
+		final SimpleName simpleName = new SimpleName(this);
+		simpleName.internalSetIdentifier(identifiers[0]);
+		Name result = simpleName;
+		for (int i = 1; i < count; i++) {
+			SimpleName name = new SimpleName(this);
+			name.internalSetIdentifier(identifiers[i]);
+			result = newQualifiedName(result, name);
+		}
+		return result;
+	}
+
+	/**
+	 * Returns the modification count for this AST. The modification count
+	 * is a non-negative value that increases (by 1 or perhaps by more) as
+	 * this AST or its nodes are changed. The initial value is unspecified.
+	 * <p>
+	 * The following things count as modifying an AST:
+	 * <ul>
+	 * <li>creating a new node owned by this AST,</li>
+	 * <li>adding a child to a node owned by this AST,</li>
+	 * <li>removing a child from a node owned by this AST,</li>
+	 * <li>setting a non-node attribute of a node owned by this AST.</li>
+	 * </ul>
+	 * </p>
+	 * Operations which do not entail creating or modifying existing nodes
+	 * do not increase the modification count.
+	 * <p>
+	 * N.B. This method may be called several times in the course
+	 * of a single client operation. The only promise is that the modification
+	 * count increases monotonically as the AST or its nodes change; there is
+	 * no promise that a modifying operation increases the count by exactly 1.
+	 * </p>
+	 *
+	 * @return the current value (non-negative) of the modification counter of
+	 *    this AST
+	 */
+	public long modificationCount() {
+		return this.modificationCount;
+	}
+
+	/**
+	 * Indicates that this AST is about to be modified.
+	 * <p>
+	 * The following things count as modifying an AST:
+	 * <ul>
+	 * <li>creating a new node owned by this AST</li>
+	 * <li>adding a child to a node owned by this AST</li>
+	 * <li>removing a child from a node owned by this AST</li>
+	 * <li>setting a non-node attribute of a node owned by this AST</li>.
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * N.B. This method may be called several times in the course
+	 * of a single client operation.
+	 * </p>
+	 */
+	void modifying() {
+		// when this method is called during lazy init, events are disabled
+		// and the modification count will not be increased
+		if (this.disableEvents > 0) {
+			return;
+		}
+		// increase the modification count
+		this.modificationCount++;
+	}
+
+	/**
+	 * Creates and returns a new unparented annotation type declaration
+	 * node for an unspecified, but legal, name; no modifiers; no javadoc;
+	 * and an empty list of member declarations.
+	 *
+	 * @return a new unparented annotation type declaration node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public AnnotationTypeDeclaration newAnnotationTypeDeclaration() {
+		AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented annotation type
+	 * member declaration node for an unspecified, but legal,
+	 * member name and type; no modifiers; no javadoc;
+	 * and no default value.
+	 *
+	 * @return a new unparented annotation type member declaration node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() {
+		AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented anonymous class declaration
+	 * node owned by this AST. By default, the body declaration list is empty.
+	 *
+	 * @return a new unparented anonymous class declaration node
+	 */
+	public AnonymousClassDeclaration newAnonymousClassDeclaration() {
+		AnonymousClassDeclaration result = new AnonymousClassDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented array access expression node
+	 * owned by this AST. By default, the array and index expression are
+	 * both unspecified (but legal).
+	 *
+	 * @return a new unparented array access expression node
+	 */
+	public ArrayAccess newArrayAccess() {
+		ArrayAccess result = new ArrayAccess(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented array creation expression node
+	 * owned by this AST. By default, the array type is an unspecified
+	 * 1-dimensional array, the list of dimensions is empty, and there is no
+	 * array initializer.
+	 * <p>
+	 * Examples:
+	 * <code>
+	 * <pre>
+	 * // new String[len]
+	 * ArrayCreation ac1 = ast.newArrayCreation();
+	 * ac1.setType(
+	 *    ast.newArrayType(
+	 *       ast.newSimpleType(ast.newSimpleName("String"))));
+	 * ac1.dimensions().add(ast.newSimpleName("len"));
+     *
+	 * // new double[7][24][]
+	 * ArrayCreation ac2 = ast.newArrayCreation();
+	 * ac2.setType(
+	 *    ast.newArrayType(
+	 *       ast.newPrimitiveType(PrimitiveType.DOUBLE), 3));
+	 * ac2.dimensions().add(ast.newNumberLiteral("7"));
+	 * ac2.dimensions().add(ast.newNumberLiteral("24"));
+	 *
+	 * // new int[] {1, 2}
+	 * ArrayCreation ac3 = ast.newArrayCreation();
+	 * ac3.setType(
+	 *    ast.newArrayType(
+	 *       ast.newPrimitiveType(PrimitiveType.INT)));
+	 * ArrayInitializer ai = ast.newArrayInitializer();
+	 * ac3.setInitializer(ai);
+	 * ai.expressions().add(ast.newNumberLiteral("1"));
+	 * ai.expressions().add(ast.newNumberLiteral("2"));
+	 * </pre>
+	 * </code>
+	 * </p>
+	 *
+	 * @return a new unparented array creation expression node
+	 */
+	public ArrayCreation newArrayCreation() {
+		ArrayCreation result = new ArrayCreation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented array initializer node
+	 * owned by this AST. By default, the initializer has no expressions.
+	 *
+	 * @return a new unparented array initializer node
+	 */
+	public ArrayInitializer newArrayInitializer() {
+		ArrayInitializer result = new ArrayInitializer(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented array type node with the given
+	 * component type, which may be another array type.
+	 *
+	 * @param componentType the component type (possibly another array type)
+	 * @return a new unparented array type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public ArrayType newArrayType(Type componentType) {
+		ArrayType result = new ArrayType(this);
+		result.setComponentType(componentType);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented array type node with the given
+	 * element type and number of (additional) dimensions.
+	 * <p>
+	 * Note that if the element type passed in is an array type, the
+	 * element type of the result will not be the same as what was passed in.
+	 * </p>
+	 *
+	 * @param elementType the element type (can be an array type)
+	 * @param dimensions the number of dimensions, a positive number
+	 * @return a new unparented array type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>the element type is null</li>
+	 * <li>the number of dimensions is lower than 1</li>
+	 * <li>the number of dimensions is greater than 1000</li>
+	 * </ul>
+	 */
+	public ArrayType newArrayType(Type elementType, int dimensions) {
+		if (elementType == null) {
+			throw new IllegalArgumentException();
+		}
+		if (dimensions < 1 || dimensions > 1000) {
+			// we would blow our stacks anyway with a 1000-D array
+			throw new IllegalArgumentException();
+		}
+		ArrayType result = new ArrayType(this);
+		result.setComponentType(elementType);
+		for (int i = 2; i <= dimensions; i++) {
+			result = newArrayType(result);
+		}
+		return result;
+
+	}
+
+	/**
+	 * Creates a new unparented assert statement node owned by this AST.
+	 * By default, the first expression is unspecified, but legal, and has no
+	 * message expression.
+	 *
+	 * @return a new unparented assert statement node
+	 */
+	public AssertStatement newAssertStatement() {
+		return new AssertStatement(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented assignment expression node
+	 * owned by this AST. By default, the assignment operator is "=" and
+	 * the left and right hand side expressions are unspecified, but
+	 * legal, names.
+	 *
+	 * @return a new unparented assignment expression node
+	 */
+	public Assignment newAssignment() {
+		Assignment result = new Assignment(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented block node owned by this AST, for an empty list
+	 * of statements.
+	 *
+	 * @return a new unparented, empty block node
+	 */
+	public Block newBlock() {
+		return new Block(this);
+	}
+
+	/**
+	 * Creates and returns a new block comment placeholder node.
+	 * <p>
+	 * Note that this node type is used to recording the source
+	 * range where a comment was found in the source string.
+	 * These comment nodes are normally found (only) in
+	 * {@linkplain CompilationUnit#getCommentList()
+	 * the comment table} for parsed compilation units.
+	 * </p>
+	 *
+	 * @return a new unparented block comment node
+	 * @since 3.0
+	 */
+	public BlockComment newBlockComment() {
+		BlockComment result = new BlockComment(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented boolean literal node.
+	 * <p>
+	 * For example, the assignment expression <code>foo = true</code>
+	 * is generated by the following snippet:
+	 * <code>
+	 * <pre>
+	 * Assignment e= ast.newAssignment();
+	 * e.setLeftHandSide(ast.newSimpleName("foo"));
+	 * e.setRightHandSide(ast.newBooleanLiteral(true));
+	 * </pre>
+	 * </code>
+	 * </p>
+	 *
+	 * @param value the boolean value
+	 * @return a new unparented boolean literal node
+	 */
+	public BooleanLiteral newBooleanLiteral(boolean value) {
+		BooleanLiteral result = new BooleanLiteral(this);
+		result.setBooleanValue(value);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented break statement node owned by this AST.
+	 * The break statement has no label.
+	 *
+	 * @return a new unparented break statement node
+	 */
+	public BreakStatement newBreakStatement() {
+		return new BreakStatement(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented cast expression node
+	 * owned by this AST. By default, the type and expression are unspecified
+	 * (but legal).
+	 *
+	 * @return a new unparented cast expression node
+	 */
+	public CastExpression newCastExpression() {
+		CastExpression result = new CastExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented catch clause node owned by this AST.
+	 * By default, the catch clause declares an unspecified, but legal,
+	 * exception declaration and has an empty block.
+	 *
+	 * @return a new unparented catch clause node
+	 */
+	public CatchClause newCatchClause() {
+		return new CatchClause(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented character literal node.
+	 * Initially the node has an unspecified character literal.
+	 *
+	 * @return a new unparented character literal node
+	 */
+	public CharacterLiteral newCharacterLiteral() {
+		return new CharacterLiteral(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented class instance creation
+	 * ("new") expression node owned by this AST. By default,
+	 * there is no qualifying expression, no type parameters,
+	 * an unspecified (but legal) type name, an empty list of
+	 * arguments, and does not declare an anonymous class declaration.
+	 *
+	 * @return a new unparented class instance creation expression node
+	 */
+	public ClassInstanceCreation newClassInstanceCreation() {
+		ClassInstanceCreation result = new ClassInstanceCreation(this);
+		return result;
+	}
+
+	//=============================== DECLARATIONS ===========================
+	/**
+	 * Creates an unparented compilation unit node owned by this AST.
+	 * The compilation unit initially has no package declaration, no
+	 * import declarations, and no type declarations.
+	 *
+	 * @return the new unparented compilation unit node
+	 */
+	public CompilationUnit newCompilationUnit() {
+		return new CompilationUnit(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented conditional expression node
+	 * owned by this AST. By default, the condition and both expressions
+	 * are unspecified (but legal).
+	 *
+	 * @return a new unparented array conditional expression node
+	 */
+	public ConditionalExpression newConditionalExpression() {
+		ConditionalExpression result = new ConditionalExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented alternate constructor ("this(...);") invocation
+	 * statement node owned by this AST. By default, the lists of arguments
+	 * and type arguments are both empty.
+	 * <p>
+	 * Note that this type of node is a Statement, whereas a regular
+	 * method invocation is an Expression. The only valid use of these
+	 * statements are as the first statement of a constructor body.
+	 * </p>
+	 *
+	 * @return a new unparented alternate constructor invocation statement node
+	 */
+	public ConstructorInvocation newConstructorInvocation() {
+		ConstructorInvocation result = new ConstructorInvocation(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented continue statement node owned by this AST.
+	 * The continue statement has no label.
+	 *
+	 * @return a new unparented continue statement node
+	 */
+	public ContinueStatement newContinueStatement() {
+		return new ContinueStatement(this);
+	}
+
+	/**
+	 * Creates an unparented creation reference node owned by this AST.
+	 * By default, the type is unspecified (but legal), and there are no type arguments.
+	 * 
+	 * @return a new unparented creation reference expression node
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public CreationReference newCreationReference() {
+		CreationReference result = new CreationReference(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented do statement node owned by this AST.
+	 * By default, the expression is unspecified (but legal), and
+	 * the body statement is an empty block.
+	 *
+	 * @return a new unparented do statement node
+	 */
+	public DoStatement newDoStatement() {
+		return new DoStatement(this);
+	}
+
+	/**
+	 * Creates a new unparented empty statement node owned by this AST.
+	 *
+	 * @return a new unparented empty statement node
+	 */
+	public EmptyStatement newEmptyStatement() {
+		return new EmptyStatement(this);
+	}
+
+	/**
+	 * Creates a new unparented enhanced for statement node owned by this AST.
+	 * By default, the paramter and expression are unspecified
+	 * but legal subtrees, and the body is an empty block.
+	 *
+	 * @return a new unparented throw statement node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public EnhancedForStatement newEnhancedForStatement() {
+		return new EnhancedForStatement(this);
+	}
+
+	/**
+	 * Creates an unparented enum constant declaration node owned by this AST.
+	 * The name of the constant is an unspecified, but legal, name;
+	 * no doc comment; no modifiers or annotations; no arguments;
+	 * and does not declare an anonymous class.
+	 *
+	 * @return a new unparented enum constant declaration node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public EnumConstantDeclaration newEnumConstantDeclaration() {
+		EnumConstantDeclaration result = new EnumConstantDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented enum declaration node owned by this AST.
+	 * The name of the enum is an unspecified, but legal, name;
+	 * no doc comment; no modifiers or annotations;
+	 * no superinterfaces; and empty lists of enum constants
+	 * and body declarations.
+	 *
+	 * @return a new unparented enum declaration node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public EnumDeclaration newEnumDeclaration() {
+		EnumDeclaration result = new EnumDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented expression method reference node owned by this AST.
+	 * By default, the expression and method name are unspecified (but legal),
+	 * and there are no type arguments.
+	 * 
+	 * @return a new unparented expression method reference expression node
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public ExpressionMethodReference newExpressionMethodReference() {
+		ExpressionMethodReference result = new ExpressionMethodReference(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented expression statement node owned by this AST,
+	 * for the given expression.
+	 * <p>
+	 * This method can be used to convert an expression
+	 * (<code>Expression</code>) into a statement (<code>Type</code>)
+	 * by wrapping it. Note, however, that the result is only legal for
+	 * limited expression types, including method invocations, assignments,
+	 * and increment/decrement operations.
+	 * </p>
+	 *
+	 * @param expression the expression
+	 * @return a new unparented statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public ExpressionStatement newExpressionStatement(Expression expression) {
+		ExpressionStatement result = new ExpressionStatement(this);
+		result.setExpression(expression);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented annotatable extra dimension node
+	 * (Supported only in JLS8 level).
+	 *
+	 * @return a new unparented annotatable extra dimension node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public ExtraDimension newExtraDimension() {
+		ExtraDimension result = new ExtraDimension(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented field access expression node
+	 * owned by this AST. By default, the expression and field are both
+	 * unspecified, but legal, names.
+	 *
+	 * @return a new unparented field access expression node
+	 */
+	public FieldAccess newFieldAccess() {
+		FieldAccess result = new FieldAccess(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented field declaration node owned by this AST,
+	 * for the given variable declaration fragment. By default, there are no
+	 * modifiers, no doc comment, and the base type is unspecified
+	 * (but legal).
+	 * <p>
+	 * This method can be used to wrap a variable declaration fragment
+	 * (<code>VariableDeclarationFragment</code>) into a field declaration
+	 * suitable for inclusion in the body of a type declaration
+	 * (<code>FieldDeclaration</code> implements <code>BodyDeclaration</code>).
+	 * Additional variable declaration fragments can be added afterwards.
+	 * </p>
+	 *
+	 * @param fragment the variable declaration fragment
+	 * @return a new unparented field declaration node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>the given fragment is null</li>
+	 * </ul>
+	 */
+	public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) {
+		if (fragment == null) {
+			throw new IllegalArgumentException();
+		}
+		FieldDeclaration result = new FieldDeclaration(this);
+		result.fragments().add(fragment);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented for statement node owned by this AST.
+	 * By default, there are no initializers, no condition expression,
+	 * no updaters, and the body is an empty block.
+	 *
+	 * @return a new unparented for statement node
+	 */
+	public ForStatement newForStatement() {
+		return new ForStatement(this);
+	}
+
+	/**
+	 * Creates a new unparented if statement node owned by this AST.
+	 * By default, the expression is unspecified (but legal),
+	 * the then statement is an empty block, and there is no else statement.
+	 *
+	 * @return a new unparented if statement node
+	 */
+	public IfStatement newIfStatement() {
+		return new IfStatement(this);
+	}
+
+	/**
+	 * Creates an unparented import declaration node owned by this AST.
+	 * The import declaration initially contains a single-type import
+	 * of a type with an unspecified name.
+	 *
+	 * @return the new unparented import declaration node
+	 */
+	public ImportDeclaration newImportDeclaration() {
+		ImportDeclaration result = new ImportDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented infix expression node
+	 * owned by this AST. By default, the operator and left and right
+	 * operand are unspecified (but legal), and there are no extended
+	 * operands.
+	 *
+	 * @return a new unparented infix expression node
+	 */
+	public InfixExpression newInfixExpression() {
+		InfixExpression result = new InfixExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented initializer node owned by this AST, with an
+	 * empty block. By default, the initializer has no modifiers and
+	 * an empty block.
+	 *
+	 * @return a new unparented initializer node
+	 */
+	public Initializer newInitializer() {
+		Initializer result = new Initializer(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented instanceof expression node
+	 * owned by this AST. By default, the operator and left and right
+	 * operand are unspecified (but legal).
+	 *
+	 * @return a new unparented instanceof expression node
+	 */
+	public InstanceofExpression newInstanceofExpression() {
+		InstanceofExpression result = new InstanceofExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new doc comment node.
+	 * Initially the new node has an empty list of tag elements
+	 * (and, for backwards compatability, an unspecified, but legal,
+	 * doc comment string)
+	 *
+	 * @return a new unparented doc comment node
+	 */
+	public Javadoc newJavadoc() {
+		Javadoc result = new Javadoc(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented labeled statement node owned by this AST.
+	 * By default, the label and statement are both unspecified, but legal.
+	 *
+	 * @return a new unparented labeled statement node
+	 */
+	public LabeledStatement newLabeledStatement() {
+		return new LabeledStatement(this);
+	}
+
+	/**
+	 * Creates an unparented lambda expression node owned by this AST.
+	 * By default, the new lambda expression has parentheses enabled, contains an empty argument
+	 * list, and the body is an empty block.
+	 * 
+	 * @return a new unparented lambda expression node
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public LambdaExpression newLambdaExpression() {
+		LambdaExpression result = new LambdaExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new line comment placeholder node.
+	 * <p>
+	 * Note that this node type is used to recording the source
+	 * range where a comment was found in the source string.
+	 * These comment nodes are normally found (only) in
+	 * {@linkplain CompilationUnit#getCommentList()
+	 * the comment table} for parsed compilation units.
+	 * </p>
+	 *
+	 * @return a new unparented line comment node
+	 * @since 3.0
+	 */
+	public LineComment newLineComment() {
+		LineComment result = new LineComment(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented marker annotation node with
+	 * an unspecified type name.
+	 *
+	 * @return a new unparented marker annotation node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public MarkerAnnotation newMarkerAnnotation() {
+		MarkerAnnotation result = new MarkerAnnotation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new member reference node.
+	 * Initially the new node has no qualifier name and
+	 * an unspecified, but legal, member name.
+	 * <p>
+	 * Note that this node type is used only inside doc comments
+	 * ({@link Javadoc}).
+	 * </p>
+	 *
+	 * @return a new unparented member reference node
+	 * @since 3.0
+	 */
+	public MemberRef newMemberRef() {
+		MemberRef result = new MemberRef(this);
+		return result;
+	}
+
+	//=============================== COMMENTS ===========================
+
+	/**
+	 * Creates and returns a new unparented member value pair node with
+	 * an unspecified member name and value.
+	 *
+	 * @return a new unparented member value pair node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public MemberValuePair newMemberValuePair() {
+		MemberValuePair result = new MemberValuePair(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented method declaration node owned by this AST.
+	 * By default, the declaration is for a method of an unspecified, but
+	 * legal, name; no modifiers; no doc comment; no parameters; return
+	 * type void; no extra array dimensions; no thrown exceptions; and no
+	 * body (as opposed to an empty body).
+	 * <p>
+	 * To create a constructor, use this method and then call
+	 * <code>MethodDeclaration.setConstructor(true)</code> and
+	 * <code>MethodDeclaration.setName(className)</code>.
+	 * </p>
+	 *
+	 * @return a new unparented method declaration node
+	 */
+	public MethodDeclaration newMethodDeclaration() {
+		MethodDeclaration result = new MethodDeclaration(this);
+		result.setConstructor(false);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented method invocation expression node owned by this
+	 * AST. By default, the name of the method is unspecified (but legal)
+	 * there is no receiver expression, no type arguments, and the list of
+	 * arguments is empty.
+	 *
+	 * @return a new unparented method invocation expression node
+	 */
+	public MethodInvocation newMethodInvocation() {
+		MethodInvocation result = new MethodInvocation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new method reference node.
+	 * Initially the new node has no qualifier name,
+	 * an unspecified, but legal, method name, and an
+	 * empty parameter list.
+	 * <p>
+	 * Note that this node type is used only inside doc comments
+	 * ({@link Javadoc Javadoc}).
+	 * </p>
+	 *
+	 * @return a new unparented method reference node
+	 * @since 3.0
+	 */
+	public MethodRef newMethodRef() {
+		MethodRef result = new MethodRef(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new method reference node.
+	 * Initially the new node has an unspecified, but legal,
+	 * type, not variable arity, and no parameter name.
+	 * <p>
+	 * Note that this node type is used only inside doc comments
+	 * ({@link Javadoc}).
+	 * </p>
+	 *
+	 * @return a new unparented method reference parameter node
+	 * @since 3.0
+	 */
+	public MethodRefParameter newMethodRefParameter() {
+		MethodRefParameter result = new MethodRefParameter(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented modifier node for the given
+	 * modifier.
+	 *
+	 * @param keyword one of the modifier keyword constants
+	 * @return a new unparented modifier node
+	 * @exception IllegalArgumentException if the primitive type code is invalid
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public Modifier newModifier(Modifier.ModifierKeyword keyword) {
+		Modifier result = new Modifier(this);
+		result.setKeyword(keyword);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a list of new unparented modifier nodes
+	 * for the given modifier flags. When multiple modifiers are
+	 * requested, the modifier nodes will appear in the following order:
+	 * <pre> public protected private
+	 * abstract default static final synchronized native strictfp transient volatile</pre>
+	 * <p>
+	 * This order is consistent with the recommendations in JLS8 ("*Modifier:" rules in chapters 8 and 9).
+	 * </p>
+	 *
+	 * @param flags bitwise or of modifier flags declared on {@link Modifier}
+	 * @return a possibly empty list of new unparented modifier nodes
+	 *   (element type <code>Modifier</code>)
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List newModifiers(int flags) {
+		if (this.apiLevel == AST.JLS2) {
+			unsupportedIn2();
+		}
+		List result = new ArrayList(3); // 3 modifiers is more than average
+		if (Modifier.isPublic(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD));
+		}
+		if (Modifier.isProtected(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD));
+		}
+		if (Modifier.isPrivate(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD));
+		}
+		if (Modifier.isAbstract(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD));
+		}
+		if (Modifier.isDefault(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.DEFAULT_KEYWORD));
+		}
+		if (Modifier.isStatic(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD));
+		}
+		if (Modifier.isFinal(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
+		}
+		if (Modifier.isSynchronized(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD));
+		}
+		if (Modifier.isNative(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD));
+		}
+		if (Modifier.isStrictfp(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD));
+		}
+		if (Modifier.isTransient(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD));
+		}
+		if (Modifier.isVolatile(flags)) {
+			result.add(newModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD));
+		}
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented name node for the given name.
+	 * The name string must consist of 1 or more name segments separated
+	 * by single dots '.'. Returns a {@link QualifiedName} if the name has
+	 * dots, and a {@link SimpleName} otherwise. Each of the name
+	 * segments should be legal Java identifiers (this constraint may or may
+	 * not be enforced), and there must be at least one name segment.
+	 * The string must not contains white space, '&lt;', '&gt;',
+	 * '[', ']', or other any other characters that are not
+	 * part of the Java identifiers or separating '.'s.
+	 *
+	 * @param qualifiedName string consisting of 1 or more name segments,
+	 * each of which is a legal Java identifier, separated  by single dots '.'
+	 * @return a new unparented name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the string is empty</li>
+	 * <li>the string begins or ends in a '.'</li>
+	 * <li>the string has adjacent '.'s</li>
+	 * <li>the segments between the '.'s are not valid Java identifiers</li>
+	 * </ul>
+	 * @since 3.1
+	 */
+	public Name newName(String qualifiedName) {
+		StringTokenizer t = new StringTokenizer(qualifiedName, ".", true); //$NON-NLS-1$
+		Name result = null;
+		// balance is # of name tokens - # of period tokens seen so far
+		// initially 0; finally 1; should never drop < 0 or > 1
+		int balance = 0;
+		while(t.hasMoreTokens()) {
+			String s = t.nextToken();
+			if (s.indexOf('.') >= 0) {
+				// this is a delimiter
+				if (s.length() > 1) {
+					// too many dots in a row
+					throw new IllegalArgumentException();
+				}
+				balance--;
+				if (balance < 0) {
+					throw new IllegalArgumentException();
+				}
+			} else {
+				// this is an identifier segment
+				balance++;
+				SimpleName name = newSimpleName(s);
+				if (result == null) {
+					result = name;
+				} else {
+					result = newQualifiedName(result, name);
+				}
+			}
+		}
+		if (balance != 1) {
+			throw new IllegalArgumentException();
+		}
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented name node for the given name
+	 * segments. Returns a simple name if there is only one name segment, and
+	 * a qualified name if there are multiple name segments. Each of the name
+	 * segments should be legal Java identifiers (this constraint may or may
+	 * not be enforced), and there must be at least one name segment.
+	 *
+	 * @param identifiers a list of 1 or more name segments, each of which
+	 *    is a legal Java identifier
+	 * @return a new unparented name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the identifier is invalid</li>
+	 * <li>the list of identifiers is empty</li>
+	 * </ul>
+	 */
+	public Name newName(String[] identifiers) {
+		// update internalSetName(String[] if changed
+		int count = identifiers.length;
+		if (count == 0) {
+			throw new IllegalArgumentException();
+		}
+		Name result = newSimpleName(identifiers[0]);
+		for (int i = 1; i < count; i++) {
+			SimpleName name = newSimpleName(identifiers[i]);
+			result = newQualifiedName(result, name);
+		}
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented normal annotation node with
+	 * an unspecified type name and an empty list of member value
+	 * pairs.
+	 *
+	 * @return a new unparented normal annotation node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public NormalAnnotation newNormalAnnotation() {
+		NormalAnnotation result = new NormalAnnotation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented null literal node.
+	 *
+	 * @return a new unparented null literal node
+	 */
+	public NullLiteral newNullLiteral() {
+		return new NullLiteral(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented number literal node.
+	 * Initially the number literal token is <code>"0"</code>.
+	 *
+	 * @return a new unparented number literal node
+	 */
+	public NumberLiteral newNumberLiteral() {
+		NumberLiteral result = new NumberLiteral(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented number literal node.
+	 *
+	 * @param literal the token for the numeric literal as it would
+	 *    appear in Java source code
+	 * @return a new unparented number literal node
+	 * @exception IllegalArgumentException if the literal is null
+	 */
+	public NumberLiteral newNumberLiteral(String literal) {
+		if (literal == null) {
+			throw new IllegalArgumentException();
+		}
+		NumberLiteral result = new NumberLiteral(this);
+		result.setToken(literal);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented package declaration node owned by this AST.
+	 * The package declaration initially declares a package with an
+	 * unspecified name.
+	 *
+	 * @return the new unparented package declaration node
+	 */
+	public PackageDeclaration newPackageDeclaration() {
+		PackageDeclaration result = new PackageDeclaration(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented package qualified type node with
+	 * the given qualifier and name.
+	 *
+	 * @param qualifier the package qualifier type node
+	 * @param name the simple name being qualified
+	 * @return a new unparented qualified type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2, JLS3 and JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public PackageQualifiedType newPackageQualifiedType(Name qualifier, SimpleName name) {
+		PackageQualifiedType result = new PackageQualifiedType(this);
+		result.setQualifier(qualifier);
+		result.setName(name);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented parameterized type node with the
+	 * given type and an empty list of type arguments.
+	 *
+	 * @param type the type that is parameterized
+	 * @return a new unparented parameterized type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public ParameterizedType newParameterizedType(Type type) {
+		ParameterizedType result = new ParameterizedType(this);
+		result.setType(type);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented parenthesized expression node
+	 * owned by this AST. By default, the expression is unspecified (but legal).
+	 *
+	 * @return a new unparented parenthesized expression node
+	 */
+	public ParenthesizedExpression newParenthesizedExpression() {
+		ParenthesizedExpression result = new ParenthesizedExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented postfix expression node
+	 * owned by this AST. By default, the operator and operand are
+	 * unspecified (but legal).
+	 *
+	 * @return a new unparented postfix expression node
+	 */
+	public PostfixExpression newPostfixExpression() {
+		PostfixExpression result = new PostfixExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented prefix expression node
+	 * owned by this AST. By default, the operator and operand are
+	 * unspecified (but legal).
+	 *
+	 * @return a new unparented prefix expression node
+	 */
+	public PrefixExpression newPrefixExpression() {
+		PrefixExpression result = new PrefixExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented primitive type node with the given
+	 * type code.
+	 *
+	 * @param typeCode one of the primitive type code constants declared in
+	 *    <code>PrimitiveType</code>
+	 * @return a new unparented primitive type node
+	 * @exception IllegalArgumentException if the primitive type code is invalid
+	 */
+	public PrimitiveType newPrimitiveType(PrimitiveType.Code typeCode) {
+		PrimitiveType result = new PrimitiveType(this);
+		result.setPrimitiveTypeCode(typeCode);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented qualified name node for the given
+	 * qualifier and simple name child node.
+	 *
+	 * @param qualifier the qualifier name node
+	 * @param name the simple name being qualified
+	 * @return a new unparented qualified name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public QualifiedName newQualifiedName(
+		Name qualifier,
+		SimpleName name) {
+		QualifiedName result = new QualifiedName(this);
+		result.setQualifier(qualifier);
+		result.setName(name);
+		return result;
+
+	}
+
+	/**
+	 * Creates and returns a new unparented qualified type node with
+	 * the given qualifier type and name.
+	 *
+	 * @param qualifier the qualifier type node
+	 * @param name the simple name being qualified
+	 * @return a new unparented qualified type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public QualifiedType newQualifiedType(Type qualifier, SimpleName name) {
+		QualifiedType result = new QualifiedType(this);
+		result.setQualifier(qualifier);
+		result.setName(name);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented return statement node owned by this AST.
+	 * By default, the return statement has no expression.
+	 *
+	 * @return a new unparented return statement node
+	 */
+	public ReturnStatement newReturnStatement() {
+		return new ReturnStatement(this);
+	}
+
+	//=============================== NAMES ===========================
+	/**
+	 * Creates and returns a new unparented simple name node for the given
+	 * identifier. The identifier should be a legal Java identifier, but not
+	 * a keyword, boolean literal ("true", "false") or null literal ("null").
+	 *
+	 * @param identifier the identifier
+	 * @return a new unparented simple name node
+	 * @exception IllegalArgumentException if the identifier is invalid
+	 */
+	public SimpleName newSimpleName(String identifier) {
+		if (identifier == null) {
+			throw new IllegalArgumentException();
+		}
+		SimpleName result = new SimpleName(this);
+		result.setIdentifier(identifier);
+		return result;
+	}
+
+	//=============================== TYPES ===========================
+	/**
+	 * Creates and returns a new unparented simple type node with the given
+	 * type name.
+	 * <p>
+	 * This method can be used to convert a name (<code>Name</code>) into a
+	 * type (<code>Type</code>) by wrapping it.
+	 * </p>
+	 *
+	 * @param typeName the name of the class or interface
+	 * @return a new unparented simple type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public SimpleType newSimpleType(Name typeName) {
+		SimpleType result = new SimpleType(this);
+		result.setName(typeName);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented single member annotation node with
+	 * an unspecified type name and value.
+	 *
+	 * @return a new unparented single member annotation node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public SingleMemberAnnotation newSingleMemberAnnotation() {
+		SingleMemberAnnotation result = new SingleMemberAnnotation(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented single variable declaration node owned by this AST.
+	 * By default, the declaration is for a variable with an unspecified, but
+	 * legal, name and type; no modifiers; no array dimensions after the
+	 * variable; no initializer; not variable arity.
+	 *
+	 * @return a new unparented single variable declaration node
+	 */
+	public SingleVariableDeclaration newSingleVariableDeclaration() {
+		SingleVariableDeclaration result = new SingleVariableDeclaration(this);
+		return result;
+	}
+
+	//=============================== EXPRESSIONS ===========================
+	/**
+	 * Creates and returns a new unparented string literal node for
+	 * the empty string literal.
+	 *
+	 * @return a new unparented string literal node
+	 */
+	public StringLiteral newStringLiteral() {
+		return new StringLiteral(this);
+	}
+
+	/**
+	 * Creates an unparented alternate super constructor ("super(...);")
+	 * invocation statement node owned by this AST. By default, there is no
+	 * qualifier, no type arguments, and the list of arguments is empty.
+	 * <p>
+	 * Note that this type of node is a Statement, whereas a regular
+	 * super method invocation is an Expression. The only valid use of these
+	 * statements are as the first statement of a constructor body.
+	 * </p>
+	 *
+	 * @return a new unparented super constructor invocation statement node
+	 */
+	public SuperConstructorInvocation newSuperConstructorInvocation() {
+		SuperConstructorInvocation result =
+			new SuperConstructorInvocation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented super field access expression node
+	 * owned by this AST. By default, the expression and field are both
+	 * unspecified, but legal, names.
+	 *
+	 * @return a new unparented super field access expression node
+	 */
+	public SuperFieldAccess newSuperFieldAccess() {
+		SuperFieldAccess result = new SuperFieldAccess(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented "super" method invocation expression node owned by
+	 * this AST. By default, the name of the method is unspecified (but legal),
+	 * there is no qualifier, no type arguments, and the list of arguments is empty.
+	 *
+	 * @return a new unparented  "super" method invocation
+	 *    expression node
+	 */
+	public SuperMethodInvocation newSuperMethodInvocation() {
+		SuperMethodInvocation result = new SuperMethodInvocation(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented super method reference node owned by
+	 * this AST. By default, the name of the method is unspecified (but legal),
+	 * and there is no qualifier and no type arguments.
+	 *
+	 * @return a new unparented super method reference node
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public SuperMethodReference newSuperMethodReference() {
+		SuperMethodReference result = new SuperMethodReference(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented switch case statement node owned by
+	 * this AST. By default, the expression is unspecified, but legal.
+	 *
+	 * @return a new unparented switch case node
+	 */
+	public SwitchCase newSwitchCase() {
+		return new SwitchCase(this);
+	}
+
+
+	/**
+	 * Creates a new unparented switch statement node owned by this AST.
+	 * By default, the expression is unspecified, but legal, and there are
+	 * no statements or switch cases.
+	 *
+	 * @return a new unparented labeled statement node
+	 */
+	public SwitchStatement newSwitchStatement() {
+		return new SwitchStatement(this);
+	}
+
+	/**
+	 * Creates a new unparented synchronized statement node owned by this AST.
+	 * By default, the expression is unspecified, but legal, and the body is
+	 * an empty block.
+	 *
+	 * @return a new unparented synchronized statement node
+	 */
+	public SynchronizedStatement newSynchronizedStatement() {
+		return new SynchronizedStatement(this);
+	}
+
+	/**
+	 * Creates and returns a new tag element node.
+	 * Initially the new node has no tag name and an empty list of fragments.
+	 * <p>
+	 * Note that this node type is used only inside doc comments
+	 * ({@link Javadoc}).
+	 * </p>
+	 *
+	 * @return a new unparented tag element node
+	 * @since 3.0
+	 */
+	public TagElement newTagElement() {
+		TagElement result = new TagElement(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new text element node.
+	 * Initially the new node has an empty text string.
+	 * <p>
+	 * Note that this node type is used only inside doc comments
+	 * ({@link Javadoc Javadoc}).
+	 * </p>
+	 *
+	 * @return a new unparented text element node
+	 * @since 3.0
+	 */
+	public TextElement newTextElement() {
+		TextElement result = new TextElement(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented "this" expression node
+	 * owned by this AST. By default, there is no qualifier.
+	 *
+	 * @return a new unparented "this" expression node
+	 */
+	public ThisExpression newThisExpression() {
+		ThisExpression result = new ThisExpression(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented throw statement node owned by this AST.
+	 * By default, the expression is unspecified, but legal.
+	 *
+	 * @return a new unparented throw statement node
+	 */
+	public ThrowStatement newThrowStatement() {
+		return new ThrowStatement(this);
+	}
+
+	/**
+	 * Creates a new unparented try statement node owned by this AST.
+	 * By default, the try statement has no resources, an empty block, no catch
+	 * clauses, and no finally block.
+	 *
+	 * @return a new unparented try statement node
+	 */
+	public TryStatement newTryStatement() {
+		return new TryStatement(this);
+	}
+
+	/**
+	 * Creates an unparented class declaration node owned by this AST.
+	 * The name of the class is an unspecified, but legal, name;
+	 * no modifiers; no doc comment; no superclass or superinterfaces;
+	 * and an empty class body.
+	 * <p>
+	 * To create an interface, use this method and then call
+	 * <code>TypeDeclaration.setInterface(true)</code>.
+	 * </p>
+	 *
+	 * @return a new unparented type declaration node
+	 */
+	public TypeDeclaration newTypeDeclaration() {
+		TypeDeclaration result = new TypeDeclaration(this);
+		result.setInterface(false);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented local type declaration statement node
+	 * owned by this AST, for the given type declaration.
+	 * <p>
+	 * This method can be used to convert any kind of type declaration
+	 * (<code>AbstractTypeDeclaration</code>) into a statement
+	 * (<code>Statement</code>) by wrapping it.
+	 * </p>
+	 *
+	 * @param decl the type declaration
+	 * @return a new unparented local type declaration statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @since 3.0
+	 */
+	public TypeDeclarationStatement
+			newTypeDeclarationStatement(AbstractTypeDeclaration decl) {
+		TypeDeclarationStatement result = new TypeDeclarationStatement(this);
+		if (this.apiLevel == AST.JLS2) {
+			result.internalSetTypeDeclaration((TypeDeclaration) decl);
+		}
+		if (this.apiLevel >= AST.JLS3) {
+			result.setDeclaration(decl);
+		}
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented local type declaration statement node
+	 * owned by this AST, for the given type declaration.
+	 * <p>
+	 * This method can be used to convert a type declaration
+	 * (<code>TypeDeclaration</code>) into a statement
+	 * (<code>Statement</code>) by wrapping it.
+	 * </p>
+	 *
+	 * @param decl the type declaration
+	 * @return a new unparented local type declaration statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public TypeDeclarationStatement
+			newTypeDeclarationStatement(TypeDeclaration decl) {
+		TypeDeclarationStatement result = new TypeDeclarationStatement(this);
+		result.setDeclaration(decl);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented type literal expression node
+	 * owned by this AST. By default, the type is unspecified (but legal).
+	 *
+	 * @return a new unparented type literal node
+	 */
+	public TypeLiteral newTypeLiteral() {
+		TypeLiteral result = new TypeLiteral(this);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented type method reference node owned by this AST.
+	 * By default, the type and method name are unspecified (but legal),
+	 * and there are no type arguments.
+	 * 
+	 * @return a new unparented type method reference node
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public TypeMethodReference newTypeMethodReference() {
+		TypeMethodReference result = new TypeMethodReference(this);
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented type parameter type node with an
+	 * unspecified type variable name and an empty list of type bounds.
+	 *
+	 * @return a new unparented type parameter node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public TypeParameter newTypeParameter() {
+		TypeParameter result = new TypeParameter(this);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented union type node owned by this AST.
+	 * By default, the union type has no types.
+	 *
+	 * @return a new unparented UnionType node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 or JLS3 AST
+	 * @since 3.7.1
+	 */
+	public UnionType newUnionType() {
+		return new UnionType(this);
+	}
+
+	/**
+	 * Creates a new unparented intersection type node owned by this AST.
+	 * By default, the intersection type has no types.
+	 *
+	 * @return a new unparented IntersectionType node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public IntersectionType newIntersectionType() {
+		return new IntersectionType(this);
+	}
+
+	/**
+	 * Creates a new unparented local variable declaration expression node
+	 * owned by this AST, for the given variable declaration fragment. By
+	 * default, there are no modifiers and the base type is unspecified
+	 * (but legal).
+	 * <p>
+	 * This method can be used to convert a variable declaration fragment
+	 * (<code>VariableDeclarationFragment</code>) into an expression
+	 * (<code>Expression</code>) by wrapping it. Additional variable
+	 * declaration fragments can be added afterwards.
+	 * </p>
+	 *
+	 * @param fragment the first variable declaration fragment
+	 * @return a new unparented variable declaration expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>the given fragment is null</li>
+	 * </ul>
+	 */
+	public VariableDeclarationExpression
+			newVariableDeclarationExpression(VariableDeclarationFragment fragment) {
+		if (fragment == null) {
+			throw new IllegalArgumentException();
+		}
+		VariableDeclarationExpression result =
+			new VariableDeclarationExpression(this);
+		result.fragments().add(fragment);
+		return result;
+	}
+
+	/**
+	 * Creates an unparented variable declaration fragment node owned by this
+	 * AST. By default, the fragment is for a variable with an unspecified, but
+	 * legal, name; no extra array dimensions; and no initializer.
+	 *
+	 * @return a new unparented variable declaration fragment node
+	 */
+	public VariableDeclarationFragment newVariableDeclarationFragment() {
+		VariableDeclarationFragment result = new VariableDeclarationFragment(this);
+		return result;
+	}
+
+	//=============================== STATEMENTS ===========================
+	/**
+	 * Creates a new unparented local variable declaration statement node
+	 * owned by this AST, for the given variable declaration fragment.
+	 * By default, there are no modifiers and the base type is unspecified
+	 * (but legal).
+	 * <p>
+	 * This method can be used to convert a variable declaration fragment
+	 * (<code>VariableDeclarationFragment</code>) into a statement
+	 * (<code>Statement</code>) by wrapping it. Additional variable
+	 * declaration fragments can be added afterwards.
+	 * </p>
+	 *
+	 * @param fragment the variable declaration fragment
+	 * @return a new unparented variable declaration statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>the variable declaration fragment is null</li>
+	 * </ul>
+	 */
+	public VariableDeclarationStatement
+			newVariableDeclarationStatement(VariableDeclarationFragment fragment) {
+		if (fragment == null) {
+			throw new IllegalArgumentException();
+		}
+		VariableDeclarationStatement result =
+			new VariableDeclarationStatement(this);
+		result.fragments().add(fragment);
+		return result;
+	}
+
+	/**
+	 * Creates a new unparented while statement node owned by this AST.
+	 * By default, the expression is unspecified (but legal), and
+	 * the body statement is an empty block.
+	 *
+	 * @return a new unparented while statement node
+	 */
+	public WhileStatement newWhileStatement() {
+		return new WhileStatement(this);
+	}
+
+	/**
+	 * Creates and returns a new unparented wildcard type node with no
+	 * type bound.
+	 *
+	 * @return a new unparented wildcard type node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public WildcardType newWildcardType() {
+		WildcardType result = new WildcardType(this);
+		return result;
+	}
+
+	/**
+	 * Reports that the given node has just gained a child.
+	 *
+	 * @param node the node that was modified
+	 * @param child the node that was added as a child
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE ADD]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.postAddChildEvent(node, child, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node has just been cloned.
+	 *
+	 * @param node the node that was cloned
+	 * @param clone the clone of <code>node</code>
+	 * @since 3.0
+	 */
+	void postCloneNodeEvent(ASTNode node, ASTNode clone) {
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE CLONE]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.postCloneNodeEvent(node, clone);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node jsut lost a child.
+	 *
+	 * @param node the node that was modified
+	 * @param child the child node that was removed
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE DEL]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.postRemoveChildEvent(node, child, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has not been changed yet
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node has just had a child replaced.
+	 *
+	 * @param node the node modified
+	 * @param child the child removed
+	 * @param newChild the replacement child
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE REP]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.postReplaceChildEvent(node, child, newChild, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has not been changed yet
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node has just changed the value of a
+	 * non-child property.
+	 *
+	 * @param node the node that was modified
+	 * @param property the property descriptor
+	 * @since 3.0
+	 */
+	void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE CHANGE]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.postValueChangeEvent(node, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node is about to gain a child.
+	 *
+	 * @param node the node that to be modified
+	 * @param child the node that to be added as a child
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE ADD]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.preAddChildEvent(node, child, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node is about to be cloned.
+	 *
+	 * @param node the node to be cloned
+	 * @since 3.0
+	 */
+	void preCloneNodeEvent(ASTNode node) {
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE CLONE]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.preCloneNodeEvent(node);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node is about to lose a child.
+	 *
+	 * @param node the node about to be modified
+	 * @param child the node about to be removed
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE DEL]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.preRemoveChildEvent(node, child, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has not been changed yet
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node is about have a child replaced.
+	 *
+	 * @param node the node about to be modified
+	 * @param child the child node about to be removed
+	 * @param newChild the replacement child
+	 * @param property the child or child list property descriptor
+	 * @since 3.0
+	 */
+	void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE REP]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.preReplaceChildEvent(node, child, newChild, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has not been changed yet
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Reports that the given node is about to change the value of a
+	 * non-child property.
+	 *
+	 * @param node the node to be modified
+	 * @param property the property descriptor
+	 * @since 3.0
+	 */
+	void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers during lazy init
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by a reader doing lazy init
+			if (this.disableEvents > 0) {
+				// doing lazy init OR already processing an event
+				// System.out.println("[BOUNCE CHANGE]");
+				return;
+			} else {
+				disableEvents();
+			}
+		}
+		try {
+			this.eventHandler.preValueChangeEvent(node, property);
+			// N.B. even if event handler blows up, the AST is not
+			// corrupted since node has already been changed
+		} finally {
+			reenableEvents();
+		}
+	}
+
+	/**
+	 * Enables the recording of changes to the given compilation
+	 * unit and its descendents. The compilation unit must have
+	 * been created by <code>ASTParser</code> and still be in
+	 * its original state. Once recording is on,
+	 * arbitrary changes to the subtree rooted at the compilation
+	 * unit are recorded internally. Once the modification has
+	 * been completed, call <code>rewrite</code> to get an object
+	 * representing the corresponding edits to the original
+	 * source code string.
+	 *
+	 * @exception IllegalArgumentException if this compilation unit is
+	 * marked as unmodifiable, or if this compilation unit has already
+	 * been tampered with, or if recording has already been enabled,
+	 * or if <code>root</code> is not owned by this AST
+	 * @see CompilationUnit#recordModifications()
+	 * @since 3.0
+	 */
+	void recordModifications(CompilationUnit root) {
+		if(this.modificationCount != this.originalModificationCount) {
+			throw new IllegalArgumentException("AST is already modified"); //$NON-NLS-1$
+		} else if(this.rewriter  != null) {
+			throw new IllegalArgumentException("AST modifications are already recorded"); //$NON-NLS-1$
+		} else if((root.getFlags() & ASTNode.PROTECT) != 0) {
+			throw new IllegalArgumentException("Root node is unmodifiable"); //$NON-NLS-1$
+		} else if(root.getAST() != this) {
+			throw new IllegalArgumentException("Root node is not owned by this ast"); //$NON-NLS-1$
+		}
+
+		this.rewriter = new InternalASTRewrite(root);
+		setEventHandler(this.rewriter);
+	}
+
+	//=============================== ANNOTATIONS ====================
+
+	/**
+     * Reenable events.
+	 * This method is thread-safe for AST readers.
+	 *
+	 * @see #disableEvents()
+     * @since 3.0
+     */
+	final void reenableEvents() {
+		synchronized (this.internalASTLock) {
+			// guard against concurrent access by another reader
+			this.disableEvents--;
+		}
+	}
+
+	/**
+	 * Returns the type binding for a "well known" type.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 * <p>
+	 * The following type names are supported:
+	 * <ul>
+	 * <li><code>"boolean"</code></li>
+	 * <li><code>"byte"</code></li>
+	 * <li><code>"char"</code></li>
+	 * <li><code>"double"</code></li>
+	 * <li><code>"float"</code></li>
+	 * <li><code>"int"</code></li>
+	 * <li><code>"long"</code></li>
+	 * <li><code>"short"</code></li>
+	 * <li><code>"void"</code></li>
+	 * <li><code>"java.lang.AssertionError"</code> (since 3.7)</li>
+	 * <li><code>"java.lang.Boolean"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Byte"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Character"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Class"</code></li>
+	 * <li><code>"java.lang.Cloneable"</code></li>
+	 * <li><code>"java.lang.Double"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Error"</code></li>
+	 * <li><code>"java.lang.Exception"</code></li>
+	 * <li><code>"java.lang.Float"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Integer"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Long"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Object"</code></li>
+	 * <li><code>"java.lang.RuntimeException"</code></li>
+	 * <li><code>"java.lang.Short"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.String"</code></li>
+	 * <li><code>"java.lang.StringBuffer"</code></li>
+	 * <li><code>"java.lang.Throwable"</code></li>
+	 * <li><code>"java.lang.Void"</code> (since 3.1)</li>
+	 * <li><code>"java.io.Serializable"</code></li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @param name the name of a well known type
+	 * @return the corresponding type binding, or <code>null</code> if the
+	 *   named type is not considered well known or if no binding can be found
+	 *   for it
+	 */
+	public ITypeBinding resolveWellKnownType(String name) {
+		if (name == null) {
+			return null;
+		}
+		return getBindingResolver().resolveWellKnownType(name);
+	}
+
+	/**
+	 * Converts all modifications recorded into an object
+	 * representing the corresponding text edits to the
+	 * given document containing the original source
+	 * code for the compilation unit that gave rise to
+	 * this AST.
+	 *
+	 * @param document original document containing source code
+	 * for the compilation unit
+	 * @param options the table of formatter options
+	 * (key type: <code>String</code>; value type: <code>String</code>);
+	 * or <code>null</code> to use the standard global options
+	 * {@link JavaCore#getOptions() JavaCore.getOptions()}.
+	 * @return text edit object describing the changes to the
+	 * document corresponding to the recorded AST modifications
+	 * @exception IllegalArgumentException if the document passed is
+	 * <code>null</code> or does not correspond to this AST
+	 * @exception IllegalStateException if <code>recordModifications</code>
+	 * was not called to enable recording
+	 * @see CompilationUnit#rewrite(IDocument, Map)
+	 * @since 3.0
+	 */
+	TextEdit rewrite(IDocument document, Map options) {
+		if (document == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.rewriter  == null) {
+			throw new IllegalStateException("Modifications record is not enabled"); //$NON-NLS-1$
+		}
+		return this.rewriter.rewriteAST(document, options);
+	}
+
+	/**
+	 * Sets the binding resolver for this AST.
+	 *
+	 * @param resolver the new binding resolver for this AST
+	 */
+	void setBindingResolver(BindingResolver resolver) {
+		if (resolver == null) {
+			throw new IllegalArgumentException();
+		}
+		this.resolver = resolver;
+	}
+
+	/**
+	 * Sets default node flags of new nodes of this AST.
+	 *
+	 * @param flag node flags of new nodes of this AST
+	 * @since 3.0
+	 */
+	void setDefaultNodeFlag(int flag) {
+		this.defaultNodeFlag = flag;
+	}
+
+	/**
+	 * Sets the event handler for this AST.
+	 *
+	 * @param eventHandler the event handler for this AST
+	 * @since 3.0
+	 */
+	void setEventHandler(NodeEventHandler eventHandler) {
+		if (this.eventHandler == null) {
+			throw new IllegalArgumentException();
+		}
+		this.eventHandler = eventHandler;
+	}
+
+	void setFlag(int newValue) {
+		this.bits |= newValue;
+	}
+
+	/**
+	 * Set <code>originalModificationCount</code> to the current modification count
+	 *
+	 * @since 3.0
+	 */
+	void setOriginalModificationCount(long count) {
+		this.originalModificationCount = count;
+	}
+
+	/**
+     * Checks that this AST operation is only used when
+     * building level JLS2 ASTs.
+
+     * @exception UnsupportedOperationException
+	 * @since 3.0
+     */
+	void supportedOnlyIn2() {
+	  if (this.apiLevel != AST.JLS2) {
+	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
+	  }
+	}
+
+	/**
+     * Checks that this AST operation is not used when
+     * building level JLS2 ASTs.
+
+     * @exception UnsupportedOperationException
+	 * @since 3.0
+     */
+	void unsupportedIn2() {
+	  if (this.apiLevel == AST.JLS2) {
+	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
+	  }
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
new file mode 100644
index 0000000..79f9331
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -0,0 +1,5865 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for
+ *								bug 393719 - [compiler] inconsistent warnings on iteration variables
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
+import org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression;
+import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.core.dom.SourceRangeVerifier;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Internal class for converting internal compiler ASTs into public ASTs.
+ */
+class ASTConverter {
+
+	protected AST ast;
+	private ASTNode referenceContext;
+	protected Comment[] commentsTable;
+	char[] compilationUnitSource;
+	int compilationUnitSourceLength;
+	protected DocCommentParser docParser;
+	// comments
+	protected boolean insideComments;
+	protected IProgressMonitor monitor;
+	protected Set pendingNameScopeResolution;
+	protected Set pendingThisExpressionScopeResolution;
+	protected boolean resolveBindings;
+	Scanner scanner;
+	private DefaultCommentMapper commentMapper;
+
+	public ASTConverter(Map options, boolean resolveBindings, IProgressMonitor monitor) {
+		this.resolveBindings = resolveBindings;
+		this.referenceContext = null;
+		Object sourceModeSetting = options.get(JavaCore.COMPILER_SOURCE);
+		long sourceLevel = CompilerOptions.versionToJdkLevel(sourceModeSetting);
+		if (sourceLevel == 0) {
+			// unknown sourceModeSetting
+			sourceLevel = ClassFileConstants.JDK1_3;
+		}
+		this.scanner = new Scanner(
+			true /*comment*/,
+			false /*whitespace*/,
+			false /*nls*/,
+			sourceLevel /*sourceLevel*/,
+			null /*taskTags*/,
+			null/*taskPriorities*/,
+			true/*taskCaseSensitive*/);
+		this.monitor = monitor;
+		this.insideComments = JavaCore.ENABLED.equals(options.get(JavaCore.COMPILER_DOC_COMMENT_SUPPORT));
+	}
+
+	protected void adjustSourcePositionsForParent(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
+		int start = expression.sourceStart;
+		int end = expression.sourceEnd;
+		int leftParentCount = 1;
+		int rightParentCount = 0;
+		this.scanner.resetTo(start, end);
+		try {
+			int token = this.scanner.getNextToken();
+			expression.sourceStart = this.scanner.currentPosition;
+			boolean stop = false;
+			while (!stop && ((token  = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)) {
+				switch(token) {
+					case TerminalTokens.TokenNameLPAREN:
+						leftParentCount++;
+						break;
+					case TerminalTokens.TokenNameRPAREN:
+						rightParentCount++;
+						if (rightParentCount == leftParentCount) {
+							// we found the matching parenthesis
+							stop = true;
+						}
+				}
+			}
+			expression.sourceEnd = this.scanner.startPosition - 1;
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+
+	protected void buildBodyDeclarations(
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration,
+			AbstractTypeDeclaration typeDecl,
+			boolean isInterface) {
+		// add body declaration in the lexical order
+		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = typeDeclaration.memberTypes;
+		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = typeDeclaration.fields;
+		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+
+		int fieldsLength = fields == null? 0 : fields.length;
+		int methodsLength = methods == null? 0 : methods.length;
+		int membersLength = members == null ? 0 : members.length;
+		int fieldsIndex = 0;
+		int methodsIndex = 0;
+		int membersIndex = 0;
+
+		while ((fieldsIndex < fieldsLength)
+			|| (membersIndex < membersLength)
+			|| (methodsIndex < methodsLength)) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
+
+			int position = Integer.MAX_VALUE;
+			int nextDeclarationType = -1;
+			if (fieldsIndex < fieldsLength) {
+				nextFieldDeclaration = fields[fieldsIndex];
+				if (nextFieldDeclaration.declarationSourceStart < position) {
+					position = nextFieldDeclaration.declarationSourceStart;
+					nextDeclarationType = 0; // FIELD
+				}
+			}
+			if (methodsIndex < methodsLength) {
+				nextMethodDeclaration = methods[methodsIndex];
+				if (nextMethodDeclaration.declarationSourceStart < position) {
+					position = nextMethodDeclaration.declarationSourceStart;
+					nextDeclarationType = 1; // METHOD
+				}
+			}
+			if (membersIndex < membersLength) {
+				nextMemberDeclaration = members[membersIndex];
+				if (nextMemberDeclaration.declarationSourceStart < position) {
+					position = nextMemberDeclaration.declarationSourceStart;
+					nextDeclarationType = 2; // MEMBER
+				}
+			}
+			switch (nextDeclarationType) {
+				case 0 :
+					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						typeDecl.bodyDeclarations().add(convert(nextFieldDeclaration));
+					} else {
+						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, typeDecl.bodyDeclarations());
+					}
+					fieldsIndex++;
+					break;
+				case 1 :
+					methodsIndex++;
+					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
+						typeDecl.bodyDeclarations().add(convert(isInterface, nextMethodDeclaration));
+					}
+					break;
+				case 2 :
+					membersIndex++;
+					ASTNode node = convert(nextMemberDeclaration);
+					if (node == null) {
+						typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
+					} else {
+						typeDecl.bodyDeclarations().add(node);
+					}
+			}
+		}
+		// Convert javadoc
+		convert(typeDeclaration.javadoc, typeDecl);
+	}
+
+	protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2, EnumDeclaration enumDeclaration) {
+		// add body declaration in the lexical order
+		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = enumDeclaration2.memberTypes;
+		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = enumDeclaration2.fields;
+		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = enumDeclaration2.methods;
+
+		int fieldsLength = fields == null? 0 : fields.length;
+		int methodsLength = methods == null? 0 : methods.length;
+		int membersLength = members == null ? 0 : members.length;
+		int fieldsIndex = 0;
+		int methodsIndex = 0;
+		int membersIndex = 0;
+
+		while ((fieldsIndex < fieldsLength)
+			|| (membersIndex < membersLength)
+			|| (methodsIndex < methodsLength)) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
+
+			int position = Integer.MAX_VALUE;
+			int nextDeclarationType = -1;
+			if (fieldsIndex < fieldsLength) {
+				nextFieldDeclaration = fields[fieldsIndex];
+				if (nextFieldDeclaration.declarationSourceStart < position) {
+					position = nextFieldDeclaration.declarationSourceStart;
+					nextDeclarationType = 0; // FIELD
+				}
+			}
+			if (methodsIndex < methodsLength) {
+				nextMethodDeclaration = methods[methodsIndex];
+				if (nextMethodDeclaration.declarationSourceStart < position) {
+					position = nextMethodDeclaration.declarationSourceStart;
+					nextDeclarationType = 1; // METHOD
+				}
+			}
+			if (membersIndex < membersLength) {
+				nextMemberDeclaration = members[membersIndex];
+				if (nextMemberDeclaration.declarationSourceStart < position) {
+					position = nextMemberDeclaration.declarationSourceStart;
+					nextDeclarationType = 2; // MEMBER
+				}
+			}
+			switch (nextDeclarationType) {
+				case 0 :
+					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						enumDeclaration.enumConstants().add(convert(nextFieldDeclaration));
+					} else {
+						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, enumDeclaration.bodyDeclarations());
+					}
+					fieldsIndex++;
+					break;
+				case 1 :
+					methodsIndex++;
+					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
+						enumDeclaration.bodyDeclarations().add(convert(false, nextMethodDeclaration));
+					}
+					break;
+				case 2 :
+					membersIndex++;
+					enumDeclaration.bodyDeclarations().add(convert(nextMemberDeclaration));
+					break;
+			}
+		}
+		convert(enumDeclaration2.javadoc, enumDeclaration);
+	}
+
+	protected void buildBodyDeclarations(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration expression, AnonymousClassDeclaration anonymousClassDeclaration) {
+		// add body declaration in the lexical order
+		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] members = expression.memberTypes;
+		org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = expression.fields;
+		org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration[] methods = expression.methods;
+
+		int fieldsLength = fields == null? 0 : fields.length;
+		int methodsLength = methods == null? 0 : methods.length;
+		int membersLength = members == null ? 0 : members.length;
+		int fieldsIndex = 0;
+		int methodsIndex = 0;
+		int membersIndex = 0;
+
+		while ((fieldsIndex < fieldsLength)
+			|| (membersIndex < membersLength)
+			|| (methodsIndex < methodsLength)) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration nextFieldDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration nextMethodDeclaration = null;
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = null;
+
+			int position = Integer.MAX_VALUE;
+			int nextDeclarationType = -1;
+			if (fieldsIndex < fieldsLength) {
+				nextFieldDeclaration = fields[fieldsIndex];
+				if (nextFieldDeclaration.declarationSourceStart < position) {
+					position = nextFieldDeclaration.declarationSourceStart;
+					nextDeclarationType = 0; // FIELD
+				}
+			}
+			if (methodsIndex < methodsLength) {
+				nextMethodDeclaration = methods[methodsIndex];
+				if (nextMethodDeclaration.declarationSourceStart < position) {
+					position = nextMethodDeclaration.declarationSourceStart;
+					nextDeclarationType = 1; // METHOD
+				}
+			}
+			if (membersIndex < membersLength) {
+				nextMemberDeclaration = members[membersIndex];
+				if (nextMemberDeclaration.declarationSourceStart < position) {
+					position = nextMemberDeclaration.declarationSourceStart;
+					nextDeclarationType = 2; // MEMBER
+				}
+			}
+			switch (nextDeclarationType) {
+				case 0 :
+					if (nextFieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						anonymousClassDeclaration.bodyDeclarations().add(convert(nextFieldDeclaration));
+					} else {
+						checkAndAddMultipleFieldDeclaration(fields, fieldsIndex, anonymousClassDeclaration.bodyDeclarations());
+					}
+					fieldsIndex++;
+					break;
+				case 1 :
+					methodsIndex++;
+					if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
+						anonymousClassDeclaration.bodyDeclarations().add(convert(false, nextMethodDeclaration));
+					}
+					break;
+				case 2 :
+					membersIndex++;
+					ASTNode node = convert(nextMemberDeclaration);
+					if (node == null) {
+						anonymousClassDeclaration.setFlags(anonymousClassDeclaration.getFlags() | ASTNode.MALFORMED);
+					} else {
+						anonymousClassDeclaration.bodyDeclarations().add(node);
+					}
+			}
+		}
+	}
+	/** 
+	 * Internal access method to SingleVariableDeclaration#setExtraDimensions() for avoiding deprecated warnings
+	 *
+	 * @param node
+	 * @param dimensions
+	 * @deprecated
+	 */
+	private static void internalSetExtraDimensions(SingleVariableDeclaration node, int dimensions) {
+		node.setExtraDimensions(dimensions);
+	}
+	/** 
+	 * Internal access method to VariableDeclarationFragment#setExtraDimensions() for avoiding deprecated warnings
+	 *
+	 * @param node
+	 * @param dimensions
+	 * @deprecated
+	 */
+	private static void internalSetExtraDimensions(VariableDeclarationFragment node, int dimensions) {
+		node.setExtraDimensions(dimensions);
+	}
+	/** 
+	 * Internal access method to MethodDeclaration#setExtraDimension() for avoiding deprecated warnings
+	 *
+	 * @param node
+	 * @param dimensions
+	 * @deprecated
+	 */
+	private static void internalSetExtraDimensions(MethodDeclaration node, int dimensions) {
+		node.setExtraDimensions(dimensions);
+	}
+	/** 
+	 * Internal access method to MethodDeclaration#thrownExceptions() for avoiding deprecated warnings
+	 *
+	 * @param node
+	 * @deprecated
+	 */
+	private static List internalThownExceptions(MethodDeclaration node) {
+		return node.thrownExceptions();
+	}
+
+	/**
+	 * @param compilationUnit
+	 * @param comments
+	 */
+	void buildCommentsTable(CompilationUnit compilationUnit, int[][] comments) {
+		// Build comment table
+		this.commentsTable = new Comment[comments.length];
+		int nbr = 0;
+		for (int i = 0; i < comments.length; i++) {
+			Comment comment = createComment(comments[i]);
+			if (comment != null) {
+				comment.setAlternateRoot(compilationUnit);
+				this.commentsTable[nbr++] = comment;
+			}
+		}
+		// Resize table if  necessary
+		if (nbr<comments.length) {
+			Comment[] newCommentsTable = new Comment[nbr];
+			System.arraycopy(this.commentsTable, 0, newCommentsTable, 0, nbr);
+			this.commentsTable = newCommentsTable;
+		}
+		compilationUnit.setCommentTable(this.commentsTable);
+	}
+
+	protected void checkAndAddMultipleFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List bodyDeclarations) {
+		if (fields[index] instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
+			org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) fields[index];
+			Initializer initializer = new Initializer(this.ast);
+			initializer.setBody(convert(oldInitializer.block));
+			setModifiers(initializer, oldInitializer);
+			initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
+			// The javadoc comment is now got from list store in compilation unit declaration
+			convert(oldInitializer.javadoc, initializer);
+			bodyDeclarations.add(initializer);
+			return;
+		}
+		if (index > 0 && fields[index - 1].declarationSourceStart == fields[index].declarationSourceStart) {
+			// we have a multiple field declaration
+			// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) bodyDeclarations.get(bodyDeclarations.size() - 1);
+			fieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fields[index]));
+		} else {
+			// we can create a new FieldDeclaration
+			bodyDeclarations.add(convertToFieldDeclaration(fields[index]));
+		}
+	}
+
+	protected void checkAndAddMultipleLocalDeclaration(org.eclipse.jdt.internal.compiler.ast.Statement[] stmts, int index, List blockStatements) {
+		if (index > 0
+				&& stmts[index - 1] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local1 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index - 1];
+			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration local2 = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) stmts[index];
+			if (local1.declarationSourceStart == local2.declarationSourceStart) {
+				// we have a multiple local declarations
+				// We retrieve the existing VariableDeclarationStatement to add the new VariableDeclarationFragment
+				VariableDeclarationStatement variableDeclarationStatement = (VariableDeclarationStatement) blockStatements.get(blockStatements.size() - 1);
+				variableDeclarationStatement.fragments().add(convertToVariableDeclarationFragment((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
+			} else {
+				// we can create a new FieldDeclaration
+				blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
+			}
+		} else {
+			// we can create a new FieldDeclaration
+			blockStatements.add(convertToVariableDeclarationStatement((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)stmts[index]));
+		}
+	}
+
+	protected void checkCanceled() {
+		if (this.monitor != null && this.monitor.isCanceled())
+			throw new OperationCanceledException();
+	}
+
+	protected void completeRecord(ArrayType arrayType, org.eclipse.jdt.internal.compiler.ast.ASTNode astNode) {
+		ArrayType array = arrayType;
+		int dimensions = array.getDimensions();
+		for (int i = 0; i < dimensions; i++) {
+			Type componentType = array.getComponentType();
+			this.recordNodes(componentType, astNode);
+			if (componentType.isArrayType()) {
+				array = (ArrayType) componentType;
+			}
+		}
+	}
+
+	public ASTNode convert(boolean isInterface, org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration methodDeclaration) {
+		checkCanceled();
+		if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) methodDeclaration);
+		}
+		MethodDeclaration methodDecl = new MethodDeclaration(this.ast);
+		ASTNode oldReferenceContext = this.referenceContext;
+		this.referenceContext = methodDecl;
+		setModifiers(methodDecl, methodDeclaration);
+		boolean isConstructor = methodDeclaration.isConstructor();
+		methodDecl.setConstructor(isConstructor);
+		final SimpleName methodName = new SimpleName(this.ast);
+		methodName.internalSetIdentifier(new String(methodDeclaration.selector));
+		int start = methodDeclaration.sourceStart;
+		int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
+		methodName.setSourceRange(start, end - start + 1);
+		methodDecl.setName(methodName);
+		org.eclipse.jdt.internal.compiler.ast.TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+		int methodHeaderEnd = methodDeclaration.sourceEnd;
+		int thrownExceptionsLength = thrownExceptions == null ? 0 : thrownExceptions.length;
+		if (thrownExceptionsLength > 0) {
+			if (this.ast.apiLevel() < AST.JLS8) {
+				Name thrownException;
+				int i = 0;
+				do {
+					TypeReference typeRef = thrownExceptions[i++];
+					thrownException = convert(typeRef);
+					if (typeRef.annotations != null && typeRef.annotations.length > 0) {
+						thrownException.setFlags(thrownException.getFlags() | ASTNode.MALFORMED);
+					}
+					internalThownExceptions(methodDecl).add(thrownException);
+				} while (i < thrownExceptionsLength);
+				methodHeaderEnd = thrownException.getStartPosition() + thrownException.getLength();				
+			} else {
+				Type thrownExceptionType;
+				int i = 0;
+				do {
+					thrownExceptionType = convertType(thrownExceptions[i++]);
+					methodDecl.thrownExceptionTypes().add(thrownExceptionType);
+				} while (i < thrownExceptionsLength);
+				methodHeaderEnd = thrownExceptionType.getStartPosition() + thrownExceptionType.getLength();				
+			}
+		}
+
+		if (methodDeclaration.receiver != null) {
+			if(this.ast.apiLevel >= AST.JLS8) {
+				convertAndSetReceiver(methodDeclaration, methodDecl);
+			} else {
+				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+			}
+		}
+		org.eclipse.jdt.internal.compiler.ast.Argument[] parameters = methodDeclaration.arguments;
+		int parametersLength = parameters == null ? 0 : parameters.length;
+		if (parametersLength > 0) {
+			SingleVariableDeclaration parameter;
+			int i = 0;
+			do {
+				parameter = convert(parameters[i++]);
+				methodDecl.parameters().add(parameter);
+			} while (i < parametersLength);
+			if (thrownExceptionsLength == 0) {
+				methodHeaderEnd = parameter.getStartPosition() + parameter.getLength();
+			}
+		}
+		org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall explicitConstructorCall = null;
+		if (isConstructor) {
+			if (isInterface) {
+				// interface cannot have a constructor
+				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+			}
+			org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
+			explicitConstructorCall = constructorDeclaration.constructorCall;
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					// set the return type to VOID
+					PrimitiveType returnType = new PrimitiveType(this.ast);
+					returnType.setPrimitiveTypeCode(PrimitiveType.VOID);
+					returnType.setSourceRange(methodDeclaration.sourceStart, 0);
+					methodDecl.internalSetReturnType(returnType);
+					break;
+				default :
+					methodDecl.setReturnType2(null);
+			}
+		} else if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.MethodDeclaration method = (org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) methodDeclaration;
+			org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = method.returnType;
+			if (typeReference != null) {
+				Type returnType = convertType(typeReference);
+				// get the positions of the right parenthesis
+				int rightParenthesisPosition = retrieveEndOfRightParenthesisPosition(end, method.bodyEnd);
+				int extraDimensions = retrieveExtraDimension(rightParenthesisPosition, method.bodyEnd);
+				if (this.ast.apiLevel >= AST.JLS8) {
+					setExtraAnnotatedDimensions(rightParenthesisPosition, this.scanner.currentPosition, typeReference,
+												methodDecl.extraDimensions(), extraDimensions);
+				} else {
+					internalSetExtraDimensions(methodDecl, extraDimensions);
+				}
+				setTypeForMethodDeclaration(methodDecl, returnType, extraDimensions);
+			} else {
+				// no return type for a method that is not a constructor
+				methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						break;
+					default :
+						methodDecl.setReturnType2(null);
+				}
+			}
+		}
+		int declarationSourceStart = methodDeclaration.declarationSourceStart;
+		int bodyEnd = methodDeclaration.bodyEnd;
+		methodDecl.setSourceRange(declarationSourceStart, bodyEnd - declarationSourceStart + 1);
+		int declarationSourceEnd = methodDeclaration.declarationSourceEnd;
+		int rightBraceOrSemiColonPositionStart = bodyEnd == declarationSourceEnd ? bodyEnd : bodyEnd + 1;
+		int closingPosition = retrieveRightBraceOrSemiColonPosition(rightBraceOrSemiColonPositionStart, declarationSourceEnd);
+		if (closingPosition != -1) {
+			int startPosition = methodDecl.getStartPosition();
+			methodDecl.setSourceRange(startPosition, closingPosition - startPosition + 1);
+
+			org.eclipse.jdt.internal.compiler.ast.Statement[] statements = methodDeclaration.statements;
+
+			start = retrieveStartBlockPosition(methodHeaderEnd, methodDeclaration.bodyStart);
+			if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
+			end = retrieveRightBrace(methodDeclaration.bodyEnd, declarationSourceEnd);
+			Block block = null;
+			if (start != -1 && end != -1) {
+				/*
+				 * start or end can be equal to -1 if we have an interface's method.
+				 */
+				block = new Block(this.ast);
+				block.setSourceRange(start, closingPosition - start + 1);
+				methodDecl.setBody(block);
+			}
+			if (block != null && (statements != null || explicitConstructorCall != null)) {
+				if (explicitConstructorCall != null && explicitConstructorCall.accessMode != org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall.ImplicitSuper) {
+					block.statements().add(convert(explicitConstructorCall));
+				}
+				int statementsLength = statements == null ? 0 : statements.length;
+				for (int i = 0; i < statementsLength; i++) {
+					if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+						checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
+					} else {
+						final Statement statement = convert(statements[i]);
+						if (statement != null) {
+							block.statements().add(statement);
+						}
+					}
+				}
+			}
+			if (block != null) {
+				if ((methodDeclaration.modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccNative)) != 0
+						|| (isInterface && (this.ast.apiLevel < AST.JLS8 ||
+							(methodDeclaration.modifiers & (ClassFileConstants.AccStatic | ExtraCompilerModifiers.AccDefaultMethod)) == 0))) {
+					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+				}
+			}
+		} else {
+			// syntax error in this method declaration
+			methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+			if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract()) {
+				start = retrieveStartBlockPosition(methodHeaderEnd, bodyEnd);
+				if (start == -1) start = methodDeclaration.bodyStart; // use recovery position for body start
+				end = methodDeclaration.bodyEnd;
+				// try to get the best end position
+				CategorizedProblem[] problems = methodDeclaration.compilationResult().problems;
+				if (problems != null) {
+					for (int i = 0, max = methodDeclaration.compilationResult().problemCount; i < max; i++) {
+						CategorizedProblem currentProblem = problems[i];
+						if (currentProblem.getSourceStart() == start && currentProblem.getID() == IProblem.ParsingErrorInsertToComplete) {
+							end = currentProblem.getSourceEnd();
+							break;
+						}
+					}
+				}
+				int startPosition = methodDecl.getStartPosition();
+				methodDecl.setSourceRange(startPosition, end - startPosition + 1);
+				if (start != -1 && end != -1) {
+					/*
+					 * start or end can be equal to -1 if we have an interface's method.
+					 */
+					Block block = new Block(this.ast);
+					block.setSourceRange(start, end - start + 1);
+					methodDecl.setBody(block);
+				}
+			}
+		}
+
+		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = methodDeclaration.typeParameters();
+		if (typeParameters != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					for (int i = 0, max = typeParameters.length; i < max; i++) {
+						methodDecl.typeParameters().add(convert(typeParameters[i]));
+					}
+			}
+		}
+
+		// The javadoc comment is now got from list store in compilation unit declaration
+		convert(methodDeclaration.javadoc, methodDecl);
+		if (this.resolveBindings) {
+			recordNodes(methodDecl, methodDeclaration);
+			recordNodes(methodName, methodDeclaration);
+			methodDecl.resolveBinding();
+		}
+		this.referenceContext = oldReferenceContext;
+		return methodDecl;
+	}
+
+	public ClassInstanceCreation convert(org.eclipse.jdt.internal.compiler.ast.AllocationExpression expression) {
+		ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(classInstanceCreation, expression);
+		}
+		if (expression.typeArguments != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					for (int i = 0, max = expression.typeArguments.length; i < max; i++) {
+						classInstanceCreation.typeArguments().add(convertType(expression.typeArguments[i]));
+					}
+			}
+		}
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				classInstanceCreation.internalSetName(convert(expression.type));
+				break;
+			default :
+				classInstanceCreation.setType(convertType(expression.type));
+		}
+		classInstanceCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
+		if (arguments != null) {
+			int length = arguments.length;
+			for (int i = 0; i < length; i++) {
+				classInstanceCreation.arguments().add(convert(arguments[i]));
+			}
+		}
+		return classInstanceCreation;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression expression) {
+		InfixExpression infixExpression = new InfixExpression(this.ast);
+		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
+		if (this.resolveBindings) {
+			this.recordNodes(infixExpression, expression);
+		}
+		final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
+		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
+			// create an extended string literal equivalent => use the extended operands list
+			infixExpression.extendedOperands().add(convert(expression.right));
+			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
+			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
+			do {
+				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
+				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
+							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
+					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
+							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
+				 	List extendedOperands = infixExpression.extendedOperands();
+				 	InfixExpression temp = new InfixExpression(this.ast);
+					if (this.resolveBindings) {
+						this.recordNodes(temp, expression);
+					}
+				 	temp.setOperator(getOperatorFor(expressionOperatorID));
+				 	Expression leftSide = convert(leftOperand);
+					temp.setLeftOperand(leftSide);
+					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
+					int size = extendedOperands.size();
+				 	for (int i = 0; i < size - 1; i++) {
+				 		Expression expr = temp;
+				 		temp = new InfixExpression(this.ast);
+
+						if (this.resolveBindings) {
+							this.recordNodes(temp, expression);
+						}
+				 		temp.setLeftOperand(expr);
+					 	temp.setOperator(getOperatorFor(expressionOperatorID));
+						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
+				 	}
+				 	infixExpression = temp;
+				 	for (int i = 0; i < size; i++) {
+				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
+				 		temp.setRightOperand(extendedOperand);
+				 		int startPosition = temp.getLeftOperand().getStartPosition();
+				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
+				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
+				 			temp = (InfixExpression) temp.getLeftOperand();
+				 		}
+				 	}
+					int startPosition = infixExpression.getLeftOperand().getStartPosition();
+					infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+					if (this.resolveBindings) {
+						this.recordNodes(infixExpression, expression);
+					}
+					return infixExpression;
+				}
+				infixExpression.extendedOperands().add(0, convert(rightOperand));
+				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
+			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
+			Expression leftExpression = convert(leftOperand);
+			infixExpression.setLeftOperand(leftExpression);
+			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
+			int startPosition = leftExpression.getStartPosition();
+			infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+			return infixExpression;
+		}
+		Expression leftExpression = convert(expression.left);
+		infixExpression.setLeftOperand(leftExpression);
+		infixExpression.setRightOperand(convert(expression.right));
+		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND);
+		int startPosition = leftExpression.getStartPosition();
+		infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+		return infixExpression;
+	}
+
+	private AnnotationTypeDeclaration convertToAnnotationDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+		checkCanceled();
+		if (this.scanner.sourceLevel < ClassFileConstants.JDK1_5) return null;
+		AnnotationTypeDeclaration typeDecl = this.ast.newAnnotationTypeDeclaration();
+		setModifiers(typeDecl, typeDeclaration);
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
+		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
+		typeDecl.setName(typeName);
+		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
+
+		buildBodyDeclarations(typeDeclaration, typeDecl, false);
+		// The javadoc comment is now got from list store in compilation unit declaration
+		if (this.resolveBindings) {
+			recordNodes(typeDecl, typeDeclaration);
+			recordNodes(typeName, typeDeclaration);
+			typeDecl.resolveBinding();
+		}
+		return typeDecl;
+	}
+
+	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
+		checkCanceled();
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			return null;
+		}
+		AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = new AnnotationTypeMemberDeclaration(this.ast);
+		setModifiers(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
+		final SimpleName methodName = new SimpleName(this.ast);
+		methodName.internalSetIdentifier(new String(annotationTypeMemberDeclaration.selector));
+		int start = annotationTypeMemberDeclaration.sourceStart;
+		int end = retrieveIdentifierEndPosition(start, annotationTypeMemberDeclaration.sourceEnd);
+		methodName.setSourceRange(start, end - start + 1);
+		annotationTypeMemberDeclaration2.setName(methodName);
+		org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference = annotationTypeMemberDeclaration.returnType;
+		if (typeReference != null) {
+			Type returnType = convertType(typeReference);
+			setTypeForMethodDeclaration(annotationTypeMemberDeclaration2, returnType, 0);
+		}
+		int declarationSourceStart = annotationTypeMemberDeclaration.declarationSourceStart;
+		int declarationSourceEnd = annotationTypeMemberDeclaration.bodyEnd;
+		annotationTypeMemberDeclaration2.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
+		// The javadoc comment is now got from list store in compilation unit declaration
+		convert(annotationTypeMemberDeclaration.javadoc, annotationTypeMemberDeclaration2);
+		org.eclipse.jdt.internal.compiler.ast.Expression memberValue = annotationTypeMemberDeclaration.defaultValue;
+		if (memberValue != null) {
+			annotationTypeMemberDeclaration2.setDefault(convert(memberValue));
+		}
+		if (this.resolveBindings) {
+			recordNodes(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
+			recordNodes(methodName, annotationTypeMemberDeclaration);
+			annotationTypeMemberDeclaration2.resolveBinding();
+		}
+		return annotationTypeMemberDeclaration2;
+	}
+
+	private void convertAndSetReceiver(AbstractMethodDeclaration method, MethodDeclaration methodDecl) {
+		Receiver receiver = method.receiver;
+		if (receiver.qualifyingName != null) {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(receiver.qualifyingName.getName()[0]));
+			int start = receiver.qualifyingName.sourceStart;
+			int nameEnd = receiver.qualifyingName.sourceEnd;
+			name.setSourceRange(start, nameEnd - start + 1);
+			methodDecl.setReceiverQualifier(name);
+			if (this.resolveBindings) {
+				recordNodes(name, receiver);
+			}
+		}
+		AnnotatableType type = (AnnotatableType) convertType(receiver.type);
+		methodDecl.setReceiverType(type);
+		if (receiver.modifiers != 0) {
+			methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+		}
+		if (this.resolveBindings) {
+			recordNodes(type, receiver);
+			type.resolveBinding();
+		}
+	}
+
+	public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) {
+		SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
+		setModifiers(variableDecl, argument);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(argument.name));
+		int start = argument.sourceStart;
+		int nameEnd = argument.sourceEnd;
+		name.setSourceRange(start, nameEnd - start + 1);
+		variableDecl.setName(name);
+		final int typeSourceEnd = argument.type.sourceEnd;
+		final int extraDimensions = retrieveExtraDimension(nameEnd + 1, typeSourceEnd);
+		if (this.ast.apiLevel >= AST.JLS8) {
+			setExtraAnnotatedDimensions(nameEnd + 1, this.scanner.currentPosition, argument.type,
+										variableDecl.extraDimensions(), extraDimensions);
+		} else {
+			internalSetExtraDimensions(variableDecl, extraDimensions);
+		}
+		final boolean isVarArgs = argument.isVarArgs();
+		if (isVarArgs && extraDimensions == 0) {
+			// remove the ellipsis from the type source end
+			argument.type.sourceEnd = retrieveEllipsisStartPosition(argument.type.sourceStart, typeSourceEnd);
+		}
+		Type type = convertType(argument.type);
+		int typeEnd = type.getStartPosition() + type.getLength() - 1;
+		int rightEnd = Math.max(typeEnd, argument.declarationSourceEnd);
+		/*
+		 * There is extra work to do to set the proper type positions
+		 * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
+		 */
+		if (isVarArgs) {
+			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=391898
+			if (type.isAnnotatable()) {
+				AnnotatableType annotatableType = (AnnotatableType) type;
+				if (this.ast.apiLevel() >= AST.JLS8 && !annotatableType.annotations().isEmpty()) {
+					Iterator annotations = annotatableType.annotations().iterator();
+					while (annotations.hasNext()) {
+						Annotation annotation = (Annotation) annotations.next();
+						annotation.setParent(null, null);
+						variableDecl.varargsAnnotations().add(annotation);
+					}
+				}
+			}
+			if (extraDimensions != 0) {
+				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
+			}
+		} else {
+			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
+		}
+		variableDecl.setSourceRange(argument.declarationSourceStart, rightEnd - argument.declarationSourceStart + 1);
+
+		if (isVarArgs) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					variableDecl.setVarargs(true);
+			}
+		}
+		if (this.resolveBindings) {
+			recordNodes(name, argument);
+			recordNodes(variableDecl, argument);
+			variableDecl.resolveBinding();
+		}
+		return variableDecl;
+	}
+
+
+	public Annotation convert(org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
+		if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) annotation);
+		} else if (annotation instanceof org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) annotation);
+		} else {
+			return convert((org.eclipse.jdt.internal.compiler.ast.NormalAnnotation) annotation);
+		}
+	}
+
+	public ArrayCreation convert(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression expression) {
+		ArrayCreation arrayCreation = new ArrayCreation(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(arrayCreation, expression);
+		}
+		arrayCreation.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		org.eclipse.jdt.internal.compiler.ast.Expression[] dimensions = expression.dimensions;
+
+		int dimensionsLength = dimensions.length;
+		for (int i = 0; i < dimensionsLength; i++) {
+			if (dimensions[i] != null) {
+				Expression dimension = convert(dimensions[i]);
+				if (this.resolveBindings) {
+					recordNodes(dimension, dimensions[i]);
+				}
+				arrayCreation.dimensions().add(dimension);
+			}
+		}
+		Type type = convertType(expression.type);
+		if (this.resolveBindings) {
+			recordNodes(type, expression.type);
+		}
+		ArrayType arrayType = null;
+		if (type.isArrayType()) {
+			arrayType = (ArrayType) type;
+		} else {
+			arrayType = this.ast.newArrayType(type, dimensionsLength);
+			if (this.resolveBindings) {
+				completeRecord(arrayType, expression);
+			}
+			int start = type.getStartPosition();
+			int end = type.getStartPosition() + type.getLength();
+			int previousSearchStart = end - 1;
+			ArrayType componentType = (ArrayType) type.getParent();
+			for (int i = 0; i < dimensionsLength; i++) {
+				previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSourceLength);
+				componentType.setSourceRange(start, previousSearchStart - start + 1);
+				componentType = (ArrayType) componentType.getParent();
+			}
+		}
+		if (expression.annotationsOnDimensions != null) {
+			annotateType(arrayType, expression.annotationsOnDimensions);
+		}
+		arrayCreation.setType(arrayType);
+		if (this.resolveBindings) {
+			recordNodes(arrayType, expression);
+		}
+		if (expression.initializer != null) {
+			arrayCreation.setInitializer(convert(expression.initializer));
+		}
+		return arrayCreation;
+	}
+
+	public ArrayInitializer convert(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer expression) {
+		ArrayInitializer arrayInitializer = new ArrayInitializer(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(arrayInitializer, expression);
+		}
+		arrayInitializer.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = expression.expressions;
+		if (expressions != null) {
+			int length = expressions.length;
+			for (int i = 0; i < length; i++) {
+				Expression expr = convert(expressions[i]);
+				if (this.resolveBindings) {
+					recordNodes(expr, expressions[i]);
+				}
+				arrayInitializer.expressions().add(expr);
+			}
+		}
+		return arrayInitializer;
+	}
+
+	public ArrayAccess convert(org.eclipse.jdt.internal.compiler.ast.ArrayReference reference) {
+		ArrayAccess arrayAccess = new ArrayAccess(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(arrayAccess, reference);
+		}
+		arrayAccess.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
+		arrayAccess.setArray(convert(reference.receiver));
+		arrayAccess.setIndex(convert(reference.position));
+		return arrayAccess;
+	}
+
+	public AssertStatement convert(org.eclipse.jdt.internal.compiler.ast.AssertStatement statement) {
+		AssertStatement assertStatement = new AssertStatement(this.ast);
+		final Expression assertExpression = convert(statement.assertExpression);
+		Expression searchingNode = assertExpression;
+		assertStatement.setExpression(assertExpression);
+		org.eclipse.jdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
+		if (exceptionArgument != null) {
+			final Expression exceptionMessage = convert(exceptionArgument);
+			assertStatement.setMessage(exceptionMessage);
+			searchingNode = exceptionMessage;
+		}
+		int start = statement.sourceStart;
+		int sourceEnd = retrieveSemiColonPosition(searchingNode);
+		if (sourceEnd == -1) {
+			sourceEnd = searchingNode.getStartPosition() + searchingNode.getLength() - 1;
+			assertStatement.setSourceRange(start, sourceEnd - start + 1);
+		} else {
+			assertStatement.setSourceRange(start, sourceEnd - start + 1);
+		}
+		return assertStatement;
+	}
+
+	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.Assignment expression) {
+		Assignment assignment = new Assignment(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(assignment, expression);
+		}
+		Expression lhs = convert(expression.lhs);
+		assignment.setLeftHandSide(lhs);
+		assignment.setOperator(Assignment.Operator.ASSIGN);
+		Expression rightHandSide = convert(expression.expression);
+		assignment.setRightHandSide(rightHandSide);
+		int start = lhs.getStartPosition();
+		int end = rightHandSide.getStartPosition() + rightHandSide.getLength() - 1;
+		assignment.setSourceRange(start, end - start + 1);
+		return assignment;
+	}
+
+	/*
+	 * Internal use only
+	 * Used to convert class body declarations
+	 */
+	public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes) {
+		final TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
+		ASTNode oldReferenceContext = this.referenceContext;
+		this.referenceContext = typeDecl;
+		typeDecl.setInterface(false);
+		int nodesLength = nodes.length;
+		for (int i = 0; i < nodesLength; i++) {
+			org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodes[i];
+			if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
+				org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) node;
+				Initializer initializer = new Initializer(this.ast);
+				initializer.setBody(convert(oldInitializer.block));
+				setModifiers(initializer, oldInitializer);
+				initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
+//				setJavaDocComment(initializer);
+//				initializer.setJavadoc(convert(oldInitializer.javadoc));
+				convert(oldInitializer.javadoc, initializer);
+				typeDecl.bodyDeclarations().add(initializer);
+			} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+				if (i > 0
+					&& (nodes[i - 1] instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)
+					&& ((org.eclipse.jdt.internal.compiler.ast.FieldDeclaration)nodes[i - 1]).declarationSourceStart == fieldDeclaration.declarationSourceStart) {
+					// we have a multiple field declaration
+					// We retrieve the existing fieldDeclaration to add the new VariableDeclarationFragment
+					FieldDeclaration currentFieldDeclaration = (FieldDeclaration) typeDecl.bodyDeclarations().get(typeDecl.bodyDeclarations().size() - 1);
+					currentFieldDeclaration.fragments().add(convertToVariableDeclarationFragment(fieldDeclaration));
+				} else {
+					// we can create a new FieldDeclaration
+					typeDecl.bodyDeclarations().add(convertToFieldDeclaration(fieldDeclaration));
+				}
+			} else if(node instanceof org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) {
+				AbstractMethodDeclaration nextMethodDeclaration = (AbstractMethodDeclaration) node;
+				if (!nextMethodDeclaration.isDefaultConstructor() && !nextMethodDeclaration.isClinit()) {
+					typeDecl.bodyDeclarations().add(convert(false, nextMethodDeclaration));
+				}
+			} else if(node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration nextMemberDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+				ASTNode nextMemberDeclarationNode = convert(nextMemberDeclaration);
+				if (nextMemberDeclarationNode == null) {
+					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
+				} else {
+					typeDecl.bodyDeclarations().add(nextMemberDeclarationNode);
+				}
+			}
+		}
+		this.referenceContext = oldReferenceContext;
+		return typeDecl;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.BinaryExpression expression) {
+		InfixExpression infixExpression = new InfixExpression(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(infixExpression, expression);
+		}
+
+		int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
+		infixExpression.setOperator(getOperatorFor(expressionOperatorID));
+
+		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
+			// create an extended string literal equivalent => use the extended operands list
+			infixExpression.extendedOperands().add(convert(expression.right));
+			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
+			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
+			do {
+				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
+				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
+							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
+					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
+							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
+				 	List extendedOperands = infixExpression.extendedOperands();
+				 	InfixExpression temp = new InfixExpression(this.ast);
+					if (this.resolveBindings) {
+						this.recordNodes(temp, expression);
+					}
+				 	temp.setOperator(getOperatorFor(expressionOperatorID));
+				 	Expression leftSide = convert(leftOperand);
+					temp.setLeftOperand(leftSide);
+					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
+					int size = extendedOperands.size();
+				 	for (int i = 0; i < size - 1; i++) {
+				 		Expression expr = temp;
+				 		temp = new InfixExpression(this.ast);
+
+						if (this.resolveBindings) {
+							this.recordNodes(temp, expression);
+						}
+				 		temp.setLeftOperand(expr);
+					 	temp.setOperator(getOperatorFor(expressionOperatorID));
+						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
+				 	}
+				 	infixExpression = temp;
+				 	for (int i = 0; i < size; i++) {
+				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
+				 		temp.setRightOperand(extendedOperand);
+				 		int startPosition = temp.getLeftOperand().getStartPosition();
+				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
+				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
+				 			temp = (InfixExpression) temp.getLeftOperand();
+				 		}
+				 	}
+					int startPosition = infixExpression.getLeftOperand().getStartPosition();
+					infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+					if (this.resolveBindings) {
+						this.recordNodes(infixExpression, expression);
+					}
+					return infixExpression;
+				}
+				infixExpression.extendedOperands().add(0, convert(rightOperand));
+				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
+			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
+			Expression leftExpression = convert(leftOperand);
+			infixExpression.setLeftOperand(leftExpression);
+			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
+			int startPosition = leftExpression.getStartPosition();
+			infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+			return infixExpression;
+		} else if (expression.left instanceof StringLiteralConcatenation
+				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)
+				&& (OperatorIds.PLUS == expressionOperatorID)) {
+			StringLiteralConcatenation literal = (StringLiteralConcatenation) expression.left;
+			final org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = literal.literals;
+			infixExpression.setLeftOperand(convert(stringLiterals[0]));
+			infixExpression.setRightOperand(convert(stringLiterals[1]));
+			for (int i = 2; i < literal.counter; i++) {
+				infixExpression.extendedOperands().add(convert(stringLiterals[i]));
+			}
+			infixExpression.extendedOperands().add(convert(expression.right));
+			int startPosition = literal.sourceStart;
+			infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+			return infixExpression;
+		}
+		Expression leftExpression = convert(expression.left);
+		infixExpression.setLeftOperand(leftExpression);
+		infixExpression.setRightOperand(convert(expression.right));
+		int startPosition = leftExpression.getStartPosition();
+		infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+		return infixExpression;
+	}
+
+	public Block convert(org.eclipse.jdt.internal.compiler.ast.Block statement) {
+		Block block = new Block(this.ast);
+		if (statement.sourceEnd > 0) {
+			block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		}
+		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++) {
+				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+					checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
+				} else {
+					Statement statement2 = convert(statements[i]);
+					if (statement2 != null) {
+						block.statements().add(statement2);
+					}
+				}
+			}
+		}
+		return block;
+	}
+
+	public BreakStatement convert(org.eclipse.jdt.internal.compiler.ast.BreakStatement statement)  {
+		BreakStatement breakStatement = new BreakStatement(this.ast);
+		breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		if (statement.label != null) {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(statement.label));
+			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
+			breakStatement.setLabel(name);
+		}
+		return breakStatement;
+	}
+
+
+	public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
+		SwitchCase switchCase = new SwitchCase(this.ast);
+		org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
+		if (constantExpression == null) {
+			switchCase.setExpression(null);
+		} else {
+			switchCase.setExpression(convert(constantExpression));
+		}
+		switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		retrieveColonPosition(switchCase);
+		return switchCase;
+	}
+
+	public CastExpression convert(org.eclipse.jdt.internal.compiler.ast.CastExpression expression) {
+		CastExpression castExpression = new CastExpression(this.ast);
+		castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		TypeReference type = expression.type;
+		trimWhiteSpacesAndComments(type);
+		castExpression.setType(convertType(type));
+		castExpression.setExpression(convert(expression.expression));
+		if (this.resolveBindings) {
+			recordNodes(castExpression, expression);
+		}
+		return castExpression;
+	}
+
+	public CharacterLiteral convert(org.eclipse.jdt.internal.compiler.ast.CharLiteral expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		CharacterLiteral literal = new CharacterLiteral(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess expression) {
+		TypeLiteral typeLiteral = new TypeLiteral(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(typeLiteral, expression);
+		}
+		typeLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		typeLiteral.setType(convertType(expression.type));
+		return typeLiteral;
+	}
+
+	public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
+		try {
+			if(unit.compilationResult.recoveryScannerData != null) {
+				RecoveryScanner recoveryScanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused());
+				this.scanner = recoveryScanner;
+				this.docParser.scanner = this.scanner;
+			}
+			this.compilationUnitSource = source;
+			this.compilationUnitSourceLength = source.length;
+			this.scanner.setSource(source, unit.compilationResult);
+			CompilationUnit compilationUnit = new CompilationUnit(this.ast);
+			compilationUnit.setStatementsRecoveryData(unit.compilationResult.recoveryScannerData);
+	
+			// Parse comments
+			int[][] comments = unit.comments;
+			if (comments != null) {
+				buildCommentsTable(compilationUnit, comments);
+			}
+	
+			// handle the package declaration immediately
+			// There is no node corresponding to the package declaration
+			if (this.resolveBindings) {
+				recordNodes(compilationUnit, unit);
+			}
+			if (unit.currentPackage != null) {
+				PackageDeclaration packageDeclaration = convertPackage(unit);
+				compilationUnit.setPackage(packageDeclaration);
+			}
+			org.eclipse.jdt.internal.compiler.ast.ImportReference[] imports = unit.imports;
+			if (imports != null) {
+				int importLength = imports.length;
+				for (int i = 0; i < importLength; i++) {
+					compilationUnit.imports().add(convertImport(imports[i]));
+				}
+			}
+	
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
+			if (types != null) {
+				int typesLength = types.length;
+				for (int i = 0; i < typesLength; i++) {
+					org.eclipse.jdt.internal.compiler.ast.TypeDeclaration declaration = types[i];
+					if (CharOperation.equals(declaration.name, TypeConstants.PACKAGE_INFO_NAME)) {
+						continue;
+					}
+					ASTNode type = convert(declaration);
+					if (type == null) {
+						compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
+					} else {
+						compilationUnit.types().add(type);
+					}
+				}
+			}
+			compilationUnit.setSourceRange(unit.sourceStart, unit.sourceEnd - unit.sourceStart  + 1);
+	
+			int problemLength = unit.compilationResult.problemCount;
+			if (problemLength != 0) {
+				CategorizedProblem[] resizedProblems = null;
+				final CategorizedProblem[] problems = unit.compilationResult.getProblems();
+				final int realProblemLength=problems.length;
+				if (realProblemLength == problemLength) {
+					resizedProblems = problems;
+				} else {
+					System.arraycopy(problems, 0, (resizedProblems = new CategorizedProblem[realProblemLength]), 0, realProblemLength);
+				}
+				ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
+				compilationUnit.accept(syntaxErrorPropagator);
+				ASTRecoveryPropagator recoveryPropagator =
+					new ASTRecoveryPropagator(resizedProblems, unit.compilationResult.recoveryScannerData);
+				compilationUnit.accept(recoveryPropagator);
+				compilationUnit.setProblems(resizedProblems);
+			}
+			if (this.resolveBindings) {
+				lookupForScopes();
+			}
+			compilationUnit.initCommentMapper(this.scanner);
+			if (SourceRangeVerifier.DEBUG) {
+				String bugs = new SourceRangeVerifier().process(compilationUnit);
+				if (bugs != null) {
+					StringBuffer message = new StringBuffer("Bad AST node structure:");  //$NON-NLS-1$
+					String lineDelimiter = Util.findLineSeparator(source);
+					if (lineDelimiter == null) lineDelimiter = System.getProperty("line.separator");//$NON-NLS-1$
+					message.append(lineDelimiter);
+					message.append(bugs.replaceAll("\n", lineDelimiter)); //$NON-NLS-1$
+					message.append(lineDelimiter);
+					message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
+					message.append(lineDelimiter);
+					message.append(source);
+					message.append(lineDelimiter);
+					message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
+					Util.log(new IllegalStateException("Bad AST node structure"), message.toString()); //$NON-NLS-1$
+					if (SourceRangeVerifier.DEBUG_THROW) {
+						throw new IllegalStateException(message.toString());
+					}
+				}
+			}
+			return compilationUnit;
+		} catch(IllegalArgumentException e) {
+			StringBuffer message = new StringBuffer("Exception occurred during compilation unit conversion:");  //$NON-NLS-1$
+			String lineDelimiter = Util.findLineSeparator(source);
+			if (lineDelimiter == null) lineDelimiter = System.getProperty("line.separator");//$NON-NLS-1$
+			message.append(lineDelimiter);
+			message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
+			message.append(lineDelimiter);
+			message.append(source);
+			message.append(lineDelimiter);
+			message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
+			Util.log(e, message.toString());
+			throw e;
+		}
+	}
+
+	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment expression) {
+		Assignment assignment = new Assignment(this.ast);
+		Expression lhs = convert(expression.lhs);
+		assignment.setLeftHandSide(lhs);
+		int start = lhs.getStartPosition();
+		assignment.setSourceRange(start, expression.sourceEnd - start + 1);
+		switch (expression.operator) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
+				assignment.setOperator(Assignment.Operator.PLUS_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
+				assignment.setOperator(Assignment.Operator.MINUS_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
+				assignment.setOperator(Assignment.Operator.TIMES_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
+				assignment.setOperator(Assignment.Operator.DIVIDE_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
+				assignment.setOperator(Assignment.Operator.BIT_AND_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
+				assignment.setOperator(Assignment.Operator.BIT_OR_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
+				assignment.setOperator(Assignment.Operator.BIT_XOR_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
+				assignment.setOperator(Assignment.Operator.REMAINDER_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
+				assignment.setOperator(Assignment.Operator.LEFT_SHIFT_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
+				assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
+				assignment.setOperator(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN);
+				break;
+		}
+		assignment.setRightHandSide(convert(expression.expression));
+		if (this.resolveBindings) {
+			recordNodes(assignment, expression);
+		}
+		return assignment;
+	}
+
+	public ConditionalExpression convert(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression expression) {
+		ConditionalExpression conditionalExpression = new ConditionalExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(conditionalExpression, expression);
+		}
+		conditionalExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		conditionalExpression.setExpression(convert(expression.condition));
+		conditionalExpression.setThenExpression(convert(expression.valueIfTrue));
+		conditionalExpression.setElseExpression(convert(expression.valueIfFalse));
+		return conditionalExpression;
+	}
+
+	public ContinueStatement convert(org.eclipse.jdt.internal.compiler.ast.ContinueStatement statement)  {
+		ContinueStatement continueStatement = new ContinueStatement(this.ast);
+		continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		if (statement.label != null) {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(statement.label));
+			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
+			continueStatement.setLabel(name);
+		}
+		return continueStatement;
+	}
+
+	public DoStatement convert(org.eclipse.jdt.internal.compiler.ast.DoStatement statement) {
+		DoStatement doStatement = new DoStatement(this.ast);
+		doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		doStatement.setExpression(convert(statement.condition));
+		final Statement action = convert(statement.action);
+		if (action == null) return null;
+		doStatement.setBody(action);
+		return doStatement;
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public EmptyStatement convert(org.eclipse.jdt.internal.compiler.ast.EmptyStatement statement) {
+		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
+		emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		return emptyStatement;
+	}
+
+	// field is an enum constant
+	public EnumConstantDeclaration convert(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration enumConstant) {
+		checkCanceled();
+		EnumConstantDeclaration enumConstantDeclaration = new EnumConstantDeclaration(this.ast);
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(enumConstant.name));
+		typeName.setSourceRange(enumConstant.sourceStart, enumConstant.sourceEnd - enumConstant.sourceStart + 1);
+		enumConstantDeclaration.setName(typeName);
+		int declarationSourceStart = enumConstant.declarationSourceStart;
+		int declarationSourceEnd = enumConstant.declarationSourceEnd;
+		final org.eclipse.jdt.internal.compiler.ast.Expression initialization = enumConstant.initialization;
+		if (initialization != null) {
+			if (initialization instanceof QualifiedAllocationExpression) {
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousType = ((QualifiedAllocationExpression) initialization).anonymousType;
+				if (anonymousType != null) {
+					AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
+					int start = retrieveStartBlockPosition(anonymousType.sourceEnd, anonymousType.bodyEnd);
+					int end = retrieveRightBrace(anonymousType.bodyEnd, declarationSourceEnd);
+					if (end == -1) end = anonymousType.bodyEnd;
+					anonymousClassDeclaration.setSourceRange(start, end - start + 1);
+					enumConstantDeclaration.setAnonymousClassDeclaration(anonymousClassDeclaration);
+					buildBodyDeclarations(anonymousType, anonymousClassDeclaration);
+					if (this.resolveBindings) {
+						recordNodes(anonymousClassDeclaration, anonymousType);
+						anonymousClassDeclaration.resolveBinding();
+					}
+					enumConstantDeclaration.setSourceRange(declarationSourceStart, end - declarationSourceStart + 1);
+				}
+			} else {
+				enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
+			}
+			final org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = ((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) initialization).arguments;
+			if (arguments != null) {
+				for (int i = 0, max = arguments.length; i < max; i++) {
+					enumConstantDeclaration.arguments().add(convert(arguments[i]));
+				}
+			}
+		} else {
+			enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
+		}
+		setModifiers(enumConstantDeclaration, enumConstant);
+		if (this.resolveBindings) {
+			recordNodes(enumConstantDeclaration, enumConstant);
+			recordNodes(typeName, enumConstant);
+			enumConstantDeclaration.resolveVariable();
+		}
+		convert(enumConstant.javadoc, enumConstantDeclaration);
+		return enumConstantDeclaration;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.EqualExpression expression) {
+		InfixExpression infixExpression = new InfixExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(infixExpression, expression);
+		}
+		Expression leftExpression = convert(expression.left);
+		infixExpression.setLeftOperand(leftExpression);
+		infixExpression.setRightOperand(convert(expression.right));
+		int startPosition = leftExpression.getStartPosition();
+		infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+		switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
+				infixExpression.setOperator(InfixExpression.Operator.EQUALS);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
+				infixExpression.setOperator(InfixExpression.Operator.NOT_EQUALS);
+		}
+		return infixExpression;
+
+	}
+
+	public Statement convert(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall statement) {
+		Statement newStatement;
+		int sourceStart = statement.sourceStart;
+		if (statement.isSuperAccess() || statement.isSuper()) {
+			SuperConstructorInvocation superConstructorInvocation = new SuperConstructorInvocation(this.ast);
+			if (statement.qualification != null) {
+				superConstructorInvocation.setExpression(convert(statement.qualification));
+			}
+			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
+			if (arguments != null) {
+				int length = arguments.length;
+				for (int i = 0; i < length; i++) {
+					superConstructorInvocation.arguments().add(convert(arguments[i]));
+				}
+			}
+			if (statement.typeArguments != null) {
+				if (sourceStart > statement.typeArgumentsSourceStart) {
+					sourceStart = statement.typeArgumentsSourceStart;
+				}
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						superConstructorInvocation.setFlags(superConstructorInvocation.getFlags() | ASTNode.MALFORMED);
+						break;
+					default :
+						for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
+							superConstructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
+						}
+						break;
+				}
+			}
+			newStatement = superConstructorInvocation;
+		} else {
+			ConstructorInvocation constructorInvocation = new ConstructorInvocation(this.ast);
+			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
+			if (arguments != null) {
+				int length = arguments.length;
+				for (int i = 0; i < length; i++) {
+					constructorInvocation.arguments().add(convert(arguments[i]));
+				}
+			}
+			if (statement.typeArguments != null) {
+				if (sourceStart > statement.typeArgumentsSourceStart) {
+					sourceStart = statement.typeArgumentsSourceStart;
+				}
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
+						break;
+					default :
+						for (int i = 0, max = statement.typeArguments.length; i < max; i++) {
+							constructorInvocation.typeArguments().add(convertType(statement.typeArguments[i]));
+						}
+					break;
+				}
+			}
+			if (statement.qualification != null) {
+				// this is an error
+				constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
+			}
+			newStatement = constructorInvocation;
+		}
+		newStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
+		if (this.resolveBindings) {
+			recordNodes(newStatement, statement);
+		}
+		return newStatement;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
+		if ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
+			return convertToParenthesizedExpression(expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.Annotation) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CastExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.CastExpression) expression);
+		}
+		// switch between all types of expression
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AllocationExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.AllocationExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PrefixExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.PrefixExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.PostfixExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.PostfixExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.CompoundAssignment) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Assignment) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.Assignment) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FalseLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.FalseLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TrueLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.TrueLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.NullLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.NullLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.CharLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.CharLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.DoubleLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.FloatLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.FloatLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.IntLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.IntLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LongLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.LongLiteral) expression);
+		}
+		if (expression instanceof StringLiteralConcatenation) {
+			return convert((StringLiteralConcatenation) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.StringLiteral) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.StringLiteral) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.EqualExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.EqualExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.UnaryExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.UnaryExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.MessageSend) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.MessageSend) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Reference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.Reference) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.TypeReference) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.LambdaExpression) expression);
+		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) expression);
+		}
+		return null;
+	}
+
+	public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral expression) {
+		expression.computeConstant();
+		StringLiteral literal = new StringLiteral(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setLiteralValue(expression.constant.stringValue());
+		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return literal;
+	}
+
+	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.FalseLiteral expression) {
+		final BooleanLiteral literal =  new BooleanLiteral(this.ast);
+		literal.setBooleanValue(false);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return literal;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.FieldReference reference) {
+		if (reference.receiver.isSuper()) {
+			final SuperFieldAccess superFieldAccess = new SuperFieldAccess(this.ast);
+			if (this.resolveBindings) {
+				recordNodes(superFieldAccess, reference);
+			}
+			if (reference.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
+				Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference.receiver);
+				superFieldAccess.setQualifier(qualifier);
+				if (this.resolveBindings) {
+					recordNodes(qualifier, reference.receiver);
+				}
+			}
+			final SimpleName simpleName = new SimpleName(this.ast);
+			simpleName.internalSetIdentifier(new String(reference.token));
+			int sourceStart = (int)(reference.nameSourcePosition>>>32);
+			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
+			simpleName.setSourceRange(sourceStart, length);
+			superFieldAccess.setName(simpleName);
+			if (this.resolveBindings) {
+				recordNodes(simpleName, reference);
+			}
+			superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
+			return superFieldAccess;
+		} else {
+			final FieldAccess fieldAccess = new FieldAccess(this.ast);
+			if (this.resolveBindings) {
+				recordNodes(fieldAccess, reference);
+			}
+			Expression receiver = convert(reference.receiver);
+			fieldAccess.setExpression(receiver);
+			final SimpleName simpleName = new SimpleName(this.ast);
+			simpleName.internalSetIdentifier(new String(reference.token));
+			int sourceStart = (int)(reference.nameSourcePosition>>>32);
+			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
+			simpleName.setSourceRange(sourceStart, length);
+			fieldAccess.setName(simpleName);
+			if (this.resolveBindings) {
+				recordNodes(simpleName, reference);
+			}
+			fieldAccess.setSourceRange(receiver.getStartPosition(), reference.sourceEnd - receiver.getStartPosition() + 1);
+			return fieldAccess;
+		}
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.FloatLiteral expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public Statement convert(ForeachStatement statement) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				return createFakeEmptyStatement(statement);
+			default :
+				EnhancedForStatement enhancedForStatement = new EnhancedForStatement(this.ast);
+				enhancedForStatement.setParameter(convertToSingleVariableDeclaration(statement.elementVariable));
+				org.eclipse.jdt.internal.compiler.ast.Expression collection = statement.collection;
+				if (collection == null) return null;
+				enhancedForStatement.setExpression(convert(collection));
+				final Statement action = convert(statement.action);
+				if (action == null) return null;
+				enhancedForStatement.setBody(action);
+				int start = statement.sourceStart;
+				int end = statement.sourceEnd;
+				enhancedForStatement.setSourceRange(start, end - start + 1);
+				return enhancedForStatement;
+		}
+	}
+
+	public ForStatement convert(org.eclipse.jdt.internal.compiler.ast.ForStatement statement) {
+		ForStatement forStatement = new ForStatement(this.ast);
+		forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		org.eclipse.jdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
+		if (initializations != null) {
+			// we know that we have at least one initialization
+			if (initializations[0] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.LocalDeclaration initialization = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[0];
+				VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(initialization);
+				int initializationsLength = initializations.length;
+				for (int i = 1; i < initializationsLength; i++) {
+					initialization = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)initializations[i];
+					variableDeclarationExpression.fragments().add(convertToVariableDeclarationFragment(initialization));
+				}
+				if (initializationsLength != 1) {
+					int start = variableDeclarationExpression.getStartPosition();
+					int end = ((org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) initializations[initializationsLength - 1]).declarationSourceEnd;
+					variableDeclarationExpression.setSourceRange(start, end - start + 1);
+				}
+				forStatement.initializers().add(variableDeclarationExpression);
+			} else {
+				int initializationsLength = initializations.length;
+				for (int i = 0; i < initializationsLength; i++) {
+					Expression initializer = convertToExpression(initializations[i]);
+					if (initializer != null) {
+						forStatement.initializers().add(initializer);
+					} else {
+						forStatement.setFlags(forStatement.getFlags() | ASTNode.MALFORMED);
+					}
+				}
+			}
+		}
+		if (statement.condition != null) {
+			forStatement.setExpression(convert(statement.condition));
+		}
+		org.eclipse.jdt.internal.compiler.ast.Statement[] increments = statement.increments;
+		if (increments != null) {
+			int incrementsLength = increments.length;
+			for (int i = 0; i < incrementsLength; i++) {
+				forStatement.updaters().add(convertToExpression(increments[i]));
+			}
+		}
+		final Statement action = convert(statement.action);
+		if (action == null) return null;
+		forStatement.setBody(action);
+		return forStatement;
+	}
+
+	public IfStatement convert(org.eclipse.jdt.internal.compiler.ast.IfStatement statement) {
+		IfStatement ifStatement = new IfStatement(this.ast);
+		ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		ifStatement.setExpression(convert(statement.condition));
+		final Statement thenStatement = convert(statement.thenStatement);
+		if (thenStatement == null) return null;
+		ifStatement.setThenStatement(thenStatement);
+		org.eclipse.jdt.internal.compiler.ast.Statement statement2 = statement.elseStatement;
+		if (statement2 != null) {
+			final Statement elseStatement = convert(statement2);
+			if (elseStatement != null) {
+				ifStatement.setElseStatement(elseStatement);
+			}
+		}
+		return ifStatement;
+	}
+
+	public InstanceofExpression convert(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression expression) {
+		InstanceofExpression instanceOfExpression = new InstanceofExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(instanceOfExpression, expression);
+		}
+		Expression leftExpression = convert(expression.expression);
+		instanceOfExpression.setLeftOperand(leftExpression);
+		final Type convertType = convertType(expression.type);
+		instanceOfExpression.setRightOperand(convertType);
+		int startPosition = leftExpression.getStartPosition();
+		int sourceEnd = convertType.getStartPosition() + convertType.getLength() - 1;
+		instanceOfExpression.setSourceRange(startPosition, sourceEnd - startPosition + 1);
+		return instanceOfExpression;
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteral expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
+		if (bodyDeclaration.getJavadoc() == null) {
+			if (javadoc != null) {
+				if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
+					this.commentMapper = new DefaultCommentMapper(this.commentsTable);
+				}
+				Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
+				if (comment != null && comment.isDocComment() && comment.getParent() == null) {
+					Javadoc docComment = (Javadoc) comment;
+					if (this.resolveBindings) {
+						recordNodes(docComment, javadoc);
+						// resolve member and method references binding
+						Iterator tags = docComment.tags().listIterator();
+						while (tags.hasNext()) {
+							recordNodes(javadoc, (TagElement) tags.next());
+						}
+					}
+					bodyDeclaration.setJavadoc(docComment);
+				}
+			}
+		}
+	}
+
+	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, PackageDeclaration packageDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				return;
+		}
+		if (packageDeclaration.getJavadoc() == null) {
+			if (javadoc != null) {
+				if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
+					this.commentMapper = new DefaultCommentMapper(this.commentsTable);
+				}
+				Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
+				if (comment != null && comment.isDocComment() && comment.getParent() == null) {
+					Javadoc docComment = (Javadoc) comment;
+					if (this.resolveBindings) {
+						recordNodes(docComment, javadoc);
+						// resolve member and method references binding
+						Iterator tags = docComment.tags().listIterator();
+						while (tags.hasNext()) {
+							recordNodes(javadoc, (TagElement) tags.next());
+						}
+					}
+					packageDeclaration.setJavadoc(docComment);
+				}
+			}
+		}
+	}
+
+	public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
+		LabeledStatement labeledStatement = new LabeledStatement(this.ast);
+		final int sourceStart = statement.sourceStart;
+		labeledStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
+		Statement body = convert(statement.statement);
+		if (body == null) return null;
+		labeledStatement.setBody(body);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(statement.label));
+		name.setSourceRange(sourceStart, statement.labelEnd - sourceStart + 1);
+		labeledStatement.setLabel(name);
+		return labeledStatement;
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteral expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue expression) {
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(sourceStart, length);
+		removeLeadingAndTrailingCommentsFromLiteral(literal);
+		return literal;
+	}
+
+	public Expression convert(MessageSend expression) {
+		// will return a MethodInvocation or a SuperMethodInvocation or
+		Expression expr;
+		int sourceStart = expression.sourceStart;
+		if (expression.isSuperAccess()) {
+			// returns a SuperMethodInvocation
+			final SuperMethodInvocation superMethodInvocation = new SuperMethodInvocation(this.ast);
+			if (this.resolveBindings) {
+				recordNodes(superMethodInvocation, expression);
+			}
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(expression.selector));
+			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
+			int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
+			name.setSourceRange(nameSourceStart, nameSourceLength);
+			if (this.resolveBindings) {
+				recordNodes(name, expression);
+			}
+			superMethodInvocation.setName(name);
+			// expression.receiver is either a QualifiedSuperReference or a SuperReference
+			// so the casting cannot fail
+			if (expression.receiver instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
+				Name qualifier = convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) expression.receiver);
+				superMethodInvocation.setQualifier(qualifier);
+				if (this.resolveBindings) {
+					recordNodes(qualifier, expression.receiver);
+				}
+				if (qualifier != null) {
+					sourceStart = qualifier.getStartPosition();
+				}
+			}
+			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
+			if (arguments != null) {
+				int argumentsLength = arguments.length;
+				for (int i = 0; i < argumentsLength; i++) {
+					Expression expri = convert(arguments[i]);
+					if (this.resolveBindings) {
+						recordNodes(expri, arguments[i]);
+					}
+					superMethodInvocation.arguments().add(expri);
+				}
+			}
+			final TypeReference[] typeArguments = expression.typeArguments;
+			if (typeArguments != null) {
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						superMethodInvocation.setFlags(superMethodInvocation.getFlags() | ASTNode.MALFORMED);
+						break;
+					default :
+						for (int i = 0, max = typeArguments.length; i < max; i++) {
+							superMethodInvocation.typeArguments().add(convertType(typeArguments[i]));
+						}
+						break;
+				}
+			}
+			expr = superMethodInvocation;
+		} else {
+			// returns a MethodInvocation
+			final MethodInvocation methodInvocation = new MethodInvocation(this.ast);
+			if (this.resolveBindings) {
+				recordNodes(methodInvocation, expression);
+			}
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(expression.selector));
+			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
+			int nameSourceLength = ((int) expression.nameSourcePosition) - nameSourceStart + 1;
+			name.setSourceRange(nameSourceStart, nameSourceLength);
+			methodInvocation.setName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, expression);
+			}
+			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = expression.arguments;
+			if (arguments != null) {
+				int argumentsLength = arguments.length;
+				for (int i = 0; i < argumentsLength; i++) {
+					Expression expri = convert(arguments[i]);
+					if (this.resolveBindings) {
+						recordNodes(expri, arguments[i]);
+					}
+					methodInvocation.arguments().add(expri);
+				}
+			}
+			Expression qualifier = null;
+			org.eclipse.jdt.internal.compiler.ast.Expression receiver = expression.receiver;
+			if (receiver instanceof MessageSend) {
+				if ((receiver.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) != 0) {
+					qualifier = convertToParenthesizedExpression(receiver);
+				} else {
+					qualifier = convert((MessageSend) receiver);
+				}
+			} else {
+				qualifier = convert(receiver);
+			}
+			if (qualifier instanceof Name && this.resolveBindings) {
+				recordNodes(qualifier, receiver);
+			}
+			methodInvocation.setExpression(qualifier);
+			if (qualifier != null) {
+				sourceStart = qualifier.getStartPosition();
+			}
+			final TypeReference[] typeArguments = expression.typeArguments;
+			if (typeArguments != null) {
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						methodInvocation.setFlags(methodInvocation.getFlags() | ASTNode.MALFORMED);
+						break;
+					default :
+						for (int i = 0, max = typeArguments.length; i < max; i++) {
+							methodInvocation.typeArguments().add(convertType(typeArguments[i]));
+						}
+						break;
+				}
+			}
+			expr = methodInvocation;
+		}
+		expr.setSourceRange(sourceStart, expression.sourceEnd - sourceStart + 1);
+		return expr;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambda) {
+		if (this.ast.apiLevel < AST.JLS8) {
+			return createFakeNullLiteral(lambda);		
+		}
+		final LambdaExpression	lambdaExpression = new LambdaExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(lambdaExpression, lambda);
+		}
+		org.eclipse.jdt.internal.compiler.ast.Argument[] arguments = lambda.arguments;
+		if (arguments != null) {
+			int argumentsLength = arguments.length;
+			for (int i = 0; i < argumentsLength; i++) {
+				org.eclipse.jdt.internal.compiler.ast.Argument argument = arguments[i];
+				if (argument.type == null) {
+					VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
+					SimpleName simpleName = new SimpleName(this.ast);
+					simpleName.internalSetIdentifier(new String(argument.name));
+					int start = argument.sourceStart;
+					int end = argument.sourceEnd;
+					simpleName.setSourceRange(start, end - start + 1);
+					if (this.resolveBindings) {
+						recordNodes(simpleName, argument);
+						recordNodes(variableDeclarationFragment, argument);
+					}
+					variableDeclarationFragment.setName(simpleName);
+					variableDeclarationFragment.setSourceRange(start, end - start + 1);
+					lambdaExpression.parameters().add(variableDeclarationFragment);					
+				} else {
+					SingleVariableDeclaration singleVariableDeclaration = convert(argument);
+					lambdaExpression.parameters().add(singleVariableDeclaration);					
+				}
+			}
+		}
+		if (lambda.body instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			lambdaExpression.setBody(convert((org.eclipse.jdt.internal.compiler.ast.Expression) lambda.body));
+		} else {
+			lambdaExpression.setBody(convert((org.eclipse.jdt.internal.compiler.ast.Block) lambda.body));
+		}
+		int sourceStart = lambda.sourceStart;
+		lambdaExpression.setSourceRange(sourceStart, lambda.sourceEnd - sourceStart + 1);
+		lambdaExpression.setParentheses(lambda.hasParentheses);
+		return lambdaExpression;
+	}
+
+	public MarkerAnnotation convert(org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation annotation) {
+		final MarkerAnnotation markerAnnotation = new MarkerAnnotation(this.ast);
+		setTypeNameForAnnotation(annotation, markerAnnotation);
+		int start = annotation.sourceStart;
+		int end = annotation.declarationSourceEnd;
+		markerAnnotation.setSourceRange(start, end - start + 1);
+		if (this.resolveBindings) {
+			recordNodes(markerAnnotation, annotation);
+			markerAnnotation.resolveAnnotationBinding();
+		}
+		return markerAnnotation;
+	}
+
+	public MemberValuePair convert(org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair) {
+		final MemberValuePair pair = new MemberValuePair(this.ast);
+		final SimpleName simpleName = new SimpleName(this.ast);
+		simpleName.internalSetIdentifier(new String(memberValuePair.name));
+		int start = memberValuePair.sourceStart;
+		int end = memberValuePair.sourceEnd;
+		simpleName.setSourceRange(start, end - start + 1);
+		pair.setName(simpleName);
+		final Expression value = convert(memberValuePair.value);
+		pair.setValue(value);
+		start = memberValuePair.sourceStart;
+		end = value.getStartPosition() + value.getLength() - 1;
+		pair.setSourceRange(start, end - start + 1);
+
+		if (memberValuePair.value instanceof SingleNameReference &&
+				((SingleNameReference)memberValuePair.value).token == RecoveryScanner.FAKE_IDENTIFIER) {
+			pair.setFlags(pair.getFlags() | ASTNode.RECOVERED);
+		}
+
+		if (this.resolveBindings) {
+			recordNodes(simpleName, memberValuePair);
+			recordNodes(pair, memberValuePair);
+		}
+		return pair;
+	}
+
+	public Name convert(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
+		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference) reference);
+		} else {
+			return convert((org.eclipse.jdt.internal.compiler.ast.SingleNameReference) reference);
+		}
+	}
+
+	public InfixExpression convert(StringLiteralConcatenation expression) {
+		expression.computeConstant();
+		final InfixExpression infixExpression = new InfixExpression(this.ast);
+		infixExpression.setOperator(InfixExpression.Operator.PLUS);
+		org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = expression.literals;
+		infixExpression.setLeftOperand(convert(stringLiterals[0]));
+		infixExpression.setRightOperand(convert(stringLiterals[1]));
+		for (int i = 2; i < expression.counter; i++) {
+			infixExpression.extendedOperands().add(convert(stringLiterals[i]));
+		}
+		if (this.resolveBindings) {
+			this.recordNodes(infixExpression, expression);
+		}
+		infixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return infixExpression;
+	}
+
+	public NormalAnnotation convert(org.eclipse.jdt.internal.compiler.ast.NormalAnnotation annotation) {
+		final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast);
+		setTypeNameForAnnotation(annotation, normalAnnotation);
+
+		int start = annotation.sourceStart;
+		int end = annotation.declarationSourceEnd;
+
+		org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
+		if (memberValuePairs != null) {
+			for (int i = 0, max = memberValuePairs.length; i < max; i++) {
+				MemberValuePair memberValuePair = convert(memberValuePairs[i]);
+				int memberValuePairEnd = memberValuePair.getStartPosition() + memberValuePair.getLength() - 1;
+				if (end == memberValuePairEnd) {
+					normalAnnotation.setFlags(normalAnnotation.getFlags() | ASTNode.RECOVERED);
+				}
+				normalAnnotation.values().add(memberValuePair);
+			}
+		}
+
+		normalAnnotation.setSourceRange(start, end - start + 1);
+		if (this.resolveBindings) {
+			recordNodes(normalAnnotation, annotation);
+			normalAnnotation.resolveAnnotationBinding();
+		}
+		return normalAnnotation;
+	}
+
+	public NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
+		final NullLiteral literal = new NullLiteral(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return literal;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression expression) {
+		InfixExpression infixExpression = new InfixExpression(this.ast);
+		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
+		if (this.resolveBindings) {
+			this.recordNodes(infixExpression, expression);
+		}
+		final int expressionOperatorID = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT;
+		if (expression.left instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				&& ((expression.left.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0)) {
+			// create an extended string literal equivalent => use the extended operands list
+			infixExpression.extendedOperands().add(convert(expression.right));
+			org.eclipse.jdt.internal.compiler.ast.Expression leftOperand = expression.left;
+			org.eclipse.jdt.internal.compiler.ast.Expression rightOperand = null;
+			do {
+				rightOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).right;
+				if ((((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID
+							&& ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))
+					 || ((rightOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression
+				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
+							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
+				 	List extendedOperands = infixExpression.extendedOperands();
+				 	InfixExpression temp = new InfixExpression(this.ast);
+					if (this.resolveBindings) {
+						this.recordNodes(temp, expression);
+					}
+				 	temp.setOperator(getOperatorFor(expressionOperatorID));
+				 	Expression leftSide = convert(leftOperand);
+					temp.setLeftOperand(leftSide);
+					temp.setSourceRange(leftSide.getStartPosition(), leftSide.getLength());
+					int size = extendedOperands.size();
+				 	for (int i = 0; i < size - 1; i++) {
+				 		Expression expr = temp;
+				 		temp = new InfixExpression(this.ast);
+
+						if (this.resolveBindings) {
+							this.recordNodes(temp, expression);
+						}
+				 		temp.setLeftOperand(expr);
+					 	temp.setOperator(getOperatorFor(expressionOperatorID));
+						temp.setSourceRange(expr.getStartPosition(), expr.getLength());
+				 	}
+				 	infixExpression = temp;
+				 	for (int i = 0; i < size; i++) {
+				 		Expression extendedOperand = (Expression) extendedOperands.remove(size - 1 - i);
+				 		temp.setRightOperand(extendedOperand);
+				 		int startPosition = temp.getLeftOperand().getStartPosition();
+				 		temp.setSourceRange(startPosition, extendedOperand.getStartPosition() + extendedOperand.getLength() - startPosition);
+				 		if (temp.getLeftOperand().getNodeType() == ASTNode.INFIX_EXPRESSION) {
+				 			temp = (InfixExpression) temp.getLeftOperand();
+				 		}
+				 	}
+					int startPosition = infixExpression.getLeftOperand().getStartPosition();
+					infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+					if (this.resolveBindings) {
+						this.recordNodes(infixExpression, expression);
+					}
+					return infixExpression;
+				}
+				infixExpression.extendedOperands().add(0, convert(rightOperand));
+				leftOperand = ((org.eclipse.jdt.internal.compiler.ast.BinaryExpression) leftOperand).left;
+			} while (leftOperand instanceof org.eclipse.jdt.internal.compiler.ast.BinaryExpression && ((leftOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0));
+			Expression leftExpression = convert(leftOperand);
+			infixExpression.setLeftOperand(leftExpression);
+			infixExpression.setRightOperand((Expression)infixExpression.extendedOperands().remove(0));
+			int startPosition = leftExpression.getStartPosition();
+			infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+			return infixExpression;
+		}
+		Expression leftExpression = convert(expression.left);
+		infixExpression.setLeftOperand(leftExpression);
+		infixExpression.setRightOperand(convert(expression.right));
+		infixExpression.setOperator(InfixExpression.Operator.CONDITIONAL_OR);
+		int startPosition = leftExpression.getStartPosition();
+		infixExpression.setSourceRange(startPosition, expression.sourceEnd - startPosition + 1);
+		return infixExpression;
+	}
+
+	public PostfixExpression convert(org.eclipse.jdt.internal.compiler.ast.PostfixExpression expression) {
+		final PostfixExpression postfixExpression = new PostfixExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(postfixExpression, expression);
+		}
+		postfixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		postfixExpression.setOperand(convert(expression.lhs));
+		switch (expression.operator) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
+				postfixExpression.setOperator(PostfixExpression.Operator.INCREMENT);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
+				postfixExpression.setOperator(PostfixExpression.Operator.DECREMENT);
+				break;
+		}
+		return postfixExpression;
+	}
+
+	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.PrefixExpression expression) {
+		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(prefixExpression, expression);
+		}
+		prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		prefixExpression.setOperand(convert(expression.lhs));
+		switch (expression.operator) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
+				prefixExpression.setOperator(PrefixExpression.Operator.INCREMENT);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
+				prefixExpression.setOperator(PrefixExpression.Operator.DECREMENT);
+				break;
+		}
+		return prefixExpression;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
+		final ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
+		if (allocation.enclosingInstance != null) {
+			classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
+		}
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				classInstanceCreation.internalSetName(convert(allocation.type));
+				break;
+			default :
+				classInstanceCreation.setType(convertType(allocation.type));
+		}
+		org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = allocation.arguments;
+		if (arguments != null) {
+			int length = arguments.length;
+			for (int i = 0; i < length; i++) {
+				Expression argument = convert(arguments[i]);
+				if (this.resolveBindings) {
+					recordNodes(argument, arguments[i]);
+				}
+				classInstanceCreation.arguments().add(argument);
+			}
+		}
+		if (allocation.typeArguments != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					for (int i = 0, max = allocation.typeArguments.length; i < max; i++) {
+						classInstanceCreation.typeArguments().add(convertType(allocation.typeArguments[i]));
+					}
+			}
+		}
+		if (allocation.anonymousType != null) {
+			int declarationSourceStart = allocation.sourceStart;
+			classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
+			final AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
+			int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
+			anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
+			classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
+			buildBodyDeclarations(allocation.anonymousType, anonymousClassDeclaration);
+			if (this.resolveBindings) {
+				recordNodes(classInstanceCreation, allocation.anonymousType);
+				recordNodes(anonymousClassDeclaration, allocation.anonymousType);
+				anonymousClassDeclaration.resolveBinding();
+			}
+			return classInstanceCreation;
+		} else {
+			final int start = allocation.sourceStart;
+			classInstanceCreation.setSourceRange(start, allocation.sourceEnd - start + 1);
+			if (this.resolveBindings) {
+				recordNodes(classInstanceCreation, allocation);
+			}
+			return classInstanceCreation;
+		}
+	}
+
+	public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference nameReference) {
+		return setQualifiedNameNameAndSourceRanges(nameReference.tokens, nameReference.sourcePositions, nameReference);
+	}
+
+	public Name convert(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference reference) {
+		return convert(reference.qualification);
+	}
+
+	public ThisExpression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference reference) {
+		final ThisExpression thisExpression = new ThisExpression(this.ast);
+		thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
+		thisExpression.setQualifier(convert(reference.qualification));
+		if (this.resolveBindings) {
+			recordNodes(thisExpression, reference);
+			recordPendingThisExpressionScopeResolution(thisExpression);
+		}
+		return thisExpression;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.Reference reference) {
+		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.NameReference) reference);
+		}
+		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ThisReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ThisReference) reference);
+		}
+		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.ArrayReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ArrayReference) reference);
+		}
+		if (reference instanceof org.eclipse.jdt.internal.compiler.ast.FieldReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.FieldReference) reference);
+		}
+		return null; // cannot be reached
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression reference) {
+		if (this.ast.apiLevel < AST.JLS8) {
+			return createFakeNullLiteral(reference);
+		}
+		Expression result = null;
+		org.eclipse.jdt.internal.compiler.ast.Expression lhs = reference.lhs;
+		org.eclipse.jdt.internal.compiler.ast.TypeReference[] arguments = reference.typeArguments;
+		int start = arguments != null && arguments.length > 0 ? arguments[arguments.length - 1].sourceEnd + 1 : reference.lhs.sourceEnd + 1;
+		final SimpleName name = new SimpleName(this.ast);
+		retrieveIdentifierAndSetPositions(start, reference.sourceEnd, name);
+		name.internalSetIdentifier(new String(reference.selector));
+		if (this.resolveBindings) {
+			recordNodes(name, reference);
+		}
+		List typeArguments = null;
+		if (name.getStartPosition() == -1 && name.getIdentifier().equals("<init>")) { // check for "new"  //$NON-NLS-1$
+			retrieveInitAndSetPositions(start, reference.sourceEnd, name);
+			Type type = null;
+			if (lhs instanceof TypeReference) {
+				type = convertType((TypeReference) lhs);
+			} else if (lhs instanceof NameReference) {
+				Name typeName = convert((NameReference) lhs);
+				SimpleType simpleType = new SimpleType(this.ast);
+				simpleType.setName(typeName);
+				if (this.resolveBindings) {
+					recordNodes(simpleType, lhs);
+				}
+				simpleType.setSourceRange(lhs.sourceStart, lhs.sourceEnd - lhs.sourceStart + 1);
+				type = simpleType;
+			}
+			CreationReference creationReference = new CreationReference(this.ast);
+			creationReference.setType(type);
+			typeArguments = creationReference.typeArguments();
+			result = creationReference;
+		} else if (lhs instanceof TypeReference) {
+			TypeMethodReference typeMethodReference = new TypeMethodReference(this.ast);
+			typeMethodReference.setType(convertType((TypeReference) lhs));
+			typeMethodReference.setName(name);
+			typeArguments = typeMethodReference.typeArguments();
+			result = typeMethodReference;
+		} else if (lhs instanceof SuperReference) {
+			SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
+			superMethodReference.setName(name);
+			typeArguments = superMethodReference.typeArguments();
+			result = superMethodReference;
+		} else if (lhs instanceof QualifiedSuperReference) {
+			SuperMethodReference superMethodReference = new SuperMethodReference(this.ast);
+			superMethodReference.setQualifier(convert((QualifiedSuperReference)lhs));
+			superMethodReference.setName(name);
+			typeArguments = superMethodReference.typeArguments();
+			result = superMethodReference;
+		} else {
+			ExpressionMethodReference expressionMethodReference = new ExpressionMethodReference(this.ast);
+			expressionMethodReference.setExpression(convert(lhs));
+			typeArguments = expressionMethodReference.typeArguments();
+			expressionMethodReference.setName(name);
+			result = expressionMethodReference;
+		}
+		if (typeArguments != null && arguments != null) {
+			int argumentsLength = arguments.length;
+			for (int i = 0; i < argumentsLength; i++) {
+				org.eclipse.jdt.internal.compiler.ast.TypeReference argument = arguments[i];
+				typeArguments.add(convertType(argument));
+			}
+		}
+		if (this.resolveBindings) {
+			recordNodes(result, reference);
+		}
+		int sourceStart = reference.sourceStart; 
+		result.setSourceRange(sourceStart, reference.sourceEnd - sourceStart + 1);
+		return result;
+	}
+
+	public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
+		final ReturnStatement returnStatement = new ReturnStatement(this.ast);
+		returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		if (statement.expression != null) {
+			returnStatement.setExpression(convert(statement.expression));
+		}
+		return returnStatement;
+	}
+
+	public SingleMemberAnnotation convert(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation annotation) {
+		final SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(this.ast);
+		setTypeNameForAnnotation(annotation, singleMemberAnnotation);
+		singleMemberAnnotation.setValue(convert(annotation.memberValue));
+		int start = annotation.sourceStart;
+		int end = annotation.declarationSourceEnd;
+		singleMemberAnnotation.setSourceRange(start, end - start + 1);
+		if (this.resolveBindings) {
+			recordNodes(singleMemberAnnotation, annotation);
+			singleMemberAnnotation.resolveAnnotationBinding();
+		}
+		return singleMemberAnnotation;
+	}
+
+	public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) {
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(nameReference.token));
+		if (this.resolveBindings) {
+			recordNodes(name, nameReference);
+		}
+		name.setSourceRange(nameReference.sourceStart, nameReference.sourceEnd - nameReference.sourceStart + 1);
+		return name;
+	}
+
+	public Statement convert(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
+		if (statement instanceof ForeachStatement) {
+			return convert((ForeachStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration = (org.eclipse.jdt.internal.compiler.ast.LocalDeclaration)statement;
+			return convertToVariableDeclarationStatement(localDeclaration);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.AssertStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.AssertStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Block) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.Block) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.BreakStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.BreakStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ContinueStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ContinueStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.CaseStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.CaseStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.DoStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.DoStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.EmptyStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.EmptyStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ForStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ForStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.IfStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.IfStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.LabeledStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.LabeledStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ReturnStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ReturnStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SwitchStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.SwitchStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.ThrowStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.ThrowStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TryStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.TryStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			ASTNode result = convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement);
+			if (result == null) {
+				return createFakeEmptyStatement(statement);
+			}
+			// annotation and enum type declarations are not returned by the parser inside method bodies
+			TypeDeclaration typeDeclaration = (TypeDeclaration) result;
+			TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
+			typeDeclarationStatement.setDeclaration(typeDeclaration);
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					TypeDeclaration typeDecl = typeDeclarationStatement.internalGetTypeDeclaration();
+					typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
+					break;
+				default :
+					AbstractTypeDeclaration typeDeclAST3 = typeDeclarationStatement.getDeclaration();
+					typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());
+					break;
+			}
+			return typeDeclarationStatement;
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.WhileStatement) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.WhileStatement) statement);
+		}
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			org.eclipse.jdt.internal.compiler.ast.Expression statement2 = (org.eclipse.jdt.internal.compiler.ast.Expression) statement;
+			final Expression expr = convert(statement2);
+			final ExpressionStatement stmt = new ExpressionStatement(this.ast);
+			stmt.setExpression(expr);
+			int sourceStart = expr.getStartPosition();
+			int sourceEnd = statement2.statementEnd;
+			stmt.setSourceRange(sourceStart, sourceEnd - sourceStart + 1);
+			return stmt;
+		}
+		return createFakeEmptyStatement(statement);
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.StringLiteral expression) {
+		if (expression instanceof StringLiteralConcatenation) {
+			return convert((StringLiteralConcatenation) expression);
+		}
+		int length = expression.sourceEnd - expression.sourceStart + 1;
+		int sourceStart = expression.sourceStart;
+		StringLiteral literal = new StringLiteral(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
+		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return literal;
+	}
+
+	public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
+		SwitchStatement switchStatement = new SwitchStatement(this.ast);
+		switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		switchStatement.setExpression(convert(statement.expression));
+		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++) {
+				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+					checkAndAddMultipleLocalDeclaration(statements, i, switchStatement.statements());
+				} else {
+					final Statement currentStatement = convert(statements[i]);
+					if (currentStatement != null) {
+						switchStatement.statements().add(currentStatement);
+					}
+				}
+			}
+		}
+		return switchStatement;
+	}
+
+	public SynchronizedStatement convert(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement statement) {
+		SynchronizedStatement synchronizedStatement = new SynchronizedStatement(this.ast);
+		synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		synchronizedStatement.setBody(convert(statement.block));
+		synchronizedStatement.setExpression(convert(statement.expression));
+		return synchronizedStatement;
+	}
+
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ThisReference reference) {
+		if (reference.isImplicitThis()) {
+			// There is no source associated with an implicit this
+			return null;
+		} else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference) reference);
+		} else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) reference);
+		}  else {
+			ThisExpression thisExpression = new ThisExpression(this.ast);
+			thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
+			if (this.resolveBindings) {
+				recordNodes(thisExpression, reference);
+				recordPendingThisExpressionScopeResolution(thisExpression);
+			}
+			return thisExpression;
+		}
+	}
+
+	public ThrowStatement convert(org.eclipse.jdt.internal.compiler.ast.ThrowStatement statement) {
+		final ThrowStatement throwStatement = new ThrowStatement(this.ast);
+		throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		throwStatement.setExpression(convert(statement.exception));
+		return throwStatement;
+	}
+
+	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.TrueLiteral expression) {
+		final BooleanLiteral literal = new BooleanLiteral(this.ast);
+		literal.setBooleanValue(true);
+		if (this.resolveBindings) {
+			this.recordNodes(literal, expression);
+		}
+		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return literal;
+	}
+
+	public TryStatement convert(org.eclipse.jdt.internal.compiler.ast.TryStatement statement) {
+		final TryStatement tryStatement = new TryStatement(this.ast);
+		tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		LocalDeclaration[] localDeclarations = statement.resources;
+		int resourcesLength = localDeclarations.length;
+		if (resourcesLength > 0) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+				case AST.JLS3_INTERNAL :
+					// convert it to a simple try statement tagged as MALFORMED
+					tryStatement.setFlags(tryStatement.getFlags() | ASTNode.MALFORMED);
+					break;
+				default:
+					for (int i = 0; i < resourcesLength; i++) {
+						LocalDeclaration localDeclaration = localDeclarations[i];
+						VariableDeclarationExpression variableDeclarationExpression = convertToVariableDeclarationExpression(localDeclaration);
+						int start = variableDeclarationExpression.getStartPosition();
+						int end = localDeclaration.declarationEnd;
+						variableDeclarationExpression.setSourceRange(start, end - start + 1);
+						tryStatement.resources().add(variableDeclarationExpression);
+					}
+			}
+		}
+		tryStatement.setBody(convert(statement.tryBlock));
+		org.eclipse.jdt.internal.compiler.ast.Argument[] catchArguments = statement.catchArguments;
+		if (catchArguments != null) {
+			int catchArgumentsLength = catchArguments.length;
+			org.eclipse.jdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
+			int start = statement.tryBlock.sourceEnd;
+			for (int i = 0; i < catchArgumentsLength; i++) {
+				CatchClause catchClause = new CatchClause(this.ast);
+				int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
+				catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);
+				catchClause.setBody(convert(catchBlocks[i]));
+				catchClause.setException(convert(catchArguments[i]));
+				tryStatement.catchClauses().add(catchClause);
+				start = catchBlocks[i].sourceEnd;
+			}
+		}
+		if (statement.finallyBlock != null) {
+			tryStatement.setFinally(convert(statement.finallyBlock));
+		}
+		return tryStatement;
+	}
+
+	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+		int kind = org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.kind(typeDeclaration.modifiers);
+		switch (kind) {
+			case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ENUM_DECL :
+				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+					return null;
+				} else {
+					return convertToEnumDeclaration(typeDeclaration);
+				}
+			case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.ANNOTATION_TYPE_DECL :
+				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+					return null;
+				} else {
+					return convertToAnnotationDeclaration(typeDeclaration);
+				}
+		}
+
+		checkCanceled();
+		TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
+		ASTNode oldReferenceContext = this.referenceContext;
+		this.referenceContext = typeDecl;
+		if (typeDeclaration.modifiersSourceStart != -1) {
+			setModifiers(typeDecl, typeDeclaration);
+		}
+		boolean isInterface = kind == org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.INTERFACE_DECL;
+		typeDecl.setInterface(isInterface);
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
+		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
+		typeDecl.setName(typeName);
+		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
+
+		// need to set the superclass and super interfaces here since we cannot distinguish them at
+		// the type references level.
+		if (typeDeclaration.superclass != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					typeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));
+					break;
+				default :
+					typeDecl.setSuperclassType(convertType(typeDeclaration.superclass));
+					break;
+			}
+		}
+
+		org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					for (int index = 0, length = superInterfaces.length; index < length; index++) {
+						typeDecl.internalSuperInterfaces().add(convert(superInterfaces[index]));
+					}
+					break;
+				default :
+					for (int index = 0, length = superInterfaces.length; index < length; index++) {
+						typeDecl.superInterfaceTypes().add(convertType(superInterfaces[index]));
+					}
+			}
+		}
+		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
+		if (typeParameters != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					for (int index = 0, length = typeParameters.length; index < length; index++) {
+						typeDecl.typeParameters().add(convert(typeParameters[index]));
+					}
+			}
+		}
+		buildBodyDeclarations(typeDeclaration, typeDecl, isInterface);
+		if (this.resolveBindings) {
+			recordNodes(typeDecl, typeDeclaration);
+			recordNodes(typeName, typeDeclaration);
+			typeDecl.resolveBinding();
+		}
+		this.referenceContext = oldReferenceContext;
+		return typeDecl;
+	}
+
+	public TypeParameter convert(org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter) {
+		final TypeParameter typeParameter2 = new TypeParameter(this.ast);
+		final SimpleName simpleName = new SimpleName(this.ast);
+		simpleName.internalSetIdentifier(new String(typeParameter.name));
+		int start = typeParameter.sourceStart;
+		int end = typeParameter.sourceEnd;
+		simpleName.setSourceRange(start, end - start + 1);
+		typeParameter2.setName(simpleName);
+		int annotationsStart = start;
+		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = typeParameter.annotations;
+		if (annotations != null) {
+			if (annotations[0] != null)
+				annotationsStart = annotations[0].sourceStart;
+			annotateTypeParameter(typeParameter2, typeParameter.annotations);
+		}
+		final TypeReference superType = typeParameter.type;
+		end = typeParameter.declarationSourceEnd;
+		if (superType != null) {
+			Type type = convertType(superType);
+			typeParameter2.typeBounds().add(type);
+			end = type.getStartPosition() + type.getLength() - 1;
+		}
+		TypeReference[] bounds = typeParameter.bounds;
+		if (bounds != null) {
+			Type type = null;
+			for (int index = 0, length = bounds.length; index < length; index++) {
+				type = convertType(bounds[index]);
+				typeParameter2.typeBounds().add(type);
+				end = type.getStartPosition() + type.getLength() - 1;
+			}
+		}
+		start = annotationsStart < typeParameter.declarationSourceStart ? annotationsStart : typeParameter.declarationSourceStart;
+		end = retrieveClosingAngleBracketPosition(end);
+		typeParameter2.setSourceRange(start, end - start + 1);
+		if (this.resolveBindings) {
+			recordName(simpleName, typeParameter);
+			recordNodes(typeParameter2, typeParameter);
+			typeParameter2.resolveBinding();
+		}
+		return typeParameter2;
+	}
+
+	public Name convert(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
+		char[][] typeName = typeReference.getTypeName();
+		int length = typeName.length;
+		if (length > 1) {
+			// QualifiedName
+			org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
+			final long[] positions = qualifiedTypeReference.sourcePositions;
+			return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
+		} else {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(typeName[0]));
+			name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
+			name.index = 1;
+			if (this.resolveBindings) {
+				recordNodes(name, typeReference);
+			}
+			return name;
+		}
+	}
+
+	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.UnaryExpression expression) {
+		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
+		if (this.resolveBindings) {
+			this.recordNodes(prefixExpression, expression);
+		}
+		prefixExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		prefixExpression.setOperand(convert(expression.expression));
+		switch ((expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
+				prefixExpression.setOperator(PrefixExpression.Operator.PLUS);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
+				prefixExpression.setOperator(PrefixExpression.Operator.MINUS);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT :
+				prefixExpression.setOperator(PrefixExpression.Operator.NOT);
+				break;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.TWIDDLE :
+				prefixExpression.setOperator(PrefixExpression.Operator.COMPLEMENT);
+		}
+		return prefixExpression;
+	}
+
+	public WhileStatement convert(org.eclipse.jdt.internal.compiler.ast.WhileStatement statement) {
+		final WhileStatement whileStatement = new WhileStatement(this.ast);
+		whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
+		whileStatement.setExpression(convert(statement.condition));
+		final Statement action = convert(statement.action);
+		if (action == null) return null;
+		whileStatement.setBody(action);
+		return whileStatement;
+	}
+
+	public ImportDeclaration convertImport(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
+		final ImportDeclaration importDeclaration = new ImportDeclaration(this.ast);
+		final boolean onDemand = (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0;
+		final char[][] tokens = importReference.tokens;
+		int length = importReference.tokens.length;
+		final long[] positions = importReference.sourcePositions;
+		if (length > 1) {
+			importDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
+		} else {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(tokens[0]));
+			final int start = (int)(positions[0]>>>32);
+			final int end = (int)(positions[0] & 0xFFFFFFFF);
+			name.setSourceRange(start, end - start + 1);
+			name.index = 1;
+			importDeclaration.setName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, importReference);
+			}
+		}
+		importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
+		importDeclaration.setOnDemand(onDemand);
+		int modifiers = importReference.modifiers;
+		if (modifiers != ClassFileConstants.AccDefault) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
+					break;
+				default :
+					if (modifiers == ClassFileConstants.AccStatic) {
+						importDeclaration.setStatic(true);
+					} else {
+						importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
+					}
+			}
+		}
+		if (this.resolveBindings) {
+			recordNodes(importDeclaration, importReference);
+		}
+		return importDeclaration;
+	}
+
+	public PackageDeclaration convertPackage(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
+		org.eclipse.jdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
+		final PackageDeclaration packageDeclaration = new PackageDeclaration(this.ast);
+		final char[][] tokens = importReference.tokens;
+		final int length = importReference.tokens.length;
+		long[] positions = importReference.sourcePositions;
+		if (length > 1) {
+			packageDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
+		} else {
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(tokens[0]));
+			int start = (int)(positions[0]>>>32);
+			int end = (int)(positions[length - 1] & 0xFFFFFFFF);
+			name.setSourceRange(start, end - start + 1);
+			name.index = 1;
+			packageDeclaration.setName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, compilationUnitDeclaration);
+			}
+		}
+		packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
+		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = importReference.annotations;
+		if (annotations != null) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					packageDeclaration.setFlags(packageDeclaration.getFlags() & ASTNode.MALFORMED);
+					break;
+				default :
+					for (int i = 0, max = annotations.length; i < max; i++) {
+						packageDeclaration.annotations().add(convert(annotations[i]));
+					}
+			}
+		}
+		if (this.resolveBindings) {
+			recordNodes(packageDeclaration, importReference);
+		}
+		// Set javadoc
+		convert(compilationUnitDeclaration.javadoc, packageDeclaration);
+		return packageDeclaration;
+	}
+
+	private EnumDeclaration convertToEnumDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+		checkCanceled();
+		// enum declaration cannot be built if the source is not >= 1.5, since enum is then seen as an identifier
+		final EnumDeclaration enumDeclaration2 = new EnumDeclaration(this.ast);
+		setModifiers(enumDeclaration2, typeDeclaration);
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
+		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
+		enumDeclaration2.setName(typeName);
+		enumDeclaration2.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
+
+		org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			for (int index = 0, length = superInterfaces.length; index < length; index++) {
+				enumDeclaration2.superInterfaceTypes().add(convertType(superInterfaces[index]));
+			}
+		}
+		buildBodyDeclarations(typeDeclaration, enumDeclaration2);
+		if (this.resolveBindings) {
+			recordNodes(enumDeclaration2, typeDeclaration);
+			recordNodes(typeName, typeDeclaration);
+			enumDeclaration2.resolveBinding();
+		}
+		return enumDeclaration2;
+	}
+	public Expression convertToExpression(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
+		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
+		} else {
+			return null;
+		}
+	}
+
+	protected FieldDeclaration convertToFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
+		VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
+		final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
+		fieldDeclaration.fragments().add(variableDeclarationFragment);
+		if (this.resolveBindings) {
+			recordNodes(variableDeclarationFragment, fieldDecl);
+			variableDeclarationFragment.resolveBinding();
+		}
+		fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
+		Type type = convertType(fieldDecl.type);
+		setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
+		setModifiers(fieldDeclaration, fieldDecl);
+		convert(fieldDecl.javadoc, fieldDeclaration);
+		return fieldDeclaration;
+	}
+
+	public ParenthesizedExpression convertToParenthesizedExpression(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
+		final ParenthesizedExpression parenthesizedExpression = new ParenthesizedExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(parenthesizedExpression, expression);
+		}
+		parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		adjustSourcePositionsForParent(expression);
+		trimWhiteSpacesAndComments(expression);
+		// decrement the number of parenthesis
+		int numberOfParenthesis = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
+		expression.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
+		expression.bits |= (numberOfParenthesis - 1) << org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
+		parenthesizedExpression.setExpression(convert(expression));
+		return parenthesizedExpression;
+	}
+
+	protected VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
+		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
+		final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
+		variableDeclarationExpression.fragments().add(variableDeclarationFragment);
+		if (this.resolveBindings) {
+			recordNodes(variableDeclarationFragment, localDeclaration);
+		}
+		variableDeclarationExpression.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
+		Type type = convertType(localDeclaration.type);
+		setTypeForVariableDeclarationExpression(variableDeclarationExpression, type, variableDeclarationFragment.getExtraDimensions());
+		if (localDeclaration.modifiersSourceStart != -1) {
+			setModifiers(variableDeclarationExpression, localDeclaration);
+		}
+		return variableDeclarationExpression;
+	}
+
+	protected SingleVariableDeclaration convertToSingleVariableDeclaration(LocalDeclaration localDeclaration) {
+		final SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
+		setModifiers(variableDecl, localDeclaration);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(localDeclaration.name));
+		int start = localDeclaration.sourceStart;
+		int nameEnd = localDeclaration.sourceEnd;
+		name.setSourceRange(start, nameEnd - start + 1);
+		variableDecl.setName(name);
+		final int extraDimensions = retrieveExtraDimension(nameEnd + 1, localDeclaration.type.sourceEnd);
+		if (this.ast.apiLevel >= AST.JLS8) {
+			setExtraAnnotatedDimensions(nameEnd + 1, this.scanner.currentPosition, localDeclaration.type,
+					variableDecl.extraDimensions(), extraDimensions);
+		} else {
+			internalSetExtraDimensions(variableDecl, extraDimensions);
+		}
+		Type type = convertType(localDeclaration.type);
+		int typeEnd = type.getStartPosition() + type.getLength() - 1;
+		// https://bugs.eclipse.org/393719 - [compiler] inconsistent warnings on iteration variables
+		// compiler considers collectionExpression as within the declarationSourceEnd, DOM AST must use the shorter range to avoid overlap
+		int sourceEnd = ((localDeclaration.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsForeachElementVariable) != 0)  
+				? localDeclaration.sourceEnd : localDeclaration.declarationSourceEnd;
+		int rightEnd = Math.max(typeEnd, sourceEnd);
+		/*
+		 * There is extra work to do to set the proper type positions
+		 * See PR http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284
+		 */
+		setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
+		variableDecl.setSourceRange(localDeclaration.declarationSourceStart, rightEnd - localDeclaration.declarationSourceStart + 1);
+		if (this.resolveBindings) {
+			recordNodes(name, localDeclaration);
+			recordNodes(variableDecl, localDeclaration);
+			variableDecl.resolveBinding();
+		}
+		return variableDecl;
+	}
+
+	private ExtraDimension convertToExtraDimensions(int start, int end, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotation) {
+		int length = annotation == null ? 0 : annotation.length;
+		ExtraDimension dimension = this.ast.newExtraDimension();
+		for (int i = 0; i < length; i++) {
+			Annotation annot = convert(annotation[i]);
+			dimension.annotations().add(annot);
+		}
+		retrieveDimensionAndSetPositions(start, end, dimension);
+		return dimension;
+	}
+
+	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
+		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(fieldDeclaration.name));
+		name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
+		variableDeclarationFragment.setName(name);
+		int start = fieldDeclaration.sourceEnd;
+		int end = start;
+		int extraDimensions = retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd );
+		if (this.ast.apiLevel >= AST.JLS8) {
+			setExtraAnnotatedDimensions(fieldDeclaration.sourceEnd + 1, this.scanner.currentPosition,
+					fieldDeclaration.type, variableDeclarationFragment.extraDimensions(), extraDimensions);
+		} else {
+			internalSetExtraDimensions(variableDeclarationFragment, extraDimensions);
+		}
+		if (fieldDeclaration.initialization != null) {
+			final Expression expression = convert(fieldDeclaration.initialization);
+			variableDeclarationFragment.setInitializer(expression);
+			start = expression.getStartPosition() + expression.getLength();
+			end = start - 1;
+		} else {
+			// we need to do it even if extendedDimension is null in case of syntax error in an array initializer
+			// need the exclusive range for retrieveEndOfPotentialExtendedDimensions
+			int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, fieldDeclaration.sourceEnd, fieldDeclaration.declarationSourceEnd);
+			if (possibleEnd == Integer.MIN_VALUE) {
+				end = fieldDeclaration.declarationSourceEnd;
+				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
+			} if (possibleEnd < 0) {
+				end = -possibleEnd;
+				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
+			} else {
+				end = possibleEnd;
+			}
+		}
+		variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
+		if (this.resolveBindings) {
+			recordNodes(name, fieldDeclaration);
+			recordNodes(variableDeclarationFragment, fieldDeclaration);
+			variableDeclarationFragment.resolveBinding();
+		}
+		return variableDeclarationFragment;
+	}
+
+	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
+		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(localDeclaration.name));
+		name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
+		variableDeclarationFragment.setName(name);
+		int start = localDeclaration.sourceEnd;
+		org.eclipse.jdt.internal.compiler.ast.Expression initialization = localDeclaration.initialization;
+		int extraDimension = retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength);
+		if (this.ast.apiLevel >= AST.JLS8) {
+			setExtraAnnotatedDimensions(localDeclaration.sourceEnd + 1, this.scanner.currentPosition,
+					localDeclaration.type, variableDeclarationFragment.extraDimensions(), extraDimension);
+		} else {
+			internalSetExtraDimensions(variableDeclarationFragment, extraDimension);
+		}
+
+		boolean hasInitialization = initialization != null;
+		int end;
+		if (hasInitialization) {
+			final Expression expression = convert(initialization);
+			variableDeclarationFragment.setInitializer(expression);
+			start = expression.getStartPosition() + expression.getLength();
+			end = start - 1;
+		} else {
+			// we need to do it even if extendedDimension is null in case of syntax error in an array initializer
+			// start + 1 because we need the exclusive range for retrieveEndOfPotentialExtendedDimensions
+			int possibleEnd = retrieveEndOfPotentialExtendedDimensions(start + 1, localDeclaration.sourceEnd, localDeclaration.declarationSourceEnd);
+			if (possibleEnd == Integer.MIN_VALUE) {
+				end = start;
+				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
+			} else if (possibleEnd < 0) {
+				end = -possibleEnd;
+				variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
+			} else {
+				end = possibleEnd;
+			}
+		}
+		variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
+		if (this.resolveBindings) {
+			recordNodes(variableDeclarationFragment, localDeclaration);
+			recordNodes(name, localDeclaration);
+			variableDeclarationFragment.resolveBinding();
+		}
+		return variableDeclarationFragment;
+	}
+
+	protected void setExtraAnnotatedDimensions(int start, int end, TypeReference type, final List extraAnnotatedDimensions, int extraDimension) {
+		if (extraDimension > 0) {
+			org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDims = type.getAnnotationsOnDimensions();
+			int length = (annotationsOnDims == null) ? 0 : annotationsOnDims.length;
+			for (int i = (length - extraDimension); i < length; i++) {
+				ExtraDimension dim = convertToExtraDimensions(start, end, (annotationsOnDims == null) ? null : annotationsOnDims[i]);
+				extraAnnotatedDimensions.add(dim);
+				start = dim.getStartPosition() + dim.getLength();
+			}
+		}
+	}
+
+	protected VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
+		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
+		final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast);
+		variableDeclarationStatement.fragments().add(variableDeclarationFragment);
+		if (this.resolveBindings) {
+			recordNodes(variableDeclarationFragment, localDeclaration);
+		}
+		variableDeclarationStatement.setSourceRange(localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd - localDeclaration.declarationSourceStart + 1);
+		Type type = convertType(localDeclaration.type);
+		setTypeForVariableDeclarationStatement(variableDeclarationStatement, type, variableDeclarationFragment.getExtraDimensions());
+		if (localDeclaration.modifiersSourceStart != -1) {
+			setModifiers(variableDeclarationStatement, localDeclaration);
+		}
+		return variableDeclarationStatement;
+	}
+
+	private void annotateType(AnnotatableType type, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				type.setFlags(type.getFlags() | ASTNode.MALFORMED);
+				break;
+			default:
+				int annotationsLength = annotations.length;
+				for (int i = 0; i < annotationsLength; i++) {
+					org.eclipse.jdt.internal.compiler.ast.Annotation typeAnnotation = annotations[i];
+					if (typeAnnotation != null) {
+						Annotation annotation = convert(typeAnnotation);
+						type.annotations().add(annotation);
+					}
+				}
+		}
+	}
+	private void annotateType(Type type, org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotations) {
+		int level = annotations.length - 1;
+		while(type.isArrayType()) {
+			ArrayType arrayType = (ArrayType) type;
+			org.eclipse.jdt.internal.compiler.ast.Annotation[] typeAnnotations = annotations[level--];
+			if (typeAnnotations != null) {
+				annotateType(arrayType, typeAnnotations);
+			}
+			type = arrayType.getComponentType();
+		}
+	}
+
+	private void annotateTypeParameter(TypeParameter typeParameter, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				typeParameter.setFlags(typeParameter.getFlags() | ASTNode.MALFORMED);
+				break;
+			default:
+				int annotationsLength = annotations.length;
+				for (int i = 0; i < annotationsLength; i++) {
+					org.eclipse.jdt.internal.compiler.ast.Annotation typeAnnotation = annotations[i];
+					if (typeAnnotation != null) {
+						Annotation annotation = convert(typeAnnotation);
+						typeParameter.annotations().add(annotation);
+					}
+				}
+		}
+	}
+
+	public Type convertType(TypeReference typeReference) {
+		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations;
+		if (typeReference instanceof Wildcard) {
+			final Wildcard wildcard = (Wildcard) typeReference;
+			final WildcardType wildcardType = new WildcardType(this.ast);
+			if (wildcard.bound != null) {
+				final Type bound = convertType(wildcard.bound);
+				wildcardType.setBound(bound, wildcard.kind == Wildcard.EXTENDS);
+				int start = wildcard.sourceStart;
+				wildcardType.setSourceRange(start, bound.getStartPosition() + bound.getLength() - start);
+			} else {
+				final int start = wildcard.sourceStart;
+				final int end = wildcard.sourceEnd;
+				wildcardType.setSourceRange(start, end - start + 1);
+			}
+			if (this.resolveBindings) {
+				recordNodes(wildcardType, typeReference);
+			}
+			if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
+				annotateType(wildcardType, annotations);
+			}
+			return wildcardType;
+		}
+		Type type = null;
+		int sourceStart = -1;
+		int length = 0;
+		int dimensions = typeReference.dimensions();
+		if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) {
+			// this is either an ArrayTypeReference or a SingleTypeReference
+			char[] name = ((org.eclipse.jdt.internal.compiler.ast.SingleTypeReference) typeReference).getTypeName()[0];
+			sourceStart = typeReference.sourceStart;
+			length = typeReference.sourceEnd - typeReference.sourceStart + 1;
+			// need to find out if this is an array type of primitive types or not
+			if (isPrimitiveType(name)) {
+				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
+				int end = positions[1];
+				if (end == -1) {
+					end = sourceStart + length - 1;
+				}
+				final PrimitiveType primitiveType = new PrimitiveType(this.ast);
+				primitiveType.setPrimitiveTypeCode(getPrimitiveTypeCode(name));
+				primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
+				type = primitiveType;
+				if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
+					annotateType(primitiveType, annotations);
+				}
+			} else if (typeReference instanceof ParameterizedSingleTypeReference) {
+				ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference;
+				final SimpleName simpleName = new SimpleName(this.ast);
+				simpleName.internalSetIdentifier(new String(name));
+				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
+				int end = positions[1];
+				if (end == -1) {
+					end = sourceStart + length - 1;
+				}
+				if (positions[0] != -1) {
+					simpleName.setSourceRange(positions[0], end - positions[0] + 1);
+				} else {
+					simpleName.setSourceRange(sourceStart, end - sourceStart + 1);					
+				}
+
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						SimpleType simpleType = new SimpleType(this.ast);
+						simpleType.setName(simpleName);
+						simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
+						simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
+						type = simpleType;
+						if (this.resolveBindings) {
+							this.recordNodes(simpleName, typeReference);
+						}
+						break;
+					default :
+						simpleType = new SimpleType(this.ast);
+						simpleType.setName(simpleName);
+						simpleType.setSourceRange(simpleName.getStartPosition(), simpleName.getLength());
+						if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
+							annotateType(simpleType, annotations);
+						}
+						final ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+						parameterizedType.setType(simpleType);
+						type = parameterizedType;
+						TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
+						if (typeArguments != null) {
+							Type type2 = null;
+							for (int i = 0, max = typeArguments.length; i < max; i++) {
+								type2 = convertType(typeArguments[i]);
+								((ParameterizedType) type).typeArguments().add(type2);
+								end = type2.getStartPosition() + type2.getLength() - 1;
+							}
+							end = retrieveClosingAngleBracketPosition(end + 1);
+							type.setSourceRange(sourceStart, end - sourceStart + 1);
+						} else {
+							type.setSourceRange(sourceStart, end - sourceStart + 1);
+						}
+						if (this.resolveBindings) {
+							this.recordNodes(simpleName, typeReference);
+							this.recordNodes(simpleType, typeReference);
+						}
+				}
+			} else {
+				final SimpleName simpleName = new SimpleName(this.ast);
+				simpleName.internalSetIdentifier(new String(name));
+				// we need to search for the starting position of the first brace in order to set the proper length
+				// PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
+				int[] positions = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
+				int end = positions[1];
+				if (end == -1) {
+					end = sourceStart + length - 1;
+				}
+				if (positions[0] != -1) {
+					simpleName.setSourceRange(positions[0], end - positions[0] + 1);
+				} else {
+					simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
+				}
+				final SimpleType simpleType = new SimpleType(this.ast);
+				simpleType.setName(simpleName);
+				type = simpleType;
+				type.setSourceRange(sourceStart, end - sourceStart + 1);
+				type = simpleType;
+				if (this.resolveBindings) {
+					this.recordNodes(simpleName, typeReference);
+				}
+				if (typeReference.annotations != null && (annotations = typeReference.annotations[0]) != null) {
+					annotateType(simpleType, annotations);
+				}
+			}
+			if (dimensions != 0) {
+				org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDimensions = typeReference.getAnnotationsOnDimensions();
+				type = this.ast.newArrayType(type, dimensions);
+				type.setSourceRange(sourceStart, length);
+				ArrayType subarrayType = (ArrayType) type;
+				int index = dimensions - 1;
+				while (index > 0) {
+					if (annotationsOnDimensions != null && (annotations = annotationsOnDimensions[index]) != null) {
+						annotateType(subarrayType, annotations);
+					}
+					subarrayType = (ArrayType) subarrayType.getComponentType();
+					int end = retrieveProperRightBracketPosition(index, sourceStart);
+					subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
+					index--;
+				}
+				if (annotationsOnDimensions != null && (annotations = annotationsOnDimensions[0]) != null) {
+					annotateType(subarrayType, annotations);
+				}
+				if (this.resolveBindings) {
+					// store keys for inner types
+					completeRecord((ArrayType) type, typeReference);
+				}
+			}
+		} else {
+			if (typeReference instanceof ParameterizedQualifiedTypeReference) {
+				ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) typeReference;
+				char[][] tokens = parameterizedQualifiedTypeReference.tokens;
+				TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
+				org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = parameterizedQualifiedTypeReference.annotations;
+				TypeReference[] arguments = null;
+				int lenth = tokens.length;
+				int firstTypeIndex = lenth - 1;
+				long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
+				sourceStart = (int)(positions[0]>>>32);
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL : {
+						char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
+						int nameLength = name.length;
+						sourceStart = (int)(positions[0]>>>32);
+						length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
+						Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
+						final SimpleType simpleType = new SimpleType(this.ast);
+						simpleType.setName(qualifiedName);
+						simpleType.setSourceRange(sourceStart, length);
+						simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
+						type = simpleType;
+					}
+					break;
+					default :
+						for (int i = 0; i < lenth; ++i) {
+							if (typeArguments != null && typeArguments[i] != null) {
+								firstTypeIndex = i;
+								break;
+							}
+							if (typeAnnotations != null && typeAnnotations[i] != null) {
+								firstTypeIndex = i;
+								break;
+							}
+						}						
+						
+						Name name = null;						
+						if (firstTypeIndex == 0) {
+							final SimpleName simpleName = new SimpleName(this.ast);
+							simpleName.setIdentifier(new String(tokens[0]));
+							recordPendingNameScopeResolution(simpleName);
+							int start = (int) (positions[0] >>> 32);
+							int end = (int) positions[0];
+							simpleName.setSourceRange(start, end - start + 1);
+							simpleName.index = 1;
+							name = simpleName;
+							if (this.resolveBindings) {
+								recordNodes(simpleName, typeReference);
+							}
+						} else {
+							name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex, typeReference);
+						}
+						
+						SimpleType simpleType = new SimpleType(this.ast);
+						simpleType.setName(name);
+						int start = (int)(positions[0] >>> 32);
+						int end = (int)positions[firstTypeIndex];
+						setSourceRangeAnnotationsAndRecordNodes(typeReference, simpleType, positions, typeAnnotations, firstTypeIndex, 0, firstTypeIndex);
+						Type currentType = simpleType;						
+						int indexOfEnclosingType = 1;
+						if (typeArguments != null && (arguments = typeArguments[firstTypeIndex]) != null) {
+							int arglen = arguments.length;
+							ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+							parameterizedType.index = indexOfEnclosingType;
+							parameterizedType.setType(currentType);
+							if (this.resolveBindings) {
+								recordNodes(parameterizedType, typeReference);
+							}
+							Type type2 = null; 
+							for (int i = 0; i < arglen; ++i ) {
+								type2 = convertType(arguments[i]);
+								parameterizedType.typeArguments().add(type2);
+							}
+							end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
+							end = retrieveClosingAngleBracketPosition(end + 1);
+							parameterizedType.setSourceRange(start, end - start + 1);
+							currentType = parameterizedType;
+						}
+						
+						for (int i = firstTypeIndex + 1; i < lenth; ++i) {
+							SimpleName simpleName = new SimpleName(this.ast);
+							simpleName.setIdentifier(new String(tokens[i]));
+							simpleName.index = i + 1;
+							start = (int) (positions[i] >>> 32);
+							end = (int) positions[i];
+							simpleName.setSourceRange(start, end - start + 1);
+							recordPendingNameScopeResolution(simpleName);
+							QualifiedType qualifiedType = new QualifiedType(this.ast);
+							qualifiedType.setQualifier(currentType);
+							qualifiedType.setName(simpleName);
+							if (typeAnnotations != null &&  (annotations = typeAnnotations[i]) != null) {
+								annotateType(qualifiedType, annotations);
+							}
+							if (this.resolveBindings) {
+								recordNodes(simpleName, typeReference);
+								recordNodes(qualifiedType, typeReference);
+							}
+							start = currentType.getStartPosition();
+							end = simpleName.getStartPosition() + simpleName.getLength() - 1;
+							qualifiedType.setSourceRange(start, end - start + 1);
+							currentType = qualifiedType;
+							indexOfEnclosingType++;
+							
+							if (typeArguments != null && (arguments = typeArguments[i]) != null) {
+								int arglen = arguments.length;
+								qualifiedType.index = indexOfEnclosingType;
+								ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+								parameterizedType.index = indexOfEnclosingType;
+								parameterizedType.setType(currentType);
+								if (this.resolveBindings) {
+									recordNodes(parameterizedType, typeReference);
+								}
+								Type type2 = null; 
+								for (int j = 0; j < arglen; ++j ) {
+									type2 = convertType(arguments[j]);
+									parameterizedType.typeArguments().add(type2);
+								}
+								end = type2 != null ? type2.getStartPosition() + type2.getLength() - 1 : end;
+								end = retrieveClosingAngleBracketPosition(end + 1);
+								parameterizedType.setSourceRange(start, end - start + 1);
+								currentType = parameterizedType;
+							} else {
+								qualifiedType.index = indexOfEnclosingType;
+							}
+						}
+						type = currentType;
+				}
+			} else if (typeReference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) {			
+				QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
+				long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
+				org.eclipse.jdt.internal.compiler.ast.Annotation [][] typeAnnotations = typeReference.annotations;
+				char [][] tokens = qualifiedTypeReference.tokens;
+				int lenth = tokens.length;
+				int firstTypeIndex = lenth;
+				
+				if (typeAnnotations != null) {
+					for (int i = 0; i < lenth; ++i) {
+						if (typeAnnotations[i] != null) {
+							firstTypeIndex = i;
+							break;
+						}
+					}
+				}  
+				sourceStart = (int)(positions[0]>>>32);
+				Name name = null;
+				Type currentType = null;
+				if (firstTypeIndex == lenth) {//Just a QualifiedName
+					name = setQualifiedNameNameAndSourceRanges(tokens, positions, lenth - 1, typeReference);
+					currentType = createSimpleType(name, typeReference, positions, 0, lenth - 1);
+				} else {
+					if (firstTypeIndex <= 1) {
+						name = createSimpleName(typeReference, positions, tokens, 0 );
+						firstTypeIndex = 1;
+					} else {
+						name = setQualifiedNameNameAndSourceRanges(tokens, positions, firstTypeIndex - 1, typeReference);
+					}						
+
+					org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = typeReference.resolvedType;
+					boolean createPackageQualifiedType = false;
+					if (typeBinding instanceof ReferenceBinding) {
+						ReferenceBinding referenceBinding = (ReferenceBinding)typeBinding;			
+						PackageBinding packageBinding = referenceBinding.getPackage();
+						if (packageBinding != null && Arrays.equals(name.toString().toCharArray(), packageBinding.readableName())) {
+							createPackageQualifiedType = true;
+						}
+					}
+					
+					if (createPackageQualifiedType && this.ast.apiLevel >= AST.JLS8) {
+						PackageQualifiedType packageQualifiedType = new PackageQualifiedType(this.ast);
+						packageQualifiedType.setQualifier(name);
+						packageQualifiedType.setName(createSimpleName(typeReference, positions, tokens, firstTypeIndex));
+						setSourceRangeAnnotationsAndRecordNodes(typeReference, packageQualifiedType, positions, typeAnnotations, firstTypeIndex, 0, firstTypeIndex);
+						currentType = packageQualifiedType;																	
+					} else {
+						SimpleType simpleType = this.ast.newSimpleType(name);	
+						setSourceRangeAnnotationsAndRecordNodes(typeReference, simpleType, positions, typeAnnotations, 0, 0, name.index > 0 ? name.index - 1 : 0);
+						currentType = createQualifiedType(typeReference, positions,  typeAnnotations, tokens, firstTypeIndex, simpleType);
+						if (createPackageQualifiedType) 
+							currentType.setFlags(currentType.getFlags() | ASTNode.MALFORMED);
+					}
+					for (int i = firstTypeIndex + 1; i < lenth; ++i) {
+						currentType = createQualifiedType(typeReference, positions,  typeAnnotations, tokens, i, currentType);
+					}					
+				}
+				type = currentType;
+			} else if (typeReference instanceof UnionTypeReference){
+				TypeReference[] typeReferences = ((org.eclipse.jdt.internal.compiler.ast.UnionTypeReference) typeReference).typeReferences;
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+					case AST.JLS3_INTERNAL :
+						// recovery
+						type = this.convertType(typeReferences[0]);
+						int start = typeReference.sourceStart;
+						int endPosition = typeReference.sourceEnd;
+						length = endPosition - start + 1;
+						type.setSourceRange(start, length);
+						type.setFlags(type.getFlags() | ASTNode.MALFORMED);
+						break;
+					default:
+						// union type reference
+						final UnionType unionType = new UnionType(this.ast);
+						for (int i = 0, max = typeReferences.length; i < max; i++) {
+							unionType.types().add(this.convertType(typeReferences[i]));
+						}
+						type = unionType;
+						List types = unionType.types();
+						int size = types.size();
+						start = ((Type) types.get(0)).getStartPosition();
+						Type lastType = (Type) types.get(size - 1);
+						endPosition = lastType.getStartPosition() + lastType.getLength();
+						length = endPosition - start; /* + 1 - 1 == 0 */
+						type.setSourceRange(start, length);
+				}
+			} else if (typeReference instanceof IntersectionCastTypeReference) {
+				TypeReference[] typeReferences = ((IntersectionCastTypeReference) typeReference).typeReferences;
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+					case AST.JLS3_INTERNAL :
+					case AST.JLS4_INTERNAL :
+						type = this.convertType(typeReferences[0]);
+						int start = typeReference.sourceStart;
+						int endPosition = typeReference.sourceEnd;
+						length = endPosition - start + 1;
+						type.setSourceRange(start, length);
+						type.setFlags(type.getFlags() | ASTNode.MALFORMED);
+						break;
+					default:
+						// intersection type reference
+						final IntersectionType castType = new IntersectionType(this.ast);
+						for (int i = 0, max = typeReferences.length; i < max; i++) {
+							castType.types().add(this.convertType(typeReferences[i]));
+						}
+						type = castType;
+						List types = castType.types();
+						int size = types.size();
+						start = ((Type) types.get(0)).getStartPosition();
+						Type lastType = (Type) types.get(size - 1);
+						endPosition = lastType.getStartPosition() + lastType.getLength();
+						length = endPosition - start;
+						type.setSourceRange(start, length);
+				}
+			}
+
+			length = typeReference.sourceEnd - sourceStart + 1;
+			if (dimensions != 0) {
+				org.eclipse.jdt.internal.compiler.ast.Annotation[][] annotationsOnDimensions = typeReference.getAnnotationsOnDimensions();
+				type = this.ast.newArrayType(type, dimensions);
+				if (this.resolveBindings) {
+					completeRecord((ArrayType) type, typeReference);
+				}
+				int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSourceLength);
+				if (end != -1) {
+					type.setSourceRange(sourceStart, end - sourceStart + 1);
+				} else {
+					type.setSourceRange(sourceStart, length);
+				}
+				ArrayType subarrayType = (ArrayType) type;
+				int index = dimensions - 1;
+				while (index > 0) {
+					if (annotationsOnDimensions != null  && (annotations = annotationsOnDimensions[index]) != null) {
+						annotateType(subarrayType, annotations);
+					}
+					subarrayType = (ArrayType) subarrayType.getComponentType();
+					end = retrieveProperRightBracketPosition(index, sourceStart);
+					subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
+					index--;
+				}
+				if (annotationsOnDimensions != null  && (annotations = annotationsOnDimensions[0]) != null) {
+					annotateType(subarrayType, annotations);
+				}
+			}
+		}
+		if (this.resolveBindings) {
+			this.recordNodes(type, typeReference);
+		}
+		boolean sawDiamond = false;
+		if (typeReference instanceof ParameterizedSingleTypeReference) {
+			ParameterizedSingleTypeReference pstr = (ParameterizedSingleTypeReference) typeReference;
+			if (pstr.typeArguments == TypeReference.NO_TYPE_ARGUMENTS) {
+				sawDiamond = true;
+			}
+		} else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference pqtr = (ParameterizedQualifiedTypeReference) typeReference;
+			for (int i = 0, len = pqtr.typeArguments.length; i < len; i++) {
+				if (pqtr.typeArguments[i] == TypeReference.NO_TYPE_ARGUMENTS) {
+					sawDiamond = true;
+					break;
+				}
+			}
+		} 
+		if (sawDiamond) {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+				case AST.JLS3_INTERNAL :
+					type.setFlags(type.getFlags() | ASTNode.MALFORMED);
+			}
+		}
+		return type;
+	}
+
+	private QualifiedType createQualifiedType(TypeReference typeReference, long[] positions,
+			org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, char[][] tokens, int index,
+			Type qualifier) {
+		SimpleName simpleName = createSimpleName(typeReference, positions, tokens, index);
+		QualifiedType qualifiedType = new QualifiedType(this.ast);
+		qualifiedType.setQualifier(qualifier);
+		qualifiedType.setName(simpleName);
+		int start = qualifier.getStartPosition();
+		int end = simpleName.getStartPosition() + simpleName.getLength() - 1;
+		setSourceRangeAnnotationsAndRecordNodes(typeReference, qualifiedType, typeAnnotations, index, start, end);
+		return qualifiedType;
+	}
+
+	private SimpleType createSimpleType(Name name, TypeReference typeReference, long[] positions,
+			int startIndex, int endIndex) {
+		SimpleType simpleType = new SimpleType(this.ast);
+		simpleType.setName(name);
+		int start = (int)(positions[startIndex] >>> 32);
+		int end = (int)positions[endIndex];
+		simpleType.setSourceRange(start, end - start + 1);
+		if (this.resolveBindings) {
+			recordNodes(simpleType, typeReference);
+		}
+		return simpleType;
+	}
+
+	private void setSourceRangeAnnotationsAndRecordNodes(TypeReference typeReference, AnnotatableType annotatableType,
+			org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, int index, int start, int end) {
+		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations;
+		int annotationsStart = start;
+		int length = end - start + 1;
+		if (typeAnnotations != null && (annotations = typeAnnotations[index]) != null) {
+			annotateType(annotatableType, annotations);
+			if (annotations[0] != null && (annotationsStart = annotations[0].sourceStart) < start) {
+				length += annotationsStart > 0 ? start - annotationsStart : 0;
+				start = annotationsStart;
+			}
+		}
+		annotatableType.setSourceRange(start, length);
+		if (this.resolveBindings) {
+			recordNodes(annotatableType, typeReference);
+		}
+	}
+
+	private void setSourceRangeAnnotationsAndRecordNodes(TypeReference typeReference, AnnotatableType annotatableType, 
+			long[] positions, org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations, int index, int startIndex, int endIndex) {
+		int start = (int) (positions[startIndex] >>> 32);
+		int end = (int) positions[endIndex];
+		setSourceRangeAnnotationsAndRecordNodes(typeReference, annotatableType, typeAnnotations, index, start, end);
+	}
+
+	private SimpleName createSimpleName(TypeReference typeReference, long[] positions, char[][] tokens, int index) {
+		final SimpleName simpleName = new SimpleName(this.ast);
+		simpleName.internalSetIdentifier(new String(tokens[index]));
+		recordPendingNameScopeResolution(simpleName);
+		int start = (int) (positions[index] >>> 32);
+		int end = (int) positions[index];
+		simpleName.setSourceRange(start, end - start + 1);
+		simpleName.index = index + 1;
+		if (this.resolveBindings) {
+			recordNodes(simpleName, typeReference);
+		}
+		return simpleName;
+	}
+
+	protected Comment createComment(int[] positions) {
+		// Create comment node
+		Comment comment = null;
+		int start = positions[0];
+		int end = positions[1];
+		if (positions[1]>0) { // Javadoc comments have positive end position
+			Javadoc docComment = this.docParser.parse(positions);
+			if (docComment == null) return null;
+			comment = docComment;
+		} else {
+			end = -end;
+			if (positions[0] == 0) { // we cannot know without testing chars again
+				if (this.docParser.scanner.source[1] == '/') {
+					comment = new LineComment(this.ast);
+				} else {
+					comment = new BlockComment(this.ast);
+				}
+			}
+			else if (positions[0]>0) { // Block comment have positive start position
+				comment = new BlockComment(this.ast);
+			} else { // Line comment have negative start and end position
+				start = -start;
+				comment = new LineComment(this.ast);
+			}
+			comment.setSourceRange(start, end - start);
+		}
+		return comment;
+	}
+
+	protected Statement createFakeEmptyStatement(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
+		if (statement == null) return null;
+		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
+		emptyStatement.setFlags(emptyStatement.getFlags() | ASTNode.MALFORMED);
+		int start = statement.sourceStart;
+		int end = statement.sourceEnd;
+		emptyStatement.setSourceRange(start, end - start + 1);
+		return emptyStatement;
+	}
+
+	/**
+	 * Warning: Callers of this method must ensure that the fake literal node is not recorded in
+	 * {@link #recordNodes(ASTNode, org.eclipse.jdt.internal.compiler.ast.ASTNode)}, see bug 403444!
+	 */
+	protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression expression) {
+		if (this.referenceContext != null) {
+			this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED);
+		}
+		NullLiteral nullLiteral = new NullLiteral(this.ast);
+		nullLiteral.setFlags(nullLiteral.getFlags() | ASTNode.MALFORMED);
+		nullLiteral.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		return nullLiteral;
+	}
+
+	/**
+	 * @return a new modifier
+	 */
+	private Modifier createModifier(ModifierKeyword keyword) {
+		final Modifier modifier = new Modifier(this.ast);
+		modifier.setKeyword(keyword);
+		int start = this.scanner.getCurrentTokenStartPosition();
+		int end = this.scanner.getCurrentTokenEndPosition();
+		modifier.setSourceRange(start, end - start + 1);
+		return modifier;
+	}
+
+	protected InfixExpression.Operator getOperatorFor(int operatorID) {
+		switch (operatorID) {
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.EQUAL_EQUAL :
+				return InfixExpression.Operator.EQUALS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS_EQUAL :
+				return InfixExpression.Operator.LESS_EQUALS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER_EQUAL :
+				return InfixExpression.Operator.GREATER_EQUALS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.NOT_EQUAL :
+				return InfixExpression.Operator.NOT_EQUALS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LEFT_SHIFT :
+				return InfixExpression.Operator.LEFT_SHIFT;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.RIGHT_SHIFT :
+				return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.UNSIGNED_RIGHT_SHIFT :
+				return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR_OR :
+				return InfixExpression.Operator.CONDITIONAL_OR;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND_AND :
+				return InfixExpression.Operator.CONDITIONAL_AND;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.PLUS :
+				return InfixExpression.Operator.PLUS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MINUS :
+				return InfixExpression.Operator.MINUS;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.REMAINDER :
+				return InfixExpression.Operator.REMAINDER;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.XOR :
+				return InfixExpression.Operator.XOR;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.AND :
+				return InfixExpression.Operator.AND;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.MULTIPLY :
+				return InfixExpression.Operator.TIMES;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.OR :
+				return InfixExpression.Operator.OR;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.DIVIDE :
+				return InfixExpression.Operator.DIVIDE;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.GREATER :
+				return InfixExpression.Operator.GREATER;
+			case org.eclipse.jdt.internal.compiler.ast.OperatorIds.LESS :
+				return InfixExpression.Operator.LESS;
+		}
+		return null;
+	}
+
+	protected PrimitiveType.Code getPrimitiveTypeCode(char[] name) {
+		switch(name[0]) {
+			case 'i' :
+				if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
+					return PrimitiveType.INT;
+				}
+				break;
+			case 'l' :
+				if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
+					return PrimitiveType.LONG;
+				}
+				break;
+			case 'd' :
+				if (name.length == 6
+					 && name[1] == 'o'
+					 && name[2] == 'u'
+					 && name[3] == 'b'
+					 && name[4] == 'l'
+					 && name[5] == 'e') {
+					return PrimitiveType.DOUBLE;
+				}
+				break;
+			case 'f' :
+				if (name.length == 5
+					 && name[1] == 'l'
+					 && name[2] == 'o'
+					 && name[3] == 'a'
+					 && name[4] == 't') {
+					return PrimitiveType.FLOAT;
+				}
+				break;
+			case 'b' :
+				if (name.length == 4
+					 && name[1] == 'y'
+					 && name[2] == 't'
+					 && name[3] == 'e') {
+					return PrimitiveType.BYTE;
+				} else
+					if (name.length == 7
+						 && name[1] == 'o'
+						 && name[2] == 'o'
+						 && name[3] == 'l'
+						 && name[4] == 'e'
+						 && name[5] == 'a'
+						 && name[6] == 'n') {
+					return PrimitiveType.BOOLEAN;
+				}
+				break;
+			case 'c' :
+				if (name.length == 4
+					 && name[1] == 'h'
+					 && name[2] == 'a'
+					 && name[3] == 'r') {
+					return PrimitiveType.CHAR;
+				}
+				break;
+			case 's' :
+				if (name.length == 5
+					 && name[1] == 'h'
+					 && name[2] == 'o'
+					 && name[3] == 'r'
+					 && name[4] == 't') {
+					return PrimitiveType.SHORT;
+				}
+				break;
+			case 'v' :
+				if (name.length == 4
+					 && name[1] == 'o'
+					 && name[2] == 'i'
+					 && name[3] == 'd') {
+					return PrimitiveType.VOID;
+				}
+		}
+		return null; // cannot be reached
+	}
+
+	protected boolean isPrimitiveType(char[] name) {
+		switch(name[0]) {
+			case 'i' :
+				if (name.length == 3 && name[1] == 'n' && name[2] == 't') {
+					return true;
+				}
+				return false;
+			case 'l' :
+				if (name.length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g') {
+					return true;
+				}
+				return false;
+			case 'd' :
+				if (name.length == 6
+					 && name[1] == 'o'
+					 && name[2] == 'u'
+					 && name[3] == 'b'
+					 && name[4] == 'l'
+					 && name[5] == 'e') {
+					return true;
+				}
+				return false;
+			case 'f' :
+				if (name.length == 5
+					 && name[1] == 'l'
+					 && name[2] == 'o'
+					 && name[3] == 'a'
+					 && name[4] == 't') {
+					return true;
+				}
+				return false;
+			case 'b' :
+				if (name.length == 4
+					 && name[1] == 'y'
+					 && name[2] == 't'
+					 && name[3] == 'e') {
+					return true;
+				} else
+					if (name.length == 7
+						 && name[1] == 'o'
+						 && name[2] == 'o'
+						 && name[3] == 'l'
+						 && name[4] == 'e'
+						 && name[5] == 'a'
+						 && name[6] == 'n') {
+					return true;
+				}
+				return false;
+			case 'c' :
+				if (name.length == 4
+					 && name[1] == 'h'
+					 && name[2] == 'a'
+					 && name[3] == 'r') {
+					return true;
+				}
+				return false;
+			case 's' :
+				if (name.length == 5
+					 && name[1] == 'h'
+					 && name[2] == 'o'
+					 && name[3] == 'r'
+					 && name[4] == 't') {
+					return true;
+				}
+				return false;
+			case 'v' :
+				if (name.length == 4
+					 && name[1] == 'o'
+					 && name[2] == 'i'
+					 && name[3] == 'd') {
+					return true;
+				}
+				return false;
+		}
+		return false;
+	}
+
+	private void lookupForScopes() {
+		if (this.pendingNameScopeResolution != null) {
+			for (Iterator iterator = this.pendingNameScopeResolution.iterator(); iterator.hasNext(); ) {
+				Name name = (Name) iterator.next();
+				this.ast.getBindingResolver().recordScope(name, lookupScope(name));
+			}
+		}
+		if (this.pendingThisExpressionScopeResolution != null) {
+			for (Iterator iterator = this.pendingThisExpressionScopeResolution.iterator(); iterator.hasNext(); ) {
+				ThisExpression thisExpression = (ThisExpression) iterator.next();
+				this.ast.getBindingResolver().recordScope(thisExpression, lookupScope(thisExpression));
+			}
+		}
+
+	}
+
+	private BlockScope lookupScope(ASTNode node) {
+		ASTNode currentNode = node;
+		while(currentNode != null
+			&&!(currentNode instanceof MethodDeclaration)
+			&& !(currentNode instanceof Initializer)
+			&& !(currentNode instanceof FieldDeclaration)
+			&& !(currentNode instanceof AbstractTypeDeclaration)) {
+			currentNode = currentNode.getParent();
+		}
+		if (currentNode == null) {
+			return null;
+		}
+		if (currentNode instanceof Initializer) {
+			Initializer initializer = (Initializer) currentNode;
+			while(!(currentNode instanceof AbstractTypeDeclaration)) {
+				currentNode = currentNode.getParent();
+			}
+			if (currentNode instanceof TypeDeclaration
+				|| currentNode instanceof EnumDeclaration
+				|| currentNode instanceof AnnotationTypeDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
+				if ((initializer.getModifiers() & Modifier.STATIC) != 0) {
+					return typeDecl.staticInitializerScope;
+				} else {
+					return typeDecl.initializerScope;
+				}
+			}
+		} else if (currentNode instanceof FieldDeclaration) {
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) currentNode;
+			while(!(currentNode instanceof AbstractTypeDeclaration)) {
+				currentNode = currentNode.getParent();
+			}
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
+			if ((fieldDeclaration.getModifiers() & Modifier.STATIC) != 0) {
+				return typeDecl.staticInitializerScope;
+			} else {
+				return typeDecl.initializerScope;
+			}
+		} else if (currentNode instanceof AbstractTypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDecl = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
+			return typeDecl.initializerScope;
+		}
+		AbstractMethodDeclaration abstractMethodDeclaration = (AbstractMethodDeclaration) this.ast.getBindingResolver().getCorrespondingNode(currentNode);
+		return abstractMethodDeclaration.scope;
+	}
+
+	protected void recordName(Name name, org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode) {
+		if (compilerNode != null) {
+			recordNodes(name, compilerNode);
+			if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
+				org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) compilerNode;
+				if (name.isQualifiedName()) {
+					SimpleName simpleName = null;
+					while (name.isQualifiedName()) {
+						simpleName = ((QualifiedName) name).getName();
+						recordNodes(simpleName, typeRef);
+						name = ((QualifiedName) name).getQualifier();
+						recordNodes(name, typeRef);
+					}
+				}
+			}
+		}
+	}
+
+	protected void recordNodes(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
+		// Do not record the fake literal node created in lieu of functional expressions at JLS levels < 8, as it would lead to CCE down the road.
+		if (oldASTNode instanceof org.eclipse.jdt.internal.compiler.ast.FunctionalExpression && node instanceof NullLiteral) {
+			return;
+		}
+		this.ast.getBindingResolver().store(node, oldASTNode);
+	}
+
+	protected void recordNodes(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, TagElement tagElement) {
+		Iterator fragments = tagElement.fragments().listIterator();
+		while (fragments.hasNext()) {
+			ASTNode node = (ASTNode) fragments.next();
+			if (node.getNodeType() == ASTNode.MEMBER_REF) {
+				MemberRef memberRef = (MemberRef) node;
+				Name name = memberRef.getName();
+				// get compiler node and record nodes
+				int start = name.getStartPosition();
+				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
+				if (compilerNode!= null) {
+					recordNodes(name, compilerNode);
+					recordNodes(node, compilerNode);
+				}
+				// Replace qualifier to have all nodes recorded
+				if (memberRef.getQualifier() != null) {
+					org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
+					if (compilerNode instanceof JavadocFieldReference) {
+						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocFieldReference)compilerNode).receiver;
+						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
+							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
+						}
+					}
+					else if (compilerNode instanceof JavadocMessageSend) {
+						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((JavadocMessageSend)compilerNode).receiver;
+						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
+							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
+						}
+					}
+					if (typeRef != null) {
+						recordName(memberRef.getQualifier(), typeRef);
+					}
+				}
+			} else if (node.getNodeType() == ASTNode.METHOD_REF) {
+				MethodRef methodRef = (MethodRef) node;
+				Name name = methodRef.getName();
+				// get method name start position
+				int start = methodRef.getStartPosition();
+				this.scanner.resetTo(start, start + name.getStartPosition()+name.getLength());
+				int token;
+				try {
+					nextToken: while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF && token != TerminalTokens.TokenNameLPAREN)  {
+						if (token == TerminalTokens.TokenNameERROR && this.scanner.currentCharacter == '#') {
+							start = this.scanner.getCurrentTokenEndPosition()+1;
+							break nextToken;
+						}
+					}
+				}
+				catch(InvalidInputException e) {
+					// ignore
+				}
+				// get compiler node and record nodes
+				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(start);
+				// record nodes
+				if (compilerNode != null) {
+					recordNodes(methodRef, compilerNode);
+					// get type ref
+					org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
+					if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression) {
+						typeRef = ((org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
+						if (typeRef != null) recordNodes(name, compilerNode);
+					}
+					else if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend) {
+						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
+						if (expression instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
+							typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) expression;
+						}
+						recordNodes(name, compilerNode);
+					}
+					// record name and qualifier
+					if (typeRef != null && methodRef.getQualifier() != null) {
+						recordName(methodRef.getQualifier(), typeRef);
+					}
+				}
+				// Resolve parameters
+				Iterator parameters = methodRef.parameters().listIterator();
+				while (parameters.hasNext()) {
+					MethodRefParameter param = (MethodRefParameter) parameters.next();
+					org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) javadoc.getNodeStartingAt(param.getStartPosition());
+					if (expression != null) {
+						recordNodes(param, expression);
+						if (expression instanceof JavadocArgumentExpression) {
+							JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
+							org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
+							if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+								param.setVarargs(argExpr.argument.isVarArgs());
+							}
+							recordNodes(param.getType(), typeRef);
+							if (param.getType().isSimpleType()) {
+								recordName(((SimpleType)param.getType()).getName(), typeRef);
+							} else if (param.getType().isArrayType()) {
+								Type type = ((ArrayType) param.getType()).getElementType();
+								recordNodes(type, typeRef);
+								if (type.isSimpleType()) {
+									recordName(((SimpleType)type).getName(), typeRef);
+								}
+							}
+						}
+					}
+				}
+			} else if (node.getNodeType() == ASTNode.SIMPLE_NAME ||
+					node.getNodeType() == ASTNode.QUALIFIED_NAME) {
+				org.eclipse.jdt.internal.compiler.ast.ASTNode compilerNode = javadoc.getNodeStartingAt(node.getStartPosition());
+				recordName((Name) node, compilerNode);
+			} else if (node.getNodeType() == ASTNode.TAG_ELEMENT) {
+				// resolve member and method references binding
+				recordNodes(javadoc, (TagElement) node);
+			}
+		}
+	}
+
+	protected void recordPendingNameScopeResolution(Name name) {
+		if (this.pendingNameScopeResolution == null) {
+			this.pendingNameScopeResolution = new HashSet();
+		}
+		this.pendingNameScopeResolution.add(name);
+	}
+
+	protected void recordPendingThisExpressionScopeResolution(ThisExpression thisExpression) {
+		if (this.pendingThisExpressionScopeResolution == null) {
+			this.pendingThisExpressionScopeResolution = new HashSet();
+		}
+		this.pendingThisExpressionScopeResolution.add(thisExpression);
+	}
+
+	/**
+	 * Remove whitespaces and comments before and after the expression.
+	 */
+	private void trimWhiteSpacesAndComments(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
+		int start = expression.sourceStart;
+		int end = expression.sourceEnd;
+		int token;
+		int trimLeftPosition = expression.sourceStart;
+		int trimRightPosition = expression.sourceEnd;
+		boolean first = true;
+		Scanner removeBlankScanner = this.ast.scanner;
+		try {
+			removeBlankScanner.setSource(this.compilationUnitSource);
+			removeBlankScanner.resetTo(start, end);
+			while (true) {
+				token = removeBlankScanner.getNextToken();
+				switch (token) {
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						if (first) {
+							trimLeftPosition = removeBlankScanner.currentPosition;
+						}
+						break;
+					case TerminalTokens.TokenNameWHITESPACE :
+						if (first) {
+							trimLeftPosition = removeBlankScanner.currentPosition;
+						}
+						break;
+					case TerminalTokens.TokenNameEOF :
+						expression.sourceStart = trimLeftPosition;
+						expression.sourceEnd = trimRightPosition;
+						return;
+					default :
+						/*
+						 * if we find something else than a whitespace or a comment,
+						 * then we reset the trimRigthPosition to the expression
+						 * source end.
+						 */
+						trimRightPosition = removeBlankScanner.currentPosition - 1;
+						first = false;
+				}
+			}
+		} catch (InvalidInputException e){
+			// ignore
+		}
+	}
+
+	/**
+	 * Remove potential trailing comment by settings the source end on the closing parenthesis
+	 */
+	protected void removeLeadingAndTrailingCommentsFromLiteral(ASTNode node) {
+		int start = node.getStartPosition();
+		this.scanner.resetTo(start, start + node.getLength());
+		int token;
+		int startPosition = -1;
+		try {
+			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
+				switch(token) {
+					case TerminalTokens.TokenNameIntegerLiteral :
+					case TerminalTokens.TokenNameFloatingPointLiteral :
+					case TerminalTokens.TokenNameLongLiteral :
+					case TerminalTokens.TokenNameDoubleLiteral :
+					case TerminalTokens.TokenNameCharacterLiteral :
+						if (startPosition == -1) {
+							startPosition = this.scanner.startPosition;
+						}
+						int end = this.scanner.currentPosition;
+						node.setSourceRange(startPosition, end - startPosition);
+						return;
+					case TerminalTokens.TokenNameMINUS :
+						startPosition = this.scanner.startPosition;
+						break;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+
+	/**
+	 * This method is used to retrieve the end position of the block.
+	 * @return the dimension found, -1 if none
+	 */
+	protected int retrieveClosingAngleBracketPosition(int start) {
+		this.scanner.resetTo(start, this.compilationUnitSourceLength);
+		this.scanner.returnOnlyGreater = true;
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameGREATER:
+						return this.scanner.currentPosition - 1;
+					case TerminalTokens.TokenNameLESS:
+						// TokenNameLESS can only be found if the current type has a diamond, start is located before the '<'
+						continue;
+					default:
+						return start;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		this.scanner.returnOnlyGreater = false;
+		return start;
+	}
+
+	/**
+	 * This method is used to set the right end position for expression
+	 * statement. The actual AST nodes don't include the trailing semicolon.
+	 * This method fixes the length of the corresponding node.
+	 */
+	protected void retrieveColonPosition(ASTNode node) {
+		int start = node.getStartPosition();
+		int length = node.getLength();
+		int end = start + length;
+		this.scanner.resetTo(end, this.compilationUnitSourceLength);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameCOLON:
+						node.setSourceRange(start, this.scanner.currentPosition - start);
+						return;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+	/**
+	 * This method is used to retrieve the start position of the Ellipsis
+	 */
+	protected int retrieveEllipsisStartPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameELLIPSIS:
+						return this.scanner.startPosition - 1;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+
+	}
+	/**
+	 * This method is used to retrieve the end position of the block.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveEndBlockPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		int count = 0;
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACE://110
+						count++;
+						break;
+					case TerminalTokens.TokenNameRBRACE://95
+						count--;
+						if (count == 0) {
+							return this.scanner.currentPosition - 1;
+						}
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	protected int retrieveSemiColonPosition(Expression node) {
+		int start = node.getStartPosition();
+		int length = node.getLength();
+		int end = start + length;
+		this.scanner.resetTo(end, this.compilationUnitSourceLength);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameSEMICOLON:
+						return this.scanner.currentPosition - 1;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve the ending position for a type declaration when the dimension is right after the type
+	 * name.
+	 * For example:
+	 *    int[] i; => return 5, but int i[] => return -1;
+	 * @return int the dimension found
+	 */
+	protected int retrieveEndOfDimensionsPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		int foundPosition = -1;
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACKET:
+					case TerminalTokens.TokenNameCOMMENT_BLOCK:
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC:
+					case TerminalTokens.TokenNameCOMMENT_LINE:
+						break;
+					case TerminalTokens.TokenNameRBRACKET://166
+						foundPosition = this.scanner.currentPosition - 1;
+						break;
+					default:
+						return foundPosition;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return foundPosition;
+	}
+
+	/**
+	 * This method is used to retrieve the start and end position of a name or primitive type token.
+	 * 
+	 * @return int[] a single dimensional array, with two elements, for the start and end positions of the name respectively
+	 */
+	protected int[] retrieveEndOfElementTypeNamePosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		boolean isAnnotation = false;
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameAT:
+						isAnnotation = true;
+						break;
+					case TerminalTokens.TokenNameIdentifier:
+						if (isAnnotation) {
+							isAnnotation = false;
+							break;
+						}
+						//$FALL-THROUGH$
+					case TerminalTokens.TokenNamebyte:
+					case TerminalTokens.TokenNamechar:
+					case TerminalTokens.TokenNamedouble:
+					case TerminalTokens.TokenNamefloat:
+					case TerminalTokens.TokenNameint:
+					case TerminalTokens.TokenNamelong:
+					case TerminalTokens.TokenNameshort:
+					case TerminalTokens.TokenNameboolean:
+						return new int[]{this.scanner.startPosition, this.scanner.currentPosition - 1};
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return new int[]{-1, -1};
+	}
+
+	/**
+	 * This method is used to retrieve the position after the right parenthesis.
+	 * @return int the position found
+	 */
+	protected int retrieveEndOfRightParenthesisPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			int count = 0;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameRPAREN:
+						count--;
+						if (count <= 0) return this.scanner.currentPosition;
+						 break;
+					case TerminalTokens.TokenNameLPAREN:
+						count++;
+						//$FALL-THROUGH$
+					default:
+						break;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve the array dimension declared after the
+	 * name of a local or a field declaration.
+	 * For example:
+	 *    int i, j[] = null, k[][] = {{}};
+	 *    It should return 0 for i, 1 for j and 2 for k.
+	 * @return int the dimension found
+	 */
+	protected int retrieveExtraDimension(int start, int end) {
+		this.scanner.resetTo(start, end);
+		int dimensions = 0;
+		try {
+			int token;
+			boolean isAnnotation = false;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACKET:
+					case TerminalTokens.TokenNameCOMMENT_BLOCK:
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC:
+					case TerminalTokens.TokenNameCOMMENT_LINE:
+						isAnnotation = false;
+						break;
+					case TerminalTokens.TokenNameAT:
+						isAnnotation = true;
+						break;
+					case TerminalTokens.TokenNameIdentifier:
+						if (!isAnnotation) {
+							return dimensions;
+						}
+						isAnnotation = false;
+						break;
+					case TerminalTokens.TokenNameRBRACKET://166
+						isAnnotation = false;
+						dimensions++;
+						break;
+					default:
+						return dimensions;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return dimensions;
+	}
+
+	protected void retrieveDimensionAndSetPositions(int start, int end, ExtraDimension dim) {
+		this.scanner.resetTo(start, end);
+		int token;
+		boolean startSet = false;
+		try {
+			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
+				switch(token) {
+					case TerminalTokens.TokenNameWHITESPACE:
+						break;
+					case TerminalTokens.TokenNameRBRACKET:
+						int endDim = this.scanner.currentPosition - 1;
+						dim.setSourceRange(start, endDim - start + 1);
+						return;
+					default:
+						if (!startSet) {
+							start = this.scanner.startPosition;
+							startSet = true;
+						}
+						break;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+	protected void retrieveIdentifierAndSetPositions(int start, int end, Name name) {
+		this.scanner.resetTo(start, end);
+		int token;
+		try {
+			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
+				if (token == TerminalTokens.TokenNameIdentifier) {
+					int startName = this.scanner.startPosition;
+					int endName = this.scanner.currentPosition - 1;
+					name.setSourceRange(startName, endName - startName + 1);
+					return;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+
+	/**
+	 * This method is used to retrieve the start position of the block.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveIdentifierEndPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameIdentifier://110
+						return this.scanner.getCurrentTokenEndPosition();
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * retrieves the start and and of new and set the positions of the name
+	 * @param start position to start search
+	 * @param end position to end search
+	 * @param name object where these positions will be updated.
+	 */
+	protected void retrieveInitAndSetPositions(int start, int end, Name name) {
+		this.scanner.resetTo(start, end);
+		int token;
+		try {
+			while((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF)  {
+				if (token == TerminalTokens.TokenNamenew) {
+					int startName = this.scanner.startPosition;
+					int endName = this.scanner.currentPosition;
+					name.setSourceRange(startName, endName - startName);
+					return;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+
+	/**
+	 * This method is used to retrieve position before the next comma or semi-colon.
+	 * @param initializerEnd the given initializer end exclusive
+	 * @return int the position found.
+	 */
+	protected int retrieveEndOfPotentialExtendedDimensions(int initializerEnd, int nameEnd, int end) {
+		this.scanner.resetTo(initializerEnd, end);
+		boolean hasTokens = false;
+		int balance = 0;
+		int pos = initializerEnd > nameEnd ? initializerEnd - 1 : nameEnd;
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				hasTokens = true;
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACE :
+					case TerminalTokens.TokenNameLBRACKET :
+						balance++;
+						break;
+					case TerminalTokens.TokenNameRBRACKET :
+					case TerminalTokens.TokenNameRBRACE :
+						balance --;
+						pos = this.scanner.currentPosition - 1;
+						break;
+					case TerminalTokens.TokenNameCOMMA :
+						if (balance == 0) return pos;
+						// case where a missing closing brace doesn't close an array initializer
+						pos = this.scanner.currentPosition - 1;
+						break;
+					case TerminalTokens.TokenNameSEMICOLON :
+						if (balance == 0) return pos;
+						return -pos;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		// no token, we simply return pos as the right position
+		return hasTokens ? Integer.MIN_VALUE : pos;
+	}
+
+	protected int retrieveProperRightBracketPosition(int bracketNumber, int start) {
+		this.scanner.resetTo(start, this.compilationUnitSourceLength);
+		try {
+			int token, count = 0;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameRBRACKET:
+						count++;
+						if (count == bracketNumber) {
+							return this.scanner.currentPosition - 1;
+						}
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve position before the next right brace or semi-colon.
+	 * @return int the position found.
+	 */
+	protected int retrieveRightBraceOrSemiColonPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameRBRACE :
+						return this.scanner.currentPosition - 1;
+					case TerminalTokens.TokenNameSEMICOLON :
+						return this.scanner.currentPosition - 1;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve position before the next right brace or semi-colon.
+	 * @return int the position found.
+	 */
+	protected int retrieveRightBrace(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameRBRACE :
+						return this.scanner.currentPosition - 1;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve the position of the right bracket.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveRightBracketPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			int balance = 0;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACKET :
+						balance++;
+						break;
+					case TerminalTokens.TokenNameRBRACKET :
+						balance--;
+						if (balance == 0) return this.scanner.currentPosition - 1;
+						break;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve the start position of the block.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveStartBlockPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameLBRACE://110
+						return this.scanner.startPosition;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	/**
+	 * This method is used to retrieve the starting position of the catch keyword.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveStartingCatchPosition(int start, int end) {
+		this.scanner.resetTo(start, end);
+		try {
+			int token;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNamecatch://225
+						return this.scanner.startPosition;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return -1;
+	}
+
+	public void setAST(AST ast) {
+		this.ast = ast;
+		this.docParser = new DocCommentParser(this.ast, this.scanner, this.insideComments);
+	}
+
+	protected void setModifiers(AnnotationTypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+		this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
+		this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
+	}
+
+	protected void setModifiers(AnnotationTypeMemberDeclaration annotationTypeMemberDecl, org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
+		this.scanner.resetTo(annotationTypeMemberDeclaration.declarationSourceStart, annotationTypeMemberDeclaration.sourceStart);
+		this.setModifiers(annotationTypeMemberDecl, annotationTypeMemberDeclaration.annotations, annotationTypeMemberDeclaration.sourceStart);
+	}
+
+	/**
+	 * @param bodyDeclaration
+	 */
+	protected void setModifiers(BodyDeclaration bodyDeclaration, org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations, int modifiersEnd) {
+		this.scanner.tokenizeWhiteSpace = false;
+		try {
+			int token;
+			int indexInAnnotations = 0;
+			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				IExtendedModifier modifier = null;
+				switch(token) {
+					case TerminalTokens.TokenNameabstract:
+						modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamepublic:
+						modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamestatic:
+						modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
+						break;
+					case TerminalTokens.TokenNameprotected:
+						modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
+						break;
+					case TerminalTokens.TokenNameprivate:
+						modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamefinal:
+						modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamenative:
+						modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamesynchronized:
+						modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
+						break;
+					case TerminalTokens.TokenNametransient:
+						modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamevolatile:
+						modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamestrictfp:
+						modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
+						break;
+					case TerminalTokens.TokenNamedefault:
+						modifier = createModifier(Modifier.ModifierKeyword.DEFAULT_KEYWORD);
+						break;
+					case TerminalTokens.TokenNameAT :
+						// we have an annotation
+						if (annotations != null && indexInAnnotations < annotations.length) {
+							org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
+							modifier = convert(annotation);
+							this.scanner.resetTo(annotation.declarationSourceEnd + 1, modifiersEnd);
+						}
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						break;
+					default :
+						// there is some syntax errors in source code
+						break;
+				}
+				if (modifier != null) {
+					bodyDeclaration.modifiers().add(modifier);
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+	}
+
+	protected void setModifiers(EnumDeclaration enumDeclaration, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enumDeclaration2) {
+		this.scanner.resetTo(enumDeclaration2.declarationSourceStart, enumDeclaration2.sourceStart);
+		this.setModifiers(enumDeclaration, enumDeclaration2.annotations, enumDeclaration2.sourceStart);
+	}
+
+	protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				enumConstantDeclaration.internalSetModifiers(fieldDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
+				if (fieldDeclaration.annotations != null) {
+					enumConstantDeclaration.setFlags(enumConstantDeclaration.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceStart);
+				this.setModifiers(enumConstantDeclaration, fieldDeclaration.annotations, fieldDeclaration.sourceStart);
+		}
+	}
+
+	/**
+	 * @param fieldDeclaration
+	 * @param fieldDecl
+	 */
+	protected void setModifiers(FieldDeclaration fieldDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				fieldDeclaration.internalSetModifiers(fieldDecl.modifiers & ExtraCompilerModifiers.AccJustFlag);
+				if (fieldDecl.annotations != null) {
+					fieldDeclaration.setFlags(fieldDeclaration.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(fieldDecl.declarationSourceStart, fieldDecl.sourceStart);
+				this.setModifiers(fieldDeclaration, fieldDecl.annotations, fieldDecl.sourceStart);
+		}
+	}
+
+	/**
+	 * @param initializer
+	 * @param oldInitializer
+	 */
+	protected void setModifiers(Initializer initializer, org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL:
+				initializer.internalSetModifiers(oldInitializer.modifiers & ExtraCompilerModifiers.AccJustFlag);
+				if (oldInitializer.annotations != null) {
+					initializer.setFlags(initializer.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(oldInitializer.declarationSourceStart, oldInitializer.bodyStart);
+				this.setModifiers(initializer, oldInitializer.annotations, oldInitializer.bodyStart);
+		}
+	}
+	/**
+	 * @param methodDecl
+	 * @param methodDeclaration
+	 */
+	protected void setModifiers(MethodDeclaration methodDecl, AbstractMethodDeclaration methodDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				methodDecl.internalSetModifiers(methodDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
+				if (methodDeclaration.annotations != null) {
+					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(methodDeclaration.declarationSourceStart, methodDeclaration.sourceStart);
+				this.setModifiers(methodDecl, methodDeclaration.annotations, methodDeclaration.sourceStart);
+		}
+	}
+
+	/**
+	 * @param variableDecl
+	 * @param argument
+	 */
+	protected void setModifiers(SingleVariableDeclaration variableDecl, Argument argument) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				variableDecl.internalSetModifiers(argument.modifiers & ExtraCompilerModifiers.AccJustFlag);
+				if (argument.annotations != null) {
+					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(argument.declarationSourceStart, argument.sourceStart);
+				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = argument.annotations;
+				int indexInAnnotations = 0;
+				try {
+					int token;
+					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+						IExtendedModifier modifier = null;
+						switch(token) {
+							case TerminalTokens.TokenNameabstract:
+								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamepublic:
+								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestatic:
+								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprotected:
+								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprivate:
+								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamefinal:
+								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamenative:
+								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamesynchronized:
+								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNametransient:
+								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamevolatile:
+								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestrictfp:
+								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameAT :
+								// we have an annotation
+								if (annotations != null && indexInAnnotations < annotations.length) {
+									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
+									modifier = convert(annotation);
+									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
+								}
+								break;
+							case TerminalTokens.TokenNameCOMMENT_BLOCK :
+							case TerminalTokens.TokenNameCOMMENT_LINE :
+							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+								break;
+							default :
+								return;
+						}
+						if (modifier != null) {
+							variableDecl.modifiers().add(modifier);
+						}
+					}
+				} catch(InvalidInputException e) {
+					// ignore
+				}
+		}
+	}
+
+	protected void setModifiers(SingleVariableDeclaration variableDecl, LocalDeclaration localDeclaration) {
+		switch(this.ast.apiLevel) {
+		case AST.JLS2_INTERNAL :
+			variableDecl.internalSetModifiers(localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag);
+			if (localDeclaration.annotations != null) {
+				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
+			}
+			break;
+		default :
+			this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
+			org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
+			int indexInAnnotations = 0;
+			try {
+				int token;
+				while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+					IExtendedModifier modifier = null;
+					switch(token) {
+						case TerminalTokens.TokenNameabstract:
+							modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamepublic:
+							modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamestatic:
+							modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
+							break;
+						case TerminalTokens.TokenNameprotected:
+							modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
+							break;
+						case TerminalTokens.TokenNameprivate:
+							modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamefinal:
+							modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamenative:
+							modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamesynchronized:
+							modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
+							break;
+						case TerminalTokens.TokenNametransient:
+							modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamevolatile:
+							modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
+							break;
+						case TerminalTokens.TokenNamestrictfp:
+							modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
+							break;
+						case TerminalTokens.TokenNameAT :
+							// we have an annotation
+							if (annotations != null && indexInAnnotations < annotations.length) {
+								org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
+								modifier = convert(annotation);
+								this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
+							}
+							break;
+						case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						case TerminalTokens.TokenNameCOMMENT_LINE :
+						case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+							break;
+						default :
+							return;
+					}
+					if (modifier != null) {
+						variableDecl.modifiers().add(modifier);
+					}
+				}
+			} catch(InvalidInputException e) {
+				// ignore
+			}
+		}
+	}
+
+	/**
+	 * @param typeDecl
+	 * @param typeDeclaration
+	 */
+	protected void setModifiers(TypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				int modifiers = typeDeclaration.modifiers;
+				modifiers &= ~ClassFileConstants.AccInterface; // remove AccInterface flags
+				modifiers &= ExtraCompilerModifiers.AccJustFlag;
+				typeDecl.internalSetModifiers(modifiers);
+				if (typeDeclaration.annotations != null) {
+					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(typeDeclaration.declarationSourceStart, typeDeclaration.sourceStart);
+				this.setModifiers(typeDecl, typeDeclaration.annotations, typeDeclaration.sourceStart);
+		}
+	}
+
+	/**
+	 * @param variableDeclarationExpression
+	 * @param localDeclaration
+	 */
+	protected void setModifiers(VariableDeclarationExpression variableDeclarationExpression, LocalDeclaration localDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
+				modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
+				variableDeclarationExpression.internalSetModifiers(modifiers);
+				if (localDeclaration.annotations != null) {
+					variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
+				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
+				int indexInAnnotations = 0;
+				try {
+					int token;
+					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+						IExtendedModifier modifier = null;
+						switch(token) {
+							case TerminalTokens.TokenNameabstract:
+								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamepublic:
+								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestatic:
+								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprotected:
+								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprivate:
+								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamefinal:
+								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamenative:
+								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamesynchronized:
+								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNametransient:
+								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamevolatile:
+								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestrictfp:
+								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameAT :
+								// we have an annotation
+								if (annotations != null && indexInAnnotations < annotations.length) {
+									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
+									modifier = convert(annotation);
+									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
+								}
+								break;
+							case TerminalTokens.TokenNameCOMMENT_BLOCK :
+							case TerminalTokens.TokenNameCOMMENT_LINE :
+							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+								break;
+							default :
+								return;
+						}
+						if (modifier != null) {
+							variableDeclarationExpression.modifiers().add(modifier);
+						}
+					}
+				} catch(InvalidInputException e) {
+					// ignore
+				}
+		}
+	}
+
+	/**
+	 * @param variableDeclarationStatement
+	 * @param localDeclaration
+	 */
+	protected void setModifiers(VariableDeclarationStatement variableDeclarationStatement, LocalDeclaration localDeclaration) {
+		switch(this.ast.apiLevel) {
+			case AST.JLS2_INTERNAL :
+				int modifiers = localDeclaration.modifiers & ExtraCompilerModifiers.AccJustFlag;
+				modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
+				variableDeclarationStatement.internalSetModifiers(modifiers);
+				if (localDeclaration.annotations != null) {
+					variableDeclarationStatement.setFlags(variableDeclarationStatement.getFlags() | ASTNode.MALFORMED);
+				}
+				break;
+			default :
+				this.scanner.resetTo(localDeclaration.declarationSourceStart, localDeclaration.sourceStart);
+				org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = localDeclaration.annotations;
+				int indexInAnnotations = 0;
+				try {
+					int token;
+					while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+						IExtendedModifier modifier = null;
+						switch(token) {
+							case TerminalTokens.TokenNameabstract:
+								modifier = createModifier(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamepublic:
+								modifier = createModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestatic:
+								modifier = createModifier(Modifier.ModifierKeyword.STATIC_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprotected:
+								modifier = createModifier(Modifier.ModifierKeyword.PROTECTED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameprivate:
+								modifier = createModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamefinal:
+								modifier = createModifier(Modifier.ModifierKeyword.FINAL_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamenative:
+								modifier = createModifier(Modifier.ModifierKeyword.NATIVE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamesynchronized:
+								modifier = createModifier(Modifier.ModifierKeyword.SYNCHRONIZED_KEYWORD);
+								break;
+							case TerminalTokens.TokenNametransient:
+								modifier = createModifier(Modifier.ModifierKeyword.TRANSIENT_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamevolatile:
+								modifier = createModifier(Modifier.ModifierKeyword.VOLATILE_KEYWORD);
+								break;
+							case TerminalTokens.TokenNamestrictfp:
+								modifier = createModifier(Modifier.ModifierKeyword.STRICTFP_KEYWORD);
+								break;
+							case TerminalTokens.TokenNameAT :
+								// we have an annotation
+								if (annotations != null && indexInAnnotations < annotations.length) {
+									org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
+									modifier = convert(annotation);
+									this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
+								}
+								break;
+							case TerminalTokens.TokenNameCOMMENT_BLOCK :
+							case TerminalTokens.TokenNameCOMMENT_LINE :
+							case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+								break;
+							default :
+								return;
+						}
+						if (modifier != null) {
+							variableDeclarationStatement.modifiers().add(modifier);
+						}
+					}
+				} catch(InvalidInputException e) {
+					// ignore
+				}
+		}
+	}
+
+	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
+	    int length = typeName.length;
+		final SimpleName firstToken = new SimpleName(this.ast);
+		firstToken.internalSetIdentifier(new String(typeName[0]));
+		firstToken.index = 1;
+		int start0 = (int)(positions[0]>>>32);
+		int start = start0;
+		int end = (int)(positions[0] & 0xFFFFFFFF);
+		firstToken.setSourceRange(start, end - start + 1);
+		final SimpleName secondToken = new SimpleName(this.ast);
+		secondToken.internalSetIdentifier(new String(typeName[1]));
+		secondToken.index = 2;
+		start = (int)(positions[1]>>>32);
+		end = (int)(positions[1] & 0xFFFFFFFF);
+		secondToken.setSourceRange(start, end - start + 1);
+		QualifiedName qualifiedName = new QualifiedName(this.ast);
+		qualifiedName.setQualifier(firstToken);
+		qualifiedName.setName(secondToken);
+		if (this.resolveBindings) {
+			recordNodes(qualifiedName, node);
+			recordPendingNameScopeResolution(qualifiedName);
+			recordNodes(firstToken, node);
+			recordNodes(secondToken, node);
+			recordPendingNameScopeResolution(firstToken);
+			recordPendingNameScopeResolution(secondToken);
+		}
+		qualifiedName.index = 2;
+		qualifiedName.setSourceRange(start0, end - start0 + 1);
+		SimpleName newPart = null;
+		for (int i = 2; i < length; i++) {
+			newPart = new SimpleName(this.ast);
+			newPart.internalSetIdentifier(new String(typeName[i]));
+			newPart.index = i + 1;
+			start = (int)(positions[i]>>>32);
+			end = (int)(positions[i] & 0xFFFFFFFF);
+			newPart.setSourceRange(start,  end - start + 1);
+			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
+			qualifiedName2.setQualifier(qualifiedName);
+			qualifiedName2.setName(newPart);
+			qualifiedName = qualifiedName2;
+			qualifiedName.index = newPart.index;
+			qualifiedName.setSourceRange(start0, end - start0 + 1);
+			if (this.resolveBindings) {
+				recordNodes(qualifiedName, node);
+				recordNodes(newPart, node);
+				recordPendingNameScopeResolution(qualifiedName);
+				recordPendingNameScopeResolution(newPart);
+			}
+		}
+		QualifiedName name = qualifiedName;
+		if (this.resolveBindings) {
+			recordNodes(name, node);
+			recordPendingNameScopeResolution(name);
+		}
+		return name;
+	}
+
+	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, org.eclipse.jdt.internal.compiler.ast.TypeReference node) {
+ 		int length = endingIndex + 1;
+		final SimpleName firstToken = new SimpleName(this.ast);
+		firstToken.internalSetIdentifier(new String(typeName[0]));
+		firstToken.index = 1;
+		int start0 = (int)(positions[0]>>>32);
+		int start = start0;
+		int end = (int) positions[0];
+		firstToken.setSourceRange(start, end - start + 1);
+		final SimpleName secondToken = new SimpleName(this.ast);
+		secondToken.internalSetIdentifier(new String(typeName[1]));
+		secondToken.index = 2;
+		start = (int)(positions[1]>>>32);
+		end = (int) positions[1];
+		secondToken.setSourceRange(start, end - start + 1);
+		QualifiedName qualifiedName = new QualifiedName(this.ast);
+		qualifiedName.setQualifier(firstToken);
+		qualifiedName.setName(secondToken);
+		if (this.resolveBindings) {
+			recordNodes(qualifiedName, node);
+			recordPendingNameScopeResolution(qualifiedName);
+			recordNodes(firstToken, node);
+			recordNodes(secondToken, node);
+			recordPendingNameScopeResolution(firstToken);
+			recordPendingNameScopeResolution(secondToken);
+		}
+		qualifiedName.index = 2;
+		qualifiedName.setSourceRange(start0, end - start0 + 1);
+		SimpleName newPart = null;
+		for (int i = 2; i < length; i++) {
+			newPart = new SimpleName(this.ast);
+			newPart.internalSetIdentifier(new String(typeName[i]));
+			newPart.index = i + 1;
+			start = (int)(positions[i]>>>32);
+			end = (int) positions[i];
+			newPart.setSourceRange(start,  end - start + 1);
+			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
+			qualifiedName2.setQualifier(qualifiedName);
+			qualifiedName2.setName(newPart);
+			qualifiedName = qualifiedName2;
+			qualifiedName.index = newPart.index;
+			qualifiedName.setSourceRange(start0, end - start0 + 1);
+			if (this.resolveBindings) {
+				recordNodes(qualifiedName, node);
+				recordNodes(newPart, node);
+				recordPendingNameScopeResolution(qualifiedName);
+				recordPendingNameScopeResolution(newPart);
+			}
+		}
+        if (newPart == null && this.resolveBindings) {
+            recordNodes(qualifiedName, node);
+            recordPendingNameScopeResolution(qualifiedName);
+        }
+		return qualifiedName;
+	}
+
+	protected void setTypeNameForAnnotation(org.eclipse.jdt.internal.compiler.ast.Annotation compilerAnnotation, Annotation annotation) {
+		TypeReference typeReference = compilerAnnotation.type;
+		if (typeReference instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
+			char[][] tokens = qualifiedTypeReference.tokens;
+			long[] positions = qualifiedTypeReference.sourcePositions;
+			// QualifiedName
+			annotation.setTypeName(setQualifiedNameNameAndSourceRanges(tokens, positions, typeReference));
+		} else {
+			SingleTypeReference singleTypeReference = (SingleTypeReference) typeReference;
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(singleTypeReference.token));
+			int start = singleTypeReference.sourceStart;
+			int end = singleTypeReference.sourceEnd;
+			name.setSourceRange(start, end - start + 1);
+			name.index = 1;
+			annotation.setTypeName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, typeReference);
+			}
+		}
+	}
+
+	protected void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
+		if (extraDimension != 0) {
+			if (type.isArrayType()) {
+				ArrayType arrayType = (ArrayType) type;
+				int remainingDimensions = arrayType.getDimensions() - extraDimension;
+				if (remainingDimensions == 0)  {
+					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
+					Type elementType = arrayType.getElementType();
+					// cut the child loose from its parent (without creating garbage)
+					elementType.setParent(null, null);
+					this.ast.getBindingResolver().updateKey(type, elementType);
+					fieldDeclaration.setType(elementType);
+				} else {
+					int start = type.getStartPosition();
+					ArrayType subarrayType = arrayType;
+					int index = extraDimension;
+					while (index > 0) {
+						subarrayType = (ArrayType) subarrayType.getComponentType();
+						index--;
+					}
+					int end = retrieveProperRightBracketPosition(remainingDimensions, start);
+					subarrayType.setSourceRange(start, end - start + 1);
+					// cut the child loose from its parent (without creating garbage)
+					subarrayType.setParent(null, null);
+					fieldDeclaration.setType(subarrayType);
+					updateInnerPositions(subarrayType, remainingDimensions);
+					this.ast.getBindingResolver().updateKey(type, subarrayType);
+				}
+			} else {
+				fieldDeclaration.setType(type);
+			}
+		} else {
+			if (type.isArrayType()) {
+				// update positions of the component types of the array type
+				int dimensions = ((ArrayType) type).getDimensions();
+				updateInnerPositions(type, dimensions);
+			}
+			fieldDeclaration.setType(type);
+		}
+	}
+
+	protected void setTypeForMethodDeclaration(MethodDeclaration methodDeclaration, Type type, int extraDimension) {
+		if (extraDimension != 0) {
+			if (type.isArrayType()) {
+				ArrayType arrayType = (ArrayType) type;
+				int remainingDimensions = arrayType.getDimensions() - extraDimension;
+				if (remainingDimensions == 0)  {
+					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
+					Type elementType = arrayType.getElementType();
+					// cut the child loose from its parent (without creating garbage)
+					elementType.setParent(null, null);
+					this.ast.getBindingResolver().updateKey(type, elementType);
+					switch(this.ast.apiLevel) {
+						case AST.JLS2_INTERNAL :
+							methodDeclaration.internalSetReturnType(elementType);
+							break;
+						default :
+							methodDeclaration.setReturnType2(elementType);
+						break;
+					}
+				} else {
+					int start = type.getStartPosition();
+					ArrayType subarrayType = arrayType;
+					int index = extraDimension;
+					while (index > 0) {
+						subarrayType = (ArrayType) subarrayType.getComponentType();
+						index--;
+					}
+					int end = retrieveProperRightBracketPosition(remainingDimensions, start);
+					subarrayType.setSourceRange(start, end - start + 1);
+					// cut the child loose from its parent (without creating garbage)
+					subarrayType.setParent(null, null);
+					updateInnerPositions(subarrayType, remainingDimensions);
+					switch(this.ast.apiLevel) {
+						case AST.JLS2_INTERNAL :
+							methodDeclaration.internalSetReturnType(subarrayType);
+							break;
+						default :
+							methodDeclaration.setReturnType2(subarrayType);
+							break;
+					}
+					this.ast.getBindingResolver().updateKey(type, subarrayType);
+				}
+			} else {
+				switch(this.ast.apiLevel) {
+					case AST.JLS2_INTERNAL :
+						methodDeclaration.internalSetReturnType(type);
+						break;
+					default :
+						methodDeclaration.setReturnType2(type);
+					break;
+				}
+			}
+		} else {
+			switch(this.ast.apiLevel) {
+				case AST.JLS2_INTERNAL :
+					methodDeclaration.internalSetReturnType(type);
+					break;
+				default :
+					methodDeclaration.setReturnType2(type);
+				break;
+			}
+		}
+	}
+
+	protected void setTypeForMethodDeclaration(AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration, Type type, int extraDimension) {
+		annotationTypeMemberDeclaration.setType(type);
+	}
+
+	protected void setTypeForSingleVariableDeclaration(SingleVariableDeclaration singleVariableDeclaration, Type type, int extraDimension) {
+		if (extraDimension != 0) {
+			if (type.isArrayType()) {
+				ArrayType arrayType = (ArrayType) type;
+				int remainingDimensions = arrayType.getDimensions() - extraDimension;
+				if (remainingDimensions == 0)  {
+					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
+					Type elementType = arrayType.getElementType();
+					// cut the child loose from its parent (without creating garbage)
+					elementType.setParent(null, null);
+					this.ast.getBindingResolver().updateKey(type, elementType);
+					singleVariableDeclaration.setType(elementType);
+				} else {
+					int start = type.getStartPosition();
+					ArrayType subarrayType = arrayType;
+					int index = extraDimension;
+					while (index > 0) {
+						subarrayType = (ArrayType) subarrayType.getComponentType();
+						index--;
+					}
+					int end = retrieveProperRightBracketPosition(remainingDimensions, start);
+					subarrayType.setSourceRange(start, end - start + 1);
+					// cut the child loose from its parent (without creating garbage)
+					subarrayType.setParent(null, null);
+					updateInnerPositions(subarrayType, remainingDimensions);
+					singleVariableDeclaration.setType(subarrayType);
+					this.ast.getBindingResolver().updateKey(type, subarrayType);
+				}
+			} else {
+				singleVariableDeclaration.setType(type);
+			}
+		} else {
+			singleVariableDeclaration.setType(type);
+		}
+	}
+
+	protected void setTypeForVariableDeclarationExpression(VariableDeclarationExpression variableDeclarationExpression, Type type, int extraDimension) {
+		if (extraDimension != 0) {
+			if (type.isArrayType()) {
+				ArrayType arrayType = (ArrayType) type;
+				int remainingDimensions = arrayType.getDimensions() - extraDimension;
+				if (remainingDimensions == 0)  {
+					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
+					Type elementType = arrayType.getElementType();
+					// cut the child loose from its parent (without creating garbage)
+					elementType.setParent(null, null);
+					this.ast.getBindingResolver().updateKey(type, elementType);
+					variableDeclarationExpression.setType(elementType);
+				} else {
+					int start = type.getStartPosition();
+					ArrayType subarrayType = arrayType;
+					int index = extraDimension;
+					while (index > 0) {
+						subarrayType = (ArrayType) subarrayType.getComponentType();
+						index--;
+					}
+					int end = retrieveProperRightBracketPosition(remainingDimensions, start);
+					subarrayType.setSourceRange(start, end - start + 1);
+					// cut the child loose from its parent (without creating garbage)
+					subarrayType.setParent(null, null);
+					updateInnerPositions(subarrayType, remainingDimensions);
+					variableDeclarationExpression.setType(subarrayType);
+					this.ast.getBindingResolver().updateKey(type, subarrayType);
+				}
+			} else {
+				variableDeclarationExpression.setType(type);
+			}
+		} else {
+			variableDeclarationExpression.setType(type);
+		}
+	}
+
+	protected void setTypeForVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement, Type type, int extraDimension) {
+		if (extraDimension != 0) {
+			if (type.isArrayType()) {
+				ArrayType arrayType = (ArrayType) type;
+				int remainingDimensions = arrayType.getDimensions() - extraDimension;
+				if (remainingDimensions == 0)  {
+					// the dimensions are after the name so the type of the fieldDeclaration is a simpleType
+					Type elementType = arrayType.getElementType();
+					// cut the child loose from its parent (without creating garbage)
+					elementType.setParent(null, null);
+					this.ast.getBindingResolver().updateKey(type, elementType);
+					variableDeclarationStatement.setType(elementType);
+				} else {
+					int start = type.getStartPosition();
+					ArrayType subarrayType = arrayType;
+					int index = extraDimension;
+					while (index > 0) {
+						subarrayType = (ArrayType) subarrayType.getComponentType();
+						index--;
+					}
+					int end = retrieveProperRightBracketPosition(remainingDimensions, start);
+					subarrayType.setSourceRange(start, end - start + 1);
+					// cut the child loose from its parent (without creating garbage)
+					subarrayType.setParent(null, null);
+					updateInnerPositions(subarrayType, remainingDimensions);
+					variableDeclarationStatement.setType(subarrayType);
+					this.ast.getBindingResolver().updateKey(type, subarrayType);
+				}
+			} else {
+				variableDeclarationStatement.setType(type);
+			}
+		} else {
+			variableDeclarationStatement.setType(type);
+		}
+	}
+
+	protected void updateInnerPositions(Type type, int dimensions) {
+		if (dimensions > 1) {
+			// need to set positions for intermediate array type see 42839
+			int start = type.getStartPosition();
+			Type currentComponentType = ((ArrayType) type).getComponentType();
+			int searchedDimension = dimensions - 1;
+			int rightBracketEndPosition = start;
+			while (currentComponentType.isArrayType()) {
+				rightBracketEndPosition = retrieveProperRightBracketPosition(searchedDimension, start);
+				currentComponentType.setSourceRange(start, rightBracketEndPosition - start + 1);
+				currentComponentType = ((ArrayType) currentComponentType).getComponentType();
+				searchedDimension--;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
new file mode 100644
index 0000000..f33c5e2
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -0,0 +1,2597 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Concrete superclass and default implementation of an AST subtree matcher.
+ * <p>
+ * For example, to compute whether two ASTs subtrees are structurally
+ * isomorphic, use <code>n1.subtreeMatch(new ASTMatcher(), n2)</code> where
+ * <code>n1</code> and <code>n2</code> are the AST root nodes of the subtrees.
+ * </p>
+ * <p>
+ * For each different concrete AST node type <i>T</i> there is a
+ * <code>public boolean match(<i>T</i> node, Object other)</code> method
+ * that matches the given node against another object (typically another
+ * AST node, although this is not essential). The default implementations
+ * provided by this class tests whether the other object is a node of the
+ * same type with structurally isomorphic child subtrees. For nodes with
+ * list-valued properties, the child nodes within the list are compared in
+ * order. For nodes with multiple properties, the child nodes are compared
+ * in the order that most closely corresponds to the lexical reading order
+ * of the source program. For instance, for a type declaration node, the
+ * child ordering is: name, superclass, superinterfaces, and body
+ * declarations.
+ * </p>
+ * <p>
+ * Subclasses may override (extend or reimplement) some or all of the
+ * <code>match</code> methods in order to define more specialized subtree
+ * matchers.
+ * </p>
+ *
+ * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(ASTMatcher, Object)
+ * @since 2.0
+ */
+public class ASTMatcher {
+
+	/**
+	 * Indicates whether doc tags should be matched.
+	 * @since 3.0
+	 */
+	private boolean matchDocTags;
+
+	/**
+	 * Creates a new AST matcher instance.
+	 * <p>
+	 * For backwards compatibility, the matcher ignores tag
+	 * elements below doc comments by default. Use
+	 * {@link #ASTMatcher(boolean) ASTMatcher(true)}
+	 * for a matcher that compares doc tags by default.
+	 * </p>
+	 */
+	public ASTMatcher() {
+		this(false);
+	}
+
+	/**
+	 * Creates a new AST matcher instance.
+	 *
+	 * @param matchDocTags <code>true</code> if doc comment tags are
+	 * to be compared by default, and <code>false</code> otherwise
+	 * @see #match(Javadoc,Object)
+	 * @since 3.0
+	 */
+	public ASTMatcher(boolean matchDocTags) {
+		this.matchDocTags = matchDocTags;
+	}
+
+	/**
+	 * Returns whether the given lists of AST nodes match pair wise according
+	 * to <code>ASTNode.subtreeMatch</code>.
+	 * <p>
+	 * Note that this is a convenience method, useful for writing recursive
+	 * subtree matchers.
+	 * </p>
+	 *
+	 * @param list1 the first list of AST nodes
+	 *    (element type: {@link ASTNode})
+	 * @param list2 the second list of AST nodes
+	 *    (element type: {@link ASTNode})
+	 * @return <code>true</code> if the lists have the same number of elements
+	 *    and match pair-wise according to {@link ASTNode#subtreeMatch(ASTMatcher, Object) ASTNode.subtreeMatch}
+	 * @see ASTNode#subtreeMatch(ASTMatcher matcher, Object other)
+	 */
+	public final boolean safeSubtreeListMatch(List list1, List list2) {
+		int size1 = list1.size();
+		int size2 = list2.size();
+		if (size1 != size2) {
+			return false;
+		}
+		for (Iterator it1 = list1.iterator(), it2 = list2.iterator(); it1.hasNext();) {
+			ASTNode n1 = (ASTNode) it1.next();
+			ASTNode n2 = (ASTNode) it2.next();
+			if (!n1.subtreeMatch(this, n2)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given nodes match according to
+	 * <code>AST.subtreeMatch</code>. Returns <code>false</code> if one or
+	 * the other of the nodes are <code>null</code>. Returns <code>true</code>
+	 * if both nodes are <code>null</code>.
+	 * <p>
+	 * Note that this is a convenience method, useful for writing recursive
+	 * subtree matchers.
+	 * </p>
+	 *
+	 * @param node1 the first AST node, or <code>null</code>; must be an
+	 *    instance of <code>ASTNode</code>
+	 * @param node2 the second AST node, or <code>null</code>; must be an
+	 *    instance of <code>ASTNode</code>
+	 * @return <code>true</code> if the nodes match according
+	 *    to <code>AST.subtreeMatch</code> or both are <code>null</code>, and
+	 *    <code>false</code> otherwise
+	 * @see ASTNode#subtreeMatch(ASTMatcher, Object)
+	 */
+	public final boolean safeSubtreeMatch(Object node1, Object node2) {
+		if (node1 == null && node2 == null) {
+			return true;
+		}
+		if (node1 == null || node2 == null) {
+			return false;
+		}
+		// N.B. call subtreeMatch even node1==node2!=null
+		return ((ASTNode) node1).subtreeMatch(this, node2);
+	}
+
+	/**
+	 * Returns whether the given objects are equal according to
+	 * <code>equals</code>. Returns <code>false</code> if either
+	 * node is <code>null</code>.
+	 *
+	 * @param o1 the first object, or <code>null</code>
+	 * @param o2 the second object, or <code>null</code>
+	 * @return <code>true</code> if the nodes are equal according to
+	 *    <code>equals</code> or both <code>null</code>, and
+	 *    <code>false</code> otherwise
+	 */
+	public static boolean safeEquals(Object o1, Object o2) {
+		if (o1 == o2) {
+			return true;
+		}
+		if (o1 == null || o2 == null) {
+			return false;
+		}
+		return o1.equals(o2);
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(AnnotationTypeDeclaration node, Object other) {
+		if (!(other instanceof AnnotationTypeDeclaration)) {
+			return false;
+		}
+		AnnotationTypeDeclaration o = (AnnotationTypeDeclaration) other;
+		// node type added in JLS3 - ignore old JLS2-style modifiers
+		return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeListMatch(node.modifiers(), o.modifiers())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(AnnotationTypeMemberDeclaration node, Object other) {
+		if (!(other instanceof AnnotationTypeMemberDeclaration)) {
+			return false;
+		}
+		AnnotationTypeMemberDeclaration o = (AnnotationTypeMemberDeclaration) other;
+		// node type added in JLS3 - ignore old JLS2-style modifiers
+		return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeListMatch(node.modifiers(), o.modifiers())
+				&& safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeMatch(node.getDefault(), o.getDefault()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(AnonymousClassDeclaration node, Object other) {
+		if (!(other instanceof AnonymousClassDeclaration)) {
+			return false;
+		}
+		AnonymousClassDeclaration o = (AnonymousClassDeclaration) other;
+		return safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ArrayAccess node, Object other) {
+		if (!(other instanceof ArrayAccess)) {
+			return false;
+		}
+		ArrayAccess o = (ArrayAccess) other;
+		return (
+			safeSubtreeMatch(node.getArray(), o.getArray())
+				&& safeSubtreeMatch(node.getIndex(), o.getIndex()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ArrayCreation node, Object other) {
+		if (!(other instanceof ArrayCreation)) {
+			return false;
+		}
+		ArrayCreation o = (ArrayCreation) other;
+		return (
+			safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeListMatch(node.dimensions(), o.dimensions())
+				&& safeSubtreeMatch(node.getInitializer(), o.getInitializer()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ArrayInitializer node, Object other) {
+		if (!(other instanceof ArrayInitializer)) {
+			return false;
+		}
+		ArrayInitializer o = (ArrayInitializer) other;
+		return safeSubtreeListMatch(node.expressions(), o.expressions());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ArrayType node, Object other) {
+		if (!(other instanceof ArrayType)) {
+			return false;
+		}
+		ArrayType o = (ArrayType) other;
+		int level = node.getAST().apiLevel;
+		return safeSubtreeMatch(node.getComponentType(), o.getComponentType())
+				&& (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true);
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(AssertStatement node, Object other) {
+		if (!(other instanceof AssertStatement)) {
+			return false;
+		}
+		AssertStatement o = (AssertStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getMessage(), o.getMessage()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(Assignment node, Object other) {
+		if (!(other instanceof Assignment)) {
+			return false;
+		}
+		Assignment o = (Assignment) other;
+		return (
+			node.getOperator().equals(o.getOperator())
+				&& safeSubtreeMatch(node.getLeftHandSide(), o.getLeftHandSide())
+				&& safeSubtreeMatch(node.getRightHandSide(), o.getRightHandSide()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(Block node, Object other) {
+		if (!(other instanceof Block)) {
+			return false;
+		}
+		Block o = (Block) other;
+		return safeSubtreeListMatch(node.statements(), o.statements());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type. Subclasses may override
+	 * this method as needed.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(BlockComment node, Object other) {
+		if (!(other instanceof BlockComment)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(BooleanLiteral node, Object other) {
+		if (!(other instanceof BooleanLiteral)) {
+			return false;
+		}
+		BooleanLiteral o = (BooleanLiteral) other;
+		return node.booleanValue() == o.booleanValue();
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(BreakStatement node, Object other) {
+		if (!(other instanceof BreakStatement)) {
+			return false;
+		}
+		BreakStatement o = (BreakStatement) other;
+		return safeSubtreeMatch(node.getLabel(), o.getLabel());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(CastExpression node, Object other) {
+		if (!(other instanceof CastExpression)) {
+			return false;
+		}
+		CastExpression o = (CastExpression) other;
+		return (
+			safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeMatch(node.getExpression(), o.getExpression()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(CatchClause node, Object other) {
+		if (!(other instanceof CatchClause)) {
+			return false;
+		}
+		CatchClause o = (CatchClause) other;
+		return (
+			safeSubtreeMatch(node.getException(), o.getException())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(CharacterLiteral node, Object other) {
+		if (!(other instanceof CharacterLiteral)) {
+			return false;
+		}
+		CharacterLiteral o = (CharacterLiteral) other;
+		return safeEquals(node.getEscapedValue(), o.getEscapedValue());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ClassInstanceCreation node, Object other) {
+		if (!(other instanceof ClassInstanceCreation)) {
+			return false;
+		}
+		ClassInstanceCreation o = (ClassInstanceCreation) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (!safeSubtreeMatch(node.internalGetName(), o.internalGetName())) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
+				return false;
+			}
+			if (!safeSubtreeMatch(node.getType(), o.getType())) {
+				return false;
+			}
+		}
+		return
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.arguments(), o.arguments())
+				&& safeSubtreeMatch(
+					node.getAnonymousClassDeclaration(),
+					o.getAnonymousClassDeclaration());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(CompilationUnit node, Object other) {
+		if (!(other instanceof CompilationUnit)) {
+			return false;
+		}
+		CompilationUnit o = (CompilationUnit) other;
+		return (
+			safeSubtreeMatch(node.getPackage(), o.getPackage())
+				&& safeSubtreeListMatch(node.imports(), o.imports())
+				&& safeSubtreeListMatch(node.types(), o.types()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ConditionalExpression node, Object other) {
+		if (!(other instanceof ConditionalExpression)) {
+			return false;
+		}
+		ConditionalExpression o = (ConditionalExpression) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getThenExpression(), o.getThenExpression())
+				&& safeSubtreeMatch(node.getElseExpression(), o.getElseExpression()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ConstructorInvocation node, Object other) {
+		if (!(other instanceof ConstructorInvocation)) {
+			return false;
+		}
+		ConstructorInvocation o = (ConstructorInvocation) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
+				return false;
+			}
+		}
+		return safeSubtreeListMatch(node.arguments(), o.arguments());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ContinueStatement node, Object other) {
+		if (!(other instanceof ContinueStatement)) {
+			return false;
+		}
+		ContinueStatement o = (ContinueStatement) other;
+		return safeSubtreeMatch(node.getLabel(), o.getLabel());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(CreationReference node, Object other) {
+		if (!(other instanceof CreationReference)) {
+			return false;
+		}
+		CreationReference o = (CreationReference) other;
+		return (
+			safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeListMatch(node.typeArguments(), o.typeArguments()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(DoStatement node, Object other) {
+		if (!(other instanceof DoStatement)) {
+			return false;
+		}
+		DoStatement o = (DoStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(EmptyStatement node, Object other) {
+		if (!(other instanceof EmptyStatement)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(EnhancedForStatement node, Object other) {
+		if (!(other instanceof EnhancedForStatement)) {
+			return false;
+		}
+		EnhancedForStatement o = (EnhancedForStatement) other;
+		return (
+			safeSubtreeMatch(node.getParameter(), o.getParameter())
+				&& safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(EnumConstantDeclaration node, Object other) {
+		if (!(other instanceof EnumConstantDeclaration)) {
+			return false;
+		}
+		EnumConstantDeclaration o = (EnumConstantDeclaration) other;
+		return (
+			safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeListMatch(node.modifiers(), o.modifiers())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.arguments(), o.arguments())
+				&& safeSubtreeMatch(
+					node.getAnonymousClassDeclaration(),
+					o.getAnonymousClassDeclaration()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(EnumDeclaration node, Object other) {
+		if (!(other instanceof EnumDeclaration)) {
+			return false;
+		}
+		EnumDeclaration o = (EnumDeclaration) other;
+		return (
+			safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeListMatch(node.modifiers(), o.modifiers())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())
+				&& safeSubtreeListMatch(node.enumConstants(), o.enumConstants())
+				&& safeSubtreeListMatch(
+					node.bodyDeclarations(),
+					o.bodyDeclarations()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(ExpressionMethodReference node, Object other) {
+		if (!(other instanceof ExpressionMethodReference)) {
+			return false;
+		}
+		ExpressionMethodReference o = (ExpressionMethodReference) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ExpressionStatement node, Object other) {
+		if (!(other instanceof ExpressionStatement)) {
+			return false;
+		}
+		ExpressionStatement o = (ExpressionStatement) other;
+		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(ExtraDimension node, Object other) {
+		if (!(other instanceof ExtraDimension)) {
+			return false;
+		}
+		ExtraDimension o = (ExtraDimension) other;
+		return safeSubtreeListMatch(node.annotations(), o.annotations());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(FieldAccess node, Object other) {
+		if (!(other instanceof FieldAccess)) {
+			return false;
+		}
+		FieldAccess o = (FieldAccess) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(FieldDeclaration node, Object other) {
+		if (!(other instanceof FieldDeclaration)) {
+			return false;
+		}
+		FieldDeclaration o = (FieldDeclaration) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (node.getModifiers() != o.getModifiers()) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
+				return false;
+			}
+		}
+		return
+			safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+			&& safeSubtreeMatch(node.getType(), o.getType())
+			&& safeSubtreeListMatch(node.fragments(), o.fragments());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ForStatement node, Object other) {
+		if (!(other instanceof ForStatement)) {
+			return false;
+		}
+		ForStatement o = (ForStatement) other;
+		return (
+			safeSubtreeListMatch(node.initializers(), o.initializers())
+				&& safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.updaters(), o.updaters())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(IfStatement node, Object other) {
+		if (!(other instanceof IfStatement)) {
+			return false;
+		}
+		IfStatement o = (IfStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getThenStatement(), o.getThenStatement())
+				&& safeSubtreeMatch(node.getElseStatement(), o.getElseStatement()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ImportDeclaration node, Object other) {
+		if (!(other instanceof ImportDeclaration)) {
+			return false;
+		}
+		ImportDeclaration o = (ImportDeclaration) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (node.isStatic() != o.isStatic()) {
+				return false;
+			}
+		}
+		return (
+			safeSubtreeMatch(node.getName(), o.getName())
+				&& node.isOnDemand() == o.isOnDemand());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(InfixExpression node, Object other) {
+		if (!(other instanceof InfixExpression)) {
+			return false;
+		}
+		InfixExpression o = (InfixExpression) other;
+		// be careful not to trigger lazy creation of extended operand lists
+		if (node.hasExtendedOperands() && o.hasExtendedOperands()) {
+			if (!safeSubtreeListMatch(node.extendedOperands(), o.extendedOperands())) {
+				return false;
+			}
+		}
+		if (node.hasExtendedOperands() != o.hasExtendedOperands()) {
+			return false;
+		}
+		return (
+			node.getOperator().equals(o.getOperator())
+				&& safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
+				&& safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(Initializer node, Object other) {
+		if (!(other instanceof Initializer)) {
+			return false;
+		}
+		Initializer o = (Initializer) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (node.getModifiers() != o.getModifiers()) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
+				return false;
+			}
+		}
+		return (
+				safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(InstanceofExpression node, Object other) {
+		if (!(other instanceof InstanceofExpression)) {
+			return false;
+		}
+		InstanceofExpression o = (InstanceofExpression) other;
+		return (
+				safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
+				&& safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(IntersectionType node, Object other) {
+		if (!(other instanceof IntersectionType)) {
+			return false;
+		}
+		IntersectionType o = (IntersectionType) other;
+		return safeSubtreeListMatch(node.types(), o.types());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * Unlike other node types, the behavior of the default
+	 * implementation is controlled by a constructor-supplied
+	 * parameter  {@link #ASTMatcher(boolean) ASTMatcher(boolean)}
+	 * which is <code>false</code> if not specified.
+	 * When this parameter is <code>true</code>, the implementation
+	 * tests whether the other object is also a <code>Javadoc</code>
+	 * with structurally isomorphic child subtrees; the comment string
+	 * (<code>Javadoc.getComment()</code>) is ignored.
+	 * Conversely, when the parameter is <code>false</code>, the
+	 * implementation tests whether the other object is also a
+	 * <code>Javadoc</code> with exactly the same comment string;
+	 * the tag elements ({@link Javadoc#tags() Javadoc.tags} are
+	 * ignored. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @see #ASTMatcher()
+	 * @see #ASTMatcher(boolean)
+	 */
+	public boolean match(Javadoc node, Object other) {
+		if (!(other instanceof Javadoc)) {
+			return false;
+		}
+		Javadoc o = (Javadoc) other;
+		if (this.matchDocTags) {
+			return safeSubtreeListMatch(node.tags(), o.tags());
+		} else {
+			return compareDeprecatedComment(node, o);
+		}
+	}
+
+	/**
+	 * Return whether the deprecated comment strings of the given java doc are equals.
+	 * <p>
+	 * Note the only purpose of this method is to hide deprecated warnings.
+	 * @deprecated mark deprecated to hide deprecated usage
+	 */
+	private boolean compareDeprecatedComment(Javadoc first, Javadoc second) {
+		if (first.getAST().apiLevel == AST.JLS2_INTERNAL) {
+			return safeEquals(first.getComment(), second.getComment());
+		} else {
+			return true;
+		}
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(LabeledStatement node, Object other) {
+		if (!(other instanceof LabeledStatement)) {
+			return false;
+		}
+		LabeledStatement o = (LabeledStatement) other;
+		return (
+			safeSubtreeMatch(node.getLabel(), o.getLabel())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 * 
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(LambdaExpression node, Object other) {
+		if (!(other instanceof LambdaExpression)) {
+			return false;
+		}
+		LambdaExpression o = (LambdaExpression) other;
+		return	(node.hasParentheses() == o.hasParentheses())
+				&& safeSubtreeListMatch(node.parameters(), o.parameters())
+				&& safeSubtreeMatch(node.getBody(), o.getBody());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type. Subclasses may override
+	 * this method as needed.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(LineComment node, Object other) {
+		if (!(other instanceof LineComment)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(MarkerAnnotation node, Object other) {
+		if (!(other instanceof MarkerAnnotation)) {
+			return false;
+		}
+		MarkerAnnotation o = (MarkerAnnotation) other;
+		return safeSubtreeMatch(node.getTypeName(), o.getTypeName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(MemberRef node, Object other) {
+		if (!(other instanceof MemberRef)) {
+			return false;
+		}
+		MemberRef o = (MemberRef) other;
+		return (
+				safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(MemberValuePair node, Object other) {
+		if (!(other instanceof MemberValuePair)) {
+			return false;
+		}
+		MemberValuePair o = (MemberValuePair) other;
+		return (safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeMatch(node.getValue(), o.getValue()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(MethodRef node, Object other) {
+		if (!(other instanceof MethodRef)) {
+			return false;
+		}
+		MethodRef o = (MethodRef) other;
+		return (
+				safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+		        && safeSubtreeListMatch(node.parameters(), o.parameters()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(MethodRefParameter node, Object other) {
+		if (!(other instanceof MethodRefParameter)) {
+			return false;
+		}
+		MethodRefParameter o = (MethodRefParameter) other;
+		int level = node.getAST().apiLevel;
+		if (level >= AST.JLS3_INTERNAL) {
+			if (node.isVarargs() != o.isVarargs()) {
+				return false;
+			}
+		}
+		return (
+				safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 * <p>
+	 * Note that extra array dimensions are compared since they are an
+	 * important part of the method declaration.
+	 * </p>
+	 * <p>
+	 * Note that the method return types are compared even for constructor
+	 * declarations.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(MethodDeclaration node, Object other) {
+		if (!(other instanceof MethodDeclaration)) {
+			return false;
+		}
+		MethodDeclaration o = (MethodDeclaration) other;
+		int level = node.getAST().apiLevel;
+		return node.isConstructor() == o.isConstructor()
+				&& safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& (level >= AST.JLS3_INTERNAL
+						? safeSubtreeListMatch(node.modifiers(), o.modifiers())
+								&& safeSubtreeListMatch(node.typeParameters(), o.typeParameters())
+								// n.b. compare return type even for constructors
+								&& safeSubtreeMatch(node.getReturnType2(), o.getReturnType2())
+						: node.getModifiers() == o.getModifiers()
+								// n.b. compare return type even for constructors
+								&& safeSubtreeMatch(node.internalGetReturnType(), o.internalGetReturnType()))
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& (level >= AST.JLS8
+						? safeSubtreeMatch(node.getReceiverType(), o.getReceiverType())
+								&& safeSubtreeMatch(node.getReceiverQualifier(), o.getReceiverQualifier())
+						: true)
+				&& safeSubtreeListMatch(node.parameters(), o.parameters())
+				&& (level >= AST.JLS8
+						? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
+								&& safeSubtreeListMatch(node.thrownExceptionTypes(), o.thrownExceptionTypes())
+						: node.getExtraDimensions() == o.getExtraDimensions()
+								&& safeSubtreeListMatch(node.internalThrownExceptions(), o.internalThrownExceptions()))
+				&& safeSubtreeMatch(node.getBody(), o.getBody());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(MethodInvocation node, Object other) {
+		if (!(other instanceof MethodInvocation)) {
+			return false;
+		}
+		MethodInvocation o = (MethodInvocation) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
+				return false;
+			}
+		}
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.arguments(), o.arguments()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(Modifier node, Object other) {
+		if (!(other instanceof Modifier)) {
+			return false;
+		}
+		Modifier o = (Modifier) other;
+		return (node.getKeyword() == o.getKeyword());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(NormalAnnotation node, Object other) {
+		if (!(other instanceof NormalAnnotation)) {
+			return false;
+		}
+		NormalAnnotation o = (NormalAnnotation) other;
+		return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
+					&& safeSubtreeListMatch(node.values(), o.values()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(NullLiteral node, Object other) {
+		if (!(other instanceof NullLiteral)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(NumberLiteral node, Object other) {
+		if (!(other instanceof NumberLiteral)) {
+			return false;
+		}
+		NumberLiteral o = (NumberLiteral) other;
+		return safeEquals(node.getToken(), o.getToken());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(PackageDeclaration node, Object other) {
+		if (!(other instanceof PackageDeclaration)) {
+			return false;
+		}
+		PackageDeclaration o = (PackageDeclaration) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())) {
+				return false;
+			}
+			if (!safeSubtreeListMatch(node.annotations(), o.annotations())) {
+				return false;
+			}
+		}
+		return safeSubtreeMatch(node.getName(), o.getName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(PackageQualifiedType node, Object other) {
+		if (!(other instanceof PackageQualifiedType)) {
+			return false;
+		}
+		PackageQualifiedType o = (PackageQualifiedType) other;
+		return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeListMatch(node.annotations(), o.annotations())
+				&& safeSubtreeMatch(node.getName(), o.getName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(ParameterizedType node, Object other) {
+		if (!(other instanceof ParameterizedType)) {
+			return false;
+		}
+		ParameterizedType o = (ParameterizedType) other;
+		return safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeListMatch(node.typeArguments(), o.typeArguments());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ParenthesizedExpression node, Object other) {
+		if (!(other instanceof ParenthesizedExpression)) {
+			return false;
+		}
+		ParenthesizedExpression o = (ParenthesizedExpression) other;
+		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(PostfixExpression node, Object other) {
+		if (!(other instanceof PostfixExpression)) {
+			return false;
+		}
+		PostfixExpression o = (PostfixExpression) other;
+		return (
+			node.getOperator().equals(o.getOperator())
+				&& safeSubtreeMatch(node.getOperand(), o.getOperand()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(PrefixExpression node, Object other) {
+		if (!(other instanceof PrefixExpression)) {
+			return false;
+		}
+		PrefixExpression o = (PrefixExpression) other;
+		return (
+			node.getOperator().equals(o.getOperator())
+				&& safeSubtreeMatch(node.getOperand(), o.getOperand()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(PrimitiveType node, Object other) {
+		if (!(other instanceof PrimitiveType)) {
+			return false;
+		}
+		PrimitiveType o = (PrimitiveType) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
+				&& node.getPrimitiveTypeCode() == o.getPrimitiveTypeCode();
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(QualifiedName node, Object other) {
+		if (!(other instanceof QualifiedName)) {
+			return false;
+		}
+		QualifiedName o = (QualifiedName) other;
+		return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeMatch(node.getName(), o.getName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(QualifiedType node, Object other) {
+		if (!(other instanceof QualifiedType)) {
+			return false;
+		}
+		QualifiedType o = (QualifiedType) other;
+		int level = node.getAST().apiLevel;
+		return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
+				&& safeSubtreeMatch(node.getName(), o.getName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ReturnStatement node, Object other) {
+		if (!(other instanceof ReturnStatement)) {
+			return false;
+		}
+		ReturnStatement o = (ReturnStatement) other;
+		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SimpleName node, Object other) {
+		if (!(other instanceof SimpleName)) {
+			return false;
+		}
+		SimpleName o = (SimpleName) other;
+		return node.getIdentifier().equals(o.getIdentifier());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SimpleType node, Object other) {
+		if (!(other instanceof SimpleType)) {
+			return false;
+		}
+		SimpleType o = (SimpleType) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
+				&& safeSubtreeMatch(node.getName(), o.getName());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(SingleMemberAnnotation node, Object other) {
+		if (!(other instanceof SingleMemberAnnotation)) {
+			return false;
+		}
+		SingleMemberAnnotation o = (SingleMemberAnnotation) other;
+		return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
+				&& safeSubtreeMatch(node.getValue(), o.getValue()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 * <p>
+	 * Note that extra array dimensions and the variable arity flag
+	 * are compared since they are both important parts of the declaration.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SingleVariableDeclaration node, Object other) {
+		if (!(other instanceof SingleVariableDeclaration)) {
+			return false;
+		}
+		SingleVariableDeclaration o = (SingleVariableDeclaration) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS3_INTERNAL
+						? safeSubtreeListMatch(node.modifiers(), o.modifiers())
+						: node.getModifiers() == o.getModifiers())
+				&& safeSubtreeMatch(node.getType(), o.getType())
+				&& (level >= AST.JLS8 && node.isVarargs()
+						? safeSubtreeListMatch(node.varargsAnnotations(), o.varargsAnnotations())
+						: true)
+				&& (level >= AST.JLS3_INTERNAL
+						? node.isVarargs() == o.isVarargs()
+						: true)
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& ((level >= AST.JLS8)
+						? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
+						: node.getExtraDimensions() == o.getExtraDimensions())
+				&& safeSubtreeMatch(node.getInitializer(), o.getInitializer());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(StringLiteral node, Object other) {
+		if (!(other instanceof StringLiteral)) {
+			return false;
+		}
+		StringLiteral o = (StringLiteral) other;
+		return safeEquals(node.getEscapedValue(), o.getEscapedValue());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SuperConstructorInvocation node, Object other) {
+		if (!(other instanceof SuperConstructorInvocation)) {
+			return false;
+		}
+		SuperConstructorInvocation o = (SuperConstructorInvocation) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
+				return false;
+			}
+		}
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.arguments(), o.arguments()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SuperFieldAccess node, Object other) {
+		if (!(other instanceof SuperFieldAccess)) {
+			return false;
+		}
+		SuperFieldAccess o = (SuperFieldAccess) other;
+		return (
+			safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeMatch(node.getQualifier(), o.getQualifier()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SuperMethodInvocation node, Object other) {
+		if (!(other instanceof SuperMethodInvocation)) {
+			return false;
+		}
+		SuperMethodInvocation o = (SuperMethodInvocation) other;
+		if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
+				return false;
+			}
+		}
+		return (
+			safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.arguments(), o.arguments()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 *   
+	 *   @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(SuperMethodReference node, Object other) {
+		if (!(other instanceof SuperMethodReference)) {
+			return false;
+		}
+		SuperMethodReference o = (SuperMethodReference) other;
+		return (safeSubtreeMatch(node.getQualifier(), o.getQualifier())
+				&& safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SwitchCase node, Object other) {
+		if (!(other instanceof SwitchCase)) {
+			return false;
+		}
+		SwitchCase o = (SwitchCase) other;
+		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SwitchStatement node, Object other) {
+		if (!(other instanceof SwitchStatement)) {
+			return false;
+		}
+		SwitchStatement o = (SwitchStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.statements(), o.statements()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(SynchronizedStatement node, Object other) {
+		if (!(other instanceof SynchronizedStatement)) {
+			return false;
+		}
+		SynchronizedStatement o = (SynchronizedStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(TagElement node, Object other) {
+		if (!(other instanceof TagElement)) {
+			return false;
+		}
+		TagElement o = (TagElement) other;
+		return (
+				safeEquals(node.getTagName(), o.getTagName())
+				&& safeSubtreeListMatch(node.fragments(), o.fragments()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.0
+	 */
+	public boolean match(TextElement node, Object other) {
+		if (!(other instanceof TextElement)) {
+			return false;
+		}
+		TextElement o = (TextElement) other;
+		return safeEquals(node.getText(), o.getText());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ThisExpression node, Object other) {
+		if (!(other instanceof ThisExpression)) {
+			return false;
+		}
+		ThisExpression o = (ThisExpression) other;
+		return safeSubtreeMatch(node.getQualifier(), o.getQualifier());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(ThrowStatement node, Object other) {
+		if (!(other instanceof ThrowStatement)) {
+			return false;
+		}
+		ThrowStatement o = (ThrowStatement) other;
+		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(TryStatement node, Object other) {
+		if (!(other instanceof TryStatement)) {
+			return false;
+		}
+		TryStatement o = (TryStatement) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS4_INTERNAL ? safeSubtreeListMatch(node.resources(), o.resources()) : true)
+				&& safeSubtreeMatch(node.getBody(), o.getBody())
+				&& safeSubtreeListMatch(node.catchClauses(), o.catchClauses())
+				&& safeSubtreeMatch(node.getFinally(), o.getFinally());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(TypeDeclaration node, Object other) {
+		if (!(other instanceof TypeDeclaration)) {
+			return false;
+		}
+		TypeDeclaration o = (TypeDeclaration) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (node.getModifiers() != o.getModifiers()) {
+				return false;
+			}
+			if (!safeSubtreeMatch(node.internalGetSuperclass(), o.internalGetSuperclass())) {
+				return false;
+			}
+			if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o.internalSuperInterfaces())) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
+				return false;
+			}
+			if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
+				return false;
+			}
+			if (!safeSubtreeMatch(node.getSuperclassType(), o.getSuperclassType())) {
+				return false;
+			}
+			if (!safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())) {
+				return false;
+			}
+		}
+		return (
+				(node.isInterface() == o.isInterface())
+				&& safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(TypeDeclarationStatement node, Object other) {
+		if (!(other instanceof TypeDeclarationStatement)) {
+			return false;
+		}
+		TypeDeclarationStatement o = (TypeDeclarationStatement) other;
+		return safeSubtreeMatch(node.getDeclaration(), o.getDeclaration());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(TypeLiteral node, Object other) {
+		if (!(other instanceof TypeLiteral)) {
+			return false;
+		}
+		TypeLiteral o = (TypeLiteral) other;
+		return safeSubtreeMatch(node.getType(), o.getType());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean match(TypeMethodReference node, Object other) {
+		if (!(other instanceof TypeMethodReference)) {
+			return false;
+		}
+		TypeMethodReference o = (TypeMethodReference) other;
+		return (
+			safeSubtreeMatch(node.getType(), o.getType())
+				&& safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
+				&& safeSubtreeMatch(node.getName(), o.getName()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(TypeParameter node, Object other) {
+		if (!(other instanceof TypeParameter)) {
+			return false;
+		}
+		TypeParameter o = (TypeParameter) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
+				&& safeSubtreeMatch(node.getName(), o.getName())
+				&& safeSubtreeListMatch(node.typeBounds(), o.typeBounds());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.7.1
+	 */
+	public boolean match(UnionType node, Object other) {
+		if (!(other instanceof UnionType)) {
+			return false;
+		}
+		UnionType o = (UnionType) other;
+		return safeSubtreeListMatch(node.types(),	o.types());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(VariableDeclarationExpression node, Object other) {
+		if (!(other instanceof VariableDeclarationExpression)) {
+			return false;
+		}
+		VariableDeclarationExpression o = (VariableDeclarationExpression) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (node.getModifiers() != o.getModifiers()) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
+				return false;
+			}
+		}
+		return safeSubtreeMatch(node.getType(), o.getType())
+			&& safeSubtreeListMatch(node.fragments(), o.fragments());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 * <p>
+	 * Note that extra array dimensions are compared since they are an
+	 * important part of the type of the variable.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(VariableDeclarationFragment node, Object other) {
+		if (!(other instanceof VariableDeclarationFragment)) {
+			return false;
+		}
+		VariableDeclarationFragment o = (VariableDeclarationFragment) other;
+		int level = node.getAST().apiLevel;
+		return safeSubtreeMatch(node.getName(), o.getName())
+				&& (level >= AST.JLS8
+						? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
+						: node.getExtraDimensions() == o.getExtraDimensions())
+				&& safeSubtreeMatch(node.getInitializer(), o.getInitializer());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(VariableDeclarationStatement node, Object other) {
+		if (!(other instanceof VariableDeclarationStatement)) {
+			return false;
+		}
+		VariableDeclarationStatement o = (VariableDeclarationStatement) other;
+		int level = node.getAST().apiLevel;
+		if (level == AST.JLS2_INTERNAL) {
+			if (node.getModifiers() != o.getModifiers()) {
+				return false;
+			}
+		}
+		if (level >= AST.JLS3_INTERNAL) {
+			if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
+				return false;
+			}
+		}
+		return safeSubtreeMatch(node.getType(), o.getType())
+			&& safeSubtreeListMatch(node.fragments(), o.fragments());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 */
+	public boolean match(WhileStatement node, Object other) {
+		if (!(other instanceof WhileStatement)) {
+			return false;
+		}
+		WhileStatement o = (WhileStatement) other;
+		return (
+			safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeMatch(node.getBody(), o.getBody()));
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 *
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.1
+	 */
+	public boolean match(WildcardType node, Object other) {
+		if (!(other instanceof WildcardType)) {
+			return false;
+		}
+		WildcardType o = (WildcardType) other;
+		int level = node.getAST().apiLevel;
+		return (level >= AST.JLS8 ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
+				&& node.isUpperBound() == o.isUpperBound()
+				&& safeSubtreeMatch(node.getBound(), o.getBound());
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
new file mode 100644
index 0000000..5885d33
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -0,0 +1,2975 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.core.dom.NaiveASTFlattener;
+
+/**
+ * Abstract superclass of all Abstract Syntax Tree (AST) node types.
+ * <p>
+ * An AST node represents a Java source code construct, such
+ * as a name, type, expression, statement, or declaration.
+ * </p>
+ * <p>
+ * Each AST node belongs to a unique AST instance, called the owning AST.
+ * The children of an AST node always have the same owner as their parent node.
+ * If a node from one AST is to be added to a different AST, the subtree must
+ * be cloned first to ensure that the added nodes have the correct owning AST.
+ * </p>
+ * <p>
+ * When an AST node is part of an AST, it has a unique parent node.
+ * Clients can navigate upwards, from child to parent, as well as downwards,
+ * from parent to child. Newly created nodes are unparented. When an
+ * unparented node is set as a child of a node (using a
+ * <code>set<i>CHILD</i></code> method), its parent link is set automatically
+ * and the parent link of the former child is set to <code>null</code>.
+ * For nodes with properties that include a list of children (for example,
+ * <code>Block</code> whose <code>statements</code> property is a list
+ * of statements), adding or removing an element to/for the list property
+ * automatically updates the parent links. These lists support the
+ * <code>List.set</code> method; however, the constraint that the same
+ * node cannot appear more than once means that this method cannot be used
+ * to swap elements without first removing the node.
+ * </p>
+ * <p>
+ * ASTs must not contain cycles. All operations that could create a cycle
+ * detect this possibility and fail.
+ * </p>
+ * <p>
+ * ASTs do not contain "holes" (missing subtrees). If a node is required to
+ * have a certain property, a syntactically plausible initial value is
+ * always supplied.
+ * </p>
+ * <p>
+ * The hierarchy of AST node types has some convenient groupings marked
+ * by abstract superclasses:
+ * <ul>
+ * <li>expressions - <code>Expression</code></li>
+ * <li>names - <code>Name</code> (a sub-kind of expression)</li>
+ * <li>statements - <code>Statement</code></li>
+ * <li>types - <code>Type</code></li>
+ * <li>type body declarations - <code>BodyDeclaration</code></li>
+ * </ul>
+ * </p>
+ * <p>
+ * Abstract syntax trees may be hand constructed by clients, using the
+ * <code>new<i>TYPE</i></code> factory methods (see <code>AST</code>) to
+ * create new nodes, and the various <code>set<i>CHILD</i></code> methods
+ * to connect them together.
+ * </p>
+ * <p>
+ * The class {@link ASTParser} parses a string
+ * containing a Java source code and returns an abstract syntax tree
+ * for it. The resulting nodes carry source ranges relating the node back to
+ * the original source characters. The source range covers the construct
+ * as a whole.
+ * </p>
+ * <p>
+ * Each AST node carries bit flags, which may convey additional information about
+ * the node. For instance, the parser uses a flag to indicate a syntax error.
+ * Newly created nodes have no flags set.
+ * </p>
+ * <p>
+ * Each AST node is capable of carrying an open-ended collection of
+ * client-defined properties. Newly created nodes have none.
+ * <code>getProperty</code> and <code>setProperty</code> are used to access
+ * these properties.
+ * </p>
+ * <p>
+ * AST nodes are thread-safe for readers provided there are no active writers.
+ * If one thread is modifying an AST, including creating new nodes or cloning
+ * existing ones, it is <b>not</b> safe for another thread to read, visit,
+ * write, create, or clone <em>any</em> of the nodes on the same AST.
+ * When synchronization is required, consider using the common AST
+ * object that owns the node; that is, use
+ * <code>synchronize (node.getAST()) {...}</code>.
+ * </p>
+ * <p>
+ * ASTs also support the visitor pattern; see the class <code>ASTVisitor</code>
+ * for details. The <code>NodeFinder</code> class can be used to find a specific
+ * node inside a tree.
+ * </p>
+ * <p>
+ * Compilation units created by <code>ASTParser</code> from a
+ * source document can be serialized after arbitrary modifications
+ * with minimal loss of original formatting. See
+ * {@link CompilationUnit#recordModifications()} for details.
+ * See also {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite} for
+ * an alternative way to describe and serialize changes to a
+ * read-only AST.
+ * </p>
+ *
+ * @see ASTParser
+ * @see ASTVisitor
+ * @see NodeFinder
+ * @since 2.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class ASTNode {
+	/*
+	 * ATTENTION: When doing anything to the ASTNode hierarchy, do not try to
+	 * reinvent the wheel.
+	 * 
+	 * Look out for precedents with
+	 * - the same structural property type
+	 * - for child node properties: the same optionality (can be null / lazy initialization blurbs and impl.)
+	 * - the same declaring node type kind (abstract supertype or concrete type)
+	 * - a similar history (added in JLSx API, below JLSx only, replaced by {@link #xx})
+	 * ..., and copy what was done there. Most of the code and
+	 * Javadoc in this package should look like it was created by a code generator.
+	 * 
+	 * In subclasses of ASTNode, order properties by order of occurrence in source.
+	 * In general classes that list all AST node types, order alphabetically.  
+	 */
+
+	/*
+	 * INSTRUCTIONS FOR ADDING NEW CONCRETE AST NODE TYPES
+	 *
+	 * There are several things that need to be changed when a
+	 * new concrete AST node type (call it "FooBar") is added:
+	 *
+	 * 1. Create the FooBar AST node type class.
+	 * The most effective way to do this is to copy a similar
+	 * existing concrete node class to get a template that
+     * includes all the framework methods that must be implemented.
+	 *
+	 * 2. Add node type constant ASTNode.FOO_BAR.
+	 * Node constants are numbered consecutively. Add the
+	 * constant after the existing ones.
+	 *
+	 * 3. Add entry to ASTNode.nodeClassForType(int).
+	 *
+	 * 4. Add AST.newFooBar() factory method.
+	 *
+	 * 5. Add ASTVisitor.visit(FooBar) and endVisit(FooBar) methods. Same for DefaultASTVisitor.
+	 *
+	 * 6. Add ASTMatcher.match(FooBar,Object) method.
+	 *
+	 * 7. Ensure that SimpleName.isDeclaration() covers FooBar
+	 * nodes if required.
+	 *
+	 * 8. Add NaiveASTFlattener.visit(FooBar) method to illustrate
+	 * how these nodes should be serialized.
+	 *
+	 * 9. Update the AST test suites (ASTVisitorTest, etc.)
+	 *
+	 * The next steps are to update AST.parse* to start generating
+	 * the new type of nodes, and ASTRewrite to serialize them back out.
+	 */
+
+	/*
+	 * INSTRUCTIONS FOR ADDING A NEW PROPERTY TO AN AST NODE TYPE
+	 * 
+	 * For concrete node types, use e.g. properties of SimpleName or ClassInstanceCreation
+	 * as templates:
+	 * 
+	 * 1. Copy/paste the field, property descriptor, and getter/setter.
+	 * 
+	 * 2. Adjust everything to the new property name and type. In the field's
+	 * Javadoc, properly document default value, initialization, and applicable
+	 * API levels.
+	 * 
+	 * 3. Add/remove @since tags as necessary.
+	 * 
+	 * 4. Search for references to the members in the template, and add similar
+	 * references in corresponding places for the new property.
+	 * 
+	 * 
+	 * For abstract node types, use AbstractTypeDeclaration as a template:
+	 * 
+	 * 1. Same steps as above, but take extra care to copy and adjust the
+	 * *internal*() methods as well. 
+	 * 
+	 * 2. Search for references to the members in the template, and add similar
+	 * references in corresponding places for the new property (e.g. property
+	 * descriptor in each leaf type).
+	 */
+
+	/*
+	 * INSTRUCTIONS FOR REPLACING/DEPRECATING A PROPERTY OF AN AST NODE
+	 * 
+	 * To replace a simple property with a child list property, see e.g. how
+	 * SingleVariableDeclaration replaced MODIFIERS_PROPERTY with
+	 * MODIFIERS2_PROPERTY.
+	 * 
+	 * 1. Reuse the old property id.
+	 * 
+	 * 2. Deprecate all references to the old property, except for the old
+	 * getter, which should compute the value from the new property in
+	 * later API levels.
+	 * 
+	 * To completely replace a property, see how ClassInstanceCreation replaced
+	 * NAME_PROPERTY with TYPE_PROPERTY.
+	 */
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>AnonymousClassDeclaration</code>.
+	 * @see AnonymousClassDeclaration
+	 */
+	public static final int ANONYMOUS_CLASS_DECLARATION = 1;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ArrayAccess</code>.
+	 * @see ArrayAccess
+	 */
+	public static final int ARRAY_ACCESS = 2;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ArrayCreation</code>.
+	 * @see ArrayCreation
+	 */
+	public static final int ARRAY_CREATION = 3;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ArrayInitializer</code>.
+	 * @see ArrayInitializer
+	 */
+	public static final int ARRAY_INITIALIZER = 4;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ArrayType</code>.
+	 * @see ArrayType
+	 */
+	public static final int ARRAY_TYPE = 5;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>AssertStatement</code>.
+	 * @see AssertStatement
+	 */
+	public static final int ASSERT_STATEMENT = 6;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>Assignment</code>.
+	 * @see Assignment
+	 */
+	public static final int ASSIGNMENT = 7;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>Block</code>.
+	 * @see Block
+	 */
+	public static final int BLOCK = 8;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>BooleanLiteral</code>.
+	 * @see BooleanLiteral
+	 */
+	public static final int BOOLEAN_LITERAL = 9;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>BreakStatement</code>.
+	 * @see BreakStatement
+	 */
+	public static final int BREAK_STATEMENT = 10;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>CastExpression</code>.
+	 * @see CastExpression
+	 */
+	public static final int CAST_EXPRESSION = 11;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>CatchClause</code>.
+	 * @see CatchClause
+	 */
+	public static final int CATCH_CLAUSE = 12;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>CharacterLiteral</code>.
+	 * @see CharacterLiteral
+	 */
+	public static final int CHARACTER_LITERAL = 13;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ClassInstanceCreation</code>.
+	 * @see ClassInstanceCreation
+	 */
+	public static final int CLASS_INSTANCE_CREATION = 14;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>CompilationUnit</code>.
+	 * @see CompilationUnit
+	 */
+	public static final int COMPILATION_UNIT = 15;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ConditionalExpression</code>.
+	 * @see ConditionalExpression
+	 */
+	public static final int CONDITIONAL_EXPRESSION = 16;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ConstructorInvocation</code>.
+	 * @see ConstructorInvocation
+	 */
+	public static final int CONSTRUCTOR_INVOCATION = 17;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ContinueStatement</code>.
+	 * @see ContinueStatement
+	 */
+	public static final int CONTINUE_STATEMENT = 18;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>DoStatement</code>.
+	 * @see DoStatement
+	 */
+	public static final int DO_STATEMENT = 19;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>EmptyStatement</code>.
+	 * @see EmptyStatement
+	 */
+	public static final int EMPTY_STATEMENT = 20;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ExpressionStatement</code>.
+	 * @see ExpressionStatement
+	 */
+	public static final int EXPRESSION_STATEMENT = 21;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>FieldAccess</code>.
+	 * @see FieldAccess
+	 */
+	public static final int FIELD_ACCESS = 22;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>FieldDeclaration</code>.
+	 * @see FieldDeclaration
+	 */
+	public static final int FIELD_DECLARATION = 23;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ForStatement</code>.
+	 * @see ForStatement
+	 */
+	public static final int FOR_STATEMENT = 24;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>IfStatement</code>.
+	 * @see IfStatement
+	 */
+	public static final int IF_STATEMENT = 25;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ImportDeclaration</code>.
+	 * @see ImportDeclaration
+	 */
+	public static final int IMPORT_DECLARATION = 26;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>InfixExpression</code>.
+	 * @see InfixExpression
+	 */
+	public static final int INFIX_EXPRESSION = 27;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>Initializer</code>.
+	 * @see Initializer
+	 */
+	public static final int INITIALIZER = 28;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>Javadoc</code>.
+	 * @see Javadoc
+	 */
+	public static final int JAVADOC = 29;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>LabeledStatement</code>.
+	 * @see LabeledStatement
+	 */
+	public static final int LABELED_STATEMENT = 30;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MethodDeclaration</code>.
+	 * @see MethodDeclaration
+	 */
+	public static final int METHOD_DECLARATION = 31;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MethodInvocation</code>.
+	 * @see MethodInvocation
+	 */
+	public static final int METHOD_INVOCATION = 32;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>NullLiteral</code>.
+	 * @see NullLiteral
+	 */
+	public static final int NULL_LITERAL = 33;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>NumberLiteral</code>.
+	 * @see NumberLiteral
+	 */
+	public static final int NUMBER_LITERAL = 34;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>PackageDeclaration</code>.
+	 * @see PackageDeclaration
+	 */
+	public static final int PACKAGE_DECLARATION = 35;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ParenthesizedExpression</code>.
+	 * @see ParenthesizedExpression
+	 */
+	public static final int PARENTHESIZED_EXPRESSION = 36;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>PostfixExpression</code>.
+	 * @see PostfixExpression
+	 */
+	public static final int POSTFIX_EXPRESSION = 37;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>PrefixExpression</code>.
+	 * @see PrefixExpression
+	 */
+	public static final int PREFIX_EXPRESSION = 38;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>PrimitiveType</code>.
+	 * @see PrimitiveType
+	 */
+	public static final int PRIMITIVE_TYPE = 39;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>QualifiedName</code>.
+	 * @see QualifiedName
+	 */
+	public static final int QUALIFIED_NAME = 40;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ReturnStatement</code>.
+	 * @see ReturnStatement
+	 */
+	public static final int RETURN_STATEMENT = 41;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SimpleName</code>.
+	 * @see SimpleName
+	 */
+	public static final int SIMPLE_NAME = 42;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SimpleType</code>.
+	 * @see SimpleType
+	 */
+	public static final int SIMPLE_TYPE = 43;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SingleVariableDeclaration</code>.
+	 * @see SingleVariableDeclaration
+	 */
+	public static final int SINGLE_VARIABLE_DECLARATION = 44;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>StringLiteral</code>.
+	 * @see StringLiteral
+	 */
+	public static final int STRING_LITERAL = 45;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SuperConstructorInvocation</code>.
+	 * @see SuperConstructorInvocation
+	 */
+	public static final int SUPER_CONSTRUCTOR_INVOCATION = 46;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SuperFieldAccess</code>.
+	 * @see SuperFieldAccess
+	 */
+	public static final int SUPER_FIELD_ACCESS = 47;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SuperMethodInvocation</code>.
+	 * @see SuperMethodInvocation
+	 */
+	public static final int SUPER_METHOD_INVOCATION = 48;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SwitchCase</code>.
+	 * @see SwitchCase
+	 */
+	public static final int SWITCH_CASE = 49;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SwitchStatement</code>.
+	 * @see SwitchStatement
+	 */
+	public static final int SWITCH_STATEMENT = 50;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SynchronizedStatement</code>.
+	 * @see SynchronizedStatement
+	 */
+	public static final int SYNCHRONIZED_STATEMENT = 51;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ThisExpression</code>.
+	 * @see ThisExpression
+	 */
+	public static final int THIS_EXPRESSION = 52;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ThrowStatement</code>.
+	 * @see ThrowStatement
+	 */
+	public static final int THROW_STATEMENT = 53;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TryStatement</code>.
+	 * @see TryStatement
+	 */
+	public static final int TRY_STATEMENT = 54;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TypeDeclaration</code>.
+	 * @see TypeDeclaration
+	 */
+	public static final int TYPE_DECLARATION = 55;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TypeDeclarationStatement</code>.
+	 * @see TypeDeclarationStatement
+	 */
+	public static final int TYPE_DECLARATION_STATEMENT = 56;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TypeLiteral</code>.
+	 * @see TypeLiteral
+	 */
+	public static final int TYPE_LITERAL = 57;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>VariableDeclarationExpression</code>.
+	 * @see VariableDeclarationExpression
+	 */
+	public static final int VARIABLE_DECLARATION_EXPRESSION = 58;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>VariableDeclarationFragment</code>.
+	 * @see VariableDeclarationFragment
+	 */
+	public static final int VARIABLE_DECLARATION_FRAGMENT = 59;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>VariableDeclarationStatement</code>.
+	 * @see VariableDeclarationStatement
+	 */
+	public static final int VARIABLE_DECLARATION_STATEMENT = 60;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>WhileStatement</code>.
+	 * @see WhileStatement
+	 */
+	public static final int WHILE_STATEMENT = 61;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>InstanceofExpression</code>.
+	 * @see InstanceofExpression
+	 */
+	public static final int INSTANCEOF_EXPRESSION = 62;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>LineComment</code>.
+	 * @see LineComment
+	 * @since 3.0
+	 */
+	public static final int LINE_COMMENT = 63;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>BlockComment</code>.
+	 * @see BlockComment
+	 * @since 3.0
+	 */
+	public static final int BLOCK_COMMENT = 64;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TagElement</code>.
+	 * @see TagElement
+	 * @since 3.0
+	 */
+	public static final int TAG_ELEMENT = 65;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TextElement</code>.
+	 * @see TextElement
+	 * @since 3.0
+	 */
+	public static final int TEXT_ELEMENT = 66;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MemberRef</code>.
+	 * @see MemberRef
+	 * @since 3.0
+	 */
+	public static final int MEMBER_REF = 67;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MethodRef</code>.
+	 * @see MethodRef
+	 * @since 3.0
+	 */
+	public static final int METHOD_REF = 68;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MethodRefParameter</code>.
+	 * @see MethodRefParameter
+	 * @since 3.0
+	 */
+	public static final int METHOD_REF_PARAMETER = 69;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>EnhancedForStatement</code>.
+	 * @see EnhancedForStatement
+	 * @since 3.1
+	 */
+	public static final int ENHANCED_FOR_STATEMENT = 70;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>EnumDeclaration</code>.
+	 * @see EnumDeclaration
+	 * @since 3.1
+	 */
+	public static final int ENUM_DECLARATION = 71;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>EnumConstantDeclaration</code>.
+	 * @see EnumConstantDeclaration
+	 * @since 3.1
+	 */
+	public static final int ENUM_CONSTANT_DECLARATION = 72;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TypeParameter</code>.
+	 * @see TypeParameter
+	 * @since 3.1
+	 */
+	public static final int TYPE_PARAMETER = 73;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ParameterizedType</code>.
+	 * @see ParameterizedType
+	 * @since 3.1
+	 */
+	public static final int PARAMETERIZED_TYPE = 74;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>QualifiedType</code>.
+	 * @see QualifiedType
+	 * @since 3.1
+	 */
+	public static final int QUALIFIED_TYPE = 75;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>WildcardType</code>.
+	 * @see WildcardType
+	 * @since 3.1
+	 */
+	public static final int WILDCARD_TYPE = 76;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>NormalAnnotation</code>.
+	 * @see NormalAnnotation
+	 * @since 3.1
+	 */
+	public static final int NORMAL_ANNOTATION = 77;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MarkerAnnotation</code>.
+	 * @see MarkerAnnotation
+	 * @since 3.1
+	 */
+	public static final int MARKER_ANNOTATION = 78;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SingleMemberAnnotation</code>.
+	 * @see SingleMemberAnnotation
+	 * @since 3.1
+	 */
+	public static final int SINGLE_MEMBER_ANNOTATION = 79;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>MemberValuePair</code>.
+	 * @see MemberValuePair
+	 * @since 3.1
+	 */
+	public static final int MEMBER_VALUE_PAIR = 80;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>AnnotationTypeDeclaration</code>.
+	 * @see AnnotationTypeDeclaration
+	 * @since 3.1
+	 */
+	public static final int ANNOTATION_TYPE_DECLARATION = 81;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>AnnotationTypeMemberDeclaration</code>.
+	 * @see AnnotationTypeMemberDeclaration
+	 * @since 3.1
+	 */
+	public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>Modifier</code>.
+	 * @see Modifier
+	 * @since 3.1
+	 */
+	public static final int MODIFIER = 83;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>UnionType</code>.
+	 * @see UnionType
+	 * @since 3.7.1
+	 */
+	public static final int UNION_TYPE = 84;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ExtraDimension</code>.
+	 *
+	 * @see ExtraDimension
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int EXTRA_DIMENSION = 85;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>LambdaExpression</code>.
+	 * @see LambdaExpression
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int LAMBDA_EXPRESSION = 86;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>IntersectionType</code>.
+	 *
+	 * @see IntersectionType
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int INTERSECTION_TYPE = 87;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>QualifiedType</code>.
+	 * @see QualifiedType
+	 * @since 3.9 BETA_JAV8
+	 */
+	public static final int PACKAGE_QUALIFIED_TYPE = 88;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>CreationReference</code>.
+	 * @see CreationReference
+	 * @since 3.9 BETA_JAV8
+	 */
+	public static final int CREATION_REFERENCE = 89;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>ExpressionMethodReference</code>.
+	 * @see ExpressionMethodReference
+	 * @since 3.9 BETA_JAV8
+	 */
+	public static final int EXPRESSION_METHOD_REFERENCE = 90;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SuperMethhodReference</code>.
+	 * @see SuperMethodReference
+	 * @since 3.9 BETA_JAV8
+	 */
+	public static final int SUPER_METHOD_REFERENCE = 91;
+
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>TypeMethodReference</code>.
+	 * @see TypeMethodReference
+	 * @since 3.9 BETA_JAV8
+	 */
+	public static final int TYPE_METHOD_REFERENCE = 92;
+
+	/**
+	 * Returns the node class for the corresponding node type.
+	 *
+	 * @param nodeType AST node type
+	 * @return the corresponding <code>ASTNode</code> subclass
+	 * @exception IllegalArgumentException if <code>nodeType</code> is
+	 * not a legal AST node type
+	 * @see #getNodeType()
+	 * @since 3.0
+	 */
+	public static Class nodeClassForType(int nodeType) {
+		switch (nodeType) {
+			case ANNOTATION_TYPE_DECLARATION :
+				return AnnotationTypeDeclaration.class;
+			case ANNOTATION_TYPE_MEMBER_DECLARATION :
+				return AnnotationTypeMemberDeclaration.class;
+			case ANONYMOUS_CLASS_DECLARATION :
+				return AnonymousClassDeclaration.class;
+			case ARRAY_ACCESS :
+				return ArrayAccess.class;
+			case ARRAY_CREATION :
+				return ArrayCreation.class;
+			case ARRAY_INITIALIZER :
+				return ArrayInitializer.class;
+			case ARRAY_TYPE :
+				return ArrayType.class;
+			case ASSERT_STATEMENT :
+				return AssertStatement.class;
+			case ASSIGNMENT :
+				return Assignment.class;
+			case BLOCK :
+				return Block.class;
+			case BLOCK_COMMENT :
+				return BlockComment.class;
+			case BOOLEAN_LITERAL :
+				return BooleanLiteral.class;
+			case BREAK_STATEMENT :
+				return BreakStatement.class;
+			case CAST_EXPRESSION :
+				return CastExpression.class;
+			case CATCH_CLAUSE :
+				return CatchClause.class;
+			case CHARACTER_LITERAL :
+				return CharacterLiteral.class;
+			case CLASS_INSTANCE_CREATION :
+				return ClassInstanceCreation.class;
+			case COMPILATION_UNIT :
+				return CompilationUnit.class;
+			case CONDITIONAL_EXPRESSION :
+				return ConditionalExpression.class;
+			case CONSTRUCTOR_INVOCATION :
+				return ConstructorInvocation.class;
+			case CONTINUE_STATEMENT :
+				return ContinueStatement.class;
+			case CREATION_REFERENCE :
+				return CreationReference.class;
+			case UNION_TYPE :
+				return UnionType.class;
+			case DO_STATEMENT :
+				return DoStatement.class;
+			case EMPTY_STATEMENT :
+				return EmptyStatement.class;
+			case ENHANCED_FOR_STATEMENT :
+				return EnhancedForStatement.class;
+			case ENUM_CONSTANT_DECLARATION :
+				return EnumConstantDeclaration.class;
+			case ENUM_DECLARATION :
+				return EnumDeclaration.class;
+			case EXPRESSION_METHOD_REFERENCE :
+				return ExpressionMethodReference.class;
+			case EXPRESSION_STATEMENT :
+				return ExpressionStatement.class;
+			case EXTRA_DIMENSION:
+				return ExtraDimension.class;
+			case FIELD_ACCESS :
+				return FieldAccess.class;
+			case FIELD_DECLARATION :
+				return FieldDeclaration.class;
+			case FOR_STATEMENT :
+				return ForStatement.class;
+			case IF_STATEMENT :
+				return IfStatement.class;
+			case IMPORT_DECLARATION :
+				return ImportDeclaration.class;
+			case INFIX_EXPRESSION :
+				return InfixExpression.class;
+			case INITIALIZER :
+				return Initializer.class;
+			case INSTANCEOF_EXPRESSION :
+				return InstanceofExpression.class;
+			case INTERSECTION_TYPE:
+				return IntersectionType.class;
+			case JAVADOC :
+				return Javadoc.class;
+			case LABELED_STATEMENT :
+				return LabeledStatement.class;
+			case LAMBDA_EXPRESSION :
+				return LambdaExpression.class;
+			case LINE_COMMENT :
+				return LineComment.class;
+			case MARKER_ANNOTATION :
+				return MarkerAnnotation.class;
+			case MEMBER_REF :
+				return MemberRef.class;
+			case MEMBER_VALUE_PAIR :
+				return MemberValuePair.class;
+			case METHOD_DECLARATION :
+				return MethodDeclaration.class;
+			case METHOD_INVOCATION :
+				return MethodInvocation.class;
+			case METHOD_REF :
+				return MethodRef.class;
+			case METHOD_REF_PARAMETER :
+				return MethodRefParameter.class;
+			case MODIFIER :
+				return Modifier.class;
+			case NORMAL_ANNOTATION :
+				return NormalAnnotation.class;
+			case NULL_LITERAL :
+				return NullLiteral.class;
+			case NUMBER_LITERAL :
+				return NumberLiteral.class;
+			case PACKAGE_DECLARATION :
+				return PackageDeclaration.class;
+			case PACKAGE_QUALIFIED_TYPE :
+				return PackageQualifiedType.class;
+			case PARAMETERIZED_TYPE :
+				return ParameterizedType.class;
+			case PARENTHESIZED_EXPRESSION :
+				return ParenthesizedExpression.class;
+			case POSTFIX_EXPRESSION :
+				return PostfixExpression.class;
+			case PREFIX_EXPRESSION :
+				return PrefixExpression.class;
+			case PRIMITIVE_TYPE :
+				return PrimitiveType.class;
+			case QUALIFIED_NAME :
+				return QualifiedName.class;
+			case QUALIFIED_TYPE :
+				return QualifiedType.class;
+			case RETURN_STATEMENT :
+				return ReturnStatement.class;
+			case SIMPLE_NAME :
+				return SimpleName.class;
+			case SIMPLE_TYPE :
+				return SimpleType.class;
+			case SINGLE_MEMBER_ANNOTATION :
+				return SingleMemberAnnotation.class;
+			case SINGLE_VARIABLE_DECLARATION :
+				return SingleVariableDeclaration.class;
+			case STRING_LITERAL :
+				return StringLiteral.class;
+			case SUPER_CONSTRUCTOR_INVOCATION :
+				return SuperConstructorInvocation.class;
+			case SUPER_FIELD_ACCESS :
+				return SuperFieldAccess.class;
+			case SUPER_METHOD_INVOCATION :
+				return SuperMethodInvocation.class;
+			case SUPER_METHOD_REFERENCE :
+				return SuperMethodReference.class;
+			case SWITCH_CASE:
+				return SwitchCase.class;
+			case SWITCH_STATEMENT :
+				return SwitchStatement.class;
+			case SYNCHRONIZED_STATEMENT :
+				return SynchronizedStatement.class;
+			case TAG_ELEMENT :
+				return TagElement.class;
+			case TEXT_ELEMENT :
+				return TextElement.class;
+			case THIS_EXPRESSION :
+				return ThisExpression.class;
+			case THROW_STATEMENT :
+				return ThrowStatement.class;
+			case TRY_STATEMENT :
+				return TryStatement.class;
+			case TYPE_DECLARATION :
+				return TypeDeclaration.class;
+			case TYPE_DECLARATION_STATEMENT :
+				return TypeDeclarationStatement.class;
+			case TYPE_METHOD_REFERENCE :
+				return TypeMethodReference.class;
+			case TYPE_LITERAL :
+				return TypeLiteral.class;
+			case TYPE_PARAMETER :
+				return TypeParameter.class;
+			case VARIABLE_DECLARATION_EXPRESSION :
+				return VariableDeclarationExpression.class;
+			case VARIABLE_DECLARATION_FRAGMENT :
+				return VariableDeclarationFragment.class;
+			case VARIABLE_DECLARATION_STATEMENT :
+				return VariableDeclarationStatement.class;
+			case WHILE_STATEMENT :
+				return WhileStatement.class;
+			case WILDCARD_TYPE :
+				return WildcardType.class;
+		}
+		throw new IllegalArgumentException();
+	}
+
+	/**
+	 * Owning AST.
+     * <p>
+     * N.B. This is a private field, but declared as package-visible
+     * for more efficient access from inner classes.
+     * </p>
+	 */
+	final AST ast;
+
+	/**
+	 * Parent AST node, or <code>null</code> if this node is a root.
+	 * Initially <code>null</code>.
+	 */
+	private ASTNode parent = null;
+
+	/**
+	 * An unmodifiable empty map (used to implement <code>properties()</code>).
+	 */
+	private static final Map UNMODIFIABLE_EMPTY_MAP
+		= Collections.unmodifiableMap(new HashMap(1));
+
+	/**
+	 * Primary field used in representing node properties efficiently.
+	 * If <code>null</code>, this node has no properties.
+	 * If a {@link String}, this is the name of this node's sole property,
+	 * and <code>property2</code> contains its value.
+	 * If a {@link Map}, this is the table of property name-value
+	 * mappings; <code>property2</code>, if non-null is its unmodifiable
+	 * equivalent.
+	 * Initially <code>null</code>.
+	 *
+	 * @see #property2
+	 */
+	private Object property1 = null;
+
+	/**
+	 * Auxiliary field used in representing node properties efficiently.
+	 *
+	 * @see #property1
+	 */
+	private Object property2 = null;
+
+	/**
+	 * A character index into the original source string,
+	 * or <code>-1</code> if no source position information is available
+	 * for this node; <code>-1</code> by default.
+	 */
+	private int startPosition = -1;
+
+	/**
+	 * A character length, or <code>0</code> if no source position
+	 * information is recorded for this node; <code>0</code> by default.
+	 */
+	private int length = 0;
+
+	/**
+	 * Flag constant (bit mask, value 1) indicating that there is something
+	 * not quite right with this AST node.
+	 * <p>
+	 * The standard parser (<code>ASTParser</code>) sets this
+	 * flag on a node to indicate a syntax error detected in the vicinity.
+	 * </p>
+	 */
+	public static final int MALFORMED = 1;
+
+	/**
+	 * Flag constant (bit mask, value 2) indicating that this is a node
+	 * that was created by the parser (as opposed to one created by another
+	 * party).
+	 * <p>
+	 * The standard parser (<code>ASTParser</code>) sets this
+	 * flag on the nodes it creates.
+	 * </p>
+	 * @since 3.0
+	 */
+	public static final int ORIGINAL = 2;
+
+	/**
+	 * Flag constant (bit mask, value 4) indicating that this node
+	 * is unmodifiable. When a node is marked unmodifiable, the
+	 * following operations result in a runtime exception:
+	 * <ul>
+	 * <li>Change a simple property of this node.</li>
+	 * <li>Add or remove a child node from this node.</li>
+	 * <li>Parent (or reparent) this node.</li>
+	 * </ul>
+	 * <p>
+	 * The standard parser (<code>ASTParser</code>) does not set
+	 * this flag on the nodes it creates. However, clients may set
+	 * this flag on a node to prevent further modification of the
+	 * its structural properties.
+	 * </p>
+	 * @since 3.0
+	 */
+	public static final int PROTECT = 4;
+
+	/**
+	 * Flag constant (bit mask, value 8) indicating that this node
+	 * or a part of this node is recovered from source that contains
+	 * a syntax error detected in the vicinity.
+	 * <p>
+	 * The standard parser (<code>ASTParser</code>) sets this
+	 * flag on a node to indicate a recovered node.
+	 * </p>
+	 * @since 3.2
+	 */
+	public static final int RECOVERED = 8;
+
+	/**
+	 * int containing the node type in the top 16 bits and
+	 * flags in the bottom 16 bits; none set by default.
+     * <p>
+     * N.B. This is a private field, but declared as package-visible
+     * for more efficient access from inner classes.
+     * </p>
+	 *
+	 * @see #MALFORMED
+	 */
+	int typeAndFlags = 0;
+
+	/**
+	 * Property of parent in which this node is a child, or <code>null</code>
+	 * if this node is a root. Initially <code>null</code>.
+	 *
+	 * @see #getLocationInParent
+	 * @since 3.0
+	 */
+	private StructuralPropertyDescriptor location = null;
+
+	/** Internal convenience constant indicating that there is definite risk of cycles.
+	 * @since 3.0
+	 */
+	static final boolean CYCLE_RISK = true;
+
+	/** Internal convenience constant indicating that there is no risk of cycles.
+	 * @since 3.0
+	 */
+	static final boolean NO_CYCLE_RISK = false;
+
+	/** Internal convenience constant indicating that a structural property is mandatory.
+	 * @since 3.0
+	 */
+	static final boolean MANDATORY = true;
+
+	/** Internal convenience constant indicating that a structural property is optional.
+	 * @since 3.0
+	 */
+	static final boolean OPTIONAL = false;
+
+	/**
+	 * A specialized implementation of a list of ASTNodes. The
+	 * implementation is based on an ArrayList.
+	 */
+	class NodeList extends AbstractList {
+
+		/**
+		 * The underlying list in which the nodes of this list are
+		 * stored (element type: {@link ASTNode}).
+		 * <p>
+		 * Be stingy on storage - assume that list will be empty.
+		 * </p>
+		 * <p>
+		 * This field declared default visibility (rather than private)
+		 * so that accesses from <code>NodeList.Cursor</code> do not require
+		 * a synthetic accessor method.
+		 * </p>
+		 */
+		ArrayList store = new ArrayList(0);
+
+		/**
+		 * The property descriptor for this list.
+		 */
+		ChildListPropertyDescriptor propertyDescriptor;
+
+		/**
+		 * A cursor for iterating over the elements of the list.
+		 * Does not lose its position if the list is changed during
+		 * the iteration.
+		 */
+		class Cursor implements Iterator {
+			/**
+			 * The position of the cursor between elements. If the value
+			 * is N, then the cursor sits between the element at positions
+			 * N-1 and N. Initially just before the first element of the
+			 * list.
+			 */
+			private int position = 0;
+
+			/* (non-Javadoc)
+			 * Method declared on <code>Iterator</code>.
+			 */
+			public boolean hasNext() {
+				return this.position < NodeList.this.store.size();
+			}
+
+			/* (non-Javadoc)
+			 * Method declared on <code>Iterator</code>.
+			 */
+			public Object next() {
+				Object result = NodeList.this.store.get(this.position);
+				this.position++;
+				return result;
+		    }
+
+			/* (non-Javadoc)
+			 * Method declared on <code>Iterator</code>.
+			 */
+			public void remove() {
+				throw new UnsupportedOperationException();
+			}
+
+			/**
+			 * Adjusts this cursor to accommodate an add/remove at the given
+			 * index.
+			 *
+			 * @param index the position at which the element was added
+			 *    or removed
+			 * @param delta +1 for add, and -1 for remove
+			 */
+			void update(int index, int delta) {
+				if (this.position > index) {
+					// the cursor has passed the added or removed element
+					this.position += delta;
+				}
+			}
+		}
+
+		/**
+		 * A list of currently active cursors (element type:
+		 * {@link Cursor}), or <code>null</code> if there are no
+		 * active cursors.
+		 * <p>
+		 * It is important for storage considerations to maintain the
+		 * null-means-empty invariant; otherwise, every NodeList instance
+		 * will waste a lot of space. A cursor is needed only for the duration
+		 * of a visit to the child nodes. Under normal circumstances, only a
+		 * single cursor is needed; multiple cursors are only required if there
+		 * are multiple visits going on at the same time.
+		 * </p>
+		 */
+		private List cursors = null;
+
+		/**
+		 * Creates a new empty list of nodes owned by this node.
+		 * This node will be the common parent of all nodes added to
+		 * this list.
+		 *
+		 * @param property the property descriptor
+		 * @since 3.0
+		 */
+		NodeList(ChildListPropertyDescriptor property) {
+			super();
+			this.propertyDescriptor = property;
+		}
+
+		/* (non-javadoc)
+		 * @see java.util.AbstractCollection#size()
+		 */
+		public int size() {
+			return this.store.size();
+		}
+
+		/* (non-javadoc)
+		 * @see AbstractList#get(int)
+		 */
+		public Object get(int index) {
+			return this.store.get(index);
+		}
+
+		/* (non-javadoc)
+		 * @see List#set(int, java.lang.Object)
+		 */
+		public Object set(int index, Object element) {
+		    if (element == null) {
+		        throw new IllegalArgumentException();
+		    }
+			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
+				// this node is protected => cannot gain or lose children
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+			// delink old child from parent, and link new child to parent
+			ASTNode newChild = (ASTNode) element;
+			ASTNode oldChild = (ASTNode) this.store.get(index);
+			if (oldChild == newChild) {
+				return oldChild;
+			}
+			if ((oldChild.typeAndFlags & PROTECT) != 0) {
+				// old child is protected => cannot be unparented
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
+			ASTNode.this.ast.preReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
+
+			Object result = this.store.set(index, newChild);
+			// n.b. setParent will call ast.modifying()
+			oldChild.setParent(null, null);
+			newChild.setParent(ASTNode.this, this.propertyDescriptor);
+			ASTNode.this.ast.postReplaceChildEvent(ASTNode.this, oldChild, newChild, this.propertyDescriptor);
+			return result;
+		}
+
+		/* (non-javadoc)
+		 * @see List#add(int, java.lang.Object)
+		 */
+		public void add(int index, Object element) {
+		    if (element == null) {
+		        throw new IllegalArgumentException();
+		    }
+			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
+				// this node is protected => cannot gain or lose children
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+			// link new child to parent
+			ASTNode newChild = (ASTNode) element;
+			ASTNode.checkNewChild(ASTNode.this, newChild, this.propertyDescriptor.cycleRisk, this.propertyDescriptor.elementType);
+			ASTNode.this.ast.preAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
+
+
+			this.store.add(index, element);
+			updateCursors(index, +1);
+			// n.b. setParent will call ast.modifying()
+			newChild.setParent(ASTNode.this, this.propertyDescriptor);
+			ASTNode.this.ast.postAddChildEvent(ASTNode.this, newChild, this.propertyDescriptor);
+		}
+
+		/* (non-javadoc)
+		 * @see List#remove(int)
+		 */
+		public Object remove(int index) {
+			if ((ASTNode.this.typeAndFlags & PROTECT) != 0) {
+				// this node is protected => cannot gain or lose children
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+			// delink old child from parent
+			ASTNode oldChild = (ASTNode) this.store.get(index);
+			if ((oldChild.typeAndFlags & PROTECT) != 0) {
+				// old child is protected => cannot be unparented
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+
+			ASTNode.this.ast.preRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
+			// n.b. setParent will call ast.modifying()
+			oldChild.setParent(null, null);
+			Object result = this.store.remove(index);
+			updateCursors(index, -1);
+			ASTNode.this.ast.postRemoveChildEvent(ASTNode.this, oldChild, this.propertyDescriptor);
+			return result;
+
+		}
+
+		/**
+		 * Allocate a cursor to use for a visit. The client must call
+		 * <code>releaseCursor</code> when done.
+		 * <p>
+		 * This method is internally synchronized on this NodeList.
+		 * It is thread-safe to create a cursor.
+		 * </p>
+		 *
+		 * @return a new cursor positioned before the first element
+		 *    of the list
+		 */
+		Cursor newCursor() {
+			synchronized (this) {
+				// serialize cursor management on this NodeList
+				if (this.cursors == null) {
+					// convert null to empty list
+					this.cursors = new ArrayList(1);
+				}
+				Cursor result = new Cursor();
+				this.cursors.add(result);
+				return result;
+			}
+		}
+
+		/**
+		 * Releases the given cursor at the end of a visit.
+		 * <p>
+		 * This method is internally synchronized on this NodeList.
+		 * It is thread-safe to release a cursor.
+		 * </p>
+		 *
+		 * @param cursor the cursor
+		 */
+		void releaseCursor(Cursor cursor) {
+			synchronized (this) {
+				// serialize cursor management on this NodeList
+				this.cursors.remove(cursor);
+				if (this.cursors.isEmpty()) {
+					// important: convert empty list back to null
+					// otherwise the node will hang on to needless junk
+					this.cursors = null;
+				}
+			}
+		}
+
+		/**
+		 * Adjusts all cursors to accommodate an add/remove at the given
+		 * index.
+		 * <p>
+		 * This method is only used when the list is being modified.
+		 * The AST is not thread-safe if any of the clients are modifying it.
+		 * </p>
+		 *
+		 * @param index the position at which the element was added
+		 *    or removed
+		 * @param delta +1 for add, and -1 for remove
+		 */
+		private synchronized void updateCursors(int index, int delta) {
+			if (this.cursors == null) {
+				// there are no cursors to worry about
+				return;
+			}
+			for (Iterator it = this.cursors.iterator(); it.hasNext(); ) {
+				Cursor c = (Cursor) it.next();
+				c.update(index, delta);
+			}
+		}
+
+		/**
+		 * Returns an estimate of the memory footprint of this node list
+		 * instance in bytes.
+	     * <ul>
+	     * <li>1 object header for the NodeList instance</li>
+	     * <li>5 4-byte fields of the NodeList instance</li>
+	     * <li>0 for cursors since null unless walk in progress</li>
+	     * <li>1 object header for the ArrayList instance</li>
+	     * <li>2 4-byte fields of the ArrayList instance</li>
+	     * <li>1 object header for an Object[] instance</li>
+	     * <li>4 bytes in array for each element</li>
+	     * </ul>
+	 	 *
+		 * @return the size of this node list in bytes
+		 */
+		int memSize() {
+			int result = HEADERS + 5 * 4;
+			result += HEADERS + 2 * 4;
+			result += HEADERS + 4 * size();
+			return result;
+		}
+
+		/**
+		 * Returns an estimate of the memory footprint in bytes of this node
+		 * list and all its subtrees.
+		 *
+		 * @return the size of this list of subtrees in bytes
+		 */
+		int listSize() {
+			int result = memSize();
+			for (Iterator it = iterator(); it.hasNext(); ) {
+				ASTNode child = (ASTNode) it.next();
+				result += child.treeSize();
+			}
+			return result;
+		}
+	}
+
+	/**
+	 * Creates a new AST node owned by the given AST. Once established,
+	 * the relationship between an AST node and its owning AST does not change
+	 * over the lifetime of the node. The new node has no parent node,
+	 * and no properties.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses my be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ASTNode(AST ast) {
+		if (ast == null) {
+			throw new IllegalArgumentException();
+		}
+
+		this.ast = ast;
+		setNodeType(getNodeType0());
+		setFlags(ast.getDefaultNodeFlag());
+		// setFlags calls modifying();
+	}
+
+	/**
+	 * Returns this node's AST.
+	 * <p>
+	 * Note that the relationship between an AST node and its owing AST does
+	 * not change over the lifetime of a node.
+	 * </p>
+	 *
+	 * @return the AST that owns this node
+	 */
+	public final AST getAST() {
+		return this.ast;
+	}
+
+	/**
+	 * Returns this node's parent node, or <code>null</code> if this is the
+	 * root node.
+	 * <p>
+	 * Note that the relationship between an AST node and its parent node
+	 * may change over the lifetime of a node.
+	 * </p>
+	 *
+	 * @return the parent of this node, or <code>null</code> if none
+	 */
+	public final ASTNode getParent() {
+		return this.parent;
+	}
+
+	/**
+	 * Returns the location of this node within its parent,
+	 * or <code>null</code> if this is a root node.
+	 * <p>
+	 * <pre>
+	 * ASTNode node = ...;
+	 * ASTNode parent = node.getParent();
+	 * StructuralPropertyDescriptor location = node.getLocationInParent();
+	 * assert (parent != null) == (location != null);
+	 * if ((location != null) && location.isChildProperty())
+	 *    assert parent.getStructuralProperty(location) == node;
+	 * if ((location != null) && location.isChildListProperty())
+	 *    assert ((List) parent.getStructuralProperty(location)).contains(node);
+	 * </pre>
+	 * </p>
+	 * <p>
+	 * Note that the relationship between an AST node and its parent node
+	 * may change over the lifetime of a node.
+	 * </p>
+	 *
+	 * @return the location of this node in its parent,
+	 * or <code>null</code> if this node has no parent
+	 * @since 3.0
+	 */
+	public final StructuralPropertyDescriptor getLocationInParent() {
+		return this.location;
+	}
+
+	/**
+	 * Returns the root node at or above this node; returns this node if
+	 * it is a root.
+	 *
+	 * @return the root node at or above this node
+	 */
+	public final ASTNode getRoot() {
+		ASTNode candidate = this;
+		while (true) {
+			ASTNode p = candidate.getParent();
+			if (p == null) {
+				// candidate has no parent - that's the guy
+				return candidate;
+			}
+			candidate = p;
+		}
+	}
+
+	/**
+	 * Returns the value of the given structural property for this node. The value
+	 * returned depends on the kind of property:
+	 * <ul>
+	 * <li>{@link SimplePropertyDescriptor} - the value of the given simple property,
+	 * or <code>null</code> if none; primitive values are "boxed"</li>
+	 * <li>{@link ChildPropertyDescriptor} - the child node (type <code>ASTNode</code>),
+	 * or <code>null</code> if none</li>
+	 * <li>{@link ChildListPropertyDescriptor} - the list (element type: {@link ASTNode})</li>
+	 * </ul>
+	 *
+	 * @param property the property
+	 * @return the value, or <code>null</code> if none
+	 * @exception RuntimeException if this node does not have the given property
+	 * @since 3.0
+	 */
+	public final Object getStructuralProperty(StructuralPropertyDescriptor property) {
+		if (property instanceof SimplePropertyDescriptor) {
+			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
+			if (p.getValueType() == int.class) {
+				int result = internalGetSetIntProperty(p, true, 0);
+				return new Integer(result);
+			} else if (p.getValueType() == boolean.class) {
+				boolean result = internalGetSetBooleanProperty(p, true, false);
+				return Boolean.valueOf(result);
+			} else {
+				return internalGetSetObjectProperty(p, true, null);
+			}
+		}
+		if (property instanceof ChildPropertyDescriptor) {
+			return internalGetSetChildProperty((ChildPropertyDescriptor) property, true, null);
+		}
+		if (property instanceof ChildListPropertyDescriptor) {
+			return internalGetChildListProperty((ChildListPropertyDescriptor) property);
+		}
+		throw new IllegalArgumentException();
+	}
+
+	/**
+	 * Sets the value of the given structural property for this node. The value
+	 * passed depends on the kind of property:
+	 * <ul>
+	 * <li>{@link SimplePropertyDescriptor} - the new value of the given simple property,
+	 * or <code>null</code> if none; primitive values are "boxed"</li>
+	 * <li>{@link ChildPropertyDescriptor} - the new child node (type <code>ASTNode</code>),
+	 * or <code>null</code> if none</li>
+	 * <li>{@link ChildListPropertyDescriptor} - not allowed</li>
+	 * </ul>
+	 *
+	 * @param property the property
+	 * @param value the property value
+	 * @exception RuntimeException if this node does not have the
+	 * given property, or if the given property cannot be set
+	 * @since 3.0
+	 */
+	public final void setStructuralProperty(StructuralPropertyDescriptor property, Object value) {
+		if (property instanceof SimplePropertyDescriptor) {
+			SimplePropertyDescriptor p = (SimplePropertyDescriptor) property;
+			if (p.getValueType() == int.class) {
+				int arg = ((Integer) value).intValue();
+				internalGetSetIntProperty(p, false, arg);
+				return;
+			} else if (p.getValueType() == boolean.class) {
+				boolean arg = ((Boolean) value).booleanValue();
+				internalGetSetBooleanProperty(p, false, arg);
+				return;
+			} else {
+				if (value == null && p.isMandatory()) {
+					throw new IllegalArgumentException();
+				}
+				internalGetSetObjectProperty(p, false, value);
+				return;
+			}
+		}
+		if (property instanceof ChildPropertyDescriptor) {
+			ChildPropertyDescriptor p = (ChildPropertyDescriptor) property;
+			ASTNode child = (ASTNode) value;
+			if (child == null && p.isMandatory()) {
+				throw new IllegalArgumentException();
+			}
+			internalGetSetChildProperty(p, false, child);
+			return;
+		}
+		if (property instanceof ChildListPropertyDescriptor) {
+			throw new IllegalArgumentException("Cannot set the list of child list property");  //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Sets the value of the given int-valued property for this node.
+	 * The default implementation of this method throws an exception explaining
+	 * that this node does not have such a property. This method should be
+	 * extended in subclasses that have at least one simple property whose value
+	 * type is int.
+	 *
+	 * @param property the property
+	 * @param get <code>true</code> for a get operation, and
+	 * <code>false</code> for a set operation
+	 * @param value the new property value; ignored for get operations
+	 * @return the value; always returns
+	 * <code>0</code> for set operations
+	 * @exception RuntimeException if this node does not have the
+	 * given property, or if the given value cannot be set as specified
+	 * @since 3.0
+	 */
+	int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
+	}
+
+	/**
+	 * Sets the value of the given boolean-valued property for this node.
+	 * The default implementation of this method throws an exception explaining
+	 * that this node does not have such a property. This method should be
+	 * extended in subclasses that have at least one simple property whose value
+	 * type is boolean.
+	 *
+	 * @param property the property
+	 * @param get <code>true</code> for a get operation, and
+	 * <code>false</code> for a set operation
+	 * @param value the new property value; ignored for get operations
+	 * @return the value; always returns
+	 * <code>false</code> for set operations
+	 * @exception RuntimeException if this node does not have the
+	 * given property, or if the given value cannot be set as specified
+	 * @since 3.0
+	 */
+	boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
+	}
+
+	/**
+	 * Sets the value of the given property for this node.
+	 * The default implementation of this method throws an exception explaining
+	 * that this node does not have such a property. This method should be
+	 * extended in subclasses that have at least one simple property whose value
+	 * type is a reference type.
+	 *
+	 * @param property the property
+	 * @param get <code>true</code> for a get operation, and
+	 * <code>false</code> for a set operation
+	 * @param value the new property value, or <code>null</code> if none;
+	 * ignored for get operations
+	 * @return the value, or <code>null</code> if none; always returns
+	 * <code>null</code> for set operations
+	 * @exception RuntimeException if this node does not have the
+	 * given property, or if the given value cannot be set as specified
+	 * @since 3.0
+	 */
+	Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
+	}
+
+	/**
+	 * Sets the child value of the given property for this node.
+	 * The default implementation of this method throws an exception explaining
+	 * that this node does not have such a property. This method should be
+	 * extended in subclasses that have at least one child property.
+	 *
+	 * @param property the property
+	 * @param get <code>true</code> for a get operation, and
+	 * <code>false</code> for a set operation
+	 * @param child the new child value, or <code>null</code> if none;
+	 * always <code>null</code> for get operations
+	 * @return the child, or <code>null</code> if none; always returns
+	 * <code>null</code> for set operations
+	 * @exception RuntimeException if this node does not have the
+	 * given property, or if the given child cannot be set as specified
+	 * @since 3.0
+	 */
+	ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the list value of the given property for this node.
+	 * The default implementation of this method throws an exception explaining
+	 * that this node does not have such a property. This method should be
+	 * extended in subclasses that have at least one child list property.
+	 *
+	 * @param property the property
+	 * @return the list (element type: {@link ASTNode})
+	 * @exception RuntimeException if the given node does not have the
+	 * given property
+	 * @since 3.0
+	 */
+	List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		throw new RuntimeException("Node does not have this property");  //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for nodes of the
+	 * same type as this node. Clients must not modify the result.
+	 * <p>
+	 * Note that property descriptors are a meta-level mechanism
+	 * for manipulating ASTNodes in a generic way. They are
+	 * unrelated to <code>get/setProperty</code>.
+	 * </p>
+	 *
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public final List structuralPropertiesForType() {
+		return internalStructuralPropertiesForType(this.ast.apiLevel);
+	}
+
+	/**
+	 * Returns a list of property descriptors for this node type.
+	 * Clients must not modify the result. This abstract method
+	 * must be implemented in each concrete AST node type.
+	 * <p>
+	 * N.B. This method is package-private, so that the implementations
+	 * of this method in each of the concrete AST node types do not
+	 * clutter up the API doc.
+	 * </p>
+	 *
+	 * @param apiLevel the API level; one of the <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	abstract List internalStructuralPropertiesForType(int apiLevel);
+
+	/**
+	 * Internal helper method that starts the building a list of
+	 * property descriptors for the given node type.
+	 *
+	 * @param nodeClass the class for a concrete node type with n properties
+	 * @param propertyList empty list, with capacity for n+1 elements
+	 */
+	static void createPropertyList(Class nodeClass, List propertyList) {
+		// stuff nodeClass at head of list for future ref
+		propertyList.add(nodeClass);
+	}
+
+	/**
+	 * Internal helper method that adding a property descriptor.
+	 *
+	 * @param property the structural property descriptor
+	 * @param propertyList list beginning with the AST node class
+	 * followed by accumulated structural property descriptors
+	 */
+	static void addProperty(StructuralPropertyDescriptor property, List propertyList) {
+		Class nodeClass = (Class) propertyList.get(0);
+		if (property.getNodeClass() != nodeClass) {
+			// easily made cut-and-paste mistake
+			throw new RuntimeException("Structural property descriptor has wrong node class!");  //$NON-NLS-1$
+		}
+		propertyList.add(property);
+	}
+
+	/**
+	 * Internal helper method that completes the building of
+	 * a node type's structural property descriptor list.
+	 *
+	 * @param propertyList list beginning with the AST node class
+	 * followed by accumulated structural property descriptors
+	 * @return unmodifiable list of structural property descriptors
+	 * (element type: {@link StructuralPropertyDescriptor})
+	 */
+	static List reapPropertyList(List propertyList) {
+		propertyList.remove(0); // remove nodeClass
+		// compact
+		ArrayList a = new ArrayList(propertyList.size());
+		a.addAll(propertyList);
+		return Collections.unmodifiableList(a);
+	}
+
+	/**
+     * Checks that this AST operation is not used when
+     * building JLS2 level ASTs.
+     * <p>
+     * Use this method to prevent access to new properties that have been added in JLS3.
+     * </p>
+     * 
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2 AST
+	 * @since 3.0
+     */
+	final void unsupportedIn2() {
+	  if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
+	  }
+	}
+
+	/**
+     * Checks that this AST operation is not used when
+     * building JLS2 or JLS3 level ASTs.
+     * <p>
+     * Use this method to prevent access to new properties that have been added in JLS4.
+     * </p>
+     * 
+	 * @exception UnsupportedOperationException if this operation is used in a JLS2 or JLS3 AST
+	 * @since 3.7
+	 */
+	final void unsupportedIn2_3() {
+		if (this.ast.apiLevel <= AST.JLS3_INTERNAL) {
+			throw new UnsupportedOperationException("Operation only supported in JLS4 and later AST"); //$NON-NLS-1$
+		}
+	}
+	
+	/**
+     * Checks that this AST operation is not used when
+     * building JLS2 or JLS3 or JLS4 level ASTs.
+     * <p>
+     * Use this method to prevent access to new properties that have been added in JLS8.
+     * </p>
+     * 
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final void unsupportedIn2_3_4() {
+		if (this.ast.apiLevel < AST.JLS8) {
+			throw new UnsupportedOperationException("Operation only supported in JLS8 and later AST"); //$NON-NLS-1$
+		}
+	}
+	
+	/**
+     * Checks that this AST operation is only used when
+     * building JLS2 level ASTs.
+     * <p>
+     * Use this method to prevent access to deprecated properties (deprecated in JLS3).
+     * </p>
+     * 
+	 * @exception UnsupportedOperationException if this operation is used in an AST later than JLS2
+	 * @since 3.0
+     */
+	// In API Javadocs, add: * @deprecated In the JLS3 API, this method is replaced by {@link #replacement()}.
+	final void supportedOnlyIn2() {
+	  if (this.ast.apiLevel != AST.JLS2_INTERNAL) {
+	  	throw new UnsupportedOperationException("Operation only supported in JLS2 AST"); //$NON-NLS-1$
+	  }
+	}
+
+	/**
+     * Checks that this AST operation is only used when
+     * building JLS2, JLS3 or JLS4 level ASTs.
+     * <p>
+     * Use this method to prevent access to deprecated properties (deprecated in JLS8).
+     * </p>
+     * 
+	 * @exception UnsupportedOperationException if this operation is used in an AST later than JLS4
+     * @since 3.9 BETA_JAVA8
+     */
+	// In API Javadocs, add: * @deprecated In the JLS8 API, this method is replaced by {@link #replacement()}.
+	final void supportedOnlyIn2_3_4() {
+	  if (this.ast.apiLevel >= AST.JLS8) {
+	  	throw new UnsupportedOperationException("Operation only supported in JLS2, JLS3 and JLS4 ASTs"); //$NON-NLS-1$
+	  }
+	}
+	
+	/**
+	 * Sets or clears this node's parent node and location.
+	 * <p>
+	 * Note that this method is package-private. The pointer from a node
+	 * to its parent is set implicitly as a side effect of inserting or
+	 * removing the node as a child of another node. This method calls
+	 * <code>ast.modifying()</code>.
+	 * </p>
+	 *
+	 * @param parent the new parent of this node, or <code>null</code> if none
+	 * @param property the location of this node in its parent,
+	 * or <code>null</code> if <code>parent</code> is <code>null</code>
+	 * @see #getLocationInParent
+	 * @see #getParent
+	 * @since 3.0
+	 */
+	final void setParent(ASTNode parent, StructuralPropertyDescriptor property) {
+		this.ast.modifying();
+		this.parent = parent;
+		this.location = property;
+	}
+
+	/**
+	 * Removes this node from its parent. Has no effect if this node
+	 * is unparented. If this node appears as an element of a child list
+	 * property of its parent, then this node is removed from the
+	 * list using <code>List.remove</code>.
+	 * If this node appears as the value of a child property of its
+	 * parent, then this node is detached from its parent
+	 * by passing <code>null</code> to the appropriate setter method;
+	 * this operation fails if this node is in a mandatory property.
+	 *
+	 * @since 3.0
+	 */
+	public final void delete() {
+		StructuralPropertyDescriptor p = getLocationInParent();
+		if (p == null) {
+			// node is unparented
+			return;
+		}
+		if (p.isChildProperty()) {
+			getParent().setStructuralProperty(this.location, null);
+			return;
+		}
+		if (p.isChildListProperty()) {
+			List l = (List) getParent().getStructuralProperty(this.location);
+			l.remove(this);
+		}
+	}
+
+	/**
+	 * Checks whether the given new child node is a node
+	 * in a different AST from its parent-to-be, whether it is
+	 * already has a parent, whether adding it to its
+	 * parent-to-be would create a cycle, and whether the child is of
+	 * the right type. The parent-to-be is the enclosing instance.
+	 *
+	 * @param node the parent-to-be node
+	 * @param newChild the new child of the parent
+	 * @param cycleCheck <code>true</code> if cycles are possible and need
+	 *   to be checked, <code>false</code> if cycles are impossible and do
+	 *   not need to be checked
+	 * @param nodeType a type constraint on child nodes, or <code>null</code>
+	 *   if no special check is required
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the child is null</li>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the child has the incorrect node type</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	static void checkNewChild(ASTNode node, ASTNode newChild,
+			boolean cycleCheck, Class nodeType) {
+		if (newChild.ast != node.ast) {
+			// new child is from a different AST
+			throw new IllegalArgumentException();
+		}
+		if (newChild.getParent() != null) {
+			// new child currently has a different parent
+			throw new IllegalArgumentException();
+		}
+		if (cycleCheck && newChild == node.getRoot()) {
+			// inserting new child would create a cycle
+			throw new IllegalArgumentException();
+		}
+		Class childClass = newChild.getClass();
+		if (nodeType != null && !nodeType.isAssignableFrom(childClass)) {
+			// new child is not of the right type
+			throw new ClassCastException();
+		}
+		if ((newChild.typeAndFlags & PROTECT) != 0) {
+			// new child node is protected => cannot be parented
+			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+		}
+	}
+
+	/**
+     * Prelude portion of the "3 step program" for replacing the
+	 * old child of this node with another node.
+     * Here is the code pattern found in all AST node subclasses:
+     * <pre>
+     * ASTNode oldChild = this.foo;
+     * preReplaceChild(oldChild, newFoo, FOO_PROPERTY);
+     * this.foo = newFoo;
+     * postReplaceChild(oldChild, newFoo, FOO_PROPERTY);
+     * </pre>
+     * The first part (preReplaceChild) does all the precondition checks,
+     * reports pre-delete events, and changes parent links.
+	 * The old child is delinked from its parent (making it a root node),
+	 * and the new child node is linked to its parent. The new child node
+	 * must be a root node in the same AST as its new parent, and must not
+	 * be an ancestor of this node. All three nodes must be
+     * modifiable (not PROTECTED). The replace operation must fail
+     * atomically; so it is crucial that all precondition checks
+     * be done before any linking and delinking happens.
+     * The final part (postReplaceChild )reports post-add events.
+	 * <p>
+	 * This method calls <code>ast.modifying()</code> for the nodes affected.
+	 * </p>
+	 *
+	 * @param oldChild the old child of this node, or <code>null</code> if
+	 *   there was no old child to replace
+	 * @param newChild the new child of this node, or <code>null</code> if
+	 *   there is no replacement child
+	 * @param property the property descriptor of this node describing
+     * the relationship between node and child
+	 * @exception RuntimeException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * <li>any of the nodes involved are unmodifiable</li>
+	 * </ul>
+	 * @since 3.0
+	 */
+	final void preReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
+		if ((this.typeAndFlags & PROTECT) != 0) {
+			// this node is protected => cannot gain or lose children
+			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+		}
+		if (newChild != null) {
+			checkNewChild(this, newChild, property.cycleRisk, null);
+		}
+		// delink old child from parent
+		if (oldChild != null) {
+			if ((oldChild.typeAndFlags & PROTECT) != 0) {
+				// old child node is protected => cannot be unparented
+				throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+			}
+			if (newChild != null) {
+				this.ast.preReplaceChildEvent(this, oldChild, newChild, property);
+			} else {
+				this.ast.preRemoveChildEvent(this, oldChild, property);
+			}
+			oldChild.setParent(null, null);
+		} else {
+			if(newChild != null) {
+				this.ast.preAddChildEvent(this, newChild, property);
+			}
+		}
+		// link new child to parent
+		if (newChild != null) {
+			newChild.setParent(this, property);
+			// cannot notify postAddChildEvent until parent is linked to child too
+		}
+	}
+
+	/**
+     * Postlude portion of the "3 step program" for replacing the
+	 * old child of this node with another node.
+     * See {@link #preReplaceChild(ASTNode, ASTNode, ChildPropertyDescriptor)}
+     * for details.
+	 * @since 3.0
+	 */
+	final void postReplaceChild(ASTNode oldChild, ASTNode newChild, ChildPropertyDescriptor property) {
+		// link new child to parent
+		if (newChild != null) {
+			if (oldChild != null) {
+				this.ast.postReplaceChildEvent(this, oldChild, newChild, property);
+			} else {
+				this.ast.postAddChildEvent(this, newChild, property);
+			}
+		} else {
+			this.ast.postRemoveChildEvent(this, oldChild, property);
+		}
+	}
+
+	/**
+     * Prelude portion of the "3 step program" for changing the
+	 * value of a simple property of this node.
+     * Here is the code pattern found in all AST node subclasses:
+     * <pre>
+     * preValueChange(FOO_PROPERTY);
+     * this.foo = newFoo;
+     * postValueChange(FOO_PROPERTY);
+     * </pre>
+     * The first part (preValueChange) does the precondition check
+     * to make sure the node is modifiable (not PROTECTED).
+     * The change operation must fail atomically; so it is crucial
+     * that the precondition checks are done before the field is
+     * hammered. The final part (postValueChange)reports post-change
+     * events.
+	 * <p>
+	 * This method calls <code>ast.modifying()</code> for the node affected.
+	 * </p>
+	 *
+	 * @param property the property descriptor of this node
+	 * @exception RuntimeException if:
+	 * <ul>
+	 * <li>this node is unmodifiable</li>
+	 * </ul>
+	 * @since 3.0
+	 */
+	final void preValueChange(SimplePropertyDescriptor property) {
+		if ((this.typeAndFlags & PROTECT) != 0) {
+			// this node is protected => cannot change value of properties
+			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+		}
+		this.ast.preValueChangeEvent(this, property);
+		this.ast.modifying();
+	}
+
+	/**
+     * Postlude portion of the "3 step program" for replacing the
+	 * old child of this node with another node.
+     * See {@link #preValueChange(SimplePropertyDescriptor)} for details.
+	 * @since 3.0
+	 */
+	final void postValueChange(SimplePropertyDescriptor property) {
+		this.ast.postValueChangeEvent(this, property);
+	}
+
+	/**
+     * Ensures that this node is modifiable (that is, not marked PROTECTED).
+     * If successful, calls ast.modifying().
+     * @exception RuntimeException is not modifiable
+     */
+	final void checkModifiable() {
+		if ((this.typeAndFlags & PROTECT) != 0) {
+			throw new IllegalArgumentException("AST node cannot be modified"); //$NON-NLS-1$
+		}
+		this.ast.modifying();
+	}
+
+	/**
+     * Begin lazy initialization of this node.
+     * Here is the code pattern found in all AST
+     * node subclasses:
+     * <pre>
+     * if (this.foo == null) {
+	 *    // lazy init must be thread-safe for readers
+     *    synchronized (this) {
+     *       if (this.foo == null) {
+     *          preLazyInit();
+     *          this.foo = ...; // code to create new node
+     *          postLazyInit(this.foo, FOO_PROPERTY);
+     *       }
+     *    }
+     * }
+     * </pre>
+     * @since 3.0
+     */
+	final void preLazyInit() {
+		// IMPORTANT: this method is called by readers
+		// ASTNode.this is locked at this point
+		this.ast.disableEvents();
+		// will turn events back on in postLasyInit
+	}
+
+	/**
+     * End lazy initialization of this node.
+     *
+	 * @param newChild the new child of this node, or <code>null</code> if
+	 *   there is no replacement child
+	 * @param property the property descriptor of this node describing
+     * the relationship between node and child
+     * @since 3.0
+     */
+	final void postLazyInit(ASTNode newChild, ChildPropertyDescriptor property) {
+		// IMPORTANT: this method is called by readers
+		// ASTNode.this is locked at this point
+		// newChild is brand new (so no chance of concurrent access)
+		newChild.setParent(this, property);
+		// turn events back on (they were turned off in corresponding preLazyInit)
+		this.ast.reenableEvents();
+	}
+
+	/**
+	 * Returns the value of the named property of this node, or <code>null</code> if none.
+	 *
+	 * @param propertyName the property name
+	 * @return the property value, or <code>null</code> if none
+	 * @see #setProperty(String,Object)
+	 */
+	public final Object getProperty(String propertyName) {
+		if (propertyName == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.property1 == null) {
+			// node has no properties at all
+			return null;
+		}
+		if (this.property1 instanceof String) {
+			// node has only a single property
+			if (propertyName.equals(this.property1)) {
+				return this.property2;
+			} else {
+				return null;
+			}
+		}
+		// otherwise node has table of properties
+		Map m = (Map) this.property1;
+		return m.get(propertyName);
+	}
+
+	/**
+	 * Sets the named property of this node to the given value,
+	 * or to <code>null</code> to clear it.
+	 * <p>
+	 * Clients should employ property names that are sufficiently unique
+	 * to avoid inadvertent conflicts with other clients that might also be
+	 * setting properties on the same node.
+	 * </p>
+	 * <p>
+	 * Note that modifying a property is not considered a modification to the
+	 * AST itself. This is to allow clients to decorate existing nodes with
+	 * their own properties without jeopardizing certain things (like the
+	 * validity of bindings), which rely on the underlying tree remaining static.
+	 * </p>
+	 *
+	 * @param propertyName the property name
+	 * @param data the new property value, or <code>null</code> if none
+	 * @see #getProperty(String)
+	 * @throws IllegalArgumentException if the given property name is <code>null</code>
+	 */
+	public final void setProperty(String propertyName, Object data) {
+		if (propertyName == null) {
+			throw new IllegalArgumentException();
+		}
+		// N.B. DO NOT CALL ast.modifying();
+
+		if (this.property1 == null) {
+			// node has no properties at all
+			if (data == null) {
+				// we already know this
+				return;
+			}
+			// node gets its fist property
+			this.property1 = propertyName;
+			this.property2 = data;
+			return;
+		}
+
+		if (this.property1 instanceof String) {
+			// node has only a single property
+			if (propertyName.equals(this.property1)) {
+				// we're in luck
+				if (data == null) {
+					// just deleted last property
+					this.property1 = null;
+					this.property2 = null;
+				} else {
+					this.property2 = data;
+				}
+				return;
+			}
+			if (data == null) {
+				// we already know this
+				return;
+			}
+			// node already has one property - getting its second
+			// convert to more flexible representation
+			Map m = new HashMap(3);
+			m.put(this.property1, this.property2);
+			m.put(propertyName, data);
+			this.property1 = m;
+			this.property2 = null;
+			return;
+		}
+
+		// node has two or more properties
+		Map m = (Map) this.property1;
+		if (data == null) {
+			m.remove(propertyName);
+			// check for just one property left
+			if (m.size() == 1) {
+				// convert to more efficient representation
+				Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
+				this.property1 = entries[0].getKey();
+				this.property2 = entries[0].getValue();
+			}
+			return;
+		} else {
+			m.put(propertyName, data);
+			// still has two or more properties
+			return;
+		}
+	}
+
+	/**
+	 * Returns an unmodifiable table of the properties of this node with
+	 * non-<code>null</code> values.
+	 *
+	 * @return the table of property values keyed by property name
+	 *   (key type: <code>String</code>; value type: <code>Object</code>)
+	 */
+	public final Map properties() {
+		if (this.property1 == null) {
+			// node has no properties at all
+			return UNMODIFIABLE_EMPTY_MAP;
+		}
+		if (this.property1 instanceof String) {
+			// node has a single property
+			return Collections.singletonMap(this.property1, this.property2);
+		}
+
+		// node has two or more properties
+		if (this.property2 == null) {
+			this.property2 = Collections.unmodifiableMap((Map) this.property1);
+		}
+		// property2 is unmodifiable wrapper for map in property1
+		return (Map) this.property2;
+	}
+
+	/**
+	 * Returns the flags associated with this node.
+	 * <p>
+	 * No flags are associated with newly created nodes.
+	 * </p>
+	 * <p>
+	 * The flags are the bitwise-or of individual flags.
+	 * The following flags are currently defined:
+	 * <ul>
+	 * <li>{@link #MALFORMED} - indicates node is syntactically
+	 *   malformed</li>
+	 * <li>{@link #ORIGINAL} - indicates original node
+	 * created by ASTParser</li>
+	 * <li>{@link #PROTECT} - indicates node is protected
+	 * from further modification</li>
+	 * <li>{@link #RECOVERED} - indicates node or a part of this node
+	 *  is recovered from source that contains a syntax error</li>
+	 * </ul>
+	 * Other bit positions are reserved for future use.
+	 * </p>
+	 *
+	 * @return the bitwise-or of individual flags
+	 * @see #setFlags(int)
+	 */
+	public final int getFlags() {
+		return this.typeAndFlags & 0xFFFF;
+	}
+
+	/**
+	 * Sets the flags associated with this node to the given value.
+	 * <p>
+	 * The flags are the bitwise-or of individual flags.
+	 * The following flags are currently defined:
+	 * <ul>
+	 * <li>{@link #MALFORMED} - indicates node is syntactically
+	 *   malformed</li>
+	 * <li>{@link #ORIGINAL} - indicates original node
+	 * created by ASTParser</li>
+	 * <li>{@link #PROTECT} - indicates node is protected
+	 * from further modification</li>
+	 * <li>{@link #RECOVERED} - indicates node or a part of this node
+	 *  is recovered from source that contains a syntax error</li>
+	 * </ul>
+	 * Other bit positions are reserved for future use.
+	 * </p>
+	 * <p>
+	 * Note that the flags are <em>not</em> considered a structural
+	 * property of the node, and can be changed even if the
+	 * node is marked as protected.
+	 * </p>
+	 *
+	 * @param flags the bitwise-or of individual flags
+	 * @see #getFlags()
+	 */
+	public final void setFlags(int flags) {
+		this.ast.modifying();
+		int old = this.typeAndFlags & 0xFFFF0000;
+		this.typeAndFlags = old | (flags & 0xFFFF);
+	}
+
+	/**
+	 * Returns an integer value identifying the type of this concrete AST node.
+	 * The values are small positive integers, suitable for use in switch statements.
+	 * <p>
+	 * For each concrete node type there is a unique node type constant (name
+	 * and value). The unique node type constant for a concrete node type such as
+	 * <code>CastExpression</code> is <code>ASTNode.CAST_EXPRESSION</code>.
+	 * </p>
+	 *
+	 * @return one of the node type constants
+	 */
+	public final int getNodeType() {
+		return this.typeAndFlags >>> 16;
+	}
+
+	/**
+	 * Sets the integer value identifying the type of this concrete AST node.
+	 * The values are small positive integers, suitable for use in switch statements.
+	 *
+	 * @param nodeType one of the node type constants
+	 */
+	private void setNodeType(int nodeType) {
+		int old = this.typeAndFlags & 0xFFFF0000;
+		this.typeAndFlags = old | (nodeType << 16);
+	}
+
+	/**
+	 * Returns an integer value identifying the type of this concrete AST node.
+	 * <p>
+	 * This internal method is implemented in each of the
+	 * concrete node subclasses.
+	 * </p>
+	 *
+	 * @return one of the node type constants
+	 */
+	abstract int getNodeType0();
+
+	/**
+	 * The <code>ASTNode</code> implementation of this <code>Object</code>
+	 * method uses object identity (==). Use <code>subtreeMatch</code> to
+	 * compare two subtrees for equality.
+	 *
+	 * @param obj {@inheritDoc}
+	 * @return {@inheritDoc}
+	 * @see #subtreeMatch(ASTMatcher matcher, Object other)
+	 */
+	public final boolean equals(Object obj) {
+		return this == obj; // equivalent to Object.equals
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * This makes it consistent with the fact that a equals methods has been provided.
+	 * @see java.lang.Object#hashCode()
+	 */
+	public final int hashCode() {
+		return super.hashCode();
+	}
+
+	/**
+	 * Returns whether the subtree rooted at the given node matches the
+	 * given other object as decided by the given matcher.
+	 *
+	 * @param matcher the matcher
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 * <code>false</code> if they do not match
+	 */
+	public final boolean subtreeMatch(ASTMatcher matcher, Object other) {
+		return subtreeMatch0(matcher, other);
+	}
+
+	/**
+	 * Returns whether the subtree rooted at the given node matches the
+	 * given other object as decided by the given matcher.
+	 * <p>
+	 * This internal method is implemented in each of the
+	 * concrete node subclasses.
+	 * </p>
+	 *
+	 * @param matcher the matcher
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 * <code>false</code> if they do not match
+	 */
+	abstract boolean subtreeMatch0(ASTMatcher matcher, Object other);
+
+	/**
+	 * Returns a deep copy of the subtree of AST nodes rooted at the
+	 * given node. The resulting nodes are owned by the given AST,
+	 * which may be different from the ASTs of the given node.
+	 * Even if the given node has a parent, the result node will be unparented.
+	 * <p>
+	 * Source range information on the original nodes is automatically copied to the new
+	 * nodes. Client properties (<code>properties</code>) are not carried over.
+	 * </p>
+	 * <p>
+	 * The node's <code>AST</code> and the target <code>AST</code> must support
+     * the same API level.
+	 * </p>
+	 *
+	 * @param target the AST that is to own the nodes in the result
+	 * @param node the node to copy, or <code>null</code> if none
+	 * @return the copied node, or <code>null</code> if <code>node</code>
+	 *    is <code>null</code>
+	 */
+	public static ASTNode copySubtree(AST target, ASTNode node) {
+		if (node == null) {
+			return null;
+		}
+		if (target == null) {
+			throw new IllegalArgumentException();
+		}
+		if (target.apiLevel() != node.getAST().apiLevel()) {
+			throw new UnsupportedOperationException();
+		}
+		ASTNode newNode = node.clone(target);
+		return newNode;
+	}
+
+	/**
+	 * Returns a deep copy of the subtrees of AST nodes rooted at the
+	 * given list of nodes. The resulting nodes are owned by the given AST,
+	 * which may be different from the ASTs of the nodes in the list.
+	 * Even if the nodes in the list have parents, the nodes in the result
+	 * will be unparented.
+	 * <p>
+	 * Source range information on the original nodes is automatically copied to the new
+	 * nodes. Client properties (<code>properties</code>) are not carried over.
+	 * </p>
+	 *
+	 * @param target the AST that is to own the nodes in the result
+	 * @param nodes the list of nodes to copy
+	 *    (element type: {@link ASTNode})
+	 * @return the list of copied subtrees
+	 *    (element type: {@link ASTNode})
+	 */
+	public static List copySubtrees(AST target, List nodes) {
+		List result = new ArrayList(nodes.size());
+		for (Iterator it = nodes.iterator(); it.hasNext(); ) {
+			ASTNode oldNode = (ASTNode) it.next();
+			ASTNode newNode = oldNode.clone(target);
+			result.add(newNode);
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
+	 * The resulting nodes are owned by the given AST, which may be different
+	 * from the AST of this node. Even if this node has a parent, the
+	 * result node will be unparented.
+	 * <p>
+	 * This method reports pre- and post-clone events, and dispatches
+	 * to <code>clone0(AST)</code> which is reimplemented in node subclasses.
+	 * </p>
+	 *
+	 * @param target the AST that is to own the nodes in the result
+	 * @return the root node of the copies subtree
+	 */
+	final ASTNode clone(AST target) {
+		this.ast.preCloneNodeEvent(this);
+		ASTNode c = clone0(target);
+		this.ast.postCloneNodeEvent(this, c);
+		return c;
+	}
+
+	/**
+	 * Returns a deep copy of the subtree of AST nodes rooted at this node.
+	 * The resulting nodes are owned by the given AST, which may be different
+	 * from the AST of this node. Even if this node has a parent, the
+	 * result node will be unparented.
+	 * <p>
+	 * This method must be implemented in subclasses.
+	 * </p>
+	 * <p>
+	 * General template for implementation on each concrete ASTNode class:
+	 * <pre>
+	 * <code>
+	 * ConcreteNodeType result = new ConcreteNodeType(target);
+	 * result.setSourceRange(getStartPosition(), getLength());
+	 * result.setChildProperty(
+	 *         (ChildPropertyType) ASTNode.copySubtree(target, getChildProperty()));
+	 * result.setSimpleProperty(isSimpleProperty());
+	 * result.childrenProperty().addAll(
+	 *         ASTNode.copySubtrees(target, childrenProperty()));
+	 * return result;
+	 * </code>
+	 * </pre>
+	 * </p>
+	 * <p>
+	 * This method does not report pre- and post-clone events.
+	 * All callers should instead call <code>clone(AST)</code>
+	 * to ensure that pre- and post-clone events are reported.
+	 * </p>
+	 * <p>
+	 * N.B. This method is package-private, so that the implementations
+	 * of this method in each of the concrete AST node types do not
+	 * clutter up the API doc.
+	 * </p>
+	 *
+	 * @param target the AST that is to own the nodes in the result
+	 * @return the root node of the copies subtree
+	 */
+	abstract ASTNode clone0(AST target);
+
+	/**
+	 * Accepts the given visitor on a visit of the current node.
+	 *
+	 * @param visitor the visitor object
+	 * @exception IllegalArgumentException if the visitor is null
+	 */
+	public final void accept(ASTVisitor visitor) {
+		if (visitor == null) {
+			throw new IllegalArgumentException();
+		}
+		// begin with the generic pre-visit
+		if (visitor.preVisit2(this)) {
+			// dynamic dispatch to internal method for type-specific visit/endVisit
+			accept0(visitor);
+		}
+		// end with the generic post-visit
+		visitor.postVisit(this);
+	}
+
+	/**
+	 * Accepts the given visitor on a type-specific visit of the current node.
+	 * This method must be implemented in all concrete AST node types.
+	 * <p>
+	 * General template for implementation on each concrete ASTNode class:
+	 * <pre>
+	 * <code>
+	 * boolean visitChildren = visitor.visit(this);
+	 * if (visitChildren) {
+	 *    // visit children in normal left to right reading order
+	 *    acceptChild(visitor, getProperty1());
+	 *    acceptChildren(visitor, this.rawListProperty);
+	 *    acceptChild(visitor, getProperty2());
+	 * }
+	 * visitor.endVisit(this);
+	 * </code>
+	 * </pre>
+	 * Note that the caller (<code>accept</code>) take cares of invoking
+	 * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
+	 * </p>
+	 *
+	 * @param visitor the visitor object
+	 */
+	abstract void accept0(ASTVisitor visitor);
+
+	/**
+	 * Accepts the given visitor on a visit of the current node.
+	 * <p>
+	 * This method should be used by the concrete implementations of
+	 * <code>accept0</code> to traverse optional properties. Equivalent
+	 * to <code>child.accept(visitor)</code> if <code>child</code>
+	 * is not <code>null</code>.
+	 * </p>
+	 *
+	 * @param visitor the visitor object
+	 * @param child the child AST node to dispatch too, or <code>null</code>
+	 *    if none
+	 */
+	final void acceptChild(ASTVisitor visitor, ASTNode child) {
+		if (child == null) {
+			return;
+		}
+		child.accept(visitor);
+	}
+
+	/**
+	 * Accepts the given visitor on a visit of the given live list of
+	 * child nodes.
+	 * <p>
+	 * This method must be used by the concrete implementations of
+	 * <code>accept</code> to traverse list-values properties; it
+	 * encapsulates the proper handling of on-the-fly changes to the list.
+	 * </p>
+	 *
+	 * @param visitor the visitor object
+	 * @param children the child AST node to dispatch too, or <code>null</code>
+	 *    if none
+	 */
+	final void acceptChildren(ASTVisitor visitor, ASTNode.NodeList children) {
+		// use a cursor to keep track of where we are up to
+		// (the list may be changing under foot)
+		NodeList.Cursor cursor = children.newCursor();
+		try {
+			while (cursor.hasNext()) {
+				ASTNode child = (ASTNode) cursor.next();
+				child.accept(visitor);
+			}
+		} finally {
+			children.releaseCursor(cursor);
+		}
+	}
+
+	/**
+	 * Returns the character index into the original source file indicating
+	 * where the source fragment corresponding to this node begins.
+	 * <p>
+	 * The parser supplies useful well-defined source ranges to the nodes it creates.
+	 * See {@link ASTParser#setKind(int)} for details
+	 * on precisely where source ranges begin and end.
+	 * </p>
+	 *
+	 * @return the 0-based character index, or <code>-1</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getLength()
+	 * @see ASTParser
+	 */
+	public final int getStartPosition() {
+		return this.startPosition;
+	}
+
+	/**
+	 * Returns the length in characters of the original source file indicating
+	 * where the source fragment corresponding to this node ends.
+	 * <p>
+	 * The parser supplies useful well-defined source ranges to the nodes it creates.
+	 * See {@link ASTParser#setKind(int)} methods for details
+	 * on precisely where source ranges begin and end.
+	 * </p>
+	 *
+	 * @return a (possibly 0) length, or <code>0</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getStartPosition()
+	 * @see ASTParser
+	 */
+	public final int getLength() {
+		return this.length;
+	}
+
+	/**
+	 * Sets the source range of the original source file where the source
+	 * fragment corresponding to this node was found.
+	 * <p>
+	 * See {@link ASTParser#setKind(int)} for details
+	 * on precisely where source ranges are supposed to begin and end.
+	 * </p>
+	 *
+	 * @param startPosition a 0-based character index,
+	 *    or <code>-1</code> if no source position information is
+	 *    available for this node
+	 * @param length a (possibly 0) length,
+	 *    or <code>0</code> if no source position information is recorded
+	 *    for this node
+	 * @see #getStartPosition()
+	 * @see #getLength()
+	 * @see ASTParser
+	 */
+	public final void setSourceRange(int startPosition, int length) {
+		if (startPosition >= 0 && length < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (startPosition < 0 && length != 0) {
+			throw new IllegalArgumentException();
+		}
+		// source positions are not considered a structural property
+		// but we protect them nevertheless
+		checkModifiable();
+		this.startPosition = startPosition;
+		this.length = length;
+	}
+
+	/**
+	 * Returns a string representation of this node suitable for debugging
+	 * purposes only.
+	 *
+	 * @return a debug string
+	 */
+	public final String toString() {
+		StringBuffer buffer = new StringBuffer();
+		int p = buffer.length();
+		try {
+			appendDebugString(buffer);
+		} catch (RuntimeException e) {
+			// since debugger sometimes call toString methods, problems can easily happen when
+			// toString is called on an instance that is being initialized
+			buffer.setLength(p);
+			buffer.append("!"); //$NON-NLS-1$
+			buffer.append(standardToString());
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * Returns the string representation of this node produced by the standard
+	 * <code>Object.toString</code> method.
+	 *
+	 * @return a debug string
+	 */
+	final String standardToString() {
+		return super.toString();
+	}
+
+	/**
+	 * Appends a debug representation of this node to the given string buffer.
+	 * <p>
+	 * The <code>ASTNode</code> implementation of this method prints out the entire
+	 * subtree. Subclasses may override to provide a more succinct representation.
+	 * </p>
+	 *
+	 * @param buffer the string buffer to append to
+	 */
+	void appendDebugString(StringBuffer buffer) {
+		// print the subtree by default
+		appendPrintString(buffer);
+	}
+
+	/**
+	 * Appends a standard Java source code representation of this subtree to the given
+	 * string buffer.
+	 *
+	 * @param buffer the string buffer to append to
+	 */
+	final void appendPrintString(StringBuffer buffer) {
+		NaiveASTFlattener printer = new NaiveASTFlattener();
+		accept(printer);
+		buffer.append(printer.getResult());
+	}
+
+	/**
+	 * Estimate of size of an object header in bytes.
+	 */
+	static final int HEADERS = 12;
+
+	/**
+	 * Approximate base size of an AST node instance in bytes,
+	 * including object header and instance fields.
+	 * That is, HEADERS + (# instance vars in ASTNode)*4.
+	 */
+	static final int BASE_NODE_SIZE = HEADERS + 7 * 4;
+
+	/**
+	 * Returns an estimate of the memory footprint, in bytes,
+	 * of the given string.
+	 *
+	 * @param string the string to measure, or <code>null</code>
+	 * @return the size of this string object in bytes, or
+	 *   0 if the string is <code>null</code>
+     * @since 3.0
+	 */
+	static int stringSize(String string) {
+		int size = 0;
+		if (string != null) {
+			// Strings usually have 4 instance fields, one of which is a char[]
+			size += HEADERS + 4 * 4;
+			// char[] has 2 bytes per character
+			size += HEADERS + 2 * string.length();
+		}
+		return size;
+	}
+
+	/**
+	 * Returns an estimate of the memory footprint in bytes of the entire
+	 * subtree rooted at this node.
+	 *
+	 * @return the size of this subtree in bytes
+	 */
+	public final int subtreeBytes() {
+		return treeSize();
+	}
+
+	/**
+	 * Returns an estimate of the memory footprint in bytes of the entire
+	 * subtree rooted at this node.
+	 * <p>
+	 * N.B. This method is package-private, so that the implementations
+	 * of this method in each of the concrete AST node types do not
+	 * clutter up the API doc.
+	 * </p>
+	 *
+	 * @return the size of this subtree in bytes
+	 */
+	abstract int treeSize();
+
+	/**
+	 * Returns an estimate of the memory footprint of this node in bytes.
+	 * The estimate does not include the space occupied by child nodes.
+	 *
+	 * @return the size of this node in bytes
+	 */
+	abstract int memSize();
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
new file mode 100644
index 0000000..5ae5776
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
@@ -0,0 +1,1485 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
+import org.eclipse.jdt.internal.core.util.RecordedParsingInformation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A Java language parser for creating abstract syntax trees (ASTs).
+ * <p>
+ * Example: Create basic AST from source string
+ * <pre>
+ * char[] source = ...;
+ * ASTParser parser = ASTParser.newParser(AST.JLS3);  // handles JDK 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
+ * parser.setSource(source);
+ * // In order to parse 1.5 code, some compiler options need to be set to 1.5
+ * Map options = JavaCore.getOptions();
+ * JavaCore.setComplianceOptions(JavaCore.VERSION_1_5, options);
+ * parser.setCompilerOptions(options);
+ * CompilationUnit result = (CompilationUnit) parser.createAST(null);
+ * </pre>
+ * Once a configured parser instance has been used to create an AST,
+ * the settings are automatically reset to their defaults,
+ * ready for the parser instance to be reused.
+ * </p>
+ * <p>
+ * There are a number of configurable features:
+ * <ul>
+ * <li>Source string from {@link #setSource(char[]) char[]},
+ * {@link #setSource(ICompilationUnit) ICompilationUnit},
+ * or {@link #setSource(IClassFile) IClassFile}, and limited
+ * to a specified {@linkplain #setSourceRange(int,int) subrange}.</li>
+ * <li>Whether {@linkplain #setResolveBindings(boolean) bindings} will be created.</li>
+ * <li>Which {@linkplain #setWorkingCopyOwner(WorkingCopyOwner)
+ * working copy owner} to use when resolving bindings.</li>
+ * <li>A hypothetical {@linkplain #setUnitName(String) compilation unit file name}
+ * and {@linkplain #setProject(IJavaProject) Java project}
+ * for locating a raw source string in the Java model (when
+ * resolving bindings)</li>
+ * <li>Which {@linkplain #setCompilerOptions(Map) compiler options}
+ * to use. This is especially important to use if the parsing/scanning of the source code requires a
+ * different version than the default of the workspace. For example, the workspace defaults are 1.4 and
+ * you want to create an AST for a source code that is using 1.5 constructs.</li>
+ * <li>Whether to parse just {@linkplain #setKind(int) an expression, statements,
+ * or body declarations} rather than an entire compilation unit.</li>
+ * <li>Whether to return a {@linkplain #setFocalPosition(int) abridged AST}
+ * focused on the declaration containing a given source position.</li>
+ * </ul>
+ * </p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ASTParser {
+
+	/**
+	 * Kind constant used to request that the source be parsed
+     * as a single expression.
+	 */
+	public static final int K_EXPRESSION = 0x01;
+
+	/**
+	 * Kind constant used to request that the source be parsed
+     * as a sequence of statements.
+	 */
+	public static final int K_STATEMENTS = 0x02;
+
+	/**
+	 * Kind constant used to request that the source be parsed
+	 * as a sequence of class body declarations.
+	 */
+	public static final int K_CLASS_BODY_DECLARATIONS = 0x04;
+
+	/**
+	 * Kind constant used to request that the source be parsed
+	 * as a compilation unit.
+	 */
+	public static final int K_COMPILATION_UNIT = 0x08;
+
+	/**
+	 * Creates a new object for creating a Java abstract syntax tree
+     * (AST) following the specified set of API rules.
+     *
+ 	 * @param level the API level; one of the <code>.JLS*</code> level constants
+     * declared on {@link AST}
+	 * @return new ASTParser instance
+	 */
+	public static ASTParser newParser(int level) {
+		return new ASTParser(level);
+	}
+
+	/**
+	 * Level of AST API desired.
+	 */
+	private final int apiLevel;
+
+	/**
+	 * Kind of parse requested. Defaults to an entire compilation unit.
+	 */
+	private int astKind;
+
+	/**
+	 * Compiler options. Defaults to JavaCore.getOptions().
+	 */
+	private Map compilerOptions;
+	
+    /**
+	 * The focal point for a partial AST request.
+     * Only used when <code>partial</code> is <code>true</code>.
+     */
+	private int focalPointPosition;
+
+    /**
+     * Source string.
+     */
+    private char[] rawSource = null;
+
+    /**
+     * Java model class file or compilation unit supplying the source.
+     */
+    private ITypeRoot typeRoot = null;
+
+    /**
+     * Character-based offset into the source string where parsing is to
+     * begin. Defaults to 0.
+     */
+	private int sourceOffset = 0;
+
+    /**
+     * Character-based length limit, or -1 if unlimited.
+     * All characters in the source string between <code>offset</code>
+     * and <code>offset+length-1</code> inclusive are parsed. Defaults to -1,
+     * which means the rest of the source string.
+     */
+	private int sourceLength = -1;
+
+    /**
+     * Working copy owner. Defaults to primary owner.
+     */
+	private WorkingCopyOwner workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
+
+    /**
+	 * Java project used to resolve names, or <code>null</code> if none.
+     * Defaults to none.
+     */
+	private IJavaProject project = null;
+
+    /**
+	 * Name of the compilation unit for resolving bindings, or
+	 * <code>null</code> if none. Defaults to none.
+     */
+	private String unitName = null;
+	
+	/**
+	 * Classpath entries to use to resolve bindings when no java project are available.
+	 */
+	private String[] classpaths;
+
+	/**
+	 * Sourcepath entries to use to resolve bindings when no java project are available.
+	 */
+	private String[] sourcepaths;
+	
+	/**
+	 * Encoding of the given sourcepaths entries.
+	 */
+	private String[] sourcepathsEncodings;
+	
+	/**
+	 * Bits used to set the different values from CompilationUnitResolver values.
+	 */
+	private int bits;
+
+	/**
+	 * Creates a new AST parser for the given API level.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param level the API level; one of the <code>JLS*</code> level constants
+	 * declared on {@link AST}
+	 */
+	ASTParser(int level) {
+		switch(level) {
+			case AST.JLS2_INTERNAL:
+			case AST.JLS3_INTERNAL:
+			case AST.JLS4_INTERNAL:
+			case AST.JLS8:
+				break;
+			default:
+				throw new IllegalArgumentException();
+		}
+		this.apiLevel = level;
+		initializeDefaults();
+	}
+
+	private List getClasspath() throws IllegalStateException {
+		Main main = new Main(new PrintWriter(System.out), new PrintWriter(System.err), false/*systemExit*/, null/*options*/, null/*progress*/);
+		ArrayList allClasspaths = new ArrayList();
+		try {
+			if ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) != 0) {
+				org.eclipse.jdt.internal.compiler.util.Util.collectRunningVMBootclasspath(allClasspaths);
+			}
+			if (this.sourcepaths != null) {
+				for (int i = 0, max = this.sourcepaths.length; i < max; i++) {
+					String encoding = this.sourcepathsEncodings == null ? null : this.sourcepathsEncodings[i];
+					main.processPathEntries(
+							Main.DEFAULT_SIZE_CLASSPATH,
+							allClasspaths, this.sourcepaths[i], encoding, true, false);
+				}
+			}
+			if (this.classpaths != null) {
+				for (int i = 0, max = this.classpaths.length; i < max; i++) {
+					main.processPathEntries(
+							Main.DEFAULT_SIZE_CLASSPATH,
+							allClasspaths, this.classpaths[i], null, false, false);
+				}
+			}
+			ArrayList pendingErrors = main.pendingErrors;
+			if (pendingErrors != null && pendingErrors.size() != 0) {
+				throw new IllegalStateException("invalid environment settings"); //$NON-NLS-1$
+			}
+		} catch (IllegalArgumentException e) {
+			throw new IllegalStateException("invalid environment settings"); //$NON-NLS-1$
+		}
+		return allClasspaths;
+	}
+	/**
+	 * Sets all the setting to their default values.
+	 */
+	private void initializeDefaults() {
+		this.astKind = K_COMPILATION_UNIT;
+		this.rawSource = null;
+		this.typeRoot = null;
+		this.bits = 0;
+		this.sourceLength = -1;
+		this.sourceOffset = 0;
+		this.workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
+		this.unitName = null;
+		this.project = null;
+		this.classpaths = null;
+		this.sourcepaths = null;
+		this.sourcepathsEncodings = null;
+		Map options = JavaCore.getOptions();
+		options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
+		this.compilerOptions = options;
+	}
+
+	/**
+	 * Requests that the compiler should perform bindings recovery.
+	 * When bindings recovery is enabled the compiler returns incomplete bindings.
+	 * <p>
+	 * Default to <code>false</code>.
+	 * </p>
+	 * <p>This should be set to true only if bindings are resolved. It has no effect if there is no binding
+	 * resolution.</p>
+	 *
+	 * @param enabled <code>true</code> if incomplete bindings are expected,
+	 *   and <code>false</code> if only complete bindings are expected.
+	 *
+	 * @see IBinding#isRecovered()
+	 * @since 3.3
+	 */
+	public void setBindingsRecovery(boolean enabled) {
+		if (enabled) {
+			this.bits |= CompilationUnitResolver.BINDING_RECOVERY;
+		} else {
+			this.bits &= ~CompilationUnitResolver.BINDING_RECOVERY;
+		}
+	}
+	
+	/**
+	 * Sets the environment to be used when no {@link IJavaProject} is available.
+	 * 
+	 * <p>The user has to make sure that all the required types are included either in the classpath or source paths. 
+	 * All the paths containing binary types must be included in the <code>classpathEntries</code> whereas all paths containing  
+	 * source types must be included in the <code>sourcepathEntries</code>.</p>
+	 * <p>All paths in the <code>classpathEntries</code> and <code>sourcepathEntries</code> are absolute paths.</p>
+	 * <p>If the source paths contain units using a specific encoding (other than the platform encoding), then the
+	 * given <code>encodings</code> must be set. When the <code>encodings</code> is set to non <code>null</code>, its length must
+	 * match the length of <code>sourcepathEntries</code> or an IllegalArgumentException will be thrown.</p>
+	 * <p>If <code>encodings</code> is not <code>null</code>, the given <code>sourcepathEntries</code> must not be <code>null</code>.</p>
+	 * 
+	 * @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 <code>null</code> if the platform encoding
+	 * can be used.
+	 * @param includeRunningVMBootclasspath <code>true</code> if the bootclasspath of the running VM must be prepended to the
+	 * given classpath and <code>false</code> 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 <code>
+	 * sourcepathEntries</code>
+	 * @since 3.6
+	 */
+	public void setEnvironment(String[] classpathEntries, String[] sourcepathEntries, String[] encodings, boolean includeRunningVMBootclasspath) {
+		this.classpaths = classpathEntries;
+		this.sourcepaths = sourcepathEntries;
+		this.sourcepathsEncodings = encodings;
+		if (encodings != null) {
+			if (sourcepathEntries == null || sourcepathEntries.length != encodings.length) {
+				throw new IllegalArgumentException(); 
+			}
+		}
+		if (includeRunningVMBootclasspath) {
+			this.bits |= CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH;
+		}
+	}
+	/**
+	 * Sets the compiler options to be used when parsing.
+	 * <p>
+	 * Note that {@link #setSource(IClassFile)},
+	 * {@link #setSource(ICompilationUnit)},
+	 * and {@link #setProject(IJavaProject)} reset the compiler options
+	 * based on the Java project. In other cases, compiler options default
+	 * to {@link JavaCore#getOptions()}. In either case, and especially
+	 * in the latter, the caller should carefully weight the consequences of
+	 * allowing compiler options to be defaulted as opposed to being
+	 * explicitly specified for the {@link ASTParser} instance.
+	 * For instance, there is a compiler option called "Source Compatibility Mode"
+	 * which determines which JDK level the source code is expected to meet.
+	 * If you specify "1.4", then "assert" is treated as a keyword and disallowed
+	 * as an identifier; if you specify "1.3", then "assert" is allowed as an
+	 * identifier. So this particular setting has a major bearing on what is
+	 * considered syntactically legal. By explicitly specifying the setting,
+	 * the client control exactly how the parser works. On the other hand,
+	 * allowing default settings means the parsing behaves like other JDT tools.
+	 * </p>
+	 *
+	 * @param options the table of options (key type: <code>String</code>;
+	 * value type: <code>String</code>), or <code>null</code>
+	 * to set it back to the default
+	 */
+	public void setCompilerOptions(Map options) {
+		if (options == null) {
+			options = JavaCore.getOptions();
+		} else {
+			// copy client's options so as to not do any side effect on them
+			options = new HashMap(options);
+		}
+		options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
+		this.compilerOptions = options;
+	}
+
+	/**
+	 * Requests that the compiler should provide binding information for
+	 * the AST nodes it creates.
+	 * <p>
+	 * Default to <code>false</code> (no bindings).
+	 * </p>
+	 * <p>
+	 * If {@link #setResolveBindings(boolean) setResolveBindings(true)}, the various names
+	 * and types appearing in the AST can be resolved to "bindings"
+	 * by calling the <code>resolveBinding</code> methods. These bindings
+	 * draw connections between the different parts of a program, and
+	 * generally afford a more powerful vantage point for clients who wish to
+	 * analyze a program's structure more deeply. These bindings come at a
+	 * considerable cost in both time and space, however, and should not be
+	 * requested frivolously. The additional space is not reclaimed until the
+	 * AST, all its nodes, and all its bindings become garbage. So it is very
+	 * important to not retain any of these objects longer than absolutely
+	 * necessary. Bindings are resolved at the time the AST is created. Subsequent
+	 * modifications to the AST do not affect the bindings returned by
+	 * <code>resolveBinding</code> methods in any way; these methods return the
+	 * same binding as before the AST was modified (including modifications
+	 * that rearrange subtrees by reparenting nodes).
+	 * If {@link #setResolveBindings(boolean) setResolveBindings(false)}, (the default), the analysis
+	 * does not go beyond parsing and building the tree, and all
+	 * <code>resolveBinding</code> methods return <code>null</code> from the outset.
+	 * </p>
+	 * <p>
+	 * When bindings are requested, instead of considering compilation units on disk only
+	 * one can supply a <code>WorkingCopyOwner</code>. Working copies owned
+	 * by this owner take precedence over the underlying compilation units when looking
+	 * up names and drawing the connections.
+	 * </p>
+	 * <p>Note that working copy owner are used only if the <code>org.eclipse.jdt.core</code>
+	 * bundle is initialized.</p>
+	 * <p>
+	 * Binding information is obtained from the Java model.
+	 * This means that the compilation unit must be located relative to the
+	 * Java model. This happens automatically when the source code comes from
+	 * either {@link #setSource(ICompilationUnit) setSource(ICompilationUnit)}
+	 * or {@link #setSource(IClassFile) setSource(IClassFile)}.
+	 * When source is supplied by {@link #setSource(char[]) setSource(char[])},
+	 * the location must be established explicitly by setting an environment using
+	 * {@link #setProject(IJavaProject)} or {@link #setEnvironment(String[], String[], String[], boolean)} 
+	 * and a unit name {@link #setUnitName(String)}.
+	 * Note that the compiler options that affect doc comment checking may also
+	 * affect whether any bindings are resolved for nodes within doc comments.
+	 * </p>
+	 *
+	 * @param enabled <code>true</code> if bindings are wanted,
+	 *   and <code>false</code> if bindings are not of interest
+	 */
+	public void setResolveBindings(boolean enabled) {
+		if (enabled) {
+			this.bits |= CompilationUnitResolver.RESOLVE_BINDING;
+		} else {
+			this.bits &= ~CompilationUnitResolver.RESOLVE_BINDING;
+		}
+	}
+
+	/**
+	 * Requests an abridged abstract syntax tree.
+	 * By default, complete ASTs are returned.
+	 * <p>
+	 * When the given <code>position</code> is a valid position within the source code of 
+	 * the compilation unit, the resulting AST does not have nodes for
+	 * the entire compilation unit. Rather, the AST is only fleshed out
+	 * for the node that include the given source position. This kind of limited
+	 * AST is sufficient for certain purposes but totally unsuitable for others.
+	 * In places where it can be used, the limited AST offers the advantage of
+	 * being smaller and faster to construct.
+	 * </p>
+	 * <p>
+	 * The AST will include nodes for all of the compilation unit's
+	 * package, import, and top-level type declarations. It will also always contain
+	 * nodes for all the body declarations for those top-level types, as well
+	 * as body declarations for any member types. However, some of the body
+	 * declarations may be abridged. In particular, the statements ordinarily
+	 * found in the body of a method declaration node will not be included
+	 * (the block will be empty) unless the source position falls somewhere
+	 * within the source range of that method declaration node. The same is true
+	 * for initializer declarations; the statements ordinarily found in the body
+	 * of initializer node will not be included unless the source position falls
+	 * somewhere within the source range of that initializer declaration node.
+	 * Field declarations are never abridged. Note that the AST for the body of
+	 * that one unabridged method (or initializer) is 100% complete; it has all
+	 * its statements, including any local or anonymous type declarations
+	 * embedded within them. When the given <code>position</code> is not located within
+	 * the source range of any body declaration of a top-level type, the AST
+	 * returned will be a skeleton that includes nodes for all and only the major
+	 * declarations; this kind of AST is still quite useful because it contains
+	 * all the constructs that introduce names visible to the world outside the
+	 * compilation unit.
+	 * </p>
+	 *
+	 * <p>This focal position is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 * 
+	 * @param position a position into the corresponding body declaration
+	 */
+	public void setFocalPosition(int position) {
+		this.bits |= CompilationUnitResolver.PARTIAL;
+		this.focalPointPosition = position;
+	}
+
+	/**
+	 * Sets the kind of constructs to be parsed from the source.
+	 * Defaults to an entire compilation unit.
+	 * <p>
+	 * When the parse is successful the result returned includes the ASTs for the
+	 * requested source:
+	 * <ul>
+	 * <li>{@link #K_COMPILATION_UNIT K_COMPILATION_UNIT}: The result node
+	 * is a {@link CompilationUnit}.</li>
+	 * <li>{@link #K_CLASS_BODY_DECLARATIONS K_CLASS_BODY_DECLARATIONS}: The result node
+	 * is a {@link TypeDeclaration} whose
+	 * {@link TypeDeclaration#bodyDeclarations() bodyDeclarations}
+	 * are the new trees. Other aspects of the type declaration are unspecified.</li>
+	 * <li>{@link #K_STATEMENTS K_STATEMENTS}: The result node is a
+	 * {@link Block Block} whose {@link Block#statements() statements}
+	 * are the new trees. Other aspects of the block are unspecified.</li>
+	 * <li>{@link #K_EXPRESSION K_EXPRESSION}: The result node is a subclass of
+	 * {@link Expression Expression}. Other aspects of the expression are unspecified.</li>
+	 * </ul>
+	 * The resulting AST node is rooted under (possibly contrived)
+	 * {@link CompilationUnit CompilationUnit} node, to allow the
+	 * client to retrieve the following pieces of information
+	 * available there:
+	 * <ul>
+	 * <li>{@linkplain CompilationUnit#getLineNumber(int) Line number map}. Line
+	 * numbers start at 1 and only cover the subrange scanned
+	 * (<code>source[offset]</code> through <code>source[offset+length-1]</code>).</li>
+	 * <li>{@linkplain CompilationUnit#getMessages() Compiler messages}
+	 * and {@linkplain CompilationUnit#getProblems() detailed problem reports}.
+	 * Character positions are relative to the start of
+	 * <code>source</code>; line positions are for the subrange scanned.</li>
+	 * <li>{@linkplain CompilationUnit#getCommentList() Comment list}
+	 * for the subrange scanned.</li>
+	 * </ul>
+	 * The contrived nodes do not have source positions. Other aspects of the
+	 * {@link CompilationUnit CompilationUnit} node are unspecified, including
+	 * the exact arrangement of intervening nodes.
+	 * </p>
+	 * <p>
+	 * Lexical or syntax errors detected while parsing can result in
+	 * a result node being marked as {@link ASTNode#MALFORMED MALFORMED}.
+	 * In more severe failure cases where the parser is unable to
+	 * recognize the input, this method returns
+	 * a {@link CompilationUnit CompilationUnit} node with at least the
+	 * compiler messages.
+	 * </p>
+	 * <p>Each node in the subtree (other than the contrived nodes)
+	 * carries source range(s) information relating back
+	 * to positions in the given source (the given source itself
+	 * is not remembered with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * </p>
+	 * <p>
+	 * Binding information is only computed when <code>kind</code> is
+	 * {@link #K_COMPILATION_UNIT}.
+	 * </p>
+	 * 
+	 * <p>This kind is not used when the AST is built using
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 * 
+	 * @param kind the kind of construct to parse: one of
+	 * {@link #K_COMPILATION_UNIT},
+	 * {@link #K_CLASS_BODY_DECLARATIONS},
+	 * {@link #K_EXPRESSION},
+	 * {@link #K_STATEMENTS}
+	 */
+	public void setKind(int kind) {
+	    if ((kind != K_COMPILATION_UNIT)
+		    && (kind != K_CLASS_BODY_DECLARATIONS)
+		    && (kind != K_EXPRESSION)
+		    && (kind != K_STATEMENTS)) {
+	    	throw new IllegalArgumentException();
+	    }
+		this.astKind = kind;
+	}
+
+	/**
+	 * Sets the source code to be parsed.
+	 *
+	 * <p>This source is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 *
+	 * <p>If this method is used, the user needs to specify compiler options explicitly using
+	 * {@link #setCompilerOptions(Map)} as 1.5 code will not be properly parsed without setting
+	 * the appropriate values for the compiler options: {@link JavaCore#COMPILER_SOURCE},
+	 * {@link JavaCore#COMPILER_CODEGEN_TARGET_PLATFORM}, and {@link JavaCore#COMPILER_COMPLIANCE}.</p>
+	 * <p>Otherwise the default values for the compiler options will be used to parse the given source.</p>
+	 *
+	 * @param source the source string to be parsed,
+	 * or <code>null</code> if none
+	 * @see JavaCore#setComplianceOptions(String, Map)
+	 */
+	public void setSource(char[] source) {
+		this.rawSource = source;
+		// clear the type root
+		this.typeRoot = null;
+	}
+
+	/**
+	 * Sets the source code to be parsed.
+	 * 
+	 * <p>This method automatically sets the project (and compiler
+	 * options) based on the given compilation unit, in a manner
+	 * equivalent to {@link #setProject(IJavaProject) setProject(source.getJavaProject())}.</p>
+	 *
+	 * <p>This source is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 * 
+	 * @param source the Java model compilation unit whose source code
+	 * is to be parsed, or <code>null</code> if none
+	 */
+	public void setSource(ICompilationUnit source) {
+		setSource((ITypeRoot)source);
+	}
+
+	/**
+	 * Sets the source code to be parsed.
+	 *
+	 * <p>This method automatically sets the project (and compiler
+	 * options) based on the given compilation unit, in a manner
+	 * equivalent to {@link #setProject(IJavaProject) setProject(source.getJavaProject())}.</p>
+	 * <p>If the given class file has  no source attachment, the creation of the
+	 * ast will fail with an {@link IllegalStateException}.</p>
+	 *
+	 * <p>This source is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 * 
+	 * @param source the Java model class file whose corresponding source code
+	 * is to be parsed, or <code>null</code> if none
+	 */
+	public void setSource(IClassFile source) {
+		setSource((ITypeRoot)source);
+	}
+
+	/**
+	 * Sets the source code to be parsed.
+	 *
+	 * <p>This method automatically sets the project (and compiler
+	 * options) based on the given compilation unit of class file, in a manner
+	 * equivalent to {@link #setProject(IJavaProject) setProject(source.getJavaProject())}.</p>
+	 * <p>If the source is a class file without source attachment, the creation of the
+	 * ast will fail with an {@link IllegalStateException}.</p>
+	 *
+	 * <p>This source is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 *
+	 * @param source the Java model compilation unit or class file whose corresponding source code
+	 * is to be parsed, or <code>null</code> if none
+	 * @since 3.3
+	 */
+	public void setSource(ITypeRoot source) {
+		this.typeRoot = source;
+		// clear the raw source
+		this.rawSource = null;
+		if (source != null) {
+			this.project = source.getJavaProject();
+			Map options = this.project.getOptions(true);
+			options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
+			this.compilerOptions = options;
+		}
+	}
+
+	/**
+     * Sets the subrange of the source code to be parsed.
+     * By default, the entire source string will be parsed
+     * (<code>offset</code> 0 and <code>length</code> -1).
+     *
+	 * <p>This range is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+     *
+     * @param offset the index of the first character to parse
+     * @param length the number of characters to parse, or -1 if
+     * the remainder of the source string is to be parsed
+     */
+	public void setSourceRange(int offset, int length) {
+		if (offset < 0 || length < -1) {
+			throw new IllegalArgumentException();
+		}
+		this.sourceOffset = offset;
+		this.sourceLength = length;
+	}
+
+	/**
+	 * Requests that the compiler should perform statements recovery.
+	 * When statements recovery is enabled the compiler tries to create statement nodes
+	 * from code containing syntax errors
+     * <p>
+     * Default to <code>false</code>.
+     * </p>
+	 *
+	 * @param enabled <code>true</code> if statements containing syntax errors are wanted,
+	 *   and <code>false</code> if these statements aren't wanted.
+	 *
+	 * @since 3.2
+	 */
+	public void setStatementsRecovery(boolean enabled) {
+		if (enabled) {
+			this.bits |= CompilationUnitResolver.STATEMENT_RECOVERY;
+		} else {
+			this.bits &= ~CompilationUnitResolver.STATEMENT_RECOVERY;
+		}
+	}
+	
+	/**
+	 * Requests an abstract syntax tree without method bodies. 
+	 * 
+	 * <p>When ignore method bodies is enabled, all method bodies are discarded.
+	 * This has no impact on the binding resolution.</p>
+	 *
+	 * <p>This setting is not used when the kind used in {@link #setKind(int)} is either 
+	 * {@link #K_EXPRESSION} or {@link #K_STATEMENTS}.</p>
+	 * @since 3.5.2
+	 */
+	public void setIgnoreMethodBodies(boolean enabled) {
+		if (enabled) {
+			this.bits |= CompilationUnitResolver.IGNORE_METHOD_BODIES;
+		} else {
+			this.bits &= ~CompilationUnitResolver.IGNORE_METHOD_BODIES;
+		}
+	}
+
+    /**
+     * Sets the working copy owner using when resolving bindings, where
+     * <code>null</code> means the primary owner. Defaults to the primary owner.
+     *
+	 * @param owner the owner of working copies that take precedence over underlying
+	 *   compilation units, or <code>null</code> if the primary owner should be used
+     */
+	public void setWorkingCopyOwner(WorkingCopyOwner owner) {
+	    if (owner == null) {
+			this.workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
+		} else {
+			this.workingCopyOwner = owner;
+	 	}
+	}
+
+	/**
+	 * Sets the name of the compilation unit that would hypothetically contains the
+	 * source string.
+	 * 
+	 *  <p>This is used in conjunction with {@link #setSource(char[])}
+	 * and {@link #setProject(IJavaProject)} to locate the compilation unit relative to a Java project.
+	 * Defaults to none (<code>null</code>).</p>
+	 * <p>
+	 * The name of the compilation unit must be supplied for resolving bindings.
+	 * This name should be suffixed by a dot ('.') followed by one of the
+	 * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
+	 * and match the name of the main (public) class or interface declared in the source.</p>
+	 *
+	 * <p>This name must represent the full path of the unit inside the given project. For example, if the source
+	 * declares a public class named "Foo" in a project "P" where the source folder is the project itself, the name
+	 * of the compilation unit must be "/P/Foo.java".
+	 * If the source declares a public class name "Bar" in a package "p1.p2" in a project "P" in a source folder "src",
+	 * the name of the compilation unit must be "/P/src/p1/p2/Bar.java".</p>
+	 *
+	 * <p>This unit name is not used when the AST is built using 
+	 * {@link #createASTs(ICompilationUnit[], String[], ASTRequestor, IProgressMonitor)}.</p>
+	 *
+	 * @param unitName the name of the compilation unit that would contain the source
+	 *    string, or <code>null</code> if none
+	 */
+	public void setUnitName(String unitName) {
+		this.unitName = unitName;
+	}
+
+	/**
+	 * Sets the Java project used when resolving bindings.
+	 * 
+	 * <p>This method automatically sets the compiler
+	 * options based on the given project:</p>
+	 * <pre>
+	 * setCompilerOptions(project.getOptions(true));
+	 * </pre>
+	 * <p>See {@link #setCompilerOptions(Map)} for a discussion of
+	 * the pros and cons of using these options vs specifying
+	 * compiler options explicitly.</p>
+	 * <p>This setting is used in conjunction with {@link #setSource(char[])}.
+	 * For the purposes of resolving bindings, types declared in the
+	 * source string will hide types by the same name available
+	 * through the classpath of the given project.</p>
+	 * <p>Defaults to none (<code>null</code>).</p>
+	 *
+	 * @param project the Java project used to resolve names, or
+	 *    <code>null</code> if none
+	 */
+	public void setProject(IJavaProject project) {
+		this.project = project;
+		if (project != null) {
+			Map options = project.getOptions(true);
+			options.remove(JavaCore.COMPILER_TASK_TAGS); // no need to parse task tags
+			this.compilerOptions = options;
+		}
+	}
+
+	/**
+	 * Creates an abstract syntax tree.
+	 * <p>
+	 * A successful call to this method returns all settings to their
+	 * default values so the object is ready to be reused.
+	 * </p>
+	 *
+	 * @param monitor the progress monitor used to report progress and request cancellation,
+	 *   or <code>null</code> if none
+	 * @return an AST node whose type depends on the kind of parse
+	 *  requested, with a fallback to a <code>CompilationUnit</code>
+	 *  in the case of severe parsing errors
+	 * @exception IllegalStateException if the settings provided
+	 * are insufficient, contradictory, or otherwise unsupported
+	 */
+	public ASTNode createAST(IProgressMonitor monitor) {
+		ASTNode result = null;
+		if (monitor != null) monitor.beginTask("", 1); //$NON-NLS-1$
+		try {
+			if (this.rawSource == null && this.typeRoot == null) {
+				throw new IllegalStateException("source not specified"); //$NON-NLS-1$
+			}
+			result = internalCreateAST(monitor);
+		} finally {
+			// reset to defaults to allow reuse (and avoid leaking)
+			initializeDefaults();
+			if (monitor != null) monitor.done();
+		}
+		return result;
+	}
+
+	/**
+	 * Creates ASTs for a batch of compilation units.
+	 * <p>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.</p>
+	 * <p>
+	 * When bindings are being resolved, all compilation units must
+	 * come from the same Java project, which must be set beforehand
+	 * with {@link #setProject(IJavaProject) setProject}.</p>
+	 * <p>The compilation units are processed one at a time in no
+	 * specified order. For each of the compilation units in turn,</p>
+	 * <ul>
+	 * <li>{@link #createAST(IProgressMonitor) ASTParser.createAST} is called to parse it
+	 * and create a corresponding AST. The calls to
+	 * {@link #createAST(IProgressMonitor) ASTParser.createAST} all employ the same settings.</li>
+	 * <li>{@link ASTRequestor#acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST}
+	 * is called passing the compilation unit and the corresponding AST to <code>requestor</code>.
+	 * </li>
+	 * </ul>
+	 * 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.
+	 * </p>
+	 * <p>
+	 * Note also the following parser parameters are used, regardless of what
+	 * may have been specified:
+	 * <ul>
+	 * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
+	 * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
+	 * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * 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 ASTRequestor#acceptBinding(String, IBinding) ASTRequestor.acceptBinding}.
+	 * Note that binding keys for elements outside the set of compilation units being processed
+	 * are looked up after all {@link ASTRequestor#acceptAST(ICompilationUnit, 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 ASTRequestor#acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST} callback has been made.
+	 * No {@link ASTRequestor#acceptBinding(String, IBinding) ASTRequestor.acceptBinding} callbacks are made unless
+	 * bindings are being resolved.
+	 * </p>
+	 * <p>
+	 * A successful call to this method returns all settings to their
+	 * default values so the object is ready to be reused.
+	 * </p>
+	 *
+	 * @param compilationUnits the compilation units to create ASTs for
+	 * @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.1
+	 */
+	public void createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor) {
+		try {
+			int flags = 0;
+			if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
+				flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
+			}
+			if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) {
+				flags |= ICompilationUnit.IGNORE_METHOD_BODIES;
+			}
+			if ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0) {
+				if (this.project == null)
+					throw new IllegalStateException("project not specified"); //$NON-NLS-1$
+				if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) {
+					flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
+				}
+				CompilationUnitResolver.resolve(compilationUnits, bindingKeys, requestor, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, monitor);
+			} else {
+				CompilationUnitResolver.parse(compilationUnits, requestor, this.apiLevel, this.compilerOptions, flags, monitor);
+			}
+		} finally {
+			// reset to defaults to allow reuse (and avoid leaking)
+			initializeDefaults();
+		}
+	}
+
+	/**
+	 * 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.
+	 * <p>
+	 * 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,
+	 * <ul>
+	 * <li>{@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>
+	 * <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.
+	 * </li>
+	 * </ul>
+	 * 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.
+	 * </p>
+	 * <p>
+	 * Note also the following parser parameters are used, regardless of what
+	 * may have been specified:
+	 * <ul>
+	 * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
+	 * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
+	 * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * 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.
+	 * </p>
+	 * <p>
+	 * A successful call to this method returns all settings to their
+	 * default values so the object is ready to be reused.
+	 * </p>
+	 * <p>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>.</p>
+	 *
+	 * @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) {
+		try {
+			int flags = 0;
+			if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
+				flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
+			}
+			if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) {
+				flags |= ICompilationUnit.IGNORE_METHOD_BODIES;
+			}
+			if ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0) {
+				if (this.classpaths == null && this.sourcepaths == null && ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) == 0)) {
+					throw new IllegalStateException("no environment is specified"); //$NON-NLS-1$
+				}
+				if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) {
+					flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
+				}
+				CompilationUnitResolver.resolve(sourceFilePaths, encodings, bindingKeys, requestor, this.apiLevel, this.compilerOptions, getClasspath(), flags, monitor);
+			} else {
+				CompilationUnitResolver.parse(sourceFilePaths, encodings, requestor, this.apiLevel, this.compilerOptions, flags, monitor);
+			}
+		} finally {
+			// reset to defaults to allow reuse (and avoid leaking)
+			initializeDefaults();
+		}
+	}
+	/**
+	 * Creates bindings for a batch of Java elements.
+	 * 
+	 * <p>These elements are either
+	 * enclosed in {@link ICompilationUnit ICompilationUnits} or in {@link IClassFile IClassFiles}.</p>
+	 * <p>
+	 * All enclosing compilation units and class files must
+	 * come from the same Java project, which must be set beforehand
+	 * with {@link #setProject(IJavaProject) setProject}.
+	 * </p>
+	 * <p>
+	 * All elements must exist. If one doesn't exist, an {@link IllegalStateException}
+	 * is thrown.
+	 * </p>
+	 * <p>
+	 * The returned array has the same size as the given elements array. At a given position
+	 * it contains the binding of the corresponding Java element, or <code>null</code>
+	 * if no binding could be created.
+	 * </p>
+	 * <p>
+	 * Note also the following parser parameters are used, regardless of what
+	 * may have been specified:
+	 * <ul>
+	 * <li>The {@linkplain #setResolveBindings(boolean) binding resolution flag} is <code>true</code></li>
+	 * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
+	 * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
+	 * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * A successful call to this method returns all settings to their
+	 * default values so the object is ready to be reused.
+	 * </p>
+	 *
+	 * @param elements the Java elements to create bindings for
+	 * @return the bindings for the given Java elements, possibly containing <code>null</code>s
+	 *              if some bindings could not be created
+	 * @exception IllegalStateException if the settings provided
+	 * are insufficient, contradictory, or otherwise unsupported
+	 * @since 3.1
+	 */
+	public IBinding[] createBindings(IJavaElement[] elements, IProgressMonitor monitor) {
+		try {
+			if (this.project == null)
+				throw new IllegalStateException("project or classpath not specified"); //$NON-NLS-1$
+			int flags = 0;
+			if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
+				flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
+			}
+			if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) {
+				flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
+			}
+			if ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0) {
+				flags |= ICompilationUnit.IGNORE_METHOD_BODIES;
+			}
+			return CompilationUnitResolver.resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, flags, monitor);
+		} finally {
+			// reset to defaults to allow reuse (and avoid leaking)
+			initializeDefaults();
+		}
+	}
+
+	private ASTNode internalCreateAST(IProgressMonitor monitor) {
+		boolean needToResolveBindings = (this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0;
+		switch(this.astKind) {
+			case K_CLASS_BODY_DECLARATIONS :
+			case K_EXPRESSION :
+			case K_STATEMENTS :
+				if (this.rawSource == null) {
+					if (this.typeRoot != null) {
+						// get the source from the type root
+						if (this.typeRoot instanceof ICompilationUnit) {
+							org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.typeRoot;
+							this.rawSource = sourceUnit.getContents();
+						} else if (this.typeRoot instanceof IClassFile) {
+							try {
+								String sourceString = this.typeRoot.getSource();
+								if (sourceString != null) {
+									this.rawSource = sourceString.toCharArray();
+								}
+							} catch(JavaModelException e) {
+								// an error occured accessing the java element
+								StringWriter stringWriter = new StringWriter();
+								PrintWriter writer = null;
+								try {
+									writer = new PrintWriter(stringWriter);
+									e.printStackTrace(writer);
+								} finally {
+									if (writer != null) writer.close();
+								}
+								throw new IllegalStateException(String.valueOf(stringWriter.getBuffer()));
+							}
+						}
+					}
+				}
+				if (this.rawSource != null) {
+					if (this.sourceOffset + this.sourceLength > this.rawSource.length) {
+						throw new IllegalStateException();
+					}
+					return internalCreateASTForKind();
+				}
+				break;
+			case K_COMPILATION_UNIT :
+				CompilationUnitDeclaration compilationUnitDeclaration = null;
+				try {
+					NodeSearcher searcher = null;
+					org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = null;
+					WorkingCopyOwner wcOwner = this.workingCopyOwner;
+					if (this.typeRoot instanceof ICompilationUnit) {
+							/*
+							 * this.compilationUnitSource is an instance of org.eclipse.jdt.internal.core.CompilationUnit that implements
+							 * both org.eclipse.jdt.core.ICompilationUnit and org.eclipse.jdt.internal.compiler.env.ICompilationUnit
+							 */
+							sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.typeRoot;
+							/*
+							 * use a BasicCompilation that caches the source instead of using the compilationUnitSource directly
+							 * (if it is a working copy, the source can change between the parse and the AST convertion)
+							 * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=75632)
+							 */
+							sourceUnit = new BasicCompilationUnit(sourceUnit.getContents(), sourceUnit.getPackageName(), new String(sourceUnit.getFileName()), this.project);
+							wcOwner = ((ICompilationUnit) this.typeRoot).getOwner();
+					} else if (this.typeRoot instanceof IClassFile) {
+						try {
+							String sourceString = this.typeRoot.getSource();
+							if (sourceString == null) {
+								throw new IllegalStateException();
+							}
+							PackageFragment packageFragment = (PackageFragment) this.typeRoot.getParent();
+							BinaryType type = (BinaryType) this.typeRoot.findPrimaryType();
+							IBinaryType binaryType = (IBinaryType) type.getElementInfo();
+							// file name is used to recreate the Java element, so it has to be the toplevel .class file name
+							char[] fileName = binaryType.getFileName();
+							int firstDollar = CharOperation.indexOf('$', fileName);
+							if (firstDollar != -1) {
+								char[] suffix = SuffixConstants.SUFFIX_class;
+								int suffixLength = suffix.length;
+								char[] newFileName = new char[firstDollar + suffixLength];
+								System.arraycopy(fileName, 0, newFileName, 0, firstDollar);
+								System.arraycopy(suffix, 0, newFileName, firstDollar, suffixLength);
+								fileName = newFileName;
+							}
+							sourceUnit = new BasicCompilationUnit(sourceString.toCharArray(), Util.toCharArrays(packageFragment.names), new String(fileName), this.project);
+						} catch(JavaModelException e) {
+							// an error occured accessing the java element
+							StringWriter stringWriter = new StringWriter();
+							PrintWriter writer = null;
+							try {
+								writer = new PrintWriter(stringWriter);
+								e.printStackTrace(writer);
+							} finally {
+								if (writer != null) writer.close();
+							}
+							throw new IllegalStateException(String.valueOf(stringWriter.getBuffer()));
+						}
+					} else if (this.rawSource != null) {
+						needToResolveBindings = 
+							((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0)
+							&& this.unitName != null
+							&& (this.project != null
+									|| this.classpaths != null
+									|| this.sourcepaths != null
+									|| ((this.bits & CompilationUnitResolver.INCLUDE_RUNNING_VM_BOOTCLASSPATH) != 0))
+							&& this.compilerOptions != null;
+						sourceUnit = new BasicCompilationUnit(this.rawSource, null, this.unitName == null ? "" : this.unitName, this.project); //$NON-NLS-1$
+					} else {
+						throw new IllegalStateException();
+					}
+					if ((this.bits & CompilationUnitResolver.PARTIAL) != 0) {
+						searcher = new NodeSearcher(this.focalPointPosition);
+					}
+					int flags = 0;
+					if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
+						flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
+					}
+					if (searcher == null && ((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0)) {
+						flags |= ICompilationUnit.IGNORE_METHOD_BODIES;
+					}
+					if (needToResolveBindings) {
+						if ((this.bits & CompilationUnitResolver.BINDING_RECOVERY) != 0) {
+							flags |= ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
+						}
+						try {
+							// parse and resolve
+							compilationUnitDeclaration =
+								CompilationUnitResolver.resolve(
+									sourceUnit,
+									this.project,
+									getClasspath(),
+									searcher,
+									this.compilerOptions,
+									this.workingCopyOwner,
+									flags,
+									monitor);
+						} catch (JavaModelException e) {
+							flags &= ~ICompilationUnit.ENABLE_BINDINGS_RECOVERY;
+							compilationUnitDeclaration = CompilationUnitResolver.parse(
+									sourceUnit,
+									searcher,
+									this.compilerOptions,
+									flags);
+							needToResolveBindings = false;
+						}
+					} else {
+						compilationUnitDeclaration = CompilationUnitResolver.parse(
+								sourceUnit,
+								searcher,
+								this.compilerOptions,
+								flags);
+						needToResolveBindings = false;
+					}
+					CompilationUnit result = CompilationUnitResolver.convert(
+						compilationUnitDeclaration,
+						sourceUnit.getContents(),
+						this.apiLevel,
+						this.compilerOptions,
+						needToResolveBindings,
+						wcOwner,
+						needToResolveBindings ? new DefaultBindingResolver.BindingTables() : null,
+						flags,
+						monitor,
+						this.project != null);
+					result.setTypeRoot(this.typeRoot);
+					return result;
+				} finally {
+					if (compilationUnitDeclaration != null
+							&& ((this.bits & CompilationUnitResolver.RESOLVE_BINDING) != 0)) {
+						compilationUnitDeclaration.cleanUp();
+					}
+				}
+		}
+		throw new IllegalStateException();
+	}
+
+	/**
+	 * Parses the given source between the bounds specified by the given offset (inclusive)
+	 * and the given length and creates and returns a corresponding abstract syntax tree.
+	 * <p>
+	 * When the parse is successful the result returned includes the ASTs for the
+	 * requested source:
+	 * <ul>
+	 * <li>{@link #K_CLASS_BODY_DECLARATIONS K_CLASS_BODY_DECLARATIONS}: The result node
+	 * is a {@link TypeDeclaration TypeDeclaration} whose
+	 * {@link TypeDeclaration#bodyDeclarations() bodyDeclarations}
+	 * are the new trees. Other aspects of the type declaration are unspecified.</li>
+	 * <li>{@link #K_STATEMENTS K_STATEMENTS}: The result node is a
+	 * {@link Block Block} whose {@link Block#statements() statements}
+	 * are the new trees. Other aspects of the block are unspecified.</li>
+	 * <li>{@link #K_EXPRESSION K_EXPRESSION}: The result node is a subclass of
+	 * {@link Expression Expression}. Other aspects of the expression are unspecified.</li>
+	 * </ul>
+	 * The resulting AST node is rooted under an contrived
+	 * {@link CompilationUnit CompilationUnit} node, to allow the
+	 * client to retrieve the following pieces of information
+	 * available there:
+	 * <ul>
+	 * <li>{@linkplain CompilationUnit#getLineNumber(int) Line number map}. Line
+	 * numbers start at 1 and only cover the subrange scanned
+	 * (<code>source[offset]</code> through <code>source[offset+length-1]</code>).</li>
+	 * <li>{@linkplain CompilationUnit#getMessages() Compiler messages}
+	 * and {@linkplain CompilationUnit#getProblems() detailed problem reports}.
+	 * Character positions are relative to the start of
+	 * <code>source</code>; line positions are for the subrange scanned.</li>
+	 * <li>{@linkplain CompilationUnit#getCommentList() Comment list}
+	 * for the subrange scanned.</li>
+	 * </ul>
+	 * The contrived nodes do not have source positions. Other aspects of the
+	 * {@link CompilationUnit CompilationUnit} node are unspecified, including
+	 * the exact arrangment of intervening nodes.
+	 * </p>
+	 * <p>
+	 * Lexical or syntax errors detected while parsing can result in
+	 * a result node being marked as {@link ASTNode#MALFORMED MALFORMED}.
+	 * In more severe failure cases where the parser is unable to
+	 * recognize the input, this method returns
+	 * a {@link CompilationUnit CompilationUnit} node with at least the
+	 * compiler messages.
+	 * </p>
+	 * <p>Each node in the subtree (other than the contrived nodes)
+	 * carries source range(s) information relating back
+	 * to positions in the given source (the given source itself
+	 * is not remembered with the AST).
+	 * The source range usually begins at the first character of the first token
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * </p>
+	 * <p>
+	 * This method does not compute binding information; all <code>resolveBinding</code>
+	 * methods applied to nodes of the resulting AST return <code>null</code>.
+	 * </p>
+	 *
+	 * @return an AST node whose type depends on the kind of parse
+	 *  requested, with a fallback to a <code>CompilationUnit</code>
+	 *  in the case of severe parsing errors
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 */
+	private ASTNode internalCreateASTForKind() {
+		final ASTConverter converter = new ASTConverter(this.compilerOptions, false, null);
+		converter.compilationUnitSource = this.rawSource;
+		converter.compilationUnitSourceLength = this.rawSource.length;
+		converter.scanner.setSource(this.rawSource);
+
+		AST ast = AST.newAST(this.apiLevel);
+		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+		ast.setBindingResolver(new BindingResolver());
+		if ((this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0) {
+			ast.setFlag(ICompilationUnit.ENABLE_STATEMENTS_RECOVERY);
+		}
+		converter.setAST(ast);
+		CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil((this.bits & CompilationUnitResolver.IGNORE_METHOD_BODIES) != 0);
+		CompilationUnit compilationUnit = ast.newCompilationUnit();
+		if (this.sourceLength == -1) {
+			this.sourceLength = this.rawSource.length;
+		}
+		switch(this.astKind) {
+			case K_STATEMENTS :
+				ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(
+						this.rawSource,
+						this.sourceOffset,
+						this.sourceLength,
+						this.compilerOptions,
+						true,
+						(this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0);
+				RecoveryScannerData data = constructorDeclaration.compilationResult.recoveryScannerData;
+				if(data != null) {
+					Scanner scanner = converter.scanner;
+					converter.scanner = new RecoveryScanner(scanner, data.removeUnused());
+					converter.docParser.scanner = converter.scanner;
+					converter.scanner.setSource(scanner.source);
+					
+					compilationUnit.setStatementsRecoveryData(data);
+				}
+				RecordedParsingInformation recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
+				int[][] comments = recordedParsingInformation.commentPositions;
+				if (comments != null) {
+					converter.buildCommentsTable(compilationUnit, comments);
+				}
+				compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds);
+				Block block = ast.newBlock();
+				block.setSourceRange(this.sourceOffset, this.sourceOffset + this.sourceLength);
+				org.eclipse.jdt.internal.compiler.ast.Statement[] statements = constructorDeclaration.statements;
+				if (statements != null) {
+					int statementsLength = statements.length;
+					for (int i = 0; i < statementsLength; i++) {
+						if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+							converter.checkAndAddMultipleLocalDeclaration(statements, i, block.statements());
+						} else {
+							Statement statement = converter.convert(statements[i]);
+							if (statement != null) {
+								block.statements().add(statement);
+							}
+						}
+					}
+				}
+				rootNodeToCompilationUnit(ast, compilationUnit, block, recordedParsingInformation, data);
+				ast.setDefaultNodeFlag(0);
+				ast.setOriginalModificationCount(ast.modificationCount());
+				return block;
+			case K_EXPRESSION :
+				org.eclipse.jdt.internal.compiler.ast.Expression expression = codeSnippetParsingUtil.parseExpression(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true);
+				recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
+				comments = recordedParsingInformation.commentPositions;
+				if (comments != null) {
+					converter.buildCommentsTable(compilationUnit, comments);
+				}
+				compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds);
+				if (expression != null) {
+					Expression expression2 = converter.convert(expression);
+					rootNodeToCompilationUnit(expression2.getAST(), compilationUnit, expression2, codeSnippetParsingUtil.recordedParsingInformation, null);
+					ast.setDefaultNodeFlag(0);
+					ast.setOriginalModificationCount(ast.modificationCount());
+					return expression2;
+				} else {
+					CategorizedProblem[] problems = recordedParsingInformation.problems;
+					if (problems != null) {
+						compilationUnit.setProblems(problems);
+					}
+					ast.setDefaultNodeFlag(0);
+					ast.setOriginalModificationCount(ast.modificationCount());
+					return compilationUnit;
+				}
+			case K_CLASS_BODY_DECLARATIONS :
+				final org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes =
+					codeSnippetParsingUtil.parseClassBodyDeclarations(
+							this.rawSource,
+							this.sourceOffset,
+							this.sourceLength,
+							this.compilerOptions,
+							true,
+							(this.bits & CompilationUnitResolver.STATEMENT_RECOVERY) != 0);
+				recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation;
+				comments = recordedParsingInformation.commentPositions;
+				if (comments != null) {
+					converter.buildCommentsTable(compilationUnit, comments);
+				}
+				compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds);
+				if (nodes != null) {
+					// source has no syntax error or the statement recovery is enabled
+					TypeDeclaration typeDeclaration = converter.convert(nodes);
+					typeDeclaration.setSourceRange(this.sourceOffset, this.sourceOffset + this.sourceLength);
+					rootNodeToCompilationUnit(typeDeclaration.getAST(), compilationUnit, typeDeclaration, codeSnippetParsingUtil.recordedParsingInformation, null);
+					ast.setDefaultNodeFlag(0);
+					ast.setOriginalModificationCount(ast.modificationCount());
+					return typeDeclaration;
+				} else {
+					// source has syntax error and the statement recovery is disabled
+					CategorizedProblem[] problems = recordedParsingInformation.problems;
+					if (problems != null) {
+						compilationUnit.setProblems(problems);
+					}
+					ast.setDefaultNodeFlag(0);
+					ast.setOriginalModificationCount(ast.modificationCount());
+					return compilationUnit;
+				}
+		}
+		throw new IllegalStateException();
+	}
+
+	private void propagateErrors(ASTNode astNode, CategorizedProblem[] problems, RecoveryScannerData data) {
+		astNode.accept(new ASTSyntaxErrorPropagator(problems));
+		if (data != null) {
+			astNode.accept(new ASTRecoveryPropagator(problems, data));
+		}
+	}
+
+	private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation, RecoveryScannerData data) {
+		final int problemsCount = recordedParsingInformation.problemsCount;
+		switch(node.getNodeType()) {
+			case ASTNode.BLOCK :
+				{
+					Block block = (Block) node;
+					if (problemsCount != 0) {
+						// propagate and record problems
+						final CategorizedProblem[] problems = recordedParsingInformation.problems;
+						propagateErrors(block, problems, data);
+						compilationUnit.setProblems(problems);
+					}
+					TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
+					Initializer initializer = ast.newInitializer();
+					initializer.setBody(block);
+					typeDeclaration.bodyDeclarations().add(initializer);
+					compilationUnit.types().add(typeDeclaration);
+				}
+				break;
+			case ASTNode.TYPE_DECLARATION :
+				{
+					TypeDeclaration typeDeclaration = (TypeDeclaration) node;
+					if (problemsCount != 0) {
+						// propagate and record problems
+						final CategorizedProblem[] problems = recordedParsingInformation.problems;
+						propagateErrors(typeDeclaration, problems, data);
+						compilationUnit.setProblems(problems);
+					}
+					compilationUnit.types().add(typeDeclaration);
+				}
+				break;
+			default :
+				if (node instanceof Expression) {
+					Expression expression = (Expression) node;
+					if (problemsCount != 0) {
+						// propagate and record problems
+						final CategorizedProblem[] problems = recordedParsingInformation.problems;
+						propagateErrors(expression, problems, data);
+						compilationUnit.setProblems(problems);
+					}
+					ExpressionStatement expressionStatement = ast.newExpressionStatement(expression);
+					Block block = ast.newBlock();
+					block.statements().add(expressionStatement);
+					Initializer initializer = ast.newInitializer();
+					initializer.setBody(block);
+					TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
+					typeDeclaration.bodyDeclarations().add(initializer);
+					compilationUnit.types().add(typeDeclaration);
+				}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java
new file mode 100644
index 0000000..28371d6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+import java.util.Vector;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToIntArray;
+
+/**
+ * Internal AST visitor for propagating syntax errors.
+ */
+class ASTRecoveryPropagator extends DefaultASTVisitor {
+	private static final int NOTHING = -1;
+	HashtableOfObjectToIntArray endingTokens = new HashtableOfObjectToIntArray();
+	{
+		this.endingTokens.put(AnonymousClassDeclaration.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(ArrayAccess.class, new int[]{TerminalTokens.TokenNameRBRACKET});
+		this.endingTokens.put(ArrayCreation.class, new int[]{NOTHING, TerminalTokens.TokenNameRBRACKET});
+		this.endingTokens.put(ArrayInitializer.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(ArrayType.class, new int[]{TerminalTokens.TokenNameRBRACKET});
+		this.endingTokens.put(AssertStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(Block.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(BooleanLiteral.class, new int[]{TerminalTokens.TokenNamefalse, TerminalTokens.TokenNametrue});
+		this.endingTokens.put(BreakStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(CharacterLiteral.class, new int[]{TerminalTokens.TokenNameCharacterLiteral});
+		this.endingTokens.put(ClassInstanceCreation.class, new int[]{TerminalTokens.TokenNameRBRACE, TerminalTokens.TokenNameRPAREN});
+		this.endingTokens.put(ConstructorInvocation.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(ContinueStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(DoStatement.class, new int[]{TerminalTokens.TokenNameRPAREN});
+		this.endingTokens.put(EmptyStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(ExpressionStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(FieldDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(ImportDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(Initializer.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(MethodDeclaration.class, new int[]{NOTHING, TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(MethodInvocation.class, new int[]{TerminalTokens.TokenNameRPAREN});
+		this.endingTokens.put(NullLiteral.class, new int[]{TerminalTokens.TokenNamenull});
+		this.endingTokens.put(NumberLiteral.class, new int[]{TerminalTokens.TokenNameIntegerLiteral, TerminalTokens.TokenNameLongLiteral, TerminalTokens.TokenNameFloatingPointLiteral, TerminalTokens.TokenNameDoubleLiteral});
+		this.endingTokens.put(PackageDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(ParenthesizedExpression.class, new int[]{TerminalTokens.TokenNameRPAREN});
+		this.endingTokens.put(PostfixExpression.class, new int[]{TerminalTokens.TokenNamePLUS_PLUS, TerminalTokens.TokenNameMINUS_MINUS});
+		this.endingTokens.put(PrimitiveType.class, new int[]{TerminalTokens.TokenNamebyte, TerminalTokens.TokenNameshort, TerminalTokens.TokenNamechar, TerminalTokens.TokenNameint, TerminalTokens.TokenNamelong, TerminalTokens.TokenNamefloat, TerminalTokens.TokenNameboolean, TerminalTokens.TokenNamedouble, TerminalTokens.TokenNamevoid});
+		this.endingTokens.put(ReturnStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(SimpleName.class, new int[]{TerminalTokens.TokenNameIdentifier});
+		this.endingTokens.put(SingleVariableDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(StringLiteral.class, new int[]{TerminalTokens.TokenNameStringLiteral});
+		this.endingTokens.put(SuperConstructorInvocation.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(SuperMethodInvocation.class, new int[]{TerminalTokens.TokenNameRPAREN});
+		this.endingTokens.put(SwitchCase.class, new int[]{TerminalTokens.TokenNameCOLON});
+		this.endingTokens.put(SwitchStatement.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(SynchronizedStatement.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(ThisExpression.class, new int[]{TerminalTokens.TokenNamethis});
+		this.endingTokens.put(ThrowStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+		this.endingTokens.put(TypeDeclaration.class, new int[]{TerminalTokens.TokenNameRBRACE});
+		this.endingTokens.put(TypeLiteral.class, new int[]{TerminalTokens.TokenNameclass});
+		this.endingTokens.put(VariableDeclarationStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON});
+	}
+
+	private CategorizedProblem[] problems;
+	private boolean[] usedOrIrrelevantProblems;
+
+	private RecoveryScannerData data;
+	private int blockDepth = 0;
+	private int lastEnd;
+
+	private int[] insertedTokensKind;
+	private int[] insertedTokensPosition;
+	private boolean[] insertedTokensFlagged;
+
+	private boolean[] removedTokensFlagged;
+	private boolean[] replacedTokensFlagged;
+
+	private Vector stack = new Vector();
+
+	/**
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	ASTRecoveryPropagator(CategorizedProblem[] problems, RecoveryScannerData data) {
+		// visit Javadoc.tags() as well
+		this.problems = problems;
+		this.usedOrIrrelevantProblems = new boolean[problems.length];
+
+		this.data = data;
+
+		if(this.data != null) {
+
+			int length = 0;
+			for (int i = 0; i < data.insertedTokensPtr + 1; i++) {
+				length += data.insertedTokens[i].length;
+			}
+			this.insertedTokensKind = new int[length];
+			this.insertedTokensPosition = new int[length];
+			this.insertedTokensFlagged = new boolean[length];
+			int tokenCount = 0;
+			for (int i = 0; i < data.insertedTokensPtr + 1; i++) {
+				for (int j = 0; j < data.insertedTokens[i].length; j++) {
+					this.insertedTokensKind[tokenCount] = data.insertedTokens[i][j];
+					this.insertedTokensPosition[tokenCount] = data.insertedTokensPosition[i];
+					tokenCount++;
+				}
+			}
+
+			if(data.removedTokensPtr != -1) {
+				this.removedTokensFlagged = new boolean[data.removedTokensPtr + 1];
+			}
+			if(data.replacedTokensPtr != -1) {
+				this.replacedTokensFlagged = new boolean[data.replacedTokensPtr + 1];
+			}
+		}
+	}
+
+	public void endVisit(Block node) {
+		this.blockDepth--;
+		if(this.blockDepth <= 0) {
+			flagNodeWithInsertedTokens();
+		}
+		super.endVisit(node);
+	}
+
+
+
+	public boolean visit(Block node) {
+		boolean visitChildren = super.visit(node);
+		this.blockDepth++;
+		return visitChildren;
+	}
+
+	protected boolean visitNode(ASTNode node) {
+		if(this.blockDepth > 0) {
+			int start = node.getStartPosition();
+			int end = start + node.getLength() - 1;
+
+			// continue to visit the node only if it contains tokens modifications
+
+			if(this.insertedTokensFlagged != null) {
+				for (int i = 0; i < this.insertedTokensFlagged.length; i++) {
+					if(this.insertedTokensPosition[i] >= start &&
+							this.insertedTokensPosition[i] <= end) {
+						return true;
+					}
+				}
+			}
+
+			if(this.removedTokensFlagged != null) {
+				for (int i = 0; i <= this.data.removedTokensPtr; i++) {
+					if(this.data.removedTokensStart[i] >= start &&
+							this.data.removedTokensEnd[i] <= end) {
+						return true;
+					}
+				}
+			}
+
+			if(this.replacedTokensFlagged != null) {
+				for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
+					if(this.data.replacedTokensStart[i] >= start &&
+							this.data.replacedTokensEnd[i] <= end) {
+						return true;
+					}
+				}
+			}
+
+			return false;
+		}
+		return true;
+	}
+
+	protected void endVisitNode(ASTNode node) {
+		int start = node.getStartPosition();
+		int end = start + node.getLength() - 1;
+
+		// is inside diet part of the ast
+		if(this.blockDepth < 1) {
+			switch (node.getNodeType()) {
+				case ASTNode.ANNOTATION_TYPE_DECLARATION:
+				case ASTNode.COMPILATION_UNIT:
+				case ASTNode.ENUM_DECLARATION:
+				case ASTNode.FIELD_DECLARATION:
+				case ASTNode.IMPORT_DECLARATION:
+				case ASTNode.INITIALIZER:
+				case ASTNode.METHOD_DECLARATION:
+				case ASTNode.PACKAGE_DECLARATION:
+				case ASTNode.TYPE_DECLARATION:
+				case ASTNode.MARKER_ANNOTATION:
+				case ASTNode.NORMAL_ANNOTATION:
+				case ASTNode.SINGLE_MEMBER_ANNOTATION:
+				case ASTNode.BLOCK:
+					if(markIncludedProblems(start, end)) {
+						node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+					}
+					break;
+			}
+		} else {
+			markIncludedProblems(start, end);
+
+			if(this.insertedTokensFlagged != null) {
+				if(this.lastEnd != end) {
+					flagNodeWithInsertedTokens();
+				}
+				this.stack.add(node);
+			}
+
+			if(this.removedTokensFlagged != null) {
+				for (int i = 0; i <= this.data.removedTokensPtr; i++) {
+					if(!this.removedTokensFlagged[i] &&
+							this.data.removedTokensStart[i] >= start &&
+							this.data.removedTokensEnd[i] <= end) {
+						node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+						this.removedTokensFlagged[i] = true;
+					}
+				}
+			}
+
+			if(this.replacedTokensFlagged != null) {
+				for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
+					if(!this.replacedTokensFlagged[i] &&
+							this.data.replacedTokensStart[i] >= start &&
+							this.data.replacedTokensEnd[i] <= end) {
+						node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+						this.replacedTokensFlagged[i] = true;
+					}
+				}
+			}
+		}
+		this.lastEnd = end;
+	}
+
+	private void flagNodeWithInsertedTokens() {
+		if(this.insertedTokensKind != null && this.insertedTokensKind.length > 0) {
+			int s = this.stack.size();
+			for (int i = s - 1; i > -1; i--) {
+				flagNodesWithInsertedTokensAtEnd((ASTNode)this.stack.get(i));
+			}
+			for (int i = 0; i < s; i++) {
+				flagNodesWithInsertedTokensInside((ASTNode)this.stack.get(i));
+			}
+			this.stack = new Vector();
+		}
+	}
+
+	private boolean flagNodesWithInsertedTokensAtEnd(ASTNode node) {
+		int[] expectedEndingToken = this.endingTokens.get(node.getClass());
+		if (expectedEndingToken != null) {
+			int start = node.getStartPosition();
+			int end = start + node.getLength() - 1;
+
+			boolean flagParent = false;
+			done : for (int i = this.insertedTokensKind.length - 1; i > -1 ; i--) {
+				if(!this.insertedTokensFlagged[i] &&
+						this.insertedTokensPosition[i] == end){
+					this.insertedTokensFlagged[i] = true;
+					for (int j = 0; j < expectedEndingToken.length; j++) {
+						if(expectedEndingToken[j] == this.insertedTokensKind[i]) {
+							node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+							break done;
+						}
+					}
+					flagParent = true;
+				}
+			}
+
+			if(flagParent) {
+				ASTNode parent = node.getParent();
+				while (parent != null) {
+					parent.setFlags(node.getFlags() | ASTNode.RECOVERED);
+					if((parent.getStartPosition() + parent.getLength() - 1) != end) {
+						parent = null;
+					} else {
+						parent = parent.getParent();
+					}
+				}
+			}
+		}
+		return true;
+	}
+
+	private boolean flagNodesWithInsertedTokensInside(ASTNode node) {
+		int start = node.getStartPosition();
+		int end = start + node.getLength() - 1;
+		for (int i = 0; i < this.insertedTokensKind.length; i++) {
+			if(!this.insertedTokensFlagged[i] &&
+					start <= this.insertedTokensPosition[i] &&
+					this.insertedTokensPosition[i] < end){
+				node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+				this.insertedTokensFlagged[i] = true;
+			}
+		}
+		return true;
+	}
+
+	private boolean markIncludedProblems(int start, int end) {
+		boolean foundProblems = false;
+		next: for (int i = 0, max = this.problems.length; i < max; i++) {
+			CategorizedProblem problem = this.problems[i];
+
+			if(this.usedOrIrrelevantProblems[i]) continue next;
+
+			switch(problem.getID()) {
+				case IProblem.ParsingErrorOnKeywordNoSuggestion :
+				case IProblem.ParsingErrorOnKeyword :
+				case IProblem.ParsingError :
+				case IProblem.ParsingErrorNoSuggestion :
+				case IProblem.ParsingErrorInsertTokenBefore :
+				case IProblem.ParsingErrorInsertTokenAfter :
+				case IProblem.ParsingErrorDeleteToken :
+				case IProblem.ParsingErrorDeleteTokens :
+				case IProblem.ParsingErrorMergeTokens :
+				case IProblem.ParsingErrorInvalidToken :
+				case IProblem.ParsingErrorMisplacedConstruct :
+				case IProblem.ParsingErrorReplaceTokens :
+				case IProblem.ParsingErrorNoSuggestionForTokens :
+				case IProblem.ParsingErrorUnexpectedEOF :
+				case IProblem.ParsingErrorInsertToComplete :
+				case IProblem.ParsingErrorInsertToCompleteScope :
+				case IProblem.ParsingErrorInsertToCompletePhrase :
+				case IProblem.EndOfSource :
+				case IProblem.InvalidHexa :
+				case IProblem.InvalidOctal :
+				case IProblem.InvalidCharacterConstant :
+				case IProblem.InvalidEscape :
+				case IProblem.InvalidInput :
+				case IProblem.InvalidUnicodeEscape :
+				case IProblem.InvalidFloat :
+				case IProblem.NullSourceString :
+				case IProblem.UnterminatedString :
+				case IProblem.UnterminatedComment :
+				case IProblem.InvalidDigit :
+					break;
+				default:
+					this.usedOrIrrelevantProblems[i] = true;
+					continue next;
+
+			}
+
+			int problemStart = problem.getSourceStart();
+			int problemEnd = problem.getSourceEnd();
+			if ((start <= problemStart) && (problemStart <= end) ||
+					(start <= problemEnd) && (problemEnd <= end)) {
+				this.usedOrIrrelevantProblems[i] = true;
+				foundProblems = true;
+			}
+		}
+		return foundProblems;
+	}
+
+	public void endVisit(ExpressionStatement node) {
+		endVisitNode(node);
+		if ((node.getFlags() & ASTNode.RECOVERED) == 0) return;
+		Expression expression = node.getExpression();
+		if (expression.getNodeType() == ASTNode.ASSIGNMENT) {
+			Assignment assignment = (Assignment) expression;
+			Expression rightHandSide = assignment.getRightHandSide();
+			if (rightHandSide.getNodeType() == ASTNode.SIMPLE_NAME) {
+				SimpleName simpleName = (SimpleName) rightHandSide;
+				if (CharOperation.equals(RecoveryScanner.FAKE_IDENTIFIER, simpleName.getIdentifier().toCharArray())) {
+					Expression expression2 =  assignment.getLeftHandSide();
+					// unparent the expression to add it in the expression stateemnt
+					expression2.setParent(null, null);
+					expression2.setFlags(expression2.getFlags() | ASTNode.RECOVERED);
+					node.setExpression(expression2);
+				}
+			}
+		}
+	}
+
+	public void endVisit(ForStatement node) {
+		endVisitNode(node);
+		List initializers = node.initializers();
+		if (initializers.size() == 1) {
+			Expression expression = (Expression) initializers.get(0);
+			if (expression.getNodeType() == ASTNode.VARIABLE_DECLARATION_EXPRESSION) {
+				VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) expression;
+				List fragments = variableDeclarationExpression.fragments();
+				for (int i = 0, max = fragments.size(); i <max; i++) {
+					VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(i);
+					SimpleName simpleName = fragment.getName();
+					if (CharOperation.equals(RecoveryScanner.FAKE_IDENTIFIER, simpleName.getIdentifier().toCharArray())) {
+						fragments.remove(fragment);
+						variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.RECOVERED);
+					}
+				}
+			}
+		}
+	}
+
+	public void endVisit(VariableDeclarationStatement node) {
+		endVisitNode(node);
+		List fragments = node.fragments();
+		for (int i = 0, max = fragments.size(); i <max; i++) {
+			VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(i);
+			Expression expression = fragment.getInitializer();
+			if (expression == null) continue;
+			if ((expression.getFlags() & ASTNode.RECOVERED) == 0) continue;
+			if (expression.getNodeType() == ASTNode.SIMPLE_NAME) {
+				SimpleName simpleName = (SimpleName) expression;
+				if (CharOperation.equals(RecoveryScanner.FAKE_IDENTIFIER, simpleName.getIdentifier().toCharArray())) {
+					fragment.setInitializer(null);
+					fragment.setFlags(fragment.getFlags() | ASTNode.RECOVERED);
+				}
+			}
+		}
+	}
+
+	public void endVisit(NormalAnnotation node) {
+		endVisitNode(node);
+		// is inside diet part of the ast
+		if(this.blockDepth < 1) {
+			List values = node.values();
+			int size = values.size();
+			if (size > 0) {
+				MemberValuePair lastMemberValuePair = (MemberValuePair)values.get(size - 1);
+
+				int annotationEnd = node.getStartPosition() + node.getLength();
+				int lastMemberValuePairEnd = lastMemberValuePair.getStartPosition() + lastMemberValuePair.getLength();
+				if (annotationEnd == lastMemberValuePairEnd) {
+					node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+				}
+			}
+		}
+	}
+
+	public void endVisit(SingleMemberAnnotation node) {
+		endVisitNode(node);
+		// is inside diet part of the ast
+		if(this.blockDepth < 1) {
+			Expression value = node.getValue();
+			int annotationEnd = node.getStartPosition() + node.getLength();
+			int valueEnd = value.getStartPosition() + value.getLength();
+			if (annotationEnd == valueEnd) {
+				node.setFlags(node.getFlags() | ASTNode.RECOVERED);
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java
new file mode 100644
index 0000000..5dbb1d0
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+
+/**
+ * An AST requestor handles ASTs for compilation units passed to
+ * {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * <p>
+ * {@link #acceptAST(ICompilationUnit, CompilationUnit) ASTRequestor.acceptAST} is called for each of the
+ * compilation units passed to {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * After all the compilation units have been processed,
+ * {@link #acceptBinding(String, IBinding) ASTRequestor.acceptBindings} is called for each
+ * of the binding keys passed to {@link ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * </p>
+ * <p>
+ * This class is intended to be subclassed by clients.
+ * AST requestors are serially reusable, but neither reentrant nor thread-safe.
+ * </p>
+ *
+ * @see ASTParser#createASTs(ICompilationUnit[], String[], ASTRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ * @since 3.1
+ */
+public abstract class ASTRequestor {
+
+	/**
+	 * The compilation unit resolver used to resolve bindings, or
+	 * <code>null</code> if none. Note that this field is non-null
+	 * only within the dynamic scope of a call to
+	 * <code>ASTParser.createASTs</code>.
+	 */
+	CompilationUnitResolver compilationUnitResolver = null;
+
+	/**
+	 * Creates a new instance.
+	 */
+	protected ASTRequestor() {
+		// do nothing
+	}
+
+	/**
+	 * Accepts an AST corresponding to the compilation unit.
+	 * That is, <code>ast</code> is an AST for <code>source</code>.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients should override to process the resulting AST.
+	 * </p>
+	 *
+	 * @param source the compilation unit the ast is coming from
+	 * @param ast the requested abtract syntax tree
+	 */
+	public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
+		// do nothing
+	}
+
+	/**
+	 * Accepts a binding corresponding to the binding key.
+	 * That is, <code>binding</code> is the binding for
+	 * <code>bindingKey</code>; <code>binding</code> is <code>null</code>
+	 * if the key cannot be resolved.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients should override to process the resulting binding.
+	 * </p>
+	 *
+	 * @param bindingKey the key of the requested binding
+	 * @param binding the requested binding, or <code>null</code> if none
+	 */
+	public void acceptBinding(String bindingKey, IBinding binding) {
+		// do nothing
+	}
+
+	/**
+	 * Resolves bindings for the given binding keys.
+	 * The given binding keys must have been obtained earlier
+	 * using {@link IBinding#getKey()}.
+	 * <p>
+	 * If a binding key cannot be resolved, <code>null</code> is put in the resulting array.
+	 * Bindings can only be resolved in the dynamic scope of a <code>ASTParser.createASTs</code>,
+	 * and only if <code>ASTParser.resolveBindings(true)</code> was specified.
+	 * </p>
+	 * <p>
+	 * Caveat: During an <code>acceptAST</code> callback, there are implementation
+	 * limitations concerning the look up of binding keys representing local elements.
+	 * In some cases, the binding is unavailable, and <code>null</code> will be returned.
+	 * This is only an issue during an <code>acceptAST</code> callback, and only
+	 * when the binding key represents a local element (e.g., local variable,
+	 * local class, method declared in anonymous class). There is no such limitation
+	 * outside of <code>acceptAST</code> callbacks, or for top-level types and their
+	 * members even within <code>acceptAST</code> callbacks.
+	 * </p>
+	 *
+	 * @param bindingKeys the binding keys to look up
+	 * @return a list of bindings paralleling the <code>bindingKeys</code> parameter,
+	 * with <code>null</code> entries for keys that could not be resolved
+	 */
+	public final IBinding[] createBindings(String[] bindingKeys) {
+		int length = bindingKeys.length;
+		IBinding[] result = new IBinding[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = null;
+			if (this.compilationUnitResolver != null) {
+				result[i] = this.compilationUnitResolver.createBinding(bindingKeys[i]);
+			}
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java
new file mode 100644
index 0000000..8590672
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Internal AST visitor for propagating syntax errors.
+ */
+class ASTSyntaxErrorPropagator extends ASTVisitor {
+
+	private CategorizedProblem[] problems;
+
+	ASTSyntaxErrorPropagator(CategorizedProblem[] problems) {
+		// visit Javadoc.tags() as well
+		super(true);
+		this.problems = problems;
+	}
+
+	private boolean checkAndTagAsMalformed(ASTNode node) {
+		boolean tagWithErrors = false;
+		search: for (int i = 0, max = this.problems.length; i < max; i++) {
+			CategorizedProblem problem = this.problems[i];
+			switch(problem.getID()) {
+				case IProblem.ParsingErrorOnKeywordNoSuggestion :
+				case IProblem.ParsingErrorOnKeyword :
+				case IProblem.ParsingError :
+				case IProblem.ParsingErrorNoSuggestion :
+				case IProblem.ParsingErrorInsertTokenBefore :
+				case IProblem.ParsingErrorInsertTokenAfter :
+				case IProblem.ParsingErrorDeleteToken :
+				case IProblem.ParsingErrorDeleteTokens :
+				case IProblem.ParsingErrorMergeTokens :
+				case IProblem.ParsingErrorInvalidToken :
+				case IProblem.ParsingErrorMisplacedConstruct :
+				case IProblem.ParsingErrorReplaceTokens :
+				case IProblem.ParsingErrorNoSuggestionForTokens :
+				case IProblem.ParsingErrorUnexpectedEOF :
+				case IProblem.ParsingErrorInsertToComplete :
+				case IProblem.ParsingErrorInsertToCompleteScope :
+				case IProblem.ParsingErrorInsertToCompletePhrase :
+				case IProblem.EndOfSource :
+				case IProblem.InvalidHexa :
+				case IProblem.InvalidOctal :
+				case IProblem.InvalidCharacterConstant :
+				case IProblem.InvalidEscape :
+				case IProblem.InvalidInput :
+				case IProblem.InvalidUnicodeEscape :
+				case IProblem.InvalidFloat :
+				case IProblem.NullSourceString :
+				case IProblem.UnterminatedString :
+				case IProblem.UnterminatedComment :
+				case IProblem.InvalidDigit :
+					break;
+				default:
+					continue search;
+			}
+			int position = problem.getSourceStart();
+			int start = node.getStartPosition();
+			int end = start + node.getLength();
+			if ((start <= position) && (position <= end)) {
+				node.setFlags(node.getFlags() | ASTNode.MALFORMED);
+				// clear the bits on parent
+				ASTNode currentNode = node.getParent();
+				while (currentNode != null) {
+					currentNode.setFlags(currentNode.getFlags() & ~ASTNode.MALFORMED);
+					currentNode = currentNode.getParent();
+				}
+				tagWithErrors = true;
+			}
+		}
+		return tagWithErrors;
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(FieldDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(MethodDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(PackageDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(ImportDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(CompilationUnit node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(AnnotationTypeDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(EnumDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(TypeDeclaration node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+	/*
+	 * Method declared on ASTVisitor.
+	 */
+	public boolean visit(Initializer node) {
+		return checkAndTagAsMalformed(node);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
new file mode 100644
index 0000000..b4ffbaf
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
@@ -0,0 +1,2866 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A visitor for abstract syntax trees.
+ * <p>
+ * For each different concrete AST node type <i>T</i> there are
+ * a pair of methods:
+ * <ul>
+ * <li><code>public boolean visit(<i>T</i> node)</code> - Visits
+ * the given node to perform some arbitrary operation. If <code>true</code>
+ * is returned, the given node's child nodes will be visited next; however,
+ * if <code>false</code> is returned, the given node's child nodes will
+ * not be visited. The default implementation provided by this class does
+ * nothing and returns <code>true</code> (with the exception of
+ * {@link #visit(Javadoc) ASTVisitor.visit(Javadoc)}).
+ * Subclasses may reimplement this method as needed.</li>
+ * <li><code>public void endVisit(<i>T</i> node)</code> - Visits
+ * the given node to perform some arbitrary operation. When used in the
+ * conventional way, this method is called after all of the given node's
+ * children have been visited (or immediately, if <code>visit</code> returned
+ * <code>false</code>). The default implementation provided by this class does
+ * nothing. Subclasses may reimplement this method as needed.</li>
+ * </ul>
+ * </p>
+ * In addition, there are a pair of methods for visiting AST nodes in the
+ * abstract, regardless of node type:
+ * <ul>
+ * <li><code>public void preVisit(ASTNode node)</code> - Visits
+ * the given node to perform some arbitrary operation.
+ * This method is invoked prior to the appropriate type-specific
+ * <code>visit</code> method.
+ * The default implementation of this method does nothing.
+ * Subclasses may reimplement this method as needed.</li>
+ * <li><code>public void postVisit(ASTNode node)</code> - Visits
+ * the given node to perform some arbitrary operation.
+ * This method is invoked after the appropriate type-specific
+ * <code>endVisit</code> method.
+ * The default implementation of this method does nothing.
+ * Subclasses may reimplement this method as needed.</li>
+ * </ul>
+ * <p>
+ * For nodes with list-valued properties, the child nodes within the list
+ * are visited in order. For nodes with multiple properties, the child nodes
+ * are visited in the order that most closely corresponds to the lexical
+ * reading order of the source program. For instance, for a type declaration
+ * node, the child ordering is: name, superclass, superinterfaces, and
+ * body declarations.
+ * </p>
+ * <p>
+ * While it is possible to modify the tree in the visitor, care is required to
+ * ensure that the consequences are as expected and desirable.
+ * During the course of an ordinary visit starting at a given node, every node
+ * in the subtree is visited exactly twice, first with <code>visit</code> and
+ * then with <code>endVisit</code>. During a traversal of a stationary tree,
+ * each node is either behind (after <code>endVisit</code>), ahead (before
+ * <code>visit</code>), or in progress (between <code>visit</code> and
+ * the matching <code>endVisit</code>). Changes to the "behind" region of the
+ * tree are of no consequence to the visit in progress. Changes to the "ahead"
+ * region will be taken in stride. Changes to the "in progress" portion are
+ * the more interesting cases. With a node, the various properties are arranged
+ * in a linear list, with a cursor that separates the properties that have
+ * been visited from the ones that are still to be visited (the cursor
+ * is between the elements, rather than on an element). The cursor moves from
+ * the head to the tail of this list, advancing to the next position just
+ * <i>before</i> <code>visit</code> if called for that child. After the child
+ * subtree has been completely visited, the visit moves on the child
+ * immediately after the cursor. Removing a child while it is being visited
+ * does not alter the course of the visit. But any children added at positions
+ * after the cursor are considered in the "ahead" portion and will be visited.
+ * </p>
+ * <p>
+ * Cases to watch out for:
+ * <ul>
+ * <li>Moving a child node further down the list. This could result in the
+ * child subtree being visited multiple times; these visits are sequential.</li>
+ * <li>Moving a child node up into an ancestor. If the new home for
+ * the node is in the "ahead" portion, the subtree will be visited
+ * a second time; again, these visits are sequential.</li>
+ * <li>Moving a node down into a child. If the new home for
+ * the node is in the "ahead" portion, the subtree will be visited
+ * a second time; in this case, the visits will be nested. In some cases,
+ * this can lead to a stack overflow or out of memory condition.</li>
+ * </ul>
+ * <p>Note that {@link LineComment} and {@link BlockComment} nodes are
+ * not normally visited in an AST because they are not considered
+ * part of main structure of the AST. Use
+ * {@link CompilationUnit#getCommentList()} to find these additional
+ * comments nodes.
+ * </p>
+ *
+ * @see org.eclipse.jdt.core.dom.ASTNode#accept(ASTVisitor)
+ */
+public abstract class ASTVisitor {
+
+	/**
+	 * Indicates whether doc tags should be visited by default.
+	 * @since 3.0
+	 */
+	private boolean visitDocTags;
+
+	/**
+	 * Creates a new AST visitor instance.
+	 * <p>
+	 * For backwards compatibility, the visitor does not visit tag
+	 * elements below doc comments by default. Use
+	 * {@link #ASTVisitor(boolean) ASTVisitor(true)}
+	 * for an visitor that includes doc comments by default.
+	 * </p>
+	 */
+	public ASTVisitor() {
+		this(false);
+	}
+
+	/**
+	 * Creates a new AST visitor instance.
+	 *
+	 * @param visitDocTags <code>true</code> if doc comment tags are
+	 * to be visited by default, and <code>false</code> otherwise
+	 * @see Javadoc#tags()
+	 * @see #visit(Javadoc)
+	 * @since 3.0
+	 */
+	public ASTVisitor(boolean visitDocTags) {
+		this.visitDocTags = visitDocTags;
+	}
+
+	/**
+	 * Visits the given AST node prior to the type-specific visit
+	 * (before <code>visit</code>).
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 *
+	 * @see #preVisit2(ASTNode)
+	 */
+	public void preVisit(ASTNode node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * Visits the given AST node prior to the type-specific visit (before <code>visit</code>).
+	 * <p>
+	 * The default implementation calls {@link #preVisit(ASTNode)} and then
+	 * returns true. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if <code>visit(node)</code> should be called,
+	 * and <code>false</code> otherwise.
+	 * @see #preVisit(ASTNode)
+	 * @since 3.5
+	 */
+	public boolean preVisit2(ASTNode node) {
+		preVisit(node);
+		return true;
+	}
+
+	/**
+	 * Visits the given AST node following the type-specific visit
+	 * (after <code>endVisit</code>).
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void postVisit(ASTNode node) {
+		// default implementation: do nothing
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(AnnotationTypeDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(AnonymousClassDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ArrayAccess node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ArrayCreation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ArrayInitializer node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ArrayType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(AssertStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(Assignment node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(Block node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(BlockComment node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(BooleanLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(BreakStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(CastExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(CatchClause node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(CharacterLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ClassInstanceCreation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(CompilationUnit node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ConditionalExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ConstructorInvocation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ContinueStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may re-implement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(CreationReference node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(DoStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(EmptyStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(EnhancedForStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(EnumConstantDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(EnumDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may re-implement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(ExpressionMethodReference node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ExpressionStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(ExtraDimension node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(FieldAccess node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(FieldDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ForStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(IfStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ImportDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(InfixExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(Initializer node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(InstanceofExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(IntersectionType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given AST node.
+	 * <p>
+	 * Unlike other node types, the boolean returned by the default
+	 * implementation is controlled by a constructor-supplied
+	 * parameter  {@link #ASTVisitor(boolean) ASTVisitor(boolean)}
+	 * which is <code>false</code> by default.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @see #ASTVisitor()
+	 * @see #ASTVisitor(boolean)
+	 */
+	public boolean visit(Javadoc node) {
+		// visit tag elements inside doc comments only if requested
+		return this.visitDocTags;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(LabeledStatement node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(LambdaExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(LineComment node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(MarkerAnnotation node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(MemberRef node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(MemberValuePair node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(MethodRef node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(MethodRefParameter node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(MethodDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(MethodInvocation node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(Modifier node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(NormalAnnotation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(NullLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(NumberLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(PackageDeclaration node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(PackageQualifiedType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(ParameterizedType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ParenthesizedExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(PostfixExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(PrefixExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(PrimitiveType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(QualifiedName node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(QualifiedType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ReturnStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SimpleName node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SimpleType node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(SingleMemberAnnotation node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SingleVariableDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(StringLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SuperConstructorInvocation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SuperFieldAccess node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SuperMethodInvocation node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(SuperMethodReference node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SwitchCase node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SwitchStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(SynchronizedStatement node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(TagElement node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.0
+	 */
+	public boolean visit(TextElement node) {
+		return true;
+	}
+
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ThisExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(ThrowStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(TryStatement node) {
+		return true;
+	}
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(TypeDeclaration node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(TypeDeclarationStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(TypeLiteral node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(TypeMethodReference node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(TypeParameter node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.7.1
+	 */
+	public boolean visit(UnionType node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(VariableDeclarationExpression node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(VariableDeclarationStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(VariableDeclarationFragment node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 */
+	public boolean visit(WhileStatement node) {
+		return true;
+	}
+
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.1
+	 */
+	public boolean visit(WildcardType node) {
+		return true;
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(AnnotationTypeDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(AnnotationTypeMemberDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(AnonymousClassDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ArrayAccess node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ArrayCreation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ArrayInitializer node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ArrayType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(AssertStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(Assignment node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(Block node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(BlockComment node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(BooleanLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(BreakStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(CastExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(CatchClause node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(CharacterLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ClassInstanceCreation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(CompilationUnit node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ConditionalExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ConstructorInvocation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ContinueStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(CreationReference node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(DoStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(EmptyStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(EnhancedForStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(EnumConstantDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(EnumDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(ExpressionMethodReference node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ExpressionStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(ExtraDimension node) {
+		// do nothing by default
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(FieldAccess node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(FieldDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ForStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(IfStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ImportDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(InfixExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(InstanceofExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(Initializer node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(Javadoc node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(LabeledStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(LambdaExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(LineComment node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(MarkerAnnotation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(MemberRef node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(MemberValuePair node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(MethodRef node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(MethodRefParameter node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(MethodDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(MethodInvocation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(Modifier node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(NormalAnnotation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(NullLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(NumberLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(PackageDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(PackageQualifiedType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(ParameterizedType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ParenthesizedExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(PostfixExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(PrefixExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(PrimitiveType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(QualifiedName node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(QualifiedType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ReturnStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SimpleName node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SimpleType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(SingleMemberAnnotation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SingleVariableDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(StringLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SuperConstructorInvocation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SuperFieldAccess node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SuperMethodInvocation node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(SuperMethodReference node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SwitchCase node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SwitchStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(SynchronizedStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(TagElement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.0
+	 */
+	public void endVisit(TextElement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ThisExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(ThrowStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(TryStatement node) {
+		// default implementation: do nothing
+	}
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(TypeDeclaration node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(TypeDeclarationStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(TypeLiteral node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(TypeMethodReference node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(TypeParameter node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.7.1
+	 */
+	public void endVisit(UnionType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void endVisit(IntersectionType node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(VariableDeclarationExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(VariableDeclarationStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(VariableDeclarationFragment node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 */
+	public void endVisit(WhileStatement node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @since 3.1
+	 */
+	public void endVisit(WildcardType node) {
+		// default implementation: do nothing
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java
new file mode 100644
index 0000000..db9754f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+
+/**
+ * Abstract subclass for type declaration, enum declaration,
+ * and annotation type declaration AST node types.
+ * <pre>
+ * AbstractTypeDeclaration:
+ * 		TypeDeclaration
+ * 		EnumDeclaration
+ * 		AnnotationTypeDeclaration
+ * </pre>
+ *
+ * @since 3.0
+ */
+public abstract class AbstractTypeDeclaration extends BodyDeclaration {
+
+	/**
+	 * The type name; lazily initialized; defaults to a unspecified,
+	 * legal Java class identifier.
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	SimpleName typeName = null;
+
+	/**
+	 * The body declarations (element type: {@link BodyDeclaration}).
+	 * Defaults to an empty list.
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	ASTNode.NodeList bodyDeclarations;
+
+	/**
+	 * Returns structural property descriptor for the "bodyDeclarations" property
+	 * of this node (element type: {@link BodyDeclaration}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildListPropertyDescriptor internalBodyDeclarationsProperty();
+
+	/**
+	 * Returns structural property descriptor for the "bodyDeclarations" property
+	 * of this node (element type: {@link BodyDeclaration}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildListPropertyDescriptor getBodyDeclarationsProperty() {
+		return internalBodyDeclarationsProperty();
+	}
+
+	/**
+	 * Returns structural property descriptor for the "name" property
+	 * of this node (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildPropertyDescriptor internalNameProperty();
+
+	/**
+	 * Returns structural property descriptor for the "name" property
+	 * of this node (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildPropertyDescriptor getNameProperty() {
+		return internalNameProperty();
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "bodyDeclaration" property declared on the given concrete node type (element type: {@link BodyDeclaration}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildListPropertyDescriptor internalBodyDeclarationPropertyFactory(Class nodeClass) {
+		return new ChildListPropertyDescriptor(nodeClass, "bodyDeclarations", BodyDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "name" property declared on the given concrete node type (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildPropertyDescriptor internalNamePropertyFactory(Class nodeClass) {
+		return new ChildPropertyDescriptor(nodeClass, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates a new AST node for an abstract type declaration owned by the given
+	 * AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AbstractTypeDeclaration(AST ast) {
+		super(ast);
+		this.bodyDeclarations = new ASTNode.NodeList(internalBodyDeclarationsProperty());
+	}
+
+	/**
+	 * Returns the name of the type declared in this type declaration.
+	 *
+	 * @return the type name node
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	public SimpleName getName() {
+		if (this.typeName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeName == null) {
+					preLazyInit();
+					this.typeName = new SimpleName(this.ast);
+					postLazyInit(this.typeName, internalNameProperty());
+				}
+			}
+		}
+		return this.typeName;
+	}
+
+	/**
+	 * Sets the name of the type declared in this type declaration to the
+	 * given name.
+	 *
+	 * @param typeName the new type name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	public void setName(SimpleName typeName) {
+		if (typeName == null) {
+			throw new IllegalArgumentException();
+		}
+		ChildPropertyDescriptor p = internalNameProperty();
+		ASTNode oldChild = this.typeName;
+		preReplaceChild(oldChild, typeName, p);
+		this.typeName = typeName;
+		postReplaceChild(oldChild, typeName, p);
+	}
+
+	/**
+	 * Returns the live ordered list of body declarations of this type
+	 * declaration.
+	 *
+	 * @return the live list of body declarations
+	 *    (element type: {@link BodyDeclaration})
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	public List bodyDeclarations() {
+		return this.bodyDeclarations;
+	}
+
+	/**
+	 * Returns whether this type declaration is a package member (that is,
+	 * a top-level type).
+	 * <p>
+	 * Note that this is a convenience method that simply checks whether
+	 * this node's parent is a compilation unit node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type declaration is a child of
+	 *   a compilation unit node, and <code>false</code> otherwise
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	public boolean isPackageMemberTypeDeclaration() {
+		ASTNode parent = getParent();
+		return (parent instanceof CompilationUnit);
+	}
+
+	/**
+	 * Returns whether this type declaration is a type member.
+	 * <p>
+	 * Note that this is a convenience method that simply checks whether
+	 * this node's parent is a type declaration node or an anonymous
+	 * class declaration.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type declaration is a child of
+	 *   a type declaration node or an anonymous class declaration node,
+	 *   and <code>false</code> otherwise
+	 * @since 2.0 (originally declared on {@link TypeDeclaration})
+	 */
+	public boolean isMemberTypeDeclaration() {
+		ASTNode parent = getParent();
+		return (parent instanceof AbstractTypeDeclaration)
+			|| (parent instanceof AnonymousClassDeclaration);
+	}
+
+	/**
+	 * Returns whether this type declaration is a local type.
+	 * <p>
+	 * Note that this is a convenience method that simply checks whether
+	 * this node's parent is a type declaration statement node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type declaration is a child of
+	 *   a type declaration statement node, and <code>false</code> otherwise
+	 * @since 2.0 (originally declared on <code>TypeDeclaration</code>)
+	 */
+	public boolean isLocalTypeDeclaration() {
+		ASTNode parent = getParent();
+		return (parent instanceof TypeDeclarationStatement);
+	}
+
+	/**
+	 * Resolves and returns the binding for the type declared in this type
+	 * declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 * @since 3.1 Declared in 3.0 on the individual subclasses.
+	 */
+	public final ITypeBinding resolveBinding() {
+		return internalResolveBinding();
+	}
+
+	/**
+	 * Resolves and returns the binding for the type declared in this type
+	 * declaration. This method must be implemented by subclasses.
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	abstract ITypeBinding internalResolveBinding();
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java
new file mode 100644
index 0000000..8b2c16d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotatableType.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+
+/**
+ * Abstract base class of AST nodes that represent an annotatable type (added in JLS8 API).
+ * <p>
+ * Introduced in JLS8, type references that can be annotated are represented by 
+ * AnnotatableType. For the list of types extending AnnotatableType, see {@link Type}.</p>
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+public abstract class AnnotatableType extends Type {
+	
+	/**
+	 * The annotations (element type: {@link Annotation}).
+	 * Null in JLS < 8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 */
+	ASTNode.NodeList annotations = null;
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "annotations" property declared on the given concrete node type (element type: {@link Annotation}) (added in JLS8 API).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildListPropertyDescriptor internalAnnotationsPropertyFactory(Class nodeClass) {
+		return 	new ChildListPropertyDescriptor(nodeClass, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the structural property descriptor for the "annotations" property
+	 * of this node (element type: {@link Annotation}) (added in JLS8 API).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildListPropertyDescriptor internalAnnotationsProperty();
+
+	/**
+	 * Returns the structural property descriptor for the "annotations" property
+	 * of this node (element type: {@link Annotation}) (added in JLS8 API).
+	 *
+	 * @return the property descriptor
+	 */
+	public final ChildListPropertyDescriptor getAnnotationsProperty() {
+		return internalAnnotationsProperty();
+	}
+
+	/**
+	 * Creates a new unparented node for an annotatable type owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AnnotatableType(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS8) {
+			this.annotations = new ASTNode.NodeList(getAnnotationsProperty());
+		}
+	}
+
+	/**
+	 * Returns the live ordered list of annotations for this Type node (added in JLS8 API).
+	 *
+	 * @return the live list of annotations (element type: {@link Annotation})
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 */
+	public List annotations() {
+		// more efficient than just calling unsupportedIn2_3_4() to check
+		if (this.annotations == null) {
+			unsupportedIn2_3_4();
+		}
+		return this.annotations;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java
new file mode 100644
index 0000000..bfa5efe
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Abstract base class of AST nodes that represent annotations.
+ * <p>
+ * <pre>
+ * Annotation:
+ *		NormalAnnotation
+ *		MarkerAnnotation
+ *		SingleMemberAnnotation
+ * </pre>
+ * </p>
+ * @since 3.1
+ */
+public abstract class Annotation extends Expression implements IExtendedModifier {
+
+	/**
+	 * Returns structural property descriptor for the "typeName" property
+	 * of this node (child type: {@link Name}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildPropertyDescriptor internalTypeNameProperty();
+
+	/**
+	 * Returns structural property descriptor for the "typeName" property
+	 * of this node (child type: {@link Name}).
+	 *
+	 * @return the property descriptor
+	 */
+	public final ChildPropertyDescriptor getTypeNameProperty() {
+		return internalTypeNameProperty();
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "typeName" property declared on the given concrete node type (child type: {@link Name}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildPropertyDescriptor internalTypeNamePropertyFactory(Class nodeClass) {
+		return new ChildPropertyDescriptor(nodeClass, "typeName", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * The annotation type name; lazily initialized; defaults to an unspecified,
+	 * legal Java identifier.
+	 */
+	Name typeName = null;
+
+	/**
+	 * Creates a new AST node for an annotation node owned by the
+	 * given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Annotation(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * @see IExtendedModifier#isModifier()
+	 */
+	public boolean isModifier() {
+		return false;
+	}
+
+	/**
+	 * @see IExtendedModifier#isAnnotation()
+	 */
+	public boolean isAnnotation() {
+		return true;
+	}
+
+	/**
+	 * Returns the annotation type name of this annotation.
+	 *
+	 * @return the annotation type name
+	 */
+	public Name getTypeName() {
+		if (this.typeName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeName == null) {
+					preLazyInit();
+					this.typeName = new SimpleName(this.ast);
+					postLazyInit(this.typeName, internalTypeNameProperty());
+				}
+			}
+		}
+		return this.typeName;
+	}
+
+	/**
+	 * Sets the annotation type name of this annotation.
+	 *
+	 * @param typeName the annotation type name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setTypeName(Name typeName) {
+		if (typeName == null) {
+			throw new IllegalArgumentException();
+		}
+		ChildPropertyDescriptor p = internalTypeNameProperty();
+		ASTNode oldChild = this.typeName;
+		preReplaceChild(oldChild, typeName, p);
+		this.typeName = typeName;
+		postReplaceChild(oldChild, typeName, p);
+	}
+
+	/**
+	 * Returns whether this is a normal annotation
+	 * ({@link NormalAnnotation}).
+	 *
+	 * @return <code>true</code> if this is a normal annotation,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isNormalAnnotation() {
+		return (this instanceof NormalAnnotation);
+	}
+
+	/**
+	 * Returns whether this is a marker annotation
+	 * ({@link MarkerAnnotation}).
+	 *
+	 * @return <code>true</code> if this is a marker annotation,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isMarkerAnnotation() {
+		return (this instanceof MarkerAnnotation);
+	}
+
+	/**
+	 * Returns whether this is a single member annotation.
+	 * ({@link SingleMemberAnnotation}).
+	 *
+	 * @return <code>true</code> if this is a single member annotation,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isSingleMemberAnnotation() {
+		return (this instanceof SingleMemberAnnotation);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/**
+	 * Resolves and returns the resolved annotation for this annotation.
+	 * <p>
+	 * Note that bindings (which includes resolved annotations) are generally unavailable unless
+	 * requested when the AST is being built.
+	 * </p>
+	 *
+	 * @return the resolved annotation, or <code>null</code> if the annotation cannot be resolved
+	 * @since 3.2
+	 */
+	public IAnnotationBinding resolveAnnotationBinding() {
+	    return this.ast.getBindingResolver().resolveAnnotation(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java
new file mode 100644
index 0000000..0e8f6db
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationBinding.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 BEA Systems, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *    IBM Corporation - implemented methods from IBinding
+ *    IBM Corporation - renamed from ResolvedAnnotation to AnnotationBinding
+ *    IBM Corporation - Fix for 328969
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.util.*;
+
+/**
+ * Internal class
+ */
+class AnnotationBinding implements IAnnotationBinding {
+	static final AnnotationBinding[] NoAnnotations = new AnnotationBinding[0];
+	private org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding binding;
+	private BindingResolver bindingResolver;
+	private String key;
+
+	AnnotationBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding annotation, BindingResolver resolver) {
+		if (annotation == null)
+			throw new IllegalStateException();
+		this.binding = annotation;
+		this.bindingResolver = resolver;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		return NoAnnotations;
+	}
+
+	public ITypeBinding getAnnotationType() {
+		ITypeBinding typeBinding = this.bindingResolver.getTypeBinding(this.binding.getAnnotationType());
+		if (typeBinding == null)
+			return null;
+		return typeBinding;
+	}
+
+	public IMemberValuePairBinding[] getDeclaredMemberValuePairs() {
+		ReferenceBinding typeBinding = this.binding.getAnnotationType();
+		if (typeBinding == null || ((typeBinding.tagBits & TagBits.HasMissingType) != 0)) {
+			return MemberValuePairBinding.NoPair;
+		}
+		ElementValuePair[] internalPairs = this.binding.getElementValuePairs();
+		int length = internalPairs.length;
+		IMemberValuePairBinding[] pairs = length == 0 ? MemberValuePairBinding.NoPair : new MemberValuePairBinding[length];
+		int counter = 0;
+		for (int i = 0; i < length; i++) {
+			ElementValuePair valuePair = internalPairs[i];
+			if (valuePair.binding == null) continue;
+			pairs[counter++] = this.bindingResolver.getMemberValuePairBinding(valuePair);
+		}
+		if (counter == 0) return MemberValuePairBinding.NoPair;
+		if (counter != length) {
+			// resize
+			System.arraycopy(pairs, 0, (pairs = new MemberValuePairBinding[counter]), 0, counter);
+		}
+		return pairs;
+	}
+
+	public IMemberValuePairBinding[] getAllMemberValuePairs() {
+		IMemberValuePairBinding[] pairs = getDeclaredMemberValuePairs();
+		ReferenceBinding typeBinding = this.binding.getAnnotationType();
+		if (typeBinding == null || ((typeBinding.tagBits & TagBits.HasMissingType) != 0)) return pairs;
+		MethodBinding[] methods = typeBinding.availableMethods(); // resilience
+		int methodLength = methods == null ? 0 : methods.length;
+		if (methodLength == 0) return pairs;
+
+		int declaredLength = pairs.length;
+		if (declaredLength == methodLength)
+			return pairs;
+
+		HashtableOfObject table = new HashtableOfObject(declaredLength);
+		for (int i = 0; i < declaredLength; i++) {
+			char[] internalName = ((MemberValuePairBinding) pairs[i]).internalName();
+			if (internalName == null) continue;
+			table.put(internalName, pairs[i]);
+		}
+
+		// handle case of more methods than declared members
+		IMemberValuePairBinding[] allPairs = new  IMemberValuePairBinding[methodLength];
+		for (int i = 0; i < methodLength; i++) {
+			Object pair = table.get(methods[i].selector);
+			allPairs[i] = pair == null ? new DefaultValuePairBinding(methods[i], this.bindingResolver) : (IMemberValuePairBinding) pair;
+		}
+		return allPairs;
+	}
+
+	public IJavaElement getJavaElement() {
+		if (!(this.bindingResolver instanceof DefaultBindingResolver)) return null;
+		ASTNode node = (ASTNode) ((DefaultBindingResolver) this.bindingResolver).bindingsToAstNodes.get(this);
+		if (!(node instanceof Annotation)) return null;
+		ASTNode parent = node.getParent();
+		IJavaElement parentElement = null;
+		switch (parent.getNodeType()) {
+		case ASTNode.PACKAGE_DECLARATION:
+			IJavaElement cu = ((CompilationUnit) parent.getParent()).getJavaElement();
+			if (cu instanceof ICompilationUnit) {
+				String pkgName = ((PackageDeclaration) parent).getName().getFullyQualifiedName();
+				parentElement =  ((ICompilationUnit) cu).getPackageDeclaration(pkgName);
+			}
+			break;
+		case ASTNode.ENUM_DECLARATION:
+		case ASTNode.TYPE_DECLARATION:
+		case ASTNode.ANNOTATION_TYPE_DECLARATION:
+			parentElement = ((AbstractTypeDeclaration) parent).resolveBinding().getJavaElement();
+			break;
+		case ASTNode.FIELD_DECLARATION:
+			VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) parent).fragments().get(0);
+			IVariableBinding variableBinding = fragment.resolveBinding();
+			if (variableBinding == null) {
+				return null;
+			}
+			parentElement = variableBinding.getJavaElement();
+			break;
+		case ASTNode.METHOD_DECLARATION:
+				IMethodBinding methodBinding = ((MethodDeclaration) parent).resolveBinding();
+				if (methodBinding == null) return null;
+				parentElement = methodBinding.getJavaElement();
+			break;
+		case ASTNode.VARIABLE_DECLARATION_STATEMENT:
+			fragment = (VariableDeclarationFragment) ((VariableDeclarationStatement) parent).fragments().get(0);
+			variableBinding = fragment.resolveBinding();
+			if (variableBinding == null) {
+				return null;
+			}
+			parentElement = variableBinding.getJavaElement();
+			break;
+		default:
+			return null;
+		}
+		if (! (parentElement instanceof IAnnotatable)) return null;
+		if ((parentElement instanceof IMember) && ((IMember) parentElement).isBinary()) {
+			return ((IAnnotatable) parentElement).getAnnotation(getAnnotationType().getQualifiedName());
+		}
+		return ((IAnnotatable) parentElement).getAnnotation(getName());
+	}
+
+	public String getKey() {
+		if (this.key == null) {
+			String recipientKey = getRecipientKey();
+			this.key = new String(this.binding.computeUniqueKey(recipientKey.toCharArray()));
+		}
+		return this.key;
+	}
+
+	private String getRecipientKey() {
+		if (!(this.bindingResolver instanceof DefaultBindingResolver)) return ""; //$NON-NLS-1$
+		DefaultBindingResolver resolver = (DefaultBindingResolver) this.bindingResolver;
+		ASTNode node = (ASTNode) resolver.bindingsToAstNodes.get(this);
+		if (node == null) {
+			// Can happen if annotation bindings have been resolved before having parsed the declaration
+			return ""; //$NON-NLS-1$
+		}
+		ASTNode recipient = node.getParent();
+		switch (recipient.getNodeType()) {
+		case ASTNode.PACKAGE_DECLARATION:
+			String pkgName = ((PackageDeclaration) recipient).getName().getFullyQualifiedName();
+			return pkgName.replace('.', '/');
+		case ASTNode.TYPE_DECLARATION:
+			return ((TypeDeclaration) recipient).resolveBinding().getKey();
+		case ASTNode.FIELD_DECLARATION:
+			VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) recipient).fragments().get(0);
+			return fragment.resolveBinding().getKey();
+		case ASTNode.METHOD_DECLARATION:
+			return ((MethodDeclaration) recipient).resolveBinding().getKey();
+		case ASTNode.VARIABLE_DECLARATION_STATEMENT:
+			fragment = (VariableDeclarationFragment) ((VariableDeclarationStatement) recipient).fragments().get(0);
+			return fragment.resolveBinding().getKey();
+		default:
+			return ""; //$NON-NLS-1$
+		}
+	}
+
+	public int getKind() {
+		return IBinding.ANNOTATION;
+	}
+
+	public int getModifiers() {
+		return Modifier.NONE;
+	}
+
+	public String getName() {
+		ITypeBinding annotationType = getAnnotationType();
+		if (annotationType == null) {
+			return new String(this.binding.getAnnotationType().sourceName());
+		} else {
+			return annotationType.getName();
+		}
+	}
+
+	public boolean isDeprecated() {
+		ReferenceBinding typeBinding = this.binding.getAnnotationType();
+		if (typeBinding == null) return false;
+		return typeBinding.isDeprecated();
+	}
+
+	public boolean isEqualTo(IBinding otherBinding) {
+		if (this == otherBinding)
+			return true;
+		if (otherBinding.getKind() != IBinding.ANNOTATION)
+			return false;
+		IAnnotationBinding other = (IAnnotationBinding) otherBinding;
+		if (!getAnnotationType().isEqualTo(other.getAnnotationType()))
+			return false;
+		IMemberValuePairBinding[] memberValuePairs = getDeclaredMemberValuePairs();
+		IMemberValuePairBinding[] otherMemberValuePairs = other.getDeclaredMemberValuePairs();
+		if (memberValuePairs.length != otherMemberValuePairs.length)
+			return false;
+		for (int i = 0, length = memberValuePairs.length; i < length; i++) {
+			if (!memberValuePairs[i].isEqualTo(otherMemberValuePairs[i]))
+				return false;
+		}
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+        ReferenceBinding annotationType = this.binding.getAnnotationType();
+        return annotationType == null || (annotationType.tagBits & TagBits.HasMissingType) != 0;	}
+
+	public boolean isSynthetic() {
+		return false;
+	}
+
+	public String toString() {
+		ITypeBinding type = getAnnotationType();
+		final StringBuffer buffer = new StringBuffer();
+		buffer.append('@');
+		if (type != null)
+			buffer.append(type.getName());
+		buffer.append('(');
+		IMemberValuePairBinding[] pairs = getDeclaredMemberValuePairs();
+		for (int i = 0, len = pairs.length; i < len; i++) {
+			if (i != 0)
+				buffer.append(", "); //$NON-NLS-1$
+			buffer.append(pairs[i].toString());
+		}
+		buffer.append(')');
+		return buffer.toString();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java
new file mode 100644
index 0000000..6200463
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Annotation type declaration AST node type (added in JLS3 API).
+ * <pre>
+ * AnnotationTypeDeclaration:
+ *   [ Javadoc ] { ExtendedModifier } <b>@</b> <b>interface</b> Identifier
+ *		<b>{</b> { AnnotationTypeBodyDeclaration | <b>;</b> } <b>}</b>
+ * AnnotationTypeBodyDeclaration:
+ *   AnnotationTypeMemberDeclaration
+ *   FieldDeclaration
+ *   TypeDeclaration
+ *   EnumDeclaration
+ *   AnnotationTypeDeclaration
+ * </pre>
+ * <p>
+ * The thing to note is that method declaration are replaced
+ * by annotation type member declarations in this context.
+ * </p>
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier keyword (if modifiers), or the
+ * first character of the "@interface" (if no
+ * modifiers). The source range extends through the last character of the "}"
+ * token following the body declarations.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class AnnotationTypeDeclaration extends AbstractTypeDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(AnnotationTypeDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}).
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(AnnotationTypeDeclaration.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		internalNamePropertyFactory(AnnotationTypeDeclaration.class);
+
+	/**
+	 * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}).
+	 */
+	public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
+		internalBodyDeclarationPropertyFactory(AnnotationTypeDeclaration.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(5);
+		createPropertyList(AnnotationTypeDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(BODY_DECLARATIONS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new AST node for an annotation type declaration owned by the given
+	 * AST. By default, the type declaration is for an annotation
+	 * type of an unspecified, but legal, name; no modifiers; no javadoc;
+	 * and an empty list of body declarations.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AnnotationTypeDeclaration(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == BODY_DECLARATIONS_PROPERTY) {
+			return bodyDeclarations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		// this property will not be asked for (node type did not exist in JLS2)
+		return null;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildPropertyDescriptor internalNameProperty() {
+		return NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
+		return BODY_DECLARATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ANNOTATION_TYPE_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		result.setName((SimpleName) getName().clone(target));
+		result.bodyDeclarations().addAll(ASTNode.copySubtrees(target, bodyDeclarations()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			acceptChildren(visitor, this.modifiers);
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.bodyDeclarations);
+		}
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AsbtractTypeDeclaration.
+	 */
+	ITypeBinding internalResolveBinding() {
+		return this.ast.getBindingResolver().resolveType(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ this.modifiers.listSize()
+			+ (this.typeName == null ? 0 : getName().treeSize())
+			+ this.bodyDeclarations.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java
new file mode 100644
index 0000000..fdb31e7
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Annotation type member declaration AST node type (added in JLS3 API).
+ * <pre>
+ * AnnotationTypeMemberDeclaration:
+ *   [ Javadoc ] { ExtendedModifier }
+ *       Type Identifier <b>(</b> <b>)</b> [ <b>default</b> Expression ] <b>;</b>
+ * </pre>
+ * <p>
+ * Note that annotation type member declarations are only meaningful as
+ * elements of {@link AnnotationTypeDeclaration#bodyDeclarations()}.
+ * </p>
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier keyword (if modifiers),
+ * or the first character of the member type (no modifiers).
+ * The source range extends through the last character of the
+ * ";" token.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class AnnotationTypeMemberDeclaration extends BodyDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(AnnotationTypeMemberDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}).
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(AnnotationTypeMemberDeclaration.class);
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+			new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "default" structural property of this node type (child type: {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor DEFAULT_PROPERTY =
+		new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "default", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(6);
+		createPropertyList(AnnotationTypeMemberDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(DEFAULT_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The member type; lazily initialized; defaults to int.
+	 */
+	private Type memberType = null;
+
+	/**
+	 * The member name; lazily initialized; defaults to an unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName memberName = null;
+
+	/**
+	 * The optional default expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalDefaultValue = null;
+
+	/**
+	 * Creates a new AST node for an annotation type member declaration owned
+	 * by the given AST. By default, the declaration is for a member of an
+	 * unspecified, but legal, name; no modifiers; no javadoc;
+	 * an unspecified value type; and no default value.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AnnotationTypeMemberDeclaration(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == DEFAULT_PROPERTY) {
+			if (get) {
+				return getDefault();
+			} else {
+				setDefault((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		// this property will not be asked for (node type did not exist in JLS2)
+		return null;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ANNOTATION_TYPE_MEMBER_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		result.setType((Type) ASTNode.copySubtree(target, getType()));
+		result.setName((SimpleName) getName().clone(target));
+		result.setDefault((Expression) ASTNode.copySubtree(target, getDefault()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			acceptChildren(visitor, this.modifiers);
+			acceptChild(visitor, getType());
+			acceptChild(visitor, getName());
+			acceptChild(visitor, getDefault());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type of the annotation type member declared in this
+	 * declaration.
+	 *
+	 * @return the type of the member
+	 */
+	public Type getType() {
+		if (this.memberType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.memberType == null) {
+					preLazyInit();
+					this.memberType = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.memberType, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.memberType;
+	}
+
+	/**
+	 * Sets the type of the annotation type member declared in this declaration
+	 * to the given type.
+	 *
+	 * @param type the new member type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.memberType;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.memberType = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the name of the annotation type member declared in this declaration.
+	 *
+	 * @return the member name node
+	 */
+	public SimpleName getName() {
+		if (this.memberName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.memberName == null) {
+					preLazyInit();
+					this.memberName = new SimpleName(this.ast);
+					postLazyInit(this.memberName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.memberName;
+	}
+
+	/**
+	 * Sets the name of the annotation type member declared in this declaration to the
+	 * given name.
+	 *
+	 * @param memberName the new member name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName memberName) {
+		if (memberName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.memberName;
+		preReplaceChild(oldChild, memberName, NAME_PROPERTY);
+		this.memberName = memberName;
+		postReplaceChild(oldChild, memberName, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the default value of this annotation type member, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getDefault() {
+		return this.optionalDefaultValue;
+	}
+
+	/**
+	 * Sets or clears the default value of this annotation type member.
+	 *
+	 * @param defaultValue the expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setDefault(Expression defaultValue) {
+		// a AnnotationTypeMemberDeclaration may occur inside an Expression - must check cycles
+		ASTNode oldChild = this.optionalDefaultValue;
+		preReplaceChild(oldChild, defaultValue, DEFAULT_PROPERTY);
+		this.optionalDefaultValue = defaultValue;
+		postReplaceChild(oldChild, defaultValue, DEFAULT_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the annotation type member declared
+	 * in this declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IMethodBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveMember(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ this.modifiers.listSize()
+			+ (this.memberName == null ? 0 : getName().treeSize())
+			+ (this.memberType == null ? 0 : getType().treeSize())
+			+ (this.optionalDefaultValue == null ? 0 : getDefault().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java
new file mode 100644
index 0000000..14d4caf
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Anonymous class declaration AST node type. For JLS2, this type of node appears
+ * only as a child on a class instance creation expression.
+ * For JLS3, this type of node appears may also appear as the child of
+ * an enum constant declaration.
+ *
+ * <pre>
+ * AnonymousClassDeclaration:
+ *        <b>{</b> ClassBodyDeclaration <b>}</b>
+ * </pre>
+ *
+ * @see ClassInstanceCreation
+ * @see EnumConstantDeclaration
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class AnonymousClassDeclaration extends ASTNode {
+
+	/**
+	 * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
+		new ChildListPropertyDescriptor(AnonymousClassDeclaration.class, "bodyDeclarations", BodyDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(AnonymousClassDeclaration.class, properyList);
+		addProperty(BODY_DECLARATIONS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The body declarations (element type: {@link BodyDeclaration}).
+	 * Defaults to none.
+	 */
+	private ASTNode.NodeList bodyDeclarations =
+		new ASTNode.NodeList(BODY_DECLARATIONS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for an anonymous class declaration owned
+	 * by the given AST. By default, the list of body declarations is empty.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AnonymousClassDeclaration(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == BODY_DECLARATIONS_PROPERTY) {
+			return bodyDeclarations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ANONYMOUS_CLASS_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		AnonymousClassDeclaration result = new AnonymousClassDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.bodyDeclarations().addAll(
+			ASTNode.copySubtrees(target, bodyDeclarations()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.bodyDeclarations);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of body declarations of this
+	 * anonymous class declaration.
+	 *
+	 * @return the live list of body declarations
+	 *    (element type: {@link BodyDeclaration})
+	 */
+	public List bodyDeclarations() {
+		return this.bodyDeclarations;
+	}
+
+	/**
+	 * Resolves and returns the binding for the anonymous class declared in
+	 * this declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public ITypeBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveType(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ this.bodyDeclarations.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java
new file mode 100644
index 0000000..9f173c2
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Array access expression AST node type.
+ *
+ * <pre>
+ * ArrayAccess:
+ *    Expression <b>[</b> Expression <b>]</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ArrayAccess extends Expression {
+
+	/**
+	 * The "array" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor ARRAY_PROPERTY =
+		new ChildPropertyDescriptor(ArrayAccess.class, "array", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "index" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor INDEX_PROPERTY =
+		new ChildPropertyDescriptor(ArrayAccess.class, "index", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(ArrayAccess.class, properyList);
+		addProperty(ARRAY_PROPERTY, properyList);
+		addProperty(INDEX_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The array expression; lazily initialized; defaults to an unspecified,
+	 * but legal, expression.
+	 */
+	private Expression arrayExpression = null;
+
+	/**
+	 * The index expression; lazily initialized; defaults to an unspecified,
+	 * but legal, expression.
+	 */
+	private Expression indexExpression = null;
+
+	/**
+	 * Creates a new unparented array access expression node owned by the given
+	 * AST. By default, the array and index expresssions are unspecified,
+	 * but legal.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ArrayAccess(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == ARRAY_PROPERTY) {
+			if (get) {
+				return getArray();
+			} else {
+				setArray((Expression) child);
+				return null;
+			}
+		}
+		if (property == INDEX_PROPERTY) {
+			if (get) {
+				return getIndex();
+			} else {
+				setIndex((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ARRAY_ACCESS;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ArrayAccess result = new ArrayAccess(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setArray((Expression) getArray().clone(target));
+		result.setIndex((Expression) getIndex().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getArray());
+			acceptChild(visitor, getIndex());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the array expression of this array access expression.
+	 *
+	 * @return the array expression node
+	 */
+	public Expression getArray() {
+		if (this.arrayExpression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.arrayExpression == null) {
+					preLazyInit();
+					this.arrayExpression = new SimpleName(this.ast);
+					postLazyInit(this.arrayExpression, ARRAY_PROPERTY);
+				}
+			}
+		}
+		return this.arrayExpression;
+	}
+
+	/**
+	 * Sets the array expression of this array access expression.
+	 *
+	 * @param expression the array expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setArray(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		// an ArrayAccess may occur inside an Expression
+		// must check cycles
+		ASTNode oldChild = this.arrayExpression;
+		preReplaceChild(oldChild, expression, ARRAY_PROPERTY);
+		this.arrayExpression = expression;
+		postReplaceChild(oldChild, expression, ARRAY_PROPERTY);
+	}
+
+	/**
+	 * Returns the index expression of this array access expression.
+	 *
+	 * @return the index expression node
+	 */
+	public Expression getIndex() {
+		if (this.indexExpression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.indexExpression == null) {
+					preLazyInit();
+					this.indexExpression = new SimpleName(this.ast);
+					postLazyInit(this.indexExpression, INDEX_PROPERTY);
+				}
+			}
+		}
+		return this.indexExpression;
+	}
+
+	/**
+	 * Sets the index expression of this array access expression.
+	 *
+	 * @param expression the index expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setIndex(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		// an ArrayAccess may occur inside an Expression
+		// must check cycles
+		ASTNode oldChild = this.indexExpression;
+		preReplaceChild(oldChild, expression, INDEX_PROPERTY);
+		this.indexExpression = expression;
+		postReplaceChild(oldChild, expression, INDEX_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.arrayExpression == null ? 0 : getArray().treeSize())
+			+ (this.indexExpression == null ? 0 : getIndex().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java
new file mode 100644
index 0000000..76127e4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Array creation expression AST node type.
+ * <pre>
+ * ArrayCreation:
+ *    <b>new</b> PrimitiveType <b>[</b> Expression <b>]</b> { <b>[</b> Expression <b>]</b> } { <b>[</b> <b>]</b> }
+ *    <b>new</b> TypeName [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *        <b>[</b> Expression <b>]</b> { <b>[</b> Expression <b>]</b> } { <b>[</b> <b>]</b> }
+ *    <b>new</b> PrimitiveType <b>[</b> <b>]</b> { <b>[</b> <b>]</b> } ArrayInitializer
+ *    <b>new</b> TypeName [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *        <b>[</b> <b>]</b> { <b>[</b> <b>]</b> } ArrayInitializer
+ * </pre>
+ * <p>
+ * The mapping from Java language syntax to AST nodes is as follows:
+ * <ul>
+ * <li>the type node is the array type of the creation expression,
+ *   with one level of array per set of square brackets,</li>
+ * <li>the dimension expressions are collected into the <code>dimensions</code>
+ *   list.</li>
+ * </ul>
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ArrayCreation extends Expression {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link ArrayType}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(ArrayCreation.class, "type", ArrayType.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "dimensions" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor DIMENSIONS_PROPERTY =
+		new ChildListPropertyDescriptor(ArrayCreation.class, "dimensions", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "initializer" structural property of this node type (child type: {@link ArrayInitializer}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor INITIALIZER_PROPERTY =
+		new ChildPropertyDescriptor(ArrayCreation.class, "initializer", ArrayInitializer.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(ArrayCreation.class, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(DIMENSIONS_PROPERTY, properyList);
+		addProperty(INITIALIZER_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The array type; lazily initialized; defaults to a unspecified,
+	 * legal array type.
+	 */
+	private ArrayType arrayType = null;
+
+	/**
+	 * The list of dimension expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList dimensions =
+		new ASTNode.NodeList(DIMENSIONS_PROPERTY);
+
+	/**
+	 * The optional array initializer, or <code>null</code> if none;
+	 * defaults to none.
+	 */
+	private ArrayInitializer optionalInitializer = null;
+
+	/**
+	 * Creates a new AST node for an array creation expression owned by the
+	 * given AST. By default, the array type is an unspecified 1-dimensional
+	 * array, the list of dimensions is empty, and there is no array
+	 * initializer.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ArrayCreation(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == INITIALIZER_PROPERTY) {
+			if (get) {
+				return getInitializer();
+			} else {
+				setInitializer((ArrayInitializer) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((ArrayType) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == DIMENSIONS_PROPERTY) {
+			return dimensions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ARRAY_CREATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ArrayCreation result = new ArrayCreation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((ArrayType) getType().clone(target));
+		result.dimensions().addAll(ASTNode.copySubtrees(target, dimensions()));
+		result.setInitializer(
+			(ArrayInitializer) ASTNode.copySubtree(target, getInitializer()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.dimensions);
+			acceptChild(visitor, getInitializer());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the array type in this array creation expression.
+	 *
+	 * @return the array type
+	 */
+	public ArrayType getType() {
+		if (this.arrayType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.arrayType == null) {
+					preLazyInit();
+					this.arrayType = this.ast.newArrayType(
+							this.ast.newPrimitiveType(PrimitiveType.INT));
+					postLazyInit(this.arrayType, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.arrayType;
+	}
+
+	/**
+	 * Sets the array type in this array creation expression.
+	 *
+	 * @param type the new array type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(ArrayType type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		// an ArrayCreation cannot occur inside a ArrayType - cycles not possible
+		ASTNode oldChild = this.arrayType;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.arrayType = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of dimension expressions in this array
+	 * initializer.
+	 *
+	 * @return the live list of dimension expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List dimensions() {
+		return this.dimensions;
+	}
+
+	/**
+	 * Returns the array initializer of this array creation expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the array initializer node, or <code>null</code> if
+	 *    there is none
+	 */
+	public ArrayInitializer getInitializer() {
+		return this.optionalInitializer;
+	}
+
+	/**
+	 * Sets or clears the array initializer of this array creation expression.
+	 *
+	 * @param initializer the array initializer node, or <code>null</code>
+	 *    if there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setInitializer(ArrayInitializer initializer) {
+		// an ArrayCreation may occur inside an ArrayInitializer
+		// must check cycles
+		ASTNode oldChild = this.optionalInitializer;
+		preReplaceChild(oldChild, initializer, INITIALIZER_PROPERTY);
+		this.optionalInitializer = initializer;
+		postReplaceChild(oldChild, initializer, INITIALIZER_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		int size = memSize()
+			+ (this.arrayType == null ? 0 : getType().treeSize())
+			+ (this.optionalInitializer == null ? 0 : getInitializer().treeSize())
+			+ this.dimensions.listSize();
+		return size;
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java
new file mode 100644
index 0000000..f2c115d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Array initializer AST node type.
+ *
+ * <pre>
+ * ArrayInitializer:
+ * 		<b>{</b> [ Expression { <b>,</b> Expression} [ <b>,</b> ]] <b>}</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ArrayInitializer extends Expression {
+
+	/**
+	 * The "expressions" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor EXPRESSIONS_PROPERTY =
+		new ChildListPropertyDescriptor(ArrayInitializer.class, "expressions", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(ArrayInitializer.class, properyList);
+		addProperty(EXPRESSIONS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The list of expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList expressions =
+		new ASTNode.NodeList(EXPRESSIONS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for an array initializer owned by the
+	 * given AST. By default, the list of expressions is empty.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ArrayInitializer(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == EXPRESSIONS_PROPERTY) {
+			return expressions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ARRAY_INITIALIZER;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ArrayInitializer result = new ArrayInitializer(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.expressions().addAll(ASTNode.copySubtrees(target, expressions()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChildren(visitor, this.expressions);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of expressions in this array initializer.
+	 *
+	 * @return the live list of expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List expressions() {
+		return this.expressions;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize() + this.expressions.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java
new file mode 100644
index 0000000..cd1dd83
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for an array type.
+ * <p>
+ * Array types are expressed in a recursive manner, one dimension at a time.
+ * </p>
+ * <pre>
+ * ArrayType:
+ *    Type { Annotation } <b>'['</b> <b>']'</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ArrayType extends AnnotatableType {
+
+	/**
+	 * The "componentType" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor COMPONENT_TYPE_PROPERTY =
+		new ChildPropertyDescriptor(ArrayType.class, "componentType", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(ArrayType.class);
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ArrayType.class, propertyList);
+		addProperty(COMPONENT_TYPE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(3);
+		createPropertyList(ArrayType.class, propertyList);
+		addProperty(COMPONENT_TYPE_PROPERTY, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The component type; lazily initialized; defaults to a simple type with
+	 * an unspecified, but legal, name.
+	 */
+	private Type componentType = null;
+
+	/**
+	 * Creates a new unparented node for an array type owned by the given AST.
+	 * By default, a 1-dimensional array of an unspecified simple type.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ArrayType(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == COMPONENT_TYPE_PROPERTY) {
+			if (get) {
+				return getComponentType();
+			} else {
+				setComponentType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ARRAY_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ArrayType result = new ArrayType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setComponentType((Type) getComponentType().clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getComponentType());
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the component type of this array type. The component type
+	 * may be another array type.
+	 *
+	 * @return the component type node
+	 */
+	public Type getComponentType() {
+		if (this.componentType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.componentType == null) {
+					preLazyInit();
+					this.componentType = new SimpleType(this.ast);
+					postLazyInit(this.componentType, COMPONENT_TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.componentType;
+	}
+
+	/**
+	 * Sets the component type of this array type. The component type
+	 * may be another array type.
+	 *
+	 * @param componentType the component type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setComponentType(Type componentType) {
+		if (componentType == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.componentType;
+		preReplaceChild(oldChild, componentType, COMPONENT_TYPE_PROPERTY);
+		this.componentType = componentType;
+		postReplaceChild(oldChild, componentType, COMPONENT_TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the element type of this array type. The element type is
+	 * never an array type.
+	 * <p>
+	 * This is a convenience method that descends a chain of nested array types
+	 * until it reaches a non-array type.
+	 * </p>
+	 *
+	 * @return the component type node
+	 */
+	public Type getElementType() {
+		Type t = getComponentType();
+		while (t.isArrayType()) {
+			t = ((ArrayType) t).getComponentType();
+		}
+		return t;
+	}
+
+	/**
+	 * Returns the number of dimensions in this array type.
+	 * <p>
+	 * This is a convenience method that descends a chain of nested array types
+	 * until it reaches a non-array type.
+	 * </p>
+	 *
+	 * @return the number of dimensions (always positive)
+	 */
+	public int getDimensions() {
+		Type t = getComponentType();
+		int dimensions = 1; // always include this array type
+		while (t.isArrayType()) {
+			dimensions++;
+			t = ((ArrayType) t).getComponentType();
+		}
+		return dimensions;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.componentType == null ? 0 : getComponentType().treeSize())
+			+ (this.annotations == null ? 0 : this.annotations.listSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java
new file mode 100644
index 0000000..6c71fa6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Assert statement AST node type.
+ *
+ * <pre>
+ * AssertStatement:
+ *    <b>assert</b> Expression [ <b>:</b> Expression ] <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class AssertStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(AssertStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "message" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor MESSAGE_PROPERTY =
+		new ChildPropertyDescriptor(AssertStatement.class, "message", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(AssertStatement.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(MESSAGE_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The message expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalMessageExpression = null;
+
+	/**
+	 * Creates a new unparented assert statement node owned by the given
+	 * AST. By default, the assert statement has an unspecified, but legal,
+	 * expression, and not message expression.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	AssertStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == MESSAGE_PROPERTY) {
+			if (get) {
+				return getMessage();
+			} else {
+				setMessage((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ASSERT_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		AssertStatement result = new AssertStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		result.setMessage(
+			(Expression) ASTNode.copySubtree(target, getMessage()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getMessage());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the first expression of this assert statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the first expression of this assert statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		// an AssertStatement may occur inside an Expression - must check cycles
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the message expression of this assert statement, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the message expression node, or <code>null</code> if there
+	 *    is none
+	 */
+	public Expression getMessage() {
+		return this.optionalMessageExpression;
+	}
+
+	/**
+	 * Sets or clears the message expression of this assert statement.
+	 *
+	 * @param expression the message expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setMessage(Expression expression) {
+		// an AsertStatement may occur inside an Expression - must check cycles
+		ASTNode oldChild = this.optionalMessageExpression;
+		preReplaceChild(oldChild, expression, MESSAGE_PROPERTY);
+		this.optionalMessageExpression = expression;
+		postReplaceChild(oldChild, expression, MESSAGE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.optionalMessageExpression == null ? 0 : getMessage().treeSize());
+
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java
new file mode 100644
index 0000000..3a6542c
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Assignment expression AST node type.
+ *
+ * <pre>
+ * Assignment:
+ *    Expression AssignmentOperator Expression
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class Assignment extends Expression {
+
+	/**
+ 	 * Assignment operators (typesafe enumeration).
+	 * <pre>
+	 * AssignmentOperator:<code>
+	 *    <b>=</b> ASSIGN
+	 *    <b>+=</b> PLUS_ASSIGN
+	 *    <b>-=</b> MINUS_ASSIGN
+	 *    <b>*=</b> TIMES_ASSIGN
+	 *    <b>/=</b> DIVIDE_ASSIGN
+	 *    <b>&amp;=</b> BIT_AND_ASSIGN
+	 *    <b>|=</b> BIT_OR_ASSIGN
+	 *    <b>^=</b> BIT_XOR_ASSIGN
+	 *    <b>%=</b> REMAINDER_ASSIGN
+	 *    <b>&lt;&lt;=</b> LEFT_SHIFT_ASSIGN
+	 *    <b>&gt;&gt;=</b> RIGHT_SHIFT_SIGNED_ASSIGN
+	 *    <b>&gt;&gt;&gt;=</b> RIGHT_SHIFT_UNSIGNED_ASSIGN</code>
+	 * </pre>
+	 */
+	public static class Operator {
+
+		/**
+		 * The name of the operator
+		 */
+		private String op;
+
+		/**
+		 * Creates a new assignment operator with the given name.
+		 * <p>
+		 * Note: this constructor is private. The only instances
+		 * ever created are the ones for the standard operators.
+		 * </p>
+		 *
+		 * @param op the character sequence for the operator
+		 */
+		private Operator(String op) {
+			this.op = op;
+		}
+
+		/**
+		 * Returns the character sequence for the operator.
+		 *
+		 * @return the character sequence for the operator
+		 */
+		public String toString() {
+			return this.op;
+		}
+
+		/** = operator. */
+		public static final Operator ASSIGN = new Operator("=");//$NON-NLS-1$
+		/** += operator. */
+		public static final Operator PLUS_ASSIGN = new Operator("+=");//$NON-NLS-1$
+		/** -= operator. */
+		public static final Operator MINUS_ASSIGN = new Operator("-=");//$NON-NLS-1$
+		/** *= operator. */
+		public static final Operator TIMES_ASSIGN = new Operator("*=");//$NON-NLS-1$
+		/** /= operator. */
+		public static final Operator DIVIDE_ASSIGN = new Operator("/=");//$NON-NLS-1$
+		/** &amp;= operator. */
+		public static final Operator BIT_AND_ASSIGN = new Operator("&=");//$NON-NLS-1$
+		/** |= operator. */
+		public static final Operator BIT_OR_ASSIGN = new Operator("|=");//$NON-NLS-1$
+		/** ^= operator. */
+		public static final Operator BIT_XOR_ASSIGN = new Operator("^=");//$NON-NLS-1$
+		/** %= operator. */
+		public static final Operator REMAINDER_ASSIGN = new Operator("%=");//$NON-NLS-1$
+		/** &lt;&lt;== operator. */
+		public static final Operator LEFT_SHIFT_ASSIGN =
+			new Operator("<<=");//$NON-NLS-1$
+		/** &gt;&gt;= operator. */
+		public static final Operator RIGHT_SHIFT_SIGNED_ASSIGN =
+			new Operator(">>=");//$NON-NLS-1$
+		/** &gt;&gt;&gt;= operator. */
+		public static final Operator RIGHT_SHIFT_UNSIGNED_ASSIGN =
+			new Operator(">>>=");//$NON-NLS-1$
+
+		/**
+		 * Returns the assignment operator corresponding to the given string,
+		 * or <code>null</code> if none.
+		 * <p>
+		 * <code>toOperator</code> is the converse of <code>toString</code>:
+		 * that is, <code>Operator.toOperator(op.toString()) == op</code> for all
+		 * operators <code>op</code>.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 * @return the assignment operator, or <code>null</code> if none
+		 */
+		public static Operator toOperator(String token) {
+			return (Operator) CODES.get(token);
+		}
+
+		/**
+		 * Map from token to operator (key type: <code>String</code>;
+		 * value type: <code>Operator</code>).
+		 */
+		private static final Map CODES;
+		static {
+			CODES = new HashMap(20);
+			Operator[] ops = {
+					ASSIGN,
+					PLUS_ASSIGN,
+					MINUS_ASSIGN,
+					TIMES_ASSIGN,
+					DIVIDE_ASSIGN,
+					BIT_AND_ASSIGN,
+					BIT_OR_ASSIGN,
+					BIT_XOR_ASSIGN,
+					REMAINDER_ASSIGN,
+					LEFT_SHIFT_ASSIGN,
+					RIGHT_SHIFT_SIGNED_ASSIGN,
+					RIGHT_SHIFT_UNSIGNED_ASSIGN
+				};
+			for (int i = 0; i < ops.length; i++) {
+				CODES.put(ops[i].toString(), ops[i]);
+			}
+		}
+	}
+
+	/**
+	 * The "leftHandSide" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LEFT_HAND_SIDE_PROPERTY =
+		new ChildPropertyDescriptor(Assignment.class, "leftHandSide", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "operator" structural property of this node type (type: {@link Assignment.Operator}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
+		new SimplePropertyDescriptor(Assignment.class, "operator", Assignment.Operator.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "rightHandSide" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor RIGHT_HAND_SIDE_PROPERTY =
+		new ChildPropertyDescriptor(Assignment.class, "rightHandSide", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(Assignment.class, properyList);
+		addProperty(LEFT_HAND_SIDE_PROPERTY, properyList);
+		addProperty(OPERATOR_PROPERTY, properyList);
+		addProperty(RIGHT_HAND_SIDE_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The assignment operator; defaults to Assignment.Operator.ASSIGN
+	 */
+	private Assignment.Operator assignmentOperator = Assignment.Operator.ASSIGN;
+
+	/**
+	 * The left hand side; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression leftHandSide = null;
+
+	/**
+	 * The right hand side; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression rightHandSide = null;
+
+	/**
+	 * Creates a new AST node for an assignment expression owned by the given
+	 * AST. By default, the node has an assignment operator, and unspecified
+	 * left and right hand sides.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Assignment(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == OPERATOR_PROPERTY) {
+			if (get) {
+				return getOperator();
+			} else {
+				setOperator((Operator) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LEFT_HAND_SIDE_PROPERTY) {
+			if (get) {
+				return getLeftHandSide();
+			} else {
+				setLeftHandSide((Expression) child);
+				return null;
+			}
+		}
+		if (property == RIGHT_HAND_SIDE_PROPERTY) {
+			if (get) {
+				return getRightHandSide();
+			} else {
+				setRightHandSide((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ASSIGNMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		Assignment result = new Assignment(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setOperator(getOperator());
+		result.setLeftHandSide((Expression) getLeftHandSide().clone(target));
+		result.setRightHandSide((Expression) getRightHandSide().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getLeftHandSide());
+			acceptChild(visitor, getRightHandSide());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the operator of this assignment expression.
+	 *
+	 * @return the assignment operator
+	 */
+	public Assignment.Operator getOperator() {
+		return this.assignmentOperator;
+	}
+
+	/**
+	 * Sets the operator of this assignment expression.
+	 *
+	 * @param assignmentOperator the assignment operator
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setOperator(Assignment.Operator assignmentOperator) {
+		if (assignmentOperator == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(OPERATOR_PROPERTY);
+		this.assignmentOperator = assignmentOperator;
+		postValueChange(OPERATOR_PROPERTY);
+	}
+
+	/**
+	 * Returns the left hand side of this assignment expression.
+	 *
+	 * @return the left hand side node
+	 */
+	public Expression getLeftHandSide() {
+		if (this.leftHandSide  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.leftHandSide == null) {
+					preLazyInit();
+					this.leftHandSide= new SimpleName(this.ast);
+					postLazyInit(this.leftHandSide, LEFT_HAND_SIDE_PROPERTY);
+				}
+			}
+		}
+		return this.leftHandSide;
+	}
+
+	/**
+	 * Sets the left hand side of this assignment expression.
+	 *
+	 * @param expression the left hand side node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setLeftHandSide(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		// an Assignment may occur inside a Expression - must check cycles
+		ASTNode oldChild = this.leftHandSide;
+		preReplaceChild(oldChild, expression, LEFT_HAND_SIDE_PROPERTY);
+		this.leftHandSide = expression;
+		postReplaceChild(oldChild, expression, LEFT_HAND_SIDE_PROPERTY);
+	}
+
+	/**
+	 * Returns the right hand side of this assignment expression.
+	 *
+	 * @return the right hand side node
+	 */
+	public Expression getRightHandSide() {
+		if (this.rightHandSide  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.rightHandSide == null) {
+					preLazyInit();
+					this.rightHandSide= new SimpleName(this.ast);
+					postLazyInit(this.rightHandSide, RIGHT_HAND_SIDE_PROPERTY);
+				}
+			}
+		}
+		return this.rightHandSide;
+	}
+
+	/**
+	 * Sets the right hand side of this assignment expression.
+	 *
+	 * @param expression the right hand side node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setRightHandSide(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		// an Assignment may occur inside a Expression - must check cycles
+		ASTNode oldChild = this.rightHandSide;
+		preReplaceChild(oldChild, expression, RIGHT_HAND_SIDE_PROPERTY);
+		this.rightHandSide = expression;
+		postReplaceChild(oldChild, expression, RIGHT_HAND_SIDE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.leftHandSide == null ? 0 : getLeftHandSide().treeSize())
+			+ (this.rightHandSide == null ? 0 : getRightHandSide().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
new file mode 100644
index 0000000..9cf4068
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.HashSet;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+
+/**
+ * Internal helper class for comparing bindings.
+ *
+ * @since 3.1
+ */
+class BindingComparator {
+	/**
+	 * @param bindings
+	 * @param otherBindings
+	 * @return true if both parameters are equals, false otherwise
+	 */
+	static boolean isEqual(TypeVariableBinding[] bindings, TypeVariableBinding[] otherBindings) {
+		if (bindings == null) {
+			return otherBindings == null;
+		}
+		if (otherBindings == null) {
+			return false;
+		}
+		int length = bindings.length;
+		int otherLength = otherBindings.length;
+		if (length != otherLength) {
+			return false;
+		}
+		for (int i = 0; i < length; i++) {
+			TypeVariableBinding typeVariableBinding = bindings[i];
+			TypeVariableBinding typeVariableBinding2 = otherBindings[i];
+			if (!isEqual(typeVariableBinding, typeVariableBinding2)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @param declaringElement
+	 * @param declaringElement2
+	 * @return true if both parameters are equals, false otherwise
+	 */
+	static boolean isEqual(Binding declaringElement, Binding declaringElement2, HashSet visitedTypes) {
+		if (declaringElement instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+			if (!(declaringElement2 instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding)){
+				return false;
+			}
+			return isEqual((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement,
+					(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement2,
+					visitedTypes);
+		} else if (declaringElement instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
+			if (!(declaringElement2 instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding)) {
+				return false;
+			}
+			return isEqual((org.eclipse.jdt.internal.compiler.lookup.MethodBinding) declaringElement,
+					(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) declaringElement2,
+					visitedTypes);
+		} else if (declaringElement instanceof VariableBinding) {
+			if (!(declaringElement2 instanceof VariableBinding)) {
+				return false;
+			}
+			return isEqual((VariableBinding) declaringElement,
+					(VariableBinding) declaringElement2);
+		} else if (declaringElement instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+			if (!(declaringElement2 instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding)) {
+				return false;
+			}
+			org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding = (org.eclipse.jdt.internal.compiler.lookup.PackageBinding) declaringElement;
+			org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding2 = (org.eclipse.jdt.internal.compiler.lookup.PackageBinding) declaringElement2;
+			return CharOperation.equals(packageBinding.compoundName, packageBinding2.compoundName);
+		} else if (declaringElement instanceof ImportBinding) {
+			if (!(declaringElement2 instanceof ImportBinding)) {
+				return false;
+			}
+			ImportBinding importBinding = (ImportBinding) declaringElement;
+			ImportBinding importBinding2 = (ImportBinding) declaringElement2;
+			return importBinding.isStatic() == importBinding2.isStatic()
+				&& importBinding.onDemand == importBinding2.onDemand
+				&& CharOperation.equals(importBinding.compoundName, importBinding2.compoundName);
+		}
+		return false;
+	}
+
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding,
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding2) {
+		return isEqual(methodBinding, methodBinding2, new HashSet());
+	}
+
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding,
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding2,
+			HashSet visitedTypes) {
+		if (methodBinding == null) {
+			return methodBinding2 == null;
+		}
+		if (methodBinding2 == null) return false;
+		return CharOperation.equals(methodBinding.selector, methodBinding2.selector)
+				&& isEqual(methodBinding.returnType, methodBinding2.returnType, visitedTypes)
+				&& isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, visitedTypes)
+				&& isEqual(methodBinding.declaringClass, methodBinding2.declaringClass, visitedTypes)
+				&& isEqual(methodBinding.typeVariables, methodBinding2.typeVariables, visitedTypes)
+				&& isEqual(methodBinding.parameters, methodBinding2.parameters, visitedTypes);
+	}
+
+	static boolean isEqual(VariableBinding variableBinding, VariableBinding variableBinding2) {
+		return (variableBinding.modifiers & ExtraCompilerModifiers.AccJustFlag) == (variableBinding2.modifiers & ExtraCompilerModifiers.AccJustFlag)
+				&& CharOperation.equals(variableBinding.name, variableBinding2.name)
+				&& isEqual(variableBinding.type, variableBinding2.type)
+				&& (variableBinding.id == variableBinding2.id);
+	}
+
+	static boolean isEqual(FieldBinding fieldBinding, FieldBinding fieldBinding2) {
+		HashSet visitedTypes = new HashSet();
+		return (fieldBinding.modifiers & ExtraCompilerModifiers.AccJustFlag) == (fieldBinding2.modifiers & ExtraCompilerModifiers.AccJustFlag)
+				&& CharOperation.equals(fieldBinding.name, fieldBinding2.name)
+				&& isEqual(fieldBinding.type, fieldBinding2.type, visitedTypes)
+				&& isEqual(fieldBinding.declaringClass, fieldBinding2.declaringClass, visitedTypes);
+	}
+
+	/**
+	 * @param bindings
+	 * @param otherBindings
+	 * @return true if both parameters are equals, false otherwise
+	 */
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] bindings, org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] otherBindings) {
+		return isEqual(bindings, otherBindings, new HashSet());
+	}
+	/**
+	 * @param bindings
+	 * @param otherBindings
+	 * @return true if both parameters are equals, false otherwise
+	 */
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] bindings, org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] otherBindings, HashSet visitedTypes) {
+		if (bindings == null) {
+			return otherBindings == null;
+		}
+		if (otherBindings == null) {
+			return false;
+		}
+		int length = bindings.length;
+		int otherLength = otherBindings.length;
+		if (length != otherLength) {
+			return false;
+		}
+		for (int i = 0; i < length; i++) {
+			if (!isEqual(bindings[i], otherBindings[i], visitedTypes)) {
+				return false;
+			}
+		}
+		return true;
+	}
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2, HashSet visitedTypes) {
+		if (typeBinding == typeBinding2)
+			return true;
+		if (typeBinding == null || typeBinding2 == null)
+			return false;
+
+		switch (typeBinding.kind()) {
+			case Binding.BASE_TYPE :
+				if (!typeBinding2.isBaseType()) {
+					return false;
+				}
+				return typeBinding.id == typeBinding2.id;
+
+			case Binding.ARRAY_TYPE :
+				if (!typeBinding2.isArrayType()) {
+					return false;
+				}
+				return typeBinding.dimensions() == typeBinding2.dimensions()
+						&& isEqual(typeBinding.leafComponentType(), typeBinding2.leafComponentType(), visitedTypes);
+
+			case Binding.PARAMETERIZED_TYPE :
+				if (!typeBinding2.isParameterizedType()) {
+					return false;
+				}
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding;
+				ParameterizedTypeBinding parameterizedTypeBinding2 = (ParameterizedTypeBinding) typeBinding2;
+				return CharOperation.equals(parameterizedTypeBinding.compoundName, parameterizedTypeBinding2.compoundName)
+					&& (parameterizedTypeBinding.modifiers & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+							== (parameterizedTypeBinding2.modifiers & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+					&& isEqual(parameterizedTypeBinding.arguments, parameterizedTypeBinding2.arguments, visitedTypes)
+					&& isEqual(parameterizedTypeBinding.enclosingType(), parameterizedTypeBinding2.enclosingType(), visitedTypes);
+
+			case Binding.WILDCARD_TYPE :
+				if (typeBinding2.kind() != Binding.WILDCARD_TYPE) {
+					return false;
+				}
+				WildcardBinding wildcardBinding = (WildcardBinding) typeBinding;
+				WildcardBinding wildcardBinding2 = (WildcardBinding) typeBinding2;
+				return isEqual(wildcardBinding.bound, wildcardBinding2.bound, visitedTypes)
+					&& wildcardBinding.boundKind == wildcardBinding2.boundKind;
+
+			case Binding.INTERSECTION_TYPE:
+				if (typeBinding2.kind() != Binding.INTERSECTION_TYPE) {
+					return false;
+				}
+				WildcardBinding intersectionBinding = (WildcardBinding) typeBinding;
+				WildcardBinding intersectionBinding2 = (WildcardBinding) typeBinding2;
+				return isEqual(intersectionBinding.bound, intersectionBinding2.bound, visitedTypes)
+					&& isEqual(intersectionBinding.otherBounds, intersectionBinding2.otherBounds, visitedTypes);
+
+			case Binding.TYPE_PARAMETER :
+				if (!(typeBinding2.isTypeVariable())) {
+					return false;
+				}
+				if (typeBinding.isCapture()) {
+					if (!(typeBinding2.isCapture())) {
+						return false;
+					}
+					CaptureBinding captureBinding = (CaptureBinding) typeBinding;
+					CaptureBinding captureBinding2 = (CaptureBinding) typeBinding2;
+					if (captureBinding.position == captureBinding2.position) {
+						if (visitedTypes.contains(typeBinding)) return true;
+						visitedTypes.add(typeBinding);
+
+						return isEqual(captureBinding.wildcard, captureBinding2.wildcard, visitedTypes)
+							&& isEqual(captureBinding.sourceType, captureBinding2.sourceType, visitedTypes);
+					}
+					return false;
+				}
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding;
+				TypeVariableBinding typeVariableBinding2 = (TypeVariableBinding) typeBinding2;
+				if (CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)) {
+					if (visitedTypes.contains(typeBinding)) return true;
+					visitedTypes.add(typeBinding);
+
+					return isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, visitedTypes)
+					&& isEqual(typeVariableBinding.superclass(), typeVariableBinding2.superclass(), visitedTypes)
+					&& isEqual(typeVariableBinding.superInterfaces(), typeVariableBinding2.superInterfaces(), visitedTypes);
+				}
+				return false;
+			case Binding.GENERIC_TYPE :
+				if (!typeBinding2.isGenericType()) {
+					return false;
+				}
+				ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
+				ReferenceBinding referenceBinding2 = (ReferenceBinding) typeBinding2;
+				return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
+					&& (referenceBinding.modifiers & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+							== (referenceBinding2.modifiers & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+					&& isEqual(referenceBinding.typeVariables(), referenceBinding2.typeVariables(), visitedTypes)
+					&& isEqual(referenceBinding.enclosingType(), referenceBinding2.enclosingType(), visitedTypes);
+
+			case Binding.RAW_TYPE :
+			default :
+				if (!(typeBinding2 instanceof ReferenceBinding)) {
+					return false;
+				}
+				referenceBinding = (ReferenceBinding) typeBinding;
+				referenceBinding2 = (ReferenceBinding) typeBinding2;
+				char[] constantPoolName = referenceBinding.constantPoolName();
+				char[] constantPoolName2 = referenceBinding2.constantPoolName();
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=116833
+				if (constantPoolName == null) {
+					if (constantPoolName2 != null) {
+						return false;
+					}
+					if (!CharOperation.equals(referenceBinding.computeUniqueKey(), referenceBinding2.computeUniqueKey())) {
+						return false;
+					}
+				} else {
+					if (constantPoolName2 == null) {
+						return false;
+					}
+					if (!CharOperation.equals(constantPoolName, constantPoolName2)) {
+						return false;
+					}
+				}
+				return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
+					&& (!referenceBinding2.isGenericType())
+					&& (referenceBinding.isRawType() == referenceBinding2.isRawType())
+					&& ((referenceBinding.modifiers & ~ClassFileConstants.AccSuper) & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+							== ((referenceBinding2.modifiers & ~ClassFileConstants.AccSuper) & (ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation))
+					&& isEqual(referenceBinding.enclosingType(), referenceBinding2.enclosingType(), visitedTypes);
+		}
+	}
+	/**
+	 * @param typeBinding
+	 * @param typeBinding2
+	 * @return true if both parameters are equals, false otherwise
+	 */
+	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2) {
+		return isEqual(typeBinding, typeBinding2, new HashSet());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
new file mode 100644
index 0000000..de79a4c
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
@@ -0,0 +1,1052 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+
+/**
+ * A binding resolver is an internal mechanism for figuring out the binding
+ * for a major declaration, type, or name reference. This also handles
+ * the creation and mapping between annotations and the ast nodes that define them.
+ * <p>
+ * The default implementation serves as the default binding resolver
+ * that does no resolving whatsoever. Internal subclasses do all the real work.
+ * </p>
+ *
+ * @see AST#getBindingResolver
+ */
+class BindingResolver {
+
+	/**
+	 * Creates a binding resolver.
+	 */
+	BindingResolver() {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * Finds the corresponding AST node from which the given binding originated.
+	 * Returns <code>null</code> if the binding does not correspond to any node
+	 * in the compilation unit.
+	 * <p>
+	 * The following table indicates the expected node type for the various
+	 * different kinds of bindings:
+	 * <ul>
+	 * <li></li>
+	 * <li>package - a <code>PackageDeclaration</code></li>
+	 * <li>class or interface - a <code>TypeDeclaration</code> or a
+	 *    <code>ClassInstanceCreation</code> (for anonymous classes) </li>
+	 * <li>primitive type - none</li>
+	 * <li>array type - none</li>
+	 * <li>field - a <code>VariableDeclarationFragment</code> in a
+	 *    <code>FieldDeclaration</code> </li>
+	 * <li>local variable - a <code>SingleVariableDeclaration</code>, or
+	 *    a <code>VariableDeclarationFragment</code> in a
+	 *    <code>VariableDeclarationStatement</code> or
+	 *    <code>VariableDeclarationExpression</code></li>
+	 * <li>method - a <code>MethodDeclaration</code> </li>
+	 * <li>constructor - a <code>MethodDeclaration</code> </li>
+	 * <li>annotation type - an <code>AnnotationTypeDeclaration</code>
+	 * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * The implementation of <code>CompilationUnit.findDeclaringNode</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param binding the binding
+	 * @return the corresponding node where the bindings is declared,
+	 *    or <code>null</code> if none
+	 */
+	ASTNode findDeclaringNode(IBinding binding) {
+		return null;
+	}
+
+	/**
+	 * Finds the corresponding AST node from which the given binding key originated.
+	 *
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param bindingKey the binding key
+	 * @return the corresponding node where the bindings is declared,
+	 *    or <code>null</code> if none
+	 */
+	ASTNode findDeclaringNode(String bindingKey) {
+		return null;
+	}
+
+	/**
+	 * Finds the corresponding AST node from which the given annotation instance originated.
+	 *
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param instance the dom annotation
+	 * @return the corresponding node where the bindings is declared,
+	 *    or <code>null</code> if none
+	 */
+	ASTNode findDeclaringNode(IAnnotationBinding instance) {
+		return null;
+	}
+
+	/**
+	 * Allows the user to get information about the given old/new pair of
+	 * AST nodes.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param currentNode the new node
+	 * @return org.eclipse.jdt.internal.compiler.ast.ASTNode
+	 */
+	org.eclipse.jdt.internal.compiler.ast.ASTNode getCorrespondingNode(ASTNode currentNode) {
+		return null;
+	}
+
+	/**
+	 * Returns the new method binding corresponding to the given old method binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param methodBinding the old method binding
+	 * @return the new method binding
+	 */
+	IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) {
+		return null;
+	}
+
+	/**
+	 * Returns the new member value pair binding corresponding to the given old value pair binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param valuePair the old value pair binding
+	 * @return the new member value pair binding
+	 */
+	IMemberValuePairBinding getMemberValuePairBinding(ElementValuePair valuePair) {
+		return null;
+	}
+
+	/**
+	 * Returns the new package binding corresponding to the given old package binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param packageBinding the old package binding
+	 * @return the new package binding
+	 */
+	IPackageBinding getPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding) {
+		return null;
+	}
+
+	/**
+	 * Returns the new type binding corresponding to the given old type binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param referenceBinding the old type binding
+	 * @return the new type binding
+	 */
+	ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) {
+		return null;
+	}
+
+
+	/**
+	 * Returns the new type binding corresponding to the given variableDeclaration.
+	 * This is used for recovered binding only.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param variableDeclaration the given variable declaration
+	 * @return the new type binding
+	 */
+	ITypeBinding getTypeBinding(VariableDeclaration variableDeclaration) {
+		return null;
+	}
+
+	/**
+	 * Returns the new type binding corresponding to the given type. This is used for recovered binding
+	 * only.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the given type
+	 * @return the new type binding
+	 */
+	ITypeBinding getTypeBinding(Type type) {
+		return null;
+	}
+
+	/**
+	 * Returns the new type binding corresponding to the given recovered type binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param recoveredTypeBinding the recovered type binding
+	 * @param dimensions the dimensions to add the to given type binding dimensions
+	 * @return the new type binding
+	 */
+	ITypeBinding getTypeBinding(RecoveredTypeBinding recoveredTypeBinding, int dimensions) {
+		return null;
+	}
+
+	/**
+	 * Returns the new variable binding corresponding to the given old variable binding.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param binding the old variable binding
+	 * @return the new variable binding
+	 */
+	IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding binding) {
+		return null;
+	}
+
+	/**
+	 * Return the working copy owner for the receiver.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * @return the working copy owner for the receiver
+	 */
+	public WorkingCopyOwner getWorkingCopyOwner() {
+		return null;
+	}
+
+	/**
+	 * Return the new annotation corresponding to the given old annotation
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param instance the old annotation
+	 * @return the new DOM annotation
+	 */
+	IAnnotationBinding getAnnotationInstance(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding instance) {
+		return null;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(MethodInvocation methodInvocation) {
+		return false;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(SuperMethodInvocation methodInvocation) {
+		return false;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(ClassInstanceCreation classInstanceCreation) {
+		return false;
+	}
+	
+	/**
+	 * Returns the compiler lookup environment used by this binding resolver.
+	 * Returns <code>null</code> if none.
+	 *
+	 * @return the lookup environment used by this resolver, or <code>null</code> if none.
+	 */
+	LookupEnvironment lookupEnvironment() {
+		return null;
+	}
+
+	/**
+	 * This method is used to record the scope and its corresponding node.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * @param astNode
+	 */
+	void recordScope(ASTNode astNode, BlockScope blockScope) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * Returns whether this expression node is the site of a boxing
+	 * conversion (JLS3 5.1.7). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if this expression is the site of a
+	 * boxing conversion, or <code>false</code> if either no boxing conversion
+	 * is involved or if bindings were not requested when the AST was created
+	 * @since 3.1
+	 */
+	boolean resolveBoxing(Expression expression) {
+		return false;
+	}
+
+	/**
+	 * Returns whether this expression node is the site of an unboxing
+	 * conversion (JLS3 5.1.8). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if this expression is the site of an
+	 * unboxing conversion, or <code>false</code> if either no unboxing
+	 * conversion is involved or if bindings were not requested when the
+	 * AST was created
+	 * @since 3.1
+	 */
+	boolean resolveUnboxing(Expression expression) {
+		return false;
+	}
+
+	/**
+	 * Resolves and returns the compile-time constant expression value as
+	 * specified in JLS2 15.28, if this expression has one. Constant expression
+	 * values are unavailable unless bindings are requested when the AST is
+	 * being built. If the type of the value is a primitive type, the result
+	 * is the boxed equivalent (i.e., int returned as an <code>Integer</code>);
+	 * if the type of the value is <code>String</code>, the result is the string
+	 * itself. If the expression does not have a compile-time constant expression
+	 * value, the result is <code>null</code>.
+	 * <p>
+	 * Resolving constant expressions takes into account the value of simple
+	 * and qualified names that refer to constant variables (JLS2 4.12.4).
+	 * </p>
+	 * <p>
+	 * Note 1: enum constants are not considered constant expressions either.
+	 * The result is always <code>null</code> for these.
+	 * </p>
+	 * <p>
+	 * Note 2: Compile-time constant expressions cannot denote <code>null</code>.
+	 * So technically {@link NullLiteral} nodes are not constant expressions.
+	 * The result is <code>null</code> for these nonetheless.
+	 * </p>
+	 *
+	 * @return the constant expression value, or <code>null</code> if this
+	 * expression has no constant expression value or if bindings were not
+	 * requested when the AST was created
+	 * @since 3.1
+	 */
+	Object resolveConstantExpressionValue(Expression expression) {
+		return null;
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ClassInstanceCreation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
+		return null;
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(ConstructorInvocation expression) {
+		return null;
+	}
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param enumConstantDeclaration the enum constant declaration of interest
+	 * @return the binding for the constructor being invoked, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(EnumConstantDeclaration enumConstantDeclaration) {
+		return null;
+	}
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>SuperConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(SuperConstructorInvocation expression) {
+		return null;
+	}
+	/**
+	 * Resolves the type of the given expression and returns the type binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>Expression.resolveTypeBinding</code>
+	 * forwards to this method. The result is often a function of the context
+	 * in which the expression node is embedded as well as the expression
+	 * subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param expression the expression whose type is of interest
+	 * @return the binding for the type of the given expression, or
+	 *    <code>null</code> if no binding is available
+	 */
+	ITypeBinding resolveExpressionType(Expression expression) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given field access and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>FieldAccess.resolveFieldBinding</code>
+	 * forwards to this method. How the field resolves is often a function of
+	 * the context in which the field access node is embedded as well as
+	 * the field access subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param fieldAccess the field access of interest
+	 * @return the binding for the given field access, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveField(FieldAccess fieldAccess) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given super field access and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>SuperFieldAccess.resolveFieldBinding</code>
+	 * forwards to this method. How the field resolves is often a function of
+	 * the context in which the super field access node is embedded as well as
+	 * the super field access subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param fieldAccess the super field access of interest
+	 * @return the binding for the given field access, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given import declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>ImportDeclaration.resolveBinding</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param importDeclaration the import declaration of interest
+	 * @return the binding for the given package declaration, or
+	 *         the package binding (for on-demand imports) or type binding
+	 *         (for single-type imports), or <code>null</code> if no binding is
+	 *         available
+	 */
+	IBinding resolveImport(ImportDeclaration importDeclaration) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given annotation type declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnnotationTypeMemberDeclaration.resolveBinding</code>
+	 * forwards to this method. How the declaration resolves is often a
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param member the annotation type member declaration of interest
+	 * @return the binding for the given annotation type member declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	IMethodBinding resolveMember(AnnotationTypeMemberDeclaration member) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given method declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodDeclaration.resolveBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method declaration node is embedded as well as
+	 * the method declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param method the method or constructor declaration of interest
+	 * @return the binding for the given method declaration, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(MethodDeclaration method) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given  method reference and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodReference.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method reference node is embedded as well as
+	 * the method reference subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param methodReference the  method reference of interest
+	 * @return the binding for the given  method reference, or
+	 *    <code>null</code> if no binding is available
+	 * @since 3.9 BETA_JAVA8
+	 */
+	IMethodBinding resolveMethod(MethodReference methodReference) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given Lambda Expression and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>LambdaExpression.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method declaration node is embedded as well as
+	 * the method declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may re-implement.
+	 * </p>
+	 *
+	 * @param lambda LambdaExpression of interest
+	 * @return the binding for the given lambda expression, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(LambdaExpression lambda) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given method invocation and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method invocation node is embedded as well as
+	 * the method invocation subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param method the method invocation of interest
+	 * @return the binding for the given method invocation, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(MethodInvocation method) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given method invocation and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method invocation node is embedded as well as
+	 * the method invocation subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param method the method invocation of interest
+	 * @return the binding for the given method invocation, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(SuperMethodInvocation method) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given name and returns the type binding for it.
+	 * <p>
+	 * The implementation of <code>Name.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param name the name of interest
+	 * @return the binding for the name, or <code>null</code> if no binding is
+	 *    available
+	 */
+	IBinding resolveName(Name name) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given package declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>PackageDeclaration.resolveBinding</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param pkg the package declaration of interest
+	 * @return the binding for the given package declaration, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IPackageBinding resolvePackage(PackageDeclaration pkg) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given reference and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MemberRef.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param ref the reference of interest
+	 * @return the binding for the reference, or <code>null</code> if no binding is
+	 *    available
+	 * @since 3.0
+	 */
+	IBinding resolveReference(MemberRef ref) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given member value pair and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MemberValuePair.resolveMemberValuePairBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param memberValuePair the member value pair of interest
+	 * @return the binding for the member value pair, or <code>null</code> if no binding is
+	 *    available
+	 * @since 3.2
+	 */
+	IMemberValuePairBinding resolveMemberValuePair(MemberValuePair memberValuePair) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given reference and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodRef.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param ref the reference of interest
+	 * @return the binding for the reference, or <code>null</code> if no binding is
+	 *    available
+	 * @since 3.0
+	 */
+	IBinding resolveReference(MethodRef ref) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given annotation type declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnnotationTypeDeclaration.resolveBinding</code>
+	 * forwards to this method. How the declaration resolves is often a
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the annotation type declaration of interest
+	 * @return the binding for the given annotation type declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	ITypeBinding resolveType(AnnotationTypeDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given anonymous class declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnonymousClassDeclaration.resolveBinding</code>
+	 * forwards to this method. How the declaration resolves is often a
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the anonymous class declaration of interest
+	 * @return the binding for the given class declaration, or <code>null</code>
+	 *    if no binding is available
+	 */
+	ITypeBinding resolveType(AnonymousClassDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given enum declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>EnumDeclaration.resolveBinding</code>
+	 * forwards to this method. How the enum declaration resolves is often
+	 * a function of the context in which the declaration node is embedded
+	 * as well as the enum declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the enum declaration of interest
+	 * @return the binding for the given enum declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	ITypeBinding resolveType(EnumDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given type and returns the type binding for it.
+	 * <p>
+	 * The implementation of <code>Type.resolveBinding</code>
+	 * forwards to this method. How the type resolves is often a function
+	 * of the context in which the type node is embedded as well as the type
+	 * subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the type of interest
+	 * @return the binding for the given type, or <code>null</code>
+	 *    if no binding is available
+	 */
+	ITypeBinding resolveType(Type type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given class or interface declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>TypeDeclaration.resolveBinding</code>
+	 * (and <code>TypeDeclarationStatement.resolveBinding</code>) forwards
+	 * to this method. How the type declaration resolves is often a function of
+	 * the context in which the type declaration node is embedded as well as the
+	 * type declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the class or interface declaration of interest
+	 * @return the binding for the given type declaration, or <code>null</code>
+	 *    if no binding is available
+	 */
+	ITypeBinding resolveType(TypeDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given type parameter and returns the type binding for the
+	 * type parameter.
+	 * <p>
+	 * The implementation of <code>TypeParameter.resolveBinding</code>
+	 * forwards to this method. How the declaration resolves is often a
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param typeParameter the type paramter of interest
+	 * @return the binding for the given type parameter, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.1
+	 */
+	ITypeBinding resolveTypeParameter(TypeParameter typeParameter) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given enum constant declaration and returns the binding for
+	 * the field.
+	 * <p>
+	 * The implementation of <code>EnumConstantDeclaration.resolveVariable</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param enumConstant the enum constant declaration of interest
+	 * @return the field binding for the given enum constant declaration, or
+	 *    <code>null</code> if no binding is available
+	 * @since 3.0
+	 */
+	IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given variable declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>VariableDeclaration.resolveBinding</code>
+	 * forwards to this method. How the variable declaration resolves is often
+	 * a function of the context in which the variable declaration node is
+	 * embedded as well as the variable declaration subtree itself. VariableDeclaration
+	 * declarations used as local variable, formal parameter and exception
+	 * variables resolve to local variable bindings; variable declarations
+	 * used to declare fields resolve to field bindings.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param variable the variable declaration of interest
+	 * @return the binding for the given variable declaration, or
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveVariable(VariableDeclaration variable) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given well known type by name and returns the type binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AST.resolveWellKnownType</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param name the name of a well known type
+	 * @return the corresponding type binding, or <code>null<code> if the
+	 *   named type is not considered well known or if no binding can be found
+	 *   for it
+	 */
+	ITypeBinding resolveWellKnownType(String name) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given annotation instance and returns the DOM representation for it.
+	 * <p>
+	 * The implementation of {@link Annotation#resolveAnnotationBinding()}
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param annotation the annotation ast node of interest
+	 * @return the DOM annotation representation for the given ast node, or
+	 *    <code>null</code> if none is available
+	 */
+	IAnnotationBinding resolveAnnotation(Annotation annotation) {
+		return null;
+	}
+
+	/**
+	 * Answer an array type binding with the given type binding and the given
+	 * dimensions.
+	 *
+	 * <p>If the given type binding is an array binding, then the resulting dimensions is the given dimensions
+	 * plus the existing dimensions of the array binding. Otherwise the resulting dimensions is the given
+	 * dimensions.</p>
+	 *
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param typeBinding the given type binding
+	 * @param dimensions the given dimensions
+	 * @return an array type binding with the given type binding and the given
+	 * dimensions
+	 * @throws IllegalArgumentException if the type binding represents the <code>void</code> type binding
+	 */
+	ITypeBinding resolveArrayType(ITypeBinding typeBinding, int dimensions) {
+		return null;
+	}
+
+	/**
+	 * Returns the compilation unit scope used by this binding resolver.
+	 * Returns <code>null</code> if none.
+	 *
+	 * @return the compilation unit scope by this resolver, or <code>null</code> if none.
+	 */
+	public CompilationUnitScope scope() {
+		return null;
+	}
+
+	/**
+	 * Allows the user to store information about the given old/new pair of
+	 * AST nodes.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param newNode the new AST node
+	 * @param oldASTNode the old AST node
+	 */
+	void store(ASTNode newNode, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * Allows the user to update information about the given old/new pair of
+	 * AST nodes.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the old AST node
+	 * @param newNode the new AST node
+	 */
+	void updateKey(ASTNode node, ASTNode newNode) {
+		// default implementation: do nothing
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java
new file mode 100644
index 0000000..2c13e89
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Block statement AST node type.
+ *
+ * <pre>
+ * Block:
+ *    <b>{</b> { Statement } <b>}</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class Block extends Statement {
+
+	/**
+	 * The "statements" structural property of this node type (element type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor STATEMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(Block.class, "statements", Statement.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(Block.class, properyList);
+		addProperty(STATEMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The list of statements (element type: {@link Statement}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList statements =
+		new ASTNode.NodeList(STATEMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented block node owned by the given AST.
+	 * By default, the block is empty.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Block(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == STATEMENTS_PROPERTY) {
+			return statements();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return BLOCK;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		Block result = new Block(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.statements().addAll(
+			ASTNode.copySubtrees(target, statements()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChildren(visitor, this.statements);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live list of statements in this block. Adding and
+	 * removing nodes from this list affects this node dynamically.
+	 * All nodes in this list must be <code>Statement</code>s;
+	 * attempts to add any other type of node will trigger an
+	 * exception.
+	 *
+	 * @return the live list of statements in this block
+	 *    (element type: {@link Statement})
+	 */
+	public List statements() {
+		return this.statements;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize() + this.statements.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java
new file mode 100644
index 0000000..72534c6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Block comment AST node type.
+ * <p>
+ * Block comments (also called "traditional" comments in JLS 3.7)
+ * begin with "/&#42;", may contain line breaks, and must end
+ * with "&#42;/". Following the definition in the JLS (first edition
+ * but not second edition), block comment normally exclude comments
+ * that begin with "/&#42;#42;", which are instead classified as doc
+ * comments ({@link Javadoc}).
+ * </p>
+ * <p>
+ * Note that this node type is a comment placeholder, and is
+ * only useful for recording the source range where a comment
+ * was found in a source string. It is not useful for creating
+ * comments.
+ * </p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class BlockComment extends Comment {
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(1);
+		createPropertyList(BlockComment.class, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new block comment node owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	BlockComment(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return BLOCK_COMMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		BlockComment result = new BlockComment(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java
new file mode 100644
index 0000000..a1951e2
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Abstract base class of all AST nodes that represent body declarations
+ * that may appear in the body of some kind of class or interface declaration,
+ * including anonymous class declarations, enumeration declarations, and
+ * enumeration constant declarations.
+ * <p>
+ * <pre>
+ * BodyDeclaration:
+ * 		{@link AbstractTypeDeclaration}
+ * 			{@link AnnotationTypeDeclaration}
+ * 			{@link EnumDeclaration}
+ * 			{@link TypeDeclaration} (for classes and interfaces)
+ *		{@link AnnotationTypeMemberDeclaration}
+ *		{@link EnumConstantDeclaration}
+ * 		{@link FieldDeclaration}
+ * 		{@link Initializer}
+ *		{@link MethodDeclaration} (for methods and constructors)
+ * </pre>
+ * </p>
+ * <p>
+ * All types of body declarations carry modifiers (and annotations), although they differ in
+ * which modifiers are allowed. Most types of body declarations can carry a
+ * doc comment; Initializer is the only ones that does not. The source range
+ * for body declarations always includes the doc comment if present.
+ * </p>
+ *
+ * @since 2.0
+ */
+public abstract class BodyDeclaration extends ASTNode {
+
+	/**
+	 * The doc comment, or <code>null</code> if none.
+	 * Defaults to none.
+	 */
+	Javadoc optionalDocComment = null;
+
+	/**
+	 * The modifier flags; bit-wise or of Modifier flags.
+	 * Defaults to none. Not used in 3.0.
+	 * @since 3.0 - field was moved up from subclasses
+	 */
+	private int modifierFlags = Modifier.NONE;
+
+	/**
+	 * The extended modifiers (element type: {@link IExtendedModifier}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 *
+	 * @since 3.0
+	 */
+	ASTNode.NodeList modifiers = null;
+
+	/**
+	 * Returns structural property descriptor for the "modifiers" property
+	 * of this node as used in JLS2 (type: {@link Integer}).
+	 *
+	 * @return the property descriptor
+	 * @deprecated In the JLS3 API, this method is replaced by {@link #internalModifiers2Property()}.
+	 */
+	abstract SimplePropertyDescriptor internalModifiersProperty();
+
+	/**
+	 * Returns structural property descriptor for the "modifiers" property
+	 * of this node as used in JLS3 (element type: {@link IExtendedModifier}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildListPropertyDescriptor internalModifiers2Property();
+
+	/**
+	 * Returns structural property descriptor for the "modifiers" property
+	 * of this node as used in JLS3 (element type: {@link IExtendedModifier}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildListPropertyDescriptor getModifiersProperty() {
+		// important: return property for AST.JLS3
+		return internalModifiers2Property();
+	}
+
+	/**
+	 * Returns structural property descriptor for the "javadoc" property
+	 * of this node (child type: {@link Javadoc}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildPropertyDescriptor internalJavadocProperty();
+
+	/**
+	 * Returns structural property descriptor for the "javadoc" property
+	 * of this node (child type: {@link Javadoc}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildPropertyDescriptor getJavadocProperty() {
+		return internalJavadocProperty();
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "javadoc" property declared on the given concrete node type (child type: {@link Javadoc}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildPropertyDescriptor internalJavadocPropertyFactory(Class nodeClass) {
+		return new ChildPropertyDescriptor(nodeClass, "javadoc", Javadoc.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "modifiers" property declared on the given concrete node type (type: {@link Integer}).
+	 *
+	 * @return the property descriptor
+	 * @deprecated In the JLS3 API, this method is replaced by {@link #internalModifiers2PropertyFactory(Class)}.
+	 */
+	static final SimplePropertyDescriptor internalModifiersPropertyFactory(Class nodeClass) {
+		return new SimplePropertyDescriptor(nodeClass, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "modifiers" property declared on the given concrete node type (element type: {@link IExtendedModifier}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildListPropertyDescriptor internalModifiers2PropertyFactory(Class nodeClass) {
+		return new ChildListPropertyDescriptor(nodeClass, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates a new AST node for a body declaration node owned by the
+	 * given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	BodyDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.modifiers = new ASTNode.NodeList(internalModifiers2Property());
+		}
+	}
+
+	/**
+	 * Returns the doc comment node.
+	 *
+	 * @return the doc comment node, or <code>null</code> if none
+	 */
+	public Javadoc getJavadoc() {
+		return this.optionalDocComment;
+	}
+
+	/**
+	 * Sets or clears the doc comment node.
+	 *
+	 * @param docComment the doc comment node, or <code>null</code> if none
+	 * @exception IllegalArgumentException if the doc comment string is invalid
+	 */
+	public void setJavadoc(Javadoc docComment) {
+		ChildPropertyDescriptor p = internalJavadocProperty();
+		ASTNode oldChild = this.optionalDocComment;
+		preReplaceChild(oldChild, docComment, p);
+		this.optionalDocComment = docComment;
+		postReplaceChild(oldChild, docComment, p);
+	}
+
+	/**
+	 * Returns the modifiers explicitly specified on this declaration.
+	 * <p>
+	 * In the JLS3 API, this method is a convenience method that
+	 * computes these flags from {@link #modifiers()}.
+	 * </p>
+	 *
+	 * @return the bit-wise "or" of <code>Modifier</code> constants
+	 * @see Modifier
+	 */
+	public int getModifiers() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.modifiers == null) {
+			// JLS2 behavior - bona fide property
+			return this.modifierFlags;
+		} else {
+			// JLS3 behavior - convenience method
+			// performance could be improved by caching computed flags
+			// but this would require tracking changes to this.modifiers
+			int computedmodifierFlags = Modifier.NONE;
+			for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
+				Object x = it.next();
+				if (x instanceof Modifier) {
+					computedmodifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
+				}
+			}
+			return computedmodifierFlags;
+		}
+	}
+
+	/**
+	 * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
+	 *
+	 * @param modifiers the given modifiers (bit-wise "or" of {@link Modifier} constants)
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #modifiers()}, which contains a list of {@link Modifier} nodes.
+	 */
+	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
+		// more efficient than just calling supportedOnlyIn2() to check
+		if (this.modifiers != null) {
+			supportedOnlyIn2();
+		}
+		SimplePropertyDescriptor p = internalModifiersProperty();
+		preValueChange(p);
+		this.modifierFlags = pmodifiers;
+		postValueChange(p);
+	}
+
+	/**
+	 * Returns the live ordered list of modifiers and annotations
+	 * of this declaration (added in JLS3 API).
+	 *
+	 * @return the live list of modifiers and annotations
+	 *    (element type: {@link IExtendedModifier})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List modifiers() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		return this.modifiers;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java
new file mode 100644
index 0000000..c360297
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Boolean literal node.
+ *
+ * <pre>
+ * BooleanLiteral:
+ * 		<b>true</b>
+ * 		<b>false</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class BooleanLiteral extends Expression {
+
+	/**
+	 * The "booleanValue" structural property of this node type (type: {@link Boolean}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor BOOLEAN_VALUE_PROPERTY =
+		new SimplePropertyDescriptor(BooleanLiteral.class, "booleanValue", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(BooleanLiteral.class, properyList);
+		addProperty(BOOLEAN_VALUE_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The boolean; defaults to the literal for <code>false</code>.
+	 */
+	private boolean value = false;
+
+	/**
+	 * Creates a new unparented boolean literal node owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	BooleanLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean newValue) {
+		if (property == BOOLEAN_VALUE_PROPERTY) {
+			if (get) {
+				return booleanValue();
+			} else {
+				setBooleanValue(newValue);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, newValue);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return BOOLEAN_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		BooleanLiteral result = new BooleanLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setBooleanValue(booleanValue());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the boolean value of this boolean literal node.
+	 *
+	 * @return <code>true</code> for the boolean literal spelled
+	 *    <code>"true"</code>, and <code>false</code> for the boolean literal
+	 *    spelled <code>"false"</code>.
+	 */
+	public boolean booleanValue() {
+		return this.value;
+	}
+
+	/**
+	 * Sets the boolean value of this boolean literal node.
+	 *
+	 * @param value <code>true</code> for the boolean literal spelled
+	 *    <code>"true"</code>, and <code>false</code> for the boolean literal
+	 *    spelled <code>"false"</code>.
+	 */
+	public void setBooleanValue(boolean value) {
+		preValueChange(BOOLEAN_VALUE_PROPERTY);
+		this.value = value;
+		postValueChange(BOOLEAN_VALUE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
new file mode 100644
index 0000000..1b0e2f4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Break statement AST node type.
+ *
+ * <pre>
+ * BreakStatement:
+ *    <b>break</b> [ Identifier ] <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class BreakStatement extends Statement {
+
+	/**
+	 * The "label" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LABEL_PROPERTY =
+		new ChildPropertyDescriptor(BreakStatement.class, "label", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(BreakStatement.class, properyList);
+		addProperty(LABEL_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The label, or <code>null</code> if none; none by default.
+	 */
+	private SimpleName optionalLabel = null;
+
+	/**
+	 * Creates a new unparented break statement node owned by the given
+	 * AST. By default, the break statement has no label.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	BreakStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LABEL_PROPERTY) {
+			if (get) {
+				return getLabel();
+			} else {
+				setLabel((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return BREAK_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		BreakStatement result = new BreakStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setLabel((SimpleName) ASTNode.copySubtree(target, getLabel()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getLabel());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the label of this break statement, or <code>null</code> if
+	 * there is none.
+	 *
+	 * @return the label, or <code>null</code> if there is none
+	 */
+	public SimpleName getLabel() {
+		return this.optionalLabel;
+	}
+
+	/**
+	 * Sets or clears the label of this break statement.
+	 *
+	 * @param label the label, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setLabel(SimpleName label) {
+		ASTNode oldChild = this.optionalLabel;
+		preReplaceChild(oldChild, label, LABEL_PROPERTY);
+		this.optionalLabel = label;
+		postReplaceChild(oldChild, label, LABEL_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalLabel == null ? 0 : getLabel().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java
new file mode 100644
index 0000000..a11e0e0
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Cast expression AST node type.
+ *
+ * <pre>
+ * CastExpression:
+ *    <b>(</b> Type <b>)</b> Expression
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CastExpression extends Expression {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(CastExpression.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(CastExpression.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(CastExpression.class, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The type; lazily initialized; defaults to a unspecified,
+	 * legal type.
+	 */
+	private Type type = null;
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * Creates a new AST node for a cast expression owned by the given
+	 * AST. By default, the type and expression are unspecified (but legal).
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	CastExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CAST_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		CastExpression result = new CastExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) getType().clone(target));
+		result.setExpression((Expression) getExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type in this cast expression.
+	 *
+	 * @return the type
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type in this cast expression to the given type.
+	 *
+	 * @param type the new type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the expression of this cast expression.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this cast expression.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.type == null ? 0 : getType().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java
new file mode 100644
index 0000000..c5ecb45
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Catch clause AST node type.
+ *
+ * <pre>
+ * CatchClause:
+ *    <b>catch</b> <b>(</b> FormalParameter <b>)</b> Block
+ * </pre>
+ *
+ * <p>The FormalParameter is represented by a {@link SingleVariableDeclaration}.</p>
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CatchClause extends ASTNode {
+
+	/**
+	 * The "exception" structural property of this node type (child type: {@link SingleVariableDeclaration}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXCEPTION_PROPERTY =
+		new ChildPropertyDescriptor(CatchClause.class, "exception", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(CatchClause.class, "body", Block.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(CatchClause.class, properyList);
+		addProperty(EXCEPTION_PROPERTY, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The body; lazily initialized; defaults to an empty block.
+	 */
+	private Block body = null;
+
+	/**
+	 * The exception variable declaration; lazily initialized; defaults to a
+	 * unspecified, but legal, variable declaration.
+	 */
+	private SingleVariableDeclaration exceptionDecl = null;
+
+	/**
+	 * Creates a new AST node for a catch clause owned by the given
+	 * AST. By default, the catch clause declares an unspecified, but legal,
+	 * exception declaration and has an empty block.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	CatchClause(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXCEPTION_PROPERTY) {
+			if (get) {
+				return getException();
+			} else {
+				setException((SingleVariableDeclaration) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Block) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CATCH_CLAUSE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		CatchClause result = new CatchClause(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setBody((Block) getBody().clone(target));
+		result.setException(
+			(SingleVariableDeclaration) ASTNode.copySubtree(target, getException()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getException());
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the exception variable declaration of this catch clause.
+	 *
+	 * @return the exception variable declaration node
+	 */
+	public SingleVariableDeclaration getException() {
+		if (this.exceptionDecl == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.exceptionDecl == null) {
+					preLazyInit();
+					this.exceptionDecl = new SingleVariableDeclaration(this.ast);
+					postLazyInit(this.exceptionDecl, EXCEPTION_PROPERTY);
+				}
+			}
+		}
+		return this.exceptionDecl;
+	}
+
+	/**
+	 * Sets the variable declaration of this catch clause.
+	 *
+	 * @param exception the exception variable declaration node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setException(SingleVariableDeclaration exception) {
+		if (exception == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.exceptionDecl;
+		preReplaceChild(oldChild, exception, EXCEPTION_PROPERTY);
+		this.exceptionDecl= exception;
+		postReplaceChild(oldChild, exception, EXCEPTION_PROPERTY);
+	}
+
+	/**
+	 * Returns the body of this catch clause.
+	 *
+	 * @return the catch clause body
+	 */
+	public Block getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this catch clause.
+	 *
+	 * @param body the catch clause block node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Block body) {
+		if (body == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, body, BODY_PROPERTY);
+		this.body = body;
+		postReplaceChild(oldChild, body, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.exceptionDecl == null ? 0 : getException().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
new file mode 100644
index 0000000..a932a70
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Character literal nodes.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CharacterLiteral extends Expression {
+
+	/**
+	 * The "escapedValue" structural property of this node type (type: {@link String}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor ESCAPED_VALUE_PROPERTY =
+		new SimplePropertyDescriptor(CharacterLiteral.class, "escapedValue", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(CharacterLiteral.class, properyList);
+		addProperty(ESCAPED_VALUE_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The literal string, including quotes and escapes; defaults to the
+	 * literal for the character 'X'.
+	 */
+	private String escapedValue = "\'X\'";//$NON-NLS-1$
+
+	/**
+	 * Creates a new unparented character literal node owned by the given AST.
+	 * By default, the character literal denotes an unspecified character.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	CharacterLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == ESCAPED_VALUE_PROPERTY) {
+			if (get) {
+				return getEscapedValue();
+			} else {
+				setEscapedValue((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CHARACTER_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		CharacterLiteral result = new CharacterLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setEscapedValue(getEscapedValue());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the string value of this literal node. The value is the sequence
+	 * of characters that would appear in the source program, including
+	 * enclosing single quotes and embedded escapes.
+	 *
+	 * @return the escaped string value, including enclosing single quotes
+	 *    and embedded escapes
+	 */
+	public String getEscapedValue() {
+		return this.escapedValue;
+	}
+
+	/**
+	 * Sets the string value of this literal node. The value is the sequence
+	 * of characters that would appear in the source program, including
+	 * enclosing single quotes and embedded escapes. For example,
+	 * <ul>
+	 * <li><code>'a'</code> <code>setEscapedValue("\'a\'")</code></li>
+	 * <li><code>'\n'</code> <code>setEscapedValue("\'\\n\'")</code></li>
+	 * </ul>
+	 *
+	 * @param value the string value, including enclosing single quotes
+	 *    and embedded escapes
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setEscapedValue(String value) {
+		// check setInternalEscapedValue(String) if this method is changed
+		if (value == null) {
+			throw new IllegalArgumentException();
+		}
+		Scanner scanner = this.ast.scanner;
+		char[] source = value.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		try {
+			int tokenType = scanner.getNextToken();
+			switch(tokenType) {
+				case TerminalTokens.TokenNameCharacterLiteral:
+					break;
+				default:
+					throw new IllegalArgumentException();
+			}
+		} catch(InvalidInputException e) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = value;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setEscapedValue(String) that doesn't do any validation.
+	 */
+	void internalSetEscapedValue(String value) {
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = value;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
+	/**
+	 * Returns the value of this literal node.
+	 * <p>
+	 * For example,
+	 * <pre>
+	 * CharacterLiteral s;
+	 * s.setEscapedValue("\'x\'");
+	 * assert s.charValue() == 'x';
+	 * </pre>
+	 * </p>
+	 *
+	 * @return the character value without enclosing quotes and embedded
+	 *    escapes
+	 * @exception IllegalArgumentException if the literal value cannot be converted
+	 */
+	public char charValue() {
+		Scanner scanner = this.ast.scanner;
+		char[] source = this.escapedValue.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		int firstChar = scanner.getNextChar();
+		int secondChar = scanner.getNextChar();
+
+		if (firstChar == -1 || firstChar != '\'') {
+			throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+		}
+		char value = (char) secondChar;
+		int nextChar = scanner.getNextChar();
+		if (secondChar == '\\') {
+			if (nextChar == -1) {
+				throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+			}
+			switch(nextChar) {
+				case 'b' :
+					value = '\b';
+					break;
+				case 't' :
+					value = '\t';
+					break;
+				case 'n' :
+					value = '\n';
+					break;
+				case 'f' :
+					value = '\f';
+					break;
+				case 'r' :
+					value = '\r';
+					break;
+				case '\"':
+					value = '\"';
+					break;
+				case '\'':
+					value = '\'';
+					break;
+				case '\\':
+					value = '\\';
+					break;
+				default : //octal (well-formed: ended by a ' )
+					try {
+						if (ScannerHelper.isDigit((char) nextChar)) {
+							int number = ScannerHelper.getNumericValue((char) nextChar);
+							nextChar = scanner.getNextChar();
+							if (nextChar == -1) {
+								throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+							}
+							if (nextChar != '\'') {
+								if (!ScannerHelper.isDigit((char) nextChar)) {
+									throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+								}
+								number = (number * 8) + ScannerHelper.getNumericValue((char) nextChar);
+								nextChar = scanner.getNextChar();
+								if (nextChar == -1) {
+									throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+								}
+								if (nextChar != '\'') {
+									if (!ScannerHelper.isDigit((char) nextChar)) {
+										throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+									}
+									number = (number * 8) + ScannerHelper.getNumericValue((char) nextChar);
+								}
+							}
+							return (char) number;
+						} else {
+							throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+						}
+					} catch (InvalidInputException e) {
+						throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+					}
+			}
+			nextChar = scanner.getNextChar();
+			if (nextChar == -1) {
+				throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+			}
+		}
+		if (nextChar == -1 || nextChar != '\'') {
+			throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+		}
+		return value;
+	}
+	/**
+	 * Sets the value of this character literal node to the given character.
+	 * <p>
+	 * For example,
+	 * <pre>
+	 * CharacterLiteral s;
+	 * s.setCharValue('x');
+	 * assert s.charValue() == 'x';
+	 * assert s.getEscapedValue().equals("\'x\'");
+	 * </pre>
+	 * </p>
+	 *
+	 * @param value the character value
+	 */
+	public void setCharValue(char value) {
+		StringBuffer b = new StringBuffer(3);
+
+		b.append('\''); // opening delimiter
+		switch(value) {
+			case '\b' :
+				b.append("\\b"); //$NON-NLS-1$
+				break;
+			case '\t' :
+				b.append("\\t"); //$NON-NLS-1$
+				break;
+			case '\n' :
+				b.append("\\n"); //$NON-NLS-1$
+				break;
+			case '\f' :
+				b.append("\\f"); //$NON-NLS-1$
+				break;
+			case '\r' :
+				b.append("\\r"); //$NON-NLS-1$
+				break;
+			case '\"':
+				b.append("\\\""); //$NON-NLS-1$
+				break;
+			case '\'':
+				b.append("\\\'"); //$NON-NLS-1$
+				break;
+			case '\\':
+				b.append("\\\\"); //$NON-NLS-1$
+				break;
+			case '\0' :
+				b.append("\\0"); //$NON-NLS-1$
+				break;
+			case '\1' :
+				b.append("\\1"); //$NON-NLS-1$
+				break;
+			case '\2' :
+				b.append("\\2"); //$NON-NLS-1$
+				break;
+			case '\3' :
+				b.append("\\3"); //$NON-NLS-1$
+				break;
+			case '\4' :
+				b.append("\\4"); //$NON-NLS-1$
+				break;
+			case '\5' :
+				b.append("\\5"); //$NON-NLS-1$
+				break;
+			case '\6' :
+				b.append("\\6"); //$NON-NLS-1$
+				break;
+			case '\7' :
+				b.append("\\7"); //$NON-NLS-1$
+				break;
+			default:
+				b.append(value);
+		}
+		b.append('\''); // closing delimiter
+		setEscapedValue(b.toString());
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 1 * 4 + stringSize(this.escapedValue);
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java
new file mode 100644
index 0000000..d624efc
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Descriptor for a child list property of an AST node.
+ * A child list property is one whose value is a list of
+ * {@link ASTNode}.
+ *
+ * @see org.eclipse.jdt.core.dom.ASTNode#getStructuralProperty(StructuralPropertyDescriptor)
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class ChildListPropertyDescriptor extends StructuralPropertyDescriptor {
+
+	/**
+	 * Element type. For example, for a node type like
+	 * CompilationUnit, the "imports" property is ImportDeclaration.class.
+	 * <p>
+	 * Field is private, but marked package-visible for fast
+	 * access from ASTNode.
+	 * </p>
+	 */
+	final Class elementType;
+
+	/**
+	 * Indicates whether a cycle is possible.
+	 * <p>
+	 * Field is private, but marked package-visible for fast
+	 * access from ASTNode.
+	 * </p>
+	 */
+	final boolean cycleRisk;
+
+	/**
+	 * Creates a new child list property descriptor with the given property id.
+	 * Note that this constructor is declared package-private so that
+	 * property descriptors can only be created by the AST
+	 * implementation.
+	 *
+	 * @param nodeClass concrete AST node type that owns this property
+	 * @param propertyId the property id
+	 * @param elementType the element type of this property
+	 * @param cycleRisk <code>true</code> if this property is at
+	 * risk of cycles, and <code>false</code> if there is no worry about cycles
+	 */
+	ChildListPropertyDescriptor(Class nodeClass, String propertyId, Class elementType, boolean cycleRisk) {
+		super(nodeClass, propertyId);
+		if (elementType == null) {
+			throw new IllegalArgumentException();
+		}
+		this.elementType = elementType;
+		this.cycleRisk = cycleRisk;
+	}
+
+	/**
+	 * Returns the element type of this list property.
+	 * <p>
+	 * For example, for a node type like CompilationUnit,
+	 * the "imports" property returns <code>ImportDeclaration.class</code>.
+	 * </p>
+	 *
+	 * @return the element type of the property
+	 */
+	public final Class getElementType() {
+		return this.elementType;
+	}
+
+	/**
+	 * Returns whether this property is vulnerable to cycles.
+	 * <p>
+	 * A property is vulnerable to cycles if a node of the owning
+	 * type (that is, the type that owns this property) could legally
+	 * appear in the AST subtree below this property. For example,
+	 * the body property of a
+	 * {@link MethodDeclaration} node
+	 * admits a body which might include statement that embeds
+	 * another {@link MethodDeclaration} node.
+	 * On the other hand, the name property of a
+	 * MethodDeclaration node admits only names, and thereby excludes
+	 * another MethodDeclaration node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if cycles are possible,
+	 * and <code>false</code> if cycles are impossible
+	 */
+	public final boolean cycleRisk() {
+		return this.cycleRisk;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java
new file mode 100644
index 0000000..86c2566
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Descriptor for a child property of an AST node.
+ * A child property is one whose value is an
+ * {@link ASTNode}.
+ *
+ * @see org.eclipse.jdt.core.dom.ASTNode#getStructuralProperty(StructuralPropertyDescriptor)
+ * @see org.eclipse.jdt.core.dom.ASTNode#setStructuralProperty(StructuralPropertyDescriptor, Object)
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class ChildPropertyDescriptor extends StructuralPropertyDescriptor {
+
+	/**
+	 * Child type. For example, for a node type like
+	 * CompilationUnit, the "package" property is PackageDeclaration.class
+	 */
+	private final Class childClass;
+
+	/**
+	 * Indicates whether the child is mandatory. A child property is allowed
+	 * to be <code>null</code> only if it is not mandatory.
+	 */
+	private final boolean mandatory;
+
+	/**
+	 * Indicates whether a cycle is possible.
+	 * Field is private, but marked package-visible for fast
+	 * access from ASTNode.
+	 */
+	final boolean cycleRisk;
+
+	/**
+	 * Creates a new child property descriptor with the given property id.
+	 * Note that this constructor is declared package-private so that
+	 * property descriptors can only be created by the AST
+	 * implementation.
+	 *
+	 * @param nodeClass concrete AST node type that owns this property
+	 * @param propertyId the property id
+	 * @param childType the child type of this property
+	 * @param mandatory <code>true</code> if the property is mandatory,
+	 * and <code>false</code> if it is may be <code>null</code>
+	 * @param cycleRisk <code>true</code> if this property is at
+	 * risk of cycles, and <code>false</code> if there is no worry about cycles
+	 */
+	ChildPropertyDescriptor(Class nodeClass, String propertyId, Class childType, boolean mandatory, boolean cycleRisk) {
+		super(nodeClass, propertyId);
+		if (childType == null || !ASTNode.class.isAssignableFrom(childType)) {
+			throw new IllegalArgumentException();
+		}
+		this.childClass = childType;
+		this.mandatory = mandatory;
+		this.cycleRisk = cycleRisk;
+	}
+
+	/**
+	 * Returns the child type of this property.
+	 * <p>
+	 * For example, for a node type like CompilationUnit,
+	 * the "package" property returns <code>PackageDeclaration.class</code>.
+	 * </p>
+	 *
+	 * @return the child type of the property
+	 */
+	public final Class getChildType() {
+		return this.childClass;
+	}
+
+	/**
+	 * Returns whether this property is mandatory. A property value
+	 * is not allowed to be <code>null</code> if it is mandatory.
+	 *
+	 * @return <code>true</code> if the property is mandatory,
+	 * and <code>false</code> if it is may be <code>null</code>
+	 */
+	public final boolean isMandatory() {
+		return this.mandatory;
+	}
+
+	/**
+	 * Returns whether this property is vulnerable to cycles.
+	 * <p>
+	 * A property is vulnerable to cycles if a node of the owning
+	 * type (that is, the type that owns this property) could legally
+	 * appear in the AST subtree below this property. For example,
+	 * the body property of a
+	 * {@link MethodDeclaration} node
+	 * admits a body which might include statement that embeds
+	 * another {@link MethodDeclaration} node.
+	 * On the other hand, the name property of a
+	 * MethodDeclaration node admits only names, and thereby excludes
+	 * another MethodDeclaration node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if cycles are possible,
+	 * and <code>false</code> if cycles are impossible
+	 */
+	public final boolean cycleRisk() {
+		return this.cycleRisk;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
new file mode 100644
index 0000000..f6c6f9d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
@@ -0,0 +1,590 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class instance creation expression AST node type.
+ * <pre>
+ * ClassInstanceCreation:
+ *        [ Expression <b>.</b> ]
+ *            <b>new</b> [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *            Type <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
+ *            [ AnonymousClassDeclaration ]
+ * </pre>
+ * <p>
+ * Not all node arrangements will represent legal Java constructs. In particular,
+ * it is nonsense if the type is a primitive type or an array type (primitive
+ * types cannot be instantiated, and array creations must be represented with
+ * <code>ArrayCreation</code> nodes). The normal use is when the type is a
+ * simple, qualified, or parameterized type.
+ * </p>
+ * <p>
+ * A type like "A.B" can be represented either of two ways:
+ * <ol>
+ * <li>
+ * <code>QualifiedType(SimpleType(SimpleName("A")),SimpleName("B"))</code>
+ * </li>
+ * <li>
+ * <code>SimpleType(QualifiedName(SimpleName("A"),SimpleName("B")))</code>
+ * </li>
+ * </ol>
+ * The first form is preferred when "A" is known to be a type (as opposed
+ * to a package). However, a parser cannot always determine this. Clients
+ * should be prepared to handle either rather than make assumptions.
+ * (Note also that the first form became possible as of JLS3; only the second
+ * form existed in JLS2.)
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ClassInstanceCreation extends Expression {
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(ClassInstanceCreation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ClassInstanceCreation.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link Name}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #TYPE_PROPERTY}.
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(ClassInstanceCreation.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(ClassInstanceCreation.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(ClassInstanceCreation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "anonymousClassDeclaration" structural property of this node type (child type: {@link AnonymousClassDeclaration}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY =
+		new ChildPropertyDescriptor(ClassInstanceCreation.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(5);
+		createPropertyList(ClassInstanceCreation.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(6);
+		createPropertyList(ClassInstanceCreation.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The optional expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalExpression = null;
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeArguments = null;
+
+	/**
+	 * The type name; lazily initialized; defaults to a unspecified,
+	 * legal type name. Not used in JLS3.
+	 */
+	private Name typeName = null;
+
+	/**
+	 * The type; lazily initialized; defaults to a unspecified type.
+	 * @since 3.0
+	 */
+	private Type type = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * The optional anonymous class declaration; <code>null</code> for none;
+	 * defaults to none.
+	 */
+	private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
+
+	/**
+	 * Creates a new AST node for a class instance creation expression owned
+	 * by the given AST. By default, there is no qualifying expression,
+	 * an empty list of type parameters, an unspecified type, an empty
+     * list of arguments, and does not declare an anonymous class.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ClassInstanceCreation (AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((Name) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
+			if (get) {
+				return getAnonymousClassDeclaration();
+			} else {
+				setAnonymousClassDeclaration((AnonymousClassDeclaration) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CLASS_INSTANCE_CREATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ClassInstanceCreation result = new ClassInstanceCreation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.setName((Name) getName().clone(target));
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+			result.setType((Type) getType().clone(target));
+		}
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		result.setAnonymousClassDeclaration(
+			(AnonymousClassDeclaration)
+			   ASTNode.copySubtree(target, getAnonymousClassDeclaration()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+				acceptChild(visitor, getName());
+			}
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.typeArguments);
+				acceptChild(visitor, getType());
+			}
+			acceptChildren(visitor, this.arguments);
+			acceptChild(visitor, getAnonymousClassDeclaration());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this class instance creation expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getExpression() {
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Sets or clears the expression of this class instance creation expression.
+	 *
+	 * @param expression the expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		// a ClassInstanceCreation may occur inside an Expression
+		// must check cycles
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this class
+	 * instance creation (added in JLS3 API).
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeArguments() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeArguments == null) {
+			unsupportedIn2();
+		}
+		return this.typeArguments;
+	}
+
+    /**
+	 * Returns the name of the type instantiated in this class instance
+	 * creation expression (JLS2 API only).
+	 *
+	 * @return the type name node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #getType()}, which returns a <code>Type</code> instead of a
+	 * <code>Name</code>.
+	 */
+	public Name getName() {
+		return internalGetName();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ Name internalGetName() {
+	    supportedOnlyIn2();
+		if (this.typeName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeName == null) {
+					preLazyInit();
+					this.typeName = new SimpleName(this.ast);
+					postLazyInit(this.typeName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.typeName;
+	}
+
+	/**
+	 * Sets the name of the type instantiated in this class instance
+	 * creation expression (JLS2 API only).
+	 *
+	 * @param name the new type name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>`
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #setType(Type)}, which expects a <code>Type</code> instead of
+	 * a <code>Name</code>.
+	 */
+	public void setName(Name name) {
+		internalSetName(name);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ void internalSetName(Name name) {
+	    supportedOnlyIn2();
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.typeName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.typeName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the type instantiated in this class instance creation
+	 * expression (added in JLS3 API).
+	 *
+	 * @return the type node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public Type getType() {
+	    unsupportedIn2();
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = new SimpleType(this.ast);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type instantiated in this class instance creation
+	 * expression (added in JLS3 API).
+	 *
+	 * @param type the new type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>`
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public void setType(Type type) {
+	    unsupportedIn2();
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this class
+	 * instance creation expression.
+	 *
+	 * @return the live list of argument expressions (possibly empty)
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Returns the anonymous class declaration introduced by this
+	 * class instance creation expression, if it has one.
+	 *
+	 * @return the anonymous class declaration, or <code>null</code> if none
+	 */
+	public AnonymousClassDeclaration getAnonymousClassDeclaration() {
+		return this.optionalAnonymousClassDeclaration;
+	}
+
+	/**
+	 * Sets whether this class instance creation expression declares
+	 * an anonymous class (that is, has class body declarations).
+	 *
+	 * @param decl the anonymous class declaration, or <code>null</code>
+	 *    if none
+	 */
+	public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
+		ASTNode oldChild = this.optionalAnonymousClassDeclaration;
+		preReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+		this.optionalAnonymousClassDeclaration = decl;
+		postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor invoked by this
+	 * expression. For anonymous classes, the binding is that of the anonymous
+	 * constructor.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the constructor binding, or <code>null</code> if the binding
+	 *    cannot be resolved
+	 */
+	public IMethodBinding resolveConstructorBinding() {
+		return this.ast.getBindingResolver().resolveConstructor(this);
+	}
+
+	/**
+	 * Returns <code>true</code> if the resolved class type has been inferred
+	 * from the assignment context (JLS4 15.12.2.8), <code>false</code> otherwise.
+	 * <p>
+	 * This information is available only when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if the resolved class type has been inferred
+	 * 	from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise
+	 * @since 3.7.1
+	 */
+	public boolean isResolvedTypeInferredFromExpectedType() {
+		return this.ast.getBindingResolver().isResolvedTypeInferredFromExpectedType(this);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 6 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		// n.b. type == null for ast.API_LEVEL == JLS2
+		// n.b. typeArguments == null for ast.API_LEVEL == JLS2
+		// n.b. typeName == null for ast.API_LEVEL >= JLS3
+		return
+			memSize()
+			+ (this.typeName == null ? 0 : getName().treeSize())
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ (this.optionalExpression == null ? 0 : getExpression().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.arguments == null ? 0 : this.arguments.listSize())
+			+ (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java
new file mode 100644
index 0000000..01cd412
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Abstract base class for all AST nodes that represent comments.
+ * There are exactly three kinds of comment:
+ * line comments ({@link LineComment}),
+ * block comments ({@link BlockComment}), and
+ * doc comments ({@link Javadoc}).
+ * <p>
+ * <pre>
+ * Comment:
+ *     LineComment
+ *     BlockComment
+ *     Javadoc
+ * </pre>
+ * </p>
+ *
+ * @since 3.0
+ */
+public abstract class Comment extends ASTNode {
+
+	/**
+	 * Alternate root node, or <code>null</code> if none.
+	 * Initially <code>null</code>.
+	 */
+	private ASTNode alternateRoot = null;
+
+	/**
+	 * Creates a new AST node for a comment owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Comment(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * Returns whether this comment is a block comment
+	 * (<code>BlockComment</code>).
+	 *
+	 * @return <code>true</code> if this is a block comment, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isBlockComment() {
+		return (this instanceof BlockComment);
+	}
+
+	/**
+	 * Returns whether this comment is a line comment
+	 * (<code>LineComment</code>).
+	 *
+	 * @return <code>true</code> if this is a line comment, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isLineComment() {
+		return (this instanceof LineComment);
+	}
+
+	/**
+	 * Returns whether this comment is a doc comment
+	 * (<code>Javadoc</code>).
+	 *
+	 * @return <code>true</code> if this is a doc comment, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isDocComment() {
+		return (this instanceof Javadoc);
+	}
+
+	/**
+	 * Returns the root AST node that this comment occurs
+	 * within, or <code>null</code> if none (or not recorded).
+	 * <p>
+	 * Typically, the comment nodes created while parsing a compilation
+	 * unit are not considered descendents of the normal AST
+	 * root, namely an {@link CompilationUnit}. Instead, these
+	 * comment nodes exist outside the normal AST and each is
+	 * a root in its own right. This optional property provides
+	 * a well-known way to navigate from the comment to the
+	 * compilation unit in such cases. Note that the alternate root
+	 * property is not one of the comment node's children. It is simply a
+	 * reference to a node.
+	 * </p>
+	 *
+	 * @return the alternate root node, or <code>null</code>
+	 * if none
+	 * @see #setAlternateRoot(ASTNode)
+	 */
+	public final ASTNode getAlternateRoot() {
+		return this.alternateRoot;
+	}
+
+	/**
+	 * Returns the root AST node that this comment occurs
+	 * within, or <code>null</code> if none (or not recorded).
+	 * <p>
+	 * </p>
+	 *
+	 * @param root the alternate root node, or <code>null</code>
+	 * if none
+	 * @see #getAlternateRoot()
+	 */
+	public final void setAlternateRoot(ASTNode root) {
+		// alternate root is *not* considered a structural property
+		// but we protect them nevertheless
+		checkModifiable();
+		this.alternateRoot = root;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
new file mode 100644
index 0000000..8f83ed7
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
@@ -0,0 +1,1089 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Java compilation unit AST node type. This is the type of the root of an AST.
+ * <p>
+ * The source range for this type of node is ordinarily the entire source file,
+ * including leading and trailing whitespace and comments.
+ * </p>
+ * <pre>
+ * CompilationUnit:
+ *    [ PackageDeclaration ]
+ *        { ImportDeclaration }
+ *        { TypeDeclaration | EnumDeclaration | AnnotationTypeDeclaration | <b>;</b> }
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CompilationUnit extends ASTNode {
+
+	/**
+	 * Canonical empty list of messages.
+	 */
+	private static final Message[] EMPTY_MESSAGES = new Message[0];
+
+	/**
+	 * Canonical empty list of problems.
+	 */
+	private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0];
+
+	/**
+	 * The "imports" structural property of this node type (element type: {@link ImportDeclaration}).
+	 *
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor IMPORTS_PROPERTY =
+		new ChildListPropertyDescriptor(CompilationUnit.class, "imports", ImportDeclaration.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "package" structural property of this node type (child type: {@link PackageDeclaration}).
+	 *
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor PACKAGE_PROPERTY =
+		new ChildPropertyDescriptor(CompilationUnit.class, "package", PackageDeclaration.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	/**
+	 * The "types" structural property of this node type (element type: {@link AbstractTypeDeclaration}).
+	 *
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(CompilationUnit.class, "types", AbstractTypeDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(CompilationUnit.class, properyList);
+		addProperty(PACKAGE_PROPERTY, properyList);
+		addProperty(IMPORTS_PROPERTY, properyList);
+		addProperty(TYPES_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The comment mapper, or <code>null</code> if none;
+	 * initially <code>null</code>.
+	 * @since 3.0
+	 */
+	private DefaultCommentMapper commentMapper = null;
+
+	/**
+	 * The Java type root (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an <code>org.eclipse.jdt.core.IClassFile</code>)
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java type root.
+	 */
+	private ITypeRoot typeRoot = null;
+
+	/**
+	 * The list of import declarations in textual order order;
+	 * initially none (elementType: <code>ImportDeclaration</code>).
+	 */
+	private ASTNode.NodeList imports =
+		new ASTNode.NodeList(IMPORTS_PROPERTY);
+
+	/**
+	 * Line end table. If <code>lineEndTable[i] == p</code> then the
+	 * line number <code>i+1</code> ends at character position
+	 * <code>p</code>. Except for the last line, the positions are that
+	 * of the last character of the line delimiter.
+	 * For example, the source string <code>A\nB\nC</code> has
+	 * line end table {1, 3} (if \n is one character).
+	 */
+	private int[] lineEndTable = Util.EMPTY_INT_ARRAY;
+
+	/**
+	 * Messages reported by the compiler during parsing or name resolution.
+	 */
+	private Message[] messages;
+
+	/**
+	 * The comment list (element type: {@link Comment},
+	 * or <code>null</code> if none; initially <code>null</code>.
+	 * @since 3.0
+	 */
+	private List optionalCommentList = null;
+
+	/**
+	 * The comment table, or <code>null</code> if none; initially
+	 * <code>null</code>. This array is the storage underlying
+	 * the <code>optionalCommentList</code> ArrayList.
+	 * @since 3.0
+	 */
+	Comment[] optionalCommentTable = null;
+
+	/**
+	 * The package declaration, or <code>null</code> if none; initially
+	 * <code>null</code>.
+	 */
+	private PackageDeclaration optionalPackageDeclaration = null;
+
+	/**
+	 * Problems reported by the compiler during parsing or name resolution.
+	 */
+	private IProblem[] problems = EMPTY_PROBLEMS;
+	
+	/**
+	 * Internal data used to perform statements recovery.
+	 */
+	private Object statementsRecoveryData;
+
+	/**
+	 * The list of type declarations in textual order order;
+	 * initially none (elementType: <code>AbstractTypeDeclaration</code>)
+	 */
+	private ASTNode.NodeList types =
+		new ASTNode.NodeList(TYPES_PROPERTY);
+
+	/**
+	 * Creates a new AST node for a compilation owned by the given AST.
+	 * The compilation unit initially has no package declaration, no
+	 * import declarations, and no type declarations.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	CompilationUnit(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getPackage());
+			acceptChildren(visitor, this.imports);
+			acceptChildren(visitor, this.types);
+		}
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		CompilationUnit result = new CompilationUnit(target);
+		// n.b do not copy line number table or messages
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setPackage(
+			(PackageDeclaration) ASTNode.copySubtree(target, getPackage()));
+		result.imports().addAll(ASTNode.copySubtrees(target, imports()));
+		result.types().addAll(ASTNode.copySubtrees(target, types()));
+		return result;
+	}
+
+
+	/**
+	 * Returns the column number corresponding to the given source character
+	 * position in the original source string. Column number are zero-based.
+	 * Return <code>-1</code> if it is beyond the valid range or <code>-2</code>
+	 * if the column number information is unknown.
+	 *
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 0-based column number, or <code>-1</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or <code>-2</code> if column number information is unknown for this
+	 *    compilation unit
+	 * @see ASTParser
+	 * @since 3.2
+	 */
+	public int getColumnNumber(final int position) {
+		if (this.lineEndTable == null) return -2;
+		final int line = getLineNumber(position);
+		if (line == -1) {
+			return -1;
+		}
+		if (line == 1) {
+			if (position >= getStartPosition() + getLength()) return -1;
+			return position;
+		}
+		// length is different from 0
+		int length = this.lineEndTable.length;
+		// -1 to for one-based to zero-based conversion.
+		// -1, again, to get previous line.
+		final int previousLineOffset = this.lineEndTable[line - 2];
+		 // previousLineOffset + 1 is the first character of the current line
+		final int offsetForLine = previousLineOffset + 1;
+		final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1 :	this.lineEndTable[line - 1];
+		if (offsetForLine > currentLineEnd) {
+			return -1;
+		} else {
+			return position - offsetForLine;
+		}
+	}
+
+	/**
+	 * Finds the corresponding AST node in the given compilation unit from
+	 * which the given binding originated. Returns <code>null</code> if the
+	 * binding does not correspond to any node in this compilation unit.
+	 * This method always returns <code>null</code> if bindings were not requested
+	 * when this AST was built.
+	 * <p>
+	 * The following table indicates the expected node type for the various
+	 * different kinds of bindings:
+	 * <ul>
+	 * <li>package - a <code>PackageDeclaration</code></li>
+	 * <li>class or interface - a <code>TypeDeclaration</code> or a
+	 *    <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
+	 * <li>primitive type - none</li>
+	 * <li>array type - none</li>
+	 * <li>field - a <code>VariableDeclarationFragment</code> in a
+	 *    <code>FieldDeclaration</code> </li>
+	 * <li>local variable - a <code>SingleVariableDeclaration</code>, or
+	 *    a <code>VariableDeclarationFragment</code> in a
+	 *    <code>VariableDeclarationStatement</code> or
+	 *    <code>VariableDeclarationExpression</code></li>
+	 * <li>method - a <code>MethodDeclaration</code> </li>
+	 * <li>constructor - a <code>MethodDeclaration</code> </li>
+     * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
+     * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
+     * <li>enum type - an <code>EnumDeclaration</code></li>
+     * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
+     * <li>type variable - a <code>TypeParameter</code></li>
+     * <li>capture binding - none</li>
+     * <li>annotation binding - an <code>Annotation</code></li>
+     * <li>member value pair binding - an <code>MemberValuePair</code>,
+     *      or <code>null</code> if it represents a default value or a single member value</li>
+	 * </ul>
+     * For parameterized or raw type bindings, the declaring node is
+     * that of the corresponding generic type. And for parameterized or raw
+     * method bindings, the declaring node is that of the corresponding
+     * generic method.
+	 * </p>
+	 * <p>
+	 * Each call to {@link ASTParser#createAST(org.eclipse.core.runtime.IProgressMonitor)} with a request for bindings
+	 * gives rise to separate universe of binding objects. This method always returns
+	 * <code>null</code> when the binding object comes from a different AST.
+	 * Use <code>findDeclaringNode(binding.getKey())</code> when the binding comes
+	 * from a different AST.
+	 * </p>
+	 *
+	 * @param binding the binding
+	 * @return the corresponding node where the given binding is declared,
+	 * or <code>null</code> if the binding does not correspond to a node in this
+	 * compilation unit or if bindings were not requested when this AST was built
+	 * @see #findDeclaringNode(String)
+	 */
+	public ASTNode findDeclaringNode(IBinding binding) {
+		return this.ast.getBindingResolver().findDeclaringNode(binding);
+	}
+
+	/**
+	 * Finds the corresponding AST node in the given compilation unit from
+	 * which the binding with the given key originated. Returns
+	 * <code>null</code> if the corresponding node cannot be determined.
+	 * This method always returns <code>null</code> if bindings were not requested
+	 * when this AST was built.
+	 * <p>
+	 * The following table indicates the expected node type for the various
+	 * different kinds of binding keys:
+	 * <ul>
+	 * <li></li>
+	 * <li>package - a <code>PackageDeclaration</code></li>
+	 * <li>class or interface - a <code>TypeDeclaration</code> or a
+	 *    <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
+	 * <li>primitive type - none</li>
+	 * <li>array type - none</li>
+	 * <li>field - a <code>VariableDeclarationFragment</code> in a
+	 *    <code>FieldDeclaration</code> </li>
+	 * <li>local variable - a <code>SingleVariableDeclaration</code>, or
+	 *    a <code>VariableDeclarationFragment</code> in a
+	 *    <code>VariableDeclarationStatement</code> or
+	 *    <code>VariableDeclarationExpression</code></li>
+	 * <li>method - a <code>MethodDeclaration</code> </li>
+	 * <li>constructor - a <code>MethodDeclaration</code> </li>
+     * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
+     * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
+     * <li>enum type - an <code>EnumDeclaration</code></li>
+     * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
+	 * <li>type variable - a <code>TypeParameter</code></li>
+     * <li>capture binding - none</li>
+	 * </ul>
+     * For parameterized or raw type bindings, the declaring node is
+     * that of the corresponding generic type. And for parameterized or raw
+     * method bindings, the declaring node is that of the corresponding
+     * generic method.
+	 * </p>
+	 *
+	 * @param key the binding key, or <code>null</code>
+	 * @return the corresponding node where a binding with the given
+	 * key is declared, or <code>null</code> if the key is <code>null</code>
+	 * or if the key does not correspond to a node in this compilation unit
+	 * or if bindings were not requested when this AST was built
+	 * @see IBinding#getKey()
+	 * @since 2.1
+	 */
+	public ASTNode findDeclaringNode(String key) {
+		return this.ast.getBindingResolver().findDeclaringNode(key);
+	}
+
+	/**
+	 * Returns a list of the comments encountered while parsing
+	 * this compilation unit.
+	 * <p>
+	 * Since the Java language allows comments to appear most anywhere
+	 * in the source text, it is problematic to locate comments in relation
+	 * to the structure of an AST. The one exception is doc comments
+	 * which, by convention, immediately precede type, field, and
+	 * method declarations; these comments are located in the AST
+	 * by {@link  BodyDeclaration#getJavadoc BodyDeclaration.getJavadoc}.
+	 * Other comments do not show up in the AST. The table of comments
+	 * is provided for clients that need to find the source ranges of
+	 * all comments in the original source string. It includes entries
+	 * for comments of all kinds (line, block, and doc), arranged in order
+	 * of increasing source position.
+	 * </p>
+	 * <p>
+	 * Note on comment parenting: The {@link ASTNode#getParent() getParent()}
+	 * of a doc comment associated with a body declaration is the body
+	 * declaration node; for these comment nodes
+	 * {@link ASTNode#getRoot() getRoot()} will return the compilation unit
+	 * (assuming an unmodified AST) reflecting the fact that these nodes
+	 * are property located in the AST for the compilation unit.
+	 * However, for other comment nodes, {@link ASTNode#getParent() getParent()}
+	 * will return <code>null</code>, and {@link ASTNode#getRoot() getRoot()}
+	 * will return the comment node itself, indicating that these comment nodes
+	 * are not directly connected to the AST for the compilation unit. The
+	 * {@link Comment#getAlternateRoot Comment.getAlternateRoot}
+	 * method provides a way to navigate from a comment to its compilation
+	 * unit.
+	 * </p>
+	 * <p>
+	 * A note on visitors: The only comment nodes that will be visited when
+	 * visiting a compilation unit are the doc comments parented by body
+	 * declarations. To visit all comments in normal reading order, iterate
+	 * over the comment table and call {@link ASTNode#accept(ASTVisitor) accept}
+	 * on each element.
+	 * </p>
+	 * <p>
+	 * Clients cannot modify the resulting list.
+	 * </p>
+	 *
+	 * @return an unmodifiable list of comments in increasing order of source
+	 * start position (element type: {@link Comment}, or <code>null</code> if comment information
+	 * for this compilation unit is not available
+	 * @see ASTParser
+	 * @since 3.0
+	 */
+	public List getCommentList() {
+		return this.optionalCommentList;
+	}
+
+	/**
+	 * Returns the internal comment mapper.
+	 *
+	 * @return the comment mapper, or <code>null</code> if none.
+	 * @since 3.0
+	 */
+	DefaultCommentMapper getCommentMapper() {
+		return this.commentMapper;
+	}
+
+	/**
+	 * Returns the extended source length of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 *
+	 * @param node the node
+	 * @return a (possibly 0) length, or <code>0</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getExtendedStartPosition(ASTNode)
+	 * @since 3.0
+	 */
+	public int getExtendedLength(ASTNode node) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			// fall back: use best info available
+			return node.getLength();
+		} else {
+			return this.commentMapper.getExtendedLength(node);
+		}
+	}
+
+	/**
+	 * Returns the extended start position of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 *
+	 * @param node the node
+	 * @return the 0-based character index, or <code>-1</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getExtendedLength(ASTNode)
+	 * @since 3.0
+	 */
+	public int getExtendedStartPosition(ASTNode node) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			// fall back: use best info available
+			return node.getStartPosition();
+		} else {
+			return this.commentMapper.getExtendedStartPosition(node);
+		}
+	}
+
+	/**
+	 * The Java element (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an <code>org.eclipse.jdt.core.IClassFile</code>)
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java element.
+	 *
+	 * @return the Java element this compilation unit was created from, or <code>null</code> if none
+	 * @since 3.1
+	 * @see #getTypeRoot()
+	 */
+	public IJavaElement getJavaElement() {
+		return this.typeRoot;
+	}
+
+	/**
+	 * Returns the list of messages reported by the compiler during the parsing
+	 * or the type checking of this compilation unit. This list might be a subset of
+	 * errors detected and reported by a Java compiler.
+	 * <p>
+	 * This list of messages is suitable for simple clients that do little
+	 * more than log the messages or display them to the user. Clients that
+	 * need further details should call <code>getProblems</code> to get
+	 * compiler problem objects.
+	 * </p>
+	 *
+	 * @return the list of messages, possibly empty
+	 * @see #getProblems()
+	 * @see ASTParser
+	 */
+	public Message[] getMessages() {
+		if (this.messages == null) {
+			int problemLength = this.problems.length;
+			if (problemLength == 0) {
+				this.messages = EMPTY_MESSAGES;
+			} else {
+				this.messages = new Message[problemLength];
+				for (int i = 0; i < problemLength; i++) {
+					IProblem problem = this.problems[i];
+					int start = problem.getSourceStart();
+					int end = problem.getSourceEnd();
+					this.messages[i] = new Message(problem.getMessage(), start, end - start + 1);
+				}
+			}
+		}
+		return this.messages;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return COMPILATION_UNIT;
+	}
+
+	/**
+	 * Returns the node for the package declaration of this compilation
+	 * unit, or <code>null</code> if this compilation unit is in the
+	 * default package.
+	 *
+	 * @return the package declaration node, or <code>null</code> if none
+	 */
+	public PackageDeclaration getPackage() {
+		return this.optionalPackageDeclaration;
+	}
+
+	/**
+	 * Given a line number and column number, returns the corresponding
+	 * position in the original source string.
+	 * Returns -2 if no line number information is available for this
+	 * compilation unit.
+	 * Returns the total size of the source string if <code>line</code>
+	 * is greater than the actual number lines in the unit.
+	 * Returns -1 if <code>column</code> is less than 0,
+	 * or the position of the last character of the line if <code>column</code>
+	 * is beyond the legal range, or the given line number is less than one.
+	 *
+	 * @param line the one-based line number
+	 * @param column the zero-based column number
+	 * @return the 0-based character position in the source string;
+	 * <code>-2</code> if line/column number information is not known
+	 * for this compilation unit or <code>-1</code> the inputs are not valid
+	 * @since 3.2
+	 */
+	 public int getPosition(int line, int column) {
+		if (this.lineEndTable == null) return -2;
+		if (line < 1 || column < 0) return -1;
+		int length;
+		if ((length = this.lineEndTable.length) == 0) {
+			if (line != 1) return -1;
+			return column >= getStartPosition() + getLength() ? -1 : column;
+		}
+		if (line == 1) {
+			final int endOfLine = this.lineEndTable[0];
+			return column > endOfLine ? -1 : column;
+		} else if( line > length + 1 ) {
+			// greater than the number of lines in the source string.
+			return -1;
+		}
+		// -1 to for one-based to zero-based conversion.
+		// -1, again, to get previous line.
+		final int previousLineOffset = this.lineEndTable[line - 2];
+		 // previousLineOffset + 1 is the first character of the current line
+		final int offsetForLine = previousLineOffset + 1;
+		final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1 : this.lineEndTable[line-1];
+		if ((offsetForLine + column) > currentLineEnd) {
+			return -1;
+		} else {
+			return offsetForLine + column;
+		}
+	}
+
+	/**
+	 * Returns the list of detailed problem reports noted by the compiler
+	 * during the parsing or the type checking of this compilation unit. This
+	 * list might be a subset of errors detected and reported by a Java
+	 * compiler.
+	 * <p>
+	 * Simple clients that do little more than log the messages or display
+	 * them to the user should probably call <code>getMessages</code> instead.
+	 * </p>
+	 *
+	 * @return the list of detailed problem objects, possibly empty
+	 * @see #getMessages()
+	 * @see ASTParser
+	 * @since 2.1
+	 */
+	public IProblem[] getProblems() {
+		return this.problems;
+	}
+
+	/**
+	 * Internal method
+	 * 
+	 * This method return internal data used to perform statements recovery.
+	 * 
+	 * @return internal data used to perform statements recovery.
+	 * 
+	 * @noreference This method is not intended to be referenced by clients.
+	 * @since 3.5
+	 */
+	public Object getStatementsRecoveryData() {
+		return this.statementsRecoveryData;
+	}
+	
+	/**
+	 * The Java type root (a {@link org.eclipse.jdt.core.ICompilationUnit compilation unit} or a {@link org.eclipse.jdt.core.IClassFile class file})
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java type root.
+	 *
+	 * @return the Java type root this compilation unit was created from, or <code>null</code> if none
+	 * @since 3.3
+	 */
+	public ITypeRoot getTypeRoot() {
+		return this.typeRoot;
+	}
+
+	/**
+	 * Returns the live list of nodes for the import declarations of this
+	 * compilation unit, in order of appearance.
+	 *
+	 * @return the live list of import declaration nodes
+	 *    (elementType: {@link ImportDeclaration})
+	 */
+	public List imports() {
+		return this.imports;
+	}
+
+	/**
+	 * Return the index in the whole comments list {@link #getCommentList() }
+	 * of the first leading comments associated with the given node.
+	 *
+	 * @param node the node
+	 * @return 0-based index of first leading comment or -1 if node has no associated
+	 * 	comment before its start position.
+	 * @since 3.2
+	 */
+	public int firstLeadingCommentIndex(ASTNode node) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			return -1;
+		}
+		return this.commentMapper.firstLeadingCommentIndex(node);
+	}
+
+	/**
+	 * Return the index in the whole comments list {@link #getCommentList() }
+	 * of the last trailing comments associated with the given node.
+	 *
+	 * @param node the node
+	 * @return 0-based index of last trailing comment or -1 if node has no
+	 * 	associated comment after its end position.
+	 * @since 3.2
+	 */
+	public int lastTrailingCommentIndex(ASTNode node) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			return -1;
+		}
+		return this.commentMapper.lastTrailingCommentIndex(node);
+	}
+
+	/**
+	 * Initializes the internal comment mapper with the given
+	 * scanner.
+	 *
+	 * @param scanner the scanner
+	 * @since 3.0
+	 */
+	void initCommentMapper(Scanner scanner) {
+		this.commentMapper = new DefaultCommentMapper(this.optionalCommentTable);
+		this.commentMapper.initialize(this, scanner);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == IMPORTS_PROPERTY) {
+			return imports();
+		}
+		if (property == TYPES_PROPERTY) {
+			return types();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == PACKAGE_PROPERTY) {
+			if (get) {
+				return getPackage();
+			} else {
+				setPackage((PackageDeclaration) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/**
+	 * Returns the line number corresponding to the given source character
+	 * position in the original source string. The initial line of the
+	 * compilation unit is numbered 1, and each line extends through the
+	 * last character of the end-of-line delimiter. The very last line extends
+	 * through the end of the source string and has no line delimiter.
+	 * For example, the source string <code>class A\n{\n}</code> has 3 lines
+	 * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
+	 * Returns 1 for a character position that does not correspond to any
+	 * source line, or if no line number information is available for this
+	 * compilation unit.
+	 *
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 1-based line number, or <code>1</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or if line number information is not known for this
+	 *    compilation unit
+	 * @deprecated Use getLineNumber(int) instead. Be careful to handle the negative values.
+	 * @see ASTParser
+	 * @see #getLineNumber(int)
+	 */
+	public int lineNumber(int position) {
+		int lineNumber = getLineNumber(position);
+		return lineNumber < 1 ? 1 : lineNumber;
+	}
+
+	/**
+	 * Returns the line number corresponding to the given source character
+	 * position in the original source string. The initial line of the
+	 * compilation unit is numbered 1, and each line extends through the
+	 * last character of the end-of-line delimiter. The very last line extends
+	 * through the end of the source string and has no line delimiter.
+	 * For example, the source string <code>class A\n{\n}</code> has 3 lines
+	 * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
+	 * Returns -1 for a character position that does not correspond to any
+	 * source line, or -2 if no line number information is available for this
+	 * compilation unit.
+	 *
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 1-based line number, or <code>-1</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or <code>-2</code> if line number information is not known for this
+	 *    compilation unit
+	 * @see ASTParser
+	 * @since 3.2
+	 */
+	public int getLineNumber(int position) {
+		if (this.lineEndTable == null) return -2;
+		int length;
+		if ((length = this.lineEndTable.length) == 0) {
+			if (position >= getStartPosition() + getLength()) {
+				return -1;
+			}
+			return 1;
+		}
+		int low = 0;
+		if (position < 0) {
+			// position illegal
+			return -1;
+		}
+		if (position <= this.lineEndTable[low]) {
+			// before the first line delimiter
+			return 1;
+		}
+		// assert position > lineEndTable[low+1]  && low == 0
+		int hi = length - 1;
+		if (position > this.lineEndTable[hi]) {
+			// position beyond the last line separator
+			if (position >= getStartPosition() + getLength()) {
+				// this is beyond the end of the source length
+				return -1;
+			} else {
+				return length + 1;
+			}
+		}
+		// assert lineEndTable[low]  < position <= lineEndTable[hi]
+		// && low == 0 && hi == length - 1 && low < hi
+
+		// binary search line end table
+		while (true) {
+			// invariant lineEndTable[low] < position <= lineEndTable[hi]
+			// && 0 <= low < hi <= length - 1
+			// reducing measure hi - low
+			if (low + 1 == hi) {
+				// assert lineEndTable[low] < position <= lineEndTable[low+1]
+				// position is on line low+1 (line number is low+2)
+				return low + 2;
+			}
+			// assert hi - low >= 2, so average is truly in between
+			int mid = low + (hi - low) / 2;
+			// assert 0 <= low < mid < hi <= length - 1
+			if (position <= this.lineEndTable[mid]) {
+				// assert lineEndTable[low] < position <= lineEndTable[mid]
+				// && 0 <= low < mid < hi <= length - 1
+				hi = mid;
+			} else {
+				// position > lineEndTable[mid]
+				// assert lineEndTable[mid] < position <= lineEndTable[hi]
+				// && 0 <= low < mid < hi <= length - 1
+				low = mid;
+			}
+			// in both cases, invariant reachieved with reduced measure
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 8 * 4;
+		if (this.lineEndTable != null) {
+			size += HEADERS + 4 * this.lineEndTable.length;
+		}
+		if (this.optionalCommentTable != null) {
+			size += HEADERS + 4 * this.optionalCommentTable.length;
+		}
+		// ignore the space taken up by optionalCommentList
+		return size;
+	}
+
+	/**
+	 * Enables the recording of changes to this compilation
+	 * unit and its descendants. The compilation unit must have
+	 * been created by {@link ASTParser} and still be in
+	 * its original state. Once recording is on,
+	 * arbitrary changes to the subtree rooted at this compilation
+	 * unit are recorded internally. Once the modification has
+	 * been completed, call {@link #rewrite(IDocument, Map)} to get an object
+	 * representing the corresponding edits to the original
+	 * source code string.
+	 * <p>
+	 * Note that this way of manipulating an AST only allows a single line of modifications.
+	 * To modify an AST in a non-destructive way, use an external {@link ASTRewrite}.
+	 * As an added benefit, you can then also use
+	 * {@link ASTRewrite#createStringPlaceholder(String, int) string placeholders} and
+	 * {@link ASTRewrite#createCopyTarget(ASTNode) copy} nodes including comments and formatting.
+	 * </p>
+	 *
+	 * @exception IllegalArgumentException if this compilation unit is
+	 * marked as unmodifiable, or if this compilation unit has already
+	 * been tampered with, or recording has already been enabled
+	 * @since 3.0
+	 */
+	public void recordModifications() {
+		getAST().recordModifications(this);
+	}
+
+	/**
+	 * Converts all modifications recorded for this compilation
+	 * unit into an object representing the corresponding text
+	 * edits to the given document containing the original source
+	 * code for this compilation unit.
+	 * <p>
+	 * The compilation unit must have been created by
+	 * {@link ASTParser} from the source code string in the
+	 * given document, and recording must have been turned
+	 * on with a prior call to {@link #recordModifications()}
+	 * while the AST was still in its original state.
+	 * </p>
+	 * <p>
+	 * Calling this methods does not discard the modifications
+	 * on record. Subsequence modifications made to the AST
+	 * are added to the ones already on record. If this method
+	 * is called again later, the resulting text edit object will
+	 * accurately reflect the net cumulative effect of all those
+	 * changes.
+	 * </p>
+	 *
+	 * @param document original document containing source code
+	 * for this compilation unit
+	 * @param options the table of formatter options
+	 * (key type: <code>String</code>; value type: <code>String</code>);
+	 * or <code>null</code> to use the standard global options
+	 * {@link org.eclipse.jdt.core.JavaCore#getOptions() JavaCore.getOptions()}.
+	 * @return text edit object describing the changes to the
+	 * document corresponding to the recorded AST modifications
+	 * @exception IllegalArgumentException if the document passed is
+	 * <code>null</code> or does not correspond to this AST
+	 * @exception IllegalStateException if <code>recordModifications</code>
+	 * was not called to enable recording
+	 * @see #recordModifications()
+	 * @since 3.0
+	 */
+	public TextEdit rewrite(IDocument document, Map options) {
+		return getAST().rewrite(document, options);
+	}
+
+	/**
+	 * Sets the list of the comments encountered while parsing
+	 * this compilation unit.
+	 *
+	 * @param commentTable a list of comments in increasing order
+	 * of source start position, or <code>null</code> if comment
+	 * information for this compilation unit is not available
+	 * @exception IllegalArgumentException if the comment table is
+	 * not in increasing order of source position
+	 * @see #getCommentList()
+	 * @see ASTParser
+	 * @since 3.0
+	 */
+	void setCommentTable(Comment[] commentTable) {
+		// double check table to ensure that all comments have
+		// source positions and are in strictly increasing order
+		if (commentTable == null) {
+			this.optionalCommentList = null;
+			this.optionalCommentTable = null;
+		} else {
+			int nextAvailablePosition = 0;
+			for (int i = 0; i < commentTable.length; i++) {
+				Comment comment = commentTable[i];
+				if (comment == null) {
+					throw new IllegalArgumentException();
+				}
+				int start = comment.getStartPosition();
+				int length = comment.getLength();
+				if (start < 0 || length < 0 || start < nextAvailablePosition) {
+					throw new IllegalArgumentException();
+				}
+				nextAvailablePosition = comment.getStartPosition() + comment.getLength();
+			}
+			this.optionalCommentTable = commentTable;
+			List commentList = Arrays.asList(commentTable);
+			// protect the list from further modification
+			this.optionalCommentList = Collections.unmodifiableList(commentList);
+		}
+	}
+
+	/**
+	 * Sets the Java type root (a {@link org.eclipse.jdt.core.ICompilationUnit compilation unit} or a {@link org.eclipse.jdt.core.IClassFile class file})
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java type root.
+	 *
+	 * @param typeRoot the Java type root this compilation unit was created from
+	 */
+	void setTypeRoot(ITypeRoot typeRoot) {
+		this.typeRoot = typeRoot;
+	}
+
+	/**
+	 * Sets the line end table for this compilation unit.
+	 * If <code>lineEndTable[i] == p</code> then line number <code>i+1</code>
+	 * ends at character position <code>p</code>. Except for the last line, the
+	 * positions are that of (the last character of) the line delimiter.
+	 * For example, the source string <code>A\nB\nC</code> has
+	 * line end table {1, 3, 4}.
+	 *
+	 * @param lineEndTable the line end table
+	 */
+	void setLineEndTable(int[] lineEndTable) {
+		if (lineEndTable == null) {
+			throw new NullPointerException();
+		}
+		// alternate root is *not* considered a structural property
+		// but we protect them nevertheless
+		checkModifiable();
+		this.lineEndTable = lineEndTable;
+	}
+
+	/**
+	 * Sets or clears the package declaration of this compilation unit
+	 * node to the given package declaration node.
+	 *
+	 * @param pkgDecl the new package declaration node, or
+	 *   <code>null</code> if this compilation unit does not have a package
+	 *   declaration (that is in the default package)
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setPackage(PackageDeclaration pkgDecl) {
+		ASTNode oldChild = this.optionalPackageDeclaration;
+		preReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY);
+		this.optionalPackageDeclaration = pkgDecl;
+		postReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY);
+	}
+
+
+	/**
+	 * Sets the array of problems reported by the compiler during the parsing or
+	 * name resolution of this compilation unit.
+	 *
+	 * @param problems the list of problems
+	 */
+	void setProblems(IProblem[] problems) {
+		if (problems == null) {
+			throw new IllegalArgumentException();
+		}
+		this.problems = problems;
+	}
+	
+	/**
+	 * Internal method
+	 * 
+	 * Sets internal data used to perform statements recovery.
+	 * @param data
+	 * 
+	 * @since 3.5
+	 */
+	void setStatementsRecoveryData(Object data) {
+		this.statementsRecoveryData = data;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		int size = memSize();
+		if (this.optionalPackageDeclaration != null) {
+			size += getPackage().treeSize();
+		}
+		size += this.imports.listSize();
+		size += this.types.listSize();
+		// include disconnected comments
+		if (this.optionalCommentList != null) {
+			for (int i = 0; i < this.optionalCommentList.size(); i++) {
+				Comment comment = (Comment) this.optionalCommentList.get(i);
+				if (comment != null && comment.getParent() == null) {
+					size += comment.treeSize();
+				}
+			}
+		}
+		return size;
+	}
+
+	/**
+	 * Returns the live list of nodes for the top-level type declarations of this
+	 * compilation unit, in order of appearance.
+     * <p>
+     * Note that in JLS3, the types may include both enum declarations
+     * and annotation type declarations introduced in J2SE 5.
+     * For JLS2, the elements are always <code>TypeDeclaration</code>.
+     * </p>
+	 *
+	 * @return the live list of top-level type declaration
+	 *    nodes (element type: {@link AbstractTypeDeclaration})
+	 */
+	public List types() {
+		return this.types;
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
new file mode 100644
index 0000000..daa3323
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
@@ -0,0 +1,1297 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 363858 - [dom] early throwing of AbortCompilation causes NPE in CompilationUnitResolver
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.BinaryMember;
+import org.eclipse.jdt.internal.core.CancelableNameEnvironment;
+import org.eclipse.jdt.internal.core.CancelableProblemFactory;
+import org.eclipse.jdt.internal.core.INameEnvironmentWithProgress;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SourceRefElement;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.util.BindingKeyResolver;
+import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
+import org.eclipse.jdt.internal.core.util.DOMFinder;
+
+class CompilationUnitResolver extends Compiler {
+	public static final int RESOLVE_BINDING = 0x1;
+	public static final int PARTIAL = 0x2;
+	public static final int STATEMENT_RECOVERY = 0x4;
+	public static final int IGNORE_METHOD_BODIES = 0x8;
+	public static final int BINDING_RECOVERY = 0x10;
+	public static final int INCLUDE_RUNNING_VM_BOOTCLASSPATH = 0x20;
+
+	/* A list of int */
+	static class IntArrayList {
+		public int[] list = new int[5];
+		public int length = 0;
+		public void add(int i) {
+			if (this.list.length == this.length) {
+				System.arraycopy(this.list, 0, this.list = new int[this.length*2], 0, this.length);
+			}
+				this.list[this.length++] = i;
+			}
+		}
+
+	/*
+	 * The sources that were requested.
+	 * Map from file name (char[]) to org.eclipse.jdt.internal.compiler.env.ICompilationUnit.
+	 */
+	HashtableOfObject requestedSources;
+
+	/*
+	 * The binding keys that were requested.
+	 * Map from file name (char[]) to BindingKey (or ArrayList if multiple keys in the same file).
+	 */
+	HashtableOfObject requestedKeys;
+
+	DefaultBindingResolver.BindingTables bindingTables;
+
+	boolean hasCompilationAborted;
+	CategorizedProblem abortProblem;
+
+	private IProgressMonitor monitor;
+	
+	/**
+	 * Set to <code>true</code> if the receiver was initialized using a java project name environment
+	 */
+	boolean fromJavaProject;
+
+	/**
+	 * Answer a new CompilationUnitVisitor using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (for example, in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *	@param compilerOptions The compiler options to use for the resolution.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 */
+	public CompilationUnitResolver(
+		INameEnvironment environment,
+		IErrorHandlingPolicy policy,
+		CompilerOptions compilerOptions,
+		ICompilerRequestor requestor,
+		IProblemFactory problemFactory,
+		IProgressMonitor monitor,
+		boolean fromJavaProject) {
+
+		super(environment, policy, compilerOptions, requestor, problemFactory);
+		this.hasCompilationAborted = false;
+		this.monitor =monitor;
+		this.fromJavaProject = fromJavaProject;
+	}
+
+	/*
+	 * Add additional source types
+	 */
+	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		// Need to reparse the entire source of the compilation unit so as to get source positions
+		// (case of processing a source that was not known by beginToCompile (e.g. when asking to createBinding))
+		SourceTypeElementInfo sourceType = (SourceTypeElementInfo) sourceTypes[0];
+		accept((org.eclipse.jdt.internal.compiler.env.ICompilationUnit) sourceType.getHandle().getCompilationUnit(), accessRestriction);
+	}
+	
+	public synchronized void accept(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+		super.accept(sourceUnit, accessRestriction);
+	}
+
+	/**
+	 * Add the initial set of compilation units into the loop
+	 *  ->  build compilation unit declarations, their bindings and record their results.
+	 */
+	protected void beginToCompile(org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] sourceUnits, String[] bindingKeys) {
+		int sourceLength = sourceUnits.length;
+		int keyLength = bindingKeys.length;
+		int maxUnits = sourceLength + keyLength;
+		this.totalUnits = 0;
+		this.unitsToProcess = new CompilationUnitDeclaration[maxUnits];
+		int index = 0;
+
+		// walks the source units
+		this.requestedSources = new HashtableOfObject();
+		for (int i = 0; i < sourceLength; i++) {
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = sourceUnits[i];
+			CompilationUnitDeclaration parsedUnit;
+			CompilationResult unitResult =
+				new CompilationResult(sourceUnit, index++, maxUnits, this.options.maxProblemsPerUnit);
+			try {
+				if (this.options.verbose) {
+					this.out.println(
+						Messages.bind(Messages.compilation_request,
+						new String[] {
+							String.valueOf(index++ + 1),
+							String.valueOf(maxUnits),
+							new String(sourceUnit.getFileName())
+						}));
+				}
+				// diet parsing for large collection of units
+				if (this.totalUnits < this.parseThreshold) {
+					parsedUnit = this.parser.parse(sourceUnit, unitResult);
+				} else {
+					parsedUnit = this.parser.dietParse(sourceUnit, unitResult);
+				}
+				// initial type binding creation
+				this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+				addCompilationUnit(sourceUnit, parsedUnit);
+				this.requestedSources.put(unitResult.getFileName(), sourceUnit);
+				worked(1);
+			} finally {
+				sourceUnits[i] = null; // no longer hold onto the unit
+			}
+		}
+
+		// walk the binding keys
+		this.requestedKeys = new HashtableOfObject();
+		for (int i = 0; i < keyLength; i++) {
+			BindingKeyResolver resolver = new BindingKeyResolver(bindingKeys[i], this, this.lookupEnvironment);
+			resolver.parse(true/*pause after fully qualified name*/);
+			// If it doesn't have a type name, then it is either an array type, package or base type, which will definitely not have a compilation unit.
+			// Skipping it will speed up performance because the call will open jars. (theodora)
+			CompilationUnitDeclaration parsedUnit = resolver.hasTypeName() ? resolver.getCompilationUnitDeclaration() : null;
+			if (parsedUnit != null) {
+				char[] fileName = parsedUnit.compilationResult.getFileName();
+				Object existing = this.requestedKeys.get(fileName);
+				if (existing == null)
+					this.requestedKeys.put(fileName, resolver);
+				else if (existing instanceof ArrayList)
+					((ArrayList) existing).add(resolver);
+				else {
+					ArrayList list = new ArrayList();
+					list.add(existing);
+					list.add(resolver);
+					this.requestedKeys.put(fileName, list);
+				}
+
+			} else {
+				char[] key = resolver.hasTypeName()
+					? resolver.getKey().toCharArray() // binary binding
+					: CharOperation.concatWith(resolver.compoundName(), '.'); // package binding or base type binding
+				this.requestedKeys.put(key, resolver);
+			}
+			worked(1);
+		}
+
+		// binding resolution
+		this.lookupEnvironment.completeTypeBindings();
+	}
+
+	IBinding createBinding(String key) {
+		if (this.bindingTables == null)
+			throw new RuntimeException("Cannot be called outside ASTParser#createASTs(...)"); //$NON-NLS-1$
+		BindingKeyResolver keyResolver = new BindingKeyResolver(key, this, this.lookupEnvironment);
+		Binding compilerBinding = keyResolver.getCompilerBinding();
+		if (compilerBinding == null) return null;
+		DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null/*no owner*/, this.bindingTables, false, this.fromJavaProject);
+		return resolver.getBinding(compilerBinding);
+	}
+
+	public static CompilationUnit convert(
+			CompilationUnitDeclaration compilationUnitDeclaration,
+			char[] source,
+			int apiLevel,
+			Map options,
+			boolean needToResolveBindings,
+			WorkingCopyOwner owner,
+			DefaultBindingResolver.BindingTables bindingTables,
+			int flags,
+			IProgressMonitor monitor,
+			boolean fromJavaProject) {
+		BindingResolver resolver = null;
+		AST ast = AST.newAST(apiLevel);
+		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+		CompilationUnit compilationUnit = null;
+		ASTConverter converter = new ASTConverter(options, needToResolveBindings, monitor);
+		if (needToResolveBindings) {
+			resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope, owner, bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, fromJavaProject);
+			ast.setFlag(flags | AST.RESOLVED_BINDINGS);
+		} else {
+			resolver = new BindingResolver();
+			ast.setFlag(flags);
+		}
+		ast.setBindingResolver(resolver);
+		converter.setAST(ast);
+		compilationUnit = converter.convert(compilationUnitDeclaration, source);
+		compilationUnit.setLineEndTable(compilationUnitDeclaration.compilationResult.getLineSeparatorPositions());
+		ast.setDefaultNodeFlag(0);
+		ast.setOriginalModificationCount(ast.modificationCount());
+		return compilationUnit;
+	}
+
+	protected static CompilerOptions getCompilerOptions(Map options, boolean statementsRecovery) {
+		CompilerOptions compilerOptions = new CompilerOptions(options);
+		compilerOptions.performMethodsFullRecovery = statementsRecovery;
+		compilerOptions.performStatementsRecovery = statementsRecovery;
+		compilerOptions.parseLiteralExpressionsAsConstants = false;
+		compilerOptions.storeAnnotations = true /*store annotations in the bindings*/;
+		compilerOptions.ignoreSourceFolderWarningOption = true;
+		return compilerOptions;
+	}
+	/*
+	 *  Low-level API performing the actual compilation
+	 */
+	protected static IErrorHandlingPolicy getHandlingPolicy() {
+
+		// passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
+		return new IErrorHandlingPolicy() {
+			public boolean stopOnFirstError() {
+				return false;
+			}
+			public boolean proceedOnErrors() {
+				return false; // stop if there are some errors
+			}
+			public boolean ignoreAllErrors() {
+				return false;
+			}
+		};
+	}
+
+	/*
+	 * Answer the component to which will be handed back compilation results from the compiler
+	 */
+	protected static ICompilerRequestor getRequestor() {
+		return new ICompilerRequestor() {
+			public void acceptResult(CompilationResult compilationResult) {
+				// do nothing
+			}
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser()
+	 */
+	public void initializeParser() {
+		this.parser = new CommentRecorderParser(this.problemReporter, false);
+	}
+	public void process(CompilationUnitDeclaration unit, int i) {
+		// don't resolve a second time the same unit (this would create the same binding twice)
+		char[] fileName = unit.compilationResult.getFileName();
+		if (this.requestedKeys.get(fileName) == null && this.requestedSources.get(fileName) == null)
+			super.process(unit, i);
+	}
+	/*
+	 * Compiler crash recovery in case of unexpected runtime exceptions
+	 */
+	protected void handleInternalException(
+			Throwable internalException,
+			CompilationUnitDeclaration unit,
+			CompilationResult result) {
+		super.handleInternalException(internalException, unit, result);
+		if (unit != null) {
+			removeUnresolvedBindings(unit);
+		}
+	}
+
+	/*
+	 * Compiler recovery in case of internal AbortCompilation event
+	 */
+	protected void handleInternalException(
+			AbortCompilation abortException,
+			CompilationUnitDeclaration unit) {
+		super.handleInternalException(abortException, unit);
+		if (unit != null) {
+			removeUnresolvedBindings(unit);
+		}
+		this.hasCompilationAborted = true;
+		this.abortProblem = abortException.problem;
+	}
+
+	public static void parse(ICompilationUnit[] compilationUnits, ASTRequestor astRequestor, int apiLevel, Map options, int flags, IProgressMonitor monitor) {
+		try {
+			CompilerOptions compilerOptions = new CompilerOptions(options);
+			compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+			Parser parser = new CommentRecorderParser(
+				new ProblemReporter(
+						DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+						compilerOptions,
+						new DefaultProblemFactory()),
+				false);
+			int unitLength = compilationUnits.length;
+			if (monitor != null) monitor.beginTask("", unitLength); //$NON-NLS-1$
+			for (int i = 0; i < unitLength; i++) {
+				org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnits[i];
+				CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+				CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
+
+				if (compilationUnitDeclaration.ignoreMethodBodies) {
+					compilationUnitDeclaration.ignoreFurtherInvestigation = true;
+					// if initial diet parse did not work, no need to dig into method bodies.
+					continue;
+				}
+
+				//fill the methods bodies in order for the code to be generated
+				//real parse of the method....
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+				if (types != null) {
+					for (int j = 0, typeLength = types.length; j < typeLength; j++) {
+						types[j].parseMethods(parser, compilationUnitDeclaration);
+					}
+				}
+
+				// convert AST
+				CompilationUnit node = convert(compilationUnitDeclaration, parser.scanner.getSource(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, flags /* flags */, monitor, true);
+				node.setTypeRoot(compilationUnits[i]);
+
+				// accept AST
+				astRequestor.acceptAST(compilationUnits[i], node);
+
+				if (monitor != null) monitor.worked(1);
+			}
+		} finally {
+			if (monitor != null) monitor.done();
+		}
+	}
+	public static void parse(
+			String[] sourceUnits,
+			String[] encodings,
+			FileASTRequestor astRequestor,
+			int apiLevel,
+			Map options,
+			int flags,
+			IProgressMonitor monitor) {
+		try {
+			CompilerOptions compilerOptions = new CompilerOptions(options);
+			compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+			Parser parser = new CommentRecorderParser(
+				new ProblemReporter(
+						DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+						compilerOptions,
+						new DefaultProblemFactory()),
+				false);
+			int unitLength = sourceUnits.length;
+			if (monitor != null) monitor.beginTask("", unitLength); //$NON-NLS-1$
+			for (int i = 0; i < unitLength; i++) {
+				char[] contents = null;
+				String encoding = encodings != null ? encodings[i] : null;
+				try {
+					contents = Util.getFileCharContent(new File(sourceUnits[i]), encoding);
+				} catch(IOException e) {
+					// go to the next unit
+					continue;
+				}
+				if (contents == null) {
+					// go to the next unit
+					continue;
+				}
+				org.eclipse.jdt.internal.compiler.batch.CompilationUnit compilationUnit = new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(contents, sourceUnits[i], encoding);
+				org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationUnit;
+				CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+				CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
+
+				if (compilationUnitDeclaration.ignoreMethodBodies) {
+					compilationUnitDeclaration.ignoreFurtherInvestigation = true;
+					// if initial diet parse did not work, no need to dig into method bodies.
+					continue;
+				}
+
+				//fill the methods bodies in order for the code to be generated
+				//real parse of the method....
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+				if (types != null) {
+					for (int j = 0, typeLength = types.length; j < typeLength; j++) {
+						types[j].parseMethods(parser, compilationUnitDeclaration);
+					}
+				}
+
+				// convert AST
+				CompilationUnit node = convert(compilationUnitDeclaration, parser.scanner.getSource(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, flags /* flags */, monitor, true);
+				node.setTypeRoot(null);
+
+				// accept AST
+				astRequestor.acceptAST(sourceUnits[i], node);
+
+				if (monitor != null) monitor.worked(1);
+			}
+		} finally {
+			if (monitor != null) monitor.done();
+		}
+	}
+	public static CompilationUnitDeclaration parse(
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
+			NodeSearcher nodeSearcher,
+			Map settings,
+			int flags) {
+		if (sourceUnit == null) {
+			throw new IllegalStateException();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		boolean statementsRecovery = (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0;
+		compilerOptions.performMethodsFullRecovery = statementsRecovery;
+		compilerOptions.performStatementsRecovery = statementsRecovery;
+		compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+		Parser parser = new CommentRecorderParser(
+			new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					compilerOptions,
+					new DefaultProblemFactory()),
+			false);
+		CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
+
+		if (compilationUnitDeclaration.ignoreMethodBodies) {
+			compilationUnitDeclaration.ignoreFurtherInvestigation = true;
+			// if initial diet parse did not work, no need to dig into method bodies.
+			return compilationUnitDeclaration;
+		}
+
+		if (nodeSearcher != null) {
+			char[] source = parser.scanner.getSource();
+			int searchPosition = nodeSearcher.position;
+			if (searchPosition < 0 || searchPosition > source.length) {
+				// the position is out of range. There is no need to search for a node.
+				return compilationUnitDeclaration;
+			}
+
+			compilationUnitDeclaration.traverse(nodeSearcher, compilationUnitDeclaration.scope);
+
+			org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodeSearcher.found;
+			if (node == null) {
+				return compilationUnitDeclaration;
+			}
+
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingTypeDeclaration = nodeSearcher.enclosingType;
+
+			if (node instanceof AbstractMethodDeclaration) {
+				((AbstractMethodDeclaration)node).parseStatements(parser, compilationUnitDeclaration);
+			} else if (enclosingTypeDeclaration != null) {
+				if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
+					((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(parser, enclosingTypeDeclaration, compilationUnitDeclaration);
+				} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+					((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethods(parser, compilationUnitDeclaration);
+				}
+			}
+		} else {
+				//fill the methods bodies in order for the code to be generated
+				//real parse of the method....			
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+				if (types != null) {
+					for (int j = 0, typeLength = types.length; j < typeLength; j++) {
+						types[j].parseMethods(parser, compilationUnitDeclaration);
+					}
+				}
+		}
+		return compilationUnitDeclaration;
+	}
+
+	public static void resolve(
+		ICompilationUnit[] compilationUnits,
+		String[] bindingKeys,
+		ASTRequestor requestor,
+		int apiLevel,
+		Map options,
+		IJavaProject javaProject,
+		WorkingCopyOwner owner,
+		int flags,
+		IProgressMonitor monitor) {
+
+		CancelableNameEnvironment environment = null;
+		CancelableProblemFactory problemFactory = null;
+		try {
+			if (monitor != null) {
+				int amountOfWork = (compilationUnits.length + bindingKeys.length) * 2; // 1 for beginToCompile, 1 for resolve
+				monitor.beginTask("", amountOfWork); //$NON-NLS-1$
+			}
+			environment = new CancelableNameEnvironment(((JavaProject) javaProject), owner, monitor);
+			problemFactory = new CancelableProblemFactory(monitor);
+			CompilerOptions compilerOptions = getCompilerOptions(options, (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+			compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+			CompilationUnitResolver resolver =
+				new CompilationUnitResolver(
+					environment,
+					getHandlingPolicy(),
+					compilerOptions,
+					getRequestor(),
+					problemFactory,
+					monitor,
+					javaProject != null);
+			resolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, options, owner, flags);
+			if (NameLookup.VERBOSE) {
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		} catch (JavaModelException e) {
+			// project doesn't exist -> simple parse without resolving
+			parse(compilationUnits, requestor, apiLevel, options, flags, monitor);
+		} finally {
+			if (monitor != null) monitor.done();
+			if (environment != null) {
+				environment.setMonitor(null); // don't hold a reference to this external object
+			}
+			if (problemFactory != null) {
+				problemFactory.monitor = null; // don't hold a reference to this external object
+			}
+		}
+	}
+	public static void resolve(
+			String[] sourceUnits,
+			String[] encodings,
+			String[] bindingKeys,
+			FileASTRequestor requestor,
+			int apiLevel,
+			Map options,
+			List classpaths,
+			int flags,
+			IProgressMonitor monitor) {
+
+			INameEnvironmentWithProgress environment = null;
+			CancelableProblemFactory problemFactory = null;
+			try {
+				if (monitor != null) {
+					int amountOfWork = (sourceUnits.length + bindingKeys.length) * 2; // 1 for beginToCompile, 1 for resolve
+					monitor.beginTask("", amountOfWork); //$NON-NLS-1$
+				}
+				Classpath[] allEntries = new Classpath[classpaths.size()];
+				classpaths.toArray(allEntries);
+				environment = new NameEnvironmentWithProgress(allEntries, null, monitor);
+				problemFactory = new CancelableProblemFactory(monitor);
+				CompilerOptions compilerOptions = getCompilerOptions(options, (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+				compilerOptions.ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+				CompilationUnitResolver resolver =
+					new CompilationUnitResolver(
+						environment,
+						getHandlingPolicy(),
+						compilerOptions,
+						getRequestor(),
+						problemFactory,
+						monitor,
+						false);
+				resolver.resolve(sourceUnits, encodings, bindingKeys, requestor, apiLevel, options, flags);
+				if (NameLookup.VERBOSE && (environment instanceof CancelableNameEnvironment)) {
+					CancelableNameEnvironment cancelableNameEnvironment = (CancelableNameEnvironment) environment;
+					System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+					System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			} finally {
+				if (monitor != null) monitor.done();
+				if (environment != null) {
+					environment.setMonitor(null); // don't hold a reference to this external object
+				}
+				if (problemFactory != null) {
+					problemFactory.monitor = null; // don't hold a reference to this external object
+				}
+			}
+		}
+	public static CompilationUnitDeclaration resolve(
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
+			IJavaProject javaProject,
+			List classpaths,
+			NodeSearcher nodeSearcher,
+			Map options,
+			WorkingCopyOwner owner,
+			int flags,
+			IProgressMonitor monitor) throws JavaModelException {
+
+		CompilationUnitDeclaration unit = null;
+		INameEnvironmentWithProgress environment = null;
+		CancelableProblemFactory problemFactory = null;
+		CompilationUnitResolver resolver = null;
+		try {
+			if (javaProject == null) {
+				Classpath[] allEntries = new Classpath[classpaths.size()];
+				classpaths.toArray(allEntries);
+				environment = new NameEnvironmentWithProgress(allEntries, null, monitor);
+			} else {
+				environment = new CancelableNameEnvironment((JavaProject) javaProject, owner, monitor);
+			}
+			problemFactory = new CancelableProblemFactory(monitor);
+			CompilerOptions compilerOptions = getCompilerOptions(options, (flags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+			boolean ignoreMethodBodies = (flags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+			compilerOptions.ignoreMethodBodies = ignoreMethodBodies;
+			resolver =
+				new CompilationUnitResolver(
+					environment,
+					getHandlingPolicy(),
+					compilerOptions,
+					getRequestor(),
+					problemFactory,
+					monitor,
+					javaProject != null);
+			boolean analyzeAndGenerateCode = !ignoreMethodBodies;
+			unit =
+				resolver.resolve(
+					null, // no existing compilation unit declaration
+					sourceUnit,
+					nodeSearcher,
+					true, // method verification
+					analyzeAndGenerateCode, // analyze code
+					analyzeAndGenerateCode); // generate code
+			if (resolver.hasCompilationAborted) {
+				// the bindings could not be resolved due to missing types in name environment
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=86541
+				CompilationUnitDeclaration unitDeclaration = parse(sourceUnit, nodeSearcher, options, flags);
+				if (unit != null) {
+					final int problemCount = unit.compilationResult.problemCount;
+					if (problemCount != 0) {
+						unitDeclaration.compilationResult.problems = new CategorizedProblem[problemCount];
+						System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount);
+						unitDeclaration.compilationResult.problemCount = problemCount;
+					}
+				} else if (resolver.abortProblem != null) {
+					unitDeclaration.compilationResult.problemCount = 1;
+					unitDeclaration.compilationResult.problems = new CategorizedProblem[] { resolver.abortProblem };
+				}
+				return unitDeclaration;
+			}
+			if (NameLookup.VERBOSE && environment instanceof CancelableNameEnvironment) {
+				CancelableNameEnvironment cancelableNameEnvironment = (CancelableNameEnvironment) environment;
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + cancelableNameEnvironment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			return unit;
+		} finally {
+			if (environment != null) {
+				// don't hold a reference to this external object
+				environment.setMonitor(null);
+			}
+			if (problemFactory != null) {
+				problemFactory.monitor = null; // don't hold a reference to this external object
+			}
+		}
+	}
+	public static IBinding[] resolve(
+		final IJavaElement[] elements,
+		int apiLevel,
+		Map compilerOptions,
+		IJavaProject javaProject,
+		WorkingCopyOwner owner,
+		int flags,
+		IProgressMonitor monitor) {
+
+		final int length = elements.length;
+		final HashMap sourceElementPositions = new HashMap(); // a map from ICompilationUnit to int[] (positions in elements)
+		int cuNumber = 0;
+		final HashtableOfObjectToInt binaryElementPositions = new HashtableOfObjectToInt(); // a map from String (binding key) to int (position in elements)
+		for (int i = 0; i < length; i++) {
+			IJavaElement element = elements[i];
+			if (!(element instanceof SourceRefElement))
+				throw new IllegalStateException(element + " is not part of a compilation unit or class file"); //$NON-NLS-1$
+			Object cu = element.getAncestor(IJavaElement.COMPILATION_UNIT);
+			if (cu != null) {
+				// source member
+				IntArrayList intList = (IntArrayList) sourceElementPositions.get(cu);
+				if (intList == null) {
+					sourceElementPositions.put(cu, intList = new IntArrayList());
+					cuNumber++;
+				}
+				intList.add(i);
+			} else {
+				// binary member
+				try {
+					String key = ((BinaryMember) element).getKey(true/*open to get resolved info*/);
+					binaryElementPositions.put(key, i);
+				} catch (JavaModelException e) {
+					throw new IllegalArgumentException(element + " does not exist"); //$NON-NLS-1$
+				}
+			}
+		}
+		ICompilationUnit[] cus = new ICompilationUnit[cuNumber];
+		sourceElementPositions.keySet().toArray(cus);
+
+		int bindingKeyNumber = binaryElementPositions.size();
+		String[] bindingKeys = new String[bindingKeyNumber];
+		binaryElementPositions.keysToArray(bindingKeys);
+
+		class Requestor extends ASTRequestor {
+			IBinding[] bindings = new IBinding[length];
+			public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
+				// TODO (jerome) optimize to visit the AST only once
+				IntArrayList intList = (IntArrayList) sourceElementPositions.get(source);
+				for (int i = 0; i < intList.length; i++) {
+					final int index = intList.list[i];
+					SourceRefElement element = (SourceRefElement) elements[index];
+					DOMFinder finder = new DOMFinder(ast, element, true/*resolve binding*/);
+					try {
+						finder.search();
+					} catch (JavaModelException e) {
+						throw new IllegalArgumentException(element + " does not exist"); //$NON-NLS-1$
+					}
+					this.bindings[index] = finder.foundBinding;
+				}
+			}
+			public void acceptBinding(String bindingKey, IBinding binding) {
+				int index = binaryElementPositions.get(bindingKey);
+				this.bindings[index] = binding;
+			}
+		}
+		Requestor requestor = new Requestor();
+		resolve(cus, bindingKeys, requestor, apiLevel, compilerOptions, javaProject, owner, flags, monitor);
+		return requestor.bindings;
+	}
+	/*
+	 * When unit result is about to be accepted, removed back pointers
+	 * to unresolved bindings
+	 */
+	public void removeUnresolvedBindings(CompilationUnitDeclaration compilationUnitDeclaration) {
+		final org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+		if (types != null) {
+			for (int i = 0, max = types.length; i < max; i++) {
+				removeUnresolvedBindings(types[i]);
+			}
+		}
+	}
+	private void removeUnresolvedBindings(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration type) {
+		final org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] memberTypes = type.memberTypes;
+		if (memberTypes != null) {
+			for (int i = 0, max = memberTypes.length; i < max; i++){
+				removeUnresolvedBindings(memberTypes[i]);
+			}
+		}
+		if (type.binding != null && (type.binding.modifiers & ExtraCompilerModifiers.AccUnresolved) != 0) {
+			type.binding = null;
+		}
+
+		final org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields = type.fields;
+		if (fields != null) {
+			for (int i = 0, max = fields.length; i < max; i++){
+				if (fields[i].binding != null && (fields[i].binding.modifiers & ExtraCompilerModifiers.AccUnresolved) != 0) {
+					fields[i].binding = null;
+				}
+			}
+		}
+
+		final AbstractMethodDeclaration[] methods = type.methods;
+		if (methods != null) {
+			for (int i = 0, max = methods.length; i < max; i++){
+				if (methods[i].binding !=  null && (methods[i].binding.modifiers & ExtraCompilerModifiers.AccUnresolved) != 0) {
+					methods[i].binding = null;
+				}
+			}
+		}
+	}
+
+	private void resolve(
+			ICompilationUnit[] compilationUnits,
+			String[] bindingKeys,
+			ASTRequestor astRequestor,
+			int apiLevel,
+			Map compilerOptions,
+			WorkingCopyOwner owner,
+			int flags) {
+
+		// temporarily connect ourselves to the ASTResolver - must disconnect when done
+		astRequestor.compilationUnitResolver = this;
+		this.bindingTables = new DefaultBindingResolver.BindingTables();
+		CompilationUnitDeclaration unit = null;
+		try {
+			int length = compilationUnits.length;
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] sourceUnits = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[length];
+			System.arraycopy(compilationUnits, 0, sourceUnits, 0, length);
+			beginToCompile(sourceUnits, bindingKeys);
+			// process all units (some more could be injected in the loop by the lookup environment)
+			for (int i = 0; i < this.totalUnits; i++) {
+				if (resolvedRequestedSourcesAndKeys(i)) {
+					// no need to keep resolving if no more ASTs and no more binding keys are needed
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=114935
+					// cleanup remaining units
+					for (; i < this.totalUnits; i++) {
+						this.unitsToProcess[i].cleanUp();
+						this.unitsToProcess[i] = null;
+					}
+					break;
+				}
+				unit = this.unitsToProcess[i];
+				try {
+					super.process(unit, i); // this.process(...) is optimized to not process already known units
+
+					// requested AST
+					char[] fileName = unit.compilationResult.getFileName();
+					ICompilationUnit source = (ICompilationUnit) this.requestedSources.get(fileName);
+					if (source != null) {
+						// convert AST
+						CompilationResult compilationResult = unit.compilationResult;
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationResult.compilationUnit;
+						char[] contents = sourceUnit.getContents();
+						AST ast = AST.newAST(apiLevel);
+						ast.setFlag(flags | AST.RESOLVED_BINDINGS);
+						ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+						ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, this.monitor);
+						BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, this.fromJavaProject);
+						ast.setBindingResolver(resolver);
+						converter.setAST(ast);
+						CompilationUnit compilationUnit = converter.convert(unit, contents);
+						compilationUnit.setTypeRoot(source);
+						compilationUnit.setLineEndTable(compilationResult.getLineSeparatorPositions());
+						ast.setDefaultNodeFlag(0);
+						ast.setOriginalModificationCount(ast.modificationCount());
+
+						// pass it to requestor
+						astRequestor.acceptAST(source, compilationUnit);
+
+						worked(1);
+
+						// remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested
+						this.requestedSources.put(fileName, null); // mark it as removed
+					}
+
+					// requested binding
+					Object key = this.requestedKeys.get(fileName);
+					if (key != null) {
+						if (key instanceof BindingKeyResolver) {
+							reportBinding(key, astRequestor, owner, unit);
+							worked(1);
+						} else if (key instanceof ArrayList) {
+							Iterator iterator = ((ArrayList) key).iterator();
+							while (iterator.hasNext()) {
+								reportBinding(iterator.next(), astRequestor, owner, unit);
+								worked(1);
+							}
+						}
+
+						// remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested
+						this.requestedKeys.put(fileName, null); // mark it as removed
+					}
+				} finally {
+					// cleanup compilation unit result
+					unit.cleanUp();
+				}
+				this.unitsToProcess[i] = null; // release reference to processed unit declaration
+				this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+			}
+
+			// remaining binding keys
+			DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, owner, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, true);
+			Object[] keys = this.requestedKeys.valueTable;
+			for (int j = 0, keysLength = keys.length; j < keysLength; j++) {
+				BindingKeyResolver keyResolver = (BindingKeyResolver) keys[j];
+				if (keyResolver == null) continue;
+				Binding compilerBinding = keyResolver.getCompilerBinding();
+				IBinding binding = compilerBinding == null ? null : resolver.getBinding(compilerBinding);
+				// pass it to requestor
+				astRequestor.acceptBinding(((BindingKeyResolver) this.requestedKeys.valueTable[j]).getKey(), binding);
+				worked(1);
+			}
+		} catch (OperationCanceledException e) {
+			throw e;
+		} catch (AbortCompilation e) {
+			this.handleInternalException(e, unit);
+		} catch (Error e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} catch (RuntimeException e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} finally {
+			// disconnect ourselves from ast requestor
+			astRequestor.compilationUnitResolver = null;
+		}
+	}
+
+	private void resolve(
+			String[] sourceCompilationUnits,
+			String[] encodings,
+			String[] bindingKeys,
+			FileASTRequestor astRequestor,
+			int apiLevel,
+			Map compilerOptions,
+			int flags) {
+
+		// temporarily connect ourselves to the ASTResolver - must disconnect when done
+		astRequestor.compilationUnitResolver = this;
+		this.bindingTables = new DefaultBindingResolver.BindingTables();
+		CompilationUnitDeclaration unit = null;
+		try {
+			int length = sourceCompilationUnits.length;
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] sourceUnits = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[length];
+			int count = 0;
+			for (int i = 0; i < length; i++) {
+				char[] contents = null;
+				String encoding = encodings != null ? encodings[i] : null;
+				String sourceUnitPath = sourceCompilationUnits[i];
+				try {
+					contents = Util.getFileCharContent(new File(sourceUnitPath), encoding);
+				} catch(IOException e) {
+					// go to the next unit
+					continue;
+				}
+				if (contents == null) {
+					// go to the next unit
+					continue;
+				}
+				sourceUnits[count++] = new org.eclipse.jdt.internal.compiler.batch.CompilationUnit(contents, sourceUnitPath, encoding);
+			}
+			beginToCompile(sourceUnits, bindingKeys);
+			// process all units (some more could be injected in the loop by the lookup environment)
+			for (int i = 0; i < this.totalUnits; i++) {
+				if (resolvedRequestedSourcesAndKeys(i)) {
+					// no need to keep resolving if no more ASTs and no more binding keys are needed
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=114935
+					// cleanup remaining units
+					for (; i < this.totalUnits; i++) {
+						this.unitsToProcess[i].cleanUp();
+						this.unitsToProcess[i] = null;
+					}
+					break;
+				}
+				unit = this.unitsToProcess[i];
+				try {
+					super.process(unit, i); // this.process(...) is optimized to not process already known units
+
+					// requested AST
+					char[] fileName = unit.compilationResult.getFileName();
+					org.eclipse.jdt.internal.compiler.env.ICompilationUnit source = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.requestedSources.get(fileName);
+					if (source != null) {
+						// convert AST
+						CompilationResult compilationResult = unit.compilationResult;
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationResult.compilationUnit;
+						char[] contents = sourceUnit.getContents();
+						AST ast = AST.newAST(apiLevel);
+						ast.setFlag(flags | AST.RESOLVED_BINDINGS);
+						ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+						ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, this.monitor);
+						BindingResolver resolver = new DefaultBindingResolver(unit.scope, null, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, this.fromJavaProject);
+						ast.setBindingResolver(resolver);
+						converter.setAST(ast);
+						CompilationUnit compilationUnit = converter.convert(unit, contents);
+						compilationUnit.setTypeRoot(null);
+						compilationUnit.setLineEndTable(compilationResult.getLineSeparatorPositions());
+						ast.setDefaultNodeFlag(0);
+						ast.setOriginalModificationCount(ast.modificationCount());
+
+						// pass it to requestor
+						astRequestor.acceptAST(new String(source.getFileName()), compilationUnit);
+
+						worked(1);
+
+						// remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested
+						this.requestedSources.put(fileName, null); // mark it as removed
+					}
+
+					// requested binding
+					Object key = this.requestedKeys.get(fileName);
+					if (key != null) {
+						if (key instanceof BindingKeyResolver) {
+							reportBinding(key, astRequestor, unit);
+							worked(1);
+						} else if (key instanceof ArrayList) {
+							Iterator iterator = ((ArrayList) key).iterator();
+							while (iterator.hasNext()) {
+								reportBinding(iterator.next(), astRequestor, unit);
+								worked(1);
+							}
+						}
+
+						// remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested
+						this.requestedKeys.put(fileName, null); // mark it as removed
+					}
+				} finally {
+					// cleanup compilation unit result
+					unit.cleanUp();
+				}
+				this.unitsToProcess[i] = null; // release reference to processed unit declaration
+				this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+			}
+
+			// remaining binding keys
+			DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null, this.bindingTables, (flags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0, true);
+			Object[] keys = this.requestedKeys.valueTable;
+			for (int j = 0, keysLength = keys.length; j < keysLength; j++) {
+				BindingKeyResolver keyResolver = (BindingKeyResolver) keys[j];
+				if (keyResolver == null) continue;
+				Binding compilerBinding = keyResolver.getCompilerBinding();
+				IBinding binding = compilerBinding == null ? null : resolver.getBinding(compilerBinding);
+				// pass it to requestor
+				astRequestor.acceptBinding(((BindingKeyResolver) this.requestedKeys.valueTable[j]).getKey(), binding);
+				worked(1);
+			}
+		} catch (OperationCanceledException e) {
+			throw e;
+		} catch (AbortCompilation e) {
+			this.handleInternalException(e, unit);
+		} catch (Error e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} catch (RuntimeException e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} finally {
+			// disconnect ourselves from ast requestor
+			astRequestor.compilationUnitResolver = null;
+		}
+	}
+
+	private void reportBinding(Object key, ASTRequestor astRequestor, WorkingCopyOwner owner, CompilationUnitDeclaration unit) {
+		BindingKeyResolver keyResolver = (BindingKeyResolver) key;
+		Binding compilerBinding = keyResolver.getCompilerBinding();
+		if (compilerBinding != null) {
+			DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables, false, this.fromJavaProject);
+			AnnotationBinding annotationBinding = keyResolver.getAnnotationBinding();
+			IBinding binding;
+			if (annotationBinding != null) {
+				binding = resolver.getAnnotationInstance(annotationBinding);
+			} else {
+				binding = resolver.getBinding(compilerBinding);
+			}
+			if (binding != null)
+				astRequestor.acceptBinding(keyResolver.getKey(), binding);
+		}
+	}
+
+	private void reportBinding(Object key, FileASTRequestor astRequestor, CompilationUnitDeclaration unit) {
+		BindingKeyResolver keyResolver = (BindingKeyResolver) key;
+		Binding compilerBinding = keyResolver.getCompilerBinding();
+		if (compilerBinding != null) {
+			DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, null, this.bindingTables, false, this.fromJavaProject);
+			AnnotationBinding annotationBinding = keyResolver.getAnnotationBinding();
+			IBinding binding;
+			if (annotationBinding != null) {
+				binding = resolver.getAnnotationInstance(annotationBinding);
+			} else {
+				binding = resolver.getBinding(compilerBinding);
+			}
+			if (binding != null)
+				astRequestor.acceptBinding(keyResolver.getKey(), binding);
+		}
+	}
+
+	private CompilationUnitDeclaration resolve(
+			CompilationUnitDeclaration unit,
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
+			NodeSearcher nodeSearcher,
+			boolean verifyMethods,
+			boolean analyzeCode,
+			boolean generateCode) {
+
+		try {
+
+			if (unit == null) {
+				// build and record parsed units
+				this.parseThreshold = 0; // will request a full parse
+				beginToCompile(new org.eclipse.jdt.internal.compiler.env.ICompilationUnit[] { sourceUnit });
+				// find the right unit from what was injected via accept(ICompilationUnit,..):
+				for (int i=0, max = this.totalUnits; i < max; i++) {
+					CompilationUnitDeclaration currentCompilationUnitDeclaration = this.unitsToProcess[i];
+					if (currentCompilationUnitDeclaration != null
+							&& currentCompilationUnitDeclaration.compilationResult.compilationUnit == sourceUnit) {
+						unit = currentCompilationUnitDeclaration;
+						break;
+					}
+				}
+				if (unit == null) {
+					unit = this.unitsToProcess[0]; // fall back to old behavior
+				}
+			} else {
+				// initial type binding creation
+				this.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);
+
+				// binding resolution
+				this.lookupEnvironment.completeTypeBindings();
+			}
+
+			if (nodeSearcher == null) {
+				this.parser.getMethodBodies(unit); // no-op if method bodies have already been parsed
+			} else {
+				int searchPosition = nodeSearcher.position;
+				char[] source = sourceUnit.getContents();
+				int length = source.length;
+				if (searchPosition >= 0 && searchPosition <= length) {
+					unit.traverse(nodeSearcher, unit.scope);
+
+					org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodeSearcher.found;
+
+		 			if (node != null) {
+						// save existing values to restore them at the end of the parsing process
+						// see bug 47079 for more details
+						int[] oldLineEnds = this.parser.scanner.lineEnds;
+						int oldLinePtr = this.parser.scanner.linePtr;
+
+						this.parser.scanner.setSource(source, unit.compilationResult);
+
+						org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingTypeDeclaration = nodeSearcher.enclosingType;
+						if (node instanceof AbstractMethodDeclaration) {
+							((AbstractMethodDeclaration)node).parseStatements(this.parser, unit);
+						} else if (enclosingTypeDeclaration != null) {
+							if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
+								((org.eclipse.jdt.internal.compiler.ast.Initializer) node).parseStatements(this.parser, enclosingTypeDeclaration, unit);
+							} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+								((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)node).parseMethods(this.parser, unit);
+							}
+						}
+						// this is done to prevent any side effects on the compilation unit result
+						// line separator positions array.
+						this.parser.scanner.lineEnds = oldLineEnds;
+						this.parser.scanner.linePtr = oldLinePtr;
+					}
+				}
+			}
+
+			if (unit.scope != null) {
+				// fault in fields & methods
+				unit.scope.faultInTypes();
+				if (unit.scope != null && verifyMethods) {
+					// http://dev.eclipse.org/bugs/show_bug.cgi?id=23117
+ 					// verify inherited methods
+					unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
+				}
+				// type checking
+				unit.resolve();
+
+				// flow analysis
+				if (analyzeCode) unit.analyseCode();
+
+				// code generation
+				if (generateCode) unit.generateCode();
+
+				// finalize problems (suppressWarnings)
+				unit.finalizeProblems();
+			}
+			if (this.unitsToProcess != null) this.unitsToProcess[0] = null; // release reference to processed unit declaration
+			this.requestor.acceptResult(unit.compilationResult.tagAsAccepted());
+			return unit;
+		} catch (AbortCompilation e) {
+			this.handleInternalException(e, unit);
+			return unit == null ? this.unitsToProcess[0] : unit;
+		} catch (Error e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} catch (RuntimeException e) {
+			this.handleInternalException(e, unit, null);
+			throw e; // rethrow
+		} finally {
+			// No reset is performed there anymore since,
+			// within the CodeAssist (or related tools),
+			// the compiler may be called *after* a call
+			// to this resolve(...) method. And such a call
+			// needs to have a compiler with a non-empty
+			// environment.
+			// this.reset();
+		}
+	}
+	/*
+	 * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
+	 */
+	public CompilationUnitDeclaration resolve(
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
+			boolean verifyMethods,
+			boolean analyzeCode,
+			boolean generateCode) {
+
+		return resolve(
+			null, /* no existing compilation unit declaration*/
+			sourceUnit,
+			null/*no node searcher*/,
+			verifyMethods,
+			analyzeCode,
+			generateCode);
+	}
+
+	boolean resolvedRequestedSourcesAndKeys(int unitIndexToProcess) {
+		if (unitIndexToProcess < this.requestedSources.size() && unitIndexToProcess < this.requestedKeys.size())
+			return false; // must process at least this many units before checking to see if all are done
+
+		Object[] sources = this.requestedSources.valueTable;
+		for (int i = 0, l = sources.length; i < l; i++)
+			if (sources[i] != null) return false;
+		Object[] keys = this.requestedKeys.valueTable;
+		for (int i = 0, l = keys.length; i < l; i++)
+			if (keys[i] != null) return false;
+		return true;
+	}
+
+	/*
+	 * Internal API used to resolve a given compilation unit. Can run a subset of the compilation process
+	 */
+	public CompilationUnitDeclaration resolve(
+			CompilationUnitDeclaration unit,
+			org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit,
+			boolean verifyMethods,
+			boolean analyzeCode,
+			boolean generateCode) {
+
+		return resolve(
+			unit,
+			sourceUnit,
+			null/*no node searcher*/,
+			verifyMethods,
+			analyzeCode,
+			generateCode);
+	}
+
+	private void worked(int work) {
+		if (this.monitor != null) {
+			if (this.monitor.isCanceled())
+				throw new OperationCanceledException();
+			this.monitor.worked(work);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java
new file mode 100644
index 0000000..84696c6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Conditional expression AST node type.
+ *
+ * <pre>
+ * ConditionalExpression:
+ *    Expression <b>?</b> Expression <b>:</b> Expression
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ConditionalExpression extends Expression {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ConditionalExpression.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "thenExpression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor THEN_EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ConditionalExpression.class, "thenExpression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "elseExpression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor ELSE_EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ConditionalExpression.class, "elseExpression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(ConditionalExpression.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(THEN_EXPRESSION_PROPERTY, properyList);
+		addProperty(ELSE_EXPRESSION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The condition expression; lazily initialized; defaults to an unspecified,
+	 * but legal, expression.
+	 */
+	private Expression conditionExpression = null;
+
+	/**
+	 * The "then" expression; lazily initialized; defaults to an unspecified,
+	 * but legal, expression.
+	 */
+	private Expression thenExpression = null;
+
+	/**
+	 * The "else" expression; lazily initialized; defaults to an unspecified,
+	 * but legal, expression.
+	 */
+	private Expression elseExpression = null;
+
+	/**
+	 * Creates a new unparented conditional expression node owned by the given
+	 * AST. By default, the condition, "then", and "else" expresssions are
+	 * unspecified, but legal.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ConditionalExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == THEN_EXPRESSION_PROPERTY) {
+			if (get) {
+				return getThenExpression();
+			} else {
+				setThenExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == ELSE_EXPRESSION_PROPERTY) {
+			if (get) {
+				return getElseExpression();
+			} else {
+				setElseExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CONDITIONAL_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ConditionalExpression result = new ConditionalExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setThenExpression(
+			(Expression) getThenExpression().clone(target));
+		result.setElseExpression(
+			(Expression) getElseExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getThenExpression());
+			acceptChild(visitor, getElseExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the condition of this conditional expression.
+	 *
+	 * @return the condition node
+	 */
+	public Expression getExpression() {
+		if (this.conditionExpression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.conditionExpression == null) {
+					preLazyInit();
+					this.conditionExpression = new SimpleName(this.ast);
+					postLazyInit(this.conditionExpression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.conditionExpression;
+	}
+
+	/**
+	 * Sets the condition of this conditional expression.
+	 *
+	 * @param expression the condition node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.conditionExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.conditionExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the "then" part of this conditional expression.
+	 *
+	 * @return the "then" expression node
+	 */
+	public Expression getThenExpression() {
+		if (this.thenExpression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.thenExpression == null) {
+					preLazyInit();
+					this.thenExpression = new SimpleName(this.ast);
+					postLazyInit(this.thenExpression, THEN_EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.thenExpression;
+	}
+
+	/**
+	 * Sets the "then" part of this conditional expression.
+	 *
+	 * @param expression the "then" expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setThenExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.thenExpression;
+		preReplaceChild(oldChild, expression, THEN_EXPRESSION_PROPERTY);
+		this.thenExpression = expression;
+		postReplaceChild(oldChild, expression, THEN_EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the "else" part of this conditional expression.
+	 *
+	 * @return the "else" expression node
+	 */
+	public Expression getElseExpression() {
+		if (this.elseExpression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.elseExpression == null) {
+					preLazyInit();
+					this.elseExpression = new SimpleName(this.ast);
+					postLazyInit(this.elseExpression, ELSE_EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.elseExpression;
+	}
+
+	/**
+	 * Sets the "else" part of this conditional expression.
+	 *
+	 * @param expression the "else" expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setElseExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.elseExpression;
+		preReplaceChild(oldChild, expression, ELSE_EXPRESSION_PROPERTY);
+		this.elseExpression = expression;
+		postReplaceChild(oldChild, expression, ELSE_EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.conditionExpression == null ? 0 : getExpression().treeSize())
+			+ (this.thenExpression == null ? 0 : getThenExpression().treeSize())
+			+ (this.elseExpression == null ? 0 : getElseExpression().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java
new file mode 100644
index 0000000..3263777
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Alternate constructor invocation statement AST node type.
+ * <pre>
+ * ConstructorInvocation:
+ *    [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *            <b>this</b> <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ConstructorInvocation extends Statement {
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(ConstructorInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(ConstructorInvocation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(ConstructorInvocation.class, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(3);
+		createPropertyList(ConstructorInvocation.class, properyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeArguments = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for an alternate constructor invocation statement
+	 * owned by the given AST. By default, an empty list of arguments.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ConstructorInvocation(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CONSTRUCTOR_INVOCATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ConstructorInvocation result = new ConstructorInvocation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		}
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.typeArguments);
+			}
+			acceptChildren(visitor, this.arguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this constructor
+	 * invocation (added in JLS3 API).
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeArguments() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeArguments == null) {
+			unsupportedIn2();
+		}
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this alternate
+	 * constructor invocation statement.
+	 *
+	 * @return the live list of argument expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor invoked by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the constructor binding, or <code>null</code> if the binding
+	 *    cannot be resolved
+	 */
+	public IMethodBinding resolveConstructorBinding() {
+		return this.ast.getBindingResolver().resolveConstructor(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.arguments == null ? 0 : this.arguments.listSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java
new file mode 100644
index 0000000..08a5bc3
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Continue statement AST node type.
+ *
+ * <pre>
+ * ContinueStatement:
+ *    <b>continue</b> [ Identifier ] <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ContinueStatement extends Statement {
+
+	/**
+	 * The "label" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LABEL_PROPERTY =
+		new ChildPropertyDescriptor(ContinueStatement.class, "label", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(ContinueStatement.class, properyList);
+		addProperty(LABEL_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The label, or <code>null</code> if none; none by default.
+	 */
+	private SimpleName optionalLabel = null;
+
+	/**
+	 * Creates a new unparented continue statement node owned by the given
+	 * AST. By default, the continue statement has no label.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ContinueStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LABEL_PROPERTY) {
+			if (get) {
+				return getLabel();
+			} else {
+				setLabel((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CONTINUE_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ContinueStatement result = new ContinueStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setLabel((SimpleName) ASTNode.copySubtree(target, getLabel()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getLabel());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the label of this continue statement, or <code>null</code> if
+	 * there is none.
+	 *
+	 * @return the label, or <code>null</code> if there is none
+	 */
+	public SimpleName getLabel() {
+		return this.optionalLabel;
+	}
+
+	/**
+	 * Sets or clears the label of this continue statement.
+	 *
+	 * @param label the label, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setLabel(SimpleName label) {
+		ASTNode oldChild = this.optionalLabel;
+		preReplaceChild(oldChild, label, LABEL_PROPERTY);
+		this.optionalLabel = label;
+		postReplaceChild(oldChild, label, LABEL_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalLabel == null ? 0 : getLabel().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java
new file mode 100644
index 0000000..13602f0
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CreationReference.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Creation reference expression AST node type (added in JLS8 API).
+ * 
+ * <pre>
+ * CreationReference:
+ *     Type <b>::</b> 
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         <b>new</b>
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CreationReference extends MethodReference {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(CreationReference.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) 
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		internalTypeArgumentsFactory(CreationReference.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(CreationReference.class, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The type; lazily initialized; defaults to an unspecified type.
+	 */
+	private Type type = null;
+
+	/**
+	 * Creates a new AST node for an CreationReference declaration owned
+	 * by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	CreationReference(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on MethodReference.
+	 */
+	final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+		return TYPE_ARGUMENTS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return CREATION_REFERENCE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		CreationReference result = new CreationReference(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) ASTNode.copySubtree(target, getType()));
+		result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.typeArguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type of this creation reference expression.
+	 *
+	 * @return the type node
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = new SimpleType(this.ast);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type of this creation reference expression.
+	 *
+	 * @param type the new type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this creation reference expression.
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
new file mode 100644
index 0000000..c8bffe5
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
@@ -0,0 +1,624 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+/**
+ */
+class DefaultASTVisitor extends ASTVisitor {
+	/**
+	 *
+	 */
+	public DefaultASTVisitor() {
+		super();
+	}
+
+	/**
+	 *
+	 */
+	public DefaultASTVisitor(boolean visitDocTags) {
+		super(visitDocTags);
+	}
+
+	public void endVisit(AnnotationTypeDeclaration node) {
+		endVisitNode(node);
+	}
+
+	public void endVisit(AnnotationTypeMemberDeclaration node) {
+		endVisitNode(node);
+	}
+
+	public void endVisit(AnonymousClassDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ArrayAccess node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ArrayCreation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ArrayInitializer node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ArrayType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(AssertStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(Assignment node) {
+		endVisitNode(node);
+	}
+	public void endVisit(Block node) {
+		endVisitNode(node);
+	}
+	/* since 3.0 */
+	public void endVisit(BlockComment node) {
+		endVisitNode(node);
+	}
+	public void endVisit(BooleanLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(BreakStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(CastExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(CatchClause node) {
+		endVisitNode(node);
+	}
+	public void endVisit(CharacterLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ClassInstanceCreation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(CompilationUnit node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ConditionalExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ConstructorInvocation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ContinueStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(CreationReference node) {
+		endVisitNode(node);
+	}
+	public void endVisit(DoStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(EmptyStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(EnhancedForStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(EnumConstantDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(EnumDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ExpressionMethodReference node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ExpressionStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ExtraDimension node) {
+		endVisitNode(node);
+	}
+	public void endVisit(FieldAccess node) {
+		endVisitNode(node);
+	}
+	public void endVisit(FieldDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ForStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(IfStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ImportDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(InfixExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(Initializer node) {
+		endVisitNode(node);
+	}
+	public void endVisit(InstanceofExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(IntersectionType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(Javadoc node) {
+		endVisitNode(node);
+	}
+	public void endVisit(LabeledStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(LambdaExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(LineComment node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MarkerAnnotation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MemberRef node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MemberValuePair node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MethodDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MethodInvocation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MethodRef node) {
+		endVisitNode(node);
+	}
+	public void endVisit(MethodRefParameter node) {
+		endVisitNode(node);
+	}
+	public void endVisit(Modifier node) {
+		endVisitNode(node);
+	}
+	public void endVisit(NormalAnnotation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(NullLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(NumberLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(PackageDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(PackageQualifiedType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ParameterizedType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ParenthesizedExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(PostfixExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(PrefixExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(PrimitiveType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(QualifiedName node) {
+		endVisitNode(node);
+	}
+	public void endVisit(QualifiedType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ReturnStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SimpleName node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SimpleType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SingleMemberAnnotation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SingleVariableDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(StringLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SuperConstructorInvocation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SuperFieldAccess node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SuperMethodInvocation node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SuperMethodReference node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SwitchCase node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SwitchStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(SynchronizedStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TagElement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TextElement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ThisExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(ThrowStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TryStatement node) {
+		endVisitNode(node);
+	}
+
+	public void endVisit(TypeDeclaration node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TypeDeclarationStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TypeLiteral node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TypeMethodReference node) {
+		endVisitNode(node);
+	}
+	public void endVisit(TypeParameter node) {
+		endVisitNode(node);
+	}
+	public void endVisit(UnionType node) {
+		endVisitNode(node);
+	}
+	public void endVisit(VariableDeclarationExpression node) {
+		endVisitNode(node);
+	}
+	public void endVisit(VariableDeclarationFragment node) {
+		endVisitNode(node);
+	}
+	public void endVisit(VariableDeclarationStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(WhileStatement node) {
+		endVisitNode(node);
+	}
+	public void endVisit(WildcardType node) {
+		endVisitNode(node);
+	}
+	protected void endVisitNode(ASTNode node) {
+		// do nothing
+	}
+	public boolean visit(AnnotationTypeDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(AnonymousClassDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(ArrayAccess node) {
+		return visitNode(node);
+	}
+	public boolean visit(ArrayCreation node) {
+		return visitNode(node);
+	}
+	public boolean visit(ArrayInitializer node) {
+		return visitNode(node);
+	}
+	public boolean visit(ArrayType node) {
+		visitNode(node);
+		return false;
+	}
+	public boolean visit(AssertStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(Assignment node) {
+		return visitNode(node);
+	}
+	public boolean visit(Block node) {
+		return visitNode(node);
+	}
+	/* since 3.0 */
+	public boolean visit(BlockComment node) {
+		return visitNode(node);
+	}
+	public boolean visit(BooleanLiteral node) {
+		return visitNode(node);
+	}
+	public boolean visit(BreakStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(CastExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(CatchClause node) {
+		return visitNode(node);
+	}
+	public boolean visit(CharacterLiteral node) {
+		return visitNode(node);
+	}
+	public boolean visit(ClassInstanceCreation node) {
+		return visitNode(node);
+	}
+	public boolean visit(CompilationUnit node) {
+		return visitNode(node);
+	}
+	public boolean visit(ConditionalExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(ConstructorInvocation node) {
+		return visitNode(node);
+	}
+	public boolean visit(ContinueStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(CreationReference node) {
+		return visitNode(node);
+	}
+	public boolean visit(DoStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(EmptyStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(EnhancedForStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(EnumConstantDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(EnumDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(ExpressionMethodReference node) {
+		return visitNode(node);
+	}
+	public boolean visit(ExpressionStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(ExtraDimension node) {
+		return visitNode(node);
+	}
+	public boolean visit(FieldAccess node) {
+		return visitNode(node);
+	}
+	public boolean visit(FieldDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(ForStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(IfStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(ImportDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(InfixExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(Initializer node) {
+		return visitNode(node);
+	}
+	public boolean visit(InstanceofExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(IntersectionType node) {
+		return visitNode(node);
+	}
+	public boolean visit(Javadoc node) {
+		//	do not visit Javadoc tags by default. Use constructor with boolean to enable.
+		if (super.visit(node)) {
+			return visitNode(node);
+		}
+		return false;
+	}
+	public boolean visit(LabeledStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(LambdaExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(LineComment node) {
+		return visitNode(node);
+	}
+	public boolean visit(MarkerAnnotation node) {
+		return visitNode(node);
+	}
+	public boolean visit(MemberRef node) {
+		return visitNode(node);
+	}
+	public boolean visit(MemberValuePair node) {
+		return visitNode(node);
+	}
+	public boolean visit(MethodDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(MethodInvocation node) {
+		return visitNode(node);
+	}
+	public boolean visit(MethodRef node) {
+		return visitNode(node);
+	}
+	public boolean visit(Modifier node) {
+		return visitNode(node);
+	}
+	public boolean visit(MethodRefParameter node) {
+		return visitNode(node);
+	}
+	public boolean visit(NormalAnnotation node) {
+		return visitNode(node);
+	}
+	public boolean visit(NullLiteral node) {
+		return visitNode(node);
+	}
+	public boolean visit(NumberLiteral node) {
+		return visitNode(node);
+	}
+	public boolean visit(PackageDeclaration node) {
+		return visitNode(node);
+	}
+	public boolean visit(PackageQualifiedType node) {
+		return visitNode(node);
+	}
+	public boolean visit(ParameterizedType node) {
+		return visitNode(node);
+	}
+	public boolean visit(ParenthesizedExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(PostfixExpression node) {
+		return visitNode(node);
+	}
+	public boolean visit(PrefixExpression node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(PrimitiveType node) {
+		return visitNode(node);
+	}
+	public boolean visit(QualifiedName node) {
+		return visitNode(node);
+	}
+	public boolean visit(QualifiedType node) {
+		return visitNode(node);
+	}
+	public boolean visit(ReturnStatement node) {
+		return visitNode(node);
+	}
+	public boolean visit(SimpleName node) {
+		return visitNode(node);
+	}
+	public boolean visit(SimpleType node) {
+		return visitNode(node);
+	}
+	public boolean visit(SingleMemberAnnotation node) {
+		return visitNode(node);
+	}
+	public boolean visit(SingleVariableDeclaration node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(StringLiteral node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SuperConstructorInvocation node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SuperFieldAccess node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SuperMethodInvocation node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SuperMethodReference node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SwitchCase node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SwitchStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(SynchronizedStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TagElement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TextElement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(ThisExpression node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(ThrowStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TryStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TypeDeclaration node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TypeDeclarationStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TypeLiteral node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TypeMethodReference node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(TypeParameter node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(UnionType node) {
+		return visitNode(node);
+	}
+	
+	public boolean visit(VariableDeclarationExpression node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(VariableDeclarationFragment node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(VariableDeclarationStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(WhileStatement node) {
+		return visitNode(node);
+	}
+
+	public boolean visit(WildcardType node) {
+		return visitNode(node);
+	}
+
+	protected boolean visitNode(ASTNode node) {
+		return true;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
new file mode 100644
index 0000000..4f266a1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -0,0 +1,1928 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend;
+import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Literal;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Internal class for resolving bindings using old ASTs.
+ * <p>
+ * IMPORTANT: The methods on this class are synchronized. This is required
+ * because there may be multiple clients in separate threads concurrently
+ * reading an AST and asking for bindings for its nodes. These requests all
+ * end up invoking instance methods on this class. There are various internal
+ * tables and caches which are built and maintained in the course of looking
+ * up bindings. To ensure that they remain coherent in the presence of multiple
+ * threads, the methods are synchronized on the DefaultBindingResolver instance.
+ * </p>
+ */
+class DefaultBindingResolver extends BindingResolver {
+
+	/*
+	 * Holds on binding tables that can be shared by several ASTs.
+	 */
+	static class BindingTables {
+
+		/**
+		 * This map is used to get a binding from its binding key.
+		 */
+		Map bindingKeysToBindings;
+		/**
+		 * This map is used to keep the correspondance between new bindings and the
+		 * compiler bindings as well as new annotation instances to their internal counterpart.
+		 * This is an identity map. We should only create one object for one binding or annotation.
+		 */
+		Map compilerBindingsToASTBindings;
+
+		BindingTables() {
+			this.compilerBindingsToASTBindings = new HashMap();
+			this.bindingKeysToBindings = new HashMap();
+		}
+
+	}
+	/**
+	 * This map is used to retrieve the corresponding block scope for a ast node
+	 */
+	Map astNodesToBlockScope;
+
+	/**
+	 * This map is used to get an ast node from its binding (new binding) or DOM
+	 */
+	Map bindingsToAstNodes;
+
+	/*
+	 * The shared binding tables accros ASTs.
+	 */
+	BindingTables bindingTables;
+
+	/**
+	 * This map is used to retrieve an old ast node using the new ast node. This is not an
+	 * identity map, as several nested DOM nodes may be associated with the same "larger"
+	 * compiler AST node.
+	 * E.g., an ArrayAllocationExpression "new MyType[1]" will appear as the right-hand value
+	 * for the SimpleType "MyType", the ArrayType "MyType[1]", and the ArrayCreation "new MyType[1]".
+	 */
+	Map newAstToOldAst;
+
+	/**
+	 * Compilation unit scope
+	 */
+	private CompilationUnitScope scope;
+
+	/**
+	 * The working copy owner that defines the context in which this resolver is creating the bindings.
+	 */
+	WorkingCopyOwner workingCopyOwner;
+
+	/**
+	 * Toggle controlling whether DOM bindings should be created when missing internal compiler bindings..
+	 */
+	boolean isRecoveringBindings;
+	
+	/**
+	 * Set to <code>true</code> if initialized from a java project
+	 */
+	boolean fromJavaProject;
+	
+	/**
+	 * Constructor for DefaultBindingResolver.
+	 */
+	DefaultBindingResolver(CompilationUnitScope scope, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) {
+		this.newAstToOldAst = new HashMap();
+		this.astNodesToBlockScope = new HashMap();
+		this.bindingsToAstNodes = new HashMap();
+		this.bindingTables = bindingTables;
+		this.scope = scope;
+		this.workingCopyOwner = workingCopyOwner;
+		this.isRecoveringBindings = isRecoveringBindings;
+		this.fromJavaProject = fromJavaProject;
+	}
+
+	DefaultBindingResolver(LookupEnvironment lookupEnvironment, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) {
+		this.newAstToOldAst = new HashMap();
+		this.astNodesToBlockScope = new HashMap();
+		this.bindingsToAstNodes = new HashMap();
+		this.bindingTables = bindingTables;
+		this.scope = new CompilationUnitScope(new CompilationUnitDeclaration(null, null, -1), lookupEnvironment);
+		this.workingCopyOwner = workingCopyOwner;
+		this.isRecoveringBindings = isRecoveringBindings;
+		this.fromJavaProject = fromJavaProject;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ASTNode findDeclaringNode(IBinding binding) {
+		if (binding == null) {
+			return null;
+		}
+		if (binding instanceof IMethodBinding) {
+			IMethodBinding methodBinding = (IMethodBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(methodBinding.getMethodDeclaration());
+		} else if (binding instanceof ITypeBinding) {
+			ITypeBinding typeBinding = (ITypeBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(typeBinding.getTypeDeclaration());
+		} else if (binding instanceof IVariableBinding) {
+			IVariableBinding variableBinding = (IVariableBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(variableBinding.getVariableDeclaration());
+		}
+		return (ASTNode) this.bindingsToAstNodes.get(binding);
+	}
+
+	synchronized ASTNode findDeclaringNode(String bindingKey) {
+		if (bindingKey == null) {
+			return null;
+		}
+		Object binding = this.bindingTables.bindingKeysToBindings.get(bindingKey);
+		if (binding == null)
+			return null;
+		return (ASTNode) this.bindingsToAstNodes.get(binding);
+	}
+
+	IBinding getBinding(org.eclipse.jdt.internal.compiler.lookup.Binding binding) {
+		switch (binding.kind()) {
+			case Binding.PACKAGE:
+				return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
+			case Binding.TYPE:
+			case Binding.BASE_TYPE:
+			case Binding.GENERIC_TYPE:
+			case Binding.PARAMETERIZED_TYPE:
+			case Binding.RAW_TYPE:
+				return getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+			case Binding.ARRAY_TYPE:
+			case Binding.TYPE_PARAMETER:
+				return new TypeBinding(this, (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+			case Binding.METHOD:
+				return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding) binding);
+			case Binding.FIELD:
+			case Binding.LOCAL:
+				return getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding);
+		}
+		return null;
+	}
+
+	Util.BindingsToNodesMap getBindingsToNodesMap() {
+		return new Util.BindingsToNodesMap() {
+			public org.eclipse.jdt.internal.compiler.ast.ASTNode get(Binding binding) {
+				return (org.eclipse.jdt.internal.compiler.ast.ASTNode)
+					DefaultBindingResolver.this.newAstToOldAst.get(DefaultBindingResolver.this.bindingsToAstNodes.get(binding));
+			}
+		};
+	}
+
+	synchronized org.eclipse.jdt.internal.compiler.ast.ASTNode getCorrespondingNode(ASTNode currentNode) {
+		return (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(currentNode);
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) {
+ 		if (methodBinding != null && !methodBinding.isValidBinding()) {
+			org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding problemMethodBinding =
+				(org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) methodBinding;
+			methodBinding = problemMethodBinding.closestMatch;
+ 		}
+
+		if (methodBinding != null) {
+			if (!this.isRecoveringBindings && ((methodBinding.tagBits & TagBits.HasMissingType) != 0)) {
+				return null;
+			}
+			IMethodBinding binding = (IMethodBinding) this.bindingTables.compilerBindingsToASTBindings.get(methodBinding);
+			if (binding != null) {
+				return binding;
+			}
+			binding = new MethodBinding(this, methodBinding);
+			this.bindingTables.compilerBindingsToASTBindings.put(methodBinding, binding);
+			return binding;
+		}
+		return null;
+	}
+
+	synchronized IMemberValuePairBinding getMemberValuePairBinding(ElementValuePair valuePair) {
+		if (valuePair == null || valuePair.binding == null) return null;
+		IMemberValuePairBinding binding =
+			(IMemberValuePairBinding) this.bindingTables.compilerBindingsToASTBindings.get(valuePair);
+		if (binding != null)
+			return binding;
+		binding = new MemberValuePairBinding(valuePair, this);
+		this.bindingTables.compilerBindingsToASTBindings.put(valuePair, binding);
+		return binding;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IPackageBinding getPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding) {
+		if (packageBinding == null) {
+			return null;
+		}
+		IPackageBinding binding = (IPackageBinding) this.bindingTables.compilerBindingsToASTBindings.get(packageBinding);
+		if (binding != null) {
+			return binding;
+		}
+		binding = new PackageBinding(packageBinding, this);
+		this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding);
+		return binding;
+	}
+	private int getTypeCount(ParameterizedQualifiedTypeReference typeReference) {
+		TypeReference[][] typeArguments = typeReference.typeArguments;
+		int value = 0;
+		org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = typeReference.annotations;
+		int length = typeReference.tokens.length;	
+		for (int i = 0; i < length; ++i) {
+			if (value != 0 || (typeArguments != null && typeArguments[i] != null) ||
+				(typeAnnotations != null && typeAnnotations[i] != null )) {
+				value++;
+			}
+		}
+		return value;
+	}
+
+	/**
+	 * Returns the new type binding corresponding to the given variable declaration.
+	 * This is used for recovered binding only.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param variableDeclaration the given variable declaration
+	 * @return the new type binding
+	 */
+	synchronized ITypeBinding getTypeBinding(VariableDeclaration variableDeclaration) {
+		ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableDeclaration);
+		if (binding != null) {
+			return binding;
+		}
+		binding = new RecoveredTypeBinding(this, variableDeclaration);
+		this.bindingTables.compilerBindingsToASTBindings.put(variableDeclaration, binding);
+		return binding;
+	}
+
+	/**
+	 * Returns the new type binding corresponding to the given type.
+	 * This is used for recovered binding only.
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param type the given type
+	 * @return the new type binding
+	 */
+	synchronized ITypeBinding getTypeBinding(Type type) {
+		ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(type);
+		if (binding != null) {
+			return binding;
+		}
+		binding = new RecoveredTypeBinding(this, type);
+		this.bindingTables.compilerBindingsToASTBindings.put(type, binding);
+		return binding;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) {
+		if (referenceBinding == null) {
+			return null;
+		} else if (!referenceBinding.isValidBinding()) {
+			switch(referenceBinding.problemId()) {
+				case ProblemReasons.NotVisible :
+				case ProblemReasons.NonStaticReferenceInStaticContext :
+					if (referenceBinding instanceof ProblemReferenceBinding) {
+						ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) referenceBinding;
+						org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding2 = problemReferenceBinding.closestMatch();
+						ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(binding2);
+						if (binding != null) {
+							return binding;
+						}
+						binding = new TypeBinding(this, binding2);
+						this.bindingTables.compilerBindingsToASTBindings.put(binding2, binding);
+						return binding;
+					}
+					break;
+				case ProblemReasons.NotFound :
+					if (!this.isRecoveringBindings) {
+						return null;
+					}
+					ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(referenceBinding);
+					if (binding != null) {
+						return binding;
+					}
+					if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0) {
+						binding = new TypeBinding(this, referenceBinding);
+					} else {
+						binding = new RecoveredTypeBinding(this, referenceBinding);
+					}
+					this.bindingTables.compilerBindingsToASTBindings.put(referenceBinding, binding);
+					return binding;
+			}
+			return null;
+		} else {
+			if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0 && !this.isRecoveringBindings) {
+				return null;
+			}
+			ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(referenceBinding);
+			if (binding != null) {
+				return binding;
+			}
+			binding = new TypeBinding(this, referenceBinding);
+			this.bindingTables.compilerBindingsToASTBindings.put(referenceBinding, binding);
+			return binding;
+		}
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding getTypeBinding(RecoveredTypeBinding recoveredTypeBinding, int dimensions) {
+		if (recoveredTypeBinding== null) {
+			return null;
+		}
+		return new RecoveredTypeBinding(this, recoveredTypeBinding, dimensions);
+	}
+
+	synchronized IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding variableBinding, VariableDeclaration variableDeclaration) {
+		if (this.isRecoveringBindings) {
+			if (variableBinding != null) {
+				if (variableBinding.isValidBinding()) {
+					IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding);
+					if (binding != null) {
+						return binding;
+					}
+					if (variableBinding.type != null) {
+						binding = new VariableBinding(this, variableBinding);
+					} else {
+						binding = new RecoveredVariableBinding(this, variableDeclaration);
+					}
+					this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding);
+					return binding;
+				} else {
+					/*
+					 * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449
+					 */
+					if (variableBinding instanceof ProblemFieldBinding) {
+						ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) variableBinding;
+						switch(problemFieldBinding.problemId()) {
+							case ProblemReasons.NotVisible :
+							case ProblemReasons.NonStaticReferenceInStaticContext :
+							case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+								ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
+								FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/);
+								if (exactBinding != null) {
+									IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+									if (variableBinding2 != null) {
+										return variableBinding2;
+									}
+									variableBinding2 = new VariableBinding(this, exactBinding);
+									this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2);
+									return variableBinding2;
+								}
+								break;
+						}
+					}
+				}
+			}
+			return null;
+		}
+		return this.getVariableBinding(variableBinding);
+	}
+
+	public WorkingCopyOwner getWorkingCopyOwner() {
+		return this.workingCopyOwner;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding variableBinding) {
+		if (variableBinding != null) {
+			if (variableBinding.isValidBinding()) {
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding variableType = variableBinding.type;
+				if (variableType != null) {
+					if (!this.isRecoveringBindings && ((variableType.tagBits & TagBits.HasMissingType) != 0)) {
+						return null;
+					}
+					IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding);
+					if (binding != null) {
+						return binding;
+					}
+					binding = new VariableBinding(this, variableBinding);
+					this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding);
+					return binding;
+				}
+			} else {
+				/*
+				 * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449
+				 */
+				if (variableBinding instanceof ProblemFieldBinding) {
+					ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) variableBinding;
+					switch(problemFieldBinding.problemId()) {
+						case ProblemReasons.NotVisible :
+						case ProblemReasons.NonStaticReferenceInStaticContext :
+						case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+							ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
+							FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/);
+							if (exactBinding != null) {
+								IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+								if (variableBinding2 != null) {
+									return variableBinding2;
+								}
+								variableBinding2 = new VariableBinding(this, exactBinding);
+								this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2);
+								return variableBinding2;
+							}
+							break;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	synchronized IAnnotationBinding getAnnotationInstance(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance) {
+		if (internalInstance == null) return null;
+		ReferenceBinding annotationType = internalInstance.getAnnotationType();
+		if (!this.isRecoveringBindings) {
+			if (annotationType == null || ((annotationType.tagBits & TagBits.HasMissingType) != 0)) {
+				return null;
+			}
+		}
+		IAnnotationBinding domInstance =
+			(IAnnotationBinding) this.bindingTables.compilerBindingsToASTBindings.get(internalInstance);
+		if (domInstance != null)
+			return domInstance;
+		domInstance = new AnnotationBinding(internalInstance, this);
+		this.bindingTables.compilerBindingsToASTBindings.put(internalInstance, domInstance);
+		return domInstance;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(MethodInvocation methodInvocation) {
+		Object oldNode = this.newAstToOldAst.get(methodInvocation);
+		if (oldNode instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) oldNode;
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = messageSend.binding;
+			if (methodBinding instanceof ParameterizedGenericMethodBinding) {
+				ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) methodBinding;
+				return genericMethodBinding.inferredReturnType;
+			}
+		}
+		return false;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(SuperMethodInvocation superMethodInvocation) {
+		Object oldNode = this.newAstToOldAst.get(superMethodInvocation);
+		if (oldNode instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) oldNode;
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = messageSend.binding;
+			if (methodBinding instanceof ParameterizedGenericMethodBinding) {
+				ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) methodBinding;
+				return genericMethodBinding.inferredReturnType;
+			}
+		}
+		return false;
+	}
+
+	boolean isResolvedTypeInferredFromExpectedType(ClassInstanceCreation classInstanceCreation) {
+		Object oldNode = this.newAstToOldAst.get(classInstanceCreation);
+		if (oldNode instanceof AllocationExpression) {
+			AllocationExpression allocationExpression = (AllocationExpression) oldNode;
+			return allocationExpression.inferredReturnType;
+		}
+		return false;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	LookupEnvironment lookupEnvironment() {
+		return this.scope.environment();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#recordScope(ASTNode, BlockScope)
+	 */
+	synchronized void recordScope(ASTNode astNode, BlockScope blockScope) {
+		this.astNodesToBlockScope.put(astNode, blockScope);
+	}
+
+	/*
+	 * @see BindingResolver#resolveBoxing(Expression)
+	 */
+	boolean resolveBoxing(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			return (compilerExpression.implicitConversion & TypeIds.BOXING) != 0;
+		}
+		return false;
+	}
+
+	/*
+	 * @see BindingResolver#resolveUnboxing(Expression)
+	 */
+	boolean resolveUnboxing(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			return (compilerExpression.implicitConversion & TypeIds.UNBOXING) != 0;
+		}
+		return false;
+	}
+
+	/*
+	 * @see BindingResolver#resolveConstantExpressionValue(Expression)
+	 */
+	Object resolveConstantExpressionValue(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			Constant constant = compilerExpression.constant;
+			if (constant != null && constant != Constant.NotAConstant) {
+				switch (constant.typeID()) {
+					case TypeIds.T_int : return new Integer(constant.intValue());
+					case TypeIds.T_byte : return new Byte(constant.byteValue());
+					case TypeIds.T_short : return new Short(constant.shortValue());
+					case TypeIds.T_char : return new Character(constant.charValue());
+					case TypeIds.T_float : return new Float(constant.floatValue());
+					case TypeIds.T_double : return new Double(constant.doubleValue());
+					case TypeIds.T_boolean : return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE;
+					case TypeIds.T_long : return new Long(constant.longValue());
+					case TypeIds.T_JavaLangString : return constant.stringValue();
+				}
+				return null;
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveConstructor(ClassInstanceCreation)
+	 */
+	synchronized IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node != null && (node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousLocalTypeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			return getMethodBinding(anonymousLocalTypeDeclaration.allocation.binding);
+		} else if (node instanceof AllocationExpression) {
+			return getMethodBinding(((AllocationExpression)node).binding);
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveConstructor(ConstructorInvocation)
+	 */
+	synchronized IMethodBinding resolveConstructor(ConstructorInvocation expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node instanceof ExplicitConstructorCall) {
+			ExplicitConstructorCall explicitConstructorCall = (ExplicitConstructorCall) node;
+			return getMethodBinding(explicitConstructorCall.binding);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveConstructor(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
+	 */
+	IMethodBinding resolveConstructor(EnumConstantDeclaration enumConstantDeclaration) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(enumConstantDeclaration);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+			if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT && fieldDeclaration.initialization != null) {
+				AllocationExpression allocationExpression = (AllocationExpression) fieldDeclaration.initialization;
+				return getMethodBinding(allocationExpression.binding);
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveConstructor(SuperConstructorInvocation)
+	 */
+	synchronized IMethodBinding resolveConstructor(SuperConstructorInvocation expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node instanceof ExplicitConstructorCall) {
+			ExplicitConstructorCall explicitConstructorCall = (ExplicitConstructorCall) node;
+			return getMethodBinding(explicitConstructorCall.binding);
+		}
+		return null;
+	}
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding resolveExpressionType(Expression expression) {
+		try {
+			switch(expression.getNodeType()) {
+				case ASTNode.CLASS_INSTANCE_CREATION :
+					org.eclipse.jdt.internal.compiler.ast.ASTNode astNode = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+					if (astNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+						// anonymous type case
+						org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) astNode;
+						ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+						if (typeBinding != null) {
+							return typeBinding;
+						}
+					} else if (astNode instanceof AllocationExpression) {
+						// should be an AllocationExpression
+						AllocationExpression allocationExpression = (AllocationExpression) astNode;
+						return this.getTypeBinding(allocationExpression.resolvedType);
+					}
+					break;
+				case ASTNode.SIMPLE_NAME :
+				case ASTNode.QUALIFIED_NAME :
+					return resolveTypeBindingForName((Name) expression);
+				case ASTNode.ARRAY_INITIALIZER :
+				case ASTNode.ARRAY_CREATION :
+				case ASTNode.ASSIGNMENT :
+				case ASTNode.POSTFIX_EXPRESSION :
+				case ASTNode.PREFIX_EXPRESSION :
+				case ASTNode.CAST_EXPRESSION :
+				case ASTNode.TYPE_LITERAL :
+				case ASTNode.INFIX_EXPRESSION :
+				case ASTNode.INSTANCEOF_EXPRESSION :
+				case ASTNode.LAMBDA_EXPRESSION:
+				case ASTNode.CREATION_REFERENCE:
+				case ASTNode.EXPRESSION_METHOD_REFERENCE:
+				case ASTNode.TYPE_METHOD_REFERENCE:
+				case ASTNode.SUPER_METHOD_REFERENCE :
+				case ASTNode.FIELD_ACCESS :
+				case ASTNode.SUPER_FIELD_ACCESS :
+				case ASTNode.ARRAY_ACCESS :
+				case ASTNode.METHOD_INVOCATION :
+				case ASTNode.SUPER_METHOD_INVOCATION :
+				case ASTNode.CONDITIONAL_EXPRESSION :
+				case ASTNode.MARKER_ANNOTATION :
+				case ASTNode.NORMAL_ANNOTATION :
+				case ASTNode.SINGLE_MEMBER_ANNOTATION :
+					org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(expression);
+					if (compilerExpression != null) {
+						return this.getTypeBinding(compilerExpression.resolvedType);
+					}
+					break;
+				case ASTNode.STRING_LITERAL :
+					if (this.scope != null) {
+						return this.getTypeBinding(this.scope.getJavaLangString());
+					}
+					break;
+				case ASTNode.BOOLEAN_LITERAL :
+				case ASTNode.NULL_LITERAL :
+				case ASTNode.CHARACTER_LITERAL :
+				case ASTNode.NUMBER_LITERAL :
+					Literal literal = (Literal) this.newAstToOldAst.get(expression);
+					if (literal != null) {
+						return this.getTypeBinding(literal.literalType(null));
+					}
+					break;
+				case ASTNode.THIS_EXPRESSION :
+					ThisReference thisReference = (ThisReference) this.newAstToOldAst.get(expression);
+					BlockScope blockScope = (BlockScope) this.astNodesToBlockScope.get(expression);
+					if (blockScope != null) {
+						return this.getTypeBinding(thisReference.resolveType(blockScope));
+					}
+					break;
+				case ASTNode.PARENTHESIZED_EXPRESSION :
+					ParenthesizedExpression parenthesizedExpression = (ParenthesizedExpression) expression;
+					return resolveExpressionType(parenthesizedExpression.getExpression());
+				case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
+					VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) expression;
+					Type type = variableDeclarationExpression.getType();
+					if (type != null) {
+						return type.resolveBinding();
+					}
+					break;
+			}
+		} catch (AbortCompilation e) {
+			// handle missing types
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveField(FieldAccess)
+	 */
+	synchronized IVariableBinding resolveField(FieldAccess fieldAccess) {
+		Object oldNode = this.newAstToOldAst.get(fieldAccess);
+		if (oldNode instanceof FieldReference) {
+			FieldReference fieldReference = (FieldReference) oldNode;
+			return this.getVariableBinding(fieldReference.binding);
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveField(SuperFieldAccess)
+	 */
+	synchronized IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
+		Object oldNode = this.newAstToOldAst.get(fieldAccess);
+		if (oldNode instanceof FieldReference) {
+			FieldReference fieldReference = (FieldReference) oldNode;
+			return this.getVariableBinding(fieldReference.binding);
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolveImport(ImportDeclaration)
+	 */
+	synchronized IBinding resolveImport(ImportDeclaration importDeclaration) {
+		if (this.scope == null) return null;
+		try {
+			org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(importDeclaration);
+			if (node instanceof ImportReference) {
+				ImportReference importReference = (ImportReference) node;
+				final boolean isStatic = importReference.isStatic();
+				if ((importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0) {
+					Binding binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length), true, isStatic);
+					if (binding != null) {
+						if (isStatic) {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;
+							}
+						} else {
+							if ((binding.kind() & Binding.PACKAGE) != 0) {
+								IPackageBinding packageBinding = getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
+								if (packageBinding == null) {
+									return null;
+								}
+								return packageBinding;
+							} else {
+								// if it is not a package, it has to be a type
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								if (typeBinding == null) {
+									return null;
+								}
+								return typeBinding;
+							}
+						}
+					}
+				} else {
+					Binding binding = this.scope.getImport(importReference.tokens, false, isStatic);
+					if (binding != null) {
+						if (isStatic) {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;
+							} else if (binding instanceof FieldBinding) {
+								IVariableBinding variableBinding = this.getVariableBinding((FieldBinding) binding);
+								return variableBinding == null ? null : variableBinding;
+							} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
+								// it is a type
+								return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding);
+							}
+						} else {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;
+							}
+						}
+					}
+				}
+			}
+		} catch(AbortCompilation e) {
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveMember(org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration)
+	 */
+	IMethodBinding resolveMember(AnnotationTypeMemberDeclaration declaration) {
+		Object oldNode = this.newAstToOldAst.get(declaration);
+		if (oldNode instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode;
+			IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding);
+			if (methodBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(methodBinding, declaration);
+			String key = methodBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+			}
+			return methodBinding;
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding resolveMethod(LambdaExpression lambda) {
+		Object oldNode = this.newAstToOldAst.get(lambda);
+		if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) {
+			org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode;
+			IMethodBinding methodBinding = getMethodBinding(lambdaExpression.binding);
+			if (methodBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(methodBinding, lambda);
+			String key = methodBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+			}
+			return methodBinding;
+		}
+		return null;
+	}
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding resolveMethod(MethodDeclaration method) {
+		Object oldNode = this.newAstToOldAst.get(method);
+		if (oldNode instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode;
+			IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding);
+			if (methodBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(methodBinding, method);
+			String key = methodBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+			}
+			return methodBinding;
+		}
+		return null;
+	}
+/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding resolveMethod(MethodInvocation method) {
+		Object oldNode = this.newAstToOldAst.get(method);
+		if (oldNode instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) oldNode;
+			return getMethodBinding(messageSend.binding);
+		}
+		return null;
+	}
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding resolveMethod(MethodReference methodReference) {
+		Object oldNode = this.newAstToOldAst.get(methodReference);
+		if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+			org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) oldNode;
+			IMethodBinding methodBinding = getMethodBinding(referenceExpression.binding);
+			if (methodBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(methodBinding, methodReference);
+			String key = methodBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, methodBinding);
+			}
+			return methodBinding;
+		}
+		return null;
+	}
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IMethodBinding resolveMethod(SuperMethodInvocation method) {
+		Object oldNode = this.newAstToOldAst.get(method);
+		if (oldNode instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) oldNode;
+			return getMethodBinding(messageSend.binding);
+		}
+		return null;
+	}
+
+	synchronized ITypeBinding resolveTypeBindingForName(Name name) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(name);
+		int index = name.index;
+		if (node instanceof QualifiedNameReference) {
+			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node;
+			final char[][] tokens = qualifiedNameReference.tokens;
+			if (tokens.length == index) {
+				return this.getTypeBinding(qualifiedNameReference.resolvedType);
+			}
+			int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based
+			if (index < indexOfFirstFieldBinding) {
+				// an extra lookup is required
+				BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+				Binding binding = null;
+				try {
+					if (internalScope == null) {
+						if (this.scope == null) return null;
+						binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					} else {
+						binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					}
+				} catch (AbortCompilation e) {
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+				}
+				if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+					return null;
+				} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+					// it is a type
+					return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+				}
+			} else if (index == indexOfFirstFieldBinding) {
+				if (qualifiedNameReference.isTypeReference()) {
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
+				} else {
+					// in this case we want to get the next field declaring's class
+					if (qualifiedNameReference.otherBindings == null) {
+						return null;
+					}
+					FieldBinding fieldBinding = qualifiedNameReference.otherBindings[0];
+					if (fieldBinding == null) return null;
+					org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass;
+					if (type == null) { // array length scenario
+						// use type from first binding (no capture needed for array type)
+						switch (qualifiedNameReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.RestrictiveFlagMASK) {
+							case Binding.FIELD:
+								type = ((FieldBinding) qualifiedNameReference.binding).type;
+								break;
+							case Binding.LOCAL:
+								type = ((LocalVariableBinding) qualifiedNameReference.binding).type;
+								break;
+						}
+					}
+					return this.getTypeBinding(type);
+				}
+			} else {
+				/* This is the case for a name which is part of a qualified name that
+				 * cannot be resolved. See PR 13063.
+				 */
+				if (qualifiedNameReference.otherBindings == null) return null;
+				final int otherBindingsLength = qualifiedNameReference.otherBindings.length;
+				if (otherBindingsLength == (index - indexOfFirstFieldBinding)) {
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
+				}
+				FieldBinding fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding];
+				if (fieldBinding == null) return null;
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass;
+				if (type == null) { // array length scenario
+					// use type from previous binding (no capture needed for array type)
+					fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1];
+					if (fieldBinding == null) return null;
+					type = fieldBinding.type;
+				}
+				return this.getTypeBinding(type);
+			}
+		} else if (node instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) node;
+			if (qualifiedTypeReference.resolvedType == null) {
+				return null;
+			}
+			if (index == qualifiedTypeReference.tokens.length) {
+				if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) {
+					JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node;
+					if (typeRef.packageBinding != null) {
+						return null;
+					}
+				}
+				return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType());
+			} else {
+				if (index >= 0) {
+					BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+					Binding binding = null;
+					try {
+						if (internalScope == null) {
+							if (this.scope == null) return null;
+							binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						} else {
+							binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						}
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+						return null;
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					} else {
+						return null;
+					}
+				}
+			}
+		} else if (node instanceof ImportReference) {
+			ImportReference importReference = (ImportReference) node;
+			int importReferenceLength = importReference.tokens.length;
+			if (index >= 0) {
+				Binding binding = null;
+				if (this.scope == null) return null;
+				if (importReferenceLength == index) {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0, importReference.isStatic());
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				} else {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic());
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				}
+				if (binding != null) {
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					}
+					return null;
+				}
+			}
+		} else if (node instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node;
+			IMethodBinding method = getMethodBinding(methodDeclaration.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding != null) {
+				return typeBinding;
+			}
+		} if (node instanceof JavadocSingleNameReference) {
+			JavadocSingleNameReference singleNameReference = (JavadocSingleNameReference) node;
+			LocalVariableBinding localVariable = (LocalVariableBinding)singleNameReference.binding;
+			if (localVariable != null) {
+				return this.getTypeBinding(localVariable.type);
+			}
+		} if (node instanceof SingleNameReference) {
+			SingleNameReference singleNameReference = (SingleNameReference) node;
+			return this.getTypeBinding(singleNameReference.resolvedType);
+		} else if (node instanceof QualifiedSuperReference) {
+			QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) node;
+			return this.getTypeBinding(qualifiedSuperReference.qualification.resolvedType);
+		} else if (node instanceof LocalDeclaration) {
+			IVariableBinding variable = this.getVariableBinding(((LocalDeclaration)node).binding);
+			if (variable == null) return null;
+			return variable.getType();
+		} else if (node instanceof JavadocFieldReference) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) node;
+			if (fieldRef.methodBinding != null) {
+				return getMethodBinding(fieldRef.methodBinding).getReturnType();
+			}
+			return getTypeBinding(fieldRef.resolvedType);
+		} else if (node instanceof FieldReference) {
+			return getTypeBinding(((FieldReference) node).resolvedType);
+		} else if (node instanceof SingleTypeReference) {
+			SingleTypeReference singleTypeReference = (SingleTypeReference) node;
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = singleTypeReference.resolvedType;
+			if (binding != null) {
+				return this.getTypeBinding(binding.leafComponentType());
+			}
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+			IVariableBinding field = this.getVariableBinding(fieldDeclaration.binding);
+			if (field == null) return null;
+			return field.getType();
+		} else if (node instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) node;
+			IMethodBinding method = getMethodBinding(messageSend.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		} else if (node instanceof AllocationExpression) {
+			AllocationExpression allocation = (AllocationExpression) node;
+			return getTypeBinding(allocation.resolvedType);
+		} else if (node instanceof JavadocImplicitTypeReference) {
+			JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node;
+			return getTypeBinding(implicitRef.resolvedType);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) {
+			org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node;
+			return this.getTypeBinding(typeParameter.binding);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) {
+			org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node;
+			IMethodBinding method = getMethodBinding(memberValuePair.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+			org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
+			IMethodBinding method = getMethodBinding(referenceExpression.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IBinding resolveName(Name name) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(name);
+		int index = name.index;
+		if (node instanceof QualifiedNameReference) {
+			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node;
+			final char[][] tokens = qualifiedNameReference.tokens;
+			int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based
+			if (index < indexOfFirstFieldBinding) {
+				// an extra lookup is required
+				BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+				Binding binding = null;
+				try {
+					if (internalScope == null) {
+						if (this.scope == null) return null;
+						binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					} else {
+						binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					}
+				} catch (AbortCompilation e) {
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+				}
+				if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+					return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding);
+				} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+					// it is a type
+					return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+				}
+			} else if (index == indexOfFirstFieldBinding) {
+				if (qualifiedNameReference.isTypeReference()) {
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
+				} else {
+					Binding binding = qualifiedNameReference.binding;
+					if (binding != null) {
+						if (binding.isValidBinding()) {
+							return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding);
+						} else  if (binding instanceof ProblemFieldBinding) {
+							ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding;
+							switch(problemFieldBinding.problemId()) {
+								case ProblemReasons.NotVisible :
+								case ProblemReasons.NonStaticReferenceInStaticContext :
+									ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
+									if (declaringClass != null) {
+										FieldBinding exactBinding = declaringClass.getField(tokens[tokens.length - 1], true /*resolve*/);
+										if (exactBinding != null) {
+											if (exactBinding.type != null) {
+												IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+												if (variableBinding != null) {
+													return variableBinding;
+												}
+												variableBinding = new VariableBinding(this, exactBinding);
+												this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding);
+												return variableBinding;
+											}
+										}
+									}
+									break;
+							}
+						}
+					}
+				}
+			} else {
+				/* This is the case for a name which is part of a qualified name that
+				 * cannot be resolved. See PR 13063.
+				 */
+				if (qualifiedNameReference.otherBindings == null || (index - indexOfFirstFieldBinding - 1) < 0) {
+					return null;
+				} else {
+					return this.getVariableBinding(qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1]);
+				}
+			}
+		} else if (node instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) node;
+			if (qualifiedTypeReference.resolvedType == null) {
+				return null;
+			}
+			if (index == qualifiedTypeReference.tokens.length) {
+				if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) {
+					JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node;
+					if (typeRef.packageBinding != null) {
+						return getPackageBinding(typeRef.packageBinding);
+					}
+				}
+				return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType());
+			} else {
+				if (index >= 0) {
+					BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+					Binding binding = null;
+					try {
+						if (internalScope == null) {
+							if (this.scope == null) return null;
+							binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						} else {
+							binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						}
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+						return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding);
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					} else {
+						return null;
+					}
+				}
+			}
+		} else if (node instanceof ImportReference) {
+			ImportReference importReference = (ImportReference) node;
+			int importReferenceLength = importReference.tokens.length;
+			if (index >= 0) {
+				Binding binding = null;
+				if (this.scope == null) return null;
+				if (importReferenceLength == index) {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0, importReference.isStatic());
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				} else {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic());
+					} catch (AbortCompilation e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				}
+				if (binding != null) {
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+						return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding);
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.FieldBinding) {
+						// it is a type
+						return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.FieldBinding)binding);
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
+						// it is a type
+						return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding);
+					} else {
+						return null;
+					}
+				}
+			}
+		} else if (node instanceof CompilationUnitDeclaration) {
+			CompilationUnitDeclaration compilationUnitDeclaration = (CompilationUnitDeclaration) node;
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+			if (types == null || types.length == 0) {
+				return null;
+			}
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration type = types[0];
+			if (type != null) {
+				ITypeBinding typeBinding = this.getTypeBinding(type.binding);
+				if (typeBinding != null) {
+					return typeBinding.getPackage();
+				}
+			}
+		} else if (node instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node;
+			IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding);
+			if (methodBinding != null) {
+				return methodBinding;
+			}
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding != null) {
+				return typeBinding;
+			}
+		} if (node instanceof SingleNameReference) {
+			SingleNameReference singleNameReference = (SingleNameReference) node;
+			if (singleNameReference.isTypeReference()) {
+				return this.getTypeBinding(singleNameReference.resolvedType);
+			} else {
+				// this is a variable or a field
+				Binding binding = singleNameReference.binding;
+				if (binding != null) {
+					if (binding.isValidBinding()) {
+						return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding);
+					} else {
+						/*
+						 * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449
+						 */
+						if (binding instanceof ProblemFieldBinding) {
+							ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding;
+							switch(problemFieldBinding.problemId()) {
+								case ProblemReasons.NotVisible :
+								case ProblemReasons.NonStaticReferenceInStaticContext :
+								case ProblemReasons.NonStaticReferenceInConstructorInvocation :
+									ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
+									FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/);
+									if (exactBinding != null) {
+										if (exactBinding.type != null) {
+											IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+											if (variableBinding2 != null) {
+												return variableBinding2;
+											}
+											variableBinding2 = new VariableBinding(this, exactBinding);
+											this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2);
+											return variableBinding2;
+										}
+									}
+									break;
+							}
+						}
+					}
+				}
+			}
+		} else if (node instanceof QualifiedSuperReference) {
+			QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) node;
+			return this.getTypeBinding(qualifiedSuperReference.qualification.resolvedType);
+		} else if (node instanceof LocalDeclaration) {
+			return this.getVariableBinding(((LocalDeclaration)node).binding);
+		} else if (node instanceof JavadocFieldReference) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) node;
+			if (fieldRef.methodBinding != null) {
+				return getMethodBinding(fieldRef.methodBinding);
+			}
+			return getVariableBinding(fieldRef.binding);
+		} else if (node instanceof FieldReference) {
+			return getVariableBinding(((FieldReference) node).binding);
+		} else if (node instanceof SingleTypeReference) {
+			if (node instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) node;
+				if (typeRef.packageBinding != null) {
+					return getPackageBinding(typeRef.packageBinding);
+				}
+			}
+			SingleTypeReference singleTypeReference = (SingleTypeReference) node;
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = singleTypeReference.resolvedType;
+			if (binding == null) {
+				return null;
+			}
+			return this.getTypeBinding(binding.leafComponentType());
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+			return this.getVariableBinding(fieldDeclaration.binding);
+		} else if (node instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) node;
+			return getMethodBinding(messageSend.binding);
+		} else if (node instanceof AllocationExpression) {
+			AllocationExpression allocation = (AllocationExpression) node;
+			return getMethodBinding(allocation.binding);
+		} else if (node instanceof JavadocImplicitTypeReference) {
+			JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node;
+			return getTypeBinding(implicitRef.resolvedType);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) {
+			org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node;
+			return this.getTypeBinding(typeParameter.binding);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) {
+			org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node;
+			return getMethodBinding(memberValuePair.binding);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
+			org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node;
+			return getMethodBinding(referenceExpression.binding);
+		}
+		return null;
+	}
+
+	/*
+	 * @see BindingResolver#resolvePackage(PackageDeclaration)
+	 */
+	synchronized IPackageBinding resolvePackage(PackageDeclaration pkg) {
+		if (this.scope == null) return null;
+		try {
+			org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(pkg);
+			if (node instanceof ImportReference) {
+				ImportReference importReference = (ImportReference) node;
+				Binding binding = this.scope.getOnlyPackage(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length));
+				if ((binding != null) && (binding.isValidBinding())) {
+					if (binding instanceof ReferenceBinding) {
+						// this only happens if a type name has the same name as its package
+						ReferenceBinding referenceBinding = (ReferenceBinding) binding;
+						binding = referenceBinding.fPackage;
+					}
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+						IPackageBinding packageBinding = getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
+						if (packageBinding == null) {
+							return null;
+						}
+						this.bindingsToAstNodes.put(packageBinding, pkg);
+						String key = packageBinding.getKey();
+						if (key != null) {
+							this.bindingTables.bindingKeysToBindings.put(key, packageBinding);
+						}
+						return packageBinding;
+					}
+				}
+			}
+		} catch (AbortCompilation e) {
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see BindingResolver#resolveReference(MemberRef)
+     * @since 3.0
+	 */
+	synchronized IBinding resolveReference(MemberRef ref) {
+		org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(ref);
+		if (expression instanceof TypeReference) {
+			return getTypeBinding(expression.resolvedType);
+		} else if (expression instanceof JavadocFieldReference) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) expression;
+			if (fieldRef.methodBinding != null) {
+				return getMethodBinding(fieldRef.methodBinding);
+			}
+			return getVariableBinding(fieldRef.binding);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see BindingResolver#resolveMemberValuePair(MemberValuePair)
+     * @since 3.2
+	 */
+	synchronized IMemberValuePairBinding resolveMemberValuePair(org.eclipse.jdt.core.dom.MemberValuePair memberValuePair) {
+		MemberValuePair valuePair = (MemberValuePair) this.newAstToOldAst.get(memberValuePair);
+		if (valuePair != null) {
+			return getMemberValuePairBinding(valuePair.compilerElementPair);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see BindingResolver#resolveReference(MethodRef)
+     * @since 3.0
+	 */
+	synchronized IBinding resolveReference(MethodRef ref) {
+		org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(ref);
+		if (expression instanceof JavadocMessageSend) {
+			return getMethodBinding(((JavadocMessageSend)expression).binding);
+		}
+		else if (expression instanceof JavadocAllocationExpression) {
+			return getMethodBinding(((JavadocAllocationExpression)expression).binding);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveType(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
+	 */
+	ITypeBinding resolveType(AnnotationTypeDeclaration type) {
+		final Object node = this.newAstToOldAst.get(type);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(typeBinding, type);
+			String key = typeBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+			}
+			return typeBinding;
+		}
+		return null;
+	}
+	/*
+	 * @see BindingResolver#resolveType(AnonymousClassDeclaration)
+	 */
+	synchronized ITypeBinding resolveType(AnonymousClassDeclaration type) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type);
+		if (node != null && (node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousLocalTypeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(anonymousLocalTypeDeclaration.binding);
+			if (typeBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(typeBinding, type);
+			String key = typeBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+			}
+			return typeBinding;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveType(org.eclipse.jdt.core.dom.EnumDeclaration)
+	 */
+	ITypeBinding resolveType(EnumDeclaration type) {
+		final Object node = this.newAstToOldAst.get(type);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(typeBinding, type);
+			String key = typeBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+			}
+			return typeBinding;
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding resolveType(Type type) {
+		// retrieve the old ast node
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type);
+		org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = null;
+		if (node != null) {
+			if (node instanceof Receiver) {
+				node = ((Receiver) node).type;
+			}
+			if (node instanceof ParameterizedQualifiedTypeReference) {
+ 				ParameterizedQualifiedTypeReference typeReference = (ParameterizedQualifiedTypeReference) node;
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = typeReference.resolvedType;
+				// This unlikely case is possible when for some reason binding resolution has been stopped, like duplicate type declaration (bug 376440)
+				if (typeBinding == null) return null;
+				if (type.isArrayType()) {
+					if (this.scope == null) {
+						return null;
+					}
+					ArrayType arrayType = (ArrayType) type;
+					ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
+					return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
+				}
+				if (typeBinding.isArrayType()) {
+					// 'typeBinding' can still be an array type because 'node' may be "larger" than 'type' (see comment of newAstToOldAst).
+					typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+				}
+				int index;
+				if (type.isQualifiedType()) {
+					index = ((QualifiedType) type).index;
+				} else if (type.isParameterizedType()) {
+					index = ((ParameterizedType) type).index;
+				} else {
+					index = 1;
+				}
+				final int numberOfTypeArgumentsNotNull = getTypeCount(typeReference);
+				if (index != numberOfTypeArgumentsNotNull) {
+					int  i = numberOfTypeArgumentsNotNull;
+					while (i != index) {
+						typeBinding = typeBinding.enclosingType();
+						i --;
+					}
+					binding = typeBinding;
+				} else {
+					binding = typeBinding;
+				}
+			} else if (node instanceof TypeReference) {
+				if (type instanceof QualifiedType) {
+					return resolveTypeBindingForName(((QualifiedType)type).getName());
+				} else if (type instanceof PackageQualifiedType){
+					return resolveTypeBindingForName(((PackageQualifiedType)type).getName());
+				}
+				TypeReference typeReference = (TypeReference) node;
+				binding = typeReference.resolvedType;
+			} else if (node instanceof SingleNameReference && ((SingleNameReference)node).isTypeReference()) {
+				binding = (((SingleNameReference)node).resolvedType);
+			} else if (node instanceof QualifiedNameReference && ((QualifiedNameReference)node).isTypeReference()) {
+				binding = (((QualifiedNameReference)node).resolvedType);
+			} else if (node instanceof ArrayAllocationExpression) {
+				binding = ((ArrayAllocationExpression) node).resolvedType;
+			}
+			if (binding != null) {
+				if (type.isArrayType()) {
+					ArrayType arrayType = (ArrayType) type;
+					if (this.scope == null) {
+						return null;
+					}
+					ArrayBinding arrayBinding = (ArrayBinding) binding;
+					return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
+				} else if (binding.isArrayType()) {
+					// 'binding' can still be an array type because 'node' may be "larger" than 'type' (see comment of newAstToOldAst).
+					ArrayBinding arrayBinding = (ArrayBinding) binding;
+					return getTypeBinding(arrayBinding.leafComponentType);
+				}
+				return getTypeBinding(binding);
+			}
+		} else if (type.isPrimitiveType()) {
+			/* Handle the void primitive type returned by getReturnType for a method declaration
+			 * that is a constructor declaration. It prevents null from being returned
+			 */
+			if (((PrimitiveType) type).getPrimitiveTypeCode() == PrimitiveType.VOID) {
+				return this.getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding.VOID);
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding resolveType(TypeDeclaration type) {
+		final Object node = this.newAstToOldAst.get(type);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(typeBinding, type);
+			String key = typeBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+			}
+			return typeBinding;
+		}
+		return null;
+	}
+
+	synchronized ITypeBinding resolveTypeParameter(TypeParameter typeParameter) {
+		final Object node = this.newAstToOldAst.get(typeParameter);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) {
+			org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter2 = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeParameter2.binding);
+			if (typeBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(typeBinding, typeParameter);
+			String key = typeBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+			}
+			return typeBinding;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveVariable(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
+	 */
+	synchronized IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
+		final Object node = this.newAstToOldAst.get(enumConstant);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+			IVariableBinding variableBinding = this.getVariableBinding(fieldDeclaration.binding);
+			if (variableBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(variableBinding, enumConstant);
+			String key = variableBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, variableBinding);
+			}
+			return variableBinding;
+		}
+		return null;
+	}
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized IVariableBinding resolveVariable(VariableDeclaration variable) {
+		final Object node = this.newAstToOldAst.get(variable);
+		if (node instanceof AbstractVariableDeclaration) {
+			AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) node;
+			IVariableBinding variableBinding = null;
+			if (abstractVariableDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+				org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) abstractVariableDeclaration;
+				variableBinding = this.getVariableBinding(fieldDeclaration.binding, variable);
+			} else {
+				variableBinding = this.getVariableBinding(((LocalDeclaration) abstractVariableDeclaration).binding, variable);
+			}
+			if (variableBinding == null) {
+				return null;
+			}
+			this.bindingsToAstNodes.put(variableBinding, variable);
+			String key = variableBinding.getKey();
+			if (key != null) {
+				this.bindingTables.bindingKeysToBindings.put(key, variableBinding);
+			}
+			return variableBinding;
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized ITypeBinding resolveWellKnownType(String name) {
+		if (this.scope == null) return null;
+		ITypeBinding typeBinding = null;
+		try {
+			if (("boolean".equals(name))//$NON-NLS-1$
+				|| ("char".equals(name))//$NON-NLS-1$
+				|| ("byte".equals(name))//$NON-NLS-1$
+				|| ("short".equals(name))//$NON-NLS-1$
+				|| ("int".equals(name))//$NON-NLS-1$
+				|| ("long".equals(name))//$NON-NLS-1$
+				|| ("float".equals(name))//$NON-NLS-1$
+				|| ("double".equals(name))//$NON-NLS-1$
+				|| ("void".equals(name))) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(Scope.getBaseType(name.toCharArray()));
+			} else if ("java.lang.Object".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaLangObject());
+			} else if ("java.lang.String".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaLangString());
+			} else if ("java.lang.StringBuffer".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_STRINGBUFFER, 3));
+			} else if ("java.lang.Throwable".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaLangThrowable());
+			} else if ("java.lang.Exception".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_EXCEPTION, 3));
+			} else if ("java.lang.RuntimeException".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION, 3));
+			} else if ("java.lang.Error".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_ERROR, 3));
+			} else if ("java.lang.Class".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaLangClass());
+			} else if ("java.lang.Cloneable".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaLangCloneable());
+			} else if ("java.io.Serializable".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getJavaIoSerializable());
+			} else if ("java.lang.Boolean".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BOOLEAN, 3));
+			} else if ("java.lang.Byte".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BYTE, 3));
+			} else if ("java.lang.Character".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_CHARACTER, 3));
+			} else if ("java.lang.Double".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_DOUBLE, 3));
+			} else if ("java.lang.Float".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_FLOAT, 3));
+			} else if ("java.lang.Integer".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_INTEGER, 3));
+			} else if ("java.lang.Long".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_LONG, 3));
+			} else if ("java.lang.Short".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_SHORT, 3));
+			} else if ("java.lang.Void".equals(name)) {//$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_VOID, 3));
+			} else if ("java.lang.AssertionError".equals(name)) { //$NON-NLS-1$
+				typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_ASSERTIONERROR, 3));
+			}
+		} catch (AbortCompilation e) {
+			// ignore missing types
+		}
+		if (typeBinding != null && !typeBinding.isRecovered()) {
+			return typeBinding;
+		}
+		return null;
+	}
+
+	synchronized IAnnotationBinding resolveAnnotation(final Annotation domASTNode) {
+		Object oldNode = this.newAstToOldAst.get(domASTNode);
+		if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
+			org.eclipse.jdt.internal.compiler.ast.Annotation internalAstNode =
+				(org.eclipse.jdt.internal.compiler.ast.Annotation) oldNode;
+
+			IAnnotationBinding domAnnotation = getAnnotationInstance(internalAstNode.getCompilerAnnotation());
+			if (domAnnotation == null)
+				return null;
+			this.bindingsToAstNodes.put(domAnnotation, domASTNode);
+			return domAnnotation;
+		}
+		return null;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	public CompilationUnitScope scope() {
+		return this.scope;
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized void store(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
+		this.newAstToOldAst.put(node, oldASTNode);
+	}
+
+	/*
+	 * Method declared on BindingResolver.
+	 */
+	synchronized void updateKey(ASTNode node, ASTNode newNode) {
+		Object astNode = this.newAstToOldAst.remove(node);
+		if (astNode != null) {
+			this.newAstToOldAst.put(newNode, astNode);
+		}
+	}
+
+	/**
+	 * Answer an array type binding with the given type binding and the given
+	 * dimensions.
+	 *
+	 * <p>If the given type binding is an array binding, then the resulting dimensions is the given dimensions
+	 * plus the existing dimensions of the array binding. Otherwise the resulting dimensions is the given
+	 * dimensions.</p>
+	 *
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param typeBinding the given type binding
+	 * @param dimensions the given dimensions
+	 * @return an array type binding with the given type binding and the given
+	 * dimensions
+	 * @throws IllegalArgumentException if the type binding represents the <code>void</code> type binding
+	 */
+	ITypeBinding resolveArrayType(ITypeBinding typeBinding, int dimensions) {
+		if (typeBinding instanceof RecoveredTypeBinding) throw new IllegalArgumentException("Cannot be called on a recovered type binding"); //$NON-NLS-1$
+		ITypeBinding leafComponentType = typeBinding;
+		int actualDimensions = dimensions;
+		if (typeBinding.isArray()) {
+			leafComponentType = typeBinding.getElementType();
+			actualDimensions += typeBinding.getDimensions();
+		}
+ 		org.eclipse.jdt.internal.compiler.lookup.TypeBinding leafTypeBinding = null;
+ 		if (leafComponentType.isPrimitive()) {
+ 	 		String name = leafComponentType.getBinaryName();
+			switch(name.charAt(0)) {
+				case 'I' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.INT;
+					break;
+				case 'B' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.BYTE;
+					break;
+				case 'Z' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.BOOLEAN;
+					break;
+				case 'C' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.CHAR;
+					break;
+				case 'J' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.LONG;
+					break;
+				case 'S' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.SHORT;
+					break;
+				case 'D' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.DOUBLE;
+					break;
+				case 'F' :
+					leafTypeBinding = org.eclipse.jdt.internal.compiler.lookup.TypeBinding.FLOAT;
+					break;
+				case 'V' :
+					throw new IllegalArgumentException();
+			}
+ 		} else {
+ 			if (!(leafComponentType instanceof TypeBinding)) return null;
+ 			leafTypeBinding = ((TypeBinding) leafComponentType).binding;
+ 		}
+		return this.getTypeBinding(lookupEnvironment().createArrayType(leafTypeBinding, actualDimensions));
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
new file mode 100644
index 0000000..6188f2a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
@@ -0,0 +1,648 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Internal class for associating comments with AST nodes.
+ *
+ * @since 3.0
+ */
+class DefaultCommentMapper {
+	Comment[] comments;
+	Scanner scanner;
+
+	// extended nodes storage
+	int leadingPtr;
+	ASTNode[] leadingNodes;
+	long[] leadingIndexes;
+	int trailingPtr, lastTrailingPtr;
+	ASTNode[] trailingNodes;
+	long[] trailingIndexes;
+	static final int STORAGE_INCREMENT = 16;
+
+	/**
+	 * @param table the given table of comments
+	 */
+	DefaultCommentMapper(Comment[] table) {
+		this.comments = table;
+	}
+
+	boolean hasSameTable(Comment[] table) {
+		return this.comments == table;
+	}
+
+	/**
+	 * Get comment of the list which includes a given position
+	 *
+	 * @param position The position belonging to the looked up comment
+	 * @return comment which includes the given position or null if none was found
+	 */
+	Comment getComment(int position) {
+
+		if (this.comments == null) {
+			return null;
+		}
+		int size = this.comments.length;
+		if (size == 0) {
+			return null;
+		}
+		int index = getCommentIndex(0, position, 0);
+		if (index<0) {
+			return null;
+		}
+		return this.comments[index];
+	}
+
+	/*
+	 * Get the index of comment which contains given position.
+	 * If there's no matching comment, then return depends on exact parameter:
+	 *		= 0: return -1
+	 *		< 0: return index of the comment before the given position
+	 *		> 0: return index of the comment after the given position
+	 */
+	private int getCommentIndex(int start, int position, int exact) {
+		if (position == 0) {
+			if (this.comments.length > 0 && this.comments[0].getStartPosition() == 0) {
+				return 0;
+			}
+			return -1;
+		}
+		int bottom = start, top = this.comments.length - 1;
+		int i = 0, index = -1;
+		Comment comment = null;
+		while (bottom <= top) {
+			i = bottom + (top - bottom) /2;
+			comment = this.comments[i];
+			int commentStart = comment.getStartPosition();
+			if (position < commentStart) {
+				top = i-1;
+			} else if (position >=(commentStart+comment.getLength())) {
+				bottom = i+1;
+			} else {
+				index = i;
+				break;
+			}
+		}
+		if (index<0 && exact!=0) {
+			comment = this.comments[i];
+			if (position < comment.getStartPosition()) {
+				return exact<0 ? i-1 : i;
+			} else {
+				return exact<0 ? i : i+1;
+			}
+		}
+		return index;
+	}
+
+	/**
+	 * Returns the extended start position of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 *
+	 * @param node the node
+	 * @return the 0-based character index, or <code>-1</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getExtendedLength(ASTNode)
+	 * @since 3.0
+	 */
+	public int getExtendedStartPosition(ASTNode node) {
+		if (this.leadingPtr >= 0) {
+			long range = -1;
+			for (int i=0; range<0 && i<=this.leadingPtr; i++) {
+				if (this.leadingNodes[i] == node) range = this.leadingIndexes[i];
+			}
+			if (range >= 0) {
+				return  this.comments[(int)(range>>32)].getStartPosition() ;
+			}
+		}
+		return node.getStartPosition();
+	}
+
+	/*
+	 * Search the line number corresponding to a specific position
+	 * between the given line range (inclusive)
+	 * @param position int
+	 * @parem lineRange size-2 int[]
+	 * @return int
+	 */
+	public final int getLineNumber(int position, int[] lineRange) {
+		int[] lineEnds = this.scanner.lineEnds;
+		int length = lineEnds.length;
+		return Util.getLineNumber(position, lineEnds, (lineRange[0] > length ? length : lineRange[0]) -1, (lineRange[1] > length ? length : lineRange[1]) - 1);
+	}
+
+	/*
+	 * Returns the extended end position of the given node.
+	 */
+	public int getExtendedEnd(ASTNode node) {
+		int end = node.getStartPosition() + node.getLength();
+		if (this.trailingPtr >= 0) {
+			long range = -1;
+			for (int i=0; range<0 && i<=this.trailingPtr; i++) {
+				if (this.trailingNodes[i] == node) range = this.trailingIndexes[i];
+			}
+			if (range >= 0) {
+				Comment lastComment = this.comments[(int) range];
+				end = lastComment.getStartPosition() + lastComment.getLength();
+			}
+		}
+		return end-1;
+	}
+
+	/**
+	 * Returns the extended source length of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 *
+	 * @param node the node
+	 * @return a (possibly 0) length, or <code>0</code>
+	 *    if no source position information is recorded for this node
+	 * @see #getExtendedStartPosition(ASTNode)
+	 * @see #getExtendedEnd(ASTNode)
+	 * @since 3.0
+	 */
+	public int getExtendedLength(ASTNode node) {
+		return getExtendedEnd(node) - getExtendedStartPosition(node) + 1;
+	}
+
+	/**
+	 * Return index of first leading comment of a given node.
+	 *
+	 * @param node
+	 * @return index of first leading comment or -1 if node has no leading comment
+	 */
+	int firstLeadingCommentIndex(ASTNode node) {
+		if (this.leadingPtr >= 0) {
+			for (int i=0; i<=this.leadingPtr; i++) {
+				if (this.leadingNodes[i] == node) {
+					return (int) (this.leadingIndexes[i]>>32);
+				}
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Return index of last trailing comment of a given node.
+	 *
+	 * @param node
+	 * @return index of last trailing comment or -1 if node has no trailing comment
+	 */
+	int lastTrailingCommentIndex(ASTNode node) {
+		if (this.trailingPtr >= 0) {
+			for (int i=0; i<=this.trailingPtr; i++) {
+				if (this.trailingNodes[i] == node) {
+					return (int) this.trailingIndexes[i];
+				}
+			}
+		}
+		return -1;
+	}
+
+	/*
+	 * Initialize leading and trailing comments tables in whole nodes hierarchy of a compilation
+	 * unit.
+	 * Scanner is necessary to scan between nodes and comments and verify if there's
+	 * nothing else than white spaces.
+	 */
+	void initialize(CompilationUnit unit, Scanner sc) {
+
+		// Init array pointers
+		this.leadingPtr = -1;
+		this.trailingPtr = -1;
+
+		// Init comments
+		this.comments = unit.optionalCommentTable;
+		if (this.comments == null) {
+			return;
+		}
+		int size = this.comments.length;
+		if (size == 0) {
+			return;
+		}
+
+		// Init scanner and start ranges computing
+		this.scanner = sc;
+		this.scanner.tokenizeWhiteSpace = true;
+
+		// Start unit visit
+		DefaultASTVisitor commentVisitor = new CommentMapperVisitor();
+		unit.accept(commentVisitor);
+
+		// Reduce leading arrays if necessary
+		int leadingCount = this.leadingPtr + 1;
+		if (leadingCount > 0 && leadingCount < this.leadingIndexes.length) {
+			System.arraycopy(this.leadingNodes, 0, this.leadingNodes = new ASTNode[leadingCount], 0, leadingCount);
+			System.arraycopy(this.leadingIndexes, 0, this.leadingIndexes= new long[leadingCount], 0, leadingCount);
+		}
+
+		// Reduce trailing arrays if necessary
+		if (this.trailingPtr >= 0) {
+			// remove last remaining unresolved nodes
+			while (this.trailingIndexes[this.trailingPtr] == -1) {
+				this.trailingPtr--;
+				if (this.trailingPtr < 0) {
+					this.trailingIndexes = null;
+					this.trailingNodes = null;
+					break;
+				}
+			}
+
+			// reduce array size
+			int trailingCount = this.trailingPtr + 1;
+			if (trailingCount > 0 && trailingCount < this.trailingIndexes.length) {
+				System.arraycopy(this.trailingNodes, 0, this.trailingNodes = new ASTNode[trailingCount], 0, trailingCount);
+				System.arraycopy(this.trailingIndexes, 0, this.trailingIndexes= new long[trailingCount], 0, trailingCount);
+			}
+		}
+
+		// Release scanner as it's only used during unit visit
+		this.scanner = null;
+	}
+
+	/**
+	 * Search and store node leading comments. Comments are searched in position range
+	 * from previous extended position to node start position. If one or several comment are found,
+	 * returns first comment start position, otherwise returns node start position.
+	 * <p>
+	 * Starts to search for first comment before node start position and return if none was found...
+	 *</p><p>
+	 * When first comment is found before node, goes up in comment list until one of
+	 * following conditions becomes true:
+	 * <ol>
+	 * 	<li>comment end is before previous end</li>
+	 * 	<li>comment start and previous end is on the same line but not on same line of node start</li>
+	 * 	<li>there's other than white characters between current node and comment</li>
+	 * 	<li>there's more than 1 line between current node and comment</li>
+	 * </ol>
+	 * If some comment have been found, then no token should be on
+	 * on the same line before, so remove all comments which do not verify this assumption.
+	 * </p><p>
+	 * If finally there's leading still comments, then stores indexes of the first and last one
+	 * in leading comments table.
+	 */
+	int storeLeadingComments(ASTNode node, int previousEnd, int[] parentLineRange) {
+		// Init extended position
+		int nodeStart = node.getStartPosition();
+		int extended = nodeStart;
+
+		// Get line of node start position
+		int previousEndLine = getLineNumber(previousEnd, parentLineRange);
+		int nodeStartLine = getLineNumber(nodeStart, parentLineRange);
+
+		// Find first comment index
+		int idx = getCommentIndex(0, nodeStart, -1);
+		if (idx == -1) {
+			return nodeStart;
+		}
+
+		// Look after potential comments
+		int startIdx = -1;
+		int endIdx = idx;
+		int previousStart = nodeStart;
+		while (idx >= 0 && previousStart  >= previousEnd) {
+			// Verify for each comment that there's only white spaces between end and start of {following comment|node}
+			Comment comment = this.comments[idx];
+			int commentStart = comment.getStartPosition();
+			int end = commentStart+comment.getLength()-1;
+			int commentLine = getLineNumber(commentStart, parentLineRange);
+			if (end <= previousEnd || (commentLine == previousEndLine && commentLine != nodeStartLine)) {
+				// stop search on condition 1) and 2)
+				break;
+			} else if ((end+1) < previousStart) { // may be equals => then no scan is necessary
+				this.scanner.resetTo(end+1, previousStart);
+				try {
+					int token = this.scanner.getNextToken();
+					if (token != TerminalTokens.TokenNameWHITESPACE || this.scanner.currentPosition != previousStart) {
+						// stop search on condition 3)
+						// if first comment fails, then there's no extended position in fact
+						if (idx == endIdx) {
+							return nodeStart;
+						}
+						break;
+					}
+				} catch (InvalidInputException e) {
+					// Should not happen, but return no extended position...
+					return nodeStart;
+				}
+				// verify that there's no more than one line between node/comments
+				char[] gap = this.scanner.getCurrentIdentifierSource();
+				int nbrLine = 0;
+				int pos = -1;
+				while ((pos=CharOperation.indexOf('\n', gap,pos+1)) >= 0) {
+					nbrLine++;
+				}
+				if (nbrLine > 1) {
+					// stop search on condition 4)
+					break;
+				}
+			}
+			// Store previous infos
+			previousStart = commentStart;
+			startIdx = idx--;
+		}
+		if (startIdx != -1) {
+			// Verify that there's no token on the same line before first leading comment
+			int commentStart = this.comments[startIdx].getStartPosition();
+			if (previousEnd < commentStart && previousEndLine != nodeStartLine) {
+				int lastTokenEnd = previousEnd;
+				this.scanner.resetTo(previousEnd, commentStart);
+				try {
+					while (this.scanner.currentPosition < commentStart) {
+						if (this.scanner.getNextToken() != TerminalTokens.TokenNameWHITESPACE) {
+							lastTokenEnd =  this.scanner.getCurrentTokenEndPosition();
+						}
+					}
+				} catch (InvalidInputException e) {
+					// do nothing
+				}
+				int lastTokenLine = getLineNumber(lastTokenEnd, parentLineRange);
+				int length = this.comments.length;
+				while (startIdx<length && lastTokenLine == getLineNumber(this.comments[startIdx].getStartPosition(), parentLineRange) && nodeStartLine != lastTokenLine) {
+					startIdx++;
+				}
+			}
+			// Store leading comments indexes
+			if (startIdx <= endIdx) {
+				if (++this.leadingPtr == 0) {
+					this.leadingNodes = new ASTNode[STORAGE_INCREMENT];
+					this.leadingIndexes = new long[STORAGE_INCREMENT];
+				} else if (this.leadingPtr == this.leadingNodes.length) {
+					int newLength = (this.leadingPtr*3/2)+STORAGE_INCREMENT;
+					System.arraycopy(this.leadingNodes, 0, this.leadingNodes = new ASTNode[newLength], 0, this.leadingPtr);
+					System.arraycopy(this.leadingIndexes, 0, this.leadingIndexes = new long[newLength], 0, this.leadingPtr);
+				}
+				this.leadingNodes[this.leadingPtr] = node;
+				this.leadingIndexes[this.leadingPtr] = (((long)startIdx)<<32) + endIdx;
+				extended = this.comments[endIdx].getStartPosition();
+			}
+		}
+		return extended;
+	}
+
+	/**
+	 * Search and store node trailing comments. Comments are searched in position range
+	 * from node end position to specified next start. If one or several comment are found,
+	 * returns last comment end position, otherwise returns node end position.
+	 * <p>
+	 * Starts to search for first comment after node end position and return if none was found...
+	 *</p><p>
+	 * When first comment is found after node, goes down in comment list until one of
+	 * following conditions becomes true:
+	 * <ol>
+	 * 	<li>comment start is after next start</li>
+	 * 	<li>there's other than white characters between current node and comment</li>
+	 * 	<li>there's more than 1 line between current node and comment</li>
+	 *</ol>
+	 * If at least potential comments have been found, then all of them has to be separated
+	 * from following node. So, remove all comments which do not verify this assumption.
+	 * Note that this verification is not applicable on last node.
+	 * </p><p>
+	 * If finally there's still trailing comments, then stores indexes of the first and last one
+	 * in trailing comments table.
+	 */
+	int storeTrailingComments(ASTNode node, int nextStart,  boolean lastChild, int[] parentLineRange) {
+
+		// Init extended position
+		int nodeEnd = node.getStartPosition()+node.getLength()-1;
+		if (nodeEnd == nextStart) {
+			// special case for last child of its parent
+			if (++this.trailingPtr == 0) {
+				this.trailingNodes = new ASTNode[STORAGE_INCREMENT];
+				this.trailingIndexes = new long[STORAGE_INCREMENT];
+				this.lastTrailingPtr = -1;
+			} else if (this.trailingPtr == this.trailingNodes.length) {
+				int newLength = (this.trailingPtr*3/2)+STORAGE_INCREMENT;
+				System.arraycopy(this.trailingNodes, 0, this.trailingNodes = new ASTNode[newLength], 0, this.trailingPtr);
+				System.arraycopy(this.trailingIndexes, 0, this.trailingIndexes = new long[newLength], 0, this.trailingPtr);
+			}
+			this.trailingNodes[this.trailingPtr] = node;
+			this.trailingIndexes[this.trailingPtr] = -1;
+			return nodeEnd;
+		}
+		int extended = nodeEnd;
+
+		// Get line number
+		int nodeEndLine = getLineNumber(nodeEnd, parentLineRange);
+
+		// Find comments range index
+		int idx = getCommentIndex(0, nodeEnd, 1);
+		if (idx == -1) {
+			return nodeEnd;
+		}
+
+		// Look after potential comments
+		int startIdx = idx;
+		int endIdx = -1;
+		int length = this.comments.length;
+		int commentStart = extended+1;
+		int previousEnd = nodeEnd+1;
+		int sameLineIdx = -1;
+		while (idx<length && commentStart < nextStart) {
+			// get comment and leave if next starting position has been reached
+			Comment comment = this.comments[idx];
+			commentStart = comment.getStartPosition();
+			// verify that there's nothing else than white spaces between node/comments
+			if (commentStart >= nextStart) {
+				// stop search on condition 1)
+				break;
+			} else if (previousEnd < commentStart) {
+				this.scanner.resetTo(previousEnd, commentStart);
+				try {
+					int token = this.scanner.getNextToken();
+					if (token != TerminalTokens.TokenNameWHITESPACE || this.scanner.currentPosition != commentStart) {
+						// stop search on condition 2)
+						// if first index fails, then there's no extended position in fact...
+						if (idx == startIdx) {
+							return nodeEnd;
+						}
+						// otherwise we get the last index of trailing comment => break
+						break;
+					}
+				} catch (InvalidInputException e) {
+					// Should not happen, but return no extended position...
+					return nodeEnd;
+				}
+				// verify that there's no more than one line between node/comments
+				char[] gap = this.scanner.getCurrentIdentifierSource();
+				int nbrLine = 0;
+				int pos = -1;
+				while ((pos=CharOperation.indexOf('\n', gap,pos+1)) >= 0) {
+					nbrLine++;
+				}
+				if (nbrLine > 1) {
+					// stop search on condition 3)
+					break;
+				}
+			}
+			// Store index if we're on the same line than node end
+			int commentLine = getLineNumber(commentStart, parentLineRange);
+			if (commentLine == nodeEndLine) {
+				sameLineIdx = idx;
+			}
+			// Store previous infos
+			previousEnd = commentStart+comment.getLength();
+			endIdx = idx++;
+		}
+		if (endIdx != -1) {
+			// Verify that following node start is separated
+			if (!lastChild) {
+				int nextLine = getLineNumber(nextStart, parentLineRange);
+				int previousLine = getLineNumber(previousEnd, parentLineRange);
+				if((nextLine - previousLine) <= 1) {
+					if (sameLineIdx == -1) return nodeEnd;
+					endIdx = sameLineIdx;
+				}
+			}
+			// Store trailing comments indexes
+			if (++this.trailingPtr == 0) {
+				this.trailingNodes = new ASTNode[STORAGE_INCREMENT];
+				this.trailingIndexes = new long[STORAGE_INCREMENT];
+				this.lastTrailingPtr = -1;
+			} else if (this.trailingPtr == this.trailingNodes.length) {
+				int newLength = (this.trailingPtr*3/2)+STORAGE_INCREMENT;
+				System.arraycopy(this.trailingNodes, 0, this.trailingNodes = new ASTNode[newLength], 0, this.trailingPtr);
+				System.arraycopy(this.trailingIndexes, 0, this.trailingIndexes = new long[newLength], 0, this.trailingPtr);
+			}
+			this.trailingNodes[this.trailingPtr] = node;
+			long nodeRange = (((long)startIdx)<<32) + endIdx;
+			this.trailingIndexes[this.trailingPtr] = nodeRange;
+			// Compute new extended end
+			extended = this.comments[endIdx].getStartPosition()+this.comments[endIdx].getLength()-1;
+			// Look for children unresolved extended end
+			ASTNode previousNode = node;
+			int ptr = this.trailingPtr - 1; // children extended end were stored before
+			while (ptr >= 0) {
+				long range = this.trailingIndexes[ptr];
+				if (range != -1) break; // there's no more unresolved nodes
+				ASTNode unresolved = this.trailingNodes[ptr];
+				if (previousNode != unresolved.getParent()) break; // we're no longer in node ancestor hierarchy
+				this.trailingIndexes[ptr] = nodeRange;
+				previousNode = unresolved;
+				ptr--; // get previous node
+			}
+			// Remove remaining unresolved nodes
+			if (ptr > this.lastTrailingPtr) {
+				int offset = ptr - this.lastTrailingPtr;
+				for (int i=ptr+1; i<=this.trailingPtr; i++) {
+					this.trailingNodes[i-offset] = this.trailingNodes[i];
+					this.trailingIndexes[i-offset] = this.trailingIndexes[i];
+				}
+				this.trailingPtr -= offset;
+			}
+			this.lastTrailingPtr = this.trailingPtr;
+		}
+		return extended;
+	}
+
+	class CommentMapperVisitor extends DefaultASTVisitor {
+
+		ASTNode topSiblingParent = null;
+		ASTNode[] siblings = new ASTNode[10];
+		int[][] parentLineRange = new int[10][];
+		int siblingPtr = -1;
+
+		protected boolean visitNode(ASTNode node) {
+
+			// Get default previous end
+			ASTNode parent = node.getParent();
+			int previousEnd = parent.getStartPosition();
+
+			// Look for sibling node
+ 			ASTNode sibling = parent == this.topSiblingParent ? (ASTNode) this.siblings[this.siblingPtr] : null;
+			if (sibling != null) {
+				// Found one previous sibling, so compute its trailing comments using current node start position
+				try {
+					previousEnd = storeTrailingComments(sibling, node.getStartPosition(), false, this.parentLineRange[this.siblingPtr]);
+				} catch (Exception ex) {
+					// Give up extended ranges at this level if unexpected exception happens...
+				}
+			}
+
+			// Stop visit for malformed node (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=84049)
+			if ((node.typeAndFlags & ASTNode.MALFORMED) != 0) {
+				return false;
+			}
+
+			// Compute leading comments for current node
+			int[] previousLineRange = this.siblingPtr > -1 ? this.parentLineRange[this.siblingPtr] : new int[] {1, DefaultCommentMapper.this.scanner.linePtr+1};
+			try {
+				storeLeadingComments(node, previousEnd, previousLineRange);
+			} catch (Exception ex) {
+				// Give up extended ranges at this level if unexpected exception happens...
+			}
+
+			// Store current node as waiting sibling for its parent
+			if (this.topSiblingParent != parent) {
+				if (this.siblings.length == ++this.siblingPtr) {
+					System.arraycopy(this.siblings, 0, this.siblings = new ASTNode[this.siblingPtr*2], 0, this.siblingPtr);
+					System.arraycopy(this.parentLineRange, 0, this.parentLineRange = new int[this.siblingPtr*2][], 0, this.siblingPtr);
+				}
+				if (this.topSiblingParent == null) {
+					// node is a CompilationUnit
+					this.parentLineRange[this.siblingPtr] = previousLineRange;
+				} else {
+					int parentStart = parent.getStartPosition();
+					int firstLine = getLineNumber(parentStart, previousLineRange);
+					int lastLine = getLineNumber(parentStart + parent.getLength() - 1, previousLineRange);
+					if (this.parentLineRange[this.siblingPtr] == null) {
+						this.parentLineRange[this.siblingPtr] = new int[] {firstLine, lastLine};
+					} else {
+						int[] lineRange = this.parentLineRange[this.siblingPtr];
+						lineRange[0] = firstLine;
+						lineRange[1] = lastLine;
+					}
+				}
+				this.topSiblingParent = parent;
+			}
+			this.siblings[this.siblingPtr] = node;
+
+			// We're always ok to visit sub-levels
+			return true;
+		}
+
+		protected void endVisitNode(ASTNode node) {
+
+			// Look if a child node is waiting for trailing comments computing
+			ASTNode sibling = this.topSiblingParent == node ? (ASTNode) this.siblings[this.siblingPtr] : null;
+			if (sibling != null) {
+				try {
+					storeTrailingComments(sibling, node.getStartPosition()+node.getLength()-1, true, this.parentLineRange[this.siblingPtr]);
+				} catch (Exception ex) {
+					// Give up extended ranges at this level if unexpected exception happens...
+				}
+			}
+			// Remove sibling if needed
+			if (this.topSiblingParent != null /*not a CompilationUnit*/
+					&& this.topSiblingParent == node) {
+				this.siblingPtr--;
+				this.topSiblingParent = node.getParent();
+			}
+		}
+
+		public boolean visit (Modifier modifier) {
+			// we don't want to map comment to the modifier
+			return false;
+		}
+		public boolean visit ( CompilationUnit node) {
+			// do nothing special, just go down in sub-levels
+			return true;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java
new file mode 100644
index 0000000..2f7a1f1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultValuePairBinding.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *    IBM Corporation - implemented methods from IBinding
+ *    IBM Corporation - renamed from ResolvedDefaultValuePair to DefaultValuePairBinding
+ *    IBM Corporation - Fix for 328969
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.dom.BindingResolver;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+
+/**
+ * Member value pair which compose of default values.
+ */
+class DefaultValuePairBinding extends MemberValuePairBinding {
+
+	private org.eclipse.jdt.internal.compiler.lookup.MethodBinding method;
+
+	DefaultValuePairBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding, BindingResolver resolver) {
+		super(null, resolver);
+		this.method = binding;
+		this.value = MemberValuePairBinding.buildDOMValue(binding.getDefaultValue(), resolver);
+		if (binding.returnType != null && binding.returnType.isArrayType()) {
+			// wrap into an array
+			if (this.value == null) {
+				this.value = new Object[0];
+			} else if (!this.value.getClass().isArray()) {
+				this.value = new Object[] { this.value };
+			}
+		}
+	}
+
+	public IMethodBinding getMethodBinding() {
+		return this.bindingResolver.getMethodBinding(this.method);
+	}
+
+	public String getName() {
+		return new String(this.method.selector);
+	}
+
+	public Object getValue() {
+		return this.value;
+	}
+
+	public boolean isDefault() {
+		return true;
+	}
+
+	public boolean isDeprecated() {
+		return this.method.isDeprecated();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java
new file mode 100644
index 0000000..b54f3ed
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Do statement AST node type.
+ *
+ * <pre>
+ * DoStatement:
+ *    <b>do</b> Statement <b>while</b> <b>(</b> Expression <b>)</b> <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class DoStatement extends Statement {
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(DoStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+			new ChildPropertyDescriptor(DoStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(DoStatement.class, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The body statement; lazily initialized; defaults to an empty block.
+	 */
+	private Statement body = null;
+	
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified, but
+	 * legal, expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * Creates a new unparented do statement node owned by the given
+	 * AST. By default, the expression is unspecified, but legal,
+	 * and the body statement is an empty block.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	DoStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Statement) child);
+				return null;
+			}
+		}
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return DO_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		DoStatement result = new DoStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setBody((Statement) getBody().clone(target));
+		result.setExpression((Expression) getExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getBody());
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the body of this do statement.
+	 *
+	 * @return the body statement node
+	 */
+	public Statement getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this do statement.
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the body of a do statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the body of a <code>DoStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, statement, BODY_PROPERTY);
+		this.body = statement;
+		postReplaceChild(oldChild, statement, BODY_PROPERTY);
+	}
+
+    /**
+     * Returns the expression of this do statement.
+     *
+     * @return the expression node
+     */
+    public Expression getExpression() {
+        if (this.expression == null) {
+            // lazy init must be thread-safe for readers
+            synchronized (this) {
+                if (this.expression == null) {
+                    preLazyInit();
+                    this.expression = new SimpleName(this.ast);
+                    postLazyInit(this.expression, EXPRESSION_PROPERTY);
+                }
+            }
+        }
+        return this.expression;
+    }
+
+    /**
+     * Sets the expression of this do statement.
+     *
+     * @param expression the expression node
+     * @exception IllegalArgumentException if:
+     * <ul>
+     * <li>the node belongs to a different AST</li>
+     * <li>the node already has a parent</li>
+     * <li>a cycle in would be created</li>
+     * </ul>
+     */
+    public void setExpression(Expression expression) {
+        if (expression == null) {
+            throw new IllegalArgumentException();
+        }
+        ASTNode oldChild = this.expression;
+        preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+        this.expression = expression;
+        postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+    }
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
new file mode 100644
index 0000000..5583fb6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
@@ -0,0 +1,750 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Internal parser used for decoding doc comments.
+ *
+ * @since 3.0
+ */
+class DocCommentParser extends AbstractCommentParser {
+
+	private Javadoc docComment;
+	private AST ast;
+
+	DocCommentParser(AST ast, Scanner scanner, boolean check) {
+		super(null);
+		this.ast = ast;
+		this.scanner = scanner;
+		switch(this.ast.apiLevel()) {
+			case AST.JLS2_INTERNAL :
+				this.sourceLevel = ClassFileConstants.JDK1_3;
+				break;
+			case AST.JLS3_INTERNAL:
+				this.sourceLevel = ClassFileConstants.JDK1_5;
+				break;
+			default:
+				// AST.JLS4 for now
+				this.sourceLevel = ClassFileConstants.JDK1_7;
+		}
+		this.checkDocComment = check;
+		this.kind = DOM_PARSER | TEXT_PARSE;
+	}
+
+	/* (non-Javadoc)
+	 * Returns true if tag @deprecated is present in annotation.
+	 *
+	 * If annotation checking is enabled, will also construct an Annotation node, which will be stored into Parser.annotation
+	 * slot for being consumed later on.
+	 */
+	public Javadoc parse(int[] positions) {
+		return parse(positions[0], positions[1]-positions[0]);
+	}
+	public Javadoc parse(int start, int length) {
+
+		// Init
+		this.source = this.scanner.source;
+		this.lineEnds = this.scanner.lineEnds;
+		this.docComment = new Javadoc(this.ast);
+
+		// Parse
+		if (this.checkDocComment) {
+			this.javadocStart = start;
+			this.javadocEnd = start+length-1;
+			this.firstTagPosition = this.javadocStart;
+			commentParse();
+		}
+		this.docComment.setSourceRange(start, length);
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			setComment(start, length);  // backward compatibility
+		}
+		return this.docComment;
+	}
+
+	/**
+	 * Sets the comment starting at the given position and with the given length.
+	 * <p>
+	 * Note the only purpose of this method is to hide deprecated warnings.
+	 * @deprecated mark deprecated to hide deprecated usage
+	 */
+	private void setComment(int start, int length) {
+		this.docComment.setComment(new String(this.source, start, length));
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("javadoc: ").append(this.docComment).append("\n");	//$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append(super.toString());
+		return buffer.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createArgumentReference(char[], java.lang.Object, int)
+	 */
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+		try {
+			MethodRefParameter argument = this.ast.newMethodRefParameter();
+			ASTNode node = (ASTNode) typeRef;
+			int argStart = node.getStartPosition();
+			int argEnd = node.getStartPosition()+node.getLength()-1;
+			if (dim > 0) argEnd = (int) dimPositions[dim-1];
+			if (argNamePos >= 0) argEnd = (int) argNamePos;
+			if (name.length != 0) {
+				final SimpleName argName = new SimpleName(this.ast);
+				argName.internalSetIdentifier(new String(name));
+				argument.setName(argName);
+				int argNameStart = (int) (argNamePos >>> 32);
+				argName.setSourceRange(argNameStart, argEnd-argNameStart+1);
+			}
+			Type argType = null;
+			if (node.getNodeType() == ASTNode.PRIMITIVE_TYPE) {
+				argType = (PrimitiveType) node;
+//				if (dim > 0) {
+//					argType = this.ast.newArrayType(argType, dim);
+//					argType.setSourceRange(argStart, ((int) dimPositions[dim-1])-argStart+1);
+//				}
+			} else {
+				Name argTypeName = (Name) node;
+				argType = this.ast.newSimpleType(argTypeName);
+				argType.setSourceRange(argStart, node.getLength());
+			}
+			if (dim > 0 && !isVarargs) {
+				for (int i=0; i<dim; i++) {
+					argType = this.ast.newArrayType(argType);
+					argType.setSourceRange(argStart, ((int) dimPositions[i])-argStart+1);
+				}
+			}
+			argument.setType(argType);
+			argument.setSourceRange(argStart, argEnd - argStart + 1);
+			return argument;
+		}
+		catch (ClassCastException ex) {
+				throw new InvalidInputException();
+		}
+	}
+/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createFieldReference()
+	 */
+	protected Object createFieldReference(Object receiver) throws InvalidInputException {
+		try {
+			MemberRef fieldRef = this.ast.newMemberRef();
+			SimpleName fieldName = new SimpleName(this.ast);
+			fieldName.internalSetIdentifier(new String(this.identifierStack[0]));
+			fieldRef.setName(fieldName);
+			int start = (int) (this.identifierPositionStack[0] >>> 32);
+			int end = (int) this.identifierPositionStack[0];
+			fieldName.setSourceRange(start, end - start + 1);
+			if (receiver == null) {
+				start = this.memberStart;
+				fieldRef.setSourceRange(start, end - start + 1);
+			} else {
+				Name typeRef = (Name) receiver;
+				fieldRef.setQualifier(typeRef);
+				start = typeRef.getStartPosition();
+				end = fieldName.getStartPosition()+fieldName.getLength()-1;
+				fieldRef.setSourceRange(start, end-start+1);
+			}
+			return fieldRef;
+		}
+		catch (ClassCastException ex) {
+				throw new InvalidInputException();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createMethodReference(java.lang.Object[])
+	 */
+	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+		try {
+			// Create method ref
+			MethodRef methodRef = this.ast.newMethodRef();
+			SimpleName methodName = new SimpleName(this.ast);
+			int length = this.identifierLengthStack[0] - 1; // may be > 0 for member class constructor reference
+			methodName.internalSetIdentifier(new String(this.identifierStack[length]));
+			methodRef.setName(methodName);
+			int start = (int) (this.identifierPositionStack[length] >>> 32);
+			int end = (int) this.identifierPositionStack[length];
+			methodName.setSourceRange(start, end - start + 1);
+			// Set qualifier
+			if (receiver == null) {
+				start = this.memberStart;
+				methodRef.setSourceRange(start, end - start + 1);
+			} else {
+				Name typeRef = (Name) receiver;
+				methodRef.setQualifier(typeRef);
+				start = typeRef.getStartPosition();
+			}
+			// Add arguments
+			if (arguments != null) {
+				Iterator parameters = arguments.listIterator();
+				while (parameters.hasNext()) {
+					MethodRefParameter param = (MethodRefParameter) parameters.next();
+					methodRef.parameters().add(param);
+				}
+			}
+			methodRef.setSourceRange(start, this.scanner.getCurrentTokenEndPosition()-start+1);
+			return methodRef;
+		}
+		catch (ClassCastException ex) {
+				throw new InvalidInputException();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createTag()
+	 */
+	protected void createTag() {
+		TagElement tagElement = this.ast.newTagElement();
+		int position = this.scanner.currentPosition;
+		this.scanner.resetTo(this.tagSourceStart, this.tagSourceEnd);
+		StringBuffer tagName = new StringBuffer();
+		int start = this.tagSourceStart;
+		this.scanner.getNextChar();
+		while (this.scanner.currentPosition <= (this.tagSourceEnd+1)) {
+			tagName.append(this.scanner.currentCharacter);
+			this.scanner.getNextChar();
+		}
+		tagElement.setTagName(tagName.toString());
+		if (this.inlineTagStarted) {
+			start = this.inlineTagStart;
+			TagElement previousTag = null;
+			if (this.astPtr == -1) {
+				previousTag = this.ast.newTagElement();
+				previousTag.setSourceRange(start, this.tagSourceEnd-start+1);
+				pushOnAstStack(previousTag, true);
+			} else {
+				previousTag = (TagElement) this.astStack[this.astPtr];
+			}
+			int previousStart = previousTag.getStartPosition();
+			previousTag.fragments().add(tagElement);
+			previousTag.setSourceRange(previousStart, this.tagSourceEnd-previousStart+1);
+		} else {
+			pushOnAstStack(tagElement, true);
+		}
+		tagElement.setSourceRange(start, this.tagSourceEnd-start+1);
+		this.scanner.resetTo(position, this.javadocEnd);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createTypeReference()
+	 */
+	protected Object createTypeReference(int primitiveToken) {
+		int size = this.identifierLengthStack[this.identifierLengthPtr];
+		String[] identifiers = new String[size];
+		int pos = this.identifierPtr - size + 1;
+		for (int i = 0; i < size; i++) {
+			identifiers[i] = new String(this.identifierStack[pos+i]);
+		}
+		ASTNode typeRef = null;
+		if (primitiveToken == -1) {
+			typeRef = this.ast.internalNewName(identifiers);
+		} else {
+			switch (primitiveToken) {
+				case TerminalTokens.TokenNamevoid :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.VOID);
+					break;
+				case TerminalTokens.TokenNameboolean :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.BOOLEAN);
+					break;
+				case TerminalTokens.TokenNamebyte :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.BYTE);
+					break;
+				case TerminalTokens.TokenNamechar :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.CHAR);
+					break;
+				case TerminalTokens.TokenNamedouble :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.DOUBLE);
+					break;
+				case TerminalTokens.TokenNamefloat :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.FLOAT);
+					break;
+				case TerminalTokens.TokenNameint :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.INT);
+					break;
+				case TerminalTokens.TokenNamelong :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.LONG);
+					break;
+				case TerminalTokens.TokenNameshort :
+					typeRef = this.ast.newPrimitiveType(PrimitiveType.SHORT);
+					break;
+				default:
+					// should not happen
+					return null;
+			}
+		}
+		// Update ref for whole name
+		int start = (int) (this.identifierPositionStack[pos] >>> 32);
+//		int end = (int) this.identifierPositionStack[this.identifierPtr];
+//		typeRef.setSourceRange(start, end-start+1);
+		// Update references of each simple name
+		if (size > 1) {
+			Name name = (Name)typeRef;
+			int nameIndex = size;
+			for (int i=this.identifierPtr; i>pos; i--, nameIndex--) {
+				int s = (int) (this.identifierPositionStack[i] >>> 32);
+				int e = (int) this.identifierPositionStack[i];
+				name.index = nameIndex;
+				SimpleName simpleName = ((QualifiedName)name).getName();
+				simpleName.index = nameIndex;
+				simpleName.setSourceRange(s, e-s+1);
+				name.setSourceRange(start, e-start+1);
+				name =  ((QualifiedName)name).getQualifier();
+			}
+			int end = (int) this.identifierPositionStack[pos];
+			name.setSourceRange(start, end-start+1);
+			name.index = nameIndex;
+		} else {
+			int end = (int) this.identifierPositionStack[pos];
+			typeRef.setSourceRange(start, end-start+1);
+		}
+		return typeRef;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseIdentifierTag(boolean)
+	 */
+	protected boolean parseIdentifierTag(boolean report) {
+		if (super.parseIdentifierTag(report)) {
+			createTag();
+			this.index = this.tagSourceEnd+1;
+			this.scanner.resetTo(this.index, this.javadocEnd);
+			return true;
+		}
+		return false;
+	}
+
+	/*
+	 * Parse @return tag declaration
+	 */
+	protected boolean parseReturn() {
+		createTag();
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseTag(int)
+	 */
+	protected boolean parseTag(int previousPosition) throws InvalidInputException {
+
+		// Read tag name
+		int currentPosition = this.index;
+		int token = readTokenAndConsume();
+		char[] tagName = CharOperation.NO_CHAR;
+		if (currentPosition == this.scanner.startPosition) {
+			this.tagSourceStart = this.scanner.getCurrentTokenStartPosition();
+			this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+			tagName = this.scanner.getCurrentIdentifierSource();
+		} else {
+			this.tagSourceEnd = currentPosition-1;
+		}
+
+		// Try to get tag name other than java identifier
+		// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
+		if (this.scanner.currentCharacter != ' ' && !ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
+			tagNameToken: while (token != TerminalTokens.TokenNameEOF && this.index < this.scanner.eofPosition) {
+				int length = tagName.length;
+				// !, ", #, %, &, ', -, :, <, >, * chars and spaces are not allowed in tag names
+				switch (this.scanner.currentCharacter) {
+					case '}':
+					case '*': // break for '*' as this is perhaps the end of comment (bug 65288)
+					case '!':
+					case '#':
+					case '%':
+					case '&':
+					case '\'':
+					case '"':
+					case ':':
+					case '<':
+					case '>':
+						break tagNameToken;
+					case '-': // allowed in tag names as this character is often used in doclets (bug 68087)
+						System.arraycopy(tagName, 0, tagName = new char[length+1], 0, length);
+						tagName[length] = this.scanner.currentCharacter;
+						break;
+					default:
+						if (this.scanner.currentCharacter == ' ' || ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
+							break tagNameToken;
+						}
+						token = readTokenAndConsume();
+						char[] ident = this.scanner.getCurrentIdentifierSource();
+						System.arraycopy(tagName, 0, tagName = new char[length+ident.length], 0, length);
+						System.arraycopy(ident, 0, tagName, length, ident.length);
+						break;
+				}
+				this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+				this.scanner.getNextChar();
+				this.index = this.scanner.currentPosition;
+			}
+		}
+		int length = tagName.length;
+		this.index = this.tagSourceEnd+1;
+		this.scanner.currentPosition = this.tagSourceEnd+1;
+		this.tagSourceStart = previousPosition;
+
+		// tage name may be empty (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=125903)
+		if (tagName.length == 0) {
+			return false;
+		}
+
+		// Decide which parse to perform depending on tag name
+		this.tagValue = NO_TAG_VALUE;
+		boolean valid = true;
+		switch (token) {
+			case TerminalTokens.TokenNameIdentifier :
+				switch (tagName[0]) {
+					case 'c':
+						if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName)) {
+							this.tagValue = TAG_CATEGORY_VALUE;
+							valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+						break;
+					case 'd':
+						if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName)) {
+							this.deprecated = true;
+							this.tagValue = TAG_DEPRECATED_VALUE;
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+						}
+						createTag();
+					break;
+					case 'i':
+						if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) {
+							if (this.reportProblems) {
+								recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
+							}
+							this.tagValue = TAG_INHERITDOC_VALUE;
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+						}
+						createTag();
+					break;
+					case 'p':
+						if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName)) {
+							this.tagValue = TAG_PARAM_VALUE;
+							valid = parseParam();
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+					break;
+					case 'e':
+						if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName)) {
+							this.tagValue = TAG_EXCEPTION_VALUE;
+							valid = parseThrows();
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+					break;
+					case 's':
+						if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName)) {
+							this.tagValue = TAG_SEE_VALUE;
+							if (this.inlineTagStarted) {
+								// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+								// Cannot have @see inside inline comment
+								valid = false;
+							} else {
+								valid = parseReference();
+							}
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+					break;
+					case 'l':
+						if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) {
+							this.tagValue = TAG_LINK_VALUE;
+						} else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName)) {
+							this.tagValue = TAG_LINKPLAIN_VALUE;
+						}
+						if (this.tagValue != NO_TAG_VALUE)  {
+							if (this.inlineTagStarted) {
+								valid = parseReference();
+							} else {
+								// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+								// Cannot have @link outside inline comment
+								valid = false;
+							}
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+					break;
+					case 'v':
+						if (this.sourceLevel >= ClassFileConstants.JDK1_5 && length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) {
+							this.tagValue = TAG_VALUE_VALUE;
+							if (this.inlineTagStarted) {
+								valid = parseReference();
+							} else {
+								valid = false;
+							}
+						} else {
+							this.tagValue = TAG_OTHERS_VALUE;
+							createTag();
+						}
+					break;
+					default:
+						this.tagValue = TAG_OTHERS_VALUE;
+						createTag();
+				}
+				break;
+			case TerminalTokens.TokenNamereturn :
+				this.tagValue = TAG_RETURN_VALUE;
+				valid = parseReturn();
+				break;
+			case TerminalTokens.TokenNamethrows :
+				this.tagValue = TAG_THROWS_VALUE;
+				valid = parseThrows();
+				break;
+			case TerminalTokens.TokenNameabstract:
+			case TerminalTokens.TokenNameassert:
+			case TerminalTokens.TokenNameboolean:
+			case TerminalTokens.TokenNamebreak:
+			case TerminalTokens.TokenNamebyte:
+			case TerminalTokens.TokenNamecase:
+			case TerminalTokens.TokenNamecatch:
+			case TerminalTokens.TokenNamechar:
+			case TerminalTokens.TokenNameclass:
+			case TerminalTokens.TokenNamecontinue:
+			case TerminalTokens.TokenNamedefault:
+			case TerminalTokens.TokenNamedo:
+			case TerminalTokens.TokenNamedouble:
+			case TerminalTokens.TokenNameelse:
+			case TerminalTokens.TokenNameextends:
+			case TerminalTokens.TokenNamefalse:
+			case TerminalTokens.TokenNamefinal:
+			case TerminalTokens.TokenNamefinally:
+			case TerminalTokens.TokenNamefloat:
+			case TerminalTokens.TokenNamefor:
+			case TerminalTokens.TokenNameif:
+			case TerminalTokens.TokenNameimplements:
+			case TerminalTokens.TokenNameimport:
+			case TerminalTokens.TokenNameinstanceof:
+			case TerminalTokens.TokenNameint:
+			case TerminalTokens.TokenNameinterface:
+			case TerminalTokens.TokenNamelong:
+			case TerminalTokens.TokenNamenative:
+			case TerminalTokens.TokenNamenew:
+			case TerminalTokens.TokenNamenull:
+			case TerminalTokens.TokenNamepackage:
+			case TerminalTokens.TokenNameprivate:
+			case TerminalTokens.TokenNameprotected:
+			case TerminalTokens.TokenNamepublic:
+			case TerminalTokens.TokenNameshort:
+			case TerminalTokens.TokenNamestatic:
+			case TerminalTokens.TokenNamestrictfp:
+			case TerminalTokens.TokenNamesuper:
+			case TerminalTokens.TokenNameswitch:
+			case TerminalTokens.TokenNamesynchronized:
+			case TerminalTokens.TokenNamethis:
+			case TerminalTokens.TokenNamethrow:
+			case TerminalTokens.TokenNametransient:
+			case TerminalTokens.TokenNametrue:
+			case TerminalTokens.TokenNametry:
+			case TerminalTokens.TokenNamevoid:
+			case TerminalTokens.TokenNamevolatile:
+			case TerminalTokens.TokenNamewhile:
+			case TerminalTokens.TokenNameenum :
+			case TerminalTokens.TokenNameconst :
+			case TerminalTokens.TokenNamegoto :
+				this.tagValue = TAG_OTHERS_VALUE;
+				createTag();
+				break;
+		}
+		this.textStart = this.index;
+		return valid;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushParamName(java.lang.Object)
+	 */
+	protected boolean pushParamName(boolean isTypeParam) {
+		int idIndex = isTypeParam ? 1 : 0;
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(this.identifierStack[idIndex]));
+		int nameStart = (int) (this.identifierPositionStack[idIndex] >>> 32);
+		int nameEnd = (int) (this.identifierPositionStack[idIndex] & 0x00000000FFFFFFFFL);
+		name.setSourceRange(nameStart, nameEnd-nameStart+1);
+		TagElement paramTag = this.ast.newTagElement();
+		paramTag.setTagName(TagElement.TAG_PARAM);
+		if (isTypeParam) { // specific storage for @param <E> (see bug 79809)
+			// '<' was stored in identifiers stack
+			TextElement text = this.ast.newTextElement();
+			text.setText(new String(this.identifierStack[0]));
+			int txtStart = (int) (this.identifierPositionStack[0] >>> 32);
+			int txtEnd = (int) (this.identifierPositionStack[0] & 0x00000000FFFFFFFFL);
+			text.setSourceRange(txtStart, txtEnd-txtStart+1);
+			paramTag.fragments().add(text);
+			// add simple name
+			paramTag.fragments().add(name);
+			// '>' was stored in identifiers stack
+			text = this.ast.newTextElement();
+			text.setText(new String(this.identifierStack[2]));
+			txtStart = (int) (this.identifierPositionStack[2] >>> 32);
+			txtEnd = (int) (this.identifierPositionStack[2] & 0x00000000FFFFFFFFL);
+			text.setSourceRange(txtStart, txtEnd-txtStart+1);
+			paramTag.fragments().add(text);
+			// set param tag source range
+			paramTag.setSourceRange(this.tagSourceStart, txtEnd-this.tagSourceStart+1);
+		} else {
+			paramTag.setSourceRange(this.tagSourceStart, nameEnd-this.tagSourceStart+1);
+			paramTag.fragments().add(name);
+		}
+		pushOnAstStack(paramTag, true);
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushSeeRef(java.lang.Object)
+	 */
+	protected boolean pushSeeRef(Object statement) {
+		TagElement seeTag = this.ast.newTagElement();
+		ASTNode node = (ASTNode) statement;
+		seeTag.fragments().add(node);
+		int end = node.getStartPosition()+node.getLength()-1;
+		if (this.inlineTagStarted) {
+			seeTag.setSourceRange(this.inlineTagStart, end-this.inlineTagStart+1);
+			switch (this.tagValue) {
+				case TAG_LINK_VALUE:
+					seeTag.setTagName(TagElement.TAG_LINK);
+				break;
+				case TAG_LINKPLAIN_VALUE:
+					seeTag.setTagName(TagElement.TAG_LINKPLAIN);
+				break;
+				case TAG_VALUE_VALUE:
+					seeTag.setTagName(TagElement.TAG_VALUE);
+				break;
+			}
+			TagElement previousTag = null;
+			int previousStart = this.inlineTagStart;
+			if (this.astPtr == -1) {
+				previousTag = this.ast.newTagElement();
+				pushOnAstStack(previousTag, true);
+			} else {
+				previousTag = (TagElement) this.astStack[this.astPtr];
+				previousStart = previousTag.getStartPosition();
+			}
+			previousTag.fragments().add(seeTag);
+			previousTag.setSourceRange(previousStart, end-previousStart+1);
+		} else {
+			seeTag.setTagName(TagElement.TAG_SEE);
+			seeTag.setSourceRange(this.tagSourceStart, end-this.tagSourceStart+1);
+			pushOnAstStack(seeTag, true);
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
+	 */
+	protected void pushText(int start, int end) {
+
+		// Create text element
+		TextElement text = this.ast.newTextElement();
+		text.setText(new String( this.source, start, end-start));
+		text.setSourceRange(start, end-start);
+
+		// Search previous tag on which to add the text element
+		TagElement previousTag = null;
+		int previousStart = start;
+		if (this.astPtr == -1) {
+			previousTag = this.ast.newTagElement();
+			previousTag.setSourceRange(start, end-start);
+			pushOnAstStack(previousTag, true);
+		} else {
+			previousTag = (TagElement) this.astStack[this.astPtr];
+			previousStart = previousTag.getStartPosition();
+		}
+
+		// If we're in a inline tag, then retrieve previous tag in its fragments
+		List fragments = previousTag.fragments();
+		if (this.inlineTagStarted) {
+			int size = fragments.size();
+			if (size == 0) {
+				// no existing fragment => just add the element
+				TagElement inlineTag = this.ast.newTagElement();
+				fragments.add(inlineTag);
+				previousTag = inlineTag;
+			} else {
+				// If last fragment is a tag, then use it as previous tag
+				ASTNode lastFragment = (ASTNode) fragments.get(size-1);
+				if (lastFragment.getNodeType() == ASTNode.TAG_ELEMENT) {
+					previousTag = (TagElement) lastFragment;
+					previousStart = previousTag.getStartPosition();
+				}
+			}
+		}
+
+		// Add the text
+		previousTag.fragments().add(text);
+		previousTag.setSourceRange(previousStart, end-previousStart);
+		this.textStart = -1;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushThrowName(java.lang.Object)
+	 */
+	protected boolean pushThrowName(Object typeRef) {
+		TagElement throwsTag = this.ast.newTagElement();
+		switch (this.tagValue) {
+			case TAG_THROWS_VALUE:
+				throwsTag.setTagName(TagElement.TAG_THROWS);
+			break;
+			case TAG_EXCEPTION_VALUE:
+				throwsTag.setTagName(TagElement.TAG_EXCEPTION);
+			break;
+		}
+		throwsTag.setSourceRange(this.tagSourceStart, this.scanner.getCurrentTokenEndPosition()-this.tagSourceStart+1);
+		throwsTag.fragments().add(typeRef);
+		pushOnAstStack(throwsTag, true);
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#refreshInlineTagPosition(int)
+	 */
+	protected void refreshInlineTagPosition(int previousPosition) {
+		if (this.astPtr != -1) {
+			TagElement previousTag = (TagElement) this.astStack[this.astPtr];
+			if (this.inlineTagStarted) {
+				int previousStart = previousTag.getStartPosition();
+				previousTag.setSourceRange(previousStart, previousPosition-previousStart+1);
+				if (previousTag.fragments().size() > 0) {
+					ASTNode inlineTag = (ASTNode) previousTag.fragments().get(previousTag.fragments().size()-1);
+					if (inlineTag.getNodeType() == ASTNode.TAG_ELEMENT) {
+						int inlineStart = inlineTag.getStartPosition();
+						inlineTag.setSourceRange(inlineStart, previousPosition-inlineStart+1);
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * Add stored tag elements to associated comment.
+	 */
+	protected void updateDocComment() {
+		for (int idx = 0; idx <= this.astPtr; idx++) {
+			this.docComment.tags().add(this.astStack[idx]);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java
new file mode 100644
index 0000000..e46e897
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Null statement AST node type.
+ *
+ * <pre>
+ * EmptyStatement:
+ *    <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class EmptyStatement extends Statement {
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(1);
+		createPropertyList(EmptyStatement.class, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new unparented null statement node owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	EmptyStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return EMPTY_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		EmptyStatement result = new EmptyStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java
new file mode 100644
index 0000000..3a4522a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Enhanced For statement AST node type (added in JLS3 API).
+ *
+ * <pre>
+ * EnhancedForStatement:
+ *    <b>for</b> <b>(</b> FormalParameter <b>:</b> Expression <b>)</b>
+ * 			Statement
+ * </pre>
+ * 
+ * <p>The FormalParameter is represented by a {@link SingleVariableDeclaration}
+ * (without an initializer).</p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class EnhancedForStatement extends Statement {
+
+	/**
+	 * The "parameter" structural property of this node type (child type: {@link SingleVariableDeclaration}).
+	 */
+	public static final ChildPropertyDescriptor PARAMETER_PROPERTY =
+		new ChildPropertyDescriptor(EnhancedForStatement.class, "parameter", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(EnhancedForStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Statement}).
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(EnhancedForStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(EnhancedForStatement.class, properyList);
+		addProperty(PARAMETER_PROPERTY, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The parameter; lazily initialized; defaults to a unspecified,
+	 * legal node.
+	 */
+	private SingleVariableDeclaration parameter = null;
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The body statement; lazily initialized; defaults to an empty block
+	 * statement.
+	 */
+	private Statement body = null;
+
+	/**
+	 * Creates a new AST node for an enchanced for statement owned by the
+	 * given AST. By default, the parameter and expression are unspecified
+	 * but legal subtrees, and the body is an empty block.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	EnhancedForStatement(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == PARAMETER_PROPERTY) {
+			if (get) {
+				return getParameter();
+			} else {
+				setParameter((SingleVariableDeclaration) child);
+				return null;
+			}
+		}
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Statement) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ENHANCED_FOR_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		EnhancedForStatement result = new EnhancedForStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setParameter((SingleVariableDeclaration) getParameter().clone(target));
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setBody(
+			(Statement) ASTNode.copySubtree(target, getBody()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getParameter());
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the formal parameter in this enhanced for statement.
+	 *
+	 * @return the parameter
+	 */
+	public SingleVariableDeclaration getParameter() {
+		if (this.parameter == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.parameter == null) {
+					preLazyInit();
+					this.parameter = this.ast.newSingleVariableDeclaration();
+					postLazyInit(this.parameter, PARAMETER_PROPERTY);
+				}
+			}
+		}
+		return this.parameter;
+	}
+
+	/**
+	 * Sets the formal parameter in this enhanced for statement.
+	 *
+	 * @param parameter the new parameter
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setParameter(SingleVariableDeclaration parameter) {
+		if (parameter == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.parameter;
+		preReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
+		this.parameter = parameter;
+		postReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
+	}
+
+	/**
+	 * Returns the expression of this enhanced for statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this enhanced for statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the body of this enchanced for statement.
+	 *
+	 * @return the body statement node
+	 */
+	public Statement getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this enhanced for statement.
+	 *
+	 * @param statement the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, statement, BODY_PROPERTY);
+		this.body = statement;
+		postReplaceChild(oldChild, statement, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.parameter == null ? 0 : getParameter().treeSize())
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java
new file mode 100644
index 0000000..e7643ba
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Enumeration constant declaration AST node type (added in JLS3 API).
+ *
+ * <pre>
+ * EnumConstantDeclaration:
+ *     [ Javadoc ] { ExtendedModifier } Identifier
+ *         [ <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> ]
+ *         [ AnonymousClassDeclaration ]
+ * </pre>
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the identifier. If there are class body declarations, the
+ * source range extends through the last character of the last character of
+ * the "}" token following the body declarations. If there are arguments but
+ * no class body declarations, the source range extends through the last
+ * character of the ")" token following the arguments. If there are no
+ * arguments and no class body declarations, the source range extends through
+ * the last character of the identifier.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class EnumConstantDeclaration extends BodyDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(EnumConstantDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}).
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(EnumConstantDeclaration.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(EnumConstantDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(EnumConstantDeclaration.class, "arguments", Expression.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "anonymousClassDeclaration" structural property of this node type (child type: {@link AnonymousClassDeclaration}).
+	 */
+	public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY =
+		new ChildPropertyDescriptor(EnumConstantDeclaration.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(6);
+		createPropertyList(EnumConstantDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The constant name; lazily initialized; defaults to a unspecified,
+	 * legal Java class identifier.
+	 */
+	private SimpleName constantName = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * The optional anonymous class declaration; <code>null</code> for none;
+	 * defaults to none.
+	 */
+	private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
+
+	/**
+	 * Creates a new AST node for an enumeration constants declaration owned by
+	 * the given AST. By default, the enumeration constant has an unspecified,
+	 * but legal, name; no javadoc; an empty list of modifiers and annotations;
+	 * an empty list of arguments; and does not declare an anonymous class.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	EnumConstantDeclaration(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
+			if (get) {
+				return getAnonymousClassDeclaration();
+			} else {
+				setAnonymousClassDeclaration((AnonymousClassDeclaration) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		// this property will not be asked for (node type did not exist in JLS2)
+		return null;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ENUM_CONSTANT_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		EnumConstantDeclaration result = new EnumConstantDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		result.setName((SimpleName) getName().clone(target));
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		result.setAnonymousClassDeclaration(
+				(AnonymousClassDeclaration) ASTNode.copySubtree(target, getAnonymousClassDeclaration()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			acceptChildren(visitor, this.modifiers);
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.arguments);
+			acceptChild(visitor, getAnonymousClassDeclaration());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the name of the constant declared in this enum declaration.
+	 *
+	 * @return the constant name node
+	 */
+	public SimpleName getName() {
+		if (this.constantName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.constantName == null) {
+					preLazyInit();
+					this.constantName = new SimpleName(this.ast);
+					postLazyInit(this.constantName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.constantName;
+	}
+
+	/**
+	 * Sets the name of the constant declared in this enum declaration to the
+	 * given name.
+	 *
+	 * @param constantName the new constant name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName constantName) {
+		if (constantName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.constantName;
+		preReplaceChild(oldChild, constantName, NAME_PROPERTY);
+		this.constantName = constantName;
+		postReplaceChild(oldChild, constantName, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this enumeration
+	 * constant declaration. Note that an empty list of arguments is equivalent
+	 * to not explicitly specifying arguments.
+	 *
+	 * @return the live list of argument expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Returns the anonymous class declaration introduced by this
+	 * enum constant declaration, if it has one.
+	 *
+	 * @return the anonymous class declaration, or <code>null</code> if none
+	 */
+	public AnonymousClassDeclaration getAnonymousClassDeclaration() {
+		return this.optionalAnonymousClassDeclaration;
+	}
+
+	/**
+	 * Sets whether this enum constant declaration declares
+	 * an anonymous class (that is, has class body declarations).
+	 *
+	 * @param decl the anonymous class declaration, or <code>null</code>
+	 *    if none
+	 */
+	public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
+		ASTNode oldChild = this.optionalAnonymousClassDeclaration;
+		preReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+		this.optionalAnonymousClassDeclaration = decl;
+		postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor invoked by this
+	 * enum constant.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the constructor binding, or <code>null</code> if the binding
+	 *    cannot be resolved
+	 */
+	public IMethodBinding resolveConstructorBinding() {
+		return this.ast.getBindingResolver().resolveConstructor(this);
+	}
+
+	/**
+	 * Resolves and returns the field binding for this enum constant.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IVariableBinding resolveVariable() {
+		return this.ast.getBindingResolver().resolveVariable(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ this.modifiers.listSize()
+			+ (this.constantName == null ? 0 : getName().treeSize())
+			+ this.arguments.listSize()
+			+ (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
new file mode 100644
index 0000000..45e0499
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
@@ -0,0 +1,335 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Enum declaration AST node type (added in JLS3 API).
+ *
+ * <pre>
+ * EnumDeclaration:
+ *     [ Javadoc ] { ExtendedModifier } <b>enum</b> Identifier
+ *         [ <b>implements</b> Type { <b>,</b> Type } ]
+ *         <b>{</b>
+ *         [ EnumConstantDeclaration { <b>,</b> EnumConstantDeclaration } ] [ <b>,</b> ]
+ *         [ <b>;</b> { ClassBodyDeclaration | <b>;</b> } ]
+ *         <b>}</b>
+ * </pre>
+ * The {@link #enumConstants()} list holds the enum constant declarations,
+ * while the {@link #bodyDeclarations()} list holds the class body declarations
+ * that appear after the semicolon.
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier or annotation (if present), or the
+ * first character of the "enum" keyword (if no
+ * modifiers or annotations). The source range extends through the last
+ * character of the "}" token following the body declarations.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class EnumDeclaration extends AbstractTypeDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(EnumDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(EnumDeclaration.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		internalNamePropertyFactory(EnumDeclaration.class);
+
+	/**
+	 * The "superInterfaceTypes" structural property of this node type (element type: {@link Type}).
+	 */
+	public static final ChildListPropertyDescriptor SUPER_INTERFACE_TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(EnumDeclaration.class, "superInterfaceTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "enumConstants" structural property of this node type (element type: {@link EnumConstantDeclaration}).
+	 */
+	public static final ChildListPropertyDescriptor ENUM_CONSTANTS_PROPERTY =
+		new ChildListPropertyDescriptor(EnumDeclaration.class, "enumConstants", EnumConstantDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}).
+	 */
+	public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
+		internalBodyDeclarationPropertyFactory(EnumDeclaration.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(6);
+		createPropertyList(EnumDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(SUPER_INTERFACE_TYPES_PROPERTY, properyList);
+		addProperty(ENUM_CONSTANTS_PROPERTY, properyList);
+		addProperty(BODY_DECLARATIONS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The superinterface types (element type: {@link Type}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList superInterfaceTypes =
+		new ASTNode.NodeList(SUPER_INTERFACE_TYPES_PROPERTY);
+
+	/**
+	 * The enum constant declarations
+	 * (element type: {@link EnumConstantDeclaration}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList enumConstants =
+		new ASTNode.NodeList(ENUM_CONSTANTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for an enum declaration owned by the given
+	 * AST. By default, the enum declaration has an unspecified, but legal,
+	 * name; no modifiers; no javadoc; no superinterfaces;
+	 * and empty lists of enum constants and body declarations.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	EnumDeclaration(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == SUPER_INTERFACE_TYPES_PROPERTY) {
+			return superInterfaceTypes();
+		}
+		if (property == ENUM_CONSTANTS_PROPERTY) {
+			return enumConstants();
+		}
+		if (property == BODY_DECLARATIONS_PROPERTY) {
+			return bodyDeclarations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		// this property will not be asked for (node type did not exist in JLS2)
+		return null;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildPropertyDescriptor internalNameProperty() {
+		return NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
+		return BODY_DECLARATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return ENUM_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		EnumDeclaration result = new EnumDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		result.setName((SimpleName) getName().clone(target));
+		result.superInterfaceTypes().addAll(
+			ASTNode.copySubtrees(target, superInterfaceTypes()));
+		result.enumConstants().addAll(
+				ASTNode.copySubtrees(target, enumConstants()));
+		result.bodyDeclarations().addAll(
+			ASTNode.copySubtrees(target, bodyDeclarations()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			acceptChildren(visitor, this.modifiers);
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.superInterfaceTypes);
+			acceptChildren(visitor, this.enumConstants);
+			acceptChildren(visitor, this.bodyDeclarations);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of superinterfaces of this enum
+	 * declaration.
+	 *
+	 * @return the live list of super interface types
+	 *    (element type: {@link Type})
+	 */
+	public List superInterfaceTypes() {
+		return this.superInterfaceTypes;
+	}
+
+	/**
+	 * Returns the live ordered list of enum constant declarations
+	 * of this enum declaration.
+	 *
+	 * @return the live list of enum constant declarations
+	 *    (element type: {@link EnumConstantDeclaration})
+	 */
+	public List enumConstants() {
+		return this.enumConstants;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AsbtractTypeDeclaration.
+	 */
+	ITypeBinding internalResolveBinding() {
+		return this.ast.getBindingResolver().resolveType(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ this.modifiers.listSize()
+			+ (this.typeName == null ? 0 : getName().treeSize())
+			+ this.superInterfaceTypes.listSize()
+			+ this.enumConstants.listSize()
+			+ this.bodyDeclarations.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
new file mode 100644
index 0000000..a5b6dab
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Abstract base class of AST nodes that represent expressions.
+ * There are several kinds of expressions.
+ * <p>
+ * <pre>
+ * Expression:
+ *    {@link Annotation},
+ *    {@link ArrayAccess},
+ *    {@link ArrayCreation},
+ *    {@link ArrayInitializer},
+ *    {@link Assignment},
+ *    {@link BooleanLiteral},
+ *    {@link CastExpression},
+ *    {@link CharacterLiteral},
+ *    {@link ClassInstanceCreation},
+ *    {@link ConditionalExpression},
+ *    {@link CreationReference},
+ *    {@link ExpressionMethodReference},
+ *    {@link FieldAccess},
+ *    {@link InfixExpression},
+ *    {@link InstanceofExpression},
+ *    {@link LambdaExpression},
+ *    {@link MethodInvocation},
+ *    {@link MethodReference},
+ *    {@link Name},
+ *    {@link NullLiteral},
+ *    {@link NumberLiteral},
+ *    {@link ParenthesizedExpression},
+ *    {@link PostfixExpression},
+ *    {@link PrefixExpression},
+ *    {@link StringLiteral},
+ *    {@link SuperFieldAccess},
+ *    {@link SuperMethodInvocation},
+ *    {@link SuperMethodReference},
+ *    {@link ThisExpression},
+ *    {@link TypeLiteral},
+ *    {@link TypeMethodReference},
+ *    {@link VariableDeclarationExpression}
+ * </pre>
+ * </p>
+ *
+ * @since 2.0
+ */
+public abstract class Expression extends ASTNode {
+
+	/**
+	 * Creates a new AST node for an expression owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Expression(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * Resolves and returns the compile-time constant expression value as
+	 * specified in JLS2 15.28, if this expression has one. Constant expression
+	 * values are unavailable unless bindings are requested when the AST is
+	 * being built. If the type of the value is a primitive type, the result
+	 * is the boxed equivalent (i.e., int returned as an <code>Integer</code>);
+	 * if the type of the value is <code>String</code>, the result is the string
+	 * itself. If the expression does not have a compile-time constant expression
+	 * value, the result is <code>null</code>.
+	 * <p>
+	 * Resolving constant expressions takes into account the value of simple
+	 * and qualified names that refer to constant variables (JLS2 4.12.4).
+	 * </p>
+	 * <p>
+	 * Note 1: enum constants are not considered constant expressions.
+	 * The result is always <code>null</code> for these.
+	 * </p>
+	 * <p>
+	 * Note 2: Compile-time constant expressions cannot denote <code>null</code>.
+	 * So technically {@link NullLiteral} nodes are not constant expressions.
+	 * The result is <code>null</code> for these nonetheless.
+	 * </p>
+	 *
+	 * @return the constant expression value, or <code>null</code> if this
+	 * expression has no constant expression value or if bindings were not
+	 * requested when the AST was created
+	 * @since 3.1
+	 */
+	public final Object resolveConstantExpressionValue() {
+		return this.ast.getBindingResolver().resolveConstantExpressionValue(this);
+	}
+
+	/**
+	 * Resolves and returns the binding for the type of this expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding for the type of this expression, or
+	 *    <code>null</code> if the type cannot be resolved
+	 */
+	public final ITypeBinding resolveTypeBinding() {
+		return this.ast.getBindingResolver().resolveExpressionType(this);
+	}
+
+	/**
+	 * Returns whether this expression node is the site of a boxing
+	 * conversion (JLS3 5.1.7). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if this expression is the site of a
+	 * boxing conversion, or <code>false</code> if either no boxing conversion
+	 * is involved or if bindings were not requested when the AST was created
+	 * @since 3.1
+	 */
+	public final boolean resolveBoxing() {
+		return this.ast.getBindingResolver().resolveBoxing(this);
+	}
+
+	/**
+	 * Returns whether this expression node is the site of an unboxing
+	 * conversion (JLS3 5.1.8). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if this expression is the site of an
+	 * unboxing conversion, or <code>false</code> if either no unboxing
+	 * conversion is involved or if bindings were not requested when the
+	 * AST was created
+	 * @since 3.1
+	 */
+	public final boolean resolveUnboxing() {
+		return this.ast.getBindingResolver().resolveUnboxing(this);
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java
new file mode 100644
index 0000000..b98eba8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionMethodReference.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Expression method reference AST node type (added in JLS8 API).
+ * <pre>
+ * ExpressionMethodReference:
+ *     Expression <b>::</b> 
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         Identifier
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ExpressionMethodReference extends MethodReference {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ExpressionMethodReference.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) 
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		internalTypeArgumentsFactory(ExpressionMethodReference.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}. 
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(ExpressionMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(ExpressionMethodReference.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified,
+	 * legal expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to an unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * Creates a new AST node for an ExpressionMethodReference declaration owned
+	 * by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ExpressionMethodReference(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on MethodReference.
+	 */
+	final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+		return TYPE_ARGUMENTS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return EXPRESSION_METHOD_REFERENCE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ExpressionMethodReference result = new ExpressionMethodReference(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		result.setName((SimpleName) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChildren(visitor, this.typeArguments);
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this expression method reference expression
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this expression method reference.
+	 *
+	 * @param expression the expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this expression method reference
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the name of the method referenced in this expression.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method referenced in this expression to the
+	 * given name.
+	 *
+	 * @param name the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java
new file mode 100644
index 0000000..e098950
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Expression statement AST node type.
+ * <p>
+ * This kind of node is used to convert an expression (<code>Expression</code>)
+ * into a statement (<code>Statement</code>) by wrapping it.
+ * </p>
+ * <pre>
+ * ExpressionStatement:
+ *    StatementExpression <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ExpressionStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ExpressionStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(ExpressionStatement.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * Creates a new unparented expression statement node owned by the given
+	 * AST. By default, the expression statement is unspecified, but legal,
+	 * method invocation expression.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ExpressionStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return EXPRESSION_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ExpressionStatement result = new ExpressionStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this expression statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new MethodInvocation(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this expression statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java
new file mode 100644
index 0000000..306abe9
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExtraDimension.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The extra dimension node. An extra dimension, represented as <b>[]</b>, can have
+ * type annotations. This node type is supported only in JLS8 or later.
+ * <p>
+ * The extra dimension node is used to represent an extra dimension in the following node types:
+ * {@link SingleVariableDeclaration}, {@link VariableDeclarationFragment}, {@link MethodDeclaration}.
+ * It is not used for annotations on an {@link ArrayType}, since that type extends {@link AnnotatableType} now.
+ * </p>
+ * 
+ * <pre>
+ * ExtraDimension:
+ * 	{ Annotation } <b>[]</b>
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ExtraDimension extends ASTNode {
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+		new ChildListPropertyDescriptor(ExtraDimension.class, "annotations", Annotation.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ExtraDimension.class, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The list of annotations for this dimension (element type: {@link Annotation}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY);
+
+	/**
+	 * Creates a new extra dimension node (Supported only in level
+	 * JLS8 or above).
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2, JLS3 or JLS4 AST
+	 */
+	ExtraDimension(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return EXTRA_DIMENSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ExtraDimension result = new ExtraDimension(target);
+		result.annotations().addAll(
+				ASTNode.copySubtrees(target, annotations()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.annotations);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of annotations for this dimension.
+	 *
+	 * @return the live list of annotations (element type: {@link Annotation})
+	 */
+	public List annotations() {
+		return this.annotations;
+	}
+
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	int treeSize() {
+		return
+			memSize()
+			+ this.annotations.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java
new file mode 100644
index 0000000..8efcb7f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Field access expression AST node type.
+ *
+ * <pre>
+ * FieldAccess:
+ * 		Expression <b>.</b> Identifier
+ * </pre>
+ *
+ * <p>
+ * Note that there are several kinds of expressions that resemble field access
+ * expressions: qualified names, this expressions, and super field access
+ * expressions. The following guidelines help with correct usage:
+ * <ul>
+ *   <li>An expression like "foo.this" can only be represented as a this
+ *   expression (<code>ThisExpression</code>) containing a simple name.
+ *   "this" is a keyword, and therefore invalid as an identifier.</li>
+ *   <li>An expression like "this.foo" can only be represented as a field
+ *   access expression (<code>FieldAccess</code>) containing a this expression
+ *   and a simple name. Again, this is because "this" is a keyword, and
+ *   therefore invalid as an identifier.</li>
+ *   <li>An expression with "super" can only be represented as a super field
+ *   access expression (<code>SuperFieldAccess</code>). "super" is a also
+ *   keyword, and therefore invalid as an identifier.</li>
+ *   <li>An expression like "foo.bar" can be represented either as a
+ *   qualified name (<code>QualifiedName</code>) or as a field access
+ *   expression (<code>FieldAccess</code>) containing simple names. Either
+ *   is acceptable, and there is no way to choose between them without
+ *   information about what the names resolve to
+ *   (<code>ASTParser</code> may return either).</li>
+ *   <li>Other expressions ending in an identifier, such as "foo().bar" can
+ *   only be represented as field access expressions
+ *   (<code>FieldAccess</code>).</li>
+ * </ul>
+ * </p>
+ *
+ * @see QualifiedName
+ * @see ThisExpression
+ * @see SuperFieldAccess
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class FieldAccess extends Expression {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(FieldAccess.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(FieldAccess.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(FieldAccess.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The field; lazily initialized; defaults to an unspecified,
+	 * but legal, simple field name.
+	 */
+	private SimpleName fieldName = null;
+
+	/**
+	 * Creates a new unparented node for a field access expression owned by the
+	 * given AST. By default, the expression and field are both unspecified,
+	 * but legal, names.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	FieldAccess(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return FIELD_ACCESS;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		FieldAccess result = new FieldAccess(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setName((SimpleName) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this field access expression.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this field access expression.
+	 *
+	 * @param expression the new expression
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the name of the field accessed in this field access expression.
+	 *
+	 * @return the field name
+	 */
+	public SimpleName getName() {
+		if (this.fieldName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.fieldName == null) {
+					preLazyInit();
+					this.fieldName = new SimpleName(this.ast);
+					postLazyInit(this.fieldName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.fieldName;
+	}
+
+	/**
+	 * Sets the name of the field accessed in this field access expression.
+	 *
+	 * @param fieldName the field name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName fieldName) {
+		if (fieldName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.fieldName;
+		preReplaceChild(oldChild, fieldName, NAME_PROPERTY);
+		this.fieldName = fieldName;
+		postReplaceChild(oldChild, fieldName, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/**
+	 * Resolves and returns the binding for the field accessed by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the variable binding, or <code>null</code> if the binding cannot
+	 * be resolved
+	 * @since 3.0
+	 */
+	public IVariableBinding resolveFieldBinding() {
+		return this.ast.getBindingResolver().resolveField(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.fieldName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java
new file mode 100644
index 0000000..f36b0b4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Field declaration node type.
+ * <p>
+ * This kind of node collects several variable declaration fragments
+ * (<code>VariableDeclarationFragment</code>) into a single body declaration
+ * (<code>BodyDeclaration</code>), all sharing the same modifiers and base type.
+ * </p>
+ * <pre>
+ * FieldDeclaration:
+ *    [Javadoc] { ExtendedModifier } Type VariableDeclarationFragment
+ *         { <b>,</b> VariableDeclarationFragment } <b>;</b>
+ * </pre>
+ * <p>
+ * When a Javadoc comment is present, the source range begins with the first
+ * character of the "/**" comment delimiter. When there is no Javadoc comment,
+ * the source range begins with the first character of the initial modifier or
+ * type. The source range extends through the last character of the final ";".
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class FieldDeclaration extends BodyDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(FieldDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		internalModifiersPropertyFactory(FieldDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(FieldDeclaration.class);
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(FieldDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "fragments" structural property of this node type (element type: {@link VariableDeclarationFragment}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(FieldDeclaration.class, "fragments", VariableDeclarationFragment.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(5);
+		createPropertyList(FieldDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS_PROPERTY, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(FRAGMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(5);
+		createPropertyList(FieldDeclaration.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(FRAGMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The base type; lazily initialized; defaults to an unspecified,
+	 * legal type.
+	 */
+	private Type baseType = null;
+
+	/**
+	 * The list of variable declaration fragments (element type:
+	 * {@link VariableDeclarationFragment}).  Defaults to an empty list.
+	 */
+	private ASTNode.NodeList variableDeclarationFragments =
+		new ASTNode.NodeList(FRAGMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented field declaration statement node owned
+	 * by the given AST.  By default, the field declaration has: no modifiers,
+	 * an unspecified (but legal) type, and an empty list of variable
+	 * declaration fragments (which is syntactically illegal).
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	FieldDeclaration(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				internalSetModifiers(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == FRAGMENTS_PROPERTY) {
+			return fragments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		return MODIFIERS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return FIELD_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		FieldDeclaration result = new FieldDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		}
+		result.setType((Type) getType().clone(target));
+		result.fragments().addAll(
+			ASTNode.copySubtrees(target, fragments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.modifiers);
+			}
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.variableDeclarationFragments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the base type declared in this field declaration.
+	 * <p>
+	 * N.B. The individual child variable declaration fragments may specify
+	 * additional array dimensions. So the type of the variable are not
+	 * necessarily exactly this type.
+	 * </p>
+	 *
+	 * @return the base type
+	 */
+	public Type getType() {
+		if (this.baseType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.baseType == null) {
+					preLazyInit();
+					this.baseType = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.baseType, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.baseType;
+	}
+
+	/**
+	 * Sets the base type declared in this field declaration to the given type.
+	 *
+	 * @param type the new base type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.baseType;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.baseType = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live list of variable declaration fragments in this field
+	 * declaration. Adding and removing nodes from this list affects this node
+	 * dynamically. All nodes in this list must be
+	 * <code>VariableDeclarationFragment</code>s; attempts to add any other
+	 * type of node will trigger an exception.
+	 *
+	 * @return the live list of variable declaration fragments in this
+	 *    statement (element type: {@link VariableDeclarationFragment})
+	 */
+	public List fragments() {
+		return this.variableDeclarationFragments;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.baseType == null ? 0 : getType().treeSize())
+			+ this.variableDeclarationFragments.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FileASTRequestor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FileASTRequestor.java
new file mode 100644
index 0000000..0a96f51
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FileASTRequestor.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * An AST requestor handles ASTs for compilation units passed to
+ * {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * <p>
+ * {@link FileASTRequestor#acceptAST(String, CompilationUnit) FileASTRequestor.acceptAST} is called for each of the
+ * compilation units passed to {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * After all the compilation units have been processed,
+ * {@link #acceptBinding(String, IBinding) FileASTRequestor.acceptBinding} is called for each
+ * of the binding keys passed to {@link ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor) ASTParser.createASTs}.
+ * </p>
+ * <p>
+ * This class is intended to be subclassed by clients.
+ * AST requestors are serially reusable, but neither reentrant nor thread-safe.
+ * </p>
+ *
+ * @see ASTParser#createASTs(String[], String[], String[], FileASTRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ * @since 3.6
+ */
+public abstract class FileASTRequestor {
+
+	/**
+	 * The compilation unit resolver used to resolve bindings, or
+	 * <code>null</code> if none. Note that this field is non-null
+	 * only within the dynamic scope of a call to
+	 * <code>ASTParser.createASTs</code>.
+	 */
+	CompilationUnitResolver compilationUnitResolver = null;
+
+	/**
+	 * Accepts an AST corresponding to the compilation unit.
+	 * That is, <code>ast</code> is an AST for <code>source</code>.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients should override to process the resulting AST.
+	 * </p>
+	 *
+	 * @param sourceFilePath the compilation unit the given ast is coming from
+	 * @param ast the requested abstract syntax tree
+	 */
+	public void acceptAST(String sourceFilePath, CompilationUnit ast) {
+		// do nothing
+	}
+
+	/**
+	 * Accepts a binding corresponding to the binding key.
+	 * That is, <code>binding</code> is the binding for
+	 * <code>bindingKey</code>; <code>binding</code> is <code>null</code>
+	 * if the key cannot be resolved.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients should override to process the resulting binding.
+	 * </p>
+	 *
+	 * @param bindingKey the key of the requested binding
+	 * @param binding the requested binding, or <code>null</code> if none
+	 */
+	public void acceptBinding(String bindingKey, IBinding binding) {
+		// do nothing
+	}
+
+	/**
+	 * Resolves bindings for the given binding keys.
+	 * The given binding keys must have been obtained earlier
+	 * using {@link IBinding#getKey()}.
+	 * <p>
+	 * If a binding key cannot be resolved, <code>null</code> is put in the resulting array.
+	 * Bindings can only be resolved in the dynamic scope of a <code>ASTParser.createASTs</code>,
+	 * and only if <code>ASTParser.resolveBindings(true)</code> was specified.
+	 * </p>
+	 * <p>
+	 * Caveat: During an <code>acceptAST</code> callback, there are implementation
+	 * limitations concerning the look up of binding keys representing local elements.
+	 * In some cases, the binding is unavailable, and <code>null</code> will be returned.
+	 * This is only an issue during an <code>acceptAST</code> callback, and only
+	 * when the binding key represents a local element (e.g., local variable,
+	 * local class, method declared in anonymous class). There is no such limitation
+	 * outside of <code>acceptAST</code> callbacks, or for top-level types and their
+	 * members even within <code>acceptAST</code> callbacks.
+	 * </p>
+	 *
+	 * @param bindingKeys the binding keys to look up
+	 * @return a list of bindings paralleling the <code>bindingKeys</code> parameter,
+	 * with <code>null</code> entries for keys that could not be resolved
+	 */
+	public final IBinding[] createBindings(String[] bindingKeys) {
+		int length = bindingKeys.length;
+		IBinding[] result = new IBinding[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = null;
+			if (this.compilationUnitResolver != null) {
+				result[i] = this.compilationUnitResolver.createBinding(bindingKeys[i]);
+			}
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java
new file mode 100644
index 0000000..38c373d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * For statement AST node type.
+ *
+ * <pre>
+ * ForStatement:
+ *    <b>for</b> <b>(</b>
+ * 			[ ForInit ]<b>;</b>
+ * 			[ Expression ] <b>;</b>
+ * 			[ ForUpdate ] <b>)</b>
+ * 			Statement
+ * ForInit:
+ * 		Expression { <b>,</b> Expression }
+ * ForUpdate:
+ * 		Expression { <b>,</b> Expression }
+ * </pre>
+ * <p>
+ * Note: When variables are declared in the initializer
+ * of a for statement such as "<code>for (int a=1, b=2;;);</code>",
+ * they should be represented as a single
+ * <code>VariableDeclarationExpression</code>
+ * with two fragments, rather than being split up into a pair
+ * of expressions.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ForStatement extends Statement {
+
+	/**
+	 * The "initializers" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor INITIALIZERS_PROPERTY =
+		new ChildListPropertyDescriptor(ForStatement.class, "initializers", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ForStatement.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "updaters" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor UPDATERS_PROPERTY =
+		new ChildListPropertyDescriptor(ForStatement.class, "updaters", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(ForStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(5);
+		createPropertyList(ForStatement.class, properyList);
+		addProperty(INITIALIZERS_PROPERTY, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(UPDATERS_PROPERTY, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The list of initializer expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList initializers =
+		new ASTNode.NodeList(INITIALIZERS_PROPERTY);
+
+	/**
+	 * The condition expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalConditionExpression = null;
+
+	/**
+	 * The list of update expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList updaters =
+		new ASTNode.NodeList(UPDATERS_PROPERTY);
+
+	/**
+	 * The body statement; lazily initialized; defaults to an empty block
+	 * statement.
+	 */
+	private Statement body = null;
+
+	/**
+	 * Creates a new AST node for a for statement owned by the given AST.
+	 * By default, there are no initializers, no condition expression,
+	 * no updaters, and the body is an empty block.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ForStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Statement) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == INITIALIZERS_PROPERTY) {
+			return initializers();
+		}
+		if (property == UPDATERS_PROPERTY) {
+			return updaters();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return FOR_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ForStatement result = new ForStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.initializers().addAll(ASTNode.copySubtrees(target, initializers()));
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		result.updaters().addAll(ASTNode.copySubtrees(target, updaters()));
+		result.setBody(
+			(Statement) ASTNode.copySubtree(target, getBody()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.initializers);
+			acceptChild(visitor, getExpression());
+			acceptChildren(visitor, this.updaters);
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of initializer expressions in this for
+	 * statement.
+	 * <p>
+	 * The list should consist of either a list of so called statement
+	 * expressions (JLS2, 14.8), or a single <code>VariableDeclarationExpression</code>.
+	 * Otherwise, the for statement would have no Java source equivalent.
+	 * </p>
+	 *
+	 * @return the live list of initializer expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List initializers() {
+		return this.initializers;
+	}
+
+	/**
+	 * Returns the condition expression of this for statement, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the condition expression node, or <code>null</code> if
+	 *     there is none
+	 */
+	public Expression getExpression() {
+		return this.optionalConditionExpression;
+	}
+
+	/**
+	 * Sets or clears the condition expression of this return statement.
+	 *
+	 * @param expression the condition expression node, or <code>null</code>
+	 *    if there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		ASTNode oldChild = this.optionalConditionExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalConditionExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of update expressions in this for
+	 * statement.
+	 * <p>
+	 * The list should consist of so called statement expressions. Otherwise,
+	 * the for statement would have no Java source equivalent.
+	 * </p>
+	 *
+	 * @return the live list of update expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List updaters() {
+		return this.updaters;
+	}
+
+	/**
+	 * Returns the body of this for statement.
+	 *
+	 * @return the body statement node
+	 */
+	public Statement getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this for statement.
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the body of a for statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the body of a <code>ForStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, statement, BODY_PROPERTY);
+		this.body = statement;
+		postReplaceChild(oldChild, statement, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ this.initializers.listSize()
+			+ this.updaters.listSize()
+			+ (this.optionalConditionExpression == null ? 0 : getExpression().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IAnnotationBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IAnnotationBinding.java
new file mode 100644
index 0000000..516692b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IAnnotationBinding.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *    IBM Corporation - changed interface to extend IBinding
+ *    IBM Corporation - renamed from IResolvedAnnotation to IAnnotationBinding
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Represents a resolved annotation. Resolved annotations are computed along with other
+ * bindings; they correspond to {@link Annotation} nodes.
+ *
+ * @since 3.2
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAnnotationBinding extends IBinding {
+
+	/**
+	 * Returns the complete list of member value pairs for this annotation, including
+	 * ones explicitly listed in the annotation as well as entries for
+	 * annotation type members with default values that are implied.
+	 *
+	 * @return a possibly empty list of resolved member value pairs
+	 */
+	IMemberValuePairBinding[] getAllMemberValuePairs();
+
+	/**
+	 * Returns the type of the annotation. The resulting type binding will always
+	 * return <code>true</code>	to <code>ITypeBinding.isAnnotation()</code>.
+	 *
+	 * @return the type of the annotation
+	 */
+	ITypeBinding getAnnotationType();
+
+	/**
+	 * Returns the list of declared member value pairs for this annotation.
+	 * Returns an empty list for a {@link MarkerAnnotation}, a one element
+	 * list for a {@link SingleMemberAnnotation}, and one entry for each
+	 * of the explicitly listed values in a {@link NormalAnnotation}.
+	 * <p>
+	 * Note that the list only includes entries for annotation type members that are
+	 * explicitly mentioned in the annotation. The list does not include any
+	 * annotation type members with default values that are merely implied.
+	 * Use {@link #getAllMemberValuePairs()} to get those as well.
+	 * </p>
+	 *
+	 * @return a possibly empty list of resolved member value pairs
+	 */
+	IMemberValuePairBinding[] getDeclaredMemberValuePairs();
+
+	/**
+	 * Returns the name of the annotation type.
+	 *
+	 * @return the name of the annotation type
+	 */
+	public String getName();
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java
new file mode 100644
index 0000000..06678c1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A binding represents a named entity in the Java language. The world of
+ * bindings provides an integrated picture of the structure of the program as
+ * seen from the compiler's point of view. This interface declare protocol
+ * common to the various different kinds of named entities in the Java language:
+ * packages, types, fields, methods, constructors, and local variables.
+ *
+ * @see IPackageBinding
+ * @see ITypeBinding
+ * @see IVariableBinding
+ * @see IMethodBinding
+ * @see IAnnotationBinding
+ * @see IMemberValuePairBinding
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IBinding {
+
+	/**
+	 * Kind constant (value 1) indicating a package binding.
+	 * Bindings of this kind can be safely cast to <code>IPackageBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see IPackageBinding
+	 */
+	public static final int PACKAGE = 1;
+
+	/**
+	 * Kind constant (value 2) indicating a type binding.
+	 * Bindings of this kind can be safely cast to <code>ITypeBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see ITypeBinding
+	 */
+	public static final int TYPE = 2;
+
+	/**
+	 * Kind constant (value 3) indicating a field or local variable binding.
+	 * Bindings of this kind can be safely cast to <code>IVariableBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see IVariableBinding
+	 */
+	public static final int VARIABLE = 3;
+
+	/**
+	 * Kind constant (value 4) indicating a method or constructor binding.
+	 * Bindings of this kind can be safely cast to <code>IMethodBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see IMethodBinding
+	 */
+	public static final int METHOD = 4;
+
+	/**
+	 * Kind constant (value 5) indicating an annotation binding.
+	 * Bindings of this kind can be safely cast to <code>IAnnotationBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see IAnnotationBinding
+	 * @since 3.2
+	 */
+	public static final int ANNOTATION = 5;
+
+	/**
+	 * Kind constant (value 6) indicating a member value pair binding.
+	 * Bindings of this kind can be safely cast to <code>IMemberValuePairBinding</code>.
+	 *
+	 * @see #getKind()
+	 * @see IMemberValuePairBinding
+	 * @since 3.2
+	 */
+	public static final int MEMBER_VALUE_PAIR = 6;
+
+	/**
+	 * Return the resolved annotations associated with this binding.
+	 * <ul>
+	 * <li>Package bindings - these are annotations on a package declaration.
+	 * </li>
+	 * <li>Type bindings - these are annotations on a class, interface, enum,
+	 * or annotation type declaration. The result is the same regardless of
+	 * whether the type is parameterized.</li>
+	 * <li>Method bindings - these are annotations on a method or constructor
+	 * declaration. The result is the same regardless of whether the method is
+	 * parameterized.</li>
+	 * <li>Variable bindings - these are annotations on a field, enum constant,
+	 * or formal parameter declaration.</li>
+	 * <li>Annotation bindings - an empty array is always returned</li>
+	 * <li>Member value pair bindings - an empty array is always returned</li>
+	 * </ul>
+	 *
+	 * @return the list of resolved annotations, or the empty list if there are no
+	 * annotations associated with the object
+	 * @since 3.2
+	 */
+	public IAnnotationBinding[] getAnnotations();
+
+	/**
+	 * Returns the kind of bindings this is. That is one of the kind constants:
+	 * <code>PACKAGE</code>,
+	 * 	<code>TYPE</code>,
+	 * 	<code>VARIABLE</code>,
+	 * 	<code>METHOD</code>,
+	 * 	<code>ANNOTATION</code>,
+	 * or <code>MEMBER_VALUE_PAIR</code>.
+	 * <p>
+	 * Note that additional kinds might be added in the
+	 * future, so clients should not assume this list is exhaustive and
+	 * should program defensively, e.g. by having a reasonable default
+	 * in a switch statement.
+	 * </p>
+	 * @return one of the kind constants
+	 */
+	public int getKind();
+
+	/**
+	 * Returns the name of this binding.
+	 * Details of the name are specified with each specific kind of binding.
+	 *
+	 * @return the name of this binding
+	 */
+	public String getName();
+
+	/**
+	 * Returns the modifiers for this binding.
+	 * <p>
+	 * Note that deprecated is not included among the modifiers.
+	 * Use <code>isDeprecated</code> to find out whether a binding is deprecated.
+	 * </p>
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see Modifier
+	 */
+	public int getModifiers();
+
+	/**
+	 * Return whether this binding is for something that is deprecated.
+	 * A deprecated class, interface, field, method, or constructor is one that
+	 * is marked with the 'deprecated' tag in its Javadoc comment.
+	 *
+	 * @return <code>true</code> if this binding is deprecated, and
+	 *    <code>false</code> otherwise
+	 */
+	public boolean isDeprecated();
+
+	/**
+	 * Return whether this binding is created because the bindings recovery is enabled. This binding is considered
+	 * to be incomplete. Its internal state might be incomplete.
+	 *
+	 * @return <code>true</code> if this binding is a recovered binding, and
+	 *    <code>false</code> otherwise
+	 * @since 3.3
+	 */
+	public boolean isRecovered();
+
+	/**
+	 * Returns whether this binding is synthetic. A synthetic binding is one that
+	 * was made up by the compiler, rather than something declared in the
+	 * source code. Note that default constructors (the 0-argument constructor that
+	 * the compiler generates for class declarations with no explicit constructors
+	 * declarations) are not generally considered synthetic (although they
+	 * may be if the class itself is synthetic).
+	 * But see {@link IMethodBinding#isDefaultConstructor() IMethodBinding.isDefaultConstructor}
+	 * for cases where the compiled-generated default constructor can be recognized
+	 * instead.
+	 *
+	 * @return <code>true</code> if this binding is synthetic, and
+	 *    <code>false</code> otherwise
+	 * @see IMethodBinding#isDefaultConstructor()
+	 */
+	public boolean isSynthetic();
+
+	/**
+	 * Returns the Java element that corresponds to this binding.
+	 * Returns <code>null</code> if this binding has no corresponding
+	 * Java element.
+	 * <p>
+	 * For array types, this method returns the Java element that corresponds
+	 * to the array's element type. For raw and parameterized types, this method
+	 * returns the Java element of the erasure. For annotations, this method
+	 * returns the Java element of the annotation (i.e. an {@link IAnnotation}).
+	 * </p>
+	 * <p>
+	 * Here are the cases where a <code>null</code> should be expected:
+	 * <ul>
+	 * <li>primitive types, including void</li>
+	 * <li>null type</li>
+	 * <li>wildcard types</li>
+	 * <li>capture types</li>
+	 * <li>array types of any of the above</li>
+	 * <li>the "length" field of an array type</li>
+	 * <li>the default constructor of a source class</li>
+	 * <li>the constructor of an anonymous class</li>
+	 * <li>member value pairs</li>
+	 * </ul>
+	 * For all other kind of type, method, variable, annotation and package bindings,
+	 * this method returns non-<code>null</code>.
+	 * </p>
+	 *
+	 * @return the Java element that corresponds to this binding,
+	 * 		or <code>null</code> if none
+	 * @since 3.1
+	 */
+	public IJavaElement getJavaElement();
+
+	/**
+	 * Returns the key for this binding.
+	 * <p>
+	 * Within a connected cluster of bindings (for example, all bindings
+	 * reachable from a given AST), each binding will have a distinct keys.
+	 * The keys are generated in a manner that is predictable and as
+	 * stable as possible. This last property makes these keys useful for
+	 * comparing bindings between disconnected clusters of bindings (for example,
+	 * the bindings between the "before" and "after" ASTs of the same
+	 * compilation unit).
+	 * </p>
+	 * <p>
+	 * The exact details of how the keys are generated is unspecified.
+	 * However, it is a function of the following information:
+	 * <ul>
+	 * <li>packages - the name of the package (for an unnamed package,
+	 *   some internal id)</li>
+	 * <li>classes or interfaces - the VM name of the type and the key
+	 *   of its package</li>
+	 * <li>array types - the key of the component type and number of
+	 *   dimensions</li>
+	 * <li>primitive types - the name of the primitive type</li>
+	 * <li>fields - the name of the field and the key of its declaring
+	 *   type</li>
+	 * <li>methods - the name of the method, the key of its declaring
+	 *   type, and the keys of the parameter types</li>
+	 * <li>constructors - the key of its declaring class, and the
+	 *   keys of the parameter types</li>
+	 * <li>local variables - the name of the local variable, the index of the
+	 *   declaring block relative to its parent, the key of its method</li>
+	 * <li>local types - the name of the type, the index of the declaring
+	 *   block relative to its parent, the key of its method</li>
+	 * <li>anonymous types - the occurence count of the anonymous
+	 *   type relative to its declaring type, the key of its declaring type</li>
+	 * <li>enum types - treated like classes</li>
+	 * <li>annotation types - treated like interfaces</li>
+	 * <li>type variables - the name of the type variable and
+	 * the key of the generic type or generic method that declares that
+	 * type variable</li>
+	 * <li>wildcard types - the key of the optional wildcard type bound</li>
+     * <li>capture type bindings - the key of the wildcard captured</li>
+	 * <li>generic type instances - the key of the generic type and the keys
+	 * of the type arguments used to instantiate it, and whether the
+	 * instance is explicit (a parameterized type reference) or
+	 * implicit (a raw type reference)</li>
+	 * <li>generic method instances - the key of the generic method and the keys
+	 * of the type arguments used to instantiate it, and whether the
+	 * instance is explicit (a parameterized method reference) or
+	 * implicit (a raw method reference)</li>
+	 * <li>members of generic type instances - the key of the generic type
+	 * instance and the key of the corresponding member in the generic
+	 * type</li>
+	 * <li>annotations - the key of the annotated element and the key of
+	 * the annotation type</li>
+	 * </ul>
+	 * </p>
+	 * <p>Note that the key for member value pair bindings is
+	 * not yet implemented. This returns <code>null</code> for this kind of bindings.<br>
+	 * Recovered bindings have a unique key.
+	 * </p>
+	 *
+	 * @return the key for this binding
+	 */
+	public String getKey();
+
+	/**
+	 * There is no special definition of equality for bindings; equality is
+	 * simply object identity.  Within the context of a single cluster of
+	 * bindings, each binding is represented by a distinct object. However,
+	 * between different clusters of bindings, the binding objects may or may
+	 * not be different; in these cases, the client should compare bindings
+	 * using {@link #isEqualTo(IBinding)}, which checks their keys.
+	 *
+	 * @param obj {@inheritDoc}
+	 * @return {@inheritDoc}
+	 */
+	public boolean equals(Object obj);
+
+	/**
+	 * Returns whether this binding has the same key as that of the given
+	 * binding. Within the context of a single cluster of bindings, each
+	 * binding is represented by a distinct object. However, between
+	 * different clusters of bindings, the binding objects may or may
+	 * not be different objects; in these cases, the binding keys
+	 * are used where available.
+	 *
+	 * @param binding the other binding, or <code>null</code>
+	 * @return <code>true</code> if the given binding is the identical
+	 * object as this binding, or if the keys of both bindings are the
+	 * same string; <code>false</code> if the given binding is
+	 * <code>null</code>, or if the bindings do not have the same key,
+	 * or if one or both of the bindings have no key
+	 * @see #getKey()
+	 * @since 3.1
+	 */
+	public boolean isEqualTo(IBinding binding);
+
+	/**
+	 * Returns a string representation of this binding suitable for debugging
+	 * purposes only.
+	 *
+	 * @return a debug string
+	 */
+	public String toString();
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
new file mode 100644
index 0000000..d492a90
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Internal marker-type interface used to tag node types that can legitimately
+ * be included in {@link TagElement#fragments() TagElement.fragments()}.
+ *
+ * @since 3.0
+ */
+interface IDocElement {
+	// marker-type interfaces have no members
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
new file mode 100644
index 0000000..7872c3f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Common interface for AST nodes that represent modifiers or
+ * annotations.
+ * <pre>
+ * ExtendedModifier:
+ *   Modifier
+ *   Annotation
+ * </pre>
+ * @since 3.1
+ */
+public interface IExtendedModifier {
+
+	/**
+	 * Returns whether this extended modifier is a standard modifier.
+	 *
+	 * @return <code>true</code> if this is a standard modifier
+	 * (instance of {@link Modifier}), and <code>false</code> otherwise
+	 */
+	public boolean isModifier();
+
+	/**
+	 * Returns whether this extended modifier is an annotation.
+	 *
+	 * @return <code>true</code> if this is an annotation
+	 * (instance of a subclass of {@link Annotation}), and
+	 * <code>false</code> otherwise
+	 */
+	public boolean isAnnotation();
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMemberValuePairBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMemberValuePairBinding.java
new file mode 100644
index 0000000..e1813a5
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMemberValuePairBinding.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *    IBM Corporation - changed interface to extend IBinding
+ *    IBM Corporation - renamed from IResolvedMemberValuePair to IMemberValuePairBinding
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Represents a resolved instance of an annotation's member value pair.
+ * Resolved annotation are computed along with other bindings; these objects
+ * correspond to {@link MemberValuePair} nodes.
+ *
+ * @since 3.2
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMemberValuePairBinding extends IBinding {
+/**
+ * Returns the name of the annotation type member.
+ *
+ * @return the name of the member
+ */
+public String getName();
+
+/**
+ * Returns the method binding corresponding to the named annotation type member.
+ *
+ * @return the method binding for the annotation type member
+ */
+public IMethodBinding getMethodBinding();
+
+/**
+ * Returns the resolved value. Resolved values are represented as follows:
+ * <ul>
+ * <li>Primitive type - the equivalent boxed object</li>
+ * <li>java.lang.Class - the <code>ITypeBinding</code> for the class object</li>
+ * <li>java.lang.String - the string value itself</li>
+ * <li>enum type - the <code>IVariableBinding</code> for the enum constant</li>
+ * <li>annotation type - an <code>IAnnotationBinding</code></li>
+ * <li>array type - an <code>Object[]</code> whose elements are as per above
+ * (the language only allows single dimensional arrays in annotations)</li>
+ * </ul>
+ *
+ * @return the resolved value, or <code>null</code> if none exists
+ */
+public Object getValue();
+
+/**
+ * @return <code>true</code> iff this member value pair's value is the default value.
+ *         Returns <code>false</code> otherwise.
+ */
+public boolean isDefault();
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
new file mode 100644
index 0000000..564b2a7
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A method binding represents a method or constructor of a class or interface.
+ * Method bindings usually correspond directly to method or
+ * constructor declarations found in the source code.
+ * However, in certain cases of references to a generic method,
+ * the method binding may correspond to a copy of a generic method
+ * declaration with substitutions for the method's type parameters
+ * (for these, <code>getTypeArguments</code> returns a non-empty
+ * list, and either <code>isParameterizedMethod</code> or
+ * <code>isRawMethod</code> returns <code>true</code>).
+ * And in certain cases of references to a method declared in a
+ * generic type, the method binding may correspond to a copy of a
+ * method declaration with substitutions for the type's type
+ * parameters (for these, <code>getTypeArguments</code> returns
+ * an empty list, and both <code>isParameterizedMethod</code> and
+ * <code>isRawMethod</code> return <code>false</code>).
+ *
+ * @see ITypeBinding#getDeclaredMethods()
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMethodBinding extends IBinding {
+
+	/**
+	 * Returns whether this binding is for a constructor or a method.
+	 *
+	 * @return <code>true</code> if this is the binding for a constructor,
+	 *    and <code>false</code> if this is the binding for a method
+	 */
+	public boolean isConstructor();
+
+	/**
+	 * Returns whether this binding is known to be a compiler-generated
+	 * default constructor.
+	 * <p>
+	 * This method returns <code>false</code> for:
+	 * <ul>
+	 * <li>methods</li>
+	 * <li>constructors with more than one parameter</li>
+	 * <li>0-argument constructors where the binding information was obtained
+	 * from a Java source file containing an explicit 0-argument constructor
+	 * declaration</li>
+	 * <li>0-argument constructors where the binding information was obtained
+	 * from a Java class file (it is not possible to determine from a
+	 * class file whether a 0-argument constructor was present in the source
+	 * code versus generated automatically by a Java compiler)</li>
+	 * </ul>
+	 *
+	 * @return <code>true</code> if this is known to be the binding for a
+	 * compiler-generated default constructor, and <code>false</code>
+	 * otherwise
+	 * @since 3.0
+	 */
+	public boolean isDefaultConstructor();
+
+	/**
+	 * Returns the name of the method declared in this binding. The method name
+	 * is always a simple identifier. The name of a constructor is always the
+	 * same as the declared name of its declaring class.
+	 *
+	 * @return the name of this method, or the declared name of this
+	 *   constructor's declaring class
+	 */
+	public String getName();
+
+	/**
+	 * Returns the type binding representing the class or interface
+	 * that declares this method or constructor.
+	 *
+	 * @return the binding of the class or interface that declares this method
+	 *    or constructor
+	 */
+	public ITypeBinding getDeclaringClass();
+
+	/**
+	 * Returns the resolved default value of an annotation type member,
+	 * or <code>null</code> if the member has no default value, or if this
+	 * is not the binding for an annotation type member.
+	 * <p>
+	 * Resolved values are represented as follows (same as for
+	 * {@link IMemberValuePairBinding#getValue()}):
+	 * <ul>
+	 * <li>Primitive type - the equivalent boxed object</li>
+	 * <li>java.lang.Class - the <code>ITypeBinding</code> for the class object</li>
+	 * <li>java.lang.String - the string value itself</li>
+	 * <li>enum type - the <code>IVariableBinding</code> for the enum constant</li>
+	 * <li>annotation type - an <code>IAnnotationBinding</code></li>
+	 * <li>array type - an <code>Object[]</code> whose elements are as per above
+	 * (the language only allows single dimensional arrays in annotations)</li>
+	 * </ul>
+	 *
+	 * @return the default value of this annotation type member, or <code>null</code>
+	 * if none or not applicable
+	 * @since 3.2
+	 */
+	public Object getDefaultValue();
+
+	/**
+	 * Returns the resolved annotations of a parameter of this method.
+	 * The result returned is the same regardless of whether
+	 * this is a parameterized method.
+	 *
+	 * @param paramIndex the index of the parameter of interest
+	 * @return the resolved annotations of the <code>paramIndex</code>th parameter,
+	 * or an empty list if there are none
+	 * @throws ArrayIndexOutOfBoundsException if <code>paramIndex</code> is
+	 * not a valid index
+	 * @since 3.2
+	 */
+	public IAnnotationBinding[] getParameterAnnotations(int paramIndex);
+
+	/**
+	 * Returns a list of type bindings representing the formal parameter types,
+	 * in declaration order, of this method or constructor. Returns an array of
+	 * length 0 if this method or constructor does not takes any parameters.
+	 * <p>
+	 * Note that the binding for the last parameter type of a vararg method
+	 * declaration like <code>void fun(Foo... args)</code> is always for
+	 * an array type (i.e., <code>Foo[]</code>) reflecting the the way varargs
+	 * get compiled. However, the type binding obtained directly from
+	 * the <code>SingleVariableDeclaration</code> for the vararg parameter
+	 * is always for the type as written; i.e., the type binding for
+	 * <code>Foo</code>.
+	 * </p>
+	 * <p>
+	 * Note: The result does not include synthetic parameters introduced by
+	 * inner class emulation.
+	 * </p>
+	 *
+	 * @return a (possibly empty) list of type bindings for the formal
+	 *   parameters of this method or constructor
+	 */
+	public ITypeBinding[] getParameterTypes();
+
+	/**
+	 * Returns the binding for the return type of this method. Returns the
+	 * special primitive <code>void</code> return type for constructors.
+	 *
+	 * @return the binding for the return type of this method, or the
+	 *    <code>void</code> return type for constructors
+	 */
+	public ITypeBinding getReturnType();
+
+	/**
+	 * Returns a list of type bindings representing the types of the exceptions thrown
+	 * by this method or constructor. Returns an array of length 0 if this method
+	 * throws no exceptions. The resulting types are in no particular order.
+	 *
+	 * @return a list of type bindings for exceptions
+	 *   thrown by this method or constructor
+	 */
+	public ITypeBinding[] getExceptionTypes();
+
+	/**
+	 * Returns the type parameters of this method or constructor binding.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic method. Type bindings corresponding to a raw or
+	 * parameterized reference to a generic method do not carry type
+	 * parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * </p>
+	 *
+	 * @return the list of binding for the type variables for the type
+	 * parameters of this method, or otherwise the empty list
+	 * @see ITypeBinding#isTypeVariable()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeParameters();
+
+	/**
+	 * Returns whether this is the binding for an annotation type member.
+	 *
+	 * @return <code>true</code> iff this is the binding for an annotation type member
+	 *         and <code>false</code> otherwise
+	 * @since 3.2
+	 */
+	public boolean isAnnotationMember();
+
+	/**
+	 * Returns whether this method binding represents a declaration of
+	 * a generic method.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic method; e.g., <code>public &lt;T&gt; T identity(T t);</code>.
+	 * Method bindings corresponding to a raw or parameterized reference to a generic
+	 * method do not carry type parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * This method is fully equivalent to <code>getTypeParameters().length &gt; 0)</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericMethod()},
+	 * {@link #isParameterizedMethod()},
+	 * and {@link #isRawMethod()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this method binding represents a
+	 * declaration of a generic method, and <code>false</code> otherwise
+	 * @see #getTypeParameters()
+	 * @since 3.1
+	 */
+	public boolean isGenericMethod();
+
+	/**
+	 * Returns whether this method binding represents an instance of
+	 * a generic method corresponding to a parameterized method reference.
+	 * <p>
+	 * Note that {@link #isGenericMethod()},
+	 * {@link #isParameterizedMethod()},
+	 * and {@link #isRawMethod()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this method binding represents a
+	 * an instance of a generic method corresponding to a parameterized
+	 * method reference, and <code>false</code> otherwise
+	 * @see #getMethodDeclaration()
+	 * @see #getTypeArguments()
+	 * @since 3.1
+	 */
+	public boolean isParameterizedMethod();
+
+	/**
+	 * Returns the type arguments of this generic method instance, or the
+	 * empty list for other method bindings.
+	 * <p>
+	 * Note that type arguments only occur on a method binding that represents
+	 * an instance of a generic method corresponding to a raw or parameterized
+	 * reference to a generic method. Do not confuse these with type parameters
+	 * which only occur on the method binding corresponding directly to the
+	 * declaration of a generic method.
+	 * </p>
+	 *
+	 * @return the list of type bindings for the type arguments used to
+	 * instantiate the corrresponding generic method, or otherwise the empty list
+	 * @see #getMethodDeclaration()
+	 * @see #isParameterizedMethod()
+	 * @see #isRawMethod()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeArguments();
+
+	/**
+	 * Returns the binding for the method declaration corresponding to this
+	 * method binding.
+	 * <ul>
+	 * <li>For parameterized methods ({@link #isParameterizedMethod()})
+	 * and raw methods ({@link #isRawMethod()}), this method returns the binding
+	 * for the corresponding generic method.</li>
+	 * <li>For references to the method {@link Object#getClass() Object.getClass()},
+	 * returns the binding for the method declaration which is declared to return
+	 * <code>Class&lt;?&gt;</code> or <code>Class&lt;? extends Object&gt;</code>. In the
+	 * reference binding, the return type becomes
+	 * <code>Class&lt;? extends </code><em>R</em><code>&gt;</code>, where <em>R</em>
+	 * is the erasure of the static type of the receiver of the method invocation.</li>
+	 * <li>For references to a signature polymorphic method from class MethodHandle,
+	 * returns the declaration of the method. In the reference binding, the parameter types and
+	 * the return type are determined by the concrete invocation context.</li>
+	 * <li>For other method bindings, this returns the same binding.</li>
+	 * </ul>
+	 *
+	 * @return the method binding
+	 * @since 3.1
+	 */
+	public IMethodBinding getMethodDeclaration();
+
+	/**
+	 * Returns whether this method binding represents an instance of
+	 * a generic method corresponding to a raw method reference.
+	 * <p>
+	 * Note that {@link #isGenericMethod()},
+	 * {@link #isParameterizedMethod()},
+	 * and {@link #isRawMethod()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this method binding represents a
+	 * an instance of a generic method corresponding to a raw
+	 * method reference, and <code>false</code> otherwise
+	 * @see #getMethodDeclaration()
+	 * @see #getTypeArguments()
+	 * @since 3.1
+	 */
+	public boolean isRawMethod();
+
+	/**
+	 * Returns whether this method's signature is a subsignature of the given method as
+	 * specified in section 8.4.2 of <em>The Java Language Specification, Third Edition</em> (JLS3).
+	 *
+	 * @return <code>true</code> if this method's signature is a subsignature of the given method
+	 * @since 3.1
+	 */
+	public boolean isSubsignature(IMethodBinding otherMethod);
+
+	/**
+	 * Returns whether this is a variable arity method.
+	 * <p>
+	 * Note: Variable arity ("varargs") methods were added in JLS3.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is a variable arity method,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isVarargs();
+
+	/**
+	 * Returns whether this method overrides the given method,
+	 * as specified in section 8.4.8.1 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 *
+	 * @param method the method that is possibly overriden
+	 * @return <code>true</code> if this method overrides the given method,
+	 * and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean overrides(IMethodBinding method);
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java
new file mode 100644
index 0000000..cd6ac47
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A package binding represents a named or unnamed package.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IPackageBinding extends IBinding {
+
+	/**
+	 * Returns the name of the package represented by this binding. For named
+	 * packages, this is the fully qualified package name (using "." for
+	 * separators). For unnamed packages, this is an empty string.
+	 *
+	 * @return the name of the package represented by this binding, or
+	 *    an empty string for an unnamed package
+	 */
+	public String getName();
+
+	/**
+	 * Returns whether this package is an unnamed package.
+	 * See <em>The Java Language Specification</em> section 7.4.2 for details.
+	 *
+	 * @return <code>true</code> if this is an unnamed package, and
+	 *    <code>false</code> otherwise
+	 */
+	public boolean isUnnamed();
+
+	/**
+	 * Returns the list of name component making up the name of the package
+	 * represented by this binding. For example, for the package named
+	 * "com.example.tool", this method returns {"com", "example", "tool"}.
+	 * Returns the empty list for unnamed packages.
+	 *
+	 * @return the name of the package represented by this binding, or the
+	 *    empty list for unnamed packages
+	 */
+	public String[] getNameComponents();
+
+//	/**
+//	 * Finds and returns the binding for the class or interface with the given
+//	 * name declared in this package.
+//	 * <p>
+//	 * For top-level classes and interfaces, the name here is just the simple
+//	 * name of the class or interface. For nested classes and interfaces, the
+//	 * name is the VM class name (in other words, a name like
+//	 * <code>"Outer$Inner"</code> as used to name the class file; see
+//	 * <code>ITypeBinding.getName</code>).
+//	 * </p>
+//	 *
+//	 * @param name the name of a class or interface
+//	 * @return the type binding for the class or interface with the
+//	 *   given name declared in this package, or <code>null</code>
+//	 *   if there is no such type
+//	 */
+//	public ITypeBinding findTypeBinding(String name);
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
new file mode 100644
index 0000000..1505277
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -0,0 +1,955 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A type binding represents fully-resolved type. There are a number of
+ * different kinds of type bindings:
+ * <ul>
+ * <li>a class - represents the class declaration;
+ * possibly with type parameters</li>
+ * <li>an interface - represents the class declaration;
+ * possibly with type parameters</li>
+ * <li>an enum - represents the enum declaration (enum types do not have
+ * have type parameters)</li>
+ * <li>an annotation - represents the annotation type declaration
+ * (annotation types do not have have type parameters)</li>
+ * <li>an array type - array types are referenced but not explicitly
+ * declared</li>
+ * <li>a primitive type (including the special return type <code>void</code>)
+ * - primitive types are referenced but not explicitly declared</li>
+ * <li>the null type - this is the special type of <code>null</code></li>
+ * <li>a type variable - represents the declaration of a type variable;
+ * possibly with type bounds</li>
+ * <li>a wildcard type - represents a wild card used as a type argument in
+ * a parameterized type reference</li>
+ * <li>a raw type - represents a legacy non-parameterized reference to
+ * a generic type</li>
+ * <li>a parameterized type - represents an copy of a type declaration
+ * with substitutions for its type parameters</li>
+ * <li>a capture - represents a capture binding</li>
+ * </ul>
+ *
+ * @see ITypeBinding#getDeclaredTypes()
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITypeBinding extends IBinding {
+
+
+	/**
+	 * Answer an array type binding using the receiver and the given dimension.
+	 *
+	 * <p>If the receiver is an array binding, then the resulting dimension is the given dimension
+	 * plus the dimension of the receiver. Otherwise the resulting dimension is the given
+	 * dimension.</p>
+	 *
+	 * @param dimension the given dimension
+	 * @return an array type binding
+	 * @throws IllegalArgumentException:<ul>
+	 * <li>if the receiver represents the void type</li>
+	 * <li>if the resulting dimensions is lower than one or greater than 255</li>
+	 * </ul>
+	 * @since 3.3
+	 */
+	public ITypeBinding createArrayType(int dimension);
+
+	/**
+	 * Returns the binary name of this type binding.
+	 * The binary name of a class is defined in the Java Language
+	 * Specification 3rd edition, section 13.1.
+	 * <p>
+	 * Note that in some cases, the binary name may be unavailable.
+	 * This may happen, for example, for a local type declared in
+	 * unreachable code.
+	 * </p>
+	 *
+	 * @return the binary name of this type, or <code>null</code>
+	 * if the binary name is unknown
+	 * @since 3.0
+	 */
+	public String getBinaryName();
+
+	/**
+	 * Returns the bound of this wildcard type if it has one.
+	 * Returns <code>null</code> if this is not a wildcard type.
+	 *
+	 * @return the bound of this wildcard type, or <code>null</code> if none
+	 * @see #isWildcardType()
+	 * @see #isUpperbound()
+	 * @since 3.1
+	 */
+	public ITypeBinding getBound();
+	
+	/**
+	 * Returns the generic type associated with this wildcard type, if it has one.
+	 * Returns <code>null</code> if this is not a wildcard type.
+	 *
+	 * @return the generic type associated with this wildcard type, or <code>null</code> if none
+	 * @see #isWildcardType()
+	 * @since 3.5
+	 */
+	public ITypeBinding getGenericTypeOfWildcardType();
+
+	/**
+	 * Returns the rank associated with this wildcard type. The rank of this wild card type is the relative
+	 * position of the wild card type in the parameterization of the associated generic type.
+	 * Returns <code>-1</code> if this is not a wildcard type.
+	 *
+	 * @return the rank associated with this wildcard type, or <code>-1</code> if none
+	 * @see #isWildcardType()
+	 * @since 3.5
+	 */
+	public int getRank();
+	
+	/**
+	 * Returns the binding representing the component type of this array type,
+	 * or <code>null</code> if this is not an array type binding. The component
+	 * type of an array might be an array type.
+	 * <p>This is subject to change before 3.2 release.</p>
+	 *
+	 * @return the component type binding, or <code>null</code> if this is
+	 *   not an array type
+	 * @since 3.2
+	 */
+	public ITypeBinding getComponentType();
+
+	/**
+	 * Returns a list of bindings representing all the fields declared
+	 * as members of this class, interface, or enum type.
+	 *
+	 * <p>These include public, protected, default (package-private) access,
+	 * and private fields declared by the class, but excludes inherited fields.
+	 * Synthetic fields may or may not be included. Fields from binary types that
+	 * reference unresolved types may not be included.</p>
+	 *
+	 * <p>Returns an empty list if the class, interface, or enum declares no fields,
+	 * and for other kinds of type bindings that do not directly have members.</p>
+	 *
+	 * <p>The resulting bindings are in no particular order.</p>
+	 *
+	 * @return the list of bindings for the field members of this type,
+	 *   or the empty list if this type does not have field members
+	 */
+	public IVariableBinding[] getDeclaredFields();
+
+	/**
+	 * Returns a list of method bindings representing all the methods and
+	 * constructors declared for this class, interface, enum, or annotation
+	 * type.
+	 * <p>These include public, protected, default (package-private) access,
+	 * and private methods Synthetic methods and constructors may or may not be
+	 * included. Returns an empty list if the class, interface, or enum,
+	 * type declares no methods or constructors, if the annotation type declares
+	 * no members, or if this type binding represents some other kind of type
+	 * binding. Methods from binary types that reference unresolved types may
+	 * not be included.</p>
+	 * <p>The resulting bindings are in no particular order.</p>
+	 *
+	 * @return the list of method bindings for the methods and constructors
+	 *   declared by this class, interface, enum type, or annotation type,
+	 *   or the empty list if this type does not declare any methods or constructors
+	 */
+	public IMethodBinding[] getDeclaredMethods();
+
+	/**
+	 * Returns the declared modifiers for this class or interface binding
+	 * as specified in the original source declaration of the class or
+	 * interface. The result may not correspond to the modifiers in the compiled
+	 * binary, since the compiler may change them (in particular, for inner
+	 * class emulation). The <code>getModifiers</code> method should be used if
+	 * the compiled modifiers are needed. Returns -1 if this type does not
+	 * represent a class or interface.
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see #getModifiers()
+	 * @see Modifier
+	 */
+	public int getDeclaredModifiers();
+
+	/**
+	 * Returns a list of type bindings representing all the types declared as
+	 * members of this class, interface, or enum type.
+	 * These include public, protected, default (package-private) access,
+	 * and private classes, interfaces, enum types, and annotation types
+	 * declared by the type, but excludes inherited types. Returns an empty
+	 * list if the type declares no type members, or if this type
+	 * binding represents an array type, a primitive type, a type variable,
+	 * a wildcard type, a capture, or the null type.
+	 * The resulting bindings are in no particular order.
+	 *
+	 * @return the list of type bindings for the member types of this type,
+	 *   or the empty list if this type does not have member types
+	 */
+	public ITypeBinding[] getDeclaredTypes();
+
+	/**
+	 * Returns the type binding representing the class, interface, or enum
+	 * that declares this binding.
+	 * <p>
+	 * The declaring class of a member class, interface, enum, annotation
+	 * type is the class, interface, or enum type of which it is a member.
+	 * The declaring class of a local class or interface (including anonymous
+	 * classes) is the innermost class or interface containing the expression
+	 * or statement in which this type is declared.
+	 * </p>
+	 * <p>The declaring class of a type variable is the class in which the type
+	 * variable is declared if it is declared on a type. It returns
+	 * <code>null</code> otherwise.
+	 * </p>
+	 * <p>The declaring class of a capture binding is the innermost class or
+	 * interface containing the expression or statement in which this capture is
+	 * declared.
+	 * </p>
+	 * <p>Array types, primitive types, the null type, top-level types,
+	 * wildcard types, recovered binding have no declaring class.
+	 * </p>
+	 *
+	 * @return the binding of the type that declares this type, or
+	 * <code>null</code> if none
+	 */
+	public ITypeBinding getDeclaringClass();
+
+	/**
+	 * Returns the method binding representing the method that declares this binding
+	 * of a local type or type variable.
+	 * <p>
+	 * The declaring method of a local class or interface (including anonymous
+	 * classes) is the innermost method containing the expression or statement in
+	 * which this type is declared. Returns <code>null</code> if the type
+	 * is declared in an initializer.
+	 * </p>
+	 * <p>
+	 * The declaring method of a type variable is the method in which the type
+	 * variable is declared if it is declared on a method. It
+	 * returns <code>null</code> otherwise.
+	 * </p>
+	 * <p>Array types, primitive types, the null type, top-level types,
+	 * wildcard types, capture bindings, and recovered binding have no
+	 * declaring method.
+	 * </p>
+	 *
+	 * @return the binding of the method that declares this type, or
+	 * <code>null</code> if none
+	 * @since 3.1
+	 */
+	public IMethodBinding getDeclaringMethod();
+
+	/**
+	 * Returns the dimensionality of this array type, or <code>0</code> if this
+	 * is not an array type binding.
+	 *
+	 * @return the number of dimension of this array type binding, or
+	 *   <code>0</code> if this is not an array type
+	 */
+	public int getDimensions();
+
+	/**
+	 * Returns the binding representing the element type of this array type,
+	 * or <code>null</code> if this is not an array type binding. The element
+	 * type of an array is never itself an array type.
+	 *
+	 * @return the element type binding, or <code>null</code> if this is
+	 *   not an array type
+	 */
+	public ITypeBinding getElementType();
+
+	/**
+	 * Returns the erasure of this type binding.
+	 * <ul>
+	 * <li>For parameterized types ({@link #isParameterizedType()})
+	 * - returns the binding for the corresponding generic type.</li>
+	 * <li>For raw types ({@link #isRawType()})
+	 * - returns the binding for the corresponding generic type.</li>
+	 * <li>For wildcard types ({@link #isWildcardType()})
+	 * - returns the binding for the upper bound if it has one and
+	 * java.lang.Object in other cases.</li>
+	 * <li>For type variables ({@link #isTypeVariable()})
+	 * - returns the binding for the erasure of the leftmost bound
+	 * if it has bounds and java.lang.Object if it does not.</li>
+	 * <li>For captures ({@link #isCapture()})
+	 * - returns the binding for the erasure of the leftmost bound
+	 * if it has bounds and java.lang.Object if it does not.</li>
+	 * <li>For array types ({@link #isArray()}) - returns an array type of
+	 * the same dimension ({@link #getDimensions()}) as this type
+	 * binding for which the element type is the erasure of the element type
+	 * ({@link #getElementType()}) of this type binding.</li>
+	 * <li>For all other type bindings - returns the identical binding.</li>
+	 * </ul>
+	 *
+	 * @return the erasure type binding
+	 * @since 3.1
+	 */
+	public ITypeBinding getErasure();
+
+	/**
+	 * Returns a list of type bindings representing the direct superinterfaces
+	 * of the class, interface, or enum type represented by this type binding.
+	 * <p>
+	 * If this type binding represents a class or enum type, the return value
+	 * is an array containing type bindings representing all interfaces
+	 * directly implemented by this class. The number and order of the interface
+	 * objects in the array corresponds to the number and order of the interface
+	 * names in the <code>implements</code> clause of the original declaration
+	 * of this type.
+	 * </p>
+	 * <p>
+	 * If this type binding represents an interface, the array contains
+	 * type bindings representing all interfaces directly extended by this
+	 * interface. The number and order of the interface objects in the array
+	 * corresponds to the number and order of the interface names in the
+	 * <code>extends</code> clause of the original declaration of this interface.
+	 * </p>
+	 * <p>
+	 * If the class or enum implements no interfaces, or the interface extends
+	 * no interfaces, or if this type binding represents an array type, a
+	 * primitive type, the null type, a type variable, an annotation type,
+	 * a wildcard type, or a capture binding, this method returns an array of
+     * length 0.
+	 * </p>
+	 *
+	 * @return the list of type bindings for the interfaces extended by this
+	 *   class or enum, or interfaces extended by this interface, or otherwise
+	 *   the empty list
+	 */
+	public ITypeBinding[] getInterfaces();
+
+	/**
+	 * Returns the compiled modifiers for this class, interface, enum,
+	 * or annotation type binding.
+	 * The result may not correspond to the modifiers as declared in the
+	 * original source, since the compiler may change them (in particular,
+	 * for inner class emulation). The <code>getDeclaredModifiers</code> method
+	 * should be used if the original modifiers are needed.
+	 * Returns 0 if this type does not represent a class, an interface, an enum, an annotation
+	 * type or a recovered type.
+	 *
+	 * @return the compiled modifiers for this type binding or 0
+	 * if this type does not represent a class, an interface, an enum, an annotation
+	 * type or a recovered type.
+	 * @see #getDeclaredModifiers()
+	 */
+	public int getModifiers();
+
+	/**
+	 * Returns the unqualified name of the type represented by this binding
+	 * if it has one.
+	 * <ul>
+	 * <li>For top-level types, member types, and local types,
+	 * the name is the simple name of the type.
+	 * Example: <code>"String"</code> or <code>"Collection"</code>.
+	 * Note that the type parameters of a generic type are not included.</li>
+	 * <li>For primitive types, the name is the keyword for the primitive type.
+	 * Example: <code>"int"</code>.</li>
+	 * <li>For the null type, the name is the string "null".</li>
+	 * <li>For anonymous classes, which do not have a name,
+	 * this method returns an empty string.</li>
+	 * <li>For array types, the name is the unqualified name of the component
+	 * type (as computed by this method) followed by "[]".
+	 * Example: <code>"String[]"</code>. Note that the component type is never an
+	 * an anonymous class.</li>
+	 * <li>For type variables, the name is just the simple name of the
+	 * type variable (type bounds are not included).
+	 * Example: <code>"X"</code>.</li>
+	 * <li>For type bindings that correspond to particular instances of a generic
+	 * type arising from a parameterized type reference,
+	 * the name is the unqualified name of the erasure type (as computed by this method)
+	 * followed by the names (again, as computed by this method) of the type arguments
+	 * surrounded by "&lt;&gt;" and separated by ",".
+	 * Example: <code>"Collection&lt;String&gt;"</code>.
+	 * </li>
+	 * <li>For type bindings that correspond to particular instances of a generic
+	 * type arising from a raw type reference, the name is the unqualified name of
+	 * the erasure type (as computed by this method).
+	 * Example: <code>"Collection"</code>.</li>
+	 * <li>For wildcard types, the name is "?" optionally followed by
+	 * a single space followed by the keyword "extends" or "super"
+	 * followed a single space followed by the name of the bound (as computed by
+	 * this method) when present.
+	 * Example: <code>"? extends InputStream"</code>.
+	 * </li>
+     * <li>Capture types do not have a name. For these types,
+     * and array types thereof, this method returns an empty string.</li>
+	 * </ul>
+	 *
+	 * @return the unqualified name of the type represented by this binding,
+	 * or the empty string if it has none
+	 * @see #getQualifiedName()
+	 */
+	public String getName();
+
+	/**
+	 * Returns the binding for the package in which this type is declared.
+	 *
+	 * <p>The package of a recovered type reference binding is either
+	 * the package of the enclosing type, or, if the type name is the name of a
+	 * {@linkplain AST#resolveWellKnownType(String) well-known type},
+	 * the package of the matching well-known type.</p>
+	 *
+	 * @return the binding for the package in which this class, interface,
+	 * enum, or annotation type is declared, or <code>null</code> if this type
+	 * binding represents a primitive type, an array type, the null type,
+	 * a type variable, a wildcard type, a capture binding.
+	 */
+	public IPackageBinding getPackage();
+
+	/**
+	 * Returns the fully qualified name of the type represented by this
+	 * binding if it has one.
+	 * <ul>
+	 * <li>For top-level types, the fully qualified name is the simple name of
+	 * the type preceded by the package name (or unqualified if in a default package)
+	 * and a ".".
+	 * Example: <code>"java.lang.String"</code> or <code>"java.util.Collection"</code>.
+	 * Note that the type parameters of a generic type are not included.</li>
+	 * <li>For members of top-level types, the fully qualified name is the
+	 * simple name of the type preceded by the fully qualified name of the
+	 * enclosing type (as computed by this method) and a ".".
+	 * Example: <code>"java.io.ObjectInputStream.GetField"</code>.
+	 * If the binding is for a member type that corresponds to a particular instance
+	 * of a generic type arising from a parameterized type reference, the simple
+	 * name of the type is followed by the fully qualified names of the type arguments
+	 * (as computed by this method) surrounded by "&lt;&gt;" and separated by ",".
+	 * Example: <code>"pkg.Outer.Inner&lt;java.lang.String&gt;"</code>.
+	 * </li>
+	 * <li>For primitive types, the fully qualified name is the keyword for
+	 * the primitive type.
+	 * Example: <code>"int"</code>.</li>
+	 * <li>For the null type, the fully qualified name is the string
+	 * "null".</li>
+	 * <li>Local types (including anonymous classes) and members of local
+	 * types do not have a fully qualified name. For these types, and array
+	 * types thereof, this method returns an empty string.</li>
+	 * <li>For array types whose component type has a fully qualified name,
+	 * the fully qualified name is the fully qualified name of the component
+	 * type (as computed by this method) followed by "[]".
+	 * Example: <code>"java.lang.String[]"</code>.</li>
+	 * <li>For type variables, the fully qualified name is just the name of the
+	 * type variable (type bounds are not included).
+	 * Example: <code>"X"</code>.</li>
+	 * <li>For type bindings that correspond to particular instances of a generic
+	 * type arising from a parameterized type reference,
+	 * the fully qualified name is the fully qualified name of the erasure
+	 * type followed by the fully qualified names of the type arguments surrounded by "&lt;&gt;" and separated by ",".
+	 * Example: <code>"java.util.Collection&lt;java.lang.String&gt;"</code>.
+	 * </li>
+	 * <li>For type bindings that correspond to particular instances of a generic
+	 * type arising from a raw type reference,
+	 * the fully qualified name is the fully qualified name of the erasure type.
+	 * Example: <code>"java.util.Collection"</code>. Note that the
+	 * the type parameters are omitted.</li>
+	 * <li>For wildcard types, the fully qualified name is "?" optionally followed by
+	 * a single space followed by the keyword "extends" or "super"
+	 * followed a single space followed by the fully qualified name of the bound
+	 * (as computed by this method) when present.
+	 * Example: <code>"? extends java.io.InputStream"</code>.
+	 * </li>
+    * <li>Capture types do not have a fully qualified name. For these types,
+    * and array types thereof, this method returns an empty string.</li>
+	 * </ul>
+	 *
+	 * @return the fully qualified name of the type represented by this
+	 *    binding, or the empty string if it has none
+	 * @see #getName()
+	 * @since 2.1
+	 */
+	public String getQualifiedName();
+
+	/**
+	 * Returns the type binding for the superclass of the type represented
+	 * by this class binding.
+	 * <p>
+	 * If this type binding represents any class other than the class
+	 * <code>java.lang.Object</code>, then the type binding for the direct
+	 * superclass of this class is returned. If this type binding represents
+	 * the class <code>java.lang.Object</code>, then <code>null</code> is
+	 * returned.
+	 * <p>
+	 * Loops that ascend the class hierarchy need a suitable termination test.
+	 * Rather than test the superclass for <code>null</code>, it is more
+	 * transparent to check whether the class is <code>Object</code>, by
+	 * comparing whether the class binding is identical to
+	 * <code>ast.resolveWellKnownType("java.lang.Object")</code>.
+	 * </p>
+	 * <p>
+	 * If this type binding represents an interface, an array type, a
+	 * primitive type, the null type, a type variable, an enum type,
+	 * an annotation type, a wildcard type, or a capture binding then
+	 * <code>null</code> is returned.
+	 * </p>
+	 *
+	 * @return the superclass of the class represented by this type binding,
+	 *    or <code>null</code> if none
+	 * @see AST#resolveWellKnownType(String)
+	 */
+	public ITypeBinding getSuperclass();
+
+	/**
+	 * Returns the type arguments of this generic type instance, or the
+	 * empty list for other type bindings.
+	 * <p>
+	 * Note that type arguments only occur on a type binding that represents
+	 * an instance of a generic type corresponding to a parameterized type
+	 * reference (e.g., <code>Collection&lt;String&gt;</code>).
+	 * Do not confuse these with type parameters which only occur on the
+	 * type binding corresponding directly to the declaration of the
+	 * generic class or interface (e.g., <code>Collection&lt;T&gt;</code>).
+	 * </p>
+	 *
+	 * @return the list of type bindings for the type arguments used to
+	 * instantiate the corresponding generic type, or otherwise the empty list
+	 * @see #getTypeDeclaration()
+	 * @see #isGenericType()
+	 * @see #isParameterizedType()
+	 * @see #isRawType()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeArguments();
+
+	/**
+	 * Returns the declared type bounds of this type variable or capture. If the
+	 * variable or the capture had no explicit bound, then it returns an empty list.
+     * <p>
+     * Note that per construction, it can only contain one class or array type,
+     * at most, and then it is located in first position.
+     * </p>
+     * <p>
+     * Also note that array type bound may only occur in the case of a capture
+     * binding, e.g. <code>capture-of ? extends Object[]</code>
+     * </p>
+	 *
+	 * @return the list of type bindings for this type variable or capture,
+     * or otherwise the empty list
+	 * @see #isCapture()
+	 * @see #isTypeVariable()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeBounds();
+
+	/**
+	 * Returns the binding for the type declaration corresponding to this type
+	 * binding.
+	 * <p>For parameterized types ({@link #isParameterizedType()})
+	 * and most raw types ({@link #isRawType()}), this method returns the binding
+	 * for the corresponding generic type.</p>
+	 * <p>For raw member types ({@link #isRawType()}, {@link #isMember()})
+	 * of a raw declaring class, the type declaration is a generic or a non-generic
+	 * type.</p>
+	 * <p>A different non-generic binding will be returned when one of the declaring
+	 * types/methods was parameterized.</p>
+	 * <p>For other type bindings, this returns the same binding.</p>
+	 *
+	 * @return the type binding
+	 * @since 3.1
+	 */
+	public ITypeBinding getTypeDeclaration();
+
+	/**
+	 * Returns the type parameters of this class or interface type binding.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
+	 * Type bindings corresponding to a raw or parameterized reference to a generic
+	 * type do not carry type parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * </p>
+	 *
+	 * @return the list of binding for the type variables for the type
+	 * parameters of this type, or otherwise the empty list
+	 * @see #isTypeVariable()
+	 * @since 3.1
+	 */
+	// TODO (jeem) - clarify whether binding for a generic type instance carries a copy of the generic type's type parameters as well as type arguments
+	public ITypeBinding[] getTypeParameters();
+
+	/**
+	 * Returns the corresponding wildcard binding of this capture binding.
+     * Returns <code>null</code> if this type bindings does not represent
+     * a capture binding.
+	 *
+	 * @return the corresponding wildcard binding for a capture
+	 * binding, <code>null</code> otherwise
+	 * @since 3.1
+	 */
+	public ITypeBinding getWildcard();
+
+	/**
+	 * Returns whether this type binding represents an annotation type.
+	 * <p>
+	 * Note that an annotation type is always an interface.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents an annotation type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isAnnotation();
+
+	/**
+	 * Returns whether this type binding represents an anonymous class.
+	 * <p>
+	 * An anonymous class is a subspecies of local class, and therefore mutually
+	 * exclusive with member types. Note that anonymous classes have no name
+	 * (<code>getName</code> returns the empty string).
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for an anonymous class,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isAnonymous();
+
+	/**
+	 * Returns whether this type binding represents an array type.
+	 *
+	 * @return <code>true</code> if this type binding is for an array type,
+	 *   and <code>false</code> otherwise
+	 * @see #getElementType()
+	 * @see #getDimensions()
+	 */
+	public boolean isArray();
+
+	/**
+	 * Returns whether an expression of this type can be assigned to a variable
+	 * of the given type, as specified in section 5.2 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 *
+	 * <p>If the receiver or the argument is a recovered type, the answer is always false,
+	 * unless the two types are identical or the argument is <code>java.lang.Object</code>.</p>
+	 *
+	 * @param variableType the type of a variable to check compatibility against
+	 * @return <code>true</code> if an expression of this type can be assigned to a
+	 *   variable of the given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isAssignmentCompatible(ITypeBinding variableType);
+
+	/**
+	 * Returns whether this type binding represents a capture binding.
+	 * <p>
+	 * Capture bindings result from capture conversion as specified
+	 * in section 5.1.10 of <em>The Java Language Specification,
+	 * Third Edition</em> (JLS3).
+	 * </p>
+	 * <p>
+	 * A capture binding may have upper bounds and a lower bound.
+	 * Upper bounds may be accessed using {@link #getTypeBounds()},
+	 * the lower bound must be accessed indirectly through the associated
+	 * wildcard {@link #getWildcard()} when it is a lower bound wildcard.
+	 * </p>
+	 * <p>
+	 * Note that capture bindings are distinct from type variables
+     * (even though they are often depicted as synthetic type
+     * variables); as such, {@link #isTypeVariable()} answers
+     * <code>false</code> for capture bindings, and
+     * {@link #isCapture()} answers <code>false</code> for type variables.
+	 * </p>
+     *
+	 * @return <code>true</code> if this type binding is a capture,
+	 *   and <code>false</code> otherwise
+	 * @see #getTypeBounds()
+	 * @see #getWildcard()
+	 * @since 3.1
+	 */
+	public boolean isCapture();
+
+	/**
+	 * Returns whether this type is cast compatible with the given type,
+	 * as specified in section 5.5 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 * <p>
+	 * NOTE: The cast compatibility check performs backwards.
+	 * When testing whether type B can be cast to type A, one would use:
+	 * <code>A.isCastCompatible(B)</code>
+	 * </p>
+	 *
+	 * <p>If the receiver or the argument is a recovered type, the answer is always false,
+	 * unless the two types are identical or the argument is <code>java.lang.Object</code>.</p>
+	 *
+	 * @param type the type to check compatibility against
+	 * @return <code>true</code> if this type is cast compatible with the
+	 * given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isCastCompatible(ITypeBinding type);
+
+	/**
+	 * Returns whether this type binding represents a class type or a recovered binding.
+	 *
+	 * @return <code>true</code> if this object represents a class or a recovered binding,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isClass();
+
+	/**
+	 * Returns whether this type binding represents an enum type.
+	 *
+	 * @return <code>true</code> if this object represents an enum type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isEnum();
+
+	/**
+	 * Returns whether this type binding originated in source code.
+	 * Returns <code>false</code> for all primitive types, the null type,
+	 * array types, and for all classes, interfaces, enums, annotation
+	 * types, type variables, parameterized type references,
+	 * raw type references, wildcard types, and capture bindings
+     * whose information came from a pre-compiled binary class file.
+	 *
+	 * @return <code>true</code> if the type is in source code,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isFromSource();
+
+	/**
+	 * Returns whether this type binding represents a declaration of
+	 * a generic class or interface.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
+	 * Type bindings corresponding to a raw or parameterized reference to a generic
+	 * type do not carry type parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * This method is fully equivalent to <code>getTypeParameters().length &gt; 0)</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a
+	 * declaration of a generic class or interface, and <code>false</code> otherwise
+	 * @see #getTypeParameters()
+	 * @since 3.1
+	 */
+	public boolean isGenericType();
+
+	/**
+	 * Returns whether this type binding represents an interface type.
+	 * <p>
+	 * Note that an interface can also be an annotation type.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents an interface,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isInterface();
+
+	/**
+	 * Returns whether this type binding represents a local class.
+	 * <p>
+	 * A local class is any nested class or enum type not declared as a member
+	 * of another class or interface. A local class is a subspecies of nested
+	 * type, and mutually exclusive with member types. For anonymous
+	 * classes, which are considered a subspecies of local classes, this method
+	 * returns true. 
+	 * </p>
+	 * <p>
+	 * Note: This deviates from JLS3 14.3, which states that anonymous types are 
+	 * not local types since they do not have a name. Also note that interfaces 
+	 * and annotation types cannot be local.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a local class or
+	 * enum type, and <code>false</code> otherwise
+	 */
+	public boolean isLocal();
+
+	/**
+	 * Returns whether this type binding represents a member class or
+	 * interface.
+	 * <p>
+	 * A member type is any type declared as a member of
+	 * another type. A member type is a subspecies of nested
+	 * type, and mutually exclusive with local types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a member class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isMember();
+
+	/**
+	 * Returns whether this type binding represents a nested class, interface,
+	 * enum, or annotation type.
+	 * <p>
+	 * A nested type is any type whose declaration occurs within
+	 * the body of another. The set of nested types is disjoint from the set of
+	 * top-level types. Nested types further subdivide into member types, local
+	 * types, and anonymous types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a nested class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isNested();
+
+	/**
+	 * Returns whether this type binding represents the null type.
+	 * <p>
+	 * The null type is the type of a <code>NullLiteral</code> node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for the null type,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isNullType();
+
+	/**
+	 * Returns whether this type binding represents an instance of
+	 * a generic type corresponding to a parameterized type reference.
+	 * <p>
+	 * For example, an AST type like
+	 * <code>Collection&lt;String&gt;</code> typically resolves to a
+	 * type binding whose type argument is the type binding for the
+	 * class <code>java.lang.String</code> and whose erasure is the type
+	 * binding for the generic type <code>java.util.Collection</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a
+	 * an instance of a generic type corresponding to a parameterized
+	 * type reference, and <code>false</code> otherwise
+	 * @see #getTypeArguments()
+	 * @see #getTypeDeclaration()
+	 * @since 3.1
+	 */
+	public boolean isParameterizedType();
+
+	/**
+	 * Returns whether this type binding represents a primitive type.
+	 * <p>
+	 * There are nine predefined type bindings to represent the eight primitive
+	 * types and <code>void</code>. These have the same names as the primitive
+	 * types that they represent, namely boolean, byte, char, short, int,
+	 * long, float, and double, and void.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a primitive type,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isPrimitive();
+
+	/**
+	 * Returns whether this type binding represents an instance of
+	 * a generic type corresponding to a raw type reference.
+	 * <p>
+	 * For example, an AST type like
+	 * <code>Collection</code> typically resolves to a
+	 * type binding whose type argument is the type binding for
+	 * the class <code>java.lang.Object</code> (the
+	 * default bound for the single type parameter of
+	 * <code>java.util.Collection</code>) and whose erasure is the
+	 * type binding for the generic type
+	 * <code>java.util.Collection</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a
+	 * an instance of a generic type corresponding to a raw
+	 * type reference, and <code>false</code> otherwise
+	 * @see #getTypeDeclaration()
+	 * @see #getTypeArguments()
+	 * @since 3.1
+	 */
+	public boolean isRawType();
+
+	/**
+	 * Returns whether this type is subtype compatible with the given type,
+	 * as specified in section 4.10 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 *
+	 * <p>If the receiver or the argument is a recovered type, the answer is always false,
+	 * unless the two types are identical or the argument is <code>java.lang.Object</code>.</p>
+	 *
+	 * @param type the type to check compatibility against
+	 * @return <code>true</code> if this type is subtype compatible with the
+	 * given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isSubTypeCompatible(ITypeBinding type);
+
+	/**
+	 * Returns whether this type binding represents a top-level class,
+	 * interface, enum, or annotation type.
+	 * <p>
+	 * A top-level type is any type whose declaration does not occur within the
+	 * body of another type declaration. The set of top level types is disjoint
+	 * from the set of nested types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a top-level class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isTopLevel();
+
+	/**
+	 * Returns whether this type binding represents a type variable.
+	 * Type variables bindings carry the type variable's bounds.
+     * <p>
+     * Note that type variables are distinct from capture bindings
+     * (even though capture bindings are often depicted as synthetic
+     * type variables); as such, {@link #isTypeVariable()} answers
+     * <code>false</code> for capture bindings, and
+     * {@link #isCapture()} answers <code>false</code> for type variables.
+     * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a type variable,
+	 *   and <code>false</code> otherwise
+	 * @see #getName()
+	 * @see #getTypeBounds()
+	 * @since 3.1
+	 */
+	public boolean isTypeVariable();
+
+	/**
+	 * Returns whether this wildcard type is an upper bound
+	 * ("extends") as opposed to a lower bound ("super").
+	 * Note that this property is only relevant for wildcards
+	 * that have a bound.
+	 *
+	 * @return <code>true</code> if this wildcard type has a bound that is
+	 * an upper bound, and <code>false</code> in all other cases
+	 * @see #isWildcardType()
+	 * @see #getBound()
+	 * @since 3.1
+	 */
+	public boolean isUpperbound();
+
+	/**
+	 * Returns whether this type binding represents a wildcard type. A wildcard
+	 * type occurs only as an argument to a parameterized type reference.
+	 * <p>
+	 * For example, a AST type like
+	 * <code>Collection&lt;? extends Object&gt;</code> typically resolves to a
+	 * parameterized type binding whose type argument is a wildcard type
+	 * with upper type bound <code>java.util.Object</code>.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents a wildcard type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 * @see #getBound()
+	 * @see #isUpperbound()
+	 */
+	public boolean isWildcardType();
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java
new file mode 100644
index 0000000..789b568
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A variable binding represents either a field of a class or interface, or
+ * a local variable declaration (including formal parameters, local variables,
+ * and exception variables).
+ *
+ * @see ITypeBinding#getDeclaredFields()
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IVariableBinding extends IBinding {
+
+	/**
+	 * Returns whether this binding is for a field.
+	 * Note that this method returns <code>true</code> for constants,
+	 * including enum constants. This method returns <code>false</code>
+	 * for local variables.
+	 *
+	 * @return <code>true</code> if this is the binding for a field,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isField();
+
+	/**
+	 * Returns whether this binding is for an enum constant.
+	 * Note that this method returns <code>false</code> for local variables
+	 * and for fields other than enum constants.
+	 *
+	 * @return <code>true</code> if this is the binding for an enum constant,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isEnumConstant();
+
+	/**
+	 * Returns whether this binding corresponds to a parameter.
+	 *
+	 * @return <code>true</code> if this is the binding for a parameter,
+	 *    and <code>false</code> otherwise
+	 * @since 3.2
+	 */
+	public boolean isParameter();
+
+	/**
+	 * Returns the name of the field or local variable declared in this binding.
+	 * The name is always a simple identifier.
+	 *
+	 * @return the name of this field or local variable
+	 */
+	public String getName();
+
+	/**
+	 * Returns the type binding representing the class or interface
+	 * that declares this field.
+	 * <p>
+	 * The declaring class of a field is the class or interface of which it is
+	 * a member. Local variables have no declaring class. The field length of an
+	 * array type has no declaring class.
+	 * </p>
+	 *
+	 * @return the binding of the class or interface that declares this field,
+	 *   or <code>null</code> if none
+	 */
+	public ITypeBinding getDeclaringClass();
+
+	/**
+	 * Returns the binding for the type of this field or local variable.
+	 *
+	 * @return the binding for the type of this field or local variable
+	 */
+	public ITypeBinding getType();
+
+	/**
+	 * Returns a small integer variable id for this variable binding.
+	 * <p>
+	 * <b>Local variables inside methods:</b> Local variables (and parameters)
+	 * declared within a single method are assigned ascending ids in normal
+	 * code reading order; var1.getVariableId()&lt;var2.getVariableId() means that var1 is
+	 * declared before var2.
+	 * </p>
+	 * <p>
+	 * <b>Local variables outside methods:</b> Local variables declared in a
+	 * type's static initializers (or initializer expressions of static fields)
+	 * are assigned ascending ids in normal code reading order. Local variables
+	 * declared in a type's instance initializers (or initializer expressions
+	 * of non-static fields) are assigned ascending ids in normal code reading
+	 * order. These ids are useful when checking definite assignment for
+	 * static initializers (JLS 16.7) and instance initializers (JLS 16.8),
+	 * respectively.
+	 * </p>
+	 * <p>
+	 * <b>Fields:</b> Fields declared as members of a type are assigned
+	 * ascending ids in normal code reading order;
+	 * field1.getVariableId()&lt;field2.getVariableId() means that field1 is declared before
+	 * field2.
+	 * </p>
+	 *
+	 * @return a small non-negative variable id
+	 */
+	public int getVariableId();
+
+	/**
+	 * Returns this binding's constant value if it has one.
+	 * Some variables may have a value computed at compile-time. If the type of
+	 * the value is a primitive type, the result is the boxed equivalent (i.e.,
+	 * int returned as an <code>Integer</code>). If the type of the value is
+	 * <code>String</code>, the result is the string itself. If the variable has
+	 * no compile-time computed value, the result is <code>null</code>.
+	 * (Note: compile-time constant expressions cannot denote <code>null</code>;
+	 * JLS2 15.28.). The result is always <code>null</code> for enum constants.
+	 *
+	 * @return the constant value, or <code>null</code> if none
+	 * @since 3.0
+	 */
+	public Object getConstantValue();
+
+	/**
+	 * Returns the method binding representing the method containing the scope
+	 * in which this local variable is declared.
+	 * <p>
+	 * The declaring method of a method formal parameter is the method itself.
+	 * For a local variable declared somewhere within the body of a method,
+	 * the declaring method is the enclosing method. When local or anonymous
+	 * classes are involved, the declaring method is the innermost such method.
+	 * There is no declaring method for a field, or for a local variable
+	 * declared in a static or instance initializer; this method returns
+	 * <code>null</code> in those cases.
+	 * </p>
+	 *
+	 * @return the binding of the method or constructor that declares this
+	 * local variable, or <code>null</code> if none
+	 * @since 3.1
+	 */
+	public IMethodBinding getDeclaringMethod();
+
+	/**
+	 * Returns the binding for the variable declaration corresponding to this
+	 * variable binding. For a binding for a field declaration in an instance
+	 * of a generic type, this method returns the binding for the corresponding
+	 * field declaration in the generic type. For other variable bindings,
+	 * including all ones for local variables and parameters, this method
+	 * returns the same binding.
+	 *
+	 * @return the variable binding for the originating declaration
+	 * @since 3.1
+	 */
+	public IVariableBinding getVariableDeclaration();
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java
new file mode 100644
index 0000000..44e426e
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * If statement AST node type.
+ * <pre>
+ * IfStatement:
+ *    <b>if</b> <b>(</b> Expression <b>)</b> Statement [ <b>else</b> Statement]
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class IfStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(IfStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "thenStatement" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor THEN_STATEMENT_PROPERTY =
+		new ChildPropertyDescriptor(IfStatement.class, "thenStatement", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "elseStatement" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor ELSE_STATEMENT_PROPERTY =
+		new ChildPropertyDescriptor(IfStatement.class, "elseStatement", Statement.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(IfStatement.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(THEN_STATEMENT_PROPERTY, properyList);
+		addProperty(ELSE_STATEMENT_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified, but
+	 * legal, expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The then statement; lazily initialized; defaults to an unspecified, but
+	 * legal, statement.
+	 */
+	private Statement thenStatement = null;
+
+	/**
+	 * The else statement; <code>null</code> for none; defaults to none.
+	 */
+	private Statement optionalElseStatement = null;
+
+	/**
+	 * Creates a new unparented if statement node owned by the given
+	 * AST. By default, the expresssion is unspecified,
+	 * but legal, the then statement is an empty block, and there is no else
+	 * statement.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	IfStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == THEN_STATEMENT_PROPERTY) {
+			if (get) {
+				return getThenStatement();
+			} else {
+				setThenStatement((Statement) child);
+				return null;
+			}
+		}
+		if (property == ELSE_STATEMENT_PROPERTY) {
+			if (get) {
+				return getElseStatement();
+			} else {
+				setElseStatement((Statement) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return IF_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		IfStatement result = new IfStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setThenStatement(
+			(Statement) getThenStatement().clone(target));
+		result.setElseStatement(
+			(Statement) ASTNode.copySubtree(target, getElseStatement()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getThenStatement());
+			acceptChild(visitor, getElseStatement());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this if statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the condition of this if statement.
+	 *
+	 * @param expression the expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the "then" part of this if statement.
+	 *
+	 * @return the "then" statement node
+	 */
+	public Statement getThenStatement() {
+		if (this.thenStatement == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.thenStatement == null) {
+					preLazyInit();
+					this.thenStatement = new Block(this.ast);
+					postLazyInit(this.thenStatement, THEN_STATEMENT_PROPERTY);
+				}
+			}
+		}
+		return this.thenStatement;
+	}
+
+	/**
+	 * Sets the "then" part of this if statement.
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the "then" part of an if statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the thenStatement of a <code>IfStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the "then" statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setThenStatement(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.thenStatement;
+		preReplaceChild(oldChild, statement, THEN_STATEMENT_PROPERTY);
+		this.thenStatement = statement;
+		postReplaceChild(oldChild, statement, THEN_STATEMENT_PROPERTY);
+	}
+
+	/**
+	 * Returns the "else" part of this if statement, or <code>null</code> if
+	 * this if statement has <b>no</b> "else" part.
+	 * <p>
+	 * Note that there is a subtle difference between having no else
+	 * statement and having an empty statement ("{}") or null statement (";").
+	 * </p>
+	 *
+	 * @return the "else" statement node, or <code>null</code> if none
+	 */
+	public Statement getElseStatement() {
+		return this.optionalElseStatement;
+	}
+
+	/**
+	 * Sets or clears the "else" part of this if statement.
+	 * <p>
+	 * Note that there is a subtle difference between having no else part
+	 * (as in <code>"if(true){}"</code>) and having an empty block (as in
+	 * "if(true){}else{}") or null statement (as in "if(true){}else;").
+	 * </p>
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the "else" part of an if statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the elseStatement of a <code>IfStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the "else" statement node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setElseStatement(Statement statement) {
+		ASTNode oldChild = this.optionalElseStatement;
+		preReplaceChild(oldChild, statement, ELSE_STATEMENT_PROPERTY);
+		this.optionalElseStatement = statement;
+		postReplaceChild(oldChild, statement, ELSE_STATEMENT_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.thenStatement == null ? 0 : getThenStatement().treeSize())
+			+ (this.optionalElseStatement == null ? 0 : getElseStatement().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java
new file mode 100644
index 0000000..0ea488a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Import declaration AST node type.
+ *
+ * <pre>
+ * ImportDeclaration:
+ *    <b>import</b> [ <b>static</b> ] Name [ <b>.</b> <b>*</b> ] <b>;</b>
+ * </pre>
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ImportDeclaration extends ASTNode {
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(ImportDeclaration.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "onDemand" structural property of this node type (type: {@link Boolean}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor ON_DEMAND_PROPERTY =
+		new SimplePropertyDescriptor(ImportDeclaration.class, "onDemand", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "static" structural property of this node type (type: {@link Boolean}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final SimplePropertyDescriptor STATIC_PROPERTY =
+		new SimplePropertyDescriptor(ImportDeclaration.class, "static", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(ImportDeclaration.class, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ON_DEMAND_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(4);
+		createPropertyList(ImportDeclaration.class, properyList);
+		addProperty(STATIC_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ON_DEMAND_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The import name; lazily initialized; defaults to a unspecified,
+	 * legal Java identifier.
+	 */
+	private Name importName = null;
+
+	/**
+	 * On demand versus single type import; defaults to single type import.
+	 */
+	private boolean onDemand = false;
+
+	/**
+	 * Static versus regular; defaults to regular import.
+	 * Added in JLS3; not used in JLS2.
+	 * @since 3.1
+	 */
+	private boolean isStatic = false;
+
+	/**
+	 * Creates a new AST node for an import declaration owned by the
+	 * given AST. The import declaration initially is a regular (non-static)
+	 * single type import for an unspecified, but legal, Java type name.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ImportDeclaration(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == ON_DEMAND_PROPERTY) {
+			if (get) {
+				return isOnDemand();
+			} else {
+				setOnDemand(value);
+				return false;
+			}
+		}
+		if (property == STATIC_PROPERTY) {
+			if (get) {
+				return isStatic();
+			} else {
+				setStatic(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return IMPORT_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ImportDeclaration result = new ImportDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setOnDemand(isOnDemand());
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.setStatic(isStatic());
+		}
+		result.setName((Name) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the name imported by this declaration.
+	 * <p>
+	 * For a regular on-demand import, this is the name of a package.
+	 * For a static on-demand import, this is the qualified name of
+	 * a type. For a regular single-type import, this is the qualified name
+	 * of a type. For a static single-type import, this is the qualified name
+	 * of a static member of a type.
+	 * </p>
+	 *
+	 * @return the imported name node
+	 */
+	public Name getName()  {
+		if (this.importName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.importName == null) {
+					preLazyInit();
+					this.importName =this.ast.newQualifiedName(
+							new SimpleName(this.ast), new SimpleName(this.ast));
+					postLazyInit(this.importName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.importName;
+	}
+
+	/**
+	 * Sets the name of this import declaration to the given name.
+	 * <p>
+	 * For a regular on-demand import, this is the name of a package.
+	 * For a static on-demand import, this is the qualified name of
+	 * a type. For a regular single-type import, this is the qualified name
+	 * of a type. For a static single-type import, this is the qualified name
+	 * of a static member of a type.
+	 * </p>
+	 *
+	 * @param name the new import name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(Name name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.importName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.importName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this import declaration is an on-demand or a
+	 * single-type import.
+	 *
+	 * @return <code>true</code> if this is an on-demand import,
+	 *    and <code>false</code> if this is a single type import
+	 */
+	public boolean isOnDemand() {
+		return this.onDemand;
+	}
+
+	/**
+	 * Sets whether this import declaration is an on-demand or a
+	 * single-type import.
+	 *
+	 * @param onDemand <code>true</code> if this is an on-demand import,
+	 *    and <code>false</code> if this is a single type import
+	 */
+	public void setOnDemand(boolean onDemand) {
+		preValueChange(ON_DEMAND_PROPERTY);
+		this.onDemand = onDemand;
+		postValueChange(ON_DEMAND_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this import declaration is a static import (added in JLS3 API).
+	 *
+	 * @return <code>true</code> if this is a static import,
+	 *    and <code>false</code> if this is a regular import
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public boolean isStatic() {
+		unsupportedIn2();
+		return this.isStatic;
+	}
+
+	/**
+	 * Sets whether this import declaration is a static import (added in JLS3 API).
+	 *
+	 * @param isStatic <code>true</code> if this is a static import,
+	 *    and <code>false</code> if this is a regular import
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public void setStatic(boolean isStatic) {
+		unsupportedIn2();
+		preValueChange(STATIC_PROPERTY);
+		this.isStatic = isStatic;
+		postValueChange(STATIC_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the package, type, field, or
+	 * method named in this import declaration.
+	 * <p>
+	 * The name specified in a non-static single-type import can resolve
+	 * to a type (only). The name specified in a non-static on-demand
+	 * import can itself resolve to either a package or a type.
+	 * For static imports (introduced in JLS3), the name specified in a
+	 * static on-demand import can itself resolve to a type (only).
+	 * The name specified in a static single import can resolve to a
+	 * type, field, or method; in cases where the name could be resolved
+	 * to more than one element with that name (for example, two
+	 * methods both named "max", or a method and a field), this method
+	 * returns one of the plausible bindings.
+	 * </p>
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return a package, type, field, or method binding, or <code>null</code>
+	 * if the binding cannot be resolved
+	 */
+	public IBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveImport(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.importName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java
new file mode 100644
index 0000000..f647e10
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java
@@ -0,0 +1,538 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Infix expression AST node type.
+ * <pre>
+ * InfixExpression:
+ *    Expression InfixOperator Expression { InfixOperator Expression }
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class InfixExpression extends Expression {
+
+	/**
+ 	 * Infix operators (typesafe enumeration).
+ 	 * <pre>
+	 * InfixOperator:<code>
+	 *    <b>*</b>	TIMES
+	 *    <b>/</b>  DIVIDE
+	 *    <b>%</b>  REMAINDER
+	 *    <b>+</b>  PLUS
+	 *    <b>-</b>  MINUS
+	 *    <b>&lt;&lt;</b>  LEFT_SHIFT
+	 *    <b>&gt;&gt;</b>  RIGHT_SHIFT_SIGNED
+	 *    <b>&gt;&gt;&gt;</b>  RIGHT_SHIFT_UNSIGNED
+	 *    <b>&lt;</b>  LESS
+	 *    <b>&gt;</b>  GREATER
+	 *    <b>&lt;=</b>  LESS_EQUALS
+	 *    <b>&gt;=</b>  GREATER_EQUALS
+	 *    <b>==</b>  EQUALS
+	 *    <b>!=</b>  NOT_EQUALS
+	 *    <b>^</b>  XOR
+	 *    <b>&amp;</b>  AND
+	 *    <b>|</b>  OR
+	 *    <b>&amp;&amp;</b>  CONDITIONAL_AND
+	 *    <b>||</b>  CONDITIONAL_OR</code>
+	 * </pre>
+	 */
+	public static class Operator {
+
+		/**
+		 * The token for the operator.
+		 */
+		private String token;
+
+		/**
+		 * Creates a new infix operator with the given token.
+		 * <p>
+		 * Note: this constructor is private. The only instances
+		 * ever created are the ones for the standard operators.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 */
+		private Operator(String token) {
+			this.token = token;
+		}
+
+		/**
+		 * Returns the character sequence for the operator.
+		 *
+		 * @return the character sequence for the operator
+		 */
+		public String toString() {
+			return this.token;
+		}
+
+		/** Multiplication "*" operator. */
+		public static final Operator TIMES = new Operator("*");//$NON-NLS-1$
+		/** Division "/" operator. */
+		public static final Operator DIVIDE = new Operator("/");//$NON-NLS-1$
+		/** Remainder "%" operator. */
+		public static final Operator REMAINDER = new Operator("%");//$NON-NLS-1$
+		/** Addition (or string concatenation) "+" operator. */
+		public static final Operator PLUS = new Operator("+");//$NON-NLS-1$
+		/** Subtraction "-" operator. */
+		public static final Operator MINUS = new Operator("-");//$NON-NLS-1$
+		/** Left shift "&lt;&lt;" operator. */
+		public static final Operator LEFT_SHIFT = new Operator("<<");//$NON-NLS-1$
+		/** Signed right shift "&gt;&gt;" operator. */
+		public static final Operator RIGHT_SHIFT_SIGNED = new Operator(">>");//$NON-NLS-1$
+		/** Unsigned right shift "&gt;&gt;&gt;" operator. */
+		public static final Operator RIGHT_SHIFT_UNSIGNED =
+			new Operator(">>>");//$NON-NLS-1$
+		/** Less than "&lt;" operator. */
+		public static final Operator LESS = new Operator("<");//$NON-NLS-1$
+		/** Greater than "&gt;" operator. */
+		public static final Operator GREATER = new Operator(">");//$NON-NLS-1$
+		/** Less than or equals "&lt;=" operator. */
+		public static final Operator LESS_EQUALS = new Operator("<=");//$NON-NLS-1$
+		/** Greater than or equals "&gt=;" operator. */
+		public static final Operator GREATER_EQUALS = new Operator(">=");//$NON-NLS-1$
+		/** Equals "==" operator. */
+		public static final Operator EQUALS = new Operator("==");//$NON-NLS-1$
+		/** Not equals "!=" operator. */
+		public static final Operator NOT_EQUALS = new Operator("!=");//$NON-NLS-1$
+		/** Exclusive OR "^" operator. */
+		public static final Operator XOR = new Operator("^");//$NON-NLS-1$
+		/** Inclusive OR "|" operator. */
+		public static final Operator OR = new Operator("|");//$NON-NLS-1$
+		/** AND "&amp;" operator. */
+		public static final Operator AND = new Operator("&");//$NON-NLS-1$
+		/** Conditional OR "||" operator. */
+		public static final Operator CONDITIONAL_OR = new Operator("||");//$NON-NLS-1$
+		/** Conditional AND "&amp;&amp;" operator. */
+		public static final Operator CONDITIONAL_AND = new Operator("&&");//$NON-NLS-1$
+
+		/**
+		 * Map from token to operator (key type: <code>String</code>;
+		 * value type: <code>Operator</code>).
+		 */
+		private static final Map CODES;
+		static {
+			CODES = new HashMap(20);
+			Operator[] ops = {
+					TIMES,
+					DIVIDE,
+					REMAINDER,
+					PLUS,
+					MINUS,
+					LEFT_SHIFT,
+					RIGHT_SHIFT_SIGNED,
+					RIGHT_SHIFT_UNSIGNED,
+					LESS,
+					GREATER,
+					LESS_EQUALS,
+					GREATER_EQUALS,
+					EQUALS,
+					NOT_EQUALS,
+					XOR,
+					OR,
+					AND,
+					CONDITIONAL_OR,
+					CONDITIONAL_AND,
+				};
+			for (int i = 0; i < ops.length; i++) {
+				CODES.put(ops[i].toString(), ops[i]);
+			}
+		}
+
+		/**
+		 * Returns the infix operator corresponding to the given string,
+		 * or <code>null</code> if none.
+		 * <p>
+		 * <code>toOperator</code> is the converse of <code>toString</code>:
+		 * that is, <code>Operator.toOperator(op.toString()) == op</code> for
+		 * all operators <code>op</code>.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 * @return the infix operator, or <code>null</code> if none
+		 */
+		public static Operator toOperator(String token) {
+			return (Operator) CODES.get(token);
+		}
+
+	}
+
+	/**
+	 * The "leftOperand" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LEFT_OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(InfixExpression.class, "leftOperand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "operator" structural property of this node type (type: {@link InfixExpression.Operator}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
+		new SimplePropertyDescriptor(InfixExpression.class, "operator", InfixExpression.Operator.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "rightOperand" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor RIGHT_OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(InfixExpression.class, "rightOperand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "extendedOperands" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor EXTENDED_OPERANDS_PROPERTY =
+		new ChildListPropertyDescriptor(InfixExpression.class, "extendedOperands", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(5);
+		createPropertyList(InfixExpression.class, properyList);
+		addProperty(LEFT_OPERAND_PROPERTY, properyList);
+		addProperty(OPERATOR_PROPERTY, properyList);
+		addProperty(RIGHT_OPERAND_PROPERTY, properyList);
+		addProperty(EXTENDED_OPERANDS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The infix operator; defaults to InfixExpression.Operator.PLUS.
+	 */
+	private InfixExpression.Operator operator = InfixExpression.Operator.PLUS;
+
+	/**
+	 * The left operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression leftOperand = null;
+
+	/**
+	 * The right operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression rightOperand = null;
+
+	/**
+	 * The list of extended operand expressions (element type:
+	 * {@link Expression}). Lazily initialized; defaults to an empty list.
+	 */
+	private ASTNode.NodeList extendedOperands = null;
+
+	/**
+	 * Creates a new AST node for an infix expression owned by the given
+	 * AST. By default, the node has unspecified (but legal) operator,
+	 * left and right operands, and an empty list of additional operands.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	InfixExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == OPERATOR_PROPERTY) {
+			if (get) {
+				return getOperator();
+			} else {
+				setOperator((Operator) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LEFT_OPERAND_PROPERTY) {
+			if (get) {
+				return getLeftOperand();
+			} else {
+				setLeftOperand((Expression) child);
+				return null;
+			}
+		}
+		if (property == RIGHT_OPERAND_PROPERTY) {
+			if (get) {
+				return getRightOperand();
+			} else {
+				setRightOperand((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == EXTENDED_OPERANDS_PROPERTY) {
+			return extendedOperands();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return INFIX_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		InfixExpression result = new InfixExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setOperator(getOperator());
+		result.setLeftOperand((Expression) getLeftOperand().clone(target));
+		result.setRightOperand((Expression) getRightOperand().clone(target));
+		if (this.extendedOperands != null) {
+			// be careful not to trigger lazy creation of list
+			result.extendedOperands().addAll(
+				ASTNode.copySubtrees(target, extendedOperands()));
+		}
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getLeftOperand());
+			acceptChild(visitor, getRightOperand());
+			if (this.extendedOperands != null) {
+				// be careful not to trigger lazy creation of list
+				acceptChildren(visitor, this.extendedOperands);
+			}
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the operator of this infix expression.
+	 *
+	 * @return the infix operator
+	 */
+	public InfixExpression.Operator getOperator() {
+		return this.operator;
+	}
+
+	/**
+	 * Sets the operator of this infix expression.
+	 *
+	 * @param operator the infix operator
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setOperator(InfixExpression.Operator operator) {
+		if (operator == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(OPERATOR_PROPERTY);
+		this.operator = operator;
+		postValueChange(OPERATOR_PROPERTY);
+	}
+
+	/**
+	 * Returns the left operand of this infix expression.
+	 *
+	 * @return the left operand node
+	 */
+	public Expression getLeftOperand() {
+		if (this.leftOperand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.leftOperand == null) {
+					preLazyInit();
+					this.leftOperand= new SimpleName(this.ast);
+					postLazyInit(this.leftOperand, LEFT_OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.leftOperand;
+	}
+
+	/**
+	 * Sets the left operand of this infix expression.
+	 *
+	 * @param expression the left operand node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setLeftOperand(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.leftOperand;
+		preReplaceChild(oldChild, expression, LEFT_OPERAND_PROPERTY);
+		this.leftOperand = expression;
+		postReplaceChild(oldChild, expression, LEFT_OPERAND_PROPERTY);
+	}
+
+	/**
+	 * Returns the right operand of this infix expression.
+	 *
+	 * @return the right operand node
+	 */
+	public Expression getRightOperand() {
+		if (this.rightOperand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.rightOperand  == null) {
+					preLazyInit();
+					this.rightOperand= new SimpleName(this.ast);
+					postLazyInit(this.rightOperand, RIGHT_OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.rightOperand;
+	}
+
+	/**
+	 * Sets the right operand of this infix expression.
+	 *
+	 * @param expression the right operand node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setRightOperand(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.rightOperand;
+		preReplaceChild(oldChild, expression, RIGHT_OPERAND_PROPERTY);
+		this.rightOperand = expression;
+		postReplaceChild(oldChild, expression, RIGHT_OPERAND_PROPERTY);
+	}
+
+	/**
+	 * Returns where there are any extended operands.
+	 *
+	 * @return <code>true</code> if there are one or more extended operands,
+	 *    and <code>false</code> if there are no extended operands
+	 */
+	public boolean hasExtendedOperands() {
+		return
+			(this.extendedOperands != null) && this.extendedOperands.size() > 0;
+	}
+
+	/**
+	 * Returns the live list of extended operands.
+	 * <p>
+	 * The extended operands is the preferred way of representing deeply nested
+	 * expressions of the form <code>L op R op R2 op R3...</code> where
+	 * the same operator appears between all the operands (the most
+	 * common case being lengthy string concatenation expressions). Using
+	 * the extended operands keeps the trees from getting too deep; this
+	 * decreases the risk is running out of thread stack space at runtime
+	 * when traversing such trees.
+	 * ((a + b) + c) + d would be translated to:
+	 * 	leftOperand: a
+	 * 	rightOperand: b
+	 * 	extendedOperands: {c, d}
+	 * 	operator: +
+	 * </p>
+	 *
+	 * @return the live list of extended operands
+	 *   (element type: {@link Expression})
+	 */
+	public List extendedOperands() {
+		if (this.extendedOperands == null) {
+			// lazily initialize
+			this.extendedOperands = new ASTNode.NodeList(EXTENDED_OPERANDS_PROPERTY);
+		}
+		return this.extendedOperands;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.leftOperand == null ? 0 : getLeftOperand().treeSize())
+			+ (this.rightOperand == null ? 0 : getRightOperand().treeSize())
+			+ (this.extendedOperands == null ? 0 : this.extendedOperands.listSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java
new file mode 100644
index 0000000..f1f8874
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Static or instance initializer AST node type.
+ * <pre>
+ * Initializer:
+ *     [ <b>static</b> ] Block
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class Initializer extends BodyDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(Initializer.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		internalModifiersPropertyFactory(Initializer.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(Initializer.class);
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(Initializer.class, "body", Block.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(Initializer.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS_PROPERTY, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(4);
+		createPropertyList(Initializer.class, properyList);
+		addProperty(JAVADOC_PROPERTY, properyList);
+		addProperty(MODIFIERS2_PROPERTY, properyList);
+		addProperty(BODY_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The initializer body; lazily initialized; defaults to an empty block.
+	 */
+	private Block body = null;
+
+	/**
+	 * Creates a new AST node for an initializer declaration owned by the given
+	 * AST. By default, the initializer has no modifiers and an empty block.
+	 * The javadoc comment is not used for initializers.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Initializer(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				internalSetModifiers(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Block) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		return MODIFIERS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return INITIALIZER;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		Initializer result = new Initializer(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		}
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		result.setBody((Block) getBody().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getJavadoc());
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.modifiers);
+			}
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the body of this initializer declaration.
+	 *
+	 * @return the initializer body
+	 */
+	public Block getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body= new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this initializer declaration.
+	 *
+	 * @param body the block node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Block body) {
+		if (body == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, body, BODY_PROPERTY);
+		this.body = body;
+		postReplaceChild(oldChild, body, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
new file mode 100644
index 0000000..3a334a7
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Instanceof expression AST node type.
+ * <pre>
+ * InstanceofExpression:
+ *    Expression <b>instanceof</b> Type
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class InstanceofExpression extends Expression {
+
+	/**
+	 * The "leftOperand" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LEFT_OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(InstanceofExpression.class, "leftOperand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "rightOperand" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor RIGHT_OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(InstanceofExpression.class, "rightOperand", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(InstanceofExpression.class, properyList);
+		addProperty(LEFT_OPERAND_PROPERTY, properyList);
+		addProperty(RIGHT_OPERAND_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The left operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression leftOperand = null;
+
+	/**
+	 * The right operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple type.
+	 */
+	private Type rightOperand = null;
+
+	/**
+	 * Creates a new AST node for an instanceof expression owned by the given
+	 * AST. By default, the node has unspecified (but legal) operator,
+	 * left and right operands.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	InstanceofExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LEFT_OPERAND_PROPERTY) {
+			if (get) {
+				return getLeftOperand();
+			} else {
+				setLeftOperand((Expression) child);
+				return null;
+			}
+		}
+		if (property == RIGHT_OPERAND_PROPERTY) {
+			if (get) {
+				return getRightOperand();
+			} else {
+				setRightOperand((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return INSTANCEOF_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		InstanceofExpression result = new InstanceofExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setLeftOperand((Expression) getLeftOperand().clone(target));
+		result.setRightOperand((Type) getRightOperand().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getLeftOperand());
+			acceptChild(visitor, getRightOperand());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the left operand of this instanceof expression.
+	 *
+	 * @return the left operand node
+	 */
+	public Expression getLeftOperand() {
+		if (this.leftOperand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.leftOperand == null) {
+					preLazyInit();
+					this.leftOperand= new SimpleName(this.ast);
+					postLazyInit(this.leftOperand, LEFT_OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.leftOperand;
+	}
+
+	/**
+	 * Sets the left operand of this instanceof expression.
+	 *
+	 * @param expression the left operand node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setLeftOperand(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.leftOperand;
+		preReplaceChild(oldChild, expression, LEFT_OPERAND_PROPERTY);
+		this.leftOperand = expression;
+		postReplaceChild(oldChild, expression, LEFT_OPERAND_PROPERTY);
+	}
+
+	/**
+	 * Returns the right operand of this instanceof expression.
+	 *
+	 * @return the right operand node
+	 */
+	public Type getRightOperand() {
+		if (this.rightOperand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.rightOperand == null) {
+					preLazyInit();
+					this.rightOperand= new SimpleType(this.ast);
+					postLazyInit(this.rightOperand, RIGHT_OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.rightOperand;
+	}
+
+	/**
+	 * Sets the right operand of this instanceof expression.
+	 *
+	 * @param referenceType the right operand node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setRightOperand(Type referenceType) {
+		if (referenceType == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.rightOperand;
+		preReplaceChild(oldChild, referenceType, RIGHT_OPERAND_PROPERTY);
+		this.rightOperand = referenceType;
+		postReplaceChild(oldChild, referenceType, RIGHT_OPERAND_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.leftOperand == null ? 0 : getLeftOperand().treeSize())
+			+ (this.rightOperand == null ? 0 : getRightOperand().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
new file mode 100644
index 0000000..150fe9c
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
@@ -0,0 +1,278 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.SimplePropertyDescriptor;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
+import org.eclipse.jdt.internal.core.dom.rewrite.LineInformation;
+import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.PropertyLocation;
+
+/**
+ * Internal class: not intended to be used by client.
+ * When AST modifications recording is enabled, all changes are recorded by this class.
+ */
+class InternalASTRewrite extends NodeEventHandler {
+
+	/** root node for the rewrite: Only nodes under this root are accepted */
+	private CompilationUnit root;
+
+	protected final RewriteEventStore eventStore;
+	protected final NodeInfoStore nodeStore;
+	/** ASTNode clone -> ASTNode original */ 
+	protected final Hashtable clonedNodes;
+
+	int cloneDepth = 0;
+
+	/**
+	 * Constructor
+	 * @param root root node of the recorded ast.
+	 */
+	public InternalASTRewrite(CompilationUnit root) {
+		this.root = root;
+		this.eventStore = new RewriteEventStore();
+		this.nodeStore = new NodeInfoStore(root.getAST());
+		this.clonedNodes = new Hashtable();
+	}
+
+	/**
+	 * Performs the rewrite: The rewrite events are translated to the corresponding in text changes.
+	 * The given options can be null in which case the global options {@link JavaCore#getOptions() JavaCore.getOptions()}
+	 * will be used.
+	 *
+	 * @param document Document which describes the code of the AST that is passed in in the
+	 * constructor. This document is accessed read-only.
+	 * @param options the given options
+	 * @throws IllegalArgumentException if the rewrite fails
+	 * @return Returns the edit describing the text changes.
+	 */
+	public TextEdit rewriteAST(IDocument document, Map options) {
+		TextEdit result = new MultiTextEdit();
+
+		final CompilationUnit rootNode = getRootNode();
+		if (rootNode != null) {
+			TargetSourceRangeComputer xsrComputer = new TargetSourceRangeComputer() {
+				/**
+				 * This implementation of
+				 * {@link TargetSourceRangeComputer#computeSourceRange(ASTNode)}
+				 * is specialized to work in the case of internal AST rewriting, where the
+				 * original AST has been modified from its original form. This means that
+				 * one cannot trust that the root of the given node is the compilation unit.
+				 */
+				public SourceRange computeSourceRange(ASTNode node) {
+					int extendedStartPosition = rootNode.getExtendedStartPosition(node);
+					int extendedLength = rootNode.getExtendedLength(node);
+					return new SourceRange(extendedStartPosition, extendedLength);
+				}
+			};
+			char[] content= document.get().toCharArray();
+			LineInformation lineInfo= LineInformation.create(document);
+			String lineDelim= TextUtilities.getDefaultLineDelimiter(document);
+			List comments= rootNode.getCommentList();
+
+			Map currentOptions = options == null ? JavaCore.getOptions() : options;
+			ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(content, lineInfo, lineDelim, result, this.eventStore, this.nodeStore, comments, currentOptions, xsrComputer, (RecoveryScannerData)rootNode.getStatementsRecoveryData());
+			rootNode.accept(visitor);
+		}
+		return result;
+	}
+
+	private  void markAsMoveOrCopyTarget(ASTNode node, ASTNode newChild) {
+		if (this.cloneDepth == 0) {
+			while (node != null && this.clonedNodes.containsKey(node)) {
+				/*
+				 * A modified node cannot be considered as cloned any more.
+				 * we can't copy the original formatting/comments and at the same time modify the node.
+				 * 
+				 * Workaround for https://bugs.eclipse.org/405699 is to remove such nodes from clonedNodes
+				 * and instead mark all children as cloned (or skip them if they are not in clonedNodes).
+				 */
+				ASTNode orig = (ASTNode) this.clonedNodes.remove(node);
+				if (orig != null) {
+					List properties = node.structuralPropertiesForType();
+					for (int i= 0; i < properties.size(); i++) {
+						StructuralPropertyDescriptor property = (StructuralPropertyDescriptor) properties.get(i);
+						Object child = node.getStructuralProperty(property);
+						if (child instanceof ASTNode) {
+							markAsMoveOrCopyTarget(node, (ASTNode) child);
+						} else if (child instanceof List) {
+							List children = (List) child;
+							for (int j= 0; j < children.size(); j++) {
+								ASTNode clonedChild = (ASTNode) children.get(j);
+								markAsMoveOrCopyTarget(node, clonedChild);
+							}
+						}
+					}
+				}
+				
+				node = node.getParent();
+			}
+		}
+		
+		ASTNode source = (ASTNode)this.clonedNodes.get(newChild);
+		if(source != null) {
+			if(this.cloneDepth == 0) {
+				PropertyLocation propertyLocation = this.eventStore.getPropertyLocation(source, RewriteEventStore.ORIGINAL);
+				CopySourceInfo sourceInfo =
+					this.eventStore.markAsCopySource(
+						propertyLocation.getParent(),
+						propertyLocation.getProperty(),
+						source,
+						false);
+				this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
+			}
+		} else if((newChild.getFlags() & ASTNode.ORIGINAL) != 0) {
+			PropertyLocation propertyLocation = this.eventStore.getPropertyLocation(newChild, RewriteEventStore.ORIGINAL);
+			CopySourceInfo sourceInfo =
+				this.eventStore.markAsCopySource(
+					propertyLocation.getParent(),
+					propertyLocation.getProperty(),
+					newChild,
+					true);
+			this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
+		}
+	}
+
+	private CompilationUnit getRootNode() {
+		return this.root;
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		buf.append("Events:\n"); //$NON-NLS-1$
+		buf.append(this.eventStore.toString());
+		return buf.toString();
+	}
+
+	void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		// force event creation
+		getNodeEvent(node, property);
+	}
+
+	void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		NodeRewriteEvent event = getNodeEvent(node, property);
+		event.setNewValue(node.getStructuralProperty(property));
+	}
+
+	void preAddChildEvent(ASTNode node, ASTNode child,	StructuralPropertyDescriptor property) {
+		if(property.isChildProperty()) {
+			NodeRewriteEvent event = getNodeEvent(node, property);
+			event.setNewValue(child);
+			if(child != null) {
+				markAsMoveOrCopyTarget(node, child);
+			}
+		} else if(property.isChildListProperty()) {
+			// force event creation
+			getListEvent(node, property);
+		}
+	}
+
+	void postAddChildEvent(ASTNode node, ASTNode child,	StructuralPropertyDescriptor property) {
+		if(property.isChildListProperty()) {
+
+			ListRewriteEvent event = getListEvent(node, property);
+			List list = (List)node.getStructuralProperty(property);
+			int i = list.indexOf(child);
+			int s = list.size();
+			int index;
+			if(i + 1 < s) {
+				ASTNode nextNode = (ASTNode)list.get(i + 1);
+				index = event.getIndex(nextNode, ListRewriteEvent.NEW);
+			} else {
+				index = -1;
+			}
+			event.insert(child, index);
+			if(child != null) {
+				markAsMoveOrCopyTarget(node, child);
+			}
+		}
+	}
+
+	void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		if(property.isChildProperty()) {
+			NodeRewriteEvent event = getNodeEvent(node, property);
+			event.setNewValue(null);
+		} else if(property.isChildListProperty()) {
+			ListRewriteEvent event = getListEvent(node, property);
+			int i = event.getIndex(child, ListRewriteEvent.NEW);
+			NodeRewriteEvent nodeEvent = (NodeRewriteEvent)event.getChildren()[i];
+			if(nodeEvent.getOriginalValue() == null) {
+				event.revertChange(nodeEvent);
+			} else {
+				nodeEvent.setNewValue(null);
+			}
+		}
+	}
+
+	void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
+		if(property.isChildProperty()) {
+			NodeRewriteEvent event = getNodeEvent(node, property);
+			event.setNewValue(newChild);
+			if(newChild != null) {
+				markAsMoveOrCopyTarget(node, newChild);
+			}
+		} else if(property.isChildListProperty()) {
+			ListRewriteEvent event = getListEvent(node, property);
+			int i = event.getIndex(child, ListRewriteEvent.NEW);
+			NodeRewriteEvent nodeEvent = (NodeRewriteEvent)event.getChildren()[i];
+			nodeEvent.setNewValue(newChild);
+			if(newChild != null) {
+				markAsMoveOrCopyTarget(node, newChild);
+			}
+		}
+	}
+
+
+	void preCloneNodeEvent(ASTNode node) {
+		this.cloneDepth++;
+	}
+
+
+	void postCloneNodeEvent(ASTNode node, ASTNode clone) {
+		if(node.ast == this.root.ast && clone.ast == this.root.ast) {
+			if((node.getFlags() & ASTNode.ORIGINAL) != 0) {
+				this.clonedNodes.put(clone, node);
+			} else {
+				// node can be a cloned node
+				Object original = this.clonedNodes.get(node);
+				if(original != null) {
+					this.clonedNodes.put(clone, original);
+				}
+			}
+		}
+		this.cloneDepth--;
+	}
+
+	private NodeRewriteEvent getNodeEvent(ASTNode node, StructuralPropertyDescriptor property) {
+		return this.eventStore.getNodeEvent(node, property, true);
+	}
+
+	private ListRewriteEvent getListEvent(ASTNode node, StructuralPropertyDescriptor property) {
+		return this.eventStore.getListEvent(node, property, true);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IntersectionType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IntersectionType.java
new file mode 100644
index 0000000..df210fd
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IntersectionType.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for an intersection type in a cast expression (added in JLS8 API).
+ * <pre>
+ * IntersectionType:
+ *    Type <b>&</b> Type { <b>&</b> Type }
+ * </pre>
+ * <p>
+ * This kind of node is used only inside a cast expression.
+ * </p>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class IntersectionType extends Type {
+
+	/**
+	 * The "types" structural property of this node type (element type: {@link Type}).
+	 */
+	public static final ChildListPropertyDescriptor TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(IntersectionType.class, "types", Type.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(IntersectionType.class, propertyList);
+		addProperty(TYPES_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The list of types (element type: {@link Type}).  Defaults to an empty list.
+	 */
+	private ASTNode.NodeList types = new ASTNode.NodeList(TYPES_PROPERTY);
+
+	/**
+	 * Creates a new unparented node for an intersection type owned by the given AST.
+	 * By default, it has no types.<p>
+	 * 
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	IntersectionType(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPES_PROPERTY) {
+			return types();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return INTERSECTION_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		IntersectionType result = new IntersectionType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.types().addAll(
+				ASTNode.copySubtrees(target, types()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.types);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of types in this intersection type.
+	 * Adding and removing nodes from this list affects this node
+	 * dynamically. All nodes in this list must be
+	 * <code>Type</code>s; attempts to add any other
+	 * type of node will trigger an exception.
+	 *
+	 * @return the live list of types in this intersection type (element type: {@link Type})
+	 */
+	public List types() {
+		return this.types;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ this.types.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java
new file mode 100644
index 0000000..ccc4680
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * AST node for a Javadoc-style doc comment.
+ * <pre>
+ * Javadoc:
+ *   <b>/** </b> { TagElement } <b>*</b><b>/</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class Javadoc extends Comment {
+
+	/**
+	 * The "comment" structural property of this node type (type: {@link String}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated Replaced by {@link #TAGS_PROPERTY} in the JLS3 API.
+	 */
+	public static final SimplePropertyDescriptor COMMENT_PROPERTY =
+		new SimplePropertyDescriptor(Javadoc.class, "comment", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "tags" structural property of this node type (element type: {@link TagElement}).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TAGS_PROPERTY =
+		new ChildListPropertyDescriptor(Javadoc.class, "tags", TagElement.class, CYCLE_RISK); //$NON-NLS-1$
+
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(Javadoc.class, properyList);
+		addProperty(COMMENT_PROPERTY, properyList);
+		addProperty(TAGS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(2);
+		createPropertyList(Javadoc.class, properyList);
+		addProperty(TAGS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * Canonical minimal doc comment.
+     * @since 3.0
+	 */
+	private static final String MINIMAL_DOC_COMMENT = "/** */";//$NON-NLS-1$
+
+	/**
+	 * The doc comment string, including opening and closing comment
+	 * delimiters; defaults to a minimal Javadoc comment.
+	 * @deprecated The comment string was replaced in the 3.0 release
+	 * by a representation of the structure of the doc comment.
+	 * For backwards compatibility, it is still funcational as before.
+	 */
+	private String comment = MINIMAL_DOC_COMMENT;
+
+	/**
+	 * The list of tag elements (element type: {@link TagElement}).
+	 * Defaults to an empty list.
+	 * @since 3.0
+	 */
+	private ASTNode.NodeList tags =
+		new ASTNode.NodeList(TAGS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for a doc comment owned by the given AST.
+	 * The new node has an empty list of tag elements (and, for backwards
+	 * compatability, an unspecified, but legal, doc comment string).
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Javadoc(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == COMMENT_PROPERTY) {
+			if (get) {
+				return getComment();
+			} else {
+				setComment((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TAGS_PROPERTY) {
+			return tags();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return JAVADOC;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		Javadoc result = new Javadoc(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.setComment(getComment());
+		}
+		result.tags().addAll(ASTNode.copySubtrees(target, tags()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.tags);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the doc comment string, including the starting
+	 * and ending comment delimiters, and any embedded line breaks.
+	 *
+	 * @return the doc comment string
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated The comment string was replaced in the 3.0 release
+	 * by a representation of the structure of the doc comment.
+	 * See {@link #tags() tags}.
+	 */
+	public String getComment() {
+	    supportedOnlyIn2();
+		return this.comment;
+	}
+
+	/**
+	 * Sets or clears the doc comment string. The documentation
+	 * string must include the starting and ending comment delimiters,
+	 * and any embedded line breaks.
+	 *
+	 * @param docComment the doc comment string
+	 * @exception IllegalArgumentException if the Java comment string is invalid
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated The comment string was replaced in the 3.0 release
+	 * by a representation of the structure of the doc comment.
+	 * See {@link #tags() tags}.
+	 */
+	public void setComment(String docComment) {
+	    supportedOnlyIn2();
+		if (docComment == null) {
+			throw new IllegalArgumentException();
+		}
+		char[] source = docComment.toCharArray();
+		Scanner scanner = this.ast.scanner;
+		scanner.resetTo(0, source.length);
+		scanner.setSource(source);
+		try {
+			int token;
+			boolean onlyOneComment = false;
+			while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						if (onlyOneComment) {
+							throw new IllegalArgumentException();
+						}
+						onlyOneComment = true;
+						break;
+					default:
+						onlyOneComment = false;
+				}
+			}
+			if (!onlyOneComment) {
+				throw new IllegalArgumentException();
+			}
+		} catch (InvalidInputException e) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(COMMENT_PROPERTY);
+		this.comment = docComment;
+		postValueChange(COMMENT_PROPERTY);
+	}
+
+	/**
+	 * Returns the live list of tag elements that make up this doc
+	 * comment.
+	 * <p>
+	 * The tag elements cover everything except the starting and ending
+	 * comment delimiters, and generally omit leading whitespace
+	 * (including a leading "*") and embedded line breaks.
+	 * The first tag element of a typical doc comment represents
+	 * all the material before the first explicit doc tag; this
+	 * first tag element has a <code>null</code> tag name and
+	 * generally contains 1 or more {@link TextElement}s,
+	 * and possibly interspersed with tag elements for nested tags
+	 * like "{@link String String}".
+	 * Subsequent tag elements represent successive top-level doc
+	 * tag (e.g., "@param", "@return", "@see").
+	 * </p>
+	 * <p>
+	 * Adding and removing nodes from this list affects this node
+	 * dynamically.
+	 * </p>
+	 *
+	 * @return the live list of tag elements in this doc comment
+	 * (element type: {@link TagElement})
+	 * @since 3.0
+	 */
+	public List tags() {
+		return this.tags;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = super.memSize() + 2 * 4;
+		if (this.comment != MINIMAL_DOC_COMMENT) {
+			// anything other than the default string takes space
+			size += stringSize(this.comment);
+		}
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize() + this.tags.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java
new file mode 100644
index 0000000..0478995
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Labeled statement AST node type.
+ *
+ * <pre>
+ * LabeledStatement:
+ *    Identifier <b>:</b> Statement
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class LabeledStatement extends Statement {
+
+	/**
+	 * The "label" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor LABEL_PROPERTY =
+		new ChildPropertyDescriptor(LabeledStatement.class, "label", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(LabeledStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(LabeledStatement.class, propertyList);
+		addProperty(LABEL_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The label; lazily initialized; defaults to a unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName labelName = null;
+
+	/**
+	 * The body statement; lazily initialized; defaults to an unspecified, but
+	 * legal, statement.
+	 */
+	private Statement body = null;
+
+	/**
+	 * Creates a new AST node for a labeled statement owned by the given
+	 * AST. By default, the statement has an unspecified (but legal) label
+	 * and an unspecified (but legal) statement.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	LabeledStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == LABEL_PROPERTY) {
+			if (get) {
+				return getLabel();
+			} else {
+				setLabel((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Statement) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return LABELED_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		LabeledStatement result = new LabeledStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setLabel(
+			(SimpleName) ASTNode.copySubtree(target, getLabel()));
+		result.setBody(
+			(Statement) ASTNode.copySubtree(target, getBody()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getLabel());
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the label of this labeled statement.
+	 *
+	 * @return the variable name node
+	 */
+	public SimpleName getLabel() {
+		if (this.labelName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.labelName == null) {
+					preLazyInit();
+					this.labelName= new SimpleName(this.ast);
+					postLazyInit(this.labelName, LABEL_PROPERTY);
+				}
+			}
+		}
+		return this.labelName;
+	}
+
+	/**
+	 * Sets the label of this labeled statement.
+	 *
+	 * @param label the new label
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setLabel(SimpleName label) {
+		if (label == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.labelName;
+		preReplaceChild(oldChild, label, LABEL_PROPERTY);
+		this.labelName = label;
+		postReplaceChild(oldChild, label, LABEL_PROPERTY);
+	}
+
+	/**
+	 * Returns the body of this labeled statement.
+	 *
+	 * @return the body statement node
+	 */
+	public Statement getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body= new EmptyStatement(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this labeled statement.
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the body of a labeled statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the body of a <code>LabeledStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, statement, BODY_PROPERTY);
+		this.body = statement;
+		postReplaceChild(oldChild, statement, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.labelName == null ? 0 : getLabel().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java
new file mode 100644
index 0000000..35fa5b5
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LambdaExpression.java
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Lambda expression AST node type (added in JLS8 API).
+ * <pre>
+ * LambdaExpression:
+ *    Identifier <b>-></b> Body
+ *    <b>(</b> [ Identifier { <b>,</b> Identifier } ] <b>)</b> <b>-></b> Body
+ *    <b>(</b> [ FormalParameter { <b>,</b> FormalParameter } ] <b>)</b> <b>-></b> Body
+ * </pre>
+ * 
+ *<p> 
+ * The first two forms use {@link VariableDeclarationFragment} for the parameter or parameters,
+ * while the third form uses {@link SingleVariableDeclaration}.</p>
+ *<p>The Body can be either a {@link Block} or an {@link Expression}.</p>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients 
+ */
+public class LambdaExpression extends Expression {
+
+	/**
+	 * The "parentheses" structural property of this node type (type: {@link Boolean}).
+	 * <p>
+	 * Note that parentheses are required unless {@link #parameters()} contains
+	 * just a single {@link VariableDeclarationFragment}.
+	 * ASTRewrite may ignore this property if necessary.
+	 * </p>
+	 */
+	public static final SimplePropertyDescriptor PARENTHESES_PROPERTY =
+		new SimplePropertyDescriptor(LambdaExpression.class, "parentheses", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "parameters" structural property of this node type (element type: {@link VariableDeclaration}).
+	 * <p>
+	 * Note that all elements must be of the same type, either all {@link SingleVariableDeclaration} or all {@link VariableDeclarationFragment}.
+	 * </p>
+	 */
+	public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY =
+		new ChildListPropertyDescriptor(LambdaExpression.class, "parameters", VariableDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * The "body" structural property of this node type (child type: {@link ASTNode},
+	 * must be either a {@link Block} or an {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(LambdaExpression.class, "body", ASTNode.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+	
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(LambdaExpression.class, propertyList);
+		addProperty(PARENTHESES_PROPERTY, propertyList);
+		addProperty(PARAMETERS_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+	
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * Indicates whether parentheses are present or not.
+	 * Defaults to <code>true</code>. 
+	 */
+	private boolean hasParentheses = true;
+
+	/**
+	 * The parameter declarations
+	 * (element type: {@link VariableDeclaration}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList parameters =
+		new ASTNode.NodeList(PARAMETERS_PROPERTY);
+
+	/**
+	 * The method body.
+	 * The method body; lazily initialized, defaults to an empty Block.
+	 */
+	private ASTNode body = null;
+
+	/**
+	 * Creates a new AST node for a LambdaExpression declaration owned
+	 * by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	LambdaExpression(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == PARENTHESES_PROPERTY) {
+			if (get) {
+				return hasParentheses();
+			} else {
+				setParentheses(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == PARAMETERS_PROPERTY) {
+			return parameters();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody( child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return LAMBDA_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		LambdaExpression result = new LambdaExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setParentheses(hasParentheses());
+		result.parameters().addAll(ASTNode.copySubtrees(target, parameters()));
+		result.setBody(ASTNode.copySubtree(target, getBody()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.parameters);
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns whether parentheses around the parameters are present or not.
+	 * <p>
+	 * Note that parentheses are required unless {@link #parameters()} contains
+	 * just a single {@link VariableDeclarationFragment}.
+	 * ASTRewrite may ignore this property if necessary.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if this lambda expression has parentheses around
+	 * its parameters and <code>false</code> otherwise
+	 */
+	public boolean hasParentheses() {
+		return this.hasParentheses;
+	}
+
+	/**
+	 * Sets whether this lambda expression should have parentheses around its parameters or not.
+	 * <p>
+	 * Note that parentheses are required unless {@link #parameters()} contains
+	 * just a single {@link VariableDeclarationFragment}.
+	 * ASTRewrite may ignore this property if necessary.
+	 * </p>
+	 *
+	 * @param hasParentheses <code>true</code> if this lambda expression should have parentheses around its parameters
+	 *  and <code>false</code> otherwise
+	 */
+	public void setParentheses(boolean hasParentheses) {
+		preValueChange(PARENTHESES_PROPERTY);
+		this.hasParentheses = hasParentheses;
+		postValueChange(PARENTHESES_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of formal parameters of this lambda expression.
+	 * <p>
+	 * Note that all elements must be of the same type, either all {@link SingleVariableDeclaration} or all {@link VariableDeclarationFragment}.
+	 * </p>
+	 *
+	 * @return the live list of formal parameters of this lambda expression
+	 *    (element type: {@link VariableDeclaration} 
+	 */
+	public List parameters() {
+		return this.parameters;
+	}
+
+	/**
+	 * Returns the body of this lambda expression.
+	 * 
+	 * @return the lambda expression body, which can be either a {@link Block} or an {@link Expression}
+	 */
+	public ASTNode getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this lambda expression.
+	 *
+	 * @param body a block node or an expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * <li>body is neither a {@link Block} nor an {@link Expression}</li>
+	 * </ul>
+	 */
+	public void setBody(ASTNode body) {
+		if (!(body instanceof Expression || body instanceof Block)) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, body, BODY_PROPERTY);
+		this.body = body;
+		postReplaceChild(oldChild, body, BODY_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the lambda expression
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IMethodBinding resolveMethodBinding() {
+		return this.ast.getBindingResolver().resolveMethod(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ this.parameters.listSize()
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java
new file mode 100644
index 0000000..2ed2bc0
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * End-of-line comment AST node type.
+ * <p>
+ * End-of-line comments begin with "//",
+ * must end with a line delimiter (as per JLS 3.7),
+ * and must not contain line breaks.
+ * </p>
+ * <p>
+ * Note that this node type is a comment placeholder, and is
+ * only useful for recording the source range where a comment
+ * was found in a source string. It is not useful for creating
+ * comments.
+ * </p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class LineComment extends Comment {
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(1);
+		createPropertyList(LineComment.class, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new line comment node owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	LineComment(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return LINE_COMMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		LineComment result = new LineComment(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java
new file mode 100644
index 0000000..adf2b59
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Marker annotation node (added in JLS3 API). The marker annotation
+ * "@foo" is equivalent to the normal annotation "@foo()".
+ * <p>
+ * <pre>
+ * MarkerAnnotation:
+ *   <b>@</b> TypeName
+ * </pre>
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class MarkerAnnotation extends Annotation {
+
+	/**
+	 * The "typeName" structural property of this node type (child type: {@link Name}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY =
+		internalTypeNamePropertyFactory(MarkerAnnotation.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(MarkerAnnotation.class, propertyList);
+		addProperty(TYPE_NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new unparented marker annotation node owned
+	 * by the given AST. By default, the annotation has an
+	 * unspecified type name .
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MarkerAnnotation(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_NAME_PROPERTY) {
+			if (get) {
+				return getTypeName();
+			} else {
+				setTypeName((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalTypeNameProperty() {
+		return TYPE_NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return MARKER_ANNOTATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MarkerAnnotation result = new MarkerAnnotation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setTypeName((Name) ASTNode.copySubtree(target, getTypeName()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getTypeName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.typeName == null ? 0 : getTypeName().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java
new file mode 100644
index 0000000..072a573
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AST node for a member reference within a doc comment
+ * ({@link Javadoc}). The principal uses of these are in "@see" and "@link"
+ * tag elements, for references to field members (and occasionally to method
+ * and constructor members).
+ * <pre>
+ * MemberRef:
+ * 		[ Name ] <b>#</b> Identifier
+ * </pre>
+ *
+ * @see Javadoc
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MemberRef extends ASTNode implements IDocElement {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(MemberRef.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MemberRef.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(MemberRef.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * The member name; lazily initialized; defaults to a unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName memberName = null;
+
+	/**
+	 * Creates a new AST node for a member reference owned by the given
+	 * AST. By default, the method reference is for a member with an
+	 * unspecified, but legal, name; and no qualifier.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MemberRef(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return MEMBER_REF;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MemberRef result = new MemberRef(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this member reference, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Sets or clears the qualifier of this member reference.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name of the referenced member.
+	 *
+	 * @return the member name node
+	 */
+	public SimpleName getName() {
+		if (this.memberName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.memberName == null) {
+					preLazyInit();
+					this.memberName = new SimpleName(this.ast);
+					postLazyInit(this.memberName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.memberName;
+	}
+
+	/**
+	 * Sets the name of the referenced member to the given name.
+	 *
+	 * @param name the new member name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the name is <code>null</code></li>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.memberName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.memberName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the entity referred to by
+	 * this member reference.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public final IBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveReference(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.memberName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java
new file mode 100644
index 0000000..b1a01e1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Member value pair node (added in JLS3 API). Member value pairs appear in annotations.
+ * <p>
+ * <pre>
+ * MemberValuePair:
+ *   SimpleName <b>=</b> Expression
+ * </pre>
+ * Within annotations, only certain kinds of expressions are meaningful,
+ * including other annotations.
+ * </p>
+ *
+ * @see NormalAnnotation
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MemberValuePair extends ASTNode {
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MemberValuePair.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "value" structural property of this node type (child type: {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor VALUE_PROPERTY =
+		new ChildPropertyDescriptor(MemberValuePair.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(MemberValuePair.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(VALUE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The member name; lazily initialized; defaults to a unspecified,
+	 * legal name.
+	 */
+	private SimpleName name = null;
+
+	/**
+	 * The value; lazily initialized; defaults to a unspecified,
+	 * legal expression.
+	 */
+	private Expression value = null;
+
+	/**
+	 * Creates a new AST node for a member value pair owned by the given
+	 * AST. By default, the node has an unspecified (but legal) member
+	 * name and value.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MemberValuePair(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == VALUE_PROPERTY) {
+			if (get) {
+				return getValue();
+			} else {
+				setValue((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return MEMBER_VALUE_PAIR;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MemberValuePair result = new MemberValuePair(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
+		result.setValue((Expression) ASTNode.copySubtree(target, getValue()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getName());
+			acceptChild(visitor, getValue());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the member name.
+	 *
+	 * @return the member name node
+	 */
+	public SimpleName getName() {
+		if (this.name == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.name == null) {
+					preLazyInit();
+					this.name = new SimpleName(this.ast);
+					postLazyInit(this.name, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.name;
+	}
+
+	/**
+	 * Resolves and returns the member value pair binding for this member value pair.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 * @since 3.2
+	 */
+	public final IMemberValuePairBinding resolveMemberValuePairBinding() {
+		return this.ast.getBindingResolver().resolveMemberValuePair(this);
+	}
+
+	/**
+	 * Sets the member name.
+	 *
+	 * @param name the member name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.name;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.name = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the value expression.
+	 *
+	 * @return the value expression
+	 */
+	public Expression getValue() {
+		if (this.value == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.value == null) {
+					preLazyInit();
+					this.value= new SimpleName(this.ast);
+					postLazyInit(this.value, VALUE_PROPERTY);
+				}
+			}
+		}
+		return this.value;
+	}
+
+	/**
+	 * Sets the value of this pair.
+	 *
+	 * @param value the new value
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setValue(Expression value) {
+		if (value == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.value;
+		preReplaceChild(oldChild, value, VALUE_PROPERTY);
+		this.value = value;
+		postReplaceChild(oldChild, value, VALUE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.name == null ? 0 : getName().treeSize())
+			+ (this.value == null ? 0 : getValue().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePairBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePairBinding.java
new file mode 100644
index 0000000..cfd8640
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePairBinding.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 BEA Systems, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    tyeung@bea.com - initial API and implementation
+ *    IBM Corporation - implemented methods from IBinding
+ *    IBM Corporation - renamed from ResolvedMemberValuePair to MemberValuePairBinding
+ *    jgarms@bea.com - Fix for IllegalStateException
+ *    IBM Corporation - Fix for 223225
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+/**
+ * Internal class.
+ */
+class MemberValuePairBinding implements IMemberValuePairBinding {
+	static final MemberValuePairBinding[] NoPair = new MemberValuePairBinding[0];
+	private static final Object NoValue = new Object();
+	private static final Object[] EmptyArray = new Object[0];
+
+	private ElementValuePair internalPair;
+	protected Object value = null;
+	protected BindingResolver bindingResolver;
+
+	static void appendValue(Object value, StringBuffer buffer) {
+		if (value instanceof Object[]) {
+			Object[] values = (Object[]) value;
+			buffer.append('{');
+			for (int i = 0, l = values.length; i < l; i++) {
+				if (i != 0)
+					buffer.append(", "); //$NON-NLS-1$
+				appendValue(values[i], buffer);
+			}
+			buffer.append('}');
+		} else if (value instanceof ITypeBinding) {
+			buffer.append(((ITypeBinding) value).getName());
+			buffer.append(".class"); //$NON-NLS-1$
+		} else {
+			buffer.append(value);
+		}
+	}
+
+	static Object buildDOMValue(final Object internalObject, BindingResolver resolver) {
+		if (internalObject == null)
+			return null;
+
+		if (internalObject instanceof Constant) {
+			Constant constant = (Constant) internalObject;
+			switch (constant.typeID()) {
+				case TypeIds.T_boolean:
+					return Boolean.valueOf(constant.booleanValue());
+				case TypeIds.T_byte:
+					return new Byte(constant.byteValue());
+				case TypeIds.T_char:
+					return new Character(constant.charValue());
+				case TypeIds.T_double:
+					return new Double(constant.doubleValue());
+				case TypeIds.T_float:
+					return new Float(constant.floatValue());
+				case TypeIds.T_int:
+					return new Integer(constant.intValue());
+				case TypeIds.T_long:
+					return new Long(constant.longValue());
+				case TypeIds.T_short:
+					return new Short(constant.shortValue());
+				default:
+					// TypeIds.T_JavaLangString:
+					return constant.stringValue();
+			}
+		} else if (internalObject instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+			return resolver.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) internalObject);
+		} else if (internalObject instanceof org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) {
+			return resolver.getAnnotationInstance((org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding) internalObject);
+		} else if (internalObject instanceof org.eclipse.jdt.internal.compiler.lookup.FieldBinding) {
+			return resolver.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.FieldBinding) internalObject);
+		} else if (internalObject instanceof Object[]) {
+			Object[] elements = (Object[]) internalObject;
+			int length = elements.length;
+			Object[] values = length == 0 ? EmptyArray : new Object[length];
+			for (int i = 0; i < length; i++)
+				values[i] = buildDOMValue(elements[i], resolver);
+			return values;
+		}
+		return null;
+	}
+
+	MemberValuePairBinding(ElementValuePair pair, BindingResolver resolver) {
+		this.internalPair = pair;
+		this.bindingResolver = resolver;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		return AnnotationBinding.NoAnnotations;
+	}
+
+	public IJavaElement getJavaElement() {
+		return null;
+	}
+
+	public String getKey() {
+		// TODO when implementing, update spec in IBinding
+		return null;
+	}
+
+	public int getKind() {
+		return IBinding.MEMBER_VALUE_PAIR;
+	}
+
+	public IMethodBinding getMethodBinding() {
+		return this.bindingResolver.getMethodBinding(this.internalPair.getMethodBinding());
+	}
+
+	public int getModifiers() {
+		return Modifier.NONE;
+	}
+
+	public String getName() {
+		if (this.internalPair == null)
+			return null;
+		final char[] membername = this.internalPair.getName();
+		return membername == null ? null : new String(membername);
+	}
+
+	public Object getValue() {
+		if (this.value == null)
+			init();
+		return this.value == NoValue ? null : this.value;
+	}
+
+	private void init() {
+		this.value = buildDOMValue(this.internalPair.getValue(), this.bindingResolver);
+		if (this.value == null)
+			this.value = NoValue;
+		IMethodBinding methodBinding = getMethodBinding();
+		if (methodBinding.getReturnType().isArray() && !this.value.getClass().isArray()) {
+			this.value = new Object[] { this.value }; 
+		}
+	}
+
+	char[] internalName() {
+		return this.internalPair == null ? null : this.internalPair.getName();
+	}
+
+	public boolean isDefault() {
+		Object value2 = getValue();
+		Object defaultValue = getMethodBinding().getDefaultValue();
+		if (value2 instanceof IBinding) {
+			if (defaultValue instanceof IBinding) {
+				return ((IBinding) value2).isEqualTo((IBinding) defaultValue);
+			}
+			return false;
+		}
+		if (defaultValue == null) return false;
+		return defaultValue.equals(value2);
+	}
+
+	public boolean isDeprecated() {
+		MethodBinding methodBinding = this.internalPair.getMethodBinding();
+		return methodBinding == null ? false : methodBinding.isDeprecated();
+	}
+
+	public boolean isEqualTo(IBinding binding) {
+		if (this == binding)
+			return true;
+		if (binding.getKind() != IBinding.MEMBER_VALUE_PAIR)
+			return false;
+		IMemberValuePairBinding otherMemberValuePairBinding = (IMemberValuePairBinding) binding;
+		if (!getMethodBinding().isEqualTo(otherMemberValuePairBinding.getMethodBinding())) {
+			return false;
+		}
+		Object otherValue = otherMemberValuePairBinding.getValue();
+		Object currentValue = getValue();
+		if (currentValue == null) {
+			return otherValue == null;
+		}
+		if (currentValue instanceof IBinding) {
+			if (otherValue instanceof IBinding) {
+				return ((IBinding) currentValue).isEqualTo((IBinding) otherValue);
+			}
+			return false;
+		}
+		if (currentValue.getClass().isArray()) {
+			if (!otherValue.getClass().isArray()) {
+				return false;
+			}
+			Object[] currentValues = (Object[]) currentValue;
+			Object[] otherValues = (Object[]) otherValue;
+			final int length = currentValues.length;
+			if (length != otherValues.length) {
+				return false;
+			}
+			for (int i = 0; i < length; i++) {
+				Object current = currentValues[i];
+				Object other = otherValues[i];
+				if (current instanceof IBinding) {
+					if (!(other instanceof IBinding)) {
+						return false;
+					}
+					if (!((IBinding) current).isEqualTo((IBinding) other)) {
+						return false;
+					}
+				} else if (!current.equals(other)) {
+					return false;
+				}
+			}
+			return true;
+		} else {
+			return currentValue.equals(otherValue);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return false;
+	}
+
+	public boolean isSynthetic() {
+		return false;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(getName());
+		buffer.append(" = "); //$NON-NLS-1$
+		appendValue(getValue(), buffer);
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java
new file mode 100644
index 0000000..cf231c8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Error message used to report potential errors found during the AST parsing
+ * or name resolution. Instances of this class are immutable.
+ *
+ * @since 2.0
+ */
+public class Message {
+
+	/**
+	 * The message.
+	 */
+	private String message;
+
+	/**
+	 * The character index into the original source string, or -1 if none.
+	 */
+	private int startPosition;
+
+	/**
+	 * The length in characters of the original source file indicating
+	 * where the source fragment corresponding to this message ends.
+	 */
+	private int length;
+
+	/**
+	 * Creates a message.
+	 *
+	 * @param message the localized message reported by the compiler
+	 * @param startPosition the 0-based character index into the
+	 *    original source file, or <code>-1</code> if no source position
+	 *    information is to be recorded for this message
+	 * @throws IllegalArgumentException if the message is null
+	 * @throws IllegalArgumentException if the startPosition is lower than -1.
+	 */
+	public Message(String message, int startPosition) {
+		if (message == null) {
+			throw new IllegalArgumentException();
+		}
+		if (startPosition < -1) {
+			throw new IllegalArgumentException();
+		}
+		this.message = message;
+		this.startPosition = startPosition;
+		this.length = 0;
+	}
+
+	/**
+	 * Creates a message.
+	 *
+	 * @param message the localized message reported by the compiler
+	 * @param startPosition the 0-based character index into the
+	 *    original source file, or <code>-1</code> if no source position
+	 *    information is to be recorded for this message
+	 * @param length the length in character of the original source file indicating
+	 * 	  where the source fragment corresponding to this message ends. 0 or a negative number
+	 *    if none. A negative number will be converted to a 0-length.
+	 * @throws IllegalArgumentException if the message is null
+	 * @throws IllegalArgumentException if the startPosition is lower than -1.
+	 */
+	public Message(String message, int startPosition, int length) {
+		if (message == null) {
+			throw new IllegalArgumentException();
+		}
+		if (startPosition < -1) {
+			throw new IllegalArgumentException();
+		}
+		this.message = message;
+		this.startPosition = startPosition;
+		if (length <= 0) {
+			this.length = 0;
+		} else {
+			this.length = length;
+		}
+	}
+
+	/**
+	 * Returns the localized message.
+	 *
+	 * @return the localized message
+	 */
+	public String getMessage() {
+		return this.message;
+	}
+
+	/**
+	 * Returns the character index into the original source file.
+	 *
+	 * @return the 0-based character index, or <code>-1</code>
+	 *    if no source position information is recorded for this
+	 *    message
+	 * @deprecated Use {@link #getStartPosition()} instead.
+	 * @see #getLength()
+	 */
+	public int getSourcePosition() {
+		return getStartPosition();
+	}
+
+	/**
+	 * Returns the character index into the original source file.
+	 *
+	 * @return the 0-based character index, or <code>-1</code>
+	 *    if no source position information is recorded for this
+	 *    message
+	 * @see #getLength()
+	 */
+	public int getStartPosition() {
+		return this.startPosition;
+	}
+
+	/**
+	 * Returns the length in characters of the original source file indicating
+	 * where the source fragment corresponding to this message ends.
+	 *
+	 * @return a length, or <code>0</code>
+	 *    if no source length information is recorded for this message
+	 * @see #getStartPosition()
+	 */
+	public int getLength() {
+		return this.length;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
new file mode 100644
index 0000000..534984d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -0,0 +1,447 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Internal implementation of method bindings.
+ */
+class MethodBinding implements IMethodBinding {
+
+	private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+		Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | Modifier.NATIVE |
+		Modifier.STRICTFP;
+	private static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
+	private org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding;
+	private BindingResolver resolver;
+	private ITypeBinding[] parameterTypes;
+	private ITypeBinding[] exceptionTypes;
+	private String name;
+	private ITypeBinding declaringClass;
+	private ITypeBinding returnType;
+	private String key;
+	private ITypeBinding[] typeParameters;
+	private ITypeBinding[] typeArguments;
+	private IAnnotationBinding[] annotations;
+	private IAnnotationBinding[][] parameterAnnotations;
+
+	MethodBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.MethodBinding binding) {
+		this.resolver = resolver;
+		this.binding = binding;
+	}
+
+	public boolean isAnnotationMember() {
+		return getDeclaringClass().isAnnotation();
+	}
+
+	/**
+	 * @see IMethodBinding#isConstructor()
+	 */
+	public boolean isConstructor() {
+		return this.binding.isConstructor();
+	}
+
+	/**
+	 * @see IMethodBinding#isDefaultConstructor()
+	 * @since 3.0
+	 */
+	public boolean isDefaultConstructor() {
+		final ReferenceBinding declaringClassBinding = this.binding.declaringClass;
+		if (declaringClassBinding.isRawType()) {
+			RawTypeBinding rawTypeBinding = (RawTypeBinding) declaringClassBinding;
+			if (rawTypeBinding.genericType().isBinaryBinding()) {
+				return false;
+			}
+			return (this.binding.modifiers & ExtraCompilerModifiers.AccIsDefaultConstructor) != 0;
+		}
+		if (declaringClassBinding.isBinaryBinding()) {
+			return false;
+		}
+		return (this.binding.modifiers & ExtraCompilerModifiers.AccIsDefaultConstructor) != 0;
+	}
+
+	/**
+	 * @see IBinding#getName()
+	 */
+	public String getName() {
+		if (this.name == null) {
+			if (this.binding.isConstructor()) {
+				this.name = getDeclaringClass().getName();
+			} else {
+				this.name = new String(this.binding.selector);
+			}
+		}
+		return this.name;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		if (this.annotations != null) {
+			return this.annotations;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = this.binding.getAnnotations();
+		int length = internalAnnotations == null ? 0 : internalAnnotations.length;
+		if (length != 0) {
+			IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
+			int convertedAnnotationCount = 0;
+			for (int i = 0; i < length; i++) {
+				org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
+				final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
+				if (annotationInstance == null) {
+					continue;
+				}
+				tempAnnotations[convertedAnnotationCount++] = annotationInstance;
+			}
+			if (convertedAnnotationCount != length) {
+				if (convertedAnnotationCount == 0) {
+					return this.annotations = AnnotationBinding.NoAnnotations;
+				}
+				System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
+			}
+			return this.annotations = tempAnnotations;
+		}
+		return this.annotations = AnnotationBinding.NoAnnotations;
+	}
+
+	/**
+	 * @see IMethodBinding#getDeclaringClass()
+	 */
+	public ITypeBinding getDeclaringClass() {
+		if (this.declaringClass == null) {
+			this.declaringClass = this.resolver.getTypeBinding(this.binding.declaringClass);
+		}
+		return this.declaringClass;
+	}
+
+	public IAnnotationBinding[] getParameterAnnotations(int index) {
+		if (getParameterTypes() == NO_TYPE_BINDINGS) {
+			return AnnotationBinding.NoAnnotations;
+		}
+		if (this.parameterAnnotations != null) {
+			return this.parameterAnnotations[index];
+		}
+		org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[][] bindingAnnotations = this.binding.getParameterAnnotations();
+		if (bindingAnnotations == null) return AnnotationBinding.NoAnnotations;
+
+		int length = bindingAnnotations.length;
+		IAnnotationBinding[][] domAnnotations = new IAnnotationBinding[length][];
+		for (int i = 0; i < length; i++) {
+			org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] paramBindingAnnotations = bindingAnnotations[i];
+			int pLength = paramBindingAnnotations.length;
+			domAnnotations[i] = new AnnotationBinding[pLength];
+			for (int j=0; j<pLength; j++) {
+				IAnnotationBinding domAnnotation = this.resolver.getAnnotationInstance(paramBindingAnnotations[j]);
+				if (domAnnotation == null) {
+					domAnnotations[i] = AnnotationBinding.NoAnnotations;
+					break;
+				}
+				domAnnotations[i][j] = domAnnotation;
+			}
+		}
+		this.parameterAnnotations = domAnnotations;
+
+		return this.parameterAnnotations[index];
+	}
+
+	/**
+	 * @see IMethodBinding#getParameterTypes()
+	 */
+	public ITypeBinding[] getParameterTypes() {
+		if (this.parameterTypes != null) {
+			return this.parameterTypes;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] parameters = this.binding.parameters;
+		int length = parameters == null ? 0 : parameters.length;
+		if (length == 0) {
+			return this.parameterTypes = NO_TYPE_BINDINGS;
+		} else {
+			ITypeBinding[] paramTypes = new ITypeBinding[length];
+			for (int i = 0; i < length; i++) {
+				final TypeBinding parameterBinding = parameters[i];
+				if (parameterBinding != null) {
+					ITypeBinding typeBinding = this.resolver.getTypeBinding(parameterBinding);
+					if (typeBinding == null) {
+						return this.parameterTypes = NO_TYPE_BINDINGS;
+					}
+					paramTypes[i] = typeBinding;
+				} else {
+					// log error
+					StringBuffer message = new StringBuffer("Report method binding where a parameter is null:\n");  //$NON-NLS-1$
+					message.append(toString());
+					Util.log(new IllegalArgumentException(), message.toString());
+					// report no binding since one or more parameter has no binding
+					return this.parameterTypes = NO_TYPE_BINDINGS;
+				}
+			}
+			return this.parameterTypes = paramTypes;
+		}
+	}
+
+	/**
+	 * @see IMethodBinding#getReturnType()
+	 */
+	public ITypeBinding getReturnType() {
+		if (this.returnType == null) {
+			this.returnType = this.resolver.getTypeBinding(this.binding.returnType);
+		}
+		return this.returnType;
+	}
+
+	public Object getDefaultValue() {
+		if (isAnnotationMember())
+			return MemberValuePairBinding.buildDOMValue(this.binding.getDefaultValue(), this.resolver);
+		return null;
+	}
+
+	/**
+	 * @see IMethodBinding#getExceptionTypes()
+	 */
+	public ITypeBinding[] getExceptionTypes() {
+		if (this.exceptionTypes != null) {
+			return this.exceptionTypes;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] exceptions = this.binding.thrownExceptions;
+		int length = exceptions == null ? 0 : exceptions.length;
+		if (length == 0) {
+			return this.exceptionTypes = NO_TYPE_BINDINGS;
+		}
+		ITypeBinding[] exTypes = new ITypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			ITypeBinding typeBinding = this.resolver.getTypeBinding(exceptions[i]);
+			if (typeBinding == null) {
+				return this.exceptionTypes = NO_TYPE_BINDINGS;
+			}
+			exTypes[i] = typeBinding;
+		}
+		return this.exceptionTypes = exTypes;
+	}
+
+	public IJavaElement getJavaElement() {
+		JavaElement element = getUnresolvedJavaElement();
+		if (element == null)
+			return null;
+		return element.resolved(this.binding);
+	}
+
+	private JavaElement getUnresolvedJavaElement() {
+		if (JavaCore.getPlugin() == null) {
+			return null;
+		}
+		if (!(this.resolver instanceof DefaultBindingResolver)) return null;
+
+		DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
+		if (!defaultBindingResolver.fromJavaProject) return null;
+		return Util.getUnresolvedJavaElement(
+				this.binding,
+				defaultBindingResolver.workingCopyOwner,
+				defaultBindingResolver.getBindingsToNodesMap());
+	}
+
+	/**
+	 * @see IBinding#getKind()
+	 */
+	public int getKind() {
+		return IBinding.METHOD;
+	}
+
+	/**
+	 * @see IBinding#getModifiers()
+	 */
+	public int getModifiers() {
+		return this.binding.getAccessFlags() & VALID_MODIFIERS;
+	}
+
+	/**
+	 * @see IBinding#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		return this.binding.isDeprecated();
+	}
+
+	/**
+	 * @see IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return false;
+	}
+
+	/**
+	 * @see IBinding#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return this.binding.isSynthetic();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#isVarargs()
+	 * @since 3.1
+	 */
+	public boolean isVarargs() {
+		return this.binding.isVarargs();
+	}
+
+	/**
+	 * @see IBinding#getKey()
+	 */
+	public String getKey() {
+		if (this.key == null) {
+			this.key = new String(this.binding.computeUniqueKey());
+		}
+		return this.key;
+	}
+
+	/**
+	 * @see IBinding#isEqualTo(IBinding)
+	 * @since 3.1
+	 */
+	public boolean isEqualTo(IBinding other) {
+		if (other == this) {
+			// identical binding - equal (key or no key)
+			return true;
+		}
+		if (other == null) {
+			// other binding missing
+			return false;
+		}
+		if (!(other instanceof MethodBinding)) {
+			return false;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.MethodBinding otherBinding = ((MethodBinding) other).binding;
+		return BindingComparator.isEqual(this.binding, otherBinding);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#getTypeParameters()
+	 */
+	public ITypeBinding[] getTypeParameters() {
+		if (this.typeParameters != null) {
+			return this.typeParameters;
+		}
+		TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
+		int typeVariableBindingsLength = typeVariableBindings == null ? 0 : typeVariableBindings.length;
+		if (typeVariableBindingsLength == 0) {
+			return this.typeParameters = NO_TYPE_BINDINGS;
+		}
+		ITypeBinding[] tParameters = new ITypeBinding[typeVariableBindingsLength];
+		for (int i = 0; i < typeVariableBindingsLength; i++) {
+			ITypeBinding typeBinding = this.resolver.getTypeBinding(typeVariableBindings[i]);
+			if (typeBinding == null) {
+				return this.typeParameters = NO_TYPE_BINDINGS;
+			}
+			tParameters[i] = typeBinding;
+		}
+		return this.typeParameters = tParameters;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#isGenericMethod()
+	 * @since 3.1
+	 */
+	public boolean isGenericMethod() {
+		// equivalent to return getTypeParameters().length > 0;
+		if (this.typeParameters != null) {
+			return this.typeParameters.length > 0;
+		}
+		TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
+		return (typeVariableBindings != null && typeVariableBindings.length > 0);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#getTypeArguments()
+	 */
+	public ITypeBinding[] getTypeArguments() {
+		if (this.typeArguments != null) {
+			return this.typeArguments;
+		}
+
+		if (this.binding instanceof ParameterizedGenericMethodBinding) {
+			ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) this.binding;
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] typeArgumentsBindings = genericMethodBinding.typeArguments;
+			int typeArgumentsLength = typeArgumentsBindings == null ? 0 : typeArgumentsBindings.length;
+			if (typeArgumentsLength != 0) {
+				ITypeBinding[] tArguments = new ITypeBinding[typeArgumentsLength];
+				for (int i = 0; i < typeArgumentsLength; i++) {
+					ITypeBinding typeBinding = this.resolver.getTypeBinding(typeArgumentsBindings[i]);
+					if (typeBinding == null) {
+						return this.typeArguments = NO_TYPE_BINDINGS;
+					}
+					tArguments[i] = typeBinding;
+				}
+				return this.typeArguments = tArguments;
+			}
+		}
+		return this.typeArguments = NO_TYPE_BINDINGS;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#isParameterizedMethod()
+	 */
+	public boolean isParameterizedMethod() {
+		return (this.binding instanceof ParameterizedGenericMethodBinding)
+			&& !((ParameterizedGenericMethodBinding) this.binding).isRaw;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#isRawMethod()
+	 */
+	public boolean isRawMethod() {
+		return (this.binding instanceof ParameterizedGenericMethodBinding)
+			&& ((ParameterizedGenericMethodBinding) this.binding).isRaw;
+	}
+
+	public boolean isSubsignature(IMethodBinding otherMethod) {
+		try {
+			LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
+			return lookupEnvironment != null
+				&& lookupEnvironment.methodVerifier().isMethodSubsignature(this.binding, ((MethodBinding) otherMethod).binding);
+		} catch (AbortCompilation e) {
+			// don't surface internal exception to clients
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
+			return false;
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#getMethodDeclaration()
+	 */
+	public IMethodBinding getMethodDeclaration() {
+		return this.resolver.getMethodBinding(this.binding.original());
+	}
+
+	/**
+	 * @see IMethodBinding#overrides(IMethodBinding)
+	 */
+	public boolean overrides(IMethodBinding otherMethod) {
+			LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
+			return lookupEnvironment != null
+				&& lookupEnvironment.methodVerifier().doesMethodOverride(this.binding, ((MethodBinding) otherMethod).binding);
+	}
+
+	/**
+	 * For debugging purpose only.
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.binding.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
new file mode 100644
index 0000000..b00d0de
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
@@ -0,0 +1,1181 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Method declaration AST node type. A method declaration
+ * is the union of a method declaration and a constructor declaration.
+ * 
+ * <pre>
+ * MethodDeclaration:
+ *    [ Javadoc ] { ExtendedModifier } [ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ] ( Type | <b>void</b> )
+ *        Identifier <b>(</b>
+ *            [ ReceiverParameter <b>,</b> ] [ FormalParameter { <b>,</b> FormalParameter } ]
+ *        <b>)</b> { ExtraDimension }
+ *        [ <b>throws</b> Type { <b>,</b> Type } ]
+ *        ( Block | <b>;</b> )
+ * ConstructorDeclaration:
+ *    [ Javadoc ] { ExtendedModifier } [ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
+ *        Identifier <b>(</b>
+ *            [ ReceiverParameter <b>,</b> ] [ FormalParameter { <b>,</b> FormalParameter } ]
+ *        <b>)</b> { ExtraDimension }
+ *        [ <b>throws</b> Type { <b>,</b> Type } ]
+ *        ( Block | <b>;</b> )
+ * </pre>
+ * <p>
+ * The ReceiverParameter is represented as: <code>AnnotatableType [ SimpleName <b>.</b> ] <b>this</b></code><br>
+ * The FormalParameter is represented by a {@link SingleVariableDeclaration}.
+ * </p>
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier keyword (if modifiers), or the
+ * first character of the "&lt;" token (method, no modifiers, type parameters),
+ * or the first character of the return type (method, no modifiers, no type
+ * parameters), or the first character of the identifier (constructor,
+ * no modifiers). The source range extends through the last character of the
+ * ";" token (if no body), or the last character of the block (if body).
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MethodDeclaration extends BodyDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(MethodDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		internalModifiersPropertyFactory(MethodDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(MethodDeclaration.class);
+
+	/**
+	 * The "constructor" structural property of this node type (type: {@link Boolean}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor CONSTRUCTOR_PROPERTY =
+		new SimplePropertyDescriptor(MethodDeclaration.class, "constructor", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MethodDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "returnType" structural property of this node type (child type: {@link Type}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #RETURN_TYPE2_PROPERTY}.
+	 */
+	public static final ChildPropertyDescriptor RETURN_TYPE_PROPERTY =
+		new ChildPropertyDescriptor(MethodDeclaration.class, "returnType", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "returnType2" structural property of this node type (child type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildPropertyDescriptor RETURN_TYPE2_PROPERTY =
+		new ChildPropertyDescriptor(MethodDeclaration.class, "returnType2", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "extraDimensions" structural property of this node type (type: {@link Integer}) (below JLS8 only).
+	 *
+	 * @since 3.0
+	 * @deprecated In JLS8 and later, use {@link MethodDeclaration#EXTRA_DIMENSIONS2_PROPERTY} instead.
+	 */
+	public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY =
+		new SimplePropertyDescriptor(MethodDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
+	
+	/**
+	 * The "extraDimensions2" structural property of this node type (element type: {@link ExtraDimension}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor EXTRA_DIMENSIONS2_PROPERTY =
+			new ChildListPropertyDescriptor(MethodDeclaration.class, "extraDimensions2", ExtraDimension.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "parameters" structural property of this node type (element type: {@link SingleVariableDeclaration}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodDeclaration.class, "parameters", SingleVariableDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "receiverType" structural property of this node type (child type: {@link AnnotatableType}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildPropertyDescriptor RECEIVER_TYPE_PROPERTY =
+			new ChildPropertyDescriptor(MethodDeclaration.class, "receiverType", AnnotatableType.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * The "receiverQualifier" structural property of this node type (child type: {@link SimpleName}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildPropertyDescriptor RECEIVER_QUALIFIER_PROPERTY =
+			new ChildPropertyDescriptor(MethodDeclaration.class, "receiverQualifier", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "thrownExceptions" structural property of this node type (element type: {@link Name}) (before JLS8 only).
+	 * @deprecated In JLS8 and later, use {@link MethodDeclaration#THROWN_EXCEPTION_TYPES_PROPERTY} instead.
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor THROWN_EXCEPTIONS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptions", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "thrownExceptionTypes" structural property of this node type (element type: {@link Type}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor THROWN_EXCEPTION_TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptionTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(MethodDeclaration.class, "body", Block.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(10);
+		createPropertyList(MethodDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(MODIFIERS_PROPERTY, propertyList);
+		addProperty(CONSTRUCTOR_PROPERTY, propertyList);
+		addProperty(RETURN_TYPE_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(PARAMETERS_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
+		addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(11);
+		createPropertyList(MethodDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(CONSTRUCTOR_PROPERTY, propertyList);
+		addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
+		addProperty(RETURN_TYPE2_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(PARAMETERS_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
+		addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(13);
+		createPropertyList(MethodDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(CONSTRUCTOR_PROPERTY, propertyList);
+		addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
+		addProperty(RETURN_TYPE2_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(RECEIVER_TYPE_PROPERTY, propertyList);
+		addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList);
+		addProperty(PARAMETERS_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList);
+		addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);	
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else if (apiLevel < AST.JLS8) {
+			return PROPERTY_DESCRIPTORS_3_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * <code>true</code> for a constructor, <code>false</code> for a method.
+	 * Defaults to method.
+	 */
+	private boolean isConstructor = false;
+
+	/**
+	 * The method name; lazily initialized; defaults to an unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * The explicit receiver type, or <code>null</code> if none.
+	 * Defaults to none.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private AnnotatableType optionalReceiverType = null;
+	
+	/**
+	 * Qualifying name of the explicit </code>this</code> parameter, or <code>null</code> if none.
+	 * Defaults to none.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private SimpleName optionalReceiverQualifier = null;
+
+	/**
+	 * The parameter declarations
+	 * (element type: {@link SingleVariableDeclaration}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList parameters =
+		new ASTNode.NodeList(PARAMETERS_PROPERTY);
+
+	/**
+	 * The return type.
+	 * JLS2 behavior: lazily initialized; defaults to void.
+	 * JLS3 and later: lazily initialized; defaults to void; null allowed.
+	 * Note that this field is ignored for constructor declarations.
+	 */
+	private Type returnType = null;
+
+	/**
+	 * Indicated whether the return type has been initialized.
+	 * @since 3.1
+	 */
+	private boolean returnType2Initialized = false;
+
+	/**
+	 * The type paramters (element type: {@link TypeParameter}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeParameters = null;
+
+	/**
+	 * The number of array dimensions that appear after the parameters, rather
+	 * than after the return type itself; defaults to 0. Not used in JLS8 and later.
+	 *
+	 * @since 2.1
+	 * @deprecated In JLS8 and later, use {@link #extraDimensions} instead.
+	 */
+	private int extraArrayDimensions = 0;
+
+	/**
+	 * List of extra dimensions this node has with optional annotations
+	 * (element type: {@link ExtraDimension}).
+	 * Null before JLS8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private ASTNode.NodeList extraDimensions = null;
+
+	/**
+	 * The list of thrown exception names (element type: {@link Name}).
+	 * Before JLS8: defaults to an empty list (see constructor).
+	 * JLS8 and later: null.
+	 * @deprecated In JLS8 and later, use {@link #thrownExceptionTypes} instead.
+	 */
+	private ASTNode.NodeList thrownExceptions = null;
+
+	/**
+	 * The list of thrown exception Types (element type: {@link Type}).
+	 * Null before JLS8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private ASTNode.NodeList thrownExceptionTypes = null;
+
+	/**
+	 * The method body, or <code>null</code> if none.
+	 * Defaults to none.
+	 */
+	private Block optionalBody = null;
+
+	/**
+	 * Creates a new AST node for a method declaration owned
+	 * by the given AST. By default, the declaration is for a method of an
+	 * unspecified, but legal, name; no modifiers; no javadoc; no type
+	 * parameters; void return type; no parameters; no array dimensions after
+	 * the parameters; no thrown exceptions; and no body (as opposed to an
+	 * empty body).
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MethodDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY);
+		}
+		if (ast.apiLevel < AST.JLS8) {
+			this.thrownExceptions = new ASTNode.NodeList(THROWN_EXCEPTIONS_PROPERTY);
+		} else {
+			this.extraDimensions = new ASTNode.NodeList(EXTRA_DIMENSIONS2_PROPERTY);
+			this.thrownExceptionTypes = new ASTNode.NodeList(THROWN_EXCEPTION_TYPES_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				internalSetModifiers(value);
+				return 0;
+			}
+		}
+		if (property == EXTRA_DIMENSIONS_PROPERTY) {
+			if (get) {
+				return getExtraDimensions();
+			} else {
+				setExtraDimensions(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == CONSTRUCTOR_PROPERTY) {
+			if (get) {
+				return isConstructor();
+			} else {
+				setConstructor(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == RETURN_TYPE_PROPERTY) {
+			if (get) {
+				return getReturnType();
+			} else {
+				setReturnType((Type) child);
+				return null;
+			}
+		}
+		if (property == RETURN_TYPE2_PROPERTY) {
+			if (get) {
+				return getReturnType2();
+			} else {
+				setReturnType2((Type) child);
+				return null;
+			}
+		}
+		if (property == RECEIVER_TYPE_PROPERTY) {
+			if (get) {
+				return getReceiverType();
+			} else {
+				setReceiverType((AnnotatableType) child);
+				return null;
+			}
+		}
+		if (property == RECEIVER_QUALIFIER_PROPERTY) {
+			if (get) {
+				return getReceiverQualifier();
+			} else {
+				setReceiverQualifier((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Block) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == TYPE_PARAMETERS_PROPERTY) {
+			return typeParameters();
+		}
+		if (property == PARAMETERS_PROPERTY) {
+			return parameters();
+		}
+		if (property == THROWN_EXCEPTIONS_PROPERTY) {
+			return thrownExceptions();
+		}
+		if (property == THROWN_EXCEPTION_TYPES_PROPERTY) {
+			return thrownExceptionTypes();
+		}		
+		if (property == EXTRA_DIMENSIONS2_PROPERTY) {
+			return extraDimensions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		return MODIFIERS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return METHOD_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MethodDeclaration result = new MethodDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
+			result.setReturnType(
+					(Type) ASTNode.copySubtree(target, getReturnType()));
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+			result.typeParameters().addAll(
+					ASTNode.copySubtrees(target, typeParameters()));
+			result.setReturnType2(
+					(Type) ASTNode.copySubtree(target, getReturnType2()));
+		}
+		result.setConstructor(isConstructor());
+		result.setName((SimpleName) getName().clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.setReceiverType((AnnotatableType) ASTNode.copySubtree(target, getReceiverType()));
+			result.setReceiverQualifier((SimpleName) ASTNode.copySubtree(target, getReceiverQualifier()));
+		}
+		result.parameters().addAll(
+			ASTNode.copySubtrees(target, parameters()));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.extraDimensions().addAll(ASTNode.copySubtrees(target, extraDimensions()));
+		} else {
+			result.setExtraDimensions(getExtraDimensions());
+		}
+		if (this.ast.apiLevel() >= AST.JLS8) {
+			result.thrownExceptionTypes().addAll(ASTNode.copySubtrees(target, thrownExceptionTypes()));
+		} else {
+			result.thrownExceptions().addAll(ASTNode.copySubtrees(target, thrownExceptions()));			
+		}
+		result.setBody(
+			(Block) ASTNode.copySubtree(target, getBody()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getJavadoc());
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+				acceptChild(visitor, getReturnType());
+			} else {
+				acceptChildren(visitor, this.modifiers);
+				acceptChildren(visitor, this.typeParameters);
+				acceptChild(visitor, getReturnType2());
+			}
+			// n.b. visit return type even for constructors
+			acceptChild(visitor, getName());
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChild(visitor, this.optionalReceiverType);
+				acceptChild(visitor, this.optionalReceiverQualifier);
+			}
+			acceptChildren(visitor, this.parameters);
+			if (this.ast.apiLevel() >= AST.JLS8) {
+				acceptChildren(visitor, this.extraDimensions);
+				acceptChildren(visitor, this.thrownExceptionTypes);				
+			} else {
+				acceptChildren(visitor, this.thrownExceptions);				
+			}
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns whether this declaration declares a constructor or a method.
+	 *
+	 * @return <code>true</code> if this is a constructor declaration,
+	 *    and <code>false</code> if this is a method declaration
+	 */
+	public boolean isConstructor() {
+		return this.isConstructor;
+	}
+
+	/**
+	 * Sets whether this declaration declares a constructor or a method.
+	 *
+	 * @param isConstructor <code>true</code> for a constructor declaration,
+	 *    and <code>false</code> for a method declaration
+	 */
+	public void setConstructor(boolean isConstructor) {
+		preValueChange(CONSTRUCTOR_PROPERTY);
+		this.isConstructor = isConstructor;
+		postValueChange(CONSTRUCTOR_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type parameters of this method
+	 * declaration (added in JLS3 API). This list is non-empty for parameterized methods.
+	 *
+	 * @return the live list of type parameters
+	 *    (element type: {@link TypeParameter})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeParameters() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeParameters == null) {
+			unsupportedIn2();
+		}
+		return this.typeParameters;
+	}
+
+	/**
+	 * Returns the name of the method declared in this method declaration.
+	 * For a constructor declaration, this should be the same as the name
+	 * of the class.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method declared in this method declaration to the
+	 * given name. For a constructor declaration, this should be the same as
+	 * the name of the class.
+	 *
+	 * @param methodName the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName methodName) {
+		if (methodName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, methodName, NAME_PROPERTY);
+		this.methodName = methodName;
+		postReplaceChild(oldChild, methodName, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the receiver type explicitly declared in the method or constructor 
+	 * declaration (added in JLS8 API).
+	 *
+	 * If the receiver is not explicitly declared in the method or constructor 
+	 * declaration, <code>null</code> is returned.
+	 *
+	 * @return the receiver type or <code>null</code> if receiver is not declared explicitly
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public AnnotatableType getReceiverType() {
+		unsupportedIn2_3_4();
+		return this.optionalReceiverType;
+	}
+
+	/**
+	 * Sets or clears the given type as the type of explicit receiver parameter (added in JLS8 API).
+	 * <p>
+	 * A receiver type is only legal in Java code if it appears on an instance method or on a constructor of an inner class.
+	 * </p>
+	 * 
+	 * @param receiverType type of the explicit receiver parameter, or <code>null</code> if there is none
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void setReceiverType(AnnotatableType receiverType) {
+		unsupportedIn2_3_4();
+		ASTNode oldChild = this.optionalReceiverType;
+		preReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY);
+		this.optionalReceiverType = receiverType;
+		postReplaceChild(oldChild, receiverType, RECEIVER_TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the qualifying name, if any, for the explicit receiver or <code>null</code> if not used (added in JLS8 API).
+	 * <p>
+	 * A receiver qualifier is only legal in Java code if it appears on a constructor of an inner class.
+	 * </p>
+	 * 
+	 * @returns the qualifying name or <code>null</code> if a qualifier was not specified
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public SimpleName getReceiverQualifier() {
+		unsupportedIn2_3_4();
+		return this.optionalReceiverQualifier;
+	}
+	
+	/**
+	 * Sets the given simple name as the qualifier for the receiver (added in JLS8 API).
+	 * 
+	 * @param receiverQualifier explicit receiver parameter to be added to the method declaration
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public void setReceiverQualifier(SimpleName receiverQualifier) {
+		unsupportedIn2_3_4();
+		ASTNode oldChild = this.optionalReceiverQualifier;
+		preReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY);
+		this.optionalReceiverQualifier = receiverQualifier;
+		postReplaceChild(oldChild, receiverQualifier, RECEIVER_QUALIFIER_PROPERTY);
+	}
+	
+	/**
+	 * Returns the live ordered list of method parameter declarations for this
+	 * method declaration.
+	 *
+	 * @return the live list of method parameter declarations
+	 *    (element type: {@link SingleVariableDeclaration})
+	 */
+	public List parameters() {
+		return this.parameters;
+	}
+
+	/**
+	 * Returns whether this method declaration declares a
+	 * variable arity method (added in JLS3 API). The convenience method checks
+	 * whether the last parameter is so marked.
+	 *
+	 * @return <code>true</code> if this is a variable arity method declaration,
+	 *    and <code>false</code> otherwise
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @see SingleVariableDeclaration#isVarargs()
+	 * @since 3.1
+	 */
+	public boolean isVarargs() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		if (parameters().isEmpty()) {
+			return false;
+		} else {
+			SingleVariableDeclaration v = (SingleVariableDeclaration) parameters().get(parameters().size() - 1);
+			return v.isVarargs();
+		}
+	}
+
+	/**
+	 * Returns the live ordered list of thrown exception names in this method
+	 * declaration (below JLS8 API only).
+	 *
+	 * @return the live list of exception names
+	 *    (element type: {@link Name})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 *    a JLS8 or later AST
+	 * @deprecated In the JLS8 API, this method is replaced by {@link #thrownExceptionTypes()}.
+	 */
+	public List thrownExceptions() {
+		return internalThrownExceptions();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @exception UnsupportedOperationException if this operation is used in
+	 *    a JLS8 or later AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	/*package*/	List internalThrownExceptions() {
+		// more efficient than just calling supportedOnlyIn2_3_4() to check
+		if (this.thrownExceptions == null) {
+			supportedOnlyIn2_3_4();
+		}
+		return this.thrownExceptions;
+	}
+
+	/**
+	 * Returns the live ordered list of thrown exception types in this method
+	 * declaration.
+	 *
+	 * @return the live list of exception types
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2, JLS3 or JLS4 AST    
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public List thrownExceptionTypes()  {
+		if (this.thrownExceptionTypes == null) {
+			unsupportedIn2_3_4();
+		}
+		return this.thrownExceptionTypes;
+	}
+
+	/**
+	 * Returns the return type of the method declared in this method
+	 * declaration, exclusive of any extra array dimensions (JLS2 API only).
+	 * This is one of the few places where the void type is meaningful.
+	 * <p>
+	 * Note that this child is not relevant for constructor declarations
+	 * (although, it does still figure in subtree equality comparisons
+	 * and visits), and is devoid of the binding information ordinarily
+	 * available.
+	 * </p>
+	 *
+	 * @return the return type, possibly the void primitive type
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by {@link #getReturnType2()},
+	 * which may return <code>null</code>.
+	 */
+	public Type getReturnType() {
+		return internalGetReturnType();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @since 3.1
+	 */
+	/*package*/ final Type internalGetReturnType() {
+		supportedOnlyIn2();
+		if (this.returnType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.returnType == null) {
+					preLazyInit();
+					this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
+					postLazyInit(this.returnType, RETURN_TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.returnType;
+	}
+
+	/**
+	 * Sets the return type of the method declared in this method declaration
+	 * to the given type, exclusive of any extra array dimensions (JLS2 API only). This is one
+	 * of the few places where the void type is meaningful.
+	 * <p>
+	 * Note that this child is not relevant for constructor declarations
+	 * (although it does still figure in subtree equality comparisons and visits).
+	 * </p>
+	 *
+	 * @param type the new return type, possibly the void primitive type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #setReturnType2(Type)}, which accepts <code>null</code>.
+	 */
+	public void setReturnType(Type type) {
+		internalSetReturnType(type);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ void internalSetReturnType(Type type) {
+	    supportedOnlyIn2();
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.returnType;
+		preReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY);
+		this.returnType = type;
+		postReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the return type of the method declared in this method
+	 * declaration, exclusive of any extra array dimensions (added in JLS3 API).
+	 * This is one of the few places where the void type is meaningful.
+	 * <p>
+	 * Note that this child is not relevant for constructor declarations
+	 * (although, if present, it does still figure in subtree equality comparisons
+	 * and visits), and is devoid of the binding information ordinarily
+	 * available. In the JLS2 API, the return type is mandatory.
+	 * In the JLS3 API, the return type is optional.
+	 * </p>
+	 *
+	 * @return the return type, possibly the void primitive type,
+	 * or <code>null</code> if none
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public Type getReturnType2() {
+	    unsupportedIn2();
+		if (this.returnType == null && !this.returnType2Initialized) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.returnType == null && !this.returnType2Initialized) {
+					preLazyInit();
+					this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
+					this.returnType2Initialized = true;
+					postLazyInit(this.returnType, RETURN_TYPE2_PROPERTY);
+				}
+			}
+		}
+		return this.returnType;
+	}
+
+	/**
+	 * Sets the return type of the method declared in this method declaration
+	 * to the given type, exclusive of any extra array dimensions (added in JLS3 API).
+	 * This is one of the few places where the void type is meaningful.
+	 * <p>
+	 * Note that this child is not relevant for constructor declarations
+	 * (although it does still figure in subtree equality comparisons and visits).
+	 * In the JLS2 API, the return type is mandatory.
+	 * In the JLS3 API, the return type is optional.
+	 * </p>
+	 *
+	 * @param type the new return type, possibly the void primitive type,
+	 * or <code>null</code> if none
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @since 3.1
+	 */
+	public void setReturnType2(Type type) {
+	    unsupportedIn2();
+		this.returnType2Initialized = true;
+		ASTNode oldChild = this.returnType;
+		preReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY);
+		this.returnType = type;
+		postReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY);
+	}
+
+	/**
+	 * Returns the number of extra array dimensions over and above the
+	 * explicitly-specified return type.
+	 * <p>
+	 * For example, <code>int foo()[][]</code> has a return type of
+	 * <code>int</code> and two extra array dimensions;
+	 * <code>int[][] foo()</code> has a return type of <code>int[][]</code>
+	 * and zero extra array dimensions. The two constructs have different
+	 * ASTs, even though there are really syntactic variants of the same
+	 * method declaration.
+	 * </p>
+	 * <p>
+	 * In the JLS8 API, this method is a convenience method that
+	 * counts {@link #extraDimensions()}.
+	 * </p>
+	 *
+	 * @return the number of extra array dimensions
+	 * @since 2.1
+	 */
+	public int getExtraDimensions() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.extraDimensions == null) {
+			// JLS2,3,4 behavior - bona fide property
+			return this.extraArrayDimensions;
+		} else {
+			return this.extraDimensions.size();
+		}
+	}
+
+	/**
+	 * Sets the number of extra array dimensions over and above the
+	 * explicitly-specified return type.
+	 * <p>
+	 * For example, <code>int foo()[][]</code> is rendered as a return
+	 * type of <code>int</code> with two extra array dimensions;
+	 * <code>int[][] foo()</code> is rendered as a return type of
+	 * <code>int[][]</code> with zero extra array dimensions. The two
+	 * constructs have different ASTs, even though there are really syntactic
+	 * variants of the same method declaration.
+	 * </p>
+	 *
+	 * @param dimensions the number of array dimensions
+	 * @exception IllegalArgumentException if the number of dimensions is
+	 *    negative
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS8 or later AST 
+	 * @since 2.1
+	 * @deprecated In the JLS8 API, this method is replaced by
+	 * {@link #extraDimensions()} which contains a list of {@link ExtraDimension} nodes.
+	 */
+	public void setExtraDimensions(int dimensions) {
+		// more efficient than just calling supportedOnlyIn2_3_4() to check
+		if (this.extraDimensions != null) {
+			supportedOnlyIn2_3_4();
+		}
+		if (dimensions < 0) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(EXTRA_DIMENSIONS_PROPERTY);
+		this.extraArrayDimensions = dimensions;
+		postValueChange(EXTRA_DIMENSIONS_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of extra dimensions with optional annotations (added in JLS8 API).
+	 * 
+	 * @return the live list of extra dimensions with optional annotations (element type: {@link ExtraDimension})
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public List extraDimensions() {
+		// more efficient than just calling unsupportedIn2_3_4() to check
+		if (this.extraDimensions == null) {
+			unsupportedIn2_3_4();
+		}
+		return this.extraDimensions;
+	}
+
+	/**
+	 * Returns the body of this method declaration, or <code>null</code> if
+	 * this method has <b>no</b> body.
+	 * <p>
+	 * Note that there is a subtle difference between having no body and having
+	 * an empty body ("{}").
+	 * </p>
+	 *
+	 * @return the method body, or <code>null</code> if this method has no
+	 *    body
+	 */
+	public Block getBody() {
+		return this.optionalBody;
+	}
+
+	/**
+	 * Sets or clears the body of this method declaration.
+	 * <p>
+	 * Note that there is a subtle difference between having no body
+	 * (as in <code>"void foo();"</code>) and having an empty body (as in
+	 * "void foo() {}"). Abstract methods, and methods declared in interfaces,
+	 * have no body. Non-abstract methods, and all constructors, have a body.
+	 * </p>
+	 *
+	 * @param body the block node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Block body) {
+		// a MethodDeclaration may occur in a Block - must check cycles
+		ASTNode oldChild = this.optionalBody;
+		preReplaceChild(oldChild, body, BODY_PROPERTY);
+		this.optionalBody = body;
+		postReplaceChild(oldChild, body, BODY_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the method or constructor declared
+	 * in this method or constructor declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IMethodBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveMethod(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 13 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.typeParameters == null ? 0 : this.typeParameters.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize())
+			+ (this.optionalReceiverType == null ? 0 : this.optionalReceiverType.treeSize())
+			+ (this.optionalReceiverQualifier == null ? 0 : this.optionalReceiverQualifier.treeSize())
+			+ (this.returnType == null ? 0 : this.returnType.treeSize())
+			+ this.parameters.listSize()
+			+ (this.ast.apiLevel < AST.JLS8
+					? this.thrownExceptions.listSize()
+					: this.extraDimensions.listSize() + this.thrownExceptionTypes.listSize())
+			+ (this.optionalBody == null ? 0 : getBody().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java
new file mode 100644
index 0000000..7e6336f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java
@@ -0,0 +1,392 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Method invocation expression AST node type.
+ * <pre>
+ * MethodInvocation:
+ *     [ Expression <b>.</b> ]
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         Identifier <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MethodInvocation extends Expression {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(MethodInvocation.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MethodInvocation.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodInvocation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(MethodInvocation.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(5);
+		createPropertyList(MethodInvocation.class, properyList);
+		addProperty(EXPRESSION_PROPERTY, properyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(ARGUMENTS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalExpression = null;
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeArguments = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to a unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for a method invocation expression owned by the
+	 * given AST. By default, no expression, no type arguments,
+	 * an unspecified, but legal, method name, and an empty list of arguments.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MethodInvocation(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return METHOD_INVOCATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MethodInvocation result = new MethodInvocation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) getName().clone(target));
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		}
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.typeArguments);
+			}
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.arguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this method invocation expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getExpression() {
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Returns <code>true</code> if the resolved return type has been inferred
+	 * from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise.
+	 * <p>
+	 * This information is available only when bindings are requested when the AST is being built
+	 * </p>.
+	 *
+	 * @return <code>true</code> if the resolved return type has been inferred
+	 * 	from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise
+	 * @since 3.3
+	 */
+	public boolean isResolvedTypeInferredFromExpectedType() {
+		return this.ast.getBindingResolver().isResolvedTypeInferredFromExpectedType(this);
+	}
+
+	/**
+	 * Sets or clears the expression of this method invocation expression.
+	 *
+	 * @param expression the expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this method
+	 * invocation (added in JLS3 API).
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeArguments() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeArguments == null) {
+			unsupportedIn2();
+		}
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the name of the method invoked in this expression.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method invoked in this expression to the
+	 * given name.
+	 *
+	 * @param name the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this method
+	 * invocation expression.
+	 *
+	 * @return the live list of argument expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Resolves and returns the binding for the method invoked by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the method binding, or <code>null</code> if the binding cannot
+	 * be resolved
+	 * @since 2.1
+	 */
+	public IMethodBinding resolveMethodBinding() {
+		return this.ast.getBindingResolver().resolveMethod(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalExpression == null ? 0 : getExpression().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize())
+			+ (this.arguments == null ? 0 : this.arguments.listSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java
new file mode 100644
index 0000000..56f70fe
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AST node for a method or constructor reference within a doc comment
+ * ({@link Javadoc}). The principal uses of these are in "@see" and "@link"
+ * tag elements, for references to method and constructor members.
+ * <pre>
+ * MethodRef:
+ *     [ Name ] <b>#</b> Identifier
+ *         <b>(</b> [ MethodRefParameter | { <b>,</b> MethodRefParameter } ] <b>)</b>
+ * </pre>
+ *
+ * @see Javadoc
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MethodRef extends ASTNode implements IDocElement {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(MethodRef.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MethodRef.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "parameters" structural property of this node type (element type: {@link MethodRefParameter}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY =
+		new ChildListPropertyDescriptor(MethodRef.class, "parameters", MethodRefParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List properyList = new ArrayList(4);
+		createPropertyList(MethodRef.class, properyList);
+		addProperty(QUALIFIER_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		addProperty(PARAMETERS_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to a unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * The parameter declarations
+	 * (element type: {@link MethodRefParameter}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList parameters =
+		new ASTNode.NodeList(PARAMETERS_PROPERTY);
+
+
+	/**
+	 * Creates a new AST node for a method reference owned by the given
+	 * AST. By default, the method reference is for a method with an
+	 * unspecified, but legal, name; no qualifier; and an empty parameter
+	 * list.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MethodRef(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == PARAMETERS_PROPERTY) {
+			return parameters();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return METHOD_REF;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MethodRef result = new MethodRef(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
+		result.parameters().addAll(
+			ASTNode.copySubtrees(target, parameters()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.parameters);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this method reference, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Sets or clears the qualifier of this method reference.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name of the referenced method or constructor.
+	 *
+	 * @return the method or constructor name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the referenced method or constructor to the
+	 * given name.
+	 *
+	 * @param name the new method or constructor name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the name is <code>null</code></li>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of method parameter references for this
+	 * method reference.
+	 *
+	 * @return the live list of method parameter references
+	 *    (element type: {@link MethodRefParameter})
+	 */
+	public List parameters() {
+		return this.parameters;
+	}
+
+	/**
+	 * Resolves and returns the binding for the entity referred to by
+	 * this method reference.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public final IBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveReference(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.methodName == null ? 0 : getName().treeSize())
+			+ this.parameters.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java
new file mode 100644
index 0000000..07e52ac
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AST node for a parameter within a method reference ({@link MethodRef}).
+ * These nodes only occur within doc comments ({@link Javadoc}).
+ * <pre>
+ * MethodRefParameter:
+ * 		Type [ <b>...</b> ] [ Identifier ]
+ * </pre>
+ * <p>
+ * Note: The 1.5 spec for the Javadoc tool does not mention the possibility
+ * of a variable arity indicator in method references. However, the 1.5
+ * Javadoc tool itself does indeed support it. Since it makes sense to have
+ * a way to explicitly refer to variable arity methods, it seems more likely
+ * that the Javadoc spec is wrong in this case.
+ * </p>
+ *
+ * @see Javadoc
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class MethodRefParameter extends ASTNode {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(MethodRefParameter.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "varargs" structural property of this node type (type: {@link Boolean}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final SimplePropertyDescriptor VARARGS_PROPERTY =
+		new SimplePropertyDescriptor(MethodRefParameter.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(MethodRefParameter.class, "name", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List properyList = new ArrayList(3);
+		createPropertyList(MethodRefParameter.class, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+
+		properyList = new ArrayList(3);
+		createPropertyList(MethodRefParameter.class, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(VARARGS_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The type; lazily initialized; defaults to a unspecified,
+	 * legal type.
+	 */
+	private Type type = null;
+
+	/**
+	 * Indicates the last parameter of a variable arity method;
+	 * defaults to false.
+	 *
+	 * @since 3.1
+	 */
+	private boolean variableArity = false;
+
+	/**
+	 * The parameter name, or <code>null</code> if none; none by
+	 * default.
+	 */
+	private SimpleName optionalParameterName = null;
+
+	/**
+	 * Creates a new AST node for a method referenece parameter owned by the given
+	 * AST. By default, the node has an unspecified (but legal) type,
+	 * not variable arity, and no parameter name.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MethodRefParameter(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == VARARGS_PROPERTY) {
+			if (get) {
+				return isVarargs();
+			} else {
+				setVarargs(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return METHOD_REF_PARAMETER;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		MethodRefParameter result = new MethodRefParameter(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) ASTNode.copySubtree(target, getType()));
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.setVarargs(isVarargs());
+		}
+		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the paramter type.
+	 *
+	 * @return the parameter type
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the paramter type to the given type.
+	 *
+	 * @param type the new type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the type is <code>null</code></li>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this method reference parameter is for
+	 * the last parameter of a variable arity method (added in JLS3 API).
+	 * <p>
+	 * Note that the binding for the type <code>Foo</code>in the vararg method
+	 * reference <code>#fun(Foo...)</code> is always for the type as
+	 * written; i.e., the type binding for <code>Foo</code>. However, if you
+	 * navigate from the MethodRef to its method binding to the
+	 * type binding for its last parameter, the type binding for the vararg
+	 * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+	 * the way vararg methods get compiled.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is a variable arity parameter,
+	 *    and <code>false</code> otherwise
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public boolean isVarargs() {
+		unsupportedIn2();
+		return this.variableArity;
+	}
+
+	/**
+	 * Sets whether this method reference parameter is for the last parameter of
+	 * a variable arity method (added in JLS3 API).
+	 *
+	 * @param variableArity <code>true</code> if this is a variable arity
+	 *    parameter, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public void setVarargs(boolean variableArity) {
+		unsupportedIn2();
+		preValueChange(VARARGS_PROPERTY);
+		this.variableArity = variableArity;
+		postValueChange(VARARGS_PROPERTY);
+	}
+
+	/**
+	 * Returns the parameter name, or <code>null</code> if there is none.
+	 *
+	 * @return the parameter name node, or <code>null</code> if there is none
+	 */
+	public SimpleName getName() {
+		return this.optionalParameterName;
+	}
+
+	/**
+	 * Sets or clears the parameter name.
+	 *
+	 * @param name the parameter name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		ASTNode oldChild = this.optionalParameterName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.optionalParameterName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 2 * 5;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ (this.optionalParameterName == null ? 0 : getName().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java
new file mode 100644
index 0000000..b7cfe30
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodReference.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+
+/**
+ * Abstract base class of all AST node types that represent a method reference
+ * expression (added in JLS8 API).
+ * 
+ * <pre>
+ * MethodReference:
+ *    CreationReference
+ *    ExpressionMethodReference
+ *    SuperMethodReference
+ *    TypeMethodReference
+ * </pre>
+ * <p>
+ * A method reference that is represented by a simple or qualified name,
+ * followed by <code>::</code>, followed by a simple name can be represented
+ * as {@link ExpressionMethodReference} or as {@link TypeMethodReference}. 
+ * The ASTParser currently prefers the first form.
+ * </p>
+ *
+ * @see CreationReference
+ * @see ExpressionMethodReference
+ * @see SuperMethodReference
+ * @see TypeMethodReference
+ * @since 3.9 BETA_JAVA8
+ */
+public abstract class MethodReference extends Expression {
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Defaults to an empty list (see constructor).
+	 */
+	ASTNode.NodeList typeArguments;
+
+	/**
+	 * Creates and returns a structural property descriptor for the "typeArguments" 
+	 * property declared on the given concrete node type (element type: {@link Type}).
+	 * 
+	 * @return the property descriptor
+	 */
+	static final ChildListPropertyDescriptor internalTypeArgumentsFactory(Class nodeClass) {
+		return new ChildListPropertyDescriptor(nodeClass, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the structural property descriptor for the "typeArguments" property
+	 * of this node (element type: {@link Type}).
+	 *
+	 * @return the property descriptor
+	 */
+	abstract ChildListPropertyDescriptor internalTypeArgumentsProperty();
+
+	/**
+	 * Returns the structural property descriptor for the "typeArguments" property
+	 * of this node (element type: {@link Type}).
+	 *
+	 * @return the property descriptor
+	 */
+	public final ChildListPropertyDescriptor getTypeArgumentsProperty() {
+		return internalTypeArgumentsProperty();
+	}
+
+	/**
+	 * Creates a new AST node for a method reference owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	MethodReference(AST ast) {
+		super(ast);
+		this.typeArguments = new ASTNode.NodeList(getTypeArgumentsProperty());
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this method reference.
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/**
+	 * Resolves and returns the binding for the method referenced by this
+	 * method reference expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the method binding, or <code>null</code> if the binding cannot
+	 * be resolved
+	 */
+	public IMethodBinding resolveMethodBinding() {
+		return this.ast.getBindingResolver().resolveMethod(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java
new file mode 100644
index 0000000..e59ca8b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java
@@ -0,0 +1,758 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Modifier node.
+ * <pre>
+ * Modifier:
+ *    <b>public</b>
+ *    <b>protected</b>
+ *    <b>private</b>
+ *    <b>static</b>
+ *    <b>abstract</b>
+ *    <b>final</b>
+ *    <b>native</b>
+ *    <b>synchronized</b>
+ *    <b>transient</b>
+ *    <b>volatile</b>
+ *    <b>strictfp</b>
+ *    <b>default</b>
+ * </pre>
+ * <p>
+ * The numeric values of these flags match the ones for class
+ * files as described in the Java Virtual Machine Specification
+ * (except for {@link #DEFAULT}). Note that the Java model class
+ * {@link org.eclipse.jdt.core.Flags} also provides the same
+ * constants as this class.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Modifier extends ASTNode implements IExtendedModifier {
+
+	/**
+ 	 * Modifier keywords (typesafe enumeration).
+ 	 * @since 3.0
+	 */
+	public static class ModifierKeyword {
+
+		/** "abstract" modifier with flag value {@link Modifier#ABSTRACT}. */
+		public static final ModifierKeyword ABSTRACT_KEYWORD = new ModifierKeyword("abstract", ABSTRACT);//$NON-NLS-1$
+
+		/** "final" modifier with flag value {@link Modifier#FINAL}. */
+		public static final ModifierKeyword FINAL_KEYWORD = new ModifierKeyword("final", FINAL);//$NON-NLS-1$
+
+		/**
+		 * Map from token to operator (key type: <code>String</code>;
+		 * value type: <code>Operator</code>).
+		 */
+		private static final Map KEYWORDS;
+
+		/** "native" modifier with flag value {@link Modifier#NATIVE}. */
+		public static final ModifierKeyword NATIVE_KEYWORD = new ModifierKeyword("native", NATIVE);//$NON-NLS-1$
+
+		/** "private" modifier with flag value {@link Modifier#PRIVATE}. */
+		public static final ModifierKeyword PRIVATE_KEYWORD = new ModifierKeyword("private", PRIVATE);//$NON-NLS-1$
+
+		/** "protected" modifier with flag value {@link Modifier#PROTECTED}. */
+		public static final ModifierKeyword PROTECTED_KEYWORD = new ModifierKeyword("protected", PROTECTED);//$NON-NLS-1$
+
+		/** "public" modifier with flag value {@link Modifier#PUBLIC}. */
+		public static final ModifierKeyword PUBLIC_KEYWORD = new ModifierKeyword("public", PUBLIC);//$NON-NLS-1$
+
+		/** "static" modifier with flag value {@link Modifier#STATIC}. */
+		public static final ModifierKeyword STATIC_KEYWORD = new ModifierKeyword("static", STATIC);//$NON-NLS-1$
+
+		/** "strictfp" modifier with flag value {@link Modifier#STRICTFP}. */
+		public static final ModifierKeyword STRICTFP_KEYWORD = new ModifierKeyword("strictfp", STRICTFP);//$NON-NLS-1$
+
+		/** "synchronized" modifier with flag value {@link Modifier#SYNCHRONIZED}. */
+		public static final ModifierKeyword SYNCHRONIZED_KEYWORD = new ModifierKeyword("synchronized", SYNCHRONIZED);//$NON-NLS-1$
+
+		/** "transient" modifier with flag value {@link Modifier#TRANSIENT}. */
+		public static final ModifierKeyword TRANSIENT_KEYWORD = new ModifierKeyword("transient", TRANSIENT);//$NON-NLS-1$
+
+		/** "volatile" modifier with flag value {@link Modifier#VOLATILE}. */
+		public static final ModifierKeyword VOLATILE_KEYWORD = new ModifierKeyword("volatile", VOLATILE);//$NON-NLS-1$
+
+		/**
+		 * "default" modifier with flag value {@link Modifier#DEFAULT} (added in JLS8 API).
+		 * <p>
+		 * Note that the value of this modifier is
+		 * internal and is not specified in the Java Virtual Machine Specification.
+		 * </p>
+		 * @since 3.9 BETA_JAVA8
+		 */
+		public static final ModifierKeyword DEFAULT_KEYWORD = new ModifierKeyword("default", DEFAULT);//$NON-NLS-1$
+
+		static {
+			KEYWORDS = new HashMap(20);
+			ModifierKeyword[] ops = {
+					PUBLIC_KEYWORD,
+					PROTECTED_KEYWORD,
+					PRIVATE_KEYWORD,
+					STATIC_KEYWORD,
+					ABSTRACT_KEYWORD,
+					FINAL_KEYWORD,
+					NATIVE_KEYWORD,
+					SYNCHRONIZED_KEYWORD,
+					TRANSIENT_KEYWORD,
+					VOLATILE_KEYWORD,
+					STRICTFP_KEYWORD,
+					DEFAULT_KEYWORD
+				};
+			for (int i = 0; i < ops.length; i++) {
+				KEYWORDS.put(ops[i].toString(), ops[i]);
+			}
+		}
+
+		/**
+		 * Returns the modifier corresponding to the given single-bit flag value,
+		 * or <code>null</code> if none or if more than one bit is set.
+		 * <p>
+		 * <code>fromFlagValue</code> is the converse of <code>toFlagValue</code>:
+		 * that is, <code>ModifierKind.fromFlagValue(k.toFlagValue()) == k</code> for
+		 * all modifier keywords <code>k</code>.
+		 * </p>
+		 *
+		 * @param flagValue the single-bit flag value for the modifier
+		 * @return the modifier keyword, or <code>null</code> if none
+		 * @see #toFlagValue()
+		 */
+		public static ModifierKeyword fromFlagValue(int flagValue) {
+			for (Iterator it = KEYWORDS.values().iterator(); it.hasNext(); ) {
+				ModifierKeyword k = (ModifierKeyword) it.next();
+				if (k.toFlagValue() == flagValue) {
+					return k;
+				}
+			}
+			return null;
+		}
+
+		/**
+		 * Returns the modifier corresponding to the given string,
+		 * or <code>null</code> if none.
+		 * <p>
+		 * <code>toKeyword</code> is the converse of <code>toString</code>:
+		 * that is, <code>ModifierKind.toKeyword(k.toString()) == k</code> for
+		 * all modifier keywords <code>k</code>.
+		 * </p>
+		 *
+		 * @param keyword the lowercase string name for the modifier
+		 * @return the modifier keyword, or <code>null</code> if none
+		 * @see #toString()
+		 */
+		public static ModifierKeyword toKeyword(String keyword) {
+			return (ModifierKeyword) KEYWORDS.get(keyword);
+		}
+
+		/**
+		 * The flag value for the modifier.
+		 */
+		private int flagValue;
+
+		/**
+		 * The keyword modifier string.
+		 */
+		private String keyword;
+
+		/**
+		 * Creates a new modifier with the given keyword.
+		 * <p>
+		 * Note: this constructor is private. The only instances
+		 * ever created are the ones for the standard modifiers.
+		 * </p>
+		 *
+		 * @param keyword the character sequence for the modifier
+		 * @param flagValue flag value as described in the Java Virtual Machine Specification
+		 */
+		private ModifierKeyword(String keyword, int flagValue) {
+			this.keyword = keyword;
+			this.flagValue = flagValue;
+		}
+
+		/**
+		 * Returns the modifier flag value corresponding to this modifier keyword.
+		 * These flag values are as described in the Java Virtual Machine Specification.
+		 *
+		 * @return one of the <code>Modifier</code> constants
+		 * @see #fromFlagValue(int)
+		 */
+		public int toFlagValue() {
+			return this.flagValue;
+		}
+
+		/**
+		 * Returns the keyword for the modifier.
+		 *
+		 * @return the keyword for the modifier
+		 * @see #toKeyword(String)
+		 */
+		public String toString() {
+			return this.keyword;
+		}
+	}
+
+	/**
+	 * "abstract" modifier constant (bit mask).
+	 * Applicable to types and methods.
+	 * @since 2.0
+	 */
+	public static final int ABSTRACT = 0x0400;
+
+	/**
+	 * "final" modifier constant (bit mask).
+	 * Applicable to types, methods, fields, and variables.
+	 * @since 2.0
+	 */
+	public static final int FINAL = 0x0010;
+
+	/**
+	 * The "keyword" structural property of this node type (type: {@link Modifier.ModifierKeyword}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor KEYWORD_PROPERTY =
+		new SimplePropertyDescriptor(Modifier.class, "keyword", Modifier.ModifierKeyword.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * "native" modifier constant (bit mask).
+	 * Applicable only to methods.
+	 * @since 2.0
+	 */
+	public static final int NATIVE = 0x0100;
+
+	/**
+	 * Modifier constant (bit mask, value 0) indicating no modifiers.
+	 * @since 2.0
+	 */
+	public static final int NONE = 0x0000;
+
+	/**
+	 * "private" modifier constant (bit mask).
+	 * Applicable to types, methods, constructors, and fields.
+	 * @since 2.0
+	 */
+	public static final int PRIVATE = 0x0002;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	/**
+	 * "protected" modifier constant (bit mask).
+	 * Applicable to types, methods, constructors, and fields.
+	 * @since 2.0
+	 */
+	public static final int PROTECTED = 0x0004;
+
+	/**
+	 * "public" modifier constant (bit mask).
+	 * Applicable to types, methods, constructors, and fields.
+	 * @since 2.0
+	 */
+	public static final int PUBLIC = 0x0001;
+
+	/**
+	 * "static" modifier constant (bit mask).
+	 * Applicable to types, methods, fields, and initializers.
+	 * @since 2.0
+	 */
+	public static final int STATIC = 0x0008;
+
+	/**
+	 * "strictfp" modifier constant (bit mask).
+	 * Applicable to types and methods.
+	 * @since 2.0
+	 */
+	public static final int STRICTFP = 0x0800;
+
+	/**
+	 * "synchronized" modifier constant (bit mask).
+	 * Applicable only to methods.
+	 * @since 2.0
+	 */
+	public static final int SYNCHRONIZED = 0x0020;
+
+	/**
+	 * "transient" modifier constant (bit mask).
+	 * Applicable only to fields.
+	 * @since 2.0
+	 */
+	public static final int TRANSIENT = 0x0080;
+
+	/**
+	 * "volatile" modifier constant (bit mask).
+	 * Applicable only to fields.
+	 * @since 2.0
+	 */
+	public static final int VOLATILE = 0x0040;
+
+	/**
+	 * "default" modifier constant (bit mask) (added in JLS8 API).
+	 * Applicable only to methods in interfaces (but not for annotation methods with a default value).
+	 * <p>
+	 * Note that the value of this flag is internal and is not
+	 * specified in the Java Virtual Machine Specification.
+	 * </p>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int DEFAULT = 0x10000;
+
+	static {
+		List properyList = new ArrayList(2);
+		createPropertyList(Modifier.class, properyList);
+		addProperty(KEYWORD_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+	}
+
+	/**
+	 * Returns whether the given flags includes the "abstract" modifier.
+	 * Applicable to types and methods.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>ABSTRACT</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isAbstract(int flags) {
+		return (flags & ABSTRACT) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "final" modifier.
+	 * Applicable to types, methods, fields, and variables.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>FINAL</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isFinal(int flags) {
+		return (flags & FINAL) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "native" modifier.
+	 * Applicable only to methods.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>NATIVE</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isNative(int flags) {
+		return (flags & NATIVE) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "private" modifier.
+	 * Applicable to types, methods, constructors, and fields.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>PRIVATE</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isPrivate(int flags) {
+		return (flags & PRIVATE) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "protected" modifier.
+	 * Applicable to types, methods, constructors, and fields.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>PROTECTED</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isProtected(int flags) {
+		return (flags & PROTECTED) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "public" modifier.
+	 * Applicable to types, methods, constructors, and fields.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>PUBLIC</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isPublic(int flags) {
+		return (flags & PUBLIC) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "static" modifier.
+	 * Applicable to types, methods, fields, and initializers.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>STATIC</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isStatic(int flags) {
+		return (flags & STATIC) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "strictfp" modifier.
+	 * Applicable to types and methods.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>STRICTFP</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isStrictfp(int flags) {
+		return (flags & STRICTFP) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "synchronized" modifier.
+	 * Applicable only to methods.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>SYNCHRONIZED</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isSynchronized(int flags) {
+		return (flags & SYNCHRONIZED) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "transient" modifier.
+	 * Applicable only to fields.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>TRANSIENT</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isTransient(int flags) {
+		return (flags & TRANSIENT) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "volatile" modifier.
+	 * Applicable only to fields.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>VOLATILE</code> bit is
+	 *   set, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	public static boolean isVolatile(int flags) {
+		return (flags & VOLATILE) != 0;
+	}
+
+	/**
+	 * Returns whether the given flags includes the "default" modifier.
+	 * Applicable only to methods.
+	 *
+	 * @param flags the modifier flags
+	 * @return <code>true</code> if the <code>DEFAULT</code> bit is set
+	 * and <code>false</code> otherwise
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static boolean isDefault(int flags) {
+		return (flags & DEFAULT) != 0;
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The modifier keyword; defaults to an unspecified modifier.
+	 * @since 3.0
+	 */
+	private ModifierKeyword modifierKeyword = ModifierKeyword.PUBLIC_KEYWORD;
+
+	/**
+	 * Creates a new unparented modifier node owned by the given AST.
+	 * By default, the node has unspecified (but legal) modifier.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 * @since 3.0
+	 */
+	Modifier(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	ASTNode clone0(AST target) {
+		Modifier result = new Modifier(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setKeyword(getKeyword());
+		return result;
+	}
+
+	/**
+	 * Returns the modifier keyword of this modifier node.
+	 *
+	 * @return the modifier keyword
+	 * @since 3.0
+	 */
+	public ModifierKeyword getKeyword() {
+		return this.modifierKeyword;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final int getNodeType0() {
+		return MODIFIER;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == KEYWORD_PROPERTY) {
+			if (get) {
+				return getKeyword();
+			} else {
+				setKeyword((ModifierKeyword) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/**
+	 * Answer true if the receiver is the abstract modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the abstract modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isAbstract() {
+		return this.modifierKeyword == ModifierKeyword.ABSTRACT_KEYWORD;
+	}
+
+	/**
+	 * @see IExtendedModifier#isAnnotation()
+	 */
+	public boolean isAnnotation() {
+		return false;
+	}
+
+	/**
+	 * Answer true if the receiver is the final modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the final modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isFinal() {
+		return this.modifierKeyword == ModifierKeyword.FINAL_KEYWORD;
+	}
+
+	/**
+	 * @see IExtendedModifier#isModifier()
+	 */
+	public boolean isModifier() {
+		return true;
+	}
+
+	/**
+	 * Answer true if the receiver is the native modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the native modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isNative() {
+		return this.modifierKeyword == ModifierKeyword.NATIVE_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the private modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the private modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isPrivate() {
+		return this.modifierKeyword == ModifierKeyword.PRIVATE_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the protected modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the protected modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isProtected() {
+		return this.modifierKeyword == ModifierKeyword.PROTECTED_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the public modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the public modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isPublic() {
+		return this.modifierKeyword == ModifierKeyword.PUBLIC_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the static modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the static modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isStatic() {
+		return this.modifierKeyword == ModifierKeyword.STATIC_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the strictfp modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the strictfp modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isStrictfp() {
+		return this.modifierKeyword == ModifierKeyword.STRICTFP_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the synchronized modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the synchronized modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isSynchronized() {
+		return this.modifierKeyword == ModifierKeyword.SYNCHRONIZED_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the transient modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the transient modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isTransient() {
+		return this.modifierKeyword == ModifierKeyword.TRANSIENT_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the volatile modifier, false otherwise.
+	 *
+	 * @return true if the receiver is the volatile modifier, false otherwise
+	 * @since 3.2
+	 */
+	public boolean isVolatile() {
+		return this.modifierKeyword == ModifierKeyword.VOLATILE_KEYWORD;
+	}
+
+	/**
+	 * Answer true if the receiver is the default modifier, false otherwise.
+	 * @return true if the receiver is the default modifier, false otherwise
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean isDefault() {
+		return this.modifierKeyword == ModifierKeyword.DEFAULT_KEYWORD;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	int memSize() {
+		// treat ModifierKeyword as free
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/**
+	 * Sets the modifier keyword of this modifier node.
+	 *
+	 * @param modifierKeyord the modifier keyword
+	 * @exception IllegalArgumentException if the argument is <code>null</code>
+	 * @since 3.0
+	 */
+	public void setKeyword(ModifierKeyword modifierKeyord) {
+		if (modifierKeyord == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(KEYWORD_PROPERTY);
+		this.modifierKeyword = modifierKeyord;
+		postValueChange(KEYWORD_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java
new file mode 100644
index 0000000..65430ed
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Abstract base class for all AST nodes that represent names.
+ * There are exactly two kinds of name: simple ones
+ * (<code>SimpleName</code>) and qualified ones (<code>QualifiedName</code>).
+ * <p>
+ * <pre>
+ * Name:
+ *     SimpleName
+ *     QualifiedName
+ * </pre>
+ * </p>
+ *
+ * @since 2.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class Name extends Expression implements IDocElement {
+
+	/**
+	 * Approximate base size of an expression node instance in bytes,
+	 * including object header and instance fields.
+	 */
+	static final int BASE_NAME_NODE_SIZE = BASE_NODE_SIZE + 1 * 4;
+
+	/**
+	 * This index represents the position inside a qualified name.
+	 */
+	int index;
+
+	/**
+	 * Creates a new AST node for a name owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Name(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * Returns whether this name is a simple name
+	 * (<code>SimpleName</code>).
+	 *
+	 * @return <code>true</code> if this is a simple name, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isSimpleName() {
+		return (this instanceof SimpleName);
+	}
+
+	/**
+	 * Returns whether this name is a qualified name
+	 * (<code>QualifiedName</code>).
+	 *
+	 * @return <code>true</code> if this is a qualified name, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isQualifiedName() {
+		return (this instanceof QualifiedName);
+	}
+
+	/**
+	 * Resolves and returns the binding for the entity referred to by this name.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public final IBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveName(this);
+	}
+
+	/**
+	 * Returns the standard dot-separated representation of this name.
+	 * If the name is a simple name, the result is the name's identifier.
+	 * If the name is a qualified name, the result is the name of the qualifier
+	 * (as computed by this method) followed by "." followed by the name's
+	 * identifier.
+	 *
+	 * @return the fully qualified name
+	 * @since 3.0
+	 */
+	public final String getFullyQualifiedName() {
+		if (isSimpleName()) {
+			// avoid creating garbage for common case
+			return ((SimpleName) this).getIdentifier();
+		} else {
+			StringBuffer buffer = new StringBuffer(50);
+			appendName(buffer);
+			return new String(buffer);
+		}
+	}
+
+	/**
+	 * Appends the standard representation of this name to the given string
+	 * buffer.
+	 *
+	 * @param buffer the buffer
+	 * @since 3.0
+	 */
+	abstract void appendName(StringBuffer buffer);
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
new file mode 100644
index 0000000..f5bc4e8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.INameEnvironmentWithProgress;
+import org.eclipse.jdt.internal.core.NameLookup;
+
+/**
+ * Batch name environment that can be canceled using a monitor.
+ * @since 3.6
+ */
+class NameEnvironmentWithProgress extends FileSystem implements INameEnvironmentWithProgress {
+	IProgressMonitor monitor;
+	
+	public NameEnvironmentWithProgress(Classpath[] paths, String[] initialFileNames, IProgressMonitor monitor) {
+		super(paths, initialFileNames);
+		setMonitor(monitor);
+	}
+	private void checkCanceled() {
+		if (this.monitor != null && this.monitor.isCanceled()) {
+			if (NameLookup.VERBOSE) {
+				System.out.println(Thread.currentThread() + " CANCELLING LOOKUP "); //$NON-NLS-1$
+			}
+			throw new AbortCompilation(true/*silent*/, new OperationCanceledException());
+		}
+	}
+	public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+		checkCanceled();
+		return super.findType(typeName, packageName);
+	}
+	public NameEnvironmentAnswer findType(char[][] compoundName) {
+		checkCanceled();
+		return super.findType(compoundName);
+	}
+	public boolean isPackage(char[][] compoundName, char[] packageName) {
+		checkCanceled();
+		return super.isPackage(compoundName, packageName);
+	}
+	
+	public void setMonitor(IProgressMonitor monitor) {
+		this.monitor = monitor;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java
new file mode 100644
index 0000000..91f9856
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * A node event handler is an internal mechanism for receiving
+ * notification of changes to nodes in an AST.
+ * <p>
+ * The default implementation serves as the default event handler
+ * that does nothing. Internal subclasses do all the real work.
+ * </p>
+ *
+ * @see AST#getEventHandler()
+ */
+class NodeEventHandler {
+
+	/**
+	 * Creates a node event handler.
+	 */
+	NodeEventHandler() {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * Reports that the given node is about to lose a child.
+	 * The first half of an event pair. The default implementation does nothing.
+	 *
+	 * @param node the node about to be modified
+	 * @param child the node about to be removed
+	 * @param property the child or child list property descriptor
+	 * @see #postRemoveChildEvent(ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void preRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("DEL1 " + property);
+	}
+
+	/**
+	 * Reports that the given node has just lose a child.
+	 * The second half of an event pair. The default implementation does nothing.
+	 *
+	 * @param node the node that was modified
+	 * @param child the child that was removed; note that this node is unparented
+	 * @param property the child or child list property descriptor
+	 * @see #preRemoveChildEvent(ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void postRemoveChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("DEL2 " + property);
+	}
+
+	/**
+	 * Reports that the given node is about to have a child replaced.
+	 * The first half of an event pair.
+	 * The default implementation does nothing.
+	 *
+	 * @param node the node about to be modified
+	 * @param child the node about to be replaced
+	 * @param newChild the replacement child; note that this node is unparented
+	 * @param property the child or child list property descriptor
+	 * @see #preReplaceChildEvent(ASTNode, ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void preReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("REP1 " + property);
+	}
+
+	/**
+	 * Reports that the given node has had its child replaced. The second half
+	 * of an event pair. The default implementation does nothing.
+	 *
+	 * @param node the node that was modified
+	 * @param child the node that was replaced; note that this node is unparented
+	 * @param newChild the replacement child
+	 * @param property the child or child list property descriptor
+	 * @see #postReplaceChildEvent(ASTNode, ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void postReplaceChildEvent(ASTNode node, ASTNode child, ASTNode newChild, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("REP2 " + property);
+	}
+
+	/**
+	 * Reports that the given node is about to gain a child.
+	 * The first half of an event pair. The default implementation does nothing.
+	 *
+	 * @param node the node that to be modified
+	 * @param child the node that is to be added as a child; note that this
+	 * node is unparented; in the case of a child list property, the exact
+	 * location of insertion is not supplied (but is known on the
+	 * corresponding <code>postAddChildEvent</code> to
+	 * follow)
+	 * @param property the child or child list property descriptor
+	 * @see #postAddChildEvent(ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void preAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("ADD1 " + property);
+	}
+
+	/**
+	 * Reports that the given node has just gained a child.
+	 * The second half of an event pair. The default implementation does nothing.
+	 *
+	 * @param node the node that was modified
+	 * @param child the node that was added as a child
+	 * @param property the child or child list property descriptor
+	 * @see #preAddChildEvent(ASTNode, ASTNode, StructuralPropertyDescriptor)
+	 * @since 3.0
+	 */
+	void postAddChildEvent(ASTNode node, ASTNode child, StructuralPropertyDescriptor property) {
+		// do nothing
+		// System.out.println("ADD2 " + property);
+	}
+
+	/**
+	 * Reports that the given node is about to change the value of a
+	 * non-child property. The first half of an event pair.
+	 * The default implementation does nothing.
+	 *
+	 * @param node the node to be modified
+	 * @param property the property descriptor
+	 * @see #postValueChangeEvent(ASTNode, SimplePropertyDescriptor)
+	 * @since 3.0
+	 */
+	void preValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		// do nothing
+		// System.out.println("MOD1 " + property);
+	}
+
+	/**
+	 * Reports that the given node has just changed the value of a
+	 * non-child property. The second half of an event pair.
+	 * The default implementation does nothing.
+	 *
+	 * @param node the node that was modified
+	 * @param property the property descriptor
+	 * @see #preValueChangeEvent(ASTNode, SimplePropertyDescriptor)
+	 * @since 3.0
+	 */
+	void postValueChangeEvent(ASTNode node, SimplePropertyDescriptor property) {
+		// do nothing
+		// System.out.println("MOD2 " + property);
+	}
+
+	/**
+	 * Reports that the given node is about to be cloned.
+	 * The first half of an event pair.
+	 * The default implementation does nothing.
+	 *
+	 * @param node the node to be modified
+	 * @see #postCloneNodeEvent(ASTNode, ASTNode)
+	 * @since 3.0
+	 */
+	void preCloneNodeEvent(ASTNode node) {
+		// do nothing
+		// System.out.println("CLONE1");
+	}
+
+	/**
+	 * Reports that the given node has just been cloned.
+	 * The second half of an event pair.
+	 * The default implementation does nothing.
+	 *
+	 * @param node the node that was modified
+	 * @param clone the clone of <code>node</code>
+	 * @see #preCloneNodeEvent(ASTNode)
+	 * @since 3.0
+	 */
+	void postCloneNodeEvent(ASTNode node, ASTNode clone) {
+		// do nothing
+		// System.out.println("CLONE2");
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeFinder.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeFinder.java
new file mode 100644
index 0000000..36cef08
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeFinder.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.compiler.IScanner;
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+
+/**
+ * For a given range, finds the covered node and the covering node.
+ *
+ * @since 3.5
+ */
+public final class NodeFinder {
+	/**
+	 * This class defines the actual visitor that finds the node.
+	 */
+	private static class NodeFinderVisitor extends ASTVisitor {
+		private int fStart;
+		private int fEnd;
+		private ASTNode fCoveringNode;
+		private ASTNode fCoveredNode;
+
+		NodeFinderVisitor(int offset, int length) {
+			super(true); // include Javadoc tags
+			this.fStart= offset;
+			this.fEnd= offset + length;
+		}
+
+		public boolean preVisit2(ASTNode node) {
+			int nodeStart= node.getStartPosition();
+			int nodeEnd= nodeStart + node.getLength();
+			if (nodeEnd < this.fStart || this.fEnd < nodeStart) {
+				return false;
+			}
+			if (nodeStart <= this.fStart && this.fEnd <= nodeEnd) {
+				this.fCoveringNode= node;
+			}
+			if (this.fStart <= nodeStart && nodeEnd <= this.fEnd) {
+				if (this.fCoveringNode == node) { // nodeStart == fStart && nodeEnd == fEnd
+					this.fCoveredNode= node;
+					return true; // look further for node with same length as parent
+				} else if (this.fCoveredNode == null) { // no better found
+					this.fCoveredNode= node;
+				}
+				return false;
+			}
+			return true;
+		}
+		/**
+		 * Returns the covered node. If more than one nodes are covered by the selection, the
+		 * returned node is first covered node found in a top-down traversal of the AST
+		 * @return ASTNode
+		 */
+		public ASTNode getCoveredNode() {
+			return this.fCoveredNode;
+		}
+
+		/**
+		 * Returns the covering node. If more than one nodes are covering the selection, the
+		 * returned node is last covering node found in a top-down traversal of the AST
+		 * @return ASTNode
+		 */
+		public ASTNode getCoveringNode() {
+			return this.fCoveringNode;
+		}
+	}
+	/**
+	 * Maps a selection to a given ASTNode, where the selection is defined using a start and a length.
+	 * The result node is determined as follows:
+	 * <ul>
+	 *   <li>first the visitor tries to find a node with the exact <code>start</code> and <code>length</code></li>
+	 *   <li>if no such node exists then the node that encloses the range defined by
+	 *       <code>start</code> and <code>length</code> is returned.</li>
+	 *   <li>if the length is zero then also nodes are considered where the node's
+	 *       start or end position matches <code>start</code>.</li>
+	 *   <li>otherwise <code>null</code> is returned.</li>
+	 * </ul>
+	 *
+	 * @param root the root node from which the search starts
+	 * @param start the given start
+	 * @param length the given length
+	 *
+	 * @return the found node
+	 */
+	public static ASTNode perform(ASTNode root, int start, int length) {
+		NodeFinder finder = new NodeFinder(root, start, length);
+		ASTNode result= finder.getCoveredNode();
+		if (result == null || result.getStartPosition() != start || result.getLength() != length) {
+			return finder.getCoveringNode();
+		}
+		return result;
+	}
+
+	/**
+	 * Maps a selection to a given ASTNode, where the selection is defined using a source range.
+	 * It calls <code>perform(root, range.getOffset(), range.getLength())</code>.
+	 * 
+	 * @return the result node
+	 * @see #perform(ASTNode, int, int)
+	 */
+	public static ASTNode perform(ASTNode root, ISourceRange range) {
+		return perform(root, range.getOffset(), range.getLength());
+	}
+
+	/**
+	 * Maps a selection to a given ASTNode, where the selection is given by a start and a length.
+	 * The result node is determined as follows:
+	 * <ul>
+	 *   <li>first the visitor tries to find a node that is covered by <code>start</code> and
+	 *       <code>length</code> where either <code>start</code> and <code>length</code> exactly
+	 *       matches the node or where the text covered before and after the node only consists
+	 *       of white spaces or comments.</li>
+	 *   <li>if no such node exists then the node that encloses the range defined by
+	 *       <code>start</code> and <code>length</code> is returned.</li>
+	 *   <li>if the length is zero then also nodes are considered where the node's
+	 *       start or end position matches <code>start</code>.</li>
+	 *   <li>otherwise <code>null</code> is returned.</li>
+	 * </ul>
+	 *
+	 * @param root the root node from which the search starts
+	 * @param start the given start
+	 * @param length the given length
+	 * @param source the source of the compilation unit
+	 *
+	 * @return the result node
+	 * @throws JavaModelException if an error occurs in the Java model
+	 */
+	public static ASTNode perform(ASTNode root, int start, int length, ITypeRoot source) throws JavaModelException {
+		NodeFinder finder = new NodeFinder(root, start, length);
+		ASTNode result= finder.getCoveredNode();
+		if (result == null)
+			return null;
+		int nodeStart= result.getStartPosition();
+		if (start <= nodeStart && ((nodeStart + result.getLength()) <= (start + length))) {
+			IBuffer buffer= source.getBuffer();
+			if (buffer != null) {
+				IScanner scanner= ToolFactory.createScanner(false, false, false, false);
+				try {
+					scanner.setSource(buffer.getText(start, length).toCharArray());
+					int token= scanner.getNextToken();
+					if (token != ITerminalSymbols.TokenNameEOF) {
+						int tStart= scanner.getCurrentTokenStartPosition();
+						if (tStart == result.getStartPosition() - start) {
+							scanner.resetTo(tStart + result.getLength(), length - 1);
+							token= scanner.getNextToken();
+							if (token == ITerminalSymbols.TokenNameEOF)
+								return result;
+						}
+					}
+				} catch (InvalidInputException e) {
+					// ignore
+				} catch (IndexOutOfBoundsException e) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305001
+					return null;
+				}
+			}
+		}
+		return finder.getCoveringNode();
+	}
+	private ASTNode fCoveringNode;
+	private ASTNode fCoveredNode;
+
+	/**
+	 * Instantiate a new node finder using the given root node, the given start and the given length.
+	 *
+	 * @param root the given root node
+	 * @param start the given start
+	 * @param length the given length
+	 */
+	public NodeFinder(ASTNode root, int start, int length) {
+		NodeFinderVisitor nodeFinderVisitor = new NodeFinderVisitor(start, length);
+		root.accept(nodeFinderVisitor);
+		this.fCoveredNode = nodeFinderVisitor.getCoveredNode();
+		this.fCoveringNode = nodeFinderVisitor.getCoveringNode();
+	}
+	/**
+	 * Returns the covered node. If more than one nodes are covered by the selection, the
+	 * returned node is first covered node found in a top-down traversal of the AST.
+	 *
+	 * @return the covered node
+	 */
+	public ASTNode getCoveredNode() {
+		return this.fCoveredNode;
+	}
+
+	/**
+	 * Returns the covering node. If more than one nodes are covering the selection, the
+	 * returned node is last covering node found in a top-down traversal of the AST.
+	 *
+	 * @return the covering node
+	 */
+	public ASTNode getCoveringNode() {
+		return this.fCoveringNode;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java
new file mode 100644
index 0000000..4a144ac
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+
+class NodeSearcher extends ASTVisitor {
+	public org.eclipse.jdt.internal.compiler.ast.ASTNode found;
+	public TypeDeclaration enclosingType;
+	public int position;
+
+	NodeSearcher(int position) {
+		this.position = position;
+	}
+
+	public boolean visit(
+		ConstructorDeclaration constructorDeclaration,
+		ClassScope scope) {
+
+		if (constructorDeclaration.declarationSourceStart <= this.position
+			&& this.position <= constructorDeclaration.declarationSourceEnd) {
+				this.found = constructorDeclaration;
+				return false;
+		}
+		return true;
+	}
+
+	public boolean visit(
+		FieldDeclaration fieldDeclaration,
+		MethodScope scope) {
+			if (fieldDeclaration.declarationSourceStart <= this.position
+				&& this.position <= fieldDeclaration.declarationSourceEnd) {
+					this.found = fieldDeclaration;
+					return false;
+			}
+			return true;
+	}
+
+	public boolean visit(Initializer initializer, MethodScope scope) {
+		if (initializer.declarationSourceStart <= this.position
+			&& this.position <= initializer.declarationSourceEnd) {
+				this.found = initializer;
+				return false;
+		}
+		return true;
+	}
+
+	public boolean visit(
+		TypeDeclaration memberTypeDeclaration,
+		ClassScope scope) {
+			if (memberTypeDeclaration.declarationSourceStart <= this.position
+				&& this.position <= memberTypeDeclaration.declarationSourceEnd) {
+					this.enclosingType = memberTypeDeclaration;
+					return true;
+
+			}
+			return false;
+	}
+
+	public boolean visit(
+		MethodDeclaration methodDeclaration,
+		ClassScope scope) {
+
+		if (methodDeclaration.declarationSourceStart <= this.position
+			&& this.position <= methodDeclaration.declarationSourceEnd) {
+				this.found = methodDeclaration;
+				return false;
+		}
+		return true;
+	}
+
+	public boolean visit(
+		TypeDeclaration typeDeclaration,
+		CompilationUnitScope scope) {
+			if (typeDeclaration.declarationSourceStart <= this.position
+				&& this.position <= typeDeclaration.declarationSourceEnd) {
+					this.enclosingType = typeDeclaration;
+					return true;
+			}
+			return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java
new file mode 100644
index 0000000..234383c
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Normal annotation node (added in JLS3 API).
+ * <p>
+ * <pre>
+ * NormalAnnotation:
+ *   <b>@</b> TypeName <b>(</b> [ MemberValuePair { <b>,</b> MemberValuePair } ] <b>)</b>
+ * </pre>
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class NormalAnnotation extends Annotation {
+
+	/**
+	 * The "typeName" structural property of this node type (child type: {@link Name}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY =
+		internalTypeNamePropertyFactory(NormalAnnotation.class);
+
+	/**
+	 * The "values" structural property of this node type (element type: {@link MemberValuePair}).
+	 */
+	public static final ChildListPropertyDescriptor VALUES_PROPERTY =
+		new ChildListPropertyDescriptor(NormalAnnotation.class, "values", MemberValuePair.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(NormalAnnotation.class, propertyList);
+		addProperty(TYPE_NAME_PROPERTY, propertyList);
+		addProperty(VALUES_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The list of member value pairs (element type:
+	 * {@link MemberValuePair}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList values =
+		new ASTNode.NodeList(VALUES_PROPERTY);
+
+	/**
+	 * Creates a new unparented normal annotation node owned
+	 * by the given AST.  By default, the annotation has an
+	 * unspecified type name and an empty list of member value
+	 * pairs.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	NormalAnnotation(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_NAME_PROPERTY) {
+			if (get) {
+				return getTypeName();
+			} else {
+				setTypeName((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == VALUES_PROPERTY) {
+			return values();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalTypeNameProperty() {
+		return TYPE_NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return NORMAL_ANNOTATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		NormalAnnotation result = new NormalAnnotation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setTypeName((Name) ASTNode.copySubtree(target, getTypeName()));
+		result.values().addAll(ASTNode.copySubtrees(target, values()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getTypeName());
+			acceptChildren(visitor, this.values);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live list of member value pairs in this annotation.
+	 * Adding and removing nodes from this list affects this node
+	 * dynamically. All nodes in this list must be
+	 * {@link MemberValuePair}s; attempts to add any other
+	 * type of node will trigger an exception.
+	 *
+	 * @return the live list of member value pairs in this
+	 *    annotation (element type: {@link MemberValuePair})
+	 */
+	public List values() {
+		return this.values;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.typeName == null ? 0 : getTypeName().treeSize())
+			+ this.values.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java
new file mode 100644
index 0000000..3d3f6d5
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Null literal node.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class NullLiteral extends Expression {
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(1);
+		createPropertyList(NullLiteral.class, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Creates a new unparented null literal node owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	NullLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return NULL_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		NullLiteral result = new NullLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java
new file mode 100644
index 0000000..a1eb08b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Number literal nodes.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class NumberLiteral extends Expression {
+
+	/**
+	 * The "token" structural property of this node type (type: {@link String}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor TOKEN_PROPERTY =
+		new SimplePropertyDescriptor(NumberLiteral.class, "token", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(NumberLiteral.class, propertyList);
+		addProperty(TOKEN_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The token string; defaults to the integer literal "0".
+	 */
+	private String tokenValue = "0";//$NON-NLS-1$
+
+	/**
+	 * Creates a new unparented number literal node owned by the given AST.
+	 * By default, the number literal is the token "<code>0</code>".
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	NumberLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == TOKEN_PROPERTY) {
+			if (get) {
+				return getToken();
+			} else {
+				setToken((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return NUMBER_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		NumberLiteral result = new NumberLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setToken(getToken());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the token of this number literal node. The value is the sequence
+	 * of characters that would appear in the source program.
+	 *
+	 * @return the numeric literal token
+	 */
+	public String getToken() {
+		return this.tokenValue;
+	}
+
+	/**
+	 * Sets the token of this number literal node. The value is the sequence
+	 * of characters that would appear in the source program.
+	 *
+	 * @param token the numeric literal token
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setToken(String token) {
+		// update internalSetToken(String) if this is changed
+		if (token == null || token.length() == 0) {
+			throw new IllegalArgumentException();
+		}
+		Scanner scanner = this.ast.scanner;
+		char[] source = token.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		scanner.tokenizeComments = false;
+		scanner.tokenizeWhiteSpace = false;
+		try {
+			int tokenType = scanner.getNextToken();
+			switch(tokenType) {
+				case TerminalTokens.TokenNameDoubleLiteral:
+				case TerminalTokens.TokenNameIntegerLiteral:
+				case TerminalTokens.TokenNameFloatingPointLiteral:
+				case TerminalTokens.TokenNameLongLiteral:
+					break;
+				case TerminalTokens.TokenNameMINUS :
+					tokenType = scanner.getNextToken();
+					switch(tokenType) {
+						case TerminalTokens.TokenNameDoubleLiteral:
+						case TerminalTokens.TokenNameIntegerLiteral:
+						case TerminalTokens.TokenNameFloatingPointLiteral:
+						case TerminalTokens.TokenNameLongLiteral:
+							break;
+						default:
+							throw new IllegalArgumentException("Invalid number literal : >" + token + "<"); //$NON-NLS-1$//$NON-NLS-2$
+					}
+					break;
+				default:
+					throw new IllegalArgumentException("Invalid number literal : >" + token + "<");//$NON-NLS-1$//$NON-NLS-2$
+			}
+		} catch(InvalidInputException e) {
+			throw new IllegalArgumentException();
+		} finally {
+			scanner.tokenizeComments = true;
+			scanner.tokenizeWhiteSpace = true;
+		}
+		preValueChange(TOKEN_PROPERTY);
+		this.tokenValue = token;
+		postValueChange(TOKEN_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setToken(String) that doesn't do any validation.
+	 */
+	void internalSetToken(String token) {
+		preValueChange(TOKEN_PROPERTY);
+		this.tokenValue = token;
+		postValueChange(TOKEN_PROPERTY);
+	}
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 1 * 4 + stringSize(this.tokenValue);
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java
new file mode 100644
index 0000000..148584e
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+
+/**
+ * Internal implementation of package bindings.
+ */
+class PackageBinding implements IPackageBinding {
+
+	private static final String[] NO_NAME_COMPONENTS = CharOperation.NO_STRINGS;
+	private static final String UNNAMED = Util.EMPTY_STRING;
+	private static final char PACKAGE_NAME_SEPARATOR = '.';
+
+	private org.eclipse.jdt.internal.compiler.lookup.PackageBinding binding;
+	private String name;
+	private BindingResolver resolver;
+	private String[] components;
+
+	PackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding binding, BindingResolver resolver) {
+		this.binding = binding;
+		this.resolver = resolver;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		try {
+			INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment;
+			if (!(nameEnvironment instanceof SearchableEnvironment))
+				return AnnotationBinding.NoAnnotations;
+			NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup;
+			if (nameLookup == null)
+				return AnnotationBinding.NoAnnotations;
+			final String pkgName = getName();
+			IPackageFragment[] pkgs = nameLookup.findPackageFragments(pkgName, false/*exact match*/);
+			if (pkgs == null)
+				return AnnotationBinding.NoAnnotations;
+
+			for (int i = 0, len = pkgs.length; i < len; i++) {
+				int fragType = pkgs[i].getKind();
+				switch(fragType) {
+					case IPackageFragmentRoot.K_SOURCE:
+						String unitName = "package-info.java"; //$NON-NLS-1$
+						ICompilationUnit unit = pkgs[i].getCompilationUnit(unitName);
+						if (unit != null && unit.exists()) {
+							ASTParser p = ASTParser.newParser(AST.JLS3_INTERNAL);
+							p.setSource(unit);
+							p.setResolveBindings(true);
+							p.setUnitName(unitName);
+							p.setFocalPosition(0);
+							p.setKind(ASTParser.K_COMPILATION_UNIT);
+							CompilationUnit domUnit = (CompilationUnit) p.createAST(null);
+							PackageDeclaration pkgDecl = domUnit.getPackage();
+							if (pkgDecl != null) {
+								List annos = pkgDecl.annotations();
+								if (annos == null || annos.isEmpty())
+									return AnnotationBinding.NoAnnotations;
+								IAnnotationBinding[] result = new IAnnotationBinding[annos.size()];
+								int index=0;
+		 						for (Iterator it = annos.iterator(); it.hasNext(); index++) {
+									result[index] = ((Annotation) it.next()).resolveAnnotationBinding();
+									// not resolving bindings
+									if (result[index] == null)
+										return AnnotationBinding.NoAnnotations;
+								}
+								return result;
+							}
+						}
+						break;
+					case IPackageFragmentRoot.K_BINARY:
+						NameEnvironmentAnswer answer =
+							nameEnvironment.findType(TypeConstants.PACKAGE_INFO_NAME, this.binding.compoundName);
+						if (answer != null && answer.isBinaryType()) {
+							IBinaryType type = answer.getBinaryType();
+							char[][][] missingTypeNames = type.getMissingTypeNames();
+							IBinaryAnnotation[] binaryAnnotations = type.getAnnotations();
+							org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] binaryInstances =
+								BinaryTypeBinding.createAnnotations(binaryAnnotations, this.binding.environment, missingTypeNames);
+							org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] allInstances =
+								org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding.addStandardAnnotations(binaryInstances, type.getTagBits(), this.binding.environment);
+							int total = allInstances.length;
+							IAnnotationBinding[] domInstances = new AnnotationBinding[total];
+							for (int a = 0; a < total; a++) {
+								final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(allInstances[a]);
+								if (annotationInstance == null) {// not resolving binding
+									return AnnotationBinding.NoAnnotations;
+								}
+								domInstances[a] = annotationInstance;
+							}
+							return domInstances;
+						}
+				}
+			}
+		} catch(JavaModelException e) {
+			return AnnotationBinding.NoAnnotations;
+		}
+		return AnnotationBinding.NoAnnotations;
+	}
+
+	/*
+	 * @see IBinding#getName()
+	 */
+	public String getName() {
+		if (this.name == null) {
+			computeNameAndComponents();
+		}
+		return this.name;
+	}
+
+	/*
+	 * @see IPackageBinding#isUnnamed()
+	 */
+	public boolean isUnnamed() {
+		return getName().equals(UNNAMED);
+	}
+
+	/*
+	 * @see IPackageBinding#getNameComponents()
+	 */
+	public String[] getNameComponents() {
+		if (this.components == null) {
+			computeNameAndComponents();
+		}
+		return this.components;
+	}
+
+	/*
+	 * @see IBinding#getKind()
+	 */
+	public int getKind() {
+		return IBinding.PACKAGE;
+	}
+
+	/*
+	 * @see IBinding#getModifiers()
+	 */
+	public int getModifiers() {
+		return Modifier.NONE;
+	}
+
+	/*
+	 * @see IBinding#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		return false;
+	}
+
+	/**
+	 * @see IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return false;
+	}
+
+	/**
+	 * @see IBinding#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return false;
+	}
+
+	/*
+	 * @see IBinding#getJavaElement()
+	 */
+	public IJavaElement getJavaElement() {
+		INameEnvironment nameEnvironment = this.binding.environment.nameEnvironment; // a package binding always has a LooupEnvironment set
+		if (!(nameEnvironment instanceof SearchableEnvironment)) return null;
+		// this is not true in standalone DOM/AST
+		NameLookup nameLookup = ((SearchableEnvironment) nameEnvironment).nameLookup;
+		if (nameLookup == null) return null;
+		IJavaElement[] pkgs = nameLookup.findPackageFragments(getName(), false/*exact match*/);
+		if (pkgs == null) return null;
+		if (pkgs.length == 0) {
+			// add additional tracing as this should not happen
+			org.eclipse.jdt.internal.core.util.Util.log(
+				new Status(
+						IStatus.WARNING,
+						JavaCore.PLUGIN_ID,
+						"Searching for package " + getName() + " returns an empty array")); //$NON-NLS-1$ //$NON-NLS-2$
+			return null;
+		}
+		return pkgs[0];
+	}
+
+	/*
+	 * @see IBinding#getKey()
+	 */
+	public String getKey() {
+		return new String(this.binding.computeUniqueKey());
+	}
+
+	/*
+	 * @see IBinding#isEqualTo(Binding)
+	 * @since 3.1
+	 */
+	public boolean isEqualTo(IBinding other) {
+		if (other == this) {
+			// identical binding - equal (key or no key)
+			return true;
+		}
+		if (other == null) {
+			// other binding missing
+			return false;
+		}
+		if (!(other instanceof PackageBinding)) {
+			return false;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding2 = ((PackageBinding) other).binding;
+		return CharOperation.equals(this.binding.compoundName, packageBinding2.compoundName);
+	}
+
+	private void computeNameAndComponents() {
+		char[][] compoundName = this.binding.compoundName;
+		if (compoundName == CharOperation.NO_CHAR_CHAR || compoundName == null) {
+			this.name = UNNAMED;
+			this.components = NO_NAME_COMPONENTS;
+		} else {
+			int length = compoundName.length;
+			this.components = new String[length];
+			StringBuffer buffer = new StringBuffer();
+			for (int i = 0; i < length - 1; i++) {
+				this.components[i] = new String(compoundName[i]);
+				buffer.append(compoundName[i]).append(PACKAGE_NAME_SEPARATOR);
+			}
+			this.components[length - 1] = new String(compoundName[length - 1]);
+			buffer.append(compoundName[length - 1]);
+			this.name = buffer.toString();
+		}
+	}
+
+	/*
+	 * For debugging purpose only.
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.binding.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java
new file mode 100644
index 0000000..0d8aef3
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Package declaration AST node type.
+ * <pre>
+ * PackageDeclaration:
+ *    [ Javadoc ] { Annotation } <b>package</b> Name <b>;</b>
+ * </pre>
+ * Note that the standard AST parser only recognizes a Javadoc comment
+ * immediately preceding the package declaration when it occurs in the
+ * special <code>package-info.java</code> compilation unit (JLS3 7.4.1.1).
+ * The Javadoc comment in that file contains the package description.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class PackageDeclaration extends ASTNode {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}) (added in JLS3 API).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		new ChildPropertyDescriptor(PackageDeclaration.class, "javadoc", Javadoc.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+		new ChildListPropertyDescriptor(PackageDeclaration.class, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(PackageDeclaration.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(PackageDeclaration.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(4);
+		createPropertyList(PackageDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The doc comment, or <code>null</code> if none.
+	 * Defaults to none.
+	 * @since 3.0
+	 */
+	Javadoc optionalDocComment = null;
+
+	/**
+	 * The annotations (element type: {@link Annotation}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList annotations = null;
+
+	/**
+	 * The package name; lazily initialized; defaults to a unspecified,
+	 * legal Java package identifier.
+	 */
+	private Name packageName = null;
+
+	/**
+	 * Creates a new AST node for a package declaration owned by the
+	 * given AST. The package declaration initially has an unspecified,
+	 * but legal, Java identifier; and an empty list of annotations.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	PackageDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return PACKAGE_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		PackageDeclaration result = new PackageDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.setJavadoc((Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+			result.annotations().addAll(ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setName((Name) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChild(visitor, getJavadoc());
+				acceptChildren(visitor, this.annotations);
+			}
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of annotations of this
+	 * package declaration (added in JLS3 API).
+	 *
+	 * @return the live list of annotations
+	 *    (element type: {@link Annotation})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List annotations() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.annotations == null) {
+			unsupportedIn2();
+		}
+		return this.annotations;
+	}
+
+	/**
+	 * Returns the doc comment node (added in JLS3 API).
+	 *
+	 * @return the doc comment node, or <code>null</code> if none
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.0
+	 */
+	public Javadoc getJavadoc() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.annotations == null) {
+			unsupportedIn2();
+		}
+		return this.optionalDocComment;
+	}
+
+	/**
+	 * Sets or clears the doc comment node (added in JLS3 API).
+	 *
+	 * @param docComment the doc comment node, or <code>null</code> if none
+	 * @exception IllegalArgumentException if the doc comment string is invalid
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.0
+	 */
+	public void setJavadoc(Javadoc docComment) {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.annotations == null) {
+			unsupportedIn2();
+		}
+		ASTNode oldChild = this.optionalDocComment;
+		preReplaceChild(oldChild, docComment, JAVADOC_PROPERTY);
+		this.optionalDocComment = docComment;
+		postReplaceChild(oldChild, docComment, JAVADOC_PROPERTY);
+	}
+
+	/**
+	 * Returns the package name of this package declaration.
+	 *
+	 * @return the package name node
+	 */
+	public Name getName() {
+		if (this.packageName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.packageName == null) {
+					preLazyInit();
+					this.packageName = new SimpleName(this.ast);
+					postLazyInit(this.packageName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.packageName;
+	}
+
+	/**
+	 * Sets the package name of this package declaration to the given name.
+	 *
+	 * @param name the new package name
+	 * @exception IllegalArgumentException if`:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(Name name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.packageName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.packageName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Resolves and returns the binding for the package declared in this package
+	 * declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IPackageBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolvePackage(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ (this.annotations == null ? 0 : this.annotations.listSize())
+			+ (this.packageName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java
new file mode 100644
index 0000000..b3154b4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageQualifiedType.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Node for a package qualified type (added in JLS8 API).
+ * 
+ * <pre>
+ * PackageQualifiedType:
+ *    Name <b>.</b> { Annotation } SimpleName
+ * </pre>
+ * 
+ * <p>
+ * Note that if no annotation is present, then a package-qualified type can
+ * also be represented by a SimpleType or a QualifiedType, see the discussion
+ * in {@link QualifiedType}.
+ * </p>
+ *
+ * @see SimpleType
+ * @see QualifiedType
+ * 
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class PackageQualifiedType extends AnnotatableType {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(PackageQualifiedType.class, "qualifier", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(PackageQualifiedType.class);
+	
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(PackageQualifiedType.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(PackageQualifiedType.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The qualifier node; lazily initialized; defaults to 
+	 * an unspecified, but legal, simple name.
+	 */
+	private Name qualifier = null;
+
+	/**
+	 * The name being qualified; lazily initialized; defaults to a unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName name = null;
+
+	/**
+	 * Creates a new unparented node for a package qualified type owned by the
+	 * given AST. By default, an unspecified, but legal, qualifier and name.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	PackageQualifiedType(AST ast) {
+		super(ast);
+	    unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 */
+	ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	final int getNodeType0() {
+		return PACKAGE_QUALIFIED_TYPE;
+	}
+
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	ASTNode clone0(AST target) {
+		PackageQualifiedType result = new PackageQualifiedType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Name) ((ASTNode) getQualifier()).clone(target));
+		result.annotations().addAll(ASTNode.copySubtrees(target, annotations()));
+		result.setName((SimpleName) ((ASTNode) getName()).clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChildren(visitor, this.annotations);
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this package qualified type.
+	 *
+	 * @return the qualifier of this package qualified type
+	 */
+	public Name getQualifier() {
+		if (this.qualifier == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.qualifier == null) {
+					preLazyInit();
+					this.qualifier = new SimpleName(this.ast);
+					postLazyInit(this.qualifier, QUALIFIER_PROPERTY);
+				}
+			}
+		}
+		return this.qualifier;
+	}
+
+	/**
+	 * Sets the qualifier of this package qualified type to the given name.
+	 *
+	 * @param name the new qualifier of this package qualified type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.qualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.qualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name part of this package qualified type.
+	 *
+	 * @return the name being qualified
+	 */
+	public SimpleName getName() {
+		if (this.name == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.name == null) {
+					preLazyInit();
+					this.name = new SimpleName(this.ast);
+					postLazyInit(this.name, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.name;
+	}
+
+	/**
+	 * Sets the name part of this package qualified type to the given simple name.
+	 *
+	 * @param name the identifier of this qualified name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.name;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.name = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.qualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.annotations == null ? 0 : this.annotations.listSize())
+			+ (this.name == null ? 0 : getName().treeSize());
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java
new file mode 100644
index 0000000..39e8bea
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for a parameterized type (added in JLS3 API).
+ * These nodes are used for type references (as opposed to
+ * declarations of parameterized types.)
+ * <pre>
+ * ParameterizedType:
+ *    Type <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b>
+ * </pre>
+ * The first type may be a simple type or a qualified type;
+ * other kinds of types are meaningless.
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ParameterizedType extends Type {
+    /**
+     * This index represents the position inside a parameterized qualified type.
+     */
+    int index;
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(ParameterizedType.class, "type", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}).
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(ParameterizedType.class, "typeArguments", Type.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(ParameterizedType.class, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The type node; lazily initialized; defaults to an unspecified, but legal,
+	 * type.
+	 */
+	private Type type = null;
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList typeArguments =
+		new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented node for a parameterized type owned by the
+	 * given AST. By default, an unspecified, but legal, type, and no type
+	 * arguments.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ParameterizedType(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return PARAMETERIZED_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ParameterizedType result = new ParameterizedType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) ((ASTNode) getType()).clone(target));
+		result.typeArguments().addAll(
+			ASTNode.copySubtrees(target, typeArguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.typeArguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type of this parameterized type.
+	 *
+	 * @return the type of this parameterized type
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = new SimpleType(this.ast);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type of this parameterized type.
+	 *
+	 * @param type the new type of this parameterized type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this parameterized
+	 * type. For the parameterized type to be plausible, the list should contain
+	 * at least one element and not contain primitive or union types.
+	 * <p>
+	 * Since JLS4, the list can also be empty if this is the type of a
+	 * {@link ClassInstanceCreation} (a so-called "diamond").
+	 * </p>
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ this.typeArguments.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java
new file mode 100644
index 0000000..ba97b47
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parenthesized expression AST node type.
+ *
+ * <pre>
+ * ParenthesizedExpression:
+ *     <b>(</b> Expression <b>)</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ParenthesizedExpression extends Expression {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ParenthesizedExpression.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ParenthesizedExpression.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * Creates a new unparented parenthesized expression node owned by the given
+	 * AST. By default, the parenthesized expression has an unspecified, but
+	 * legal, expression.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ParenthesizedExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return PARENTHESIZED_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ParenthesizedExpression result = new ParenthesizedExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression((Expression) getExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this parenthesized expression.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this parenthesized expression.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java
new file mode 100644
index 0000000..da88378
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Postfix expression AST node type.
+ *
+ * <pre>
+ * PostfixExpression:
+ *    Expression PostfixOperator
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class PostfixExpression extends Expression {
+
+	/**
+ 	 * Postfix operators (typesafe enumeration).
+	 * <pre>
+	 * PostfixOperator:
+	 *    <b><code>++</code></b>  <code>INCREMENT</code>
+	 *    <b><code>--</code></b>  <code>DECREMENT</code>
+	 * </pre>
+	 */
+	public static class Operator {
+
+		/**
+		 * The token for the operator.
+		 */
+		private String token;
+
+		/**
+		 * Creates a new postfix operator with the given token.
+		 * <p>
+		 * Note: this constructor is private. The only instances
+		 * ever created are the ones for the standard operators.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 */
+		private Operator(String token) {
+			this.token = token;
+		}
+
+		/**
+		 * Returns the character sequence for the operator.
+		 *
+		 * @return the character sequence for the operator
+		 */
+		public String toString() {
+			return this.token;
+		}
+
+		/** Postfix increment "++" operator. */
+		public static final Operator INCREMENT = new Operator("++");//$NON-NLS-1$
+		/** Postfix decrement "--" operator. */
+		public static final Operator DECREMENT = new Operator("--");//$NON-NLS-1$
+
+		/**
+		 * Map from token to operator (key type: <code>String</code>;
+		 * value type: <code>Operator</code>).
+		 */
+		private static final Map CODES;
+		static {
+			CODES = new HashMap(20);
+			Operator[] ops = {
+					INCREMENT,
+					DECREMENT,
+				};
+			for (int i = 0; i < ops.length; i++) {
+				CODES.put(ops[i].toString(), ops[i]);
+			}
+		}
+
+		/**
+		 * Returns the postfix operator corresponding to the given string,
+		 * or <code>null</code> if none.
+		 * <p>
+		 * <code>toOperator</code> is the converse of <code>toString</code>:
+		 * that is, <code>Operator.toOperator(op.toString()) == op</code> for
+		 * all operators <code>op</code>.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 * @return the postfix operator, or <code>null</code> if none
+		 */
+		public static Operator toOperator(String token) {
+			return (Operator) CODES.get(token);
+		}
+	}
+
+	/**
+	 * The "operator" structural property of this node type (type: {@link PostfixExpression.Operator}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
+		new SimplePropertyDescriptor(PostfixExpression.class, "operator", PostfixExpression.Operator.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "operand" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(PostfixExpression.class, "operand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(PostfixExpression.class, propertyList);
+		addProperty(OPERAND_PROPERTY, propertyList);
+		addProperty(OPERATOR_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The operator; defaults to an unspecified postfix operator.
+	 */
+	private PostfixExpression.Operator operator =
+		PostfixExpression.Operator.INCREMENT;
+
+	/**
+	 * The operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression operand = null;
+
+	/**
+	 * Creates a new AST node for an postfix expression owned by the given
+	 * AST. By default, the node has unspecified (but legal) operator and
+	 * operand.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	PostfixExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == OPERATOR_PROPERTY) {
+			if (get) {
+				return getOperator();
+			} else {
+				setOperator((Operator) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == OPERAND_PROPERTY) {
+			if (get) {
+				return getOperand();
+			} else {
+				setOperand((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return POSTFIX_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		PostfixExpression result = new PostfixExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setOperator(getOperator());
+		result.setOperand((Expression) getOperand().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getOperand());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the operator of this postfix expression.
+	 *
+	 * @return the operator
+	 */
+	public PostfixExpression.Operator getOperator() {
+		return this.operator;
+	}
+
+	/**
+	 * Sets the operator of this postfix expression.
+	 *
+	 * @param operator the operator
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setOperator(PostfixExpression.Operator operator) {
+		if (operator == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(OPERATOR_PROPERTY);
+		this.operator = operator;
+		postValueChange(OPERATOR_PROPERTY);
+	}
+
+	/**
+	 * Returns the operand of this postfix expression.
+	 *
+	 * @return the operand expression node
+	 */
+	public Expression getOperand() {
+		if (this.operand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.operand == null) {
+					preLazyInit();
+					this.operand= new SimpleName(this.ast);
+					postLazyInit(this.operand, OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.operand;
+	}
+
+	/**
+	 * Sets the operand of this postfix expression.
+	 *
+	 * @param expression the operand expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setOperand(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.operand;
+		preReplaceChild(oldChild, expression, OPERAND_PROPERTY);
+		this.operand = expression;
+		postReplaceChild(oldChild, expression, OPERAND_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.operand == null ? 0 : getOperand().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java
new file mode 100644
index 0000000..307109d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Prefix expression AST node type.
+ *
+ * <pre>
+ * PrefixExpression:
+ *    PrefixOperator Expression
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class PrefixExpression extends Expression {
+
+	/**
+ 	 * Prefix operators (typesafe enumeration).
+	 * <pre>
+	 * PrefixOperator:
+	 *    <b><code>++</code></b>  <code>INCREMENT</code>
+	 *    <b><code>--</code></b>  <code>DECREMENT</code>
+	 *    <b><code>+</code></b>  <code>PLUS</code>
+	 *    <b><code>-</code></b>  <code>MINUS</code>
+	 *    <b><code>~</code></b>  <code>COMPLEMENT</code>
+	 *    <b><code>!</code></b>  <code>NOT</code>
+	 * </pre>
+	 */
+	public static class Operator {
+
+		/**
+		 * The token for the operator.
+		 */
+		private String token;
+
+		/**
+		 * Creates a new prefix operator with the given token.
+		 * <p>
+		 * Note: this constructor is private. The only instances
+		 * ever created are the ones for the standard operators.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 */
+		private Operator(String token) {
+			this.token = token;
+		}
+
+		/**
+		 * Returns the character sequence for the operator.
+		 *
+		 * @return the character sequence for the operator
+		 */
+		public String toString() {
+			return this.token;
+		}
+
+		/** Prefix increment "++" operator. */
+		public static final Operator INCREMENT = new Operator("++");//$NON-NLS-1$
+		/** Prefix decrement "--" operator. */
+		public static final Operator DECREMENT = new Operator("--");//$NON-NLS-1$
+		/** Unary plus "+" operator. */
+		public static final Operator PLUS = new Operator("+");//$NON-NLS-1$
+		/** Unary minus "-" operator. */
+		public static final Operator MINUS = new Operator("-");//$NON-NLS-1$
+		/** Bitwise complement "~" operator. */
+		public static final Operator COMPLEMENT = new Operator("~");//$NON-NLS-1$
+		/** Logical complement "!" operator. */
+		public static final Operator NOT = new Operator("!");//$NON-NLS-1$
+
+		/**
+		 * Map from token to operator (key type: <code>String</code>;
+		 * value type: <code>Operator</code>).
+		 */
+		private static final Map CODES;
+		static {
+			CODES = new HashMap(20);
+			Operator[] ops = {
+					INCREMENT,
+					DECREMENT,
+					PLUS,
+					MINUS,
+					COMPLEMENT,
+					NOT,
+				};
+			for (int i = 0; i < ops.length; i++) {
+				CODES.put(ops[i].toString(), ops[i]);
+			}
+		}
+
+		/**
+		 * Returns the prefix operator corresponding to the given string,
+		 * or <code>null</code> if none.
+		 * <p>
+		 * <code>toOperator</code> is the converse of <code>toString</code>:
+		 * that is, <code>Operator.toOperator(op.toString()) == op</code> for
+		 * all operators <code>op</code>.
+		 * </p>
+		 *
+		 * @param token the character sequence for the operator
+		 * @return the prefix operator, or <code>null</code> if none
+		 */
+		public static Operator toOperator(String token) {
+			return (Operator) CODES.get(token);
+		}
+	}
+
+	/**
+	 * The "operator" structural property of this node type (type: {@link PrefixExpression.Operator}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
+		new SimplePropertyDescriptor(PrefixExpression.class, "operator", PrefixExpression.Operator.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "operand" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor OPERAND_PROPERTY =
+		new ChildPropertyDescriptor(PrefixExpression.class, "operand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(PrefixExpression.class, propertyList);
+		addProperty(OPERATOR_PROPERTY, propertyList);
+		addProperty(OPERAND_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The operator; defaults to an unspecified prefix operator.
+	 */
+	private PrefixExpression.Operator operator =
+		PrefixExpression.Operator.PLUS;
+
+	/**
+	 * The operand; lazily initialized; defaults to an unspecified,
+	 * but legal, simple name.
+	 */
+	private Expression operand = null;
+
+	/**
+	 * Creates a new AST node for an prefix expression owned by the given
+	 * AST. By default, the node has unspecified (but legal) operator and
+	 * operand.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	PrefixExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == OPERATOR_PROPERTY) {
+			if (get) {
+				return getOperator();
+			} else {
+				setOperator((Operator) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == OPERAND_PROPERTY) {
+			if (get) {
+				return getOperand();
+			} else {
+				setOperand((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return PREFIX_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		PrefixExpression result = new PrefixExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setOperator(getOperator());
+		result.setOperand((Expression) getOperand().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getOperand());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the operator of this prefix expression.
+	 *
+	 * @return the operator
+	 */
+	public PrefixExpression.Operator getOperator() {
+		return this.operator;
+	}
+
+	/**
+	 * Sets the operator of this prefix expression.
+	 *
+	 * @param operator the operator
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setOperator(PrefixExpression.Operator operator) {
+		if (operator == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(OPERATOR_PROPERTY);
+		this.operator = operator;
+		postValueChange(OPERATOR_PROPERTY);
+	}
+
+	/**
+	 * Returns the operand of this prefix expression.
+	 *
+	 * @return the operand expression node
+	 */
+	public Expression getOperand() {
+		if (this.operand  == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.operand == null) {
+					preLazyInit();
+					this.operand= new SimpleName(this.ast);
+					postLazyInit(this.operand, OPERAND_PROPERTY);
+				}
+			}
+		}
+		return this.operand;
+	}
+
+	/**
+	 * Sets the operand of this prefix expression.
+	 *
+	 * @param expression the operand expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setOperand(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.operand;
+		preReplaceChild(oldChild, expression, OPERAND_PROPERTY);
+		this.operand = expression;
+		postReplaceChild(oldChild, expression, OPERAND_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.operand == null ? 0 : getOperand().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java
new file mode 100644
index 0000000..948c32c
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Primitive type nodes.
+ * <pre>
+ * PrimitiveType:
+ *    { Annotation } <b>byte</b>
+ *    { Annotation } <b>short</b>
+ *    { Annotation } <b>char</b>
+ *    { Annotation } <b>int</b>
+ *    { Annotation } <b>long</b>
+ *    { Annotation } <b>float</b>
+ *    { Annotation } <b>double</b>
+ *    { Annotation } <b>boolean</b>
+ *    { Annotation } <b>void</b>
+ * </pre>
+ * <p>
+ * Note that due to the fact that AST nodes belong to a specific AST and
+ * have a specific parent, there needs to multiple instances of these
+ * nodes.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class PrimitiveType extends AnnotatableType {
+
+	/**
+ 	 * Primitive type codes (typesafe enumeration).
+	 * <pre>
+	 *    <b>byte</b> 	BYTE
+	 *    <b>short</b> 	SHORT
+	 *    <b>char</b> 	CHAR
+	 *    <b>int</b>  	INT
+	 *    <b>long</b>  	LONG
+	 *    <b>float</b>  	FLOAT
+	 *    <b>double</b> 	DOUBLE
+	 *    <b>boolean</b>	BOOLEAN
+	 *    <b>void</b>  	VOID
+	 * </pre>
+	 */
+	public static class Code {
+
+		/**
+		 * The name of the type.
+		 */
+		private String name;
+
+		/**
+		 * Creates a new primitive type code with the given name.
+		 * <p>
+		 * Note: this constructor is package-private. The only instances
+		 * ever created are the ones for the standard primitive types.
+		 * </p>
+		 *
+		 * @param name the standard name of the primitive type
+		 */
+		Code(String name) {
+			this.name = name;
+		}
+
+		/**
+		 * Returns the standard name of the primitive type.
+		 *
+		 * @return the standard name of the primitive type
+		 */
+		public String toString() {
+			return this.name;
+		}
+	}
+
+	/** Type code for the primitive type "int". */
+	public static final Code INT = new Code("int");//$NON-NLS-1$
+	/** Type code for the primitive type "char". */
+	public static final Code CHAR = new Code("char");//$NON-NLS-1$
+	/** Type code for the primitive type "boolean". */
+	public static final Code BOOLEAN = new Code("boolean");//$NON-NLS-1$
+	/** Type code for the primitive type "short". */
+	public static final Code SHORT = new Code("short");//$NON-NLS-1$
+	/** Type code for the primitive type "long". */
+	public static final Code LONG = new Code("long");//$NON-NLS-1$
+	/** Type code for the primitive type "float". */
+	public static final Code FLOAT = new Code("float");//$NON-NLS-1$
+	/** Type code for the primitive type "double". */
+	public static final Code DOUBLE = new Code("double");//$NON-NLS-1$
+	/** Type code for the primitive type "byte". */
+	public static final Code BYTE = new Code("byte");//$NON-NLS-1$
+
+	/** Type code for the primitive type "void". Note that "void" is
+	 * special in that its only legitimate uses are as a method return
+	 * type and as a type literal.
+	 */
+	public static final Code VOID = new Code("void");//$NON-NLS-1$
+
+	/**
+	 * The primitive type code; one of the PrimitiveType constants; default
+	 * is int.
+	 */
+	private PrimitiveType.Code typeCode = INT;
+
+	/**
+	 * Map from token to primitive type code (key type: <code>String</code>;
+	 * value type: <code>PrimitiveType.Code</code>).
+	 */
+	private static final Map CODES;
+	static {
+		CODES = new HashMap(20);
+		Code[] ops = {
+				INT,
+				BYTE,
+				CHAR,
+				BOOLEAN,
+				SHORT,
+				LONG,
+				FLOAT,
+				DOUBLE,
+				VOID,
+			};
+		for (int i = 0; i < ops.length; i++) {
+			CODES.put(ops[i].toString(), ops[i]);
+		}
+	}
+
+	/**
+	 * Returns the primitive type code corresponding to the given string,
+	 * or <code>null</code> if none.
+	 * <p>
+	 * <code>toCode</code> is the converse of <code>toString</code>:
+	 * that is,
+	 * <code>PrimitiveType.Code.toCode(code.toString()) == code</code>
+	 * for all type code <code>code</code>.
+	 * </p>
+	 *
+	 * @param token the standard name of the primitive type
+	 * @return the primitive type code, or <code>null</code> if none
+	 */
+	public static PrimitiveType.Code toCode(String token) {
+		return (PrimitiveType.Code) CODES.get(token);
+	}
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(PrimitiveType.class);
+	
+	/**
+	 * The "primitiveTypeCode" structural property of this node type (type: {@link PrimitiveType.Code}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor PRIMITIVE_TYPE_CODE_PROPERTY =
+		new SimplePropertyDescriptor(PrimitiveType.class, "primitiveTypeCode", PrimitiveType.Code.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(PrimitiveType.class, propertyList);
+		addProperty(PRIMITIVE_TYPE_CODE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(3);
+		createPropertyList(PrimitiveType.class, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(PRIMITIVE_TYPE_CODE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * Creates a new unparented node for a primitive type owned by the given
+	 * AST. By default, the node has type "int".
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	PrimitiveType(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == PRIMITIVE_TYPE_CODE_PROPERTY) {
+			if (get) {
+				return getPrimitiveTypeCode();
+			} else {
+				setPrimitiveTypeCode((Code) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return PRIMITIVE_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		PrimitiveType result = new PrimitiveType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setPrimitiveTypeCode(getPrimitiveTypeCode());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the primitive type code.
+	 *
+	 * @return one of the primitive type code constants declared in this
+	 *    class
+	 */
+	public PrimitiveType.Code getPrimitiveTypeCode() {
+		return this.typeCode;
+	}
+
+	/**
+	 * Sets the primitive type code.
+	 *
+	 * @param typeCode one of the primitive type code constants declared in
+	 *    this class
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setPrimitiveTypeCode(PrimitiveType.Code typeCode) {
+		if (typeCode == null) {
+			throw new IllegalArgumentException();
+		}
+		preValueChange(PRIMITIVE_TYPE_CODE_PROPERTY);
+		this.typeCode = typeCode;
+		postValueChange(PRIMITIVE_TYPE_CODE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize()
+				+ (this.annotations == null ? 0 : this.annotations.listSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java
new file mode 100644
index 0000000..c7753b2
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * AST node for a qualified name. A qualified name is defined recursively
+ * as a simple name preceded by a name, which qualifies it. Expressing it this
+ * way means that the qualifier and the simple name get their own AST nodes.
+ * <pre>
+ * QualifiedName:
+ *    Name <b>.</b> SimpleName
+ * </pre>
+ * <p>
+ * See <code>FieldAccess</code> for guidelines on handling other expressions
+ * that resemble qualified names.
+ * </p>
+ *
+ * @see FieldAccess
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class QualifiedName extends Name {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(QualifiedName.class, "qualifier", Name.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(QualifiedName.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(QualifiedName.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The identifier; lazily initialized; defaults to a unspecified, legal
+	 * Java identifier.
+	 */
+	private Name qualifier = null;
+
+	/**
+	 * The name being qualified; lazily initialized; defaults to a unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName name = null;
+
+	/**
+	 * Creates a new AST node for a qualified name owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	QualifiedName(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return QUALIFIED_NAME;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		QualifiedName result = new QualifiedName(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Name) getQualifier().clone(target));
+		result.setName((SimpleName) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier part of this qualified name.
+	 *
+	 * @return the qualifier part of this qualified name
+	 */
+	public Name getQualifier() {
+		if (this.qualifier == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.qualifier == null) {
+					preLazyInit();
+					this.qualifier = new SimpleName(this.ast);
+					postLazyInit(this.qualifier, QUALIFIER_PROPERTY);
+				}
+			}
+		}
+		return this.qualifier;
+	}
+
+	/**
+	 * Sets the qualifier of this qualified name to the given name.
+	 *
+	 * @param qualifier the qualifier of this qualified name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name qualifier) {
+		if (qualifier == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.qualifier;
+		preReplaceChild(oldChild, qualifier, QUALIFIER_PROPERTY);
+		this.qualifier = qualifier;
+		postReplaceChild(oldChild, qualifier, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name part of this qualified name.
+	 *
+	 * @return the name being qualified
+	 */
+	public SimpleName getName() {
+		if (this.name == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.name == null) {
+					preLazyInit();
+					this.name = new SimpleName(this.ast);
+					postLazyInit(this.name, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.name;
+	}
+
+	/**
+	 * Sets the name part of this qualified name to the given simple name.
+	 *
+	 * @param name the identifier of this qualified name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.name;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.name = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on Name.
+	 */
+	void appendName(StringBuffer buffer) {
+		getQualifier().appendName(buffer);
+		buffer.append('.');
+		getName().appendName(buffer);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NAME_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.name == null ? 0 : getName().treeSize())
+			+ (this.qualifier == null ? 0 : getQualifier().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java
new file mode 100644
index 0000000..b3b549f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java
@@ -0,0 +1,360 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for a qualified type (added in JLS3 API).
+ * 
+ * <pre>
+ * QualifiedType:
+ *    Type <b>.</b> { Annotation } SimpleName
+ * </pre>
+ * <p>
+ * Not all node arrangements will represent legal Java constructs. In particular,
+ * it is nonsense if the type is an array type or primitive type. The normal use
+ * is when the type is a simple or parameterized type.
+ * </p>
+ * <p>
+ * A type like "A.B" can be represented either of two ways:
+ * <ol>
+ * <li>
+ * <code>QualifiedType(SimpleType(SimpleName("A")),SimpleName("B"))</code>
+ * </li>
+ * <li>
+ * <code>SimpleType(QualifiedName(SimpleName("A"),SimpleName("B")))</code>
+ * </li>
+ * </ol>
+ * The first form is preferred when "A" is known to be a type. However, a
+ * parser cannot always determine this. Clients should be prepared to handle
+ * either rather than make assumptions. (Note also that the first form
+ * became possible as of JLS3; only the second form existed in JLS2 API;
+ * the ASTParser currently prefers the second form).
+ * </p>
+ * <p>
+ * Since JLS8, it's also possible to annotate qualified type names.
+ * A type like "a.@X B" cannot be represented in either of
+ * the old ways, because "a" is not a type, but a package.
+ * Such types are represented as:
+ * </p>
+ * <ol start="3">
+ * <li>
+ * <code>PackageQualifiedType(SimpleName("a"),MarkerAnnotation("X"),SimpleName("B"))</code>
+ * </li>
+ * </ol>
+ * 
+ * @see SimpleType
+ * @see PackageQualifiedType
+ * 
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class QualifiedType extends AnnotatableType {
+    /**
+     * This index represents the position inside a parameterized qualified type.
+     */
+    int index;
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(QualifiedType.class, "qualifier", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(QualifiedType.class);
+	
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(QualifiedType.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(QualifiedType.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(4);
+		createPropertyList(QualifiedType.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The type node; lazily initialized; defaults to a type with
+	 * an unspecified, but legal, simple name.
+	 */
+	private Type qualifier = null;
+
+	/**
+	 * The name being qualified; lazily initialized; defaults to a unspecified,
+	 * legal Java identifier.
+	 */
+	private SimpleName name = null;
+
+	/**
+	 * Creates a new unparented node for a qualified type owned by the
+	 * given AST. By default, an unspecified, but legal, qualifier and name.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	QualifiedType(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Type) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return QUALIFIED_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		QualifiedType result = new QualifiedType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Type) ((ASTNode) getQualifier()).clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setName((SimpleName) ((ASTNode) getName()).clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this qualified type.
+	 *
+	 * @return the qualifier of this qualified type
+	 */
+	public Type getQualifier() {
+		if (this.qualifier == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.qualifier == null) {
+					preLazyInit();
+					this.qualifier = new SimpleType(this.ast);
+					postLazyInit(this.qualifier, QUALIFIER_PROPERTY);
+				}
+			}
+		}
+		return this.qualifier;
+	}
+
+	/**
+	 * Sets the qualifier of this qualified type to the given type.
+	 *
+	 * @param type the new qualifier of this qualified type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.qualifier;
+		preReplaceChild(oldChild, type, QUALIFIER_PROPERTY);
+		this.qualifier = type;
+		postReplaceChild(oldChild, type, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name part of this qualified type.
+	 *
+	 * @return the name being qualified
+	 */
+	public SimpleName getName() {
+		if (this.name == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.name == null) {
+					preLazyInit();
+					this.name = new SimpleName(this.ast);
+					postLazyInit(this.name, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.name;
+	}
+
+	/**
+	 * Sets the name part of this qualified type to the given simple name.
+	 *
+	 * @param name the identifier of this qualified name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.name;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.name = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.qualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.annotations == null ? 0 : this.annotations.listSize())
+			+ (this.name == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
new file mode 100644
index 0000000..b72d128
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
@@ -0,0 +1,711 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.PackageFragment;
+
+/**
+ * This class represents the recovered binding for a type
+ */
+class RecoveredTypeBinding implements ITypeBinding {
+
+	private VariableDeclaration variableDeclaration;
+	private Type currentType;
+	private BindingResolver resolver;
+	private int dimensions;
+	private RecoveredTypeBinding innerTypeBinding;
+	private ITypeBinding[] typeArguments;
+	private org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding;
+
+	RecoveredTypeBinding(BindingResolver resolver, VariableDeclaration variableDeclaration) {
+		this.variableDeclaration = variableDeclaration;
+		this.resolver = resolver;
+		this.currentType = getType();
+		this.dimensions = variableDeclaration.getExtraDimensions();
+		if (this.currentType.isArrayType()) {
+			this.dimensions += ((ArrayType) this.currentType).getDimensions();
+		}
+	}
+
+	RecoveredTypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding) {
+		this.resolver = resolver;
+		this.dimensions = typeBinding.dimensions();
+		this.binding = typeBinding;
+	}
+
+	RecoveredTypeBinding(BindingResolver resolver, Type type) {
+		this.currentType = type;
+		this.resolver = resolver;
+		this.dimensions = 0;
+		if (type.isArrayType()) {
+			this.dimensions += ((ArrayType) type).getDimensions();
+		}
+	}
+
+	RecoveredTypeBinding(BindingResolver resolver, RecoveredTypeBinding typeBinding, int dimensions) {
+		this.innerTypeBinding = typeBinding;
+		this.dimensions = typeBinding.getDimensions() + dimensions;
+		this.resolver = resolver;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#createArrayType(int)
+	 */
+	public ITypeBinding createArrayType(int dims) {
+		return this.resolver.getTypeBinding(this, dims);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getBinaryName()
+	 */
+	public String getBinaryName() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getBound()
+	 */
+	public ITypeBinding getBound() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getGenericTypeOfWildcardType()
+	 */
+	public ITypeBinding getGenericTypeOfWildcardType() {
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getRank()
+	 */
+	public int getRank() {
+		return -1;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getComponentType()
+	 */
+	public ITypeBinding getComponentType() {
+		if (this.dimensions == 0) return null;
+		return this.resolver.getTypeBinding(this, -1);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredFields()
+	 */
+	public IVariableBinding[] getDeclaredFields() {
+		return TypeBinding.NO_VARIABLE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredMethods()
+	 */
+	public IMethodBinding[] getDeclaredMethods() {
+		return TypeBinding.NO_METHOD_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredModifiers()
+	 */
+	public int getDeclaredModifiers() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaredTypes()
+	 */
+	public ITypeBinding[] getDeclaredTypes() {
+		return TypeBinding.NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringClass()
+	 */
+	public ITypeBinding getDeclaringClass() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringMethod()
+	 */
+	public IMethodBinding getDeclaringMethod() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getDimensions()
+	 */
+	public int getDimensions() {
+		return this.dimensions;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getElementType()
+	 */
+	public ITypeBinding getElementType() {
+		if (this.binding != null) {
+			if (this.binding.isArrayType()) {
+				ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+				return new RecoveredTypeBinding(this.resolver, arrayBinding.leafComponentType);
+			} else {
+				return new RecoveredTypeBinding(this.resolver, this.binding);
+			}
+		}
+		if (this.innerTypeBinding != null) {
+			return this.innerTypeBinding.getElementType();
+		}
+		if (this.currentType!= null && this.currentType.isArrayType()) {
+			return this.resolver.getTypeBinding(((ArrayType) this.currentType).getElementType());
+		}
+		if (this.variableDeclaration != null && this.variableDeclaration.getExtraDimensions() != 0) {
+			return this.resolver.getTypeBinding(getType());
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getErasure()
+	 */
+	public ITypeBinding getErasure() {
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getInterfaces()
+	 */
+	public ITypeBinding[] getInterfaces() {
+		return TypeBinding.NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getModifiers()
+	 */
+	public int getModifiers() {
+		return Modifier.NONE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getName()
+	 */
+	public String getName() {
+		char[] brackets = new char[this.dimensions * 2];
+		for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+			brackets[i] = ']';
+			brackets[i - 1] = '[';
+		}
+		StringBuffer buffer = new StringBuffer(getInternalName());
+		buffer.append(brackets);
+		return String.valueOf(buffer);
+	}
+
+	private String getInternalName() {
+		if (this.innerTypeBinding != null) {
+			return this.innerTypeBinding.getInternalName();
+		}
+		ReferenceBinding referenceBinding = getReferenceBinding();
+		if (referenceBinding != null) {
+			return new String(referenceBinding.compoundName[referenceBinding.compoundName.length - 1]);
+		}
+		return getTypeNameFrom(getType());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getPackage()
+	 */
+	public IPackageBinding getPackage() {
+		if (this.binding != null) {
+			switch (this.binding.kind()) {
+				case Binding.BASE_TYPE :
+				case Binding.ARRAY_TYPE :
+				case Binding.TYPE_PARAMETER : // includes capture scenario
+				case Binding.WILDCARD_TYPE :
+				case Binding.INTERSECTION_TYPE:
+					return null;
+			}
+			IPackageBinding packageBinding = this.resolver.getPackageBinding(this.binding.getPackage());
+			if (packageBinding != null) return packageBinding;
+		}
+		if (this.innerTypeBinding != null && this.dimensions > 0) {
+			return null;
+		}
+		CompilationUnitScope scope = this.resolver.scope();
+		if (scope != null) {
+			return this.resolver.getPackageBinding(scope.getCurrentPackage());
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getQualifiedName()
+	 */
+	public String getQualifiedName() {
+		ReferenceBinding referenceBinding = getReferenceBinding();
+		if (referenceBinding != null) {
+			StringBuffer buffer = new StringBuffer();
+			char[] brackets = new char[this.dimensions * 2];
+			for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) {
+				brackets[i] = ']';
+				brackets[i - 1] = '[';
+			}
+			buffer.append(CharOperation.toString(referenceBinding.compoundName));
+			buffer.append(brackets);
+			return String.valueOf(buffer);
+		} else {
+			return getName();
+		}
+	}
+
+	private ReferenceBinding getReferenceBinding() {
+		if (this.binding != null) {
+			if (this.binding.isArrayType()) {
+				ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+				if (arrayBinding.leafComponentType instanceof ReferenceBinding) {
+					return (ReferenceBinding) arrayBinding.leafComponentType;
+				}
+			} else if (this.binding instanceof ReferenceBinding) {
+				return (ReferenceBinding) this.binding;
+			}
+		} else if (this.innerTypeBinding != null) {
+			return this.innerTypeBinding.getReferenceBinding();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getSuperclass()
+	 */
+	public ITypeBinding getSuperclass() {
+		if (getQualifiedName().equals("java.lang.Object")) {	//$NON-NLS-1$
+			return null;
+		}
+		return this.resolver.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeArguments()
+	 */
+	public ITypeBinding[] getTypeArguments() {
+		if (this.binding != null) {
+			return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
+		}
+		if (this.typeArguments != null) {
+			return this.typeArguments;
+		}
+
+		if (this.innerTypeBinding != null) {
+			return this.innerTypeBinding.getTypeArguments();
+		}
+
+		if (this.currentType.isParameterizedType()) {
+			ParameterizedType parameterizedType = (ParameterizedType) this.currentType;
+			List typeArgumentsList = parameterizedType.typeArguments();
+			int size = typeArgumentsList.size();
+			ITypeBinding[] temp = new ITypeBinding[size];
+			for (int i = 0; i < size; i++) {
+				ITypeBinding currentTypeBinding = ((Type) typeArgumentsList.get(i)).resolveBinding();
+				if (currentTypeBinding == null) {
+					return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
+				}
+				temp[i] = currentTypeBinding;
+			}
+			return this.typeArguments = temp;
+		}
+		return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeBounds()
+	 */
+	public ITypeBinding[] getTypeBounds() {
+		return TypeBinding.NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeDeclaration()
+	 */
+	public ITypeBinding getTypeDeclaration() {
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeParameters()
+	 */
+	public ITypeBinding[] getTypeParameters() {
+		return TypeBinding.NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getWildcard()
+	 */
+	public ITypeBinding getWildcard() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isAnnotation()
+	 */
+	public boolean isAnnotation() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isAnonymous()
+	 */
+	public boolean isAnonymous() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isArray()
+	 */
+	public boolean isArray() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isAssignmentCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
+	 */
+	public boolean isAssignmentCompatible(ITypeBinding typeBinding) {
+		if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
+			return true;
+		}
+		// since recovered binding are not unique isEqualTo is required
+		return isEqualTo(typeBinding);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isCapture()
+	 */
+	public boolean isCapture() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isCastCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
+	 */
+	public boolean isCastCompatible(ITypeBinding typeBinding) {
+		if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
+			return true;
+		}
+		// since recovered binding are not unique isEqualTo is required
+		return isEqualTo(typeBinding);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isClass()
+	 */
+	public boolean isClass() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isEnum()
+	 */
+	public boolean isEnum() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isFromSource()
+	 */
+	public boolean isFromSource() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isGenericType()
+	 */
+	public boolean isGenericType() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isInterface()
+	 */
+	public boolean isInterface() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isLocal()
+	 */
+	public boolean isLocal() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isMember()
+	 */
+	public boolean isMember() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isNested()
+	 */
+	public boolean isNested() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isNullType()
+	 */
+	public boolean isNullType() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isParameterizedType()
+	 */
+	public boolean isParameterizedType() {
+		if (this.innerTypeBinding != null) {
+			return this.innerTypeBinding.isParameterizedType();
+		}
+		if (this.currentType != null) {
+			return this.currentType.isParameterizedType();
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isPrimitive()
+	 */
+	public boolean isPrimitive() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isRawType()
+	 */
+	public boolean isRawType() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isSubTypeCompatible(org.eclipse.jdt.core.dom.ITypeBinding)
+	 */
+	public boolean isSubTypeCompatible(ITypeBinding typeBinding) {
+		if ("java.lang.Object".equals(typeBinding.getQualifiedName())) { //$NON-NLS-1$
+			return true;
+		}
+		// since recovered binding are not unique isEqualTo is required
+		return isEqualTo(typeBinding);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isTopLevel()
+	 */
+	public boolean isTopLevel() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isTypeVariable()
+	 */
+	public boolean isTypeVariable() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isUpperbound()
+	 */
+	public boolean isUpperbound() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isWildcardType()
+	 */
+	public boolean isWildcardType() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#getAnnotations()
+	 */
+	public IAnnotationBinding[] getAnnotations() {
+		return AnnotationBinding.NoAnnotations;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#getJavaElement()
+	 */
+	public IJavaElement getJavaElement() {
+		IPackageBinding packageBinding = getPackage();
+		if (packageBinding != null) {
+			final IJavaElement javaElement = packageBinding.getJavaElement();
+			if (javaElement != null && javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+				// best effort: we don't know if the recovered binding is a binary or source binding, so go with a simple source type
+				return ((PackageFragment) javaElement).getCompilationUnit(getInternalName() + SuffixConstants.SUFFIX_STRING_java).getType(this.getName());
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+	 */
+	public String getKey() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Recovered#"); //$NON-NLS-1$
+		if (this.innerTypeBinding != null) {
+			buffer.append("innerTypeBinding") //$NON-NLS-1$
+			      .append(this.innerTypeBinding.getKey());
+		} else if (this.currentType != null) {
+			buffer.append("currentType") //$NON-NLS-1$
+			      .append(this.currentType.toString());
+		} else if (this.binding != null) {
+			buffer.append("typeBinding") //$NON-NLS-1$
+				  .append(this.binding.computeUniqueKey());
+		} else if (this.variableDeclaration != null) {
+			buffer
+				.append("variableDeclaration") //$NON-NLS-1$
+				.append(this.variableDeclaration.getClass())
+				.append(this.variableDeclaration.getName().getIdentifier())
+				.append(this.variableDeclaration.getExtraDimensions());
+		}
+		buffer.append(getDimensions());
+		if (this.typeArguments != null) {
+			buffer.append('<');
+			for (int i = 0, max = this.typeArguments.length; i < max; i++) {
+				if (i != 0) {
+					buffer.append(',');
+				}
+				buffer.append(this.typeArguments[i].getKey());
+			}
+			buffer.append('>');
+		}
+		return String.valueOf(buffer);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#getKind()
+	 */
+	public int getKind() {
+		return IBinding.TYPE;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isEqualTo(org.eclipse.jdt.core.dom.IBinding)
+	 */
+	public boolean isEqualTo(IBinding other) {
+		if (!other.isRecovered() || other.getKind() != IBinding.TYPE) return false;
+		return getKey().equals(other.getKey());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return false;
+	}
+
+	private String getTypeNameFrom(Type type) {
+		if (type == null) return Util.EMPTY_STRING;
+		switch(type.getNodeType0()) {
+			case ASTNode.ARRAY_TYPE :
+				ArrayType arrayType = (ArrayType) type;
+				type = arrayType.getElementType();
+				return getTypeNameFrom(type);
+			case ASTNode.PARAMETERIZED_TYPE :
+				ParameterizedType parameterizedType = (ParameterizedType) type;
+				StringBuffer buffer = new StringBuffer(getTypeNameFrom(parameterizedType.getType()));
+				ITypeBinding[] tArguments = getTypeArguments();
+				final int typeArgumentsLength = tArguments.length;
+				if (typeArgumentsLength != 0) {
+					buffer.append('<');
+					for (int i = 0; i < typeArgumentsLength; i++) {
+						if (i > 0) {
+							buffer.append(',');
+						}
+						buffer.append(tArguments[i].getName());
+					}
+					buffer.append('>');
+				}
+				return String.valueOf(buffer);
+			case ASTNode.PRIMITIVE_TYPE :
+				PrimitiveType primitiveType = (PrimitiveType) type;
+				return primitiveType.getPrimitiveTypeCode().toString();
+			case ASTNode.QUALIFIED_TYPE :
+				QualifiedType qualifiedType = (QualifiedType) type;
+				return qualifiedType.getName().getIdentifier();
+			case ASTNode.PACKAGE_QUALIFIED_TYPE :
+				PackageQualifiedType packageQualifiedType = (PackageQualifiedType) type;
+				return packageQualifiedType.getName().getIdentifier();
+			case ASTNode.SIMPLE_TYPE :
+				SimpleType simpleType = (SimpleType) type;
+				Name name = simpleType.getName();
+				if (name.isQualifiedName()) {
+					QualifiedName qualifiedName = (QualifiedName) name;
+					return qualifiedName.getName().getIdentifier();
+				}
+				return ((SimpleName) name).getIdentifier();
+		}
+		return Util.EMPTY_STRING;
+	}
+
+	private Type getType() {
+		if (this.currentType != null) {
+			return this.currentType;
+		}
+		if (this.variableDeclaration == null) return null;
+		switch(this.variableDeclaration.getNodeType()) {
+			case ASTNode.SINGLE_VARIABLE_DECLARATION :
+				SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) this.variableDeclaration;
+				return singleVariableDeclaration.getType();
+			default :
+				// this is a variable declaration fragment
+				ASTNode parent = this.variableDeclaration.getParent();
+				switch(parent.getNodeType()) {
+					case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
+						VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) parent;
+						return variableDeclarationExpression.getType();
+					case ASTNode.VARIABLE_DECLARATION_STATEMENT :
+						VariableDeclarationStatement statement = (VariableDeclarationStatement) parent;
+						return statement.getType();
+					case ASTNode.FIELD_DECLARATION :
+						FieldDeclaration fieldDeclaration  = (FieldDeclaration) parent;
+						return fieldDeclaration.getType();
+				}
+		}
+		return null; // should not happen
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredVariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredVariableBinding.java
new file mode 100644
index 0000000..ba512fc
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredVariableBinding.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * This class represents the recovered binding for a variable
+ */
+class RecoveredVariableBinding implements IVariableBinding {
+
+	private VariableDeclaration variableDeclaration;
+	private BindingResolver resolver;
+
+	RecoveredVariableBinding(BindingResolver resolver, VariableDeclaration variableDeclaration) {
+		this.resolver = resolver;
+		this.variableDeclaration = variableDeclaration;
+	}
+	public Object getConstantValue() {
+		return null;
+	}
+
+	public ITypeBinding getDeclaringClass() {
+		ASTNode parent = this.variableDeclaration.getParent();
+		while (parent != null && parent.getNodeType() != ASTNode.TYPE_DECLARATION) {
+			parent = parent.getParent();
+		}
+		if (parent != null) {
+			return ((TypeDeclaration) parent).resolveBinding();
+		}
+		return null;
+	}
+
+	public IMethodBinding getDeclaringMethod() {
+		ASTNode parent = this.variableDeclaration.getParent();
+		while (parent != null && parent.getNodeType() != ASTNode.METHOD_DECLARATION) {
+			parent = parent.getParent();
+		}
+		if (parent != null) {
+			return ((MethodDeclaration) parent).resolveBinding();
+		}
+		return null;
+	}
+
+	public String getName() {
+		return this.variableDeclaration.getName().getIdentifier();
+	}
+
+	public ITypeBinding getType() {
+		return this.resolver.getTypeBinding(this.variableDeclaration);
+	}
+
+	public IVariableBinding getVariableDeclaration() {
+		return this;
+	}
+
+	public int getVariableId() {
+		return 0;
+	}
+
+	public boolean isEnumConstant() {
+		return false;
+	}
+
+	public boolean isField() {
+		return this.variableDeclaration.getParent() instanceof FieldDeclaration;
+	}
+
+	public boolean isParameter() {
+		return this.variableDeclaration instanceof SingleVariableDeclaration;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		return AnnotationBinding.NoAnnotations;
+	}
+
+	public IJavaElement getJavaElement() {
+		return null;
+	}
+
+	public String getKey() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Recovered#"); //$NON-NLS-1$
+		if (this.variableDeclaration != null) {
+			buffer
+				.append("variableDeclaration") //$NON-NLS-1$
+				.append(this.variableDeclaration.getClass())
+				.append(this.variableDeclaration.getName().getIdentifier())
+				.append(this.variableDeclaration.getExtraDimensions());
+		}
+		return String.valueOf(buffer);
+	}
+
+	public int getKind() {
+		return IBinding.VARIABLE;
+	}
+
+	public int getModifiers() {
+		return 0;
+	}
+
+	public boolean isDeprecated() {
+		return false;
+	}
+
+	public boolean isEqualTo(IBinding binding) {
+		if (binding.isRecovered() && binding.getKind() == IBinding.VARIABLE) {
+			return getKey().equals(binding.getKey());
+		}
+		return false;
+	}
+
+	public boolean isRecovered() {
+		return true;
+	}
+
+	public boolean isSynthetic() {
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java
new file mode 100644
index 0000000..046e81b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Return statement AST node type.
+ *
+ * <pre>
+ * ReturnStatement:
+ *    <b>return</b> [ Expression ] <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ReturnStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ReturnStatement.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ReturnStatement.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalExpression = null;
+
+	/**
+	 * Creates a new AST node for a return statement owned by the
+	 * given AST. By default, the statement has no expression.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ReturnStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return RETURN_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ReturnStatement result = new ReturnStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this return statement, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getExpression() {
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Sets or clears the expression of this return statement.
+	 *
+	 * @param expression the expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalExpression == null ? 0 : getExpression().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java
new file mode 100644
index 0000000..b8cd48f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * AST node for a simple name. A simple name is an identifier other than
+ * a keyword, boolean literal ("true", "false") or null literal ("null").
+ * <pre>
+ * SimpleName:
+ *     Identifier
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SimpleName extends Name {
+
+	/**
+	 * The "identifier" structural property of this node type (type: {@link String}).
+	 *
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor IDENTIFIER_PROPERTY =
+		new SimplePropertyDescriptor(SimpleName.class, "identifier", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(SimpleName.class, propertyList);
+		addProperty(IDENTIFIER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * An unspecified (but externally observable) legal Java identifier.
+	 */
+	private static final String MISSING_IDENTIFIER = "MISSING";//$NON-NLS-1$
+
+	/**
+	 * The identifier; defaults to a unspecified, legal Java identifier.
+	 */
+	private String identifier = MISSING_IDENTIFIER;
+
+	/**
+	 * Creates a new AST node for a simple name owned by the given AST.
+	 * The new node has an unspecified, legal Java identifier.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SimpleName(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == IDENTIFIER_PROPERTY) {
+			if (get) {
+				return getIdentifier();
+			} else {
+				setIdentifier((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SIMPLE_NAME;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SimpleName result = new SimpleName(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setIdentifier(getIdentifier());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns this node's identifier.
+	 *
+	 * @return the identifier of this node
+	 */
+	public String getIdentifier() {
+		return this.identifier;
+	}
+
+	/**
+	 * Sets the identifier of this node to the given value.
+	 * The identifier should be legal according to the rules
+	 * of the Java language. Note that keywords are not legal
+	 * identifiers.
+	 * <p>
+	 * Note that the list of keywords may depend on the version of the
+	 * language (determined when the AST object was created).
+	 * </p>
+	 *
+	 * @param identifier the identifier of this node
+	 * @exception IllegalArgumentException if the identifier is invalid
+	 */
+	public void setIdentifier(String identifier) {
+		// update internalSetIdentifier if this is changed
+		if (identifier == null) {
+			throw new IllegalArgumentException();
+		}
+		Scanner scanner = this.ast.scanner;
+		long sourceLevel = scanner.sourceLevel;
+		long complianceLevel = scanner.complianceLevel;
+
+		try {
+			scanner.sourceLevel = ClassFileConstants.JDK1_3;
+			scanner.complianceLevel = ClassFileConstants.JDK1_5;
+			char[] source = identifier.toCharArray();
+			scanner.setSource(source);
+			final int length = source.length;
+			scanner.resetTo(0, length - 1);
+			try {
+				int tokenType = scanner.scanIdentifier();
+				if (tokenType != TerminalTokens.TokenNameIdentifier) {
+					throw new IllegalArgumentException();
+				}
+				if (scanner.currentPosition != length) {
+					// this is the case when there is only one identifier see 87849
+					throw new IllegalArgumentException();
+				}
+			} catch(InvalidInputException e) {
+				throw new IllegalArgumentException();
+			}
+		} finally {
+			this.ast.scanner.sourceLevel = sourceLevel;
+			this.ast.scanner.complianceLevel = complianceLevel;
+		}
+		preValueChange(IDENTIFIER_PROPERTY);
+		this.identifier = identifier;
+		postValueChange(IDENTIFIER_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setIdentifier(String) that doesn't do any validation.
+	 */
+	void internalSetIdentifier(String ident) {
+		preValueChange(IDENTIFIER_PROPERTY);
+		this.identifier = ident;
+		postValueChange(IDENTIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this simple name represents a name that is being defined,
+	 * as opposed to one being referenced. The following positions are considered
+	 * ones where a name is defined:
+	 * <ul>
+	 * <li>The type name in a <code>TypeDeclaration</code> node.</li>
+	 * <li>The method name in a <code>MethodDeclaration</code> node
+	 * providing <code>isConstructor</code> is <code>false</code>.</li>
+	 * <li>The variable name in any type of <code>VariableDeclaration</code>
+	 * node.</li>
+	 * <li>The enum type name in a <code>EnumDeclaration</code> node.</li>
+	 * <li>The enum constant name in an <code>EnumConstantDeclaration</code>
+	 * node.</li>
+	 * <li>The variable name in an <code>EnhancedForStatement</code>
+	 * node.</li>
+	 * <li>The type variable name in a <code>TypeParameter</code>
+	 * node.</li>
+	 * <li>The type name in an <code>AnnotationTypeDeclaration</code> node.</li>
+	 * <li>The member name in an <code>AnnotationTypeMemberDeclaration</code> node.</li>
+	 * </ul>
+	 * <p>
+	 * Note that this is a convenience method that simply checks whether
+	 * this node appears in the declaration position relative to its parent.
+	 * It always returns <code>false</code> if this node is unparented.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this node declares a name, and
+	 *    <code>false</code> otherwise
+	 */
+	public boolean isDeclaration() {
+		StructuralPropertyDescriptor d = getLocationInParent();
+		if (d == null) {
+			// unparented node
+			return false;
+		}
+		ASTNode parent = getParent();
+		if (parent instanceof TypeDeclaration) {
+			return (d == TypeDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof MethodDeclaration) {
+			MethodDeclaration p = (MethodDeclaration) parent;
+			// could be the name of the method or constructor
+			return !p.isConstructor() && (d == MethodDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof SingleVariableDeclaration) {
+			return (d == SingleVariableDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof VariableDeclarationFragment) {
+			return (d == VariableDeclarationFragment.NAME_PROPERTY);
+		}
+		if (parent instanceof EnumDeclaration) {
+			return (d == EnumDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof EnumConstantDeclaration) {
+			return (d == EnumConstantDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof TypeParameter) {
+			return (d == TypeParameter.NAME_PROPERTY);
+		}
+		if (parent instanceof AnnotationTypeDeclaration) {
+			return (d == AnnotationTypeDeclaration.NAME_PROPERTY);
+		}
+		if (parent instanceof AnnotationTypeMemberDeclaration) {
+			return (d == AnnotationTypeMemberDeclaration.NAME_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on Name.
+	 */
+	void appendName(StringBuffer buffer) {
+		buffer.append(getIdentifier());
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NAME_NODE_SIZE + 2 * 4;
+		if (this.identifier != MISSING_IDENTIFIER) {
+			// everything but our missing id costs
+			size += stringSize(this.identifier);
+		}
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java
new file mode 100644
index 0000000..b9038b1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Descriptor for a simple property of an AST node.
+ * A simple property is one whose value is a
+ * primitive type (such as <code>int</code> or <code>boolean</code>)
+ * or some simple value type (such as <code>String</code> or
+ * <code>InfixExpression.Operator</code>).
+ *
+ * @see org.eclipse.jdt.core.dom.ASTNode#getStructuralProperty(StructuralPropertyDescriptor)
+ * @see org.eclipse.jdt.core.dom.ASTNode#setStructuralProperty(StructuralPropertyDescriptor, Object)
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class SimplePropertyDescriptor extends StructuralPropertyDescriptor {
+
+	/**
+	 * Value type. For example, for a node type like
+	 * SingleVariableDeclaration, the modifiers property is int.class
+	 */
+	private final Class valueType;
+
+	/**
+	 * Indicates whether a value is mandatory. A property value is allowed
+	 * to be <code>null</code> only if it is not mandatory.
+	 */
+	private final boolean mandatory;
+
+	/**
+	 * Creates a new simple property descriptor with the given property id.
+	 * Note that this constructor is declared package-private so that
+	 * property descriptors can only be created by the AST
+	 * implementation.
+	 *
+	 * @param nodeClass concrete AST node type that owns this property
+	 * @param propertyId the property id
+	 * @param valueType the value type of this property
+	 * @param mandatory <code>true</code> if the property is mandatory,
+	 * and <code>false</code> if it is may be <code>null</code>
+	 */
+	SimplePropertyDescriptor(Class nodeClass, String propertyId, Class valueType, boolean mandatory) {
+		super(nodeClass, propertyId);
+		if (valueType == null || ASTNode.class.isAssignableFrom(valueType)) {
+			throw new IllegalArgumentException();
+		}
+		this.valueType = valueType;
+		this.mandatory = mandatory;
+	}
+
+	/**
+	 * Returns the value type of this property.
+	 * <p>
+	 * For example, for a node type like SingleVariableDeclaration,
+	 * the "modifiers" property returns <code>int.class</code>.
+	 * </p>
+	 *
+	 * @return the value type of the property
+	 */
+	public Class getValueType() {
+		return this.valueType;
+	}
+
+	/**
+	 * Returns whether this property is mandatory. A property value
+	 * is not allowed to be <code>null</code> if it is mandatory.
+	 *
+	 * @return <code>true</code> if the property is mandatory,
+	 * and <code>false</code> if it is may be <code>null</code>
+	 */
+	public boolean isMandatory() {
+		return this.mandatory;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java
new file mode 100644
index 0000000..91818f4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for a named class type, a named interface type, or a type variable.
+ * <pre>
+ * SimpleType:
+ *    { Annotation } TypeName
+ * </pre>
+ * <p>
+ * This kind of node is used to convert a name ({@link Name}) into a type
+ * ({@link Type}) by wrapping it.
+ * </p>
+ *
+ * In JLS8 and later, the SimpleType may have optional annotations.
+ * If annotations are present, then the name must be a {@link SimpleName}.
+ * Annotated qualified names are represented as {@link QualifiedType} or {@link PackageQualifiedType}.
+ * 
+ * @see QualifiedType
+ * @see PackageQualifiedType
+ * 
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SimpleType extends AnnotatableType {
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(SimpleType.class);
+	
+	/**
+	 * The "name" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(SimpleType.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(SimpleType.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(3);
+		createPropertyList(SimpleType.class, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The type name node; lazily initialized; defaults to a type with
+	 * an unspecified, but legal, name.
+	 */
+	private Name typeName = null;
+
+	/**
+	 * Creates a new unparented node for a simple type owned by the given AST.
+	 * By default, an unspecified, but legal, name.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SimpleType(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SIMPLE_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SimpleType result = new SimpleType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setName((Name) (getName()).clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the name of this simple type.
+	 *
+	 * @return the name of this simple type
+	 */
+	public Name getName() {
+		if (this.typeName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeName == null) {
+					preLazyInit();
+					this.typeName = new SimpleName(this.ast);
+					postLazyInit(this.typeName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.typeName;
+	}
+
+	/**
+	 * Sets the name of this simple type to the given name.
+	 *
+	 * @param typeName the new name of this simple type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(Name typeName) {
+		if (typeName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.typeName;
+		preReplaceChild(oldChild, typeName, NAME_PROPERTY);
+		this.typeName = typeName;
+		postReplaceChild(oldChild, typeName, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.annotations == null ? 0 : this.annotations.listSize())
+			+ (this.typeName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java
new file mode 100644
index 0000000..ddee30e
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Single member annotation node (added in JLS3 API). The single member annotation
+ * "@foo(bar)" is equivalent to the normal annotation "@foo(value=bar)".
+ * <p>
+ * <pre>
+ * SingleMemberAnnotation:
+ *   <b>@</b> TypeName <b>(</b> Expression  <b>)</b>
+ * </pre>
+ * Within annotations, only certain kinds of expressions are meaningful,
+ * including other annotations.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class SingleMemberAnnotation extends Annotation {
+
+	/**
+	 * The "typeName" structural property of this node type (child type: {@link Name}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY =
+		internalTypeNamePropertyFactory(SingleMemberAnnotation.class);
+
+	/**
+	 * The "value" structural property of this node type (child type: {@link Expression}).
+	 */
+	public static final ChildPropertyDescriptor VALUE_PROPERTY =
+		new ChildPropertyDescriptor(SingleMemberAnnotation.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SingleMemberAnnotation.class, propertyList);
+		addProperty(TYPE_NAME_PROPERTY, propertyList);
+		addProperty(VALUE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The value; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression value = null;
+
+	/**
+	 * Creates a new unparented normal annotation node owned
+	 * by the given AST.  By default, the annotation has an
+	 * unspecified type name and an unspecified value.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SingleMemberAnnotation(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_NAME_PROPERTY) {
+			if (get) {
+				return getTypeName();
+			} else {
+				setTypeName((Name) child);
+				return null;
+			}
+		}
+		if (property == VALUE_PROPERTY) {
+			if (get) {
+				return getValue();
+			} else {
+				setValue((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalTypeNameProperty() {
+		return TYPE_NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SINGLE_MEMBER_ANNOTATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SingleMemberAnnotation result = new SingleMemberAnnotation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setTypeName((Name) ASTNode.copySubtree(target, getTypeName()));
+		result.setValue((Expression) ASTNode.copySubtree(target, getValue()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getTypeName());
+			acceptChild(visitor, getValue());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the value of this annotation.
+	 *
+	 * @return the value node
+	 */
+	public Expression getValue() {
+		if (this.value == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.value == null) {
+					preLazyInit();
+					this.value = new SimpleName(this.ast);
+					postLazyInit(this.value, VALUE_PROPERTY);
+				}
+			}
+		}
+		return this.value;
+	}
+
+	/**
+	 * Sets the value of this annotation.
+	 *
+	 * @param value the new value
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setValue(Expression value) {
+		if (value == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.value;
+		preReplaceChild(oldChild, value, VALUE_PROPERTY);
+		this.value = value;
+		postReplaceChild(oldChild, value, VALUE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.typeName == null ? 0 : getTypeName().treeSize())
+			+ (this.value == null ? 0 : getValue().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java
new file mode 100644
index 0000000..1045a6a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java
@@ -0,0 +1,643 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Single variable declaration AST node type. Single variable
+ * declaration nodes are used in a limited number of places, including formal
+ * parameter lists and catch clauses. They are not used for field declarations
+ * and regular variable declaration statements.
+ * <pre>
+ * SingleVariableDeclaration:
+ *    { ExtendedModifier } Type {Annotation} [ <b>...</b> ] Identifier { ExtraDimension } [ <b>=</b> Expression ]
+ * </pre>
+ * <p>
+ * Note: There's currently no construct in the Java language that allows an initializer on a SingleVariableDeclaration.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SingleVariableDeclaration extends VariableDeclaration {
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		new SimplePropertyDescriptor(SingleVariableDeclaration.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+			new ChildPropertyDescriptor(SingleVariableDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "varargsAnnotations" structural property of variable arguments of this node type (element type: {@link Annotation})
+	 * (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor VARARGS_ANNOTATIONS_PROPERTY =
+			new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "varargsAnnotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "varargs" structural property of this node type (type: {@link Boolean}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final SimplePropertyDescriptor VARARGS_PROPERTY =
+		new SimplePropertyDescriptor(SingleVariableDeclaration.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+			internalNamePropertyFactory(SingleVariableDeclaration.class);
+
+	/**
+	 * The "extraDimensions" structural property of this node type (type: {@link Integer})
+	 * (before JLS8 only).
+	 *
+	 * @since 3.0
+	 * @deprecated In JLS8 and later, use {@link SingleVariableDeclaration#EXTRA_DIMENSIONS2_PROPERTY} instead.
+	 */
+	public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY =
+			internalExtraDimensionsPropertyFactory(SingleVariableDeclaration.class);
+
+	/**
+	 * The "extraDimensions2" structural property of this node type (element type: {@link ExtraDimension}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor EXTRA_DIMENSIONS2_PROPERTY =
+			internalExtraDimensions2PropertyFactory(SingleVariableDeclaration.class);
+
+	/**
+	 * The "initializer" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor INITIALIZER_PROPERTY =
+			internalInitializerPropertyFactory(SingleVariableDeclaration.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(6);
+		createPropertyList(SingleVariableDeclaration.class, propertyList);
+		addProperty(MODIFIERS_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
+		addProperty(INITIALIZER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(7);
+		createPropertyList(SingleVariableDeclaration.class, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(VARARGS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
+		addProperty(INITIALIZER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(8);
+		createPropertyList(SingleVariableDeclaration.class, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(VARARGS_ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(VARARGS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList);
+		addProperty(INITIALIZER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else if (apiLevel < AST.JLS8) {
+			return PROPERTY_DESCRIPTORS_3_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The extended modifiers (element type: {@link IExtendedModifier}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 *
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList modifiers = null;
+
+	/**
+	 * The modifiers; bit-wise or of Modifier flags.
+	 * Defaults to none. Not used in 3.0.
+	 */
+	private int modifierFlags = Modifier.NONE;
+
+	/**
+	 * The type; lazily initialized; defaults to an unspecified,
+	 * legal type.
+	 */
+	private Type type = null;
+
+	/**
+	 * The type annotations on the varargs token (element type: {@link Annotation}).
+	 * Null before JLS8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private ASTNode.NodeList varargsAnnotations = null;
+
+	/**
+	 * Indicates the last parameter of a variable arity method;
+	 * defaults to false.
+	 *
+	 * @since 3.1
+	 */
+	private boolean variableArity = false;
+
+	/**
+	 * Creates a new AST node for a variable declaration owned by the given
+	 * AST. By default, the variable declaration has: no modifiers, an
+	 * unspecified (but legal) type, an unspecified (but legal) variable name,
+	 * 0 dimensions after the variable; no initializer; not variable arity.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SingleVariableDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
+			if (ast.apiLevel >= AST.JLS8) {
+				this.varargsAnnotations = new ASTNode.NodeList(VARARGS_ANNOTATIONS_PROPERTY);
+			}
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final ChildPropertyDescriptor internalNameProperty() {
+		return NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final SimplePropertyDescriptor internalExtraDimensionsProperty() {
+		return EXTRA_DIMENSIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalExtraDimensions2Property() {
+		return EXTRA_DIMENSIONS2_PROPERTY;
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final ChildPropertyDescriptor internalInitializerProperty() {
+		return INITIALIZER_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				setModifiers(value);
+				return 0;
+			}
+		}
+		if (property == EXTRA_DIMENSIONS_PROPERTY) {
+			if (get) {
+				return getExtraDimensions();
+			} else {
+				internalSetExtraDimensions(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == VARARGS_PROPERTY) {
+			if (get) {
+				return isVarargs();
+			} else {
+				setVarargs(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == INITIALIZER_PROPERTY) {
+			if (get) {
+				return getInitializer();
+			} else {
+				setInitializer((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == VARARGS_ANNOTATIONS_PROPERTY) {
+			return varargsAnnotations();
+		}
+		if (property == EXTRA_DIMENSIONS2_PROPERTY) {
+			return extraDimensions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SINGLE_VARIABLE_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SingleVariableDeclaration result = new SingleVariableDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.setModifiers(getModifiers());
+		} else {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+			result.setVarargs(isVarargs());
+		}
+		result.setType((Type) getType().clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.varargsAnnotations().addAll(
+					ASTNode.copySubtrees(target, varargsAnnotations()));
+		}
+		result.setName((SimpleName) getName().clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.extraDimensions().addAll(
+					ASTNode.copySubtrees(target, this.extraDimensions()));
+		} else {
+			result.internalSetExtraDimensions(getExtraDimensions());
+		}
+		result.setInitializer(
+				(Expression) ASTNode.copySubtree(target, getInitializer()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.modifiers);
+			}
+			acceptChild(visitor, getType());
+			if (this.ast.apiLevel >= AST.JLS8 && isVarargs()) {
+				acceptChildren(visitor, this.varargsAnnotations);
+			}
+			acceptChild(visitor, getName());
+			if (this.ast.apiLevel >= AST.JLS8){
+				acceptChildren(visitor, this.extraDimensions);
+			}
+			acceptChild(visitor, getInitializer());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of modifiers and annotations
+	 * of this declaration (added in JLS3 API).
+	 * <p>
+	 * Note that the final modifier is the only meaningful modifier for local
+	 * variable and formal parameter declarations.
+	 * </p>
+	 *
+	 * @return the live list of modifiers and annotations
+	 *    (element type: {@link IExtendedModifier})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List modifiers() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		return this.modifiers;
+	}
+
+	/**
+	 * Returns the modifiers explicitly specified on this declaration.
+	 * <p>
+	 * In the JLS3 API, this method is a convenience method that
+	 * computes these flags from <code>modifiers()</code>.
+	 * </p>
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see Modifier
+	 */
+	public int getModifiers() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.modifiers == null) {
+			// JLS2 behavior - bona fide property
+			return this.modifierFlags;
+		} else {
+			// JLS3 behavior - convenient method
+			// performance could be improved by caching computed flags
+			// but this would require tracking changes to this.modifiers
+			int computedModifierFlags = Modifier.NONE;
+			for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
+				Object x = it.next();
+				if (x instanceof Modifier) {
+					computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
+				}
+			}
+			return computedModifierFlags;
+		}
+	}
+
+	/**
+	 * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
+	 * <p>
+	 * The following modifiers are meaningful for fields: public, private, protected,
+	 * static, final, volatile, and transient. For local variable and formal
+	 * parameter declarations, the only meaningful modifier is final.
+	 * </p>
+	 *
+	 * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
+	 */
+	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
+	    supportedOnlyIn2();
+		preValueChange(MODIFIERS_PROPERTY);
+		this.modifierFlags = pmodifiers;
+		postValueChange(MODIFIERS_PROPERTY);
+	}
+
+	/**
+	 * Returns the type of the variable declared in this variable declaration,
+	 * exclusive of any extra array dimensions.
+	 *
+	 * @return the type
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type of the variable declared in this variable declaration to
+	 * the given type, exclusive of any extra array dimensions.
+	 *
+	 * @param type the new type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this declaration declares the last parameter of
+	 * a variable arity method (added in JLS3 API).
+	 * <p>
+	 * Note that the binding for the type <code>Foo</code>in the vararg method
+	 * declaration <code>void fun(Foo... args)</code> is always for the type as
+	 * written; i.e., the type binding for <code>Foo</code>. However, if you
+	 * navigate from the method declaration to its method binding to the
+	 * type binding for its last parameter, the type binding for the vararg
+	 * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+	 * the way vararg methods get compiled.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is a variable arity parameter declaration,
+	 *    and <code>false</code> otherwise
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public boolean isVarargs() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		return this.variableArity;
+	}
+
+	/**
+	 * Sets whether this declaration declares the last parameter of
+	 * a variable arity method (added in JLS3 API).
+	 *
+	 * @param variableArity <code>true</code> if this is a variable arity
+	 *    parameter declaration, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public void setVarargs(boolean variableArity) {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		preValueChange(VARARGS_PROPERTY);
+		this.variableArity = variableArity;
+		postValueChange(VARARGS_PROPERTY);
+	}
+
+	/**
+	 * Returns the ordered list of annotations on the varargs token (added in JLS8 API).
+	 *
+	 * @return the list of annotations on the varargs token (element type: {@link Annotation})
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public List varargsAnnotations() {
+		if (this.varargsAnnotations == null) {
+			unsupportedIn2_3_4(); 
+		}
+		return this.varargsAnnotations;
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 9 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ (this.varargsAnnotations == null ? 0 : this.varargsAnnotations.listSize())
+			+ (this.variableName == null ? 0 : getName().treeSize())
+			+ (this.extraDimensions == null ? 0 : this.extraDimensions.listSize())
+			+ (this.optionalInitializer == null ? 0 : getInitializer().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
new file mode 100644
index 0000000..dffc912
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Abstract base class of AST nodes that represent statements.
+ * There are many kinds of statements.
+ * <p>
+ * The grammar combines both Statement and BlockStatement.</p>
+ * <pre>
+ * Statement:
+ *    {@link AssertStatement},
+ *    {@link Block},
+ *    {@link BreakStatement},
+ *    {@link ConstructorInvocation},
+ *    {@link ContinueStatement},
+ *    {@link DoStatement},
+ *    {@link EmptyStatement},
+ *    {@link EnhancedForStatement}
+ *    {@link ExpressionStatement},
+ *    {@link ForStatement},
+ *    {@link IfStatement},
+ *    {@link LabeledStatement},
+ *    {@link ReturnStatement},
+ *    {@link SuperConstructorInvocation},
+ *    {@link SwitchCase},
+ *    {@link SwitchStatement},
+ *    {@link SynchronizedStatement},
+ *    {@link ThrowStatement},
+ *    {@link TryStatement},
+ *    {@link TypeDeclarationStatement},
+ *    {@link VariableDeclarationStatement},
+ *    {@link WhileStatement}
+ * </pre>
+ *
+ * @since 2.0
+ */
+public abstract class Statement extends ASTNode {
+
+	/**
+	 * The leading comment, or <code>null</code> if none.
+	 * Defaults to none.
+	 *
+	 * @deprecated The leading comment feature was removed in 2.1.
+	 */
+	private String optionalLeadingComment = null;
+
+	/**
+	 * Creates a new AST node for a statement owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Statement(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * Returns the leading comment string, including the starting
+	 * and ending comment delimiters, and any embedded line breaks.
+	 * <p>
+	 * A leading comment is a comment that appears before the statement.
+	 * It may be either a traditional comment or an end-of-line comment.
+	 * Traditional comments must begin with "/&#42;, may contain line breaks,
+	 * and must end with "&#42;/. End-of-line comments must begin with "//",
+	 * must end with a line delimiter (as per JLS 3.7), and must not contain
+	 * line breaks.
+	 * </p>
+	 *
+	 * @return the comment string, or <code>null</code> if none
+	 * @deprecated This feature was removed in the 2.1 release because it was
+	 * only a partial, and inadequate, solution to the issue of associating
+	 * comments with statements. Furthermore, AST.parseCompilationUnit did not
+	 * associate leading comments, making this moot. Clients that need to access
+	 * comments preceding a statement should either consult the compilation
+	 * unit's {@linkplain CompilationUnit#getCommentList() comment table}
+	 * or use a scanner to reanalyze the source text immediately preceding
+	 * the statement's source range.
+	 */
+	public String getLeadingComment() {
+		return this.optionalLeadingComment;
+	}
+
+	/**
+	 * Sets or clears the leading comment string. The comment
+	 * string must include the starting and ending comment delimiters,
+	 * and any embedded linebreaks.
+	 * <p>
+	 * A leading comment is a comment that appears before the statement.
+	 * It may be either a traditional comment or an end-of-line comment.
+	 * Traditional comments must begin with "/&#42;, may contain line breaks,
+	 * and must end with "&#42;/. End-of-line comments must begin with "//"
+	 * (as per JLS 3.7), and must not contain line breaks.
+	 * </p>
+	 * <p>
+	 * Examples:
+	 * <code>
+	 * <pre>
+	 * setLeadingComment("/&#42; traditional comment &#42;/");  // correct
+	 * setLeadingComment("missing comment delimiters");  // wrong
+	 * setLeadingComment("/&#42; unterminated traditional comment ");  // wrong
+	 * setLeadingComment("/&#42; broken\n traditional comment &#42;/");  // correct
+	 * setLeadingComment("// end-of-line comment\n");  // correct
+	 * setLeadingComment("// end-of-line comment without line terminator");  // correct
+	 * setLeadingComment("// broken\n end-of-line comment\n");  // wrong
+	 * </pre>
+	 * </code>
+	 * </p>
+	 *
+	 * @param comment the comment string, or <code>null</code> if none
+	 * @exception IllegalArgumentException if the comment string is invalid
+	 * @deprecated This feature was removed in the 2.1 release because it was
+	 * only a partial, and inadequate, solution to the issue of associating
+	 * comments with statements.
+	 */
+	public void setLeadingComment(String comment) {
+		if (comment != null) {
+			char[] source = comment.toCharArray();
+			Scanner scanner = this.ast.scanner;
+			scanner.resetTo(0, source.length);
+			scanner.setSource(source);
+			try {
+				int token;
+				boolean onlyOneComment = false;
+				while ((token = scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+					switch(token) {
+						case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						case TerminalTokens.TokenNameCOMMENT_LINE :
+							if (onlyOneComment) {
+								throw new IllegalArgumentException();
+							}
+							onlyOneComment = true;
+							break;
+						default:
+							onlyOneComment = false;
+					}
+				}
+				if (!onlyOneComment) {
+					throw new IllegalArgumentException();
+				}
+			} catch (InvalidInputException e) {
+				throw new IllegalArgumentException();
+			}
+		}
+		// we do not consider the obsolete comment as a structureal property
+		// but we protect them nevertheless
+		checkModifiable();
+		this.optionalLeadingComment = comment;
+	}
+
+	/**
+	 * Copies the leading comment from the given statement.
+	 *
+	 * @param source the statement that supplies the leading comment
+	 * @since 2.1
+	 */
+	void copyLeadingComment(Statement source) {
+		setLeadingComment(source.getLeadingComment());
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 1 * 4 + stringSize(getLeadingComment());
+		return size;
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
new file mode 100644
index 0000000..c5b7b89
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * String literal nodes.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class StringLiteral extends Expression {
+
+	/**
+	 * The "escapedValue" structural property of this node type (type: {@link String}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor ESCAPED_VALUE_PROPERTY =
+		new SimplePropertyDescriptor(StringLiteral.class, "escapedValue", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(StringLiteral.class, propertyList);
+		addProperty(ESCAPED_VALUE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The literal string, including quotes and escapes; defaults to the
+	 * literal for the empty string.
+	 */
+	private String escapedValue = "\"\"";//$NON-NLS-1$
+
+	/**
+	 * Creates a new unparented string literal node owned by the given AST.
+	 * By default, the string literal denotes the empty string.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	StringLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == ESCAPED_VALUE_PROPERTY) {
+			if (get) {
+				return getEscapedValue();
+			} else {
+				setEscapedValue((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return STRING_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		StringLiteral result = new StringLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setEscapedValue(getEscapedValue());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the string value of this literal node to the given string
+	 * literal token. The token is the sequence of characters that would appear
+	 * in the source program, including enclosing double quotes and embedded
+	 * escapes.
+	 *
+	 * @return the string literal token, including enclosing double
+	 *    quotes and embedded escapes
+	 */
+	public String getEscapedValue() {
+		return this.escapedValue;
+	}
+
+	/**
+	 * Sets the string value of this literal node to the given string literal
+	 * token. The token is the sequence of characters that would appear in the
+	 * source program, including enclosing double quotes and embedded escapes.
+	 * For example,
+	 * <ul>
+	 * <li><code>""</code> <code>setLiteral("\"\"")</code></li>
+	 * <li><code>"hello world"</code> <code>setLiteral("\"hello world\"")</code></li>
+	 * <li><code>"boo\nhoo"</code> <code>setLiteral("\"boo\\nhoo\"")</code></li>
+	 * </ul>
+	 *
+	 * @param token the string literal token, including enclosing double
+	 *    quotes and embedded escapes
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setEscapedValue(String token) {
+		// update internalSetEscapedValue(String) if this is changed
+		if (token == null) {
+			throw new IllegalArgumentException("Token cannot be null"); //$NON-NLS-1$
+		}
+		Scanner scanner = this.ast.scanner;
+		char[] source = token.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		try {
+			int tokenType = scanner.getNextToken();
+			switch(tokenType) {
+				case TerminalTokens.TokenNameStringLiteral:
+					break;
+				default:
+					throw new IllegalArgumentException("Invalid string literal : >" + token + "<"); //$NON-NLS-1$//$NON-NLS-2$
+			}
+		} catch(InvalidInputException e) {
+			throw new IllegalArgumentException("Invalid string literal : >" + token + "<");//$NON-NLS-1$//$NON-NLS-2$
+		}
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = token;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setEscapedValue(String) that doesn't do any validation.
+	 */
+	void internalSetEscapedValue(String token) {
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = token;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
+	/**
+	 * Returns the value of this literal node.
+	 * <p>
+	 * For example,
+	 * <pre>
+	 * StringLiteral s;
+	 * s.setEscapedValue("\"hello\\nworld\"");
+	 * assert s.getLiteralValue().equals("hello\nworld");
+	 * </pre>
+	 * </p>
+	 * <p>
+	 * Note that this is a convenience method that converts from the stored
+	 * string literal token returned by <code>getEscapedLiteral</code>.
+	 * </p>
+	 *
+	 * @return the string value without enclosing double quotes and embedded
+	 *    escapes
+	 * @exception IllegalArgumentException if the literal value cannot be converted
+	 */
+	public String getLiteralValue() {
+		String s = getEscapedValue();
+		int len = s.length();
+		if (len < 2 || s.charAt(0) != '\"' || s.charAt(len-1) != '\"' ) {
+			throw new IllegalArgumentException();
+		}
+
+		Scanner scanner = this.ast.scanner;
+		char[] source = s.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		try {
+			int tokenType = scanner.getNextToken();
+			switch(tokenType) {
+				case TerminalTokens.TokenNameStringLiteral:
+					return scanner.getCurrentStringLiteral();
+				default:
+					throw new IllegalArgumentException();
+			}
+		} catch(InvalidInputException e) {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Sets the value of this literal node.
+	 * <p>
+	 * For example,
+	 * <pre>
+	 * StringLiteral s;
+	 * s.setLiteralValue("hello\nworld");
+	 * assert s.getEscapedValue().equals("\"hello\\nworld\"");
+	 * assert s.getLiteralValue().equals("hello\nworld");
+	 * </pre>
+	 * </p>
+	 * <p>
+	 * Note that this is a convenience method that converts to the stored
+	 * string literal token acceptable to <code>setEscapedLiteral</code>.
+	 * </p>
+	 *
+	 * @param value the string value without enclosing double quotes and
+	 *    embedded escapes
+	 * @exception IllegalArgumentException if the argument is incorrect
+	 */
+	public void setLiteralValue(String value) {
+		if (value == null) {
+			throw new IllegalArgumentException();
+		}
+		int len = value.length();
+		StringBuffer b = new StringBuffer(len + 2);
+
+		b.append("\""); // opening delimiter //$NON-NLS-1$
+		for (int i = 0; i < len; i++) {
+			char c = value.charAt(i);
+			switch(c) {
+				case '\b' :
+					b.append("\\b"); //$NON-NLS-1$
+					break;
+				case '\t' :
+					b.append("\\t"); //$NON-NLS-1$
+					break;
+				case '\n' :
+					b.append("\\n"); //$NON-NLS-1$
+					break;
+				case '\f' :
+					b.append("\\f"); //$NON-NLS-1$
+					break;
+				case '\r' :
+					b.append("\\r"); //$NON-NLS-1$
+					break;
+				case '\"':
+					b.append("\\\""); //$NON-NLS-1$
+					break;
+				case '\\':
+					b.append("\\\\"); //$NON-NLS-1$
+					break;
+				case '\0' :
+					b.append("\\0"); //$NON-NLS-1$
+					break;
+				case '\1' :
+					b.append("\\1"); //$NON-NLS-1$
+					break;
+				case '\2' :
+					b.append("\\2"); //$NON-NLS-1$
+					break;
+				case '\3' :
+					b.append("\\3"); //$NON-NLS-1$
+					break;
+				case '\4' :
+					b.append("\\4"); //$NON-NLS-1$
+					break;
+				case '\5' :
+					b.append("\\5"); //$NON-NLS-1$
+					break;
+				case '\6' :
+					b.append("\\6"); //$NON-NLS-1$
+					break;
+				case '\7' :
+					b.append("\\7"); //$NON-NLS-1$
+					break;
+				default:
+					b.append(c);
+			}
+		}
+		b.append("\""); // closing delimiter //$NON-NLS-1$
+		setEscapedValue(b.toString());
+	}
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 1 * 4 + stringSize(this.escapedValue);
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java
new file mode 100644
index 0000000..f036de4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+/**
+ * Abstract base class for property descriptors of AST nodes.
+ * There are three kinds of properties:
+ * <ul>
+ * <li>simple properties ({@link SimplePropertyDescriptor})
+ * - properties where the value is a primitive (int, boolean)
+ * or simple (String, InfixExprsssion.Operator) type other than an
+ * AST node; for example, the identifier of a {@link SimpleName}</li>
+ * <li>child properties ({@link ChildPropertyDescriptor})
+ * - properties whose value is another AST node;
+ * for example, the name of a {@link MethodDeclaration}</li>
+ * <li>child list properties ({@link ChildListPropertyDescriptor})
+ * - properties where the value is a list of AST nodes;
+ * for example, the statements of a {@link Block}</li>
+ * </ul>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class StructuralPropertyDescriptor {
+
+	/**
+	 * Property id.
+	 */
+	private final String propertyId;
+
+	/**
+	 * The concrete AST node type that owns this property.
+	 */
+	private final Class nodeClass;
+
+	/**
+	 * Creates a new property descriptor for the given node type
+	 * with the given property id.
+	 * Note that this constructor is declared package-private so that
+	 * property descriptors can only be created by the AST
+	 * implementation.
+	 *
+	 * @param nodeClass concrete AST node type that owns this property
+	 * @param propertyId the property id
+	 */
+	StructuralPropertyDescriptor(Class nodeClass, String propertyId) {
+		if (nodeClass == null || propertyId == null) {
+			throw new IllegalArgumentException();
+		}
+		this.propertyId = propertyId;
+		this.nodeClass = nodeClass;
+	}
+
+	/**
+	 * Returns the id of this property.
+	 *
+	 * @return the property id
+	 */
+	public final String getId() {
+		return this.propertyId;
+	}
+
+	/**
+	 * Returns the AST node type that owns this property.
+	 * <p>
+	 * For example, for all properties of the node type
+	 * TypeDeclaration, this method returns <code>TypeDeclaration.class</code>.
+	 * </p>
+	 *
+	 * @return the node type that owns this property
+	 */
+	public final Class getNodeClass() {
+		return this.nodeClass;
+	}
+
+	/**
+	 * Returns whether this property is a simple property
+	 * (instance of {@link SimplePropertyDescriptor}.
+	 *
+	 * @return <code>true</code> if this is a simple property, and
+	 * <code>false</code> otherwise
+	 */
+	public final boolean isSimpleProperty(){
+		return (this instanceof SimplePropertyDescriptor);
+	}
+
+	/**
+	 * Returns whether this property is a child property
+	 * (instance of {@link ChildPropertyDescriptor}.
+	 *
+	 * @return <code>true</code> if this is a child property, and
+	 * <code>false</code> otherwise
+	 */
+	public final boolean isChildProperty() {
+		return (this instanceof ChildPropertyDescriptor);
+	}
+
+	/**
+	 * Returns whether this property is a child list property
+	 * (instance of {@link ChildListPropertyDescriptor}.
+	 *
+	 * @return <code>true</code> if this is a child list property, and
+	 * <code>false</code> otherwise
+	 */
+	public final boolean isChildListProperty() {
+		return (this instanceof ChildListPropertyDescriptor);
+	}
+
+	/**
+	 * Returns a string suitable for debug purposes.
+	 * @return {@inheritDoc}
+	 */
+	public String toString() {
+		StringBuffer b = new StringBuffer();
+		if (isChildListProperty()) {
+			b.append("ChildList"); //$NON-NLS-1$
+		}
+		if (isChildProperty()) {
+			b.append("Child"); //$NON-NLS-1$
+		}
+		if (isSimpleProperty()) {
+			b.append("Simple"); //$NON-NLS-1$
+		}
+		b.append("Property["); //$NON-NLS-1$
+		if (this.nodeClass != null) {
+			b.append(this.nodeClass.getName());
+		}
+		b.append(","); //$NON-NLS-1$
+		if (this.propertyId != null) {
+			b.append(this.propertyId);
+		}
+		b.append("]"); //$NON-NLS-1$
+		return b.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java
new file mode 100644
index 0000000..bc9ed9b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java
@@ -0,0 +1,311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Super constructor invocation statement AST node type.
+ * <pre>
+ * SuperConstructorInvocation:
+ *     [ Expression <b>.</b> ]
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         <b>super</b> <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SuperConstructorInvocation extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(SuperConstructorInvocation.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SuperConstructorInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SuperConstructorInvocation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SuperConstructorInvocation.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(4);
+		createPropertyList(SuperConstructorInvocation.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		addProperty(ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The expression; <code>null</code> for none; defaults to none.
+	 */
+	private Expression optionalExpression = null;
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeArguments = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for an super constructor invocation statement
+	 * owned by the given AST. By default, no type arguments, and an empty list
+	 * of arguments.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SuperConstructorInvocation(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SUPER_CONSTRUCTOR_INVOCATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SuperConstructorInvocation result = new SuperConstructorInvocation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		}
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.typeArguments);
+			}
+			acceptChildren(visitor, this.arguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this super constructor invocation statement,
+	 * or <code>null</code> if there is none.
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getExpression() {
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Sets or clears the expression of this super constructor invocation
+	 * statement.
+	 *
+	 * @param expression the expression node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this constructor
+	 * invocation (added in JLS3 API).
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeArguments() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeArguments == null) {
+			unsupportedIn2();
+		}
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this super
+	 * constructor invocation statement.
+	 *
+	 * @return the live list of argument expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor invoked by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the constructor binding, or <code>null</code> if the binding
+	 *    cannot be resolved
+	 */
+	public IMethodBinding resolveConstructorBinding() {
+		return this.ast.getBindingResolver().resolveConstructor(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize()
+		+ (this.optionalExpression == null ? 0 : getExpression().treeSize())
+		+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+		+ (this.arguments == null ? 0 : this.arguments.listSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java
new file mode 100644
index 0000000..12ebbf1
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple or qualified "super" field access expression AST node type.
+ *
+ * <pre>
+ * SuperFieldAccess:
+ *     [ ClassName <b>.</b> ] <b>super</b> <b>.</b> Identifier
+ * </pre>
+ *
+ * <p>
+ * See <code>FieldAccess</code> for guidelines on handling other expressions
+ * that resemble qualified names.
+ * </p>
+ *
+ * @see FieldAccess
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SuperFieldAccess extends Expression {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(SuperFieldAccess.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(SuperFieldAccess.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SuperFieldAccess.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * The field; lazily initialized; defaults to an unspecified,
+	 * but legal, simple field name.
+	 */
+	private SimpleName fieldName = null;
+
+	/**
+	 * Creates a new unparented node for a super field access expression owned
+	 * by the given AST. By default, field name is an unspecified, but legal,
+	 * name, and there is no qualifier.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SuperFieldAccess(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SUPER_FIELD_ACCESS;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SuperFieldAccess result = new SuperFieldAccess(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this "super" field access expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Sets or clears the qualifier of this "super" field access expression.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the name of the field accessed in this "super" field access
+	 * expression.
+	 *
+	 * @return the field name
+	 */
+	public SimpleName getName() {
+		if (this.fieldName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.fieldName == null) {
+					preLazyInit();
+					this.fieldName = new SimpleName(this.ast);
+					postLazyInit(this.fieldName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.fieldName;
+	}
+
+	/**
+	 * Resolves and returns the binding for the field accessed by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the variable binding, or <code>null</code> if the binding cannot
+	 * be resolved
+	 * @since 3.0
+	 */
+	public IVariableBinding resolveFieldBinding() {
+		return this.ast.getBindingResolver().resolveField(this);
+	}
+
+	/**
+	 * Sets the name of the field accessed in this "super" field access
+	 * expression.
+	 *
+	 * @param fieldName the field name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName fieldName) {
+		if (fieldName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.fieldName;
+		preReplaceChild(oldChild, fieldName, NAME_PROPERTY);
+		this.fieldName = fieldName;
+		postReplaceChild(oldChild, fieldName, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.fieldName == null ? 0 : getName().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java
new file mode 100644
index 0000000..919eebe
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple or qualified "super" method invocation expression AST node type.
+ * <pre>
+ * SuperMethodInvocation:
+ *     [ ClassName <b>.</b> ] <b>super</b> <b>.</b>
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         Identifier <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SuperMethodInvocation extends Expression {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(SuperMethodInvocation.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SuperMethodInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(SuperMethodInvocation.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "arguments" structural property of this node type (element type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SuperMethodInvocation.class, "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(SuperMethodInvocation.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(5);
+		createPropertyList(SuperMethodInvocation.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(ARGUMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * The type arguments (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeArguments = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to a unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * The list of argument expressions (element type:
+	 * {@link Expression}). Defaults to an empty list.
+	 */
+	private ASTNode.NodeList arguments =
+		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for a "super" method invocation expression owned
+	 * by the given AST. By default, no qualifier, no type arguments,
+	 * an unspecified, but legal, method name, and an empty list of arguments.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SuperMethodInvocation(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeArguments = new ASTNode.NodeList(TYPE_ARGUMENTS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ARGUMENTS_PROPERTY) {
+			return arguments();
+		}
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SUPER_METHOD_INVOCATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SuperMethodInvocation result = new SuperMethodInvocation(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) getName().clone(target));
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		}
+		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.typeArguments);
+			}
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.arguments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this "super" method invocation expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Returns true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise.
+	 * <p>
+	 * This information is available only when bindings are requested when the AST is being built
+	 * </p>.
+	 *
+	 * @return true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise
+	 * @since 3.3
+	 */
+	public boolean isResolvedTypeInferredFromExpectedType() {
+		return this.ast.getBindingResolver().isResolvedTypeInferredFromExpectedType(this);
+	}
+
+
+	/**
+	 * Sets or clears the qualifier of this "super" method invocation expression.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this method
+	 * invocation (added in JLS3 API).
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeArguments() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeArguments == null) {
+			unsupportedIn2();
+		}
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the name of the method invoked in this expression.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method invoked in this expression to the
+	 * given name.
+	 *
+	 * @param name the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of argument expressions in this
+	 * "super" method invocation expression.
+	 *
+	 * @return the live list of argument expressions
+	 *    (element type: {@link Expression})
+	 */
+	public List arguments() {
+		return this.arguments;
+	}
+
+	/**
+	 * Resolves and returns the binding for the method invoked by this
+	 * expression.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the method binding, or <code>null</code> if the binding cannot
+	 * be resolved
+	 * @since 2.1
+	 */
+	public IMethodBinding resolveMethodBinding() {
+		return this.ast.getBindingResolver().resolveMethod(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize())
+			+ (this.arguments == null ? 0 : this.arguments.listSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java
new file mode 100644
index 0000000..0dfbc2e
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodReference.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Super method reference AST node type (added in JLS8 API).
+ * 
+ * <pre>
+ * SuperMethodReference:
+ *     [ ClassName <b>.</b> ] <b>super</b> <b>::</b>
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         Identifier
+ * </pre>
+ * 
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients
+ */
+public class SuperMethodReference extends MethodReference {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(SuperMethodReference.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) 
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		internalTypeArgumentsFactory(SuperMethodReference.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(SuperMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(SuperMethodReference.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to a unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+	/**
+	 * Creates a new AST  node for a super method reference owned
+	 * by the given AST. By default, there is no qualifier.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SuperMethodReference(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on MethodReference.
+	 */
+	final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+		return TYPE_ARGUMENTS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SUPER_METHOD_REFERENCE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SuperMethodReference result = new SuperMethodReference(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) getName().clone(target));
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getQualifier());
+			acceptChildren(visitor, this.typeArguments);
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this "super" method reference, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Sets the qualifier of this "super" method reference expression.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this super method reference.
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the name of the method referenced in this expression.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method referenced in this expression to the
+	 * given name.
+	 *
+	 * @param name the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
new file mode 100644
index 0000000..87953a6
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Switch case AST node type. A switch case is a special kind of node used only
+ * in switch statements. It is a <code>Statement</code> in name only.
+ * <p>
+ * <pre>
+ * SwitchCase:
+ *		<b>case</b> Expression  <b>:</b>
+ *		<b>default</b> <b>:</b>
+ * </pre>
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SwitchCase extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(SwitchCase.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(SwitchCase.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; <code>null</code> for none; lazily initialized (but
+	 * does <b>not</b> default to none).
+	 * @see #expressionInitialized
+	 */
+	private Expression optionalExpression = null;
+
+	/**
+	 * Indicates whether <code>optionalExpression</code> has been initialized.
+	 */
+	private boolean expressionInitialized = false;
+
+	/**
+	 * Creates a new AST node for a switch case pseudo-statement owned by the
+	 * given AST. By default, there is an unspecified, but legal, expression.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SwitchCase(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SWITCH_CASE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SwitchCase result = new SwitchCase(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression(
+			(Expression) ASTNode.copySubtree(target, getExpression()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this switch case, or
+	 * <code>null</code> if there is none (the "default:" case).
+	 *
+	 * @return the expression node, or <code>null</code> if there is none
+	 */
+	public Expression getExpression() {
+		if (!this.expressionInitialized) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (!this.expressionInitialized) {
+					preLazyInit();
+					this.optionalExpression = new SimpleName(this.ast);
+					this.expressionInitialized = true;
+					postLazyInit(this.optionalExpression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Sets the expression of this switch case, or clears it (turns it into
+	 * the  "default:" case).
+	 *
+	 * @param expression the expression node, or <code>null</code> to
+	 *    turn it into the  "default:" case
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		this.expressionInitialized = true;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns whether this switch case represents the "default:" case.
+	 * <p>
+	 * This convenience method is equivalent to
+	 * <code>getExpression() == null</code>.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is the default switch case, and
+	 *    <code>false</code> if this is a non-default switch case
+	 */
+	public boolean isDefault()  {
+		return getExpression() == null;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalExpression == null ? 0 : this.optionalExpression.treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java
new file mode 100644
index 0000000..cd19e2a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Switch statement AST node type.
+ * <p>
+ * <pre>
+ * SwitchStatement:
+ *		<b>switch</b> <b>(</b> Expression <b>)</b>
+ * 			<b>{</b> { SwitchCase | Statement } } <b>}</b>
+ * SwitchCase:
+ *		<b>case</b> Expression  <b>:</b>
+ *		<b>default</b> <b>:</b>
+ * </pre>
+ * <code>SwitchCase</code> nodes are treated as a kind of
+ * <code>Statement</code>.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SwitchStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(SwitchStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "statements" structural property of this node type (element type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor STATEMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SwitchStatement.class, "statements", Statement.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SwitchStatement.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(STATEMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The statements and SwitchCase nodes
+	 * (element type: {@link Statement}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList statements =
+		new ASTNode.NodeList(STATEMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented switch statement node owned by the given
+	 * AST. By default, the swicth statement has an unspecified, but legal,
+	 * expression, and an empty list of switch groups.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SwitchStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == STATEMENTS_PROPERTY) {
+			return statements();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SWITCH_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SwitchStatement result = new SwitchStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		result.statements().addAll(ASTNode.copySubtrees(target, statements()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChildren(visitor, this.statements);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this switch statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this switch statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of statements for this switch statement.
+	 * Within this list, <code>SwitchCase</code> nodes mark the start of
+	 * the switch groups.
+	 *
+	 * @return the live list of statement nodes
+	 *    (element type: {@link Statement})
+	 */
+	public List statements() {
+		return this.statements;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ this.statements.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java
new file mode 100644
index 0000000..dbc27f4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Synchronized statement AST node type.
+ *
+ * <pre>
+ * SynchronizedStatement:
+ *    <b>synchronized</b> <b>(</b> Expression <b>)</b> Block
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class SynchronizedStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(SynchronizedStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(SynchronizedStatement.class, "body", Block.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SynchronizedStatement.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified, but
+	 * legal, expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The body; lazily initialized; defaults to an empty block.
+	 */
+	private Block body = null;
+
+	/**
+	 * Creates a new unparented synchronized statement node owned by the given
+	 * AST. By default, the expression is unspecified, but legal, and the
+	 * blody is an empty block.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	SynchronizedStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Block) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return SYNCHRONIZED_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		SynchronizedStatement result = new SynchronizedStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setBody((Block) getBody().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this synchronized statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this synchronized statement.
+	 *
+	 * @param expression the expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the body of this synchronized statement.
+	 *
+	 * @return the body block node
+	 */
+	public Block getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this synchronized statement.
+	 *
+	 * @param block the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Block block) {
+		if (block == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, block, BODY_PROPERTY);
+		this.body = block;
+		postReplaceChild(oldChild, block, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java
new file mode 100644
index 0000000..cb84691
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * AST node for a tag within a doc comment.
+ * Tag elements nested within another tag element are called
+ * inline doc tags.
+ * <pre>
+ * TagElement:
+ *     [ <b>@</b> Identifier ] { DocElement }
+ * DocElement:
+ *     TextElement
+ *     Name
+ *     MethodRef
+ *     MemberRef
+ *     <b>{</b> TagElement <b>}</b>
+ * </pre>
+ *
+ * @see Javadoc
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class TagElement extends ASTNode implements IDocElement {
+
+	/**
+	 * The "tagName" structural property of this node type (type: {@link String}).
+	 *
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor TAG_NAME_PROPERTY =
+		new SimplePropertyDescriptor(TagElement.class, "tagName", String.class, OPTIONAL); //$NON-NLS-1$
+
+	/**
+	 * The "fragments" structural property of this node type (element type: {@link IDocElement}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(TagElement.class, "fragments", IDocElement.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(TagElement.class, propertyList);
+		addProperty(TAG_NAME_PROPERTY, propertyList);
+		addProperty(FRAGMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_AUTHOR = "@author"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 * <p>
+	 * Note that this tag first appeared in J2SE 5.
+	 * </p>
+	 * @since 3.1
+	 */
+	public static final String TAG_CODE = "@code"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_DEPRECATED = "@deprecated"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 */
+	public static final String TAG_DOCROOT = "@docRoot"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_EXCEPTION = "@exception"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 */
+	public static final String TAG_INHERITDOC = "@inheritDoc"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 */
+	public static final String TAG_LINK = "@link"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 */
+	public static final String TAG_LINKPLAIN = "@linkplain"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 * <p>
+	 * Note that this tag first appeared in J2SE 5.
+	 * </p>
+	 * @since 3.1
+	 */
+	public static final String TAG_LITERAL = "@literal"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_PARAM = "@param"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_RETURN = "@return"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_SEE = "@see"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_SERIAL = "@serial"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_SERIALDATA= "@serialData"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_SERIALFIELD= "@serialField"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_SINCE = "@since"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_THROWS = "@throws"; //$NON-NLS-1$
+
+	/**
+	 * Standard inline doc tag name (value {@value}).
+	 */
+	public static final String TAG_VALUE= "@value"; //$NON-NLS-1$
+
+	/**
+	 * Standard doc tag name (value {@value}).
+	 */
+	public static final String TAG_VERSION = "@version"; //$NON-NLS-1$
+
+	/**
+	 * The tag name, or null if none; defaults to null.
+	 */
+	private String optionalTagName = null;
+
+	/**
+	 * The list of doc elements (element type: {@link IDocElement}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList fragments =
+		new ASTNode.NodeList(FRAGMENTS_PROPERTY);
+
+	/**
+	 * Creates a new AST node for a tag element owned by the given AST.
+	 * The new node has no name and an empty list of fragments.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TagElement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == TAG_NAME_PROPERTY) {
+			if (get) {
+				return getTagName();
+			} else {
+				setTagName((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == FRAGMENTS_PROPERTY) {
+			return fragments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TAG_ELEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TagElement result = new TagElement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setTagName(getTagName());
+		result.fragments().addAll(ASTNode.copySubtrees(target, fragments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChildren(visitor, this.fragments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns this node's tag name, or <code>null</code> if none.
+	 * For top level doc tags such as parameter tags, the tag name
+     * includes the "@" character ("@param").
+	 * For inline doc tags such as link tags, the tag name
+     * includes the "@" character ("@link").
+     * The tag name may also be <code>null</code>; this is used to
+     * represent the material at the start of a doc comment preceding
+     * the first explicit tag.
+     *
+	 * @return the tag name, or <code>null</code> if none
+	 */
+	public String getTagName() {
+		return this.optionalTagName;
+	}
+
+	/**
+	 * Sets the tag name of this node to the given value.
+	 * For top level doc tags such as parameter tags, the tag name
+	 * includes the "@" character ("@param").
+	 * For inline doc tags such as link tags, the tag name
+	 * includes the "@" character ("@link").
+	 * The tag name may also be <code>null</code>; this is used to
+	 * represent the material at the start of a doc comment preceding
+	 * the first explicit tag.
+	 *
+	 * @param tagName the tag name, or <code>null</code> if none
+	 */
+	public void setTagName(String tagName) {
+		preValueChange(TAG_NAME_PROPERTY);
+		this.optionalTagName = tagName;
+		postValueChange(TAG_NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live list of fragments in this tag element.
+	 * <p>
+	 * The fragments cover everything following the tag name
+	 * (or everything if there is no tag name), and generally omit
+	 * embedded line breaks (and leading whitespace on new lines,
+	 * including any leading "*"). {@link org.eclipse.jdt.core.dom.TagElement}
+	 * nodes are used to represent tag elements (e.g., "@link")
+	 * nested within this tag element.
+	 * </p>
+	 * <p>
+	 * Here are some typical examples:
+	 * <ul>
+	 * <li>"@see Foo#bar()" - TagElement with tag name "@see";
+	 * fragments() contains a single MethodRef node</li>
+	 * <li>"@param args the program arguments" -
+	 * TagElement with tag name "@param";
+	 * 2 fragments: SimpleName ("args"), TextElement
+	 * (" the program arguments")</li>
+	 * <li>"@return See {&#64;link #foo foo} instead." -
+	 * TagElement with tag name "@return";
+	 * 3 fragments: TextElement ("See "),
+	 * TagElement (for "&#64;link #foo foo"),
+	 * TextElement (" instead.")</li>
+	 * </ul>
+	 * The use of Name, MethodRef, and MemberRef nodes within
+	 * tag elements allows these fragments to be queried for
+	 * binding information.
+	 * </p>
+	 * <p>
+	 * Adding and removing nodes from this list affects this node
+	 * dynamically. The nodes in this list may be of various
+	 * types, including {@link TextElement},
+	 * {@link org.eclipse.jdt.core.dom.TagElement}, {@link Name},
+	 * {@link MemberRef}, and {@link MethodRef}.
+	 * Clients should assume that the list of types may grow in
+	 * the future, and write their code to deal with unexpected
+	 * nodes types. However, attempts to add a non-proscribed type
+	 * of node will trigger an exception.
+	 *
+	 * @return the live list of doc elements in this tag element
+	 * (element type: {@link IDocElement})
+	 */
+	public List fragments() {
+		return this.fragments;
+	}
+
+	/**
+	 * Returns whether this tag element is nested within another
+	 * tag element. Nested tag elements appears enclosed in
+	 * "{" and "}"; certain doc tags, including "@link" and
+	 * "@linkplain" are only meaningful as nested tags.
+	 * Top-level (i.e., non-nested) doc tags begin on a new line;
+	 * certain doc tags, including "@param" and
+	 * "@see" are only meaningful as top-level tags.
+	 * <p>
+	 * This convenience methods checks to see whether the parent
+	 * of this node is of type {@link org.eclipse.jdt.core.dom.TagElement}.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this node is a nested tag element,
+	 * and false if this node is either parented by a doc comment node
+	 * ({@link Javadoc}), or is unparented
+	 */
+	public boolean isNested() {
+		return (getParent() instanceof TagElement);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 2 * 4 + stringSize(this.optionalTagName);
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize() + this.fragments.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java
new file mode 100644
index 0000000..774c861
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * AST node for a text element within a doc comment.
+ * <pre>
+ * TextElement:
+ *     Sequence of characters not including a close comment delimiter <b>*</b><b>/</b>
+ * </pre>
+ *
+ * @see Javadoc
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class TextElement extends ASTNode implements IDocElement {
+
+	/**
+	 * The "text" structural property of this node type (type: {@link String}).
+	 *
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor TEXT_PROPERTY =
+		new SimplePropertyDescriptor(TextElement.class, "text", String.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(TextElement.class, propertyList);
+		addProperty(TEXT_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The text element; defaults to the empty string.
+	 */
+	private String text = Util.EMPTY_STRING;
+
+	/**
+	 * Creates a new AST node for a text element owned by the given AST.
+	 * The new node has an empty text string.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TextElement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
+		if (property == TEXT_PROPERTY) {
+			if (get) {
+				return getText();
+			} else {
+				setText((String) value);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetObjectProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TEXT_ELEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TextElement result = new TextElement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setText(getText());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		visitor.visit(this);
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns this node's text.
+	 *
+	 * @return the text of this node
+	 */
+	public String getText() {
+		return this.text;
+	}
+
+	/**
+	 * Sets the text of this node to the given value.
+	 * <p>
+	 * The text element typically includes leading and trailing
+	 * whitespace that separates it from the immediately preceding
+	 * or following elements. The text element must not include
+	 * a block comment closing delimiter "*"+"/".
+	 * </p>
+	 *
+	 * @param text the text of this node
+	 * @exception IllegalArgumentException if the text is null
+	 * or contains a block comment closing delimiter
+	 */
+	public void setText(String text) {
+		if (text == null) {
+			throw new IllegalArgumentException();
+		}
+		if (text.indexOf("*/") > 0) { //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		}
+		preValueChange(TEXT_PROPERTY);
+		this.text = text;
+		postValueChange(TEXT_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		int size = BASE_NODE_SIZE + 1 * 4;
+		if (this.text != Util.EMPTY_STRING) {
+			// everything but our empty string costs
+			size += stringSize(this.text);
+		}
+		return size;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java
new file mode 100644
index 0000000..88ce5e8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Simple or qualified "this" AST node type.
+ *
+ * <pre>
+ * ThisExpression:
+ *     [ ClassName <b>.</b> ] <b>this</b>
+ * </pre>
+ * <p>
+ * See <code>FieldAccess</code> for guidelines on handling other expressions
+ * that resemble qualified names.
+ * </p>
+ *
+ * @see FieldAccess
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ThisExpression extends Expression {
+
+	/**
+	 * The "qualifier" structural property of this node type (child type: {@link Name}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
+		new ChildPropertyDescriptor(ThisExpression.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ThisExpression.class, propertyList);
+		addProperty(QUALIFIER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The optional qualifier; <code>null</code> for none; defaults to none.
+	 */
+	private Name optionalQualifier = null;
+
+	/**
+	 * Creates a new AST node for a "this" expression owned by the
+	 * given AST. By default, there is no qualifier.
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ThisExpression(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == QUALIFIER_PROPERTY) {
+			if (get) {
+				return getQualifier();
+			} else {
+				setQualifier((Name) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return THIS_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ThisExpression result = new ThisExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getQualifier());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the qualifier of this "this" expression, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the qualifier name node, or <code>null</code> if there is none
+	 */
+	public Name getQualifier() {
+		return this.optionalQualifier;
+	}
+
+	/**
+	 * Sets or clears the qualifier of this "this" expression.
+	 *
+	 * @param name the qualifier name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setQualifier(Name name) {
+		ASTNode oldChild = this.optionalQualifier;
+		preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+		this.optionalQualifier = name;
+		postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.optionalQualifier == null ? 0 : getQualifier().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java
new file mode 100644
index 0000000..2f9b77b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Throw statement AST node type.
+ *
+ * <pre>
+ * ThrowStatement:
+ *    <b>throw</b> Expression <b>;</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class ThrowStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(ThrowStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(ThrowStatement.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * Creates a new unparented throw statement node owned by the given
+	 * AST. By default, the throw statement has an unspecified, but legal,
+	 * expression.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	ThrowStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return THROW_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		ThrowStatement result = new ThrowStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getExpression());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this throw statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this throw statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java
new file mode 100644
index 0000000..4d84544
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Try statement AST node type.
+ * <pre>
+ * TryStatement:
+ *     <b>try</b> [ <b>(</b> Resources <b>)</b> ]
+ *         Block
+ *         [ { CatchClause } ]
+ *         [ <b>finally</b> Block ]
+ * </pre>
+ *
+ * <p>
+ * Not all node arrangements will represent legal Java constructs. In particular,
+ * at least one resource, catch clause, or finally block must be present.</p>
+ * 
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TryStatement extends Statement {
+
+	/**
+	 * The "resources" structural property of this node type (element type: {@link VariableDeclarationExpression}) (added in JLS4 API).
+	 * @since 3.7.1
+	 */
+	public static final ChildListPropertyDescriptor RESOURCES_PROPERTY =
+		new ChildListPropertyDescriptor(TryStatement.class, "resources", VariableDeclarationExpression.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(TryStatement.class, "body", Block.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "catchClauses" structural property of this node type (element type: {@link CatchClause}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor CATCH_CLAUSES_PROPERTY =
+		new ChildListPropertyDescriptor(TryStatement.class, "catchClauses", CatchClause.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "finally" structural property of this node type (child type: {@link Block}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor FINALLY_PROPERTY =
+		new ChildPropertyDescriptor(TryStatement.class, "finally", Block.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.7
+	 */
+	private static final List PROPERTY_DESCRIPTORS_4_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(TryStatement.class, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		addProperty(CATCH_CLAUSES_PROPERTY, propertyList);
+		addProperty(FINALLY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(5);
+		createPropertyList(TryStatement.class, propertyList);
+		addProperty(RESOURCES_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		addProperty(CATCH_CLAUSES_PROPERTY, propertyList);
+		addProperty(FINALLY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_4_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_4_0;
+		}
+	}
+
+	/**
+	 * The resource expressions (element type: {@link VariableDeclarationExpression}).
+	 * Null in JLS2 and JLS3. Added in JLS4; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.7
+	 */
+	private ASTNode.NodeList resources = null;
+
+	/**
+	 * The body; lazily initialized; defaults to an empty block.
+	 */
+	private Block body = null;
+
+	/**
+	 * The catch clauses (element type: {@link CatchClause}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList catchClauses =
+		new ASTNode.NodeList(CATCH_CLAUSES_PROPERTY);
+
+	/**
+	 * The finally block, or <code>null</code> if none.
+	 * Defaults to none.
+	 */
+	private Block optionalFinallyBody = null;
+
+
+	/**
+	 * Creates a new AST node for a try statement owned by the given
+	 * AST. By default, the try statement has no resources, an empty block, no catch
+	 * clauses, and no finally block.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TryStatement(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS4_INTERNAL) {
+			this.resources = new ASTNode.NodeList(RESOURCES_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Block) child);
+				return null;
+			}
+		}
+		if (property == FINALLY_PROPERTY) {
+			if (get) {
+				return getFinally();
+			} else {
+				setFinally((Block) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == RESOURCES_PROPERTY) {
+			return resources();
+		}
+		if (property == CATCH_CLAUSES_PROPERTY) {
+			return catchClauses();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TRY_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TryStatement result = new TryStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		if (this.ast.apiLevel >= AST.JLS4_INTERNAL) {
+			result.resources().addAll(
+					ASTNode.copySubtrees(target, resources()));
+		}
+		result.setBody((Block) getBody().clone(target));
+		result.catchClauses().addAll(
+			ASTNode.copySubtrees(target, catchClauses()));
+		result.setFinally(
+			(Block) ASTNode.copySubtree(target, getFinally()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS4_INTERNAL) {
+				acceptChildren(visitor, this.resources);
+			}
+			acceptChild(visitor, getBody());
+			acceptChildren(visitor, this.catchClauses);
+			acceptChild(visitor, getFinally());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the body of this try statement.
+	 *
+	 * @return the try body
+	 */
+	public Block getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this try statement.
+	 *
+	 * @param body the block node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Block body) {
+		if (body == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, body, BODY_PROPERTY);
+		this.body = body;
+		postReplaceChild(oldChild, body, BODY_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of catch clauses for this try statement.
+	 *
+	 * @return the live list of catch clauses
+	 *    (element type: {@link CatchClause})
+	 */
+	public List catchClauses() {
+		return this.catchClauses;
+	}
+
+	/**
+	 * Returns the finally block of this try statement, or <code>null</code> if
+	 * this try statement has <b>no</b> finally block.
+	 *
+	 * @return the finally block, or <code>null</code> if this try statement
+	 *    has none
+	 */
+	public Block getFinally() {
+		return this.optionalFinallyBody;
+	}
+
+	/**
+	 * Sets or clears the finally block of this try statement.
+	 *
+	 * @param block the finally block node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setFinally(Block block) {
+		ASTNode oldChild = this.optionalFinallyBody;
+		preReplaceChild(oldChild, block, FINALLY_PROPERTY);
+		this.optionalFinallyBody = block;
+		postReplaceChild(oldChild, block, FINALLY_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of resources for this try statement (added in JLS4 API).
+	 *
+	 * @return the live list of resources
+	 *    (element type: {@link VariableDeclarationExpression})
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2 or JLS3 AST
+	 * @since 3.7.1
+	 */
+	public List resources() {
+		// more efficient than just calling unsupportedIn2_3() to check
+		if (this.resources == null) {
+			unsupportedIn2_3();
+		}
+		return this.resources;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.resources == null ? 0 : this.resources.listSize())
+			+ (this.body == null ? 0 : getBody().treeSize())
+			+ this.catchClauses.listSize()
+			+ (this.optionalFinallyBody == null ? 0 : getFinally().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java
new file mode 100644
index 0000000..336deda
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+
+/**
+ * Abstract base class of all type AST node types. A type node represents a
+ * reference to a primitive type (including void), to an array type, or to a
+ * simple named type (or type variable), to a qualified type, to a
+ * parameterized type, to a union type, or to a wildcard type. Note that not all of these
+ * are meaningful in all contexts; for example, a wildcard type is only
+ * meaningful in the type argument position of a parameterized type.
+ * UnionType got introduced in JLS4 to support common catch blocks for disjunctive types.
+ * For JLS8, optional annotations indicated by {Annotation} got added.
+ * <p>
+ * <pre>
+ * Type:
+ *    AnnotatableType:
+ *       PrimitiveType
+ *       ArrayType
+ *       SimpleType
+ *       QualifiedType
+ *       PackageQualifiedType
+ *       WildcardType
+ *    ParameterizedType
+ *    UnionType
+ *    IntersectionType
+ *    
+ * {@link PrimitiveType}:
+ *    { Annotation } <b>byte</b>
+ *    { Annotation } <b>short</b>
+ *    { Annotation } <b>char</b>
+ *    { Annotation } <b>int</b>
+ *    { Annotation } <b>long</b>
+ *    { Annotation } <b>float</b>
+ *    { Annotation } <b>double</b>
+ *    { Annotation } <b>boolean</b>
+ *    { Annotation } <b>void</b>
+ * {@link ArrayType}:
+ *    Type { Annotation } <b>'['</b> <b>']'</b>
+ * {@link SimpleType}:
+ *    { Annotation } TypeName
+ * {@link QualifiedType}:
+ *    Type <b>.</b> {Annotation} SimpleName
+ * {@link PackageQualifiedType}:
+ *    Name <b>.</b> { Annotation } SimpleName
+ * {@link WildcardType}:
+ *    { Annotation } <b>?</b> [ ( <b>extends</b> | <b>super</b>) Type ]
+ * {@link ParameterizedType}:
+ *    Type <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b>
+ * {@link UnionType}:
+ *    Type <b>|</b> Type { <b>|</b> Type }
+ * {@link IntersectionType}:
+ *    Type <b>&</b> Type { <b>&</b> Type }
+ * </pre>
+ * </p>
+ *
+ * @since 2.0
+ */
+public abstract class Type extends ASTNode {
+	
+	/**
+	 * Creates a new AST node for a type owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	Type(AST ast) {
+		super(ast);
+	}
+
+	/**
+	 * Returns whether this type is a primitive type
+	 * ({@link PrimitiveType}).
+	 *
+	 * @return <code>true</code> if this is a primitive type, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isPrimitiveType() {
+		return (this instanceof PrimitiveType);
+	}
+
+	/**
+	 * Returns whether this type is a simple type
+	 * ({@link SimpleType}).
+	 *
+	 * @return <code>true</code> if this is a simple type, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isSimpleType() {
+		return (this instanceof SimpleType);
+	}
+
+	/**
+	 * Returns whether this type is an array type
+	 * ({@link ArrayType}).
+	 *
+	 * @return <code>true</code> if this is an array type, and
+	 *    <code>false</code> otherwise
+	 */
+	public final boolean isArrayType() {
+		return (this instanceof ArrayType);
+	}
+
+	/**
+	 * Returns whether this type is a package qualified type
+	 * ({@link PackageQualifiedType}).
+	 *
+	 * @return <code>true</code> if this is a package qualified type, and
+	 *    <code>false</code> otherwise
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public final boolean isPackageQualifiedType() {
+		return (this instanceof PackageQualifiedType);
+	}
+
+	/**
+	 * Returns whether this type is a parameterized type
+	 * ({@link ParameterizedType}).
+	 *
+	 * @return <code>true</code> if this is a parameterized type, and
+	 *    <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isParameterizedType() {
+		return (this instanceof ParameterizedType);
+	}
+
+	/**
+	 * Returns whether this type is a qualified type
+	 * ({@link QualifiedType}).
+	 * <p>
+	 * Note that a type like "A.B" can be represented either of two ways:
+	 * <ol>
+	 * <li>
+	 * <code>QualifiedType(SimpleType(SimpleName("A")),SimpleName("B"))</code>
+	 * </li>
+	 * <li>
+	 * <code>SimpleType(QualifiedName(SimpleName("A"),SimpleName("B")))</code>
+	 * </li>
+	 * </ol>
+	 * The first form is preferred when "A" is known to be a type. However, a
+	 * parser cannot always determine this. Clients should be prepared to handle
+	 * either rather than make assumptions. (Note also that the first form
+	 * became possible as of JLS3; only the second form existed in the
+	 * JLS2 API.)
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is a qualified type, and
+	 *    <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isQualifiedType() {
+		return (this instanceof QualifiedType);
+	}
+
+	/**
+	 * Returns whether this type is a union type
+	 * ({@link UnionType}).
+	 *
+	 * @return <code>true</code> if this is a union type, and
+	 *    <code>false</code> otherwise
+	 * @since 3.7.1
+	 */
+	public final boolean isUnionType() {
+		return (this instanceof UnionType);
+	}
+
+	/**
+	 * Returns whether this type is an intersection type
+	 * ({@link IntersectionType}).
+	 *
+	 * @return <code>true</code> if this is an intersection type, and
+	 * 		<code>false</code> otherwise
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public final boolean isIntersectionType() {
+		return (this instanceof IntersectionType);
+	}
+
+	/**
+	 * Returns whether this type is a wildcard type
+	 * ({@link WildcardType}).
+	 * <p>
+	 * Note that a wildcard type is only meaningful as a
+	 * type argument of a {@link ParameterizedType} node.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this is a wildcard type, and
+	 *    <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isWildcardType() {
+		return (this instanceof WildcardType);
+	}
+	
+	/**
+	 * Returns whether this type can be annotated. All sub-classes of
+	 * {@link AnnotatableType} can be annotated.
+	 *
+	 * @return <code>true</code> if this type is an instance of {@link AnnotatableType}, and
+	 * <code>false</code> otherwise
+	 * 			
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean isAnnotatable() {
+		return (this instanceof AnnotatableType);
+	}
+
+	/**
+	 * Resolves and returns the binding for this type.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the type binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public final ITypeBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveType(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
new file mode 100644
index 0000000..14df83d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -0,0 +1,1269 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.PackageFragment;
+
+/**
+ * Internal implementation of type bindings.
+ */
+class TypeBinding implements ITypeBinding {
+	private static final StringLiteral EXPRESSION = new org.eclipse.jdt.internal.compiler.ast.StringLiteral(0,0);
+
+	protected static final IMethodBinding[] NO_METHOD_BINDINGS = new IMethodBinding[0];
+
+	private static final String NO_NAME = ""; //$NON-NLS-1$
+	protected static final ITypeBinding[] NO_TYPE_BINDINGS = new ITypeBinding[0];
+	protected static final IVariableBinding[] NO_VARIABLE_BINDINGS = new IVariableBinding[0];
+
+	private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+		Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.STRICTFP;
+
+	org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding;
+	private String key;
+	private BindingResolver resolver;
+	private IVariableBinding[] fields;
+	private IAnnotationBinding[] annotations;
+	private IMethodBinding[] methods;
+	private ITypeBinding[] members;
+	private ITypeBinding[] interfaces;
+	private ITypeBinding[] typeArguments;
+	private ITypeBinding[] bounds;
+	private ITypeBinding[] typeParameters;
+
+	public TypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding) {
+		this.binding = binding;
+		this.resolver = resolver;
+	}
+
+	public ITypeBinding createArrayType(int dimension) {
+		int realDimensions = dimension;
+		realDimensions += getDimensions();
+		if (realDimensions < 1 || realDimensions > 255) {
+			throw new IllegalArgumentException();
+		}
+		return this.resolver.resolveArrayType(this, dimension);
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		if (this.annotations != null) {
+			return this.annotations;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding refType = null;
+		if (this.binding instanceof ParameterizedTypeBinding) {
+			refType = ((ParameterizedTypeBinding) this.binding).genericType();
+		} else if (this.binding.isAnnotationType() || this.binding.isClass() || this.binding.isEnum() || this.binding.isInterface()) {
+			refType = (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) this.binding;
+		}
+		if (refType != null) {
+			org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = refType.getAnnotations();
+			int length = internalAnnotations == null ? 0 : internalAnnotations.length;
+			if (length != 0) {
+				IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
+				int convertedAnnotationCount = 0;
+				for (int i = 0; i < length; i++) {
+					org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
+					IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
+					if (annotationInstance == null) {
+						continue;
+					}
+					tempAnnotations[convertedAnnotationCount++] = annotationInstance;
+				}
+				if (convertedAnnotationCount != length) {
+					if (convertedAnnotationCount == 0) {
+						return this.annotations = AnnotationBinding.NoAnnotations;
+					}
+					System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
+				}
+				return this.annotations = tempAnnotations;
+			}
+		}
+		return this.annotations = AnnotationBinding.NoAnnotations;
+	}
+
+	/*
+	 * @see ITypeBinding#getBinaryName()
+	 * @since 3.0
+	 */
+	public String getBinaryName() {
+		if (this.binding.isCapture()) {
+			return null; // no binary name for capture binding
+		} else if (this.binding.isTypeVariable()) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			org.eclipse.jdt.internal.compiler.lookup.Binding declaring = typeVariableBinding.declaringElement;
+			StringBuffer binaryName = new StringBuffer();
+			switch(declaring.kind()) {
+				case org.eclipse.jdt.internal.compiler.lookup.Binding.METHOD :
+					MethodBinding methodBinding = (MethodBinding) declaring;
+					char[] constantPoolName = methodBinding.declaringClass.constantPoolName();
+					if (constantPoolName == null) return null;
+					binaryName
+						.append(CharOperation.replaceOnCopy(constantPoolName, '/', '.'))
+						.append('$')
+						.append(methodBinding.signature())
+						.append('$')
+						.append(typeVariableBinding.sourceName);
+					break;
+				default :
+					org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaring;
+					constantPoolName = typeBinding.constantPoolName();
+					if (constantPoolName == null) return null;
+					binaryName
+						.append(CharOperation.replaceOnCopy(constantPoolName, '/', '.'))
+						.append('$')
+						.append(typeVariableBinding.sourceName);
+			}
+			return String.valueOf(binaryName);
+		}
+ 		char[] constantPoolName = this.binding.constantPoolName();
+		if (constantPoolName == null) return null;
+		char[] dotSeparated = CharOperation.replaceOnCopy(constantPoolName, '/', '.');
+		return new String(dotSeparated);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getBound()
+	 */
+	public ITypeBinding getBound() {
+		switch (this.binding.kind()) {
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE :
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				if (wildcardBinding.bound != null) {
+					return this.resolver.getTypeBinding(wildcardBinding.bound);
+				}
+				break;
+		}
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getGenericTypeOfWildcardType()
+	 */
+	public ITypeBinding getGenericTypeOfWildcardType() {
+		switch (this.binding.kind()) {
+			case Binding.WILDCARD_TYPE :
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				if (wildcardBinding.genericType != null) {
+					return this.resolver.getTypeBinding(wildcardBinding.genericType);
+				}
+				break;
+		}
+		return null;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getRank()
+	 */
+	public int getRank() {
+		switch (this.binding.kind()) {
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE :
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				return wildcardBinding.rank;
+			default:
+				return -1;
+		}
+	}
+	
+	/*
+	 * @see ITypeBinding#getComponentType()
+	 */
+	public ITypeBinding getComponentType() {
+		if (!isArray()) {
+			return null;
+		}
+		ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+		return this.resolver.getTypeBinding(arrayBinding.elementsType());
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaredFields()
+	 */
+	public synchronized IVariableBinding[] getDeclaredFields() {
+		if (this.fields != null) {
+			return this.fields;
+		}
+		try {
+			if (isClass() || isInterface() || isEnum()) {
+				ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+				FieldBinding[] fieldBindings = referenceBinding.availableFields(); // resilience
+				int length = fieldBindings.length;
+				if (length != 0) {
+					int convertedFieldCount = 0;
+					IVariableBinding[] newFields = new IVariableBinding[length];
+					for (int i = 0; i < length; i++) {
+						FieldBinding fieldBinding = fieldBindings[i];
+						IVariableBinding variableBinding = this.resolver.getVariableBinding(fieldBinding);
+						if (variableBinding != null) {
+							newFields[convertedFieldCount++] = variableBinding;
+						}
+					}
+
+					if (convertedFieldCount != length) {
+						if (convertedFieldCount == 0) {
+							return this.fields = NO_VARIABLE_BINDINGS;
+						}
+						System.arraycopy(newFields, 0, (newFields = new IVariableBinding[convertedFieldCount]), 0, convertedFieldCount);
+					}
+					return this.fields = newFields;
+				}
+			}
+		} catch (RuntimeException e) {
+			/* in case a method cannot be resolvable due to missing jars on the classpath
+			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+			 */
+			org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared fields"); //$NON-NLS-1$
+		}
+		return this.fields = NO_VARIABLE_BINDINGS;
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaredMethods()
+	 */
+	public synchronized IMethodBinding[] getDeclaredMethods() {
+		if (this.methods != null) {
+			return this.methods;
+		}
+		try {
+			if (isClass() || isInterface() || isEnum()) {
+				ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+				org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] internalMethods = referenceBinding.availableMethods(); // be resilient
+				int length = internalMethods.length;
+				if (length != 0) {
+					int convertedMethodCount = 0;
+					IMethodBinding[] newMethods = new IMethodBinding[length];
+					for (int i = 0; i < length; i++) {
+						org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = internalMethods[i];
+						if (methodBinding.isDefaultAbstract() || methodBinding.isSynthetic() || (methodBinding.isConstructor() && isInterface())) {
+							continue;
+						}
+						IMethodBinding methodBinding2 = this.resolver.getMethodBinding(methodBinding);
+						if (methodBinding2 != null) {
+							newMethods[convertedMethodCount++] = methodBinding2;
+						}
+					}
+					if (convertedMethodCount != length) {
+						if (convertedMethodCount == 0) {
+							return this.methods = NO_METHOD_BINDINGS;
+						}
+						System.arraycopy(newMethods, 0, (newMethods = new IMethodBinding[convertedMethodCount]), 0, convertedMethodCount);
+					}
+					return this.methods = newMethods;
+				}
+			}
+		} catch (RuntimeException e) {
+			/* in case a method cannot be resolvable due to missing jars on the classpath
+			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+			 */
+			org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared methods"); //$NON-NLS-1$
+		}
+		return this.methods = NO_METHOD_BINDINGS;
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaredModifiers()
+	 */
+	public int getDeclaredModifiers() {
+		return getModifiers();
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaredTypes()
+	 */
+	public synchronized ITypeBinding[] getDeclaredTypes() {
+		if (this.members != null) {
+			return this.members;
+		}
+		try {
+			if (isClass() || isInterface() || isEnum()) {
+				ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+				ReferenceBinding[] internalMembers = referenceBinding.memberTypes();
+				int length = internalMembers.length;
+				if (length != 0) {
+					ITypeBinding[] newMembers = new ITypeBinding[length];
+					for (int i = 0; i < length; i++) {
+						ITypeBinding typeBinding = this.resolver.getTypeBinding(internalMembers[i]);
+						if (typeBinding == null) {
+							return this.members = NO_TYPE_BINDINGS;
+						}
+						newMembers[i] = typeBinding;
+					}
+					return this.members = newMembers;
+				}
+			}
+		} catch (RuntimeException e) {
+			/* in case a method cannot be resolvable due to missing jars on the classpath
+			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+			 */
+			org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declared methods"); //$NON-NLS-1$
+		}
+		return this.members = NO_TYPE_BINDINGS;
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaringMethod()
+	 */
+	public synchronized IMethodBinding getDeclaringMethod() {
+		if (this.binding instanceof LocalTypeBinding) {
+			LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.binding;
+			MethodBinding methodBinding = localTypeBinding.enclosingMethod;
+			if (methodBinding != null) {
+				try {
+					return this.resolver.getMethodBinding(localTypeBinding.enclosingMethod);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+					org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring method"); //$NON-NLS-1$
+				}
+			}
+		} else if (this.binding.isTypeVariable()) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			Binding declaringElement = typeVariableBinding.declaringElement;
+			if (declaringElement instanceof MethodBinding) {
+				try {
+					return this.resolver.getMethodBinding((MethodBinding)declaringElement);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+					org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring method"); //$NON-NLS-1$
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see ITypeBinding#getDeclaringClass()
+	 */
+	public synchronized ITypeBinding getDeclaringClass() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			if (referenceBinding.isNestedType()) {
+				try {
+					return this.resolver.getTypeBinding(referenceBinding.enclosingType());
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+					org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring class"); //$NON-NLS-1$
+				}
+			}
+		} else if (this.binding.isTypeVariable()) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			Binding declaringElement = typeVariableBinding.isCapture() ? ((CaptureBinding) typeVariableBinding).sourceType : typeVariableBinding.declaringElement;
+			if (declaringElement instanceof ReferenceBinding) {
+				try {
+					return this.resolver.getTypeBinding((ReferenceBinding)declaringElement);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+					org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve declaring class"); //$NON-NLS-1$
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see ITypeBinding#getDimensions()
+	 */
+	public int getDimensions() {
+		if (!isArray()) {
+			return 0;
+		}
+		ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+		return arrayBinding.dimensions;
+	}
+
+	/*
+	 * @see ITypeBinding#getElementType()
+	 */
+	public ITypeBinding getElementType() {
+		if (!isArray()) {
+			return null;
+		}
+		ArrayBinding arrayBinding = (ArrayBinding) this.binding;
+		return this.resolver.getTypeBinding(arrayBinding.leafComponentType);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeDeclaration()
+	 */
+	public ITypeBinding getTypeDeclaration() {
+		if (this.binding instanceof ParameterizedTypeBinding)
+			return this.resolver.getTypeBinding(((ParameterizedTypeBinding)this.binding).genericType());
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getErasure()
+	 */
+	public ITypeBinding getErasure() {
+		return this.resolver.getTypeBinding(this.binding.erasure());
+	}
+
+	public synchronized ITypeBinding[] getInterfaces() {
+		if (this.interfaces != null) {
+			return this.interfaces;
+		}
+		if (this.binding == null)
+			return this.interfaces = NO_TYPE_BINDINGS;
+		switch (this.binding.kind()) {
+			case Binding.ARRAY_TYPE :
+			case Binding.BASE_TYPE :
+				return this.interfaces = NO_TYPE_BINDINGS;
+		}
+		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+		ReferenceBinding[] internalInterfaces = null;
+		try {
+			internalInterfaces = referenceBinding.superInterfaces();
+		} catch (RuntimeException e) {
+			/* in case a method cannot be resolvable due to missing jars on the classpath
+			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+			 */
+			org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve interfaces"); //$NON-NLS-1$
+		}
+		int length = internalInterfaces == null ? 0 : internalInterfaces.length;
+		if (length != 0) {
+			ITypeBinding[] newInterfaces = new ITypeBinding[length];
+			int interfacesCounter = 0;
+			for (int i = 0; i < length; i++) {
+				ITypeBinding typeBinding = this.resolver.getTypeBinding(internalInterfaces[i]);
+				if (typeBinding == null) {
+					continue;
+				}
+				newInterfaces[interfacesCounter++] = typeBinding;
+			}
+			if (length != interfacesCounter) {
+				System.arraycopy(newInterfaces, 0, (newInterfaces = new ITypeBinding[interfacesCounter]), 0, interfacesCounter);
+			}
+			return this.interfaces = newInterfaces;
+		}
+		return this.interfaces = NO_TYPE_BINDINGS;
+	}
+
+	public IJavaElement getJavaElement() {
+		JavaElement element = getUnresolvedJavaElement();
+		if (element != null)
+			return element.resolved(this.binding);
+		if (isRecovered()) {
+			IPackageBinding packageBinding = getPackage();
+			if (packageBinding != null) {
+				final IJavaElement javaElement = packageBinding.getJavaElement();
+				if (javaElement != null && javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+					// best effort: we don't know if the recovered binding is a binary or source binding, so go with a simple source type
+					return ((PackageFragment) javaElement).getCompilationUnit(new String(this.binding.sourceName()) + SuffixConstants.SUFFIX_STRING_java).getType(this.getName());
+				}
+			}
+			return null;
+		}
+		return null;
+	}
+
+	private JavaElement getUnresolvedJavaElement() {
+		return getUnresolvedJavaElement(this.binding);
+	}
+	private JavaElement getUnresolvedJavaElement(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding ) {
+		if (JavaCore.getPlugin() == null) {
+			return null;
+		}
+		if (this.resolver instanceof DefaultBindingResolver) {
+			DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
+			if (!defaultBindingResolver.fromJavaProject) return null;
+			return org.eclipse.jdt.internal.core.util.Util.getUnresolvedJavaElement(
+					typeBinding,
+					defaultBindingResolver.workingCopyOwner,
+					defaultBindingResolver.getBindingsToNodesMap());
+		}
+		return null;
+	}
+
+	/*
+	 * @see IBinding#getKey()
+	 */
+	public String getKey() {
+		if (this.key == null) {
+			this.key = new String(this.binding.computeUniqueKey());
+		}
+		return this.key;
+	}
+
+	/*
+	 * @see IBinding#getKind()
+	 */
+	public int getKind() {
+		return IBinding.TYPE;
+	}
+
+	/*
+	 * @see IBinding#getModifiers()
+	 */
+	public int getModifiers() {
+		if (isClass()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
+			if (referenceBinding.isAnonymousType()) {
+				return accessFlags & ~Modifier.FINAL;
+			}
+			return accessFlags;
+		} else if (isAnnotation()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
+			// clear the AccAbstract, AccAnnotation and the AccInterface bits
+			return accessFlags & ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation);
+		} else if (isInterface()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
+			// clear the AccAbstract and the AccInterface bits
+			return accessFlags & ~(ClassFileConstants.AccAbstract | ClassFileConstants.AccInterface);
+		} else if (isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
+			// clear the AccEnum bits
+			return accessFlags & ~ClassFileConstants.AccEnum;
+		} else {
+			return Modifier.NONE;
+		}
+	}
+
+	public String getName() {
+		StringBuffer buffer;
+		switch (this.binding.kind()) {
+
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(TypeConstants.WILDCARD_NAME);
+				if (wildcardBinding.bound != null) {
+					switch(wildcardBinding.boundKind) {
+				        case Wildcard.SUPER :
+				        	buffer.append(TypeConstants.WILDCARD_SUPER);
+				            break;
+				        case Wildcard.EXTENDS :
+				        	buffer.append(TypeConstants.WILDCARD_EXTENDS);
+					}
+					buffer.append(getBound().getName());
+				}
+				return String.valueOf(buffer);
+
+			case Binding.TYPE_PARAMETER :
+				if (isCapture()) {
+					return NO_NAME;
+				}
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+				return new String(typeVariableBinding.sourceName);
+
+			case Binding.PARAMETERIZED_TYPE :
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(parameterizedTypeBinding.sourceName());
+				ITypeBinding[] tArguments = getTypeArguments();
+				final int typeArgumentsLength = tArguments.length;
+				if (typeArgumentsLength != 0) {
+					buffer.append('<');
+					for (int i = 0; i < typeArgumentsLength; i++) {
+						if (i > 0) {
+							buffer.append(',');
+						}
+						buffer.append(tArguments[i].getName());
+					}
+					buffer.append('>');
+				}
+				return String.valueOf(buffer);
+
+			case Binding.RAW_TYPE :
+				return getTypeDeclaration().getName();
+
+			case Binding.ARRAY_TYPE :
+				ITypeBinding elementType = getElementType();
+				if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) {
+					return NO_NAME;
+				}
+				int dimensions = getDimensions();
+				char[] brackets = new char[dimensions * 2];
+				for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
+					brackets[i] = ']';
+					brackets[i - 1] = '[';
+				}
+				buffer = new StringBuffer(elementType.getName());
+				buffer.append(brackets);
+				return String.valueOf(buffer);
+
+			default :
+				if (isPrimitive() || isNullType()) {
+					BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
+					return new String(baseTypeBinding.simpleName);
+				}
+				if (isAnonymous()) {
+					return NO_NAME;
+				}
+				return new String(this.binding.sourceName());
+		}
+	}
+
+	/*
+	 * @see ITypeBinding#getPackage()
+	 */
+	public IPackageBinding getPackage() {
+		switch (this.binding.kind()) {
+			case Binding.BASE_TYPE :
+			case Binding.ARRAY_TYPE :
+			case Binding.TYPE_PARAMETER : // includes capture scenario
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+			case Binding.INTERSECTION_CAST_TYPE:
+				return null;
+		}
+		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+		return this.resolver.getPackageBinding(referenceBinding.getPackage());
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getQualifiedName()
+	 */
+	public String getQualifiedName() {
+		StringBuffer buffer;
+		switch (this.binding.kind()) {
+
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(TypeConstants.WILDCARD_NAME);
+				final ITypeBinding bound = getBound();
+				if (bound != null) {
+					switch(wildcardBinding.boundKind) {
+						case Wildcard.SUPER :
+							buffer.append(TypeConstants.WILDCARD_SUPER);
+							break;
+						case Wildcard.EXTENDS :
+							buffer.append(TypeConstants.WILDCARD_EXTENDS);
+					}
+					buffer.append(bound.getQualifiedName());
+				}
+				return String.valueOf(buffer);
+
+			case Binding.RAW_TYPE :
+				return getTypeDeclaration().getQualifiedName();
+
+			case Binding.ARRAY_TYPE :
+				ITypeBinding elementType = getElementType();
+				if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) {
+					return elementType.getQualifiedName();
+				}
+				final int dimensions = getDimensions();
+				char[] brackets = new char[dimensions * 2];
+				for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
+					brackets[i] = ']';
+					brackets[i - 1] = '[';
+				}
+				buffer = new StringBuffer(elementType.getQualifiedName());
+				buffer.append(brackets);
+				return String.valueOf(buffer);
+
+			case Binding.TYPE_PARAMETER :
+				if (isCapture()) {
+					return NO_NAME;
+				}
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+				return new String(typeVariableBinding.sourceName);
+
+			case Binding.PARAMETERIZED_TYPE :
+				if (this.binding.isLocalType()) {
+					return NO_NAME;
+				}
+				buffer = new StringBuffer();
+				if (isMember()) {
+					buffer
+						.append(getDeclaringClass().getQualifiedName())
+						.append('.');
+					ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
+					buffer.append(parameterizedTypeBinding.sourceName());
+					ITypeBinding[] tArguments = getTypeArguments();
+					final int typeArgumentsLength = tArguments.length;
+					if (typeArgumentsLength != 0) {
+						buffer.append('<');
+						for (int i = 0; i < typeArgumentsLength; i++) {
+							if (i > 0) {
+								buffer.append(',');
+							}
+							buffer.append(tArguments[i].getQualifiedName());
+						}
+						buffer.append('>');
+					}
+					return String.valueOf(buffer);
+				}
+				buffer.append(getTypeDeclaration().getQualifiedName());
+				ITypeBinding[] tArguments = getTypeArguments();
+				final int typeArgumentsLength = tArguments.length;
+				if (typeArgumentsLength != 0) {
+					buffer.append('<');
+					for (int i = 0; i < typeArgumentsLength; i++) {
+						if (i > 0) {
+							buffer.append(',');
+						}
+						buffer.append(tArguments[i].getQualifiedName());
+					}
+					buffer.append('>');
+				}
+				return String.valueOf(buffer);
+			default :
+				if (isAnonymous() || this.binding.isLocalType() || this.binding.isIntersectionCastType()) {
+					return NO_NAME;
+				}
+				if (isPrimitive() || isNullType()) {
+					BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
+					return new String(baseTypeBinding.simpleName);
+				}
+				if (isMember()) {
+					buffer = new StringBuffer();
+					buffer
+						.append(getDeclaringClass().getQualifiedName())
+						.append('.');
+					buffer.append(getName());
+					return String.valueOf(buffer);
+				}
+				PackageBinding packageBinding = this.binding.getPackage();
+				buffer = new StringBuffer();
+				if (packageBinding != null && packageBinding.compoundName != CharOperation.NO_CHAR_CHAR) {
+					buffer.append(CharOperation.concatWith(packageBinding.compoundName, '.')).append('.');
+				}
+				buffer.append(getName());
+				return String.valueOf(buffer);
+		}
+	}
+
+	/*
+	 * @see ITypeBinding#getSuperclass()
+	 */
+	public synchronized ITypeBinding getSuperclass() {
+		if (this.binding == null)
+			return null;
+		switch (this.binding.kind()) {
+			case Binding.ARRAY_TYPE :
+			case Binding.BASE_TYPE :
+				return null;
+			default:
+				// no superclass for interface types (interface | annotation type)
+				if (this.binding.isInterface())
+					return null;
+		}
+		ReferenceBinding superclass = null;
+		try {
+			superclass = ((ReferenceBinding)this.binding).superclass();
+		} catch (RuntimeException e) {
+			/* in case a method cannot be resolvable due to missing jars on the classpath
+			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+			 */
+			org.eclipse.jdt.internal.core.util.Util.log(e, "Could not retrieve superclass"); //$NON-NLS-1$
+			return this.resolver.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
+		}
+		if (superclass == null) {
+			return null;
+		}
+		return this.resolver.getTypeBinding(superclass);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeArguments()
+	 */
+	public ITypeBinding[] getTypeArguments() {
+		if (this.typeArguments != null) {
+			return this.typeArguments;
+		}
+		if (this.binding.isParameterizedTypeWithActualArguments()) {
+			ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
+			final org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] arguments = parameterizedTypeBinding.arguments;
+			int argumentsLength = arguments.length;
+			ITypeBinding[] newTypeArguments = new ITypeBinding[argumentsLength];
+			for (int i = 0; i < argumentsLength; i++) {
+				ITypeBinding typeBinding = this.resolver.getTypeBinding(arguments[i]);
+				if (typeBinding == null) {
+					return this.typeArguments = NO_TYPE_BINDINGS;
+				}
+				newTypeArguments[i] = typeBinding;
+			}
+			return this.typeArguments = newTypeArguments;
+		}
+		return this.typeArguments = NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeBounds()
+	 */
+	public ITypeBinding[] getTypeBounds() {
+		if (this.bounds != null) {
+			return this.bounds;
+		}
+		if (this.binding instanceof TypeVariableBinding) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			ReferenceBinding varSuperclass = typeVariableBinding.superclass();
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound;
+			int boundsLength = 0;
+			if (firstClassOrArrayBound != null) {
+				if (firstClassOrArrayBound == varSuperclass) {
+					boundsLength++;
+				} else if (firstClassOrArrayBound.isArrayType()) { // capture of ? extends/super arrayType
+					boundsLength++;
+				} else {
+					firstClassOrArrayBound = null;
+				}
+			}
+			ReferenceBinding[] superinterfaces = typeVariableBinding.superInterfaces();
+			int superinterfacesLength = 0;
+			if (superinterfaces != null) {
+				superinterfacesLength = superinterfaces.length;
+				boundsLength += superinterfacesLength;
+			}
+			if (boundsLength != 0) {
+				ITypeBinding[] typeBounds = new ITypeBinding[boundsLength];
+				int boundsIndex = 0;
+				if (firstClassOrArrayBound != null) {
+					ITypeBinding typeBinding = this.resolver.getTypeBinding(firstClassOrArrayBound);
+					if (typeBinding == null) {
+						return this.bounds = NO_TYPE_BINDINGS;
+					}
+					typeBounds[boundsIndex++] = typeBinding;
+				}
+				if (superinterfaces != null) {
+					for (int i = 0; i < superinterfacesLength; i++, boundsIndex++) {
+						ITypeBinding typeBinding = this.resolver.getTypeBinding(superinterfaces[i]);
+						if (typeBinding == null) {
+							return this.bounds = NO_TYPE_BINDINGS;
+						}
+						typeBounds[boundsIndex] = typeBinding;
+					}
+				}
+				return this.bounds = typeBounds;
+			}
+		}
+		return this.bounds = NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeParameters()
+	 */
+	public ITypeBinding[] getTypeParameters() {
+		if (this.typeParameters != null) {
+			return this.typeParameters;
+		}
+		switch(this.binding.kind()) {
+			case Binding.RAW_TYPE :
+			case Binding.PARAMETERIZED_TYPE :
+				return this.typeParameters = NO_TYPE_BINDINGS;
+		}
+		TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
+		int typeVariableBindingsLength = typeVariableBindings == null ? 0 : typeVariableBindings.length;
+		if (typeVariableBindingsLength != 0) {
+			ITypeBinding[] newTypeParameters = new ITypeBinding[typeVariableBindingsLength];
+			for (int i = 0; i < typeVariableBindingsLength; i++) {
+				ITypeBinding typeBinding = this.resolver.getTypeBinding(typeVariableBindings[i]);
+				if (typeBinding == null) {
+					return this.typeParameters = NO_TYPE_BINDINGS;
+				}
+				newTypeParameters[i] = typeBinding;
+			}
+			return this.typeParameters = newTypeParameters;
+		}
+		return this.typeParameters = NO_TYPE_BINDINGS;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getWildcard()
+	 * @since 3.1
+	 */
+	public ITypeBinding getWildcard() {
+		if (this.binding instanceof CaptureBinding) {
+			CaptureBinding captureBinding = (CaptureBinding) this.binding;
+			return this.resolver.getTypeBinding(captureBinding.wildcard);
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isGenericType()
+	 * @since 3.1
+	 */
+	public boolean isGenericType() {
+		// equivalent to return getTypeParameters().length > 0;
+		if (isRawType()) {
+			return false;
+		}
+		TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
+		return (typeVariableBindings != null && typeVariableBindings.length > 0);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isAnnotation()
+	 */
+	public boolean isAnnotation() {
+		return this.binding.isAnnotationType();
+	}
+
+	/*
+	 * @see ITypeBinding#isAnonymous()
+	 */
+	public boolean isAnonymous() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return referenceBinding.isAnonymousType();
+		}
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isArray()
+	 */
+	public boolean isArray() {
+		return this.binding.isArrayType();
+	}
+
+	/* (non-Javadoc)
+	 * @see ITypeBinding#isAssignmentCompatible(ITypeBinding)
+	 */
+	public boolean isAssignmentCompatible(ITypeBinding type) {
+		try {
+			if (this == type) return true;
+			if (!(type instanceof TypeBinding)) return false;
+			TypeBinding other = (TypeBinding) type;
+			Scope scope = this.resolver.scope();
+			if (scope == null) return false;
+			return this.binding.isCompatibleWith(other.binding) || scope.isBoxingCompatibleWith(this.binding, other.binding);
+		} catch (AbortCompilation e) {
+			// don't surface internal exception to clients
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
+			return false;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see ITypeBinding#isCapture()
+	 */
+	public boolean isCapture() {
+		return this.binding.isCapture();
+	}
+
+	/* (non-Javadoc)
+	 * @see ITypeBinding#isCastCompatible(ITypeBinding)
+	 */
+	public boolean isCastCompatible(ITypeBinding type) {
+		try {
+			Scope scope = this.resolver.scope();
+			if (scope == null) return false;
+			if (!(type instanceof TypeBinding)) return false;
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding expressionType = ((TypeBinding) type).binding;
+			// simulate capture in case checked binding did not properly get extracted from a reference
+			expressionType = expressionType.capture(scope, 0);
+			return TypeBinding.EXPRESSION.checkCastTypesCompatibility(scope, this.binding, expressionType, null);
+		} catch (AbortCompilation e) {
+			// don't surface internal exception to clients
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
+			return false;
+		}
+	}
+
+	/*
+	 * @see ITypeBinding#isClass()
+	 */
+	public boolean isClass() {
+		switch (this.binding.kind()) {
+			case Binding.TYPE_PARAMETER :
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE :
+				return false;
+		}
+		return this.binding.isClass();
+	}
+
+	/*
+	 * @see IBinding#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return referenceBinding.isDeprecated();
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see ITypeBinding#isEnum()
+	 */
+	public boolean isEnum() {
+		return this.binding.isEnum();
+	}
+
+	/*
+	 * @see IBinding#isEqualTo(Binding)
+	 * @since 3.1
+	 */
+	public boolean isEqualTo(IBinding other) {
+		if (other == this) {
+			// identical binding - equal (key or no key)
+			return true;
+		}
+		if (other == null) {
+			// other binding missing
+			return false;
+		}
+		if (!(other instanceof TypeBinding)) {
+			return false;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.TypeBinding otherBinding = ((TypeBinding) other).binding;
+		// check return type
+		return BindingComparator.isEqual(this.binding, otherBinding);
+	}
+
+	/*
+	 * @see ITypeBinding#isFromSource()
+	 */
+	public boolean isFromSource() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			if (referenceBinding.isRawType()) {
+				return !((RawTypeBinding) referenceBinding).genericType().isBinaryBinding();
+			} else if (referenceBinding.isParameterizedType()) {
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) referenceBinding;
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding erasure = parameterizedTypeBinding.erasure();
+				if (erasure instanceof ReferenceBinding) {
+					return !((ReferenceBinding) erasure).isBinaryBinding();
+				}
+				return false;
+			} else {
+				return !referenceBinding.isBinaryBinding();
+			}
+		} else if (isTypeVariable()) {
+			final TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			final Binding declaringElement = typeVariableBinding.declaringElement;
+			if (declaringElement instanceof MethodBinding) {
+				MethodBinding methodBinding = (MethodBinding) declaringElement;
+				return !methodBinding.declaringClass.isBinaryBinding();
+			} else {
+				final org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement;
+				if (typeBinding instanceof ReferenceBinding) {
+					return !((ReferenceBinding) typeBinding).isBinaryBinding();
+				} else if (typeBinding instanceof ArrayBinding) {
+					final ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
+					final org.eclipse.jdt.internal.compiler.lookup.TypeBinding leafComponentType = arrayBinding.leafComponentType;
+					if (leafComponentType instanceof ReferenceBinding) {
+						return !((ReferenceBinding) leafComponentType).isBinaryBinding();
+					}
+				}
+			}
+
+		} else if (isCapture()) {
+			CaptureBinding captureBinding = (CaptureBinding) this.binding;
+			return !captureBinding.sourceType.isBinaryBinding();
+		}
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isInterface()
+	 */
+	public boolean isInterface() {
+		switch (this.binding.kind()) {
+			case Binding.TYPE_PARAMETER :
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE :
+				return false;
+		}
+		return this.binding.isInterface();
+	}
+
+	/*
+	 * @see ITypeBinding#isLocal()
+	 */
+	public boolean isLocal() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return referenceBinding.isLocalType() && !referenceBinding.isMemberType();
+		}
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isMember()
+	 */
+	public boolean isMember() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return referenceBinding.isMemberType();
+		}
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isNested()
+	 */
+	public boolean isNested() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return referenceBinding.isNestedType();
+		}
+		return false;
+	}
+
+	/**
+	 * @see ITypeBinding#isNullType()
+	 */
+	public boolean isNullType() {
+		return this.binding == org.eclipse.jdt.internal.compiler.lookup.TypeBinding.NULL;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isParameterizedType()
+	 */
+	public boolean isParameterizedType() {
+		return this.binding.isParameterizedTypeWithActualArguments();
+	}
+
+	/*
+	 * @see ITypeBinding#isPrimitive()
+	 */
+	public boolean isPrimitive() {
+		return !isNullType() && this.binding.isBaseType();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isRawType()
+	 */
+	public boolean isRawType() {
+		return this.binding.isRawType();
+	}
+
+	/* (non-Javadoc)
+	 * @see IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return (this.binding.tagBits & TagBits.HasMissingType) != 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see ITypeBinding#isSubTypeCompatible(ITypeBinding)
+	 */
+	public boolean isSubTypeCompatible(ITypeBinding type) {
+		try {
+			if (this == type) return true;
+			if (this.binding.isBaseType()) return false;
+			if (!(type instanceof TypeBinding)) return false;
+			TypeBinding other = (TypeBinding) type;
+			if (other.binding.isBaseType()) return false;
+			return this.binding.isCompatibleWith(other.binding);
+		} catch (AbortCompilation e) {
+			// don't surface internal exception to clients
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
+			return false;
+		}
+	}
+
+	/**
+	 * @see IBinding#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isTopLevel()
+	 */
+	public boolean isTopLevel() {
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			return !referenceBinding.isNestedType();
+		}
+		return false;
+	}
+
+	/*
+	 * @see ITypeBinding#isTypeVariable()
+	 */
+	public boolean isTypeVariable() {
+		return this.binding.isTypeVariable() && !this.binding.isCapture();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isUpperbound()
+	 */
+	public boolean isUpperbound() {
+		switch (this.binding.kind()) {
+			case Binding.WILDCARD_TYPE :
+				return ((WildcardBinding) this.binding).boundKind == Wildcard.EXTENDS;
+			case Binding.INTERSECTION_TYPE :
+				return true;
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isWildcardType()
+	 */
+	public boolean isWildcardType() {
+		return this.binding.isWildcard();
+	}
+
+	/*
+	 * For debugging purpose only.
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.binding.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java
new file mode 100644
index 0000000..d56807f
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java
@@ -0,0 +1,809 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Type declaration AST node type. A type declaration
+ * is the union of a class declaration and an interface declaration.
+ * 
+ * <pre>
+ * TypeDeclaration:
+ * 		ClassDeclaration
+ * 		InterfaceDeclaration
+ * ClassDeclaration:
+ *      [ Javadoc ] { ExtendedModifier } <b>class</b> Identifier
+ *			[ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
+ *			[ <b>extends</b> Type ]
+ *			[ <b>implements</b> Type { <b>,</b> Type } ]
+ *			<b>{</b> { ClassBodyDeclaration | <b>;</b> } <b>}</b>
+ * InterfaceDeclaration:
+ *      [ Javadoc ] { ExtendedModifier } <b>interface</b> Identifier
+ *			[ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
+ *			[ <b>extends</b> Type { <b>,</b> Type } ]
+ * 			<b>{</b> { InterfaceBodyDeclaration | <b>;</b> } <b>}</b>
+ * </pre>
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier or annotation (if any), or the
+ * first character of the "class" or "interface" keyword (if no
+ * modifiers or annotations). The source range extends through the last character of the "}"
+ * token following the body declarations.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeDeclaration extends AbstractTypeDeclaration {
+
+	/**
+	 * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+		internalJavadocPropertyFactory(TypeDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		internalModifiersPropertyFactory(TypeDeclaration.class);
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		internalModifiers2PropertyFactory(TypeDeclaration.class);
+
+	/**
+	 * The "interface" structural property of this node type (type: {@link Boolean}).
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor INTERFACE_PROPERTY =
+		new SimplePropertyDescriptor(TypeDeclaration.class, "interface", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		internalNamePropertyFactory(TypeDeclaration.class);
+
+	/**
+	 * The "superclass" structural property of this node type (child type: {@link Name}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #SUPERCLASS_TYPE_PROPERTY}.
+	 */
+	public static final ChildPropertyDescriptor SUPERCLASS_PROPERTY =
+		new ChildPropertyDescriptor(TypeDeclaration.class, "superclass", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "superInterfaces" structural property of this node type (element type: {@link Name}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #SUPER_INTERFACE_TYPES_PROPERTY}.
+	 */
+	public static final ChildListPropertyDescriptor SUPER_INTERFACES_PROPERTY =
+		new ChildListPropertyDescriptor(TypeDeclaration.class, "superInterfaces", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "superclassType" structural property of this node type (child type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildPropertyDescriptor SUPERCLASS_TYPE_PROPERTY =
+		new ChildPropertyDescriptor(TypeDeclaration.class, "superclassType", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "superInterfaceTypes" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor SUPER_INTERFACE_TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(TypeDeclaration.class, "superInterfaceTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY =
+		new ChildListPropertyDescriptor(TypeDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}) (added in JLS3 API).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
+		internalBodyDeclarationPropertyFactory(TypeDeclaration.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(8);
+		createPropertyList(TypeDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(MODIFIERS_PROPERTY, propertyList);
+		addProperty(INTERFACE_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(SUPERCLASS_PROPERTY, propertyList);
+		addProperty(SUPER_INTERFACES_PROPERTY, propertyList);
+		addProperty(BODY_DECLARATIONS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(9);
+		createPropertyList(TypeDeclaration.class, propertyList);
+		addProperty(JAVADOC_PROPERTY, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(INTERFACE_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
+		addProperty(SUPERCLASS_TYPE_PROPERTY, propertyList);
+		addProperty(SUPER_INTERFACE_TYPES_PROPERTY, propertyList);
+		addProperty(BODY_DECLARATIONS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * <code>true</code> for an interface, <code>false</code> for a class.
+	 * Defaults to class.
+	 */
+	private boolean isInterface = false;
+
+	/**
+	 * The type parameters (element type: {@link TypeParameter}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList typeParameters = null;
+
+	/**
+	 * The optional superclass name; <code>null</code> if none.
+	 * Defaults to none. Note that this field is not used for
+	 * interface declarations. Not used in 3.0.
+	 */
+	private Name optionalSuperclassName = null;
+
+	/**
+	 * The superinterface names (element type: {@link Name}).
+	 * JLS2 only; defaults to an empty list. Not used in JLS3.
+	 * (see constructor).
+	 *
+	 */
+	private ASTNode.NodeList superInterfaceNames = null;
+
+	/**
+	 * The optional superclass type; <code>null</code> if none.
+	 * Defaults to none. Note that this field is not used for
+	 * interface declarations. Null in JLS2. Added in JLS3.
+	 * @since 3.1
+	 */
+	private Type optionalSuperclassType = null;
+
+	/**
+	 * The superinterface types (element type: {@link Type}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList superInterfaceTypes = null;
+
+	/**
+	 * Creates a new AST node for a type declaration owned by the given
+	 * AST. By default, the type declaration is for a class of an
+	 * unspecified, but legal, name; no modifiers; no javadoc;
+	 * no type parameters; no superclass or superinterfaces; and an empty list
+	 * of body declarations.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TypeDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel == AST.JLS2_INTERNAL) {
+			this.superInterfaceNames = new ASTNode.NodeList(SUPER_INTERFACES_PROPERTY);
+		}
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY);
+			this.superInterfaceTypes = new ASTNode.NodeList(SUPER_INTERFACE_TYPES_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				internalSetModifiers(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == INTERFACE_PROPERTY) {
+			if (get) {
+				return isInterface();
+			} else {
+				setInterface(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == JAVADOC_PROPERTY) {
+			if (get) {
+				return getJavadoc();
+			} else {
+				setJavadoc((Javadoc) child);
+				return null;
+			}
+		}
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == SUPERCLASS_PROPERTY) {
+			if (get) {
+				return getSuperclass();
+			} else {
+				setSuperclass((Name) child);
+				return null;
+			}
+		}
+		if (property == SUPERCLASS_TYPE_PROPERTY) {
+			if (get) {
+				return getSuperclassType();
+			} else {
+				setSuperclassType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == TYPE_PARAMETERS_PROPERTY) {
+			return typeParameters();
+		}
+		if (property == SUPER_INTERFACES_PROPERTY) {
+			return superInterfaces();
+		}
+		if (property == SUPER_INTERFACE_TYPES_PROPERTY) {
+			return superInterfaceTypes();
+		}
+		if (property == BODY_DECLARATIONS_PROPERTY) {
+			return bodyDeclarations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildPropertyDescriptor internalJavadocProperty() {
+		return JAVADOC_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalModifiers2Property() {
+		return MODIFIERS2_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on BodyDeclaration.
+	 */
+	final SimplePropertyDescriptor internalModifiersProperty() {
+		return MODIFIERS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildPropertyDescriptor internalNameProperty() {
+		return NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AbstractTypeDeclaration.
+	 */
+	final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
+		return BODY_DECLARATIONS_PROPERTY;
+	}
+
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TYPE_DECLARATION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TypeDeclaration result = new TypeDeclaration(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setJavadoc(
+			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
+			result.setSuperclass(
+					(Name) ASTNode.copySubtree(target, getSuperclass()));
+			result.superInterfaces().addAll(
+					ASTNode.copySubtrees(target, superInterfaces()));
+		}
+		result.setInterface(isInterface());
+		result.setName((SimpleName) getName().clone(target));
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+			result.typeParameters().addAll(
+					ASTNode.copySubtrees(target, typeParameters()));
+			result.setSuperclassType(
+					(Type) ASTNode.copySubtree(target, getSuperclassType()));
+			result.superInterfaceTypes().addAll(
+					ASTNode.copySubtrees(target, superInterfaceTypes()));
+		}
+		result.bodyDeclarations().addAll(
+			ASTNode.copySubtrees(target, bodyDeclarations()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+				acceptChild(visitor, getJavadoc());
+				acceptChild(visitor, getName());
+				acceptChild(visitor, getSuperclass());
+				acceptChildren(visitor, this.superInterfaceNames);
+				acceptChildren(visitor, this.bodyDeclarations);
+			}
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChild(visitor, getJavadoc());
+				acceptChildren(visitor, this.modifiers);
+				acceptChild(visitor, getName());
+				acceptChildren(visitor, this.typeParameters);
+				acceptChild(visitor, getSuperclassType());
+				acceptChildren(visitor, this.superInterfaceTypes);
+				acceptChildren(visitor, this.bodyDeclarations);
+			}
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns whether this type declaration declares a class or an
+	 * interface.
+	 *
+	 * @return <code>true</code> if this is an interface declaration,
+	 *    and <code>false</code> if this is a class declaration
+	 */
+	public boolean isInterface() {
+		return this.isInterface;
+	}
+
+	/**
+	 * Sets whether this type declaration declares a class or an
+	 * interface.
+	 *
+	 * @param isInterface <code>true</code> if this is an interface
+	 *    declaration, and <code>false</code> if this is a class
+	 * 	  declaration
+	 */
+	public void setInterface(boolean isInterface) {
+		preValueChange(INTERFACE_PROPERTY);
+		this.isInterface = isInterface;
+		postValueChange(INTERFACE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type parameters of this type
+	 * declaration (added in JLS3 API). This list is non-empty for parameterized types.
+	 *
+	 * @return the live list of type parameters
+	 *    (element type: {@link TypeParameter})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List typeParameters() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.typeParameters == null) {
+			unsupportedIn2();
+		}
+		return this.typeParameters;
+	}
+
+	/**
+	 * Returns the name of the superclass declared in this type
+	 * declaration, or <code>null</code> if there is none (JLS2 API only).
+	 * <p>
+	 * Note that this child is not relevant for interface
+	 * declarations (although it does still figure in subtree
+	 * equality comparisons).
+	 * </p>
+	 *
+	 * @return the superclass name node, or <code>null</code> if
+	 *    there is none
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #getSuperclassType()}, which returns a <code>Type</code>
+	 * instead of a <code>Name</code>.
+	 */
+	public Name getSuperclass() {
+		return internalGetSuperclass();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final Name internalGetSuperclass() {
+		supportedOnlyIn2();
+		return this.optionalSuperclassName;
+	}
+
+	/**
+	* Returns the superclass declared in this type
+	* declaration, or <code>null</code> if there is none (added in JLS3 API).
+	* <p>
+	* Note that this child is not relevant for interface
+	* declarations (although it does still figure in subtree
+	* equality comparisons).
+	* </p>
+	*
+	* @return the superclass type node, or <code>null</code> if
+	*    there is none
+	* @exception UnsupportedOperationException if this operation is used in
+	* a JLS2 AST
+	* @since 3.1
+	*/
+	public Type getSuperclassType() {
+	    unsupportedIn2();
+		return this.optionalSuperclassType;
+	}
+
+	/**
+	 * Sets or clears the name of the superclass declared in this type
+	 * declaration (JLS2 API only).
+	 * <p>
+	 * Note that this child is not relevant for interface
+	 * declarations (although it does still figure in subtree
+	 * equality comparisons).
+	 * </p>
+	 *
+	 * @param superclassName the superclass name node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #setSuperclassType(Type)}, which expects a
+	 * <code>Type</code> instead of a <code>Name</code>.
+	 */
+	public void setSuperclass(Name superclassName) {
+		internalSetSuperclass(superclassName);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetSuperclass(Name superclassName) {
+	    supportedOnlyIn2();
+		ASTNode oldChild = this.optionalSuperclassName;
+		preReplaceChild(oldChild, superclassName, SUPERCLASS_PROPERTY);
+		this.optionalSuperclassName = superclassName;
+		postReplaceChild(oldChild, superclassName, SUPERCLASS_PROPERTY);
+	}
+
+	/**
+	 * Sets or clears the superclass declared in this type
+	 * declaration (added in JLS3 API).
+	 * <p>
+	 * Note that this child is not relevant for interface declarations
+	 * (although it does still figure in subtree equality comparisons).
+	 * </p>
+	 *
+	 * @param superclassType the superclass type node, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public void setSuperclassType(Type superclassType) {
+	    unsupportedIn2();
+		ASTNode oldChild = this.optionalSuperclassType;
+		preReplaceChild(oldChild, superclassType, SUPERCLASS_TYPE_PROPERTY);
+		this.optionalSuperclassType = superclassType;
+		postReplaceChild(oldChild, superclassType, SUPERCLASS_TYPE_PROPERTY);
+ 	}
+
+	/**
+	 * Returns the live ordered list of names of superinterfaces of this type
+	 * declaration (JLS2 API only). For a class declaration, these are the names
+	 * of the interfaces that this class implements; for an interface
+	 * declaration, these are the names of the interfaces that this interface
+	 * extends.
+	 *
+	 * @return the live list of interface names
+	 *    (element type: {@link Name})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #superInterfaceTypes()}.
+	 */
+	public List superInterfaces() {
+		return internalSuperInterfaces();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final List internalSuperInterfaces() {
+		// more efficient than just calling supportedOnlyIn2() to check
+		if (this.superInterfaceNames == null) {
+			supportedOnlyIn2();
+		}
+		return this.superInterfaceNames;
+	}
+
+	/**
+	 * Returns the live ordered list of superinterfaces of this type
+	 * declaration (added in JLS3 API). For a class declaration, these are the interfaces
+	 * that this class implements; for an interface declaration,
+	 * these are the interfaces that this interface extends.
+	 *
+	 * @return the live list of interface types
+	 *    (element type: {@link Type})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List superInterfaceTypes() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.superInterfaceTypes == null) {
+			unsupportedIn2();
+		}
+		return this.superInterfaceTypes;
+	}
+
+	/**
+	 * Returns the ordered list of field declarations of this type
+	 * declaration. For a class declaration, these are the
+	 * field declarations; for an interface declaration, these are
+	 * the constant declarations.
+	 * <p>
+	 * This convenience method returns this node's body declarations
+	 * with non-fields filtered out. Unlike <code>bodyDeclarations</code>,
+	 * this method does not return a live result.
+	 * </p>
+	 *
+	 * @return the (possibly empty) list of field declarations
+	 */
+	public FieldDeclaration[] getFields() {
+		List bd = bodyDeclarations();
+		int fieldCount = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			if (it.next() instanceof FieldDeclaration) {
+				fieldCount++;
+			}
+		}
+		FieldDeclaration[] fields = new FieldDeclaration[fieldCount];
+		int next = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			Object decl = it.next();
+			if (decl instanceof FieldDeclaration) {
+				fields[next++] = (FieldDeclaration) decl;
+			}
+		}
+		return fields;
+	}
+
+	/**
+	 * Returns the ordered list of method declarations of this type
+	 * declaration.
+	 * <p>
+	 * This convenience method returns this node's body declarations
+	 * with non-methods filtered out. Unlike <code>bodyDeclarations</code>,
+	 * this method does not return a live result.
+	 * </p>
+	 *
+	 * @return the (possibly empty) list of method (and constructor)
+	 *    declarations
+	 */
+	public MethodDeclaration[] getMethods() {
+		List bd = bodyDeclarations();
+		int methodCount = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			if (it.next() instanceof MethodDeclaration) {
+				methodCount++;
+			}
+		}
+		MethodDeclaration[] methods = new MethodDeclaration[methodCount];
+		int next = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			Object decl = it.next();
+			if (decl instanceof MethodDeclaration) {
+				methods[next++] = (MethodDeclaration) decl;
+			}
+		}
+		return methods;
+	}
+
+	/**
+	 * Returns the ordered list of member type declarations of this type
+	 * declaration.
+	 * <p>
+	 * This convenience method returns this node's body declarations
+	 * with non-types filtered out. Unlike <code>bodyDeclarations</code>,
+	 * this method does not return a live result.
+	 * </p>
+	 *
+	 * @return the (possibly empty) list of member type declarations
+	 */
+	public TypeDeclaration[] getTypes() {
+		List bd = bodyDeclarations();
+		int typeCount = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			if (it.next() instanceof TypeDeclaration) {
+				typeCount++;
+			}
+		}
+		TypeDeclaration[] memberTypes = new TypeDeclaration[typeCount];
+		int next = 0;
+		for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+			Object decl = it.next();
+			if (decl instanceof TypeDeclaration) {
+				memberTypes[next++] = (TypeDeclaration) decl;
+			}
+		}
+		return memberTypes;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AsbtractTypeDeclaration.
+	 */
+	ITypeBinding internalResolveBinding() {
+		return this.ast.getBindingResolver().resolveType(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 6 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return memSize()
+			+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.typeName == null ? 0 : getName().treeSize())
+			+ (this.typeParameters == null ? 0 : this.typeParameters.listSize())
+			+ (this.optionalSuperclassName == null ? 0 : getSuperclass().treeSize())
+			+ (this.optionalSuperclassType == null ? 0 : getSuperclassType().treeSize())
+			+ (this.superInterfaceNames == null ? 0 : this.superInterfaceNames.listSize())
+			+ (this.superInterfaceTypes == null ? 0 : this.superInterfaceTypes.listSize())
+			+ this.bodyDeclarations.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java
new file mode 100644
index 0000000..515b5a7
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Local type declaration statement AST node type.
+ * <p>
+ * This kind of node is used to convert a type declaration
+ * node into a statement node by wrapping it.
+ * </p>
+ * <pre>
+ * TypeDeclarationStatement:
+ *    TypeDeclaration
+ *    EnumDeclaration
+ * </pre>
+ * Although allowed at the AST, not all arrangements of AST nodes are meaningful;
+ * in particular, only class and enum declarations are meaningful in the context of
+ * a block.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeDeclarationStatement extends Statement {
+
+	/**
+	 * The "typeDeclaration" structural property of this node type (child type: {@link TypeDeclaration}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #DECLARATION_PROPERTY}.
+	 */
+	public static final ChildPropertyDescriptor TYPE_DECLARATION_PROPERTY =
+		new ChildPropertyDescriptor(TypeDeclarationStatement.class, "typeDeclaration", TypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "declaration" structural property of this node type (child type: {@link AbstractTypeDeclaration}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildPropertyDescriptor DECLARATION_PROPERTY =
+		new ChildPropertyDescriptor(TypeDeclarationStatement.class, "declaration", AbstractTypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(TypeDeclarationStatement.class, propertyList);
+		addProperty(TYPE_DECLARATION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(2);
+		createPropertyList(TypeDeclarationStatement.class, propertyList);
+		addProperty(DECLARATION_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The type declaration; lazily initialized; defaults to a unspecified,
+	 * but legal, type declaration. In JLS2, corresponds to TYPE_DECLARATION_PROPERTY.
+     * After JLS2, corresponds to DECLARATION_PROPERTY.
+     * @see #typeDeclProperty
+	 */
+	private AbstractTypeDeclaration typeDecl = null;
+
+    /**
+     * The child property stored on the <code>typeDecl</code> instance variable.
+     * In JLS2, corresponds to TYPE_DECLARATION_PROPERTY. After JLS2, corresponds to
+     * DECLARATION_PROPERTY.
+     *
+     * @return the property corresponding to the <code>typeDecl</code> instance variable;
+     * never <code>null</code>
+     */
+    private ChildPropertyDescriptor typeDeclProperty () {
+        if (getAST().apiLevel() == AST.JLS2_INTERNAL) {
+            return TYPE_DECLARATION_PROPERTY;
+        } else {
+            return DECLARATION_PROPERTY;
+        }
+    }
+
+
+	/**
+	 * Creates a new unparented local type declaration statement node owned
+	 * by the given AST. By default, the local type declaration is an
+	 * unspecified, but legal, type declaration.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TypeDeclarationStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 * @since 3.0
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_DECLARATION_PROPERTY) {
+			if (get) {
+				return getTypeDeclaration();
+			} else {
+				setTypeDeclaration((TypeDeclaration) child);
+				return null;
+			}
+		}
+		if (property == DECLARATION_PROPERTY) {
+			if (get) {
+				return getDeclaration();
+			} else {
+				setDeclaration((AbstractTypeDeclaration) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TYPE_DECLARATION_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TypeDeclarationStatement result =
+			new TypeDeclarationStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setDeclaration(
+			(AbstractTypeDeclaration) getDeclaration().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getDeclaration());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the abstract type declaration of this local type declaration
+	 * statement (added in JLS3 API).
+	 *
+	 * @return the type declaration node
+	 * @since 3.1
+	 */
+	public AbstractTypeDeclaration getDeclaration() {
+		if (this.typeDecl == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeDecl == null) {
+					preLazyInit();
+					this.typeDecl = new TypeDeclaration(this.ast);
+					postLazyInit(this.typeDecl, typeDeclProperty());
+				}
+			}
+		}
+		return this.typeDecl;
+	}
+
+	/**
+	 * Sets the abstract type declaration of this local type declaration
+	 * statement (added in JLS3 API).
+	 *
+	 * @param decl the type declaration node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 * @since 3.1
+	 */
+	public void setDeclaration(AbstractTypeDeclaration decl) {
+		if (decl == null) {
+			throw new IllegalArgumentException();
+		}
+		// a TypeDeclarationStatement may occur inside an
+		// TypeDeclaration - must check cycles
+		ASTNode oldChild = this.typeDecl;
+		ChildPropertyDescriptor typeDeclProperty = typeDeclProperty();
+		preReplaceChild(oldChild, decl, typeDeclProperty);
+		this.typeDecl= decl;
+		postReplaceChild(oldChild, decl, typeDeclProperty);
+	}
+
+	/**
+	 * Returns the type declaration of this local type declaration
+	 * statement (JLS2 API only).
+	 *
+	 * @return the type declaration node
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #getDeclaration()}, which returns <code>AbstractTypeDeclaration</code>
+	 * instead of <code>TypeDeclaration</code>.
+	 */
+	public TypeDeclaration getTypeDeclaration() {
+		return internalGetTypeDeclaration();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final TypeDeclaration internalGetTypeDeclaration() {
+		supportedOnlyIn2();
+		return (TypeDeclaration) getDeclaration();
+	}
+
+	/**
+	 * Sets the type declaration of this local type declaration
+	 * statement (JLS2 API only).
+	 *
+	 * @param decl the type declaration node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+     * @deprecated In the JLS3 API, this method is replaced by
+     * {@link #setDeclaration(AbstractTypeDeclaration)} which takes
+     * <code>AbstractTypeDeclaration</code> instead of
+     * <code>TypeDeclaration</code>.
+	 */
+	public void setTypeDeclaration(TypeDeclaration decl) {
+		internalSetTypeDeclaration(decl);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetTypeDeclaration(TypeDeclaration decl) {
+	    supportedOnlyIn2();
+		// forward to non-deprecated replacement method
+		setDeclaration(decl);
+	}
+
+	/**
+	 * Resolves and returns the binding for the class or interface declared in
+	 * this type declaration statement.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public ITypeBinding resolveBinding() {
+		// forward request to the wrapped type declaration
+		AbstractTypeDeclaration d = getDeclaration();
+		if (d instanceof TypeDeclaration) {
+			return ((TypeDeclaration) d).resolveBinding();
+		} else if (d instanceof AnnotationTypeDeclaration) {
+			return ((AnnotationTypeDeclaration) d).resolveBinding();
+		} else {
+			// shouldn't happen
+			return null;
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.typeDecl == null ? 0 : getDeclaration().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java
new file mode 100644
index 0000000..d37e264
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type literal AST node type.
+ *
+ * <pre>
+ * TypeLiteral:
+ *     ( Type | <b>void</b> ) <b>.</b> <b>class</b>
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeLiteral extends Expression {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(TypeLiteral.class, "type", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(TypeLiteral.class, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The type; lazily initialized; defaults to a unspecified,
+	 * legal type.
+	 */
+	private Type type = null;
+
+	/**
+	 * Creates a new AST node for a type literal owned by the given
+	 * AST. By default, the expression has an unspecified (but legal) type.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TypeLiteral(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TYPE_LITERAL;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TypeLiteral result = new TypeLiteral(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) getType().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			acceptChild(visitor, getType());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type in this type literal expression.
+	 *
+	 * @return the type
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type in this type literal expression to the given type.
+	 *
+	 * @param type the new type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.type == null ? 0 : getType().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java
new file mode 100644
index 0000000..1cebbe4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeMethodReference.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type method reference expression AST node type (added in JLS8 API).
+ * <pre>
+ * TypeMethodReference:
+ *     Type <b>::</b> 
+ *         [ <b>&lt;</b> Type { <b>,</b> Type } <b>&gt;</b> ]
+ *         Identifier
+ * </pre>
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeMethodReference extends MethodReference {
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(TypeMethodReference.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeArguments" structural property of this node type (element type: {@link Type}) 
+	 */
+	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY =
+		internalTypeArgumentsFactory(TypeMethodReference.class);
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}. 
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(TypeMethodReference.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+	
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(TypeMethodReference.class, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the AST.JLS* constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_8_0;
+	}
+
+	/**
+	 * The type; lazily initialized; defaults to an unspecified type.
+	 */
+	private Type type = null;
+
+	/**
+	 * The method name; lazily initialized; defaults to an unspecified,
+	 * legal Java method name.
+	 */
+	private SimpleName methodName = null;
+
+	/**
+	 * Creates a new AST node for an TypeMethodReference declaration owned
+	 * by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private; all subclasses must be
+	 * declared in the same package; clients are unable to declare
+	 * additional subclasses.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TypeMethodReference(AST ast) {
+		super(ast);
+		unsupportedIn2_3_4();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on MethodReference.
+	 */
+	final ChildListPropertyDescriptor internalTypeArgumentsProperty() {
+		return TYPE_ARGUMENTS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPE_ARGUMENTS_PROPERTY) {
+			return typeArguments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TYPE_METHOD_REFERENCE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TypeMethodReference result = new TypeMethodReference(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setType((Type) ASTNode.copySubtree(target, getType()));
+		result.typeArguments().addAll(ASTNode.copySubtrees(target, typeArguments()));
+		result.setName((SimpleName) getName().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.typeArguments);
+			acceptChild(visitor, getName());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the type of this type method reference expression.
+	 *
+	 * @return the type node
+	 */
+	public Type getType() {
+		if (this.type == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.type == null) {
+					preLazyInit();
+					this.type = new SimpleType(this.ast);
+					postLazyInit(this.type, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.type;
+	}
+
+	/**
+	 * Sets the type of this type method reference expression.
+	 *
+	 * @param type the new type node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.type;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.type = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type arguments of this type method reference expression.
+	 *
+	 * @return the live list of type arguments
+	 *    (element type: {@link Type})
+	 */
+	public List typeArguments() {
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns the name of the method referenced in this expression.
+	 *
+	 * @return the method name node
+	 */
+	public SimpleName getName() {
+		if (this.methodName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.methodName == null) {
+					preLazyInit();
+					this.methodName = new SimpleName(this.ast);
+					postLazyInit(this.methodName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.methodName;
+	}
+
+	/**
+	 * Sets the name of the method referenced in this expression to the
+	 * given name.
+	 *
+	 * @param name the new method name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName name) {
+		if (name == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.methodName;
+		preReplaceChild(oldChild, name, NAME_PROPERTY);
+		this.methodName = name;
+		postReplaceChild(oldChild, name, NAME_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.type == null ? 0 : getType().treeSize())
+			+ (this.typeArguments == null ? 0 : this.typeArguments.listSize())
+			+ (this.methodName == null ? 0 : getName().treeSize());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java
new file mode 100644
index 0000000..1db6bf4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type parameter node (added in JLS3 API).
+ * 
+ * <pre>
+ * TypeParameter:
+ *    { Annotation } TypeVariable [ <b>extends</b> Type { <b>&</b> Type } ]
+ * </pre>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class TypeParameter extends ASTNode {
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			new ChildListPropertyDescriptor(TypeParameter.class, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+		new ChildPropertyDescriptor(TypeParameter.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "typeBounds" structural property of this node type (element type: {@link Type}).
+	 */
+	public static final ChildListPropertyDescriptor TYPE_BOUNDS_PROPERTY =
+		new ChildListPropertyDescriptor(TypeParameter.class, "typeBounds", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(TypeParameter.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(TYPE_BOUNDS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(4);
+		createPropertyList(TypeParameter.class, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(TYPE_BOUNDS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The type variable node; lazily initialized; defaults to an unspecified,
+	 * but legal, name.
+	 */
+	private SimpleName typeVariableName = null;
+
+	/**
+	 * The type bounds (element type: {@link Type}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList typeBounds =
+		new ASTNode.NodeList(TYPE_BOUNDS_PROPERTY);
+
+	/**
+	 * The type annotations (element type: {@link Annotation}).
+	 * Null in JLS < 8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 */
+	private ASTNode.NodeList annotations = null;
+	
+	/**
+	 * Creates a new unparented node for a parameterized type owned by the
+	 * given AST. By default, an unspecified, but legal, type variable name,
+	 * and no type bounds.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	TypeParameter(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	    if (ast.apiLevel >= AST.JLS8) {
+			this.annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		if (property == TYPE_BOUNDS_PROPERTY) {
+			return typeBounds();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return TYPE_PARAMETER;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		TypeParameter result = new TypeParameter(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setName((SimpleName) ((ASTNode) getName()).clone(target));
+		result.typeBounds().addAll(
+			ASTNode.copySubtrees(target, typeBounds()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+			acceptChild(visitor, getName());
+			acceptChildren(visitor, this.typeBounds);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the name of the type variable declared in this type parameter.
+	 *
+	 * @return the name of the type variable
+	 */
+	public SimpleName getName() {
+		if (this.typeVariableName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.typeVariableName == null) {
+					preLazyInit();
+					this.typeVariableName = new SimpleName(this.ast);
+					postLazyInit(this.typeVariableName, NAME_PROPERTY);
+				}
+			}
+		}
+		return this.typeVariableName;
+	}
+
+	/**
+	 * Resolves and returns the binding for this type parameter.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public final ITypeBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveTypeParameter(this);
+	}
+
+	/**
+	 * Sets the name of the type variable of this type parameter to the given
+	 * name.
+	 *
+	 * @param typeName the new name of this type parameter
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName typeName) {
+		if (typeName == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.typeVariableName;
+		preReplaceChild(oldChild, typeName, NAME_PROPERTY);
+		this.typeVariableName = typeName;
+		postReplaceChild(oldChild, typeName, NAME_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of type bounds of this type parameter.
+	 * For the type parameter to be plausible, there can be at most one
+	 * class in the list, and it must be first, and the remaining ones must be
+	 * interfaces; the list should not contain primitive types (but array types
+	 * and parameterized types are allowed).
+	 *
+	 * @return the live list of type bounds
+	 *    (element type: {@link Type})
+	 */
+	public List typeBounds() {
+		return this.typeBounds;
+	}
+	
+	/**
+	 * Returns the live ordered list of annotations for this TypeParameter node (added in JLS8 API).
+	 *
+	 * @return the live list of annotations (element type: {@link Annotation})
+	 * @exception UnsupportedOperationException if this operation is used
+	 *            in a JLS2, JLS3 or JLS4 AST
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public List annotations() {
+		// more efficient than just calling unsupportedIn2_3_4() to check
+		if (this.annotations == null) {
+			unsupportedIn2_3_4();
+		}
+		return this.annotations;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Code as free
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.annotations == null ? 0 : this.annotations.listSize())
+			+ (this.typeVariableName == null ? 0 : getName().treeSize())
+			+ this.typeBounds.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/UnionType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/UnionType.java
new file mode 100644
index 0000000..5ed7b41
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/UnionType.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for an union type (added in JLS4 API).
+ * <pre>
+ * UnionType:
+ *    Type <b>|</b> Type { <b>|</b> Type }
+ * </pre>
+ * <p>
+ * This kind of node is used inside a catch clause's formal parameter type.
+ * </p>
+ *
+ * @since 3.7.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class UnionType extends Type {
+
+	/**
+	 * The "types" structural property of this node type (element type: {@link Type}).
+	 */
+	public static final ChildListPropertyDescriptor TYPES_PROPERTY =
+		new ChildListPropertyDescriptor(UnionType.class, "types", Type.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(2);
+		createPropertyList(UnionType.class, propertyList);
+		addProperty(TYPES_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The list of types (element type: {@link Type}).  Defaults to an empty list.
+	 */
+	private ASTNode.NodeList types = new ASTNode.NodeList(TYPES_PROPERTY);
+
+	/**
+	 * Creates a new unparented node for an union type owned by the given AST.
+	 * By default, it has no types.<p>
+	 * 
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	UnionType(AST ast) {
+		super(ast);
+		unsupportedIn2_3();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == TYPES_PROPERTY) {
+			return types();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return UNION_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		UnionType result = new UnionType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.types().addAll(
+				ASTNode.copySubtrees(target, types()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChildren(visitor, this.types);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of types in this union type.
+	 * Adding and removing nodes from this list affects this node
+	 * dynamically. All nodes in this list must be
+	 * <code>Type</code>s; attempts to add any other
+	 * type of node will trigger an exception.
+	 *
+	 * @return the live list of types in this union type (element type: {@link Type})
+	 */
+	public List types() {
+		return this.types;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 1 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ this.types.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
new file mode 100644
index 0000000..c877900
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
@@ -0,0 +1,426 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.util.IModifierConstants;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
+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.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.LocalVariable;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Internal implementation of variable bindings.
+ */
+class VariableBinding implements IVariableBinding {
+
+	private static final int VALID_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE |
+		Modifier.STATIC | Modifier.FINAL | Modifier.TRANSIENT | Modifier.VOLATILE;
+
+	private org.eclipse.jdt.internal.compiler.lookup.VariableBinding binding;
+	private ITypeBinding declaringClass;
+	private String key;
+	private String name;
+	private BindingResolver resolver;
+	private ITypeBinding type;
+	private IAnnotationBinding[] annotations;
+
+	VariableBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.VariableBinding binding) {
+		this.resolver = resolver;
+		this.binding = binding;
+	}
+
+	public IAnnotationBinding[] getAnnotations() {
+		if (this.annotations != null) {
+			return this.annotations;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] internalAnnotations = this.binding.getAnnotations();
+		int length = internalAnnotations == null ? 0 : internalAnnotations.length;
+		if (length != 0) {
+			IAnnotationBinding[] tempAnnotations = new IAnnotationBinding[length];
+			int convertedAnnotationCount = 0;
+			for (int i = 0; i < length; i++) {
+				org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalAnnotation = internalAnnotations[i];
+				final IAnnotationBinding annotationInstance = this.resolver.getAnnotationInstance(internalAnnotation);
+				if (annotationInstance == null) {
+					continue;
+				}
+				tempAnnotations[convertedAnnotationCount++] = annotationInstance;
+			}
+			if (convertedAnnotationCount != length) {
+				if (convertedAnnotationCount == 0) {
+					return this.annotations = AnnotationBinding.NoAnnotations;
+				}
+				System.arraycopy(tempAnnotations, 0, (tempAnnotations = new IAnnotationBinding[convertedAnnotationCount]), 0, convertedAnnotationCount);
+			}
+			return this.annotations = tempAnnotations;
+		}
+		return this.annotations = AnnotationBinding.NoAnnotations;
+	}
+
+	/* (non-Javadoc)
+	 * @see IVariableBinding#getConstantValue()
+	 * @since 3.0
+	 */
+	public Object getConstantValue() {
+		Constant c = this.binding.constant();
+		if (c == null || c == Constant.NotAConstant) return null;
+		switch (c.typeID()) {
+			case TypeIds.T_boolean:
+				return Boolean.valueOf(c.booleanValue());
+			case TypeIds.T_byte:
+				return new Byte(c.byteValue());
+			case TypeIds.T_char:
+				return new Character(c.charValue());
+			case TypeIds.T_double:
+				return new Double(c.doubleValue());
+			case TypeIds.T_float:
+				return new Float(c.floatValue());
+			case TypeIds.T_int:
+				return new Integer(c.intValue());
+			case TypeIds.T_long:
+				return new Long(c.longValue());
+			case TypeIds.T_short:
+				return new Short(c.shortValue());
+			case TypeIds.T_JavaLangString:
+				return c.stringValue();
+		}
+		return null;
+	}
+
+	/*
+	 * @see IVariableBinding#getDeclaringClass()
+	 */
+	public ITypeBinding getDeclaringClass() {
+		if (isField()) {
+			if (this.declaringClass == null) {
+				FieldBinding fieldBinding = (FieldBinding) this.binding;
+				this.declaringClass = this.resolver.getTypeBinding(fieldBinding.declaringClass);
+			}
+			return this.declaringClass;
+		} else {
+			return null;
+		}
+	}
+
+	/*
+	 * @see IVariableBinding#getDeclaringMethod()
+	 */
+	public IMethodBinding getDeclaringMethod() {
+		if (!isField()) {
+			ASTNode node = this.resolver.findDeclaringNode(this);
+			while (true) {
+				if (node == null) {
+					if (this.binding instanceof LocalVariableBinding) {
+						LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
+						BlockScope blockScope = localVariableBinding.declaringScope;
+						if (blockScope != null) {
+							ReferenceContext referenceContext = blockScope.referenceContext();
+							if (referenceContext instanceof Initializer) {
+								return null;
+							}
+							if (referenceContext instanceof AbstractMethodDeclaration) {
+								return this.resolver.getMethodBinding(((AbstractMethodDeclaration) referenceContext).binding);
+							}
+						}
+					}
+					return null;
+				}
+				switch(node.getNodeType()) {
+					case ASTNode.INITIALIZER :
+						return null;
+					case ASTNode.METHOD_DECLARATION :
+						MethodDeclaration methodDeclaration = (MethodDeclaration) node;
+						return methodDeclaration.resolveBinding();
+					default:
+						node = node.getParent();
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see IBinding#getJavaElement()
+	 */
+	public IJavaElement getJavaElement() {
+		JavaElement element = getUnresolvedJavaElement();
+		if (element == null)
+			return null;
+		return element.resolved(this.binding);
+	}
+
+	/*
+	 * @see IBinding#getKey()
+	 */
+	public String getKey() {
+		if (this.key == null) {
+			this.key = new String(this.binding.computeUniqueKey());
+		}
+		return this.key;
+	}
+
+	/*
+	 * @see IBinding#getKind()
+	 */
+	public int getKind() {
+		return IBinding.VARIABLE;
+	}
+
+	/*
+	 * @see IBinding#getModifiers()
+	 */
+	public int getModifiers() {
+		if (isField()) {
+			return ((FieldBinding) this.binding).getAccessFlags() & VALID_MODIFIERS;
+		}
+		if (this.binding.isFinal()) {
+			return IModifierConstants.ACC_FINAL;
+		}
+		return Modifier.NONE;
+	}
+
+	/*
+	 * @see IBinding#getName()
+	 */
+	public String getName() {
+		if (this.name == null) {
+			this.name = new String(this.binding.name);
+		}
+		return this.name;
+	}
+
+	/*
+	 * @see IVariableBinding#getType()
+	 */
+	public ITypeBinding getType() {
+		if (this.type == null) {
+			this.type = this.resolver.getTypeBinding(this.binding.type);
+		}
+		return this.type;
+	}
+
+	private JavaElement getUnresolvedJavaElement() {
+		if (JavaCore.getPlugin() == null) {
+			return null;
+		}
+		if (isField()) {
+			if (this.resolver instanceof DefaultBindingResolver) {
+				DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
+				if (!defaultBindingResolver.fromJavaProject) return null;
+				return Util.getUnresolvedJavaElement(
+						(FieldBinding) this.binding,
+						defaultBindingResolver.workingCopyOwner,
+						defaultBindingResolver.getBindingsToNodesMap());
+			}
+			return null;
+		}
+		// local variable
+		if (!(this.resolver instanceof DefaultBindingResolver)) return null;
+		DefaultBindingResolver defaultBindingResolver = (DefaultBindingResolver) this.resolver;
+		if (!defaultBindingResolver.fromJavaProject) return null;
+		VariableDeclaration localVar = (VariableDeclaration) defaultBindingResolver.bindingsToAstNodes.get(this);
+		if (localVar == null) return null;
+		SimpleName localName = localVar.getName();
+		int nameStart = localName.getStartPosition();
+		int nameLength = localName.getLength();
+		int sourceStart;
+		int sourceLength;
+		int modifiers = 0;
+		if (localVar instanceof SingleVariableDeclaration) {
+			sourceStart = localVar.getStartPosition();
+			sourceLength = localVar.getLength();
+			final SingleVariableDeclaration singleVariableDeclaration = (SingleVariableDeclaration) localVar;
+			modifiers = singleVariableDeclaration.getModifiers();
+		} else {
+			ASTNode node = localVar.getParent();
+			sourceStart = node.getStartPosition();
+			sourceLength = node.getLength();
+			VariableDeclarationFragment fragment = (VariableDeclarationFragment) localVar;
+			final ASTNode parent = fragment.getParent();
+			switch (parent.getNodeType()) {
+				case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
+					VariableDeclarationExpression expression = (VariableDeclarationExpression) parent;
+					modifiers = expression.getModifiers();
+					break;
+				case ASTNode.VARIABLE_DECLARATION_STATEMENT :
+					VariableDeclarationStatement statement = (VariableDeclarationStatement) parent;
+					modifiers = statement.getModifiers();
+					break;
+				case ASTNode.FIELD_DECLARATION :
+					FieldDeclaration fieldDeclaration = (FieldDeclaration) parent;
+					modifiers = fieldDeclaration.getModifiers();
+					break;
+			}
+		}
+		int sourceEnd = sourceStart+sourceLength-1;
+		char[] typeSig = this.binding.type.genericTypeSignature();
+		JavaElement parent = null;
+		IMethodBinding declaringMethod = getDeclaringMethod();
+		final LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
+		if (declaringMethod == null) {
+			ReferenceContext referenceContext = localVariableBinding.declaringScope.referenceContext();
+			if (referenceContext instanceof TypeDeclaration){
+				// Local variable is declared inside an initializer
+				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+				JavaElement typeHandle = null;
+				typeHandle = Util.getUnresolvedJavaElement(
+					typeDeclaration.binding,
+					defaultBindingResolver.workingCopyOwner,
+					defaultBindingResolver.getBindingsToNodesMap());
+				parent = Util.getUnresolvedJavaElement(sourceStart, sourceEnd, typeHandle);
+			} else {
+				return null;
+			}
+		} else {
+			parent = (JavaElement) declaringMethod.getJavaElement();
+		}
+		if (parent == null) return null;
+		return new LocalVariable(
+				parent,
+				localName.getIdentifier(),
+				sourceStart,
+				sourceEnd,
+				nameStart,
+				nameStart+nameLength-1,
+				new String(typeSig),
+				localVariableBinding.declaration.annotations,
+				modifiers,
+				(localVariableBinding.tagBits & TagBits.IsArgument) != 0);
+	}
+
+	/*
+	 * @see IVariableBinding#getVariableDeclaration()
+	 * @since 3.1
+	 */
+	public IVariableBinding getVariableDeclaration() {
+		if (isField()) {
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			return this.resolver.getVariableBinding(fieldBinding.original());
+		}
+		return this;
+	}
+
+	/*
+	 * @see IVariableBinding#getVariableId()
+	 */
+	public int getVariableId() {
+		return this.binding.id;
+	}
+
+	/*
+	 * @see IVariableBinding#isParameter()
+	 */
+	public boolean isParameter() {
+		return (this.binding.tagBits & TagBits.IsArgument) != 0;
+	}
+	/*
+	 * @see IBinding#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		if (isField()) {
+			return ((FieldBinding) this.binding).isDeprecated();
+		}
+		return false;
+	}
+
+	/*
+	 * @see IVariableBinding#isEnumConstant()
+	 * @since 3.1
+	 */
+	public boolean isEnumConstant() {
+		return (this.binding.modifiers & ClassFileConstants.AccEnum) != 0;
+	}
+
+	/*
+	 * @see IBinding#isEqualTo(Binding)
+	 * @since 3.1
+	 */
+	public boolean isEqualTo(IBinding other) {
+		if (other == this) {
+			// identical binding - equal (key or no key)
+			return true;
+		}
+		if (other == null) {
+			// other binding missing
+			return false;
+		}
+		if (!(other instanceof VariableBinding)) {
+			return false;
+		}
+		org.eclipse.jdt.internal.compiler.lookup.VariableBinding otherBinding = ((VariableBinding) other).binding;
+		if (this.binding instanceof FieldBinding) {
+			if (otherBinding instanceof FieldBinding) {
+				return BindingComparator.isEqual((FieldBinding) this.binding, (FieldBinding) otherBinding);
+			} else {
+				return false;
+			}
+		} else {
+			if (BindingComparator.isEqual(this.binding, otherBinding)) {
+				IMethodBinding declaringMethod = getDeclaringMethod();
+				IMethodBinding otherDeclaringMethod = ((VariableBinding) other).getDeclaringMethod();
+				if (declaringMethod == null) {
+					if (otherDeclaringMethod != null) {
+						return false;
+					}
+					return true;
+				}
+				return declaringMethod.isEqualTo(otherDeclaringMethod);
+			}
+			return false;
+		}
+	}
+
+	/*
+	 * @see IVariableBinding#isField()
+	 */
+	public boolean isField() {
+		return this.binding instanceof FieldBinding;
+	}
+
+	/*
+	 * @see IBinding#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		if (isField()) {
+			return ((FieldBinding) this.binding).isSynthetic();
+		}
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.IBinding#isRecovered()
+	 */
+	public boolean isRecovered() {
+		return false;
+	}
+
+	/*
+	 * For debugging purpose only.
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.binding.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java
new file mode 100644
index 0000000..c13bd9b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.List;
+
+/**
+ * Abstract base class of all AST node types that declare a single
+ * variable.
+ * <p>
+ * <pre>
+ * VariableDeclaration:
+ *    SingleVariableDeclaration
+ *    VariableDeclarationFragment
+ * </pre>
+ * </p>
+ *
+ * @see SingleVariableDeclaration
+ * @see VariableDeclarationFragment
+ * @since 2.0
+ */
+public abstract class VariableDeclaration extends ASTNode {
+
+	/**
+	 * The variable name; lazily initialized; defaults to an unspecified,
+	 * legal Java identifier.
+	 */
+	SimpleName variableName = null;
+
+	/**
+	 * The number of extra array dimensions that appear after the variable;
+	 * defaults to 0. Not used in JLS8 and later.
+	 *
+	 * @since 2.1
+	 * @deprecated In JLS8 and later, use {@link #extraDimensions} instead.
+	 */
+	int extraArrayDimensions = 0;
+
+	/**
+	 * List of extra dimensions this node has with optional annotations
+	 * (element type: {@link ExtraDimension}).
+	 * Null before JLS8. Added in JLS8; defaults to an empty list
+	 * (see constructor).
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	ASTNode.NodeList extraDimensions = null;
+
+	/**
+	 * The initializer expression, or <code>null</code> if none;
+	 * defaults to none.
+	 */
+	Expression optionalInitializer = null;
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "name" property declared on the given concrete node type (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildPropertyDescriptor internalNamePropertyFactory(Class nodeClass) {
+		return new ChildPropertyDescriptor(nodeClass, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "extraDimensions" property declared on the given concrete node type (type: {@link Integer}).
+	 *
+	 * @return the property descriptor
+	 * @deprecated In JLS8 and later, use {@link #internalExtraDimensions2PropertyFactory(Class)} instead.
+	 */
+	static final SimplePropertyDescriptor internalExtraDimensionsPropertyFactory(Class nodeClass) {
+		return 	new SimplePropertyDescriptor(nodeClass, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "extraDimensions2" property declared on the given concrete node type (element type: {@link ExtraDimension}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildListPropertyDescriptor internalExtraDimensions2PropertyFactory(Class nodeClass) {
+		return 	new ChildListPropertyDescriptor(nodeClass, "extraDimensions2", ExtraDimension.class, CYCLE_RISK); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Creates and returns a structural property descriptor for the
+	 * "initializer" property declared on the given concrete node type (child type: {@link Expression}).
+	 *
+	 * @return the property descriptor
+	 */
+	static final ChildPropertyDescriptor internalInitializerPropertyFactory(Class nodeClass) {
+		return 	new ChildPropertyDescriptor(nodeClass, "initializer", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns structural property descriptor for the "name" property
+	 * of this node (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	abstract ChildPropertyDescriptor internalNameProperty();
+
+	/**
+	 * Returns the structural property descriptor for the "name" property
+	 * of this node (child type: {@link SimpleName}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildPropertyDescriptor getNameProperty() {
+		return internalNameProperty();
+	}
+
+	
+	/**
+	 * Returns the structural property descriptor for the "extraDimensions" property
+	 * of this node (type: {@link Integer}) (below JLS8 only).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 * @deprecated In JLS8 and later, use {@link #internalExtraDimensions2Property()} instead.
+	 */
+	abstract SimplePropertyDescriptor internalExtraDimensionsProperty();
+
+	/**
+	 * Returns the structural property descriptor for the "extraDimensions" property
+	 * of this node (type: {@link Integer}) (below JLS8 only).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 * @deprecated In JLS8 and later, use {@link #getExtraDimensions2Property()} instead.
+	 */
+	public final SimplePropertyDescriptor getExtraDimensionsProperty() {
+		return internalExtraDimensionsProperty();
+	}
+
+	/**
+	 * Returns the structural property descriptor for the "extraDimensions" property
+	 * of this node (element type: {@link ExtraDimension}) (added in JLS8 API).
+	 *
+	 * @return the property descriptor
+	 * @since 3.9 BETA_JAVA8
+	 */
+	abstract ChildListPropertyDescriptor internalExtraDimensions2Property();
+	
+	/**
+	 * Returns the structural property descriptor for the "extraDimensions" property
+	 * of this node (element type: {@link ExtraDimension}) (added in JLS8 API).
+	 *
+	 * @return the property descriptor
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public final ChildListPropertyDescriptor getExtraDimensions2Property() {
+		return internalExtraDimensions2Property();
+	}
+	
+	/**
+	 * Returns structural property descriptor for the "initializer" property
+	 * of this node (child type: {@link Expression}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	abstract ChildPropertyDescriptor internalInitializerProperty();
+
+	/**
+	 * Returns structural property descriptor for the "initializer" property
+	 * of this node (child type: {@link Expression}).
+	 *
+	 * @return the property descriptor
+	 * @since 3.1
+	 */
+	public final ChildPropertyDescriptor getInitializerProperty() {
+		return internalInitializerProperty();
+	}
+
+	/**
+	 * Creates a new AST node for a variable declaration owned by the given AST.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	VariableDeclaration(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS8) {
+			this.extraDimensions = new ASTNode.NodeList(getExtraDimensions2Property());
+		}
+	}
+
+	/**
+	 * Returns the name of the variable declared in this variable declaration.
+	 *
+	 * @return the variable name node
+	 */
+	public SimpleName getName() {
+		if (this.variableName == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.variableName == null) {
+					preLazyInit();
+					this.variableName = new SimpleName(this.ast);
+					postLazyInit(this.variableName, internalNameProperty());
+				}
+			}
+		}
+		return this.variableName;
+	}
+
+	/**
+	 * Sets the name of the variable declared in this variable declaration
+	 * to the given name.
+	 *
+	 * @param variableName the new variable name
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setName(SimpleName variableName) {
+		if (variableName == null) {
+			throw new IllegalArgumentException();
+		}
+		ChildPropertyDescriptor p = internalNameProperty();
+		ASTNode oldChild = this.variableName;
+		preReplaceChild(oldChild, variableName, p);
+		this.variableName = variableName;
+		postReplaceChild(oldChild, variableName, p);
+	}
+
+	/**
+	 * Returns the number of extra array dimensions over and above the
+	 * explicitly-specified type.
+	 * <p>
+	 * For example, <code>int x[][]</code> has a type of
+	 * <code>int</code> and two extra array dimensions;
+	 * <code>int[][] x</code> has a type of <code>int[][]</code>
+	 * and zero extra array dimensions. The two constructs have different
+	 * ASTs, even though there are really syntactic variants of the same
+	 * variable declaration.
+	 * </p>
+	 * <p>
+	 * In the JLS8 API, this method is a convenience method that
+	 * counts {@link #extraDimensions()}.
+	 * </p>
+	 *
+	 * @return the number of extra array dimensions
+	 * @since 2.1
+	 */
+	public int getExtraDimensions() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.extraDimensions == null) {
+			// JLS2,3,4 behavior - bona fide property
+			return this.extraArrayDimensions;
+		} else {
+			return this.extraDimensions.size();
+		}
+	}
+
+	/**
+	 * Sets the number of extra array dimensions over and above the
+	 * explicitly-specified type.
+	 * <p>
+	 * For example, <code>int x[][]</code> has a type of
+	 * <code>int</code> and two extra array dimensions;
+	 * <code>int[][] x</code> has a type of <code>int[][]</code>
+	 * and zero extra array dimensions. The two constructs have different
+	 * ASTs, even though there are really syntactic variants of the same
+	 * variable declaration.
+	 * </p>
+	 *
+	 * @param dimensions the number of array dimensions
+	 * @exception IllegalArgumentException if the number of dimensions is
+	 *    negative
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS8 or later AST 
+	 * @deprecated In the JLS8 API, this method is replaced by
+	 * {@link #extraDimensions()} which contains a list of {@link ExtraDimension} nodes.
+	 * @since 2.1
+	 */
+	public void setExtraDimensions(int dimensions) {
+		internalSetExtraDimensions(dimensions);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final void internalSetExtraDimensions(int dimensions) {
+		// more efficient than just calling supportedOnlyIn2_3_4() to check
+		if (this.extraDimensions != null) {
+			supportedOnlyIn2_3_4();
+		}
+		if (dimensions < 0) {
+			throw new IllegalArgumentException();
+		}
+		SimplePropertyDescriptor p = internalExtraDimensionsProperty();
+		preValueChange(p);
+		this.extraArrayDimensions = dimensions;
+		postValueChange(p);
+	}
+
+	/**
+	 * Returns the live ordered list of extra dimensions with optional annotations (added in JLS8 API).
+	 *
+	 * @return the live list of extra dimensions with optional annotations (element type: {@link ExtraDimension})
+	 * @exception UnsupportedOperationException if this operation is used below JLS8
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public List extraDimensions() {
+		// more efficient than just calling unsupportedIn2_3_4() to check
+		if (this.extraDimensions == null) {
+			unsupportedIn2_3_4();
+		}
+		return this.extraDimensions;
+	}
+
+	/**
+	 * Returns the initializer of this variable declaration, or
+	 * <code>null</code> if there is none.
+	 *
+	 * @return the initializer expression node, or <code>null</code> if
+	 *    there is none
+	 */
+	public Expression getInitializer() {
+		return this.optionalInitializer;
+	}
+
+	/**
+	 * Sets or clears the initializer of this variable declaration.
+	 *
+	 * @param initializer the initializer expression node, or <code>null</code>
+	 *    if there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setInitializer(Expression initializer) {
+		ChildPropertyDescriptor p = internalInitializerProperty();
+		ASTNode oldChild = this.optionalInitializer;
+		preReplaceChild(oldChild, initializer, p);
+		this.optionalInitializer = initializer;
+		postReplaceChild(oldChild, initializer, p);
+	}
+
+	/**
+	 * Resolves and returns the binding for the variable declared in this
+	 * variable declaration.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 *
+	 * @return the binding, or <code>null</code> if the binding cannot be
+	 *    resolved
+	 */
+	public IVariableBinding resolveBinding() {
+		return this.ast.getBindingResolver().resolveVariable(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java
new file mode 100644
index 0000000..7568b78
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Local variable declaration expression AST node type.
+ * <p>
+ * This kind of node collects together several variable declaration fragments
+ * (<code>VariableDeclarationFragment</code>) into a single expression
+ * (<code>Expression</code>), all sharing the same modifiers and base type.
+ * This type of node can be used as the initializer of a
+ * <code>ForStatement</code>, or wrapped in an <code>ExpressionStatement</code>
+ * to form the equivalent of a <code>VariableDeclarationStatement</code>.
+ * </p>
+ * <pre>
+ * VariableDeclarationExpression:
+ *    { ExtendedModifier } Type VariableDeclarationFragment
+ *         { <b>,</b> VariableDeclarationFragment }
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class VariableDeclarationExpression extends Expression {
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 * @since 3.0
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		new SimplePropertyDescriptor(VariableDeclarationExpression.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		new ChildListPropertyDescriptor(VariableDeclarationExpression.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(VariableDeclarationExpression.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "fragments" structural property of this node type (element type: {@link VariableDeclarationFragment}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(VariableDeclarationExpression.class, "fragments", VariableDeclarationFragment.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationExpression.class, propertyList);
+		addProperty(MODIFIERS_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(FRAGMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationExpression.class, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(FRAGMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The extended modifiers (element type: {@link IExtendedModifier}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.0
+	 */
+	private ASTNode.NodeList modifiers = null;
+
+	/**
+	 * The modifier flags; bit-wise or of Modifier flags.
+	 * Defaults to none. Not used in 3.0.
+	 */
+	private int modifierFlags = Modifier.NONE;
+
+	/**
+	 * The base type; lazily initialized; defaults to an unspecified,
+	 * legal type.
+	 */
+	private Type baseType = null;
+
+	/**
+	 * The list of variable declaration fragments (element type:
+	 * {@link VariableDeclarationFragment}).  Defaults to an empty list.
+	 */
+	private ASTNode.NodeList variableDeclarationFragments =
+		new ASTNode.NodeList(FRAGMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented local variable declaration expression node
+	 * owned by the given AST.  By default, the variable declaration has: no
+	 * modifiers, an unspecified (but legal) type, and an empty list of variable
+	 * declaration fragments (which is syntactically illegal).
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	VariableDeclarationExpression(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				setModifiers(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == FRAGMENTS_PROPERTY) {
+			return fragments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return VARIABLE_DECLARATION_EXPRESSION;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		VariableDeclarationExpression result =
+			new VariableDeclarationExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.setModifiers(getModifiers());
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		}
+		result.setType((Type) getType().clone(target));
+		result.fragments().addAll(
+			ASTNode.copySubtrees(target, fragments()));
+		return result;
+
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.modifiers);
+			}
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.variableDeclarationFragments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of modifiers and annotations
+	 * of this declaration (added in JLS3 API).
+	 * <p>
+	 * Note that the final modifier is the only meaningful modifier for local
+	 * variable declarations.
+	 * </p>
+	 *
+	 * @return the live list of modifiers and annotations
+	 *    (element type: {@link IExtendedModifier})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List modifiers() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		return this.modifiers;
+	}
+
+	/**
+	 * Returns the modifiers explicitly specified on this declaration.
+	 * <p>
+	 * In the JLS3 API, this method is a convenience method that
+	 * computes these flags from <code>modifiers()</code>.
+	 * </p>
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see Modifier
+	 */
+	public int getModifiers() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.modifiers == null) {
+			// JLS2 behavior - bona fide property
+			return this.modifierFlags;
+		} else {
+			// JLS3 behavior - convenient method
+			// performance could be improved by caching computed flags
+			// but this would require tracking changes to this.modifiers
+			int computedModifierFlags = Modifier.NONE;
+			for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
+				Object x = it.next();
+				if (x instanceof Modifier) {
+					computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
+				}
+			}
+			return computedModifierFlags;
+		}
+	}
+
+	/**
+	 * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
+	 * <p>
+	 * Note that the final modifier is the only meaningful modifier for local
+	 * variable declarations.
+	 * </p>
+	 *
+	 * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
+	 */
+	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
+	    supportedOnlyIn2();
+		preValueChange(MODIFIERS_PROPERTY);
+		this.modifierFlags = pmodifiers;
+		postValueChange(MODIFIERS_PROPERTY);
+	}
+
+	/**
+	 * Returns the base type declared in this variable declaration.
+	 * <p>
+	 * N.B. The individual child variable declaration fragments may specify
+	 * additional array dimensions. So the type of the variable are not
+	 * necessarily exactly this type.
+	 * </p>
+	 *
+	 * @return the base type
+	 */
+	public Type getType() {
+		if (this.baseType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.baseType == null) {
+					preLazyInit();
+					this.baseType = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.baseType, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.baseType;
+	}
+
+	/**
+	 * Sets the base type declared in this variable declaration to the given
+	 * type.
+	 *
+	 * @param type the new base type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.baseType;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.baseType = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live list of variable declaration fragments in this
+	 * expression. Adding and removing nodes from this list affects this node
+	 * dynamically. All nodes in this list must be
+	 * <code>VariableDeclarationFragment</code>s; attempts to add any other
+	 * type of node will trigger an exception.
+	 *
+	 * @return the live list of variable declaration fragments in this
+	 *    expression (element type: {@link VariableDeclarationFragment})
+	 */
+	public List fragments() {
+		return this.variableDeclarationFragments;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.baseType == null ? 0 : getType().treeSize())
+			+ this.variableDeclarationFragments.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java
new file mode 100644
index 0000000..7d990e9
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Variable declaration fragment AST node type, used in field declarations,
+ * local variable declarations, and <code>ForStatement</code> initializers.
+ * In contrast to <code>SingleVariableDeclaration</code>, fragments are
+ * missing the modifiers and the type; these are located in the fragment's
+ * parent node.
+ *
+ * <pre>
+ * VariableDeclarationFragment:
+ *    Identifier { ExtraDimension } [ <b>=</b> Expression ]
+ * </pre>
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class VariableDeclarationFragment extends VariableDeclaration {
+
+	/**
+	 * The "name" structural property of this node type (child type: {@link SimpleName}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor NAME_PROPERTY =
+			internalNamePropertyFactory(VariableDeclarationFragment.class);
+
+	/**
+	 * The "extraDimensions" structural property of this node type (type: {@link Integer}) (below JLS8 only).
+	 *
+	 * @since 3.0
+	 * @deprecated in JLS8 and later, use {@link VariableDeclarationFragment#EXTRA_DIMENSIONS2_PROPERTY} instead.
+	 */
+	public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY =
+			internalExtraDimensionsPropertyFactory(VariableDeclarationFragment.class);
+
+	/**
+	 * The "extraDimensions2" structural property of this node type (element type: {@link ExtraDimension}) (added in JLS8 API).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor EXTRA_DIMENSIONS2_PROPERTY =
+			internalExtraDimensions2PropertyFactory(VariableDeclarationFragment.class);
+
+	/**
+	 * The "initializer" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor INITIALIZER_PROPERTY =
+			internalInitializerPropertyFactory(VariableDeclarationFragment.class);
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationFragment.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
+		addProperty(INITIALIZER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationFragment.class, propertyList);
+		addProperty(NAME_PROPERTY, propertyList);
+		addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList);
+		addProperty(INITIALIZER_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel >= AST.JLS8) {
+			return PROPERTY_DESCRIPTORS_8_0;
+		} else {
+			return PROPERTY_DESCRIPTORS;
+		}
+	}
+
+	/**
+	 * Creates a new AST node for a variable declaration fragment owned by the
+	 * given AST. By default, the variable declaration has: an unspecified
+	 * (but legal) variable name, no initializer, and no extra array dimensions.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	VariableDeclarationFragment(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final ChildPropertyDescriptor internalNameProperty() {
+		return NAME_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final SimplePropertyDescriptor internalExtraDimensionsProperty() {
+		return EXTRA_DIMENSIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalExtraDimensions2Property() {
+		return EXTRA_DIMENSIONS2_PROPERTY;
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on VariableDeclaration.
+	 * @since 3.1
+	 */
+	final ChildPropertyDescriptor internalInitializerProperty() {
+		return INITIALIZER_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == EXTRA_DIMENSIONS_PROPERTY) {
+			if (get) {
+				return getExtraDimensions();
+			} else {
+				internalSetExtraDimensions(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == NAME_PROPERTY) {
+			if (get) {
+				return getName();
+			} else {
+				setName((SimpleName) child);
+				return null;
+			}
+		}
+		if (property == INITIALIZER_PROPERTY) {
+			if (get) {
+				return getInitializer();
+			} else {
+				setInitializer((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == EXTRA_DIMENSIONS2_PROPERTY) {
+			return extraDimensions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return VARIABLE_DECLARATION_FRAGMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		VariableDeclarationFragment result = new VariableDeclarationFragment(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setName((SimpleName) getName().clone(target));
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.extraDimensions().addAll(
+					ASTNode.copySubtrees(target, extraDimensions()));
+		} else {
+			result.internalSetExtraDimensions(getExtraDimensions());
+		}
+		result.setInitializer(
+			(Expression) ASTNode.copySubtree(target, getInitializer()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getName());
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.extraDimensions);
+			}
+			acceptChild(visitor, getInitializer());
+		}
+		visitor.endVisit(this);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		// treat Operator as free
+		return BASE_NODE_SIZE + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.variableName == null ? 0 : getName().treeSize())
+			+ (this.extraDimensions == null ? 0 : this.extraDimensions.listSize())
+			+ (this.optionalInitializer == null ? 0 : getInitializer().treeSize());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
new file mode 100644
index 0000000..3756136
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
@@ -0,0 +1,430 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Local variable declaration statement AST node type.
+ * <p>
+ * This kind of node collects several variable declaration fragments
+ * (<code>VariableDeclarationFragment</code>) into a statement
+ * (<code>Statement</code>), all sharing the same modifiers and base type.
+ * </p>
+ * <pre>
+ * VariableDeclarationStatement:
+ *    { ExtendedModifier } Type VariableDeclarationFragment
+ *        { <b>,</b> VariableDeclarationFragment } <b>;</b>
+ * </pre>
+ * <p>
+ * Note: This type of node is a convenience of sorts.
+ * An equivalent way to represent the same statement is to use
+ * a <code>VariableDeclarationExpression</code>
+ * wrapped in an <code>ExpressionStatement</code>.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class VariableDeclarationStatement extends Statement {
+
+	/**
+	 * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
+	 * @since 3.0
+	 * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
+	 */
+	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
+		new SimplePropertyDescriptor(VariableDeclarationStatement.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+		new ChildListPropertyDescriptor(VariableDeclarationStatement.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "type" structural property of this node type (child type: {@link Type}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor TYPE_PROPERTY =
+		new ChildPropertyDescriptor(VariableDeclarationStatement.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "fragments" structural property of this node type (element type: {@link VariableDeclarationFragment}).
+	 * @since 3.0
+	 */
+	public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(VariableDeclarationStatement.class, "fragments", VariableDeclarationFragment.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.0
+	 */
+	private static final List PROPERTY_DESCRIPTORS_2_0;
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+
+	static {
+		List propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationStatement.class, propertyList);
+		addProperty(MODIFIERS_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(FRAGMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
+
+		propertyList = new ArrayList(4);
+		createPropertyList(VariableDeclarationStatement.class, propertyList);
+		addProperty(MODIFIERS2_PROPERTY, propertyList);
+		addProperty(TYPE_PROPERTY, propertyList);
+		addProperty(FRAGMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
+	}
+
+	/**
+	 * The extended modifiers (element type: {@link IExtendedModifier}).
+	 * Null in JLS2. Added in JLS3; defaults to an empty list
+	 * (see constructor).
+	 * @since 3.1
+	 */
+	private ASTNode.NodeList modifiers = null;
+
+	/**
+	 * The modifier flagss; bit-wise or of Modifier flags.
+	 * Defaults to none. Not used in JLS3.
+	 */
+	private int modifierFlags = Modifier.NONE;
+
+	/**
+	 * The base type; lazily initialized; defaults to an unspecified,
+	 * legal type.
+	 */
+	private Type baseType = null;
+
+	/**
+	 * The list of variable variable declaration fragments (element type:
+	 * {@link VariableDeclarationFragment}).  Defaults to an empty list.
+	 */
+	private ASTNode.NodeList variableDeclarationFragments =
+		new ASTNode.NodeList(FRAGMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented local variable declaration statement node owned
+	 * by the given AST.  By default, the variable declaration has: no modifiers,
+	 * an unspecified (but legal) type, and an empty list of variable
+	 * declaration fragments (which is syntactically illegal).
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	VariableDeclarationStatement(AST ast) {
+		super(ast);
+		if (ast.apiLevel >= AST.JLS3_INTERNAL) {
+			this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
+		}
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
+		if (property == MODIFIERS_PROPERTY) {
+			if (get) {
+				return getModifiers();
+			} else {
+				setModifiers(value);
+				return 0;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetIntProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == TYPE_PROPERTY) {
+			if (get) {
+				return getType();
+			} else {
+				setType((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == MODIFIERS2_PROPERTY) {
+			return modifiers();
+		}
+		if (property == FRAGMENTS_PROPERTY) {
+			return fragments();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return VARIABLE_DECLARATION_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		VariableDeclarationStatement result =
+			new VariableDeclarationStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.setModifiers(getModifiers());
+		}
+		if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+		}
+		result.setType((Type) getType().clone(target));
+		result.fragments().addAll(
+			ASTNode.copySubtrees(target, fragments()));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
+				acceptChildren(visitor, this.modifiers);
+			}
+			acceptChild(visitor, getType());
+			acceptChildren(visitor, this.variableDeclarationFragments);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the live ordered list of modifiers and annotations
+	 * of this declaration (added in JLS3 API).
+	 * <p>
+	 * Note that the final modifier is the only meaningful modifier for local
+	 * variable declarations.
+	 * </p>
+	 *
+	 * @return the live list of modifiers and annotations
+	 *    (element type: {@link IExtendedModifier})
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */
+	public List modifiers() {
+		// more efficient than just calling unsupportedIn2() to check
+		if (this.modifiers == null) {
+			unsupportedIn2();
+		}
+		return this.modifiers;
+	}
+
+	/**
+	 * Returns the modifiers explicitly specified on this declaration.
+	 * <p>
+	 * In the JLS3 API, this method is a convenience method that
+	 * computes these flags from <code>modifiers()</code>.
+	 * </p>
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see Modifier
+	 */
+	public int getModifiers() {
+		// more efficient than checking getAST().API_LEVEL
+		if (this.modifiers == null) {
+			// JLS2 behavior - bona fide property
+			return this.modifierFlags;
+		} else {
+			// JLS3 behavior - convenience method
+			// performance could be improved by caching computed flags
+			// but this would require tracking changes to this.modifiers
+			int computedModifierFlags = Modifier.NONE;
+			for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
+				Object x = it.next();
+				if (x instanceof Modifier) {
+					computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
+				}
+			}
+			return computedModifierFlags;
+		}
+	}
+
+	/**
+	 * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
+	 * <p>
+	 * Note that the final modifier is the only meaningful modifier for local
+	 * variable declarations.
+	 * </p>
+	 *
+	 * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * an AST later than JLS2
+	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
+	 */
+	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
+	    supportedOnlyIn2();
+		preValueChange(MODIFIERS_PROPERTY);
+		this.modifierFlags = pmodifiers;
+		postValueChange(MODIFIERS_PROPERTY);
+	}
+
+	/**
+	 * Returns the base type declared in this variable declaration statement.
+	 * <p>
+	 * N.B. The individual child variable declaration fragments may specify
+	 * additional array dimensions. So the type of the variable are not
+	 * necessarily exactly this type.
+	 * </p>
+	 *
+	 * @return the base type
+	 */
+	public Type getType() {
+		if (this.baseType == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.baseType == null) {
+					preLazyInit();
+					this.baseType = this.ast.newPrimitiveType(PrimitiveType.INT);
+					postLazyInit(this.baseType, TYPE_PROPERTY);
+				}
+			}
+		}
+		return this.baseType;
+	}
+
+	/**
+	 * Sets the base type declared in this variable declaration statement to
+	 * the given type.
+	 *
+	 * @param type the new base type
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 */
+	public void setType(Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.baseType;
+		preReplaceChild(oldChild, type, TYPE_PROPERTY);
+		this.baseType = type;
+		postReplaceChild(oldChild, type, TYPE_PROPERTY);
+	}
+
+	/**
+	 * Returns the live list of variable declaration fragments in this statement.
+	 * Adding and removing nodes from this list affects this node dynamically.
+	 * All nodes in this list must be <code>VariableDeclarationFragment</code>s;
+	 * attempts to add any other type of node will trigger an
+	 * exception.
+	 *
+	 * @return the live list of variable declaration fragments in this
+	 *    statement (element type: {@link VariableDeclarationFragment})
+	 */
+	public List fragments() {
+		return this.variableDeclarationFragments;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 4 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.modifiers == null ? 0 : this.modifiers.listSize())
+			+ (this.baseType == null ? 0 : getType().treeSize())
+			+ this.variableDeclarationFragments.listSize();
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java
new file mode 100644
index 0000000..d7e04cf
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * While statement AST node type.
+ *
+ * <pre>
+ * WhileStatement:
+ *    <b>while</b> <b>(</b> Expression <b>)</b> Statement
+ * </pre>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class WhileStatement extends Statement {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(WhileStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "body" structural property of this node type (child type: {@link Statement}).
+	 * @since 3.0
+	 */
+	public static final ChildPropertyDescriptor BODY_PROPERTY =
+		new ChildPropertyDescriptor(WhileStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(WhileStatement.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(BODY_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.0
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to an unspecified, but
+	 * legal, expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The body statement; lazily initialized; defaults to an empty block
+	 * statement.
+	 */
+	private Statement body = null;
+
+	/**
+	 * Creates a new unparented while statement node owned by the given
+	 * AST. By default, the expresssion is unspecified, but legal, and
+	 * the body statement is an empty block.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	WhileStatement(AST ast) {
+		super(ast);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		if (property == BODY_PROPERTY) {
+			if (get) {
+				return getBody();
+			} else {
+				setBody((Statement) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return WHILE_STATEMENT;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		WhileStatement result = new WhileStatement(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.copyLeadingComment(this);
+		result.setExpression((Expression) getExpression().clone(target));
+		result.setBody((Statement) getBody().clone(target));
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChild(visitor, getBody());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this while statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this while statement.
+	 *
+	 * @param expression the expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the body of this while statement.
+	 *
+	 * @return the body statement node
+	 */
+	public Statement getBody() {
+		if (this.body == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.body == null) {
+					preLazyInit();
+					this.body = new Block(this.ast);
+					postLazyInit(this.body, BODY_PROPERTY);
+				}
+			}
+		}
+		return this.body;
+	}
+
+	/**
+	 * Sets the body of this while statement.
+	 * <p>
+	 * Special note: The Java language does not allow a local variable declaration
+	 * to appear as the body of a while statement (they may only appear within a
+	 * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
+	 * as the body of a <code>WhileStatement</code>. To get something that will
+	 * compile, be sure to embed the <code>VariableDeclarationStatement</code>
+	 * inside a <code>Block</code>.
+	 * </p>
+	 *
+	 * @param statement the body statement node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setBody(Statement statement) {
+		if (statement == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.body;
+		preReplaceChild(oldChild, statement, BODY_PROPERTY);
+		this.body = statement;
+		postReplaceChild(oldChild, statement, BODY_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return super.memSize() + 2 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ (this.body == null ? 0 : getBody().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java
new file mode 100644
index 0000000..93fd054
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type node for a wildcard type (added in JLS3 API).
+ * <pre>
+ * WildcardType:
+ *    { Annotation } <b>?</b> [ ( <b>extends</b> | <b>super</b>) Type ]
+ * </pre>
+ * <p>
+ * Not all node arrangements will represent legal Java constructs. In particular,
+ * it is nonsense if a wildcard type node appears anywhere other than as an
+ * argument of a <code>ParameterizedType</code> node.
+ * </p>
+ *
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class WildcardType extends AnnotatableType {
+
+	/**
+	 * The "annotations" structural property of this node type (element type: {@link Annotation}).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+			internalAnnotationsPropertyFactory(WildcardType.class);
+	
+	/**
+	 * The "bound" structural property of this node type (child type: {@link Type}).
+	 */
+	public static final ChildPropertyDescriptor BOUND_PROPERTY =
+		new ChildPropertyDescriptor(WildcardType.class, "bound", Type.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "upperBound" structural property of this node type (type: {@link Boolean}).
+	 */
+	public static final SimplePropertyDescriptor UPPER_BOUND_PROPERTY =
+		new SimplePropertyDescriptor(WildcardType.class, "upperBound", boolean.class, MANDATORY); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS;
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final List PROPERTY_DESCRIPTORS_8_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(WildcardType.class, propertyList);
+		addProperty(BOUND_PROPERTY, propertyList);
+		addProperty(UPPER_BOUND_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(4);
+		createPropertyList(WildcardType.class, propertyList);
+		addProperty(ANNOTATIONS_PROPERTY, propertyList);
+		addProperty(BOUND_PROPERTY, propertyList);
+		addProperty(UPPER_BOUND_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		switch (apiLevel) {
+			case AST.JLS2_INTERNAL :
+			case AST.JLS3_INTERNAL :
+			case AST.JLS4_INTERNAL:
+				return PROPERTY_DESCRIPTORS;
+			default :
+				return PROPERTY_DESCRIPTORS_8_0;
+		}
+	}
+
+	/**
+	 * The optional type bound node; <code>null</code> if none;
+	 * defaults to none.
+	 */
+	private Type optionalBound = null;
+
+	/**
+	 * Indicates whether the wildcard bound is an upper bound
+	 * ("extends") as opposed to a lower bound ("super").
+	 * Defaults to <code>true</code> initially.
+	 */
+	private boolean isUpperBound = true;
+
+	/**
+	 * Creates a new unparented node for a wildcard type owned by the
+	 * given AST. By default, no upper bound.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 */
+	WildcardType(AST ast) {
+		super(ast);
+	    unsupportedIn2();
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on AnnotatableType.
+	 * @since 3.9 BETA_JAVA8
+	 */
+	final ChildListPropertyDescriptor internalAnnotationsProperty() {
+		return ANNOTATIONS_PROPERTY;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == UPPER_BOUND_PROPERTY) {
+			if (get) {
+				return isUpperBound();
+			} else {
+				setUpperBound(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == ANNOTATIONS_PROPERTY) {
+			return annotations();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == BOUND_PROPERTY) {
+			if (get) {
+				return getBound();
+			} else {
+				setBound((Type) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final int getNodeType0() {
+		return WILDCARD_TYPE;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	ASTNode clone0(AST target) {
+		WildcardType result = new WildcardType(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		if (this.ast.apiLevel >= AST.JLS8) {
+			result.annotations().addAll(
+					ASTNode.copySubtrees(target, annotations()));
+		}
+		result.setBound((Type) ASTNode.copySubtree(target, getBound()), isUpperBound());
+		return result;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			if (this.ast.apiLevel >= AST.JLS8) {
+				acceptChildren(visitor, this.annotations);
+			}
+			acceptChild(visitor, getBound());
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns whether this wildcard type is an upper bound
+	 * ("extends") as opposed to a lower bound ("super").
+	 * <p>
+	 * Note that this property is irrelevant for wildcards
+	 * that do not have a bound.
+	 * </p>
+	 *
+	 * @return <code>true</code> if an upper bound,
+	 *    and <code>false</code> if a lower bound
+	 * @see #setBound(Type)
+	 */
+	public boolean isUpperBound() {
+		return this.isUpperBound;
+	}
+
+	/**
+	 * Returns the bound of this wildcard type if it has one.
+	 * If {@link #isUpperBound isUpperBound} returns true, this
+	 * is an upper bound ("? extends B"); if it returns false, this
+	 * is a lower bound ("? super B").
+	 *
+	 * @return the bound of this wildcard type, or <code>null</code>
+	 * if none
+	 * @see #setBound(Type)
+	 */
+	public Type getBound() {
+		return this.optionalBound;
+	}
+
+	/**
+	 * Sets the bound of this wildcard type to the given type and
+	 * marks it as an upper or a lower bound. The method is
+	 * equivalent to calling <code>setBound(type); setUpperBound(isUpperBound)</code>.
+	 *
+	 * @param type the new bound of this wildcard type, or <code>null</code>
+	 * if none
+	 * @param isUpperBound <code>true</code> for an upper bound ("? extends B"),
+	 * and <code>false</code> for a lower bound ("? super B")
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @see #getBound()
+	 * @see #isUpperBound()
+	 */
+	public void setBound(Type type, boolean isUpperBound) {
+		setBound(type);
+		setUpperBound(isUpperBound);
+	}
+
+	/**
+	 * Sets the bound of this wildcard type to the given type.
+	 *
+	 * @param type the new bound of this wildcard type, or <code>null</code>
+	 * if none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @see #getBound()
+	 */
+	public void setBound(Type type) {
+		ASTNode oldChild = this.optionalBound;
+		preReplaceChild(oldChild, type, BOUND_PROPERTY);
+		this.optionalBound = type;
+		postReplaceChild(oldChild, type, BOUND_PROPERTY);
+	}
+
+	/**
+	 * Sets whether this wildcard type is an upper bound
+	 * ("extends") as opposed to a lower bound ("super").
+	 *
+	 * @param isUpperBound <code>true</code> if an upper bound,
+	 *    and <code>false</code> if a lower bound
+	 * @see #isUpperBound()
+	 */
+	public void setUpperBound(boolean isUpperBound) {
+		preValueChange(UPPER_BOUND_PROPERTY);
+		this.isUpperBound = isUpperBound;
+		postValueChange(UPPER_BOUND_PROPERTY);
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	int treeSize() {
+		return
+		memSize()
+		+ (this.annotations == null ? 0 : this.annotations.listSize())
+		+ (this.optionalBound == null ? 0 : getBound().treeSize());
+	}
+}
+
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/package.html b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/package.html
new file mode 100644
index 0000000..f0ec902
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/package.html
@@ -0,0 +1,24 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+The Java DOM/AST is the set of classes that model the source code of a Java program
+as a structured document.
+
+<h2>
+Package Specification</h2>
+
+<p><br>This package contains the Java DOM/AST classes. An API for manipulating the
+source code of a Java program as a structured document. In particular, it provides
+a full abstract syntax tree for a Java compilation unit, which can be queried for
+resolved type information, and modified. 
+The principal classes are {@link org.eclipse.jdt.core.dom.AST AST}
+{@link org.eclipse.jdt.core.dom.ASTNode ASTNode}, and
+{@link org.eclipse.jdt.core.dom.ASTParser ASTParser}.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
new file mode 100644
index 0000000..9bd4fe2
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
@@ -0,0 +1,870 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.ChildPropertyDescriptor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.SimplePropertyDescriptor;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
+import org.eclipse.jdt.internal.core.dom.rewrite.LineInformation;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeRewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.TrackedNodePosition;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.PropertyLocation;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+/**
+ * Infrastructure for modifying code by describing changes to AST nodes.
+ * The AST rewriter collects descriptions of modifications to nodes and
+ * translates these descriptions into text edits that can then be applied to
+ * the original source. The key thing is that this is all done without actually
+ * modifying the original AST, which has the virtue of allowing one to entertain
+ * several alternate sets of changes on the same AST (e.g., for calculating
+ * quick fix proposals). The rewrite infrastructure tries to generate minimal
+ * text changes, preserve existing comments and indentation, and follow code
+ * formatter settings. If the freedom to explore multiple alternate changes is
+ * not required, consider using the AST's built-in rewriter
+ * (see {@link org.eclipse.jdt.core.dom.CompilationUnit#rewrite(IDocument, Map)}).
+ * <p>
+ * The following code snippet illustrated usage of this class:
+ * </p>
+ * <pre>
+ * Document document = new Document("import java.util.List;\nclass X {}\n");
+ * ASTParser parser = ASTParser.newParser(AST.JLS3);
+ * parser.setSource(document.get().toCharArray());
+ * CompilationUnit cu = (CompilationUnit) parser.createAST(null);
+ * AST ast = cu.getAST();
+ * ImportDeclaration id = ast.newImportDeclaration();
+ * id.setName(ast.newName(new String[] {"java", "util", "Set"}));
+ * ASTRewrite rewriter = ASTRewrite.create(ast);
+ * TypeDeclaration td = (TypeDeclaration) cu.types().get(0);
+ * ITrackedNodePosition tdLocation = rewriter.track(td);
+ * ListRewrite lrw = rewriter.getListRewrite(cu, CompilationUnit.IMPORTS_PROPERTY);
+ * lrw.insertLast(id, null);
+ * TextEdit edits = rewriter.rewriteAST(document, null);
+ * UndoEdit undo = null;
+ * try {
+ *     undo = edits.apply(document);
+ * } catch(MalformedTreeException e) {
+ *     e.printStackTrace();
+ * } catch(BadLocationException e) {
+ *     e.printStackTrace();
+ * }
+ * assert "import java.util.List;\nimport java.util.Set;\nclass X {}\n".equals(document.get());
+ * // tdLocation.getStartPosition() and tdLocation.getLength()
+ * // are new source range for "class X {}" in document.get()
+ * </pre>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ASTRewrite {
+	/** root node for the rewrite: Only nodes under this root are accepted */
+	private final AST ast;
+
+	private final RewriteEventStore eventStore;
+	private final NodeInfoStore nodeStore;
+
+	/**
+	 * Target source range computer; null means uninitialized;
+	 * lazy initialized to <code>new TargetSourceRangeComputer()</code>.
+	 * @since 3.1
+	 */
+	private TargetSourceRangeComputer targetSourceRangeComputer = null;
+	
+	/**
+	 * Primary field used in representing rewrite properties efficiently.
+	 * If <code>null</code>, this rewrite has no properties.
+	 * If a {@link String}, this is the name of this rewrite's sole property,
+	 * and <code>property2</code> contains its value.
+	 * If a {@link Map}, this is the table of property name-value
+	 * mappings.
+	 * Initially <code>null</code>.
+	 * 
+	 * @see #property2
+	 */
+	private Object property1 = null;
+
+	/**
+	 * Auxiliary field used in representing rewrite properties efficiently.
+	 *
+	 * @see #property1
+	 */
+	private Object property2 = null;
+
+	/**
+	 * Creates a new instance for describing manipulations of
+	 * the given AST.
+	 *
+	 * @param ast the AST whose nodes will be rewritten
+	 * @return the new rewriter instance
+	 */
+	public static ASTRewrite create(AST ast) {
+		return new ASTRewrite(ast);
+	}
+
+	/**
+	 * Internal constructor. Creates a new instance for the given AST.
+	 * Clients should use {@link #create(AST)} to create instances.
+	 *
+	 * @param ast the AST being rewritten
+	 */
+	protected ASTRewrite(AST ast) {
+		this.ast= ast;
+		this.eventStore= new RewriteEventStore();
+		this.nodeStore= new NodeInfoStore(ast);
+	}
+
+	/**
+	 * Returns the AST the rewrite was set up on.
+	 *
+	 * @return the AST the rewrite was set up on
+	 */
+	public final AST getAST() {
+		return this.ast;
+	}
+
+	/**
+	 * Internal method. Returns the internal event store.
+	 * Clients should not use.
+	 * @return Returns the internal event store. Clients should not use.
+	 */
+	protected final RewriteEventStore getRewriteEventStore() {
+		return this.eventStore;
+	}
+
+	/**
+	 * Internal method. Returns the internal node info store.
+	 * Clients should not use.
+	 * @return Returns the internal info store. Clients should not use.
+	 */
+	protected final NodeInfoStore getNodeStore() {
+		return this.nodeStore;
+	}
+
+	/**
+	 * Converts all modifications recorded by this rewriter
+	 * into an object representing the corresponding text
+	 * edits to the given document containing the original source
+	 * code. The document itself is not modified.
+	 * <p>
+	 * For nodes in the original that are being replaced or deleted,
+	 * this rewriter computes the adjusted source ranges
+	 * by calling {@link TargetSourceRangeComputer#computeSourceRange(ASTNode) getExtendedSourceRangeComputer().computeSourceRange(node)}.
+	 * </p>
+	 * <p>
+	 * Calling this methods does not discard the modifications
+	 * on record. Subsequence modifications are added to the ones
+	 * already on record. If this method is called again later,
+	 * the resulting text edit object will accurately reflect
+	 * the net cumulative effect of all those changes.
+	 * </p>
+	 *
+	 * @param document original document containing source code
+	 * @param options the table of formatter options
+	 * (key type: <code>String</code>; value type: <code>String</code>);
+	 * or <code>null</code> to use the standard global options
+	 * {@link JavaCore#getOptions() JavaCore.getOptions()}
+	 * @return text edit object describing the changes to the
+	 * document corresponding to the changes recorded by this rewriter
+	 * @throws IllegalArgumentException An <code>IllegalArgumentException</code>
+	 * is thrown if the document passed does not correspond to the AST that is rewritten.
+	 */
+	public TextEdit rewriteAST(IDocument document, Map options) throws IllegalArgumentException {
+		if (document == null) {
+			throw new IllegalArgumentException();
+		}
+
+		ASTNode rootNode= getRootNode();
+		if (rootNode == null) {
+			return new MultiTextEdit(); // no changes
+		}
+
+		char[] content= document.get().toCharArray();
+		LineInformation lineInfo= LineInformation.create(document);
+		String lineDelim= TextUtilities.getDefaultLineDelimiter(document);
+
+		ASTNode astRoot= rootNode.getRoot();
+		List commentNodes= astRoot instanceof CompilationUnit ? ((CompilationUnit) astRoot).getCommentList() : null;
+		Map currentOptions = options == null ? JavaCore.getOptions() : options;
+		return internalRewriteAST(content, lineInfo, lineDelim, commentNodes, currentOptions, rootNode, (RecoveryScannerData)((CompilationUnit) astRoot).getStatementsRecoveryData());
+	}
+
+	/**
+	 * Converts all modifications recorded by this rewriter into an object representing the the corresponding text
+	 * edits to the source of a {@link ITypeRoot} from which the AST was created from.
+	 * The type root's source itself is not modified by this method call.
+	 * <p>
+	 * Important: This API can only be used if the modified AST has been created from a
+	 * {@link ITypeRoot} with source. That means {@link ASTParser#setSource(ICompilationUnit)},
+	 * {@link ASTParser#setSource(IClassFile)} or {@link ASTParser#setSource(ITypeRoot)}
+	 * has been used when initializing the {@link ASTParser}. A {@link IllegalArgumentException} is thrown
+	 * otherwise. An {@link IllegalArgumentException} is also thrown when the type roots buffer does not correspond
+	 * anymore to the AST. Use {@link #rewriteAST(IDocument, Map)} for all ASTs created from other content.
+	 * </p>
+	 * <p>
+	 * For nodes in the original that are being replaced or deleted,
+	 * this rewriter computes the adjusted source ranges
+	 * by calling {@link TargetSourceRangeComputer#computeSourceRange(ASTNode) getExtendedSourceRangeComputer().computeSourceRange(node)}.
+	 * </p>
+	 * <p>
+	 * Calling this methods does not discard the modifications
+	 * on record. Subsequence modifications are added to the ones
+	 * already on record. If this method is called again later,
+	 * the resulting text edit object will accurately reflect
+	 * the net cumulative effect of all those changes.
+	 * </p>
+	 *
+	 * @return text edit object describing the changes to the
+	 * document corresponding to the changes recorded by this rewriter
+	 * @throws JavaModelException A {@link JavaModelException} is thrown when
+	 * the underlying compilation units buffer could not be accessed.
+	 * @throws IllegalArgumentException An {@link IllegalArgumentException}
+	 * is thrown if the document passed does not correspond to the AST that is rewritten.
+	 *
+	 * @since 3.2
+	 */
+	public TextEdit rewriteAST() throws JavaModelException, IllegalArgumentException {
+		ASTNode rootNode= getRootNode();
+		if (rootNode == null) {
+			return new MultiTextEdit(); // no changes
+		}
+
+		ASTNode root= rootNode.getRoot();
+		if (!(root instanceof CompilationUnit)) {
+			throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
+		}
+		CompilationUnit astRoot= (CompilationUnit) root;
+		ITypeRoot typeRoot = astRoot.getTypeRoot();
+		if (typeRoot == null || typeRoot.getBuffer() == null) {
+			throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
+		}
+
+		char[] content= typeRoot.getBuffer().getCharacters();
+		LineInformation lineInfo= LineInformation.create(astRoot);
+		String lineDelim= typeRoot.findRecommendedLineSeparator();
+		Map options= typeRoot.getJavaProject().getOptions(true);
+
+		return internalRewriteAST(content, lineInfo, lineDelim, astRoot.getCommentList(), options, rootNode, (RecoveryScannerData)astRoot.getStatementsRecoveryData());
+	}
+
+	private TextEdit internalRewriteAST(char[] content, LineInformation lineInfo, String lineDelim, List commentNodes, Map options, ASTNode rootNode, RecoveryScannerData recoveryScannerData) {
+		TextEdit result= new MultiTextEdit();
+		//validateASTNotModified(rootNode);
+
+		TargetSourceRangeComputer sourceRangeComputer= getExtendedSourceRangeComputer();
+		this.eventStore.prepareMovedNodes(sourceRangeComputer);
+
+		ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(content, lineInfo, lineDelim, result, this.eventStore, this.nodeStore, commentNodes, options, sourceRangeComputer, recoveryScannerData);
+		rootNode.accept(visitor); // throws IllegalArgumentException
+
+		this.eventStore.revertMovedNodes();
+		return result;
+	}
+
+	private ASTNode getRootNode() {
+		ASTNode node= null;
+		int start= -1;
+		int end= -1;
+
+		for (Iterator iter= getRewriteEventStore().getChangeRootIterator(); iter.hasNext();) {
+			ASTNode curr= (ASTNode) iter.next();
+			if (!RewriteEventStore.isNewNode(curr)) {
+				int currStart= curr.getStartPosition();
+				int currEnd= currStart + curr.getLength();
+				if (node == null || currStart < start && currEnd > end) {
+					start= currStart;
+					end= currEnd;
+					node= curr;
+				} else if (currStart < start) {
+					start= currStart;
+				} else if (currEnd > end) {
+					end= currEnd;
+				}
+			}
+		}
+		if (node != null) {
+			int currStart= node.getStartPosition();
+			int currEnd= currStart + node.getLength();
+			while (start < currStart || end > currEnd) { // go up until a node covers all
+				node= node.getParent();
+				currStart= node.getStartPosition();
+				currEnd= currStart + node.getLength();
+			}
+			ASTNode parent= node.getParent(); // go up until a parent has different range
+			while (parent != null && parent.getStartPosition() == node.getStartPosition() && parent.getLength() == node.getLength()) {
+				node= parent;
+				parent= node.getParent();
+			}
+		}
+		return node;
+	}
+
+	/*
+	private void validateASTNotModified(ASTNode root) throws IllegalArgumentException {
+		GenericVisitor isModifiedVisitor= new GenericVisitor() {
+			protected boolean visitNode(ASTNode node) {
+				if ((node.getFlags() & ASTNode.ORIGINAL) == 0) {
+					throw new IllegalArgumentException("The AST that is rewritten must not be modified."); //$NON-NLS-1$
+				}
+				return true;
+			}
+		};
+		root.accept(isModifiedVisitor);
+	}
+	*/
+
+	/**
+	 * Removes the given node from its parent in this rewriter. The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node should not be there.
+	 *
+	 * @param node the node being removed. The node can either be an original node in the AST
+	 * or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not
+	 * part of this rewriter's AST, or if the described modification is invalid
+	 * (such as removing a required node)
+	 */
+	public final void remove(ASTNode node, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+
+		StructuralPropertyDescriptor property;
+		ASTNode parent;
+		if (RewriteEventStore.isNewNode(node)) { // remove a new node, bug 164862
+			PropertyLocation location= this.eventStore.getPropertyLocation(node, RewriteEventStore.NEW);
+			if (location != null) {
+				property= location.getProperty();
+				parent= location.getParent();
+			} else {
+				throw new IllegalArgumentException("Node is not part of the rewriter's AST"); //$NON-NLS-1$
+			}
+		} else {
+			property= node.getLocationInParent();
+			parent= node.getParent();
+		}
+
+		if (property.isChildListProperty()) {
+			getListRewrite(parent, (ChildListPropertyDescriptor) property).remove(node, editGroup);
+		} else {
+			set(parent, property, null, editGroup);
+		}
+	}
+
+	/**
+	 * Replaces the given node in this rewriter. The replacement node
+	 * must either be brand new (not part of the original AST) or a placeholder
+	 * node (for example, one created by {@link #createCopyTarget(ASTNode)}
+	 * or {@link #createStringPlaceholder(String, int)}). The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node has been replaced.
+	 *
+	 * @param node the node being replaced. The node can either be an original node in the AST
+	 * or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
+	 * @param replacement the replacement node, or <code>null</code> if no
+	 * replacement
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not part
+	 * of this rewriter's AST, or if the replacement node is not a new node (or
+     * placeholder), or if the described modification is otherwise invalid
+	 */
+	public final void replace(ASTNode node, ASTNode replacement, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+
+		StructuralPropertyDescriptor property;
+		ASTNode parent;
+		if (RewriteEventStore.isNewNode(node)) { // replace a new node, bug 164862
+			PropertyLocation location= this.eventStore.getPropertyLocation(node, RewriteEventStore.NEW);
+			if (location != null) {
+				property= location.getProperty();
+				parent= location.getParent();
+			} else {
+				throw new IllegalArgumentException("Node is not part of the rewriter's AST"); //$NON-NLS-1$
+			}
+		} else {
+			property= node.getLocationInParent();
+			parent= node.getParent();
+		}
+
+		if (property.isChildListProperty()) {
+			getListRewrite(parent, (ChildListPropertyDescriptor) property).replace(node, replacement, editGroup);
+		} else {
+			set(parent, property, replacement, editGroup);
+		}
+	}
+
+	/**
+	 * Sets the given property of the given node. If the given property is a child
+     * property, the value must be a replacement node that is either be brand new
+     * (not part of the original AST) or a placeholder node (for example, one
+     * created by {@link #createCopyTarget(ASTNode)}
+	 * or {@link #createStringPlaceholder(String, int)}); or it must be
+	 * <code>null</code>, indicating that the child should be deleted.
+	 * If the given property is a simple property, the value must be the new
+	 * value (primitive types must be boxed) or <code>null</code>.
+     * The AST itself is not actually modified in any way; rather, the rewriter
+     * just records a note that this node has been changed in the specified way.
+	 *
+	 * @param node the node
+	 * @param property the node's property; either a simple property or a child property
+	 * @param value the replacement child or new value, or <code>null</code> if none
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node or property is null, or if the node
+	 * is not part of this rewriter's AST, or if the property is not a node property,
+	 * or if the described modification is invalid
+	 */
+	public final void set(ASTNode node, StructuralPropertyDescriptor property, Object value, TextEditGroup editGroup) {
+		if (node == null || property == null) {
+			throw new IllegalArgumentException();
+		}
+		validateIsCorrectAST(node);
+		validatePropertyType(property, value);
+		validateIsPropertyOfNode(property, node);
+
+		NodeRewriteEvent nodeEvent= this.eventStore.getNodeEvent(node, property, true);
+		nodeEvent.setNewValue(value);
+		if (editGroup != null) {
+			this.eventStore.setEventEditGroup(nodeEvent, editGroup);
+		}
+	}
+
+	/**
+	 * Returns the value of the given property as managed by this rewriter. If the property
+	 * has been removed, <code>null</code> is returned. If it has been replaced, the replacing value
+	 * is returned. If the property has not been changed yet, the original value is returned.
+	 * <p>
+	 * For child list properties use {@link ListRewrite#getRewrittenList()} to get access to the
+	 * rewritten nodes in a list. </p>
+	 *
+	 * @param node the node
+	 * @param property the node's property
+	 * @return the value of the given property as managed by this rewriter
+	 *
+	 * @since 3.2
+	 */
+	public Object get(ASTNode node, StructuralPropertyDescriptor property) {
+		if (node == null || property == null) {
+			throw new IllegalArgumentException();
+		}
+		if (property.isChildListProperty()) {
+			throw new IllegalArgumentException("Use the list rewriter to access nodes in a list"); //$NON-NLS-1$
+		}
+		return this.eventStore.getNewValue(node, property);
+	}
+
+	/**
+	 * Creates and returns a new rewriter for describing modifications to the
+	 * given list property of the given node.
+	 *
+	 * @param node the node
+	 * @param property the node's property; the child list property
+	 * @return a new list rewriter object
+	 * @throws IllegalArgumentException if the node or property is null, or if the node
+	 * is not part of this rewriter's AST, or if the property is not a node property,
+	 * or if the described modification is invalid
+	 */
+	public final ListRewrite getListRewrite(ASTNode node, ChildListPropertyDescriptor property) {
+		if (node == null || property == null) {
+			throw new IllegalArgumentException();
+		}
+		
+		validateIsCorrectAST(node);
+		validateIsListProperty(property);
+		validateIsPropertyOfNode(property, node);
+
+		return new ListRewrite(this, node, property);
+	}
+
+	/**
+	 * Returns the value of the named property of this rewrite, or <code>null</code> if none.
+	 *
+	 * @param propertyName the property name
+	 * @return the property value, or <code>null</code> if none
+	 * @see #setProperty(String,Object)
+	 * @throws IllegalArgumentException if the given property name is <code>null</code>
+	 * @since 3.7
+	 */
+	public final Object getProperty(String propertyName) {
+		if (propertyName == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.property1 == null) {
+			// rewrite has no properties at all
+			return null;
+		}
+		if (this.property1 instanceof String) {
+			// rewrite has only a single property
+			if (propertyName.equals(this.property1)) {
+				return this.property2;
+			} else {
+				return null;
+			}
+		}
+		// otherwise rewrite has table of properties
+		Map m = (Map) this.property1;
+		return m.get(propertyName);
+	}
+	
+	/**
+	 * Returns an object that tracks the source range of the given node
+	 * across the rewrite to its AST. Upon return, the result object reflects
+	 * the given node's current source range in the AST. After
+	 * <code>rewrite</code> is called, the result object is updated to
+	 * reflect the given node's source range in the rewritten AST.
+	 *
+	 * @param node the node to track
+	 * @return an object that tracks the source range of <code>node</code>
+	 * @throws IllegalArgumentException if the node is null, or if the node
+	 * is not part of this rewriter's AST, or if the node is already being
+	 * tracked
+	 */
+	public final ITrackedNodePosition track(ASTNode node) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		TextEditGroup group= this.eventStore.getTrackedNodeData(node);
+		if (group == null) {
+			group= new TextEditGroup("internal"); //$NON-NLS-1$
+			this.eventStore.setTrackedNodeData(node, group);
+		}
+		return new TrackedNodePosition(group, node);
+	}
+
+	private void validateIsExistingNode(ASTNode node) {
+		if (node.getStartPosition() == -1) {
+			throw new IllegalArgumentException("Node is not an existing node"); //$NON-NLS-1$
+		}
+	}
+
+	private void validateIsCorrectAST(ASTNode node) {
+		if (node.getAST() != getAST()) {
+			throw new IllegalArgumentException("Node is not inside the AST"); //$NON-NLS-1$
+		}
+	}
+
+	private void validateIsListProperty(StructuralPropertyDescriptor property) {
+		if (!property.isChildListProperty()) {
+			String message= property.getId() + " is not a list property"; //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+	}
+	
+	private void validateIsPropertyOfNode(StructuralPropertyDescriptor property, ASTNode node) {
+		if (!property.getNodeClass().isInstance(node)) {
+			String message= property.getId() + " is not a property of type " + node.getClass().getName(); //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+	}
+
+	private void validatePropertyType(StructuralPropertyDescriptor prop, Object value) {
+		if (prop.isChildListProperty()) {
+			String message = "Can not modify a list property, use getListRewrite()"; //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+		if (!RewriteEventStore.DEBUG) {
+			return;
+		}
+		
+		if (value == null) {
+			if (prop.isSimpleProperty() && ((SimplePropertyDescriptor) prop).isMandatory()
+					|| prop.isChildProperty() && ((ChildPropertyDescriptor) prop).isMandatory()) {
+				String message = "Can not remove property " + prop.getId(); //$NON-NLS-1$
+				throw new IllegalArgumentException(message);
+			}
+			
+		} else {
+			Class valueType;
+			if (prop.isSimpleProperty()) {
+				SimplePropertyDescriptor p = (SimplePropertyDescriptor) prop;
+				valueType = p.getValueType();
+				if (valueType == int.class) {
+					valueType = Integer.class;
+				} else if (valueType == boolean.class) {
+					valueType = Boolean.class;
+				}
+			} else {
+				ChildPropertyDescriptor p = (ChildPropertyDescriptor) prop;
+				valueType = p.getChildType();
+			}
+			if (!valueType.isAssignableFrom(value.getClass())) {
+				String message = value.getClass().getName() + " is not a valid type for " + prop.getNodeClass().getName() //$NON-NLS-1$
+						+ " property '" + prop.getId() + '\''; //$NON-NLS-1$
+				throw new IllegalArgumentException(message);
+			}
+		}
+	}
+
+	/**
+	 * Creates and returns a placeholder node for a source string that is to be inserted into
+	 * the output document at the position corresponding to the placeholder.
+	 * The string will be inserted without being reformatted beyond correcting
+	 * the indentation level. The placeholder node can either be inserted as new or
+	 * used to replace an existing node.
+	 *
+	 * @param code the string to be inserted; lines should should not have extra indentation
+	 * @param nodeType the ASTNode type that corresponds to the passed code.
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException if the code is null, or if the node
+	 * type is invalid
+	 */
+	public final ASTNode createStringPlaceholder(String code, int nodeType) {
+		if (code == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode placeholder= getNodeStore().newPlaceholderNode(nodeType);
+		if (placeholder == null) {
+			throw new IllegalArgumentException("String placeholder is not supported for type" + nodeType); //$NON-NLS-1$
+		}
+
+		getNodeStore().markAsStringPlaceholder(placeholder, code);
+		return placeholder;
+	}
+
+	/**
+	 * Creates and returns a node that represents a sequence of nodes.
+	 * Each of the given nodes must be either be brand new (not part of the original AST), or
+	 * a placeholder node (for example, one created by {@link #createCopyTarget(ASTNode)}
+	 * or {@link #createStringPlaceholder(String, int)}), or another group node.
+	 * The type of the returned node is unspecified. The returned node can be used
+	 * to replace an existing node (or as an element of another group node).
+	 * When the document is rewritten, the source code for each of the given nodes is
+	 * inserted, in order, into the output document at the position corresponding to the
+	 * group (indentation is adjusted).
+	 *
+	 * @param targetNodes the nodes to go in the group
+	 * @return the new group node
+	 * @throws IllegalArgumentException if the targetNodes is <code>null</code> or empty
+	 * @since 3.1
+	 */
+	public final ASTNode createGroupNode(ASTNode[] targetNodes) {
+		if (targetNodes == null || targetNodes.length == 0) {
+			throw new IllegalArgumentException();
+		}
+		Block res= getNodeStore().createCollapsePlaceholder();
+		ListRewrite listRewrite= getListRewrite(res, Block.STATEMENTS_PROPERTY);
+		for (int i= 0; i < targetNodes.length; i++) {
+			listRewrite.insertLast(targetNodes[i], null);
+		}
+		return res;
+	}
+
+
+	private ASTNode createTargetNode(ASTNode node, boolean isMove) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		validateIsExistingNode(node);
+		validateIsCorrectAST(node);
+		CopySourceInfo info= getRewriteEventStore().markAsCopySource(node.getParent(), node.getLocationInParent(), node, isMove);
+
+		ASTNode placeholder= getNodeStore().newPlaceholderNode(node.getNodeType());
+		if (placeholder == null) {
+			throw new IllegalArgumentException("Creating a target node is not supported for nodes of type" + node.getClass().getName()); //$NON-NLS-1$
+		}
+		getNodeStore().markAsCopyTarget(placeholder, info);
+
+		return placeholder;
+	}
+
+	/**
+	 * Creates and returns a placeholder node for a true copy of the given node.
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. When the document is rewritten, a copy of the source code
+	 * for the given node is inserted into the output document at the position
+	 * corresponding to the placeholder (indentation is adjusted).
+	 *
+	 * @param node the node to create a copy placeholder for
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException if the node is null, or if the node
+	 * is not part of this rewriter's AST
+	 */
+	public final ASTNode createCopyTarget(ASTNode node) {
+		return createTargetNode(node, false);
+	}
+
+	/**
+	 * Creates and returns a placeholder node for the new locations of the given node.
+	 * After obtaining a placeholder, the node must be removed or replaced.
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. The placeholder must be used somewhere in the AST and must not be dropped
+	 * by subsequent modifications. When the document is rewritten, the source code for the given
+	 * node is inserted into the output document at the position corresponding to the
+	 * placeholder (indentation is adjusted).
+	 *
+	 * @param node the node to create a move placeholder for
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException if the node is null, or if the node
+	 * is not part of this rewriter's AST
+	 */
+	public final ASTNode createMoveTarget(ASTNode node) {
+		return createTargetNode(node, true);
+	}
+
+	/**
+	 * Returns the extended source range computer for this AST rewriter.
+	 * The default value is a <code>new TargetSourceRangeComputer()</code>.
+	 *
+	 * @return an extended source range computer
+	 * @since 3.1
+	 * @see #setTargetSourceRangeComputer(TargetSourceRangeComputer)
+	 */
+	public final TargetSourceRangeComputer getExtendedSourceRangeComputer() {
+		if (this.targetSourceRangeComputer == null) {
+			// lazy initialize
+			this.targetSourceRangeComputer = new TargetSourceRangeComputer();
+		}
+		return this.targetSourceRangeComputer;
+	}
+
+	/**
+	 * Sets the named property of this rewrite to the given value,
+	 * or to <code>null</code> to clear it.
+	 * <p>
+	 * Clients should employ property names that are sufficiently unique
+	 * to avoid inadvertent conflicts with other clients that might also be
+	 * setting properties on the same rewrite.
+	 * </p>
+	 * <p>
+	 * Note that modifying a property is not considered a modification to the
+	 * AST itself. This is to allow clients to decorate existing rewrites with
+	 * their own properties without jeopardizing certain things (like the
+	 * validity of bindings), which rely on the underlying tree remaining static.
+	 * </p>
+	 *
+	 * @param propertyName the property name
+	 * @param data the new property value, or <code>null</code> if none
+	 * @see #getProperty(String)
+	 * @throws IllegalArgumentException if the given property name is <code>null</code>
+	 * @since 3.7
+	 */
+	public final void setProperty(String propertyName, Object data) {
+		if (propertyName == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.property1 == null) {
+			// rewrite has no properties at all
+			if (data == null) {
+				// rewrite already knows this
+				return;
+			}
+			// rewrite gets its fist property
+			this.property1 = propertyName;
+			this.property2 = data;
+			return;
+		}
+		if (this.property1 instanceof String) {
+			// rewrite has only a single property
+			if (propertyName.equals(this.property1)) {
+				// we're in luck
+				if (data == null) {
+					// just delete last property
+					this.property1 = null;
+					this.property2 = null;
+				} else {
+					this.property2 = data;
+				}
+				return;
+			}
+			if (data == null) {
+				// we already know this
+				return;
+			}
+			// rewrite already has one property - getting its second
+			// convert to more flexible representation
+			Map m = new HashMap(3);
+			m.put(this.property1, this.property2);
+			m.put(propertyName, data);
+			this.property1 = m;
+			this.property2 = null;
+			return;
+		}
+		// rewrite has two or more properties
+		Map m = (Map) this.property1;
+		if (data == null) {
+			m.remove(propertyName);
+			// check for just one property left
+			if (m.size() == 1) {
+				// convert to more efficient representation
+				Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
+				this.property1 = entries[0].getKey();
+				this.property2 = entries[0].getValue();
+			}
+			return;
+		} else {
+			m.put(propertyName, data);
+			// still has two or more properties
+			return;
+		}
+	}
+
+	/**
+	 * Sets a custom target source range computer for this AST rewriter. This is advanced feature to modify how
+	 * comments are associated with nodes, which should be done only in special cases.
+	 *
+	 * @param computer a target source range computer,
+	 * or <code>null</code> to restore the default value of
+	 * <code>new TargetSourceRangeComputer()</code>
+	 * @since 3.1
+	 * @see #getExtendedSourceRangeComputer()
+	 */
+	public final void setTargetSourceRangeComputer(TargetSourceRangeComputer computer) {
+		// if computer==null, rely on lazy init code in getExtendedSourceRangeComputer()
+		this.targetSourceRangeComputer = computer;
+	}
+
+	/**
+	 * Returns a string suitable for debugging purposes (only).
+	 *
+	 * @return a debug string
+	 */
+	public String toString() {
+		StringBuffer buf= new StringBuffer();
+		buf.append("Events:\n"); //$NON-NLS-1$
+		// be extra careful of uninitialized or mangled instances
+		if (this.eventStore != null) {
+			buf.append(this.eventStore.toString());
+		}
+		return buf.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java
new file mode 100644
index 0000000..782e1d4
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+/**
+ * A tracked node position is returned when a rewrite change is
+ * requested to be tracked.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ *
+ * @see ASTRewrite#track(org.eclipse.jdt.core.dom.ASTNode)
+ * @since 3.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITrackedNodePosition {
+
+	/**
+	 * Returns the original or modified start position of the tracked node depending if called before
+	 * or after the rewrite is applied. <code>-1</code> is returned for removed nodes.
+	 *
+	 * @return the original or modified start position of the tracked node
+	 */
+	public int getStartPosition();
+
+	/**
+	 * Returns the original or modified length of the tracked node depending if called before
+	 * or after the rewrite is applied. <code>-1</code> is returned for removed nodes.
+	 *
+	 * @return the original or modified length of the tracked node
+	 */
+	public int getLength();
+
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
new file mode 100644
index 0000000..ae03cda
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ImportRewrite.java
@@ -0,0 +1,1161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.internal.core.dom.rewrite.ImportRewriteAnalyzer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+
+
+/**
+ * The {@link ImportRewrite} helps updating imports following a import order and on-demand imports threshold as configured by a project.
+ * <p>
+ * The import rewrite is created on a compilation unit and collects references to types that are added or removed. When adding imports, e.g. using
+ * {@link #addImport(String)}, the import rewrite evaluates if the type can be imported and returns the a reference to the type that can be used in code.
+ * This reference is either unqualified if the import could be added, or fully qualified if the import failed due to a conflict with another element of the same name.
+ * </p>
+ * <p>
+ * On {@link #rewriteImports(IProgressMonitor)} the rewrite translates these descriptions into
+ * text edits that can then be applied to the original source. The rewrite infrastructure tries to generate minimal text changes and only
+ * works on the import statements. It is possible to combine the result of an import rewrite with the result of a {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite}
+ * as long as no import statements are modified by the AST rewrite.
+ * </p>
+ * <p>The options controlling the import order and on-demand thresholds are:
+ * <ul><li>{@link #setImportOrder(String[])} specifies the import groups and their preferred order</li>
+ * <li>{@link #setOnDemandImportThreshold(int)} specifies the number of imports in a group needed for a on-demand import statement (star import)</li>
+ * <li>{@link #setStaticOnDemandImportThreshold(int)} specifies the number of static imports in a group needed for a on-demand import statement (star import)</li>
+ *</ul>
+ * This class is not intended to be subclassed.
+ * </p>
+ * @since 3.2
+ */
+public final class ImportRewrite {
+
+	/**
+	 * A {@link ImportRewrite.ImportRewriteContext} can optionally be used in e.g. {@link ImportRewrite#addImport(String, ImportRewrite.ImportRewriteContext)} to
+	 * give more information about the types visible in the scope. These types can be for example inherited inner types where it is
+	 * unnecessary to add import statements for.
+	 *
+	 * </p>
+	 * <p>
+	 * This class can be implemented by clients.
+	 * </p>
+	 */
+	public static abstract class ImportRewriteContext {
+
+		/**
+		 * Result constant signaling that the given element is know in the context.
+		 */
+		public final static int RES_NAME_FOUND= 1;
+
+		/**
+		 * Result constant signaling that the given element is not know in the context.
+		 */
+		public final static int RES_NAME_UNKNOWN= 2;
+
+		/**
+		 * Result constant signaling that the given element is conflicting with an other element in the context.
+		 */
+		public final static int RES_NAME_CONFLICT= 3;
+
+		/**
+		 * Kind constant specifying that the element is a type import.
+		 */
+		public final static int KIND_TYPE= 1;
+
+		/**
+		 * Kind constant specifying that the element is a static field import.
+		 */
+		public final static int KIND_STATIC_FIELD= 2;
+
+		/**
+		 * Kind constant specifying that the element is a static method import.
+		 */
+		public final static int KIND_STATIC_METHOD= 3;
+
+		/**
+		 * Searches for the given element in the context and reports if the element is known ({@link #RES_NAME_FOUND}),
+		 * unknown ({@link #RES_NAME_UNKNOWN}) or if its name conflicts ({@link #RES_NAME_CONFLICT}) with an other element.
+		 * @param qualifier The qualifier of the element, can be package or the qualified name of a type
+		 * @param name The simple name of the element; either a type, method or field name or * for on-demand imports.
+		 * @param kind The kind of the element. Can be either {@link #KIND_TYPE}, {@link #KIND_STATIC_FIELD} or
+		 * {@link #KIND_STATIC_METHOD}. Implementors should be prepared for new, currently unspecified kinds and return
+		 * {@link #RES_NAME_UNKNOWN} by default.
+		 * @return Returns the result of the lookup. Can be either {@link #RES_NAME_FOUND}, {@link #RES_NAME_UNKNOWN} or
+		 * {@link #RES_NAME_CONFLICT}.
+		 */
+		public abstract int findInContext(String qualifier, String name, int kind);
+	}
+
+	private static final char STATIC_PREFIX= 's';
+	private static final char NORMAL_PREFIX= 'n';
+
+	private final ImportRewriteContext defaultContext;
+
+	private final ICompilationUnit compilationUnit;
+	private final CompilationUnit astRoot;
+
+	private final boolean restoreExistingImports;
+	private final List existingImports;
+	private final Map importsKindMap;
+
+	private String[] importOrder;
+	private int importOnDemandThreshold;
+	private int staticImportOnDemandThreshold;
+
+	private List addedImports;
+	private List removedImports;
+
+	private String[] createdImports;
+	private String[] createdStaticImports;
+
+	private boolean filterImplicitImports;
+	private boolean useContextToFilterImplicitImports;
+
+	/**
+	 * Creates a {@link ImportRewrite} from a {@link ICompilationUnit}. If <code>restoreExistingImports</code>
+	 * is <code>true</code>, all existing imports are kept, and new imports will be inserted at best matching locations. If
+	 * <code>restoreExistingImports</code> is <code>false</code>, the existing imports will be removed and only the
+	 * newly added imports will be created.
+	 * <p>
+	 * Note that {@link #create(ICompilationUnit, boolean)} is more efficient than this method if an AST for
+	 * the compilation unit is already available.
+	 * </p>
+	 * @param cu the compilation unit to create the imports for
+	 * @param restoreExistingImports specifies if the existing imports should be kept or removed.
+	 * @return the created import rewriter.
+	 * @throws JavaModelException thrown when the compilation unit could not be accessed.
+	 */
+	public static ImportRewrite create(ICompilationUnit cu, boolean restoreExistingImports) throws JavaModelException {
+		if (cu == null) {
+			throw new IllegalArgumentException("Compilation unit must not be null"); //$NON-NLS-1$
+		}
+		List existingImport= null;
+		if (restoreExistingImports) {
+			existingImport= new ArrayList();
+			IImportDeclaration[] imports= cu.getImports();
+			for (int i= 0; i < imports.length; i++) {
+				IImportDeclaration curr= imports[i];
+				char prefix= Flags.isStatic(curr.getFlags()) ? STATIC_PREFIX : NORMAL_PREFIX;
+				existingImport.add(prefix + curr.getElementName());
+			}
+		}
+		return new ImportRewrite(cu, null, existingImport);
+	}
+
+	/**
+	 * Creates a {@link ImportRewrite} from a an AST ({@link CompilationUnit}). The AST has to be created from a
+	 * {@link ICompilationUnit}, that means {@link ASTParser#setSource(ICompilationUnit)} has been used when creating the
+	 * AST. If <code>restoreExistingImports</code> is <code>true</code>, all existing imports are kept, and new imports
+	 * will be inserted at best matching locations. If <code>restoreExistingImports</code> is <code>false</code>, the
+	 * existing imports will be removed and only the newly added imports will be created.
+	 * <p>
+	 * Note that this method is more efficient than using {@link #create(ICompilationUnit, boolean)} if an AST is already available.
+	 * </p>
+	 * @param astRoot the AST root node to create the imports for
+	 * @param restoreExistingImports specifies if the existing imports should be kept or removed.
+	 * @return the created import rewriter.
+	 * @throws IllegalArgumentException thrown when the passed AST is null or was not created from a compilation unit.
+	 */
+	public static ImportRewrite create(CompilationUnit astRoot, boolean restoreExistingImports) {
+		if (astRoot == null) {
+			throw new IllegalArgumentException("AST must not be null"); //$NON-NLS-1$
+		}
+		ITypeRoot typeRoot = astRoot.getTypeRoot();
+		if (!(typeRoot instanceof ICompilationUnit)) {
+			throw new IllegalArgumentException("AST must have been constructed from a Java element"); //$NON-NLS-1$
+		}
+		List existingImport= null;
+		if (restoreExistingImports) {
+			existingImport= new ArrayList();
+			List imports= astRoot.imports();
+			for (int i= 0; i < imports.size(); i++) {
+				ImportDeclaration curr= (ImportDeclaration) imports.get(i);
+				StringBuffer buf= new StringBuffer();
+				buf.append(curr.isStatic() ? STATIC_PREFIX : NORMAL_PREFIX).append(curr.getName().getFullyQualifiedName());
+				if (curr.isOnDemand()) {
+					if (buf.length() > 1)
+						buf.append('.');
+					buf.append('*');
+				}
+				existingImport.add(buf.toString());
+			}
+		}
+		return new ImportRewrite((ICompilationUnit) typeRoot, astRoot, existingImport);
+	}
+
+	private ImportRewrite(ICompilationUnit cu, CompilationUnit astRoot, List existingImports) {
+		this.compilationUnit= cu;
+		this.astRoot= astRoot; // might be null
+		if (existingImports != null) {
+			this.existingImports= existingImports;
+			this.restoreExistingImports= !existingImports.isEmpty();
+		} else {
+			this.existingImports= new ArrayList();
+			this.restoreExistingImports= false;
+		}
+		this.filterImplicitImports= true;
+		// consider that no contexts are used
+		this.useContextToFilterImplicitImports = false;
+
+		this.defaultContext= new ImportRewriteContext() {
+			public int findInContext(String qualifier, String name, int kind) {
+				return findInImports(qualifier, name, kind);
+			}
+		};
+		this.addedImports= null; // Initialized on use
+		this.removedImports= null; // Initialized on use
+		this.createdImports= null;
+		this.createdStaticImports= null;
+
+		this.importOrder= CharOperation.NO_STRINGS;
+		this.importOnDemandThreshold= 99;
+		this.staticImportOnDemandThreshold= 99;
+		
+		this.importsKindMap = new HashMap();
+	}
+
+
+	 /**
+	 * Defines the import groups and order to be used by the {@link ImportRewrite}.
+	 * Imports are added to the group matching their qualified name most. The empty group name groups all imports not matching
+	 * any other group. Static imports are managed in separate groups. Static import group names are prefixed with a '#' character.
+	 * @param order A list of strings defining the import groups. A group name must be a valid package name or empty. If can be
+	 * prefixed by the '#' character for static import groups
+	 */
+	public void setImportOrder(String[] order) {
+		if (order == null)
+			throw new IllegalArgumentException("Order must not be null"); //$NON-NLS-1$
+		this.importOrder= order;
+	}
+
+	 /**
+	 *	Sets the on-demand import threshold for normal (non-static) imports.
+	 *	This threshold defines the number of imports that need to be in a group to use
+	 * a on-demand (star) import declaration instead.
+	 *
+	 * @param threshold a positive number defining the on-demand import threshold
+	 * for normal (non-static) imports.
+	 * @throws IllegalArgumentException a {@link IllegalArgumentException} is thrown
+	 * if the number is not positive.
+     */
+	public void setOnDemandImportThreshold(int threshold) {
+		if (threshold <= 0)
+			throw new IllegalArgumentException("Threshold must be positive."); //$NON-NLS-1$
+		this.importOnDemandThreshold= threshold;
+	}
+
+	 /**
+	 *	Sets the on-demand import threshold for static imports.
+	 *	This threshold defines the number of imports that need to be in a group to use
+	 * a on-demand (star) import declaration instead.
+	 *
+	 * @param threshold a positive number defining the on-demand import threshold
+	 * for normal (non-static) imports.
+	 * @throws IllegalArgumentException a {@link IllegalArgumentException} is thrown
+	 * if the number is not positive.
+     */
+	public void setStaticOnDemandImportThreshold(int threshold) {
+		if (threshold <= 0)
+			throw new IllegalArgumentException("Threshold must be positive."); //$NON-NLS-1$
+		this.staticImportOnDemandThreshold= threshold;
+	}
+
+	/**
+	 * The compilation unit for which this import rewrite was created for.
+	 * @return the compilation unit for which this import rewrite was created for.
+	 */
+	public ICompilationUnit getCompilationUnit() {
+		return this.compilationUnit;
+	}
+
+	/**
+	 * Returns the default rewrite context that only knows about the imported types. Clients
+	 * can write their own context and use the default context for the default behavior.
+	 * @return the default import rewrite context.
+	 */
+	public ImportRewriteContext getDefaultImportRewriteContext() {
+		return this.defaultContext;
+	}
+
+	/**
+	 * Specifies that implicit imports (for types in <code>java.lang</code>, types in the same package as the rewrite
+	 * compilation unit, and types in the compilation unit's main type) should not be created, except if necessary to
+	 * resolve an on-demand import conflict.
+	 * <p>
+	 * The filter is enabled by default.
+	 * </p>
+	 * <p>
+	 * Note: {@link #setUseContextToFilterImplicitImports(boolean)} can be used to filter implicit imports
+	 * when a context is used.
+	 * </p>
+	 * 
+	 * @param filterImplicitImports
+	 *            if <code>true</code>, implicit imports will be filtered
+	 * 
+	 * @see #setUseContextToFilterImplicitImports(boolean)
+	 */
+	public void setFilterImplicitImports(boolean filterImplicitImports) {
+		this.filterImplicitImports= filterImplicitImports;
+	}
+
+	/**
+	* Sets whether a context should be used to properly filter implicit imports.
+	* <p>
+	* By default, the option is disabled to preserve pre-3.6 behavior.
+	* </p>
+	* <p>
+	* When this option is set, the context passed to the <code>addImport*(...)</code> 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 <code>addImport*(...)</code> methods are called without a context.
+	* </p>
+	* 
+	* @param useContextToFilterImplicitImports the given setting
+	* 
+	* @see #setFilterImplicitImports(boolean)
+	* @since 3.6
+	*/
+	public void setUseContextToFilterImplicitImports(boolean useContextToFilterImplicitImports) {
+		this.useContextToFilterImplicitImports = useContextToFilterImplicitImports;
+	}
+	
+	private static int compareImport(char prefix, String qualifier, String name, String curr) {
+		if (curr.charAt(0) != prefix || !curr.endsWith(name)) {
+			return ImportRewriteContext.RES_NAME_UNKNOWN;
+		}
+
+		curr= curr.substring(1); // remove the prefix
+
+		if (curr.length() == name.length()) {
+			if (qualifier.length() == 0) {
+				return ImportRewriteContext.RES_NAME_FOUND;
+			}
+			return ImportRewriteContext.RES_NAME_CONFLICT;
+		}
+		// at this place: curr.length > name.length
+
+		int dotPos= curr.length() - name.length() - 1;
+		if (curr.charAt(dotPos) != '.') {
+			return ImportRewriteContext.RES_NAME_UNKNOWN;
+		}
+		if (qualifier.length() != dotPos || !curr.startsWith(qualifier)) {
+			return ImportRewriteContext.RES_NAME_CONFLICT;
+		}
+		return ImportRewriteContext.RES_NAME_FOUND;
+	}
+
+	/**
+	 * Not API, package visibility as accessed from an anonymous type
+	 */
+	/* package */ final int findInImports(String qualifier, String name, int kind) {
+		boolean allowAmbiguity=  (kind == ImportRewriteContext.KIND_STATIC_METHOD) || (name.length() == 1 && name.charAt(0) == '*');
+		List imports= this.existingImports;
+		char prefix= (kind == ImportRewriteContext.KIND_TYPE) ? NORMAL_PREFIX : STATIC_PREFIX;
+
+		for (int i= imports.size() - 1; i >= 0 ; i--) {
+			String curr= (String) imports.get(i);
+			int res= compareImport(prefix, qualifier, name, curr);
+			if (res != ImportRewriteContext.RES_NAME_UNKNOWN) {
+				if (!allowAmbiguity || res == ImportRewriteContext.RES_NAME_FOUND) {
+					if (prefix != STATIC_PREFIX) {
+						return res;
+					}
+					Object currKind = this.importsKindMap.get(curr.substring(1));
+					if (currKind != null && currKind.equals(this.importsKindMap.get(qualifier + '.' + name))) {
+						return res;
+					}
+				}
+			}
+		}
+		if (this.filterImplicitImports && this.useContextToFilterImplicitImports) {
+			String fPackageName= this.compilationUnit.getParent().getElementName();
+			String mainTypeSimpleName= JavaCore.removeJavaLikeExtension(this.compilationUnit.getElementName());
+			String fMainTypeName= Util.concatenateName(fPackageName, mainTypeSimpleName, '.');
+			if (kind == ImportRewriteContext.KIND_TYPE
+					&& (qualifier.equals(fPackageName)
+							|| fMainTypeName.equals(Util.concatenateName(qualifier, name, '.'))))
+				return ImportRewriteContext.RES_NAME_FOUND;
+		}
+		return ImportRewriteContext.RES_NAME_UNKNOWN;
+	}
+	/**
+	 * Adds a new import to the rewriter's record and returns a {@link Type} node that can be used
+	 * in the code as a reference to the type. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param typeSig the signature of the type to be added.
+	 * @param ast the AST to create the returned type for.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public Type addImportFromSignature(String typeSig, AST ast) {
+		return addImportFromSignature(typeSig, ast, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a {@link Type} node that can be used
+	 * in the code as a reference to the type. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param typeSig the signature of the type to be added.
+	 * @param ast the AST to create the returned type for.
+	 * @param context an optional context that knows about types visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public Type addImportFromSignature(String typeSig, AST ast, ImportRewriteContext context) {
+		if (typeSig == null || typeSig.length() == 0) {
+			throw new IllegalArgumentException("Invalid type signature: empty or null"); //$NON-NLS-1$
+		}
+		int sigKind= Signature.getTypeSignatureKind(typeSig);
+		switch (sigKind) {
+			case Signature.BASE_TYPE_SIGNATURE:
+				return ast.newPrimitiveType(PrimitiveType.toCode(Signature.toString(typeSig)));
+			case Signature.ARRAY_TYPE_SIGNATURE:
+				Type elementType= addImportFromSignature(Signature.getElementType(typeSig), ast, context);
+				return ast.newArrayType(elementType, Signature.getArrayCount(typeSig));
+			case Signature.CLASS_TYPE_SIGNATURE:
+				String erasureSig= Signature.getTypeErasure(typeSig);
+
+				String erasureName= Signature.toString(erasureSig);
+				if (erasureSig.charAt(0) == Signature.C_RESOLVED) {
+					erasureName= internalAddImport(erasureName, context);
+				}
+				Type baseType= ast.newSimpleType(ast.newName(erasureName));
+				String[] typeArguments= Signature.getTypeArguments(typeSig);
+				if (typeArguments.length > 0) {
+					ParameterizedType type= ast.newParameterizedType(baseType);
+					List argNodes= type.typeArguments();
+					for (int i= 0; i < typeArguments.length; i++) {
+						String curr= typeArguments[i];
+						if (containsNestedCapture(curr)) { // see bug 103044
+							argNodes.add(ast.newWildcardType());
+						} else {
+							argNodes.add(addImportFromSignature(curr, ast, context));
+						}
+					}
+					return type;
+				}
+				return baseType;
+			case Signature.TYPE_VARIABLE_SIGNATURE:
+				return ast.newSimpleType(ast.newSimpleName(Signature.toString(typeSig)));
+			case Signature.WILDCARD_TYPE_SIGNATURE:
+				WildcardType wildcardType= ast.newWildcardType();
+				char ch= typeSig.charAt(0);
+				if (ch != Signature.C_STAR) {
+					Type bound= addImportFromSignature(typeSig.substring(1), ast, context);
+					wildcardType.setBound(bound, ch == Signature.C_EXTENDS);
+				}
+				return wildcardType;
+			case Signature.CAPTURE_TYPE_SIGNATURE:
+				return addImportFromSignature(typeSig.substring(1), ast, context);
+			default:
+				throw new IllegalArgumentException("Unknown type signature kind: " + typeSig); //$NON-NLS-1$
+		}
+	}
+
+
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a type reference that can be used
+	 * in the code. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding the signature of the type to be added.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public String addImport(ITypeBinding binding) {
+		return addImport(binding, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a type reference that can be used
+	 * in the code. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding the signature of the type to be added.
+	 * @param context an optional context that knows about types visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public String addImport(ITypeBinding binding, ImportRewriteContext context) {
+		if (binding.isPrimitive() || binding.isTypeVariable() || binding.isRecovered()) {
+			return binding.getName();
+		}
+
+		ITypeBinding normalizedBinding= normalizeTypeBinding(binding);
+		if (normalizedBinding == null) {
+			return "invalid"; //$NON-NLS-1$
+		}
+		if (normalizedBinding.isWildcardType()) {
+			StringBuffer res= new StringBuffer("?"); //$NON-NLS-1$
+			ITypeBinding bound= normalizedBinding.getBound();
+			if (bound != null && !bound.isWildcardType() && !bound.isCapture()) { // bug 95942
+				if (normalizedBinding.isUpperbound()) {
+					res.append(" extends "); //$NON-NLS-1$
+				} else {
+					res.append(" super "); //$NON-NLS-1$
+				}
+				res.append(addImport(bound, context));
+			}
+			return res.toString();
+		}
+
+		if (normalizedBinding.isArray()) {
+			StringBuffer res= new StringBuffer(addImport(normalizedBinding.getElementType(), context));
+			for (int i= normalizedBinding.getDimensions(); i > 0; i--) {
+				res.append("[]"); //$NON-NLS-1$
+			}
+			return res.toString();
+		}
+
+		String qualifiedName= getRawQualifiedName(normalizedBinding);
+		if (qualifiedName.length() > 0) {
+			String str= internalAddImport(qualifiedName, context);
+
+			ITypeBinding[] typeArguments= normalizedBinding.getTypeArguments();
+			if (typeArguments.length > 0) {
+				StringBuffer res= new StringBuffer(str);
+				res.append('<');
+				for (int i= 0; i < typeArguments.length; i++) {
+					if (i > 0) {
+						res.append(',');
+					}
+					ITypeBinding curr= typeArguments[i];
+					if (containsNestedCapture(curr, false)) { // see bug 103044
+						res.append('?');
+					} else {
+						res.append(addImport(curr, context));
+					}
+				}
+				res.append('>');
+				return res.toString();
+			}
+			return str;
+		}
+		return getRawName(normalizedBinding);
+	}
+
+	private boolean containsNestedCapture(ITypeBinding binding, boolean isNested) {
+		if (binding == null || binding.isPrimitive() || binding.isTypeVariable()) {
+			return false;
+		}
+		if (binding.isCapture()) {
+			if (isNested) {
+				return true;
+			}
+			return containsNestedCapture(binding.getWildcard(), true);
+		}
+		if (binding.isWildcardType()) {
+			return containsNestedCapture(binding.getBound(), true);
+		}
+		if (binding.isArray()) {
+			return containsNestedCapture(binding.getElementType(), true);
+		}
+		ITypeBinding[] typeArguments= binding.getTypeArguments();
+		for (int i= 0; i < typeArguments.length; i++) {
+			if (containsNestedCapture(typeArguments[i], true)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean containsNestedCapture(String signature) {
+		return signature.length() > 1 && signature.indexOf(Signature.C_CAPTURE, 1) != -1;
+	}
+
+	private static ITypeBinding normalizeTypeBinding(ITypeBinding binding) {
+		if (binding != null && !binding.isNullType() && !"void".equals(binding.getName())) { //$NON-NLS-1$
+			if (binding.isAnonymous()) {
+				ITypeBinding[] baseBindings= binding.getInterfaces();
+				if (baseBindings.length > 0) {
+					return baseBindings[0];
+				}
+				return binding.getSuperclass();
+			}
+			if (binding.isCapture()) {
+				return binding.getWildcard();
+			}
+			return binding;
+		}
+		return null;
+	}
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a {@link Type} that can be used
+	 * in the code. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding the signature of the type to be added.
+	 * @param ast the AST to create the returned type for.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public Type addImport(ITypeBinding binding, AST ast) {
+		return addImport(binding, ast, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a {@link Type} that can be used
+	 * in the code. The type binding can be an array binding, type variable or wildcard.
+	 * If the binding is a generic type, the type parameters are ignored. For parameterized types, also the type
+	 * arguments are processed and imports added if necessary. Anonymous types inside type arguments are normalized to their base type, wildcard
+	 * of wildcards are ignored.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding the signature of the type to be added.
+	 * @param ast the AST to create the returned type for.
+	 * @param context an optional context that knows about types visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public Type addImport(ITypeBinding binding, AST ast, ImportRewriteContext context) {
+		if (binding.isPrimitive()) {
+			return ast.newPrimitiveType(PrimitiveType.toCode(binding.getName()));
+		}
+
+		ITypeBinding normalizedBinding= normalizeTypeBinding(binding);
+		if (normalizedBinding == null) {
+			return ast.newSimpleType(ast.newSimpleName("invalid")); //$NON-NLS-1$
+		}
+
+		if (normalizedBinding.isTypeVariable()) {
+			// no import
+			return ast.newSimpleType(ast.newSimpleName(binding.getName()));
+		}
+		if (normalizedBinding.isWildcardType()) {
+			WildcardType wcType= ast.newWildcardType();
+			ITypeBinding bound= normalizedBinding.getBound();
+			if (bound != null && !bound.isWildcardType() && !bound.isCapture()) { // bug 96942
+				Type boundType= addImport(bound, ast, context);
+				wcType.setBound(boundType, normalizedBinding.isUpperbound());
+			}
+			return wcType;
+		}
+
+		if (normalizedBinding.isArray()) {
+			Type elementType= addImport(normalizedBinding.getElementType(), ast, context);
+			return ast.newArrayType(elementType, normalizedBinding.getDimensions());
+		}
+
+		String qualifiedName= getRawQualifiedName(normalizedBinding);
+		if (qualifiedName.length() > 0) {
+			String res= internalAddImport(qualifiedName, context);
+
+			ITypeBinding[] typeArguments= normalizedBinding.getTypeArguments();
+			if (typeArguments.length > 0) {
+				Type erasureType= ast.newSimpleType(ast.newName(res));
+				ParameterizedType paramType= ast.newParameterizedType(erasureType);
+				List arguments= paramType.typeArguments();
+				for (int i= 0; i < typeArguments.length; i++) {
+					ITypeBinding curr= typeArguments[i];
+					if (containsNestedCapture(curr, false)) { // see bug 103044
+						arguments.add(ast.newWildcardType());
+					} else {
+						arguments.add(addImport(curr, ast, context));
+					}
+				}
+				return paramType;
+			}
+			return ast.newSimpleType(ast.newName(res));
+		}
+		return ast.newSimpleType(ast.newName(getRawName(normalizedBinding)));
+	}
+
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a type reference that can be used
+	 * in the code. The type binding can only be an array or non-generic type.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param qualifiedTypeName the qualified type name of the type to be added
+	 * @param context an optional context that knows about types visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public String addImport(String qualifiedTypeName, ImportRewriteContext context) {
+		int angleBracketOffset= qualifiedTypeName.indexOf('<');
+		if (angleBracketOffset != -1) {
+			return internalAddImport(qualifiedTypeName.substring(0, angleBracketOffset), context) + qualifiedTypeName.substring(angleBracketOffset);
+		}
+		int bracketOffset= qualifiedTypeName.indexOf('[');
+		if (bracketOffset != -1) {
+			return internalAddImport(qualifiedTypeName.substring(0, bracketOffset), context) + qualifiedTypeName.substring(bracketOffset);
+		}
+		return internalAddImport(qualifiedTypeName, context);
+	}
+
+	/**
+	 * Adds a new import to the rewriter's record and returns a type reference that can be used
+	 * in the code. The type binding can only be an array or non-generic type.
+	 * 	<p>
+ 	 * No imports are added for types that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param qualifiedTypeName the qualified type name of the type to be added
+	 * @return returns a type to which the type binding can be assigned to. The returned type contains is unqualified
+	 * when an import could be added or was already known. It is fully qualified, if an import conflict prevented the import.
+	 */
+	public String addImport(String qualifiedTypeName) {
+		return addImport(qualifiedTypeName, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new static import to the rewriter's record and returns a reference that can be used in the code. The reference will
+	 * be fully qualified if an import conflict prevented the import or unqualified if the import succeeded or was already
+	 * existing.
+	 * 	<p>
+ 	 * No imports are added for members that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding The binding of the static field or method to be added.
+	 * @return returns either the simple member name if the import was successful or else the qualified name if
+	 * an import conflict prevented the import.
+	 * @throws IllegalArgumentException an {@link IllegalArgumentException} is thrown if the binding is not a static field
+	 * or method.
+	 */
+	public String addStaticImport(IBinding binding) {
+		return addStaticImport(binding, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new static import to the rewriter's record and returns a reference that can be used in the code. The reference will
+	 * be fully qualified if an import conflict prevented the import or unqualified if the import succeeded or was already
+	 * existing.
+	 * 	<p>
+ 	 * No imports are added for members that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param binding The binding of the static field or method to be added.
+	 * @param context an optional context that knows about members visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns either the simple member name if the import was successful or else the qualified name if
+	 * an import conflict prevented the import.
+	 * @throws IllegalArgumentException an {@link IllegalArgumentException} is thrown if the binding is not a static field
+	 * or method.
+	 */
+	public String addStaticImport(IBinding binding, ImportRewriteContext context) {
+		if (Modifier.isStatic(binding.getModifiers())) {
+			if (binding instanceof IVariableBinding) {
+				IVariableBinding variableBinding= (IVariableBinding) binding;
+				if (variableBinding.isField()) {
+					ITypeBinding declaringType= variableBinding.getDeclaringClass();
+					return addStaticImport(getRawQualifiedName(declaringType), binding.getName(), true, context);
+				}
+			} else if (binding instanceof IMethodBinding) {
+				ITypeBinding declaringType= ((IMethodBinding) binding).getDeclaringClass();
+				return addStaticImport(getRawQualifiedName(declaringType), binding.getName(), false, context);
+			}
+		}
+		throw new IllegalArgumentException("Binding must be a static field or method."); //$NON-NLS-1$
+	}
+
+	/**
+	 * Adds a new static import to the rewriter's record and returns a reference that can be used in the code. The reference will
+	 * be fully qualified if an import conflict prevented the import or unqualified if the import succeeded or was already
+	 * existing.
+	 * 	<p>
+ 	 * No imports are added for members that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param declaringTypeName The qualified name of the static's member declaring type
+	 * @param simpleName the simple name of the member; either a field or a method name.
+	 * @param isField <code>true</code> specifies that the member is a field, <code>false</code> if it is a
+	 * method.
+	 * @return returns either the simple member name if the import was successful or else the qualified name if
+	 * an import conflict prevented the import.
+	 */
+	public String addStaticImport(String declaringTypeName, String simpleName, boolean isField) {
+		return addStaticImport(declaringTypeName, simpleName, isField, this.defaultContext);
+	}
+
+	/**
+	 * Adds a new static import to the rewriter's record and returns a reference that can be used in the code. The reference will
+	 * be fully qualified if an import conflict prevented the import or unqualified if the import succeeded or was already
+	 * existing.
+	 * 	<p>
+ 	 * No imports are added for members that are already known. If a import for a type is recorded to be removed, this record is discarded instead.
+	 * </p>
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been added.
+	 * </p>
+	 * @param declaringTypeName The qualified name of the static's member declaring type
+	 * @param simpleName the simple name of the member; either a field or a method name.
+	 * @param isField <code>true</code> specifies that the member is a field, <code>false</code> if it is a
+	 * method.
+	 * @param context an optional context that knows about members visible in the current scope or <code>null</code>
+	 * to use the default context only using the available imports.
+	 * @return returns either the simple member name if the import was successful or else the qualified name if
+	 * an import conflict prevented the import.
+	 */
+	public String addStaticImport(String declaringTypeName, String simpleName, boolean isField, ImportRewriteContext context) {
+		String key = declaringTypeName + '.' + simpleName;
+		if (declaringTypeName.indexOf('.') == -1) {
+			return key;
+		}
+		if (context == null) {
+			context= this.defaultContext;
+		}
+		int kind= isField ? ImportRewriteContext.KIND_STATIC_FIELD : ImportRewriteContext.KIND_STATIC_METHOD;
+		this.importsKindMap.put(key, new Integer(kind));
+		int res= context.findInContext(declaringTypeName, simpleName, kind);
+		if (res == ImportRewriteContext.RES_NAME_CONFLICT) {
+			return key;
+		}
+		if (res == ImportRewriteContext.RES_NAME_UNKNOWN) {
+			addEntry(STATIC_PREFIX + key);
+		}
+		return simpleName;
+	}
+
+	private String internalAddImport(String fullTypeName, ImportRewriteContext context) {
+		int idx= fullTypeName.lastIndexOf('.');
+		String typeContainerName, typeName;
+		if (idx != -1) {
+			typeContainerName= fullTypeName.substring(0, idx);
+			typeName= fullTypeName.substring(idx + 1);
+		} else {
+			typeContainerName= ""; //$NON-NLS-1$
+			typeName= fullTypeName;
+		}
+
+		if (typeContainerName.length() == 0 && PrimitiveType.toCode(typeName) != null) {
+			return fullTypeName;
+		}
+
+		if (context == null)
+			context= this.defaultContext;
+
+		int res= context.findInContext(typeContainerName, typeName, ImportRewriteContext.KIND_TYPE);
+		if (res == ImportRewriteContext.RES_NAME_CONFLICT) {
+			return fullTypeName;
+		}
+		if (res == ImportRewriteContext.RES_NAME_UNKNOWN) {
+			addEntry(NORMAL_PREFIX + fullTypeName);
+		}
+		return typeName;
+	}
+
+	private void addEntry(String entry) {
+		this.existingImports.add(entry);
+
+		if (this.removedImports != null) {
+			if (this.removedImports.remove(entry)) {
+				return;
+			}
+		}
+
+		if (this.addedImports == null) {
+			this.addedImports= new ArrayList();
+		}
+		this.addedImports.add(entry);
+	}
+
+	private boolean removeEntry(String entry) {
+		if (this.existingImports.remove(entry)) {
+			if (this.addedImports != null) {
+				if (this.addedImports.remove(entry)) {
+					return true;
+				}
+			}
+			if (this.removedImports == null) {
+				this.removedImports= new ArrayList();
+			}
+			this.removedImports.add(entry);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Records to remove a import. No remove is recorded if no such import exists or if such an import is recorded
+	 * to be added. In that case the record of the addition is discarded.
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that an import has been removed.
+	 * </p>
+	 * @param qualifiedName The import name to remove.
+	 * @return <code>true</code> is returned of an import of the given name could be found.
+	 */
+	public boolean removeImport(String qualifiedName) {
+		return removeEntry(NORMAL_PREFIX + qualifiedName);
+	}
+
+	/**
+	 * Records to remove a static import. No remove is recorded if no such import exists or if such an import is recorded
+	 * to be added. In that case the record of the addition is discarded.
+	 * <p>
+	 * The content of the compilation unit itself is actually not modified
+	 * in any way by this method; rather, the rewriter just records that a new import has been removed.
+	 * </p>
+	 * @param qualifiedName The import name to remove.
+	 * @return <code>true</code> is returned of an import of the given name could be found.
+	 */
+	public boolean removeStaticImport(String qualifiedName) {
+		return removeEntry(STATIC_PREFIX + qualifiedName);
+	}
+
+	private static String getRawName(ITypeBinding normalizedBinding) {
+		return normalizedBinding.getTypeDeclaration().getName();
+	}
+
+	private static String getRawQualifiedName(ITypeBinding normalizedBinding) {
+		return normalizedBinding.getTypeDeclaration().getQualifiedName();
+	}
+
+
+	/**
+	 * Converts all modifications recorded by this rewriter into an object representing the corresponding text
+	 * edits to the source code of the rewrite's compilation unit. The compilation unit itself is not modified.
+	 * <p>
+	 * Calling this methods does not discard the modifications on record. Subsequence modifications are added
+	 * to the ones already on record. If this method is called again later, the resulting text edit object will accurately
+	 * reflect the net cumulative effect of all those changes.
+	 * </p>
+	 * @param monitor the progress monitor or <code>null</code>
+	 * @return text edit object describing the changes to the document corresponding to the changes
+	 * recorded by this rewriter
+	 * @throws CoreException the exception is thrown if the rewrite fails.
+	 */
+	public final TextEdit rewriteImports(IProgressMonitor monitor) throws CoreException {
+		if (monitor == null) {
+			monitor= new NullProgressMonitor();
+		}
+
+		try {
+			monitor.beginTask(Messages.bind(Messages.importRewrite_processDescription), 2);
+			if (!hasRecordedChanges()) {
+				this.createdImports= CharOperation.NO_STRINGS;
+				this.createdStaticImports= CharOperation.NO_STRINGS;
+				return new MultiTextEdit();
+			}
+
+			CompilationUnit usedAstRoot= this.astRoot;
+			if (usedAstRoot == null) {
+				ASTParser parser= ASTParser.newParser(AST.JLS8);
+				parser.setSource(this.compilationUnit);
+				parser.setFocalPosition(0); // reduced AST
+				parser.setResolveBindings(false);
+				usedAstRoot= (CompilationUnit) parser.createAST(new SubProgressMonitor(monitor, 1));
+			}
+
+			ImportRewriteAnalyzer computer=
+				new ImportRewriteAnalyzer(
+						this.compilationUnit,
+						usedAstRoot,
+						this.importOrder,
+						this.importOnDemandThreshold,
+						this.staticImportOnDemandThreshold,
+						this.restoreExistingImports,
+						this.useContextToFilterImplicitImports);
+			computer.setFilterImplicitImports(this.filterImplicitImports);
+
+			if (this.addedImports != null) {
+				for (int i= 0; i < this.addedImports.size(); i++) {
+					String curr= (String) this.addedImports.get(i);
+					computer.addImport(curr.substring(1), STATIC_PREFIX == curr.charAt(0), usedAstRoot, this.restoreExistingImports);
+				}
+			}
+
+			if (this.removedImports != null) {
+				for (int i= 0; i < this.removedImports.size(); i++) {
+					String curr= (String) this.removedImports.get(i);
+					computer.removeImport(curr.substring(1), STATIC_PREFIX == curr.charAt(0));
+				}
+			}
+
+			TextEdit result= computer.getResultingEdits(new SubProgressMonitor(monitor, 1));
+			this.createdImports= computer.getCreatedImports();
+			this.createdStaticImports= computer.getCreatedStaticImports();
+			return result;
+		} finally {
+			monitor.done();
+		}
+	}
+
+	/**
+	 * Returns all new non-static imports created by the last invocation of {@link #rewriteImports(IProgressMonitor)}
+	 * or <code>null</code> if these methods have not been called yet.
+	 * <p>
+	 * 	Note that this list doesn't need to be the same as the added imports (see {@link #getAddedImports()}) as
+	 * implicit imports are not created and some imports are represented by on-demand imports instead.
+	 * </p>
+	 * @return the created imports
+	 */
+	public String[] getCreatedImports() {
+		return this.createdImports;
+	}
+
+	/**
+	 * Returns all new static imports created by the last invocation of {@link #rewriteImports(IProgressMonitor)}
+	 * or <code>null</code> if these methods have not been called yet.
+	 * <p>
+	 * Note that this list doesn't need to be the same as the added static imports ({@link #getAddedStaticImports()}) as
+	 * implicit imports are not created and some imports are represented by on-demand imports instead.
+	 * </p
+	 * @return the created imports
+	 */
+	public String[] getCreatedStaticImports() {
+		return this.createdStaticImports;
+	}
+
+	/**
+	 * Returns all non-static imports that are recorded to be added.
+	 *
+	 * @return the imports recorded to be added.
+	 */
+	public String[] getAddedImports() {
+		return filterFromList(this.addedImports, NORMAL_PREFIX);
+	}
+
+	/**
+	 * Returns all static imports that are recorded to be added.
+	 *
+	 * @return the static imports recorded to be added.
+	 */
+	public String[] getAddedStaticImports() {
+		return filterFromList(this.addedImports, STATIC_PREFIX);
+	}
+
+	/**
+	 * Returns all non-static imports that are recorded to be removed.
+	 *
+	 * @return the imports recorded to be removed.
+	 */
+	public String[] getRemovedImports() {
+		return filterFromList(this.removedImports, NORMAL_PREFIX);
+	}
+
+	/**
+	 * Returns all static imports that are recorded to be removed.
+	 *
+	 * @return the static imports recorded to be removed.
+	 */
+	public String[] getRemovedStaticImports() {
+		return filterFromList(this.removedImports, STATIC_PREFIX);
+	}
+
+	/**
+	 * Returns <code>true</code> if imports have been recorded to be added or removed.
+	 * @return boolean returns if any changes to imports have been recorded.
+	 */
+	public boolean hasRecordedChanges() {
+		return !this.restoreExistingImports ||
+			(this.addedImports != null && !this.addedImports.isEmpty()) ||
+			(this.removedImports != null && !this.removedImports.isEmpty());
+	}
+
+
+	private static String[] filterFromList(List imports, char prefix) {
+		if (imports == null) {
+			return CharOperation.NO_STRINGS;
+		}
+		ArrayList res= new ArrayList();
+		for (int i= 0; i < imports.size(); i++) {
+			String curr= (String) imports.get(i);
+			if (prefix == curr.charAt(0)) {
+				res.add(curr.substring(1));
+			}
+		}
+		return (String[]) res.toArray(new String[res.size()]);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
new file mode 100644
index 0000000..fd70c13
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
@@ -0,0 +1,434 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+import org.eclipse.text.edits.TextEditGroup;
+
+/**
+ * For describing manipulations to a child list property of an AST node.
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ * @see ASTRewrite#getListRewrite(ASTNode, ChildListPropertyDescriptor)
+ * @since 3.0
+ */
+public final class ListRewrite {
+
+	private ASTNode parent;
+	private ChildListPropertyDescriptor childListProperty;
+	private ASTRewrite rewriter;
+
+
+	/* package*/ ListRewrite(ASTRewrite rewriter, ASTNode parent, ChildListPropertyDescriptor childProperty) {
+		this.rewriter= rewriter;
+		this.parent= parent;
+		this.childListProperty= childProperty;
+	}
+
+	private RewriteEventStore getRewriteStore() {
+		return this.rewriter.getRewriteEventStore();
+	}
+
+	private ListRewriteEvent getEvent() {
+		return getRewriteStore().getListEvent(this.parent, this.childListProperty, true);
+	}
+
+	/**
+	 * Returns the parent of the list for which this list rewriter was created.
+
+	 * @return the node that contains the list for which this list rewriter was created
+	 * @see #getLocationInParent()
+	 * @since 3.1
+	 */
+	public ASTNode getParent() {
+		return this.parent;
+	}
+
+	/**
+	 * Returns the property of the parent node for which this list rewriter was created.
+	 *
+	 * @return the property of the parent node for which this list rewriter was created
+	 * @see #getParent()
+	 * @since 3.1
+	 */
+	public StructuralPropertyDescriptor getLocationInParent() {
+		return this.childListProperty;
+	}
+
+	/**
+	 * Removes the given node from its parent's list property in the rewriter.
+	 * The node must be contained in the list.
+	 * The AST itself is not actually modified in any way; rather, the rewriter
+	 * just records a note that this node has been removed from this list.
+	 *
+	 * @param node the node being removed. The node can either be an original node in this list
+	 * or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not
+	 * part of this rewriter's AST, or if the described modification is invalid
+	 * (not a member of this node's original list)
+	 */
+	public void remove(ASTNode node, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		RewriteEvent event= getEvent().removeEntry(node);
+		if (editGroup != null) {
+			getRewriteStore().setEventEditGroup(event, editGroup);
+		}
+	}
+
+	/**
+	 * Returns the ASTRewrite instance from which this ListRewriter has been created from.
+	 * @return the parent AST Rewriter instance.
+	 * @since 3.1
+	 */
+	public ASTRewrite getASTRewrite() {
+		return this.rewriter;
+	}
+
+
+	/**
+	 * Replaces the given node from its parent's list property in the rewriter.
+	 * The node must be contained in the list.
+	 * The replacement node must either be brand new (not part of the original AST)
+	 * or a placeholder node (for example, one created by
+	 * {@link ASTRewrite#createCopyTarget(ASTNode)},
+	 * {@link ASTRewrite#createMoveTarget(ASTNode)},
+	 * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node has been replaced in this list.
+	 *
+	 * @param node the node being removed. The node can either be an original node in this list
+	 * or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
+	 * @param replacement the replacement node, or <code>null</code> if no
+	 * replacement
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not part
+	 * of this rewriter's AST, or if the replacement node is not a new node (or
+     * placeholder), or if the described modification is otherwise invalid
+     * (not a member of this node's original list)
+	 */
+	public void replace(ASTNode node, ASTNode replacement, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		validatePropertyType(node);
+		RewriteEvent event= getEvent().replaceEntry(node, replacement);
+		if (editGroup != null) {
+			getRewriteStore().setEventEditGroup(event, editGroup);
+		}
+	}
+
+	/**
+	 * Inserts the given node into the list after the given element.
+	 * The existing node <code>previousElement</code> must be in the list, either as an original or as a new
+	 * node that has been inserted.
+	 * The inserted node must either be brand new (not part of the original AST)
+	 * or a placeholder node (for example, one created by
+	 * {@link ASTRewrite#createCopyTarget(ASTNode)},
+	 * {@link ASTRewrite#createMoveTarget(ASTNode)},
+	 * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node has been inserted into the list.
+	 *
+	 * @param node the node to insert
+	 * @param previousElement the element after which the given node is to be inserted
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node or element is null,
+	 * or if the node is not part of this rewriter's AST, or if the inserted node
+	 * is not a new node (or placeholder), or if <code>previousElement</code> is not a member
+	 * of the list (original or new), or if the described modification is
+	 * otherwise invalid
+	 */
+	public void insertAfter(ASTNode node, ASTNode previousElement, TextEditGroup editGroup) {
+		if (node == null || previousElement == null) {
+			throw new IllegalArgumentException();
+		}
+		int index= getEvent().getIndex(previousElement, ListRewriteEvent.BOTH);
+		if (index == -1) {
+			throw new IllegalArgumentException("Node does not exist"); //$NON-NLS-1$
+		}
+		internalInsertAt(node, index + 1, true, editGroup);
+	}
+
+	/**
+	 * Inserts the given node into the list before the given element.
+	 * The existing node <code>nextElement</code> must be in the list, either as an original or as a new
+	 * node that has been inserted.
+	 * The inserted node must either be brand new (not part of the original AST)
+	 * or a placeholder node (for example, one created by
+	 * {@link ASTRewrite#createCopyTarget(ASTNode)},
+	 * {@link ASTRewrite#createMoveTarget(ASTNode)},
+	 * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node has been inserted into the list.
+	 *
+	 * @param node the node to insert
+	 * @param nextElement the element before which the given node is to be inserted
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node or next element is null,
+	 * or if the node is not part of this rewriter's AST, or if the inserted node
+	 * is not a new node (or placeholder), or if <code>nextElement</code> is not a member
+	 * of the list (original or new), or if the described modification is
+	 * otherwise invalid
+	 */
+	public void insertBefore(ASTNode node, ASTNode nextElement, TextEditGroup editGroup) {
+		if (node == null || nextElement == null) {
+			throw new IllegalArgumentException();
+		}
+		int index= getEvent().getIndex(nextElement, ListRewriteEvent.BOTH);
+		if (index == -1) {
+			throw new IllegalArgumentException("Node does not exist"); //$NON-NLS-1$
+		}
+		internalInsertAt(node, index, false, editGroup);
+	}
+
+	/**
+	 * Inserts the given node into the list at the start of the list.
+	 * Equivalent to <code>insertAt(node, 0, editGroup)</code>.
+	 *
+	 * @param node the node to insert
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not part
+	 * of this rewriter's AST, or if the inserted node is not a new node (or
+     * placeholder), or if the described modification is otherwise invalid
+     * (not a member of this node's original list)
+     * @see #insertAt(ASTNode, int, TextEditGroup)
+	 */
+	public void insertFirst(ASTNode node, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		internalInsertAt(node, 0, false, editGroup);
+	}
+
+	/**
+	 * Inserts the given node into the list at the end of the list.
+	 * Equivalent to <code>insertAt(node, -1, editGroup)</code>.
+	 *
+	 * @param node the node to insert
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not part
+	 * of this rewriter's AST, or if the inserted node is not a new node (or
+     * placeholder), or if the described modification is otherwise invalid
+     * (not a member of this node's original list)
+     * @see #insertAt(ASTNode, int, TextEditGroup)
+	 */
+	public void insertLast(ASTNode node, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		internalInsertAt(node, -1, true, editGroup);
+	}
+
+	/**
+	 * Inserts the given node into the list at the given index.
+	 * The index corresponds to a combined list of original and new nodes;
+	 * removed or replaced nodes are still in the combined list.
+	 * The inserted node must either be brand new (not part of the original AST)
+	 * or a placeholder node (for example, one created by
+	 * {@link ASTRewrite#createCopyTarget(ASTNode)},
+	 * {@link ASTRewrite#createMoveTarget(ASTNode)},
+	 * or {@link ASTRewrite#createStringPlaceholder(String, int)}). The AST itself
+     * is not actually modified in any way; rather, the rewriter just records
+     * a note that this node has been inserted into the list.
+	 *
+	 * @param node the node to insert
+	 * @param index insertion index in the combined list of original and
+	 * inserted nodes; <code>-1</code> indicates insertion as the last element
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits, or <code>null</code> if ungrouped
+	 * @throws IllegalArgumentException if the node is null, or if the node is not part
+	 * of this rewriter's AST, or if the inserted node is not a new node (or
+     * placeholder), or if the described modification is otherwise invalid
+     * (not a member of this node's original list)
+	 * @throws IndexOutOfBoundsException if the index is negative and not -1,
+	 * or if it is larger than the size of the combined list
+	 */
+	public void insertAt(ASTNode node, int index, TextEditGroup editGroup) {
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		internalInsertAt(node, index, isInsertBoundToPreviousByDefault(node), editGroup);
+	}
+
+	private void internalInsertAt(ASTNode node, int index, boolean boundToPrevious, TextEditGroup editGroup) {
+		validatePropertyType(node);
+		RewriteEvent event= getEvent().insert(node, index);
+		if (boundToPrevious) {
+			getRewriteStore().setInsertBoundToPrevious(node);
+		}
+		if (editGroup != null) {
+			getRewriteStore().setEventEditGroup(event, editGroup);
+		}
+	}
+
+	private void validatePropertyType(ASTNode node) {
+		if (!RewriteEventStore.DEBUG) {
+			return;
+		}
+		if (!this.childListProperty.getElementType().isAssignableFrom(node.getClass())) {
+			String message = node.getClass().getName() + " is not a valid type for " + this.childListProperty.getNodeClass().getName() //$NON-NLS-1$
+					+ " property '" + this.childListProperty.getId() + "'. Must be " + this.childListProperty.getElementType().getName(); //$NON-NLS-1$ //$NON-NLS-2$
+			throw new IllegalArgumentException(message);
+		}
+	}
+
+
+	private ASTNode createTargetNode(ASTNode first, ASTNode last, boolean isMove, ASTNode replacingNode, TextEditGroup editGroup) {
+		if (first == null || last == null) {
+			throw new IllegalArgumentException();
+		}
+
+		NodeInfoStore nodeStore= this.rewriter.getNodeStore();
+		ASTNode placeholder= nodeStore.newPlaceholderNode(first.getNodeType()); // revisit: could use list type
+		if (placeholder == null) {
+			throw new IllegalArgumentException("Creating a target node is not supported for nodes of type" + first.getClass().getName()); //$NON-NLS-1$
+		}
+
+		Block internalPlaceHolder= nodeStore.createCollapsePlaceholder();
+		CopySourceInfo info= getRewriteStore().createRangeCopy(this.parent, this.childListProperty, first, last, isMove, internalPlaceHolder, replacingNode, editGroup);
+		nodeStore.markAsCopyTarget(placeholder, info);
+
+		return placeholder;
+	}
+
+	/**
+	 * Creates and returns a placeholder node for a true copy of a range of nodes of the
+	 * current list.
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. When the document is rewritten, a copy of the source code
+	 * for the given node range is inserted into the output document at the position
+	 * corresponding to the placeholder (indentation is adjusted).
+	 *
+	 * @param first the node that starts the range
+	 * @param last the node that ends the range
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException An exception is thrown if the first or last node
+	 * are <code>null</code>, if a node is not a child of the current list or if the first node
+	 * is not before the last node. An <code>IllegalArgumentException</code> is
+	 * also thrown if the copied range is overlapping with an other moved or copied range.
+	 */
+	public final ASTNode createCopyTarget(ASTNode first, ASTNode last) {
+		if (first == last) {
+			return this.rewriter.createCopyTarget(first);
+		} else {
+			return createTargetNode(first, last, false, null, null);
+		}
+	}
+
+	/**
+	 * Creates and returns a placeholder node for a move of a range of nodes of the
+	 * current list.
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. When the document is rewritten, a copy of the source code
+	 * for the given node range is inserted into the output document at the position
+	 * corresponding to the placeholder (indentation is adjusted).
+	 *
+	 * @param first the node that starts the range
+	 * @param last the node that ends the range
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException An exception is thrown if the first or last node
+	 * are <code>null</code>, if a node is not a child of the current list or if the first node
+	 * is not before the last node. An <code>IllegalArgumentException</code> is
+	 * also thrown if the moved range is overlapping with an other moved or copied range.
+	 *
+	 * @since 3.1
+	 */
+	public final ASTNode createMoveTarget(ASTNode first, ASTNode last) {
+		return createMoveTarget(first, last, null, null);
+	}
+
+	/**
+	 * Creates and returns a placeholder node for a move of a range of nodes of the
+	 * current list. The moved nodes can optionally be replaced by a specified node.
+	 *
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. When the document is rewritten, a copy of the source code
+	 * for the given node range is inserted into the output document at the position
+	 * corresponding to the placeholder (indentation is adjusted).
+	 *
+	 * @param first the node that starts the range
+	 * @param last the node that ends the range
+	 * @param replacingNode a node that is set at the location of the moved nodes
+	 * or <code>null</code> to remove all nodes
+	 * @param editGroup the edit group in which to collect the corresponding
+	 * text edits fro a replace, or <code>null</code> if ungrouped
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException An exception is thrown if the first or
+	 * last node are <code>null</code>, if a node is not a child of the current list or
+	 * if the first node is not before the last node. An <code>IllegalArgumentException
+	 * </code> is also thrown if the moved range is overlapping with an other moved
+	 * or copied range.
+	 *
+	 * @since 3.1
+	 */
+	public final ASTNode createMoveTarget(ASTNode first, ASTNode last, ASTNode replacingNode, TextEditGroup editGroup) {
+		if (first == last) {
+			replace(first, replacingNode, editGroup);
+			return this.rewriter.createMoveTarget(first);
+		} else {
+			return createTargetNode(first, last, true, replacingNode, editGroup);
+		}
+	}
+
+	/*
+	 * Heuristic to decide if a inserted node is bound to previous or the next sibling.
+	 */
+	private boolean isInsertBoundToPreviousByDefault(ASTNode node) {
+		return (node instanceof Statement || node instanceof FieldDeclaration);
+	}
+
+	/**
+	 * Returns the original nodes in the list property managed by this
+	 * rewriter. The returned list is unmodifiable.
+	 *
+	 * @return a list of all original nodes in the list
+	 */
+	public List getOriginalList() {
+		List list= (List) getEvent().getOriginalValue();
+		return Collections.unmodifiableList(list);
+	}
+
+	/**
+	 * Returns the nodes in the revised list property managed by this
+	 * rewriter. The returned list is unmodifiable.
+	 *
+	 * @return a list of all nodes in the list taking into account
+	 * all the described changes
+	 */
+	public List getRewrittenList() {
+		List list= (List) getEvent().getNewValue();
+		return Collections.unmodifiableList(list);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
new file mode 100644
index 0000000..652fcfb
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+/**
+ * An object for computing adjusted source ranges for AST nodes
+ * that are being replaced or deleted.
+ * <p>
+ * For example, a refactoring like inline method may choose to replace
+ * calls to the method but leave intact any comments immediately preceding
+ * the calls. On the other hand, a refactoring like extract method may choose
+ * to extract not only the nodes for the selected code but also any
+ * comments preceding or following them.
+ * </p>
+ * <p>
+ * Clients should subclass if they need to influence the
+ * the source range to be affected when replacing or deleting a particular node.
+ * An instance of the subclass should be registered with
+ * {@link ASTRewrite#setTargetSourceRangeComputer(TargetSourceRangeComputer)}.
+ * During a call to {@link ASTRewrite#rewriteAST(org.eclipse.jface.text.IDocument, java.util.Map)},
+ * the {@link #computeSourceRange(ASTNode)} method on this object will be
+ * used to compute the source range for a node being deleted or replaced.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class TargetSourceRangeComputer {
+
+	/**
+	 * Reified source range. Instances are &quot;value&quot; object
+	 * (cannot be modified).
+	 *
+	 * @since 3.1
+	 */
+	public static final class SourceRange {
+		/**
+		 * 0-based character index, or <code>-1</code>
+		 * if no source position information is known.
+		 */
+		private int startPosition;
+
+		/**
+		 * (possibly 0) length, or <code>0</code>
+		 * if no source position information is known.
+		 */
+		private int length;
+
+		/**
+		 * Creates a new source range.
+		 *
+		 * @param startPosition the 0-based character index, or <code>-1</code>
+		 *    if no source position information is known
+		 * @param length the (possibly 0) length, or <code>0</code>
+		 *    if no source position information is known
+		 */
+		public SourceRange(int startPosition, int length) {
+			this.startPosition = startPosition;
+			this.length = length;
+		}
+
+		/**
+		 * Returns the start position.
+		 *
+		 * @return the 0-based character index, or <code>-1</code>
+		 *    if no source position information is known
+		 */
+		public int getStartPosition() {
+			return this.startPosition;
+		}
+
+		/**
+		 * Returns the source length.
+		 *
+		 * @return a (possibly 0) length, or <code>0</code>
+		 *    if no source position information is known
+		 */
+		public int getLength() {
+			return this.length;
+		}
+	}
+
+	/**
+	 * Creates a new target source range computer.
+	 */
+	public TargetSourceRangeComputer() {
+		// do nothing
+	}
+
+	/**
+	 * Returns the target source range of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 * <p>
+	 * The returned source ranges must satisfy the following conditions:
+	 * <dl>
+	 * <li>no two source ranges in an AST may be overlapping</li>
+	 * <li>a source range of a parent node must fully cover the source ranges of its children</li>
+	 * 	</dl>
+	 * 	</p>
+	 * <p>
+	 * The default implementation uses
+	 * {@link CompilationUnit#getExtendedStartPosition(ASTNode)}
+	 * and {@link CompilationUnit#getExtendedLength(ASTNode)}
+	 * to compute the target source range. Clients may override or
+	 * extend this method to expand or contract the source range of the
+	 * given node. The resulting source range must cover at least the
+	 * original source range of the node.
+	 * </p>
+	 *
+	 * @param node the node with a known source range in the compilation unit
+	 * being rewritten
+	 * @return the exact source range in the compilation unit being rewritten
+	 * that should be replaced (or deleted)
+	 */
+	public SourceRange computeSourceRange(ASTNode node) {
+		ASTNode root= node.getRoot();
+		if (root instanceof CompilationUnit) {
+			CompilationUnit cu= (CompilationUnit) root;
+			return new SourceRange(cu.getExtendedStartPosition(node), cu.getExtendedLength(node));
+		}
+		return new SourceRange(node.getStartPosition(), node.getLength());
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html
new file mode 100644
index 0000000..2f568ac
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html
@@ -0,0 +1,18 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+The Java DOM/AST rewrite is the set of classes that are used to make changes to an existing DOM/AST tree.
+
+<h2>
+Package Specification</h2>
+
+<p>This package contains the Java DOM/AST classes used to make changes to an existing DOM/AST tree.
+The principal classes are {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite ASTRewrite} and
+{@link org.eclipse.jdt.core.dom.rewrite.ListRewrite ListRewrite}.</p>
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
new file mode 100644
index 0000000..b735dea
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -0,0 +1,1947 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * Internal AST visitor for serializing an AST in a quick and dirty fashion.
+ * For various reasons the resulting string is not necessarily legal
+ * Java code; and even if it is legal Java code, it is not necessarily the string
+ * that corresponds to the given AST. Although useless for most purposes, it's
+ * fine for generating debug print strings.
+ * <p>
+ * Example usage:
+ * <code>
+ * <pre>
+ *    NaiveASTFlattener p = new NaiveASTFlattener();
+ *    node.accept(p);
+ *    String result = p.getResult();
+ * </pre>
+ * </code>
+ * Call the <code>reset</code> method to clear the previous result before reusing an
+ * existing instance.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class NaiveASTFlattener extends ASTVisitor {
+	/**
+	 * Internal synonym for {@link AST#JLS2}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private static final int JLS2 = AST.JLS2;
+	
+	/**
+	 * Internal synonym for {@link AST#JLS3}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private static final int JLS3 = AST.JLS3;
+
+	/**
+	 * Internal synonym for {@link AST#JLS4}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static final int JLS4 = AST.JLS4;
+
+	/**
+	 * The string buffer into which the serialized representation of the AST is
+	 * written.
+	 */
+	protected StringBuffer buffer;
+
+	private int indent = 0;
+
+	/**
+	 * Creates a new AST printer.
+	 */
+	public NaiveASTFlattener() {
+		this.buffer = new StringBuffer();
+	}
+
+	/**
+	 * Internal synonym for {@link ClassInstanceCreation#getName()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private Name getName(ClassInstanceCreation node) {
+		return node.getName();
+	}
+
+	/**
+	 * Returns the string accumulated in the visit.
+	 *
+	 * @return the serialized
+	 */
+	public String getResult() {
+		return this.buffer.toString();
+	}
+
+	/**
+	 * Internal synonym for {@link MethodDeclaration#getReturnType()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private static Type getReturnType(MethodDeclaration node) {
+		return node.getReturnType();
+	}
+
+	/**
+	 * Internal synonym for {@link TypeDeclaration#getSuperclass()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private static Name getSuperclass(TypeDeclaration node) {
+		return node.getSuperclass();
+	}
+
+	/**
+	 * Internal synonym for {@link TypeDeclarationStatement#getTypeDeclaration()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private static TypeDeclaration getTypeDeclaration(TypeDeclarationStatement node) {
+		return node.getTypeDeclaration();
+	}
+
+	/**
+	 * Internal synonym for {@link MethodDeclaration#thrownExceptions()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.9 BETA_JAVA8
+	 */
+	private static List thrownExceptions(MethodDeclaration node) {
+		return node.thrownExceptions();
+	}
+
+	void printIndent() {
+		for (int i = 0; i < this.indent; i++)
+			this.buffer.append("  "); //$NON-NLS-1$
+	}
+
+	/**
+	 * Appends the text representation of the given modifier flags, followed by a single space.
+	 * Used for JLS2 modifiers.
+	 *
+	 * @param modifiers the modifier flags
+	 */
+	void printModifiers(int modifiers) {
+		if (Modifier.isPublic(modifiers)) {
+			this.buffer.append("public ");//$NON-NLS-1$
+		}
+		if (Modifier.isProtected(modifiers)) {
+			this.buffer.append("protected ");//$NON-NLS-1$
+		}
+		if (Modifier.isPrivate(modifiers)) {
+			this.buffer.append("private ");//$NON-NLS-1$
+		}
+		if (Modifier.isStatic(modifiers)) {
+			this.buffer.append("static ");//$NON-NLS-1$
+		}
+		if (Modifier.isAbstract(modifiers)) {
+			this.buffer.append("abstract ");//$NON-NLS-1$
+		}
+		if (Modifier.isFinal(modifiers)) {
+			this.buffer.append("final ");//$NON-NLS-1$
+		}
+		if (Modifier.isSynchronized(modifiers)) {
+			this.buffer.append("synchronized ");//$NON-NLS-1$
+		}
+		if (Modifier.isVolatile(modifiers)) {
+			this.buffer.append("volatile ");//$NON-NLS-1$
+		}
+		if (Modifier.isNative(modifiers)) {
+			this.buffer.append("native ");//$NON-NLS-1$
+		}
+		if (Modifier.isStrictfp(modifiers)) {
+			this.buffer.append("strictfp ");//$NON-NLS-1$
+		}
+		if (Modifier.isTransient(modifiers)) {
+			this.buffer.append("transient ");//$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Appends the text representation of the given modifier flags, followed by a single space.
+	 * Used for 3.0 modifiers and annotations.
+	 *
+	 * @param ext the list of modifier and annotation nodes
+	 * (element type: <code>IExtendedModifiers</code>)
+	 */
+	void printModifiers(List ext) {
+		for (Iterator it = ext.iterator(); it.hasNext(); ) {
+			ASTNode p = (ASTNode) it.next();
+			p.accept(this);
+			this.buffer.append(" ");//$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * reference node helper function that is common to all
+	 * the difference reference nodes.
+	 * 
+	 * @param typeArguments list of type arguments 
+	 */
+	private void visitReferenceTypeArguments(List typeArguments) {
+		this.buffer.append("::");//$NON-NLS-1$
+		if (!typeArguments.isEmpty()) {
+			this.buffer.append('<');
+			for (Iterator it = typeArguments.iterator(); it.hasNext(); ) {
+				Type t = (Type) it.next();
+				t.accept(this);
+				if (it.hasNext()) {
+					this.buffer.append(',');
+				}
+			}
+			this.buffer.append('>');
+		}
+	}
+	
+	private void visitTypeAnnotations(AnnotatableType node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitAnnotationsList(node.annotations());
+		}
+	}
+
+	private void visitAnnotationsList(List annotations) {
+		for (Iterator it = annotations.iterator(); it.hasNext(); ) {
+			Annotation annotation = (Annotation) it.next();
+			annotation.accept(this);
+			this.buffer.append(' ');
+		}
+	}
+	
+	/**
+	 * Resets this printer so that it can be used again.
+	 */
+	public void reset() {
+		this.buffer.setLength(0);
+	}
+
+	/**
+	 * Internal synonym for {@link TypeDeclaration#superInterfaces()}. Use to alleviate
+	 * deprecation warnings.
+	 * @deprecated
+	 * @since 3.4
+	 */
+	private List superInterfaces(TypeDeclaration node) {
+		return node.superInterfaces();
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
+	 * @since 3.1
+	 */
+	public boolean visit(AnnotationTypeDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		printModifiers(node.modifiers());
+		this.buffer.append("@interface ");//$NON-NLS-1$
+		node.getName().accept(this);
+		this.buffer.append(" {");//$NON-NLS-1$
+		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
+			BodyDeclaration d = (BodyDeclaration) it.next();
+			d.accept(this);
+		}
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
+	 * @since 3.1
+	 */
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		printModifiers(node.modifiers());
+		node.getType().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		node.getName().accept(this);
+		this.buffer.append("()");//$NON-NLS-1$
+		if (node.getDefault() != null) {
+			this.buffer.append(" default ");//$NON-NLS-1$
+			node.getDefault().accept(this);
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
+	 */
+	public boolean visit(AnonymousClassDeclaration node) {
+		this.buffer.append("{\n");//$NON-NLS-1$
+		this.indent++;
+		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
+			BodyDeclaration b = (BodyDeclaration) it.next();
+			b.accept(this);
+		}
+		this.indent--;
+		printIndent();
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayAccess)
+	 */
+	public boolean visit(ArrayAccess node) {
+		node.getArray().accept(this);
+		this.buffer.append("[");//$NON-NLS-1$
+		node.getIndex().accept(this);
+		this.buffer.append("]");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayCreation)
+	 */
+	public boolean visit(ArrayCreation node) {
+		this.buffer.append("new ");//$NON-NLS-1$
+		ArrayType at = node.getType();
+		int dims = at.getDimensions();
+		Type elementType = at.getElementType();
+		elementType.accept(this);
+		for (Iterator it = node.dimensions().iterator(); it.hasNext(); ) {
+			this.buffer.append("[");//$NON-NLS-1$
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			this.buffer.append("]");//$NON-NLS-1$
+			dims--;
+		}
+		// add empty "[]" for each extra array dimension
+		for (int i= 0; i < dims; i++) {
+			this.buffer.append("[]");//$NON-NLS-1$
+		}
+		if (node.getInitializer() != null) {
+			node.getInitializer().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayInitializer)
+	 */
+	public boolean visit(ArrayInitializer node) {
+		this.buffer.append("{");//$NON-NLS-1$
+		for (Iterator it = node.expressions().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append("}");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayType)
+	 */
+	public boolean visit(ArrayType node) {
+		node.getComponentType().accept(this);
+		visitTypeAnnotations(node);
+		this.buffer.append("[]");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AssertStatement)
+	 */
+	public boolean visit(AssertStatement node) {
+		printIndent();
+		this.buffer.append("assert ");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		if (node.getMessage() != null) {
+			this.buffer.append(" : ");//$NON-NLS-1$
+			node.getMessage().accept(this);
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Assignment)
+	 */
+	public boolean visit(Assignment node) {
+		node.getLeftHandSide().accept(this);
+		this.buffer.append(node.getOperator().toString());
+		node.getRightHandSide().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Block)
+	 */
+	public boolean visit(Block node) {
+		this.buffer.append("{\n");//$NON-NLS-1$
+		this.indent++;
+		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
+			Statement s = (Statement) it.next();
+			s.accept(this);
+		}
+		this.indent--;
+		printIndent();
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(BlockComment)
+	 * @since 3.0
+	 */
+	public boolean visit(BlockComment node) {
+		printIndent();
+		this.buffer.append("/* */");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(BooleanLiteral)
+	 */
+	public boolean visit(BooleanLiteral node) {
+		if (node.booleanValue() == true) {
+			this.buffer.append("true");//$NON-NLS-1$
+		} else {
+			this.buffer.append("false");//$NON-NLS-1$
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(BreakStatement)
+	 */
+	public boolean visit(BreakStatement node) {
+		printIndent();
+		this.buffer.append("break");//$NON-NLS-1$
+		if (node.getLabel() != null) {
+			this.buffer.append(" ");//$NON-NLS-1$
+			node.getLabel().accept(this);
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CastExpression)
+	 */
+	public boolean visit(CastExpression node) {
+		this.buffer.append("(");//$NON-NLS-1$
+		node.getType().accept(this);
+		this.buffer.append(")");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CatchClause)
+	 */
+	public boolean visit(CatchClause node) {
+		this.buffer.append("catch (");//$NON-NLS-1$
+		node.getException().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CharacterLiteral)
+	 */
+	public boolean visit(CharacterLiteral node) {
+		this.buffer.append(node.getEscapedValue());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ClassInstanceCreation)
+	 */
+	public boolean visit(ClassInstanceCreation node) {
+		if (node.getExpression() != null) {
+			node.getExpression().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		this.buffer.append("new ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() == JLS2) {
+			getName(node).accept(this);
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeArguments().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+			node.getType().accept(this);
+		}
+		this.buffer.append("(");//$NON-NLS-1$
+		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		if (node.getAnonymousClassDeclaration() != null) {
+			node.getAnonymousClassDeclaration().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CompilationUnit)
+	 */
+	public boolean visit(CompilationUnit node) {
+		if (node.getPackage() != null) {
+			node.getPackage().accept(this);
+		}
+		for (Iterator it = node.imports().iterator(); it.hasNext(); ) {
+			ImportDeclaration d = (ImportDeclaration) it.next();
+			d.accept(this);
+		}
+		for (Iterator it = node.types().iterator(); it.hasNext(); ) {
+			AbstractTypeDeclaration d = (AbstractTypeDeclaration) it.next();
+			d.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ConditionalExpression)
+	 */
+	public boolean visit(ConditionalExpression node) {
+		node.getExpression().accept(this);
+		this.buffer.append(" ? ");//$NON-NLS-1$
+		node.getThenExpression().accept(this);
+		this.buffer.append(" : ");//$NON-NLS-1$
+		node.getElseExpression().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ConstructorInvocation)
+	 */
+	public boolean visit(ConstructorInvocation node) {
+		printIndent();
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeArguments().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append("this(");//$NON-NLS-1$
+		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(");\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ContinueStatement)
+	 */
+	public boolean visit(ContinueStatement node) {
+		printIndent();
+		this.buffer.append("continue");//$NON-NLS-1$
+		if (node.getLabel() != null) {
+			this.buffer.append(" ");//$NON-NLS-1$
+			node.getLabel().accept(this);
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+	
+	/*
+	 * @see ASTVisitor#visit(CreationReference)
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(CreationReference node) {
+		node.getType().accept(this);
+		visitReferenceTypeArguments(node.typeArguments());
+		this.buffer.append("new");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(DoStatement)
+	 */
+	public boolean visit(DoStatement node) {
+		printIndent();
+		this.buffer.append("do ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		this.buffer.append(" while (");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(");\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EmptyStatement)
+	 */
+	public boolean visit(EmptyStatement node) {
+		printIndent();
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnhancedForStatement)
+	 * @since 3.1
+	 */
+	public boolean visit(EnhancedForStatement node) {
+		printIndent();
+		this.buffer.append("for (");//$NON-NLS-1$
+		node.getParameter().accept(this);
+		this.buffer.append(" : ");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnumConstantDeclaration)
+	 * @since 3.1
+	 */
+	public boolean visit(EnumConstantDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		printModifiers(node.modifiers());
+		node.getName().accept(this);
+		if (!node.arguments().isEmpty()) {
+			this.buffer.append("(");//$NON-NLS-1$
+			for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+				Expression e = (Expression) it.next();
+				e.accept(this);
+				if (it.hasNext()) {
+					this.buffer.append(",");//$NON-NLS-1$
+				}
+			}
+			this.buffer.append(")");//$NON-NLS-1$
+		}
+		if (node.getAnonymousClassDeclaration() != null) {
+			node.getAnonymousClassDeclaration().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnumDeclaration)
+	 * @since 3.1
+	 */
+	public boolean visit(EnumDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		printModifiers(node.modifiers());
+		this.buffer.append("enum ");//$NON-NLS-1$
+		node.getName().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		if (!node.superInterfaceTypes().isEmpty()) {
+			this.buffer.append("implements ");//$NON-NLS-1$
+			for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
+				Type t = (Type) it.next();
+				t.accept(this);
+				if (it.hasNext()) {
+					this.buffer.append(", ");//$NON-NLS-1$
+				}
+			}
+			this.buffer.append(" ");//$NON-NLS-1$
+		}
+		this.buffer.append("{");//$NON-NLS-1$
+		for (Iterator it = node.enumConstants().iterator(); it.hasNext(); ) {
+			EnumConstantDeclaration d = (EnumConstantDeclaration) it.next();
+			d.accept(this);
+			// enum constant declarations do not include punctuation
+			if (it.hasNext()) {
+				// enum constant declarations are separated by commas
+				this.buffer.append(", ");//$NON-NLS-1$
+			}
+		}
+		if (!node.bodyDeclarations().isEmpty()) {
+			this.buffer.append("; ");//$NON-NLS-1$
+			for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
+				BodyDeclaration d = (BodyDeclaration) it.next();
+				d.accept(this);
+				// other body declarations include trailing punctuation
+			}
+		}
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ExpressionMethodReference)
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(ExpressionMethodReference node) {
+		node.getExpression().accept(this);
+		visitReferenceTypeArguments(node.typeArguments());
+		node.getName().accept(this);
+		return false;
+	}	
+
+	/*
+	 * @see ASTVisitor#visit(ExpressionStatement)
+	 */
+	public boolean visit(ExpressionStatement node) {
+		printIndent();
+		node.getExpression().accept(this);
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	public boolean visit(ExtraDimension node) {
+		this.buffer.append(" ");//$NON-NLS-1$
+		visitAnnotationsList(node.annotations());
+		this.buffer.append("[]"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(FieldAccess)
+	 */
+	public boolean visit(FieldAccess node) {
+		node.getExpression().accept(this);
+		this.buffer.append(".");//$NON-NLS-1$
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(FieldDeclaration)
+	 */
+	public boolean visit(FieldDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		node.getType().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
+			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
+			f.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(", ");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ForStatement)
+	 */
+	public boolean visit(ForStatement node) {
+		printIndent();
+		this.buffer.append("for (");//$NON-NLS-1$
+		for (Iterator it = node.initializers().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) this.buffer.append(", ");//$NON-NLS-1$
+		}
+		this.buffer.append("; ");//$NON-NLS-1$
+		if (node.getExpression() != null) {
+			node.getExpression().accept(this);
+		}
+		this.buffer.append("; ");//$NON-NLS-1$
+		for (Iterator it = node.updaters().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) this.buffer.append(", ");//$NON-NLS-1$
+		}
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(IfStatement)
+	 */
+	public boolean visit(IfStatement node) {
+		printIndent();
+		this.buffer.append("if (");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getThenStatement().accept(this);
+		if (node.getElseStatement() != null) {
+			this.buffer.append(" else ");//$NON-NLS-1$
+			node.getElseStatement().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ImportDeclaration)
+	 */
+	public boolean visit(ImportDeclaration node) {
+		printIndent();
+		this.buffer.append("import ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (node.isStatic()) {
+				this.buffer.append("static ");//$NON-NLS-1$
+			}
+		}
+		node.getName().accept(this);
+		if (node.isOnDemand()) {
+			this.buffer.append(".*");//$NON-NLS-1$
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(InfixExpression)
+	 */
+	public boolean visit(InfixExpression node) {
+		node.getLeftOperand().accept(this);
+		this.buffer.append(' ');  // for cases like x= i - -1; or x= i++ + ++i;
+		this.buffer.append(node.getOperator().toString());
+		this.buffer.append(' ');
+		node.getRightOperand().accept(this);
+		final List extendedOperands = node.extendedOperands();
+		if (extendedOperands.size() != 0) {
+			this.buffer.append(' ');
+			for (Iterator it = extendedOperands.iterator(); it.hasNext(); ) {
+				this.buffer.append(node.getOperator().toString()).append(' ');
+				Expression e = (Expression) it.next();
+				e.accept(this);
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Initializer)
+	 */
+	public boolean visit(Initializer node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(InstanceofExpression)
+	 */
+	public boolean visit(InstanceofExpression node) {
+		node.getLeftOperand().accept(this);
+		this.buffer.append(" instanceof ");//$NON-NLS-1$
+		node.getRightOperand().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(IntersectionType)
+	 * @since 3.7
+	 */
+	public boolean visit(IntersectionType node) {
+		for (Iterator it = node.types().iterator(); it.hasNext(); ) {
+			Type t = (Type) it.next();
+			t.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(" & "); //$NON-NLS-1$
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Javadoc)
+	 */
+	public boolean visit(Javadoc node) {
+		printIndent();
+		this.buffer.append("/** ");//$NON-NLS-1$
+		for (Iterator it = node.tags().iterator(); it.hasNext(); ) {
+			ASTNode e = (ASTNode) it.next();
+			e.accept(this);
+		}
+		this.buffer.append("\n */\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(LabeledStatement)
+	 */
+	public boolean visit(LabeledStatement node) {
+		printIndent();
+		node.getLabel().accept(this);
+		this.buffer.append(": ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(LambdaExpression)
+	 */
+	public boolean visit(LambdaExpression node) {
+		boolean hasParentheses = node.hasParentheses();
+		if (hasParentheses)
+			this.buffer.append('(');
+		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
+			VariableDeclaration v = (VariableDeclaration) it.next();
+			v.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		if (hasParentheses)
+			this.buffer.append(')');
+		this.buffer.append(" -> "); //$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(LineComment)
+	 * @since 3.0
+	 */
+	public boolean visit(LineComment node) {
+		this.buffer.append("//\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MarkerAnnotation)
+	 * @since 3.1
+	 */
+	public boolean visit(MarkerAnnotation node) {
+		this.buffer.append("@");//$NON-NLS-1$
+		node.getTypeName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MemberRef)
+	 * @since 3.0
+	 */
+	public boolean visit(MemberRef node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+		}
+		this.buffer.append("#");//$NON-NLS-1$
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MemberValuePair)
+	 * @since 3.1
+	 */
+	public boolean visit(MemberValuePair node) {
+		node.getName().accept(this);
+		this.buffer.append("=");//$NON-NLS-1$
+		node.getValue().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodDeclaration)
+	 */
+	public boolean visit(MethodDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		printIndent();
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+			if (!node.typeParameters().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
+					TypeParameter t = (TypeParameter) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		if (!node.isConstructor()) {
+			if (node.getAST().apiLevel() == JLS2) {
+				getReturnType(node).accept(this);
+			} else {
+				if (node.getReturnType2() != null) {
+					node.getReturnType2().accept(this);
+				} else {
+					// methods really ought to have a return type
+					this.buffer.append("void");//$NON-NLS-1$
+				}
+			}
+			this.buffer.append(" ");//$NON-NLS-1$
+		}
+		node.getName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			AnnotatableType receiverType = node.getReceiverType();
+			if (receiverType != null) {
+				receiverType.accept(this);
+				this.buffer.append(' ');
+				SimpleName qualifier = node.getReceiverQualifier();
+				if (qualifier != null) {
+					qualifier.accept(this);
+					this.buffer.append('.');
+				}
+				this.buffer.append("this"); //$NON-NLS-1$
+				if (node.parameters().size() > 0) {
+					this.buffer.append(',');
+				}
+			}
+		}
+		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
+			SingleVariableDeclaration v = (SingleVariableDeclaration) it.next();
+			v.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		int size = node.getExtraDimensions();
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			List dimensions = node.extraDimensions();
+			for (int i = 0; i < size; i++) {
+				visit((ExtraDimension) dimensions.get(i));
+			}
+		} else {
+			for (int i = 0; i < size; i++) {
+				this.buffer.append("[]"); //$NON-NLS-1$
+			}
+		}
+		if (node.getAST().apiLevel() < AST.JLS8) {
+			if (!thrownExceptions(node).isEmpty()) {
+				this.buffer.append(" throws ");//$NON-NLS-1$
+				for (Iterator it = thrownExceptions(node).iterator(); it.hasNext(); ) {
+					Name n = (Name) it.next();
+					n.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(", ");//$NON-NLS-1$
+					}
+				}				
+				this.buffer.append(" ");//$NON-NLS-1$
+			} 
+		} else {
+			if (!node.thrownExceptionTypes().isEmpty()) {				
+				this.buffer.append(" throws ");//$NON-NLS-1$
+				for (Iterator it = node.thrownExceptionTypes().iterator(); it.hasNext(); ) {
+					Type n = (Type) it.next();
+					n.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(", ");//$NON-NLS-1$
+					}
+				}	
+				this.buffer.append(" ");//$NON-NLS-1$				
+			}
+		}
+		if (node.getBody() == null) {
+			this.buffer.append(";\n");//$NON-NLS-1$
+		} else {
+			node.getBody().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodInvocation)
+	 */
+	public boolean visit(MethodInvocation node) {
+		if (node.getExpression() != null) {
+			node.getExpression().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeArguments().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		node.getName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodRef)
+	 * @since 3.0
+	 */
+	public boolean visit(MethodRef node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+		}
+		this.buffer.append("#");//$NON-NLS-1$
+		node.getName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		for (Iterator it = node.parameters().iterator(); it.hasNext(); ) {
+			MethodRefParameter e = (MethodRefParameter) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodRefParameter)
+	 * @since 3.0
+	 */
+	public boolean visit(MethodRefParameter node) {
+		node.getType().accept(this);
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (node.isVarargs()) {
+				this.buffer.append("...");//$NON-NLS-1$
+			}
+		}
+		if (node.getName() != null) {
+			this.buffer.append(" ");//$NON-NLS-1$
+			node.getName().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Modifier)
+	 * @since 3.1
+	 */
+	public boolean visit(Modifier node) {
+		this.buffer.append(node.getKeyword().toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NormalAnnotation)
+	 * @since 3.1
+	 */
+	public boolean visit(NormalAnnotation node) {
+		this.buffer.append("@");//$NON-NLS-1$
+		node.getTypeName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		for (Iterator it = node.values().iterator(); it.hasNext(); ) {
+			MemberValuePair p = (MemberValuePair) it.next();
+			p.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NullLiteral)
+	 */
+	public boolean visit(NullLiteral node) {
+		this.buffer.append("null");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NumberLiteral)
+	 */
+	public boolean visit(NumberLiteral node) {
+		this.buffer.append(node.getToken());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PackageDeclaration)
+	 */
+	public boolean visit(PackageDeclaration node) {
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (node.getJavadoc() != null) {
+				node.getJavadoc().accept(this);
+			}
+			for (Iterator it = node.annotations().iterator(); it.hasNext(); ) {
+				Annotation p = (Annotation) it.next();
+				p.accept(this);
+				this.buffer.append(" ");//$NON-NLS-1$
+			}
+		}
+		printIndent();
+		this.buffer.append("package ");//$NON-NLS-1$
+		node.getName().accept(this);
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PackageQualifiedType)
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(PackageQualifiedType node) {
+		node.getQualifier().accept(this);
+		this.buffer.append('.');
+		visitTypeAnnotations(node);
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ParameterizedType)
+	 * @since 3.1
+	 */
+	public boolean visit(ParameterizedType node) {
+		node.getType().accept(this);
+		this.buffer.append("<");//$NON-NLS-1$
+		for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+			Type t = (Type) it.next();
+			t.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(">");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ParenthesizedExpression)
+	 */
+	public boolean visit(ParenthesizedExpression node) {
+		this.buffer.append("(");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PostfixExpression)
+	 */
+	public boolean visit(PostfixExpression node) {
+		node.getOperand().accept(this);
+		this.buffer.append(node.getOperator().toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PrefixExpression)
+	 */
+	public boolean visit(PrefixExpression node) {
+		this.buffer.append(node.getOperator().toString());
+		node.getOperand().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PrimitiveType)
+	 */
+	public boolean visit(PrimitiveType node) {
+		visitTypeAnnotations(node);
+		this.buffer.append(node.getPrimitiveTypeCode().toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(QualifiedName)
+	 */
+	public boolean visit(QualifiedName node) {
+		node.getQualifier().accept(this);
+		this.buffer.append(".");//$NON-NLS-1$
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(QualifiedType)
+	 * @since 3.1
+	 */
+	public boolean visit(QualifiedType node) {
+		node.getQualifier().accept(this);
+		this.buffer.append(".");//$NON-NLS-1$
+		visitTypeAnnotations(node);
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ReturnStatement)
+	 */
+	public boolean visit(ReturnStatement node) {
+		printIndent();
+		this.buffer.append("return");//$NON-NLS-1$
+		if (node.getExpression() != null) {
+			this.buffer.append(" ");//$NON-NLS-1$
+			node.getExpression().accept(this);
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SimpleName)
+	 */
+	public boolean visit(SimpleName node) {
+		this.buffer.append(node.getIdentifier());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SimpleType)
+	 */
+	public boolean visit(SimpleType node) {
+		Name name = node.getName();
+		if (name.isQualifiedName()) {
+			QualifiedName qualifiedName = (QualifiedName) name;
+			qualifiedName.getQualifier().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+			visitTypeAnnotations(node);
+			qualifiedName.getName().accept(this);
+		} else {
+			visitTypeAnnotations(node);
+			node.getName().accept(this);			
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SingleMemberAnnotation)
+	 * @since 3.1
+	 */
+	public boolean visit(SingleMemberAnnotation node) {
+		this.buffer.append("@");//$NON-NLS-1$
+		node.getTypeName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		node.getValue().accept(this);
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SingleVariableDeclaration)
+	 */
+	public boolean visit(SingleVariableDeclaration node) {
+		printIndent();
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		node.getType().accept(this);
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (node.isVarargs()) {
+				if (node.getAST().apiLevel() >= AST.JLS8) {
+					List annotations = node.varargsAnnotations();
+					if (annotations.size() > 0) {
+						this.buffer.append(' ');
+					}
+					visitAnnotationsList(annotations);
+				}
+				this.buffer.append("...");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(" ");//$NON-NLS-1$
+		node.getName().accept(this);
+		int size = node.getExtraDimensions();
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			List dimensions = node.extraDimensions();
+			for (int i = 0; i < size; i++) {
+				visit((ExtraDimension) dimensions.get(i));
+			}
+		} else {
+			for (int i = 0; i < size; i++) {
+				this.buffer.append("[]"); //$NON-NLS-1$
+			}
+		}
+		if (node.getInitializer() != null) {
+			this.buffer.append("=");//$NON-NLS-1$
+			node.getInitializer().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(StringLiteral)
+	 */
+	public boolean visit(StringLiteral node) {
+		this.buffer.append(node.getEscapedValue());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperConstructorInvocation)
+	 */
+	public boolean visit(SuperConstructorInvocation node) {
+		printIndent();
+		if (node.getExpression() != null) {
+			node.getExpression().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeArguments().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append("super(");//$NON-NLS-1$
+		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(");\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperFieldAccess)
+	 */
+	public boolean visit(SuperFieldAccess node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		this.buffer.append("super.");//$NON-NLS-1$
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperMethodInvocation)
+	 */
+	public boolean visit(SuperMethodInvocation node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		this.buffer.append("super.");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeArguments().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeArguments().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		node.getName().accept(this);
+		this.buffer.append("(");//$NON-NLS-1$
+		for (Iterator it = node.arguments().iterator(); it.hasNext(); ) {
+			Expression e = (Expression) it.next();
+			e.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(",");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(")");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperMethodReference)
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(SuperMethodReference node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+			this.buffer.append('.');
+		}
+		this.buffer.append("super");//$NON-NLS-1$
+		visitReferenceTypeArguments(node.typeArguments());
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SwitchCase)
+	 */
+	public boolean visit(SwitchCase node) {
+		if (node.isDefault()) {
+			this.buffer.append("default :\n");//$NON-NLS-1$
+		} else {
+			this.buffer.append("case ");//$NON-NLS-1$
+			node.getExpression().accept(this);
+			this.buffer.append(":\n");//$NON-NLS-1$
+		}
+		this.indent++; //decremented in visit(SwitchStatement)
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SwitchStatement)
+	 */
+	public boolean visit(SwitchStatement node) {
+		this.buffer.append("switch (");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		this.buffer.append("{\n");//$NON-NLS-1$
+		this.indent++;
+		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
+			Statement s = (Statement) it.next();
+			s.accept(this);
+			this.indent--; // incremented in visit(SwitchCase)
+		}
+		this.indent--;
+		printIndent();
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SynchronizedStatement)
+	 */
+	public boolean visit(SynchronizedStatement node) {
+		this.buffer.append("synchronized (");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TagElement)
+	 * @since 3.0
+	 */
+	public boolean visit(TagElement node) {
+		if (node.isNested()) {
+			// nested tags are always enclosed in braces
+			this.buffer.append("{");//$NON-NLS-1$
+		} else {
+			// top-level tags always begin on a new line
+			this.buffer.append("\n * ");//$NON-NLS-1$
+		}
+		boolean previousRequiresWhiteSpace = false;
+		if (node.getTagName() != null) {
+			this.buffer.append(node.getTagName());
+			previousRequiresWhiteSpace = true;
+		}
+		boolean previousRequiresNewLine = false;
+		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
+			ASTNode e = (ASTNode) it.next();
+			// Name, MemberRef, MethodRef, and nested TagElement do not include white space.
+			// TextElements don't always include whitespace, see <https://bugs.eclipse.org/206518>.
+			boolean currentIncludesWhiteSpace = false;
+			if (e instanceof TextElement) {
+				String text = ((TextElement) e).getText();
+				if (text.length() > 0 && ScannerHelper.isWhitespace(text.charAt(0))) {
+					currentIncludesWhiteSpace = true; // workaround for https://bugs.eclipse.org/403735
+				}
+			}
+			if (previousRequiresNewLine && currentIncludesWhiteSpace) {
+				this.buffer.append("\n * ");//$NON-NLS-1$
+			}
+			previousRequiresNewLine = currentIncludesWhiteSpace;
+			// add space if required to separate
+			if (previousRequiresWhiteSpace && !currentIncludesWhiteSpace) {
+				this.buffer.append(" "); //$NON-NLS-1$
+			}
+			e.accept(this);
+			previousRequiresWhiteSpace = !currentIncludesWhiteSpace && !(e instanceof TagElement);
+		}
+		if (node.isNested()) {
+			this.buffer.append("}");//$NON-NLS-1$
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TextElement)
+	 * @since 3.0
+	 */
+	public boolean visit(TextElement node) {
+		this.buffer.append(node.getText());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ThisExpression)
+	 */
+	public boolean visit(ThisExpression node) {
+		if (node.getQualifier() != null) {
+			node.getQualifier().accept(this);
+			this.buffer.append(".");//$NON-NLS-1$
+		}
+		this.buffer.append("this");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ThrowStatement)
+	 */
+	public boolean visit(ThrowStatement node) {
+		printIndent();
+		this.buffer.append("throw ");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TryStatement)
+	 */
+	public boolean visit(TryStatement node) {
+		printIndent();
+		this.buffer.append("try ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS4) {
+			List resources = node.resources();
+			if (!resources.isEmpty()) {
+				this.buffer.append('(');
+				for (Iterator it = resources.iterator(); it.hasNext(); ) {
+					VariableDeclarationExpression variable = (VariableDeclarationExpression) it.next();
+					variable.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(';');
+					}
+				}
+				this.buffer.append(')');
+			}
+		}
+		node.getBody().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		for (Iterator it = node.catchClauses().iterator(); it.hasNext(); ) {
+			CatchClause cc = (CatchClause) it.next();
+			cc.accept(this);
+		}
+		if (node.getFinally() != null) {
+			this.buffer.append(" finally ");//$NON-NLS-1$
+			node.getFinally().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeDeclaration)
+	 */
+	public boolean visit(TypeDeclaration node) {
+		if (node.getJavadoc() != null) {
+			node.getJavadoc().accept(this);
+		}
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		this.buffer.append(node.isInterface() ? "interface " : "class ");//$NON-NLS-2$//$NON-NLS-1$
+		node.getName().accept(this);
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (!node.typeParameters().isEmpty()) {
+				this.buffer.append("<");//$NON-NLS-1$
+				for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
+					TypeParameter t = (TypeParameter) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(">");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(" ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() == JLS2) {
+			if (getSuperclass(node) != null) {
+				this.buffer.append("extends ");//$NON-NLS-1$
+				getSuperclass(node).accept(this);
+				this.buffer.append(" ");//$NON-NLS-1$
+			}
+			if (!superInterfaces(node).isEmpty()) {
+				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
+				for (Iterator it = superInterfaces(node).iterator(); it.hasNext(); ) {
+					Name n = (Name) it.next();
+					n.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(", ");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(" ");//$NON-NLS-1$
+			}
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			if (node.getSuperclassType() != null) {
+				this.buffer.append("extends ");//$NON-NLS-1$
+				node.getSuperclassType().accept(this);
+				this.buffer.append(" ");//$NON-NLS-1$
+			}
+			if (!node.superInterfaceTypes().isEmpty()) {
+				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
+				for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
+					Type t = (Type) it.next();
+					t.accept(this);
+					if (it.hasNext()) {
+						this.buffer.append(", ");//$NON-NLS-1$
+					}
+				}
+				this.buffer.append(" ");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append("{\n");//$NON-NLS-1$
+		this.indent++;
+		for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
+			BodyDeclaration d = (BodyDeclaration) it.next();
+			d.accept(this);
+		}
+		this.indent--;
+		printIndent();
+		this.buffer.append("}\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeDeclarationStatement)
+	 */
+	public boolean visit(TypeDeclarationStatement node) {
+		if (node.getAST().apiLevel() == JLS2) {
+			getTypeDeclaration(node).accept(this);
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			node.getDeclaration().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeLiteral)
+	 */
+	public boolean visit(TypeLiteral node) {
+		node.getType().accept(this);
+		this.buffer.append(".class");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeMethodReference)
+	 * 
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(TypeMethodReference node) {
+		node.getType().accept(this);
+		visitReferenceTypeArguments(node.typeArguments());
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeParameter)
+	 * @since 3.1
+	 */
+	public boolean visit(TypeParameter node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitAnnotationsList(node.annotations());
+		}
+		node.getName().accept(this);
+		if (!node.typeBounds().isEmpty()) {
+			this.buffer.append(" extends ");//$NON-NLS-1$
+			for (Iterator it = node.typeBounds().iterator(); it.hasNext(); ) {
+				Type t = (Type) it.next();
+				t.accept(this);
+				if (it.hasNext()) {
+					this.buffer.append(" & ");//$NON-NLS-1$
+				}
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(UnionType)
+	 * @since 3.7
+	 */
+	public boolean visit(UnionType node) {
+		for (Iterator it = node.types().iterator(); it.hasNext(); ) {
+			Type t = (Type) it.next();
+			t.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append('|');
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationExpression)
+	 */
+	public boolean visit(VariableDeclarationExpression node) {
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		node.getType().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
+			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
+			f.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(", ");//$NON-NLS-1$
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationFragment)
+	 */
+	public boolean visit(VariableDeclarationFragment node) {
+		node.getName().accept(this);
+		int size = node.getExtraDimensions();
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			List dimensions = node.extraDimensions();
+			for (int i = 0; i < size; i++) {
+				visit((ExtraDimension) dimensions.get(i));
+			}
+		} else {
+			for (int i = 0; i < size; i++) {
+				this.buffer.append("[]");//$NON-NLS-1$
+			}
+		}
+		if (node.getInitializer() != null) {
+			this.buffer.append("=");//$NON-NLS-1$
+			node.getInitializer().accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationStatement)
+	 */
+	public boolean visit(VariableDeclarationStatement node) {
+		printIndent();
+		if (node.getAST().apiLevel() == JLS2) {
+			printModifiers(node.getModifiers());
+		}
+		if (node.getAST().apiLevel() >= JLS3) {
+			printModifiers(node.modifiers());
+		}
+		node.getType().accept(this);
+		this.buffer.append(" ");//$NON-NLS-1$
+		for (Iterator it = node.fragments().iterator(); it.hasNext(); ) {
+			VariableDeclarationFragment f = (VariableDeclarationFragment) it.next();
+			f.accept(this);
+			if (it.hasNext()) {
+				this.buffer.append(", ");//$NON-NLS-1$
+			}
+		}
+		this.buffer.append(";\n");//$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(WhileStatement)
+	 */
+	public boolean visit(WhileStatement node) {
+		printIndent();
+		this.buffer.append("while (");//$NON-NLS-1$
+		node.getExpression().accept(this);
+		this.buffer.append(") ");//$NON-NLS-1$
+		node.getBody().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(WildcardType)
+	 * @since 3.1
+	 */
+	public boolean visit(WildcardType node) {
+		visitTypeAnnotations(node);
+		this.buffer.append("?");//$NON-NLS-1$
+		Type bound = node.getBound();
+		if (bound != null) {
+			if (node.isUpperBound()) {
+				this.buffer.append(" extends ");//$NON-NLS-1$
+			} else {
+				this.buffer.append(" super ");//$NON-NLS-1$
+			}
+			bound.accept(this);
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java
new file mode 100644
index 0000000..d261a12
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/SourceRangeVerifier.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.ArrayCreation;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+
+public class SourceRangeVerifier extends ASTVisitor {
+
+	public static boolean DEBUG = false;
+	public static boolean DEBUG_THROW = false;
+	
+	private StringBuffer bugs; 
+	
+	/**
+	 * Verifies proper node nesting as specified in {@link ASTParser#setKind(int)}:
+	 * <p>
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * </p>
+	 * 
+	 * @param node
+	 * @return <code>null</code> if everything is OK; a list of errors otherwise
+	 */
+	public String process(ASTNode node) {
+		StringBuffer buffer = new StringBuffer();
+		this.bugs = buffer;
+		node.accept(this);
+		this.bugs = null;
+		if (buffer.length() == 0)
+			return null;
+		return buffer.toString();
+	}
+	
+	public boolean preVisit2(ASTNode node) {
+		ASTNode previous = null;
+		
+		List properties = node.structuralPropertiesForType();
+		for (int i = 0; i < properties.size(); i++) {
+			StructuralPropertyDescriptor property = (StructuralPropertyDescriptor) properties.get(i);
+			if (property.isChildProperty()) {
+				ASTNode child = (ASTNode) node.getStructuralProperty(property);
+				if (child != null) {
+					boolean ok = checkChild(node, previous, child);
+					if (ok) {
+						previous = child;
+					} else {
+						return false;
+					}
+				}
+			} else if (property.isChildListProperty()) {
+				List children = (List) node.getStructuralProperty(property);
+				for (int j= 0; j < children.size(); j++) {
+					ASTNode child = (ASTNode) children.get(j);
+					boolean ok = checkChild(node, previous, child);
+					if (ok) {
+						previous = child;
+					} else {
+						return false;
+					}
+				}
+			}
+		}
+		return true;
+	}
+
+	private boolean checkChild(ASTNode parent, ASTNode previous, ASTNode child) {
+		if ((parent.getFlags() & (ASTNode.RECOVERED | ASTNode.MALFORMED)) != 0
+				|| (child.getFlags() & (ASTNode.RECOVERED | ASTNode.MALFORMED)) != 0)
+			return false; 
+		
+		int parentStart = parent.getStartPosition();
+		int parentEnd = parentStart + parent.getLength();
+		
+		int childStart = child.getStartPosition();
+		int childEnd = childStart + child.getLength();
+		
+		if (previous != null) {
+			// Turn a blind eye on a known problem ... see https://bugs.eclipse.org/391894#c4
+			if (child.getLocationInParent() == ArrayCreation.DIMENSIONS_PROPERTY)
+				return false;
+			
+			int previousStart = previous.getStartPosition();
+			int previousEnd = previousStart + previous.getLength();
+			if (childStart < previousEnd) {
+				String bug = "- parent [" + parentStart + ", " + parentEnd + "] " + parent.getClass().getName() + '\n' //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+						+ "   previous [" + previousStart + ", " + previousEnd + "] "  + previous.getClass().getName() + '\n'//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+						+ "   " + child.getLocationInParent().getId() + " [" + childStart + ", " + childEnd + "] " + child.getClass().getName() + '\n'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+				this.bugs.append(bug);
+			}
+		}
+		if (!(parentStart <= childStart && childEnd <= parentEnd)) {
+			String bug = "- parent [" + parentStart + ", " + parentEnd + "] " + parent.getClass().getName() + '\n' //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+					   + "   " + child.getLocationInParent().getId() + " [" + childStart + ", " + childEnd + "] " + child.getClass().getName() + '\n'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+			this.bugs.append(bug);
+		}
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
new file mode 100644
index 0000000..6cf44a9
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -0,0 +1,4141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer.SourceRange;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext;
+import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker;
+import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.Prefix;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.CopyPlaceholderData;
+import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore.StringPlaceholderData;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+import org.eclipse.text.edits.CopySourceEdit;
+import org.eclipse.text.edits.CopyTargetEdit;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MoveSourceEdit;
+import org.eclipse.text.edits.MoveTargetEdit;
+import org.eclipse.text.edits.RangeMarker;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+
+/**
+ * Infrastructure to support code modifications. Existing code must stay untouched, new code
+ * added with correct formatting, moved code left with the user's formatting / comments.
+ * Idea:
+ * - Get the AST for existing code
+ * - Describe changes
+ * - This visitor analyzes the changes or annotations and generates text edits
+ * (text manipulation API) that describe the required code changes.
+ */
+public final class ASTRewriteAnalyzer extends ASTVisitor {
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_FIELD_MODIFIERS_PROPERTY = FieldDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_INITIALIZER_MODIFIERS_PROPERTY3 = Initializer.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_METHOD_MODIFIERS_PROPERTY2 = MethodDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_METHOD_RETURN_TYPE_PROPERTY = MethodDeclaration.RETURN_TYPE_PROPERTY;
+	
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY = MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildListPropertyDescriptor INTERNAL_METHOD_THROWN_EXCEPTIONS_PROPERTY = MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_TYPE_MODIFIERS_PROPERTY = TypeDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_TYPE_SUPERCLASS_PROPERTY = TypeDeclaration.SUPERCLASS_PROPERTY;
+	
+	/** @deprecated using deprecated code */
+	private static final ChildListPropertyDescriptor INTERNAL_TYPE_SUPER_INTERFACES_PROPERTY = TypeDeclaration.SUPER_INTERFACES_PROPERTY;
+	
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_CIC_NAME_PROPERTY = ClassInstanceCreation.NAME_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY = VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_TDS_TYPE_DECLARATION_PROPERTY = TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VARIABLE_MODIFIERS_PROPERTY = SingleVariableDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY = SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VDE_MODIFIERS_PROPERTY = VariableDeclarationExpression.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VDS_MODIFIERS_PROPERTY = VariableDeclarationStatement.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final int JLS2_INTERNAL = AST.JLS2;
+	
+	/** @deprecated using deprecated code */
+	private static final int JLS3_INTERNAL = AST.JLS3;
+	
+	/** @deprecated using deprecated code */
+	private static final int JLS4_INTERNAL = AST.JLS4;
+
+
+	TextEdit currentEdit;
+	final RewriteEventStore eventStore; // used from inner classes
+
+	private TokenScanner tokenScanner; // shared scanner
+
+	private final Map sourceCopyInfoToEdit;
+	private final Stack sourceCopyEndNodes;
+
+	private final char[] content;
+	private final LineInformation lineInfo;
+	private final ASTRewriteFormatter formatter;
+	private final NodeInfoStore nodeInfos;
+	private final TargetSourceRangeComputer extendedSourceRangeComputer;
+	private final LineCommentEndOffsets lineCommentEndOffsets;
+	
+	private int beforeRequiredSpaceIndex = -1;
+	
+	Map options;
+	
+	private RecoveryScannerData recoveryScannerData;
+
+	/**
+	 * Constructor for ASTRewriteAnalyzer.
+	 * <p>The given options cannot be null.</p>
+	 * 
+	 * @param content the content of the compilation unit to rewrite.
+	 * @param lineInfo line information for the content of the compilation unit to rewrite.
+	 * @param rootEdit the edit to add all generated edits to
+	 * @param eventStore the event store containing the description of changes
+	 * @param nodeInfos annotations to nodes, such as if a node is a string placeholder or a copy target
+	 * @param comments list of comments of the compilation unit to rewrite (elements of type <code>Comment</code>) or <code>null</code>.
+	 * @param options the current jdt.core options (formatting/compliance)
+	 * @param extendedSourceRangeComputer the source range computer to use
+	 * @param recoveryScannerData internal data used by {@link RecoveryScanner}
+	 */
+	public ASTRewriteAnalyzer(
+			char[] content,
+			LineInformation lineInfo,
+			String lineDelim,
+			TextEdit rootEdit,
+			RewriteEventStore eventStore,
+			NodeInfoStore nodeInfos,
+			List comments,
+			Map options,
+			TargetSourceRangeComputer extendedSourceRangeComputer,
+			RecoveryScannerData recoveryScannerData) {
+		this.eventStore= eventStore;
+		this.content= content;
+		this.lineInfo= lineInfo;
+		this.nodeInfos= nodeInfos;
+		this.tokenScanner= null;
+		this.currentEdit= rootEdit;
+		this.sourceCopyInfoToEdit= new IdentityHashMap();
+		this.sourceCopyEndNodes= new Stack();
+
+		this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, lineDelim);
+
+		this.extendedSourceRangeComputer = extendedSourceRangeComputer;
+		this.lineCommentEndOffsets= new LineCommentEndOffsets(comments);
+		
+		this.options = options;
+		
+		this.recoveryScannerData = recoveryScannerData;
+	}
+
+	final TokenScanner getScanner() {
+		if (this.tokenScanner == null) {
+			CompilerOptions compilerOptions = new CompilerOptions(this.options);
+			Scanner scanner;
+			if (this.recoveryScannerData == null) {
+				scanner = 
+					new Scanner(
+							true,/*tokenizeComments*/
+							false,/*tokenizeWhiteSpace*/
+							false,/*checkNonExternalizedStringLiterals*/
+							compilerOptions.sourceLevel,
+							compilerOptions.complianceLevel,
+							null/*taskTags*/,
+							null/*taskPriorities*/,
+							true/*taskCaseSensitive*/);
+			} else {
+				scanner =
+					new RecoveryScanner(
+							false,/*tokenizeWhiteSpace*/
+							false,/*checkNonExternalizedStringLiterals*/
+							compilerOptions.sourceLevel,
+							compilerOptions.complianceLevel,
+							null/*taskTags*/,
+							null/*taskPriorities*/,
+							true/*taskCaseSensitive*/,
+							this.recoveryScannerData);
+			}
+			scanner.setSource(this.content);
+			this.tokenScanner= new TokenScanner(scanner);
+		}
+		return this.tokenScanner;
+	}
+
+	final char[] getContent() {
+		return this.content;
+	}
+
+	final LineInformation getLineInformation() {
+		return this.lineInfo;
+	}
+
+	/**
+	 * Returns the extended source range for a node.
+	 *
+	 * @return an extended source range (never null)
+	 * @since 3.1
+	 */
+	final SourceRange getExtendedRange(ASTNode node) {
+		if (this.eventStore.isRangeCopyPlaceholder(node)) {
+			return new SourceRange(node.getStartPosition(), node.getLength());
+		}
+		return this.extendedSourceRangeComputer.computeSourceRange(node);
+	}
+
+	final int getExtendedOffset(ASTNode node) {
+		return getExtendedRange(node).getStartPosition();
+	}
+
+	final int getExtendedEnd(ASTNode node) {
+		TargetSourceRangeComputer.SourceRange range= getExtendedRange(node);
+		return range.getStartPosition() + range.getLength();
+	}
+
+	final TextEdit getCopySourceEdit(CopySourceInfo info) {
+		TextEdit edit= (TextEdit) this.sourceCopyInfoToEdit.get(info);
+		if (edit == null) {
+			SourceRange range= getExtendedRange(info.getNode());
+			int start= range.getStartPosition();
+			int end= start + range.getLength();
+			if (info.isMove) {
+				MoveSourceEdit moveSourceEdit= new MoveSourceEdit(start, end - start);
+				moveSourceEdit.setTargetEdit(new MoveTargetEdit(0));
+				edit= moveSourceEdit;
+			} else {
+				CopySourceEdit copySourceEdit= new CopySourceEdit(start, end - start);
+				copySourceEdit.setTargetEdit(new CopyTargetEdit(0));
+				edit= copySourceEdit;
+			}
+			this.sourceCopyInfoToEdit.put(info, edit);
+		}
+		return edit;
+	}
+
+	private final int getChangeKind(ASTNode node, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(node, property);
+		if (event != null) {
+			return event.getChangeKind();
+		}
+		return RewriteEvent.UNCHANGED;
+	}
+
+	private final boolean hasChildrenChanges(ASTNode node) {
+		return this.eventStore.hasChangedProperties(node);
+	}
+
+	private final boolean isChanged(ASTNode node, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(node, property);
+		if (event != null) {
+			return event.getChangeKind() != RewriteEvent.UNCHANGED;
+		}
+		return false;
+	}
+
+	private final boolean isCollapsed(ASTNode node) {
+		return this.nodeInfos.isCollapsed(node);
+	}
+
+	final boolean isInsertBoundToPrevious(ASTNode node) {
+		return this.eventStore.isInsertBoundToPrevious(node);
+	}
+
+	private final TextEditGroup getEditGroup(ASTNode parent, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			return getEditGroup(event);
+		}
+		return null;
+	}
+
+	final RewriteEvent getEvent(ASTNode parent, StructuralPropertyDescriptor property) {
+		return this.eventStore.getEvent(parent, property);
+	}
+
+	final TextEditGroup getEditGroup(RewriteEvent change) {
+		return this.eventStore.getEventEditGroup(change);
+	}
+
+	private final Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor property) {
+		return this.eventStore.getOriginalValue(parent, property);
+	}
+
+	private final Object getNewValue(ASTNode parent, StructuralPropertyDescriptor property) {
+		return this.eventStore.getNewValue(parent, property);
+	}
+
+	final void addEdit(TextEdit edit) {
+		this.currentEdit.addChild(edit);
+	}
+
+	final String getLineDelimiter() {
+		return this.formatter.getLineDelimiter();
+	}
+
+	final String createIndentString(int indent) {
+	    return this.formatter.createIndentString(indent);
+	}
+
+	final private String getIndentOfLine(int pos) {
+		int line= getLineInformation().getLineOfOffset(pos);
+		if (line >= 0) {
+			char[] cont= getContent();
+			int lineStart= getLineInformation().getLineOffset(line);
+		    int i= lineStart;
+			while (i < cont.length && IndentManipulation.isIndentChar(this.content[i])) {
+			    i++;
+			}
+			return new String(cont, lineStart, i - lineStart);
+		}
+		return Util.EMPTY_STRING;
+	}
+
+
+	final String getIndentAtOffset(int pos) {
+		return this.formatter.getIndentString(getIndentOfLine(pos));
+	}
+
+	final void doTextInsert(int offset, String insertString, TextEditGroup editGroup) {
+		if (insertString.length() > 0) {
+			// bug fix for 95839: problem with inserting at the end of a line comment
+			if (this.lineCommentEndOffsets.isEndOfLineComment(offset, this.content)) {
+				if (!insertString.startsWith(getLineDelimiter())) {
+					TextEdit edit= new InsertEdit(offset, getLineDelimiter());  // add a line delimiter
+					addEdit(edit);
+					if (editGroup != null) {
+						addEditGroup(editGroup, edit);
+					}
+				}
+				this.lineCommentEndOffsets.remove(offset); // only one line delimiter per line comment required
+			}
+			TextEdit edit= new InsertEdit(offset, insertString);
+			addEdit(edit);
+			if (editGroup != null) {
+				addEditGroup(editGroup, edit);
+			}
+		}
+	}
+
+	final void addEditGroup(TextEditGroup editGroup, TextEdit edit) {
+		editGroup.addTextEdit(edit);
+	}
+
+	final TextEdit doTextRemove(int offset, int len, TextEditGroup editGroup) {
+		if (len == 0) {
+			return null;
+		}
+		TextEdit edit= new DeleteEdit(offset, len);
+		addEdit(edit);
+		if (editGroup != null) {
+			addEditGroup(editGroup, edit);
+		}
+		return edit;
+	}
+
+	final void doTextRemoveAndVisit(int offset, int len, ASTNode node, TextEditGroup editGroup) {
+		TextEdit edit= doTextRemove(offset, len, editGroup);
+		if (edit != null) {
+			this.currentEdit= edit;
+			voidVisit(node);
+			this.currentEdit= edit.getParent();
+		} else {
+			voidVisit(node);
+		}
+	}
+
+	final int doVisit(ASTNode node) {
+		node.accept(this);
+		return getExtendedEnd(node);
+	}
+
+	private final int doVisit(ASTNode parent, StructuralPropertyDescriptor property, int offset) {
+		Object node= getOriginalValue(parent, property);
+		if (property.isChildProperty() && node != null) {
+			return doVisit((ASTNode) node);
+		} else if (property.isChildListProperty()) {
+			return doVisitList((List) node, offset);
+		}
+		return offset;
+	}
+
+	private int doVisitList(List list, int offset) {
+		int endPos= offset;
+		for (Iterator iter= list.iterator(); iter.hasNext();) {
+			ASTNode curr= ((ASTNode) iter.next());
+			endPos= doVisit(curr);
+		}
+		return endPos;
+	}
+
+	final void voidVisit(ASTNode node) {
+		node.accept(this);
+	}
+
+	private final void voidVisit(ASTNode parent, StructuralPropertyDescriptor property) {
+		Object node= getOriginalValue(parent, property);
+		if (property.isChildProperty() && node != null) {
+			voidVisit((ASTNode) node);
+		} else if (property.isChildListProperty()) {
+			voidVisitList((List) node);
+		}
+	}
+
+	private void voidVisitList(List list) {
+		for (Iterator iter= list.iterator(); iter.hasNext();) {
+			doVisit(((ASTNode) iter.next()));
+		}
+	}
+
+	private final boolean doVisitUnchangedChildren(ASTNode parent) {
+		List properties= parent.structuralPropertiesForType();
+		for (int i= 0; i < properties.size(); i++) {
+			voidVisit(parent, (StructuralPropertyDescriptor) properties.get(i));
+		}
+		return false;
+	}
+
+
+	private final void doTextReplace(int offset, int len, String insertString, TextEditGroup editGroup) {
+		if (len > 0 || insertString.length() > 0) {
+			TextEdit edit= new ReplaceEdit(offset, len, insertString);
+			addEdit(edit);
+			if (editGroup != null) {
+				addEditGroup(editGroup, edit);
+			}
+		}
+	}
+
+	private final TextEdit doTextCopy(TextEdit sourceEdit, int destOffset, int sourceIndentLevel, String destIndentString, TextEditGroup editGroup) {
+		TextEdit targetEdit;
+		SourceModifier modifier= new SourceModifier(sourceIndentLevel, destIndentString, this.formatter.getTabWidth(), this.formatter.getIndentWidth());
+
+		if (sourceEdit instanceof MoveSourceEdit) {
+			MoveSourceEdit moveEdit= (MoveSourceEdit) sourceEdit;
+			moveEdit.setSourceModifier(modifier);
+
+			targetEdit= new MoveTargetEdit(destOffset, moveEdit);
+			addEdit(targetEdit);
+		} else {
+			CopySourceEdit copyEdit= (CopySourceEdit) sourceEdit;
+			copyEdit.setSourceModifier(modifier);
+
+			targetEdit= new CopyTargetEdit(destOffset, copyEdit);
+			addEdit(targetEdit);
+		}
+
+		if (editGroup != null) {
+			addEditGroup(editGroup, sourceEdit);
+			addEditGroup(editGroup, targetEdit);
+		}
+		return targetEdit;
+
+	}
+
+	private void changeNotSupported(ASTNode node) {
+		Assert.isTrue(false, "Change not supported in " + node.getClass().getName()); //$NON-NLS-1$
+	}
+
+
+	class ListRewriter {
+		protected String constantSeparator;
+		protected int startPos;
+
+		protected RewriteEvent[] list;
+
+		protected final ASTNode getOriginalNode(int index) {
+			return (ASTNode) this.list[index].getOriginalValue();
+		}
+
+		protected final ASTNode getNewNode(int index) {
+			return (ASTNode) this.list[index].getNewValue();
+		}
+
+		protected String getSeparatorString(int nodeIndex) {
+			return this.constantSeparator;
+		}
+
+		protected int getInitialIndent() {
+			return getIndent(this.startPos);
+		}
+
+		protected int getNodeIndent(int nodeIndex) {
+			ASTNode node= getOriginalNode(nodeIndex);
+			if (node == null) {
+				for (int i= nodeIndex - 1; i>= 0; i--) {
+					ASTNode curr= getOriginalNode(i);
+					if (curr != null) {
+						return getIndent(curr.getStartPosition());
+					}
+				}
+				return getInitialIndent();
+			}
+			return getIndent(node.getStartPosition());
+		}
+
+		protected int getStartOfNextNode(int nextIndex, int defaultPos) {
+			for (int i= nextIndex; i < this.list.length; i++) {
+				RewriteEvent elem= this.list[i];
+				if (elem.getChangeKind() != RewriteEvent.INSERTED) {
+					ASTNode node= (ASTNode) elem.getOriginalValue();
+					return getExtendedOffset(node);
+				}
+			}
+			return defaultPos;
+		}
+
+		protected int getEndOfNode(ASTNode node) {
+			return getExtendedEnd(node);
+		}
+
+		public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, String separator) {
+			this.constantSeparator= separator;
+			return rewriteList(parent, property, keyword, null, offset);
+		}
+
+		private boolean insertAfterSeparator(ASTNode node) {
+			return !isInsertBoundToPrevious(node);
+		}
+
+		protected boolean mustRemoveSeparator(int originalOffset, int nodeIndex) {
+			return true;
+		}
+
+		private int rewriteList(
+				ASTNode parent,
+				StructuralPropertyDescriptor property,
+				String keyword,
+				String endKeyword,
+				int offset) {
+			this.startPos= offset;
+			this.list= getEvent(parent, property).getChildren();
+
+			int total= this.list.length;
+			if (total == 0) {
+				return this.startPos;
+			}
+
+			int currPos= -1;
+
+			int lastNonInsert= -1;
+			int lastNonDelete= -1;
+
+			for (int i= 0; i < total; i++) {
+				int currMark= this.list[i].getChangeKind();
+
+				if (currMark != RewriteEvent.INSERTED) {
+					lastNonInsert= i;
+					if (currPos == -1) {
+						ASTNode elem= (ASTNode) this.list[i].getOriginalValue();
+						currPos= getExtendedOffset(elem);
+					}
+				}
+				if (currMark != RewriteEvent.REMOVED) {
+					lastNonDelete= i;
+				}
+			}
+
+			boolean insertNew = currPos == -1;
+			if (insertNew) { // only inserts
+				if (keyword.length() > 0) {  // creating a new list -> insert keyword first (e.g. " throws ")
+					TextEditGroup editGroup= getEditGroup(this.list[0]); // first node is insert
+					doTextInsert(offset, keyword, editGroup);
+				}
+				currPos= offset;
+			}
+			if (lastNonDelete == -1) { // all removed, set back to start so the keyword is removed as well
+				currPos= offset;
+			}
+
+			int prevEnd= currPos;
+			int prevMark= RewriteEvent.UNCHANGED;
+
+			final int NONE= 0, NEW= 1, EXISTING= 2;
+			int separatorState= NEW;
+
+			for (int i= 0; i < total; i++) {
+				RewriteEvent currEvent= this.list[i];
+				int currMark= currEvent.getChangeKind();
+				int nextIndex= i + 1;
+
+				if (currMark == RewriteEvent.INSERTED) {
+					TextEditGroup editGroup= getEditGroup(currEvent);
+					ASTNode node= (ASTNode) currEvent.getNewValue();
+
+					if (separatorState == NONE) { // element after last existing element (but not first)
+						doTextInsert(currPos, getSeparatorString(i - 1), editGroup); // insert separator
+						separatorState= NEW;
+					}
+					if (separatorState == NEW || insertAfterSeparator(node)) {
+						if (separatorState == EXISTING) {
+							updateIndent(prevMark, currPos, i, editGroup);
+						}
+						
+						doTextInsert(currPos, node, getNodeIndent(i), true, editGroup); // insert node
+
+						separatorState= NEW;
+						if (i != lastNonDelete) {
+							if (this.list[nextIndex].getChangeKind() != RewriteEvent.INSERTED) {
+								doTextInsert(currPos, getSeparatorString(i), editGroup); // insert separator
+							} else {
+								separatorState= NONE;
+							}
+						}
+					} else { // EXISTING && insert before separator
+						doTextInsert(prevEnd, getSeparatorString(i - 1), editGroup);
+						doTextInsert(prevEnd, node, getNodeIndent(i), true, editGroup);
+					}
+					if (insertNew) {
+						if (endKeyword != null && endKeyword.length() > 0) {
+							doTextInsert(currPos, endKeyword, editGroup);
+						}
+					}
+				} else if (currMark == RewriteEvent.REMOVED) {
+					ASTNode node= (ASTNode) currEvent.getOriginalValue();
+					TextEditGroup editGroup= getEditGroup(currEvent);
+					int currEnd= getEndOfNode(node);
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=306524
+					// Check for leading comments that are not part of extended range, and prevent them
+					// from getting removed.
+					try {
+						TokenScanner scanner = getScanner();
+						int newOffset = prevEnd;
+						int extendedOffset = getExtendedOffset(node);
+						// Try to find the end of the last comment which is not part of extended source
+						// range of the node.
+						while (TokenScanner.isComment(scanner.readNext(newOffset, false))) {
+							int tempOffset = scanner.getNextEndOffset(newOffset, false);
+							// check whether the comment is part of extended source range of the node.
+							// If it is then we need to stop.
+							if (tempOffset < extendedOffset) {
+								newOffset = tempOffset;
+							} else {
+								break;
+							}
+						}
+						if (currPos < newOffset) {
+							currPos = extendedOffset;
+						} 
+						prevEnd = newOffset;		
+					} catch (CoreException e) {
+						// ignore
+					}
+					if (i > lastNonDelete && separatorState == EXISTING) {
+						// is last, remove previous separator: split delete to allow range copies
+						doTextRemove(prevEnd, currPos - prevEnd, editGroup); // remove separator
+						doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); // remove node
+						currPos= currEnd;
+						prevEnd= currEnd;
+					} else {
+						if (i < lastNonDelete) {
+							updateIndent(prevMark, currPos, i, editGroup);
+						}
+						
+						// remove element and next separator
+						int end= getStartOfNextNode(nextIndex, currEnd); // start of next
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=306524
+						// Check for trailing comments that are not part of extended range, and prevent them
+						// from getting removed.
+						try {
+							TokenScanner scanner = getScanner();
+							int nextToken= scanner.readNext(currEnd, false);
+							if (TokenScanner.isComment(nextToken)) {
+								// the separator also has comments that are not part of extended
+								// source range of this node or the next node. So dont remove the separator
+								if (end != scanner.getNextStartOffset(currEnd, false)) {
+									// If this condition were true, comments just found as part of the separator would've basically been
+									// part of the extended source range of the next node. So 'end' wud've safely been set to the correct position
+									// and no change is needed.
+									end = currEnd;
+								}
+							}
+						} catch (CoreException e) {
+							// ignore
+						}
+						doTextRemoveAndVisit(currPos, currEnd - currPos, node, getEditGroup(currEvent)); // remove node
+						if (mustRemoveSeparator(currPos, i)) {
+							doTextRemove(currEnd, end - currEnd, editGroup); // remove separator
+						}
+						currPos= end;
+						prevEnd= currEnd;
+						separatorState= NEW;
+					}
+				} else { // replaced or unchanged
+					if (currMark == RewriteEvent.REPLACED) {
+						ASTNode node= (ASTNode) currEvent.getOriginalValue();
+						int currEnd= getEndOfNode(node);
+
+						TextEditGroup editGroup= getEditGroup(currEvent);
+						ASTNode changed= (ASTNode) currEvent.getNewValue();
+						
+						updateIndent(prevMark, currPos, i, editGroup);
+						// make sure that comments between last modified source position and extended starting position of
+						// node to be replaced are not touched
+						try {
+							TokenScanner scanner = getScanner();
+							int newOffset = prevEnd;
+							int extendedOffset = getExtendedOffset(node);
+							// Try to find the end of the last comment which is not part of extended source
+							// range of the node.
+							while (TokenScanner.isComment(scanner.readNext(newOffset, false))) {
+								int tempOffset = scanner.getNextEndOffset(newOffset, false);
+								// check whether the comment is part of extended source range of the node.
+								// If it is then we need to stop.
+								if (tempOffset < extendedOffset) {
+									newOffset = tempOffset;
+								} else {
+									break;
+								}
+							}
+							if (currPos < newOffset) {
+								currPos = extendedOffset;
+							} 		
+						} catch (CoreException e) {
+							// ignore
+						}
+						doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup);
+						doTextInsert(currPos, changed, getNodeIndent(i), true, editGroup);
+
+						prevEnd= currEnd;
+					} else { // is unchanged
+						ASTNode node= (ASTNode) currEvent.getOriginalValue();
+						voidVisit(node);
+					}
+					if (i == lastNonInsert) { // last node or next nodes are all inserts
+						separatorState= NONE;
+						if (currMark == RewriteEvent.UNCHANGED) {
+							ASTNode node= (ASTNode) currEvent.getOriginalValue();
+							prevEnd= getEndOfNode(node);
+						}
+						currPos= prevEnd;
+					} else if (this.list[nextIndex].getChangeKind() != RewriteEvent.UNCHANGED) {
+						// no updates needed while nodes are unchanged
+						if (currMark == RewriteEvent.UNCHANGED) {
+							ASTNode node= (ASTNode) currEvent.getOriginalValue();
+							prevEnd= getEndOfNode(node);
+						}
+						currPos= getStartOfNextNode(nextIndex, prevEnd); // start of next
+						separatorState= EXISTING;
+					}
+				}
+				
+				prevMark = currMark;
+			}
+			return currPos;
+		}
+		public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword) {
+			return rewriteList(parent, property, keyword, null, offset);
+		}
+		
+		protected void updateIndent(int prevMark, int originalOffset, int nodeIndex, TextEditGroup editGroup) {
+			// Do nothing.
+		}
+
+		public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, String endKeyword, String separator) {
+			this.constantSeparator= separator;
+			return rewriteList(parent, property, keyword, endKeyword, offset);
+		}
+	}
+
+	private int rewriteRequiredNode(ASTNode parent, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null && event.getChangeKind() == RewriteEvent.REPLACED) {
+			ASTNode node= (ASTNode) event.getOriginalValue();
+			TextEditGroup editGroup= getEditGroup(event);
+			SourceRange range= getExtendedRange(node);
+			int offset= range.getStartPosition();
+			int length= range.getLength();
+			doTextRemoveAndVisit(offset, length, node, editGroup);
+			doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
+			return offset + length;
+		}
+		return doVisit(parent, property, 0);
+	}
+
+	private int rewriteNode(ASTNode parent, StructuralPropertyDescriptor property, int offset, Prefix prefix) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			switch (event.getChangeKind()) {
+				case RewriteEvent.INSERTED: {
+					ASTNode node= (ASTNode) event.getNewValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					int indent= getIndent(offset);
+					doTextInsert(offset, prefix.getPrefix(indent), editGroup);
+					doTextInsert(offset, node, indent, true, editGroup);
+					return offset;
+				}
+				case RewriteEvent.REMOVED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					
+					// if there is a prefix, remove the prefix as well
+					int nodeEnd;
+					int len;
+					if (offset == 0) {
+						SourceRange range= getExtendedRange(node);
+						offset= range.getStartPosition();
+						len= range.getLength();
+						nodeEnd= offset+len;
+					} else {
+						nodeEnd= getExtendedEnd(node);
+						len= nodeEnd-offset;
+					}
+					doTextRemoveAndVisit(offset, len, node, editGroup);
+					return nodeEnd;
+				}
+				case RewriteEvent.REPLACED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					SourceRange range= getExtendedRange(node);
+					int nodeOffset= range.getStartPosition();
+					int nodeLen= range.getLength();
+					doTextRemoveAndVisit(nodeOffset, nodeLen, node, editGroup);
+					doTextInsert(nodeOffset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
+					return nodeOffset + nodeLen;
+				}
+			}
+		}
+		return doVisit(parent, property, offset);
+	}
+
+	private int rewriteJavadoc(ASTNode node, StructuralPropertyDescriptor property) {
+		int pos= rewriteNode(node, property, node.getStartPosition(), ASTRewriteFormatter.NONE);
+		int changeKind= getChangeKind(node, property);
+		if (changeKind == RewriteEvent.INSERTED) {
+			String indent= getLineDelimiter() + getIndentAtOffset(pos);
+			doTextInsert(pos, indent, getEditGroup(node, property));
+		} else if (changeKind == RewriteEvent.REMOVED) {
+			try {
+				getScanner().readNext(pos, false);
+				doTextRemove(pos, getScanner().getCurrentStartOffset() - pos, getEditGroup(node, property));
+				pos= getScanner().getCurrentStartOffset();
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+		return pos;
+	}
+
+
+	/*
+	 * endpos can be -1 -> use the end pos of the body
+	 */
+	private int rewriteBodyNode(ASTNode parent, StructuralPropertyDescriptor property, int offset, int endPos, int indent, BlockContext context) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			switch (event.getChangeKind()) {
+				case RewriteEvent.INSERTED: {
+					ASTNode node= (ASTNode) event.getNewValue();
+					TextEditGroup editGroup= getEditGroup(event);
+
+					String[] strings= context.getPrefixAndSuffix(indent, node, this.eventStore);
+
+					doTextInsert(offset, strings[0], editGroup);
+					doTextInsert(offset, node, indent, true, editGroup);
+					doTextInsert(offset, strings[1], editGroup);
+					return offset;
+				}
+				case RewriteEvent.REMOVED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					if (endPos == -1) {
+						endPos= getExtendedEnd(node);
+					}
+
+					TextEditGroup editGroup= getEditGroup(event);
+					// if there is a prefix, remove the prefix as well
+					int len= endPos - offset;
+					doTextRemoveAndVisit(offset, len, node, editGroup);
+					return endPos;
+				}
+				case RewriteEvent.REPLACED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					boolean insertNewLine = false;
+					if (endPos == -1) {
+						int previousEnd = node.getStartPosition() + node.getLength();
+						endPos= getExtendedEnd(node);
+						if (endPos != previousEnd) {
+							// check if the end is a comment
+							int token = TokenScanner.END_OF_FILE;
+							try {
+								token = getScanner().readNext(previousEnd, false);
+							} catch(CoreException e) {
+								// ignore
+							}
+							if (token == TerminalTokens.TokenNameCOMMENT_LINE) {
+								insertNewLine = true;
+							}
+						}
+					}
+					TextEditGroup editGroup= getEditGroup(event);
+					int nodeLen= endPos - offset;
+
+					ASTNode replacingNode= (ASTNode) event.getNewValue();
+					String[] strings= context.getPrefixAndSuffix(indent, replacingNode, this.eventStore);
+					doTextRemoveAndVisit(offset, nodeLen, node, editGroup);
+
+					String prefix= strings[0];
+					String insertedPrefix = prefix;
+					if (insertNewLine) {
+						insertedPrefix = getLineDelimiter() + this.formatter.createIndentString(indent) + insertedPrefix.trim() + ' ';
+					}
+					doTextInsert(offset, insertedPrefix, editGroup);
+					int lineStart= getCurrentLineStart(prefix, prefix.length());
+					if (lineStart != 0) {
+						// prefix contains a new line: update the indent to the one used in the prefix
+						indent= this.formatter.computeIndentUnits(prefix.substring(lineStart));
+					}
+					doTextInsert(offset, replacingNode, indent, true, editGroup);
+					doTextInsert(offset, strings[1], editGroup);
+					return endPos;
+				}
+			}
+		}
+		int pos= doVisit(parent, property, offset);
+		if (endPos != -1) {
+			return endPos;
+		}
+		return pos;
+	}
+	private int rewriteOptionalQualifier(ASTNode parent, StructuralPropertyDescriptor property, int startPos) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			switch (event.getChangeKind()) {
+				case RewriteEvent.INSERTED: {
+					ASTNode node= (ASTNode) event.getNewValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					doTextInsert(startPos, node, getIndent(startPos), true, editGroup);
+					doTextInsert(startPos, ".", editGroup); //$NON-NLS-1$
+					return startPos;
+				}
+				case RewriteEvent.REMOVED: {
+					try {
+						ASTNode node= (ASTNode) event.getOriginalValue();
+						TextEditGroup editGroup= getEditGroup(event);
+						int dotEnd= getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, node.getStartPosition() + node.getLength());
+						doTextRemoveAndVisit(startPos, dotEnd - startPos, node, editGroup);
+						return dotEnd;
+					} catch (CoreException e) {
+						handleException(e);
+					}
+					break;
+				}
+				case RewriteEvent.REPLACED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					SourceRange range= getExtendedRange(node);
+					int offset= range.getStartPosition();
+					int length= range.getLength();
+
+					doTextRemoveAndVisit(offset, length, node, editGroup);
+					doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup);
+					try {
+						return getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, offset + length);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+					break;
+				}
+			}
+		}
+		Object node= getOriginalValue(parent, property);
+		if (node == null) {
+			return startPos;
+		}
+		int pos= doVisit((ASTNode) node);
+		try {
+			return getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return pos;
+	}
+
+	class ParagraphListRewriter extends ListRewriter {
+
+		public final static int DEFAULT_SPACING= 1;
+
+		private int initialIndent;
+		private int separatorLines;
+
+		public ParagraphListRewriter(int initialIndent, int separator) {
+			this.initialIndent= initialIndent;
+			this.separatorLines= separator;
+		}
+
+		protected int getInitialIndent() {
+			return this.initialIndent;
+		}
+
+		protected String getSeparatorString(int nodeIndex) {
+			return getSeparatorString(nodeIndex, nodeIndex + 1);
+		}
+		
+		protected String getSeparatorString(int nodeIndex, int nextNodeIndex) {
+			int newLines= this.separatorLines == -1 ? getNewLines(nodeIndex) : this.separatorLines;
+
+			String lineDelim= getLineDelimiter();
+			StringBuffer buf= new StringBuffer(lineDelim);
+			for (int i= 0; i < newLines; i++) {
+				buf.append(lineDelim);
+			}
+			buf.append(createIndentString(getNodeIndent(nextNodeIndex)));
+			return buf.toString();
+		}
+
+		private ASTNode getNode(int nodeIndex) {
+			ASTNode elem= (ASTNode) this.list[nodeIndex].getOriginalValue();
+			if (elem == null) {
+				elem= (ASTNode) this.list[nodeIndex].getNewValue();
+			}
+			return elem;
+		}
+
+		private int getNewLines(int nodeIndex) {
+			ASTNode curr= getNode(nodeIndex);
+			ASTNode next= getNode(nodeIndex + 1);
+
+			int currKind= curr.getNodeType();
+			int nextKind= next.getNodeType();
+
+			ASTNode last= null;
+			ASTNode secondLast= null;
+			for (int i= 0; i < this.list.length; i++) {
+				ASTNode elem= (ASTNode) this.list[i].getOriginalValue();
+				if (elem != null) {
+					if (last != null) {
+						if (elem.getNodeType() == nextKind && last.getNodeType() == currKind) {
+							return countEmptyLines(last);
+						}
+						secondLast= last;
+					}
+					last= elem;
+				}
+			}
+			if (currKind == ASTNode.FIELD_DECLARATION && nextKind == ASTNode.FIELD_DECLARATION ) {
+				return 0;
+			}
+			if (secondLast != null) {
+				return countEmptyLines(secondLast);
+			}
+			return DEFAULT_SPACING;
+		}
+
+		private int countEmptyLines(ASTNode last) {
+			LineInformation lineInformation= getLineInformation();
+			int lastLine= lineInformation.getLineOfOffset(getExtendedEnd(last));
+			if (lastLine >= 0) {
+				int startLine= lastLine + 1;
+				int start= lineInformation.getLineOffset(startLine);
+				if (start < 0) {
+					return 0;
+				}
+				char[] cont= getContent();
+				int i= start;
+				while (i < cont.length && ScannerHelper.isWhitespace(cont[i])) {
+					i++;
+				}
+				if (i > start) {
+					lastLine= lineInformation.getLineOfOffset(i);
+					if (lastLine > startLine) {
+						return lastLine - startLine;
+					}
+				}
+			}
+			return 0;
+		}
+		
+		protected boolean mustRemoveSeparator(int originalOffset, int nodeIndex) {
+			// Do not remove separator if the previous non removed node is on the same line and the next node is on another line
+			int previousNonRemovedNodeIndex = nodeIndex - 1;
+			while (previousNonRemovedNodeIndex >= 0 && this.list[previousNonRemovedNodeIndex].getChangeKind() == RewriteEvent.REMOVED) {
+				previousNonRemovedNodeIndex--;
+			}
+			
+			if (previousNonRemovedNodeIndex > -1) {
+				LineInformation lineInformation = getLineInformation();
+				
+				RewriteEvent prevEvent = this.list[previousNonRemovedNodeIndex];
+				int prevKind = prevEvent.getChangeKind();
+				if (prevKind == RewriteEvent.UNCHANGED || prevKind == RewriteEvent.REPLACED) {
+					ASTNode prevNode = (ASTNode) this.list[previousNonRemovedNodeIndex].getOriginalValue();
+					int prevEndPosition = prevNode.getStartPosition() + prevNode.getLength();
+					int prevLine = lineInformation.getLineOfOffset(prevEndPosition);
+					int line = lineInformation.getLineOfOffset(originalOffset);
+					
+					if (prevLine == line && nodeIndex + 1 < this.list.length) {
+						RewriteEvent nextEvent = this.list[nodeIndex + 1];
+						int nextKind = nextEvent.getChangeKind();
+						
+						if (nextKind == RewriteEvent.UNCHANGED || prevKind == RewriteEvent.REPLACED) {
+							ASTNode nextNode = (ASTNode) nextEvent.getOriginalValue();
+							int nextStartPosition = nextNode.getStartPosition();
+							int nextLine = lineInformation.getLineOfOffset(nextStartPosition);
+							
+							return nextLine == line;
+						}
+						return false;
+					}
+				}
+			}
+			
+			return true;
+		}
+	}
+
+	private int rewriteParagraphList(ASTNode parent, StructuralPropertyDescriptor property, int insertPos, int insertIndent, int separator, int lead) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
+			return doVisit(parent, property, insertPos);
+		}
+
+		RewriteEvent[] events= event.getChildren();
+		ParagraphListRewriter listRewriter= new ParagraphListRewriter(insertIndent, separator);
+		StringBuffer leadString= new StringBuffer();
+		if (isAllOfKind(events, RewriteEvent.INSERTED)) {
+			for (int i= 0; i < lead; i++) {
+				leadString.append(getLineDelimiter());
+			}
+			leadString.append(createIndentString(insertIndent));
+		}
+		return listRewriter.rewriteList(parent, property, insertPos, leadString.toString());
+	}
+
+	private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, boolean adjustOnNext, boolean needsSpaceOnRemoveAll) {
+		int pos= offset;
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			RewriteEvent[] children= event.getChildren();
+			try {
+				boolean isAllInserted= isAllOfKind(children, RewriteEvent.INSERTED);
+				if (isAllInserted && adjustOnNext) {
+					pos= getScanner().getNextStartOffset(pos, false); // adjust on next element
+				}
+				boolean isAllRemoved= !isAllInserted && isAllOfKind(children, RewriteEvent.REMOVED);
+				if (isAllRemoved) { // all removed: set start to left bracket
+					int posBeforeOpenBracket= getScanner().getTokenStartOffset(TerminalTokens.TokenNameLESS, pos);
+					if (posBeforeOpenBracket != pos) {
+						needsSpaceOnRemoveAll= false;
+					}
+					pos= posBeforeOpenBracket;
+				}
+				pos= new ListRewriter().rewriteList(parent, property, pos, String.valueOf('<'), ", "); //$NON-NLS-1$
+				if (isAllRemoved) { // all removed: remove right and space up to next element
+					int endPos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameGREATER, pos); // set pos to '>'
+					endPos= getScanner().getNextStartOffset(endPos, false);
+					String replacement= needsSpaceOnRemoveAll ? String.valueOf(' ') : Util.EMPTY_STRING;
+					doTextReplace(pos, endPos - pos, replacement, getEditGroup(children[children.length - 1]));
+					return endPos;
+				} else if (isAllInserted) {
+					doTextInsert(pos, String.valueOf('>' + keyword), getEditGroup(children[children.length - 1]));
+					return pos;
+				}
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			pos= doVisit(parent, property, pos);
+		}
+		if (pos != offset) { // list contained some type -> parse after closing bracket
+			try {
+				return getScanner().getTokenEndOffset(TerminalTokens.TokenNameGREATER, pos);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+		return pos;
+	}
+
+	private boolean isAllOfKind(RewriteEvent[] children, int kind) {
+		for (int i= 0; i < children.length; i++) {
+			if (children[i].getChangeKind() != kind) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	private int rewriteNodeList(ASTNode parent, StructuralPropertyDescriptor property, int pos, String keyword, String endKeyword, String separator) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			return new ListRewriter().rewriteList(parent, property, pos, keyword, endKeyword, separator);
+		}
+		return doVisit(parent, property, pos);
+	}
+
+	private int rewriteNodeList(ASTNode parent, StructuralPropertyDescriptor property, int pos, String keyword, String separator) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			return new ListRewriter().rewriteList(parent, property, pos, keyword, separator);
+		}
+		return doVisit(parent, property, pos);
+	}
+
+	private void rewriteMethodBody(MethodDeclaration parent, int startPos) {
+		RewriteEvent event= getEvent(parent, MethodDeclaration.BODY_PROPERTY);
+		if (event != null) {
+			switch (event.getChangeKind()) {
+				case RewriteEvent.INSERTED: {
+					int endPos= parent.getStartPosition() + parent.getLength();
+					TextEditGroup editGroup= getEditGroup(event);
+					ASTNode body= (ASTNode) event.getNewValue();
+					doTextRemove(startPos, endPos - startPos, editGroup);
+					int indent= getIndent(parent.getStartPosition());
+					String prefix= this.formatter.METHOD_BODY.getPrefix(indent);
+					doTextInsert(startPos, prefix, editGroup);
+					doTextInsert(startPos, body, indent, true, editGroup);
+					return;
+				}
+				case RewriteEvent.REMOVED: {
+					TextEditGroup editGroup= getEditGroup(event);
+					ASTNode body= (ASTNode) event.getOriginalValue();
+					int endPos= parent.getStartPosition() + parent.getLength();
+					doTextRemoveAndVisit(startPos, endPos - startPos, body, editGroup);
+					doTextInsert(startPos, ";", editGroup); //$NON-NLS-1$
+					return;
+				}
+				case RewriteEvent.REPLACED: {
+					TextEditGroup editGroup= getEditGroup(event);
+					ASTNode body= (ASTNode) event.getOriginalValue();
+					doTextRemoveAndVisit(body.getStartPosition(), body.getLength(), body, editGroup);
+					doTextInsert(body.getStartPosition(), (ASTNode) event.getNewValue(), getIndent(body.getStartPosition()), true, editGroup);
+					return;
+				}
+			}
+		}
+		voidVisit(parent, MethodDeclaration.BODY_PROPERTY);
+	}
+
+	protected int rewriteExtraDimensionsInfo(ASTNode node, int pos, ChildListPropertyDescriptor property) {
+		return rewriteNodeList(node, property, pos, " ", " "); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	private int rewriteExtraDimensions(ASTNode parent, StructuralPropertyDescriptor property, int pos) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
+			return ((Integer) getOriginalValue(parent, property)).intValue();
+		}
+		int oldDim= ((Integer) event.getOriginalValue()).intValue();
+		int newDim= ((Integer) event.getNewValue()).intValue();
+
+		if (oldDim != newDim) {
+			TextEditGroup editGroup= getEditGroup(event);
+			rewriteExtraDimensions(oldDim, newDim, pos, editGroup);
+		}
+		return oldDim;
+	}
+
+	private void rewriteExtraDimensions(int oldDim, int newDim, int pos, TextEditGroup editGroup) {
+
+		if (oldDim < newDim) {
+			for (int i= oldDim; i < newDim; i++) {
+				doTextInsert(pos, "[]", editGroup); //$NON-NLS-1$
+			}
+		} else if (newDim < oldDim) {
+			try {
+				getScanner().setOffset(pos);
+				for (int i= newDim; i < oldDim; i++) {
+					getScanner().readToToken(TerminalTokens.TokenNameRBRACKET);
+				}
+				doTextRemove(pos, getScanner().getCurrentEndOffset() - pos, editGroup);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+	}
+
+	/*
+	 * Next token is a left brace. Returns the offset after the brace. For incomplete code, return the start offset.
+	 */
+	private int getPosAfterLeftBrace(int pos) {
+		try {
+			int nextToken= getScanner().readNext(pos, true);
+			if (nextToken == TerminalTokens.TokenNameLBRACE) {
+				return getScanner().getCurrentEndOffset();
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return pos;
+	}
+
+	/*
+	 * Next token is try keyword. Returns the offset after 'try' keyword. For incomplete code, return the start offset.
+	 */
+	private int getPosAfterTry(int pos) {
+		try {
+			int nextToken= getScanner().readNext(pos, true);
+			if (nextToken == TerminalTokens.TokenNametry) {
+				return getScanner().getCurrentEndOffset();
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return pos;
+	}
+
+	final int getIndent(int offset) {
+		return this.formatter.computeIndentUnits(getIndentOfLine(offset));
+	}
+
+	final void doTextInsert(int insertOffset, ASTNode node, int initialIndentLevel, boolean removeLeadingIndent, TextEditGroup editGroup) {
+		ArrayList markers= new ArrayList();
+		String formatted= this.formatter.getFormattedResult(node, initialIndentLevel, markers);
+
+
+		int currPos= 0;
+		if (removeLeadingIndent) {
+			while (currPos < formatted.length() && ScannerHelper.isWhitespace(formatted.charAt(currPos))) {
+				currPos++;
+			}
+		}
+		for (int i= 0; i < markers.size(); i++) { // markers.size can change!
+			NodeMarker curr= (NodeMarker) markers.get(i);
+
+			int offset= curr.offset;
+			if (offset >= currPos) {
+				String insertStr= formatted.substring(currPos, offset);
+				doTextInsert(insertOffset, insertStr, editGroup); // insert until the marker's begin
+			} else {
+				// already processed
+				continue;
+			}
+
+			Object data= curr.data;
+			if (data instanceof TextEditGroup) { // tracking a node
+				// need to split and create 2 edits as tracking node can surround replaced node.
+				TextEdit edit= new RangeMarker(insertOffset, 0);
+				addEditGroup((TextEditGroup) data, edit);
+				addEdit(edit);
+				if (curr.length != 0) {
+					int end= offset + curr.length;
+					int k= i + 1;
+					while (k < markers.size() && ((NodeMarker) markers.get(k)).offset < end) {
+						k++;
+					}
+					curr.offset= end;
+					curr.length= 0;
+					markers.add(k, curr); // add again for end position
+				}
+				currPos= offset;
+			} else {
+				// If in the first line, there are cases (eg: catch clause) where the line will not be prefixed with 
+				// proper indentation - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285
+				int lineOffset = getCurrentLineStart(formatted, offset);
+				String destIndentString = (lineOffset == 0)
+						? this.formatter.createIndentString(initialIndentLevel)
+						: this.formatter.getIndentString(formatted.substring(lineOffset, offset));
+				if (data instanceof CopyPlaceholderData) { // replace with a copy/move target
+					CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource;
+					int srcIndentLevel= getIndent(copySource.getNode().getStartPosition());
+					TextEdit sourceEdit= getCopySourceEdit(copySource);
+					doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, editGroup);
+					currPos= offset + curr.length; // continue to insert after the replaced string
+					if (needsNewLineForLineComment(copySource.getNode(), formatted, currPos)) {
+						doTextInsert(insertOffset, getLineDelimiter(), editGroup);
+					}
+				} else if (data instanceof StringPlaceholderData) { // replace with a placeholder
+					String code= ((StringPlaceholderData) data).code;
+					String str= this.formatter.changeIndent(code, 0, destIndentString);
+					doTextInsert(insertOffset, str, editGroup);
+					currPos= offset + curr.length; // continue to insert after the replaced string
+				}
+			}
+
+		}
+		if (currPos < formatted.length()) {
+			String insertStr= formatted.substring(currPos);
+			doTextInsert(insertOffset, insertStr, editGroup);
+		}
+	}
+
+	private boolean needsNewLineForLineComment(ASTNode node, String formatted, int offset) {
+		if (!this.lineCommentEndOffsets.isEndOfLineComment(getExtendedEnd(node), this.content)) {
+			return false;
+		}
+		// copied code ends with a line comment, but doesn't contain the new line
+		return offset < formatted.length() && !IndentManipulation.isLineDelimiterChar(formatted.charAt(offset));
+	}
+
+	private int getCurrentLineStart(String str, int pos) {
+		for (int i= pos - 1; i>= 0; i--) {
+			char ch= str.charAt(i);
+			if (IndentManipulation.isLineDelimiterChar(ch)) {
+				return i+1;
+			}
+		}
+		return 0;
+	}
+	
+	private void rewriteModifiers(ASTNode parent, StructuralPropertyDescriptor property, int offset) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event == null || event.getChangeKind() != RewriteEvent.REPLACED) {
+			return;
+		}
+		try {
+			int oldModifiers= ((Integer) event.getOriginalValue()).intValue();
+			int newModifiers= ((Integer) event.getNewValue()).intValue();
+			TextEditGroup editGroup= getEditGroup(event);
+
+			TokenScanner scanner= getScanner();
+
+			int tok= scanner.readNext(offset, false);
+			int startPos= scanner.getCurrentStartOffset();
+			int nextStart= startPos;
+			loop: while (true) {
+				if (TokenScanner.isComment(tok)) {
+					tok= scanner.readNext(true); // next non-comment token
+				}
+				boolean keep= true;
+				switch (tok) {
+					case TerminalTokens.TokenNamepublic: keep= Modifier.isPublic(newModifiers); break;
+					case TerminalTokens.TokenNameprotected: keep= Modifier.isProtected(newModifiers); break;
+					case TerminalTokens.TokenNameprivate: keep= Modifier.isPrivate(newModifiers); break;
+					case TerminalTokens.TokenNamestatic: keep= Modifier.isStatic(newModifiers); break;
+					case TerminalTokens.TokenNamefinal: keep= Modifier.isFinal(newModifiers); break;
+					case TerminalTokens.TokenNameabstract: keep= Modifier.isAbstract(newModifiers); break;
+					case TerminalTokens.TokenNamenative: keep= Modifier.isNative(newModifiers); break;
+					case TerminalTokens.TokenNamevolatile: keep= Modifier.isVolatile(newModifiers); break;
+					case TerminalTokens.TokenNamestrictfp: keep= Modifier.isStrictfp(newModifiers); break;
+					case TerminalTokens.TokenNametransient: keep= Modifier.isTransient(newModifiers); break;
+					case TerminalTokens.TokenNamesynchronized: keep= Modifier.isSynchronized(newModifiers); break;
+					default:
+						break loop;
+				}
+				tok= getScanner().readNext(false); // include comments
+				int currPos= nextStart;
+				nextStart= getScanner().getCurrentStartOffset();
+				if (!keep) {
+					doTextRemove(currPos, nextStart - currPos, editGroup);
+				}
+			}
+			int addedModifiers= newModifiers & ~oldModifiers;
+			if (addedModifiers != 0) {
+				if (startPos != nextStart) {
+					int visibilityModifiers= addedModifiers & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
+					if (visibilityModifiers != 0) {
+						StringBuffer buf= new StringBuffer();
+						ASTRewriteFlattener.printModifiers(visibilityModifiers, buf);
+						doTextInsert(startPos, buf.toString(), editGroup);
+						addedModifiers &= ~visibilityModifiers;
+					}
+				}
+				StringBuffer buf= new StringBuffer();
+				ASTRewriteFlattener.printModifiers(addedModifiers, buf);
+				doTextInsert(nextStart, buf.toString(), editGroup);
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+	}
+
+	class ModifierRewriter extends ListRewriter {
+
+		private final Prefix annotationSeparation;
+
+		public ModifierRewriter(Prefix annotationSeparation) {
+			this.annotationSeparation= annotationSeparation;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.ListRewriter#getSeparatorString(int)
+		 */
+		protected String getSeparatorString(int nodeIndex) {
+			ASTNode curr= getNewNode(nodeIndex);
+			if (curr instanceof Annotation) {
+				return this.annotationSeparation.getPrefix(getNodeIndent(nodeIndex + 1));
+			}
+			return super.getSeparatorString(nodeIndex);
+		}
+	}
+
+
+	private int rewriteModifiers2(ASTNode node, ChildListPropertyDescriptor property, int pos) {
+		RewriteEvent event= getEvent(node, property);
+		if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
+			return doVisit(node, property, pos);
+		}
+		RewriteEvent[] children= event.getChildren();
+		boolean isAllInsert= isAllOfKind(children, RewriteEvent.INSERTED);
+		boolean isAllRemove= isAllOfKind(children, RewriteEvent.REMOVED);
+		String keyword= Util.EMPTY_STRING;
+		boolean isAnnotationsProperty = property == SingleVariableDeclaration.VARARGS_ANNOTATIONS_PROPERTY 
+				|| node instanceof AnnotatableType && property == ((AnnotatableType) node).getAnnotationsProperty();
+		if (isAnnotationsProperty) {
+			keyword= " "; //$NON-NLS-1$
+		} else if (isAllInsert || isAllRemove) {
+			// update pos
+			try {
+				pos= getScanner().getNextStartOffset(pos, false);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+
+		Prefix formatterPrefix;
+		if (property == SingleVariableDeclaration.MODIFIERS2_PROPERTY || isAnnotationsProperty)
+			formatterPrefix= this.formatter.PARAM_ANNOTATION_SEPARATION;
+		else
+			formatterPrefix= this.formatter.ANNOTATION_SEPARATION;
+
+		int endPos= new ModifierRewriter(formatterPrefix).rewriteList(node, property, pos, keyword, " "); //$NON-NLS-1$ 
+
+		try {
+			int nextPos= getScanner().getNextStartOffset(endPos, false);
+			RewriteEvent lastChild = children[children.length - 1];
+			boolean lastUnchanged= lastChild.getChangeKind() != RewriteEvent.UNCHANGED;
+
+			if (isAllRemove) {
+				doTextRemove(endPos, nextPos - endPos, getEditGroup(lastChild));
+				return nextPos;
+			} else if ((isAllInsert || (nextPos == endPos && lastUnchanged)) // see bug 165654
+					&& !isAnnotationsProperty) {
+				String separator;
+				if (lastChild.getNewValue() instanceof Annotation) {
+					separator= formatterPrefix.getPrefix(getIndent(pos));
+				} else {
+					separator= String.valueOf(' ');
+				}
+				doTextInsert(endPos, separator, getEditGroup(lastChild));
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return endPos;
+	}
+	
+	private int rewriteTypeAnnotations(ASTNode node, ChildListPropertyDescriptor property, int pos) {
+		return rewriteModifiers2(node, property, pos);
+	}
+
+	private int rewriteVarargsAnnotations(ASTNode node, ChildListPropertyDescriptor property, int pos) {
+		return rewriteModifiers2(node, property, pos);
+	}
+
+	private void replaceOperation(int posBeforeOperation, String newOperation, TextEditGroup editGroup) {
+		try {
+			getScanner().readNext(posBeforeOperation, true);
+			doTextReplace(getScanner().getCurrentStartOffset(), getScanner().getCurrentLength(), newOperation, editGroup);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+	}
+
+	private void rewriteOperation(ASTNode parent, StructuralPropertyDescriptor property, int posBeforeOperation) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			try {
+				String newOperation= event.getNewValue().toString();
+				TextEditGroup editGroup= getEditGroup(event);
+				getScanner().readNext(posBeforeOperation, true);
+				doTextReplace(getScanner().getCurrentStartOffset(), getScanner().getCurrentLength(), newOperation, editGroup);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#postVisit(ASTNode)
+	 */
+	public void postVisit(ASTNode node) {
+		TextEditGroup editGroup= this.eventStore.getTrackedNodeData(node);
+		if (editGroup != null) {
+			this.currentEdit= this.currentEdit.getParent();
+		}
+		// remove copy source edits
+		doCopySourcePostVisit(node, this.sourceCopyEndNodes);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#preVisit(ASTNode)
+	 */
+	public void preVisit(ASTNode node) {
+		// copies, then range marker
+
+		CopySourceInfo[] infos= this.eventStore.getNodeCopySources(node);
+		doCopySourcePreVisit(infos, this.sourceCopyEndNodes);
+
+		TextEditGroup editGroup= this.eventStore.getTrackedNodeData(node);
+		if (editGroup != null) {
+			SourceRange range= getExtendedRange(node);
+			int offset= range.getStartPosition();
+			int length= range.getLength();
+			TextEdit edit= new RangeMarker(offset, length);
+			addEditGroup(editGroup, edit);
+			addEdit(edit);
+			this.currentEdit= edit;
+		}
+		
+		ensureSpaceBeforeReplace(node);
+	}
+
+	final void doCopySourcePreVisit(CopySourceInfo[] infos, Stack nodeEndStack) {
+		if (infos != null) {
+			for (int i= 0; i < infos.length; i++) {
+				CopySourceInfo curr= infos[i];
+				TextEdit edit= getCopySourceEdit(curr);
+				addEdit(edit);
+				this.currentEdit= edit;
+				nodeEndStack.push(curr.getNode());
+			}
+		}
+	}
+
+	final void doCopySourcePostVisit(ASTNode node, Stack nodeEndStack) {
+		while (!nodeEndStack.isEmpty() && nodeEndStack.peek() == node) {
+			nodeEndStack.pop();
+			this.currentEdit= this.currentEdit.getParent();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CompilationUnit)
+	 */
+	public boolean visit(CompilationUnit node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int startPos= rewriteNode(node, CompilationUnit.PACKAGE_PROPERTY, 0, ASTRewriteFormatter.NONE);
+
+		if (getChangeKind(node, CompilationUnit.PACKAGE_PROPERTY) == RewriteEvent.INSERTED) {
+			doTextInsert(0, getLineDelimiter(), getEditGroup(node, CompilationUnit.PACKAGE_PROPERTY));
+		}
+
+		startPos= rewriteParagraphList(node, CompilationUnit.IMPORTS_PROPERTY, startPos, 0, 0, 2);
+		rewriteParagraphList(node, CompilationUnit.TYPES_PROPERTY, startPos, 0, -1, 2);
+		return false;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclaration)
+	 */
+	public boolean visit(TypeDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int apiLevel= node.getAST().apiLevel();
+
+		int pos= rewriteJavadoc(node, TypeDeclaration.JAVADOC_PROPERTY);
+
+		boolean isJLS2 = apiLevel == JLS2_INTERNAL;
+		if (isJLS2) {
+			rewriteModifiers(node, INTERNAL_TYPE_MODIFIERS_PROPERTY, pos);
+		} else {
+			rewriteModifiers2(node, TypeDeclaration.MODIFIERS2_PROPERTY, pos);
+		}
+
+		boolean isInterface= ((Boolean) getOriginalValue(node, TypeDeclaration.INTERFACE_PROPERTY)).booleanValue();
+		// modifiers & class/interface
+		boolean invertType= isChanged(node, TypeDeclaration.INTERFACE_PROPERTY);
+		if (invertType) {
+			try {
+				int typeToken= isInterface ? TerminalTokens.TokenNameinterface : TerminalTokens.TokenNameclass;
+				int startPosition = node.getStartPosition();
+				if (!isJLS2) {
+					List modifiers = node.modifiers();
+					final int size = modifiers.size();
+					if (size != 0) {
+						ASTNode modifierNode = (ASTNode) modifiers.get(size - 1);
+						startPosition = modifierNode.getStartPosition() + modifierNode.getLength();
+					}
+				}
+				getScanner().readToToken(typeToken, startPosition);
+
+				String str= isInterface ? "class" : "interface"; //$NON-NLS-1$ //$NON-NLS-2$
+				int start= getScanner().getCurrentStartOffset();
+				int end= getScanner().getCurrentEndOffset();
+
+				doTextReplace(start, end - start, str, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
+			} catch (CoreException e) {
+				// ignore
+			}
+		}
+
+		// name
+		pos= rewriteRequiredNode(node, TypeDeclaration.NAME_PROPERTY);
+
+		if (!isJLS2) {
+			pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, Util.EMPTY_STRING, false, true); 
+		}
+
+		// superclass
+		if (!isInterface || invertType) {
+			ChildPropertyDescriptor superClassProperty= isJLS2 ? INTERNAL_TYPE_SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
+
+			RewriteEvent superClassEvent= getEvent(node, superClassProperty);
+
+			int changeKind= superClassEvent != null ? superClassEvent.getChangeKind() : RewriteEvent.UNCHANGED;
+			switch (changeKind) {
+				case RewriteEvent.INSERTED: {
+					doTextInsert(pos, " extends ", getEditGroup(superClassEvent)); //$NON-NLS-1$
+					doTextInsert(pos, (ASTNode) superClassEvent.getNewValue(), 0, false, getEditGroup(superClassEvent));
+					break;
+				}
+				case RewriteEvent.REMOVED: {
+					ASTNode superClass= (ASTNode) superClassEvent.getOriginalValue();
+					int endPos= getExtendedEnd(superClass);
+					doTextRemoveAndVisit(pos, endPos - pos, superClass, getEditGroup(superClassEvent));
+					pos= endPos;
+					break;
+				}
+				case RewriteEvent.REPLACED: {
+					ASTNode superClass= (ASTNode) superClassEvent.getOriginalValue();
+					SourceRange range= getExtendedRange(superClass);
+					int offset= range.getStartPosition();
+					int length= range.getLength();
+					doTextRemoveAndVisit(offset, length, superClass, getEditGroup(superClassEvent));
+					doTextInsert(offset, (ASTNode) superClassEvent.getNewValue(), 0, false, getEditGroup(superClassEvent));
+					pos= offset + length;
+					break;
+				}
+				case RewriteEvent.UNCHANGED: {
+					pos= doVisit(node, superClassProperty, pos);
+				}
+			}
+		}
+		// extended interfaces
+		ChildListPropertyDescriptor superInterfaceProperty= isJLS2 ? INTERNAL_TYPE_SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
+
+		RewriteEvent interfaceEvent= getEvent(node, superInterfaceProperty);
+		if (interfaceEvent == null || interfaceEvent.getChangeKind() == RewriteEvent.UNCHANGED) {
+			if (invertType) {
+				List originalNodes= (List) getOriginalValue(node, superInterfaceProperty);
+				if (!originalNodes.isEmpty()) {
+					String keyword= isInterface ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$
+					ASTNode firstNode= (ASTNode) originalNodes.get(0);
+					doTextReplace(pos, firstNode.getStartPosition() - pos, keyword, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
+				}
+			}
+			pos= doVisit(node, superInterfaceProperty, pos);
+		} else {
+			String keyword= (isInterface == invertType) ? " implements " : " extends "; //$NON-NLS-1$ //$NON-NLS-2$
+			if (invertType) {
+				List newNodes= (List) interfaceEvent.getNewValue();
+				if (!newNodes.isEmpty()) {
+					List origNodes= (List) interfaceEvent.getOriginalValue();
+					int firstStart= pos;
+					if (!origNodes.isEmpty()) {
+						firstStart= ((ASTNode) origNodes.get(0)).getStartPosition();
+					}
+					doTextReplace(pos, firstStart - pos, keyword, getEditGroup(node, TypeDeclaration.INTERFACE_PROPERTY));
+					keyword= Util.EMPTY_STRING; 
+					pos= firstStart;
+				}
+			}
+			pos= rewriteNodeList(node, superInterfaceProperty, pos, keyword, ", "); //$NON-NLS-1$
+		}
+
+		// type members
+		// startPos : find position after left brace of type, be aware that bracket might be missing
+		int startIndent= getIndent(node.getStartPosition()) + 1;
+		int startPos= getPosAfterLeftBrace(pos);
+		rewriteParagraphList(node, TypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
+		return false;
+	}
+
+	private void rewriteReturnType(MethodDeclaration node, boolean isConstructor, boolean isConstructorChange) {
+		ChildPropertyDescriptor property= (node.getAST().apiLevel() == JLS2_INTERNAL) ? INTERNAL_METHOD_RETURN_TYPE_PROPERTY : MethodDeclaration.RETURN_TYPE2_PROPERTY;
+
+		// weakness in the AST: return type can exist, even if missing in source
+		ASTNode originalReturnType= (ASTNode) getOriginalValue(node, property);
+		boolean returnTypeExists=  originalReturnType != null && originalReturnType.getStartPosition() != -1;
+		if (!isConstructorChange && returnTypeExists) {
+			rewriteRequiredNode(node, property);
+			ensureSpaceAfterReplace(node, property);
+			return;
+		}
+		// difficult cases: return type insert or remove
+		ASTNode newReturnType= (ASTNode) getNewValue(node, property);
+		if (isConstructorChange || !returnTypeExists && newReturnType != originalReturnType) {
+			// use the start offset of the method name to insert
+			ASTNode originalMethodName= (ASTNode) getOriginalValue(node, MethodDeclaration.NAME_PROPERTY);
+			int nextStart= originalMethodName.getStartPosition(); // see bug 84049: can't use extended offset
+			TextEditGroup editGroup= getEditGroup(node, property);
+			if (isConstructor || !returnTypeExists) { // insert
+				doTextInsert(nextStart, newReturnType, getIndent(nextStart), true, editGroup);
+				doTextInsert(nextStart, " ", editGroup); //$NON-NLS-1$
+			} else { // remove up to the method name
+				int offset= getExtendedOffset(originalReturnType);
+				doTextRemoveAndVisit(offset, nextStart - offset, originalReturnType, editGroup);
+			}
+		}
+	}
+	
+	private int rewriteMethodReceiver(MethodDeclaration method, int offset) throws CoreException {
+		offset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, offset);
+		if (method.getAST().apiLevel() < AST.JLS8) {
+			return offset;
+		}
+
+		int newParamCount = ((List) getNewValue(method, MethodDeclaration.PARAMETERS_PROPERTY)).size();
+		int oldParamCount = method.parameters().size();
+		RewriteEvent event = getEvent(method, MethodDeclaration.RECEIVER_TYPE_PROPERTY);
+		RewriteEvent qualEvent = getEvent(method, MethodDeclaration.RECEIVER_QUALIFIER_PROPERTY);
+
+		boolean rewriteQualifier = false;
+		ASTNode newQual = null;
+		ASTNode oldQual = null;
+		if (qualEvent != null) {
+			newQual = (ASTNode) qualEvent.getNewValue();
+			oldQual = (ASTNode) qualEvent.getOriginalValue();
+		}
+
+		TextEditGroup editGroup= getEditGroup(event);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			int changeKind= event.getChangeKind();
+			if (changeKind == RewriteEvent.INSERTED) {
+				 doTextInsert(offset, (ASTNode) event.getNewValue(), 0, false, editGroup);
+				doTextInsert(offset, " ", editGroup); //$NON-NLS-1$
+				if (newQual != null ) {
+					doTextInsert(offset, newQual, 0, false, getEditGroup(qualEvent));
+					doTextInsert(offset, ".", editGroup); //$NON-NLS-1$
+				}
+				doTextInsert(offset, "this", editGroup); //$NON-NLS-1$
+				if (newParamCount > 0) {
+					doTextInsert(offset, ", ", editGroup); //$NON-NLS-1$
+				}
+			} else {
+				ASTNode elem= (ASTNode) event.getOriginalValue();
+				SourceRange range= getExtendedRange(elem);
+				int elemOffset= range.getStartPosition();
+				int elemLength= range.getLength();
+				int elemEnd= elemOffset + elemLength;
+				if (changeKind == RewriteEvent.REMOVED) {
+					editGroup= getEditGroup(event);
+					int endPos;
+					if (oldParamCount == 0) {
+						endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNameRPAREN, elemEnd);
+					} else {
+						endPos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOMMA, elemEnd);
+					}
+					doTextRemoveAndVisit(offset, endPos - offset, elem, editGroup);
+					return endPos;
+				} else if (changeKind == RewriteEvent.REPLACED) {
+					editGroup= getEditGroup(event);
+					doTextRemoveAndVisit(elemOffset, elemLength, elem, editGroup);
+					doTextInsert(elemOffset, (ASTNode) event.getNewValue(), 0, false, editGroup);
+					rewriteQualifier = true;
+				}
+			}
+		} else {
+			rewriteRequiredNode(method, MethodDeclaration.RECEIVER_TYPE_PROPERTY);
+			if (method.getReceiverType() != null) {
+				rewriteQualifier = true;
+			}
+		}
+		if (rewriteQualifier) {
+			if (qualEvent != null) {
+				int qualChangeKind = qualEvent.getChangeKind();
+				TextEditGroup qualGroup = getEditGroup(qualEvent);
+				if (qualChangeKind == RewriteEvent.INSERTED) {
+					int pos= getScanner().getTokenStartOffset(TerminalTokens.TokenNamethis, offset);
+					doTextInsert(pos, (ASTNode) qualEvent.getNewValue(), 0, false, qualGroup);
+					doTextInsert(pos, ".", qualGroup); //$NON-NLS-1$
+				} else if (qualChangeKind == RewriteEvent.REMOVED) {
+					int qualOffset = oldQual.getStartPosition();
+					int endPos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, qualOffset);
+					doTextRemove(qualOffset, endPos - qualOffset, qualGroup);
+				} else if (qualChangeKind == RewriteEvent.REPLACED) {
+					SourceRange range= getExtendedRange(oldQual);
+					int elemOffset= range.getStartPosition();
+					int elemLength= range.getLength();
+					doTextRemoveAndVisit(elemOffset, elemLength, oldQual, qualGroup);
+					doTextInsert(elemOffset, newQual, 0, false, qualGroup);
+				}
+			}
+			offset=  getScanner().getTokenEndOffset(TerminalTokens.TokenNamethis, offset);
+			if (newParamCount > 0 && oldParamCount == 0) {
+				doTextInsert(offset, ", ", editGroup); //$NON-NLS-1$
+			}
+		}
+		return offset;
+	}
+
+	public boolean visit(ExtraDimension node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteNodeList(node, ExtraDimension.ANNOTATIONS_PROPERTY, node.getStartPosition(), Util.EMPTY_STRING, " "); //$NON-NLS-1$
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(MethodDeclaration)
+	 */
+	public boolean visit(MethodDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, MethodDeclaration.JAVADOC_PROPERTY);
+		int apiLevel= node.getAST().apiLevel();
+		if (apiLevel == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_METHOD_MODIFIERS_PROPERTY2, pos);
+		} else {
+			pos= rewriteModifiers2(node, MethodDeclaration.MODIFIERS2_PROPERTY, pos);
+			pos= rewriteOptionalTypeParameters(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true, pos != node.getStartPosition()); //$NON-NLS-1$
+		}
+
+		boolean isConstructorChange= isChanged(node, MethodDeclaration.CONSTRUCTOR_PROPERTY);
+		boolean isConstructor= ((Boolean) getOriginalValue(node, MethodDeclaration.CONSTRUCTOR_PROPERTY)).booleanValue();
+		if (!isConstructor || isConstructorChange) {
+			rewriteReturnType(node, isConstructor, isConstructorChange);
+		}
+		// method name
+		pos= rewriteRequiredNode(node, MethodDeclaration.NAME_PROPERTY);
+
+		// parameters
+		try {
+			pos= rewriteMethodReceiver(node, pos);
+			pos= rewriteNodeList(node, MethodDeclaration.PARAMETERS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+
+			pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos);
+			ChildListPropertyDescriptor exceptionsProperty = apiLevel < AST.JLS8 ? INTERNAL_METHOD_THROWN_EXCEPTIONS_PROPERTY : MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY;
+
+			if (apiLevel < AST.JLS8) {
+				int extraDims= rewriteExtraDimensions(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, pos);
+
+				boolean hasExceptionChanges= isChanged(node, exceptionsProperty);
+
+				int bodyChangeKind= getChangeKind(node, MethodDeclaration.BODY_PROPERTY);
+
+				if ((extraDims > 0) && (hasExceptionChanges || bodyChangeKind == RewriteEvent.INSERTED || bodyChangeKind == RewriteEvent.REMOVED)) {
+					int dim= ((Integer) getOriginalValue(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY)).intValue();
+					while (dim > 0) {
+						pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRBRACKET, pos);
+						dim--;
+					}
+				}
+			} else {
+				pos= rewriteExtraDimensionsInfo(node, pos, MethodDeclaration.EXTRA_DIMENSIONS2_PROPERTY);
+			}
+
+			pos= rewriteNodeList(node, exceptionsProperty, pos, " throws ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+			
+			rewriteMethodBody(node, pos);
+		} catch (CoreException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Block)
+	 */
+	public boolean visit(Block node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int startPos;
+		if (isCollapsed(node)) {
+			startPos= node.getStartPosition();
+		} else {
+			startPos= getPosAfterLeftBrace(node.getStartPosition());
+		}
+		int startIndent= getIndent(node.getStartPosition()) + 1;
+		rewriteParagraphList(node, Block.STATEMENTS_PROPERTY, startPos, startIndent, 0, 1);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ReturnStatement)
+	 */
+	public boolean visit(ReturnStatement node) {
+		try {
+			this.beforeRequiredSpaceIndex = getScanner().getTokenEndOffset(TerminalTokens.TokenNamereturn, node.getStartPosition());
+			
+			if (!hasChildrenChanges(node)) {
+				return doVisitUnchangedChildren(node);
+			}
+			
+			ensureSpaceBeforeReplace(node);
+			
+			rewriteNode(node, ReturnStatement.EXPRESSION_PROPERTY, this.beforeRequiredSpaceIndex, ASTRewriteFormatter.SPACE);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(AnonymousClassDeclaration)
+	 */
+	public boolean visit(AnonymousClassDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int startPos= getPosAfterLeftBrace(node.getStartPosition());
+		int startIndent= getIndent(node.getStartPosition()) + 1;
+		rewriteParagraphList(node, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayAccess)
+	 */
+	public boolean visit(ArrayAccess node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, ArrayAccess.ARRAY_PROPERTY);
+		rewriteRequiredNode(node, ArrayAccess.INDEX_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayCreation)
+	 */
+	public boolean visit(ArrayCreation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		ArrayType arrayType= (ArrayType) getOriginalValue(node, ArrayCreation.TYPE_PROPERTY);
+		ArrayType replacingType= arrayType;
+		int nOldBrackets= getDimensions(arrayType); // number of total brackets
+
+		TextEditGroup editGroup= null;
+		RewriteEvent typeEvent= getEvent(node, ArrayCreation.TYPE_PROPERTY);
+		if (typeEvent != null && typeEvent.getChangeKind() == RewriteEvent.REPLACED) { // changed arraytype can have different dimension or type name
+			replacingType= (ArrayType) typeEvent.getNewValue();
+			editGroup= getEditGroup(typeEvent);
+			Type newType= replacingType.getElementType();
+			Type oldType= getElementType(arrayType);
+			if (!newType.equals(oldType)) {
+				SourceRange range= getExtendedRange(oldType);
+				int offset= range.getStartPosition();
+				int length= range.getLength();
+				doTextRemove(offset, length, editGroup);
+				doTextInsert(offset, newType, 0, false, editGroup);
+			}
+		}
+
+		try {
+			// dimension node with expressions and/or annotations
+			RewriteEvent dimEvent= getEvent(node, ArrayCreation.DIMENSIONS_PROPERTY);
+			boolean hasDimensionChanges= (dimEvent != null && dimEvent.getChangeKind() != RewriteEvent.UNCHANGED);
+			RewriteEvent[] events= hasDimensionChanges ? dimEvent.getChildren() : null;
+			ArrayType currentLevel= (ArrayType) replacingType.getElementType().getParent();
+			int i=0, dimSize= (events == null) ? 0 : events.length;
+			Type elementType= arrayType.getElementType();
+			int offset= elementType.getStartPosition() + elementType.getLength();
+			while(currentLevel != null) {
+				if (node.getAST().apiLevel() >= AST.JLS8) {
+					rewriteTypeAnnotations(currentLevel, ArrayType.ANNOTATIONS_PROPERTY, offset);
+				}
+				if (i < dimSize) {
+					 offset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLBRACKET, offset);
+					if (hasDimensionChanges) {
+						RewriteEvent event= events[i];
+						int changeKind= event.getChangeKind();
+						if (changeKind == RewriteEvent.INSERTED) { // insert new dimension
+							editGroup= getEditGroup(event);
+							int endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNameRBRACKET, offset);
+							doTextRemove(offset, endPos - offset, editGroup);
+							doTextInsert(offset, (ASTNode) event.getNewValue(), 0, false, editGroup);
+						} else {
+							ASTNode elem= (ASTNode) event.getOriginalValue();
+							int elemEnd= elem.getStartPosition() + elem.getLength();
+							int endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNameRBRACKET, elemEnd);
+							if (changeKind == RewriteEvent.REMOVED) {
+								editGroup= getEditGroup(event);
+								doTextRemoveAndVisit(offset, endPos - offset, elem, editGroup);
+							} else if (changeKind == RewriteEvent.REPLACED) {
+								editGroup= getEditGroup(event);
+								SourceRange range= getExtendedRange(elem);
+								int elemOffset= range.getStartPosition();
+								int elemLength= range.getLength();
+								doTextRemoveAndVisit(elemOffset, elemLength, elem, editGroup);
+								doTextInsert(elemOffset, (ASTNode) event.getNewValue(), 0, false, editGroup);
+							} else {
+								voidVisit(elem);
+							}
+						}
+						offset= retrieveRightBracketEndPosition(offset, 1, true);
+					} else {
+						ASTNode elem= (ASTNode) node.dimensions().get(i);
+						voidVisit(elem);
+						offset= retrieveRightBracketEndPosition(offset, 1, true);
+					}
+				} else if (i < nOldBrackets) {
+					offset= retrieveRightBracketEndPosition(offset, 1, false);
+				} else {
+					doTextInsert(offset, "[]", editGroup); //$NON-NLS-1$
+				}
+				i++;
+				if (currentLevel == replacingType) break;
+				currentLevel= (ArrayType) currentLevel.getParent();
+			}
+			if (i < nOldBrackets) {
+				int endPos= retrieveRightBracketEndPosition(offset, nOldBrackets - i, false);
+				doTextRemove(offset, endPos - offset, editGroup);
+			}
+
+			int kind= getChangeKind(node, ArrayCreation.INITIALIZER_PROPERTY);
+			if (kind == RewriteEvent.REMOVED) {
+				offset= getScanner().getPreviousTokenEndOffset(TerminalTokens.TokenNameLBRACE, offset);
+			} else {
+				offset= node.getStartPosition() + node.getLength(); // insert pos
+			}
+			rewriteNode(node, ArrayCreation.INITIALIZER_PROPERTY, offset, ASTRewriteFormatter.SPACE);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/**
+	 * This method is used to retrieve the position of the right bracket.
+	 * @return int the dimension found, -1 if none
+	 */
+	protected int retrieveRightBracketEndPosition(int offset, int count, boolean isLeftRead) throws CoreException {
+		TokenScanner scanner= getScanner();
+		int token;
+		int balance= 0;
+		if (isLeftRead) balance++;
+		scanner.setOffset(offset);
+		while ((token= scanner.readNext(true)) != TerminalTokens.TokenNameEOF) {
+			switch(token) {
+				case TerminalTokens.TokenNameLBRACKET :
+					balance++;
+					break;
+				case TerminalTokens.TokenNameRBRACKET :
+					balance--;
+					if (balance == 0) {
+						if (--count == 0) {
+							return scanner.getCurrentEndOffset();
+						}
+					}
+					break;
+			}
+		}
+		return -1;
+	}
+
+	private Type getElementType(ArrayType parent) {
+		Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY);
+		while (t.isArrayType()) {
+			t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY);
+		}
+		return t;
+	}
+
+	private int getDimensions(ArrayType parent) {
+		Type t = (Type) getOriginalValue(parent, ArrayType.COMPONENT_TYPE_PROPERTY);
+		int dimensions = 1; // always include this array type
+		while (t.isArrayType()) {
+			dimensions++;
+			t = (Type) getOriginalValue(t, ArrayType.COMPONENT_TYPE_PROPERTY);
+		}
+		return dimensions;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayInitializer)
+	 */
+	public boolean visit(ArrayInitializer node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int startPos= getPosAfterLeftBrace(node.getStartPosition());
+		rewriteNodeList(node, ArrayInitializer.EXPRESSIONS_PROPERTY, startPos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+		return false;
+	}
+
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ArrayType)
+	 */
+	public boolean visit(ArrayType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos = rewriteRequiredNode(node, ArrayType.COMPONENT_TYPE_PROPERTY);
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			rewriteTypeAnnotations(node, ArrayType.ANNOTATIONS_PROPERTY, pos);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(AssertStatement)
+	 */
+	public boolean visit(AssertStatement node) {
+		try {
+			this.beforeRequiredSpaceIndex = getScanner().getNextEndOffset(node.getStartPosition(), true);
+			
+			if (!hasChildrenChanges(node)) {
+				return doVisitUnchangedChildren(node);
+			}
+			
+			ensureSpaceBeforeReplace(node);
+			
+			int offset= rewriteRequiredNode(node, AssertStatement.EXPRESSION_PROPERTY);
+			rewriteNode(node, AssertStatement.MESSAGE_PROPERTY, offset, ASTRewriteFormatter.ASSERT_COMMENT);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Assignment)
+	 */
+	public boolean visit(Assignment node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, Assignment.LEFT_HAND_SIDE_PROPERTY);
+		rewriteOperation(node, Assignment.OPERATOR_PROPERTY, pos);
+		rewriteRequiredNode(node, Assignment.RIGHT_HAND_SIDE_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(BooleanLiteral)
+	 */
+	public boolean visit(BooleanLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		Boolean newLiteral= (Boolean) getNewValue(node, BooleanLiteral.BOOLEAN_VALUE_PROPERTY);
+		TextEditGroup group = getEditGroup(node, BooleanLiteral.BOOLEAN_VALUE_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newLiteral.toString(), group);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(BreakStatement)
+	 */
+	public boolean visit(BreakStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		try {
+			int offset= getScanner().getTokenEndOffset(TerminalTokens.TokenNamebreak, node.getStartPosition());
+			rewriteNode(node, BreakStatement.LABEL_PROPERTY, offset, ASTRewriteFormatter.SPACE); // space between break and label
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CastExpression)
+	 */
+	public boolean visit(CastExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, CastExpression.TYPE_PROPERTY);
+		rewriteRequiredNode(node, CastExpression.EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CatchClause)
+	 */
+	public boolean visit(CatchClause node) { // catch (Exception) Block
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, CatchClause.EXCEPTION_PROPERTY);
+		rewriteRequiredNode(node, CatchClause.BODY_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CharacterLiteral)
+	 */
+	public boolean visit(CharacterLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		String escapedSeq= (String) getNewValue(node, CharacterLiteral.ESCAPED_VALUE_PROPERTY);
+		TextEditGroup group = getEditGroup(node, CharacterLiteral.ESCAPED_VALUE_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), escapedSeq, group);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ClassInstanceCreation)
+	 */
+	public boolean visit(ClassInstanceCreation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteOptionalQualifier(node, ClassInstanceCreation.EXPRESSION_PROPERTY, node.getStartPosition());
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			pos= rewriteRequiredNode(node, INTERNAL_CIC_NAME_PROPERTY);
+		} else {
+			if (isChanged(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY)) {
+				try {
+					pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNamenew, pos); //after 'new'
+					rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " ", true, true); //$NON-NLS-1$
+				} catch (CoreException e) {
+					handleException(e);
+				}
+			} else {
+				voidVisit(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY);
+			}
+			pos= rewriteRequiredNode(node, ClassInstanceCreation.TYPE_PROPERTY);
+		}
+
+		if (isChanged(node, ClassInstanceCreation.ARGUMENTS_PROPERTY)) {
+			try {
+				int startpos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, ClassInstanceCreation.ARGUMENTS_PROPERTY, startpos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, ClassInstanceCreation.ARGUMENTS_PROPERTY);
+		}
+
+		int kind= getChangeKind(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+		if (kind == RewriteEvent.REMOVED) {
+			try {
+				pos= getScanner().getPreviousTokenEndOffset(TerminalTokens.TokenNameLBRACE, pos);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			pos= node.getStartPosition() + node.getLength(); // insert pos
+		}
+		rewriteNode(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY, pos, ASTRewriteFormatter.SPACE);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ConditionalExpression)
+	 */
+	public boolean visit(ConditionalExpression node) { // expression ? thenExpression : elseExpression
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, ConditionalExpression.EXPRESSION_PROPERTY);
+		rewriteRequiredNode(node, ConditionalExpression.THEN_EXPRESSION_PROPERTY);
+		rewriteRequiredNode(node, ConditionalExpression.ELSE_EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ConstructorInvocation)
+	 */
+	public boolean visit(ConstructorInvocation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= node.getStartPosition();
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, false, false); 
+		}
+		try {
+			pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+			rewriteNodeList(node, ConstructorInvocation.ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ContinueStatement)
+	 */
+	public boolean visit(ContinueStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		try {
+			int offset= getScanner().getTokenEndOffset(TerminalTokens.TokenNamecontinue, node.getStartPosition());
+			rewriteNode(node, ContinueStatement.LABEL_PROPERTY, offset, ASTRewriteFormatter.SPACE); // space between continue and label
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	private void visitReferenceTypeArguments(ASTNode node, StructuralPropertyDescriptor childProperty, int pos) {
+		if (isChanged(node, childProperty)) {
+			try {
+				pos = getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON_COLON, pos);
+				rewriteOptionalTypeParameters(node, childProperty, pos, Util.EMPTY_STRING, false, false);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(CreationReference)
+	 */
+	public boolean visit(CreationReference node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, CreationReference.TYPE_PROPERTY);
+		visitReferenceTypeArguments(node, CreationReference.TYPE_ARGUMENTS_PROPERTY, pos);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(DoStatement)
+	 */
+	public boolean visit(DoStatement node) { // do statement while expression
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= node.getStartPosition();
+		try {
+			RewriteEvent event= getEvent(node, DoStatement.BODY_PROPERTY);
+			if (event != null && event.getChangeKind() == RewriteEvent.REPLACED) {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNamedo, pos);
+				ASTNode body= (ASTNode) event.getOriginalValue();
+				int bodyEnd= body.getStartPosition() + body.getLength();
+				int endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNamewhile, bodyEnd);
+				rewriteBodyNode(node, DoStatement.BODY_PROPERTY, startOffset, endPos, getIndent(node.getStartPosition()), this.formatter.DO_BLOCK); // body
+			} else {
+				voidVisit(node, DoStatement.BODY_PROPERTY);
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+
+		rewriteRequiredNode(node, DoStatement.EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(EmptyStatement)
+	 */
+	public boolean visit(EmptyStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		changeNotSupported(node); // no modification possible
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ExpressionStatement)
+	 */
+	public boolean visit(ExpressionStatement node) { // expression
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, ExpressionStatement.EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(FieldAccess)
+	 */
+	public boolean visit(FieldAccess node) { // expression.name
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, FieldAccess.EXPRESSION_PROPERTY); // expression
+		rewriteRequiredNode(node, FieldAccess.NAME_PROPERTY); // name
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(FieldDeclaration)
+	 */
+	public boolean visit(FieldDeclaration node) { //{ Modifier } Type VariableDeclarationFragment { ',' VariableDeclarationFragment } ';'
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, FieldDeclaration.JAVADOC_PROPERTY);
+
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_FIELD_MODIFIERS_PROPERTY, pos);
+		} else {
+			rewriteModifiers2(node, FieldDeclaration.MODIFIERS2_PROPERTY, pos);
+		}
+
+		pos= rewriteRequiredNode(node, FieldDeclaration.TYPE_PROPERTY);
+		ensureSpaceAfterReplace(node, FieldDeclaration.TYPE_PROPERTY);
+		rewriteNodeList(node, FieldDeclaration.FRAGMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ForStatement)
+	 */
+	public boolean visit(ForStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		try {
+			int pos= node.getStartPosition();
+
+			if (isChanged(node, ForStatement.INITIALIZERS_PROPERTY)) {
+				// position after opening parent
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				pos= rewriteNodeList(node, ForStatement.INITIALIZERS_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} else {
+				pos= doVisit(node, ForStatement.INITIALIZERS_PROPERTY, pos);
+			}
+
+			// position after first semicolon
+			pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameSEMICOLON, pos);
+
+			pos= rewriteNode(node, ForStatement.EXPRESSION_PROPERTY, pos, ASTRewriteFormatter.NONE);
+
+			if (isChanged(node, ForStatement.UPDATERS_PROPERTY)) {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameSEMICOLON, pos);
+				pos= rewriteNodeList(node, ForStatement.UPDATERS_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} else {
+				pos= doVisit(node, ForStatement.UPDATERS_PROPERTY, pos);
+			}
+
+			RewriteEvent bodyEvent= getEvent(node, ForStatement.BODY_PROPERTY);
+			if (bodyEvent != null && bodyEvent.getChangeKind() == RewriteEvent.REPLACED) {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos);
+				rewriteBodyNode(node, ForStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.FOR_BLOCK); // body
+			} else {
+				voidVisit(node, ForStatement.BODY_PROPERTY);
+			}
+
+		} catch (CoreException e) {
+			handleException(e);
+		}
+
+
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(IfStatement)
+	 */
+	public boolean visit(IfStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, IfStatement.EXPRESSION_PROPERTY); // statement
+
+		RewriteEvent thenEvent= getEvent(node, IfStatement.THEN_STATEMENT_PROPERTY);
+		int elseChange= getChangeKind(node, IfStatement.ELSE_STATEMENT_PROPERTY);
+
+		if (thenEvent != null && thenEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			try {
+				int tok= getScanner().readNext(pos, true); // after the closing parent
+				pos= (tok == TerminalTokens.TokenNameRPAREN) ? getScanner().getCurrentEndOffset() : getScanner().getCurrentStartOffset();
+				
+				int indent= getIndent(node.getStartPosition());
+
+				int endPos= -1;
+				Object elseStatement= getOriginalValue(node, IfStatement.ELSE_STATEMENT_PROPERTY);
+				if (elseStatement != null) {
+					ASTNode thenStatement = (ASTNode) thenEvent.getOriginalValue();
+					endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNameelse, thenStatement.getStartPosition() + thenStatement.getLength()); // else keyword
+				}
+				if (elseStatement == null || elseChange != RewriteEvent.UNCHANGED) {
+					pos= rewriteBodyNode(node, IfStatement.THEN_STATEMENT_PROPERTY, pos, endPos, indent, this.formatter.IF_BLOCK_NO_ELSE);
+				} else {
+					pos= rewriteBodyNode(node, IfStatement.THEN_STATEMENT_PROPERTY, pos, endPos, indent, this.formatter.IF_BLOCK_WITH_ELSE);
+				}
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			pos= doVisit(node, IfStatement.THEN_STATEMENT_PROPERTY, pos);
+		}
+
+		if (elseChange != RewriteEvent.UNCHANGED) {
+			int indent= getIndent(node.getStartPosition());
+			Object newThen= getNewValue(node, IfStatement.THEN_STATEMENT_PROPERTY);
+			if (newThen instanceof Block) {
+				rewriteBodyNode(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos, -1, indent, this.formatter.ELSE_AFTER_BLOCK);
+			} else {
+				rewriteBodyNode(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos, -1, indent, this.formatter.ELSE_AFTER_STATEMENT);
+			}
+		} else {
+			pos= doVisit(node, IfStatement.ELSE_STATEMENT_PROPERTY, pos);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ImportDeclaration)
+	 */
+	public boolean visit(ImportDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			RewriteEvent event= getEvent(node, ImportDeclaration.STATIC_PROPERTY);
+			if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+				try {
+					int pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameimport, node.getStartPosition());
+					boolean wasStatic= ((Boolean) event.getOriginalValue()).booleanValue();
+					if (wasStatic) {
+						int endPos= getScanner().getTokenEndOffset(TerminalTokens.TokenNamestatic, pos);
+						doTextRemove(pos, endPos - pos, getEditGroup(event));
+					} else {
+						doTextInsert(pos, " static", getEditGroup(event)); //$NON-NLS-1$
+					}
+				} catch (CoreException e) {
+					handleException(e);
+				}
+			}
+		}
+
+		int pos= rewriteRequiredNode(node, ImportDeclaration.NAME_PROPERTY);
+
+		RewriteEvent event= getEvent(node, ImportDeclaration.ON_DEMAND_PROPERTY);
+		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+			boolean isOnDemand= ((Boolean) event.getOriginalValue()).booleanValue();
+			if (!isOnDemand) {
+				doTextInsert(pos, ".*", getEditGroup(event)); //$NON-NLS-1$
+			} else {
+				try {
+					int endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNameSEMICOLON, pos);
+					doTextRemove(pos, endPos - pos, getEditGroup(event));
+				} catch (CoreException e) {
+					handleException(e);
+				}
+			}
+		}
+		return false;
+	}
+
+
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(InfixExpression)
+	 */
+	public boolean visit(InfixExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, InfixExpression.LEFT_OPERAND_PROPERTY);
+
+		boolean needsNewOperation= isChanged(node, InfixExpression.OPERATOR_PROPERTY);
+		String operation= getNewValue(node, InfixExpression.OPERATOR_PROPERTY).toString();
+		if (needsNewOperation) {
+			replaceOperation(pos, operation, getEditGroup(node, InfixExpression.OPERATOR_PROPERTY));
+		}
+
+		pos= rewriteRequiredNode(node, InfixExpression.RIGHT_OPERAND_PROPERTY);
+
+		RewriteEvent event= getEvent(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY);
+		String prefixString= ' ' + operation + ' ';
+
+		if (needsNewOperation) {
+			int startPos= pos;
+			TextEditGroup editGroup= getEditGroup(node, InfixExpression.OPERATOR_PROPERTY);
+
+			if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+				RewriteEvent[] extendedOperands= event.getChildren();
+				for (int i= 0; i < extendedOperands.length; i++) {
+					RewriteEvent curr= extendedOperands[i];
+					ASTNode elem= (ASTNode) curr.getOriginalValue();
+					if (elem != null) {
+						if (curr.getChangeKind() != RewriteEvent.REPLACED) {
+							replaceOperation(startPos, operation, editGroup);
+						}
+						startPos= elem.getStartPosition() + elem.getLength();
+					}
+				}
+			} else {
+				List extendedOperands= (List) getOriginalValue(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY);
+				for (int i= 0; i < extendedOperands.size(); i++) {
+					ASTNode elem= (ASTNode) extendedOperands.get(i);
+					replaceOperation(startPos, operation, editGroup);
+					startPos= elem.getStartPosition() + elem.getLength();
+				}
+			}
+		}
+		rewriteNodeList(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY, pos, prefixString, prefixString);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Initializer)
+	 */
+	public boolean visit(Initializer node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, Initializer.JAVADOC_PROPERTY);
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_INITIALIZER_MODIFIERS_PROPERTY3, pos);
+		} else {
+			rewriteModifiers2(node, Initializer.MODIFIERS2_PROPERTY, pos);
+		}
+		rewriteRequiredNode(node, Initializer.BODY_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(InstanceofExpression)
+	 */
+	public boolean visit(InstanceofExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, InstanceofExpression.LEFT_OPERAND_PROPERTY);
+		ensureSpaceAfterReplace(node, InstanceofExpression.LEFT_OPERAND_PROPERTY);
+		rewriteRequiredNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY);
+		return false;
+	}
+
+	private void ensureSpaceAfterReplace(ASTNode node, ChildPropertyDescriptor desc) {
+		if (getChangeKind(node, desc) == RewriteEvent.REPLACED) {
+			int leftOperandEnd= getExtendedEnd((ASTNode) getOriginalValue(node, desc));
+			try {
+				int offset= getScanner().getNextStartOffset(leftOperandEnd, true); // instanceof
+
+				if (offset == leftOperandEnd) {
+					doTextInsert(offset, String.valueOf(' '), getEditGroup(node, desc));
+				}
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+	}
+	
+	private void ensureSpaceBeforeReplace(ASTNode node) {
+		if (this.beforeRequiredSpaceIndex  == -1) return;
+		
+		List events = this.eventStore.getChangedPropertieEvents(node);
+		
+		for (Iterator iterator = events.iterator(); iterator.hasNext();) {
+			RewriteEvent event = (RewriteEvent) iterator.next();
+			if (event.getChangeKind() == RewriteEvent.REPLACED && event.getOriginalValue() instanceof ASTNode) {
+				if (this.beforeRequiredSpaceIndex  == getExtendedOffset((ASTNode) event.getOriginalValue())) {
+					doTextInsert(this.beforeRequiredSpaceIndex , String.valueOf(' '), getEditGroup(event));
+					this.beforeRequiredSpaceIndex  = -1;
+					return;
+				}
+			}
+		}
+		
+		if (this.beforeRequiredSpaceIndex  < getExtendedOffset(node)) {
+			this.beforeRequiredSpaceIndex  = -1;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(IntersectionType)
+	 */
+	public boolean visit(IntersectionType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteNodeList(node, IntersectionType.TYPES_PROPERTY, node.getStartPosition(), Util.EMPTY_STRING, " & "); //$NON-NLS-1$
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(Javadoc)
+	 */
+	public boolean visit(Javadoc node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int startPos= node.getStartPosition() + 3;
+		String separator= getLineDelimiter() + getIndentAtOffset(node.getStartPosition())  + " * "; //$NON-NLS-1$
+
+		rewriteNodeList(node, Javadoc.TAGS_PROPERTY, startPos, separator, separator);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(LabeledStatement)
+	 */
+	public boolean visit(LabeledStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, LabeledStatement.LABEL_PROPERTY);
+		rewriteRequiredNode(node, LabeledStatement.BODY_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(LambdaExpression)
+	 */
+	public boolean visit(LambdaExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		Boolean newValue = (Boolean) getNewValue(node, LambdaExpression.PARENTHESES_PROPERTY);
+		boolean hasParentheses = newValue.equals(Boolean.TRUE);
+		if (!hasParentheses) {// Parentheses can be absent if and only if there is one and only one type elided parameter.
+			List parameters = (List) getNewValue(node, LambdaExpression.PARAMETERS_PROPERTY);
+			hasParentheses = !(parameters.size() == 1 && parameters.get(0) instanceof VariableDeclarationFragment);
+		}
+
+		boolean deleteParentheses = false;
+		boolean insertParentheses = false;
+		TextEditGroup editGroup = null;
+
+		boolean oldHasParentheses = getOriginalValue(node, LambdaExpression.PARENTHESES_PROPERTY).equals(Boolean.TRUE);
+		RewriteEvent event = getEvent(node, LambdaExpression.PARENTHESES_PROPERTY);
+		if (event != null) {
+			editGroup = getEditGroup(event);
+			if (event.getChangeKind() == RewriteEvent.REPLACED) {
+				if (newValue != Boolean.FALSE) {
+					insertParentheses = true;
+				} else {// apply the stricter check for parentheses deletion
+					deleteParentheses = !hasParentheses;
+				}
+			}
+		} else if (!oldHasParentheses && hasParentheses) {// parameter property changed to effect parentheses insertion
+			if ((event = getEvent(node, LambdaExpression.PARAMETERS_PROPERTY)) != null) {// a null check though event cannot be null here
+				editGroup = getEditGroup(event);
+				insertParentheses = true;
+			}
+		}
+		
+		int pos = node.getStartPosition();
+		if (insertParentheses) {
+			doTextInsert(pos, "(", editGroup); //$NON-NLS-1$
+		} else if (deleteParentheses) {
+			try {
+				int lparensEnd = getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				doTextRemove(pos, lparensEnd - pos, editGroup);
+				pos = lparensEnd;
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+
+		if (isChanged(node, LambdaExpression.PARAMETERS_PROPERTY)) {
+			try {
+				pos = oldHasParentheses ? getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos) : pos;
+				pos = rewriteNodeList(node, LambdaExpression.PARAMETERS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			pos = doVisit(node, LambdaExpression.PARAMETERS_PROPERTY, pos);
+		}
+
+		if (insertParentheses) {
+			doTextInsert(pos, ")", editGroup); //$NON-NLS-1$
+		} else if (deleteParentheses) {
+			try {
+				doTextRemove(pos, getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos) - pos, editGroup);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+		rewriteRequiredNode(node, LambdaExpression.BODY_PROPERTY);
+
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(MethodInvocation)
+	 */
+	public boolean visit(MethodInvocation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteOptionalQualifier(node, MethodInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, false, false); 
+		}
+
+		pos= rewriteRequiredNode(node, MethodInvocation.NAME_PROPERTY);
+
+		if (isChanged(node, MethodInvocation.ARGUMENTS_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, MethodInvocation.ARGUMENTS_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, MethodInvocation.ARGUMENTS_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(NullLiteral)
+	 */
+	public boolean visit(NullLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		changeNotSupported(node); // no modification possible
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(NumberLiteral)
+	 */
+	public boolean visit(NumberLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		String newLiteral= (String) getNewValue(node, NumberLiteral.TOKEN_PROPERTY);
+		TextEditGroup group = getEditGroup(node, NumberLiteral.TOKEN_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newLiteral, group);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PackageDeclaration)
+	 */
+	public boolean visit(PackageDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			int pos= rewriteJavadoc(node, PackageDeclaration.JAVADOC_PROPERTY);
+			rewriteModifiers2(node, PackageDeclaration.ANNOTATIONS_PROPERTY, pos);
+		}
+
+		rewriteRequiredNode(node, PackageDeclaration.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ParenthesizedExpression)
+	 */
+	public boolean visit(ParenthesizedExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, ParenthesizedExpression.EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PostfixExpression)
+	 */
+	public boolean visit(PostfixExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, PostfixExpression.OPERAND_PROPERTY);
+		rewriteOperation(node, PostfixExpression.OPERATOR_PROPERTY, pos);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PrefixExpression)
+	 */
+	public boolean visit(PrefixExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteOperation(node, PrefixExpression.OPERATOR_PROPERTY, node.getStartPosition());
+		rewriteRequiredNode(node, PrefixExpression.OPERAND_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(PrimitiveType)
+	 */
+	public boolean visit(PrimitiveType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			rewriteTypeAnnotations(node, PrimitiveType.ANNOTATIONS_PROPERTY, node.getStartPosition());
+		}
+		PrimitiveType.Code newCode= (PrimitiveType.Code) getNewValue(node, PrimitiveType.PRIMITIVE_TYPE_CODE_PROPERTY);
+		TextEditGroup group = getEditGroup(node, PrimitiveType.PRIMITIVE_TYPE_CODE_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newCode.toString(), group);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(QualifiedName)
+	 */
+	public boolean visit(QualifiedName node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, QualifiedName.QUALIFIER_PROPERTY);
+		rewriteRequiredNode(node, QualifiedName.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SimpleName)
+	 */
+	public boolean visit(SimpleName node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		String newString= (String) getNewValue(node, SimpleName.IDENTIFIER_PROPERTY);
+		TextEditGroup group = getEditGroup(node, SimpleName.IDENTIFIER_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newString, group);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SimpleType)
+	 */
+	public boolean visit(SimpleType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			rewriteTypeAnnotations(node, SimpleType.ANNOTATIONS_PROPERTY, node.getStartPosition());
+		}
+		rewriteRequiredNode(node, SimpleType.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SingleVariableDeclaration)
+	 */
+	public boolean visit(SingleVariableDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= node.getStartPosition();
+		int apiLevel= node.getAST().apiLevel();
+		if (apiLevel == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_VARIABLE_MODIFIERS_PROPERTY, pos);
+		} else {
+			rewriteModifiers2(node, SingleVariableDeclaration.MODIFIERS2_PROPERTY, pos);
+		}
+		pos= rewriteRequiredNode(node, SingleVariableDeclaration.TYPE_PROPERTY);
+		if (apiLevel >= JLS3_INTERNAL) {
+			if (isChanged(node, SingleVariableDeclaration.VARARGS_PROPERTY)) {
+				TextEditGroup editGroup = getEditGroup(node, SingleVariableDeclaration.VARARGS_PROPERTY);
+				if (getNewValue(node, SingleVariableDeclaration.VARARGS_PROPERTY).equals(Boolean.TRUE)) {
+					if (apiLevel >= AST.JLS8) {
+						pos= rewriteVarargsAnnotations(node, SingleVariableDeclaration.VARARGS_ANNOTATIONS_PROPERTY, pos);
+					}
+					int indent= getIndent(node.getStartPosition());
+					String prefix= this.formatter.VARARGS.getPrefix(indent);
+					doTextInsert(pos, prefix, editGroup);
+					doTextInsert(pos, "...", editGroup); //$NON-NLS-1$
+				} else {
+					try {
+						int ellipsisEnd;
+						int noOfAnnotations = apiLevel >= AST.JLS8 ? node.varargsAnnotations().size() : 0;
+						if (noOfAnnotations > 0) {
+							Annotation annotation= (Annotation) node.varargsAnnotations().get(noOfAnnotations - 1);
+							int annotationEndPosition= annotation.getStartPosition() + annotation.getLength();
+							ellipsisEnd= getScanner().getNextEndOffset(annotationEndPosition, true);
+						} else {
+							ellipsisEnd= getScanner().getNextEndOffset(pos, true);
+						}
+						doTextRemove(pos, ellipsisEnd - pos, editGroup);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+				}
+			} else {
+				if (apiLevel >= AST.JLS8 && node.isVarargs()) {
+					pos = rewriteVarargsAnnotations(node, SingleVariableDeclaration.VARARGS_ANNOTATIONS_PROPERTY, pos);
+				}
+			}
+			if (!node.isVarargs()) {
+				ensureSpaceAfterReplace(node, SingleVariableDeclaration.TYPE_PROPERTY);
+			}
+		} else {
+			ensureSpaceAfterReplace(node, SingleVariableDeclaration.TYPE_PROPERTY);
+		}
+
+		pos= rewriteRequiredNode(node, SingleVariableDeclaration.NAME_PROPERTY);
+		if (apiLevel < AST.JLS8) {
+			int extraDims= rewriteExtraDimensions(node, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY, pos);
+
+			if (extraDims > 0) {
+				int kind= getChangeKind(node, SingleVariableDeclaration.INITIALIZER_PROPERTY);
+				if (kind == RewriteEvent.REMOVED) {
+					try {
+						pos= getScanner().getPreviousTokenEndOffset(TerminalTokens.TokenNameEQUAL, pos);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+				} else {
+					pos= node.getStartPosition() + node.getLength(); // insert pos
+				}
+			}
+		} else {
+			pos = rewriteExtraDimensionsInfo(node, pos, SingleVariableDeclaration.EXTRA_DIMENSIONS2_PROPERTY);
+		}
+
+		rewriteNode(node, SingleVariableDeclaration.INITIALIZER_PROPERTY, pos, this.formatter.VAR_INITIALIZER);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(StringLiteral)
+	 */
+	public boolean visit(StringLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		String escapedSeq= (String) getNewValue(node, StringLiteral.ESCAPED_VALUE_PROPERTY);
+		TextEditGroup group = getEditGroup(node, StringLiteral.ESCAPED_VALUE_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), escapedSeq, group);
+
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperConstructorInvocation)
+	 */
+	public boolean visit(SuperConstructorInvocation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteOptionalQualifier(node, SuperConstructorInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
+
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, false, false); 
+		}
+
+		if (isChanged(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperFieldAccess)
+	 */
+	public boolean visit(SuperFieldAccess node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteOptionalQualifier(node, SuperFieldAccess.QUALIFIER_PROPERTY, node.getStartPosition());
+		rewriteRequiredNode(node, SuperFieldAccess.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperMethodInvocation)
+	 */
+	public boolean visit(SuperMethodInvocation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteOptionalQualifier(node, SuperMethodInvocation.QUALIFIER_PROPERTY, node.getStartPosition());
+
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			if (isChanged(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY)) {
+				try {
+					pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+					rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, false, false); 
+				} catch (CoreException e) {
+					handleException(e);
+				}
+			}
+		}
+
+		pos= rewriteRequiredNode(node, SuperMethodInvocation.NAME_PROPERTY);
+
+		if (isChanged(node, SuperMethodInvocation.ARGUMENTS_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, SuperMethodInvocation.ARGUMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, SuperMethodInvocation.ARGUMENTS_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SwitchCase)
+	 */
+	public boolean visit(SwitchCase node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		// dont allow switching from case to default or back. New statements should be created.
+		rewriteRequiredNode(node, SwitchCase.EXPRESSION_PROPERTY);
+		return false;
+	}
+
+	class SwitchListRewriter extends ParagraphListRewriter {
+		
+		private boolean indentSwitchStatementsCompareToCases;
+
+		public SwitchListRewriter(int initialIndent) {
+			super(initialIndent, 0);
+			this.indentSwitchStatementsCompareToCases = 
+				DefaultCodeFormatterConstants.TRUE.equals(ASTRewriteAnalyzer.this.options.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES));
+		}
+
+		protected int getNodeIndent(int nodeIndex) {
+			int indent= getInitialIndent();
+			
+			if (this.indentSwitchStatementsCompareToCases) {
+				RewriteEvent event = this.list[nodeIndex];
+				int changeKind = event.getChangeKind();
+				
+				ASTNode node;
+				if (changeKind == RewriteEvent.INSERTED || changeKind == RewriteEvent.REPLACED) {
+					node= (ASTNode)event.getNewValue();
+				} else {
+					node= (ASTNode)event.getOriginalValue();
+				}
+				
+				if (node.getNodeType() != ASTNode.SWITCH_CASE) {
+					indent++;
+				}
+			}
+			return indent;
+		}
+		
+		protected String getSeparatorString(int nodeIndex) {
+			int total = this.list.length;
+			
+			int nextNodeIndex = nodeIndex + 1;
+			while (nextNodeIndex < total && this.list[nextNodeIndex].getChangeKind() == RewriteEvent.REMOVED) {
+				nextNodeIndex++;
+			}
+			if (nextNodeIndex == total) {
+				return super.getSeparatorString(nodeIndex);
+			}
+			return getSeparatorString(nodeIndex, nextNodeIndex);
+		}
+		
+		protected void updateIndent(int prevMark, int originalOffset, int nodeIndex, TextEditGroup editGroup) {
+			if (prevMark != RewriteEvent.UNCHANGED && prevMark != RewriteEvent.REPLACED) return;
+			
+			// Do not change indent if the previous non removed node is on the same line
+			int previousNonRemovedNodeIndex = nodeIndex - 1;
+			while (previousNonRemovedNodeIndex >= 0 && this.list[previousNonRemovedNodeIndex].getChangeKind() == RewriteEvent.REMOVED) {
+				previousNonRemovedNodeIndex--;
+			}
+			
+			if (previousNonRemovedNodeIndex > -1) {
+				LineInformation lineInformation = getLineInformation();
+				
+				RewriteEvent prevEvent = this.list[previousNonRemovedNodeIndex];
+				int prevKind = prevEvent.getChangeKind();
+				if (prevKind == RewriteEvent.UNCHANGED || prevKind == RewriteEvent.REPLACED) {
+					ASTNode prevNode = (ASTNode) this.list[previousNonRemovedNodeIndex].getOriginalValue();
+					int prevEndPosition = prevNode.getStartPosition() + prevNode.getLength();
+					int prevLine = lineInformation.getLineOfOffset(prevEndPosition);
+					int line = lineInformation.getLineOfOffset(originalOffset);
+					
+					if (prevLine == line) {
+						return;
+					}
+				}
+			}
+			
+			int total = this.list.length;
+			while (nodeIndex < total && this.list[nodeIndex].getChangeKind() == RewriteEvent.REMOVED) {
+				nodeIndex++;
+			}
+			
+			int originalIndent = getIndent(originalOffset);
+			int newIndent = getNodeIndent(nodeIndex);
+			
+			if (originalIndent != newIndent) {
+				
+				int line= getLineInformation().getLineOfOffset(originalOffset);
+				if (line >= 0) {
+					int lineStart= getLineInformation().getLineOffset(line);
+					
+					doTextRemove(lineStart, originalOffset - lineStart, editGroup); // remove previous indentation
+					doTextInsert(lineStart, createIndentString(newIndent), editGroup); // add new indentation
+				}
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SwitchStatement)
+	 */
+	public boolean visit(SwitchStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, SwitchStatement.EXPRESSION_PROPERTY);
+
+		ChildListPropertyDescriptor property= SwitchStatement.STATEMENTS_PROPERTY;
+		if (getChangeKind(node, property) != RewriteEvent.UNCHANGED) {
+			try {
+				pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLBRACE, pos);
+				int insertIndent= getIndent(node.getStartPosition());
+				if (DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH))) {
+					insertIndent++;
+				}
+				
+				ParagraphListRewriter listRewriter= new SwitchListRewriter(insertIndent);
+				StringBuffer leadString= new StringBuffer();
+				leadString.append(getLineDelimiter());
+				leadString.append(createIndentString(insertIndent));
+				listRewriter.rewriteList(node, property, pos, leadString.toString());
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, SwitchStatement.STATEMENTS_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SynchronizedStatement)
+	 */
+	public boolean visit(SynchronizedStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, SynchronizedStatement.EXPRESSION_PROPERTY);
+		rewriteRequiredNode(node, SynchronizedStatement.BODY_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ThisExpression)
+	 */
+	public boolean visit(ThisExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteOptionalQualifier(node, ThisExpression.QUALIFIER_PROPERTY, node.getStartPosition());
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ThrowStatement)
+	 */
+	public boolean visit(ThrowStatement node) {
+		try {
+			this.beforeRequiredSpaceIndex = getScanner().getTokenEndOffset(TerminalTokens.TokenNamethrow, node.getStartPosition());
+			
+			if (!hasChildrenChanges(node)) {
+				return doVisitUnchangedChildren(node);
+			}
+			
+			ensureSpaceBeforeReplace(node);
+
+			rewriteRequiredNode(node, ThrowStatement.EXPRESSION_PROPERTY);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TryStatement)
+	 */
+	public boolean visit(TryStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= node.getStartPosition();
+		if (node.getAST().apiLevel() >= JLS4_INTERNAL) {
+			if (isChanged(node, TryStatement.RESOURCES_PROPERTY)) {
+				int indent= getIndent(node.getStartPosition());
+				String prefix= this.formatter.TRY_RESOURCES.getPrefix(indent);
+				String newParen = this.formatter.TRY_RESOURCES_PAREN.getPrefix(indent) + "("; //$NON-NLS-1$
+				pos= rewriteNodeList(node, TryStatement.RESOURCES_PROPERTY, getPosAfterTry(pos), newParen, ")", ";" + prefix); //$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				pos= doVisit(node, TryStatement.RESOURCES_PROPERTY, pos);
+			}
+		}
+
+		pos= rewriteRequiredNode(node, TryStatement.BODY_PROPERTY);
+		
+		if (isChanged(node, TryStatement.CATCH_CLAUSES_PROPERTY)) {
+			int indent= getIndent(node.getStartPosition());
+			String prefix= this.formatter.CATCH_BLOCK.getPrefix(indent);
+			pos= rewriteNodeList(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos, prefix, prefix);
+		} else {
+			pos= doVisit(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos);
+		}
+		rewriteNode(node, TryStatement.FINALLY_PROPERTY, pos, this.formatter.FINALLY_BLOCK);
+		return false;
+	}
+
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeDeclarationStatement)
+	 */
+	public boolean visit(TypeDeclarationStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			rewriteRequiredNode(node, INTERNAL_TDS_TYPE_DECLARATION_PROPERTY);
+		} else {
+			rewriteRequiredNode(node, TypeDeclarationStatement.DECLARATION_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeLiteral)
+	 */
+	public boolean visit(TypeLiteral node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		rewriteRequiredNode(node, TypeLiteral.TYPE_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(UnionType)
+	 */
+	public boolean visit(UnionType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteNodeList(node, UnionType.TYPES_PROPERTY, node.getStartPosition(), Util.EMPTY_STRING, " | "); //$NON-NLS-1$
+		return false;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationExpression)
+	 */
+	public boolean visit(VariableDeclarationExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		// same code as FieldDeclaration
+		int pos= node.getStartPosition();
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_VDE_MODIFIERS_PROPERTY, pos);
+		} else {
+			rewriteModifiers2(node, VariableDeclarationExpression.MODIFIERS2_PROPERTY, pos);
+		}
+		pos= rewriteRequiredNode(node, VariableDeclarationExpression.TYPE_PROPERTY);
+		rewriteNodeList(node, VariableDeclarationExpression.FRAGMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationFragment)
+	 */
+	public boolean visit(VariableDeclarationFragment node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, VariableDeclarationFragment.NAME_PROPERTY);
+
+		if (node.getAST().apiLevel() < AST.JLS8) {
+			int extraDims= rewriteExtraDimensions(node, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, pos);
+			if (extraDims > 0) {
+				int kind= getChangeKind(node, VariableDeclarationFragment.INITIALIZER_PROPERTY);
+				if (kind == RewriteEvent.REMOVED) {
+					try {
+						pos= getScanner().getPreviousTokenEndOffset(TerminalTokens.TokenNameEQUAL, pos);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+				} else {
+					pos= node.getStartPosition() + node.getLength(); // insert pos
+				}
+			}
+		} else {
+			pos = rewriteExtraDimensionsInfo(node, pos, VariableDeclarationFragment.EXTRA_DIMENSIONS2_PROPERTY);
+		}
+		rewriteNode(node, VariableDeclarationFragment.INITIALIZER_PROPERTY, pos, this.formatter.VAR_INITIALIZER);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(VariableDeclarationStatement)
+	 */
+	public boolean visit(VariableDeclarationStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		// same code as FieldDeclaration
+		int pos= node.getStartPosition();
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			rewriteModifiers(node, INTERNAL_VDS_MODIFIERS_PROPERTY, pos);
+		} else {
+			rewriteModifiers2(node, VariableDeclarationStatement.MODIFIERS2_PROPERTY, pos);
+		}
+		pos= rewriteRequiredNode(node, VariableDeclarationStatement.TYPE_PROPERTY);
+
+		rewriteNodeList(node, VariableDeclarationStatement.FRAGMENTS_PROPERTY, pos, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(WhileStatement)
+	 */
+	public boolean visit(WhileStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, WhileStatement.EXPRESSION_PROPERTY);
+
+		try {
+			if (isChanged(node, WhileStatement.BODY_PROPERTY)) {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos);
+				rewriteBodyNode(node, WhileStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.WHILE_BLOCK); // body
+			} else {
+				voidVisit(node, WhileStatement.BODY_PROPERTY);
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef)
+	 */
+	public boolean visit(MemberRef node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteNode(node, MemberRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE);
+
+		rewriteRequiredNode(node, MemberRef.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef)
+	 */
+	public boolean visit(MethodRef node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteNode(node, MethodRef.QUALIFIER_PROPERTY, node.getStartPosition(), ASTRewriteFormatter.NONE);
+
+		int pos= rewriteRequiredNode(node, MethodRef.NAME_PROPERTY);
+
+		if (isChanged(node, MethodRef.PARAMETERS_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, MethodRef.PARAMETERS_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, MethodRef.PARAMETERS_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter)
+	 */
+	public boolean visit(MethodRefParameter node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, MethodRefParameter.TYPE_PROPERTY);
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			if (isChanged(node, MethodRefParameter.VARARGS_PROPERTY)) {
+				if (getNewValue(node, MethodRefParameter.VARARGS_PROPERTY).equals(Boolean.TRUE)) {
+					doTextInsert(pos, "...", getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$
+				} else {
+					try {
+						int ellipsisEnd= getScanner().getNextEndOffset(pos, true);
+						doTextRemove(pos, ellipsisEnd - pos, getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY));
+					} catch (CoreException e) {
+						handleException(e);
+					}
+				}
+			}
+		}
+		rewriteNode(node, MethodRefParameter.NAME_PROPERTY, pos, ASTRewriteFormatter.SPACE);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement)
+	 */
+	public boolean visit(TagElement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int changeKind= getChangeKind(node, TagElement.TAG_NAME_PROPERTY);
+		switch (changeKind) {
+			case RewriteEvent.INSERTED: {
+			    String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY);
+				doTextInsert(node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
+				break;
+			}
+			case RewriteEvent.REMOVED: {
+			    doTextRemove(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
+			    break;
+			}
+			case RewriteEvent.REPLACED: {
+			    String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY);
+		    	doTextReplace(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
+			    break;
+			}
+		}
+
+		if (isChanged(node, TagElement.FRAGMENTS_PROPERTY)) {
+			// eval position after name
+			int endOffset= findTagNameEnd(node);
+            rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, endOffset, " ", " ");  //$NON-NLS-1$//$NON-NLS-2$
+		} else {
+			voidVisit(node, TagElement.FRAGMENTS_PROPERTY);
+		}
+		return false;
+	}
+
+	private int findTagNameEnd(TagElement tagNode) {
+		if (tagNode.getTagName() != null) {
+			char[] cont= getContent();
+		    int len= cont.length;
+			int i= tagNode.getStartPosition();
+			while (i < len && !IndentManipulation.isIndentChar(cont[i])) {
+			    i++;
+			}
+			return i;
+		}
+	    return tagNode.getStartPosition();
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement)
+	 */
+	public boolean visit(TextElement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		String newText= (String) getNewValue(node, TextElement.TEXT_PROPERTY);
+		TextEditGroup group = getEditGroup(node, TextElement.TEXT_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newText, group);
+		return false;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
+	 */
+	public boolean visit(AnnotationTypeDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, AnnotationTypeDeclaration.JAVADOC_PROPERTY);
+		rewriteModifiers2(node, AnnotationTypeDeclaration.MODIFIERS2_PROPERTY, pos);
+		pos= rewriteRequiredNode(node, AnnotationTypeDeclaration.NAME_PROPERTY);
+
+		int startIndent= getIndent(node.getStartPosition()) + 1;
+		int startPos= getPosAfterLeftBrace(pos);
+		rewriteParagraphList(node, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY, startPos, startIndent, -1, 2);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration)
+	 */
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, AnnotationTypeMemberDeclaration.JAVADOC_PROPERTY);
+		rewriteModifiers2(node, AnnotationTypeMemberDeclaration.MODIFIERS2_PROPERTY, pos);
+		rewriteRequiredNode(node, AnnotationTypeMemberDeclaration.TYPE_PROPERTY);
+		pos= rewriteRequiredNode(node, AnnotationTypeMemberDeclaration.NAME_PROPERTY);
+
+		try {
+			int changeKind= getChangeKind(node, AnnotationTypeMemberDeclaration.DEFAULT_PROPERTY);
+			if (changeKind == RewriteEvent.INSERTED || changeKind == RewriteEvent.REMOVED) {
+				pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos);
+			}
+			rewriteNode(node, AnnotationTypeMemberDeclaration.DEFAULT_PROPERTY, pos, this.formatter.ANNOT_MEMBER_DEFAULT);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnhancedForStatement)
+	 */
+	public boolean visit(EnhancedForStatement node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteRequiredNode(node, EnhancedForStatement.PARAMETER_PROPERTY);
+		int pos= rewriteRequiredNode(node, EnhancedForStatement.EXPRESSION_PROPERTY);
+
+		RewriteEvent bodyEvent= getEvent(node, EnhancedForStatement.BODY_PROPERTY);
+		if (bodyEvent != null && bodyEvent.getChangeKind() == RewriteEvent.REPLACED) {
+			int startOffset;
+			try {
+				startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameRPAREN, pos);
+				rewriteBodyNode(node, EnhancedForStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.FOR_BLOCK); // body
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, EnhancedForStatement.BODY_PROPERTY);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
+	 */
+	public boolean visit(EnumConstantDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, EnumConstantDeclaration.JAVADOC_PROPERTY);
+		rewriteModifiers2(node, EnumConstantDeclaration.MODIFIERS2_PROPERTY, pos);
+		pos= rewriteRequiredNode(node, EnumConstantDeclaration.NAME_PROPERTY);
+		RewriteEvent argsEvent= getEvent(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY);
+		if (argsEvent != null && argsEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			RewriteEvent[] children= argsEvent.getChildren();
+			try {
+				int nextTok= getScanner().readNext(pos, true);
+				boolean hasParents= (nextTok == TerminalTokens.TokenNameLPAREN);
+				boolean isAllRemoved= hasParents && isAllOfKind(children, RewriteEvent.REMOVED);
+				String prefix= Util.EMPTY_STRING; 
+				if (!hasParents) {
+					prefix= "("; //$NON-NLS-1$
+				} else if (!isAllRemoved) {
+					pos= getScanner().getCurrentEndOffset();
+				}
+				pos= rewriteNodeList(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY, pos, prefix, ", "); //$NON-NLS-1$
+
+				if (!hasParents) {
+					doTextInsert(pos, ")", getEditGroup(children[children.length - 1])); //$NON-NLS-1$
+				} else if (isAllRemoved) {
+					int afterClosing= getScanner().getNextEndOffset(pos, true);
+					doTextRemove(pos, afterClosing - pos, getEditGroup(children[children.length - 1]));
+					pos= afterClosing;
+				}
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			pos= doVisit(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY, pos);
+		}
+
+		if (isChanged(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY)) {
+			int kind= getChangeKind(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+			if (kind == RewriteEvent.REMOVED) {
+				try {
+					// 'pos' can be before brace
+					pos= getScanner().getPreviousTokenEndOffset(TerminalTokens.TokenNameLBRACE, pos);
+				} catch (CoreException e) {
+					handleException(e);
+				}
+			} else {
+				pos= node.getStartPosition() + node.getLength(); // insert pos
+			}
+			rewriteNode(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY, pos, ASTRewriteFormatter.SPACE);
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration)
+	 */
+	public boolean visit(EnumDeclaration node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteJavadoc(node, EnumDeclaration.JAVADOC_PROPERTY);
+		rewriteModifiers2(node, EnumDeclaration.MODIFIERS2_PROPERTY, pos);
+		pos= rewriteRequiredNode(node, EnumDeclaration.NAME_PROPERTY);
+		pos= rewriteNodeList(node, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, pos, " implements ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+
+		pos= getPosAfterLeftBrace(pos);
+
+		String leadString= Util.EMPTY_STRING; 
+		RewriteEvent constEvent= getEvent(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
+
+		if (constEvent != null && constEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			RewriteEvent[] events= constEvent.getChildren();
+			if (isAllOfKind(events, RewriteEvent.INSERTED)) {
+				leadString= this.formatter.FIRST_ENUM_CONST.getPrefix(getIndent(node.getStartPosition()));
+			}
+		}
+		pos= rewriteNodeList(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY, pos, leadString, ", "); //$NON-NLS-1$
+
+		RewriteEvent bodyEvent= getEvent(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY);
+		int indent= 0;
+		if (bodyEvent != null && bodyEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			boolean hasConstants= !((List) getNewValue(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY)).isEmpty();
+
+			RewriteEvent[] children= bodyEvent.getChildren();
+			try {
+				if (hasConstants) {
+					indent= getIndent(pos);
+				} else {
+					indent= getIndent(node.getStartPosition()) + 1;
+				}
+				int token= getScanner().readNext(pos, true);
+				boolean hasSemicolon= token == TerminalTokens.TokenNameSEMICOLON;
+				if (!hasSemicolon && isAllOfKind(children, RewriteEvent.INSERTED)) {
+					if (!hasConstants) {
+						String str= this.formatter.FIRST_ENUM_CONST.getPrefix(indent - 1);
+						doTextInsert(pos, str, getEditGroup(children[0]));
+					}
+					if (token == TerminalTokens.TokenNameCOMMA) {
+						// a comma is at the end of the enum constant before a potential semicolon
+						int endPos= getScanner().getCurrentEndOffset();
+						int nextToken= getScanner().readNext(endPos, true);
+						if (nextToken != TerminalTokens.TokenNameSEMICOLON) {
+							doTextInsert(endPos, ";", getEditGroup(children[0])); //$NON-NLS-1$
+						} else {
+							endPos= getScanner().getCurrentEndOffset();
+							if (isAllOfKind(children, RewriteEvent.REMOVED)) {
+								doTextRemove(pos, endPos - pos, getEditGroup(children[0]));
+							}
+						}
+						pos= endPos;
+					} else {
+						doTextInsert(pos, ";", getEditGroup(children[0])); //$NON-NLS-1$
+					}
+				} else if (hasSemicolon) {
+					int endPos= getScanner().getCurrentEndOffset();
+					if (isAllOfKind(children, RewriteEvent.REMOVED)) {
+						doTextRemove(pos, endPos - pos, getEditGroup(children[0]));
+					}
+					pos= endPos;
+				}
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+		rewriteParagraphList(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY, pos, indent, -1, 2);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(ExpressionMethodReference)
+	 */
+	public boolean visit(ExpressionMethodReference node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, ExpressionMethodReference.EXPRESSION_PROPERTY);
+		visitReferenceTypeArguments(node, ExpressionMethodReference.TYPE_ARGUMENTS_PROPERTY, pos);
+		rewriteRequiredNode(node, ExpressionMethodReference.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MarkerAnnotation)
+	 */
+	public boolean visit(MarkerAnnotation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteRequiredNode(node, MarkerAnnotation.TYPE_NAME_PROPERTY);
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberValuePair)
+	 */
+	public boolean visit(MemberValuePair node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteRequiredNode(node, MemberValuePair.NAME_PROPERTY);
+		rewriteRequiredNode(node, MemberValuePair.VALUE_PROPERTY);
+
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Modifier)
+	 */
+	public boolean visit(Modifier node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		String newText= getNewValue(node, Modifier.KEYWORD_PROPERTY).toString(); // type Modifier.ModifierKeyword
+		TextEditGroup group = getEditGroup(node, Modifier.KEYWORD_PROPERTY);
+		doTextReplace(node.getStartPosition(), node.getLength(), newText, group);
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NormalAnnotation)
+	 */
+	public boolean visit(NormalAnnotation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, NormalAnnotation.TYPE_NAME_PROPERTY);
+		if (isChanged(node, NormalAnnotation.VALUES_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLPAREN, pos);
+				rewriteNodeList(node, NormalAnnotation.VALUES_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, NormalAnnotation.VALUES_PROPERTY);
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PackageQualifiedType)
+	 */
+	public boolean visit(PackageQualifiedType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos = rewriteRequiredNode(node, PackageQualifiedType.QUALIFIER_PROPERTY);
+		try {
+			pos = getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+			rewriteTypeAnnotations(node, PackageQualifiedType.ANNOTATIONS_PROPERTY, pos);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		rewriteRequiredNode(node, PackageQualifiedType.NAME_PROPERTY);
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParameterizedType)
+	 */
+	public boolean visit(ParameterizedType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, ParameterizedType.TYPE_PROPERTY);
+		if (isChanged(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY)) {
+			// eval position after opening parent
+			try {
+				int startOffset= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLESS, pos);
+				rewriteNodeList(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY, startOffset, Util.EMPTY_STRING, ", "); //$NON-NLS-1$ 
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedType)
+	 */
+	public boolean visit(QualifiedType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos = rewriteRequiredNode(node, QualifiedType.QUALIFIER_PROPERTY);
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			try {
+				pos = getScanner().getTokenEndOffset(TerminalTokens.TokenNameDOT, pos);
+				rewriteTypeAnnotations(node, QualifiedType.ANNOTATIONS_PROPERTY, pos);
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		}
+		rewriteRequiredNode(node, QualifiedType.NAME_PROPERTY);
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation)
+	 */
+	public boolean visit(SingleMemberAnnotation node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		rewriteRequiredNode(node, SingleMemberAnnotation.TYPE_NAME_PROPERTY);
+		rewriteRequiredNode(node, SingleMemberAnnotation.VALUE_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(SuperMethodReference)
+	 */
+	public boolean visit(SuperMethodReference node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos = rewriteOptionalQualifier(node, SuperMethodReference.QUALIFIER_PROPERTY, node.getStartPosition());
+		visitReferenceTypeArguments(node, SuperMethodReference.TYPE_ARGUMENTS_PROPERTY, pos);
+		rewriteRequiredNode(node, SuperMethodReference.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(TypeMethodReference)
+	 */
+	public boolean visit(TypeMethodReference node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos= rewriteRequiredNode(node, TypeMethodReference.TYPE_PROPERTY);
+		visitReferenceTypeArguments(node, TypeMethodReference.TYPE_ARGUMENTS_PROPERTY, pos);
+		rewriteRequiredNode(node, TypeMethodReference.NAME_PROPERTY);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
+	 */
+	public boolean visit(TypeParameter node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		int pos;
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			pos = rewriteTypeAnnotations(node, TypeParameter.ANNOTATIONS_PROPERTY, node.getStartPosition());
+		}
+		pos= rewriteRequiredNode(node, TypeParameter.NAME_PROPERTY);
+		rewriteNodeList(node, TypeParameter.TYPE_BOUNDS_PROPERTY, pos, " extends ", " & "); //$NON-NLS-1$ //$NON-NLS-2$
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WildcardType)
+	 */
+	public boolean visit(WildcardType node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			rewriteTypeAnnotations(node, WildcardType.ANNOTATIONS_PROPERTY, node.getStartPosition());
+		}
+		try {
+			int pos= getScanner().getNextEndOffset(node.getStartPosition(), true); // pos after question mark
+
+			Prefix prefix;
+			if (Boolean.TRUE.equals(getNewValue(node, WildcardType.UPPER_BOUND_PROPERTY))) {
+				prefix= this.formatter.WILDCARD_EXTENDS;
+			} else {
+				prefix= this.formatter.WILDCARD_SUPER;
+			}
+
+			int boundKindChange= getChangeKind(node, WildcardType.UPPER_BOUND_PROPERTY);
+			if (boundKindChange != RewriteEvent.UNCHANGED) {
+				int boundTypeChange= getChangeKind(node, WildcardType.BOUND_PROPERTY);
+				if (boundTypeChange != RewriteEvent.INSERTED && boundTypeChange != RewriteEvent.REMOVED) {
+					ASTNode type= (ASTNode) getOriginalValue(node, WildcardType.BOUND_PROPERTY);
+					String str= prefix.getPrefix(0);
+					doTextReplace(pos, type.getStartPosition() - pos, str, getEditGroup(node, WildcardType.BOUND_PROPERTY));
+				}
+			}
+			rewriteNode(node, WildcardType.BOUND_PROPERTY, pos, prefix);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return false;
+	}
+
+	final void handleException(Throwable e) {
+		IllegalArgumentException runtimeException= new IllegalArgumentException("Document does not match the AST"); //$NON-NLS-1$
+		runtimeException.initCause(e);
+		throw runtimeException;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
new file mode 100644
index 0000000..20f66e3
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -0,0 +1,1541 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ASTRewriteFlattener extends ASTVisitor {
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_FIELD_MODIFIERS_PROPERTY = FieldDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_INITIALIZER_MODIFIERS_PROPERTY = Initializer.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_METHOD_MODIFIERS_PROPERTY = MethodDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_METHOD_RETURN_TYPE_PROPERTY = MethodDeclaration.RETURN_TYPE_PROPERTY;
+	
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY = MethodDeclaration.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildListPropertyDescriptor INTERNAL_METHOD_THROWN_EXCEPTIONS_PROPERTY = MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_TYPE_MODIFIERS_PROPERTY = TypeDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_TYPE_SUPERCLASS_PROPERTY = TypeDeclaration.SUPERCLASS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildListPropertyDescriptor INTERNAL_TYPE_SUPER_INTERFACES_PROPERTY = TypeDeclaration.SUPER_INTERFACES_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_CIC_NAME_PROPERTY = ClassInstanceCreation.NAME_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY = VariableDeclarationFragment.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_TDS_TYPE_DECLARATION_PROPERTY = TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VARIABLE_MODIFIERS_PROPERTY = SingleVariableDeclaration.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY = SingleVariableDeclaration.EXTRA_DIMENSIONS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VDE_MODIFIERS_PROPERTY = VariableDeclarationExpression.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final SimplePropertyDescriptor INTERNAL_VDS_MODIFIERS_PROPERTY = VariableDeclarationStatement.MODIFIERS_PROPERTY;
+
+	/** @deprecated using deprecated code */
+	private static final int JLS2_INTERNAL = AST.JLS2;
+
+	/** @deprecated using deprecated code */
+	private static final int JLS3_INTERNAL = AST.JLS3;
+
+	/** @deprecated using deprecated code */
+	private static final int JLS4_INTERNAL = AST.JLS4;
+
+
+	public static String asString(ASTNode node, RewriteEventStore store) {
+		ASTRewriteFlattener flattener= new ASTRewriteFlattener(store);
+		node.accept(flattener);
+		return flattener.getResult();
+	}
+
+	protected StringBuffer result;
+	private RewriteEventStore store;
+
+	public ASTRewriteFlattener(RewriteEventStore store) {
+		this.store= store;
+		this.result= new StringBuffer();
+	}
+
+	/**
+	 * Returns the string accumulated in the visit.
+	 *
+	 * @return the serialized
+	 */
+	public String getResult() {
+		// convert to a string, but lose any extra space in the string buffer by copying
+		return new String(this.result.toString());
+	}
+
+	/**
+	 * Resets this printer so that it can be used again.
+	 */
+	public void reset() {
+		this.result.setLength(0);
+	}
+
+	/**
+	 * Appends the text representation of the given modifier flags, followed by a single space.
+	 *
+	 * @param modifiers the modifiers
+	 * @param buf The <code>StringBuffer</code> to write the result to.
+	 */
+	public static void printModifiers(int modifiers, StringBuffer buf) {
+		if (Modifier.isPublic(modifiers)) {
+			buf.append("public "); //$NON-NLS-1$
+		}
+		if (Modifier.isProtected(modifiers)) {
+			buf.append("protected "); //$NON-NLS-1$
+		}
+		if (Modifier.isPrivate(modifiers)) {
+			buf.append("private "); //$NON-NLS-1$
+		}
+		if (Modifier.isStatic(modifiers)) {
+			buf.append("static "); //$NON-NLS-1$
+		}
+		if (Modifier.isAbstract(modifiers)) {
+			buf.append("abstract "); //$NON-NLS-1$
+		}
+		if (Modifier.isFinal(modifiers)) {
+			buf.append("final "); //$NON-NLS-1$
+		}
+		if (Modifier.isSynchronized(modifiers)) {
+			buf.append("synchronized "); //$NON-NLS-1$
+		}
+		if (Modifier.isVolatile(modifiers)) {
+			buf.append("volatile "); //$NON-NLS-1$
+		}
+		if (Modifier.isNative(modifiers)) {
+			buf.append("native "); //$NON-NLS-1$
+		}
+		if (Modifier.isStrictfp(modifiers)) {
+			buf.append("strictfp "); //$NON-NLS-1$
+		}
+		if (Modifier.isTransient(modifiers)) {
+			buf.append("transient "); //$NON-NLS-1$
+		}
+	}
+
+	protected List getChildList(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		return (List) getAttribute(parent, childProperty);
+	}
+
+	protected ASTNode getChildNode(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		return (ASTNode) getAttribute(parent, childProperty);
+	}
+
+	protected int getIntAttribute(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		return ((Integer) getAttribute(parent, childProperty)).intValue();
+	}
+
+	protected boolean getBooleanAttribute(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		return ((Boolean) getAttribute(parent, childProperty)).booleanValue();
+	}
+
+	protected Object getAttribute(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		return this.store.getNewValue(parent, childProperty);
+	}
+
+	protected void visitList(ASTNode parent, StructuralPropertyDescriptor childProperty, String separator) {
+		List list= getChildList(parent, childProperty);
+		for (int i= 0; i < list.size(); i++) {
+			if (separator != null && i > 0) {
+				this.result.append(separator);
+			}
+			((ASTNode) list.get(i)).accept(this);
+		}
+	}
+
+	protected void visitList(ASTNode parent, StructuralPropertyDescriptor childProperty, String separator, String lead, String post) {
+		List list= getChildList(parent, childProperty);
+		if (!list.isEmpty()) {
+			this.result.append(lead);
+			for (int i= 0; i < list.size(); i++) {
+				if (separator != null && i > 0) {
+					this.result.append(separator);
+				}
+				((ASTNode) list.get(i)).accept(this);
+			}
+			this.result.append(post);
+		}
+	}
+
+	private void visitExtraDimensions(ASTNode node, SimplePropertyDescriptor dimensions, ChildListPropertyDescriptor dimensionsInfo) {
+		if (node.getAST().apiLevel() < AST.JLS8) {
+			int extraDimensions= getIntAttribute(node, dimensions);
+			for (int i = 0; i < extraDimensions; i++) {
+				this.result.append("[]"); //$NON-NLS-1$
+			}
+		} else {
+			visitList(node, dimensionsInfo, String.valueOf(' '), String.valueOf(' '), Util.EMPTY_STRING);
+		}
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AnonymousClassDeclaration)
+	 */
+	public boolean visit(AnonymousClassDeclaration node) {
+		this.result.append('{');
+		visitList(node, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY, null);
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayAccess)
+	 */
+	public boolean visit(ArrayAccess node) {
+		getChildNode(node, ArrayAccess.ARRAY_PROPERTY).accept(this);
+		this.result.append('[');
+		getChildNode(node, ArrayAccess.INDEX_PROPERTY).accept(this);
+		this.result.append(']');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayCreation)
+	 */
+	public boolean visit(ArrayCreation node) {
+		this.result.append("new "); //$NON-NLS-1$
+		ArrayType arrayType= (ArrayType) getChildNode(node, ArrayCreation.TYPE_PROPERTY);
+
+		// get the element type and count dimensions
+		Type elementType= (Type) getChildNode(arrayType, ArrayType.COMPONENT_TYPE_PROPERTY);
+		int dimensions= 1; // always include this array type
+		while (elementType.isArrayType()) {
+			dimensions++;
+			elementType = (Type) getChildNode(elementType, ArrayType.COMPONENT_TYPE_PROPERTY);
+		}
+
+		elementType.accept(this);
+
+		// add "<annotations> [ <dimension> ]" for each dimension expression
+		Type type= arrayType;
+		List list= getChildList(node, ArrayCreation.DIMENSIONS_PROPERTY);
+		for (int i= 0; i < list.size(); i++) {
+			if (node.getAST().apiLevel() >= AST.JLS8 && type instanceof ArrayType) {
+				visitList(type, ArrayType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+				type = (Type) getChildNode(type, ArrayType.COMPONENT_TYPE_PROPERTY);
+			}
+			this.result.append('[');
+			((ASTNode) list.get(i)).accept(this);
+			this.result.append(']');
+			dimensions--;
+		}
+
+		// add "<annotations> []" for each extra array dimension
+		for (int i= 0; i < dimensions; i++) {
+			if (node.getAST().apiLevel() >= AST.JLS8 && type instanceof ArrayType) {
+				visitList(type, ArrayType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+				type = (Type) getChildNode(type, ArrayType.COMPONENT_TYPE_PROPERTY);
+			}
+			this.result.append("[]"); //$NON-NLS-1$
+		}
+
+		ASTNode initializer= getChildNode(node, ArrayCreation.INITIALIZER_PROPERTY);
+		if (initializer != null) {
+			getChildNode(node, ArrayCreation.INITIALIZER_PROPERTY).accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayInitializer)
+	 */
+	public boolean visit(ArrayInitializer node) {
+		this.result.append('{');
+		visitList(node, ArrayInitializer.EXPRESSIONS_PROPERTY, String.valueOf(','));
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ArrayType)
+	 */
+	public boolean visit(ArrayType node) {
+		getChildNode(node, ArrayType.COMPONENT_TYPE_PROPERTY).accept(this);
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, ArrayType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		this.result.append("[]"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AssertStatement)
+	 */
+	public boolean visit(AssertStatement node) {
+		this.result.append("assert "); //$NON-NLS-1$
+		getChildNode(node, AssertStatement.EXPRESSION_PROPERTY).accept(this);
+
+		ASTNode message= getChildNode(node, AssertStatement.MESSAGE_PROPERTY);
+		if (message != null) {
+			this.result.append(':');
+			message.accept(this);
+		}
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Assignment)
+	 */
+	public boolean visit(Assignment node) {
+		getChildNode(node, Assignment.LEFT_HAND_SIDE_PROPERTY).accept(this);
+		this.result.append(getAttribute(node, Assignment.OPERATOR_PROPERTY).toString());
+		getChildNode(node, Assignment.RIGHT_HAND_SIDE_PROPERTY).accept(this);
+		return false;
+	}
+
+
+
+	/*
+	 * @see ASTVisitor#visit(Block)
+	 */
+	public boolean visit(Block node) {
+		this.result.append('{');
+		visitList(node, Block.STATEMENTS_PROPERTY, null);
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(BooleanLiteral)
+	 */
+	public boolean visit(BooleanLiteral node) {
+		if (node.booleanValue() == true) {
+			this.result.append("true"); //$NON-NLS-1$
+		} else {
+			this.result.append("false"); //$NON-NLS-1$
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(BreakStatement)
+	 */
+	public boolean visit(BreakStatement node) {
+		this.result.append("break"); //$NON-NLS-1$
+		ASTNode label= getChildNode(node, BreakStatement.LABEL_PROPERTY);
+		if (label != null) {
+			this.result.append(' ');
+			label.accept(this);
+		}
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CastExpression)
+	 */
+	public boolean visit(CastExpression node) {
+		this.result.append('(');
+		getChildNode(node, CastExpression.TYPE_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, CastExpression.EXPRESSION_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CatchClause)
+	 */
+	public boolean visit(CatchClause node) {
+		this.result.append("catch ("); //$NON-NLS-1$
+		getChildNode(node, CatchClause.EXCEPTION_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, CatchClause.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CharacterLiteral)
+	 */
+	public boolean visit(CharacterLiteral node) {
+		this.result.append(getAttribute(node, CharacterLiteral.ESCAPED_VALUE_PROPERTY));
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ClassInstanceCreation)
+	 */
+	public boolean visit(ClassInstanceCreation node) {
+		ASTNode expression= getChildNode(node, ClassInstanceCreation.EXPRESSION_PROPERTY);
+		if (expression != null) {
+			expression.accept(this);
+			this.result.append('.');
+		}
+		this.result.append("new ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			getChildNode(node, INTERNAL_CIC_NAME_PROPERTY).accept(this);
+		} else {
+			visitList(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+			getChildNode(node, ClassInstanceCreation.TYPE_PROPERTY).accept(this);
+		}
+
+		this.result.append('(');
+		visitList(node, ClassInstanceCreation.ARGUMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(')');
+		ASTNode decl= getChildNode(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+		if (decl != null) {
+			decl.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CompilationUnit)
+	 */
+	public boolean visit(CompilationUnit node) {
+		ASTNode pack= getChildNode(node, CompilationUnit.PACKAGE_PROPERTY);
+		if (pack != null) {
+			pack.accept(this);
+		}
+		visitList(node, CompilationUnit.IMPORTS_PROPERTY, null);
+		visitList(node, CompilationUnit.TYPES_PROPERTY, null);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ConditionalExpression)
+	 */
+	public boolean visit(ConditionalExpression node) {
+		getChildNode(node, ConditionalExpression.EXPRESSION_PROPERTY).accept(this);
+		this.result.append('?');
+		getChildNode(node, ConditionalExpression.THEN_EXPRESSION_PROPERTY).accept(this);
+		this.result.append(':');
+		getChildNode(node, ConditionalExpression.ELSE_EXPRESSION_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ConstructorInvocation)
+	 */
+	public boolean visit(ConstructorInvocation node) {
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			visitList(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+		this.result.append("this("); //$NON-NLS-1$
+		visitList(node, ConstructorInvocation.ARGUMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(");"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ContinueStatement)
+	 */
+	public boolean visit(ContinueStatement node) {
+		this.result.append("continue"); //$NON-NLS-1$
+		ASTNode label= getChildNode(node, ContinueStatement.LABEL_PROPERTY);
+		if (label != null) {
+			this.result.append(' ');
+			label.accept(this);
+		}
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(CreationReference)
+	 */
+	public boolean visit(CreationReference node) {
+		getChildNode(node, CreationReference.TYPE_PROPERTY).accept(this);
+		this.result.append("::"); //$NON-NLS-1$
+		visitList(node, CreationReference.TYPE_ARGUMENTS_PROPERTY, Util.EMPTY_STRING, String.valueOf('<'), String.valueOf('>'));
+		this.result.append("new"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(DoStatement)
+	 */
+	public boolean visit(DoStatement node) {
+		this.result.append("do "); //$NON-NLS-1$
+		getChildNode(node, DoStatement.BODY_PROPERTY).accept(this);
+		this.result.append(" while ("); //$NON-NLS-1$
+		getChildNode(node, DoStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(");"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EmptyStatement)
+	 */
+	public boolean visit(EmptyStatement node) {
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ExpressionStatement)
+	 */
+	public boolean visit(ExpressionStatement node) {
+		getChildNode(node, ExpressionStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(';');
+		return false;
+	}
+
+	public boolean visit(ExtraDimension node) {
+		visitList(node, ExtraDimension.ANNOTATIONS_PROPERTY, String.valueOf(' '), String.valueOf(' '), String.valueOf(' '));
+		this.result.append("[]"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(FieldAccess)
+	 */
+	public boolean visit(FieldAccess node) {
+		getChildNode(node, FieldAccess.EXPRESSION_PROPERTY).accept(this);
+		this.result.append('.');
+		getChildNode(node, FieldAccess.NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(FieldDeclaration)
+	 */
+	public boolean visit(FieldDeclaration node) {
+		ASTNode javadoc= getChildNode(node, FieldDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_FIELD_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, FieldDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, FieldDeclaration.TYPE_PROPERTY).accept(this);
+		this.result.append(' ');
+		visitList(node, FieldDeclaration.FRAGMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ForStatement)
+	 */
+	public boolean visit(ForStatement node) {
+		this.result.append("for ("); //$NON-NLS-1$
+		visitList(node, ForStatement.INITIALIZERS_PROPERTY, String.valueOf(','));
+		this.result.append(';');
+		ASTNode expression= getChildNode(node, ForStatement.EXPRESSION_PROPERTY);
+		if (expression != null) {
+			expression.accept(this);
+		}
+		this.result.append(';');
+		visitList(node, ForStatement.UPDATERS_PROPERTY, String.valueOf(','));
+		this.result.append(')');
+		getChildNode(node, ForStatement.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(IfStatement)
+	 */
+	public boolean visit(IfStatement node) {
+		this.result.append("if ("); //$NON-NLS-1$
+		getChildNode(node, IfStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, IfStatement.THEN_STATEMENT_PROPERTY).accept(this);
+		ASTNode elseStatement= getChildNode(node, IfStatement.ELSE_STATEMENT_PROPERTY);
+		if (elseStatement != null) {
+			this.result.append(" else "); //$NON-NLS-1$
+			elseStatement.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ImportDeclaration)
+	 */
+	public boolean visit(ImportDeclaration node) {
+		this.result.append("import "); //$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			if (getBooleanAttribute(node, ImportDeclaration.STATIC_PROPERTY)) {
+				this.result.append("static ");//$NON-NLS-1$
+			}
+		}
+		getChildNode(node, ImportDeclaration.NAME_PROPERTY).accept(this);
+		if (getBooleanAttribute(node, ImportDeclaration.ON_DEMAND_PROPERTY)) {
+			this.result.append(".*"); //$NON-NLS-1$
+		}
+		this.result.append(';');
+		return false;
+	}
+
+
+
+	/*
+	 * @see ASTVisitor#visit(InfixExpression)
+	 */
+	public boolean visit(InfixExpression node) {
+		getChildNode(node, InfixExpression.LEFT_OPERAND_PROPERTY).accept(this);
+		this.result.append(' ');
+		String operator= getAttribute(node, InfixExpression.OPERATOR_PROPERTY).toString();
+
+		this.result.append(operator);
+		this.result.append(' ');
+		getChildNode(node, InfixExpression.RIGHT_OPERAND_PROPERTY).accept(this);
+
+		String separator= ' ' + operator + ' ';
+		visitList(node, InfixExpression.EXTENDED_OPERANDS_PROPERTY, separator, separator, Util.EMPTY_STRING);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Initializer)
+	 */
+	public boolean visit(Initializer node) {
+		ASTNode javadoc= getChildNode(node, Initializer.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_INITIALIZER_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, Initializer.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, Initializer.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(InstanceofExpression)
+	 */
+	public boolean visit(InstanceofExpression node) {
+		getChildNode(node, InstanceofExpression.LEFT_OPERAND_PROPERTY).accept(this);
+		this.result.append(" instanceof "); //$NON-NLS-1$
+		getChildNode(node, InstanceofExpression.RIGHT_OPERAND_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(IntersectionType)
+	 */
+	public boolean visit(IntersectionType node) {
+		visitList(node, IntersectionType.TYPES_PROPERTY, " & ", Util.EMPTY_STRING, Util.EMPTY_STRING); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(Javadoc)
+	 */
+	public boolean visit(Javadoc node) {
+		this.result.append("/**"); //$NON-NLS-1$
+		List list= getChildList(node, Javadoc.TAGS_PROPERTY);
+		for (int i= 0; i < list.size(); i++) {
+			this.result.append("\n * "); //$NON-NLS-1$
+			((ASTNode) list.get(i)).accept(this);
+		}
+		this.result.append("\n */"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(LabeledStatement)
+	 */
+	public boolean visit(LabeledStatement node) {
+		getChildNode(node, LabeledStatement.LABEL_PROPERTY).accept(this);
+		this.result.append(": "); //$NON-NLS-1$
+		getChildNode(node, LabeledStatement.BODY_PROPERTY).accept(this);
+		return false;
+	}
+	/*
+	 * @see ASTVisitor#visit(LambdaExpression)
+	 */
+	public boolean visit(LambdaExpression node) {
+		boolean hasParentheses = getBooleanAttribute(node, LambdaExpression.PARENTHESES_PROPERTY);
+		if (!hasParentheses) {
+			List parameters = getChildList(node, LambdaExpression.PARAMETERS_PROPERTY);
+			hasParentheses = !(parameters.size() == 1 && parameters.get(0) instanceof VariableDeclarationFragment);
+		}
+
+		if (hasParentheses)
+			this.result.append('(');
+		visitList(node, LambdaExpression.PARAMETERS_PROPERTY, String.valueOf(','));
+		if (hasParentheses)
+			this.result.append(')');
+		this.result.append("->"); //$NON-NLS-1$
+		getChildNode(node, LambdaExpression.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodDeclaration)
+	 */
+	public boolean visit(MethodDeclaration node) {
+		ASTNode javadoc= getChildNode(node, MethodDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_METHOD_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, MethodDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+			visitList(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+
+		if (!getBooleanAttribute(node, MethodDeclaration.CONSTRUCTOR_PROPERTY)) {
+			if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+				getChildNode(node, INTERNAL_METHOD_RETURN_TYPE_PROPERTY).accept(this);
+			} else {
+				ASTNode returnType = getChildNode(node, MethodDeclaration.RETURN_TYPE2_PROPERTY);
+				if (returnType != null) {
+					returnType.accept(this);
+				} else {
+					// methods really ought to have a return type
+					this.result.append("void");//$NON-NLS-1$
+				}
+			}
+			this.result.append(' ');
+		}
+		getChildNode(node, MethodDeclaration.NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		// receiver parameter
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			ASTNode receiverType = getChildNode(node, MethodDeclaration.RECEIVER_TYPE_PROPERTY);
+			if (receiverType != null) {
+				receiverType.accept(this);
+				this.result.append(' ');
+				ASTNode qualifier = getChildNode(node, MethodDeclaration.RECEIVER_QUALIFIER_PROPERTY);
+				if (qualifier != null) {
+					qualifier.accept(this);
+					this.result.append('.');
+				}
+				this.result.append("this"); //$NON-NLS-1$
+				if (getChildList(node, MethodDeclaration.PARAMETERS_PROPERTY).size() > 0) {
+					this.result.append(',');
+				}
+			}
+		}
+	
+		visitList(node, MethodDeclaration.PARAMETERS_PROPERTY, String.valueOf(','));
+		this.result.append(')');
+		visitExtraDimensions(node, INTERNAL_METHOD_EXTRA_DIMENSIONS_PROPERTY, MethodDeclaration.EXTRA_DIMENSIONS2_PROPERTY);
+
+		ChildListPropertyDescriptor exceptionsProperty = node.getAST().apiLevel() <	AST.JLS8 ? 
+				INTERNAL_METHOD_THROWN_EXCEPTIONS_PROPERTY : MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY;
+		visitList(node, exceptionsProperty, String.valueOf(','), " throws ", Util.EMPTY_STRING); //$NON-NLS-1$			
+		ASTNode body= getChildNode(node, MethodDeclaration.BODY_PROPERTY);
+		if (body == null) {
+			this.result.append(';');
+		} else {
+			body.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MethodInvocation)
+	 */
+	public boolean visit(MethodInvocation node) {
+		ASTNode expression= getChildNode(node, MethodInvocation.EXPRESSION_PROPERTY);
+		if (expression != null) {
+			expression.accept(this);
+			this.result.append('.');
+		}
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			visitList(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+
+		getChildNode(node, MethodInvocation.NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		visitList(node, MethodInvocation.ARGUMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(')');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NullLiteral)
+	 */
+	public boolean visit(NullLiteral node) {
+		this.result.append("null"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NumberLiteral)
+	 */
+	public boolean visit(NumberLiteral node) {
+		this.result.append(getAttribute(node, NumberLiteral.TOKEN_PROPERTY).toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PackageDeclaration)
+	 */
+	public boolean visit(PackageDeclaration node) {
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			ASTNode javadoc = getChildNode(node, PackageDeclaration.JAVADOC_PROPERTY);
+			if (javadoc != null) {
+				javadoc.accept(this);
+			}
+			visitList(node, PackageDeclaration.ANNOTATIONS_PROPERTY, String.valueOf(' '));
+		}
+		this.result.append("package "); //$NON-NLS-1$
+		getChildNode(node, PackageDeclaration.NAME_PROPERTY).accept(this);
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ParenthesizedExpression)
+	 */
+	public boolean visit(ParenthesizedExpression node) {
+		this.result.append('(');
+		getChildNode(node, ParenthesizedExpression.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PostfixExpression)
+	 */
+	public boolean visit(PostfixExpression node) {
+		getChildNode(node, PostfixExpression.OPERAND_PROPERTY).accept(this);
+		this.result.append(getAttribute(node, PostfixExpression.OPERATOR_PROPERTY).toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PrefixExpression)
+	 */
+	public boolean visit(PrefixExpression node) {
+		this.result.append(getAttribute(node, PrefixExpression.OPERATOR_PROPERTY).toString());
+		getChildNode(node, PrefixExpression.OPERAND_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PrimitiveType)
+	 */
+	public boolean visit(PrimitiveType node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, PrimitiveType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		this.result.append(getAttribute(node, PrimitiveType.PRIMITIVE_TYPE_CODE_PROPERTY).toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(QualifiedName)
+	 */
+	public boolean visit(QualifiedName node) {
+		getChildNode(node, QualifiedName.QUALIFIER_PROPERTY).accept(this);
+		this.result.append('.');
+		getChildNode(node, QualifiedName.NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ReturnStatement)
+	 */
+	public boolean visit(ReturnStatement node) {
+		this.result.append("return"); //$NON-NLS-1$
+		ASTNode expression= getChildNode(node, ReturnStatement.EXPRESSION_PROPERTY);
+		if (expression != null) {
+			this.result.append(' ');
+			expression.accept(this);
+		}
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SimpleName)
+	 */
+	public boolean visit(SimpleName node) {
+		this.result.append(getAttribute(node, SimpleName.IDENTIFIER_PROPERTY));
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SimpleType)
+	 */
+	public boolean visit(SimpleType node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, SimpleType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SingleVariableDeclaration)
+	 */
+	public boolean visit(SingleVariableDeclaration node) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_VARIABLE_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, SingleVariableDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, SingleVariableDeclaration.TYPE_PROPERTY).accept(this);
+		if (node.getAST().apiLevel() >= AST.JLS8  && node.isVarargs()) {
+			visitList(node, SingleVariableDeclaration.VARARGS_ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			if (getBooleanAttribute(node, SingleVariableDeclaration.VARARGS_PROPERTY)) {
+				this.result.append("...");//$NON-NLS-1$
+			}
+		}
+		this.result.append(' ');
+		getChildNode(node, SingleVariableDeclaration.NAME_PROPERTY).accept(this);
+		visitExtraDimensions(node, INTERNAL_VARIABLE_EXTRA_DIMENSIONS_PROPERTY, SingleVariableDeclaration.EXTRA_DIMENSIONS2_PROPERTY);
+		ASTNode initializer= getChildNode(node, SingleVariableDeclaration.INITIALIZER_PROPERTY);
+		if (initializer != null) {
+			this.result.append('=');
+			initializer.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(StringLiteral)
+	 */
+	public boolean visit(StringLiteral node) {
+		this.result.append(getAttribute(node, StringLiteral.ESCAPED_VALUE_PROPERTY));
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperConstructorInvocation)
+	 */
+	public boolean visit(SuperConstructorInvocation node) {
+		ASTNode expression= getChildNode(node, SuperConstructorInvocation.EXPRESSION_PROPERTY);
+		if (expression != null) {
+			expression.accept(this);
+			this.result.append('.');
+		}
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			visitList(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+		this.result.append("super("); //$NON-NLS-1$
+		visitList(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(");"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperFieldAccess)
+	 */
+	public boolean visit(SuperFieldAccess node) {
+		ASTNode qualifier= getChildNode(node, SuperFieldAccess.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+			this.result.append('.');
+		}
+		this.result.append("super."); //$NON-NLS-1$
+		getChildNode(node, SuperFieldAccess.NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperMethodInvocation)
+	 */
+	public boolean visit(SuperMethodInvocation node) {
+		ASTNode qualifier= getChildNode(node, SuperMethodInvocation.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+			this.result.append('.');
+		}
+		this.result.append("super."); //$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			visitList(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+		getChildNode(node, SuperMethodInvocation.NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		visitList(node, SuperMethodInvocation.ARGUMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(')');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SwitchCase)
+	 */
+	public boolean visit(SwitchCase node) {
+		ASTNode expression= getChildNode(node, SwitchCase.EXPRESSION_PROPERTY);
+		if (expression == null) {
+			this.result.append("default"); //$NON-NLS-1$
+		} else {
+			this.result.append("case "); //$NON-NLS-1$
+			expression.accept(this);
+		}
+		this.result.append(':');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SwitchStatement)
+	 */
+	public boolean visit(SwitchStatement node) {
+		this.result.append("switch ("); //$NON-NLS-1$
+		getChildNode(node, SwitchStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		this.result.append('{');
+		visitList(node, SwitchStatement.STATEMENTS_PROPERTY, null);
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SynchronizedStatement)
+	 */
+	public boolean visit(SynchronizedStatement node) {
+		this.result.append("synchronized ("); //$NON-NLS-1$
+		getChildNode(node, SynchronizedStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, SynchronizedStatement.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ThisExpression)
+	 */
+	public boolean visit(ThisExpression node) {
+		ASTNode qualifier= getChildNode(node, ThisExpression.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+			this.result.append('.');
+		}
+		this.result.append("this"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ThrowStatement)
+	 */
+	public boolean visit(ThrowStatement node) {
+		this.result.append("throw "); //$NON-NLS-1$
+		getChildNode(node, ThrowStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TryStatement)
+	 */
+	public boolean visit(TryStatement node) {
+		this.result.append("try "); //$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS4_INTERNAL) {
+			visitList(node, TryStatement.RESOURCES_PROPERTY, String.valueOf(';'), String.valueOf('('), String.valueOf(')'));
+		}
+		getChildNode(node, TryStatement.BODY_PROPERTY).accept(this);
+		this.result.append(' ');
+		visitList(node, TryStatement.CATCH_CLAUSES_PROPERTY, null);
+		ASTNode finallyClause= getChildNode(node, TryStatement.FINALLY_PROPERTY);
+		if (finallyClause != null) {
+			this.result.append(" finally "); //$NON-NLS-1$
+			finallyClause.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeDeclaration)
+	 */
+	public boolean visit(TypeDeclaration node) {
+		int apiLevel= node.getAST().apiLevel();
+
+		ASTNode javadoc= getChildNode(node, TypeDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+
+		if (apiLevel == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_TYPE_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, TypeDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+
+		boolean isInterface= getBooleanAttribute(node, TypeDeclaration.INTERFACE_PROPERTY);
+		this.result.append(isInterface ? "interface " : "class "); //$NON-NLS-1$ //$NON-NLS-2$
+		getChildNode(node, TypeDeclaration.NAME_PROPERTY).accept(this);
+		if (apiLevel >= JLS3_INTERNAL) {
+			visitList(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+		}
+
+		this.result.append(' ');
+
+		ChildPropertyDescriptor superClassProperty= (apiLevel == JLS2_INTERNAL) ? INTERNAL_TYPE_SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
+		ASTNode superclass= getChildNode(node, superClassProperty);
+		if (superclass != null) {
+			this.result.append("extends "); //$NON-NLS-1$
+			superclass.accept(this);
+			this.result.append(' ');
+		}
+
+		ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == JLS2_INTERNAL) ? INTERNAL_TYPE_SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
+		String lead= isInterface ? "extends " : "implements ";  //$NON-NLS-1$//$NON-NLS-2$
+		visitList(node, superInterfaceProperty, String.valueOf(','), lead, Util.EMPTY_STRING);
+		this.result.append('{');
+		visitList(node, TypeDeclaration.BODY_DECLARATIONS_PROPERTY, null);
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeDeclarationStatement)
+	 */
+	public boolean visit(TypeDeclarationStatement node) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			getChildNode(node, INTERNAL_TDS_TYPE_DECLARATION_PROPERTY).accept(this);
+		} else {
+			getChildNode(node, TypeDeclarationStatement.DECLARATION_PROPERTY).accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeLiteral)
+	 */
+	public boolean visit(TypeLiteral node) {
+		getChildNode(node, TypeLiteral.TYPE_PROPERTY).accept(this);
+		this.result.append(".class"); //$NON-NLS-1$
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(UnionType)
+	 */
+	public boolean visit(UnionType node) {
+		visitList(node, UnionType.TYPES_PROPERTY, " | ", Util.EMPTY_STRING, Util.EMPTY_STRING); //$NON-NLS-1$
+		return false;
+	}
+	
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationExpression)
+	 */
+	public boolean visit(VariableDeclarationExpression node) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_VDE_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, VariableDeclarationExpression.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, VariableDeclarationExpression.TYPE_PROPERTY).accept(this);
+		this.result.append(' ');
+		visitList(node, VariableDeclarationExpression.FRAGMENTS_PROPERTY, String.valueOf(','));
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationFragment)
+	 */
+	public boolean visit(VariableDeclarationFragment node) {
+		getChildNode(node, VariableDeclarationFragment.NAME_PROPERTY).accept(this);
+		visitExtraDimensions(node, INTERNAL_FRAGMENT_EXTRA_DIMENSIONS_PROPERTY, VariableDeclarationFragment.EXTRA_DIMENSIONS2_PROPERTY);
+		ASTNode initializer= getChildNode(node, VariableDeclarationFragment.INITIALIZER_PROPERTY);
+		if (initializer != null) {
+			this.result.append('=');
+			initializer.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(VariableDeclarationStatement)
+	 */
+	public boolean visit(VariableDeclarationStatement node) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
+			printModifiers(getIntAttribute(node, INTERNAL_VDS_MODIFIERS_PROPERTY), this.result);
+		} else {
+			visitList(node, VariableDeclarationStatement.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, VariableDeclarationStatement.TYPE_PROPERTY).accept(this);
+		this.result.append(' ');
+		visitList(node, VariableDeclarationStatement.FRAGMENTS_PROPERTY, String.valueOf(','));
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(WhileStatement)
+	 */
+	public boolean visit(WhileStatement node) {
+		this.result.append("while ("); //$NON-NLS-1$
+		getChildNode(node, WhileStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, WhileStatement.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BlockComment)
+	 */
+	public boolean visit(BlockComment node) {
+		return false; // cant flatten, needs source
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.LineComment)
+	 */
+	public boolean visit(LineComment node) {
+		return false; // cant flatten, needs source
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MemberRef)
+	 */
+	public boolean visit(MemberRef node) {
+		ASTNode qualifier= getChildNode(node, MemberRef.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+		}
+		this.result.append('#');
+		getChildNode(node, MemberRef.NAME_PROPERTY).accept(this);
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRef)
+	 */
+	public boolean visit(MethodRef node) {
+		ASTNode qualifier= getChildNode(node, MethodRef.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+		}
+		this.result.append('#');
+		getChildNode(node, MethodRef.NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		visitList(node, MethodRef.PARAMETERS_PROPERTY, ","); //$NON-NLS-1$
+		this.result.append(')');
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodRefParameter)
+	 */
+	public boolean visit(MethodRefParameter node) {
+		getChildNode(node, MethodRefParameter.TYPE_PROPERTY).accept(this);
+		if (node.getAST().apiLevel() >= JLS3_INTERNAL) {
+			if (getBooleanAttribute(node, MethodRefParameter.VARARGS_PROPERTY)) {
+				this.result.append("..."); //$NON-NLS-1$
+			}
+		}
+		ASTNode name= getChildNode(node, MethodRefParameter.NAME_PROPERTY);
+		if (name != null) {
+			this.result.append(' ');
+			name.accept(this);
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TagElement)
+	 */
+	public boolean visit(TagElement node) {
+		Object tagName= getAttribute(node, TagElement.TAG_NAME_PROPERTY);
+		if (tagName != null) {
+			this.result.append((String) tagName);
+		}
+		List list= getChildList(node, TagElement.FRAGMENTS_PROPERTY);
+		for (int i= 0; i < list.size(); i++) {
+			if (i > 0 || tagName != null) {
+				this.result.append(' ');
+			}
+			ASTNode curr= (ASTNode) list.get(i);
+			if (curr instanceof TagElement) {
+				this.result.append('{');
+				curr.accept(this);
+				this.result.append('}');
+			} else {
+				curr.accept(this);
+			}
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TextElement)
+	 */
+	public boolean visit(TextElement node) {
+		this.result.append(getAttribute(node, TextElement.TEXT_PROPERTY));
+		return false;
+	}
+	/*
+	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
+	 * @since 3.0
+	 */
+	public boolean visit(AnnotationTypeDeclaration node) {
+		ASTNode javadoc= getChildNode(node, AnnotationTypeDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		visitList(node, AnnotationTypeDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		this.result.append("@interface ");//$NON-NLS-1$
+		getChildNode(node, AnnotationTypeDeclaration.NAME_PROPERTY).accept(this);
+		this.result.append('{');
+		visitList(node, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY, Util.EMPTY_STRING);
+		this.result.append('}');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
+	 * @since 3.0
+	 */
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		ASTNode javadoc= getChildNode(node, AnnotationTypeMemberDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		visitList(node, AnnotationTypeMemberDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		getChildNode(node, AnnotationTypeMemberDeclaration.TYPE_PROPERTY).accept(this);
+		this.result.append(' ');
+		getChildNode(node, AnnotationTypeMemberDeclaration.NAME_PROPERTY).accept(this);
+		this.result.append("()");//$NON-NLS-1$
+		ASTNode def= getChildNode(node, AnnotationTypeMemberDeclaration.DEFAULT_PROPERTY);
+		if (def != null) {
+			this.result.append(" default ");//$NON-NLS-1$
+			def.accept(this);
+		}
+		this.result.append(';');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnhancedForStatement)
+	 * @since 3.0
+	 */
+	public boolean visit(EnhancedForStatement node) {
+		this.result.append("for (");//$NON-NLS-1$
+		getChildNode(node, EnhancedForStatement.PARAMETER_PROPERTY).accept(this);
+		this.result.append(':');
+		getChildNode(node, EnhancedForStatement.EXPRESSION_PROPERTY).accept(this);
+		this.result.append(')');
+		getChildNode(node, EnhancedForStatement.BODY_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnumConstantDeclaration)
+	 * @since 3.0
+	 */
+	public boolean visit(EnumConstantDeclaration node) {
+		ASTNode javadoc= getChildNode(node, EnumConstantDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		visitList(node, EnumConstantDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		getChildNode(node, EnumConstantDeclaration.NAME_PROPERTY).accept(this);
+		visitList(node, EnumConstantDeclaration.ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('('), String.valueOf(')'));
+		ASTNode classDecl= getChildNode(node, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
+		if (classDecl != null) {
+			classDecl.accept(this);
+		}
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(EnumDeclaration)
+	 * @since 3.0
+	 */
+	public boolean visit(EnumDeclaration node) {
+		ASTNode javadoc= getChildNode(node, EnumDeclaration.JAVADOC_PROPERTY);
+		if (javadoc != null) {
+			javadoc.accept(this);
+		}
+		visitList(node, EnumDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		this.result.append("enum ");//$NON-NLS-1$
+		getChildNode(node, EnumDeclaration.NAME_PROPERTY).accept(this);
+		this.result.append(' ');
+		visitList(node, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, String.valueOf(','), "implements ", Util.EMPTY_STRING); //$NON-NLS-1$
+
+		this.result.append('{');
+		visitList(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY, String.valueOf(','), Util.EMPTY_STRING, Util.EMPTY_STRING);
+		visitList(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY, Util.EMPTY_STRING, String.valueOf(';'), Util.EMPTY_STRING);
+		this.result.append('}');
+		return false;
+	}
+	/*
+	 * @see ASTVisitor#visit(ExpressionMethodReference)
+	 */
+	public boolean visit(ExpressionMethodReference node) {
+		getChildNode(node, ExpressionMethodReference.EXPRESSION_PROPERTY).accept(this);
+		this.result.append("::"); //$NON-NLS-1$
+		visitList(node, ExpressionMethodReference.TYPE_ARGUMENTS_PROPERTY, Util.EMPTY_STRING, String.valueOf('<'), String.valueOf('>'));
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MarkerAnnotation)
+	 * @since 3.0
+	 */
+	public boolean visit(MarkerAnnotation node) {
+		this.result.append('@');
+		getChildNode(node, MarkerAnnotation.TYPE_NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(MemberValuePair)
+	 * @since 3.0
+	 */
+	public boolean visit(MemberValuePair node) {
+		getChildNode(node, MemberValuePair.NAME_PROPERTY).accept(this);
+		this.result.append('=');
+		getChildNode(node, MemberValuePair.VALUE_PROPERTY).accept(this);
+		return false;
+	}
+	/*
+	 * @see ASTVisitor#visit(Modifier)
+	 * @since 3.0
+	 */
+	public boolean visit(Modifier node) {
+		this.result.append(getAttribute(node, Modifier.KEYWORD_PROPERTY).toString());
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(NormalAnnotation)
+	 * @since 3.0
+	 */
+	public boolean visit(NormalAnnotation node) {
+		this.result.append('@');
+		getChildNode(node, NormalAnnotation.TYPE_NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		visitList(node, NormalAnnotation.VALUES_PROPERTY, ", "); //$NON-NLS-1$
+		this.result.append(')');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(PackageQualifiedType)
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public boolean visit(PackageQualifiedType node) {
+		getChildNode(node, PackageQualifiedType.QUALIFIER_PROPERTY).accept(this);
+		this.result.append('.');
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, PackageQualifiedType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, PackageQualifiedType.NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(ParameterizedType)
+	 * @since 3.0
+	 */
+	public boolean visit(ParameterizedType node) {
+		getChildNode(node, ParameterizedType.TYPE_PROPERTY).accept(this);
+		this.result.append('<');
+		visitList(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY, ", "); //$NON-NLS-1$
+		this.result.append('>');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(QualifiedType)
+	 * @since 3.0
+	 */
+	public boolean visit(QualifiedType node) {
+		getChildNode(node, QualifiedType.QUALIFIER_PROPERTY).accept(this);
+		this.result.append('.');
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, QualifiedType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, QualifiedType.NAME_PROPERTY).accept(this);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SingleMemberAnnotation)
+	 */
+	public boolean visit(SingleMemberAnnotation node) {
+		this.result.append('@');
+		getChildNode(node, SingleMemberAnnotation.TYPE_NAME_PROPERTY).accept(this);
+		this.result.append('(');
+		getChildNode(node, SingleMemberAnnotation.VALUE_PROPERTY).accept(this);
+		this.result.append(')');
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(SuperMethodReference)
+	 */
+	public boolean visit(SuperMethodReference node) {
+		ASTNode qualifier = getChildNode(node, SuperMethodReference.QUALIFIER_PROPERTY);
+		if (qualifier != null) {
+			qualifier.accept(this);
+			this.result.append('.');
+		}
+		this.result.append("super ::"); //$NON-NLS-1$
+		visitList(node, SuperMethodReference.TYPE_ARGUMENTS_PROPERTY, Util.EMPTY_STRING, String.valueOf('<'), String.valueOf('>'));
+		node.getName().accept(this);
+		return false;
+	}
+
+	/*
+	 * @see ASTVisitor#visit(TypeMethodReference)
+	 */
+	public boolean visit(TypeMethodReference node) {
+		getChildNode(node, TypeMethodReference.TYPE_PROPERTY).accept(this);
+		this.result.append("::"); //$NON-NLS-1$
+		visitList(node, TypeMethodReference.TYPE_ARGUMENTS_PROPERTY, Util.EMPTY_STRING, String.valueOf('<'), String.valueOf('>'));
+		node.getName().accept(this);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeParameter)
+	 */
+	public boolean visit(TypeParameter node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, TypeParameter.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		getChildNode(node, TypeParameter.NAME_PROPERTY).accept(this);
+		visitList(node, TypeParameter.TYPE_BOUNDS_PROPERTY, " & ", " extends ", Util.EMPTY_STRING); //$NON-NLS-1$ //$NON-NLS-2$
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.WildcardType)
+	 */
+	public boolean visit(WildcardType node) {
+		if (node.getAST().apiLevel() >= AST.JLS8) {
+			visitList(node, WildcardType.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+		}
+		this.result.append('?');
+		ASTNode bound = getChildNode(node, WildcardType.BOUND_PROPERTY);
+		if (bound != null) {
+			if (getBooleanAttribute(node, WildcardType.UPPER_BOUND_PROPERTY)) {
+				this.result.append(" extends ");//$NON-NLS-1$
+			} else {
+				this.result.append(" super ");//$NON-NLS-1$
+			}
+			bound.accept(this);
+		}
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
new file mode 100644
index 0000000..a6dd2dc
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
@@ -0,0 +1,570 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Annotation;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.Position;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/* package */ final class ASTRewriteFormatter {
+
+	public static class NodeMarker extends Position {
+		public Object data;
+	}
+
+	private class ExtendedFlattener extends ASTRewriteFlattener {
+
+		private ArrayList positions;
+
+		public ExtendedFlattener(RewriteEventStore store) {
+			super(store);
+			this.positions= new ArrayList();
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jdt.core.dom.ASTVisitor#preVisit(ASTNode)
+		 */
+		public void preVisit(ASTNode node) {
+			Object trackData= getEventStore().getTrackedNodeData(node);
+			if (trackData != null) {
+				addMarker(trackData, this.result.length(), 0);
+			}
+			Object placeholderData= getPlaceholders().getPlaceholderData(node);
+			if (placeholderData != null) {
+				addMarker(placeholderData, this.result.length(), 0);
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jdt.core.dom.ASTVisitor#postVisit(ASTNode)
+		 */
+		public void postVisit(ASTNode node) {
+			Object placeholderData= getPlaceholders().getPlaceholderData(node);
+			if (placeholderData != null) {
+				fixupLength(placeholderData, this.result.length());
+			}
+			Object trackData= getEventStore().getTrackedNodeData(node);
+			if (trackData != null) {
+				fixupLength(trackData, this.result.length());
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jdt.internal.corext.dom.ASTRewriteFlattener#visit(org.eclipse.jdt.core.dom.Block)
+		 */
+		public boolean visit(Block node) {
+			if (getPlaceholders().isCollapsed(node)) {
+				visitList(node, Block.STATEMENTS_PROPERTY, null);
+				return false;
+			}
+			return super.visit(node);
+		}
+
+		private NodeMarker addMarker(Object annotation, int startOffset, int length) {
+			NodeMarker marker= new NodeMarker();
+			marker.offset= startOffset;
+			marker.length= length;
+			marker.data= annotation;
+			this.positions.add(marker);
+			return marker;
+		}
+
+		private void fixupLength(Object data, int endOffset) {
+			for (int i= this.positions.size()-1; i >= 0 ; i--) {
+				NodeMarker marker= (NodeMarker) this.positions.get(i);
+				if (marker.data == data) {
+					marker.length= endOffset - marker.offset;
+					return;
+				}
+			}
+		}
+
+		public NodeMarker[] getMarkers() {
+			return (NodeMarker[]) this.positions.toArray(new NodeMarker[this.positions.size()]);
+		}
+	}
+
+	private final String lineDelimiter;
+	private final int tabWidth;
+	private final int indentWidth;
+
+	private final NodeInfoStore placeholders;
+	private final RewriteEventStore eventStore;
+
+	private final Map options;
+
+
+	public ASTRewriteFormatter(NodeInfoStore placeholders, RewriteEventStore eventStore, Map options, String lineDelimiter) {
+		this.placeholders= placeholders;
+		this.eventStore= eventStore;
+	
+		this.options= options == null ? JavaCore.getOptions() : (Map) new HashMap(options);
+		this.options.put(
+				DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY,
+				DefaultCodeFormatterConstants.createAlignmentValue(true, DefaultCodeFormatterConstants.WRAP_NEXT_PER_LINE, DefaultCodeFormatterConstants.INDENT_DEFAULT));
+
+		this.lineDelimiter= lineDelimiter;
+	
+		this.tabWidth= IndentManipulation.getTabWidth(options);
+		this.indentWidth= IndentManipulation.getIndentWidth(options);
+	}
+
+
+
+	public NodeInfoStore getPlaceholders() {
+		return this.placeholders;
+	}
+
+	public RewriteEventStore getEventStore() {
+		return this.eventStore;
+	}
+
+	public int getTabWidth() {
+		return this.tabWidth;
+	}
+
+	public int getIndentWidth() {
+		return this.indentWidth;
+	}
+
+	public String getLineDelimiter() {
+		return this.lineDelimiter;
+	}
+
+	/**
+	 * Returns the string accumulated in the visit formatted using the default formatter.
+	 * Updates the existing node's positions.
+	 *
+	 * @param node The node to flatten.
+	 * @param initialIndentationLevel The initial indentation level.
+	 * @param resultingMarkers Resulting the updated NodeMarkers.
+	 * @return Returns the serialized and formatted code.
+	 */
+	public String getFormattedResult(ASTNode node, int initialIndentationLevel, Collection resultingMarkers) {
+
+		ExtendedFlattener flattener= new ExtendedFlattener(this.eventStore);
+		node.accept(flattener);
+
+		NodeMarker[] markers= flattener.getMarkers();
+		for (int i= 0; i < markers.length; i++) {
+			resultingMarkers.add(markers[i]); // add to result
+		}
+
+		String unformatted= flattener.getResult();
+		TextEdit edit= formatNode(node, unformatted, initialIndentationLevel);
+		if (edit == null) {
+		    if (initialIndentationLevel > 0) {
+		        // at least correct the indent
+		        String indentString = createIndentString(initialIndentationLevel);
+				ReplaceEdit[] edits = IndentManipulation.getChangeIndentEdits(unformatted, 0, this.tabWidth, this.indentWidth, indentString);
+				edit= new MultiTextEdit();
+				edit.addChild(new InsertEdit(0, indentString));
+				edit.addChildren(edits);
+		    } else {
+		       return unformatted;
+		    }
+		}
+		return evaluateFormatterEdit(unformatted, edit, markers);
+	}
+
+    public String createIndentString(int indentationUnits) {
+    	return ToolFactory.createCodeFormatter(this.options).createIndentationString(indentationUnits);
+    }
+
+	public String getIndentString(String currentLine) {
+		return IndentManipulation.extractIndentString(currentLine, this.tabWidth, this.indentWidth);
+	}
+
+	public String changeIndent(String code, int codeIndentLevel, String newIndent) {
+		return IndentManipulation.changeIndent(code, codeIndentLevel, this.tabWidth, this.indentWidth, newIndent, this.lineDelimiter);
+	}
+
+	public int computeIndentUnits(String line) {
+		return IndentManipulation.measureIndentUnits(line, this.tabWidth, this.indentWidth);
+	}
+
+	/**
+	 * Evaluates the edit on the given string.
+	 * @param string The string to format
+	 * @param edit The edit resulted from the code formatter
+	 * @param positions Positions to update or <code>null</code>.
+	 * @return The formatted string
+	 * @throws IllegalArgumentException If the positions are not inside the string, a
+	 *  IllegalArgumentException is thrown.
+	 */
+	public static String evaluateFormatterEdit(String string, TextEdit edit, Position[] positions) {
+		try {
+			Document doc= createDocument(string, positions);
+			edit.apply(doc, 0);
+			if (positions != null) {
+				for (int i= 0; i < positions.length; i++) {
+					Assert.isTrue(!positions[i].isDeleted, "Position got deleted"); //$NON-NLS-1$
+				}
+			}
+			return doc.get();
+		} catch (BadLocationException e) {
+			//JavaPlugin.log(e); // bug in the formatter
+			Assert.isTrue(false, "Fromatter created edits with wrong positions: " + e.getMessage()); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	public TextEdit formatString(int kind, String string, int offset, int length, int indentationLevel) {
+		return ToolFactory.createCodeFormatter(this.options).format(kind, string, offset, length, indentationLevel, this.lineDelimiter);
+	}
+
+	/**
+	 * Creates edits that describe how to format the given string. Returns <code>null</code> if the code could not be formatted for the given kind.
+	 * @param node Node describing the type of the string
+	 * @param str The unformatted string
+	 * @param indentationLevel
+	 * @return Returns the edit representing the result of the formatter
+	 * @throws IllegalArgumentException If the offset and length are not inside the string, a
+	 *  IllegalArgumentException is thrown.
+	 */
+	private TextEdit formatNode(ASTNode node, String str, int indentationLevel) {
+		int code;
+		String prefix= ""; //$NON-NLS-1$
+		String suffix= ""; //$NON-NLS-1$
+		if (node instanceof Statement) {
+			code= CodeFormatter.K_STATEMENTS;
+			if (node.getNodeType() == ASTNode.SWITCH_CASE) {
+				prefix= "switch(1) {"; //$NON-NLS-1$
+				suffix= "}"; //$NON-NLS-1$
+				code= CodeFormatter.K_STATEMENTS;
+			}
+		} else if (node instanceof Expression && node.getNodeType() != ASTNode.VARIABLE_DECLARATION_EXPRESSION) {
+			if (node instanceof Annotation) {
+				suffix= "\nclass A {}"; //$NON-NLS-1$
+				code= CodeFormatter.K_COMPILATION_UNIT;
+			} else {
+				code= CodeFormatter.K_EXPRESSION;
+			}
+		} else if (node instanceof BodyDeclaration) {
+			code= CodeFormatter.K_CLASS_BODY_DECLARATIONS;
+		} else {
+			switch (node.getNodeType()) {
+				case ASTNode.ARRAY_TYPE:
+				case ASTNode.PARAMETERIZED_TYPE:
+				case ASTNode.PRIMITIVE_TYPE:
+				case ASTNode.QUALIFIED_TYPE:
+				case ASTNode.SIMPLE_TYPE:
+					suffix= " x;"; //$NON-NLS-1$
+					code= CodeFormatter.K_CLASS_BODY_DECLARATIONS;
+					break;
+				case ASTNode.WILDCARD_TYPE:
+					prefix= "A<"; //$NON-NLS-1$
+					suffix= "> x;"; //$NON-NLS-1$
+					code= CodeFormatter.K_CLASS_BODY_DECLARATIONS;
+					break;
+				case ASTNode.COMPILATION_UNIT:
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
+				case ASTNode.SINGLE_VARIABLE_DECLARATION:
+					suffix= ";"; //$NON-NLS-1$
+					code= CodeFormatter.K_STATEMENTS;
+					break;
+				case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
+					prefix= "A "; //$NON-NLS-1$
+					suffix= ";"; //$NON-NLS-1$
+					code= CodeFormatter.K_STATEMENTS;
+					break;
+				case ASTNode.PACKAGE_DECLARATION:
+				case ASTNode.IMPORT_DECLARATION:
+					suffix= "\nclass A {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.JAVADOC:
+					suffix= "\nclass A {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.CATCH_CLAUSE:
+					prefix= "try {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_STATEMENTS;
+					break;
+				case ASTNode.ANONYMOUS_CLASS_DECLARATION:
+					prefix= "new A()"; //$NON-NLS-1$
+					suffix= ";"; //$NON-NLS-1$
+					code= CodeFormatter.K_STATEMENTS;
+					break;
+				case ASTNode.MEMBER_VALUE_PAIR:
+					prefix= "@Author("; //$NON-NLS-1$
+					suffix= ") class x {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.MODIFIER:
+					suffix= " class x {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.TYPE_PARAMETER:
+					prefix= "class X<"; //$NON-NLS-1$
+					suffix= "> {}"; //$NON-NLS-1$
+					code= CodeFormatter.K_COMPILATION_UNIT;
+					break;
+				case ASTNode.MEMBER_REF:
+				case ASTNode.METHOD_REF:
+				case ASTNode.METHOD_REF_PARAMETER:
+				case ASTNode.TAG_ELEMENT:
+				case ASTNode.TEXT_ELEMENT:
+					// javadoc formatting disabled due to bug 93644
+					return null;
+
+//				wiat for bug 93644
+//				case ASTNode.MEMBER_REF:
+//				case ASTNode.METHOD_REF:
+//					prefix= "/**\n * @see ";
+//					suffix= "\n*/";
+//					code= CodeFormatter.K_JAVA_DOC;
+//					break;
+//				case ASTNode.METHOD_REF_PARAMETER:
+//					prefix= "/**\n * @see A#foo(";
+//					suffix= ")\n*/";
+//					code= CodeFormatter.K_JAVA_DOC;
+//					break;
+//				case ASTNode.TAG_ELEMENT:
+//				case ASTNode.TEXT_ELEMENT:
+//					prefix= "/**\n * ";
+//					suffix= "\n*/";
+//					code= CodeFormatter.K_JAVA_DOC;
+//					break;
+				default:
+					//Assert.isTrue(false, "Node type not covered: " + node.getClass().getName());
+					return null;
+			}
+		}
+
+		String concatStr= prefix + str + suffix;
+		TextEdit edit= formatString(code, concatStr, prefix.length(), str.length(), indentationLevel);
+
+		if (prefix.length() > 0) {
+			edit= shifEdit(edit, prefix.length());
+		}
+		return edit;
+	}
+
+	private static TextEdit shifEdit(TextEdit oldEdit, int diff) {
+		TextEdit newEdit;
+		if (oldEdit instanceof ReplaceEdit) {
+			ReplaceEdit edit= (ReplaceEdit) oldEdit;
+			newEdit= new ReplaceEdit(edit.getOffset() - diff, edit.getLength(), edit.getText());
+		} else if (oldEdit instanceof InsertEdit) {
+			InsertEdit edit= (InsertEdit) oldEdit;
+			newEdit= new InsertEdit(edit.getOffset() - diff,  edit.getText());
+		} else if (oldEdit instanceof DeleteEdit) {
+			DeleteEdit edit= (DeleteEdit) oldEdit;
+			newEdit= new DeleteEdit(edit.getOffset() - diff,  edit.getLength());
+		} else if (oldEdit instanceof MultiTextEdit) {
+			newEdit= new MultiTextEdit();
+		} else {
+			return null; // not supported
+		}
+		TextEdit[] children= oldEdit.getChildren();
+		for (int i= 0; i < children.length; i++) {
+			TextEdit shifted= shifEdit(children[i], diff);
+			if (shifted != null) {
+				newEdit.addChild(shifted);
+			}
+		}
+		return newEdit;
+	}
+
+	private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException {
+		Document doc= new Document(string);
+		try {
+			if (positions != null) {
+				final String POS_CATEGORY= "myCategory"; //$NON-NLS-1$
+
+				doc.addPositionCategory(POS_CATEGORY);
+				doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
+					protected boolean notDeleted() {
+						int start= this.fOffset;
+						int end= start + this.fLength;
+						if (start < this.fPosition.offset && (this.fPosition.offset + this.fPosition.length < end)) {
+							this.fPosition.offset= end; // deleted positions: set to end of remove
+							return false;
+						}
+						return true;
+					}
+				});
+				for (int i= 0; i < positions.length; i++) {
+					try {
+						doc.addPosition(POS_CATEGORY, positions[i]);
+					} catch (BadLocationException e) {
+						throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + string.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+					}
+				}
+			}
+		} catch (BadPositionCategoryException cannotHappen) {
+			// can not happen: category is correctly set up
+		}
+		return doc;
+	}
+
+
+
+    public static interface Prefix {
+		String getPrefix(int indent);
+	}
+
+	public static interface BlockContext {
+		String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events);
+	}
+
+	public static class ConstPrefix implements Prefix {
+		private String prefix;
+
+		public ConstPrefix(String prefix) {
+			this.prefix= prefix;
+		}
+
+		public String getPrefix(int indent) {
+			return this.prefix;
+		}
+	}
+
+	private class FormattingPrefix implements Prefix {
+		private int kind;
+		private String string;
+		private int start;
+		private int length;
+
+		public FormattingPrefix(String string, String sub, int kind) {
+			this.start= string.indexOf(sub);
+			this.length= sub.length();
+			this.string= string;
+			this.kind= kind;
+		}
+
+		public String getPrefix(int indent) {
+			Position pos= new Position(this.start, this.length);
+			String str= this.string;
+			TextEdit res= formatString(this.kind, str, 0, str.length(), indent);
+			if (res != null) {
+				str= evaluateFormatterEdit(str, res, new Position[] { pos });
+			}
+			return str.substring(pos.offset + 1, pos.offset + pos.length - 1);
+		}
+	}
+
+	private class BlockFormattingPrefix implements BlockContext {
+		private String prefix;
+		private int start;
+
+		public BlockFormattingPrefix(String prefix, int start) {
+			this.start= start;
+			this.prefix= prefix;
+		}
+
+		public String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events) {
+			String nodeString= ASTRewriteFlattener.asString(node, events);
+			String str= this.prefix + nodeString;
+			Position pos= new Position(this.start, this.prefix.length() + 1 - this.start);
+
+			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, 0, str.length(), indent);
+			if (res != null) {
+				str= evaluateFormatterEdit(str, res, new Position[] { pos });
+			}
+			return new String[] { str.substring(pos.offset + 1, pos.offset + pos.length - 1), ""}; //$NON-NLS-1$
+		}
+	}
+
+	private class BlockFormattingPrefixSuffix implements BlockContext {
+		private String prefix;
+		private String suffix;
+		private int start;
+
+		public BlockFormattingPrefixSuffix(String prefix, String suffix, int start) {
+			this.start= start;
+			this.suffix= suffix;
+			this.prefix= prefix;
+		}
+
+		public String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events) {
+			String nodeString= ASTRewriteFlattener.asString(node, events);
+			int nodeStart= this.prefix.length();
+			int nodeEnd= nodeStart + nodeString.length() - 1;
+
+			String str= this.prefix + nodeString + this.suffix;
+
+			Position pos1= new Position(this.start, nodeStart + 1 - this.start);
+			Position pos2= new Position(nodeEnd, 2);
+
+			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, 0, str.length(), indent);
+			if (res != null) {
+				str= evaluateFormatterEdit(str, res, new Position[] { pos1, pos2 });
+			}
+			return new String[] {
+				str.substring(pos1.offset + 1, pos1.offset + pos1.length - 1),
+				str.substring(pos2.offset + 1, pos2.offset + pos2.length - 1)
+			};
+		}
+	}
+
+	public final static Prefix NONE= new ConstPrefix(""); //$NON-NLS-1$
+	public final static Prefix SPACE= new ConstPrefix(" "); //$NON-NLS-1$
+	public final static Prefix ASSERT_COMMENT= new ConstPrefix(" : "); //$NON-NLS-1$
+
+	public final Prefix VAR_INITIALIZER= new FormattingPrefix("A a={};", "a={" , CodeFormatter.K_STATEMENTS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix METHOD_BODY= new FormattingPrefix("void a() {}", ") {" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix FINALLY_BLOCK= new FormattingPrefix("try {} finally {}", "} finally {", CodeFormatter.K_STATEMENTS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix CATCH_BLOCK= new FormattingPrefix("try {} catch(Exception e) {}", "} c" , CodeFormatter.K_STATEMENTS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix ANNOT_MEMBER_DEFAULT= new FormattingPrefix("String value() default 1;", ") default 1" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix ENUM_BODY_START= new FormattingPrefix("enum E { A(){void foo(){}} }", "){v" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix ENUM_BODY_END= new FormattingPrefix("enum E { A(){void foo(){ }}, B}", "}}," , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix WILDCARD_EXTENDS= new FormattingPrefix("A<? extends B> a;", "? extends B" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix WILDCARD_SUPER= new FormattingPrefix("A<? super B> a;", "? super B" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+
+	public final Prefix FIRST_ENUM_CONST= new FormattingPrefix("enum E { X;}", "{ X" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix ANNOTATION_SEPARATION= new FormattingPrefix("@A @B class C {}", "A @" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix PARAM_ANNOTATION_SEPARATION= new FormattingPrefix("void foo(@A @B C p) { }", "A @" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix VARARGS= new FormattingPrefix("void foo(A ... a) { }", "A ." , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix TRY_RESOURCES = new FormattingPrefix("try (A a = new A(); B b = new B()) {}", "; B" , CodeFormatter.K_STATEMENTS); //$NON-NLS-1$ //$NON-NLS-2$
+	public final Prefix TRY_RESOURCES_PAREN = new FormattingPrefix("try (A a = new A(); B b = new B()) {}", "y (" , CodeFormatter.K_STATEMENTS); //$NON-NLS-1$ //$NON-NLS-2$
+	
+	public final BlockContext IF_BLOCK_WITH_ELSE= new BlockFormattingPrefixSuffix("if (true)", "else{}", 8); //$NON-NLS-1$ //$NON-NLS-2$
+	public final BlockContext IF_BLOCK_NO_ELSE= new BlockFormattingPrefix("if (true)", 8); //$NON-NLS-1$
+	public final BlockContext ELSE_AFTER_STATEMENT= new BlockFormattingPrefix("if (true) foo();else ", 15); //$NON-NLS-1$
+	public final BlockContext ELSE_AFTER_BLOCK= new BlockFormattingPrefix("if (true) {}else ", 11); //$NON-NLS-1$
+
+	public final BlockContext FOR_BLOCK= new BlockFormattingPrefix("for (;;) ", 7); //$NON-NLS-1$
+	public final BlockContext WHILE_BLOCK= new BlockFormattingPrefix("while (true)", 11); //$NON-NLS-1$
+	public final BlockContext DO_BLOCK= new BlockFormattingPrefixSuffix("do ", "while (true);", 1); //$NON-NLS-1$ //$NON-NLS-2$
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java
new file mode 100644
index 0000000..15c1cd8
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ImportRewriteAnalyzer.java
@@ -0,0 +1,1521 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *		IBM Corporation - initial API and implementation
+ *		Stephan Herrmann - Contribution for Bug 378024 - Ordering of comments between imports not preserved
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Comment;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.LineComment;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.TypeNameRequestor;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MultiTextEdit;
+
+public final class ImportRewriteAnalyzer {
+
+	private final ICompilationUnit compilationUnit;
+	private final ArrayList packageEntries;
+
+	private final List importsCreated;
+	private final List staticImportsCreated;
+
+	private final IRegion replaceRange;
+
+	private final int importOnDemandThreshold;
+	private final int staticImportOnDemandThreshold;
+
+	private boolean filterImplicitImports;
+	private boolean useContextToFilterImplicitImports;
+	private boolean findAmbiguousImports;
+
+	private IRegion[] preserveExistingCommentsRanges;
+
+	private int flags= 0;
+
+	private static final int F_NEEDS_LEADING_DELIM= 2;
+	private static final int F_NEEDS_TRAILING_DELIM= 4;
+
+	private static final String JAVA_LANG= "java.lang"; //$NON-NLS-1$
+
+	public ImportRewriteAnalyzer(
+			ICompilationUnit cu,
+			CompilationUnit root,
+			String[] importOrder,
+			int threshold,
+			int staticThreshold,
+			boolean restoreExistingImports,
+			boolean useContextToFilterImplicitImports) {
+		this.compilationUnit= cu;
+		this.importOnDemandThreshold= threshold;
+		this.staticImportOnDemandThreshold= staticThreshold;
+		this.useContextToFilterImplicitImports = useContextToFilterImplicitImports;
+
+		this.filterImplicitImports= true;
+		this.findAmbiguousImports= true; //!restoreExistingImports;
+
+		this.packageEntries= new ArrayList(20);
+		this.importsCreated= new ArrayList();
+		this.staticImportsCreated= new ArrayList();
+		this.flags= 0;
+
+		this.replaceRange= evaluateReplaceRange(root);
+		if (restoreExistingImports) {
+			addExistingImports(root);
+		} else {
+			// collect all existing comments inside imports and concatenate them
+			this.preserveExistingCommentsRanges = retrieveExistingCommentsInImports(root);
+		}
+
+		PackageEntry[] order= new PackageEntry[importOrder.length];
+		for (int i= 0; i < order.length; i++) {
+			String curr= importOrder[i];
+			if (curr.length() > 0 && curr.charAt(0) == '#') {
+				curr= curr.substring(1);
+				order[i]= new PackageEntry(curr, curr, true); // static import group
+			} else {
+				order[i]= new PackageEntry(curr, curr, false); // normal import group
+			}
+		}
+
+		addPreferenceOrderHolders(order);
+	}
+
+	private int getSpacesBetweenImportGroups() {
+		try {
+			int num= Integer.parseInt(this.compilationUnit.getJavaProject().getOption(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS, true));
+			if (num >= 0)
+				return num;
+		} catch (NumberFormatException e) {
+			// fall through
+		}
+		return 1;
+	}
+	
+	private boolean insertSpaceBeforeSemicolon() {
+		return JavaCore.INSERT.equals(this.compilationUnit.getJavaProject().getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON, true));
+	}
+
+	private void addPreferenceOrderHolders(PackageEntry[] preferenceOrder) {
+		if (this.packageEntries.isEmpty()) {
+			// all new: copy the elements
+			for (int i= 0; i < preferenceOrder.length; i++) {
+				this.packageEntries.add(preferenceOrder[i]);
+			}
+		} else {
+			// match the preference order entries to existing imports
+			// entries not found are appended after the last successfully matched entry
+
+			PackageEntry[] lastAssigned= new PackageEntry[preferenceOrder.length];
+
+			// find an existing package entry that matches most
+			for (int k= 0; k < this.packageEntries.size(); k++) {
+				PackageEntry entry= (PackageEntry) this.packageEntries.get(k);
+				if (!entry.isComment()) {
+					String currName= entry.getName();
+					int currNameLen= currName.length();
+					int bestGroupIndex= -1;
+					int bestGroupLen= -1;
+					for (int i= 0; i < preferenceOrder.length; i++) {
+						boolean currPrevStatic= preferenceOrder[i].isStatic();
+						if (currPrevStatic == entry.isStatic()) {
+							String currPrefEntry= preferenceOrder[i].getName();
+							int currPrefLen= currPrefEntry.length();
+							if (currName.startsWith(currPrefEntry) && currPrefLen >= bestGroupLen) {
+								if (currPrefLen == currNameLen || currName.charAt(currPrefLen) == '.') {
+									if (bestGroupIndex == -1 || currPrefLen > bestGroupLen) {
+										bestGroupLen= currPrefLen;
+										bestGroupIndex= i;
+									}
+								}
+							}
+						}
+					}
+					if (bestGroupIndex != -1) {
+						entry.setGroupID(preferenceOrder[bestGroupIndex].getName());
+						lastAssigned[bestGroupIndex]= entry; // remember last entry
+					}
+				}
+			}
+			// fill in not-assigned categories, keep partial order
+			int currAppendIndex= 0;
+			for (int i= 0; i < lastAssigned.length; i++) {
+				PackageEntry entry= lastAssigned[i];
+				if (entry == null) {
+					PackageEntry newEntry= preferenceOrder[i];
+					if (currAppendIndex == 0 && !newEntry.isStatic()) {
+						currAppendIndex= getIndexAfterStatics();
+					}
+					this.packageEntries.add(currAppendIndex, newEntry);
+					currAppendIndex++;
+				} else {
+					currAppendIndex= this.packageEntries.indexOf(entry) + 1;
+				}
+			}
+		}
+	}
+
+	private String getQualifier(ImportDeclaration decl) {
+		String name = decl.getName().getFullyQualifiedName();
+		/*
+		 * If it's on demand import, return the fully qualified name. (e.g. pack1.Foo.* => pack.Foo, pack1.* => pack1)
+		 * This is because we need to have pack1.Foo.* and pack1.Bar under different qualifier groups.
+		 */
+		if (decl.isOnDemand()) {
+			return name;
+		}
+		return getQualifier(name, decl.isStatic());
+	}
+
+	private String getQualifier(String name, boolean isStatic) {
+		// For static imports, return the Type name as well as part of the qualifier
+		if (isStatic || !this.useContextToFilterImplicitImports) {
+			return Signature.getQualifier(name);
+		}
+
+		char[] searchedName = name.toCharArray();
+		int index = name.length();
+		/* Stop at the last fragment */
+		JavaProject project = (JavaProject) this.compilationUnit.getJavaProject();
+		do {
+			String testedName = new String(searchedName, 0, index);
+			IJavaElement fragment = null;
+			try {
+				fragment = project.findPackageFragment(testedName);
+			} catch (JavaModelException e) {
+				return name;
+			}
+			if (fragment != null) {
+				return testedName;
+			}
+			try {
+				fragment = project.findType(testedName);
+			} catch (JavaModelException e) {
+				return name;
+			}
+			if (fragment != null) {
+				index = CharOperation.lastIndexOf(Signature.C_DOT, searchedName, 0, index - 1);
+			} else {
+				// we use the heuristic that a name starting with a lowercase is a package name
+				index = CharOperation.lastIndexOf(Signature.C_DOT, searchedName, 0, index - 1);
+				if (Character.isLowerCase(searchedName[index + 1])) {
+					return testedName;
+				}
+			}
+		} while (index >= 0); 
+		return name;
+	}
+
+	private static String getFullName(ImportDeclaration decl) {
+		String name= decl.getName().getFullyQualifiedName();
+		return decl.isOnDemand() ? name + ".*": name; //$NON-NLS-1$
+	}
+
+	private void addExistingImports(CompilationUnit root) {
+		List/*ImportDeclaration*/ decls= root.imports();
+		if (decls.isEmpty()) {
+			return;
+		}
+		PackageEntry currPackage= null;
+
+		ImportDeclaration curr= (ImportDeclaration) decls.get(0);
+		int currOffset= curr.getStartPosition();
+		int currLength= curr.getLength();
+		int currEndLine= root.getLineNumber(currOffset + currLength);
+
+		for (int i= 1; i < decls.size(); i++) {
+			boolean isStatic= curr.isStatic();
+			String name= getFullName(curr);
+			String packName= getQualifier(curr);
+			if (currPackage == null || currPackage.compareTo(packName, isStatic) != 0) {
+				currPackage= new PackageEntry(packName, null, isStatic);
+				this.packageEntries.add(currPackage);
+			}
+
+			ImportDeclaration next= (ImportDeclaration) decls.get(i);
+			int nextOffset= next.getStartPosition();
+			int nextLength= next.getLength();
+			int nextOffsetLine= root.getLineNumber(nextOffset);
+
+			int extendedStart = root.getExtendedStartPosition(curr);
+			int extendedLength = root.getExtendedLength(curr);
+			if (extendedStart < this.replaceRange.getOffset()) {
+				// don't touch the first comments before the start of import declarations
+				extendedLength -=  (currOffset - extendedStart);
+				extendedStart = currOffset;
+			}
+			
+			// if next import is on a different line, modify the end position to the next line begin offset
+			int nextLineOffset = nextOffset; // offset at the start of next line. Next import may not start here
+			if (currEndLine < nextOffsetLine) {
+				currEndLine++;
+				nextLineOffset = root.getPosition(currEndLine, 0); 
+				// There may be some leading comments (or line delimiters) before the next import. The start of those comments
+				// is not the real start offset of the next import. So don't change nextOffset
+			}
+			// retrieve preceding and trailing comments if any
+			IRegion rangeBefore = null;
+			IRegion rangeAfter = null;
+			
+			if (currOffset > extendedStart) {
+				rangeBefore = new Region(extendedStart, currOffset - extendedStart);
+			}
+			int currLen = curr.getLength();
+			if (currLen < extendedLength - (currOffset - extendedStart)) {
+				int currEndOffset = currOffset + currLen;
+				int rangeBeforeLen = rangeBefore != null? rangeBefore.getLength() : 0;
+				rangeAfter = new Region(currEndOffset, extendedLength - rangeBeforeLen - currLen);
+			}
+			currPackage.add(
+					new ImportDeclEntry(
+							packName.length(), 
+							name, 
+							isStatic, 
+							new Region(currOffset, nextLineOffset - currOffset), // should not include leading comments of next import, line delimiters, etc.
+							rangeBefore,
+							rangeAfter));
+			currOffset= nextOffset;
+			curr= next;
+
+			// add a comment entry for spacing between imports
+			if (currEndLine < nextOffsetLine) {
+				nextOffset= root.getPosition(nextOffsetLine, 0);
+
+				int length = nextOffset - nextLineOffset;
+				if (length > 2) { // valid comment has at least two chars
+					currPackage.add(new ImportDeclEntry(packName.length(), null, false, new Region(nextLineOffset, length)));
+				}
+
+				currOffset= nextOffset;
+			}
+			currEndLine= root.getLineNumber(nextOffset + nextLength);
+		}
+
+		boolean isStatic= curr.isStatic();
+		String name= getFullName(curr);
+		String packName= getQualifier(curr);
+		if (currPackage == null || currPackage.compareTo(packName, isStatic) != 0) {
+			currPackage= new PackageEntry(packName, null, isStatic);
+			this.packageEntries.add(currPackage);
+		}
+		int currStartOffset = curr.getStartPosition();
+		int currLen = curr.getLength();
+		int extendedStartOffset = root.getExtendedStartPosition(curr);
+		IRegion leadingComments = null;
+		IRegion allTrailingComments = null;
+		
+		if (currStartOffset > extendedStartOffset) {
+			leadingComments = new Region(extendedStartOffset, currOffset - extendedStartOffset);
+		}
+		int length= this.replaceRange.getOffset() + this.replaceRange.getLength() - currStartOffset;
+		int extendedLength = root.getExtendedLength(curr);
+		if (currLen < extendedLength - (currOffset - extendedStartOffset)) {
+			int currEndOffset = currOffset + currLen;
+			int leadingCommentsLen = leadingComments != null? leadingComments.getLength() : 0;
+			allTrailingComments = new Region(currEndOffset, extendedLength - leadingCommentsLen - currLen);
+		}
+		currPackage.add(new ImportDeclEntry(packName.length(), name, isStatic, new Region(curr.getStartPosition(), length), leadingComments, allTrailingComments));
+	}
+
+	private IRegion[] retrieveExistingCommentsInImports(CompilationUnit root) {
+		List/*ImportDeclaration*/ decls= root.imports();
+		if (decls.isEmpty()) {
+			return null;
+		}
+		
+		List commentList = root.getCommentList();
+		int numberOfComments = commentList.size();
+		List regions = null;
+		int currentExtendedEnd = -1;
+		int currEndLine= -1;
+
+		/* for the first comment, we only take the trailing comment if any and the replace range doesn't 
+		 * include the preceding comment
+		 */
+		for (int i= 0; i < decls.size(); i++) {
+			ImportDeclaration next= (ImportDeclaration) decls.get(i);
+			int nextOffset= next.getStartPosition();
+			int nextLength= next.getLength();
+
+			int extendedStart = root.getExtendedStartPosition(next);
+			int extendedLength = root.getExtendedLength(next);
+			int nextOffsetLine= root.getLineNumber(nextOffset);
+
+			if (nextOffset != extendedStart) {
+				// preceding comment
+				int lengthOfPrecedingComment = nextOffset - extendedStart;
+				if (i != 0) {
+					if (regions == null) {
+						regions = new ArrayList();
+					}
+					regions.add(new Region(extendedStart, lengthOfPrecedingComment));
+				}
+				
+				if (extendedLength != (nextLength + lengthOfPrecedingComment)) {
+					// Preceding and trailing comments 
+					int regionLength = extendedLength - (nextLength + lengthOfPrecedingComment);
+					if (regions == null) {
+						regions = new ArrayList();
+					}
+					regions.add(new Region(nextOffset + nextLength, regionLength));
+				}
+			} else if (nextLength != extendedLength) {
+				// no extended start - only trailing comment
+				int regionLength = extendedLength - nextLength;
+				if (regions == null) {
+					regions = new ArrayList();
+				}
+				regions.add(new Region(nextOffset + nextLength, regionLength));
+			}
+			if (i > 0) {
+				// record comments between the previous comment and the current one that are not part
+				// of any comment extended range.
+				if ((nextOffsetLine - currEndLine) > 1) {
+					// check for comments between the two imports
+					LineComment comment = root.getAST().newLineComment();
+					comment.setSourceRange(currentExtendedEnd + 1, 0);
+					int index = Collections.binarySearch(commentList, comment, new Comparator() {
+						public int compare(Object o1, Object o2) {
+							return ((Comment) o1).getStartPosition() - ((Comment) o2).getStartPosition();
+						}
+					});
+					// index = -(insertion point) - 1. 
+					if (index < 0) {
+						loop: for (int j = -(index + 1); j < numberOfComments; j++) {
+							Comment currentComment = (Comment) commentList.get(j);
+							int commentStartPosition = currentComment.getStartPosition();
+							int commentLength = currentComment.getLength();
+							if ((commentStartPosition > currentExtendedEnd)
+									&& ((commentStartPosition + commentLength - 1) < extendedStart)) {
+								if (regions == null) {
+									regions = new ArrayList();
+								}
+								regions.add(new Region(commentStartPosition, commentLength));
+							} else {
+								break loop;
+							}
+						}
+					}
+				}
+			}
+			currentExtendedEnd = extendedStart + extendedLength - 1;
+			currEndLine = root.getLineNumber(currentExtendedEnd);
+		}
+		if (regions == null) {
+			return null;
+		}
+		// sort regions according to their positions to restore comments in the same order
+		IRegion[] result = (IRegion[]) regions.toArray(new IRegion[regions.size()]);
+		Arrays.sort(result, new Comparator() {
+			public int compare(Object o1, Object o2) {
+				return ((IRegion) o1).getOffset() - ((IRegion) o2).getOffset();
+			}
+		});
+		return result;
+	}
+	/**
+	 * Specifies that implicit imports (for types in <code>java.lang</code>, types in the same package as the rewrite
+	 * compilation unit and types in the compilation unit's main type) should not be created, except if necessary to
+	 * resolve an on-demand import conflict.
+	 * <p>
+	 * The filter is enabled by default.
+	 * </p>
+	 * <p>
+	 * Note: {@link #ImportRewriteAnalyzer(ICompilationUnit, CompilationUnit, String[], int, int, boolean, boolean)} with true as the last
+	 * parameter can be used to filter implicit imports when a context is used.
+	 * </p>
+	 * 
+	 * @param filterImplicitImports
+	 *            if <code>true</code>, implicit imports will be filtered
+	 * 
+	 * @see #ImportRewriteAnalyzer(ICompilationUnit, CompilationUnit, String[], int, int, boolean, boolean)
+	 */
+	public void setFilterImplicitImports(boolean filterImplicitImports) {
+		this.filterImplicitImports= filterImplicitImports;
+	}
+	/**
+	 * When set searches for imports that can not be folded into on-demand
+	 * imports but must be specified explicitly
+	 * @param findAmbiguousImports The new value
+	 */
+	public void setFindAmbiguousImports(boolean findAmbiguousImports) {
+		this.findAmbiguousImports= findAmbiguousImports;
+	}
+
+	private static class PackageMatcher {
+		private String newName;
+		private String bestName;
+		private int bestMatchLen;
+
+		public PackageMatcher() {
+			// initialization in 'initialize'
+		}
+
+		public void initialize(String newImportName, String bestImportName) {
+			this.newName= newImportName;
+			this.bestName= bestImportName;
+			this.bestMatchLen= getCommonPrefixLength(bestImportName, newImportName);
+		}
+
+		public boolean isBetterMatch(String currName, boolean preferCurr) {
+			boolean isBetter;
+			int currMatchLen= getCommonPrefixLength(currName, this.newName);
+			int matchDiff= currMatchLen - this.bestMatchLen;
+			if (matchDiff == 0) {
+				if (currMatchLen == this.newName.length() && currMatchLen == currName.length() && currMatchLen == this.bestName.length()) {
+					// duplicate entry and complete match
+					isBetter= preferCurr;
+				} else {
+					isBetter= sameMatchLenTest(currName);
+				}
+			} else {
+				isBetter= (matchDiff > 0); // curr has longer match
+			}
+			if (isBetter) {
+				this.bestName= currName;
+				this.bestMatchLen= currMatchLen;
+			}
+			return isBetter;
+		}
+
+		private boolean sameMatchLenTest(String currName) {
+			int matchLen= this.bestMatchLen;
+			// known: bestName and currName differ from newName at position 'matchLen'
+			// currName and bestName don't have to differ at position 'matchLen'
+
+			// determine the order and return true if currName is closer to newName
+			char newChar= getCharAt(this.newName, matchLen);
+			char currChar= getCharAt(currName, matchLen);
+			char bestChar= getCharAt(this.bestName, matchLen);
+
+			if (newChar < currChar) {
+				if (bestChar < newChar) {								// b < n < c
+					return (currChar - newChar) < (newChar - bestChar);	// -> (c - n) < (n - b)
+				} else {												// n < b  && n < c
+					if (currChar == bestChar) { // longer match between curr and best
+						return false; // keep curr and best together, new should be before both
+					} else {
+						return currChar < bestChar; // -> (c < b)
+					}
+				}
+			} else {
+				if (bestChar > newChar) {								// c < n < b
+					return (newChar - currChar) < (bestChar - newChar);	// -> (n - c) < (b - n)
+				} else {												// n > b  && n > c
+					if (currChar == bestChar) {  // longer match between curr and best
+						return true; // keep curr and best together, new should be ahead of both
+					} else {
+						return currChar > bestChar; // -> (c > b)
+					}
+				}
+			}
+		}
+	}
+
+	/* package */ static int getCommonPrefixLength(String s, String t) {
+		int len= Math.min(s.length(), t.length());
+		for (int i= 0; i < len; i++) {
+			if (s.charAt(i) != t.charAt(i)) {
+				return i;
+			}
+		}
+		return len;
+	}
+
+	/* package */ static char getCharAt(String str, int index) {
+		if (str.length() > index) {
+			return str.charAt(index);
+		}
+		return 0;
+	}
+
+	private PackageEntry findBestMatch(String newName, boolean isStatic) {
+		if (this.packageEntries.isEmpty()) {
+			return null;
+		}
+		String groupId= null;
+		int longestPrefix= -1;
+		PackageEntry matchingCommentEntry = null;
+		// find the matching group
+		for (int i= 0; i < this.packageEntries.size(); i++) {
+			PackageEntry curr= (PackageEntry) this.packageEntries.get(i);
+			if (isStatic == curr.isStatic()) {
+				String currGroup= curr.getGroupID();
+				if (currGroup != null && newName.startsWith(currGroup)) {
+					int prefixLen= currGroup.length();
+					if (prefixLen == newName.length() && !curr.isComment()) {
+						return curr; // perfect fit, use entry
+					} else if (curr.isComment()) {
+						matchingCommentEntry = curr; // may be the only fit if no actual import of this group is already present
+						continue;
+					}
+					if ((newName.charAt(prefixLen) == '.' || prefixLen == 0) && prefixLen > longestPrefix) {
+						longestPrefix= prefixLen;
+						groupId= currGroup;
+					}
+				}
+			}
+		}
+		if (matchingCommentEntry != null) {
+			return matchingCommentEntry;
+		}
+		PackageEntry bestMatch= null;
+		PackageMatcher matcher= new PackageMatcher();
+		matcher.initialize(newName, ""); //$NON-NLS-1$
+		for (int i= 0; i < this.packageEntries.size(); i++) { // find the best match with the same group
+			PackageEntry curr= (PackageEntry) this.packageEntries.get(i);
+			if (!curr.isComment() && curr.isStatic() == isStatic) {
+				if (groupId == null || groupId.equals(curr.getGroupID())) {
+					boolean preferrCurr= (bestMatch == null) || (curr.getNumberOfImports() > bestMatch.getNumberOfImports());
+					if (matcher.isBetterMatch(curr.getName(), preferrCurr)) {
+						bestMatch= curr;
+					}
+				}
+			}
+		}
+		return bestMatch;
+	}
+
+	private boolean isImplicitImport(String qualifier) {
+		if (JAVA_LANG.equals(qualifier)) {
+			return true;
+		}
+		ICompilationUnit cu= this.compilationUnit;
+		String packageName= cu.getParent().getElementName();
+		if (qualifier.equals(packageName)) {
+			return true;
+		}
+		String mainTypeName= JavaCore.removeJavaLikeExtension(cu.getElementName());
+		if (packageName.length() == 0) {
+			return qualifier.equals(mainTypeName);
+		}
+		return qualifier.equals(packageName +'.' + mainTypeName);
+	}
+
+	public void addImport(String fullTypeName, boolean isStatic, CompilationUnit root, boolean restoreExistingImports) {
+		String typeContainerName= getQualifier(fullTypeName, isStatic);
+		ImportDeclEntry decl;
+		if (restoreExistingImports) {
+			decl = new ImportDeclEntry(typeContainerName.length(), fullTypeName, isStatic, null);
+		} else {
+			decl = addImportDeclEntry(typeContainerName, fullTypeName, isStatic, root);
+		}
+		sortIn(typeContainerName, decl, isStatic);
+	}
+
+	/**
+	 * adds the import entry, but if its an existing import entry then preserves the comments surrounding the import
+	 */
+	private ImportDeclEntry addImportDeclEntry(String containerName, String fullTypeName, boolean isStatic, CompilationUnit root) {
+		List/*ImportDeclaration*/ decls= root.imports();
+		if (decls.isEmpty() || this.preserveExistingCommentsRanges == null || this.preserveExistingCommentsRanges.length == 0) {
+			return new ImportDeclEntry(containerName.length(), fullTypeName, isStatic, null);
+		}
+		IRegion precedingCommentRange = null;
+		IRegion trailingCommentRange = null;
+		int prevOffset = this.replaceRange.getOffset();  // will store offset of the previous import's extended end
+		int numOfImports = decls.size();
+		for (int i= 0; i < numOfImports; i++) {
+			ImportDeclaration curr= (ImportDeclaration) decls.get(i);
+			int currOffset= curr.getStartPosition();
+			int currLength= curr.getLength();
+			int currExtendedStart = root.getExtendedStartPosition(curr);
+			int currExtendedLen = root.getExtendedLength(curr);
+			String name= getFullName(curr);
+			String packName= getQualifier(curr);
+			if (packName.equals(containerName) && (name.equals(fullTypeName) || name.endsWith("*"))) {//$NON-NLS-1$
+				int preserveCommentsLen = this.preserveExistingCommentsRanges.length;
+				for (int j = 0; j < preserveCommentsLen; j++) {
+					int offset = this.preserveExistingCommentsRanges[j].getOffset();
+					boolean wasRangeUsed = false;
+					int existingCommentLength = this.preserveExistingCommentsRanges[j].getLength();
+					if (offset == currExtendedStart) {
+						// comments belonging to this import's extended start
+						precedingCommentRange = new Region(offset, existingCommentLength);
+						wasRangeUsed = true;
+					} else if (offset < currExtendedStart && offset > prevOffset) {
+						// comment between two imports but not inside either's extended ranges
+						// to preserve the position of these comments add a dummy comment entry
+						PackageEntry commentEntry = new PackageEntry(); // create a comment package entry for this
+						commentEntry.setGroupID(packName);	// the comment should belong to the current group
+						this.packageEntries.add(commentEntry);
+						commentEntry.add(new ImportDeclEntry(packName.length(), null, false, new Region(offset, existingCommentLength)));
+						wasRangeUsed = true;
+					} else if ((currExtendedStart + currExtendedLen) != (currOffset + currLength)){
+						if (offset == currOffset + currLength) {
+							// comment is in the extended end of the import
+							trailingCommentRange = new Region(offset, existingCommentLength);
+							wasRangeUsed = true;
+						} else if (offset > (currOffset + currLength)) {
+							break;
+						}
+					}
+					if (wasRangeUsed) {
+						// remove this comment from preserveExistingCommentsRanges array
+						IRegion[] tempRegions = new IRegion[--preserveCommentsLen];
+						System.arraycopy(this.preserveExistingCommentsRanges, 0, tempRegions, 0, j);
+						System.arraycopy(this.preserveExistingCommentsRanges, j+1, tempRegions, j, tempRegions.length - j);
+						this.preserveExistingCommentsRanges = tempRegions;
+						j--;
+					}
+				}
+				return new ImportDeclEntry(containerName.length(), fullTypeName, isStatic, null, precedingCommentRange, trailingCommentRange);
+			}
+			prevOffset = currExtendedStart + currExtendedLen - 1;
+		}
+		return new ImportDeclEntry(containerName.length(), fullTypeName, isStatic, null);
+	}
+
+	public boolean removeImport(String qualifiedName, boolean isStatic) {
+		String containerName= getQualifier(qualifiedName, isStatic);
+
+		int nPackages= this.packageEntries.size();
+		for (int i= 0; i < nPackages; i++) {
+			PackageEntry entry= (PackageEntry) this.packageEntries.get(i);
+			if (entry.compareTo(containerName, isStatic) == 0) {
+				if (entry.remove(qualifiedName, isStatic)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private int getIndexAfterStatics() {
+		for (int i= 0; i < this.packageEntries.size(); i++) {
+			if (!((PackageEntry) this.packageEntries.get(i)).isStatic()) {
+				return i;
+			}
+		}
+		return this.packageEntries.size();
+	}
+
+
+	private void sortIn(String typeContainerName, ImportDeclEntry decl, boolean isStatic) {
+		PackageEntry bestMatch= findBestMatch(typeContainerName, isStatic);
+		if (bestMatch == null) {
+			PackageEntry packEntry= new PackageEntry(typeContainerName, null, isStatic);
+			packEntry.add(decl);
+			int insertPos= packEntry.isStatic() ? 0 : getIndexAfterStatics();
+			this.packageEntries.add(insertPos, packEntry);
+		} else {
+			int cmp= typeContainerName.compareTo(bestMatch.getName());
+			if (cmp == 0) {
+				bestMatch.sortIn(decl);
+			} else {
+				// create a new package entry
+				String group= bestMatch.getGroupID();
+				if (group != null) {
+					if (!typeContainerName.startsWith(group)) {
+						group= null;
+					}
+				}
+				PackageEntry packEntry= new PackageEntry(typeContainerName, group, isStatic);
+				packEntry.add(decl);
+				int index= this.packageEntries.indexOf(bestMatch);
+				if (cmp < 0) {
+					// insert ahead of best match
+					this.packageEntries.add(index, packEntry);
+				} else {
+					// insert after best match
+					this.packageEntries.add(index + 1, packEntry);
+				}
+			}
+		}
+	}
+
+	private IRegion evaluateReplaceRange(CompilationUnit root) {
+		List imports= root.imports();
+		if (!imports.isEmpty()) {
+			ImportDeclaration first= (ImportDeclaration) imports.get(0);
+			ImportDeclaration last= (ImportDeclaration) imports.get(imports.size() - 1);
+
+			int startPos= first.getStartPosition(); // no extended range for first: bug 121428
+			int endPos= root.getExtendedStartPosition(last) + root.getExtendedLength(last);
+			int endLine= root.getLineNumber(endPos);
+			if (endLine > 0) {
+				int nextLinePos= root.getPosition(endLine + 1, 0);
+				if (nextLinePos >= 0) {
+					int firstTypePos= getFirstTypeBeginPos(root);
+					if (firstTypePos != -1 && firstTypePos < nextLinePos) {
+						endPos= firstTypePos;
+					} else {
+						endPos= nextLinePos;
+					}
+				}
+			}
+			return new Region(startPos, endPos - startPos);
+		} else {
+			int start= getPackageStatementEndPos(root);
+			return new Region(start, 0);
+		}
+	}
+
+	public MultiTextEdit getResultingEdits(IProgressMonitor monitor) throws JavaModelException {
+		if (monitor == null) {
+			monitor= new NullProgressMonitor();
+		}
+		try {
+			int importsStart=  this.replaceRange.getOffset();
+			int importsLen= this.replaceRange.getLength();
+
+			String lineDelim= this.compilationUnit.findRecommendedLineSeparator();
+			IBuffer buffer= this.compilationUnit.getBuffer();
+
+			int currPos= importsStart;
+			MultiTextEdit resEdit= new MultiTextEdit();
+
+			if ((this.flags & F_NEEDS_LEADING_DELIM) != 0) {
+				// new import container
+				resEdit.addChild(new InsertEdit(currPos, lineDelim));
+			}
+
+			PackageEntry lastPackage= null;
+
+			Set onDemandConflicts= null;
+			if (this.findAmbiguousImports) {
+				onDemandConflicts= evaluateStarImportConflicts(monitor);
+			}
+
+			int spacesBetweenGroups= getSpacesBetweenImportGroups();
+
+			ArrayList stringsToInsert= new ArrayList();
+
+			int nPackageEntries= this.packageEntries.size();
+			for (int i= 0; i < nPackageEntries; i++) {
+				PackageEntry pack= (PackageEntry) this.packageEntries.get(i);
+				if (this.filterImplicitImports && !pack.isStatic() && isImplicitImport(pack.getName())) {
+					pack.filterImplicitImports(this.useContextToFilterImplicitImports);
+				}
+				int nImports= pack.getNumberOfImports();
+				if (nImports == 0) {
+					continue;
+				}
+
+				if (spacesBetweenGroups > 0 && lastPackage != null) {
+					// add a space between two different groups by looking at the two adjacent imports
+					if (!lastPackage.isComment() && !pack.isComment() && !pack.isSameGroup(lastPackage)) {
+						for (int k= spacesBetweenGroups; k > 0; k--) {
+							stringsToInsert.add(lineDelim);
+						}
+					} else if (lastPackage.isComment() && pack.isSameGroup(lastPackage)) {
+						// the last pack may be a dummy for a comment which doesn't belong to any extended range
+						stringsToInsert.add(lineDelim);
+					}
+				}
+				lastPackage= pack;
+
+				boolean isStatic= pack.isStatic();
+				int threshold= isStatic ? this.staticImportOnDemandThreshold : this.importOnDemandThreshold;
+
+				boolean doStarImport= pack.hasStarImport(threshold, onDemandConflicts);
+				boolean allImportsAddedToStar = false;
+				if (doStarImport && (pack.find("*") == null)) { //$NON-NLS-1$
+					String[] imports = getNewImportStrings(buffer, pack, isStatic, lineDelim);
+					for (int j = 0, max = imports.length; j < max; j++) {
+						stringsToInsert.add(imports[j]);
+					}
+					allImportsAddedToStar = true; // may still need to handle onDemandConflicts below
+				}
+
+				for (int k= 0; k < nImports; k++) {
+					ImportDeclEntry currDecl= pack.getImportAt(k);
+					IRegion region= currDecl.getSourceRange();
+					boolean isConflict = !currDecl.isComment() && onDemandConflicts != null && onDemandConflicts.contains(currDecl.getSimpleName());
+					boolean addRegularToStar = doStarImport && !currDecl.isOnDemand();
+					
+					if (region == null) { // new entry
+						if (!addRegularToStar || isConflict) {
+							IRegion rangeBefore = currDecl.getPrecedingCommentRange();
+							IRegion rangeAfter = currDecl.getTrailingCommentRange();
+							if (rangeBefore != null) {
+								stringsToInsert.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+							}
+							
+							String trailingComment = null;
+							if (rangeAfter != null) {
+								trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength());
+							}
+							String str= getNewImportString(currDecl.getElementName(), isStatic, trailingComment, lineDelim);
+							stringsToInsert.add(str);
+						} else if (addRegularToStar && !allImportsAddedToStar) {
+							String simpleName = currDecl.getTypeQualifiedName();
+							if (simpleName.indexOf('.') != -1) {
+								String str= getNewImportString(currDecl.getElementName(), isStatic, lineDelim);
+								if (stringsToInsert.indexOf(str) == -1) {
+									stringsToInsert.add(str);
+								}
+							}
+						}
+					} else if (!addRegularToStar || isConflict) {
+						int offset= region.getOffset();
+						IRegion rangeBefore = currDecl.getPrecedingCommentRange();
+						if (rangeBefore != null && currPos > rangeBefore.getOffset()) {
+							// moved ahead of the leading comments, bring the currPos back
+							currPos = rangeBefore.getOffset();
+						}
+						if (rangeBefore != null) {
+							stringsToInsert.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+						}
+						removeAndInsertNew(buffer, currPos, offset, stringsToInsert, resEdit);
+						stringsToInsert.clear();
+						currPos= offset + region.getLength();
+					} else if (addRegularToStar && !allImportsAddedToStar && !currDecl.isComment()) {
+						String simpleName = currDecl.getTypeQualifiedName();
+						if (simpleName.indexOf('.') != -1) {
+							IRegion rangeBefore = currDecl.getPrecedingCommentRange();
+							if (rangeBefore != null && currPos > rangeBefore.getOffset()) {
+								// moved ahead of the leading comments, bring the currPos back
+								currPos = rangeBefore.getOffset();
+							}
+							if (rangeBefore != null) {
+								stringsToInsert.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+							}
+							IRegion rangeAfter = currDecl.getTrailingCommentRange();
+							String trailingComment = null;
+							if (rangeAfter != null) {
+								trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength());
+							}
+							String str= getNewImportString(currDecl.getElementName(), isStatic, trailingComment, lineDelim);
+							if (stringsToInsert.indexOf(str) == -1) {
+								stringsToInsert.add(str);
+							}
+						}
+					}
+				}
+			}
+
+			// insert back all existing imports comments since existing imports were not preserved
+			if (this.preserveExistingCommentsRanges != null) {
+				for (int i = 0, max = this.preserveExistingCommentsRanges.length; (i < max && this.preserveExistingCommentsRanges[i] != null); i++) {
+					IRegion region = this.preserveExistingCommentsRanges[i];
+					String text = buffer.getText(region.getOffset(), region.getLength());
+					// remove preceding whitespaces
+					int index = 0;
+					int length = text.length();
+					loop: while (index < length) {
+						if (Character.isWhitespace(text.charAt(index))) {
+							index++;
+						} else {
+							break loop;
+						}
+					}
+					if (index != 0) {
+						text = text.substring(index);
+					}
+					if (!text.endsWith(lineDelim)) {
+						text += lineDelim;
+					}
+					stringsToInsert.add(text);
+				}
+			}
+			int end= importsStart + importsLen;
+			removeAndInsertNew(buffer, currPos, end, stringsToInsert, resEdit);
+
+			if (importsLen == 0) {
+				if (!this.importsCreated.isEmpty() || !this.staticImportsCreated.isEmpty()) { // new import container
+					if ((this.flags & F_NEEDS_TRAILING_DELIM) != 0) {
+						resEdit.addChild(new InsertEdit(currPos, lineDelim));
+					}
+				} else {
+					return new MultiTextEdit(); // no changes
+				}
+			}
+			return resEdit;
+		} finally {
+			monitor.done();
+		}
+	}
+
+	private void removeAndInsertNew(IBuffer buffer, int contentOffset, int contentEnd, ArrayList stringsToInsert, MultiTextEdit resEdit) {
+		int pos= contentOffset;
+		for (int i= 0; i < stringsToInsert.size(); i++) {
+			String curr= (String) stringsToInsert.get(i);
+			int idx= findInBuffer(buffer, curr, pos, contentEnd);
+			if (idx != -1) {
+				if (idx != pos) {
+					resEdit.addChild(new DeleteEdit(pos, idx - pos));
+				}
+				pos= idx + curr.length();
+			} else {
+				resEdit.addChild(new InsertEdit(pos, curr));
+			}
+		}
+		if (pos < contentEnd) {
+			resEdit.addChild(new DeleteEdit(pos, contentEnd - pos));
+		}
+	}
+
+	private int findInBuffer(IBuffer buffer, String str, int start, int end) {
+		int pos= start;
+		int len= str.length();
+		if (pos + len > end || str.length() == 0) {
+			return -1;
+		}
+		char first= str.charAt(0);
+		int step= str.indexOf(first, 1);
+		if (step == -1) {
+			step= len;
+		}
+		while (pos + len <= end) {
+			if (buffer.getChar(pos) == first) {
+				int k= 1;
+				while (k < len && buffer.getChar(pos + k) == str.charAt(k)) {
+					k++;
+				}
+				if (k == len) {
+					return pos; // found
+				}
+				if (k < step) {
+					pos+= k;
+				} else {
+					pos+= step;
+				}
+			} else {
+				pos++;
+			}
+		}
+		return -1;
+	}
+
+	private Set evaluateStarImportConflicts(IProgressMonitor monitor) throws JavaModelException {
+		//long start= System.currentTimeMillis();
+
+		final HashSet/*String*/ onDemandConflicts= new HashSet();
+
+		IJavaSearchScope scope= SearchEngine.createJavaSearchScope(new IJavaElement[] { this.compilationUnit.getJavaProject() });
+
+		ArrayList/*<char[][]>*/  starImportPackages= new ArrayList();
+		ArrayList/*<char[][]>*/ simpleTypeNames= new ArrayList();
+		int nPackageEntries= this.packageEntries.size();
+		for (int i= 0; i < nPackageEntries; i++) {
+			PackageEntry pack= (PackageEntry) this.packageEntries.get(i);
+			if (!pack.isStatic() && pack.hasStarImport(this.importOnDemandThreshold, null)) {
+				starImportPackages.add(pack.getName().toCharArray());
+				for (int k= 0; k < pack.getNumberOfImports(); k++) {
+					ImportDeclEntry curr= pack.getImportAt(k);
+					if (!curr.isOnDemand() && !curr.isComment()) {
+						simpleTypeNames.add(curr.getSimpleName().toCharArray());
+					}
+				}
+			}
+		}
+		if (starImportPackages.isEmpty()) {
+			return null;
+		}
+
+		starImportPackages.add(this.compilationUnit.getParent().getElementName().toCharArray());
+		starImportPackages.add(JAVA_LANG.toCharArray());
+
+		char[][] allPackages= (char[][]) starImportPackages.toArray(new char[starImportPackages.size()][]);
+		char[][] allTypes= (char[][]) simpleTypeNames.toArray(new char[simpleTypeNames.size()][]);
+
+		TypeNameRequestor requestor= new TypeNameRequestor() {
+			HashMap foundTypes= new HashMap();
+
+			private String getTypeContainerName(char[] packageName, char[][] enclosingTypeNames) {
+				StringBuffer buf= new StringBuffer();
+				buf.append(packageName);
+				for (int i= 0; i < enclosingTypeNames.length; i++) {
+					if (buf.length() > 0)
+						buf.append('.');
+					buf.append(enclosingTypeNames[i]);
+				}
+				return buf.toString();
+			}
+
+			public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
+				String name= new String(simpleTypeName);
+				String containerName= getTypeContainerName(packageName, enclosingTypeNames);
+
+				String oldContainer= (String) this.foundTypes.put(name, containerName);
+				if (oldContainer != null && !oldContainer.equals(containerName)) {
+					onDemandConflicts.add(name);
+				}
+			}
+		};
+		new SearchEngine().searchAllTypeNames(allPackages, allTypes, scope, requestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor);
+		return onDemandConflicts;
+	}
+
+	private String getNewImportString(String importName, boolean isStatic, String lineDelim) {
+		return getNewImportString(importName, isStatic, null, lineDelim);
+	}
+	
+	private String getNewImportString(String importName, boolean isStatic, String trailingComment, String lineDelim) {
+		StringBuffer buf= new StringBuffer();
+		buf.append("import "); //$NON-NLS-1$
+		if (isStatic) {
+			buf.append("static "); //$NON-NLS-1$
+		}
+		buf.append(importName);
+		if (insertSpaceBeforeSemicolon()) buf.append(' ');
+		buf.append(';');
+		if (trailingComment != null) {
+			buf.append(trailingComment);
+		}
+		buf.append(lineDelim);
+
+		if (isStatic) {
+			this.staticImportsCreated.add(importName);
+		} else {
+			this.importsCreated.add(importName);
+		}
+		return buf.toString();
+	}
+	
+	private String[] getNewImportStrings(IBuffer buffer, PackageEntry packageEntry, boolean isStatic, String lineDelim) {
+		boolean isStarImportAdded = false;
+		List allImports = new ArrayList();
+		int nImports = packageEntry.getNumberOfImports();
+		StringBuffer allComments = null;
+		StringBuffer allCommentsLead = null;
+		for (int i= 0; i < nImports; i++) {
+			ImportDeclEntry curr= packageEntry.getImportAt(i);
+			if (curr.isComment()) {
+				IRegion rangeBefore = curr.getPrecedingCommentRange();
+				if (rangeBefore != null) {
+					allImports.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+				}
+				IRegion rangeAfter = curr.getTrailingCommentRange();
+				String trailingComment = null;
+				if (rangeAfter != null) {
+					trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength());
+				}
+				if (trailingComment != null) {
+					allImports.add(buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()));
+				}
+			} else {
+				String simpleName = curr.getTypeQualifiedName();
+				if (simpleName.indexOf('.') != -1) {
+					// member type imports - we preserve it
+					IRegion rangeBefore = curr.getPrecedingCommentRange();
+					if (rangeBefore != null) {
+						allImports.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+					}
+					IRegion rangeAfter = curr.getTrailingCommentRange();
+					String trailingComment = null;
+					if (rangeAfter != null) {
+						trailingComment = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength());
+					}
+					allImports.add(getNewImportString(curr.getElementName(), isStatic, trailingComment, lineDelim));
+				} else if (!isStarImportAdded) {
+					String starImportString= packageEntry.getName() + ".*"; //$NON-NLS-1$
+					// collect all comments
+					IRegion rangeBefore = curr.getPrecedingCommentRange();
+					if (rangeBefore != null) {
+						allImports.add(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+					}
+					IRegion rangeAfter = curr.getTrailingCommentRange();
+					String trailComments = null;
+					if (rangeAfter != null) {
+						trailComments = buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength());
+					}
+					allImports.add(getNewImportString(starImportString, isStatic, trailComments, lineDelim));
+					isStarImportAdded = true;
+				} else {
+					// collect all comments
+					IRegion rangeBefore = curr.getPrecedingCommentRange();
+					if (rangeBefore != null) {
+						if (allCommentsLead == null) {
+							allCommentsLead = new StringBuffer();
+						}
+						allCommentsLead.append(buffer.getText(rangeBefore.getOffset(), rangeBefore.getLength()));
+					}
+					IRegion rangeAfter = curr.getTrailingCommentRange();
+					if (rangeAfter != null) {
+						if (allComments == null) {
+							allComments = new StringBuffer();
+						}
+						allComments.append(buffer.getText(rangeAfter.getOffset(), rangeAfter.getLength()));
+					}
+				}
+			}
+		}
+		if (allCommentsLead != null) {
+			allImports.add(0, String.valueOf(allCommentsLead));
+		}
+		if (allComments != null) {
+			allImports.add(String.valueOf(allComments.append(lineDelim)));
+		}
+		return (String[]) allImports.toArray(new String[allImports.size()]);
+	}
+
+	private static int getFirstTypeBeginPos(CompilationUnit root) {
+		List types= root.types();
+		if (!types.isEmpty()) {
+			return root.getExtendedStartPosition(((ASTNode) types.get(0)));
+		}
+		return -1;
+	}
+
+	private int getPackageStatementEndPos(CompilationUnit root) {
+		PackageDeclaration packDecl= root.getPackage();
+		if (packDecl != null) {
+			int afterPackageStatementPos= -1;
+			int lineNumber= root.getLineNumber(packDecl.getStartPosition() + packDecl.getLength());
+			if (lineNumber >= 0) {
+				int lineAfterPackage= lineNumber + 1;
+				afterPackageStatementPos= root.getPosition(lineAfterPackage, 0);
+			}
+			if (afterPackageStatementPos < 0) {
+				this.flags|= F_NEEDS_LEADING_DELIM;
+				return packDecl.getStartPosition() + packDecl.getLength();
+			}
+			int firstTypePos= getFirstTypeBeginPos(root);
+			if (firstTypePos != -1 && firstTypePos <= afterPackageStatementPos) {
+				this.flags|= F_NEEDS_TRAILING_DELIM;
+				if (firstTypePos == afterPackageStatementPos) {
+					this.flags|= F_NEEDS_LEADING_DELIM;
+				}
+				return firstTypePos;
+			}
+			this.flags|= F_NEEDS_LEADING_DELIM;
+			return afterPackageStatementPos; // insert a line after after package statement
+		}
+		this.flags |= F_NEEDS_TRAILING_DELIM;
+		return 0;
+	}
+
+	public String toString() {
+		int nPackages= this.packageEntries.size();
+		StringBuffer buf= new StringBuffer("\n-----------------------\n"); //$NON-NLS-1$
+		for (int i= 0; i < nPackages; i++) {
+			PackageEntry entry= (PackageEntry) this.packageEntries.get(i);
+			if (entry.isStatic()) {
+				buf.append("static "); //$NON-NLS-1$
+			}
+			buf.append(entry.toString());
+		}
+		return buf.toString();
+	}
+
+	private static final class ImportDeclEntry {
+
+		private String elementName;
+		private IRegion sourceRange;
+		private final boolean isStatic;
+		private int containerNameLength;
+		IRegion precedingCommentRange;
+		IRegion trailingCommentRange;
+
+		public ImportDeclEntry(
+				int containerNameLength,
+				String elementName,
+				boolean isStatic,
+				IRegion sourceRange,
+				IRegion precedingCommentRange,
+				IRegion trailingCommentRange) {
+			this(containerNameLength, elementName, isStatic, sourceRange);
+			this.precedingCommentRange = precedingCommentRange;
+			this.trailingCommentRange = trailingCommentRange;
+		}
+
+		public ImportDeclEntry(int containerNameLength, String elementName, boolean isStatic, IRegion sourceRange) {
+			this.elementName= elementName;
+			this.sourceRange= sourceRange;
+			this.isStatic= isStatic;
+			this.containerNameLength = containerNameLength;
+		}
+
+		public String getElementName() {
+			return this.elementName;
+		}
+
+		public int compareTo(String fullName, boolean isStaticImport) {
+			int cmp= this.elementName.compareTo(fullName);
+			if (cmp == 0) {
+				if (this.isStatic == isStaticImport) {
+					return 0;
+				}
+				return this.isStatic ? -1 : 1;
+			}
+			return cmp;
+		}
+
+		public String getSimpleName() {
+			return Signature.getSimpleName(this.elementName);
+		}
+
+		public String getTypeQualifiedName() {
+			return this.elementName.substring(this.containerNameLength + 1);
+		}
+		
+		public boolean isOnDemand() {
+			return this.elementName != null && this.elementName.endsWith(".*"); //$NON-NLS-1$
+		}
+
+		public boolean isStatic() {
+			return this.isStatic;
+		}
+
+		public boolean isNew() {
+			return this.sourceRange == null;
+		}
+
+		public boolean isComment() {
+			return this.elementName == null;
+		}
+
+		public IRegion getSourceRange() {
+			return this.sourceRange;
+		}
+		
+		public IRegion getPrecedingCommentRange() {
+			return this.precedingCommentRange;
+		}
+
+		public IRegion getTrailingCommentRange() {
+			return this.trailingCommentRange;
+		}
+	}
+
+	/*
+	 * Internal element for the import structure: A container for imports
+	 * of all types from the same package
+	 */
+	private final static class PackageEntry {
+		private String name;
+		private ArrayList importEntries;
+		private String group;
+		private boolean isStatic;
+
+		/**
+		 * Comment package entry
+		 */
+		public PackageEntry() {
+			this("!", null, false); //$NON-NLS-1$
+		}
+
+		/**
+		 * @param name Name of the package entry. e.g. org.eclipse.jdt.ui, containing imports like
+		 * org.eclipse.jdt.ui.JavaUI.
+		 * @param group The index of the preference order entry assigned
+		 *    different group id's will result in spacers between the entries
+		 */
+		public PackageEntry(String name, String group, boolean isStatic) {
+			this.name= name;
+			this.importEntries= new ArrayList(5);
+			this.group= group;
+			this.isStatic= isStatic;
+		}
+
+		public boolean isStatic() {
+			return this.isStatic;
+		}
+
+		public int compareTo(String otherName, boolean isOtherStatic) {
+			int cmp= this.name.compareTo(otherName);
+			if (cmp == 0) {
+				if (this.isStatic == isOtherStatic) {
+					return 0;
+				}
+				return this.isStatic ? -1 : 1;
+			}
+			return cmp;
+		}
+
+		public void sortIn(ImportDeclEntry imp) {
+			String fullImportName= imp.getElementName();
+			int insertPosition= -1;
+			int nInports= this.importEntries.size();
+			for (int i= 0; i < nInports; i++) {
+				ImportDeclEntry curr= getImportAt(i);
+				if (!curr.isComment()) {
+					int cmp= curr.compareTo(fullImportName, imp.isStatic());
+					if (cmp == 0) {
+						return; // exists already
+					} else if (cmp > 0 && insertPosition == -1) {
+						insertPosition= i;
+					}
+				}
+			}
+			if (insertPosition == -1) {
+				this.importEntries.add(imp);
+			} else {
+				this.importEntries.add(insertPosition, imp);
+			}
+		}
+
+
+		public void add(ImportDeclEntry imp) {
+			this.importEntries.add(imp);
+		}
+
+		public ImportDeclEntry find(String simpleName) {
+			int nInports= this.importEntries.size();
+			for (int i= 0; i < nInports; i++) {
+				ImportDeclEntry curr= getImportAt(i);
+				if (!curr.isComment()) {
+					String currName= curr.getElementName();
+					if (currName.endsWith(simpleName)) {
+						int dotPos= currName.length() - simpleName.length() - 1;
+						if ((dotPos == -1) || (dotPos > 0 && currName.charAt(dotPos) == '.')) {
+							return curr;
+						}
+					}
+				}
+			}
+			return null;
+		}
+
+		public boolean remove(String fullName, boolean isStaticImport) {
+			int nInports= this.importEntries.size();
+			for (int i= 0; i < nInports; i++) {
+				ImportDeclEntry curr= getImportAt(i);
+				if (!curr.isComment() && curr.compareTo(fullName, isStaticImport) == 0) {
+					this.importEntries.remove(i);
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public void filterImplicitImports(boolean useContextToFilterImplicitImports) {
+			int nInports= this.importEntries.size();
+			for (int i= nInports - 1; i >= 0; i--) {
+				ImportDeclEntry curr= getImportAt(i);
+				if (curr.isNew()) {
+					if (!useContextToFilterImplicitImports) {
+						this.importEntries.remove(i);
+					} else {
+						String elementName = curr.getElementName();
+						int lastIndexOf = elementName.lastIndexOf('.');
+						boolean internalClassImport = lastIndexOf > getName().length();
+						if (!internalClassImport) {
+							this.importEntries.remove(i);
+						}
+					}
+				}
+			}
+		}
+
+		public ImportDeclEntry getImportAt(int index) {
+			return (ImportDeclEntry) this.importEntries.get(index);
+		}
+
+		public boolean hasStarImport(int threshold, Set explicitImports) {
+			if (isComment() || isDefaultPackage()) { // can not star import default package
+				return false;
+			}
+			int nImports= getNumberOfImports();
+			int count= 0;
+			boolean containsNew= false;
+			for (int i= 0; i < nImports; i++) {
+				ImportDeclEntry curr= getImportAt(i);
+				if (curr.isOnDemand()) {
+					return true;
+				}
+				if (!curr.isComment()) {
+					count++;
+					boolean isExplicit= !curr.isStatic() && (explicitImports != null) && explicitImports.contains(curr.getSimpleName());
+					containsNew |= curr.isNew() && !isExplicit;
+				}
+			}
+			return (count >= threshold) && containsNew;
+		}
+
+		public int getNumberOfImports() {
+			return this.importEntries.size();
+		}
+
+		public String getName() {
+			return this.name;
+		}
+
+		public String getGroupID() {
+			return this.group;
+		}
+
+		public void setGroupID(String groupID) {
+			this.group= groupID;
+		}
+
+		public boolean isSameGroup(PackageEntry other) {
+			if (this.group == null) {
+				return other.getGroupID() == null;
+			} else {
+				return this.group.equals(other.getGroupID()) && (this.isStatic == other.isStatic());
+			}
+		}
+
+		public boolean isComment() {
+			return "!".equals(this.name); //$NON-NLS-1$
+		}
+
+		public boolean isDefaultPackage() {
+			return this.name.length() == 0;
+		}
+
+		public String toString() {
+			StringBuffer buf= new StringBuffer();
+			if (isComment()) {
+				buf.append("comment\n"); //$NON-NLS-1$
+			} else {
+				buf.append(this.name); buf.append(", groupId: "); buf.append(this.group); buf.append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
+				int nImports= getNumberOfImports();
+				for (int i= 0; i < nImports; i++) {
+					ImportDeclEntry curr= getImportAt(i);
+					buf.append(" "); //$NON-NLS-1$
+					if (curr.isComment()) {
+						buf.append("comment"); //$NON-NLS-1$
+					} else {
+						if (curr.isStatic()) {
+							buf.append("static "); //$NON-NLS-1$
+						}
+						buf.append(curr.getTypeQualifiedName());
+					}
+					if (curr.isNew()) {
+						buf.append(" (new)"); //$NON-NLS-1$
+					}
+					buf.append("\n"); //$NON-NLS-1$
+				}
+			}
+			return buf.toString();
+		}
+	}
+
+	public String[] getCreatedImports() {
+	    return (String[]) this.importsCreated.toArray(new String[this.importsCreated.size()]);
+	}
+
+	public String[] getCreatedStaticImports() {
+	    return (String[]) this.staticImportsCreated.toArray(new String[this.staticImportsCreated.size()]);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineCommentEndOffsets.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineCommentEndOffsets.java
new file mode 100644
index 0000000..026b1cf
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineCommentEndOffsets.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.LineComment;
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class LineCommentEndOffsets {
+
+	private int[] offsets;
+	private final List commentList;
+
+	public LineCommentEndOffsets(List commentList) {
+		this.commentList= commentList;
+		this.offsets= null; // create on demand
+	}
+
+	private int[] getOffsets() {
+		if (this.offsets == null) {
+			if (this.commentList != null) {
+				int nComments= this.commentList.size();
+				// count the number of line comments
+				int count= 0;
+				for (int i= 0; i < nComments; i++) {
+					Object curr= this.commentList.get(i);
+					if (curr instanceof LineComment) {
+						count++;
+					}
+				}
+				// fill the offset table
+				this.offsets= new int[count];
+				for (int i= 0, k= 0; i < nComments; i++) {
+					Object curr= this.commentList.get(i);
+					if (curr instanceof LineComment) {
+						LineComment comment= (LineComment) curr;
+						this.offsets[k++]= comment.getStartPosition() + comment.getLength();
+					}
+				}
+			} else {
+				this.offsets= Util.EMPTY_INT_ARRAY;
+			}
+		}
+		return this.offsets;
+	}
+
+	public boolean isEndOfLineComment(int offset) {
+		return offset >= 0 && Arrays.binarySearch(getOffsets(), offset) >= 0;
+	}
+
+	public boolean isEndOfLineComment(int offset, char[] content) {
+		if (offset < 0 || (offset < content.length && !IndentManipulation.isLineDelimiterChar(content[offset]))) {
+			return false;
+		}
+		return Arrays.binarySearch(getOffsets(), offset) >= 0;
+	}
+
+	public boolean remove(int offset) {
+		int[] offsetArray= getOffsets(); // returns the shared array
+		int index= Arrays.binarySearch(offsetArray, offset);
+		if (index >= 0) {
+			if (index > 0) {
+				// shift from the beginning and insert -1 (smallest number) at the beginning
+				// 1, 2, 3, x, 4, 5 -> -1, 1, 2, 3, 4, 5
+				System.arraycopy(offsetArray, 0, offsetArray, 1, index);
+			}
+			offsetArray[0]= -1;
+			return true;
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineInformation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineInformation.java
new file mode 100644
index 0000000..200db80
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/LineInformation.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ *
+ */
+public abstract class LineInformation {
+
+	public static LineInformation create(final IDocument doc) {
+		return new LineInformation() {
+			public int getLineOfOffset(int offset) {
+				try {
+					return doc.getLineOfOffset(offset);
+				} catch (BadLocationException e) {
+					return -1;
+				}
+			}
+
+			public int getLineOffset(int line) {
+				try {
+					return doc.getLineOffset(line);
+				} catch (BadLocationException e) {
+					return -1;
+				}
+			}
+		};
+	}
+
+	public static LineInformation create(final CompilationUnit astRoot) {
+		return new LineInformation() {
+			public int getLineOfOffset(int offset) {
+				return astRoot.getLineNumber(offset) - 1;
+			}
+			public int getLineOffset(int line) {
+				return astRoot.getPosition(line + 1, 0);
+			}
+		};
+	}
+
+
+
+	public abstract int getLineOfOffset(int offset);
+	public abstract int getLineOffset(int line);
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java
new file mode 100644
index 0000000..7ba9a33
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+
+/**
+ *
+ */
+public class ListRewriteEvent extends RewriteEvent {
+
+	public final static int NEW= 1;
+	public final static int OLD= 2;
+	public final static int BOTH= NEW | OLD;
+
+	/** original list of 'ASTNode' */
+	private List originalNodes;
+
+	/** list of type 'RewriteEvent' */
+	private List listEntries;
+
+	/**
+	 * Creates a ListRewriteEvent from the original ASTNodes. The resulting event
+	 * represents the unmodified list.
+	 * @param originalNodes The original nodes (type ASTNode)
+	 */
+	public ListRewriteEvent(List originalNodes) {
+		this.originalNodes= new ArrayList(originalNodes);
+	}
+
+	/**
+	 * Creates a ListRewriteEvent from existing rewrite events.
+	 * @param children The rewrite events for this list.
+	 */
+	public ListRewriteEvent(RewriteEvent[] children) {
+		this.listEntries= new ArrayList(children.length * 2);
+		this.originalNodes= new ArrayList(children.length * 2);
+		for (int i= 0; i < children.length; i++) {
+			RewriteEvent curr= children[i];
+			this.listEntries.add(curr);
+			if (curr.getOriginalValue() != null) {
+				this.originalNodes.add(curr.getOriginalValue());
+			}
+		}
+	}
+
+	private List getEntries() {
+		if (this.listEntries == null) {
+			// create if not yet existing
+			int nNodes= this.originalNodes.size();
+			this.listEntries= new ArrayList(nNodes * 2);
+			for (int i= 0; i < nNodes; i++) {
+				ASTNode node= (ASTNode) this.originalNodes.get(i);
+				// all nodes unchanged
+				this.listEntries.add(new NodeRewriteEvent(node, node));
+			}
+		}
+		return this.listEntries;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.ASTRewriteChange#getChangeKind()
+	 */
+	public int getChangeKind() {
+		if (this.listEntries != null) {
+			for (int i= 0; i < this.listEntries.size(); i++) {
+				RewriteEvent curr= (RewriteEvent) this.listEntries.get(i);
+				if (curr.getChangeKind() != UNCHANGED) {
+					return CHILDREN_CHANGED;
+				}
+			}
+		}
+		return UNCHANGED;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.ASTRewriteChange#isListChange()
+	 */
+	public boolean isListRewrite() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#getChildren()
+	 */
+	public RewriteEvent[] getChildren() {
+		List entries= getEntries();
+		return (RewriteEvent[]) entries.toArray(new RewriteEvent[entries.size()]);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#getOriginalNode()
+	 */
+	public Object getOriginalValue() {
+		return this.originalNodes;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#getNewValue()
+	 */
+	public Object getNewValue() {
+		List entries= getEntries();
+		ArrayList res= new ArrayList(entries.size());
+		for (int i= 0; i < entries.size(); i++) {
+			RewriteEvent curr= (RewriteEvent) entries.get(i);
+			Object newVal= curr.getNewValue();
+			if (newVal != null) {
+				res.add(newVal);
+			}
+		}
+		return res;
+	}
+
+	// API to modify the list nodes
+
+	public RewriteEvent removeEntry(ASTNode originalEntry) {
+		return replaceEntry(originalEntry, null);
+	}
+
+	public RewriteEvent replaceEntry(ASTNode entry, ASTNode newEntry) {
+		if (entry == null) {
+			throw new IllegalArgumentException();
+		}
+
+		List entries= getEntries();
+		int nEntries= entries.size();
+		for (int i= 0; i < nEntries; i++) {
+			NodeRewriteEvent curr= (NodeRewriteEvent) entries.get(i);
+			if (curr.getOriginalValue() == entry || curr.getNewValue() == entry) {
+				curr.setNewValue(newEntry);
+				if (curr.getNewValue() == null && curr.getOriginalValue() == null) { // removed an inserted node
+					entries.remove(i);
+					return null;
+				}
+				return curr;
+			}
+		}
+		return null;
+	}
+
+	public void revertChange(NodeRewriteEvent event) {
+		Object originalValue = event.getOriginalValue();
+		if (originalValue == null) {
+			List entries= getEntries();
+			entries.remove(event);
+		} else {
+			event.setNewValue(originalValue);
+		}
+	}
+
+	public int getIndex(ASTNode node, int kind) {
+		List entries= getEntries();
+		for (int i= entries.size() - 1; i >= 0; i--) {
+			RewriteEvent curr= (RewriteEvent) entries.get(i);
+			if (((kind & OLD) != 0) && (curr.getOriginalValue() == node)) {
+				return i;
+			}
+			if (((kind & NEW) != 0) && (curr.getNewValue() == node)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	public RewriteEvent insert(ASTNode insertedNode, int insertIndex) {
+		NodeRewriteEvent change= new NodeRewriteEvent(null, insertedNode);
+		if (insertIndex != -1) {
+			getEntries().add(insertIndex, change);
+		} else {
+			getEntries().add(change);
+		}
+		return change;
+	}
+
+	public void setNewValue(ASTNode newValue, int insertIndex) {
+		NodeRewriteEvent curr= (NodeRewriteEvent) getEntries().get(insertIndex);
+		curr.setNewValue(newValue);
+	}
+
+	public int getChangeKind(int index) {
+		return ((NodeRewriteEvent) getEntries().get(index)).getChangeKind();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buf= new StringBuffer();
+		buf.append(" [list change\n\t"); //$NON-NLS-1$
+
+		RewriteEvent[] events= getChildren();
+		for (int i= 0; i < events.length; i++) {
+			if (i != 0) {
+				buf.append("\n\t"); //$NON-NLS-1$
+			}
+			buf.append(events[i]);
+		}
+		buf.append("\n]"); //$NON-NLS-1$
+		return buf.toString();
+	}
+
+
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java
new file mode 100644
index 0000000..a26e75d
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+
+/**
+ *
+ */
+public final class NodeInfoStore {
+	private AST ast;
+
+	private Map placeholderNodes;
+	private Set collapsedNodes;
+
+	public NodeInfoStore(AST ast) {
+		super();
+		this.ast= ast;
+		this.placeholderNodes= null;
+		this.collapsedNodes= null;
+	}
+
+	/**
+	 * Marks a node as a placehoder for a plain string content. The type of the node should correspond to the
+	 * code's code content.
+	 * @param placeholder The placeholder node that acts for the string content.
+	 * @param code The string content.
+	 */
+	public final void markAsStringPlaceholder(ASTNode placeholder, String code) {
+		StringPlaceholderData data= new StringPlaceholderData();
+		data.code= code;
+		setPlaceholderData(placeholder, data);
+	}
+
+	/**
+	 * Marks a node as a copy or move target. The copy target represents a copied node at the target (copied) site.
+	 * @param target The node at the target site. Can be a placeholder node but also the source node itself.
+	 * @param copySource The info at the source site.
+	 */
+	public final void markAsCopyTarget(ASTNode target, CopySourceInfo copySource) {
+		CopyPlaceholderData data= new CopyPlaceholderData();
+		data.copySource= copySource;
+		setPlaceholderData(target, data);
+	}
+
+	/**
+	 * Creates a placeholder node of the given type. <code>null</code> if the type is not supported
+	 * @param nodeType Type of the node to create. Use the type constants in {@link NodeInfoStore}.
+	 * @return Returns a place holder node.
+	 */
+	public final ASTNode newPlaceholderNode(int nodeType) {
+		try {
+			ASTNode node= this.ast.createInstance(nodeType);
+			switch (node.getNodeType()) {
+				case ASTNode.FIELD_DECLARATION:
+					((FieldDeclaration) node).fragments().add(this.ast.newVariableDeclarationFragment());
+					break;
+				case ASTNode.MODIFIER:
+					((Modifier) node).setKeyword(Modifier.ModifierKeyword.ABSTRACT_KEYWORD);
+					break;
+				case ASTNode.TRY_STATEMENT :
+					((TryStatement) node).setFinally(this.ast.newBlock()); // have to set at least a finally block to be legal code
+					break;
+				case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
+					((VariableDeclarationExpression) node).fragments().add(this.ast.newVariableDeclarationFragment());
+					break;
+				case ASTNode.VARIABLE_DECLARATION_STATEMENT :
+					((VariableDeclarationStatement) node).fragments().add(this.ast.newVariableDeclarationFragment());
+					break;
+				case ASTNode.PARAMETERIZED_TYPE :
+					((ParameterizedType) node).typeArguments().add(this.ast.newWildcardType());
+					break;
+			}
+			return node;
+		} catch (IllegalArgumentException e) {
+			return null;
+		}
+ 	}
+
+
+	// collapsed nodes: in source: use one node that represents many; to be used as
+	// copy/move source or to replace at once.
+	// in the target: one block node that is not flattened.
+
+	public Block createCollapsePlaceholder() {
+		Block placeHolder= this.ast.newBlock();
+		if (this.collapsedNodes == null) {
+			this.collapsedNodes= new HashSet();
+		}
+		this.collapsedNodes.add(placeHolder);
+		return placeHolder;
+	}
+
+	public boolean isCollapsed(ASTNode node) {
+		if (this.collapsedNodes != null) {
+			return this.collapsedNodes.contains(node);
+		}
+		return false;
+	}
+
+	public Object getPlaceholderData(ASTNode node) {
+		if (this.placeholderNodes != null) {
+			return this.placeholderNodes.get(node);
+		}
+		return null;
+	}
+
+	private void setPlaceholderData(ASTNode node, PlaceholderData data) {
+		if (this.placeholderNodes == null) {
+			this.placeholderNodes= new IdentityHashMap();
+		}
+		this.placeholderNodes.put(node, data);
+	}
+
+	static class PlaceholderData {
+		// base class
+	}
+
+	protected static final class CopyPlaceholderData extends PlaceholderData {
+		public CopySourceInfo copySource;
+		public String toString() {
+			return "[placeholder " + this.copySource +"]";  //$NON-NLS-1$//$NON-NLS-2$
+		}
+	}
+
+	protected static final class StringPlaceholderData extends PlaceholderData {
+		public String code;
+		public String toString() {
+			return "[placeholder string: " + this.code +"]"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	/**
+	 *
+	 */
+	public void clear() {
+		this.placeholderNodes= null;
+		this.collapsedNodes= null;
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java
new file mode 100644
index 0000000..42b13ce
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+
+
+/**
+ *
+ */
+public class NodeRewriteEvent extends RewriteEvent {
+
+	private Object originalValue;
+	private Object newValue;
+
+	public NodeRewriteEvent(Object originalValue, Object newValue) {
+		this.originalValue= originalValue;
+		this.newValue= newValue;
+	}
+
+	/**
+	 * @return Returns the new value.
+	 */
+	public Object getNewValue() {
+		return this.newValue;
+	}
+
+	/**
+	 * @return Returns the original value.
+	 */
+	public Object getOriginalValue() {
+		return this.originalValue;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#getChangeKind()
+	 */
+	public int getChangeKind() {
+		if (this.originalValue == this.newValue) {
+			return UNCHANGED;
+		}
+		if (this.originalValue == null) {
+			return INSERTED;
+		}
+		if (this.newValue == null) {
+			return REMOVED;
+		}
+		if (this.originalValue.equals(this.newValue)) {
+			return UNCHANGED;
+		}
+		return REPLACED;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#isListRewrite()
+	 */
+	public boolean isListRewrite() {
+		return false;
+	}
+
+	/*
+	 * Sets a new value for the new node. Internal access only.
+	 * @param newValue The new value to set.
+	 */
+	public void setNewValue(Object newValue) {
+		this.newValue= newValue;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.RewriteEvent#getChildren()
+	 */
+	public RewriteEvent[] getChildren() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buf= new StringBuffer();
+		switch (getChangeKind()) {
+		case INSERTED:
+			buf.append(" [inserted: "); //$NON-NLS-1$
+			buf.append(getNewValue());
+			buf.append(']');
+			break;
+		case REPLACED:
+			buf.append(" [replaced: "); //$NON-NLS-1$
+			buf.append(getOriginalValue());
+			buf.append(" -> "); //$NON-NLS-1$
+			buf.append(getNewValue());
+			buf.append(']');
+			break;
+		case REMOVED:
+			buf.append(" [removed: "); //$NON-NLS-1$
+			buf.append(getOriginalValue());
+			buf.append(']');
+			break;
+		default:
+			buf.append(" [unchanged]"); //$NON-NLS-1$
+		}
+		return buf.toString();
+	}
+
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java
new file mode 100644
index 0000000..397c838
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+
+/**
+ *
+ */
+public abstract class RewriteEvent {
+
+	/**
+	 * Change kind to describe that the event is an insert event.
+	 * Does not apply for list events.
+	 */
+	public static final int INSERTED= 1;
+
+	/**
+	 * Change kind to describe that the event is an remove event.
+	 * Does not apply for list events.
+	 */
+	public static final int REMOVED= 2;
+
+	/**
+	 * Change kind to describe that the event is an replace event.
+	 * Does not apply for list events.
+	 */
+	public static final int REPLACED= 4;
+
+	/**
+	 * Change kind to signal that children changed. Does only apply for list events.
+	 */
+	public static final int CHILDREN_CHANGED= 8;
+
+	/**
+	 * Change kind to signal that the property did not change
+	 */
+	public static final int UNCHANGED= 0;
+
+	/**
+	 * @return Returns the event's change kind.
+	 */
+	public abstract int getChangeKind();
+
+	/**
+	 * @return Returns true if the given event is a list event.
+	 */
+	public abstract boolean isListRewrite();
+
+	/**
+	 * @return Returns the original value. For lists this is a List of ASTNodes, for non-list
+	 * events this can be an ASTNode (for node properties), Integer (for an integer property),
+	 * Boolean (for boolean node properties) or properties like Operator.
+	 * <code>null</code> is returned if the event is an insert event.
+	 */
+	public abstract Object getOriginalValue();
+
+	/**
+	 * @return Returns the new value. For lists this is a List of ASTNodes, for non-list
+	 * events this can be an ASTNode (for node properties), Integer (for an integer property),
+	 * Boolean (for boolean node properties) or properties like Operator.
+	 * <code>null</code> is returned if the event is a remove event.
+	 */
+	public abstract Object getNewValue();
+
+	/**
+	 * @return Return the events describing the changes in a list. returns <code>null</code> if the
+	 * event is not a list event.
+	 */
+	public abstract RewriteEvent[] getChildren();
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
new file mode 100644
index 0000000..f82d5da
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
@@ -0,0 +1,890 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.*;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.text.edits.TextEditGroup;
+
+
+/**
+ * Stores all rewrite events, descriptions of events and knows which nodes
+ * are copy or move sources or tracked.
+ */
+public final class RewriteEventStore {
+
+	/**
+	 * Debug AST rewrite events.
+	 * <p>
+	 * If enabled, then {@link ASTRewrite} and {@link ListRewrite}
+	 * throw an {@link IllegalArgumentException} if a rewrite operation tries to insert an
+	 * AST node in a place where nodes of this type are not allowed (node type not a subtype of
+	 * the structural property's type). 
+	 * </p>
+	 * <p>
+	 * Disabled by default, since this hasn't been enforced from the beginning, and there are clients
+	 * (e.g. in JDT UI refactorings) that rely on a bit of leeway here.
+	 * E.g. the qualifier of a QualifiedName cannot be a MethodInvocation expression or a SimpleType, but
+	 * that's sometimes the easiest solution for such a change, and ASTRewrite has no problems with it.  
+	 * </p>
+	 */
+	public static boolean DEBUG = false;
+
+	public static final class PropertyLocation {
+		private final ASTNode parent;
+		private final StructuralPropertyDescriptor property;
+
+		public PropertyLocation(ASTNode parent, StructuralPropertyDescriptor property) {
+			this.parent= parent;
+			this.property= property;
+		}
+
+		public ASTNode getParent() {
+			return this.parent;
+		}
+
+		public StructuralPropertyDescriptor getProperty() {
+			return this.property;
+		}
+
+		public boolean equals(Object obj) {
+			if (obj != null && obj.getClass().equals(getClass())) {
+				PropertyLocation other= (PropertyLocation) obj;
+				return other.getParent().equals(getParent()) && other.getProperty().equals(getProperty());
+			}
+			return false;
+		}
+
+		public int hashCode() {
+			return getParent().hashCode() + getProperty().hashCode();
+		}
+
+	}
+
+	/**
+	 * Interface that allows to override the way how children are accessed from
+	 * a parent. Use this interface when the rewriter is set up on an already
+	 * modified AST's (as it is the case in the old ASTRewrite infrastructure)
+	 */
+	public static interface INodePropertyMapper {
+		/**
+		 * Returns the node attribute for a given property name.
+		 * @param parent The parent node
+		 * @param childProperty The child property to access
+		 * @return The child node at the given property location.
+		 */
+		Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor childProperty);
+	}
+
+	/*
+	 * Store element to associate event and node position/
+	 */
+	private static class EventHolder {
+		public final ASTNode parent;
+		public final StructuralPropertyDescriptor childProperty;
+		public final RewriteEvent event;
+
+		public EventHolder(ASTNode parent, StructuralPropertyDescriptor childProperty, RewriteEvent change) {
+			this.parent= parent;
+			this.childProperty= childProperty;
+			this.event= change;
+		}
+
+		public String toString() {
+			StringBuffer buf= new StringBuffer();
+			buf.append(this.parent).append(" - "); //$NON-NLS-1$
+			buf.append(this.childProperty.getId()).append(": "); //$NON-NLS-1$
+			buf.append(this.event).append('\n');
+			return buf.toString();
+		}
+	}
+
+	public static class CopySourceInfo implements Comparable {
+		public final PropertyLocation location; // can be null, only used to mark as removed on move
+		private final ASTNode node;
+		public final boolean isMove;
+
+		public CopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) {
+			this.location= location;
+			this.node= node;
+			this.isMove= isMove;
+		}
+
+		public ASTNode getNode() {
+			return this.node;
+		}
+
+		public int compareTo(Object o2) {
+			CopySourceInfo r2= (CopySourceInfo) o2;
+
+			int startDiff= getNode().getStartPosition() - r2.getNode().getStartPosition();
+			if (startDiff != 0) {
+				return startDiff; // insert before if start node is first
+			}
+
+			if (r2.isMove != this.isMove) {
+				return this.isMove ? -1 : 1; // first move then copy
+			}
+			return 0;
+		}
+
+		public String toString() {
+			StringBuffer buf= new StringBuffer();
+			if (this.isMove) {
+				buf.append("move source: "); //$NON-NLS-1$
+			} else {
+				buf.append("copy source: "); //$NON-NLS-1$
+			}
+			buf.append(this.node);
+			return buf.toString();
+		}
+	}
+
+	private static class NodeRangeInfo implements Comparable {
+		private final ASTNode first;
+		private final ASTNode last;
+		public final CopySourceInfo copyInfo; // containing the internal placeholder and the 'isMove' flag
+		public final ASTNode replacingNode;
+		public final TextEditGroup editGroup;
+
+		public NodeRangeInfo(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, CopySourceInfo copyInfo, ASTNode replacingNode, TextEditGroup editGroup) {
+			this.first= first;
+			this.last= last;
+			this.copyInfo= copyInfo;
+			this.replacingNode= replacingNode;
+			this.editGroup= editGroup;
+		}
+
+		public ASTNode getStartNode() {
+			return this.first;
+		}
+
+		public ASTNode getEndNode() {
+			return this.last;
+		}
+
+		public boolean isMove() {
+			return this.copyInfo.isMove;
+		}
+
+		public Block getInternalPlaceholder() {
+			return (Block) this.copyInfo.getNode();
+		}
+
+		public int compareTo(Object o2) {
+			NodeRangeInfo r2= (NodeRangeInfo) o2;
+
+			int startDiff= getStartNode().getStartPosition() - r2.getStartNode().getStartPosition();
+			if (startDiff != 0) {
+				return startDiff; // insert before if start node is first
+			}
+			int endDiff= getEndNode().getStartPosition() - r2.getEndNode().getStartPosition();
+			if (endDiff != 0) {
+				return -endDiff; // insert before if length is longer
+			}
+			if (r2.isMove() != isMove()) {
+				return isMove() ? -1 : 1; // first move then copy
+			}
+			return 0;
+		}
+
+		public void updatePlaceholderSourceRanges(TargetSourceRangeComputer sourceRangeComputer) {
+			TargetSourceRangeComputer.SourceRange startRange= sourceRangeComputer.computeSourceRange(getStartNode());
+			TargetSourceRangeComputer.SourceRange endRange= sourceRangeComputer.computeSourceRange(getEndNode());
+			int startPos= startRange.getStartPosition();
+			int endPos= endRange.getStartPosition() + endRange.getLength();
+
+			Block internalPlaceholder= getInternalPlaceholder();
+			internalPlaceholder.setSourceRange(startPos, endPos - startPos);
+		}
+
+		public String toString() {
+			StringBuffer buf= new StringBuffer();
+			if (this.first != this.last) {
+				buf.append("range ");  //$NON-NLS-1$
+			}
+			if (isMove()) {
+				buf.append("move source: "); //$NON-NLS-1$
+			} else {
+				buf.append("copy source: "); //$NON-NLS-1$
+			}
+			buf.append(this.first);
+			buf.append(" - "); //$NON-NLS-1$
+			buf.append(this.last);
+			return buf.toString();
+		}
+
+
+	}
+
+	/**
+	 * Iterates over all event parent nodes, tracked nodes and all copy/move sources
+	 */
+	private class ParentIterator implements Iterator {
+
+		private Iterator eventIter;
+		private Iterator sourceNodeIter;
+		private Iterator rangeNodeIter;
+		private Iterator trackedNodeIter;
+
+		public ParentIterator() {
+			this.eventIter= RewriteEventStore.this.eventLookup.keySet().iterator();
+			if (RewriteEventStore.this.nodeCopySources != null) {
+				this.sourceNodeIter= RewriteEventStore.this.nodeCopySources.iterator();
+			} else {
+				this.sourceNodeIter= Collections.EMPTY_LIST.iterator();
+			}
+			if (RewriteEventStore.this.nodeRangeInfos != null) {
+				this.rangeNodeIter= RewriteEventStore.this.nodeRangeInfos.keySet().iterator();
+			} else {
+				this.rangeNodeIter= Collections.EMPTY_LIST.iterator();
+			}
+			if (RewriteEventStore.this.trackedNodes != null) {
+				this.trackedNodeIter= RewriteEventStore.this.trackedNodes.keySet().iterator();
+			} else {
+				this.trackedNodeIter= Collections.EMPTY_LIST.iterator();
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#hasNext()
+		 */
+		public boolean hasNext() {
+			return this.eventIter.hasNext() || this.sourceNodeIter.hasNext() || this.rangeNodeIter.hasNext() || this.trackedNodeIter.hasNext();
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#next()
+		 */
+		public Object next() {
+			if (this.eventIter.hasNext()) {
+				return this.eventIter.next();
+			}
+			if (this.sourceNodeIter.hasNext()) {
+				return ((CopySourceInfo) this.sourceNodeIter.next()).getNode();
+			}
+			if (this.rangeNodeIter.hasNext()) {
+				return ((PropertyLocation) this.rangeNodeIter.next()).getParent();
+			}
+			return this.trackedNodeIter.next();
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Iterator#remove()
+		 */
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	public final static int NEW= 1;
+	public final static int ORIGINAL= 2;
+	public final static int BOTH= NEW | ORIGINAL;
+
+
+	/** all events by parent*/
+	final Map eventLookup;
+
+	/** cache for last accessed event */
+	private EventHolder lastEvent;
+
+	/** Maps events to group descriptions */
+	private Map editGroups;
+
+	/** Stores which nodes are source of a copy or move (list of CopySourceInfo)*/
+	List nodeCopySources;
+
+	/** Stores node ranges that are used to copy or move (map of <PropertyLocation, CopyRangeInfo>)*/
+	Map nodeRangeInfos;
+
+	/** Stores which nodes are tracked and the corresponding edit group*/
+	Map trackedNodes;
+
+	/** Stores which inserted nodes bound to the previous node. If not, a node is
+	 * always bound to the next node */
+	private Set insertBoundToPrevious;
+
+	/** optional mapper to allow fix already modified AST trees */
+	private INodePropertyMapper nodePropertyMapper;
+
+	private static final String INTERNAL_PLACEHOLDER_PROPERTY= "rewrite_internal_placeholder"; //$NON-NLS-1$
+
+	public RewriteEventStore() {
+		this.eventLookup= new HashMap();
+		this.lastEvent= null;
+
+		this.editGroups= null; // lazy initialization
+
+		this.trackedNodes= null;
+		this.insertBoundToPrevious= null;
+
+		this.nodePropertyMapper= null;
+		this.nodeCopySources= null;
+		this.nodeRangeInfos= null;
+	}
+
+	/**
+	 * Override the default way how to access children from a parent node.
+	 * @param nodePropertyMapper The new <code>INodePropertyMapper</code> or
+	 * <code>null</code>. to use the default.
+	 */
+	public void setNodePropertyMapper(INodePropertyMapper nodePropertyMapper) {
+		this.nodePropertyMapper= nodePropertyMapper;
+	}
+
+	public void clear() {
+		this.eventLookup.clear();
+		this.lastEvent= null;
+		this.trackedNodes= null;
+
+		this.editGroups= null; // lazy initialization
+		this.insertBoundToPrevious= null;
+		this.nodeCopySources= null;
+	}
+
+	public void addEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, RewriteEvent event) {
+		validateHasChildProperty(parent, childProperty);
+
+		if (event.isListRewrite()) {
+			validateIsListProperty(childProperty);
+		}
+
+		EventHolder holder= new EventHolder(parent, childProperty, event);
+
+		List entriesList = (List) this.eventLookup.get(parent);
+		if (entriesList != null) {
+			for (int i= 0; i < entriesList.size(); i++) {
+				EventHolder curr= (EventHolder) entriesList.get(i);
+				if (curr.childProperty == childProperty) {
+					entriesList.set(i, holder);
+					this.lastEvent= null;
+					return;
+				}
+			}
+		} else {
+			entriesList= new ArrayList(3);
+			this.eventLookup.put(parent, entriesList);
+		}
+		entriesList.add(holder);
+	}
+
+	public RewriteEvent getEvent(ASTNode parent, StructuralPropertyDescriptor property) {
+		validateHasChildProperty(parent, property);
+
+		if (this.lastEvent != null && this.lastEvent.parent == parent && this.lastEvent.childProperty == property) {
+			return this.lastEvent.event;
+		}
+
+		List entriesList = (List) this.eventLookup.get(parent);
+		if (entriesList != null) {
+			for (int i= 0; i < entriesList.size(); i++) {
+				EventHolder holder= (EventHolder) entriesList.get(i);
+				if (holder.childProperty == property) {
+					this.lastEvent= holder;
+					return holder.event;
+				}
+			}
+		}
+		return null;
+	}
+
+	public NodeRewriteEvent getNodeEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, boolean forceCreation) {
+		validateIsNodeProperty(childProperty);
+		NodeRewriteEvent event= (NodeRewriteEvent) getEvent(parent, childProperty);
+		if (event == null && forceCreation) {
+			Object originalValue= accessOriginalValue(parent, childProperty);
+			event= new NodeRewriteEvent(originalValue, originalValue);
+			addEvent(parent, childProperty, event);
+		}
+		return event;
+	}
+
+	public ListRewriteEvent getListEvent(ASTNode parent, StructuralPropertyDescriptor childProperty, boolean forceCreation) {
+		validateIsListProperty(childProperty);
+		ListRewriteEvent event= (ListRewriteEvent) getEvent(parent, childProperty);
+		if (event == null && forceCreation) {
+			List originalValue= (List) accessOriginalValue(parent, childProperty);
+			event= new ListRewriteEvent(originalValue);
+			addEvent(parent, childProperty, event);
+		}
+		return event;
+	}
+
+	public Iterator getChangeRootIterator() {
+		return new ParentIterator();
+	}
+
+
+	public boolean hasChangedProperties(ASTNode parent) {
+		List entriesList = (List) this.eventLookup.get(parent);
+		if (entriesList != null) {
+			for (int i= 0; i < entriesList.size(); i++) {
+				EventHolder holder= (EventHolder) entriesList.get(i);
+				if (holder.event.getChangeKind() != RewriteEvent.UNCHANGED) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	public PropertyLocation getPropertyLocation(Object value, int kind) {
+		for (Iterator iter= this.eventLookup.values().iterator(); iter.hasNext();) {
+			List events= (List) iter.next();
+			for (int i= 0; i < events.size(); i++) {
+				EventHolder holder= (EventHolder) events.get(i);
+				RewriteEvent event= holder.event;
+				if (isNodeInEvent(event, value, kind)) {
+					return new PropertyLocation(holder.parent, holder.childProperty);
+				}
+				if (event.isListRewrite()) {
+					RewriteEvent[] children= event.getChildren();
+					for (int k= 0; k < children.length; k++) {
+						if (isNodeInEvent(children[k], value, kind)) {
+							return new PropertyLocation(holder.parent, holder.childProperty);
+						}
+					}
+				}
+			}
+		}
+		if (value instanceof ASTNode) {
+			ASTNode node= (ASTNode) value;
+			return new PropertyLocation(node.getParent(), node.getLocationInParent());
+		}
+		return null;
+	}
+
+
+	/**
+	 * Kind is either ORIGINAL, NEW, or BOTH
+	 * @param value
+	 * @param kind
+	 * @return Returns the event with the given value of <code>null</code>.
+	 */
+	public RewriteEvent findEvent(Object value, int kind) {
+		for (Iterator iter= this.eventLookup.values().iterator(); iter.hasNext();) {
+			List events= (List) iter.next();
+			for (int i= 0; i < events.size(); i++) {
+				RewriteEvent event= ((EventHolder) events.get(i)).event;
+				if (isNodeInEvent(event, value, kind)) {
+					return event;
+				}
+				if (event.isListRewrite()) {
+					RewriteEvent[] children= event.getChildren();
+					for (int k= 0; k < children.length; k++) {
+						if (isNodeInEvent(children[k], value, kind)) {
+							return children[k];
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	private boolean isNodeInEvent(RewriteEvent event, Object value, int kind) {
+		if (((kind & NEW) != 0) && event.getNewValue() == value) {
+			return true;
+		}
+		if (((kind & ORIGINAL) != 0) && event.getOriginalValue() == value) {
+			return true;
+		}
+		return false;
+	}
+
+
+	public Object getOriginalValue(ASTNode parent, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			return event.getOriginalValue();
+		}
+		return accessOriginalValue(parent, property);
+	}
+
+	public Object getNewValue(ASTNode parent, StructuralPropertyDescriptor property) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			return event.getNewValue();
+		}
+		return accessOriginalValue(parent, property);
+	}
+	
+	public List getChangedPropertieEvents(ASTNode parent) {
+		List changedPropertiesEvent = new ArrayList();
+		
+		List entriesList = (List) this.eventLookup.get(parent);
+		if (entriesList != null) {
+			for (int i= 0; i < entriesList.size(); i++) {
+				EventHolder holder= (EventHolder) entriesList.get(i);
+				if (holder.event.getChangeKind() != RewriteEvent.UNCHANGED) {
+					changedPropertiesEvent.add(holder.event);
+				}
+			}
+		}
+		return changedPropertiesEvent;
+	}
+
+	public int getChangeKind(ASTNode node) {
+		RewriteEvent event= findEvent(node, ORIGINAL);
+		if (event != null) {
+			return event.getChangeKind();
+		}
+		return RewriteEvent.UNCHANGED;
+	}
+
+	/*
+	 * Gets an original child from the AST.
+	 * Temporarily overridden to port the old rewriter to the new infrastructure.
+	 */
+	private Object accessOriginalValue(ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		if (this.nodePropertyMapper != null) {
+			return this.nodePropertyMapper.getOriginalValue(parent, childProperty);
+		}
+
+		return parent.getStructuralProperty(childProperty);
+	}
+
+	public TextEditGroup getEventEditGroup(RewriteEvent event) {
+		if (this.editGroups == null) {
+			return null;
+		}
+		return (TextEditGroup) this.editGroups.get(event);
+	}
+
+	public void setEventEditGroup(RewriteEvent event, TextEditGroup editGroup) {
+		if (this.editGroups == null) {
+			this.editGroups= new IdentityHashMap(5);
+		}
+		this.editGroups.put(event, editGroup);
+	}
+
+
+	public final TextEditGroup getTrackedNodeData(ASTNode node) {
+		if (this.trackedNodes != null) {
+			return (TextEditGroup) this.trackedNodes.get(node);
+		}
+		return null;
+	}
+
+	public void setTrackedNodeData(ASTNode node, TextEditGroup editGroup) {
+		if (this.trackedNodes == null) {
+			this.trackedNodes= new IdentityHashMap();
+		}
+		this.trackedNodes.put(node, editGroup);
+	}
+
+	/**
+	 * Marks a node as tracked. The edits added to the group editGroup can be used to get the
+	 * position of the node after the rewrite operation.
+	 * @param node The node to track
+	 * @param editGroup Collects the range markers describing the node position.
+	 */
+	public final void markAsTracked(ASTNode node, TextEditGroup editGroup) {
+		if (getTrackedNodeData(node) != null) {
+			throw new IllegalArgumentException("Node is already marked as tracked"); //$NON-NLS-1$
+		}
+		setTrackedNodeData(node, editGroup);
+	}
+
+	private final CopySourceInfo createCopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) {
+		CopySourceInfo copySource= new CopySourceInfo(location, node, isMove);
+
+		if (this.nodeCopySources == null) {
+			this.nodeCopySources= new ArrayList();
+		}
+		this.nodeCopySources.add(copySource);
+		return copySource;
+	}
+
+	public final CopySourceInfo markAsCopySource(ASTNode parent, StructuralPropertyDescriptor property, ASTNode node, boolean isMove) {
+		return createCopySourceInfo(new PropertyLocation(parent, property), node, isMove);
+	}
+
+	public final boolean isRangeCopyPlaceholder(ASTNode node) {
+		return node.getProperty(INTERNAL_PLACEHOLDER_PROPERTY) != null;
+	}
+
+	public final CopySourceInfo createRangeCopy(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, boolean isMove, ASTNode internalPlaceholder, ASTNode replacingNode, TextEditGroup editGroup) {
+		CopySourceInfo copyInfo= createCopySourceInfo(null, internalPlaceholder, isMove);
+		internalPlaceholder.setProperty(INTERNAL_PLACEHOLDER_PROPERTY, internalPlaceholder);
+
+		NodeRangeInfo copyRangeInfo= new NodeRangeInfo(parent, childProperty, first, last, copyInfo, replacingNode, editGroup);
+
+		ListRewriteEvent listEvent= getListEvent(parent, childProperty, true);
+
+		int indexFirst= listEvent.getIndex(first, ListRewriteEvent.OLD);
+		if (indexFirst == -1) {
+			throw new IllegalArgumentException("Start node is not a original child of the given list"); //$NON-NLS-1$
+		}
+		int indexLast= listEvent.getIndex(last, ListRewriteEvent.OLD);
+		if (indexLast == -1) {
+			throw new IllegalArgumentException("End node is not a original child of the given list"); //$NON-NLS-1$
+		}
+
+		if (indexFirst > indexLast) {
+			throw new IllegalArgumentException("Start node must be before end node"); //$NON-NLS-1$
+		}
+
+		if (this.nodeRangeInfos == null) {
+			this.nodeRangeInfos= new HashMap();
+		}
+		PropertyLocation loc= new PropertyLocation(parent, childProperty);
+		List innerList= (List) this.nodeRangeInfos.get(loc);
+		if (innerList == null) {
+			innerList= new ArrayList(2);
+			this.nodeRangeInfos.put(loc, innerList);
+		} else {
+			assertNoOverlap(listEvent, indexFirst, indexLast, innerList);
+		}
+		innerList.add(copyRangeInfo);
+
+
+		return copyInfo;
+	}
+
+	public CopySourceInfo[] getNodeCopySources(ASTNode node) {
+		if (this.nodeCopySources == null) {
+			return null;
+		}
+		return internalGetCopySources(this.nodeCopySources, node);
+	}
+
+
+	public CopySourceInfo[] internalGetCopySources(List copySources, ASTNode node) {
+		ArrayList res= new ArrayList(3);
+		for (int i= 0; i < copySources.size(); i++) {
+			CopySourceInfo curr= (CopySourceInfo) copySources.get(i);
+			if (curr.getNode() == node) {
+				res.add(curr);
+			}
+		}
+		if (res.isEmpty()) {
+			return null;
+		}
+
+		CopySourceInfo[] arr= (CopySourceInfo[]) res.toArray(new CopySourceInfo[res.size()]);
+		Arrays.sort(arr);
+		return arr;
+	}
+
+
+	private void assertNoOverlap(ListRewriteEvent listEvent, int indexFirst, int indexLast, List innerList) {
+		for (Iterator iter= innerList.iterator(); iter.hasNext();) {
+			NodeRangeInfo curr= (NodeRangeInfo) iter.next();
+			int currStart= listEvent.getIndex(curr.getStartNode(), ListRewriteEvent.BOTH);
+			int currEnd= listEvent.getIndex(curr.getEndNode(), ListRewriteEvent.BOTH);
+			if (currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst
+					|| currStart > indexFirst && currStart <= currEnd && currEnd > indexLast) {
+				throw new IllegalArgumentException("Range overlapps with an existing copy or move range"); //$NON-NLS-1$
+			}
+		}
+	}
+
+	public void prepareMovedNodes(TargetSourceRangeComputer sourceRangeComputer) {
+		if (this.nodeCopySources != null) {
+			prepareSingleNodeCopies();
+		}
+
+		if (this.nodeRangeInfos != null) {
+			prepareNodeRangeCopies(sourceRangeComputer);
+		}
+	}
+
+	public void revertMovedNodes() {
+		if (this.nodeRangeInfos != null) {
+			removeMoveRangePlaceholders();
+		}
+	}
+
+	private void removeMoveRangePlaceholders() {
+		for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry= (Map.Entry) iter.next();
+			Set placeholders= new HashSet(); // collect all placeholders
+			List rangeInfos= (List) entry.getValue(); // list of CopySourceRange
+			for (int i= 0; i < rangeInfos.size(); i++) {
+				placeholders.add(((NodeRangeInfo) rangeInfos.get(i)).getInternalPlaceholder());
+			}
+
+			PropertyLocation loc= (PropertyLocation) entry.getKey();
+
+			RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren();
+			List revertedChildren= new ArrayList();
+			revertListWithRanges(children, placeholders, revertedChildren);
+			RewriteEvent[] revertedChildrenArr= (RewriteEvent[]) revertedChildren.toArray(new RewriteEvent[revertedChildren.size()]);
+			addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(revertedChildrenArr)); // replace the current edits
+		}
+	}
+
+	private void revertListWithRanges(RewriteEvent[] childEvents, Set placeholders, List revertedChildren) {
+		for (int i= 0; i < childEvents.length; i++) {
+			RewriteEvent event= childEvents[i];
+			ASTNode node= (ASTNode) event.getOriginalValue();
+			if (placeholders.contains(node)) {
+				RewriteEvent[] placeholderChildren= getListEvent(node, Block.STATEMENTS_PROPERTY, false).getChildren();
+				revertListWithRanges(placeholderChildren, placeholders, revertedChildren);
+			} else {
+				revertedChildren.add(event);
+			}
+		}
+	}
+
+	private void prepareNodeRangeCopies(TargetSourceRangeComputer sourceRangeComputer) {
+		for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry= (Map.Entry) iter.next();
+			List rangeInfos= (List) entry.getValue(); // list of CopySourceRange
+			Collections.sort(rangeInfos); // sort by start index, length, move or copy
+
+			PropertyLocation loc= (PropertyLocation) entry.getKey();
+			RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren();
+
+			RewriteEvent[] newChildren= processListWithRanges(rangeInfos, children, sourceRangeComputer);
+			addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(newChildren)); // replace the current edits
+		}
+	}
+
+	private RewriteEvent[] processListWithRanges(List rangeInfos, RewriteEvent[] childEvents, TargetSourceRangeComputer sourceRangeComputer) {
+		List newChildEvents= new ArrayList(childEvents.length);
+		NodeRangeInfo topInfo= null;
+		Stack newChildrenStack= new Stack();
+		Stack topInfoStack= new Stack();
+
+		Iterator rangeInfoIterator= rangeInfos.iterator();
+		NodeRangeInfo nextInfo= (NodeRangeInfo) rangeInfoIterator.next();
+
+		for (int k= 0; k < childEvents.length; k++) {
+			RewriteEvent event= childEvents[k];
+			ASTNode node= (ASTNode) event.getOriginalValue();
+			// check for ranges and add a placeholder for them
+			while (nextInfo != null && node == nextInfo.getStartNode()) { // is this child the beginning of a range?
+				nextInfo.updatePlaceholderSourceRanges(sourceRangeComputer);
+
+				Block internalPlaceholder= nextInfo.getInternalPlaceholder();
+				RewriteEvent newEvent;
+				if (nextInfo.isMove()) {
+					newEvent= new NodeRewriteEvent(internalPlaceholder, nextInfo.replacingNode); // remove or replace
+				} else {
+					newEvent= new NodeRewriteEvent(internalPlaceholder, internalPlaceholder); // unchanged
+				}
+				newChildEvents.add(newEvent);
+				if (nextInfo.editGroup != null) {
+					setEventEditGroup(newEvent, nextInfo.editGroup);
+				}
+
+				newChildrenStack.push(newChildEvents);
+				topInfoStack.push(topInfo);
+
+				newChildEvents= new ArrayList(childEvents.length);
+				topInfo= nextInfo;
+
+				nextInfo= rangeInfoIterator.hasNext() ? (NodeRangeInfo) rangeInfoIterator.next() : null;
+			}
+
+			newChildEvents.add(event);
+
+			while (topInfo != null && node == topInfo.getEndNode()) {
+				RewriteEvent[] placeholderChildEvents= (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]);
+				Block internalPlaceholder= topInfo.getInternalPlaceholder();
+				addEvent(internalPlaceholder, Block.STATEMENTS_PROPERTY, new ListRewriteEvent(placeholderChildEvents));
+
+				newChildEvents= (List) newChildrenStack.pop();
+				topInfo= (NodeRangeInfo) topInfoStack.pop();
+			}
+		}
+		return (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]);
+	}
+
+	/**
+	 * Make sure all moved nodes are marked as removed or replaced.
+	 */
+	private void prepareSingleNodeCopies() {
+		for (int i= 0; i < this.nodeCopySources.size(); i++) {
+			CopySourceInfo curr= (CopySourceInfo) this.nodeCopySources.get(i);
+			if (curr.isMove && curr.location != null) {
+				doMarkMovedAsRemoved(curr, curr.location.getParent(), curr.location.getProperty());
+			}
+		}
+
+	}
+
+	private void doMarkMovedAsRemoved(CopySourceInfo curr, ASTNode parent, StructuralPropertyDescriptor childProperty) {
+		if (childProperty.isChildListProperty()) {
+			ListRewriteEvent event= getListEvent(parent, childProperty, true);
+			int index= event.getIndex(curr.getNode(), ListRewriteEvent.OLD);
+			if (index != -1 && event.getChangeKind(index) == RewriteEvent.UNCHANGED) {
+				event.setNewValue(null, index);
+			}
+		} else {
+			NodeRewriteEvent event= getNodeEvent(parent, childProperty, true);
+			if (event.getChangeKind() == RewriteEvent.UNCHANGED) {
+				event.setNewValue(null);
+			}
+		}
+	}
+
+	public boolean isInsertBoundToPrevious(ASTNode node) {
+		if (this.insertBoundToPrevious != null) {
+			return this.insertBoundToPrevious.contains(node);
+		}
+		return false;
+	}
+
+	public void setInsertBoundToPrevious(ASTNode node) {
+		if (this.insertBoundToPrevious == null) {
+			this.insertBoundToPrevious= new HashSet();
+		}
+		this.insertBoundToPrevious.add(node);
+	}
+
+	private void validateIsListProperty(StructuralPropertyDescriptor property) {
+		if (!property.isChildListProperty()) {
+			String message= property.getId() + " is not a list property"; //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+	}
+
+	private void validateHasChildProperty(ASTNode parent, StructuralPropertyDescriptor property) {
+		if (!parent.structuralPropertiesForType().contains(property)) {
+			String message= Signature.getSimpleName(parent.getClass().getName()) + " has no property " + property.getId(); //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+	}
+
+	private void validateIsNodeProperty(StructuralPropertyDescriptor property) {
+		if (property.isChildListProperty()) {
+			String message= property.getId() + " is not a node property"; //$NON-NLS-1$
+			throw new IllegalArgumentException(message);
+		}
+	}
+
+	public String toString() {
+		StringBuffer buf= new StringBuffer();
+		for (Iterator iter = this.eventLookup.values().iterator(); iter.hasNext();) {
+			List events = (List) iter.next();
+			for (int i= 0; i < events.size(); i++) {
+				buf.append(events.get(i).toString()).append('\n');
+			}
+		}
+		return buf.toString();
+	}
+
+	public static boolean isNewNode(ASTNode node) {
+		return (node.getFlags() & ASTNode.ORIGINAL) == 0;
+	}
+
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java
new file mode 100644
index 0000000..a22669a
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+import org.eclipse.text.edits.ISourceModifier;
+import org.eclipse.text.edits.ReplaceEdit;
+
+
+public class SourceModifier implements ISourceModifier {
+
+	private final String destinationIndent;
+	private final int sourceIndentLevel;
+	private final int tabWidth;
+	private final int indentWidth;
+
+	public SourceModifier(int sourceIndentLevel, String destinationIndent, int tabWidth, int indentWidth) {
+		this.destinationIndent= destinationIndent;
+		this.sourceIndentLevel= sourceIndentLevel;
+		this.tabWidth= tabWidth;
+		this.indentWidth= indentWidth;
+	}
+
+	public ISourceModifier copy() {
+		// We are state less
+		return this;
+	}
+
+	public ReplaceEdit[] getModifications(String source) {
+		List result= new ArrayList();
+		int destIndentLevel= IndentManipulation.measureIndentUnits(this.destinationIndent, this.tabWidth, this.indentWidth);
+		if (destIndentLevel == this.sourceIndentLevel) {
+			return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]);
+		}
+		return IndentManipulation.getChangeIndentEdits(source, this.sourceIndentLevel, this.tabWidth, this.indentWidth, this.destinationIndent);
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java
new file mode 100644
index 0000000..344272b
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+/**
+ * Wraps a scanner and offers convenient methods for finding tokens
+ */
+public class TokenScanner {
+
+	public static final int END_OF_FILE= 20001;
+	public static final int LEXICAL_ERROR= 20002;
+	public static final int DOCUMENT_ERROR= 20003;
+
+	private final Scanner scanner;
+	private final int endPosition;
+
+	/**
+	 * Creates a TokenScanner
+	 * @param scanner The scanner to be wrapped
+	 */
+	public TokenScanner(Scanner scanner) {
+		this.scanner= scanner;
+		this.endPosition= this.scanner.getSource().length - 1;
+	}
+
+	/**
+	 * Returns the wrapped scanner
+	 * @return IScanner
+	 */
+	public Scanner getScanner() {
+		return this.scanner;
+	}
+
+	/**
+	 * Sets the scanner offset to the given offset.
+	 * @param offset The offset to set
+	 */
+	public void setOffset(int offset) {
+		this.scanner.resetTo(offset, this.endPosition);
+	}
+
+	/**
+	 * @return Returns the offset after the current token
+	 */
+	public int getCurrentEndOffset() {
+		return this.scanner.getCurrentTokenEndPosition() + 1;
+	}
+
+	/**
+	 * @return Returns the start offset of the current token
+	 */
+	public int getCurrentStartOffset() {
+		return this.scanner.getCurrentTokenStartPosition();
+	}
+
+	/**
+	 * @return Returns the length of the current token
+	 */
+	public int getCurrentLength() {
+		return getCurrentEndOffset() - getCurrentStartOffset();
+	}
+
+	/**
+	 * Reads the next token.
+	 * @param ignoreComments If set, comments will be overread
+	 * @return Return the token id.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int readNext(boolean ignoreComments) throws CoreException {
+		int curr= 0;
+		do {
+			try {
+				curr= this.scanner.getNextToken();
+				if (curr == TerminalTokens.TokenNameEOF) {
+					throw new CoreException(createError(END_OF_FILE, "End Of File", null)); //$NON-NLS-1$
+				}
+			} catch (InvalidInputException e) {
+				throw new CoreException(createError(LEXICAL_ERROR, e.getMessage(), e));
+			}
+		} while (ignoreComments && isComment(curr));
+		return curr;
+	}
+
+	/**
+	 * Reads the next token from the given offset.
+	 * @param offset The offset to start reading from.
+	 * @param ignoreComments If set, comments will be overread.
+	 * @return Returns the token id.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int readNext(int offset, boolean ignoreComments) throws CoreException {
+		setOffset(offset);
+		return readNext(ignoreComments);
+	}
+
+	/**
+	 * Reads the next token from the given offset and returns the start offset of the token.
+	 * @param offset The offset to start reading from.
+	 * @param ignoreComments If set, comments will be overread
+	 * @return Returns the start position of the next token.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int getNextStartOffset(int offset, boolean ignoreComments) throws CoreException {
+		readNext(offset, ignoreComments);
+		return getCurrentStartOffset();
+	}
+
+	/**
+	 * Reads the next token from the given offset and returns the offset after the token.
+	 * @param offset The offset to start reading from.
+	 * @param ignoreComments If set, comments will be overread
+	 * @return Returns the start position of the next token.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int getNextEndOffset(int offset, boolean ignoreComments) throws CoreException {
+		readNext(offset, ignoreComments);
+		return getCurrentEndOffset();
+	}
+
+	/**
+	 * Reads until a token is reached.
+	 * @param tok The token to read to.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public void readToToken(int tok) throws CoreException {
+		int curr= 0;
+		do {
+			curr= readNext(false);
+		} while (curr != tok);
+	}
+
+	/**
+	 * Reads until a token is reached, starting from the given offset.
+	 * @param tok The token to read to.
+	 * @param offset The offset to start reading from.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public void readToToken(int tok, int offset) throws CoreException {
+		setOffset(offset);
+		readToToken(tok);
+	}
+
+	/**
+	 * Reads from the given offset until a token is reached and returns the start offset of the token.
+	 * @param token The token to be found.
+	 * @param startOffset The offset to start reading from.
+	 * @return Returns the start position of the found token.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int getTokenStartOffset(int token, int startOffset) throws CoreException {
+		readToToken(token, startOffset);
+		return getCurrentStartOffset();
+	}
+
+	/**
+	 * Reads from the given offset until a token is reached and returns the offset after the token.
+	 * @param token The token to be found.
+	 * @param startOffset Offset to start reading from
+	 * @return Returns the end position of the found token.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int getTokenEndOffset(int token, int startOffset) throws CoreException {
+		readToToken(token, startOffset);
+		return getCurrentEndOffset();
+	}
+
+	/**
+	 * Reads from the given offset until a token is reached and returns the offset after the previous token.
+	 * @param token The token to be found.
+	 * @param startOffset The offset to start scanning from.
+	 * @return Returns the end offset of the token previous to the given token.
+	 * @exception CoreException Thrown when the end of the file has been reached (code END_OF_FILE)
+	 * or a lexical error was detected while scanning (code LEXICAL_ERROR)
+	 */
+	public int getPreviousTokenEndOffset(int token, int startOffset) throws CoreException {
+		setOffset(startOffset);
+		int res= startOffset;
+		int curr= readNext(false);
+		while (curr != token) {
+			res= getCurrentEndOffset();
+			curr= readNext(false);
+		}
+		return res;
+	}
+
+	public static boolean isComment(int token) {
+		return token == TerminalTokens.TokenNameCOMMENT_BLOCK || token == TerminalTokens.TokenNameCOMMENT_JAVADOC
+			|| token == TerminalTokens.TokenNameCOMMENT_LINE;
+	}
+
+	public static boolean isModifier(int token) {
+		switch (token) {
+			case TerminalTokens.TokenNamepublic:
+			case TerminalTokens.TokenNameprotected:
+			case TerminalTokens.TokenNameprivate:
+			case TerminalTokens.TokenNamestatic:
+			case TerminalTokens.TokenNamefinal:
+			case TerminalTokens.TokenNameabstract:
+			case TerminalTokens.TokenNamenative:
+			case TerminalTokens.TokenNamevolatile:
+			case TerminalTokens.TokenNamestrictfp:
+			case TerminalTokens.TokenNametransient:
+			case TerminalTokens.TokenNamesynchronized:
+				return true;
+			default:
+				return false;
+		}
+	}
+
+	public static IStatus createError(int code, String message, Throwable throwable) {
+		return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, code, message, throwable);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
new file mode 100644
index 0000000..c2bc836
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.dom.rewrite;
+
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ *
+ */
+public class TrackedNodePosition implements ITrackedNodePosition {
+
+	private final TextEditGroup group;
+	private final ASTNode node;
+
+	public TrackedNodePosition(TextEditGroup group, ASTNode node) {
+		this.group= group;
+		this.node= node;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.ITrackedNodePosition#getStartPosition()
+	 */
+	public int getStartPosition() {
+		if (this.group.isEmpty()) {
+			return this.node.getStartPosition();
+		}
+		IRegion coverage= TextEdit.getCoverage(this.group.getTextEdits());
+		if (coverage == null) {
+			return this.node.getStartPosition();
+		}
+		return coverage.getOffset();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.corext.dom.ITrackedNodePosition#getLength()
+	 */
+	public int getLength() {
+		if (this.group.isEmpty()) {
+			return this.node.getLength();
+		}
+		IRegion coverage= TextEdit.getCoverage(this.group.getTextEdits());
+		if (coverage == null) {
+			return this.node.getLength();
+		}
+		return coverage.getLength();
+	}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java
new file mode 100644
index 0000000..b638a70
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+public class CodeSnippetAllocationExpression extends AllocationExpression implements ProblemReasons, EvaluationConstants {
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+/**
+ * CodeSnippetAllocationExpression constructor comment.
+ */
+public CodeSnippetAllocationExpression(EvaluationContext evaluationContext) {
+	this.evaluationContext = evaluationContext;
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, 	boolean valueRequired) {
+	int pc = codeStream.position;
+	MethodBinding codegenBinding = this.binding.original();
+	ReferenceBinding allocatedType = codegenBinding.declaringClass;
+
+	if (codegenBinding.canBeSeenBy(allocatedType, this, currentScope)) {
+		codeStream.new_(this.type, allocatedType);
+		if (valueRequired) {
+			codeStream.dup();
+		}
+		// better highlight for allocation: display the type individually
+		codeStream.recordPositionsFrom(pc, this.type.sourceStart);
+
+		// handling innerclass instance allocation - enclosing instance arguments
+		if (allocatedType.isNestedType()) {
+			codeStream.generateSyntheticEnclosingInstanceValues(
+				currentScope,
+				allocatedType,
+				enclosingInstance(),
+				this);
+		}
+		// generate the arguments for constructor
+		if (this.arguments != null) {
+			for (int i = 0, count = this.arguments.length; i < count; i++) {
+				this.arguments[i].generateCode(currentScope, codeStream, true);
+			}
+		}
+		// handling innerclass instance allocation - outer local arguments
+		if (allocatedType.isNestedType()) {
+			codeStream.generateSyntheticOuterArgumentValues(
+				currentScope,
+				allocatedType,
+				this);
+		}
+		// invoke constructor
+		codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */);
+	} else {
+		// private emulation using reflect
+		codeStream.generateEmulationForConstructor(currentScope, codegenBinding);
+		// generate arguments
+		if (this.arguments != null) {
+			int argsLength = this.arguments.length;
+			codeStream.generateInlinedValue(argsLength);
+			codeStream.newArray(null, currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1));
+			codeStream.dup();
+			for (int i = 0; i < argsLength; i++) {
+				codeStream.generateInlinedValue(i);
+				this.arguments[i].generateCode(currentScope, codeStream, true);
+				TypeBinding parameterBinding = codegenBinding.parameters[i];
+				if (parameterBinding.isBaseType() && parameterBinding != TypeBinding.NULL) {
+					codeStream.generateBoxingConversion(codegenBinding.parameters[i].id);
+				}
+				codeStream.aastore();
+				if (i < argsLength - 1) {
+					codeStream.dup();
+				}
+			}
+		} else {
+			codeStream.generateInlinedValue(0);
+			codeStream.newArray(null, currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1));
+		}
+		codeStream.invokeJavaLangReflectConstructorNewInstance();
+		codeStream.checkcast(allocatedType);
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+/* Inner emulation consists in either recording a dependency
+ * link only, or performing one level of propagation.
+ *
+ * Dependency mechanism is used whenever dealing with source target
+ * types, since by the time we reach them, we might not yet know their
+ * exact need.
+ */
+public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	// not supported yet
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+	// do nothing
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// Propagate the type checking to the arguments, and check if the constructor is defined.
+	this.constant = Constant.NotAConstant;
+	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/); // will check for null after args are resolved
+	checkParameterizedAllocation: {
+		if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
+			ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
+			if (currentType == null) return currentType;
+			do {
+				// isStatic() is answering true for toplevel types
+				if ((currentType.modifiers & ClassFileConstants.AccStatic) != 0) break checkParameterizedAllocation;
+				if (currentType.isRawType()) break checkParameterizedAllocation;
+			} while ((currentType = currentType.enclosingType())!= null);
+			ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
+			for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
+				if (qRef.typeArguments[i] != null) {
+					scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
+					break;
+				}
+			}
+		}
+	}
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
+	// resolve type arguments (for generic constructor call)
+	if (this.typeArguments != null) {
+		int length = this.typeArguments.length;
+		boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
+		this.genericTypeArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			TypeReference typeReference = this.typeArguments[i];
+			if ((this.genericTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
+				argHasError = true;
+			}
+			if (argHasError && typeReference instanceof Wildcard) {
+				scope.problemReporter().illegalUsageOfWildcard(typeReference);
+			}
+		}
+		if (isDiamond) {
+			scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
+			return null;
+		}
+		if (argHasError) {
+			if (this.arguments != null) { // still attempt to resolve arguments
+				for (int i = 0, max = this.arguments.length; i < max; i++) {
+					this.arguments[i].resolveType(scope);
+				}
+			}
+			return null;
+		}
+	}
+
+	// buffering the arguments' types
+	boolean argsContainCast = false;
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+	boolean polyExpressionSeen = false;
+	if (this.arguments != null) {
+		boolean argHasError = false;
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		TypeBinding argumentType;
+		for (int i = 0; i < length; i++) {
+			Expression argument = this.arguments[i];
+			if (argument instanceof CastExpression) {
+				argument.bits |= DisableUnnecessaryCastCheck; // will check later on
+				argsContainCast = true;
+			}
+			argument.setExpressionContext(INVOCATION_CONTEXT);
+			if ((argumentType = argumentTypes[i] = argument.resolveType(scope)) == null) {
+				argHasError = true;
+			}
+			if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+				polyExpressionSeen = true;
+		}
+		if (argHasError) {
+			return this.resolvedType;
+		}
+	}
+	if (this.resolvedType == null) {
+		return null;
+	}
+	if (!this.resolvedType.canBeInstantiated()) {
+		scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
+		return this.resolvedType;
+	}
+	if (isDiamond) {
+		TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+		if (inferredTypes == null) {
+			scope.problemReporter().cannotInferElidedTypes(this);
+			return this.resolvedType = null;
+		}
+		this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+ 	}
+	
+	ReferenceBinding allocatedType = (ReferenceBinding) this.resolvedType;
+	this.binding = scope.getConstructor(allocatedType, argumentTypes, this);
+	if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+		return null;
+
+	if (!this.binding.isValidBinding()) {	
+		if (this.binding instanceof ProblemMethodBinding
+			&& ((ProblemMethodBinding) this.binding).problemId() == NotVisible) {
+			if (this.evaluationContext.declaringTypeName != null) {
+				this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+				if (this.delegateThis == null) {
+					if (this.binding.declaringClass == null) {
+						this.binding.declaringClass = allocatedType;
+					}
+					if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+						return null;
+					}
+					scope.problemReporter().invalidConstructor(this, this.binding);
+					return this.resolvedType;
+				}
+			} else {
+				if (this.binding.declaringClass == null) {
+					this.binding.declaringClass = allocatedType;
+				}
+				if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+					return null;
+				}
+				scope.problemReporter().invalidConstructor(this, this.binding);
+				return this.resolvedType;
+			}
+			CodeSnippetScope localScope = new CodeSnippetScope(scope);
+			MethodBinding privateBinding = localScope.getConstructor((ReferenceBinding)this.delegateThis.type, argumentTypes, this);
+			if (!privateBinding.isValidBinding()) {
+				if (this.binding.declaringClass == null) {
+					this.binding.declaringClass = allocatedType;
+				}
+				if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+					return null;
+				}
+				scope.problemReporter().invalidConstructor(this, this.binding);
+				return this.resolvedType;
+			} else {
+				this.binding = privateBinding;
+			}
+		} else {
+			if (this.binding.declaringClass == null) {
+				this.binding.declaringClass = allocatedType;
+			}
+			if (this.type != null && !this.type.resolvedType.isValidBinding()) {
+				return null;
+			}
+			scope.problemReporter().invalidConstructor(this, this.binding);
+			return this.resolvedType;
+		}
+	}
+	if (isMethodUseDeprecated(this.binding, scope, true)) {
+		scope.problemReporter().deprecatedMethod(this.binding, this);
+	}
+	if (this.arguments != null) {
+		for (int i = 0; i < this.arguments.length; i++) {
+			TypeBinding parameterType = this.binding.parameters[i];
+			TypeBinding argumentType = argumentTypes[i];
+			this.arguments[i].computeConversion(scope, parameterType, argumentType);
+			if (argumentType.needsUncheckedConversion(parameterType)) {
+				scope.problemReporter().unsafeTypeConversion(this.arguments[i], argumentType, parameterType);
+			}
+		}
+		if (argsContainCast) {
+			CastExpression.checkNeedForArgumentCasts(scope, null, allocatedType, this.binding, this.arguments, argumentTypes, this);
+		}
+	}
+	if (allocatedType.isRawType() && this.binding.hasSubstitutedParameters()) {
+		scope.problemReporter().unsafeRawInvocation(this, this.binding);
+	}
+	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
+		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
+	}
+	return allocatedType;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
new file mode 100644
index 0000000..56a0ade
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.TypeAnnotationCodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CodeSnippetClassFile extends ClassFile {
+/**
+ * CodeSnippetClassFile constructor comment.
+ * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
+ * @param enclosingClassFile org.eclipse.jdt.internal.compiler.ClassFile
+ * @param creatingProblemType boolean
+ */
+public CodeSnippetClassFile(
+	org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding aType,
+	org.eclipse.jdt.internal.compiler.ClassFile enclosingClassFile,
+	boolean creatingProblemType) {
+	/**
+	 * INTERNAL USE-ONLY
+	 * This methods creates a new instance of the receiver.
+	 *
+	 * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
+	 * @param enclosingClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
+	 * @param creatingProblemType <CODE>boolean</CODE>
+	 */
+	this.referenceBinding = aType;
+	initByteArrays();
+	// generate the magic numbers inside the header
+	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
+	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
+	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
+	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);
+
+	long targetVersion = this.targetJDK = this.referenceBinding.scope.compilerOptions().targetJDK;
+	//TODO: Might have to update even for CLDC_1_1
+	this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high
+	this.header[this.headerOffset++] = (byte) (targetVersion >> 0); // minor low
+	this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high
+	this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low
+
+	this.constantPoolOffset = this.headerOffset;
+	this.headerOffset += 2;
+	this.constantPool = new ConstantPool(this);
+	int accessFlags = aType.getAccessFlags();
+
+	if (!aType.isInterface()) { // class or enum
+		accessFlags |= ClassFileConstants.AccSuper;
+	}
+	if (aType.isNestedType()) {
+		if (aType.isStatic()) {
+			// clear Acc_Static
+			accessFlags &= ~ClassFileConstants.AccStatic;
+		}
+		if (aType.isPrivate()) {
+			// clear Acc_Private and Acc_Public
+			accessFlags &= ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccPublic);
+		}
+		if (aType.isProtected()) {
+			// clear Acc_Protected and set Acc_Public
+			accessFlags &= ~ClassFileConstants.AccProtected;
+			accessFlags |= ClassFileConstants.AccPublic;
+		}
+	}
+	// clear Acc_Strictfp
+	accessFlags &= ~ClassFileConstants.AccStrictfp;
+
+	this.enclosingClassFile = enclosingClassFile;
+	// now we continue to generate the bytes inside the contents array
+	this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
+	this.contents[this.contentsOffset++] = (byte) accessFlags;
+	int classNameIndex = this.constantPool.literalIndexForType(aType);
+	this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
+	this.contents[this.contentsOffset++] = (byte) classNameIndex;
+	int superclassNameIndex;
+	if (aType.isInterface()) {
+		superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
+	} else {
+		superclassNameIndex =
+			(aType.superclass == null ? 0 : this.constantPool.literalIndexForType(aType.superclass));
+	}
+	this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
+	this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
+	ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
+	int interfacesCount = superInterfacesBinding.length;
+	this.contents[this.contentsOffset++] = (byte) (interfacesCount >> 8);
+	this.contents[this.contentsOffset++] = (byte) interfacesCount;
+	for (int i = 0; i < interfacesCount; i++) {
+		int interfaceIndex = this.constantPool.literalIndexForType(superInterfacesBinding[i]);
+		this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) interfaceIndex;
+	}
+	this.produceAttributes = this.referenceBinding.scope.compilerOptions().produceDebugAttributes;
+	this.creatingProblemType = creatingProblemType;
+	if (this.targetJDK >= ClassFileConstants.JDK1_6) {
+		this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
+		if (this.targetJDK >= ClassFileConstants.JDK1_8) {
+			this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
+			this.codeStream = new TypeAnnotationCodeStream(this);
+		} else {
+			this.codeStream = new StackMapFrameCodeStream(this);
+		}
+	} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
+		this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
+		this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
+		this.codeStream = new StackMapFrameCodeStream(this);
+	} else {
+		this.codeStream = new CodeStream(this);
+	}
+	// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
+	// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
+	this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
+}
+/**
+ * INTERNAL USE-ONLY
+ * Request the creation of a ClassFile compatible representation of a problematic type
+ *
+ * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
+ * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
+ */
+public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
+	SourceTypeBinding typeBinding = typeDeclaration.binding;
+	ClassFile classFile = new CodeSnippetClassFile(typeBinding, null, true);
+
+	// inner attributes
+	if (typeBinding.hasMemberTypes()) {
+		// see bug 180109
+		ReferenceBinding[] members = typeBinding.memberTypes;
+		for (int i = 0, l = members.length; i < l; i++)
+			classFile.recordInnerClasses(members[i]);
+	}
+	// TODO (olivier) handle cases where a field cannot be generated (name too long)
+	// TODO (olivier) handle too many methods
+	// inner attributes
+	if (typeBinding.isNestedType()) {
+		classFile.recordInnerClasses(typeBinding);
+	}
+	TypeVariableBinding[] typeVariables = typeBinding.typeVariables();
+	for (int i = 0, max = typeVariables.length; i < max; i++) {
+		TypeVariableBinding typeVariableBinding = typeVariables[i];
+		if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(classFile, typeVariableBinding);
+		}
+	}
+
+	// add its fields
+	FieldBinding[] fields = typeBinding.fields();
+	if ((fields != null) && (fields != Binding.NO_FIELDS)) {
+		classFile.addFieldInfos();
+	} else {
+		// we have to set the number of fields to be equals to 0
+		classFile.contents[classFile.contentsOffset++] = 0;
+		classFile.contents[classFile.contentsOffset++] = 0;
+	}
+	// leave some space for the methodCount
+	classFile.setForMethodInfos();
+	// add its user defined methods
+	int problemsLength;
+	CategorizedProblem[] problems = unitResult.getErrors();
+	if (problems == null) {
+		problems = new CategorizedProblem[0];
+	}
+	CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
+	System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
+	AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
+	if (methodDecls != null) {
+		if (typeBinding.isInterface()) {
+			// we cannot create problem methods for an interface. So we have to generate a clinit
+			// which should contain all the problem
+			classFile.addProblemClinit(problemsCopy);
+			for (int i = 0, length = methodDecls.length; i < length; i++) {
+				AbstractMethodDeclaration methodDecl = methodDecls[i];
+				MethodBinding method = methodDecl.binding;
+				if (method == null || method.isConstructor()) continue;
+				method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
+				classFile.addAbstractMethod(methodDecl, method);
+			}
+		} else {
+			for (int i = 0, length = methodDecls.length; i < length; i++) {
+				AbstractMethodDeclaration methodDecl = methodDecls[i];
+				MethodBinding method = methodDecl.binding;
+				if (method == null) continue;
+				if (method.isConstructor()) {
+					classFile.addProblemConstructor(methodDecl, method, problemsCopy);
+				} else if (method.isAbstract()) {
+					classFile.addAbstractMethod(methodDecl, method);
+				} else {
+					classFile.addProblemMethod(methodDecl, method, problemsCopy);
+				}
+			}
+		}
+		// add abstract methods
+		classFile.addDefaultAbstractMethods();
+	}
+	// propagate generation of (problem) member types
+	if (typeDeclaration.memberTypes != null) {
+		for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
+			TypeDeclaration memberType = typeDeclaration.memberTypes[i];
+			if (memberType.binding != null) {
+				ClassFile.createProblemType(memberType, unitResult);
+			}
+		}
+	}
+	classFile.addAttributes();
+	unitResult.record(typeBinding.constantPoolName(), classFile);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java
new file mode 100644
index 0000000..ca98716
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * A compiler that compiles code snippets.
+ */
+public class CodeSnippetCompiler extends Compiler {
+
+	EvaluationContext evaluationContext;
+	int codeSnippetStart;
+	int codeSnippetEnd;
+
+	/**
+	 * Creates a new code snippet compiler initialized with a code snippet parser.
+	 */
+	public CodeSnippetCompiler(
+    		INameEnvironment environment,
+    		IErrorHandlingPolicy policy,
+    		CompilerOptions compilerOptions,
+    		ICompilerRequestor requestor,
+    		IProblemFactory problemFactory,
+    		EvaluationContext evaluationContext,
+    		int codeSnippetStart,
+    		int codeSnippetEnd) {
+		super(environment, policy, compilerOptions, requestor, problemFactory);
+		this.codeSnippetStart = codeSnippetStart;
+		this.codeSnippetEnd = codeSnippetEnd;
+		this.evaluationContext = evaluationContext;
+		this.parser =
+			new CodeSnippetParser(
+				this.problemReporter,
+				evaluationContext,
+				this.options.parseLiteralExpressionsAsConstants,
+				codeSnippetStart,
+				codeSnippetEnd);
+		this.parseThreshold = 1;
+		// fully parse only the code snippet compilation unit
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser()
+	 */
+	public void initializeParser() {
+		this.parser =
+			new CodeSnippetParser(
+				this.problemReporter,
+				this.evaluationContext,
+				this.options.parseLiteralExpressionsAsConstants,
+				this.codeSnippetStart,
+				this.codeSnippetEnd);
+		}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java
new file mode 100644
index 0000000..24b0b5e
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+
+/**
+ * An environment that wraps the client's name environment.
+ * This wrapper always considers the wrapped environment then if the name is
+ * not found, it search in the code snippet support. This includes the super class
+ * org.eclipse.jdt.internal.eval.target.CodeSnippet as well as the global variable classes.
+ */
+public class CodeSnippetEnvironment implements INameEnvironment, EvaluationConstants {
+	INameEnvironment env;
+	EvaluationContext context;
+/**
+ * Creates a new wrapper for the given environment.
+ */
+public CodeSnippetEnvironment(INameEnvironment env, EvaluationContext context) {
+	this.env = env;
+	this.context = context;
+}
+/**
+ * @see INameEnvironment#findType(char[][])
+ */
+public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
+	NameEnvironmentAnswer result = this.env.findType(compoundTypeName);
+	if (result != null) {
+		return result;
+	}
+	if (CharOperation.equals(compoundTypeName, ROOT_COMPOUND_NAME)) {
+		IBinaryType binary = this.context.getRootCodeSnippetBinary();
+		if (binary == null) {
+			return null;
+		} else {
+			return new NameEnvironmentAnswer(binary, null /*no access restriction*/);
+		}
+	}
+	VariablesInfo installedVars = this.context.installedVars;
+	ClassFile[] classFiles = installedVars.classFiles;
+	for (int i = 0; i < classFiles.length; i++) {
+		ClassFile classFile = classFiles[i];
+		if (CharOperation.equals(compoundTypeName, classFile.getCompoundName())) {
+			ClassFileReader binary = null;
+			try {
+				binary = new ClassFileReader(classFile.getBytes(), null);
+			} catch (ClassFormatException e) {
+				e.printStackTrace();  // Should never happen since we compiled this type
+				return null;
+			}
+			return new NameEnvironmentAnswer(binary, null /*no access restriction*/);
+		}
+	}
+	return null;
+}
+/**
+ * @see INameEnvironment#findType(char[], char[][])
+ */
+public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+	NameEnvironmentAnswer result = this.env.findType(typeName, packageName);
+	if (result != null) {
+		return result;
+	}
+	return findType(CharOperation.arrayConcat(packageName, typeName));
+}
+/**
+ * @see INameEnvironment#isPackage(char[][], char[])
+ */
+public boolean isPackage(char[][] parentPackageName, char[] packageName) {
+	return this.env.isPackage(parentPackageName, packageName);
+}
+public void cleanup() {
+	this.env.cleanup();
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
new file mode 100644
index 0000000..55612ed
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * A code snippet evaluator compiles and returns class file for a code snippet.
+ * Or it reports problems against the code snippet.
+ */
+public class CodeSnippetEvaluator extends Evaluator implements EvaluationConstants {
+	/**
+	 * Whether the code snippet support classes should be found in the provided name environment
+	 * or on disk.
+	 */
+	static final boolean DEVELOPMENT_MODE = false;
+
+	/**
+	 * The code snippet to evaluate.
+	 */
+	char[] codeSnippet;
+
+	/**
+	 * The code snippet to generated compilation unit mapper
+	 */
+	CodeSnippetToCuMapper mapper;
+/**
+ * Creates a new code snippet evaluator.
+ */
+CodeSnippetEvaluator(char[] codeSnippet, EvaluationContext context, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) {
+	super(context, environment, options, requestor, problemFactory);
+	this.codeSnippet = codeSnippet;
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected void addEvaluationResultForCompilationProblem(Map resultsByIDs, CategorizedProblem problem, char[] cuSource) {
+	CodeSnippetToCuMapper sourceMapper = getMapper();
+	int pbLineNumber = problem.getSourceLineNumber();
+	int evaluationType = sourceMapper.getEvaluationType(pbLineNumber);
+
+	char[] evaluationID = null;
+	switch(evaluationType) {
+		case EvaluationResult.T_PACKAGE:
+			evaluationID = this.context.packageName;
+
+			// shift line number, source start and source end
+			problem.setSourceLineNumber(1);
+			problem.setSourceStart(0);
+			problem.setSourceEnd(evaluationID.length - 1);
+			break;
+
+		case EvaluationResult.T_IMPORT:
+			evaluationID = sourceMapper.getImport(pbLineNumber);
+
+			// shift line number, source start and source end
+			problem.setSourceLineNumber(1);
+			problem.setSourceStart(0);
+			problem.setSourceEnd(evaluationID.length - 1);
+			break;
+
+		case EvaluationResult.T_CODE_SNIPPET:
+			evaluationID = this.codeSnippet;
+
+			// shift line number, source start and source end
+			problem.setSourceLineNumber(pbLineNumber - this.mapper.lineNumberOffset);
+			problem.setSourceStart(problem.getSourceStart() - this.mapper.startPosOffset);
+			problem.setSourceEnd(problem.getSourceEnd() - this.mapper.startPosOffset);
+			break;
+
+		case EvaluationResult.T_INTERNAL:
+			evaluationID = cuSource;
+			break;
+	}
+
+	EvaluationResult result = (EvaluationResult)resultsByIDs.get(evaluationID);
+	if (result == null) {
+		resultsByIDs.put(evaluationID, new EvaluationResult(evaluationID, evaluationType, new CategorizedProblem[] {problem}));
+	} else {
+		result.addProblem(problem);
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected char[] getClassName() {
+	return CharOperation.concat(CODE_SNIPPET_CLASS_NAME_PREFIX, Integer.toString(EvaluationContext.CODE_SNIPPET_COUNTER + 1).toCharArray());
+}
+/**
+ * @see Evaluator
+ */
+Compiler getCompiler(ICompilerRequestor compilerRequestor) {
+	Compiler compiler = null;
+	if (!DEVELOPMENT_MODE) {
+		// If we are not developping the code snippet support classes,
+		// use a regular compiler and feed its lookup environment with
+		// the code snippet support classes
+
+		CompilerOptions compilerOptions = new CompilerOptions(this.options);
+		compilerOptions.performMethodsFullRecovery = true;
+		compilerOptions.performStatementsRecovery = true;
+		compiler =
+			new CodeSnippetCompiler(
+				this.environment,
+				DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+				compilerOptions,
+				compilerRequestor,
+				this.problemFactory,
+				this.context,
+				getMapper().startPosOffset,
+				getMapper().startPosOffset + this.codeSnippet.length - 1);
+		((CodeSnippetParser) compiler.parser).lineSeparatorLength = this.context.lineSeparator.length();
+		// Initialize the compiler's lookup environment with the already compiled super classes
+		IBinaryType binary = this.context.getRootCodeSnippetBinary();
+		if (binary != null) {
+			compiler.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
+		}
+		VariablesInfo installedVars = this.context.installedVars;
+		if (installedVars != null) {
+			ClassFile[] globalClassFiles = installedVars.classFiles;
+			for (int i = 0; i < globalClassFiles.length; i++) {
+				ClassFileReader binaryType = null;
+				try {
+					binaryType = new ClassFileReader(globalClassFiles[i].getBytes(), null);
+				} catch (ClassFormatException e) {
+					e.printStackTrace(); // Should never happen since we compiled this type
+				}
+				compiler.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
+			}
+		}
+	} else {
+		// If we are developping the code snippet support classes,
+		// use a wrapped environment so that if the code snippet classes are not found
+		// then a default implementation is provided.
+
+		CompilerOptions compilerOptions = new CompilerOptions(this.options);
+		compilerOptions.performMethodsFullRecovery = true;
+		compilerOptions.performStatementsRecovery = true;
+		compiler = new Compiler(
+			getWrapperEnvironment(),
+			DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+			compilerOptions,
+			compilerRequestor,
+			this.problemFactory);
+	}
+	return compiler;
+}
+private CodeSnippetToCuMapper getMapper() {
+	if (this.mapper == null) {
+		char[] varClassName = null;
+		VariablesInfo installedVars = this.context.installedVars;
+		if (installedVars != null) {
+			char[] superPackageName = installedVars.packageName;
+			if (superPackageName != null && superPackageName.length != 0) {
+				varClassName = CharOperation.concat(superPackageName, installedVars.className, '.');
+			} else {
+				varClassName = installedVars.className;
+			}
+
+		}
+		this.mapper = new CodeSnippetToCuMapper(
+			this.codeSnippet,
+			this.context.packageName,
+			this.context.imports,
+			getClassName(),
+			varClassName,
+			this.context.localVariableNames,
+			this.context.localVariableTypeNames,
+			this.context.localVariableModifiers,
+			this.context.declaringTypeName,
+			this.context.lineSeparator,
+			CompilerOptions.versionToJdkLevel(this.options.get(JavaCore.COMPILER_COMPLIANCE))
+		);
+
+	}
+	return this.mapper;
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected char[] getSource() {
+	return getMapper().cuSource;
+}
+/**
+ * Returns an environment that wraps the client's name environment.
+ * This wrapper always considers the wrapped environment then if the name is
+ * not found, it search in the code snippet support. This includes the superclass
+ * org.eclipse.jdt.internal.eval.target.CodeSnippet as well as the global variable classes.
+ */
+private INameEnvironment getWrapperEnvironment() {
+	return new CodeSnippetEnvironment(this.environment, this.context);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
new file mode 100644
index 0000000..ea7fb3a
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class CodeSnippetFieldReference extends FieldReference implements ProblemReasons, EvaluationConstants {
+
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+/**
+ * CodeSnippetFieldReference constructor comment.
+ * @param source char[]
+ * @param pos long
+ */
+public CodeSnippetFieldReference(char[] source, long pos, EvaluationContext evaluationContext) {
+	super(source, pos);
+	this.evaluationContext = evaluationContext;
+}
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	FieldBinding codegenBinding = this.binding.original();
+	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+		this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic());
+		assignment.expression.generateCode(currentScope, codeStream, true);
+		fieldStore(currentScope, codeStream, codegenBinding, null, this.actualReceiverType, this.receiver.isImplicitThis(), valueRequired);
+	} else {
+		codeStream.generateEmulationForField(codegenBinding);
+		this.receiver.generateCode(currentScope, codeStream, !codegenBinding.isStatic());
+		if (codegenBinding.isStatic()) { // need a receiver?
+			codeStream.aconst_null();
+		}
+		assignment.expression.generateCode(currentScope, codeStream, true);
+		if (valueRequired) {
+			switch (codegenBinding.type.id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.dup2_x2();
+					break;
+				default :
+					codeStream.dup_x2();
+					break;
+			}			
+		}
+		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
+	}
+	if (valueRequired){
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+/**
+ * Field reference code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		}
+	} else {
+		FieldBinding codegenBinding = this.binding.original();
+		boolean isStatic = codegenBinding.isStatic();
+		this.receiver.generateCode(currentScope, codeStream, !isStatic);
+		if (valueRequired) {
+			Constant fieldConstant = codegenBinding.constant();
+			if (fieldConstant == Constant.NotAConstant) {
+				if (codegenBinding.declaringClass == null) { // array length
+					codeStream.arraylength();
+				} else {
+					if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+						if (isStatic) {
+							codeStream.fieldAccess(Opcodes.OPC_getstatic , codegenBinding, constantPoolDeclaringClass);
+						} else {
+							codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
+						}
+					} else {
+						if (isStatic) {
+							// we need a null on the stack to use the reflect emulation
+							codeStream.aconst_null();
+						}
+						codeStream.generateEmulatedReadAccessForField(codegenBinding);
+					}
+				}
+				codeStream.generateImplicitConversion(this.implicitConversion);
+			} else {
+				if (!isStatic) {
+					codeStream.invokeObjectGetClass(); // perform null check
+					codeStream.pop();
+				}
+				codeStream.generateConstant(fieldConstant, this.implicitConversion);
+			}
+		} else {
+			if (!isStatic){
+				codeStream.invokeObjectGetClass(); // perform null check
+				codeStream.pop();
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	boolean isStatic;
+	FieldBinding codegenBinding = this.binding.original();
+	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
+		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+		if (isStatic) {
+			codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			codeStream.dup();
+			codeStream.fieldAccess(Opcodes.OPC_getfield, codegenBinding, constantPoolDeclaringClass);
+		}
+		int operationTypeID;
+		switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
+			case T_JavaLangString :
+			case T_JavaLangObject :
+			case T_undefined :
+				codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+				break;
+			default :
+				// promote the array reference to the suitable operation type
+				codeStream.generateImplicitConversion(this.implicitConversion);
+				// generate the increment value (will by itself  be promoted to the operation value)
+				if (expression == IntLiteral.One){ // prefix operation
+					codeStream.generateConstant(expression.constant, this.implicitConversion);
+				} else {
+					expression.generateCode(currentScope, codeStream, true);
+				}
+				// perform the operation
+				codeStream.sendOperator(operator, operationTypeID);
+				// cast the value back to the array reference type
+				codeStream.generateImplicitConversion(assignmentImplicitConversion);
+		}
+		fieldStore(currentScope, codeStream, codegenBinding, null, this.actualReceiverType, this.receiver.isImplicitThis(), valueRequired);
+	} else {
+		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
+		if (isStatic) {
+			// used to store the value
+			codeStream.generateEmulationForField(codegenBinding);
+			codeStream.aconst_null();
+
+			// used to retrieve the actual value
+			codeStream.aconst_null();
+			codeStream.generateEmulatedReadAccessForField(codegenBinding);
+		} else {
+			// used to store the value
+			codeStream.generateEmulationForField(this.binding);
+			this.receiver.generateCode(currentScope, codeStream, !isStatic);
+
+			// used to retrieve the actual value
+			codeStream.dup();
+			codeStream.generateEmulatedReadAccessForField(codegenBinding);
+		}
+		int operationTypeID;
+		if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+		} else {
+			// promote the array reference to the suitable operation type
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One){ // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+		}
+		// current stack is:
+		// field receiver value
+		if (valueRequired) {
+			if ((codegenBinding.type == TypeBinding.LONG) || (codegenBinding.type == TypeBinding.DOUBLE)) {
+				codeStream.dup2_x2();
+			} else {
+				codeStream.dup_x2();
+			}
+		}
+		// current stack is:
+		// value field receiver value
+		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
+	}
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	boolean isStatic;
+	FieldBinding codegenBinding = this.binding.original();
+	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
+	} else {
+		this.receiver.generateCode(currentScope, codeStream, !(isStatic = codegenBinding.isStatic()));
+		if (isStatic) {
+			codeStream.aconst_null();
+		}
+		// the actual stack is: receiver
+		codeStream.dup();
+		// the actual stack is: receiver receiver
+		codeStream.generateEmulatedReadAccessForField(codegenBinding);
+		// the actual stack is: receiver value
+		// receiver value
+		// value receiver value 							dup_x1 or dup2_x1 if value required
+		// value value receiver value					dup_x1 or dup2_x1
+		// value value receiver							pop or pop2
+		// value value receiver field						generateEmulationForField
+		// value value field receiver 					swap
+		// value field receiver value field receiver 	dup2_x1 or dup2_x2
+		// value field receiver value 				 	pop2
+		// value field receiver newvalue 				generate constant + op
+		// value 												store
+		int typeID;
+		switch (typeID = codegenBinding.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				if (valueRequired) {
+					codeStream.dup2_x1();
+				}
+				codeStream.dup2_x1();
+				codeStream.pop2();
+				break;
+			default :
+				if (valueRequired) {
+					codeStream.dup_x1();
+				}
+				codeStream.dup_x1();
+				codeStream.pop();
+				break;
+		}
+		codeStream.generateEmulationForField(codegenBinding);
+		codeStream.swap();
+		switch (typeID) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2_x2();
+				break;
+			default :
+				codeStream.dup2_x1();
+				break;
+		}
+		codeStream.pop2();
+
+		codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+		codeStream.sendOperator(postIncrement.operator, codegenBinding.type.id);
+		codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+		codeStream.generateEmulatedWriteAccessForField(codegenBinding);
+	}
+}
+/*
+ * No need to emulate access to protected fields since not implicitly accessed
+ */
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess){
+	// The private access will be managed through the code generation
+
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature type of the field.
+	// constants are propaged when the field is final
+	// and initialized with a (compile time) constant
+
+	// regular receiver reference
+	this.actualReceiverType = this.receiver.resolveType(scope);
+	if (this.actualReceiverType == null){
+		this.constant = Constant.NotAConstant;
+		return null;
+	}
+	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
+	this.binding = scope.getField(this.actualReceiverType, this.token, this);
+	FieldBinding firstAttempt = this.binding;
+	boolean isNotVisible = false;
+	if (!this.binding.isValidBinding()) {
+		if (this.binding instanceof ProblemFieldBinding
+			&& ((ProblemFieldBinding) this.binding).problemId() == NotVisible) {
+				isNotVisible = true;
+				if (this.evaluationContext.declaringTypeName != null) {
+					this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+					if (this.delegateThis == null){  // if not found then internal error, field should have been found
+						this.constant = Constant.NotAConstant;
+						scope.problemReporter().invalidField(this, this.actualReceiverType);
+						return null;
+					}
+					this.actualReceiverType = this.delegateThis.type;
+				} else {
+					this.constant = Constant.NotAConstant;
+					scope.problemReporter().invalidField(this, this.actualReceiverType);
+					return null;
+				}
+			CodeSnippetScope localScope = new CodeSnippetScope(scope);
+			this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this);
+		}
+	}
+
+	if (!this.binding.isValidBinding()) {
+		this.constant = Constant.NotAConstant;
+		if (isNotVisible) {
+			this.binding = firstAttempt;
+		}
+		scope.problemReporter().invalidField(this, this.actualReceiverType);
+		return null;
+	}
+
+	if (isFieldUseDeprecated(this.binding, scope, this.bits)) {
+		scope.problemReporter().deprecatedField(this.binding, this);
+	}
+	// check for this.x in static is done in the resolution of the receiver
+	this.constant = this.receiver.isImplicitThis() ? this.binding.constant() : Constant.NotAConstant;
+	if (!this.receiver.isThis()) { // TODO need to check if shouldn't be isImplicitThis check (and then removed)
+		this.constant = Constant.NotAConstant;
+	}
+	return this.resolvedType = this.binding.type;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
new file mode 100644
index 0000000..3f68c38
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+
+public class CodeSnippetMessageSend extends MessageSend {
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+/**
+ * CodeSnippetMessageSend constructor comment.
+ */
+public CodeSnippetMessageSend(EvaluationContext evaluationContext) {
+	this.evaluationContext = evaluationContext;
+}
+/**
+ * MessageSend code generation
+ *
+ * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	MethodBinding codegenBinding = this.binding.original();
+	if (codegenBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+		// generate receiver/enclosing instance access
+		boolean isStatic = codegenBinding.isStatic();
+		// outer access ?
+		if (!isStatic && ((this.bits & DepthMASK) != 0)) {
+			// outer method can be reached through emulation
+			ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
+			Object[] path = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+			if (path == null) {
+				// emulation was not possible (should not happen per construction)
+				currentScope.problemReporter().needImplementation(this);
+			} else {
+				codeStream.generateOuterAccess(path, this, targetType, currentScope);
+			}
+		} else {
+			this.receiver.generateCode(currentScope, codeStream, !isStatic);
+			if ((this.bits & NeedReceiverGenericCast) != 0) {
+				codeStream.checkcast(this.actualReceiverType);
+			}			
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		}
+		// generate arguments
+		generateArguments(this.binding, this.arguments, currentScope, codeStream);
+		// actual message invocation
+		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
+		if (isStatic) {
+			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass);
+		} else if( (this.receiver.isSuper()) || codegenBinding.isPrivate()){
+			codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, constantPoolDeclaringClass);
+		} else {
+			if (constantPoolDeclaringClass.isInterface()) { // interface or annotation type
+				codeStream.invoke(Opcodes.OPC_invokeinterface, codegenBinding, constantPoolDeclaringClass);
+			} else {
+				codeStream.invoke(Opcodes.OPC_invokevirtual, codegenBinding, constantPoolDeclaringClass);
+			}
+		}
+	} else {
+		codeStream.generateEmulationForMethod(currentScope, codegenBinding);
+		// generate receiver/enclosing instance access
+		boolean isStatic = codegenBinding.isStatic();
+		// outer access ?
+		if (!isStatic && ((this.bits & DepthMASK) != 0)) {
+			// not supported yet
+			currentScope.problemReporter().needImplementation(this);
+		} else {
+			this.receiver.generateCode(currentScope, codeStream, !isStatic);
+			if ((this.bits & NeedReceiverGenericCast) != 0) {
+				codeStream.checkcast(this.actualReceiverType);
+			}			
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		}
+		if (isStatic) {
+			// we need an object on the stack which is ignored for the method invocation
+			codeStream.aconst_null();
+		}
+		// generate arguments
+		if (this.arguments != null) {
+			int argsLength = this.arguments.length;
+			codeStream.generateInlinedValue(argsLength);
+			codeStream.newArray(null, currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1));
+			codeStream.dup();
+			for (int i = 0; i < argsLength; i++) {
+				codeStream.generateInlinedValue(i);
+				this.arguments[i].generateCode(currentScope, codeStream, true);
+				TypeBinding parameterBinding = codegenBinding.parameters[i];
+				if (parameterBinding.isBaseType() && parameterBinding != TypeBinding.NULL) {
+					codeStream.generateBoxingConversion(codegenBinding.parameters[i].id);
+				}
+				codeStream.aastore();
+				if (i < argsLength - 1) {
+					codeStream.dup();
+				}
+			}
+		} else {
+			codeStream.generateInlinedValue(0);
+			codeStream.newArray(null, currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1));
+		}
+		codeStream.invokeJavaLangReflectMethodInvoke();
+
+		// convert the return value to the appropriate type for primitive types
+		if (codegenBinding.returnType.isBaseType()) {
+			int typeID = codegenBinding.returnType.id;
+			if (typeID == T_void) {
+				// remove the null from the stack
+				codeStream.pop();
+			}
+			codeStream.checkcast(typeID);
+			codeStream.getBaseTypeValue(typeID);
+		} else {
+			codeStream.checkcast(codegenBinding.returnType);
+		}
+	}
+	// required cast must occur even if no value is required
+	if (this.valueCast != null) codeStream.checkcast(this.valueCast);
+	if (valueRequired){
+		// implicit conversion if necessary
+		codeStream.generateImplicitConversion(this.implicitConversion);
+	} else {
+		boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+		// conversion only generated if unboxing
+		if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+		switch (isUnboxing ? postConversionType(currentScope).id : codegenBinding.returnType.id) {
+			case T_long :
+			case T_double :
+				codeStream.pop2();
+				break;
+			case T_void :
+				break;
+			default :
+				codeStream.pop();
+		}
+	}
+	codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
+
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
+		// if method from parameterized type got found, use the original method at codegen time
+		MethodBinding codegenBinding = this.binding.original();
+		if (codegenBinding != this.binding) {
+		    // extra cast needed if method return type was type variable
+		    if (codegenBinding.returnType.isTypeVariable()) {
+		        TypeVariableBinding variableReturnType = (TypeVariableBinding) codegenBinding.returnType;
+		        if (variableReturnType.firstBound != this.binding.returnType) { // no need for extra cast if same as first bound anyway
+				    this.valueCast = this.binding.returnType;
+		        }
+		    }
+		}
+	}
+}
+public TypeBinding resolveType(BlockScope scope) {
+	// Answer the signature return type
+	// Base type promotion
+
+	this.constant = Constant.NotAConstant;
+	boolean receiverCast = false, argsContainCast = false;
+	if (this.receiver instanceof CastExpression) {
+		this.receiver.bits |= DisableUnnecessaryCastCheck; // will check later on
+		receiverCast = true;
+	}
+	this.actualReceiverType = this.receiver.resolveType(scope);
+	if (receiverCast && this.actualReceiverType != null) {
+		 // due to change of declaring class with receiver type, only identity cast should be notified
+		if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+			scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
+		}
+	}
+	// resolve type arguments (for generic constructor call)
+	if (this.typeArguments != null) {
+		int length = this.typeArguments.length;
+		boolean argHasError = false; // typeChecks all arguments
+		this.genericTypeArguments = new TypeBinding[length];
+		for (int i = 0; i < length; i++) {
+			if ((this.genericTypeArguments[i] = this.typeArguments[i].resolveType(scope, true /* check bounds*/)) == null) {
+				argHasError = true;
+			}
+		}
+		if (argHasError) {
+			return null;
+		}
+	}
+	// will check for null after args are resolved
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
+	boolean polyExpressionSeen = false;
+	if (this.arguments != null) {
+		boolean argHasError = false; // typeChecks all arguments
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		TypeBinding argumentType;
+		for (int i = 0; i < length; i++) {
+			Expression argument = this.arguments[i];
+			if (argument instanceof CastExpression) {
+				argument.bits |= DisableUnnecessaryCastCheck; // will check later on
+				argsContainCast = true;
+			}
+			argument.setExpressionContext(INVOCATION_CONTEXT);
+			if ((argumentType = argumentTypes[i] = this.arguments[i].resolveType(scope)) == null)
+				argHasError = true;
+			if (argumentType != null && argumentType.kind() == Binding.POLY_TYPE)
+				polyExpressionSeen = true;
+		}
+		if (argHasError) {
+			if(this.actualReceiverType instanceof ReferenceBinding) {
+				// record any selector match, for clients who may still need hint about possible method match
+				this.binding = scope.findMethod((ReferenceBinding)this.actualReceiverType, this.selector, new TypeBinding[]{}, this);
+			}
+			return null;
+		}
+	}
+	if (this.actualReceiverType == null) {
+		return null;
+	}
+	// base type cannot receive any message
+	if (this.actualReceiverType.isBaseType()) {
+		scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+		return null;
+	}
+
+	this.binding =
+		this.receiver.isImplicitThis()
+			? scope.getImplicitMethod(this.selector, argumentTypes, this)
+			: scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+	
+	if (polyExpressionSeen && polyExpressionsHaveErrors(scope, this.binding, this.arguments, argumentTypes))
+		return null;
+	
+	if (!this.binding.isValidBinding()) {
+		if (this.binding instanceof ProblemMethodBinding
+			&& ((ProblemMethodBinding) this.binding).problemId() == ProblemReasons.NotVisible) {
+			if (this.evaluationContext.declaringTypeName != null) {
+				this.delegateThis = scope.getField(scope.enclosingSourceType(), EvaluationConstants.DELEGATE_THIS, this);
+				if (this.delegateThis == null){ // if not found then internal error, field should have been found
+					this.constant = Constant.NotAConstant;
+					scope.problemReporter().invalidMethod(this, this.binding);
+					return null;
+				}
+			} else {
+				this.constant = Constant.NotAConstant;
+				scope.problemReporter().invalidMethod(this, this.binding);
+				return null;
+			}
+			CodeSnippetScope localScope = new CodeSnippetScope(scope);
+			MethodBinding privateBinding =
+				this.receiver instanceof CodeSnippetThisReference && ((CodeSnippetThisReference) this.receiver).isImplicit
+					? localScope.getImplicitMethod((ReferenceBinding)this.delegateThis.type, this.selector, argumentTypes, this)
+					: localScope.getMethod(this.delegateThis.type, this.selector, argumentTypes, this);
+			if (!privateBinding.isValidBinding()) {
+				if (this.binding.declaringClass == null) {
+					if (this.actualReceiverType instanceof ReferenceBinding) {
+						this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
+					} else { // really bad error ....
+						scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+						return null;
+					}
+				}
+				scope.problemReporter().invalidMethod(this, this.binding);
+				return null;
+			} else {
+				this.binding = privateBinding;
+			}
+		} else {
+			if (this.binding.declaringClass == null) {
+				if (this.actualReceiverType instanceof ReferenceBinding) {
+					this.binding.declaringClass = (ReferenceBinding) this.actualReceiverType;
+				} else { // really bad error ....
+					scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
+					return null;
+				}
+			}
+			scope.problemReporter().invalidMethod(this, this.binding);
+			return null;
+		}
+	}
+	if (!this.binding.isStatic()) {
+		// the "receiver" must not be a type, in other words, a NameReference that the TC has bound to a Type
+		if (this.receiver instanceof NameReference
+				&& (((NameReference) this.receiver).bits & Binding.TYPE) != 0) {
+			scope.problemReporter().mustUseAStaticMethod(this, this.binding);
+		} else {
+			// handle indirect inheritance thru variable secondary bound
+			// receiver may receive generic cast, as part of implicit conversion
+			TypeBinding oldReceiverType = this.actualReceiverType;
+			this.actualReceiverType = this.actualReceiverType.getErasureCompatibleType(this.binding.declaringClass);
+			this.receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
+			if (this.actualReceiverType != oldReceiverType && this.receiver.postConversionType(scope) != this.actualReceiverType) { // record need for explicit cast at codegen since receiver could not handle it
+				this.bits |= NeedReceiverGenericCast;
+			}			
+		}
+	}
+	if (checkInvocationArguments(scope, this.receiver, this.actualReceiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
+		this.bits |= ASTNode.Unchecked;
+	}
+
+	//-------message send that are known to fail at compile time-----------
+	if (this.binding.isAbstract()) {
+		if (this.receiver.isSuper()) {
+			scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
+		}
+		// abstract private methods cannot occur nor abstract static............
+	}
+	if (isMethodUseDeprecated(this.binding, scope, true))
+		scope.problemReporter().deprecatedMethod(this.binding, this);
+
+	// from 1.5 compliance on, array#clone() returns the array type (but binding still shows Object)
+	if (this.actualReceiverType.isArrayType()
+			&& this.binding.parameters == Binding.NO_PARAMETERS
+			&& scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5
+			&& CharOperation.equals(this.binding.selector, CLONE)) {
+		this.resolvedType = this.actualReceiverType;
+	} else {
+		TypeBinding returnType = this.binding.returnType;
+		
+		if (returnType != null) {
+			if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
+				returnType = scope.environment().convertToRawType(returnType.erasure(), true);
+			}
+			returnType = returnType.capture(scope, this.sourceEnd);			
+		}
+		this.resolvedType = returnType;
+	}
+	return this.resolvedType;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
new file mode 100644
index 0000000..fc6df8d
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
@@ -0,0 +1,827 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+/**
+ * A parser for code snippets.
+ */
+public class CodeSnippetParser extends Parser implements EvaluationConstants {
+	int codeSnippetStart, codeSnippetEnd;
+	EvaluationContext evaluationContext;
+	boolean hasRecoveredOnExpression;
+	int lastStatement = -1; // end of last top level statement
+	int lineSeparatorLength;
+
+	int problemCountBeforeRecovery = 0;
+/**
+ * Creates a new code snippet parser.
+ */
+public CodeSnippetParser(ProblemReporter problemReporter, EvaluationContext evaluationContext, boolean optimizeStringLiterals, int codeSnippetStart, int codeSnippetEnd) {
+	super(problemReporter, optimizeStringLiterals);
+	this.codeSnippetStart = codeSnippetStart;
+	this.codeSnippetEnd = codeSnippetEnd;
+	this.evaluationContext = evaluationContext;
+	this.reportOnlyOneSyntaxError = true;
+	this.javadocParser.checkDocComment = false;
+}
+protected void classInstanceCreation(boolean alwaysQualified) {
+	// ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+
+	// ClassBodyopt produces a null item on the astStak if it produces NO class body
+	// An empty class body produces a 0 on the length stack.....
+
+	AllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+		//NO ClassBody
+		this.astPtr--;
+		if (alwaysQualified) {
+			alloc = new QualifiedAllocationExpression();
+		} else {
+			alloc = new CodeSnippetAllocationExpression(this.evaluationContext);
+		}
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
+		
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+	} else {
+		dispatchDeclarationInto(length);
+		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
+		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
+		if (anonymousTypeDeclaration.allocation != null) {
+			anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
+		}
+		this.astPtr--;
+		this.astLengthPtr--;
+	}
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	// ClassInstanceCreationExpression ::= 'new' TypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt
+	AllocationExpression alloc;
+	int length;
+	if (((length = this.astLengthStack[this.astLengthPtr--]) == 1)
+		&& (this.astStack[this.astPtr] == null)) {
+		//NO ClassBody
+		this.astPtr--;
+		alloc = new CodeSnippetAllocationExpression(this.evaluationContext);
+		alloc.sourceEnd = this.endPosition; //the position has been stored explicitly
+
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			this.expressionPtr -= length;
+			System.arraycopy(
+				this.expressionStack,
+				this.expressionPtr + 1,
+				alloc.arguments = new Expression[length],
+				0,
+				length);
+		}
+		alloc.type = getTypeReference(0);
+		rejectIllegalLeadingTypeAnnotations(alloc.type);
+
+		length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;
+
+		//the default constructor with the correct number of argument
+		//will be created and added by the TC (see createsInternalConstructorWithBinding)
+		alloc.sourceStart = this.intStack[this.intPtr--];
+		pushOnExpressionStack(alloc);
+	} else {
+		dispatchDeclarationInto(length);
+		TypeDeclaration anonymousTypeDeclaration = (TypeDeclaration)this.astStack[this.astPtr];
+		anonymousTypeDeclaration.declarationSourceEnd = this.endStatementPosition;
+		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
+		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
+			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
+		}
+		this.astPtr--;
+		this.astLengthPtr--;
+
+		QualifiedAllocationExpression allocationExpression = anonymousTypeDeclaration.allocation;
+		if (allocationExpression != null) {
+			allocationExpression.sourceEnd = this.endStatementPosition;
+			// handle type arguments
+			length = this.genericsLengthStack[this.genericsLengthPtr--];
+			this.genericsPtr -= length;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
+			allocationExpression.sourceStart = this.intStack[this.intPtr--];
+		}
+	}
+}
+protected void consumeClassDeclaration() {
+	super.consumeClassDeclaration();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeClassHeaderName1() {
+	// ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
+	TypeDeclaration typeDecl;
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+			typeDecl.bits |= ASTNode.IsMemberType;
+		} else {
+			typeDecl = new CodeSnippetTypeDeclaration(this.compilationUnit.compilationResult);
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+		typeDecl.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	typeDecl.sourceEnd = (int) pos;
+	typeDecl.sourceStart = (int) (pos >>> 32);
+	typeDecl.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--;
+	// 'class' and 'interface' push an int position
+	typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiers = this.intStack[this.intPtr--];
+	if (typeDecl.modifiersSourceStart >= 0) {
+		typeDecl.declarationSourceStart = typeDecl.modifiersSourceStart;
+	}
+	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
+	pushOnAstStack(typeDecl);
+
+	this.listLength = 0; // will be updated when reading super-interfaces
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = typeDecl.bodyStart;
+		this.currentElement = this.currentElement.add(typeDecl, 0);
+		this.lastIgnoredToken = -1;
+	}
+	// javadoc
+	typeDecl.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeEmptyStatement() {
+	super.consumeEmptyStatement();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeEnhancedForStatement() {
+	super.consumeEnhancedForStatement();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeExpressionStatement() {
+	super.consumeExpressionStatement();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	// FieldAccess ::= Primary '.' 'Identifier'
+	// FieldAccess ::= 'super' '.' 'Identifier'
+
+	FieldReference fr =
+		new CodeSnippetFieldReference(
+			this.identifierStack[this.identifierPtr],
+			this.identifierPositionStack[this.identifierPtr--],
+			this.evaluationContext);
+	this.identifierLengthPtr--;
+	if (isSuperAccess) {
+		//considerates the fieldReference beginning at the 'super' ....
+		fr.sourceStart = this.intStack[this.intPtr--];
+		problemReporter().codeSnippetMissingClass(null,0, 0);
+		fr.receiver = new CodeSnippetSuperReference(fr.sourceStart, this.endPosition);
+		pushOnExpressionStack(fr);
+	} else {
+		//optimize push/pop
+		if ((fr.receiver = this.expressionStack[this.expressionPtr]).isThis()) {
+			//fieldreference begins at the this
+			fr.sourceStart = fr.receiver.sourceStart;
+		}
+		this.expressionStack[this.expressionPtr] = fr;
+	}
+}
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
+protected void consumeLocalVariableDeclarationStatement() {
+	super.consumeLocalVariableDeclarationStatement();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+
+/**
+ * In case emulating local variables, wrap the (recovered) statements inside a
+ * try statement so as to achieve local state commiting (copy local vars back to fields).
+ * The CSToCuMapper could not be used, since it could have interfered with
+ * the syntax recovery specific to code snippets.
+ */
+protected void consumeMethodDeclaration(boolean isNotAbstract) {
+	// MethodDeclaration ::= MethodHeader MethodBody
+	// AbstractMethodDeclaration ::= MethodHeader ';'
+
+	super.consumeMethodDeclaration(isNotAbstract);
+
+	// now we know that we have a method declaration at the top of the ast stack
+	MethodDeclaration methodDecl = (MethodDeclaration) this.astStack[this.astPtr];
+
+	// automatically wrap the last statement inside a return statement, if it is an expression
+	// support have to be defined at toplevel only
+	if (isTopLevelType()) {
+		int last = methodDecl.statements == null ? -1 : methodDecl.statements.length - 1;
+		if (last >= 0 && methodDecl.statements[last] instanceof Expression){
+			Expression lastExpression = (Expression) methodDecl.statements[last];
+			methodDecl.statements[last] = new CodeSnippetReturnStatement(
+											lastExpression,
+											lastExpression.sourceStart,
+											lastExpression.sourceEnd);
+		}
+	}
+
+	int start = methodDecl.bodyStart-1, end = start;
+	long position = ((long)start << 32) + end;
+	long[] positions = new long[]{position};
+	if (this.evaluationContext.localVariableNames != null) {
+
+		int varCount = this.evaluationContext.localVariableNames.length; // n local decls+ try statement
+
+		// generate n local variable declarations: [type] [name] = val$[name];
+		Statement[] newStatements = new Statement[varCount+1];
+		for (int i = 0; i < varCount; i++){
+			char[] trimmedTypeName = this.evaluationContext.localVariableTypeNames[i];
+			int nameEnd = CharOperation.indexOf('[', trimmedTypeName);
+			if (nameEnd >= 0) {
+				trimmedTypeName = CharOperation.subarray(trimmedTypeName, 0, nameEnd);
+			}
+			nameEnd = CharOperation.indexOf(' ', trimmedTypeName);
+			if (nameEnd >= 0) {
+				trimmedTypeName = CharOperation.subarray(trimmedTypeName, 0, nameEnd);
+			}
+			TypeReference typeReference;
+			if (CharOperation.indexOf('.', trimmedTypeName) == -1) {
+				typeReference = new SingleTypeReference(trimmedTypeName, position);
+			} else {
+				typeReference = new QualifiedTypeReference(
+						CharOperation.splitOn('.', trimmedTypeName),
+						positions);
+			}
+			int dimCount = CharOperation.occurencesOf('[', this.evaluationContext.localVariableTypeNames[i]);
+			if (dimCount > 0) {
+				typeReference = copyDims(typeReference, dimCount);
+			}
+			NameReference init = new SingleNameReference(
+									CharOperation.concat(LOCAL_VAR_PREFIX, this.evaluationContext.localVariableNames[i]), position);
+			LocalDeclaration declaration = new LocalDeclaration(this.evaluationContext.localVariableNames[i], start, end);
+			declaration.initialization = init;
+			declaration.type = typeReference;
+			declaration.modifiers = this.evaluationContext.localVariableModifiers[i];
+			newStatements[i] = declaration;
+		}
+
+		// generate try { [snippet] } finally { [save locals to fields] }
+		// try block
+		TryStatement tryStatement = new TryStatement();
+		Block tryBlock = new Block(methodDecl.explicitDeclarations);
+		tryBlock.sourceStart = start;
+		tryBlock.sourceEnd = end;
+		tryBlock.statements = methodDecl.statements; // snippet statements
+		tryStatement.tryBlock = tryBlock;
+		// finally block
+		Block finallyBlock = new Block(0);
+		finallyBlock.sourceStart = start;
+		finallyBlock.sourceEnd = end;
+		finallyBlock.statements = new Statement[varCount];
+		for (int i = 0; i < varCount; i++){
+			SingleNameReference nameRef = new SingleNameReference(this.evaluationContext.localVariableNames[i], position);
+			finallyBlock.statements[i] = new Assignment(
+				new SingleNameReference(CharOperation.concat(LOCAL_VAR_PREFIX, this.evaluationContext.localVariableNames[i]), position),
+				nameRef,
+				nameRef.sourceEnd);
+		}
+		tryStatement.finallyBlock = finallyBlock;
+
+		newStatements[varCount] = tryStatement;
+		methodDecl.statements = newStatements;
+	}
+}
+
+protected void consumeMethodInvocationName() {
+	// MethodInvocation ::= Name '(' ArgumentListopt ')'
+
+	if (this.scanner.startPosition >= this.codeSnippetStart
+		&& this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
+		&& isTopLevelType()) {
+
+		// when the name is only an identifier...we have a message send to "this" (implicit)
+
+		MessageSend m = newMessageSend();
+		m.sourceEnd = this.rParenPos;
+		m.sourceStart =
+			(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+		m.selector = this.identifierStack[this.identifierPtr--];
+		if (this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+			m.receiver = new CodeSnippetThisReference(0,0,this.evaluationContext, true);
+			this.identifierLengthPtr--;
+		} else {
+			this.identifierLengthStack[this.identifierLengthPtr]--;
+			int length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--];
+			Annotation [] typeAnnotations;
+			if (length != 0) {
+				System.arraycopy(
+						this.typeAnnotationStack,
+						(this.typeAnnotationPtr -= length) + 1,
+						typeAnnotations = new Annotation[length],
+						0,
+						length);
+				problemReporter().misplacedTypeAnnotations(typeAnnotations[0], typeAnnotations[typeAnnotations.length - 1]);
+			}
+			m.receiver = getUnspecifiedReference();
+			m.sourceStart = m.receiver.sourceStart;
+		}
+		pushOnExpressionStack(m);
+	} else {
+		super.consumeMethodInvocationName();
+	}
+}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	// MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+	if (this.scanner.startPosition >= this.codeSnippetStart
+			&& this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
+			&& isTopLevelType()) {
+
+	
+		MessageSend m = newMessageSendWithTypeArguments();
+		m.sourceEnd = this.rParenPos;
+		m.sourceStart =
+			(int) ((m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr]) >>> 32);
+		m.selector = this.identifierStack[this.identifierPtr--];
+		this.identifierLengthPtr--;
+	
+		// handle type arguments
+		int length = this.genericsLengthStack[this.genericsLengthPtr--];
+		this.genericsPtr -= length;
+		System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+		this.intPtr--;
+	
+		m.receiver = getUnspecifiedReference();
+		m.sourceStart = m.receiver.sourceStart;
+		pushOnExpressionStack(m);
+	} else {
+		super.consumeMethodInvocationNameWithTypeArguments();
+	}
+}
+protected void consumeMethodInvocationSuper() {
+	// MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSend();
+	m.sourceStart = this.intStack[this.intPtr--];
+	m.sourceEnd = this.rParenPos;
+	m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition);
+	pushOnExpressionStack(m);
+}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	// MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+
+	MessageSend m = newMessageSendWithTypeArguments();
+	this.intPtr--; // start position of the typeArguments
+	m.sourceEnd = this.rParenPos;
+	m.nameSourcePosition = this.identifierPositionStack[this.identifierPtr];
+	m.selector = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	// handle type arguments
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, m.typeArguments = new TypeReference[length], 0, length);
+	m.sourceStart = this.intStack[this.intPtr--]; // start position of the super keyword
+
+	m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition);
+	pushOnExpressionStack(m);
+}
+protected void consumePrimaryNoNewArrayThis() {
+	// PrimaryNoNewArray ::= 'this'
+
+	if (this.scanner.startPosition >= this.codeSnippetStart
+		&& this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
+		&& isTopLevelType()) {
+		pushOnExpressionStack(
+			new CodeSnippetThisReference(this.intStack[this.intPtr--], this.endPosition, this.evaluationContext, false));
+	} else {
+		super.consumePrimaryNoNewArrayThis();
+	}
+}
+protected void consumeStatementBreak() {
+	super.consumeStatementBreak();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementBreakWithLabel() {
+	super.consumeStatementBreakWithLabel();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementCatch() {
+	super.consumeStatementCatch();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementContinue() {
+	super.consumeStatementContinue();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementContinueWithLabel() {
+	super.consumeStatementContinueWithLabel();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementDo() {
+	super.consumeStatementDo();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementFor() {
+	super.consumeStatementFor();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementIfNoElse() {
+	super.consumeStatementIfNoElse();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementIfWithElse() {
+	super.consumeStatementIfWithElse();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementLabel() {
+	super.consumeStatementLabel();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementReturn() {
+	// ReturnStatement ::= 'return' Expressionopt ';'
+
+	// returned value intercepted by code snippet
+	// support have to be defined at toplevel only
+	if ((this.hasRecoveredOnExpression
+			|| (this.scanner.startPosition >= this.codeSnippetStart && this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /* 14838*/))
+		&& this.expressionLengthStack[this.expressionLengthPtr] != 0
+		&& isTopLevelType()) {
+		this.expressionLengthPtr--;
+		Expression expression = this.expressionStack[this.expressionPtr--];
+		pushOnAstStack(
+			new CodeSnippetReturnStatement(
+				expression,
+				expression.sourceStart,
+				expression.sourceEnd));
+	} else {
+		super.consumeStatementReturn();
+	}
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementSwitch() {
+	super.consumeStatementSwitch();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementSynchronized() {
+	super.consumeStatementSynchronized();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementThrow() {
+	super.consumeStatementThrow();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementTry(boolean arg_0, boolean arg_1) {
+	super.consumeStatementTry(arg_0, arg_1);
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected void consumeStatementWhile() {
+	super.consumeStatementWhile();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+protected CompilationUnitDeclaration endParse(int act) {
+	if (this.hasRecoveredOnExpression) {
+		CompilationResult unitResult = this.compilationUnit.compilationResult;
+		if (act != ERROR_ACTION) { // expression recovery worked
+			// flush previously recorded problems
+			for (int i = 0; i < unitResult.problemCount; i++) {
+				unitResult.problems[i] = null; // discard problem
+			}
+			unitResult.problemCount = 0;
+			if (this.referenceContext instanceof AbstractMethodDeclaration) {
+				((AbstractMethodDeclaration)this.referenceContext).ignoreFurtherInvestigation = false;
+			}
+			if (this.referenceContext instanceof CompilationUnitDeclaration) {
+				((CompilationUnitDeclaration)this.referenceContext).ignoreFurtherInvestigation = false;
+			}
+
+			// consume expresion as a return statement
+			consumeStatementReturn();
+			int fieldsCount =
+				(this.evaluationContext.localVariableNames == null ? 0 : this.evaluationContext.localVariableNames.length)
+				+ (this.evaluationContext.declaringTypeName == null ? 0 : 1);
+			if (this.astPtr > (this.diet ? 0 : 2 + fieldsCount)) {
+					// in diet mode, the ast stack was empty when we went for method body
+					// otherwise it contained the type, the generated fields for local variables,
+					// the generated field for 'this' and the method
+				consumeBlockStatements();
+			}
+			consumeMethodBody();
+			if (!this.diet) {
+				consumeMethodDeclaration(true);
+				if (fieldsCount > 0) {
+					consumeClassBodyDeclarations();
+				}
+				consumeClassBodyDeclarationsopt();
+				consumeClassDeclaration();
+				consumeInternalCompilationUnitWithTypes();
+				consumeCompilationUnit();
+			}
+			this.lastAct = ACCEPT_ACTION;
+		} else {
+			// might have more than one error recorded:
+			// 1. during regular parse
+			// 2. during expression recovery
+			// -> must filter out one of them, the earliest one is less accurate
+			int maxRegularPos = 0, problemCount = unitResult.problemCount;
+			for (int i = 0; i < this.problemCountBeforeRecovery; i++) {
+				// skip unmatched bracket problems
+				if (unitResult.problems[i].getID() == IProblem.UnmatchedBracket) continue;
+
+				int start = unitResult.problems[i].getSourceStart();
+				if (start > maxRegularPos && start <= this.codeSnippetEnd) {
+					maxRegularPos = start;
+				}
+			}
+			int maxRecoveryPos = 0;
+			for (int i = this.problemCountBeforeRecovery; i < problemCount; i++) {
+				// skip unmatched bracket problems
+				if (unitResult.problems[i].getID() == IProblem.UnmatchedBracket) continue;
+
+				int start = unitResult.problems[i].getSourceStart();
+				if (start > maxRecoveryPos && start <= this.codeSnippetEnd) {
+					maxRecoveryPos = start;
+				}
+			}
+			if (maxRecoveryPos > maxRegularPos) {
+				System.arraycopy(unitResult.problems, this.problemCountBeforeRecovery, unitResult.problems, 0, problemCount - this.problemCountBeforeRecovery);
+				unitResult.problemCount -= this.problemCountBeforeRecovery;
+			} else {
+				unitResult.problemCount -= (problemCount - this.problemCountBeforeRecovery);
+			}
+			for (int i = unitResult.problemCount; i < problemCount; i++) {
+				unitResult.problems[i] = null; // discard problem
+			}
+
+		}
+	}
+	return super.endParse(act);
+}
+protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	/* build a (unspecified) NameReference which may be qualified*/
+	if (rejectTypeAnnotations) {
+		consumeNonTypeUseName();
+	}
+
+	if (this.scanner.startPosition >= this.codeSnippetStart
+		&& this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /*14838*/){
+		int length;
+		NameReference ref;
+		if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+			// single variable reference
+			ref =
+				new CodeSnippetSingleNameReference(
+					this.identifierStack[this.identifierPtr],
+					this.identifierPositionStack[this.identifierPtr--],
+					this.evaluationContext);
+		} else {
+			//Qualified variable reference
+			char[][] tokens = new char[length][];
+			this.identifierPtr -= length;
+			System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+			long[] positions = new long[length];
+			System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+			ref =
+				new CodeSnippetQualifiedNameReference(tokens,
+					positions,
+					(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+					(int) this.identifierPositionStack[this.identifierPtr + length],
+					this.evaluationContext); // sourceEnd
+		}
+		return ref;
+	} else {
+		return super.getUnspecifiedReference(rejectTypeAnnotations);
+	}
+}
+protected NameReference getUnspecifiedReferenceOptimized() {
+	/* build a (unspecified) NameReference which may be qualified
+	The optimization occurs for qualified reference while we are
+	certain in this case the last item of the qualified name is
+	a field access. This optimization is IMPORTANT while it results
+	that when a NameReference is build, the type checker should always
+	look for that it is not a type reference */
+	consumeNonTypeUseName();
+
+	if (this.scanner.startPosition >= this.codeSnippetStart
+		&& this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /*14838*/){
+		int length;
+		NameReference ref;
+		if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+			// single variable reference
+			ref =
+				new CodeSnippetSingleNameReference(
+					this.identifierStack[this.identifierPtr],
+					this.identifierPositionStack[this.identifierPtr--],
+					this.evaluationContext);
+			ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+			ref.bits |= Binding.LOCAL | Binding.FIELD;
+			return ref;
+		}
+
+		//Qualified-variable-reference
+		//In fact it is variable-reference DOT field-ref , but it would result in a type
+		//conflict tha can be only reduce by making a superclass (or inetrface ) between
+		//nameReference and FiledReference or putting FieldReference under NameReference
+		//or else..........This optimisation is not really relevant so just leave as it is
+
+		char[][] tokens = new char[length][];
+		this.identifierPtr -= length;
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+		long[] positions = new long[length];
+		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+		ref = new CodeSnippetQualifiedNameReference(
+				tokens,
+				positions,
+				(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+				(int) this.identifierPositionStack[this.identifierPtr + length],
+				this.evaluationContext); // sourceEnd
+		ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+		ref.bits |= Binding.LOCAL | Binding.FIELD;
+		return ref;
+	} else {
+		return super.getUnspecifiedReferenceOptimized();
+	}
+}
+protected void ignoreExpressionAssignment() {
+	super.ignoreExpressionAssignment();
+	/* recovery */
+	recordLastStatementIfNeeded();
+}
+/**
+ * Returns whether we are parsing a top level type or not.
+ */
+private boolean isTopLevelType() {
+	return this.nestedType == (this.diet ? 0 : 1);
+}
+protected MessageSend newMessageSend() {
+	// '(' ArgumentListopt ')'
+	// the arguments are on the expression stack
+
+	CodeSnippetMessageSend m = new CodeSnippetMessageSend(this.evaluationContext);
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			m.arguments = new Expression[length],
+			0,
+			length);
+	}
+	return m;
+}
+protected MessageSend newMessageSendWithTypeArguments() {
+	// '(' ArgumentListopt ')'
+	// the arguments are on the expression stack
+	CodeSnippetMessageSend m = new CodeSnippetMessageSend(this.evaluationContext);
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			m.arguments = new Expression[length],
+			0,
+			length);
+	}
+	return m;
+}
+/**
+ * Records the scanner position if we're parsing a top level type.
+ */
+private void recordLastStatementIfNeeded() {
+	if ((isTopLevelType()) && (this.scanner.startPosition <= this.codeSnippetEnd+this.lineSeparatorLength /*14838*/)) {
+		this.lastStatement = this.scanner.startPosition;
+	}
+}
+
+protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) {
+	if (!isDietParse) {
+		this.scanner.initialPosition = this.lastStatement;
+		this.scanner.eofPosition = this.codeSnippetEnd + 1; // stop after expression
+		oldFirstToken = TokenNameTWIDDLE;//TokenNameREMAINDER; // first token of th expression parse
+	}
+	super.reportSyntaxErrors(isDietParse, oldFirstToken);
+}
+/*
+ * A syntax error was detected. If a method is being parsed, records the number of errors and
+ * attempts to restart from the last statement by going for an expression.
+ */
+protected boolean resumeOnSyntaxError() {
+	if (this.diet || this.hasRecoveredOnExpression) { // no reentering inside expression recovery
+		return false;
+	}
+
+	// record previous error, in case more accurate than potential one in expression recovery
+	// e.g. "return foo(a a); 1+3"
+	this.problemCountBeforeRecovery = this.compilationUnit.compilationResult.problemCount;
+
+	// reposition for expression parsing
+	if (this.lastStatement < 0) {
+		this.lastStatement = this.codeSnippetStart; // no statement reduced prior to error point
+	}
+	this.scanner.initialPosition = this.lastStatement;
+	this.scanner.startPosition = this.lastStatement;
+	this.scanner.currentPosition = this.lastStatement;
+	this.scanner.eofPosition = this.codeSnippetEnd < Integer.MAX_VALUE ? this.codeSnippetEnd + 1 : this.codeSnippetEnd; // stop after expression
+	this.scanner.commentPtr = -1;
+
+	// reset stacks in consistent state
+	this.expressionPtr = -1;
+	this.typeAnnotationLengthPtr = -1;
+	this.typeAnnotationPtr = -1;
+	this.identifierPtr = -1;
+	this.identifierLengthPtr = -1;
+
+	// go for the expression
+	goForExpression(true /* record line separators */);
+	this.hasRecoveredOnExpression = true;
+	this.hasReportedError = false;
+	this.hasError = false;
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
new file mode 100644
index 0000000..9e15270
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
@@ -0,0 +1,599 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+public class CodeSnippetQualifiedNameReference extends QualifiedNameReference implements EvaluationConstants, ProblemReasons {
+
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+/**
+ * CodeSnippetQualifiedNameReference constructor comment.
+ * @param sources char[][]
+ * @param sourceStart int
+ * @param sourceEnd int
+ */
+public CodeSnippetQualifiedNameReference(char[][] sources, long[] positions, int sourceStart, int sourceEnd, EvaluationContext evaluationContext) {
+	super(sources, positions, sourceStart, sourceEnd);
+	this.evaluationContext = evaluationContext;
+}
+
+/**
+ * Check and/or redirect the field access to the delegate receiver if any
+ */
+public TypeBinding checkFieldAccess(BlockScope scope) {
+	FieldBinding fieldBinding = (FieldBinding) this.binding;
+	MethodScope methodScope = scope.methodScope();
+	TypeBinding declaringClass = fieldBinding.original().declaringClass;
+	// check for forward references
+	if ((this.indexOfFirstFieldBinding == 1 || declaringClass.isEnum())
+			&& methodScope.enclosingSourceType() == declaringClass
+			&& methodScope.lastVisibleFieldID >= 0
+			&& fieldBinding.id >= methodScope.lastVisibleFieldID
+			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
+		scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding-1, fieldBinding);
+	}
+	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
+	this.bits |= Binding.FIELD;
+	return getOtherFieldBindings(scope);
+}
+
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if ((this.bits & Binding.VARIABLE) == 0) { // nothing to do if type ref
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+		return;
+	}
+	FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
+	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
+		super.generateCode(currentScope, codeStream, valueRequired);
+		return;
+	}
+	lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	if (lastFieldBinding != null) {
+		boolean isStatic = lastFieldBinding.isStatic();
+		Constant fieldConstant = lastFieldBinding.constant();
+		if (fieldConstant != Constant.NotAConstant) {
+			if (!isStatic){
+				codeStream.invokeObjectGetClass();
+				codeStream.pop();
+			}
+			if (valueRequired) { // inline the last field constant
+				codeStream.generateConstant(fieldConstant, this.implicitConversion);
+			}
+		} else {
+			boolean isFirst = lastFieldBinding == this.binding
+											&& (this.indexOfFirstFieldBinding == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
+											&& this.otherBindings == null; // could be dup: next.next.next
+			TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
+			if (valueRequired
+					|| (!isFirst && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+					|| ((this.implicitConversion & TypeIds.UNBOXING) != 0)
+					|| requiredGenericCast != null) {
+				int lastFieldPc = codeStream.position;
+				if (lastFieldBinding.declaringClass == null) { // array length
+					codeStream.arraylength();
+					if (valueRequired) {
+						codeStream.generateImplicitConversion(this.implicitConversion);
+					} else {
+						// could occur if !valueRequired but compliance >= 1.4
+						codeStream.pop();
+					}
+				} else {
+					codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+					if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
+					if (valueRequired) {
+						codeStream.generateImplicitConversion(this.implicitConversion);
+					} else {
+						boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
+						// conversion only generated if unboxing
+						if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
+						switch (isUnboxing ? postConversionType(currentScope).id : lastFieldBinding.type.id) {
+							case T_long :
+							case T_double :
+								codeStream.pop2();
+								break;
+							default :
+								codeStream.pop();
+						}
+					}
+				}
+
+				int fieldPosition = (int) (this.sourcePositions[this.sourcePositions.length - 1] >>> 32);
+				codeStream.recordPositionsFrom(lastFieldPc, fieldPosition);
+			} else {
+				if (!isStatic){
+					codeStream.invokeObjectGetClass(); // perform null check
+					codeStream.pop();
+				}
+			}
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+/**
+ * Check and/or redirect the field access to the delegate receiver if any
+ */
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
+	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
+		super.generateAssignment(currentScope, codeStream, assignment, valueRequired);
+		return;
+	}
+	lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	codeStream.generateEmulationForField(lastFieldBinding);
+	codeStream.swap();
+	assignment.expression.generateCode(currentScope, codeStream, true);
+	if (valueRequired) {
+		switch (lastFieldBinding.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2_x2();
+				break;
+			default :
+				codeStream.dup_x2();
+			break;	
+		}		
+	}
+	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+	if (valueRequired) {
+		codeStream.generateImplicitConversion(assignment.implicitConversion);
+	}
+}
+
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
+	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
+		super.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
+		return;
+	}
+	lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	if (lastFieldBinding.isStatic()){
+		codeStream.generateEmulationForField(lastFieldBinding);
+		codeStream.swap();
+		codeStream.aconst_null();
+		codeStream.swap();
+		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	} else {
+		codeStream.generateEmulationForField(lastFieldBinding);
+		codeStream.swap();
+		codeStream.dup();
+
+		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	}
+	// the last field access is a write access
+	// perform the actual compound operation
+	int operationTypeID;
+	if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
+		codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+	} else {
+		// promote the array reference to the suitable operation type
+		codeStream.generateImplicitConversion(this.implicitConversion);
+		// generate the increment value (will by itself  be promoted to the operation value)
+		if (expression == IntLiteral.One){ // prefix operation
+			codeStream.generateConstant(expression.constant, this.implicitConversion);
+		} else {
+			expression.generateCode(currentScope, codeStream, true);
+		}
+		// perform the operation
+		codeStream.sendOperator(operator, operationTypeID);
+		// cast the value back to the array reference type
+		codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// actual assignment
+
+	// current stack is:
+	// field receiver value
+	if (valueRequired) {
+		switch (lastFieldBinding.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2_x2();
+				break;
+			default :
+				codeStream.dup_x2();
+			break;	
+		}
+	}
+	// current stack is:
+	// value field receiver value
+	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
+	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
+		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
+		return;
+	}
+	lastFieldBinding = generateReadSequence(currentScope, codeStream);
+	codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+	if (valueRequired) {
+		switch (lastFieldBinding.type.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.dup2();
+				break;
+			default :
+				codeStream.dup();
+			break;	
+		}		
+	}
+	codeStream.generateEmulationForField(lastFieldBinding);
+	if ((lastFieldBinding.type == TypeBinding.LONG) || (lastFieldBinding.type == TypeBinding.DOUBLE)) {
+		codeStream.dup_x2();
+		codeStream.pop();
+		if (lastFieldBinding.isStatic()) {
+			codeStream.aconst_null();
+		} else {
+			generateReadSequence(currentScope, codeStream);
+		}
+		codeStream.dup_x2();
+		codeStream.pop();
+	} else {
+		codeStream.dup_x1();
+		codeStream.pop();
+		if (lastFieldBinding.isStatic()) {
+			codeStream.aconst_null();
+		} else {
+			generateReadSequence(currentScope, codeStream);
+		}
+		codeStream.dup_x1();
+		codeStream.pop();
+	}
+	codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+	codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
+	codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
+}
+
+/*
+ * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
+ * for a read or write access.
+ */
+public FieldBinding generateReadSequence(BlockScope currentScope, CodeStream codeStream) {
+	// determine the rank until which we now we do not need any actual value for the field access
+	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
+	boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
+	FieldBinding lastFieldBinding;
+	TypeBinding lastGenericCast;
+	TypeBinding lastReceiverType;
+	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
+	
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD :
+			lastFieldBinding = ((FieldBinding) this.binding).original();
+			lastGenericCast = this.genericCast;
+			lastReceiverType = this.actualReceiverType;
+			// if first field is actually constant, we can inline it
+			if (lastFieldBinding.constant() != Constant.NotAConstant) {
+				break;
+			}
+			if (needValue) {
+				if (lastFieldBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
+					if (!lastFieldBinding.isStatic()) {
+						if ((this.bits & DepthMASK) != 0) {
+							ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
+							Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+							codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+						} else {
+							generateReceiver(codeStream);
+						}
+					}
+				} else {
+					if (!lastFieldBinding.isStatic()) {
+						if ((this.bits & DepthMASK) != 0) {
+							// internal error, per construction we should have found it
+							// not yet supported
+							currentScope.problemReporter().needImplementation(this);
+						} else {
+							generateReceiver(codeStream);
+						}
+					} else {
+						codeStream.aconst_null();
+					}
+				}
+			}
+			break;
+		case Binding.LOCAL : // reading the first local variable
+			lastFieldBinding = null;
+			lastGenericCast = null;
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			lastReceiverType = localBinding.type;
+			if (!needValue) break; // no value needed
+			// regular local variable read
+			Constant localConstant = localBinding.constant();
+			if (localConstant != Constant.NotAConstant) {
+				codeStream.generateConstant(localConstant, 0);
+				// no implicit conversion
+			} else {
+				// outer local?
+				if ((this.bits & IsCapturedOuterLocal) != 0) {
+					checkEffectiveFinality(localBinding, currentScope);
+					// outer local can be reached either through a synthetic arg or a synthetic field
+					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+					codeStream.generateOuterAccess(path, this, localBinding, currentScope);
+				} else {
+					codeStream.load(localBinding);
+				}
+			}
+			break;
+		default : // should not occur
+			return null;			
+	}
+	// all intermediate field accesses are read accesses
+	// only the last field binding is a write access
+	int positionsLength = this.sourcePositions.length;
+	FieldBinding initialFieldBinding = lastFieldBinding; // can be null if initial was a local binding
+	if (this.otherBindings != null) {
+		for (int i = 0; i < otherBindingsCount; i++) {
+			int pc = codeStream.position;
+			FieldBinding nextField = this.otherBindings[i].original();
+			TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
+			if (lastFieldBinding != null) {
+				needValue = !nextField.isStatic();
+				Constant fieldConstant = lastFieldBinding.constant();
+				if (fieldConstant != Constant.NotAConstant) {
+					if (i > 0 && !lastFieldBinding.isStatic()) {
+						codeStream.invokeObjectGetClass(); // perform null check
+						codeStream.pop();
+					}
+					if (needValue) {
+						codeStream.generateConstant(fieldConstant, 0);
+					}
+				} else {
+					if (needValue || (i > 0 && complyTo14) || lastGenericCast != null) {
+						if (lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
+							MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
+							if (accessor == null) {
+								TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
+								if (lastFieldBinding.isStatic()) {
+									codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+								} else {
+									codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
+								}
+							} else {
+								codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+							}
+						} else {
+							codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+						}
+						if (lastGenericCast != null) {
+							codeStream.checkcast(lastGenericCast);
+							lastReceiverType = lastGenericCast;
+						} else {
+							lastReceiverType = lastFieldBinding.type;
+						}
+						if (!needValue) codeStream.pop();
+					} else {
+						if (lastFieldBinding == initialFieldBinding) {
+							if (lastFieldBinding.isStatic()){
+								// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
+								if (initialFieldBinding.declaringClass != this.actualReceiverType.erasure()) {
+									if (lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
+										MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
+										if (accessor == null) {
+											TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
+											codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
+										} else {
+											codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
+										}
+									} else {
+										codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
+									}
+									codeStream.pop();
+								}
+							}
+						} else if (!lastFieldBinding.isStatic()){
+							codeStream.invokeObjectGetClass(); // perform null check
+							codeStream.pop();
+						}
+						lastReceiverType = lastFieldBinding.type;
+					}
+					if ((positionsLength - otherBindingsCount + i - 1) >= 0) {
+						int fieldPosition = (int) (this.sourcePositions[positionsLength - otherBindingsCount + i - 1] >>>32);
+						codeStream.recordPositionsFrom(pc, fieldPosition);
+					}
+				}
+			}
+			lastFieldBinding = nextField;
+			lastGenericCast = nextGenericCast;
+			if (lastFieldBinding != null && !lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
+				if (lastFieldBinding.isStatic()) {
+					codeStream.aconst_null();
+				}
+			}			
+		}
+	}
+	return lastFieldBinding;	
+}
+
+
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+	if (this.delegateThis != null) {
+		codeStream.fieldAccess(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegated field access
+	}
+}
+
+public TypeBinding getOtherFieldBindings(BlockScope scope) {
+	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
+	int length = this.tokens.length;
+	if ((this.bits & Binding.FIELD) != 0) {
+		if (!((FieldBinding) this.binding).isStatic()) { //must check for the static status....
+			if (this.indexOfFirstFieldBinding == 1) {
+				//the field is the first token of the qualified reference....
+				if (scope.methodScope().isStatic) {
+					scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
+					return null;
+				}
+			} else { //accessing to a field using a type as "receiver" is allowed only with static field
+				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
+				return null;
+			}
+		}
+		// only last field is actually a write access if any
+		if (isFieldUseDeprecated((FieldBinding) this.binding, scope, this.indexOfFirstFieldBinding == length ? this.bits : 0)) {
+			scope.problemReporter().deprecatedField((FieldBinding) this.binding, this);
+		}
+	}
+
+	TypeBinding type = ((VariableBinding) this.binding).type;
+	int index = this.indexOfFirstFieldBinding;
+	if (index == length) { //	restrictiveFlag == FIELD
+		this.constant = ((FieldBinding) this.binding).constant();
+		return type;
+	}
+
+	// allocation of the fieldBindings array	and its respective constants
+	int otherBindingsLength = length - index;
+	this.otherBindings = new FieldBinding[otherBindingsLength];
+
+	// fill the first constant (the one of the binding)
+	this.constant =((VariableBinding) this.binding).constant();
+
+	// iteration on each field
+	while (index < length) {
+		char[] token = this.tokens[index];
+		if (type == null) return null; // could not resolve type prior to this point
+		FieldBinding field = scope.getField(type, token, this);
+		int place = index - this.indexOfFirstFieldBinding;
+		this.otherBindings[place] = field;
+		if (!field.isValidBinding()) {
+			// try to retrieve the field as private field
+			CodeSnippetScope localScope = new CodeSnippetScope(scope);
+			if (this.delegateThis == null) {
+				if (this.evaluationContext.declaringTypeName != null) {
+					this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+					if (this.delegateThis == null){  // if not found then internal error, field should have been found
+						return super.reportError(scope);
+					}
+					this.actualReceiverType = this.delegateThis.type;
+				} else {
+					this.constant = Constant.NotAConstant; //don't fill other constants slots...
+					scope.problemReporter().invalidField(this, field, index, type);
+					return null;
+				}
+			}
+			field = localScope.getFieldForCodeSnippet(this.delegateThis.type, token, this);
+			this.otherBindings[place] = field;
+		}
+		if (field.isValidBinding()) {
+			// only last field is actually a write access if any
+			if (isFieldUseDeprecated(field, scope, index+1 == length ? this.bits : 0)) {
+				scope.problemReporter().deprecatedField(field, this);
+			}
+			// constant propagation can only be performed as long as the previous one is a constant too.
+			if (this.constant != Constant.NotAConstant){
+				this.constant = field.constant();
+			}
+			type = field.type;
+			index++;
+		} else {
+			this.constant = Constant.NotAConstant; //don't fill other constants slots...
+			scope.problemReporter().invalidField(this, field, index, type);
+			return null;
+		}
+	}
+	return (this.otherBindings[otherBindingsLength - 1]).type;
+}
+
+/**
+ * index is <0 to denote write access emulation
+ */
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
+	// do nothing
+}
+
+/**
+ * Normal field binding did not work, try to bind to a field of the delegate receiver.
+ */
+public TypeBinding reportError(BlockScope scope) {
+	if (this.evaluationContext.declaringTypeName != null) {
+		this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+		if (this.delegateThis == null){  // if not found then internal error, field should have been found
+			return super.reportError(scope);
+		}
+		this.actualReceiverType = this.delegateThis.type;
+	} else {
+		return super.reportError(scope);
+	}
+
+	if ((this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotFound)
+		|| (this.binding instanceof ProblemBinding && ((ProblemBinding) this.binding).problemId() == NotFound)){
+		// will not support innerclass emulation inside delegate
+		FieldBinding fieldBinding = scope.getField(this.delegateThis.type, this.tokens[0], this);
+		if (!fieldBinding.isValidBinding()) {
+			if (((ProblemFieldBinding) fieldBinding).problemId() == NotVisible) {
+				// manage the access to a private field of the enclosing type
+				CodeSnippetScope localScope = new CodeSnippetScope(scope);
+				this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.tokens[0], this);
+				if (this.binding.isValidBinding()) {
+					return checkFieldAccess(scope);
+				} else {
+					return super.reportError(scope);
+				}
+			} else {
+				return super.reportError(scope);
+			}
+		}
+		this.binding = fieldBinding;
+		return checkFieldAccess(scope);
+	}
+
+	TypeBinding result;
+	if (this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotVisible) {
+		// field and/or local are done before type lookups
+		// the only available value for the restrictiveFlag BEFORE
+		// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField
+		CodeSnippetScope localScope = new CodeSnippetScope(scope);
+		if ((this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) {
+			this.bits &= ~RestrictiveFlagMASK; // clear bits
+			this.bits |= Binding.FIELD;
+			result = getOtherFieldBindings(scope);
+		} else {
+			return super.reportError(scope);
+		}
+		if (result != null && result.isValidBinding()) {
+			return result;
+		}
+	}
+	return super.reportError(scope);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
new file mode 100644
index 0000000..6daf04e
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/**
+ * A return statement inside a code snippet. During the code gen,
+ * it uses a macro to set the result of the code snippet instead
+ * of returning it.
+ */
+public class CodeSnippetReturnStatement extends ReturnStatement implements InvocationSite, EvaluationConstants {
+	MethodBinding setResultMethod;
+public CodeSnippetReturnStatement(Expression expr, int s, int e) {
+	super(expr, s, e);
+}
+
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+	FlowInfo info = super.analyseCode(currentScope, flowContext, flowInfo);
+	// we need to remove this optimization in order to prevent the inlining of the return bytecode
+	// 1GH0AU7: ITPJCORE:ALL - Eval - VerifyError in scrapbook page
+	this.expression.bits &= ~IsReturnedValue;
+	return info;
+}
+
+/**
+ * Dump the suitable return bytecode for a return statement
+ *
+ */
+public void generateReturnBytecode(CodeStream codeStream) {
+
+	// output the return bytecode
+	codeStream.return_();
+}
+public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
+
+	// push receiver
+	codeStream.aload_0();
+
+	// push the 2 parameters of "setResult(Object, Class)"
+	if (this.expression == null || this.expression.resolvedType == TypeBinding.VOID) { // expressionType == VoidBinding if code snippet is the expression "System.out.println()"
+		// push null
+		codeStream.aconst_null();
+
+		// void.class
+		codeStream.generateClassLiteralAccessForType(TypeBinding.VOID, null);
+	} else {
+		// swap with expression
+		int valueTypeID = this.expression.resolvedType.id;
+		if (valueTypeID == T_long || valueTypeID == T_double) {
+			codeStream.dup_x2();
+			codeStream.pop();
+		} else {
+			codeStream.swap();
+		}
+
+		// generate wrapper if needed
+		if (this.expression.resolvedType.isBaseType() && this.expression.resolvedType != TypeBinding.NULL) {
+			codeStream.generateBoxingConversion(this.expression.resolvedType.id);
+		}
+
+		// generate the expression type
+		codeStream.generateClassLiteralAccessForType(this.expression.resolvedType, null);
+	}
+
+	// generate the invoke virtual to "setResult(Object,Class)"
+	codeStream.invoke(Opcodes.OPC_invokevirtual, this.setResultMethod, null /* default declaringClass */);
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return null;
+}
+public boolean isSuperAccess() {
+	return false;
+}
+public boolean isTypeAccess() {
+	return false;
+}
+public boolean needValue(){
+	return true;
+}
+public void prepareSaveValueLocation(TryStatement targetTryStatement){
+
+	// do nothing: no storage is necessary for snippets
+}
+public void resolve(BlockScope scope) {
+	if (this.expression != null) {
+		if (this.expression.resolveType(scope) != null) {
+			TypeBinding javaLangClass = scope.getJavaLangClass();
+			if (!javaLangClass.isValidBinding()) {
+				scope.problemReporter().codeSnippetMissingClass("java.lang.Class", this.sourceStart, this.sourceEnd); //$NON-NLS-1$
+				return;
+			}
+			TypeBinding javaLangObject = scope.getJavaLangObject();
+			if (!javaLangObject.isValidBinding()) {
+				scope.problemReporter().codeSnippetMissingClass("java.lang.Object", this.sourceStart, this.sourceEnd); //$NON-NLS-1$
+				return;
+			}
+			TypeBinding[] argumentTypes = new TypeBinding[] {javaLangObject, javaLangClass};
+			this.setResultMethod = scope.getImplicitMethod(SETRESULT_SELECTOR, argumentTypes, this);
+			if (!this.setResultMethod.isValidBinding()) {
+				scope.problemReporter().codeSnippetMissingMethod(ROOT_FULL_CLASS_NAME, new String(SETRESULT_SELECTOR), new String(SETRESULT_ARGUMENTS), this.sourceStart, this.sourceEnd);
+				return;
+			}
+			// in constant case, the implicit conversion cannot be left uninitialized
+			if (this.expression.constant != Constant.NotAConstant) {
+				// fake 'no implicit conversion' (the return type is always void)
+				this.expression.implicitConversion = this.expression.constant.typeID() << 4;
+			}
+		}
+	}
+}
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	// ignored
+}
+public void setDepth(int depth) {
+	// ignored
+}
+public void setFieldIndex(int depth) {
+	// ignored
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
new file mode 100644
index 0000000..9d96645
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller <jesper@selskabet.org> - Contributions for
+ *								bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+
+/**
+ * This scope is used for code snippet lookup to emulate private, protected and default access.
+ * These accesses inside inner classes are not managed yet.
+ */
+public class CodeSnippetScope extends BlockScope {
+/**
+ * CodeSnippetScope constructor comment.
+ * @param kind int
+ * @param parent org.eclipse.jdt.internal.compiler.lookup.Scope
+ */
+protected CodeSnippetScope(int kind, Scope parent) {
+	super(kind, parent);
+}
+/**
+ * CodeSnippetScope constructor comment.
+ * @param parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ */
+public CodeSnippetScope(BlockScope parent) {
+	super(parent);
+}
+/**
+ * CodeSnippetScope constructor comment.
+ * @param parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
+ * @param variableCount int
+ */
+public CodeSnippetScope(BlockScope parent, int variableCount) {
+	super(parent, variableCount);
+}
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+
+public final boolean canBeSeenByForCodeSnippet(FieldBinding fieldBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+	if (fieldBinding.isPublic()) return true;
+
+	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
+	if (invocationType == fieldBinding.declaringClass) return true;
+
+	if (fieldBinding.isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the receiverType is the invocationType or its subclass
+		//    OR the field is a static field accessed directly through a type
+		if (invocationType == fieldBinding.declaringClass) return true;
+		if (invocationType.fPackage == fieldBinding.declaringClass.fPackage) return true;
+		if (fieldBinding.declaringClass.isSuperclassOf(invocationType)) {
+			if (invocationSite.isSuperAccess()) return true;
+			// receiverType can be an array binding in one case... see if you can change it
+			if (receiverType instanceof ArrayBinding)
+				return false;
+			if (invocationType.isSuperclassOf((ReferenceBinding) receiverType))
+				return true;
+			if (fieldBinding.isStatic())
+				return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
+		}
+		return false;
+	}
+
+	if (fieldBinding.isPrivate()) {
+		// answer true if the receiverType is the declaringClass
+		// AND the invocationType and the declaringClass have a common enclosingType
+		if (receiverType != fieldBinding.declaringClass) return false;
+
+		if (invocationType != fieldBinding.declaringClass) {
+			ReferenceBinding outerInvocationType = invocationType;
+			ReferenceBinding temp = outerInvocationType.enclosingType();
+			while (temp != null) {
+				outerInvocationType = temp;
+				temp = temp.enclosingType();
+			}
+
+			ReferenceBinding outerDeclaringClass = fieldBinding.declaringClass;
+			temp = outerDeclaringClass.enclosingType();
+			while (temp != null) {
+				outerDeclaringClass = temp;
+				temp = temp.enclosingType();
+			}
+			if (outerInvocationType != outerDeclaringClass) return false;
+		}
+		return true;
+	}
+
+	// isDefault()
+	if (invocationType.fPackage != fieldBinding.declaringClass.fPackage) return false;
+
+	// receiverType can be an array binding in one case... see if you can change it
+	if (receiverType instanceof ArrayBinding)
+		return false;
+	ReferenceBinding type = (ReferenceBinding) receiverType;
+	PackageBinding declaringPackage = fieldBinding.declaringClass.fPackage;
+	TypeBinding originalDeclaringClass = fieldBinding.declaringClass .original();
+	do {
+		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
+			if (originalDeclaringClass == type.erasure().original()) return true;	
+		} else {
+			if (originalDeclaringClass == type.original()) return true;
+		}
+		if (declaringPackage != type.fPackage) return false;
+	} while ((type = type.superclass()) != null);
+	return false;
+}
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+public final boolean canBeSeenByForCodeSnippet(MethodBinding methodBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+	if (methodBinding.isPublic()) return true;
+
+	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
+	if (invocationType == methodBinding.declaringClass) return true;
+
+	if (methodBinding.isProtected()) {
+		// answer true if the invocationType is the declaringClass or they are in the same package
+		// OR the invocationType is a subclass of the declaringClass
+		//    AND the receiverType is the invocationType or its subclass
+		//    OR the method is a static method accessed directly through a type
+		if (invocationType == methodBinding.declaringClass) return true;
+		if (invocationType.fPackage == methodBinding.declaringClass.fPackage) return true;
+		if (methodBinding.declaringClass.isSuperclassOf(invocationType)) {
+			if (invocationSite.isSuperAccess()) return true;
+			// receiverType can be an array binding in one case... see if you can change it
+			if (receiverType instanceof ArrayBinding)
+				return false;
+			if (invocationType.isSuperclassOf((ReferenceBinding) receiverType))
+				return true;
+			if (methodBinding.isStatic())
+				return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
+		}
+		return false;
+	}
+
+	if (methodBinding.isPrivate()) {
+		// answer true if the receiverType is the declaringClass
+		// AND the invocationType and the declaringClass have a common enclosingType
+		if (receiverType != methodBinding.declaringClass) return false;
+
+		if (invocationType != methodBinding.declaringClass) {
+			ReferenceBinding outerInvocationType = invocationType;
+			ReferenceBinding temp = outerInvocationType.enclosingType();
+			while (temp != null) {
+				outerInvocationType = temp;
+				temp = temp.enclosingType();
+			}
+
+			ReferenceBinding outerDeclaringClass = methodBinding.declaringClass;
+			temp = outerDeclaringClass.enclosingType();
+			while (temp != null) {
+				outerDeclaringClass = temp;
+				temp = temp.enclosingType();
+			}
+			if (outerInvocationType != outerDeclaringClass) return false;
+		}
+		return true;
+	}
+
+	// isDefault()
+	if (invocationType.fPackage != methodBinding.declaringClass.fPackage) return false;
+
+	// receiverType can be an array binding in one case... see if you can change it
+	if (receiverType instanceof ArrayBinding)
+		return false;
+	ReferenceBinding type = (ReferenceBinding) receiverType;
+	PackageBinding declaringPackage = methodBinding.declaringClass.fPackage;
+	TypeBinding originalDeclaringClass = methodBinding.declaringClass .original();
+	do {
+		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
+			if (originalDeclaringClass == type.erasure().original()) return true;
+		} else {
+			if (originalDeclaringClass == type.original()) return true;
+		}
+		if (declaringPackage != type.fPackage) return false;
+	} while ((type = type.superclass()) != null);
+	return false;
+}
+/* Answer true if the receiver is visible to the type provided by the scope.
+* InvocationSite implements isSuperAccess() to provide additional information
+* if the receiver is protected.
+*
+* NOTE: Cannot invoke this method with a compilation unit scope.
+*/
+
+public final boolean canBeSeenByForCodeSnippet(ReferenceBinding referenceBinding, ReferenceBinding receiverType) {
+	if (referenceBinding.isPublic()) return true;
+
+	if (receiverType == referenceBinding) return true;
+
+	if (referenceBinding.isProtected()) {
+		// answer true if the receiver (or its enclosing type) is the superclass
+		//	of the receiverType or in the same package
+		return receiverType.fPackage == referenceBinding.fPackage
+				|| referenceBinding.isSuperclassOf(receiverType)
+				|| referenceBinding.enclosingType().isSuperclassOf(receiverType); // protected types always have an enclosing one
+	}
+
+	if (referenceBinding.isPrivate()) {
+		// answer true if the receiver and the receiverType have a common enclosingType
+		// already know they are not the identical type
+		ReferenceBinding outerInvocationType = receiverType;
+		ReferenceBinding temp = outerInvocationType.enclosingType();
+		while (temp != null) {
+			outerInvocationType = temp;
+			temp = temp.enclosingType();
+		}
+
+		ReferenceBinding outerDeclaringClass = referenceBinding;
+		temp = outerDeclaringClass.enclosingType();
+		while (temp != null) {
+			outerDeclaringClass = temp;
+			temp = temp.enclosingType();
+		}
+		return outerInvocationType == outerDeclaringClass;
+	}
+
+	// isDefault()
+	return receiverType.fPackage == referenceBinding.fPackage;
+}
+// Internal use only
+public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+	MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, null);
+	if (exactMethod != null){
+		if (receiverType.isInterface() || canBeSeenByForCodeSnippet(exactMethod, receiverType, invocationSite, this))
+			return exactMethod;
+	}
+	return null;
+}
+// Internal use only
+
+/*	Answer the field binding that corresponds to fieldName.
+	Start the lookup at the receiverType.
+	InvocationSite implements
+		isSuperAccess(); this is used to determine if the discovered field is visible.
+	Only fields defined by the receiverType or its supertypes are answered;
+	a field of an enclosing type will not be found using this API.
+
+	If no visible field is discovered, null is answered.
+*/
+
+public FieldBinding findFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) {
+	if (receiverType.isBaseType())
+		return null;
+	if (receiverType.isArrayType()) {
+		TypeBinding leafType = receiverType.leafComponentType();
+		if (leafType instanceof ReferenceBinding)
+		if (!((ReferenceBinding)leafType).canBeSeenBy(this)) {
+			return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
+		}
+		if (CharOperation.equals(fieldName, TypeConstants.LENGTH))
+			return ArrayBinding.ArrayLength;
+		return null;
+	}
+
+	ReferenceBinding currentType = (ReferenceBinding) receiverType;
+	if (!currentType.canBeSeenBy(this))
+		return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
+
+	FieldBinding field = currentType.getField(fieldName, true /*resolve*/);
+	if (field != null) {
+		if (canBeSeenByForCodeSnippet(field, currentType, invocationSite, this))
+			return field;
+		else
+			return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, ProblemReasons.NotVisible);
+	}
+
+	// collect all superinterfaces of receiverType until the field is found in a supertype
+	ReferenceBinding[][] interfacesToVisit = null;
+	int lastPosition = -1;
+	FieldBinding visibleField = null;
+	boolean keepLooking = true;
+	boolean notVisible = false; // we could hold onto the not visible field for extra error reporting
+	while (keepLooking) {
+		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+			if (interfacesToVisit == null)
+				interfacesToVisit = new ReferenceBinding[5][];
+			if (++lastPosition == interfacesToVisit.length)
+				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+			interfacesToVisit[lastPosition] = itsInterfaces;
+		}
+		if ((currentType = currentType.superclass()) == null)
+			break;
+
+		if ((field = currentType.getField(fieldName, true /*resolve*/)) != null) {
+			keepLooking = false;
+			if (canBeSeenByForCodeSnippet(field, receiverType, invocationSite, this)) {
+				if (visibleField == null)
+					visibleField = field;
+				else
+					return new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
+			} else {
+				notVisible = true;
+			}
+		}
+	}
+
+	// walk all visible interfaces to find ambiguous references
+	if (interfacesToVisit != null) {
+		ProblemFieldBinding ambiguous = null;
+		org.eclipse.jdt.internal.compiler.util.SimpleSet interfacesSeen = new org.eclipse.jdt.internal.compiler.util.SimpleSet(lastPosition * 2);
+		done : for (int i = 0; i <= lastPosition; i++) {
+			ReferenceBinding[] interfaces = interfacesToVisit[i];
+			for (int j = 0, length = interfaces.length; j < length; j++) {
+				ReferenceBinding anInterface = interfaces[j];
+				if (interfacesSeen.addIfNotIncluded(anInterface) == anInterface) {
+					// if interface as not already been visited
+					if ((field = anInterface.getField(fieldName, true /*resolve*/)) != null) {
+						if (visibleField == null) {
+							visibleField = field;
+						} else {
+							ambiguous = new ProblemFieldBinding(visibleField, visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
+							break done;
+						}
+					} else {
+						ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+						if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+							if (++lastPosition == interfacesToVisit.length)
+								System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+							interfacesToVisit[lastPosition] = itsInterfaces;
+						}
+					}
+				}
+			}
+		}
+		if (ambiguous != null) return ambiguous;
+	}
+
+	if (visibleField != null)
+		return visibleField;
+	if (notVisible)
+		return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.NotVisible);
+	return null;
+}
+// Internal use only
+public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+	MethodBinding methodBinding = super.findMethod(receiverType, selector, argumentTypes, invocationSite);
+	if (methodBinding != null && methodBinding.isValidBinding())
+		if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
+			return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible);
+	return methodBinding;
+}
+
+// Internal use only
+public MethodBinding findMethodForArray(ArrayBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+	ReferenceBinding object = getJavaLangObject();
+	MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null);
+	if (methodBinding != null) {
+		// handle the method clone() specially... cannot be protected or throw exceptions
+		if (argumentTypes == Binding.NO_PARAMETERS && CharOperation.equals(selector, TypeConstants.CLONE))
+			return new MethodBinding((methodBinding.modifiers & ~ClassFileConstants.AccProtected) | ClassFileConstants.AccPublic, TypeConstants.CLONE, methodBinding.returnType, argumentTypes, null, object);
+		if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
+			return methodBinding;
+	}
+
+	// answers closest approximation, may not check argumentTypes or visibility
+	methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
+	if (methodBinding == null)
+		return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+	if (methodBinding.isValidBinding()) {
+	    MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
+	    if (compatibleMethod == null)
+			return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotFound);
+	    methodBinding = compatibleMethod;
+		if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
+			return new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, ProblemReasons.NotVisible);
+	}
+	return methodBinding;
+}
+/* API
+	flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE.
+	Only bindings corresponding to the mask will be answered.
+
+	if the VARIABLE mask is set then
+		If the first name provided is a field (or local) then the field (or local) is answered
+		Otherwise, package names and type names are consumed until a field is found.
+		In this case, the field is answered.
+
+	if the TYPE mask is set,
+		package names and type names are consumed until the end of the input.
+		Only if all of the input is consumed is the type answered
+
+	All other conditions are errors, and a problem binding is returned.
+
+	NOTE: If a problem binding is returned, senders should extract the compound name
+	from the binding & not assume the problem applies to the entire compoundName.
+
+	The VARIABLE mask has precedence over the TYPE mask.
+
+	InvocationSite implements
+		isSuperAccess(); this is used to determine if the discovered field is visible.
+		setFieldIndex(int); this is used to record the number of names that were consumed.
+
+	For example, getBinding({"foo","y","q", VARIABLE, site) will answer
+	the binding for the field or local named "foo" (or an error binding if none exists).
+	In addition, setFieldIndex(1) will be sent to the invocation site.
+	If a type named "foo" exists, it will not be detected (and an error binding will be answered)
+
+	IMPORTANT NOTE: This method is written under the assumption that compoundName is longer than length 1.
+*/
+
+public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite, ReferenceBinding receiverType) {
+	Binding binding = getBinding(compoundName[0], mask | Binding.TYPE | Binding.PACKAGE, invocationSite, true /*resolve*/);
+	invocationSite.setFieldIndex(1);
+	if (!binding.isValidBinding() || binding instanceof VariableBinding)
+		return binding;
+
+	int length = compoundName.length;
+	int currentIndex = 1;
+	foundType: if (binding instanceof PackageBinding) {
+		PackageBinding packageBinding = (PackageBinding) binding;
+
+		while (currentIndex < length) {
+			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
+			invocationSite.setFieldIndex(currentIndex);
+ 			if (binding == null) {
+	 			if (currentIndex == length) // must be a type if its the last name, otherwise we have no idea if its a package or type
+					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound);
+				else
+					return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound);
+ 			}
+ 			if (binding instanceof ReferenceBinding) {
+	 			if (!binding.isValidBinding())
+					return new ProblemReferenceBinding(
+									CharOperation.subarray(compoundName, 0, currentIndex),
+									(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+									binding.problemId());
+	 			if (!this.canBeSeenByForCodeSnippet((ReferenceBinding) binding, receiverType))
+					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), (ReferenceBinding) binding, ProblemReasons.NotVisible);
+	 			break foundType;
+ 			}
+ 			packageBinding = (PackageBinding) binding;
+		}
+
+		// It is illegal to request a PACKAGE from this method.
+		return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound);
+	}
+
+	// know binding is now a ReferenceBinding
+	while (currentIndex < length) {
+		ReferenceBinding typeBinding = (ReferenceBinding) binding;
+		char[] nextName = compoundName[currentIndex++];
+		invocationSite.setFieldIndex(currentIndex);
+		if ((binding = findFieldForCodeSnippet(typeBinding, nextName, invocationSite)) != null) {
+			if (!binding.isValidBinding()) {
+				return new ProblemFieldBinding(
+						(FieldBinding)binding,
+						((FieldBinding)binding).declaringClass,
+						CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+						binding.problemId());
+			}
+			break; // binding is now a field
+		}
+		if ((binding = findMemberType(nextName, typeBinding)) == null)
+			return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), typeBinding, ProblemReasons.NotFound);
+		 if (!binding.isValidBinding())
+			return new ProblemReferenceBinding(
+								CharOperation.subarray(compoundName, 0, currentIndex),
+								(ReferenceBinding)((ReferenceBinding)binding).closestMatch(),
+								binding.problemId());
+	}
+
+	if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) { // was looking for a field and found a field
+		FieldBinding field = (FieldBinding) binding;
+		if (!field.isStatic()) {
+			return new ProblemFieldBinding(
+					field,
+					field.declaringClass,
+					CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
+					ProblemReasons.NonStaticReferenceInStaticContext);
+		}
+		// Since a qualified reference must be for a static member, it won't affect static-ness of the enclosing method, 
+		// so we don't have to call resetEnclosingMethodStaticFlag() in this case
+		return binding;
+	}
+	if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) { // was looking for a type and found a type
+		return binding;
+	}
+
+	// handle the case when a field or type was asked for but we resolved the compoundName to a type or field
+	return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound);
+}
+/* API
+
+	Answer the constructor binding that corresponds to receiverType, argumentTypes.
+
+	InvocationSite implements
+		isSuperAccess(); this is used to determine if the discovered constructor is visible.
+
+	If no visible constructor is discovered, an error binding is answered.
+*/
+
+public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+	MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes);
+	if (methodBinding != null) {
+		if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) {
+			return methodBinding;
+		}
+	}
+	MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT);
+	if (methods == Binding.NO_METHODS) {
+		return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound);
+	}
+	MethodBinding[] compatible = new MethodBinding[methods.length];
+	int compatibleIndex = 0;
+	for (int i = 0, length = methods.length; i < length; i++) {
+	    MethodBinding compatibleMethod = computeCompatibleMethod(methods[i], argumentTypes, invocationSite);
+		if (compatibleMethod != null)
+			compatible[compatibleIndex++] = compatibleMethod;
+	}
+	if (compatibleIndex == 0)
+		return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound); // need a more descriptive error... cannot convert from X to Y
+
+	MethodBinding[] visible = new MethodBinding[compatibleIndex];
+	int visibleIndex = 0;
+	for (int i = 0; i < compatibleIndex; i++) {
+		MethodBinding method = compatible[i];
+		if (canBeSeenByForCodeSnippet(method, receiverType, invocationSite, this)) {
+			visible[visibleIndex++] = method;
+		}
+	}
+	if (visibleIndex == 1) {
+		return visible[0];
+	}
+	if (visibleIndex == 0) {
+		return new ProblemMethodBinding(compatible[0], TypeConstants.INIT, compatible[0].parameters, ProblemReasons.NotVisible);
+	}
+	return mostSpecificClassMethodBinding(visible, visibleIndex, invocationSite);
+}
+/* API
+
+	Answer the field binding that corresponds to fieldName.
+	Start the lookup at the receiverType.
+	InvocationSite implements
+		isSuperAccess(); this is used to determine if the discovered field is visible.
+	Only fields defined by the receiverType or its supertypes are answered;
+	a field of an enclosing type will not be found using this API.
+
+	If no visible field is discovered, an error binding is answered.
+*/
+
+public FieldBinding getFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) {
+	FieldBinding field = findFieldForCodeSnippet(receiverType, fieldName, invocationSite);
+	if (field == null)
+		return new ProblemFieldBinding(receiverType instanceof ReferenceBinding ? (ReferenceBinding) receiverType : null, fieldName, ProblemReasons.NotFound);
+	else
+		return field;
+}
+/* API
+
+	Answer the method binding that corresponds to selector, argumentTypes.
+	Start the lookup at the enclosing type of the receiver.
+	InvocationSite implements
+		isSuperAccess(); this is used to determine if the discovered method is visible.
+		setDepth(int); this is used to record the depth of the discovered method
+			relative to the enclosing type of the receiver. (If the method is defined
+			in the enclosing type of the receiver, the depth is 0; in the next enclosing
+			type, the depth is 1; and so on
+
+	If no visible method is discovered, an error binding is answered.
+*/
+
+public MethodBinding getImplicitMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+	// retrieve an exact visible match (if possible)
+	MethodBinding methodBinding = findExactMethod(receiverType, selector, argumentTypes, invocationSite);
+	if (methodBinding == null)
+		methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
+	if (methodBinding != null) { // skip it if we did not find anything
+		if (methodBinding.isValidBinding())
+		    if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
+				return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible);
+		return methodBinding;
+	}
+	return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
new file mode 100644
index 0000000..42034a7
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -0,0 +1,642 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
+
+/**
+ * A single name reference inside a code snippet can denote a field of a remote
+ * receiver object (that is, the receiver of the context in the stack frame).
+ */
+public class CodeSnippetSingleNameReference extends SingleNameReference implements EvaluationConstants, ProblemReasons {
+
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+
+public CodeSnippetSingleNameReference(char[] source, long pos, EvaluationContext evaluationContext) {
+	super(source, pos);
+	this.evaluationContext = evaluationContext;
+}
+public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
+
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			// check if reading a final blank field
+			FieldBinding fieldBinding;
+			if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
+					&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
+				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
+				if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
+					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+				}
+			}
+			break;
+		case Binding.LOCAL : // reading a local variable
+			LocalVariableBinding localBinding;
+			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
+				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
+			}
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
+				localBinding.useFlag = LocalVariableBinding.USED;
+			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
+				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
+			}
+	}
+	return flowInfo;
+}
+/**
+ * Check and/or redirect the field access to the delegate receiver if any
+ */
+public TypeBinding checkFieldAccess(BlockScope scope) {
+
+	if (this.delegateThis == null) {
+		return super.checkFieldAccess(scope);
+	}
+	FieldBinding fieldBinding = (FieldBinding) this.binding;
+	this.bits &= ~RestrictiveFlagMASK; // clear bits
+	this.bits |= Binding.FIELD;
+	if (!fieldBinding.isStatic()) {
+		// must check for the static status....
+		if (this.evaluationContext.isStatic) {
+			scope.problemReporter().staticFieldAccessToNonStaticVariable(
+				this,
+				fieldBinding);
+			this.constant = Constant.NotAConstant;
+			return null;
+		}
+	}
+	this.constant = fieldBinding.constant();
+
+	if (isFieldUseDeprecated(fieldBinding, scope, this.bits)) {
+		scope.problemReporter().deprecatedField(fieldBinding, this);
+	}
+	return fieldBinding.type;
+
+}
+public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
+	// optimizing assignment like: i = i + 1 or i = 1 + i
+	if (assignment.expression.isCompactableOperation()) {
+		BinaryExpression operation = (BinaryExpression) assignment.expression;
+		int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
+		SingleNameReference variableReference;
+		if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == this.binding)) {
+			// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.right, operator, operation.implicitConversion, valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			return;
+		}
+		if ((operation.right instanceof SingleNameReference)
+				&& ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
+				&& ((variableReference = (SingleNameReference) operation.right).binding == this.binding)
+				&& (operation.left.constant != Constant.NotAConstant) // exclude non constant expressions, since could have side-effect
+				&& (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards
+				&& (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards
+			// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
+			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+			return;
+		}
+	}
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+				if (!codegenField.isStatic()) { // need a receiver?
+					if ((this.bits & DepthMASK) != 0) {
+						ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
+						Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+						codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+					} else {
+						generateReceiver(codeStream);
+					}
+				}
+				assignment.expression.generateCode(currentScope, codeStream, true);
+				fieldStore(currentScope, codeStream, codegenField, null, this.actualReceiverType, this.delegateThis == null /*implicit this*/, valueRequired);
+				if (valueRequired) {
+					codeStream.generateImplicitConversion(assignment.implicitConversion);
+				}
+			} else {
+				codeStream.generateEmulationForField(codegenField);
+				if (!codegenField.isStatic()) { // need a receiver?
+					if ((this.bits & DepthMASK) != 0) {
+						// internal error, per construction we should have found it
+						// not yet supported
+						currentScope.problemReporter().needImplementation(this);
+					} else {
+						generateReceiver(codeStream);
+					}
+				} else {
+					codeStream.aconst_null();
+				}
+				assignment.expression.generateCode(currentScope, codeStream, true);
+				if (valueRequired) {
+					if ((codegenField.type == TypeBinding.LONG) || (codegenField.type == TypeBinding.DOUBLE)) {
+						codeStream.dup2_x2();
+					} else {
+						codeStream.dup_x2();
+					}
+				}
+				codeStream.generateEmulatedWriteAccessForField(codegenField);
+				if (valueRequired) {
+					codeStream.generateImplicitConversion(assignment.implicitConversion);
+				}
+			}
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			if (localBinding.resolvedPosition != -1) {
+				assignment.expression.generateCode(currentScope, codeStream, true);
+			} else {
+				if (assignment.expression.constant != Constant.NotAConstant) {
+					// assigning an unused local to a constant value = no actual assignment is necessary
+					if (valueRequired) {
+						codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion);
+					}
+				} else {
+					assignment.expression.generateCode(currentScope, codeStream, true);
+					/* Even though the value may not be required, we force it to be produced, and discard it later
+					on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3.	*/
+					if (valueRequired) {
+						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
+					} else {
+						if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) {
+							codeStream.pop2();
+						} else {
+							codeStream.pop();
+						}
+					}
+				}
+				return;
+			}
+			// normal local assignment (since cannot store in outer local which are final locations)
+			codeStream.store(localBinding, valueRequired);
+			if ((this.bits & FirstAssignmentToLocal) != 0) { // for local variable debug attributes
+				localBinding.recordInitializationStartPC(codeStream.position);
+			}
+			// implicit conversion
+			if (valueRequired) {
+				codeStream.generateImplicitConversion(assignment.implicitConversion);
+			}
+	}
+}
+public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+	int pc = codeStream.position;
+	if (this.constant != Constant.NotAConstant) {
+		if (valueRequired) {
+			codeStream.generateConstant(this.constant, this.implicitConversion);
+		}
+	} else {
+		switch (this.bits & RestrictiveFlagMASK) {
+			case Binding.FIELD : // reading a field
+				if (!valueRequired)
+					break;
+				FieldBinding codegenField = ((FieldBinding) this.binding).original();
+				Constant fieldConstant = codegenField.constant();
+				if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields
+					if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+						TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
+						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */);
+						if (codegenField.isStatic()) {
+							codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
+						} else {
+							if ((this.bits & DepthMASK) != 0) {
+								ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
+								Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+								codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+							} else {
+								generateReceiver(codeStream);
+							}
+							codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
+						}
+					} else {
+						// managing private access
+						if (!codegenField.isStatic()) {
+							if ((this.bits & DepthMASK) != 0) {
+								// internal error, per construction we should have found it
+								// not yet supported
+								currentScope.problemReporter().needImplementation(this);
+							} else {
+								generateReceiver(codeStream);
+							}
+						} else {
+							codeStream.aconst_null();
+						}
+						codeStream.generateEmulatedReadAccessForField(codegenField);
+					}
+					if (this.genericCast != null) codeStream.checkcast(this.genericCast);
+					codeStream.generateImplicitConversion(this.implicitConversion);
+				} else { // directly use the inlined value
+					codeStream.generateConstant(fieldConstant, this.implicitConversion);
+				}
+				break;
+			case Binding.LOCAL : // reading a local
+				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+				if (localBinding.resolvedPosition == -1) {
+					if (valueRequired) {
+						// restart code gen
+						localBinding.useFlag = LocalVariableBinding.USED;
+						throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+					}
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
+					return;
+				}
+				if (!valueRequired)
+					break;
+				// outer local?
+				if ((this.bits & IsCapturedOuterLocal) != 0) {
+					checkEffectiveFinality(localBinding, currentScope);
+					// outer local can be reached either through a synthetic arg or a synthetic field
+					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
+					codeStream.generateOuterAccess(path, this, localBinding, currentScope);
+				} else {
+					// regular local variable read
+					codeStream.load(localBinding);
+				}
+				codeStream.generateImplicitConversion(this.implicitConversion);
+				break;
+		}
+	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
+}
+/*
+ * The APIs with an extra argument is used whenever there are two references to the same variable which
+ * are optimized in one access: e.g "a = a + 1" optimized into "a++".
+ */
+public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			if (codegenField.isStatic()) {
+				if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+					TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */);
+					codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
+				} else {
+					// used to store the value
+					codeStream.generateEmulationForField(codegenField);
+					codeStream.aconst_null();
+
+					// used to retrieve the actual value
+					codeStream.aconst_null();
+					codeStream.generateEmulatedReadAccessForField(codegenField);
+				}
+			} else {
+				if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+					if ((this.bits & DepthMASK) != 0) {
+						ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
+						Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
+						codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
+					} else {
+						generateReceiver(codeStream);
+					}
+					codeStream.dup();
+					TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
+					TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */);
+					codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
+				} else {
+					if ((this.bits & DepthMASK) != 0) {
+						// internal error, per construction we should have found it
+						// not yet supported
+						currentScope.problemReporter().needImplementation(this);
+					}
+					// used to store the value
+					codeStream.generateEmulationForField(codegenField);
+					generateReceiver(codeStream);
+
+					// used to retrieve the actual value
+					codeStream.dup();
+					codeStream.generateEmulatedReadAccessForField(codegenField);
+				}
+			}
+			break;
+		case Binding.LOCAL : // assigning to a local variable (cannot assign to outer local)
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			// using incr bytecode if possible
+			Constant assignConstant;
+			switch (localBinding.type.id) {
+				case T_JavaLangString :
+					codeStream.generateStringConcatenationAppend(currentScope, this, expression);
+					if (valueRequired) {
+						codeStream.dup();
+					}
+					codeStream.store(localBinding, false);
+					return;
+				case T_int :
+					assignConstant = expression.constant;
+					if (localBinding.resolvedPosition == -1) {
+						if (valueRequired) {
+							/*
+							 * restart code gen because we either:
+							 * - need the value
+							 * - the constant can have potential side-effect
+							 */
+							localBinding.useFlag = LocalVariableBinding.USED;
+							throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+						} else if (assignConstant == Constant.NotAConstant) {
+							// we only need to generate the value of the expression's constant if it is not a constant expression
+							expression.generateCode(currentScope, codeStream, false);
+						}
+						return;
+					}
+					if ((assignConstant != Constant.NotAConstant)
+							&& (assignConstant.typeID() != TypeIds.T_float) // only for integral types
+							&& (assignConstant.typeID() != TypeIds.T_double)) { // TODO (philippe) is this test needed ?
+						switch (operator) {
+							case PLUS :
+								int increment  = assignConstant.intValue();
+								if (increment != (short) increment) break; // not representable as a 16-bits value
+								codeStream.iinc(localBinding.resolvedPosition, increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+							case MINUS :
+								increment  = -assignConstant.intValue();
+								if (increment != (short) increment) break; // not representable as a 16-bits value
+								codeStream.iinc(localBinding.resolvedPosition, increment);
+								if (valueRequired) {
+									codeStream.load(localBinding);
+								}
+								return;
+						}
+					}
+					//$FALL-THROUGH$
+				default :
+					if (localBinding.resolvedPosition == -1) {
+						assignConstant = expression.constant;
+						if (valueRequired) {
+							/*
+							 * restart code gen because we either:
+							 * - need the value
+							 * - the constant can have potential side-effect
+							 */
+							localBinding.useFlag = LocalVariableBinding.USED;
+							throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
+						} else if (assignConstant == Constant.NotAConstant) {
+							// we only need to generate the value of the expression's constant if it is not a constant expression
+							expression.generateCode(currentScope, codeStream, false);
+						}
+						return;
+					}
+					codeStream.load(localBinding);
+			}
+	}
+	// perform the actual compound operation
+	int operationTypeID;
+	switch(operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
+		case T_JavaLangString :
+		case T_JavaLangObject :
+		case T_undefined :
+			codeStream.generateStringConcatenationAppend(currentScope, null, expression);
+			break;
+		default :
+			// promote the array reference to the suitable operation type
+			codeStream.generateImplicitConversion(this.implicitConversion);
+			// generate the increment value (will by itself  be promoted to the operation value)
+			if (expression == IntLiteral.One){ // prefix operation
+				codeStream.generateConstant(expression.constant, this.implicitConversion);
+			} else {
+				expression.generateCode(currentScope, codeStream, true);
+			}
+			// perform the operation
+			codeStream.sendOperator(operator, operationTypeID);
+			// cast the value back to the array reference type
+			codeStream.generateImplicitConversion(assignmentImplicitConversion);
+	}
+	// store the result back into the variable
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+				fieldStore(currentScope, codeStream, codegenField, writeAccessor, this.actualReceiverType, this.delegateThis == null /* implicit this */, valueRequired);
+			} else {
+				// current stack is:
+				// field receiver value
+				if (valueRequired) {
+					switch (codegenField.type.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.dup2_x2();
+							break;
+						default:
+							codeStream.dup_x2();
+							break;
+					}					
+				}
+				// current stack is:
+				// value field receiver value
+				codeStream.generateEmulatedWriteAccessForField(codegenField);
+			}
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
+			if (valueRequired) {
+				switch (localBinding.type.id) {
+					case TypeIds.T_long :
+					case TypeIds.T_double :
+						codeStream.dup2();
+						break;
+					default:
+						codeStream.dup();
+						break;
+				}				
+			}
+			codeStream.store(localBinding, false);
+	}
+}
+public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
+	switch (this.bits & RestrictiveFlagMASK) {
+		case Binding.FIELD : // assigning to a field
+			FieldBinding codegenField = ((FieldBinding) this.binding).original();
+			if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
+				super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
+			} else {
+				if (codegenField.isStatic()) {
+					codeStream.aconst_null();
+				} else {
+					if ((this.bits & DepthMASK) != 0) {
+						// internal error, per construction we should have found it
+						// not yet supported
+						currentScope.problemReporter().needImplementation(this);
+					} else {
+						generateReceiver(codeStream);
+					}
+				}
+				codeStream.generateEmulatedReadAccessForField(codegenField);
+				if (valueRequired) {
+					switch (codegenField.type.id) {
+						case TypeIds.T_long :
+						case TypeIds.T_double :
+							codeStream.dup2();
+							break;
+						default:
+							codeStream.dup();
+							break;
+					}
+				}
+				codeStream.generateEmulationForField(codegenField);
+				switch (codegenField.type.id) {
+					case TypeIds.T_long :
+					case TypeIds.T_double :
+						codeStream.dup_x2();
+						codeStream.pop();
+						if (codegenField.isStatic()) {
+							codeStream.aconst_null();
+						} else {
+							generateReceiver(codeStream);
+						}
+						codeStream.dup_x2();
+						codeStream.pop();
+						break;
+					default:
+						codeStream.dup_x1();
+					codeStream.pop();
+					if (codegenField.isStatic()) {
+						codeStream.aconst_null();
+					} else {
+						generateReceiver(codeStream);
+					}
+					codeStream.dup_x1();
+					codeStream.pop();
+						break;
+				}
+				codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
+				codeStream.sendOperator(postIncrement.operator, codegenField.type.id);
+				codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+				codeStream.generateEmulatedWriteAccessForField(codegenField);
+			}
+			return;
+		case Binding.LOCAL : // assigning to a local variable
+			super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
+	}
+}
+public void generateReceiver(CodeStream codeStream) {
+	codeStream.aload_0();
+	if (this.delegateThis != null) {
+		codeStream.fieldAccess(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access
+	}
+}
+/**
+ * Check and/or redirect the field access to the delegate receiver if any
+ */
+public TypeBinding getReceiverType(BlockScope currentScope) {
+	Scope scope = currentScope.parent;
+	while (true) {
+			switch (scope.kind) {
+				case Scope.CLASS_SCOPE :
+					return ((ClassScope) scope).referenceContext.binding;
+				default:
+					scope = scope.parent;
+			}
+	}
+}
+public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
+
+	if (this.delegateThis == null) {
+		super.manageSyntheticAccessIfNecessary(currentScope, flowInfo, isReadAccess);
+		return;
+	}
+
+	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;
+	//If inlinable field, forget the access emulation, the code gen will directly target it
+	if (this.constant != Constant.NotAConstant)
+		return;
+	// if field from parameterized type got found, use the original field at codegen time
+	if (this.binding instanceof ParameterizedFieldBinding) {
+	    ParameterizedFieldBinding parameterizedField = (ParameterizedFieldBinding) this.binding;
+	    FieldBinding codegenField = parameterizedField.originalField;
+	    // extra cast needed if field type was type variable
+	    if ((codegenField.type.tagBits & TagBits.HasTypeVariable) != 0) {
+	        this.genericCast = codegenField.type.genericCast(currentScope.boxing(parameterizedField.type)); // runtimeType could be base type in boxing case
+	    }
+	}
+}
+/**
+ * Normal field binding did not work, try to bind to a field of the delegate receiver.
+ */
+public TypeBinding reportError(BlockScope scope) {
+
+	this.constant = Constant.NotAConstant;
+	if (this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotFound){
+		if (this.evaluationContext.declaringTypeName != null) {
+			this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+			if (this.delegateThis != null){  // if not found then internal error, field should have been found
+				this.actualReceiverType = this.delegateThis.type;
+				// will not support innerclass emulation inside delegate
+				this.binding = scope.getField(this.delegateThis.type, this.token, this);
+				if (!this.binding.isValidBinding()) {
+					return super.reportError(scope);
+				}
+				return checkFieldAccess(scope);
+			}
+		}
+	}
+	if (this.binding instanceof ProblemBinding && ((ProblemBinding) this.binding).problemId() == NotFound){
+		if (this.evaluationContext.declaringTypeName != null) {
+			this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
+			if (this.delegateThis != null){  // if not found then internal error, field should have been found
+				this.actualReceiverType = this.delegateThis.type;
+				// will not support innerclass emulation inside delegate
+				FieldBinding fieldBinding = scope.getField(this.delegateThis.type, this.token, this);
+				if (!fieldBinding.isValidBinding()) {
+					if (((ProblemFieldBinding) fieldBinding).problemId() == NotVisible) {
+						// manage the access to a private field of the enclosing type
+						CodeSnippetScope localScope = new CodeSnippetScope(scope);
+						this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.token, this);
+						return checkFieldAccess(scope);
+					} else {
+						return super.reportError(scope);
+					}
+				}
+				this.binding = fieldBinding;
+				return checkFieldAccess(scope);
+			}
+		}
+	}
+	return super.reportError(scope);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
new file mode 100644
index 0000000..f0090b1
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * The skeleton of the class 'org.eclipse.jdt.internal.eval.target.CodeSnippet'
+ * used at compile time. Note that the method run() is declared to
+ * throw Throwable so that the user can write a code snipet that
+ * throws checked exceptio without having to catch those.
+ */
+public class CodeSnippetSkeleton implements IBinaryType, EvaluationConstants {
+	public static class BinaryMethodSkeleton implements IBinaryMethod {
+		char[][] exceptionTypeNames;
+		char[] methodDescriptor;
+		char[] selector;
+		boolean isConstructor;
+
+		public BinaryMethodSkeleton(char[] selector, char[] methodDescriptor, char[][] exceptionTypeNames, boolean isConstructor) {
+			this.selector = selector;
+			this.methodDescriptor = methodDescriptor;
+			this.exceptionTypeNames = exceptionTypeNames;
+			this.isConstructor = isConstructor;
+		}
+		public IBinaryAnnotation[] getAnnotations() {
+			return null;
+		}
+		public char[][] getArgumentNames() {
+			return null;
+		}
+		public Object getDefaultValue() {
+			return null;
+		}
+		public char[][] getExceptionTypeNames() {
+			return this.exceptionTypeNames;
+		}
+		public char[] getGenericSignature() {
+			return null;
+		}
+		public char[] getMethodDescriptor() {
+			return this.methodDescriptor;
+		}
+		public int getModifiers() {
+			return ClassFileConstants.AccPublic;
+		}
+		public IBinaryAnnotation[] getParameterAnnotations(int index) {
+			return null;
+		}
+		public int getAnnotatedParametersCount() {
+			return 0;
+		}
+		public char[] getSelector() {
+			return this.selector;
+		}
+		public long getTagBits() {
+			return 0;
+		}
+		public boolean isClinit() {
+			return false;
+		}
+		public boolean isConstructor() {
+			return this.isConstructor;
+		}
+}
+
+	IBinaryMethod[] methods = new IBinaryMethod[] {
+		new BinaryMethodSkeleton(
+			"<init>".toCharArray(), //$NON-NLS-1$
+			"()V".toCharArray(), //$NON-NLS-1$
+			new char[][] {},
+			true
+		),
+		new BinaryMethodSkeleton(
+			"run".toCharArray(), //$NON-NLS-1$
+			"()V".toCharArray(), //$NON-NLS-1$
+			new char[][] {"java/lang/Throwable".toCharArray()}, //$NON-NLS-1$
+			false
+		),
+		new BinaryMethodSkeleton(
+			"setResult".toCharArray(), //$NON-NLS-1$
+			"(Ljava/lang/Object;Ljava/lang/Class;)V".toCharArray(), //$NON-NLS-1$
+			new char[][] {},
+			false
+		)
+	};
+
+/**
+ * CodeSnippetSkeleton constructor comment.
+ */
+public CodeSnippetSkeleton() {
+	super();
+}
+public IBinaryAnnotation[] getAnnotations() {
+	return null;
+}
+public char[] getEnclosingMethod() {
+	return null;
+}
+public char[] getEnclosingTypeName() {
+	return null;
+}
+public IBinaryField[] getFields() {
+	return null;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return CharOperation.concat(CODE_SNIPPET_NAME, Util.defaultJavaExtension().toCharArray());
+}
+public char[] getGenericSignature() {
+	return null;
+}
+public char[][] getInterfaceNames() {
+	return null;
+}
+public String getJavadocContents() {
+	return null;
+}
+public String getJavadocContents(IProgressMonitor monitor, String defaultEncoding) throws JavaModelException {
+	return null;
+}
+public IBinaryNestedType[] getMemberTypes() {
+	return null;
+}
+public IBinaryMethod[] getMethods() {
+	return this.methods;
+}
+public int getModifiers() {
+	return ClassFileConstants.AccPublic;
+}
+public char[][][] getMissingTypeNames() {
+	return null;
+}
+public char[] getName() {
+	return CODE_SNIPPET_NAME;
+}
+public char[] getSourceName() {
+	return ROOT_CLASS_NAME;
+}
+public char[] getSuperclassName() {
+	return null;
+}
+public long getTagBits() {
+	return 0;
+}
+public String getURLContents(String docUrlValue, String defaultEncoding) {
+	return null;
+}
+public boolean isAnonymous() {
+	return false;
+}
+public boolean isBinaryType() {
+	return true;
+}
+public boolean isLocal() {
+	return false;
+}
+public boolean isMember() {
+	return false;
+}
+public char[] sourceFileName() {
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java
new file mode 100644
index 0000000..cc3a773
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/**
+ * A super reference inside a code snippet denotes a reference to the super type of
+ * the remote receiver object (that is, the receiver of the context in the stack frame). This is
+ * used to report an error through JavaModelException according to the fact that super
+ * reference are not supported in code snippet.
+ */
+public class CodeSnippetSuperReference extends SuperReference implements EvaluationConstants, InvocationSite {
+
+public CodeSnippetSuperReference(int pos, int sourceEnd) {
+	super(pos, sourceEnd);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+ */
+public TypeBinding[] genericTypeArguments() {
+	return null;
+}
+
+public TypeBinding resolveType(BlockScope scope) {
+	scope.problemReporter().cannotUseSuperInCodeSnippet(this.sourceStart, this.sourceEnd);
+	return null;
+}
+public boolean isSuperAccess(){
+	return false;
+}
+public boolean isTypeAccess(){
+	return false;
+}
+public void setActualReceiverType(ReferenceBinding receiverType) {
+	// ignored
+}
+public void setDepth(int depth){
+	// ignored
+}
+public void setFieldIndex(int index){
+	// ignored
+}
+}
+
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java
new file mode 100644
index 0000000..8bf7193
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper S Moller - Contributions for
+ *								Bug 378674 - "The method can be declared as static" is wrong
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+/**
+ * A this reference inside a code snippet denotes a remote
+ * receiver object (that is, the receiver of the context in the stack frame)
+ */
+public class CodeSnippetThisReference extends ThisReference implements EvaluationConstants, InvocationSite {
+
+	EvaluationContext evaluationContext;
+	FieldBinding delegateThis;
+	boolean isImplicit;
+
+	/**
+	 * CodeSnippetThisReference constructor comment.
+	 * @param s int
+	 * @param sourceEnd int
+	 */
+	public CodeSnippetThisReference(int s, int sourceEnd, EvaluationContext evaluationContext, boolean isImplicit) {
+		super(s, sourceEnd);
+		this.evaluationContext = evaluationContext;
+		this.isImplicit = isImplicit;
+	}
+	
+	public boolean checkAccess(BlockScope scope, ReferenceBinding thisType) {
+		// this/super cannot be used in constructor call
+		MethodScope methodScope = scope.methodScope();
+		if (this.evaluationContext.isConstructorCall) {
+			methodScope.problemReporter().fieldsOrThisBeforeConstructorInvocation(this);
+			return false;
+		}
+
+		// static may not refer to this/super
+		if (this.evaluationContext.declaringTypeName == null || this.evaluationContext.isStatic) {
+			methodScope.problemReporter().errorThisSuperInStatic(this);
+			return false;
+		}
+		scope.tagAsAccessingEnclosingInstanceStateOf(thisType, false /* type variable access */);
+		return true;
+	}
+	
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		int pc = codeStream.position;
+		if (valueRequired) {
+			codeStream.aload_0();
+			codeStream.fieldAccess(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegate field access
+		}
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
+	}
+	
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#genericTypeArguments()
+	 */
+	public TypeBinding[] genericTypeArguments() {
+		return null;
+	}
+	
+	public boolean isSuperAccess(){
+		return false;
+	}
+	
+	public boolean isTypeAccess(){
+		return false;
+	}
+	
+	public StringBuffer printExpression(int indent, StringBuffer output){
+
+		char[] declaringType = this.evaluationContext.declaringTypeName;
+		output.append('(');
+		if (declaringType == null)
+			output.append("<NO DECLARING TYPE>"); //$NON-NLS-1$
+		else
+			output.append(declaringType);
+		return output.append(")this"); //$NON-NLS-1$
+	}
+	
+	public TypeBinding resolveType(BlockScope scope) {
+		// implicit this
+		this.constant = Constant.NotAConstant;
+		ReferenceBinding snippetType = scope.enclosingSourceType();
+		MethodScope methodScope = scope.methodScope();
+		if (!this.isImplicit && !checkAccess(scope, snippetType)) {
+			return null;
+		}
+
+		this.delegateThis = scope.getField(snippetType, DELEGATE_THIS, this);
+		if (this.delegateThis == null || !this.delegateThis.isValidBinding()) {
+			// should not happen
+			// if this happen we should report illegal access to this in a static context
+			methodScope.problemReporter().errorThisSuperInStatic(this);
+			return null;
+		}
+		return this.resolvedType = this.delegateThis.type;
+	}
+	
+	public void setActualReceiverType(ReferenceBinding receiverType) {
+		// ignored
+	}
+	
+	public void setDepth(int depth){
+		// ignored
+	}
+	
+	public void setFieldIndex(int index){
+		// ignored
+	}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
new file mode 100644
index 0000000..c8391d0
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+/**
+ * Maps back and forth a code snippet to a compilation unit.
+ * The structure of the compilation unit is as follows:
+ * <pre>
+ * [package <package name>;]
+ * [import <import name>;]*
+ * public class <code snippet class name> extends <global variable class name> {
+ *   [<declaring type> val$this;]
+ *   public void run() {
+ *     <code snippet>
+ *   }
+ * }
+ * </pre>
+ */
+class CodeSnippetToCuMapper implements EvaluationConstants {
+	/**
+	 * The generated compilation unit.
+	 */
+	public char[] cuSource;
+
+	/**
+	 * Where the code snippet starts in the generated compilation unit.
+	 */
+	public int lineNumberOffset = 0;
+	public int startPosOffset = 0;
+
+	// Internal fields
+	char[] codeSnippet;
+	char[] snippetPackageName;
+	char[][] snippetImports;
+	char[] snippetClassName;
+	char[] snippetVarClassName;
+	char[] snippetDeclaringTypeName;
+
+	// Mapping of external local variables
+	char[][] localVarNames;
+	char[][] localVarTypeNames;
+	
+	long complianceVersion;
+
+/**
+ * Rebuild source in presence of external local variables
+ */
+ public CodeSnippetToCuMapper(
+		char[] codeSnippet,
+		char[] packageName,
+		char[][] imports,
+		char[] className,
+		char[] varClassName,
+		char[][] localVarNames,
+		char[][] localVarTypeNames,
+		int[] localVarModifiers,
+		char[] declaringTypeName,
+		String lineSeparator,
+		long complianceVersion) {
+	this.codeSnippet = codeSnippet;
+	this.snippetPackageName = packageName;
+	this.snippetImports = imports;
+	this.snippetClassName = className;
+	this.snippetVarClassName = varClassName;
+	this.localVarNames = localVarNames;
+	this.localVarTypeNames = localVarTypeNames;
+	this.snippetDeclaringTypeName = declaringTypeName;
+	this.complianceVersion = complianceVersion;
+	buildCUSource(lineSeparator);
+}
+private void buildCUSource(String lineSeparator) {
+	StringBuffer buffer = new StringBuffer();
+
+	// package declaration
+	if (this.snippetPackageName != null && this.snippetPackageName.length != 0) {
+		buffer.append("package "); //$NON-NLS-1$
+		buffer.append(this.snippetPackageName);
+		buffer.append(";").append(lineSeparator); //$NON-NLS-1$
+		this.lineNumberOffset++;
+	}
+
+	// import declarations
+	char[][] imports = this.snippetImports;
+	for (int i = 0; i < imports.length; i++) {
+		buffer.append("import "); //$NON-NLS-1$
+		buffer.append(imports[i]);
+		buffer.append(';').append(lineSeparator);
+		this.lineNumberOffset++;
+	}
+
+	// class declaration
+	buffer.append("public class "); //$NON-NLS-1$
+	buffer.append(this.snippetClassName);
+
+	// super class is either a global variable class or the CodeSnippet class
+	if (this.snippetVarClassName != null) {
+		buffer.append(" extends "); //$NON-NLS-1$
+		buffer.append(this.snippetVarClassName);
+	} else {
+		buffer.append(" extends "); //$NON-NLS-1$
+		buffer.append(PACKAGE_NAME);
+		buffer.append("."); //$NON-NLS-1$
+		buffer.append(ROOT_CLASS_NAME);
+	}
+	buffer.append(" {").append(lineSeparator); //$NON-NLS-1$
+	this.lineNumberOffset++;
+
+	if (this.snippetDeclaringTypeName != null){
+		buffer.append("  "); //$NON-NLS-1$
+		buffer.append(this.snippetDeclaringTypeName);
+		buffer.append(" "); //$NON-NLS-1$
+		buffer.append(DELEGATE_THIS); // val$this
+		buffer.append(';').append(lineSeparator);
+		this.lineNumberOffset++;
+	}
+	// add some storage location for local variable persisted state
+	if (this.localVarNames != null) {
+		for (int i = 0, max = this.localVarNames.length; i < max; i++) {
+			buffer.append("    "); //$NON-NLS-1$
+			buffer.append(this.localVarTypeNames[i]);
+			buffer.append(" "); //$NON-NLS-1$
+			buffer.append(LOCAL_VAR_PREFIX); // val$...
+			buffer.append(this.localVarNames[i]);
+			buffer.append(';').append(lineSeparator);
+			this.lineNumberOffset++;
+		}
+	}
+	// run() method declaration
+	if (this.complianceVersion >= ClassFileConstants.JDK1_5) {
+		buffer.append("@Override "); //$NON-NLS-1$
+	}
+	buffer.append("public void run() throws Throwable {").append(lineSeparator); //$NON-NLS-1$
+	this.lineNumberOffset++;
+	this.startPosOffset = buffer.length();
+	buffer.append(this.codeSnippet);
+	// a line separator is required after the code snippet source code
+	// in case the code snippet source code ends with a line comment
+	// http://dev.eclipse.org/bugs/show_bug.cgi?id=14838
+	buffer.append(lineSeparator).append('}').append(lineSeparator);
+
+	// end of class declaration
+	buffer.append('}').append(lineSeparator);
+
+	// store result
+	int length = buffer.length();
+	this.cuSource = new char[length];
+	buffer.getChars(0, length, this.cuSource, 0);
+}
+/**
+ * Returns a completion requestor that wraps the given requestor and shift the results
+ * according to the start offset and line number offset of the code snippet in the generated compilation unit.
+ */
+public CompletionRequestor getCompletionRequestor(final CompletionRequestor originalRequestor) {
+	return new CompletionRequestor() {
+		public void accept(CompletionProposal proposal) {
+			switch(proposal.getKind()) {
+				case CompletionProposal.TYPE_REF:
+					int flags = proposal.getFlags();
+					if((flags & Flags.AccEnum) == 0 &&
+							(flags & Flags.AccInterface) == 0) {
+						// Remove completion on generated class name or generated global variable class name
+						char[] packageName = proposal.getDeclarationSignature();
+						char[] className = Signature.getSignatureSimpleName(proposal.getSignature());
+						if (CharOperation.equals(packageName, CodeSnippetToCuMapper.this.snippetPackageName)
+								&& (CharOperation.equals(className, CodeSnippetToCuMapper.this.snippetClassName)
+									|| CharOperation.equals(className, CodeSnippetToCuMapper.this.snippetVarClassName))) return;
+
+						if (CharOperation.equals(packageName, PACKAGE_NAME)
+								&& CharOperation.equals(className, ROOT_CLASS_NAME)) return;
+					}
+					break;
+				case CompletionProposal.METHOD_REF:
+				case CompletionProposal.METHOD_DECLARATION:
+				case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER:
+					// Remove completion on generated method
+					char[] declaringTypePackageName = Signature.getSignatureQualifier(proposal.getDeclarationSignature());
+					char[] declaringTypeName = Signature.getSignatureSimpleName(proposal.getDeclarationSignature());
+
+					if (CharOperation.equals(declaringTypePackageName, CodeSnippetToCuMapper.this.snippetPackageName)
+							&& CharOperation.equals(declaringTypeName, CodeSnippetToCuMapper.this.snippetClassName)) return;
+
+					if (CharOperation.equals(declaringTypePackageName, PACKAGE_NAME)
+							&& CharOperation.equals(declaringTypeName, ROOT_CLASS_NAME)) return;
+					break;
+			}
+			originalRequestor.accept(proposal);
+		}
+
+		public void completionFailure(IProblem problem) {
+			problem.setSourceStart(problem.getSourceStart() - CodeSnippetToCuMapper.this.startPosOffset);
+			problem.setSourceEnd(problem.getSourceEnd() - CodeSnippetToCuMapper.this.startPosOffset);
+			problem.setSourceLineNumber(problem.getSourceLineNumber() -  CodeSnippetToCuMapper.this.lineNumberOffset);
+			originalRequestor.completionFailure(problem);
+		}
+
+		public void acceptContext(CompletionContext context) {
+			originalRequestor.acceptContext(context);
+		}
+
+		public void beginReporting() {
+			originalRequestor.beginReporting();
+		}
+
+		public void endReporting() {
+			originalRequestor.endReporting();
+		}
+
+		public boolean isIgnored(int completionProposalKind) {
+			return originalRequestor.isIgnored(completionProposalKind);
+		}
+
+		public void setIgnored(int completionProposalKind, boolean ignore) {
+			originalRequestor.setIgnored(completionProposalKind, ignore);
+		}
+
+		public boolean isAllowingRequiredProposals(int mainKind, int requiredKind) {
+			return originalRequestor.isAllowingRequiredProposals(mainKind, requiredKind);
+		}
+
+		public void setAllowsRequiredProposals(int mainKind, int requiredKind, boolean allow) {
+			originalRequestor.setAllowsRequiredProposals(mainKind, requiredKind, allow);
+		}
+	};
+}
+public char[] getCUSource(String lineSeparator) {
+	if (this.cuSource == null) {
+		buildCUSource(lineSeparator);
+	}
+	return this.cuSource;
+}
+/**
+ * Returns the type of evaluation that corresponds to the given line number in the generated compilation unit.
+ */
+public int getEvaluationType(int lineNumber) {
+	int currentLine = 1;
+
+	// check package declaration
+	if (this.snippetPackageName != null && this.snippetPackageName.length != 0) {
+		if (lineNumber == 1) {
+			return EvaluationResult.T_PACKAGE;
+		}
+		currentLine++;
+	}
+
+	// check imports
+	char[][] imports = this.snippetImports;
+	if ((currentLine <= lineNumber) && (lineNumber < (currentLine + imports.length))) {
+		return EvaluationResult.T_IMPORT;
+	}
+	currentLine += imports.length + 1; // + 1 to skip the class declaration line
+
+	// check generated fields
+	currentLine +=
+		(this.snippetDeclaringTypeName == null ? 0 : 1)
+		+ (this.localVarNames == null ? 0 : this.localVarNames.length);
+	if (currentLine > lineNumber) {
+		return EvaluationResult.T_INTERNAL;
+	}
+	currentLine ++; // + 1 to skip the method declaration line
+
+	// check code snippet
+	if (currentLine >= this.lineNumberOffset) {
+		return EvaluationResult.T_CODE_SNIPPET;
+	}
+
+	// default
+	return EvaluationResult.T_INTERNAL;
+}
+/**
+ * Returns the import defined at the given line number.
+ */
+public char[] getImport(int lineNumber) {
+	int importStartLine = this.lineNumberOffset - 1 - this.snippetImports.length;
+	return this.snippetImports[lineNumber - importStartLine];
+}
+/**
+ * Returns a selection requestor that wraps the given requestor and shift the problems
+ * according to the start offset and line number offset of the code snippet in the generated compilation unit.
+ */
+public ISelectionRequestor getSelectionRequestor(final ISelectionRequestor originalRequestor) {
+	return new ISelectionRequestor() {
+		public void acceptType(char[] packageName, char[] typeName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+			originalRequestor.acceptType(packageName, typeName, modifiers, isDeclaration, uniqueKey, start, end);
+		}
+		public void acceptError(CategorizedProblem error) {
+			error.setSourceLineNumber(error.getSourceLineNumber() -  CodeSnippetToCuMapper.this.lineNumberOffset);
+			error.setSourceStart(error.getSourceStart() - CodeSnippetToCuMapper.this.startPosOffset);
+			error.setSourceEnd(error.getSourceEnd() - CodeSnippetToCuMapper.this.startPosOffset);
+			originalRequestor.acceptError(error);
+		}
+		public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+			originalRequestor.acceptField(declaringTypePackageName, declaringTypeName, name, isDeclaration, uniqueKey, start, end);
+		}
+		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, char[][] typeParameterNames, char[][][] typeParameterBoundNames, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+			originalRequestor.acceptMethod(declaringTypePackageName, declaringTypeName, enclosingDeclaringTypeSignature, selector, parameterPackageNames, parameterTypeNames, parameterSignatures, typeParameterNames, typeParameterBoundNames, isConstructor, isDeclaration, uniqueKey, start, end);
+		}
+		public void acceptPackage(char[] packageName) {
+			originalRequestor.acceptPackage(packageName);
+		}
+
+		public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
+			originalRequestor.acceptTypeParameter(declaringTypePackageName, declaringTypeName, typeParameterName, isDeclaration, start, end);
+		}
+		public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, int selectorStart, int selectorEnd, char[] typeParameterName,boolean isDeclaration, int start, int end) {
+			originalRequestor.acceptMethodTypeParameter(declaringTypePackageName, declaringTypeName, selector, selectorStart, selectorEnd, typeParameterName, isDeclaration, start, end);
+		}
+	};
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
new file mode 100644
index 0000000..a2c1219
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortType;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class CodeSnippetTypeDeclaration extends TypeDeclaration {
+
+public CodeSnippetTypeDeclaration(CompilationResult compilationResult){
+	super(compilationResult);
+}
+
+/**
+ * Generic bytecode generation for type
+ */
+public void generateCode(ClassFile enclosingClassFile) {
+	if ((this.bits & ASTNode.HasBeenGenerated) != 0) return;
+	this.bits |= ASTNode.HasBeenGenerated;
+
+	if (this.ignoreFurtherInvestigation) {
+		if (this.binding == null)
+			return;
+		CodeSnippetClassFile.createProblemType(this, this.scope.referenceCompilationUnit().compilationResult);
+		return;
+	}
+	try {
+		// create the result for a compiled type
+		ClassFile classFile = new CodeSnippetClassFile(this.binding, enclosingClassFile, false);
+		// generate all fiels
+		classFile.addFieldInfos();
+		if (this.binding.isMemberType()) {
+			classFile.recordInnerClasses(this.binding);
+		} else if (this.binding.isLocalType()) {
+			enclosingClassFile.recordInnerClasses(this.binding);
+			classFile.recordInnerClasses(this.binding);
+		}
+		TypeVariableBinding[] typeVariables = this.binding.typeVariables();
+		for (int i = 0, max = typeVariables.length; i < max; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariables[i];
+			if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+				Util.recordNestedType(classFile, typeVariableBinding);
+			}
+		}
+		if (this.memberTypes != null) {
+			for (int i = 0, max = this.memberTypes.length; i < max; i++) {
+				TypeDeclaration memberType = this.memberTypes[i];
+				classFile.recordInnerClasses(memberType.binding);
+				memberType.generateCode(this.scope, classFile);
+			}
+		}
+		// generate all methods
+		classFile.setForMethodInfos();
+		if (this.methods != null) {
+			for (int i = 0, max = this.methods.length; i < max; i++) {
+				this.methods[i].generateCode(this.scope, classFile);
+			}
+		}
+
+		// generate all methods
+		classFile.addSpecialMethods();
+
+		if (this.ignoreFurtherInvestigation){ // trigger problem type generation for code gen errors
+			throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);
+		}
+
+		// finalize the compiled type result
+		classFile.addAttributes();
+		this.scope.referenceCompilationUnit().compilationResult.record(this.binding.constantPoolName(), classFile);
+	} catch (AbortType e) {
+		if (this.binding == null)
+			return;
+		CodeSnippetClassFile.createProblemType(this, this.scope.referenceCompilationUnit().compilationResult);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java
new file mode 100644
index 0000000..5266c5a
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public interface EvaluationConstants {
+	public static final char[] CODE_SNIPPET_CLASS_NAME_PREFIX = "CodeSnippet_".toCharArray(); //$NON-NLS-1$
+	public static final char[] GLOBAL_VARS_CLASS_NAME_PREFIX = "GlobalVariables_".toCharArray(); //$NON-NLS-1$
+	public static final char[] PACKAGE_NAME = "org.eclipse.jdt.internal.eval.target".toCharArray(); //$NON-NLS-1$
+	public static final char[] CODE_SNIPPET_NAME = "org/eclipse/jdt/internal/eval/target/CodeSnippet".toCharArray(); //$NON-NLS-1$
+	public static final char[] ROOT_CLASS_NAME = "CodeSnippet".toCharArray(); //$NON-NLS-1$
+	public static final String ROOT_FULL_CLASS_NAME = new String(PACKAGE_NAME) + "." + new String(ROOT_CLASS_NAME); //$NON-NLS-1$
+	public static final char[] SETRESULT_SELECTOR = "setResult".toCharArray(); //$NON-NLS-1$
+	public static final char[] SETRESULT_ARGUMENTS = "Ljava.lang.Object;Ljava.lang.Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[][] ROOT_COMPOUND_NAME = CharOperation.arrayConcat(CharOperation.splitOn('.', PACKAGE_NAME), ROOT_CLASS_NAME);
+	public static final String RUN_METHOD = "run"; //$NON-NLS-1$
+	public static final String RESULT_VALUE_FIELD = "resultValue"; //$NON-NLS-1$
+	public static final String RESULT_TYPE_FIELD = "resultType"; //$NON-NLS-1$
+	public static final char[] LOCAL_VAR_PREFIX = "val$".toCharArray(); //$NON-NLS-1$
+	public static final char[] DELEGATE_THIS = "val$this".toCharArray(); //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
new file mode 100644
index 0000000..33c30f4
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
@@ -0,0 +1,637 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.CompletionRequestor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ */
+public class EvaluationContext implements EvaluationConstants, SuffixConstants {
+	/**
+	 * Global counters so that several evaluation context can deploy on the same runtime.
+	 */
+	static int VAR_CLASS_COUNTER = 0;
+	static int CODE_SNIPPET_COUNTER = 0;
+
+	GlobalVariable[] variables;
+	int variableCount;
+	char[][] imports;
+	char[] packageName;
+	boolean varsChanged;
+	VariablesInfo installedVars;
+	IBinaryType codeSnippetBinary;
+	String lineSeparator;
+
+	/* do names implicitly refer to a given type */
+	char[] declaringTypeName;
+	int[] localVariableModifiers;
+	char[][] localVariableTypeNames;
+	char[][] localVariableNames;
+
+	/* can 'this' be used in this context */
+	boolean isStatic;
+	boolean isConstructorCall;
+/**
+ * Creates a new evaluation context.
+ */
+public EvaluationContext() {
+	this.variables = new GlobalVariable[5];
+	this.variableCount = 0;
+	this.imports = CharOperation.NO_CHAR_CHAR;
+	this.packageName = CharOperation.NO_CHAR;
+	this.varsChanged = true;
+	this.isStatic = true;
+	this.isConstructorCall = false;
+	this.lineSeparator = org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; // default value
+}
+/**
+ * Returns the global variables of this evaluation context in the order they were created in.
+ */
+public GlobalVariable[] allVariables() {
+	GlobalVariable[] result = new GlobalVariable[this.variableCount];
+	System.arraycopy(this.variables, 0, result, 0, this.variableCount);
+	return result;
+}
+/**
+ * Computes a completion at the specified position of the given code snippet.
+ * (Note that this evaluation context's VM doesn't need to be running.)
+ *
+ *  @param environment
+ *      used to resolve type/package references and search for types/packages
+ *      based on partial names.
+ *
+ *  @param requestor
+ *      since the engine might produce answers of various forms, the engine
+ *      is associated with a requestor able to accept all possible completions.
+ *
+ *  @param options
+ *		set of options used to configure the code assist engine.
+ *
+ *  @param owner
+ *  	the owner of working copies that take precedence over their original compilation units
+ *  
+ *  @param monitor
+ *  	the progress monitor used to report progress
+ */
+public void complete(
+		char[] codeSnippet,
+		int completionPosition,
+		SearchableEnvironment environment,
+		CompletionRequestor requestor,
+		Map options,
+		final IJavaProject project,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor) {
+	try {
+		IRequestor variableRequestor = new IRequestor() {
+			public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
+				// Do nothing
+				return true;
+			}
+			public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
+				// Do nothing
+			}
+		};
+		evaluateVariables(environment, options, variableRequestor, new DefaultProblemFactory(Locale.getDefault()));
+	} catch (InstallException e) {
+		// Do nothing
+	}
+	final char[] className = "CodeSnippetCompletion".toCharArray(); //$NON-NLS-1$
+	final long complianceVersion = CompilerOptions.versionToJdkLevel(options.get(JavaCore.COMPILER_COMPLIANCE));
+	final CodeSnippetToCuMapper mapper = new CodeSnippetToCuMapper(
+		codeSnippet,
+		this.packageName,
+		this.imports,
+		className,
+		this.installedVars == null ? null : this.installedVars.className,
+		this.localVariableNames,
+		this.localVariableTypeNames,
+		this.localVariableModifiers,
+		this.declaringTypeName,
+		this.lineSeparator,
+		complianceVersion
+	);
+	ICompilationUnit sourceUnit = new ICompilationUnit() {
+		public char[] getFileName() {
+			return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
+		}
+		public char[] getContents() {
+			return mapper.getCUSource(EvaluationContext.this.lineSeparator);
+		}
+		public char[] getMainTypeName() {
+			return className;
+		}
+		public char[][] getPackageName() {
+			return null;
+		}
+		public boolean ignoreOptionalProblems() {
+			return false;
+		}
+	};
+
+	CompletionEngine engine = new CompletionEngine(environment, mapper.getCompletionRequestor(requestor), options, project, owner, monitor);
+
+	if (this.installedVars != null) {
+		IBinaryType binaryType = getRootCodeSnippetBinary();
+		if (binaryType != null) {
+			engine.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
+		}
+
+		ClassFile[] classFiles = this.installedVars.classFiles;
+		for (int i = 0; i < classFiles.length; i++) {
+			ClassFile classFile = classFiles[i];
+			IBinaryType binary = null;
+			try {
+				binary = new ClassFileReader(classFile.getBytes(), null);
+			} catch (ClassFormatException e) {
+				e.printStackTrace(); // Should never happen since we compiled this type
+			}
+			engine.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
+		}
+	}
+
+	engine.complete(sourceUnit, mapper.startPosOffset + completionPosition, mapper.startPosOffset, null/*extended context isn't computed*/);
+}
+/**
+ * Deletes the given variable from this evaluation context. This will take effect in the target VM only
+ * the next time global variables are installed.
+ */
+public void deleteVariable(GlobalVariable variable) {
+	GlobalVariable[] vars = this.variables;
+	int index = -1;
+	for (int i = 0; i < this.variableCount; i++) {
+		if (vars[i].equals(variable)) {
+			index = i;
+			break;
+		}
+	}
+	if (index == -1) {
+		return;
+	}
+	int elementCount = this.variableCount--;
+	int j = elementCount - index - 1;
+	if (j > 0) {
+	    System.arraycopy(vars, index + 1, vars, index, j);
+	}
+	vars[elementCount - 1] = null;
+	this.varsChanged = true;
+}
+private void deployCodeSnippetClassIfNeeded(IRequestor requestor) throws InstallException {
+	if (this.codeSnippetBinary == null) {
+		// Deploy CodeSnippet class (only once)
+		if (!requestor.acceptClassFiles(
+			new ClassFile[] {
+				new ClassFile() {
+					public byte[] getBytes() {
+						return getCodeSnippetBytes();
+					}
+					public char[][] getCompoundName() {
+						return EvaluationConstants.ROOT_COMPOUND_NAME;
+					}
+				}
+			},
+			null))
+				throw new InstallException();
+	}
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
+ */
+public void evaluate(
+	char[] codeSnippet,
+	char[][] contextLocalVariableTypeNames,
+	char[][] contextLocalVariableNames,
+	int[] contextLocalVariableModifiers,
+	char[] contextDeclaringTypeName,
+	boolean contextIsStatic,
+	boolean contextIsConstructorCall,
+	INameEnvironment environment,
+	Map options,
+	final IRequestor requestor,
+	IProblemFactory problemFactory) throws InstallException {
+
+	// Initialialize context
+	this.localVariableTypeNames = contextLocalVariableTypeNames;
+	this.localVariableNames = contextLocalVariableNames;
+	this.localVariableModifiers = contextLocalVariableModifiers;
+	this.declaringTypeName = contextDeclaringTypeName;
+	this.isStatic = contextIsStatic;
+	this.isConstructorCall = contextIsConstructorCall;
+
+	deployCodeSnippetClassIfNeeded(requestor);
+
+	try {
+		// Install new variables if needed
+		class ForwardingRequestor implements IRequestor {
+			boolean hasErrors = false;
+			public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
+				return requestor.acceptClassFiles(classFiles, codeSnippetClassName);
+			}
+			public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
+				requestor.acceptProblem(problem, fragmentSource, fragmentKind);
+				if (problem.isError()) {
+					this.hasErrors = true;
+				}
+			}
+		}
+		ForwardingRequestor forwardingRequestor = new ForwardingRequestor();
+		if (this.varsChanged) {
+			evaluateVariables(environment, options, forwardingRequestor, problemFactory);
+		}
+
+		// Compile code snippet if there was no errors while evaluating the variables
+		if (!forwardingRequestor.hasErrors) {
+			Evaluator evaluator =
+				new CodeSnippetEvaluator(
+					codeSnippet,
+					this,
+					environment,
+					options,
+					requestor,
+					problemFactory);
+			ClassFile[] classes = evaluator.getClasses();
+			// Send code snippet on target
+			if (classes != null && classes.length > 0) {
+				char[] simpleClassName = evaluator.getClassName();
+				char[] pkgName = getPackageName();
+				char[] qualifiedClassName =
+					pkgName.length == 0 ?
+						simpleClassName :
+						CharOperation.concat(pkgName, simpleClassName, '.');
+				CODE_SNIPPET_COUNTER++;
+				if (!requestor.acceptClassFiles(classes, qualifiedClassName))
+					throw new InstallException();
+			}
+		}
+	} finally {
+		// Reinitialize context to default values
+		this.localVariableTypeNames = null;
+		this.localVariableNames = null;
+		this.localVariableModifiers = null;
+		this.declaringTypeName = null;
+		this.isStatic = true;
+		this.isConstructorCall = false;
+	}
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
+ */
+public void evaluate(char[] codeSnippet, INameEnvironment environment, Map options, final IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
+	this.evaluate(
+		codeSnippet,
+		null,
+		null,
+		null,
+		null,
+		true,
+		false,
+		environment,
+		options,
+		requestor,
+		problemFactory);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ */
+public void evaluateImports(INameEnvironment environment, IRequestor requestor, IProblemFactory problemFactory) {
+	for (int i = 0; i < this.imports.length; i++) {
+		CategorizedProblem[] problems = new CategorizedProblem[] {null};
+		char[] importDeclaration = this.imports[i];
+		char[][] splitDeclaration = CharOperation.splitOn('.', importDeclaration);
+		int splitLength = splitDeclaration.length;
+		if (splitLength > 0) {
+			char[] pkgName = splitDeclaration[splitLength - 1];
+			if (pkgName.length == 1 && pkgName[0] == '*') {
+				char[][] parentName;
+				switch (splitLength) {
+					case 1:
+						parentName = null;
+						break;
+					case 2:
+						parentName = null;
+						pkgName = splitDeclaration[splitLength - 2];
+						break;
+					default:
+						parentName = CharOperation.subarray(splitDeclaration, 0, splitLength - 2);
+						pkgName = splitDeclaration[splitLength - 2];
+				}
+				if (!environment.isPackage(parentName, pkgName)) {
+					String[] arguments = new String[] {new String(importDeclaration)};
+					problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
+				}
+			} else {
+				if (environment.findType(splitDeclaration) == null) {
+					String[] arguments = new String[] {new String(importDeclaration)};
+					problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
+				}
+			}
+		} else {
+			String[] arguments = new String[] {new String(importDeclaration)};
+			problems[0] = problemFactory.createProblem(importDeclaration, IProblem.ImportNotFound, arguments, arguments, ProblemSeverities.Warning, 0, importDeclaration.length - 1, i, 0);
+		}
+		if (problems[0] != null) {
+			requestor.acceptProblem(problems[0], importDeclaration, EvaluationResult.T_IMPORT);
+		}
+	}
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
+ * @exception java.lang.IllegalArgumentException if the global has not been installed yet.
+ */
+public void evaluateVariable(GlobalVariable variable, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
+	this.evaluate(variable.getName(), environment, options, requestor, problemFactory);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext
+ * @exception org.eclipse.jdt.internal.eval.InstallException if the code snippet class files could not be deployed.
+ */
+public void evaluateVariables(INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) throws InstallException {
+	deployCodeSnippetClassIfNeeded(requestor);
+	VariablesEvaluator evaluator = new VariablesEvaluator(this, environment, options, requestor, problemFactory);
+	ClassFile[] classes = evaluator.getClasses();
+	if (classes != null) {
+		if (classes.length > 0) {
+			// Sort classes so that enclosing types are cached before nested types
+			// otherwise an AbortCompilation is thrown in 1.5 mode since the enclosing type
+			// is needed to resolve a nested type
+			Util.sort(classes, new Util.Comparer() {
+				public int compare(Object a, Object b) {
+					if (a == b) return 0;
+					ClassFile enclosing = ((ClassFile) a).enclosingClassFile;
+					while (enclosing != null) {
+						if (enclosing == b)
+							return 1;
+						enclosing = enclosing.enclosingClassFile;
+					}
+					return -1;
+				}
+			});
+
+			// Send classes
+			if (!requestor.acceptClassFiles(classes, null)) {
+				throw new InstallException();
+			}
+
+			// Remember that the variables have been installed
+			int count = this.variableCount;
+			GlobalVariable[] variablesCopy = new GlobalVariable[count];
+			System.arraycopy(this.variables, 0, variablesCopy, 0, count);
+			this.installedVars = new VariablesInfo(evaluator.getPackageName(), evaluator.getClassName(), classes, variablesCopy, count);
+			VAR_CLASS_COUNTER++;
+		}
+		this.varsChanged = false;
+	}
+}
+/**
+ * Returns the bytes of the CodeSnippet class.
+ * Generated using the following code snippet:
+[java.io.BufferedWriter writer = new java.io.BufferedWriter(new java.io.FileWriter("d:/temp/CodeSnippet.java"));
+writer.write(org.eclipse.jdt.internal.eval.EvaluationContext.getCodeSnippetSource());
+writer.close();
+org.eclipse.jdt.internal.compiler.batch.Main.compile(
+	"d:/temp/CodeSnippet.java -d d:/temp -classpath d:/jdk1.2.2/jre/lib/rt.jar -verbose");
+java.io.FileInputStream reader =  new java.io.FileInputStream("d:/temp/org/eclipse/jdt/internal/eval/target/CodeSnippet.class");
+byte[] bytes = org.eclipse.jdt.internal.core.Util.readContentsAsBytes(reader);
+reader.close();
+StringBuffer buffer = new StringBuffer();
+buffer.append("private byte[] getCodeSnippetBytes() {\n");
+buffer.append("	return new byte[] {\n");
+buffer.append("		");
+for (int i = 0; i < bytes.length; i++) {
+	buffer.append(bytes[i]);
+	if (i == bytes.length - 1) {
+		buffer.append("\n");
+	} else {
+		buffer.append(", ");
+	}
+}
+buffer.append("	};\n");
+buffer.append("}");
+buffer.toString()
+]
+ */
+byte[] getCodeSnippetBytes() {
+	return new byte[] {
+		-54, -2, -70, -66, 0, 3, 0, 45, 0, 35, 1, 0, 48, 111, 114, 103, 47, 101, 99, 108, 105, 112, 115, 101, 47, 106, 100, 116, 47, 105, 110, 116, 101, 114, 110, 97, 108, 47, 101, 118, 97, 108, 47, 116, 97, 114, 103, 101, 116, 47, 67, 111, 100, 101, 83, 110, 105, 112, 112, 101, 116, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 7, 0, 3, 1, 0, 10, 114, 101, 115, 117, 108, 116, 84, 121, 112, 101, 1, 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 1, 0, 11, 114, 101, 115, 117, 108, 116, 86, 97, 108, 117, 101, 1, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 1, 0, 7, 99, 108, 97, 115, 115, 36, 48, 1, 0, 9, 83, 121, 110, 116, 104, 101, 116, 105, 99, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 12, 0, 11, 0, 12, 10, 0, 4, 0, 14, 1, 0, 14, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 86, 111, 105, 100, 7, 0, 16, 1, 0, 4, 84, 89, 80, 69, 12, 0, 18, 0, 6, 9, 0, 17, 0, 19, 12, 0, 5, 0, 6, 9, 0, 2, 0, 21, 12, 0, 7, 0, 8, 9, 0, 2, 0, 23, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 13, 103, 101, 116, 82, 101, 115, 117, 108, 116, 84, 121, 112, 101, 1, 0, 19, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 1, 0, 14, 103, 101, 116, 82, 101, 115, 117, 108, 116, 86, 97, 108, 117, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 1, 0, 3, 114, 117, 110, 1, 0, 9, 115, 101, 116, 82, 101, 115, 117, 108, 116, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 41, 86, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 67, 111, 100, 101, 83, 110, 105, 112, 112, 101, 116, 46, 106, 97, 118, 97, 0, 33, 0, 2, 0, 4, 0, 0, 0, 3, 0, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 7, 0, 8, 0, 0, 0, 8, 0, 9, 0, 6, 0, 1, 0, 10, 0, 0, 0, 0, 0, 5, 0, 1, 0, 11, 0, 12, 0, 1, 0, 13, 0, 0, 0, 53, 0, 2, 0, 1, 0, 0, 0, 17, 42, -73, 0, 15, 42, -78, 0, 20, -75, 0, 22, 42, 1, -75, 0, 24, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 18, 0, 4, 0, 0, 0, 17, 0, 4, 0, 18, 0, 11, 0, 19, 0, 16, 0, 17, 0, 1, 0, 26, 0, 27, 0, 1, 0, 13, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -76, 0, 22, -80, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 24, 0, 1, 0, 28, 0, 29, 0, 1, 0, 13, 0, 0, 0, 29, 0, 1, 0, 1, 0, 0, 0, 5, 42, -76, 0, 24, -80, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 30, 0, 1, 0, 30, 0, 12, 0, 1, 0, 13, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 1, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 6, 0, 1, 0, 0, 0, 36, 0, 1, 0, 31, 0, 32, 0, 1, 0, 13, 0, 0, 0, 43, 0, 2, 0, 3, 0, 0, 0, 11, 42, 43, -75, 0, 24, 42, 44, -75, 0, 22, -79, 0, 0, 0, 1, 0, 25, 0, 0, 0, 14, 0, 3, 0, 0, 0, 42, 0, 5, 0, 43, 0, 10, 0, 41, 0, 1, 0, 33, 0, 0, 0, 2, 0, 34
+	};
+}
+/**
+ * Returns the source of the CodeSnippet class.
+ * This is used to generate the binary of the CodeSnippetClass
+ */
+public static String getCodeSnippetSource() {
+	return
+		"package org.eclipse.jdt.internal.eval.target;\n" + //$NON-NLS-1$
+		"\n" + //$NON-NLS-1$
+		"/*\n" + //$NON-NLS-1$
+		" * (c) Copyright IBM Corp. 2000, 2001.\n" + //$NON-NLS-1$
+		" * All Rights Reserved.\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"/**\n" + //$NON-NLS-1$
+		" * The root of all code snippet classes. Code snippet classes\n" + //$NON-NLS-1$
+		" * are supposed to overide the run() method.\n" + //$NON-NLS-1$
+		" * <p>\n" + //$NON-NLS-1$
+		" * IMPORTANT NOTE:\n" + //$NON-NLS-1$
+		" * All methods in this class must be public since this class is going to be loaded by the\n" + //$NON-NLS-1$
+		" * bootstrap class loader, and the other code snippet support classes might be loaded by \n" + //$NON-NLS-1$
+		" * another class loader (so their runtime packages are going to be different).\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"public class CodeSnippet {\n" + //$NON-NLS-1$
+		"	private Class resultType = void.class;\n" + //$NON-NLS-1$
+		"	private Object resultValue = null;\n" + //$NON-NLS-1$
+		"/**\n" + //$NON-NLS-1$
+		" * Returns the result type of the code snippet evaluation.\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"public Class getResultType() {\n" + //$NON-NLS-1$
+		"	return this.resultType;\n" + //$NON-NLS-1$
+		"}\n" + //$NON-NLS-1$
+		"/**\n" + //$NON-NLS-1$
+		" * Returns the result value of the code snippet evaluation.\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"public Object getResultValue() {\n" + //$NON-NLS-1$
+		"	return this.resultValue;\n" + //$NON-NLS-1$
+		"}\n" + //$NON-NLS-1$
+		"/**\n" + //$NON-NLS-1$
+		" * The code snippet. Subclasses must override this method with a transformed code snippet\n" + //$NON-NLS-1$
+		" * that stores the result using setResult(Class, Object).\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"public void run() {\n" + //$NON-NLS-1$
+		"}\n" + //$NON-NLS-1$
+		"/**\n" + //$NON-NLS-1$
+		" * Stores the result type and value of the code snippet evaluation.\n" + //$NON-NLS-1$
+		" */\n" + //$NON-NLS-1$
+		"public void setResult(Object someResultValue, Class someResultType) {\n" + //$NON-NLS-1$
+		"	this.resultValue = someResultValue;\n" + //$NON-NLS-1$
+		"	this.resultType = someResultType;\n" + //$NON-NLS-1$
+		"}\n" + //$NON-NLS-1$
+		"}\n"; //$NON-NLS-1$
+}
+/**
+ * Returns the imports of this evaluation context. An import is the name of a package
+ * or the fully qualified name of a type as defined in the import statement of
+ * a compilation unit.
+ */
+public char[][] getImports() {
+	return this.imports;
+}
+/**
+ * Returns the dot-separated name of the package code snippets are run into.
+ * Returns an empty array for the default package. This is the default if
+ * the package name has never been set.
+ */
+public char[] getPackageName() {
+	return this.packageName;
+}
+/**
+ * Return the binary for the root code snippet class (i.e. org.eclipse.jdt.internal.eval.target.CodeSnippet).
+ */
+IBinaryType getRootCodeSnippetBinary() {
+	if (this.codeSnippetBinary == null) {
+		this.codeSnippetBinary = new CodeSnippetSkeleton();
+	}
+	return this.codeSnippetBinary;
+}
+public char[] getVarClassName() {
+	if (this.installedVars == null) return CharOperation.NO_CHAR;
+	return CharOperation.concat(this.installedVars.packageName, this.installedVars.className, '.');
+}
+/**
+ * Creates a new global variable with the given name, type and initializer.
+ * If the variable is not initialized, the initializer can be null.
+ * Note that this doesn't install it to this evaluation context's VM.
+ *
+ * @see GlobalVariable
+ */
+public GlobalVariable newVariable(char[] typeName, char[] name, char[] initializer) {
+	GlobalVariable var = new GlobalVariable(typeName, name, initializer);
+	if (this.variableCount >= this.variables.length) // assume variables is never empty
+		System.arraycopy(this.variables, 0, this.variables = new GlobalVariable[this.variableCount * 2], 0, this.variableCount);
+	this.variables[this.variableCount++] = var;
+	this.varsChanged = true;
+	return var;
+}
+/**
+ * Computes the selection at the specified positions of the given code snippet.
+ * (Note that this evaluation context's VM doesn't need to be running.)
+ *  @param codeSnippet char[]
+ * 		The code snipper source
+ *
+ *  @param selectionSourceStart int
+ *
+ *  @param selectionSourceEnd int
+ *
+ *  @param environment org.eclipse.jdt.internal.core.SearchableEnvironment
+ *      used to resolve type/package references and search for types/packages
+ *      based on partial names.
+ *
+ *  @param requestor org.eclipse.jdt.internal.codeassist.ISelectionRequestor
+ *      since the engine might produce answers of various forms, the engine
+ *      is associated with a requestor able to accept all possible selections.
+ *
+ *  @param options java.util.Map
+ *		set of options used to configure the code assist engine.
+ */
+public void select(
+	char[] codeSnippet,
+	int selectionSourceStart,
+	int selectionSourceEnd,
+	SearchableEnvironment environment,
+	ISelectionRequestor requestor,
+	Map options,
+	WorkingCopyOwner owner) {
+
+	final char[] className = "CodeSnippetSelection".toCharArray(); //$NON-NLS-1$
+	final long complianceVersion = CompilerOptions.versionToJdkLevel(options.get(JavaCore.COMPILER_COMPLIANCE));
+	final CodeSnippetToCuMapper mapper = new CodeSnippetToCuMapper(
+		codeSnippet,
+		this.packageName,
+		this.imports,
+		className,
+		this.installedVars == null ? null : this.installedVars.className,
+		this.localVariableNames,
+		this.localVariableTypeNames,
+		this.localVariableModifiers,
+		this.declaringTypeName,
+		this.lineSeparator,
+		complianceVersion
+	);
+	ICompilationUnit sourceUnit = new ICompilationUnit() {
+		public char[] getFileName() {
+			return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
+		}
+		public char[] getContents() {
+			return mapper.getCUSource(EvaluationContext.this.lineSeparator);
+		}
+		public char[] getMainTypeName() {
+			return className;
+		}
+		public char[][] getPackageName() {
+			return null;
+		}
+		public boolean ignoreOptionalProblems() {
+			return false;
+		}
+	};
+	SelectionEngine engine = new SelectionEngine(environment, mapper.getSelectionRequestor(requestor), options, owner);
+	engine.select(sourceUnit, mapper.startPosOffset + selectionSourceStart, mapper.startPosOffset + selectionSourceEnd);
+}
+/**
+ * Sets the imports of this evaluation context. An import is the name of a package
+ * or the fully qualified name of a type as defined in the import statement of
+ * a compilation unit (see the Java Language Specifications for more details).
+ */
+public void setImports(char[][] imports) {
+	this.imports = imports;
+	this.varsChanged = true; // this may change the visibility of the variable's types
+}
+/**
+ * Sets the line separator used by this evaluation context.
+ */
+public void setLineSeparator(String lineSeparator) {
+	this.lineSeparator = lineSeparator;
+}
+/**
+ * Sets the dot-separated name of the package code snippets are ran into.
+ * The default package name is an empty array.
+ */
+public void setPackageName(char[] packageName) {
+	this.packageName = packageName;
+	this.varsChanged = true; // this may change the visibility of the variable's types
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java
new file mode 100644
index 0000000..c0828c3
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+/**
+ * An EvaluationResult is the result of a code snippet evaluation, a global
+ * variable evaluation or it is used to report problems against imports and
+ * package declaration.
+ * It primarily contains the representation of the resulting value (e.g. its
+ * toString() representation). However if the code snippet, a global variable
+ * definition, an import or the package declaration could not be compiled, it
+ * contains the corresponding compilation problems.
+ */
+public class EvaluationResult {
+
+	static final CategorizedProblem[] NO_PROBLEMS = new CategorizedProblem[0];
+
+	char[] evaluationID;
+	int evaluationType;
+	CategorizedProblem[] problems;
+	char[] displayString;
+	char[] typeName;
+
+	/**
+	 * The evaluation result contains the value of a variable or
+	 * it reports a problem on a variable. Note that if the problem is
+	 * on the type of the variable, the source line number is -1. If the
+	 * problem is on the name of the variable, the source line number is 0.
+	 * Otherwise the source line number is relative to the initializer code.
+	 */
+	public static final int T_VARIABLE = 1;
+
+	/**
+	 * The evaluation result contains the value of a code snippet or
+	 * it reports a problem on a code snippet.
+	 */
+	public static final int T_CODE_SNIPPET = 2;
+
+	/**
+	 * The evaluation result reports a problem on an import declaration.
+	 */
+	public static final int T_IMPORT = 3;
+
+	/**
+	 * The evaluation result reports a problem on a package declaration.
+	 */
+	public static final int T_PACKAGE = 4;
+
+	/**
+	 * The evaluation result reports an internal problem.
+	 */
+	public static final int T_INTERNAL = 5;
+
+public EvaluationResult(char[] evaluationID, int evaluationType, char[] displayString, char[] typeName) {
+	this.evaluationID = evaluationID;
+	this.evaluationType = evaluationType;
+	this.displayString = displayString;
+	this.typeName = typeName;
+	this.problems = NO_PROBLEMS;
+}
+public EvaluationResult(char[] evaluationID, int evaluationType, CategorizedProblem[] problems) {
+	this.evaluationID = evaluationID;
+	this.evaluationType = evaluationType;
+	this.problems = problems;
+}
+/**
+ * Adds the given problem to the list of problems of this evaluation result.
+ */
+void addProblem(CategorizedProblem problem) {
+	CategorizedProblem[] existingProblems = this.problems;
+	int existingLength = existingProblems.length;
+	this.problems = new CategorizedProblem[existingLength + 1];
+	System.arraycopy(existingProblems, 0, this.problems, 0, existingLength);
+	this.problems[existingLength] = problem;
+}
+/**
+ * Returns the ID of the evaluation.
+ * If the result is about a global variable, returns the name of the variable.
+ * If the result is about a code snippet, returns the code snippet.
+ * If the result is about an import, returns the import.
+ * If the result is about a package declaration, returns the package declaration.
+ */
+public char[] getEvaluationID() {
+	return this.evaluationID;
+}
+/**
+ * Returns the type of evaluation this result is about.
+ * This indicates if the result is about a global variable,
+ * a code snippet, an import or a package declaration.
+ * Use getEvaluationID() to get the object itself.
+ */
+public int getEvaluationType() {
+	return this.evaluationType;
+}
+/**
+ * Returns an array of problems (errors and warnings) encountered
+ * during the compilation of a code snippet or a global variable definition,
+ * or during the analysis of a package name or an import.
+ * Returns an empty array if there are no problems.
+ */
+public CategorizedProblem[] getProblems() {
+	return this.problems;
+}
+/**
+ * Returns a proxy object on this result's value.
+ * Returns null if the result's value is null.
+ * The returned value is undefined if there is no result.
+ * The proxy object is expected to answer questions like:
+ *   - What is the proxy type for this object?
+ *	 - What is the toString() representation for this object?
+ *   - What are the field names of this object?
+ *   - What is the value for a given field name?
+ * Special proxy objects are expected if the value is a primitive type.
+ */
+public Object getValue() {
+	return null; // Not yet implemented
+}
+/**
+ * Returns the displayable representation of this result's value.
+ * This is obtained by sending toString() to the result object on the target side
+ * if it is not a primitive value. If it is a primitive value, the corresponding
+ * static toString(...) is used, e.g. Integer.toString(int n) if it is an int.
+ * Returns null if there is no value.
+ */
+public char[] getValueDisplayString() {
+	return this.displayString;
+}
+/**
+ * Returns the dot-separated fully qualified name of this result's value type.
+ * If the value is a primitive value, returns the toString() representation of its type
+ * (e.g. "int", "boolean", etc.)
+ * Returns null if there is no value.
+ */
+public char[] getValueTypeName() {
+	return this.typeName;
+}
+/**
+ * Returns whether there are errors in the code snippet or the global variable definition.
+ */
+public boolean hasErrors() {
+	if (this.problems == null) {
+		return false;
+	} else {
+		for (int i = 0; i < this.problems.length; i++) {
+			if (this.problems[i].isError()) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
+/**
+ * Returns whether there are problems in the code snippet or the global variable definition.
+ */
+public boolean hasProblems() {
+	return (this.problems != null) && (this.problems.length != 0);
+}
+/**
+ * Returns whether this result has a value.
+ */
+public boolean hasValue() {
+	return this.displayString != null;
+}
+/**
+ * Returns whether there are warnings in the code snippet or the global variable definition.
+ */
+public boolean hasWarnings() {
+	if (this.problems == null) {
+		return false;
+	} else {
+		for (int i = 0; i < this.problems.length; i++) {
+			if (this.problems[i].isWarning()) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
+/**
+ * Returns a readable representation of this result.
+ * This is for debugging purpose only.
+ */
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	switch (this.evaluationType) {
+		case T_CODE_SNIPPET:
+			buffer.append("Code snippet"); //$NON-NLS-1$
+			break;
+		case T_IMPORT:
+			buffer.append("Import"); //$NON-NLS-1$
+			break;
+		case T_INTERNAL:
+			buffer.append("Internal problem"); //$NON-NLS-1$
+			break;
+		case T_PACKAGE:
+			buffer.append("Package"); //$NON-NLS-1$
+			break;
+		case T_VARIABLE:
+			buffer.append("Global variable"); //$NON-NLS-1$
+			break;
+	}
+	buffer.append(": "); //$NON-NLS-1$
+	buffer.append(this.evaluationID == null ? "<unknown>".toCharArray() : this.evaluationID);  //$NON-NLS-1$
+	buffer.append("\n"); //$NON-NLS-1$
+	if (hasProblems()) {
+		buffer.append("Problems:\n"); //$NON-NLS-1$
+		for (int i = 0; i < this.problems.length; i++) {
+			buffer.append(this.problems[i].toString());
+		}
+	} else {
+		if (hasValue()) {
+			buffer.append("("); //$NON-NLS-1$
+			buffer.append(this.typeName);
+			buffer.append(") "); //$NON-NLS-1$
+			buffer.append(this.displayString);
+		} else {
+			buffer.append("(No explicit return value)"); //$NON-NLS-1$
+		}
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java
new file mode 100644
index 0000000..de07b66
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A evaluator builds a compilation unit and compiles it into class files.
+ * If the compilation unit has problems, reports the problems using the
+ * requestor.
+ */
+public abstract class Evaluator {
+	EvaluationContext context;
+	INameEnvironment environment;
+	Map options;
+	IRequestor requestor;
+	IProblemFactory problemFactory;
+/**
+ * Creates a new evaluator.
+ */
+Evaluator(EvaluationContext context, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) {
+	this.context = context;
+	this.environment = environment;
+	this.options = options;
+	this.requestor = requestor;
+	this.problemFactory = problemFactory;
+}
+/**
+ * Adds the given problem to the corresponding evaluation result in the given table. If the evaluation
+ * result doesn't exist yet, adds it in the table. Its evaluation id and evaluation type
+ * are computed so that they correspond to the given problem. If it is found to be an internal problem,
+ * then the evaluation id of the result is the given compilation unit source.
+ */
+protected abstract void addEvaluationResultForCompilationProblem(Map resultsByIDs,CategorizedProblem problem, char[] cuSource);
+/**
+ * Returns the evaluation results that converts the given compilation result that has problems.
+ * If the compilation result has more than one problem, then the problems are broken down so that
+ * each evaluation result has the same evaluation id.
+ */
+protected EvaluationResult[] evaluationResultsForCompilationProblems(CompilationResult result, char[] cuSource) {
+	// Break down the problems and group them by ids in evaluation results
+	CategorizedProblem[] problems = result.getAllProblems();
+	HashMap resultsByIDs = new HashMap(5);
+	for (int i = 0; i < problems.length; i++) {
+		addEvaluationResultForCompilationProblem(resultsByIDs, problems[i], cuSource);
+	}
+
+	// Copy results
+	int size = resultsByIDs.size();
+	EvaluationResult[] evalResults = new EvaluationResult[size];
+	Iterator results = resultsByIDs.values().iterator();
+	for (int i = 0; i < size; i++) {
+		evalResults[i] = (EvaluationResult)results.next();
+	}
+
+	return evalResults;
+}
+/**
+ * Compiles and returns the class definitions for the current compilation unit.
+ * Returns null if there are any errors.
+ */
+ClassFile[] getClasses() {
+	final char[] source = getSource();
+	final ArrayList classDefinitions = new ArrayList();
+
+	// The requestor collects the class definitions and problems
+	class CompilerRequestor implements ICompilerRequestor {
+		boolean hasErrors = false;
+		public void acceptResult(CompilationResult result) {
+			if (result.hasProblems()) {
+				EvaluationResult[] evalResults = evaluationResultsForCompilationProblems(result, source);
+				for (int i = 0; i < evalResults.length; i++) {
+					EvaluationResult evalResult = evalResults[i];
+					CategorizedProblem[] problems = evalResult.getProblems();
+					for (int j = 0; j < problems.length; j++) {
+						Evaluator.this.requestor.acceptProblem(problems[j], evalResult.getEvaluationID(), evalResult.getEvaluationType());
+					}
+				}
+			}
+			if (result.hasErrors()) {
+				this.hasErrors = true;
+			} else {
+				ClassFile[] classFiles = result.getClassFiles();
+				for (int i = 0; i < classFiles.length; i++) {
+					ClassFile classFile = classFiles[i];
+/*
+
+					char[] filename = classFile.fileName();
+					int length = filename.length;
+					char[] relativeName = new char[length + 6];
+					System.arraycopy(filename, 0, relativeName, 0, length);
+					System.arraycopy(".class".toCharArray(), 0, relativeName, length, 6);
+					CharOperation.replace(relativeName, '/', java.io.File.separatorChar);
+					ClassFile.writeToDisk("d:/test/snippet", new String(relativeName), classFile.getBytes());
+					String str = "d:/test/snippet" + "/" + new String(relativeName);
+					System.out.println(org.eclipse.jdt.core.tools.classfmt.disassembler.ClassFileDisassembler.disassemble(str));
+ */
+					classDefinitions.add(classFile);
+				}
+			}
+		}
+	}
+
+	// Compile compilation unit
+	CompilerRequestor compilerRequestor = new CompilerRequestor();
+	Compiler compiler = getCompiler(compilerRequestor);
+	compiler.compile(new ICompilationUnit[] {new ICompilationUnit() {
+		public char[] getFileName() {
+			 // Name of class is name of CU
+			return CharOperation.concat(Evaluator.this.getClassName(), Util.defaultJavaExtension().toCharArray());
+		}
+		public char[] getContents() {
+			return source;
+		}
+		public char[] getMainTypeName() {
+			return Evaluator.this.getClassName();
+		}
+		public char[][] getPackageName() {
+			return null;
+		}
+		public boolean ignoreOptionalProblems() {
+			return false;
+		}
+	}});
+	if (compilerRequestor.hasErrors) {
+		return null;
+	} else {
+		ClassFile[] result = new ClassFile[classDefinitions.size()];
+		classDefinitions.toArray(result);
+		return result;
+	}
+}
+/**
+ * Returns the name of the current class. This is the simple name of the class.
+ * This doesn't include the extension ".java" nor the name of the package.
+ */
+protected abstract char[] getClassName();
+/**
+ * Creates and returns a compiler for this evaluator.
+ */
+Compiler getCompiler(ICompilerRequestor compilerRequestor) {
+	CompilerOptions compilerOptions = new CompilerOptions(this.options);
+	compilerOptions.performMethodsFullRecovery = true;
+	compilerOptions.performStatementsRecovery = true;
+	return new Compiler(
+		this.environment,
+		DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+		compilerOptions,
+		compilerRequestor,
+		this.problemFactory);
+}
+/**
+ * Builds and returns the source for the current compilation unit.
+ */
+protected abstract char[] getSource();
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java
new file mode 100644
index 0000000..4b28df4
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+/**
+ * A global variable is a variable defined for an evaluation context and that persists
+ * accross evaluations.
+ */
+public class GlobalVariable {
+	char[] typeName;
+	char[] name;
+	char[] initializer;
+	int declarationStart = -1, initializerStart = -1, initExpressionStart; // positions in the global variable class definition
+	int initializerLineStart = -1; // line in the global variable class definition
+/**
+ * Creates a new global variable with the given type name, name and initializer.
+ * initializer can be null if there is none.
+ */
+public GlobalVariable(char[] typeName, char[] name, char[] initializer) {
+	this.typeName = typeName;
+	this.name = name;
+	this.initializer = initializer;
+}
+/**
+ * Returns the initializer of this global variable. The initializer is a
+ * variable initializer (i.e. an expression or an array initializer) as defined
+ * in the Java Language Specifications.
+ */
+public char[] getInitializer() {
+	return this.initializer;
+}
+/**
+ * Returns the name of this global variable.
+ */
+public char[] getName() {
+	return this.name;
+}
+/**
+ * Returns the dot separated fully qualified name of the type of this global variable,
+ * or its simple representation if it is a primitive type (e.g. int, boolean, etc.)
+ */
+public char[] getTypeName() {
+	return this.typeName;
+}
+/**
+ * Returns a readable representation of the receiver.
+ * This is for debugging purpose only.
+ */
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(this.typeName);
+	buffer.append(" "); //$NON-NLS-1$
+	buffer.append(this.name);
+	if (this.initializer != null) {
+		buffer.append("= "); //$NON-NLS-1$
+		buffer.append(this.initializer);
+	}
+	buffer.append(";"); //$NON-NLS-1$
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java
new file mode 100644
index 0000000..3a529e5
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+
+/**
+ * A callback interface for receiving code snippet evaluation results.
+ */
+public interface IRequestor {
+/**
+ * @see org.eclipse.jdt.core.eval.ICodeSnippetRequestor
+ */
+boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName);
+/**
+ * @see org.eclipse.jdt.core.eval.ICodeSnippetRequestor
+ */
+void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind);
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java
new file mode 100644
index 0000000..6774606
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+/**
+ * A <code>InstallException</code> is thrown when installing class files on a target has failed
+ * for any reason.
+ */
+public class InstallException extends Exception {
+
+	private static final long serialVersionUID = -5870897747810654203L;	// backward compatible
+/**
+ * Constructs a <code>InstallException</code> with no detail  message.
+ */
+public InstallException() {
+	super();
+}
+/**
+ * Constructs a <code>InstallException</code> with the specified
+ * detail message.
+ *
+ * @param   s   the detail message.
+ */
+public InstallException(String s) {
+	super(s);
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
new file mode 100644
index 0000000..f9cb137
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+
+/**
+ * A variables evaluator compiles the global variables of an evaluation context and returns
+ * the corresponding class files. Or it reports problems against these variables.
+ */
+public class VariablesEvaluator extends Evaluator implements EvaluationConstants {
+/**
+ * Creates a new global variables evaluator.
+ */
+VariablesEvaluator(EvaluationContext context, INameEnvironment environment, Map options, IRequestor requestor, IProblemFactory problemFactory) {
+	super(context, environment, options, requestor, problemFactory);
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected void addEvaluationResultForCompilationProblem(Map resultsByIDs, CategorizedProblem problem, char[] cuSource) {
+	// set evaluation id and type to an internal problem by default
+	char[] evaluationID = cuSource;
+	int evaluationType = EvaluationResult.T_INTERNAL;
+
+	int pbLine = problem.getSourceLineNumber();
+	int currentLine = 1;
+
+	// check package declaration
+	char[] packageName = getPackageName();
+	if (packageName.length > 0) {
+		if (pbLine == 1) {
+			// set evaluation id and type
+			evaluationID = packageName;
+			evaluationType = EvaluationResult.T_PACKAGE;
+
+			// shift line number, source start and source end
+			problem.setSourceLineNumber(1);
+			problem.setSourceStart(0);
+			problem.setSourceEnd(evaluationID.length - 1);
+		}
+		currentLine++;
+	}
+
+	// check imports
+	char[][] imports = this.context.imports;
+	if ((currentLine <= pbLine) && (pbLine < (currentLine + imports.length))) {
+		// set evaluation id and type
+		evaluationID = imports[pbLine - currentLine];
+		evaluationType = EvaluationResult.T_IMPORT;
+
+		// shift line number, source start and source end
+		problem.setSourceLineNumber(1);
+		problem.setSourceStart(0);
+		problem.setSourceEnd(evaluationID.length - 1);
+	}
+	currentLine += imports.length + 1; // + 1 to skip the class declaration line
+
+	// check variable declarations
+	int varCount = this.context.variableCount;
+	if ((currentLine <= pbLine) && (pbLine < currentLine + varCount)) {
+		GlobalVariable var = this.context.variables[pbLine - currentLine];
+
+		// set evaluation id and type
+		evaluationID = var.getName();
+		evaluationType = EvaluationResult.T_VARIABLE;
+
+		// shift line number, source start and source end
+		int pbStart = problem.getSourceStart() - var.declarationStart;
+		int pbEnd = problem.getSourceEnd() - var.declarationStart;
+		int typeLength = var.getTypeName().length;
+		if ((0 <= pbStart) && (pbEnd < typeLength)) {
+			// problem on the type of the variable
+			problem.setSourceLineNumber(-1);
+		} else {
+			// problem on the name of the variable
+			pbStart -= typeLength + 1; // type length + space
+			pbEnd -= typeLength + 1; // type length + space
+			problem.setSourceLineNumber(0);
+		}
+		problem.setSourceStart(pbStart);
+		problem.setSourceEnd(pbEnd);
+	}
+	currentLine = -1; // not needed any longer
+
+	// check variable initializers
+	for (int i = 0; i < varCount; i++) {
+		GlobalVariable var = this.context.variables[i];
+		char[] initializer = var.getInitializer();
+		int initializerLength = initializer == null ? 0 : initializer.length;
+		if ((var.initializerStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initializerStart + var.name.length)) {
+			/* Problem with the variable name.
+			   Ignore because it must have already been reported
+			   when checking the declaration.
+			 */
+			return;
+		} else if ((var.initExpressionStart <= problem.getSourceStart()) && (problem.getSourceEnd() < var.initExpressionStart + initializerLength)) {
+			// set evaluation id and type
+			evaluationID = var.name;
+			evaluationType = EvaluationResult.T_VARIABLE;
+
+			// shift line number, source start and source end
+			problem.setSourceLineNumber(pbLine - var.initializerLineStart + 1);
+			problem.setSourceStart(problem.getSourceStart() - var.initExpressionStart);
+			problem.setSourceEnd(problem.getSourceEnd() - var.initExpressionStart);
+
+			break;
+		}
+	}
+
+	EvaluationResult result = (EvaluationResult)resultsByIDs.get(evaluationID);
+	if (result == null) {
+		resultsByIDs.put(evaluationID, new EvaluationResult(evaluationID, evaluationType, new CategorizedProblem[] {problem}));
+	} else {
+		result.addProblem(problem);
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected char[] getClassName() {
+	return CharOperation.concat(EvaluationConstants.GLOBAL_VARS_CLASS_NAME_PREFIX, Integer.toString(EvaluationContext.VAR_CLASS_COUNTER + 1).toCharArray());
+}
+/**
+ * Creates and returns a compiler for this evaluator.
+ */
+Compiler getCompiler(ICompilerRequestor compilerRequestor) {
+	Compiler compiler = super.getCompiler(compilerRequestor);
+
+	// Initialize the compiler's lookup environment with the already compiled super class
+	IBinaryType binaryType = this.context.getRootCodeSnippetBinary();
+	if (binaryType != null) {
+		compiler.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
+	}
+
+	// and the installed global variable classes
+	VariablesInfo installedVars = this.context.installedVars;
+	if (installedVars != null) {
+		ClassFile[] classFiles = installedVars.classFiles;
+		for (int i = 0; i < classFiles.length; i++) {
+			ClassFile classFile = classFiles[i];
+			IBinaryType binary = null;
+			try {
+				binary = new ClassFileReader(classFile.getBytes(), null);
+			} catch (ClassFormatException e) {
+				e.printStackTrace(); // Should never happen since we compiled this type
+			}
+			compiler.lookupEnvironment.cacheBinaryType(binary, null /*no access restriction*/);
+		}
+	}
+
+	return compiler;
+}
+/**
+ * Returns the name of package of the current compilation unit.
+ */
+protected char[] getPackageName() {
+	return this.context.packageName;
+}
+/**
+ * @see org.eclipse.jdt.internal.eval.Evaluator
+ */
+protected char[] getSource() {
+	StringBuffer buffer = new StringBuffer();
+	int lineNumberOffset = 1;
+
+	// package declaration
+	char[] packageName = getPackageName();
+	if (packageName.length != 0) {
+		buffer.append("package "); //$NON-NLS-1$
+		buffer.append(packageName);
+		buffer.append(';').append(this.context.lineSeparator);
+		lineNumberOffset++;
+	}
+
+	// import declarations
+	char[][] imports = this.context.imports;
+	for (int i = 0; i < imports.length; i++) {
+		buffer.append("import "); //$NON-NLS-1$
+		buffer.append(imports[i]);
+		buffer.append(';').append(this.context.lineSeparator);
+		lineNumberOffset++;
+	}
+
+	// class declaration
+	buffer.append("public class "); //$NON-NLS-1$
+	buffer.append(getClassName());
+	buffer.append(" extends "); //$NON-NLS-1$
+	buffer.append(PACKAGE_NAME);
+	buffer.append("."); //$NON-NLS-1$
+	buffer.append(ROOT_CLASS_NAME);
+	buffer.append(" {").append(this.context.lineSeparator); //$NON-NLS-1$
+	lineNumberOffset++;
+
+	// field declarations
+	GlobalVariable[] vars = this.context.variables;
+	VariablesInfo installedVars = this.context.installedVars;
+	for (int i = 0; i < this.context.variableCount; i++){
+		GlobalVariable var = vars[i];
+		buffer.append("\tpublic static "); //$NON-NLS-1$
+		var.declarationStart = buffer.length();
+		buffer.append(var.typeName);
+		buffer.append(" "); //$NON-NLS-1$
+		char[] varName = var.name;
+		buffer.append(varName);
+		buffer.append(';').append(this.context.lineSeparator);
+		lineNumberOffset++;
+	}
+
+	// field initializations
+	buffer.append("\tstatic {").append(this.context.lineSeparator); //$NON-NLS-1$
+	lineNumberOffset++;
+	for (int i = 0; i < this.context.variableCount; i++){
+		GlobalVariable var = vars[i];
+		char[] varName = var.name;
+		GlobalVariable installedVar = installedVars == null ? null : installedVars.varNamed(varName);
+		if (installedVar == null || !CharOperation.equals(installedVar.typeName, var.typeName)) {
+			// Initialize with initializer if there was no previous value
+			char[] initializer = var.initializer;
+			if (initializer != null) {
+				buffer.append("\t\ttry {").append(this.context.lineSeparator); //$NON-NLS-1$
+				lineNumberOffset++;
+				var.initializerLineStart = lineNumberOffset;
+				buffer.append("\t\t\t"); //$NON-NLS-1$
+				var.initializerStart = buffer.length();
+				buffer.append(varName);
+				buffer.append("= "); //$NON-NLS-1$
+				var.initExpressionStart = buffer.length();
+				buffer.append(initializer);
+				lineNumberOffset += numberOfCRs(initializer);
+				buffer.append(';').append(this.context.lineSeparator);
+				buffer.append("\t\t} catch (Throwable e) {").append(this.context.lineSeparator); //$NON-NLS-1$
+				buffer.append("\t\t\te.printStackTrace();").append(this.context.lineSeparator); //$NON-NLS-1$
+				buffer.append("\t\t}").append(this.context.lineSeparator); //$NON-NLS-1$
+				lineNumberOffset += 4; // 4 CRs
+			}
+		} else {
+			// Initialize with previous value if name and type are the same
+			buffer.append("\t\t"); //$NON-NLS-1$
+			buffer.append(varName);
+			buffer.append("= "); //$NON-NLS-1$
+			char[] installedPackageName = installedVars.packageName;
+			if (installedPackageName != null && installedPackageName.length != 0) {
+				buffer.append(installedPackageName);
+				buffer.append("."); //$NON-NLS-1$
+			}
+			buffer.append(installedVars.className);
+			buffer.append("."); //$NON-NLS-1$
+			buffer.append(varName);
+			buffer.append(';').append(this.context.lineSeparator);
+			lineNumberOffset++;
+		}
+	}
+	buffer.append("\t}").append(this.context.lineSeparator); //$NON-NLS-1$
+
+	// end of class declaration
+	buffer.append('}').append(this.context.lineSeparator);
+
+	// return result
+	int length = buffer.length();
+	char[] result = new char[length];
+	buffer.getChars(0, length, result, 0);
+	return result;
+}
+/**
+ * Returns the number of cariage returns included in the given source.
+ */
+private int numberOfCRs(char[] source) {
+	int numberOfCRs = 0;
+	boolean lastWasCR = false;
+	for (int i = 0; i < source.length; i++) {
+		char currentChar = source[i];
+		switch(currentChar){
+			case '\r' :
+				lastWasCR = true;
+				numberOfCRs++;
+				break;
+			case '\n' :
+				if (!lastWasCR) numberOfCRs++; // merge CR-LF
+				lastWasCR = false;
+				break;
+			default :
+				lastWasCR = false;
+		}
+	}
+	return numberOfCRs;
+}
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java
new file mode 100644
index 0000000..885d7a1
--- /dev/null
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.eval;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+
+/**
+ * This contains information about the installed variables such as
+ * their names, their types, the name of the class that defines them,
+ * the binary of the class (to be passed to the name environment when
+ * compiling the code snippet).
+ */
+public class VariablesInfo {
+	GlobalVariable[] variables;
+	int variableCount;
+	char[] packageName;
+	char[] className;
+	ClassFile[] classFiles;
+/**
+ * Creates a new variables info.
+ * The name of the global variable class is the simple name of this class.
+ * The package name can be null if the variables have been defined in the default package.
+ */
+public VariablesInfo(char[] packageName, char[] className, ClassFile[] classFiles, GlobalVariable[] variables, int variableCount) {
+	this.packageName = packageName;
+	this.className = className;
+	this.classFiles = classFiles;
+	this.variables = variables;
+	this.variableCount = variableCount;
+}
+/**
+ * Returns the index of the given variable.
+ * Returns -1 if not found.
+ */
+int indexOf(GlobalVariable var) {
+	for (int i = 0; i < this.variableCount; i++) {
+		if (var.equals(this.variables[i])) {
+			return i;
+		}
+	}
+	return -1;
+}
+/**
+ * Returns the variable with the given name.
+ * Returns null if not found.
+ */
+GlobalVariable varNamed(char[] name) {
+	GlobalVariable[] vars = this.variables;
+	for (int i = 0; i < this.variableCount; i++) {
+		GlobalVariable var = vars[i];
+		if (CharOperation.equals(name, var.name)) {
+			return var;
+		}
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/forceQualifierUpdate.txt b/org.eclipse.jdt.core/forceQualifierUpdate.txt
new file mode 100644
index 0000000..13bf69d
--- /dev/null
+++ b/org.eclipse.jdt.core/forceQualifierUpdate.txt
@@ -0,0 +1,5 @@
+# To force a version qualifier update, add the bug here
+Bug 403352 - Update all parent versions to match our build stream
+Bug 407853 - ECJ download misses legal file (about.html)
+Bug 407852 - ECJ source download is not correct
+Bug 408447 - compiler (log message) needs updating for copyright and bundle_qualifier
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
new file mode 100644
index 0000000..787d4e6
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.formatter;
+
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Specification for a generic source code formatter.
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class CodeFormatter {
+
+	/**
+	 * Unknown kind
+	 *<p>
+	 * <b>Since 3.6</b>, if the corresponding comment options are set to
+	 * <code>true</code> then it is also possible to format the comments on the fly
+	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+	 * </p>
+	 */
+	public static final int K_UNKNOWN = 0x00;
+
+	/**
+	 * Kind used to format an expression
+	 * <p>
+	 * Note that using this constant, the comments encountered while formatting
+	 * the expression may be shifted to match the correct indentation but are not
+	 * formatted.
+	 * </p><p>
+	 * <b>Since 3.6</b>, if the corresponding comment options are set to
+	 * <code>true</code> then it is also possible to format the comments on the fly
+	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+	 * </p>
+	 */
+	public static final int K_EXPRESSION = 0x01;
+
+	/**
+	 * Kind used to format a set of statements
+	 * <p>
+	 * Note that using this constant, the comments encountered while formatting
+	 * the statements may be shifted to match the correct indentation but are not
+	 * formatted.
+	 * </p><p>
+	 * <b>Since 3.6</b>, if the corresponding comment options are set to
+	 * <code>true</code> then it is also possible to format the comments on the fly
+	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+	 * </p>
+	 */
+	public static final int K_STATEMENTS = 0x02;
+
+	/**
+	 * Kind used to format a set of class body declarations
+	 * <p>
+	 * Note that using this constant, the comments encountered while formatting
+	 * the body declarations may be shifted to match the correct indentation but
+	 * are not formatted.
+	 * </p><p>
+	 * <b>Since 3.6</b>, if the corresponding comment options are set to
+	 * <code>true</code> then it is also possible to format the comments on the fly
+	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+	 * </p>
+	 */
+	public static final int K_CLASS_BODY_DECLARATIONS = 0x04;
+
+	/**
+	 * Kind used to format a compilation unit
+	 * <p>
+	 * Note that using this constant, the comments are only indented while
+	 * formatting the compilation unit.
+	 * </p><p>
+	 * <b>Since 3.4</b>, if the corresponding comment option is set to
+	 * <code>true</code> then it is also possible to format the comments on the fly
+	 * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+	 * </p>
+	 */
+	public static final int K_COMPILATION_UNIT = 0x08;
+
+	/**
+	 * Kind used to format a single-line comment
+	 * @since 3.1
+	 */
+	public static final int K_SINGLE_LINE_COMMENT = 0x10;
+
+	/**
+	 * Kind used to format a multi-line comment
+	 * @since 3.1
+	 */
+	public static final int K_MULTI_LINE_COMMENT = 0x20;
+
+	/**
+	 * Kind used to format a Javadoc comment
+	 *
+	 * @since 3.1
+	 */
+	public static final int K_JAVA_DOC = 0x40;
+
+	/**
+	 * Flag used to include the comments during the formatting of the code
+	 * snippet.
+	 * <p>
+	 * This flag can be combined with the following kinds:
+	 * <ul>
+	 * 		<li>{@link #K_COMPILATION_UNIT}</li>
+	 * 		<li>{@link #K_UNKNOWN}</li>
+	 * 		<li>{@link #K_CLASS_BODY_DECLARATIONS} <i>(since 3.6)</i></li>
+	 * 		<li>{@link #K_EXPRESSION} <i>(since 3.6)</i></li>
+	 * 		<li>{@link #K_STATEMENTS} <i>(since 3.6)</i></li>
+	 * </ul>
+	 * </p><p>
+	 * Note also that it has an effect only when one or several format comments
+	 * options for
+	 * {@link DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT javadoc}
+	 * ,
+	 * {@link DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT block}
+	 * or
+	 * {@link DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_LINE_COMMENT line}
+	 * are set to {@link DefaultCodeFormatterConstants#TRUE true} while calling
+	 * {@link #format(int, String, int, int, int, String)} or
+	 * {@link #format(int, String, IRegion[], int, String)} methods
+	 * </p><p>
+	 * For example, with the Eclipse default formatter options, the formatting
+	 * of the following code snippet using {@link #K_COMPILATION_UNIT}:
+	 * <pre>
+	 * public class X {
+	 * &#047;&#042;&#042;
+	 *  &#042; This is just a simple example to show that comments will be formatted while processing a compilation unit only if the constant flag <code>F_INCLUDE_COMMENT</code> flag is set.
+	 *  &#042; &#064;param str The input string
+	 *  &#042;&#047;
+	 *  void foo(String str){}}
+	 * </pre>
+	 * will produce the following output:
+	 * <pre>
+	 * public class X {
+	 * 	&#047;&#042;&#042;
+	 *  	 &#042; This is just a simple example to show that comments will be formatted while processing a compilation unit only if the constant flag <code>F_INCLUDE_COMMENT</code> flag is set.
+	 *  	 &#042;
+	 *  	 &#042; &#064;param str The input string
+	 *  	 &#042;&#047;
+	 *  	void foo(String str){
+	 *  	}
+	 *  }
+	 * </pre>
+	 * Adding this flavor to the kind given while formatting the same source
+	 * (e.g. {@link #K_COMPILATION_UNIT} | {@link #F_INCLUDE_COMMENTS})
+	 * will produce the following output instead:
+	 * <pre>
+	 * public class X {
+	 * 	&#047;&#042;&#042;
+	 *  	 &#042; This is just a simple example to show that comments will be formatted
+	 *  	 &#042; while processing a compilation unit only if the constant flag
+	 *  	 &#042; <code>F_INCLUDE_COMMENT</code> flag is set.
+	 *  	 &#042;
+	 *  	 &#042; &#064;param str
+	 *  	 &#042; 		The input string
+	 *  	 &#042;&#047;
+	 *  	void foo(String str){
+	 *  	}
+	 *  }
+	 * </pre>
+	 * </p><p>
+	 * <i><u>Note</u>: Although we're convinced that the formatter should
+	 * always include the comments while processing a
+	 * {@link #K_COMPILATION_UNIT kind of compilation unit}, we
+	 * have decided to add a specific flag to fix this formatter incorrect behavior.
+	 * This will prevent all existing clients (e.g. 3.3 and previous versions) using
+	 * the {@link #K_COMPILATION_UNIT} kind to be broken while formatting.</i>
+	 * </p>
+	 * @since 3.4
+	 */
+	public static final int F_INCLUDE_COMMENTS = 0x1000;
+
+	/**
+	 * Format <code>source</code>,
+	 * and returns a text edit that correspond to the difference between the given
+	 * string and the formatted string.
+	 * <p>
+	 * It returns null if the given string cannot be formatted.
+	 * </p><p>
+	 * If the offset position is matching a whitespace, the result can include
+	 * whitespaces. It would be up to the caller to get rid of preceding
+	 * whitespaces.
+	 * </p>
+	 *
+	 * @param kind Use to specify the kind of the code snippet to format. It can
+	 * be any of these:
+	 * <ul>
+	 * 	<li>{@link #K_EXPRESSION}</li>
+	 * 	<li>{@link #K_STATEMENTS}</li>
+	 * 	<li>{@link #K_CLASS_BODY_DECLARATIONS}</li>
+	 * 	<li>{@link #K_COMPILATION_UNIT}<br>
+	 * 		<b>Since 3.4</b>, the comments can be formatted on the fly while
+	 * 		using this kind of code snippet<br>
+	 * 		(see {@link #F_INCLUDE_COMMENTS} for more detailed explanation on
+	 * 		this flag)
+	 * 	</li>
+	 * 	<li>{@link #K_UNKNOWN}</li>
+	 * 	<li>{@link #K_SINGLE_LINE_COMMENT}</li>
+	 * 	<li>{@link #K_MULTI_LINE_COMMENT}</li>
+	 * 	<li>{@link #K_JAVA_DOC}</li>
+	 * </ul>
+	 * @param source the source to format
+	 * @param offset the given offset to start recording the edits (inclusive).
+	 * @param length the given length to stop recording the edits (exclusive).
+	 * @param indentationLevel the initial indentation level, used
+	 *      to shift left/right the entire source fragment. An initial indentation
+	 *      level of zero or below has no effect.
+	 * @param lineSeparator the line separator to use in formatted source,
+	 *     if set to <code>null</code>, then the platform default one will be used.
+	 * @return the text edit
+	 * @throws IllegalArgumentException if offset is lower than 0, length is lower than 0 or
+	 * length is greater than source length.
+	 */
+	public abstract TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator);
+
+	/**
+	 * Format <code>source</code>,
+	 * and returns a text edit that correspond to the difference between the given string and the formatted string.
+	 * <p>It returns null if the given string cannot be formatted.</p>
+	 *
+	 * <p>If an offset position is matching a whitespace, the result can include whitespaces. It would be up to the
+	 * caller to get rid of preceding whitespaces.</p>
+	 *
+	 * <p>No region in <code>regions</code> must overlap with any other region in <code>regions</code>.
+	 * Each region must be within source. There must be at least one region. Regions must be sorted
+	 * by their offsets, smaller offset first.</p>
+	 *
+	 * @param kind Use to specify the kind of the code snippet to format. It can
+	 * be any of these:
+	 * <ul>
+	 * 	<li>{@link #K_EXPRESSION}</li>
+	 * 	<li>{@link #K_STATEMENTS}</li>
+	 * 	<li>{@link #K_CLASS_BODY_DECLARATIONS}</li>
+	 * 	<li>{@link #K_COMPILATION_UNIT}<br>
+	 * 		<b>Since 3.4</b>, the comments can be formatted on the fly while
+	 * 		using this kind of code snippet<br>
+	 * 		(see {@link #F_INCLUDE_COMMENTS} for more detailed explanation on
+	 * 		this flag)
+	 * 	</li>
+	 * 	<li>{@link #K_UNKNOWN}</li>
+	 * 	<li>{@link #K_SINGLE_LINE_COMMENT}</li>
+	 * 	<li>{@link #K_MULTI_LINE_COMMENT}</li>
+	 * 	<li>{@link #K_JAVA_DOC}</li>
+	 * </ul>
+	 * @param source the source to format
+	 * @param regions a set of regions in source to format
+	 * @param indentationLevel the initial indentation level, used
+	 *      to shift left/right the entire source fragment. An initial indentation
+	 *      level of zero or below has no effect.
+	 * @param lineSeparator the line separator to use in formatted source,
+	 *     if set to <code>null</code>, then the platform default one will be used.
+	 * @return the text edit
+	 * @throws IllegalArgumentException if there is no region, a region overlaps with another region, or the regions are not
+	 * sorted in the ascending order.
+	 * @since 3.4
+	 */
+	public abstract TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator);
+
+	/**
+	 * Answers the string that corresponds to the indentation to the given indentation level or an empty string
+	 * if the indentation cannot be computed.
+	 * <p>This method needs to be overridden in a subclass.</p>
+	 *
+	 * <p>The default implementation returns an empty string.</p>
+	 *
+	 * @param indentationLevel the given indentation level
+	 * @return the string corresponding to the right indentation level
+	 * @exception IllegalArgumentException if the given indentation level is lower than zero
+	 * @since 3.2
+	 */
+	public String createIndentationString(int indentationLevel) {
+		return Util.EMPTY_STRING;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatterApplication.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatterApplication.java
new file mode 100644
index 0000000..d40c718
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatterApplication.java
@@ -0,0 +1,430 @@
+/*******************************************************************************
+ *  Copyright (c) 2005, 2011 IBM Corporation and others.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ * 
+ *  Contributors:
+ *     Ben Konrath <ben@bagu.org> - initial implementation
+ *     Red Hat Incorporated - improvements based on comments from JDT developers
+ *     IBM Corporation - Code review and integration
+ *     IBM Corporation - Fix for 340181
+ *******************************************************************************/
+package org.eclipse.jdt.core.formatter;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Implements an Eclipse Application for org.eclipse.jdt.core.JavaCodeFormatter.
+ * 
+ * <p>On MacOS, when invoked using the Eclipse executable, the "user.dir" property is set to the folder
+ * in which the eclipse.ini file is located. This makes it harder to use relative paths to point to the 
+ * files to be formatted or the configuration file to use to set the code formatter's options.</p>
+ *
+ * <p>There are a couple improvements that could be made: 1. Make a list of all the
+ * files first so that a file does not get formatted twice. 2. Use a text based
+ * progress monitor for output.</p>
+ *
+ * @author Ben Konrath <bkonrath@redhat.com>
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CodeFormatterApplication implements IApplication {
+
+	/**
+	 * Deals with the messages in the properties file (cut n' pasted from a
+	 * generated class).
+	 */
+	private final static class Messages extends NLS {
+		private static final String BUNDLE_NAME = "org.eclipse.jdt.core.formatter.messages";//$NON-NLS-1$
+
+		public static String CommandLineConfigFile;
+
+		public static String CommandLineDone;
+
+		public static String CommandLineErrorConfig;
+
+		public static String CommandLineErrorFileTryFullPath;
+
+		public static String CommandLineErrorFile;
+
+		public static String CommandLineErrorFileDir;
+
+		public static String CommandLineErrorQuietVerbose;
+
+		public static String CommandLineErrorNoConfigFile;
+
+		public static String CommandLineFormatting;
+
+		public static String CommandLineStart;
+
+		public static String CommandLineUsage;
+
+		public static String ConfigFileNotFoundErrorTryFullPath;
+
+		public static String ConfigFileReadingError;
+
+		public static String FormatProblem;
+
+		public static String CaughtException;
+
+		public static String ExceptionSkip;
+
+		static {
+			NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+		}
+
+		/**
+		 * Bind the given message's substitution locations with the given string
+		 * values.
+		 *
+		 * @param message
+		 *            the message to be manipulated
+		 * @return the manipulated String
+		 */
+		public static String bind(String message) {
+			return bind(message, null);
+		}
+
+		/**
+		 * Bind the given message's substitution locations with the given string
+		 * values.
+		 *
+		 * @param message
+		 *            the message to be manipulated
+		 * @param binding
+		 *            the object to be inserted into the message
+		 * @return the manipulated String
+		 */
+		public static String bind(String message, Object binding) {
+			return bind(message, new Object[] {
+				binding
+			});
+		}
+
+		/**
+		 * Bind the given message's substitution locations with the given string
+		 * values.
+		 *
+		 * @param message
+		 *            the message to be manipulated
+		 * @param binding1
+		 *            An object to be inserted into the message
+		 * @param binding2
+		 *            A second object to be inserted into the message
+		 * @return the manipulated String
+		 */
+		public static String bind(String message, Object binding1, Object binding2) {
+			return bind(message, new Object[] {
+					binding1, binding2
+			});
+		}
+
+		/**
+		 * Bind the given message's substitution locations with the given string
+		 * values.
+		 *
+		 * @param message
+		 *            the message to be manipulated
+		 * @param bindings
+		 *            An array of objects to be inserted into the message
+		 * @return the manipulated String
+		 */
+		public static String bind(String message, Object[] bindings) {
+			return MessageFormat.format(message, bindings);
+		}
+	}
+
+	private static final String ARG_CONFIG = "-config"; //$NON-NLS-1$
+
+	private static final String ARG_HELP = "-help"; //$NON-NLS-1$
+
+	private static final String ARG_QUIET = "-quiet"; //$NON-NLS-1$
+
+	private static final String ARG_VERBOSE = "-verbose"; //$NON-NLS-1$
+
+	private String configName;
+
+	private Map options = null;
+
+	private static final String PDE_LAUNCH = "-pdelaunch"; //$NON-NLS-1$
+
+	private boolean quiet = false;
+
+	private boolean verbose = false;
+
+	/**
+	 * Display the command line usage message.
+	 */
+	private void displayHelp() {
+		System.out.println(Messages.bind(Messages.CommandLineUsage));
+	}
+
+	private void displayHelp(String message) {
+		System.err.println(message);
+		System.out.println();
+		displayHelp();
+	}
+
+	/**
+	 * Recursively format the Java source code that is contained in the
+	 * directory rooted at dir.
+	 */
+	private void formatDirTree(File dir, CodeFormatter codeFormatter) {
+
+		File[] files = dir.listFiles();
+		if (files == null)
+			return;
+
+		for (int i = 0; i < files.length; i++) {
+			File file = files[i];
+			if (file.isDirectory()) {
+				formatDirTree(file, codeFormatter);
+			} else if (Util.isJavaLikeFileName(file.getPath())) {
+				formatFile(file, codeFormatter);
+			}
+		}
+	}
+
+	/**
+	 * Format the given Java source file.
+	 */
+	private void formatFile(File file, CodeFormatter codeFormatter) {
+		IDocument doc = new Document();
+		try {
+			// read the file
+			if (this.verbose) {
+				System.out.println(Messages.bind(Messages.CommandLineFormatting, file.getAbsolutePath()));
+			}
+			String contents = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(file, null));
+			// format the file (the meat and potatoes)
+			doc.set(contents);
+			TextEdit edit = codeFormatter.format(CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, contents, 0, contents.length(), 0, null);
+			if (edit != null) {
+				edit.apply(doc);
+			} else {
+				System.err.println(Messages.bind(Messages.FormatProblem, file.getAbsolutePath()));
+				return;
+			}
+
+			// write the file
+			final BufferedWriter out = new BufferedWriter(new FileWriter(file));
+			try {
+				out.write(doc.get());
+				out.flush();
+			} finally {
+				try {
+					out.close();
+				} catch (IOException e) {
+					/* ignore */
+				}
+			}
+		} catch (IOException e) {
+			String errorMessage = Messages.bind(Messages.CaughtException, "IOException", e.getLocalizedMessage()); //$NON-NLS-1$
+			Util.log(e, errorMessage);
+			System.err.println(Messages.bind(Messages.ExceptionSkip ,errorMessage));
+		} catch (BadLocationException e) {
+			String errorMessage = Messages.bind(Messages.CaughtException, "BadLocationException", e.getLocalizedMessage()); //$NON-NLS-1$
+			Util.log(e, errorMessage);
+			System.err.println(Messages.bind(Messages.ExceptionSkip ,errorMessage));
+		}
+	}
+
+	private File[] processCommandLine(String[] argsArray) {
+
+		ArrayList args = new ArrayList();
+		for (int i = 0, max = argsArray.length; i < max; i++) {
+			args.add(argsArray[i]);
+		}
+		int index = 0;
+		final int argCount = argsArray.length;
+
+		final int DEFAULT_MODE = 0;
+		final int CONFIG_MODE = 1;
+
+		int mode = DEFAULT_MODE;
+		final int INITIAL_SIZE = 1;
+		int fileCounter = 0;
+
+		File[] filesToFormat = new File[INITIAL_SIZE];
+
+		loop: while (index < argCount) {
+			String currentArg = argsArray[index++];
+
+			switch(mode) {
+				case DEFAULT_MODE :
+					if (PDE_LAUNCH.equals(currentArg)) {
+						continue loop;
+					}
+					if (ARG_HELP.equals(currentArg)) {
+						displayHelp();
+						return null;
+					}
+					if (ARG_VERBOSE.equals(currentArg)) {
+						this.verbose = true;
+						continue loop;
+					}
+					if (ARG_QUIET.equals(currentArg)) {
+						this.quiet = true;
+						continue loop;
+					}
+					if (ARG_CONFIG.equals(currentArg)) {
+						mode = CONFIG_MODE;
+						continue loop;
+					}
+					// the current arg should be a file or a directory name
+					File file = new File(currentArg);
+					if (file.exists()) {
+						if (filesToFormat.length == fileCounter) {
+							System.arraycopy(filesToFormat, 0, (filesToFormat = new File[fileCounter * 2]), 0, fileCounter);
+						}
+						filesToFormat[fileCounter++] = file;
+					} else {
+						String canonicalPath;
+						try {
+							canonicalPath = file.getCanonicalPath();
+						} catch(IOException e2) {
+							canonicalPath = file.getAbsolutePath();
+						}
+						String errorMsg = file.isAbsolute()?
+										  Messages.bind(Messages.CommandLineErrorFile, canonicalPath):
+										  Messages.bind(Messages.CommandLineErrorFileTryFullPath, canonicalPath);
+						displayHelp(errorMsg);
+						return null;
+					}
+					break;
+				case CONFIG_MODE :
+					this.configName = currentArg;
+					this.options = readConfig(currentArg);
+					if (this.options == null) {
+						displayHelp(Messages.bind(Messages.CommandLineErrorConfig, currentArg));
+						return null;
+					}
+					mode = DEFAULT_MODE;
+					continue loop;
+			}
+		}
+
+		if (mode == CONFIG_MODE || this.options == null) {
+			displayHelp(Messages.bind(Messages.CommandLineErrorNoConfigFile));
+			return null;
+		}
+		if (this.quiet && this.verbose) {
+			displayHelp(
+				Messages.bind(
+					Messages.CommandLineErrorQuietVerbose,
+					new String[] { ARG_QUIET, ARG_VERBOSE }
+				));
+			return null;
+		}
+		if (fileCounter == 0) {
+			displayHelp(Messages.bind(Messages.CommandLineErrorFileDir));
+			return null;
+		}
+		if (filesToFormat.length != fileCounter) {
+			System.arraycopy(filesToFormat, 0, (filesToFormat = new File[fileCounter]), 0, fileCounter);
+		}
+		return filesToFormat;
+	}
+
+	/**
+	 * Return a Java Properties file representing the options that are in the
+	 * specified configuration file.
+	 */
+	private Properties readConfig(String filename) {
+		BufferedInputStream stream = null;
+		File configFile = new File(filename);
+		try {
+			stream = new BufferedInputStream(new FileInputStream(configFile));
+			final Properties formatterOptions = new Properties();
+			formatterOptions.load(stream);
+			return formatterOptions;
+		} catch (IOException e) {
+			String canonicalPath = null;
+			try {
+				canonicalPath = configFile.getCanonicalPath();
+			} catch(IOException e2) {
+				canonicalPath = configFile.getAbsolutePath();
+			}
+			String errorMessage;
+			if (!configFile.exists() && !configFile.isAbsolute()) {
+				errorMessage = Messages.bind(Messages.ConfigFileNotFoundErrorTryFullPath, new Object[] {
+					canonicalPath,
+					System.getProperty("user.dir") //$NON-NLS-1$
+				});
+
+			} else {
+				errorMessage = Messages.bind(Messages.ConfigFileReadingError, canonicalPath);
+			}
+			Util.log(e, errorMessage);
+			System.err.println(errorMessage);
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					/* ignore */
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Runs the Java code formatter application
+	 */
+	public Object start(IApplicationContext context) throws Exception {
+		File[] filesToFormat = processCommandLine((String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS));
+
+		if (filesToFormat == null) {
+			return IApplication.EXIT_OK;
+		}
+
+		if (!this.quiet) {
+			if (this.configName != null) {
+				System.out.println(Messages.bind(Messages.CommandLineConfigFile, this.configName));
+			}
+			System.out.println(Messages.bind(Messages.CommandLineStart));
+		}
+
+		final CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(this.options);
+		// format the list of files and/or directories
+		for (int i = 0, max = filesToFormat.length; i < max; i++) {
+			final File file = filesToFormat[i];
+			if (file.isDirectory()) {
+				formatDirTree(file, codeFormatter);
+			} else if (Util.isJavaLikeFileName(file.getPath())) {
+				formatFile(file, codeFormatter);
+			}
+		}
+		if (!this.quiet) {
+			System.out.println(Messages.bind(Messages.CommandLineDone));
+		}
+
+		return IApplication.EXIT_OK;
+	}
+	public void stop() {
+		// do nothing
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
new file mode 100644
index 0000000..87600c7
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -0,0 +1,4278 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation  - initial API and implementation
+ *     Brock Janiczak   - Contribution for bug 150741
+ *     Ray V. (voidstar@gmail.com) - Contribution for bug 282988
+ *     Jesper S Moller - Contribution for bug 402173
+ *******************************************************************************/
+package org.eclipse.jdt.core.formatter;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
+import org.eclipse.jdt.internal.formatter.align.Alignment;
+
+/**
+ * Constants used to set up the options of the code formatter.
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DefaultCodeFormatterConstants {
+
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the end of a line.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY
+	 * @since 3.0
+	 */
+	public static final String END_OF_LINE = "end_of_line";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set an option to false.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FALSE = "false"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to align type members of a type declaration on column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.formatter.align_type_members_on_columns"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS = JavaCore.PLUGIN_ID + ".formatter.align_type_members_on_columns";	 //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of arguments in allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_allocation_expression";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of arguments in enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_enum_constant";	 //$NON-NLS-1$
+	/**
+	 * <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)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_annotation";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of arguments in explicit constructor call
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_explicit_constructor_call";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of arguments in method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_method_invocation";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of arguments in qualified allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_arguments_in_qualified_allocation_expression";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of assignment
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_assignment"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_NO_SPLIT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.2
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ASSIGNMENT  = JavaCore.PLUGIN_ID + ".formatter.alignment_for_assignment";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of binary expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_binary_expression"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_binary_expression";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of compact if
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_compact_if"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_ONE_PER_LINE, INDENT_BY_ONE)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_COMPACT_IF = JavaCore.PLUGIN_ID + ".formatter.alignment_for_compact_if";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of conditional expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_conditional_expression"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_ONE_PER_LINE, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_conditional_expression";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of enum constants
+	 *     - option id:        "org.eclipse.jdt.core.formatter.alignment_for_enum_constants"
+	 *     - possible values:  values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:          createAlignmentValue(false, WRAP_NO_SPLIT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS = JavaCore.PLUGIN_ID + ".formatter.alignment_for_enum_constants";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of expressions in array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.alignment_for_expressions_in_array_initializer";	 //$NON-NLS-1$
+	/**
+	 * <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)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_method_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of multiple fields
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_multiple_fields"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS = JavaCore.PLUGIN_ID + ".formatter.alignment_for_multiple_fields";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of parameters in constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_parameters_in_constructor_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of parameters in method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_parameters_in_method_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of resources in a try with resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_resources_in_try"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_NEXT_PER_LINE, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY = JavaCore.PLUGIN_ID + ".formatter.alignment_for_resources_in_try";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of selector in method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_selector_in_method_invocation";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of superclass in type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_NEXT_SHIFTED, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_superclass_in_type_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of superinterfaces in enum declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_superinterfaces_in_enum_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of superinterfaces in type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_superinterfaces_in_type_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of throws clause in constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_throws_clause_in_constructor_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of throws clause in method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_throws_clause_in_method_declaration";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option for alignment of exceptions declared in a Union Type in the argument of a multicatch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH = JavaCore.PLUGIN_ID + ".formatter.alignment_for_union_type_in_multicatch";	 //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines after the imports declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_imports"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_AFTER_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_imports";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines after the package declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_package"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_AFTER_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_package";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines at the beginning of the method body
+	 *     - option id:         "org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.number_of_blank_lines_at_beginning_of_method_body"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a field declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_field"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_FIELD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_field";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the first class body declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_first_class_body_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the imports declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_imports"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_imports";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a member type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_member_type"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_member_type";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_method"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_METHOD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_method";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a new chunk
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_new_chunk";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the package declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_package"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_package";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines between import groups
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_between_import_groups"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "1"
+	 * </pre>
+	 * Note: Import groups are defined once "Organize Import" operation has been executed. The code formatter itself
+	 * doesn't define the import groups.
+	 *
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_between_import_groups";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines between type declarations
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_between_type_declarations";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of an annotation type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_annotation_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of an anonymous type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_anonymous_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_array_initializer"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_block"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_block";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a block in a case statement when the block is the first statement following
+	 *             the case
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_block_in_case"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_block_in_case";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of an enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_enum_constant"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of an enum declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_enum_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_method_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a switch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_switch"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_SWITCH = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_switch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_type_declaration";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a lambda block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_lambda_body"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_lambda_body";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether blank lines are cleared inside comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 * @deprecated Use {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT} and {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT}
+	 */
+	public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether blank lines are cleared inside javadoc comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether blank lines are cleared inside block comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether comments are formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 * @deprecated Use multiple settings for each kind of comments. See {@link #FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT},
+	 * {@link #FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT} and {@link #FORMATTER_COMMENT_FORMAT_LINE_COMMENT}.
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT = "org.eclipse.jdt.core.formatter.comment.format_comments"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether single line comments are formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_line_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_LINE_COMMENT = "org.eclipse.jdt.core.formatter.comment.format_line_comments"; //$NON-NLS-1$
+	/**
+	 * <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
+	 * </pre>
+	 * 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
+	 */
+	public static final String FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN = JavaCore.PLUGIN_ID + ".formatter.format_line_comment_starting_on_first_column"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether the white space between code and line comments should be preserved or replaced with a single space
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.7
+	 */
+	public final static String FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT = "org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether multiple lines comments are formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_block_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT = "org.eclipse.jdt.core.formatter.comment.format_block_comments"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether javadoc comments are formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_javadoc_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT = "org.eclipse.jdt.core.formatter.comment.format_javadoc_comments"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether the header comment of a Java source file is formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_HEADER = "org.eclipse.jdt.core.formatter.comment.format_header"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether HTML tags are formatted.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_html"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_HTML = "org.eclipse.jdt.core.formatter.comment.format_html"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether code snippets are formatted in comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_source_code"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_FORMAT_SOURCE = "org.eclipse.jdt.core.formatter.comment.format_source_code"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether description of Javadoc parameters are indented
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.indent_parameter_description"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION = "org.eclipse.jdt.core.formatter.comment.indent_parameter_description"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether Javadoc root tags are indented.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.indent_root_tags"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_INDENT_ROOT_TAGS = "org.eclipse.jdt.core.formatter.comment.indent_root_tags"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert an empty line before the Javadoc root tag block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS = "org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after Javadoc root tag parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER = "org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the line length for comments.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.line_length"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "80"
+	 * </pre>
+	 * @since 3.1
+	 */
+	public final static String FORMATTER_COMMENT_LINE_LENGTH = "org.eclipse.jdt.core.formatter.comment.line_length"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to 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
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.6
+	 */
+	public final static String FORMATTER_COMMENT_NEW_LINES_AT_BLOCK_BOUNDARIES = "org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * 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
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.6
+	 */
+	public final static String FORMATTER_COMMENT_NEW_LINES_AT_JAVADOC_BOUNDARIES = "org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to compact else/if
+	 *     - option id:         "org.eclipse.jdt.core.formatter.compact_else_if"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_COMPACT_ELSE_IF = JavaCore.PLUGIN_ID + ".formatter.compact_else_if";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to set the continuation indentation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.continuation_indentation"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "2"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_CONTINUATION_INDENTATION = JavaCore.PLUGIN_ID + ".formatter.continuation_indentation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to set the continuation indentation inside array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "2"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.continuation_indentation_for_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to 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
+	 * </pre>
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_USE_ON_OFF_TAGS = JavaCore.PLUGIN_ID + ".formatter.use_on_off_tags";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to define the tag to put in a comment to disable the formatting.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.disabling_tag"
+	 *     - possible values:   String, with constraints mentioned below
+	 *     - default:           "@formatter:off"
+	 * 
+	 * See the {@link #FORMATTER_ENABLING_TAG} option to re-enable it.
+	 * </pre>
+	 * 
+	 * <p>
+	 * Note that:
+	 * <ol>
+	 * <li>This tag is used by the formatter only if the 
+	 * {@link #FORMATTER_USE_ON_OFF_TAGS} option is set to {@link #TRUE}.</li>
+	 * <li>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</li>
+	 * <li>If a tag is starting with a letter or digit, then it cannot be leaded by
+	 * another letter or digit to be recognized
+	 * (<code>"ToDisableFormatter"</code> will not be recognized as a disabling tag
+	 * <code>"DisableFormatter"</code>, but <code>"To:DisableFormatter"</code>
+	 * will be detected for either tag <code>"DisableFormatter"</code> or
+	 * <code>":DisableFormatter"</code>).<br>
+	 * Respectively, a tag ending with a letter or digit cannot be followed by a letter
+	 * or digit to be recognized (<code>"DisableFormatter1"</code> will not be
+	 * recognized as a disabling tag <code>"DisableFormatter"</code>, but
+	 * <code>"DisableFormatter:1"</code> will be detected either for tag
+	 * <code>"DisableFormatter"</code> or <code>"DisableFormatter:"</code>)</li>
+	 * <li>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.
+	 * <p>
+	 * For example, the second default enabling tag &quot;<b>@formatter:off</b>&quot;
+	 * in the following snippet is not necessary as the formatter was already disabled
+	 * since the first one:
+	 * <pre>
+	 * class X {
+	 * // @formatter:off
+	 * void foo1() {}
+	 * // @formatter:off
+	 * void foo2() {}
+	 * void bar1() {}
+	 * void bar2() {}
+	 * }
+	 * </pre></p>
+	 * </li>
+	 * <li>If no enabling tag is found by the formatter after the disabling tag, then
+	 * the end of the snippet won't be formatted.<br>
+	 * 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:
+	 * <pre>
+	 * // @formatter:off
+	 * class X {
+	 * void foo1() {}
+	 * void foo2() {}
+	 * void bar1() {}
+	 * void bar2() {}
+	 * }
+	 * </pre>
+	 * </li>
+	 * <li>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.
+	 * <p>For example, in the following snippet, the formatter will be disabled after
+	 * the comment:</p>
+	 * <pre>
+	 * class X {
+	 * &#47;&#42;
+	 * &nbsp;&#42; This is a comment with a mix of disabling and enabling tags:
+	 * &nbsp;&#42;  - <b>@formatter:off</b>
+	 * &nbsp;&#42;  - <b>@formatter:on</b>
+	 * &nbsp;&#42;  - <b>@formatter:off</b>
+	 * &nbsp;&#42; The formatter will stop to format from the beginning of this comment...
+	 * &nbsp;&#42;&#47;
+	 * void foo() {}
+	 * void bar() {}
+	 * }
+	 * </pre>
+	 * </li>
+	 * <li>The tag cannot include newline character (i.e. '\n') but it can have white
+	 * spaces.<br>
+	 * E.g. "<b>format: off</b>" is a valid disabling tag.<br>
+	 * In the future, newlines may be used to support multiple disabling tags.
+	 * </li>
+	 * <li>The tag can include line or block comments start/end tokens.
+	 * <p>If such tags are used, e.g. "<b>//J-</b>", then the single comment can
+	 * also stop the formatting as shown in the following snippet:</p>
+	 * <pre>
+	 * //J-
+	 * // Formatting was stopped from comment above...
+	 * public class X {
+	 * //J+
+	 * // Formatting is restarted from here...
+	 * void foo() {}
+	 * </pre>
+	 * <p>As any disabling tags, as soon as a comment includes it,
+	 * the formatting stops from this comment:</p>
+	 * <pre>
+	 * public class X {
+	 * // Line comment including the disabling tag: //J-
+	 * // Formatting was stopped from comment above...
+	 * void   foo1()   {}
+	 * //J+
+	 * // Formatting restarts from here...
+	 * void   bar1()   {}
+	 * &#47;&#42;
+	 * &nbsp;&#42; Block comment including the disabling tag: //J+
+	 * &nbsp;&#42; The formatter stops from this comment...
+	 * &nbsp;&#42;&#47;
+	 * void   foo2()   {}
+	 * //J+
+	 * // Formatting restarts from here...
+	 * void   bar2()   {}
+	 * &#47;&#42;&#42;
+	 * &nbsp;&#42; Javadoc comment including the enabling tag: //J+
+	 * &nbsp;&#42; The formatter stops from this comment...
+	 * &nbsp;&#42;&#47;
+	 * void   foo3()   {}
+	 * }
+	 * </pre>
+	 * </li>
+	 * </ol>
+	 * </p>
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_DISABLING_TAG = JavaCore.PLUGIN_ID + ".formatter.disabling_tag";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * 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:           "@formatter:on"
+	 * </pre>
+	 * 
+	 * <p>
+	 * Note that:
+	 * <ol>
+	 * <li>This tag is used by the formatter only if the 
+	 * {@link #FORMATTER_USE_ON_OFF_TAGS} option is set to {@link #TRUE}.</li>
+	 * <li>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</li>
+	 * <li>If a tag is starting with a letter or digit, then it cannot be leaded by
+	 * another letter or digit to be recognized
+	 * (<code>"ReEnableFormatter"</code> will not be recognized as an enabling tag
+	 * <code>"EnableFormatter"</code>, but <code>"Re:EnableFormatter"</code>
+	 * will be detected for either tag <code>"EnableFormatter"</code> or
+	 * <code>":EnableFormatter"</code>).<br>
+	 * Respectively, a tag ending with a letter or digit cannot be followed by a letter
+	 * or digit to be recognized (<code>"EnableFormatter1"</code> will not be
+	 * recognized as an enabling tag <code>"EnableFormatter"</code>, but
+	 * <code>"EnableFormatter:1"</code> will be detected either for tag
+	 * <code>"EnableFormatter"</code> or <code>"EnableFormatter:"</code>)</li>
+	 * <li>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.
+	 * <p>
+	 * For example, the default enabling tag &quot;<b>@formatter:on</b>&quot;
+	 * in the following snippet is not necessary as the formatter has never been
+	 * disabled:
+	 * <pre>
+	 * class X {
+	 * void foo1() {}
+	 * void foo2() {}
+	 * // @formatter:on
+	 * void bar1() {}
+	 * void bar2() {}
+	 * }
+	 * </pre>
+	 * 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:
+	 * <pre>
+	 * class X {
+	 * // @formatter:off
+	 * void foo1() {}
+	 * void foo2() {}
+	 * // @formatter:on
+	 * void bar1() {}
+	 * // @formatter:on
+	 * void bar2() {}
+	 * }
+	 * </pre></p>
+	 * </li>
+	 * <li>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.
+	 * <p>For example, in the following snippet, the formatter will be re-enabled after
+	 * the comment:</p>
+	 * <pre>
+	 * // @formatter:off
+	 * class X {
+	 * &#47;&#42;
+	 * &nbsp;&#42; This is a comment with a mix of disabling and enabling tags:
+	 * &nbsp;&#42;  - <b>@formatter:on</b>
+	 * &nbsp;&#42;  - <b>@formatter:off</b>
+	 * &nbsp;&#42;  - <b>@formatter:on</b>
+	 * &nbsp;&#42; The formatter will restart to format after this comment...
+	 * &nbsp;&#42;&#47;
+	 * void foo() {}
+	 * void bar() {}
+	 * }
+	 * </pre>
+	 * </li>
+	 * <li>The tag cannot include newline character (i.e. '\n') but it can have white
+	 * spaces.<br>
+	 * E.g. "<b>format: on</b>" is a valid enabling tag<br>
+	 * In the future, newlines may be used to support multiple enabling tags.
+	 * </li>
+	 * <li>The tag can include line or block comments start/end tokens. Javadoc
+	 * tokens are not considered as valid tags.
+	 * <p>If such tags are used, e.g. "<b>//J+</b>", then the single comment can
+	 * also start the formatting as shown in the following snippet:</p>
+	 * <pre>
+	 * //J-
+	 * // Formatting was stopped from comment above...
+	 * public class X {
+	 * //J+
+	 * // Formatting restarts from here...
+	 * void foo() {}
+	 * }
+	 * </pre>
+	 * <p>As any enabling tags, as soon as a comment includes it,
+	 * the formatting restarts just after the comment:</p>
+	 * <pre>
+	 * public class X {
+	 * //J-
+	 * // Formatting was stopped from comment above...
+	 * void   foo1()   {}
+	 * // Line comment including the enabling tag: //J+
+	 * // Formatting restarts from here...
+	 * void   bar1()   {}
+	 * //J-
+	 * // Formatting was stopped from comment above...
+	 * void   foo2()   {}
+	 * &#47;&#42;
+	 * &nbsp;&#42; Block comment including the enabling tag: //J+
+	 * &nbsp;&#42; The formatter restarts after this comment...
+	 * &nbsp;&#42;&#47;
+	 * // Formatting restarts from here...
+	 * void   bar2()   {}
+	 * //J-
+	 * // Formatting was stopped from comment above...
+	 * void   foo3()   {}
+	 * &#47;&#42;&#42;
+	 * &nbsp;&#42; Javadoc comment including the enabling tag: //J+
+	 * &nbsp;&#42; The formatter restarts after this comment...
+	 * &nbsp;&#42;&#47;
+	 * void   bar3()   {}
+	 * }
+	 * </pre>
+	 * </li>
+	 * </ol>
+	 * </p>
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_ENABLING_TAG = JavaCore.PLUGIN_ID + ".formatter.enabling_tag";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent body declarations compare to its enclosing annotation declaration header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.2
+	 */
+	public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ANNOTATION_DECLARATION_HEADER = JavaCore.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_annotation_declaration_header";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent body declarations compare to its enclosing enum constant header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_CONSTANT_HEADER = JavaCore.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_enum_constant_header";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent body declarations compare to its enclosing enum declaration header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_DECLARATION_HEADER = JavaCore.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_enum_declaration_header";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent body declarations compare to its enclosing type header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_TYPE_HEADER = JavaCore.PLUGIN_ID + ".formatter.indent_body_declarations_compare_to_type_header";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent breaks compare to cases
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES = JavaCore.PLUGIN_ID + ".formatter.indent_breaks_compare_to_cases";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent empty lines
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_empty_lines"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.2
+	 */
+	public static final String FORMATTER_INDENT_EMPTY_LINES = JavaCore.PLUGIN_ID + ".formatter.indent_empty_lines"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent statements inside a block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_statements_compare_to_block"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK = JavaCore.PLUGIN_ID + ".formatter.indent_statements_compare_to_block"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent statements inside the body of a method or a constructor
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_statements_compare_to_body"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY = JavaCore.PLUGIN_ID + ".formatter.indent_statements_compare_to_body"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent switch statements compare to cases
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES = JavaCore.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_cases";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent switch statements compare to switch
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH = JavaCore.PLUGIN_ID + ".formatter.indent_switchstatements_compare_to_switch";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the equivalent number of spaces that represents one indentation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indentation.size"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "4"
+	 * </pre>
+	 * <p>This option is used only if the tab char is set to MIXED.
+	 * </p>
+	 * @see #FORMATTER_TAB_CHAR
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INDENTATION_SIZE = JavaCore.PLUGIN_ID + ".formatter.indentation.size"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after an annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 * @deprecated
+	 * All new options must be enabled to activate old strategy
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER}
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE}
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER}
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after an annotation on a member (package, class, method, field declaration)
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.4
+	 * @deprecated
+	 * All new options must be enabled to activate old strategy
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD}
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD}
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE}
+	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE}
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_member";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * 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:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_field";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * 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
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_method";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * 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
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_package";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * 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>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_type";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after an annotation on a parameter
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.4
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_parameter";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after an annotation on a local variable
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.4
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_local_variable";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after a label
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_label"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_LABEL = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_label";	//$NON-NLS-1$	
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after the opening brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_opening_brace_in_array_initializer";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line at the end of the current file if missing
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_at_end_of_file_if_missing";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line before the catch keyword in try statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_before_catch_in_try_statement";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line before the closing brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_before_closing_brace_in_array_initializer";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line before the else keyword in if statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_before_else_in_if_statement";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line before the finally keyword in try statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_before_finally_in_try_statement";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line before while in do statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_before_while_in_do_statement";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty annotation declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.2
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_annotation_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty anonymous type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_anonymous_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_block";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty enum declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty method body
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_method_body";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line in an empty type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after and in wilcard
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_AND_IN_TYPE_PARAMETER = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_and_in_type_parameter"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after an assignment operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_assignment_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after at in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_at_in_annotation"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after at in annotation type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_at_in_annotation_type_declaration"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after a binary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_binary_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_binary_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the closing angle bracket in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_angle_bracket_in_type_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the closing angle bracket in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_angle_bracket_in_type_parameters"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the closing brace of a block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_brace_in_block"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the closing parenthesis of a cast expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_paren_in_cast"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the colon in an assert statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_ASSERT = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_colon_in_assert"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after colon in a case statement when a opening brace follows the colon
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_colon_in_case";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the colon in a conditional expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_colon_in_conditional"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after colon in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_colon_in_for";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the colon in a labeled statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_colon_in_labeled_statement"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in an allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_allocation_expression"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_annotation"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_array_initializer"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the parameters of a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_constructor_declaration_parameters"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the exception names in a throws clause of a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_constructor_declaration_throws"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the arguments of an enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_CONSTANT_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_enum_constant_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in enum declarations
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_enum_declarations"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the arguments of an explicit constructor call
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the increments of a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_for_increments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the initializations of a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_for_inits"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the parameters of a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_declaration_parameters"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the exception names in a throws clause of a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_declaration_throws"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the arguments of a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_invocation_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in multiple field declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_multiple_field_declarations"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in multiple local declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_multiple_local_declarations"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in parameterized type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_parameterized_type_reference"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in superinterfaces names of a type header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_SUPERINTERFACES = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_superinterfaces"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_type_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_type_parameters"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after ellipsis
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_ellipsis"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS  = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_ellipsis";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the -> in lambda expressions
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_LAMBDA_ARROW  = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_lambda_arrow";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening angle bracket in parameterized type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening angle bracket in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_type_arguments";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening angle bracket in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_type_parameters";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_brace_in_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening bracket inside an array allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_bracket_in_array_allocation_expression";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening bracket inside an array reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_bracket_in_array_reference";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_annotation"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a cast expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_cast"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a catch
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_catch"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_enum_constant"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_for"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in an if statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_if"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_method_invocation"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a parenthesized expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a switch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_switch"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a synchronized statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SYNCHRONIZED = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_synchronized"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a try with resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_try"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening parenthesis in a while statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_while"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after a postfix operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_postfix_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after a prefix operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_prefix_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after question mark in a conditional expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_question_in_conditional"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after question mark in a wildcard
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_WILDCARD = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_question_in_wildcard"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after semicolon in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_semicolon_in_for"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after semicolons following each resource declaration in a try with 
+	 * resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_semicolon_in_try_resources"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space after an unary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_unary_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_unary_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before and in wildcard
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_AND_IN_TYPE_PARAMETER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_and_in_type_parameter";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before an assignment operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_assignment_operator";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before at in annotation type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_AT_IN_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_at_in_annotation_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before an binary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_binary_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_binary_operator";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing angle bracket in parameterized type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference";		//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing angle bracket in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_angle_bracket_in_type_arguments";		//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing angle bracket in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_angle_bracket_in_type_parameters";		//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_brace_in_array_initializer";		//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing bracket in an array allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_bracket_in_array_allocation_expression";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing bracket in an array reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_bracket_in_array_reference";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_annotation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a cast expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_cast";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a catch
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_catch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_for";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in an if statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_if";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_method_invocation"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a parenthesized expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_parenthesized_expression"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a switch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_switch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a synchronized statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SYNCHRONIZED = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_synchronized";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a try with resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_try";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the closing parenthesis in a while statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_while";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in an assert statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_ASSERT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_assert";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in a case statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_case";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in a conditional expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_conditional";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in a default statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_default";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_for";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before colon in a labeled statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_colon_in_labeled_statement";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in an allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_allocation_expression";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_annotation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the parameters of a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_constructor_declaration_parameters";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the exception names of the throws clause of a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_constructor_declaration_throws";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the arguments of enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_CONSTANT_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_enum_constant_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in enum declarations
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_enum_declarations";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the arguments of an explicit constructor call
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_explicitconstructorcall_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the increments of a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_for_increments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the initializations of a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_for_inits";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the parameters of a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_declaration_parameters";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the exception names of the throws clause of a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_declaration_throws";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the arguments of a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_invocation_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in a multiple field declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_multiple_field_declarations";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in a multiple local declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_multiple_local_declarations";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in parameterized type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_parameterized_type_reference";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the superinterfaces names in a type header
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_SUPERINTERFACES = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_superinterfaces";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_type_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_type_parameters";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before ellipsis
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_ellipsis"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS  = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_ellipsis";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before lambda ->
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_ARROW = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_lambda_arrow";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening angle bracket in parameterized type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE  = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening angle bracket in type arguments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_angle_bracket_in_type_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening angle bracket in type parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_angle_bracket_in_type_parameters";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in an annotation type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_annotation_type_declaration"; 	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in an anonymous type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANONYMOUS_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"; 	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_array_initializer"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in a block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_block";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in an enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in an enum declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_enum_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in a switch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_switch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening brace in a type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening bracket in an array allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_bracket_in_array_allocation_expression";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening bracket in an array reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_bracket_in_array_reference";//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening bracket in an array type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_bracket_in_array_type_reference";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in annotation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_annotation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in annotation type member declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION_TYPE_MEMBER_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a catch
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_catch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_for";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in an if statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_if";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_invocation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a parenthesized expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a switch statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_switch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a synchronized statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SYNCHRONIZED = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_synchronized";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a try with resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_try";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a while statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_while";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before parenthesized expression in return statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 *
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.2
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN  = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_parenthesized_expression_in_return";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before parenthesized expression in throw statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 *
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_THROW  = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_parenthesized_expression_in_throw";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before a postfix operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_postfix_operator";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before a prefix operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_prefix_operator";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before question mark in a conditional expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_question_in_conditional";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before question mark in a wildcard
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_WILDCARD = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_question_in_wildcard"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before semicolon
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_semicolon"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_semicolon";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before semicolon in for statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_semicolon_in_for";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before semicolons following each resource declaration in a try with
+	 * resources statement
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_semicolon_in_try_resources";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space before unary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_unary_operator"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_unary_operator";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between brackets in an array type reference
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_BRACKETS_IN_ARRAY_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_brackets_in_array_type_reference";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty braces in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_braces_in_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty brackets in an array allocation expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS_IN_ARRAY_ALLOCATION_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_brackets_in_array_allocation_expression";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty parenthesis in an annotation type member declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ANNOTATION_TYPE_MEMBER_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty parenthesis in a constructor declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_CONSTRUCTOR_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_constructor_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty parenthesis in enum constant
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_enum_constant";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty parenthesis in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a space between empty parenthesis in a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_method_invocation";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to keep else statement on the same line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_else_statement_on_same_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to keep empty array initializer one one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_empty_array_initializer_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to keep guardian clause on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to keep simple if statement on the one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_imple_if_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to keep then statement on the same line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_then_statement_on_same_line";//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
+	 *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "80"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_LINE_SPLIT = JavaCore.PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent block comments that start on the first column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.formatter.never_indent_block_comments_on_first_column"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * Note that this option is ignored if the formatter is created with the mode {@link ToolFactory#M_FORMAT_NEW}.
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @see ToolFactory#createCodeFormatter(Map, int)
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN = JavaCore.PLUGIN_ID + ".formatter.never_indent_block_comments_on_first_column"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to indent line comments that start on the first column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.formatter.never_indent_line_comments_on_first_column"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * Note that:
+	 * <ul>
+	 * <li>this option is ignored if the formatter is created with the mode {@link ToolFactory#M_FORMAT_NEW}</li>
+	 * <li>even with this option activated, the formatter still can ignore line comments starting at first column
+	 * if the option {@link #FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN} is set to {@value #FALSE}</li>
+	 * </ul>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @see ToolFactory#createCodeFormatter(Map, int)
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN = JavaCore.PLUGIN_ID + ".formatter.never_indent_line_comments_on_first_column"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the number of empty lines to preserve
+	 *     - option id:         "org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE = JavaCore.PLUGIN_ID + ".formatter.number_of_empty_lines_to_preserve";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify whether the formatter can join wrapped lines or not
+	 * 
+	 * 		For example, the wrapped lines of method foo return statement in following test case:
+	 * 			class X {
+	 * 			String foo() {
+	 * 			return "select x "
+	 * 			       + "from y "
+	 * 			       + "where z=a";
+	 * 			}
+	 * 			}
+	 *
+	 * 		will be preserved by the formatter when the new preference is used
+	 * 		even if the maximum line width would give it enough space to join the lines.
+	 * 		Hence produces the following output:
+	 * 			class X {
+	 * 			    String foo() {
+	 * 			        return "select x "
+	 * 			                + "from y "
+	 * 			                + "where z=a";
+	 * 			    }
+	 * 			}
+	 *
+	 *     - option id:         "org.eclipse.jdt.core.formatter.join_wrapped_lines"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @since 3.5
+	 */
+	public static final String FORMATTER_JOIN_WRAPPED_LINES = JavaCore.PLUGIN_ID + ".formatter.join_wrapped_lines";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify whether the formatter can join text lines in comments or not
+	 * 
+	 * 		For example, the following comment:
+	 * 			/**
+	 * 			 * The foo method.
+	 * 			 * foo is a substitute for bar.
+	 * 			 *&#0047;
+	 * 			public class X {
+	 * 			}
+	 * 
+	 * 		will be unchanged by the formatter when this new preference is used,
+	 * 		even if the maximum line width would give it enough space to join the lines.
+	 *
+	 *     - option id:         "org.eclipse.jdt.core.formatter.join_lines_in_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @since 3.5
+	 */
+	public static final String FORMATTER_JOIN_LINES_IN_COMMENTS = JavaCore.PLUGIN_ID + ".formatter.join_lines_in_comments";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify whether or not empty statement should be on a new line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE = JavaCore.PLUGIN_ID + ".formatter.put_empty_statement_on_new_line";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the tabulation size
+	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.char"
+	 *     - possible values:   { TAB, SPACE, MIXED }
+	 *     - default:           TAB
+	 * </pre>
+	 * More values may be added in the future.
+	 *
+	 * @see JavaCore#TAB
+	 * @see JavaCore#SPACE
+	 * @see #MIXED
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_TAB_CHAR = JavaCore.PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the equivalent number of spaces that represents one tabulation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "4"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_TAB_SIZE = JavaCore.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to use tabulations for indentation and spaces for line wrapping
+	 *     - option id:         "org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS = JavaCore.PLUGIN_ID + ".formatter.use_tabs_only_for_leading_indentations"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to wrap before the binary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.wrap_before_binary_operator"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * This option is used only if the option {@link #FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION} is set.
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_WRAP_BEFORE_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.wrap_before_binary_operator"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to wrap before the '|' operator in multi-catch statements
+	 *     - option id:         "org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * This option is used only if the option {@link #FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH} is set.
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.7.1
+	 */
+	public static final String FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH = JavaCore.PLUGIN_ID + ".formatter.wrap_before_or_operator_multicatch"; //$NON-NLS-1$
+	/**
+	 * <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
+	 * </pre>
+	 * <p>
+	 * 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.</p>
+	 * <p>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:</p>
+	 * <pre>
+	 * public class X01 {
+	 *     void test() {
+	 *         foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));
+	 *     }
+	 * }
+	 * </pre>
+	 * <p>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.</p>
+	 * <p>Hence, the output will be:</p>
+	 * <pre>
+	 * public class X01 {
+	 *     void test() {
+	 *         foo(bar(1, 2, 3, 4),
+	 *             bar(5, 6, 7, 8));
+	 *     }
+	 * }
+	 * </pre>
+	 * <p>
+	 * </p>
+	 * <p><b><u>Important notes</u></b>:</p>
+	 * <ol>
+	 * <li>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.</li>
+	 * <li>The new strategy currently only applies to nested method calls, but might be extended to other nested expressions in future versions</li>
+	 * </ol>
+	 * 
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.6
+	 */
+	public static final String FORMATTER_WRAP_OUTER_EXPRESSIONS_WHEN_NESTED = JavaCore.PLUGIN_ID + ".formatter.wrap_outer_expressions_when_nested"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_BY_ONE= 2;
+
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by using the current indentation.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_DEFAULT= 0;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by indenting on column under the splitting location.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_ON_COLUMN = 1;
+
+	/**
+	 * <pre>
+	 * FORMATTER / Possible value for the option FORMATTER_TAB_CHAR
+	 * </pre>
+	 * @since 3.1
+	 * @see JavaCore#TAB
+	 * @see JavaCore#SPACE
+	 * @see #FORMATTER_TAB_CHAR
+	 */
+	public static final String MIXED = "mixed"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line with
+	 *             the right indentation.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY
+	 * @since 3.0
+	 */
+	public static final String NEXT_LINE = "next_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line if a wrapping
+	 *             occured.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY
+	 * @since 3.0
+	 */
+    public static final String NEXT_LINE_ON_WRAP = "next_line_on_wrap"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line with
+	 *             an extra indentation.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY
+	 * @since 3.0
+	 */
+	public static final String NEXT_LINE_SHIFTED = "next_line_shifted";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set an option to true.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String TRUE = "true"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done using as few lines as possible.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_COMPACT= 1;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done putting the first element on a new
+	 *             line and then wrapping next elements using as few lines as possible.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_COMPACT_FIRST_BREAK= 2;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line
+	 *             except the first element.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NEXT_PER_LINE= 5;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line.
+	 *             All elements are indented by one except the first element.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NEXT_SHIFTED= 4;
+
+	/**
+	 * <pre>
+	 * FORMATTER / Value to disable alignment.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NO_SPLIT= 0;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_ONE_PER_LINE= 3;
+
+	/*
+	 * Private constants. Not in javadoc
+	 */
+	private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
+	/**
+	 * Create a new alignment value according to the given values. This must be used to set up
+	 * the alignment options.
+	 *
+	 * @param forceSplit the given force value
+	 * @param wrapStyle the given wrapping style
+	 * @param indentStyle the given indent style
+	 *
+	 * @return the new alignement value
+	 */
+	public static String createAlignmentValue(boolean forceSplit, int wrapStyle, int indentStyle) {
+		int alignmentValue = 0;
+		switch(wrapStyle) {
+			case WRAP_COMPACT :
+				alignmentValue |= Alignment.M_COMPACT_SPLIT;
+				break;
+			case WRAP_COMPACT_FIRST_BREAK :
+				alignmentValue |= Alignment.M_COMPACT_FIRST_BREAK_SPLIT;
+				break;
+			case WRAP_NEXT_PER_LINE :
+				alignmentValue |= Alignment.M_NEXT_PER_LINE_SPLIT;
+				break;
+			case WRAP_NEXT_SHIFTED :
+				alignmentValue |= Alignment.M_NEXT_SHIFTED_SPLIT;
+				break;
+			case WRAP_ONE_PER_LINE :
+				alignmentValue |= Alignment.M_ONE_PER_LINE_SPLIT;
+				break;
+		}
+		if (forceSplit) {
+			alignmentValue |= Alignment.M_FORCE;
+		}
+		switch(indentStyle) {
+			case INDENT_BY_ONE :
+				alignmentValue |= Alignment.M_INDENT_BY_ONE;
+				break;
+			case INDENT_ON_COLUMN :
+				alignmentValue |= Alignment.M_INDENT_ON_COLUMN;
+		}
+		return String.valueOf(alignmentValue);
+	}
+
+	/**
+	 * Returns the formatter settings that most closely approximate
+	 * the default formatter settings of Eclipse version 2.1.
+	 *
+	 * @return the Eclipse 2.1 settings
+	 * @since 3.0
+	 */
+	public static Map getEclipse21Settings() {
+		return DefaultCodeFormatterOptions.getDefaultSettings().getMap();
+	}
+
+	/**
+	 * Returns the default Eclipse formatter settings
+	 *
+	 * @return the Eclipse default settings
+	 * @since 3.1
+	 */
+	public static Map getEclipseDefaultSettings() {
+		return DefaultCodeFormatterOptions.getEclipseDefaultSettings().getMap();
+	}
+
+	/**
+	 * <p>Return the force value of the given alignment value.
+	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @return the force value of the given alignment value
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, or if it
+	 * doesn't have a valid format.
+	 */
+	public static boolean getForceWrapping(String value) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			return (existingValue & Alignment.M_FORCE) != 0;
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+
+	/**
+	 * <p>Return the indentation style of the given alignment value.
+	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @return the indentation style of the given alignment value
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, or if it
+	 * doesn't have a valid format.
+	 */
+	public static int getIndentStyle(String value) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			if ((existingValue & Alignment.M_INDENT_BY_ONE) != 0) {
+				return INDENT_BY_ONE;
+			} else if ((existingValue & Alignment.M_INDENT_ON_COLUMN) != 0) {
+				return INDENT_ON_COLUMN;
+			} else {
+				return INDENT_DEFAULT;
+			}
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+
+	/**
+	 * Returns the settings according to the Java conventions.
+	 *
+	 * @return the settings according to the Java conventions
+	 * @since 3.0
+	 */
+	public static Map getJavaConventionsSettings() {
+		return DefaultCodeFormatterOptions.getJavaConventionsSettings().getMap();
+	}
+	/**
+	 * <p>Return the wrapping style of the given alignment value.
+	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @return the wrapping style of the given alignment value
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, or if it
+	 * doesn't have a valid format.
+	 */
+	public static int getWrappingStyle(String value) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value) & Alignment.SPLIT_MASK;
+			switch(existingValue) {
+				case Alignment.M_COMPACT_SPLIT :
+					return WRAP_COMPACT;
+				case Alignment.M_COMPACT_FIRST_BREAK_SPLIT :
+					return WRAP_COMPACT_FIRST_BREAK;
+				case Alignment.M_NEXT_PER_LINE_SPLIT :
+					return WRAP_NEXT_PER_LINE;
+				case Alignment.M_NEXT_SHIFTED_SPLIT :
+					return WRAP_NEXT_SHIFTED;
+				case Alignment.M_ONE_PER_LINE_SPLIT :
+					return WRAP_ONE_PER_LINE;
+				default:
+					return WRAP_NO_SPLIT;
+			}
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+	/**
+	 * <p>Set the force value of the given alignment value and return the new value.
+	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @param force the given force value
+	 * @return the new alignment value
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, or if it
+	 * doesn't have a valid format.
+	 */
+	public static String setForceWrapping(String value, boolean force) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			// clear existing force bit
+			existingValue &= ~Alignment.M_FORCE;
+			if (force) {
+				existingValue |= Alignment.M_FORCE;
+			}
+			return String.valueOf(existingValue);
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+
+	/**
+	 * <p>Set the indentation style of the given alignment value and return the new value.
+	 * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @param indentStyle the given indentation style
+	 * @return the new alignment value
+	 * @see #INDENT_BY_ONE
+	 * @see #INDENT_DEFAULT
+	 * @see #INDENT_ON_COLUMN
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, if the given
+	 * indentation style is not one of the possible indentation styles, or if the given
+	 * alignment value doesn't have a valid format.
+	 */
+	public static String setIndentStyle(String value, int indentStyle) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		switch(indentStyle) {
+			case INDENT_BY_ONE :
+			case INDENT_DEFAULT :
+			case INDENT_ON_COLUMN :
+				break;
+			default :
+				throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			// clear existing indent bits
+			existingValue &= ~(Alignment.M_INDENT_BY_ONE | Alignment.M_INDENT_ON_COLUMN);
+			switch(indentStyle) {
+				case INDENT_BY_ONE :
+					existingValue |= Alignment.M_INDENT_BY_ONE;
+					break;
+				case INDENT_ON_COLUMN :
+					existingValue |= Alignment.M_INDENT_ON_COLUMN;
+			}
+			return String.valueOf(existingValue);
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+	/**
+	 * <p>Set the wrapping style of the given alignment value and return the new value.
+	 * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
+	 * API.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @param wrappingStyle the given wrapping style
+	 * @return the new alignment value
+	 * @see #WRAP_COMPACT
+	 * @see #WRAP_COMPACT_FIRST_BREAK
+	 * @see #WRAP_NEXT_PER_LINE
+	 * @see #WRAP_NEXT_SHIFTED
+	 * @see #WRAP_NO_SPLIT
+	 * @see #WRAP_ONE_PER_LINE
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, if the given
+	 * wrapping style is not one of the possible wrapping styles, or if the given
+	 * alignment value doesn't have a valid format.
+	 */
+	public static String setWrappingStyle(String value, int wrappingStyle) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		switch(wrappingStyle) {
+			case WRAP_COMPACT :
+			case WRAP_COMPACT_FIRST_BREAK :
+			case WRAP_NEXT_PER_LINE :
+			case WRAP_NEXT_SHIFTED :
+			case WRAP_NO_SPLIT :
+			case WRAP_ONE_PER_LINE :
+				break;
+			default:
+				throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			// clear existing split bits
+			existingValue &= ~(Alignment.SPLIT_MASK);
+			switch(wrappingStyle) {
+				case WRAP_COMPACT :
+					existingValue |= Alignment.M_COMPACT_SPLIT;
+					break;
+				case WRAP_COMPACT_FIRST_BREAK :
+					existingValue |= Alignment.M_COMPACT_FIRST_BREAK_SPLIT;
+					break;
+				case WRAP_NEXT_PER_LINE :
+					existingValue |= Alignment.M_NEXT_PER_LINE_SPLIT;
+					break;
+				case WRAP_NEXT_SHIFTED :
+					existingValue |= Alignment.M_NEXT_SHIFTED_SPLIT;
+					break;
+				case WRAP_ONE_PER_LINE :
+					existingValue |= Alignment.M_ONE_PER_LINE_SPLIT;
+					break;
+			}
+			return String.valueOf(existingValue);
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java
new file mode 100644
index 0000000..da519a7
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/IndentManipulation.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.formatter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+
+import org.eclipse.text.edits.ReplaceEdit;
+
+/**
+ * Helper class to provide String manipulation functions dealing with indentations.
+ *
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class IndentManipulation {
+
+	private IndentManipulation() {
+		// don't instantiate
+	}
+
+	/**
+	 * Returns <code>true</code> if the given character is an indentation character. Indentation character are all whitespace characters
+	 * except the line delimiter characters.
+	 *
+	 * @param ch the given character
+	 * @return Returns <code>true</code> if this the character is a indent character, <code>false</code> otherwise
+	 */
+	public static boolean isIndentChar(char ch) {
+		return ScannerHelper.isWhitespace(ch) && !isLineDelimiterChar(ch);
+	}
+
+	/**
+	 * Returns <code>true</code> if the given character is a line delimiter character.
+	 *
+	 * @param ch the given character
+	 * @return Returns <code>true</code> if this the character is a line delimiter character, <code>false</code> otherwise
+	 */
+	public static boolean isLineDelimiterChar(char ch) {
+		return ch == '\n' || ch == '\r';
+	}
+
+	/**
+	 * Returns the indentation of the given line in indentation units. Odd spaces are
+	 * not counted. This method only analyzes the content of <code>line</code> up to the first
+	 * non-whitespace character.
+	 *
+	 * @param line the string to measure the indent of
+	 * @param tabWidth the width of one tab character in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @return the number of indentation units that line is indented by
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>indentWidth</code> is lower than zero</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * <li>the given <code>line</code> is null</li>
+	 * </ul>
+	 */
+	public static int measureIndentUnits(CharSequence line, int tabWidth, int indentWidth) {
+		if (indentWidth < 0 || tabWidth < 0 || line == null) {
+			throw new IllegalArgumentException();
+		}
+
+		if (indentWidth == 0) return 0;
+		int visualLength= measureIndentInSpaces(line, tabWidth);
+		return visualLength / indentWidth;
+	}
+
+	/**
+	 * Returns the indentation of the given line in space equivalents.
+	 *
+	 * <p>Tab characters are counted using the given <code>tabWidth</code> and every other indent
+	 * character as one. This method analyzes the content of <code>line</code> up to the first
+	 * non-whitespace character.</p>
+	 *
+	 * @param line the string to measure the indent of
+	 * @param tabWidth the width of one tab in space equivalents
+	 * @return the measured indent width in space equivalents
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>line</code> is null</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * </ul>
+	 */
+	public static int measureIndentInSpaces(CharSequence line, int tabWidth) {
+		if (tabWidth < 0 || line == null) {
+			throw new IllegalArgumentException();
+		}
+
+		int length= 0;
+		int max= line.length();
+		for (int i= 0; i < max; i++) {
+			char ch= line.charAt(i);
+			if (ch == '\t') {
+				length = calculateSpaceEquivalents(tabWidth, length);
+			} else if (isIndentChar(ch)) {
+				length++;
+			} else {
+				return length;
+			}
+		}
+		return length;
+	}
+
+	/**
+	 * Returns the leading indentation string of the given line. Note that the returned string
+	 * need not be equal to the leading whitespace as odd spaces are not considered part of the
+	 * indentation.
+	 *
+	 * @param line the line to scan
+	 * @param tabWidth the size of one tab in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @return the indent part of <code>line</code>, but no odd spaces
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>indentWidth</code> is lower than zero</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * <li>the given <code>line</code> is null</li>
+	 * </ul>
+	 */
+	public static String extractIndentString(String line, int tabWidth, int indentWidth) {
+		if (tabWidth < 0 || indentWidth < 0 || line == null) {
+			throw new IllegalArgumentException();
+		}
+
+		int size = line.length();
+		int end = 0;
+
+		int spaceEquivs = 0;
+		int characters = 0;
+		for (int i = 0; i < size; i++) {
+			char c = line.charAt(i);
+			if (c == '\t') {
+				spaceEquivs = calculateSpaceEquivalents(tabWidth, spaceEquivs);
+				characters++;
+			} else if (isIndentChar(c)) {
+				spaceEquivs++;
+				characters++;
+			} else {
+				break;
+			}
+			if (spaceEquivs >= indentWidth) {
+				end += characters;
+				characters = 0;
+				if(indentWidth == 0) {
+					spaceEquivs = 0;
+				} else {
+					spaceEquivs = spaceEquivs % indentWidth;
+				}
+			}
+		}
+		if (end == 0) {
+			return Util.EMPTY_STRING;
+		} else if (end == size) {
+			return line;
+		} else {
+			return line.substring(0, end);
+		}
+	}
+
+
+	/**
+	 * Removes the given number of indentation units from a given line. If the line
+	 * has less indent than the given indentUnitsToRemove, all the available indentation is removed.
+	 * If <code>indentsToRemove <= 0 or indent == 0</code> the line is returned.
+	 *
+	 * @param line the line to trim
+	 * @param tabWidth the width of one tab in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @return the trimmed string
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>indentWidth</code> is lower than zero</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * <li>the given <code>line</code> is null</li>
+	 * </ul>
+	 */
+	public static String trimIndent(String line, int indentUnitsToRemove, int tabWidth, int indentWidth) {
+		if (tabWidth < 0 || indentWidth < 0 || line == null) {
+			throw new IllegalArgumentException();
+		}
+
+		if (indentUnitsToRemove <= 0 || indentWidth == 0) {
+			return line;
+		}
+		final int spaceEquivalentsToRemove= indentUnitsToRemove * indentWidth;
+
+		int start= 0;
+		int spaceEquivalents= 0;
+		int size= line.length();
+		String prefix= null;
+		for (int i= 0; i < size; i++) {
+			char c= line.charAt(i);
+			if (c == '\t') {
+				spaceEquivalents = calculateSpaceEquivalents(tabWidth, spaceEquivalents);
+			} else if (isIndentChar(c)) {
+				spaceEquivalents++;
+			} else {
+				// Assert.isTrue(false, "Line does not have requested number of indents");
+				start= i;
+				break;
+			}
+			if (spaceEquivalents == spaceEquivalentsToRemove) {
+				start= i + 1;
+				break;
+			}
+			if (spaceEquivalents > spaceEquivalentsToRemove) {
+				// can happen if tabSize > indentSize, e.g tabsize==8, indent==4, indentsToRemove==1, line prefixed with one tab
+				// this implements the third option
+				start= i + 1; // remove the tab
+				// and add the missing spaces
+				char[] missing= new char[spaceEquivalents - spaceEquivalentsToRemove];
+				Arrays.fill(missing, ' ');
+				prefix= new String(missing);
+				break;
+			}
+		}
+		String trimmed;
+		if (start == size)
+			trimmed= Util.EMPTY_STRING;
+		else
+			trimmed= line.substring(start);
+
+		if (prefix == null)
+			return trimmed;
+		return prefix + trimmed;
+	}
+
+	/**
+	 * Change the indent of a, possible multiple line, code string. The given number of indent units is removed,
+	 * and a new indent string is added.
+	 * <p>The first line of the code will not be changed (It is considered to have no indent as it might start in
+	 * the middle of a line).</p>
+	 *
+	 * @param code the code to change the indent of
+	 * @param indentUnitsToRemove the number of indent units to remove from each line (except the first) of the given code
+	 * @param tabWidth the size of one tab in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @param newIndentString the new indent string to be added to all lines (except the first)
+	 * @param lineDelim the new line delimiter to be used. The returned code will contain only this line delimiter.
+	 * @return the newly indent code, containing only the given line delimiters.
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>indentWidth</code> is lower than zero</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * <li>the given <code>code</code> is null</li>
+	 * <li>the given <code>indentUnitsToRemove</code> is lower than zero</li>
+	 * <li>the given <code>newIndentString</code> is null</li>
+	 * <li>the given <code>lineDelim</code> is null</li>
+	 * </ul>
+	 */
+	public static String changeIndent(String code, int indentUnitsToRemove, int tabWidth, int indentWidth, String newIndentString, String lineDelim) {
+		if (tabWidth < 0 || indentWidth < 0 || code == null || indentUnitsToRemove < 0 || newIndentString == null || lineDelim == null) {
+			throw new IllegalArgumentException();
+		}
+
+		try {
+			ILineTracker tracker= new DefaultLineTracker();
+			tracker.set(code);
+			int nLines= tracker.getNumberOfLines();
+			if (nLines == 1) {
+				return code;
+			}
+
+			StringBuffer buf= new StringBuffer();
+
+			for (int i= 0; i < nLines; i++) {
+				IRegion region= tracker.getLineInformation(i);
+				int start= region.getOffset();
+				int end= start + region.getLength();
+				String line= code.substring(start, end);
+
+				if (i == 0) {  // no indent for first line (contained in the formatted string)
+					buf.append(line);
+				} else { // no new line after last line
+					buf.append(lineDelim);
+					buf.append(newIndentString);
+					if(indentWidth != 0) {
+						buf.append(trimIndent(line, indentUnitsToRemove, tabWidth, indentWidth));
+					} else {
+						buf.append(line);
+					}
+				}
+			}
+			return buf.toString();
+		} catch (BadLocationException e) {
+			// can not happen
+			return code;
+		}
+	}
+
+	/**
+	 * Returns the text edits retrieved after changing the indentation of a, possible multi-line, code string.
+	 *
+	 * <p>The given number of indent units is removed, and a new indent string is added.</p>
+	 * <p>The first line of the code will not be changed (It is considered to have no indent as it might start in
+	 * the middle of a line).</p>
+	 *
+	 * @param source The code to change the indent of
+	 * @param indentUnitsToRemove the number of indent units to remove from each line (except the first) of the given code
+	 * @param tabWidth the size of one tab in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @param newIndentString the new indent string to be added to all lines (except the first)
+	 * @return returns the resulting text edits
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the given <code>indentWidth</code> is lower than zero</li>
+	 * <li>the given <code>tabWidth</code> is lower than zero</li>
+	 * <li>the given <code>source</code> is null</li>
+	 * <li>the given <code>indentUnitsToRemove</code> is lower than zero</li>
+	 * <li>the given <code>newIndentString</code> is null</li>
+	 * </ul>
+	 */
+	public static ReplaceEdit[] getChangeIndentEdits(String source, int indentUnitsToRemove, int tabWidth, int indentWidth, String newIndentString) {
+		if (tabWidth < 0 || indentWidth < 0 || source == null || indentUnitsToRemove < 0 || newIndentString == null) {
+			throw new IllegalArgumentException();
+		}
+
+		ArrayList result= new ArrayList();
+		try {
+			ILineTracker tracker= new DefaultLineTracker();
+			tracker.set(source);
+			int nLines= tracker.getNumberOfLines();
+			if (nLines == 1)
+				return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]);
+			for (int i= 1; i < nLines; i++) {
+				IRegion region= tracker.getLineInformation(i);
+				int offset= region.getOffset();
+				String line= source.substring(offset, offset + region.getLength());
+				int length= indexOfIndent(line, indentUnitsToRemove, tabWidth, indentWidth);
+				if (length >= 0) {
+					result.add(new ReplaceEdit(offset, length, newIndentString));
+				} else {
+					length= measureIndentUnits(line, tabWidth, indentWidth);
+					result.add(new ReplaceEdit(offset, length, "")); //$NON-NLS-1$
+				}
+			}
+		} catch (BadLocationException cannotHappen) {
+			// can not happen
+		}
+		return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]);
+	}
+
+	/*
+	 * Returns the index where the indent of the given size ends.
+	 * Returns <code>-1<code> if the line isn't prefixed with an indent of
+	 * the given number of indents.
+	 */
+	private static int indexOfIndent(CharSequence line, int numberOfIndentUnits, int tabWidth, int indentWidth) {
+
+		int spaceEquivalents= numberOfIndentUnits * indentWidth;
+
+		int size= line.length();
+		int result= -1;
+		int blanks= 0;
+		for (int i= 0; i < size && blanks < spaceEquivalents; i++) {
+			char c= line.charAt(i);
+			if (c == '\t') {
+				blanks = calculateSpaceEquivalents(tabWidth, blanks);
+			} else if (isIndentChar(c)) {
+				blanks++;
+			} else {
+				break;
+			}
+			result= i;
+		}
+		if (blanks < spaceEquivalents)
+			return -1;
+		return result + 1;
+	}
+
+	/*
+	 * Calculates space equivalents up to the next tab stop
+	 */
+	private static int calculateSpaceEquivalents(int tabWidth, int spaceEquivalents) {
+		if (tabWidth == 0){
+			return spaceEquivalents;
+		}
+		int remainder = spaceEquivalents % tabWidth;
+		spaceEquivalents += tabWidth - remainder;
+		return spaceEquivalents;
+	}
+
+	/**
+	 * Returns the tab width as configured in the given map.
+	 * <p>Use {@link org.eclipse.jdt.core.IJavaProject#getOptions(boolean)} to get the most current project options.</p>
+	 *
+	 * @param options the map to get the formatter settings from.
+	 *
+	 * @return the tab width
+	 * @exception IllegalArgumentException if the given <code>options</code> is null
+	 */
+	public static int getTabWidth(Map options) {
+		if (options == null) {
+			throw new IllegalArgumentException();
+		}
+		return getIntValue(options, DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4);
+	}
+
+	/**
+	 * Returns the tab width as configured in the given map.
+	 * <p>Use {@link org.eclipse.jdt.core.IJavaProject#getOptions(boolean)} to get the most current project options.</p>
+	 *
+	 * @param options the map to get the formatter settings from
+	 *
+	 * @return the indent width
+	 * @exception IllegalArgumentException if the given <code>options</code> is null
+	 */
+	public static int getIndentWidth(Map options) {
+		if (options == null) {
+			throw new IllegalArgumentException();
+		}
+		int tabWidth=getTabWidth(options);
+		boolean isMixedMode= DefaultCodeFormatterConstants.MIXED.equals(options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
+		if (isMixedMode) {
+			return getIntValue(options, DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, tabWidth);
+		}
+		return tabWidth;
+	}
+
+	private static int getIntValue(Map options, String key, int def) {
+		try {
+			return Integer.parseInt((String) options.get(key));
+		} catch (NumberFormatException e) {
+			return def;
+		}
+	}
+}
+
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/messages.properties b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/messages.properties
new file mode 100644
index 0000000..c606e38
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/messages.properties
@@ -0,0 +1,44 @@
+###############################################################################
+# Copyright (c) 2006, 2011 Ben Konrath <ben@bagu.org>
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     Ben Konrath <ben@bagu.org> - initial implementation
+#     IBM Corporation - Code review and integration
+#     IBM Corporation - Fix for 340181
+###############################################################################
+CommandLineStart=Starting format job ...
+CommandLineDone=Done.
+CommandLineConfigFile=Configuration Name: {0}
+CommandLineFormatting=Formatting: {0}
+
+CommandLineUsage=Usage: eclipse -application org.eclipse.jdt.core.JavaCodeFormatter [ OPTIONS ] -config <configFile> <files>\n\
+\n\
+\   <files>   Java source files and/or directories to format.\n\
+\             Only files ending with .java will be formatted in the given directory.\n\
+\   -config <configFile> Use the formatting style from the specified properties file.\n\
+\                        Refer to the help documentation to find out how to generate this file.\n\
+\n\
+\ OPTIONS:\n\
+\n\
+\   -help                Display this message.\n\
+\   -quiet               Only print error messages.\n\
+\   -verbose             Be verbose about the formatting job.
+
+CommandLineErrorFileTryFullPath={0} does not exist. Please try specifying valid absolute path. 
+CommandLineErrorFile={0} does not exist. Please specify only valid Java Source files.
+CommandLineErrorConfig=A problem occurred while reading the config file {0}.
+CommandLineErrorFileDir=You must specify at least one file or directory to format.
+CommandLineErrorQuietVerbose=You cannot use the options {0} and {1} together.
+CommandLineErrorNoConfigFile=No configuration file specified.
+
+CaughtException=Caught {0} : {1}
+ExceptionSkip= {0}\nSkipping File.
+
+ConfigFileNotFoundErrorTryFullPath=Error reading configuration file (file path : {0}, current user directory used to read the file: {1}). Try specifying absolute path.
+ConfigFileReadingError=Error reading configuration file {0}.
+
+FormatProblem=The Eclipse formatter failed to format {0}. Skip the file.
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html
new file mode 100644
index 0000000..90588e9
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html
@@ -0,0 +1,19 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+The code formatter is the set of classes that are used to format Java code.
+
+<h2>
+Package Specification</h2>
+
+<p>This package contains classes to format Java code.
+The principal classes are {@link org.eclipse.jdt.core.formatter.CodeFormatter CodeFormatter} and
+{@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants DefaultCodeFormatterConstants}.
+</p>
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java
new file mode 100644
index 0000000..156b944
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+/**
+ * Unchecked exception wrapping invalid input checked exception which may occur
+ * when scanning original formatted source.
+ *
+ * @since 2.1
+ */
+public class AbortFormatting extends RuntimeException {
+
+	Throwable nestedException;
+	private static final long serialVersionUID = -5796507276311428526L; // backward compatible
+
+	public AbortFormatting(String message) {
+		super(message);
+	}
+	public AbortFormatting(Throwable nestedException) {
+		super(nestedException.getMessage());
+		this.nestedException = nestedException;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java
new file mode 100644
index 0000000..2c196de
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java
@@ -0,0 +1,479 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
+import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.FloatLiteral;
+import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.ast.LongLiteral;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
+import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+class BinaryExpressionFragmentBuilder
+	extends ASTVisitor {
+
+	ArrayList fragmentsList;
+	ArrayList operatorsList;
+	private int realFragmentsSize;
+
+	BinaryExpressionFragmentBuilder() {
+		this.fragmentsList = new ArrayList();
+		this.operatorsList = new ArrayList();
+		this.realFragmentsSize = 0;
+	}
+
+	private final void addRealFragment(ASTNode node) {
+		this.fragmentsList.add(node);
+		this.realFragmentsSize++;
+	}
+
+	private final void addSmallFragment(ASTNode node) {
+		this.fragmentsList.add(node);
+	}
+
+	private boolean buildFragments(Expression expression) {
+		if (((expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+			addRealFragment(expression);
+			return false;
+		}
+		return true;
+	}
+
+	public ASTNode[] fragments() {
+		ASTNode[] fragments = new ASTNode[this.fragmentsList.size()];
+		this.fragmentsList.toArray(fragments);
+		return fragments;
+	}
+
+	public int[] operators() {
+		int length = this.operatorsList.size();
+		int[] tab = new int[length];
+		for (int i = 0; i < length; i++) {
+			tab[i] = ((Integer)this.operatorsList.get(i)).intValue();
+		}
+		return tab;
+	}
+
+	public int realFragmentsSize() {
+		return this.realFragmentsSize;
+	}
+
+	public boolean visit(
+		AllocationExpression allocationExpression,
+		BlockScope scope) {
+			addRealFragment(allocationExpression);
+			return false;
+	}
+
+	public boolean visit(
+		AND_AND_Expression and_and_Expression,
+		BlockScope scope) {
+
+		if (((and_and_Expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+			addRealFragment(and_and_Expression);
+		} else {
+			and_and_Expression.left.traverse(this, scope);
+			this.operatorsList.add(new Integer(TerminalTokens.TokenNameAND_AND));
+			and_and_Expression.right.traverse(this, scope);
+		}
+		return false;
+	}
+
+	public boolean visit(
+		ArrayAllocationExpression arrayAllocationExpression,
+		BlockScope scope) {
+			addRealFragment(arrayAllocationExpression);
+			return false;
+	}
+
+	public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		addRealFragment(arrayInitializer);
+		return false;
+	}
+
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		BlockScope scope) {
+			addRealFragment(arrayQualifiedTypeReference);
+			return false;
+	}
+
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		ClassScope scope) {
+			addRealFragment(arrayQualifiedTypeReference);
+			return false;
+	}
+
+	public boolean visit(ArrayReference arrayReference, BlockScope scope) {
+		addRealFragment(arrayReference);
+		return false;
+	}
+
+	public boolean visit(
+		ArrayTypeReference arrayTypeReference,
+		BlockScope scope) {
+			addRealFragment(arrayTypeReference);
+			return false;
+	}
+
+	public boolean visit(
+		ArrayTypeReference arrayTypeReference,
+		ClassScope scope) {
+			addRealFragment(arrayTypeReference);
+			return false;
+	}
+
+	public boolean visit(Assignment assignment, BlockScope scope) {
+		addRealFragment(assignment);
+		return false;
+	}
+
+	public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
+		if (binaryExpression instanceof CombinedBinaryExpression) {
+			CombinedBinaryExpression expression = (CombinedBinaryExpression) binaryExpression;
+			if (expression.referencesTable != null) {
+				return this.visit(expression, scope);
+			}
+		}
+		final int numberOfParens = (binaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			addRealFragment(binaryExpression);
+		} else {
+			switch((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
+				case OperatorIds.PLUS :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.MINUS :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameMINUS));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.MULTIPLY :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameMULTIPLY));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.REMAINDER :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameREMAINDER));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.XOR :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameXOR));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.DIVIDE :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameDIVIDE));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.OR :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameOR));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				case OperatorIds.AND :
+					if (buildFragments(binaryExpression)) {
+						binaryExpression.left.traverse(this, scope);
+						this.operatorsList.add(new Integer(TerminalTokens.TokenNameAND));
+						binaryExpression.right.traverse(this, scope);
+					}
+					return false;
+				default:
+					addRealFragment(binaryExpression);
+			}
+		}
+		return false;
+	}
+
+	public boolean visit(CombinedBinaryExpression combinedBinaryExpression, BlockScope scope) {
+		// keep implementation in sync with BinaryExpression#resolveType
+		if (combinedBinaryExpression.referencesTable == null) {
+			addRealFragment(combinedBinaryExpression.left);
+			this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+			addRealFragment(combinedBinaryExpression.right);
+			return false;
+		}
+		BinaryExpression cursor = combinedBinaryExpression.referencesTable[0];
+		if (cursor.left instanceof CombinedBinaryExpression) {
+			this.visit((CombinedBinaryExpression) cursor.left, scope);
+		} else {
+			addRealFragment(cursor.left);
+		}
+		for (int i = 0, end = combinedBinaryExpression.arity; i < end; i ++) {
+			this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+			addRealFragment(combinedBinaryExpression.referencesTable[i].right);
+		}
+		this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+		addRealFragment(combinedBinaryExpression.right);
+		return false;
+	}
+
+	public boolean visit(CastExpression castExpression, BlockScope scope) {
+		addRealFragment(castExpression);
+		return false;
+	}
+
+	public boolean visit(CharLiteral charLiteral, BlockScope scope) {
+		addSmallFragment(charLiteral);
+		return false;
+	}
+
+	public boolean visit(
+		ClassLiteralAccess classLiteralAccess,
+		BlockScope scope) {
+			addRealFragment(classLiteralAccess);
+			return false;
+	}
+
+	public boolean visit(
+		CompoundAssignment compoundAssignment,
+		BlockScope scope) {
+			addRealFragment(compoundAssignment);
+			return false;
+	}
+
+	public boolean visit(
+		ConditionalExpression conditionalExpression,
+		BlockScope scope) {
+			addRealFragment(conditionalExpression);
+			return false;
+	}
+
+	public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) {
+		addSmallFragment(doubleLiteral);
+		return false;
+	}
+
+	public boolean visit(EqualExpression equalExpression, BlockScope scope) {
+		addRealFragment(equalExpression);
+		return false;
+	}
+
+	public boolean visit(
+		ExtendedStringLiteral extendedStringLiteral,
+		BlockScope scope) {
+			addRealFragment(extendedStringLiteral);
+			return false;
+	}
+
+	public boolean visit(FalseLiteral falseLiteral, BlockScope scope) {
+		addSmallFragment(falseLiteral);
+		return false;
+	}
+
+	public boolean visit(FieldReference fieldReference, BlockScope scope) {
+		addRealFragment(fieldReference);
+		return false;
+	}
+
+	public boolean visit(FloatLiteral floatLiteral, BlockScope scope) {
+		addSmallFragment(floatLiteral);
+		return false;
+	}
+
+	public boolean visit(
+		InstanceOfExpression instanceOfExpression,
+		BlockScope scope) {
+			addRealFragment(instanceOfExpression);
+			return false;
+	}
+
+	public boolean visit(IntLiteral intLiteral, BlockScope scope) {
+		addSmallFragment(intLiteral);
+		return false;
+	}
+
+	public boolean visit(LongLiteral longLiteral, BlockScope scope) {
+		addSmallFragment(longLiteral);
+		return false;
+	}
+
+	public boolean visit(MessageSend messageSend, BlockScope scope) {
+		addRealFragment(messageSend);
+		return false;
+	}
+
+	public boolean visit(StringLiteralConcatenation stringLiteral, BlockScope scope) {
+		if (((stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+			addRealFragment(stringLiteral);
+		} else {
+			for (int i = 0, max = stringLiteral.counter; i < max; i++) {
+				addRealFragment(stringLiteral.literals[i]);
+				if (i < max - 1) {
+					this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+				}
+			}
+		}
+		return false;
+	}
+
+	public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
+		addRealFragment(nullLiteral);
+		return false;
+	}
+
+	public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		if (((or_or_Expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+			addRealFragment(or_or_Expression);
+		} else {
+			or_or_Expression.left.traverse(this, scope);
+			this.operatorsList.add(new Integer(TerminalTokens.TokenNameOR_OR));
+			or_or_Expression.right.traverse(this, scope);
+		}
+		return false;
+	}
+
+	public boolean visit(
+		PostfixExpression postfixExpression,
+		BlockScope scope) {
+			addRealFragment(postfixExpression);
+			return false;
+	}
+
+	public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
+		addRealFragment(prefixExpression);
+		return false;
+	}
+
+	public boolean visit(
+		QualifiedAllocationExpression qualifiedAllocationExpression,
+		BlockScope scope) {
+			addRealFragment(qualifiedAllocationExpression);
+			return false;
+	}
+	public boolean visit(
+		QualifiedNameReference qualifiedNameReference,
+		BlockScope scope) {
+			addRealFragment(qualifiedNameReference);
+			return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+			QualifiedSuperReference qualifiedSuperReference,
+			BlockScope scope) {
+		addRealFragment(qualifiedSuperReference);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+			QualifiedThisReference qualifiedThisReference,
+			BlockScope scope) {
+		addRealFragment(qualifiedThisReference);
+		return false;
+	}
+
+	public boolean visit(
+		SingleNameReference singleNameReference,
+		BlockScope scope) {
+			addRealFragment(singleNameReference);
+			return false;
+	}
+
+	public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
+		addRealFragment(stringLiteral);
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(SuperReference superReference, BlockScope scope) {
+		addRealFragment(superReference);
+		return false;
+	}
+
+	public boolean visit(ThisReference thisReference, BlockScope scope) {
+		addRealFragment(thisReference);
+		return false;
+	}
+
+	public boolean visit(TrueLiteral trueLiteral, BlockScope scope) {
+		addSmallFragment(trueLiteral);
+		return false;
+	}
+
+	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
+		addRealFragment(unaryExpression);
+		return false;
+	}
+
+	public int size() {
+		return this.fragmentsList.size();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java
new file mode 100644
index 0000000..03aa9bc
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+class CascadingMethodInvocationFragmentBuilder
+	extends ASTVisitor {
+
+	ArrayList fragmentsList;
+
+	CascadingMethodInvocationFragmentBuilder() {
+		this.fragmentsList = new ArrayList();
+	}
+
+	public MessageSend[] fragments() {
+		MessageSend[] fragments = new MessageSend[this.fragmentsList.size()];
+		this.fragmentsList.toArray(fragments);
+		return fragments;
+	}
+
+	public int size() {
+		return this.fragmentsList.size();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.MessageSend, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(MessageSend messageSend, BlockScope scope) {
+		if ((messageSend.receiver.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT == 0) {
+			if (messageSend.receiver instanceof MessageSend) {
+				this.fragmentsList.add(0, messageSend);
+				messageSend.receiver.traverse(this, scope);
+				return false;
+			}
+			this.fragmentsList.add(0, messageSend);
+			this.fragmentsList.add(1, messageSend);
+		} else {
+			this.fragmentsList.add(0, messageSend);
+			this.fragmentsList.add(1, messageSend);
+		}
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
new file mode 100644
index 0000000..ba541ab
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
@@ -0,0 +1,6035 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Brock Janiczak - Contribution for bug 150741
+ *     Nanda Firdausi - Contribution for bug 298844
+ *     Jesper S Moller - Contribution for bug 402173
+ *                       Contribution for bug 402174
+ *                       Contribution for bug 402819
+ *                       Contribution for bug 402892
+ *                       Contribution for bug 403881
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
+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.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
+import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.Clinit;
+import org.eclipse.jdt.internal.compiler.ast.CombinedBinaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ContinueStatement;
+import org.eclipse.jdt.internal.compiler.ast.DoStatement;
+import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
+import org.eclipse.jdt.internal.compiler.ast.EmptyStatement;
+import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.FloatLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ForStatement;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
+import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
+import org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LongLiteral;
+import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
+import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
+import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
+import org.eclipse.jdt.internal.compiler.ast.SuperReference;
+import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
+import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
+import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
+import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
+import org.eclipse.jdt.internal.formatter.align.Alignment;
+import org.eclipse.jdt.internal.formatter.align.AlignmentException;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This class is responsible for formatting a valid java source code.
+ * @since 2.1
+ */
+/*
+   <extension
+         id="org.eclipse.jdt.core.newformatter.codeformatter"
+         name="org.eclipse.jdt.core.newformatter.codeformatter"
+         point="org.eclipse.jdt.core.codeFormatter">
+      <codeFormatter
+            class="org.eclipse.jdt.internal.formatter.CodeFormatterVisitor">
+      </codeFormatter>
+   </extension>
+*/
+public class CodeFormatterVisitor extends ASTVisitor {
+
+	public static class MultiFieldDeclaration extends FieldDeclaration {
+
+		FieldDeclaration[] declarations;
+
+		MultiFieldDeclaration(FieldDeclaration[] declarations){
+			this.declarations = declarations;
+			this.modifiers = declarations[0].modifiers;
+		}
+	}
+
+	public final static boolean DEBUG = false;
+	private static final int NO_MODIFIERS = 0;
+	/*
+	 * Set of expected tokens type for a single type reference.
+	 * This array needs to be SORTED.
+	 */
+	private static final int[] SINGLETYPEREFERENCE_EXPECTEDTOKENS = new int[] {
+		TerminalTokens.TokenNameIdentifier,
+		TerminalTokens.TokenNameboolean,
+		TerminalTokens.TokenNamebyte,
+		TerminalTokens.TokenNamechar,
+		TerminalTokens.TokenNamedouble,
+		TerminalTokens.TokenNamefloat,
+		TerminalTokens.TokenNameint,
+		TerminalTokens.TokenNamelong,
+		TerminalTokens.TokenNameshort,
+		TerminalTokens.TokenNamevoid
+	};
+	private static final int[] CLOSING_GENERICS_EXPECTEDTOKENS = new int[] {
+		TerminalTokens.TokenNameRIGHT_SHIFT,
+		TerminalTokens.TokenNameGREATER,
+		TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT,
+	};
+	public int lastLocalDeclarationSourceStart;
+	int lastBinaryExpressionAlignmentBreakIndentation;
+	private Scanner localScanner;
+	public DefaultCodeFormatterOptions preferences;
+	public Scribe scribe;
+
+	// Binary expression positions storage
+	final static long  EXPRESSIONS_POS_ENTER_EQUALITY = 1;
+	final static long  EXPRESSIONS_POS_ENTER_TWO = 2;
+	final static long  EXPRESSIONS_POS_BETWEEN_TWO = 3;
+	final static long  EXPRESSIONS_POS_MASK = EXPRESSIONS_POS_BETWEEN_TWO;
+	long expressionsPos;
+	int expressionsDepth = -1;
+
+	// Array initializers information
+	int arrayInitializersDepth = -1;
+
+	public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil, boolean includeComments) {
+		long sourceLevel = settings == null
+			? ClassFileConstants.JDK1_3
+			: CompilerOptions.versionToJdkLevel(settings.get(JavaCore.COMPILER_SOURCE));
+		this.localScanner = new Scanner(true, false, false/*nls*/, sourceLevel/*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+
+		this.preferences = preferences;
+		this.scribe = new Scribe(this, sourceLevel, regions, codeSnippetParsingUtil, includeComments);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#acceptProblem(org.eclipse.jdt.core.compiler.IProblem)
+	 */
+	public void acceptProblem(IProblem problem) {
+		super.acceptProblem(problem);
+	}
+
+	private BinaryExpressionFragmentBuilder buildFragments(BinaryExpression binaryExpression, BlockScope scope) {
+		BinaryExpressionFragmentBuilder builder = new BinaryExpressionFragmentBuilder();
+
+		if (binaryExpression instanceof CombinedBinaryExpression) {
+			binaryExpression.traverse(builder, scope);
+			return builder;
+		}
+		switch((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
+			case OperatorIds.MULTIPLY :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameMULTIPLY));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.PLUS :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.DIVIDE :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameDIVIDE));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.REMAINDER :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameREMAINDER));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.XOR :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameXOR));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.MINUS :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameMINUS));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.OR :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameOR));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.AND :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameAND));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.AND_AND :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameAND_AND));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+			case OperatorIds.OR_OR :
+				binaryExpression.left.traverse(builder, scope);
+				builder.operatorsList.add(new Integer(TerminalTokens.TokenNameOR_OR));
+				binaryExpression.right.traverse(builder, scope);
+				break;
+		}
+
+		return builder;
+	}
+
+	private CascadingMethodInvocationFragmentBuilder buildFragments(MessageSend messageSend, BlockScope scope) {
+		CascadingMethodInvocationFragmentBuilder builder = new CascadingMethodInvocationFragmentBuilder();
+
+		messageSend.traverse(builder, scope);
+		return builder;
+	}
+
+	private boolean commentStartsBlock(int start, int end) {
+		this.localScanner.resetTo(start, end);
+		try {
+			if (this.localScanner.getNextToken() ==  TerminalTokens.TokenNameLBRACE) {
+				switch(this.localScanner.getNextToken()) {
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						return true;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private ASTNode[] computeMergedMemberDeclarations(ASTNode[] nodes){
+		ArrayList mergedNodes = new ArrayList();
+		for (int i = 0, max = nodes.length; i < max; i++) {
+			ASTNode currentNode = nodes[i];
+			if (currentNode instanceof FieldDeclaration) {
+				FieldDeclaration currentField = (FieldDeclaration) currentNode;
+				if (mergedNodes.size() == 0) {
+					// first node
+					mergedNodes.add(currentNode);
+				} else {
+					// we need to check if the previous merged node is a field declaration
+					ASTNode previousMergedNode = (ASTNode) mergedNodes.get(mergedNodes.size() - 1);
+					if (previousMergedNode instanceof MultiFieldDeclaration) {
+						// we merge the current node
+						MultiFieldDeclaration multiFieldDeclaration = (MultiFieldDeclaration) previousMergedNode;
+						int length = multiFieldDeclaration.declarations.length;
+						System.arraycopy(multiFieldDeclaration.declarations, 0, multiFieldDeclaration.declarations= new FieldDeclaration[length+1], 0, length);
+						multiFieldDeclaration.declarations[length] = currentField;
+					} else if (previousMergedNode instanceof FieldDeclaration) {
+						// need to check we need to create a multiple field declaration
+						final FieldDeclaration previousFieldDeclaration = (FieldDeclaration)previousMergedNode;
+						if (currentField.declarationSourceStart == previousFieldDeclaration.declarationSourceStart) {
+							// we create a multi field declaration
+							final MultiFieldDeclaration multiFieldDeclaration = new MultiFieldDeclaration(new FieldDeclaration[]{ previousFieldDeclaration, currentField});
+							multiFieldDeclaration.annotations = previousFieldDeclaration.annotations;
+							mergedNodes.set(mergedNodes.size() - 1, multiFieldDeclaration);
+						} else {
+							mergedNodes.add(currentNode);
+						}
+					} else {
+						mergedNodes.add(currentNode);
+					}
+				}
+			} else {
+				mergedNodes.add(currentNode);
+			}
+		}
+		if (mergedNodes.size() != nodes.length) {
+			ASTNode[] result = new ASTNode[mergedNodes.size()];
+			mergedNodes.toArray(result);
+			return result;
+		} else {
+			return nodes;
+		}
+	}
+
+	private ASTNode[] computeMergedMemberDeclarations(TypeDeclaration typeDeclaration){
+
+		int fieldIndex = 0, fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length;
+		FieldDeclaration field = fieldCount == 0 ? null : typeDeclaration.fields[fieldIndex];
+		int fieldStart = field == null ? Integer.MAX_VALUE : field.declarationSourceStart;
+
+		int methodIndex = 0, methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length;
+		AbstractMethodDeclaration method = methodCount == 0 ? null : typeDeclaration.methods[methodIndex];
+		int methodStart = method == null ? Integer.MAX_VALUE : method.declarationSourceStart;
+
+		int typeIndex = 0, typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length;
+		TypeDeclaration type = typeCount == 0 ? null : typeDeclaration.memberTypes[typeIndex];
+		int typeStart = type == null ? Integer.MAX_VALUE : type.declarationSourceStart;
+
+		final int memberLength = fieldCount+methodCount+typeCount;
+		ASTNode[] members = new ASTNode[memberLength];
+		if (memberLength != 0) {
+			int index = 0;
+			int previousFieldStart = -1;
+			do {
+				if (fieldStart < methodStart && fieldStart < typeStart) {
+					if (field.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						// filter out enum constants
+						previousFieldStart = fieldStart;
+						if (++fieldIndex < fieldCount) { // find next field if any
+							fieldStart = (field = typeDeclaration.fields[fieldIndex]).declarationSourceStart;
+						} else {
+							fieldStart = Integer.MAX_VALUE;
+						}
+						continue;
+					}
+					// next member is a field
+					if (fieldStart == previousFieldStart){
+						ASTNode previousMember = members[index - 1];
+						if (previousMember instanceof MultiFieldDeclaration) {
+							MultiFieldDeclaration multiField = (MultiFieldDeclaration) previousMember;
+							int length = multiField.declarations.length;
+							System.arraycopy(multiField.declarations, 0, multiField.declarations=new FieldDeclaration[length+1], 0, length);
+							multiField.declarations[length] = field;
+						} else {
+							FieldDeclaration fieldDeclaration = (FieldDeclaration)previousMember;
+							final MultiFieldDeclaration multiFieldDeclaration = new MultiFieldDeclaration(new FieldDeclaration[]{ fieldDeclaration, field});
+							multiFieldDeclaration.annotations = fieldDeclaration.annotations;
+							members[index - 1] = multiFieldDeclaration;
+						}
+					} else {
+						members[index++] = field;
+					}
+					previousFieldStart = fieldStart;
+					if (++fieldIndex < fieldCount) { // find next field if any
+						fieldStart = (field = typeDeclaration.fields[fieldIndex]).declarationSourceStart;
+					} else {
+						fieldStart = Integer.MAX_VALUE;
+					}
+				} else if (methodStart < fieldStart && methodStart < typeStart) {
+					// next member is a method
+					if (!method.isDefaultConstructor() && !method.isClinit()) {
+						members[index++] = method;
+					}
+					if (++methodIndex < methodCount) { // find next method if any
+						methodStart = (method = typeDeclaration.methods[methodIndex]).declarationSourceStart;
+					} else {
+						methodStart = Integer.MAX_VALUE;
+					}
+				} else {
+					// next member is a type
+					members[index++] = type;
+					if (++typeIndex < typeCount) { // find next type if any
+						typeStart = (type = typeDeclaration.memberTypes[typeIndex]).declarationSourceStart;
+					} else {
+						typeStart = Integer.MAX_VALUE;
+					}
+				}
+			} while ((fieldIndex < fieldCount) || (typeIndex < typeCount) || (methodIndex < methodCount));
+
+			if (members.length != index) {
+				System.arraycopy(members, 0, members=new ASTNode[index], 0, index);
+			}
+		}
+		return members;
+	}
+
+	private boolean dumpBinaryExpression(
+		BinaryExpression binaryExpression,
+		int operator,
+		BlockScope scope) {
+
+		final int numberOfParens = (binaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(binaryExpression, numberOfParens);
+		}
+		BinaryExpressionFragmentBuilder builder = buildFragments(binaryExpression, scope);
+		final int fragmentsSize = builder.size();
+
+		if (this.expressionsDepth < 0) {
+			this.expressionsDepth = 0;
+		} else {
+			this.expressionsDepth++;
+			this.expressionsPos <<= 2;
+		}
+		try {
+			this.lastBinaryExpressionAlignmentBreakIndentation = 0;
+			if ((builder.realFragmentsSize() > 1 || fragmentsSize > 4) && numberOfParens == 0) {
+				int scribeLine = this.scribe.line;
+				this.scribe.printComment();
+				Alignment binaryExpressionAlignment = this.scribe.createAlignment(
+						Alignment.BINARY_EXPRESSION,
+						this.preferences.alignment_for_binary_expression,
+						Alignment.R_OUTERMOST,
+						fragmentsSize,
+						this.scribe.scanner.currentPosition);
+				this.scribe.enterAlignment(binaryExpressionAlignment);
+				boolean ok = false;
+				ASTNode[] fragments = builder.fragments();
+				int[] operators = builder.operators();
+				do {
+					try {
+						final int max = fragmentsSize - 1;
+						for (int i = 0; i < max; i++) {
+							ASTNode fragment = fragments[i];
+							fragment.traverse(this, scope);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							if (this.scribe.lastNumberOfNewLines == 1) {
+								// a new line has been inserted while printing the comment
+								// hence we need to use the break indentation level before printing next token...
+								this.scribe.indentationLevel = binaryExpressionAlignment.breakIndentationLevel;
+							}
+							if (this.preferences.wrap_before_binary_operator) {
+								this.scribe.alignFragment(binaryExpressionAlignment, i);
+								this.scribe.printNextToken(operators[i], this.preferences.insert_space_before_binary_operator);
+							} else {
+								this.scribe.printNextToken(operators[i], this.preferences.insert_space_before_binary_operator);
+								this.scribe.alignFragment(binaryExpressionAlignment, i);
+							}
+							switch(operators[i]) {
+								case TerminalTokens.TokenNameMINUS :
+									if (isNextToken(TerminalTokens.TokenNameMINUS)
+											|| isNextToken(TerminalTokens.TokenNameMINUS_MINUS)) {
+										// the next character is a '-' or '--' (unary operator)
+										this.scribe.space();
+									}
+									break;
+								case TerminalTokens.TokenNamePLUS :
+									if (isNextToken(TerminalTokens.TokenNamePLUS)
+											|| isNextToken(TerminalTokens.TokenNamePLUS_PLUS)) {
+										// the next character is a + or ++ (unary operator)
+										this.scribe.space();
+									}
+							}
+							if (this.preferences.insert_space_after_binary_operator) {
+								this.scribe.space();
+							}
+						}
+						fragments[max].traverse(this, scope);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						ok = true;
+					} catch(AlignmentException e){
+						this.scribe.redoAlignment(e);
+					}
+				} while (!ok);
+				this.scribe.exitAlignment(binaryExpressionAlignment, true);
+				if (this.scribe.line == scribeLine) {
+					// The expression was not broken => reset last break indentation
+					this.lastBinaryExpressionAlignmentBreakIndentation = 0;
+				} else {
+					this.lastBinaryExpressionAlignmentBreakIndentation = binaryExpressionAlignment.breakIndentationLevel;
+				}
+			} else {
+				this.expressionsPos |= EXPRESSIONS_POS_ENTER_TWO;
+				binaryExpression.left.traverse(this, scope);
+				this.expressionsPos &= ~EXPRESSIONS_POS_MASK;
+				this.expressionsPos |= EXPRESSIONS_POS_BETWEEN_TWO;
+				this.scribe.printNextToken(operator, this.preferences.insert_space_before_binary_operator, Scribe.PRESERVE_EMPTY_LINES_IN_BINARY_EXPRESSION);
+				if (operator == TerminalTokens.TokenNameMINUS && isNextToken(TerminalTokens.TokenNameMINUS)) {
+					// the next character is a minus (unary operator)
+					this.scribe.space();
+				}
+				if (this.preferences.insert_space_after_binary_operator) {
+					this.scribe.space();
+				}
+				binaryExpression.right.traverse(this, scope);
+			}
+		}
+		finally {
+			this.expressionsDepth--;
+			this.expressionsPos >>= 2;
+			if (this.expressionsDepth < 0) {
+				this.lastBinaryExpressionAlignmentBreakIndentation = 0;
+			}
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(binaryExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	private boolean dumpEqualityExpression(
+		BinaryExpression binaryExpression,
+		int operator,
+		BlockScope scope) {
+
+		final int numberOfParens = (binaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(binaryExpression, numberOfParens);
+		}
+		if (this.expressionsDepth < 0) {
+			this.expressionsDepth = 0;
+		} else {
+			this.expressionsDepth++;
+			this.expressionsPos <<= 2;
+		}
+		try {
+			this.expressionsPos |= EXPRESSIONS_POS_ENTER_EQUALITY;
+			binaryExpression.left.traverse(this, scope);
+			this.scribe.printNextToken(operator, this.preferences.insert_space_before_binary_operator, Scribe.PRESERVE_EMPTY_LINES_IN_EQUALITY_EXPRESSION);
+			if (this.preferences.insert_space_after_binary_operator) {
+				this.scribe.space();
+			}
+			binaryExpression.right.traverse(this, scope);
+		}
+		finally {
+			this.expressionsDepth--;
+			this.expressionsPos >>= 2;
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(binaryExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	private final TextEdit failedToFormat() {
+		if (DEBUG) {
+			System.out.println("COULD NOT FORMAT \n" + this.scribe.scanner); //$NON-NLS-1$
+			System.out.println(this.scribe);
+		}
+		return null;
+	}
+
+	private void format(
+		AbstractMethodDeclaration methodDeclaration,
+		ClassScope scope,
+		boolean isChunkStart,
+		boolean isFirstClassBodyDeclaration) {
+
+		if (isFirstClassBodyDeclaration) {
+			int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+			if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+			}
+		} else {
+			final int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+			if (newLineBeforeChunk > 0) {
+				this.scribe.printEmptyLines(newLineBeforeChunk);
+			}
+		}
+		final int newLinesBeforeMethod = this.preferences.blank_lines_before_method;
+		if (newLinesBeforeMethod > 0 && !isFirstClassBodyDeclaration) {
+			this.scribe.printEmptyLines(newLinesBeforeMethod);
+		} else if (this.scribe.line != 0 || this.scribe.column != 1) {
+			this.scribe.printNewLine();
+		}
+		methodDeclaration.traverse(this, scope);
+	}
+
+	private void format(FieldDeclaration fieldDeclaration, ASTVisitor visitor, MethodScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) {
+
+		if (isFirstClassBodyDeclaration) {
+			int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+			if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+			}
+		} else {
+			int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+			if (newLineBeforeChunk > 0) {
+				this.scribe.printEmptyLines(newLineBeforeChunk);
+			}
+			final int newLinesBeforeField = this.preferences.blank_lines_before_field;
+			if (newLinesBeforeField > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeField);
+			}
+		}
+		Alignment memberAlignment = this.scribe.getMemberAlignment();
+
+        this.scribe.printComment();
+		this.scribe.printModifiers(fieldDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD);
+		this.scribe.space();
+		/*
+		 * Field type
+		 */
+		fieldDeclaration.type.traverse(this, scope);
+
+		/*
+		 * Field name
+		 */
+		this.scribe.alignFragment(memberAlignment, 0);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+
+		formatExtraDimensions(fieldDeclaration.type);
+
+		/*
+		 * Field initialization
+		 */
+		final Expression initialization = fieldDeclaration.initialization;
+		if (initialization != null) {
+			this.scribe.alignFragment(memberAlignment, 1);
+			this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator);
+			if (this.preferences.insert_space_after_assignment_operator) {
+				this.scribe.space();
+			}
+			Alignment assignmentAlignment = this.scribe.createAlignment(
+					Alignment.FIELD_DECLARATION_ASSIGNMENT,
+					this.preferences.alignment_for_assignment,
+					Alignment.R_INNERMOST,
+					1,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(assignmentAlignment);
+			boolean ok = false;
+			do {
+				try {
+					this.scribe.alignFragment(assignmentAlignment, 0);
+					initialization.traverse(this, scope);
+					ok = true;
+				} catch(AlignmentException e){
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(assignmentAlignment, true);
+		}
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+
+		if (memberAlignment != null) {
+			this.scribe.alignFragment(memberAlignment, 2);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		} else {
+			this.scribe.space();
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+	}
+
+	private void formatExtraDimensions(TypeReference typeReference) {
+		/*
+		 * Check for extra dimensions
+		 */
+		int extraDimensions = getDimensions();
+		if (extraDimensions != 0) {
+			int anchor = typeReference != null ? (typeReference.dimensions() - extraDimensions) : 0;
+			formatDimensions(typeReference, anchor, extraDimensions, true);
+		}
+	}
+
+	private void formatLeadingDimensions(TypeReference typeReference, boolean spaceBeforeAnnotation) {
+		int leadingDimensions = Math.min(getDimensions(), typeReference != null ? typeReference.dimensions() : 0);
+		if (leadingDimensions != 0) formatDimensions(typeReference, 0, leadingDimensions, spaceBeforeAnnotation);
+	}
+
+	private void formatDimensions(TypeReference typeReference, int anchor, int count, boolean spaceBeforeAnnotation) {
+		if (count != 0) {
+			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
+				this.scribe.space();
+			}
+			Annotation[][] annotationsOnDimensions = typeReference != null ? typeReference.getAnnotationsOnDimensions() : null;
+			for (int i = 0; i < count; i++) {
+				int dimensionIndex = anchor + i;
+				if (annotationsOnDimensions != null && annotationsOnDimensions.length > dimensionIndex) {
+					boolean hadAnnotations = formatInlineAnnotations(annotationsOnDimensions[dimensionIndex], spaceBeforeAnnotation && i == 0);
+					if (hadAnnotations && this.preferences.insert_space_before_opening_bracket_in_array_type_reference) this.scribe.space();
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET);
+				if (this.preferences.insert_space_between_brackets_in_array_type_reference) {
+					this.scribe.space();
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET);
+			}
+		}
+	}
+
+	private void format(ImportReference importRef, boolean isLast) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameimport);
+		if (!isLast) this.scribe.blank_lines_between_import_groups = this.preferences.blank_lines_between_import_groups;
+		this.scribe.space();
+		if (importRef.isStatic()) {
+			this.scribe.printNextToken(TerminalTokens.TokenNamestatic);
+			this.scribe.space();
+		}
+		if ((importRef.bits & ASTNode.OnDemand) != 0) {
+			this.scribe.printQualifiedReference(importRef.sourceEnd, false/*do not expect parenthesis*/);
+			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+			this.scribe.printNextToken(TerminalTokens.TokenNameMULTIPLY);
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		} else {
+			this.scribe.printQualifiedReference(importRef.sourceEnd, false/*do not expect parenthesis*/);
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		}
+		if (isLast) {
+			this.scribe.blank_lines_between_import_groups = -1;
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.IMPORT_TRAILING_COMMENT);
+		} else {
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.NO_TRAILING_COMMENT);
+			this.scribe.blank_lines_between_import_groups = -1;
+		}
+		this.scribe.printNewLine();
+	}
+
+
+	private void format(MultiFieldDeclaration multiFieldDeclaration, ASTVisitor visitor, MethodScope scope, boolean isChunkStart, boolean isFirstClassBodyDeclaration) {
+
+		if (isFirstClassBodyDeclaration) {
+			int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+			if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+			}
+		} else {
+			int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+			if (newLineBeforeChunk > 0) {
+				this.scribe.printEmptyLines(newLineBeforeChunk);
+			}
+			final int newLinesBeforeField = this.preferences.blank_lines_before_field;
+			if (newLinesBeforeField > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeField);
+			}
+		}
+		Alignment fieldAlignment = this.scribe.getMemberAlignment();
+
+        this.scribe.printComment();
+		this.scribe.printModifiers(multiFieldDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD);
+		this.scribe.space();
+
+		multiFieldDeclaration.declarations[0].type.traverse(this, scope);
+
+		final int multipleFieldDeclarationsLength = multiFieldDeclaration.declarations.length;
+
+		Alignment multiFieldDeclarationsAlignment =this.scribe.createAlignment(
+				Alignment.MULTIPLE_FIELD,
+				this.preferences.alignment_for_multiple_fields,
+				multipleFieldDeclarationsLength - 1,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(multiFieldDeclarationsAlignment);
+
+		boolean ok = false;
+		do {
+			try {
+				for (int i = 0, length = multipleFieldDeclarationsLength; i < length; i++) {
+					FieldDeclaration fieldDeclaration = multiFieldDeclaration.declarations[i];
+					/*
+					 * Field name
+					 */
+					if (i == 0) {
+						this.scribe.alignFragment(fieldAlignment, 0);
+						this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+					} else {
+						this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false);
+					}
+
+					formatExtraDimensions(fieldDeclaration.type);
+
+					/*
+					 * Field initialization
+					 */
+					final Expression initialization = fieldDeclaration.initialization;
+					if (initialization != null) {
+						if (i == 0) {
+							this.scribe.alignFragment(fieldAlignment, 1);
+						}
+						this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator);
+						if (this.preferences.insert_space_after_assignment_operator) {
+							this.scribe.space();
+						}
+						initialization.traverse(this, scope);
+					}
+
+					if (i != length - 1) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_multiple_field_declarations);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						this.scribe.alignFragment(multiFieldDeclarationsAlignment, i);
+
+						if (this.preferences.insert_space_after_comma_in_multiple_field_declarations) {
+							this.scribe.space();
+						}
+					} else {
+						this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+						this.scribe.alignFragment(fieldAlignment, 2);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					}
+				}
+				ok = true;
+			} catch (AlignmentException e) {
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(multiFieldDeclarationsAlignment, true);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
+	 */
+	public TextEdit format(String string, ASTNode[] nodes) {
+		// reset the scribe
+		this.scribe.reset();
+
+		long startTime = 0;
+		if (DEBUG) {
+			startTime = System.currentTimeMillis();
+		}
+
+		final char[] compilationUnitSource = string.toCharArray();
+
+		this.localScanner.setSource(compilationUnitSource);
+		this.scribe.resetScanner(compilationUnitSource);
+
+		if (nodes == null) {
+			return null;
+		}
+
+		this.lastLocalDeclarationSourceStart = -1;
+		try {
+			formatClassBodyDeclarations(nodes);
+		} catch(AbortFormatting e){
+			return failedToFormat();
+		}
+		if (DEBUG){
+			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
+		}
+		return this.scribe.getRootEdit();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
+	 */
+	public TextEdit format(String string, CompilationUnitDeclaration compilationUnitDeclaration) {
+		// reset the scribe
+		this.scribe.reset();
+
+		if (compilationUnitDeclaration == null || compilationUnitDeclaration.ignoreFurtherInvestigation) {
+			return failedToFormat();
+		}
+
+		long startTime = 0;
+		if (DEBUG) {
+			startTime = System.currentTimeMillis();
+		}
+
+		final char[] compilationUnitSource = string.toCharArray();
+
+		this.localScanner.setSource(compilationUnitSource);
+		this.scribe.resetScanner(compilationUnitSource);
+
+		this.lastLocalDeclarationSourceStart = -1;
+		try {
+			compilationUnitDeclaration.traverse(this, compilationUnitDeclaration.scope);
+		} catch(AbortFormatting e){
+			return failedToFormat();
+		}
+		if (DEBUG){
+			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
+		}
+		return this.scribe.getRootEdit();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
+	 */
+	public TextEdit format(String string, ConstructorDeclaration constructorDeclaration) {
+		// reset the scribe
+		this.scribe.reset();
+
+		long startTime = 0;
+		if (DEBUG) {
+			startTime = System.currentTimeMillis();
+		}
+
+		final char[] compilationUnitSource = string.toCharArray();
+
+		this.localScanner.setSource(compilationUnitSource);
+		this.scribe.resetScanner(compilationUnitSource);
+
+		if (constructorDeclaration == null) {
+			return null;
+		}
+
+		this.lastLocalDeclarationSourceStart = -1;
+		try {
+			ExplicitConstructorCall explicitConstructorCall = constructorDeclaration.constructorCall;
+			if (explicitConstructorCall != null && !explicitConstructorCall.isImplicitSuper()) {
+				explicitConstructorCall.traverse(this, null);
+			}
+			Statement[] statements = constructorDeclaration.statements;
+			if (statements != null) {
+				formatStatements(null, statements, false);
+			}
+			if (hasComments()) {
+				this.scribe.printNewLine();
+			}
+			this.scribe.printComment();
+		} catch(AbortFormatting e){
+			return failedToFormat();
+		}
+		if (DEBUG){
+			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
+		}
+		return this.scribe.getRootEdit();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
+	 */
+	public TextEdit format(String string, Expression expression) {
+		// reset the scribe
+		this.scribe.reset();
+
+		long startTime = 0;
+		if (DEBUG) {
+			startTime = System.currentTimeMillis();
+		}
+
+		final char[] compilationUnitSource = string.toCharArray();
+
+		this.localScanner.setSource(compilationUnitSource);
+		this.scribe.resetScanner(compilationUnitSource);
+
+		if (expression == null) {
+			return null;
+		}
+
+		this.lastLocalDeclarationSourceStart = -1;
+		try {
+			expression.traverse(this, (BlockScope) null);
+			this.scribe.printComment();
+		} catch(AbortFormatting e){
+			return failedToFormat();
+		}
+		if (DEBUG){
+			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
+		}
+		return this.scribe.getRootEdit();
+	}
+
+	/**
+	 * @param source the source of the comment to format
+	 */
+	public void formatComment(int kind, String source, int start, int end, int indentationLevel) {
+		if (source == null) return;
+		this.scribe.printComment(kind, source, start, end, indentationLevel);
+	}
+
+	private void format(TypeDeclaration typeDeclaration){
+		/*
+		 * Print comments to get proper line number
+		 */
+		this.scribe.printComment();
+		int line = this.scribe.line;
+
+		this.scribe.printModifiers(typeDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_TYPE);
+
+		if (this.scribe.line > line) {
+			// annotations introduced new line, but this is not a line wrapping
+			// see 158267
+			line = this.scribe.line;
+		}
+
+		/*
+		 * Type name
+		 */
+		switch(TypeDeclaration.kind(typeDeclaration.modifiers)) {
+			case TypeDeclaration.CLASS_DECL :
+				this.scribe.printNextToken(TerminalTokens.TokenNameclass, true);
+				break;
+			case TypeDeclaration.INTERFACE_DECL :
+				this.scribe.printNextToken(TerminalTokens.TokenNameinterface, true);
+				break;
+			case TypeDeclaration.ENUM_DECL :
+				this.scribe.printNextToken(TerminalTokens.TokenNameenum, true);
+				break;
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				this.scribe.printNextToken(TerminalTokens.TokenNameAT, this.preferences.insert_space_before_at_in_annotation_type_declaration);
+				this.scribe.printNextToken(TerminalTokens.TokenNameinterface, this.preferences.insert_space_after_at_in_annotation_type_declaration);
+				break;
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+
+		TypeParameter[] typeParameters = typeDeclaration.typeParameters;
+		if (typeParameters != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters);
+			if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) {
+				this.scribe.space();
+			}
+			int length = typeParameters.length;
+			for (int i = 0; i < length - 1; i++) {
+				typeParameters[i].traverse(this, typeDeclaration.scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters);
+				if (this.preferences.insert_space_after_comma_in_type_parameters) {
+					this.scribe.space();
+				}
+			}
+			typeParameters[length - 1].traverse(this, typeDeclaration.scope);
+			if (isClosingGenericToken()) {
+				this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters);
+			}
+			if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) {
+				this.scribe.space();
+			}
+		}
+		/*
+		 * Superclass
+		 */
+		final TypeReference superclass = typeDeclaration.superclass;
+		if (superclass != null) {
+			Alignment superclassAlignment =this.scribe.createAlignment(
+					Alignment.SUPER_CLASS,
+					this.preferences.alignment_for_superclass_in_type_declaration,
+					2,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(superclassAlignment);
+			boolean ok = false;
+			do {
+				try {
+					this.scribe.alignFragment(superclassAlignment, 0);
+					this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+					this.scribe.alignFragment(superclassAlignment, 1);
+					this.scribe.space();
+					superclass.traverse(this, typeDeclaration.scope);
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(superclassAlignment, true);
+		}
+
+		/*
+		 * Super Interfaces
+		 */
+		final TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			int alignment_for_superinterfaces;
+			int kind = TypeDeclaration.kind(typeDeclaration.modifiers);
+			switch(kind) {
+				case TypeDeclaration.ENUM_DECL :
+					alignment_for_superinterfaces = this.preferences.alignment_for_superinterfaces_in_enum_declaration;
+					break;
+				default:
+					alignment_for_superinterfaces = this.preferences.alignment_for_superinterfaces_in_type_declaration;
+					break;
+			}
+			int superInterfaceLength = superInterfaces.length;
+			Alignment interfaceAlignment =this.scribe.createAlignment(
+					Alignment.SUPER_INTERFACES,
+					alignment_for_superinterfaces,
+					superInterfaceLength+1,  // implements token is first fragment
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(interfaceAlignment);
+			boolean ok = false;
+			do {
+				try {
+					this.scribe.alignFragment(interfaceAlignment, 0);
+					if (kind == TypeDeclaration.INTERFACE_DECL) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+					} else  {
+						this.scribe.printNextToken(TerminalTokens.TokenNameimplements, true);
+					}
+					for (int i = 0; i < superInterfaceLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_superinterfaces);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							this.scribe.alignFragment(interfaceAlignment, i+1);
+							if (this.preferences.insert_space_after_comma_in_superinterfaces) {
+								this.scribe.space();
+							}
+							superInterfaces[i].traverse(this, typeDeclaration.scope);
+						} else {
+							this.scribe.alignFragment(interfaceAlignment, i+1);
+							this.scribe.space();
+							superInterfaces[i].traverse(this, typeDeclaration.scope);
+						}
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(interfaceAlignment, true);
+		}
+
+		/*
+		 * Type body
+		 */
+		String class_declaration_brace;
+		boolean space_before_opening_brace;
+		int kind = TypeDeclaration.kind(typeDeclaration.modifiers);
+		switch(kind) {
+			case TypeDeclaration.ENUM_DECL :
+				class_declaration_brace = this.preferences.brace_position_for_enum_declaration;
+				space_before_opening_brace = this.preferences.insert_space_before_opening_brace_in_enum_declaration;
+				break;
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				class_declaration_brace = this.preferences.brace_position_for_annotation_type_declaration;
+				space_before_opening_brace =  this.preferences.insert_space_before_opening_brace_in_annotation_type_declaration;
+				break;
+			default:
+				class_declaration_brace = this.preferences.brace_position_for_type_declaration;
+				space_before_opening_brace = this.preferences.insert_space_before_opening_brace_in_type_declaration;
+				break;
+		}
+		formatLeftCurlyBrace(line, class_declaration_brace);
+		formatTypeOpeningBrace(class_declaration_brace, space_before_opening_brace, typeDeclaration);
+
+		boolean indent_body_declarations_compare_to_header;
+		switch(kind) {
+			case TypeDeclaration.ENUM_DECL :
+				indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_enum_declaration_header;
+				break;
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_annotation_declaration_header;
+				break;
+			default:
+				indent_body_declarations_compare_to_header = this.preferences.indent_body_declarations_compare_to_type_header;
+				break;
+		}
+		if (indent_body_declarations_compare_to_header) {
+			this.scribe.indent();
+		}
+
+		if (kind == TypeDeclaration.ENUM_DECL) {
+			FieldDeclaration[] fieldDeclarations = typeDeclaration.fields;
+			boolean hasConstants = false;
+			int length = fieldDeclarations != null ? fieldDeclarations.length : 0;
+			int enumConstantsLength = 0;
+			if (fieldDeclarations != null) {
+				for (int i = 0; i < length; i++) {
+					FieldDeclaration fieldDeclaration = fieldDeclarations[i];
+					if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						enumConstantsLength++;
+					} else {
+						break;
+					}
+				}
+				hasConstants = enumConstantsLength != 0;
+				if (enumConstantsLength > 1) {
+					Alignment enumConstantsAlignment = this.scribe.createAlignment(
+							Alignment.ENUM_CONSTANTS,
+							this.preferences.alignment_for_enum_constants,
+							enumConstantsLength,
+							this.scribe.scanner.currentPosition,
+							0, // we don't want to indent enum constants when splitting to a new line
+							false);
+					this.scribe.enterAlignment(enumConstantsAlignment);
+					boolean ok = false;
+					do {
+						try {
+							for (int i = 0; i < enumConstantsLength; i++) {
+								this.scribe.alignFragment(enumConstantsAlignment, i);
+								FieldDeclaration fieldDeclaration = fieldDeclarations[i];
+								fieldDeclaration.traverse(this, typeDeclaration.initializerScope);
+								if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+									this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations);
+									if (this.preferences.insert_space_after_comma_in_enum_declarations) {
+										this.scribe.space();
+									}
+									this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+									if (fieldDeclaration.initialization instanceof QualifiedAllocationExpression) {
+										this.scribe.printNewLine();
+									}
+								}
+							}
+							ok = true;
+						} catch (AlignmentException e) {
+							this.scribe.redoAlignment(e);
+						}
+					} while (!ok);
+					this.scribe.exitAlignment(enumConstantsAlignment, true);
+				} else if (hasConstants) {
+					// only one enum constant
+					FieldDeclaration fieldDeclaration = fieldDeclarations[0];
+					fieldDeclaration.traverse(this, typeDeclaration.initializerScope);
+					if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations);
+						if (this.preferences.insert_space_after_comma_in_enum_declarations) {
+							this.scribe.space();
+						}
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						if (fieldDeclaration.initialization instanceof QualifiedAllocationExpression) {
+							this.scribe.printNewLine();
+						}
+					}
+				}
+			}
+			if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				if (hasConstants
+						|| ((enumConstantsLength - length) != 0)
+						|| typeDeclaration.methods != null
+						|| typeDeclaration.memberTypes != null) {
+					// make sure that empty enums don't get a new line
+					this.scribe.printNewLine();
+				}
+			} else if (hasConstants) {
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				// only had a new line if there is at least one enum constant
+				this.scribe.printNewLine();
+			}
+		}
+
+		formatTypeMembers(typeDeclaration);
+
+		if (indent_body_declarations_compare_to_header) {
+			this.scribe.unIndent();
+		}
+
+		switch(kind) {
+			case TypeDeclaration.ENUM_DECL :
+				if (this.preferences.insert_new_line_in_empty_enum_declaration) {
+					this.scribe.printNewLine();
+				}
+				break;
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				if (this.preferences.insert_new_line_in_empty_annotation_declaration) {
+					this.scribe.printNewLine();
+				}
+				break;
+			default :
+				if (this.preferences.insert_new_line_in_empty_type_declaration) {
+					this.scribe.printNewLine();
+				}
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		if (class_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+			this.scribe.unIndent();
+		}
+		if (hasComments()) {
+			this.scribe.printNewLine();
+		}
+	}
+
+	private void format(
+		TypeDeclaration memberTypeDeclaration,
+		ClassScope scope,
+		boolean isChunkStart,
+		boolean isFirstClassBodyDeclaration) {
+
+		if (isFirstClassBodyDeclaration) {
+			int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+			if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+			}
+		} else {
+			int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+			if (newLineBeforeChunk > 0) {
+				this.scribe.printEmptyLines(newLineBeforeChunk);
+			}
+			final int newLinesBeforeMember = this.preferences.blank_lines_before_member_type;
+			if (newLinesBeforeMember > 0) {
+				this.scribe.printEmptyLines(newLinesBeforeMember);
+			}
+		}
+		memberTypeDeclaration.traverse(this, scope);
+	}
+
+	private void formatAnonymousTypeDeclaration(TypeDeclaration typeDeclaration) {
+		/*
+		 * Type body
+		 */
+		String anonymous_type_declaration_brace_position = this.preferences.brace_position_for_anonymous_type_declaration;
+
+		formatTypeOpeningBrace(anonymous_type_declaration_brace_position, this.preferences.insert_space_before_opening_brace_in_anonymous_type_declaration, typeDeclaration);
+
+		this.scribe.indent();
+
+		formatTypeMembers(typeDeclaration);
+
+		this.scribe.unIndent();
+		if (this.preferences.insert_new_line_in_empty_anonymous_type_declaration) {
+			this.scribe.printNewLine();
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+		if (anonymous_type_declaration_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+			this.scribe.unIndent();
+		}
+	}
+
+	/**
+	 * @param block
+	 * @param scope
+	 * @param block_brace_position
+	 */
+	private void formatBlock(Block block, BlockScope scope, String block_brace_position, boolean insertSpaceBeforeOpeningBrace) {
+		formatOpeningBrace(block_brace_position, insertSpaceBeforeOpeningBrace);
+		final Statement[] statements = block.statements;
+		if (statements != null) {
+			this.scribe.printNewLine();
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.indent();
+			}
+			formatStatements(scope, statements, true);
+			this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK);
+
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.unIndent();
+			}
+		} else if (this.preferences.insert_new_line_in_empty_block) {
+			this.scribe.printNewLine();
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.indent();
+			}
+			this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK);
+
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.unIndent();
+			}
+		} else {
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.indent();
+			}
+			this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK);
+
+			if (this.preferences.indent_statements_compare_to_block) {
+				this.scribe.unIndent();
+			}
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		if (DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(block_brace_position)) {
+			this.scribe.unIndent();
+		}
+	}
+
+	private void formatCascadingMessageSends(CascadingMethodInvocationFragmentBuilder builder, BlockScope scope) {
+		int size = builder.size();
+		MessageSend[] fragments = builder.fragments();
+		Expression fragment = fragments[0].receiver;
+		int startingPositionInCascade = 1;
+		if (!fragment.isImplicitThis()) {
+			fragment.traverse(this, scope);
+		} else {
+			MessageSend currentMessageSend = fragments[1];
+			final int numberOfParens = (currentMessageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParens > 0) {
+				manageOpeningParenthesizedExpression(currentMessageSend, numberOfParens);
+			}
+			ASTNode[] arguments = currentMessageSend.arguments;
+			TypeReference[] typeArguments = currentMessageSend.typeArguments;
+			if (typeArguments != null) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+					if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+						this.scribe.space();
+					}
+					int length = typeArguments.length;
+					for (int i = 0; i < length - 1; i++) {
+						typeArguments[i].traverse(this, scope);
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+						if (this.preferences.insert_space_after_comma_in_type_arguments) {
+							this.scribe.space();
+						}
+					}
+					typeArguments[length - 1].traverse(this, scope);
+					if (isClosingGenericToken()) {
+						this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+					}
+					if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+						this.scribe.space();
+					}
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector
+			this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+			if (arguments != null) {
+				if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+					this.scribe.space();
+				}
+				int argumentLength = arguments.length;
+				Alignment argumentsAlignment = this.scribe.createAlignment(
+						Alignment.MESSAGE_ARGUMENTS,
+						this.preferences.alignment_for_arguments_in_method_invocation,
+						Alignment.R_OUTERMOST,
+						argumentLength,
+						this.scribe.scanner.currentPosition);
+				this.scribe.enterAlignment(argumentsAlignment);
+				boolean okForArguments = false;
+				do {
+					try {
+						for (int j = 0; j < argumentLength; j++) {
+							if (j > 0) {
+								this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments);
+								this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							}
+							this.scribe.alignFragment(argumentsAlignment, j);
+							if (j > 0 && this.preferences.insert_space_after_comma_in_method_invocation_arguments) {
+								this.scribe.space();
+							}
+							arguments[j].traverse(this, scope);
+						}
+						okForArguments = true;
+					} catch (AlignmentException e) {
+						this.scribe.redoAlignment(e);
+					}
+				} while (!okForArguments);
+				this.scribe.exitAlignment(argumentsAlignment, true);
+				this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+			} else {
+				this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+			}
+			if (numberOfParens > 0) {
+				manageClosingParenthesizedExpression(currentMessageSend, numberOfParens);
+			}
+			startingPositionInCascade = 2;
+		}
+		int tieBreakRule = this.preferences.wrap_outer_expressions_when_nested && size-startingPositionInCascade > 2
+			? Alignment.R_OUTERMOST
+			: Alignment.R_INNERMOST;
+		Alignment cascadingMessageSendAlignment =
+			this.scribe.createAlignment(
+				Alignment.CASCADING_MESSAGE_SEND,
+				this.preferences.alignment_for_selector_in_method_invocation,
+				tieBreakRule,
+				size,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(cascadingMessageSendAlignment);
+		boolean ok = false;
+		boolean setStartingColumn = true;
+		switch (this.preferences.alignment_for_arguments_in_method_invocation & Alignment.SPLIT_MASK) {
+			case Alignment.M_COMPACT_FIRST_BREAK_SPLIT:
+			case Alignment.M_NEXT_SHIFTED_SPLIT:
+			case Alignment.M_ONE_PER_LINE_SPLIT:
+				setStartingColumn = false;
+				break;
+		}
+		do {
+			if (setStartingColumn) {
+				cascadingMessageSendAlignment.startingColumn = this.scribe.column;
+			}
+			try {
+				this.scribe.alignFragment(cascadingMessageSendAlignment, 0);
+				this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+				for (int i = startingPositionInCascade; i < size; i++) {
+					MessageSend currentMessageSend = fragments[i];
+					final int numberOfParens = (currentMessageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+					if (numberOfParens > 0) {
+						manageOpeningParenthesizedExpression(currentMessageSend, numberOfParens);
+					}
+					TypeReference[] typeArguments = currentMessageSend.typeArguments;
+					if (typeArguments != null) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+							if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+								this.scribe.space();
+							}
+							int length = typeArguments.length;
+							for (int j = 0; j < length - 1; j++) {
+								typeArguments[j].traverse(this, scope);
+								this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+								if (this.preferences.insert_space_after_comma_in_type_arguments) {
+									this.scribe.space();
+								}
+							}
+							typeArguments[length - 1].traverse(this, scope);
+							if (isClosingGenericToken()) {
+								this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+							}
+							if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+								this.scribe.space();
+							}
+					}
+					ASTNode[] arguments = currentMessageSend.arguments;
+					this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector
+					this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+					if (arguments != null) {
+						if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+							this.scribe.space();
+						}
+						int argumentLength = arguments.length;
+						int alignmentMode = this.preferences.alignment_for_arguments_in_method_invocation;
+						Alignment argumentsAlignment = this.scribe.createAlignment(
+								Alignment.MESSAGE_ARGUMENTS,
+								alignmentMode,
+								Alignment.R_OUTERMOST,
+								argumentLength,
+								this.scribe.scanner.currentPosition);
+						this.scribe.enterAlignment(argumentsAlignment);
+						boolean okForArguments = false;
+						do {
+							switch (alignmentMode & Alignment.SPLIT_MASK) {
+								case Alignment.M_COMPACT_SPLIT:
+								case Alignment.M_NEXT_PER_LINE_SPLIT:
+									argumentsAlignment.startingColumn = this.scribe.column;
+									break;
+							}
+							try {
+								for (int j = 0; j < argumentLength; j++) {
+									if (j > 0) {
+										this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments);
+										this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+									}
+									this.scribe.alignFragment(argumentsAlignment, j);
+									if (j == 0) {
+										int fragmentIndentation = argumentsAlignment.fragmentIndentations[j];
+										if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) {
+											this.scribe.indentationLevel = fragmentIndentation;
+										}	
+									} else if (this.preferences.insert_space_after_comma_in_method_invocation_arguments) {
+										this.scribe.space();
+									}
+									arguments[j].traverse(this, scope);
+									argumentsAlignment.startingColumn = -1;
+								}
+								okForArguments = true;
+							} catch (AlignmentException e) {
+								this.scribe.redoAlignment(e);
+							}
+						} while (!okForArguments);
+						this.scribe.exitAlignment(argumentsAlignment, true);
+						this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+					} else {
+						this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+					}
+					if (numberOfParens > 0) {
+						manageClosingParenthesizedExpression(currentMessageSend, numberOfParens);
+					}
+					cascadingMessageSendAlignment.startingColumn = -1;
+					if (i < size - 1) {
+						this.scribe.alignFragment(cascadingMessageSendAlignment, i);
+						this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+					}
+				}
+				ok = true;
+			} catch(AlignmentException e){
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(cascadingMessageSendAlignment, true);
+	}
+
+	/*
+	 * Merged traversal of member (types, fields, methods)
+	 */
+	private void formatClassBodyDeclarations(ASTNode[] nodes) {
+		final int FIELD = 1, METHOD = 2, TYPE = 3;
+		this.scribe.lastNumberOfNewLines = 1;
+		ASTNode[] mergedNodes = computeMergedMemberDeclarations(nodes);
+		Alignment memberAlignment = this.scribe.createMemberAlignment(
+				Alignment.TYPE_MEMBERS,
+				this.preferences.align_type_members_on_columns ? Alignment.M_MULTICOLUMN : Alignment.M_NO_ALIGNMENT,
+				4,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterMemberAlignment(memberAlignment);
+		boolean isChunkStart = false;
+		boolean ok = false;
+		int startIndex = 0;
+		do {
+			try {
+				for (int i = startIndex, max = mergedNodes.length; i < max; i++) {
+					ASTNode member = mergedNodes[i];
+					if (member instanceof FieldDeclaration) {
+						isChunkStart = memberAlignment.checkChunkStart(FIELD, i, this.scribe.scanner.currentPosition);
+						if (member instanceof MultiFieldDeclaration){
+							MultiFieldDeclaration multiField = (MultiFieldDeclaration) member;
+							format(multiField, this, null, isChunkStart, i == 0);
+						} else if (member instanceof Initializer) {
+							int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+							if (newLineBeforeChunk > 0 && i != 0) {
+								this.scribe.printEmptyLines(newLineBeforeChunk);
+							} else if (i == 0) {
+								int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+								if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+									this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+								}
+							}
+							Initializer initializer = (Initializer) member;
+							initializer.traverse(this, null);
+						} else {
+							FieldDeclaration field = (FieldDeclaration) member;
+							format(field, this, null, isChunkStart, i == 0);
+						}
+					} else if (member instanceof AbstractMethodDeclaration) {
+						isChunkStart = memberAlignment.checkChunkStart(METHOD, i, this.scribe.scanner.currentPosition);
+						format((AbstractMethodDeclaration) member, null, isChunkStart, i == 0);
+					} else {
+						isChunkStart = memberAlignment.checkChunkStart(TYPE, i, this.scribe.scanner.currentPosition);
+						format((TypeDeclaration)member, null, isChunkStart, i == 0);
+					}
+					while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					}
+					if (i != max - 1) {
+						this.scribe.printNewLine();
+					}
+				}
+				ok = true;
+			} catch(AlignmentException e){
+				startIndex = memberAlignment.chunkStartIndex;
+				this.scribe.redoMemberAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitMemberAlignment(memberAlignment);
+		if (hasComments()) {
+			this.scribe.printNewLine();
+		}
+		this.scribe.printComment();
+	}
+
+	private void formatEmptyTypeDeclaration(boolean isFirst) {
+		boolean hasSemiColon = isNextToken(TerminalTokens.TokenNameSEMICOLON);
+		while(isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+			this.scribe.printComment();
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+		if (hasSemiColon && isFirst) {
+			this.scribe.printNewLine();
+		}
+	}
+
+	private void formatGuardClauseBlock(Block block, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, this.preferences.insert_space_before_opening_brace_in_block);
+		this.scribe.space();
+
+		final Statement[] statements = block.statements;
+		statements[0].traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, true);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+	}
+
+	private void formatLeftCurlyBrace(final int line, final String bracePosition) {
+		/*
+		 * deal with (quite unexpected) comments right before lcurly
+		 */
+		this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_FORMAT_LEFT_CURLY_BRACE);
+		if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition)
+				&& (this.scribe.line > line || this.scribe.column >= this.preferences.page_width))
+		{
+			this.scribe.printNewLine();
+		}
+	}
+
+	private void formatLocalDeclaration(LocalDeclaration localDeclaration, BlockScope scope, boolean insertSpaceBeforeComma, boolean insertSpaceAfterComma) {
+
+		if (!isMultipleLocalDeclaration(localDeclaration)) {
+			if (localDeclaration.modifiers != NO_MODIFIERS || localDeclaration.annotations != null) {
+		        this.scribe.printComment();
+				this.scribe.printModifiers(localDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_LOCAL_VARIABLE);
+				this.scribe.space();
+			}
+
+			/*
+			 * Argument type
+			 */
+			if (localDeclaration.type != null) {
+				localDeclaration.type.traverse(this, scope);
+			}
+			/*
+			 * Print the argument name
+		 	*/
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+		} else {
+			/*
+			 * Print the argument name
+		 	*/
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false);
+		}
+		formatExtraDimensions(localDeclaration.type);
+
+		final Expression initialization = localDeclaration.initialization;
+		if (initialization != null) {
+			/*
+			 * Print the method name
+			 */
+			this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator);
+			if (this.preferences.insert_space_after_assignment_operator) {
+				this.scribe.space();
+			}
+			Alignment assignmentAlignment = this.scribe.createAlignment(
+					Alignment.LOCAL_DECLARATION_ASSIGNMENT,
+					this.preferences.alignment_for_assignment,
+					Alignment.R_OUTERMOST,
+					1,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(assignmentAlignment);
+			boolean ok = false;
+			do {
+				try {
+					this.scribe.alignFragment(assignmentAlignment, 0);
+					initialization.traverse(this, scope);
+					ok = true;
+				} catch(AlignmentException e){
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(assignmentAlignment, true);
+		}
+
+		if (isPartOfMultipleLocalDeclaration()) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, insertSpaceBeforeComma);
+			if (insertSpaceAfterComma) {
+				this.scribe.space();
+			}
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+	}
+
+	private void formatMessageSend(
+		MessageSend messageSend,
+		BlockScope scope,
+		Alignment messageAlignment) {
+
+		if (messageAlignment != null) {
+			if (!this.preferences.wrap_outer_expressions_when_nested || messageAlignment.canAlign()) {
+				this.scribe.alignFragment(messageAlignment, 0);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		}
+		TypeReference[] typeArguments = messageSend.typeArguments;
+		if (typeArguments != null) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+				if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+				int length = typeArguments.length;
+				for (int i = 0; i < length - 1; i++) {
+					typeArguments[i].traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+					if (this.preferences.insert_space_after_comma_in_type_arguments) {
+						this.scribe.space();
+					}
+				}
+				typeArguments[length - 1].traverse(this, scope);
+				if (isClosingGenericToken()) {
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+				}
+				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+
+		final Expression[] arguments = messageSend.arguments;
+		if (arguments != null) {
+			if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+				this.scribe.space();
+			}
+			int argumentsLength = arguments.length;
+			if (argumentsLength > 1) {
+				int alignmentMode = this.preferences.alignment_for_arguments_in_method_invocation;
+				Alignment argumentsAlignment = this.scribe.createAlignment(
+						Alignment.MESSAGE_ARGUMENTS,
+						alignmentMode,
+						argumentsLength,
+						this.scribe.scanner.currentPosition);
+				this.scribe.enterAlignment(argumentsAlignment);
+				boolean ok = false;
+				do {
+					switch (alignmentMode & Alignment.SPLIT_MASK) {
+						case Alignment.M_COMPACT_SPLIT:
+						case Alignment.M_NEXT_PER_LINE_SPLIT:
+							argumentsAlignment.startingColumn = this.scribe.column;
+							break;
+					}
+					try {
+						for (int i = 0; i < argumentsLength; i++) {
+							if (i > 0) {
+								this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_method_invocation_arguments);
+								this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+								if (this.scribe.lastNumberOfNewLines == 1) {
+									// a new line has been inserted while printing the comment
+									// hence we need to use the break indentation level before printing next token...
+									this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel;
+								}
+							}
+							this.scribe.alignFragment(argumentsAlignment, i);
+							if (i > 0 && this.preferences.insert_space_after_comma_in_method_invocation_arguments) {
+								this.scribe.space();
+							}
+							int fragmentIndentation = 0;
+							if (i == 0) {
+								int wrappedIndex = argumentsAlignment.wrappedIndex();
+								if (wrappedIndex >= 0) {
+									fragmentIndentation = argumentsAlignment.fragmentIndentations[wrappedIndex];
+									if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) {
+										this.scribe.indentationLevel = fragmentIndentation;
+									}
+								}
+							}
+							arguments[i].traverse(this, scope);
+							argumentsAlignment.startingColumn = -1;
+						}
+						ok = true;
+					} catch (AlignmentException e) {
+						this.scribe.redoAlignment(e);
+					}
+				} while (!ok);
+				this.scribe.exitAlignment(argumentsAlignment, true);
+			} else {
+				arguments[0].traverse(this, scope);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+		}
+	}
+
+	private void formatTryResources(
+			TryStatement tryStatement,
+			boolean spaceBeforeOpenParen,
+			boolean spaceBeforeClosingParen,
+			boolean spaceBeforeFirstResource,
+			boolean spaceBeforeSemicolon,
+			boolean spaceAfterSemicolon,
+			int tryResourcesAligment) {
+
+		LocalDeclaration[] resources = tryStatement.resources;
+		int length = resources != null ? resources.length : 0;
+		if (length > 0) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen);
+			if (spaceBeforeFirstResource) {
+				this.scribe.space();
+			}
+			Alignment resourcesAlignment = this.scribe.createAlignment(
+					Alignment.TRY_RESOURCES,
+					tryResourcesAligment,
+					// make sure alignment options for try with resources takes precedence
+					Alignment.R_OUTERMOST,
+					length,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(resourcesAlignment);
+			boolean ok = false;
+			do {
+				switch (tryResourcesAligment & Alignment.SPLIT_MASK) {
+					case Alignment.M_COMPACT_SPLIT:
+					case Alignment.M_NEXT_PER_LINE_SPLIT:
+						resourcesAlignment.startingColumn = this.scribe.column;
+						break;
+				}
+				try {
+					for (int i = 0; i < length; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							if (this.scribe.lastNumberOfNewLines == 1) {
+								// a new line has been inserted while printing the comment
+								// hence we need to use the break indentation level before printing next token...
+								this.scribe.indentationLevel = resourcesAlignment.breakIndentationLevel;
+							}
+						}
+						this.scribe.alignFragment(resourcesAlignment, i);
+						if (i == 0) {
+							int fragmentIndentation = resourcesAlignment.fragmentIndentations[0];
+							if ((resourcesAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) {
+								this.scribe.indentationLevel = fragmentIndentation;
+							}
+						} else if (spaceAfterSemicolon) {
+							this.scribe.space();
+						}
+						resources[i].traverse(this, null);
+						resourcesAlignment.startingColumn = -1;
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			
+			this.scribe.exitAlignment(resourcesAlignment, true);
+			if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+				// take care of trailing semicolon
+				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, spaceBeforeSemicolon);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen);
+		}
+	}
+	private void formatMethodArguments(
+			AbstractMethodDeclaration methodDeclaration,
+			boolean spaceBeforeOpenParen,
+			boolean spaceBetweenEmptyParameters,
+			boolean spaceBeforeClosingParen,
+			boolean spaceBeforeFirstParameter,
+			boolean spaceBeforeComma,
+			boolean spaceAfterComma,
+			int methodDeclarationParametersAlignment) {
+		formatMethodArguments(
+				methodDeclaration.receiver,
+				methodDeclaration.arguments,
+				methodDeclaration.scope,
+				spaceBeforeOpenParen,
+				spaceBetweenEmptyParameters,
+				spaceBeforeClosingParen,
+				spaceBeforeFirstParameter,
+				spaceBeforeComma,
+				spaceAfterComma,
+				methodDeclarationParametersAlignment);
+	}
+	private void formatMethodArguments(
+			Receiver receiver,
+			final Argument[] arguments,
+			MethodScope scope,
+			boolean spaceBeforeOpenParen,
+			boolean spaceBetweenEmptyParameters,
+			boolean spaceBeforeClosingParen,
+			boolean spaceBeforeFirstParameter,
+			boolean spaceBeforeComma,
+			boolean spaceAfterComma,
+			int methodDeclarationParametersAlignment) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen);
+
+		if (arguments != null || receiver != null) {
+			if (spaceBeforeFirstParameter) {
+				this.scribe.space();
+			}
+			int receiverCount = receiver != null ? 1 : 0;
+			int realArgumentLength =  arguments != null ? arguments.length : 0;
+			int argumentLength = realArgumentLength + receiverCount;
+			Alignment argumentsAlignment = this.scribe.createAlignment(
+					Alignment.METHOD_ARGUMENTS,
+					methodDeclarationParametersAlignment,
+					argumentLength,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				switch (methodDeclarationParametersAlignment & Alignment.SPLIT_MASK) {
+					case Alignment.M_COMPACT_SPLIT:
+					case Alignment.M_NEXT_PER_LINE_SPLIT:
+						argumentsAlignment.startingColumn = this.scribe.column;
+						break;
+				}
+				try {
+					for (int i = 0; i < argumentLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							if (this.scribe.lastNumberOfNewLines == 1) {
+								// a new line has been inserted while printing the comment
+								// hence we need to use the break indentation level before printing next token...
+								this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel;
+							}
+						}
+						this.scribe.alignFragment(argumentsAlignment, i);
+						if (i == 0) {
+							int fragmentIndentation = argumentsAlignment.fragmentIndentations[0];
+							if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) {
+								this.scribe.indentationLevel = fragmentIndentation;
+							}
+						} else if (spaceAfterComma) {
+							this.scribe.space();
+						}
+						if (i < receiverCount) {
+							receiver.traverse(this, scope);
+						} else {
+							arguments[i - receiverCount].traverse(this, scope);
+						}
+						argumentsAlignment.startingColumn = -1;
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(argumentsAlignment, true);
+
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBetweenEmptyParameters);
+		}
+	}
+
+	private void formatEnumConstantArguments(
+			FieldDeclaration enumConstant,
+			boolean spaceBeforeOpenParen,
+			boolean spaceBetweenEmptyParameters,
+			boolean spaceBeforeClosingParen,
+			boolean spaceBeforeFirstParameter,
+			boolean spaceBeforeComma,
+			boolean spaceAfterComma,
+			int methodDeclarationParametersAlignment) {
+
+		if (!isNextToken(TerminalTokens.TokenNameLPAREN)) {
+			return;
+		}
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, spaceBeforeOpenParen);
+		final Expression[] arguments = ((AllocationExpression) enumConstant.initialization).arguments;
+		if (arguments != null) {
+			int argumentLength = arguments.length;
+			Alignment argumentsAlignment = this.scribe.createAlignment(
+					Alignment.ENUM_CONSTANTS_ARGUMENTS,
+					methodDeclarationParametersAlignment,
+					argumentLength,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				try {
+					if (spaceBeforeFirstParameter) {
+						this.scribe.space();
+					}
+					for (int i = 0; i < argumentLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.alignFragment(argumentsAlignment, i);
+						if (i > 0 && spaceAfterComma) {
+							this.scribe.space();
+						}
+						arguments[i].traverse(this, (BlockScope) null);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(argumentsAlignment, true);
+
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBeforeClosingParen);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, spaceBetweenEmptyParameters);
+		}
+	}
+
+	private void formatNecessaryEmptyStatement() {
+		if (this.preferences.put_empty_statement_on_new_line) {
+			this.scribe.printNewLine();
+			this.scribe.indent();
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			this.scribe.unIndent();
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+	}
+
+	private void formatOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace) {
+
+			if (DefaultCodeFormatterConstants.NEXT_LINE.equals(bracePosition)) {
+				this.scribe.printNewLine();
+			} else if (DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED.equals(bracePosition)) {
+				this.scribe.printNewLine();
+				this.scribe.indent();
+			} else if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition)
+					&& this.scribe.column >= this.preferences.page_width) {
+				this.scribe.printNewLine();
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, insertSpaceBeforeBrace, Scribe.PRESERVE_EMPTY_LINES_IN_FORMAT_OPENING_BRACE);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.UNMODIFIABLE_TRAILING_COMMENT);
+	}
+	private void formatStatements(BlockScope scope, final Statement[] statements, boolean insertNewLineAfterLastStatement) {
+		int statementsLength = statements.length;
+		for (int i = 0; i < statementsLength; i++) {
+			final Statement statement = statements[i];
+			if (i > 0 && (statements[i - 1] instanceof EmptyStatement) && !(statement instanceof EmptyStatement)) {
+				this.scribe.printNewLine();
+			}
+			statement.traverse(this, scope);
+			if (statement instanceof Expression) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				if (i != statementsLength - 1) {
+					if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) {
+						this.scribe.printNewLine();
+					}
+				} else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) {
+					this.scribe.printNewLine();
+				}
+			} else if (statement instanceof LocalDeclaration) {
+				LocalDeclaration currentLocal = (LocalDeclaration) statement;
+				if (i < (statementsLength - 1)) {
+					/*
+					 * We need to check that the next statement is a local declaration
+					 */
+					if (statements[i + 1] instanceof LocalDeclaration) {
+						LocalDeclaration nextLocal = (LocalDeclaration) statements[i + 1];
+						if (currentLocal.declarationSourceStart != nextLocal.declarationSourceStart) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							if (i != statementsLength - 1) {
+								if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) {
+									this.scribe.printNewLine();
+								}
+							} else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) {
+								this.scribe.printNewLine();
+							}
+						}
+					} else {
+						this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						if (i != statementsLength - 1) {
+							if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) {
+								this.scribe.printNewLine();
+							}
+						} else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) {
+							this.scribe.printNewLine();
+						}
+					}
+				} else {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					if (i != statementsLength - 1) {
+						if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) {
+							this.scribe.printNewLine();
+						}
+					} else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) {
+						this.scribe.printNewLine();
+					}
+				}
+			} else if (i != statementsLength - 1) {
+				if (!(statement instanceof EmptyStatement) && !(statements[i + 1] instanceof EmptyStatement)) {
+					this.scribe.printNewLine();
+				}
+			} else if (i == statementsLength - 1 && insertNewLineAfterLastStatement) {
+				this.scribe.printNewLine();
+			}
+		}
+	}
+
+	private void formatThrowsClause(
+		AbstractMethodDeclaration methodDeclaration,
+		boolean spaceBeforeComma,
+		boolean spaceAfterComma,
+		int alignmentForThrowsClause) {
+
+		final TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+		if (thrownExceptions != null) {
+			int thrownExceptionsLength = thrownExceptions.length;
+			Alignment throwsAlignment = this.scribe.createAlignment(
+					Alignment.THROWS,
+					alignmentForThrowsClause,
+					thrownExceptionsLength, // throws is the first token
+					this.scribe.scanner.currentPosition);
+
+			this.scribe.enterAlignment(throwsAlignment);
+			boolean ok = false;
+			do {
+				try {
+					this.scribe.alignFragment(throwsAlignment, 0);
+					this.scribe.printNextToken(TerminalTokens.TokenNamethrows, true);
+
+					for (int i = 0; i < thrownExceptionsLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, spaceBeforeComma);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							this.scribe.alignFragment(throwsAlignment, i);
+							if (spaceAfterComma) {
+								this.scribe.space();
+							}
+						} else {
+							this.scribe.space();
+						}
+						thrownExceptions[i].traverse(this, methodDeclaration.scope);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(throwsAlignment, true);
+		}
+	}
+
+	/*
+	 * Merged traversal of member (types, fields, methods)
+	 */
+	private void formatTypeMembers(TypeDeclaration typeDeclaration) {
+		Alignment memberAlignment = this.scribe.createMemberAlignment(
+				Alignment.TYPE_MEMBERS,
+				this.preferences.align_type_members_on_columns ? Alignment.M_MULTICOLUMN : Alignment.M_NO_ALIGNMENT,
+				3,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterMemberAlignment(memberAlignment);
+		ASTNode[] members = computeMergedMemberDeclarations(typeDeclaration);
+		boolean isChunkStart = false;
+		boolean ok = false;
+		int membersLength = members.length;
+		if (membersLength > 0) {
+			int startIndex = 0;
+			do {
+				try {
+					for (int i = startIndex, max = members.length; i < max; i++) {
+						while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.printNewLine();
+						ASTNode member = members[i];
+						if (member instanceof FieldDeclaration) {
+							isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_FIELD, i, this.scribe.scanner.currentPosition);
+							if (member instanceof MultiFieldDeclaration) {
+								MultiFieldDeclaration multiField = (MultiFieldDeclaration) member;
+	
+								if (multiField.isStatic()) {
+									format(multiField, this, typeDeclaration.staticInitializerScope, isChunkStart, i == 0);
+								} else {
+									format(multiField, this, typeDeclaration.initializerScope, isChunkStart, i == 0);
+								}
+							} else if (member instanceof Initializer) {
+								int newLineBeforeChunk = isChunkStart ? this.preferences.blank_lines_before_new_chunk : 0;
+								if (newLineBeforeChunk > 0 && i != 0) {
+									this.scribe.printEmptyLines(newLineBeforeChunk);
+								} else if (i == 0) {
+									int newLinesBeforeFirstClassBodyDeclaration = this.preferences.blank_lines_before_first_class_body_declaration;
+									if (newLinesBeforeFirstClassBodyDeclaration > 0) {
+										this.scribe.printEmptyLines(newLinesBeforeFirstClassBodyDeclaration);
+									}
+								}
+								Initializer initializer = (Initializer) member;
+								if (initializer.isStatic()) {
+									initializer.traverse(this, typeDeclaration.staticInitializerScope);
+								} else {
+									initializer.traverse(this, typeDeclaration.initializerScope);
+								}
+							} else {
+								FieldDeclaration field = (FieldDeclaration) member;
+								if (field.isStatic()) {
+									format(field, this, typeDeclaration.staticInitializerScope, isChunkStart, i == 0);
+								} else {
+									format(field, this, typeDeclaration.initializerScope, isChunkStart, i == 0);
+								}
+							}
+						} else if (member instanceof AbstractMethodDeclaration) {
+							isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_METHOD, i, this.scribe.scanner.currentPosition);
+							format((AbstractMethodDeclaration) member, typeDeclaration.scope, isChunkStart, i == 0);
+						} else if (member instanceof TypeDeclaration) {
+							isChunkStart = memberAlignment.checkChunkStart(Alignment.CHUNK_TYPE, i, this.scribe.scanner.currentPosition);
+							format((TypeDeclaration)member, typeDeclaration.scope, isChunkStart, i == 0);
+						}
+						while (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.printNewLine();
+						// realign to the proper value
+						if (this.scribe.memberAlignment != null) {
+							// select the last alignment
+							this.scribe.indentationLevel = this.scribe.memberAlignment.originalIndentationLevel;
+						}
+					}
+					ok = true;
+				} catch(AlignmentException e){
+					startIndex = memberAlignment.chunkStartIndex;
+					this.scribe.redoMemberAlignment(e);
+				}
+			} while (!ok);
+		} else if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+			// the only body declaration is an empty declaration (';')
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+		this.scribe.printComment(Scribe.DO_NOT_PRESERVE_EMPTY_LINES);
+		this.scribe.exitMemberAlignment(memberAlignment);
+	}
+
+	private void formatTypeOpeningBraceForEnumConstant(String bracePosition, boolean insertSpaceBeforeBrace, TypeDeclaration typeDeclaration) {
+		int fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length;
+		int methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length;
+		int typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length;
+
+		if (methodCount <= 2) {
+			for (int i = 0, max = methodCount; i < max; i++) {
+				final AbstractMethodDeclaration abstractMethodDeclaration = typeDeclaration.methods[i];
+				if (abstractMethodDeclaration.isDefaultConstructor()) {
+					methodCount--;
+				} else if (abstractMethodDeclaration.isClinit()) {
+					methodCount--;
+				}
+			}
+		}
+		final int memberLength = fieldCount + methodCount+typeCount;
+
+		boolean insertNewLine = memberLength > 0;
+
+		if (!insertNewLine) {
+			if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+				insertNewLine = this.preferences.insert_new_line_in_empty_enum_constant;
+			}
+		}
+
+		formatOpeningBrace(bracePosition, insertSpaceBeforeBrace);
+
+		if (insertNewLine) {
+			this.scribe.printNewLine();
+		}
+	}
+	private void formatTypeOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace, TypeDeclaration typeDeclaration) {
+		int fieldCount = (typeDeclaration.fields == null) ? 0 : typeDeclaration.fields.length;
+		int methodCount = (typeDeclaration.methods == null) ? 0 : typeDeclaration.methods.length;
+		int typeCount = (typeDeclaration.memberTypes == null) ? 0 : typeDeclaration.memberTypes.length;
+
+		if (methodCount <= 2) {
+			for (int i = 0, max = methodCount; i < max; i++) {
+				final AbstractMethodDeclaration abstractMethodDeclaration = typeDeclaration.methods[i];
+				if (abstractMethodDeclaration.isDefaultConstructor()) {
+					methodCount--;
+				} else if (abstractMethodDeclaration.isClinit()) {
+					methodCount--;
+				}
+			}
+		}
+		final int memberLength = fieldCount + methodCount + typeCount;
+
+		boolean insertNewLine = memberLength > 0;
+
+		if (!insertNewLine) {
+			if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ENUM_DECL) {
+				insertNewLine = this.preferences.insert_new_line_in_empty_enum_declaration;
+			} else if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+				insertNewLine = this.preferences.insert_new_line_in_empty_anonymous_type_declaration;
+			} else if (TypeDeclaration.kind(typeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
+				insertNewLine = this.preferences.insert_new_line_in_empty_annotation_declaration;
+			} else {
+				insertNewLine = this.preferences.insert_new_line_in_empty_type_declaration;
+			}
+		}
+
+		formatOpeningBrace(bracePosition, insertSpaceBeforeBrace);
+
+		if (insertNewLine) {
+			this.scribe.printNewLine();
+		}
+	}
+	private int getDimensions() {
+
+		this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1);
+		int dimensions = 0;
+		int balance = 0;
+		try {
+			int token;
+			loop: while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameRBRACKET:
+						dimensions++;
+						balance--;
+						break;
+					case TerminalTokens.TokenNameAT :
+						skipPastTypeAnnotations();
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						break;
+					case TerminalTokens.TokenNameLBRACKET :
+						balance++;
+						break;
+					default:
+						break loop;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		if (balance == 0) {
+			return dimensions;
+		}
+		return 0;
+	}
+
+		private void skipPastTypeAnnotations() {  // we get here having seen @
+		int balance = 0;
+		int currentTokenStartPosition = this.localScanner.currentPosition;
+		try {
+			loop: while (true) {
+				currentTokenStartPosition = this.localScanner.currentPosition;
+				int token = this.localScanner.getNextToken();
+				switch(token) {
+					case TerminalTokens.TokenNameEOF:
+						break loop;
+					case TerminalTokens.TokenNameIdentifier :
+					case TerminalTokens.TokenNameDOT :
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						break;
+					case TerminalTokens.TokenNameLPAREN:
+						balance++;
+						break;
+					case TerminalTokens.TokenNameRPAREN:
+						--balance; 
+						break;
+					default:
+						if (balance <= 0)
+							break loop;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		} finally {
+			this.localScanner.resetTo(currentTokenStartPosition, this.scribe.scannerEndPosition - 1);
+		}
+	}
+
+	private boolean hasComments() {
+
+		this.localScanner.resetTo(this.scribe.scanner.startPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			switch(this.localScanner.getNextToken()) {
+				case TerminalTokens.TokenNameCOMMENT_BLOCK :
+				case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+				case TerminalTokens.TokenNameCOMMENT_LINE :
+					return true;
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private boolean isNextToken(int tokenName) {
+		this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			int token = this.localScanner.getNextToken();
+			loop: while(true) {
+				switch(token) {
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						token = this.localScanner.getNextToken();
+						continue loop;
+					default:
+						break loop;
+				}
+			}
+			return  token == tokenName;
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private boolean isNextTokenPunctuation() {
+		this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			int token = this.localScanner.getNextToken();
+			return !(Scanner.isLiteral(token) || Scanner.isKeyword(token) || Scanner.isIdentifier(token));
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private boolean isClosingGenericToken() {
+		this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			int token = this.localScanner.getNextToken();
+			loop: while(true) {
+				switch(token) {
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						token = this.localScanner.getNextToken();
+						continue loop;
+					default:
+						break loop;
+				}
+			}
+			switch(token) {
+				case TerminalTokens.TokenNameGREATER :
+				case TerminalTokens.TokenNameRIGHT_SHIFT :
+				case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT :
+					return true;
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private boolean isGuardClause(Block block) {
+		return !commentStartsBlock(block.sourceStart, block.sourceEnd)
+				&& block.statements != null
+				&& block.statements.length == 1
+				&& (block.statements[0] instanceof ReturnStatement || block.statements[0] instanceof ThrowStatement);
+	}
+
+	private boolean isMultipleLocalDeclaration(LocalDeclaration localDeclaration) {
+
+		if (localDeclaration.declarationSourceStart == this.lastLocalDeclarationSourceStart) return true;
+		this.lastLocalDeclarationSourceStart = localDeclaration.declarationSourceStart;
+		return false;
+	}
+
+	private boolean isPartOfMultipleLocalDeclaration() {
+		this.localScanner.resetTo(this.scribe.scanner.currentPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			int token;
+			while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				switch(token) {
+					case TerminalTokens.TokenNameCOMMA ://90
+						return true;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						break;
+					default:
+						return false;
+				}
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+		return false;
+	}
+
+	private void manageClosingParenthesizedExpression(Expression expression, int numberOfParens) {
+		for (int i = 0; i < numberOfParens; i++) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_parenthesized_expression);
+		}
+	}
+
+	private void manageOpeningParenthesizedExpression(Expression expression, int numberOfParens) {
+		for (int i = 0; i < numberOfParens; i++) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_parenthesized_expression);
+			if (this.preferences.insert_space_after_opening_paren_in_parenthesized_expression) {
+				this.scribe.space();
+			}
+		}
+	}
+
+	private void printComment() {
+		this.localScanner.resetTo(this.scribe.scanner.startPosition, this.scribe.scannerEndPosition - 1);
+		try {
+			int token = this.localScanner.getNextToken();
+			switch(token) {
+				case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+				case TerminalTokens.TokenNameCOMMENT_BLOCK :
+				case TerminalTokens.TokenNameCOMMENT_LINE :
+	    			this.scribe.printComment(token, Scribe.NO_TRAILING_COMMENT);
+	    			break;
+			}
+		} catch(InvalidInputException e) {
+			// ignore
+		}
+    }
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		AllocationExpression allocationExpression,
+		BlockScope scope) {
+		// 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt
+
+		final int numberOfParens = (allocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(allocationExpression, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNamenew);
+		TypeReference[] typeArguments = allocationExpression.typeArguments;
+		if (typeArguments != null) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+				if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+				int length = typeArguments.length;
+				for (int i = 0; i < length - 1; i++) {
+					typeArguments[i].traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+					if (this.preferences.insert_space_after_comma_in_type_arguments) {
+						this.scribe.space();
+					}
+				}
+				typeArguments[length - 1].traverse(this, scope);
+				if (isClosingGenericToken()) {
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+				}
+				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+		} else {
+			this.scribe.space();
+		}
+
+		allocationExpression.type.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+
+		final Expression[] arguments = allocationExpression.arguments;
+		if (arguments != null) {
+			if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+				this.scribe.space();
+			}
+			int argumentLength = arguments.length;
+			Alignment argumentsAlignment =this.scribe.createAlignment(
+					Alignment.ALLOCATION,
+					this.preferences.alignment_for_arguments_in_allocation_expression,
+					argumentLength,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				try {
+					for (int i = 0; i < argumentLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_allocation_expression);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.alignFragment(argumentsAlignment, i);
+						if (i > 0 && this.preferences.insert_space_after_comma_in_allocation_expression) {
+							this.scribe.space();
+						}
+						arguments[i].traverse(this, scope);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(argumentsAlignment, true);
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+		}
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(allocationExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		AND_AND_Expression and_and_Expression,
+		BlockScope scope) {
+
+		return dumpBinaryExpression(and_and_Expression, TerminalTokens.TokenNameAND_AND, scope);
+	}
+	public boolean visit(
+			AnnotationMethodDeclaration annotationTypeMemberDeclaration,
+			ClassScope scope) {
+        /*
+         * Print comments to get proper line number
+         */
+        this.scribe.printComment();
+        this.scribe.printModifiers(annotationTypeMemberDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD);
+		this.scribe.space();
+		/*
+		 * Print the method return type
+		 */
+		final TypeReference returnType = annotationTypeMemberDeclaration.returnType;
+		final MethodScope annotationTypeMemberDeclarationScope = annotationTypeMemberDeclaration.scope;
+
+		if (returnType != null) {
+			returnType.traverse(this, annotationTypeMemberDeclarationScope);
+		}
+		/*
+		 * Print the method name
+		 */
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation_type_member_declaration);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_annotation_type_member_declaration);
+
+		/*
+		 * Check for extra dimensions
+		 */
+		int extraDimensions = annotationTypeMemberDeclaration.extendedDimensions;
+		if (extraDimensions != 0) {
+			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
+				this.scribe.space();
+			}
+			 for (int i = 0; i < extraDimensions; i++) {
+			 	this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET);
+			 	if (this.preferences.insert_space_between_brackets_in_array_type_reference) {
+			 		this.scribe.space();
+			 	}
+			 	this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET);
+			 }
+		}
+
+		Expression defaultValue = annotationTypeMemberDeclaration.defaultValue;
+		if (defaultValue != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNamedefault, true);
+			this.scribe.space();
+			defaultValue.traverse(this, (BlockScope) null);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Argument, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(Argument argument, BlockScope scope) {
+
+		if (argument.modifiers != NO_MODIFIERS || argument.annotations != null) {
+	        this.scribe.printComment();
+			this.scribe.printModifiers(argument.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_PARAMETER);
+			this.scribe.space();
+		}
+
+		/*
+		 * Argument type
+		 */
+		TypeReference argumentType = argument.type;
+		if (argumentType != null) {
+			if (argumentType instanceof UnionTypeReference) {
+				formatMultiCatchArguments(
+						argument, 
+						this.preferences.insert_space_before_binary_operator, 
+						this.preferences.insert_space_after_binary_operator,
+						this.preferences.alignment_for_union_type_in_multicatch,
+						scope);
+			} else {
+				argumentType.traverse(this, scope);
+			}
+		}
+
+		if (argument.isVarArgs()) {
+			Annotation [][] annotationsOnDimensions = argumentType.getAnnotationsOnDimensions();
+			if (annotationsOnDimensions != null) {
+				Annotation [] varargAnnotations = annotationsOnDimensions[annotationsOnDimensions.length - 1];
+				if (varargAnnotations != null) {
+					formatInlineAnnotations(varargAnnotations, true);
+				}
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameELLIPSIS, this.preferences.insert_space_before_ellipsis);
+			if (this.preferences.insert_space_after_ellipsis) {
+				this.scribe.space();
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false);
+		} else {
+			if (argument.isReceiver()) {
+				this.scribe.space();
+				NameReference qualifyingName = ((Receiver) argument).qualifyingName;
+				if (qualifyingName != null) {
+					qualifyingName.traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameDOT, false);
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNamethis, false);
+			} else {
+				/*
+				 * Print the argument name
+				 */
+				this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, argument.type != null);
+			}
+		}
+
+		formatExtraDimensions(argumentType);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		ArrayAllocationExpression arrayAllocationExpression,
+		BlockScope scope) {
+
+			final int numberOfParens = (arrayAllocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParens > 0) {
+				manageOpeningParenthesizedExpression(arrayAllocationExpression, numberOfParens);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNamenew);
+			this.scribe.space();
+			arrayAllocationExpression.type.traverse(this, scope);
+
+			final Expression[] dimensions = arrayAllocationExpression.dimensions;
+			int dimensionsLength = dimensions.length;
+			for (int i = 0; i < dimensionsLength; i++) {
+				if (arrayAllocationExpression.annotationsOnDimensions != null) {
+					formatInlineAnnotations(arrayAllocationExpression.annotationsOnDimensions[i], i == 0);
+				}
+				if (this.preferences.insert_space_before_opening_bracket_in_array_allocation_expression) {
+					this.scribe.space();
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET, false);
+				if (dimensions[i] != null) {
+					if (this.preferences.insert_space_after_opening_bracket_in_array_allocation_expression) {
+						this.scribe.space();
+					}
+					dimensions[i].traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_before_closing_bracket_in_array_allocation_expression);
+				} else {
+					this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_between_empty_brackets_in_array_allocation_expression);
+				}
+			}
+			final ArrayInitializer initializer = arrayAllocationExpression.initializer;
+			if (initializer != null) {
+				initializer.traverse(this, scope);
+			}
+
+			if (numberOfParens > 0) {
+				manageClosingParenthesizedExpression(arrayAllocationExpression, numberOfParens);
+			}
+			return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
+		final int numberOfParens = (arrayInitializer.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(arrayInitializer, numberOfParens);
+		}
+
+		if (this.arrayInitializersDepth < 0) {
+			this.arrayInitializersDepth = 0;
+		} else {
+			this.arrayInitializersDepth++;
+		}
+		int arrayInitializerIndentationLevel = this.scribe.indentationLevel;
+		try {
+			final Expression[] expressions = arrayInitializer.expressions;
+			if (expressions != null) {
+				String array_initializer_brace_position = this.preferences.brace_position_for_array_initializer;
+				formatOpeningBrace(array_initializer_brace_position, this.preferences.insert_space_before_opening_brace_in_array_initializer);
+
+				int expressionsLength = expressions.length;
+				final boolean insert_new_line_after_opening_brace = this.preferences.insert_new_line_after_opening_brace_in_array_initializer;
+				boolean ok = false;
+				Alignment arrayInitializerAlignment = null;
+				if (expressionsLength > 1) {
+					if (insert_new_line_after_opening_brace) {
+						this.scribe.printNewLine();
+					}
+					arrayInitializerAlignment = this.scribe.createAlignment(
+							Alignment.ARRAY_INITIALIZER,
+							this.preferences.alignment_for_expressions_in_array_initializer,
+							Alignment.R_OUTERMOST,
+							expressionsLength,
+							this.scribe.scanner.currentPosition,
+							this.preferences.continuation_indentation_for_array_initializer,
+							true);
+	
+					if (insert_new_line_after_opening_brace) {
+						arrayInitializerAlignment.fragmentIndentations[0] = arrayInitializerAlignment.breakIndentationLevel;
+					}
+	
+					this.scribe.enterAlignment(arrayInitializerAlignment);
+					do {
+						try {
+							this.scribe.alignFragment(arrayInitializerAlignment, 0);
+							if (this.preferences.insert_space_after_opening_brace_in_array_initializer) {
+								this.scribe.space();
+							}
+							expressions[0].traverse(this, scope);
+							for (int i = 1; i < expressionsLength; i++) {
+								this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer);
+								this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+								this.scribe.alignFragment(arrayInitializerAlignment, i);
+								if (this.preferences.insert_space_after_comma_in_array_initializer) {
+									this.scribe.space();
+								}
+								expressions[i].traverse(this, scope);
+								if (i == expressionsLength - 1) {
+									if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+										this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer);
+										this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+									}
+								}
+							}
+							ok = true;
+						} catch (AlignmentException e) {
+							this.scribe.redoAlignment(e);
+						}
+					} while (!ok);
+					this.scribe.exitAlignment(arrayInitializerAlignment, true);
+				} else {
+					// Use an alignment with no break in case when the array initializer
+					// is not inside method arguments alignments
+					if (this.scribe.currentAlignment == null || this.scribe.currentAlignment.kind != Alignment.MESSAGE_ARGUMENTS) {
+						arrayInitializerAlignment = this.scribe.createAlignment(
+								Alignment.ARRAY_INITIALIZER,
+								this.preferences.alignment_for_expressions_in_array_initializer,
+								Alignment.R_OUTERMOST,
+								0,
+								this.scribe.scanner.currentPosition,
+								this.preferences.continuation_indentation_for_array_initializer,
+								true);
+						this.scribe.enterAlignment(arrayInitializerAlignment);
+					}
+					do {
+						try {
+							if (insert_new_line_after_opening_brace) {
+								this.scribe.printNewLine();
+								this.scribe.indent();
+							}
+							// we don't need to use an alignment
+							if (this.preferences.insert_space_after_opening_brace_in_array_initializer) {
+								this.scribe.space();
+							} else {
+								this.scribe.needSpace = false;
+							}
+							expressions[0].traverse(this, scope);
+							if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+								this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer);
+								this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							}
+							if (insert_new_line_after_opening_brace) {
+								this.scribe.unIndent();
+							}
+							ok = true;
+						} catch (AlignmentException e) {
+							if (arrayInitializerAlignment == null) throw e;
+							this.scribe.redoAlignment(e);
+						}
+					} while (!ok);
+					if (arrayInitializerAlignment != null) {
+						this.scribe.exitAlignment(arrayInitializerAlignment, true);
+					}
+				}
+				if (this.preferences.insert_new_line_before_closing_brace_in_array_initializer) {
+					this.scribe.printNewLine();
+				} else if (this.preferences.insert_space_before_closing_brace_in_array_initializer) {
+					this.scribe.space();
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, false, Scribe.PRESERVE_EMPTY_LINES_IN_CLOSING_ARRAY_INITIALIZER + (arrayInitializerIndentationLevel << 16));
+				if (array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+					this.scribe.unIndent();
+				}
+			} else {
+				boolean keepEmptyArrayInitializerOnTheSameLine = this.preferences.keep_empty_array_initializer_on_one_line;
+				String array_initializer_brace_position = this.preferences.brace_position_for_array_initializer;
+				if (keepEmptyArrayInitializerOnTheSameLine) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, this.preferences.insert_space_before_opening_brace_in_array_initializer);
+					if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					}
+					this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, this.preferences.insert_space_between_empty_braces_in_array_initializer);
+				} else {
+					formatOpeningBrace(array_initializer_brace_position, this.preferences.insert_space_before_opening_brace_in_array_initializer);
+					if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_array_initializer);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					}
+					this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, this.preferences.insert_space_between_empty_braces_in_array_initializer);
+					if (array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+						this.scribe.unIndent();
+					}
+				}
+			}
+		} finally {
+			this.arrayInitializersDepth--;
+		}
+		
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(arrayInitializer, numberOfParens);
+		}
+		return false;
+	}
+
+	private void formatArrayQualifiedTypeReference(ArrayQualifiedTypeReference arrayQualifiedTypeReference) {
+		final int numberOfParens = (arrayQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens);
+		}
+		formatQualifiedTypeReference(arrayQualifiedTypeReference);
+		formatLeadingDimensions(arrayQualifiedTypeReference, true);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens);
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		BlockScope scope) {
+
+			formatArrayQualifiedTypeReference(arrayQualifiedTypeReference);
+			return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference,
+		ClassScope scope) {
+
+			formatArrayQualifiedTypeReference(arrayQualifiedTypeReference);
+			return false;
+	}
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ArrayReference arrayReference, BlockScope scope) {
+
+		final int numberOfParens = (arrayReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(arrayReference, numberOfParens);
+		}
+		arrayReference.receiver.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLBRACKET, this.preferences.insert_space_before_opening_bracket_in_array_reference);
+		if (this.preferences.insert_space_after_opening_bracket_in_array_reference) {
+			this.scribe.space();
+		}
+		arrayReference.position.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACKET, this.preferences.insert_space_before_closing_bracket_in_array_reference);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(arrayReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		ArrayTypeReference arrayTypeReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (arrayTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(arrayTypeReference, numberOfParens);
+		}
+		if (arrayTypeReference.annotations != null) {
+			formatInlineAnnotations(arrayTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS);
+
+		int dimensions = getDimensions();
+		if (dimensions != 0) {
+			formatDimensions(arrayTypeReference, 0, dimensions, true);
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(arrayTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		ArrayTypeReference arrayTypeReference,
+		ClassScope scope) {
+
+		final int numberOfParens = (arrayTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(arrayTypeReference, numberOfParens);
+		}
+		if (arrayTypeReference.annotations != null) {
+			formatInlineAnnotations(arrayTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS);
+		int dimensions = getDimensions();
+		if (dimensions != 0) {
+			formatDimensions(arrayTypeReference, 0, dimensions, true);
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(arrayTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.AssertStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(AssertStatement assertStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameassert);
+		this.scribe.space();
+		assertStatement.assertExpression.traverse(this, scope);
+
+		if (assertStatement.exceptionArgument != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_assert);
+			if (this.preferences.insert_space_after_colon_in_assert) {
+				this.scribe.space();
+			}
+			assertStatement.exceptionArgument.traverse(this, scope);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Assignment, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(Assignment assignment, BlockScope scope) {
+
+		final int numberOfParens = (assignment.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(assignment, numberOfParens);
+		}
+		assignment.lhs.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator);
+		if (this.preferences.insert_space_after_assignment_operator) {
+			this.scribe.space();
+		}
+
+		Alignment assignmentAlignment = this.scribe.createAlignment(
+				Alignment.ASSIGNMENT,
+				this.preferences.alignment_for_assignment,
+				Alignment.R_OUTERMOST,
+				1,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(assignmentAlignment);
+		boolean ok = false;
+		do {
+			try {
+				this.scribe.alignFragment(assignmentAlignment, 0);
+				assignment.expression.traverse(this, scope);
+				ok = true;
+			} catch(AlignmentException e){
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(assignmentAlignment, true);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(assignment, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.BinaryExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
+
+		switch((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
+			case OperatorIds.AND :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameAND, scope);
+			case OperatorIds.DIVIDE :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameDIVIDE, scope);
+			case OperatorIds.GREATER :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameGREATER, scope);
+			case OperatorIds.GREATER_EQUAL :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameGREATER_EQUAL, scope);
+			case OperatorIds.LEFT_SHIFT :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLEFT_SHIFT, scope);
+			case OperatorIds.LESS :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLESS, scope);
+			case OperatorIds.LESS_EQUAL :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameLESS_EQUAL, scope);
+			case OperatorIds.MINUS :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameMINUS, scope);
+			case OperatorIds.MULTIPLY :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameMULTIPLY, scope);
+			case OperatorIds.OR :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameOR, scope);
+			case OperatorIds.PLUS :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNamePLUS, scope);
+			case OperatorIds.REMAINDER :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameREMAINDER, scope);
+			case OperatorIds.RIGHT_SHIFT :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameRIGHT_SHIFT, scope);
+			case OperatorIds.UNSIGNED_RIGHT_SHIFT :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT, scope);
+			case OperatorIds.XOR :
+				return dumpBinaryExpression(binaryExpression, TerminalTokens.TokenNameXOR, scope);
+			default:
+				throw new IllegalStateException();
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Block, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(Block block, BlockScope scope) {
+		formatBlock(block, scope, this.preferences.brace_position_for_block, this.preferences.insert_space_before_opening_brace_in_block);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.BreakStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(BreakStatement breakStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamebreak);
+		if (breakStatement.label != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CaseStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(CaseStatement caseStatement, BlockScope scope) {
+		if (caseStatement.constantExpression == null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNamedefault);
+			this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_default);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNamecase);
+			this.scribe.space();
+			caseStatement.constantExpression.traverse(this, scope);
+			this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_case);
+		}
+		return false;
+	}
+
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CastExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(CastExpression castExpression, BlockScope scope) {
+
+		final int numberOfParens = (castExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(castExpression, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN);
+		if (this.preferences.insert_space_after_opening_paren_in_cast) {
+			this.scribe.space();
+		}
+		castExpression.type.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_cast);
+		if (this.preferences.insert_space_after_closing_paren_in_cast) {
+			this.scribe.space();
+		}
+		castExpression.expression.traverse(this, scope);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(castExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CharLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(CharLiteral charLiteral, BlockScope scope) {
+
+		final int numberOfParens = (charLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(charLiteral, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameCharacterLiteral);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(charLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) {
+
+		final int numberOfParens = (classLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(classLiteral, numberOfParens);
+		}
+		classLiteral.type.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		this.scribe.printNextToken(TerminalTokens.TokenNameclass);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(classLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Clinit, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(Clinit clinit, ClassScope scope) {
+
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration, org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope)
+	 */
+	public boolean visit(
+		CompilationUnitDeclaration compilationUnitDeclaration,
+		CompilationUnitScope scope) {
+
+		// fake new line to handle empty lines before package declaration or import declarations
+		this.scribe.lastNumberOfNewLines = 1;
+
+		// Set header end position
+		final TypeDeclaration[] types = compilationUnitDeclaration.types;
+		int headerEndPosition = types == null ? compilationUnitDeclaration.sourceEnd : types[0].declarationSourceStart;
+		this.scribe.setHeaderComment(headerEndPosition);
+
+		/*
+		 * Package declaration
+		 */
+		ImportReference currentPackage = compilationUnitDeclaration.currentPackage;
+		final boolean hasPackage = currentPackage != null;
+		if (hasPackage) {
+			printComment();
+			int blankLinesBeforePackage = this.preferences.blank_lines_before_package;
+			if (blankLinesBeforePackage > 0) {
+				this.scribe.printEmptyLines(blankLinesBeforePackage);
+			}
+
+			this.scribe.printModifiers(currentPackage.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_PACKAGE);
+			this.scribe.space();
+			// dump the package keyword
+			this.scribe.printNextToken(TerminalTokens.TokenNamepackage);
+			this.scribe.space();
+			this.scribe.printQualifiedReference(compilationUnitDeclaration.currentPackage.sourceEnd, false/*do not expect parenthesis*/);
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			int blankLinesAfterPackage = this.preferences.blank_lines_after_package;
+			if (blankLinesAfterPackage > 0) {
+				this.scribe.printEmptyLines(blankLinesAfterPackage);
+			} else {
+				this.scribe.printNewLine();
+			}
+		} else {
+			this.scribe.printComment();
+		}
+
+		/*
+		 * Import statements
+		 */
+		final ImportReference[] imports = compilationUnitDeclaration.imports;
+		if (imports != null) {
+			if (hasPackage) {
+				int blankLinesBeforeImports = this.preferences.blank_lines_before_imports;
+				if (blankLinesBeforeImports > 0) {
+					this.scribe.printEmptyLines(blankLinesBeforeImports);
+				}
+			}
+			int importLength = imports.length;
+			if (importLength != 1) {
+				format(imports[0], false);
+    			for (int i = 1; i < importLength - 1; i++) {
+    				format(imports[i], false);
+    			}
+    			format(imports[importLength - 1], true);
+			} else {
+				format(imports[0], true);
+			}
+
+			int blankLinesAfterImports = this.preferences.blank_lines_after_imports;
+			if (blankLinesAfterImports > 0) {
+				this.scribe.printEmptyLines(blankLinesAfterImports);
+			}
+		}
+
+		formatEmptyTypeDeclaration(true);
+
+		int blankLineBetweenTypeDeclarations = this.preferences.blank_lines_between_type_declarations;
+		/*
+		 * Type declarations
+		 */
+		if (types != null) {
+			int typesLength = types.length;
+			for (int i = 0; i < typesLength - 1; i++) {
+				types[i].traverse(this, scope);
+				formatEmptyTypeDeclaration(false);
+				if (blankLineBetweenTypeDeclarations != 0) {
+					this.scribe.printEmptyLines(blankLineBetweenTypeDeclarations);
+				} else {
+					this.scribe.printNewLine();
+				}
+			}
+			types[typesLength - 1].traverse(this, scope);
+		}
+		this.scribe.printEndOfCompilationUnit();
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		CompoundAssignment compoundAssignment,
+		BlockScope scope) {
+
+		final int numberOfParens = (compoundAssignment.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(compoundAssignment, numberOfParens);
+		}
+		compoundAssignment.lhs.traverse(this, scope);
+
+		/*
+		 * Print the operator
+		 */
+		int operator;
+		switch(compoundAssignment.operator) {
+			case OperatorIds.PLUS :
+				operator = TerminalTokens.TokenNamePLUS_EQUAL;
+				break;
+			case OperatorIds.MINUS :
+				operator = TerminalTokens.TokenNameMINUS_EQUAL;
+				break;
+			case OperatorIds.MULTIPLY :
+				operator = TerminalTokens.TokenNameMULTIPLY_EQUAL;
+				break;
+			case OperatorIds.DIVIDE :
+				operator = TerminalTokens.TokenNameDIVIDE_EQUAL;
+				break;
+			case OperatorIds.AND :
+				operator = TerminalTokens.TokenNameAND_EQUAL;
+				break;
+			case OperatorIds.OR :
+				operator = TerminalTokens.TokenNameOR_EQUAL;
+				break;
+			case OperatorIds.XOR :
+				operator = TerminalTokens.TokenNameXOR_EQUAL;
+				break;
+			case OperatorIds.REMAINDER :
+				operator = TerminalTokens.TokenNameREMAINDER_EQUAL;
+				break;
+			case OperatorIds.LEFT_SHIFT :
+				operator = TerminalTokens.TokenNameLEFT_SHIFT_EQUAL;
+				break;
+			case OperatorIds.RIGHT_SHIFT :
+				operator = TerminalTokens.TokenNameRIGHT_SHIFT_EQUAL;
+				break;
+			default: // OperatorIds.UNSIGNED_RIGHT_SHIFT :
+				operator = TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL;
+		}
+
+		this.scribe.printNextToken(operator, this.preferences.insert_space_before_assignment_operator);
+		if (this.preferences.insert_space_after_assignment_operator) {
+			this.scribe.space();
+		}
+		Alignment assignmentAlignment = this.scribe.createAlignment(
+				Alignment.COMPOUND_ASSIGNMENT,
+				this.preferences.alignment_for_assignment,
+				Alignment.R_OUTERMOST,
+				1,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(assignmentAlignment);
+		boolean ok = false;
+		do {
+			try {
+				this.scribe.alignFragment(assignmentAlignment, 0);
+				compoundAssignment.expression.traverse(this, scope);
+				ok = true;
+			} catch(AlignmentException e){
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(assignmentAlignment, true);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(compoundAssignment, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+     * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+     */
+    public boolean visit(
+    	ConditionalExpression conditionalExpression,
+    	BlockScope scope) {
+
+    	final int numberOfParens = (conditionalExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+    	if (numberOfParens > 0) {
+    		manageOpeningParenthesizedExpression(conditionalExpression, numberOfParens);
+    	}
+    	conditionalExpression.condition.traverse(this, scope);
+
+    	Alignment conditionalExpressionAlignment =this.scribe.createAlignment(
+    			Alignment.CONDITIONAL_EXPRESSION,
+    			this.preferences.alignment_for_conditional_expression,
+    			2,
+    			this.scribe.scanner.currentPosition);
+
+    	this.scribe.enterAlignment(conditionalExpressionAlignment);
+    	boolean ok = false;
+    	do {
+    		try {
+    			this.scribe.alignFragment(conditionalExpressionAlignment, 0);
+    			this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_conditional);
+
+    			if (this.preferences.insert_space_after_question_in_conditional) {
+    				this.scribe.space();
+    			}
+    			conditionalExpression.valueIfTrue.traverse(this, scope);
+    			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+    			this.scribe.alignFragment(conditionalExpressionAlignment, 1);
+    			this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_conditional);
+
+    			if (this.preferences.insert_space_after_colon_in_conditional) {
+    				this.scribe.space();
+    			}
+    			conditionalExpression.valueIfFalse.traverse(this, scope);
+
+    			ok = true;
+    		} catch (AlignmentException e) {
+    			this.scribe.redoAlignment(e);
+    		}
+    	} while (!ok);
+    	this.scribe.exitAlignment(conditionalExpressionAlignment, true);
+
+    	if (numberOfParens > 0) {
+    		manageClosingParenthesizedExpression(conditionalExpression, numberOfParens);
+    	}
+    	return false;
+    }
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		ConstructorDeclaration constructorDeclaration,
+		ClassScope scope) {
+
+		if (constructorDeclaration.ignoreFurtherInvestigation) {
+			this.scribe.printComment();
+			if (this.scribe.indentationLevel != 0) {
+				this.scribe.printIndentationIfNecessary();
+			}
+			this.scribe.scanner.resetTo(constructorDeclaration.declarationSourceEnd + 1, this.scribe.scannerEndPosition - 1);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			switch(this.scribe.scanner.source[this.scribe.scanner.currentPosition]) {
+				case '\n' :
+					this.scribe.scanner.currentPosition++;
+					this.scribe.lastNumberOfNewLines = 1;
+					break;
+				case '\r' :
+					this.scribe.scanner.currentPosition++;
+					if (this.scribe.scanner.source[this.scribe.scanner.currentPosition] == '\n') {
+						this.scribe.scanner.currentPosition++;
+					}
+					this.scribe.lastNumberOfNewLines = 1;
+			}
+			return false;
+		}
+        /*
+         * Print comments to get proper line number
+         */
+        this.scribe.printComment();
+        int line = this.scribe.line;
+		this.scribe.printModifiers(constructorDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD);
+		if (this.scribe.line > line) {
+        	// annotations introduced new line, but this is not a line wrapping
+			// see 158267
+			line = this.scribe.line;
+		}
+		this.scribe.space();
+
+		TypeParameter[] typeParameters = constructorDeclaration.typeParameters;
+		if (typeParameters != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters);
+			if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) {
+				this.scribe.space();
+			}
+			int length = typeParameters.length;
+			for (int i = 0; i < length - 1; i++) {
+				typeParameters[i].traverse(this, constructorDeclaration.scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters);
+				if (this.preferences.insert_space_after_comma_in_type_parameters) {
+					this.scribe.space();
+				}
+			}
+			typeParameters[length - 1].traverse(this, constructorDeclaration.scope);
+			if (isClosingGenericToken()) {
+				this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters);
+			}
+			if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) {
+				this.scribe.space();
+			}
+		}
+
+		/*
+		 * Print the method name
+		 */
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+
+		formatMethodArguments(
+			constructorDeclaration,
+			this.preferences.insert_space_before_opening_paren_in_constructor_declaration,
+			this.preferences.insert_space_between_empty_parens_in_constructor_declaration,
+			this.preferences.insert_space_before_closing_paren_in_constructor_declaration,
+			this.preferences.insert_space_after_opening_paren_in_constructor_declaration,
+			this.preferences.insert_space_before_comma_in_constructor_declaration_parameters,
+			this.preferences.insert_space_after_comma_in_constructor_declaration_parameters,
+			this.preferences.alignment_for_parameters_in_constructor_declaration);
+
+		formatThrowsClause(
+				constructorDeclaration,
+				this.preferences.insert_space_before_comma_in_constructor_declaration_throws,
+				this.preferences.insert_space_after_comma_in_constructor_declaration_throws,
+				this.preferences.alignment_for_throws_clause_in_constructor_declaration);
+
+		if (!constructorDeclaration.isNative() && !constructorDeclaration.isAbstract()) {
+			/*
+			 * Method body
+			 */
+			String constructor_declaration_brace = this.preferences.brace_position_for_constructor_declaration;
+			formatLeftCurlyBrace(line, constructor_declaration_brace);
+			formatOpeningBrace(constructor_declaration_brace, this.preferences.insert_space_before_opening_brace_in_constructor_declaration);
+			final int numberOfBlankLinesAtBeginningOfMethodBody = this.preferences.blank_lines_at_beginning_of_method_body;
+			if (numberOfBlankLinesAtBeginningOfMethodBody > 0) {
+				this.scribe.printEmptyLines(numberOfBlankLinesAtBeginningOfMethodBody);
+			}
+			if (constructorDeclaration.constructorCall != null && !constructorDeclaration.constructorCall.isImplicitSuper()) {
+				this.scribe.printNewLine();
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.indent();
+				}
+				constructorDeclaration.constructorCall.traverse(this, constructorDeclaration.scope);
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.unIndent();
+				}
+			}
+			final Statement[] statements = constructorDeclaration.statements;
+			if (statements != null) {
+				this.scribe.printNewLine();
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.indent();
+				}
+				formatStatements(constructorDeclaration.scope, statements, true);
+				this.scribe.printComment();
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.unIndent();
+				}
+			} else {
+				if (this.preferences.insert_new_line_in_empty_method_body) {
+					this.scribe.printNewLine();
+				}
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.indent();
+				}
+				this.scribe.printComment();
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.unIndent();
+				}
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			if (constructor_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+				this.scribe.unIndent();
+			}
+		} else {
+			// no method body
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ContinueStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ContinueStatement continueStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamecontinue);
+		if (continueStatement.label != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.DoStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(DoStatement doStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamedo);
+		final int line = this.scribe.line;
+
+		final Statement action = doStatement.action;
+		if (action != null) {
+			if (action instanceof Block) {
+				formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+				action.traverse(this, scope);
+			} else if (action instanceof EmptyStatement) {
+				/*
+				 * This is an empty statement
+				 */
+				formatNecessaryEmptyStatement();
+			} else {
+				this.scribe.printNewLine();
+				this.scribe.indent();
+				action.traverse(this, scope);
+				if (action instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+				this.scribe.printNewLine();
+				this.scribe.unIndent();
+			}
+		} else {
+			/*
+			 * This is an empty statement
+			 */
+			formatNecessaryEmptyStatement();
+		}
+
+		if (this.preferences.insert_new_line_before_while_in_do_statement) {
+			this.scribe.printNewLine();
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNamewhile, this.preferences.insert_space_after_closing_brace_in_block);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_while);
+
+		if (this.preferences.insert_space_after_opening_paren_in_while) {
+			this.scribe.space();
+		}
+
+		doStatement.condition.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_while);
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) {
+
+		final int numberOfParens = (doubleLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(doubleLiteral, numberOfParens);
+		}
+		if (isNextToken(TerminalTokens.TokenNameMINUS)) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameMINUS);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameDoubleLiteral);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(doubleLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.EmptyStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(EmptyStatement statement, BlockScope scope) {
+		if (this.preferences.put_empty_statement_on_new_line) {
+			this.scribe.printNewLine();
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+	// field is an enum constant
+	public boolean visit(FieldDeclaration enumConstant, MethodScope scope) {
+        /*
+         * Print comments to get proper line number
+         */
+        this.scribe.printComment();
+        final int line = this.scribe.line;
+        this.scribe.printModifiers(enumConstant.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_FIELD);
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false);
+		formatEnumConstantArguments(
+			enumConstant,
+			this.preferences.insert_space_before_opening_paren_in_enum_constant,
+			this.preferences.insert_space_between_empty_parens_in_enum_constant,
+			this.preferences.insert_space_before_closing_paren_in_enum_constant,
+			this.preferences.insert_space_after_opening_paren_in_enum_constant,
+			this.preferences.insert_space_before_comma_in_enum_constant_arguments,
+			this.preferences.insert_space_after_comma_in_enum_constant_arguments,
+			this.preferences.alignment_for_arguments_in_enum_constant);
+
+		Expression initialization = enumConstant.initialization;
+		if (initialization instanceof QualifiedAllocationExpression) {
+			TypeDeclaration typeDeclaration = ((QualifiedAllocationExpression) initialization).anonymousType;
+			int fieldsCount = typeDeclaration.fields == null ? 0 : typeDeclaration.fields.length;
+			int methodsCount = typeDeclaration.methods == null ? 0 : typeDeclaration.methods.length;
+			int membersCount = typeDeclaration.memberTypes == null ? 0 : typeDeclaration.memberTypes.length;
+
+			/*
+			 * Type body
+			 */
+			String enum_constant_brace = this.preferences.brace_position_for_enum_constant;
+
+			formatLeftCurlyBrace(line, enum_constant_brace);
+			formatTypeOpeningBraceForEnumConstant(enum_constant_brace, this.preferences.insert_space_before_opening_brace_in_enum_constant, typeDeclaration);
+
+			if (this.preferences.indent_body_declarations_compare_to_enum_constant_header) {
+				this.scribe.indent();
+			}
+
+			if (fieldsCount != 0 || methodsCount != 0 || membersCount != 0) {
+				formatTypeMembers(typeDeclaration);
+			}
+
+			if (this.preferences.indent_body_declarations_compare_to_enum_constant_header) {
+				this.scribe.unIndent();
+			}
+
+			if (this.preferences.insert_new_line_in_empty_enum_constant) {
+				this.scribe.printNewLine();
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			if (enum_constant_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+				this.scribe.unIndent();
+			}
+			if (hasComments()) {
+				this.scribe.printNewLine();
+			}
+		}
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.EqualExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(EqualExpression equalExpression, BlockScope scope) {
+
+		if ((equalExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.EQUAL_EQUAL) {
+			return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameEQUAL_EQUAL, scope);
+		} else {
+			return dumpEqualityExpression(equalExpression, TerminalTokens.TokenNameNOT_EQUAL, scope);
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		ExplicitConstructorCall explicitConstructor,
+		BlockScope scope) {
+
+		if (explicitConstructor.isImplicitSuper()) {
+			return false;
+		}
+		final Expression qualification = explicitConstructor.qualification;
+		if (qualification != null) {
+			qualification.traverse(this, scope);
+			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		}
+
+		TypeReference[] typeArguments = explicitConstructor.typeArguments;
+		if (typeArguments != null) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+				if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+				int length = typeArguments.length;
+				for (int i = 0; i < length - 1; i++) {
+					typeArguments[i].traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+					if (this.preferences.insert_space_after_comma_in_type_arguments) {
+						this.scribe.space();
+					}
+				}
+				typeArguments[length - 1].traverse(this, scope);
+				if (isClosingGenericToken()) {
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+				}
+				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+		}
+
+		if (explicitConstructor.isSuperAccess()) {
+			this.scribe.printNextToken(TerminalTokens.TokenNamesuper);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNamethis);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+
+		final Expression[] arguments = explicitConstructor.arguments;
+		if (arguments != null) {
+			if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+				this.scribe.space();
+			}
+			int argumentLength = arguments.length;
+			Alignment argumentsAlignment =this.scribe.createAlignment(
+					Alignment.EXPLICIT_CONSTRUCTOR_CALL,
+					this.preferences.alignment_for_arguments_in_explicit_constructor_call,
+					argumentLength,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				try {
+					for (int i = 0; i < argumentLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_explicit_constructor_call_arguments);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.alignFragment(argumentsAlignment, i);
+						if (i > 0 && this.preferences.insert_space_after_comma_in_explicit_constructor_call_arguments) {
+							this.scribe.space();
+						}
+						arguments[i].traverse(this, scope);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(argumentsAlignment, true);
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FalseLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(FalseLiteral falseLiteral, BlockScope scope) {
+
+		final int numberOfParens = (falseLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(falseLiteral, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNamefalse);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(falseLiteral, numberOfParens);
+		}
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FieldReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(FieldReference fieldReference, BlockScope scope) {
+
+		final int numberOfParens = (fieldReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(fieldReference, numberOfParens);
+		}
+		fieldReference.receiver.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(fieldReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.FloatLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(FloatLiteral floatLiteral, BlockScope scope) {
+
+		final int numberOfParens = (floatLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(floatLiteral, numberOfParens);
+		}
+		if (isNextToken(TerminalTokens.TokenNameMINUS)) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameMINUS);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameFloatingPointLiteral);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(floatLiteral, numberOfParens);
+		}
+		return false;
+	}
+	public boolean visit(ForeachStatement forStatement, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNamefor);
+	    final int line = this.scribe.line;
+	    this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_for);
+
+		if (this.preferences.insert_space_after_opening_paren_in_for) {
+			this.scribe.space();
+		}
+		formatLocalDeclaration(forStatement.elementVariable, scope, false, false);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_for);
+		if (this.preferences.insert_space_after_colon_in_for) {
+			this.scribe.space();
+		}
+		forStatement.collection.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_for);
+
+		final Statement action = forStatement.action;
+		if (action != null) {
+			if (action instanceof Block) {
+				formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+				action.traverse(this, scope);
+			} else if (action instanceof EmptyStatement) {
+				/*
+				 * This is an empty statement
+				 */
+				formatNecessaryEmptyStatement();
+			} else {
+				this.scribe.indent();
+				this.scribe.printNewLine();
+				action.traverse(this, scope);
+				this.scribe.unIndent();
+			}
+			if (action instanceof Expression) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			}
+		} else {
+			/*
+			 * This is an empty statement
+			 */
+			formatNecessaryEmptyStatement();
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ForStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ForStatement forStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamefor);
+	    final int line = this.scribe.line;
+	    this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_for);
+
+		if (this.preferences.insert_space_after_opening_paren_in_for) {
+			this.scribe.space();
+		}
+		final Statement[] initializations = forStatement.initializations;
+		if (initializations != null) {
+			int length = initializations.length;
+			for (int i = 0; i < length; i++) {
+				if (initializations[i] instanceof LocalDeclaration) {
+					formatLocalDeclaration((LocalDeclaration) initializations[i], scope, this.preferences.insert_space_before_comma_in_for_inits, this.preferences.insert_space_after_comma_in_for_inits);
+				} else {
+					initializations[i].traverse(this, scope);
+					if (i >= 0 && (i < length - 1)) {
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_for_inits);
+						if (this.preferences.insert_space_after_comma_in_for_inits) {
+							this.scribe.space();
+						}
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					}
+				}
+			}
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon_in_for);
+		final Expression condition = forStatement.condition;
+		if (condition != null) {
+			if (this.preferences.insert_space_after_semicolon_in_for) {
+				this.scribe.space();
+			}
+			condition.traverse(this, scope);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon_in_for);
+		final Statement[] increments = forStatement.increments;
+		if (increments != null) {
+			if (this.preferences.insert_space_after_semicolon_in_for) {
+				this.scribe.space();
+			}
+			for (int i = 0, length = increments.length; i < length; i++) {
+				increments[i].traverse(this, scope);
+				if (i != length - 1) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_for_increments);
+					if (this.preferences.insert_space_after_comma_in_for_increments) {
+						this.scribe.space();
+					}
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+			}
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_for);
+
+		final Statement action = forStatement.action;
+		if (action != null) {
+			if (action instanceof Block) {
+				formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+				action.traverse(this, scope);
+			} else if (action instanceof EmptyStatement) {
+				/*
+				 * This is an empty statement
+				 */
+				formatNecessaryEmptyStatement();
+			} else {
+				this.scribe.indent();
+				this.scribe.printNewLine();
+				action.traverse(this, scope);
+				this.scribe.unIndent();
+			}
+			if (action instanceof Expression) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			}
+		} else {
+			/*
+			 * This is an empty statement
+			 */
+			formatNecessaryEmptyStatement();
+		}
+		return false;
+	}
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IfStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(IfStatement ifStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameif);
+        final int line = this.scribe.line;
+        this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_if);
+		if (this.preferences.insert_space_after_opening_paren_in_if) {
+			this.scribe.space();
+		}
+		ifStatement.condition.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_if);
+
+		final Statement thenStatement = ifStatement.thenStatement;
+		final Statement elseStatement = ifStatement.elseStatement;
+
+		boolean thenStatementIsBlock = false;
+		if (thenStatement != null) {
+			if (thenStatement instanceof Block) {
+				thenStatementIsBlock = true;
+				if (isGuardClause((Block)thenStatement) && elseStatement == null && this.preferences.keep_guardian_clause_on_one_line) {
+					/*
+					 * Need a specific formatting for guard clauses
+					 * guard clauses are block with a single return or throw
+					 * statement
+					 */
+					 formatGuardClauseBlock((Block) thenStatement, scope);
+				} else {
+					formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+					thenStatement.traverse(this, scope);
+					if (elseStatement != null && (this.preferences.insert_new_line_before_else_in_if_statement)) {
+						this.scribe.printNewLine();
+					}
+				}
+			} else if (elseStatement == null && this.preferences.keep_simple_if_on_one_line) {
+				Alignment compactIfAlignment = this.scribe.createAlignment(
+						Alignment.COMPACT_IF,
+						this.preferences.alignment_for_compact_if,
+						Alignment.R_OUTERMOST,
+						1,
+						this.scribe.scanner.currentPosition,
+						1,
+						false);
+				this.scribe.enterAlignment(compactIfAlignment);
+				boolean ok = false;
+				do {
+					try {
+						this.scribe.alignFragment(compactIfAlignment, 0);
+						this.scribe.space();
+						thenStatement.traverse(this, scope);
+						if (thenStatement instanceof Expression) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						ok = true;
+					} catch (AlignmentException e) {
+						this.scribe.redoAlignment(e);
+					}
+				} while (!ok);
+				this.scribe.exitAlignment(compactIfAlignment, true);
+			} else if (this.preferences.keep_then_statement_on_same_line) {
+				this.scribe.space();
+				thenStatement.traverse(this, scope);
+				if (thenStatement instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+				if (elseStatement != null) {
+					this.scribe.printNewLine();
+				}
+			} else {
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				this.scribe.printNewLine();
+				this.scribe.indent();
+				thenStatement.traverse(this, scope);
+				if (thenStatement instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+				if (elseStatement != null) {
+					this.scribe.printNewLine();
+				}
+				this.scribe.unIndent();
+			}
+		}
+
+		if (elseStatement != null) {
+			if (thenStatementIsBlock) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameelse, this.preferences.insert_space_after_closing_brace_in_block, Scribe.PRESERVE_EMPTY_LINES_BEFORE_ELSE);
+			} else {
+				this.scribe.printNextToken(TerminalTokens.TokenNameelse, true, Scribe.PRESERVE_EMPTY_LINES_BEFORE_ELSE);
+			}
+			if (elseStatement instanceof Block) {
+				elseStatement.traverse(this, scope);
+			} else if (elseStatement instanceof IfStatement) {
+				if (!this.preferences.compact_else_if) {
+					this.scribe.printNewLine();
+					this.scribe.indent();
+				}
+				this.scribe.space();
+				elseStatement.traverse(this, scope);
+				if (!this.preferences.compact_else_if) {
+					this.scribe.unIndent();
+				}
+			} else if (this.preferences.keep_else_statement_on_same_line) {
+				this.scribe.space();
+				elseStatement.traverse(this, scope);
+				if (elseStatement instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+			} else {
+				this.scribe.printNewLine();
+				this.scribe.indent();
+				elseStatement.traverse(this, scope);
+				if (elseStatement instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+				this.scribe.unIndent();
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
+		int length = intersectionCastTypeReference.typeReferences == null ? 0 : intersectionCastTypeReference.typeReferences.length;
+		for (int i = 0; i < length; i++) {
+			intersectionCastTypeReference.typeReferences[i].traverse(this, scope);
+			if (i != length - 1) {
+				// Borrowing the formatting option from binary operators
+				this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_binary_operator);
+				if (this.preferences.insert_space_after_binary_operator) {
+					this.scribe.space();
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.Initializer, org.eclipse.jdt.internal.compiler.lookup.MethodScope)
+	 */
+	public boolean visit(Initializer initializer, MethodScope scope) {
+
+		if (initializer.isStatic()) {
+			this.scribe.printNextToken(TerminalTokens.TokenNamestatic);
+		}
+		initializer.block.traverse(this, scope);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		InstanceOfExpression instanceOfExpression,
+		BlockScope scope) {
+
+		final int numberOfParens = (instanceOfExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(instanceOfExpression, numberOfParens);
+		}
+		instanceOfExpression.expression.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameinstanceof, true);
+		this.scribe.space();
+		instanceOfExpression.type.traverse(this, scope);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(instanceOfExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.IntLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(IntLiteral intLiteral, BlockScope scope) {
+
+		final int numberOfParens = (intLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(intLiteral, numberOfParens);
+		}
+		if (isNextToken(TerminalTokens.TokenNameMINUS)) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameMINUS);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIntegerLiteral);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(intLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LabeledStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(LabeledStatement labeledStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+		this.scribe.printNextToken(TerminalTokens.TokenNameCOLON, this.preferences.insert_space_before_colon_in_labeled_statement);
+		if (this.preferences.insert_space_after_colon_in_labeled_statement) {
+			this.scribe.space();
+		}
+		if (this.preferences.insert_new_line_after_label) {
+			this.scribe.printNewLine();
+		}
+		final Statement statement = labeledStatement.statement;
+		statement.traverse(this, scope);
+		if (statement instanceof Expression) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LambdaExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(LambdaExpression lambdaExpression, BlockScope scope) {
+		
+		final int numberOfParens = (lambdaExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(lambdaExpression, numberOfParens);
+		}
+		if (isNextToken(TerminalTokens.TokenNameLPAREN)) {
+			// Format arguments
+			formatMethodArguments(
+				null,
+				lambdaExpression.arguments,
+				lambdaExpression.getScope(),
+				this.preferences.insert_space_before_opening_paren_in_method_declaration,
+				this.preferences.insert_space_between_empty_parens_in_method_declaration,
+				this.preferences.insert_space_before_closing_paren_in_method_declaration,
+				this.preferences.insert_space_after_opening_paren_in_method_declaration,
+				this.preferences.insert_space_before_comma_in_method_declaration_parameters,
+				this.preferences.insert_space_after_comma_in_method_declaration_parameters,
+				this.preferences.alignment_for_parameters_in_method_declaration);
+		} else {
+			// This MUST be a single, untyped parameter
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+		}
+		if (this.preferences.insert_space_before_lambda_arrow) this.scribe.space();
+		this.scribe.printNextToken(TerminalTokens.TokenNameARROW);
+		if (this.preferences.insert_space_after_lambda_arrow) this.scribe.space();
+		if (lambdaExpression.body instanceof Block) {
+			formatBlock((Block) lambdaExpression.body, scope, this.preferences.brace_position_for_lambda_body, this.preferences.insert_space_before_opening_brace_in_block);
+		} else {
+			lambdaExpression.body.traverse(this, scope);
+		}
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(lambdaExpression, numberOfParens);
+		}
+		return false;
+	}
+	
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
+		formatLocalDeclaration(localDeclaration, scope, this.preferences.insert_space_before_comma_in_multiple_local_declarations, this.preferences.insert_space_after_comma_in_multiple_local_declarations);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.LongLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(LongLiteral longLiteral, BlockScope scope) {
+
+		final int numberOfParens = (longLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(longLiteral, numberOfParens);
+		}
+		if (isNextToken(TerminalTokens.TokenNameMINUS)) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameMINUS);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameLongLiteral);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(longLiteral, numberOfParens);
+		}
+		return false;
+	}
+	public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameAT);
+		if (this.preferences.insert_space_after_at_in_annotation) {
+			this.scribe.space();
+		}
+		this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/);
+		return false;
+	}
+	public boolean visit(MarkerAnnotation annotation, ClassScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameAT);
+		if (this.preferences.insert_space_after_at_in_annotation) {
+			this.scribe.space();
+		}
+		this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/);
+		return false;
+	}
+	public boolean visit(MemberValuePair pair, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+		this.scribe.printNextToken(TerminalTokens.TokenNameEQUAL, this.preferences.insert_space_before_assignment_operator);
+		if (this.preferences.insert_space_after_assignment_operator) {
+			this.scribe.space();
+		}
+		pair.value.traverse(this, scope);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.MessageSend, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(MessageSend messageSend, BlockScope scope) {
+
+		final int numberOfParens = (messageSend.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(messageSend, numberOfParens);
+		}
+		CascadingMethodInvocationFragmentBuilder builder = buildFragments(messageSend, scope);
+
+		if (builder.size() >= 3 && numberOfParens == 0) {
+			formatCascadingMessageSends(builder, scope);
+		} else {
+			Alignment messageAlignment = null;
+			if (!messageSend.receiver.isImplicitThis()) {
+				messageSend.receiver.traverse(this, scope);
+				int alignmentMode = this.preferences.alignment_for_selector_in_method_invocation;
+				messageAlignment = this.scribe.createAlignment(
+						Alignment.MESSAGE_SEND,
+						alignmentMode,
+						1,
+						this.scribe.scanner.currentPosition);
+				this.scribe.enterAlignment(messageAlignment);
+				boolean ok = false;
+				do {
+					switch (alignmentMode & Alignment.SPLIT_MASK) {
+						case Alignment.M_COMPACT_SPLIT:
+						case Alignment.M_NEXT_PER_LINE_SPLIT:
+							messageAlignment.startingColumn = this.scribe.column;
+							break;
+					}
+					try {
+						formatMessageSend(messageSend, scope, messageAlignment);
+						ok = true;
+					} catch (AlignmentException e) {
+						this.scribe.redoAlignment(e);
+					}
+				} while (!ok);
+				this.scribe.exitAlignment(messageAlignment, true);
+			} else {
+				formatMessageSend(messageSend, scope, null);
+			}
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(messageSend, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		MethodDeclaration methodDeclaration,
+		ClassScope scope) {
+
+		if (methodDeclaration.ignoreFurtherInvestigation) {
+			this.scribe.printComment();
+			if (this.scribe.indentationLevel != 0) {
+				this.scribe.printIndentationIfNecessary();
+			}
+			this.scribe.scanner.resetTo(methodDeclaration.declarationSourceEnd + 1, this.scribe.scannerEndPosition - 1);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			if (!this.scribe.scanner.atEnd()) {
+				switch(this.scribe.scanner.source[this.scribe.scanner.currentPosition]) {
+					case '\n' :
+						this.scribe.scanner.currentPosition++;
+						this.scribe.lastNumberOfNewLines = 1;
+						break;
+					case '\r' :
+						this.scribe.scanner.currentPosition++;
+						if (this.scribe.scanner.source[this.scribe.scanner.currentPosition] == '\n') {
+							this.scribe.scanner.currentPosition++;
+						}
+						this.scribe.lastNumberOfNewLines = 1;
+				}
+			}
+			return false;
+		}
+
+		/*
+		 * Print comments to get proper line number
+		 */
+		this.scribe.printComment();
+		int line = this.scribe.line;
+
+		// Create alignment
+		Alignment methodDeclAlignment = this.scribe.createAlignment(
+				Alignment.METHOD_DECLARATION,
+				this.preferences.alignment_for_method_declaration,
+				Alignment.R_INNERMOST,
+				3,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(methodDeclAlignment);
+		boolean ok = false;
+		final MethodScope methodDeclarationScope = methodDeclaration.scope;
+		do {
+			try {
+
+				this.scribe.printModifiers(methodDeclaration.annotations, this, ICodeFormatterConstants.ANNOTATION_ON_METHOD);
+				int fragmentIndex = 0;
+				this.scribe.alignFragment(methodDeclAlignment, fragmentIndex);
+
+				if (this.scribe.line > line) {
+					// annotations introduced new line, but this is not a line wrapping
+					// see 158267
+					line = this.scribe.line;
+				}
+				this.scribe.space();
+
+				TypeParameter[] typeParameters = methodDeclaration.typeParameters;
+				if (typeParameters != null) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_parameters);
+					if (this.preferences.insert_space_after_opening_angle_bracket_in_type_parameters) {
+						this.scribe.space();
+					}
+					int length = typeParameters.length;
+					for (int i = 0; i < length - 1; i++) {
+						typeParameters[i].traverse(this, methodDeclaration.scope);
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_parameters);
+						if (this.preferences.insert_space_after_comma_in_type_parameters) {
+							this.scribe.space();
+						}
+					}
+					typeParameters[length - 1].traverse(this, methodDeclaration.scope);
+					if (isClosingGenericToken()) {
+						this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_parameters);
+					}
+					if (this.preferences.insert_space_after_closing_angle_bracket_in_type_parameters) {
+						this.scribe.space();
+					}
+					this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex);
+				}
+
+				/*
+				 * Print the method return type
+				 */
+				final TypeReference returnType = methodDeclaration.returnType;
+		
+				if (returnType != null) {
+					returnType.traverse(this, methodDeclarationScope);
+				}
+				this.scribe.alignFragment(methodDeclAlignment, ++fragmentIndex);
+
+				/*
+				 * Print the method name
+				 */
+				this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+
+				// Format arguments
+				formatMethodArguments(
+					methodDeclaration,
+					this.preferences.insert_space_before_opening_paren_in_method_declaration,
+					this.preferences.insert_space_between_empty_parens_in_method_declaration,
+					this.preferences.insert_space_before_closing_paren_in_method_declaration,
+					this.preferences.insert_space_after_opening_paren_in_method_declaration,
+					this.preferences.insert_space_before_comma_in_method_declaration_parameters,
+					this.preferences.insert_space_after_comma_in_method_declaration_parameters,
+					this.preferences.alignment_for_parameters_in_method_declaration);
+
+				formatExtraDimensions(methodDeclaration.returnType);
+
+				// Format throws
+				formatThrowsClause(
+					methodDeclaration,
+					this.preferences.insert_space_before_comma_in_method_declaration_throws,
+					this.preferences.insert_space_after_comma_in_method_declaration_throws,
+					this.preferences.alignment_for_throws_clause_in_method_declaration);
+				ok = true;
+			} catch (AlignmentException e) {
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(methodDeclAlignment, true);
+
+		if (!methodDeclaration.isNative() && !methodDeclaration.isAbstract() && ((methodDeclaration.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0)) {
+			/*
+			 * Method body
+			 */
+			String method_declaration_brace = this.preferences.brace_position_for_method_declaration;
+			formatLeftCurlyBrace(line, method_declaration_brace);
+			formatOpeningBrace(method_declaration_brace, this.preferences.insert_space_before_opening_brace_in_method_declaration);
+			final int numberOfBlankLinesAtBeginningOfMethodBody = this.preferences.blank_lines_at_beginning_of_method_body;
+			if (numberOfBlankLinesAtBeginningOfMethodBody > 0) {
+				this.scribe.printEmptyLines(numberOfBlankLinesAtBeginningOfMethodBody);
+			}
+			final Statement[] statements = methodDeclaration.statements;
+			if (statements != null) {
+				this.scribe.printNewLine();
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.indent();
+				}
+				formatStatements(methodDeclarationScope, statements, true);
+				this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION);
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.unIndent();
+				}
+			} else {
+				if (this.preferences.insert_new_line_in_empty_method_body) {
+					this.scribe.printNewLine();
+				}
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.indent();
+				}
+				this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION);
+				if (this.preferences.indent_statements_compare_to_body) {
+					this.scribe.unIndent();
+				}
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+			if (method_declaration_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+				this.scribe.unIndent();
+			}
+		} else {
+			// no method body
+			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+			this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.COMPLEX_TRAILING_COMMENT);
+		}
+		return false;
+	}
+
+	public boolean visit(NormalAnnotation annotation, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameAT);
+		if (this.preferences.insert_space_after_at_in_annotation) {
+			this.scribe.space();
+		}
+		this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation);
+		if (this.preferences.insert_space_after_opening_paren_in_annotation) {
+			this.scribe.space();
+		}
+		MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
+		if (memberValuePairs != null) {
+			int length = memberValuePairs.length;
+			Alignment annotationAlignment = this.scribe.createAlignment(
+					Alignment.ANNOTATION_MEMBERS_VALUE_PAIRS,
+					this.preferences.alignment_for_arguments_in_annotation,
+					length,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(annotationAlignment);
+			boolean ok = false;
+			do {
+				try {
+					for (int i = 0; i < length; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_annotation);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.alignFragment(annotationAlignment, i);
+						if (i > 0 && this.preferences.insert_space_after_comma_in_annotation) {
+							this.scribe.space();
+						}
+						memberValuePairs[i].traverse(this, scope);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(annotationAlignment, true);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_annotation);
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.NullLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
+
+		final int numberOfParens = (nullLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(nullLiteral, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNamenull);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(nullLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
+		return dumpBinaryExpression(or_or_Expression, TerminalTokens.TokenNameOR_OR, scope);
+	}
+	public boolean visit(
+			ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
+			BlockScope scope) {
+		final int numberOfParens = (parameterizedQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens);
+		}
+		TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
+		int length = typeArguments.length;
+		for (int i = 0; i < length; i++) {
+			if (parameterizedQualifiedTypeReference.annotations != null) {
+				formatInlineAnnotations(parameterizedQualifiedTypeReference.annotations[i], false);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+			TypeReference[] typeArgument = typeArguments[i];
+			if (typeArgument != null) {
+				int typeArgumentLength = typeArgument.length;
+				if (typeArgumentLength > 0) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+					if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) {
+						this.scribe.space();
+					}
+					for (int j = 0; j < typeArgumentLength - 1; j++) {
+						typeArgument[j].traverse(this, scope);
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference);
+						if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) {
+							this.scribe.space();
+						}
+					}
+					typeArgument[typeArgumentLength - 1].traverse(this, scope);
+					if (isClosingGenericToken()) {
+						this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
+					}
+				} else {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS);
+				}
+			}
+			if (i < length - 1) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+			}
+		}
+		formatLeadingDimensions(parameterizedQualifiedTypeReference, true);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens);
+		}
+		return false;
+	}
+	public boolean visit(
+			ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
+			ClassScope scope) {
+		final int numberOfParens = (parameterizedQualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens);
+		}
+		TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
+		int length = typeArguments.length;
+		for (int i = 0; i < length; i++) {
+			if (parameterizedQualifiedTypeReference.annotations != null) {
+				formatInlineAnnotations(parameterizedQualifiedTypeReference.annotations[i], false);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+			TypeReference[] typeArgument = typeArguments[i];
+			if (typeArgument != null) {
+				int typeArgumentLength = typeArgument.length;
+				if (typeArgumentLength > 0) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+					if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) {
+						this.scribe.space();
+					}
+					for (int j = 0; j < typeArgumentLength - 1; j++) {
+						typeArgument[j].traverse(this, scope);
+						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference);
+						if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) {
+							this.scribe.space();
+						}
+					}
+					typeArgument[typeArgumentLength - 1].traverse(this, scope);
+					if (isClosingGenericToken()) {
+						this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
+					}
+				} else {
+					this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS);
+				}
+			}
+			if (i < length - 1) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+			}
+		}
+		formatLeadingDimensions(parameterizedQualifiedTypeReference, true);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(parameterizedQualifiedTypeReference, numberOfParens);
+		}
+		return false;
+	}
+	public boolean visit(
+			ParameterizedSingleTypeReference parameterizedSingleTypeReference,
+			BlockScope scope) {
+		final int numberOfParens = (parameterizedSingleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens);
+		}
+		if (parameterizedSingleTypeReference.annotations != null) {
+			formatInlineAnnotations(parameterizedSingleTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+
+		TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
+		int typeArgumentsLength = typeArguments.length;
+		if (typeArgumentsLength > 0) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+			if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) {
+				this.scribe.space();
+			}
+			for (int i = 0; i < typeArgumentsLength - 1; i++) {
+				typeArguments[i].traverse(this, scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference);
+				if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) {
+					this.scribe.space();
+				}
+			}
+			typeArguments[typeArgumentsLength - 1].traverse(this, scope);
+			if (isClosingGenericToken()) {
+				this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
+			}
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+			this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS);
+		}
+		formatLeadingDimensions(parameterizedSingleTypeReference, true);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens);
+		}
+		return false;
+	}
+	public boolean visit(
+			ParameterizedSingleTypeReference parameterizedSingleTypeReference,
+			ClassScope scope) {
+		final int numberOfParens = (parameterizedSingleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens);
+		}
+		if (parameterizedSingleTypeReference.annotations != null) {
+			formatInlineAnnotations(parameterizedSingleTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+
+		TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
+		int typeArgumentsLength = typeArguments.length;
+		if (typeArgumentsLength > 0) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+			if (this.preferences.insert_space_after_opening_angle_bracket_in_parameterized_type_reference) {
+				this.scribe.space();
+			}
+			for (int i = 0; i < typeArgumentsLength - 1; i++) {
+				typeArguments[i].traverse(this, scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_parameterized_type_reference);
+				if (this.preferences.insert_space_after_comma_in_parameterized_type_reference) {
+					this.scribe.space();
+				}
+			}
+			typeArguments[typeArgumentsLength - 1].traverse(this, scope);
+			if (isClosingGenericToken()) {
+				this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
+			}
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_parameterized_type_reference);
+			this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS);
+		}
+
+		formatLeadingDimensions(parameterizedSingleTypeReference, true);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(parameterizedSingleTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.PostfixExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		PostfixExpression postfixExpression,
+		BlockScope scope) {
+
+		final int numberOfParens = (postfixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(postfixExpression, numberOfParens);
+		}
+		postfixExpression.lhs.traverse(this, scope);
+		int operator = postfixExpression.operator == OperatorIds.PLUS
+			? TerminalTokens.TokenNamePLUS_PLUS : TerminalTokens.TokenNameMINUS_MINUS;
+		this.scribe.printNextToken(operator, this.preferences.insert_space_before_postfix_operator);
+		if (this.preferences.insert_space_after_postfix_operator) {
+			this.scribe.space();
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(postfixExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.PrefixExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
+
+		final int numberOfParens = (prefixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(prefixExpression, numberOfParens);
+		}
+		int operator = prefixExpression.operator == OperatorIds.PLUS
+			? TerminalTokens.TokenNamePLUS_PLUS : TerminalTokens.TokenNameMINUS_MINUS;
+		this.scribe.printNextToken(operator, this.preferences.insert_space_before_prefix_operator);
+		if (this.preferences.insert_space_after_prefix_operator) {
+			this.scribe.space();
+		}
+		prefixExpression.lhs.traverse(this, scope);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(prefixExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		QualifiedAllocationExpression qualifiedAllocationExpression,
+		BlockScope scope) {
+
+		final int numberOfParens = (qualifiedAllocationExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(qualifiedAllocationExpression, numberOfParens);
+		}
+		final Expression enclosingInstance = qualifiedAllocationExpression.enclosingInstance;
+		if (enclosingInstance != null) {
+			enclosingInstance.traverse(this, scope);
+			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		}
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamenew);
+		// used for the new line on wrap style of formatting
+		TypeReference[] typeArguments = qualifiedAllocationExpression.typeArguments;
+		if (typeArguments != null) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+				if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+				int length = typeArguments.length;
+				for (int i = 0; i < length - 1; i++) {
+					typeArguments[i].traverse(this, scope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+					if (this.preferences.insert_space_after_comma_in_type_arguments) {
+						this.scribe.space();
+					}
+				}
+				typeArguments[length - 1].traverse(this, scope);
+				if (isClosingGenericToken()) {
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+				}
+				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+		} else {
+			this.scribe.space();
+		}
+
+		final int line = this.scribe.line;
+		qualifiedAllocationExpression.type.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
+
+		final Expression[] arguments = qualifiedAllocationExpression.arguments;
+		if (arguments != null) {
+			if (this.preferences.insert_space_after_opening_paren_in_method_invocation) {
+				this.scribe.space();
+			}
+			int argumentLength = arguments.length;
+			Alignment argumentsAlignment =this.scribe.createAlignment(
+					Alignment.ALLOCATION,
+					this.preferences.alignment_for_arguments_in_qualified_allocation_expression,
+					argumentLength,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				try {
+					for (int i = 0; i < argumentLength; i++) {
+						if (i > 0) {
+							this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_allocation_expression);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						}
+						this.scribe.alignFragment(argumentsAlignment, i);
+						if (i > 0 && this.preferences.insert_space_after_comma_in_allocation_expression) {
+							this.scribe.space();
+						}
+						arguments[i].traverse(this, scope);
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			this.scribe.exitAlignment(argumentsAlignment, true);
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_method_invocation);
+		} else {
+			this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_between_empty_parens_in_method_invocation);
+		}
+		final TypeDeclaration anonymousType = qualifiedAllocationExpression.anonymousType;
+		if (anonymousType != null) {
+			formatLeftCurlyBrace(line, this.preferences.brace_position_for_anonymous_type_declaration);
+			formatAnonymousTypeDeclaration(anonymousType);
+		}
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(qualifiedAllocationExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		QualifiedNameReference qualifiedNameReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (qualifiedNameReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(qualifiedNameReference, numberOfParens);
+		}
+		this.scribe.printQualifiedReference(qualifiedNameReference.sourceEnd, numberOfParens>=0/*expect parenthesis*/);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(qualifiedNameReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		QualifiedSuperReference qualifiedSuperReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (qualifiedSuperReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(qualifiedSuperReference, numberOfParens);
+		}
+		qualifiedSuperReference.qualification.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		this.scribe.printNextToken(TerminalTokens.TokenNamesuper);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(qualifiedSuperReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		QualifiedThisReference qualifiedThisReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (qualifiedThisReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(qualifiedThisReference, numberOfParens);
+		}
+		qualifiedThisReference.qualification.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+		this.scribe.printNextToken(TerminalTokens.TokenNamethis);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(qualifiedThisReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		QualifiedTypeReference qualifiedTypeReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (qualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(qualifiedTypeReference, numberOfParens);
+		}
+		formatQualifiedTypeReference(qualifiedTypeReference);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(qualifiedTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	private void formatQualifiedTypeReference(QualifiedTypeReference qualifiedTypeReference) {
+		for (int i = 0, length = qualifiedTypeReference.tokens.length; i < length; ++i) {
+			if (i != 0) this.scribe.printNextToken(TerminalTokens.TokenNameDOT, false);
+			if (qualifiedTypeReference.annotations != null) {
+				formatInlineAnnotations(qualifiedTypeReference.annotations[i], false);
+				this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true);
+			} else {
+				this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false);
+			}
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		QualifiedTypeReference qualifiedTypeReference,
+		ClassScope scope) {
+
+			final int numberOfParens = (qualifiedTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParens > 0) {
+				manageOpeningParenthesizedExpression(qualifiedTypeReference, numberOfParens);
+			}
+			formatQualifiedTypeReference(qualifiedTypeReference);
+
+			if (numberOfParens > 0) {
+				manageClosingParenthesizedExpression(qualifiedTypeReference, numberOfParens);
+			}
+			return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression, BlockScope blockScope) {
+		referenceExpression.lhs.traverse(this, blockScope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameCOLON_COLON);
+		
+		TypeReference[] typeArguments = referenceExpression.typeArguments;
+		if (typeArguments != null) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+				if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+				int length = typeArguments.length;
+				for (int i = 0; i < length - 1; i++) {
+					typeArguments[i].traverse(this, blockScope);
+					this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+					if (this.preferences.insert_space_after_comma_in_type_arguments) {
+						this.scribe.space();
+					}
+				}
+				typeArguments[length - 1].traverse(this, blockScope);
+				if (isClosingGenericToken()) {
+					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+				}
+				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+					this.scribe.space();
+				}
+		}
+
+		this.scribe.printNextToken(referenceExpression.isMethodReference() ? TerminalTokens.TokenNameIdentifier : TerminalTokens.TokenNamenew);
+		return false;
+	}
+	
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ReturnStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ReturnStatement returnStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamereturn);
+		final Expression expression = returnStatement.expression;
+		if (expression != null) {
+			final int numberOfParens = (expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if ((numberOfParens != 0 && this.preferences.insert_space_before_parenthesized_expression_in_return)
+					|| numberOfParens == 0) {
+				this.scribe.space();
+			}
+			expression.traverse(this, scope);
+		}
+		/*
+		 * Print the semi-colon
+		 */
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+	public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameAT);
+		if (this.preferences.insert_space_after_at_in_annotation) {
+			this.scribe.space();
+		}
+		this.scribe.printQualifiedReference(annotation.sourceEnd, false/*do not expect parenthesis*/);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_annotation);
+		if (this.preferences.insert_space_after_opening_paren_in_annotation) {
+			this.scribe.space();
+		}
+		annotation.memberValue.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_annotation);
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleNameReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(SingleNameReference singleNameReference, BlockScope scope) {
+
+		final int numberOfParens = (singleNameReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(singleNameReference, numberOfParens);
+		}
+		this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(singleNameReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		SingleTypeReference singleTypeReference,
+		BlockScope scope) {
+
+		final int numberOfParens = (singleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(singleTypeReference, numberOfParens);
+		}
+		if (singleTypeReference.annotations != null) {
+			formatInlineAnnotations(singleTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(singleTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	private boolean formatInlineAnnotations(final Annotation[] annotations, boolean spaceBefore) {
+		if (annotations != null ) {
+			if (spaceBefore) this.scribe.space();
+			int length = annotations.length;
+			for (int i = 0; i < length; ++i) {
+				if (i != 0) this.scribe.space();
+				annotations[i].traverse(this, (BlockScope)null);
+			}
+			if (length > 0 && !this.isNextTokenPunctuation()) {
+				this.scribe.space();
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SingleTypeReference, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(
+		SingleTypeReference singleTypeReference,
+		ClassScope scope) {
+
+		final int numberOfParens = (singleTypeReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(singleTypeReference, numberOfParens);
+		}
+		if (singleTypeReference.annotations != null) {
+			formatInlineAnnotations(singleTypeReference.annotations[0], false);
+		}
+		this.scribe.printNextToken(SINGLETYPEREFERENCE_EXPECTEDTOKENS);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(singleTypeReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.StringLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
+		final int numberOfParens = (stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(stringLiteral, numberOfParens);
+		}
+		this.scribe.checkNLSTag(stringLiteral.sourceStart);
+		this.scribe.printNextToken(TerminalTokens.TokenNameStringLiteral);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(stringLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.NullLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(StringLiteralConcatenation stringLiteral, BlockScope scope) {
+		final int numberOfParens = (stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(stringLiteral, numberOfParens);
+		}
+
+		this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_STRING_LITERAL_CONCATENATION);
+		ASTNode[] fragments = stringLiteral.literals;
+		int fragmentsSize = stringLiteral.counter;
+		Alignment binaryExpressionAlignment = this.scribe.createAlignment(
+				Alignment.STRING_CONCATENATION,
+				this.preferences.alignment_for_binary_expression,
+				Alignment.R_OUTERMOST,
+				fragmentsSize,
+				this.scribe.scanner.currentPosition);
+		this.scribe.enterAlignment(binaryExpressionAlignment);
+		boolean ok = false;
+		do {
+			try {
+				for (int i = 0; i < fragmentsSize - 1; i++) {
+					ASTNode fragment = fragments[i];
+					fragment.traverse(this, scope);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					if (this.scribe.lastNumberOfNewLines == 1) {
+						// a new line has been inserted by printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT)
+						this.scribe.indentationLevel = binaryExpressionAlignment.breakIndentationLevel;
+					}
+					this.scribe.alignFragment(binaryExpressionAlignment, i);
+					this.scribe.printNextToken(TerminalTokens.TokenNamePLUS, this.preferences.insert_space_before_binary_operator);
+					if (this.preferences.insert_space_after_binary_operator) {
+						this.scribe.space();
+					}
+				}
+				fragments[fragmentsSize - 1].traverse(this, scope);
+				this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				ok = true;
+			} catch(AlignmentException e){
+				this.scribe.redoAlignment(e);
+			}
+		} while (!ok);
+		this.scribe.exitAlignment(binaryExpressionAlignment, true);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(stringLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SuperReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(SuperReference superReference, BlockScope scope) {
+
+		final int numberOfParens = (superReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(superReference, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNamesuper);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(superReference, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SwitchStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(SwitchStatement switchStatement, BlockScope scope) {
+		this.scribe.printNextToken(TerminalTokens.TokenNameswitch);
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_switch);
+
+		if (this.preferences.insert_space_after_opening_paren_in_switch) {
+			this.scribe.space();
+		}
+		switchStatement.expression.traverse(this, scope);
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_switch);
+		/*
+		 * Type body
+		 */
+		String switch_brace = this.preferences.brace_position_for_switch;
+		formatOpeningBrace(switch_brace, this.preferences.insert_space_before_opening_brace_in_switch);
+		this.scribe.printNewLine();
+
+		final Statement[] statements = switchStatement.statements;
+		int switchIndentationLevel = this.scribe.indentationLevel;
+		int caseIndentation = 0;
+		int statementIndentation = 0;
+		int breakIndentation = 0;
+		if (this.preferences.indent_switchstatements_compare_to_switch) {
+			caseIndentation++;
+			statementIndentation++;
+			breakIndentation++;
+		}
+		if (this.preferences.indent_switchstatements_compare_to_cases) {
+			statementIndentation++;
+		}
+		if (this.preferences.indent_breaks_compare_to_cases) {
+			breakIndentation++;
+		}
+		boolean wasACase = false;
+		boolean wasABreak = false;
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++) {
+				final Statement statement = statements[i];
+				if (statement instanceof CaseStatement) {
+					if (wasABreak) {
+						this.scribe.setIndentation(switchIndentationLevel, caseIndentation);
+						this.scribe.printComment();
+					} else {
+						if (wasACase) {
+							this.scribe.printComment(Scribe.PRESERVE_EMPTY_LINES_IN_SWITCH_CASE);
+						} else {
+							this.scribe.printComment();
+						}
+						this.scribe.setIndentation(switchIndentationLevel, caseIndentation);
+					}
+					if (wasACase) {
+						this.scribe.printNewLine();
+					}
+					statement.traverse(this, scope);
+					// Print following trailing (if any) comment at statement indentation
+					this.scribe.setIndentation(switchIndentationLevel, statementIndentation);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.COMPLEX_TRAILING_COMMENT);
+					wasACase = true;
+					wasABreak = false;
+				} else if (statement instanceof BreakStatement) {
+					this.scribe.setIndentation(switchIndentationLevel, breakIndentation);
+					if (wasACase) {
+						this.scribe.printNewLine();
+					}
+					this.scribe.printComment();
+					statement.traverse(this, scope);
+					wasACase = false;
+					wasABreak = true;
+				} else if (statement instanceof Block) {
+					this.scribe.setIndentation(switchIndentationLevel, wasACase ? caseIndentation : statementIndentation);
+					this.scribe.printComment();
+					String bracePosition = wasACase ? this.preferences.brace_position_for_block_in_case : this.preferences.brace_position_for_block;
+					formatBlock((Block) statement, scope, bracePosition, this.preferences.insert_space_before_opening_brace_in_block);
+					wasACase = false;
+					wasABreak = false;
+				} else {
+					this.scribe.setIndentation(switchIndentationLevel, statementIndentation);
+					this.scribe.printNewLine();
+					this.scribe.printComment();
+					statement.traverse(this, scope);
+					wasACase = false;
+					wasABreak = false;
+				}
+				if (statement instanceof Expression) {
+					/*
+					 * Print the semi-colon
+					 */
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+					this.scribe.printNewLine();
+				} else if (statement instanceof LocalDeclaration) {
+					LocalDeclaration currentLocal = (LocalDeclaration) statement;
+					if (i < (statementsLength - 1)) {
+						/*
+						 * We need to check that the next statement is a local declaration
+						 */
+						if (statements[i + 1] instanceof LocalDeclaration) {
+							LocalDeclaration nextLocal = (LocalDeclaration) statements[i + 1];
+							if (currentLocal.declarationSourceStart != nextLocal.declarationSourceStart) {
+								/*
+								 * Print the semi-colon
+								 */
+								this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+								this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+								this.scribe.printNewLine();
+							}
+						} else {
+							/*
+							 * Print the semi-colon
+							 */
+							this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							this.scribe.printNewLine();
+						}
+					} else {
+						/*
+						 * Print the semi-colon
+						 */
+						this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+						this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+						this.scribe.printNewLine();
+					}
+				} else if (!wasACase) {
+					this.scribe.printNewLine();
+				}
+			}
+		}
+		this.scribe.printNewLine();
+		if (wasABreak) {
+			this.scribe.setIndentation(switchIndentationLevel, 0);
+			this.scribe.printComment();
+		} else {
+			this.scribe.printComment();
+			this.scribe.setIndentation(switchIndentationLevel, 0);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		if (switch_brace.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+			this.scribe.unIndent();
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		SynchronizedStatement synchronizedStatement,
+		BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamesynchronized);
+
+		final int line = this.scribe.line;
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_synchronized);
+
+		if (this.preferences.insert_space_after_opening_paren_in_synchronized) {
+			this.scribe.space();
+		}
+		synchronizedStatement.expression.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_synchronized);
+
+		formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+		synchronizedStatement.block.traverse(this, scope);
+		return false;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ThisReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ThisReference thisReference, BlockScope scope) {
+
+		if (!thisReference.isImplicitThis()) {
+			final int numberOfParens = (thisReference.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParens > 0) {
+				manageOpeningParenthesizedExpression(thisReference, numberOfParens);
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNamethis);
+
+			if (numberOfParens > 0) {
+				manageClosingParenthesizedExpression(thisReference, numberOfParens);
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.ThrowStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(ThrowStatement throwStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamethrow);
+		Expression expression = throwStatement.exception;
+		final int numberOfParens = (expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if ((numberOfParens > 0 && this.preferences.insert_space_before_parenthesized_expression_in_throw)
+				|| numberOfParens == 0) {
+			this.scribe.space();
+		}
+		expression.traverse(this, scope);
+		/*
+		 * Print the semi-colon
+		 */
+		this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+		this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TrueLiteral, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(TrueLiteral trueLiteral, BlockScope scope) {
+
+		final int numberOfParens = (trueLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(trueLiteral, numberOfParens);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNametrue);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(trueLiteral, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TryStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(TryStatement tryStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNametry);
+		formatTryResources(
+				tryStatement, 
+				this.preferences.insert_space_before_opening_paren_in_try, 
+				this.preferences.insert_space_before_closing_paren_in_try,
+				this.preferences.insert_space_after_opening_paren_in_try,
+				this.preferences.insert_space_before_semicolon_in_try_resources,
+				this.preferences.insert_space_after_semicolon_in_try_resources,
+				this.preferences.alignment_for_resources_in_try);
+		tryStatement.tryBlock.traverse(this, scope);
+		if (tryStatement.catchArguments != null) {
+			for (int i = 0, max = tryStatement.catchBlocks.length; i < max; i++) {
+				if (this.preferences.insert_new_line_before_catch_in_try_statement) {
+					this.scribe.printNewLine();
+				}
+				this.scribe.printNextToken(TerminalTokens.TokenNamecatch, this.preferences.insert_space_after_closing_brace_in_block);
+				final int line = this.scribe.line;
+				this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_catch);
+
+				if (this.preferences.insert_space_after_opening_paren_in_catch) {
+					this.scribe.space();
+				}
+				tryStatement.catchArguments[i].traverse(this, scope);
+
+				this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_catch);
+
+				formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+				tryStatement.catchBlocks[i].traverse(this, scope);
+			}
+		}
+		if (tryStatement.finallyBlock != null) {
+			if (this.preferences.insert_new_line_before_finally_in_try_statement) {
+				this.scribe.printNewLine();
+			}
+			this.scribe.printNextToken(TerminalTokens.TokenNamefinally, this.preferences.insert_space_after_closing_brace_in_block);
+			tryStatement.finallyBlock.traverse(this, scope);
+		}
+		return false;
+	}
+
+	private void formatMultiCatchArguments(Argument argument,
+			boolean spaceBeforePipe,
+			boolean spaceAfterPipe,
+			int multiCatchAlignment,
+			BlockScope scope) {
+		UnionTypeReference unionType = (UnionTypeReference) argument.type;
+		int length = unionType.typeReferences != null ? unionType.typeReferences.length : 0;
+		if (length > 0) {
+			Alignment argumentsAlignment = this.scribe.createAlignment(
+					Alignment.MULTI_CATCH,
+					multiCatchAlignment,
+					length,
+					this.scribe.scanner.currentPosition);
+			this.scribe.enterAlignment(argumentsAlignment);
+			boolean ok = false;
+			do {
+				switch (multiCatchAlignment & Alignment.SPLIT_MASK) {
+					case Alignment.M_COMPACT_SPLIT:
+					case Alignment.M_NEXT_PER_LINE_SPLIT:
+						argumentsAlignment.startingColumn = this.scribe.column;
+						break;
+				}
+				try {
+					for (int i = 0; i < length; i++) {
+						if (i > 0) {
+							if (this.preferences.wrap_before_or_operator_multicatch) {
+								this.scribe.alignFragment(argumentsAlignment, i);
+							}
+							this.scribe.printNextToken(TerminalTokens.TokenNameOR, spaceBeforePipe);
+							this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+							if (this.scribe.lastNumberOfNewLines == 1) {
+								// a new line has been inserted while printing the comment
+								// hence we need to use the break indentation level before printing next token...
+								this.scribe.indentationLevel = argumentsAlignment.breakIndentationLevel;
+							}
+							if (!this.preferences.wrap_before_or_operator_multicatch) {
+								this.scribe.alignFragment(argumentsAlignment, i);
+							}
+						}
+						if (i == 0) {
+							this.scribe.alignFragment(argumentsAlignment, i);
+							int fragmentIndentation = argumentsAlignment.fragmentIndentations[0];
+							if ((argumentsAlignment.mode & Alignment.M_INDENT_ON_COLUMN) != 0 && fragmentIndentation > 0) {
+								this.scribe.indentationLevel = fragmentIndentation;
+							}
+						} else if (spaceAfterPipe) {
+							this.scribe.space();
+						}
+						unionType.typeReferences[i].traverse(this, scope);
+						argumentsAlignment.startingColumn = -1;
+					}
+					ok = true;
+				} catch (AlignmentException e) {
+					this.scribe.redoAlignment(e);
+				}
+			} while (!ok);
+			
+			this.scribe.exitAlignment(argumentsAlignment, true);
+		}
+		
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		TypeDeclaration localTypeDeclaration,
+		BlockScope scope) {
+
+			format(localTypeDeclaration);
+			return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+		format(memberTypeDeclaration);
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration, org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope)
+	 */
+	public boolean visit(
+		TypeDeclaration typeDeclaration,
+		CompilationUnitScope scope) {
+
+		format(typeDeclaration);
+		return false;
+	}
+	public boolean visit(TypeParameter typeParameter, BlockScope scope) {
+		if (typeParameter.annotations != null) {
+			formatInlineAnnotations(typeParameter.annotations, false);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+		if (typeParameter.type != null) {
+			this.scribe.space();
+			this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+			this.scribe.space();
+			typeParameter.type.traverse(this, scope);
+		}
+		final TypeReference[] bounds = typeParameter.bounds;
+		if (bounds != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter);
+			if (this.preferences.insert_space_after_and_in_type_parameter) {
+				this.scribe.space();
+			}
+			int boundsLength = bounds.length;
+			for (int i = 0; i < boundsLength - 1; i++) {
+				bounds[i].traverse(this, scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter);
+				if (this.preferences.insert_space_after_and_in_type_parameter) {
+					this.scribe.space();
+				}
+			}
+			bounds[boundsLength - 1].traverse(this, scope);
+		}
+		return false;
+	}
+	public boolean visit(TypeParameter typeParameter, ClassScope scope) {
+		if (typeParameter.annotations != null) {
+			formatInlineAnnotations(typeParameter.annotations, false);
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
+		if (typeParameter.type != null) {
+			this.scribe.space();
+			this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+			this.scribe.space();
+			typeParameter.type.traverse(this, scope);
+		}
+		final TypeReference[] bounds = typeParameter.bounds;
+		if (bounds != null) {
+			this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter);
+			if (this.preferences.insert_space_after_and_in_type_parameter) {
+				this.scribe.space();
+			}
+			int boundsLength = bounds.length;
+			for (int i = 0; i < boundsLength - 1; i++) {
+				bounds[i].traverse(this, scope);
+				this.scribe.printNextToken(TerminalTokens.TokenNameAND, this.preferences.insert_space_before_and_in_type_parameter);
+				if (this.preferences.insert_space_after_and_in_type_parameter) {
+					this.scribe.space();
+				}
+			}
+			bounds[boundsLength - 1].traverse(this, scope);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnaryExpression, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
+
+		final int numberOfParens = (unaryExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+		if (numberOfParens > 0) {
+			manageOpeningParenthesizedExpression(unaryExpression, numberOfParens);
+		}
+
+		/*
+		 * Print the operator
+		 */
+		int operator;
+		int operatorValue = (unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+		switch(operatorValue) {
+			case OperatorIds.PLUS:
+				operator = TerminalTokens.TokenNamePLUS;
+				break;
+			case OperatorIds.MINUS:
+				operator = TerminalTokens.TokenNameMINUS;
+				break;
+			case OperatorIds.TWIDDLE:
+				operator = TerminalTokens.TokenNameTWIDDLE;
+				break;
+			default:
+				operator = TerminalTokens.TokenNameNOT;
+		}
+
+		this.scribe.printNextToken(operator, this.preferences.insert_space_before_unary_operator);
+		if (this.preferences.insert_space_after_unary_operator) {
+			this.scribe.space();
+		}
+		Expression expression = unaryExpression.expression;
+
+		if (expression instanceof PrefixExpression) {
+			PrefixExpression prefixExpression = (PrefixExpression) expression;
+			final int numberOfParensForExpression = (prefixExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParensForExpression == 0) {
+				switch(operatorValue) {
+					case OperatorIds.PLUS:
+						if (prefixExpression.operator == OperatorIds.PLUS) {
+							this.scribe.space();
+						}
+						break;
+					case OperatorIds.MINUS:
+						if (prefixExpression.operator == OperatorIds.MINUS) {
+							this.scribe.space();
+						}
+						break;
+				}
+			}
+		} else if (expression instanceof UnaryExpression) {
+			UnaryExpression unaryExpression2 = (UnaryExpression) expression;
+			final int numberOfParensForExpression = (unaryExpression2.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT;
+			if (numberOfParensForExpression == 0) {
+				int operatorValue2 = (unaryExpression2.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+				switch(operatorValue) {
+					case OperatorIds.PLUS:
+						if (operatorValue2 == OperatorIds.PLUS) {
+							this.scribe.space();
+						}
+						break;
+					case OperatorIds.MINUS:
+						if (operatorValue2 == OperatorIds.MINUS) {
+							this.scribe.space();
+						}
+						break;
+				}
+			}
+		}
+		expression.traverse(this, scope);
+
+		if (numberOfParens > 0) {
+			manageClosingParenthesizedExpression(unaryExpression, numberOfParens);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnionTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		UnionTypeReference unionTypeReference,
+		BlockScope scope) {
+
+		TypeReference[] typeReferences = unionTypeReference.typeReferences;
+		for (int i = 0, max = typeReferences.length; i < max; i++) {
+			if (i != 0) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameOR, true);
+				this.scribe.space();
+			}
+			typeReferences[i].traverse(this, scope);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.UnionTypeReference, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(
+		UnionTypeReference unionTypeReference,
+		ClassScope scope) {
+
+		TypeReference[] typeReferences = unionTypeReference.typeReferences;
+		for (int i = 0, max = typeReferences.length; i < max; i++) {
+			if (i != 0) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameOR, true);
+				this.scribe.space();
+			}
+			typeReferences[i].traverse(this, scope);
+		}
+		return false;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ASTVisitor#visit(org.eclipse.jdt.internal.compiler.ast.WhileStatement, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public boolean visit(WhileStatement whileStatement, BlockScope scope) {
+
+		this.scribe.printNextToken(TerminalTokens.TokenNamewhile);
+		final int line = this.scribe.line;
+		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_while);
+
+		if (this.preferences.insert_space_after_opening_paren_in_while) {
+			this.scribe.space();
+		}
+		whileStatement.condition.traverse(this, scope);
+
+		this.scribe.printNextToken(TerminalTokens.TokenNameRPAREN, this.preferences.insert_space_before_closing_paren_in_while);
+
+		final Statement action = whileStatement.action;
+		if (action != null) {
+			if (action instanceof Block) {
+				formatLeftCurlyBrace(line, this.preferences.brace_position_for_block);
+				action.traverse(this, scope);
+			} else if (action instanceof EmptyStatement) {
+				/*
+				 * This is an empty statement
+				 */
+				formatNecessaryEmptyStatement();
+			} else {
+				this.scribe.printNewLine();
+				this.scribe.indent();
+				action.traverse(this, scope);
+				if (action instanceof Expression) {
+					this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+					this.scribe.printComment(CodeFormatter.K_UNKNOWN, Scribe.BASIC_TRAILING_COMMENT);
+				}
+				this.scribe.unIndent();
+			}
+		} else {
+			/*
+			 * This is an empty statement
+			 */
+			formatNecessaryEmptyStatement();
+		}
+		return false;
+	}
+	public boolean visit(Wildcard wildcard, BlockScope scope) {
+		if (wildcard.annotations != null) {
+			if (formatInlineAnnotations(wildcard.annotations[0], false)) this.scribe.space();
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_wilcard);
+		switch(wildcard.kind) {
+			case Wildcard.SUPER :
+				this.scribe.printNextToken(TerminalTokens.TokenNamesuper, true);
+				this.scribe.space();
+				wildcard.bound.traverse(this, scope);
+				break;
+			case Wildcard.EXTENDS :
+				this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+				this.scribe.space();
+				wildcard.bound.traverse(this, scope);
+				break;
+			case Wildcard.UNBOUND :
+				if (this.preferences.insert_space_after_question_in_wilcard) {
+					this.scribe.space();
+				}
+		}
+		return false;
+	}
+	public boolean visit(Wildcard wildcard, ClassScope scope) {
+		if (wildcard.annotations != null) {
+			if (formatInlineAnnotations(wildcard.annotations[0], false)) this.scribe.space();
+		}
+		this.scribe.printNextToken(TerminalTokens.TokenNameQUESTION, this.preferences.insert_space_before_question_in_wilcard);
+		switch(wildcard.kind) {
+			case Wildcard.SUPER :
+				this.scribe.printNextToken(TerminalTokens.TokenNamesuper, true);
+				this.scribe.space();
+				wildcard.bound.traverse(this, scope);
+				break;
+			case Wildcard.EXTENDS :
+				this.scribe.printNextToken(TerminalTokens.TokenNameextends, true);
+				this.scribe.space();
+				wildcard.bound.traverse(this, scope);
+				break;
+			case Wildcard.UNBOUND :
+				if (this.preferences.insert_space_after_question_in_wilcard) {
+					this.scribe.space();
+				}
+		}
+		return false;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
new file mode 100644
index 0000000..69293d9
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -0,0 +1,501 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Jesper Steen Moller - Contributions for
+ *								bug 404146 - [1.7][compiler] nested try-catch-finally-blocks leads to unrunnable Java byte code
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.text.edits.TextEdit;
+
+public class DefaultCodeFormatter extends CodeFormatter {
+
+	/**
+	 * Debug trace
+	 */
+	public static boolean DEBUG = false;
+
+	// Mask for code formatter kinds
+	private static final int K_MASK = K_UNKNOWN
+		|  K_EXPRESSION
+		| K_STATEMENTS
+		| K_CLASS_BODY_DECLARATIONS
+		| K_COMPILATION_UNIT
+		| K_SINGLE_LINE_COMMENT
+		| K_MULTI_LINE_COMMENT
+		| K_JAVA_DOC;
+
+	// Scanner use to probe the kind of the source given to the formatter
+	private static Scanner PROBING_SCANNER;
+
+	private CodeSnippetParsingUtil codeSnippetParsingUtil;
+	private Map defaultCompilerOptions;
+
+	private CodeFormatterVisitor newCodeFormatter;
+	private Map options;
+
+	private DefaultCodeFormatterOptions preferences;
+
+	public DefaultCodeFormatter() {
+		this(new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings()), null);
+	}
+
+	public DefaultCodeFormatter(DefaultCodeFormatterOptions preferences) {
+		this(preferences, null);
+	}
+
+	public DefaultCodeFormatter(DefaultCodeFormatterOptions defaultCodeFormatterOptions, Map options) {
+		if (options != null) {
+			this.options = options;
+			this.preferences = new DefaultCodeFormatterOptions(options);
+		} else {
+			this.options = JavaCore.getOptions();
+			this.preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings());
+		}
+		this.defaultCompilerOptions = getDefaultCompilerOptions();
+		if (defaultCodeFormatterOptions != null) {
+			this.preferences.set(defaultCodeFormatterOptions.getMap());
+		}
+	}
+
+	public DefaultCodeFormatter(Map options) {
+		this(null, options);
+	}
+
+	public String createIndentationString(final int indentationLevel) {
+		if (indentationLevel < 0) {
+			throw new IllegalArgumentException();
+		}
+
+		int tabs = 0;
+		int spaces = 0;
+		switch(this.preferences.tab_char) {
+			case DefaultCodeFormatterOptions.SPACE :
+				spaces = indentationLevel * this.preferences.tab_size;
+				break;
+			case DefaultCodeFormatterOptions.TAB :
+				tabs = indentationLevel;
+				break;
+			case DefaultCodeFormatterOptions.MIXED :
+				int tabSize = this.preferences.tab_size;
+				if (tabSize != 0) {
+					int spaceEquivalents = indentationLevel * this.preferences.indentation_size;
+					tabs = spaceEquivalents / tabSize;
+					spaces = spaceEquivalents % tabSize;
+				}
+				break;
+			default:
+				return Util.EMPTY_STRING;
+		}
+		if (tabs == 0 && spaces == 0) {
+			return Util.EMPTY_STRING;
+		}
+		StringBuffer buffer = new StringBuffer(tabs + spaces);
+		for(int i = 0; i < tabs; i++) {
+			buffer.append('\t');
+		}
+		for(int i = 0; i < spaces; i++) {
+			buffer.append(' ');
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, java.lang.String, int, int, int, java.lang.String)
+	 */
+	public TextEdit format(int kind, String source, int offset, int length, int indentationLevel, String lineSeparator) {
+		if (offset < 0 || length < 0 || length > source.length()) {
+			throw new IllegalArgumentException();
+		}
+
+		switch(kind & K_MASK) {
+			case K_JAVA_DOC :
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102780
+				// use the integrated comment formatter to format comment
+                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
+				// $FALL-THROUGH$ - fall through next case when old comment formatter is activated
+			case K_MULTI_LINE_COMMENT :
+			case K_SINGLE_LINE_COMMENT :
+                return formatComment(kind & K_MASK, source, indentationLevel, lineSeparator, new IRegion[] {new Region(offset, length)});
+		}
+
+		return format(kind, source, new IRegion[] {new Region(offset, length)}, indentationLevel, lineSeparator);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) {
+		if (!regionsSatisfiesPreconditions(regions, source.length())) {
+			throw new IllegalArgumentException();
+		}
+
+		this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
+		boolean includeComments =  (kind & F_INCLUDE_COMMENTS) != 0;
+		switch(kind & K_MASK) {
+			case K_CLASS_BODY_DECLARATIONS :
+				return formatClassBodyDeclarations(source, indentationLevel, lineSeparator, regions, includeComments);
+			case K_COMPILATION_UNIT :
+				return formatCompilationUnit(source, indentationLevel, lineSeparator, regions, includeComments);
+			case K_EXPRESSION :
+				return formatExpression(source, indentationLevel, lineSeparator, regions, includeComments);
+			case K_STATEMENTS :
+				return formatStatements(source, indentationLevel, lineSeparator, regions, includeComments);
+			case K_UNKNOWN :
+				return probeFormatting(source, indentationLevel, lineSeparator, regions, includeComments);
+			case K_JAVA_DOC :
+			case K_MULTI_LINE_COMMENT :
+			case K_SINGLE_LINE_COMMENT :
+				//https://bugs.eclipse.org/bugs/show_bug.cgi?id=204091
+				throw new IllegalArgumentException();
+		}
+		return null;
+	}
+
+	private TextEdit formatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
+		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
+
+		if (bodyDeclarations == null) {
+			// a problem occurred while parsing the source
+			return null;
+		}
+		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions, includeComments);
+	}
+
+	/*
+	 * Format a javadoc comment.
+	 * Since bug 102780 this is done by a specific method when new javadoc formatter is activated.
+	 */
+	private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, IRegion[] regions) {
+		Object oldOption = oldCommentFormatOption();
+		boolean isFormattingComments = false;
+		if (oldOption == null) {
+			switch (kind & K_MASK) {
+				case K_SINGLE_LINE_COMMENT:
+					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT));
+					break;
+				case K_MULTI_LINE_COMMENT:
+					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT));
+					break;
+				case K_JAVA_DOC:
+					isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT));
+			}
+		} else {
+			isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(oldOption);
+		}
+		if (isFormattingComments) {
+			if (lineSeparator != null) {
+				this.preferences.line_separator = lineSeparator;
+			} else {
+				this.preferences.line_separator = Util.LINE_SEPARATOR;
+			}
+			this.preferences.initial_indentation_level = indentationLevel;
+			if (this.codeSnippetParsingUtil == null) this.codeSnippetParsingUtil = new CodeSnippetParsingUtil();
+			this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
+			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, true);
+			IRegion coveredRegion = getCoveredRegion(regions);
+			int start = coveredRegion.getOffset();
+			int end = start + coveredRegion.getLength();
+			this.newCodeFormatter.formatComment(kind, source, start, end, indentationLevel);
+			return this.newCodeFormatter.scribe.getRootEdit();
+		}
+		return null;
+	}
+
+	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
+		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
+
+		if (lineSeparator != null) {
+			this.preferences.line_separator = lineSeparator;
+		} else {
+			this.preferences.line_separator = Util.LINE_SEPARATOR;
+		}
+		this.preferences.initial_indentation_level = indentationLevel;
+
+		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
+
+		return this.newCodeFormatter.format(source, compilationUnitDeclaration);
+	}
+
+	private TextEdit formatExpression(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
+		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
+
+		if (expression == null) {
+			// a problem occurred while parsing the source
+			return null;
+		}
+		return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions, includeComments);
+	}
+
+	private TextEdit formatStatements(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
+		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
+
+		if (constructorDeclaration.statements == null) {
+			// a problem occured while parsing the source
+			return null;
+		}
+		return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions, includeComments);
+	}
+
+	private IRegion getCoveredRegion(IRegion[] regions) {
+		int length = regions.length;
+		if (length == 1) {
+			return regions[0];
+		}
+
+		int offset = regions[0].getOffset();
+		IRegion lastRegion = regions[length - 1];
+
+		return new Region(offset, lastRegion.getOffset() + lastRegion.getLength() - offset);
+	}
+
+	public String getDebugOutput() {
+		return this.newCodeFormatter.scribe.toString();
+	}
+
+	private Map getDefaultCompilerOptions() {
+		if (this.defaultCompilerOptions ==  null) {
+			Map optionsMap = new HashMap(30);
+			optionsMap.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
+			optionsMap.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
+			optionsMap.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE);
+			optionsMap.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
+			optionsMap.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMethodWithConstructorName, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportHiddenCatchBlock, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedObjectAllocation, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportNoEffectAssignment, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportNoImplicitStringConversion, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportIndirectStaticAccess, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportEmptyStatement, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportAssertIdentifier, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportEnumIdentifier, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadoc, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, CompilerOptions.PUBLIC);
+			optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTags, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagDescription, CompilerOptions.RETURN_TAG);
+			optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTags, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, CompilerOptions.PUBLIC);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocComments, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+			optionsMap.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+			optionsMap.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
+			optionsMap.put(CompilerOptions.OPTION_TaskPriorities, Util.EMPTY_STRING);
+			optionsMap.put(CompilerOptions.OPTION_TaskCaseSensitive, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnavoidableGenericTypeProblems, CompilerOptions.ENABLED);
+			optionsMap.put(CompilerOptions.OPTION_MaxProblemPerUnit, String.valueOf(100));
+			optionsMap.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ShareCommonFinallyBlocks, CompilerOptions.DISABLED);
+			optionsMap.put(CompilerOptions.OPTION_ReportMethodCanBeStatic, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, CompilerOptions.IGNORE);
+			optionsMap.put(CompilerOptions.OPTION_ReportUnusedTypeParameter, CompilerOptions.IGNORE);
+			this.defaultCompilerOptions = optionsMap;
+		}
+		Object sourceOption = this.options.get(CompilerOptions.OPTION_Source);
+		if (sourceOption != null) {
+			this.defaultCompilerOptions.put(CompilerOptions.OPTION_Source, sourceOption);
+		} else {
+			this.defaultCompilerOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+		}
+		return this.defaultCompilerOptions;
+	}
+
+	private TextEdit internalFormatClassBodyDeclarations(String source, int indentationLevel, String lineSeparator, ASTNode[] bodyDeclarations, IRegion[] regions, boolean includeComments) {
+		if (lineSeparator != null) {
+			this.preferences.line_separator = lineSeparator;
+		} else {
+			this.preferences.line_separator = Util.LINE_SEPARATOR;
+		}
+		this.preferences.initial_indentation_level = indentationLevel;
+
+		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
+		return this.newCodeFormatter.format(source, bodyDeclarations);
+	}
+
+	private TextEdit internalFormatExpression(String source, int indentationLevel, String lineSeparator, Expression expression, IRegion[] regions, boolean includeComments) {
+		if (lineSeparator != null) {
+			this.preferences.line_separator = lineSeparator;
+		} else {
+			this.preferences.line_separator = Util.LINE_SEPARATOR;
+		}
+		this.preferences.initial_indentation_level = indentationLevel;
+
+		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
+
+		TextEdit textEdit = this.newCodeFormatter.format(source, expression);
+		return textEdit;
+	}
+
+	private TextEdit internalFormatStatements(String source, int indentationLevel, String lineSeparator, ConstructorDeclaration constructorDeclaration, IRegion[] regions, boolean includeComments) {
+		if (lineSeparator != null) {
+			this.preferences.line_separator = lineSeparator;
+		} else {
+			this.preferences.line_separator = Util.LINE_SEPARATOR;
+		}
+		this.preferences.initial_indentation_level = indentationLevel;
+
+		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, regions, this.codeSnippetParsingUtil, includeComments);
+
+		return this.newCodeFormatter.format(source, constructorDeclaration);
+	}
+
+	/**
+	 * Deprecated as using old option constant
+	 * @deprecated
+	 */
+	private Object oldCommentFormatOption() {
+	    return this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT);
+    }
+
+	private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
+		if (PROBING_SCANNER == null) {
+			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT
+			// do not tokenize white spaces to get single comments even with spaces before...
+			PROBING_SCANNER = new Scanner(true, false/*do not tokenize whitespaces*/, false/*nls*/, ClassFileConstants.JDK1_6, ClassFileConstants.JDK1_6, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+		}
+		PROBING_SCANNER.setSource(source.toCharArray());
+
+		IRegion coveredRegion = getCoveredRegion(regions);
+		int offset = coveredRegion.getOffset();
+		int length = coveredRegion.getLength();
+
+		PROBING_SCANNER.resetTo(offset, offset + length - 1);
+		try {
+			int kind = -1;
+			switch(PROBING_SCANNER.getNextToken()) {
+				case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
+					if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) {
+						kind = K_MULTI_LINE_COMMENT;
+					}
+					break;
+				case ITerminalSymbols.TokenNameCOMMENT_LINE :
+					if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) {
+						kind = K_SINGLE_LINE_COMMENT;
+					}
+					break;
+				case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
+					if (PROBING_SCANNER.getNextToken() == TerminalTokens.TokenNameEOF) {
+						kind = K_JAVA_DOC;
+					}
+					break;
+			}
+			if (kind != -1) {
+				return formatComment(kind, source, indentationLevel, lineSeparator, regions);
+			}
+		} catch (InvalidInputException e) {
+			// ignore
+		}
+		PROBING_SCANNER.setSource((char[]) null);
+
+		// probe for expression
+		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
+		if (expression != null) {
+			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, regions, includeComments);
+		}
+
+		// probe for body declarations (fields, methods, constructors)
+		ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
+		if (bodyDeclarations != null) {
+			return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, regions, includeComments);
+		}
+
+		// probe for statements
+		ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true, false);
+		if (constructorDeclaration.statements != null) {
+			return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, regions, includeComments);
+		}
+
+		// this has to be a compilation unit
+		return formatCompilationUnit(source, indentationLevel, lineSeparator, regions, includeComments);
+	}
+
+	/**
+	 * True if
+	 * 1. All regions are within maxLength
+	 * 2. regions are sorted
+	 * 3. regions are not overlapping
+	 */
+	private boolean regionsSatisfiesPreconditions(IRegion[] regions, int maxLength) {
+		int regionsLength = regions == null ? 0 : regions.length;
+		if (regionsLength == 0) {
+			return false;
+		}
+
+		IRegion first = regions[0];
+		if (first.getOffset() < 0 || first.getLength() < 0 || first.getOffset() + first.getLength() > maxLength) {
+			return false;
+		}
+
+		int lastOffset = first.getOffset() + first.getLength() - 1;
+		for (int i= 1; i < regionsLength; i++) {
+			IRegion current = regions[i];
+			if (lastOffset > current.getOffset()) {
+				return false;
+			}
+
+			if (current.getOffset() < 0 || current.getLength() < 0 || current.getOffset() + current.getLength() > maxLength) {
+				return false;
+			}
+
+			lastOffset = current.getOffset() + current.getLength() - 1;
+		}
+
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
new file mode 100644
index 0000000..95be5f3
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -0,0 +1,2773 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Brock Janiczak - Contribution for bug 150741
+ *     Ray V. (voidstar@gmail.com) - Contribution for bug 282988
+ *     Jesper S Moller - Contribution for bug 402173
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.formatter.align.Alignment;
+
+/**
+ * This is still subject to changes before 3.0.
+ * @since 3.0
+ */
+
+public class DefaultCodeFormatterOptions {
+	public static final int TAB = 1;
+	public static final int SPACE = 2;
+	public static final int MIXED = 4;
+
+	public static DefaultCodeFormatterOptions getDefaultSettings() {
+		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
+		options.setDefaultSettings();
+		return options;
+	}
+
+	public static DefaultCodeFormatterOptions getEclipseDefaultSettings() {
+		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
+		options.setEclipseDefaultSettings();
+		return options;
+	}
+
+	public static DefaultCodeFormatterOptions getJavaConventionsSettings() {
+		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
+		options.setJavaConventionsSettings();
+		return options;
+	}
+
+	public int alignment_for_arguments_in_allocation_expression;
+	public int alignment_for_arguments_in_annotation;
+	public int alignment_for_arguments_in_enum_constant;
+	public int alignment_for_arguments_in_explicit_constructor_call;
+	public int alignment_for_arguments_in_method_invocation;
+	public int alignment_for_arguments_in_qualified_allocation_expression;
+	public int alignment_for_assignment;
+	public int alignment_for_binary_expression;
+	public int alignment_for_compact_if;
+	public int alignment_for_conditional_expression;
+	public int alignment_for_enum_constants;
+	public int alignment_for_expressions_in_array_initializer;
+	public int alignment_for_method_declaration;
+	public int alignment_for_multiple_fields;
+	public int alignment_for_parameters_in_constructor_declaration;
+	public int alignment_for_parameters_in_method_declaration;
+	public int alignment_for_selector_in_method_invocation;
+	public int alignment_for_superclass_in_type_declaration;
+	public int alignment_for_superinterfaces_in_enum_declaration;
+	public int alignment_for_superinterfaces_in_type_declaration;
+	public int alignment_for_throws_clause_in_constructor_declaration;
+	public int alignment_for_throws_clause_in_method_declaration;
+	public int alignment_for_resources_in_try;
+	public int alignment_for_union_type_in_multicatch;
+
+	public boolean align_type_members_on_columns;
+
+	public String brace_position_for_annotation_type_declaration;
+	public String brace_position_for_anonymous_type_declaration;
+	public String brace_position_for_array_initializer;
+	public String brace_position_for_block;
+	public String brace_position_for_block_in_case;
+	public String brace_position_for_constructor_declaration;
+	public String brace_position_for_enum_constant;
+	public String brace_position_for_enum_declaration;
+	public String brace_position_for_lambda_body;
+	public String brace_position_for_method_declaration;
+	public String brace_position_for_type_declaration;
+	public String brace_position_for_switch;
+
+	public int continuation_indentation;
+	public int continuation_indentation_for_array_initializer;
+
+	public int blank_lines_after_imports;
+	public int blank_lines_after_package;
+	public int blank_lines_before_field;
+	public int blank_lines_before_first_class_body_declaration;
+	public int blank_lines_before_imports;
+	public int blank_lines_before_member_type;
+	public int blank_lines_before_method;
+	public int blank_lines_before_new_chunk;
+	public int blank_lines_before_package;
+	public int blank_lines_between_import_groups;
+	public int blank_lines_between_type_declarations;
+	public int blank_lines_at_beginning_of_method_body;
+
+	public boolean comment_clear_blank_lines_in_javadoc_comment;
+	public boolean comment_clear_blank_lines_in_block_comment;
+	public boolean comment_new_lines_at_block_boundaries;
+	public boolean comment_new_lines_at_javadoc_boundaries;
+	public boolean comment_format_javadoc_comment;
+	public boolean comment_format_line_comment;
+	public boolean comment_format_line_comment_starting_on_first_column;
+	public boolean comment_format_block_comment;
+	public boolean comment_format_header;
+	public boolean comment_format_html;
+	public boolean comment_format_source;
+	public boolean comment_indent_parameter_description;
+	public boolean comment_indent_root_tags;
+	public boolean comment_insert_empty_line_before_root_tags;
+	public boolean comment_insert_new_line_for_parameter;
+	public boolean comment_preserve_white_space_between_code_and_line_comments;
+	public int comment_line_length;
+
+	public boolean use_tags;
+	public char[] disabling_tag;
+	public char[] enabling_tag;
+	private final static char[] DEFAULT_DISABLING_TAG = "@formatter:off".toCharArray(); //$NON-NLS-1$
+	private final static char[] DEFAULT_ENABLING_TAG = "@formatter:on".toCharArray(); //$NON-NLS-1$
+
+	public boolean indent_statements_compare_to_block;
+	public boolean indent_statements_compare_to_body;
+	public boolean indent_body_declarations_compare_to_annotation_declaration_header;
+	public boolean indent_body_declarations_compare_to_enum_constant_header;
+	public boolean indent_body_declarations_compare_to_enum_declaration_header;
+	public boolean indent_body_declarations_compare_to_type_header;
+	public boolean indent_breaks_compare_to_cases;
+	public boolean indent_empty_lines;
+	public boolean indent_switchstatements_compare_to_cases;
+	public boolean indent_switchstatements_compare_to_switch;
+	public int indentation_size;
+
+	public boolean insert_new_line_after_annotation_on_type;
+	public boolean insert_new_line_after_annotation_on_field;
+	public boolean insert_new_line_after_annotation_on_method;
+	public boolean insert_new_line_after_annotation_on_package;
+	public boolean insert_new_line_after_annotation_on_parameter;
+	public boolean insert_new_line_after_annotation_on_local_variable;
+	public boolean insert_new_line_after_label;
+	public boolean insert_new_line_after_opening_brace_in_array_initializer;
+	public boolean insert_new_line_at_end_of_file_if_missing;
+	public boolean insert_new_line_before_catch_in_try_statement;
+	public boolean insert_new_line_before_closing_brace_in_array_initializer;
+	public boolean insert_new_line_before_else_in_if_statement;
+	public boolean insert_new_line_before_finally_in_try_statement;
+	public boolean insert_new_line_before_while_in_do_statement;
+	public boolean insert_new_line_in_empty_anonymous_type_declaration;
+	public boolean insert_new_line_in_empty_block;
+	public boolean insert_new_line_in_empty_annotation_declaration;
+	public boolean insert_new_line_in_empty_enum_constant;
+	public boolean insert_new_line_in_empty_enum_declaration;
+	public boolean insert_new_line_in_empty_method_body;
+	public boolean insert_new_line_in_empty_type_declaration;
+	public boolean insert_space_after_and_in_type_parameter;
+	public boolean insert_space_after_assignment_operator;
+	public boolean insert_space_after_at_in_annotation;
+	public boolean insert_space_after_at_in_annotation_type_declaration;
+	public boolean insert_space_after_binary_operator;
+	public boolean insert_space_after_closing_angle_bracket_in_type_arguments;
+	public boolean insert_space_after_closing_angle_bracket_in_type_parameters;
+	public boolean insert_space_after_closing_paren_in_cast;
+	public boolean insert_space_after_closing_brace_in_block;
+	public boolean insert_space_after_colon_in_assert;
+	public boolean insert_space_after_colon_in_case;
+	public boolean insert_space_after_colon_in_conditional;
+	public boolean insert_space_after_colon_in_for;
+	public boolean insert_space_after_colon_in_labeled_statement;
+	public boolean insert_space_after_comma_in_allocation_expression;
+	public boolean insert_space_after_comma_in_annotation;
+	public boolean insert_space_after_comma_in_array_initializer;
+	public boolean insert_space_after_comma_in_constructor_declaration_parameters;
+	public boolean insert_space_after_comma_in_constructor_declaration_throws;
+	public boolean insert_space_after_comma_in_enum_constant_arguments;
+	public boolean insert_space_after_comma_in_enum_declarations;
+	public boolean insert_space_after_comma_in_explicit_constructor_call_arguments;
+	public boolean insert_space_after_comma_in_for_increments;
+	public boolean insert_space_after_comma_in_for_inits;
+	public boolean insert_space_after_comma_in_method_invocation_arguments;
+	public boolean insert_space_after_comma_in_method_declaration_parameters;
+	public boolean insert_space_after_comma_in_method_declaration_throws;
+	public boolean insert_space_after_comma_in_multiple_field_declarations;
+	public boolean insert_space_after_comma_in_multiple_local_declarations;
+	public boolean insert_space_after_comma_in_parameterized_type_reference;
+	public boolean insert_space_after_comma_in_superinterfaces;
+	public boolean insert_space_after_comma_in_type_arguments;
+	public boolean insert_space_after_comma_in_type_parameters;
+	public boolean insert_space_after_ellipsis;
+	public boolean insert_space_after_lambda_arrow;
+	public boolean insert_space_after_opening_angle_bracket_in_parameterized_type_reference;
+	public boolean insert_space_after_opening_angle_bracket_in_type_arguments;
+	public boolean insert_space_after_opening_angle_bracket_in_type_parameters;
+	public boolean insert_space_after_opening_bracket_in_array_allocation_expression;
+	public boolean insert_space_after_opening_bracket_in_array_reference;
+	public boolean insert_space_after_opening_brace_in_array_initializer;
+	public boolean insert_space_after_opening_paren_in_annotation;
+	public boolean insert_space_after_opening_paren_in_cast;
+	public boolean insert_space_after_opening_paren_in_catch;
+	public boolean insert_space_after_opening_paren_in_constructor_declaration;
+	public boolean insert_space_after_opening_paren_in_enum_constant;
+	public boolean insert_space_after_opening_paren_in_for;
+	public boolean insert_space_after_opening_paren_in_if;
+	public boolean insert_space_after_opening_paren_in_method_declaration;
+	public boolean insert_space_after_opening_paren_in_method_invocation;
+	public boolean insert_space_after_opening_paren_in_parenthesized_expression;
+	public boolean insert_space_after_opening_paren_in_switch;
+	public boolean insert_space_after_opening_paren_in_synchronized;
+	public boolean insert_space_after_opening_paren_in_try;
+	public boolean insert_space_after_opening_paren_in_while;
+	public boolean insert_space_after_postfix_operator;
+	public boolean insert_space_after_prefix_operator;
+	public boolean insert_space_after_question_in_conditional;
+	public boolean insert_space_after_question_in_wilcard;
+	public boolean insert_space_after_semicolon_in_for;
+	public boolean insert_space_after_semicolon_in_try_resources;
+	public boolean insert_space_after_unary_operator;
+	public boolean insert_space_before_and_in_type_parameter;
+	public boolean insert_space_before_at_in_annotation_type_declaration;
+	public boolean insert_space_before_assignment_operator;
+	public boolean insert_space_before_binary_operator;
+	public boolean insert_space_before_closing_angle_bracket_in_parameterized_type_reference;
+	public boolean insert_space_before_closing_angle_bracket_in_type_arguments;
+	public boolean insert_space_before_closing_angle_bracket_in_type_parameters;
+	public boolean insert_space_before_closing_brace_in_array_initializer;
+	public boolean insert_space_before_closing_bracket_in_array_allocation_expression;
+	public boolean insert_space_before_closing_bracket_in_array_reference;
+	public boolean insert_space_before_closing_paren_in_annotation;
+	public boolean insert_space_before_closing_paren_in_cast;
+	public boolean insert_space_before_closing_paren_in_catch;
+	public boolean insert_space_before_closing_paren_in_constructor_declaration;
+	public boolean insert_space_before_closing_paren_in_enum_constant;
+	public boolean insert_space_before_closing_paren_in_for;
+	public boolean insert_space_before_closing_paren_in_if;
+	public boolean insert_space_before_closing_paren_in_method_declaration;
+	public boolean insert_space_before_closing_paren_in_method_invocation;
+	public boolean insert_space_before_closing_paren_in_parenthesized_expression;
+	public boolean insert_space_before_closing_paren_in_switch;
+	public boolean insert_space_before_closing_paren_in_synchronized;
+	public boolean insert_space_before_closing_paren_in_try;
+	public boolean insert_space_before_closing_paren_in_while;
+	public boolean insert_space_before_colon_in_assert;
+	public boolean insert_space_before_colon_in_case;
+	public boolean insert_space_before_colon_in_conditional;
+	public boolean insert_space_before_colon_in_default;
+	public boolean insert_space_before_colon_in_for;
+	public boolean insert_space_before_colon_in_labeled_statement;
+	public boolean insert_space_before_comma_in_allocation_expression;
+	public boolean insert_space_before_comma_in_annotation;
+	public boolean insert_space_before_comma_in_array_initializer;
+	public boolean insert_space_before_comma_in_constructor_declaration_parameters;
+	public boolean insert_space_before_comma_in_constructor_declaration_throws;
+	public boolean insert_space_before_comma_in_enum_constant_arguments;
+	public boolean insert_space_before_comma_in_enum_declarations;
+	public boolean insert_space_before_comma_in_explicit_constructor_call_arguments;
+	public boolean insert_space_before_comma_in_for_increments;
+	public boolean insert_space_before_comma_in_for_inits;
+	public boolean insert_space_before_comma_in_method_invocation_arguments;
+	public boolean insert_space_before_comma_in_method_declaration_parameters;
+	public boolean insert_space_before_comma_in_method_declaration_throws;
+	public boolean insert_space_before_comma_in_multiple_field_declarations;
+	public boolean insert_space_before_comma_in_multiple_local_declarations;
+	public boolean insert_space_before_comma_in_parameterized_type_reference;
+	public boolean insert_space_before_comma_in_superinterfaces;
+	public boolean insert_space_before_comma_in_type_arguments;
+	public boolean insert_space_before_comma_in_type_parameters;
+	public boolean insert_space_before_ellipsis;
+	public boolean insert_space_before_lambda_arrow;
+	public boolean insert_space_before_parenthesized_expression_in_return;
+	public boolean insert_space_before_parenthesized_expression_in_throw;
+	public boolean insert_space_before_question_in_wilcard;
+	public boolean insert_space_before_opening_angle_bracket_in_parameterized_type_reference;
+	public boolean insert_space_before_opening_angle_bracket_in_type_arguments;
+	public boolean insert_space_before_opening_angle_bracket_in_type_parameters;
+	public boolean insert_space_before_opening_brace_in_annotation_type_declaration;
+	public boolean insert_space_before_opening_brace_in_anonymous_type_declaration;
+	public boolean insert_space_before_opening_brace_in_array_initializer;
+	public boolean insert_space_before_opening_brace_in_block;
+	public boolean insert_space_before_opening_brace_in_constructor_declaration;
+	public boolean insert_space_before_opening_brace_in_enum_constant;
+	public boolean insert_space_before_opening_brace_in_enum_declaration;
+	public boolean insert_space_before_opening_brace_in_method_declaration;
+	public boolean insert_space_before_opening_brace_in_type_declaration;
+	public boolean insert_space_before_opening_bracket_in_array_allocation_expression;
+	public boolean insert_space_before_opening_bracket_in_array_reference;
+	public boolean insert_space_before_opening_bracket_in_array_type_reference;
+	public boolean insert_space_before_opening_paren_in_annotation;
+	public boolean insert_space_before_opening_paren_in_annotation_type_member_declaration;
+	public boolean insert_space_before_opening_paren_in_catch;
+	public boolean insert_space_before_opening_paren_in_constructor_declaration;
+	public boolean insert_space_before_opening_paren_in_enum_constant;
+	public boolean insert_space_before_opening_paren_in_for;
+	public boolean insert_space_before_opening_paren_in_if;
+	public boolean insert_space_before_opening_paren_in_method_invocation;
+	public boolean insert_space_before_opening_paren_in_method_declaration;
+	public boolean insert_space_before_opening_paren_in_switch;
+	public boolean insert_space_before_opening_paren_in_try;
+	public boolean insert_space_before_opening_brace_in_switch;
+	public boolean insert_space_before_opening_paren_in_synchronized;
+	public boolean insert_space_before_opening_paren_in_parenthesized_expression;
+	public boolean insert_space_before_opening_paren_in_while;
+	public boolean insert_space_before_postfix_operator;
+	public boolean insert_space_before_prefix_operator;
+	public boolean insert_space_before_question_in_conditional;
+	public boolean insert_space_before_semicolon;
+	public boolean insert_space_before_semicolon_in_for;
+	public boolean insert_space_before_semicolon_in_try_resources;
+	public boolean insert_space_before_unary_operator;
+	public boolean insert_space_between_brackets_in_array_type_reference;
+	public boolean insert_space_between_empty_braces_in_array_initializer;
+	public boolean insert_space_between_empty_brackets_in_array_allocation_expression;
+	public boolean insert_space_between_empty_parens_in_annotation_type_member_declaration;
+	public boolean insert_space_between_empty_parens_in_constructor_declaration;
+	public boolean insert_space_between_empty_parens_in_enum_constant;
+	public boolean insert_space_between_empty_parens_in_method_declaration;
+	public boolean insert_space_between_empty_parens_in_method_invocation;
+	public boolean compact_else_if;
+	public boolean keep_guardian_clause_on_one_line;
+	public boolean keep_else_statement_on_same_line;
+	public boolean keep_empty_array_initializer_on_one_line;
+	public boolean keep_simple_if_on_one_line;
+	public boolean keep_then_statement_on_same_line;
+	public boolean never_indent_block_comments_on_first_column;
+	public boolean never_indent_line_comments_on_first_column;
+	public int number_of_empty_lines_to_preserve;
+	public boolean join_wrapped_lines;
+	public boolean join_lines_in_comments;
+	public boolean put_empty_statement_on_new_line;
+	public int tab_size;
+	public final char filling_space = ' ';
+	public int page_width;
+	public int tab_char;
+	public boolean use_tabs_only_for_leading_indentations;
+	public boolean wrap_before_binary_operator;
+	public boolean wrap_before_or_operator_multicatch;
+	public boolean wrap_outer_expressions_when_nested;
+
+	public int initial_indentation_level;
+	public String line_separator;
+
+	private DefaultCodeFormatterOptions() {
+		// cannot be instantiated
+	}
+
+	public DefaultCodeFormatterOptions(Map settings) {
+		setDefaultSettings();
+		if (settings == null) return;
+		set(settings);
+	}
+
+	private String getAlignment(int alignment) {
+		return Integer.toString(alignment);
+	}
+
+	public Map getMap() {
+		Map options = new HashMap();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION, getAlignment(this.alignment_for_arguments_in_allocation_expression));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ANNOTATION, getAlignment(this.alignment_for_arguments_in_annotation));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ENUM_CONSTANT, getAlignment(this.alignment_for_arguments_in_enum_constant));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL, getAlignment(this.alignment_for_arguments_in_explicit_constructor_call));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION, getAlignment(this.alignment_for_arguments_in_method_invocation));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION, getAlignment(this.alignment_for_arguments_in_qualified_allocation_expression));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, getAlignment(this.alignment_for_assignment));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, getAlignment(this.alignment_for_binary_expression));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF, getAlignment(this.alignment_for_compact_if));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION, getAlignment(this.alignment_for_conditional_expression));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS, getAlignment(this.alignment_for_enum_constants));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER, getAlignment(this.alignment_for_expressions_in_array_initializer));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION, getAlignment(this.alignment_for_method_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS, getAlignment(this.alignment_for_multiple_fields));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION, getAlignment(this.alignment_for_parameters_in_constructor_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION, getAlignment(this.alignment_for_parameters_in_method_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY, getAlignment(this.alignment_for_resources_in_try));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION, getAlignment(this.alignment_for_selector_in_method_invocation));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION, getAlignment(this.alignment_for_superclass_in_type_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_ENUM_DECLARATION, getAlignment(this.alignment_for_superinterfaces_in_enum_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_TYPE_DECLARATION, getAlignment(this.alignment_for_superinterfaces_in_type_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_CONSTRUCTOR_DECLARATION, getAlignment(this.alignment_for_throws_clause_in_constructor_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION, getAlignment(this.alignment_for_throws_clause_in_method_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH, getAlignment(this.alignment_for_union_type_in_multicatch));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS, this.align_type_members_on_columns ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANNOTATION_TYPE_DECLARATION, this.brace_position_for_annotation_type_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION, this.brace_position_for_anonymous_type_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER, this.brace_position_for_array_initializer);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, this.brace_position_for_block);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE, this.brace_position_for_block_in_case);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION, this.brace_position_for_constructor_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_CONSTANT, this.brace_position_for_enum_constant);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION, this.brace_position_for_enum_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION, this.brace_position_for_method_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION, this.brace_position_for_type_declaration);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY, this.brace_position_for_lambda_body);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH, this.brace_position_for_switch);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT, this.comment_clear_blank_lines_in_block_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT, this.comment_clear_blank_lines_in_javadoc_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_BLOCK_BOUNDARIES, this.comment_new_lines_at_block_boundaries ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_JAVADOC_BOUNDARIES, this.comment_new_lines_at_javadoc_boundaries ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT, this.comment_format_block_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, this.comment_format_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML, this.comment_format_html ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT, this.comment_format_javadoc_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT, this.comment_format_line_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN, this.comment_format_line_comment_starting_on_first_column ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE, this.comment_format_source ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION, this.comment_indent_parameter_description ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_ROOT_TAGS, this.comment_indent_root_tags ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS, this.comment_insert_empty_line_before_root_tags ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER, this.comment_insert_new_line_for_parameter ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT, this.comment_preserve_white_space_between_code_and_line_comments ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, Integer.toString(this.comment_line_length));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, Integer.toString(this.continuation_indentation));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER, Integer.toString(this.continuation_indentation_for_array_initializer));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS, Integer.toString(this.blank_lines_after_imports));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_PACKAGE, Integer.toString(this.blank_lines_after_package));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIELD, Integer.toString(this.blank_lines_before_field));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION, Integer.toString(this.blank_lines_before_first_class_body_declaration));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_IMPORTS, Integer.toString(this.blank_lines_before_imports));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE, Integer.toString(this.blank_lines_before_member_type));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_METHOD, Integer.toString(this.blank_lines_before_method));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK, Integer.toString(this.blank_lines_before_new_chunk));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_PACKAGE, Integer.toString(this.blank_lines_before_package));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS, Integer.toString(this.blank_lines_between_import_groups));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS, Integer.toString(this.blank_lines_between_type_declarations));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY, Integer.toString(this.blank_lines_at_beginning_of_method_body));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK, this.indent_statements_compare_to_block ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY, this.indent_statements_compare_to_body ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ANNOTATION_DECLARATION_HEADER, this.indent_body_declarations_compare_to_annotation_declaration_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_CONSTANT_HEADER, this.indent_body_declarations_compare_to_enum_constant_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_DECLARATION_HEADER, this.indent_body_declarations_compare_to_enum_declaration_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_TYPE_HEADER, this.indent_body_declarations_compare_to_type_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES, this.indent_breaks_compare_to_cases ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES, this.indent_empty_lines ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES, this.indent_switchstatements_compare_to_cases ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH, this.indent_switchstatements_compare_to_switch ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, Integer.toString(this.indentation_size));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE, this.insert_new_line_after_annotation_on_type ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD, this.insert_new_line_after_annotation_on_field ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD, this.insert_new_line_after_annotation_on_method ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE, this.insert_new_line_after_annotation_on_package ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER, this.insert_new_line_after_annotation_on_parameter ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE, this.insert_new_line_after_annotation_on_local_variable ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER, this.insert_new_line_after_opening_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING, this.insert_new_line_at_end_of_file_if_missing ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, this.insert_new_line_before_catch_in_try_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER, this.insert_new_line_before_closing_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, this.insert_new_line_before_else_in_if_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, this.insert_new_line_before_finally_in_try_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, this.insert_new_line_before_while_in_do_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION, this.insert_new_line_in_empty_anonymous_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, this.insert_new_line_in_empty_block? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION, this.insert_new_line_in_empty_annotation_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT, this.insert_new_line_in_empty_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION, this.insert_new_line_in_empty_enum_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, this.insert_new_line_in_empty_method_body? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, this.insert_new_line_in_empty_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL, this.insert_new_line_after_label? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AND_IN_TYPE_PARAMETER, this.insert_space_after_and_in_type_parameter? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, this.insert_space_after_assignment_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION, this.insert_space_after_at_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION_TYPE_DECLARATION, this.insert_space_after_at_in_annotation_type_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR, this.insert_space_after_binary_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS, this.insert_space_after_closing_angle_bracket_in_type_arguments ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS, this.insert_space_after_closing_angle_bracket_in_type_parameters ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST, this.insert_space_after_closing_paren_in_cast? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK, this.insert_space_after_closing_brace_in_block? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_ASSERT, this.insert_space_after_colon_in_assert ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE, this.insert_space_after_colon_in_case ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL, this.insert_space_after_colon_in_conditional ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_FOR, this.insert_space_after_colon_in_for ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT, this.insert_space_after_colon_in_labeled_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ALLOCATION_EXPRESSION, this.insert_space_after_comma_in_allocation_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ANNOTATION, this.insert_space_after_comma_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ARRAY_INITIALIZER, this.insert_space_after_comma_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS, this.insert_space_after_comma_in_constructor_declaration_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS, this.insert_space_after_comma_in_constructor_declaration_throws? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_CONSTANT_ARGUMENTS, this.insert_space_after_comma_in_enum_constant_arguments ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS, this.insert_space_after_comma_in_enum_declarations ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS, this.insert_space_after_comma_in_explicit_constructor_call_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS, this.insert_space_after_comma_in_for_increments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS, this.insert_space_after_comma_in_for_inits? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, this.insert_space_after_comma_in_method_invocation_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS, this.insert_space_after_comma_in_method_declaration_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS, this.insert_space_after_comma_in_method_declaration_throws? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS, this.insert_space_after_comma_in_multiple_field_declarations? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS, this.insert_space_after_comma_in_multiple_local_declarations? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE, this.insert_space_after_comma_in_parameterized_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_SUPERINTERFACES, this.insert_space_after_comma_in_superinterfaces? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS, this.insert_space_after_comma_in_type_arguments ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_PARAMETERS, this.insert_space_after_comma_in_type_parameters ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION, this.insert_space_after_opening_bracket_in_array_allocation_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS, this.insert_space_after_ellipsis ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_ARROW, this.insert_space_after_lambda_arrow ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE, this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS, this.insert_space_after_opening_angle_bracket_in_type_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS, this.insert_space_after_opening_angle_bracket_in_type_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_REFERENCE, this.insert_space_after_opening_bracket_in_array_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER, this.insert_space_after_opening_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ANNOTATION, this.insert_space_after_opening_paren_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST, this.insert_space_after_opening_paren_in_cast? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH, this.insert_space_after_opening_paren_in_catch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION, this.insert_space_after_opening_paren_in_constructor_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ENUM_CONSTANT, this.insert_space_after_opening_paren_in_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR, this.insert_space_after_opening_paren_in_for? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF, this.insert_space_after_opening_paren_in_if? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION, this.insert_space_after_opening_paren_in_method_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION, this.insert_space_after_opening_paren_in_method_invocation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_after_opening_paren_in_parenthesized_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH, this.insert_space_after_opening_paren_in_switch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SYNCHRONIZED, this.insert_space_after_opening_paren_in_synchronized? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY, this.insert_space_after_opening_paren_in_try? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE, this.insert_space_after_opening_paren_in_while? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR, this.insert_space_after_postfix_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR, this.insert_space_after_prefix_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL, this.insert_space_after_question_in_conditional? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_WILDCARD, this.insert_space_after_question_in_wilcard? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR, this.insert_space_after_semicolon_in_for? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES, this.insert_space_after_semicolon_in_try_resources? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR, this.insert_space_after_unary_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_AND_IN_TYPE_PARAMETER, this.insert_space_before_and_in_type_parameter ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_AT_IN_ANNOTATION_TYPE_DECLARATION, this.insert_space_before_at_in_annotation_type_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, this.insert_space_before_assignment_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR, this.insert_space_before_binary_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE, this.insert_space_before_closing_angle_bracket_in_parameterized_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS, this.insert_space_before_closing_angle_bracket_in_type_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS, this.insert_space_before_closing_angle_bracket_in_type_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER, this.insert_space_before_closing_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION, this.insert_space_before_closing_bracket_in_array_allocation_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_REFERENCE, this.insert_space_before_closing_bracket_in_array_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ANNOTATION, this.insert_space_before_closing_paren_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST, this.insert_space_before_closing_paren_in_cast? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH, this.insert_space_before_closing_paren_in_catch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CONSTRUCTOR_DECLARATION, this.insert_space_before_closing_paren_in_constructor_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ENUM_CONSTANT, this.insert_space_before_closing_paren_in_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR, this.insert_space_before_closing_paren_in_for? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF, this.insert_space_before_closing_paren_in_if? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION, this.insert_space_before_closing_paren_in_method_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION, this.insert_space_before_closing_paren_in_method_invocation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_before_closing_paren_in_parenthesized_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH, this.insert_space_before_closing_paren_in_switch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SYNCHRONIZED, this.insert_space_before_closing_paren_in_synchronized? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY, this.insert_space_before_closing_paren_in_try? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE, this.insert_space_before_closing_paren_in_while? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_ASSERT, this.insert_space_before_colon_in_assert? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE, this.insert_space_before_colon_in_case? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL, this.insert_space_before_colon_in_conditional? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT, this.insert_space_before_colon_in_default? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_FOR, this.insert_space_before_colon_in_for ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT, this.insert_space_before_colon_in_labeled_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION, this.insert_space_before_comma_in_allocation_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ANNOTATION, this.insert_space_before_comma_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ARRAY_INITIALIZER, this.insert_space_before_comma_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS, this.insert_space_before_comma_in_constructor_declaration_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS, this.insert_space_before_comma_in_constructor_declaration_throws? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_CONSTANT_ARGUMENTS, this.insert_space_before_comma_in_enum_constant_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS, this.insert_space_before_comma_in_enum_declarations? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS, this.insert_space_before_comma_in_explicit_constructor_call_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS, this.insert_space_before_comma_in_for_increments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS, this.insert_space_before_comma_in_for_inits? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, this.insert_space_before_comma_in_method_invocation_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS, this.insert_space_before_comma_in_method_declaration_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS, this.insert_space_before_comma_in_method_declaration_throws? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS, this.insert_space_before_comma_in_multiple_field_declarations? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS, this.insert_space_before_comma_in_multiple_local_declarations? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_SUPERINTERFACES, this.insert_space_before_comma_in_superinterfaces? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_ARGUMENTS, this.insert_space_before_comma_in_type_arguments ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_PARAMETERS, this.insert_space_before_comma_in_type_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE, this.insert_space_before_comma_in_parameterized_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS, this.insert_space_before_ellipsis ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_ARROW, this.insert_space_before_lambda_arrow ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE, this.insert_space_before_opening_angle_bracket_in_parameterized_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS, this.insert_space_before_opening_angle_bracket_in_type_arguments? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS, this.insert_space_before_opening_angle_bracket_in_type_parameters? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANNOTATION_TYPE_DECLARATION, this.insert_space_before_opening_brace_in_annotation_type_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANONYMOUS_TYPE_DECLARATION, this.insert_space_before_opening_brace_in_anonymous_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ARRAY_INITIALIZER, this.insert_space_before_opening_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK, this.insert_space_before_opening_brace_in_block? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_CONSTRUCTOR_DECLARATION, this.insert_space_before_opening_brace_in_constructor_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_CONSTANT, this.insert_space_before_opening_brace_in_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_DECLARATION, this.insert_space_before_opening_brace_in_enum_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION, this.insert_space_before_opening_brace_in_method_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION, this.insert_space_before_opening_brace_in_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION, this.insert_space_before_opening_bracket_in_array_allocation_expression ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_REFERENCE, this.insert_space_before_opening_bracket_in_array_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_TYPE_REFERENCE, this.insert_space_before_opening_bracket_in_array_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION, this.insert_space_before_opening_paren_in_annotation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION_TYPE_MEMBER_DECLARATION, this.insert_space_before_opening_paren_in_annotation_type_member_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH, this.insert_space_before_opening_paren_in_catch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION, this.insert_space_before_opening_paren_in_constructor_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ENUM_CONSTANT, this.insert_space_before_opening_paren_in_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR, this.insert_space_before_opening_paren_in_for? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF, this.insert_space_before_opening_paren_in_if? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION, this.insert_space_before_opening_paren_in_method_invocation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION, this.insert_space_before_opening_paren_in_method_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH, this.insert_space_before_opening_paren_in_switch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH, this.insert_space_before_opening_brace_in_switch? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SYNCHRONIZED, this.insert_space_before_opening_paren_in_synchronized? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY, this.insert_space_before_opening_paren_in_try? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION, this.insert_space_before_opening_paren_in_parenthesized_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE, this.insert_space_before_opening_paren_in_while? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN, this.insert_space_before_parenthesized_expression_in_return ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_THROW, this.insert_space_before_parenthesized_expression_in_throw ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR, this.insert_space_before_postfix_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR, this.insert_space_before_prefix_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL, this.insert_space_before_question_in_conditional? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_WILDCARD, this.insert_space_before_question_in_wilcard? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON, this.insert_space_before_semicolon? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR, this.insert_space_before_semicolon_in_for? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES, this.insert_space_before_semicolon_in_try_resources? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR, this.insert_space_before_unary_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_BRACKETS_IN_ARRAY_TYPE_REFERENCE, this.insert_space_between_brackets_in_array_type_reference? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_ARRAY_INITIALIZER, this.insert_space_between_empty_braces_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS_IN_ARRAY_ALLOCATION_EXPRESSION, this.insert_space_between_empty_brackets_in_array_allocation_expression? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ANNOTATION_TYPE_MEMBER_DECLARATION, this.insert_space_between_empty_parens_in_annotation_type_member_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_CONSTRUCTOR_DECLARATION, this.insert_space_between_empty_parens_in_constructor_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ENUM_CONSTANT, this.insert_space_between_empty_parens_in_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION, this.insert_space_between_empty_parens_in_method_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION, this.insert_space_between_empty_parens_in_method_invocation? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF, this.compact_else_if ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE, this.keep_guardian_clause_on_one_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE, this.keep_else_statement_on_same_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE, this.keep_empty_array_initializer_on_one_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE, this.keep_simple_if_on_one_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE, this.keep_then_statement_on_same_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN, this.never_indent_block_comments_on_first_column ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, this.never_indent_line_comments_on_first_column ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, Integer.toString(this.number_of_empty_lines_to_preserve));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES, this.join_wrapped_lines ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS, this.join_lines_in_comments ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE, this.put_empty_statement_on_new_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, Integer.toString(this.page_width));
+		switch(this.tab_char) {
+			case SPACE :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+				break;
+			case TAB :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.TAB);
+				break;
+			case MIXED :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, DefaultCodeFormatterConstants.MIXED);
+				break;
+		}
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, Integer.toString(this.tab_size));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS, this.use_tabs_only_for_leading_indentations ?  DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_BINARY_OPERATOR, this.wrap_before_binary_operator ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH, this.wrap_before_or_operator_multicatch ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG, this.disabling_tag == null ? Util.EMPTY_STRING : new String(this.disabling_tag));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG, this.enabling_tag == null ? Util.EMPTY_STRING : new String(this.enabling_tag));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS, this.use_tags ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_WRAP_OUTER_EXPRESSIONS_WHEN_NESTED, this.wrap_outer_expressions_when_nested ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		return options;
+	}
+
+	public void set(Map settings) {
+		final Object alignmentForArgumentsInAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION);
+		if (alignmentForArgumentsInAllocationExpressionOption != null) {
+			try {
+				this.alignment_for_arguments_in_allocation_expression = Integer.parseInt((String) alignmentForArgumentsInAllocationExpressionOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForArgumentsInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ANNOTATION);
+		if (alignmentForArgumentsInAnnotationOption != null) {
+			try {
+				this.alignment_for_arguments_in_annotation = Integer.parseInt((String) alignmentForArgumentsInAnnotationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_annotation = Alignment.M_NO_ALIGNMENT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_annotation = Alignment.M_NO_ALIGNMENT;
+			}
+		}
+		final Object alignmentForArgumentsInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ENUM_CONSTANT);
+		if (alignmentForArgumentsInEnumConstantOption != null) {
+			try {
+				this.alignment_for_arguments_in_enum_constant = Integer.parseInt((String) alignmentForArgumentsInEnumConstantOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_enum_constant = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_enum_constant = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForArgumentsInExplicitConstructorCallOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL);
+		if (alignmentForArgumentsInExplicitConstructorCallOption != null) {
+			try {
+				this.alignment_for_arguments_in_explicit_constructor_call = Integer.parseInt((String) alignmentForArgumentsInExplicitConstructorCallOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_explicit_constructor_call = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_explicit_constructor_call = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForArgumentsInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION);
+		if (alignmentForArgumentsInMethodInvocationOption != null) {
+			try {
+				this.alignment_for_arguments_in_method_invocation = Integer.parseInt((String) alignmentForArgumentsInMethodInvocationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForArgumentsInQualifiedAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION);
+		if (alignmentForArgumentsInQualifiedAllocationExpressionOption != null) {
+			try {
+				this.alignment_for_arguments_in_qualified_allocation_expression = Integer.parseInt((String) alignmentForArgumentsInQualifiedAllocationExpressionOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_arguments_in_qualified_allocation_expression = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_arguments_in_qualified_allocation_expression = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForAssignmentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT);
+		if (alignmentForAssignmentOption != null) {
+			try {
+				this.alignment_for_assignment = Integer.parseInt((String) alignmentForAssignmentOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_assignment =  Alignment.M_ONE_PER_LINE_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_assignment =  Alignment.M_ONE_PER_LINE_SPLIT;
+			}
+		}
+		final Object alignmentForBinaryExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION);
+		if (alignmentForBinaryExpressionOption != null) {
+			try {
+				this.alignment_for_binary_expression = Integer.parseInt((String) alignmentForBinaryExpressionOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_binary_expression =  Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_binary_expression =  Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForCompactIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF);
+		if (alignmentForCompactIfOption != null) {
+			try {
+				this.alignment_for_compact_if = Integer.parseInt((String) alignmentForCompactIfOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_compact_if = Alignment.M_ONE_PER_LINE_SPLIT | Alignment.M_INDENT_BY_ONE;
+			} catch (ClassCastException e) {
+				this.alignment_for_compact_if = Alignment.M_ONE_PER_LINE_SPLIT | Alignment.M_INDENT_BY_ONE;
+			}
+		}
+		final Object alignmentForConditionalExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION);
+		if (alignmentForConditionalExpressionOption != null) {
+			try {
+				this.alignment_for_conditional_expression = Integer.parseInt((String) alignmentForConditionalExpressionOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_conditional_expression = Alignment.M_ONE_PER_LINE_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_conditional_expression = Alignment.M_ONE_PER_LINE_SPLIT;
+			}
+		}
+		final Object alignmentForEnumConstantsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS);
+		if (alignmentForEnumConstantsOption != null) {
+			try {
+				this.alignment_for_enum_constants = Integer.parseInt((String) alignmentForEnumConstantsOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_enum_constants = Alignment.NONE;
+			} catch (ClassCastException e) {
+				this.alignment_for_enum_constants = Alignment.NONE;
+			}
+		}
+		final Object alignmentForExpressionsInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER);
+		if (alignmentForExpressionsInArrayInitializerOption != null) {
+			try {
+				this.alignment_for_expressions_in_array_initializer = Integer.parseInt((String) alignmentForExpressionsInArrayInitializerOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION);
+		if (alignmentForMethodDeclarationOption != null) {
+			try {
+				this.alignment_for_method_declaration = Integer.parseInt((String) alignmentForMethodDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_method_declaration = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForMultipleFieldsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS);
+		if (alignmentForMultipleFieldsOption != null) {
+			try {
+				this.alignment_for_multiple_fields = Integer.parseInt((String) alignmentForMultipleFieldsOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForParametersInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION);
+		if (alignmentForParametersInConstructorDeclarationOption != null) {
+			try {
+				this.alignment_for_parameters_in_constructor_declaration = Integer.parseInt((String) alignmentForParametersInConstructorDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+			} catch (ClassCastException e) {
+				this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForParametersInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION);
+		if (alignmentForParametersInMethodDeclarationOption != null) {
+			try {
+				this.alignment_for_parameters_in_method_declaration = Integer.parseInt((String) alignmentForParametersInMethodDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForResourcesInTry = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY);
+		if (alignmentForResourcesInTry != null) {
+			try {
+				this.alignment_for_resources_in_try = Integer.parseInt((String) alignmentForResourcesInTry);
+			} catch (NumberFormatException e) {
+				this.alignment_for_resources_in_try = Alignment.M_NEXT_PER_LINE_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_resources_in_try = Alignment.M_NEXT_PER_LINE_SPLIT;
+			}
+		}
+		final Object alignmentForSelectorInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION);
+		if (alignmentForSelectorInMethodInvocationOption != null) {
+			try {
+				this.alignment_for_selector_in_method_invocation = Integer.parseInt((String) alignmentForSelectorInMethodInvocationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_selector_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_selector_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForSuperclassInTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION);
+		if (alignmentForSuperclassInTypeDeclarationOption != null) {
+			try {
+				this.alignment_for_superclass_in_type_declaration = Integer.parseInt((String) alignmentForSuperclassInTypeDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_superclass_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_superclass_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			}
+		}
+		final Object alignmentForSuperinterfacesInEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_ENUM_DECLARATION);
+		if (alignmentForSuperinterfacesInEnumDeclarationOption != null) {
+			try {
+				this.alignment_for_superinterfaces_in_enum_declaration = Integer.parseInt((String) alignmentForSuperinterfacesInEnumDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_superinterfaces_in_enum_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_superinterfaces_in_enum_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			}
+		}
+		final Object alignmentForSuperinterfacesInTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_TYPE_DECLARATION);
+		if (alignmentForSuperinterfacesInTypeDeclarationOption != null) {
+			try {
+				this.alignment_for_superinterfaces_in_type_declaration = Integer.parseInt((String) alignmentForSuperinterfacesInTypeDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_superinterfaces_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_superinterfaces_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+			}
+		}
+		final Object alignmentForThrowsClauseInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_CONSTRUCTOR_DECLARATION);
+		if (alignmentForThrowsClauseInConstructorDeclarationOption != null) {
+			try {
+				this.alignment_for_throws_clause_in_constructor_declaration = Integer.parseInt((String) alignmentForThrowsClauseInConstructorDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_throws_clause_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_throws_clause_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForThrowsClauseInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION);
+		if (alignmentForThrowsClauseInMethodDeclarationOption != null) {
+			try {
+				this.alignment_for_throws_clause_in_method_declaration = Integer.parseInt((String) alignmentForThrowsClauseInMethodDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignmentForUnionTypeInMulticatch = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH);
+		if (alignmentForUnionTypeInMulticatch != null) {
+			try {
+				this.alignment_for_union_type_in_multicatch = Integer.parseInt((String) alignmentForUnionTypeInMulticatch);
+			} catch (NumberFormatException e) {
+				this.alignment_for_union_type_in_multicatch = Alignment.M_COMPACT_SPLIT;
+			} catch(ClassCastException e) {
+				this.alignment_for_union_type_in_multicatch = Alignment.M_COMPACT_SPLIT;
+			}
+		}
+		final Object alignTypeMembersOnColumnsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS);
+		if (alignTypeMembersOnColumnsOption != null) {
+			this.align_type_members_on_columns = DefaultCodeFormatterConstants.TRUE.equals(alignTypeMembersOnColumnsOption);
+		}
+		final Object bracePositionForAnnotationTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANNOTATION_TYPE_DECLARATION);
+		if (bracePositionForAnnotationTypeDeclarationOption != null) {
+			try {
+				this.brace_position_for_annotation_type_declaration = (String) bracePositionForAnnotationTypeDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_annotation_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForAnonymousTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION);
+		if (bracePositionForAnonymousTypeDeclarationOption != null) {
+			try {
+				this.brace_position_for_anonymous_type_declaration = (String) bracePositionForAnonymousTypeDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_anonymous_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER);
+		if (bracePositionForArrayInitializerOption != null) {
+			try {
+				this.brace_position_for_array_initializer = (String) bracePositionForArrayInitializerOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_array_initializer = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK);
+		if (bracePositionForBlockOption != null) {
+			try {
+				this.brace_position_for_block = (String) bracePositionForBlockOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_block = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForBlockInCaseOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK_IN_CASE);
+		if (bracePositionForBlockInCaseOption != null) {
+			try {
+				this.brace_position_for_block_in_case = (String) bracePositionForBlockInCaseOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_block_in_case = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION);
+		if (bracePositionForConstructorDeclarationOption != null) {
+			try {
+				this.brace_position_for_constructor_declaration = (String) bracePositionForConstructorDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_constructor_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_CONSTANT);
+		if (bracePositionForEnumConstantOption != null) {
+			try {
+				this.brace_position_for_enum_constant = (String) bracePositionForEnumConstantOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_enum_constant = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ENUM_DECLARATION);
+		if (bracePositionForEnumDeclarationOption != null) {
+			try {
+				this.brace_position_for_enum_declaration = (String) bracePositionForEnumDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_enum_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForLambdaDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_LAMBDA_BODY);
+		if (bracePositionForLambdaDeclarationOption != null) {
+			try {
+				this.brace_position_for_lambda_body = (String) bracePositionForLambdaDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_lambda_body = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION);
+		if (bracePositionForMethodDeclarationOption != null) {
+			try {
+				this.brace_position_for_method_declaration = (String) bracePositionForMethodDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_method_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH);
+		if (bracePositionForSwitchOption != null) {
+			try {
+				this.brace_position_for_switch = (String) bracePositionForSwitchOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_switch = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object bracePositionForTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION);
+		if (bracePositionForTypeDeclarationOption != null) {
+			try {
+				this.brace_position_for_type_declaration = (String) bracePositionForTypeDeclarationOption;
+			} catch(ClassCastException e) {
+				this.brace_position_for_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+			}
+		}
+		final Object continuationIndentationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION);
+		if (continuationIndentationOption != null) {
+			try {
+				this.continuation_indentation = Integer.parseInt((String) continuationIndentationOption);
+			} catch (NumberFormatException e) {
+				this.continuation_indentation = 2;
+			} catch(ClassCastException e) {
+				this.continuation_indentation = 2;
+			}
+		}
+		final Object continuationIndentationForArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER);
+		if (continuationIndentationForArrayInitializerOption != null) {
+			try {
+				this.continuation_indentation_for_array_initializer = Integer.parseInt((String) continuationIndentationForArrayInitializerOption);
+			} catch (NumberFormatException e) {
+				this.continuation_indentation_for_array_initializer = 2;
+			} catch(ClassCastException e) {
+				this.continuation_indentation_for_array_initializer = 2;
+			}
+		}
+		final Object blankLinesAfterImportsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS);
+		if (blankLinesAfterImportsOption != null) {
+			try {
+				this.blank_lines_after_imports = Integer.parseInt((String) blankLinesAfterImportsOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_after_imports = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_after_imports = 0;
+			}
+		}
+		final Object blankLinesAfterPackageOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_PACKAGE);
+		if (blankLinesAfterPackageOption != null) {
+			try {
+				this.blank_lines_after_package = Integer.parseInt((String) blankLinesAfterPackageOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_after_package = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_after_package = 0;
+			}
+		}
+		final Object blankLinesBeforeFieldOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIELD);
+		if (blankLinesBeforeFieldOption != null) {
+			try {
+				this.blank_lines_before_field = Integer.parseInt((String) blankLinesBeforeFieldOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_field = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_field = 0;
+			}
+		}
+		final Object blankLinesBeforeFirstClassBodyDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION);
+		if (blankLinesBeforeFirstClassBodyDeclarationOption != null) {
+			try {
+				this.blank_lines_before_first_class_body_declaration = Integer.parseInt((String) blankLinesBeforeFirstClassBodyDeclarationOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_first_class_body_declaration = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_first_class_body_declaration = 0;
+			}
+		}
+		final Object blankLinesBeforeImportsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_IMPORTS);
+		if (blankLinesBeforeImportsOption != null) {
+			try {
+				this.blank_lines_before_imports = Integer.parseInt((String) blankLinesBeforeImportsOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_imports = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_imports = 0;
+			}
+		}
+		final Object blankLinesBeforeMemberTypeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE);
+		if (blankLinesBeforeMemberTypeOption != null) {
+			try {
+				this.blank_lines_before_member_type = Integer.parseInt((String) blankLinesBeforeMemberTypeOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_member_type = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_member_type = 0;
+			}
+		}
+		final Object blankLinesBeforeMethodOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_METHOD);
+		if (blankLinesBeforeMethodOption != null) {
+			try {
+				this.blank_lines_before_method = Integer.parseInt((String) blankLinesBeforeMethodOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_method = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_method = 0;
+			}
+		}
+		final Object blankLinesBeforeNewChunkOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK);
+		if (blankLinesBeforeNewChunkOption != null) {
+			try {
+				this.blank_lines_before_new_chunk = Integer.parseInt((String) blankLinesBeforeNewChunkOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_new_chunk = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_new_chunk = 0;
+			}
+		}
+		final Object blankLinesBeforePackageOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_PACKAGE);
+		if (blankLinesBeforePackageOption != null) {
+			try {
+				this.blank_lines_before_package = Integer.parseInt((String) blankLinesBeforePackageOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_before_package = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_before_package = 0;
+			}
+		}
+		final Object blankLinesBetweenImportGroupsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS);
+		if (blankLinesBetweenImportGroupsOption != null) {
+			try {
+				this.blank_lines_between_import_groups = Integer.parseInt((String) blankLinesBetweenImportGroupsOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_between_import_groups = 1;
+			} catch(ClassCastException e) {
+				this.blank_lines_between_import_groups = 1;
+			}
+		}
+		final Object blankLinesBetweenTypeDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS);
+		if (blankLinesBetweenTypeDeclarationsOption != null) {
+			try {
+				this.blank_lines_between_type_declarations = Integer.parseInt((String) blankLinesBetweenTypeDeclarationsOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_between_type_declarations = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_between_type_declarations = 0;
+			}
+		}
+		final Object blankLinesAtBeginningOfMethodBodyOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY);
+		if (blankLinesAtBeginningOfMethodBodyOption != null) {
+			try {
+				this.blank_lines_at_beginning_of_method_body = Integer.parseInt((String) blankLinesAtBeginningOfMethodBodyOption);
+			} catch (NumberFormatException e) {
+				this.blank_lines_at_beginning_of_method_body = 0;
+			} catch(ClassCastException e) {
+				this.blank_lines_at_beginning_of_method_body = 0;
+			}
+		}
+		setDeprecatedOptions(settings);
+		final Object commentFormatJavadocCommentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT);
+		if (commentFormatJavadocCommentOption != null) {
+			this.comment_format_javadoc_comment = DefaultCodeFormatterConstants.TRUE.equals(commentFormatJavadocCommentOption);
+		}
+		final Object commentFormatBlockCommentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT);
+		if (commentFormatBlockCommentOption != null) {
+			this.comment_format_block_comment = DefaultCodeFormatterConstants.TRUE.equals(commentFormatBlockCommentOption);
+		}
+		final Object commentFormatLineCommentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT);
+		if (commentFormatLineCommentOption != null) {
+			this.comment_format_line_comment = DefaultCodeFormatterConstants.TRUE.equals(commentFormatLineCommentOption);
+		}
+		final Object formatLineCommentStartingOnFirstColumnOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN);
+		if (formatLineCommentStartingOnFirstColumnOption != null) {
+			this.comment_format_line_comment_starting_on_first_column = DefaultCodeFormatterConstants.TRUE.equals(formatLineCommentStartingOnFirstColumnOption);
+		}
+		final Object commentFormatHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER);
+		if (commentFormatHeaderOption != null) {
+			this.comment_format_header = DefaultCodeFormatterConstants.TRUE.equals(commentFormatHeaderOption);
+		}
+		final Object commentFormatHtmlOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML);
+		if (commentFormatHtmlOption != null) {
+			this.comment_format_html = DefaultCodeFormatterConstants.TRUE.equals(commentFormatHtmlOption);
+		}
+		final Object commentFormatSourceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE);
+		if (commentFormatSourceOption != null) {
+			this.comment_format_source = DefaultCodeFormatterConstants.TRUE.equals(commentFormatSourceOption);
+		}
+		final Object commentIndentParameterDescriptionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION);
+		if (commentIndentParameterDescriptionOption != null) {
+			this.comment_indent_parameter_description = DefaultCodeFormatterConstants.TRUE.equals(commentIndentParameterDescriptionOption);
+		}
+		final Object commentIndentRootTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_ROOT_TAGS);
+		if (commentIndentRootTagsOption != null) {
+			this.comment_indent_root_tags = DefaultCodeFormatterConstants.TRUE.equals(commentIndentRootTagsOption);
+		}
+		final Object commentInsertEmptyLineBeforeRootTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS);
+		if (commentInsertEmptyLineBeforeRootTagsOption != null) {
+			this.comment_insert_empty_line_before_root_tags = JavaCore.INSERT.equals(commentInsertEmptyLineBeforeRootTagsOption);
+		}
+		final Object commentInsertNewLineForParameterOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER);
+		if (commentInsertNewLineForParameterOption != null) {
+			this.comment_insert_new_line_for_parameter = JavaCore.INSERT.equals(commentInsertNewLineForParameterOption);
+		}
+		final Object commentPreserveWhiteSpaceBetweenCodeAndLineCommentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT);
+		if (commentPreserveWhiteSpaceBetweenCodeAndLineCommentsOption != null) {
+			this.comment_preserve_white_space_between_code_and_line_comments = DefaultCodeFormatterConstants.TRUE.equals(commentPreserveWhiteSpaceBetweenCodeAndLineCommentsOption);
+		}
+		final Object commentLineLengthOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH);
+		if (commentLineLengthOption != null) {
+			try {
+				this.comment_line_length = Integer.parseInt((String) commentLineLengthOption);
+			} catch (NumberFormatException e) {
+				this.comment_line_length = 80;
+			} catch(ClassCastException e) {
+				this.comment_line_length = 80;
+			}
+		}
+		final Object commentNewLinesAtBlockBoundariesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_BLOCK_BOUNDARIES);
+		if (commentNewLinesAtBlockBoundariesOption != null) {
+			this.comment_new_lines_at_block_boundaries = DefaultCodeFormatterConstants.TRUE.equals(commentNewLinesAtBlockBoundariesOption);
+		}
+		final Object commentNewLinesAtJavadocBoundariesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_JAVADOC_BOUNDARIES);
+		if (commentNewLinesAtJavadocBoundariesOption != null) {
+			this.comment_new_lines_at_javadoc_boundaries = DefaultCodeFormatterConstants.TRUE.equals(commentNewLinesAtJavadocBoundariesOption);
+		}
+		final Object indentStatementsCompareToBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
+		if (indentStatementsCompareToBlockOption != null) {
+			this.indent_statements_compare_to_block = DefaultCodeFormatterConstants.TRUE.equals(indentStatementsCompareToBlockOption);
+		}
+		final Object indentStatementsCompareToBodyOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY);
+		if (indentStatementsCompareToBodyOption != null) {
+			this.indent_statements_compare_to_body = DefaultCodeFormatterConstants.TRUE.equals(indentStatementsCompareToBodyOption);
+		}
+		final Object indentBodyDeclarationsCompareToAnnotationDeclarationHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ANNOTATION_DECLARATION_HEADER);
+		if (indentBodyDeclarationsCompareToAnnotationDeclarationHeaderOption != null) {
+			this.indent_body_declarations_compare_to_annotation_declaration_header = DefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToAnnotationDeclarationHeaderOption);
+		}
+		final Object indentBodyDeclarationsCompareToEnumConstantHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_CONSTANT_HEADER);
+		if (indentBodyDeclarationsCompareToEnumConstantHeaderOption != null) {
+			this.indent_body_declarations_compare_to_enum_constant_header = DefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToEnumConstantHeaderOption);
+		}
+		final Object indentBodyDeclarationsCompareToEnumDeclarationHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ENUM_DECLARATION_HEADER);
+		if (indentBodyDeclarationsCompareToEnumDeclarationHeaderOption != null) {
+			this.indent_body_declarations_compare_to_enum_declaration_header = DefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToEnumDeclarationHeaderOption);
+		}
+		final Object indentBodyDeclarationsCompareToTypeHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_TYPE_HEADER);
+		if (indentBodyDeclarationsCompareToTypeHeaderOption != null) {
+			this.indent_body_declarations_compare_to_type_header = DefaultCodeFormatterConstants.TRUE.equals(indentBodyDeclarationsCompareToTypeHeaderOption);
+		}
+		final Object indentBreaksCompareToCasesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES);
+		if (indentBreaksCompareToCasesOption != null) {
+			this.indent_breaks_compare_to_cases = DefaultCodeFormatterConstants.TRUE.equals(indentBreaksCompareToCasesOption);
+		}
+		final Object indentEmptyLinesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_EMPTY_LINES);
+		if (indentEmptyLinesOption != null) {
+			this.indent_empty_lines = DefaultCodeFormatterConstants.TRUE.equals(indentEmptyLinesOption);
+		}
+		final Object indentSwitchstatementsCompareToCasesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES);
+		if (indentSwitchstatementsCompareToCasesOption != null) {
+			this.indent_switchstatements_compare_to_cases = DefaultCodeFormatterConstants.TRUE.equals(indentSwitchstatementsCompareToCasesOption);
+		}
+		final Object indentSwitchstatementsCompareToSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH);
+		if (indentSwitchstatementsCompareToSwitchOption != null) {
+			this.indent_switchstatements_compare_to_switch = DefaultCodeFormatterConstants.TRUE.equals(indentSwitchstatementsCompareToSwitchOption);
+		}
+		final Object indentationSizeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE);
+		if (indentationSizeOption != null) {
+			try {
+				this.indentation_size = Integer.parseInt((String) indentationSizeOption);
+			} catch (NumberFormatException e) {
+				this.indentation_size = 4;
+			} catch(ClassCastException e) {
+				this.indentation_size = 4;
+			}
+		}
+		final Object insertNewLineAfterOpeningBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER);
+		if (insertNewLineAfterOpeningBraceInArrayInitializerOption != null) {
+			this.insert_new_line_after_opening_brace_in_array_initializer = JavaCore.INSERT.equals(insertNewLineAfterOpeningBraceInArrayInitializerOption);
+		}
+		final Object insertNewLineAtEndOfFileIfMissingOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING);
+		if (insertNewLineAtEndOfFileIfMissingOption != null) {
+			this.insert_new_line_at_end_of_file_if_missing = JavaCore.INSERT.equals(insertNewLineAtEndOfFileIfMissingOption);
+		}
+		final Object insertNewLineBeforeCatchInTryStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT);
+		if (insertNewLineBeforeCatchInTryStatementOption != null) {
+			this.insert_new_line_before_catch_in_try_statement = JavaCore.INSERT.equals(insertNewLineBeforeCatchInTryStatementOption);
+		}
+		final Object insertNewLineBeforeClosingBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER);
+		if (insertNewLineBeforeClosingBraceInArrayInitializerOption != null) {
+			this.insert_new_line_before_closing_brace_in_array_initializer = JavaCore.INSERT.equals(insertNewLineBeforeClosingBraceInArrayInitializerOption);
+		}
+		final Object insertNewLineBeforeElseInIfStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT);
+		if (insertNewLineBeforeElseInIfStatementOption != null) {
+			this.insert_new_line_before_else_in_if_statement = JavaCore.INSERT.equals(insertNewLineBeforeElseInIfStatementOption);
+		}
+		final Object insertNewLineBeforeFinallyInTryStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT);
+		if (insertNewLineBeforeFinallyInTryStatementOption != null) {
+			this.insert_new_line_before_finally_in_try_statement = JavaCore.INSERT.equals(insertNewLineBeforeFinallyInTryStatementOption);
+		}
+		final Object insertNewLineBeforeWhileInDoStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT);
+		if (insertNewLineBeforeWhileInDoStatementOption != null) {
+			this.insert_new_line_before_while_in_do_statement = JavaCore.INSERT.equals(insertNewLineBeforeWhileInDoStatementOption);
+		}
+		final Object insertNewLineInEmptyAnonymousTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION);
+		if (insertNewLineInEmptyAnonymousTypeDeclarationOption != null) {
+			this.insert_new_line_in_empty_anonymous_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnonymousTypeDeclarationOption);
+		}
+		final Object insertNewLineInEmptyBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK);
+		if (insertNewLineInEmptyBlockOption != null) {
+			this.insert_new_line_in_empty_block = JavaCore.INSERT.equals(insertNewLineInEmptyBlockOption);
+		}
+		final Object insertNewLineInEmptyAnnotationDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION);
+		if (insertNewLineInEmptyAnnotationDeclarationOption != null) {
+			this.insert_new_line_in_empty_annotation_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnnotationDeclarationOption);
+		}
+		final Object insertNewLineInEmptyEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT);
+		if (insertNewLineInEmptyEnumConstantOption != null) {
+			this.insert_new_line_in_empty_enum_constant = JavaCore.INSERT.equals(insertNewLineInEmptyEnumConstantOption);
+		}
+		final Object insertNewLineInEmptyEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION);
+		if (insertNewLineInEmptyEnumDeclarationOption != null) {
+			this.insert_new_line_in_empty_enum_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyEnumDeclarationOption);
+		}
+		final Object insertNewLineInEmptyMethodBodyOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY);
+		if (insertNewLineInEmptyMethodBodyOption != null) {
+			this.insert_new_line_in_empty_method_body = JavaCore.INSERT.equals(insertNewLineInEmptyMethodBodyOption);
+		}
+		final Object insertNewLineInEmptyTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION);
+		if (insertNewLineInEmptyTypeDeclarationOption != null) {
+			this.insert_new_line_in_empty_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyTypeDeclarationOption);
+		}
+		final Object insertNewLineAfterLabelOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL);
+		if (insertNewLineAfterLabelOption != null) {
+			this.insert_new_line_after_label = JavaCore.INSERT.equals(insertNewLineAfterLabelOption);
+		}
+		final Object insertSpaceAfterAndInWildcardOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AND_IN_TYPE_PARAMETER);
+		if (insertSpaceAfterAndInWildcardOption != null) {
+			this.insert_space_after_and_in_type_parameter = JavaCore.INSERT.equals(insertSpaceAfterAndInWildcardOption);
+		}
+		final Object insertSpaceAfterAssignmentOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR);
+		if (insertSpaceAfterAssignmentOperatorOption != null) {
+			this.insert_space_after_assignment_operator = JavaCore.INSERT.equals(insertSpaceAfterAssignmentOperatorOption);
+		}
+		final Object insertSpaceAfterAtInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION);
+		if (insertSpaceAfterAtInAnnotationOption != null) {
+			this.insert_space_after_at_in_annotation = JavaCore.INSERT.equals(insertSpaceAfterAtInAnnotationOption);
+		}
+		final Object insertSpaceAfterAtInAnnotationTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AT_IN_ANNOTATION_TYPE_DECLARATION);
+		if (insertSpaceAfterAtInAnnotationTypeDeclarationOption != null) {
+			this.insert_space_after_at_in_annotation_type_declaration = JavaCore.INSERT.equals(insertSpaceAfterAtInAnnotationTypeDeclarationOption);
+		}
+		final Object insertSpaceAfterBinaryOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_BINARY_OPERATOR);
+		if (insertSpaceAfterBinaryOperatorOption != null) {
+			this.insert_space_after_binary_operator = JavaCore.INSERT.equals(insertSpaceAfterBinaryOperatorOption);
+		}
+		final Object insertSpaceAfterClosingAngleBracketInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS);
+		if (insertSpaceAfterClosingAngleBracketInTypeArgumentsOption != null) {
+			this.insert_space_after_closing_angle_bracket_in_type_arguments = JavaCore.INSERT.equals(insertSpaceAfterClosingAngleBracketInTypeArgumentsOption);
+		}
+		final Object insertSpaceAfterClosingAngleBracketInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS);
+		if (insertSpaceAfterClosingAngleBracketInTypeParametersOption != null) {
+			this.insert_space_after_closing_angle_bracket_in_type_parameters = JavaCore.INSERT.equals(insertSpaceAfterClosingAngleBracketInTypeParametersOption);
+		}
+		final Object insertSpaceAfterClosingParenInCastOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST);
+		if (insertSpaceAfterClosingParenInCastOption != null) {
+			this.insert_space_after_closing_paren_in_cast = JavaCore.INSERT.equals(insertSpaceAfterClosingParenInCastOption);
+		}
+		final Object insertSpaceAfterClosingBraceInBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK);
+		if (insertSpaceAfterClosingBraceInBlockOption != null) {
+			this.insert_space_after_closing_brace_in_block = JavaCore.INSERT.equals(insertSpaceAfterClosingBraceInBlockOption);
+		}
+		final Object insertSpaceAfterColonInAssertOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_ASSERT);
+		if (insertSpaceAfterColonInAssertOption != null) {
+			this.insert_space_after_colon_in_assert = JavaCore.INSERT.equals(insertSpaceAfterColonInAssertOption);
+		}
+		final Object insertSpaceAfterColonInCaseOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CASE);
+		if (insertSpaceAfterColonInCaseOption != null) {
+			this.insert_space_after_colon_in_case = JavaCore.INSERT.equals(insertSpaceAfterColonInCaseOption);
+		}
+		final Object insertSpaceAfterColonInConditionalOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_CONDITIONAL);
+		if (insertSpaceAfterColonInConditionalOption != null) {
+			this.insert_space_after_colon_in_conditional = JavaCore.INSERT.equals(insertSpaceAfterColonInConditionalOption);
+		}
+		final Object insertSpaceAfterColonInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_FOR);
+		if (insertSpaceAfterColonInForOption != null) {
+			this.insert_space_after_colon_in_for = JavaCore.INSERT.equals(insertSpaceAfterColonInForOption);
+		}
+		final Object insertSpaceAfterColonInLabeledStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COLON_IN_LABELED_STATEMENT);
+		if (insertSpaceAfterColonInLabeledStatementOption != null) {
+			this.insert_space_after_colon_in_labeled_statement = JavaCore.INSERT.equals(insertSpaceAfterColonInLabeledStatementOption);
+		}
+		final Object insertSpaceAfterCommaInAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ALLOCATION_EXPRESSION);
+		if (insertSpaceAfterCommaInAllocationExpressionOption != null) {
+			this.insert_space_after_comma_in_allocation_expression = JavaCore.INSERT.equals(insertSpaceAfterCommaInAllocationExpressionOption);
+		}
+		final Object insertSpaceAfterCommaInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ANNOTATION);
+		if (insertSpaceAfterCommaInAnnotationOption != null) {
+			this.insert_space_after_comma_in_annotation = JavaCore.INSERT.equals(insertSpaceAfterCommaInAnnotationOption);
+		}
+		final Object insertSpaceAfterCommaInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ARRAY_INITIALIZER);
+		if (insertSpaceAfterCommaInArrayInitializerOption != null) {
+			this.insert_space_after_comma_in_array_initializer = JavaCore.INSERT.equals(insertSpaceAfterCommaInArrayInitializerOption);
+		}
+		final Object insertSpaceAfterCommaInConstructorDeclarationParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS);
+		if (insertSpaceAfterCommaInConstructorDeclarationParametersOption != null) {
+			this.insert_space_after_comma_in_constructor_declaration_parameters = JavaCore.INSERT.equals(insertSpaceAfterCommaInConstructorDeclarationParametersOption);
+		}
+		final Object insertSpaceAfterCommaInConstructorDeclarationThrowsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS);
+		if (insertSpaceAfterCommaInConstructorDeclarationThrowsOption != null) {
+			this.insert_space_after_comma_in_constructor_declaration_throws = JavaCore.INSERT.equals(insertSpaceAfterCommaInConstructorDeclarationThrowsOption);
+		}
+		final Object insertSpaceAfterCommaInEnumConstantArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_CONSTANT_ARGUMENTS);
+		if (insertSpaceAfterCommaInEnumConstantArgumentsOption != null) {
+			this.insert_space_after_comma_in_enum_constant_arguments = JavaCore.INSERT.equals(insertSpaceAfterCommaInEnumConstantArgumentsOption);
+		}
+		final Object insertSpaceAfterCommaInEnumDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_ENUM_DECLARATIONS);
+		if (insertSpaceAfterCommaInEnumDeclarationsOption != null) {
+			this.insert_space_after_comma_in_enum_declarations = JavaCore.INSERT.equals(insertSpaceAfterCommaInEnumDeclarationsOption);
+		}
+		final Object insertSpaceAfterCommaInExplicitConstructorCallArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS);
+		if (insertSpaceAfterCommaInExplicitConstructorCallArgumentsOption != null) {
+			this.insert_space_after_comma_in_explicit_constructor_call_arguments = JavaCore.INSERT.equals(insertSpaceAfterCommaInExplicitConstructorCallArgumentsOption);
+		}
+		final Object insertSpaceAfterCommaInForIncrementsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INCREMENTS);
+		if (insertSpaceAfterCommaInForIncrementsOption != null) {
+			this.insert_space_after_comma_in_for_increments = JavaCore.INSERT.equals(insertSpaceAfterCommaInForIncrementsOption);
+		}
+		final Object insertSpaceAfterCommaInForInitsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS);
+		if (insertSpaceAfterCommaInForInitsOption != null) {
+			this.insert_space_after_comma_in_for_inits = JavaCore.INSERT.equals(insertSpaceAfterCommaInForInitsOption);
+		}
+		final Object insertSpaceAfterCommaInMethodInvocationArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS);
+		if (insertSpaceAfterCommaInMethodInvocationArgumentsOption != null) {
+			this.insert_space_after_comma_in_method_invocation_arguments = JavaCore.INSERT.equals(insertSpaceAfterCommaInMethodInvocationArgumentsOption);
+		}
+		final Object insertSpaceAfterCommaInMethodDeclarationParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS);
+		if (insertSpaceAfterCommaInMethodDeclarationParametersOption != null) {
+			this.insert_space_after_comma_in_method_declaration_parameters = JavaCore.INSERT.equals(insertSpaceAfterCommaInMethodDeclarationParametersOption);
+		}
+		final Object insertSpaceAfterCommaInMethodDeclarationThrowsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS);
+		if (insertSpaceAfterCommaInMethodDeclarationThrowsOption != null) {
+			this.insert_space_after_comma_in_method_declaration_throws = JavaCore.INSERT.equals(insertSpaceAfterCommaInMethodDeclarationThrowsOption);
+		}
+		final Object insertSpaceAfterCommaInMultipleFieldDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS);
+		if (insertSpaceAfterCommaInMultipleFieldDeclarationsOption != null) {
+			this.insert_space_after_comma_in_multiple_field_declarations = JavaCore.INSERT.equals(insertSpaceAfterCommaInMultipleFieldDeclarationsOption);
+		}
+		final Object insertSpaceAfterCommaInMultipleLocalDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS);
+		if (insertSpaceAfterCommaInMultipleLocalDeclarationsOption != null) {
+			this.insert_space_after_comma_in_multiple_local_declarations = JavaCore.INSERT.equals(insertSpaceAfterCommaInMultipleLocalDeclarationsOption);
+		}
+		final Object insertSpaceAfterCommaInParameterizedTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE);
+		if (insertSpaceAfterCommaInParameterizedTypeReferenceOption != null) {
+			this.insert_space_after_comma_in_parameterized_type_reference = JavaCore.INSERT.equals(insertSpaceAfterCommaInParameterizedTypeReferenceOption);
+		}
+		final Object insertSpaceAfterCommaInSuperinterfacesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_SUPERINTERFACES);
+		if (insertSpaceAfterCommaInSuperinterfacesOption != null) {
+			this.insert_space_after_comma_in_superinterfaces = JavaCore.INSERT.equals(insertSpaceAfterCommaInSuperinterfacesOption);
+		}
+		final Object insertSpaceAfterCommaInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS);
+		if (insertSpaceAfterCommaInTypeArgumentsOption != null) {
+			this.insert_space_after_comma_in_type_arguments = JavaCore.INSERT.equals(insertSpaceAfterCommaInTypeArgumentsOption);
+		}
+		final Object insertSpaceAfterCommaInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_TYPE_PARAMETERS);
+		if (insertSpaceAfterCommaInTypeParametersOption != null) {
+			this.insert_space_after_comma_in_type_parameters = JavaCore.INSERT.equals(insertSpaceAfterCommaInTypeParametersOption);
+		}
+		final Object insertSpaceAfterEllipsisOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ELLIPSIS);
+		if (insertSpaceAfterEllipsisOption != null) {
+			this.insert_space_after_ellipsis = JavaCore.INSERT.equals(insertSpaceAfterEllipsisOption);
+		}
+		final Object insertSpaceAfterLambdaArrowOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_ARROW);
+		if (insertSpaceAfterLambdaArrowOption != null) {
+			this.insert_space_after_lambda_arrow = JavaCore.INSERT.equals(insertSpaceAfterLambdaArrowOption);
+		}
+		final Object insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE);
+		if (insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption != null) {
+			this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference = JavaCore.INSERT.equals(insertSpaceAfterOpeningAngleBracketInParameterizedTypeReferenceOption);
+		}
+		final Object insertSpaceAfterOpeningAngleBracketInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS);
+		if (insertSpaceAfterOpeningAngleBracketInTypeArgumentsOption != null) {
+			this.insert_space_after_opening_angle_bracket_in_type_arguments = JavaCore.INSERT.equals(insertSpaceAfterOpeningAngleBracketInTypeArgumentsOption);
+		}
+		final Object insertSpaceAfterOpeningAngleBracketInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS);
+		if (insertSpaceAfterOpeningAngleBracketInTypeParametersOption != null) {
+			this.insert_space_after_opening_angle_bracket_in_type_parameters = JavaCore.INSERT.equals(insertSpaceAfterOpeningAngleBracketInTypeParametersOption);
+		}
+		final Object insertSpaceAfterOpeningBracketInArrayAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION);
+		if (insertSpaceAfterOpeningBracketInArrayAllocationExpressionOption != null) {
+			this.insert_space_after_opening_bracket_in_array_allocation_expression = JavaCore.INSERT.equals(insertSpaceAfterOpeningBracketInArrayAllocationExpressionOption);
+		}
+		final Object insertSpaceAfterOpeningBracketInArrayReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_REFERENCE);
+		if (insertSpaceAfterOpeningBracketInArrayReferenceOption != null) {
+			this.insert_space_after_opening_bracket_in_array_reference = JavaCore.INSERT.equals(insertSpaceAfterOpeningBracketInArrayReferenceOption);
+		}
+		final Object insertSpaceAfterOpeningBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER);
+		if (insertSpaceAfterOpeningBraceInArrayInitializerOption != null) {
+			this.insert_space_after_opening_brace_in_array_initializer = JavaCore.INSERT.equals(insertSpaceAfterOpeningBraceInArrayInitializerOption);
+		}
+		final Object insertSpaceAfterOpeningParenInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ANNOTATION);
+		if (insertSpaceAfterOpeningParenInAnnotationOption != null) {
+			this.insert_space_after_opening_paren_in_annotation = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInAnnotationOption);
+		}
+		final Object insertSpaceAfterOpeningParenInCastOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CAST);
+		if (insertSpaceAfterOpeningParenInCastOption != null) {
+			this.insert_space_after_opening_paren_in_cast = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInCastOption);
+		}
+		final Object insertSpaceAfterOpeningParenInCatchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH);
+		if (insertSpaceAfterOpeningParenInCatchOption != null) {
+			this.insert_space_after_opening_paren_in_catch = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInCatchOption);
+		}
+		final Object insertSpaceAfterOpeningParenInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION);
+		if (insertSpaceAfterOpeningParenInConstructorDeclarationOption != null) {
+			this.insert_space_after_opening_paren_in_constructor_declaration = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInConstructorDeclarationOption);
+		}
+		final Object insertSpaceAfterOpeningParenInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_ENUM_CONSTANT);
+		if (insertSpaceAfterOpeningParenInEnumConstantOption != null) {
+			this.insert_space_after_opening_paren_in_enum_constant = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInEnumConstantOption);
+		}
+		final Object insertSpaceAfterOpeningParenInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR);
+		if (insertSpaceAfterOpeningParenInForOption != null) {
+			this.insert_space_after_opening_paren_in_for = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInForOption);
+		}
+		final Object insertSpaceAfterOpeningParenInIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF);
+		if (insertSpaceAfterOpeningParenInIfOption != null) {
+			this.insert_space_after_opening_paren_in_if = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInIfOption);
+		}
+		final Object insertSpaceAfterOpeningParenInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION);
+		if (insertSpaceAfterOpeningParenInMethodDeclarationOption != null) {
+			this.insert_space_after_opening_paren_in_method_declaration = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInMethodDeclarationOption);
+		}
+		final Object insertSpaceAfterOpeningParenInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION);
+		if (insertSpaceAfterOpeningParenInMethodInvocationOption != null) {
+			this.insert_space_after_opening_paren_in_method_invocation = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInMethodInvocationOption);
+		}
+		final Object insertSpaceAfterOpeningParenInParenthesizedExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+		if (insertSpaceAfterOpeningParenInParenthesizedExpressionOption != null) {
+			this.insert_space_after_opening_paren_in_parenthesized_expression = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInParenthesizedExpressionOption);
+		}
+		final Object insertSpaceAfterOpeningParenInSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH);
+		if (insertSpaceAfterOpeningParenInSwitchOption != null) {
+			this.insert_space_after_opening_paren_in_switch = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInSwitchOption);
+		}
+		final Object insertSpaceAfterOpeningParenInSynchronizedOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SYNCHRONIZED);
+		if (insertSpaceAfterOpeningParenInSynchronizedOption != null) {
+			this.insert_space_after_opening_paren_in_synchronized = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInSynchronizedOption);
+		}
+		final Object insertSpaceAfterOpeningParenInTryOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY);
+		if (insertSpaceAfterOpeningParenInTryOption != null) {
+			this.insert_space_after_opening_paren_in_try = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInTryOption);
+		}
+		final Object insertSpaceAfterOpeningParenInWhileOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE);
+		if (insertSpaceAfterOpeningParenInWhileOption != null) {
+			this.insert_space_after_opening_paren_in_while = JavaCore.INSERT.equals(insertSpaceAfterOpeningParenInWhileOption);
+		}
+		final Object insertSpaceAfterPostfixOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR);
+		if (insertSpaceAfterPostfixOperatorOption != null) {
+			this.insert_space_after_postfix_operator = JavaCore.INSERT.equals(insertSpaceAfterPostfixOperatorOption);
+		}
+		final Object insertSpaceAfterPrefixOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR);
+		if (insertSpaceAfterPrefixOperatorOption != null) {
+			this.insert_space_after_prefix_operator = JavaCore.INSERT.equals(insertSpaceAfterPrefixOperatorOption);
+		}
+		final Object insertSpaceAfterQuestionInConditionalOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_CONDITIONAL);
+		if (insertSpaceAfterQuestionInConditionalOption != null) {
+			this.insert_space_after_question_in_conditional = JavaCore.INSERT.equals(insertSpaceAfterQuestionInConditionalOption);
+		}
+		final Object insertSpaceAfterQuestionInWildcardOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_QUESTION_IN_WILDCARD);
+		if (insertSpaceAfterQuestionInWildcardOption != null) {
+			this.insert_space_after_question_in_wilcard = JavaCore.INSERT.equals(insertSpaceAfterQuestionInWildcardOption);
+		}
+		final Object insertSpaceAfterSemicolonInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR);
+		if (insertSpaceAfterSemicolonInForOption != null) {
+			this.insert_space_after_semicolon_in_for = JavaCore.INSERT.equals(insertSpaceAfterSemicolonInForOption);
+		}
+		final Object insertSpaceAfterSemicolonInTryOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES);
+		if (insertSpaceAfterSemicolonInTryOption != null) {
+			this.insert_space_after_semicolon_in_try_resources = JavaCore.INSERT.equals(insertSpaceAfterSemicolonInTryOption);
+		}
+		final Object insertSpaceAfterUnaryOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR);
+		if (insertSpaceAfterUnaryOperatorOption != null) {
+			this.insert_space_after_unary_operator = JavaCore.INSERT.equals(insertSpaceAfterUnaryOperatorOption);
+		}
+		final Object insertSpaceBeforeAndInWildcardOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_AND_IN_TYPE_PARAMETER);
+		if (insertSpaceBeforeAndInWildcardOption != null) {
+			this.insert_space_before_and_in_type_parameter = JavaCore.INSERT.equals(insertSpaceBeforeAndInWildcardOption);
+		}
+		final Object insertSpaceBeforeAtInAnnotationTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_AT_IN_ANNOTATION_TYPE_DECLARATION);
+		if (insertSpaceBeforeAtInAnnotationTypeDeclarationOption != null) {
+			this.insert_space_before_at_in_annotation_type_declaration = JavaCore.INSERT.equals(insertSpaceBeforeAtInAnnotationTypeDeclarationOption);
+		}
+		final Object insertSpaceBeforeAssignmentOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR);
+		if (insertSpaceBeforeAssignmentOperatorOption != null) {
+			this.insert_space_before_assignment_operator = JavaCore.INSERT.equals(insertSpaceBeforeAssignmentOperatorOption);
+		}
+		final Object insertSpaceBeforeBinaryOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR);
+		if (insertSpaceBeforeBinaryOperatorOption != null) {
+			this.insert_space_before_binary_operator = JavaCore.INSERT.equals(insertSpaceBeforeBinaryOperatorOption);
+		}
+		final Object insertSpaceBeforeClosingAngleBracketInParameterizedTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE);
+		if (insertSpaceBeforeClosingAngleBracketInParameterizedTypeReferenceOption != null) {
+			this.insert_space_before_closing_angle_bracket_in_parameterized_type_reference = JavaCore.INSERT.equals(insertSpaceBeforeClosingAngleBracketInParameterizedTypeReferenceOption);
+		}
+		final Object insertSpaceBeforeClosingAngleBracketInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS);
+		if (insertSpaceBeforeClosingAngleBracketInTypeArgumentsOption != null) {
+			this.insert_space_before_closing_angle_bracket_in_type_arguments = JavaCore.INSERT.equals(insertSpaceBeforeClosingAngleBracketInTypeArgumentsOption);
+		}
+		final Object insertSpaceBeforeClosingAngleBracketInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS);
+		if (insertSpaceBeforeClosingAngleBracketInTypeParametersOption != null) {
+			this.insert_space_before_closing_angle_bracket_in_type_parameters = JavaCore.INSERT.equals(insertSpaceBeforeClosingAngleBracketInTypeParametersOption);
+		}
+		final Object insertSpaceBeforeClosingBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER);
+		if (insertSpaceBeforeClosingBraceInArrayInitializerOption != null) {
+			this.insert_space_before_closing_brace_in_array_initializer = JavaCore.INSERT.equals(insertSpaceBeforeClosingBraceInArrayInitializerOption);
+		}
+		final Object insertSpaceBeforeClosingBracketInArrayAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION);
+		if (insertSpaceBeforeClosingBracketInArrayAllocationExpressionOption != null) {
+			this.insert_space_before_closing_bracket_in_array_allocation_expression = JavaCore.INSERT.equals(insertSpaceBeforeClosingBracketInArrayAllocationExpressionOption);
+		}
+		final Object insertSpaceBeforeClosingBracketInArrayReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_REFERENCE);
+		if (insertSpaceBeforeClosingBracketInArrayReferenceOption != null) {
+			this.insert_space_before_closing_bracket_in_array_reference = JavaCore.INSERT.equals(insertSpaceBeforeClosingBracketInArrayReferenceOption);
+		}
+		final Object insertSpaceBeforeClosingParenInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ANNOTATION);
+		if (insertSpaceBeforeClosingParenInAnnotationOption != null) {
+			this.insert_space_before_closing_paren_in_annotation = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInAnnotationOption);
+		}
+		final Object insertSpaceBeforeClosingParenInCastOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CAST);
+		if (insertSpaceBeforeClosingParenInCastOption != null) {
+			this.insert_space_before_closing_paren_in_cast = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInCastOption);
+		}
+		final Object insertSpaceBeforeClosingParenInCatchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH);
+		if (insertSpaceBeforeClosingParenInCatchOption != null) {
+			this.insert_space_before_closing_paren_in_catch = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInCatchOption);
+		}
+		final Object insertSpaceBeforeClosingParenInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CONSTRUCTOR_DECLARATION);
+		if (insertSpaceBeforeClosingParenInConstructorDeclarationOption != null) {
+			this.insert_space_before_closing_paren_in_constructor_declaration = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInConstructorDeclarationOption);
+		}
+		final Object insertSpaceBeforeClosingParenInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_ENUM_CONSTANT);
+		if (insertSpaceBeforeClosingParenInEnumConstantOption != null) {
+			this.insert_space_before_closing_paren_in_enum_constant = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInEnumConstantOption);
+		}
+		final Object insertSpaceBeforeClosingParenInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR);
+		if (insertSpaceBeforeClosingParenInForOption != null) {
+			this.insert_space_before_closing_paren_in_for = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInForOption);
+		}
+		final Object insertSpaceBeforeClosingParenInIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF);
+		if (insertSpaceBeforeClosingParenInIfOption != null) {
+			this.insert_space_before_closing_paren_in_if = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInIfOption);
+		}
+		final Object insertSpaceBeforeClosingParenInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION);
+		if (insertSpaceBeforeClosingParenInMethodDeclarationOption != null) {
+			this.insert_space_before_closing_paren_in_method_declaration = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInMethodDeclarationOption);
+		}
+		final Object insertSpaceBeforeClosingParenInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION);
+		if (insertSpaceBeforeClosingParenInMethodInvocationOption != null) {
+			this.insert_space_before_closing_paren_in_method_invocation = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInMethodInvocationOption);
+		}
+		final Object insertSpaceBeforeClosingParenInParenthesizedExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+		if (insertSpaceBeforeClosingParenInParenthesizedExpressionOption != null) {
+			this.insert_space_before_closing_paren_in_parenthesized_expression = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInParenthesizedExpressionOption);
+		}
+		final Object insertSpaceBeforeClosingParenInSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH);
+		if (insertSpaceBeforeClosingParenInSwitchOption != null) {
+			this.insert_space_before_closing_paren_in_switch = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInSwitchOption);
+		}
+		final Object insertSpaceBeforeClosingParenInSynchronizedOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SYNCHRONIZED);
+		if (insertSpaceBeforeClosingParenInSynchronizedOption != null) {
+			this.insert_space_before_closing_paren_in_synchronized = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInSynchronizedOption);
+		}
+		final Object insertSpaceBeforeClosingParenInTryOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY);
+		if (insertSpaceBeforeClosingParenInTryOption != null) {
+			this.insert_space_before_closing_paren_in_try = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInTryOption);
+		}
+		final Object insertSpaceBeforeClosingParenInWhileOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE);
+		if (insertSpaceBeforeClosingParenInWhileOption != null) {
+			this.insert_space_before_closing_paren_in_while = JavaCore.INSERT.equals(insertSpaceBeforeClosingParenInWhileOption);
+		}
+		final Object insertSpaceBeforeColonInAssertOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_ASSERT);
+		if (insertSpaceBeforeColonInAssertOption != null) {
+			this.insert_space_before_colon_in_assert = JavaCore.INSERT.equals(insertSpaceBeforeColonInAssertOption);
+		}
+		final Object insertSpaceBeforeColonInCaseOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CASE);
+		if (insertSpaceBeforeColonInCaseOption != null) {
+			this.insert_space_before_colon_in_case = JavaCore.INSERT.equals(insertSpaceBeforeColonInCaseOption);
+		}
+		final Object insertSpaceBeforeColonInConditionalOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_CONDITIONAL);
+		if (insertSpaceBeforeColonInConditionalOption != null) {
+			this.insert_space_before_colon_in_conditional = JavaCore.INSERT.equals(insertSpaceBeforeColonInConditionalOption);
+		}
+		final Object insertSpaceBeforeColonInDefaultOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_DEFAULT);
+		if (insertSpaceBeforeColonInDefaultOption != null) {
+			this.insert_space_before_colon_in_default = JavaCore.INSERT.equals(insertSpaceBeforeColonInDefaultOption);
+		}
+		final Object insertSpaceBeforeColonInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_FOR);
+		if (insertSpaceBeforeColonInForOption != null) {
+			this.insert_space_before_colon_in_for = JavaCore.INSERT.equals(insertSpaceBeforeColonInForOption);
+		}
+		final Object insertSpaceBeforeColonInLabeledStatementOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COLON_IN_LABELED_STATEMENT);
+		if (insertSpaceBeforeColonInLabeledStatementOption != null) {
+			this.insert_space_before_colon_in_labeled_statement = JavaCore.INSERT.equals(insertSpaceBeforeColonInLabeledStatementOption);
+		}
+		final Object insertSpaceBeforeCommaInAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ALLOCATION_EXPRESSION);
+		if (insertSpaceBeforeCommaInAllocationExpressionOption != null) {
+			this.insert_space_before_comma_in_allocation_expression = JavaCore.INSERT.equals(insertSpaceBeforeCommaInAllocationExpressionOption);
+		}
+		final Object insertSpaceBeforeCommaInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ANNOTATION);
+		if (insertSpaceBeforeCommaInAnnotationOption != null) {
+			this.insert_space_before_comma_in_annotation = JavaCore.INSERT.equals(insertSpaceBeforeCommaInAnnotationOption);
+		}
+		final Object insertSpaceBeforeCommaInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ARRAY_INITIALIZER);
+		if (insertSpaceBeforeCommaInArrayInitializerOption != null) {
+			this.insert_space_before_comma_in_array_initializer = JavaCore.INSERT.equals(insertSpaceBeforeCommaInArrayInitializerOption);
+		}
+		final Object insertSpaceBeforeCommaInConstructorDeclarationParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS);
+		if (insertSpaceBeforeCommaInConstructorDeclarationParametersOption != null) {
+			this.insert_space_before_comma_in_constructor_declaration_parameters = JavaCore.INSERT.equals(insertSpaceBeforeCommaInConstructorDeclarationParametersOption);
+		}
+		final Object insertSpaceBeforeCommaInConstructorDeclarationThrowsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS);
+		if (insertSpaceBeforeCommaInConstructorDeclarationThrowsOption != null) {
+			this.insert_space_before_comma_in_constructor_declaration_throws = JavaCore.INSERT.equals(insertSpaceBeforeCommaInConstructorDeclarationThrowsOption);
+		}
+		final Object insertSpaceBeforeCommaInEnumConstantArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_CONSTANT_ARGUMENTS);
+		if (insertSpaceBeforeCommaInEnumConstantArgumentsOption != null) {
+			this.insert_space_before_comma_in_enum_constant_arguments = JavaCore.INSERT.equals(insertSpaceBeforeCommaInEnumConstantArgumentsOption);
+		}
+		final Object insertSpaceBeforeCommaInEnumDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_ENUM_DECLARATIONS);
+		if (insertSpaceBeforeCommaInEnumDeclarationsOption != null) {
+			this.insert_space_before_comma_in_enum_declarations = JavaCore.INSERT.equals(insertSpaceBeforeCommaInEnumDeclarationsOption);
+		}
+		final Object insertSpaceBeforeCommaInExplicitConstructorCallArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS);
+		if (insertSpaceBeforeCommaInExplicitConstructorCallArgumentsOption != null) {
+			this.insert_space_before_comma_in_explicit_constructor_call_arguments = JavaCore.INSERT.equals(insertSpaceBeforeCommaInExplicitConstructorCallArgumentsOption);
+		}
+		final Object insertSpaceBeforeCommaInForIncrementsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INCREMENTS);
+		if (insertSpaceBeforeCommaInForIncrementsOption != null) {
+			this.insert_space_before_comma_in_for_increments = JavaCore.INSERT.equals(insertSpaceBeforeCommaInForIncrementsOption);
+		}
+		final Object insertSpaceBeforeCommaInForInitsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS);
+		if (insertSpaceBeforeCommaInForInitsOption != null) {
+			this.insert_space_before_comma_in_for_inits = JavaCore.INSERT.equals(insertSpaceBeforeCommaInForInitsOption);
+		}
+		final Object insertSpaceBeforeCommaInMethodInvocationArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS);
+		if (insertSpaceBeforeCommaInMethodInvocationArgumentsOption != null) {
+			this.insert_space_before_comma_in_method_invocation_arguments = JavaCore.INSERT.equals(insertSpaceBeforeCommaInMethodInvocationArgumentsOption);
+		}
+		final Object insertSpaceBeforeCommaInMethodDeclarationParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS);
+		if (insertSpaceBeforeCommaInMethodDeclarationParametersOption != null) {
+			this.insert_space_before_comma_in_method_declaration_parameters = JavaCore.INSERT.equals(insertSpaceBeforeCommaInMethodDeclarationParametersOption);
+		}
+		final Object insertSpaceBeforeCommaInMethodDeclarationThrowsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS);
+		if (insertSpaceBeforeCommaInMethodDeclarationThrowsOption != null) {
+			this.insert_space_before_comma_in_method_declaration_throws = JavaCore.INSERT.equals(insertSpaceBeforeCommaInMethodDeclarationThrowsOption);
+		}
+		final Object insertSpaceBeforeCommaInMultipleFieldDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_FIELD_DECLARATIONS);
+		if (insertSpaceBeforeCommaInMultipleFieldDeclarationsOption != null) {
+			this.insert_space_before_comma_in_multiple_field_declarations = JavaCore.INSERT.equals(insertSpaceBeforeCommaInMultipleFieldDeclarationsOption);
+		}
+		final Object insertSpaceBeforeCommaInMultipleLocalDeclarationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MULTIPLE_LOCAL_DECLARATIONS);
+		if (insertSpaceBeforeCommaInMultipleLocalDeclarationsOption != null) {
+			this.insert_space_before_comma_in_multiple_local_declarations = JavaCore.INSERT.equals(insertSpaceBeforeCommaInMultipleLocalDeclarationsOption);
+		}
+		final Object insertSpaceBeforeCommaInParameterizedTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE);
+		if (insertSpaceBeforeCommaInParameterizedTypeReferenceOption != null) {
+			this.insert_space_before_comma_in_parameterized_type_reference = JavaCore.INSERT.equals(insertSpaceBeforeCommaInParameterizedTypeReferenceOption);
+		}
+		final Object insertSpaceBeforeCommaInSuperinterfacesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_SUPERINTERFACES);
+		if (insertSpaceBeforeCommaInSuperinterfacesOption != null) {
+			this.insert_space_before_comma_in_superinterfaces = JavaCore.INSERT.equals(insertSpaceBeforeCommaInSuperinterfacesOption);
+		}
+		final Object insertSpaceBeforeCommaInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_ARGUMENTS);
+		if (insertSpaceBeforeCommaInTypeArgumentsOption != null) {
+			this.insert_space_before_comma_in_type_arguments = JavaCore.INSERT.equals(insertSpaceBeforeCommaInTypeArgumentsOption);
+		}
+		final Object insertSpaceBeforeCommaInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_TYPE_PARAMETERS);
+		if (insertSpaceBeforeCommaInTypeParametersOption != null) {
+			this.insert_space_before_comma_in_type_parameters = JavaCore.INSERT.equals(insertSpaceBeforeCommaInTypeParametersOption);
+		}
+		final Object insertSpaceBeforeEllipsisOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ELLIPSIS);
+		if (insertSpaceBeforeEllipsisOption != null) {
+			this.insert_space_before_ellipsis = JavaCore.INSERT.equals(insertSpaceBeforeEllipsisOption);
+		}
+		final Object insertSpaceBeforeLambdaArrowOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_ARROW);
+		if (insertSpaceBeforeLambdaArrowOption != null) {
+			this.insert_space_before_lambda_arrow = JavaCore.INSERT.equals(insertSpaceBeforeLambdaArrowOption);
+		}
+		final Object insertSpaceBeforeOpeningAngleBrackerInParameterizedTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE);
+		if (insertSpaceBeforeOpeningAngleBrackerInParameterizedTypeReferenceOption != null) {
+			this.insert_space_before_opening_angle_bracket_in_parameterized_type_reference = JavaCore.INSERT.equals(insertSpaceBeforeOpeningAngleBrackerInParameterizedTypeReferenceOption);
+		}
+		final Object insertSpaceBeforeOpeningAngleBrackerInTypeArgumentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS);
+		if (insertSpaceBeforeOpeningAngleBrackerInTypeArgumentsOption != null) {
+			this.insert_space_before_opening_angle_bracket_in_type_arguments = JavaCore.INSERT.equals(insertSpaceBeforeOpeningAngleBrackerInTypeArgumentsOption);
+		}
+		final Object insertSpaceBeforeOpeningAngleBrackerInTypeParametersOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS);
+		if (insertSpaceBeforeOpeningAngleBrackerInTypeParametersOption != null) {
+			this.insert_space_before_opening_angle_bracket_in_type_parameters = JavaCore.INSERT.equals(insertSpaceBeforeOpeningAngleBrackerInTypeParametersOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInAnnotationTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANNOTATION_TYPE_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInAnnotationTypeDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_annotation_type_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInAnnotationTypeDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInAnonymousTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANONYMOUS_TYPE_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInAnonymousTypeDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_anonymous_type_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInAnonymousTypeDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ARRAY_INITIALIZER);
+		if (insertSpaceBeforeOpeningBraceInArrayInitializerOption != null) {
+			this.insert_space_before_opening_brace_in_array_initializer = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInArrayInitializerOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK);
+		if (insertSpaceBeforeOpeningBraceInBlockOption != null) {
+			this.insert_space_before_opening_brace_in_block = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInBlockOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_CONSTRUCTOR_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInConstructorDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_constructor_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInConstructorDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInEnumDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_enum_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInEnumDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ENUM_CONSTANT);
+		if (insertSpaceBeforeOpeningBraceInEnumConstantOption != null) {
+			this.insert_space_before_opening_brace_in_enum_constant = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInEnumConstantOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInMethodDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_method_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInMethodDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION);
+		if (insertSpaceBeforeOpeningBraceInTypeDeclarationOption != null) {
+			this.insert_space_before_opening_brace_in_type_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInTypeDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningBracketInArrayAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_ALLOCATION_EXPRESSION);
+		if (insertSpaceBeforeOpeningBracketInArrayAllocationExpressionOption != null) {
+			this.insert_space_before_opening_bracket_in_array_allocation_expression = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBracketInArrayAllocationExpressionOption);
+		}
+		final Object insertSpaceBeforeOpeningBracketInArrayReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_REFERENCE);
+		if (insertSpaceBeforeOpeningBracketInArrayReferenceOption != null) {
+			this.insert_space_before_opening_bracket_in_array_reference = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBracketInArrayReferenceOption);
+		}
+		final Object insertSpaceBeforeOpeningBracketInArrayTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_TYPE_REFERENCE);
+		if (insertSpaceBeforeOpeningBracketInArrayTypeReferenceOption != null) {
+			this.insert_space_before_opening_bracket_in_array_type_reference = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBracketInArrayTypeReferenceOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION);
+		if (insertSpaceBeforeOpeningParenInAnnotationOption != null) {
+			this.insert_space_before_opening_paren_in_annotation = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInAnnotationOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInAnnotationTypeMemberDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ANNOTATION_TYPE_MEMBER_DECLARATION);
+		if (insertSpaceBeforeOpeningParenInAnnotationTypeMemberDeclarationOption != null) {
+			this.insert_space_before_opening_paren_in_annotation_type_member_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInAnnotationTypeMemberDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInCatchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH);
+		if (insertSpaceBeforeOpeningParenInCatchOption != null) {
+			this.insert_space_before_opening_paren_in_catch = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInCatchOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION);
+		if (insertSpaceBeforeOpeningParenInConstructorDeclarationOption != null) {
+			this.insert_space_before_opening_paren_in_constructor_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInConstructorDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_ENUM_CONSTANT);
+		if (insertSpaceBeforeOpeningParenInEnumConstantOption != null) {
+			this.insert_space_before_opening_paren_in_enum_constant = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInEnumConstantOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR);
+		if (insertSpaceBeforeOpeningParenInForOption != null) {
+			this.insert_space_before_opening_paren_in_for = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInForOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF);
+		if (insertSpaceBeforeOpeningParenInIfOption != null) {
+			this.insert_space_before_opening_paren_in_if = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInIfOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION);
+		if (insertSpaceBeforeOpeningParenInMethodInvocationOption != null) {
+			this.insert_space_before_opening_paren_in_method_invocation = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInMethodInvocationOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION);
+		if (insertSpaceBeforeOpeningParenInMethodDeclarationOption != null) {
+			this.insert_space_before_opening_paren_in_method_declaration = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInMethodDeclarationOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH);
+		if (insertSpaceBeforeOpeningParenInSwitchOption != null) {
+			this.insert_space_before_opening_paren_in_switch = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInSwitchOption);
+		}
+		final Object insertSpaceBeforeOpeningBraceInSwitchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH);
+		if (insertSpaceBeforeOpeningBraceInSwitchOption != null) {
+			this.insert_space_before_opening_brace_in_switch = JavaCore.INSERT.equals(insertSpaceBeforeOpeningBraceInSwitchOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInSynchronizedOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SYNCHRONIZED);
+		if (insertSpaceBeforeOpeningParenInSynchronizedOption != null) {
+			this.insert_space_before_opening_paren_in_synchronized = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInSynchronizedOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInTryOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY);
+		if (insertSpaceBeforeOpeningParenInTryOption != null) {
+			this.insert_space_before_opening_paren_in_try = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInTryOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInParenthesizedExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION);
+		if (insertSpaceBeforeOpeningParenInParenthesizedExpressionOption != null) {
+			this.insert_space_before_opening_paren_in_parenthesized_expression = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInParenthesizedExpressionOption);
+		}
+		final Object insertSpaceBeforeOpeningParenInWhileOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE);
+		if (insertSpaceBeforeOpeningParenInWhileOption != null) {
+			this.insert_space_before_opening_paren_in_while = JavaCore.INSERT.equals(insertSpaceBeforeOpeningParenInWhileOption);
+		}
+		final Object insertSpaceBeforeParenthesizedExpressionInReturnOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_RETURN);
+		if (insertSpaceBeforeParenthesizedExpressionInReturnOption != null) {
+			this.insert_space_before_parenthesized_expression_in_return = JavaCore.INSERT.equals(insertSpaceBeforeParenthesizedExpressionInReturnOption);
+		}
+		final Object insertSpaceBeforeParenthesizedExpressionInThrowOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_THROW);
+		if (insertSpaceBeforeParenthesizedExpressionInThrowOption != null) {
+			this.insert_space_before_parenthesized_expression_in_throw = JavaCore.INSERT.equals(insertSpaceBeforeParenthesizedExpressionInThrowOption);
+		}
+		final Object insertSpaceBeforePostfixOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR);
+		if (insertSpaceBeforePostfixOperatorOption != null) {
+			this.insert_space_before_postfix_operator = JavaCore.INSERT.equals(insertSpaceBeforePostfixOperatorOption);
+		}
+		final Object insertSpaceBeforePrefixOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR);
+		if (insertSpaceBeforePrefixOperatorOption != null) {
+			this.insert_space_before_prefix_operator = JavaCore.INSERT.equals(insertSpaceBeforePrefixOperatorOption);
+		}
+		final Object insertSpaceBeforeQuestionInConditionalOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_CONDITIONAL);
+		if (insertSpaceBeforeQuestionInConditionalOption != null) {
+			this.insert_space_before_question_in_conditional = JavaCore.INSERT.equals(insertSpaceBeforeQuestionInConditionalOption);
+		}
+		final Object insertSpaceBeforeQuestionInWildcardOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_QUESTION_IN_WILDCARD);
+		if (insertSpaceBeforeQuestionInWildcardOption != null) {
+			this.insert_space_before_question_in_wilcard = JavaCore.INSERT.equals(insertSpaceBeforeQuestionInWildcardOption);
+		}
+		final Object insertSpaceBeforeSemicolonOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON);
+		if (insertSpaceBeforeSemicolonOption != null) {
+			this.insert_space_before_semicolon = JavaCore.INSERT.equals(insertSpaceBeforeSemicolonOption);
+		}
+		final Object insertSpaceBeforeSemicolonInForOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR);
+		if (insertSpaceBeforeSemicolonInForOption != null) {
+			this.insert_space_before_semicolon_in_for = JavaCore.INSERT.equals(insertSpaceBeforeSemicolonInForOption);
+		}
+		final Object insertSpaceBeforeSemicolonInTryOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES);
+		if (insertSpaceBeforeSemicolonInTryOption != null) {
+			this.insert_space_before_semicolon_in_try_resources = JavaCore.INSERT.equals(insertSpaceBeforeSemicolonInTryOption);
+		}
+		final Object insertSpaceBeforeUnaryOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_UNARY_OPERATOR);
+		if (insertSpaceBeforeUnaryOperatorOption != null) {
+			this.insert_space_before_unary_operator = JavaCore.INSERT.equals(insertSpaceBeforeUnaryOperatorOption);
+		}
+		final Object insertSpaceBetweenBracketsInArrayTypeReferenceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_BRACKETS_IN_ARRAY_TYPE_REFERENCE);
+		if (insertSpaceBetweenBracketsInArrayTypeReferenceOption != null) {
+			this.insert_space_between_brackets_in_array_type_reference = JavaCore.INSERT.equals(insertSpaceBetweenBracketsInArrayTypeReferenceOption);
+		}
+		final Object insertSpaceBetweenEmptyBracesInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_ARRAY_INITIALIZER);
+		if (insertSpaceBetweenEmptyBracesInArrayInitializerOption != null) {
+			this.insert_space_between_empty_braces_in_array_initializer = JavaCore.INSERT.equals(insertSpaceBetweenEmptyBracesInArrayInitializerOption);
+		}
+		final Object insertSpaceBetweenEmptyBracketsInArrayAllocationExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACKETS_IN_ARRAY_ALLOCATION_EXPRESSION);
+		if (insertSpaceBetweenEmptyBracketsInArrayAllocationExpressionOption != null) {
+			this.insert_space_between_empty_brackets_in_array_allocation_expression = JavaCore.INSERT.equals(insertSpaceBetweenEmptyBracketsInArrayAllocationExpressionOption);
+		}
+		final Object insertSpaceBetweenEmptyParensInConstructorDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_CONSTRUCTOR_DECLARATION);
+		if (insertSpaceBetweenEmptyParensInConstructorDeclarationOption != null) {
+			this.insert_space_between_empty_parens_in_constructor_declaration = JavaCore.INSERT.equals(insertSpaceBetweenEmptyParensInConstructorDeclarationOption);
+		}
+		final Object insertSpaceBetweenEmptyParensInAnnotationTypeMemberDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ANNOTATION_TYPE_MEMBER_DECLARATION);
+		if (insertSpaceBetweenEmptyParensInAnnotationTypeMemberDeclarationOption != null) {
+			this.insert_space_between_empty_parens_in_annotation_type_member_declaration = JavaCore.INSERT.equals(insertSpaceBetweenEmptyParensInAnnotationTypeMemberDeclarationOption);
+		}
+		final Object insertSpaceBetweenEmptyParensInEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_ENUM_CONSTANT);
+		if (insertSpaceBetweenEmptyParensInEnumConstantOption != null) {
+			this.insert_space_between_empty_parens_in_enum_constant = JavaCore.INSERT.equals(insertSpaceBetweenEmptyParensInEnumConstantOption);
+		}
+		final Object insertSpaceBetweenEmptyParensInMethodDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION);
+		if (insertSpaceBetweenEmptyParensInMethodDeclarationOption != null) {
+			this.insert_space_between_empty_parens_in_method_declaration = JavaCore.INSERT.equals(insertSpaceBetweenEmptyParensInMethodDeclarationOption);
+		}
+		final Object insertSpaceBetweenEmptyParensInMethodInvocationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION);
+		if (insertSpaceBetweenEmptyParensInMethodInvocationOption != null) {
+			this.insert_space_between_empty_parens_in_method_invocation = JavaCore.INSERT.equals(insertSpaceBetweenEmptyParensInMethodInvocationOption);
+		}
+		final Object compactElseIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF);
+		if (compactElseIfOption != null) {
+			this.compact_else_if = DefaultCodeFormatterConstants.TRUE.equals(compactElseIfOption);
+		}
+		final Object keepGuardianClauseOnOneLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE);
+		if (keepGuardianClauseOnOneLineOption != null) {
+			this.keep_guardian_clause_on_one_line = DefaultCodeFormatterConstants.TRUE.equals(keepGuardianClauseOnOneLineOption);
+		}
+		final Object keepElseStatementOnSameLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ELSE_STATEMENT_ON_SAME_LINE);
+		if (keepElseStatementOnSameLineOption != null) {
+			this.keep_else_statement_on_same_line = DefaultCodeFormatterConstants.TRUE.equals(keepElseStatementOnSameLineOption);
+		}
+		final Object keepEmptyArrayInitializerOnOneLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE);
+		if (keepEmptyArrayInitializerOnOneLineOption != null) {
+			this.keep_empty_array_initializer_on_one_line = DefaultCodeFormatterConstants.TRUE.equals(keepEmptyArrayInitializerOnOneLineOption);
+		}
+		final Object keepSimpleIfOnOneLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE);
+		if (keepSimpleIfOnOneLineOption != null) {
+			this.keep_simple_if_on_one_line = DefaultCodeFormatterConstants.TRUE.equals(keepSimpleIfOnOneLineOption);
+		}
+		final Object keepThenStatementOnSameLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE);
+		if (keepThenStatementOnSameLineOption != null) {
+			this.keep_then_statement_on_same_line = DefaultCodeFormatterConstants.TRUE.equals(keepThenStatementOnSameLineOption);
+		}
+		final Object neverIndentBlockCommentOnFirstColumnOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN);
+		if (neverIndentBlockCommentOnFirstColumnOption != null) {
+			this.never_indent_block_comments_on_first_column = DefaultCodeFormatterConstants.TRUE.equals(neverIndentBlockCommentOnFirstColumnOption);
+		}
+		final Object neverIndentLineCommentOnFirstColumnOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN);
+		if (neverIndentLineCommentOnFirstColumnOption != null) {
+			this.never_indent_line_comments_on_first_column = DefaultCodeFormatterConstants.TRUE.equals(neverIndentLineCommentOnFirstColumnOption);
+		}
+		final Object numberOfEmptyLinesToPreserveOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE);
+		if (numberOfEmptyLinesToPreserveOption != null) {
+			try {
+				this.number_of_empty_lines_to_preserve = Integer.parseInt((String) numberOfEmptyLinesToPreserveOption);
+			} catch (NumberFormatException e) {
+				this.number_of_empty_lines_to_preserve = 0;
+			} catch(ClassCastException e) {
+				this.number_of_empty_lines_to_preserve = 0;
+			}
+		}
+		final Object joinLinesInCommentsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS);
+		if (joinLinesInCommentsOption != null) {
+			this.join_lines_in_comments = DefaultCodeFormatterConstants.TRUE.equals(joinLinesInCommentsOption);
+		}
+		final Object joinWrappedLinesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES);
+		if (joinWrappedLinesOption != null) {
+			this.join_wrapped_lines = DefaultCodeFormatterConstants.TRUE.equals(joinWrappedLinesOption);
+		}
+		final Object putEmptyStatementOnNewLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE);
+		if (putEmptyStatementOnNewLineOption != null) {
+			this.put_empty_statement_on_new_line = DefaultCodeFormatterConstants.TRUE.equals(putEmptyStatementOnNewLineOption);
+		}
+		final Object tabSizeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE);
+		if (tabSizeOption != null) {
+			try {
+				this.tab_size = Integer.parseInt((String) tabSizeOption);
+			} catch (NumberFormatException e) {
+				this.tab_size = 4;
+			} catch(ClassCastException e) {
+				this.tab_size = 4;
+			}
+		}
+		final Object useTabsOnlyForLeadingIndentationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS);
+		if (useTabsOnlyForLeadingIndentationsOption != null) {
+			this.use_tabs_only_for_leading_indentations = DefaultCodeFormatterConstants.TRUE.equals(useTabsOnlyForLeadingIndentationsOption);
+		}
+		final Object pageWidthOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT);
+		if (pageWidthOption != null) {
+			try {
+				this.page_width = Integer.parseInt((String) pageWidthOption);
+			} catch (NumberFormatException e) {
+				this.page_width = 80;
+			} catch(ClassCastException e) {
+				this.page_width = 80;
+			}
+		}
+		final Object useTabOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+		if (useTabOption != null) {
+			if (JavaCore.TAB.equals(useTabOption)) {
+				this.tab_char = TAB;
+			} else if (JavaCore.SPACE.equals(useTabOption)) {
+				this.tab_char = SPACE;
+			} else {
+				this.tab_char = MIXED;
+			}
+		}
+		final Object wrapBeforeBinaryOperatorOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_BINARY_OPERATOR);
+		if (wrapBeforeBinaryOperatorOption != null) {
+			this.wrap_before_binary_operator = DefaultCodeFormatterConstants.TRUE.equals(wrapBeforeBinaryOperatorOption);
+		}
+		final Object wrapBeforeOrOperatorMulticatchOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH);
+		if (wrapBeforeOrOperatorMulticatchOption != null) {
+			this.wrap_before_or_operator_multicatch = DefaultCodeFormatterConstants.TRUE.equals(wrapBeforeOrOperatorMulticatchOption);
+		}
+		final Object useTags = settings.get(DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS);
+		if (useTags != null) {
+			this.use_tags = DefaultCodeFormatterConstants.TRUE.equals(useTags);
+		}
+		final Object disableTagOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG);
+		if (disableTagOption != null) {
+			if (disableTagOption instanceof String) {
+				String stringValue = (String) disableTagOption;
+				int idx = stringValue.indexOf('\n');
+				if (idx == 0) {
+					this.disabling_tag = null;
+				} else {
+					String tag = idx < 0 ? stringValue.trim() : stringValue.substring(0, idx).trim();
+					if (tag.length() == 0) {
+						this.disabling_tag = null;
+					} else {
+						this.disabling_tag = tag.toCharArray();
+					}
+				}
+			}
+		}
+		final Object enableTagOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG);
+		if (enableTagOption != null) {
+			if (enableTagOption instanceof String) {
+				String stringValue = (String) enableTagOption;
+				int idx = stringValue.indexOf('\n');
+				if (idx == 0) {
+					this.enabling_tag = null;
+				} else {
+					String tag = idx < 0 ? stringValue.trim() : stringValue.substring(0, idx).trim();
+					if (tag.length() == 0) {
+						this.enabling_tag = null;
+					} else {
+						this.enabling_tag = tag.toCharArray();
+					}
+				}
+			}
+		}
+		final Object wrapWrapOuterExpressionsWhenNestedOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_WRAP_OUTER_EXPRESSIONS_WHEN_NESTED);
+		if (wrapWrapOuterExpressionsWhenNestedOption != null) {
+			this.wrap_outer_expressions_when_nested = DefaultCodeFormatterConstants.TRUE.equals(wrapWrapOuterExpressionsWhenNestedOption);
+		}
+	}
+
+	/**
+	 * This method is used to handle deprecated preferences which might be replaced by
+	 * one or more preferences.
+	 * Depending on deprecated option handling policy, set the new formatting option(s).
+	 * @param settings the given map
+	 * @deprecated
+	 */
+	private void setDeprecatedOptions(Map settings) {
+		// backward compatibility code
+		final Object commentClearBlankLinesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES);
+		if (commentClearBlankLinesOption != null) {
+			this.comment_clear_blank_lines_in_javadoc_comment = DefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesOption);
+			this.comment_clear_blank_lines_in_block_comment = DefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesOption);
+		} else {
+			final Object commentClearBlankLinesInJavadocCommentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT);
+			if (commentClearBlankLinesInJavadocCommentOption != null) {
+				this.comment_clear_blank_lines_in_javadoc_comment = DefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesInJavadocCommentOption);
+			}
+			final Object commentClearBlankLinesInBlockCommentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT);
+			if (commentClearBlankLinesInBlockCommentOption != null) {
+				this.comment_clear_blank_lines_in_block_comment = DefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesInBlockCommentOption);
+			}
+		}
+		
+		// New line after annotations
+		final Object insertNewLineAfterAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION);
+		
+		final Object insertNewLineAfterAnnotationOnMemberOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER);
+		final Object insertNewLineAfterAnnotationOnTypeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE);
+		final Object insertNewLineAfterAnnotationOnFieldOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD);
+		final Object insertNewLineAfterAnnotationOnMethodOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD);
+		final Object insertNewLineAfterAnnotationOnPackageOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE);
+		
+		final Object insertNewLineAfterAnnotationOnParameterOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER);
+		final Object insertNewLineAfterAnnotationOnLocalVariableOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE);
+
+		if (insertNewLineAfterAnnotationOnTypeOption == null
+				&& insertNewLineAfterAnnotationOnFieldOption == null
+				&& insertNewLineAfterAnnotationOnMethodOption == null
+				&& insertNewLineAfterAnnotationOnPackageOption == null) {
+			// if none of the new 3.7 options is used, fall back to the deprecated 3.4 option
+			if (insertNewLineAfterAnnotationOnMemberOption != null) {
+				boolean insert = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnMemberOption);
+				this.insert_new_line_after_annotation_on_type = insert;
+				this.insert_new_line_after_annotation_on_field = insert;
+				this.insert_new_line_after_annotation_on_method = insert;
+				this.insert_new_line_after_annotation_on_package = insert;
+				
+				// and use the other 3.4 options if available
+				if (insertNewLineAfterAnnotationOnParameterOption != null) {
+					this.insert_new_line_after_annotation_on_parameter = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnParameterOption);
+				}
+				if (insertNewLineAfterAnnotationOnLocalVariableOption != null) {
+					this.insert_new_line_after_annotation_on_local_variable = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnLocalVariableOption);
+				}
+				
+			} else if (insertNewLineAfterAnnotationOnParameterOption == null
+					&& insertNewLineAfterAnnotationOnLocalVariableOption == null) {
+				// if none of the new 3.4 options is used, fall back to the deprecated 3.1 option
+				if (insertNewLineAfterAnnotationOption != null) {
+					boolean insert = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOption);
+					this.insert_new_line_after_annotation_on_type = insert;
+					this.insert_new_line_after_annotation_on_field = insert;
+					this.insert_new_line_after_annotation_on_method = insert;
+					this.insert_new_line_after_annotation_on_package = insert;
+					this.insert_new_line_after_annotation_on_parameter = insert;
+					this.insert_new_line_after_annotation_on_local_variable = insert;
+				}
+			}
+		} else { // otherwise use new 3.7 options if available
+			if (insertNewLineAfterAnnotationOnTypeOption != null) {
+				this.insert_new_line_after_annotation_on_type = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnTypeOption);
+			}
+			if (insertNewLineAfterAnnotationOnFieldOption != null) {
+				this.insert_new_line_after_annotation_on_field = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnFieldOption);
+			}
+			if (insertNewLineAfterAnnotationOnMethodOption != null) {
+				this.insert_new_line_after_annotation_on_method = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnMethodOption);
+			}
+			if (insertNewLineAfterAnnotationOnPackageOption != null) {
+				this.insert_new_line_after_annotation_on_package = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnPackageOption);
+			}
+			// and the other 3.4 options if available
+			if (insertNewLineAfterAnnotationOnParameterOption != null) {
+				this.insert_new_line_after_annotation_on_parameter = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnParameterOption);
+			}
+			if (insertNewLineAfterAnnotationOnLocalVariableOption != null) {
+				this.insert_new_line_after_annotation_on_local_variable = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnLocalVariableOption);
+			}
+		}
+	}
+
+	public void setDefaultSettings() {
+		this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_annotation = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_arguments_in_enum_constant = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_explicit_constructor_call = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_qualified_allocation_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_assignment = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_compact_if = Alignment.M_ONE_PER_LINE_SPLIT | Alignment.M_INDENT_BY_ONE;
+		this.alignment_for_conditional_expression = Alignment.M_ONE_PER_LINE_SPLIT;
+		this.alignment_for_enum_constants = Alignment.NONE;
+		this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_method_declaration = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_resources_in_try = Alignment.M_NEXT_PER_LINE_SPLIT;
+		this.alignment_for_selector_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_superclass_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+		this.alignment_for_superinterfaces_in_enum_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+		this.alignment_for_superinterfaces_in_type_declaration = Alignment.M_NEXT_SHIFTED_SPLIT;
+		this.alignment_for_throws_clause_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_union_type_in_multicatch = Alignment.M_COMPACT_SPLIT;
+		this.align_type_members_on_columns = false;
+		this.brace_position_for_annotation_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_anonymous_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_array_initializer = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_block = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_block_in_case = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_constructor_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_enum_constant = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_enum_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_lambda_body = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_method_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_switch = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.comment_clear_blank_lines_in_block_comment = false;
+		this.comment_clear_blank_lines_in_javadoc_comment = false;
+		this.comment_format_block_comment = true;
+		this.comment_format_javadoc_comment = true;
+		this.comment_format_line_comment = true;
+		this.comment_format_line_comment_starting_on_first_column = true;
+		this.comment_format_header = false;
+		this.comment_format_html = true;
+		this.comment_format_source = true;
+		this.comment_indent_parameter_description = true;
+		this.comment_indent_root_tags = true;
+		this.comment_insert_empty_line_before_root_tags = true;
+		this.comment_insert_new_line_for_parameter = true;
+		this.comment_new_lines_at_block_boundaries = true;
+		this.comment_new_lines_at_javadoc_boundaries = true;
+		this.comment_line_length = 80;
+		this.comment_preserve_white_space_between_code_and_line_comments= false; 
+		this.continuation_indentation = 2;
+		this.continuation_indentation_for_array_initializer = 2;
+		this.blank_lines_after_imports = 0;
+		this.blank_lines_after_package = 0;
+		this.blank_lines_before_field = 0;
+		this.blank_lines_before_first_class_body_declaration = 0;
+		this.blank_lines_before_imports = 0;
+		this.blank_lines_before_member_type = 0;
+		this.blank_lines_before_method = 0;
+		this.blank_lines_before_new_chunk = 0;
+		this.blank_lines_before_package = 0;
+		this.blank_lines_between_import_groups = 1;
+		this.blank_lines_between_type_declarations = 0;
+		this.blank_lines_at_beginning_of_method_body = 0;
+		this.indent_statements_compare_to_block = true;
+		this.indent_statements_compare_to_body = true;
+		this.indent_body_declarations_compare_to_annotation_declaration_header = true;
+		this.indent_body_declarations_compare_to_enum_constant_header = true;
+		this.indent_body_declarations_compare_to_enum_declaration_header = true;
+		this.indent_body_declarations_compare_to_type_header = true;
+		this.indent_breaks_compare_to_cases = true;
+		this.indent_empty_lines = false;
+		this.indent_switchstatements_compare_to_cases = true;
+		this.indent_switchstatements_compare_to_switch = true;
+		this.indentation_size = 4;
+		this.insert_new_line_after_annotation_on_type = true;
+		this.insert_new_line_after_annotation_on_field = true;
+		this.insert_new_line_after_annotation_on_method = true;
+		this.insert_new_line_after_annotation_on_package = true;
+		this.insert_new_line_after_annotation_on_parameter = false;
+		this.insert_new_line_after_annotation_on_local_variable = true;
+		this.insert_new_line_after_opening_brace_in_array_initializer = false;
+		this.insert_new_line_at_end_of_file_if_missing = false;
+		this.insert_new_line_before_catch_in_try_statement = false;
+		this.insert_new_line_before_closing_brace_in_array_initializer = false;
+		this.insert_new_line_before_else_in_if_statement = false;
+		this.insert_new_line_before_finally_in_try_statement = false;
+		this.insert_new_line_before_while_in_do_statement = false;
+		this.insert_new_line_in_empty_anonymous_type_declaration = true;
+		this.insert_new_line_in_empty_block = true;
+		this.insert_new_line_in_empty_annotation_declaration = true;
+		this.insert_new_line_in_empty_enum_constant = true;
+		this.insert_new_line_in_empty_enum_declaration = true;
+		this.insert_new_line_in_empty_method_body = true;
+		this.insert_new_line_in_empty_type_declaration = true;
+		this.insert_space_after_and_in_type_parameter = true;
+		this.insert_space_after_assignment_operator = true;
+		this.insert_space_after_at_in_annotation = false;
+		this.insert_space_after_at_in_annotation_type_declaration = false;
+		this.insert_space_after_binary_operator = true;
+		this.insert_space_after_closing_angle_bracket_in_type_arguments = true;
+		this.insert_space_after_closing_angle_bracket_in_type_parameters = true;
+		this.insert_space_after_closing_paren_in_cast = true;
+		this.insert_space_after_closing_brace_in_block = true;
+		this.insert_space_after_colon_in_assert = true;
+		this.insert_space_after_colon_in_case = true;
+		this.insert_space_after_colon_in_conditional = true;
+		this.insert_space_after_colon_in_for = true;
+		this.insert_space_after_colon_in_labeled_statement = true;
+		this.insert_space_after_comma_in_allocation_expression = true;
+		this.insert_space_after_comma_in_annotation = true;
+		this.insert_space_after_comma_in_array_initializer = true;
+		this.insert_space_after_comma_in_constructor_declaration_parameters = true;
+		this.insert_space_after_comma_in_constructor_declaration_throws = true;
+		this.insert_space_after_comma_in_enum_constant_arguments = true;
+		this.insert_space_after_comma_in_enum_declarations = true;
+		this.insert_space_after_comma_in_explicit_constructor_call_arguments = true;
+		this.insert_space_after_comma_in_for_increments = true;
+		this.insert_space_after_comma_in_for_inits = true;
+		this.insert_space_after_comma_in_method_invocation_arguments = true;
+		this.insert_space_after_comma_in_method_declaration_parameters = true;
+		this.insert_space_after_comma_in_method_declaration_throws = true;
+		this.insert_space_after_comma_in_multiple_field_declarations = true;
+		this.insert_space_after_comma_in_multiple_local_declarations = true;
+		this.insert_space_after_comma_in_parameterized_type_reference = true;
+		this.insert_space_after_comma_in_superinterfaces = true;
+		this.insert_space_after_comma_in_type_arguments = true;
+		this.insert_space_after_comma_in_type_parameters = true;
+		this.insert_space_after_ellipsis = true;
+		this.insert_space_after_lambda_arrow = true;
+		this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_after_opening_angle_bracket_in_type_arguments = false;
+		this.insert_space_after_opening_angle_bracket_in_type_parameters = false;
+		this.insert_space_after_opening_bracket_in_array_allocation_expression = false;
+		this.insert_space_after_opening_bracket_in_array_reference = false;
+		this.insert_space_after_opening_brace_in_array_initializer = false;
+		this.insert_space_after_opening_paren_in_annotation = false;
+		this.insert_space_after_opening_paren_in_cast = false;
+		this.insert_space_after_opening_paren_in_catch = false;
+		this.insert_space_after_opening_paren_in_constructor_declaration = false;
+		this.insert_space_after_opening_paren_in_enum_constant = false;
+		this.insert_space_after_opening_paren_in_for = false;
+		this.insert_space_after_opening_paren_in_if = false;
+		this.insert_space_after_opening_paren_in_method_declaration = false;
+		this.insert_space_after_opening_paren_in_method_invocation = false;
+		this.insert_space_after_opening_paren_in_parenthesized_expression = false;
+		this.insert_space_after_opening_paren_in_switch = false;
+		this.insert_space_after_opening_paren_in_synchronized = false;
+		this.insert_space_after_opening_paren_in_try = false;
+		this.insert_space_after_opening_paren_in_while = false;
+		this.insert_space_after_postfix_operator = false;
+		this.insert_space_after_prefix_operator = false;
+		this.insert_space_after_question_in_conditional = true;
+		this.insert_space_after_question_in_wilcard = false;
+		this.insert_space_after_semicolon_in_for = true;
+		this.insert_space_after_semicolon_in_try_resources = true;
+		this.insert_space_after_unary_operator = false;
+		this.insert_space_before_and_in_type_parameter = true;
+		this.insert_space_before_at_in_annotation_type_declaration = true;
+		this.insert_space_before_assignment_operator = true;
+		this.insert_space_before_binary_operator = true;
+		this.insert_space_before_closing_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_before_closing_angle_bracket_in_type_arguments = false;
+		this.insert_space_before_closing_angle_bracket_in_type_parameters = false;
+		this.insert_space_before_closing_brace_in_array_initializer = false;
+		this.insert_space_before_closing_bracket_in_array_allocation_expression = false;
+		this.insert_space_before_closing_bracket_in_array_reference = false;
+		this.insert_space_before_closing_paren_in_annotation = false;
+		this.insert_space_before_closing_paren_in_cast = false;
+		this.insert_space_before_closing_paren_in_catch = false;
+		this.insert_space_before_closing_paren_in_constructor_declaration = false;
+		this.insert_space_before_closing_paren_in_enum_constant = false;
+		this.insert_space_before_closing_paren_in_for = false;
+		this.insert_space_before_closing_paren_in_if = false;
+		this.insert_space_before_closing_paren_in_method_declaration = false;
+		this.insert_space_before_closing_paren_in_method_invocation = false;
+		this.insert_space_before_closing_paren_in_parenthesized_expression = false;
+		this.insert_space_before_closing_paren_in_switch = false;
+		this.insert_space_before_closing_paren_in_synchronized = false;
+		this.insert_space_before_closing_paren_in_try = false;
+		this.insert_space_before_closing_paren_in_while = false;
+		this.insert_space_before_colon_in_assert = true;
+		this.insert_space_before_colon_in_case = true;
+		this.insert_space_before_colon_in_conditional = true;
+		this.insert_space_before_colon_in_default = true;
+		this.insert_space_before_colon_in_for = true;
+		this.insert_space_before_colon_in_labeled_statement = true;
+		this.insert_space_before_comma_in_allocation_expression = false;
+		this.insert_space_before_comma_in_array_initializer = false;
+		this.insert_space_before_comma_in_constructor_declaration_parameters = false;
+		this.insert_space_before_comma_in_constructor_declaration_throws = false;
+		this.insert_space_before_comma_in_enum_constant_arguments = false;
+		this.insert_space_before_comma_in_enum_declarations = false;
+		this.insert_space_before_comma_in_explicit_constructor_call_arguments = false;
+		this.insert_space_before_comma_in_for_increments = false;
+		this.insert_space_before_comma_in_for_inits = false;
+		this.insert_space_before_comma_in_method_invocation_arguments = false;
+		this.insert_space_before_comma_in_method_declaration_parameters = false;
+		this.insert_space_before_comma_in_method_declaration_throws = false;
+		this.insert_space_before_comma_in_multiple_field_declarations = false;
+		this.insert_space_before_comma_in_multiple_local_declarations = false;
+		this.insert_space_before_comma_in_parameterized_type_reference = false;
+		this.insert_space_before_comma_in_superinterfaces = false;
+		this.insert_space_before_comma_in_type_arguments = false;
+		this.insert_space_before_comma_in_type_parameters = false;
+		this.insert_space_before_ellipsis = false;
+		this.insert_space_before_lambda_arrow = true;
+		this.insert_space_before_parenthesized_expression_in_return = true;
+		this.insert_space_before_parenthesized_expression_in_throw = true;
+		this.insert_space_before_opening_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_before_opening_angle_bracket_in_type_arguments = false;
+		this.insert_space_before_opening_angle_bracket_in_type_parameters = false;
+		this.insert_space_before_opening_brace_in_annotation_type_declaration = true;
+		this.insert_space_before_opening_brace_in_anonymous_type_declaration = true;
+		this.insert_space_before_opening_brace_in_array_initializer = false;
+		this.insert_space_before_opening_brace_in_block = true;
+		this.insert_space_before_opening_brace_in_constructor_declaration = true;
+		this.insert_space_before_opening_brace_in_enum_constant = true;
+		this.insert_space_before_opening_brace_in_enum_declaration = true;
+		this.insert_space_before_opening_brace_in_method_declaration = true;
+		this.insert_space_before_opening_brace_in_switch = true;
+		this.insert_space_before_opening_brace_in_type_declaration = true;
+		this.insert_space_before_opening_bracket_in_array_allocation_expression = false;
+		this.insert_space_before_opening_bracket_in_array_reference = false;
+		this.insert_space_before_opening_bracket_in_array_type_reference = false;
+		this.insert_space_before_opening_paren_in_annotation = false;
+		this.insert_space_before_opening_paren_in_annotation_type_member_declaration = false;
+		this.insert_space_before_opening_paren_in_catch = true;
+		this.insert_space_before_opening_paren_in_constructor_declaration = false;
+		this.insert_space_before_opening_paren_in_enum_constant = false;
+		this.insert_space_before_opening_paren_in_for = true;
+		this.insert_space_before_opening_paren_in_if = true;
+		this.insert_space_before_opening_paren_in_method_invocation = false;
+		this.insert_space_before_opening_paren_in_method_declaration = false;
+		this.insert_space_before_opening_paren_in_switch = true;
+		this.insert_space_before_opening_paren_in_synchronized = true;
+		this.insert_space_before_opening_paren_in_try = true;
+		this.insert_space_before_opening_paren_in_parenthesized_expression = false;
+		this.insert_space_before_opening_paren_in_while = true;
+		this.insert_space_before_postfix_operator = false;
+		this.insert_space_before_prefix_operator = false;
+		this.insert_space_before_question_in_conditional = true;
+		this.insert_space_before_question_in_wilcard = false;
+		this.insert_space_before_semicolon = false;
+		this.insert_space_before_semicolon_in_for = false;
+		this.insert_space_before_semicolon_in_try_resources = false;
+		this.insert_space_before_unary_operator = false;
+		this.insert_space_between_brackets_in_array_type_reference = false;
+		this.insert_space_between_empty_braces_in_array_initializer = false;
+		this.insert_space_between_empty_brackets_in_array_allocation_expression = false;
+		this.insert_space_between_empty_parens_in_annotation_type_member_declaration = false;
+		this.insert_space_between_empty_parens_in_constructor_declaration = false;
+		this.insert_space_between_empty_parens_in_enum_constant = false;
+		this.insert_space_between_empty_parens_in_method_declaration = false;
+		this.insert_space_between_empty_parens_in_method_invocation = false;
+		this.compact_else_if = true;
+		this.keep_guardian_clause_on_one_line = false;
+		this.keep_else_statement_on_same_line = false;
+		this.keep_empty_array_initializer_on_one_line = false;
+		this.keep_simple_if_on_one_line = false;
+		this.keep_then_statement_on_same_line = false;
+		this.never_indent_block_comments_on_first_column = false;
+		this.never_indent_line_comments_on_first_column = false;
+		this.number_of_empty_lines_to_preserve = 1;
+		this.join_lines_in_comments = true;
+		this.join_wrapped_lines = true;
+		this.put_empty_statement_on_new_line = false;
+		this.tab_size = 4;
+		this.page_width = 80;
+		this.tab_char = TAB; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49081
+		this.use_tabs_only_for_leading_indentations = false;
+		this.wrap_before_binary_operator = true;
+		this.wrap_before_or_operator_multicatch = true;
+		this.use_tags = false;
+		this.disabling_tag = DEFAULT_DISABLING_TAG;
+		this.enabling_tag = DEFAULT_ENABLING_TAG;
+		this.wrap_outer_expressions_when_nested = true;
+	}
+
+	public void setEclipseDefaultSettings() {
+		setJavaConventionsSettings();
+		this.tab_char = TAB;
+		this.tab_size = 4;
+	}
+
+	public void setJavaConventionsSettings() {
+		this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_annotation = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_arguments_in_enum_constant = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_explicit_constructor_call = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_arguments_in_qualified_allocation_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_assignment = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_compact_if = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_conditional_expression = Alignment.M_NEXT_PER_LINE_SPLIT;
+		this.alignment_for_enum_constants = Alignment.NONE;
+		this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_method_declaration = Alignment.M_NO_ALIGNMENT;
+		this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_resources_in_try = Alignment.M_NEXT_PER_LINE_SPLIT;
+		this.alignment_for_selector_in_method_invocation = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_superclass_in_type_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_superinterfaces_in_enum_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_superinterfaces_in_type_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_throws_clause_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+		this.alignment_for_union_type_in_multicatch = Alignment.M_COMPACT_SPLIT;
+		this.align_type_members_on_columns = false;
+		this.brace_position_for_annotation_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_anonymous_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_array_initializer = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_block = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_block_in_case = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_constructor_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_enum_constant = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_enum_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_lambda_body = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_method_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.brace_position_for_switch = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.comment_clear_blank_lines_in_block_comment = false;
+		this.comment_clear_blank_lines_in_javadoc_comment = false;
+		this.comment_format_block_comment = true;
+		this.comment_format_javadoc_comment = true;
+		this.comment_format_line_comment = true;
+		this.comment_format_line_comment_starting_on_first_column = true;
+		this.comment_format_header = false;
+		this.comment_format_html = true;
+		this.comment_format_source = true;
+		this.comment_indent_parameter_description = true;
+		this.comment_indent_root_tags = true;
+		this.comment_insert_empty_line_before_root_tags = true;
+		this.comment_insert_new_line_for_parameter = true;
+		this.comment_new_lines_at_block_boundaries = true;
+		this.comment_new_lines_at_javadoc_boundaries = true;
+		this.comment_line_length = 80;
+		this.comment_preserve_white_space_between_code_and_line_comments= false; 
+		this.continuation_indentation = 2;
+		this.continuation_indentation_for_array_initializer = 2;
+		this.blank_lines_after_imports = 1;
+		this.blank_lines_after_package = 1;
+		this.blank_lines_before_field = 0;
+		this.blank_lines_before_first_class_body_declaration = 0;
+		this.blank_lines_before_imports = 1;
+		this.blank_lines_before_member_type = 1;
+		this.blank_lines_before_method = 1;
+		this.blank_lines_before_new_chunk = 1;
+		this.blank_lines_before_package = 0;
+		this.blank_lines_between_import_groups = 1;
+		this.blank_lines_between_type_declarations = 1;
+		this.blank_lines_at_beginning_of_method_body = 0;
+		this.indent_statements_compare_to_block = true;
+		this.indent_statements_compare_to_body = true;
+		this.indent_body_declarations_compare_to_annotation_declaration_header = true;
+		this.indent_body_declarations_compare_to_enum_constant_header = true;
+		this.indent_body_declarations_compare_to_enum_declaration_header = true;
+		this.indent_body_declarations_compare_to_type_header = true;
+		this.indent_breaks_compare_to_cases = true;
+		this.indent_empty_lines = false;
+		this.indent_switchstatements_compare_to_cases = true;
+		this.indent_switchstatements_compare_to_switch = false;
+		this.indentation_size = 4;
+		this.insert_new_line_after_annotation_on_type = true;
+		this.insert_new_line_after_annotation_on_field = true;
+		this.insert_new_line_after_annotation_on_method = true;
+		this.insert_new_line_after_annotation_on_package = true;
+		this.insert_new_line_after_annotation_on_parameter = false;
+		this.insert_new_line_after_annotation_on_local_variable = true;
+		this.insert_new_line_after_opening_brace_in_array_initializer = false;
+		this.insert_new_line_at_end_of_file_if_missing = false;
+		this.insert_new_line_before_catch_in_try_statement = false;
+		this.insert_new_line_before_closing_brace_in_array_initializer = false;
+		this.insert_new_line_before_else_in_if_statement = false;
+		this.insert_new_line_before_finally_in_try_statement = false;
+		this.insert_new_line_before_while_in_do_statement = false;
+		this.insert_new_line_in_empty_anonymous_type_declaration = true;
+		this.insert_new_line_in_empty_block = true;
+		this.insert_new_line_in_empty_annotation_declaration = true;
+		this.insert_new_line_in_empty_enum_constant = true;
+		this.insert_new_line_in_empty_enum_declaration = true;
+		this.insert_new_line_in_empty_method_body = true;
+		this.insert_new_line_in_empty_type_declaration = true;
+		this.insert_space_after_and_in_type_parameter = true;
+		this.insert_space_after_assignment_operator = true;
+		this.insert_space_after_at_in_annotation = false;
+		this.insert_space_after_at_in_annotation_type_declaration = false;
+		this.insert_space_after_binary_operator = true;
+		this.insert_space_after_closing_angle_bracket_in_type_arguments = true;
+		this.insert_space_after_closing_angle_bracket_in_type_parameters = true;
+		this.insert_space_after_closing_paren_in_cast = true;
+		this.insert_space_after_closing_brace_in_block = true;
+		this.insert_space_after_colon_in_assert = true;
+		this.insert_space_after_colon_in_case = true;
+		this.insert_space_after_colon_in_conditional = true;
+		this.insert_space_after_colon_in_for = true;
+		this.insert_space_after_colon_in_labeled_statement = true;
+		this.insert_space_after_comma_in_allocation_expression = true;
+		this.insert_space_after_comma_in_annotation = true;
+		this.insert_space_after_comma_in_array_initializer = true;
+		this.insert_space_after_comma_in_constructor_declaration_parameters = true;
+		this.insert_space_after_comma_in_constructor_declaration_throws = true;
+		this.insert_space_after_comma_in_enum_constant_arguments = true;
+		this.insert_space_after_comma_in_enum_declarations = true;
+		this.insert_space_after_comma_in_explicit_constructor_call_arguments = true;
+		this.insert_space_after_comma_in_for_increments = true;
+		this.insert_space_after_comma_in_for_inits = true;
+		this.insert_space_after_comma_in_method_invocation_arguments = true;
+		this.insert_space_after_comma_in_method_declaration_parameters = true;
+		this.insert_space_after_comma_in_method_declaration_throws = true;
+		this.insert_space_after_comma_in_multiple_field_declarations = true;
+		this.insert_space_after_comma_in_multiple_local_declarations = true;
+		this.insert_space_after_comma_in_parameterized_type_reference = true;
+		this.insert_space_after_comma_in_superinterfaces = true;
+		this.insert_space_after_comma_in_type_arguments = true;
+		this.insert_space_after_comma_in_type_parameters = true;
+		this.insert_space_after_ellipsis = true;
+		this.insert_space_after_lambda_arrow = true;
+		this.insert_space_after_opening_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_after_opening_angle_bracket_in_type_arguments = false;
+		this.insert_space_after_opening_angle_bracket_in_type_parameters = false;
+		this.insert_space_after_opening_bracket_in_array_allocation_expression = false;
+		this.insert_space_after_opening_bracket_in_array_reference = false;
+		this.insert_space_after_opening_brace_in_array_initializer = true;
+		this.insert_space_after_opening_paren_in_annotation = false;
+		this.insert_space_after_opening_paren_in_cast = false;
+		this.insert_space_after_opening_paren_in_catch = false;
+		this.insert_space_after_opening_paren_in_constructor_declaration = false;
+		this.insert_space_after_opening_paren_in_enum_constant = false;
+		this.insert_space_after_opening_paren_in_for = false;
+		this.insert_space_after_opening_paren_in_if = false;
+		this.insert_space_after_opening_paren_in_method_declaration = false;
+		this.insert_space_after_opening_paren_in_method_invocation = false;
+		this.insert_space_after_opening_paren_in_parenthesized_expression = false;
+		this.insert_space_after_opening_paren_in_switch = false;
+		this.insert_space_after_opening_paren_in_synchronized = false;
+		this.insert_space_after_opening_paren_in_try = false;
+		this.insert_space_after_opening_paren_in_while = false;
+		this.insert_space_after_postfix_operator = false;
+		this.insert_space_after_prefix_operator = false;
+		this.insert_space_after_question_in_conditional = true;
+		this.insert_space_after_question_in_wilcard = false;
+		this.insert_space_after_semicolon_in_for = true;
+		this.insert_space_after_semicolon_in_try_resources = true;
+		this.insert_space_after_unary_operator = false;
+		this.insert_space_before_and_in_type_parameter = true;
+		this.insert_space_before_at_in_annotation_type_declaration = true;
+		this.insert_space_before_assignment_operator = true;
+		this.insert_space_before_binary_operator = true;
+		this.insert_space_before_closing_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_before_closing_angle_bracket_in_type_arguments = false;
+		this.insert_space_before_closing_angle_bracket_in_type_parameters = false;
+		this.insert_space_before_closing_brace_in_array_initializer = true;
+		this.insert_space_before_closing_bracket_in_array_allocation_expression = false;
+		this.insert_space_before_closing_bracket_in_array_reference = false;
+		this.insert_space_before_closing_paren_in_annotation = false;
+		this.insert_space_before_closing_paren_in_cast = false;
+		this.insert_space_before_closing_paren_in_catch = false;
+		this.insert_space_before_closing_paren_in_constructor_declaration = false;
+		this.insert_space_before_closing_paren_in_enum_constant = false;
+		this.insert_space_before_closing_paren_in_for = false;
+		this.insert_space_before_closing_paren_in_if = false;
+		this.insert_space_before_closing_paren_in_method_declaration = false;
+		this.insert_space_before_closing_paren_in_method_invocation = false;
+		this.insert_space_before_closing_paren_in_parenthesized_expression = false;
+		this.insert_space_before_closing_paren_in_switch = false;
+		this.insert_space_before_closing_paren_in_synchronized = false;
+		this.insert_space_before_closing_paren_in_try = false;
+		this.insert_space_before_closing_paren_in_while = false;
+		this.insert_space_before_colon_in_assert = true;
+		this.insert_space_before_colon_in_case = false;
+		this.insert_space_before_colon_in_conditional = true;
+		this.insert_space_before_colon_in_default = false;
+		this.insert_space_before_colon_in_for = true;
+		this.insert_space_before_colon_in_labeled_statement = false;
+		this.insert_space_before_comma_in_allocation_expression = false;
+		this.insert_space_before_comma_in_array_initializer = false;
+		this.insert_space_before_comma_in_constructor_declaration_parameters = false;
+		this.insert_space_before_comma_in_constructor_declaration_throws = false;
+		this.insert_space_before_comma_in_enum_constant_arguments = false;
+		this.insert_space_before_comma_in_enum_declarations = false;
+		this.insert_space_before_comma_in_explicit_constructor_call_arguments = false;
+		this.insert_space_before_comma_in_for_increments = false;
+		this.insert_space_before_comma_in_for_inits = false;
+		this.insert_space_before_comma_in_method_invocation_arguments = false;
+		this.insert_space_before_comma_in_method_declaration_parameters = false;
+		this.insert_space_before_comma_in_method_declaration_throws = false;
+		this.insert_space_before_comma_in_multiple_field_declarations = false;
+		this.insert_space_before_comma_in_multiple_local_declarations = false;
+		this.insert_space_before_comma_in_parameterized_type_reference = false;
+		this.insert_space_before_comma_in_superinterfaces = false;
+		this.insert_space_before_comma_in_type_arguments = false;
+		this.insert_space_before_comma_in_type_parameters = false;
+		this.insert_space_before_ellipsis = false;
+		this.insert_space_before_lambda_arrow = true;
+		this.insert_space_before_parenthesized_expression_in_return = true;
+		this.insert_space_before_parenthesized_expression_in_throw = true;
+		this.insert_space_before_opening_angle_bracket_in_parameterized_type_reference = false;
+		this.insert_space_before_opening_angle_bracket_in_type_arguments = false;
+		this.insert_space_before_opening_angle_bracket_in_type_parameters = false;
+		this.insert_space_before_opening_brace_in_annotation_type_declaration = true;
+		this.insert_space_before_opening_brace_in_anonymous_type_declaration = true;
+		this.insert_space_before_opening_brace_in_array_initializer = true;
+		this.insert_space_before_opening_brace_in_block = true;
+		this.insert_space_before_opening_brace_in_constructor_declaration = true;
+		this.insert_space_before_opening_brace_in_enum_constant = true;
+		this.insert_space_before_opening_brace_in_enum_declaration = true;
+		this.insert_space_before_opening_brace_in_method_declaration = true;
+		this.insert_space_before_opening_brace_in_switch = true;
+		this.insert_space_before_opening_brace_in_type_declaration = true;
+		this.insert_space_before_opening_bracket_in_array_allocation_expression = false;
+		this.insert_space_before_opening_bracket_in_array_reference = false;
+		this.insert_space_before_opening_bracket_in_array_type_reference = false;
+		this.insert_space_before_opening_paren_in_annotation = false;
+		this.insert_space_before_opening_paren_in_annotation_type_member_declaration = false;
+		this.insert_space_before_opening_paren_in_catch = true;
+		this.insert_space_before_opening_paren_in_constructor_declaration = false;
+		this.insert_space_before_opening_paren_in_enum_constant = false;
+		this.insert_space_before_opening_paren_in_for = true;
+		this.insert_space_before_opening_paren_in_if = true;
+		this.insert_space_before_opening_paren_in_method_invocation = false;
+		this.insert_space_before_opening_paren_in_method_declaration = false;
+		this.insert_space_before_opening_paren_in_switch = true;
+		this.insert_space_before_opening_paren_in_synchronized = true;
+		this.insert_space_before_opening_paren_in_try = true;
+		this.insert_space_before_opening_paren_in_parenthesized_expression = false;
+		this.insert_space_before_opening_paren_in_while = true;
+		this.insert_space_before_postfix_operator = false;
+		this.insert_space_before_prefix_operator = false;
+		this.insert_space_before_question_in_conditional = true;
+		this.insert_space_before_question_in_wilcard = false;
+		this.insert_space_before_semicolon = false;
+		this.insert_space_before_semicolon_in_for = false;
+		this.insert_space_before_semicolon_in_try_resources = false;
+		this.insert_space_before_unary_operator = false;
+		this.insert_space_between_brackets_in_array_type_reference = false;
+		this.insert_space_between_empty_braces_in_array_initializer = false;
+		this.insert_space_between_empty_brackets_in_array_allocation_expression = false;
+		this.insert_space_between_empty_parens_in_annotation_type_member_declaration = false;
+		this.insert_space_between_empty_parens_in_constructor_declaration = false;
+		this.insert_space_between_empty_parens_in_enum_constant = false;
+		this.insert_space_between_empty_parens_in_method_declaration = false;
+		this.insert_space_between_empty_parens_in_method_invocation = false;
+		this.compact_else_if = true;
+		this.keep_guardian_clause_on_one_line = false;
+		this.keep_else_statement_on_same_line = false;
+		this.keep_empty_array_initializer_on_one_line = false;
+		this.keep_simple_if_on_one_line = false;
+		this.keep_then_statement_on_same_line = false;
+		this.never_indent_block_comments_on_first_column = false;
+		this.never_indent_line_comments_on_first_column = false;
+		this.number_of_empty_lines_to_preserve = 1;
+		this.join_lines_in_comments = true;
+		this.join_wrapped_lines = true;
+		this.put_empty_statement_on_new_line = true;
+		this.tab_size = 8;
+		this.page_width = 80;
+		this.tab_char = MIXED;
+		this.use_tabs_only_for_leading_indentations = false;
+		this.wrap_before_binary_operator = true;
+		this.wrap_before_or_operator_multicatch = true;
+		this.use_tags = false;
+		this.disabling_tag = DEFAULT_DISABLING_TAG;
+		this.enabling_tag = DEFAULT_ENABLING_TAG;
+		this.wrap_outer_expressions_when_nested = true;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadoc.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadoc.java
new file mode 100644
index 0000000..2ccb03e
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadoc.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import org.eclipse.jdt.internal.compiler.ast.Javadoc;
+
+/**
+ * Represents a full Javadoc comment for the {@link FormatterCommentParser}.
+ * <p>
+ * It might have one or several blocks ( see {@link FormatJavadocBlock}). The
+ * javadoc comment might starts with a <b>description</b> which means that its
+ * first block has no tag.
+ * </p>
+ */
+public class FormatJavadoc extends Javadoc {
+
+	FormatJavadocBlock[] blocks;
+	int textStart, textEnd;
+	int lineStart, lineEnd;
+
+public FormatJavadoc(int sourceStart, int sourceEnd, int length) {
+	super(sourceStart, sourceEnd);
+	if (length > 0) {
+		this.blocks = new FormatJavadocBlock[length];
+	}
+}
+
+/**
+ * Return the first block of the javadoc or <code>null</code> if has no block
+ * at all.
+ *
+ * @return a {@link FormatJavadocBlock} or <code>null</code>.
+ */
+public FormatJavadocBlock getFirstBlock() {
+	if (this.blocks != null) {
+		return this.blocks[0];
+	}
+	return null;
+}
+
+/**
+ * Returns whether it has several lines or not.
+ *
+ * @return <code>true</code> if the javadoc comment has several lines
+ * 	<code>false</code> otherwise (e.g. header and footer are on the same
+ * 	line).
+ */
+public boolean isMultiLine() {
+	return this.lineStart < this.lineEnd;
+}
+
+public String toDebugString(char[] source) {
+	if (this.blocks == null) {
+		return "No block in current Javadoc comment"; //$NON-NLS-1$
+	}
+	StringBuffer buffer = new StringBuffer();
+	int length = this.blocks.length;
+	for (int i=0; i<length; i++) {
+		this.blocks[i].toStringDebug(buffer, source);
+		buffer.append('\n');
+	}
+	return buffer.toString();
+}
+
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java
new file mode 100644
index 0000000..472f4f0
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocBlock.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;
+
+/**
+ * Represents a block in a {@link FormatJavadoc} which might be a
+ * <b>description</b> or a <b>tag</b> (see{@link #isDescription()}).
+ * </p><p>
+ * The block might have a tag, a reference and nodes (see
+ * {@link FormatJavadocNode}. Each of these elements might be present or not,
+ * but at least one of them is.
+ * </p>
+ */
+public class FormatJavadocBlock extends FormatJavadocNode implements IJavaDocTagConstants {
+	// flags
+	final static int INLINED = 0x0001;
+	final static int FIRST = 0x0002;
+	final static int ON_HEADER_LINE = 0x0004;
+	final static int TEXT_ON_TAG_LINE = 0x0008;
+	final static int ONE_LINE_TAG = 0x0010;
+	final static int PARAM_TAG = 0x0020;
+	final static int IN_PARAM_TAG = 0x0040;
+	final static int IN_DESCRIPTION = 0x0080;
+	final static int IMMUTABLE = 0x0100;
+
+	// constants
+	final static int MAX_TAG_HIERARCHY = 10;
+
+	private int tagValue = NO_TAG_VALUE;
+	int tagEnd;
+	FormatJavadocReference reference;
+	FormatJavadocNode[] nodes;
+	int nodesPtr = -1;
+	int flags = 0;
+
+public FormatJavadocBlock(int start, int end, int line, int value) {
+	super(start, end, line);
+	this.tagValue = value;
+	this.tagEnd = end;
+	switch (value) {
+		case TAG_PARAM_VALUE:
+		// TODO why are following tags considered like @param by the formatter?
+		case TAG_SERIAL_FIELD_VALUE:
+		case TAG_THROWS_VALUE:
+		case TAG_EXCEPTION_VALUE:
+			this.flags |= PARAM_TAG;
+			break;
+		case TAG_CODE_VALUE:
+		case TAG_LITERAL_VALUE:
+			this.flags |= IMMUTABLE;
+			break;
+	}
+}
+
+private void addNode(FormatJavadocNode node) {
+	// Initialize or resize array if necessary
+	if (++this.nodesPtr == 0) {
+		this.nodes = new FormatJavadocNode[DEFAULT_ARRAY_SIZE];
+	} else if (this.nodesPtr >= this.nodes.length) {
+		System.arraycopy(
+			this.nodes, 0,
+			this.nodes = new FormatJavadocNode[this.nodes.length+INCREMENT_ARRAY_SIZE], 0,
+			this.nodesPtr);
+	}
+
+	// Store the node
+	this.nodes[this.nodesPtr] = node;
+	this.sourceEnd = node.sourceEnd;
+}
+
+void addBlock(FormatJavadocBlock block, int htmlLevel) {
+	if (this.nodes != null) {
+		FormatJavadocText[] textHierarchy = getTextHierarchy(block, htmlLevel);
+		if (textHierarchy != null) {
+			FormatJavadocText lastText = textHierarchy[htmlLevel];
+			if (lastText != null) {
+				lastText.appendNode(block);
+				for (int i=htmlLevel-1; i>=0; i--) {
+					textHierarchy[i].sourceEnd = block.sourceEnd;
+				}
+				this.sourceEnd = block.sourceEnd;
+				if (isParamTag()) {
+					block.flags |= IN_PARAM_TAG;
+				} else if (isDescription()) {
+					block.flags |= IN_DESCRIPTION;
+				}
+				block.flags |= INLINED;
+				return;
+			}
+		}
+	}
+	addNode(block);
+	if (isParamTag()) {
+		block.flags |= IN_PARAM_TAG;
+	} else if (isDescription()) {
+		block.flags |= IN_DESCRIPTION;
+	}
+	block.flags |= INLINED;
+}
+
+void addText(FormatJavadocText text) {
+	if (this.nodes != null) {
+		FormatJavadocText[] textHierarchy = getTextHierarchy(text, text.depth);
+		if (textHierarchy != null) {
+			FormatJavadocText lastText = textHierarchy[text.depth];
+			if (lastText != null) {
+				lastText.appendText(text);
+				for (int i=text.depth-1; i>=0; i--) {
+					textHierarchy[i].sourceEnd = text.sourceEnd;
+				}
+				this.sourceEnd = text.sourceEnd;
+				return;
+			}
+			if (text.depth > 0) {
+				FormatJavadocText parentText = textHierarchy[text.depth-1];
+				if (parentText != null) {
+					parentText.appendText(text);
+					for (int i=text.depth-2; i>=0; i--) {
+						textHierarchy[i].sourceEnd = text.sourceEnd;
+					}
+					this.sourceEnd = text.sourceEnd;
+					return;
+				}
+			}
+		}
+	}
+	if (text.isHtmlTag()) {
+		switch (text.getHtmlTagID()) {
+			case JAVADOC_CODE_TAGS_ID:
+				text.linesBefore = this.nodesPtr == -1 ? 0 : 2;
+				break;
+			case JAVADOC_SEPARATOR_TAGS_ID:
+				text.linesBefore = 1;
+				break;
+//	    	case JAVADOC_BREAK_TAGS_ID:
+//				if (this.nodesPtr >= 0) text.linesBefore = 1;
+		}
+	}
+	addNode(text);
+	if (isImmutable()) {
+		text.immutable = true;
+	}
+}
+
+void clean() {
+	int length = this.nodes == null ? 0 : this.nodes.length;
+	if (this.nodesPtr != (length-1)) {
+		System.arraycopy(this.nodes, 0, this.nodes = new FormatJavadocNode[this.nodesPtr+1], 0, this.nodesPtr+1);
+	}
+	for (int i=0; i<=this.nodesPtr; i++) {
+		this.nodes[i].clean();
+	}
+}
+
+FormatJavadocNode getLastNode() {
+	if (this.nodes != null) {
+		return this.nodes[this.nodesPtr];
+	}
+	return null;
+}
+
+/*
+ * Return the text hierarchy for the given node
+ */
+FormatJavadocText[] getTextHierarchy(FormatJavadocNode node, int htmlDepth) {
+	if (this.nodes == null) return null;
+	FormatJavadocText[] textHierarchy = null;
+	int ptr = 0;
+	FormatJavadocText text = node.isText() ? (FormatJavadocText) node : null;
+	FormatJavadocNode lastNode = this.nodes[this.nodesPtr];
+	while (lastNode.isText()) {
+		FormatJavadocText lastText = (FormatJavadocText) lastNode;
+		int lastTagCategory = lastText.getHtmlTagID();
+		boolean lastSingleTag = lastTagCategory <= JAVADOC_SINGLE_TAGS_ID;
+		boolean lastTextCanHaveChildren = lastText.isHtmlTag() && !lastText.isClosingHtmlTag() && !lastSingleTag;
+		if (lastText.depth == htmlDepth || // found same html tag level => use it
+			lastText.htmlNodesPtr == -1) {	// no more sub-levels => add one
+			// Text breakage
+			if (lastText.isHtmlTag()) {
+				// Set some lines before if previous was specific html tag
+				// The added text is concerned if the parent has no child yet or is top level and closing html tag
+				boolean setLinesBefore = lastText.separatorsPtr == -1 || (ptr == 0 && lastText.isClosingHtmlTag());
+				if (!setLinesBefore && ptr > 0 && lastText.isClosingHtmlTag()) {
+					// for non-top level closing html tag, text is concerned only if no new text has been written after
+					FormatJavadocText parentText = textHierarchy[ptr-1];
+					int textStart = (int) parentText.separators[parentText.separatorsPtr];
+					if (textStart < lastText.sourceStart) {
+						setLinesBefore = true;
+					}
+				}
+				if (setLinesBefore) {
+					switch (lastText.getHtmlTagID()) {
+						case JAVADOC_CODE_TAGS_ID:
+							if (node.linesBefore < 2) {
+								node.linesBefore = 2;
+							}
+							break;
+						case JAVADOC_SEPARATOR_TAGS_ID:
+				    	case JAVADOC_SINGLE_BREAK_TAG_ID:
+							if (node.linesBefore < 1) {
+								node.linesBefore = 1;
+							}
+					}
+				}
+				// If adding an html tag on same html tag, then close previous one and leave
+				if (text != null && text.isHtmlTag() && !text.isClosingHtmlTag() && text.getHtmlTagIndex() == lastText.getHtmlTagIndex() && !lastText.isClosingHtmlTag()) {
+					lastText.closeTag();
+					return textHierarchy;
+				}
+			}
+			// If we have a text after another text, keep the same level to append
+			if (lastTextCanHaveChildren || (htmlDepth == 0 && !lastText.isHtmlTag() && text != null && !text.isHtmlTag())) {
+				if (textHierarchy == null) textHierarchy = new FormatJavadocText[htmlDepth+1];
+				textHierarchy[ptr] = lastText;
+				return textHierarchy;
+			}
+			// Last text cannot have children, so return the built hierarchy
+			return textHierarchy;
+		}
+		if (textHierarchy == null) textHierarchy = new FormatJavadocText[htmlDepth+1];
+		textHierarchy[ptr++] = lastText;
+		lastNode = lastText.htmlNodes[lastText.htmlNodesPtr];
+	}
+	return textHierarchy;
+}
+
+/**
+ * Returns whether the text is on the same line of the tag or not.
+ *
+ * @return <code>true</code> if the text is on the same line than the tag,
+ * 	<code>false</code> otherwise.
+ */
+public boolean hasTextOnTagLine() {
+	return (this.flags & TEXT_ON_TAG_LINE) != 0;
+}
+
+/**
+ * Returns whether the block is the javadoc comment description or not.
+ * The description begins after the starting delimiter and continues until the tag
+ * section.
+ *
+ * @return <code>true</code> if the block is the javadoc description,
+ * 	<code>false</code> otherwise.
+ */
+public boolean isDescription() {
+	return this.tagValue == NO_TAG_VALUE;
+}
+
+/**
+ * Returns whether the block is the first block of the javadoc comment or not
+ * (independently of the fact it's a description or not).
+ *
+ * @return <code>true</code> if the block is the first of the javadoc
+ * 	comment, <code>false</code> otherwise.
+ */
+public boolean isFirst() {
+	return (this.flags & FIRST) != 0;
+}
+
+/**
+ * Returns whether the first block starts on the same line than the javadoc
+ * starting delimiter or not.
+ *
+ * @return <code>true</code> if the the first block starts on the same line
+ * 	than the javadoc starting delimiter, <code>false</code> otherwise.
+ */
+public boolean isHeaderLine() {
+	return (this.flags & ON_HEADER_LINE) != 0;
+}
+
+/**
+ * Returns whether the block is immutable or not.
+ * <p>
+ * Currently, only {@code} and {@literal} inline tags block are considered as
+ * immutable.
+ * </p>
+ * @return <code>true</code> if the block is immutable,
+ * 	<code>false</code> otherwise.
+ */
+public boolean isImmutable() {
+	return (this.flags & IMMUTABLE) == IMMUTABLE;
+}
+
+/**
+ * Returns whether the block is a description or inlined in a description.
+ * @see #isParamTag()
+ *
+ * @return <code>true</code> if the block is a description or inlined in a
+ * 	description, <code>false</code> otherwise.
+ */
+public boolean isInDescription() {
+	return this.tagValue == NO_TAG_VALUE || (this.flags & IN_DESCRIPTION) == IN_DESCRIPTION;
+}
+
+/**
+ * Returns whether the text is on the same line of the tag.
+ *
+ * @return <code>true</code> if the text is on the same line than the tag,
+ * 	<code>false</code> otherwise.
+ */
+public boolean isInlined() {
+	return (this.flags & INLINED) != 0;
+}
+
+/**
+ * Returns whether the block is a param tag or inlined in a param tag.
+ * @see #isParamTag()
+ *
+ * @return <code>true</code> if the block is a param tag or inlined in a param
+ * 	tag, <code>false</code> otherwise.
+ */
+public boolean isInParamTag() {
+	return (this.flags & (PARAM_TAG | IN_PARAM_TAG)) != 0;
+}
+
+/**
+ * Returns whether the the tag is on one line only.
+ *
+ * @return <code>true</code> if the tag is on one line only,
+ * 	<code>false</code> otherwise.
+ */
+public boolean isOneLineTag() {
+	return (this.flags & ONE_LINE_TAG) != 0;
+}
+
+/**
+ * Returns whether the block is a param tag or not.  Note that this also includes
+ * &#064;serialField, &#064;throws and &#064;exception tags.
+ *
+ * @return <code>true</code> if the block is a param tag,
+ * 	<code>false</code> otherwise.
+ */
+public boolean isParamTag() {
+	return (this.flags & PARAM_TAG) == PARAM_TAG;
+}
+
+void setHeaderLine(int javadocLineStart) {
+	if (javadocLineStart == this.lineStart) {
+		this.flags |= ON_HEADER_LINE;
+	}
+	for (int i=0; i<this.nodesPtr; i++) {
+		this.nodes[i].setHeaderLine(javadocLineStart);
+	}
+}
+
+protected void toString(StringBuffer buffer) {
+	boolean inlined = (this.flags & INLINED) != 0;
+	if (inlined) buffer.append("	{"); //$NON-NLS-1$
+	buffer.append('@');
+	if (this.tagValue == TAG_OTHERS_VALUE) {
+		buffer.append("others_tag"); //$NON-NLS-1$
+	} else {
+		buffer.append(TAG_NAMES[this.tagValue]);
+	}
+	super.toString(buffer);
+	if (this.reference == null) {
+		buffer.append('\n');
+	} else {
+		buffer.append(" ("); //$NON-NLS-1$
+		this.reference.toString(buffer);
+		buffer.append(")\n"); //$NON-NLS-1$
+	}
+	StringBuffer flagsBuffer = new StringBuffer();
+	if (isDescription()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("description"); //$NON-NLS-1$
+	}
+	if (isFirst()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("first"); //$NON-NLS-1$
+	}
+	if (isHeaderLine()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("header line"); //$NON-NLS-1$
+	}
+	if (isImmutable()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("immutable"); //$NON-NLS-1$
+	}
+	if (isInDescription()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("in description"); //$NON-NLS-1$
+	}
+	if (isInlined()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("inlined"); //$NON-NLS-1$
+	}
+	if (isInParamTag()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("in param tag"); //$NON-NLS-1$
+	}
+	if (isOneLineTag()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("one line tag"); //$NON-NLS-1$
+	}
+	if (isParamTag()) {
+		if (flagsBuffer.length() > 0) flagsBuffer.append(',');
+		flagsBuffer.append("param tag"); //$NON-NLS-1$
+	}
+	if (flagsBuffer.length() > 0) {
+		if (inlined) buffer.append('\t');
+		buffer.append("	flags: "); //$NON-NLS-1$
+		buffer.append(flagsBuffer);
+		buffer.append('\n');
+	}
+	if (this.nodesPtr > -1) {
+		for (int i = 0; i <= this.nodesPtr; i++) {
+			if (inlined) buffer.append('\t');
+			this.nodes[i].toString(buffer);
+		}
+	}
+}
+
+public String toStringDebug(char[] source) {
+	StringBuffer buffer = new StringBuffer();
+	toStringDebug(buffer, source);
+	return buffer.toString();
+}
+
+public void toStringDebug(StringBuffer buffer, char[] source) {
+	if (this.tagValue > 0) {
+		buffer.append(source, this.sourceStart, this.tagEnd-this.sourceStart+1);
+		buffer.append(' ');
+	}
+	if (this.reference != null) {
+		this.reference.toStringDebug(buffer, source);
+	}
+	for (int i=0; i<=this.nodesPtr; i++) {
+		this.nodes[i].toStringDebug(buffer, source);
+	}
+}
+
+void update(Scanner scanner) {
+	int blockEnd = scanner.getLineNumber(this.sourceEnd);
+	if (blockEnd == this.lineStart) {
+		this.flags |= FormatJavadocBlock.ONE_LINE_TAG;
+	}
+	for (int i=0; i<=this.nodesPtr; i++) {
+		if (!this.nodes[i].isText()) {
+			((FormatJavadocBlock)this.nodes[i]).update(scanner);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocNode.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocNode.java
new file mode 100644
index 0000000..b73283b
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocNode.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+
+/**
+ * Abstract class for all {@link FormatJavadoc} nodes.
+ * <p>
+ * The basic information for these nodes are the start and end positions in the
+ * source.
+ * </p>
+ */
+public abstract class FormatJavadocNode implements JavadocTagConstants {
+
+	// default size used for array
+	final static int DEFAULT_ARRAY_SIZE = 10;
+	final static int INCREMENT_ARRAY_SIZE = 10;
+	protected int sourceStart, sourceEnd;
+	protected int lineStart;
+	protected int linesBefore = 0;
+
+public FormatJavadocNode(int start, int end, int line) {
+	this.sourceStart = start;
+	this.sourceEnd = end;
+	this.lineStart = line;
+}
+
+abstract void clean();
+
+FormatJavadocNode getLastNode() {
+	return null;
+}
+
+public int getLength() {
+	return this.sourceEnd - this.sourceStart + 1;
+}
+
+/**
+ * Returns whether the node is a text (see {@link FormatJavadocText} or not.
+ * In case not, that means that the node is an block (see
+ * {@link FormatJavadocBlock}).
+ *
+ * @return <code>true</code> if the node is a text <code>false</code>
+ * 	otherwise.
+ */
+public boolean isText() {
+	return false;
+}
+
+/**
+ * Returns whether the node is immutable or not. If <code>true</code>, then
+ * the formatter will leave it contents unchanged.
+ *
+ * @return <code>true</code> if the node is immutable, <code>false</code>
+ * 	otherwise.
+ */
+public boolean isImmutable() {
+	return false;
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	toString(buffer);
+	return buffer.toString();
+}
+protected void toString(StringBuffer buffer) {
+	buffer.append(": "); //$NON-NLS-1$
+	buffer.append(this.sourceStart);
+	buffer.append(" -> ");	//$NON-NLS-1$
+	buffer.append(this.sourceEnd);
+}
+
+public String toStringDebug(char[] source) {
+	StringBuffer buffer = new StringBuffer();
+	toStringDebug(buffer, source);
+	return buffer.toString();
+}
+
+public void toStringDebug(StringBuffer buffer, char[] source) {
+	buffer.append(source, this.sourceStart, this.sourceEnd-this.sourceStart+1);
+	buffer.append(' ');
+}
+
+void setHeaderLine(int javadocLineStart) {
+	// do nothing
+}
+
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocReference.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocReference.java
new file mode 100644
index 0000000..0f72661
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocReference.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+/**
+ * Represents a reference in a javadoc comment block (see
+ * {@link FormatJavadocBlock}.
+ * <p>
+ * A specific class is used as intermediate positions need to be stored for further
+ * formatting improvements (typically for qualified references).
+ * </p>
+ */
+public class FormatJavadocReference extends FormatJavadocNode {
+
+public FormatJavadocReference(int start, int end, int line) {
+	super(start, end, line);
+}
+
+public FormatJavadocReference(long position, int line) {
+	super((int) (position >>> 32), (int) position, line);
+}
+
+void clean() {
+	// Clean positions when used
+}
+
+protected void toString(StringBuffer buffer) {
+	buffer.append("ref");	//$NON-NLS-1$
+	super.toString(buffer);
+}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocText.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocText.java
new file mode 100644
index 0000000..a4ff1e3
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatJavadocText.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;
+
+/**
+ * Represents text inside a javadoc comment block.
+ * <p>
+ * Text may be simple as <code>Line inside a javadoc comment block</code>
+ * or may be a html tag. Note that to minimize memory footprint, only text
+ * positions are stored.
+ * </p><p>
+ * Simple text may have one or several lines. When it has several lines, the
+ * positions of the line breaks are also stored in the {@link #separators} array.
+ * </p><p>
+ * When text has html tags, then they are stored in {@link #htmlNodes} array
+ * in a recursive way.
+ * </p>
+ */
+public class FormatJavadocText extends FormatJavadocNode implements IJavaDocTagConstants {
+
+	long[] separators;
+	int separatorsPtr = -1;
+	private int htmlTagIndex = -1;
+	boolean immutable = false;
+	FormatJavadocNode[] htmlNodes;
+	int[] htmlIndexes;
+	int htmlNodesPtr = -1;
+	int depth = 0;
+
+public FormatJavadocText(int start, int end, int line, int htmlIndex, int htmlDepth) {
+	super(start, end, line);
+	this.htmlTagIndex = htmlIndex;
+	this.depth = htmlDepth;
+}
+
+/*
+ * Append a text to current one.
+ * If the given text is not an html tag or is a closing tag, then just append to
+ * the current text recording the separators. Otherwise, create a new html tag
+ * child node.
+ */
+void appendText(FormatJavadocText text) {
+	text.immutable = this.immutable;
+	if (this.depth == text.depth) {
+		addSeparator(text);
+		this.sourceEnd = text.sourceEnd;
+		if (text.isClosingHtmlTag()) {
+			// close the tag
+			this.htmlTagIndex = text.htmlTagIndex;
+		}
+	} else {
+		appendNode(text);
+	}
+	if (text.isHtmlTag()) {
+		switch (text.htmlTagIndex & JAVADOC_TAGS_ID_MASK) {
+			case JAVADOC_CODE_TAGS_ID:
+				text.linesBefore = this.htmlNodesPtr == -1 ? 0 : 2;
+				break;
+			case JAVADOC_SEPARATOR_TAGS_ID:
+				text.linesBefore = 1;
+				break;
+	    	case JAVADOC_SINGLE_BREAK_TAG_ID:
+				if (!text.isClosingHtmlTag()) text.linesBefore = 1;
+				break;
+	    	case JAVADOC_BREAK_TAGS_ID:
+				if (!text.isClosingHtmlTag()) text.linesBefore = 1;
+		}
+	}
+}
+void appendNode(FormatJavadocNode node) {
+	if (++this.htmlNodesPtr == 0) { // lazy initialization
+		this.htmlNodes = new FormatJavadocNode[DEFAULT_ARRAY_SIZE];
+	} else {
+		if (this.htmlNodesPtr == this.htmlNodes.length) {
+			int size = this.htmlNodesPtr + DEFAULT_ARRAY_SIZE;
+			System.arraycopy(this.htmlNodes, 0, (this.htmlNodes= new FormatJavadocNode[size]), 0, this.htmlNodesPtr);
+		}
+	}
+	addSeparator(node);
+	this.htmlNodes[this.htmlNodesPtr] = node;
+	this.sourceEnd = node.sourceEnd;
+}
+
+private void addSeparator(FormatJavadocNode node) {
+	// Just append the text
+	if (++this.separatorsPtr == 0) { // lazy initialization
+		this.separators = new long[DEFAULT_ARRAY_SIZE];
+		this.htmlIndexes = new int[DEFAULT_ARRAY_SIZE];
+	} else { // resize if needed
+		if (this.separatorsPtr == this.separators.length) {
+			int size = this.separatorsPtr + DEFAULT_ARRAY_SIZE;
+			System.arraycopy(this.separators, 0, (this.separators = new long[size]), 0, this.separatorsPtr);
+			System.arraycopy(this.htmlIndexes, 0, (this.htmlIndexes = new int[size]), 0, this.separatorsPtr);
+		}
+	}
+	this.separators[this.separatorsPtr] = (((long) this.sourceEnd) << 32) + node.sourceStart;
+	this.htmlIndexes[this.separatorsPtr] = node.isText() ? ((FormatJavadocText)node).htmlTagIndex : -1;
+}
+
+void clean() {
+	int length = this.separators == null ? 0 : this.separators.length;
+	if (this.separatorsPtr != (length-1)) {
+		System.arraycopy(this.separators, 0, this.separators = new long[this.separatorsPtr+1], 0, this.separatorsPtr+1);
+		System.arraycopy(this.htmlIndexes, 0, this.htmlIndexes = new int[this.separatorsPtr+1], 0, this.separatorsPtr+1);
+	}
+	length = this.htmlNodes == null ? 0 : this.htmlNodes.length;
+	if (this.htmlNodesPtr != (length-1)) {
+		System.arraycopy(this.htmlNodes, 0, this.htmlNodes = new FormatJavadocNode[this.htmlNodesPtr+1], 0, this.htmlNodesPtr+1);
+		for (int i=0; i<=this.htmlNodesPtr; i++) {
+			this.htmlNodes[i].clean();
+		}
+	}
+}
+
+void closeTag() {
+	this.htmlTagIndex |= JAVADOC_CLOSED_TAG;
+}
+
+int getHtmlTagIndex() {
+	return this.htmlTagIndex & JAVADOC_TAGS_INDEX_MASK;
+}
+
+int getHtmlTagID() {
+	return this.htmlTagIndex & JAVADOC_TAGS_ID_MASK;
+}
+
+FormatJavadocNode getLastNode() {
+	if (this.htmlNodes != null) {
+		return this.htmlNodes[this.htmlNodesPtr];
+	}
+	return null;
+}
+
+/**
+ * Returns whether the text is a closing html tag or not.
+ *
+ * @return <code>true</code> if the node is an html tag and has '/' before its
+ * 	name (e.g. </bla>), <code>false</code> otherwise.
+ */
+public boolean isClosingHtmlTag() {
+	return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_CLOSED_TAG) != 0;
+}
+
+/**
+ * Returns whether the text is a html tag or not.
+ *
+ * @return <code>true</code> if the node is a html tag, <code>false</code>
+ * 	otherwise.
+ */
+public boolean isHtmlTag() {
+	return this.htmlTagIndex != -1;
+}
+
+/**
+ * Returns whether the node is an immutable html tag or not.
+ * <p>
+ * The text in an immutable tags is <b>never</b> formatted.
+ * </p>
+ *
+ * @return <code>true</code> if the node is an immutable tag,
+ *		<code>false</code> otherwise.
+ */
+public boolean isImmutableHtmlTag() {
+	return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID;
+
+}
+
+/**
+ * Returns whether the text is immutable or not.
+ * <p>
+ * A text in considered as immutable when it  belongs to an immutable block
+ * or when it's an immutable html tag.
+ * </p>
+ *
+ * @return <code>true</code> if the node is an immutable tag,
+ *		<code>false</code> otherwise.
+ */
+public boolean isImmutable() {
+	return this.immutable || (this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID);
+
+}
+
+/**
+ * Returns whether the text at the given separator index position is after a
+ * separator tag or not.
+ *
+ * @return <code>true</code> if the text is after a separator tag,
+ *		<code>false</code> otherwise or if the given index is out the range of
+ *		the text separators.
+ */
+public boolean isTextAfterHtmlSeparatorTag(int separatorIndex) {
+	int ptr = separatorIndex;
+	if (ptr > this.separatorsPtr) return false;
+	int tagIndex = this.htmlIndexes[ptr] & JAVADOC_TAGS_ID_MASK;
+	return tagIndex != -1 && tagIndex == JAVADOC_SEPARATOR_TAGS_ID;
+
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.formatter.FormatJavadocNode#isText()
+ */
+public boolean isText() {
+	return true;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.formatter.FormatJavadocNode#setHeaderLine(int)
+ */
+void setHeaderLine(int javadocLineStart) {
+	for (int i=0; i<this.htmlNodesPtr; i++) {
+		FormatJavadocNode node = this.htmlNodes[i];
+		if (!node.isText()) {
+			((FormatJavadocBlock) node).setHeaderLine(javadocLineStart);
+		}
+	}
+}
+
+protected void toString(StringBuffer buffer) {
+	StringBuffer indentation = new StringBuffer();
+	for (int t=0; t<=this.depth; t++) indentation.append('\t');
+	buffer.append(indentation);
+	if (isImmutable()) {
+		buffer.append("immutable "); //$NON-NLS-1$
+	}
+	buffer.append("text"); //$NON-NLS-1$
+	super.toString(buffer);
+	buffer.append(" ("); //$NON-NLS-1$
+	buffer.append(this.separatorsPtr+1).append(" sections, "); //$NON-NLS-1$
+	buffer.append(this.htmlNodesPtr+1).append(" html tags, "); //$NON-NLS-1$
+	buffer.append(this.depth).append(" depth, "); //$NON-NLS-1$
+	buffer.append(this.linesBefore).append(" before, "); //$NON-NLS-1$
+	String tagID = "no"; //$NON-NLS-1$
+	switch (getHtmlTagID()) {
+		case JAVADOC_TAGS_ID_MASK:
+			tagID = "mask"; //$NON-NLS-1$
+			break;
+		case JAVADOC_SINGLE_BREAK_TAG_ID:
+			tagID = "single break"; //$NON-NLS-1$
+			break;
+		case JAVADOC_CODE_TAGS_ID:
+			tagID = "code"; //$NON-NLS-1$
+			break;
+		case JAVADOC_BREAK_TAGS_ID:
+			tagID = "break"; //$NON-NLS-1$
+			break;
+		case JAVADOC_IMMUTABLE_TAGS_ID:
+			tagID = "immutable"; //$NON-NLS-1$
+			break;
+		case JAVADOC_SEPARATOR_TAGS_ID:
+			tagID = "separator"; //$NON-NLS-1$
+			break;
+	}
+	buffer.append(tagID).append(" tag id)"); //$NON-NLS-1$
+	buffer.append('\n');
+}
+
+public void toStringDebug(StringBuffer buffer, char[] source) {
+	if (buffer.length() > 0) {
+		for (int l=0; l<this.linesBefore; l++) {
+			buffer.append('\n');
+			for (int t=0; t<this.depth; t++) buffer.append('\t');
+		}
+	}
+	if (this.separatorsPtr == -1) {
+		super.toStringDebug(buffer, source);
+		return;
+	}
+	int ptr = 0;
+	int nextStart = this.sourceStart;
+	int idx = 0;
+	while (idx<=this.separatorsPtr || (this.htmlNodesPtr != -1 && ptr <= this.htmlNodesPtr)) {
+		if (idx > this.separatorsPtr) {
+			// last node
+			FormatJavadocNode node = this.htmlNodes[ptr++];
+			node.toStringDebug(buffer, source);
+			return;
+		}
+		int end = (int) (this.separators[idx] >>> 32);
+		if (this.htmlNodesPtr >= 0 && ptr <= this.htmlNodesPtr && end > this.htmlNodes[ptr].sourceStart) {
+			FormatJavadocNode node = this.htmlNodes[ptr++];
+			node.toStringDebug(buffer, source);
+		} else {
+			if (idx > 1 && source[nextStart] != '<') {
+				buffer.append('\n');
+				for (int t=0; t<this.depth; t++) buffer.append('\t');
+			}
+			buffer.append(source, nextStart, end - nextStart + 1);
+		}
+		nextStart = (int) this.separators[idx++];
+	}
+	if (source[nextStart] == '<') {
+		switch (getHtmlTagID()) {
+			case JAVADOC_CODE_TAGS_ID:
+				buffer.append('\n');
+				for (int t=0; t<this.depth; t++) buffer.append('\t');
+				break;
+		}
+	}
+	buffer.append(source, nextStart, this.sourceEnd-nextStart+1);
+	buffer.append(' ');
+}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java
new file mode 100644
index 0000000..2e3e1d6
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/FormatterCommentParser.java
@@ -0,0 +1,832 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;
+
+/**
+ * Internal parser used for formatting javadoc comments.
+ */
+public class FormatterCommentParser extends JavadocParser implements IJavaDocTagConstants {
+	char[][] htmlTags;
+	int htmlTagsPtr = -1;
+	int inlineHtmlTagsPtr = -1;
+	private boolean invalidTagName;
+	public boolean parseHtmlTags;
+
+public FormatterCommentParser(long sourceLevel) {
+	super(null);
+	this.kind = FORMATTER_COMMENT_PARSER | TEXT_PARSE;
+	this.reportProblems = false;
+	this.checkDocComment = true;
+	this.sourceLevel = sourceLevel;
+}
+
+public boolean parse(int start, int end) {
+
+	// Init
+	this.javadocStart = start;
+	this.javadocEnd = end;
+	this.firstTagPosition = this.javadocStart;
+	// Need to flush html tags stack in case of unclosed ones in previous javadoc comments
+	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=239941
+	this.htmlTagsPtr = -1;
+
+	// parse comment
+	boolean valid = commentParse();
+
+	return valid && this.docComment != null;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createArgumentReference(char[], int, boolean, java.lang.Object, long[], long)
+ */
+protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object ref, long[] dimPositions, long argNamePos) throws InvalidInputException {
+	FormatJavadocReference typeRef = (FormatJavadocReference) ref;
+	if (dim > 0) {
+		typeRef.sourceEnd = (int) dimPositions[dim-1];
+	}
+	if (argNamePos >= 0) typeRef.sourceEnd = (int) argNamePos;
+	return ref;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createFakeReference(int)
+ */
+protected boolean createFakeReference(int start) {
+	// synch scanner and parser positions
+	this.scanner.currentPosition = this.index;
+	// create reference in order to be able to format it
+	int lineStart = this.scanner.getLineNumber(start);
+	FormatJavadocReference reference = new FormatJavadocReference(start, this.index-1, lineStart);
+	return pushSeeRef(reference);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createFieldReference(java.lang.Object)
+ */
+protected Object createFieldReference(Object receiver) throws InvalidInputException {
+	int start = receiver == null ? this.memberStart : ((FormatJavadocReference)receiver).sourceStart;
+	int lineStart = this.scanner.getLineNumber(start);
+	return new FormatJavadocReference(start, (int) this.identifierPositionStack[0], lineStart);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createMethodReference(java.lang.Object, java.util.List)
+ */
+protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+	int start = receiver == null ? this.memberStart : ((FormatJavadocReference) receiver).sourceStart;
+	int lineStart = this.scanner.getLineNumber(start);
+	return new FormatJavadocReference(start, this.scanner.getCurrentTokenEndPosition(), lineStart);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createTag()
+ */
+protected void createTag() {
+	int lineStart = this.scanner.getLineNumber(this.tagSourceStart);
+	if (this.inlineTagStarted) {
+		FormatJavadocBlock block = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, this.tagValue);
+		FormatJavadocBlock previousBlock = null;
+		if (this.astPtr == -1) {
+			previousBlock = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, NO_TAG_VALUE);
+			pushOnAstStack(previousBlock, true);
+		} else {
+			previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
+		}
+		previousBlock.addBlock(block, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
+	} else {
+		FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineStart, this.tagValue);
+		pushOnAstStack(block, true);
+	}
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createTypeReference(int)
+ */
+protected Object createTypeReference(int primitiveToken) {
+	int size = this.identifierLengthStack[this.identifierLengthPtr];
+	if (size == 0) return null;
+	int start = (int) (this.identifierPositionStack[this.identifierPtr] >>> 32);
+	int lineStart = this.scanner.getLineNumber(start);
+	if (size == 1) {
+		return new FormatJavadocReference(this.identifierPositionStack[this.identifierPtr], lineStart);
+	}
+	long[] positions = new long[size];
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr - size + 1, positions, 0, size);
+	return new FormatJavadocReference((int) (positions[0] >>> 32), (int) positions[positions.length-1], lineStart);
+}
+
+/*
+ * Return the html tag index in the various arrays of IJavaDocTagConstants.
+ * The returned int is set as follow:
+ * 	- the array index is set on bits 0 to 7
+ * 	- the tag category is set on bit 8 to 15 (0xFF00 if no array includes the tag)
+ */
+private int getHtmlTagIndex(char[] htmlTag) {
+	int length = htmlTag == null ? 0 : htmlTag.length;
+	int tagId = 0;
+	if (length > 0) {
+		for (int i=0, max=JAVADOC_SINGLE_BREAK_TAG.length; i<max; i++) {
+			char[] tag = JAVADOC_SINGLE_BREAK_TAG[i];
+			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
+				return (tagId | JAVADOC_SINGLE_BREAK_TAG_ID) + i;
+			}
+		}
+		for (int i=0, max=JAVADOC_CODE_TAGS.length; i<max; i++) {
+			char[] tag = JAVADOC_CODE_TAGS[i];
+			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
+				return (tagId | JAVADOC_CODE_TAGS_ID) + i;
+			}
+		}
+		for (int i=0, max=JAVADOC_BREAK_TAGS.length; i<max; i++) {
+			char[] tag = JAVADOC_BREAK_TAGS[i];
+			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
+				return (tagId | JAVADOC_BREAK_TAGS_ID) + i;
+			}
+		}
+		for (int i=0, max=JAVADOC_IMMUTABLE_TAGS.length; i<max; i++) {
+			char[] tag = JAVADOC_IMMUTABLE_TAGS[i];
+			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
+				return (tagId | JAVADOC_IMMUTABLE_TAGS_ID) + i;
+			}
+		}
+		for (int i=0, max=JAVADOC_SEPARATOR_TAGS.length; i<max; i++) {
+			char[] tag = JAVADOC_SEPARATOR_TAGS[i];
+			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
+				return (tagId | JAVADOC_SEPARATOR_TAGS_ID) + i;
+			}
+		}
+	}
+	return JAVADOC_TAGS_ID_MASK;
+}
+
+/*
+ * Parse an HTML tag expected to be either opening (e.g. <tag_name> ) or
+ * closing (e.g. </tag_name>).
+ */
+protected boolean parseHtmlTag(int previousPosition, int endTextPosition) throws InvalidInputException {
+	if (!this.parseHtmlTags) return false;
+    boolean closing = false;
+    boolean valid = false;
+    boolean incremented = false;
+    int start = this.scanner.currentPosition;
+    int currentPosition = start;
+    int htmlPtr = this.htmlTagsPtr;
+    char firstChar = peekChar();
+    boolean hasWhitespaces = firstChar == ' ' || ScannerHelper.isWhitespace(firstChar);
+	try {
+	    int token = readTokenAndConsume();
+	    char[] htmlTag;
+	    int htmlIndex;
+	    switch (token) {
+	    	case TerminalTokens.TokenNameIdentifier:
+	    		// HTML tag opening
+				htmlTag = this.scanner.getCurrentIdentifierSource();
+				htmlIndex = getHtmlTagIndex(htmlTag);
+				if (htmlIndex == JAVADOC_TAGS_ID_MASK) return false;
+				if (htmlPtr >= 0) {
+		    		int lastHtmlTagIndex = getHtmlTagIndex(this.htmlTags[htmlPtr]);
+					if ((lastHtmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID) {
+						// Do not accept tags inside immutable tags except the <pre> tag
+						if ((htmlIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_CODE_TAGS_ID) {
+							FormatJavadocBlock previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
+							FormatJavadocNode parentNode = previousBlock;
+							FormatJavadocNode lastNode = parentNode;
+							while (lastNode.getLastNode() != null) {
+								parentNode = lastNode;
+								lastNode = lastNode.getLastNode();
+							}
+							if (lastNode.isText()) {
+								FormatJavadocText text = (FormatJavadocText) lastNode;
+								if (text.separatorsPtr == -1) {
+									break;
+								}
+							}
+						}
+		    			return false;
+					}
+	    		}
+				if ((htmlIndex & JAVADOC_TAGS_ID_MASK) > JAVADOC_SINGLE_TAGS_ID) {
+		    		if (this.htmlTagsPtr == -1 || !CharOperation.equals(this.htmlTags[this.htmlTagsPtr], htmlTag, false)) {
+						if (++this.htmlTagsPtr == 0) { // lazy initialization
+							this.htmlTags = new char[AST_STACK_INCREMENT][];
+						} else { // resize if needed
+							if (this.htmlTagsPtr == this.htmlTags.length) {
+								System.arraycopy(this.htmlTags, 0, (this.htmlTags = new char[this.htmlTags.length + AST_STACK_INCREMENT][]), 0, this.htmlTagsPtr);
+							}
+						}
+						this.htmlTags[this.htmlTagsPtr] = htmlTag;
+						incremented = true;
+		    		}
+				}
+				// Accept xhtml syntax
+				currentPosition = this.scanner.currentPosition;
+				if (readToken() == TerminalTokens.TokenNameDIVIDE) {
+					consumeToken();
+				}
+		    	break;
+	    	case TerminalTokens.TokenNameDIVIDE:
+	    		// HTML tag closing
+	    		if (this.htmlTagsPtr == -1) return false;
+	    		htmlTag = this.htmlTags[this.htmlTagsPtr];
+	    		if ((token = readTokenAndConsume()) != TerminalTokens.TokenNameIdentifier) {
+	    			// not a closing html tag
+	    			return false;
+	    		}
+				char[] identifier = this.scanner.getCurrentIdentifierSource();
+				htmlIndex = getHtmlTagIndex(identifier);
+				if (htmlIndex == JAVADOC_TAGS_ID_MASK) return false;
+				int ptr = this.htmlTagsPtr;
+	    		while (!CharOperation.equals(htmlTag, identifier, false)) {
+	    			if (this.htmlTagsPtr <= 0) {
+	    				// consider the closing tag as invalid
+	    				this.htmlTagsPtr = ptr;
+	    				return false;
+	    			}
+	    			this.htmlTagsPtr--;
+		    		htmlTag = this.htmlTags[this.htmlTagsPtr];
+	    		}
+				// set closing flag
+				htmlIndex |= JAVADOC_CLOSED_TAG;
+				closing = true;
+				currentPosition = this.scanner.currentPosition;
+	    		break;
+	    	default:
+    			return false;
+	    }
+	    
+	    // Looking for tag closing
+	    switch (readTokenAndConsume()) {
+	    	case TerminalTokens.TokenNameLESS:
+	    	case TerminalTokens.TokenNameLESS_EQUAL:
+	    		// consider that the closing '>' is missing
+	    		return false;
+	    	case TerminalTokens.TokenNameGREATER:
+	    		// simple tag without attributes
+	    		break;
+	    	case TerminalTokens.TokenNameGREATER_EQUAL:
+	    	case TerminalTokens.TokenNameRIGHT_SHIFT:
+	    	case TerminalTokens.TokenNameRIGHT_SHIFT_EQUAL:
+	    		// simple tag without attributes, but the closing '>' is followed by an '=' or '>'
+	    		break;
+	    	default:
+	    		this.index = currentPosition;
+	    		loop: while (true) {
+//	    			currentPosition = this.index;
+				    switch (readChar()) {
+				    	case '<':
+				    		if (hasWhitespaces) {
+				    			// not 100% sure this is a tag definition => give up
+				    			return false;
+				    		}
+				    		// opening tag => consider the current one as closed
+				    		this.index = currentPosition;
+				    		this.scanner.startPosition = currentPosition;
+				    		this.scanner.currentPosition = currentPosition;
+				    		this.scanner.currentCharacter = '<';
+				    		break loop;
+				    	case '>':
+				    		// simple tag without attributes
+				    		this.scanner.startPosition = this.index;
+				    		this.scanner.currentPosition = this.index;
+				    		this.scanner.currentCharacter = peekChar();
+				    		break loop;
+			    		default:
+			    			break;
+				    }
+				    if (this.index >= this.javadocTextEnd) {
+		    			// the end of the comment is reached => consider current tag as closed
+			    		this.index = currentPosition;
+			    		this.scanner.startPosition = currentPosition;
+			    		this.scanner.currentPosition = currentPosition;
+			    		break;
+				    }
+	    		}
+		}
+
+	    // Push texts
+		if (this.lineStarted && this.textStart != -1 && this.textStart < endTextPosition) {
+			pushText(this.textStart, endTextPosition, -1, htmlPtr);
+		}
+		pushText(previousPosition, this.index, htmlIndex, this.htmlTagsPtr);
+		this.textStart = -1;
+		valid = true;
+	}
+	finally {
+		if (valid) {
+			if (closing) {
+				this.htmlTagsPtr--;
+			}
+		} else if (!this.abort) {
+	    	if (incremented) {
+	    		this.htmlTagsPtr--;
+	    		if (this.htmlTagsPtr == -1) this.htmlTags = null;
+	    	}
+	    	this.scanner.resetTo(start, this.scanner.eofPosition-1);
+	    	this.index = start;
+		}
+	}
+    return valid;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseIdentifierTag(boolean)
+ */
+protected boolean parseIdentifierTag(boolean report) {
+	if (super.parseIdentifierTag(report)) {
+		createTag();
+		this.index = this.tagSourceEnd+1;
+		this.scanner.resetTo(this.index, this.javadocEnd);
+		return true;
+	}
+	this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
+	return false;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseParam()
+ */
+protected boolean parseParam() throws InvalidInputException {
+	boolean valid = super.parseParam();
+	if (!valid) {
+		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
+		this.index = this.tagSourceEnd+1;
+		char ch = peekChar();
+		// Try to push an identifier in the stack, otherwise restart from the end tag position
+		if (ch == ' ' || ScannerHelper.isWhitespace(ch)) {
+			int token = this.scanner.getNextToken();
+			if (token == TerminalTokens.TokenNameIdentifier) {
+				ch = peekChar();
+				if (ch == ' ' || ScannerHelper.isWhitespace(ch)) {
+					pushIdentifier(true, false);
+					pushParamName(false);
+					this.index = this.scanner.currentPosition;
+					valid = true;
+				}
+			}
+			this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
+		}
+		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
+	}
+	return valid;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseReference()
+ */
+protected boolean parseReference() throws InvalidInputException {
+	boolean valid = super.parseReference();
+	if (!valid) {
+		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
+		this.index = this.tagSourceEnd+1;
+		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
+	}
+	return valid;
+}
+
+/*
+ * Parse @return tag declaration
+ */
+protected boolean parseReturn() {
+	createTag();
+	return true;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseTag(int)
+ */
+protected boolean parseTag(int previousPosition) throws InvalidInputException {
+
+	// Do not parse javadoc tag inside <pre>...</pre> tags
+	if (this.htmlTagsPtr >= 0) {
+		int ptr = this.htmlTagsPtr;
+   		while (ptr >= 0) {
+			if (getHtmlTagIndex(this.htmlTags[ptr--]) == JAVADOC_CODE_TAGS_ID) {
+				if (this.textStart == -1) this.textStart = this.inlineTagStarted ? this.inlineTagStart : previousPosition;
+				this.inlineTagStarted = false;
+				return true;
+			}
+		}
+	}
+
+	// Read tag name
+	int ptr = this.astPtr;
+	this.tagSourceStart = previousPosition;
+	this.scanner.startPosition = this.index;
+	this.scanner.currentCharacter = readChar();
+	switch (this.scanner.currentCharacter) {
+		case ' ':
+		case '*':
+		case '}':
+			// tag name is empty
+			this.tagSourceEnd = previousPosition;
+			if (this.textStart == -1) this.textStart = previousPosition;
+			return true;
+		default:
+			if (ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
+				// tag name is empty
+				this.tagSourceEnd = previousPosition;
+				if (this.textStart == -1) this.textStart = previousPosition;
+				return true;
+			}
+			break;
+	}
+	int currentPosition = this.index;
+	char currentChar = this.scanner.currentCharacter;
+	while (currentChar != ' ' && currentChar != '*' && currentChar != '}' && !ScannerHelper.isWhitespace(currentChar)) {
+		currentPosition = this.index;
+		currentChar = readChar();
+	}
+	this.tagSourceEnd = currentPosition - 1;
+	this.scanner.currentCharacter = currentChar;
+	this.scanner.currentPosition = currentPosition;
+	char[] tagName = this.scanner.getCurrentIdentifierSource();
+	int length = tagName.length;
+	this.index = this.tagSourceEnd+1;
+
+	// Decide which parse to perform depending on tag name
+	this.tagValue = TAG_OTHERS_VALUE;
+	boolean valid = false;
+	switch (tagName[0]) {
+		case 'a':
+			if (length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName)) {
+				this.tagValue = TAG_AUTHOR_VALUE;
+			}
+			break;
+		case 'c':
+			if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName)) {
+				this.tagValue = TAG_CATEGORY_VALUE;
+				valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec
+			} else if (length == TAG_CODE_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_CODE, tagName)) {
+				this.tagValue = TAG_CODE_VALUE;
+			}
+			break;
+		case 'd':
+			if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName)) {
+				this.deprecated = true;
+				valid = true;
+				this.tagValue = TAG_DEPRECATED_VALUE;
+			} else if (length == TAG_DOC_ROOT_LENGTH && CharOperation.equals(TAG_DOC_ROOT, tagName)) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227730
+				// identify @docRoot tag as a base tag that does not expect any argument
+				valid = true;
+				this.tagValue = TAG_DOC_ROOT_VALUE;
+			}
+			break;
+		case 'e':
+			if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName)) {
+				this.tagValue = TAG_EXCEPTION_VALUE;
+				valid = parseThrows();
+			}
+			break;
+		case 'i':
+			if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) {
+				if (this.reportProblems) {
+					recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
+				}
+				valid = true;
+				this.tagValue = TAG_INHERITDOC_VALUE;
+			}
+			break;
+		case 'l':
+			if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) {
+				this.tagValue = TAG_LINK_VALUE;
+				if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
+					valid = parseReference();
+				} else {
+					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+					// Cannot have @link outside inline comment
+					valid = false;
+					if (this.reportProblems) {
+						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+					}
+				}
+			} else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName)) {
+				this.tagValue = TAG_LINKPLAIN_VALUE;
+				if (this.inlineTagStarted) {
+					valid = parseReference();
+				} else {
+					valid = false;
+					if (this.reportProblems) {
+						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+					}
+				}
+			} else if (length == TAG_LITERAL_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_LITERAL, tagName)) {
+				this.tagValue = TAG_LITERAL_VALUE;
+			}
+			break;
+		case 'p':
+			if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName)) {
+				this.tagValue = TAG_PARAM_VALUE;
+				valid = parseParam();
+			}
+			break;
+		case 's':
+			if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName)) {
+				if (this.inlineTagStarted) {
+					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+					// Cannot have @see inside inline comment
+					valid = false;
+					if (this.reportProblems) {
+						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+					}
+				} else {
+					this.tagValue = TAG_SEE_VALUE;
+					valid = parseReference();
+				}
+			} else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName)) {
+				this.tagValue = TAG_SERIAL_VALUE;
+			} else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName)) {
+				this.tagValue = TAG_SERIAL_DATA_VALUE;
+			} else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName)) {
+				this.tagValue = TAG_SERIAL_FIELD_VALUE;
+			} else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName)) {
+				this.tagValue = TAG_SINCE_VALUE;
+			}
+			break;
+		case 'v':
+			if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) {
+				this.tagValue = TAG_VALUE_VALUE;
+				if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+					if (this.inlineTagStarted) {
+						valid = parseReference();
+					} else {
+						valid = false;
+						if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+					}
+				}
+			} else if (length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName)) {
+				this.tagValue = TAG_VERSION_VALUE;
+			} else {
+				createTag();
+			}
+			break;
+		case 'r':
+			if (length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName)) {
+				this.tagValue = TAG_RETURN_VALUE;
+				valid = parseReturn();
+			}
+			break;
+		case 't':
+			if (length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName)) {
+				this.tagValue = TAG_THROWS_VALUE;
+				valid = parseThrows();
+			}
+			break;
+		default:
+			createTag();
+			break;
+	}
+	consumeToken();
+	this.textStart = -1;
+
+	// the javadoc parser may not create tag for some valid tags: force tag creation for such tag.
+	if (valid) {
+		switch (this.tagValue) {
+			case TAG_INHERITDOC_VALUE:
+			case TAG_DEPRECATED_VALUE:
+				createTag();
+				break;
+		}
+	} else if (this.invalidTagName) {
+		this.textStart = previousPosition;
+	} else if (this.astPtr == ptr) {
+		createTag();
+	}
+	return true;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseThrows()
+ */
+protected boolean parseThrows() {
+	boolean valid = super.parseThrows();
+	if (!valid) {
+		// If invalid, restart from the end tag position
+		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
+		this.index = this.tagSourceEnd+1;
+		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
+	}
+	return valid;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#pushParamName(boolean)
+ */
+protected boolean pushParamName(boolean isTypeParam) {
+	int lineTagStart = this.scanner.getLineNumber(this.tagSourceStart);
+	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineTagStart, TAG_PARAM_VALUE);
+	int start = (int) (this.identifierPositionStack[0] >>> 32);
+	int lineStart = this.scanner.getLineNumber(start);
+	FormatJavadocReference reference;
+	reference = new FormatJavadocReference(start, (int) this.identifierPositionStack[isTypeParam ? 2 : 0], lineStart);
+	block.reference = reference;
+	block.sourceEnd = reference.sourceEnd;
+	pushOnAstStack(block, true);
+	return true;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#pushSeeRef(java.lang.Object)
+ */
+protected boolean pushSeeRef(Object statement) {
+	FormatJavadocReference reference = (FormatJavadocReference) statement;
+	int lineTagStart = this.scanner.getLineNumber(this.tagSourceStart);
+	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineTagStart, this.tagValue);
+	block.reference = reference;
+	block.sourceEnd = reference.sourceEnd;
+	if (this.inlineTagStarted) {
+		block.sourceStart = this.inlineTagStart;
+		FormatJavadocBlock previousBlock = null;
+		if (this.astPtr == -1) {
+			int lineStart = this.scanner.getLineNumber(this.inlineTagStart);
+			previousBlock = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, NO_TAG_VALUE);
+			previousBlock.sourceEnd = reference.sourceEnd;
+			pushOnAstStack(previousBlock, true);
+		} else {
+			previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
+		}
+		previousBlock.addBlock(block, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
+		block.flags |= FormatJavadocBlock.INLINED;
+	} else {
+		pushOnAstStack(block, true);
+	}
+
+	return true;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
+ */
+protected void pushText(int start, int end) {
+	pushText(start, end, -1, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
+}
+
+private void pushText(int start, int end, int htmlIndex, int htmlDepth) {
+
+	// Search previous tag on which to add the text element
+	FormatJavadocBlock previousBlock = null;
+	int previousStart = start;
+	int lineStart = this.scanner.getLineNumber(start);
+	if (this.astPtr == -1) {
+		previousBlock = new FormatJavadocBlock(start, start, lineStart, NO_TAG_VALUE);
+		pushOnAstStack(previousBlock, true);
+	} else {
+		previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
+		previousStart = previousBlock.sourceStart;
+	}
+
+	// If we're in a inline tag, then retrieve previous tag in its fragments
+	if (this.inlineTagStarted) {
+		if (previousBlock.nodes == null) {
+			// no existing fragment => just add the element
+		} else {
+			// If last fragment is a tag, then use it as previous tag
+			FormatJavadocNode lastNode = previousBlock.nodes[previousBlock.nodesPtr];
+			while (lastNode != null && lastNode.isText()) {
+				lastNode = lastNode.getLastNode();
+			}
+			if (lastNode != null) {
+				previousBlock = (FormatJavadocBlock) lastNode;
+				previousStart = previousBlock.sourceStart;
+			}
+		}
+	}
+
+	// Add the text
+	FormatJavadocText text = new FormatJavadocText(start, end-1, lineStart, htmlIndex, htmlDepth==-1 ? 0 : htmlDepth);
+	previousBlock.addText(text);
+	previousBlock.sourceStart = previousStart;
+	if (lineStart == previousBlock.lineStart) {
+		previousBlock.flags |= FormatJavadocBlock.TEXT_ON_TAG_LINE;
+	}
+	this.textStart = -1;
+}
+
+/*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushThrowName(java.lang.Object)
+ */
+protected boolean pushThrowName(Object typeRef) {
+	int lineStart = this.scanner.getLineNumber(this.tagSourceStart);
+	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineStart, this.tagValue);
+	block.reference = (FormatJavadocReference) typeRef;
+	block.sourceEnd = block.reference.sourceEnd;
+	pushOnAstStack(block, true);
+	return true;
+}
+
+/*
+ * (non-Javadoc)
+ * Will update the inline tag position (end position) once tag was fully parsed.
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#refreshInlineTagPosition(int)
+ */
+protected void refreshInlineTagPosition(int previousPosition) {
+	if (this.astPtr != -1) {
+		FormatJavadocNode previousBlock = (FormatJavadocNode) this.astStack[this.astPtr];
+		if (this.inlineTagStarted) {
+			FormatJavadocNode lastNode = previousBlock;
+			while (lastNode != null) {
+				lastNode.sourceEnd = previousPosition;
+				lastNode = lastNode.getLastNode();
+			}
+		}
+	}
+}
+
+/*
+ * Store the html tags level when entering an inline tag in case a wrong sequence
+ * of opening/closing tags is defined inside it. Then, when leaving the inline tag
+ * the level is reset to the entering value and avoid to wrongly attach subsequent
+ * html tags to node inside the inline tag last node...
+ */
+protected void setInlineTagStarted(boolean started) {
+	super.setInlineTagStarted(started);
+	if (started) {
+		this.inlineHtmlTagsPtr = this.htmlTagsPtr;
+	} else {
+		if (this.htmlTagsPtr > this.inlineHtmlTagsPtr) {
+			this.htmlTagsPtr = this.inlineHtmlTagsPtr;
+		}
+	}
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("FormatterCommentParser\n"); //$NON-NLS-1$
+	buffer.append(super.toString());
+	return buffer.toString();
+}
+
+public String toDebugString() {
+	if (this.docComment == null) {
+		return "No javadoc!";	//$NON-NLS-1$
+	}
+	return ((FormatJavadoc)this.docComment).toDebugString(this.source);
+}
+
+/*
+ * Add stored tag elements to associated comment.
+ * Clean all blocks (i.e. resize arrays to avoid null slots)
+ * Set extra information on block about line relative positions.
+ */
+protected void updateDocComment() {
+	int length = this.astPtr + 1;
+	FormatJavadoc formatJavadoc = new FormatJavadoc(this.javadocStart, this.javadocEnd, length);
+	if (length > 0) {
+		formatJavadoc.blocks = new FormatJavadocBlock[length];
+		for (int i=0; i<length; i++) {
+			FormatJavadocBlock block = (FormatJavadocBlock) this.astStack[i];
+			block.clean();
+			block.update(this.scanner);
+			formatJavadoc.blocks[i] = block;
+			if (i== 0) {
+				block.flags |= FormatJavadocBlock.FIRST;
+			}
+		}
+	}
+	formatJavadoc.textStart = this.javadocTextStart;
+	formatJavadoc.textEnd = this.javadocTextEnd;
+	formatJavadoc.lineStart = this.scanner.getLineNumber(this.javadocTextStart);
+	formatJavadoc.lineEnd = this.scanner.getLineNumber(this.javadocTextEnd);
+	FormatJavadocBlock firstBlock = formatJavadoc.getFirstBlock();
+	if (firstBlock != null) {
+		firstBlock.setHeaderLine(formatJavadoc.lineStart);
+	}
+	this.docComment = formatJavadoc;
+	if (DefaultCodeFormatter.DEBUG) {
+		System.out.println(toDebugString());
+	}
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#verifyEndLine(int)
+ */
+protected boolean verifyEndLine(int textPosition) {
+	// do not verify anything at end of line while formatting
+	return true;
+}
+
+protected boolean verifySpaceOrEndComment() {
+	// Don't care if there's no spaces after a reference...
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/ICodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/ICodeFormatterConstants.java
new file mode 100644
index 0000000..7b06d55
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/ICodeFormatterConstants.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter;
+
+/**
+ * Internal code formatter constants.
+ *
+ * @since 3.4
+ */
+
+public interface ICodeFormatterConstants {
+    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=122247
+    // constants used to handle the addition of new lines after annotations
+
+	/** annotation on unspecified source*/
+	public static final int ANNOTATION_UNSPECIFIED = 0;
+
+	/** annotation on a type */
+	public static final int ANNOTATION_ON_TYPE = 1;
+
+	/** annotation on a field */
+	public static final int ANNOTATION_ON_FIELD = 2;
+
+	/** annotation on a method */
+	public static final int ANNOTATION_ON_METHOD = 3;
+
+	/** annotation on a package */
+	public static final int ANNOTATION_ON_PACKAGE = 4;
+
+	/** annotation on a parameter */
+	public static final int ANNOTATION_ON_PARAMETER = 5;
+
+	/** annotation on a local variable */
+	public static final int ANNOTATION_ON_LOCAL_VARIABLE = 6;
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java
new file mode 100644
index 0000000..bf82570
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+/**
+ * A location maintains positional information both in original source and in the output source.
+ * It remembers source offsets, line/column and indentation level.
+ * @since 2.1
+ */
+public class Location {
+
+	public int inputOffset;
+	/** deprecated */
+	public int inputColumn;
+	public int outputLine;
+	public int outputColumn;
+	public int outputIndentationLevel;
+	public boolean needSpace;
+	public boolean pendingSpace;
+	public int nlsTagCounter;
+	public int lastLocalDeclarationSourceStart;
+	public int numberOfIndentations;
+
+	// chunk management
+	public int lastNumberOfNewLines;
+
+	// edits management
+	int editsIndex;
+	OptimizedReplaceEdit textEdit;
+
+	public Location(Scribe scribe, int sourceRestart){
+		update(scribe, sourceRestart);
+	}
+
+	public void update(Scribe scribe, int sourceRestart){
+		this.outputColumn = scribe.column;
+		this.outputLine = scribe.line;
+		this.inputOffset = sourceRestart;
+		this.inputColumn = scribe.getCurrentIndentation(sourceRestart) + 1;
+		this.outputIndentationLevel = scribe.indentationLevel;
+		this.lastNumberOfNewLines = scribe.lastNumberOfNewLines;
+		this.needSpace = scribe.needSpace;
+		this.pendingSpace = scribe.pendingSpace;
+		this.editsIndex = scribe.editsIndex;
+		this.nlsTagCounter = scribe.nlsTagCounter;
+		this.numberOfIndentations = scribe.numberOfIndentations;
+		this.textEdit = scribe.getLastEdit();
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("output (column="+this.outputColumn); //$NON-NLS-1$
+		buffer.append(", line="+this.outputLine); //$NON-NLS-1$
+		buffer.append(", indentation level="+this.outputIndentationLevel); //$NON-NLS-1$
+		buffer.append(") input (offset="+this.inputOffset); //$NON-NLS-1$
+		buffer.append(", column="+this.inputColumn); //$NON-NLS-1$
+		buffer.append(')');
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java
new file mode 100644
index 0000000..6905adc
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+public class OptimizedReplaceEdit {
+
+	int offset;
+	int length;
+	String replacement;
+
+	public OptimizedReplaceEdit(int offset, int length, String replacement) {
+		this.offset = offset;
+		this.length = length;
+		this.replacement = replacement;
+	}
+
+	public String toString() {
+		return (this.offset < 0 ? "(" : "X(") + this.offset + ", length " + this.length + " :>" + this.replacement + "<"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ //$NON-NLS-5$
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
new file mode 100644
index 0000000..b2d59c0
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
@@ -0,0 +1,5149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Ray V. (voidstar@gmail.com) - Contribution for bug 282988
+ *     Jesper S Moller - Contribution for bug 402892
+ *                       Contribution for bug 402818
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
+import org.eclipse.jdt.internal.core.util.RecordedParsingInformation;
+import org.eclipse.jdt.internal.formatter.align.Alignment;
+import org.eclipse.jdt.internal.formatter.align.AlignmentException;
+import org.eclipse.jdt.internal.formatter.comment.CommentFormatterUtil;
+import org.eclipse.jdt.internal.formatter.comment.HTMLEntity2JavaReader;
+import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;
+import org.eclipse.jdt.internal.formatter.comment.Java2HTMLEntityReader;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This class is responsible for dumping formatted source
+ * @since 2.1
+ */
+public class Scribe implements IJavaDocTagConstants {
+
+	private static final int INITIAL_SIZE = 100;
+
+	private boolean checkLineWrapping;
+	/** one-based column */
+	public int column;
+	private int[][] commentPositions;
+
+	// Most specific alignment.
+	public Alignment currentAlignment;
+	public int currentToken;
+
+	// edits management
+	private OptimizedReplaceEdit[] edits;
+	public int editsIndex;
+
+	public CodeFormatterVisitor formatter;
+	public int indentationLevel;
+	public int lastNumberOfNewLines;
+	private boolean preserveLineBreakIndentation = false;
+	public int line;
+
+	private int[] lineEnds;
+	private int maxLines;
+	public Alignment memberAlignment;
+	public boolean needSpace = false;
+
+	// Line separator infos
+	final private String lineSeparator;
+	final private String lineSeparatorAndSpace;
+	final private char firstLS;
+	final private int lsLength;
+
+	public int nlsTagCounter;
+	public int pageWidth;
+	public boolean pendingSpace = false;
+
+	public Scanner scanner;
+	public int scannerEndPosition;
+	public int tabLength;
+	public int indentationSize;
+	private final IRegion[] regions;
+	private IRegion[] adaptedRegions;
+	public int tabChar;
+	public int numberOfIndentations;
+	private boolean useTabsOnlyForLeadingIndents;
+
+	/** empty lines*/
+	private final boolean indentEmptyLines;
+	int blank_lines_between_import_groups = -1;
+
+	// Preserve empty lines constants
+	public static final int DO_NOT_PRESERVE_EMPTY_LINES = -1;
+	public static final int PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION = 1;
+	public static final int PRESERVE_EMPTY_LINES_IN_FORMAT_LEFT_CURLY_BRACE = 2;
+	public static final int PRESERVE_EMPTY_LINES_IN_STRING_LITERAL_CONCATENATION = 3;
+	public static final int PRESERVE_EMPTY_LINES_IN_CLOSING_ARRAY_INITIALIZER = 4;
+	public static final int PRESERVE_EMPTY_LINES_IN_FORMAT_OPENING_BRACE = 5;
+	public static final int PRESERVE_EMPTY_LINES_IN_BINARY_EXPRESSION = 6;
+	public static final int PRESERVE_EMPTY_LINES_IN_EQUALITY_EXPRESSION = 7;
+	public static final int PRESERVE_EMPTY_LINES_BEFORE_ELSE = 8;
+	public static final int PRESERVE_EMPTY_LINES_IN_SWITCH_CASE = 9;
+	public static final int PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION = 10;
+	public static final int PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK = 11;
+	final static int PRESERVE_EMPTY_LINES_DO_NOT_USE_ANY_INDENTATION = -1;
+	final static int PRESERVE_EMPTY_LINES_USE_CURRENT_INDENTATION = 0;
+	final static int PRESERVE_EMPTY_LINES_USE_TEMPORARY_INDENTATION = 1;
+
+	/** disabling */
+	boolean editsEnabled;
+	boolean useTags;
+	int tagsKind;
+
+	/* Comments formatting */
+	private static final int INCLUDE_BLOCK_COMMENTS = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_MULTI_LINE_COMMENT;
+	private static final int INCLUDE_JAVA_DOC = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_JAVA_DOC;
+	private static final int INCLUDE_LINE_COMMENTS = CodeFormatter.F_INCLUDE_COMMENTS | CodeFormatter.K_SINGLE_LINE_COMMENT;
+	private static final int SKIP_FIRST_WHITESPACE_TOKEN = -2;
+	private static final int INVALID_TOKEN = 2000;
+	static final int NO_TRAILING_COMMENT = 0x0000;
+	static final int BASIC_TRAILING_COMMENT = 0x0100;
+	static final int COMPLEX_TRAILING_COMMENT = 0x0200;
+	static final int IMPORT_TRAILING_COMMENT = COMPLEX_TRAILING_COMMENT | 0x0001;
+	static final int UNMODIFIABLE_TRAILING_COMMENT = 0x0400;
+	private int formatComments = 0;
+	private int headerEndPosition = -1;
+	String commentIndentation; // indentation requested in comments (usually in javadoc root tags description)
+
+	// Class to store previous line comment information
+	static class LineComment {
+		boolean contiguous = false;
+		int currentIndentation, indentation;
+		int lines;
+		char[] leadingSpaces;
+	}
+	final LineComment lastLineComment = new LineComment();
+
+	// New way to format javadoc
+	private FormatterCommentParser formatterCommentParser; // specialized parser to format comments
+
+	// Disabling and enabling tags
+	OptimizedReplaceEdit previousDisabledEdit;
+	private char[] disablingTag, enablingTag;
+
+	// Well know strings
+	private String[] newEmptyLines = new String[10];
+	private static String[] COMMENT_INDENTATIONS = new String[20];
+
+	// final string buffers
+	private final StringBuffer tempBuffer= new StringBuffer();
+	private final StringBuffer blockCommentBuffer = new StringBuffer();
+	private final StringBuffer blockCommentTokensBuffer = new StringBuffer();
+	private final StringBuffer codeSnippetBuffer = new StringBuffer();
+	private final StringBuffer javadocBlockRefBuffer= new StringBuffer();
+	private final StringBuffer javadocGapLinesBuffer = new StringBuffer();
+	private StringBuffer[] javadocHtmlTagBuffers = new StringBuffer[5];
+	private final StringBuffer javadocTextBuffer = new StringBuffer();
+	private final StringBuffer javadocTokensBuffer = new StringBuffer();
+
+	Scribe(CodeFormatterVisitor formatter, long sourceLevel, IRegion[] regions, CodeSnippetParsingUtil codeSnippetParsingUtil, boolean includeComments) {
+		initializeScanner(sourceLevel, formatter.preferences);
+		this.formatter = formatter;
+		this.pageWidth = formatter.preferences.page_width;
+		this.tabLength = formatter.preferences.tab_size;
+		this.indentationLevel= 0; // initialize properly
+		this.numberOfIndentations = 0;
+		this.useTabsOnlyForLeadingIndents = formatter.preferences.use_tabs_only_for_leading_indentations;
+		this.indentEmptyLines = formatter.preferences.indent_empty_lines;
+		this.tabChar = formatter.preferences.tab_char;
+		if (this.tabChar == DefaultCodeFormatterOptions.MIXED) {
+			this.indentationSize = formatter.preferences.indentation_size;
+		} else {
+			this.indentationSize = this.tabLength;
+		}
+		this.lineSeparator = formatter.preferences.line_separator;
+		this.lineSeparatorAndSpace = this.lineSeparator+' ';
+		this.firstLS = this.lineSeparator.charAt(0);
+		this.lsLength = this.lineSeparator.length();
+		this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize;
+		this.regions= regions;
+		if (codeSnippetParsingUtil != null) {
+			final RecordedParsingInformation information = codeSnippetParsingUtil.recordedParsingInformation;
+			if (information != null) {
+				this.lineEnds = information.lineEnds;
+				this.commentPositions = information.commentPositions;
+			}
+		}
+		if (formatter.preferences.comment_format_line_comment) this.formatComments |= CodeFormatter.K_SINGLE_LINE_COMMENT;
+		if (formatter.preferences.comment_format_block_comment) this.formatComments |= CodeFormatter.K_MULTI_LINE_COMMENT;
+		if (formatter.preferences.comment_format_javadoc_comment) this.formatComments |= CodeFormatter.K_JAVA_DOC;
+		if (includeComments) this.formatComments |= CodeFormatter.F_INCLUDE_COMMENTS;
+		reset();
+	}
+
+	/**
+	 * This method will adapt the selected regions if needed.
+	 * If a region should be adapted (see isAdaptableRegion(IRegion))
+	 * retrieve correct upper and lower bounds and replace the region.
+	 */
+	private void adaptRegions() {
+		int max = this.regions.length;
+		if (max == 1) {
+			// It's not necessary to adapt the single region which covers all the source
+			if (this.regions[0].getOffset() == 0 && this.regions[0].getLength() == this.scannerEndPosition) {
+				this.adaptedRegions = this.regions;
+				return;
+			}
+		}
+		this.adaptedRegions = new IRegion[max];
+		int commentIndex = 0;
+		for (int i = 0; i < max; i++) {
+			IRegion aRegion = this.regions[i];
+			int offset = aRegion.getOffset();
+			int length = aRegion.getLength();
+
+			// First look if the region starts or ends inside a comment
+			int index = getCommentIndex(commentIndex, offset);
+			int adaptedOffset = offset;
+			int adaptedLength = length;
+			if (index >= 0) {
+				// the offset of the region is inside a comment => restart the region from the comment start
+				adaptedOffset = this.commentPositions[index][0];
+				if (adaptedOffset >= 0) {
+					// adapt only javadoc or block comments. Since fix for bug
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=238210
+					// edits in line comments only concerns whitespaces hence can be
+					// treated as edits in code
+					adaptedLength = length + offset - adaptedOffset;
+					commentIndex = index;
+				}
+			}
+			index = getCommentIndex(commentIndex, offset+length-1);
+			if (index >= 0 && this.commentPositions[index][0] >= 0) { // only javadoc or block comment
+				// the region end is inside a comment => set the region end at the comment end
+				int commentEnd = this.commentPositions[index][1];
+				if (commentEnd < 0) commentEnd = -commentEnd;
+				adaptedLength = commentEnd - adaptedOffset;
+				commentIndex = index;
+			}
+			if (adaptedLength != length) {
+				// adapt the region and jump to next one
+				this.adaptedRegions[i] = new Region(adaptedOffset, adaptedLength);
+			} else {
+				this.adaptedRegions[i] = aRegion;
+			}
+		}
+	}
+
+	/*
+	 * Adapt edits to regions.
+	 * 
+	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=234583"
+	 * 	for more details
+	 */
+	private void adaptEdits() {
+
+		// See if adapting edits is really necessary
+		int max = this.regions.length;
+		if (max == 1) {
+			if (this.regions[0].getOffset() == 0 && this.regions[0].getLength() == this.scannerEndPosition) {
+				// No need to adapt as the regions covers the whole source
+				return;
+			}
+		}
+
+		// Sort edits
+		OptimizedReplaceEdit[] sortedEdits = new OptimizedReplaceEdit[this.editsIndex];
+		System.arraycopy(this.edits, 0, sortedEdits, 0, this.editsIndex);
+		Arrays.sort(sortedEdits, new Comparator() {
+			public int compare(Object o1, Object o2) {
+		    	OptimizedReplaceEdit edit1 = (OptimizedReplaceEdit) o1;
+		    	OptimizedReplaceEdit edit2 = (OptimizedReplaceEdit) o2;
+				return edit1.offset - edit2.offset;
+            }
+		});
+
+		// Adapt overlapping edits
+		int currentEdit = -1;
+		for (int i = 0; i < max; i++) {
+			IRegion region = this.adaptedRegions[i];
+			int offset = region.getOffset();
+			int length = region.getLength();
+
+			// modify overlapping edits on the region (if any)
+			int index = adaptEdit(sortedEdits, currentEdit, offset, offset+length);
+			if (index != -1) {
+				currentEdit = index;
+			}
+		}
+
+    	// Set invalid all edits outside the region
+		if (currentEdit != -1) {
+			int length = sortedEdits.length;
+	    	for (int e=currentEdit; e<length; e++) {
+	    		sortedEdits[e].offset = -1;
+	    	}
+    	}
+	}
+
+	/*
+     * Search whether a region overlap edit(s) at its start and/or at its end.
+     * If so, modify the concerned edits to keep only the modifications which are
+     * inside the given region.
+     * 
+     * The edit modification is done as follow:
+     * 1) start it from the region start if it overlaps the region's start
+     * 2) end it at the region end if it overlaps the region's end
+     * 3) remove from the replacement string the number of lines which are outside
+     * the region: before when overlapping region's start and after when overlapping
+     * region's end. Note that the trailing indentation of the replacement string is not
+     * kept when the region's end is overlapped because it's always outside the
+     * region.
+     */
+    private int adaptEdit(OptimizedReplaceEdit[] sortedEdits, int start, int regionStart, int regionEnd) {
+    	int initialStart = start==-1 ? 0 : start;
+		int bottom = initialStart, top = sortedEdits.length - 1;
+    	int topEnd = top;
+    	int i = 0;
+    	OptimizedReplaceEdit edit = null;
+    	int overlapIndex = -1;
+
+    	// Look for an edit overlapping the region start
+    	while (bottom <= top) {
+    		i = bottom + (top - bottom) /2;
+    		edit = sortedEdits[i];
+    		int editStart = edit.offset;
+   			int editEnd = editStart + edit.length;
+    		if (editStart > regionStart) {  // the edit starts after the region's start => no possible overlap of region's start
+    			top = i-1;
+    			if (editStart > regionEnd) { // the edit starts after the region's end => no possible overlap of region's end
+    				topEnd = top;
+    			}
+    		} else {
+    			if (editEnd < regionStart) { // the edit ends before the region's start => no possible overlap of region's start
+	    			bottom = i+1;
+				} else {
+					// Count the lines of the edit which are outside the region
+					int linesOutside = 0;
+					StringBuffer spacesOutside = new StringBuffer();
+					this.scanner.resetTo(editStart, editEnd-1);
+					while (this.scanner.currentPosition < regionStart && !this.scanner.atEnd()) {
+						char ch = (char) this.scanner.getNextChar();
+						switch (ch) {
+							case '\n':
+								linesOutside++;
+								spacesOutside.setLength(0);
+								break;
+							case '\r':
+								break;
+							default:
+								spacesOutside.append(ch);
+								break;
+						}
+					}
+
+					// Restart the edit at the beginning of the line where the region start
+					edit.offset = regionStart;
+					int editLength = edit.length;
+					edit.length -= edit.offset - editStart;
+
+					// Cut replacement string if necessary
+					int length = edit.replacement.length();
+					if (length > 0) {
+
+						// Count the lines in replacement string
+						int linesReplaced = 0;
+						for (int idx=0; idx < length; idx++) {
+							if (edit.replacement.charAt(idx) == '\n') linesReplaced++;
+						}
+
+						// If the edit was a replacement but become an insertion due to the length reduction
+						// and if the edit finishes just before the region starts and if there's no line to replace
+						// then there's no replacement to do...
+						if (editLength > 0 && edit.length == 0 && editEnd == regionStart && linesReplaced == 0 && linesOutside== 0) {
+							edit.offset = -1;
+						} else {
+
+							// As the edit starts outside the region, remove first lines from edit string if any
+							if (linesReplaced > 0) {
+								int linesCount = linesOutside >= linesReplaced ? linesReplaced : linesOutside;
+								if (linesCount > 0) {
+									int idx = 0;
+									loop: while (idx < length) {
+										char ch = edit.replacement.charAt(idx);
+										switch (ch) {
+											case '\n':
+												linesCount--;
+												if (linesCount == 0) {
+													idx++;
+													break loop;
+												}
+												break;
+											case '\r':
+											case ' ':
+											case '\t':
+												break;
+											default:
+												break loop;
+										}
+										idx++;
+									}
+									// Compare spaces outside the region and the beginning
+									// of the replacement string to remove the common part
+									int spacesOutsideLength = spacesOutside.length();
+									int replacementStart = idx;
+									for (int o=0, r=0; o < spacesOutsideLength && r<(length-idx); o++) {
+										char rch = edit.replacement.charAt(idx + r);
+										char och = spacesOutside.charAt(o);
+										if (rch == och) {
+											replacementStart++;
+											r++;
+										} else if (rch == '\t' && (this.tabLength > 0 && och == ' ')) {
+											if ((o+1)%this.tabLength == 0) {
+												replacementStart++;
+												r++;
+											}
+										} else {
+											break;
+										}
+									}
+									// Update the replacement string
+									if (replacementStart > length || (replacementStart == length && spacesOutsideLength > 0)) {
+										edit.offset = -1;
+									} else if (spacesOutsideLength == 0 && replacementStart == length) {
+										edit.replacement = ""; //$NON-NLS-1$
+									} else {
+										edit.replacement = edit.replacement.substring(replacementStart);
+									}
+								}
+							}
+						}
+					}
+					overlapIndex = i;
+					break;
+				}
+			}
+    	}
+    	int validIndex = (overlapIndex != -1) ? overlapIndex : bottom;
+
+    	// Look for an edit overlapping the region end
+    	if (overlapIndex != -1) bottom = overlapIndex;
+    	while (bottom <= topEnd) {
+    		i = bottom + (topEnd - bottom) /2;
+    		edit = sortedEdits[i];
+    		int editStart = edit.offset;
+   			int editEnd = editStart + edit.length;
+   			if (regionEnd < editStart) {	// the edit starts after the region's end => no possible overlap of region's end
+    			topEnd = i-1;
+    		} else if (regionEnd == editStart) {	// special case when the edit starts just after the region's end...
+    			// ...we got the last index of the edit inside the region
+				topEnd = i - 1;
+    			// this last edit is valid only if it's an insertion and if it has indentation
+    			if (edit.length == 0) {
+    				int nrLength = 0;
+    				int rLength = edit.replacement.length();
+    				if (nrLength < rLength) {
+	    				int ch = edit.replacement.charAt(nrLength);
+	    				loop: while (nrLength < rLength) {
+		    				switch (ch) {
+		    					case ' ':
+		    					case '\t':
+		    						nrLength++;
+		    						break;
+		    					default:
+		    						break loop;
+		    				}
+	    				}
+    				}
+    				if (nrLength > 0) {
+	    				topEnd++;
+	    				if (nrLength < rLength) {
+	    					edit.replacement = edit.replacement.substring(0, nrLength);
+	    				}
+    				}
+    			}
+    			break;
+       		} else if (editEnd <= regionEnd) {	// the edit ends before the region's end => no possible overlap of region's end
+    			bottom = i+1;
+			} else {
+				// Count the lines of the edit which are outside the region
+				int linesOutside = 0;
+				this.scanner.resetTo(editStart, editEnd-1);
+				while (!this.scanner.atEnd()) {
+					boolean after = this.scanner.currentPosition >= regionEnd;
+                    char ch = (char) this.scanner.getNextChar();
+                	if (ch == '\n' ) {
+                		if (after) linesOutside++;
+                	}
+                }
+
+				// Cut replacement string if necessary
+				int length = edit.replacement.length();
+				if (length > 0) {
+
+					// Count the lines in replacement string
+					int linesReplaced = 0;
+					for (int idx=0; idx < length; idx++) {
+						if (edit.replacement.charAt(idx) == '\n') linesReplaced++;
+					}
+
+					// Set the replacement string to the number of missing new lines
+					// As the end of the edit is out of the region, the possible trailing
+					// indentation should not be added...
+					if (linesReplaced == 0) {
+		    			edit.replacement = ""; //$NON-NLS-1$
+					} else {
+						int linesCount = linesReplaced > linesOutside ? linesReplaced - linesOutside : 0;
+						if (linesCount == 0) {
+			    			edit.replacement = ""; //$NON-NLS-1$
+						} else {
+							edit.replacement = getNewLineString(linesCount);
+						}
+					}
+				}
+				edit.length = regionEnd - editStart;
+
+		    	// We got the last edit of the regions, give up
+				topEnd = i;
+				break;
+			}
+    	}
+
+    	// Set invalid all edits outside the region
+    	for (int e=initialStart; e<validIndex; e++) {
+    		sortedEdits[e].offset = -1;
+    	}
+    	
+    	// Return the index of next edit to look at
+    	return topEnd+1;
+    }
+
+	private final void addDeleteEdit(int start, int end) {
+		if (this.edits.length == this.editsIndex) {
+			// resize
+			resize();
+		}
+		addOptimizedReplaceEdit(start, end - start + 1, Util.EMPTY_STRING);
+	}
+
+	public final void addInsertEdit(int insertPosition, String insertedString) {
+		if (this.edits.length == this.editsIndex) {
+			// resize
+			resize();
+		}
+		addOptimizedReplaceEdit(insertPosition, 0, insertedString);
+	}
+
+	private final void addOptimizedReplaceEdit(int offset, int length, String replacement) {
+		if (!this.editsEnabled) {
+			if (this.previousDisabledEdit != null && this.previousDisabledEdit.offset == offset) {
+				replacement = this.previousDisabledEdit.replacement;
+			}
+			this.previousDisabledEdit = null;
+			if (replacement.indexOf(this.lineSeparator) >= 0) {
+				if (length == 0 || printNewLinesCharacters(offset, length)) {
+					this.previousDisabledEdit = new OptimizedReplaceEdit(offset, length, replacement);
+				}
+			}
+			return;
+		}
+		if (this.editsIndex > 0) {
+			// try to merge last two edits
+			final OptimizedReplaceEdit previous = this.edits[this.editsIndex-1];
+			final int previousOffset = previous.offset;
+			final int previousLength = previous.length;
+			final int endOffsetOfPreviousEdit = previousOffset + previousLength;
+			final int replacementLength = replacement.length();
+			final String previousReplacement = previous.replacement;
+			final int previousReplacementLength = previousReplacement.length();
+			if (previousOffset == offset && previousLength == length && (replacementLength == 0 || previousReplacementLength == 0)) {
+				if (this.currentAlignment != null) {
+					final Location location = this.currentAlignment.location;
+					if (location.editsIndex == this.editsIndex) {
+						location.editsIndex--;
+						location.textEdit = previous;
+					}
+				}
+				this.editsIndex--;
+				return;
+			}
+			if (endOffsetOfPreviousEdit == offset) {
+				if (length != 0) {
+					if (replacementLength != 0) {
+						this.edits[this.editsIndex - 1] = new OptimizedReplaceEdit(previousOffset, previousLength + length, previousReplacement + replacement);
+					} else if (previousLength + length == previousReplacementLength) {
+						// check the characters. If they are identical, we can get rid of the previous edit
+						boolean canBeRemoved = true;
+						loop: for (int i = previousOffset; i < previousOffset + previousReplacementLength; i++) {
+							if (this.scanner.source[i] != previousReplacement.charAt(i - previousOffset)) {
+								this.edits[this.editsIndex - 1] = new OptimizedReplaceEdit(previousOffset, previousReplacementLength, previousReplacement);
+								canBeRemoved = false;
+								break loop;
+							}
+						}
+						if (canBeRemoved) {
+							if (this.currentAlignment != null) {
+								final Location location = this.currentAlignment.location;
+								if (location.editsIndex == this.editsIndex) {
+									location.editsIndex--;
+									location.textEdit = previous;
+								}
+							}
+							this.editsIndex--;
+						}
+					} else {
+						this.edits[this.editsIndex - 1] = new OptimizedReplaceEdit(previousOffset, previousLength + length, previousReplacement);
+					}
+				} else {
+					if (replacementLength != 0) {
+						this.edits[this.editsIndex - 1] = new OptimizedReplaceEdit(previousOffset, previousLength, previousReplacement + replacement);
+					}
+				}
+			} else if ((offset + length == previousOffset) && (previousLength + length == replacementLength + previousReplacementLength)) {
+				// check if both edits corresponds to the orignal source code
+				boolean canBeRemoved = true;
+				String totalReplacement = replacement + previousReplacement;
+				loop: for (int i = 0; i < previousLength + length; i++) {
+					if (this.scanner.source[i + offset] != totalReplacement.charAt(i)) {
+						this.edits[this.editsIndex - 1] = new OptimizedReplaceEdit(offset, previousLength + length, totalReplacement);
+						canBeRemoved = false;
+						break loop;
+					}
+				}
+				if (canBeRemoved) {
+					if (this.currentAlignment != null) {
+						final Location location = this.currentAlignment.location;
+						if (location.editsIndex == this.editsIndex) {
+							location.editsIndex--;
+							location.textEdit = previous;
+						}
+					}
+					this.editsIndex--;
+				}
+			} else {
+				this.edits[this.editsIndex++] = new OptimizedReplaceEdit(offset, length, replacement);
+			}
+		} else {
+			this.edits[this.editsIndex++] = new OptimizedReplaceEdit(offset, length, replacement);
+		}
+	}
+
+	public final void addReplaceEdit(int start, int end, String replacement) {
+		if (this.edits.length == this.editsIndex) {
+			// resize
+			resize();
+		}
+		addOptimizedReplaceEdit(start,  end - start + 1, replacement);
+	}
+
+	public void alignFragment(Alignment alignment, int fragmentIndex){
+		alignment.fragmentIndex = fragmentIndex;
+		alignment.checkColumn();
+		alignment.performFragmentEffect();
+	}
+
+	public void checkNLSTag(int sourceStart) {
+		if (hasNLSTag(sourceStart)) {
+			this.nlsTagCounter++;
+		}
+	}
+
+	private int consumeInvalidToken(int end) {
+	    this.scanner.resetTo(this.scanner.startPosition, end);
+    	// In case of invalid unicode character, consume the current backslash character before continuing
+    	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=233228
+	    if (this.scanner.currentCharacter == '\\') {
+	    	this.scanner.currentPosition = this.scanner.startPosition+1;
+	    }
+	    int previousPosition = this.scanner.currentPosition;
+	    char ch = (char) this.scanner.getNextChar();
+	    if (this.scanner.atEnd()) {
+	    	// avoid infinite loop
+	    	return INVALID_TOKEN;
+	    }
+	    while (!this.scanner.atEnd() && ch != '*' && !ScannerHelper.isWhitespace(ch)) {
+	    	previousPosition = this.scanner.currentPosition;
+	    	ch = (char) this.scanner.getNextChar();
+	    }
+	    // restore last whitespace
+	    this.scanner.currentPosition = previousPosition;
+	    return INVALID_TOKEN;
+    }
+
+	public Alignment createAlignment(int kind, int mode, int count, int sourceRestart){
+		return createAlignment(kind, mode, Alignment.R_INNERMOST, count, sourceRestart);
+	}
+
+	public Alignment createAlignment(int kind, int mode, int tieBreakRule, int count, int sourceRestart){
+		return createAlignment(kind, mode, tieBreakRule, count, sourceRestart, this.formatter.preferences.continuation_indentation, false);
+	}
+
+	public Alignment createAlignment(int kind, int mode, int count, int sourceRestart, int continuationIndent, boolean adjust){
+		return createAlignment(kind, mode, Alignment.R_INNERMOST, count, sourceRestart, continuationIndent, adjust);
+	}
+
+	public Alignment createAlignment(int kind, int mode, int tieBreakRule, int count, int sourceRestart, int continuationIndent, boolean adjust){
+		Alignment alignment = new Alignment(kind, mode, tieBreakRule, this, count, sourceRestart, continuationIndent);
+		// specific break indentation for message arguments inside binary expressions
+		if ((this.currentAlignment == null && this.formatter.expressionsDepth >= 0) ||
+			(this.currentAlignment != null && this.currentAlignment.kind == Alignment.BINARY_EXPRESSION &&
+				(this.formatter.expressionsPos & CodeFormatterVisitor.EXPRESSIONS_POS_MASK) == CodeFormatterVisitor.EXPRESSIONS_POS_BETWEEN_TWO)) {
+			switch (kind) {
+				case Alignment.CONDITIONAL_EXPRESSION:
+				case Alignment.MESSAGE_ARGUMENTS:
+				case Alignment.MESSAGE_SEND:
+					if (this.formatter.lastBinaryExpressionAlignmentBreakIndentation == alignment.breakIndentationLevel) {
+						alignment.breakIndentationLevel += this.indentationSize;
+						alignment.shiftBreakIndentationLevel += this.indentationSize;
+						this.formatter.lastBinaryExpressionAlignmentBreakIndentation = 0;
+					}
+					break;
+			}
+		}
+		// adjust break indentation
+		if (adjust && this.memberAlignment != null) {
+			Alignment current = this.memberAlignment;
+			while (current.enclosing != null) {
+				current = current.enclosing;
+			}
+			if ((current.mode & Alignment.M_MULTICOLUMN) != 0) {
+				final int indentSize = this.indentationSize;
+				switch(current.chunkKind) {
+					case Alignment.CHUNK_METHOD :
+					case Alignment.CHUNK_TYPE :
+						if ((mode & Alignment.M_INDENT_BY_ONE) != 0) {
+							alignment.breakIndentationLevel = this.indentationLevel + indentSize;
+						} else {
+							alignment.breakIndentationLevel = this.indentationLevel + continuationIndent * indentSize;
+						}
+						alignment.update();
+						break;
+					case Alignment.CHUNK_FIELD :
+						if ((mode & Alignment.M_INDENT_BY_ONE) != 0) {
+							alignment.breakIndentationLevel = current.originalIndentationLevel + indentSize;
+						} else {
+							alignment.breakIndentationLevel = current.originalIndentationLevel + continuationIndent * indentSize;
+						}
+						alignment.update();
+						break;
+				}
+			} else {
+				switch(current.mode & Alignment.SPLIT_MASK) {
+					case Alignment.M_COMPACT_SPLIT :
+					case Alignment.M_COMPACT_FIRST_BREAK_SPLIT :
+					case Alignment.M_NEXT_PER_LINE_SPLIT :
+					case Alignment.M_NEXT_SHIFTED_SPLIT :
+					case Alignment.M_ONE_PER_LINE_SPLIT :
+						final int indentSize = this.indentationSize;
+						switch(current.chunkKind) {
+							case Alignment.CHUNK_METHOD :
+							case Alignment.CHUNK_TYPE :
+								if ((mode & Alignment.M_INDENT_BY_ONE) != 0) {
+									alignment.breakIndentationLevel = this.indentationLevel + indentSize;
+								} else {
+									alignment.breakIndentationLevel = this.indentationLevel + continuationIndent * indentSize;
+								}
+								alignment.update();
+								break;
+							case Alignment.CHUNK_FIELD :
+								if ((mode & Alignment.M_INDENT_BY_ONE) != 0) {
+									alignment.breakIndentationLevel = current.originalIndentationLevel + indentSize;
+								} else {
+									alignment.breakIndentationLevel = current.originalIndentationLevel + continuationIndent * indentSize;
+								}
+								alignment.update();
+								break;
+						}
+						break;
+				}
+			}
+		}
+		return alignment;
+	}
+
+	public Alignment createMemberAlignment(int kind, int mode, int count, int sourceRestart) {
+		Alignment mAlignment = createAlignment(kind, mode, Alignment.R_INNERMOST, count, sourceRestart);
+		mAlignment.breakIndentationLevel = this.indentationLevel;
+		return mAlignment;
+	}
+
+	public void enterAlignment(Alignment alignment){
+		alignment.enclosing = this.currentAlignment;
+		alignment.location.lastLocalDeclarationSourceStart = this.formatter.lastLocalDeclarationSourceStart;
+		this.currentAlignment = alignment;
+	}
+
+	public void enterMemberAlignment(Alignment alignment) {
+		alignment.enclosing = this.memberAlignment;
+		alignment.location.lastLocalDeclarationSourceStart = this.formatter.lastLocalDeclarationSourceStart;
+		this.memberAlignment = alignment;
+	}
+
+	public void exitAlignment(Alignment alignment, boolean discardAlignment){
+		Alignment current = this.currentAlignment;
+		while (current != null){
+			if (current == alignment) break;
+			current = current.enclosing;
+		}
+		if (current == null) {
+			throw new AbortFormatting("could not find matching alignment: "+alignment); //$NON-NLS-1$
+		}
+		this.indentationLevel = alignment.location.outputIndentationLevel;
+		this.numberOfIndentations = alignment.location.numberOfIndentations;
+		this.formatter.lastLocalDeclarationSourceStart = alignment.location.lastLocalDeclarationSourceStart;
+		if (discardAlignment){
+			this.currentAlignment = alignment.enclosing;
+			if (this.currentAlignment == null) {
+				this.formatter.lastBinaryExpressionAlignmentBreakIndentation = 0;
+			}
+		}
+	}
+
+	public void exitMemberAlignment(Alignment alignment){
+		Alignment current = this.memberAlignment;
+		while (current != null){
+			if (current == alignment) break;
+			current = current.enclosing;
+		}
+		if (current == null) {
+			throw new AbortFormatting("could not find matching alignment: "+alignment); //$NON-NLS-1$
+		}
+		this.indentationLevel = current.location.outputIndentationLevel;
+		this.numberOfIndentations = current.location.numberOfIndentations;
+		this.formatter.lastLocalDeclarationSourceStart = alignment.location.lastLocalDeclarationSourceStart;
+		this.memberAlignment = current.enclosing;
+	}
+
+	/**
+	 * Answer actual indentation level based on true column position
+	 * @return int
+	 */
+	public int getColumnIndentationLevel() {
+		return this.column - 1;
+	}
+
+	public final int getCommentIndex(int position) {
+		if (this.commentPositions == null)
+			return -1;
+		int length = this.commentPositions.length;
+		if (length == 0) {
+			return -1;
+		}
+		int g = 0, d = length - 1;
+		int m = 0;
+		while (g <= d) {
+			m = g + (d - g) / 2;
+			int bound = this.commentPositions[m][1];
+			if (bound < 0) {
+				bound = -bound;
+			}
+			if (bound < position) {
+				g = m + 1;
+			} else if (bound > position) {
+				d = m - 1;
+			} else {
+				return m;
+			}
+		}
+		return -(g + 1);
+	}
+
+	/*
+     * Returns the index of the comment including the given offset position
+     * starting the search from the given start index.
+     *
+     * @param start The start index for the research
+     * @param position The position
+     * @return The index of the comment if the given position is located inside it, -1 otherwise
+     */
+    private int getCommentIndex(int start, int position) {
+    	int commentsLength = this.commentPositions == null ? 0 : this.commentPositions.length;
+    	if (commentsLength == 0) return -1;
+    	if (position == 0) {
+    		if (commentsLength > 0 && this.commentPositions[0][0]== 0) {
+    			return 0;
+    		}
+    		return -1;
+    	}
+    	int bottom = start, top = commentsLength - 1;
+    	int i = 0;
+    	int[] comment = null;
+    	while (bottom <= top) {
+    		i = bottom + (top - bottom) /2;
+    		comment = this.commentPositions[i];
+    		int commentStart = comment[0];
+    		if (commentStart < 0) commentStart = -commentStart;
+    		if (position < commentStart) {
+    			top = i-1;
+    		} else {
+    			int commentEnd = comment[1];
+    			if (commentEnd < 0) commentEnd = -commentEnd;
+    			if (position >= commentEnd) {
+    				bottom = i+1;
+    			} else {
+    				return i;
+    			}
+    		}
+    	}
+    	return -1;
+    }
+
+	private int getCurrentCommentIndentation(int start) {
+		int linePtr = -Arrays.binarySearch(this.lineEnds, start);
+		int indentation = 0;
+		int beginningOfLine = getLineEnd(linePtr - 1)+1;
+		if (beginningOfLine == -1) {
+			beginningOfLine = 0;
+		}
+		int currentStartPosition = start;
+		char[] source = this.scanner.source;
+
+		// find the position of the beginning of the line containing the comment
+		while (beginningOfLine > currentStartPosition) {
+			if (linePtr > 0) {
+				beginningOfLine = getLineEnd(--linePtr)+1;
+			} else {
+				beginningOfLine = 0;
+				break;
+			}
+		}
+		for (int i=beginningOfLine; i < currentStartPosition ; i++) {
+			char currentCharacter = source[i];
+			switch (currentCharacter) {
+				case '\t' :
+					if (this.tabLength != 0) {
+						int reminder = indentation % this.tabLength;
+						if (reminder == 0) {
+							indentation += this.tabLength;
+						} else {
+							indentation = ((indentation / this.tabLength) + 1) * this.tabLength;
+						}
+					}
+					break;
+				case '\r' :
+				case '\n' :
+					indentation = 0;
+					break;
+				default:
+					indentation++;
+					break;
+			}
+		}
+		return indentation;
+	}
+
+	int getCurrentIndentation(char[] whitespaces, int offset) {
+		if (whitespaces == null) return offset;
+		int length = whitespaces.length;
+		if (this.tabLength == 0) return length;
+		int indentation = offset;
+		for (int i=0; i<length; i++) {
+			char ch = whitespaces[i];
+			switch (ch) {
+				case '\t' :
+					int reminder = indentation % this.tabLength;
+					if (reminder == 0) {
+						indentation += this.tabLength;
+					} else {
+						indentation = ((indentation / this.tabLength) + 1) * this.tabLength;
+					}
+					break;
+				case '\r' :
+				case '\n' :
+					indentation = 0;
+					break;
+				default:
+					indentation++;
+					break;
+			}
+		}
+		return indentation;
+	}
+
+	int getCurrentIndentation(int start) {
+		int linePtr = Arrays.binarySearch(this.lineEnds, start);
+		if (linePtr < 0) {
+			linePtr = -linePtr - 1;
+		}
+		int indentation = 0;
+		int beginningOfLine = getLineEnd(linePtr)+1;
+		if (beginningOfLine == -1) {
+			beginningOfLine = 0;
+		}
+		char[] source = this.scanner.source;
+
+		for (int i=beginningOfLine; i<start; i++) {
+			char currentCharacter = source[i];
+			switch (currentCharacter) {
+				case '\t' :
+					if (this.tabLength != 0) {
+						int reminder = indentation % this.tabLength;
+						if (reminder == 0) {
+							indentation += this.tabLength;
+						} else {
+							indentation = ((indentation / this.tabLength) + 1) * this.tabLength;
+						}
+					}
+					break;
+				case '\r' :
+				case '\n' :
+					indentation = 0;
+					break;
+				case ' ':
+					indentation++;
+					break;
+				default:
+					return indentation;
+			}
+		}
+		return indentation;
+	}
+
+	public String getEmptyLines(int linesNumber) {
+		if (this.nlsTagCounter > 0) {
+			return Util.EMPTY_STRING;
+		}
+		String emptyLines;
+		if (this.lastNumberOfNewLines == 0) {
+			linesNumber++; // add an extra line breaks
+			if (this.indentEmptyLines) {
+				this.tempBuffer.setLength(0);
+				for (int i = 0; i < linesNumber; i++) {
+					printIndentationIfNecessary(this.tempBuffer);
+					this.tempBuffer.append(this.lineSeparator);
+					this.column = 1;
+				}
+				emptyLines = this.tempBuffer.toString();
+			} else {
+				emptyLines = getNewLineString(linesNumber);
+			}
+			this.lastNumberOfNewLines += linesNumber;
+			this.line += linesNumber;
+			this.column = 1;
+			this.needSpace = false;
+			this.pendingSpace = false;
+		} else if (this.lastNumberOfNewLines == 1) {
+			if (this.indentEmptyLines) {
+				this.tempBuffer.setLength(0);
+				for (int i = 0; i < linesNumber; i++) {
+					printIndentationIfNecessary(this.tempBuffer);
+					this.tempBuffer.append(this.lineSeparator);
+					this.column = 1;
+				}
+				emptyLines = this.tempBuffer.toString();
+			} else {
+				emptyLines = getNewLineString(linesNumber);
+			}
+			this.lastNumberOfNewLines += linesNumber;
+			this.line += linesNumber;
+			this.column = 1;
+			this.needSpace = false;
+			this.pendingSpace = false;
+		} else {
+			if ((this.lastNumberOfNewLines - 1) >= linesNumber) {
+				// there is no need to add new lines
+				return Util.EMPTY_STRING;
+			}
+			final int realNewLineNumber = linesNumber - this.lastNumberOfNewLines + 1;
+			if (this.indentEmptyLines) {
+				this.tempBuffer.setLength(0);
+				for (int i = 0; i < realNewLineNumber; i++) {
+					printIndentationIfNecessary(this.tempBuffer);
+					this.tempBuffer.append(this.lineSeparator);
+					this.column = 1;
+				}
+				emptyLines = this.tempBuffer.toString();
+			} else {
+				emptyLines = getNewLineString(realNewLineNumber);
+			}
+			this.lastNumberOfNewLines += realNewLineNumber;
+			this.line += realNewLineNumber;
+			this.column = 1;
+			this.needSpace = false;
+			this.pendingSpace = false;
+		}
+		return emptyLines;
+	}
+
+	public OptimizedReplaceEdit getLastEdit() {
+		if (this.editsIndex > 0) {
+			return this.edits[this.editsIndex - 1];
+		}
+		return null;
+	}
+
+	public final int getLineEnd(int lineNumber) {
+		if (this.lineEnds == null)
+			return -1;
+		if (lineNumber >= this.lineEnds.length + 1)
+			return this.scannerEndPosition;
+		if (lineNumber <= 0)
+			return -1;
+		return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
+	}
+
+	Alignment getMemberAlignment() {
+		return this.memberAlignment;
+	}
+
+	public String getNewLine() {
+		if (this.nlsTagCounter > 0) {
+			return Util.EMPTY_STRING;
+		}
+		if (this.lastNumberOfNewLines >= 1) {
+			this.column = 1; // ensure that the scribe is at the beginning of a new line
+			return Util.EMPTY_STRING;
+		}
+		this.line++;
+		this.lastNumberOfNewLines = 1;
+		this.column = 1;
+		this.needSpace = false;
+		this.pendingSpace = false;
+		return this.lineSeparator;
+	}
+
+	private String getNewLineString(int linesCount) {
+		int length = this.newEmptyLines.length;
+		if (linesCount > length) {
+			System.arraycopy(this.newEmptyLines, 0, this.newEmptyLines = new String[linesCount+10], 0, length);
+		}
+		String newLineString = this.newEmptyLines[linesCount-1];
+		if (newLineString == null) {
+			this.tempBuffer.setLength(0);
+			for (int j=0; j<linesCount; j++) {
+				this.tempBuffer.append(this.lineSeparator);
+			}
+			newLineString = this.tempBuffer.toString();
+			this.newEmptyLines[linesCount-1] = newLineString;
+		}
+		return newLineString;
+	}
+
+	/**
+	 * Answer next indentation level based on column estimated position
+	 * (if column is not indented, then use indentationLevel)
+	 */
+	public int getNextIndentationLevel(int someColumn) {
+		int indent = someColumn - 1;
+		if (indent == 0)
+			return this.indentationLevel;
+		if (this.tabChar == DefaultCodeFormatterOptions.TAB) {
+			if (this.useTabsOnlyForLeadingIndents) {
+				return indent;
+			}
+			if (this.indentationSize == 0) {
+				return indent;
+			}
+			int rem = indent % this.indentationSize;
+			int addition = rem == 0 ? 0 : this.indentationSize - rem; // round to superior
+			return indent + addition;
+		}
+		return indent;
+	}
+
+	/*
+	 * Preserve empty lines depending on given count and preferences.
+	 */
+	private String getPreserveEmptyLines(int count, int emptyLinesRules) {
+		if (count == 0) {
+			int currentIndentationLevel = this.indentationLevel;
+			int useAlignmentBreakIndentation = useAlignmentBreakIndentation(emptyLinesRules);
+			switch (useAlignmentBreakIndentation) {
+				case PRESERVE_EMPTY_LINES_DO_NOT_USE_ANY_INDENTATION:
+					return Util.EMPTY_STRING;
+				default:
+					// Return the new indented line
+					StringBuffer buffer = new StringBuffer(getNewLine());
+					printIndentationIfNecessary(buffer);
+					if (useAlignmentBreakIndentation == PRESERVE_EMPTY_LINES_USE_TEMPORARY_INDENTATION) {
+						this.indentationLevel = currentIndentationLevel;
+					}
+					return buffer.toString();
+			}
+		}
+		if (this.blank_lines_between_import_groups >= 0) {
+			useAlignmentBreakIndentation(emptyLinesRules);
+			return getEmptyLines(this.blank_lines_between_import_groups);
+		}
+		if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
+			useAlignmentBreakIndentation(emptyLinesRules);
+			int linesToPreserve = Math.min(count, this.formatter.preferences.number_of_empty_lines_to_preserve);
+			return getEmptyLines(linesToPreserve);
+		}
+		return getNewLine();
+	}
+	private int useAlignmentBreakIndentation(int emptyLinesRules) {
+		// preserve line breaks in wrapping if specified
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=198074
+		boolean specificEmptyLinesRule = emptyLinesRules != PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION;
+		if ((this.currentAlignment != null || specificEmptyLinesRule) && !this.formatter.preferences.join_wrapped_lines) {
+			// insert a new line only if it has not been already done before
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=283476
+			if (this.lastNumberOfNewLines == 0 || specificEmptyLinesRule || this.formatter.arrayInitializersDepth >= 0) {
+				
+				// Do not use alignment break indentation in specific circumstances
+				boolean useAlignmentBreakIndentation;
+				boolean useAlignmentShiftBreakIndentation = false;
+				boolean useLastBinaryExpressionAlignmentBreakIndentation = false;
+				switch (emptyLinesRules) {
+					case DO_NOT_PRESERVE_EMPTY_LINES:
+					case PRESERVE_EMPTY_LINES_IN_SWITCH_CASE:
+					case PRESERVE_EMPTY_LINES_AT_END_OF_METHOD_DECLARATION:
+					case PRESERVE_EMPTY_LINES_AT_END_OF_BLOCK:
+						return PRESERVE_EMPTY_LINES_DO_NOT_USE_ANY_INDENTATION;
+					case PRESERVE_EMPTY_LINES_IN_BINARY_EXPRESSION:
+						useAlignmentBreakIndentation = true;
+						if ((this.formatter.expressionsPos & CodeFormatterVisitor.EXPRESSIONS_POS_MASK) == CodeFormatterVisitor.EXPRESSIONS_POS_BETWEEN_TWO) {
+							// we're just before the left expression, try to use the last
+							// binary expression break indentation if any
+							useLastBinaryExpressionAlignmentBreakIndentation = true;
+						}
+						break;
+					case PRESERVE_EMPTY_LINES_IN_EQUALITY_EXPRESSION:
+						useAlignmentShiftBreakIndentation = this.currentAlignment == null || this.currentAlignment.kind == Alignment.BINARY_EXPRESSION;
+						useAlignmentBreakIndentation = !useAlignmentShiftBreakIndentation;
+						break;
+					case PRESERVE_EMPTY_LINES_IN_FORMAT_OPENING_BRACE:
+						useAlignmentBreakIndentation = this.formatter.arrayInitializersDepth <= 1
+							&& this.currentAlignment != null
+							&& this.currentAlignment.kind == Alignment.ARRAY_INITIALIZER;
+						break;
+					case PRESERVE_EMPTY_LINES_IN_FORMAT_LEFT_CURLY_BRACE:
+						useAlignmentBreakIndentation = false;
+						break;
+					default:
+						if ((emptyLinesRules & 0xFFFF) == PRESERVE_EMPTY_LINES_IN_CLOSING_ARRAY_INITIALIZER && this.scanner.currentCharacter == '}' ) {
+							// last array initializer closing brace
+							this.indentationLevel = emptyLinesRules >> 16;
+							this.preserveLineBreakIndentation = true;
+							return PRESERVE_EMPTY_LINES_USE_CURRENT_INDENTATION;
+						}
+						useAlignmentBreakIndentation = true;
+						break;
+				}
+
+				// If there's an alignment try to align on its break indentation level
+				Alignment alignment = this.currentAlignment;
+				if (alignment == null) {
+					if (useLastBinaryExpressionAlignmentBreakIndentation) {
+						if (this.indentationLevel < this.formatter.lastBinaryExpressionAlignmentBreakIndentation) {
+							this.indentationLevel = this.formatter.lastBinaryExpressionAlignmentBreakIndentation;
+						}
+					}
+					if (useAlignmentShiftBreakIndentation && this.memberAlignment != null) {
+						if (this.indentationLevel < this.memberAlignment.shiftBreakIndentationLevel) {
+							this.indentationLevel = this.memberAlignment.shiftBreakIndentationLevel;
+						}
+					}
+				} else {
+					// Use the member alignment break indentation level when
+					// it's closer from the wrapped line than the current alignment
+					if (this.memberAlignment != null && this.memberAlignment.location.inputOffset > alignment.location.inputOffset) {
+						alignment = this.memberAlignment;
+					}
+
+					// Use the break indentation level if possible...
+					if (useLastBinaryExpressionAlignmentBreakIndentation) {
+						if (this.indentationLevel < this.formatter.lastBinaryExpressionAlignmentBreakIndentation) {
+							this.indentationLevel = this.formatter.lastBinaryExpressionAlignmentBreakIndentation;
+						}
+					}
+					if (useAlignmentBreakIndentation) {
+						if (this.indentationLevel < alignment.breakIndentationLevel) {
+							this.indentationLevel = alignment.breakIndentationLevel;
+						}
+					} else if (useAlignmentShiftBreakIndentation) {
+						if (this.indentationLevel < alignment.shiftBreakIndentationLevel) {
+							this.indentationLevel = alignment.shiftBreakIndentationLevel;
+						}
+					}
+				}
+				this.preserveLineBreakIndentation = true;
+				if (useLastBinaryExpressionAlignmentBreakIndentation || useAlignmentShiftBreakIndentation) {
+					return PRESERVE_EMPTY_LINES_USE_TEMPORARY_INDENTATION;
+				}
+				return PRESERVE_EMPTY_LINES_USE_CURRENT_INDENTATION;
+			}
+		}
+		return PRESERVE_EMPTY_LINES_DO_NOT_USE_ANY_INDENTATION;
+	}
+
+	public TextEdit getRootEdit() {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=208541
+		adaptRegions();
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=234583
+		adaptEdits();
+
+		MultiTextEdit edit = null;
+		int regionsLength = this.adaptedRegions.length;
+		int textRegionStart;
+		int textRegionEnd;
+		if (regionsLength == 1) {
+			IRegion lastRegion = this.adaptedRegions[0];
+			textRegionStart = lastRegion.getOffset();
+			textRegionEnd = textRegionStart + lastRegion.getLength();
+		} else {
+			textRegionStart = this.adaptedRegions[0].getOffset();
+			IRegion lastRegion = this.adaptedRegions[regionsLength - 1];
+			textRegionEnd = lastRegion.getOffset() + lastRegion.getLength();
+		}
+
+		int length = textRegionEnd - textRegionStart + 1;
+		if (textRegionStart <= 0) {
+			if (length <= 0) {
+				edit = new MultiTextEdit(0, 0);
+			} else {
+				edit = new MultiTextEdit(0, textRegionEnd);
+			}
+		} else {
+			edit = new MultiTextEdit(textRegionStart, length - 1);
+		}
+		for (int i= 0, max = this.editsIndex; i < max; i++) {
+			OptimizedReplaceEdit currentEdit = this.edits[i];
+			if (currentEdit.offset >= 0 && currentEdit.offset <= this.scannerEndPosition) {
+				if (currentEdit.length == 0 || (currentEdit.offset != this.scannerEndPosition && isMeaningfulEdit(currentEdit))) {
+					try {
+						edit.addChild(new ReplaceEdit(currentEdit.offset, currentEdit.length, currentEdit.replacement));
+					}
+					catch (MalformedTreeException ex) {
+						// log exception in case of error
+						CommentFormatterUtil.log(ex);
+	 					throw ex;
+					}
+				}
+			}
+		}
+		this.edits = null;
+		return edit;
+	}
+
+	public void handleLineTooLong() {
+		if (this.formatter.preferences.wrap_outer_expressions_when_nested) {
+			handleLineTooLongSmartly();
+			return;
+		}
+		// search for closest breakable alignment, using tiebreak rules
+		// look for outermost breakable one
+		int relativeDepth = 0, outerMostDepth = -1;
+		Alignment targetAlignment = this.currentAlignment;
+		while (targetAlignment != null){
+			if (targetAlignment.tieBreakRule == Alignment.R_OUTERMOST && targetAlignment.couldBreak()){
+				outerMostDepth = relativeDepth;
+			}
+			targetAlignment = targetAlignment.enclosing;
+			relativeDepth++;
+		}
+		if (outerMostDepth >= 0) {
+			throw new AlignmentException(AlignmentException.LINE_TOO_LONG, outerMostDepth);
+		}
+		// look for innermost breakable one
+		relativeDepth = 0;
+		targetAlignment = this.currentAlignment;
+		while (targetAlignment != null){
+			if (targetAlignment.couldBreak()){
+				throw new AlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
+			}
+			targetAlignment = targetAlignment.enclosing;
+			relativeDepth++;
+		}
+		// did not find any breakable location - proceed
+	}
+
+	private void handleLineTooLongSmartly() {
+		// search for closest breakable alignment, using tiebreak rules
+		// look for outermost breakable one
+		int relativeDepth = 0, outerMostDepth = -1;
+		Alignment targetAlignment = this.currentAlignment;
+		int previousKind = -1;
+		int insideMessage = 0;
+		boolean insideStringConcat = false;
+		while (targetAlignment != null){
+			boolean couldBreak = targetAlignment.tieBreakRule == Alignment.R_OUTERMOST ||
+				(!insideStringConcat &&
+						insideMessage > 0 && targetAlignment.kind == Alignment.MESSAGE_ARGUMENTS &&
+						(!targetAlignment.wasReset() || previousKind != Alignment.MESSAGE_SEND));
+			if (couldBreak && targetAlignment.couldBreak()){
+				outerMostDepth = relativeDepth;
+			}
+			switch (targetAlignment.kind) {
+				case Alignment.MESSAGE_ARGUMENTS:
+				case Alignment.MESSAGE_SEND:
+					insideMessage++;
+					break;
+				case Alignment.STRING_CONCATENATION:
+					insideStringConcat = true;
+					break;
+			}
+			previousKind = targetAlignment.kind;
+			targetAlignment = targetAlignment.enclosing;
+			relativeDepth++;
+		}
+		if (outerMostDepth >= 0) {
+			throw new AlignmentException(AlignmentException.LINE_TOO_LONG, outerMostDepth);
+		}
+		// look for innermost breakable one
+		relativeDepth = 0;
+		targetAlignment = this.currentAlignment;
+		AlignmentException alignmentException = null;
+		int msgArgsDepth = -1;
+		while (targetAlignment != null) {
+			if (targetAlignment.kind == Alignment.MESSAGE_ARGUMENTS) {
+				msgArgsDepth = relativeDepth;
+			}
+			if (alignmentException == null) {
+				if (targetAlignment.couldBreak()) {
+					// do not throw the exception immediately to have a chance to reset
+					// previously broken alignments (see bug 203588)
+					alignmentException = new AlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
+					if (insideStringConcat) throw alignmentException;
+				}
+			} else if (targetAlignment.wasSplit) {
+				// reset the nearest already broken outermost alignment.
+				// Note that it's not done twice to avoid infinite loop while raising
+				// the exception on an innermost alignment...
+				if (!targetAlignment.wasReset()) {
+					targetAlignment.reset();
+					if (msgArgsDepth > alignmentException.relativeDepth) {
+						alignmentException.relativeDepth = msgArgsDepth;
+					}
+					throw alignmentException;
+				}
+			}
+			targetAlignment = targetAlignment.enclosing;
+			relativeDepth++;
+		}
+		if (alignmentException != null) {
+			throw alignmentException;
+		}
+		// did not find any breakable location - proceed
+		if (this.currentAlignment != null) {
+			this.currentAlignment.blockAlign = false;
+			this.currentAlignment.tooLong = true;
+		}
+	}
+
+	/*
+	 * Check if there is a NLS tag on this line. If yes, return true, returns false otherwise.
+	 */
+	private boolean hasNLSTag(int sourceStart) {
+		// search the last comment where commentEnd < current lineEnd
+		if (this.lineEnds == null) return false;
+		int index = Arrays.binarySearch(this.lineEnds, sourceStart);
+		int currentLineEnd = getLineEnd(-index);
+		if (currentLineEnd != -1) {
+			int commentIndex = getCommentIndex(currentLineEnd);
+			if (commentIndex < 0) {
+				commentIndex = -commentIndex - 2;
+			}
+			if (commentIndex >= 0 && commentIndex < this.commentPositions.length) {
+				int start = this.commentPositions[commentIndex][0];
+				if (start < 0) {
+					start = -start;
+					// check that we are on the same line
+					int lineIndexForComment = Arrays.binarySearch(this.lineEnds, start);
+					if (lineIndexForComment == index) {
+						return CharOperation.indexOf(Scanner.TAG_PREFIX, this.scanner.source, true, start, currentLineEnd) != -1;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	private boolean includesBlockComments() {
+	    return ((this.formatComments & INCLUDE_BLOCK_COMMENTS) == INCLUDE_BLOCK_COMMENTS && this.headerEndPosition < this.scanner.currentPosition) ||
+	    	(this.formatter.preferences.comment_format_header && this.headerEndPosition >= this.scanner.currentPosition);
+    }
+
+	private boolean includesJavadocComments() {
+	    return ((this.formatComments & INCLUDE_JAVA_DOC) == INCLUDE_JAVA_DOC && this.headerEndPosition < this.scanner.currentPosition) ||
+	    	(this.formatter.preferences.comment_format_header && this.headerEndPosition >= this.scanner.currentPosition);
+    }
+
+	private boolean includesLineComments() {
+	    return ((this.formatComments & INCLUDE_LINE_COMMENTS) == INCLUDE_LINE_COMMENTS && this.headerEndPosition < this.scanner.currentPosition) ||
+	    	(this.formatter.preferences.comment_format_header && this.headerEndPosition >= this.scanner.currentPosition);
+    }
+
+	boolean includesComments() {
+	    return (this.formatComments & CodeFormatter.F_INCLUDE_COMMENTS) != 0;
+    }
+
+	public void indent() {
+		this.indentationLevel += this.indentationSize;
+		this.numberOfIndentations++;
+	}
+
+	void setIndentation(int level, int n) {
+		this.indentationLevel = level + n * this.indentationSize;
+		this.numberOfIndentations = this.indentationLevel / this.indentationSize;
+	}
+
+	private void initializeScanner(long sourceLevel, DefaultCodeFormatterOptions preferences) {
+		this.useTags = preferences.use_tags;
+		this.tagsKind = 0;
+		char[][] taskTags = null;
+		if (this.useTags) {
+			this.disablingTag = preferences.disabling_tag;
+			this.enablingTag = preferences.enabling_tag;
+			if (this.disablingTag == null) {
+				if (this.enablingTag != null) {
+					taskTags = new char[][] { this.enablingTag };
+				}
+			} else if (this.enablingTag == null) {
+				taskTags = new char[][] { this.disablingTag };
+			} else {
+				taskTags = new char[][] { this.disablingTag, this.enablingTag };
+			}
+		}
+		if (taskTags != null) {
+			loop: for (int i=0,length=taskTags.length; i<length; i++) {
+				if (taskTags[i].length > 2 && taskTags[i][0] == '/') {
+					switch (taskTags[i][1]) {
+						case '/':
+							this.tagsKind = TerminalTokens.TokenNameCOMMENT_LINE;
+							break loop;
+						case '*':
+							if (taskTags[i][2] != '*') {
+								this.tagsKind = TerminalTokens.TokenNameCOMMENT_BLOCK;
+								break loop;
+							}
+							break;
+					}
+				}
+			}
+		}
+		this.scanner = new Scanner(true, true, false/*nls*/, sourceLevel/*sourceLevel*/, taskTags, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+		this.editsEnabled = true;
+	}
+
+	private void initFormatterCommentParser() {
+		if (this.formatterCommentParser == null) {
+			this.formatterCommentParser = new FormatterCommentParser(this.scanner.sourceLevel);
+		}
+		this.formatterCommentParser.scanner.setSource(this.scanner.source);
+		this.formatterCommentParser.source = this.scanner.source;
+		this.formatterCommentParser.scanner.lineEnds = this.lineEnds;
+		this.formatterCommentParser.scanner.linePtr = this.maxLines;
+		this.formatterCommentParser.parseHtmlTags = this.formatter.preferences.comment_format_html;
+	}
+
+	private boolean isOnFirstColumn(int start) {
+		if (this.lineEnds == null) return start == 0;
+		int index = Arrays.binarySearch(this.lineEnds, start);
+		// we want the line end of the previous line
+		int previousLineEnd = getLineEnd(-index - 1);
+		return previousLineEnd != -1 && previousLineEnd == start - 1;
+	}
+
+	private boolean isMeaningfulEdit(OptimizedReplaceEdit edit) {
+		final int editLength= edit.length;
+		final int editReplacementLength= edit.replacement.length();
+		final int editOffset= edit.offset;
+		if (editReplacementLength != 0 && editLength == editReplacementLength) {
+			for (int i = editOffset, max = editOffset + editLength; i < max; i++) {
+				if (this.scanner.source[i] != edit.replacement.charAt(i - editOffset)) {
+					return true;
+				}
+			}
+			return false;
+		}
+		return true;
+	}
+
+	private void preserveEmptyLines(int count, int insertPosition) {
+		if (count > 0) {
+			if (this.blank_lines_between_import_groups >= 0) {
+				printEmptyLines(this.blank_lines_between_import_groups, insertPosition);
+			} else if (this.formatter.preferences.number_of_empty_lines_to_preserve != 0) {
+				int linesToPreserve = Math.min(count, this.formatter.preferences.number_of_empty_lines_to_preserve);
+				printEmptyLines(linesToPreserve, insertPosition);
+			} else {
+				printNewLine(insertPosition);
+			}
+		}
+	}
+
+	private void print(int length, boolean considerSpaceIfAny) {
+		if (this.checkLineWrapping && length + this.column > this.pageWidth) {
+			handleLineTooLong();
+		}
+		this.lastNumberOfNewLines = 0;
+		if (this.indentationLevel != 0) {
+			printIndentationIfNecessary();
+		}
+		if (considerSpaceIfAny) {
+			space();
+		}
+		if (this.pendingSpace) {
+			addInsertEdit(this.scanner.getCurrentTokenStartPosition(), " "); //$NON-NLS-1$
+		}
+		this.pendingSpace = false;
+		this.column += length;
+		this.needSpace = true;
+	}
+
+	private void printBlockComment(boolean isJavadoc) {
+		int currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+		int currentTokenEndPosition = this.scanner.getCurrentTokenEndPosition() + 1;
+		boolean includesBlockComments = !isJavadoc && includesBlockComments();
+
+		this.scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition - 1);
+		int currentCharacter;
+		boolean isNewLine = false;
+		int start = currentTokenStartPosition;
+		int nextCharacterStart = currentTokenStartPosition;
+		int previousStart = currentTokenStartPosition;
+		boolean onFirstColumn = isOnFirstColumn(start);
+
+		boolean indentComment = false;
+		if (this.indentationLevel != 0) {
+			if (isJavadoc
+					|| !this.formatter.preferences.never_indent_block_comments_on_first_column
+					|| !onFirstColumn) {
+				indentComment = true;
+				printIndentationIfNecessary();
+			}
+		}
+		if (this.pendingSpace) {
+			addInsertEdit(currentTokenStartPosition, " "); //$NON-NLS-1$
+		}
+		this.needSpace = false;
+		this.pendingSpace = false;
+
+		int commentColumn = this.column;
+		if (includesBlockComments) {
+			if (printBlockComment(currentTokenStartPosition, currentTokenEndPosition)) {
+				return;
+			}
+		}
+
+		int currentIndentationLevel = this.indentationLevel;
+		if ((commentColumn-1) > this.indentationLevel) {
+			this.indentationLevel = commentColumn-1;
+		}
+		int currentCommentIndentation = onFirstColumn ? 0 : getCurrentCommentIndentation(start);
+		boolean formatComment = (isJavadoc && (this.formatComments & CodeFormatter.K_JAVA_DOC) != 0) || (!isJavadoc && (this.formatComments & CodeFormatter.K_MULTI_LINE_COMMENT) != 0);
+
+		try {
+			while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = this.scanner.getNextChar()) != -1) {
+				nextCharacterStart = this.scanner.currentPosition;
+
+				switch(currentCharacter) {
+					case '\r' :
+						start = previousStart;
+						isNewLine = true;
+						if (this.scanner.getNextChar('\n')) {
+							currentCharacter = '\n';
+							nextCharacterStart = this.scanner.currentPosition;
+						}
+						break;
+					case '\n' :
+						start = previousStart;
+						isNewLine = true;
+						nextCharacterStart = this.scanner.currentPosition;
+						break;
+					default:
+						if (isNewLine) {
+							this.column = 1;
+							this.line++;
+							isNewLine = false;
+
+							boolean addSpace = false;
+							if (onFirstColumn) {
+								if (formatComment) {
+									if (ScannerHelper.isWhitespace((char) currentCharacter)) {
+										int previousStartPosition = this.scanner.currentPosition;
+										while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
+											previousStart = nextCharacterStart;
+											previousStartPosition = this.scanner.currentPosition;
+											currentCharacter = this.scanner.getNextChar();
+											nextCharacterStart = this.scanner.currentPosition;
+										}
+										if (currentCharacter == '\r' || currentCharacter == '\n') {
+											nextCharacterStart = previousStartPosition;
+										}
+									}
+									if (currentCharacter != '\r' && currentCharacter != '\n') {
+										addSpace = true;
+									}
+								}
+							} else {
+								if (ScannerHelper.isWhitespace((char) currentCharacter)) {
+									int previousStartPosition = this.scanner.currentPosition;
+									int currentIndentation = 0;
+									loop: while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
+										if (currentIndentation >= currentCommentIndentation) {
+											break loop;
+										}
+										previousStart = nextCharacterStart;
+										previousStartPosition = this.scanner.currentPosition;
+										switch(currentCharacter) {
+											case '\t' :
+												if (this.tabLength != 0) {
+													int reminder = currentIndentation % this.tabLength;
+													if (reminder == 0) {
+														currentIndentation += this.tabLength;
+													} else {
+														currentIndentation = ((currentIndentation / this.tabLength) + 1) * this.tabLength;
+													}
+												}
+												break;
+											default :
+												currentIndentation ++;
+										}
+										currentCharacter = this.scanner.getNextChar();
+										nextCharacterStart = this.scanner.currentPosition;
+									}
+									if (currentCharacter == '\r' || currentCharacter == '\n') {
+										nextCharacterStart = previousStartPosition;
+									}
+								}
+								if (formatComment) {
+									int previousStartTemp = previousStart;
+									int nextCharacterStartTemp = nextCharacterStart;
+									while(currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n' && ScannerHelper.isWhitespace((char) currentCharacter)) {
+										previousStart = nextCharacterStart;
+										currentCharacter = this.scanner.getNextChar();
+										nextCharacterStart = this.scanner.currentPosition;
+									}
+									if (currentCharacter == '*') {
+										addSpace = true;
+									} else {
+										previousStart = previousStartTemp;
+										nextCharacterStart = nextCharacterStartTemp;
+									}
+									this.scanner.currentPosition = nextCharacterStart;
+								}
+							}
+							String replacement;
+							if (indentComment) {
+								this.tempBuffer.setLength(0);
+								this.tempBuffer.append(this.lineSeparator);
+								if (this.indentationLevel > 0) {
+									printIndentationIfNecessary(this.tempBuffer);
+								}
+								if (addSpace) {
+									this.tempBuffer.append(' ');
+								}
+								replacement = this.tempBuffer.toString();
+							} else {
+								replacement = addSpace ? this.lineSeparatorAndSpace : this.lineSeparator;
+							}
+							addReplaceEdit(start, previousStart - 1, replacement);
+						} else {
+							this.column += (nextCharacterStart - previousStart);
+						}
+				}
+				previousStart = nextCharacterStart;
+				this.scanner.currentPosition = nextCharacterStart;
+			}
+		} finally {
+			this.indentationLevel = currentIndentationLevel;
+		}
+		this.lastNumberOfNewLines = 0;
+		this.needSpace = false;
+		this.scanner.resetTo(currentTokenEndPosition, this.scannerEndPosition - 1);
+	}
+
+	private boolean printBlockComment(int currentTokenStartPosition, int currentTokenEndPosition) {
+
+		// Compute indentation
+		int maxColumn = this.formatter.preferences.comment_line_length + 1;
+		int indentLevel = this.indentationLevel;
+		int indentations = this.numberOfIndentations;
+		switch (this.tabChar) {
+			case DefaultCodeFormatterOptions.TAB:
+				switch (this.tabLength) {
+					case 0:
+						this.indentationLevel = 0;
+						this.column = 1;
+						this.numberOfIndentations = 0;
+						break;
+					case 1:
+						this.indentationLevel = this.column - 1;
+						this.numberOfIndentations = this.indentationLevel;
+						break;
+					default:
+						this.indentationLevel = (this.column / this.tabLength) * this.tabLength;
+						this.column = this.indentationLevel + 1;
+						this.numberOfIndentations = this.indentationLevel / this.tabLength;
+				}
+				break;
+			case DefaultCodeFormatterOptions.MIXED:
+				if (this.tabLength == 0) {
+					this.indentationLevel = 0;
+					this.column = 1;
+					this.numberOfIndentations = 0;
+				} else {
+					this.indentationLevel = this.column - 1;
+					this.numberOfIndentations = this.indentationLevel / this.tabLength;
+				}
+				break;
+			case DefaultCodeFormatterOptions.SPACE:
+				if (this.indentationSize == 0) {
+					this.indentationLevel = 0;
+					this.column = 1;
+					this.numberOfIndentations = 0;
+				} else {
+					this.indentationLevel = this.column - 1;
+				}
+				break;
+		}
+
+		// Consume the comment prefix
+		this.blockCommentBuffer.setLength(0);
+		this.scanner.getNextChar();
+		this.scanner.getNextChar();
+		this.column += 2;
+		this.scanner.skipComments = true;
+		this.blockCommentTokensBuffer.setLength(0);
+		int editStart = this.scanner.currentPosition;
+		int editEnd = -1;
+
+		// Consume text token per token
+		int previousToken = -1;
+		boolean newLine = false;
+		boolean multiLines = false;
+		boolean hasMultiLines = false;
+		boolean hasTokens = false;
+		boolean bufferHasTokens = false;
+		boolean bufferHasNewLine = false;
+		boolean lineHasTokens = false;
+		int hasTextOnFirstLine = 0;
+		boolean firstWord = true;
+		boolean clearBlankLines = this.formatter.preferences.comment_clear_blank_lines_in_block_comment;
+		boolean joinLines = this.formatter.preferences.join_lines_in_comments;
+		boolean newLinesAtBoundaries = this.formatter.preferences.comment_new_lines_at_block_boundaries;
+		int scannerLine = Util.getLineNumber(this.scanner.currentPosition, this.lineEnds, 0, this.maxLines);
+		int firstLine = scannerLine;
+		int lineNumber = scannerLine;
+		int lastTextLine = -1;
+		while (!this.scanner.atEnd()) {
+
+			// Consume token
+			int token;
+			try {
+				token = this.scanner.getNextToken();
+			} catch (InvalidInputException iie) {
+	    		token = consumeInvalidToken(currentTokenEndPosition-1);
+				newLine = false;
+			}
+
+			// Look at specific tokens
+    		boolean insertSpace = (previousToken == TerminalTokens.TokenNameWHITESPACE) && (!firstWord || !hasTokens);
+    		boolean isTokenStar = false;
+			switch (token) {
+				case TerminalTokens.TokenNameWHITESPACE:
+					if (this.blockCommentTokensBuffer.length() > 0) {
+						if (hasTextOnFirstLine == 1 && multiLines) {
+							printBlockCommentHeaderLine(this.blockCommentBuffer);
+							hasTextOnFirstLine = -1;
+						}
+						this.blockCommentBuffer.append(this.blockCommentTokensBuffer);
+						this.column += this.blockCommentTokensBuffer.length();
+						this.blockCommentTokensBuffer.setLength(0);
+						bufferHasTokens = true;
+						bufferHasNewLine = false;
+					}
+					if (previousToken == -1) {
+						// do not remember the first whitespace
+						previousToken = SKIP_FIRST_WHITESPACE_TOKEN;
+					} else {
+						previousToken = token;
+					}
+					lineNumber = Util.getLineNumber(this.scanner.currentPosition, this.lineEnds, scannerLine>1 ? scannerLine-2 : 0, this.maxLines);
+					if (lineNumber > scannerLine) {
+						hasMultiLines = true;
+						newLine = true;
+					}
+					scannerLine = lineNumber;
+					continue;
+				case TerminalTokens.TokenNameMULTIPLY:
+					isTokenStar = true;
+					lineNumber = Util.getLineNumber(this.scanner.currentPosition, this.lineEnds, scannerLine>1 ? scannerLine-2 : 0, this.maxLines);
+					if (lineNumber == firstLine && previousToken == SKIP_FIRST_WHITESPACE_TOKEN) {
+						this.blockCommentBuffer.append(' ');
+					}
+					previousToken = token;
+					if (this.scanner.currentCharacter == '/') {
+						editEnd = this.scanner.startPosition - 1;
+						// Add remaining buffered tokens
+						if (this.blockCommentTokensBuffer.length() > 0) {
+							this.blockCommentBuffer.append(this.blockCommentTokensBuffer);
+							this.column += this.blockCommentTokensBuffer.length();
+						}
+						// end of comment
+						if (newLinesAtBoundaries) {
+							if (multiLines || hasMultiLines) {
+						    	this.blockCommentBuffer.append(this.lineSeparator);
+						    	this.column = 1;
+						    	printIndentationIfNecessary(this.blockCommentBuffer);
+							}
+						}
+						this.blockCommentBuffer.append(' ');
+						this.column += BLOCK_FOOTER_LENGTH + 1;
+				    	this.scanner.getNextChar(); // reach the end of scanner
+				    	continue;
+					}
+					if (newLine) {
+						scannerLine = lineNumber;
+						newLine = false;
+						continue;
+					}
+					break;
+				case TerminalTokens.TokenNameMULTIPLY_EQUAL:
+					if (newLine) {
+						this.scanner.resetTo(this.scanner.startPosition, currentTokenEndPosition-1);
+						this.scanner.getNextChar(); // consume the multiply
+						previousToken = TerminalTokens.TokenNameMULTIPLY;
+						scannerLine = Util.getLineNumber(this.scanner.currentPosition, this.lineEnds, scannerLine>1 ? scannerLine-2 : 0, this.maxLines);
+						continue;
+					}
+					break;
+				case TerminalTokens.TokenNameMINUS:
+				case TerminalTokens.TokenNameMINUS_MINUS:
+					if (previousToken == -1) {
+						// Do not format comment starting with /*-
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=230944
+						this.indentationLevel = indentLevel;
+						this.numberOfIndentations = indentations;
+						this.lastNumberOfNewLines = 0;
+						this.needSpace = false;
+						this.scanner.skipComments = false;
+						this.scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition - 1);
+						return false;
+					}
+					break;
+				default:
+					// do nothing
+					break;
+			}
+
+			// Look at gap and insert corresponding lines if necessary
+			int linesGap;
+			int max;
+			lineNumber = Util.getLineNumber(this.scanner.currentPosition, this.lineEnds, scannerLine>1 ? scannerLine-2 : 0, this.maxLines);
+			if (lastTextLine == -1) {
+				linesGap = newLinesAtBoundaries ? lineNumber - firstLine : 0;
+				max = 0;
+			} else {
+				linesGap = lineNumber - lastTextLine;
+				if (token == TerminalTokens.TokenNameAT && linesGap ==1) {
+					// insert one blank line before root tags
+					linesGap = 2;
+				}
+				max = joinLines && lineHasTokens ? 1 : 0;
+			}
+			if (linesGap > max) {
+				if (clearBlankLines) {
+					// TODO (frederic) see if there's a bug for the unremoved blank line for root tags
+					 if (token == TerminalTokens.TokenNameAT) {
+						 linesGap = 1;
+					 } else {
+						linesGap = (max==0 || !joinLines) ? 1 : 0;
+					 }
+				}
+				for (int i=0; i<linesGap; i++) {
+					// Add remaining buffered tokens
+					if (this.blockCommentTokensBuffer.length() > 0) {
+						if (hasTextOnFirstLine == 1) {
+							printBlockCommentHeaderLine(this.blockCommentBuffer);
+							hasTextOnFirstLine = -1;
+						}
+						this.blockCommentBuffer.append(this.blockCommentTokensBuffer);
+						this.blockCommentTokensBuffer.setLength(0);
+						bufferHasTokens = true;
+					}
+			    	this.blockCommentBuffer.append(this.lineSeparator);
+			    	this.column = 1;
+			    	printIndentationIfNecessary(this.blockCommentBuffer);
+		    		this.blockCommentBuffer.append(BLOCK_LINE_PREFIX);
+		    		this.column += BLOCK_LINE_PREFIX_LENGTH;
+		    		firstWord = true;
+					multiLines = true;
+					bufferHasNewLine = true;
+				}
+				insertSpace = insertSpace && linesGap == 0;
+			}
+    		if (newLine) lineHasTokens = false;
+
+			// Increment column
+			int tokenStart = this.scanner.getCurrentTokenStartPosition();
+    		int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - tokenStart;
+    		hasTokens = true;
+    		if (!isTokenStar) lineHasTokens = true;
+    		if (hasTextOnFirstLine == 0 && !isTokenStar) {
+    			if (firstLine == lineNumber) {
+	    			hasTextOnFirstLine = 1;
+	    			this.column++; // include first space
+	    		} else {
+	    			hasTextOnFirstLine = -1;
+	    		}
+    		}
+    		int lastColumn = this.column + this.blockCommentTokensBuffer.length() + tokenLength;
+    		if (insertSpace) lastColumn++;
+
+    		// Append next token inserting a new line if max line is reached
+			if (lineHasTokens && !firstWord && lastColumn > maxColumn) {
+		    	String tokensString = this.blockCommentTokensBuffer.toString().trim();
+		    	int tokensStringLength = tokensString.length();
+				// not enough space on the line
+				if (hasTextOnFirstLine == 1) {
+					printBlockCommentHeaderLine(this.blockCommentBuffer);
+				}
+				if ((this.indentationLevel+tokensStringLength+tokenLength) > maxColumn) {
+					// there won't be enough room even if we break the line before the buffered tokens
+					// So add the buffered tokens now
+					this.blockCommentBuffer.append(this.blockCommentTokensBuffer);
+					this.column += this.blockCommentTokensBuffer.length();
+					this.blockCommentTokensBuffer.setLength(0);
+					bufferHasNewLine = false;
+					bufferHasTokens = true;
+				}
+				if (bufferHasTokens && !bufferHasNewLine) {
+			    	this.blockCommentBuffer.append(this.lineSeparator);
+			    	this.column = 1;
+			    	printIndentationIfNecessary(this.blockCommentBuffer);
+		    		this.blockCommentBuffer.append(BLOCK_LINE_PREFIX);
+			    	this.column += BLOCK_LINE_PREFIX_LENGTH;
+				}
+		    	if (this.blockCommentTokensBuffer.length() > 0) {
+					this.blockCommentBuffer.append(tokensString);
+					this.column += tokensStringLength;
+					this.blockCommentTokensBuffer.setLength(0);
+		    	}
+				this.blockCommentBuffer.append(this.scanner.source, tokenStart, tokenLength);
+				bufferHasTokens = true;
+				bufferHasNewLine = false;
+				this.column += tokenLength;
+				multiLines = true;
+				hasTextOnFirstLine = -1;
+			} else {
+				// append token to the line
+				if (insertSpace)  {
+					this.blockCommentTokensBuffer.append(' ');
+				}
+				this.blockCommentTokensBuffer.append(this.scanner.source, tokenStart, tokenLength);
+			}
+			previousToken = token;
+			newLine = false;
+    		firstWord = false;
+			scannerLine = lineNumber;
+			lastTextLine = lineNumber;
+		}
+
+		// Replace block comment text
+		if (this.nlsTagCounter == 0 || !multiLines) {
+			if (hasTokens || multiLines) {
+				StringBuffer replacement;
+				if (hasTextOnFirstLine == 1) {
+					this.blockCommentTokensBuffer.setLength(0);
+					replacement = this.blockCommentTokensBuffer;
+					if ((hasMultiLines || multiLines)) {
+						int col = this.column;
+						replacement.append(this.lineSeparator);
+						this.column = 1;
+						printIndentationIfNecessary(replacement);
+						replacement.append(BLOCK_LINE_PREFIX);
+				    	this.column = col;
+					} else if (this.blockCommentBuffer.length()==0 || this.blockCommentBuffer.charAt(0)!=' ') {
+						replacement.append(' ');
+					}
+					replacement.append(this.blockCommentBuffer);
+				} else {
+					replacement = this.blockCommentBuffer;
+				}
+				addReplaceEdit(editStart, editEnd, replacement.toString());
+			}
+		}
+
+		// Reset
+		this.indentationLevel = indentLevel;
+		this.numberOfIndentations = indentations;
+		this.lastNumberOfNewLines = 0;
+		this.needSpace = false;
+		this.scanner.resetTo(currentTokenEndPosition, this.scannerEndPosition - 1);
+		this.scanner.skipComments = false;
+		return true;
+	}
+
+	private void printBlockCommentHeaderLine(StringBuffer buffer) {
+		if (!this.formatter.preferences.comment_new_lines_at_block_boundaries) {
+			buffer.insert(0, ' ');
+			this.column++;
+		}
+	    else if (buffer.length() == 0) {
+	    	buffer.append(this.lineSeparator);
+	    	this.column = 1;
+	    	printIndentationIfNecessary(buffer);
+	    	buffer.append(BLOCK_LINE_PREFIX);
+	    	this.column += BLOCK_LINE_PREFIX_LENGTH;
+	    } else {
+	    	this.tempBuffer.setLength(0);
+	    	this.tempBuffer.append(this.lineSeparator);
+	    	this.column = 1;
+			printIndentationIfNecessary(this.tempBuffer);
+	    	this.tempBuffer.append(BLOCK_LINE_PREFIX);
+	    	this.column += BLOCK_LINE_PREFIX_LENGTH;
+	    	buffer.insert(0, this.tempBuffer.toString());
+	    }
+    }
+
+	public void printEndOfCompilationUnit() {
+		try {
+			// if we have a space between two tokens we ensure it will be dumped in the formatted string
+			int currentTokenStartPosition = this.scanner.currentPosition;
+			boolean hasComment = false;
+			boolean hasLineComment = false;
+			boolean hasWhitespace = false;
+			int count = 0;
+			while (true) {
+				this.currentToken = this.scanner.getNextToken();
+				switch(this.currentToken) {
+					case TerminalTokens.TokenNameWHITESPACE :
+						char[] whiteSpaces = this.scanner.getCurrentTokenSource();
+						count = 0;
+						for (int i = 0, max = whiteSpaces.length; i < max; i++) {
+							switch(whiteSpaces[i]) {
+								case '\r' :
+									if ((i + 1) < max) {
+										if (whiteSpaces[i + 1] == '\n') {
+											i++;
+										}
+									}
+									count++;
+									break;
+								case '\n' :
+									count++;
+							}
+						}
+						if (count == 0) {
+							hasWhitespace = true;
+							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						} else if (hasLineComment) {
+							preserveEmptyLines(count, this.scanner.getCurrentTokenStartPosition());
+							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						} else if (hasComment) {
+							if (count == 1) {
+								this.printNewLine(this.scanner.getCurrentTokenStartPosition());
+							} else {
+								preserveEmptyLines(count - 1, this.scanner.getCurrentTokenStartPosition());
+							}
+							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						} else {
+							addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						}
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						if (count >= 1) {
+							if (count > 1) {
+								preserveEmptyLines(count - 1, this.scanner.getCurrentTokenStartPosition());
+							} else if (count == 1) {
+								printNewLine(this.scanner.getCurrentTokenStartPosition());
+							}
+						} else if (hasWhitespace) {
+							space();
+						}
+						hasWhitespace = false;
+						printLineComment();
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = true;
+						count = 0;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						if (count >= 1) {
+							if (count > 1) {
+								preserveEmptyLines(count - 1, this.scanner.getCurrentTokenStartPosition());
+							} else if (count == 1) {
+								printNewLine(this.scanner.getCurrentTokenStartPosition());
+							}
+						} else if (hasWhitespace) {
+							space();
+						}
+						hasWhitespace = false;
+						printBlockComment(false);
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = false;
+						hasComment = true;
+						count = 0;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						if (count >= 1) {
+							if (count > 1) {
+								preserveEmptyLines(count - 1, this.scanner.startPosition);
+							} else if (count == 1) {
+								printNewLine(this.scanner.startPosition);
+							}
+						} else if (hasWhitespace) {
+							space();
+						}
+						hasWhitespace = false;
+						if (includesJavadocComments()) {
+							printJavadocComment(this.scanner.startPosition, this.scanner.currentPosition);
+						} else {
+							printBlockComment(true);
+						}
+						printNewLine();
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = false;
+						hasComment = true;
+						count = 0;
+						break;
+					case TerminalTokens.TokenNameSEMICOLON :
+						print(this.scanner.currentPosition - this.scanner.startPosition, this.formatter.preferences.insert_space_before_semicolon);
+						break;
+					case TerminalTokens.TokenNameEOF :
+						if (count >= 1 || this.formatter.preferences.insert_new_line_at_end_of_file_if_missing) {
+							this.printNewLine(this.scannerEndPosition);
+						}
+						return;
+					default :
+						// step back one token
+						this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+						return;
+				}
+			}
+		} catch (InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	/*
+	 * prints a code snippet
+	 */
+	private void printCodeSnippet(int startPosition, int endPosition, int linesGap) {
+		String snippet = new String(this.scanner.source, startPosition, endPosition - startPosition + 1);
+	
+		// 1 - strip content prefix (@see JavaDocRegion#preprocessCodeSnippet)
+		int firstLine = Util.getLineNumber(startPosition, this.lineEnds, 0, this.maxLines) - 1;
+		int lastLine = Util.getLineNumber(endPosition, this.lineEnds, firstLine>1 ? firstLine-2 : 0, this.maxLines) - 1;
+		this.codeSnippetBuffer.setLength(0);
+		if (firstLine == lastLine && linesGap == 0) {
+			this.codeSnippetBuffer.append(snippet);
+		} else {
+			boolean hasCharsAfterStar = false;
+			if (linesGap == 0) {
+				this.codeSnippetBuffer.append(this.scanner.source, startPosition, this.lineEnds[firstLine]+1-startPosition);
+				firstLine++;
+			}
+			int initialLength = this.codeSnippetBuffer.length();
+			for (int currentLine=firstLine; currentLine<=lastLine; currentLine++) {
+				this.scanner.resetTo(this.lineEnds[currentLine-1]+1, this.lineEnds[currentLine]);
+				int lineStart = this.scanner.currentPosition;
+				boolean hasStar = false;
+				loop: while (!this.scanner.atEnd()) {
+					char ch = (char) this.scanner.getNextChar();
+					switch (ch) {
+						case ' ':
+						case '\t' :
+						case '\u000c' :
+							break;
+						case '\r' :
+						case '\n' :
+							break loop;
+						case '*':
+							hasStar = true;
+							break loop;
+						default:
+							if (ScannerHelper.isWhitespace(ch)) {
+								break;
+							}
+							break loop;
+					}
+				}
+				if (hasStar) {
+					lineStart = this.scanner.currentPosition;
+					if (!hasCharsAfterStar && !this.scanner.atEnd()) {
+						char ch = (char) this.scanner.getNextChar();
+						boolean atEnd = this.scanner.atEnd();
+						switch (ch) {
+							case ' ':
+							case '\t' :
+							case '\u000c' :
+								break;
+							case '\r' :
+							case '\n' :
+								atEnd = true;
+								break;
+							default:
+								if (!ScannerHelper.isWhitespace(ch)) {
+									if (hasStar) {
+										// A non whitespace character is just after the star
+										// then we need to restart from the beginning without
+										// consuming the space after the star
+										hasCharsAfterStar = true;
+										currentLine = firstLine-1;
+										this.codeSnippetBuffer.setLength(initialLength);
+										continue;
+									}
+								}
+								break;
+						}
+						if (!hasCharsAfterStar && !atEnd) {
+							// Until then, there's always a whitespace after each star
+							// of the comment, hence we need to consume it as it will
+							// be rewritten while reindenting the snippet lines
+							lineStart = this.scanner.currentPosition;
+						}
+					}
+				}
+				int end = currentLine == lastLine ? endPosition : this.lineEnds[currentLine];
+				this.codeSnippetBuffer.append(this.scanner.source, lineStart, end+1-lineStart);
+			}
+		}
+	
+		// 2 - convert HTML to Java (@see JavaDocRegion#convertHtml2Java)
+		HTMLEntity2JavaReader reader= new HTMLEntity2JavaReader(new StringReader(this.codeSnippetBuffer.toString()));
+		char[] buf= new char[this.codeSnippetBuffer.length()]; // html2text never gets longer, only shorter!
+		String convertedSnippet;
+		try {
+			int read= reader.read(buf);
+			convertedSnippet = new String(buf, 0, read);
+		} catch (IOException e) {
+			// should not happen
+			CommentFormatterUtil.log(e);
+			return;
+		}
+	
+		// 3 - format snippet (@see JavaDocRegion#formatCodeSnippet)
+		// include comments in case of line comments are present in the snippet
+		String formattedSnippet = convertedSnippet;
+		Map options = this.formatter.preferences.getMap();
+		if (this.scanner.sourceLevel > ClassFileConstants.JDK1_3) {
+			options.put(JavaCore.COMPILER_SOURCE, CompilerOptions.versionFromJdkLevel(this.scanner.sourceLevel));
+		}
+		TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN | CodeFormatter.F_INCLUDE_COMMENTS, convertedSnippet, 0, this.lineSeparator, options);
+		if (edit == null) {
+			// 3.a - not a valid code to format, keep initial buffer
+			formattedSnippet = this.codeSnippetBuffer.toString();
+		} else {
+			// 3.b - valid code formatted
+			// 3.b.i - get the result
+			formattedSnippet = CommentFormatterUtil.evaluateFormatterEdit(convertedSnippet, edit, null);
+	
+			// 3.b.ii- convert back to HTML (@see JavaDocRegion#convertJava2Html)
+			Java2HTMLEntityReader javaReader= new Java2HTMLEntityReader(new StringReader(formattedSnippet));
+			buf= new char[256];
+			this.codeSnippetBuffer.setLength(0);
+			int l;
+			try {
+				do {
+					l= javaReader.read(buf);
+					if (l != -1)
+						this.codeSnippetBuffer.append(buf, 0, l);
+				} while (l > 0);
+				formattedSnippet = this.codeSnippetBuffer.toString();
+			} catch (IOException e) {
+				// should not happen
+				CommentFormatterUtil.log(e);
+				return;
+			}
+		}
+	
+		// 4 - add the content prefix (@see JavaDocRegion#postprocessCodeSnippet)
+		this.codeSnippetBuffer.setLength(0);
+		ILineTracker tracker = new DefaultLineTracker();
+		this.column = 1;
+		printIndentationIfNecessary(this.codeSnippetBuffer); // append indentation
+		this.codeSnippetBuffer.append(BLOCK_LINE_PREFIX);
+		String linePrefix = this.codeSnippetBuffer.toString();
+		this.codeSnippetBuffer.setLength(0);
+		String replacement = formattedSnippet;
+		tracker.set(formattedSnippet);
+		int numberOfLines = tracker.getNumberOfLines();
+		if (numberOfLines > 1) {
+			int lastLineOffset = -1;
+			for (int i=0; i<numberOfLines-1; i++) {
+				if (i>0) this.codeSnippetBuffer.append(linePrefix);
+				try {
+					lastLineOffset = tracker.getLineOffset(i+1);
+					this.codeSnippetBuffer.append(formattedSnippet.substring(tracker.getLineOffset(i), lastLineOffset));
+				} catch (BadLocationException e) {
+					// should not happen
+					CommentFormatterUtil.log(e);
+					return;
+				}
+			}
+			this.codeSnippetBuffer.append(linePrefix);
+			this.codeSnippetBuffer.append(formattedSnippet.substring(lastLineOffset));
+			replacement = this.codeSnippetBuffer.toString();
+		}
+	
+		// 5 - replace old text with the formatted snippet
+		addReplaceEdit(startPosition, endPosition, replacement);
+	}
+
+	void printComment() {
+		printComment(CodeFormatter.K_UNKNOWN, NO_TRAILING_COMMENT, PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION);
+	}
+
+	void printComment(int emptyLinesRules) {
+		printComment(CodeFormatter.K_UNKNOWN, NO_TRAILING_COMMENT, emptyLinesRules);
+	}
+
+	void printComment(int kind, int trailing) {
+		printComment(kind, trailing, PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION);
+	}
+
+	/*
+	 * Main method to print and format comments (javadoc, block and single line comments)
+	 */
+	void printComment(int kind, int trailing, int emptyLinesRules) {
+		final boolean rejectLineComment = kind  == CodeFormatter.K_MULTI_LINE_COMMENT || kind == CodeFormatter.K_JAVA_DOC;
+		final boolean rejectBlockComment = kind  == CodeFormatter.K_SINGLE_LINE_COMMENT || kind  == CodeFormatter.K_JAVA_DOC;
+		final boolean rejectJavadocComment = kind  == CodeFormatter.K_SINGLE_LINE_COMMENT || kind  == CodeFormatter.K_MULTI_LINE_COMMENT;
+		try {
+			// if we have a space between two tokens we ensure it will be dumped in the formatted string
+			int currentTokenStartPosition = this.scanner.currentPosition;
+			boolean hasComment = false;
+			boolean hasLineComment = false;
+			boolean hasWhitespaces = false;
+			int lines = 0;
+			while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				int foundTaskCount = this.scanner.foundTaskCount;
+				int tokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+				switch(this.currentToken) {
+					case TerminalTokens.TokenNameWHITESPACE :
+						char[] whiteSpaces = this.scanner.getCurrentTokenSource();
+						int whitespacesEndPosition = this.scanner.getCurrentTokenEndPosition();
+						lines = 0;
+						for (int i = 0, max = whiteSpaces.length; i < max; i++) {
+							switch(whiteSpaces[i]) {
+								case '\r' :
+									if ((i + 1) < max) {
+										if (whiteSpaces[i + 1] == '\n') {
+											i++;
+										}
+									}
+									lines++;
+									break;
+								case '\n' :
+									lines++;
+							}
+						}
+						// If following token is a line comment on the same line or the line just after,
+						// then it might be not really formatted as a trailing comment
+						boolean realTrailing = trailing > NO_TRAILING_COMMENT;
+						if (realTrailing && this.scanner.currentCharacter == '/' && (lines == 0 || (lines == 1 && !hasLineComment && trailing == IMPORT_TRAILING_COMMENT))) {
+							// sometimes changing the trailing may not be the best idea
+							// for complex trailing comment, it's basically a good idea
+							boolean canChangeTrailing = (trailing & COMPLEX_TRAILING_COMMENT) != 0;
+							// for basic trailing comment preceded by a line comment, then it depends on the comments relative position
+							// when following comment column (after having been rounded) is below the preceding one,
+							// then it becomes not a good idea to change the trailing flag
+							if (trailing == BASIC_TRAILING_COMMENT && hasLineComment) {
+								int currentCommentIndentation = getCurrentIndentation(whiteSpaces, 0);
+								int relativeIndentation = currentCommentIndentation - this.lastLineComment.currentIndentation;
+								if (this.tabLength == 0) {
+									canChangeTrailing = relativeIndentation == 0;
+								} else {
+									canChangeTrailing = relativeIndentation > -this.tabLength;
+								}
+							}
+							// if the trailing can be change, then look at the following tokens
+							if (canChangeTrailing) {
+								int currentPosition = this.scanner.currentPosition;
+								if (this.scanner.getNextToken() == TerminalTokens.TokenNameCOMMENT_LINE) {
+									realTrailing = !hasLineComment;
+									switch (this.scanner.getNextToken()) {
+										case TerminalTokens.TokenNameCOMMENT_LINE:
+											// at least two contiguous line comments
+											// the formatter should not consider comments as trailing ones
+											realTrailing = false;
+											break;
+										case TerminalTokens.TokenNameWHITESPACE:
+											if (this.scanner.getNextToken() == TerminalTokens.TokenNameCOMMENT_LINE) {
+												// at least two contiguous line comments
+												// the formatter should not consider comments as trailing ones
+												realTrailing = false;
+											}
+											break;
+									}
+								}
+								this.scanner.resetTo(currentPosition, this.scanner.eofPosition - 1);
+							}
+						}
+						// Look whether comments line may be contiguous or not
+						// Note that when preceding token is a comment line, then only one line
+						// is enough to have an empty line as the line end is included in the comment line...
+						// If comments are contiguous, store the white spaces to be able to compute the current comment indentation
+						if (lines > 1 || (lines == 1 && hasLineComment)) {
+							this.lastLineComment.contiguous = false;
+						}
+						this.lastLineComment.leadingSpaces = whiteSpaces;
+						this.lastLineComment.lines = lines;
+						// Strategy to consume spaces and eventually leave at this stage
+						// depends on the fact that a trailing comment is expected or not
+						if (realTrailing) {
+							// if a line comment is consumed, no other comment can be on the same line after
+							if (hasLineComment) {
+								if (lines >= 1) {
+									currentTokenStartPosition = tokenStartPosition;
+									preserveEmptyLines(lines, currentTokenStartPosition);
+									addDeleteEdit(currentTokenStartPosition, whitespacesEndPosition);
+									this.scanner.resetTo(this.scanner.currentPosition, this.scannerEndPosition - 1);
+									return;
+								}
+								this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+								return;
+							} 
+							// if one or several new lines are consumed, following comments cannot be considered as trailing ones
+							if (lines >= 1) {
+								if (hasComment) {
+									this.printNewLine(tokenStartPosition);
+								}
+								this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+								return;
+							}
+							// delete consumed white spaces
+							hasWhitespaces = true;
+							currentTokenStartPosition = this.scanner.currentPosition;
+							addDeleteEdit(tokenStartPosition, whitespacesEndPosition);
+						} else {
+							if (lines == 0) {
+								hasWhitespaces = true;
+								if (hasLineComment && emptyLinesRules != PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION) {
+									addReplaceEdit(tokenStartPosition, whitespacesEndPosition, getPreserveEmptyLines(0, emptyLinesRules));
+								} else {
+									addDeleteEdit(tokenStartPosition, whitespacesEndPosition);
+								}
+							} else if (hasLineComment) {
+								useAlignmentBreakIndentation(emptyLinesRules);
+								currentTokenStartPosition = tokenStartPosition;
+								preserveEmptyLines(lines, currentTokenStartPosition);
+								addDeleteEdit(currentTokenStartPosition, whitespacesEndPosition);
+							} else if (hasComment) {
+								useAlignmentBreakIndentation(emptyLinesRules);
+								if (lines == 1) {
+									this.printNewLine(tokenStartPosition);
+								} else {
+									preserveEmptyLines(lines - 1, tokenStartPosition);
+								}
+								addDeleteEdit(tokenStartPosition, whitespacesEndPosition);
+							} else if (lines != 0 && (!this.formatter.preferences.join_wrapped_lines || this.formatter.preferences.number_of_empty_lines_to_preserve != 0 || this.blank_lines_between_import_groups > 0)) {
+								addReplaceEdit(tokenStartPosition, whitespacesEndPosition, getPreserveEmptyLines(lines-1, emptyLinesRules));
+							} else {
+								useAlignmentBreakIndentation(emptyLinesRules);
+								addDeleteEdit(tokenStartPosition, whitespacesEndPosition);
+							}
+						}
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						if (this.useTags && this.editsEnabled) {
+							boolean turnOff = false;
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+								turnOff = true;
+							} else if (this.tagsKind == this.currentToken
+								&& CharOperation.fragmentEquals(this.disablingTag, this.scanner.source, tokenStartPosition, true)) {
+    							this.editsEnabled = false;
+								turnOff = true;
+					    	}
+							if (turnOff) {
+								if (!this.editsEnabled && this.editsIndex > 1) {
+									OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+									if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) {
+										printNewLinesBeforeDisablingComment();
+									}
+								}
+							}
+						}
+						if (rejectLineComment) break;
+						if (lines >= 1) {
+							if (lines > 1) {
+								preserveEmptyLines(lines - 1, this.scanner.getCurrentTokenStartPosition());
+							} else if (lines == 1) {
+								printNewLine(this.scanner.getCurrentTokenStartPosition());
+							}
+						} else if (hasWhitespaces) {
+							space();
+						}
+						hasWhitespaces = false;
+						printLineComment();
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = true;
+						lines = 0;
+						if (this.useTags && !this.editsEnabled) {
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+							} else if (this.tagsKind == this.currentToken) {
+	    						this.editsEnabled = CharOperation.fragmentEquals(this.enablingTag, this.scanner.source, tokenStartPosition, true);
+					    	}
+						}
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						if (this.useTags && this.editsEnabled) {
+							boolean turnOff = false;
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+								turnOff = true;
+							} else if (this.tagsKind == this.currentToken
+								&& CharOperation.fragmentEquals(this.disablingTag, this.scanner.source, tokenStartPosition, true)) {
+    							this.editsEnabled = false;
+								turnOff = true;
+					    	}
+							if (turnOff) {
+								if (!this.editsEnabled && this.editsIndex > 1) {
+									OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+									if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) {
+										printNewLinesBeforeDisablingComment();
+									}
+								}
+							}
+						}
+						if (trailing > NO_TRAILING_COMMENT && lines >= 1) {
+							// a block comment on next line means that there's no trailing comment
+							this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1);
+							return;
+						}
+						this.lastLineComment.contiguous = false;
+						if (rejectBlockComment) break;
+						if (lines >= 1) {
+							if (lines > 1) {
+								preserveEmptyLines(lines - 1, this.scanner.getCurrentTokenStartPosition());
+							} else if (lines == 1) {
+								printNewLine(this.scanner.getCurrentTokenStartPosition());
+							}
+						} else if (hasWhitespaces) {
+							space();
+						}
+						hasWhitespaces = false;
+						printBlockComment(false);
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = false;
+						hasComment = true;
+						lines = 0;
+						if (this.useTags && !this.editsEnabled) {
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+							} else if (this.tagsKind == this.currentToken) {
+	    						this.editsEnabled = CharOperation.fragmentEquals(this.enablingTag, this.scanner.source, tokenStartPosition, true);
+					    	}
+						}
+						break;
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						if (this.useTags && this.editsEnabled && foundTaskCount > 0) {
+							setEditsEnabled(foundTaskCount);
+							if (!this.editsEnabled && this.editsIndex > 1) {
+								OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+								if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) {
+									printNewLinesBeforeDisablingComment();
+								}
+							}
+						}
+						if (trailing > NO_TRAILING_COMMENT) {
+							// a javadoc comment should not be considered as a trailing comment
+							this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1);
+							return;
+						}
+						this.lastLineComment.contiguous = false;
+						if (rejectJavadocComment) break;
+						if (lines >= 1) {
+							if (lines > 1) {
+								preserveEmptyLines(lines - 1, this.scanner.getCurrentTokenStartPosition());
+							} else if (lines == 1) {
+								printNewLine(this.scanner.getCurrentTokenStartPosition());
+							}
+						} else if (hasWhitespaces) {
+							space();
+						}
+						hasWhitespaces = false;
+						if (includesJavadocComments()) {
+							printJavadocComment(this.scanner.startPosition, this.scanner.currentPosition);
+						} else {
+							printBlockComment(true);
+						}
+						if (this.useTags && !this.editsEnabled && foundTaskCount > 0) {
+							setEditsEnabled(foundTaskCount);
+						}
+						printNewLine();
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasLineComment = false;
+						hasComment = true;
+						lines = 0;
+						break;
+					default :
+						this.lastLineComment.contiguous = false;
+						// step back one token
+						this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+						return;
+				}
+			}
+		} catch (InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	void printComment(int kind, String source, int start, int end, int level) {
+
+		// Set scanner
+		resetScanner(source.toCharArray());
+		this.scanner.resetTo(start, end);
+		// Put back 3.4RC2 code => comment following line  as it has an impact on Linux tests
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=234336
+		// TODO (frederic) Need more investigations and a better fix in
+		// isAdaptableRegion(int) and adaptRegions()
+		// this.scannerEndPosition = end;
+
+		// Set indentation level
+	    this.numberOfIndentations = level;
+	    this.indentationLevel = level * this.indentationSize;
+	    this.column = this.indentationLevel + 1;
+
+	    // Print corresponding comment
+	    switch (kind) {
+	    	case CodeFormatter.K_SINGLE_LINE_COMMENT:
+			    printComment(kind, NO_TRAILING_COMMENT);
+	    		break;
+	    	case CodeFormatter.K_MULTI_LINE_COMMENT:
+			    printComment(kind, NO_TRAILING_COMMENT);
+	    		break;
+	    	case CodeFormatter.K_JAVA_DOC:
+	    		printJavadocComment(start, end);
+	    		break;
+	    }
+    }
+
+	private void printLineComment() {
+    	int currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+    	int currentTokenEndPosition = this.scanner.getCurrentTokenEndPosition() + 1;
+    	boolean includesLineComments = includesLineComments();
+    	boolean isNlsTag = false;
+    	if (CharOperation.indexOf(Scanner.TAG_PREFIX, this.scanner.source, true, currentTokenStartPosition, currentTokenEndPosition) != -1) {
+    		this.nlsTagCounter = 0;
+    		isNlsTag = true;
+    	}
+    	this.scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition - 1);
+    	int currentCharacter;
+    	int start = currentTokenStartPosition;
+    	int nextCharacterStart = currentTokenStartPosition;
+
+    	// Print comment line indentation
+    	int commentIndentationLevel;
+   		boolean onFirstColumn = isOnFirstColumn(start);
+    	if (this.indentationLevel == 0) {
+    		commentIndentationLevel = this.column - 1;
+    	} else {
+			if (onFirstColumn &&
+					((includesLineComments && !this.formatter.preferences.comment_format_line_comment_starting_on_first_column) ||
+					 this.formatter.preferences.never_indent_line_comments_on_first_column)
+    			) {
+	   			commentIndentationLevel = this.column - 1;
+    		} else {
+    			// Indentation may be specific for contiguous comment
+    			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300
+				if (this.lastLineComment.contiguous) {
+					// The leading spaces have been set while looping in the printComment(int) method
+					int currentCommentIndentation = getCurrentIndentation(this.lastLineComment.leadingSpaces, 0);
+					// Keep the current comment indentation when over the previous contiguous line comment
+					// and the previous comment has not been reindented
+					int relativeIndentation = currentCommentIndentation - this.lastLineComment.currentIndentation;
+					boolean similarCommentsIndentation = false;
+					if (this.tabLength == 0) {
+						similarCommentsIndentation = relativeIndentation == 0;
+					} else if (relativeIndentation > -this.tabLength) {
+						similarCommentsIndentation = relativeIndentation == 0 || currentCommentIndentation != 0 && this.lastLineComment.currentIndentation != 0;
+					}
+					if (similarCommentsIndentation && this.lastLineComment.indentation != this.indentationLevel) {
+						int currentIndentationLevel = this.indentationLevel;
+						this.indentationLevel = this.lastLineComment.indentation ;
+						printIndentationIfNecessary();
+						this.indentationLevel = currentIndentationLevel;
+			   			commentIndentationLevel = this.lastLineComment.indentation ;
+					} else {
+						printIndentationIfNecessary();
+			   			commentIndentationLevel = this.column - 1;
+					}
+				} else {
+					if (this.currentAlignment != null && this.currentAlignment.kind == Alignment.ARRAY_INITIALIZER &&
+						this.currentAlignment.fragmentCount > 0 &&
+						this.indentationLevel < this.currentAlignment.breakIndentationLevel &&
+						this.lastLineComment.lines > 0)
+					{
+						int currentIndentationLevel = this.indentationLevel;
+						this.indentationLevel = this.currentAlignment.breakIndentationLevel;
+		    			printIndentationIfNecessary();
+						this.indentationLevel = currentIndentationLevel;
+			   			commentIndentationLevel = this.currentAlignment.breakIndentationLevel;
+					} else {
+		    			printIndentationIfNecessary();
+			   			commentIndentationLevel = this.column - 1;
+					}
+				}
+    		}
+    	}
+    	
+    	// Store line comment information
+   		this.lastLineComment.contiguous = true;
+		this.lastLineComment.currentIndentation = getCurrentCommentIndentation(currentTokenStartPosition);
+		this.lastLineComment.indentation = commentIndentationLevel;
+		
+		// Add pending space if necessary
+    	if (this.pendingSpace) {
+    		if (this.formatter.preferences.comment_preserve_white_space_between_code_and_line_comments) {
+    			addInsertEdit(currentTokenStartPosition, new String(this.lastLineComment.leadingSpaces));
+    		} else {
+    			addInsertEdit(currentTokenStartPosition, " "); //$NON-NLS-1$
+    		}
+    	}
+    	this.needSpace = false;
+    	this.pendingSpace = false;
+    	int previousStart = currentTokenStartPosition;
+
+		if (!isNlsTag && includesLineComments && (!onFirstColumn || this.formatter.preferences.comment_format_line_comment_starting_on_first_column)) {
+			printLineComment(currentTokenStartPosition, currentTokenEndPosition-1);
+		} else {
+			// do nothing!?
+	    	loop: while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = this.scanner.getNextChar()) != -1) {
+	    		nextCharacterStart = this.scanner.currentPosition;
+
+	    		switch(currentCharacter) {
+	    			case '\r' :
+	    				start = previousStart;
+	    				break loop;
+	    			case '\n' :
+	    				start = previousStart;
+	    				break loop;
+	    		}
+	    		previousStart = nextCharacterStart;
+	    	}
+	    	if (start != currentTokenStartPosition) {
+	    		// this means that the line comment doesn't end the file
+	    		addReplaceEdit(start, currentTokenEndPosition - 1, this.lineSeparator);
+	    		this.line++;
+	    		this.column = 1;
+	    		this.lastNumberOfNewLines = 1;
+	    	}
+		}
+    	this.needSpace = false;
+    	this.pendingSpace = false;
+    	// realign to the proper value
+    	if (this.currentAlignment != null) {
+    		if (this.memberAlignment != null) {
+    			// select the last alignment
+    			if (this.currentAlignment.location.inputOffset > this.memberAlignment.location.inputOffset) {
+    				if (this.currentAlignment.couldBreak() && this.currentAlignment.wasSplit) {
+    					this.currentAlignment.performFragmentEffect();
+    				}
+    			} else {
+    				this.indentationLevel = Math.max(this.indentationLevel, this.memberAlignment.breakIndentationLevel);
+    			}
+    		} else if (this.currentAlignment.couldBreak() && this.currentAlignment.wasSplit) {
+    			this.currentAlignment.performFragmentEffect();
+    		}
+    		if (this.currentAlignment.kind == Alignment.BINARY_EXPRESSION &&
+    			this.currentAlignment.enclosing != null &&
+    			this.currentAlignment.enclosing.kind == Alignment.BINARY_EXPRESSION &&
+    			this.indentationLevel < this.currentAlignment.breakIndentationLevel)
+    		{
+    			this.indentationLevel = this.currentAlignment.breakIndentationLevel;
+    		}
+    	}
+    	this.scanner.resetTo(currentTokenEndPosition, this.scannerEndPosition - 1);
+    }
+
+	private void printLineComment(int commentStart, int commentEnd) {
+
+		// Compute indentation
+		int firstColumn = this.column;
+		int indentLevel = this.indentationLevel;
+		int indentations = this.numberOfIndentations;
+		this.indentationLevel = getNextIndentationLevel(firstColumn);
+		if (this.indentationSize != 0) {
+			this.numberOfIndentations = this.indentationLevel / this.indentationSize;
+		}
+		else{
+			this.numberOfIndentations = 0;
+		}
+
+		// Consume the comment prefix
+		this.scanner.resetTo(commentStart, commentEnd);
+		this.scanner.getNextChar();
+		this.scanner.getNextChar();
+		this.column += 2;
+
+		// Scan the text token per token to compact it and size it the max line length
+		int maxColumn = this.formatter.preferences.comment_line_length + 1;
+		int previousToken = -1;
+		int lastTokenEndPosition = commentStart;
+		int spaceStartPosition = -1;
+		int spaceEndPosition = -1;
+		this.scanner.skipComments = true;
+		String newLineString = null;
+		this.commentIndentation = null;
+
+		// Consume text token per token
+		while (!this.scanner.atEnd()) {
+			int token;
+			try {
+				token = this.scanner.getNextToken();
+			} catch (InvalidInputException iie) {
+	    		token = consumeInvalidToken(commentEnd);
+			}
+			switch (token) {
+				case TerminalTokens.TokenNameWHITESPACE:
+					if (previousToken == -1) {
+						// do not remember the first whitespace
+						previousToken = SKIP_FIRST_WHITESPACE_TOKEN;
+					} else {
+						previousToken = token;
+					}
+					// Remember space position
+					spaceStartPosition = this.scanner.getCurrentTokenStartPosition();
+					spaceEndPosition = this.scanner.getCurrentTokenEndPosition();
+					continue;
+				case TerminalTokens.TokenNameEOF:
+					continue;
+				case TerminalTokens.TokenNameIdentifier:
+					if (previousToken == -1 || previousToken == SKIP_FIRST_WHITESPACE_TOKEN) {
+						char[] identifier = this.scanner.getCurrentTokenSource();
+						int startPosition = this.scanner.getCurrentTokenStartPosition();
+						int restartPosition = this.scanner.currentPosition;
+						if (CharOperation.equals(identifier, Parser.FALL_THROUGH_TAG, 0, 5/*length of string "$FALL"*/) && this.scanner.currentCharacter == '-') {
+							try {
+								this.scanner.getNextToken(); //  consume the '-'
+								token = this.scanner.getNextToken(); // consume the "THROUGH"
+								if (token == TerminalTokens.TokenNameIdentifier) {
+									identifier = this.scanner.getCurrentTokenSource();
+									if (CharOperation.endsWith(Parser.FALL_THROUGH_TAG, identifier)) {
+										// the comment starts with a fall through
+										if (previousToken == SKIP_FIRST_WHITESPACE_TOKEN) {
+											addReplaceEdit(spaceStartPosition, startPosition-1, " "); //$NON-NLS-1$
+										}
+										this.scanner.startPosition = startPosition;
+										previousToken = token;
+										break;
+									}
+								}
+							} catch (InvalidInputException iie) {
+								// skip
+							}
+						}
+						// this was not a valid fall-through tag, hence continue to process the comment normally
+						this.scanner.startPosition = startPosition;
+			    		this.scanner.currentPosition = restartPosition;
+					}
+					break;
+			}
+			int tokenStart = this.scanner.getCurrentTokenStartPosition();
+    		int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - tokenStart;
+
+			// insert space at the beginning if not present
+			if (previousToken == -1 ) {
+    			addInsertEdit(this.scanner.startPosition, " "); //$NON-NLS-1$
+				this.column++;
+			}
+			// replace space at the beginning if present
+			else if (previousToken == SKIP_FIRST_WHITESPACE_TOKEN) {
+				addReplaceEdit(spaceStartPosition, this.scanner.startPosition-1, " "); //$NON-NLS-1$
+				this.column++;
+				spaceStartPosition = -1; // do not use this position to split the comment
+			} else {
+				// not on the first token
+				boolean insertSpace = previousToken == TerminalTokens.TokenNameWHITESPACE;
+				if (insertSpace) {
+					// count inserted space if any in token length
+					tokenLength++;
+				}
+				// insert new line if max line width is reached and a space was previously encountered
+				if (spaceStartPosition > 0 && (this.column+tokenLength) > maxColumn) {
+					this.lastNumberOfNewLines++;
+					this.line++;
+					if (newLineString == null) {
+						this.tempBuffer.setLength(0);
+						this.tempBuffer.append(this.lineSeparator);
+						this.column = 1;
+						if (!this.formatter.preferences.never_indent_line_comments_on_first_column) {
+							printIndentationIfNecessary(this.tempBuffer);
+						}
+					    this.tempBuffer.append(LINE_COMMENT_PREFIX);
+						this.column += LINE_COMMENT_PREFIX_LENGTH;
+						newLineString = this.tempBuffer.toString();
+				    	firstColumn = this.column;
+					} else {
+						this.column = firstColumn;
+					}
+					if (lastTokenEndPosition > spaceEndPosition) {
+						this.column += lastTokenEndPosition - (spaceEndPosition + 1); // add all previous tokens lengths since last space
+					}
+					if (this.edits[this.editsIndex-1].offset == spaceStartPosition) {
+						// previous space was already edited, so remove it
+						this.editsIndex--;
+					}
+					addReplaceEdit(spaceStartPosition, spaceEndPosition, newLineString);
+					spaceStartPosition = -1;
+					if (insertSpace) {
+						tokenLength--; // reduce token length as the space will be replaced by the new line
+					}
+				}
+				// replace space if needed
+				else if (insertSpace) {
+					addReplaceEdit(spaceStartPosition, this.scanner.startPosition-1, " "); //$NON-NLS-1$
+				}
+			}
+			// update column position and store info of the current token
+			this.column += tokenLength;
+			previousToken = token;
+			lastTokenEndPosition = this.scanner.currentPosition;
+		}
+		this.scanner.skipComments = false;
+
+		// Skip separator if the comment is not at the end of file
+		this.indentationLevel = indentLevel;
+		this.numberOfIndentations = indentations;
+		this.lastNumberOfNewLines = 0;
+		this.scanner.resetTo(lastTokenEndPosition, commentEnd);
+		while (!this.scanner.atEnd()) {
+			spaceEndPosition = this.scanner.currentPosition;
+			this.scanner.getNextChar();
+			if (this.scanner.currentCharacter == '\n' || this.scanner.currentCharacter == '\r') {
+				// line comment is normally ended with new line
+				this.column = 1;
+				this.line++;
+				this.lastNumberOfNewLines++;
+				break;
+			}
+		}
+
+		// Replace the line separator at the end of the comment if any...
+		int startReplace = previousToken == SKIP_FIRST_WHITESPACE_TOKEN ? spaceStartPosition : lastTokenEndPosition;
+		if (this.column == 1 && commentEnd >= startReplace) {
+			addReplaceEdit(startReplace, commentEnd, this.formatter.preferences.line_separator);
+		}
+	}
+
+	public void printEmptyLines(int linesNumber) {
+		this.printEmptyLines(linesNumber, this.scanner.getCurrentTokenEndPosition() + 1);
+	}
+
+	private void printEmptyLines(int linesNumber, int insertPosition) {
+		final String buffer = getEmptyLines(linesNumber);
+		if (Util.EMPTY_STRING == buffer) return;
+		addInsertEdit(insertPosition, buffer);
+	}
+
+	void printIndentationIfNecessary() {
+		this.tempBuffer.setLength(0);
+		printIndentationIfNecessary(this.tempBuffer);
+		if (this.tempBuffer.length() > 0) {
+			addInsertEdit(this.scanner.getCurrentTokenStartPosition(), this.tempBuffer.toString());
+			this.pendingSpace = false;
+		}
+	}
+
+	private void printIndentationIfNecessary(StringBuffer buffer) {
+		switch(this.tabChar) {
+			case DefaultCodeFormatterOptions.TAB :
+				boolean useTabsForLeadingIndents = this.useTabsOnlyForLeadingIndents;
+				int numberOfLeadingIndents = this.numberOfIndentations;
+				int indentationsAsTab = 0;
+				if (useTabsForLeadingIndents) {
+					while (this.column <= this.indentationLevel) {
+						if (this.tabLength > 0 && indentationsAsTab < numberOfLeadingIndents) {
+							if (buffer != null) buffer.append('\t');
+							indentationsAsTab++;
+							int complement = this.tabLength - ((this.column - 1) % this.tabLength); // amount of space
+							this.column += complement;
+						} else {
+							if (buffer != null) buffer.append(' ');
+							this.column++;
+						}
+						this.needSpace = false;
+					}
+				} else if (this.tabLength > 0) {
+					while (this.column <= this.indentationLevel) {
+						if (buffer != null) buffer.append('\t');
+						int complement = this.tabLength - ((this.column - 1) % this.tabLength); // amount of space
+						this.column += complement;
+						this.needSpace = false;
+					}
+				}
+				break;
+			case DefaultCodeFormatterOptions.SPACE :
+				while (this.column <= this.indentationLevel) {
+					if (buffer != null) buffer.append(' ');
+					this.column++;
+					this.needSpace = false;
+				}
+				break;
+			case DefaultCodeFormatterOptions.MIXED :
+				useTabsForLeadingIndents = this.useTabsOnlyForLeadingIndents;
+				numberOfLeadingIndents = this.numberOfIndentations;
+				indentationsAsTab = 0;
+				if (useTabsForLeadingIndents) {
+					final int columnForLeadingIndents = numberOfLeadingIndents * this.indentationSize;
+					while (this.column <= this.indentationLevel) {
+						if (this.column <= columnForLeadingIndents) {
+							if (this.tabLength > 0 && (this.column - 1 + this.tabLength) <= this.indentationLevel) {
+								if (buffer != null) buffer.append('\t');
+								this.column += this.tabLength;
+							} else if ((this.column - 1 + this.indentationSize) <= this.indentationLevel) {
+								// print one indentation
+								// note that this.indentationSize > 0 when entering in the following loop
+								// hence this.column will be incremented and then avoid endless loop (see bug 290905)
+								for (int i = 0, max = this.indentationSize; i < max; i++) {
+									if (buffer != null) buffer.append(' ');
+									this.column++;
+								}
+							} else {
+								if (buffer != null) buffer.append(' ');
+								this.column++;
+							}
+						} else {
+							for (int i = this.column, max = this.indentationLevel; i <= max; i++) {
+								if (buffer != null) buffer.append(' ');
+								this.column++;
+							}
+						}
+						this.needSpace = false;
+					}
+				} else {
+					while (this.column <= this.indentationLevel) {
+						if (this.tabLength > 0 && (this.column - 1 + this.tabLength) <= this.indentationLevel) {
+							if (buffer != null) buffer.append('\t');
+							this.column += this.tabLength;
+						} else if (this.indentationSize > 0 && (this.column - 1 + this.indentationSize) <= this.indentationLevel) {
+							// print one indentation
+							for (int i = 0, max = this.indentationSize; i < max; i++) {
+								if (buffer != null) buffer.append(' ');
+								this.column++;
+							}
+						} else {
+							if (buffer != null) buffer.append(' ');
+							this.column++;
+						}
+						this.needSpace = false;
+					}
+				}
+				break;
+		}
+	}
+
+	private void printJavadocBlock(FormatJavadocBlock block) {
+		if( block == null) return;
+
+		// Init positions
+		int previousEnd = block.tagEnd;
+		int maxNodes = block.nodesPtr;
+
+		// Compute indentation
+		boolean headerLine = block.isHeaderLine() && this.lastNumberOfNewLines == 0;
+		int maxColumn = this.formatter.preferences.comment_line_length + 1;
+		if (headerLine) {
+			maxColumn++;
+		}
+
+		// format tag section if necessary
+		if (!block.isInlined()) {
+			this.lastNumberOfNewLines = 0;
+		}
+		if (block.isDescription()) {
+			if (!block.isInlined()) {
+			    this.commentIndentation = null;
+			}
+		} else {
+			int tagLength = previousEnd - block.sourceStart + 1;
+			this.column += tagLength;
+			if (!block.isInlined()) {
+			    boolean indentRootTags = this.formatter.preferences.comment_indent_root_tags && !block.isInDescription();
+			    int commentIndentationLevel = 0;
+				if (indentRootTags) {
+				    commentIndentationLevel = tagLength + 1;
+					boolean indentParamTag = this.formatter.preferences.comment_indent_parameter_description && block.isInParamTag();
+					if (indentParamTag) {
+						commentIndentationLevel += this.indentationSize;
+					}
+				}
+				setCommentIndentation(commentIndentationLevel);
+			}
+			FormatJavadocReference reference= block.reference;
+			if (reference != null) {
+				// format reference
+				printJavadocBlockReference(block, reference);
+				previousEnd = reference.sourceEnd;
+			}
+
+			// Nothing else to do if the tag has no node
+			if (maxNodes < 0)  {
+				if (block.isInlined()) {
+					this.column++;
+				}
+				return;
+			}
+		}
+
+		// tag section: iterate through the blocks composing this tag but the last one
+		int previousLine = Util.getLineNumber(previousEnd, this.lineEnds, 0, this.maxLines);
+		boolean clearBlankLines = this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment;
+		boolean joinLines = this.formatter.preferences.join_lines_in_comments;
+		for (int i=0; i<=maxNodes; i++) {
+			FormatJavadocNode node = block.nodes[i];
+			int nodeStart = node.sourceStart;
+
+			// Print empty lines before the node
+			int newLines;
+			if (i == 0) {
+				newLines = this.formatter.preferences.comment_insert_new_line_for_parameter && block.isParamTag() ? 1 : 0;
+				if (nodeStart > (previousEnd+1)) {
+					if (!clearBlankLines || !joinLines) {
+						int startLine = Util.getLineNumber(nodeStart, this.lineEnds, previousLine-1, this.maxLines);
+						int gapLine = previousLine;
+						if (joinLines) gapLine++; // if not preserving line break then gap must be at least of one line
+						if (startLine > gapLine) {
+							newLines = startLine - previousLine;
+						}
+						if (clearBlankLines) {
+							// clearing blank lines in this block means that break lines should be preserved, hence only keep one new line
+							if (newLines > 0)  newLines = 1;
+						}
+					}
+					if (newLines == 0 && (!node.isImmutable() || block.reference != null)) {
+						newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
+					}
+					if (block.isImmutable()) {
+						printJavadocGapLinesForImmutableBlock(block);
+					} else {
+						printJavadocGapLines(previousEnd+1, nodeStart-1, newLines, clearBlankLines, false, null);
+					}
+				} else {
+					this.tempBuffer.setLength(0);
+					if (newLines > 0) {
+						for (int j=0; j<newLines; j++) {
+							printJavadocNewLine(this.tempBuffer);
+						}
+						addInsertEdit(nodeStart, this.tempBuffer.toString());
+					}
+				}
+			} else {
+				newLines = this.column > maxColumn ? 1 : 0;
+				if (!clearBlankLines && node.lineStart > (previousLine+1)) newLines = node.lineStart - previousLine;
+				if (newLines < node.linesBefore) newLines = node.linesBefore;
+				if (newLines == 0) {
+					newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
+				}
+				if (newLines > 0 || nodeStart > (previousEnd+1)) {
+		   			printJavadocGapLines(previousEnd+1, nodeStart-1, newLines, clearBlankLines, false, null);
+				}
+			}
+			if (headerLine && newLines > 0) {
+				headerLine = false;
+				maxColumn--;
+			}
+
+			// Print node
+			if (node.isText()) {
+				FormatJavadocText text = (FormatJavadocText) node;
+				if (text.isImmutable()) {
+					// Indent if new line was added
+					if (text.isImmutableHtmlTag() && newLines > 0 && this.commentIndentation != null) {
+				    	addInsertEdit(node.sourceStart, this.commentIndentation);
+				    	this.column += this.commentIndentation.length();
+					}
+					printJavadocImmutableText(text, block, newLines > 0);
+					this.column += getTextLength(block, text);
+				} else if (text.isHtmlTag()) {
+					printJavadocHtmlTag(text, block, newLines>0);
+				} else {
+					printJavadocText(text, block, newLines>0);
+				}
+			} else {
+				if (newLines > 0 && this.commentIndentation != null) {
+			    	addInsertEdit(node.sourceStart, this.commentIndentation);
+			    	this.column += this.commentIndentation.length();
+				}
+				printJavadocBlock((FormatJavadocBlock)node);
+			}
+
+			// Print empty lines before the node
+			previousEnd = node.sourceEnd;
+			previousLine = Util.getLineNumber(previousEnd, this.lineEnds, node.lineStart > 1 ? node.lineStart-2 : 0, this.maxLines);
+		}
+		this.lastNumberOfNewLines = 0;
+	}
+
+	private int printJavadocBlockNodesNewLines(FormatJavadocBlock block, FormatJavadocNode node, int previousEnd) {
+	   	int maxColumn = this.formatter.preferences.comment_line_length+1;
+    	int nodeStart = node.sourceStart;
+ 	    try {
+			this.scanner.resetTo(nodeStart , node.sourceEnd);
+	    	int length = 0;
+	    	boolean newLine = false;
+			boolean headerLine = block.isHeaderLine() && this.lastNumberOfNewLines == 0;
+			int firstColumn = 1 + this.indentationLevel + BLOCK_LINE_PREFIX_LENGTH;
+			if (this.commentIndentation != null) firstColumn += this.commentIndentation.length();
+			if (headerLine) maxColumn++;
+			FormatJavadocText text = null;
+			boolean isImmutableNode = node.isImmutable();
+			boolean nodeIsText = node.isText();
+			if (nodeIsText) {
+	    		text = (FormatJavadocText)node;
+			} else {
+				FormatJavadocBlock inlinedBlock = (FormatJavadocBlock)node;
+				if (isImmutableNode) {
+					text = (FormatJavadocText) inlinedBlock.getLastNode();
+					if (text != null) {
+			    		length += inlinedBlock.tagEnd - inlinedBlock.sourceStart + 1;  // tag length
+				    	if (nodeStart > (previousEnd+1)) {
+				    		length++; // include space between nodes
+				    	}
+						this.scanner.resetTo(text.sourceStart , node.sourceEnd);
+					}
+				}
+			}
+	    	if (text != null) {
+    			if (isImmutableNode) {
+			    	if (nodeStart > (previousEnd+1)) {
+			    		length++; // include space between nodes
+			    	}
+    				int lastColumn = this.column + length;
+	    			while (!this.scanner.atEnd()) {
+	    				try {
+		    				int token = this.scanner.getNextToken();
+		    				switch (token) {
+		    					case TerminalTokens.TokenNameWHITESPACE:
+		    						if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) {
+		    							return 0;
+		    						}
+									lastColumn = getCurrentIndentation(this.scanner.getCurrentTokenSource(), lastColumn);
+		    						break;
+		    					case TerminalTokens.TokenNameMULTIPLY:
+		    						if (newLine) {
+		    							newLine = false;
+		    							continue;
+		    						}
+		    						lastColumn++;
+		    						break;
+		    					default:
+					    			lastColumn += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+		    						break;
+		    				}
+	    				}
+	    				catch (InvalidInputException iie) {
+	    					// maybe an unterminated string or comment
+			    			lastColumn += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+	    				}
+	    				if (lastColumn > maxColumn) {
+	    					return 1;
+						}
+	    			}
+	    			return 0;
+    			}
+    			if (text.isHtmlTag()) {
+    				if (text.getHtmlTagID() == JAVADOC_SINGLE_BREAK_TAG_ID) {
+    					// never break before single break tag
+    					return 0;
+    				}
+	    			// read the html tag
+    				this.scanner.getNextToken();
+	    			if (this.scanner.getNextToken() == TerminalTokens.TokenNameDIVIDE) {
+	    				length++;
+	    				this.scanner.getNextToken();
+	    			}
+	    			length += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+	    			this.scanner.getNextToken(); // '>'
+	    			length++;
+	    		} else {
+	    			while (true) {
+	    				int token = this.scanner.getNextToken();
+	    				if (token == TerminalTokens.TokenNameWHITESPACE || token == TerminalTokens.TokenNameEOF) break;
+		    			int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+		    			length += tokenLength;
+		    			if ((this.column + length) >= maxColumn) {
+		    				break;
+		    			}
+	    			}
+	    		}
+	    	} else {
+	    		FormatJavadocBlock inlinedBlock = (FormatJavadocBlock) node;
+	    		length += inlinedBlock.tagEnd - inlinedBlock.sourceStart + 1;  // tag length
+	    		if (inlinedBlock.reference != null) {
+		    		length++; // space between tag and reference
+					this.scanner.resetTo(inlinedBlock.reference.sourceStart, inlinedBlock.reference.sourceEnd);
+					int previousToken = -1;
+					loop: while (!this.scanner.atEnd()) {
+						int token = this.scanner.getNextToken();
+			    		int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+						switch (token) {
+							case TerminalTokens.TokenNameWHITESPACE:
+								if (previousToken == TerminalTokens.TokenNameCOMMA) { // space between method arguments
+									length++;
+								}
+								break;
+							case TerminalTokens.TokenNameMULTIPLY:
+								break;
+							default:
+								length += tokenLength;
+								if ((this.column+length) > maxColumn) {
+									break loop;
+								}
+					    		break;
+						}
+						previousToken = token;
+		    		}
+	    		}
+	    		length++; // one more for closing brace
+	    	}
+	    	if (nodeStart > (previousEnd+1)) {
+	    		length++; // include space between nodes
+	    	}
+    		if ((firstColumn + length) >= maxColumn && node == block.nodes[0]) {
+    			// Do not split in this peculiar case as length would be also over the max
+    			// length on next line
+    			return 0;
+    		}
+			if ((this.column + length) > maxColumn) {
+	    		return 1;
+	    	}
+	    } catch (InvalidInputException iie) {
+	    	// Assume length is one
+	    	int tokenLength = 1;
+	    	if (nodeStart > (previousEnd+1)) {
+	    		tokenLength++; // include space between nodes
+	    	}
+			if ((this.column + tokenLength) > maxColumn) {
+	    		return 1;
+	    	}
+	    }
+	    return 0;
+    }
+
+	private void printJavadocBlockReference(FormatJavadocBlock block, FormatJavadocReference reference) {
+		int maxColumn = this.formatter.preferences.comment_line_length + 1;
+		boolean headerLine = block.isHeaderLine();
+		boolean inlined = block.isInlined();
+		if (headerLine) maxColumn++;
+
+		// First we need to know what is the indentation
+		this.scanner.resetTo(block.tagEnd+1, reference.sourceEnd);
+		this.javadocBlockRefBuffer.setLength(0);
+		boolean needFormat = false;
+		int previousToken = -1;
+		int spacePosition = -1;
+		String newLineString = null;
+		int firstColumn = -1;
+		while (!this.scanner.atEnd()) {
+			int token;
+			try {
+				token = this.scanner.getNextToken();
+	    		int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+				switch (token) {
+					case TerminalTokens.TokenNameWHITESPACE:
+						if (previousToken != -1 || tokenLength > 1 || this.scanner.currentCharacter != ' ') needFormat = true;
+						switch (previousToken) {
+							case TerminalTokens.TokenNameMULTIPLY :
+							case TerminalTokens.TokenNameLPAREN:
+								break;
+							default:	// space between method arguments
+								spacePosition = this.javadocBlockRefBuffer.length();
+								// $FALL-THROUGH$ - fall through next case
+							case -1:
+								this.javadocBlockRefBuffer.append(' ');
+								this.column++;
+								break;
+						}
+						break;
+					case TerminalTokens.TokenNameMULTIPLY:
+						break;
+					default:
+						if (!inlined && spacePosition > 0 && (this.column+tokenLength) > maxColumn) {
+							// not enough space on the line
+							this.lastNumberOfNewLines++;
+							this.line++;
+							if (newLineString == null) {
+								this.tempBuffer.setLength(0);
+								this.tempBuffer.append(this.lineSeparator);
+						    	this.column = 1;
+						    	printIndentationIfNecessary(this.tempBuffer);
+					    		this.tempBuffer.append(BLOCK_LINE_PREFIX);
+					    		this.column += BLOCK_LINE_PREFIX_LENGTH;
+								if (this.commentIndentation != null) {
+							    	this.tempBuffer.append(this.commentIndentation);
+							    	this.column += this.commentIndentation.length();
+						    	}
+						    	newLineString = this.tempBuffer.substring(0, this.tempBuffer.length()-1); // remove last space as buffer will be inserted before a space
+						    	firstColumn = this.column;
+							} else {
+								this.column = firstColumn;
+							}
+							this.column = firstColumn + this.javadocBlockRefBuffer.length() - spacePosition - 1;
+							this.javadocBlockRefBuffer.insert(spacePosition, newLineString);
+							if (headerLine) {
+								headerLine = false;
+								maxColumn--;
+							}
+							spacePosition = -1;
+						}
+						this.javadocBlockRefBuffer.append(this.scanner.source, this.scanner.startPosition, tokenLength);
+			    		this.column += tokenLength;
+			    		break;
+				}
+				previousToken = token;
+			} catch (InvalidInputException iie) {
+				// does not happen as syntax is correct
+			}
+		}
+		if (needFormat) {
+		    addReplaceEdit(block.tagEnd+1, reference.sourceEnd, this.javadocBlockRefBuffer.toString());
+		}
+    }
+
+	private int getTextLength(FormatJavadocBlock block, FormatJavadocText text) {
+
+		// Special case for immutable tags
+		if (text.isImmutable()) {
+			this.scanner.resetTo(text.sourceStart , text.sourceEnd);
+			int textLength = 0;
+			while (!this.scanner.atEnd()) {
+				try {
+	                int token = this.scanner.getNextToken();
+	    			if (token == TerminalTokens.TokenNameWHITESPACE) {
+						if (CharOperation.indexOf('\n', this.scanner.source, this.scanner.startPosition, this.scanner.currentPosition) >= 0) {
+							textLength = 0;
+							this.scanner.getNextChar();
+							if (this.scanner.currentCharacter == '*') {
+								this.scanner.getNextChar();
+								if (this.scanner.currentCharacter != ' ') {
+									textLength++;
+								}
+							} else {
+								textLength++;
+							}
+							continue;
+						}
+	    			}
+	    			textLength += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+                } catch (InvalidInputException e) {
+   					// maybe an unterminated string or comment
+	    			textLength += (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - this.scanner.startPosition;
+                }
+			}
+			return textLength;
+		}
+
+		// Simple for one line tags
+	    if (block.isOneLineTag()) {
+	    	return text.sourceEnd - text.sourceStart + 1;
+	    }
+
+	    // Find last line
+    	int startLine = Util.getLineNumber(text.sourceStart, this.lineEnds, 0, this.maxLines);
+    	int endLine = startLine;
+    	int previousEnd = -1;
+    	for (int i=0; i<=text.separatorsPtr; i++) {
+    		int end = (int) (text.separators[i] >>> 32);
+    		endLine = Util.getLineNumber(end, this.lineEnds, endLine-1, this.maxLines);
+    		if (endLine > startLine) {
+    			return previousEnd - text.sourceStart + 1;
+    		}
+    		previousEnd = end;
+    	}
+
+    	// This was a one line text
+		return text.sourceEnd - text.sourceStart + 1;
+    }
+
+	/*
+	 * Print and formats a javadoc comments
+	 */
+	void printJavadocComment(int start, int end) {
+		int lastIndentationLevel = this.indentationLevel;
+		try {
+			// parse the comment on the fly
+			this.scanner.resetTo(start, end-1);
+			if (! this.formatterCommentParser.parse(start, end-1)) {
+				// problem occurred while parsing the javadoc, early abort formatting
+				return;
+			}
+
+			FormatJavadoc javadoc = (FormatJavadoc) this.formatterCommentParser.docComment;
+
+			// handle indentation
+			if (this.indentationLevel != 0) {
+				printIndentationIfNecessary();
+			}
+
+			// handle pending space if any
+			if (this.pendingSpace) {
+				addInsertEdit(start, " "); //$NON-NLS-1$
+			}
+
+			if (javadoc.blocks == null) {
+				// no FormatJavadocTags in this this javadoc
+				return;
+			}
+
+			// init properly
+			this.needSpace = false;
+			this.pendingSpace = false;
+			int length = javadoc.blocks.length;
+
+			// format empty lines between before the first block
+			FormatJavadocBlock previousBlock = javadoc.blocks[0];
+			this.lastNumberOfNewLines = 0;
+			int currentLine = this.line;
+			int firstBlockStart = previousBlock.sourceStart;
+			printIndentationIfNecessary(null);
+			this.column += JAVADOC_HEADER_LENGTH; // consider that the header is already scanned
+
+			// If there are several blocks in the javadoc
+			int index = 1;
+			if (length > 1) {
+				// format the description if any
+				if (previousBlock.isDescription()) {
+					printJavadocBlock(previousBlock);
+					FormatJavadocBlock block = javadoc.blocks[index++];
+					int newLines = this.formatter.preferences.comment_insert_empty_line_before_root_tags ? 2 : 1;
+					printJavadocGapLines(previousBlock.sourceEnd+1, block.sourceStart-1, newLines, this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment, false, null);
+					previousBlock = block;
+				}
+
+				// format all tags but the last one composing this comment
+				while (index < length) {
+					printJavadocBlock(previousBlock);
+					FormatJavadocBlock block = javadoc.blocks[index++];
+					printJavadocGapLines(previousBlock.sourceEnd+1, block.sourceStart-1, 1, this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment, false, null);
+					previousBlock = block;
+				}
+			}
+
+			// format the last block
+			printJavadocBlock(previousBlock);
+
+			// format the header and footer empty spaces
+			int newLines = (this.formatter.preferences.comment_new_lines_at_javadoc_boundaries && (this.line > currentLine || javadoc.isMultiLine())) ? 1 : 0;
+			printJavadocGapLines(javadoc.textStart, firstBlockStart-1, newLines, this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment, false, null);
+			printJavadocGapLines(previousBlock.sourceEnd+1, javadoc.textEnd, newLines, this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment, true, null);
+		}
+		finally {
+			// reset the scanner
+			this.scanner.resetTo(end, this.scannerEndPosition - 1);
+			this.needSpace = false;
+			this.indentationLevel = lastIndentationLevel;
+			this.lastNumberOfNewLines = 0;
+		}
+	}
+
+	/*
+	 * prints the empty javadoc line between the 2 given positions.
+	 * May insert new '*' before each new line
+	 */
+	private void printJavadocGapLines(int textStartPosition, int textEndPosition, int newLines, boolean clearBlankLines, boolean footer, StringBuffer output) {
+		try {
+			// If no lines to set in the gap then just insert a space if there's enough room to
+			if (newLines == 0) {
+				if (output == null) {
+					addReplaceEdit(textStartPosition, textEndPosition,  " "); //$NON-NLS-1$
+				} else {
+					output.append(' ');
+				}
+				this.column++;
+				return;
+			}
+
+			// if there's no enough room to replace text, then insert the gap
+			if (textStartPosition > textEndPosition) {
+				if (newLines > 0) {
+					this.javadocGapLinesBuffer.setLength(0);
+					for (int i=0; i<newLines; i++) {
+						this.javadocGapLinesBuffer.append(this.lineSeparator);
+						this.column = 1;
+						printIndentationIfNecessary(this.javadocGapLinesBuffer);
+						if (footer) {
+							this.javadocGapLinesBuffer.append(' ');
+							this.column++;
+						} else {
+							this.javadocGapLinesBuffer.append(BLOCK_LINE_PREFIX);
+							this.column += BLOCK_LINE_PREFIX_LENGTH;
+						}
+					}
+					if (output == null) {
+						addInsertEdit(textStartPosition, this.javadocGapLinesBuffer.toString());
+					} else {
+						output.append(this.javadocGapLinesBuffer);
+					}
+				}
+				return;
+			}
+
+			// There's enough room and some lines to set...
+			// Skip the text token per token to keep existing stars when possible
+			this.scanner.resetTo(textStartPosition, textEndPosition);
+			this.scanner.recordLineSeparator = true;
+			this.scanner.linePtr = Util.getLineNumber(textStartPosition, this.lineEnds, 0, this.maxLines) - 2;
+			int linePtr = this.scanner.linePtr;
+			int lineCount = 0;
+			int start = textStartPosition;
+			boolean endsOnMultiply = false;
+			while (!this.scanner.atEnd()) {
+				switch (this.scanner.getNextToken()) {
+					case TerminalTokens.TokenNameMULTIPLY:
+						// we just need to replace each lines between '*' with the javadoc formatted ones
+						int linesGap = this.scanner.linePtr - linePtr;
+						if (linesGap > 0) {
+							this.javadocGapLinesBuffer.setLength(0);
+							if (lineCount > 0) {
+								// TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=49619
+								this.javadocGapLinesBuffer.append( ' ');
+							}
+							for (int i = 0; i < linesGap ; i++) {
+								if (clearBlankLines && lineCount >= newLines) {
+									// leave as the required new lines have been inserted
+									// so remove any remaining blanks and leave
+									if (textEndPosition >= start) {
+										if (output == null) {
+											addReplaceEdit(start, textEndPosition, this.javadocGapLinesBuffer.toString());
+										} else {
+											output.append(this.javadocGapLinesBuffer);
+										}
+									}
+									return;
+								}
+								this.javadocGapLinesBuffer.append(this.lineSeparator);
+								this.column = 1;
+								printIndentationIfNecessary(this.javadocGapLinesBuffer);
+								if (i == (linesGap-1)) {
+									this.javadocGapLinesBuffer.append(' ');
+									this.column++;
+								} else {
+									this.javadocGapLinesBuffer.append(BLOCK_LINE_PREFIX);
+									this.column += BLOCK_LINE_PREFIX_LENGTH;
+								}
+								lineCount++;
+							}
+							int currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+							int tokenLength = this.scanner.currentPosition - currentTokenStartPosition;
+							if (output == null) {
+								addReplaceEdit(start, currentTokenStartPosition-1, this.javadocGapLinesBuffer.toString());
+							} else {
+								output.append(this.javadocGapLinesBuffer);
+								output.append(this.scanner.source, currentTokenStartPosition, tokenLength);
+							}
+							this.column += tokenLength;
+							if (footer && clearBlankLines && lineCount == newLines) {
+								if (textEndPosition >= currentTokenStartPosition) {
+									if (output == null) {
+										addDeleteEdit(currentTokenStartPosition, textEndPosition);
+									}
+								}
+								return;
+							}
+						}
+						// next start is just after the current token
+						start = this.scanner.currentPosition;
+						linePtr = this.scanner.linePtr;
+						endsOnMultiply = true;
+						break;
+					default:
+						endsOnMultiply = false;
+						break;
+				}
+			}
+
+			// Format the last whitespaces
+			if (lineCount < newLines) {
+				// Insert new lines as not enough was encountered while scanning the whitespaces
+				this.javadocGapLinesBuffer.setLength(0);
+				if (lineCount > 0) {
+					// TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=49619
+					this.javadocGapLinesBuffer.append( ' ');
+				}
+				for (int i = lineCount; i < newLines-1; i++) {
+					printJavadocNewLine(this.javadocGapLinesBuffer);
+				}
+				this.javadocGapLinesBuffer.append(this.lineSeparator);
+				this.column = 1;
+				printIndentationIfNecessary(this.javadocGapLinesBuffer);
+				if (footer) {
+					this.javadocGapLinesBuffer.append(' ');
+					this.column++;
+				} else {
+					this.javadocGapLinesBuffer.append(BLOCK_LINE_PREFIX);
+					this.column += BLOCK_LINE_PREFIX_LENGTH;
+				}
+				if (output == null) {
+					if (textEndPosition >= start) {
+						addReplaceEdit(start, textEndPosition, this.javadocGapLinesBuffer.toString());
+					} else {
+						addInsertEdit(textEndPosition+1, this.javadocGapLinesBuffer.toString());
+					}
+				} else {
+					output.append(this.javadocGapLinesBuffer);
+				}
+			} else {
+				// Replace all remaining whitespaces by a single space
+				if (textEndPosition >= start) {
+					this.javadocGapLinesBuffer.setLength(0);
+					if (this.scanner.linePtr > linePtr) {
+						if (lineCount > 0) {
+							// TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=49619
+							this.javadocGapLinesBuffer.append(' ');
+						}
+						this.javadocGapLinesBuffer.append(this.lineSeparator);
+						this.column = 1;
+						printIndentationIfNecessary(this.javadocGapLinesBuffer);
+					}
+					this.javadocGapLinesBuffer.append(' ');
+					if (output == null) {
+						addReplaceEdit(start, textEndPosition, this.javadocGapLinesBuffer.toString());
+					} else {
+						output.append(this.javadocGapLinesBuffer);
+					}
+					this.needSpace = false;
+				} else if (endsOnMultiply) {
+					if (output == null) {
+						addInsertEdit(textEndPosition+1, " "); //$NON-NLS-1$
+					} else {
+						output.append(' ');
+					}
+					this.needSpace = false;
+				}
+				this.column++;
+			}
+		}
+		catch (InvalidInputException iie) {
+			// there's nothing to do if this exception happens
+		}
+		finally {
+			this.scanner.recordLineSeparator = false;
+			this.needSpace = false;
+			this.scanner.resetTo(textEndPosition+1, this.scannerEndPosition - 1);
+			this.lastNumberOfNewLines += newLines;
+			this.line += newLines;
+		}
+	}
+
+	private void printJavadocImmutableText(FormatJavadocText text, FormatJavadocBlock block, boolean textOnNewLine) {
+
+		try {
+			// Iterate on text line separators
+			int textLineStart = text.lineStart;
+			this.scanner.tokenizeWhiteSpace = false;
+			String newLineString = null;
+			for (int idx=0, max=text.separatorsPtr; idx<=max ; idx++) {
+				int start = (int) text.separators[idx];
+				int lineStart = Util.getLineNumber(start, this.lineEnds, textLineStart-1, this.maxLines);
+				while (textLineStart < lineStart) {
+					int end = this.lineEnds[textLineStart-1];
+					this.scanner.resetTo(end, start);
+					int token = this.scanner.getNextToken();
+					switch (token) {
+						case TerminalTokens.TokenNameMULTIPLY:
+						case TerminalTokens.TokenNameMULTIPLY_EQUAL:
+							break;
+						default:
+							return;
+					}
+					if (this.scanner.currentCharacter == ' ') {
+						this.scanner.getNextChar();
+					}
+					if (newLineString == null) {
+						this.tempBuffer.setLength(0);
+						this.column = 1;
+						printIndentationIfNecessary(this.tempBuffer);
+						this.tempBuffer.append(BLOCK_LINE_PREFIX);
+						this.column += BLOCK_LINE_PREFIX_LENGTH;
+						newLineString = this.tempBuffer.toString();
+					}
+					addReplaceEdit(end+1, this.scanner.getCurrentTokenEndPosition(), newLineString);
+					textLineStart = Util.getLineNumber(this.scanner.currentPosition-1, this.lineEnds, textLineStart, this.maxLines);
+				}
+			}
+		}
+		catch (InvalidInputException iie) {
+			// leave
+		}
+		finally {
+			// Reset
+			this.needSpace = false;
+			this.scanner.tokenizeWhiteSpace = true;
+			this.scanner.resetTo(text.sourceEnd+1, this.scannerEndPosition - 1);
+		}
+	}
+
+	/*
+	 *  Print the gap lines for an immutable block.
+	 *  That's needed to  be specific as the formatter needs to keep white spaces
+	 *  if possible except those which are indentation ones.
+	 *  Note that in the peculiar case of a two lines immutable tag (multi lines block),
+	 *  the formatter will join the two lines.
+	 */
+	private void printJavadocGapLinesForImmutableBlock(FormatJavadocBlock block) {
+
+		// Init
+		int firstLineEnd = -1; // not initialized
+		int newLineStart = -1; // not initialized
+		int secondLineStart = -1; // not initialized
+		int starPosition = -1; // not initialized
+		int offset = 0;
+		int start = block.tagEnd + 1;
+		int end = block.nodes[0].sourceStart-1;
+		this.scanner.resetTo(start, end);
+		int lineStart = block.lineStart;
+		int lineEnd = Util.getLineNumber(block.nodes[0].sourceEnd, this.lineEnds, lineStart-1, this.maxLines);
+		boolean multiLinesBlock = lineEnd > (lineStart+1);
+		int previousPosition = this.scanner.currentPosition;
+		String newLineString = null;
+		int indentationColumn = 0;
+		int leadingSpaces = -1;
+
+		// Scan the existing gap
+		while (!this.scanner.atEnd()) {
+			char ch = (char) this.scanner.getNextChar();
+			switch (ch) {
+				case '\t' :
+					// increase the corresponding counter from the appropriate tab value
+					if (secondLineStart > 0 || firstLineEnd < 0) {
+						int reminder = this.tabLength == 0 ? 0 : offset % this.tabLength;
+						if (reminder == 0) {
+							offset += this.tabLength;
+						} else {
+							offset = ((offset / this.tabLength) + 1) * this.tabLength;
+						}
+					} else if (leadingSpaces >= 0) {
+						int reminder = this.tabLength == 0 ? 0 : offset % this.tabLength;
+						if (reminder == 0) {
+							leadingSpaces += this.tabLength;
+						} else {
+							leadingSpaces = ((offset / this.tabLength) + 1) * this.tabLength;
+						}
+					}
+					break;
+				case '\r' :
+				case '\n' :
+					// new line, store the end of the first one
+					if (firstLineEnd < 0) {
+						firstLineEnd = previousPosition;
+					}
+					// print indentation if there were spaces without any star on the line
+					if (leadingSpaces > 0 && multiLinesBlock) {
+						if (newLineString == null) {
+							this.column = 1;
+							this.tempBuffer.setLength(0);
+							printIndentationIfNecessary(this.tempBuffer);
+							this.tempBuffer.append(BLOCK_LINE_PREFIX);
+							this.column += BLOCK_LINE_PREFIX_LENGTH;
+							newLineString = this.tempBuffer.toString();
+							indentationColumn = this.column;
+						} else {
+							this.column = indentationColumn;
+						}
+						addReplaceEdit(newLineStart, newLineStart+indentationColumn-2, newLineString);
+					}
+					// store line start and reset positions
+					newLineStart = this.scanner.currentPosition;
+					leadingSpaces = 0;
+					starPosition = -1;
+					if (multiLinesBlock) {
+						offset = 0;
+						secondLineStart = -1;
+					}
+					break;
+				case '*' :
+					// store line start position if this is the first star of the line
+					if (starPosition < 0 && firstLineEnd > 0) {
+						secondLineStart = this.scanner.currentPosition;
+						starPosition = this.scanner.currentPosition;
+						leadingSpaces = -1;
+					}
+					break;
+				default :
+					// increment offset if line has started
+					if (secondLineStart > 0) {
+						// skip first white space after the first '*'
+						if (secondLineStart == starPosition) {
+							secondLineStart = this.scanner.currentPosition;
+						} else {
+							// print indentation before the following characters
+							if (offset == 0 && multiLinesBlock) {
+								if (newLineString == null) {
+									this.tempBuffer.setLength(0);
+									this.column = 1;
+									printIndentationIfNecessary(this.tempBuffer);
+									this.tempBuffer.append(BLOCK_LINE_PREFIX);
+									this.column += BLOCK_LINE_PREFIX_LENGTH;
+									indentationColumn = this.column;
+									newLineString = this.tempBuffer.toString();
+								} else {
+									this.column = indentationColumn;
+								}
+								addReplaceEdit(newLineStart, secondLineStart-1, newLineString);
+							}
+							offset++;
+						}
+					} else if (firstLineEnd < 0) {
+						// no new line yet, increment the offset
+						offset++;
+					} else if (leadingSpaces >= 0) {
+						// no star yet, increment the leading spaces
+						leadingSpaces++;
+					}
+					break;
+			}
+			previousPosition = this.scanner.currentPosition;
+		}
+		
+		// Increment the columns from the numbers of characters counted on the line
+		if (multiLinesBlock) {
+			this.column += offset;
+		} else {
+			this.column++;
+		}
+		
+		// Replace the new line with a single space when there's only one separator
+		// or, if necessary, print the indentation on the last line
+		if (!multiLinesBlock) {
+			if (firstLineEnd > 0) {
+				addReplaceEdit(firstLineEnd, end, " "); //$NON-NLS-1$
+			}
+		}
+		else if (secondLineStart > 0) {
+			if (newLineString == null) {
+				this.tempBuffer.setLength(0);
+				this.column = 1;
+				printIndentationIfNecessary(this.tempBuffer);
+				this.tempBuffer.append(BLOCK_LINE_PREFIX);
+				this.column += BLOCK_LINE_PREFIX_LENGTH;
+				newLineString = this.tempBuffer.toString();
+				indentationColumn = this.column;
+			} else {
+				this.column = indentationColumn;
+			}
+			addReplaceEdit(newLineStart, secondLineStart-1, newLineString);
+		}
+		else if (leadingSpaces > 0) {
+			if (newLineString == null) {
+				this.tempBuffer.setLength(0);
+				this.column = 1;
+				printIndentationIfNecessary(this.tempBuffer);
+				this.tempBuffer.append(BLOCK_LINE_PREFIX);
+				this.column += BLOCK_LINE_PREFIX_LENGTH;
+				newLineString = this.tempBuffer.toString();
+				indentationColumn = this.column;
+			} else {
+				this.column = indentationColumn;
+			}
+			addReplaceEdit(newLineStart, newLineStart+indentationColumn-2, newLineString);
+		}
+
+		// Reset
+		this.needSpace = false;
+		this.scanner.resetTo(end+1, this.scannerEndPosition - 1);
+	}
+
+	private int printJavadocHtmlTag(FormatJavadocText text, FormatJavadocBlock block, boolean textOnNewLine) {
+
+		// Compute indentation if necessary
+		boolean clearBlankLines = this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment;
+
+		// Local variables init
+		int textStart = text.sourceStart;
+		int nextStart = textStart;
+		int startLine = Util.getLineNumber(textStart, this.lineEnds, 0, this.maxLines);
+	    int htmlTagID = text.getHtmlTagID();
+	    if (text.depth >= this.javadocHtmlTagBuffers.length) {
+	    	int length = this.javadocHtmlTagBuffers.length;
+	    	System.arraycopy(this.javadocHtmlTagBuffers, 0, this.javadocHtmlTagBuffers = new StringBuffer[text.depth+6], 0, length);
+	    }
+	    StringBuffer buffer = this.javadocHtmlTagBuffers[text.depth];
+	    if (buffer == null) {
+	    	buffer = new StringBuffer();
+	    	this.javadocHtmlTagBuffers[text.depth] = buffer;
+	    } else {
+	    	buffer.setLength(0);
+	    }
+
+	    // New line will be added before next node
+	    int max = text.separatorsPtr;
+		int linesAfter = 0;
+		int previousEnd = -1;
+	    boolean isHtmlBreakTag = htmlTagID == JAVADOC_SINGLE_BREAK_TAG_ID;
+		boolean isHtmlSeparatorTag = htmlTagID == JAVADOC_SEPARATOR_TAGS_ID;
+		if (isHtmlBreakTag) {
+			return 1;
+		}
+
+		// Iterate on text line separators
+		boolean isCode = htmlTagID == JAVADOC_CODE_TAGS_ID;
+		for (int idx=0, ptr=0; idx<=max || (text.htmlNodesPtr != -1 && ptr <= text.htmlNodesPtr); idx++) {
+
+			// append text to buffer realigning with the line length
+			int end = (idx > max) ? text.sourceEnd : (int) (text.separators[idx] >>> 32);
+			int nodeKind = 0; // text break
+			if (text.htmlNodesPtr >= 0 && ptr <= text.htmlNodesPtr && end > text.htmlNodes[ptr].sourceStart) {
+				FormatJavadocNode node = text.htmlNodes[ptr];
+				FormatJavadocText htmlTag = node.isText() ? (FormatJavadocText) node : null;
+				int newLines = htmlTag == null ? 0 : htmlTag.linesBefore;
+				if (linesAfter > newLines) {
+					newLines = linesAfter;
+					if (newLines > 1 && clearBlankLines) {
+						if (idx < 2 || (text.htmlIndexes[idx-2] & JAVADOC_TAGS_ID_MASK) != JAVADOC_CODE_TAGS_ID) {
+							newLines = 1;
+						}
+					}
+				}
+				if (textStart < previousEnd) {
+					addReplaceEdit(textStart, previousEnd, buffer.toString());
+				}
+				boolean immutable = node.isImmutable();
+				if (newLines == 0) {
+					newLines = printJavadocBlockNodesNewLines(block, node, previousEnd);
+				}
+				int nodeStart = node.sourceStart;
+				if (newLines > 0 || (idx > 1 && nodeStart > (previousEnd+1))) {
+					printJavadocGapLines(previousEnd+1, nodeStart-1, newLines, clearBlankLines, false, null);
+				}
+				if (newLines > 0) textOnNewLine = true;
+				buffer.setLength(0);
+				if (node.isText()) {
+					if (immutable) {
+						// do not change immutable tags, just increment column
+						if (textOnNewLine && this.commentIndentation != null) {
+					    	addInsertEdit(node.sourceStart, this.commentIndentation);
+					    	this.column += this.commentIndentation.length();
+						}
+						printJavadocImmutableText(htmlTag, block, textOnNewLine);
+						this.column += getTextLength(block, htmlTag);
+						linesAfter = 0;
+					} else {
+						linesAfter = printJavadocHtmlTag(htmlTag, block, textOnNewLine);
+					}
+					nodeKind = 1; // text
+				} else {
+					if (textOnNewLine && this.commentIndentation != null) {
+				    	addInsertEdit(node.sourceStart, this.commentIndentation);
+				    	this.column += this.commentIndentation.length();
+					}
+					printJavadocBlock((FormatJavadocBlock)node);
+					linesAfter = 0;
+					nodeKind = 2; // block
+				}
+				textStart = node.sourceEnd+1;
+				ptr++;
+				if (idx > max)  {
+					return linesAfter;
+				}
+			} else {
+				if (idx > 0 && linesAfter > 0) {
+					printJavadocGapLines(previousEnd+1, nextStart-1, linesAfter, clearBlankLines, false, buffer);
+					textOnNewLine = true;
+				}
+				boolean needIndentation = textOnNewLine;
+				if (idx > 0) {
+					if (!needIndentation && text.isTextAfterHtmlSeparatorTag(idx-1)) {
+						needIndentation = true;
+					}
+				}
+				this.needSpace = idx > 1 && (previousEnd+1) < nextStart; // There's no space between text and html tag or inline block => do not insert space a the beginning of the text
+				printJavadocTextLine(buffer, nextStart, end, block, idx==0, needIndentation, idx==0/* opening html tag?*/ || text.htmlIndexes[idx-1] != -1);
+				linesAfter = 0;
+			    if (idx==0) {
+			    	if (isHtmlSeparatorTag) {
+				    	linesAfter = 1;
+				    }
+				} else if (text.htmlIndexes[idx-1] == JAVADOC_SINGLE_BREAK_TAG_ID) {
+			    	linesAfter = 1;
+			    }
+			}
+
+			// Replace with current buffer if there are several empty lines between text lines
+			nextStart = (int) text.separators[idx];
+			int endLine = Util.getLineNumber(end, this.lineEnds, startLine-1, this.maxLines);
+			startLine = Util.getLineNumber(nextStart, this.lineEnds, endLine-1, this.maxLines);
+			int linesGap = startLine - endLine;
+			if (linesGap > 0) {
+				if (clearBlankLines) {
+					// keep previously computed lines after
+				} else {
+					if (idx==0 || linesGap > 1 || (idx < max && nodeKind==1 && (text.htmlIndexes[idx-1] & JAVADOC_TAGS_ID_MASK) != JAVADOC_IMMUTABLE_TAGS_ID)) {
+						if (linesAfter < linesGap) {
+							linesAfter = linesGap;
+						}
+					}
+				}
+			}
+			textOnNewLine = linesAfter > 0;
+
+			// print <pre> tag
+			if (isCode) {
+    			int codeEnd = (int) (text.separators[max] >>> 32);
+    			if (codeEnd > end) {
+    				if (this.formatter.preferences.comment_format_source) {
+						if (textStart < end) addReplaceEdit(textStart, end, buffer.toString());
+						// See whether there's a space before the code
+						if (linesGap > 0) {
+							int lineStart = this.scanner.getLineStart(startLine);
+							if (nextStart > lineStart) { // if code starts at the line, then no leading space is needed
+								this.scanner.resetTo(lineStart, nextStart-1);
+								try {
+									int token = this.scanner.getNextToken();
+									if (token == TerminalTokens.TokenNameWHITESPACE) {
+										// skip indentation
+										token = this.scanner.getNextToken();
+									}
+									if (token == TerminalTokens.TokenNameMULTIPLY) {
+										nextStart = this.scanner.currentPosition;
+									}
+								}
+								catch (InvalidInputException iie) {
+									// skip
+								}
+							}
+						}
+						// Format gap lines before code
+						int newLines = linesGap;
+						if (newLines == 0) newLines=1;
+						this.needSpace = false;
+						printJavadocGapLines(end+1, nextStart-1, newLines, false/* clear first blank lines inside <pre> tag as done by old formatter */, false, null);
+						// Format the code
+						printCodeSnippet(nextStart, codeEnd, linesGap);
+						// Format the gap lines after the code
+						nextStart = (int) text.separators[max];
+	    				printJavadocGapLines(codeEnd+1, nextStart-1, 1, false/* clear blank lines inside <pre> tag as done by old formatter */, false, null);
+	    				return 2;
+    				}
+    			} else {
+					nextStart = (int) text.separators[max];
+					if ((nextStart-1) > (end+1)) {
+						int line1 = Util.getLineNumber(end+1, this.lineEnds, startLine-1, this.maxLines);
+						int line2 = Util.getLineNumber(nextStart-1, this.lineEnds, line1-1, this.maxLines);
+	    				int gapLines = line2-line1-1;
+						printJavadocGapLines(end+1, nextStart-1, gapLines, false/* never clear blank lines inside <pre> tag*/, false, null);
+						if (gapLines > 0) textOnNewLine = true;
+					}
+    			}
+				return 1;
+			}
+
+			// store previous end
+			previousEnd = end;
+		}
+
+		// Insert last gap
+	    boolean closingTag = isHtmlBreakTag || (text.htmlIndexes != null && (text.htmlIndexes[max] & JAVADOC_TAGS_ID_MASK) == htmlTagID);
+		boolean isValidHtmlSeparatorTag = max > 0 && isHtmlSeparatorTag && closingTag;
+		if (previousEnd != -1) {
+		    if (isValidHtmlSeparatorTag) {
+				if (linesAfter == 0) linesAfter = 1;
+			}
+			if (linesAfter > 0) {
+				printJavadocGapLines(previousEnd+1, nextStart-1, linesAfter, clearBlankLines, false, buffer);
+				textOnNewLine = linesAfter > 0;
+			}
+		}
+
+	    // Print closing tag
+		boolean needIndentation = textOnNewLine;
+		if (!needIndentation && !isHtmlBreakTag && text.htmlIndexes != null && text.isTextAfterHtmlSeparatorTag(max)) {
+			needIndentation = true;
+		}
+		this.needSpace = !closingTag && max > 0 // not a single or not closed tag (e.g. <br>)
+			&& (previousEnd+1) < nextStart; // There's no space between text and html tag or inline block => do not insert space a the beginning of the text
+		printJavadocTextLine(buffer, nextStart, text.sourceEnd, block, max <= 0, needIndentation, closingTag/* closing html tag*/);
+		if (textStart < text.sourceEnd) {
+			addReplaceEdit(textStart, text.sourceEnd, buffer.toString());
+		}
+
+		// Reset
+		this.needSpace = false;
+		this.scanner.resetTo(text.sourceEnd+1, this.scannerEndPosition - 1);
+
+		// Return the new lines to insert after
+	    return isValidHtmlSeparatorTag ? 1 : 0;
+    }
+
+	private void printJavadocNewLine(StringBuffer buffer) {
+	    buffer.append(this.lineSeparator);
+	    this.column = 1;
+	    printIndentationIfNecessary(buffer);
+	    buffer.append(BLOCK_LINE_PREFIX);
+	    this.column += BLOCK_LINE_PREFIX_LENGTH;
+	    this.line++;
+	    this.lastNumberOfNewLines++;
+	}
+
+	private void printJavadocText(FormatJavadocText text, FormatJavadocBlock block, boolean textOnNewLine) {
+
+		boolean clearBlankLines = this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment;
+		boolean joinLines = this.formatter.preferences.join_lines_in_comments;
+		this.javadocTextBuffer.setLength(0);
+		int textStart = text.sourceStart;
+		int nextStart = textStart;
+		int startLine = Util.getLineNumber(textStart, this.lineEnds, 0, this.maxLines);
+
+		// Iterate on text line separators
+		for (int idx=0, max=text.separatorsPtr; idx<=max ; idx++) {
+
+			// append text to buffer realigning with the line length
+			int end = (int) (text.separators[idx] >>> 32);
+			boolean needIndentation = textOnNewLine;
+			if (idx > 0) {
+				if (!needIndentation && text.isTextAfterHtmlSeparatorTag(idx-1)) {
+					needIndentation = true;
+				}
+			}
+			this.needSpace = idx > 0;
+			printJavadocTextLine(this.javadocTextBuffer, nextStart, end, block, idx==0 || (!joinLines && textOnNewLine)/*first text?*/, needIndentation, false /*not an html tag*/);
+			textOnNewLine = false;
+
+			// Replace with current buffer if there are several empty lines between text lines
+			nextStart = (int) text.separators[idx];
+			if (!clearBlankLines || !joinLines) {
+				int endLine = Util.getLineNumber(end, this.lineEnds, startLine-1, this.maxLines);
+				startLine = Util.getLineNumber(nextStart, this.lineEnds, endLine-1, this.maxLines);
+				int gapLine = endLine;
+				if (joinLines) gapLine++; // if not preserving line break then gap must be at least of one line
+				if (startLine > gapLine) {
+					addReplaceEdit(textStart, end, this.javadocTextBuffer.toString());
+					textStart = nextStart;
+					this.javadocTextBuffer.setLength(0);
+					int newLines = startLine - endLine;
+					if (clearBlankLines) newLines = 1;
+					printJavadocGapLines(end+1, nextStart-1, newLines, this.formatter.preferences.comment_clear_blank_lines_in_javadoc_comment, false, null);
+					textOnNewLine = true;
+				}
+				else if (startLine > endLine) {
+					textOnNewLine = !joinLines;
+				}
+			}
+		}
+
+		// Replace remaining line
+		boolean needIndentation = textOnNewLine;
+		this.needSpace = text.separatorsPtr >= 0;
+		printJavadocTextLine(this.javadocTextBuffer, nextStart, text.sourceEnd, block, text.separatorsPtr==-1 /* first text?*/, needIndentation, false /*not an html tag*/);
+		// TODO Bring back following optimization
+		// if (lastNewLines != this.lastNumberOfNewLines || (this.column - currentColumn) != (text.sourceEnd - text.sourceStart + 1)) {
+			addReplaceEdit(textStart, text.sourceEnd, this.javadocTextBuffer.toString());
+		// }
+
+		// Reset
+		this.needSpace = false;
+		this.scanner.resetTo(text.sourceEnd+1, this.scannerEndPosition - 1);
+	}
+
+	/*
+	 * Returns whether the text has been modified or not.
+	 */
+	private void printJavadocTextLine(StringBuffer buffer, int textStart, int textEnd, FormatJavadocBlock block, boolean firstText, boolean needIndentation, boolean isHtmlTag) {
+
+		boolean headerLine = block.isHeaderLine() && this.lastNumberOfNewLines == 0;
+
+		// First we need to know what is the indentation
+		this.javadocTokensBuffer.setLength(0);
+		int firstColumn = 1 + this.indentationLevel + BLOCK_LINE_PREFIX_LENGTH;
+		int maxColumn = this.formatter.preferences.comment_line_length + 1;
+		if (headerLine) {
+			firstColumn++;
+			maxColumn++;
+		}
+		if (needIndentation && this.commentIndentation != null) {
+			buffer.append(this.commentIndentation);
+	    	this.column += this.commentIndentation.length();
+	    	firstColumn += this.commentIndentation.length();
+		}
+		if (this.column < firstColumn) {
+			this.column = firstColumn;
+		}
+
+		// Scan the text token per token to compact it and size it the max line length
+		String newLineString = null;
+		try {
+			this.scanner.resetTo(textStart, textEnd);
+			this.scanner.skipComments = true;
+			int previousToken = -1;
+			boolean textOnNewLine = needIndentation;
+
+			// Consume text token per token
+    		while (!this.scanner.atEnd()) {
+				int token;
+				try {
+					token = this.scanner.getNextToken();
+				} catch (InvalidInputException iie) {
+					token = consumeInvalidToken(textEnd);
+				}
+	    		int tokensBufferLength = this.javadocTokensBuffer.length();
+    			int tokenStart = this.scanner.getCurrentTokenStartPosition();
+	    		int tokenLength = (this.scanner.atEnd() ? this.scanner.eofPosition : this.scanner.currentPosition) - tokenStart;
+				boolean insertSpace = (previousToken == TerminalTokens.TokenNameWHITESPACE || this.needSpace) && !textOnNewLine;
+				String tokensBufferString = this.javadocTokensBuffer.toString().trim();
+				switch (token) {
+					case TerminalTokens.TokenNameWHITESPACE:
+						if (tokensBufferLength > 0) {
+							boolean shouldSplit = (this.column+tokensBufferLength) > maxColumn // the max length is reached
+								&& !isHtmlTag
+								&& (insertSpace || tokensBufferLength > 1) // allow to split at the beginning only when starting with an identifier or a token with a length > 1
+								&& tokensBufferString.charAt(0) != '@'; // avoid to split just before a '@'
+							if (shouldSplit) {
+								this.lastNumberOfNewLines++;
+								this.line++;
+								if (newLineString == null) {
+									this.tempBuffer.setLength(0);
+									this.tempBuffer.append(this.lineSeparator);
+							    	this.column = 1;
+							    	printIndentationIfNecessary(this.tempBuffer);
+						    		this.tempBuffer.append(BLOCK_LINE_PREFIX);
+							    	this.column += BLOCK_LINE_PREFIX_LENGTH;
+									if (this.commentIndentation != null) {
+										this.tempBuffer.append(this.commentIndentation);
+								    	this.column += this.commentIndentation.length();
+									}
+						    		firstColumn = this.column;
+						    		newLineString = this.tempBuffer.toString();
+								} else {
+									this.column = firstColumn;
+								}
+								buffer.append(newLineString);
+								buffer.append(tokensBufferString);
+								this.column += tokensBufferString.length();
+								if (headerLine) {
+									firstColumn--;
+									maxColumn--;
+									headerLine = false;
+								}
+							} else {
+								buffer.append(this.javadocTokensBuffer);
+								this.column += tokensBufferLength;
+							}
+							this.javadocTokensBuffer.setLength(0);
+						}
+						textOnNewLine = false;
+						previousToken = token;
+						continue;
+					case TerminalTokens.TokenNameCharacterLiteral:
+						if (this.scanner.currentPosition > this.scanner.eofPosition) {
+							this.scanner.resetTo(this.scanner.startPosition, textEnd);
+							this.scanner.getNextChar();
+							token = 1;
+						}
+						break;
+				}
+	    		int lastColumn = this.column + tokensBufferLength + tokenLength;
+	    		if (insertSpace) lastColumn++;
+				boolean shouldSplit = lastColumn > maxColumn // the max length is reached
+					&& (!isHtmlTag || previousToken == -1) // not an html tag or just at the beginning of it
+					&& token != TerminalTokens.TokenNameAT && (tokensBufferLength == 0 || this.javadocTokensBuffer.charAt(tokensBufferLength-1) != '@'); // avoid to split just before a '@'
+				if (shouldSplit) {
+					// not enough space on the line
+					if ((tokensBufferLength > 0 || tokenLength < maxColumn) && !isHtmlTag && tokensBufferLength > 0 && (firstColumn+tokensBufferLength+tokenLength) >= maxColumn) {
+						// there won't be enough room even if we break the line before the buffered tokens
+						// So add the buffered tokens now
+						buffer.append(this.javadocTokensBuffer);
+						this.column += tokensBufferLength;
+						this.javadocTokensBuffer.setLength(0);
+						tokensBufferLength = 0;
+						textOnNewLine = false;
+					}
+					if ((tokensBufferLength > 0 || /*(firstColumn+tokenLength) < maxColumn || (insertSpace &&*/ this.column > firstColumn) && (!textOnNewLine || !firstText)) {
+						this.lastNumberOfNewLines++;
+						this.line++;
+						if (newLineString == null) {
+							this.tempBuffer.setLength(0);
+							this.tempBuffer.append(this.lineSeparator);
+					    	this.column = 1;
+					    	printIndentationIfNecessary(this.tempBuffer);
+				    		this.tempBuffer.append(BLOCK_LINE_PREFIX);
+					    	this.column += BLOCK_LINE_PREFIX_LENGTH;
+							if (this.commentIndentation != null) {
+								this.tempBuffer.append(this.commentIndentation);
+						    	this.column += this.commentIndentation.length();
+							}
+				    		firstColumn = this.column;
+				    		newLineString = this.tempBuffer.toString();
+						} else {
+							this.column = firstColumn;
+						}
+						buffer.append(newLineString);
+					}
+			    	if (tokensBufferLength > 0) {
+			    		String tokensString = tokensBufferString;
+						buffer.append(tokensString);
+						this.column += tokensString.length();
+						this.javadocTokensBuffer.setLength(0);
+						tokensBufferLength = 0;
+		    		}
+					buffer.append(this.scanner.source, tokenStart, tokenLength);
+					this.column += tokenLength;
+					textOnNewLine = false;
+					if (headerLine) {
+						firstColumn--;
+						maxColumn--;
+						headerLine = false;
+					}
+    			} else {
+					// append token to the line
+		    		if (insertSpace) {
+		    			this.javadocTokensBuffer.append(' ');
+		    		}
+					this.javadocTokensBuffer.append(this.scanner.source, tokenStart, tokenLength);
+    			}
+				previousToken = token;
+    			this.needSpace = false;
+    			if (headerLine && lastColumn == maxColumn && this.scanner.atEnd()) {
+					this.lastNumberOfNewLines++;
+					this.line++;
+    			}
+    		}
+		}
+		finally {
+			this.scanner.skipComments = false;
+			// Add remaining buffered tokens
+			if (this.javadocTokensBuffer.length() > 0) {
+				buffer.append(this.javadocTokensBuffer);
+				this.column += this.javadocTokensBuffer.length();
+			}
+		}
+    }
+
+	public void printModifiers(Annotation[] annotations, ASTVisitor visitor) {
+		printModifiers(annotations, visitor, ICodeFormatterConstants.ANNOTATION_UNSPECIFIED);
+	}
+
+	public void printModifiers(Annotation[] annotations, ASTVisitor visitor, int annotationSourceKind) {
+		try {
+			int annotationsLength = annotations != null ? annotations.length : 0;
+			int annotationsIndex = 0;
+			boolean isFirstModifier = true;
+			int currentTokenStartPosition = this.scanner.currentPosition;
+			boolean hasComment = false;
+			boolean hasModifiers = false;
+			while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
+				int foundTaskCount = this.scanner.foundTaskCount;
+				int tokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+				int tokenEndPosition = this.scanner.getCurrentTokenEndPosition();
+				switch(this.currentToken) {
+					case TerminalTokens.TokenNamedefault :
+					case TerminalTokens.TokenNamepublic :
+					case TerminalTokens.TokenNameprotected :
+					case TerminalTokens.TokenNameprivate :
+					case TerminalTokens.TokenNamestatic :
+					case TerminalTokens.TokenNameabstract :
+					case TerminalTokens.TokenNamefinal :
+					case TerminalTokens.TokenNamenative :
+					case TerminalTokens.TokenNamesynchronized :
+					case TerminalTokens.TokenNametransient :
+					case TerminalTokens.TokenNamevolatile :
+					case TerminalTokens.TokenNamestrictfp :
+						hasModifiers = true;
+						print(this.scanner.currentPosition - this.scanner.startPosition, !isFirstModifier);
+						isFirstModifier = false;
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameAT :
+						hasModifiers = true;
+						if (!isFirstModifier) {
+							space();
+						}
+						this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1);
+						if (annotationsIndex < annotationsLength) {
+							boolean insertSpaceBeforeBrace = this.formatter.preferences.insert_space_before_opening_brace_in_array_initializer;
+							this.formatter.preferences.insert_space_before_opening_brace_in_array_initializer = false;
+							try {
+								annotations[annotationsIndex++].traverse(visitor, (BlockScope) null);
+							}
+							finally {
+								this.formatter.preferences.insert_space_before_opening_brace_in_array_initializer = insertSpaceBeforeBrace;
+							}
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=122247
+							boolean shouldAddNewLine = false;
+							switch (annotationSourceKind) {
+								case ICodeFormatterConstants.ANNOTATION_ON_TYPE :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_type) {
+										shouldAddNewLine = true;
+									}
+									break;
+								case ICodeFormatterConstants.ANNOTATION_ON_FIELD :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_field) {
+										shouldAddNewLine = true;
+									}
+									break;
+								case ICodeFormatterConstants.ANNOTATION_ON_METHOD :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_method) {
+										shouldAddNewLine = true;
+									}
+									break;
+								case ICodeFormatterConstants.ANNOTATION_ON_PACKAGE :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_package) {
+										shouldAddNewLine = true;
+									}
+									break;
+								case ICodeFormatterConstants.ANNOTATION_ON_PARAMETER :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_parameter) {
+										shouldAddNewLine = true;
+									}
+									break;
+								case ICodeFormatterConstants.ANNOTATION_ON_LOCAL_VARIABLE :
+									if (this.formatter.preferences.insert_new_line_after_annotation_on_local_variable) {
+										shouldAddNewLine = true;
+									}
+									break;
+								default:
+									// do nothing when no annotation formatting option specified
+							}
+							if (shouldAddNewLine) {
+								this.printNewLine();
+							}
+						} else {
+							return;
+						}
+						isFirstModifier = false;
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						if (this.useTags && this.editsEnabled) {
+							boolean turnOff = false;
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+								turnOff = true;
+							} else if (this.tagsKind == this.currentToken
+								&& CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1)) {
+    							this.editsEnabled = false;
+								turnOff = true;
+					    	}
+							if (turnOff) {
+								if (!this.editsEnabled && this.editsIndex > 1) {
+									OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+									if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) {
+										printNewLinesBeforeDisablingComment();
+									}
+								}
+							}
+						}
+						printBlockComment(this.currentToken == TerminalTokens.TokenNameCOMMENT_JAVADOC);
+						if (this.useTags && !this.editsEnabled) {
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+							} else if (this.tagsKind == this.currentToken) {
+	    						this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition+1);
+					    	}
+						}
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasComment = true;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						tokenEndPosition = -this.scanner.commentStops[this.scanner.commentPtr];
+						if (this.useTags && this.editsEnabled) {
+							boolean turnOff = false;
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+								turnOff = true;
+							} else if (this.tagsKind == this.currentToken
+								&& CharOperation.equals(this.disablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition)) {
+    							this.editsEnabled = false;
+								turnOff = true;
+					    	}
+							if (turnOff) {
+								if (!this.editsEnabled && this.editsIndex > 1) {
+									OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+									if (this.scanner.startPosition == currentEdit.offset+currentEdit.length) {
+										printNewLinesBeforeDisablingComment();
+									}
+								}
+							}
+						}
+						printLineComment();
+						if (this.useTags && !this.editsEnabled) {
+							if (foundTaskCount > 0) {
+								setEditsEnabled(foundTaskCount);
+							} else if (this.tagsKind == this.currentToken) {
+	    						this.editsEnabled = CharOperation.equals(this.enablingTag, this.scanner.source, tokenStartPosition, tokenEndPosition);
+					    	}
+						}
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameWHITESPACE :
+						addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						int count = 0;
+						char[] whiteSpaces = this.scanner.getCurrentTokenSource();
+						for (int i = 0, max = whiteSpaces.length; i < max; i++) {
+							switch(whiteSpaces[i]) {
+								case '\r' :
+									if ((i + 1) < max) {
+										if (whiteSpaces[i + 1] == '\n') {
+											i++;
+										}
+									}
+									count++;
+									break;
+								case '\n' :
+									count++;
+							}
+						}
+						if (count >= 1 && hasComment) {
+							printNewLine();
+						}
+						currentTokenStartPosition = this.scanner.currentPosition;
+						hasComment = false;
+						break;
+					default:
+						if (hasModifiers) {
+							space();
+						}
+						// step back one token
+						this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+						return;
+				}
+			}
+		} catch (InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	public void printNewLine() {
+		this.printNewLine(this.scanner.getCurrentTokenEndPosition() + 1);
+	}
+
+	public void printNewLine(int insertPosition) {
+		if (this.nlsTagCounter > 0) {
+			return;
+		}
+		if (this.lastNumberOfNewLines >= 1) {
+			// ensure that the scribe is at the beginning of a new line
+			// only if no specific indentation has been previously set
+			if (!this.preserveLineBreakIndentation) {
+				this.column = 1; 
+			}
+			this.preserveLineBreakIndentation = false;
+			return;
+		}
+		addInsertEdit(insertPosition, this.lineSeparator);
+		this.line++;
+		this.lastNumberOfNewLines = 1;
+		this.column = 1;
+		this.needSpace = false;
+		this.pendingSpace = false;
+		this.preserveLineBreakIndentation = false;
+		this.lastLineComment.contiguous = false;
+	}
+
+	/*
+	 * Print the indentation of a disabling comment
+	 */
+	private void printNewLinesBeforeDisablingComment() {
+
+		// Get the beginning of comment line
+		int linePtr = Arrays.binarySearch(this.lineEnds, this.scanner.startPosition);
+		if (linePtr < 0) {
+			linePtr = -linePtr - 1;
+		}
+		int indentation = 0;
+		int beginningOfLine = getLineEnd(linePtr)+1;
+		if (beginningOfLine == -1) {
+			beginningOfLine = 0;
+		}
+		
+		// If the comment is in the middle of the line, then there's nothing to do
+		OptimizedReplaceEdit currentEdit = this.edits[this.editsIndex-1];
+		int offset = currentEdit.offset;
+		if (offset >= beginningOfLine) return;
+
+		// Compute the comment indentation
+		int scannerStartPosition = this.scanner.startPosition;
+		int scannerEofPosition = this.scanner.eofPosition;
+		int scannerCurrentPosition = this.scanner.currentPosition;
+		char scannerCurrentChar = this.scanner.currentCharacter;
+		int length = currentEdit.length;
+		this.scanner.resetTo(beginningOfLine, offset+length-1);
+		try {
+			while (!this.scanner.atEnd()) {
+				char ch = (char) this.scanner.getNextChar();
+				switch (ch) {
+					case '\t' :
+						if (this.tabLength != 0) {
+							int reminder = indentation % this.tabLength;
+							if (reminder == 0) {
+								indentation += this.tabLength;
+							} else {
+								indentation = ((indentation / this.tabLength) + 1) * this.tabLength;
+							}
+						}
+						break;
+					case ' ':
+						indentation++;
+						break;
+					default:
+						// Should not happen as the offset of the edit is before the beginning of line
+						return;
+				}
+			}
+		
+			// Split the existing edit to keep the change before the beginning of the last line
+			// but change the indentation after. Note that at this stage, the add*Edit methods
+			// cannot be longer used as the edits are disabled
+			String indentationString;
+			int currentIndentation = getCurrentIndentation(this.scanner.currentPosition);
+			if (currentIndentation > 0 && this.indentationLevel > 0) {
+				int col = this.column;
+				this.tempBuffer.setLength(0);
+				printIndentationIfNecessary(this.tempBuffer);
+				indentationString = this.tempBuffer.toString();
+				this.column = col;
+			} else {
+				indentationString = Util.EMPTY_STRING;
+			}
+			String replacement = currentEdit.replacement;
+			if (replacement.length() == 0) {
+				// previous edit was a delete, as we're sure to have a new line before
+				// the comment, then the edit needs to be either replaced entirely with
+				// the expected indentation
+				this.edits[this.editsIndex-1] = new OptimizedReplaceEdit(beginningOfLine, offset+length-beginningOfLine, indentationString);
+			} else {
+				int idx = replacement.lastIndexOf(this.lineSeparator);
+				if (idx >= 0) {
+					// replace current edit if it contains a line separator
+					int start = idx + this.lsLength;
+					this.tempBuffer.setLength(0);
+					this.tempBuffer.append(replacement.substring(0, start));
+					if (indentationString != Util.EMPTY_STRING) {
+						this.tempBuffer.append(indentationString);
+					}
+					this.edits[this.editsIndex-1] = new OptimizedReplaceEdit(offset, length, this.tempBuffer.toString());
+				}
+			}
+		}
+		finally {
+			this.scanner.startPosition = scannerStartPosition;
+			this.scanner.eofPosition = scannerEofPosition;
+			this.scanner.currentPosition = scannerCurrentPosition;
+			this.scanner.currentCharacter = scannerCurrentChar;
+		}
+	}
+
+	/*
+	 * Print new lines characters when the edits are disabled. In this case, only
+	 * the line separator is replaced if necessary, the other white spaces are untouched.
+	 */
+	private boolean printNewLinesCharacters(int offset, int length) {
+		boolean foundNewLine = false;
+		int scannerStartPosition = this.scanner.startPosition;
+		int scannerEofPosition = this.scanner.eofPosition;
+		int scannerCurrentPosition = this.scanner.currentPosition;
+		char scannerCurrentChar = this.scanner.currentCharacter;
+		this.scanner.resetTo(offset, offset+length-1);
+		try {
+			while (!this.scanner.atEnd()) {
+				int start = this.scanner.currentPosition;
+				char ch = (char) this.scanner.getNextChar();
+				boolean needReplace = ch != this.firstLS;
+				switch (ch) {
+					case '\r':
+						if (this.scanner.atEnd()) break;
+						ch = (char) this.scanner.getNextChar();
+						if (ch != '\n') break;
+						needReplace = needReplace || this.lsLength != 2;
+						//$FALL-THROUGH$
+					case '\n':
+						if (needReplace) {
+							if (this.editsIndex == 0 || this.edits[this.editsIndex-1].offset != start) {
+								this.edits[this.editsIndex++] = new OptimizedReplaceEdit(start, this.scanner.currentPosition-start, this.lineSeparator);
+							}
+						}
+						foundNewLine = true;
+						break;
+				}
+			}
+		}
+		finally {
+			this.scanner.startPosition = scannerStartPosition;
+			this.scanner.eofPosition = scannerEofPosition;
+			this.scanner.currentPosition = scannerCurrentPosition;
+			this.scanner.currentCharacter = scannerCurrentChar;
+		}
+		return foundNewLine;		
+	}
+
+	public void printNextToken(int expectedTokenType){
+		printNextToken(expectedTokenType, false);
+	}
+
+	public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny) {
+		printNextToken(expectedTokenType, considerSpaceIfAny, PRESERVE_EMPTY_LINES_KEEP_LAST_NEW_LINES_INDENTATION);
+	}
+
+	public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny, int emptyLineRules) {
+		// Set brace flag, it's useful for the scribe while preserving line breaks
+		printComment(CodeFormatter.K_UNKNOWN, NO_TRAILING_COMMENT, emptyLineRules);
+		try {
+			this.currentToken = this.scanner.getNextToken();
+			if (expectedTokenType != this.currentToken) {
+				throw new AbortFormatting("unexpected token type, expecting:"+expectedTokenType+", actual:"+this.currentToken);//$NON-NLS-1$//$NON-NLS-2$
+			}
+			print(this.scanner.currentPosition - this.scanner.startPosition, considerSpaceIfAny);
+		} catch (InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	public void printNextToken(int[] expectedTokenTypes) {
+		printNextToken(expectedTokenTypes, false);
+	}
+
+	public void printNextToken(int[] expectedTokenTypes, boolean considerSpaceIfAny){
+		printComment(CodeFormatter.K_UNKNOWN, NO_TRAILING_COMMENT);
+		try {
+			this.currentToken = this.scanner.getNextToken();
+			if (Arrays.binarySearch(expectedTokenTypes, this.currentToken) < 0) {
+				StringBuffer expectations = new StringBuffer(5);
+				for (int i = 0; i < expectedTokenTypes.length; i++){
+					if (i > 0) {
+						expectations.append(',');
+					}
+					expectations.append(expectedTokenTypes[i]);
+				}
+				throw new AbortFormatting("unexpected token type, expecting:["+expectations.toString()+"], actual:"+this.currentToken);//$NON-NLS-1$//$NON-NLS-2$
+			}
+			print(this.scanner.currentPosition - this.scanner.startPosition, considerSpaceIfAny);
+		} catch (InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	public void printQualifiedReference(int sourceEnd, boolean expectParenthesis) {
+		int currentTokenStartPosition = this.scanner.currentPosition;
+		try {
+			do {
+				printComment(CodeFormatter.K_UNKNOWN, NO_TRAILING_COMMENT);
+				switch(this.currentToken = this.scanner.getNextToken()) {
+					case TerminalTokens.TokenNameEOF :
+						return;
+					case TerminalTokens.TokenNameWHITESPACE :
+						addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+						printBlockComment(false);
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+						printLineComment();
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameIdentifier :
+					case TerminalTokens.TokenNameDOT :
+						print(this.scanner.currentPosition - this.scanner.startPosition, false);
+						currentTokenStartPosition = this.scanner.currentPosition;
+						break;
+					case TerminalTokens.TokenNameRPAREN:
+						if (expectParenthesis) {
+							currentTokenStartPosition = this.scanner.startPosition;
+						}
+						// $FALL-THROUGH$ - fall through default case...
+					default:
+						this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+						return;
+				}
+			} while (this.scanner.currentPosition <= sourceEnd);
+		} catch(InvalidInputException e) {
+			throw new AbortFormatting(e);
+		}
+	}
+
+	private void printRule(StringBuffer stringBuffer) {
+		// only called if this.tabLength > 0
+		for (int i = 0; i < this.pageWidth; i++){
+			if ((i % this.tabLength) == 0) {
+				stringBuffer.append('+');
+			} else {
+				stringBuffer.append('-');
+			}
+		}
+		stringBuffer.append(this.lineSeparator);
+
+		for (int i = 0; i < (this.pageWidth / this.tabLength); i++) {
+			stringBuffer.append(i);
+			stringBuffer.append('\t');
+		}
+	}
+
+	void redoAlignment(AlignmentException e){
+		if (e.relativeDepth > 0) { // if exception targets a distinct context
+			e.relativeDepth--; // record fact that current context got traversed
+			this.currentAlignment = this.currentAlignment.enclosing; // pop currentLocation
+			throw e; // rethrow
+		}
+		// reset scribe/scanner to restart at this given location
+		resetAt(this.currentAlignment.location);
+		this.scanner.resetTo(this.currentAlignment.location.inputOffset, this.scanner.eofPosition - 1);
+		// clean alignment chunkKind so it will think it is a new chunk again
+		this.currentAlignment.chunkKind = 0;
+	}
+
+	void redoMemberAlignment(AlignmentException e){
+		// reset scribe/scanner to restart at this given location
+		resetAt(this.memberAlignment.location);
+		this.scanner.resetTo(this.memberAlignment.location.inputOffset, this.scanner.eofPosition - 1);
+		// clean alignment chunkKind so it will think it is a new chunk again
+		this.memberAlignment.chunkKind = 0;
+	}
+
+	public void reset() {
+		this.checkLineWrapping = true;
+		this.line = 0;
+		this.column = 1;
+		this.editsIndex = 0;
+		this.nlsTagCounter = 0;
+	}
+
+	private void resetAt(Location location) {
+		this.line = location.outputLine;
+		this.column = location.outputColumn;
+		this.indentationLevel = location.outputIndentationLevel;
+		this.numberOfIndentations = location.numberOfIndentations;
+		this.lastNumberOfNewLines = location.lastNumberOfNewLines;
+		this.needSpace = location.needSpace;
+		this.pendingSpace = location.pendingSpace;
+		this.editsIndex = location.editsIndex;
+		this.nlsTagCounter = location.nlsTagCounter;
+		if (this.editsIndex > 0) {
+			this.edits[this.editsIndex - 1] = location.textEdit;
+		}
+		this.formatter.lastLocalDeclarationSourceStart = location.lastLocalDeclarationSourceStart;
+	}
+
+	/**
+	 * @param compilationUnitSource
+	 */
+	public void resetScanner(char[] compilationUnitSource) {
+		this.scanner.setSource(compilationUnitSource);
+		this.scannerEndPosition = compilationUnitSource.length;
+		this.scanner.resetTo(0, this.scannerEndPosition - 1);
+		this.edits = new OptimizedReplaceEdit[INITIAL_SIZE];
+		this.maxLines = this.lineEnds == null ? -1 : this.lineEnds.length - 1;
+		this.scanner.lineEnds = this.lineEnds;
+		this.scanner.linePtr = this.maxLines;
+		initFormatterCommentParser();
+	}
+
+	private void resize() {
+		System.arraycopy(this.edits, 0, (this.edits = new OptimizedReplaceEdit[this.editsIndex * 2]), 0, this.editsIndex);
+	}
+
+	private void setCommentIndentation(int commentIndentationLevel) {
+		if (commentIndentationLevel == 0) {
+		    this.commentIndentation = null;
+		} else {
+			int length = COMMENT_INDENTATIONS.length;
+			if (commentIndentationLevel > length) {
+				System.arraycopy(COMMENT_INDENTATIONS, 0, COMMENT_INDENTATIONS = new String[commentIndentationLevel+10], 0, length);
+			}
+			this.commentIndentation = COMMENT_INDENTATIONS[commentIndentationLevel-1];
+			if (this.commentIndentation == null) {
+				this.tempBuffer.setLength(0);
+				for (int i=0; i<commentIndentationLevel; i++) {
+					this.tempBuffer.append(' ');
+				}
+				this.commentIndentation = this.tempBuffer.toString();
+				COMMENT_INDENTATIONS[commentIndentationLevel-1] = this.commentIndentation;
+			}
+		}
+	}
+
+	/*
+	 * Look for the tags identified by the scanner to see whether some of them
+	 * may change the status of the edition for the formatter.
+	 * Do not return as soon as a match is found, as there may have several
+	 * disabling/enabling tags in a comment, hence the last one will be the one really
+	 * changing the formatter behavior...
+	 */
+	private void setEditsEnabled(int count) {
+		for (int i=0; i<count; i++) {
+			if (this.disablingTag != null && CharOperation.equals(this.scanner.foundTaskTags[i], this.disablingTag)) {
+				this.editsEnabled = false;
+			}
+			if (this.enablingTag != null && CharOperation.equals(this.scanner.foundTaskTags[i], this.enablingTag)) {
+				this.editsEnabled = true;
+			}
+		}
+	}
+
+	void setIncludeComments(boolean on) {
+		if (on) {
+			this.formatComments |= CodeFormatter.F_INCLUDE_COMMENTS;
+		} else {
+			this.formatComments &= ~CodeFormatter.F_INCLUDE_COMMENTS;
+		}
+	}
+
+	void setHeaderComment(int position) {
+		this.headerEndPosition = position;
+	}
+
+	public void space() {
+		if (!this.needSpace) return;
+		this.lastNumberOfNewLines = 0;
+		this.pendingSpace = true;
+		this.column++;
+		this.needSpace = false;
+	}
+
+	public String toString() {
+		StringBuffer stringBuffer = new StringBuffer();
+		stringBuffer
+			.append("(page width = " + this.pageWidth + ") - (tabChar = ");//$NON-NLS-1$//$NON-NLS-2$
+		switch(this.tabChar) {
+			case DefaultCodeFormatterOptions.TAB :
+				 stringBuffer.append("TAB");//$NON-NLS-1$
+				 break;
+			case DefaultCodeFormatterOptions.SPACE :
+				 stringBuffer.append("SPACE");//$NON-NLS-1$
+				 break;
+			default :
+				 stringBuffer.append("MIXED");//$NON-NLS-1$
+		}
+		stringBuffer
+			.append(") - (tabSize = " + this.tabLength + ")")//$NON-NLS-1$//$NON-NLS-2$
+			.append(this.lineSeparator)
+			.append("(line = " + this.line + ") - (column = " + this.column + ") - (identationLevel = " + this.indentationLevel + ")")	//$NON-NLS-1$	//$NON-NLS-2$	//$NON-NLS-3$	//$NON-NLS-4$
+			.append(this.lineSeparator)
+			.append("(needSpace = " + this.needSpace + ") - (lastNumberOfNewLines = " + this.lastNumberOfNewLines + ") - (checkLineWrapping = " + this.checkLineWrapping + ")")	//$NON-NLS-1$	//$NON-NLS-2$	//$NON-NLS-3$	//$NON-NLS-4$
+			.append(this.lineSeparator)
+			.append("==================================================================================")	//$NON-NLS-1$
+			.append(this.lineSeparator);
+		if (this.tabLength > 0) {
+			printRule(stringBuffer);
+		}
+		return stringBuffer.toString();
+	}
+
+	public void unIndent() {
+		this.indentationLevel -= this.indentationSize;
+		this.numberOfIndentations--;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java
new file mode 100644
index 0000000..a7fa853
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java
@@ -0,0 +1,604 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.align;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.internal.formatter.Location;
+import org.eclipse.jdt.internal.formatter.Scribe;
+
+/**
+ * Alignment management
+ *
+ * @since 2.1
+ */
+public class Alignment {
+
+	// Kind of alignment
+	public int kind;
+	public static final int ALLOCATION = 1;
+	public static final int ANNOTATION_MEMBERS_VALUE_PAIRS = 2;
+	public static final int ARRAY_INITIALIZER = 3;
+	public static final int ASSIGNMENT = 4;
+	public static final int BINARY_EXPRESSION = 5;
+	public static final int CASCADING_MESSAGE_SEND = 6;
+	public static final int COMPACT_IF = 7;
+	public static final int COMPOUND_ASSIGNMENT = 8;
+	public static final int CONDITIONAL_EXPRESSION = 9;
+	public static final int ENUM_CONSTANTS = 10;
+	public static final int ENUM_CONSTANTS_ARGUMENTS = 11;
+	public static final int EXPLICIT_CONSTRUCTOR_CALL = 12;
+	public static final int FIELD_DECLARATION_ASSIGNMENT = 13;
+	public static final int LOCAL_DECLARATION_ASSIGNMENT = 14;
+	public static final int MESSAGE_ARGUMENTS = 15;
+	public static final int MESSAGE_SEND = 16;
+	public static final int METHOD_ARGUMENTS = 17;
+	public static final int METHOD_DECLARATION = 18;
+	public static final int MULTIPLE_FIELD = 19;
+	public static final int SUPER_CLASS = 20;
+	public static final int SUPER_INTERFACES = 21;
+	public static final int THROWS = 22;
+	public static final int TYPE_MEMBERS = 23;
+	public static final int STRING_CONCATENATION = 24;
+	public static final int TRY_RESOURCES = 25;
+	public static final int MULTI_CATCH = 26;
+
+	// name of alignment
+	public String name;
+	public static final String[] NAMES = {
+		"", //$NON-NLS-1$
+		"allocation", //$NON-NLS-1$
+		"annotationMemberValuePairs", //$NON-NLS-1$
+		"array_initializer", //$NON-NLS-1$
+		"assignmentAlignment", //$NON-NLS-1$
+		"binaryExpressionAlignment", //$NON-NLS-1$
+		"cascadingMessageSendAlignment", //$NON-NLS-1$
+		"compactIf", //$NON-NLS-1$
+		"compoundAssignmentAlignment", //$NON-NLS-1$
+		"conditionalExpression", //$NON-NLS-1$
+		"enumConstants", //$NON-NLS-1$
+		"enumConstantArguments", //$NON-NLS-1$
+		"explicit_constructor_call", //$NON-NLS-1$
+		"fieldDeclarationAssignmentAlignment", //$NON-NLS-1$
+		"localDeclarationAssignmentAlignment", //$NON-NLS-1$
+		"messageArguments", //$NON-NLS-1$
+		"messageAlignment", //$NON-NLS-1$
+		"methodArguments", //$NON-NLS-1$
+		"methodDeclaration", //$NON-NLS-1$
+		"multiple_field", //$NON-NLS-1$
+		"superclass", //$NON-NLS-1$
+		"superInterfaces", //$NON-NLS-1$
+		"throws", //$NON-NLS-1$
+		"typeMembers", //$NON-NLS-1$
+		"stringConcatenation", //$NON-NLS-1$
+		"tryResources", //$NON-NLS-1$
+		"unionTypeInMulticatch", //$NON-NLS-1$
+	};
+
+	// link to enclosing alignment
+	public Alignment enclosing;
+
+	// start location of this alignment
+	public Location location;
+
+	// indentation management
+	public int fragmentIndex;
+	public int fragmentCount;
+	public int[] fragmentIndentations;
+	public boolean needRedoColumnAlignment;
+
+	// chunk management
+	public int chunkStartIndex;
+	public int chunkKind;
+
+	// break management
+	public int originalIndentationLevel;
+	public int breakIndentationLevel;
+	public int shiftBreakIndentationLevel;
+	public int[] fragmentBreaks;
+	public boolean wasSplit;
+	public boolean blockAlign = false;
+	public boolean tooLong = false;
+
+	public Scribe scribe;
+
+	// reset
+	private boolean reset = false;
+
+	/*
+	 * Alignment modes
+	 */
+	public static final int M_FORCE = 1; // if bit set, then alignment will be non-optional (default is optional)
+	public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
+	public static final int	M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
+
+	// split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
+
+	/** foobar(#fragment1, #fragment2, <ul>
+	 *  <li>    #fragment3, #fragment4 </li>
+	 * </ul>
+	 */
+	public static final int M_COMPACT_SPLIT = 16; // fill each line with all possible fragments
+
+	/** foobar(<ul>
+	 * <li>    #fragment1, #fragment2,  </li>
+	 * <li>     #fragment3, #fragment4, </li>
+	 * </ul>
+	 */
+	public static final int M_COMPACT_FIRST_BREAK_SPLIT = 32; //  compact mode, but will first try to break before first fragment
+
+	/** foobar(<ul>
+	 * <li>     #fragment1,  </li>
+	 * <li>     #fragment2,  </li>
+	 * <li>     #fragment3 </li>
+	 * <li>     #fragment4,  </li>
+	 * </ul>
+	 */
+	public static final int M_ONE_PER_LINE_SPLIT = 32+16; // one fragment per line
+
+	/**
+	 * foobar(<ul>
+	 * <li>     #fragment1,  </li>
+	 * <li>        #fragment2,  </li>
+	 * <li>        #fragment3 </li>
+	 * <li>        #fragment4,  </li>
+	 * </ul>
+	 */
+	public static final int M_NEXT_SHIFTED_SPLIT = 64; // one fragment per line, subsequent are indented further
+
+	/** foobar(#fragment1, <ul>
+	 * <li>      #fragment2,  </li>
+	 * <li>      #fragment3 </li>
+	 * <li>      #fragment4,  </li>
+	 * </ul>
+	 */
+	public static final int M_NEXT_PER_LINE_SPLIT = 64+16; // one per line, except first fragment (if possible)
+
+	//64+32
+	//64+32+16
+
+	// mode controlling column alignments
+	/**
+	 * <table BORDER COLS=4 WIDTH="100%" >
+	 * <tr><td>#fragment1A</td>            <td>#fragment2A</td>       <td>#fragment3A</td>  <td>#very-long-fragment4A</td></tr>
+	 * <tr><td>#fragment1B</td>            <td>#long-fragment2B</td>  <td>#fragment3B</td>  <td>#fragment4B</td></tr>
+	 * <tr><td>#very-long-fragment1C</td>  <td>#fragment2C</td>       <td>#fragment3C</td>  <td>#fragment4C</td></tr>
+	 * </table>
+	 */
+	public static final int M_MULTICOLUMN = 256; // fragments are on same line, but multiple line of fragments will be aligned vertically
+
+	public static final int M_NO_ALIGNMENT = 0;
+
+	public int mode;
+
+	public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;
+
+	// alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
+	public static final int R_OUTERMOST = 1;
+	public static final int R_INNERMOST = 2;
+	public int tieBreakRule;
+	public int startingColumn = -1;
+
+	// alignment effects on a per fragment basis
+	public static final int NONE = 0;
+	public static final int BREAK = 1;
+
+	// chunk kind
+	public static final int CHUNK_FIELD = 1;
+	public static final int CHUNK_METHOD = 2;
+	public static final int CHUNK_TYPE = 3;
+	public static final int CHUNK_ENUM = 4;
+
+	// location to align and break on.
+	public Alignment(int kind, int mode, int tieBreakRule, Scribe scribe, int fragmentCount, int sourceRestart, int continuationIndent){
+
+		Assert.isTrue(kind >=ALLOCATION && kind <=MULTI_CATCH);
+		this.kind = kind;
+		this.name = NAMES[kind];
+		this.location = new Location(scribe, sourceRestart);
+		this.mode = mode;
+		this.tieBreakRule = tieBreakRule;
+		this.fragmentCount = fragmentCount;
+		this.scribe = scribe;
+		this.originalIndentationLevel = this.scribe.indentationLevel;
+		this.wasSplit = false;
+
+		// initialize the break indentation level, using modes and continuationIndentationLevel preference
+		final int indentSize = this.scribe.indentationSize;
+		int currentColumn = this.location.outputColumn;
+		if (currentColumn == 1) {
+		    currentColumn = this.location.outputIndentationLevel + 1;
+		}
+
+		if ((mode & M_INDENT_ON_COLUMN) != 0) {
+			// indent broken fragments at next indentation level, based on current column
+			this.breakIndentationLevel = this.scribe.getNextIndentationLevel(currentColumn);
+			if (this.breakIndentationLevel == this.location.outputIndentationLevel) {
+				this.breakIndentationLevel += (continuationIndent * indentSize);
+			}
+		} else if ((mode & M_INDENT_BY_ONE) != 0) {
+			// indent broken fragments exactly one level deeper than current indentation
+			this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize;
+		} else {
+			this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize;
+		}
+		this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize;
+
+		this.fragmentIndentations = new int[this.fragmentCount];
+		this.fragmentBreaks = new int[this.fragmentCount];
+
+		// check for forced alignments
+		if ((this.mode & M_FORCE) != 0) {
+			couldBreak();
+		}
+	}
+
+	public boolean checkChunkStart(int chunk, int startIndex, int sourceRestart) {
+		if (this.chunkKind != chunk) {
+			this.chunkKind = chunk;
+
+			// when redoing same chunk alignment, must not reset
+			if (startIndex != this.chunkStartIndex) {
+				this.chunkStartIndex = startIndex;
+				this.location.update(this.scribe, sourceRestart);
+				reset();
+			}
+			return true;
+		}
+		return false;
+	}
+
+	public void checkColumn() {
+		if ((this.mode & M_MULTICOLUMN) != 0 && this.fragmentCount > 0) {
+			int currentIndentation = this.scribe.getNextIndentationLevel(this.scribe.column+(this.scribe.needSpace ? 1 : 0));
+			int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex];
+			if (currentIndentation > fragmentIndentation) {
+				this.fragmentIndentations[this.fragmentIndex] =  currentIndentation;
+				if (fragmentIndentation != 0) {
+					for (int i = this.fragmentIndex+1; i < this.fragmentCount; i++) {
+						this.fragmentIndentations[i] = 0;
+					}
+					this.needRedoColumnAlignment = true;
+				}
+			}
+			// backtrack only once all fragments got checked
+			if (this.needRedoColumnAlignment && this.fragmentIndex == this.fragmentCount-1) { // alignment too small
+
+//				if (CodeFormatterVisitor.DEBUG){
+//					System.out.println("ALIGNMENT TOO SMALL");
+//					System.out.println(this);
+//				}
+				this.needRedoColumnAlignment = false;
+				int relativeDepth = 0;
+				Alignment targetAlignment = this.scribe.memberAlignment;
+				while (targetAlignment != null){
+					if (targetAlignment == this){
+						throw new AlignmentException(AlignmentException.ALIGN_TOO_SMALL, relativeDepth);
+					}
+					targetAlignment = targetAlignment.enclosing;
+					relativeDepth++;
+				}
+			}
+		}
+	}
+
+	public int depth() {
+		int depth = 0;
+		Alignment current = this.enclosing;
+		while (current != null) {
+			depth++;
+			current = current.enclosing;
+		}
+		return depth;
+	}
+	
+	/**
+	 * Returns whether the alignment can be aligned or not.
+	 * Only used for message send alignment, it currently blocks its alignment
+	 * when it's at the first nesting level of a message send. It allow to save
+	 * space on the argument broken line by reducing the number of indentations.
+	 */
+	public boolean canAlign() {
+		if (this.tooLong) {
+			return true;
+		}
+		boolean canAlign = true;
+		Alignment enclosingAlignment = this.enclosing;
+		while (enclosingAlignment != null) {
+			switch (enclosingAlignment.kind) {
+				case Alignment.ALLOCATION:
+				case Alignment.MESSAGE_ARGUMENTS:
+					// message send inside arguments, avoid to align
+					if (enclosingAlignment.isWrapped() && 
+							(enclosingAlignment.fragmentIndex > 0 || enclosingAlignment.fragmentCount < 2)) {
+						return !this.blockAlign;
+					}
+					if (enclosingAlignment.tooLong) {
+						return true;
+					}
+					canAlign = false;
+					break;
+				case Alignment.MESSAGE_SEND:
+					// multiple depth of message send, hence allow current to align
+					switch (this.kind) {
+						case Alignment.ALLOCATION:
+						case Alignment.MESSAGE_ARGUMENTS:
+						case Alignment.MESSAGE_SEND:
+							Alignment superEnclosingAlignment = enclosingAlignment.enclosing;
+							while (superEnclosingAlignment != null) {
+								switch (superEnclosingAlignment.kind) {
+									case Alignment.ALLOCATION:
+									case Alignment.MESSAGE_ARGUMENTS:
+									case Alignment.MESSAGE_SEND:
+										// block the alignment of the intermediate message send
+										if (this.scribe.nlsTagCounter == 0) {
+											enclosingAlignment.blockAlign = true;
+										}
+										return !this.blockAlign;
+								}
+								superEnclosingAlignment = superEnclosingAlignment.enclosing;
+							}
+							break;
+					}
+					return !this.blockAlign;
+			}
+			enclosingAlignment = enclosingAlignment.enclosing;
+		}
+		return canAlign && !this.blockAlign;
+	}
+
+	public boolean couldBreak(){
+		if (this.fragmentCount == 0) return false;
+		int i;
+		switch(this.mode & SPLIT_MASK){
+
+			/*  # aligned fragment
+			 *  foo(
+			 *     #AAAAA, #BBBBB,
+			 *     #CCCC);
+			 */
+			case M_COMPACT_FIRST_BREAK_SPLIT :
+				if (this.fragmentBreaks[0] == NONE) {
+					this.fragmentBreaks[0] = BREAK;
+					this.fragmentIndentations[0] = this.breakIndentationLevel;
+					return this.wasSplit = true;
+				}
+				i = this.fragmentIndex;
+				do {
+					if (this.fragmentBreaks[i] == NONE) {
+						this.fragmentBreaks[i] = BREAK;
+						this.fragmentIndentations[i] = this.breakIndentationLevel;
+						return this.wasSplit = true;
+					}
+				} while (--i >= 0);
+				break;
+			/*  # aligned fragment
+			 *  foo(#AAAAA, #BBBBB,
+			 *     #CCCC);
+			 */
+			case M_COMPACT_SPLIT :
+				i = this.fragmentIndex;
+				do {
+					if (this.fragmentBreaks[i] == NONE) {
+						this.fragmentBreaks[i] = BREAK;
+						this.fragmentIndentations[i] = this.breakIndentationLevel;
+						return this.wasSplit = true;
+					}
+				} while (--i >= 0);
+				break;
+
+			/*  # aligned fragment
+			 *  foo(
+			 *      #AAAAA,
+			 *          #BBBBB,
+			 *          #CCCC);
+			 */
+			case M_NEXT_SHIFTED_SPLIT :
+				if (this.fragmentBreaks[0] == NONE) {
+					this.fragmentBreaks[0] = BREAK;
+					this.fragmentIndentations[0] = this.breakIndentationLevel;
+					for (i = 1; i < this.fragmentCount; i++){
+						this.fragmentBreaks[i] = BREAK;
+						this.fragmentIndentations[i] = this.shiftBreakIndentationLevel;
+					}
+					return this.wasSplit = true;
+				}
+				break;
+
+			/*  # aligned fragment
+			 *  foo(
+			 *      #AAAAA,
+			 *      #BBBBB,
+			 *      #CCCC);
+			 */
+			case M_ONE_PER_LINE_SPLIT :
+				if (this.fragmentBreaks[0] == NONE) {
+					for (i = 0; i < this.fragmentCount; i++){
+						this.fragmentBreaks[i] = BREAK;
+						this.fragmentIndentations[i] = this.breakIndentationLevel;
+					}
+					return this.wasSplit = true;
+				}
+				break;
+			/*  # aligned fragment
+			 *  foo(#AAAAA,
+			 *      #BBBBB,
+			 *      #CCCC);
+			 */
+			case M_NEXT_PER_LINE_SPLIT :
+				if (this.fragmentBreaks[0] == NONE) {
+					if (this.fragmentCount > 1
+							&& this.fragmentBreaks[1] == NONE) {
+						if ((this.mode & M_INDENT_ON_COLUMN) != 0) {
+							this.fragmentIndentations[0] = this.breakIndentationLevel;
+						}
+						for (i = 1; i < this.fragmentCount; i++) {
+							this.fragmentBreaks[i] = BREAK;
+							this.fragmentIndentations[i] = this.breakIndentationLevel;
+						}
+						return this.wasSplit = true;
+					}
+				}
+				break;
+		}
+		return false; // cannot split better
+	}
+	
+	public boolean isWrapped() {
+		if (this.fragmentCount == 0) return false;
+		return this.fragmentBreaks[this.fragmentIndex] == BREAK;
+	}
+
+	public int wrappedIndex() {
+		for (int i = 0, max = this.fragmentCount; i < max; i++) {
+			if (this.fragmentBreaks[i] == BREAK) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	// perform alignment effect for current fragment
+	public void performFragmentEffect(){
+		if (this.fragmentCount == 0) return;
+		if ((this.mode & M_MULTICOLUMN) == 0) {
+			switch(this.mode & SPLIT_MASK) {
+				case Alignment.M_COMPACT_SPLIT :
+				case Alignment.M_COMPACT_FIRST_BREAK_SPLIT :
+				case Alignment.M_NEXT_PER_LINE_SPLIT :
+				case Alignment.M_NEXT_SHIFTED_SPLIT :
+				case Alignment.M_ONE_PER_LINE_SPLIT :
+					break;
+				default:
+					return;
+			}
+		}
+
+		int fragmentIndentation = this.fragmentIndentations[this.fragmentIndex];
+		if (this.startingColumn < 0 || (fragmentIndentation+1) < this.startingColumn) {
+			if (this.fragmentBreaks[this.fragmentIndex] == BREAK) {
+				this.scribe.printNewLine();
+			}
+			if (fragmentIndentation > 0) {
+				this.scribe.indentationLevel = fragmentIndentation;
+			}
+		}
+	}
+
+	// reset fragment indentation/break status
+	public void reset() {
+
+		this.wasSplit = false;
+		if (this.fragmentCount > 0){
+			this.fragmentIndentations = new int[this.fragmentCount];
+			this.fragmentBreaks = new int[this.fragmentCount];
+		}
+
+		// check for forced alignments
+		if ((this.mode & M_FORCE) != 0) {
+			couldBreak();
+		}
+		this.reset = true;
+	}
+
+	public void toFragmentsString(StringBuffer buffer){
+		// default implementation
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer(10);
+		return toString(buffer, -1);
+	}
+
+	public String toString(StringBuffer buffer, int level) {
+		
+		// Compute the indentation at the given level
+		StringBuffer indentation = new StringBuffer();
+		for (int i=0; i<level; i++) {
+			indentation.append('\t');
+		}
+		
+		// First line is for class and name
+		buffer.append(indentation);
+		buffer
+			.append("<kind: ")	//$NON-NLS-1$
+			.append(this.kind)
+			.append("> ");	//$NON-NLS-1$
+		buffer
+			.append("<name: ")	//$NON-NLS-1$
+			.append(this.name)
+			.append(">\n");	//$NON-NLS-1$
+		
+		// Line for depth and break indentation
+		buffer.append(indentation);
+		buffer
+			.append("<depth=")	//$NON-NLS-1$
+			.append(depth())
+			.append("><breakIndent=")	//$NON-NLS-1$
+			.append(this.breakIndentationLevel)
+			.append("><shiftBreakIndent=")	//$NON-NLS-1$
+			.append(this.shiftBreakIndentationLevel)
+			.append(">\n"); //$NON-NLS-1$
+
+		// Line to display the location
+		buffer.append(indentation);
+		buffer
+			.append("<location=")	//$NON-NLS-1$
+			.append(this.location.toString())
+			.append(">\n");	//$NON-NLS-1$
+
+		// Lines for fragments
+		buffer
+			.append(indentation)
+			.append("<fragments:\n");	//$NON-NLS-1$
+		for (int i = 0; i < this.fragmentCount; i++){
+			buffer
+				.append(indentation)
+				.append(" - ")	//$NON-NLS-1$
+				.append(i)
+				.append(": ")	//$NON-NLS-1$
+				.append("<break: ")	//$NON-NLS-1$
+				.append(this.fragmentBreaks[i] > 0 ? "YES" : "NO")	//$NON-NLS-1$	//$NON-NLS-2$
+				.append(">")	//$NON-NLS-1$
+				.append("<indent: ")	//$NON-NLS-1$
+				.append(this.fragmentIndentations[i])
+				.append(">\n");	//$NON-NLS-1$
+		}
+		buffer
+			.append(indentation)
+			.append(">\n"); //$NON-NLS-1$
+		
+		// Display enclosing
+		if (this.enclosing != null && level >= 0) {
+			buffer
+				.append(indentation)
+				.append("<enclosing assignement:\n");	//$NON-NLS-1$
+			this.enclosing.toString(buffer, level+1);
+			buffer
+				.append(indentation)
+				.append(">\n"); //$NON-NLS-1$
+		}
+		
+		// Return the result
+		return buffer.toString();
+	}
+
+	public void update() {
+		for (int i = 1; i < this.fragmentCount; i++){
+		    if (this.fragmentBreaks[i] == BREAK) {
+		        this.fragmentIndentations[i] = this.breakIndentationLevel;
+		    }
+		}
+	}
+
+	public boolean wasReset() {
+		return this.reset;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java
new file mode 100644
index 0000000..fea03cc
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.align;
+
+/**
+ * Exception used to backtrack and break available alignments
+ * When the exception is thrown, it is assumed that some alignment will be changed.
+ *
+ * @since 2.1
+ */
+public class AlignmentException extends RuntimeException {
+
+	public static final int LINE_TOO_LONG = 1;
+	public static final int ALIGN_TOO_SMALL = 2;
+	private static final long serialVersionUID = -3324134986466253314L; // backward compatible
+
+	int reason;
+	int value;
+	public int relativeDepth;
+
+	public AlignmentException(int reason, int relativeDepth) {
+		this(reason, 0, relativeDepth);
+	}
+
+	public AlignmentException(int reason, int value, int relativeDepth) {
+		this.reason = reason;
+		this.value = value;
+		this.relativeDepth = relativeDepth;
+	}
+
+	public String toString(){
+		StringBuffer buffer = new StringBuffer(10);
+		switch(this.reason){
+			case LINE_TOO_LONG :
+				buffer.append("LINE_TOO_LONG");	//$NON-NLS-1$
+				break;
+			case ALIGN_TOO_SMALL :
+				buffer.append("ALIGN_TOO_SMALL");	//$NON-NLS-1$
+				break;
+		}
+		buffer
+			.append("<relativeDepth: ")	//$NON-NLS-1$
+			.append(this.relativeDepth)
+			.append(">\n");	//$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java
new file mode 100644
index 0000000..217a0be
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.Map;
+
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.jdt.core.ToolFactory;
+
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Comment formatting utils.
+ *
+ * @since 3.1
+ */
+public class CommentFormatterUtil {
+
+	/**
+	 * Evaluates the edit on the given string.
+	 *
+	 * @throws IllegalArgumentException if the positions are not inside the
+	 *                 string
+	 */
+	public static String evaluateFormatterEdit(String string, TextEdit edit, Position[] positions) {
+		try {
+			Document doc= createDocument(string, positions);
+			edit.apply(doc, 0);
+			if (positions != null) {
+				for (int i= 0; i < positions.length; i++) {
+					Assert.isTrue(!positions[i].isDeleted, "Position got deleted"); //$NON-NLS-1$
+				}
+			}
+			return doc.get();
+		} catch (BadLocationException e) {
+			log(e); // bug in the formatter
+			Assert.isTrue(false, "Formatter created edits with wrong positions: " + e.getMessage()); //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	/**
+	 * Creates edits that describe how to format the given string. Returns
+	 * <code>null</code> if the code could not be formatted for the given
+	 * kind.
+	 *
+	 * @throws IllegalArgumentException if the offset and length are not
+	 *                 inside the string
+	 */
+	public static TextEdit format2(int kind, String string, int indentationLevel, String lineSeparator, Map options) {
+		int length= string.length();
+		if (0 < 0 || length < 0 || 0 + length > string.length()) {
+			throw new IllegalArgumentException("offset or length outside of string. offset: " + 0 + ", length: " + length + ", string size: " + string.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		}
+		return ToolFactory.createCodeFormatter(options).format(kind, string, 0, length, indentationLevel, lineSeparator);
+	}
+
+	/**
+	 * Returns a document with the given content and the given positions
+	 * registered with the {@link DefaultPositionUpdater}.
+	 *
+	 * @param content the content
+	 * @param positions the positions
+	 * @return the document
+	 * @throws IllegalArgumentException
+	 */
+	private static Document createDocument(String content, Position[] positions) throws IllegalArgumentException {
+		Document doc= new Document(content);
+		try {
+			if (positions != null) {
+				final String POS_CATEGORY= "myCategory"; //$NON-NLS-1$
+
+				doc.addPositionCategory(POS_CATEGORY);
+				doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
+					protected boolean notDeleted() {
+						if (this.fOffset < this.fPosition.offset && (this.fPosition.offset + this.fPosition.length < this.fOffset + this.fLength)) {
+							this.fPosition.offset= this.fOffset + this.fLength; // deleted positions: set to end of remove
+							return false;
+						}
+						return true;
+					}
+				});
+				for (int i= 0; i < positions.length; i++) {
+					try {
+						doc.addPosition(POS_CATEGORY, positions[i]);
+					} catch (BadLocationException e) {
+						throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + content.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+					}
+				}
+			}
+		} catch (BadPositionCategoryException cannotHappen) {
+			// can not happen: category is correctly set up
+		}
+		return doc;
+	}
+
+	/**
+	 * Logs the given throwable.
+	 *
+	 * @param t the throwable
+	 * @since 3.1
+	 */
+	public static void log(Throwable t) {
+		Util.log(t, "Exception occured while formatting comments"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java
new file mode 100644
index 0000000..71f93f5
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Matt McCutchen - fix for bug 198153
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * <code>SubstitutionTextReader</code> that will substitute plain text values
+ * for html entities encountered in the original text. Line breaks and
+ * whitespace are preserved.
+ *
+ * @since 3.0
+ */
+public class HTMLEntity2JavaReader extends SubstitutionTextReader {
+
+	/** The hard-coded entity map. */
+	private static final Map fgEntityLookup;
+
+	static {
+		fgEntityLookup= new HashMap(7);
+		fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$
+		fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Creates a new instance that will read from <code>reader</code>
+	 *
+	 * @param reader the source reader
+	 */
+	public HTMLEntity2JavaReader(Reader reader) {
+		super(reader);
+		setSkipWhitespace(false);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+	 */
+	protected String computeSubstitution(int c) throws IOException {
+		if (c == '&')
+			return processEntity();
+		return null;
+	}
+
+	/**
+	 * Replaces an HTML entity body (without &amp; and ;) with its
+	 * plain/text (or plain/java) counterpart.
+	 *
+	 * @param symbol the entity body to resolve
+	 * @return the plain/text counterpart of <code>symbol</code>
+	 */
+	protected String entity2Text(String symbol) {
+		if (symbol.length() > 1 && symbol.charAt(0) == '#') {
+			int ch;
+			try {
+				if (symbol.charAt(1) == 'x') {
+					ch= Integer.parseInt(symbol.substring(2), 16);
+				} else {
+					ch= Integer.parseInt(symbol.substring(1), 10);
+				}
+				return String.valueOf((char) ch);
+			} catch (NumberFormatException e) {
+				// ignore
+			}
+		} else {
+			String str= (String) fgEntityLookup.get(symbol);
+			if (str != null) {
+				return str;
+			}
+		}
+		return "&" + symbol; // not found //$NON-NLS-1$
+	}
+
+	/**
+	 * Reads an HTML entity from the stream and returns its plain/text
+	 * counterpart.
+	 *
+	 * @return an entity read from the stream, or the stream content.
+	 * @throws IOException if the underlying reader throws one
+	 */
+	private String processEntity() throws IOException {
+		StringBuffer buf= new StringBuffer();
+		int ch= nextChar();
+		while (ScannerHelper.isLetterOrDigit((char) ch) || ch == '#') {
+			buf.append((char) ch);
+			ch= nextChar();
+		}
+		if (ch == ';')
+			return entity2Text(buf.toString());
+		buf.insert(0, '&');
+		if (ch != -1)
+			buf.append((char) ch);
+		return buf.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java
new file mode 100644
index 0000000..8a9afd4
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Javadoc tag constants.
+ *
+ * @since 3.0
+ */
+public interface IJavaDocTagConstants {
+
+	/** Javadoc single break tag */
+	public static final char[][] JAVADOC_SINGLE_BREAK_TAG= new char[][] { "br".toCharArray() }; //$NON-NLS-1$
+
+	/** Javadoc code tags */
+	public static final char[][] JAVADOC_CODE_TAGS= new char[][] { "pre".toCharArray() }; //$NON-NLS-1$
+
+	/** Javadoc break tags */
+	public static final char[][] JAVADOC_BREAK_TAGS = new char[][] {
+		"dd".toCharArray(), //$NON-NLS-1$
+		"dt".toCharArray(), //$NON-NLS-1$
+		"li".toCharArray(), //$NON-NLS-1$
+		"td".toCharArray(), //$NON-NLS-1$
+		"th".toCharArray(), //$NON-NLS-1$
+		"h1".toCharArray(), //$NON-NLS-1$
+		"h2".toCharArray(), //$NON-NLS-1$
+		"h3".toCharArray(), //$NON-NLS-1$
+		"h4".toCharArray(), //$NON-NLS-1$
+		"h5".toCharArray(), //$NON-NLS-1$
+		"h6".toCharArray(), //$NON-NLS-1$
+		"q".toCharArray() //$NON-NLS-1$
+	};
+
+	/** Javadoc immutable tags */
+	public static final char[][] JAVADOC_IMMUTABLE_TAGS= new char[][] {
+			"code".toCharArray(), //$NON-NLS-1$
+			"em".toCharArray(), //$NON-NLS-1$
+			"pre".toCharArray(), //$NON-NLS-1$
+			"q".toCharArray(), //$NON-NLS-1$
+			"tt".toCharArray() //$NON-NLS-1$
+	};
+
+	/** Javadoc new line tags */
+	public static final char[][] JAVADOC_NEWLINE_TAGS= new char[][] {
+			"dd".toCharArray(), //$NON-NLS-1$
+			"dt".toCharArray(), //$NON-NLS-1$
+			"li".toCharArray(), //$NON-NLS-1$
+			"td".toCharArray(), //$NON-NLS-1$
+			"th".toCharArray(), //$NON-NLS-1$
+			"tr".toCharArray(), //$NON-NLS-1$
+			"h1".toCharArray(), //$NON-NLS-1$
+			"h2".toCharArray(), //$NON-NLS-1$
+			"h3".toCharArray(), //$NON-NLS-1$
+			"h4".toCharArray(), //$NON-NLS-1$
+			"h5".toCharArray(), //$NON-NLS-1$
+			"h6".toCharArray(), //$NON-NLS-1$
+			"q".toCharArray() //$NON-NLS-1$
+	};
+
+	/** Javadoc parameter tags */
+	// TODO (frederic) should have another name than 'param' for the following tags
+	// TODO (frederic) investigate how and why this list was created
+	public static final char[][] JAVADOC_PARAM_TAGS= new char[][] {
+			"@exception".toCharArray(), //$NON-NLS-1$
+			"@param".toCharArray(), //$NON-NLS-1$
+			"@serialField".toCharArray(), //$NON-NLS-1$
+			"@throws".toCharArray() //$NON-NLS-1$
+	};
+
+	/** Javadoc separator tags */
+	public static final char[][] JAVADOC_SEPARATOR_TAGS= new char[][] {
+			"dl".toCharArray(), //$NON-NLS-1$
+			"hr".toCharArray(), //$NON-NLS-1$
+			"nl".toCharArray(), //$NON-NLS-1$
+			"p".toCharArray(), //$NON-NLS-1$
+			"pre".toCharArray(), //$NON-NLS-1$
+			"ul".toCharArray(), //$NON-NLS-1$
+			"ol".toCharArray(), //$NON-NLS-1$
+			"table".toCharArray(), //$NON-NLS-1$
+			"tr".toCharArray(), //$NON-NLS-1$
+	};
+
+	/** Javadoc tag prefix */
+	public static final char JAVADOC_TAG_PREFIX= '@';
+
+	/** Link tag postfix */
+	public static final char LINK_TAG_POSTFIX= '}';
+
+	/** Link tag prefix */
+	public static final String LINK_TAG_PREFIX_STRING = "{@"; //$NON-NLS-1$
+
+	public static final char[] LINK_TAG_PREFIX= LINK_TAG_PREFIX_STRING.toCharArray();
+
+
+	/** Comment root tags */
+	public static final char[][] COMMENT_ROOT_TAGS= new char[][] {
+			"@deprecated".toCharArray(), //$NON-NLS-1$
+			"@see".toCharArray(), //$NON-NLS-1$
+			"@since".toCharArray(), //$NON-NLS-1$
+			"@version".toCharArray() //$NON-NLS-1$
+	};
+
+	/** Tag prefix of comment tags */
+	public static final char COMMENT_TAG_PREFIX= '@';
+
+	/** BLOCK COMMENTS */
+	public static final String BLOCK_HEADER = "/*"; //$NON-NLS-1$
+	public static final int BLOCK_HEADER_LENGTH = BLOCK_HEADER.length();
+	public static final String JAVADOC_HEADER = "/**"; //$NON-NLS-1$
+	public static final int JAVADOC_HEADER_LENGTH = JAVADOC_HEADER.length();
+	public static final String BLOCK_LINE_PREFIX = " * "; //$NON-NLS-1$
+	public static final int BLOCK_LINE_PREFIX_LENGTH = BLOCK_LINE_PREFIX.length();
+	public static final String BLOCK_FOOTER = "*/"; //$NON-NLS-1$
+	public static final int BLOCK_FOOTER_LENGTH = BLOCK_FOOTER.length();
+
+	/** LINE COMMENTS */
+	public static final String LINE_COMMENT_PREFIX = "// "; //$NON-NLS-1$
+	public static final int LINE_COMMENT_PREFIX_LENGTH = LINE_COMMENT_PREFIX.length();
+
+	/** JAVADOC STAR */
+	public static final String JAVADOC_STAR = "*"; //$NON-NLS-1$
+
+	/*
+	 *  Tags IDs
+	 */
+	static final int JAVADOC_TAGS_INDEX_MASK = 0xFFFF;
+	static final int JAVADOC_TAGS_ID_MASK = 0xFF00;
+	static final int JAVADOC_SINGLE_BREAK_TAG_ID = 0x100;
+	static final int JAVADOC_CODE_TAGS_ID = 0x200;
+	static final int JAVADOC_BREAK_TAGS_ID = 0x400;
+	static final int JAVADOC_IMMUTABLE_TAGS_ID = 0x800;
+	static final int JAVADOC_SEPARATOR_TAGS_ID = 0x1000;
+	static final int JAVADOC_SINGLE_TAGS_ID = JAVADOC_SINGLE_BREAK_TAG_ID; // ID max for tags ID with no opening/closing (e.g. <bla>....</bla>)
+	static final int JAVADOC_CLOSED_TAG = 0x10000;
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java
new file mode 100644
index 0000000..55094da
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Matt McCutchen - fix for bug 197169 and complementary fix for 109636
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.parser.*;
+
+/**
+ * <code>SubstitutionTextReader</code> that will substitute html entities for
+ * html symbols encountered in the original text. Line breaks and whitespaces
+ * are preserved.
+ *
+ * @since 3.0
+ */
+public class Java2HTMLEntityReader extends SubstitutionTextReader {
+
+	private static final int BEGIN_LINE = 0x01;
+
+	/** The hardcoded entity map. */
+	private static final Map fgEntityLookup;
+
+	/**
+	 * True if we have not yet seen a non-whitespace character on the current
+	 * line.
+	 */
+	private int bits = BEGIN_LINE;
+
+	static {
+		fgEntityLookup= new HashMap(7);
+		fgEntityLookup.put("<", "&lt;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put(">", "&gt;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("&", "&amp;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("^", "&circ;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("~", "&tilde;"); //$NON-NLS-2$ //$NON-NLS-1$
+		fgEntityLookup.put("\"", "&quot;"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Creates a new instance that will read from <code>reader</code>
+	 *
+	 * @param reader the source reader
+	 */
+	public Java2HTMLEntityReader(Reader reader) {
+		super(reader);
+		setSkipWhitespace(false);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+	 */
+	protected String computeSubstitution(int c) throws IOException {
+		StringBuffer buf = new StringBuffer();
+		// Accumulate *s into the buffer until we see something other than *.
+		while (c == '*') {
+			this.bits &= ~BEGIN_LINE;
+			c = nextChar();
+			buf.append('*');
+		}
+		if (c == -1)
+			// Snippet must have ended with *s.  Just return them.
+			return buf.toString();
+		if (c == '/' && buf.length() > 0) {
+			/*
+			 * Translate a * that precedes a / to &#42; so it isn't
+			 * misinterpreted as the end of the Javadoc comment that contains
+			 * the code we are formatting.
+			 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=109636
+			 */
+			buf.setLength(buf.length() - 1);
+			buf.append("&#42;/"); //$NON-NLS-1$
+		} else if (c == '@' && (this.bits & BEGIN_LINE) != 0) {
+			/*
+			 * When @ is first on a line, translate it to &#064; so it isn't
+			 * misinterpreted as a Javadoc tag.
+			 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=197169
+			 */
+			buf.append("&#064;"); //$NON-NLS-1$
+		} else {
+			/*
+			 * Ordinary processing.  If the character needs an entity in HTML,
+			 * add the entity, otherwise add the character.
+			 */
+			String entity = (String) fgEntityLookup.get(String.valueOf((char) c));
+			if (entity != null)
+				buf.append(entity);
+			else
+				buf.append((char) c);
+		}
+		// Update bits for the benefit of the next character.
+		if (c == '\n' || c == '\r') {
+			this.bits |= BEGIN_LINE;
+		} else if (!ScannerHelper.isWhitespace((char) c)) {
+			this.bits &= ~BEGIN_LINE;
+		}
+		return buf.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java
new file mode 100644
index 0000000..c049ef6
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Matt McCutchen - add check for EOF handling
+ ******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * Reads the text contents from a reader and computes for each character
+ * a potential substitution. The substitution may eat more characters than
+ * only the one passed into the computation routine.
+ */
+public abstract class SubstitutionTextReader extends Reader {
+
+	private Reader fReader;
+	private boolean fWasWhiteSpace;
+	private int fCharAfterWhiteSpace;
+
+	/**
+	 * Tells whether white space characters are skipped.
+	 */
+	private boolean fSkipWhiteSpace= true;
+
+	private boolean fReadFromBuffer;
+	private StringBuffer fBuffer;
+	private int fIndex;
+
+
+	protected SubstitutionTextReader(Reader reader) {
+		this.fReader= reader;
+		this.fBuffer= new StringBuffer();
+		this.fIndex= 0;
+		this.fReadFromBuffer= false;
+		this.fCharAfterWhiteSpace= -1;
+		this.fWasWhiteSpace= true;
+	}
+
+	/**
+	 * Gets the content as a String
+	 */
+	public String getString() throws IOException {
+		StringBuffer buf= new StringBuffer();
+		int ch;
+		while ((ch= read()) != -1) {
+			buf.append((char)ch);
+		}
+		return buf.toString();
+	}
+
+	/**
+	 * Implement to compute the substitution for the given character and
+	 * if necessary subsequent characters. Use <code>nextChar</code>
+	 * to read subsequent characters.
+	 */
+	protected abstract String computeSubstitution(int c) throws IOException;
+
+	/**
+	 * Returns the internal reader.
+	 */
+	protected Reader getReader() {
+		return this.fReader;
+	}
+
+	/**
+	 * Returns the next character.
+	 */
+	protected int nextChar() throws IOException {
+		this.fReadFromBuffer= (this.fBuffer.length() > 0);
+		if (this.fReadFromBuffer) {
+			char ch= this.fBuffer.charAt(this.fIndex++);
+			if (this.fIndex >= this.fBuffer.length()) {
+				this.fBuffer.setLength(0);
+				this.fIndex= 0;
+			}
+			return ch;
+		} else {
+			int ch= this.fCharAfterWhiteSpace;
+			if (ch == -1) {
+				ch= this.fReader.read();
+			}
+			if (this.fSkipWhiteSpace && ScannerHelper.isWhitespace((char)ch)) {
+				do {
+					ch= this.fReader.read();
+				} while (ScannerHelper.isWhitespace((char)ch));
+				if (ch != -1) {
+					this.fCharAfterWhiteSpace= ch;
+					return ' ';
+				}
+			} else {
+				this.fCharAfterWhiteSpace= -1;
+			}
+			return ch;
+		}
+	}
+
+	/*
+	 * @see Reader#read()
+	 */
+	public int read() throws IOException {
+		int c;
+		do {
+
+			c= nextChar();
+			while (!this.fReadFromBuffer && c != -1) {
+				String s= computeSubstitution(c);
+				if (s == null)
+					break;
+				if (s.length() > 0)
+					this.fBuffer.insert(0, s);
+				c= nextChar();
+			}
+
+		} while (this.fSkipWhiteSpace && this.fWasWhiteSpace && (c == ' '));
+		this.fWasWhiteSpace= (c == ' ' || c == '\r' || c == '\n');
+		return c;
+	}
+
+	/*
+	 * @see Reader#read(char[],int,int)
+	 */
+	public int read(char cbuf[], int off, int len) throws IOException {
+		int end= off + len;
+		for (int i= off; i < end; i++) {
+			int ch= read();
+			if (ch == -1) {
+				if (i == off) {
+					return -1;
+				} else {
+					return i - off;
+				}
+			}
+			cbuf[i]= (char)ch;
+		}
+		return len;
+	}
+
+	/*
+	 * @see java.io.Reader#ready()
+	 */
+	public boolean ready() throws IOException {
+		return this.fReader.ready();
+	}
+
+	/*
+	 * @see Reader#close()
+	 */
+	public void close() throws IOException {
+		this.fReader.close();
+	}
+
+	/*
+	 * @see Reader#reset()
+	 */
+	public void reset() throws IOException {
+		this.fReader.reset();
+		this.fWasWhiteSpace= true;
+		this.fCharAfterWhiteSpace= -1;
+		this.fBuffer.setLength(0);
+		this.fIndex= 0;
+	}
+
+	protected final void setSkipWhitespace(boolean state) {
+		this.fSkipWhiteSpace= state;
+	}
+
+	protected final boolean isSkippingWhitespace() {
+		return this.fSkipWhiteSpace;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html
new file mode 100644
index 0000000..d2210a7
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html
@@ -0,0 +1,46 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides facilities to format comments in Java source code.
+<h2>
+Package Specification</h2>
+This package provides interfaces and implementations for three kinds of comment types used in 
+Java source code:
+<ul>
+<li>Javadoc comments</li>
+<li>Multi-line comments</li>
+<li>Single-line comments</li>
+</ul>
+<h3>
+Comment Formatting</h3>
+Comment regions form the principle access point to the formatting of comments. To create a comment 
+region for a specified comment type, the factory method 
+<tt>CommentObjectFactory#createRegion(IDocument, TypedPosition, String, Map, StyledText)</tt> 
+should be used.<p>
+The formatting process is then launch by calling <tt>CommentRegion#format(String)</tt>, where 
+the argument denotes the desired indentation. This method returns a textedit representing the changes that where made during 
+the formatting process. The document for which the comment region was created is therefore guaranteed 
+to remain unchanged.<p>
+Internally, the comment region is first cast into comment lines to form the basis of the following scan step: 
+Each comment line is scanned for valid prefixes and tokenized afterwards. This tokenize step yields a stream of 
+tokens called comment ranges that are then marked with attributes representing information about the kind of 
+token associated with that comment range.<p>
+Once the comment ranges have enough attributed information, the comment region wraps the comment ranges at 
+the line margin boundary. This is coordinated by a set of rules that can be contributed to a certain type of comment 
+region. At this point of time, the comment range stream already represents the formatted comment region. The last 
+step therefore is to record the edits and to construct the resulting text edit, which describes all the changes that were 
+made to the comment region.
+<br>
+Note that the changes are not directly applied to the document. Clients are responsible for applying the textedit 
+and updating and preserving the document structure.
+<p>
+All the objects used during comment formatting should not directly be instantiated, but 
+rather retrieved from the factory <tt>CommentObjectFactory</tt>. This factory ensures 
+that the right kind of regions and lines are returned for a specific comment type.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
new file mode 100644
index 0000000..6f2c511
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.old;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
+import org.eclipse.text.edits.ReplaceEdit;
+import org.eclipse.text.edits.TextEdit;
+
+/** <h2>How to format a piece of code ?</h2>
+ * <ul><li>Create an instance of <code>CodeFormatter</code>
+ * <li>Use the method <code>void format(aString)</code>
+ * on this instance to format <code>aString</code>.
+ * It will return the formatted string.</ul>
+ * @deprecated
+*/
+public class CodeFormatter implements TerminalTokens, org.eclipse.jdt.core.ICodeFormatter {
+
+	private Map options;
+
+	public CodeFormatter(Map options) {
+		if (options == null) {
+			this.options = JavaCore.getOptions();
+		} else {
+			this.options = options;
+		}
+	}
+
+	public String format(String string, int indentLevel, int[] positions, String lineSeparator) {
+		// initialize the new formatter with old options
+		Map newOptions = DefaultCodeFormatterConstants.getEclipse21Settings();
+
+		Object formatterNewLineOpeningBrace = this.options.get(JavaCore.FORMATTER_NEWLINE_OPENING_BRACE);
+		if (formatterNewLineOpeningBrace != null) {
+			if (JavaCore.INSERT.equals(formatterNewLineOpeningBrace)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION, DefaultCodeFormatterConstants.NEXT_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, DefaultCodeFormatterConstants.NEXT_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION, DefaultCodeFormatterConstants.NEXT_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION, DefaultCodeFormatterConstants.NEXT_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH, DefaultCodeFormatterConstants.NEXT_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION, DefaultCodeFormatterConstants.NEXT_LINE);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION, DefaultCodeFormatterConstants.END_OF_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, DefaultCodeFormatterConstants.END_OF_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION, DefaultCodeFormatterConstants.END_OF_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION, DefaultCodeFormatterConstants.END_OF_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH, DefaultCodeFormatterConstants.END_OF_LINE);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION, DefaultCodeFormatterConstants.END_OF_LINE);
+			}
+		}
+		Object formatterNewLineControl = this.options.get(JavaCore.FORMATTER_NEWLINE_CONTROL);
+		if (formatterNewLineControl != null) {
+			if (JavaCore.INSERT.equals(formatterNewLineControl)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, JavaCore.INSERT);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, JavaCore.DO_NOT_INSERT);
+			}
+		}
+		Object formatterClearBlankLines = this.options.get(JavaCore.FORMATTER_CLEAR_BLANK_LINES);
+		if (formatterClearBlankLines != null) {
+			if (JavaCore.PRESERVE_ONE.equals(formatterClearBlankLines)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "1"); //$NON-NLS-1$
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "0"); //$NON-NLS-1$
+			}
+		}
+		Object formatterNewLineElseIf = this.options.get(JavaCore.FORMATTER_NEWLINE_ELSE_IF);
+		if (formatterNewLineElseIf != null) {
+			if (JavaCore.INSERT.equals(formatterNewLineElseIf)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF, DefaultCodeFormatterConstants.FALSE);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF, DefaultCodeFormatterConstants.TRUE);
+			}
+		}
+		Object formatterNewLineEmptyBlock = this.options.get(JavaCore.FORMATTER_NEWLINE_EMPTY_BLOCK);
+		if (formatterNewLineEmptyBlock != null) {
+			if (JavaCore.INSERT.equals(formatterNewLineEmptyBlock)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.DO_NOT_INSERT);
+			}
+		}
+		Object formatterCompactAssignment = this.options.get(JavaCore.FORMATTER_COMPACT_ASSIGNMENT);
+		if (formatterCompactAssignment != null) {
+			if (JavaCore.COMPACT.equals(formatterCompactAssignment)) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, JavaCore.DO_NOT_INSERT);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, JavaCore.INSERT);
+			}
+		}
+		if (this.options.get(JavaCore.FORMATTER_SPACE_CASTEXPRESSION) != null) {
+			if (JavaCore.INSERT.equals(this.options.get(JavaCore.FORMATTER_SPACE_CASTEXPRESSION))) {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST, JavaCore.INSERT);
+			} else {
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST, JavaCore.DO_NOT_INSERT);
+			}
+		}
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, this.options.get(JavaCore.FORMATTER_TAB_CHAR));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, this.options.get(JavaCore.FORMATTER_TAB_SIZE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, this.options.get(JavaCore.FORMATTER_LINE_SPLIT));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER, DefaultCodeFormatterConstants.END_OF_LINE);
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, "1");//$NON-NLS-1$
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, DefaultCodeFormatterConstants.createAlignmentValue(false, DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE, DefaultCodeFormatterConstants.INDENT_BY_ONE));
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ARRAY_INITIALIZER, JavaCore.INSERT);
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER, JavaCore.INSERT);
+		newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACE_IN_ARRAY_INITIALIZER, JavaCore.INSERT);
+
+		DefaultCodeFormatter defaultCodeFormatter = new DefaultCodeFormatter(newOptions);
+		TextEdit textEdit = defaultCodeFormatter.format(org.eclipse.jdt.core.formatter.CodeFormatter.K_UNKNOWN, string, 0, string.length(), indentLevel, lineSeparator);
+		if (positions != null && textEdit != null) {
+			// update positions
+			TextEdit[] edits = textEdit.getChildren();
+			int textEditSize = edits.length;
+			int editsIndex = 0;
+			int delta = 0;
+			int originalSourceLength = string.length() - 1;
+			if (textEditSize != 0) {
+				for (int i = 0, max = positions.length; i < max; i++) {
+					int currentPosition = positions[i];
+					if (currentPosition > originalSourceLength) {
+						currentPosition = originalSourceLength;
+					}
+					ReplaceEdit currentEdit = (ReplaceEdit) edits[editsIndex];
+					while (currentEdit.getOffset() <= currentPosition) {
+						delta += currentEdit.getText().length() - currentEdit.getLength();
+						editsIndex++;
+						if (editsIndex < textEditSize) {
+							currentEdit = (ReplaceEdit) edits[editsIndex];
+						} else {
+							break;
+						}
+					}
+					positions[i] = currentPosition + delta;
+				}
+			}
+		}
+		return org.eclipse.jdt.internal.core.util.Util.editedString(string, textEdit);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties
new file mode 100644
index 0000000..40f9549
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties
@@ -0,0 +1,75 @@
+###############################################################################
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+newline.openingBrace.number=1
+newline.openingBrace.category=Newline
+newline.openingBrace.name=I&nsert new line before opening brace
+newline.openingBrace.possibleValues=2|Insert|Do not insert
+newline.openingBrace.description=When Insert, a new line is inserted before an opening brace, otherwise nothing is inserted
+
+newline.controlStatement.number=2
+newline.controlStatement.category=Newline
+newline.controlStatement.name=Insert new &line in control statement
+newline.controlStatement.possibleValues=2|Insert|Do not insert
+newline.controlStatement.description=When Insert, a new line is inserted between } and else, catch, finally
+
+newline.clearAll.number=3
+newline.clearAll.category=Newline
+newline.clearAll.name=Clear all &blank lines
+newline.clearAll.possibleValues=2|Clear|Preserve one
+newline.clearAll.description=When Clear, all blank lines are removed. When Preserve one, only one is kept and all others removed.
+
+newline.elseIf.number=4
+newline.elseIf.category=Newline
+newline.elseIf.name=&Keep else if on the same line
+newline.elseIf.possibleValues=2|Yes|No
+newline.elseIf.description=When Yes, a blank line is inserted between a else and a if when they are contiguous
+
+newline.emptyBlock.number=5
+newline.emptyBlock.category=Newline
+newline.emptyBlock.name=In&sert a new line inside an empty block
+newline.emptyBlock.possibleValues=2|Insert|Do not insert
+newline.emptyBlock.description=When insert, a line break is inserted between contiguous { and }, if } is not followed by a keyword.
+
+line.split.number=6
+line.split.category=Line splitting
+line.split.name=Ma&ximum line length
+line.split.possibleValues=-1
+line.split.description=Enable splitting of long lines (exceeding the configurable length). Length of 0 will disable line splitting
+
+style.compactAssignment.number=7
+style.compactAssignment.category=Style
+style.compactAssignment.name=&Compact assignment
+style.compactAssignment.possibleValues=2|Compact|Normal
+style.compactAssignment.description=Assignments can be formatted asymmetrically, e.g. 'int x= 2;', when Normal, a space is inserted before the assignment operator
+
+style.reuseExistingLayout.number=8
+style.reuseExistingLayout.category=Style
+style.reuseExistingLayout.name=&Reuse existing layout
+style.reuseExistingLayout.possibleValues=2|Reuse|Do not reuse
+style.reuseExistingLayout.description=If the user has formatted his code a certain way, the formatter does not try to reformat it
+
+tabulation.char.number=9
+tabulation.char.category=Style
+tabulation.char.name=Indentation is represented by &tab
+tabulation.char.possibleValues=2|Tab|Spaces
+tabulation.char.description=Either choose to indent with tab characters or spaces
+
+tabulation.size.number=10
+tabulation.size.category=Style
+tabulation.size.name=&Amount of spaces representing a tab
+tabulation.size.possibleValues=-1
+tabulation.size.description=Tabulation size in term of space characters
+
+space.castexpression.number=11
+space.castexpression.category=Style
+space.castexpression.name=&Insert a space in cast expression
+space.castexpression.size.possibleValues=2|Insert|Do not insert
+space.castexpression.description=When insert, a space is added between the closing parenthesis and the expression of the cast expression
diff --git a/org.eclipse.jdt.core/grammar/java.g b/org.eclipse.jdt.core/grammar/java.g
new file mode 100644
index 0000000..718c3d9
--- /dev/null
+++ b/org.eclipse.jdt.core/grammar/java.g
@@ -0,0 +1,2671 @@
+--main options
+%options ACTION, AN=JavaAction.java, GP=java, 
+%options FILE-PREFIX=java, ESCAPE=$, PREFIX=TokenName, OUTPUT-SIZE=125 ,
+%options NOGOTO-DEFAULT, SINGLE-PRODUCTIONS, LALR=1 , TABLE, 
+
+--error recovering options.....
+%options ERROR_MAPS 
+
+--grammar understanding options
+%options first follow
+%options TRACE=FULL ,
+%options VERBOSE
+
+%options DEFERRED
+%options NAMES=MAX
+%options SCOPES
+
+--Usefull macros helping reading/writing semantic actions
+$Define 
+$putCase 
+/.    case $rule_number : if (DEBUG) { System.out.println("$rule_text"); }  //$NON-NLS-1$
+		   ./
+
+$break
+/. 
+			break;
+./
+
+
+$readableName 
+/.1#$rule_number#./
+$compliance
+/.2#$rule_number#./
+$recovery
+/.2#$rule_number# recovery./
+$recovery_template
+/.3#$rule_number#./
+$no_statements_recovery
+/.4#$rule_number# 1./
+-- here it starts really ------------------------------------------
+$Terminals
+
+	Identifier
+
+	abstract assert boolean break byte case catch char class 
+	continue const default do double else enum extends false final finally float
+	for goto if implements import instanceof int
+	interface long native new null package private
+	protected public return short static strictfp super switch
+	synchronized this throw throws transient true try void
+	volatile while
+
+	IntegerLiteral
+	LongLiteral
+	FloatingPointLiteral
+	DoubleLiteral
+	CharacterLiteral
+	StringLiteral
+
+	PLUS_PLUS
+	MINUS_MINUS
+	EQUAL_EQUAL
+	LESS_EQUAL
+	GREATER_EQUAL
+	NOT_EQUAL
+	LEFT_SHIFT
+	RIGHT_SHIFT
+	UNSIGNED_RIGHT_SHIFT
+	PLUS_EQUAL
+	MINUS_EQUAL
+	MULTIPLY_EQUAL
+	DIVIDE_EQUAL
+	AND_EQUAL
+	OR_EQUAL
+	XOR_EQUAL
+	REMAINDER_EQUAL
+	LEFT_SHIFT_EQUAL
+	RIGHT_SHIFT_EQUAL
+	UNSIGNED_RIGHT_SHIFT_EQUAL
+	OR_OR
+	AND_AND
+	PLUS
+	MINUS
+	NOT
+	REMAINDER
+	XOR
+	AND
+	MULTIPLY
+	OR
+	TWIDDLE
+	DIVIDE
+	GREATER
+	LESS
+	LPAREN
+	RPAREN
+	LBRACE
+	RBRACE
+	LBRACKET
+	RBRACKET
+	SEMICOLON
+	QUESTION
+	COLON
+	COMMA
+	DOT
+	EQUAL
+	AT
+	ELLIPSIS
+	ARROW
+	COLON_COLON
+	BeginLambda
+	BeginIntersectionCast
+	BeginTypeArguments
+	ElidedSemicolonAndRightBrace
+	AT308
+	AT308DOTDOTDOT
+
+--    BodyMarker
+
+$Alias
+
+	'::'   ::= COLON_COLON
+	'->'   ::= ARROW
+	'++'   ::= PLUS_PLUS
+	'--'   ::= MINUS_MINUS
+	'=='   ::= EQUAL_EQUAL
+	'<='   ::= LESS_EQUAL
+	'>='   ::= GREATER_EQUAL
+	'!='   ::= NOT_EQUAL
+	'<<'   ::= LEFT_SHIFT
+	'>>'   ::= RIGHT_SHIFT
+	'>>>'  ::= UNSIGNED_RIGHT_SHIFT
+	'+='   ::= PLUS_EQUAL
+	'-='   ::= MINUS_EQUAL
+	'*='   ::= MULTIPLY_EQUAL
+	'/='   ::= DIVIDE_EQUAL
+	'&='   ::= AND_EQUAL
+	'|='   ::= OR_EQUAL
+	'^='   ::= XOR_EQUAL
+	'%='   ::= REMAINDER_EQUAL
+	'<<='  ::= LEFT_SHIFT_EQUAL
+	'>>='  ::= RIGHT_SHIFT_EQUAL
+	'>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL
+	'||'   ::= OR_OR
+	'&&'   ::= AND_AND
+	'+'    ::= PLUS
+	'-'    ::= MINUS
+	'!'    ::= NOT
+	'%'    ::= REMAINDER
+	'^'    ::= XOR
+	'&'    ::= AND
+	'*'    ::= MULTIPLY
+	'|'    ::= OR
+	'~'    ::= TWIDDLE
+	'/'    ::= DIVIDE
+	'>'    ::= GREATER
+	'<'    ::= LESS
+	'('    ::= LPAREN
+	')'    ::= RPAREN
+	'{'    ::= LBRACE
+	'}'    ::= RBRACE
+	'['    ::= LBRACKET
+	']'    ::= RBRACKET
+	';'    ::= SEMICOLON
+	'?'    ::= QUESTION
+	':'    ::= COLON
+	','    ::= COMMA
+	'.'    ::= DOT
+	'='    ::= EQUAL
+	'@'	   ::= AT
+	'...'  ::= ELLIPSIS
+	'@308' ::= AT308
+	'@308...' ::= AT308DOTDOTDOT
+	
+$Start
+	Goal
+
+$Rules
+
+/.// This method is part of an automatic generation : do NOT edit-modify
+protected void consumeRule(int act) {
+  switch ( act ) {
+./
+
+Goal ::= '++' CompilationUnit
+Goal ::= '--' MethodBody
+-- Initializer
+Goal ::= '>>' StaticInitializer
+Goal ::= '>>' Initializer
+-- error recovery
+-- Modifiersopt is used to properly consume a header and exit the rule reduction at the end of the parse() method
+Goal ::= '>>>' Header1 Modifiersopt
+Goal ::= '!' Header2 Modifiersopt
+Goal ::= '*' BlockStatements
+Goal ::= '*' CatchHeader
+-- JDOM
+Goal ::= '&&' FieldDeclaration
+Goal ::= '||' ImportDeclaration
+Goal ::= '?' PackageDeclaration
+Goal ::= '+' TypeDeclaration
+Goal ::= '/' GenericMethodDeclaration
+Goal ::= '&' ClassBodyDeclarations
+-- code snippet
+Goal ::= '%' Expression
+Goal ::= '%' ArrayInitializer
+-- completion parser
+Goal ::= '~' BlockStatementsopt
+-- source type converter
+Goal ::= '||' MemberValue
+-- syntax diagnosis
+Goal ::= '?' AnnotationTypeMemberDeclaration
+-- JSR 335 Reconnaissance missions.
+Goal ::= '->' ParenthesizedLambdaParameterList
+Goal ::= '(' ParenthesizedCastNameAndBounds
+Goal ::= '<' ReferenceExpressionTypeArgumentsAndTrunk
+-- JSR 308 Reconnaissance mission.
+Goal ::= '@' TypeAnnotations
+/:$readableName Goal:/
+
+Literal -> IntegerLiteral
+Literal -> LongLiteral
+Literal -> FloatingPointLiteral
+Literal -> DoubleLiteral
+Literal -> CharacterLiteral
+Literal -> StringLiteral
+Literal -> null
+Literal -> BooleanLiteral
+/:$readableName Literal:/
+BooleanLiteral -> true
+BooleanLiteral -> false
+/:$readableName BooleanLiteral:/
+
+Type ::= PrimitiveType
+/.$putCase consumePrimitiveType(); $break ./
+Type -> ReferenceType
+/:$readableName Type:/
+
+PrimitiveType -> TypeAnnotationsopt NumericType
+/:$readableName PrimitiveType:/
+NumericType -> IntegralType
+NumericType -> FloatingPointType
+/:$readableName NumericType:/
+
+PrimitiveType -> TypeAnnotationsopt 'boolean'
+PrimitiveType -> TypeAnnotationsopt 'void'
+IntegralType -> 'byte'
+IntegralType -> 'short'
+IntegralType -> 'int'
+IntegralType -> 'long'
+IntegralType -> 'char'
+/:$readableName IntegralType:/
+FloatingPointType -> 'float'
+FloatingPointType -> 'double'
+/:$readableName FloatingPointType:/
+
+ReferenceType ::= ClassOrInterfaceType
+/.$putCase consumeReferenceType(); $break ./
+ReferenceType -> ArrayType
+/:$readableName ReferenceType:/
+
+---------------------------------------------------------------
+-- 1.5 feature
+---------------------------------------------------------------
+ClassOrInterfaceType -> ClassOrInterface
+ClassOrInterfaceType -> GenericType
+/:$readableName Type:/
+
+ClassOrInterface ::= Name
+/.$putCase consumeClassOrInterfaceName(); $break ./
+ClassOrInterface ::= GenericType '.' Name
+/.$putCase consumeClassOrInterface(); $break ./
+/:$readableName Type:/
+
+GenericType ::= ClassOrInterface TypeArguments
+/.$putCase consumeGenericType(); $break ./
+/:$readableName GenericType:/
+
+GenericType ::= ClassOrInterface '<' '>'
+/.$putCase consumeGenericTypeWithDiamond(); $break ./
+/:$readableName GenericType:/
+/:$compliance 1.7:/
+
+--
+-- These rules have been rewritten to avoid some conflicts introduced
+-- by adding the 1.1 features
+--
+-- ArrayType ::= PrimitiveType '[' ']'
+-- ArrayType ::= Name '[' ']'
+-- ArrayType ::= ArrayType '[' ']'
+--
+
+ArrayTypeWithTypeArgumentsName ::= GenericType '.' Name
+/.$putCase consumeArrayTypeWithTypeArgumentsName(); $break ./
+/:$readableName ArrayTypeWithTypeArgumentsName:/
+
+ArrayType ::= PrimitiveType Dims
+/.$putCase consumePrimitiveArrayType(); $break ./
+ArrayType ::= Name Dims
+/.$putCase consumeNameArrayType(); $break ./
+ArrayType ::= ArrayTypeWithTypeArgumentsName Dims
+/.$putCase consumeGenericTypeNameArrayType(); $break ./
+ArrayType ::= GenericType Dims
+/.$putCase consumeGenericTypeArrayType(); $break ./
+/:$readableName ArrayType:/
+
+ClassType -> ClassOrInterfaceType
+/:$readableName ClassType:/
+
+--------------------------------------------------------------
+--------------------------------------------------------------
+
+Name ::= SimpleName
+/.$putCase consumeZeroTypeAnnotations(); $break ./
+Name -> TypeAnnotations SimpleName
+/:$compliance 1.8:/
+Name -> QualifiedName
+/:$readableName Name:/
+/:$recovery_template Identifier:/
+
+SimpleName -> 'Identifier'
+/:$readableName SimpleName:/
+
+UnannotatableName -> SimpleName
+UnannotatableName ::= UnannotatableName '.' SimpleName
+/.$putCase consumeUnannotatableQualifiedName(); $break ./
+/:$readableName UnannotatableQualifiedName:/
+
+QualifiedName ::= Name '.' SimpleName 
+/.$putCase consumeQualifiedName(false); $break ./
+QualifiedName ::= Name '.' TypeAnnotations SimpleName 
+/.$putCase consumeQualifiedName(true); $break ./
+/:$compliance 1.8:/
+/:$readableName QualifiedName:/
+
+TypeAnnotationsopt ::= $empty
+/.$putCase consumeZeroTypeAnnotations(); $break ./
+TypeAnnotationsopt -> TypeAnnotations
+/:$compliance 1.8:/
+/:$readableName TypeAnnotationsopt:/
+
+-- Production name hardcoded in parser. Must be ::= and not -> 
+TypeAnnotations ::= TypeAnnotations0
+/:$readableName TypeAnnotations:/
+
+TypeAnnotations0 -> TypeAnnotation
+/:$compliance 1.8:/
+TypeAnnotations0 ::= TypeAnnotations0 TypeAnnotation
+/. $putCase consumeOneMoreTypeAnnotation(); $break ./
+/:$compliance 1.8:/
+/:$readableName TypeAnnotations:/
+
+TypeAnnotation ::= NormalTypeAnnotation
+/. $putCase consumeTypeAnnotation(); $break ./
+/:$compliance 1.8:/
+TypeAnnotation ::= MarkerTypeAnnotation
+/. $putCase consumeTypeAnnotation(); $break ./
+/:$compliance 1.8:/
+TypeAnnotation ::= SingleMemberTypeAnnotation
+/. $putCase consumeTypeAnnotation(); $break ./
+/:$compliance 1.8:/
+/:$readableName TypeAnnotation:/
+
+TypeAnnotationName ::= @308 UnannotatableName
+/.$putCase consumeAnnotationName() ; $break ./
+/:$readableName AnnotationName:/
+/:$compliance 1.8:/
+/:$recovery_template @ Identifier:/
+NormalTypeAnnotation ::= TypeAnnotationName '(' MemberValuePairsopt ')'
+/.$putCase consumeNormalAnnotation(true) ; $break ./
+/:$readableName NormalAnnotation:/
+/:$compliance 1.8:/
+MarkerTypeAnnotation ::= TypeAnnotationName
+/.$putCase consumeMarkerAnnotation(true) ; $break ./
+/:$readableName MarkerAnnotation:/
+/:$compliance 1.8:/
+SingleMemberTypeAnnotation ::= TypeAnnotationName '(' SingleMemberAnnotationMemberValue ')'
+/.$putCase consumeSingleMemberAnnotation(true) ; $break ./
+/:$readableName SingleMemberAnnotation:/
+/:$compliance 1.8:/
+
+RejectTypeAnnotations ::= $empty
+/.$putCase consumeNonTypeUseName(); $break ./
+/:$readableName RejectTypeAnnotations:/
+
+PushZeroTypeAnnotations ::= $empty
+/.$putCase consumeZeroTypeAnnotations(); $break ./
+/:$readableName ZeroTypeAnnotations:/
+
+VariableDeclaratorIdOrThis ::= 'this'
+/.$putCase consumeExplicitThisParameter(false); $break ./
+/:$compliance 1.8:/
+VariableDeclaratorIdOrThis ::= UnannotatableName '.' 'this'
+/.$putCase consumeExplicitThisParameter(true); $break ./
+/:$compliance 1.8:/
+VariableDeclaratorIdOrThis ::= VariableDeclaratorId
+/.$putCase consumeVariableDeclaratorIdParameter(); $break ./
+/:$readableName VariableDeclaratorId:/
+
+CompilationUnit ::= EnterCompilationUnit InternalCompilationUnit
+/.$putCase consumeCompilationUnit(); $break ./
+/:$readableName CompilationUnit:/
+
+InternalCompilationUnit ::= PackageDeclaration
+/.$putCase consumeInternalCompilationUnit(); $break ./
+InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+/.$putCase consumeInternalCompilationUnit(); $break ./
+InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+/.$putCase consumeInternalCompilationUnitWithTypes(); $break ./
+InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+/.$putCase consumeInternalCompilationUnitWithTypes(); $break ./
+InternalCompilationUnit ::= ImportDeclarations ReduceImports
+/.$putCase consumeInternalCompilationUnit(); $break ./
+InternalCompilationUnit ::= TypeDeclarations
+/.$putCase consumeInternalCompilationUnitWithTypes(); $break ./
+InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+/.$putCase consumeInternalCompilationUnitWithTypes(); $break ./
+InternalCompilationUnit ::= $empty
+/.$putCase consumeEmptyInternalCompilationUnit(); $break ./
+/:$readableName CompilationUnit:/
+
+ReduceImports ::= $empty
+/.$putCase consumeReduceImports(); $break ./
+/:$readableName ReduceImports:/
+
+EnterCompilationUnit ::= $empty
+/.$putCase consumeEnterCompilationUnit(); $break ./
+/:$readableName EnterCompilationUnit:/
+
+Header -> ImportDeclaration
+Header -> PackageDeclaration
+Header -> ClassHeader
+Header -> InterfaceHeader
+Header -> EnumHeader
+Header -> AnnotationTypeDeclarationHeader
+Header -> StaticInitializer
+Header -> RecoveryMethodHeader
+Header -> FieldDeclaration
+Header -> AllocationHeader
+Header -> ArrayCreationHeader
+/:$readableName Header:/
+
+Header1 -> Header
+Header1 -> ConstructorHeader
+/:$readableName Header1:/
+
+Header2 -> Header
+Header2 -> EnumConstantHeader
+/:$readableName Header2:/
+
+CatchHeader ::= 'catch' '(' CatchFormalParameter ')' '{'
+/.$putCase consumeCatchHeader(); $break ./
+/:$readableName CatchHeader:/
+
+ImportDeclarations -> ImportDeclaration
+ImportDeclarations ::= ImportDeclarations ImportDeclaration 
+/.$putCase consumeImportDeclarations(); $break ./
+/:$readableName ImportDeclarations:/
+
+TypeDeclarations -> TypeDeclaration
+TypeDeclarations ::= TypeDeclarations TypeDeclaration
+/.$putCase consumeTypeDeclarations(); $break ./
+/:$readableName TypeDeclarations:/
+
+PackageDeclaration ::= PackageDeclarationName ';'
+/.$putCase consumePackageDeclaration(); $break ./
+/:$readableName PackageDeclaration:/
+
+PackageDeclarationName ::= Modifiers 'package' PushRealModifiers Name RejectTypeAnnotations
+/.$putCase consumePackageDeclarationNameWithModifiers(); $break ./
+/:$readableName PackageDeclarationName:/
+/:$compliance 1.5:/
+
+PackageDeclarationName ::= PackageComment 'package' Name RejectTypeAnnotations
+/.$putCase consumePackageDeclarationName(); $break ./
+/:$readableName PackageDeclarationName:/
+
+PackageComment ::= $empty
+/.$putCase consumePackageComment(); $break ./
+/:$readableName PackageComment:/
+
+ImportDeclaration -> SingleTypeImportDeclaration
+ImportDeclaration -> TypeImportOnDemandDeclaration
+-----------------------------------------------
+-- 1.5 feature
+-----------------------------------------------
+ImportDeclaration -> SingleStaticImportDeclaration
+ImportDeclaration -> StaticImportOnDemandDeclaration
+/:$readableName ImportDeclaration:/
+
+SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
+/.$putCase consumeImportDeclaration(); $break ./
+/:$readableName SingleTypeImportDeclaration:/
+
+SingleTypeImportDeclarationName ::= 'import' Name RejectTypeAnnotations
+/.$putCase consumeSingleTypeImportDeclarationName(); $break ./
+/:$readableName SingleTypeImportDeclarationName:/
+
+TypeImportOnDemandDeclaration ::= TypeImportOnDemandDeclarationName ';'
+/.$putCase consumeImportDeclaration(); $break ./
+/:$readableName TypeImportOnDemandDeclaration:/
+
+TypeImportOnDemandDeclarationName ::= 'import' Name '.' RejectTypeAnnotations '*'
+/.$putCase consumeTypeImportOnDemandDeclarationName(); $break ./
+/:$readableName TypeImportOnDemandDeclarationName:/
+
+TypeDeclaration -> ClassDeclaration
+TypeDeclaration -> InterfaceDeclaration
+-- this declaration in part of a list od declaration and we will
+-- use and optimized list length calculation process 
+-- thus we decrement the number while it will be incremend.....
+TypeDeclaration ::= ';' 
+/. $putCase consumeEmptyTypeDeclaration(); $break ./
+-----------------------------------------------
+-- 1.5 feature
+-----------------------------------------------
+TypeDeclaration -> EnumDeclaration
+TypeDeclaration -> AnnotationTypeDeclaration
+/:$readableName TypeDeclaration:/
+
+--18.7 Only in the LALR(1) Grammar
+
+Modifiers -> Modifier
+Modifiers ::= Modifiers Modifier
+/.$putCase consumeModifiers2(); $break ./
+/:$readableName Modifiers:/
+
+Modifier -> 'public' 
+Modifier -> 'protected'
+Modifier -> 'private'
+Modifier -> 'static'
+Modifier -> 'abstract'
+Modifier -> 'final'
+Modifier -> 'native'
+Modifier -> 'synchronized'
+Modifier -> 'transient'
+Modifier -> 'volatile'
+Modifier -> 'strictfp'
+Modifier ::= Annotation
+/.$putCase consumeAnnotationAsModifier(); $break ./
+/:$readableName Modifier:/
+
+--18.8 Productions from 8: Class Declarations
+--ClassModifier ::=
+--      'abstract'
+--    | 'final'
+--    | 'public'
+--18.8.1 Productions from 8.1: Class Declarations
+
+ClassDeclaration ::= ClassHeader ClassBody
+/.$putCase consumeClassDeclaration(); $break ./
+/:$readableName ClassDeclaration:/
+
+ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
+/.$putCase consumeClassHeader(); $break ./
+/:$readableName ClassHeader:/
+
+-----------------------------------------------
+-- 1.5 features : generics
+-----------------------------------------------
+ClassHeaderName ::= ClassHeaderName1 TypeParameters
+/.$putCase consumeTypeHeaderNameWithTypeParameters(); $break ./
+
+ClassHeaderName -> ClassHeaderName1
+/:$readableName ClassHeaderName:/
+
+ClassHeaderName1 ::= Modifiersopt 'class' 'Identifier'
+/.$putCase consumeClassHeaderName1(); $break ./
+/:$readableName ClassHeaderName:/
+
+ClassHeaderExtends ::= 'extends' ClassType
+/.$putCase consumeClassHeaderExtends(); $break ./
+/:$readableName ClassHeaderExtends:/
+
+ClassHeaderImplements ::= 'implements' InterfaceTypeList
+/.$putCase consumeClassHeaderImplements(); $break ./
+/:$readableName ClassHeaderImplements:/
+
+InterfaceTypeList -> InterfaceType
+InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType
+/.$putCase consumeInterfaceTypeList(); $break ./
+/:$readableName InterfaceTypeList:/
+
+InterfaceType ::= ClassOrInterfaceType
+/.$putCase consumeInterfaceType(); $break ./
+/:$readableName InterfaceType:/
+
+ClassBody ::= '{' ClassBodyDeclarationsopt '}'
+/:$readableName ClassBody:/
+/:$no_statements_recovery:/
+
+ClassBodyDeclarations ::= ClassBodyDeclaration
+ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration
+/.$putCase consumeClassBodyDeclarations(); $break ./
+/:$readableName ClassBodyDeclarations:/
+
+ClassBodyDeclaration -> ClassMemberDeclaration
+ClassBodyDeclaration -> StaticInitializer
+ClassBodyDeclaration -> ConstructorDeclaration
+--1.1 feature
+ClassBodyDeclaration ::= Diet NestedMethod CreateInitializer Block
+/.$putCase consumeClassBodyDeclaration(); $break ./
+/:$readableName ClassBodyDeclaration:/
+
+Diet ::= $empty
+/.$putCase consumeDiet(); $break./
+/:$readableName Diet:/
+
+Initializer ::= Diet NestedMethod CreateInitializer Block
+/.$putCase consumeClassBodyDeclaration(); $break ./
+/:$readableName Initializer:/
+
+CreateInitializer ::= $empty
+/.$putCase consumeCreateInitializer(); $break./
+/:$readableName CreateInitializer:/
+
+ClassMemberDeclaration -> FieldDeclaration
+ClassMemberDeclaration -> MethodDeclaration
+--1.1 feature
+ClassMemberDeclaration -> ClassDeclaration
+--1.1 feature
+ClassMemberDeclaration -> InterfaceDeclaration
+-- 1.5 feature
+ClassMemberDeclaration -> EnumDeclaration
+ClassMemberDeclaration -> AnnotationTypeDeclaration
+/:$readableName ClassMemberDeclaration:/
+
+-- Empty declarations are not valid Java ClassMemberDeclarations.
+-- However, since the current (2/14/97) Java compiler accepts them 
+-- (in fact, some of the official tests contain this erroneous
+-- syntax)
+ClassMemberDeclaration ::= ';'
+/.$putCase consumeEmptyTypeDeclaration(); $break./
+
+GenericMethodDeclaration -> MethodDeclaration
+GenericMethodDeclaration -> ConstructorDeclaration
+/:$readableName GenericMethodDeclaration:/
+
+--18.8.2 Productions from 8.3: Field Declarations
+--VariableModifier ::=
+--      'public'
+--    | 'protected'
+--    | 'private'
+--    | 'static'
+--    | 'final'
+--    | 'transient'
+--    | 'volatile'
+
+FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
+/.$putCase consumeFieldDeclaration(); $break ./
+/:$readableName FieldDeclaration:/
+
+VariableDeclarators -> VariableDeclarator 
+VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator
+/.$putCase consumeVariableDeclarators(); $break ./
+/:$readableName VariableDeclarators:/
+/:$recovery_template Identifier:/
+
+VariableDeclarator ::= VariableDeclaratorId EnterVariable ExitVariableWithoutInitialization
+VariableDeclarator ::= VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+/:$readableName VariableDeclarator:/
+/:$recovery_template Identifier:/
+
+EnterVariable ::= $empty
+/.$putCase consumeEnterVariable(); $break ./
+/:$readableName EnterVariable:/
+
+ExitVariableWithInitialization ::= $empty
+/.$putCase consumeExitVariableWithInitialization(); $break ./
+/:$readableName ExitVariableWithInitialization:/
+
+ExitVariableWithoutInitialization ::= $empty
+/.$putCase consumeExitVariableWithoutInitialization(); $break ./
+/:$readableName ExitVariableWithoutInitialization:/
+
+ForceNoDiet ::= $empty
+/.$putCase consumeForceNoDiet(); $break ./
+/:$readableName ForceNoDiet:/
+RestoreDiet ::= $empty
+/.$putCase consumeRestoreDiet(); $break ./
+/:$readableName RestoreDiet:/
+
+VariableDeclaratorId ::= 'Identifier' Dimsopt
+/:$readableName VariableDeclaratorId:/
+/:$recovery_template Identifier:/
+
+VariableInitializer -> Expression
+VariableInitializer -> ArrayInitializer
+/:$readableName VariableInitializer:/
+/:$recovery_template Identifier:/
+
+--18.8.3 Productions from 8.4: Method Declarations
+--MethodModifier ::=
+--      'public'
+--    | 'protected'
+--    | 'private'
+--    | 'static'
+--    | 'abstract'
+--    | 'final'
+--    | 'native'
+--    | 'synchronized'
+--
+
+MethodDeclaration -> AbstractMethodDeclaration
+MethodDeclaration ::= MethodHeader MethodBody 
+/.$putCase // set to true to consume a method with a body
+ consumeMethodDeclaration(true); $break ./
+/:$readableName MethodDeclaration:/
+
+AbstractMethodDeclaration ::= MethodHeader ';'
+/.$putCase // set to false to consume a method without body
+ consumeMethodDeclaration(false); $break ./
+/:$readableName MethodDeclaration:/
+
+MethodHeader ::= MethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
+/.$putCase consumeMethodHeader(); $break ./
+/:$readableName MethodDeclaration:/
+
+DefaultMethodHeader ::= DefaultMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims MethodHeaderThrowsClauseopt
+/.$putCase consumeMethodHeader(); $break ./
+/:$readableName MethodDeclaration:/
+
+MethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+/.$putCase consumeMethodHeaderNameWithTypeParameters(false); $break ./
+MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+/.$putCase consumeMethodHeaderName(false); $break ./
+/:$readableName MethodHeaderName:/
+
+DefaultMethodHeaderName ::= ModifiersWithDefault TypeParameters Type 'Identifier' '('
+/.$putCase consumeMethodHeaderNameWithTypeParameters(false); $break ./
+DefaultMethodHeaderName ::= ModifiersWithDefault Type 'Identifier' '('
+/.$putCase consumeMethodHeaderName(false); $break ./
+/:$readableName MethodHeaderName:/
+
+ModifiersWithDefault ::= Modifiersopt 'default' Modifiersopt
+/.$putCase consumePushCombineModifiers(); $break ./
+/:$readableName Modifiers:/
+/:$compliance 1.8:/
+
+MethodHeaderRightParen ::= ')'
+/.$putCase consumeMethodHeaderRightParen(); $break ./
+/:$readableName ):/
+/:$recovery_template ):/
+
+MethodHeaderExtendedDims ::= Dimsopt
+/.$putCase consumeMethodHeaderExtendedDims(); $break ./
+/:$readableName MethodHeaderExtendedDims:/
+
+MethodHeaderThrowsClause ::= 'throws' ClassTypeList
+/.$putCase consumeMethodHeaderThrowsClause(); $break ./
+/:$readableName MethodHeaderThrowsClause:/
+
+ConstructorHeader ::= ConstructorHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderThrowsClauseopt
+/.$putCase consumeConstructorHeader(); $break ./
+/:$readableName ConstructorDeclaration:/
+
+ConstructorHeaderName ::= Modifiersopt TypeParameters 'Identifier' '('
+/.$putCase consumeConstructorHeaderNameWithTypeParameters(); $break ./
+ConstructorHeaderName ::= Modifiersopt 'Identifier' '('
+/.$putCase consumeConstructorHeaderName(); $break ./
+/:$readableName ConstructorHeaderName:/
+
+FormalParameterList -> FormalParameter
+FormalParameterList ::= FormalParameterList ',' FormalParameter
+/.$putCase consumeFormalParameterList(); $break ./
+/:$readableName FormalParameterList:/
+
+--1.1 feature
+FormalParameter ::= Modifiersopt Type VariableDeclaratorIdOrThis
+/.$putCase consumeFormalParameter(false); $break ./
+FormalParameter ::= Modifiersopt Type PushZeroTypeAnnotations '...' VariableDeclaratorIdOrThis
+/.$putCase consumeFormalParameter(true); $break ./
+/:$compliance 1.5:/
+FormalParameter ::= Modifiersopt Type @308... TypeAnnotations '...' VariableDeclaratorIdOrThis
+/.$putCase consumeFormalParameter(true); $break ./
+/:$readableName FormalParameter:/
+/:$compliance 1.8:/
+/:$recovery_template Identifier Identifier:/
+
+CatchFormalParameter ::= Modifiersopt CatchType VariableDeclaratorId
+/.$putCase consumeCatchFormalParameter(); $break ./
+/:$readableName FormalParameter:/
+/:$recovery_template Identifier Identifier:/
+
+CatchType ::= UnionType
+/.$putCase consumeCatchType(); $break ./
+/:$readableName CatchType:/
+
+UnionType ::= Type
+/.$putCase consumeUnionTypeAsClassType(); $break ./
+UnionType ::= UnionType '|' Type
+/.$putCase consumeUnionType(); $break ./
+/:$readableName UnionType:/
+/:$compliance 1.7:/
+
+ClassTypeList -> ClassTypeElt
+ClassTypeList ::= ClassTypeList ',' ClassTypeElt
+/.$putCase consumeClassTypeList(); $break ./
+/:$readableName ClassTypeList:/
+
+ClassTypeElt ::= ClassType
+/.$putCase consumeClassTypeElt(); $break ./
+/:$readableName ClassType:/
+
+MethodBody ::= NestedMethod '{' BlockStatementsopt '}' 
+/.$putCase consumeMethodBody(); $break ./
+/:$readableName MethodBody:/
+/:$no_statements_recovery:/
+
+NestedMethod ::= $empty
+/.$putCase consumeNestedMethod(); $break ./
+/:$readableName NestedMethod:/
+
+--18.8.4 Productions from 8.5: Static Initializers
+
+StaticInitializer ::= StaticOnly Block
+/.$putCase consumeStaticInitializer(); $break./
+/:$readableName StaticInitializer:/
+
+StaticOnly ::= 'static'
+/.$putCase consumeStaticOnly(); $break ./
+/:$readableName StaticOnly:/
+
+--18.8.5 Productions from 8.6: Constructor Declarations
+--ConstructorModifier ::=
+--      'public'
+--    | 'protected'
+--    | 'private'
+--
+--
+ConstructorDeclaration ::= ConstructorHeader MethodBody
+/.$putCase consumeConstructorDeclaration() ; $break ./ 
+-- These rules are added to be able to parse constructors with no body
+ConstructorDeclaration ::= ConstructorHeader ';'
+/.$putCase consumeInvalidConstructorDeclaration() ; $break ./ 
+/:$readableName ConstructorDeclaration:/
+
+-- the rules ExplicitConstructorInvocationopt has been expanded
+-- in the rule below in order to make the grammar lalr(1).
+
+ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(0, THIS_CALL); $break ./
+
+ExplicitConstructorInvocation ::= OnlyTypeArguments 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL); $break ./
+
+ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(0,SUPER_CALL); $break ./
+
+ExplicitConstructorInvocation ::= OnlyTypeArguments 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL); $break ./
+
+--1.1 feature
+ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(1, SUPER_CALL); $break ./
+
+ExplicitConstructorInvocation ::= Primary '.' OnlyTypeArguments 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL); $break ./
+
+--1.1 feature
+ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(2, SUPER_CALL); $break ./
+
+ExplicitConstructorInvocation ::= Name '.' OnlyTypeArguments 'super' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL); $break ./
+
+--1.1 feature
+ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(1, THIS_CALL); $break ./
+
+ExplicitConstructorInvocation ::= Primary '.' OnlyTypeArguments 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL); $break ./
+
+--1.1 feature
+ExplicitConstructorInvocation ::= Name '.' 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocation(2, THIS_CALL); $break ./
+
+ExplicitConstructorInvocation ::= Name '.' OnlyTypeArguments 'this' '(' ArgumentListopt ')' ';'
+/.$putCase consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL); $break ./
+/:$readableName ExplicitConstructorInvocation:/
+
+--18.9 Productions from 9: Interface Declarations
+
+--18.9.1 Productions from 9.1: Interface Declarations
+--InterfaceModifier ::=
+--      'public'
+--    | 'abstract'
+--
+InterfaceDeclaration ::= InterfaceHeader InterfaceBody
+/.$putCase consumeInterfaceDeclaration(); $break ./
+/:$readableName InterfaceDeclaration:/
+
+InterfaceHeader ::= InterfaceHeaderName InterfaceHeaderExtendsopt
+/.$putCase consumeInterfaceHeader(); $break ./
+/:$readableName InterfaceHeader:/
+
+-----------------------------------------------
+-- 1.5 features : generics
+-----------------------------------------------
+InterfaceHeaderName ::= InterfaceHeaderName1 TypeParameters
+/.$putCase consumeTypeHeaderNameWithTypeParameters(); $break ./
+
+InterfaceHeaderName -> InterfaceHeaderName1
+/:$readableName InterfaceHeaderName:/
+
+InterfaceHeaderName1 ::= Modifiersopt interface Identifier
+/.$putCase consumeInterfaceHeaderName1(); $break ./
+/:$readableName InterfaceHeaderName:/
+
+InterfaceHeaderExtends ::= 'extends' InterfaceTypeList
+/.$putCase consumeInterfaceHeaderExtends(); $break ./
+/:$readableName InterfaceHeaderExtends:/
+
+InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}' 
+/:$readableName InterfaceBody:/
+
+InterfaceMemberDeclarations -> InterfaceMemberDeclaration
+InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration
+/.$putCase consumeInterfaceMemberDeclarations(); $break ./
+/:$readableName InterfaceMemberDeclarations:/
+
+--same as for class members
+InterfaceMemberDeclaration ::= ';'
+/.$putCase consumeEmptyTypeDeclaration(); $break ./
+/:$readableName InterfaceMemberDeclaration:/
+
+
+InterfaceMemberDeclaration -> ConstantDeclaration
+InterfaceMemberDeclaration ::= DefaultMethodHeader MethodBody
+/:$compliance 1.8:/
+/.$putCase consumeInterfaceMethodDeclaration(false); $break ./
+InterfaceMemberDeclaration ::= MethodHeader MethodBody
+/.$putCase consumeInterfaceMethodDeclaration(false); $break ./
+/:$readableName InterfaceMemberDeclaration:/
+-- the next rule is illegal but allows to give a more canonical error message from inside consumeInterfaceMethodDeclaration():
+InterfaceMemberDeclaration ::= DefaultMethodHeader ';'
+/:$compliance 1.8:/
+/.$putCase consumeInterfaceMethodDeclaration(true); $break ./
+
+-- These rules are added to be able to parse constructors inside interface and then report a relevent error message
+InvalidConstructorDeclaration ::= ConstructorHeader MethodBody
+/.$putCase consumeInvalidConstructorDeclaration(true); $break ./
+InvalidConstructorDeclaration ::= ConstructorHeader ';'
+/.$putCase consumeInvalidConstructorDeclaration(false); $break ./
+/:$readableName InvalidConstructorDeclaration:/
+
+-- These rules are added to be able to parse initializers inside an interface and then report a relevent error message (bug 212713)
+InvalidInitializer -> StaticInitializer
+InvalidInitializer -> Initializer
+/:$readableName InvalidInitializer:/
+
+
+InterfaceMemberDeclaration -> AbstractMethodDeclaration
+InterfaceMemberDeclaration -> InvalidConstructorDeclaration
+InterfaceMemberDeclaration -> InvalidInitializer
+--1.1 feature
+InterfaceMemberDeclaration -> ClassDeclaration
+--1.1 feature
+InterfaceMemberDeclaration -> InterfaceDeclaration
+InterfaceMemberDeclaration -> EnumDeclaration
+InterfaceMemberDeclaration -> AnnotationTypeDeclaration
+/:$readableName InterfaceMemberDeclaration:/
+
+ConstantDeclaration -> FieldDeclaration
+/:$readableName ConstantDeclaration:/
+
+PushLeftBrace ::= $empty
+/.$putCase consumePushLeftBrace(); $break ./
+/:$readableName PushLeftBrace:/
+
+ArrayInitializer ::= '{' PushLeftBrace ,opt '}'
+/.$putCase consumeEmptyArrayInitializer(); $break ./
+ArrayInitializer ::= '{' PushLeftBrace VariableInitializers '}'
+/.$putCase consumeArrayInitializer(); $break ./
+ArrayInitializer ::= '{' PushLeftBrace VariableInitializers , '}'
+/.$putCase consumeArrayInitializer(); $break ./
+/:$readableName ArrayInitializer:/
+/:$recovery_template Identifier:/
+
+VariableInitializers ::= VariableInitializer
+VariableInitializers ::= VariableInitializers ',' VariableInitializer
+/.$putCase consumeVariableInitializers(); $break ./
+/:$readableName VariableInitializers:/
+
+Block ::= OpenBlock '{' BlockStatementsopt '}'
+/.$putCase consumeBlock(); $break ./
+/:$readableName Block:/
+
+OpenBlock ::= $empty
+/.$putCase consumeOpenBlock() ; $break ./
+/:$readableName OpenBlock:/
+
+BlockStatements -> BlockStatement
+BlockStatements ::= BlockStatements BlockStatement
+/.$putCase consumeBlockStatements() ; $break ./
+/:$readableName BlockStatements:/
+
+BlockStatement -> LocalVariableDeclarationStatement
+BlockStatement -> Statement
+--1.1 feature
+BlockStatement -> ClassDeclaration
+BlockStatement ::= InterfaceDeclaration
+/.$putCase consumeInvalidInterfaceDeclaration(); $break ./
+/:$readableName BlockStatement:/
+BlockStatement ::= AnnotationTypeDeclaration
+/.$putCase consumeInvalidAnnotationTypeDeclaration(); $break ./
+/:$readableName BlockStatement:/
+BlockStatement ::= EnumDeclaration
+/.$putCase consumeInvalidEnumDeclaration(); $break ./
+/:$readableName BlockStatement:/
+
+LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'
+/.$putCase consumeLocalVariableDeclarationStatement(); $break ./
+/:$readableName LocalVariableDeclarationStatement:/
+
+LocalVariableDeclaration ::= Type PushModifiers VariableDeclarators
+/.$putCase consumeLocalVariableDeclaration(); $break ./
+-- 1.1 feature
+-- The modifiers part of this rule makes the grammar more permissive. 
+-- The only modifier here is final. We put Modifiers to allow multiple modifiers
+-- This will require to check the validity of the modifier
+LocalVariableDeclaration ::= Modifiers Type PushRealModifiers VariableDeclarators
+/.$putCase consumeLocalVariableDeclaration(); $break ./
+/:$readableName LocalVariableDeclaration:/
+
+PushModifiers ::= $empty
+/.$putCase consumePushModifiers(); $break ./
+/:$readableName PushModifiers:/
+
+PushModifiersForHeader ::= $empty
+/.$putCase consumePushModifiersForHeader(); $break ./
+/:$readableName PushModifiersForHeader:/
+
+PushRealModifiers ::= $empty
+/.$putCase consumePushRealModifiers(); $break ./
+/:$readableName PushRealModifiers:/
+
+Statement -> StatementWithoutTrailingSubstatement
+Statement -> LabeledStatement
+Statement -> IfThenStatement
+Statement -> IfThenElseStatement
+Statement -> WhileStatement
+Statement -> ForStatement
+-----------------------------------------------
+-- 1.5 feature
+-----------------------------------------------
+Statement -> EnhancedForStatement
+/:$readableName Statement:/
+/:$recovery_template ;:/
+
+StatementNoShortIf -> StatementWithoutTrailingSubstatement
+StatementNoShortIf -> LabeledStatementNoShortIf
+StatementNoShortIf -> IfThenElseStatementNoShortIf
+StatementNoShortIf -> WhileStatementNoShortIf
+StatementNoShortIf -> ForStatementNoShortIf
+-----------------------------------------------
+-- 1.5 feature
+-----------------------------------------------
+StatementNoShortIf -> EnhancedForStatementNoShortIf
+/:$readableName Statement:/
+
+StatementWithoutTrailingSubstatement -> AssertStatement
+StatementWithoutTrailingSubstatement -> Block
+StatementWithoutTrailingSubstatement -> EmptyStatement
+StatementWithoutTrailingSubstatement -> ExpressionStatement
+StatementWithoutTrailingSubstatement -> SwitchStatement
+StatementWithoutTrailingSubstatement -> DoStatement
+StatementWithoutTrailingSubstatement -> BreakStatement
+StatementWithoutTrailingSubstatement -> ContinueStatement
+StatementWithoutTrailingSubstatement -> ReturnStatement
+StatementWithoutTrailingSubstatement -> SynchronizedStatement
+StatementWithoutTrailingSubstatement -> ThrowStatement
+StatementWithoutTrailingSubstatement -> TryStatement
+StatementWithoutTrailingSubstatement -> TryStatementWithResources
+/:$readableName Statement:/
+
+EmptyStatement ::= ';'
+/.$putCase consumeEmptyStatement(); $break ./
+/:$readableName EmptyStatement:/
+
+LabeledStatement ::= Label ':' Statement
+/.$putCase consumeStatementLabel() ; $break ./
+/:$readableName LabeledStatement:/
+
+LabeledStatementNoShortIf ::= Label ':' StatementNoShortIf
+/.$putCase consumeStatementLabel() ; $break ./
+/:$readableName LabeledStatement:/
+
+Label ::= 'Identifier'
+/.$putCase consumeLabel() ; $break ./
+/:$readableName Label:/
+
+ExpressionStatement ::= StatementExpression ';'
+/. $putCase consumeExpressionStatement(); $break ./
+ExpressionStatement ::= ExplicitConstructorInvocation
+/:$readableName Statement:/
+
+StatementExpression ::= Assignment
+StatementExpression ::= PreIncrementExpression
+StatementExpression ::= PreDecrementExpression
+StatementExpression ::= PostIncrementExpression
+StatementExpression ::= PostDecrementExpression
+StatementExpression ::= MethodInvocation
+StatementExpression ::= ClassInstanceCreationExpression
+/:$readableName Expression:/
+
+IfThenStatement ::= 'if' '(' Expression ')' Statement
+/.$putCase consumeStatementIfNoElse(); $break ./
+/:$readableName IfStatement:/
+
+IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement
+/.$putCase consumeStatementIfWithElse(); $break ./
+/:$readableName IfStatement:/
+
+IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf
+/.$putCase consumeStatementIfWithElse(); $break ./
+/:$readableName IfStatement:/
+
+SwitchStatement ::= 'switch' '(' Expression ')' OpenBlock SwitchBlock
+/.$putCase consumeStatementSwitch() ; $break ./
+/:$readableName SwitchStatement:/
+
+SwitchBlock ::= '{' '}'
+/.$putCase consumeEmptySwitchBlock() ; $break ./
+
+SwitchBlock ::= '{' SwitchBlockStatements '}'
+SwitchBlock ::= '{' SwitchLabels '}'
+SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
+/.$putCase consumeSwitchBlock() ; $break ./
+/:$readableName SwitchBlock:/
+
+SwitchBlockStatements -> SwitchBlockStatement
+SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement
+/.$putCase consumeSwitchBlockStatements() ; $break ./
+/:$readableName SwitchBlockStatements:/
+
+SwitchBlockStatement ::= SwitchLabels BlockStatements
+/.$putCase consumeSwitchBlockStatement() ; $break ./
+/:$readableName SwitchBlockStatement:/
+
+SwitchLabels -> SwitchLabel
+SwitchLabels ::= SwitchLabels SwitchLabel
+/.$putCase consumeSwitchLabels() ; $break ./
+/:$readableName SwitchLabels:/
+
+SwitchLabel ::= 'case' ConstantExpression ':'
+/. $putCase consumeCaseLabel(); $break ./
+
+SwitchLabel ::= 'default' ':'
+/. $putCase consumeDefaultLabel(); $break ./
+/:$readableName SwitchLabel:/
+
+WhileStatement ::= 'while' '(' Expression ')' Statement
+/.$putCase consumeStatementWhile() ; $break ./
+/:$readableName WhileStatement:/
+
+WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf
+/.$putCase consumeStatementWhile() ; $break ./
+/:$readableName WhileStatement:/
+
+DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';'
+/.$putCase consumeStatementDo() ; $break ./
+/:$readableName DoStatement:/
+
+ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement
+/.$putCase consumeStatementFor() ; $break ./
+/:$readableName ForStatement:/
+
+ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf
+/.$putCase consumeStatementFor() ; $break ./
+/:$readableName ForStatement:/
+
+--the minus one allows to avoid a stack-to-stack transfer
+ForInit ::= StatementExpressionList
+/.$putCase consumeForInit() ; $break ./
+ForInit -> LocalVariableDeclaration
+/:$readableName ForInit:/
+
+ForUpdate -> StatementExpressionList
+/:$readableName ForUpdate:/
+
+StatementExpressionList -> StatementExpression
+StatementExpressionList ::= StatementExpressionList ',' StatementExpression
+/.$putCase consumeStatementExpressionList() ; $break ./
+/:$readableName StatementExpressionList:/
+
+-- 1.4 feature
+AssertStatement ::= 'assert' Expression ';'
+/.$putCase consumeSimpleAssertStatement() ; $break ./
+/:$compliance 1.4:/
+
+AssertStatement ::= 'assert' Expression ':' Expression ';'
+/.$putCase consumeAssertStatement() ; $break ./
+/:$readableName AssertStatement:/
+/:$compliance 1.4:/
+
+BreakStatement ::= 'break' ';'
+/.$putCase consumeStatementBreak() ; $break ./
+
+BreakStatement ::= 'break' Identifier ';'
+/.$putCase consumeStatementBreakWithLabel() ; $break ./
+/:$readableName BreakStatement:/
+
+ContinueStatement ::= 'continue' ';'
+/.$putCase consumeStatementContinue() ; $break ./
+
+ContinueStatement ::= 'continue' Identifier ';'
+/.$putCase consumeStatementContinueWithLabel() ; $break ./
+/:$readableName ContinueStatement:/
+
+ReturnStatement ::= 'return' Expressionopt ';'
+/.$putCase consumeStatementReturn() ; $break ./
+/:$readableName ReturnStatement:/
+
+ThrowStatement ::= 'throw' Expression ';'
+/.$putCase consumeStatementThrow(); $break ./
+/:$readableName ThrowStatement:/
+
+SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
+/.$putCase consumeStatementSynchronized(); $break ./
+/:$readableName SynchronizedStatement:/
+
+OnlySynchronized ::= 'synchronized'
+/.$putCase consumeOnlySynchronized(); $break ./
+/:$readableName OnlySynchronized:/
+
+TryStatement ::= 'try' TryBlock Catches
+/.$putCase consumeStatementTry(false, false); $break ./
+TryStatement ::= 'try' TryBlock Catchesopt Finally
+/.$putCase consumeStatementTry(true, false); $break ./
+/:$readableName TryStatement:/
+
+TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt
+/.$putCase consumeStatementTry(false, true); $break ./
+TryStatementWithResources ::= 'try' ResourceSpecification TryBlock Catchesopt Finally
+/.$putCase consumeStatementTry(true, true); $break ./
+/:$readableName TryStatementWithResources:/
+/:$compliance 1.7:/
+
+ResourceSpecification ::= '(' Resources ;opt ')'
+/.$putCase consumeResourceSpecification(); $break ./
+/:$readableName ResourceSpecification:/
+/:$compliance 1.7:/
+
+;opt ::= $empty
+/.$putCase consumeResourceOptionalTrailingSemiColon(false); $break ./
+;opt ::= ';'
+/.$putCase consumeResourceOptionalTrailingSemiColon(true); $break ./
+/:$readableName ;:/
+/:$compliance 1.7:/
+
+Resources ::= Resource
+/.$putCase consumeSingleResource(); $break ./
+Resources ::= Resources TrailingSemiColon Resource
+/.$putCase consumeMultipleResources(); $break ./
+/:$readableName Resources:/
+/:$compliance 1.7:/
+
+TrailingSemiColon ::= ';'
+/.$putCase consumeResourceOptionalTrailingSemiColon(true); $break ./
+/:$readableName ;:/
+/:$compliance 1.7:/
+
+Resource ::= Type PushModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+/.$putCase consumeResourceAsLocalVariableDeclaration(); $break ./
+/:$readableName Resource:/
+/:$compliance 1.7:/
+
+Resource ::= Modifiers Type PushRealModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+/.$putCase consumeResourceAsLocalVariableDeclaration(); $break ./
+/:$readableName Resource:/
+/:$compliance 1.7:/
+
+TryBlock ::= Block ExitTryBlock
+/:$readableName Block:/
+
+ExitTryBlock ::= $empty
+/.$putCase consumeExitTryBlock(); $break ./
+/:$readableName ExitTryBlock:/
+
+Catches -> CatchClause
+Catches ::= Catches CatchClause
+/.$putCase consumeCatches(); $break ./
+/:$readableName Catches:/
+
+CatchClause ::= 'catch' '(' CatchFormalParameter ')' Block
+/.$putCase consumeStatementCatch() ; $break ./
+/:$readableName CatchClause:/
+
+Finally ::= 'finally' Block
+/:$readableName Finally:/
+/:$recovery_template finally { }:/
+
+--18.12 Productions from 14: Expressions
+
+--for source positioning purpose
+PushLPAREN ::= '('
+/.$putCase consumeLeftParen(); $break ./
+/:$readableName (:/
+/:$recovery_template (:/
+PushRPAREN ::= ')'
+/.$putCase consumeRightParen(); $break ./
+/:$readableName ):/
+/:$recovery_template ):/
+
+Primary -> PrimaryNoNewArray
+Primary -> ArrayCreationWithArrayInitializer
+Primary -> ArrayCreationWithoutArrayInitializer
+/:$readableName Expression:/
+
+PrimaryNoNewArray -> Literal
+PrimaryNoNewArray ::= 'this'
+/.$putCase consumePrimaryNoNewArrayThis(); $break ./
+
+PrimaryNoNewArray ::= PushLPAREN Expression_NotName PushRPAREN 
+/.$putCase consumePrimaryNoNewArray(); $break ./
+
+PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN 
+/.$putCase consumePrimaryNoNewArrayWithName(); $break ./
+
+PrimaryNoNewArray -> ClassInstanceCreationExpression
+PrimaryNoNewArray -> FieldAccess
+--1.1 feature
+PrimaryNoNewArray ::= Name '.' 'this'
+/.$putCase consumePrimaryNoNewArrayNameThis(); $break ./
+PrimaryNoNewArray ::= Name '.' 'super'
+/.$putCase consumePrimaryNoNewArrayNameSuper(); $break ./
+
+--1.1 feature
+--PrimaryNoNewArray ::= Type '.' 'class'
+--inline Type in the previous rule in order to make the grammar LL1 instead 
+-- of LL2. The result is the 3 next rules.
+
+PrimaryNoNewArray ::= Name '.' 'class'
+/.$putCase consumePrimaryNoNewArrayName(); $break ./
+
+PrimaryNoNewArray ::= Name Dims '.' 'class'
+/.$putCase consumePrimaryNoNewArrayArrayType(); $break ./
+
+PrimaryNoNewArray ::= PrimitiveType Dims '.' 'class'
+/.$putCase consumePrimaryNoNewArrayPrimitiveArrayType(); $break ./
+
+PrimaryNoNewArray ::= PrimitiveType '.' 'class'
+/.$putCase consumePrimaryNoNewArrayPrimitiveType(); $break ./
+
+PrimaryNoNewArray -> MethodInvocation
+PrimaryNoNewArray -> ArrayAccess
+
+-----------------------------------------------------------------------
+--                   Start of rules for JSR 335
+-----------------------------------------------------------------------
+
+PrimaryNoNewArray -> LambdaExpression
+PrimaryNoNewArray -> ReferenceExpression
+/:$readableName Expression:/
+
+-- Production name hardcoded in parser. Must be ::= and not -> 
+ReferenceExpressionTypeArgumentsAndTrunk ::= ReferenceExpressionTypeArgumentsAndTrunk0
+/:$readableName ReferenceExpressionTypeArgumentsAndTrunk:/
+
+ReferenceExpressionTypeArgumentsAndTrunk0 ::= OnlyTypeArguments Dimsopt 
+/.$putCase consumeReferenceExpressionTypeArgumentsAndTrunk(false); $break ./
+/:$compliance 1.8:/
+ReferenceExpressionTypeArgumentsAndTrunk0 ::= OnlyTypeArguments '.' ClassOrInterfaceType Dimsopt 
+/.$putCase consumeReferenceExpressionTypeArgumentsAndTrunk(true); $break ./
+/:$readableName ReferenceExpressionTypeArgumentsAndTrunk:/
+/:$compliance 1.8:/
+
+ReferenceExpression ::= PrimitiveType Dims '::' NonWildTypeArgumentsopt IdentifierOrNew
+/.$putCase consumeReferenceExpressionTypeForm(true); $break ./
+/:$compliance 1.8:/
+
+ReferenceExpression ::= Name Dimsopt '::' NonWildTypeArgumentsopt IdentifierOrNew
+/.$putCase consumeReferenceExpressionTypeForm(false); $break ./
+/:$compliance 1.8:/
+
+-- BeginTypeArguments is a synthetic token the scanner concocts to help disambiguate
+-- between '<' as an operator and '<' in '<' TypeArguments '>'
+ReferenceExpression ::= Name BeginTypeArguments ReferenceExpressionTypeArgumentsAndTrunk '::' NonWildTypeArgumentsopt IdentifierOrNew
+/.$putCase consumeReferenceExpressionGenericTypeForm(); $break ./
+/:$compliance 1.8:/
+
+ReferenceExpression ::= Primary '::' NonWildTypeArgumentsopt Identifier
+/.$putCase consumeReferenceExpressionPrimaryForm(); $break ./
+/:$compliance 1.8:/
+ReferenceExpression ::= 'super' '::' NonWildTypeArgumentsopt Identifier
+/.$putCase consumeReferenceExpressionSuperForm(); $break ./
+/:$readableName ReferenceExpression:/
+/:$compliance 1.8:/
+
+NonWildTypeArgumentsopt ::= $empty
+/.$putCase consumeEmptyTypeArguments(); $break ./
+NonWildTypeArgumentsopt -> OnlyTypeArguments
+/:$readableName NonWildTypeArgumentsopt:/
+/:$compliance 1.8:/
+
+IdentifierOrNew ::= 'Identifier'
+/.$putCase consumeIdentifierOrNew(false); $break ./
+IdentifierOrNew ::= 'new'
+/.$putCase consumeIdentifierOrNew(true); $break ./
+/:$readableName IdentifierOrNew:/
+/:$compliance 1.8:/
+
+LambdaExpression ::= LambdaParameters '->' LambdaBody
+/.$putCase consumeLambdaExpression(); $break ./
+/:$readableName LambdaExpression:/
+/:$compliance 1.8:/
+
+LambdaParameters ::= Identifier
+/.$putCase consumeTypeElidedLambdaParameter(false); $break ./
+/:$readableName TypeElidedFormalParameter:/
+/:$compliance 1.8:/
+
+-- to make the grammar LALR(1), the scanner transforms the input string to
+-- contain synthetic tokens to signal start of lambda parameter list.
+LambdaParameters -> BeginLambda LambdaParameterList
+/:$readableName LambdaParameters:/
+/:$compliance 1.8:/
+
+-- Production name hardcoded in parser. Must be ::= and not -> 
+ParenthesizedLambdaParameterList ::= LambdaParameterList
+/:$readableName ParenthesizedLambdaParameterList:/
+
+LambdaParameterList -> PushLPAREN FormalParameterListopt PushRPAREN
+LambdaParameterList -> PushLPAREN TypeElidedFormalParameterList PushRPAREN
+/:$readableName LambdaParameterList:/
+/:$compliance 1.8:/
+
+TypeElidedFormalParameterList -> TypeElidedFormalParameter
+TypeElidedFormalParameterList ::= TypeElidedFormalParameterList ',' TypeElidedFormalParameter
+/.$putCase consumeFormalParameterList(); $break ./
+/:$readableName TypeElidedFormalParameterList:/
+/:$compliance 1.8:/
+
+-- to work around a shift reduce conflict, we accept Modifiersopt prefixed
+-- identifier - downstream phases should reject input strings with modifiers.
+TypeElidedFormalParameter ::= Modifiersopt Identifier
+/.$putCase consumeTypeElidedLambdaParameter(true); $break ./
+/:$readableName TypeElidedFormalParameter:/
+/:$compliance 1.8:/
+
+-- A lambda body of the form x is really '{' return x; '}'
+LambdaBody -> ElidedLeftBraceAndReturn Expression ElidedSemicolonAndRightBrace
+LambdaBody ::= NestedType NestedMethod  '{' BlockStatementsopt '}'
+/.$putCase consumeBlock(); $break ./
+/:$readableName LambdaBody:/
+/:$compliance 1.8:/
+
+ElidedLeftBraceAndReturn ::= $empty
+/.$putCase consumeElidedLeftBraceAndReturn(); $break ./
+/:$readableName ElidedLeftBraceAndReturn:/
+/:$compliance 1.8:/
+
+-----------------------------------------------------------------------
+--                   End of rules for JSR 335
+-----------------------------------------------------------------------
+
+--1.1 feature
+--
+-- In Java 1.0 a ClassBody could not appear at all in a
+-- ClassInstanceCreationExpression.
+--
+
+AllocationHeader ::= 'new' ClassType '(' ArgumentListopt ')'
+/.$putCase consumeAllocationHeader(); $break ./
+/:$readableName AllocationHeader:/
+
+ClassInstanceCreationExpression ::= 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' UnqualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpressionWithTypeArguments(); $break ./
+
+ClassInstanceCreationExpression ::= 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' UnqualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpression(); $break ./
+--1.1 feature
+
+ClassInstanceCreationExpression ::= Primary '.' 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./
+
+ClassInstanceCreationExpression ::= Primary '.' 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
+
+--1.1 feature
+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./
+/:$readableName ClassInstanceCreationExpression:/
+
+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' OnlyTypeArguments ClassType EnterInstanceCreationArgumentList '(' ArgumentListopt ')' QualifiedClassBodyopt
+/.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./
+/:$readableName ClassInstanceCreationExpression:/
+
+EnterInstanceCreationArgumentList ::= $empty
+/.$putCase consumeEnterInstanceCreationArgumentList(); $break ./
+/:$readableName EnterInstanceCreationArgumentList:/
+
+ClassInstanceCreationExpressionName ::= Name '.'
+/.$putCase consumeClassInstanceCreationExpressionName() ; $break ./
+/:$readableName ClassInstanceCreationExpressionName:/
+
+UnqualifiedClassBodyopt ::= $empty --test made using null as contents
+/.$putCase consumeClassBodyopt(); $break ./
+UnqualifiedClassBodyopt ::= UnqualifiedEnterAnonymousClassBody ClassBody
+/:$readableName ClassBody:/
+/:$no_statements_recovery:/
+
+UnqualifiedEnterAnonymousClassBody ::= $empty
+/.$putCase consumeEnterAnonymousClassBody(false); $break ./
+/:$readableName EnterAnonymousClassBody:/
+
+QualifiedClassBodyopt ::= $empty --test made using null as contents
+/.$putCase consumeClassBodyopt(); $break ./
+QualifiedClassBodyopt ::= QualifiedEnterAnonymousClassBody ClassBody
+/:$readableName ClassBody:/
+/:$no_statements_recovery:/
+
+QualifiedEnterAnonymousClassBody ::= $empty
+/.$putCase consumeEnterAnonymousClassBody(true); $break ./
+/:$readableName EnterAnonymousClassBody:/
+
+ArgumentList ::= Expression
+ArgumentList ::= ArgumentList ',' Expression
+/.$putCase consumeArgumentList(); $break ./
+/:$readableName ArgumentList:/
+
+ArrayCreationHeader ::= 'new' PrimitiveType DimWithOrWithOutExprs
+/.$putCase consumeArrayCreationHeader(); $break ./
+
+ArrayCreationHeader ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
+/.$putCase consumeArrayCreationHeader(); $break ./
+/:$readableName ArrayCreationHeader:/
+
+ArrayCreationWithoutArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs
+/.$putCase consumeArrayCreationExpressionWithoutInitializer(); $break ./
+/:$readableName ArrayCreationWithoutArrayInitializer:/
+
+ArrayCreationWithArrayInitializer ::= 'new' PrimitiveType DimWithOrWithOutExprs ArrayInitializer
+/.$putCase consumeArrayCreationExpressionWithInitializer(); $break ./
+/:$readableName ArrayCreationWithArrayInitializer:/
+
+ArrayCreationWithoutArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs
+/.$putCase consumeArrayCreationExpressionWithoutInitializer(); $break ./
+
+ArrayCreationWithArrayInitializer ::= 'new' ClassOrInterfaceType DimWithOrWithOutExprs ArrayInitializer
+/.$putCase consumeArrayCreationExpressionWithInitializer(); $break ./
+
+DimWithOrWithOutExprs ::= DimWithOrWithOutExpr
+DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
+/.$putCase consumeDimWithOrWithOutExprs(); $break ./
+/:$readableName Dimensions:/
+
+DimWithOrWithOutExpr ::= TypeAnnotationsopt '[' Expression ']'
+DimWithOrWithOutExpr ::= TypeAnnotationsopt '[' ']'
+/. $putCase consumeDimWithOrWithOutExpr(); $break ./
+/:$readableName Dimension:/
+-- -----------------------------------------------
+
+Dims ::= DimsLoop
+/. $putCase consumeDims(); $break ./
+/:$readableName Dimensions:/
+DimsLoop -> OneDimLoop
+DimsLoop ::= DimsLoop OneDimLoop
+/:$readableName Dimensions:/
+OneDimLoop ::= '[' ']'
+/. $putCase consumeOneDimLoop(false); $break ./
+OneDimLoop ::= TypeAnnotations '[' ']'
+/:$compliance 1.8:/
+/. $putCase consumeOneDimLoop(true); $break ./
+/:$readableName Dimension:/
+
+FieldAccess ::= Primary '.' 'Identifier'
+/.$putCase consumeFieldAccess(false); $break ./
+
+FieldAccess ::= 'super' '.' 'Identifier'
+/.$putCase consumeFieldAccess(true); $break ./
+/:$readableName FieldAccess:/
+
+MethodInvocation ::= Name '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationName(); $break ./
+
+MethodInvocation ::= Name '.' OnlyTypeArguments 'Identifier' '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationNameWithTypeArguments(); $break ./
+
+MethodInvocation ::= Primary '.' OnlyTypeArguments 'Identifier' '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationPrimaryWithTypeArguments(); $break ./
+
+MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationPrimary(); $break ./
+
+MethodInvocation ::= 'super' '.' OnlyTypeArguments 'Identifier' '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationSuperWithTypeArguments(); $break ./
+
+MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
+/.$putCase consumeMethodInvocationSuper(); $break ./
+/:$readableName MethodInvocation:/
+
+ArrayAccess ::= Name '[' Expression ']'
+/.$putCase consumeArrayAccess(true); $break ./
+ArrayAccess ::= PrimaryNoNewArray '[' Expression ']'
+/.$putCase consumeArrayAccess(false); $break ./
+ArrayAccess ::= ArrayCreationWithArrayInitializer '[' Expression ']'
+/.$putCase consumeArrayAccess(false); $break ./
+/:$readableName ArrayAccess:/
+
+PostfixExpression -> Primary
+PostfixExpression ::= Name
+/.$putCase consumePostfixExpression(); $break ./
+PostfixExpression -> PostIncrementExpression
+PostfixExpression -> PostDecrementExpression
+/:$readableName Expression:/
+
+PostIncrementExpression ::= PostfixExpression '++'
+/.$putCase consumeUnaryExpression(OperatorIds.PLUS,true); $break ./
+/:$readableName PostIncrementExpression:/
+
+PostDecrementExpression ::= PostfixExpression '--'
+/.$putCase consumeUnaryExpression(OperatorIds.MINUS,true); $break ./
+/:$readableName PostDecrementExpression:/
+
+--for source managment purpose
+PushPosition ::= $empty
+ /.$putCase consumePushPosition(); $break ./
+/:$readableName PushPosition:/
+
+UnaryExpression -> PreIncrementExpression
+UnaryExpression -> PreDecrementExpression
+UnaryExpression ::= '+' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.PLUS); $break ./
+UnaryExpression ::= '-' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.MINUS); $break ./
+UnaryExpression -> UnaryExpressionNotPlusMinus
+/:$readableName Expression:/
+
+PreIncrementExpression ::= '++' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.PLUS,false); $break ./
+/:$readableName PreIncrementExpression:/
+
+PreDecrementExpression ::= '--' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.MINUS,false); $break ./
+/:$readableName PreDecrementExpression:/
+
+UnaryExpressionNotPlusMinus -> PostfixExpression
+UnaryExpressionNotPlusMinus ::= '~' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.TWIDDLE); $break ./
+UnaryExpressionNotPlusMinus ::= '!' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.NOT); $break ./
+UnaryExpressionNotPlusMinus -> CastExpression
+/:$readableName Expression:/
+
+CastExpression ::= PushLPAREN PrimitiveType Dimsopt AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpression
+/.$putCase consumeCastExpressionWithPrimitiveType(); $break ./
+CastExpression ::= PushLPAREN Name OnlyTypeArgumentsForCastExpression Dimsopt AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+/.$putCase consumeCastExpressionWithGenericsArray(); $break ./
+CastExpression ::= PushLPAREN Name OnlyTypeArgumentsForCastExpression '.' ClassOrInterfaceType Dimsopt AdditionalBoundsListOpt PushRPAREN InsideCastExpressionWithQualifiedGenerics UnaryExpressionNotPlusMinus
+/.$putCase consumeCastExpressionWithQualifiedGenericsArray(); $break ./
+CastExpression ::= PushLPAREN Name PushRPAREN InsideCastExpressionLL1 UnaryExpressionNotPlusMinus
+/.$putCase consumeCastExpressionLL1(); $break ./
+CastExpression ::=  BeginIntersectionCast PushLPAREN CastNameAndBounds PushRPAREN InsideCastExpressionLL1WithBounds UnaryExpressionNotPlusMinus
+/.$putCase consumeCastExpressionLL1WithBounds(); $break ./
+CastExpression ::= PushLPAREN Name Dims AdditionalBoundsListOpt PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
+/.$putCase consumeCastExpressionWithNameArray(); $break ./
+/:$readableName CastExpression:/
+
+AdditionalBoundsListOpt ::= $empty
+/.$putCase consumeZeroAdditionalBounds(); $break ./
+/:$readableName AdditionalBoundsListOpt:/
+AdditionalBoundsListOpt -> AdditionalBoundList
+/:$compliance 1.8:/
+/:$readableName AdditionalBoundsListOpt:/
+
+-- Production name hardcoded in parser. Must be ::= and not -> 
+ParenthesizedCastNameAndBounds ::= '(' CastNameAndBounds ')'
+/:$readableName ParenthesizedCastNameAndBounds:/
+
+CastNameAndBounds -> Name AdditionalBoundList
+/:$compliance 1.8:/
+/:$readableName CastNameAndBounds:/
+
+OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments
+/.$putCase consumeOnlyTypeArgumentsForCastExpression(); $break ./
+/:$readableName TypeArguments:/
+
+InsideCastExpression ::= $empty
+/.$putCase consumeInsideCastExpression(); $break ./
+/:$readableName InsideCastExpression:/
+InsideCastExpressionLL1 ::= $empty
+/.$putCase consumeInsideCastExpressionLL1(); $break ./
+/:$readableName InsideCastExpression:/
+InsideCastExpressionLL1WithBounds ::= $empty
+/.$putCase consumeInsideCastExpressionLL1WithBounds (); $break ./
+/:$readableName InsideCastExpression:/
+InsideCastExpressionWithQualifiedGenerics ::= $empty
+/.$putCase consumeInsideCastExpressionWithQualifiedGenerics(); $break ./
+/:$readableName InsideCastExpression:/
+
+MultiplicativeExpression -> UnaryExpression
+MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.MULTIPLY); $break ./
+MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.DIVIDE); $break ./
+MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.REMAINDER); $break ./
+/:$readableName Expression:/
+
+AdditiveExpression -> MultiplicativeExpression
+AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression
+/.$putCase consumeBinaryExpression(OperatorIds.PLUS); $break ./
+AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression
+/.$putCase consumeBinaryExpression(OperatorIds.MINUS); $break ./
+/:$readableName Expression:/
+
+ShiftExpression -> AdditiveExpression
+ShiftExpression ::= ShiftExpression '<<' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LEFT_SHIFT); $break ./
+ShiftExpression ::= ShiftExpression '>>' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); $break ./
+ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); $break ./
+/:$readableName Expression:/
+
+RelationalExpression -> ShiftExpression
+RelationalExpression ::= RelationalExpression '<' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LESS); $break ./
+RelationalExpression ::= RelationalExpression '>' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.GREATER); $break ./
+RelationalExpression ::= RelationalExpression '<=' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LESS_EQUAL); $break ./
+RelationalExpression ::= RelationalExpression '>=' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.GREATER_EQUAL); $break ./
+/:$readableName Expression:/
+
+InstanceofExpression -> RelationalExpression
+InstanceofExpression ::= InstanceofExpression 'instanceof' ReferenceType
+/.$putCase consumeInstanceOfExpression(); $break ./
+/:$readableName Expression:/
+
+EqualityExpression -> InstanceofExpression
+EqualityExpression ::= EqualityExpression '==' InstanceofExpression
+/.$putCase consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); $break ./
+EqualityExpression ::= EqualityExpression '!=' InstanceofExpression
+/.$putCase consumeEqualityExpression(OperatorIds.NOT_EQUAL); $break ./
+/:$readableName Expression:/
+
+AndExpression -> EqualityExpression
+AndExpression ::= AndExpression '&' EqualityExpression
+/.$putCase consumeBinaryExpression(OperatorIds.AND); $break ./
+/:$readableName Expression:/
+
+ExclusiveOrExpression -> AndExpression
+ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression
+/.$putCase consumeBinaryExpression(OperatorIds.XOR); $break ./
+/:$readableName Expression:/
+
+InclusiveOrExpression -> ExclusiveOrExpression
+InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression
+/.$putCase consumeBinaryExpression(OperatorIds.OR); $break ./
+/:$readableName Expression:/
+
+ConditionalAndExpression -> InclusiveOrExpression
+ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression
+/.$putCase consumeBinaryExpression(OperatorIds.AND_AND); $break ./
+/:$readableName Expression:/
+
+ConditionalOrExpression -> ConditionalAndExpression
+ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression
+/.$putCase consumeBinaryExpression(OperatorIds.OR_OR); $break ./
+/:$readableName Expression:/
+
+ConditionalExpression -> ConditionalOrExpression
+ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression
+/.$putCase consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; $break ./
+/:$readableName Expression:/
+
+AssignmentExpression -> ConditionalExpression
+AssignmentExpression -> Assignment
+/:$readableName Expression:/
+/:$recovery_template Identifier:/
+
+Assignment ::= PostfixExpression AssignmentOperator AssignmentExpression
+/.$putCase consumeAssignment(); $break ./
+/:$readableName Assignment:/
+
+-- this rule is added to parse an array initializer in a assigment and then report a syntax error knowing the exact senario
+InvalidArrayInitializerAssignement ::= PostfixExpression AssignmentOperator ArrayInitializer
+/:$readableName ArrayInitializerAssignment:/
+/:$recovery:/
+Assignment ::= InvalidArrayInitializerAssignement
+/.$putcase ignoreExpressionAssignment();$break ./
+/:$recovery:/
+
+AssignmentOperator ::= '='
+/.$putCase consumeAssignmentOperator(EQUAL); $break ./
+AssignmentOperator ::= '*='
+/.$putCase consumeAssignmentOperator(MULTIPLY); $break ./
+AssignmentOperator ::= '/='
+/.$putCase consumeAssignmentOperator(DIVIDE); $break ./
+AssignmentOperator ::= '%='
+/.$putCase consumeAssignmentOperator(REMAINDER); $break ./
+AssignmentOperator ::= '+='
+/.$putCase consumeAssignmentOperator(PLUS); $break ./
+AssignmentOperator ::= '-='
+/.$putCase consumeAssignmentOperator(MINUS); $break ./
+AssignmentOperator ::= '<<='
+/.$putCase consumeAssignmentOperator(LEFT_SHIFT); $break ./
+AssignmentOperator ::= '>>='
+/.$putCase consumeAssignmentOperator(RIGHT_SHIFT); $break ./
+AssignmentOperator ::= '>>>='
+/.$putCase consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); $break ./
+AssignmentOperator ::= '&='
+/.$putCase consumeAssignmentOperator(AND); $break ./
+AssignmentOperator ::= '^='
+/.$putCase consumeAssignmentOperator(XOR); $break ./
+AssignmentOperator ::= '|='
+/.$putCase consumeAssignmentOperator(OR); $break ./
+/:$readableName AssignmentOperator:/
+/:$recovery_template =:/
+
+-- For handling lambda expressions, we need to know when a full Expression
+-- has been reduced.
+Expression ::= AssignmentExpression
+/.$putCase consumeExpression(); $break ./
+/:$readableName Expression:/
+/:$recovery_template Identifier:/
+
+-- The following rules are for optional nonterminals.
+--
+ClassHeaderExtendsopt ::= $empty
+ClassHeaderExtendsopt -> ClassHeaderExtends
+/:$readableName ClassHeaderExtends:/
+
+Expressionopt ::= $empty
+/.$putCase consumeEmptyExpression(); $break ./
+Expressionopt -> Expression
+/:$readableName Expression:/
+
+ConstantExpression -> Expression
+/:$readableName ConstantExpression:/
+
+---------------------------------------------------------------------------------------
+--
+-- The rules below are for optional terminal symbols.  An optional comma,
+-- is only used in the context of an array initializer - It is a
+-- "syntactic sugar" that otherwise serves no other purpose. By contrast,
+-- an optional identifier is used in the definition of a break and 
+-- continue statement. When the identifier does not appear, a NULL
+-- is produced. When the identifier is present, the user should use the
+-- corresponding TOKEN(i) method. See break statement as an example.
+--
+---------------------------------------------------------------------------------------
+
+,opt -> $empty
+,opt -> ,
+/:$readableName ,:/
+
+ClassBodyDeclarationsopt ::= $empty
+/.$putCase consumeEmptyClassBodyDeclarationsopt(); $break ./
+ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
+/.$putCase consumeClassBodyDeclarationsopt(); $break ./
+/:$readableName ClassBodyDeclarations:/
+
+Modifiersopt ::= $empty 
+/. $putCase consumeDefaultModifiers(); $break ./
+Modifiersopt ::= Modifiers
+/.$putCase consumeModifiers(); $break ./ 
+/:$readableName Modifiers:/
+
+BlockStatementsopt ::= $empty
+/.$putCase consumeEmptyBlockStatementsopt(); $break ./
+BlockStatementsopt -> BlockStatements
+/:$readableName BlockStatements:/
+
+Dimsopt ::= $empty
+/. $putCase consumeEmptyDimsopt(); $break ./
+Dimsopt -> Dims
+/:$readableName Dimensions:/
+
+ArgumentListopt ::= $empty
+/. $putCase consumeEmptyArgumentListopt(); $break ./
+ArgumentListopt -> ArgumentList
+/:$readableName ArgumentList:/
+
+MethodHeaderThrowsClauseopt ::= $empty
+MethodHeaderThrowsClauseopt -> MethodHeaderThrowsClause
+/:$readableName MethodHeaderThrowsClause:/
+
+FormalParameterListopt ::= $empty
+/.$putcase consumeFormalParameterListopt(); $break ./
+FormalParameterListopt -> FormalParameterList
+/:$readableName FormalParameterList:/
+
+ClassHeaderImplementsopt ::= $empty
+ClassHeaderImplementsopt -> ClassHeaderImplements
+/:$readableName ClassHeaderImplements:/
+
+InterfaceMemberDeclarationsopt ::= $empty
+/. $putCase consumeEmptyInterfaceMemberDeclarationsopt(); $break ./
+InterfaceMemberDeclarationsopt ::= NestedType InterfaceMemberDeclarations
+/. $putCase consumeInterfaceMemberDeclarationsopt(); $break ./
+/:$readableName InterfaceMemberDeclarations:/
+
+NestedType ::= $empty 
+/.$putCase consumeNestedType(); $break./
+/:$readableName NestedType:/
+
+ForInitopt ::= $empty
+/. $putCase consumeEmptyForInitopt(); $break ./
+ForInitopt -> ForInit
+/:$readableName ForInit:/
+
+ForUpdateopt ::= $empty
+/. $putCase consumeEmptyForUpdateopt(); $break ./
+ForUpdateopt -> ForUpdate
+/:$readableName ForUpdate:/
+
+InterfaceHeaderExtendsopt ::= $empty
+InterfaceHeaderExtendsopt -> InterfaceHeaderExtends
+/:$readableName InterfaceHeaderExtends:/
+
+Catchesopt ::= $empty
+/. $putCase consumeEmptyCatchesopt(); $break ./
+Catchesopt -> Catches
+/:$readableName Catches:/
+
+-----------------------------------------------
+-- 1.5 features : enum type
+-----------------------------------------------
+EnumDeclaration ::= EnumHeader EnumBody
+/. $putCase consumeEnumDeclaration(); $break ./
+/:$readableName EnumDeclaration:/
+
+EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt
+/. $putCase consumeEnumHeader(); $break ./
+/:$readableName EnumHeader:/
+
+EnumHeaderName ::= Modifiersopt 'enum' Identifier
+/. $putCase consumeEnumHeaderName(); $break ./
+/:$compliance 1.5:/
+EnumHeaderName ::= Modifiersopt 'enum' Identifier TypeParameters
+/. $putCase consumeEnumHeaderNameWithTypeParameters(); $break ./
+/:$readableName EnumHeaderName:/
+/:$compliance 1.5:/
+
+EnumBody ::= '{' EnumBodyDeclarationsopt '}'
+/. $putCase consumeEnumBodyNoConstants(); $break ./
+EnumBody ::= '{' ',' EnumBodyDeclarationsopt '}'
+/. $putCase consumeEnumBodyNoConstants(); $break ./
+EnumBody ::= '{' EnumConstants ',' EnumBodyDeclarationsopt '}'
+/. $putCase consumeEnumBodyWithConstants(); $break ./
+EnumBody ::= '{' EnumConstants EnumBodyDeclarationsopt '}'
+/. $putCase consumeEnumBodyWithConstants(); $break ./
+/:$readableName EnumBody:/
+
+EnumConstants -> EnumConstant
+EnumConstants ::= EnumConstants ',' EnumConstant
+/.$putCase consumeEnumConstants(); $break ./
+/:$readableName EnumConstants:/
+
+EnumConstantHeaderName ::= Modifiersopt Identifier
+/.$putCase consumeEnumConstantHeaderName(); $break ./
+/:$readableName EnumConstantHeaderName:/
+
+EnumConstantHeader ::= EnumConstantHeaderName ForceNoDiet Argumentsopt RestoreDiet
+/.$putCase consumeEnumConstantHeader(); $break ./
+/:$readableName EnumConstantHeader:/
+
+EnumConstant ::= EnumConstantHeader ForceNoDiet ClassBody RestoreDiet
+/.$putCase consumeEnumConstantWithClassBody(); $break ./
+EnumConstant ::= EnumConstantHeader
+/.$putCase consumeEnumConstantNoClassBody(); $break ./
+/:$readableName EnumConstant:/
+
+Arguments ::= '(' ArgumentListopt ')'
+/.$putCase consumeArguments(); $break ./
+/:$readableName Arguments:/
+
+Argumentsopt ::= $empty
+/.$putCase consumeEmptyArguments(); $break ./
+Argumentsopt -> Arguments
+/:$readableName Argumentsopt:/
+
+EnumDeclarations ::= ';' ClassBodyDeclarationsopt
+/.$putCase consumeEnumDeclarations(); $break ./
+/:$readableName EnumDeclarations:/
+
+EnumBodyDeclarationsopt ::= $empty
+/.$putCase consumeEmptyEnumDeclarations(); $break ./
+EnumBodyDeclarationsopt -> EnumDeclarations
+/:$readableName EnumBodyDeclarationsopt:/
+
+-----------------------------------------------
+-- 1.5 features : enhanced for statement
+-----------------------------------------------
+EnhancedForStatement ::= EnhancedForStatementHeader Statement
+/.$putCase consumeEnhancedForStatement(); $break ./
+/:$readableName EnhancedForStatement:/
+
+EnhancedForStatementNoShortIf ::= EnhancedForStatementHeader StatementNoShortIf
+/.$putCase consumeEnhancedForStatement(); $break ./
+/:$readableName EnhancedForStatementNoShortIf:/
+
+EnhancedForStatementHeaderInit ::= 'for' '(' Type PushModifiers Identifier Dimsopt
+/.$putCase consumeEnhancedForStatementHeaderInit(false); $break ./
+/:$readableName EnhancedForStatementHeaderInit:/
+
+EnhancedForStatementHeaderInit ::= 'for' '(' Modifiers Type PushRealModifiers Identifier Dimsopt
+/.$putCase consumeEnhancedForStatementHeaderInit(true); $break ./
+/:$readableName EnhancedForStatementHeaderInit:/
+
+EnhancedForStatementHeader ::= EnhancedForStatementHeaderInit ':' Expression ')'
+/.$putCase consumeEnhancedForStatementHeader(); $break ./
+/:$readableName EnhancedForStatementHeader:/
+/:$compliance 1.5:/
+
+-----------------------------------------------
+-- 1.5 features : static imports
+-----------------------------------------------
+SingleStaticImportDeclaration ::= SingleStaticImportDeclarationName ';'
+/.$putCase consumeImportDeclaration(); $break ./
+/:$readableName SingleStaticImportDeclaration:/
+
+SingleStaticImportDeclarationName ::= 'import' 'static' Name RejectTypeAnnotations
+/.$putCase consumeSingleStaticImportDeclarationName(); $break ./
+/:$readableName SingleStaticImportDeclarationName:/
+/:$compliance 1.5:/
+
+StaticImportOnDemandDeclaration ::= StaticImportOnDemandDeclarationName ';'
+/.$putCase consumeImportDeclaration(); $break ./
+/:$readableName StaticImportOnDemandDeclaration:/
+
+StaticImportOnDemandDeclarationName ::= 'import' 'static' Name '.' RejectTypeAnnotations '*'
+/.$putCase consumeStaticImportOnDemandDeclarationName(); $break ./
+/:$readableName StaticImportOnDemandDeclarationName:/
+/:$compliance 1.5:/
+
+-----------------------------------------------
+-- 1.5 features : generics
+-----------------------------------------------
+TypeArguments ::= '<' TypeArgumentList1
+/.$putCase consumeTypeArguments(); $break ./
+/:$readableName TypeArguments:/
+/:$compliance 1.5:/
+
+OnlyTypeArguments ::= '<' TypeArgumentList1
+/.$putCase consumeOnlyTypeArguments(); $break ./
+/:$readableName TypeArguments:/
+/:$compliance 1.5:/
+
+TypeArgumentList1 -> TypeArgument1
+/:$compliance 1.5:/
+TypeArgumentList1 ::= TypeArgumentList ',' TypeArgument1
+/.$putCase consumeTypeArgumentList1(); $break ./
+/:$readableName TypeArgumentList1:/
+/:$compliance 1.5:/
+
+TypeArgumentList -> TypeArgument
+/:$compliance 1.5:/
+TypeArgumentList ::= TypeArgumentList ',' TypeArgument
+/.$putCase consumeTypeArgumentList(); $break ./
+/:$readableName TypeArgumentList:/
+/:$compliance 1.5:/
+
+TypeArgument ::= ReferenceType
+/.$putCase consumeTypeArgument(); $break ./
+/:$compliance 1.5:/
+TypeArgument -> Wildcard
+/:$readableName TypeArgument:/
+/:$compliance 1.5:/
+
+TypeArgument1 -> ReferenceType1
+/:$compliance 1.5:/
+TypeArgument1 -> Wildcard1
+/:$readableName TypeArgument1:/
+/:$compliance 1.5:/
+
+ReferenceType1 ::= ReferenceType '>'
+/.$putCase consumeReferenceType1(); $break ./
+/:$compliance 1.5:/
+ReferenceType1 ::= ClassOrInterface '<' TypeArgumentList2
+/.$putCase consumeTypeArgumentReferenceType1(); $break ./
+/:$readableName ReferenceType1:/
+/:$compliance 1.5:/
+
+TypeArgumentList2 -> TypeArgument2
+/:$compliance 1.5:/
+TypeArgumentList2 ::= TypeArgumentList ',' TypeArgument2
+/.$putCase consumeTypeArgumentList2(); $break ./
+/:$readableName TypeArgumentList2:/
+/:$compliance 1.5:/
+
+TypeArgument2 -> ReferenceType2
+/:$compliance 1.5:/
+TypeArgument2 -> Wildcard2
+/:$readableName TypeArgument2:/
+/:$compliance 1.5:/
+
+ReferenceType2 ::= ReferenceType '>>'
+/.$putCase consumeReferenceType2(); $break ./
+/:$compliance 1.5:/
+ReferenceType2 ::= ClassOrInterface '<' TypeArgumentList3
+/.$putCase consumeTypeArgumentReferenceType2(); $break ./
+/:$readableName ReferenceType2:/
+/:$compliance 1.5:/
+
+TypeArgumentList3 -> TypeArgument3
+TypeArgumentList3 ::= TypeArgumentList ',' TypeArgument3
+/.$putCase consumeTypeArgumentList3(); $break ./
+/:$readableName TypeArgumentList3:/
+/:$compliance 1.5:/
+
+TypeArgument3 -> ReferenceType3
+TypeArgument3 -> Wildcard3
+/:$readableName TypeArgument3:/
+/:$compliance 1.5:/
+
+ReferenceType3 ::= ReferenceType '>>>'
+/.$putCase consumeReferenceType3(); $break ./
+/:$readableName ReferenceType3:/
+/:$compliance 1.5:/
+
+Wildcard ::= TypeAnnotationsopt '?'
+/.$putCase consumeWildcard(); $break ./
+/:$compliance 1.5:/
+Wildcard ::= TypeAnnotationsopt '?' WildcardBounds
+/.$putCase consumeWildcardWithBounds(); $break ./
+/:$readableName Wildcard:/
+/:$compliance 1.5:/
+
+WildcardBounds ::= 'extends' ReferenceType
+/.$putCase consumeWildcardBoundsExtends(); $break ./
+/:$compliance 1.5:/
+WildcardBounds ::= 'super' ReferenceType
+/.$putCase consumeWildcardBoundsSuper(); $break ./
+/:$readableName WildcardBounds:/
+/:$compliance 1.5:/
+
+Wildcard1 ::= TypeAnnotationsopt '?' '>'
+/.$putCase consumeWildcard1(); $break ./
+/:$compliance 1.5:/
+Wildcard1 ::= TypeAnnotationsopt '?' WildcardBounds1
+/.$putCase consumeWildcard1WithBounds(); $break ./
+/:$readableName Wildcard1:/
+/:$compliance 1.5:/
+
+WildcardBounds1 ::= 'extends' ReferenceType1
+/.$putCase consumeWildcardBounds1Extends(); $break ./
+/:$compliance 1.5:/
+WildcardBounds1 ::= 'super' ReferenceType1
+/.$putCase consumeWildcardBounds1Super(); $break ./
+/:$readableName WildcardBounds1:/
+/:$compliance 1.5:/
+
+Wildcard2 ::= TypeAnnotationsopt '?' '>>'
+/.$putCase consumeWildcard2(); $break ./
+/:$compliance 1.5:/
+Wildcard2 ::= TypeAnnotationsopt '?' WildcardBounds2
+/.$putCase consumeWildcard2WithBounds(); $break ./
+/:$readableName Wildcard2:/
+/:$compliance 1.5:/
+
+WildcardBounds2 ::= 'extends' ReferenceType2
+/.$putCase consumeWildcardBounds2Extends(); $break ./
+/:$compliance 1.5:/
+WildcardBounds2 ::= 'super' ReferenceType2
+/.$putCase consumeWildcardBounds2Super(); $break ./
+/:$readableName WildcardBounds2:/
+/:$compliance 1.5:/
+
+Wildcard3 ::= TypeAnnotationsopt '?' '>>>'
+/.$putCase consumeWildcard3(); $break ./
+/:$compliance 1.5:/
+Wildcard3 ::= TypeAnnotationsopt '?' WildcardBounds3
+/.$putCase consumeWildcard3WithBounds(); $break ./
+/:$readableName Wildcard3:/
+/:$compliance 1.5:/
+
+WildcardBounds3 ::= 'extends' ReferenceType3
+/.$putCase consumeWildcardBounds3Extends(); $break ./
+/:$compliance 1.5:/
+WildcardBounds3 ::= 'super' ReferenceType3
+/.$putCase consumeWildcardBounds3Super(); $break ./
+/:$readableName WildcardBound3:/
+/:$compliance 1.5:/
+
+TypeParameterHeader ::= TypeAnnotationsopt Identifier
+/.$putCase consumeTypeParameterHeader(); $break ./
+/:$readableName TypeParameter:/
+/:$compliance 1.5:/
+
+TypeParameters ::= '<' TypeParameterList1
+/.$putCase consumeTypeParameters(); $break ./
+/:$readableName TypeParameters:/
+/:$compliance 1.5:/
+
+TypeParameterList -> TypeParameter
+/:$compliance 1.5:/
+TypeParameterList ::= TypeParameterList ',' TypeParameter
+/.$putCase consumeTypeParameterList(); $break ./
+/:$readableName TypeParameterList:/
+/:$compliance 1.5:/
+
+TypeParameter -> TypeParameterHeader
+/:$compliance 1.5:/
+TypeParameter ::= TypeParameterHeader 'extends' ReferenceType
+/.$putCase consumeTypeParameterWithExtends(); $break ./
+/:$compliance 1.5:/
+TypeParameter ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList
+/.$putCase consumeTypeParameterWithExtendsAndBounds(); $break ./
+/:$readableName TypeParameter:/
+/:$compliance 1.5:/
+
+AdditionalBoundList -> AdditionalBound
+/:$compliance 1.5:/
+AdditionalBoundList ::= AdditionalBoundList AdditionalBound
+/.$putCase consumeAdditionalBoundList(); $break ./
+/:$readableName AdditionalBoundList:/
+
+AdditionalBound ::= '&' ReferenceType
+/.$putCase consumeAdditionalBound(); $break ./
+/:$readableName AdditionalBound:/
+/:$compliance 1.5:/
+
+TypeParameterList1 -> TypeParameter1
+/:$compliance 1.5:/
+TypeParameterList1 ::= TypeParameterList ',' TypeParameter1
+/.$putCase consumeTypeParameterList1(); $break ./
+/:$readableName TypeParameterList1:/
+/:$compliance 1.5:/
+
+TypeParameter1 ::= TypeParameterHeader '>'
+/.$putCase consumeTypeParameter1(); $break ./
+/:$compliance 1.5:/
+TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType1
+/.$putCase consumeTypeParameter1WithExtends(); $break ./
+/:$compliance 1.5:/
+TypeParameter1 ::= TypeParameterHeader 'extends' ReferenceType AdditionalBoundList1
+/.$putCase consumeTypeParameter1WithExtendsAndBounds(); $break ./
+/:$readableName TypeParameter1:/
+/:$compliance 1.5:/
+
+AdditionalBoundList1 -> AdditionalBound1
+/:$compliance 1.5:/
+AdditionalBoundList1 ::= AdditionalBoundList AdditionalBound1
+/.$putCase consumeAdditionalBoundList1(); $break ./
+/:$readableName AdditionalBoundList1:/
+/:$compliance 1.5:/
+
+AdditionalBound1 ::= '&' ReferenceType1
+/.$putCase consumeAdditionalBound1(); $break ./
+/:$readableName AdditionalBound1:/
+/:$compliance 1.5:/
+
+-------------------------------------------------
+-- Duplicate rules to remove ambiguity for (x) --
+-------------------------------------------------
+PostfixExpression_NotName -> Primary
+PostfixExpression_NotName -> PostIncrementExpression
+PostfixExpression_NotName -> PostDecrementExpression
+/:$readableName Expression:/
+
+UnaryExpression_NotName -> PreIncrementExpression
+UnaryExpression_NotName -> PreDecrementExpression
+UnaryExpression_NotName ::= '+' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.PLUS); $break ./
+UnaryExpression_NotName ::= '-' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.MINUS); $break ./
+UnaryExpression_NotName -> UnaryExpressionNotPlusMinus_NotName
+/:$readableName Expression:/
+
+UnaryExpressionNotPlusMinus_NotName -> PostfixExpression_NotName
+UnaryExpressionNotPlusMinus_NotName ::= '~' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.TWIDDLE); $break ./
+UnaryExpressionNotPlusMinus_NotName ::= '!' PushPosition UnaryExpression
+/.$putCase consumeUnaryExpression(OperatorIds.NOT); $break ./
+UnaryExpressionNotPlusMinus_NotName -> CastExpression
+/:$readableName Expression:/
+
+MultiplicativeExpression_NotName -> UnaryExpression_NotName
+MultiplicativeExpression_NotName ::= MultiplicativeExpression_NotName '*' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.MULTIPLY); $break ./
+MultiplicativeExpression_NotName ::= Name '*' UnaryExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); $break ./
+MultiplicativeExpression_NotName ::= MultiplicativeExpression_NotName '/' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.DIVIDE); $break ./
+MultiplicativeExpression_NotName ::= Name '/' UnaryExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.DIVIDE); $break ./
+MultiplicativeExpression_NotName ::= MultiplicativeExpression_NotName '%' UnaryExpression
+/.$putCase consumeBinaryExpression(OperatorIds.REMAINDER); $break ./
+MultiplicativeExpression_NotName ::= Name '%' UnaryExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.REMAINDER); $break ./
+/:$readableName Expression:/
+
+AdditiveExpression_NotName -> MultiplicativeExpression_NotName
+AdditiveExpression_NotName ::= AdditiveExpression_NotName '+' MultiplicativeExpression
+/.$putCase consumeBinaryExpression(OperatorIds.PLUS); $break ./
+AdditiveExpression_NotName ::= Name '+' MultiplicativeExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.PLUS); $break ./
+AdditiveExpression_NotName ::= AdditiveExpression_NotName '-' MultiplicativeExpression
+/.$putCase consumeBinaryExpression(OperatorIds.MINUS); $break ./
+AdditiveExpression_NotName ::= Name '-' MultiplicativeExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.MINUS); $break ./
+/:$readableName Expression:/
+
+ShiftExpression_NotName -> AdditiveExpression_NotName
+ShiftExpression_NotName ::= ShiftExpression_NotName '<<' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LEFT_SHIFT); $break ./
+ShiftExpression_NotName ::= Name '<<' AdditiveExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); $break ./
+ShiftExpression_NotName ::= ShiftExpression_NotName '>>' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); $break ./
+ShiftExpression_NotName ::= Name '>>' AdditiveExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); $break ./
+ShiftExpression_NotName ::= ShiftExpression_NotName '>>>' AdditiveExpression
+/.$putCase consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); $break ./
+ShiftExpression_NotName ::= Name '>>>' AdditiveExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); $break ./
+/:$readableName Expression:/
+
+RelationalExpression_NotName -> ShiftExpression_NotName
+RelationalExpression_NotName ::= ShiftExpression_NotName '<' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LESS); $break ./
+RelationalExpression_NotName ::= Name '<' ShiftExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.LESS); $break ./
+RelationalExpression_NotName ::= ShiftExpression_NotName '>' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.GREATER); $break ./
+RelationalExpression_NotName ::= Name '>' ShiftExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.GREATER); $break ./
+RelationalExpression_NotName ::= RelationalExpression_NotName '<=' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.LESS_EQUAL); $break ./
+RelationalExpression_NotName ::= Name '<=' ShiftExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); $break ./
+RelationalExpression_NotName ::= RelationalExpression_NotName '>=' ShiftExpression
+/.$putCase consumeBinaryExpression(OperatorIds.GREATER_EQUAL); $break ./
+RelationalExpression_NotName ::= Name '>=' ShiftExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); $break ./
+/:$readableName Expression:/
+
+InstanceofExpression_NotName -> RelationalExpression_NotName
+InstanceofExpression_NotName ::= Name 'instanceof' ReferenceType
+/.$putCase consumeInstanceOfExpressionWithName(); $break ./
+InstanceofExpression_NotName ::= InstanceofExpression_NotName 'instanceof' ReferenceType
+/.$putCase consumeInstanceOfExpression(); $break ./
+/:$readableName Expression:/
+
+EqualityExpression_NotName -> InstanceofExpression_NotName
+EqualityExpression_NotName ::= EqualityExpression_NotName '==' InstanceofExpression
+/.$putCase consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); $break ./
+EqualityExpression_NotName ::= Name '==' InstanceofExpression
+/.$putCase consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); $break ./
+EqualityExpression_NotName ::= EqualityExpression_NotName '!=' InstanceofExpression
+/.$putCase consumeEqualityExpression(OperatorIds.NOT_EQUAL); $break ./
+EqualityExpression_NotName ::= Name '!=' InstanceofExpression
+/.$putCase consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); $break ./
+/:$readableName Expression:/
+
+AndExpression_NotName -> EqualityExpression_NotName
+AndExpression_NotName ::= AndExpression_NotName '&' EqualityExpression
+/.$putCase consumeBinaryExpression(OperatorIds.AND); $break ./
+AndExpression_NotName ::= Name '&' EqualityExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.AND); $break ./
+/:$readableName Expression:/
+
+ExclusiveOrExpression_NotName -> AndExpression_NotName
+ExclusiveOrExpression_NotName ::= ExclusiveOrExpression_NotName '^' AndExpression
+/.$putCase consumeBinaryExpression(OperatorIds.XOR); $break ./
+ExclusiveOrExpression_NotName ::= Name '^' AndExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.XOR); $break ./
+/:$readableName Expression:/
+
+InclusiveOrExpression_NotName -> ExclusiveOrExpression_NotName
+InclusiveOrExpression_NotName ::= InclusiveOrExpression_NotName '|' ExclusiveOrExpression
+/.$putCase consumeBinaryExpression(OperatorIds.OR); $break ./
+InclusiveOrExpression_NotName ::= Name '|' ExclusiveOrExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.OR); $break ./
+/:$readableName Expression:/
+
+ConditionalAndExpression_NotName -> InclusiveOrExpression_NotName
+ConditionalAndExpression_NotName ::= ConditionalAndExpression_NotName '&&' InclusiveOrExpression
+/.$putCase consumeBinaryExpression(OperatorIds.AND_AND); $break ./
+ConditionalAndExpression_NotName ::= Name '&&' InclusiveOrExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.AND_AND); $break ./
+/:$readableName Expression:/
+
+ConditionalOrExpression_NotName -> ConditionalAndExpression_NotName
+ConditionalOrExpression_NotName ::= ConditionalOrExpression_NotName '||' ConditionalAndExpression
+/.$putCase consumeBinaryExpression(OperatorIds.OR_OR); $break ./
+ConditionalOrExpression_NotName ::= Name '||' ConditionalAndExpression
+/.$putCase consumeBinaryExpressionWithName(OperatorIds.OR_OR); $break ./
+/:$readableName Expression:/
+
+ConditionalExpression_NotName -> ConditionalOrExpression_NotName
+ConditionalExpression_NotName ::= ConditionalOrExpression_NotName '?' Expression ':' ConditionalExpression
+/.$putCase consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; $break ./
+ConditionalExpression_NotName ::= Name '?' Expression ':' ConditionalExpression
+/.$putCase consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ; $break ./
+/:$readableName Expression:/
+
+AssignmentExpression_NotName -> ConditionalExpression_NotName
+AssignmentExpression_NotName -> Assignment
+/:$readableName Expression:/
+
+Expression_NotName -> AssignmentExpression_NotName
+/:$readableName Expression:/
+-----------------------------------------------
+-- 1.5 features : end of generics
+-----------------------------------------------
+-----------------------------------------------
+-- 1.5 features : annotation - Metadata feature jsr175
+-----------------------------------------------
+AnnotationTypeDeclarationHeaderName ::= Modifiers '@' PushRealModifiers interface Identifier
+/.$putCase consumeAnnotationTypeDeclarationHeaderName() ; $break ./
+/:$compliance 1.5:/
+AnnotationTypeDeclarationHeaderName ::= Modifiers '@' PushRealModifiers interface Identifier TypeParameters
+/.$putCase consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; $break ./
+/:$compliance 1.5:/
+AnnotationTypeDeclarationHeaderName ::= '@' PushModifiersForHeader interface Identifier TypeParameters
+/.$putCase consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; $break ./
+/:$compliance 1.5:/
+AnnotationTypeDeclarationHeaderName ::= '@' PushModifiersForHeader interface Identifier
+/.$putCase consumeAnnotationTypeDeclarationHeaderName() ; $break ./
+/:$readableName AnnotationTypeDeclarationHeaderName:/
+/:$compliance 1.5:/
+
+AnnotationTypeDeclarationHeader ::= AnnotationTypeDeclarationHeaderName ClassHeaderExtendsopt ClassHeaderImplementsopt
+/.$putCase consumeAnnotationTypeDeclarationHeader() ; $break ./
+/:$readableName AnnotationTypeDeclarationHeader:/
+/:$compliance 1.5:/
+
+AnnotationTypeDeclaration ::= AnnotationTypeDeclarationHeader AnnotationTypeBody
+/.$putCase consumeAnnotationTypeDeclaration() ; $break ./
+/:$readableName AnnotationTypeDeclaration:/
+/:$compliance 1.5:/
+
+AnnotationTypeBody ::= '{' AnnotationTypeMemberDeclarationsopt '}'
+/:$readableName AnnotationTypeBody:/
+/:$compliance 1.5:/
+
+AnnotationTypeMemberDeclarationsopt ::= $empty
+/.$putCase consumeEmptyAnnotationTypeMemberDeclarationsopt() ; $break ./
+/:$compliance 1.5:/
+AnnotationTypeMemberDeclarationsopt ::= NestedType AnnotationTypeMemberDeclarations
+/.$putCase consumeAnnotationTypeMemberDeclarationsopt() ; $break ./
+/:$readableName AnnotationTypeMemberDeclarations:/
+/:$compliance 1.5:/
+
+AnnotationTypeMemberDeclarations -> AnnotationTypeMemberDeclaration
+/:$compliance 1.5:/
+AnnotationTypeMemberDeclarations ::= AnnotationTypeMemberDeclarations AnnotationTypeMemberDeclaration
+/.$putCase consumeAnnotationTypeMemberDeclarations() ; $break ./
+/:$readableName AnnotationTypeMemberDeclarations:/
+/:$compliance 1.5:/
+
+AnnotationMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+/.$putCase consumeMethodHeaderNameWithTypeParameters(true); $break ./
+AnnotationMethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+/.$putCase consumeMethodHeaderName(true); $break ./
+/:$readableName MethodHeaderName:/
+/:$compliance 1.5:/
+
+AnnotationMethodHeaderDefaultValueopt ::= $empty
+/.$putCase consumeEmptyMethodHeaderDefaultValue() ; $break ./
+/:$readableName MethodHeaderDefaultValue:/
+/:$compliance 1.5:/
+AnnotationMethodHeaderDefaultValueopt ::= DefaultValue
+/.$putCase consumeMethodHeaderDefaultValue(); $break ./
+/:$readableName MethodHeaderDefaultValue:/
+/:$compliance 1.5:/
+
+AnnotationMethodHeader ::= AnnotationMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt
+/.$putCase consumeMethodHeader(); $break ./
+/:$readableName AnnotationMethodHeader:/
+/:$compliance 1.5:/
+
+AnnotationTypeMemberDeclaration ::= AnnotationMethodHeader ';'
+/.$putCase consumeAnnotationTypeMemberDeclaration() ; $break ./
+/:$compliance 1.5:/
+AnnotationTypeMemberDeclaration -> ConstantDeclaration
+/:$compliance 1.5:/
+AnnotationTypeMemberDeclaration -> ConstructorDeclaration
+/:$compliance 1.5:/
+AnnotationTypeMemberDeclaration -> TypeDeclaration
+/:$readableName AnnotationTypeMemberDeclaration:/
+/:$compliance 1.5:/
+
+DefaultValue ::= 'default' MemberValue
+/:$readableName DefaultValue:/
+/:$compliance 1.5:/
+
+Annotation -> NormalAnnotation
+/:$compliance 1.5:/
+Annotation -> MarkerAnnotation
+/:$compliance 1.5:/
+Annotation -> SingleMemberAnnotation
+/:$readableName Annotation:/
+/:$compliance 1.5:/
+
+AnnotationName ::= '@' UnannotatableName
+/.$putCase consumeAnnotationName() ; $break ./
+/:$readableName AnnotationName:/
+/:$compliance 1.5:/
+/:$recovery_template @ Identifier:/
+
+NormalAnnotation ::= AnnotationName '(' MemberValuePairsopt ')'
+/.$putCase consumeNormalAnnotation(false) ; $break ./
+/:$readableName NormalAnnotation:/
+/:$compliance 1.5:/
+
+MemberValuePairsopt ::= $empty
+/.$putCase consumeEmptyMemberValuePairsopt() ; $break ./
+/:$compliance 1.5:/
+MemberValuePairsopt -> MemberValuePairs
+/:$readableName MemberValuePairsopt:/
+/:$compliance 1.5:/
+
+MemberValuePairs -> MemberValuePair
+/:$compliance 1.5:/
+MemberValuePairs ::= MemberValuePairs ',' MemberValuePair
+/.$putCase consumeMemberValuePairs() ; $break ./
+/:$readableName MemberValuePairs:/
+/:$compliance 1.5:/
+
+MemberValuePair ::= SimpleName '=' EnterMemberValue MemberValue ExitMemberValue
+/.$putCase consumeMemberValuePair() ; $break ./
+/:$readableName MemberValuePair:/
+/:$compliance 1.5:/
+
+EnterMemberValue ::= $empty
+/.$putCase consumeEnterMemberValue() ; $break ./
+/:$readableName EnterMemberValue:/
+/:$compliance 1.5:/
+
+ExitMemberValue ::= $empty
+/.$putCase consumeExitMemberValue() ; $break ./
+/:$readableName ExitMemberValue:/
+/:$compliance 1.5:/
+
+MemberValue -> ConditionalExpression_NotName
+/:$compliance 1.5:/
+MemberValue ::= Name
+/.$putCase consumeMemberValueAsName() ; $break ./
+/:$compliance 1.5:/
+MemberValue -> Annotation
+/:$compliance 1.5:/
+MemberValue -> MemberValueArrayInitializer
+/:$readableName MemberValue:/
+/:$recovery_template Identifier:/
+/:$compliance 1.5:/
+
+MemberValueArrayInitializer ::= EnterMemberValueArrayInitializer '{' PushLeftBrace MemberValues ',' '}'
+/.$putCase consumeMemberValueArrayInitializer() ; $break ./
+/:$compliance 1.5:/
+MemberValueArrayInitializer ::= EnterMemberValueArrayInitializer '{' PushLeftBrace MemberValues '}'
+/.$putCase consumeMemberValueArrayInitializer() ; $break ./
+/:$compliance 1.5:/
+MemberValueArrayInitializer ::= EnterMemberValueArrayInitializer '{' PushLeftBrace ',' '}'
+/.$putCase consumeEmptyMemberValueArrayInitializer() ; $break ./
+/:$compliance 1.5:/
+MemberValueArrayInitializer ::= EnterMemberValueArrayInitializer '{' PushLeftBrace '}'
+/.$putCase consumeEmptyMemberValueArrayInitializer() ; $break ./
+/:$readableName MemberValueArrayInitializer:/
+/:$compliance 1.5:/
+
+EnterMemberValueArrayInitializer ::= $empty
+/.$putCase consumeEnterMemberValueArrayInitializer() ; $break ./
+/:$readableName EnterMemberValueArrayInitializer:/
+/:$compliance 1.5:/
+
+MemberValues -> MemberValue
+/:$compliance 1.5:/
+MemberValues ::= MemberValues ',' MemberValue
+/.$putCase consumeMemberValues() ; $break ./
+/:$readableName MemberValues:/
+/:$compliance 1.5:/
+
+MarkerAnnotation ::= AnnotationName
+/.$putCase consumeMarkerAnnotation(false) ; $break ./
+/:$readableName MarkerAnnotation:/
+/:$compliance 1.5:/
+
+SingleMemberAnnotationMemberValue ::= MemberValue
+/.$putCase consumeSingleMemberAnnotationMemberValue() ; $break ./
+/:$readableName MemberValue:/
+/:$compliance 1.5:/
+
+SingleMemberAnnotation ::= AnnotationName '(' SingleMemberAnnotationMemberValue ')'
+/.$putCase consumeSingleMemberAnnotation(false) ; $break ./
+/:$readableName SingleMemberAnnotation:/
+/:$compliance 1.5:/
+--------------------------------------
+-- 1.5 features : end of annotation --
+--------------------------------------
+
+-----------------------------------
+-- 1.5 features : recovery rules --
+-----------------------------------
+RecoveryMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+/.$putCase consumeRecoveryMethodHeaderNameWithTypeParameters(); $break ./
+/:$compliance 1.5:/
+RecoveryMethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+/.$putCase consumeRecoveryMethodHeaderName(); $break ./
+/:$readableName MethodHeaderName:/
+RecoveryMethodHeaderName ::= ModifiersWithDefault TypeParameters Type 'Identifier' '('
+/.$putCase consumeRecoveryMethodHeaderNameWithTypeParameters(); $break ./
+/:$compliance 1.5:/
+RecoveryMethodHeaderName ::= ModifiersWithDefault Type 'Identifier' '('
+/.$putCase consumeRecoveryMethodHeaderName(); $break ./
+/:$readableName MethodHeaderName:/
+
+RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims AnnotationMethodHeaderDefaultValueopt
+/.$putCase consumeMethodHeader(); $break ./
+RecoveryMethodHeader ::= RecoveryMethodHeaderName FormalParameterListopt MethodHeaderRightParen MethodHeaderExtendedDims MethodHeaderThrowsClause
+/.$putCase consumeMethodHeader(); $break ./
+/:$readableName MethodHeader:/
+-----------------------------------
+-- 1.5 features : recovery rules --
+-----------------------------------
+
+/.	}
+}./
+
+$names
+
+PLUS_PLUS ::=    '++'   
+MINUS_MINUS ::=    '--'   
+EQUAL_EQUAL ::=    '=='   
+LESS_EQUAL ::=    '<='   
+GREATER_EQUAL ::=    '>='   
+NOT_EQUAL ::=    '!='   
+LEFT_SHIFT ::=    '<<'   
+RIGHT_SHIFT ::=    '>>'   
+UNSIGNED_RIGHT_SHIFT ::=    '>>>'  
+PLUS_EQUAL ::=    '+='   
+MINUS_EQUAL ::=    '-='   
+MULTIPLY_EQUAL ::=    '*='   
+DIVIDE_EQUAL ::=    '/='   
+AND_EQUAL ::=    '&='   
+OR_EQUAL ::=    '|='   
+XOR_EQUAL ::=    '^='   
+REMAINDER_EQUAL ::=    '%='   
+LEFT_SHIFT_EQUAL ::=    '<<='  
+RIGHT_SHIFT_EQUAL ::=    '>>='  
+UNSIGNED_RIGHT_SHIFT_EQUAL ::=    '>>>=' 
+OR_OR ::=    '||'   
+AND_AND ::=    '&&'
+PLUS ::=    '+'    
+MINUS ::=    '-'    
+NOT ::=    '!'    
+REMAINDER ::=    '%'    
+XOR ::=    '^'    
+AND ::=    '&'    
+MULTIPLY ::=    '*'    
+OR ::=    '|'    
+TWIDDLE ::=    '~'    
+DIVIDE ::=    '/'    
+GREATER ::=    '>'    
+LESS ::=    '<'    
+LPAREN ::=    '('    
+RPAREN ::=    ')'    
+LBRACE ::=    '{'    
+RBRACE ::=    '}'    
+LBRACKET ::=    '['    
+RBRACKET ::=    ']'    
+SEMICOLON ::=    ';'    
+QUESTION ::=    '?'    
+COLON ::=    ':'    
+COMMA ::=    ','    
+DOT ::=    '.'    
+EQUAL ::=    '='    
+AT ::=    '@'
+AT308 ::= '@'
+AT308DOTDOTDOT ::= '@'
+ELLIPSIS ::=    '...'    
+ARROW ::= '->'
+COLON_COLON ::= '::'
+
+$end
+-- need a carriage return after the $end
diff --git a/org.eclipse.jdt.core/jdt_core_style.css b/org.eclipse.jdt.core/jdt_core_style.css
new file mode 100644
index 0000000..f9a680a
--- /dev/null
+++ b/org.eclipse.jdt.core/jdt_core_style.css
@@ -0,0 +1,18 @@
+@charset "iso-8859-1";
+TD.title1
+{
+font-family: "Verdana", "Arial", "Helvetica";
+}												
+B.title1
+{
+font-family:"Times New Roman";
+}
+TD.title2
+{
+font-family: "Arial", "Helvetica", "sans-serif";   
+color: #8080ff
+}
+TD.title3
+{
+font-family: "Arial", "Helvetica", "sans-serif";
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
new file mode 100644
index 0000000..7039208
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.core.util.KeyKind;
+import org.eclipse.jdt.internal.core.util.KeyToSignature;
+
+/**
+ * Utility class to decode or create a binding key.
+ * <p>
+ * This class is not intended to be subclassed by clients.
+ * </p>
+ *
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @since 3.1
+ */
+public final class BindingKey {
+
+	private String key;
+
+	/**
+	 * Creates a new binding key.
+	 *
+	 * @param key the key to decode
+	 */
+	public BindingKey(String key) {
+		this.key = key;
+	}
+
+	/**
+	 * Creates a new array type binding key from the given type binding key and the given array dimension.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createArrayTypeBindingKey("Ljava/lang/Object;", 1) -> "[Ljava/lang/Object;"
+	 * createArrayTypeBindingKey("I", 2) -> "[[I"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeKey the binding key of the given type
+	 * @param arrayDimension the given array dimension
+	 * @return a new array type binding key
+	 */
+	public static String createArrayTypeBindingKey(String typeKey, int arrayDimension) {
+		// Note this implementation is heavily dependent on ArrayTypeBinding#computeUniqueKey()
+		StringBuffer buffer = new StringBuffer();
+		while (arrayDimension-- > 0)
+			buffer.append('[');
+		buffer.append(typeKey);
+		return buffer.toString();
+	}
+
+	/**
+	 * Creates a new parameterized type binding key from the given generic type binding key and the given argument type binding keys.
+	 * If the argument type keys array is empty, then a raw type binding key is created.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createParameterizedTypeBindingKey(
+	 *     "Ljava/util/Map&lt;TK;TV;&gt;;",
+	 *     new String[] {"Ljava/lang/String;", "Ljava/lang/Object;"}) -&gt;
+	 *       "Ljava/util/Map&lt;Ljava/lang/String;Ljava/lang/Object;&gt;;"
+	 * createParameterizedTypeBindingKey(
+	 *     "Ljava/util/List&lt;TE;&gt;;", new String[] {}) -&gt;
+	 *       "Ljava/util/List&lt;&gt;;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param genericTypeKey the binding key of the generic type
+	 * @param argumentTypeKeys the possibly empty list of binding keys of argument types
+	 * @return a new parameterized type binding key
+	 */
+	public static String createParameterizedTypeBindingKey(String genericTypeKey, String[] argumentTypeKeys) {
+		// Note this implementation is heavily dependent on ParameterizedTypeBinding#computeUniqueKey() and its subclasses
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(Signature.getTypeErasure(genericTypeKey));
+		buffer.insert(buffer.length()-1, '<');
+		for (int i = 0, length = argumentTypeKeys.length; i < length; i++) {
+			String argumentTypeKey = argumentTypeKeys[i];
+			buffer.insert(buffer.length()-1, argumentTypeKey);
+		}
+		buffer.insert(buffer.length()-1, '>');
+		return buffer.toString();
+	}
+
+	/**
+	 * Creates a new type binding key from the given type name. The type name must be either
+	 * a fully qualified name, an array type name or a primitive type name.
+	 * If the type name is fully qualified, then it is expected to be dot-based.
+	 * Note that inner types, generic types and parameterized types are not supported.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createTypeBindingKey("int") -> "I"
+	 * createTypeBindingKey("java.lang.String") -> "Ljava/lang/String;"
+	 * createTypeBindingKey("boolean[]") -> "[Z"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeName the possibly qualified type name
+	 * @return a new type binding key
+	 */
+	public static String createTypeBindingKey(String typeName) {
+		// Note this implementation is heavily dependent on TypeBinding#computeUniqueKey() and its subclasses
+		return Signature.createTypeSignature(typeName.replace('.', '/'), true/*resolved*/);
+	}
+
+	/**
+	 * Creates a new type variable binding key from the given type variable name and the given declaring key.
+	 * The declaring key can either be a type binding key or a method binding key.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createTypeVariableBindingKey("T", "Ljava/util/List&lt;TE;&gt;;") -&gt;
+	 *   "Ljava/util/List&lt;TE;&gt;;:TT;"
+	 * createTypeVariableBindingKey("SomeTypeVariable", "Lp/X;.foo()V") -&gt;
+	 *   "Lp/X;.foo()V:TSomeTypeVariable;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeVariableName the name of the given type variable
+	 * @param declaringKey the binding key of the type or method the type variable belongs to
+	 * @return a new type variable binding key
+	 */
+	public static String createTypeVariableBindingKey(String typeVariableName, String declaringKey) {
+		// Note this implementation is heavily dependent on TypeVariableBinding#computeUniqueKey()
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(declaringKey);
+		buffer.append(':');
+		buffer.append('T');
+		buffer.append(typeVariableName);
+		buffer.append(';');
+		return buffer.toString();
+	}
+
+	/**
+	 * Creates a new wildcard type binding key from the given type binding key and the given wildcard kind
+	 * (one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}.
+	 * If the wildcard is {@link Signature#C_STAR}, the given type binding key is ignored.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createWilcardTypeBindingKey(null, Signature.C_STAR) -&gt; "*"
+	 * createWilcardTypeBindingKey("Ljava/util/List&lt;TE;&gt;;",
+	 *    Signature.C_SUPER) -&gt; "-Ljava/util/List&lt;TE;&gt;;"
+	 * createWilcardTypeBindingKey("Ljava/util/ArrayList;", Signature.C_EXTENDS) -&gt;
+	 *    "+Ljava/util/ArrayList;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeKey the binding key of the given type
+	 * @param kind one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}
+	 * @return a new wildcard type binding key
+	 * @deprecated  This method is missing crucial information necessary for proper wildcard binding key creation.
+	 * @see org.eclipse.jdt.core.BindingKey#createWildcardTypeBindingKey(String, char, String, int)
+	 */
+	public static String createWilcardTypeBindingKey(String typeKey, char kind) {
+		// Note this implementation is supposed to closely follow the behavior in WildcardBinding#computeUniqueKey()
+		// but it doesn't and hence the deprecation. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=234609
+		switch (kind) {
+			case Signature.C_STAR:
+				return "*"; //$NON-NLS-1$
+			case Signature.C_SUPER:
+				return '-' + typeKey;
+			case Signature.C_EXTENDS:
+				return '+' + typeKey;
+		}
+		return null;
+	}
+
+	/**
+	 * Creates a new wildcard type binding key from the given generic type binding key, the given wildcard
+	 * kind (one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}
+	 * the given bound type binding key and the given rank. If the wildcard kind is {@link Signature#C_STAR},
+	 * the given bound type binding key is ignored.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createWildcardTypeBindingKey("Ljava/util/ArrayList;", Signature.C_STAR, null, 0) -&gt; "Ljava/util/ArrayList;{0}*"
+	 * createWildcardTypeBindingKey("Ljava/util/ArrayList;", Signature.C_SUPER, "Ljava/lang/String;", 0) -&gt; "Ljava/util/ArrayList;{0}-Ljava/lang/String;"
+	 * createWildcardTypeBindingKey("Ljava/util/HashMap;", Signature.C_EXTENDS, "Ljava/lang/String;", 1) -&gt;
+	 *    "Ljava/util/HashMap;{1}+Ljava/lang/String;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param genericTypeKey the binding key of the generic type
+	 * @param boundKind one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}
+	 * @param boundTypeKey the binding key of the bounding type.
+	 * @param rank the relative position of this wild card type in the parameterization of the generic type. 
+	 * @return a new wildcard type binding key
+	 * @since 3.5
+	 */
+	
+	public static String createWildcardTypeBindingKey(String genericTypeKey, char boundKind, String boundTypeKey, int rank) {
+		// Note this implementation is heavily dependent on WildcardBinding#computeUniqueKey()
+		String wildCardKey;
+		switch (boundKind) {
+			case Signature.C_STAR:
+				wildCardKey = new String(TypeConstants.WILDCARD_STAR);
+				break;
+			case Signature.C_SUPER:
+				wildCardKey = new String(TypeConstants.WILDCARD_MINUS) + boundTypeKey;
+				break;
+			case Signature.C_EXTENDS:
+				wildCardKey = new String(TypeConstants.WILDCARD_PLUS) + boundTypeKey;
+				break;
+			default:
+				return null;
+		}
+		return genericTypeKey + '{' + rank + '}' + wildCardKey;
+	}
+
+	/**
+	 * Returns the binding key of the declaring type of the element represented by this binding key. If the binding key
+	 * does not represent a member or if the member doesn't have a declaring type, returns <code>null</code>.
+	 * 
+	 * <p>
+	 * Note that only binding keys for references to methods and fields
+	 * are fully supported. The binding keys for declarations will not have type parameters.
+	 * 
+	 * @return the type binding key or <code>null</code>
+	 * @since 3.7.1
+	 */
+	public BindingKey getDeclaringType() {
+		int end = this.key.lastIndexOf(Signature.C_DOT);
+		if (end == -1) {
+			end = this.key.lastIndexOf(Signature.C_DOLLAR); // for inner types
+			if (end == -1) return null;
+		}
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		if ((kind.flags & KeyKind.F_LOCAL_VAR) != 0) {
+			// declaring type for locals doesn't make sense, hence return null.
+			return null;
+		}
+		String typeKey = this.key.substring(0, end);
+		if (typeKey.charAt(typeKey.length()-1) != Signature.C_SEMICOLON)  {
+			typeKey += Signature.C_SEMICOLON;
+		}
+		return new BindingKey(typeKey);
+	}
+	/**
+	 * Returns the thrown exception signatures of the element represented by this binding key.
+	 * If this binding key does not  represent a method or does not throw any exception,
+	 * returns an empty array.
+	 *
+	 * @return the thrown exceptions signatures
+	 * @since 3.3
+	 */
+	public String[] getThrownExceptions() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.THROWN_EXCEPTIONS);
+		keyToSignature.parse();
+		return keyToSignature.getThrownExceptions();
+	}
+
+	/**
+	 * Returns the type argument signatures of the element represented by this binding key.
+	 * If this binding key doesn't represent a parameterized type or a parameterized method,
+	 * returns an empty array.
+	 *
+	 * @return the type argument signatures
+	 */
+	public String[] getTypeArguments() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.TYPE_ARGUMENTS);
+		keyToSignature.parse();
+		return keyToSignature.getTypeArguments();
+	}
+
+	/**
+	 * Returns whether this binding key represents a raw type.
+	 *
+	 * @return whether this binding key represents a raw type
+	 */
+	public boolean isRawType() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_RAW_TYPE) != 0;
+	}
+
+	/**
+	 * Returns whether this binding key represents a parameterized type, or if its declaring type is a parameterized type.
+	 *
+	 * @return whether this binding key represents a parameterized type
+	 */
+	public boolean isParameterizedType() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_PARAMETERIZED_TYPE) != 0;
+	}
+
+	/**
+	 * Returns whether this binding key represents a parameterized method, or if its declaring method is a parameterized method.
+	 *
+	 * @return whether this binding key represents a parameterized method
+	 */
+	public boolean isParameterizedMethod() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_PARAMETERIZED_METHOD) != 0;
+	}
+
+	/**
+	 * Transforms this binding key into a resolved signature.
+	 * If this binding key represents a field, the returned signature is
+	 * the field type's signature.
+	 *
+	 * @return the resolved signature for this binding key
+	 * @see Signature
+	 * @since 3.2
+	 */
+	public String toSignature() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.SIGNATURE);
+		keyToSignature.parse();
+		return keyToSignature.signature.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.key;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java
new file mode 100644
index 0000000..ac5a2ac
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.EventObject;
+
+/**
+ * A buffer changed event describes how a buffer has changed. These events are
+ * used in <code>IBufferChangedListener</code> notifications.
+ * <p>
+ * For text insertions, <code>getOffset</code> is the offset
+ * of the first inserted character, <code>getText</code> is the
+ * inserted text, and <code>getLength</code> is 0.
+ * </p>
+ * <p>
+ * For text removals, <code>getOffset</code> is the offset
+ * of the first removed character, <code>getText</code> is <code>null</code>,
+ * and <code>getLength</code> is the length of the text that was removed.
+ * </p>
+ * <p>
+ * For replacements (including <code>IBuffer.setContents</code>),
+ * <code>getOffset</code> is the offset
+ * of the first replaced character, <code>getText</code> is the replacement
+ * text, and <code>getLength</code> is the length of the original text
+ * that was replaced.
+ * </p>
+ * <p>
+ * When a buffer is closed, <code>getOffset</code> is 0, <code>getLength</code>
+ * is 0, and <code>getText</code> is <code>null</code>.
+ * </p>
+ *
+ * @see IBuffer
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class BufferChangedEvent extends EventObject {
+
+	/**
+	 * The length of text that has been modified in the buffer.
+	 */
+	private int length;
+
+	/**
+	 * The offset into the buffer where the modification took place.
+	 */
+	private int offset;
+
+	/**
+	 * The text that was modified.
+	 */
+	private String text;
+
+	private static final long serialVersionUID = 655379473891745999L; // backward compatible
+
+/**
+ * Creates a new buffer changed event indicating that the given buffer has changed.
+ *
+ * @param buffer the given buffer
+ * @param offset the given offset
+ * @param length the given length
+ * @param text the given text
+ */
+public BufferChangedEvent(IBuffer buffer, int offset, int length, String text) {
+	super(buffer);
+	this.offset = offset;
+	this.length = length;
+	this.text = text;
+}
+/**
+ * Returns the buffer which has changed.
+ *
+ * @return the buffer affected by the change
+ */
+public IBuffer getBuffer() {
+	return (IBuffer) this.source;
+}
+/**
+ * Returns the length of text removed or replaced in the buffer, or
+ * 0 if text has been inserted into the buffer.
+ *
+ * @return the length of the original text fragment modified by the
+ *   buffer change (<code> 0 </code> in case of insertion).
+ */
+public int getLength() {
+	return this.length;
+}
+/**
+ * Returns the index of the first character inserted, removed, or replaced
+ * in the buffer.
+ *
+ * @return the source offset of the textual manipulation in the buffer
+ */
+public int getOffset() {
+	return this.offset;
+}
+/**
+ * Returns the text that was inserted, the replacement text,
+ * or <code>null</code> if text has been removed.
+ *
+ * @return the text corresponding to the buffer change (<code> null </code>
+ *   in case of deletion).
+ */
+public String getText() {
+	return this.text;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java
new file mode 100644
index 0000000..a1c437b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java
@@ -0,0 +1,367 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added support for requesting updates of a particular
+ *                       container for generic container operations.
+ * 						 - canUpdateClasspathContainer(IPath, IJavaProject)
+ * 						 - requestClasspathContainerUpdate(IPath, IJavaProject, IClasspathContainer)
+ *     IBM Corporation - allow initializers to provide a readable description
+ *                       of a container reference, ahead of actual resolution.
+ * 						 - getDescription(IPath, IJavaProject)
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.internal.core.JavaModelStatus;
+
+/**
+ * Abstract base implementation of all classpath container initializer.
+ * Classpath variable containers are used in conjunction with the
+ * "org.eclipse.jdt.core.classpathContainerInitializer" extension point.
+ * <p>
+ * Clients should subclass this class to implement a specific classpath
+ * container initializer. The subclass must have a public 0-argument
+ * constructor and a concrete implementation of {@link #initialize(IPath, IJavaProject)}.
+ * <p>
+ * Multiple classpath containers can be registered, each of them declares
+ * the container ID they can handle, so as to narrow the set of containers they
+ * can resolve, in other words, a container initializer is guaranteed to only be
+ * activated to resolve containers which match the ID they registered onto.
+ * <p>
+ * In case multiple container initializers collide on the same container ID, the first
+ * registered one will be invoked.
+ *
+ * @see IClasspathEntry
+ * @see IClasspathContainer
+ * @since 2.0
+ */
+public abstract class ClasspathContainerInitializer {
+
+	/**
+	 * Status code indicating that an attribute is not supported.
+	 *
+	 * @see #getAccessRulesStatus(IPath, IJavaProject)
+	 * @see #getAttributeStatus(IPath, IJavaProject, String)
+	 * @see #getSourceAttachmentStatus(IPath, IJavaProject)
+	 *
+	 * @since 3.3
+	 */
+	public static final int ATTRIBUTE_NOT_SUPPORTED = 1;
+
+	/**
+	 * Status code indicating that an attribute is not modifiable.
+	 *
+	 * @see #getAccessRulesStatus(IPath, IJavaProject)
+	 * @see #getAttributeStatus(IPath, IJavaProject, String)
+	 * @see #getSourceAttachmentStatus(IPath, IJavaProject)
+	 *
+	 * @since 3.3
+	 */
+	public static final int ATTRIBUTE_READ_ONLY = 2;
+
+   /**
+     * Creates a new classpath container initializer.
+     */
+    public ClasspathContainerInitializer() {
+    	// a classpath container initializer must have a public 0-argument constructor
+    }
+
+    /**
+     * Binds a classpath container to a <code>IClasspathContainer</code> for a given project,
+     * or silently fails if unable to do so.
+     * <p>
+     * A container is identified by a container path, which must be formed of two segments.
+     * The first segment is used as a unique identifier (which this initializer did register onto), and
+     * the second segment can be used as an additional hint when performing the resolution.
+     * <p>
+     * The initializer is invoked if a container path needs to be resolved for a given project, and no
+     * value for it was recorded so far. The implementation of the initializer would typically set the
+     * corresponding container using <code>JavaCore#setClasspathContainer</code>.
+     * <p>
+     * A container initialization can be indirectly performed while attempting to resolve a project
+     * classpath using <code>IJavaProject#getResolvedClasspath(</code>; or directly when using
+     * <code>JavaCore#getClasspathContainer</code>. During the initialization process, any attempt
+     * to further obtain the same container will simply return <code>null</code> so as to avoid an
+     * infinite regression of initializations.
+     * <p>
+     * A container initialization may also occur indirectly when setting a project classpath, as the operation
+     * needs to resolve the classpath for validation purpose. While the operation is in progress, a referenced
+     * container initializer may be invoked. If the initializer further tries to access the referring project classpath,
+     * it will not see the new assigned classpath until the operation has completed. Note that once the Java
+     * change notification occurs (at the end of the operation), the model has been updated, and the project
+     * classpath can be queried normally.
+	 * <p>
+	 * This method is called by the Java model to give the party that defined
+	 * this particular kind of classpath container the chance to install
+	 * classpath container objects that will be used to convert classpath
+	 * container entries into simpler classpath entries. The method is typically
+	 * called exactly once for a given Java project and classpath container
+	 * entry. This method must not be called by other clients.
+	 * <p>
+	 * There are a wide variety of conditions under which this method may be
+	 * invoked. To ensure that the implementation does not interfere with
+	 * correct functioning of the Java model, the implementation should use
+	 * only the following Java model APIs:
+	 * <ul>
+	 * <li>{@link JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)}</li>
+	 * <li>{@link JavaCore#getClasspathContainer(IPath, IJavaProject)}</li>
+	 * <li>{@link JavaCore#create(org.eclipse.core.resources.IWorkspaceRoot)}</li>
+	 * <li>{@link JavaCore#create(org.eclipse.core.resources.IProject)}</li>
+	 * <li>{@link IJavaModel#getJavaProjects()}</li>
+	 * <li>Java element operations marked as "handle-only"</li>
+	 * </ul>
+	 * The effects of using other Java model APIs are unspecified.
+	 * </p>
+	 *
+     * @param containerPath a two-segment path (ID/hint) identifying the container that needs
+     * 	to be resolved
+     * @param project the Java project in which context the container is to be resolved.
+     *    This allows generic containers to be bound with project specific values.
+     * @throws CoreException if an exception occurs during the initialization
+     *
+     * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+     * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)
+     * @see IClasspathContainer
+     */
+    public abstract void initialize(IPath containerPath, IJavaProject project) throws CoreException;
+
+    /**
+     * Returns <code>true</code> if this container initializer can be requested to perform updates
+     * on its own container values. If so, then an update request will be performed using
+     * {@link #requestClasspathContainerUpdate(IPath, IJavaProject, IClasspathContainer)}.
+     * <p>
+     * @param containerPath the path of the container which requires to be updated
+     * @param project the project for which the container is to be updated
+     * @return returns <code>true</code> if the container can be updated
+     * @since 2.1
+     */
+    public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
+
+		// By default, classpath container initializers do not accept updating containers
+    	return false;
+    }
+
+	/**
+	 * Request a registered container definition to be updated according to a container suggestion. The container suggestion
+	 * only acts as a place-holder to pass along the information to update the matching container definition(s) held by the
+	 * container initializer. In particular, it is not expected to store the container suggestion as is, but rather adjust
+	 * the actual container definition based on suggested changes.
+	 * <p>
+	 * IMPORTANT: In reaction to receiving an update request, a container initializer will update the corresponding
+	 * container definition (after reconciling changes) at its earliest convenience, using
+	 * {@link JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)}.
+	 * Until it does so, the update will not be reflected in the Java Model.
+	 * <p>
+	 * In order to anticipate whether the container initializer allows to update its containers, the predicate
+	 * {@link #canUpdateClasspathContainer(IPath, IJavaProject)} should be used.
+	 * <p>
+	 * @param containerPath the path of the container which requires to be updated
+     * @param project the project for which the container is to be updated
+	 * @param containerSuggestion a suggestion to update the corresponding container definition
+	 * @throws CoreException when <code>JavaCore#setClasspathContainer</code> would throw any.
+	 * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], org.eclipse.core.runtime.IProgressMonitor)
+	 * @see ClasspathContainerInitializer#canUpdateClasspathContainer(IPath, IJavaProject)
+	 * @since 2.1
+	 */
+
+    public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException {
+
+		// By default, classpath container initializers do not accept updating containers
+    }
+
+	/**
+	 * Returns a readable description for a container path. A readable description for a container path can be
+	 * used for improving the display of references to container, without actually needing to resolve them.
+	 * A good implementation should answer a description consistent with the description of the associated
+	 * target container (see {@link IClasspathContainer#getDescription()}).
+	 *
+	 * @param containerPath the path of the container which requires a readable description
+	 * @param project the project from which the container is referenced
+	 * @return a string description of the container
+	 * @since 2.1
+	 */
+    public String getDescription(IPath containerPath, IJavaProject project) {
+
+    	// By default, a container path is the only available description
+    	return containerPath.makeRelative().toString();
+    }
+
+    /**
+     * Returns a classpath container that is used after this initializer failed to bind a classpath container
+     * to a {@link IClasspathContainer} for the given project. A non-<code>null</code>
+     * failure container indicates that there will be no more request to initialize the given container
+     * for the given project.
+     * <p>
+     * By default a non-<code>null</code> failure container with no classpath entries is returned.
+     * Clients wishing to get a chance to run the initializer again should override this method
+     * and return <code>null</code>.
+     * </p>
+     *
+ 	 * @param containerPath the path of the container which failed to initialize
+	 * @param project the project from which the container is referenced
+	 * @return the default failure container, or <code>null</code> if wishing to run the initializer again
+     * @since 3.3
+     */
+    public IClasspathContainer getFailureContainer(final IPath containerPath, IJavaProject project) {
+    	final String description = getDescription(containerPath, project);
+    	return
+    		new IClasspathContainer() {
+				public IClasspathEntry[] getClasspathEntries() {
+					return new IClasspathEntry[0];
+				}
+				public String getDescription() {
+					return description;
+				}
+				public int getKind() {
+					return 0;
+				}
+				public IPath getPath() {
+					return containerPath;
+				}
+				public String toString() {
+					return getDescription();
+				}
+			};
+	}
+
+	/**
+	 * Returns an object which identifies a container for comparison purpose. This allows
+	 * to eliminate redundant containers when accumulating classpath entries (e.g.
+	 * runtime classpath computation). When requesting a container comparison ID, one
+	 * should ensure using its corresponding container initializer. Indeed, a random container
+	 * initializer cannot be held responsible for determining comparison IDs for arbitrary
+	 * containers.
+	 * <p>
+	 * @param containerPath the path of the container which is being checked
+	 * @param project the project for which the container is to being checked
+	 * @return returns an Object identifying the container for comparison
+	 * @since 3.0
+	 */
+	public Object getComparisonID(IPath containerPath, IJavaProject project) {
+
+		// By default, containers are identical if they have the same containerPath first segment,
+		// but this may be refined by other container initializer implementations.
+		if (containerPath == null) {
+			return null;
+		} else {
+			return containerPath.segment(0);
+		}
+	}
+
+	/**
+	 * Returns the access rules attribute status according to this initializer.
+	 * <p>
+	 * The returned {@link IStatus status} can have one of the following severities:
+	 * <ul>
+	 * <li>{@link IStatus#OK OK}: means that the attribute is supported
+	 * 	<strong>and</strong> is modifiable</li>
+	 * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
+	 * 	is not supported or is not modifiable.<br>
+	 * 	In this case, the {@link IStatus#getCode() code}will have
+	 * 	respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
+	 * 	or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
+	 * </ul>
+	 * </p><p>
+	 * The status message can contain more information.
+	 * </p><p>
+	 * If the subclass does not override this method, then the default behavior is
+	 * to return {@link IStatus#OK OK} if and only if the classpath container can
+	 * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
+	 * </p>
+	 *
+	 * @param containerPath the path of the container which requires to be
+	 * 	updated
+	 * @param project the project for which the container is to be updated
+	 * @return returns the access rules attribute status
+	 *
+	 * @since 3.3
+	 */
+	public IStatus getAccessRulesStatus(IPath containerPath, IJavaProject project) {
+
+		if (canUpdateClasspathContainer(containerPath, project)) {
+			return Status.OK_STATUS;
+		}
+		return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
+	}
+
+	/**
+	 * Returns the extra attribute status according to this initializer.
+	 * <p>
+	 * The returned {@link IStatus status} can have one of the following severities:
+	 * <ul>
+	 * <li>{@link IStatus#OK OK}: means that the attribute is supported
+	 * 	<strong>and</strong> is modifiable</li>
+	 * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
+	 * 	is not supported or is not modifiable.<br>
+	 * 	In this case, the {@link IStatus#getCode() code}will have
+	 * 	respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
+	 * 	or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
+	 * </ul>
+	 * </p><p>
+	 * The status message can contain more information.
+	 * </p><p>
+	 * If the subclass does not override this method, then the default behavior is
+	 * to return {@link IStatus#OK OK} if and only if the classpath container can
+	 * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
+	 * </p>
+	 *
+	 * @param containerPath the path of the container which requires to be
+	 * 	updated
+	 * @param project the project for which the container is to be updated
+	 * @param attributeKey the key of the extra attribute
+	 * @return returns the extra attribute status
+	 * @see IClasspathAttribute
+	 *
+	 * @since 3.3
+	 */
+	public IStatus getAttributeStatus(IPath containerPath, IJavaProject project, String attributeKey) {
+
+		if (canUpdateClasspathContainer(containerPath, project)) {
+			return Status.OK_STATUS;
+		}
+		return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
+	}
+
+	/**
+	 * Returns the source attachment attribute status according to this initializer.
+	 * <p>
+	 * The returned {@link IStatus status} can have one of the following severities:
+	 * <ul>
+	 * <li>{@link IStatus#OK OK}: means that the attribute is supported
+	 * 	<strong>and</strong> is modifiable</li>
+	 * <li>{@link IStatus#ERROR ERROR}: means that either the attribute
+	 * 	is not supported or is not modifiable.<br>
+	 * 	In this case, the {@link IStatus#getCode() code}will have
+	 * 	respectively the {@link #ATTRIBUTE_NOT_SUPPORTED} value
+	 * 	or the {@link #ATTRIBUTE_READ_ONLY} value.</li>
+	 * </ul>
+	 * </p><p>
+	 * The status message can contain more information.
+	 * </p><p>
+	 * If the subclass does not override this method, then the default behavior is
+	 * to return {@link IStatus#OK OK} if and only if the classpath container can
+	 * be updated (see {@link #canUpdateClasspathContainer(IPath, IJavaProject)}).
+	 * </p>
+	 *
+	 * @param containerPath the path of the container which requires to be
+	 * 	updated
+	 * @param project the project for which the container is to be updated
+	 * @return returns the source attachment attribute status
+	 *
+	 * @since 3.3
+	 */
+	public IStatus getSourceAttachmentStatus(IPath containerPath, IJavaProject project) {
+
+		if (canUpdateClasspathContainer(containerPath, project)) {
+			return Status.OK_STATUS;
+		}
+		return new JavaModelStatus(ATTRIBUTE_READ_ONLY);
+	}
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java
new file mode 100644
index 0000000..0d87924
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core;
+
+/**
+ * Abstract base implementation of all classpath variable initializers.
+ * Classpath variable initializers are used in conjunction with the
+ * "org.eclipse.jdt.core.classpathVariableInitializer" extension point.
+ * <p>
+ * Clients should subclass this class to implement a specific classpath
+ * variable initializer. The subclass must have a public 0-argument
+ * constructor and a concrete implementation of <code>initialize</code>.
+ *
+ * @see IClasspathEntry
+ * @since 2.0
+ */
+public abstract class ClasspathVariableInitializer {
+
+    /**
+     * Creates a new classpath variable initializer.
+     */
+    public ClasspathVariableInitializer() {
+    	// a classpath variable initializer must have a public 0-argument constructor
+    }
+
+    /**
+     * Binds a value to the workspace classpath variable with the given name,
+     * or fails silently if this cannot be done.
+     * <p>
+     * A variable initializer is automatically activated whenever a variable value
+     * is needed and none has been recorded so far. The implementation of
+     * the initializer can set the corresponding variable using
+     * <code>JavaCore#setClasspathVariable</code>.
+     *
+     * @param variable the name of the workspace classpath variable
+     *    that requires a binding
+     *
+     * @see JavaCore#getClasspathVariable(String)
+     * @see JavaCore#setClasspathVariable(String, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+     * @see JavaCore#setClasspathVariables(String[], org.eclipse.core.runtime.IPath[], org.eclipse.core.runtime.IProgressMonitor)
+     */
+    public abstract void initialize(String variable);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
new file mode 100644
index 0000000..aacdc47
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Completion context.
+ *
+ * Represent the context in which the completion occurs.
+ *
+ * @see CompletionRequestor#acceptContext(CompletionContext)
+ * @since 3.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public class CompletionContext {
+
+	/**
+	 * The completed token is the first token of a member declaration.<br>
+	 * e.g.
+	 * <pre>
+	 * public class X {
+	 *   Foo| // completion occurs at |
+	 * }
+	 * </pre>
+	 *
+	 * @see #getTokenLocation()
+	 *
+	 * @since 3.4
+	 */
+	public static final int TL_MEMBER_START = 1;
+
+	/**
+	 * The completed token is the first token of a statement.<br>
+	 * e.g.
+	 * <pre>
+	 * public class X {
+	 *   public void bar() {
+	 *     Foo| // completion occurs at |
+	 *   }
+	 * }
+	 * </pre>
+	 *
+	 * @see #getTokenLocation()
+	 *
+	 * @since 3.4
+	 */
+	public static final int TL_STATEMENT_START = 2;
+	
+	/**
+	 * The completed token is the first token of a constructor
+	 * invocation expression.<br>
+	 * e.g.
+	 * <pre>
+	 * public class X {
+	 *   public void bar() {
+	 *     new Foo| // completion occurs at |
+	 *   }
+	 * }
+	 * </pre>
+	 *
+	 * @see #getTokenLocation()
+	 *
+	 * @since 3.9
+	 */
+	public static final int TL_CONSTRUCTOR_START = 4;
+
+	/**
+	 * The completion token is unknown.
+	 * @since 3.2
+	 */
+	public static final int TOKEN_KIND_UNKNOWN = 0;
+
+	/**
+	 * The completion token is a name.
+	 * @since 3.2
+	 */
+	public static final int TOKEN_KIND_NAME = 1;
+	/**
+	 * The completion token is a string literal.
+	 * The string literal ends quote can be not present the source.
+	 * <code>"foo"</code> or <code>"foo</code>.
+	 * @since 3.2
+	 */
+
+	public static final int TOKEN_KIND_STRING_LITERAL = 2;
+	/**
+	 * Tell user whether completion takes place in a javadoc comment or not.
+	 *
+	 * @return boolean true if completion takes place in a javadoc comment, false otherwise.
+	 * @since 3.2
+	 */
+	public boolean isInJavadoc() {
+		return false; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Tell user whether completion takes place in text area of a javadoc comment or not.
+	 *
+	 * @return boolean true if completion takes place in a text area of a javadoc comment, false otherwise.
+	 * @since 3.2
+	 */
+	public  boolean isInJavadocText() {
+		return false; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Tell user whether completion takes place in a formal reference of a javadoc tag or not.
+	 * Tags with formal reference are:
+	 * <ul>
+	 * 	<li>&#64;see</li>
+	 * 	<li>&#64;throws</li>
+	 * 	<li>&#64;exception</li>
+	 * 	<li>{&#64;link Object}</li>
+	 * 	<li>{&#64;linkplain Object}</li>
+	 * 	<li>{&#64;value} when compiler compliance is set at leats to 1.5</li>
+	 * </ul>
+	 *
+	 * @return boolean true if completion takes place in formal reference of a javadoc tag, false otherwise.
+	 * @since 3.2
+	 */
+	public boolean isInJavadocFormalReference() {
+		return false; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns whether this completion context is an extended context.
+	 * Some methods of this context can be used only if this context is an extended context but an extended context consumes more memory.
+	 *
+	 * @return <code>true</code> if this completion context is an extended context.
+	 *
+	 * @since 3.4
+	 */
+	public boolean isExtended() {
+		return false; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Return signatures of expected types of a potential completion proposal at the completion position.
+	 *
+	 * It's not mandatory to a completion proposal to respect this expectation.
+	 *
+	 * @return signatures expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 *
+	 * @see Signature
+	 */
+	public char[][] getExpectedTypesSignatures() {
+		return null; // default overridden by concrete implementation
+	}
+	
+	/**
+	 * Return keys of expected types of a potential completion proposal at the completion position.
+	 *
+	 * It's not mandatory to a completion proposal to respect this expectation.
+	 *
+	 * @return keys of expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 *
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public char[][] getExpectedTypesKeys() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the completed token.
+	 * This token is either the identifier or Java language keyword
+	 * or the string literal under, immediately preceding,
+	 * the original request offset. If the original request offset
+	 * is not within or immediately after an identifier or keyword or
+	 * a string literal then the returned value is <code>null</code>.
+	 *
+	 * @return completed token or <code>null</code>
+	 * @since 3.2
+	 */
+	public char[] getToken() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the kind of completion token being proposed.
+	 * <p>
+	 * The set of different kinds of completion token is
+	 * expected to change over time. It is strongly recommended
+	 * that clients do <b>not</b> assume that the kind is one of the
+	 * ones they know about, and code defensively for the
+	 * possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the kind; one of the kind constants declared on
+	 * this class whose name starts with <code>TOKEN_KIND</code>,
+	 * or possibly a kind unknown to the caller
+	 * @since 3.2
+	 */
+	public int getTokenKind() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the location of completion token being proposed.
+	 * The returned location is a bit mask which can contain some values
+	 * of the constants declared on this class whose name starts with <code>TL</code>,
+	 * or possibly values unknown to the caller.
+	 *
+	 * <p>
+	 * The set of different location values is expected to change over time.
+	 * It is strongly recommended that clients do <b>not</b> assume that
+	 * the location contains only known value, and code defensively for
+	 * the possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the location
+	 *
+	 * @since 3.4
+	 */
+	public int getTokenLocation() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant token being completed. This
+	 * token is either the identifier or Java language keyword
+	 * under, or immediately preceding, the original request
+	 * offset. If the original request offset is not within
+	 * or immediately after an identifier or keyword, then the
+	 * position returned is original request offset and the
+	 * token range is empty.
+	 *
+	 * @return character index of token start position (inclusive)
+	 * @since 3.2
+	 */
+	public int getTokenStart() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant token. When there is no relevant token, the
+	 * range is empty
+	 * (<code>getTokenEnd() == getTokenStart() - 1</code>).
+	 *
+	 * @return character index of token end position (exclusive)
+	 * @since 3.2
+	 */
+	// TODO (david) https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558
+	public int getTokenEnd() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the offset position in the source file buffer
+	 * after which code assist is requested.
+	 *
+	 * @return offset position in the source file buffer
+	 * @since 3.2
+	 */
+	public int getOffset() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 * The returned Java element and all Java elements in the same compilation unit which can be navigated to from the returned Java element are special Java elements:
+	 * <ul>
+	 * <li>they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation</li>
+	 * <li>they are not updated if the buffer changes.</li>
+	 * <li>they do not contain local types which are not visible from the completion location.</li>
+	 * <li>they do not give information about categories. {@link IMember#getCategories()} will return an empty array</li>
+	 * </ul>
+	 *
+	 * Reasons for returning <code>null</code> include:
+	 * <ul>
+	 * <li>the compilation unit no longer exists</li>
+	 * <li>the completion occurred in a binary type. However this restriction might be relaxed in the future.</li>
+	 * </ul>
+	 *
+	 * @return the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 *
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @since 3.4
+	 */
+	public IJavaElement getEnclosingElement() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Return the elements which are visible from the completion location and which can be assigned to the given type.
+	 * An element is assignable if its type can be assigned to a variable
+	 * of the given type, as specified in section 5.2 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 * A visible element is either:
+	 * <ul>
+	 * <li>a {@link ILocalVariable} - the element type is {@link ILocalVariable#getTypeSignature()}</li>
+	 * <li>a {@link IField} - the element type is {@link IField#getTypeSignature()}</li>
+	 * <li>a {@link IMethod} - the element type is {@link IMethod#getReturnType()}</li>
+	 * </ul>
+	 *
+	 * Returned elements defined in the completed compilation unit are special Java elements:
+	 * <ul>
+	 * <li>they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation</li>
+	 * <li>they are not updated if the buffer changes.</li>
+	 * <li>they do not contain local types which are not visible from the completion location.</li>
+	 * <li>they do not give information about categories. {@link IMember#getCategories()} will return an empty array</li>
+	 * </ul>
+	 *
+	 * Note the array can be empty if:
+	 * <ul>
+	 * <li>the compilation unit no longer exists</li>
+	 * <li>the completion occurred in a binary type. However this restriction might be relaxed in the future.</li>
+	 * </ul>
+	 *
+	 * @param typeSignature elements which can be assigned to this type are returned.
+	 * 		If <code>null</code> there is no constraint on the type of the returned elements.
+	 *
+	 * @return elements which are visible from the completion location and which can be assigned to the given type.
+	 *
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 *
+	 * @see #isExtended()
+	 *
+	 * @since 3.4
+	 */
+	public IJavaElement[] getVisibleElements(String typeSignature) {
+		return null; // default overridden by concrete implementation
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionFlags.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionFlags.java
new file mode 100644
index 0000000..a17cf17
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionFlags.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Utility class for decoding additional flags in completion proposal.
+ * <p>
+ * This class provides static methods only; it is not intended to be
+ * instantiated or subclassed by clients.
+ * </p>
+ *
+ * @see CompletionProposal#getAdditionalFlags()
+ *
+ * @since 3.3
+ */
+public final class CompletionFlags {
+	/**
+	 * Constant representing the absence of any flag
+	 */
+	public static final int Default = 0x0000;
+
+	/**
+	 * Constant representing a static import
+	 */
+	public static final int StaticImport = 0x0001;
+
+	/**
+	 * Not instantiable.
+	 */
+	private CompletionFlags() {
+		// Not instantiable
+	}
+
+	/**
+	 * Returns whether the given integer includes the {@link #StaticImport} flag.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the {@link #StaticImport} flag is included
+	 */
+	public static boolean isStaticImport(int flags) {
+		return (flags & StaticImport) != 0;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
new file mode 100644
index 0000000..b1a8f42
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
@@ -0,0 +1,1813 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal;
+
+/**
+ * Completion proposal.
+ * <p>
+ * In typical usage, the user working in a Java code editor issues
+ * a code assist command. This command results in a call to
+ * <code>ICodeAssist.codeComplete(position, completionRequestor)</code>
+ * passing the current position in the source code. The code assist
+ * engine analyzes the code in the buffer, determines what kind of
+ * Java language construct is at that position, and proposes ways
+ * to complete that construct. These proposals are instances of
+ * the class <code>CompletionProposal</code>. These proposals,
+ * perhaps after sorting and filtering, are presented to the user
+ * to make a choice.
+ * </p>
+ * <p>
+ * The proposal is as follows: insert
+ * the {@linkplain #getCompletion() completion string} into the
+ * source file buffer, replacing the characters between
+ * {@linkplain #getReplaceStart() the start}
+ * and {@linkplain #getReplaceEnd() end}. The string
+ * can be arbitrary; for example, it might include not only the
+ * name of a method but a set of parentheses. Moreover, the source
+ * range may include source positions before or after the source
+ * position where <code>ICodeAssist.codeComplete</code> was invoked.
+ * The rest of the information associated with the proposal is
+ * to provide context that may help a user to choose from among
+ * competing proposals.
+ * </p>
+ * <p>
+ * The completion engine creates instances of this class.
+ * </p>
+ *
+ * @see ICodeAssist#codeComplete(int, CompletionRequestor)
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CompletionProposal {
+
+	/**
+	 * Completion is a declaration of an anonymous class.
+	 * This kind of completion might occur in a context like
+	 * <code>"new List(^;"</code> and complete it to
+	 * <code>"new List() {}"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type being implemented or subclassed
+	 * </li>
+	 * <li>{@link #getDeclarationKey()} -
+	 * the type unique key of the type being implemented or subclassed
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the constructor that is referenced
+	 * </li>
+	 * <li>{@link #getKey()} -
+	 * the method unique key of the constructor that is referenced
+	 * if the declaring type is not an interface
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the constructor that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int ANONYMOUS_CLASS_DECLARATION = 1;
+
+	/**
+	 * Completion is a reference to a field.
+	 * This kind of completion might occur in a context like
+	 * <code>"this.ref^ = 0;"</code> and complete it to
+	 * <code>"this.refcount = 0;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int FIELD_REF = 2;
+
+	/**
+	 * Completion is a keyword.
+	 * This kind of completion might occur in a context like
+	 * <code>"public cl^ Foo {}"</code> and complete it to
+	 * <code>"public class Foo {}"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getName()} -
+	 * the keyword token
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the corresponding modifier flags if the keyword is a modifier
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int KEYWORD = 3;
+
+	/**
+	 * Completion is a reference to a label.
+	 * This kind of completion might occur in a context like
+	 * <code>"break lo^;"</code> and complete it to
+	 * <code>"break loop;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getName()} -
+	 * the simple name of the label that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int LABEL_REF = 4;
+
+	/**
+	 * Completion is a reference to a local variable.
+	 * This kind of completion might occur in a context like
+	 * <code>"ke^ = 4;"</code> and complete it to
+	 * <code>"keys = 4;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the local variable that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the local variable that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the local variable's type
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int LOCAL_VARIABLE_REF = 5;
+
+	/**
+	 * Completion is a reference to a method.
+	 * This kind of completion might occur in a context like
+	 * <code>"System.out.pr^();"</code> and complete it to
+	 * <code>""System.out.println();"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int METHOD_REF = 6;
+
+	/**
+	 * Completion is a declaration of a method.
+	 * This kind of completion might occur in a context like
+	 * <code>"new List() {si^};"</code> and complete it to
+	 * <code>"new List() {public int size() {} };"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the
+	 * method that is being overridden or implemented
+	 * </li>
+	 * <li>{@link #getDeclarationKey()} -
+	 * the unique of the type that declares the
+	 * method that is being overridden or implemented
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is being overridden
+	 * or implemented
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is being
+	 * overridden or implemented
+	 * </li>
+	 * <li>{@link #getKey()} -
+	 * the method unique key of the method that is being
+	 * overridden or implemented
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is being
+	 * overridden or implemented
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int METHOD_DECLARATION = 7;
+
+	/**
+	 * Completion is a reference to a package.
+	 * This kind of completion might occur in a context like
+	 * <code>"import java.u^.*;"</code> and complete it to
+	 * <code>"import java.util.*;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the dot-based package name of the package that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int PACKAGE_REF = 8;
+
+	/**
+	 * Completion is a reference to a type. Any kind of type
+	 * is allowed, including primitive types, reference types,
+	 * array types, parameterized types, and type variables.
+	 * This kind of completion might occur in a context like
+	 * <code>"public static Str^ key;"</code> and complete it to
+	 * <code>"public static String key;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the dot-based package name of the package that contains
+	 * the type that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the type that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including Flags.AccInterface, AccEnum,
+	 * and AccAnnotation) of the type that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 */
+	public static final int TYPE_REF = 9;
+
+	/**
+	 * Completion is a declaration of a variable (locals, parameters,
+	 * fields, etc.).
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getName()} -
+	 * the simple name of the variable being declared
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the type of the variable
+	 * being declared
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the variable being declared
+	 * </li>
+	 * </ul>
+	 * </p>
+	 * @see #getKind()
+	 */
+	public static final int VARIABLE_DECLARATION = 10;
+
+	/**
+	 * Completion is a declaration of a new potential method.
+	 * This kind of completion might occur in a context like
+	 * <code>"new List() {si^};"</code> and complete it to
+	 * <code>"new List() {public int si() {} };"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the
+	 * method that is being created
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is being created
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is being
+	 * created
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is being
+	 * created
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+     * @since 3.1
+	 */
+	public static final int POTENTIAL_METHOD_DECLARATION = 11;
+
+	/**
+	 * Completion is a reference to a method name.
+	 * This kind of completion might occur in a context like
+	 * <code>"import p.X.fo^"</code> and complete it to
+	 * <code>"import p.X.foo;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+     * @since 3.1
+	 */
+	public static final int METHOD_NAME_REFERENCE = 12;
+
+	/**
+	 * Completion is a reference to annotation's attribute.
+	 * This kind of completion might occur in a context like
+	 * <code>"@Annot(attr^=value)"</code> and complete it to
+	 * <code>"@Annot(attribute^=value)"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the annotation that declares the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the attribute's type (as opposed to the
+	 * signature of the type in which the referenced attribute
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.1
+	 */
+	public static final int ANNOTATION_ATTRIBUTE_REF = 13;
+
+	/**
+	 * Completion is a link reference to a field in a javadoc text.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* blabla System.o^ blabla"</code> and complete it to
+	 * <code>"	* blabla {&#64;link System#out } blabla"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_FIELD_REF = 14;
+
+	/**
+	 * Completion is a link reference to a method in a javadoc text.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* blabla Runtime#get^ blabla"</code> and complete it to
+	 * <code>"	* blabla {&#64;link Runtime#getRuntime() }"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_METHOD_REF = 15;
+
+	/**
+	 * Completion is a link reference to a type in a javadoc text.
+	 * Any kind of type is allowed, including primitive types, reference types,
+	 * array types, parameterized types, and type variables.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* blabla Str^ blabla"</code> and complete it to
+	 * <code>"	* blabla {&#64;link String } blabla"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the dot-based package name of the package that contains
+	 * the type that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the type that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including Flags.AccInterface, AccEnum,
+	 * and AccAnnotation) of the type that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_TYPE_REF = 16;
+
+	/**
+	 * Completion is a value reference to a static field in a javadoc text.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* blabla System.o^ blabla"</code> and complete it to
+	 * <code>"	* blabla {&#64;value System#out } blabla"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_VALUE_REF = 17;
+
+	/**
+	 * Completion is a method argument or a class/method type parameter
+	 * in javadoc param tag.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* @param arg^ blabla"</code> and complete it to
+	 * <code>"	* @param argument blabla"</code>.
+	 * or
+	 * <code>"	* @param &lt;T^ blabla"</code> and complete it to
+	 * <code>"	* @param &lt;TT&gt; blabla"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_PARAM_REF = 18;
+
+	/**
+	 * Completion is a javadoc block tag.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* @s^ blabla"</code> and complete it to
+	 * <code>"	* @see blabla"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_BLOCK_TAG = 19;
+
+	/**
+	 * Completion is a javadoc inline tag.
+	 * This kind of completion might occur in a context like
+	 * <code>"	* Insert @l^ Object"</code> and complete it to
+	 * <code>"	* Insert {&#64;link Object }"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @since 3.2
+	 */
+	public static final int JAVADOC_INLINE_TAG = 20;
+
+	/**
+	 * Completion is an import of reference to a static field.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is imported
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is imported
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is imported
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 * <li>{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int FIELD_IMPORT = 21;
+
+	/**
+	 * Completion is an import of reference to a static method.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is imported
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is imported
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is imported
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is imported
+	 * </li>
+	 * <li>{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int METHOD_IMPORT = 22;
+
+	/**
+	 * Completion is an import of reference to a type.
+	 * Only reference to reference types are allowed.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the dot-based package name of the package that contains
+	 * the type that is imported
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the type that is imported
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including Flags.AccInterface, AccEnum,
+	 * and AccAnnotation) of the type that is imported
+	 * </li>
+	 * <li>{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int TYPE_IMPORT = 23;
+
+	/**
+	 * Completion is a reference to a method with a casted receiver.
+	 * This kind of completion might occur in a context like
+	 * <code>"receiver.fo^();"</code> and complete it to
+	 * <code>""((X)receiver).foo();"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the method that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the method that is referenced
+	 * </li>
+	 * <li>{@link #getReceiverSignature()} -
+	 * the type signature of the receiver type. It's the type of the cast expression.
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the method that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.4
+	 */
+	public static final int METHOD_REF_WITH_CASTED_RECEIVER = 24;
+
+	/**
+	 * Completion is a reference to a field with a casted receiver.
+	 * This kind of completion might occur in a context like
+	 * <code>"recevier.ref^ = 0;"</code> and complete it to
+	 * <code>"((X)receiver).refcount = 0;"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the field that is referenced
+	 * </li>
+	 * <li>{@link #getReceiverSignature()} -
+	 * the type signature of the receiver type. It's the type of the cast expression.
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * </li>
+	 *
+	 * </ul>
+	 * </p>
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.4
+	 */
+	public static final int FIELD_REF_WITH_CASTED_RECEIVER = 25;
+	
+	/**
+	 * Completion is a reference to a constructor.
+	 * This kind of completion might occur in a context like
+	 * <code>"new Lis"</code> and complete it to
+	 * <code>"new List();"</code> if List is a class that is not abstract.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the constructor that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the constructor that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the constructor that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the constructor that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor}
+	 * (e.g. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)}).<br>
+	 * This kind of proposal is always is only proposals with a {@link #TYPE_REF} required proposal, so this kind of required proposal must be allowed:
+	 * <code>requestor.setAllowsRequiredProposals(CONSTRUCTOR_INVOCATION, TYPE_REF, true)</code>.
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int CONSTRUCTOR_INVOCATION = 26;
+	
+	/**
+	 * Completion is a reference of a constructor of an anonymous class.
+	 * This kind of completion might occur in a context like
+	 * <code>"new Lis^;"</code> and complete it to
+	 * <code>"new List() {}"</code> if List is an interface or abstract class.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the type being implemented or subclassed
+	 * </li>
+	 * <li>{@link #getDeclarationKey()} -
+	 * the type unique key of the type being implemented or subclassed
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the method signature of the constructor that is referenced
+	 * </li>
+	 * <li>{@link #getKey()} -
+	 * the method unique key of the constructor that is referenced
+	 * if the declaring type is not an interface
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the constructor that is referenced
+	 * </li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor}
+	 * (e.g. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)})<br>
+	 * This kind of proposal is always is only proposals with a {@link #TYPE_REF} required proposal, so this kind of required proposal must be allowed:
+	 * <code>requestor.setAllowsRequiredProposals(CONSTRUCTOR_INVOCATION, TYPE_REF, true)</code>.
+	 * </p>
+	 *
+	 * @see #getKind()
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION = 27;
+
+	/**
+	 * First valid completion kind.
+	 *
+	 * @since 3.1
+	 */
+	protected static final int FIRST_KIND = ANONYMOUS_CLASS_DECLARATION;
+
+	/**
+	 * Last valid completion kind.
+	 *
+	 * @since 3.1
+	 */
+	protected static final int LAST_KIND = ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION;
+
+	/**
+	 * Creates a basic completion proposal. All instance
+	 * field have plausible default values unless otherwise noted.
+	 * <p>
+	 * Note that the constructors for this class are internal to the
+	 * Java model implementation. Clients cannot directly create
+	 * CompletionProposal objects.
+	 * </p>
+	 *
+	 * @param kind one of the kind constants declared on this class
+	 * @param completionOffset original offset of code completion request
+	 * @return a new completion proposal
+	 */
+	public static CompletionProposal create(int kind, int completionOffset) {
+		return new InternalCompletionProposal(kind, completionOffset);
+	}
+
+	/**
+	 * Returns the completion flags relevant in the context, or
+	 * <code>CompletionFlags.Default</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>FIELD_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * <li><code>METHOD_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * <li><code>TYPE_IMPORT</code> - completion flags
+	 * of the attribute that is referenced. Completion flags for
+	 * this proposal kind can only include <code>CompletionFlags.StaticImport</code></li>
+	 * </ul>
+	 * For other kinds of completion proposals, this method returns
+	 * <code>CompletionFlags.Default</code>.
+	 * </p>
+	 *
+	 * @return the completion flags, or
+	 * <code>CompletionFlags.Default</code> if none
+	 * @see CompletionFlags
+	 *
+	 * @since 3.3
+	 */
+	public int getAdditionalFlags() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the completion flags relevant in the context.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param additionalFlags the completion flags, or
+	 * <code>CompletionFlags.Default</code> if none
+	 *
+	 * @since 3.3
+	 */
+	public void setAdditionalFlags(int additionalFlags) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the kind of completion being proposed.
+	 * <p>
+	 * The set of different kinds of completion proposals is
+	 * expected to change over time. It is strongly recommended
+	 * that clients do <b>not</b> assume that the kind is one of the
+	 * ones they know about, and code defensively for the
+	 * possibility of unexpected future growth.
+	 * </p>
+	 *
+	 * @return the kind; one of the kind constants
+	 * declared on this class, or possibly a kind unknown
+	 * to the caller
+	 */
+	public int getKind() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index in the source file buffer
+	 * where source completion was requested (the
+	 * <code>offset</code> parameter to
+	 * <code>ICodeAssist.codeComplete</code> minus one).
+	 *
+	 * @return character index in source file buffer
+	 * @see ICodeAssist#codeComplete(int,CompletionRequestor)
+	 */
+	// TODO (david) https://bugs.eclipse.org/bugs/show_bug.cgi?id=132558
+	public int getCompletionLocation() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant token being completed. This
+	 * token is either the identifier or Java language keyword
+	 * under, or immediately preceding, the original request
+	 * offset. If the original request offset is not within
+	 * or immediately after an identifier or keyword, then the
+	 * position returned is original request offset and the
+	 * token range is empty.
+	 *
+	 * @return character index of token start position (inclusive)
+	 */
+	public int getTokenStart() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant token. When there is no relevant token, the
+	 * range is empty
+	 * (<code>getEndToken() == getStartToken()</code>).
+	 *
+	 * @return character index of token end position (exclusive)
+	 */
+	public int getTokenEnd() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer containing the relevant token being
+	 * completed. This token is either the identifier or
+	 * Java language keyword under, or immediately preceding,
+	 * the original request offset. If the original request
+	 * offset is not within or immediately after an identifier
+	 * or keyword, then the source range begins at original
+	 * request offset and is empty.
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 *
+	 * @param startIndex character index of token start position (inclusive)
+	 * @param endIndex character index of token end position (exclusive)
+	 */
+	public void setTokenRange(int startIndex, int endIndex) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the proposed sequence of characters to insert into the
+	 * source file buffer, replacing the characters at the specified
+	 * source range. The string can be arbitrary; for example, it might
+	 * include not only the name of a method but a set of parentheses.
+	 * <p>
+	 * The client must not modify the array returned.
+	 * </p>
+	 *
+	 * @return the completion string
+	 */
+	public char[] getCompletion() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the proposed sequence of characters to insert into the
+	 * source file buffer, replacing the characters at the specified
+	 * source range. The string can be arbitrary; for example, it might
+	 * include not only the name of a method but a set of parentheses.
+	 * <p>
+	 * If not set, defaults to an empty character array.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param completion the completion string
+	 */
+	public void setCompletion(char[] completion) {
+		// default overridden by concrete implementation		
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer to be replaced
+	 * by the completion string. If the subrange is empty
+	 * (<code>getReplaceEnd() == getReplaceStart()</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 * <p>
+	 * Note that while the token subrange is precisely
+	 * specified, the replacement range is loosely
+	 * constrained and may not bear any direct relation
+	 * to the original request offset. For example,
+	 * it would be possible for a type completion to
+	 * propose inserting an import declaration at the
+	 * top of the compilation unit; or the completion
+	 * might include trailing parentheses and
+	 * punctuation for a method completion.
+	 * </p>
+	 *
+	 * @return replacement start position (inclusive)
+	 */
+	public int getReplaceStart() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the end of the
+	 * subrange in the source file buffer to be replaced
+	 * by the completion string. If the subrange is empty
+	 * (<code>getReplaceEnd() == getReplaceStart()</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 *
+	 * @return replacement end position (exclusive)
+	 */
+	public int getReplaceEnd() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer to be replaced by the completion
+	 * string. If the subrange is empty
+	 * (<code>startIndex == endIndex</code>),
+	 * the completion string is to be inserted at this
+	 * index.
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param startIndex character index of replacement start position (inclusive)
+	 * @param endIndex character index of replacement end position (exclusive)
+	 */
+	public void setReplaceRange(int startIndex, int endIndex) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the relative relevance rating of this proposal.
+	 *
+	 * @return relevance rating of this proposal; ratings are positive; higher means better
+	 */
+	public int getRelevance() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the relative relevance rating of this proposal.
+	 * <p>
+	 * If not set, defaults to the lowest possible rating (1).
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param rating relevance rating of this proposal; ratings are positive; higher means better
+	 */
+	public void setRelevance(int rating) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the type signature or package name of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - type signature
+	 * of the annotation that declares the attribute that is referenced</li>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - type signature
+	 * of the type that is being subclassed or implemented</li>
+	 * 	<li><code>FIELD_IMPORT</code> - type signature
+	 * of the type that declares the field that is imported</li>
+	 *  <li><code>FIELD_REF</code> - type signature
+	 * of the type that declares the field that is referenced</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that declares the field that is referenced</li>
+	 * 	<li><code>METHOD_IMPORT</code> - type signature
+	 * of the type that declares the method that is imported</li>
+	 *  <li><code>METHOD_REF</code> - type signature
+	 * of the type that declares the method that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that declares the method that is referenced</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - type signature
+	 * of the type that declares the method that is being
+	 * implemented or overridden</li>
+	 * 	<li><code>PACKAGE_REF</code> - dot-based package
+	 * name of the package that is referenced</li>
+	 * 	<li><code>TYPE_IMPORT</code> - dot-based package
+	 * name of the package containing the type that is imported</li>
+	 *  <li><code>TYPE_REF</code> - dot-based package
+	 * name of the package containing the type that is referenced</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - type signature
+	 * of the type that declares the method that is being created</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a type signature or a package name (depending
+	 * on the kind of completion), or <code>null</code> if none
+	 * @see Signature
+	 */
+	public char[] getDeclarationSignature() {
+		return null; // default overridden by concrete implementation
+
+	}
+
+	/**
+	 * Returns the key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - key
+	 * of the type that is being subclassed or implemented</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - key
+	 * of the type that declares the method that is being
+	 * implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getDeclarationKey() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the type or package signature of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the type or package signature, or
+	 * <code>null</code> if none
+	 */
+	public void setDeclarationSignature(char[] signature) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the type or package key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param key the type or package key, or
+	 * <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setDeclarationKey(char[] key) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the simple name of the method, field,
+	 * member, or variable relevant in the context, or
+	 * <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - the name of the attribute</li>
+	 * 	<li><code>FIELD_IMPORT</code> - the name of the field</li>
+	 *  <li><code>FIELD_REF</code> - the name of the field</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - the name of the field</li>
+	 * 	<li><code>KEYWORD</code> - the keyword</li>
+	 * 	<li><code>LABEL_REF</code> - the name of the label</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the name of the local variable</li>
+	 * 	<li><code>METHOD_IMPORT</code> - the name of the method</li>
+	 *  <li><code>METHOD_REF</code> - the name of the method (the type simple name for constructor)</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - the name of the method</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - the name of the method (the type simple name for constructor)</li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - the name of the variable</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - the name of the method</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the keyword, field, method, local variable, or member
+	 * name, or <code>null</code> if none
+	 */
+	public char[] getName() {
+		return null; // default overridden by concrete implementation
+	}
+
+
+	/**
+	 * Sets the simple name of the method (type simple name for constructor), field,
+	 * member, or variable relevant in the context, or
+	 * <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param name the keyword, field, method, local variable,
+	 * or member name, or <code>null</code> if none
+	 */
+	public void setName(char[] name) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the signature of the method or type
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - the type signature
+	 * of the referenced attribute's type</li>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method signature
+	 * of the constructor that is being invoked</li>
+	 * 	<li><code>FIELD_IMPORT</code> - the type signature
+	 * of the referenced field's type</li>
+	 *  <li><code>FIELD_REF</code> - the type signature
+	 * of the referenced field's type</li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - the type signature
+	 * of the referenced field's type</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - the type signature
+	 * of the referenced local variable's type</li>
+	 * 	<li><code>METHOD_IMPORT</code> - method signature
+	 * of the method that is imported</li>
+	 *  <li><code>METHOD_REF</code> - method signature
+	 * of the method that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - method signature
+	 * of the method that is referenced</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - method signature
+	 * of the method that is being implemented or overridden</li>
+	 * 	<li><code>TYPE_IMPORT</code> - type signature
+	 * of the type that is imported</li>
+	 * 	<li><code>TYPE_REF</code> - type signature
+	 * of the type that is referenced</li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - the type signature
+	 * of the type of the variable being declared</li>
+	 *  <li><code>POTENTIAL_METHOD_DECLARATION</code> - method signature
+	 * of the method that is being created</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the signature, or <code>null</code> if none
+	 * @see Signature
+	 */
+	public char[] getSignature() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the key relevant in the context,
+	 * or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method key
+	 * of the constructor that is being invoked, or <code>null</code> if
+	 * the declaring type is an interface</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - method key
+	 * of the method that is being implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return the key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getKey() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the signature of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the signature, or <code>null</code> if none
+	 */
+	public void setSignature(char[] signature) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the key of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param key the key, or <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setKey(char[] key) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the modifier flags relevant in the context, or
+	 * <code>Flags.AccDefault</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - modifier flags
+	 * of the attribute that is referenced;
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - modifier flags
+	 * of the constructor that is referenced</li>
+	 * 	<li><code>FIELD_IMPORT</code> - modifier flags
+	 * of the field that is imported.</li>
+	 *  <li><code>FIELD_REF</code> - modifier flags
+	 * of the field that is referenced;
+	 * <code>Flags.AccEnum</code> can be used to recognize
+	 * references to enum constants
+	 * </li>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - modifier flags
+	 * of the field that is referenced.
+	 * </li>
+	 * 	<li><code>KEYWORD</code> - modifier flag
+	 * corresponding to the modifier keyword</li>
+	 * 	<li><code>LOCAL_VARIABLE_REF</code> - modifier flags
+	 * of the local variable that is referenced</li>
+	 *  <li><code>METHOD_IMPORT</code> - modifier flags
+	 * of the method that is imported;
+	 *  </li>
+	 * 	<li><code>METHOD_REF</code> - modifier flags
+	 * of the method that is referenced;
+	 * <code>Flags.AccAnnotation</code> can be used to recognize
+	 * references to annotation type members
+	 * </li>
+	 * <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - modifier flags
+	 * of the method that is referenced.
+	 * </li>
+	 * <li><code>METHOD_DECLARATION</code> - modifier flags
+	 * for the method that is being implemented or overridden</li>
+	 * <li><code>TYPE_IMPORT</code> - modifier flags
+	 * of the type that is imported; <code>Flags.AccInterface</code>
+	 * can be used to recognize references to interfaces,
+	 * <code>Flags.AccEnum</code> enum types,
+	 * and <code>Flags.AccAnnotation</code> annotation types</li>
+	 * <li><code>TYPE_REF</code> - modifier flags
+	 * of the type that is referenced; <code>Flags.AccInterface</code>
+	 * can be used to recognize references to interfaces,
+	 * <code>Flags.AccEnum</code> enum types,
+	 * and <code>Flags.AccAnnotation</code> annotation types
+	 * </li>
+	 * 	<li><code>VARIABLE_DECLARATION</code> - modifier flags
+	 * for the variable being declared</li>
+	 * 	<li><code>POTENTIAL_METHOD_DECLARATION</code> - modifier flags
+	 * for the method that is being created</li>
+	 * </ul>
+	 * For other kinds of completion proposals, this method returns
+	 * <code>Flags.AccDefault</code>.
+	 * </p>
+	 *
+	 * @return the modifier flags, or
+	 * <code>Flags.AccDefault</code> if none
+	 * @see Flags
+	 */
+	public int getFlags() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the modifier flags relevant in the context.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param flags the modifier flags, or
+	 * <code>Flags.AccDefault</code> if none
+	 */
+	public void setFlags(int flags) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the required completion proposals.
+	 * The proposal can be apply only if these required completion proposals are also applied.
+	 * If the required proposal aren't applied the completion could create completion problems.
+	 *
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * 	<li><code>FIELD_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *    <li><code>TYPE_IMPORT</code></li>
+	 *    <li><code>FIELD_IMPORT</code></li>
+	 *   </ul>
+	 * </li>
+	 * 	<li><code>METHOD_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *    <li><code>TYPE_IMPORT</code></li>
+	 *    <li><code>METHOD_IMPORT</code></li>
+	 *   </ul>
+	 *  </li>
+	 * </li>
+	 * 	<li><code>TYPE_REF</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *   </ul>
+	 *  </li>
+	 *  <li><code>CONSTRUCTOR_INVOCATION</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *   </ul>
+	 *  </li>
+	 *  <li><code>ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *   </ul>
+	 *  </li>
+	 *  <li><code>ANONYMOUS_CLASS_DECLARATION</code> - The allowed required proposals for this kind are:
+	 *   <ul>
+	 *    <li><code>TYPE_REF</code></li>
+	 *   </ul>
+	 *  </li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * Other kinds of required proposals will be returned in the future, therefore clients of this
+	 * API must allow with {@link CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)}
+	 * only kinds which are in this list to avoid unexpected results in the future.
+	 * </p>
+	 * <p>
+	 * A required proposal of a given kind is proposed even if {@link CompletionRequestor#isIgnored(int)}
+	 * return <code>true</code> for that kind.
+	 * </p>
+	 * <p>
+	 * A required completion proposal cannot have required completion proposals.
+	 * </p>
+	 *
+	 * @return the required completion proposals, or <code>null</code> if none.
+	 *
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int,boolean)
+	 *
+	 * @since 3.3
+	 */
+	public CompletionProposal[] getRequiredProposals() {
+		return null; // default overridden by concrete implementation
+	}
+
+
+	/**
+	 * Sets the list of required completion proposals, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param proposals the list of required completion proposals, or
+	 * <code>null</code> if none
+     * @since 3.3
+	 */
+	public void setRequiredProposals(CompletionProposal[] proposals) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Finds the method parameter names.
+	 * This information is relevant to method reference (and
+	 * method declaration proposals). Returns <code>null</code>
+	 * if not available or not relevant.
+	 * <p>
+	 * The client must not modify the array returned.
+	 * </p>
+	 * <p>
+	 * <b>Note that this is an expensive thing to compute, which may require
+	 * parsing Java source files, etc. Use sparingly.</b>
+	 * </p>
+	 *
+	 * @param monitor the progress monitor, or <code>null</code> if none
+	 * @return the parameter names, or <code>null</code> if none
+	 * or not available or not relevant
+	 */
+	public char[][] findParameterNames(IProgressMonitor monitor) {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the method parameter names.
+	 * This information is relevant to method reference (and
+	 * method declaration proposals).
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param parameterNames the parameter names, or <code>null</code> if none
+	 */
+	public void setParameterNames(char[][] parameterNames) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the accessibility of the proposal.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * 	<li><code>TYPE_REF</code> - accessibility of the type</li>
+	 * </ul>
+	 * For these kinds of completion proposals, this method returns
+	 * {@link IAccessRule#K_ACCESSIBLE} or {@link IAccessRule#K_DISCOURAGED}
+	 * or {@link IAccessRule#K_NON_ACCESSIBLE}.
+	 * By default this method return {@link IAccessRule#K_ACCESSIBLE}.
+	 * </p>
+	 *
+	 * @see IAccessRule
+	 *
+	 * @return the accessibility of the proposal
+	 *
+	 * @since 3.1
+	 */
+	public int getAccessibility() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns whether this proposal is a constructor.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>METHOD_REF</code> - return <code>true</code>
+	 * if the referenced method is a constructor</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - return <code>true</code>
+	 * if the declared method is a constructor</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>false</code>.
+	 * </p>
+	 *
+	 * @return <code>true</code> if the proposal is a constructor.
+	 * @since 3.1
+	 */
+	public boolean isConstructor() {
+		return false; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the type signature or package name of the relevant
+	 * receiver in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that cast the receiver of the field that is referenced</li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code> - type signature
+	 * of the type that cast the receiver of the method that is referenced</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 *
+	 * @return a type signature or a package name (depending
+	 * on the kind of completion), or <code>null</code> if none
+	 * @see Signature
+	 *
+	 * @since 3.4
+	 */
+	public char[] getReceiverSignature() {
+		return null; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the start of the
+	 * subrange in the source file buffer containing the
+	 * relevant receiver of the member being completed. This
+	 * receiver is an expression.
+	 *
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code></li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code></li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns <code>0</code>.
+	 * </p>
+	 *
+	 * @return character index of receiver start position (inclusive)
+	 *
+	 * @since 3.4
+	 */
+	public int getReceiverStart() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Returns the character index of the end (exclusive) of the subrange
+	 * in the source file buffer containing the
+	 * relevant receiver of the member being completed.
+	 *
+	 * * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 *  <li><code>FIELD_REF_WITH_CASTED_RECEIVER</code></li>
+	 *  <li><code>METHOD_REF_WITH_CASTED_RECEIVER</code></li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns <code>0</code>.
+	 * </p>
+	 *
+	 * @return character index of receiver end position (exclusive)
+	 *
+	 * @since 3.4
+	 */
+	public int getReceiverEnd() {
+		return -1; // default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the type or package signature of the relevant
+	 * receiver in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 *
+	 * @param signature the type or package signature, or
+	 * <code>null</code> if none
+	 *
+	 * @since 3.4
+	 */
+	public void setReceiverSignature(char[] signature) {
+		// default overridden by concrete implementation
+	}
+
+	/**
+	 * Sets the character indices of the subrange in the
+	 * source file buffer containing the relevant receiver
+	 * of the member being completed.
+	 *
+	 * <p>
+	 * If not set, defaults to empty subrange at [0,0).
+	 * </p>
+	 *
+	 * @param startIndex character index of receiver start position (inclusive)
+	 * @param endIndex character index of receiver end position (exclusive)
+	 *
+	 * @since 3.4
+	 */
+	public void setReceiverRange(int startIndex, int endIndex) {
+		// default overridden by concrete implementation
+	}
+
+	/** 
+	 * Returns whether it is safe to use the '<>' (diamond) operator in place of explicitly specifying
+	 * type arguments for this proposal.
+	 * 
+	 * <p>
+	 * This is only relevant for source level 1.7 or greater.
+	 * </p>
+	 * 
+	 * @param coreContext the completion context associated with the proposal
+	 * @since 3.7.1
+	 * @return <code>true</code> if it is safe to use the diamond operator for the constructor invocation, 
+	 * <code>false</code> otherwise. Also returns <code>false</code> for source levels below 1.7
+	 */
+	public boolean canUseDiamond(CompletionContext coreContext) {
+		return false; // default overridden by concrete implementation
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java
new file mode 100644
index 0000000..487c9ac
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Abstract base class for a completion requestor which is passed completion
+ * proposals as they are generated in response to a code assist request.
+ * <p>
+ * This class is intended to be subclassed by clients.
+ * </p>
+ * <p>
+ * The code assist engine normally invokes methods on completion
+ * requestor in the following sequence:
+ * <pre>
+ * requestor.beginReporting();
+ * requestor.acceptContext(context);
+ * requestor.accept(proposal_1);
+ * requestor.accept(proposal_2);
+ * ...
+ * requestor.endReporting();
+ * </pre>
+ * If, however, the engine is unable to offer completion proposals
+ * for whatever reason, <code>completionFailure</code> is called
+ * with a problem object describing why completions were unavailable.
+ * In this case, the sequence of calls is:
+ * <pre>
+ * requestor.beginReporting();
+ * requestor.acceptContext(context);
+ * requestor.completionFailure(problem);
+ * requestor.endReporting();
+ * </pre>
+ * In either case, the bracketing <code>beginReporting</code>
+ * <code>endReporting</code> calls are always made as well as
+ * <code>acceptContext</code> call.
+ * </p>
+ * <p>
+ * The class was introduced in 3.0 as a more evolvable replacement
+ * for the <code>ICompletionRequestor</code> interface.
+ * </p>
+ *
+ * @see ICodeAssist
+ * @since 3.0
+ */
+public abstract class CompletionRequestor {
+
+	/**
+	 * The set of CompletionProposal kinds that this requestor
+	 * ignores; <code>0</code> means the set is empty.
+	 * 1 << completionProposalKind
+	 */
+	private int ignoreSet = 0;
+
+	private String[] favoriteReferences;
+
+	/**
+	 * The set of CompletionProposal kinds that this requestor
+	 * allows for required proposals; <code>0</code> means the set is empty.
+	 * 1 << completionProposalKind
+	 */
+	private int requiredProposalAllowSet[] = null;
+
+	private boolean requireExtendedContext = false;
+
+	/**
+	 * Creates a new completion requestor.
+	 * The requestor is interested in all kinds of completion
+	 * proposals; none will be ignored.
+	 *
+	 * Calls to this constructor are identical to calls to <code>CompletionRequestor(false)</code>
+	 */
+	public CompletionRequestor() {
+		this(false);
+	}
+
+	/**
+	 * Creates a new completion requestor.
+	 * If <code>ignoreAll</code> is <code>true</code> the requestor is not interested in
+	 * all kinds of completion proposals; all will be ignored. For each kind of completion proposals
+	 * that is of interest, <code>setIgnored(kind, false)</code> must be called.
+	 * If <code>ignoreAll</code> is <code>false</code> the requestor is interested in
+	 * all kinds of completion proposals; none will be ignored.
+	 *
+	 * @param ignoreAll <code>true</code> to ignore all kinds of completion proposals,
+	 * and <code>false</code> to propose all kinds
+	 *
+	 * @since 3.4
+	 */
+	public CompletionRequestor(boolean ignoreAll) {
+		this.ignoreSet = ignoreAll ? 0xffffffff : 0x00000000;
+	}
+
+	/**
+	 * Returns whether the given kind of completion proposal is ignored.
+	 *
+	 * @param completionProposalKind one of the kind constants declared
+	 * on <code>CompletionProposal</code>
+	 * @return <code>true</code> if the given kind of completion proposal
+	 * is ignored by this requestor, and <code>false</code> if it is of
+	 * interest
+	 * @see #setIgnored(int, boolean)
+	 * @see CompletionProposal#getKind()
+	 */
+	public boolean isIgnored(int completionProposalKind) {
+		if (completionProposalKind < CompletionProposal.FIRST_KIND
+			|| completionProposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown kind of completion proposal: "+completionProposalKind); //$NON-NLS-1$
+		}
+		return 0 != (this.ignoreSet & (1 << completionProposalKind));
+	}
+
+	/**
+	 * Sets whether the given kind of completion proposal is ignored.
+	 *
+	 * @param completionProposalKind one of the kind constants declared
+	 * on <code>CompletionProposal</code>
+	 * @param ignore <code>true</code> if the given kind of completion proposal
+	 * is ignored by this requestor, and <code>false</code> if it is of
+	 * interest
+	 * @see #isIgnored(int)
+	 * @see CompletionProposal#getKind()
+	 */
+	public void setIgnored(int completionProposalKind, boolean ignore) {
+		if (completionProposalKind < CompletionProposal.FIRST_KIND
+			|| completionProposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown kind of completion proposal: "+completionProposalKind); //$NON-NLS-1$
+		}
+		if (ignore) {
+			this.ignoreSet |= (1 << completionProposalKind);
+		} else {
+			this.ignoreSet &= ~(1 << completionProposalKind);
+		}
+	}
+
+	/**
+	 * Returns whether a proposal of a given kind with a required proposal
+	 * of the given kind is allowed.
+	 *
+	 * @param proposalKind one of the kind constants declared
+	 * @param requiredProposalKind one of the kind constants declared
+	 * on <code>CompletionProposal</code>
+	 * @return <code>true</code> if a proposal of a given kind with a required proposal
+	 * of the given kind is allowed by this requestor, and <code>false</code>
+	 * if it isn't of interest.
+	 * <p>
+	 * By default, all kinds of required proposals aren't allowed.
+	 * </p>
+	 * @see #setAllowsRequiredProposals(int, int, boolean)
+	 * @see CompletionProposal#getKind()
+	 * @see CompletionProposal#getRequiredProposals()
+	 *
+	 * @since 3.3
+	 */
+	public boolean isAllowingRequiredProposals(int proposalKind, int requiredProposalKind) {
+		if (proposalKind < CompletionProposal.FIRST_KIND
+			|| proposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
+			}
+
+		if (requiredProposalKind < CompletionProposal.FIRST_KIND
+			|| requiredProposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown required kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
+		}
+		if (this.requiredProposalAllowSet == null) return false;
+
+		return 0 != (this.requiredProposalAllowSet[proposalKind] & (1 << requiredProposalKind));
+	}
+
+	/**
+	 * Sets whether a proposal of a given kind with a required proposal
+	 * of the given kind is allowed.
+	 *
+	 * A required proposal of a given kind is proposed even if {@link #isIgnored(int)}
+	 * return <code>true</code> for that kind.
+	 *
+	 * Currently only a subset of kinds support required proposals. To see what combinations
+	 * are supported you must look at {@link CompletionProposal#getRequiredProposals()}
+	 * documentation.
+	 *
+	 * @param proposalKind one of the kind constants declared
+	 * @param requiredProposalKind one of the kind constants declared
+	 * on <code>CompletionProposal</code>
+	 * @param allow <code>true</code> if a proposal of a given kind with a required proposal
+	 * of the given kind is allowed by this requestor, and <code>false</code>
+	 * if it isn't of interest
+	 * @see #isAllowingRequiredProposals(int, int)
+	 * @see CompletionProposal#getKind()
+	 * @see CompletionProposal#getRequiredProposals()
+	 *
+	 * @since 3.3
+	 */
+	public void setAllowsRequiredProposals(int proposalKind, int requiredProposalKind, boolean allow) {
+		if (proposalKind < CompletionProposal.FIRST_KIND
+			|| proposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
+		}
+		if (requiredProposalKind < CompletionProposal.FIRST_KIND
+			|| requiredProposalKind > CompletionProposal.LAST_KIND) {
+				throw new IllegalArgumentException("Unknown required kind of completion proposal: "+requiredProposalKind); //$NON-NLS-1$
+		}
+
+		if (this.requiredProposalAllowSet == null) {
+			this.requiredProposalAllowSet = new int[CompletionProposal.LAST_KIND + 1];
+		}
+
+		if (allow) {
+			this.requiredProposalAllowSet[proposalKind] |= (1 << requiredProposalKind);
+		} else {
+			this.requiredProposalAllowSet[proposalKind] &= ~(1 << requiredProposalKind);
+		}
+	}
+
+	/**
+	 * Returns the favorite references which are used to compute some completion proposals.
+	 * <p>
+	 * A favorite reference is a qualified reference as it can be seen in an import statement.<br>
+	 * e.g. <code>{"java.util.Arrays"}</code><br>
+	 * It can be an on demand reference.<br>
+	 * e.g. <code>{"java.util.Arrays.*"}</code>
+	 * It can be a reference to a static method or field (as in a static import)<br>
+	 * e.g. <code>{"java.util.Arrays.equals"}</code>
+	 * </p>
+	 * <p>
+	 * Currently only on demand type references (<code>"java.util.Arrays.*"</code>),
+	 * references to a static method or a static field are used to compute completion proposals.
+	 * Other kind of reference could be used in the future.
+	 * </p>
+	 * @return favorite imports
+	 *
+	 * @since 3.3
+	 */
+	public String[] getFavoriteReferences() {
+		return this.favoriteReferences;
+	}
+
+	/**
+	 * Set the favorite references which will be used to compute some completion proposals.
+	 * A favorite reference is a qualified reference as it can be seen in an import statement.<br>
+	 *
+	 * @param favoriteImports
+	 *
+	 * @see #getFavoriteReferences()
+	 *
+	 * @since 3.3
+	 */
+	public void setFavoriteReferences(String[] favoriteImports) {
+		this.favoriteReferences = favoriteImports;
+	}
+
+	/**
+	 * Pro forma notification sent before reporting a batch of
+	 * completion proposals.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients may override.
+	 * </p>
+	 */
+	public void beginReporting() {
+		// do nothing
+	}
+
+	/**
+	 * Pro forma notification sent after reporting a batch of
+	 * completion proposals.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients may override.
+	 * </p>
+	 */
+	public void endReporting() {
+		// do nothing
+	}
+
+	/**
+	 * Notification of failure to produce any completions.
+	 * The problem object explains what prevented completing.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Clients may override to receive this kind of notice.
+	 * </p>
+	 *
+	 * @param problem the problem object
+	 */
+	public void completionFailure(IProblem problem) {
+		// default behavior is to ignore
+	}
+
+	/**
+	 * Proposes a completion. Has no effect if the kind of proposal
+	 * is being ignored by this requestor. Callers should consider
+	 * checking {@link #isIgnored(int)} before avoid creating proposal
+	 * objects that would only be ignored.
+	 * <p>
+	 * Similarly, implementers should check
+	 * {@link #isIgnored(int) isIgnored(proposal.getKind())}
+	 * and ignore proposals that have been declared as uninteresting.
+	 * The proposal object passed is only valid for the duration of
+	 * completion operation.
+	 *
+	 * @param proposal the completion proposal
+	 * @exception IllegalArgumentException if the proposal is null
+	 */
+	public abstract void accept(CompletionProposal proposal);
+
+	/**
+	 * Propose the context in which the completion occurs.
+	 * <p>
+	 * This method is called one and only one time before any call to
+	 * {@link #accept(CompletionProposal)}.
+	 * The default implementation of this method does nothing.
+	 * Clients may override.
+	 * </p>
+	 * @param context the completion context
+	 *
+	 * @since 3.1
+	 */
+	public void acceptContext(CompletionContext context) {
+		// do nothing
+	}
+
+	/**
+	 * Returns whether this requestor requires an extended context.
+	 *
+	 * By default this method return <code>false</code>.
+	 *
+	 * @return <code>true</code> if this requestor requires an extended context.
+	 *
+	 * @see CompletionContext#isExtended()
+	 *
+	 * @since 3.4
+	 */
+	public boolean isExtendedContextRequired() {
+		return this.requireExtendedContext;
+	}
+
+
+	/**
+	 * Sets whether this requestor requires an extended context.
+	 *
+	 * @param require <code>true</code> if this requestor requires an extended context.
+	 *
+	 * @see CompletionContext#isExtended()
+	 *
+	 * @since 3.4
+	 */
+	public void setRequireExtendedContext(boolean require) {
+		this.requireExtendedContext = require;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java
new file mode 100644
index 0000000..bb872dc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Adapter of the requestor interface <code>ICompletionRequestor</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @see ICompletionRequestor
+ * @since 2.0
+ * @deprecated Subclass {@link CompletionRequestor} instead.
+ */
+public class CompletionRequestorAdapter implements ICompletionRequestor {
+
+	/*
+	 * @see ICompletionRequestor#acceptAnonymousType(char[], char[], char[][], char[][], char[][], char[], int, int, int)
+	 */
+	public void acceptAnonymousType(
+		char[] superTypePackageName,
+		char[] superTypeName,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		char[][] parameterNames,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptClass(char[], char[], char[], int, int, int)
+	 */
+	public void acceptClass(
+		char[] packageName,
+		char[] className,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptError(IProblem)
+	 */
+	public void acceptError(IProblem error) {
+		// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptField(char[], char[], char[], char[], char[], char[], int, int, int)
+	 */
+	public void acceptField(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] name,
+		char[] typePackageName,
+		char[] typeName,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptInterface(char[], char[], char[], int, int, int)
+	 */
+	public void acceptInterface(
+		char[] packageName,
+		char[] interfaceName,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptKeyword(char[], int, int)
+	 */
+	public void acceptKeyword(
+		char[] keywordName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptLabel(char[], int, int)
+	 */
+	public void acceptLabel(
+		char[] labelName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptLocalVariable(char[], char[], char[], int, int, int)
+	 */
+	public void acceptLocalVariable(
+		char[] name,
+		char[] typePackageName,
+		char[] typeName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptMethod(char[], char[], char[], char[][], char[][], char[][], char[], char[], char[], int, int, int)
+	 */
+	public void acceptMethod(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		char[][] parameterNames,
+		char[] returnTypePackageName,
+		char[] returnTypeName,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptMethodDeclaration(char[], char[], char[], char[][], char[][], char[][], char[], char[], char[], int, int, int)
+	 */
+	public void acceptMethodDeclaration(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		char[][] parameterNames,
+		char[] returnTypePackageName,
+		char[] returnTypeName,
+		char[] completionName,
+		int modifiers,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptModifier(char[], int, int)
+	 */
+	public void acceptModifier(
+		char[] modifierName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptPackage(char[], char[], int, int)
+	 */
+	public void acceptPackage(
+		char[] packageName,
+		char[] completionName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptType(char[], char[], char[], int, int)
+	 */
+	public void acceptType(
+		char[] packageName,
+		char[] typeName,
+		char[] completionName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+
+	/*
+	 * @see ICompletionRequestor#acceptVariableName(char[], char[], char[], char[], int, int)
+	 */
+	public void acceptVariableName(
+		char[] typePackageName,
+		char[] typeName,
+		char[] name,
+		char[] completionName,
+		int completionStart,
+		int completionEnd,
+		int relevance) {
+			// default behavior is to ignore
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
new file mode 100644
index 0000000..0902f1a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * This class is the entry point for source corrections.
+ *
+ * This class is intended to be instantiated by clients.
+ *
+ * @since 2.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CorrectionEngine {
+
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected int correctionStart;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected int correctionEnd;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected int prefixLength;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected ICompilationUnit compilationUnit;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected ICorrectionRequestor correctionRequestor;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int CLASSES = 0x00000001;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int INTERFACES = 0x00000002;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int IMPORT = 0x00000004;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int METHOD = 0x00000008;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int FIELD = 0x00000010;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected static final int LOCAL = 0x00000020;
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected int filter;
+
+	/**
+	 * The CorrectionEngine is responsible for computing problem corrections.
+	 *
+	 *  @param setting java.util.Map
+	 *		set of options used to configure the code correction engine.
+	 * 		CURRENTLY THERE IS NO CORRECTION SPECIFIC SETTINGS.
+	 */
+	public CorrectionEngine(Map setting) {
+		// settings ignored for now
+	}
+
+	/**
+	 * Performs code correction for the given marker,
+	 * reporting results to the given correction requestor.
+	 *
+	 * Correction results are answered through a requestor.
+	 *
+	 * @param marker
+	 * 		the marker which describe the problem to correct.
+	 * @param targetUnit
+	 * 		replace the compilation unit given by the marker. Ignored if null.
+	 * @param positionOffset
+	 * 		the offset of position given by the marker.
+	 * @param requestor
+	 * 		the given correction requestor
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @exception JavaModelException currently this exception is never thrown, but the opportunity to thrown an exception
+	 * 	when the correction failed is kept for later.
+	 * @since 2.0
+	 */
+	public void computeCorrections(IMarker marker, ICompilationUnit targetUnit, int positionOffset, ICorrectionRequestor requestor) throws JavaModelException {
+
+		IJavaElement element = targetUnit == null ? JavaCore.create(marker.getResource()) : targetUnit;
+
+		if(!(element instanceof ICompilationUnit))
+			return;
+
+		ICompilationUnit unit = (ICompilationUnit) element;
+
+		int id = marker.getAttribute(IJavaModelMarker.ID, -1);
+		String[] args = Util.getProblemArgumentsFromMarker(marker.getAttribute(IJavaModelMarker.ARGUMENTS, "")); //$NON-NLS-1$
+		int start = marker.getAttribute(IMarker.CHAR_START, -1);
+		int end = marker.getAttribute(IMarker.CHAR_END, -1);
+
+		computeCorrections(unit, id, start + positionOffset, end + positionOffset, args, requestor);
+	}
+
+	/**
+	 * Performs code correction for the given IProblem,
+	 * reporting results to the given correction requestor.
+	 *
+	 * Correction results are answered through a requestor.
+	 *
+	 * @param problem
+	 * 		the problem which describe the problem to correct.
+	 * @param targetUnit
+	 * 		denote the compilation unit in which correction occurs. Cannot be null.
+	 * @param requestor
+	 * 		the given correction requestor
+	 * @exception IllegalArgumentException if <code>targetUnit</code> or <code>requestor</code> is <code>null</code>
+	 * @exception JavaModelException currently this exception is never thrown, but the opportunity to thrown an exception
+	 * 	when the correction failed is kept for later.
+	 * @since 2.0
+	 */
+	public void computeCorrections(IProblem problem, ICompilationUnit targetUnit, ICorrectionRequestor requestor) throws JavaModelException {
+		if (requestor == null) {
+			throw new IllegalArgumentException(Messages.correction_nullUnit);
+		}
+		this.computeCorrections(
+			targetUnit, problem.getID(),
+			problem.getSourceStart(),
+			problem.getSourceEnd(),
+			problem.getArguments(),
+			requestor);
+	}
+
+	/*
+	 * Ask the engine to compute a correction for the specified problem
+	 * of the given compilation unit.
+	 * Correction results are answered through a requestor.
+	 *
+	 *  @param unit org.eclipse.jdt.internal.core.ICompilationUnit
+	 *      the compilation unit.
+	 *
+	 * 	@param id int
+	 * 		the id of the problem.
+	 *
+	 * 	@param start int
+	 * 		a position in the source where the error begin.
+	 *
+	 *  @param end int
+	 *      a position in the source where the error finish.
+	 *
+	 * 	@param arguments String[]
+	 * 		arguments of the problem.
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @exception JavaModelException currently this exception is never thrown, but the opportunity to thrown an exception
+	 * 	when the correction failed is kept for later.
+	 * @since 2.0
+	 */
+	private void computeCorrections(ICompilationUnit unit, int id, int start, int end, String[] arguments, ICorrectionRequestor requestor) {
+
+		if(id == -1 || arguments == null || start == -1 || end == -1)
+			return;
+		if (requestor == null) {
+			throw new IllegalArgumentException(Messages.correction_nullRequestor);
+		}
+
+		this.correctionRequestor = requestor;
+		this.correctionStart = start;
+		this.correctionEnd = end;
+		this.compilationUnit = unit;
+
+		String argument = null;
+		try {
+			switch (id) {
+				// Type correction
+				case IProblem.ImportNotFound :
+					this.filter = IMPORT;
+					argument = arguments[0];
+					break;
+				case IProblem.UndefinedType :
+					this.filter = CLASSES | INTERFACES;
+					argument = arguments[0];
+					break;
+
+				// Method correction
+				case IProblem.UndefinedMethod :
+					this.filter = METHOD;
+					argument = arguments[1];
+					break;
+
+				// Field and local variable correction
+				case IProblem.UndefinedField :
+					this.filter = FIELD;
+					argument = arguments[0];
+					break;
+				case IProblem.UndefinedName :
+				case IProblem.UnresolvedVariable :
+					this.filter = FIELD | LOCAL;
+					argument = arguments[0];
+					break;
+			}
+		} catch (ArrayIndexOutOfBoundsException e) {
+			return;
+		}
+		if(argument != null) {
+			correct(argument.toCharArray());
+		}
+	}
+
+	private void correct(char[] argument) {
+		try {
+			String source = this.compilationUnit.getSource();
+			Map currentProjectOptions = this.compilationUnit.getJavaProject().getOptions(true);
+			long sourceLevel = CompilerOptions.versionToJdkLevel(currentProjectOptions.get(JavaCore.COMPILER_SOURCE));
+			long complianceLevel = CompilerOptions.versionToJdkLevel(currentProjectOptions.get(JavaCore.COMPILER_COMPLIANCE));
+			
+			Scanner scanner =
+				new Scanner(
+					false /*comment*/,
+					false /*whitespace*/,
+					false /*nls*/,
+					sourceLevel,
+					complianceLevel,
+					null/*taskTag*/,
+					null/*taskPriorities*/,
+					true /*taskCaseSensitive*/);
+			scanner.setSource(source.toCharArray());
+
+			scanner.resetTo(this.correctionStart, this.correctionEnd);
+			int token = 0;
+			char[] argumentSource = CharOperation.NO_CHAR;
+
+			// search last segment position
+			while(true) {
+				token = scanner.getNextToken();
+				if (token == TerminalTokens.TokenNameEOF) return;
+
+				char[] tokenSource = scanner.getCurrentTokenSource();
+
+				argumentSource = CharOperation.concat(argumentSource, tokenSource);
+				if(!CharOperation.prefixEquals(argumentSource, argument))
+					return;
+
+				if(CharOperation.equals(argument, argumentSource)) {
+					this.correctionStart = scanner.startPosition;
+					this.correctionEnd = scanner.currentPosition;
+					this.prefixLength = CharOperation.lastIndexOf('.', argument) + 1;
+					break;
+				}
+
+			}
+
+			// search completion position
+			int completionPosition = this.correctionStart;
+			scanner.resetTo(completionPosition, this.correctionEnd);
+			int position = completionPosition;
+
+			for (int i = 0; i < 4; i++) {
+				if(scanner.getNextCharAsJavaIdentifierPart()) {
+					completionPosition = position;
+					position = scanner.currentPosition;
+				} else {
+					break;
+				}
+			}
+			Hashtable oldOptions = JavaCore.getOptions();
+			try {
+				Hashtable options = new Hashtable(oldOptions);
+				options.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.DISABLED);
+				JavaCore.setOptions(options);
+
+				this.compilationUnit.codeComplete(
+					completionPosition,
+					this.completionRequestor
+				);
+			} finally {
+				JavaCore.setOptions(oldOptions);
+			}
+		} catch (JavaModelException e) {
+			return;
+		} catch (InvalidInputException e) {
+			return;
+		}
+	}
+
+	/**
+	 * This field is not intended to be used by client.
+	 */
+	protected CompletionRequestor completionRequestor = new CompletionRequestor() {
+		public void accept(CompletionProposal proposal) {
+			switch (proposal.getKind()) {
+				case CompletionProposal.TYPE_REF:
+					int flags = proposal.getFlags();
+					if (!(Flags.isEnum(flags) || Flags.isAnnotation(flags))) {
+						if((CorrectionEngine.this.filter & (CLASSES | INTERFACES)) != 0) {
+							char[] completionName = proposal.getCompletion();
+							CorrectionEngine.this.correctionRequestor.acceptClass(
+								proposal.getDeclarationSignature(),
+								Signature.getSignatureSimpleName(proposal.getSignature()),
+								CharOperation.subarray(completionName, CorrectionEngine.this.prefixLength, completionName.length),
+								proposal.getFlags(),
+								CorrectionEngine.this.correctionStart,
+								CorrectionEngine.this.correctionEnd);
+						} else if((CorrectionEngine.this.filter & IMPORT) != 0) {
+							char[] packageName = proposal.getDeclarationSignature();
+							char[] className = Signature.getSignatureSimpleName(proposal.getSignature());
+							char[] fullName = CharOperation.concat(packageName, className, '.');
+							CorrectionEngine.this.correctionRequestor.acceptClass(
+								packageName,
+								className,
+								CharOperation.subarray(fullName, CorrectionEngine.this.prefixLength, fullName.length),
+								proposal.getFlags(),
+								CorrectionEngine.this.correctionStart,
+								CorrectionEngine.this.correctionEnd);
+						}
+					}
+					break;
+				case CompletionProposal.FIELD_REF:
+					if((CorrectionEngine.this.filter & FIELD) != 0) {
+						char[] declaringSignature = proposal.getDeclarationSignature();
+						char[] signature = proposal.getSignature();
+						CorrectionEngine.this.correctionRequestor.acceptField(
+							Signature.getSignatureQualifier(declaringSignature),
+							Signature.getSignatureSimpleName(declaringSignature),
+							proposal.getName(),
+							Signature.getSignatureQualifier(signature),
+							Signature.getSignatureSimpleName(signature),
+							proposal.getName(),
+							proposal.getFlags(),
+							CorrectionEngine.this.correctionStart,
+							CorrectionEngine.this.correctionEnd);
+					}
+					break;
+				case CompletionProposal.LOCAL_VARIABLE_REF:
+					if((CorrectionEngine.this.filter & LOCAL) != 0) {
+						char[] signature = proposal.getSignature();
+						CorrectionEngine.this.correctionRequestor.acceptLocalVariable(
+							proposal.getName(),
+							Signature.getSignatureQualifier(signature),
+							Signature.getSignatureSimpleName(signature),
+							proposal.getFlags(),
+							CorrectionEngine.this.correctionStart,
+							CorrectionEngine.this.correctionEnd);
+					}
+					break;
+				case CompletionProposal.METHOD_REF:
+					if((CorrectionEngine.this.filter & METHOD) != 0) {
+						char[] declaringSignature = proposal.getDeclarationSignature();
+						char[] signature = proposal.getSignature();
+						char[][] parameterTypeSignatures = Signature.getParameterTypes(signature);
+						int length = parameterTypeSignatures.length;
+						char[][] parameterPackageNames = new char[length][];
+						char[][] parameterTypeNames = new char[length][];
+						for (int i = 0; i < length; i++) {
+							parameterPackageNames[i] = Signature.getSignatureQualifier(parameterTypeSignatures[i]);
+							parameterTypeNames[i] = Signature.getSignatureSimpleName(parameterTypeSignatures[i]);
+						}
+						char[] returnTypeSignature = Signature.getReturnType(signature);
+						CorrectionEngine.this.correctionRequestor.acceptMethod(
+							Signature.getSignatureQualifier(declaringSignature),
+							Signature.getSignatureSimpleName(declaringSignature),
+							proposal.getName(),
+							parameterPackageNames,
+							parameterTypeNames,
+							proposal.findParameterNames(null),
+							Signature.getSignatureQualifier(returnTypeSignature),
+							Signature.getSignatureSimpleName(returnTypeSignature),
+							proposal.getName(),
+							proposal.getFlags(),
+							CorrectionEngine.this.correctionStart,
+							CorrectionEngine.this.correctionEnd);
+					}
+					break;
+				case CompletionProposal.PACKAGE_REF:
+					if((CorrectionEngine.this.filter & (CLASSES | INTERFACES | IMPORT)) != 0) {
+						char[] packageName = proposal.getDeclarationSignature();
+						CorrectionEngine.this.correctionRequestor.acceptPackage(
+							packageName,
+							CharOperation.subarray(packageName, CorrectionEngine.this.prefixLength, packageName.length),
+							CorrectionEngine.this.correctionStart,
+							CorrectionEngine.this.correctionEnd);
+					}
+					break;
+			}
+		}
+	};
+
+
+	/**
+	 * Return an array of strings which contains one entry per warning token
+	 * accepted by the <code>@SuppressWarnings</code> annotation. This array is
+	 * neither null nor empty, it contains at least the String <code>all</code>.
+	 * It should not be modified by the caller (please take a copy if modifications
+	 * are needed).<br>
+	 * <b>Note:</b> The tokens returned are not necessarily standardized across Java
+	 * compilers. If you were to use one of these tokens in a <code>@SuppressWarnings</code>
+	 * annotation in the Java source code, the effects (if any) may vary from
+	 * compiler to compiler.
+	 *
+	 * @return an array of strings which contains one entry per warning token
+	 * 			accepted by the <code>@SuppressWarnings</code> annotation.
+	 * @since 3.2
+	 */
+	public static String[] getAllWarningTokens() {
+		return CompilerOptions.warningTokens;
+	}
+
+	/**
+	 * Helper method for decoding problem marker attributes. Returns an array of String arguments
+	 * extracted from the problem marker "arguments" attribute, or <code>null</code> if the marker
+	 * "arguments" attribute is missing or ill-formed.
+	 *
+	 * @param problemMarker
+	 * 		the problem marker to decode arguments from.
+	 * @return an array of String arguments, or <code>null</code> if unable to extract arguments
+	 * @since 2.1
+	 */
+	public static String[] getProblemArguments(IMarker problemMarker){
+		String argumentsString = problemMarker.getAttribute(IJavaModelMarker.ARGUMENTS, null);
+		return Util.getProblemArgumentsFromMarker(argumentsString);
+	}
+
+	/**
+	 * Returns a token which can be used to suppress a given warning using
+	 * <code>@SuppressWarnings</code> annotation, for a given problem ID
+	 * ({@link IProblem }). If a particular problem is not suppressable,
+	 * <code>null</code> will be returned.
+	 * <p>
+	 * <b>Note:</b> <code>@SuppressWarnings</code> can only suppress warnings,
+	 * which means that if some problems got promoted to ERROR using custom compiler
+	 * settings ({@link IJavaProject#setOption(String, String)}), the
+	 * <code>@SuppressWarnings</code> annotation will be ineffective.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> <code>@SuppressWarnings</code> can be argumented with
+	 * <code>"all"</code> so as to suppress all possible warnings at once.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> The tokens returned are not necessarily standardized across Java
+	 * compilers. If you were to use one of these tokens in an @SuppressWarnings
+	 * annotation in the Java source code, the effects (if any) may vary from
+	 * compiler to compiler.
+	 * </p>
+	 * @param problemID
+	 *         the ID of a given warning to suppress
+	 * @return a String which can be used in <code>@SuppressWarnings</code> annotation,
+	 * or <code>null</code> if unable to suppress this warning.
+	 * @since 3.1
+	 */
+	public static String getWarningToken(int problemID){
+		int irritant = ProblemReporter.getIrritant(problemID);
+		if (irritant != 0) {
+			return CompilerOptions.warningTokenFromIrritant(irritant);
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java
new file mode 100644
index 0000000..7a5c239
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.EventObject;
+
+/**
+ * An element changed event describes a change to the structure or contents
+ * of a tree of Java elements. The changes to the elements are described by
+ * the associated delta object carried by this event.
+ * <p>
+ * This class is not intended to be instantiated or subclassed by clients.
+ * Instances of this class are automatically created by the Java model.
+ * </p>
+ *
+ * @see IElementChangedListener
+ * @see IJavaElementDelta
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ElementChangedEvent extends EventObject {
+
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta()</code>.
+	 *
+	 * Note: this notification occurs during the corresponding POST_CHANGE
+	 * resource change notification, and contains a full delta accounting for
+	 * any JavaModel operation  and/or resource change.
+	 *
+	 * @see IJavaElementDelta
+	 * @see org.eclipse.core.resources.IResourceChangeEvent
+	 * @see #getDelta()
+	 * @since 2.0
+	 */
+	public static final int POST_CHANGE = 1;
+
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta</code>.
+	 *
+	 * Note: this notification occurs during the corresponding PRE_AUTO_BUILD
+	 * resource change notification. The delta, which is notified here, only contains
+	 * information relative to the previous JavaModel operations (in other words,
+	 * it ignores the possible resources which have changed outside Java operations).
+	 * In particular, it is possible that the JavaModel be inconsistent with respect to
+	 * resources, which got modified outside JavaModel operations (it will only be
+	 * fully consistent once the POST_CHANGE notification has occurred).
+	 *
+	 * @see IJavaElementDelta
+	 * @see org.eclipse.core.resources.IResourceChangeEvent
+	 * @see #getDelta()
+	 * @since 2.0
+	 * @deprecated - no longer used, such deltas are now notified during POST_CHANGE
+	 */
+	public static final int PRE_AUTO_BUILD = 2;
+
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta</code>.
+	 *
+	 * Note: this notification occurs as a result of a working copy reconcile
+	 * operation.
+	 *
+	 * @see IJavaElementDelta
+	 * @see org.eclipse.core.resources.IResourceChangeEvent
+	 * @see #getDelta()
+	 * @since 2.0
+	 */
+	public static final int 	POST_RECONCILE = 4;
+
+	private static final long serialVersionUID = -8947240431612844420L; // backward compatible
+
+	/*
+	 * Event type indicating the nature of this event.
+	 * It can be a combination either:
+	 *  - POST_CHANGE
+	 *  - PRE_AUTO_BUILD
+	 *  - POST_RECONCILE
+	 */
+	private int type;
+
+	/**
+	 * Creates an new element changed event (based on a <code>IJavaElementDelta</code>).
+	 *
+	 * @param delta the Java element delta.
+	 * @param type the type of delta (ADDED, REMOVED, CHANGED) this event contains
+	 */
+	public ElementChangedEvent(IJavaElementDelta delta, int type) {
+		super(delta);
+		this.type = type;
+	}
+	/**
+	 * Returns the delta describing the change.
+	 *
+	 * @return the delta describing the change
+	 */
+	public IJavaElementDelta getDelta() {
+		return (IJavaElementDelta) this.source;
+	}
+
+	/**
+	 * Returns the type of event being reported.
+	 *
+	 * @return one of the event type constants
+	 * @see #POST_CHANGE
+	 * @see #PRE_AUTO_BUILD
+	 * @see #POST_RECONCILE
+	 * @since 2.0
+	 */
+	public int getType() {
+		return this.type;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java
new file mode 100644
index 0000000..92fbc9d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java
@@ -0,0 +1,478 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added constant AccDefault
+ *     IBM Corporation - added constants AccBridge and AccVarargs for J2SE 1.5
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+
+/**
+ * Utility class for decoding modifier flags in Java elements.
+ * <p>
+ * This class provides static methods only.
+ * </p>
+ * <p>
+ * Note that the numeric values of these flags match the ones for class files
+ * as described in the Java Virtual Machine Specification (except for
+ * {@link #AccDeprecated}, {@link #AccAnnotationDefault}, and {@link #AccDefaultMethod}).
+ * </p>
+ * <p>
+ * The AST class <code>Modifier</code> provides
+ * similar functionality as this class, only in the
+ * <code>org.eclipse.jdt.core.dom</code> package.
+ * </p>
+ *
+ * @see IMember#getFlags()
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Flags {
+
+	/**
+	 * Constant representing the absence of any flag.
+	 * @since 3.0
+	 */
+	public static final int AccDefault = ClassFileConstants.AccDefault;
+	/**
+	 * Public access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccPublic = ClassFileConstants.AccPublic;
+	/**
+	 * Private access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccPrivate = ClassFileConstants.AccPrivate;
+	/**
+	 * Protected access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccProtected = ClassFileConstants.AccProtected;
+	/**
+	 * Static access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccStatic = ClassFileConstants.AccStatic;
+	/**
+	 * Final access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccFinal = ClassFileConstants.AccFinal;
+	/**
+	 * Synchronized access flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccSynchronized = ClassFileConstants.AccSynchronized;
+	/**
+	 * Volatile property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccVolatile = ClassFileConstants.AccVolatile;
+	/**
+	 * Transient property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccTransient = ClassFileConstants.AccTransient;
+	/**
+	 * Native property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccNative = ClassFileConstants.AccNative;
+	/**
+	 * Interface property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccInterface = ClassFileConstants.AccInterface;
+	/**
+	 * Abstract property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccAbstract = ClassFileConstants.AccAbstract;
+	/**
+	 * Strictfp property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccStrictfp = ClassFileConstants.AccStrictfp;
+	/**
+	 * Super property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccSuper = ClassFileConstants.AccSuper;
+	/**
+	 * Synthetic property flag. See The Java Virtual Machine Specification for more details.
+	 * @since 2.0
+	 */
+	public static final int AccSynthetic = ClassFileConstants.AccSynthetic;
+	/**
+	 * Deprecated property flag.
+	 * <p>
+	 * Note that this flag's value is internal and is not defined in the
+	 * Virtual Machine specification.
+	 * </p>
+	 * @since 2.0
+	 */
+	public static final int AccDeprecated = ClassFileConstants.AccDeprecated;
+
+	/**
+	 * Bridge method property flag (added in J2SE 1.5). Used to flag a compiler-generated
+	 * bridge methods.
+	 * See The Java Virtual Machine Specification for more details.
+	 * @since 3.0
+	 */
+	public static final int AccBridge = ClassFileConstants.AccBridge;
+
+	/**
+	 * Varargs method property flag (added in J2SE 1.5).
+	 * Used to flag variable arity method declarations.
+	 * See The Java Virtual Machine Specification for more details.
+	 * @since 3.0
+	 */
+	public static final int AccVarargs = ClassFileConstants.AccVarargs;
+
+	/**
+	 * Enum property flag (added in J2SE 1.5).
+	 * See The Java Virtual Machine Specification for more details.
+	 * @since 3.0
+	 */
+	public static final int AccEnum = ClassFileConstants.AccEnum;
+
+	/**
+	 * Annotation property flag (added in J2SE 1.5).
+	 * See The Java Virtual Machine Specification for more details.
+	 * @since 3.0
+	 */
+	public static final int AccAnnotation = ClassFileConstants.AccAnnotation;
+
+	/**
+	 * Default method property flag.
+	 * <p>
+	 * Note that this flag's value is internal and is not defined in the
+	 * Virtual Machine specification.
+	 * </p>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int AccDefaultMethod = ExtraCompilerModifiers.AccDefaultMethod;
+
+	/**
+	 * Annotation method default property flag.
+	 * Used to flag annotation type methods that declare a default value.
+	 * <p>
+	 * Note that this flag's value is internal and is not defined in the
+	 * Virtual Machine specification.
+	 * </p>
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static final int AccAnnotationDefault = ClassFileConstants.AccAnnotationDefault;
+	
+	/**
+	 * Not instantiable.
+	 */
+	private Flags() {
+		// Not instantiable
+	}
+	/**
+	 * Returns whether the given integer includes the <code>abstract</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>abstract</code> modifier is included
+	 */
+	public static boolean isAbstract(int flags) {
+		return (flags & AccAbstract) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the indication that the
+	 * element is deprecated (<code>@deprecated</code> tag in Javadoc comment).
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the element is marked as deprecated
+	 */
+	public static boolean isDeprecated(int flags) {
+		return (flags & AccDeprecated) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>final</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>final</code> modifier is included
+	 */
+	public static boolean isFinal(int flags) {
+		return (flags & AccFinal) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>interface</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>interface</code> modifier is included
+	 * @since 2.0
+	 */
+	public static boolean isInterface(int flags) {
+		return (flags & AccInterface) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>native</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>native</code> modifier is included
+	 */
+	public static boolean isNative(int flags) {
+		return (flags & AccNative) != 0;
+	}
+	/**
+	 * Returns whether the given integer does not include one of the
+	 * <code>public</code>, <code>private</code>, or <code>protected</code> flags.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if no visibility flag is set
+	 * @since 3.2
+	 */
+	public static boolean isPackageDefault(int flags) {
+		return (flags & (AccPublic | AccPrivate | AccProtected)) == 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>private</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>private</code> modifier is included
+	 */
+	public static boolean isPrivate(int flags) {
+		return (flags & AccPrivate) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>protected</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>protected</code> modifier is included
+	 */
+	public static boolean isProtected(int flags) {
+		return (flags & AccProtected) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>public</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>public</code> modifier is included
+	 */
+	public static boolean isPublic(int flags) {
+		return (flags & AccPublic) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>static</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>static</code> modifier is included
+	 */
+	public static boolean isStatic(int flags) {
+		return (flags & AccStatic) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>super</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>super</code> modifier is included
+	 * @since 3.2
+	 */
+	public static boolean isSuper(int flags) {
+		return (flags & AccSuper) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>strictfp</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>strictfp</code> modifier is included
+	 */
+	public static boolean isStrictfp(int flags) {
+		return (flags & AccStrictfp) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>synchronized</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>synchronized</code> modifier is included
+	 */
+	public static boolean isSynchronized(int flags) {
+		return (flags & AccSynchronized) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the indication that the
+	 * element is synthetic.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the element is marked synthetic
+	 */
+	public static boolean isSynthetic(int flags) {
+		return (flags & AccSynthetic) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>transient</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>transient</code> modifier is included
+	 */
+	public static boolean isTransient(int flags) {
+		return (flags & AccTransient) != 0;
+	}
+	/**
+	 * Returns whether the given integer includes the <code>volatile</code> modifier.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>volatile</code> modifier is included
+	 */
+	public static boolean isVolatile(int flags) {
+		return (flags & AccVolatile) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccBridge</code>
+	 * bit set.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>AccBridge</code> flag is included
+	 * @see #AccBridge
+	 * @since 3.0
+	 */
+	public static boolean isBridge(int flags) {
+		return (flags & AccBridge) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccVarargs</code>
+	 * bit set.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>AccVarargs</code> flag is included
+	 * @see #AccVarargs
+	 * @since 3.0
+	 */
+	public static boolean isVarargs(int flags) {
+		return (flags & AccVarargs) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccEnum</code>
+	 * bit set.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>AccEnum</code> flag is included
+	 * @see #AccEnum
+	 * @since 3.0
+	 */
+	public static boolean isEnum(int flags) {
+		return (flags & AccEnum) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccAnnotation</code>
+	 * bit set.
+	 *
+	 * @param flags the flags
+	 * @return <code>true</code> if the <code>AccAnnotation</code> flag is included
+	 * @see #AccAnnotation
+	 * @since 3.0
+	 */
+	public static boolean isAnnotation(int flags) {
+		return (flags & AccAnnotation) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccDefaultMethod</code>
+	 * bit set. Note that this flag represents the usage of the 'default' keyword
+	 * on a method and should not be confused with the 'package' access visibility (which used to be called 'default access').
+	 *
+	 * @return <code>true</code> if the <code>AccDefaultMethod</code> flag is included
+	 * @see #AccDefaultMethod
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static boolean isDefaultMethod(int flags) {
+		return (flags & AccDefaultMethod) != 0;
+	}
+
+	/**
+	 * Returns whether the given integer has the <code>AccAnnnotationDefault</code>
+	 * bit set.
+	 *
+	 * @return <code>true</code> if the <code>AccAnnotationDefault</code> flag is included
+	 * @see #AccAnnotationDefault
+	 * @since 3.9 BETA_JAVA8
+	 */
+	public static boolean isAnnnotationDefault(int flags) {
+		return (flags & AccAnnotationDefault) != 0;
+	}
+	
+	/**
+	 * Returns a standard string describing the given modifier flags.
+	 * Only modifier flags are included in the output; deprecated,
+	 * synthetic, bridge, etc. flags are ignored.
+	 * <p>
+	 * The flags are output in the following order:
+	 * <pre> public protected private
+	 * abstract default static final synchronized native strictfp transient volatile</pre>
+	 * <p>
+	 * This order is consistent with the recommendations in JLS8 ("*Modifier:" rules in chapters 8 and 9).
+	 * </p>
+	 * <p>
+	 * Note that the flags of a method can include the AccVarargs flag that has no standard description. Since the AccVarargs flag has the same value as
+	 * the AccTransient flag (valid for fields only), attempting to get the description of method modifiers with the AccVarargs flag set would result in an
+	 * unexpected description. Clients should ensure that the AccVarargs is not included in the flags of a method as follows:
+	 * <pre>
+	 * IMethod method = ...
+	 * int flags = method.getFlags() & ~Flags.AccVarargs;
+	 * return Flags.toString(flags);
+	 * </pre>
+	 * </p>
+	 * <p>
+	 * Examples results:
+	 * <pre>
+	 *	  <code>"public static final"</code>
+	 *	  <code>"private native"</code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param flags the flags
+	 * @return the standard string representation of the given flags
+	 */
+	public static String toString(int flags) {
+		StringBuffer sb = new StringBuffer();
+
+		if (isPublic(flags))
+			sb.append("public "); //$NON-NLS-1$
+		if (isProtected(flags))
+			sb.append("protected "); //$NON-NLS-1$
+		if (isPrivate(flags))
+			sb.append("private "); //$NON-NLS-1$
+		if (isAbstract(flags))
+			sb.append("abstract "); //$NON-NLS-1$
+		if (isDefaultMethod(flags))
+			sb.append("default "); //$NON-NLS-1$
+		if (isStatic(flags))
+			sb.append("static "); //$NON-NLS-1$
+		if (isFinal(flags))
+			sb.append("final "); //$NON-NLS-1$
+		if (isSynchronized(flags))
+			sb.append("synchronized "); //$NON-NLS-1$
+		if (isNative(flags))
+			sb.append("native "); //$NON-NLS-1$
+		if (isStrictfp(flags))
+			sb.append("strictfp "); //$NON-NLS-1$
+		if (isTransient(flags))
+			sb.append("transient "); //$NON-NLS-1$
+		if (isVolatile(flags))
+			sb.append("volatile "); //$NON-NLS-1$
+		int len = sb.length();
+		if (len == 0)
+			return ""; //$NON-NLS-1$
+		sb.setLength(len - 1);
+		return sb.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
new file mode 100644
index 0000000..12f4e3b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Describes an access rule to source and class files on a classpath entry.
+ * An access rule is composed of a file pattern and a kind (accessible,
+ * non accessible, or discouraged).
+ * <p>
+ * On a given classpath entry, the access rules are considered in the order given
+ * when the entry was created. When a source or class file matches an access
+ * rule's pattern, the access rule's kind defines whether the file is considered
+ * accessible, non-accessible, or whether its access is discouraged. If the source or class
+ * file doesn't match any access rule, it is considered accessible. A source or class
+ * file that is not accessible or discouraged can still be referred to, but it is tagged as being not
+ * accessible - the Java builder will create a problem marker, for example.
+ * The severity of the marker created from a non-accessible rule is controlled through
+ * the {@link JavaCore#COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
+ * The severity of the marker created from a discouraged rule is controlled through
+ * the {@link JavaCore#COMPILER_PB_DISCOURAGED_REFERENCE} compiler option.
+ * Note this is different from inclusion and exclusion patterns on source classpath entries,
+ * where a source file that is excluded is not even compiled.
+ * </p>
+ * <p>
+ * Files patterns look like relative file paths with wildcards and are interpreted relative
+ * to each entry's path.
+ * File patterns are case-sensitive and they can contain '**', '*' or '?' wildcards (see
+ * {@link IClasspathEntry#getExclusionPatterns()} for the full description
+ * of their syntax and semantics).
+ * Note that file patterns must not include the file extension.
+ * <code>com/xyz/tests/MyClass</code> is a valid file pattern, whereas
+ * <code>com/xyz/tests/MyClass.class</code> is not valid.
+ * </p>
+ * <p>
+ * For example, if a classpath entry path is <code>/Project/someLib.jar</code>,
+ * there are no accessible rules, and there is one non-accessible rule with pattern
+ * <code>com/xyz/tests/&#42;&#42;</code>, then class files
+ * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
+ * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
+ * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
+ * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
+ * accessible.
+ * </p>
+ *
+ * @since 3.1
+ * 
+ * @see JavaCore#newAccessRule(IPath, int)
+ * @see IClasspathEntry#getExclusionPatterns()
+ * 
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAccessRule {
+
+	/**
+	 * Constant indicating that files matching the rule's pattern are accessible.
+	 */
+	int K_ACCESSIBLE = 0;
+
+	/**
+	 * Constant indicating that files matching the rule's pattern are non-accessible.
+	 */
+	int K_NON_ACCESSIBLE = 1;
+
+	/**
+	 * Constant indicating that access to the files matching the rule's pattern is discouraged.
+	 */
+	int K_DISCOURAGED = 2;
+
+	/**
+	 * <p>Flag indicating that whether a type matching this rule should be ignored iff a type with
+	 * the same qualified name can be found on a later classpath entry with a better
+	 * accessibility.</p>
+	 * <p>E.g. if a type p.X matches a rule K_NON_ACCESSIBLE | IGNORE_IF_BETTER
+	 * on a library entry 'lib1' and another type p.X also matches a rule
+	 * K_DISCOURAGED on library entry 'lib2' ('lib2' being after 'lib1' on the
+	 * classpath), then p.X from 'lib2' will be used and reported as
+	 * discouraged.</p>
+	 *
+	 * @since 3.2
+	 */
+	int IGNORE_IF_BETTER = 0x100;
+
+	/**
+	 * Returns the file pattern for this access rule.
+	 *
+	 * @return the file pattern for this access rule
+	 *
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	IPath getPattern();
+
+	/**
+	 * Returns the kind of this access rule (one of {@link #K_ACCESSIBLE}, {@link #K_NON_ACCESSIBLE}
+	 * or {@link #K_DISCOURAGED}).
+	 *
+	 * @return the kind of this access rule
+	 */
+	int getKind();
+
+	/**
+	 * <p>Returns whether a type matching this rule should be ignored iff a type with
+	 * the same qualified name can be found on a later classpath entry with a better
+	 * accessibility.</p>
+	 * <p>E.g. if a type p.X matches a rule K_NON_ACCESSIBLE | IGNORE_IF_BETTER
+	 * on a library entry 'lib1' and another type p.X also matches a rule
+	 * K_DISCOURAGED on library entry 'lib2' ('lib2' being after 'lib1' on the
+	 * classpath), then p.X from 'lib2' will be used and reported as
+	 * discouraged.</p>
+	 *
+	 * @return whether a type matching this rule should be ignored iff a type
+	 *              with the same qualified name can be found on a later classpath
+	 *              entry with a better accessibility
+	 * @since 3.2
+	 */
+	boolean ignoreIfBetter();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotatable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotatable.java
new file mode 100644
index 0000000..a9765a8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotatable.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Common protocol for Java elements that can be annotated.
+ *
+ * @since 3.4
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAnnotatable {
+
+	/**
+	 * Returns the annotation with the given name declared on this element.
+	 * This is a handle-only method. The annotation may or may not exist.
+	 *
+	 * @param name the given simple name
+	 * @return the annotation with the given name declared on this element
+	 */
+	IAnnotation getAnnotation(String name);
+
+	/**
+	 * Returns the annotations for this element.
+	 * Returns an empty array if this element has no annotations.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *      exception occurs while accessing its corresponding resource.
+	 * @return the annotations of this element,
+	 * 		in the order declared in the source, or an empty array if none
+	 * @since 3.4
+	 */
+	IAnnotation[] getAnnotations() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotation.java
new file mode 100644
index 0000000..36dca8f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAnnotation.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents an annotation on a package declaration, a type, a method, a field
+ * or a local variable in a compilation unit or a class file.
+ * <p>
+ * Annotations are obtained using {@link IAnnotatable#getAnnotation(String)}.
+ * </p><p>
+ * Note that annotations are not children of their declaring element.
+ * To get a list of the annotations use {@link IAnnotatable#getAnnotations()}.
+ * </p>
+ *
+ * @since 3.4
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAnnotation extends IJavaElement, ISourceReference {
+
+	/**
+	 * Returns the name of this annotation. If this annotation is coming from
+	 * a compilation unit, this is either a simple name (e.g. for <code>@MyAnnot</code>, the name
+ 	 * is "MyAnnot"), or a qualified name  (e.g. for <code>@x. y.    MyAnnot</code>, the name is
+ 	 * "x.y.MyAnnot"). If this annotation is coming from a class file, this is always a fully
+ 	 * qualified name.
+ 	 * <p>Note that the name has been trimmed from its whitespaces. To extract the name as it
+ 	 * appears in the source, use {@link #getNameRange()}.
+ 	 * </p><p>
+	 * This is a handle-only method.  The annotation may or may not be present.
+	 * </p>
+	 *
+	 * @return the name of this annotation
+	 */
+	String getElementName();
+
+	/**
+	 * Returns the member-value pairs of this annotation. Returns an empty
+	 * array if this annotation is a marker annotation. Returns a size-1 array if this
+	 * annotation is a single member annotation. In this case, the member
+	 * name is always <code>"value"</code>.
+	 *
+	 * @return the member-value pairs of this annotation
+	 * @throws JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	IMemberValuePair[] getMemberValuePairs() throws JavaModelException;
+
+	/**
+	 * Returns the position relative to the order this annotation is defined in the source.
+	 * Numbering starts at 1 (thus the first occurrence is occurrence 1, not occurrence 0).
+	 * <p>
+	 * Two annotations ann1 and ann2 that are equal (e.g. 2 annotations with the same name on
+	 * the same type) can be distinguished using their occurrence counts. If annotation
+	 * ann1 appears first in the source, it will have an occurrence count of 1. If annotation
+	 * ann2 appears right after annotation ann1, it will have an occurrence count of 2.
+	 * </p><p>
+	 * This is a handle-only method.  The annotation may or may not be present.
+	 * </p>
+	 *
+	 * @return the position relative to the order this annotation is defined in the source
+	 */
+	int getOccurrenceCount();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java
new file mode 100644
index 0000000..9cebaa2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.UndoEdit;
+
+/**
+ * A buffer contains the text contents of a resource. It is not language-specific.
+ * The contents may be in the process of being edited, differing from the actual contents of the
+ * underlying resource. A buffer has an owner, which is an <code>IOpenable</code>.
+ * If a buffer does not have an underlying resource, saving the buffer has no effect.
+ * Buffers can be read-only.
+ * <p>
+ * Note that java model operations that manipulate an <code>IBuffer</code> (for example,
+ * <code>IType.createMethod(...)</code>) ensures that the same line delimiter
+ * (either <code>"\n"</code> or <code>"\r"</code> or <code>"\r\n"</code>) is
+ * used across the whole buffer. Thus these operations may change the line delimiter(s)
+ * included in the string to be append, or replaced.
+ * However implementers of this interface should be aware that other clients of <code>IBuffer</code>
+ * might not do such transformations beforehand.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ */
+public interface IBuffer {
+
+/**
+ * Implementors of {@link IBuffer} can additionally implement {@link IBuffer.ITextEditCapability}.
+ * This adds the capability to apply text edits to the buffer and will be used by
+ * {@link ICompilationUnit#applyTextEdit(TextEdit, IProgressMonitor)}.
+ *
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * @since 3.4
+ */
+public interface ITextEditCapability {
+	/**
+	 * Applies a text edit to this underlying buffer.
+	 *
+	 * @param edit the edit to apply
+	 * @param monitor the progress monitor to use or <code>null</code> if no progress should be reported
+	 * @return the undo edit
+	 * @throws JavaModelException if this edit can not be applied to the buffer. Reasons include:
+	 * <ul>
+	 * <li>The provided edit can not be applied as there is a problem with the text edit locations ({@link IJavaModelStatusConstants#BAD_TEXT_EDIT_LOCATION})}.</li>
+	 * </ul>
+	 */
+	public UndoEdit applyTextEdit(TextEdit edit, IProgressMonitor monitor) throws JavaModelException;
+}
+
+
+/**
+ * Adds the given listener for changes to this buffer.
+ * Has no effect if an identical listener is already registered or if the buffer
+ * is closed.
+ *
+ * @param listener the listener of buffer changes
+ */
+public void addBufferChangedListener(IBufferChangedListener listener);
+/**
+ * Appends the given character array to the contents of the buffer.
+ * This buffer will now have unsaved changes.
+ * Any client can append to the contents of the buffer, not just the owner of the buffer.
+ * Reports a buffer changed event.
+ * <p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param text the given character array to append to contents of the buffer
+ */
+public void append(char[] text);
+/**
+ * Appends the given string to the contents of the buffer.
+ * This buffer will now have unsaved changes.
+ * Any client can append to the contents of the buffer, not just the owner of the buffer.
+ * Reports a buffer changed event.
+ * <p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param text the <code>String</code> to append to the contents of the buffer
+ */
+public void append(String text);
+/**
+ * Closes the buffer. Any unsaved changes are lost. Reports a buffer changed event
+ * with a 0 offset and a 0 length. When this event is fired, the buffer should already
+ * be closed.
+ * <p>
+ * Further operations on the buffer are not allowed, except for close.  If an
+ * attempt is made to close an already closed buffer, the second attempt has no effect.
+ */
+public void close();
+/**
+ * Returns the character at the given position in this buffer.
+ * <p>
+ * The returned value is undefined if the buffer is closed.
+ *
+ * @param position a zero-based source offset in this buffer
+ * @return the character at the given position in this buffer
+ */
+public char getChar(int position);
+/**
+ * Returns the contents of this buffer as a character array, or <code>null</code> if
+ * the buffer has not been initialized.
+ * <p>
+ * Callers should make no assumption about whether the returned character array
+ * is or is not the genuine article or a copy. In other words, if the client
+ * wishes to change this array, they should make a copy. Likewise, if the
+ * client wishes to hang on to the array in its current state, they should
+ * make a copy.
+ * </p><p>
+ * The returned value is undefined if the buffer is closed.
+ *
+ * @return the characters contained in this buffer
+ */
+public char[] getCharacters();
+/**
+ * Returns the contents of this buffer as a <code>String</code>. Like all strings,
+ * the result is an immutable value object., It can also answer <code>null</code> if
+ * the buffer has not been initialized.
+ * <p>
+ * The returned value is undefined if the buffer is closed.
+ *
+ * @return the contents of this buffer as a <code>String</code>
+ */
+public String getContents();
+/**
+ * Returns number of characters stored in this buffer.
+ * <p>
+ * The returned value is undefined if the buffer is closed.
+ *
+ * @return the number of characters in this buffer
+ */
+public int getLength();
+/**
+ * Returns the Java openable element owning of this buffer.
+ *
+ * @return the openable element owning this buffer
+ */
+public IOpenable getOwner();
+/**
+ * Returns the given range of text in this buffer.
+ * <p>
+ * The returned value is undefined if the buffer is closed.
+ * </p>
+ *
+ * @param offset the zero-based starting offset
+ * @param length the number of characters to retrieve
+ * @return the given range of text in this buffer
+ * @exception IndexOutOfBoundsException when buffer is out of synch
+ */
+public String getText(int offset, int length) throws IndexOutOfBoundsException;
+/**
+ * Returns the underlying resource for which this buffer was opened,
+ * or <code>null</code> if this buffer was not opened on a resource.
+ *
+ * @return the underlying resource for this buffer, or <code>null</code>
+ *  if none.
+ */
+public IResource getUnderlyingResource();
+/**
+ * Returns whether this buffer has been modified since it
+ * was opened or since it was last saved.
+ * If a buffer does not have an underlying resource, this method always
+ * returns <code>true</code>.
+ * <p>
+ * NOTE: when a buffer does not have unsaved changes, the model may decide to close it
+ * to claim some memory back. If the associated element needs to be reopened later on, its
+ * buffer factory will be requested to create a new buffer.
+ * </p>
+ * @return a <code>boolean</code> indicating presence of unsaved changes (in
+ *   the absence of any underlying resource, it will always return <code>true</code>).
+ */
+public boolean hasUnsavedChanges();
+/**
+ * Returns whether this buffer has been closed.
+ *
+ * @return a <code>boolean</code> indicating whether this buffer is closed.
+ */
+public boolean isClosed();
+/**
+ * Returns whether this buffer is read-only.
+ *
+ * @return a <code>boolean</code> indicating whether this buffer is read-only
+ */
+public boolean isReadOnly();
+/**
+ * Removes the given listener from this buffer.
+ * Has no effect if an identical listener is not registered or if the buffer is closed.
+ *
+ * @param listener the listener
+ */
+public void removeBufferChangedListener(IBufferChangedListener listener);
+/**
+ * Replaces the given range of characters in this buffer with the given text.
+ * <code>position</code> and <code>position + length</code> must be in the range [0, getLength()].
+ * <code>length</code> must not be negative.
+ * <p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param position the zero-based starting position of the affected text range in this buffer
+ * @param length the length of the affected text range in this buffer
+ * @param text the replacing text as a character array
+ */
+public void replace(int position, int length, char[] text);
+/**
+ * Replaces the given range of characters in this buffer with the given text.
+ * <code>position</code> and <code>position + length</code> must be in the range [0, getLength()].
+ * <code>length</code> must not be negative.
+ * <p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param position the zero-based starting position of the affected text range in this buffer
+ * @param length the length of the affected text range in this buffer
+ * @param text the replacing text as a <code>String</code>
+ */
+public void replace(int position, int length, String text);
+/**
+ * Saves the contents of this buffer to its underlying resource. If
+ * successful, this buffer will have no unsaved changes.
+ * The buffer is left open. Saving a buffer with no unsaved
+ * changes has no effect - the underlying resource is not changed.
+ * If the buffer does not have an underlying resource or is read-only, this
+ * has no effect.
+ * <p>
+ * The <code>force</code> parameter controls how this method deals with
+ * cases where the workbench is not completely in sync with the local file system.
+ * If <code>false</code> is specified, this method will only attempt
+ * to overwrite a corresponding file in the local file system provided
+ * it is in sync with the workbench. This option ensures there is no
+ * unintended data loss; it is the recommended setting.
+ * However, if <code>true</code> is specified, an attempt will be made
+ * to write a corresponding file in the local file system,
+ * overwriting any existing one if need be.
+ * In either case, if this method succeeds, the resource will be marked
+ * as being local (even if it wasn't before).
+ * <p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param progress the progress monitor to notify
+ * @param force a <code> boolean </code> flag indicating how to deal with resource
+ *   inconsistencies.
+ *
+ * @exception JavaModelException if an error occurs writing the buffer
+ *	to the underlying resource
+ *
+ * @see org.eclipse.core.resources.IFile#setContents(java.io.InputStream, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public void save(IProgressMonitor progress, boolean force) throws JavaModelException;
+/**
+ * Sets the contents of this buffer to the given character array.
+ * This buffer will now have unsaved changes.
+ * Any client can set the contents of the buffer, not just the owner of the buffer.
+ * Reports a buffer changed event.
+ * <p>
+ * Equivalent to <code>replace(0,getLength(),contents)</code>.
+ * </p><p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param contents the new contents of this buffer as a character array
+ */
+public void setContents(char[] contents);
+/**
+ * Sets the contents of this buffer to the given <code>String</code>.
+ * This buffer will now have unsaved changes.
+ * Any client can set the contents of the buffer, not just the owner of the buffer.
+ * Reports a buffer changed event.
+ * <p>
+ * Equivalent to <code>replace(0,getLength(),contents)</code>.
+ * </p><p>
+ * Has no effect if this buffer is read-only or if the buffer is closed.
+ *
+ * @param contents the new contents of this buffer as a <code>String</code>
+ */
+public void setContents(String contents);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java
new file mode 100644
index 0000000..b146b19
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A listener, which gets notified when the contents of a specific buffer
+ * have changed, or when the buffer is closed.
+ * When a buffer is closed, the listener is notified <em>after</em> the buffer has been closed.
+ * A listener is not notified when a buffer is saved.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ */
+public interface IBufferChangedListener {
+
+	/**
+	 * Notifies that the given event has occurred.
+	 *
+	 * @param event the change event
+	 */
+	public void bufferChanged(BufferChangedEvent event);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java
new file mode 100644
index 0000000..eecad8a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A factory that creates <code>IBuffer</code>s for openables.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * @since 2.0
+ * @deprecated Use {@link WorkingCopyOwner} instead
+ */
+public interface IBufferFactory {
+
+	/**
+	 * Creates a buffer for the given owner.
+	 * The new buffer will be initialized with the contents of the owner
+	 * if and only if it was not already initialized by the factory (a buffer is uninitialized if
+	 * its content is <code>null</code>).
+	 *
+	 * @param owner the owner of the buffer
+	 * @return the newly created buffer
+	 * @see IBuffer
+	 */
+	IBuffer createBuffer(IOpenable owner);
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java
new file mode 100644
index 0000000..9c51ec3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Represents an entire binary type (single <code>.class</code> file).
+ * A class file has a single child of type <code>IType</code>.
+ * Class file elements need to be opened before they can be navigated.
+ * If a class file cannot be parsed, its structure remains unknown. Use
+ * <code>IJavaElement.isStructureKnown</code> to determine whether this is the
+ * case.
+ * <p>
+ * Note: <code>IClassFile</code> extends <code>ISourceReference</code>.
+ * Source can be obtained for a class file if and only if source has been attached to this
+ * class file. The source associated with a class file is the source code of
+ * the compilation unit it was (nominally) generated from.
+ * </p>
+ *
+ * @see IPackageFragmentRoot#attachSource(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, IProgressMonitor)
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+
+public interface IClassFile extends ITypeRoot {
+
+/**
+ * Changes this class file handle into a working copy. A new {@link IBuffer} is
+ * created using the given owner. Uses the primary owner if <code>null</code> is
+ * specified.
+ * <p>
+ * When switching to working copy mode, problems are reported to the given
+ * {@link IProblemRequestor}. Note that once in working copy mode, the given
+ * {@link IProblemRequestor} is ignored. Only the original {@link IProblemRequestor}
+ * is used to report subsequent problems.
+ * </p>
+ * <p>
+ * Once in working copy mode, changes to this working copy or its children are done in memory.
+ * Only the new buffer is affected.
+ * </p>
+ * <p>
+ * Using {@link ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)} on the working copy
+ * will throw a <code>JavaModelException</code> as a class file is implicetly read-only.
+ * </p>
+ * <p>
+ * If this class file was already in working copy mode, an internal counter is incremented and no
+ * other action is taken on this working copy. To bring this working copy back into the original mode
+ * (where it reflects the underlying resource), {@link ICompilationUnit#discardWorkingCopy} must be call as many
+ * times as {@link #becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)}.
+ * </p>
+ * <p>
+ * The primary compilation unit of a class file's working copy does not exist if the class file is not
+ * in working copy mode (<code>classFileWorkingCopy.getPrimary().exists() == false</code>).
+ * </p>
+ * <p>
+ * The resource of a class file's working copy is <code>null</code> if the class file is in an external jar file.
+ * </p>
+ *
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+ * 	that the client is not interested in problems.
+ * @param owner the given {@link WorkingCopyOwner}, or <code>null</code> for the primary owner
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or <code>null</code> if no progress should be reported
+ * @return a working copy for this class file
+ * @throws JavaModelException if this compilation unit could not become a working copy.
+ * @see ICompilationUnit#discardWorkingCopy()
+ * @since 3.2
+ * @deprecated Use {@link ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} instead.
+ * 	Note that if this deprecated method is used, problems will be reported to the given problem requestor
+ * 	as well as the problem requestor returned by the working copy owner (if not null).
+ */
+ICompilationUnit becomeWorkingCopy(IProblemRequestor problemRequestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Returns the bytes contained in this class file.
+ *
+ * @return the bytes contained in this class file
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @since 3.3
+ */
+byte[] getBytes() throws JavaModelException;
+/**
+ * Returns the type contained in this class file.
+ * This is a handle-only method. The type may or may not exist.
+ *
+ * @return the type contained in this class file
+ */
+IType getType();
+/**
+ * Returns a working copy on the source associated with this class file using the given
+ * factory to create the buffer, or <code>null</code> if there is no source associated
+ * with the class file.
+ * <p>
+ * The buffer will be automatically initialized with the source of the class file
+ * upon creation.
+ * <p>
+ * The only valid operations on this working copy are <code>getBuffer()</code> or <code>getOriginalElement</code>.
+ *
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ *                 or <code>null</code> if no progress should be reported
+ * @param factory the factory that creates a buffer that is used to get the content of the working copy
+ *                 or <code>null</code> if the internal factory should be used
+ * @return a  a working copy on the source associated with this class file
+ * @exception JavaModelException if the source of this class file can
+ *   not be determined. Reasons include:
+ * <ul>
+ * <li> This class file does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @since 2.0
+ * @deprecated Use {@link ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} instead
+ */
+IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory) throws JavaModelException;
+/**
+ * Returns whether this type represents a class. This is not guaranteed to be
+ * instantaneous, as it may require parsing the underlying file.
+ *
+ * @return <code>true</code> if the class file represents a class.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+boolean isClass() throws JavaModelException;
+/**
+ * Returns whether this type represents an interface. This is not guaranteed to
+ * be instantaneous, as it may require parsing the underlying file.
+ *
+ * @return <code>true</code> if the class file represents an interface.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+boolean isInterface() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java
new file mode 100644
index 0000000..dc2c826
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A classpath attribute defines a name/value pair that can be persisted with a classpath entry. Such an attribute
+ * can be created using the factory method {@link JavaCore#newClasspathAttribute(String, String) newClasspathAttribute(String name, String value)}.
+ *
+ * @see JavaCore#newContainerEntry(
+ *			org.eclipse.core.runtime.IPath containerPath,
+ *			IAccessRule[] accessRules,
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @see JavaCore#newLibraryEntry(
+ *			org.eclipse.core.runtime.IPath path,
+ *			org.eclipse.core.runtime.IPath sourceAttachmentPath,
+ *			org.eclipse.core.runtime.IPath sourceAttachmentRootPath,
+ *			IAccessRule[] accessRules,
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @see JavaCore#newProjectEntry(
+ *			org.eclipse.core.runtime.IPath path,
+ *			IAccessRule[] accessRules,
+ *			boolean combineAccessRestrictions,
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @see JavaCore#newSourceEntry(
+ * 			org.eclipse.core.runtime.IPath path,
+ * 			org.eclipse.core.runtime.IPath[] inclusionPatterns,
+ * 			org.eclipse.core.runtime.IPath[] exclusionPatterns,
+ * 			org.eclipse.core.runtime.IPath specificOutputLocation,
+ * 			IClasspathAttribute[] extraAttributes)
+ * @see JavaCore#newVariableEntry(
+ *			org.eclipse.core.runtime.IPath variablePath,
+ *			org.eclipse.core.runtime.IPath variableSourceAttachmentPath,
+ *			org.eclipse.core.runtime.IPath variableSourceAttachmentRootPath,
+ *			IAccessRule[] accessRules,
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @since 3.1
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IClasspathAttribute {
+
+	/**
+	 * Constant for the name of the javadoc location attribute.
+	 * 
+	 * <p>The value for this attribute has to be the string representation of a URL.</p>
+	 *
+	 * @since 3.1
+	 */
+	String JAVADOC_LOCATION_ATTRIBUTE_NAME = "javadoc_location"; //$NON-NLS-1$
+	
+	/**
+	 * Constant for the name of the index location attribute.
+	 * 
+	 * <p>The value for this attribute has to be the string representation of a URL.
+	 * It should point to an existing index file in a folder or a jar. The URL can also be of platform protocol.</p>
+	 * 
+	 * @since 3.8
+	 */
+	String INDEX_LOCATION_ATTRIBUTE_NAME = "index_location"; //$NON-NLS-1$
+
+	/**
+	 * Constant for the name of the encoding to be used for source attachments.
+	 * 
+	 * <p>The value of this attribute has to be a string representation of a valid encoding. The encoding
+	 * for a source attachment is determined in the following order: </p>
+	 *
+	 * <ul>
+	 * <li>	Encoding explicitly set on the source file (java or zip), i.e. <code>org.eclipse.core.resources.IFile#getCharset(false)</code> </li>
+	 * <li>	Encoding set on the corresponding classpath entry </li>
+	 * <li> If the source attachment is a folder, then the encoding determined by the file content if detectable </li>
+	 * <li> If the source attachment is in the workspace, then the encoding of the enclosing resources</li>
+	 * </ul>
+	 *
+	 * @see org.eclipse.core.resources.IFile#getCharset()
+	 * @since 3.8
+	 */
+	String SOURCE_ATTACHMENT_ENCODING = "source_encoding"; //$NON-NLS-1$
+
+	/**
+	 * Constant for the name of the ignore optional compile problems attribute.
+	 * This attribute is valid only for classpath entries describing source folders.
+	 * The possible values for this attribute are <code>"true"</code> or
+	 * <code>"false"</code>. When not present, <code>"false"</code> is assumed.
+	 * If the value of this attribute is <code>"true"</code>, all optional problems
+	 * from the source folder described by this classpath entry will not be reported
+	 * by the compiler.
+	 *
+	 * @since 3.8
+	 */
+	String IGNORE_OPTIONAL_PROBLEMS = "ignore_optional_problems"; //$NON-NLS-1$
+
+	/**
+	 * Constant for the name of the optional attribute. The possible values
+	 * for this attribute are <code>"true"</code> or <code>"false"</code>.
+	 * When not present, <code>"false"</code> is assumed.
+	 * If the value of this attribute is <code>"true"</code>, the classpath entry
+	 * is optional. If the underlying resource or jar file doesn't exist, no error
+	 * is reported and the classpath entry is ignored.
+	 *
+	 * @since 3.2
+	 */
+	String OPTIONAL = "optional"; //$NON-NLS-1$
+
+	/**
+	 * Returns the name of this classpath attribute.
+	 *
+	 * @return the name of this classpath attribute.
+	 * @since 3.1
+	 */
+	String getName();
+
+	/**
+	 * Returns the value of this classpath attribute.
+	 *
+	 * @return the value of this classpath attribute.
+	 * @since 3.1
+	 */
+	String getValue();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java
new file mode 100644
index 0000000..5b862f6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Interface of a classpath container.
+ * A classpath container provides a way to indirectly reference a set of classpath entries through
+ * a classpath entry of kind <code>CPE_CONTAINER</code>. Typically, a classpath container can
+ * be used to describe a complex library composed of multiple JARs or projects, considering also
+ * that containers can map to different set of entries on each project, in other words, several
+ * projects can reference the same generic container path, but have each of them actually bound
+ * to a different container object.
+ * <p>
+ * The set of entries associated with a classpath container may contain any of the following:
+ * <ul>
+ * <li> library entries (<code>CPE_LIBRARY</code>) </li>
+ * <li> project entries (<code>CPE_PROJECT</code>) </li>
+ * </ul>
+ * In particular, a classpath container can neither reference further classpath containers or classpath variables.
+ * <p> 
+ * A library entry can reference other libraries through the Class-Path section of the JAR's MANIFEST.MF file. If the
+ * container wants such referenced entries to be part of the classpath, the container must explicitly add them to the
+ * array returned from {@link #getClasspathEntries()}.
+ * <p>
+ * Classpath container values are persisted locally to the workspace, but are not preserved from a
+ * session to another. It is thus highly recommended to register a <code>ClasspathContainerInitializer</code>
+ * for each referenced container (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+ * <p>
+ * @see IClasspathEntry
+ * @since 2.0
+ */
+
+public interface IClasspathContainer {
+
+	/**
+	 * Kind for a container mapping to an application library
+	 */
+	int K_APPLICATION = 1;
+
+	/**
+	 * Kind for a container mapping to a system library
+	 */
+	int K_SYSTEM = 2;
+
+	/**
+	 * Kind for a container mapping to a default system library, implicitly contributed by the runtime
+	 */
+	int K_DEFAULT_SYSTEM = 3;
+
+	/**
+	 * Answers the set of classpath entries this container is mapping to.
+	 * <p>
+	 * The set of entries associated with a classpath container may contain any of the following:
+	 * <ul>
+	 * <li> library entries (<code>CPE_LIBRARY</code>) </li>
+	 * <li> project entries (<code>CPE_PROJECT</code>) </li>
+	 * </ul>
+	 * A classpath container can neither reference further classpath containers
+	 * or classpath variables.
+	 * <p>
+	 * A library entry can reference other libraries through the Class-Path section of the JAR's MANIFEST.MF file. If
+	 * the container wants such referenced entries to be part of the classpath, the container must explicitly add them
+	 * to the result.
+	 * <p>
+	 * This method is called by the Java model when it needs to resolve this
+	 * classpath container entry into a list of library and project entries.
+	 * The method is typically called exactly once for a given Java project,
+	 * and the resulting list of entries cached internally by the Java model.
+	 * This method must not be called by other clients.
+	 * <p>
+	 * There are a wide variety of conditions under which this method may be
+	 * invoked. To ensure that the implementation does not interfere with
+	 * correct functioning of the Java model, the implementation should use
+	 * only the following Java model APIs:
+	 * <ul>
+	 * <li>{@link JavaCore#newLibraryEntry(IPath, IPath, IPath, boolean)} and variants</li>
+	 * <li>{@link JavaCore#newProjectEntry(IPath, boolean)} and variants</li>
+	 * <li>{@link JavaCore#create(org.eclipse.core.resources.IWorkspaceRoot)}</li>
+	 * <li>{@link JavaCore#create(org.eclipse.core.resources.IProject)}</li>
+	 * <li>{@link JavaCore#getReferencedClasspathEntries(IClasspathEntry, IJavaProject)} with <code>null</code> as project</li>
+	 * <li>{@link IJavaModel#getJavaProjects()}</li>
+	 * <li>{@link IJavaProject#getRawClasspath()}</li>
+	 * <li>{@link IJavaProject#readRawClasspath()}</li>
+	 * <li>{@link IJavaProject#getOutputLocation()}</li>
+	 * <li>{@link IJavaProject#readOutputLocation()}</li>
+	 * <li>Java element operations marked as "handle-only"</li>
+	 * </ul>
+	 * The effects of using other Java model APIs are unspecified.
+	 * </p>
+	 *
+	 * @return IClasspathEntry[] - the classpath entries this container represents
+	 * @see IClasspathEntry
+	 */
+    IClasspathEntry[] getClasspathEntries();
+
+	/**
+	 * Answers a readable description of this container
+	 *
+	 * @return String - a string description of the container
+	 */
+    String getDescription();
+
+	/**
+	 * Answers the kind of this container. Can be either:
+	 * <ul>
+	 * <li><code>K_APPLICATION</code> if this container maps to an application library</li>
+	 * <li><code>K_SYSTEM</code> if this container maps to a system library</li>
+	 * <li><code>K_DEFAULT_SYSTEM</code> if this container maps to a default system library (library
+	 * 	implicitly contributed by the runtime).</li>
+	 * </ul>
+	 * Typically, system containers should be placed first on a build path.
+	 * @return the kind of this container
+	 */
+    int getKind();
+
+	/**
+	 * Answers the container path identifying this container.
+	 * A container path is formed by a first ID segment followed with extra segments, which
+	 * can be used as additional hints for resolving to this container.
+	 * <p>
+	 * The container ID is also used to identify a<code>ClasspathContainerInitializer</code>
+	 * registered on the extension point "org.eclipse.jdt.core.classpathContainerInitializer", which can
+	 * be invoked if needing to resolve the container before it is explicitly set.
+	 * <p>
+	 * @return IPath - the container path that is associated with this container
+	 */
+    IPath getPath();
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java
new file mode 100644
index 0000000..8c882fd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java
@@ -0,0 +1,475 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * An entry on a Java project classpath identifying one or more package fragment
+ * roots. A classpath entry has a content kind (either source,
+ * {@link IPackageFragmentRoot#K_SOURCE}, or binary, {@link IPackageFragmentRoot#K_BINARY}), which is inherited
+ * by each package fragment root and package fragment associated with the entry.
+ * <p>
+ * A classpath entry can refer to any of the following:<ul>
+ *
+ *	<li>Source code in the current project. In this case, the entry identifies a
+ *		root folder in the current project containing package fragments and
+ *		source files with one of the {@link JavaCore#getJavaLikeExtensions()
+ *		Java-like extensions}. The root folder itself represents a default
+ *		package, subfolders represent package fragments, and files with a
+ *     Java-like extension (e.g. <code>.java</code> files)
+ *		represent compilation units. All compilation units will be compiled when
+ * 		the project is built. The classpath entry must specify the
+ *		absolute path to the root folder. Entries of this kind are
+ *		associated with the {@link #CPE_SOURCE} constant.
+ *      Source classpath entries can carry inclusion and exclusion patterns for
+ *      selecting which source files appear as compilation
+ *      units and get compiled when the project is built.
+ *  </li>
+ *
+ *	<li>A binary library in the current project, in another project, or in the external
+ *		file system. In this case the entry identifies a JAR (or root folder) containing
+ *		package fragments and <code>.class</code> files.  The classpath entry
+ *		must specify the absolute path to the JAR (or root folder), and in case it refers
+ *		to an external JAR, then there is no associated resource in the workbench. Entries
+ *		of this kind are associated with the {@link #CPE_LIBRARY} constant.</li>
+ *
+ *	<li>A required project. In this case the entry identifies another project in
+ *		the workspace. The required project is used as a binary library when compiling
+ *		(that is, the builder looks in the output location of the required project
+ *		for required <code>.class</code> files when building). When performing other
+ *		"development" operations - such as code assist, code resolve, type hierarchy
+ *		creation, etc. - the source code of the project is referred to. Thus, development
+ *		is performed against a required project's source code, and compilation is
+ *		performed against a required project's last built state.  The
+ *		classpath entry must specify the absolute path to the
+ *		project. Entries of this kind are  associated with the {@link #CPE_PROJECT}
+ *		constant.
+ * 		Note: referencing a required project with a classpath entry refers to the source
+ *     code or associated <code>.class</code> files located in its output location.
+ *     It will also automatically include any other libraries or projects that the required project's classpath
+ *     refers to, iff the corresponding classpath entries are tagged as being exported
+ *     ({@link IClasspathEntry#isExported}).
+ *    Unless exporting some classpath entries, classpaths are not chained by default -
+ *    each project must specify its own classpath in its entirety.</li>
+ *
+ *  <li> A path beginning in a classpath variable defined globally to the workspace.
+ *		Entries of this kind are  associated with the {@link #CPE_VARIABLE} constant.
+ *      Classpath variables are created using {@link JavaCore#setClasspathVariable(String, IPath, org.eclipse.core.runtime.IProgressMonitor)},
+ * 		and gets resolved, to either a project or library entry, using
+ *      {@link JavaCore#getResolvedClasspathEntry(IClasspathEntry)}.
+ *		It is also possible to register an automatic initializer ({@link ClasspathVariableInitializer}),
+ * 	which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+ * 	After resolution, a classpath variable entry may either correspond to a project or a library entry. </li>
+ *
+ *  <li> A named classpath container identified by its container path.
+ *     A classpath container provides a way to indirectly reference a set of classpath entries through
+ *     a classpath entry of kind {@link #CPE_CONTAINER}. Typically, a classpath container can
+ *     be used to describe a complex library composed of multiple JARs, projects or classpath variables,
+ *     considering also that containers can be mapped differently on each project. Several projects can
+ *     reference the same generic container path, but have each of them actually bound to a different
+ *     container object.
+ *     The container path is a formed by a first ID segment followed with extra segments,
+ *     which can be used as additional hints for resolving this container reference. If no container was ever
+ *     recorded for this container path onto this project (using {@link JavaCore#setClasspathContainer},
+ * 	then a {@link ClasspathContainerInitializer} will be activated if any was registered for this
+ * 	container ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+ * 	A classpath container entry can be resolved explicitly using {@link JavaCore#getClasspathContainer}
+ * 	and the resulting container entries can contain any non-container entry. In particular, it may contain variable
+ *     entries, which in turn needs to be resolved before being directly used.
+ * 	<br> Also note that the container resolution APIs include an IJavaProject argument, so as to allow the same
+ * 	container path to be interpreted in different ways for different projects. </li>
+ * </ul>
+ * </p>
+ * The result of {@link IJavaProject#getResolvedClasspath} will have all entries of type
+ * {@link #CPE_VARIABLE} and {@link #CPE_CONTAINER} resolved to a set of
+ * {@link #CPE_SOURCE}, {@link #CPE_LIBRARY} or {@link #CPE_PROJECT}
+ * classpath entries.
+ * <p>
+ * Any classpath entry other than a source folder (kind {@link #CPE_SOURCE}) can
+ * be marked as being exported. Exported entries are automatically contributed to
+ * dependent projects, along with the project's default output folder, which is
+ * implicitly exported, and any auxiliary output folders specified on source
+ * classpath entries. The project's output folder(s) are always listed first,
+ * followed by the any exported entries.
+ * <p>
+ * Classpath entries can be created via methods on {@link JavaCore}.
+ * </p>
+ *
+ * @see JavaCore#newLibraryEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath)
+ * @see JavaCore#newProjectEntry(org.eclipse.core.runtime.IPath)
+ * @see JavaCore#newSourceEntry(org.eclipse.core.runtime.IPath)
+ * @see JavaCore#newVariableEntry(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath)
+ * @see JavaCore#newContainerEntry(org.eclipse.core.runtime.IPath)
+ * @see ClasspathVariableInitializer
+ * @see ClasspathContainerInitializer
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IClasspathEntry {
+
+	/**
+	 * Entry kind constant describing a classpath entry identifying a
+	 * library. A library is a folder or JAR containing package
+	 * fragments consisting of pre-compiled binaries.
+	 */
+	int CPE_LIBRARY = 1;
+
+	/**
+	 * Entry kind constant describing a classpath entry identifying a
+	 * required project.
+	 */
+	int CPE_PROJECT = 2;
+
+	/**
+	 * Entry kind constant describing a classpath entry identifying a
+	 * folder containing package fragments with source code
+	 * to be compiled.
+	 */
+	int CPE_SOURCE = 3;
+
+	/**
+	 * Entry kind constant describing a classpath entry defined using
+	 * a path that begins with a classpath variable reference.
+	 */
+	int CPE_VARIABLE = 4;
+
+	/**
+	 * Entry kind constant describing a classpath entry representing
+	 * a name classpath container.
+	 *
+	 * @since 2.0
+	 */
+	int CPE_CONTAINER = 5;
+
+	/**
+	 * Returns whether the access rules of the project's exported entries should be combined with this entry's access rules.
+	 * Returns true for container entries.
+	 * Returns false otherwise.
+	 *
+	 * @return whether the access rules of the project's exported entries should be combined with this entry's access rules
+	 * @since 3.1
+	 */
+	boolean combineAccessRules();
+
+	/**
+	 * Returns the possibly empty list of access rules for this entry.
+	 *
+	 * @return the possibly empty list of access rules for this entry
+	 * @since 3.1
+	 */
+	IAccessRule[] getAccessRules();
+	/**
+	 * Returns the kind of files found in the package fragments identified by this
+	 * classpath entry.
+	 *
+	 * @return {@link IPackageFragmentRoot#K_SOURCE} for files containing
+	 *   source code, and {@link IPackageFragmentRoot#K_BINARY} for binary
+	 *   class files.
+	 *   There is no specified value for an entry denoting a variable ({@link #CPE_VARIABLE})
+	 *   or a classpath container ({@link #CPE_CONTAINER}).
+	 */
+	int getContentKind();
+
+	/**
+	 * Returns the kind of this classpath entry.
+	 *
+	 * @return one of:
+	 * <ul>
+	 * <li>{@link #CPE_SOURCE} - this entry describes a source root in
+	 		its project
+	 * <li>{@link #CPE_LIBRARY} - this entry describes a folder or JAR
+	 		containing binaries
+	 * <li>{@link #CPE_PROJECT} - this entry describes another project
+	 *
+	 * <li>{@link #CPE_VARIABLE} - this entry describes a project or library
+	 *  	indirectly via a classpath variable in the first segment of the path
+	 * *
+	 * <li>{@link #CPE_CONTAINER} - this entry describes set of entries
+	 *  	referenced indirectly via a classpath container
+	 * </ul>
+	 */
+	int getEntryKind();
+
+	/**
+	 * Returns the set of patterns used to exclude resources or classes associated with
+	 * this classpath entry.
+	 * <p>
+	 * For source classpath entries,
+	 * exclusion patterns allow specified portions of the resource tree rooted
+	 * at this source entry's path to be filtered out. If no exclusion patterns
+	 * are specified, this source entry includes all relevent files. Each path
+	 * specified must be a relative path, and will be interpreted relative
+	 * to this source entry's path. File patterns are case-sensitive. A file
+	 * matched by one or more of these patterns is excluded from the
+	 * corresponding package fragment root.
+	 * Exclusion patterns have higher precedence than inclusion patterns;
+	 * in other words, exclusion patterns can remove files for the ones that
+	 * are to be included, not the other way around.
+	 * </p>
+	 * <p>
+	 * Note that there is no need to supply a pattern to exclude ".class" files
+	 * because a source entry filters these out automatically.
+	 * </p>
+	 * <p>
+	 * The pattern mechanism is similar to Ant's. Each pattern is represented as
+	 * a relative path. The path segments can be regular file or folder names or simple patterns
+	 * involving standard wildcard characters.
+	 * </p>
+	 * <p>
+	 * '*' matches 0 or more characters within a segment. So
+	 * <code>*.java</code> matches <code>.java</code>, <code>a.java</code>
+	 * and <code>Foo.java</code>, but not <code>Foo.properties</code>
+	 * (does not end with <code>.java</code>).
+	 * </p>
+	 * <p>
+	 * '?' matches 1 character within a segment. So <code>?.java</code>
+	 * matches <code>a.java</code>, <code>A.java</code>,
+	 * but not <code>.java</code> or <code>xyz.java</code> (neither have
+	 * just one character before <code>.java</code>).
+	 * </p>
+	 * <p>
+	 * Combinations of *'s and ?'s are allowed.
+	 * </p>
+	 * <p>
+	 * The special pattern '**' matches zero or more segments. In a source entry,
+	 * a path like <code>tests/</code> that ends in a trailing separator is interpreted
+	 * as <code>tests/&#42;&#42;</code>, and would match everything under
+	 * the folder named <code>tests</code>.
+	 * </p>
+	 * <p>
+	 * Example patterns in source entries (assuming that "java" is the only {@link JavaCore#getJavaLikeExtensions() Java-like extension}):
+	 * <ul>
+	 * <li>
+	 * <code>tests/&#42;&#42;</code> (or simply <code>tests/</code>)
+	 * matches all files under a root folder
+	 * named <code>tests</code>. This includes <code>tests/Foo.java</code>
+	 * and <code>tests/com/example/Foo.java</code>, but not
+	 * <code>com/example/tests/Foo.java</code> (not under a root folder named
+	 * <code>tests</code>).
+	 * </li>
+	 * <li>
+	 * <code>tests/&#42;</code> matches all files directly below a root
+	 * folder named <code>tests</code>. This includes <code>tests/Foo.java</code>
+	 * and <code>tests/FooHelp.java</code>
+	 * but not <code>tests/com/example/Foo.java</code> (not directly under
+	 * a folder named <code>tests</code>) or
+	 * <code>com/Foo.java</code> (not under a folder named <code>tests</code>).
+	 * </li>
+	 * <li>
+	 * <code>&#42;&#42;/tests/&#42;&#42;</code> matches all files under any
+	 * folder named <code>tests</code>. This includes <code>tests/Foo.java</code>,
+	 * <code>com/examples/tests/Foo.java</code>, and
+	 * <code>com/examples/tests/unit/Foo.java</code>, but not
+	 * <code>com/example/Foo.java</code> (not under a folder named
+	 * <code>tests</code>).
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @return the possibly empty list of resource exclusion patterns
+	 *   associated with this classpath entry, or <code>null</code> if this kind
+	 *   of classpath entry does not support exclusion patterns
+	 * @since 2.1
+	 */
+	IPath[] getExclusionPatterns();
+
+	/**
+	 * Returns the extra classpath attributes for this classpath entry. Returns an empty array if this entry
+	 * has no extra attributes.
+	 *
+	 * @return the possibly empty list of extra classpath attributes for this classpath entry
+	 * @since 3.1
+	 */
+	IClasspathAttribute[] getExtraAttributes();
+
+	/**
+	 * Returns the set of patterns used to explicitly define resources or classes
+	 * to be included with this classpath entry.
+	 * <p>
+	 * For source classpath entries,
+	 * when no inclusion patterns are specified, the source entry includes all
+	 * relevent files in the resource tree rooted at this source entry's path.
+	 * Specifying one or more inclusion patterns means that only the specified
+	 * portions of the resource tree are to be included. Each path specified
+	 * must be a relative path, and will be interpreted relative to this source
+	 * entry's path. File patterns are case-sensitive. A file matched by one or
+	 * more of these patterns is included in the corresponding package fragment
+	 * root unless it is excluded by one or more of this entrie's exclusion
+	 * patterns. Exclusion patterns have higher precedence than inclusion
+	 * patterns; in other words, exclusion patterns can remove files for the
+	 * ones that are to be included, not the other way around.
+	 * </p>
+	 * <p>
+	 * See {@link #getExclusionPatterns()} for a discussion of the syntax and
+	 * semantics of path patterns. The absence of any inclusion patterns is
+	 * semantically equivalent to the explicit inclusion pattern
+	 * <code>&#42;&#42;</code>.
+	 * </p>
+	 * <p>
+	 * Example patterns in source entries:
+	 * <ul>
+	 * <li>
+	 * The inclusion pattern <code>src/&#42;&#42;</code> by itself includes all
+	 * files under a root folder named <code>src</code>.
+	 * </li>
+	 * <li>
+	 * The inclusion patterns <code>src/&#42;&#42;</code> and
+	 * <code>tests/&#42;&#42;</code> includes all files under the root folders
+	 * named <code>src</code> and <code>tests</code>.
+	 * </li>
+	 * <li>
+	 * The inclusion pattern <code>src/&#42;&#42;</code> together with the
+	 * exclusion pattern <code>src/&#42;&#42;/Foo.java</code> includes all
+	 * files under a root folder named <code>src</code> except for ones
+	 * named <code>Foo.java</code>.
+	 * </li>
+	 * </ul>
+	 * </p>
+	 *
+	 * @return the possibly empty list of resource inclusion patterns
+	 *   associated with this classpath entry, or <code>null</code> if this kind
+	 *   of classpath entry does not support inclusion patterns
+	 * @since 3.0
+	 */
+	IPath[] getInclusionPatterns();
+
+	/**
+	 * Returns the full path to the specific location where the builder writes
+	 * <code>.class</code> files generated for this source entry
+	 * (entry kind {@link #CPE_SOURCE}).
+	 * <p>
+	 * Source entries can optionally be associated with a specific output location.
+	 * If none is provided, the source entry will be implicitly associated with its project
+	 * default output location (see {@link IJavaProject#getOutputLocation}).
+	 * </p><p>
+	 * NOTE: A specific output location cannot coincidate with another source/library entry.
+	 * </p>
+	 *
+	 * @return the full path to the specific location where the builder writes
+	 * <code>.class</code> files for this source entry, or <code>null</code>
+	 * if using default output folder
+	 * @since 2.1
+	 */
+	IPath getOutputLocation();
+
+	/**
+	 * Returns the path of this classpath entry.
+	 *
+	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
+	 *	<li>Source code in the current project ({@link #CPE_SOURCE}) -
+	 *      The path associated with this entry is the absolute path to the root folder. </li>
+	 *	<li>A binary library in the current project ({@link #CPE_LIBRARY}) - the path
+	 *		associated with this entry is the absolute path to the JAR (or root folder), and
+	 *		in case it refers to an external library, then there is no associated resource in
+	 *		the workbench.
+	 *	<li>A required project ({@link #CPE_PROJECT}) - the path of the entry denotes the
+	 *		path to the corresponding project resource.</li>
+	 *  <li>A variable entry ({@link #CPE_VARIABLE}) - the first segment of the path
+	 *      is the name of a classpath variable. If this classpath variable
+	 *		is bound to the path <i>P</i>, the path of the corresponding classpath entry
+	 *		is computed by appending to <i>P</i> the segments of the returned
+	 *		path without the variable.</li>
+	 *  <li> A container entry ({@link #CPE_CONTAINER}) - the path of the entry
+	 * 	is the name of the classpath container, which can be bound indirectly to a set of classpath
+	 * 	entries after resolution. The containerPath is a formed by a first ID segment followed with
+	 *     extra segments that can be used as additional hints for resolving this container
+	 * 	reference (also see {@link IClasspathContainer}).
+	 * </li>
+	 * </ul>
+	 *
+	 * @return the path of this classpath entry
+	 */
+	IPath getPath();
+
+	/**
+	 * Returns the path to the source archive or folder associated with this
+	 * classpath entry, or <code>null</code> if this classpath entry has no
+	 * source attachment.
+	 * <p>
+	 * Only library and variable classpath entries may have source attachments.
+	 * For library classpath entries, the result path (if present) locates a source
+	 * archive or folder. This archive or folder can be located in a project of the
+	 * workspace or outside the workspace. For variable classpath entries, the
+	 * result path (if present) has an analogous form and meaning as the
+	 * variable path, namely the first segment is the name of a classpath variable.
+	 * </p>
+	 *
+	 * @return the path to the source archive or folder, or <code>null</code> if none
+	 */
+	IPath getSourceAttachmentPath();
+
+	/**
+	 * Returns the path within the source archive or folder where package fragments
+	 * are located. An empty path indicates that packages are located at
+	 * the root of the source archive or folder. Returns a non-<code>null</code> value
+	 * if and only if {@link #getSourceAttachmentPath} returns
+	 * a non-<code>null</code> value.
+	 *
+	 * @return the path within the source archive or folder, or <code>null</code> if
+	 *    not applicable
+	 */
+	IPath getSourceAttachmentRootPath();
+
+	
+	/**
+	 * 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>.  
+	 * <p>
+	 * 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.
+	 * </p>
+	 * 
+	 * @return the classpath entry that is referencing this entry or <code>null</code> if 
+	 * 		not applicable.
+	 * @since 3.6
+	 */
+	IClasspathEntry getReferencingEntry();
+
+	/**
+	 * Returns whether this entry is exported to dependent projects.
+	 * Always returns <code>false</code> for source entries (kind
+	 * {@link #CPE_SOURCE}), which cannot be exported.
+	 *
+	 * @return <code>true</code> if exported, and <code>false</code> otherwise
+	 * @since 2.0
+	 */
+	boolean isExported();
+
+	/**
+	 * This is a helper method, which returns the resolved classpath entry denoted
+	 * by an entry (if it is a variable entry). It is obtained by resolving the variable
+	 * reference in the first segment. Returns <code>null</code> if unable to resolve using
+	 * the following algorithm:
+	 * <ul>
+	 * <li> if variable segment cannot be resolved, returns <code>null</code></li>
+	 * <li> finds a project, JAR or binary folder in the workspace at the resolved path location</li>
+	 * <li> if none finds an external JAR file or folder outside the workspace at the resolved path location </li>
+	 * <li> if none returns <code>null</code></li>
+	 * </ul>
+	 * <p>
+	 * Variable source attachment is also resolved and recorded in the resulting classpath entry.
+	 * <p>
+	 * @return the resolved library or project classpath entry, or <code>null</code>
+	 *   if the given path could not be resolved to a classpath entry
+	 *	<p>
+	 * Note that this deprecated API doesn't handle CPE_CONTAINER entries.
+	 *
+	 * @deprecated Use {@link JavaCore#getResolvedClasspathEntry(IClasspathEntry)} instead
+	 */
+	IClasspathEntry getResolvedEntry();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java
new file mode 100644
index 0000000..77f14a0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that support source code assist and code
+ * resolve.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICodeAssist {
+
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 *
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @deprecated Use {@link #codeComplete(int, ICompletionRequestor)} instead.
+	 */
+	void codeComplete(int offset, ICodeCompletionRequestor requestor)
+		throws JavaModelException;
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 2.0
+	 * @deprecated Use {@link #codeComplete(int, CompletionRequestor)} instead.
+ 	 */
+	void codeComplete(int offset, ICompletionRequestor requestor)
+		throws JavaModelException;
+
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * <p>
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 3.0
+ 	 */
+	void codeComplete(int offset, CompletionRequestor requestor)
+		throws JavaModelException;
+	
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * <p>
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         fEndTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 3.5
+ 	 */
+	void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 3.0
+	 * @deprecated Use {@link #codeComplete(int, CompletionRequestor, WorkingCopyOwner)} instead.
+	 */
+	void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner)
+		throws JavaModelException;
+
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 3.0
+	 */
+	void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner)
+		throws JavaModelException;
+	
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The <code>offset</code>
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         fEndTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The position specified is < -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
+	 * @since 3.5
+	 */
+	void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Returns the Java elements corresponding to the given selected text in this compilation unit.
+	 * The <code>offset</code> is the 0-based index of the first selected character.
+	 * The <code>length</code> is the number of selected characters.
+	 * <p>
+	 * Note that if the <code>length</code> is 0 and the <code>offset</code> is inside an identifier
+	 * or the index just after an identifier then this identifier is considered as the selection.
+	 * </p>
+	 *
+	 * @param offset the given offset position
+	 * @param length the number of selected characters
+	 * @return the Java elements corresponding to the given selected text
+	 *
+	 * @exception JavaModelException if code resolve could not be performed. Reasons include:
+	 * <ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The range specified is not within this element's
+	 *      source range (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 *
+	 */
+	IJavaElement[] codeSelect(int offset, int length) throws JavaModelException;
+	/**
+	 * Returns the Java elements corresponding to the given selected text in this compilation unit.
+	 * The <code>offset</code> is the 0-based index of the first selected character.
+	 * The <code>length</code> is the number of selected characters.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if the <code>length</code> is 0 and the <code>offset</code> is inside an identifier
+	 * or the index just after an identifier then this identifier is considered as the selection.
+	 * </p>
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param offset the given offset position
+	 * @param length the number of selected characters
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @return the Java elements corresponding to the given selected text
+	 *
+	 * @exception JavaModelException if code resolve could not be performed. Reasons include:
+	 * <ul>
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The range specified is not within this element's
+	 *      source range (INDEX_OUT_OF_BOUNDS)
+	 * </ul>
+	 * @since 3.0
+	 */
+	IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner owner) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java
new file mode 100644
index 0000000..f8c254a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * A completion requestor accepts results as they are computed and is aware
+ * of source positions to complete the various different results.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @see ICodeAssist
+ * @deprecated Use {@link CompletionRequestor} instead.
+ */
+public interface ICodeCompletionRequestor {
+/**
+ * Code assist notification of a class completion.
+ *
+ * @param packageName Declaring package name of the class.
+ * @param className Name of the class.
+ * @param completionName The completion for the class.
+ *   Can include ';' for imported classes.
+ * @param modifiers The modifiers of the class.
+ * @param completionStart The start position of insertion of the name of the class.
+ * @param completionEnd The end position of insertion of the name of the class.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptClass(
+	char[] packageName,
+	char[] className,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of a compilation error detected during completion.
+ *  @param marker Only problems which are categorized as errors are notified to the requestor,
+ *		warnings are silently ignored.
+ *		In case an error got signaled, no other completions might be available,
+ *		therefore the problem message should be presented to the user.
+ *		The source positions of the problem are related to the source where it was
+ *		detected (might be in another compilation unit, if it was indirectly requested
+ *		during the code assist process).
+ *      Note: the problem knows its originating file name.
+ */
+void acceptError(IMarker marker);
+/**
+ * Code assist notification of a field completion.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this field is declared.
+ *
+ * @param declaringTypeName Name of the type declaring this new field.
+ *
+ * @param name Name of the field.
+ *
+ * @param typePackageName Name of the package in which the type of this field is declared.
+ *
+ * @param typeName Name of the type of this field.
+ *
+ * @param completionName The completion for the field.
+ *
+ * @param modifiers The modifiers of this field.
+ *
+ * @param completionStart The start position of insertion of the name of this field.
+ *
+ * @param completionEnd The end position of insertion of the name of this field.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptField(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of an interface completion.
+ *
+ * @param packageName Declaring package name of the interface.
+ * @param interfaceName Name of the interface.
+ * @param completionName The completion for the interface.
+ *   Can include ';' for imported interfaces.
+ * @param modifiers The modifiers of the interface.
+ * @param completionStart The start position of insertion of the name of the interface.
+ * @param completionEnd The end position of insertion of the name of the interface.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptInterface(
+	char[] packageName,
+	char[] interfaceName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of a keyword completion.
+ *
+ * @param keywordName The keyword source.
+ * @param completionStart The start position of insertion of the name of this keyword.
+ * @param completionEnd The end position of insertion of the name of this keyword.
+ */
+void acceptKeyword(char[] keywordName, int completionStart, int completionEnd);
+/**
+ * Code assist notification of a label completion.
+ *
+ * @param labelName The label source.
+ * @param completionStart The start position of insertion of the name of this label.
+ * @param completionEnd The end position of insertion of the name of this label.
+ */
+void acceptLabel(char[] labelName, int completionStart, int completionEnd);
+/**
+ * Code assist notification of a local variable completion.
+ *
+ * @param name Name of the new local variable.
+ *
+ * @param typePackageName Name of the package in which the type of this new local variable is declared.
+ *
+ * @param typeName Name of the type of this new local variable.
+ *
+ * @param modifiers The modifiers of this new local variable.
+ *
+ * @param completionStart The start position of insertion of the name of this new local variable.
+ *
+ * @param completionEnd The end position of insertion of the name of this new local variable.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptLocalVariable(
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	int modifiers,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of a method completion.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared.
+ *
+ * @param declaringTypeName Name of the type declaring this new method.
+ *
+ * @param selector Name of the new method.
+ *
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *    	Should contain as many elements as parameterTypeNames.
+ *
+ * @param parameterTypeNames Names of the parameters types.
+ *    	Should contain as many elements as parameterPackageNames.
+ *
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ *
+ * @param returnTypeName Name of the return type of this new method, should be <code>null</code> for a constructor.
+ *
+ * @param completionName The completion for the method.
+ *   	Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ *
+ * @param modifiers The modifiers of this new method.
+ *
+ * @param completionStart The start position of insertion of the name of this new method.
+ *
+ * @param completionEnd The end position of insertion of the name of this new method.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ */
+void acceptMethod(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] selector,
+	char[][] parameterPackageNames,
+	char[][] parameterTypeNames,
+	char[] returnTypePackageName,
+	char[] returnTypeName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of a modifier completion.
+ *
+ * @param modifierName The new modifier.
+ * @param completionStart The start position of insertion of the name of this new modifier.
+ * @param completionEnd The end position of insertion of the name of this new modifier.
+ */
+void acceptModifier(char[] modifierName, int completionStart, int completionEnd);
+/**
+ * Code assist notification of a package completion.
+ *
+ * @param packageName The package name.
+ * @param completionName The completion for the package.
+ *   Can include '.*;' for imports.
+ * @param completionStart The start position of insertion of the name of this new package.
+ * @param completionEnd The end position of insertion of the name of this new package.
+ *
+ * NOTE - All package names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    The default package is represented by an empty array.
+ */
+void acceptPackage(
+	char[] packageName,
+	char[] completionName,
+	int completionStart,
+	int completionEnd);
+/**
+ * Code assist notification of a type completion.
+ *
+ * @param packageName Declaring package name of the type.
+ * @param typeName Name of the type.
+ * @param completionName The completion for the type.
+ *   Can include ';' for imported types.
+ * @param completionStart The start position of insertion of the name of the type.
+ * @param completionEnd The end position of insertion of the name of the type.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptType(
+	char[] packageName,
+	char[] typeName,
+	char[] completionName,
+	int completionStart,
+	int completionEnd);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java
new file mode 100644
index 0000000..7bbadfd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Specification for a generic source code formatter. Client plug-ins can contribute
+ * an implementation for an ICodeFormatter, through the extension point "org.eclipse.jdt.core.codeFormatter".
+ * In case none is found, a default formatter can be provided through the ToolFactory.
+ *
+ * @see ToolFactory#createCodeFormatter()
+ * @see ToolFactory#createDefaultCodeFormatter(java.util.Map options)
+ * @since 2.0
+ * @deprecated Use {@link org.eclipse.jdt.core.formatter.CodeFormatter} instead (note: options have changed)
+ */
+public interface ICodeFormatter {
+
+	/**
+	 * Formats the String <code>sourceString</code>,
+	 * and returns a string containing the formatted version.
+	 *
+	 * @param string the string to format
+	 * @param indentationLevel the initial indentation level, used
+	 *      to shift left/right the entire source fragment. An initial indentation
+	 *      level of zero has no effect.
+	 * @param positions an array of positions to map. These are
+	 *      character-based source positions inside the original source,
+	 * 		arranged in non-decreasing order, for which corresponding positions in
+	 *     the formatted source will be computed (so as to relocate elements associated
+	 *     with the original source). It updates the positions array with updated
+	 *     positions. If set to <code>null</code>, then no positions are mapped.
+	 * @param lineSeparator the line separator to use in formatted source,
+	 *     if set to <code>null</code>, then the platform default one will be used.
+	 * @return the formatted output string.
+	 */
+	String format(String string, int indentationLevel, int[] positions, String lineSeparator);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
new file mode 100644
index 0000000..66724a8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
@@ -0,0 +1,784 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.UndoEdit;
+
+
+/**
+ * Represents an entire Java compilation unit (source file with one of the
+ * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}).
+ * Compilation unit elements need to be opened before they can be navigated or manipulated.
+ * The children are of type {@link IPackageDeclaration},
+ * {@link IImportContainer}, and {@link IType},
+ * and appear in the order in which they are declared in the source.
+ * If a source file cannot be parsed, its structure remains unknown.
+ * Use {@link IJavaElement#isStructureKnown} to determine whether this is
+ * the case.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICompilationUnit extends ITypeRoot, IWorkingCopy, ISourceManipulation {
+/**
+ * Constant indicating that a reconcile operation should not return an AST.
+ * @since 3.0
+ */
+public static final int NO_AST = 0;
+
+/**
+ * Constant indicating that a reconcile operation should recompute the problems
+ * even if the source hasn't changed.
+ * @since 3.3
+ */
+public static final int FORCE_PROBLEM_DETECTION = 0x01;
+
+/**
+ * Constant indicating that a reconcile operation should enable the statements recovery.
+ * @see ASTParser#setStatementsRecovery(boolean)
+ * @since 3.3
+ */
+public static final int ENABLE_STATEMENTS_RECOVERY = 0x02;
+
+/**
+ * Constant indicating that a reconcile operation should enable the bindings recovery
+ * @see ASTParser#setBindingsRecovery(boolean)
+ * @see IBinding#isRecovered()
+ * @since 3.3
+ */
+public static final int ENABLE_BINDINGS_RECOVERY = 0x04;
+
+/**
+ * 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;
+
+
+/**
+ * Applies a text edit to the compilation unit's buffer.
+ * <p>
+ * Note that the edit is simply applied to the compilation unit's buffer.
+ * In particular the undo edit is not grouped with previous undo edits
+ * if the buffer doesn't implement {@link IBuffer.ITextEditCapability}.
+ * If it does, the exact semantics for grouping undo edit depends
+ * on how {@link IBuffer.ITextEditCapability#applyTextEdit(TextEdit, IProgressMonitor)}
+ * is implemented.
+ * </p>
+ *
+ * @param edit the edit to apply
+ * @param monitor the progress monitor to use or <code>null</code> if no progress should be reported
+ * @return the undo edit
+ * @throws JavaModelException if this edit can not be applied to the compilation unit's buffer. Reasons include:
+ * <ul>
+ * <li>This compilation unit does not exist ({@link IJavaModelStatusConstants#ELEMENT_DOES_NOT_EXIST}).</li>
+ * <li>The provided edit can not be applied as there is a problem with the text edit locations ({@link IJavaModelStatusConstants#BAD_TEXT_EDIT_LOCATION}).</li>
+ * </ul>
+ *
+ * @since 3.4
+ */
+public UndoEdit applyTextEdit(TextEdit edit, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Changes this compilation unit handle into a working copy. A new {@link IBuffer} is
+ * created using this compilation unit handle's owner. Uses the primary owner if none was
+ * specified when this compilation unit handle was created.
+ * <p>
+ * When switching to working copy mode, problems are reported to given
+ * {@link IProblemRequestor}. Note that once in working copy mode, the given
+ * {@link IProblemRequestor} is ignored. Only the original {@link IProblemRequestor}
+ * is used to report subsequent problems.
+ * </p>
+ * <p>
+ * Once in working copy mode, changes to this compilation unit or its children are done in memory.
+ * Only the new buffer is affected. Using {@link #commitWorkingCopy(boolean, IProgressMonitor)}
+ * will bring the underlying resource in sync with this compilation unit.
+ * </p>
+ * <p>
+ * If this compilation unit was already in working copy mode, an internal counter is incremented and no
+ * other action is taken on this compilation unit. To bring this compilation unit back into the original mode
+ * (where it reflects the underlying resource), {@link #discardWorkingCopy} must be call as many
+ * times as {@link #becomeWorkingCopy(IProblemRequestor, IProgressMonitor)}.
+ * </p>
+ *
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or <code>null</code> if no progress should be reported
+ * @throws JavaModelException if this compilation unit could not become a working copy.
+ * @see #discardWorkingCopy()
+ * @since 3.0
+ *
+ * @deprecated Use {@link #becomeWorkingCopy(IProgressMonitor)} instead.
+ * 	Note that if this deprecated method is used, problems will be reported to the given problem requestor
+ * 	as well as the problem requestor returned by the working copy owner (if not null).
+ */
+void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Changes this compilation unit handle into a working copy. A new {@link IBuffer} is
+ * created using this compilation unit handle's owner. Uses the primary owner if none was
+ * specified when this compilation unit handle was created.
+ * <p>
+ * When switching to working copy mode, problems are reported to the {@link IProblemRequestor
+ * problem requestor} of the {@link WorkingCopyOwner working copy owner}.
+ * </p><p>
+ * Once in working copy mode, changes to this compilation unit or its children are done in memory.
+ * Only the new buffer is affected. Using {@link #commitWorkingCopy(boolean, IProgressMonitor)}
+ * will bring the underlying resource in sync with this compilation unit.
+ * </p><p>
+ * If this compilation unit was already in working copy mode, an internal counter is incremented and no
+ * other action is taken on this compilation unit. To bring this compilation unit back into the original mode
+ * (where it reflects the underlying resource), {@link #discardWorkingCopy} must be call as many
+ * times as {@link #becomeWorkingCopy(IProblemRequestor, IProgressMonitor)}.
+ * </p>
+ *
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or <code>null</code> if no progress should be reported
+ * @throws JavaModelException if this compilation unit could not become a working copy.
+ * @see #discardWorkingCopy()
+ * @since 3.3
+ */
+void becomeWorkingCopy(IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Commits the contents of this working copy to its underlying resource.
+ *
+ * <p>It is possible that the contents of the original resource have changed
+ * since this working copy was created, in which case there is an update conflict.
+ * The value of the <code>force</code> parameter affects the resolution of
+ * such a conflict:<ul>
+ * <li> <code>true</code> - in this case the contents of this working copy are applied to
+ * 	the underlying resource even though this working copy was created before
+ *		a subsequent change in the resource</li>
+ * <li> <code>false</code> - in this case a {@link JavaModelException} is thrown</li>
+ * </ul>
+ * <p>
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * </p>
+ * @param force a flag to handle the cases when the contents of the original resource have changed
+ * since this working copy was created
+ * @param monitor the given progress monitor
+ * @throws JavaModelException if this working copy could not commit. Reasons include:
+ * <ul>
+ * <li> A {@link org.eclipse.core.runtime.CoreException} occurred while updating an underlying resource
+ * <li> This element is not a working copy (INVALID_ELEMENT_TYPES)
+ * <li> A update conflict (described above) (UPDATE_CONFLICT)
+ * </ul>
+ * @since 3.0
+ */
+void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Creates and returns an non-static import declaration in this compilation unit
+ * with the given name. This method is equivalent to
+ * <code>createImport(name, Flags.AccDefault, sibling, monitor)</code>.
+ *
+ * @param name the name of the import declaration to add as defined by JLS2 7.5. (For example: <code>"java.io.File"</code> or
+ *  <code>"java.awt.*"</code>)
+ * @param sibling the existing element which the import declaration will be inserted immediately before (if
+ *	<code> null </code>, then this import will be inserted as the last import declaration.
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted import declaration (or the previously existing one in case attempting to create a duplicate)
+ *
+ * @throws JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist or the specified sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A {@link org.eclipse.core.runtime.CoreException} occurred while updating an underlying resource
+ * <li> The specified sibling is not a child of this compilation unit (INVALID_SIBLING)
+ * <li> The name is not a valid import name (INVALID_NAME)
+ * </ul>
+ * @see #createImport(String, IJavaElement, int, IProgressMonitor)
+ */
+IImportDeclaration createImport(String name, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Creates and returns an import declaration in this compilation unit
+ * with the given name.
+ * <p>
+ * Optionally, the new element can be positioned before the specified
+ * sibling. If no sibling is specified, the element will be inserted
+ * as the last import declaration in this compilation unit.
+ * <p>
+ * If the compilation unit already includes the specified import declaration,
+ * the import is not generated (it does not generate duplicates).
+ * Note that it is valid to specify both a single-type import and an on-demand import
+ * for the same package, for example <code>"java.io.File"</code> and
+ * <code>"java.io.*"</code>, in which case both are preserved since the semantics
+ * of this are not the same as just importing <code>"java.io.*"</code>.
+ * Importing <code>"java.lang.*"</code>, or the package in which the compilation unit
+ * is defined, are not treated as special cases.  If they are specified, they are
+ * included in the result.
+ * <p>
+ * Note: This API element is only needed for dealing with Java code that uses
+ * new language features of J2SE 5.0.
+ * </p>
+ *
+ * @param name the name of the import declaration to add as defined by JLS2 7.5. (For example: <code>"java.io.File"</code> or
+ *  <code>"java.awt.*"</code>)
+ * @param sibling the existing element which the import declaration will be inserted immediately before (if
+ *	<code> null </code>, then this import will be inserted as the last import declaration.
+ * @param flags {@link Flags#AccStatic} for static imports, or
+ * {@link Flags#AccDefault} for regular imports; other modifier flags
+ * are ignored
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted import declaration (or the previously existing one in case attempting to create a duplicate)
+ *
+ * @throws JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist or the specified sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A {@link org.eclipse.core.runtime.CoreException} occurred while updating an underlying resource
+ * <li> The specified sibling is not a child of this compilation unit (INVALID_SIBLING)
+ * <li> The name is not a valid import name (INVALID_NAME)
+ * </ul>
+ * @see Flags
+ * @since 3.0
+ */
+IImportDeclaration createImport(String name, IJavaElement sibling, int flags, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Creates and returns a package declaration in this compilation unit
+ * with the given package name.
+ *
+ * <p>If the compilation unit already includes the specified package declaration,
+ * it is not generated (it does not generate duplicates).
+ *
+ * @param name the name of the package declaration to add as defined by JLS2 7.4. (For example, <code>"java.lang"</code>)
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted package declaration (or the previously existing one in case attempting to create a duplicate)
+ *
+ * @throws JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A {@link org.eclipse.core.runtime.CoreException} occurred while updating an underlying resource
+ * <li> The name is not a valid package name (INVALID_NAME)
+ * </ul>
+ */
+ IPackageDeclaration createPackageDeclaration(String name, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Creates and returns a type in this compilation unit with the
+ * given contents. If this compilation unit does not exist, one
+ * will be created with an appropriate package declaration.
+ * <p>
+ * Optionally, the new type can be positioned before the specified
+ * sibling. If <code>sibling</code> is <code>null</code>, the type will be appended
+ * to the end of this compilation unit.
+ *
+ * <p>It is possible that a type with the same name already exists in this compilation unit.
+ * The value of the <code>force</code> parameter affects the resolution of
+ * such a conflict:<ul>
+ * <li> <code>true</code> - in this case the type is created with the new contents</li>
+ * <li> <code>false</code> - in this case a {@link JavaModelException} is thrown</li>
+ * </ul>
+ *
+ * @param contents the source contents of the type declaration to add.
+ * @param sibling the existing element which the type will be inserted immediately before (if
+ *	<code>null</code>, then this type will be inserted as the last type declaration.
+ * @param force a <code>boolean</code> flag indicating how to deal with duplicates
+ * @param monitor the progress monitor to notify
+ * @return the newly inserted type
+ *
+ * @throws JavaModelException if the element could not be created. Reasons include:
+ * <ul>
+ * <li>The specified sibling element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A {@link org.eclipse.core.runtime.CoreException} occurred while updating an underlying resource
+ * <li> The specified sibling is not a child of this compilation unit (INVALID_SIBLING)
+ * <li> The contents could not be recognized as a type declaration (INVALID_CONTENTS)
+ * <li> There was a naming collision with an existing type (NAME_COLLISION)
+ * </ul>
+ */
+IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Changes this compilation unit in working copy mode back to its original mode.
+ * <p>
+ * This has no effect if this compilation unit was not in working copy mode.
+ * </p>
+ * <p>
+ * If {@link #becomeWorkingCopy(IProgressMonitor)} method was called several
+ * times on this compilation unit, {@link #discardWorkingCopy()} must be called
+ * as many times before it switches back to the original mode. Same as
+ * for method {@link #getWorkingCopy(IProgressMonitor)}.
+ * </p>
+ *
+ * @throws JavaModelException if this working copy could not return in its original mode.
+ * @see #becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
+ * @since 3.0
+ */
+void discardWorkingCopy() throws JavaModelException;
+/**
+ * Finds the elements in this compilation unit that correspond to
+ * the given element.
+ * An element A corresponds to an element B if:
+ * <ul>
+ * <li>A has the same element name as B.
+ * <li>If A is a method, A must have the same number of arguments as
+ *     B and the simple names of the argument types must be equals.
+ * <li>The parent of A corresponds to the parent of B recursively up to
+ *     their respective compilation units.
+ * <li>A exists.
+ * </ul>
+ * Returns <code>null</code> if no such java elements can be found
+ * or if the given element is not included in a compilation unit.
+ *
+ * @param element the given element
+ * @return the found elements in this compilation unit that correspond to the given element
+ * @since 3.0
+ */
+IJavaElement[] findElements(IJavaElement element);
+/**
+ * Finds the working copy for this compilation unit, given a {@link WorkingCopyOwner}.
+ * If no working copy has been created for this compilation unit associated with this
+ * working copy owner, returns <code>null</code>.
+ * <p>
+ * Users of this method must not destroy the resulting working copy.
+ *
+ * @param owner the given {@link WorkingCopyOwner}
+ * @return the found working copy for this compilation unit, <code>null</code> if none
+ * @see WorkingCopyOwner
+ * @since 3.0
+ */
+ICompilationUnit findWorkingCopy(WorkingCopyOwner owner);
+/**
+ * Returns all types declared in this compilation unit in the order
+ * in which they appear in the source.
+ * This includes all top-level types and nested member types.
+ * It does NOT include local types (types defined in methods).
+ *
+ * @return the array of top-level and member types defined in a compilation unit, in declaration order.
+ * @throws JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource
+ */
+IType[] getAllTypes() throws JavaModelException;
+/**
+ * Returns the first import declaration in this compilation unit with the given name.
+ * This is a handle-only method. The import declaration may or may not exist. This
+ * is a convenience method - imports can also be accessed from a compilation unit's
+ * import container.
+ *
+ * @param name the name of the import to find as defined by JLS2 7.5. (For example: <code>"java.io.File"</code>
+ * 	or <code>"java.awt.*"</code>)
+ * @return a handle onto the corresponding import declaration. The import declaration may or may not exist.
+ */
+IImportDeclaration getImport(String name) ;
+/**
+ * Returns the import container for this compilation unit.
+ * This is a handle-only method. The import container may or
+ * may not exist. The import container can used to access the
+ * imports.
+ * @return a handle onto the corresponding import container. The
+ *		import contain may or may not exist.
+ */
+IImportContainer getImportContainer();
+/**
+ * Returns the import declarations in this compilation unit
+ * in the order in which they appear in the source. This is
+ * a convenience method - import declarations can also be
+ * accessed from a compilation unit's import container.
+ *
+ * @return the import declarations in this compilation unit
+ * @throws JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource
+ */
+IImportDeclaration[] getImports() throws JavaModelException;
+/**
+ * Returns the primary compilation unit (whose owner is the primary owner)
+ * this working copy was created from, or this compilation unit if this a primary
+ * compilation unit.
+ * <p>
+ * Note that the returned primary compilation unit can be in working copy mode.
+ * </p>
+ *
+ * @return the primary compilation unit this working copy was created from,
+ * or this compilation unit if it is primary
+ * @since 3.0
+ */
+ICompilationUnit getPrimary();
+/**
+ * Returns <tt>null</tt> if this <code>ICompilationUnit</code> is the primary
+ * working copy, or this <code>ICompilationUnit</code> is not a working copy,
+ * otherwise the <code>WorkingCopyOwner</code>
+ * 
+ * @return <tt>null</tt> if this <code>ICompilationUnit</code> is the primary
+ * working copy, or this <code>ICompilationUnit</code> is not a working copy,
+ * otherwise the <code>WorkingCopyOwner</code>
+ * @since 3.0
+ */
+WorkingCopyOwner getOwner();
+/**
+ * Returns the first package declaration in this compilation unit with the given package name
+ * (there normally is at most one package declaration).
+ * This is a handle-only method. The package declaration may or may not exist.
+ *
+ * @param name the name of the package declaration as defined by JLS2 7.4. (For example, <code>"java.lang"</code>)
+ * @return the first package declaration in this compilation unit with the given package name
+ */
+IPackageDeclaration getPackageDeclaration(String name);
+/**
+ * Returns the package declarations in this compilation unit
+ * in the order in which they appear in the source.
+ * There normally is at most one package declaration.
+ *
+ * @return an array of package declaration (normally of size one)
+ *
+ * @throws JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource
+ */
+IPackageDeclaration[] getPackageDeclarations() throws JavaModelException;
+/**
+ * Returns the top-level type declared in this compilation unit with the given simple type name.
+ * The type name has to be a valid compilation unit name.
+ * This is a handle-only method. The type may or may not exist.
+ *
+ * @param name the simple name of the requested type in the compilation unit
+ * @return a handle onto the corresponding type. The type may or may not exist.
+ * @see JavaConventions#validateCompilationUnitName(String name, String sourceLevel, String complianceLevel)
+ */
+IType getType(String name);
+/**
+ * Returns the top-level types declared in this compilation unit
+ * in the order in which they appear in the source.
+ *
+ * @return the top-level types declared in this compilation unit
+ * @throws JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource
+ */
+IType[] getTypes() throws JavaModelException;
+/**
+ * Returns a new working copy of this compilation unit if it is a primary compilation unit,
+ * or this compilation unit if it is already a non-primary working copy.
+ * <p>
+ * Note: if intending to share a working copy amongst several clients, then
+ * {@link #getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)}
+ * should be used instead.
+ * </p><p>
+ * When the working copy instance is created, an ADDED IJavaElementDelta is
+ * reported on this working copy.
+ * </p><p>
+ * Once done with the working copy, users of this method must discard it using
+ * {@link #discardWorkingCopy()}.
+ * </p><p>
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * </p>
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ *                 or <code>null</code> if no progress should be reported
+ * @throws JavaModelException if the contents of this element can
+ *   not be determined.
+ * @return a new working copy of this element if this element is not
+ * a working copy, or this element if this element is already a working copy
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Returns a shared working copy on this compilation unit using the given working copy owner to create
+ * the buffer, or this compilation unit if it is already a non-primary working copy.
+ * This API can only answer an already existing working copy if it is based on the same
+ * original compilation unit AND was using the same working copy owner (that is, as defined by {@link Object#equals}).
+ * <p>
+ * The life time of a shared working copy is as follows:
+ * <ul>
+ * <li>The first call to {@link #getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)}
+ * 	creates a new working copy for this element</li>
+ * <li>Subsequent calls increment an internal counter.</li>
+ * <li>A call to {@link #discardWorkingCopy()} decrements the internal counter.</li>
+ * <li>When this counter is 0, the working copy is discarded.
+ * </ul>
+ * So users of this method must discard exactly once the working copy.
+ * <p>
+ * Note that the working copy owner will be used for the life time of this working copy, that is if the
+ * working copy is closed then reopened, this owner will be used.
+ * The buffer will be automatically initialized with the original's compilation unit content
+ * upon creation.
+ * <p>
+ * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+ * working copy.
+ * </p><p>
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * </p>
+ * @param owner the working copy owner that creates a buffer that is used to get the content
+ * 				of the working copy
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ *                 or <code>null</code> if no progress should be reported
+ * @throws JavaModelException if the contents of this element can
+ *   not be determined.
+ * @return a new working copy of this element using the given factory to create
+ * the buffer, or this element if this element is already a working copy
+ * @since 3.0
+ * @deprecated Use {@link ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} instead.
+ * 	Note that if this deprecated method is used, problems will be reported on the passed problem requester
+ * 	as well as on the problem requestor returned by the working copy owner (if not null).
+ */
+ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Returns whether the resource of this working copy has changed since the
+ * inception of this working copy.
+ * Returns <code>false</code> if this compilation unit is not in working copy mode.
+ *
+ * @return whether the resource has changed
+ * @since 3.0
+ */
+public boolean hasResourceChanged();
+/**
+ * Returns whether this element is a working copy.
+ *
+ * @return true if this element is a working copy, false otherwise
+ * @since 3.0
+ */
+boolean isWorkingCopy();
+
+/**
+ * Reconciles the contents of this working copy, sends out a Java delta
+ * notification indicating the nature of the change of the working copy since
+ * the last time it was either reconciled or made consistent
+ * ({@link IOpenable#makeConsistent(IProgressMonitor)}), and returns a
+ * compilation unit AST if requested.
+ * <p>
+ * It performs the reconciliation by locally caching the contents of
+ * the working copy, updating the contents, then creating a delta
+ * over the cached contents and the new contents, and finally firing
+ * this delta.
+ * <p>
+ * The boolean argument allows to force problem detection even if the
+ * working copy is already consistent.
+ * </p>
+ * <p>
+ * This functionality allows to specify a working copy owner which is used
+ * during problem detection. All references contained in the working copy are
+ * resolved against other units; for which corresponding owned working copies
+ * are going to take precedence over their original compilation units. If
+ * <code>null</code> is passed in, then the primary working copy owner is used.
+ * </p>
+ * <p>
+ * Compilation problems found in the new contents are notified through the
+ * {@link IProblemRequestor} interface which was passed at
+ * creation, and no longer as transient markers.
+ * </p>
+ * <p>
+ * Note: Since 3.0, added/removed/changed inner types generate change deltas.
+ * </p>
+ * <p>
+ * If requested, a DOM AST representing the compilation unit is returned.
+ * Its bindings are computed only if the problem requestor is active.
+ * This method returns <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ * <p>
+ * This method doesn't perform statements recovery. To recover statements with syntax
+ * errors, {@link #reconcile(int, boolean, boolean, WorkingCopyOwner, IProgressMonitor)} must be use.
+ * </p>
+ *
+ * @param astLevel either {@link #NO_AST} if no AST is wanted,
+ * or the {@linkplain AST#newAST(int) AST API level} of the AST if one is wanted
+ * @param forceProblemDetection boolean indicating whether problem should be
+ *   recomputed even if the source hasn't changed
+ * @param owner the owner of working copies that take precedence over the
+ *   original compilation units, or <code>null</code> if the primary working
+ *   copy owner should be used
+ * @param monitor a progress monitor
+ * @return the compilation unit AST or <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ * @throws JavaModelException if the contents of the original element
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @since 3.0
+ */
+CompilationUnit reconcile(int astLevel, boolean forceProblemDetection, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Reconciles the contents of this working copy, sends out a Java delta
+ * notification indicating the nature of the change of the working copy since
+ * the last time it was either reconciled or made consistent
+ * ({@link IOpenable#makeConsistent(IProgressMonitor)}), and returns a
+ * compilation unit AST if requested.
+ * <p>
+ * It performs the reconciliation by locally caching the contents of
+ * the working copy, updating the contents, then creating a delta
+ * over the cached contents and the new contents, and finally firing
+ * this delta.
+ * <p>
+ * The boolean argument allows to force problem detection even if the
+ * working copy is already consistent.
+ * </p>
+ * <p>
+ * This functionality allows to specify a working copy owner which is used
+ * during problem detection. All references contained in the working copy are
+ * resolved against other units; for which corresponding owned working copies
+ * are going to take precedence over their original compilation units. If
+ * <code>null</code> is passed in, then the primary working copy owner is used.
+ * </p>
+ * <p>
+ * Compilation problems found in the new contents are notified through the
+ * {@link IProblemRequestor} interface which was passed at
+ * creation, and no longer as transient markers.
+ * </p>
+ * <p>
+ * Note: Since 3.0, added/removed/changed inner types generate change deltas.
+ * </p>
+ * <p>
+ * If requested, a DOM AST representing the compilation unit is returned.
+ * Its bindings are computed only if the problem requestor is active.
+ * This method returns <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ *
+ * <p>
+ * If statements recovery is enabled then this method tries to rebuild statements
+ * with syntax error. Otherwise statements with syntax error won't be present in
+ * the returning DOM AST.
+ * </p>
+ *
+ * @param astLevel either {@link #NO_AST} if no AST is wanted,
+ * or the {@linkplain AST#newAST(int) AST API level} of the AST if one is wanted
+ * @param forceProblemDetection boolean indicating whether problem should be
+ *   recomputed even if the source hasn't changed
+ * @param enableStatementsRecovery if <code>true</code> statements recovery is enabled.
+ * @param owner the owner of working copies that take precedence over the
+ *   original compilation units, or <code>null</code> if the primary working
+ *   copy owner should be used
+ * @param monitor a progress monitor
+ * @return the compilation unit AST or <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ * @throws JavaModelException if the contents of the original element
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @since 3.2
+ */
+CompilationUnit reconcile(int astLevel, boolean forceProblemDetection, boolean enableStatementsRecovery, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Reconciles the contents of this working copy, sends out a Java delta
+ * notification indicating the nature of the change of the working copy since
+ * the last time it was either reconciled or made consistent
+ * ({@link IOpenable#makeConsistent(IProgressMonitor)}), and returns a
+ * compilation unit AST if requested.
+ *
+ * <p>
+ * If the problem detection is forced by passing the {@link #FORCE_PROBLEM_DETECTION} bit in the given reconcile flag,
+ * problem detection is run even if the working copy is already consistent.
+ * </p>
+ *
+ * <p>
+ * It performs the reconciliation by locally caching the contents of
+ * the working copy, updating the contents, then creating a delta
+ * over the cached contents and the new contents, and finally firing
+ * this delta.</p>
+ *
+ * <p>
+ * This functionality allows to specify a working copy owner which is used
+ * during problem detection. All references contained in the working copy are
+ * resolved against other units; for which corresponding owned working copies
+ * are going to take precedence over their original compilation units. If
+ * <code>null</code> is passed in, then the primary working copy owner is used.
+ * </p>
+ * <p>
+ * Compilation problems found in the new contents are notified through the
+ * {@link IProblemRequestor} interface which was passed at
+ * creation, and no longer as transient markers.
+ * </p>
+ * <p>
+ * Note: Since 3.0, added/removed/changed inner types generate change deltas.
+ * </p>
+ * <p>
+ * If requested, a DOM AST representing the compilation unit is returned.
+ * Its bindings are computed only if the problem requestor is active.
+ * This method returns <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * If statements recovery is enabled by passing the {@link #ENABLE_STATEMENTS_RECOVERY} bit in the given reconcile flag
+ * then this method tries to rebuild statements with syntax error. Otherwise statements with syntax error won't be
+ * present in the returning DOM AST.</p>
+ * <p>
+ * If bindings recovery is enabled by passing the {@link #ENABLE_BINDINGS_RECOVERY} bit in the given reconcile flag
+ * then this method tries to resolve bindings even if the type resolution contains errors.</p>
+ * <p>
+ * The given reconcile flags is a bit-mask of the different constants ({@link #ENABLE_BINDINGS_RECOVERY},
+ * {@link #ENABLE_STATEMENTS_RECOVERY}, {@link #FORCE_PROBLEM_DETECTION}). Unspecified values are left for future use.
+ * </p>
+ *
+ * @param astLevel either {@link #NO_AST} if no AST is wanted,
+ * or the {@linkplain AST#newAST(int) AST API level} of the AST if one is wanted
+ * @param reconcileFlags the given reconcile flags
+ * @param owner the owner of working copies that take precedence over the
+ *   original compilation units, or <code>null</code> if the primary working
+ *   copy owner should be used
+ * @param monitor a progress monitor
+ * @return the compilation unit AST or <code>null</code> if one of the following conditions is true:
+ * <ul>
+ *   <li>the creation of the DOM AST is not requested</li>
+ *   <li>the requested level of AST API is not supported</li>
+ *   <li>the working copy was already consistent and problem detection is not forced</li>
+ * </ul>
+ * @throws JavaModelException if the contents of the original element
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @see #FORCE_PROBLEM_DETECTION
+ * @see #ENABLE_BINDINGS_RECOVERY
+ * @see #ENABLE_STATEMENTS_RECOVERY
+ * @since 3.3
+ */
+CompilationUnit reconcile(int astLevel, int reconcileFlags, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Restores the contents of this working copy to the current contents of
+ * this working copy's original element. Has no effect if this element
+ * is not a working copy.
+ *
+ * <p>Note: This is the inverse of committing the content of the
+ * working copy to the original element with {@link #commitWorkingCopy(boolean, IProgressMonitor)}.
+ *
+ * @throws JavaModelException if the contents of the original element
+ *		cannot be accessed.  Reasons include:
+ * <ul>
+ * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @since 3.0
+ */
+void restore() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java
new file mode 100644
index 0000000..c97aa68
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java
@@ -0,0 +1,426 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * A completion requestor accepts results as they are computed and is aware
+ * of source positions to complete the various different results.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @see ICodeAssist
+ * @since 2.0
+ * @deprecated Use {@link CompletionRequestor} instead.
+ */
+public interface ICompletionRequestor {
+/**
+ * Code assist notification of an anonymous type declaration completion.
+ * @param superTypePackageName Name of the package that contains the super type of this
+ * 		new anonymous type declaration.
+ * @param superTypeName Name of the super type of this new anonymous type declaration.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *    	Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameter types.
+ * 		Should contain as many elements as parameterPackageNames.
+ * @param parameterNames Names of the parameters.
+ * 		Should contain as many elements as parameterPackageNames.
+ * @param completionName The completion for the anonymous type declaration.
+ * 		Can include zero, one or two brackets. If the closing bracket is included,
+ * 		then the cursor should be placed before it.
+ * @param modifiers The modifiers of the constructor.
+ * @param completionStart The start position of insertion of the name of this new anonymous type declaration.
+ * @param completionEnd The end position of insertion of the name of this new anonymous type declaration.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptAnonymousType(
+	char[] superTypePackageName,
+	char[] superTypeName,
+	char[][] parameterPackageNames,
+	char[][] parameterTypeNames,
+	char[][] parameterNames,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a class completion.
+ *
+ * @param packageName Declaring package name of the class.
+ * @param className Name of the class.
+ * @param completionName The completion for the class.	Can include ';' for imported classes.
+ * @param modifiers The modifiers of the class.
+ * @param completionStart The start position of insertion of the name of the class.
+ * @param completionEnd The end position of insertion of the name of the class.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptClass(
+	char[] packageName,
+	char[] className,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a compilation error detected during completion.
+ *  @param error Only problems which are categorized as non-syntax errors are notified to the
+ *     requestor, warnings are silently ignored.
+ *		In case an error got signalled, no other completions might be available,
+ *		therefore the problem message should be presented to the user.
+ *		The source positions of the problem are related to the source where it was
+ *		detected (might be in another compilation unit, if it was indirectly requested
+ *		during the code assist process).
+ *      Note: the problem knows its originating file name.
+ *
+ * @deprecated Use {@link CompletionRequestor#completionFailure(IProblem)} instead.
+ */
+void acceptError(IProblem error);
+/**
+ * Code assist notification of a field completion.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this field is declared.
+ * @param declaringTypeName Name of the type declaring this new field.
+ * @param name Name of the field.
+ * @param typePackageName Name of the package in which the type of this field is declared.
+ * @param typeName Name of the type of this field.
+ * @param completionName The completion for the field.
+ * @param modifiers The modifiers of this field.
+ * @param completionStart The start position of insertion of the name of this field.
+ * @param completionEnd The end position of insertion of the name of this field.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptField(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of an interface completion.
+ *
+ * @param packageName Declaring package name of the interface.
+ * @param interfaceName Name of the interface.
+ * @param completionName The completion for the interface.	Can include ';' for imported interfaces.
+ * @param modifiers The modifiers of the interface.
+ * @param completionStart The start position of insertion of the name of the interface.
+ * @param completionEnd The end position of insertion of the name of the interface.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptInterface(
+	char[] packageName,
+	char[] interfaceName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a keyword completion.
+ * @param keywordName The keyword source.
+ * @param completionStart The start position of insertion of the name of this keyword.
+ * @param completionEnd The end position of insertion of the name of this keyword.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptKeyword(char[] keywordName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a label completion.
+ *
+ * @param labelName The label source.
+ * @param completionStart The start position of insertion of the name of this label.
+ * @param completionEnd The end position of insertion of the name of this label.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptLabel(char[] labelName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a local variable completion.
+ *
+ * @param name Name of the new local variable.
+ * @param typePackageName Name of the package in which the type of this new local variable is declared.
+ * @param typeName Name of the type of this new local variable.
+ * @param modifiers The modifiers of this new local variable.
+ * @param completionStart The start position of insertion of the name of this new local variable.
+ * @param completionEnd The end position of insertion of the name of this new local variable.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptLocalVariable(
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a method completion.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared.
+ * @param declaringTypeName Name of the type declaring this new method.
+ * @param selector Name of the new method.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *    	Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameter types.
+ *    	Should contain as many elements as parameterPackageNames.
+ * @param parameterNames Names of the parameters.
+ *    	Should contain as many elements as parameterPackageNames.
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ * @param returnTypeName Name of the return type of this new method, should be <code>null</code> for a constructor.
+ * @param completionName The completion for the method. Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ * @param modifiers The modifiers of this new method.
+ * @param completionStart The start position of insertion of the name of this new method.
+ * @param completionEnd The end position of insertion of the name of this new method.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptMethod(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] selector,
+	char[][] parameterPackageNames,
+	char[][] parameterTypeNames,
+	char[][] parameterNames,
+	char[] returnTypePackageName,
+	char[] returnTypeName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+
+/**
+ * Code assist notification of a method completion.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared.
+ * @param declaringTypeName Name of the type declaring this new method.
+ * @param selector Name of the new method.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *    	Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameter types.
+ *    	Should contain as many elements as parameterPackageNames.
+ * @param parameterNames Names of the parameters.
+ *    	Should contain as many elements as parameterPackageNames.
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ * @param returnTypeName Name of the return type of this new method, should be <code>null</code> for a constructor.
+ * @param completionName The completion for the method. Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ * @param modifiers The modifiers of this new method.
+ * @param completionStart The start position of insertion of the name of this new method.
+ * @param completionEnd The end position of insertion of the name of this new method.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ *
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptMethodDeclaration(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] selector,
+	char[][] parameterPackageNames,
+	char[][] parameterTypeNames,
+	char[][] parameterNames,
+	char[] returnTypePackageName,
+	char[] returnTypeName,
+	char[] completionName,
+	int modifiers,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a modifier completion.
+ *
+ * @param modifierName The new modifier.
+ * @param completionStart The start position of insertion of the name of this new modifier.
+ * @param completionEnd The end position of insertion of the name of this new modifier.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptModifier(char[] modifierName, int completionStart, int completionEnd, int relevance);
+/**
+ * Code assist notification of a package completion.
+ *
+ * @param packageName The package name.
+ * @param completionName The completion for the package. Can include '.*;' for imports.
+ * @param completionStart The start position of insertion of the name of this new package.
+ * @param completionEnd The end position of insertion of the name of this new package.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    The default package is represented by an empty array.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptPackage(
+	char[] packageName,
+	char[] completionName,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+/**
+ * Code assist notification of a type completion.
+ *
+ * @param packageName Declaring package name of the type.
+ * @param typeName Name of the type.
+ * @param completionName The completion for the type. Can include ';' for imported types.
+ * @param completionStart The start position of insertion of the name of the type.
+ * @param completionEnd The end position of insertion of the name of the type.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptType(
+	char[] packageName,
+	char[] typeName,
+	char[] completionName,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+
+/**
+ * Code assist notification of a variable name completion.
+ *
+ * @param typePackageName Name of the package in which the type of this variable is declared.
+ * @param typeName Name of the type of this variable.
+ * @param name Name of the variable.
+ * @param completionName The completion for the variable.
+ * @param completionStart The start position of insertion of the name of this variable.
+ * @param completionEnd The end position of insertion of the name of this variable.
+ * @param relevance The relevance of the completion proposal
+ * 		It is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+ * 		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+ * 		value is higher.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ * @deprecated Use {@link CompletionRequestor#accept(CompletionProposal)} instead.
+ */
+void acceptVariableName(
+	char[] typePackageName,
+	char[] typeName,
+	char[] name,
+	char[] completionName,
+	int completionStart,
+	int completionEnd,
+	int relevance);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java
new file mode 100644
index 0000000..4bc382c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A callback interface for receiving java problem correction.
+ *
+ * @since 2.0
+ */
+public interface ICorrectionRequestor {
+/**
+ * Notification of a class correction.
+ *
+ * @param packageName Declaring package name of the class.
+ * @param className Name of the class.
+ * @param correctionName The correction for the class.
+ * @param modifiers The modifiers of the class.
+ * @param correctionStart The start position of insertion of the correction of the class.
+ * @param correctionEnd The end position of insertion of the correction of the class.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptClass(
+	char[] packageName,
+	char[] className,
+	char[] correctionName,
+	int modifiers,
+	int correctionStart,
+	int correctionEnd);
+/**
+ * Notification of a field correction.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this field is declared.
+ * @param declaringTypeName Name of the type declaring this field.
+ * @param name Name of the field.
+ * @param typePackageName Name of the package in which the type of this field is declared.
+ * @param typeName Name of the type of this field.
+ * @param correctionName The correction for the field.
+ * @param modifiers The modifiers of this field.
+ * @param correctionStart The start position of insertion of the correction of this field.
+ * @param correctionEnd The end position of insertion of the correction of this field.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptField(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	char[] correctionName,
+	int modifiers,
+	int correctionStart,
+	int correctionEnd);
+/**
+ * Notification of an interface correction.
+ *
+ * @param packageName Declaring package name of the interface.
+ * @param interfaceName Name of the interface.
+ * @param correctionName The correction for the interface.
+ *   Can include ';' for imported interfaces.
+ * @param modifiers The modifiers of the interface.
+ * @param correctionStart The start position of insertion of the correction of the interface.
+ * @param correctionEnd The end position of insertion of the correction of the interface.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptInterface(
+	char[] packageName,
+	char[] interfaceName,
+	char[] correctionName,
+	int modifiers,
+	int correctionStart,
+	int correctionEnd);
+/**
+ * Notification of a local variable correction.
+ *
+ * @param name Name of the local variable.
+ * @param typePackageName Name of the package in which the type of this local variable is declared.
+ * @param typeName Name of the type of this local variable.
+ * @param modifiers The modifiers of this local variable.
+ * @param correctionStart The start position of insertion of the correction of this local variable.
+ * @param correctionEnd The end position of insertion of the correction of this local variable.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ */
+void acceptLocalVariable(
+	char[] name,
+	char[] typePackageName,
+	char[] typeName,
+	int modifiers,
+	int correctionStart,
+	int correctionEnd);
+/**
+ * Notification of a method correction.
+ *
+ * @param declaringTypePackageName Name of the package in which the type that contains this method is declared.
+ * @param declaringTypeName Name of the type declaring this method.
+ * @param selector Name of the method.
+ * @param parameterPackageNames Names of the packages in which the parameter types are declared.
+ *    Should contain as many elements as parameterTypeNames.
+ * @param parameterTypeNames Names of the parameter types.
+ *    Should contain as many elements as parameterPackageNames.
+ * @param parameterNames Names of the parameters.
+ *    Should contain as many elements as parameterPackageNames.
+ * @param returnTypePackageName Name of the package in which the return type is declared.
+ * @param returnTypeName Name of the return type of this method, should be <code>null</code> for a constructor.
+ * @param correctionName The correction for the method.
+ *   Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it.
+ * @param modifiers The modifiers of this method.
+ * @param correctionStart The start position of insertion of the correction of this method.
+ * @param correctionEnd The end position of insertion of the correction of this method.
+ *
+ * NOTE - All package and type names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    Base types are in the form "int" or "boolean".
+ *    Array types are in the qualified form "M[]" or "int[]".
+ *    Nested type names are in the qualified form "A.M".
+ *    The default package is represented by an empty array.
+ *
+ * NOTE: parameter names can be retrieved from the source model after the user selects a specific method.
+ */
+void acceptMethod(
+	char[] declaringTypePackageName,
+	char[] declaringTypeName,
+	char[] selector,
+	char[][] parameterPackageNames,
+	char[][] parameterTypeNames,
+	char[][] parameterNames,
+	char[] returnTypePackageName,
+	char[] returnTypeName,
+	char[] correctionName,
+	int modifiers,
+	int correctionStart,
+	int correctionEnd);
+/**
+ * Notification of a package correction.
+ *
+ * @param packageName The package name.
+ * @param correctionName The correction for the package.
+ *   Can include '.*;' for imports.
+ * @param correctionStart The start position of insertion of the correction of this package.
+ * @param correctionEnd The end position of insertion of the correction of this package.
+ *
+ * NOTE - All package names are presented in their readable form:
+ *    Package names are in the form "a.b.c".
+ *    The default package is represented by an empty array.
+ */
+void acceptPackage(
+	char[] packageName,
+	char[] correctionName,
+	int correctionStart,
+	int correctionEnd);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java
new file mode 100644
index 0000000..ee3526d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * An element changed listener receives notification of changes to Java elements
+ * maintained by the Java model.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * 
+ * @see JavaCore#addElementChangedListener(IElementChangedListener)
+ */
+public interface IElementChangedListener {
+
+/**
+ * Notifies that one or more attributes of one or more Java elements have changed.
+ * The specific details of the change are described by the given event.
+ *
+ * @param event the change event
+ */
+public void elementChanged(ElementChangedEvent event);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java
new file mode 100644
index 0000000..15cf167
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents a field declared in a type.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IField extends IMember, IAnnotatable {
+
+/**
+ * Returns the constant value associated with this field
+ * or <code>null</code> if this field has none. The field needs to be static and final to have
+ * a constant value.
+ * Returns an instance of the wrapper type corresponding to the the type of the field.
+ * <table border="1">
+ * <tr>
+ * <th>field type</th>
+ * <th>wrapper type</th>
+ * </tr>
+ * <tr>
+ * <td>int
+ * </td>
+ * <td>java.lang.Integer
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>byte
+ * </td>
+ * <td>java.lang.Byte
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>boolean
+ * </td>
+ * <td>java.lang.Boolean
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>char
+ * </td>
+ * <td>java.lang.Character
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>double
+ * </td>
+ * <td>java.lang.Double
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>float
+ * </td>
+ * <td>java.lang.Float
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>long
+ * </td>
+ * <td>java.lang.Long
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>short
+ * </td>
+ * <td>java.lang.Short
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>java.lang.String
+ * </td>
+ * <td>java.lang.String
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * @return  the constant value associated with this field or <code>null</code> if this field has none.
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ */
+public Object getConstant() throws JavaModelException;
+/**
+ * Returns the simple name of this field.
+ * @return the simple name of this field.
+ */
+String getElementName();
+/**
+ * Returns the binding key for this field only if the given field is {@link #isResolved() resolved}.
+ * A binding key is a key that uniquely identifies this field. It allows access to generic info
+ * for parameterized fields.
+ *
+ * <p>If the given field is not resolved, the returned key is simply the java element's key.
+ * </p>
+ * @return the binding key for this field
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @see BindingKey
+ * @see #isResolved()
+ * @since 3.1
+ */
+String getKey();
+/**
+ * Returns the type signature of this field. For enum constants,
+ * this returns the signature of the declaring enum class.
+ * <p>
+ * The type signature may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ * </p>
+ *
+ * @return the type signature of this field
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @see Signature
+ */
+String getTypeSignature() throws JavaModelException;
+/**
+ * Returns whether this field represents an enum constant.
+ *
+ * @return whether this field represents an enum constant
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @since 3.1
+ */
+boolean isEnumConstant() throws JavaModelException;
+/**
+ * Returns whether this field represents a resolved field.
+ * If a field is resolved, its key contains resolved information.
+ *
+ * @return whether this field represents a resolved field.
+ * @since 3.1
+ */
+boolean isResolved();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java
new file mode 100644
index 0000000..7a98d17
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents an import container is a child of a Java compilation unit that contains
+ * all (and only) the import declarations. If a compilation unit has no import
+ * declarations, no import container will be present.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IImportContainer extends IJavaElement, IParent, ISourceReference {
+/**
+ * Returns the first import declaration in this import container with the given name.
+ * This is a handle-only method. The import declaration may or may not exist.
+ *
+ * @param name the given name
+ *
+ * @return the first import declaration in this import container with the given name
+ */
+IImportDeclaration getImport(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java
new file mode 100644
index 0000000..789279f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents an import declaration in Java compilation unit.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IImportDeclaration extends IJavaElement, ISourceReference, ISourceManipulation {
+/**
+ * Returns the name that has been imported.
+ * For an on-demand import, this includes the trailing <code>".*"</code>.
+ * For example, for the statement <code>"import java.util.*"</code>,
+ * this returns <code>"java.util.*"</code>.
+ * For the statement <code>"import java.util.Hashtable"</code>,
+ * this returns <code>"java.util.Hashtable"</code>.
+ *
+ * @return the name that has been imported
+ */
+String getElementName();
+/**
+ * Returns the modifier flags for this import. The flags can be examined using class
+ * <code>Flags</code>. Only the static flag is meaningful for import declarations.
+ *
+ * @return the modifier flags for this import
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @see Flags
+ * @since 3.0
+ */
+int getFlags() throws JavaModelException;
+/**
+ * Returns whether the import is on-demand. An import is on-demand if it ends
+ * with <code>".*"</code>.
+ * @return true if the import is on-demand, false otherwise
+ */
+boolean isOnDemand();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java
new file mode 100644
index 0000000..bba6b29
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents a stand-alone instance or class (static) initializer in a type.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IInitializer extends IMember {
+	// interface used as a marker: defines no member
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJarEntryResource.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJarEntryResource.java
new file mode 100644
index 0000000..80d2343
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJarEntryResource.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * A jar entry corresponding to a non-Java resource in an archive {@link IPackageFragment} or {@link IPackageFragmentRoot}.
+ * <p>
+ * One can navigate the non-Java resource tree using the {@link #getChildren()} and {@link #getParent()} methods.
+ * Jar entry resources are either files ({@link #isFile()} returns true) or directories ({@link #isFile()} returns false).
+ * Files don't have any children and the returned array is always empty.
+ * </p><p>
+ * Jar entry resources that refer to the same element are guaranteed to be equal, but not necessarily identical.
+ * <p>
+ *
+ * @since 3.3
+ */
+public interface IJarEntryResource extends IStorage {
+
+	/**
+	 * Returns the list of children of this jar entry resource.
+	 * Returns an empty array if this jar entry is a file, or if this jar entry is a directory and it has no children.
+	 *
+	 * @return the children of this jar entry resource
+	 */
+	IJarEntryResource[] getChildren();
+
+	/**
+	 * Returns the full, absolute path of this jar entry resource relative to the archive this jar
+	 * entry belongs to.
+	 * <p>
+	 * A jar entry resource's full path indicates the route from the root of the archive
+	 * to the jar entry resource.  Within an archive, there is exactly one such path
+	 * for any given jar entry resource. </p>
+	 * <p>
+	 * The returned path is absolute (i.e. it starts with a separator) and it never has a trailing separator.
+	 * </p>
+	 *
+	 * @return the absolute path of this jar entry resource
+	 */
+	IPath getFullPath();
+
+	/**
+	 * Returns the parent of this jar entry resource. This is either an {@link IJarEntryResource}, an {@link IPackageFragment}
+	 * or an {@link IPackageFragmentRoot}.
+	 *
+	 * @return the parent of this jar entry resource
+	 */
+	Object getParent();
+
+	/**
+	 * Returns the package fragment root this jar entry resource belongs to.
+	 *
+	 * @return the package fragment root this jar entry resource belongs to.
+	 */
+	IPackageFragmentRoot getPackageFragmentRoot();
+
+	/**
+	 * Returns <code>true</code> if this jar entry represents a file.
+	 * Returns <code>false</code> if it is a directory.
+	 *
+	 * @return whether this jar entry is a file
+	 */
+	boolean isFile();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java
new file mode 100644
index 0000000..62b9372
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java
@@ -0,0 +1,372 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+/**
+ * Common protocol for all elements provided by the Java model.
+ * Java model elements are exposed to clients as handles to the actual underlying element.
+ * The Java model may hand out any number of handles for each element. Handles
+ * that refer to the same element are guaranteed to be equal, but not necessarily identical.
+ * <p>
+ * Methods annotated as "handle-only" do not require underlying elements to exist.
+ * Methods that require underlying elements to exist throw
+ * a <code>JavaModelException</code> when an underlying element is missing.
+ * <code>JavaModelException.isDoesNotExist</code> can be used to recognize
+ * this common special case.
+ * </p>
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaElement extends IAdaptable {
+
+	/**
+	 * Constant representing a Java model (workspace level object).
+	 * A Java element with this type can be safely cast to {@link IJavaModel}.
+	 */
+	int JAVA_MODEL = 1;
+
+	/**
+	 * Constant representing a Java project.
+	 * A Java element with this type can be safely cast to {@link IJavaProject}.
+	 */
+	int JAVA_PROJECT = 2;
+
+	/**
+	 * Constant representing a package fragment root.
+	 * A Java element with this type can be safely cast to {@link IPackageFragmentRoot}.
+	 */
+	int PACKAGE_FRAGMENT_ROOT = 3;
+
+	/**
+	 * Constant representing a package fragment.
+	 * A Java element with this type can be safely cast to {@link IPackageFragment}.
+	 */
+	int PACKAGE_FRAGMENT = 4;
+
+	/**
+	 * Constant representing a Java compilation unit.
+	 * A Java element with this type can be safely cast to {@link ICompilationUnit}.
+	 */
+	int COMPILATION_UNIT = 5;
+
+	/**
+	 * Constant representing a class file.
+	 * A Java element with this type can be safely cast to {@link IClassFile}.
+	 */
+	int CLASS_FILE = 6;
+
+	/**
+	 * Constant representing a type (a class or interface).
+	 * A Java element with this type can be safely cast to {@link IType}.
+	 */
+	int TYPE = 7;
+
+	/**
+	 * Constant representing a field.
+	 * A Java element with this type can be safely cast to {@link IField}.
+	 */
+	int FIELD = 8;
+
+	/**
+	 * Constant representing a method or constructor.
+	 * A Java element with this type can be safely cast to {@link IMethod}.
+	 */
+	int METHOD = 9;
+
+	/**
+	 * Constant representing a stand-alone instance or class initializer.
+	 * A Java element with this type can be safely cast to {@link IInitializer}.
+	 */
+	int INITIALIZER = 10;
+
+	/**
+	 * Constant representing a package declaration within a compilation unit.
+	 * A Java element with this type can be safely cast to {@link IPackageDeclaration}.
+	 */
+	int PACKAGE_DECLARATION = 11;
+
+	/**
+	 * Constant representing all import declarations within a compilation unit.
+	 * A Java element with this type can be safely cast to {@link IImportContainer}.
+	 */
+	int IMPORT_CONTAINER = 12;
+
+	/**
+	 * Constant representing an import declaration within a compilation unit.
+	 * A Java element with this type can be safely cast to {@link IImportDeclaration}.
+	 */
+	int IMPORT_DECLARATION = 13;
+
+	/**
+	 * Constant representing a local variable declaration.
+	 * A Java element with this type can be safely cast to {@link ILocalVariable}.
+	 * @since 3.0
+	 */
+	int LOCAL_VARIABLE = 14;
+
+	/**
+	 * Constant representing a type parameter declaration.
+	 * A Java element with this type can be safely cast to {@link ITypeParameter}.
+	 * @since 3.1
+	 */
+	int TYPE_PARAMETER = 15;
+
+	/**
+	 * Constant representing an annotation.
+	 * A Java element with this type can be safely cast to {@link IAnnotation}.
+	 * @since 3.4
+	 */
+	int ANNOTATION = 16;
+
+	/**
+	 * Returns whether this Java element exists in the model.
+	 * <p>
+	 * Java elements are handle objects that may or may not be backed by an
+	 * actual element. Java elements that are backed by an actual element are
+	 * said to "exist", and this method returns <code>true</code>. For Java
+	 * elements that are not working copies, it is always the case that if the
+	 * element exists, then its parent also exists (provided it has one) and
+	 * includes the element as one of its children. It is therefore possible
+	 * to navigated to any existing Java element from the root of the Java model
+	 * along a chain of existing Java elements. On the other hand, working
+	 * copies are said to exist until they are destroyed (with
+	 * <code>IWorkingCopy.destroy</code>). Unlike regular Java elements, a
+	 * working copy never shows up among the children of its parent element
+	 * (which may or may not exist).
+	 * </p>
+	 *
+	 * @return <code>true</code> if this element exists in the Java model, and
+	 * <code>false</code> if this element does not exist
+	 */
+	boolean exists();
+
+	/**
+	 * Returns this Java element or the first ancestor of this element that has the given type.
+	 * Returns <code>null</code> if no such element can be found.
+	 * This is a handle-only method.
+	 *
+	 * @param ancestorType the given type
+	 * @return this Java element or the first ancestor of this element that has the given type, or <code>null</code> if no such element can be found
+	 * @since 2.0
+	 */
+	IJavaElement getAncestor(int ancestorType);
+
+	/**
+	 * <p>Returns the Javadoc as HTML source if this element has attached Javadoc,
+	 * <code>null</code> otherwise.</p>
+	 * <p>This should be used only for binary elements. Source elements will always return <code>null</code>.</p>
+	 * <p>The encoding used to read the Javadoc is the one defined by the content type of the
+	 * file. If none is defined, then the project's encoding of this Java element is used. If the project's
+	 * encoding cannot be retrieved, then the platform encoding is used.</p>
+	 * <p>In case the Javadoc doesn't exist for this element, <code>null</code> is returned.</p>
+	 *
+	 * <p>The HTML is extracted from the attached Javadoc and provided as is. No
+	 * transformation or validation is done.</p>
+	 *
+	 * @param monitor the given progress monitor, can be <code>null</code>
+	 * @exception JavaModelException if:<ul>
+	 *  <li>this element does not exist</li>
+	 *  <li>retrieving the attached javadoc fails (timed-out, invalid URL, ...)</li>
+	 *  <li>the format of the javadoc doesn't match expected standards (different anchors,...)</li>
+	 *  </ul>
+	 * @return the extracted javadoc from the attached javadoc, <code>null</code> if none
+	 * @see IClasspathAttribute#JAVADOC_LOCATION_ATTRIBUTE_NAME
+	 * @since 3.2
+	 */
+	String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Returns the resource that corresponds directly to this element,
+	 * or <code>null</code> if there is no resource that corresponds to
+	 * this element.
+	 * <p>
+	 * For example, the corresponding resource for an <code>ICompilationUnit</code>
+	 * is its underlying <code>IFile</code>. The corresponding resource for
+	 * an <code>IPackageFragment</code> that is not contained in an archive
+	 * is its underlying <code>IFolder</code>. An <code>IPackageFragment</code>
+	 * contained in an archive has no corresponding resource. Similarly, there
+	 * are no corresponding resources for <code>IMethods</code>,
+	 * <code>IFields</code>, etc.
+	 * <p>
+	 *
+	 * @return the corresponding resource, or <code>null</code> if none
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	IResource getCorrespondingResource() throws JavaModelException;
+
+	/**
+	 * Returns the name of this element. This is a handle-only method.
+	 *
+	 * @return the element name
+	 */
+	String getElementName();
+
+	/**
+	 * Returns this element's kind encoded as an integer.
+	 * This is a handle-only method.
+	 *
+	 * @return the kind of element; one of the constants declared in
+	 *   <code>IJavaElement</code>
+	 * @see IJavaElement
+	 */
+	int getElementType();
+
+	/**
+	 * Returns a string representation of this element handle. The format of
+	 * the string is not specified; however, the identifier is stable across
+	 * workspace sessions, and can be used to recreate this handle via the
+	 * <code>JavaCore.create(String)</code> method.
+	 *
+	 * @return the string handle identifier
+	 * @see JavaCore#create(java.lang.String)
+	 */
+	String getHandleIdentifier();
+
+	/**
+	 * Returns the Java model.
+	 * This is a handle-only method.
+	 *
+	 * @return the Java model
+	 */
+	IJavaModel getJavaModel();
+
+	/**
+	 * Returns the Java project this element is contained in,
+	 * or <code>null</code> if this element is not contained in any Java project
+	 * (for instance, the <code>IJavaModel</code> is not contained in any Java
+	 * project).
+	 * This is a handle-only method.
+	 *
+	 * @return the containing Java project, or <code>null</code> if this element is
+	 *   not contained in a Java project
+	 */
+	IJavaProject getJavaProject();
+
+	/**
+	 * Returns the first openable parent. If this element is openable, the element
+	 * itself is returned. Returns <code>null</code> if this element doesn't have
+	 * an openable parent.
+	 * This is a handle-only method.
+	 *
+	 * @return the first openable parent or <code>null</code> if this element doesn't have
+	 * an openable parent.
+	 * @since 2.0
+	 */
+	IOpenable getOpenable();
+
+	/**
+	 * Returns the element directly containing this element,
+	 * or <code>null</code> if this element has no parent.
+	 * This is a handle-only method.
+	 *
+	 * @return the parent element, or <code>null</code> if this element has no parent
+	 */
+	IJavaElement getParent();
+
+	/**
+	 * Returns the path to the innermost resource enclosing this element.
+	 * If this element is not included in an external library,
+	 * the path returned is the full, absolute path to the underlying resource,
+	 * relative to the workbench.
+	 * If this element is included in an external library,
+	 * the path returned is the absolute path to the archive or to the
+	 * folder in the file system.
+	 * This is a handle-only method.
+	 *
+	 * @return the path to the innermost resource enclosing this element
+	 * @since 2.0
+	 */
+	IPath getPath();
+
+	/**
+	 * Returns the primary element (whose compilation unit is the primary compilation unit)
+	 * this working copy element was created from, or this element if it is a descendant of a
+	 * primary compilation unit or if it is not a descendant of a working copy (e.g. it is a
+	 * binary member).
+	 * The returned element may or may not exist.
+	 *
+	 * @return the primary element this working copy element was created from, or this
+	 * 			element.
+	 * @since 3.0
+	 */
+	IJavaElement getPrimaryElement();
+
+	/**
+	 * Returns the innermost resource enclosing this element.
+	 * If this element is included in an archive and this archive is not external,
+	 * this is the underlying resource corresponding to the archive.
+	 * If this element is included in an external library, <code>null</code>
+	 * is returned.
+	 * This is a handle-only method.
+	 *
+	 * @return the innermost resource enclosing this element, <code>null</code> if this
+	 * element is included in an external archive
+	 * @since 2.0
+	 */
+	IResource getResource();
+
+	/**
+	 * Returns the scheduling rule associated with this Java element.
+	 * This is a handle-only method.
+	 *
+	 * @return the scheduling rule associated with this Java element
+	 * @since 3.0
+	 */
+	ISchedulingRule getSchedulingRule();
+
+	/**
+	 * Returns the smallest underlying resource that contains
+	 * this element, or <code>null</code> if this element is not contained
+	 * in a resource.
+	 *
+	 * @return the underlying resource, or <code>null</code> if none
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its underlying resource
+	 */
+	IResource getUnderlyingResource() throws JavaModelException;
+
+	/**
+	 * Returns whether this Java element is read-only. An element is read-only
+	 * if its structure cannot be modified by the java model.
+	 * <p>
+	 * Note this is different from IResource.isReadOnly(). For example, .jar
+	 * files are read-only as the java model doesn't know how to add/remove
+	 * elements in this file, but the underlying IFile can be writable.
+	 * <p>
+	 * This is a handle-only method.
+	 *
+	 * @return <code>true</code> if this element is read-only
+	 */
+	boolean isReadOnly();
+
+	/**
+	 * Returns whether the structure of this element is known. For example, for a
+	 * compilation unit that has syntax errors, <code>false</code> is returned.
+	 * If the structure of an element is unknown, navigations will return reasonable
+	 * defaults. For example, <code>getChildren</code> for a compilation unit with
+	 * syntax errors will return a collection of the children that could be parsed.
+	 * <p>
+	 * Note: This does not imply anything about consistency with the
+	 * underlying resource/buffer contents.
+	 * </p>
+	 *
+	 * @return <code>true</code> if the structure of this element is known
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */// TODO (philippe) predicate shouldn't throw an exception
+	boolean isStructureKnown() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java
new file mode 100644
index 0000000..bc17b09
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+/**
+ * A Java element delta describes changes in Java element between two discrete
+ * points in time.  Given a delta, clients can access the element that has
+ * changed, and any children that have changed.
+ * <p>
+ * Deltas have a different status depending on the kind of change they represent.
+ * The list below summarizes each status (as returned by {@link #getKind})
+ * and its meaning (see individual constants for a more detailled description):
+ * <ul>
+ * <li>{@link #ADDED} - The element described by the delta has been added.</li>
+ * <li>{@link #REMOVED} - The element described by the delta has been removed.</li>
+ * <li>{@link #CHANGED} - The element described by the delta has been changed in some way.
+ * Specification of the type of change is provided by {@link #getFlags} which returns the following values:
+ * <ul>
+ * <li>{@link #F_ADDED_TO_CLASSPATH} - A classpath entry corresponding to the element
+ * has been added to the project's classpath. This flag is only valid if the element is an
+ * {@link IPackageFragmentRoot}.</li>
+ * <li>{@link #F_ARCHIVE_CONTENT_CHANGED} - The contents of an archive
+ * has changed in some way. This flag is only valid if the element is an {@link IPackageFragmentRoot}
+ * which is an archive.</li>
+ * <li>{@link #F_CHILDREN} - A child of the element has changed in some way.  This flag
+ * is only valid if the element is an {@link IParent}.</li>
+ * <li>{@link #F_CLASSPATH_REORDER} - A classpath entry corresponding to the element
+ * has changed position in the project's classpath. This flag is only valid if the element is an
+ * {@link IPackageFragmentRoot}.</li>
+ * <li>{@link #F_CLOSED} - The underlying {@link org.eclipse.core.resources.IProject}
+ * has been closed. This flag is only valid if the element is an {@link IJavaProject}.</li>
+ * <li>{@link #F_CONTENT} - The contents of the element have been altered.  This flag
+ * is only valid for elements which correspond to files.</li>
+ *<li>{@link #F_FINE_GRAINED} - The delta is a fine-grained delta, that is, an analysis down
+ * to the members level was done to determine if there were structural changes to members of the element.</li>
+ * <li>{@link #F_MODIFIERS} - The modifiers on the element have changed in some way.
+ * This flag is only valid if the element is an {@link IMember}.</li>
+ * <li>{@link #F_OPENED} - The underlying {@link org.eclipse.core.resources.IProject}
+ * has been opened. This flag is only valid if the element is an {@link IJavaProject}.</li>
+ * <li>{@link #F_REMOVED_FROM_CLASSPATH} - A classpath entry corresponding to the element
+ * has been removed from the project's classpath. This flag is only valid if the element is an
+ * {@link IPackageFragmentRoot}.</li>
+ * <li>{@link #F_SOURCEATTACHED} - The source attachment path or the source attachment root path
+ * of a classpath entry corresponding to the element was added. This flag is only valid if the element is an
+ * {@link IPackageFragmentRoot}.</li>
+ * <li>{@link #F_SOURCEDETACHED} - The source attachment path or the source attachment root path
+ * of a classpath entry corresponding to the element was removed. This flag is only valid if the element is an
+ * {@link IPackageFragmentRoot}.</li>
+ * <li>{@link #F_SUPER_TYPES} - One of the supertypes of an {@link IType} has changed</li>.
+ * </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * Move operations are indicated by other change flags, layered on top
+ * of the change flags described above. If element A is moved to become B,
+ * the delta for the  change in A will have status {@link #REMOVED},
+ * with change flag {@link #F_MOVED_TO}. In this case,
+ * {@link #getMovedToElement} on delta A will return the handle for B.
+ * The  delta for B will have status {@link #ADDED}, with change flag
+ * {@link #F_MOVED_FROM}, and {@link #getMovedFromElement} on delta
+ * B will return the handle for A. (Note, the handle to A in this case represents
+ * an element that no longer exists).
+ * </p>
+ * <p>
+ * Note that the move change flags only describe the changes to a single element, they
+ * do not imply anything about the parent or children of the element.
+ * </p>
+ * <p>
+ * The {@link #F_ADDED_TO_CLASSPATH}, {@link #F_REMOVED_FROM_CLASSPATH} and
+ * {@link #F_CLASSPATH_REORDER} flags are triggered by changes to a project's classpath. They do not mean that
+ * the underlying resource was added, removed or changed. For example, if a project P already contains a folder src, then
+ * adding a classpath entry with the 'P/src' path to the project's classpath will result in an {@link IJavaElementDelta}
+ * with the {@link #F_ADDED_TO_CLASSPATH} flag for the {@link IPackageFragmentRoot} P/src.
+ * On the contrary, if a resource is physically added, removed or changed and this resource corresponds to a classpath
+ * entry of the project, then an {@link IJavaElementDelta} with the {@link #ADDED},
+ * {@link #REMOVED}, or {@link #CHANGED} kind will be fired.
+ * </p>
+ * <p>
+ * Note that when a source attachment path or a source attachment root path is changed, then the flags of the delta contain
+ * both {@link #F_SOURCEATTACHED} and {@link #F_SOURCEDETACHED}.
+ * </p>
+ * <p>
+ * No assumptions should be made on whether the java element delta tree is rooted at the {@link IJavaModel}
+ * level or not.
+ * </p>
+ * <p>
+ * {@link IJavaElementDelta} object are not valid outside the dynamic scope
+ * of the notification.
+ * </p>
+ *
+ * @see IElementChangedListener
+ * @see ElementChangedEvent
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaElementDelta {
+
+	/**
+	 * Status constant indicating that the element has been added.
+	 * Note that an added java element delta has no children, as they are all implicitely added.
+	 */
+	public int ADDED = 1;
+
+	/**
+	 * Status constant indicating that the element has been removed.
+	 * Note that a removed java element delta has no children, as they are all implicitely removed.
+	 */
+	public int REMOVED = 2;
+
+	/**
+	 * Status constant indicating that the element has been changed,
+	 * as described by the change flags.
+	 *
+	 * @see #getFlags()
+	 */
+	public int CHANGED = 4;
+
+	/**
+	 * Change flag indicating that the content of the element has changed.
+	 * This flag is only valid for elements which correspond to files.
+	 */
+	public int F_CONTENT = 0x000001;
+
+	/**
+	 * Change flag indicating that the modifiers of the element have changed.
+	 * This flag is only valid if the element is an {@link IMember}.
+	 */
+	public int F_MODIFIERS = 0x000002;
+
+	/**
+	 * Change flag indicating that there are changes to the children of the element.
+	 * This flag is only valid if the element is an {@link IParent}.
+	 */
+	public int F_CHILDREN = 0x000008;
+
+	/**
+	 * Change flag indicating that the element was moved from another location.
+	 * The location of the old element can be retrieved using {@link #getMovedFromElement}.
+	 */
+	public int F_MOVED_FROM = 0x000010;
+
+	/**
+	 * Change flag indicating that the element was moved to another location.
+	 * The location of the new element can be retrieved using {@link #getMovedToElement}.
+	 */
+	public int F_MOVED_TO = 0x000020;
+
+	/**
+	 * Change flag indicating that a classpath entry corresponding to the element has been added to the project's classpath.
+	 * This flag is only valid if the element is an {@link IPackageFragmentRoot}.
+	 */
+	public int F_ADDED_TO_CLASSPATH = 0x000040;
+
+	/**
+	 * Change flag indicating that a classpath entry corresponding to the element has been removed from the project's
+	 * classpath. This flag is only valid if the element is an {@link IPackageFragmentRoot}.
+	 */
+	public int F_REMOVED_FROM_CLASSPATH = 0x000080;
+
+	/**
+	 * Change flag indicating that a classpath entry corresponding to the element has changed position in the project's
+	 * classpath. This flag is only valid if the element is an {@link IPackageFragmentRoot}.
+	 * @deprecated Use {@link #F_REORDER} instead.
+	 */
+	public int F_CLASSPATH_REORDER = 0x000100;
+	/**
+	 * Change flag indicating that the element has changed position relatively to its siblings.
+	 * If the element is an {@link IPackageFragmentRoot},  a classpath entry corresponding
+	 * to the element has changed position in the project's classpath.
+	 *
+	 * @since 2.1
+	 */
+	public int F_REORDER = 0x000100;
+
+	/**
+	 * Change flag indicating that the underlying {@link org.eclipse.core.resources.IProject} has been
+	 * opened. This flag is only valid if the element is an {@link IJavaProject}.
+	 */
+	public int F_OPENED = 0x000200;
+
+	/**
+	 * Change flag indicating that the underlying {@link org.eclipse.core.resources.IProject} has been
+	 * closed. This flag is only valid if the element is an {@link IJavaProject}.
+	 */
+	public int F_CLOSED = 0x000400;
+
+	/**
+	 * Change flag indicating that one of the supertypes of an {@link IType}
+	 * has changed.
+	 */
+	public int F_SUPER_TYPES = 0x000800;
+
+	/**
+	 * Change flag indicating that the source attachment path or the source attachment root path of a classpath entry
+	 * corresponding to the element was added. This flag is only valid if the element is an
+	 * {@link IPackageFragmentRoot}.
+	 */
+	public int F_SOURCEATTACHED = 0x001000;
+
+	/**
+	 * Change flag indicating that the source attachment path or the source attachment root path of a classpath entry
+	 * corresponding to the element was removed. This flag is only valid if the element is an
+	 * {@link IPackageFragmentRoot}.
+	 */
+	public int F_SOURCEDETACHED = 0x002000;
+
+	/**
+	 * Change flag indicating that this is a fine-grained delta, that is, an analysis down
+	 * to the members level was done to determine if there were structural changes to
+	 * members.
+	 * <p>
+	 * Clients can use this flag to find out if a compilation unit
+     * that have a {@link #F_CONTENT} change should assume that there are
+     * no finer grained changes ({@link #F_FINE_GRAINED} is set) or if
+     * finer grained changes were not considered ({@link #F_FINE_GRAINED}
+     * is not set).
+     *
+     * @since 2.0
+	 */
+	public int F_FINE_GRAINED = 0x004000;
+
+	/**
+	 * Change flag indicating that the element's archive content on the classpath has changed.
+	 * This flag is only valid if the element is an {@link IPackageFragmentRoot}
+	 * which is an archive.
+	 *
+	 * @see IPackageFragmentRoot#isArchive()
+	 * @since 2.0
+	 */
+	public int F_ARCHIVE_CONTENT_CHANGED = 0x008000;
+
+	/**
+	 * Change flag indicating that a compilation unit has become a primary working copy, or that a
+	 * primary working copy has reverted to a compilation unit.
+	 * This flag is only valid if the element is an {@link ICompilationUnit}.
+	 *
+	 * @since 3.0
+	 */
+	public int F_PRIMARY_WORKING_COPY = 0x010000;
+
+	/**
+	 * Change flag indicating that the {@link IJavaProject#getRawClasspath() raw classpath}
+	 * (or the {@link IJavaProject#getOutputLocation() output folder}) of a project has changed.
+	 * This flag is only valid if the element is an {@link IJavaProject}.
+	 * Also see {@link #F_RESOLVED_CLASSPATH_CHANGED}, which indicates that there is a
+	 * change to the {@link IJavaProject#getResolvedClasspath(boolean) resolved class path}.
+	 * The resolved classpath can change without the raw classpath changing (e.g.
+	 * if a container resolves to a different set of classpath entries).
+	 * And conversely, it is possible to construct a case where the raw classpath
+	 * can change without the resolved classpath changing.
+	 *
+	 * @since 3.0
+	 */
+	public int F_CLASSPATH_CHANGED = 0x020000;
+
+	/**
+	 * Change flag indicating that the resource of a primary compilation unit has changed.
+	 * This flag is only valid if the element is a primary {@link ICompilationUnit}.
+	 *
+	 * @since 3.0
+	 */
+	public int F_PRIMARY_RESOURCE = 0x040000;
+
+	/**
+	 * Change flag indicating that a reconcile operation has affected the compilation unit AST created in a
+	 * previous reconcile operation. Use {@link #getCompilationUnitAST()} to retrieve the AST (if any is available).
+	 * This flag is only valid if the element is an {@link ICompilationUnit} in working copy mode.
+	 *
+	 * @since 3.2
+	 */
+	public int F_AST_AFFECTED = 0x080000;
+
+	/**
+	 * Change flag indicating that the categories of the element have changed.
+	 * This flag is only valid if the element is an {@link IMember}.
+	 *
+	 * @since 3.2
+	 */
+	public int F_CATEGORIES = 0x100000;
+
+	/**
+	 * Change flag indicating that the {@link IJavaProject#getResolvedClasspath(boolean)
+	 * resolved classpath} of a project has changed.
+	 * This flag is only valid if the element is an {@link IJavaProject}.
+	 * Also see {@link #F_CLASSPATH_CHANGED}, which indicates that there is a
+	 * change to the {@link IJavaProject#getRawClasspath() raw class path}.
+	 * The resolved classpath can change without the raw classpath changing (e.g.
+	 * if a container resolves to a different set of classpath entries).
+	 * And conversely, it is possible to construct a case where the raw classpath
+	 * can change without the resolved classpath changing.
+	 *
+	 * @since 3.4
+	 */
+	public int F_RESOLVED_CLASSPATH_CHANGED = 0x200000;
+
+	/**
+	 * Change flag indicating that the annotations of the element have changed.
+	 * Use {@link #getAnnotationDeltas()} to get the added/removed/changed annotations.
+	 * This flag is only valid if the element is an {@link IAnnotatable}.
+	 *
+	 * @since 3.4
+	 */
+	public int F_ANNOTATIONS = 0x400000;
+
+	/**
+	 * Returns deltas for the children that have been added.
+	 * @return deltas for the children that have been added
+	 */
+	public IJavaElementDelta[] getAddedChildren();
+
+	/**
+	 * Returns deltas for the affected (added, removed, or changed) children.
+	 * @return deltas for the affected (added, removed, or changed) children
+	 */
+	public IJavaElementDelta[] getAffectedChildren();
+
+	/**
+	 * Returns deltas for affected annotations (added, removed, or changed).
+	 * Returns an empty array if no annotations was affected, or if this delta's element is not
+	 * an {@link IAnnotatable}.
+	 *
+	 * @return deltas for affected annotations (added, removed, or changed)
+	 *
+	 * @since 3.4
+	 */
+	public IJavaElementDelta[] getAnnotationDeltas();
+
+	/**
+	 * Returns the compilation unit AST created by the last reconcile operation on this delta's element.
+	 * This returns a non-null value if and only if:
+	 * <ul>
+	 * <li>the last reconcile operation on this working copy requested an AST</li>
+	 * <li>this delta's element is an {@link ICompilationUnit} in working copy mode</li>
+	 * <li>the delta comes from a {@link ElementChangedEvent#POST_RECONCILE} event
+	 * </ul>
+	 *
+	 * @return the AST created during the last reconcile operation
+	 * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, org.eclipse.core.runtime.IProgressMonitor)
+	 * @see #F_AST_AFFECTED
+	 * @since 3.2
+	 */
+	public CompilationUnit getCompilationUnitAST();
+
+	/**
+	 * Returns deltas for the children which have changed.
+	 * @return deltas for the children which have changed
+	 */
+	public IJavaElementDelta[] getChangedChildren();
+
+	/**
+	 * Returns the element that this delta describes a change to.
+	 * @return the element that this delta describes a change to
+	 */
+	public IJavaElement getElement();
+
+	/**
+	 * Returns flags that describe how an element has changed.
+	 * Such flags should be tested using the <code>&</code> operand. For example:
+	 * <pre>
+	 * if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0) {
+	 * 	// the delta indicates a content change
+	 * }
+	 * </pre>
+	 *
+	 * @return flags that describe how an element has changed
+	 */
+	public int getFlags();
+
+	/**
+	 * Returns the kind of this delta - one of {@link #ADDED}, {@link #REMOVED},
+	 * or {@link #CHANGED}.
+	 *
+	 * @return the kind of this delta
+	 */
+	public int getKind();
+
+	/**
+	 * Returns an element describing this element before it was moved
+	 * to its current location, or <code>null</code> if the
+	 * {@link #F_MOVED_FROM} change flag is not set.
+	 *
+	 * @return an element describing this element before it was moved
+	 * to its current location, or <code>null</code> if the
+	 * {@link #F_MOVED_FROM} change flag is not set
+	 */
+	public IJavaElement getMovedFromElement();
+
+	/**
+	 * Returns an element describing this element in its new location,
+	 * or <code>null</code> if the {@link #F_MOVED_TO} change
+	 * flag is not set.
+	 *
+	 * @return an element describing this element in its new location,
+	 * or <code>null</code> if the {@link #F_MOVED_TO} change
+	 * flag is not set
+	 */
+	public IJavaElement getMovedToElement();
+
+	/**
+	 * Returns deltas for the children which have been removed.
+	 *
+	 * @return deltas for the children which have been removed
+	 */
+	public IJavaElementDelta[] getRemovedChildren();
+
+	/**
+	 * Returns the collection of resource deltas.
+	 * <p>
+	 * Note that resource deltas, like Java element deltas, are generally only valid
+	 * for the dynamic scope of an event notification. Clients must not hang on to
+	 * these objects.
+	 * </p>
+	 *
+	 * @return the underlying resource deltas, or <code>null</code> if none
+	 */
+	public IResourceDelta[] getResourceDeltas();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java
new file mode 100644
index 0000000..2df3560
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Represent the root Java element corresponding to the workspace.
+ * Since there is only one such root element, it is commonly referred to as
+ * <em>the</em> Java model element.
+ * The Java model element needs to be opened before it can be navigated or manipulated.
+ * The Java model element has no parent (it is the root of the Java element
+ * hierarchy). Its children are <code>IJavaProject</code>s.
+ * <p>
+ * This interface provides methods for performing copy, move, rename, and
+ * delete operations on multiple Java elements.
+ * </p>
+ * <p>
+ * An instance of one of these handles can be created via
+ * <code>JavaCore.create(workspace.getRoot())</code>.
+ * </p>
+ *
+ * @see JavaCore#create(org.eclipse.core.resources.IWorkspaceRoot)
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaModel extends IJavaElement, IOpenable, IParent {
+/**
+ * Returns whether this Java model contains an <code>IJavaElement</code> whose
+ * resource is the given resource or a non-Java resource which is the given resource.
+ * <p>
+ * Note: no existency check is performed on the argument resource. If it is not accessible
+ * (see <code>IResource.isAccessible()</code>) yet but would be located in Java model
+ * range, then it will return <code>true</code>.
+ * </p><p>
+ * If the resource is accessible, it can be reached by navigating the Java model down using the
+ * <code>getChildren()</code> and/or <code>getNonJavaResources()</code> methods.
+ * </p>
+ * @param resource the resource to check
+ * @return true if the resource is accessible through the Java model
+ * @since 2.1
+ */
+boolean contains(IResource resource);
+/**
+ * Copies the given elements to the specified container(s).
+ * If one container is specified, all elements are copied to that
+ * container. If more than one container is specified, the number of
+ * elements and containers must match, and each element is copied to
+ * its associated container.
+ * <p>
+ * Optionally, each copy can positioned before a sibling
+ * element. If <code>null</code> is specified for a given sibling, the copy
+ * is inserted as the last child of its associated container.
+ * </p>
+ * <p>
+ * Optionally, each copy can be renamed. If
+ * <code>null</code> is specified for the new name, the copy
+ * is not renamed.
+ * </p>
+ * <p>
+ * Optionally, any existing child in the destination container with
+ * the same name can be replaced by specifying <code>true</code> for
+ * force. Otherwise an exception is thrown in the event that a name
+ * collision occurs.
+ * </p>
+ *
+ * @param elements the elements to copy
+ * @param containers the container, or list of containers
+ * @param siblings the list of siblings element any of which may be
+ *   <code>null</code>; or <code>null</code>
+ * @param renamings the list of new names any of which may be
+ *   <code>null</code>; or <code>null</code>
+ * @param replace <code>true</code> if any existing child in a target container
+ *   with the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if an element could not be copied. Reasons include:
+ * <ul>
+ * <li> There is no element to process (NO_ELEMENTS_TO_PROCESS). The given elements is null or empty</li>
+ * <li> A specified element, container, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource</li>
+ * <li> A container is of an incompatible type (<code>INVALID_DESTINATION</code>)</li>
+ * <li> A sibling is not a child of it associated container (<code>INVALID_SIBLING</code>)</li>
+ * <li> A new name is invalid (<code>INVALID_NAME</code>)</li>
+ * <li> A child in its associated container already exists with the same
+ * 		name and <code>replace</code> has been specified as <code>false</code> (<code>NAME_COLLISION</code>)</li>
+ * <li> A container or element is read-only (<code>READ_ONLY</code>) </li>
+ * </ul>
+ * @see org.eclipse.jdt.core.IJavaModelStatusConstants#INVALID_DESTINATION
+ */
+void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Deletes the given elements, forcing the operation if necessary and specified.
+ *
+ * @param elements the elements to delete
+ * @param force a flag controlling whether underlying resources that are not
+ *    in sync with the local file system will be tolerated
+ * @param monitor a progress monitor
+ * @exception JavaModelException if an element could not be deleted. Reasons include:
+ * <ul>
+ * <li> There is no element to process (NO_ELEMENTS_TO_PROCESS). The given elements is null or empty</li>
+ * <li> A specified element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource</li>
+ * <li> An element is read-only (<code>READ_ONLY</code>) </li>
+ * </ul>
+ */
+void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Returns the Java project with the given name. The given name must be a valid
+ * path segment as defined by {@link IPath#isValidSegment(String)}.
+ * This is a handle-only method.
+ * The project may or may not exist.
+ *
+ * @param name the name of the Java project
+ * @return the Java project with the given name
+ */
+IJavaProject getJavaProject(String name);
+/**
+ * Returns the Java projects in this Java model, or an empty array if there
+ * are none.
+ *
+ * @return the Java projects in this Java model, or an empty array if there
+ * are none
+ * @exception JavaModelException if this request fails.
+ */
+IJavaProject[] getJavaProjects() throws JavaModelException;
+/**
+ * Returns an array of non-Java resources (that is, non-Java projects) in
+ * the workspace.
+ * <p>
+ * Non-Java projects include all projects that are closed (even if they have the
+ * Java nature).
+ * </p>
+ *
+ * @return an array of non-Java projects (<code>IProject</code>s) contained
+ *              in the workspace.
+ * @throws JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource
+ * @since 2.1
+ */
+Object[] getNonJavaResources() throws JavaModelException;
+/**
+ * Returns the workspace associated with this Java model.
+ *
+ * @return the workspace associated with this Java model
+ */
+IWorkspace getWorkspace();
+/**
+ * Moves the given elements to the specified container(s).
+ * If one container is specified, all elements are moved to that
+ * container. If more than one container is specified, the number of
+ * elements and containers must match, and each element is moved to
+ * its associated container.
+ * <p>
+ * Optionally, each element can positioned before a sibling
+ * element. If <code>null</code> is specified for sibling, the element
+ * is inserted as the last child of its associated container.
+ * </p>
+ * <p>
+ * Optionally, each element can be renamed. If
+ * <code>null</code> is specified for the new name, the element
+ * is not renamed.
+ * </p>
+ * <p>
+ * Optionally, any existing child in the destination container with
+ * the same name can be replaced by specifying <code>true</code> for
+ * force. Otherwise an exception is thrown in the event that a name
+ * collision occurs.
+ * </p>
+ *
+ * @param elements the elements to move
+ * @param containers the container, or list of containers
+ * @param siblings the list of siblings element any of which may be
+ *   <code>null</code>; or <code>null</code>
+ * @param renamings the list of new names any of which may be
+ *   <code>null</code>; or <code>null</code>
+ * @param replace <code>true</code> if any existing child in a target container
+ *   with the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if an element could not be moved. Reasons include:
+ * <ul>
+ * <li> There is no element to process (NO_ELEMENTS_TO_PROCESS). The given elements is null or empty</li>
+ * <li> A specified element, container, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource</li>
+ * <li> A container is of an incompatible type (<code>INVALID_DESTINATION</code>)</li>
+ * <li> A sibling is not a child of it associated container (<code>INVALID_SIBLING</code>)</li>
+ * <li> A new name is invalid (<code>INVALID_NAME</code>)</li>
+ * <li> A child in its associated container already exists with the same
+ * 		name and <code>replace</code> has been specified as <code>false</code> (<code>NAME_COLLISION</code>)</li>
+ * <li> A container or element is read-only (<code>READ_ONLY</code>) </li>
+ * </ul>
+ *
+ * @exception IllegalArgumentException any element or container is <code>null</code>
+ * @see org.eclipse.jdt.core.IJavaModelStatusConstants#INVALID_DESTINATION
+ */
+void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Triggers an update of the JavaModel with respect to the referenced external archives.
+ * This operation will issue a JavaModel delta describing the discovered changes, in term
+ * of Java element package fragment roots added, removed or changed.
+ * Note that a collection of elements can be passed so as to narrow the set of archives
+ * to refresh (passing <code>null</code> along is equivalent to refreshing the entire mode).
+ * The elements can be:
+ * <ul>
+ * <li> package fragment roots corresponding to external archives
+ * <li> Java projects, which referenced external archives will be refreshed
+ * <li> Java model, all referenced external archives will be refreshed.
+ * </ul>
+ * <p> In case an archive is used by multiple projects, the delta issued will account for
+ * all of them. This means that even if a project was not part of the elements scope, it
+ * may still be notified of changes if it is referencing a library comprised in the scope.
+ * <p>
+ * <b>Since 3.7</b>, a project refresh automatically triggers a refresh of external archives.
+ * Hence, this method doesn't need to be explicitly called after a project refresh.
+ * <p>
+ * @param elementsScope - a collection of elements defining the scope of the refresh
+ * @param monitor - a progress monitor used to report progress
+ * @exception JavaModelException in one of the corresponding situation:
+ * <ul>
+ *    <li> an exception occurs while accessing project resources </li>
+ * </ul>
+ *
+ * @see IJavaElementDelta
+ * @since 2.0
+ */
+void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Renames the given elements as specified.
+ * If one container is specified, all elements are renamed within that
+ * container. If more than one container is specified, the number of
+ * elements and containers must match, and each element is renamed within
+ * its associated container.
+ *
+ * @param elements the elements to rename
+ * @param destinations the container, or list of containers
+ * @param names the list of new names
+ * @param replace <code>true</code> if an existing child in a target container
+ *   with the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if an element could not be renamed. Reasons include:
+ * <ul>
+ * <li> There is no element to process (NO_ELEMENTS_TO_PROCESS). The given elements is null or empty</li>
+ * <li> A specified element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> A new name is invalid (<code>INVALID_NAME</code>)
+ * <li> A child already exists with the same name and <code>replace</code> has been specified as <code>false</code> (<code>NAME_COLLISION</code>)
+ * <li> An element is read-only (<code>READ_ONLY</code>)
+ * </ul>
+ */
+void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java
new file mode 100644
index 0000000..8d485ab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IMarker;
+
+/**
+ * Markers used by the Java model.
+ * <p>
+ * This interface declares constants only.
+ * </p>
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaModelMarker {
+
+	/**
+	 * Java model problem marker type (value
+	 * <code>"org.eclipse.jdt.core.problem"</code>). This can be used to
+	 * recognize those markers in the workspace that flag problems detected by
+	 * the Java tooling during compilation.
+	 */
+	String JAVA_MODEL_PROBLEM_MARKER = JavaCore.PLUGIN_ID + ".problem"; //$NON-NLS-1$
+
+	/**
+	 * Java model transient problem marker type (value
+	 * <code>"org.eclipse.jdt.core.transient_problem"</code>). This can be
+	 * used to recognize those markers in the workspace that flag transient
+	 * problems detected by the Java tooling (such as a problem detected by the
+	 * outliner, or a problem detected during a code completion). Since 1.0,
+	 * transient problems are reported as <code>IProblem</code> through
+	 * various API. Only the evaluation API is still producing markers for
+	 * transient problems.
+	 *
+	 * @see org.eclipse.jdt.core.compiler.IProblem
+	 * @see org.eclipse.jdt.core.eval.ICodeSnippetRequestor#acceptProblem(org.eclipse.core.resources.IMarker,String,
+	 *      int)
+	 */
+	String TRANSIENT_PROBLEM = JavaCore.PLUGIN_ID + ".transient_problem"; //$NON-NLS-1$
+
+	/**
+	 * Java model task marker type (value
+	 * <code>"org.eclipse.jdt.core.task"</code>). This can be used to
+	 * recognize task markers in the workspace that correspond to tasks
+	 * specified in Java source comments and detected during compilation (for
+	 * example, 'TO-DO: ...'). Tasks are identified by a task tag, which can be
+	 * customized through <code>JavaCore</code> option
+	 * <code>"org.eclipse.jdt.core.compiler.taskTag"</code>.
+	 *
+	 * @since 2.1
+	 */
+	String TASK_MARKER = JavaCore.PLUGIN_ID + ".task"; //$NON-NLS-1$
+
+	/**
+	 * Id marker attribute (value <code>"arguments"</code>). Arguments are
+	 * concatenated into one String, prefixed with an argument count (followed
+	 * with colon separator) and separated with '#' characters. For example: {
+	 * "foo", "bar" } is encoded as "2:foo#bar", { } is encoded as "0:".
+	 * <p>Empty argument is encoded as three spaces ("   ").</p>
+	 * <p>If the argument contains a '#', the character is doubled.<br>
+	 * {"foo#test", "bar" } is encoded as "2:foo##test#bar"
+	 * </p>
+	 * 
+	 * @since 2.0
+	 * @see CorrectionEngine#getProblemArguments(IMarker)
+	 */
+	String ARGUMENTS = "arguments"; //$NON-NLS-1$
+
+	/**
+	 * ID marker attribute (value <code>"id"</code>).
+	 */
+	String ID = "id"; //$NON-NLS-1$
+
+	/**
+	 * ID category marker attribute (value <code>"categoryId"</code>)
+	 * @since 3.2
+	 */
+	String CATEGORY_ID = "categoryId"; //$NON-NLS-1$
+
+	/**
+	 * Flags marker attribute (value <code>"flags"</code>). Reserved for
+	 * future use.
+	 */
+	String FLAGS = "flags"; //$NON-NLS-1$
+
+	/**
+	 * Cycle detected marker attribute (value <code>"cycleDetected"</code>).
+	 * Used only on buildpath problem markers. The value of this attribute is
+	 * either "true" or "false".
+	 */
+	String CYCLE_DETECTED = "cycleDetected"; //$NON-NLS-1$
+
+	/**
+	 * Build path problem marker type (value
+	 * <code>"org.eclipse.jdt.core.buildpath_problem"</code>). This can be
+	 * used to recognize those markers in the workspace that flag problems
+	 * detected by the Java tooling during classpath setting.
+	 */
+	String BUILDPATH_PROBLEM_MARKER = JavaCore.PLUGIN_ID
+			+ ".buildpath_problem"; //$NON-NLS-1$
+
+	/**
+	 * Classpath file format marker attribute (value
+	 * <code>"classpathFileFormat"</code>). Used only on buildpath problem
+	 * markers. The value of this attribute is either "true" or "false".
+	 *
+	 * @since 2.0
+	 */
+	String CLASSPATH_FILE_FORMAT = "classpathFileFormat"; //$NON-NLS-1$
+	
+	/**
+	 * Output overlapping another source attribute (value <code>"outputOverlappingSource"</code>). 
+	 * Used only on buildpath problem markers. The value of this attribute is 
+	 * either "true" or "false".
+	 * 
+	 * @since 3.6.4
+	 */
+	String OUTPUT_OVERLAPPING_SOURCE = "outputOverlappingSource"; //$NON-NLS-1$
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java
new file mode 100644
index 0000000..cc03a1a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * Represents the outcome of an Java model operation. Status objects are
+ * used inside <code>JavaModelException</code> objects to indicate what went
+ * wrong.
+ * <p>
+ * Java model status object are distinguished by their plug-in id:
+ * <code>getPlugin</code> returns <code>"org.eclipse.jdt.core"</code>.
+ * <code>getCode</code> returns one of the status codes declared in
+ * <code>IJavaModelStatusConstants</code>.
+ * </p>
+ * <p>
+ * A Java model status may also carry additional information (that is, in
+ * addition to the information defined in <code>IStatus</code>):
+ * <ul>
+ *   <li>elements - optional handles to Java elements associated with the failure</li>
+ *   <li>string - optional string associated with the failure</li>
+ * </ul>
+ *
+ * @see org.eclipse.core.runtime.IStatus
+ * @see IJavaModelStatusConstants
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaModelStatus extends IStatus {
+/**
+ * Returns any Java elements associated with the failure (see specification
+ * of the status code), or an empty array if no elements are related to this
+ * particular status code.
+ *
+ * @return the list of Java element culprits
+ * @see IJavaModelStatusConstants
+ */
+IJavaElement[] getElements();
+/**
+ * Returns the path associated with the failure (see specification
+ * of the status code), or <code>null</code> if the failure is not
+ * one of <code>DEVICE_PATH</code>, <code>INVALID_PATH</code>,
+ * <code>PATH_OUTSIDE_PROJECT</code>, or <code>RELATIVE_PATH</code>.
+ *
+ * @return the path that caused the failure, or <code>null</code> if none
+ * @see IJavaModelStatusConstants#DEVICE_PATH
+ * @see IJavaModelStatusConstants#INVALID_PATH
+ * @see IJavaModelStatusConstants#PATH_OUTSIDE_PROJECT
+ * @see IJavaModelStatusConstants#RELATIVE_PATH
+ */
+IPath getPath();
+/**
+ * Returns the string associated with the failure (see specification
+ * of the status code), or <code>null</code> if no string is related to this
+ * particular status code.
+ *
+ * @return the string culprit, or <code>null</code> if none
+ * @see IJavaModelStatusConstants
+ * @deprecated Use {@link IStatus#getMessage()} instead
+ */
+String getString();
+/**
+ * Returns whether this status indicates that a Java model element does not exist.
+ * This convenience method is equivalent to
+ * <code>getCode() == IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST</code>.
+ *
+ * @return <code>true</code> if the status code indicates that a Java model
+ *   element does not exist
+ * @see IJavaModelStatusConstants#ELEMENT_DOES_NOT_EXIST
+ */
+boolean isDoesNotExist();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
new file mode 100644
index 0000000..a88db5e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
@@ -0,0 +1,355 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *
+ * TODO missing 2.1 and subsequent contributions
+ * COMPILER_FAILURE
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Status codes used with Java model status objects.
+ * <p>
+ * This interface declares constants only.
+ * </p>
+ *
+ * @see IJavaModelStatus
+ * @see org.eclipse.core.runtime.IStatus#getCode()
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaModelStatusConstants {
+
+	/**
+	 * Status constant indicating that a container path was resolved
+	 * to invalid entries (null or container).
+	 *
+	 * @since 2.0
+	 */
+	public static final int INVALID_CP_CONTAINER_ENTRY = 962;
+
+	/**
+	 * Status constant indicating that a container path was not resolvable
+	 * indicating either the referred container is undefined, unbound.
+	 *
+	 * @since 2.0
+	 */
+	public static final int CP_CONTAINER_PATH_UNBOUND = 963;
+
+	/**
+	 * Status constant indicating that a classpath entry was invalid
+	 */
+	public static final int INVALID_CLASSPATH = 964;
+
+	/**
+	 * Status constant indicating that a variable path was not resolvable
+	 * indicating either the referred variable is undefined, unbound or the resolved
+	 * variable path does not correspond to an existing file or folder.
+	 */
+	public static final int CP_VARIABLE_PATH_UNBOUND = 965;
+
+	/**
+	 * Status constant indicating a core exception occurred.
+	 * Use <code>getException</code> to retrieve a <code>CoreException</code>.
+	 */
+	public static final int CORE_EXCEPTION = 966;
+
+	/**
+	 * Status constant indicating one or more of the elements
+	 * supplied are not of a valid type for the operation to
+	 * process.
+	 * The element(s) can be retrieved using <code>getElements</code> on the status object.
+	 */
+	public static final int INVALID_ELEMENT_TYPES = 967;
+
+	/**
+	 * Status constant indicating that no elements were
+	 * provided to the operation for processing.
+	 */
+	public static final int NO_ELEMENTS_TO_PROCESS = 968;
+
+	/**
+	 * Status constant indicating that one or more elements
+	 * supplied do not exist.
+	 * The element(s) can be retrieved using <code>getElements</code> on the status object.
+	 *
+	 * @see IJavaModelStatus#isDoesNotExist()
+	 */
+	public static final int ELEMENT_DOES_NOT_EXIST = 969;
+
+	/**
+	 * Status constant indicating that a <code>null</code> path was
+	 * supplied to the operation.
+	 */
+	public static final int NULL_PATH = 970;
+
+	/**
+	 * Status constant indicating that a path outside of the
+	 * project was supplied to the operation. The path can be retrieved using
+	 * <code>getPath</code> on the status object.
+	 */
+	public static final int PATH_OUTSIDE_PROJECT = 971;
+
+	/**
+	 * Status constant indicating that a relative path
+	 * was supplied to the operation when an absolute path is
+	 * required. The path can be retrieved using <code>getPath</code> on the
+	 * status object.
+	 */
+	public static final int RELATIVE_PATH = 972;
+
+	/**
+	 * Status constant indicating that a path specifying a device
+	 * was supplied to the operation when a path with no device is
+	 * required. The path can be retrieved using <code>getPath</code> on the
+	 * status object.
+	 */
+	public static final int DEVICE_PATH = 973;
+
+	/**
+	 * Status constant indicating that a string
+	 * was supplied to the operation that was <code>null</code>.
+	 */
+	public static final int NULL_STRING = 974;
+
+	/**
+	 * Status constant indicating that the operation encountered
+	 * a read-only element.
+	 * The element(s) can be retrieved using <code>getElements</code> on the status object.
+	 */
+	public static final int READ_ONLY = 976;
+
+	/**
+	 * Status constant indicating that a naming collision would occur
+	 * if the operation proceeded.
+	 */
+	public static final int NAME_COLLISION = 977;
+
+	/**
+	 * Status constant indicating that a destination provided for a copy/move/rename operation
+	 * is invalid. The destination for a package fragment must be a package fragment root; the 
+	 * destination for a compilation unit must be a package fragment; the destination for 
+	 * a package declaration or import declaration must be a compilation unit; the 
+	 * destination for a type must be a type or compilation unit; the destination for any 
+	 * type member (other than a type) must be a type. <br>
+	 * 
+	 * The destination element can be retrieved using <code>getElements</code> on the status object.
+	 */
+	public static final int INVALID_DESTINATION = 978;
+
+	/**
+	 * Status constant indicating that a path provided to an operation
+	 * is invalid. The path can be retrieved using <code>getPath</code> on the
+	 * status object.
+	 */
+	public static final int INVALID_PATH = 979;
+
+	/**
+	 * Status constant indicating the given source position is out of bounds.
+	 */
+	public static final int INDEX_OUT_OF_BOUNDS = 980;
+
+	/**
+	 * Status constant indicating there is an update conflict
+	 * for a working copy. The compilation unit on which the
+	 * working copy is based has changed since the working copy
+	 * was created.
+	 */
+	public static final int UPDATE_CONFLICT = 981;
+
+	/**
+	 * Status constant indicating that <code>null</code> was specified
+	 * as a name argument.
+	 */
+	public static final int NULL_NAME = 982;
+
+	/**
+	 * Status constant indicating that a name provided is not syntactically correct.
+	 * The name can be retrieved from <code>getString</code>.
+	 */
+	public static final int INVALID_NAME = 983;
+
+	/**
+	 * Status constant indicating that the specified contents
+	 * are not valid.
+	 */
+	public static final int INVALID_CONTENTS = 984;
+
+	/**
+	 * Status constant indicating that an <code>java.io.IOException</code>
+	 * occurred.
+	 */
+	public static final int IO_EXCEPTION = 985;
+
+	/**
+	 * Status constant indicating that a <code>DOMException</code>
+	 * occurred.
+	 */
+	public static final int DOM_EXCEPTION = 986;
+
+	/**
+	 * Status constant indicating that a <code>TargetException</code>
+	 * occurred.
+	 */
+	public static final int TARGET_EXCEPTION = 987;
+
+	/**
+	 * Status constant indicating that the Java builder
+	 * could not be initialized.
+	 */
+	public static final int BUILDER_INITIALIZATION_ERROR = 990;
+
+	/**
+	 * Status constant indicating that the Java builder's last built state
+	 * could not be serialized or deserialized.
+	 */
+	public static final int BUILDER_SERIALIZATION_ERROR = 991;
+
+	/**
+	 * Status constant indicating that an error was encountered while
+	 * trying to evaluate a code snippet, or other item.
+	 */
+	public static final int EVALUATION_ERROR = 992;
+
+	/**
+	 * Status constant indicating that a sibling specified is not valid.
+	 */
+	public static final int INVALID_SIBLING = 993;
+
+	/**
+	 * Status indicating that a Java element could not be created because
+	 * the underlying resource is invalid.
+	 * @see JavaCore
+	 */
+	 public static final int INVALID_RESOURCE = 995;
+
+	/**
+	 * Status indicating that a Java element could not be created because
+	 * the underlying resource is not of an appropriate type.
+	 * @see JavaCore
+	 */
+	 public static final int INVALID_RESOURCE_TYPE = 996;
+
+	/**
+	 * Status indicating that a Java element could not be created because
+	 * the project owning underlying resource does not have the Java nature.
+	 * @see JavaCore
+	 */
+	 public static final int INVALID_PROJECT = 997;
+
+	/**
+	 * Status indicating that the package declaration in a <code>ICompilationUnit</code>
+	 * does not correspond to the <code>IPackageFragment</code> it belongs to.
+	 * The <code>getString</code> method of the associated status object
+	 * gives the name of the package in which the <code>ICompilationUnit</code> is
+	 * declared.
+	 */
+	 public static final int INVALID_PACKAGE = 998;
+
+	/**
+	 * Status indicating that the corresponding resource has no local contents yet.
+	 * This might happen when attempting to use a resource before its contents
+	 * has been made locally available.
+	 */
+	 public static final int NO_LOCAL_CONTENTS = 999;
+
+	 /**
+	  * Status indicating that a .classpath file is ill-formed, and thus cannot
+	  * be read/written successfully.
+	  * @since 2.1
+	  */
+	 public static final int INVALID_CLASSPATH_FILE_FORMAT = 1000;
+
+	 /**
+	  * Status indicating that a project is involved in a build path cycle.
+	  * @since 2.1
+	  */
+	 public static final int CLASSPATH_CYCLE = 1001;
+
+	/**
+	 * Status constant indicating that an inclusion or an exclusion pattern got specified
+	 * on a classpath source entry, though it was explicitely disabled
+	 * according to its project preference settings.
+	 * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
+	 * @since 2.1
+	 */
+	public static final int DISABLED_CP_EXCLUSION_PATTERNS = 1002;
+
+	/**
+	 * Status constant indicating that a specific output location got associated
+	 * with a source entry, though it was explicitely disabled according to its project
+	 * preference settings.
+	 * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
+	 * @since 2.1
+	 */
+	public static final int DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS = 1003;
+
+	/**
+	 * Status constant indicating that a project is prerequisiting some library for which the
+	 * classfile JDK version level is more recent than the project JDK target level setting.
+	 * This can indicate some binary incompatibility issues later on.
+	 * @since 3.0
+	 */
+	public static final int INCOMPATIBLE_JDK_LEVEL	= 1004;
+
+	/**
+	 * Status constant indicating that a compiler failure occurred.
+	 * @since 3.0
+	 */
+	public static final int COMPILER_FAILURE	= 1005;
+	/**
+	 * Status constant indicating that an element is not on its project's claspath.
+	 * @since 3.1
+	 */
+	public static final int ELEMENT_NOT_ON_CLASSPATH	= 1006;
+	/**
+	 * Status constant indicating that a compiler option is invalid.
+	 * @since 3.1
+	 */
+//	public static final int INVALID_COMPILER_OPTION = 1007;
+	/**
+	 * <p>Status constant indicating that the attached javadoc content cannot be retrieved due to multiple reasons:
+	 * invalid url, incorrect proxy, wrong authentication,...</p>
+	 *
+	 * @since 3.2
+	 */
+	public static final int CANNOT_RETRIEVE_ATTACHED_JAVADOC = 1008;
+	/**
+	 * <p>Status constant indicating that the attached javadoc content format is unrecognized.</p>
+	 *
+	 * @since 3.2
+	 */
+	public static final int UNKNOWN_JAVADOC_FORMAT = 1009;
+	/**
+	 * <p>Status constant indicating that the variable is deprecated.</p>
+	 *
+	 * @since 3.3
+	 */
+	public static final int DEPRECATED_VARIABLE = 1010;
+
+	/**
+	 * <p>Status constant indicating that a text edit can not be applied as there
+	 * is a problem with the text edit location.</p>
+	 *
+	 * @since 3.4
+	 */
+	public static final int BAD_TEXT_EDIT_LOCATION = 1011;
+	
+	/**
+	 * <p>Status constant indicating that the attached javadoc content cannot be retrieved due to timeout
+	 * @since 3.7
+	 */
+	public static final int CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT = 1012;
+	
+	/**
+	 * <p>Status constant indicating that the default or specific output folder is overlapping
+	 * with another source location. </p>
+	 * @since 3.6.4
+	 */
+	public static final int OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = 1013;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
new file mode 100644
index 0000000..ebab53f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -0,0 +1,1162 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added getOption(String, boolean), getOptions(boolean) and setOptions(Map)
+ *     IBM Corporation - deprecated getPackageFragmentRoots(IClasspathEntry) and
+ *                               added findPackageFragmentRoots(IClasspathEntry)
+ *     IBM Corporation - added isOnClasspath(IResource)
+ *     IBM Corporation - added setOption(String, String)
+ *     IBM Corporation - added forceClasspathReload(IProgressMonitor)
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.jdt.core.dom.IAnnotationBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.IPackageBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.eval.IEvaluationContext;
+
+/**
+ * A Java project represents a view of a project resource in terms of Java
+ * elements such as package fragments, types, methods and fields.
+ * A project may contain several package roots, which contain package fragments.
+ * A package root corresponds to an underlying folder or JAR.
+ * <p>
+ * Each Java project has a classpath, defining which folders contain source code and
+ * where required libraries are located. Each Java project also has an output location,
+ * defining where the builder writes <code>.class</code> files. A project that
+ * references packages in another project can access the packages by including
+ * the required project in a classpath entry. The Java model will present the
+ * source elements in the required project; when building, the compiler will use
+ * the corresponding generated class files from the required project's output
+ * location(s)). The classpath format is a sequence of classpath entries
+ * describing the location and contents of package fragment roots.
+ * </p>
+ * Java project elements need to be opened before they can be navigated or manipulated.
+ * The children of a Java project are the package fragment roots that are
+ * defined by the classpath and contained in this project (in other words, it
+ * does not include package fragment roots for other projects). The children
+ * (i.e. the package fragment roots) appear in the order they are defined by 
+ * the classpath.
+ * </p>
+ * <p>
+ * An instance of one of these handles can be created via
+ * <code>JavaCore.create(project)</code>.
+ * </p>
+ *
+ * @see JavaCore#create(org.eclipse.core.resources.IProject)
+ * @see IClasspathEntry
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaProject extends IParent, IJavaElement, IOpenable {
+
+	/**
+	 * Path of the file containing the project's classpath relative to the project's root.
+	 * 
+	 * <p>The file is a child of the project folder.</p>
+	 * <p>The format of this file is unspecified and it is not meant to be modified.
+	 * Its contents is modified by using the <code>IJavaProject#setRawClasspath(..)</code> methods.</p>
+	 * 
+	 * @see #setRawClasspath(IClasspathEntry[], IProgressMonitor)
+	 * @see #setRawClasspath(IClasspathEntry[], boolean, IProgressMonitor)
+	 * @see #setRawClasspath(IClasspathEntry[], IPath, IProgressMonitor)
+	 * @see #setRawClasspath(IClasspathEntry[], IClasspathEntry[], IPath, IProgressMonitor)
+	 * @see #setRawClasspath(IClasspathEntry[], IPath, boolean, IProgressMonitor)
+	 * @since 3.7
+	 */
+	String CLASSPATH_FILE_NAME = ".classpath"; //$NON-NLS-1$
+
+	/**
+	 * Decodes the classpath entry that has been encoded in the given string
+	 * in the context of this project.
+	 * Returns null if the encoded entry is malformed.
+	 *
+	 * @param encodedEntry the encoded classpath entry
+	 * @return the decoded classpath entry, or <code>null</code> if unable to decode it
+	 * @since 3.2
+	 */
+	IClasspathEntry decodeClasspathEntry(String encodedEntry);
+
+	/**
+	 * Encodes the given classpath entry into a string in the context of this project.
+	 *
+	 * @param classpathEntry the classpath entry to encode
+	 * @return the encoded classpath entry
+	 * @since 3.2
+	 */
+	String encodeClasspathEntry(IClasspathEntry classpathEntry);
+
+	/**
+	 * Returns the <code>IJavaElement</code> corresponding to the given
+	 * classpath-relative path, or <code>null</code> if no such
+	 * <code>IJavaElement</code> is found. The result is one of an
+	 * <code>ICompilationUnit</code>, <code>IClassFile</code>, or
+	 * <code>IPackageFragment</code>.
+	 * <p>
+	 * When looking for a package fragment, there might be several potential
+	 * matches; only one of them is returned.
+	 *
+	 * <p>For example, the path "java/lang/Object.java", would result in the
+	 * <code>ICompilationUnit</code> or <code>IClassFile</code> corresponding to
+	 * "java.lang.Object". The path "java/lang" would result in the
+	 * <code>IPackageFragment</code> for "java.lang".
+	 * @param path the given classpath-relative path
+	 * @exception JavaModelException if the given path is <code>null</code>
+	 *  or absolute
+	 * @return the <code>IJavaElement</code> corresponding to the given
+	 * classpath-relative path, or <code>null</code> if no such
+	 * <code>IJavaElement</code> is found
+	 */
+	IJavaElement findElement(IPath path) throws JavaModelException;
+
+	/**
+	 * Returns the <code>IJavaElement</code> corresponding to the given
+	 * classpath-relative path, or <code>null</code> if no such
+	 * <code>IJavaElement</code> is found. The result is one of an
+	 * <code>ICompilationUnit</code>, <code>IClassFile</code>, or
+	 * <code>IPackageFragment</code>. If it is an <code>ICompilationUnit</code>,
+	 * its owner is the given owner.
+	 * <p>
+	 * When looking for a package fragment, there might be several potential
+	 * matches; only one of them is returned.
+	 *
+	 * <p>For example, the path "java/lang/Object.java", would result in the
+	 * <code>ICompilationUnit</code> or <code>IClassFile</code> corresponding to
+	 * "java.lang.Object". The path "java/lang" would result in the
+	 * <code>IPackageFragment</code> for "java.lang".
+	 * @param path the given classpath-relative path
+	 * @param owner the owner of the returned compilation unit, ignored if it is
+	 *   not a compilation unit.
+	 * @exception JavaModelException if the given path is <code>null</code>
+	 *  or absolute
+	 * @return the <code>IJavaElement</code> corresponding to the given
+	 * classpath-relative path, or <code>null</code> if no such
+	 * <code>IJavaElement</code> is found
+	 * @since 3.0
+	 */
+	IJavaElement findElement(IPath path, WorkingCopyOwner owner) throws JavaModelException;
+
+	/**
+	 * Finds the Java element corresponding to the given binding key if any,
+	 * else returns <code>null</code>. Elements are looked up using this
+	 * project's classpath. The first element corresponding to
+	 * the given key on this project's classpath is returned.
+	 * <p>Possible elements are:
+	 * <ul>
+	 * <li>{@link IPackageFragment} for a binding key from an
+	 * 		{@link IPackageBinding}</li>
+	 * <li>{@link IType} for a binding key from an {@link ITypeBinding}</li>
+	 * <li>{@link IMethod} for a binding key from an {@link IMethodBinding}</li>
+	 * <li>{@link IField} for a binding key from an {@link IVariableBinding}
+	 * 		representing a {@link IVariableBinding#isField() field}</li>
+	 * <li>{@link ITypeParameter} for a binding key from an {@link ITypeBinding}
+	 * 		representing a {@link ITypeBinding#isTypeVariable() type
+	 * 		variable}</li>
+	 * <li>{@link IAnnotation} for a binding key from an
+	 * 		{@link IAnnotationBinding}</li>
+	 * </ul></p>
+	 * <p>Note: if two methods correspond to the binding key because their
+	 * parameter types' simple names are the same, then the first one is returned.
+	 * For example, if a class defines two methods <code>foo(p1.Y, String)</code>
+	 * and <code>foo(p2.Y, String)</code>, in both cases the parameter type's
+	 * simple names  are <code>{"Y", "String"}</code>. Thus
+	 * <code>foo(p1.Y, String)</code> is returned.</p>
+	 *
+	 * @param bindingKey the given binding key
+	 * @param owner the owner of the returned element's compilation unit,
+	 * 		or <code>null</code> if the default working copy owner must be
+	 * 		used
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the Java element corresponding to the given key,
+	 * 		or <code>null</code> if no such Java element is found
+	 * @since 3.4
+	 */
+	IJavaElement findElement(String bindingKey, WorkingCopyOwner owner) throws JavaModelException;
+
+	/**
+	 * Returns the first existing package fragment on this project's classpath
+	 * whose path matches the given (absolute) path, or <code>null</code> if none
+	 * exist.
+	 * The path can be:
+	 * 	- internal to the workbench: "/Project/src"
+	 *  - external to the workbench: "c:/jdk/classes.zip/java/lang"
+	 * @param path the given absolute path
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first existing package fragment on this project's classpath
+	 * whose path matches the given (absolute) path, or <code>null</code> if none
+	 * exist
+	 */
+	IPackageFragment findPackageFragment(IPath path) throws JavaModelException;
+
+	/**
+	 * Returns the existing package fragment root on this project's classpath
+	 * whose path matches the given (absolute) path, or <code>null</code> if
+	 * one does not exist.
+	 * The path can be:
+	 *	- internal to the workbench: "/Compiler/src"
+	 *	- external to the workbench: "c:/jdk/classes.zip"
+	 * @param path the given absolute path
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the existing package fragment root on this project's classpath
+	 * whose path matches the given (absolute) path, or <code>null</code> if
+	 * one does not exist
+	 */
+	IPackageFragmentRoot findPackageFragmentRoot(IPath path)
+		throws JavaModelException;
+	/**
+	 * Returns the existing package fragment roots identified by the given entry.
+	 * A classpath entry within the current project identifies a single root.
+	 * <p>
+	 * If the classpath entry denotes a variable, it will be resolved and return
+	 * the roots of the target entry (empty if not resolvable).
+	 * <p>
+	 * If the classpath entry denotes a container, it will be resolved and return
+	 * the roots corresponding to the set of container entries (empty if not resolvable).
+	 * <p>
+	 * The result does not include package fragment roots in other projects
+	 * referenced on this project's classpath.
+	 * 
+	 * @param entry the given entry
+	 * @return the existing package fragment roots identified by the given entry
+	 * @see IClasspathContainer
+	 * @since 2.1
+	 */
+	IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry);
+	/**
+	 * Returns the first type (excluding secondary types) found following this project's
+	 * classpath with the given fully qualified name or <code>null</code> if none is found.
+	 * The fully qualified name is a dot-separated name. For example,
+	 * a class B defined as a member type of a class A in package x.y should have a
+	 * the fully qualified name "x.y.A.B".
+	 *
+	 * Note that in order to be found, a type name (or its top level enclosing
+	 * type name) must match its corresponding compilation unit name. As a
+	 * consequence, secondary types cannot be found using this functionality.
+	 * To find secondary types use {@link #findType(String, IProgressMonitor)} instead.
+	 *
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 2.0
+	 */
+	IType findType(String fullyQualifiedName) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String)} but also looks for secondary
+	 * types if the given name does not match a compilation unit name.
+	 *
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Returns the first type (excluding secondary types) found following this project's
+	 * classpath with the given fully qualified name or <code>null</code> if none is found.
+	 * The fully qualified name is a dot-separated name. For example,
+	 * a class B defined as a member type of a class A in package x.y should have a
+	 * the fully qualified name "x.y.A.B".
+	 * If the returned type is part of a compilation unit, its owner is the given
+	 * owner.
+	 *
+	 * Note that in order to be found, a type name (or its top level enclosing
+	 * type name) must match its corresponding compilation unit name. As a
+	 * consequence, secondary types cannot be found using this functionality.
+	 * To find secondary types use {@link #findType(String, WorkingCopyOwner, IProgressMonitor)}
+	 * instead.
+	 *
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.0
+	 */
+	IType findType(String fullyQualifiedName, WorkingCopyOwner owner) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, WorkingCopyOwner)}
+	 * but also looks for secondary types if the given name does not match
+	 * a compilation unit name.
+	 *
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String fullyQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Returns the first type (excluding secondary types) found following this
+	 * project's classpath with the given package name and type qualified name
+	 * or <code>null</code> if none is found.
+	 * The package name is a dot-separated name.
+	 * The type qualified name is also a dot-separated name. For example,
+	 * a class B defined as a member type of a class A should have the
+	 * type qualified name "A.B".
+	 *
+	 * Note that in order to be found, a type name (or its top level enclosing
+	 * type name) must match its corresponding compilation unit name. As a
+	 * consequence, secondary types cannot be found using this functionality.
+	 * To find secondary types use {@link #findType(String, String, IProgressMonitor)}
+	 * instead.
+	 *
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given package name and type qualified name
+	 * or <code>null</code> if none is found
+	 * @see IType#getTypeQualifiedName(char)
+	 * @since 2.0
+	 */
+	IType findType(String packageName, String typeQualifiedName) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, String)} but also looks for
+	 * secondary types if the given name does not match a compilation unit name.
+	 *
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String packageName, String typeQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Returns the first type (excluding secondary types) found following this
+	 * project's classpath with the given package name and type qualified name
+	 * or <code>null</code> if none is found.
+	 * The package name is a dot-separated name.
+	 * The type qualified name is also a dot-separated name. For example,
+	 * a class B defined as a member type of a class A should have the
+	 * type qualified name "A.B".
+	 * If the returned type is part of a compilation unit, its owner is the given
+	 * owner.
+	 *
+	 * Note that in order to be found, a type name (or its top level enclosing
+	 * type name) must match its corresponding compilation unit name. As a
+	 * consequence, secondary types cannot be found using this functionality.
+	 * To find secondary types use {@link #findType(String, String, WorkingCopyOwner, IProgressMonitor)}
+	 * instead.
+	 *
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given package name and type qualified name
+	 * or <code>null</code> if none is found
+	 * @see IType#getTypeQualifiedName(char)
+	 * @since 3.0
+	 */
+	IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, String, WorkingCopyOwner)}
+	 * but also looks for secondary types if the given name does not match a compilation unit name.
+	 *
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException;
+
+	/**
+	 * Returns all of the existing package fragment roots that exist
+	 * on the classpath, in the order they are defined by the classpath.
+	 *
+	 * @return all of the existing package fragment roots that exist
+	 * on the classpath
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException;
+
+	/**
+	 * Returns an array of non-Java resources directly contained in this project.
+	 * It does not transitively answer non-Java resources contained in folders;
+	 * these would have to be explicitly iterated over.
+	 * <p>
+	 * Non-Java resources includes other files and folders located in the
+	 * project not accounted for by any of it source or binary package fragment
+	 * roots. If the project is a source folder itself, resources excluded from the
+	 * corresponding source classpath entry by one or more exclusion patterns
+	 * are considered non-Java resources and will appear in the result
+	 * (possibly in a folder)
+	 * </p>
+	 *
+	 * @return an array of non-Java resources (<code>IFile</code>s and/or
+	 *              <code>IFolder</code>s) directly contained in this project
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	Object[] getNonJavaResources() throws JavaModelException;
+
+	/**
+	 * Helper method for returning one option value only. Equivalent to <code>(String)this.getOptions(inheritJavaCoreOptions).get(optionName)</code>
+	 * Note that it may answer <code>null</code> if this option does not exist, or if there is no custom value for it.
+	 * <p>
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * </p>
+	 *
+	 * @param optionName the name of an option
+	 * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+	 * @return the String value of a given option
+	 * @see JavaCore#getDefaultOptions()
+	 * @since 2.1
+	 */
+	String getOption(String optionName, boolean inheritJavaCoreOptions);
+
+	/**
+	 * Returns the table of the current custom options for this project. Projects remember their custom options,
+	 * in other words, only the options different from the the JavaCore global options for the workspace.
+	 * A boolean argument allows to directly merge the project options with global ones from <code>JavaCore</code>.
+	 * <p>
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * </p>
+	 *
+	 * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+	 * @return table of current settings of all options
+	 *   (key type: <code>String</code>; value type: <code>String</code>)
+	 * @see JavaCore#getDefaultOptions()
+	 * @since 2.1
+	 */
+	Map getOptions(boolean inheritJavaCoreOptions);
+
+	/**
+	 * Returns the default output location for this project as a workspace-
+	 * relative absolute path.
+	 * <p>
+	 * The default output location is where class files are ordinarily generated
+	 * (and resource files, copied). Each source classpath entry can also
+	 * specify an output location for the generated class files (and copied
+	 * resource files) corresponding to compilation units under that source
+	 * folder. This makes it possible to arrange generated class files for
+	 * different source folders in different output folders, and not
+	 * necessarily the default output folder. This means that the generated
+	 * class files for the project may end up scattered across several folders,
+	 * rather than all in the default output folder (which is more standard).
+	 * </p>
+	 *
+	 * @return the workspace-relative absolute path of the default output folder
+	 * @exception JavaModelException if this element does not exist
+	 * @see #setOutputLocation(org.eclipse.core.runtime.IPath, IProgressMonitor)
+	 * @see IClasspathEntry#getOutputLocation()
+	 */
+	IPath getOutputLocation() throws JavaModelException;
+
+	/**
+	 * Returns a package fragment root for an external library
+	 * (a ZIP archive - e.g. a <code>.jar</code>, a <code>.zip</code> file, etc. -
+	 * or - since 3.4 - a class folder) at the specified file system path.
+	 * This is a handle-only method.  The underlying <code>java.io.File</code>
+	 * may or may not exist. No resource is associated with this local library
+	 * package fragment root.
+	 *
+	 * @param externalLibraryPath the library's file system path
+	 * @return a package fragment root for the external library at the specified file system path
+	 */
+	IPackageFragmentRoot getPackageFragmentRoot(String externalLibraryPath);
+
+	/**
+	 * Returns a package fragment root for the given resource, which
+	 * must either be a folder representing the top of a package hierarchy,
+	 * or a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.)
+	 * This is a handle-only method.  The underlying resource may or may not exist.
+	 *
+	 * @param resource the given resource
+	 * @return a package fragment root for the given resource, which
+	 * must either be a folder representing the top of a package hierarchy,
+	 * or a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.)
+	 */
+	IPackageFragmentRoot getPackageFragmentRoot(IResource resource);
+
+	/**
+	 * Returns all of the  package fragment roots contained in this
+	 * project, identified on this project's resolved classpath. The result
+	 * does not include package fragment roots in other projects referenced
+	 * on this project's classpath. The package fragment roots appear in the 
+	 * order they are defined by the classpath.
+	 *
+	 * <p>NOTE: This is equivalent to <code>getChildren()</code>.
+	 *
+	 * @return all of the  package fragment roots contained in this
+	 * project, identified on this project's resolved classpath
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException;
+
+	/**
+	 * Returns the existing package fragment roots identified by the given entry.
+	 * A classpath entry within the current project identifies a single root.
+	 * <p>
+	 * If the classpath entry denotes a variable, it will be resolved and return
+	 * the roots of the target entry (empty if not resolvable).
+	 * <p>
+	 * If the classpath entry denotes a container, it will be resolved and return
+	 * the roots corresponding to the set of container entries (empty if not resolvable).
+	 * <p>
+	 * The result does not include package fragment roots in other projects
+	 * referenced on this project's classpath.
+	 * 
+	 * @param entry the given entry
+	 * @return the existing package fragment roots identified by the given entry
+	 * @see IClasspathContainer
+	 * @deprecated Use {@link IJavaProject#findPackageFragmentRoots(IClasspathEntry)} instead
+	 */
+	IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry);
+
+	/**
+	 * Returns all package fragments in all package fragment roots contained
+	 * in this project. This is a convenience method.
+	 *
+	 * Note that the package fragment roots corresponds to the resolved
+	 * classpath of the project.
+	 *
+	 * @return all package fragments in all package fragment roots contained
+	 * in this project
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	IPackageFragment[] getPackageFragments() throws JavaModelException;
+
+	/**
+	 * Returns the <code>IProject</code> on which this <code>IJavaProject</code>
+	 * was created. This is handle-only method.
+	 *
+	 * @return the <code>IProject</code> on which this <code>IJavaProject</code>
+	 * was created
+	 */
+	IProject getProject();
+
+	/**
+	 * Returns the raw classpath for the project, as a list of classpath
+	 * entries. This corresponds to the exact set of entries which were assigned
+	 * using <code>setRawClasspath</code>, in particular such a classpath may
+	 * contain classpath variable and classpath container entries. Classpath
+	 * variable and classpath container entries can be resolved using the
+	 * helper method <code>getResolvedClasspath</code>; classpath variable
+	 * entries also can be resolved individually using
+	 * <code>JavaCore#getClasspathVariable</code>).
+	 * <p>
+	 * Both classpath containers and classpath variables provides a level of
+	 * indirection that can make the <code>.classpath</code> file stable across
+	 * workspaces.
+	 * As an example, classpath variables allow a classpath to no longer refer
+	 * directly to external JARs located in some user specific location.
+	 * The classpath can simply refer to some variables defining the proper
+	 * locations of these external JARs. Similarly, classpath containers
+	 * allows classpath entries to be computed dynamically by the plug-in that
+	 * defines that kind of classpath container.
+	 * </p>
+	 * <p>
+	 * Note that in case the project isn't yet opened, the classpath will
+	 * be read directly from the associated <tt>.classpath</tt> file.
+	 * </p>
+	 *
+	 * @return the raw classpath for the project, as a list of classpath entries
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @see IClasspathEntry
+	 */
+	IClasspathEntry[] getRawClasspath() throws JavaModelException;
+
+	/**
+	 * Returns the names of the projects that are directly required by this
+	 * project. A project is required if it is in its classpath.
+	 * <p>
+	 * The project names are returned in the order they appear on the classpath.
+	 *
+	 * @return the names of the projects that are directly required by this
+	 * project in classpath order
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	String[] getRequiredProjectNames() throws JavaModelException;
+
+	/**
+	 * This is a helper method returning the resolved classpath for the project
+	 * as a list of simple (non-variable, non-container) classpath entries.
+	 * All classpath variable and classpath container entries in the project's
+	 * raw classpath will be replaced by the simple classpath entries they
+	 * resolve to.
+	 * <p>
+	 * The resulting resolved classpath is accurate for the given point in time.
+	 * If the project's raw classpath is later modified, or if classpath
+	 * variables are changed, the resolved classpath can become out of date.
+	 * Because of this, hanging on resolved classpath is not recommended.
+	 * </p>
+	 * <p>
+	 * Note that if the resolution creates duplicate entries 
+	 * (i.e. {@link IClasspathEntry entries} which are {@link Object#equals(Object)}), 
+	 * only the first one is added to the resolved classpath.
+	 * </p>
+	 *
+	 * @param ignoreUnresolvedEntry indicates how to handle unresolvable
+	 * variables and containers; <code>true</code> indicates that missing
+	 * variables and unresolvable classpath containers should be silently
+	 * ignored, and that the resulting list should consist only of the
+	 * entries that could be successfully resolved; <code>false</code> indicates
+	 * that a <code>JavaModelException</code> should be thrown for the first
+	 * unresolved variable or container
+	 * @return the resolved classpath for the project as a list of simple
+	 * classpath entries, where all classpath variable and container entries
+	 * have been resolved and substituted with their final target entries
+	 * @exception JavaModelException in one of the corresponding situation:
+	 * <ul>
+	 *    <li>this element does not exist</li>
+	 *    <li>an exception occurs while accessing its corresponding resource</li>
+	 *    <li>a classpath variable or classpath container was not resolvable
+	 *    and <code>ignoreUnresolvedEntry</code> is <code>false</code>.</li>
+	 * </ul>
+	 * @see IClasspathEntry
+	 */
+	IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
+	     throws JavaModelException;
+
+	/**
+	 * Returns whether this project has been built at least once and thus whether it has a build state.
+	 * @return true if this project has been built at least once, false otherwise
+	 */
+	boolean hasBuildState();
+
+	/**
+	 * Returns whether setting this project's classpath to the given classpath entries
+	 * would result in a cycle.
+	 *
+	 * If the set of entries contains some variables, those are resolved in order to determine
+	 * cycles.
+	 *
+	 * @param entries the given classpath entries
+	 * @return true if the given classpath entries would result in a cycle, false otherwise
+	 */
+	boolean hasClasspathCycle(IClasspathEntry[] entries);
+	/**
+	 * Returns whether the given element is on the classpath of this project,
+	 * that is, referenced from a classpath entry and not explicitly excluded
+	 * using an exclusion pattern.
+	 *
+	 * @param element the given element
+	 * @return <code>true</code> if the given element is on the classpath of
+	 * this project, <code>false</code> otherwise
+	 * @see IClasspathEntry#getInclusionPatterns()
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 * @since 2.0
+	 */
+	boolean isOnClasspath(IJavaElement element);
+	/**
+	 * Returns whether the given resource is on the classpath of this project,
+	 * that is, referenced from a classpath entry and not explicitly excluded
+	 * using an exclusion pattern.
+	 *
+	 * @param resource the given resource
+	 * @return <code>true</code> if the given resource is on the classpath of
+	 * this project, <code>false</code> otherwise
+	 * @see IClasspathEntry#getInclusionPatterns()
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 * @since 2.1
+	 */
+	boolean isOnClasspath(IResource resource);
+
+	/**
+	 * Creates a new evaluation context.
+	 * @return a new evaluation context.
+	 */
+	IEvaluationContext newEvaluationContext();
+
+	/**
+	 * Creates and returns a type hierarchy for all types in the given
+	 * region, considering subtypes within that region.
+	 *
+	 * @param monitor the given progress monitor
+	 * @param region the given region
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @exception IllegalArgumentException if region is <code>null</code>
+	 * @return a type hierarchy for all types in the given
+	 * region, considering subtypes within that region
+	 */
+	ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for all types in the given
+	 * region, considering subtypes within that region and considering types in the
+	 * working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param monitor the given progress monitor
+	 * @param region the given region
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @exception IllegalArgumentException if region is <code>null</code>
+	 * @return a type hierarchy for all types in the given
+	 * region, considering subtypes within that region
+	 * @since 3.0
+	 */
+	ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for the given type considering
+	 * subtypes in the specified region.
+	 *
+	 * @param type the given type
+	 * @param region the given region
+	 * @param monitor the given monitor
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 *
+	 * @exception IllegalArgumentException if type or region is <code>null</code>
+	 * @return a type hierarchy for the given type considering
+	 * subtypes in the specified region
+	 */
+	ITypeHierarchy newTypeHierarchy(
+		IType type,
+		IRegion region,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for the given type considering
+	 * subtypes in the specified region and considering types in the
+	 * working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param type the given type
+	 * @param region the given region
+	 * @param monitor the given monitor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 *
+	 * @exception IllegalArgumentException if type or region is <code>null</code>
+	 * @return a type hierarchy for the given type considering
+	 * subtypes in the specified region
+	 * @since 3.0
+	 */
+	ITypeHierarchy newTypeHierarchy(
+		IType type,
+		IRegion region,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Returns the default output location for the project as defined by its <code>.classpath</code> file from disk, or <code>null</code>
+	 * if unable to read the file.
+	 * <p>
+	 * This output location may differ from the in-memory one returned by <code>getOutputLocation</code>, in case the
+	 * automatic reconciliation mechanism has not been performed yet. Usually, any change to the <code>.classpath</code> file
+	 * is automatically noticed and reconciled at the next resource change notification event.
+	 * However, if the file is modified within an operation, where this change needs to be taken into account before the
+	 * operation ends, then the output location from disk can be read using this method, and further assigned to the project
+	 * using <code>setRawClasspath(...)</code>.
+	 * <p>
+	 * The default output location is where class files are ordinarily generated
+	 * (and resource files, copied). Each source classpath entry can also
+	 * specify an output location for the generated class files (and copied
+	 * resource files) corresponding to compilation units under that source
+	 * folder. This makes it possible to arrange generated class files for
+	 * different source folders in different output folders, and not
+	 * necessarily the default output folder. This means that the generated
+	 * class files for the project may end up scattered across several folders,
+	 * rather than all in the default output folder (which is more standard).
+	 * <p>
+	 * In order to manually force a project classpath refresh, one can simply assign the project classpath using the result of this
+	 * method, as follows:
+	 * <code>proj.setRawClasspath(proj.readRawClasspath(), proj.readOutputLocation(), monitor)</code>
+	 * (note that the <code>readRawClasspath/readOutputLocation</code> methods could return <code>null</code>).
+	 * <p>
+	 * @return the workspace-relative absolute path of the default output folder
+	 * @see #getOutputLocation()
+	 * @since 3.0
+	 */
+	IPath readOutputLocation();
+
+	/**
+	 * Returns the raw classpath for the project as defined by its
+	 * <code>.classpath</code> file from disk, or <code>null</code>
+	 * if unable to read the file.
+	 * <p>
+	 * This classpath may differ from the in-memory classpath returned by
+	 * <code>getRawClasspath</code>, in case the automatic reconciliation
+	 * mechanism has not been performed yet. Usually, any change to the
+	 * <code>.classpath</code> file is automatically noticed and reconciled at
+	 * the next resource change notification event. However, if the file is
+	 * modified within an operation, where this change needs to be taken into
+	 * account before the operation ends, then the classpath from disk can be
+	 * read using this method, and further assigned to the project using
+	 * <code>setRawClasspath(...)</code>.
+	 * </p>
+	 * <p>
+	 * Classpath variable and classpath container entries can be resolved using
+	 * the helper method <code>getResolvedClasspath</code>; classpath variable
+	 * entries also can be resolved individually using
+	 * <code>JavaCore#getClasspathVariable</code>).
+	 * </p>
+	 * <p>
+	 * Note that no check is performed whether the project has the Java nature
+	 * set, allowing an existing <code>.classpath</code> file to be considered
+	 * independantly (unlike <code>getRawClasspath</code> which requires the
+	 * Java nature to be associated with the project).
+	 * </p>
+	 * <p>
+	 * In order to manually force a project classpath refresh, one can simply
+	 * assign the project classpath using the result of this method, as follows:
+	 * <code>proj.setRawClasspath(proj.readRawClasspath(), proj.readOutputLocation(), monitor)</code>
+	 * (note that the <code>readRawClasspath/readOutputLocation</code> methods
+	 * could return <code>null</code>).
+	 * </p>
+	 *
+	 * @return the raw classpath from disk for the project, as a list of
+	 * classpath entries
+	 * @see #getRawClasspath()
+	 * @see IClasspathEntry
+	 * @since 3.0
+	 */
+	IClasspathEntry[] readRawClasspath();
+
+	/**
+	 * Helper method for setting one option value only.
+	 *<p>
+	 * Equivalent to:
+	 * <pre>
+	 * 	Map options = this.getOptions(false);
+	 * 	map.put(optionName, optionValue);
+	 * 	this.setOptions(map)
+	 *  </pre>
+	 * <p>
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * </p>
+	 *
+	 * @param optionName the name of an option
+	 * @param optionValue the value of the option to set. If <code>null</code>, then the option
+	 * 	is removed from project preferences.
+	 * @throws NullPointerException if <code>optionName</code> is <code>null</code>
+	 * 	(see {@link org.osgi.service.prefs.Preferences#put(String, String)}).
+	 * @see JavaCore#getDefaultOptions()
+	 * @since 3.0
+	 */
+	void setOption(String optionName, String optionValue);
+
+	/**
+	 * Sets the project custom options. All and only the options explicitly included in the given table
+	 * are remembered; all previous option settings are forgotten, including ones not explicitly
+	 * mentioned.
+	 * <p>
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * </p>
+	 *
+	 * @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
+	 *   or <code>null</code> to flush all custom options (clients will automatically get the global JavaCore options).
+	 * @see JavaCore#getDefaultOptions()
+	 * @since 2.1
+	 */
+	void setOptions(Map newOptions);
+
+	/**
+	 * Sets the default output location of this project to the location
+	 * described by the given workspace-relative absolute path.
+	 * <p>
+	 * The default output location is where class files are ordinarily generated
+	 * (and resource files, copied). Each source classpath entries can also
+	 * specify an output location for the generated class files (and copied
+	 * resource files) corresponding to compilation units under that source
+	 * folder. This makes it possible to arrange that generated class files for
+	 * different source folders to end up in different output folders, and not
+	 * necessarily the default output folder. This means that the generated
+	 * class files for the project may end up scattered across several folders,
+	 * rather than all in the default output folder (which is more standard).
+	 * </p>
+	 *
+	 * @param path the workspace-relative absolute path of the default output
+	 * folder
+	 * @param monitor the progress monitor
+	 *
+	 * @exception JavaModelException if the classpath could not be set. Reasons include:
+	 * <ul>
+	 *  <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *  <li> The path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+	 *  <li> The path is not an absolute path (<code>RELATIVE_PATH</code>)
+	 *  <li> The path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+	 *  <li> The output location is being modified during resource change event notification (CORE_EXCEPTION)
+	 * </ul>
+	 * @see #getOutputLocation()
+     * @see IClasspathEntry#getOutputLocation()
+	 */
+	void setOutputLocation(IPath path, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Sets both the classpath of this project and its default output
+	 * location at once. The classpath is defined using a list of classpath
+	 * entries. In particular such a classpath may contain classpath variable entries.
+	 * Classpath variable entries can be resolved individually ({@link JavaCore#getClasspathVariable(String)}),
+	 * or the full classpath can be resolved at once using the helper method {@link #getResolvedClasspath(boolean)}.
+	 * <p>
+	 * A classpath variable provides an indirection level for better sharing a classpath. As an example, it allows
+	 * a classpath to no longer refer directly to external JARs located in some user specific location. The classpath
+	 * can simply refer to some variables defining the proper locations of these external JARs.
+	 * </p><p>
+	 * If it is specified that this operation cannot modify resources, the .classpath file will not be written to disk
+	 * and no error marker will be generated. To synchronize the .classpath with the in-memory classpath,
+	 * one can use <code>setRawClasspath(readRawClasspath(), true, monitor)</code>.
+	 * </p><p>
+	 * Setting the classpath to <code>null</code> specifies a default classpath
+	 * (the project root). Setting the classpath to an empty array specifies an
+	 * empty classpath.
+	 * </p><p>
+	 * If a cycle is detected while setting this classpath (and if resources can be modified), an error marker will be added
+	 * to the project closing the cycle.
+	 * To avoid this problem, use {@link #hasClasspathCycle(IClasspathEntry[])}
+	 * before setting the classpath.
+	 * <p>
+	 * This operation acquires a lock on the workspace's root.
+	 *
+	 * @param entries a list of classpath entries
+	 * @param outputLocation the default output location
+	 * @param canModifyResources whether resources should be written to disk if needed
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the classpath could not be set. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+	 * <li> The classpath failed the validation check as defined by {@link JavaConventions#validateClasspath(IJavaProject, IClasspathEntry[], IPath)}
+	 * </ul>
+	 * @see IClasspathEntry
+	 * @since 3.2
+	 */
+	void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, boolean canModifyResources, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Sets the classpath of this project using a list of classpath entries. In particular such a classpath may contain
+	 * classpath variable entries. Classpath variable entries can be resolved individually ({@link JavaCore#getClasspathVariable(String)}),
+	 * or the full classpath can be resolved at once using the helper method {@link #getResolvedClasspath(boolean)}.
+	 * <p>
+	 * A classpath variable provides an indirection level for better sharing a classpath. As an example, it allows
+	 * a classpath to no longer refer directly to external JARs located in some user specific location. The classpath
+	 * can simply refer to some variables defining the proper locations of these external JARs.
+	 * </p><p>
+	 * If it is specified that this operation cannot modify resources, the .classpath file will not be written to disk
+	 * and no error marker will be generated. To synchronize the .classpath with the in-memory classpath,
+	 * one can use <code>setRawClasspath(readRawClasspath(), true, monitor)</code>.
+	 * </p><p>
+	 * Setting the classpath to <code>null</code> specifies a default classpath
+	 * (the project root). Setting the classpath to an empty array specifies an
+	 * empty classpath.
+	 * </p><p>
+	 * If a cycle is detected while setting this classpath (and if resources can be modified), an error marker will be added
+	 * to the project closing the cycle.
+	 * To avoid this problem, use {@link #hasClasspathCycle(IClasspathEntry[])}
+	 * before setting the classpath.
+	 * <p>
+	 * This operation acquires a lock on the workspace's root.
+	 *
+	 * @param entries a list of classpath entries
+	 * @param canModifyResources whether resources should be written to disk if needed
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the classpath could not be set. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+	 * <li> The classpath failed the validation check as defined by {@link JavaConventions#validateClasspath(IJavaProject, IClasspathEntry[], IPath)}
+	 * </ul>
+	 * @see IClasspathEntry
+	 * @since 3.2
+	 */
+	void setRawClasspath(IClasspathEntry[] entries, boolean canModifyResources, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * 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()}.
+	 * <p>
+	 * 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. 
+	 * </p> <p>
+	 * 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.
+	 *</p>
+	 * @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:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+	 * <li> The classpath failed the validation check as defined by {@link JavaConventions#validateClasspath(IJavaProject, IClasspathEntry[], IPath)}
+	 * </ul>
+	 * @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;
+	
+	/**
+	 * Sets the classpath of this project using a list of classpath entries. In particular such a classpath may contain
+	 * classpath variable entries. Classpath variable entries can be resolved individually ({@link JavaCore#getClasspathVariable(String)}),
+	 * or the full classpath can be resolved at once using the helper method {@link #getResolvedClasspath(boolean)}.
+	 * <p>
+	 * A classpath variable provides an indirection level for better sharing a classpath. As an example, it allows
+	 * a classpath to no longer refer directly to external JARs located in some user specific location. The classpath
+	 * can simply refer to some variables defining the proper locations of these external JARs.
+	 * <p>
+	 * Setting the classpath to <code>null</code> specifies a default classpath
+	 * (the project root). Setting the classpath to an empty array specifies an
+	 * empty classpath.
+	 * <p>
+	 * If a cycle is detected while setting this classpath, an error marker will be added
+	 * to the project closing the cycle.
+	 * To avoid this problem, use {@link #hasClasspathCycle(IClasspathEntry[])}
+	 * before setting the classpath.
+	 * <p>
+	 * This operation acquires a lock on the workspace's root.
+	 *
+	 * @param entries a list of classpath entries
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the classpath could not be set. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+	 * <li> The classpath failed the validation check as defined by {@link JavaConventions#validateClasspath(IJavaProject, IClasspathEntry[], IPath)}
+	 * </ul>
+	 * @see IClasspathEntry
+	 */
+	void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Sets the both the classpath of this project and its default output
+	 * location at once. The classpath is defined using a list of classpath
+	 * entries. In particular, such a classpath may contain classpath variable
+	 * entries. Classpath variable entries can be resolved individually (see
+	 * ({@link JavaCore#getClasspathVariable(String)}), or the full classpath can be
+	 * resolved at once using the helper method
+	 * {@link #getResolvedClasspath(boolean)}.
+	 * <p>
+	 * A classpath variable provides an indirection level for better sharing a
+	 * classpath. As an example, it allows a classpath to no longer refer
+	 * directly to external JARs located in some user specific location. The
+	 * classpath can simply refer to some variables defining the proper
+	 * locations of these external JARs.
+	 * </p>
+	 * <p>
+	 * Setting the classpath to <code>null</code> specifies a default classpath
+	 * (the project root). Setting the classpath to an empty array specifies an
+	 * empty classpath.
+	 * </p>
+	 * <p>
+	 * If a cycle is detected while setting this classpath, an error marker will
+	 * be added to the project closing the cycle. To avoid this problem, use
+	 * {@link #hasClasspathCycle(IClasspathEntry[])} before setting
+	 * the classpath.
+	 * </p>
+	 * <p>
+	 * This operation acquires a lock on the workspace's root.
+	 * </p>
+	 *
+	 * @param entries a list of classpath entries
+	 * @param monitor the progress monitor
+	 * @param outputLocation the default output location
+	 * @exception JavaModelException if the classpath could not be set. Reasons
+	 * include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
+	 * <li> A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
+	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 *	<li>The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+	 *	<li>The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
+	 *  <li>The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+	 * <li> The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+	 * </ul>
+	 * @see IClasspathEntry
+	 * @since 2.0
+	 */
+	void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, IProgressMonitor monitor)
+		throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java
new file mode 100644
index 0000000..eb47351
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents a local variable declared in a method or an initializer.
+ * <code>ILocalVariable</code> are pseudo-elements created as the result of a <code>ICodeAssist.codeSelect(...)</code>
+ * operation. They are not part of the Java model (<code>exists()</code> returns whether the parent exists rather than
+ * whether the local variable exists in the parent) and they are not included in the children of an <code>IMethod</code>
+ * or an <code>IInitializer</code>.
+ * <p>
+ * In particular such a pseudo-element should not be used as a handle. For example its name range won't be updated
+ * if the underlying source changes.
+ * </p>
+ *
+ * @since 3.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ILocalVariable extends IJavaElement, ISourceReference, IAnnotatable {
+
+	/**
+	 * Returns the name of this local variable.
+	 *
+	 * @return the name of this local variable.
+	 */
+	String getElementName();
+
+	/**
+	 * Returns the source range of this local variable's name.
+	 *
+	 * @return the source range of this local variable's name
+	 */
+	ISourceRange getNameRange();
+
+	/**
+	 * Returns the type signature of this local variable.
+	 * <p>
+	 * The type signature may be either unresolved (for source types)
+	 * or resolved (for binary types), and either basic (for basic types)
+	 * or rich (for parameterized types). See {@link Signature} for details.
+	 * </p>
+	 *
+	 * @return the type signature of this local variable.
+	 * @see Signature
+	 */
+	String getTypeSignature();
+	
+	/**
+	 * Returns <code>true</code> if this local variable is a method parameter, <code>false</code> otherwise.
+	 * 
+	 * @return <code>true</code> if this local variable is a method parameter, <code>false</code> otherwise
+	 * @since 3.7
+	 */
+	boolean isParameter();
+
+	/**
+	 * Returns the modifier flags for this local variable. The flags can be examined using class
+	 * {@link Flags}.
+	 * 
+	 * <p>Note that only flags as indicated in the source are returned.</p>
+	 *
+	 * @return the modifier flags for this local variable
+	 * @see Flags
+	 * @since 3.7
+	 */
+	int getFlags();
+
+	/**
+	 * Returns the declaring member of this local variable.
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return the declaring member of this local variable
+	 * @since 3.7
+	 */
+	IMember getDeclaringMember();
+
+	/**
+	 * Returns the Java type root in which this local variable is declared.
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return the Java type root in which this local variable is declared
+	 * @since 3.7
+	 */
+	ITypeRoot getTypeRoot();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java
new file mode 100644
index 0000000..072ff6e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Common protocol for Java elements that can be members of types.
+ * This set consists of <code>IType</code>, <code>IMethod</code>,
+ * <code>IField</code>, and <code>IInitializer</code>.
+ * <p>
+ * The children are listed in the order in which they appear in the source or class file.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMember extends IJavaElement, ISourceReference, ISourceManipulation, IParent {
+/**
+ * Returns the categories defined by this member's Javadoc. A category is the identifier
+ * following the tag <code>@category</code> in the member's Javadoc.
+ * Returns an empty array if no category is defined in this member's Javadoc.
+ *
+ * @return the categories defined by this member's doc
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ *  @since 3.2
+ */
+String[] getCategories() throws JavaModelException;
+/**
+ * Returns the class file in which this member is declared, or <code>null</code>
+ * if this member is not declared in a class file (for example, a source type).
+ * This is a handle-only method.
+ *
+ * @return the class file in which this member is declared, or <code>null</code>
+ * if this member is not declared in a class file (for example, a source type)
+ */
+IClassFile getClassFile();
+/**
+ * Returns the compilation unit in which this member is declared, or <code>null</code>
+ * if this member is not declared in a compilation unit (for example, a binary type).
+ * This is a handle-only method.
+ *
+ * @return the compilation unit in which this member is declared, or <code>null</code>
+ * if this member is not declared in a compilation unit (for example, a binary type)
+ */
+ICompilationUnit getCompilationUnit();
+/**
+ * Returns the type in which this member is declared, or <code>null</code>
+ * if this member is not declared in a type (for example, a top-level type).
+ * This is a handle-only method.
+ *
+ * @return the type in which this member is declared, or <code>null</code>
+ * if this member is not declared in a type (for example, a top-level type)
+ */
+IType getDeclaringType();
+/**
+ * Returns the modifier flags for this member. The flags can be examined using class
+ * <code>Flags</code>.
+ * <p>
+ * For {@linkplain #isBinary() binary} members, flags from the class file
+ * as well as derived flags {@link Flags#AccAnnotationDefault} and {@link Flags#AccDefaultMethod} are included.
+ * </p>
+ * <p>
+ * For source members, only flags as indicated in the source are returned. Thus if an interface
+ * defines a method <code>void myMethod();</code>, the flags don't include the
+ * 'public' flag. Source flags include {@link Flags#AccAnnotationDefault} as well.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the modifier flags for this member
+ * @see Flags
+ */
+int getFlags() throws JavaModelException;
+/**
+ * Returns the Javadoc range if this element is from source or if this element
+ * is a binary element with an attached source, null otherwise.
+ *
+ * <p>If this element is from source, the javadoc range is
+ * extracted from the corresponding source.</p>
+ * <p>If this element is from a binary, the javadoc is extracted from the
+ * attached source if present.</p>
+ * <p>If this element's openable is not consistent, then null is returned.</p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return a source range corresponding to the javadoc source or <code>null</code>
+ * if no source is available, this element has no javadoc comment or
+ * this element's openable is not consistent
+ * @see IOpenable#isConsistent()
+ * @since 3.2
+ */
+ISourceRange getJavadocRange() throws JavaModelException;
+/**
+ * Returns the position relative to the order this member is defined in the source.
+ * Numbering starts at 1 (thus the first occurrence is occurrence 1, not occurrence 0).
+ * <p>
+ * Two members m1 and m2 that are equal (e.g. 2 fields with the same name in
+ * the same type) can be distinguished using their occurrence counts. If member
+ * m1 appears first in the source, it will have an occurrence count of 1. If member
+ * m2 appears right after member m1, it will have an occurrence count of 2.
+ * </p><p>
+ * The occurrence count can be used to distinguish initializers inside a type
+ * or anonymous types inside a method.
+ * </p><p>
+ * This is a handle-only method.  The member may or may not be present.
+ * </p>
+ *
+ * @return the position relative to the order this member is defined in the source
+ * @since 3.2
+ */
+int getOccurrenceCount();
+/**
+ * Returns the Java type root in which this member is declared.
+ * This is a handle-only method.
+ *
+ * @return the Java type root in which this member is declared.
+ * @since 3.3
+ */
+ITypeRoot getTypeRoot();
+/**
+ * Returns the local or anonymous type declared in this source member with the given simple name and/or
+ * with the specified position relative to the order they are defined in the source.
+ * The name is empty if it is an anonymous type.
+ * Numbering starts at 1 (thus the first occurrence is occurrence 1, not occurrence 0).
+ * This is a handle-only method. The type may or may not exist.
+ * Throws a <code>RuntimeException</code> if this member is not a source member.
+ *
+ * @param name the given simple name
+ * @param occurrenceCount the specified position
+ * @return the type with the given name and/or with the specified position relative to the order they are defined in the source
+ * @since 3.0
+ */
+IType getType(String name, int occurrenceCount);
+/**
+ * Returns whether this member is from a class file.
+ * This is a handle-only method.
+ *
+ * @return <code>true</code> if from a class file, and <code>false</code> if
+ *   from a compilation unit
+ */
+boolean isBinary();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMemberValuePair.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMemberValuePair.java
new file mode 100644
index 0000000..89167b8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMemberValuePair.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents a member-value pair of an annotation.
+ * The {@link #getValue() value} is represented by an {@link Object}. To get the exact
+ * type of this object, use its {@link #getValueKind() value kind}. If this value is an array,
+ * {@link #getValue()} returns an instance of {@link Object}[] and the value kind returns
+ * the kind of the elements in this array.
+ * <p>
+ * This interface is not intended to be implemented or extended by clients.
+ * </p>
+ *
+ * @since 3.4
+ */
+public interface IMemberValuePair {
+	/**
+	 * Constant indicating that the value kind is an <code>int</code> represented by
+	 * an instance of {@link Integer}.
+	 */
+	int K_INT = 1;
+
+	/**
+	 * Constant indicating that the value kind is a <code>byte</code> represented by
+	 * an instance of {@link Byte}.
+	 */
+	int K_BYTE = 2;
+
+	/**
+	 * Constant indicating that the value kind is a <code>short</code> represented by
+	 * an instance of {@link Short}.
+	 */
+	int K_SHORT = 3;
+
+	/**
+	 * Constant indicating that the value kind is a <code>char</code> represented by
+	 * an instance of {@link Character}.
+	 */
+	int K_CHAR = 4;
+
+	/**
+	 * Constant indicating that the value kind is a <code>float</code> represented by
+	 * an instance of {@link Float}.
+	 */
+	int K_FLOAT = 5;
+
+	/**
+	 * Constant indicating that the value kind is a <code>double</code> represented by
+	 * an instance of {@link Double}.
+	 */
+	int K_DOUBLE = 6;
+
+	/**
+	 * Constant indicating that the value kind is a <code>long</code> represented by
+	 * an instance of {@link Long}.
+	 */
+	int K_LONG = 7;
+
+	/**
+	 * Constant indicating that the value kind is a <code>boolean</code> represented by
+	 * an instance of {@link Boolean}.
+	 */
+	int K_BOOLEAN = 8;
+
+	/**
+	 * Constant indicating that the value kind is a {@link String} represented by
+	 * the corresponding {@link String}.
+	 */
+	int K_STRING = 9;
+
+	/**
+	 * Constant indicating that the value kind is an annotation represented by
+	 * an instance of {@link IAnnotation}.
+	 */
+	int K_ANNOTATION = 10;
+
+	/**
+	 * Constant indicating that the value kind is a {@link Class} represented by
+	 * the name of the class (i.e. a {@link String}. If the member-value pair is coming from
+	 * a compilation unit, this is either a simple name (e.g. for <code>MyType.class</code>,
+	 * the name is "MyType"), or a qualified name  (e.g. for <code>x.y.MyType.MyNestedType.class</code>,
+	 * the name is "x.y.MyType.MyNestedType"). If the member-value pair is coming from a class file, this is
+	 * always a fully qualified name.
+	 * <p>
+	 * Note that one can use {@link IType#resolveType(String)} and e.g.
+	 * {@link IJavaProject#findType(String, String, org.eclipse.core.runtime.IProgressMonitor)}
+	 * to find the corresponding {@link IType}.
+	 * </p>
+	 */
+	int K_CLASS = 11;
+
+	/**
+	 * Constant indicating that the value is a qualified name represented by a
+	 * {@link String}. The qualified name refers to an enum constant or another
+	 * compile-time constant if the code is correct (e.g. "MyEnum.FIRST").
+	 */
+	int K_QUALIFIED_NAME = 12;
+
+	/**
+	 * Constant indicating that the value is a simple name represented by a
+	 * {@link String}. The simple name refers to an enum constant or another
+	 * compile-time constant if the code is correct (e.g. "FIRST" when there is
+	 * a static import for "MyEnum.FIRST").
+	 */
+	int K_SIMPLE_NAME = 13;
+
+	/**
+	 * Constant indicating that the value kind is unknown at this stage. The value is unknown in the
+	 * following cases:
+	 * <ul>
+	 * <li>the value is an expression that would need to be further analyzed to determine its kind. For
+	 * example, in <code>@MyAnnot(1 + 2.3)</code> the kind of the expression "1 + 2.3" is
+	 * unknown</li>
+	 * <li>the value is an array of size 0, e.g. <code>@MyAnnot({})</code></li>
+	 * <li>the value is an array that contains at least one expression that would need to be further
+	 *      analyzed to determine its kind. For example, in <code>@MyAnnot({3.4, 1 + 2.3})</code>,
+	 *      the kind of the second element "1 + 2.3" is unknown.</li>
+	 * <li>the value is an array that contains heterogeneous values, e.g.
+	 *      <code>@MyAnnot({1, 2.3, "abc"})</code></li>
+	 * </ul>
+	 * If the value kind is unknown, the returned value is always either <code>null</code>, or an
+	 * array containing {@link Object}s and/or <code>null</code>s for unknown elements.
+	 */
+	int K_UNKNOWN = 14;
+
+	/**
+	 * Returns the member's name of this member-value pair.
+	 *
+	 * @return the member's name of this member-value pair.
+	 */
+	String getMemberName();
+
+	/**
+	 * Returns the value of this member-value pair. The type of this value
+	 * is function of this member-value pair's {@link #getValueKind() value kind}. It is an
+	 * instance of {@link Object}[] if the value is an array.
+	 * <p>
+	 * If the value kind is {@link #K_UNKNOWN} and the value is not an array, then the
+	 * value is <code>null</code>.
+	 * If the value kind is {@link #K_UNKNOWN} and the value is an array, then the
+	 * value is an array containing {@link Object}s and/or <code>null</code>s for
+	 * unknown elements.
+	 * See {@link #K_UNKNOWN} for more details.
+	 * </p>
+	 * @return the value of this member-value pair.
+	 */
+	Object getValue();
+
+	/**
+	 * Returns the value kind of this member-value pair. This indicates the instance of
+	 * the returned {@link #getValue() value}, or the instance of the elements if the value
+	 * is an array. The value kind is one of the following constants:
+	 * {@link #K_ANNOTATION}, {@link #K_BOOLEAN}, {@link #K_BYTE}, {@link #K_CHAR},
+	 * {@link #K_CLASS}, {@link #K_DOUBLE}, {@link #K_FLOAT}, {@link #K_INT}, {@link #K_LONG},
+	 * {@link #K_QUALIFIED_NAME}, {@link #K_SIMPLE_NAME}, {@link #K_SHORT}, {@link #K_STRING},
+	 * {@link #K_UNKNOWN}.
+	 *
+	 * @return the value kind of this member-value pair
+	 */
+	int getValueKind();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
new file mode 100644
index 0000000..fb46973
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Represents a method (or constructor) declared in a type.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IMethod extends IMember, IAnnotatable {
+/**
+ * Returns a {@link IMemberValuePair member value pair} representing the default
+ * value of this method if any, or <code>null</code> if this method's parent is
+ * not an annotation type, or else if this method does not have a default value.
+ * <p>
+ * Note that {@link IMemberValuePair#getValue()} might return <code>null</code>.
+ * Please see this method for more details.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return a member pair value if any, or <code>null</code> if none
+ * @since 3.4
+ */
+IMemberValuePair getDefaultValue() throws JavaModelException;
+/**
+ * Returns the simple name of this method.
+ * For a constructor, this returns the simple name of the declaring type.
+ * Note: This holds whether the constructor appears in a source or binary type
+ * (even though class files internally define constructor names to be <code>"&lt;init&gt;"</code>).
+ * For the class initialization methods in binary types, this returns
+ * the special name <code>"&lt;clinit&gt;"</code>.
+ * This is a handle-only method.
+ * @return the simple name of this method
+ */
+String getElementName();
+/**
+ * Returns the type signatures of the exceptions this method throws,
+ * in the order declared in the source. Returns an empty array
+ * if this method throws no exceptions.
+ * <p>
+ * For example, a source method declaring <code>"throws IOException"</code>,
+ * would return the array <code>{"QIOException;"}</code>.
+ * </p>
+ * <p>
+ * The type signatures may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the type signatures of the exceptions this method throws,
+ * in the order declared in the source, an empty array if this method throws no exceptions
+ * @see Signature
+ */
+String[] getExceptionTypes() throws JavaModelException;
+
+/**
+ * Returns the formal type parameter signatures for this method.
+ * Returns an empty array if this method has no formal type parameters.
+ * <p>
+ * The formal type parameter signatures may be either unresolved (for source
+ * types) or resolved (for binary types). See {@link Signature} for details.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the formal type parameter signatures of this method,
+ * in the order declared in the source, an empty array if none
+ * @see Signature
+ * @since 3.0
+ * @deprecated Use {@link #getTypeParameters()} instead
+ */
+String[] getTypeParameterSignatures() throws JavaModelException;
+/**
+ * Returns the formal type parameters for this method.
+ * Returns an empty array if this method has no formal type parameters.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the formal type parameters of this method,
+ * in the order declared in the source, an empty array if none
+ * @since 3.1
+ */
+ITypeParameter[] getTypeParameters() throws JavaModelException;
+/**
+ * Returns the number of parameters of this method.
+ * This is a handle-only method.
+ *
+ * @return the number of parameters of this method
+ */
+int getNumberOfParameters();
+
+/**
+ * Returns the parameters of this method.
+ * <p>An empty array is returned, if the method has no parameters.</p>
+ * <p>For binary types, associated source is used to retrieve the {@link ILocalVariable#getNameRange() name range},
+ * {@link ILocalVariable#getSourceRange() source range} and the {@link ILocalVariable#getFlags() flags}.</p>
+ * <p>These local variables can be used to retrieve the {@link ILocalVariable#getAnnotations() parameter annotations}.</p>
+ * 
+ * @return the parameters of this method
+ * @throws JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @since 3.7
+ */
+ILocalVariable[] getParameters() throws JavaModelException;
+
+/**
+ * Returns the binding key for this method only if the given method is {@link #isResolved() resolved}.
+ * A binding key is a key that uniquely identifies this method. It allows access to:
+ * <ul>
+ * <li>generic info for parameterized methods</li>
+ * <li>the actual return type for references to {@link Object#getClass() Object.getClass()}</li>
+ * <li>the actual parameter types and return type for references to signature polymorphic methods from class MethodHandle</li>
+ * </ul>
+ *
+ * <p>If the given method is not resolved, the returned key is simply the java element's key.
+ * </p>
+ * @return the binding key for this method
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @see BindingKey
+ * @see #isResolved()
+ * @since 3.1
+ */
+String getKey();
+/**
+ * Returns the names of parameters in this method.
+ * For binary types, associated source or attached Javadoc are used to retrieve the names.
+ * If none can be retrieved, then these names are invented as "arg"+i, where i starts at 0.
+ * Returns an empty array if this method has no parameters.
+ *
+ * <p>For example, a method declared as <code>public void foo(String text, int length)</code>
+ * would return the array <code>{"text","length"}</code>.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the names of parameters in this method, an empty array if this method has no parameters
+ */
+String[] getParameterNames() throws JavaModelException;
+/**
+ * Returns the type signatures for the parameters of this method.
+ * Returns an empty array if this method has no parameters.
+ * This is a handle-only method.
+ * <p>
+ * For example, a source method declared as <code>public void foo(String text, int length)</code>
+ * would return the array <code>{"QString;","I"}</code>.
+ * </p>
+ * <p>
+ * The type signatures may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ * </p>
+ *
+ * @return the type signatures for the parameters of this method, an empty array if this method has no parameters
+ * @see Signature
+ */
+String[] getParameterTypes();
+/**
+ * Returns the names of parameters in this method.
+ * For binary types, these names are invented as "arg"+i, where i starts at 0
+ * (even if source is associated with the binary or if Javdoc is attached to the binary).
+ * Returns an empty array if this method has no parameters.
+ *
+ * <p>For example, a method declared as <code>public void foo(String text, int length)</code>
+ * would return the array <code>{"text","length"}</code>. For the same method in a
+ * binary, this would return <code>{"arg0", "arg1"}</code>.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the names of parameters in this method, an empty array if this method has no parameters
+ * @since 3.2
+ */
+String[] getRawParameterNames() throws JavaModelException;
+/**
+ * Returns the type signature of the return value of this method.
+ * For constructors, this returns the signature for void.
+ * <p>
+ * For example, a source method declared as <code>public String getName()</code>
+ * would return <code>"QString;"</code>.
+ * </p>
+ * <p>
+ * The type signature may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ * </p>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the type signature of the return value of this method, void  for constructors
+ * @see Signature
+ */
+String getReturnType() throws JavaModelException;
+/**
+ * Returns the signature of this method. This includes the signatures for the
+ * parameter types and return type, but does not include the method name,
+ * exception types, or type parameters.
+ * <p>
+ * For example, a source method declared as <code>public void foo(String text, int length)</code>
+ * would return <code>"(QString;I)V"</code>.
+ * </p>
+ * <p>
+ * The type signatures embedded in the method signature may be either unresolved
+ * (for source types) or resolved (for binary types), and either basic (for
+ * basic types) or rich (for parameterized types). See {@link Signature} for
+ * details.
+ * </p>
+ *
+ * @return the signature of this method
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @see Signature
+ */
+String getSignature() throws JavaModelException;
+/**
+ * Returns the type parameter declared in this method with the given name.
+ * This is a handle-only method. The type parameter may or may not exist.
+ *
+ * @param name the given simple name
+ * @return the type parameter declared in this method with the given name
+ * @since 3.1
+ */
+ITypeParameter getTypeParameter(String name);
+/**
+ * Returns whether this method is a constructor.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ *
+ * @return true if this method is a constructor, false otherwise
+ */
+boolean isConstructor() throws JavaModelException;
+
+/**
+ * Returns whether this method is a main method.
+ * It is a main method if:
+ * <ul>
+ * <li>its name is equal to <code>"main"</code></li>
+ * <li>its return type is <code>void</code></li>
+ * <li>it is <code>static</code> and <code>public</code></li>
+ * <li>it defines one parameter whose type's simple name is <code>String[]</code></li>
+ * </ul>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @since 2.0
+ * @return true if this method is a main method, false otherwise
+ */
+boolean isMainMethod() throws JavaModelException;
+/**
+ * Returns whether this method represents a resolved method.
+ * If a method is resolved, its key contains resolved information.
+ *
+ * @return whether this method represents a resolved method.
+ * @since 3.1
+ */
+boolean isResolved();
+/**
+ * Returns whether this method is similar to the given method.
+ * Two methods are similar if:
+ * <ul>
+ * <li>their element names are equal</li>
+ * <li>they have the same number of parameters</li>
+ * <li>the simple names of their parameter types are equal</li>
+ * </ul>
+ * This is a handle-only method.
+ *
+ * @param method the given method
+ * @return true if this method is similar to the given method.
+ * @see Signature#getSimpleName(char[])
+ * @since 2.0
+ */
+boolean isSimilar(IMethod method);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java
new file mode 100644
index 0000000..0702061
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that must be opened before they can be
+ * navigated or modified. Opening a textual element (such as a compilation unit)
+ * involves opening a buffer on its contents.  While open, any changes to the buffer
+ * can be reflected in the element's structure;
+ * see {@link #isConsistent} and {@link #makeConsistent(IProgressMonitor)}.
+ * <p>
+ * To reduce complexity in clients, elements are automatically opened
+ * by the Java model as element properties are accessed. The Java model maintains
+ * an LRU cache of open elements, and automatically closes elements as they
+ * are swapped out of the cache to make room for other elements. Elements with
+ * unsaved changes are never removed from the cache, and thus, if the client
+ * maintains many open elements with unsaved
+ * changes, the LRU cache can grow in size (in this case the cache is not
+ * bounded). However, as elements are saved, the cache will shrink back to its
+ * original bounded size.
+ * </p>
+ * <p>
+ * To open an element, all openable parent elements must be open.
+ * The Java model automatically opens parent elements, as it automatically opens elements.
+ * Opening an element may provide access to direct children and other descendants,
+ * but does not automatically open any descendents which are themselves {@link IOpenable}.
+ * For example, opening a compilation unit provides access to all its constituent elements,
+ * but opening a package fragment does not open all compilation units in the package fragment.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IOpenable {
+
+/**
+ * Closes this element and its buffer (if any).
+ * Closing an element which is not open has no effect.
+ *
+ * <p>Note: although {@link #close} is exposed in the API, clients are
+ * not expected to open and close elements - the Java model does this automatically
+ * as elements are accessed.
+ *
+ * @exception JavaModelException if an error occurs closing this element
+ */
+public void close() throws JavaModelException;
+/**
+ * Finds and returns the recommended line separator for this element.
+ * The element's buffer is first searched and the first line separator in this buffer is returned if any.
+ * Otherwise the preference {@link org.eclipse.core.runtime.Platform#PREF_LINE_SEPARATOR}
+ * on this element's project or workspace is returned.
+ * Finally if no such preference is set, the system line separator is returned.
+ *
+ * @return the recommended line separator for this element
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @since 3.2
+ */
+public String findRecommendedLineSeparator() throws JavaModelException;
+/**
+ * Returns the buffer opened for this element, or <code>null</code>
+ * if this element does not have a buffer.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @return the buffer opened for this element, or <code>null</code>
+ * if this element does not have a buffer
+ */
+public IBuffer getBuffer() throws JavaModelException;
+/**
+ * Returns <code>true</code> if this element is open and:
+ * <ul>
+ * <li>its buffer has unsaved changes, or
+ * <li>one of its descendants has unsaved changes, or
+ * <li>a working copy has been created on one of this
+ * element's children and has not yet destroyed
+ * </ul>
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @return <code>true</code> if this element is open and:
+ * <ul>
+ * <li>its buffer has unsaved changes, or
+ * <li>one of its descendants has unsaved changes, or
+ * <li>a working copy has been created on one of this
+ * element's children and has not yet destroyed
+ * </ul>
+ */
+boolean hasUnsavedChanges() throws JavaModelException;
+/**
+ * Returns whether the element is consistent with its underlying resource or buffer.
+ * The element is consistent when opened, and is consistent if the underlying resource
+ * or buffer has not been modified since it was last consistent.
+ *
+ * <p>NOTE: Child consistency is not considered. For example, a package fragment
+ * responds <code>true</code> when it knows about all of its
+ * compilation units present in its underlying folder. However, one or more of
+ * the compilation units could be inconsistent.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @return true if the element is consistent with its underlying resource or buffer, false otherwise.
+ * @see IOpenable#makeConsistent(IProgressMonitor)
+ */
+boolean isConsistent() throws JavaModelException;
+/**
+ * Returns whether this openable is open. This is a handle-only method.
+ * @return true if this openable is open, false otherwise
+ */
+boolean isOpen();
+/**
+ * Makes this element consistent with its underlying resource or buffer
+ * by updating the element's structure and properties as necessary.
+ *<p>
+ * Note: Using this functionality on a working copy will interfere with any
+ * subsequent reconciling operation. Indeed, the next
+ * {@link ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)} or
+ * {@link ICompilationUnit#reconcile(int, boolean, boolean, WorkingCopyOwner, IProgressMonitor)}
+ * operation will not account for changes which occurred before an
+ * explicit use of {@link #makeConsistent(IProgressMonitor)}
+ * <p>
+ * @param progress the given progress monitor
+ * @exception JavaModelException if the element is unable to access the contents
+ * 		of its underlying resource. Reasons include:
+ * <ul>
+ *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @see IOpenable#isConsistent()
+ * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
+ */
+void makeConsistent(IProgressMonitor progress) throws JavaModelException;
+/**
+ * Opens this element and all parent elements that are not already open.
+ * For compilation units, a buffer is opened on the contents of the underlying resource.
+ *
+ * <p>Note: although {@link #open} is exposed in the API, clients are
+ * not expected to open and close elements - the Java model does this automatically
+ * as elements are accessed.
+ *
+ * @param progress the given progress monitor
+ * @exception JavaModelException if an error occurs accessing the contents
+ * 		of its underlying resource. Reasons include:
+ * <ul>
+ *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ */
+public void open(IProgressMonitor progress) throws JavaModelException;
+/**
+ * Saves any changes in this element's buffer to its underlying resource
+ * via a workspace resource operation. This has no effect if the element has no underlying
+ * buffer, or if there are no unsaved changed in the buffer.
+ * <p>
+ * The <code>force</code> parameter controls how this method deals with
+ * cases where the workbench is not completely in sync with the local file system.
+ * If <code>false</code> is specified, this method will only attempt
+ * to overwrite a corresponding file in the local file system provided
+ * it is in sync with the workbench. This option ensures there is no
+ * unintended data loss; it is the recommended setting.
+ * However, if <code>true</code> is specified, an attempt will be made
+ * to write a corresponding file in the local file system,
+ * overwriting any existing one if need be.
+ * In either case, if this method succeeds, the resource will be marked
+ * as being local (even if it wasn't before).
+ * <p>
+ * As a result of this operation, the element is consistent with its underlying
+ * resource or buffer.
+ *
+ * @param progress the given progress monitor
+ * @param force it controls how this method deals with
+ * cases where the workbench is not completely in sync with the local file system
+ * @exception JavaModelException if an error occurs accessing the contents
+ * 		of its underlying resource. Reasons include:
+ * <ul>
+ *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ *  <li>This Java element is read-only (READ_ONLY)</li>
+ * </ul>
+ */
+public void save(IProgressMonitor progress, boolean force) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java
new file mode 100644
index 0000000..2f394d7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+
+/**
+ * Represents a package declaration in Java compilation unit.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IPackageDeclaration extends IJavaElement, ISourceReference, IAnnotatable {
+/**
+ * Returns the name of the package the statement refers to.
+ * This is a handle-only method.
+ *
+ * @return the name of the package the statement
+ */
+String getElementName();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java
new file mode 100644
index 0000000..cea9e2b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A package fragment is a portion of the workspace corresponding to an entire package,
+ * or to a portion thereof. The distinction between a package fragment and a package
+ * is that a package with some name is the union of all package fragments in the class path
+ * which have the same name.
+ * <p>
+ * Package fragments elements need to be opened before they can be navigated or manipulated.
+ * The children are of type <code>ICompilationUnit</code> (representing a source file) or
+ * <code>IClassFile</code> (representing a binary class file).
+ * The children are listed in no particular order.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IPackageFragment extends IParent, IJavaElement, IOpenable, ISourceManipulation {
+
+	/**
+	 * <p>
+	 * The name of package fragment for the default package (value: the empty
+	 * string, <code>""</code>).
+	 * </p>
+ 	*/
+	public static final String DEFAULT_PACKAGE_NAME = ""; //$NON-NLS-1$
+	/**
+	 * Returns whether this fragment contains at least one Java resource.
+	 * @return true if this fragment contains at least one Java resource, false otherwise
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 */
+	boolean containsJavaResources() throws JavaModelException;
+	/**
+	 * Creates and returns a compilation unit in this package fragment
+	 * with the specified name and contents. No verification is performed
+	 * on the contents.
+	 *
+	 * <p>It is possible that a compilation unit with the same name already exists in this
+	 * package fragment.
+	 * The value of the <code>force</code> parameter affects the resolution of
+	 * such a conflict:<ul>
+	 * <li> <code>true</code> - in this case the compilation is created with the new contents</li>
+	 * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+	 * </ul>
+	 *
+	 * @param contents the given contents
+	 * @param force specify how to handle conflict is the same name already exists
+	 * @param monitor the given progress monitor
+	 * @param name the given name
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while creating an underlying resource
+	 * <li> The name is not a valid compilation unit name (INVALID_NAME)
+	 * <li> The contents are <code>null</code> (INVALID_CONTENTS)
+	 * </ul>
+	 * @return a compilation unit in this package fragment
+	 * with the specified name and contents
+	 */
+	ICompilationUnit createCompilationUnit(String name, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException;
+	/**
+	 * Returns the class file with the specified name
+	 * in this package (for example, <code>"Object.class"</code>).
+	 * The ".class" suffix is required.
+	 * This is a handle-only method.  The class file may or may not be present.
+	 * @param name the given name
+	 * @return the class file with the specified name in this package
+	 */
+	IClassFile getClassFile(String name);
+	/**
+	 * Returns all of the class files in this package fragment.
+	 *
+	 * <p>Note: it is possible that a package fragment contains only
+	 * compilation units (in other words, its kind is <code>K_SOURCE</code>), in
+	 * which case this method returns an empty collection.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return all of the class files in this package fragment
+	 */
+	IClassFile[] getClassFiles() throws JavaModelException;
+	/**
+	 * Returns the compilation unit with the specified name
+	 * in this package (for example, <code>"Object.java"</code>).
+	 * The name has to be a valid compilation unit name.
+	 * This is a handle-only method.  The compilation unit may or may not be present.
+	 *
+	 * @param name the given name
+	 * @return the compilation unit with the specified name in this package
+	 * @see JavaConventions#validateCompilationUnitName(String name, String sourceLevel, String complianceLevel)
+	 */
+	ICompilationUnit getCompilationUnit(String name);
+	/**
+	 * Returns all of the compilation units in this package fragment.
+	 *
+	 * <p>Note: it is possible that a package fragment contains only
+	 * class files (in other words, its kind is <code>K_BINARY</code>), in which
+	 * case this method returns an empty collection.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return all of the compilation units in this package fragment
+	 */
+	ICompilationUnit[] getCompilationUnits() throws JavaModelException;
+	/**
+	 * Returns all of the compilation units in this package fragment that are
+	 * in working copy mode and that have the given owner.
+	 * <p>
+	 * Only existing working copies are returned. So a compilation unit handle that has no
+	 * corresponding resource on disk will be included if and only if is in working copy mode.
+	 * </p>
+	 * <p>Note: it is possible that a package fragment contains only
+	 * class files (in other words, its kind is <code>K_BINARY</code>), in which
+	 * case this method returns an empty collection.
+	 * </p>
+	 *
+	 * @param owner the owner of the returned compilation units
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return all of the compilation units in this package fragment
+	 * @since 3.0
+	 */
+	ICompilationUnit[] getCompilationUnits(WorkingCopyOwner owner) throws JavaModelException;
+	/**
+	 * Returns the dot-separated package name of this fragment, for example
+	 * <code>"java.lang"</code>, or <code>""</code> (the empty string),
+	 * for the default package.
+	 *
+	 * @return the dot-separated package name of this fragment
+	 */
+	String getElementName();
+	/**
+	 * Returns this package fragment's root kind encoded as an integer.
+	 * A package fragment can contain source files (i.e. files with one of
+	 * the {@link JavaCore#getJavaLikeExtensions() Java-like extensions}),
+	 * or <code>.class</code> files. This is a convenience method.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return this package fragment's root kind encoded as an integer
+	 * @see IPackageFragmentRoot#K_SOURCE
+	 * @see IPackageFragmentRoot#K_BINARY
+	 */
+	int getKind() throws JavaModelException;
+	/**
+	 * Returns an array of non-Java resources contained in this package fragment.
+	 * <p>
+	 * Non-Java resources includes other files and folders located in the same
+	 * directory as the compilation units or class files for this package
+	 * fragment. Source files excluded from this package by virtue of
+	 * inclusion/exclusion patterns on the corresponding source classpath entry
+	 * are considered non-Java resources and will appear in the result
+	 * (possibly in a folder).
+	 * </p><p>
+	 * Since 3.3, if this package fragment is inside an archive, the non-Java resources
+	 * are a tree of {@link IJarEntryResource}s. One can navigate this tree using
+	 * the {@link IJarEntryResource#getChildren()} and
+	 * {@link IJarEntryResource#getParent()} methods.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return an array of non-Java resources (<code>IFile</code>s,
+	 *              <code>IFolder</code>s, or <code>IStorage</code>s if the
+	 *              package fragment is in an archive) contained in this package
+	 *              fragment
+	 * @see IClasspathEntry#getInclusionPatterns()
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	Object[] getNonJavaResources() throws JavaModelException;
+	/**
+	 * Returns whether this package fragment's name is
+	 * a prefix of other package fragments in this package fragment's
+	 * root.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this package fragment's name is a prefix of other package fragments in this package fragment's root, false otherwise
+	 */
+	boolean hasSubpackages() throws JavaModelException;
+	/**
+	 * Returns whether this package fragment is a default package.
+	 * This is a handle-only method.
+	 *
+	 * @return true if this package fragment is a default package
+	 */
+	boolean isDefaultPackage();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
new file mode 100644
index 0000000..c1ed588
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
@@ -0,0 +1,449 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - specified that a source archive or a source folder can be attached to a binary
+ *                               package fragment root.
+ *     IBM Corporation - added root manipulation APIs: copy, delete, move
+ *     IBM Corporation - added DESTINATION_PROJECT_CLASSPATH
+ *     IBM Corporation - added OTHER_REFERRING_PROJECTS_CLASSPATH
+ *     IBM Corporation - added NO_RESOURCE_MODIFICATION
+ *     IBM Corporation - added REPLACE
+ *     IBM Corporation - added ORIGINATING_PROJECT_CLASSPATH
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A package fragment root contains a set of package fragments.
+ * It corresponds to an underlying resource which is either a folder,
+ * JAR, or zip.  In the case of a folder, all descendant folders represent
+ * package fragments.  For a given child folder representing a package fragment,
+ * the corresponding package name is composed of the folder names between the folder
+ * for this root and the child folder representing the package, separated by '.'.
+ * In the case of a JAR or zip, the contents of the archive dictates
+ * the set of package fragments in an analogous manner.
+ * Package fragment roots need to be opened before they can be navigated or manipulated.
+ * The children are of type <code>IPackageFragment</code>, and are in no particular order.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IPackageFragmentRoot
+	extends IParent, IJavaElement, IOpenable {
+	/**
+	 * Kind constant for a source path root. Indicates this root
+	 * only contains source files.
+	 */
+	int K_SOURCE = 1;
+	/**
+	 * Kind constant for a binary path root. Indicates this
+	 * root only contains binary files.
+	 */
+	int K_BINARY = 2;
+	/**
+	 * Empty root path
+	 */
+	String DEFAULT_PACKAGEROOT_PATH = ""; //$NON-NLS-1$
+	/**
+	 * Update model flag constant (bit mask value 1) indicating that the operation
+	 * is to not copy/move/delete the package fragment root resource.
+	 * @since 2.1
+	 */
+	int NO_RESOURCE_MODIFICATION = 1;
+	/**
+	 * Update model flag constant (bit mask value 2) indicating that the operation
+	 * is to update the classpath of the originating project.
+	 * @since 2.1
+	 */
+	int ORIGINATING_PROJECT_CLASSPATH = 2;
+	/**
+	 * Update model flag constant (bit mask value 4) indicating that the operation
+	 * is to update the classpath of all referring projects except the originating project.
+	 * @since 2.1
+	 */
+	int OTHER_REFERRING_PROJECTS_CLASSPATH = 4;
+	/**
+	 * Update model flag constant (bit mask value 8) indicating that the operation
+	 * is to update the classpath of the destination project.
+	 * @since 2.1
+	 */
+	int DESTINATION_PROJECT_CLASSPATH = 8;
+	/**
+	 * Update model flag constant (bit mask value 16) indicating that the operation
+	 * is to replace the resource and the destination project's classpath entry.
+	 * @since 2.1
+	 */
+	int REPLACE = 16;
+	/**
+	 * Attaches the source archive identified by the given absolute path to this
+	 * binary package fragment root. <code>rootPath</code> specifies the location
+	 * of the root within the archive or folder (empty specifies the default root
+	 * and <code>null</code> specifies the root path should be detected).
+	 * Once a source archive or folder is attached to the package fragment root,
+	 * the <code>getSource</code> and <code>getSourceRange</code>
+	 * methods become operational for binary types/members.
+	 * To detach a source archive or folder from a package fragment root, specify
+	 * <code>null</code> as the source path.
+	 *
+	 * @param sourcePath the given absolute path to the source archive or folder
+	 * @param rootPath specifies the location of the root within the archive
+	 *              (empty specifies the default root and <code>null</code> specifies
+	 *               automatic detection of the root path)
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this operation fails. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while updating a server property
+	 * <li> This package fragment root is not of kind binary (INVALID_ELEMENT_TYPES)
+	 * <li> The path provided is not absolute (RELATIVE_PATH)
+	 * </ul>
+	 */
+	void attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Copies the resource of this package fragment root to the destination path
+	 * as specified by <code>IResource.copy(IPath, int, IProgressMonitor)</code>
+	 * but excluding nested source folders.
+	 * <p>
+	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
+	 * <code>updateModelFlags</code> or if this package fragment root is external,
+	 * this operation doesn't copy the resource. <code>updateResourceFlags</code>
+	 * is then ignored.
+	 * </p><p>
+	 * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, updates the classpath of the
+	 * destination's project (if it is a Java project). If a non-<code>null</code>
+	 * sibling is specified, a copy of this root's classpath entry is inserted before the
+	 * sibling on the destination project's raw classpath. If <code>null</code> is
+	 * specified, the classpath entry is added at the end of the raw classpath.
+	 * </p><p>
+	 * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
+	 * overwrites the resource at the destination path if any.
+	 * If the same classpath entry already exists on the destination project's raw
+	 * classpath, then the sibling is ignored and the new classpath entry replaces the
+	 * existing one.
+	 * </p><p>
+	 * If no flags is specified in <code>updateModelFlags</code> (using
+	 * <code>IResource.NONE</code>), the default behavior applies: the
+	 * resource is copied (if this package fragment root is not external) and the
+	 * classpath is not updated.
+	 * </p>
+	 *
+	 * @param destination the destination path
+	 * @param updateResourceFlags bit-wise or of update resource flag constants
+	 *   (<code>IResource.FORCE</code> and <code>IResource.SHALLOW</code>)
+	 * @param updateModelFlags bit-wise or of update resource flag constants
+	 *   (<code>DESTINATION_PROJECT_CLASSPATH</code> and
+	 *   <code>NO_RESOURCE_MODIFICATION</code>)
+	 * @param sibling the classpath entry before which a copy of the classpath
+	 * entry should be inserted or <code>null</code> if the classpath entry should
+	 * be inserted at the end
+	 * @param monitor a progress monitor
+	 *
+	 * @exception JavaModelException if this root could not be copied. Reasons
+	 * include:
+	 * <ul>
+	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while copying the
+	 * resource or updating a classpath</li>
+	 * <li>
+	 * The destination is not inside an existing project and <code>updateModelFlags</code>
+	 * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code>
+	 * (INVALID_DESTINATION)</li>
+	 * <li> The sibling is not a classpath entry on the destination project's
+	 * raw classpath (INVALID_SIBLING)</li>
+	 * <li> The same classpath entry already exists on the destination project's
+	 * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
+	 * has not been specified as <code>REPLACE</code></li>
+	 * </ul>
+	 * @see org.eclipse.core.resources.IResource#copy(IPath, boolean, IProgressMonitor)
+	 * @since 2.1
+	 */
+	void copy(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
+	/**
+	 * Creates and returns a package fragment in this root with the
+	 * given dot-separated package name.  An empty string specifies the default package.
+	 * This has the side effect of creating all package
+	 * fragments that are a prefix of the new package fragment which
+	 * do not exist yet. If the package fragment already exists, this
+	 * has no effect.
+	 *
+	 * For a description of the <code>force</code> flag, see <code>IFolder.create</code>.
+	 *
+	 * @param name the given dot-separated package name
+	 * @param force a flag controlling how to deal with resources that
+	 *    are not in sync with the local file system
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while creating an underlying resource
+	 * <li> This package fragment root is read only (READ_ONLY)
+	 * <li> The name is not a valid package name (INVALID_NAME)
+	 * </ul>
+	 * @return a package fragment in this root with the given dot-separated package name
+	 * @see org.eclipse.core.resources.IFolder#create(boolean, boolean, IProgressMonitor)
+	 */
+	IPackageFragment createPackageFragment(
+		String name,
+		boolean force,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+	/**
+	 * Deletes the resource of this package fragment root as specified by
+	 * <code>IResource.delete(int, IProgressMonitor)</code> but excluding nested
+	 * source folders.
+	 * <p>
+	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
+	 * <code>updateModelFlags</code> or if this package fragment root is external,
+	 * this operation doesn't delete the resource. <code>updateResourceFlags</code>
+	 * is then ignored.
+	 * </p><p>
+	 * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, update the raw classpath of this package
+	 * fragment root's project by removing the corresponding classpath entry.
+	 * </p><p>
+	 * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, update the raw classpaths of all other Java
+	 * projects referring to this root's resource by removing the corresponding classpath
+	 * entries.
+	 * </p><p>
+	 * If no flags is specified in <code>updateModelFlags</code> (using
+	 * <code>IResource.NONE</code>), the default behavior applies: the
+	 * resource is deleted (if this package fragment root is not external) and no
+	 * classpaths are updated.
+	 * </p>
+	 *
+	 * @param updateResourceFlags bit-wise or of update resource flag constants
+	 *   (<code>IResource.FORCE</code> and <code>IResource.KEEP_HISTORY</code>)
+	 * @param updateModelFlags bit-wise or of update resource flag constants
+	 *   (<code>ORIGINATING_PROJECT_CLASSPATH</code>,
+	 *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and
+	 *   <code>NO_RESOURCE_MODIFICATION</code>)
+	 * @param monitor a progress monitor
+	 *
+	 * @exception JavaModelException if this root could not be deleted. Reasons
+	 * include:
+	 * <ul>
+	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while deleting the resource
+	 * or updating a classpath
+	 * </li>
+	 * </ul>
+	 * @see org.eclipse.core.resources.IResource#delete(boolean, IProgressMonitor)
+	 * @since 2.1
+	 */
+	void delete(int updateResourceFlags, int updateModelFlags, IProgressMonitor monitor) throws JavaModelException;
+	/**
+	 * Returns this package fragment root's kind encoded as an integer.
+	 * A package fragment root can contain source files (i.e. files with one
+	 * of the {@link JavaCore#getJavaLikeExtensions() Java-like extensions},
+	 * or <code>.class</code> files, but not both.
+	 * If the underlying folder or archive contains other kinds of files, they are ignored.
+	 * In particular, <code>.class</code> files are ignored under a source package fragment root,
+	 * and source files are ignored under a binary package fragment root.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return this package fragment root's kind encoded as an integer
+	 * @see IPackageFragmentRoot#K_SOURCE
+	 * @see IPackageFragmentRoot#K_BINARY
+	 */
+	int getKind() throws JavaModelException;
+
+	/**
+	 * Returns an array of non-Java resources contained in this package fragment root.
+	 * <p>
+	 * Non-Java resources includes other files and folders located in the same
+	 * directories as the compilation units or class files under this package
+	 * fragment root. Resources excluded from this package fragment root
+	 * by virtue of inclusion/exclusion patterns on the corresponding source classpath
+	 * entry are considered non-Java resources and will appear in the result
+	 * (possibly in a folder). Thus when a nested source folder is excluded, it will appear
+	 * in the non-Java resources of the outer folder.
+	 * </p><p>
+	 * Since 3.3, if this package fragment root is an archive, the non-Java resources
+	 * are a tree of {@link IJarEntryResource}s. One can navigate this tree using
+	 * the {@link IJarEntryResource#getChildren()} and
+	 * {@link IJarEntryResource#getParent()} methods.
+	 * </p>
+	 *
+	 * @return an array of non-Java resources (<code>IFile</code>s,
+	 *              <code>IFolder</code>s, or <code>IStorage</code>s if the
+	 *              package fragment root is in archive) contained in this package
+	 *              fragment root
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @see IClasspathEntry#getInclusionPatterns()
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	Object[] getNonJavaResources() throws JavaModelException;
+
+	/**
+	 * Returns the package fragment with the given package name.
+	 * An empty string indicates the default package.
+	 * This is a handle-only operation.  The package fragment
+	 * may or may not exist.
+	 *
+	 * @param packageName the given package name
+	 * @return the package fragment with the given package name
+	 */
+	IPackageFragment getPackageFragment(String packageName);
+
+
+	/**
+	 * Returns the first raw classpath entry that corresponds to this package
+	 * fragment root.
+	 * A raw classpath entry corresponds to a package fragment root if once resolved
+	 * this entry's path is equal to the root's path.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the first raw classpath entry that corresponds to this package fragment root
+	 * @since 2.0
+	 */
+	IClasspathEntry getRawClasspathEntry() throws JavaModelException;
+	
+	/**
+	 * 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;
+
+	/**
+	 * Returns the absolute path to the source archive attached to
+	 * this package fragment root's binary archive.
+	 *
+	 * @return the absolute path to the corresponding source archive,
+	 *   or <code>null</code> if this package fragment root's binary archive
+	 *   has no corresponding source archive, or if this package fragment root
+	 *   is not a binary archive
+	 * @exception JavaModelException if this operation fails
+	 */
+	IPath getSourceAttachmentPath() throws JavaModelException;
+
+	/**
+	 * Returns the path within this package fragment root's source archive.
+	 * An empty path indicates that packages are located at the root of the
+	 * source archive.
+	 *
+	 * @return the path within the corresponding source archive,
+	 *   or <code>null</code> if this package fragment root's binary archive
+	 *   has no corresponding source archive, or if this package fragment root
+	 *   is not a binary archive
+	 * @exception JavaModelException if this operation fails
+	 */
+	IPath getSourceAttachmentRootPath() throws JavaModelException;
+
+	/**
+	 * Returns whether this package fragment root's underlying
+	 * resource is a binary archive (a JAR or zip file).
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return true if this package fragment root's underlying resource is a binary archive, false otherwise
+	 */
+	public boolean isArchive();
+
+	/**
+	 * Returns whether this package fragment root is external
+	 * to the workbench (that is, a local file), and has no
+	 * underlying resource.
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return true if this package fragment root is external
+	 * to the workbench (that is, a local file), and has no
+	 * underlying resource, false otherwise
+	 */
+	boolean isExternal();
+
+	/**
+	 * Moves the resource of this package fragment root to the destination path
+	 * as specified by <code>IResource.move(IPath,int,IProgressMonitor)</code>
+	 * but excluding nested source folders.
+	 * <p>
+	 * If <code>NO_RESOURCE_MODIFICATION</code> is specified in
+	 * <code>updateModelFlags</code> or if this package fragment root is external,
+	 * this operation doesn't move the resource. <code>updateResourceFlags</code>
+	 * is then ignored.
+	 * </p><p>
+	 * If <code>DESTINATION_PROJECT_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, updates the classpath of the
+	 * destination's project (if it is a Java project). If a non-<code>null</code>
+	 * sibling is specified, a copy of this root's classpath entry is inserted before the
+	 * sibling on the destination project's raw classpath. If <code>null</code> is
+	 * specified, the classpath entry is added at the end of the raw classpath.
+	 * </p><p>
+	 * If <code>ORIGINATING_PROJECT_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, update the raw classpath of this package
+	 * fragment root's project by removing the corresponding classpath entry.
+	 * </p><p>
+	 * If <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> is specified in
+	 * <code>updateModelFlags</code>, update the raw classpaths of all other Java
+	 * projects referring to this root's resource by removing the corresponding classpath
+	 * entries.
+	 * </p><p>
+	 * If <code>REPLACE</code> is specified in <code>updateModelFlags</code>,
+	 * overwrites the resource at the destination path if any.
+	 * If the same classpath entry already exists on the destination project's raw
+	 * classpath, then the sibling is ignored and the new classpath entry replaces the
+	 * existing one.
+	 * </p><p>
+	 * If no flags is specified in <code>updateModelFlags</code> (using
+	 * <code>IResource.NONE</code>), the default behavior applies: the
+	 * resource is moved (if this package fragment root is not external) and no
+	 * classpaths are updated.
+	 * </p>
+	 *
+	 * @param destination the destination path
+	 * @param updateResourceFlags bit-wise or of update flag constants
+	 * (<code>IResource.FORCE</code>, <code>IResource.KEEP_HISTORY</code>
+	 * and <code>IResource.SHALLOW</code>)
+	 * @param updateModelFlags bit-wise or of update resource flag constants
+	 *   (<code>DESTINATION_PROJECT_CLASSPATH</code>,
+	 *   <code>ORIGINATING_PROJECT_CLASSPATH</code>,
+	 *   <code>OTHER_REFERRING_PROJECTS_CLASSPATH</code> and
+	 *   <code>NO_RESOURCE_MODIFICATION</code>)
+	 * @param sibling the classpath entry before which a copy of the classpath
+	 * entry should be inserted or <code>null</code> if the classpath entry should
+	 * be inserted at the end
+	 * @param monitor a progress monitor
+	 *
+	 * @exception JavaModelException if this root could not be moved. Reasons
+	 * include:
+	 * <ul>
+	 * <li> This root does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while copying the
+	 * resource or updating a classpath</li>
+	 * <li>
+	 * The destination is not inside an existing project and <code>updateModelFlags</code>
+	 * has been specified as <code>DESTINATION_PROJECT_CLASSPATH</code>
+	 * (INVALID_DESTINATION)</li>
+	 * <li> The sibling is not a classpath entry on the destination project's
+	 * raw classpath (INVALID_SIBLING)</li>
+	 * <li> The same classpath entry already exists on the destination project's
+	 * classpath (NAME_COLLISION) and <code>updateModelFlags</code>
+	 * has not been specified as <code>REPLACE</code></li>
+	 * </ul>
+	 * @see org.eclipse.core.resources.IResource#move(IPath, boolean, IProgressMonitor)
+	 * @since 2.1
+	 */
+	void move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java
new file mode 100644
index 0000000..b483d69
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Common protocol for Java elements that contain other Java elements.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IParent {
+/**
+ * Returns the immediate children of this element.
+ * Unless otherwise specified by the implementing element,
+ * the children are in no particular order.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @return the immediate children of this element
+ */
+IJavaElement[] getChildren() throws JavaModelException;
+/**
+ * Returns whether this element has one or more immediate children.
+ * This is a convenience method, and may be more efficient than
+ * testing whether <code>getChildren</code> is an empty array.
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @return true if the immediate children of this element, false otherwise
+ */
+boolean hasChildren() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java
new file mode 100644
index 0000000..e14bfa0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * A callback interface for receiving java problem as they are discovered
+ * by some Java operation.
+ *
+ * @see IProblem
+ * @since 2.0
+ */
+public interface IProblemRequestor {
+
+	/**
+	 * Notification of a Java problem.
+	 *
+	 * @param problem IProblem - The discovered Java problem.
+	 */
+	void acceptProblem(IProblem problem);
+
+	/**
+	 * Notification sent before starting the problem detection process.
+	 * Typically, this would tell a problem collector to clear previously recorded problems.
+	 */
+	void beginReporting();
+
+	/**
+	 * Notification sent after having completed problem detection process.
+	 * Typically, this would tell a problem collector that no more problems should be expected in this
+	 * iteration.
+	 */
+	void endReporting();
+
+	/**
+	 * Predicate allowing the problem requestor to signal whether or not it is currently
+	 * interested by problem reports. When answering <code>false</code>, problem will
+	 * not be discovered any more until the next iteration.
+	 *
+	 * This  predicate will be invoked once prior to each problem detection iteration.
+	 *
+	 * @return boolean - indicates whether the requestor is currently interested by problems.
+	 */
+	boolean isActive();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java
new file mode 100644
index 0000000..268501d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A Java model region describes a hierarchical set of elements.
+ * Regions are often used to describe a set of elements to be considered
+ * when performing operations; for example, the set of elements to be
+ * considered during a search. A region may include elements from different
+ * projects.
+ * <p>
+ * When an element is included in a region, all of its children
+ * are considered to be included. Children of an included element
+ * <b>cannot</b> be selectively excluded.
+ * </p>
+ * <p>
+ * Instances can be created via the <code>JavaCore.newRegion</code>.
+ * </p>
+ *
+ * @see JavaCore#newRegion()
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IRegion {
+	/**
+	 * Adds the given element and all of its descendents to this region.
+	 * If the specified element is already included, or one of its
+	 * ancestors is already included, this has no effect. If the element
+	 * being added is an ancestor of an element already contained in this
+	 * region, the ancestor subsumes the descendent.
+	 *
+	 * @param element the given element
+	 */
+	void add(IJavaElement element);
+	/**
+	 * Returns whether the given element is contained in this region.
+	 *
+	 * @param element the given element
+	 * @return true if the given element is contained in this region, false otherwise
+	 */
+	boolean contains(IJavaElement element);
+	/**
+	 * Returns the top level elements in this region.
+	 * All descendents of these elements are also included in this region.
+	 *
+	 * @return the top level elements in this region
+	 */
+	IJavaElement[] getElements();
+	/**
+	 * Removes the specified element from the region and returns
+	 * <code>true</code> if successful, <code>false</code> if the remove
+	 * fails. If an ancestor of the given element is included, the
+	 * remove fails (in other words, it is not possible to selectively
+	 * exclude descendants of included ancestors).
+	 *
+	 * @param element the given element
+	 * @return <code>true</code> if successful, <code>false</code> if the remove fails
+	 */
+	boolean remove(IJavaElement element);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java
new file mode 100644
index 0000000..c915c7c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that support source code manipulations such
+ * as copy, move, rename, and delete.
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ISourceManipulation {
+/**
+ * Copies this element to the given container.
+ *
+ * @param container the container
+ * @param sibling the sibling element before which the copy should be inserted,
+ *   or <code>null</code> if the copy should be inserted as the last child of
+ *   the container
+ * @param rename the new name for the element, or <code>null</code> if the copy
+ *   retains the name of this element
+ * @param replace <code>true</code> if any existing child in the container with
+ *   the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be copied. Reasons include:
+ * <ul>
+ * <li> This Java element, container element, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The container is of an incompatible type (INVALID_DESTINATION)
+ * <li> The sibling is not a child of the given container (INVALID_SIBLING)
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *		and <code>replace</code> has been specified as <code>false</code>
+ * <li> The container or this element is read-only (READ_ONLY)
+ * </ul>
+ *
+ * @exception IllegalArgumentException if container is <code>null</code>
+ * @see org.eclipse.jdt.core.IJavaModelStatusConstants#INVALID_DESTINATION
+ */
+void copy(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Deletes this element, forcing if specified and necessary.
+ *
+ * @param force a flag controlling whether underlying resources that are not
+ *    in sync with the local file system will be tolerated (same as the force flag
+ *	  in IResource operations).
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be deleted. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource (CORE_EXCEPTION)</li>
+ * <li> This element is read-only (READ_ONLY)</li>
+ * </ul>
+ */
+void delete(boolean force, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Moves this element to the given container.
+ *
+ * @param container the container
+ * @param sibling the sibling element before which the element should be inserted,
+ *   or <code>null</code> if the element should be inserted as the last child of
+ *   the container
+ * @param rename the new name for the element, or <code>null</code> if the
+ *   element retains its name
+ * @param replace <code>true</code> if any existing child in the container with
+ *   the target name should be replaced, and <code>false</code> to throw an
+ *   exception in the event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be moved. Reasons include:
+ * <ul>
+ * <li> This Java element, container element, or sibling does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The container is of an incompatible type (INVALID_DESTINATION)
+ * <li> The sibling is not a child of the given container (INVALID_SIBLING)
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *		and <code>replace</code> has been specified as <code>false</code>
+ * <li> The container or this element is read-only (READ_ONLY)
+ * </ul>
+ *
+ * @exception IllegalArgumentException if container is <code>null</code>
+ * @see org.eclipse.jdt.core.IJavaModelStatusConstants#INVALID_DESTINATION
+ */
+void move(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Renames this element to the given name.
+ *
+ * @param name the new name for the element
+ * @param replace <code>true</code> if any existing element with the target name
+ *   should be replaced, and <code>false</code> to throw an exception in the
+ *   event of a name collision
+ * @param monitor a progress monitor
+ * @exception JavaModelException if this element could not be renamed. Reasons include:
+ * <ul>
+ * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> A <code>CoreException</code> occurred while updating an underlying resource
+ * <li> The new name is invalid (INVALID_NAME)
+ * <li> A child in the container already exists with the same name (NAME_COLLISION)
+ *		and <code>replace</code> has been specified as <code>false</code>
+ * <li> This element is read-only (READ_ONLY)
+ * </ul>
+ */
+void rename(String name, boolean replace, IProgressMonitor monitor) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java
new file mode 100644
index 0000000..8bc9e02
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A source range defines an element's source coordinates relative to
+ * its source buffer.
+ *
+ * <p>Clients may use the method {@link org.eclipse.jdt.core.SourceRange#isAvailable(ISourceRange)}
+ * in order to find out if a source range is available. This method returns <code>false</code>
+ * when the source range offset is equals to <code>-1</code>.</p>
+ * 
+ * <p>Clients may use the default implementation provided by {@link SourceRange}.</p>
+ *
+ * @see SourceRange
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ISourceRange {
+
+/**
+ * Returns the number of characters of the source code for this element,
+ * relative to the source buffer in which this element is contained.
+ *
+ * @return the number of characters of the source code for this element,
+ * relative to the source buffer in which this element is contained
+ */
+int getLength();
+/**
+ * Returns the 0-based index of the first character of the source code for this element,
+ * relative to the source buffer in which this element is contained. However, if the element
+ * has no associated source code, an implementation may return -1. 
+ *
+ * @return the 0-based index of the first character of the source code for this element,
+ * relative to the source buffer in which this element is contained. However, if the element
+ * has no associated source code, an implementation may return -1. 
+ */
+int getOffset();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java
new file mode 100644
index 0000000..f9f045e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * Common protocol for Java elements that have associated source code.
+ * This set consists of {@link IClassFile}, {@link ICompilationUnit},
+ * {@link IPackageDeclaration}, {@link IImportDeclaration},
+ * {@link IImportContainer}, {@link IType}, {@link IField},
+ * {@link IMethod}, {@link IInitializer}, {@link ITypeParameter},
+ * {@link ILocalVariable}, and {@link IAnnotation}.
+ * <p>
+ * Note: For <code>IClassFile</code>, <code>IType</code> and other members
+ * derived from a binary type, the implementation returns source iff the
+ * element has attached source code.
+ * </p>
+ * <p>
+ * Source reference elements may be working copies if they were created from
+ * a compilation unit that is a working copy.
+ * </p>
+ *
+ * @see IPackageFragmentRoot#attachSource(org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ISourceReference {
+/**
+ * Returns whether this element exists in the model.
+ *
+ * @return <code>true</code> if this element exists in the Java model
+ * @since 2.0
+ */
+boolean exists();
+
+/**
+ * Returns the source code associated with this element.
+ * This extracts the substring from the source buffer containing this source
+ * element. This corresponds to the source range that would be returned by
+ * <code>getSourceRange</code>.
+ * <p>
+ * For class files, this returns the source of the entire compilation unit
+ * associated with the class file (if there is one).
+ * </p>
+ *
+ * @return the source code, or <code>null</code> if this element has no
+ *   associated source code
+ * @exception JavaModelException if an exception occurs while accessing its corresponding resource
+ */
+String getSource() throws JavaModelException;
+/**
+ * Returns the source range associated with this element.
+ * <p>
+ * For class files, this returns the range of the entire compilation unit
+ * associated with the class file (if there is one).
+ * </p>
+ * <p>
+ * If this element has no associated source code, either <code>null</code> is returned,
+ * or a source range with a -1 offset and a 0 length. {@link SourceRange#isAvailable(ISourceRange)}
+ * can be used to detect that case.
+ * </p>
+ *
+ * @return the source range, or either <code>null</code> or [-1, 0] if this element has no
+ *   associated source code
+ * @exception JavaModelException if an exception occurs while accessing its corresponding resource
+ * @see SourceRange#isAvailable(ISourceRange)
+ */
+ISourceRange getSourceRange() throws JavaModelException;
+
+/**
+ * Returns the name range associated with this element.
+ * 
+ * <p>If the element is an {@link IMember}, it returns
+ * the source range of this member's simple name,
+ * or <code>null</code> 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).</p>
+ * 
+ * <p>If this element is an {@link IImportDeclaration}, the source range
+ * of this import declaration's name, or <code>null</code> if this import
+ * declaration does not have associated source code (for example, a binary type).
+ * <br>The source range for the name includes the trailing '*' if the call to
+ * {@link IImportDeclaration#isOnDemand()} returns true.
+ * </p>
+ *
+ * <p>If this element is an {@link IPackageDeclaration}, the source range of
+ * this package declaration's name, or <code>null</code> if this package 
+ * declaration does not have associated source code (for example, a binary type).</p>
+ *
+ * <p>If this element is an {@link IAnnotation}, the source range of
+ * this annotation's name, or <code>null</code> if this annotation does not have
+ * associated source code (for example, in a binary type).</p>
+ * 
+ * <p>If this element is an {@link ITypeParameter}, the source range of this 
+ * type parameter's name, or <code>null</code> if this type parameter does not have
+ * associated source code (for example, in a binary type).</p>
+ * 
+ * <p>If this element is an {@link ITypeRoot} or {@link IImportContainer}, it
+ * returns null.</p>
+ *
+ * @return the name range associated with this element, or <code>null</code> if
+ * not available
+ *
+ * @since 3.7
+ */
+ISourceRange getNameRange() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
new file mode 100644
index 0000000..7f12435
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
@@ -0,0 +1,1208 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Represents either a source type in a compilation unit (either a top-level
+ * type, a member type, a local type or an anonymous type)
+ * or a binary type in a class file. Enumeration classes and annotation
+ * types are subkinds of classes and interfaces, respectively.
+ * <p>
+ * Note that the element name of an anonymous source type is always empty.
+ * </p><p>
+ * If a binary type cannot be parsed, its structure remains unknown.
+ * Use <code>IJavaElement.isStructureKnown</code> to determine whether this
+ * is the case.
+ * </p>
+ * <p>
+ * The children are of type <code>IMember</code>, which includes <code>IField</code>,
+ * <code>IMethod</code>, <code>IInitializer</code> and <code>IType</code>.
+ * The children are listed in the order in which they appear in the source or class file.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IType extends IMember, IAnnotatable {
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 *
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position within snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 2.0
+	 * @deprecated Use {@link #codeComplete(char[],int,int,char[][],char[][],int[],boolean,CompletionRequestor)} instead.
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		ICompletionRequestor requestor)
+		throws JavaModelException;
+
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p><p>
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 * </p>
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position with in snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.0
+	 * @deprecated Use {@link #codeComplete(char[],int,int,char[][],char[][],int[],boolean,CompletionRequestor,WorkingCopyOwner)} instead.
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		ICompletionRequestor requestor,
+		WorkingCopyOwner owner)
+		throws JavaModelException;
+
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 *
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position within snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.1
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor)
+		throws JavaModelException;
+	
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 *
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         fEndTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position within snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.5
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p><p>
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 * </p>
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position with in snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.1
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner)
+		throws JavaModelException;
+	
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p><p>
+	 * If the type has access to its source code and the insertion position is valid,
+	 * then completion is performed against the source. Otherwise the completion is performed
+	 * against the type structure and the given locals variables.
+	 * </p>
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         endTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position with in snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.5
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+
+	/**
+	 * Creates and returns a field in this type with the
+	 * given contents.
+	 * <p>
+	 * Optionally, the new element can be positioned before the specified
+	 * sibling. If no sibling is specified, the element will be inserted
+	 * as the last field declaration in this type.</p>
+	 *
+	 * <p>It is possible that a field with the same name already exists in this type.
+	 * The value of the <code>force</code> parameter affects the resolution of
+	 * such a conflict:<ul>
+	 * <li> <code>true</code> - in this case the field is created with the new contents</li>
+	 * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+	 * </ul></p>
+	 *
+	 * @param contents the given contents
+	 * @param sibling the given sibling
+	 * @param force a flag in case the same name already exists in this type
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while updating an underlying resource
+	 * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+	 * <li> The contents could not be recognized as a field declaration (INVALID_CONTENTS)
+	 * <li> This type is read-only (binary) (READ_ONLY)
+	 * <li> There was a naming collision with an existing field (NAME_COLLISION)
+	 * </ul>
+	 * @return a field in this type with the given contents
+	 */
+	IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a static initializer in this type with the
+	 * given contents.
+	 * <p>
+	 * Optionally, the new element can be positioned before the specified
+	 * sibling. If no sibling is specified, the new initializer is positioned
+	 * after the last existing initializer declaration, or as the first member
+	 * in the type if there are no initializers.</p>
+	 *
+	 * @param contents the given contents
+	 * @param sibling the given sibling
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This element does not exist
+	 * <li> A <code>CoreException</code> occurred while updating an underlying resource
+	 * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+	 * <li> The contents could not be recognized as an initializer declaration (INVALID_CONTENTS)
+	 * <li> This type is read-only (binary) (READ_ONLY)
+	 * </ul>
+	 * @return a static initializer in this type with the given contents
+	 */
+	IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a method or constructor in this type with the
+	 * given contents.
+	 * <p>
+	 * Optionally, the new element can be positioned before the specified
+	 * sibling. If no sibling is specified, the element will be appended
+	 * to this type.
+	 *
+	 * <p>It is possible that a method with the same signature already exists in this type.
+	 * The value of the <code>force</code> parameter affects the resolution of
+	 * such a conflict:<ul>
+	 * <li> <code>true</code> - in this case the method is created with the new contents</li>
+	 * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+	 * </ul></p>
+	 *
+	 * @param contents the given contents
+	 * @param sibling the given sibling
+	 * @param force a flag in case the same name already exists in this type
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while updating an underlying resource
+	 * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+	 * <li> The contents could not be recognized as a method or constructor
+	 *		declaration (INVALID_CONTENTS)
+	 * <li> This type is read-only (binary) (READ_ONLY)
+	 * <li> There was a naming collision with an existing method (NAME_COLLISION)
+	 * </ul>
+	 * @return a method or constructor in this type with the given contents
+	 */
+	IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type in this type with the
+	 * given contents.
+	 * <p>
+	 * Optionally, the new type can be positioned before the specified
+	 * sibling. If no sibling is specified, the type will be appended
+	 * to this type.</p>
+	 *
+	 * <p>It is possible that a type with the same name already exists in this type.
+	 * The value of the <code>force</code> parameter affects the resolution of
+	 * such a conflict:<ul>
+	 * <li> <code>true</code> - in this case the type is created with the new contents</li>
+	 * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+	 * </ul></p>
+	 *
+	 * @param contents the given contents
+	 * @param sibling the given sibling
+	 * @param force a flag in case the same name already exists in this type
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if the element could not be created. Reasons include:
+	 * <ul>
+	 * <li> This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> A <code>CoreException</code> occurred while updating an underlying resource
+	 * <li> The specified sibling is not a child of this type (INVALID_SIBLING)
+	 * <li> The contents could not be recognized as a type declaration (INVALID_CONTENTS)
+	 * <li> This type is read-only (binary) (READ_ONLY)
+	 * <li> There was a naming collision with an existing field (NAME_COLLISION)
+	 * </ul>
+	 * @return a type in this type with the given contents
+	 */
+	IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Finds the methods in this type that correspond to
+	 * the given method.
+	 * A method m1 corresponds to another method m2 if:
+	 * <ul>
+	 * <li>m1 has the same element name as m2.
+	 * <li>m1 has the same number of arguments as m2 and
+	 *     the simple names of the argument types must be equals.
+	 * <li>m1 exists.
+	 * </ul>
+	 * @param method the given method
+	 * @return the found method or <code>null</code> if no such methods can be found.
+	 *
+	 * @since 2.0
+	 */
+	IMethod[] findMethods(IMethod method);
+
+	/**
+	 * Returns the children of this type that have the given category as a <code>@category</code> tag.
+	 * Returns an empty array if no children with this category exist.
+	 *
+	 * <p>
+	 * The results are listed in the order in which they appear in the source or class file.
+	 * </p>
+	 * 
+	 * @return the children for the given category.
+	 * @exception JavaModelException if this element does not exist or if an
+	 *      exception occurs while accessing its corresponding resource.
+	 *  @since 3.2
+	 */
+	IJavaElement[] getChildrenForCategory(String category) throws JavaModelException;
+
+	/**
+	 * Returns the simple name of this type, unqualified by package or enclosing type.
+	 * This is a handle-only method.
+	 *
+	 * @return the simple name of this type
+	 */
+	String getElementName();
+
+	/**
+	 * Returns the field with the specified name
+	 * in this type (for example, <code>"bar"</code>).
+	 * This is a handle-only method.  The field may or may not exist.
+	 *
+	 * @param name the given name
+	 * @return the field with the specified name in this type
+	 */
+	IField getField(String name);
+
+	/**
+	 * Returns the fields declared by this type in the order in which they appear 
+	 * in the source or class file. For binary types, this includes synthetic fields.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the fields declared by this type
+	 */
+	IField[] getFields() throws JavaModelException;
+
+	/**
+	 * Returns the fully qualified name of this type,
+	 * including qualification for any containing types and packages.
+	 * This is the name of the package, followed by <code>'.'</code>,
+	 * followed by the type-qualified name.
+	 * <p>
+	 * <b>Note</b>: The enclosing type separator used in the type-qualified
+	 * name is <code>'$'</code>, not <code>'.'</code>.
+	 * </p>
+	 * This method is fully equivalent to <code>getFullyQualifiedName('$')</code>.
+	 * This is a handle-only method.
+	 *
+	 * @see IType#getTypeQualifiedName()
+	 * @see IType#getFullyQualifiedName(char)
+	 * @return the fully qualified name of this type
+	 */
+	String getFullyQualifiedName();
+
+	/**
+	 * Returns the fully qualified name of this type,
+	 * including qualification for any containing types and packages.
+	 * This is the name of the package, followed by <code>'.'</code>,
+	 * followed by the type-qualified name using the <code>enclosingTypeSeparator</code>.
+	 *
+	 * For example:
+	 * <ul>
+	 * <li>the fully qualified name of a class B defined as a member of a class A in a compilation unit A.java
+	 *     in a package x.y using the '.' separator is "x.y.A.B"</li>
+	 * <li>the fully qualified name of a class B defined as a member of a class A in a compilation unit A.java
+	 *     in a package x.y using the '$' separator is "x.y.A$B"</li>
+	 * <li>the fully qualified name of a binary type whose class file is x/y/A$B.class
+	 *     using the '.' separator is "x.y.A.B"</li>
+	 * <li>the fully qualified name of a binary type whose class file is x/y/A$B.class
+	 *     using the '$' separator is "x.y.A$B"</li>
+	 * <li>the fully qualified name of an anonymous binary type whose class file is x/y/A$1.class
+	 *     using the '.' separator is "x.y.A.1"</li>
+	 * </ul>
+	 *
+	 * This is a handle-only method.
+	 *
+	 * @param enclosingTypeSeparator the given enclosing type separator
+	 * @return the fully qualified name of this type, including qualification for any containing types and packages
+	 * @see IType#getTypeQualifiedName(char)
+	 * @since 2.0
+	 */
+	String getFullyQualifiedName(char enclosingTypeSeparator);
+
+	/**
+	 * Returns this type's fully qualified name using a '.' enclosing type separator
+	 * followed by its type parameters between angle brackets if it is a generic type.
+	 * For example, "p.X&lt;T&gt;", "java.util.Map&lt;java.lang.String, p.X&gt;"
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *      exception occurs while accessing its corresponding resource.
+	 * @return the fully qualified parameterized representation of this type
+	 * @since 3.1
+	 */
+	String getFullyQualifiedParameterizedName() throws JavaModelException;
+
+	/**
+	 * Returns the initializer with the specified position relative to
+	 * the order they are defined in the source.
+	 * Numbering starts at 1 (thus the first occurrence is occurrence 1, not occurrence 0).
+	 * This is a handle-only method.  The initializer may or may not be present.
+	 *
+	 * @param occurrenceCount the specified position
+	 * @return the initializer with the specified position relative to the order they are defined in the source
+	 */
+	IInitializer getInitializer(int occurrenceCount);
+
+	/**
+	 * Returns the initializers declared by this type. For binary types this is an 
+	 * empty collection. For source types, the results are listed in the order in 
+	 * which they appear in the source. 
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the initializers declared by this type
+	 */
+	IInitializer[] getInitializers() throws JavaModelException;
+
+	/**
+	 * Returns the binding key for this type only if the given type is {@link #isResolved() resolved}.
+	 * A binding key is a key that uniquely identifies this type. It allows access
+	 * to generic info for parameterized types.
+	 *
+	 * <p>If the given type is not resolved, the returned key is simply the java element's key.
+	 * </p>
+	 * @return the binding key for this type
+	 * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+	 * @see BindingKey
+	 * @since 3.1
+	 * @see #isResolved()
+	 */
+	String getKey();
+
+	/**
+	 * Returns the method with the specified name and parameter types
+	 * in this type (for example, <code>"foo", {"I", "QString;"}</code>).
+	 * To get the handle for a constructor, the name specified must be the
+	 * simple name of the enclosing type.
+	 * This is a handle-only method.  The method may or may not be present.
+	 * <p>
+	 * The type signatures may be either unresolved (for source types)
+	 * or resolved (for binary types), and either basic (for basic types)
+	 * or rich (for parameterized types). See {@link Signature} for details.
+	 * </p>
+	 *
+	 * @param name the given name
+	 * @param parameterTypeSignatures the given parameter types
+	 * @return the method with the specified name and parameter types in this type
+	 */
+	IMethod getMethod(String name, String[] parameterTypeSignatures);
+
+	/**
+	 * Returns the methods and constructors declared by this type.
+	 * For binary types, this may include the special <code>&lt;clinit&gt;</code> method
+	 * and synthetic methods.
+	 * <p>
+	 * The results are listed in the order in which they appear in the source or class file. 
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the methods and constructors declared by this type
+	 */
+	IMethod[] getMethods() throws JavaModelException;
+
+	/**
+	 * Returns the package fragment in which this element is defined.
+	 * This is a handle-only method.
+	 *
+	 * @return the package fragment in which this element is defined
+	 */
+	IPackageFragment getPackageFragment();
+
+	/**
+	 * Returns the name of this type's superclass, or <code>null</code>
+	 * for source types that do not specify a superclass.
+	 * <p>
+	 * For interfaces, the superclass name is always <code>"java.lang.Object"</code>.
+	 * For source types, the name as declared is returned, for binary types,
+	 * the resolved, qualified name is returned.
+	 * For anonymous types, the superclass name is the name appearing after the 'new' keyword'.
+	 * If the superclass is a parameterized type, the string
+	 * may include its type arguments enclosed in "&lt;&gt;".
+	 * If the returned string is needed for anything other than display
+	 * purposes, use {@link #getSuperclassTypeSignature()} which returns
+	 * a structured type signature string containing more precise information.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the name of this type's superclass, or <code>null</code> for source types that do not specify a superclass
+	 */
+	String getSuperclassName() throws JavaModelException;
+
+	/**
+	 * Returns the type signature of this type's superclass, or
+	 * <code>null</code> if none.
+	 * <p>
+	 * The type signature may be either unresolved (for source types)
+	 * or resolved (for binary types), and either basic (for basic types)
+	 * or rich (for parameterized types). See {@link Signature} for details.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the type signature of this type's superclass, or
+	 * <code>null</code> if none
+	 * @since 3.0
+	 */
+	String getSuperclassTypeSignature() throws JavaModelException;
+
+	/**
+	 * Returns the type signatures of the interfaces that this type
+	 * implements or extends, in the order in which they are listed in the
+	 * source.
+	 * <p>
+	 * For classes and enum types, this gives the interfaces that this
+	 * class implements. For interfaces and annotation types,
+	 * this gives the interfaces that this interface extends.
+	 * An empty collection is returned if this type does not implement or
+	 * extend any interfaces. For anonymous types, an empty collection is
+	 * always returned.
+	 * </p>
+	 * <p>
+	 * The type signatures may be either unresolved (for source types)
+	 * or resolved (for binary types), and either basic (for basic types)
+	 * or rich (for parameterized types). See {@link Signature} for details.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return  the type signatures of interfaces that this type implements
+	 * or extends, in the order in which they are listed in the source,
+	 * an empty collection if none
+	 * @since 3.0
+	 */
+	String[] getSuperInterfaceTypeSignatures() throws JavaModelException;
+
+	/**
+	 * Returns the names of interfaces that this type implements or extends,
+	 * in the order in which they are listed in the source.
+	 * <p>
+	 * For classes, this gives the interfaces that this class implements.
+	 * For interfaces, this gives the interfaces that this interface extends.
+	 * An empty collection is returned if this type does not implement or
+	 * extend any interfaces. For source types, simple names are returned,
+	 * for binary types, qualified names are returned.
+	 * For anonymous types, an empty collection is always returned.
+	 * If the list of supertypes includes parameterized types,
+	 * the string may include type arguments enclosed in "&lt;&gt;".
+	 * If the result is needed for anything other than display
+	 * purposes, use {@link #getSuperInterfaceTypeSignatures()} which returns
+	 * structured signature strings containing more precise information.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return  the names of interfaces that this type implements or extends, in the order in which they are listed in the source,
+	 * an empty collection if none
+	 */
+	String[] getSuperInterfaceNames() throws JavaModelException;
+
+	/**
+	 * Returns the formal type parameter signatures for this type.
+	 * Returns an empty array if this type has no formal type parameters.
+	 * <p>
+	 * The formal type parameter signatures may be either unresolved (for source
+	 * types) or resolved (for binary types). See {@link Signature} for details.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *      exception occurs while accessing its corresponding resource.
+	 * @return the formal type parameter signatures of this type,
+	 * in the order declared in the source, an empty array if none
+	 * @see Signature
+	 * @since 3.0
+	 */
+	String[] getTypeParameterSignatures() throws JavaModelException;
+
+	/**
+	 * Returns the formal type parameters for this type.
+	 * Returns an empty array if this type has no formal type parameters.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *      exception occurs while accessing its corresponding resource.
+	 * @return the formal type parameters of this type,
+	 * in the order declared in the source, an empty array if none
+	 * @since 3.1
+	 */
+	ITypeParameter[] getTypeParameters() throws JavaModelException;
+
+	/**
+	 * Returns the member type declared in this type with the given simple name.
+	 * This is a handle-only method. The type may or may not exist.
+	 *
+	 * @param name the given simple name
+	 * @return the member type declared in this type with the given simple name
+	 */
+	IType getType(String name);
+
+	/**
+	 * Returns the type parameter declared in this type with the given name.
+	 * This is a handle-only method. The type parameter may or may not exist.
+	 *
+	 * @param name the given simple name
+	 * @return the type parameter declared in this type with the given name
+	 * @since 3.1
+	 */
+	ITypeParameter getTypeParameter(String name);
+
+	/**
+	 * Returns the type-qualified name of this type,
+	 * including qualification for any enclosing types,
+	 * but not including package qualification.
+	 * For source types, this consists of the simple names of any enclosing types,
+	 * separated by <code>'$'</code>, followed by the simple name of this type
+	 * or the occurrence count of this type if it is anonymous.
+	 * For binary types, this is the name of the class file without the ".class" suffix.
+	 * This method is fully equivalent to <code>getTypeQualifiedName('$')</code>.
+	 * This is a handle-only method.
+	 *
+	 * @see #getTypeQualifiedName(char)
+	 * @return the type-qualified name of this type
+	 */
+	String getTypeQualifiedName();
+
+	/**
+	 * Returns the type-qualified name of this type,
+	 * including qualification for any enclosing types,
+	 * but not including package qualification.
+	 * For source types, this consists of the simple names of any enclosing types,
+	 * separated by <code>enclosingTypeSeparator</code>, followed by the
+	 * simple name of this type  or the occurrence count of this type if it is anonymous.
+	 * For binary types, this is the name of the class file without the ".class" suffix,
+	 * and - since 3.4 - the '$' characters in the class file name are replaced with the
+	 * <code>enclosingTypeSeparator</code> character.
+	 *
+	 * For example:
+	 * <ul>
+	 * <li>the type qualified name of a class B defined as a member of a class A
+	 *     using the '.' separator is "A.B"</li>
+	 * <li>the type qualified name of a class B defined as a member of a class A
+	 *     using the '$' separator is "A$B"</li>
+	 * <li>the type qualified name of a binary type whose class file is A$B.class
+	 *     using the '.' separator is "A.B"</li>
+	 * <li>the type qualified name of a binary type whose class file is A$B.class
+	 *     using the '$' separator is "A$B"</li>
+	 * <li>the type qualified name of an anonymous binary type whose class file is A$1.class
+	 *     using the '.' separator is "A.1"</li>
+	 * </ul>
+	 *
+	 * This is a handle-only method.
+	 *
+	 * @param enclosingTypeSeparator the specified enclosing type separator
+	 * @return the type-qualified name of this type
+	 * @since 2.0
+	 */
+	String getTypeQualifiedName(char enclosingTypeSeparator);
+
+	/**
+	 * Returns the immediate member types declared by this type.
+	 * The results are listed in the order in which they appear in the source or class file.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return the immediate member types declared by this type
+	 */
+	IType[] getTypes() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents an anonymous type.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents an anonymous type, false otherwise
+	 * @since 2.0
+	 */
+	boolean isAnonymous() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents a class.
+	 * <p>
+	 * Note that a class can neither be an interface, an enumeration class, nor an annotation type.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents a class, false otherwise
+	 */
+	boolean isClass() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents an enumeration class.
+	 * <p>
+	 * Note that an enumeration class can neither be a class, an interface, nor an annotation type.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents an enumeration class,
+	 * false otherwise
+	 * @since 3.0
+	 */
+	boolean isEnum() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents an interface.
+	 * <p>
+	 * Note that an interface can also be an annotation type, but it can neither be a class nor an enumeration class.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents an interface, false otherwise
+	 */
+	boolean isInterface() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents an annotation type.
+	 * <p>
+	 * Note that an annotation type is also an interface, but it can neither be a class nor an enumeration class.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents an annotation type,
+	 * false otherwise
+	 * @since 3.0
+	 */
+	boolean isAnnotation() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents a local type. For an anonymous type, 
+	 * this method returns true.
+	 * <p>
+	 * Note: This deviates from JLS3 14.3, which states that anonymous types are 
+	 * not local types since they do not have a name.
+	 * </p>
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents a local type, false otherwise
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isLocal()
+	 * @since 2.0
+	 */
+	boolean isLocal() throws JavaModelException;
+
+	/**
+	 * Returns whether this type represents a member type.
+	 *
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return true if this type represents a member type, false otherwise
+	 * @since 2.0
+	 */
+	boolean isMember() throws JavaModelException;
+	/**
+	 * Returns whether this type represents a resolved type.
+	 * If a type is resolved, its key contains resolved information.
+	 *
+	 * @return whether this type represents a resolved type.
+	 * @since 3.1
+	 */
+	boolean isResolved();
+	/**
+	 * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
+	 * be stored using ITypeHierachy#store(OutputStream).
+	 *
+	 * Only hierarchies originally created by the following methods can be loaded:
+	 * <ul>
+	 * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
+	 * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
+	 * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
+	 * </ul>
+	 *
+	 * @param input stream where hierarchy will be read
+	 * @param monitor the given progress monitor
+	 * @return the stored hierarchy
+	 * @exception JavaModelException if the hierarchy could not be restored, reasons include:
+	 *      - type is not the focus of the hierarchy or
+	 *		- unable to read the input stream (wrong format, IOException during reading, ...)
+	 * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
+	 * @since 2.1
+	 */
+	ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException;
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type and all of its supertypes.
+	 *
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return a type hierarchy for this type containing this type and all of its supertypes
+	 */
+	ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type and all of its supertypes, considering types in the given
+	 * working copies. In other words, the list of working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing this type and all of its supertypes
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.0
+	 */
+	ITypeHierarchy newSupertypeHierarchy(ICompilationUnit[] workingCopies, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type and all of its supertypes, considering types in the given
+	 * working copies. In other words, the list of working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing this type and all of its supertypes
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 2.0
+	 * @deprecated Use {@link #newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)} instead
+	 */
+	ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type and all of its supertypes, considering types in the
+	 * working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing this type and all of its supertypes
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.0
+	 */
+	ITypeHierarchy newSupertypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes
+	 * in the context of the given project.
+	 *
+	 * @param project the given project
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes
+	 * in the context of the given project
+	 */
+	ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes
+	 * in the context of the given project, considering types in the
+	 * working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param project the given project
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes
+	 * in the context of the given project
+	 * @since 3.0
+	 */
+	ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace.
+	 *
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace
+	 */
+	ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace,
+	 * considering types in the given working copies. In other words, the list of working
+	 * copies that will take precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.0
+	 */
+	ITypeHierarchy newTypeHierarchy(ICompilationUnit[] workingCopies, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace,
+	 * considering types in the given working copies. In other words, the list of working
+	 * copies that will take precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 2.0
+	 * @deprecated Use {@link #newTypeHierarchy(ICompilationUnit[], IProgressMonitor)} instead
+	 */
+	ITypeHierarchy newTypeHierarchy(IWorkingCopy[] workingCopies, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Creates and returns a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace,
+	 * considering types in the working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the given progress monitor
+	 * @return a type hierarchy for this type containing
+	 * this type, all of its supertypes, and all its subtypes in the workspace
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.0
+	 */
+	ITypeHierarchy newTypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Resolves the given type name within the context of this type (depending on the type hierarchy
+	 * and its imports).
+	 * <p>
+	 * Multiple answers might be found in case there are ambiguous matches.
+	 * </p>
+	 * <p>
+	 * Each matching type name is decomposed as an array of two strings, the first denoting the package
+	 * name (dot-separated) and the second being the type name. The package name is empty if it is the
+	 * default package. The type name is the type qualified name using a '.' enclosing type separator.
+	 * </p>
+	 * <p>
+	 * Returns <code>null</code> if unable to find any matching type.
+	 * </p>
+	 *<p>
+	 * For example, resolution of <code>"Object"</code> would typically return
+	 * <code>{{"java.lang", "Object"}}</code>. Another resolution that returns
+	 * <code>{{"", "X.Inner"}}</code> represents the inner type Inner defined in type X in the
+	 * default package.
+	 * </p>
+	 *
+	 * @param typeName the given type name
+	 * @exception JavaModelException if code resolve could not be performed.
+	 * @return the resolved type names or <code>null</code> if unable to find any matching type
+	 * @see #getTypeQualifiedName(char)
+	 */
+	String[][] resolveType(String typeName) throws JavaModelException;
+
+	/**
+	 * Resolves the given type name within the context of this type (depending on the type hierarchy
+	 * and its imports) and using the given owner's working copies, considering types in the
+	 * working copies with the given owner. In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>Multiple answers might be found in case there are ambiguous matches.
+	 * </p>
+	 * <p>
+	 * Each matching type name is decomposed as an array of two strings, the first denoting the package
+	 * name (dot-separated) and the second being the type name. The package name is empty if it is the
+	 * default package. The type name is the type qualified name using a '.' enclosing type separator.
+	 * </p>
+	 * <p>
+	 * Returns <code>null</code> if unable to find any matching type.
+	 *</p>
+	 *<p>
+	 * For example, resolution of <code>"Object"</code> would typically return
+	 * <code>{{"java.lang", "Object"}}</code>. Another resolution that returns
+	 * <code>{{"", "X.Inner"}}</code> represents the inner type Inner defined in type X in the
+	 * default package.
+	 * </p>
+	 *
+	 * @param typeName the given type name
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code resolve could not be performed.
+	 * @return the resolved type names or <code>null</code> if unable to find any matching type
+	 * @see #getTypeQualifiedName(char)
+	 * @since 3.0
+	 */
+	String[][] resolveType(String typeName, WorkingCopyOwner owner) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java
new file mode 100644
index 0000000..51f0755
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.OutputStream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * A type hierarchy provides navigations between a type and its resolved
+ * supertypes and subtypes for a specific type or for all types within a region.
+ * Supertypes may extend outside of the type hierarchy's region in which it was
+ * created such that the root of the hierarchy is always included. For example, if a type
+ * hierarchy is created for a <code>java.io.File</code>, and the region the hierarchy was
+ * created in is the package fragment <code>java.io</code>, the supertype
+ * <code>java.lang.Object</code> will still be included. As a historical quirk,
+ * <code>java.lang.Object</code> has always been included in type hierarchies
+ * created on interface types.
+ * <p>
+ * A type hierarchy is static and can become stale. Although consistent when
+ * created, it does not automatically track changes in the model.
+ * As changes in the model potentially invalidate the hierarchy, change notifications
+ * are sent to registered <code>ITypeHierarchyChangedListener</code>s. Listeners should
+ * use the <code>exists</code> method to determine if the hierarchy has become completely
+ * invalid (for example, when the type or project the hierarchy was created on
+ * has been removed). To refresh a hierarchy, use the <code>refresh</code> method.
+ * </p>
+ * <p>
+ * The type hierarchy may contain cycles due to malformed supertype declarations.
+ * Most type hierarchy queries are oblivious to cycles; the <code>getAll* </code>
+ * methods are implemented such that they are unaffected by cycles.
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITypeHierarchy {
+/**
+ * Adds the given listener for changes to this type hierarchy. Listeners are
+ * notified when this type hierarchy changes and needs to be refreshed.
+ * Has no effect if an identical listener is already registered.
+ *
+ * @param listener the listener
+ */
+void addTypeHierarchyChangedListener(ITypeHierarchyChangedListener listener);
+/**
+ * Returns whether the given type is part of this hierarchy.
+ *
+ * @param type the given type
+ * @return true if the given type is part of this hierarchy, false otherwise
+ */
+boolean contains(IType type);
+/**
+ * Returns whether the type and project this hierarchy was created on exist.
+ * @return true if the type and project this hierarchy was created on exist, false otherwise
+ */
+boolean exists();
+/**
+ * Returns all classes in this type hierarchy's graph, in no particular
+ * order. Any classes in the creation region which were not resolved to
+ * have any subtypes or supertypes are not included in the result.
+ *
+ * @return all classes in this type hierarchy's graph
+ */
+IType[] getAllClasses();
+/**
+ * Returns all interfaces in this type hierarchy's graph, in no particular
+ * order. Any interfaces in the creation region which were not resolved to
+ * have any subtypes or supertypes are not included in the result.
+ *
+ * @return all interfaces in this type hierarchy's graph
+ */
+IType[] getAllInterfaces();
+/**
+ * Returns all resolved subtypes (direct and indirect) of the
+ * given type, in no particular order, limited to the
+ * types in this type hierarchy's graph. An empty array
+ * is returned if there are no resolved subtypes for the
+ * given type.
+ *
+ * @param type the given type
+ * @return all resolved subtypes (direct and indirect) of the given type
+ */
+IType[] getAllSubtypes(IType type);
+/**
+ * Returns all resolved superclasses of the
+ * given class, in bottom-up order. An empty array
+ * is returned if there are no resolved superclasses for the
+ * given class.
+ *
+ * <p>NOTE: once a type hierarchy has been created, it is more efficient to
+ * query the hierarchy for superclasses than to query a class recursively up
+ * the superclass chain. Querying an element performs a dynamic resolution,
+ * whereas the hierarchy returns a pre-computed result.
+ *
+ * @param type the given type
+ * @return all resolved superclasses of the given class, in bottom-up order, an empty
+ * array if none.
+ */
+IType[] getAllSuperclasses(IType type);
+/**
+ * Returns all resolved superinterfaces (direct and indirect) of the given type.
+ * If the given type is a class, this includes all superinterfaces of all superclasses.
+ * An empty array is returned if there are no resolved superinterfaces for the
+ * given type.
+ *
+ * <p>NOTE: once a type hierarchy has been created, it is more efficient to
+ * query the hierarchy for superinterfaces than to query a type recursively.
+ * Querying an element performs a dynamic resolution,
+ * whereas the hierarchy returns a pre-computed result.
+ *
+ * @param type the given type
+ * @return all resolved superinterfaces (direct and indirect) of the given type, an empty array if none
+ */
+IType[] getAllSuperInterfaces(IType type);
+/**
+ * Returns all resolved supertypes of the
+ * given type, in bottom-up order. An empty array
+ * is returned if there are no resolved supertypes for the
+ * given type.
+ * <p>
+ * Note that <code>java.lang.Object</code> is NOT considered to be a supertype
+ * of any interface type.
+ * </p><p>NOTE: once a type hierarchy has been created, it is more efficient to
+ * query the hierarchy for supertypes than to query a type recursively up
+ * the supertype chain. Querying an element performs a dynamic resolution,
+ * whereas the hierarchy returns a pre-computed result.
+ *
+ * @param type the given type
+ * @return all resolved supertypes of the given class, in bottom-up order, an empty array
+ * if none
+ */
+IType[] getAllSupertypes(IType type);
+/**
+ * Returns all types in this type hierarchy's graph, in no particular
+ * order. Any types in the creation region which were not resolved to
+ * have any subtypes or supertypes are not included in the result.
+ *
+ * @return all types in this type hierarchy's graph
+ */
+IType[] getAllTypes();
+
+/**
+ * Return the flags associated with the given type (would be equivalent to <code>IMember.getFlags()</code>),
+ * or <code>-1</code> if this information wasn't cached on the hierarchy during its computation.
+ *
+ * @param type the given type
+ * @return the modifier flags for this member
+ * @see Flags
+ * @since 2.0
+ */
+int getCachedFlags(IType type);
+
+/**
+ * Returns all interfaces resolved to extend the given interface,
+ * in no particular order, limited to the interfaces in this
+ * hierarchy's graph.
+ * Returns an empty collection if the given type is a class, or
+ * if no interfaces were resolved to extend the given interface.
+ *
+ * @param type the given type
+ * @return all interfaces resolved to extend the given interface limited to the interfaces in this
+ * hierarchy's graph, an empty array if none.
+ */
+IType[] getExtendingInterfaces(IType type);
+/**
+ * Returns all classes resolved to implement the given interface,
+ * in no particular order, limited to the classes in this type
+ * hierarchy's  graph. Returns an empty collection if the given type is a
+ * class, or if no classes were resolved to implement the given
+ * interface.
+ *
+ * @param type the given type
+ * @return all classes resolved to implement the given interface limited to the classes in this type
+ * hierarchy's  graph, an empty array if none
+ */
+IType[] getImplementingClasses(IType type);
+/**
+ * Returns all classes in the graph which have no resolved superclass,
+ * in no particular order.
+ *
+ * @return all classes in the graph which have no resolved superclass
+ */
+IType[] getRootClasses();
+/**
+ * Returns all interfaces in the graph which have no resolved superinterfaces,
+ * in no particular order.
+ *
+ * @return all interfaces in the graph which have no resolved superinterfaces
+ */
+IType[] getRootInterfaces();
+/**
+ * Returns the direct resolved subclasses of the given class,
+ * in no particular order, limited to the classes in this
+ * type hierarchy's graph.
+ * Returns an empty collection if the given type is an interface,
+ * or if no classes were resolved to be subclasses of the given
+ * class.
+ *
+ * @param type the given type
+ * @return the direct resolved subclasses of the given class limited to the classes in this
+ * type hierarchy's graph, an empty collection if none.
+ */
+IType[] getSubclasses(IType type);
+/**
+ * Returns the direct resolved subtypes of the given type,
+ * in no particular order, limited to the types in this
+ * type hierarchy's graph.
+ * If the type is a class, this returns the resolved subclasses.
+ * If the type is an interface, this returns both the classes which implement
+ * the interface and the interfaces which extend it.
+ *
+ * @param type the given type
+ * @return the direct resolved subtypes of the given type limited to the types in this
+ * type hierarchy's graph
+ */
+IType[] getSubtypes(IType type);
+/**
+ * Returns the resolved superclass of the given class,
+ * or <code>null</code> if the given class has no superclass,
+ * the superclass could not be resolved, or if the given
+ * type is an interface.
+ *
+ * @param type the given type
+ * @return the resolved superclass of the given class,
+ * or <code>null</code> if the given class has no superclass,
+ * the superclass could not be resolved, or if the given
+ * type is an interface
+ */
+IType getSuperclass(IType type);
+/**
+ * Returns the direct resolved interfaces that the given type implements or extends,
+ * in no particular order, limited to the interfaces in this type
+ * hierarchy's graph.
+ * For classes, this gives the interfaces that the class implements.
+ * For interfaces, this gives the interfaces that the interface extends.
+ *
+ * @param type the given type
+ * @return the direct resolved interfaces that the given type implements or extends limited to the interfaces in this type
+ * hierarchy's graph
+ */
+IType[] getSuperInterfaces(IType type);
+/**
+ * Returns the resolved supertypes of the given type,
+ * in no particular order, limited to the types in this
+ * type hierarchy's graph.
+ * For classes, this returns its superclass and the interfaces that the class implements.
+ * For interfaces, this returns the interfaces that the interface extends. As a consequence
+ * <code>java.lang.Object</code> is NOT considered to be a supertype of any interface
+ * type.
+ *
+ * @param type the given type
+ * @return the resolved supertypes of the given type limited to the types in this
+ * type hierarchy's graph
+ */
+IType[] getSupertypes(IType type);
+/**
+ * Returns the type this hierarchy was computed for.
+ * Returns <code>null</code> if this hierarchy was computed for a region.
+ *
+ * @return the type this hierarchy was computed for
+ */
+IType getType();
+/**
+ * Re-computes the type hierarchy reporting progress.
+ *
+ * @param monitor the given progress monitor
+ * @exception JavaModelException if unable to refresh the hierarchy
+ */
+void refresh(IProgressMonitor monitor) throws JavaModelException;
+/**
+ * Removes the given listener from this type hierarchy.
+ * Has no effect if an identical listener is not registered.
+ *
+ * @param listener the listener
+ */
+void removeTypeHierarchyChangedListener(ITypeHierarchyChangedListener listener);
+/**
+ * Stores the type hierarchy in an output stream. This stored hierarchy can be load by
+ * IType#loadTypeHierachy(IJavaProject, InputStream, IProgressMonitor).
+ * Listeners of this hierarchy are not stored.
+ *
+ * Only hierarchies created by the following methods can be store:
+ * <ul>
+ * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
+ * </ul>
+ *
+ * @param outputStream output stream where the hierarchy will be stored
+ * @param monitor the given progress monitor
+ * @exception JavaModelException if unable to store the hierarchy in the ouput stream
+ * @see IType#loadTypeHierachy(java.io.InputStream, IProgressMonitor)
+ * @since 2.1
+ */
+void store(OutputStream outputStream, IProgressMonitor monitor) throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java
new file mode 100644
index 0000000..5d52f8f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A listener which gets notified when a particular type hierarchy object
+ * changes.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ */
+public interface ITypeHierarchyChangedListener {
+	/**
+	 * Notifies that the given type hierarchy has changed in some way and should
+	 * be refreshed at some point to make it consistent with the current state of
+	 * the Java model.
+	 *
+	 * @param typeHierarchy the given type hierarchy
+	 */
+	void typeHierarchyChanged(ITypeHierarchy typeHierarchy);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java
new file mode 100644
index 0000000..3fe8d1b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+
+/**
+ * Represents a type parameter defined by a type or a method
+ * in a compilation unit or a class file.
+ * <p>
+ * Type parameters are obtained using {@link IType#getTypeParameter(String)} and
+ * {@link IMethod#getTypeParameter(String)}.
+ * </p><p>
+ * Note that type parameters are not children of their declaring type or method. To get a list
+ * of the type parameters use {@link IType#getTypeParameters()} for a type and use
+ * {@link IMethod#getTypeParameters()} for a method.
+ * </p>
+ *
+ * @since 3.1
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITypeParameter extends IJavaElement, ISourceReference {
+
+	/**
+	 * Returns the names of the class and interface bounds of this type parameter. Returns an empty
+	 * array if this type parameter has no bounds. A bound name is the name as it appears in the
+	 * source (without the <code>extends</code> keyword) if the type parameter comes from a
+	 * compilation unit. It is the dot-separated fully qualified name of the bound if the type
+	 * parameter comes from a class file.
+	 *
+	 * @return the names of the bounds
+	 * @throws JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 */
+	String[] getBounds() throws JavaModelException;
+
+	/**
+	 * 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;
+	
+	/**
+	 * Returns the declaring member of this type parameter. This can be either an <code>IType</code>
+	 * or an <code>IMethod</code>.
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return the declaring member of this type parameter.
+	 */
+	IMember getDeclaringMember();
+
+	/**
+	 * Returns the Java type root in which this type parameter is declared.
+	 * <p>
+	 * This is a handle-only method.
+	 * </p>
+	 *
+	 * @return the Java type root in which this type parameter is declared
+	 * @since 3.7
+	 */
+	ITypeRoot getTypeRoot();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeRoot.java
new file mode 100644
index 0000000..97ebff6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeRoot.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+
+/**
+ * Represents an entire Java type root (either an <code>ICompilationUnit</code>
+ * or an <code>IClassFile</code>).
+ *
+ * @see ICompilationUnit Note that methods {@link #findPrimaryType()} and {@link #getElementAt(int)}
+ * 	were already implemented in this interface respectively since version 3.0 and version 1.0.
+ * @see IClassFile Note that method {@link #getWorkingCopy(WorkingCopyOwner, IProgressMonitor)}
+ * 	was already implemented in this interface since version 3.0.
+ * @since 3.3
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITypeRoot extends IJavaElement, IParent, IOpenable, ISourceReference, ICodeAssist {
+
+/**
+ * Finds the primary type of this Java type root (that is, the type with the same name as the
+ * compilation unit, or the type of a class file), or <code>null</code> if no such a type exists.
+ *
+ * @return the found primary type of this Java type root, or <code>null</code> if no such a type exists
+ */
+IType findPrimaryType();
+
+/**
+ * Returns the smallest element within this Java type root that
+ * includes the given source position (that is, a method, field, etc.), or
+ * <code>null</code> if there is no element other than the Java type root
+ * itself at the given position, or if the given position is not
+ * within the source range of the source of this Java type root.
+ *
+ * @param position a source position inside the Java type root
+ * @return the innermost Java element enclosing a given source position or <code>null</code>
+ *	if none (excluding the Java type root).
+ * @throws JavaModelException if the Java type root does not exist or if an
+ *	exception occurs while accessing its corresponding resource
+ */
+IJavaElement getElementAt(int position) throws JavaModelException;
+
+/**
+ * Returns a shared working copy on this compilation unit or class file using the given working copy owner to create
+ * the buffer. If this is already a working copy of the given owner, the element itself is returned.
+ * This API can only answer an already existing working copy if it is based on the same
+ * original Java type root AND was using the same working copy owner (that is, as defined by {@link Object#equals}).
+ * <p>
+ * The life time of a shared working copy is as follows:
+ * <ul>
+ * <li>The first call to {@link #getWorkingCopy(WorkingCopyOwner, IProgressMonitor)}
+ * 	creates a new working copy for this element</li>
+ * <li>Subsequent calls increment an internal counter.</li>
+ * <li>A call to {@link ICompilationUnit#discardWorkingCopy()} decrements the internal counter.</li>
+ * <li>When this counter is 0, the working copy is discarded.
+ * </ul>
+ * So users of this method must discard exactly once the working copy.
+ * <p>
+ * Note that the working copy owner will be used for the life time of the shared working copy, that is if the
+ * working copy is closed then reopened, this owner will be used.
+ * The buffer will be automatically initialized with the original's Java type root content upon creation.
+ * <p>
+ * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+ * working copy.
+ * </p><p>
+ * A working copy can be created on a not-yet existing compilation unit.
+ * In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * </p><p>
+ * Note that possible problems of this working copy are reported using this method only
+ * if the given working copy owner returns a problem requestor for this working copy
+ * (see {@link WorkingCopyOwner#getProblemRequestor(ICompilationUnit)}).
+ * </p>
+ *
+ * @param owner the working copy owner that creates a buffer that is used to get the content
+ * 				of the working copy
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ *                 or <code>null</code> if no progress should be reported
+ * @throws JavaModelException if the contents of this element can
+ *   	not be determined.
+ * @return a new working copy of this Java type root using the given owner to create
+ *		the buffer, or this Java type root if it is already a working copy
+ */
+ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java
new file mode 100644
index 0000000..e7537ea
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Common protocol for Java elements that support working copies.
+ * <p>
+ * A working copy of a Java element acts just like a regular element (handle),
+ * except it is not attached to an underlying resource. A working copy is not
+ * visible to the rest of the Java model. Changes in a working copy's
+ * buffer are not realized in a resource. To bring the Java model up-to-date with a working
+ * copy's contents, an explicit commit must be performed on the working copy.
+ * Other operations performed on a working copy update the
+ * contents of the working copy's buffer but do not commit the contents
+ * of the working copy.
+ * </p>
+ * <p>
+ * Note: The contents of a working copy is determined when a working
+ * copy is created, based on the current content of the element the working
+ * copy is created from. If a working copy is an <code>IOpenable</code> and is explicitly
+ * closed, the working copy's buffer will be thrown away. However, clients should not
+ * explicitly open and close working copies.
+ * </p>
+ * <p>
+ * The client that creates a working copy is responsible for
+ * destroying the working copy. The Java model will never automatically
+ * destroy or close a working copy. (Note that destroying a working copy
+ * does not commit it to the model, it only frees up the memory occupied by
+ * the element). After a working copy is destroyed, the working copy cannot
+ * be accessed again. Non-handle methods will throw a
+ * <code>JavaModelException</code> indicating the Java element does not exist.
+ * </p>
+ * <p>
+ * A working copy cannot be created from another working copy.
+ * Calling <code>getWorkingCopy</code> on a working copy returns the receiver.
+ * </p>
+ *
+ * @deprecated Use {@link ICompilationUnit} instead
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IWorkingCopy {
+
+	/**
+	 * Commits the contents of this working copy to its original element
+	 * and underlying resource, bringing the Java model up-to-date with
+	 * the current contents of the working copy.
+	 *
+	 * <p>It is possible that the contents of the original resource have changed
+	 * since this working copy was created, in which case there is an update conflict.
+	 * The value of the <code>force</code> parameter affects the resolution of
+	 * such a conflict:<ul>
+	 * <li> <code>true</code> - in this case the contents of this working copy are applied to
+	 * 	the underlying resource even though this working copy was created before
+	 *	a subsequent change in the resource</li>
+	 * <li> <code>false</code> - in this case a <code>JavaModelException</code> is thrown</li>
+	 * </ul>
+	 * <p>
+	 * Since 2.1, a working copy can be created on a not-yet existing compilation
+	 * unit. In particular, such a working copy can then be committed in order to create
+	 * the corresponding compilation unit.
+	 * </p>
+	 * @param force a flag to handle the cases when the contents of the original resource have changed
+	 * since this working copy was created
+	 * @param monitor the given progress monitor
+	 * @exception JavaModelException if this working copy could not commit. Reasons include:
+	 * <ul>
+	 * <li> A <code>CoreException</code> occurred while updating an underlying resource
+	 * <li> This element is not a working copy (INVALID_ELEMENT_TYPES)
+	 * <li> A update conflict (described above) (UPDATE_CONFLICT)
+	 * </ul>
+	 * @deprecated Use {@link ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)} instead.
+	 */
+	void commit(boolean force, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Destroys this working copy, closing its buffer and discarding
+	 * its structure. Subsequent attempts to access non-handle information
+	 * for this working copy will result in <code>IJavaModelException</code>s. Has
+	 * no effect if this element is not a working copy.
+	 * <p>
+	 * If this working copy is shared, it is destroyed only when the number of calls to
+	 * <code>destroy()</code> is the same as the number of calls to <code>
+	 * getSharedWorkingCopy(IProgressMonitor, IBufferFactory)</code>.
+	 * </p><p>
+	 * When it is destroyed, a REMOVED IJavaElementDelta is reported on this
+	 * working copy.
+	 * </p>
+	 * @deprecated Use {@link ICompilationUnit#discardWorkingCopy()} instead.
+	 */
+	void destroy();
+
+	/**
+	 * Finds the shared working copy for this element, given a <code>IBuffer</code> factory.
+	 * If no working copy has been created for this element associated with this
+	 * buffer factory, returns <code>null</code>.
+	 * <p>
+	 * Users of this method must not destroy the resulting working copy.
+	 *
+	 * @param bufferFactory the given <code>IBuffer</code> factory
+	 * @return the found shared working copy for this element, <code>null</code> if none
+	 * @see IBufferFactory
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ICompilationUnit#findWorkingCopy(WorkingCopyOwner)} instead.
+	 */
+	IJavaElement findSharedWorkingCopy(IBufferFactory bufferFactory);
+
+	/**
+	 * Returns the original element the specified working copy element was created from,
+	 * or <code>null</code> if this is not a working copy element.  This is a handle
+	 * only method, the returned element may or may not exist.
+	 *
+	 * @param workingCopyElement the specified working copy element
+	 * @return the original element the specified working copy element was created from,
+	 * or <code>null</code> if this is not a working copy element
+	 *
+	 * @deprecated Use {@link IJavaElement#getPrimaryElement()} instead.
+	 */
+	IJavaElement getOriginal(IJavaElement workingCopyElement);
+
+	/**
+	 * Returns the original element this working copy was created from,
+	 * or <code>null</code> if this is not a working copy.
+	 *
+	 * @return the original element this working copy was created from,
+	 * or <code>null</code> if this is not a working copy
+	 *
+	 * @deprecated Use {@link ICompilationUnit#getPrimaryElement()} instead.
+	 */
+	IJavaElement getOriginalElement();
+
+	/**
+	 * Finds the elements in this compilation unit that correspond to
+	 * the given element.
+	 * An element A corresponds to an element B if:
+	 * <ul>
+	 * <li>A has the same element name as B.
+	 * <li>If A is a method, A must have the same number of arguments as
+	 *     B and the simple names of the argument types must be equals.
+	 * <li>The parent of A corresponds to the parent of B recursively up to
+	 *     their respective compilation units.
+	 * <li>A exists.
+	 * </ul>
+	 * Returns <code>null</code> if no such java elements can be found
+	 * or if the given element is not included in a compilation unit.
+	 *
+	 * @param element the given element
+	 * @return the found elements in this compilation unit that correspond to the given element
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ICompilationUnit#findElements(IJavaElement)} instead.
+	 */
+	IJavaElement[] findElements(IJavaElement element);
+
+	/**
+	 * Finds the primary type of this compilation unit (that is, the type with the same name as the
+	 * compilation unit), or <code>null</code> if no such a type exists.
+	 *
+	 * @return the found primary type of this compilation unit, or <code>null</code> if no such a type exists
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ITypeRoot#findPrimaryType()} instead.
+	 */
+	IType findPrimaryType();
+
+	/**
+	 * Returns a shared working copy on this element using the given factory to create
+	 * the buffer, or this element if this element is already a working copy.
+	 * This API can only answer an already existing working copy if it is based on the same
+	 * original compilation unit AND was using the same buffer factory (that is, as defined by <code>Object.equals</code>).
+	 * <p>
+	 * The life time of a shared working copy is as follows:
+	 * <ul>
+	 * <li>The first call to <code>getSharedWorkingCopy(...)</code> creates a new working copy for this
+	 *     element</li>
+	 * <li>Subsequent calls increment an internal counter.</li>
+	 * <li>A call to <code>destroy()</code> decrements the internal counter.</li>
+	 * <li>When this counter is 0, the working copy is destroyed.
+	 * </ul>
+	 * So users of this method must destroy exactly once the working copy.
+	 * <p>
+	 * Note that the buffer factory will be used for the life time of this working copy, that is if the
+	 * working copy is closed then reopened, this factory will be used.
+	 * The buffer will be automatically initialized with the original's compilation unit content
+	 * upon creation.
+	 * <p>
+	 * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+	 * working copy.
+	 *
+	 * @param monitor a progress monitor used to report progress while opening this compilation unit
+	 *                 or <code>null</code> if no progress should be reported
+	 * @param factory the factory that creates a buffer that is used to get the content of the working copy
+	 *                 or <code>null</code> if the internal factory should be used
+	 * @param problemRequestor a requestor which will get notified of problems detected during
+	 * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+	 * 	that the client is not interested in problems.
+	 * @exception JavaModelException if the contents of this element can
+	 *   not be determined.
+	 * @return a shared working copy on this element using the given factory to create
+	 * the buffer, or this element if this element is already a working copy
+	 * @see IBufferFactory
+	 * @see IProblemRequestor
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)} instead.
+	 */
+	IJavaElement getSharedWorkingCopy(
+		IProgressMonitor monitor,
+		IBufferFactory factory,
+		IProblemRequestor problemRequestor)
+		throws JavaModelException;
+
+	/**
+	 * Returns a new working copy of this element if this element is not
+	 * a working copy, or this element if this element is already a working copy.
+	 * <p>
+	 * Note: if intending to share a working copy amongst several clients, then
+	 * <code>#getSharedWorkingCopy</code> should be used instead.
+	 * </p><p>
+	 * When the working copy instance is created, an ADDED IJavaElementDelta is
+	 * reported on this working copy.
+	 * </p><p>
+	 * Since 2.1, a working copy can be created on a not-yet existing compilation
+	 * unit. In particular, such a working copy can then be committed in order to create
+	 * the corresponding compilation unit.
+	 * </p>
+	 * @exception JavaModelException if the contents of this element can
+	 *   not be determined.
+	 * @return a new working copy of this element if this element is not
+	 * a working copy, or this element if this element is already a working copy
+	 *
+	 * @deprecated Use {@link ICompilationUnit#getWorkingCopy(IProgressMonitor)} instead.
+	 */
+	IJavaElement getWorkingCopy() throws JavaModelException;
+
+	/**
+	 * Returns a new working copy of this element using the given factory to create
+	 * the buffer, or this element if this element is already a working copy.
+	 * Note that this factory will be used for the life time of this working copy, that is if the
+	 * working copy is closed then reopened, this factory will be reused.
+	 * The buffer will be automatically initialized with the original's compilation unit content
+	 * upon creation.
+	 * <p>
+	 * Note: if intending to share a working copy amongst several clients, then
+	 * <code>#getSharedWorkingCopy</code> should be used instead.
+	 * </p><p>
+	 * When the working copy instance is created, an ADDED IJavaElementDelta is
+	 * reported on this working copy.
+	 * </p><p>
+	 * Since 2.1, a working copy can be created on a not-yet existing compilation
+	 * unit. In particular, such a working copy can then be committed in order to create
+	 * the corresponding compilation unit.
+	 * </p>
+	 * @param monitor a progress monitor used to report progress while opening this compilation unit
+	 *                 or <code>null</code> if no progress should be reported
+	 * @param factory the factory that creates a buffer that is used to get the content of the working copy
+	 *                 or <code>null</code> if the internal factory should be used
+	 * @param problemRequestor a requestor which will get notified of problems detected during
+	 * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+	 * 	that the client is not interested in problems.
+	 * @exception JavaModelException if the contents of this element can
+	 *   not be determined.
+	 * @return a new working copy of this element using the given factory to create
+	 * the buffer, or this element if this element is already a working copy
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)} instead.
+	 */
+	IJavaElement getWorkingCopy(
+		IProgressMonitor monitor,
+		IBufferFactory factory,
+		IProblemRequestor problemRequestor)
+		throws JavaModelException;
+
+	/**
+	 * Returns whether this working copy's original element's content
+	 * has not changed since the inception of this working copy.
+	 *
+	 * @param resource this working copy's resource
+	 * @return true if this working copy's original element's content
+	 * has not changed since the inception of this working copy, false otherwise
+	 *
+	 * @deprecated Use {@link ICompilationUnit#hasResourceChanged()} instead.
+	 */
+	boolean isBasedOn(IResource resource);
+
+	/**
+	 * Returns whether this element is a working copy.
+	 *
+	 * @return true if this element is a working copy, false otherwise
+	 *
+	 * @deprecated Use {@link ICompilationUnit#isWorkingCopy()} instead.
+	 */
+	boolean isWorkingCopy();
+
+	/**
+	 * Reconciles the contents of this working copy.
+	 * It performs the reconciliation by locally caching the contents of
+	 * the working copy, updating the contents, then creating a delta
+	 * over the cached contents and the new contents, and finally firing
+	 * this delta.
+	 * <p>
+	 * If the working copy hasn't changed, then no problem will be detected,
+	 * this is equivalent to <code>IWorkingCopy#reconcile(false, null)</code>.</p>
+	 * <p>
+	 * Compilation problems found in the new contents are notified through the
+	 * <code>IProblemRequestor</code> interface which was passed at
+	 * creation, and no longer as transient markers. Therefore this API will
+	 * return <code>null</code>.</p>
+	 * <p>
+ 	 * Note: Since 3.0 added/removed/changed inner types generate change deltas.</p>
+	 *
+	 * @exception JavaModelException if the contents of the original element
+	 *		cannot be accessed. Reasons include:
+	 * <ul>
+	 * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * </ul>
+	 * @return <code>null</code>
+	 *
+	 * @deprecated Use {@link ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)} instead.
+	 */
+	IMarker[] reconcile() throws JavaModelException;
+
+	/**
+	 * Reconciles the contents of this working copy.
+	 * It performs the reconciliation by locally caching the contents of
+	 * the working copy, updating the contents, then creating a delta
+	 * over the cached contents and the new contents, and finally firing
+	 * this delta.
+	 * <p>
+	 * The boolean argument allows to force problem detection even if the
+	 * working copy is already consistent.</p>
+	 * <p>
+	 * Compilation problems found in the new contents are notified through the
+	 * <code>IProblemRequestor</code> interface which was passed at
+	 * creation, and no longer as transient markers. Therefore this API answers
+	 * nothing.</p>
+	 * <p>
+ 	 * Note: Since 3.0 added/removed/changed inner types generate change deltas.</p>
+	 *
+	 * @param forceProblemDetection boolean indicating whether problem should be recomputed
+	 *   even if the source hasn't changed.
+	 * @param monitor a progress monitor
+	 * @exception JavaModelException if the contents of the original element
+	 *		cannot be accessed. Reasons include:
+	 * <ul>
+	 * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * </ul>
+	 * @since 2.0
+	 *
+	 * @deprecated Use {@link ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)} instead.
+	 */
+	void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException;
+
+	/**
+	 * Restores the contents of this working copy to the current contents of
+	 * this working copy's original element. Has no effect if this element
+	 * is not a working copy.
+	 *
+	 * <p>Note: This is the inverse of committing the content of the
+	 * working copy to the original element with <code>commit(boolean, IProgressMonitor)</code>.
+	 *
+	 * @exception JavaModelException if the contents of the original element
+	 *		cannot be accessed.  Reasons include:
+	 * <ul>
+	 * <li> The original Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * </ul>
+	 * @deprecated Use {@link ICompilationUnit#restore()} instead.
+	 */
+	void restore() throws JavaModelException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
new file mode 100644
index 0000000..79c9b69
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
@@ -0,0 +1,820 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.StringTokenizer;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * Provides methods for checking Java-specific conventions such as name syntax.
+ * <p>
+ * This class provides static methods and constants only.
+ * </p>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class JavaConventions {
+
+	private static final char DOT= '.';
+	private static final String PACKAGE_INFO = new String(TypeConstants.PACKAGE_INFO_NAME);
+	private static final Scanner SCANNER = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
+
+	private JavaConventions() {
+		// Not instantiable
+	}
+
+	/**
+	 * Returns whether the given package fragment root paths are considered
+	 * to overlap.
+	 * <p>
+	 * Two root paths overlap if one is a prefix of the other, or they point to
+	 * the same location. However, a JAR is allowed to be nested in a root.
+	 *
+	 * @param rootPath1 the first root path
+	 * @param rootPath2 the second root path
+	 * @return true if the given package fragment root paths are considered to overlap, false otherwise
+	 * @deprecated Overlapping roots are allowed in 2.1
+	 */
+	public static boolean isOverlappingRoots(IPath rootPath1, IPath rootPath2) {
+		if (rootPath1 == null || rootPath2 == null) {
+			return false;
+		}
+		return rootPath1.isPrefixOf(rootPath2) || rootPath2.isPrefixOf(rootPath1);
+	}
+
+	/*
+	 * Returns the current identifier extracted by the scanner (without unicode
+	 * escapes) from the given id and for the given source and compliance levels.
+	 * Returns <code>null</code> if the id was not valid
+	 */
+	private static synchronized char[] scannedIdentifier(String id, String sourceLevel, String complianceLevel) {
+		if (id == null) {
+			return null;
+		}
+		// Set scanner for given source and compliance levels
+		SCANNER.sourceLevel = sourceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(sourceLevel);
+		SCANNER.complianceLevel = complianceLevel == null ? ClassFileConstants.JDK1_3 : CompilerOptions.versionToJdkLevel(complianceLevel);
+
+		try {
+			SCANNER.setSource(id.toCharArray());
+			int token = SCANNER.scanIdentifier();
+			if (token != TerminalTokens.TokenNameIdentifier) return null;
+			if (SCANNER.currentPosition == SCANNER.eofPosition) { // to handle case where we had an ArrayIndexOutOfBoundsException
+				try {
+					return SCANNER.getCurrentIdentifierSource();
+				} catch (ArrayIndexOutOfBoundsException e) {
+					return null;
+				}
+			} else {
+				return null;
+			}
+		}
+		catch (InvalidInputException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Validate the given compilation unit name.
+	 * <p>
+	 * A compilation unit name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must be suffixed by a dot ('.') followed by one of the
+	 *       {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
+	 * <li> its prefix must be a valid identifier
+	 * <li> it must not contain any characters or substrings that are not valid
+	 *		   on the file system on which workspace root is located.
+	 * </ul>
+	 * </p>
+	 * @param name the name of a compilation unit
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a compilation unit name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @deprecated Use {@link #validateCompilationUnitName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateCompilationUnitName(String name) {
+		return validateCompilationUnitName(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given compilation unit name for the given source and compliance levels.
+	 * <p>
+	 * A compilation unit name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must be suffixed by a dot ('.') followed by one of the
+	 *       {@link JavaCore#getJavaLikeExtensions() Java-like extensions}
+	 * <li> its prefix must be a valid identifier
+	 * <li> it must not contain any characters or substrings that are not valid
+	 *		   on the file system on which workspace root is located.
+	 * </ul>
+	 * </p>
+	 * @param name the name of a compilation unit
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a compilation unit name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateCompilationUnitName(String name, String sourceLevel, String complianceLevel) {
+		if (name == null) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_nullName, null);
+		}
+		if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
+		}
+		String identifier;
+		int index;
+		index = name.lastIndexOf('.');
+		if (index == -1) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null);
+		}
+		identifier = name.substring(0, index);
+		// JSR-175 metadata strongly recommends "package-info.java" as the
+		// file in which to store package annotations and
+		// the package-level spec (replaces package.html)
+		if (!identifier.equals(PACKAGE_INFO)) {
+			IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
+			if (!status.isOK()) {
+				return status;
+			}
+		}
+		IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
+		if (!status.isOK()) {
+			return status;
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	/**
+	 * Validate the given .class file name.
+	 * <p>
+	 * A .class file name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must include the <code>".class"</code> suffix
+	 * <li> its prefix must be a valid identifier
+	 * <li> it must not contain any characters or substrings that are not valid
+	 *		   on the file system on which workspace root is located.
+	 * </ul>
+	 * </p>
+	 * @param name the name of a .class file
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a .class file name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 2.0
+	 * @deprecated Use {@link #validateClassFileName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateClassFileName(String name) {
+		return validateClassFileName(name, CompilerOptions.VERSION_1_3, CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given .class file name for the given source and compliance levels.
+	 * <p>
+	 * A .class file name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must include the <code>".class"</code> suffix
+	 * <li> its prefix must be a valid identifier
+	 * <li> it must not contain any characters or substrings that are not valid
+	 *		   on the file system on which workspace root is located.
+	 * </ul>
+	 * </p>
+	 * @param name the name of a .class file
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a .class file name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateClassFileName(String name, String sourceLevel, String complianceLevel) {
+		if (name == null) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_nullName, null);		}
+		if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
+		}
+		String identifier;
+		int index;
+		index = name.lastIndexOf('.');
+		if (index == -1) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
+		}
+		identifier = name.substring(0, index);
+		// JSR-175 metadata strongly recommends "package-info.java" as the
+		// file in which to store package annotations and
+		// the package-level spec (replaces package.html)
+		if (!identifier.equals(PACKAGE_INFO)) {
+			IStatus status = validateIdentifier(identifier, sourceLevel, complianceLevel);
+			if (!status.isOK()) {
+				return status;
+			}
+		}
+		IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
+		if (!status.isOK()) {
+			return status;
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	/**
+	 * Validate the given field name.
+	 * <p>
+	 * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
+	 * For example, <code>"x"</code>.
+	 *
+	 * @param name the name of a field
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a field name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @deprecated Use {@link #validateFieldName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateFieldName(String name) {
+		return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given field name for the given source and compliance levels.
+	 * <p>
+	 * Syntax of a field name corresponds to VariableDeclaratorId (JLS2 8.3).
+	 * For example, <code>"x"</code>.
+	 *
+	 * @param name the name of a field
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a field name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateFieldName(String name, String sourceLevel, String complianceLevel) {
+		return validateIdentifier(name, sourceLevel, complianceLevel);
+	}
+
+	/**
+	 * Validate the given Java identifier.
+	 * The identifier must not have the same spelling as a Java keyword,
+	 * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
+	 * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
+	 * A valid identifier can act as a simple type name, method name or field name.
+	 *
+	 * @param id the Java identifier
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given identifier is a valid Java identifier, otherwise a status
+	 *		object indicating what is wrong with the identifier
+	 * @deprecated Use {@link #validateIdentifier(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateIdentifier(String id) {
+		return validateIdentifier(id,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given Java identifier for the given source and compliance levels
+	 * The identifier must not have the same spelling as a Java keyword,
+	 * boolean literal (<code>"true"</code>, <code>"false"</code>), or null literal (<code>"null"</code>).
+	 * See section 3.8 of the <em>Java Language Specification, Second Edition</em> (JLS2).
+	 * A valid identifier can act as a simple type name, method name or field name.
+	 *
+	 * @param id the Java identifier
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given identifier is a valid Java identifier, otherwise a status
+	 *		object indicating what is wrong with the identifier
+	 * @since 3.3
+	 */
+	public static IStatus validateIdentifier(String id, String sourceLevel, String complianceLevel) {
+		if (scannedIdentifier(id, sourceLevel, complianceLevel) != null) {
+			return JavaModelStatus.VERIFIED_OK;
+		} else {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, id), null);
+		}
+	}
+
+	/**
+	 * Validate the given import declaration name.
+	 * <p>
+	 * The name of an import corresponds to a fully qualified type name
+	 * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
+	 * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
+	 *
+	 * @param name the import declaration
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as an import declaration, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @deprecated Use {@link #validateImportDeclaration(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateImportDeclaration(String name) {
+		return validateImportDeclaration(name,CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given import declaration name for the given source and compliance levels.
+	 * <p>
+	 * The name of an import corresponds to a fully qualified type name
+	 * or an on-demand package name as defined by ImportDeclaration (JLS2 7.5).
+	 * For example, <code>"java.util.*"</code> or <code>"java.util.Hashtable"</code>.
+	 *
+	 * @param name the import declaration
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as an import declaration, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateImportDeclaration(String name, String sourceLevel, String complianceLevel) {
+		if (name == null || name.length() == 0) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_nullImport, null);
+		}
+		if (name.charAt(name.length() - 1) == '*') {
+			if (name.charAt(name.length() - 2) == '.') {
+				return validatePackageName(name.substring(0, name.length() - 2), sourceLevel, complianceLevel);
+			} else {
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_unqualifiedImport, null);
+			}
+		}
+		return validatePackageName(name, sourceLevel, complianceLevel);
+	}
+
+	/**
+	 * Validate the given Java type name, either simple or qualified.
+	 * For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.
+	 * <p>
+	 *
+	 * @param name the name of a type
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a Java type name,
+	 *      a status with code <code>IStatus.WARNING</code>
+	 *		indicating why the given name is discouraged,
+	 *      otherwise a status object indicating what is wrong with
+	 *      the name
+	 * @deprecated Use {@link #validateJavaTypeName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateJavaTypeName(String name) {
+		return validateJavaTypeName(name, JavaCore.VERSION_1_3, JavaCore.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given Java type name, either simple or qualified, for the given source and compliance levels.
+	 * 
+	 * <p>For example, <code>"java.lang.Object"</code>, or <code>"Object"</code>.</p>
+	 * 
+	 * <p>The source level and compliance level values should be taken from the constant defined inside
+	 * {@link JavaCore} class. The constants are named <code>JavaCore#VERSION_1_x</code>, x being set
+	 * between '1' and '8'.
+	 * </p>
+	 *
+	 * @param name the name of a type
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a Java type name,
+	 *      a status with code <code>IStatus.WARNING</code>
+	 *		indicating why the given name is discouraged,
+	 *      otherwise a status object indicating what is wrong with
+	 *      the name
+	 * @since 3.3
+	 * @see JavaCore#VERSION_1_1
+	 * @see JavaCore#VERSION_1_2
+	 * @see JavaCore#VERSION_1_3
+	 * @see JavaCore#VERSION_1_4
+	 * @see JavaCore#VERSION_1_5
+	 * @see JavaCore#VERSION_1_6
+	 * @see JavaCore#VERSION_1_7
+	 * @see JavaCore#VERSION_1_8
+	 */
+	public static IStatus validateJavaTypeName(String name, String sourceLevel, String complianceLevel) {
+		if (name == null) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nullName, null);
+		}
+		String trimmed = name.trim();
+		if (!name.equals(trimmed)) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nameWithBlanks, null);
+		}
+		int index = name.lastIndexOf('.');
+		char[] scannedID;
+		if (index == -1) {
+			// simple name
+			scannedID = scannedIdentifier(name, sourceLevel, complianceLevel);
+		} else {
+			// qualified name
+			String pkg = name.substring(0, index).trim();
+			IStatus status = validatePackageName(pkg, sourceLevel, complianceLevel);
+			if (!status.isOK()) {
+				return status;
+			}
+			String type = name.substring(index + 1).trim();
+			scannedID = scannedIdentifier(type, sourceLevel, complianceLevel);
+		}
+
+		if (scannedID != null) {
+			IStatus status = ResourcesPlugin.getWorkspace().validateName(new String(scannedID), IResource.FILE);
+			if (!status.isOK()) {
+				return status;
+			}
+			if (CharOperation.contains('$', scannedID)) {
+				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_dollarName, null);
+			}
+			if ((scannedID.length > 0 && ScannerHelper.isLowerCase(scannedID[0]))) {
+				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_lowercaseName, null);
+			}
+			return JavaModelStatus.VERIFIED_OK;
+		} else {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, name), null);
+		}
+	}
+
+	/**
+	 * Validate the given method name.
+	 * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
+	 * <p>
+	 * The syntax for a method  name is defined by Identifier
+	 * of MethodDeclarator (JLS2 8.4). For example "println".
+	 *
+	 * @param name the name of a method
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a method name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @deprecated Use {@link #validateMethodName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateMethodName(String name) {
+		return validateMethodName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given method name for the given source and compliance levels.
+	 * The special names "&lt;init&gt;" and "&lt;clinit&gt;" are not valid.
+	 * <p>
+	 * The syntax for a method  name is defined by Identifier
+	 * of MethodDeclarator (JLS2 8.4). For example "println".
+	 *
+	 * @param name the name of a method
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a method name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateMethodName(String name, String sourceLevel, String complianceLevel) {
+		return validateIdentifier(name, sourceLevel,complianceLevel);
+	}
+
+	/**
+	 * Validate the given package name.
+	 * <p>
+	 * The syntax of a package name corresponds to PackageName as
+	 * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
+	 * <p>
+	 * Note that the given name must be a non-empty package name (that is, attempting to
+	 * validate the default package will return an error status.)
+	 * Also it must not contain any characters or substrings that are not valid
+	 * on the file system on which workspace root is located.
+	 *
+	 * @param name the name of a package
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a package name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @deprecated Use {@link #validatePackageName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validatePackageName(String name) {
+		return validatePackageName(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given package name for the given source and compliance levels.
+	 * <p>
+	 * The syntax of a package name corresponds to PackageName as
+	 * defined by PackageDeclaration (JLS2 7.4). For example, <code>"java.lang"</code>.
+	 * <p>
+	 * Note that the given name must be a non-empty package name (that is, attempting to
+	 * validate the default package will return an error status.)
+	 * Also it must not contain any characters or substrings that are not valid
+	 * on the file system on which workspace root is located.
+	 *
+	 * @param name the name of a package
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a package name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validatePackageName(String name, String sourceLevel, String complianceLevel) {
+
+		if (name == null) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nullName, null);
+		}
+		int length;
+		if ((length = name.length()) == 0) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_emptyName, null);
+		}
+		if (name.charAt(0) == DOT || name.charAt(length-1) == DOT) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_dotName, null);
+		}
+		if (CharOperation.isWhitespace(name.charAt(0)) || CharOperation.isWhitespace(name.charAt(name.length() - 1))) {
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nameWithBlanks, null);
+		}
+		int dot = 0;
+		while (dot != -1 && dot < length-1) {
+			if ((dot = name.indexOf(DOT, dot+1)) != -1 && dot < length-1 && name.charAt(dot+1) == DOT) {
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_consecutiveDotsName, null);
+				}
+		}
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		StringTokenizer st = new StringTokenizer(name, "."); //$NON-NLS-1$
+		boolean firstToken = true;
+		IStatus warningStatus = null;
+		while (st.hasMoreTokens()) {
+			String typeName = st.nextToken();
+			typeName = typeName.trim(); // grammar allows spaces
+			char[] scannedID = scannedIdentifier(typeName, sourceLevel, complianceLevel);
+			if (scannedID == null) {
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, typeName), null);
+			}
+			IStatus status = workspace.validateName(new String(scannedID), IResource.FOLDER);
+			if (!status.isOK()) {
+				return status;
+			}
+			if (firstToken && scannedID.length > 0 && ScannerHelper.isUpperCase(scannedID[0])) {
+				if (warningStatus == null) {
+					warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_package_uppercaseName, null);
+				}
+			}
+			firstToken = false;
+		}
+		if (warningStatus != null) {
+			return warningStatus;
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	/**
+	 * Validate a given classpath and output location for a project, using the following rules:
+	 * <ul>
+	 *   <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
+	 *   <li> The project output location path cannot be null, must be absolute and located inside the project.
+	 *   <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
+	 *   <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
+     *   <li> Classpath entries or output locations cannot coincide or be nested in each other, except for the following scenarios listed below:
+	 *      <ul><li> A source folder can coincide with its own output location, in which case this output can then contain library archives.
+	 *                     However, a specific output location cannot coincide with any library or a distinct source folder than the one referring to it.<br>
+	 *                     Note: Since 3.8, this behavior can be overridden by configuring {@link JavaCore#CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE}
+	 *                     </li>
+	 *              <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
+	 * 			<li> An output location can be nested in a source folder, if the source folder coincides with the project itself, or if the output
+	 * 					location is excluded from the source folder.
+	 *      </ul>
+	 * </ul>
+	 *
+	 *  Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
+	 *  in the checking process (this allows to perform a consistency check on a classpath which has references to
+	 *  yet non existing projects, folders, ...).
+	 *  <p>
+	 *  This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
+	 *  be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
+	 *  <p>
+	 * @param javaProject the given java project
+	 * @param rawClasspath the given classpath
+	 * @param projectOutputLocation the given output location
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given classpath and output location are compatible, otherwise a status
+	 *		object indicating what is wrong with the classpath or output location
+	 * @since 2.0
+	 */
+	public static IJavaModelStatus validateClasspath(IJavaProject javaProject, IClasspathEntry[] rawClasspath, IPath projectOutputLocation) {
+
+		return ClasspathEntry.validateClasspath(javaProject, rawClasspath, projectOutputLocation);
+	}
+
+	/**
+	 * Returns a Java model status describing the problem related to this classpath entry if any,
+	 * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
+	 * given classpath entry denotes a valid element to be referenced onto a classpath).
+	 *
+	 * @param project the given java project
+	 * @param entry the given classpath entry
+	 * @param checkSourceAttachment a flag to determine if source attachment should be checked
+	 * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
+	 * @since 2.0
+	 */
+	public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment){
+		return ClasspathEntry.validateClasspathEntry(project, entry, checkSourceAttachment, false/*not referred by container*/);
+	}
+
+	/**
+	 * Validate the given type variable name.
+	 * <p>
+	 * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
+	 * For example, <code>"E"</code>.
+	 *
+	 * @param name the name of a type variable
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a type variable name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.1
+	 * @deprecated Use {@link #validateTypeVariableName(String id, String sourceLevel, String complianceLevel)} instead
+	 */
+	public static IStatus validateTypeVariableName(String name) {
+		return validateIdentifier(name, CompilerOptions.VERSION_1_3,CompilerOptions.VERSION_1_3);
+	}
+
+	/**
+	 * Validate the given type variable name for the given source and compliance levels.
+	 * <p>
+	 * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
+	 * For example, <code>"E"</code>.
+	 *
+	 * @param name the name of a type variable
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a type variable name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 * @since 3.3
+	 */
+	public static IStatus validateTypeVariableName(String name, String sourceLevel, String complianceLevel) {
+		return validateIdentifier(name, sourceLevel, complianceLevel);
+	}
+
+	/**
+	 * Validate that all compiler options of the given project match keys and values
+	 * described in {@link JavaCore#getDefaultOptions()} method.
+	 *
+	 * @param javaProject the given java project
+	 * @param inheritJavaCoreOptions inherit project options from JavaCore or not.
+	 * @return a status object with code <code>IStatus.OK</code> if all project
+	 *		compiler options are valid, otherwise a status object indicating what is wrong
+	 *		with the keys and their value.
+	 * @since 3.1
+	 * TODO (frederic) finalize for all possible options (JavaCore, DefaultCodeFormatterOptions, AssistOptions) and open to API
+	 */
+	/*
+	public static IStatus validateCompilerOptions(IJavaProject javaProject, boolean inheritJavaCoreOptions)	  {
+		return validateCompilerOptions(javaProject.getOptions(inheritJavaCoreOptions));
+	}
+	*/
+
+	/**
+	 * Validate that all compiler options of the given project match keys and values
+	 * described in {@link JavaCore#getDefaultOptions()} method.
+	 *
+	 * @param compilerOptions Map of options
+	 * @return a status object with code <code>IStatus.OK</code> if all
+	 *		compiler options are valid, otherwise a status object indicating what is wrong
+	 *		with the keys and their value.
+	 * @since 3.1
+	 */
+	/*
+	public static IStatus validateCompilerOptions(Map compilerOptions)	  {
+
+		// Get current options
+		String compliance = (String) compilerOptions.get(JavaCore.COMPILER_COMPLIANCE);
+		String source = (String) compilerOptions.get(JavaCore.COMPILER_SOURCE);
+		String target = (String) compilerOptions.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
+		if (compliance == null && source == null && target == null) {
+			return JavaModelStatus.VERIFIED_OK; // default is OK
+		}
+
+		// Initialize multi-status
+		List errors = new ArrayList();
+
+		// Set default for compliance if necessary (not set on project and not inherited...)
+		if (compliance == null) {
+			compliance = JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE);
+		}
+
+		// Verify compliance level value and set source and target default if necessary
+		long complianceLevel = 0;
+		long sourceLevel = 0;
+		long targetLevel = 0;
+		if (JavaCore.VERSION_1_3.equals(compliance)) {
+			complianceLevel = ClassFileConstants.JDK1_3;
+			if (source == null) {
+				source = JavaCore.VERSION_1_3;
+				sourceLevel = ClassFileConstants.JDK1_3;
+			}
+			if (target == null) {
+				target = JavaCore.VERSION_1_1;
+				targetLevel = ClassFileConstants.JDK1_1;
+			}
+		} else if (JavaCore.VERSION_1_4.equals(compliance)) {
+			complianceLevel = ClassFileConstants.JDK1_4;
+			if (source == null) {
+				source = JavaCore.VERSION_1_3;
+				sourceLevel = ClassFileConstants.JDK1_3;
+			}
+			if (target == null) {
+				target = JavaCore.VERSION_1_2;
+				targetLevel = ClassFileConstants.JDK1_2;
+			}
+		} else if (JavaCore.VERSION_1_5.equals(compliance)) {
+			complianceLevel = ClassFileConstants.JDK1_5;
+			if (source == null) {
+				source = JavaCore.VERSION_1_5;
+				sourceLevel = ClassFileConstants.JDK1_5;
+			}
+			if (target == null) {
+				target = JavaCore.VERSION_1_5;
+				targetLevel = ClassFileConstants.JDK1_5;
+			}
+		} else {
+			// compliance is not valid
+			errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", compliance==null?"":compliance, JavaCore.COMPILER_COMPLIANCE))); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		// Verify source value and set default for target if necessary
+		 if (JavaCore.VERSION_1_4.equals(source)) {
+			sourceLevel = ClassFileConstants.JDK1_4;
+			if (target == null) {
+				target = JavaCore.VERSION_1_4;
+				targetLevel = ClassFileConstants.JDK1_4;
+			}
+		} else if (JavaCore.VERSION_1_5.equals(source)) {
+			sourceLevel = ClassFileConstants.JDK1_5;
+			if (target == null) {
+				target = JavaCore.VERSION_1_5;
+				targetLevel = ClassFileConstants.JDK1_5;
+			}
+		} else if (JavaCore.VERSION_1_3.equals(source)) {
+			sourceLevel = ClassFileConstants.JDK1_3;
+		} else {
+			// source is not valid
+			errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", source==null?"":source, JavaCore.COMPILER_SOURCE))); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		// Verify target value
+		 if (targetLevel == 0) {
+			 targetLevel = CompilerOptions.versionToJdkLevel(target);
+			 if (targetLevel == 0) {
+				// target is not valid
+				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.invalidCompilerOption", target==null?"":target, JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))); //$NON-NLS-1$ //$NON-NLS-2$
+			 }
+		}
+
+		// Check and set compliance/source/target compatibilities (only if they have valid values)
+		if (complianceLevel != 0 && sourceLevel != 0 && targetLevel != 0) {
+			// target must be 1.5 if source is 1.5
+			if (sourceLevel >= ClassFileConstants.JDK1_5 && targetLevel < ClassFileConstants.JDK1_5) {
+				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_5))); //$NON-NLS-1$
+			}
+	   		else
+		   		// target must be 1.4 if source is 1.4
+	   			if (sourceLevel >= ClassFileConstants.JDK1_4 && targetLevel < ClassFileConstants.JDK1_4) {
+					errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleTargetForSource", target, JavaCore.VERSION_1_4))); //$NON-NLS-1$
+	   		}
+			// target cannot be greater than compliance level
+			if (complianceLevel < targetLevel){
+				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForTarget", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
+			}
+			// compliance must be 1.5 if source is 1.5
+			if (source.equals(JavaCore.VERSION_1_5) && complianceLevel < ClassFileConstants.JDK1_5) {
+				errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_5))); //$NON-NLS-1$
+			} else
+				// compliance must be 1.4 if source is 1.4
+				if (source.equals(JavaCore.VERSION_1_4) && complianceLevel < ClassFileConstants.JDK1_4) {
+					errors.add(new JavaModelStatus(IStatus.ERROR, Util.bind("convention.compiler.incompatibleComplianceForSource", compliance, JavaCore.VERSION_1_4))); //$NON-NLS-1$
+			}
+		}
+
+		// Return status
+		int size = errors.size();
+		switch (size) {
+			case 0:
+				return JavaModelStatus.VERIFIED_OK;
+			case 1:
+				return (IStatus) errors.get(0);
+			default:
+				IJavaModelStatus[] allStatus = new IJavaModelStatus[size];
+				errors.toArray(allStatus);
+				return JavaModelStatus.newMultiStatus(allStatus);
+		}
+	}
+	*/
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
new file mode 100644
index 0000000..ec6f02d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -0,0 +1,5637 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE
+ *                                 COMPILER_PB_STATIC_ACCESS_RECEIVER
+ *                                 COMPILER_TASK_TAGS
+ *                                 CORE_CIRCULAR_CLASSPATH
+ *                                 CORE_INCOMPLETE_CLASSPATH
+ *     IBM Corporation - added run(IWorkspaceRunnable, IProgressMonitor)
+ *     IBM Corporation - added exclusion patterns to source classpath entries
+ *     IBM Corporation - added specific output location to source classpath entries
+ *     IBM Corporation - added the following constants:
+ *                                 CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER
+ *                                 CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER
+ *                                 CLEAN
+ *     IBM Corporation - added getClasspathContainerInitializer(String)
+ *     IBM Corporation - added the following constants:
+ *                                 CODEASSIST_ARGUMENT_PREFIXES
+ *                                 CODEASSIST_ARGUMENT_SUFFIXES
+ *                                 CODEASSIST_FIELD_PREFIXES
+ *                                 CODEASSIST_FIELD_SUFFIXES
+ *                                 CODEASSIST_LOCAL_PREFIXES
+ *                                 CODEASSIST_LOCAL_SUFFIXES
+ *                                 CODEASSIST_STATIC_FIELD_PREFIXES
+ *                                 CODEASSIST_STATIC_FIELD_SUFFIXES
+ *                                 COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_LOCAL_VARIABLE_HIDING
+ *                                 COMPILER_PB_SPECIAL_PARAMETER_HIDING_FIELD
+ *                                 COMPILER_PB_FIELD_HIDING
+ *                                 COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT
+ *                                 CORE_INCOMPATIBLE_JDK_LEVEL
+ *                                 VERSION_1_5
+ *                                 COMPILER_PB_EMPTY_STATEMENT
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_INDIRECT_STATIC_ACCESS
+ *                                 COMPILER_PB_BOOLEAN_METHOD_THROWING_EXCEPTION
+ *                                 COMPILER_PB_UNNECESSARY_CAST
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_INVALID_JAVADOC
+ *                                 COMPILER_PB_INVALID_JAVADOC_TAGS
+ *                                 COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY
+ *                                 COMPILER_PB_MISSING_JAVADOC_TAGS
+ *                                 COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY
+ *                                 COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING
+ *                                 COMPILER_PB_MISSING_JAVADOC_COMMENTS
+ *                                 COMPILER_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY
+ *                                 COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING
+ *                                 COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD
+ *                                 COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING
+ *     IBM Corporation - added the following constants:
+ *                                 TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_FALLTHROUGH_CASE
+ *                                 COMPILER_PB_PARAMETER_ASSIGNMENT
+ *                                 COMPILER_PB_NULL_REFERENCE
+ *     IBM Corporation - added the following constants:
+ *                                 CODEASSIST_DEPRECATION_CHECK
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_POTENTIAL_NULL_REFERENCE
+ *                                 COMPILER_PB_REDUNDANT_NULL_CHECK
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_UNUSED_PARAMETER_INCLUDE_DOC_COMMENT_REFERENCE
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION
+ *								   COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_NO_TAG
+ *								   COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_RETURN_TAG
+ *								   COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_ALL_TAGS
+ *     IBM Corporation - added the following constants:
+ *                                 COMPILER_PB_REDUNDANT_SUPERINTERFACE
+ *     IBM Corporation - added the following constant:
+ *                                 COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE
+ *     IBM Corporation - added getOptionForConfigurableSeverity(int)
+ *     Benjamin Muskalla - added COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD
+ *     Stephan Herrmann  - added COMPILER_PB_UNUSED_OBJECT_ALLOCATION
+ *     Stephan Herrmann  - added COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS
+ *     Stephan Herrmann  - added the following constants:
+ *     								COMPILER_PB_UNCLOSED_CLOSEABLE,
+ *     								COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE
+ *     								COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE
+ *     								COMPILER_ANNOTATION_NULL_ANALYSIS
+ *     								COMPILER_NULLABLE_ANNOTATION_NAME
+ *     								COMPILER_NONNULL_ANNOTATION_NAME
+ *     								COMPILER_PB_NULL_SPECIFICATION_VIOLATION
+ *     								COMPILER_PB_POTENTIAL_NULL_SPECIFICATION_VIOLATION
+ *     								COMPILER_PB_NULL_SPECIFICATION_INSUFFICIENT_INFO
+ *									COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT
+ *									COMPILER_PB_SWITCH_MISSING_DEFAULT_CASE
+ *									COMPILER_INHERIT_NULL_ANNOTATIONS
+ *									COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED
+ *									COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS
+ *     Jesper S Moller  - Contributions for bug 381345 : [1.8] Take care of the Java 8 major version
+ *******************************************************************************/
+
+package org.eclipse.jdt.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.TypeNameRequestor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.core.builder.State;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The plug-in runtime class for the Java model plug-in containing the core
+ * (UI-free) support for Java projects.
+ * <p>
+ * Like all plug-in runtime classes (subclasses of <code>Plugin</code>), this
+ * class is automatically instantiated by the platform when the plug-in gets
+ * activated. Clients must not attempt to instantiate plug-in runtime classes
+ * directly.
+ * </p>
+ * <p>
+ * The single instance of this class can be accessed from any plug-in declaring
+ * the Java model plug-in as a prerequisite via
+ * <code>JavaCore.getJavaCore()</code>. The Java model plug-in will be activated
+ * automatically if not already active.
+ * </p>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class JavaCore extends Plugin {
+
+	private static final IResource[] NO_GENERATED_RESOURCES = new IResource[0];
+
+	private static Plugin JAVA_CORE_PLUGIN = null;
+	/**
+	 * The plug-in identifier of the Java core support
+	 * (value <code>"org.eclipse.jdt.core"</code>).
+	 */
+	public static final String PLUGIN_ID = "org.eclipse.jdt.core" ; //$NON-NLS-1$
+
+	/**
+	 * The identifier for the Java builder
+	 * (value <code>"org.eclipse.jdt.core.javabuilder"</code>).
+	 */
+	public static final String BUILDER_ID = PLUGIN_ID + ".javabuilder" ; //$NON-NLS-1$
+
+	/**
+	 * The identifier for the Java model
+	 * (value <code>"org.eclipse.jdt.core.javamodel"</code>).
+	 */
+	public static final String MODEL_ID = PLUGIN_ID + ".javamodel" ; //$NON-NLS-1$
+
+	/**
+	 * The identifier for the Java nature
+	 * (value <code>"org.eclipse.jdt.core.javanature"</code>).
+	 * The presence of this nature on a project indicates that it is
+	 * Java-capable.
+	 *
+	 * @see org.eclipse.core.resources.IProject#hasNature(java.lang.String)
+	 */
+	public static final String NATURE_ID = PLUGIN_ID + ".javanature" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the handle id attribute in a Java marker.
+	 */
+	protected static final String ATT_HANDLE_ID =
+		"org.eclipse.jdt.internal.core.JavaModelManager.handleId" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the User Library Container id.
+	 * @since 3.0
+	 */
+	public static final String USER_LIBRARY_CONTAINER_ID= "org.eclipse.jdt.USER_LIBRARY"; //$NON-NLS-1$
+
+	// Begin configurable option IDs {
+
+	/**
+	 * Compiler option ID: Generating Local Variable Debug Attribute.
+	 * <p>When generated, this attribute will enable local variable names
+	 *    to be displayed in debugger, only in place where variables are
+	 *    definitely assigned (.class file is then bigger).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.debug.localVariable"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "generate", "do not generate" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"generate"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_LOCAL_VARIABLE_ATTR = PLUGIN_ID + ".compiler.debug.localVariable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Generating Line Number Debug Attribute.
+	 * <p>When generated, this attribute will enable source code highlighting in debugger
+	 *    (.class file is then bigger).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.debug.lineNumber"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "generate", "do not generate" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"generate"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_LINE_NUMBER_ATTR = PLUGIN_ID + ".compiler.debug.lineNumber"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Generating Source Debug Attribute.
+	 * <p>When generated, this attribute will enable the debugger to present the
+	 *    corresponding source code.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.debug.sourceFile"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "generate", "do not generate" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"generate"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_SOURCE_FILE_ATTR = PLUGIN_ID + ".compiler.debug.sourceFile"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Preserving Unused Local Variables.
+	 * <p>Unless requested to preserve unused local variables (that is, never read), the
+	 *    compiler will optimize them out, potentially altering debugging.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.codegen.unusedLocal"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "preserve", "optimize out" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"preserve"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_CODEGEN_UNUSED_LOCAL = PLUGIN_ID + ".compiler.codegen.unusedLocal"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Defining Target Java Platform.
+	 * <p>For binary compatibility reason, .class files can be tagged to with certain VM versions and later.</p>
+	 * <p>Note that <code>"1.4"</code> target requires to toggle compliance mode to <code>"1.4"</code>, <code>"1.5"</code> target requires
+	 *    to toggle compliance mode to <code>"1.5"</code>, <code>"1.6"</code> target requires to toggle compliance mode to <code>"1.6"</code> and
+	 *    <code>"1.7"</code> target requires to toggle compliance mode to <code>"1.7"</code>.
+	 *    <code>"cldc1.1"</code> requires the source version to be <code>"1.3"</code> and the compliance version to be <code>"1.4"</code> or lower.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.codegen.targetPlatform"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "cldc1.1" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"1.2"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_CODEGEN_TARGET_PLATFORM = PLUGIN_ID + ".compiler.codegen.targetPlatform"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Inline JSR Bytecode Instruction.
+	 * <p>When enabled, the compiler will no longer generate JSR instructions, but rather inline corresponding
+	 *    subroutine code sequences (mostly corresponding to try finally blocks). The generated code will thus
+	 *    get bigger, but will load faster on virtual machines since the verification process is then much simpler.</p>
+	 * <p>This mode is anticipating support for the Java Specification Request 202.</p>
+	 * <p>Note that JSR inlining is optional only for target platform lesser than 1.5. From 1.5 on, the JSR
+	 *    inlining is mandatory (also see related setting {@link #COMPILER_CODEGEN_TARGET_PLATFORM}).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_CODEGEN_INLINE_JSR_BYTECODE = PLUGIN_ID + ".compiler.codegen.inlineJsrBytecode"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Javadoc Comment Support.
+	 * <p>When this support is disabled, the compiler will ignore all javadoc problems options settings
+	 *    and will not report any javadoc problem. It will also not find any reference in javadoc comment and
+	 *    DOM AST Javadoc node will be only a flat text instead of having structured tag elements.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.doc.comment.support"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_DOC_COMMENT_SUPPORT = PLUGIN_ID + ".compiler.doc.comment.support"; //$NON-NLS-1$
+	/**
+	 * @deprecated Discontinued since turning off would violate language specs.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String COMPILER_PB_UNREACHABLE_CODE = PLUGIN_ID + ".compiler.problem.unreachableCode"; //$NON-NLS-1$
+	/**
+	 * @deprecated Discontinued since turning off would violate language specs.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_IMPORT = PLUGIN_ID + ".compiler.problem.invalidImport"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Attempt to Override Package Visible Method.
+	 * <p>A package visible method, which is any method that is not explicitly
+	 *    declared as public, protected or private, is not visible from other
+	 *    packages, and thus cannot be overridden from another package.
+	 *    Attempting to override a package visible method from another package
+	 *    introduces a new method that is unrelated to the original one. When
+	 *    enabling this option, the compiler will signal such situations as an
+	 *    error or a warning.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_OVERRIDING_PACKAGE_DEFAULT_METHOD = PLUGIN_ID + ".compiler.problem.overridingPackageDefaultMethod"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Method With Constructor Name.
+	 * <p>Naming a method with a constructor name is generally considered poor
+	 *    style programming. When enabling this option, the compiler will signal such
+	 *    scenario either as an error or a warning.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.methodWithConstructorName"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_METHOD_WITH_CONSTRUCTOR_NAME = PLUGIN_ID + ".compiler.problem.methodWithConstructorName"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Deprecation.
+	 * <p>When enabled, the compiler will signal use of deprecated API either as an
+	 *    error or a warning.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.deprecation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_DEPRECATION = PLUGIN_ID + ".compiler.problem.deprecation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Deprecation Inside Deprecated Code.
+	 * <p>When enabled, the compiler will signal use of deprecated API inside deprecated code.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_DEPRECATION}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE = PLUGIN_ID + ".compiler.problem.deprecationInDeprecatedCode"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Deprecation When Overriding Deprecated Method.
+	 * <p>When enabled, the compiler will signal the declaration of a method overriding a deprecated one.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_DEPRECATION}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_DEPRECATION_WHEN_OVERRIDING_DEPRECATED_METHOD = "org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Hidden Catch Block.
+	 * <p>Locally to a try statement, some catch blocks may hide others. For example,</p>
+	 *    <pre>
+	 *      try {  throw new java.io.CharConversionException();
+	 *      } catch (java.io.CharConversionException e) {
+	 *      } catch (java.io.IOException e) {}.
+	 *    </pre>
+	 * <p>When enabling this option, the compiler will issue an error or a warning for hidden
+	 *    catch blocks corresponding to checked exceptions.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_HIDDEN_CATCH_BLOCK = PLUGIN_ID + ".compiler.problem.hiddenCatchBlock"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Local.
+	 * <p>When enabled, the compiler will issue an error or a warning for unused local
+	 *    variables (that is, variables never read from).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedLocal"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_LOCAL = PLUGIN_ID + ".compiler.problem.unusedLocal"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Parameter.
+	 * <p>When enabled, the compiler will issue an error or a warning for unused method
+	 *    parameters (that is, parameters never read from).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedParameter"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedParameter"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Parameter if Implementing Abstract Method.
+	 * <p>When enabled, the compiler will signal unused parameters in abstract method implementations.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_UNUSED_PARAMETER}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_IMPLEMENTING_ABSTRACT = PLUGIN_ID + ".compiler.problem.unusedParameterWhenImplementingAbstract"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Parameter if Overriding Concrete Method.
+	 * <p>When enabled, the compiler will signal unused parameters in methods overriding concrete ones.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_UNUSED_PARAMETER}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_PARAMETER_WHEN_OVERRIDING_CONCRETE = PLUGIN_ID + ".compiler.problem.unusedParameterWhenOverridingConcrete"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Consider Reference in Doc Comment for Unused Parameter Check.
+	 * <p>When enabled, the compiler will consider doc comment references to parameters (i.e. <code>@param</code> clauses) for the unused
+	 *    parameter check. Thus, documented parameters will be considered as mandated as per doc contract.</p>
+	 * <p>The severity of the unused parameter problem is controlled with option {@link #COMPILER_PB_UNUSED_PARAMETER}.</p>
+	 * <p>Note: this option has no effect until the doc comment support is enabled according to the
+	 *    option {@link #COMPILER_DOC_COMMENT_SUPPORT}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.3
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_PARAMETER_INCLUDE_DOC_COMMENT_REFERENCE = PLUGIN_ID + ".compiler.problem.unusedParameterIncludeDocCommentReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Import.
+	 * <p>When enabled, the compiler will issue an error or a warning for unused import
+	 *    reference.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedImport"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_IMPORT = PLUGIN_ID + ".compiler.problem.unusedImport"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Presence of Type Arguments for a Non-Generic Method Invocation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever type arguments are encountered for a
+	 *    non-generic method invocation. Note that prior to compliance level is <code>"1.7"</code>, this situation would automatically result
+	 *    in an error. From Java7 on, unused type arguments are being tolerated, and optionally warned against.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedTypeArgumentsForMethodInvocation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_TYPE_ARGUMENTS_FOR_METHOD_INVOCATION = PLUGIN_ID + ".compiler.problem.unusedTypeArgumentsForMethodInvocation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Synthetic Access Emulation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever it emulates
+	 *    access to a non-accessible member of an enclosing type. Such access can have
+	 *    performance implications.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SYNTHETIC_ACCESS_EMULATION = PLUGIN_ID + ".compiler.problem.syntheticAccessEmulation"; //$NON-NLS-1$
+
+	/**
+	 * Compiler option ID: Reporting Unused Type Parameter.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever it encounters an 
+	 * unused type parameter. </p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedTypeParameter"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.9
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_TYPE_PARAMETER = PLUGIN_ID + ".compiler.problem.unusedTypeParameter"; //$NON-NLS-1$
+
+	/**
+	 * Compiler option ID: Reporting Non-Externalized String Literal.
+	 * <p>When enabled, the compiler will issue an error or a warning for non externalized
+	 *    String literal (that is, not tagged with <code>//$NON-NLS-&lt;n&gt;$</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NON_NLS_STRING_LITERAL = PLUGIN_ID + ".compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Usage of <code>'assert'</code> Identifier.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever <code>'assert'</code> is
+	 *    used as an identifier (reserved keyword in 1.4).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.assertIdentifier"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_ASSERT_IDENTIFIER = PLUGIN_ID + ".compiler.problem.assertIdentifier"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Usage of <code>'enum'</code> Identifier.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever <code>'enum'</code> is
+	 *    used as an identifier (reserved keyword in 1.5).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.enumIdentifier"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_ENUM_IDENTIFIER = PLUGIN_ID + ".compiler.problem.enumIdentifier"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Non-Static Reference to a Static Member.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a static field
+	 *    or method is accessed with an expression receiver. A reference to a static member should
+	 *    be qualified with a type name.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_STATIC_ACCESS_RECEIVER = PLUGIN_ID + ".compiler.problem.staticAccessReceiver"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Indirect Reference to a Static Member.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a static field
+	 *    or method is accessed in an indirect way. A reference to a static member should
+	 *    preferably be qualified with its declaring type name.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.indirectStaticAccess"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INDIRECT_STATIC_ACCESS = PLUGIN_ID + ".compiler.problem.indirectStaticAccess"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Assignment with no Effect.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever an assignment
+	 *    has no effect (e.g <code>'x = x'</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.noEffectAssignment"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NO_EFFECT_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.noEffectAssignment"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Interface Method not Compatible with non-Inherited Methods.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever an interface
+	 *    defines a method incompatible with a non-inherited <code>Object</code> method. Until this conflict
+	 *    is resolved, such an interface cannot be implemented. For example,</p>
+	 *    <pre>
+	 *      interface I {
+	 *         int clone();
+	 *      }
+	 *    </pre>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INCOMPATIBLE_NON_INHERITED_INTERFACE_METHOD = PLUGIN_ID + ".compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Private Members.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a private
+	 *    method or field is declared but never used within the same unit.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_PRIVATE_MEMBER = PLUGIN_ID + ".compiler.problem.unusedPrivateMember"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Local Variable Declaration Hiding another Variable.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a local variable
+	 *    declaration is hiding some field or local variable (either locally, inherited or defined in enclosing type).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.localVariableHiding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_LOCAL_VARIABLE_HIDING = PLUGIN_ID + ".compiler.problem.localVariableHiding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Special Parameter Hiding another Field.
+	 * <p>When enabled, the compiler will signal cases where a constructor or setter method parameter declaration
+	 *    is hiding some field (either locally, inherited or defined in enclosing type).</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_LOCAL_VARIABLE_HIDING}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SPECIAL_PARAMETER_HIDING_FIELD = PLUGIN_ID + ".compiler.problem.specialParameterHidingField"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Field Declaration Hiding another Variable.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a field
+	 *    declaration is hiding some field or local variable (either locally, inherited or defined in enclosing type).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.fieldHiding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FIELD_HIDING = PLUGIN_ID + ".compiler.problem.fieldHiding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Type Declaration Hiding another Type.
+	 * <p>When enabled, the compiler will issue an error or a warning in situations where a type parameter
+	 *    declaration is hiding some type, when a nested type is hiding some type parameter, or when
+	 *    a nested type is hiding another nested type defined in same unit.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.typeParameterHiding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_TYPE_PARAMETER_HIDING = PLUGIN_ID + ".compiler.problem.typeParameterHiding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Possible Accidental Boolean Assignment.
+	 * <p>When enabled, the compiler will issue an error or a warning if a boolean assignment is acting as the condition
+	 *    of a control statement  (where it probably was meant to be a boolean comparison).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.possibleAccidentalBooleanAssignment"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Switch Fall-Through Case.
+	 * <p>When enabled, the compiler will issue an error or a warning if a case may be
+	 *    entered by falling through previous case. Empty cases are allowed.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.fallthroughCase"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FALLTHROUGH_CASE = PLUGIN_ID + ".compiler.problem.fallthroughCase"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Empty Statements and Unnecessary Semicolons.
+	 * <p>When enabled, the compiler will issue an error or a warning if an empty statement or a
+	 *    unnecessary semicolon is encountered.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.emptyStatement"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_EMPTY_STATEMENT = PLUGIN_ID + ".compiler.problem.emptyStatement"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID.
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.booleanMethodThrowingException"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 * @deprecated - this option has no effect
+	 */
+	public static final String COMPILER_PB_BOOLEAN_METHOD_THROWING_EXCEPTION = PLUGIN_ID + ".compiler.problem.booleanMethodThrowingException"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unnecessary Type Check.
+	 * <p>When enabled, the compiler will issue an error or a warning when a cast or an <code>instanceof</code> operation
+	 *    is unnecessary.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNNECESSARY_TYPE_CHECK = PLUGIN_ID + ".compiler.problem.unnecessaryTypeCheck"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unnecessary Else.
+	 * <p>When enabled, the compiler will issue an error or a warning when a statement is unnecessarily
+	 *    nested within an <code>else</code> clause (in situation where then clause is not completing normally).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unnecessaryElse"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNNECESSARY_ELSE = PLUGIN_ID + ".compiler.problem.unnecessaryElse"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Undocumented Empty Block.
+	 * <p>When enabled, the compiler will issue an error or a warning when an empty block is detected and it is not
+	 *    documented with any comment.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNDOCUMENTED_EMPTY_BLOCK = PLUGIN_ID + ".compiler.problem.undocumentedEmptyBlock"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Finally Blocks Not Completing Normally.
+	 * <p>When enabled, the compiler will issue an error or a warning when a finally block does not complete normally.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FINALLY_BLOCK_NOT_COMPLETING = PLUGIN_ID + ".compiler.problem.finallyBlockNotCompletingNormally"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Declared Thrown Exception.
+	 * <p>When enabled, the compiler will issue an error or a warning when a
+	 *    method or a constructor is declaring a checked exception as thrown,
+	 *    but its body actually raises neither that exception, nor any other
+	 *    exception extending it.</p>
+	 * <p>This diagnostic is further tuned by options
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE},
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE},
+	 *    and {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION = PLUGIN_ID + ".compiler.problem.unusedDeclaredThrownException"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Declared Thrown Exception in Overriding Method.
+	 * <p>When disabled, the compiler will report unused declared thrown
+	 *    exceptions neither on overriding methods nor on implementing methods.</p>
+	 * <p>The severity of the unused declared thrown exception problem is
+	 *    controlled with option {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION}.</p>
+	 * <p>This diagnostic is further tuned by options
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE} and
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING = PLUGIN_ID + ".compiler.problem.unusedDeclaredThrownExceptionWhenOverriding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Consider Reference in Doc Comment for Unused Declared Thrown Exception Check.
+	 * <p>When enabled, the compiler will consider doc comment references to
+	 *    exceptions (i.e. <code>@throws</code> clauses) for the unused
+	 *    declared thrown exception check. Thus, documented exceptions will be
+	 *    considered as mandated as per doc contract.</p>
+	 * <p>The severity of the unused declared thrown exception problem is controlled with option {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION}.</p>
+	 * <p>Note: this option has no effect until the doc comment support is enabled according to the
+	 *    option {@link #COMPILER_DOC_COMMENT_SUPPORT}.</p>
+	 * <p>This diagnostic is further tuned by options
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE}
+	 *    and {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE = PLUGIN_ID + ".compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unused Declared Thrown Exception Exempts Exception And Throwable.
+	 * <p>When enabled, the compiler will issue an error or a warning when a
+	 *    method or a constructor is declaring a checked exception else than
+	 *    {@link java.lang.Throwable} or {@link java.lang.Exception} as thrown,
+	 *    but its body actually raises neither that exception, nor any other
+	 *    exception extending it. When disabled, the compiler will issue an
+	 *    error or a warning when a method or a constructor is declaring a
+	 *    checked exception (including {@link java.lang.Throwable} and
+	 *    {@link java.lang.Exception}) as thrown, but its body actually raises
+	 *    neither that exception, nor any other exception extending it.</p>
+	 * <p>The severity of the unused declared thrown exception problem is
+	 *    controlled with option
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION}.</p>
+	 * <p>This diagnostic is further tuned by options
+	 *    {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE}
+	 *    and {@link #COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_EXEMPT_EXCEPTION_AND_THROWABLE = PLUGIN_ID + ".compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unqualified Access to Field.
+	 * <p>When enabled, the compiler will issue an error or a warning when a field is access without any qualification.
+	 *    In order to improve code readability, it should be qualified, e.g. <code>'x'</code> should rather be written <code>'this.x'</code>.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNQUALIFIED_FIELD_ACCESS = PLUGIN_ID + ".compiler.problem.unqualifiedFieldAccess"; //$NON-NLS-1$
+	/**
+	 * @deprecated Use {@link #COMPILER_PB_UNCHECKED_TYPE_OPERATION} instead.
+	 * @since 3.1
+	 * @category DeprecatedOptionID
+	 */
+	public static final String COMPILER_PB_UNSAFE_TYPE_OPERATION = PLUGIN_ID + ".compiler.problem.uncheckedTypeOperation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unchecked Type Operation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever an operation involves generic types, and potentially
+	 *    invalidates type safety since involving raw types (e.g. invoking <code>#foo(X&lt;String&gt;)</code> with arguments <code>(X)</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNCHECKED_TYPE_OPERATION = PLUGIN_ID + ".compiler.problem.uncheckedTypeOperation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Raw Type Reference.
+	 * <p>When enabled, the compiler will issue an error or a warning when detecting references to raw types. Raw types are
+	 *    discouraged, and are intended to help interfacing with legacy code. In the future, the language specification may
+	 *    reject raw references to generic types.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.rawTypeReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_RAW_TYPE_REFERENCE = PLUGIN_ID + ".compiler.problem.rawTypeReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting of Unavoidable Generic Type Problems.
+	 * <p> When enabled, the compiler will issue an error or warning even when it detects a generic type problem
+	 *     that could not have been avoided by the programmer. As an example, a type may be forced to use raw types
+	 *     in its method signatures and return types because the methods it overrides from a super type are declared to
+	 *     use raw types in the first place.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS = PLUGIN_ID + ".compiler.problem.unavoidableGenericTypeProblems"; //$NON-NLS-1$
+
+	/**
+	 * Compiler option ID: Reporting final Bound for Type Parameter.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a generic type parameter is associated with a
+	 *    bound corresponding to a final type; since final types cannot be further extended, the parameter is pretty useless.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.finalParameterBound"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FINAL_PARAMETER_BOUND = PLUGIN_ID + ".compiler.problem.finalParameterBound"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Declaration of serialVersionUID Field on Serializable Class.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a serializable class is missing a local declaration
+	 *    of a <code>serialVersionUID</code> field. This field must be declared as static final and be of type <code>long</code>.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingSerialVersion"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_SERIAL_VERSION = PLUGIN_ID + ".compiler.problem.missingSerialVersion"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Varargs Argument Needing a Cast in Method/Constructor Invocation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a varargs arguments should be cast
+	 *    when passed to a method/constructor invocation. (e.g. <code>Class.getMethod(String name, Class ... args )</code>
+	 *    invoked with arguments <code>("foo", null)</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_VARARGS_ARGUMENT_NEED_CAST = PLUGIN_ID + ".compiler.problem.varargsArgumentNeedCast"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Boxing/Unboxing Conversion.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a boxing or an unboxing
+	 *    conversion is performed.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.autoboxing"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_AUTOBOXING = PLUGIN_ID + ".compiler.problem.autoboxing"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Use of Annotation Type as Super Interface.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever an annotation type is used
+	 *    as a super-interface. Though legal, this is discouraged.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_ANNOTATION_SUPER_INTERFACE = PLUGIN_ID + ".compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing <code>@Override</code> Annotation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever encountering a method
+	 *    declaration which overrides a superclass method but has no <code>@Override</code> annotation.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_OVERRIDE_ANNOTATION = PLUGIN_ID + ".compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing <code>@Override</code> Annotation for interface method implementation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever encountering a method
+	 *    declaration which overrides or implements a superinterface method but has no <code>@Override</code> annotation.</p>
+	 * <p>This option only has an effect if the compiler compliance is 1.6 or greater.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_MISSING_OVERRIDE_ANNOTATION}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.6
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_OVERRIDE_ANNOTATION_FOR_INTERFACE_METHOD_IMPLEMENTATION = PLUGIN_ID + ".compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing <code>@Deprecated</code> Annotation.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever encountering a declaration
+	 *    carrying a <code>@deprecated</code> doc tag but having no corresponding <code>@Deprecated</code> annotation.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_DEPRECATED_ANNOTATION = PLUGIN_ID + ".compiler.problem.missingDeprecatedAnnotation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing HashCode Method.
+	 * <p>When enabled, the compiler will issue an error or a warning if a type
+	 * overrides Object.equals(Object) but does not override hashCode().</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_HASHCODE_METHOD = PLUGIN_ID + ".compiler.problem.missingHashCodeMethod"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Dead Code.
+	 * <p>When enabled, the compiler will issue an error or a warning if some non fatal dead code is detected. For instance, <code>if (false) foo();</code>
+	 * is not reported as truly unreachable code by the Java Language Specification. If this diagnostic is enabled, then the invocation of <code>foo()</code> is
+	 * going to be signaled as being dead code.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.deadCode"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_DEAD_CODE = PLUGIN_ID + ".compiler.problem.deadCode"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Dead Code Inside Trivial If Statement.
+	 * <p>When enabled, the compiler will signal presence of dead code inside trivial IF statement, e.g. <code>if (DEBUG)...</code>.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_DEAD_CODE}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CompilerOptionID
+	 */	
+	public static final String COMPILER_PB_DEAD_CODE_IN_TRIVIAL_IF_STATEMENT = PLUGIN_ID + ".compiler.problem.deadCodeInTrivialIfStatement"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Incomplete Enum Switch.
+	 * <p>When enabled, the compiler will issue an error or a warning
+	 * 		regarding each enum constant for which a corresponding case label is lacking.
+	 * 		Reporting is further controlled by the option {@link #COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INCOMPLETE_ENUM_SWITCH = PLUGIN_ID + ".compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Enum Case In Switch Despite An Existing Default Case.
+	 * <p>This option further controls the option {@link #COMPILER_PB_INCOMPLETE_ENUM_SWITCH}:</p>
+	 * 	<ul>
+	 * 	<li>If enabled the compiler will report problems about missing enum constants even if a default case exists
+	 * 		in the same switch statement.</li>
+	 *  <li>If disabled existence of a default case is considered as sufficient to make a switch statement complete.</li>
+	 *  </ul>
+	 *  This option has no effect if {@link #COMPILER_PB_INCOMPLETE_ENUM_SWITCH} is set to <code>"ignore"</code>.
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT = PLUGIN_ID + ".compiler.problem.missingEnumCaseDespiteDefault"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Default Case In Switch.
+	 * <p>When enabled, the compiler will issue an error or a warning 
+	 * 		against each switch statement that lacks a default case.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingDefaultCase"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SWITCH_MISSING_DEFAULT_CASE = PLUGIN_ID + ".compiler.problem.missingDefaultCase"; //$NON-NLS-1$
+	/**
+	 * @since 3.1
+	 * @deprecated Use {@link #COMPILER_PB_NULL_REFERENCE} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String COMPILER_PB_INCONSISTENT_NULL_CHECK = PLUGIN_ID + ".compiler.problem.inconsistentNullCheck"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unreferenced Label.
+	 * <p>When enabled, the compiler will issue an error or a warning when encountering a labeled statement which label
+	 *    is never explicitly referenced. A label is considered to be referenced if its name explicitly appears behind a break
+	 *    or continue statement; for instance the following label would be considered unreferenced:</p>
+	 *    <code>LABEL: { break; }</code>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedLabel"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_LABEL = PLUGIN_ID + ".compiler.problem.unusedLabel"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Invalid Javadoc Comment.
+	 * <p>This is the generic control for the severity of Javadoc problems.
+	 *    When enabled, the compiler will issue an error or a warning for a problem in Javadoc.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.invalidJavadoc"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_JAVADOC = PLUGIN_ID + ".compiler.problem.invalidJavadoc"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Invalid Javadoc Tags.
+	 * <p>When enabled, the compiler will signal unbound or unexpected reference tags in Javadoc.
+	 *    A <code>@throws</code> tag referencing an undeclared exception would be considered as unexpected.</p>
+	 * <p>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting {@link #COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.invalidJavadocTags"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_JAVADOC_TAGS = PLUGIN_ID + ".compiler.problem.invalidJavadocTags"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Invalid Javadoc Tags with Deprecated References.
+	 * <p>Specify whether the compiler will report deprecated references used in Javadoc tags.</p>
+	 * <p>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting {@link #COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_JAVADOC_TAGS__DEPRECATED_REF = PLUGIN_ID + ".compiler.problem.invalidJavadocTagsDeprecatedRef"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Invalid Javadoc Tags with Not Visible References.
+	 * <p>Specify whether the compiler will report non-visible references used in Javadoc tags.</p>
+	 * <p>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting {@link #COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_JAVADOC_TAGS__NOT_VISIBLE_REF = PLUGIN_ID + ".compiler.problem.invalidJavadocTagsNotVisibleRef"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Visibility Level For Invalid Javadoc Tags.
+	 * <p>Set the minimum visibility level for Javadoc tag problems. Below this level problems will be ignored.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "public", "protected", "default", "private" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"public"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY = PLUGIN_ID + ".compiler.problem.invalidJavadocTagsVisibility"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting missing tag description.
+	 * <p>When enabled, the compiler will report a warning or an error for any Javadoc tag missing a required description.</p>
+	 * <p>The severity of the problem is controlled with option {@link #COMPILER_PB_INVALID_JAVADOC}.</p>
+	 * <p>It does not depend on option {@link #COMPILER_PB_INVALID_JAVADOC_TAGS}.</p>
+	 * <p>When this option is valued to {@link #COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_ALL_STANDARD_TAGS},
+	 *       a subset of the standard <a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javadoc.html#javadoctags">Javadoc tags</a>
+	 *       that have a description, text or label are checked. While this set may grow in the future, note that user-defined tags are not and will not be checked.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "return_tag", "all_standard_tags", "no_tag" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"return_tag"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION = PLUGIN_ID + ".compiler.problem.missingJavadocTagDescription"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Javadoc Tags.
+	 * <p>This is the generic control for the severity of Javadoc missing tag problems.
+	 *    When enabled, the compiler will issue an error or a warning when tags are missing in Javadoc comments.</p>
+	 * <p>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting {@link #COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTags"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAGS = PLUGIN_ID + ".compiler.problem.missingJavadocTags"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Visibility Level For Missing Javadoc Tags.
+	 * <p>Set the minimum visibility level for Javadoc missing tag problems. Below this level problems will be ignored.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "public", "protected", "default", "private" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"public"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY = PLUGIN_ID + ".compiler.problem.missingJavadocTagsVisibility"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Javadoc Tags on Overriding Methods.
+	 * <p>Specify whether the compiler will verify overriding methods in order to report Javadoc missing tag problems.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING = PLUGIN_ID + ".compiler.problem.missingJavadocTagsOverriding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Javadoc Tags for Method Type Parameters.
+	 * <p>Specify whether a missing <code>@param</code> for a type parameter in a method declaration should be reported.
+	 *    When enabled, the compiler will issue a missing Javadoc tag error or warning for a type parameter without a 
+	 *    corresponding <code>@param</code> tag.</p>
+	 * <p>This option only has an effect if the compiler compliance is 1.5 or greater.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS = PLUGIN_ID + ".compiler.problem.missingJavadocTagsMethodTypeParameters"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Javadoc Comments.
+	 * <p>This is the generic control for the severity of missing Javadoc comment problems.
+	 *    When enabled, the compiler will issue an error or a warning when Javadoc comments are missing.</p>
+	 * <p>Note that this diagnosis can be enabled based on the visibility of the construct associated with the expected Javadoc;
+	 *    also see the setting {@link #COMPILER_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY}.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocComments"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_COMMENTS = PLUGIN_ID + ".compiler.problem.missingJavadocComments"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Visibility Level For Missing Javadoc Comments.
+	 * <p>Set the minimum visibility level for missing Javadoc problems. Below this level problems will be ignored.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "public", "protected", "default", "private" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"public"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_COMMENTS_VISIBILITY = PLUGIN_ID + ".compiler.problem.missingJavadocCommentsVisibility"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Javadoc Comments on Overriding Methods.
+	 * <p>Specify whether the compiler will verify overriding methods in order to report missing Javadoc comment problems.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING = PLUGIN_ID + ".compiler.problem.missingJavadocCommentsOverriding"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Usage of <code>char[]</code> Expressions in String Concatenations.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a <code>char[]</code> expression
+	 *    is used in String concatenations (for example, <code>"hello" + new char[]{'w','o','r','l','d'}</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_CHAR_ARRAY_IN_STRING_CONCATENATION = PLUGIN_ID + ".compiler.problem.noImplicitStringConversion"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Maximum Number of Problems Reported per Compilation Unit.
+	 * <p>Specify the maximum number of problems reported on each compilation unit.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.maxProblemPerUnit"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>"&lt;n&gt;"</code> where <code>&lt;n&gt;</code> is zero or a positive integer (if zero then all problems are reported).</dd>
+	 * <dt>Default:</dt><dd><code>"100"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MAX_PER_UNIT = PLUGIN_ID + ".compiler.maxProblemPerUnit"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Treating Optional Error as Fatal.
+	 * <p>When enabled, optional errors (i.e. optional problems which severity is set to <code>"error"</code>) will be treated as standard
+	 *    compiler errors, yielding problem methods/types preventing from running offending code until the issue got resolved.</p>
+	 * <p>When disabled, optional errors are only considered as warnings, still carrying an error indication to make them more
+	 *    severe. Note that by default, optional errors are not fatal. Non-optional errors are
+	 *    always fatal.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.fatalOptionalError"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FATAL_OPTIONAL_ERROR = PLUGIN_ID + ".compiler.problem.fatalOptionalError"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Parameter Assignment.
+	 * <p>When enabled, the compiler will issue an error or a warning if a parameter is
+	 *    assigned to.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.parameterAssignment"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_PARAMETER_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.parameterAssignment"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting a method that qualifies as static, but not declared static.
+	 * <p>When enabled, the compiler will issue an error or a warning if a method has
+	 *    not been declared as <code>static</code>, even though it qualifies as one.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBeStatic"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting a method that may qualify as static, but not declared static.
+	 * <p>When enabled, the compiler will issue an error or a warning if a method has
+	 *    not been declared as <code>static</code>, even though it may qualify as one,
+	 *    when another method doesn't override it.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting a resource that is not closed properly.
+	 * <p>When enabled, the compiler will issue an error or a warning if
+	 *    a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) 
+	 *    or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if
+	 *    flow analysis shows that the method <code>close()</code> is not invoked locally on that value.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportUnclosedCloseable"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.unclosedCloseable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting a resource that may not be closed properly.
+	 * <p>When enabled, the compiler will issue an error or a warning if
+	 *    a local variable holds a value of type <code>java.lang.AutoCloseable</code> (compliance>=1.7) 
+	 *    or a value of type <code>java.io.Closeable</code> (compliance<=1.6) and if
+	 *    flow analysis shows that the method <code>close()</code> is 
+	 *    not invoked locally on that value for all execution paths.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE = PLUGIN_ID + ".compiler.problem.potentiallyUnclosedCloseable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting a resource that is not managed by try-with-resources.
+	 * <p>When enabled, the compiler will issue an error or a warning if a local variable 
+	 * 	  holds a value of type <code>java.lang.AutoCloseable</code>, and if the method
+	 *    <code>close()</code> is explicitly invoked on that resource, but the resource is
+	 *    not managed by a try-with-resources block.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPotentiallyUnclosedCloseable"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_EXPLICITLY_CLOSED_AUTOCLOSEABLE = PLUGIN_ID + ".compiler.problem.explicitlyClosedAutoCloseable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Annotation-based Null Analysis.
+	 * <p>This option controls whether the compiler will use null annotations for
+	 *    improved analysis of (potential) null references.</p>
+	 * <p>When enabled, the compiler will interpret the annotation types defined using
+	 *    {@link #COMPILER_NONNULL_ANNOTATION_NAME} and {@link #COMPILER_NULLABLE_ANNOTATION_NAME}
+	 *    as specifying whether or not a given type includes the value <code>null</code>.</p>
+	 * <p>The effect of these analyses is further controlled by the options
+	 *    {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+	 *    {@link #COMPILER_PB_NULL_ANNOTATION_INFERENCE_CONFLICT} and
+	 *    {@link #COMPILER_PB_NULL_UNCHECKED_CONVERSION}.
+	 * </p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nullanalysis"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "disabled", "enabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_ANNOTATION_NULL_ANALYSIS = PLUGIN_ID + ".compiler.annotation.nullanalysis"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Name of Annotation Type for Nullable Types.
+	 * <p>This option defines a fully qualified Java type name that the compiler may use
+	 *    to perform special null analysis.</p>
+	 * <p>If the annotation specified by this option is applied to a type in a method
+	 *    signature or variable declaration, this will be interpreted as a specification
+	 *    that <code>null</code> is a legal value in that position. Currently supported
+	 *    positions are: method parameters, method return type, fields and local variables.</p>
+	 * <p>If a value whose type
+	 *    is annotated with this annotation is dereferenced without checking for null,
+	 *    the compiler will trigger a diagnostic as further controlled by
+	 *    {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}.</p>
+	 * <p>The compiler may furthermore check adherence to the null specification as
+	 *    further controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+	 *    {@link #COMPILER_PB_NULL_ANNOTATION_INFERENCE_CONFLICT} and
+	 *    {@link #COMPILER_PB_NULL_UNCHECKED_CONVERSION}.</p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nullable"</code></dd>
+	 * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type.</dd>
+	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.Nullable"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_NULLABLE_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nullable"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Name of Annotation Type for Non-Null Types.
+	 * <p>This option defines a fully qualified Java type name that the compiler may use
+	 *    to perform special null analysis.</p>
+	 * <p>If the annotation specified by this option is applied to a type in a method
+	 *    signature or variable declaration, this will be interpreted as a specification
+	 *    that <code>null</code> is <b>not</b> a legal value in that position. Currently
+	 *    supported positions are: method parameters, method return type, fields and local variables.</p>
+	 * <p>For values declared with this annotation, the compiler will never trigger a null
+	 *    reference diagnostic (as controlled by {@link #COMPILER_PB_POTENTIAL_NULL_REFERENCE}
+	 *    and {@link #COMPILER_PB_NULL_REFERENCE}), because the assumption is made that null
+	 *    will never occur at runtime in these positions.</p>
+	 * <p>The compiler may furthermore check adherence to the null specification as further
+	 *    controlled by {@link #COMPILER_PB_NULL_SPECIFICATION_VIOLATION},
+	 *    {@link #COMPILER_PB_NULL_ANNOTATION_INFERENCE_CONFLICT} and
+	 *    {@link #COMPILER_PB_NULL_UNCHECKED_CONVERSION}.</p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnull"</code></dd>
+	 * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type.</dd>
+	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.NonNull"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_NONNULL_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnull"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Name of Annotation Type to specify a nullness default for unannotated types.
+	 * <p>This option defines a fully qualified Java type name that the compiler may use
+	 *    to perform special null analysis.</p>
+	 * <p>If the annotation is applied without an argument, all unannotated types in method signatures
+	 *    and field declarations within the annotated element will be treated as if they were specified
+	 *    with the non-null annotation (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}).</p>
+	 * <p>If the annotation is applied with the constant <code>false</code> as its argument
+	 *    all corresponding defaults at outer scopes will be canceled for the annotated element.</p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.nonnullbydefault"</code></dd>
+	 * <dt>Possible values:</dt><dd>any legal, fully qualified Java type name; must resolve to an annotation type.
+	 *     That annotation type should have exactly one boolean parameter.</dd>
+	 * <dt>Default:</dt><dd><code>"org.eclipse.jdt.annotation.NonNullByDefault"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME = PLUGIN_ID + ".compiler.annotation.nonnullbydefault"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting missing default nullness annotation.
+	 * <p>When enabled, the compiler will issue an error or a warning in the following cases:</p>
+	 * <ul>
+	 * <li> When a package does not contain a default nullness annotation, as a result of missing package-info.java 
+	 * or missing default nullness annotation in package-info.java.</li>
+	 * <li> When a type inside a default package does not contain a default nullness annotation.</li>
+	 * </ul>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code>.</dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION = PLUGIN_ID + ".compiler.annotation.missingNonNullByDefaultAnnotation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Violations of Null Specifications.
+	 * <p>Depending on this option, the compiler will issue either an error or a warning
+	 *    whenever one of the following situations is detected:</p>
+	 *    <ol>
+	 *    <li>A method declared with a nonnull annotation returns a
+	 *        <em>nullable</em> expression.</li>
+	 *    <li>A <em>nullable</em> expression is passed
+     *        as an argument in a method call where the corresponding parameter of the called
+     *        method is declared with a nonnull annotation.</li>
+	 *    <li>A <em>nullable</em> expression is assigned
+     *        to a local variable that is declared with a nonnull annotation.</li>
+	 *    <li>A method that overrides an inherited method declared with a nonnull annotation
+	 *        tries to relax that contract by specifying a nullable annotation
+	 *        (prohibition of contravariant return).</li>
+	 *    <li>A method that overrides an inherited method which has a nullable declaration
+	 *        for at least one of its parameters, tries to tighten that null contract by
+	 *        specifying a nonnull annotation for its corresponding parameter
+	 *        (prohibition of covariant parameters).</li>
+	 *    <li>A non-static field with a nonnull annotation is not definitely assigned at
+	 *        the end of each constructor.</li>
+	 *    <li>A static field with a nonnull annotation is not definitely assigned in static initializers.</li>
+	 *    </ol>
+	 *    In the above an expression is considered as <em>nullable</em> if
+	 *    either it is statically known to evaluate to the value <code>null</code>, or if it is
+	 *    declared with a nullable annotation.
+	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+	 *    shall interpret as nonnull or nullable annotations, respectively.
+	 * </p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullSpecViolation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NULL_SPECIFICATION_VIOLATION = PLUGIN_ID + ".compiler.problem.nullSpecViolation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting conflicts between declared null annotation and inferred null value 
+	 * <p>When enabled, the compiler will issue an error or a warning whenever one of the
+	 *    following situations is detected:</p>
+	 *    <ol>
+	 *    <li>A method declared with a nonnull annotation returns an expression that is
+	 *          statically known to evaluate to a null value on some flow.</li>
+	 *    <li>An expression that is statically known to evaluate to a null value on some flow
+	 *        is passed as an argument in a method call where the corresponding parameter of
+	 *        the called method is declared with a nonnull annotation.</li>
+	 *    <li>An expression that is statically known to evaluate to a null value on some flow
+	 *        is assigned to a local variable that is declared with a nonnull annotation.</li>
+	 *    </ol>
+	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+	 *    shall interpret as nonnull or nullable annotations, respectively.
+	 * </p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NULL_ANNOTATION_INFERENCE_CONFLICT = PLUGIN_ID + ".compiler.problem.nullAnnotationInferenceConflict"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting unchecked conversion from a type with unknown nullness to a null annotated type
+	 * <p>When enabled, the compiler will issue an error or a warning whenever one of the
+	 *    following situations is detected:</p>
+	 *    <ol>
+	 *    <li>A method declared with a nonnull annotation returns an expression for which
+	 *        insufficient nullness information is available for statically proving that no
+	 *        flow will pass a null value at runtime.</li>
+	 *    <li>An expression for which insufficient nullness information is available for
+	 *        statically proving that it will never evaluate to a null value at runtime
+	 *        is passed as an argument in a method call where the corresponding parameter of
+	 *        the called method is declared with a nonnull annotation.</li>
+	 *    <li>An expression for which insufficient nullness information is available for
+	 *        statically proving that it will never evaluate to a null value at runtime
+	 *        is assigned to a local variable that is declared with a nonnull annotation.</li>
+	 *    </ol>
+	 * <p>Unchecked null conversion is usually a consequence of using other unannotated
+	 *    variables or methods.</p>
+	 * <p>The compiler options {@link #COMPILER_NONNULL_ANNOTATION_NAME} and
+	 *    {@link #COMPILER_NULLABLE_ANNOTATION_NAME} control which annotations the compiler
+	 *    shall interpret as nonnull or nullable annotations, respectively.
+	 * </p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NULL_UNCHECKED_CONVERSION = PLUGIN_ID + ".compiler.problem.nullUncheckedConversion"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Redundant Null Annotations.
+	 * <p>When enabled, the compiler will issue an error or a warning when a non-null annotation
+	 *    (see {@link #COMPILER_NONNULL_ANNOTATION_NAME})
+	 *    is applied although the same effect is already achieved by a default applicable at the
+	 *    current location. Such a default may be set by using the annotation specified by the option
+	 *    {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}.
+	 * </p>
+	 * <p>This option only has an effect if the option {@link #COMPILER_ANNOTATION_NULL_ANALYSIS} is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.8
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_NULL_ANNOTATION = PLUGIN_ID + ".compiler.problem.redundantNullAnnotation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Perform syntactic null analysis for fields.
+	 * <p>When enabled, the compiler will detect certain syntactic constellations where a null
+	 *	  related warning against a field reference would normally be raised but can be suppressed
+	 *    at low risk given that the same field reference was known to be non-null immediately before.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "disabled", "enabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.9
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS = JavaCore.PLUGIN_ID+".compiler.problem.syntacticNullAnalysisForFields"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Inheritance of null annotations.
+	 * <p>When enabled, the compiler will check for each method without any explicit null annotations:
+	 *    If it overrides a method which has null annotations, it will treat the
+	 *    current method as if it had the same annotations as the overridden method.</p>
+	 * <p>Annotation inheritance will use the <em>effective</em> nullness of the overridden method
+	 *    after transitively applying inheritance and after applying any default nullness
+	 *    (see {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}) at the site of the overridden method.</p>
+	 * <p>If different implicit null annotations (from a nonnull default and/or overridden methods) are applicable
+	 *    to the same type in a method signature, this is flagged as an error 
+	 *    and an explicit null annotation must be used to disambiguate.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "disabled", "enabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.9
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_INHERIT_NULL_ANNOTATIONS = JavaCore.PLUGIN_ID+".compiler.annotation.inheritNullAnnotations"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Dropped Nonnull Parameter Annotations.
+	 * <p>When enabled, the compiler will issue an error or a warning against a parameter of 
+	 *    a method that overrides an inherited method
+	 *    if all of the following hold:</p>
+	 * <ul>
+	 *    <li>The overridden method declares the corresponding parameter as non-null (see {@link #COMPILER_NONNULL_ANNOTATION_NAME}).</li>
+	 *    <li>The parameter in the overriding method has no null annotation.</li>
+	 *    <li>The overriding method is not affected by a nullness default (see {@link #COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME}).</li>
+	 *    <li>Inheritance of null annotations is disabled (see {@link #COMPILER_INHERIT_NULL_ANNOTATIONS}).</li>
+	 * </ul>
+	 * <p>This particular situation bears the same inherent risk as any unannotated method parameter,
+	 *    because the compiler's null ananysis cannot decide wither <code>null</code> is or is not a legal value for this parameter.
+	 *    However, the annotation in the overridden method <em>suggests</em> that the parameter should also be annotated as non-null.
+	 *    If that is not intended or possible, it is recommended to annotate the parameter as nullable,
+	 *    in order to make this (legal) change of contract explicit.</p>   
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.9
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED = JavaCore.PLUGIN_ID+".compiler.problem.nonnullParameterAnnotationDropped"; //$NON-NLS-1$
+
+	/**
+	 * Compiler option ID: Setting Source Compatibility Mode.
+	 * <p>Specify whether which source level compatibility is used. From 1.4 on, <code>'assert'</code> is a keyword
+	 *    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
+	 *    level should be set to <code>"1.4"</code> and the compliance mode should be <code>"1.4"</code>.</p>
+	 * <p>Source level 1.5 is necessary to enable generics, autoboxing, covariance, annotations, enumerations
+	 *    enhanced for loop, static imports and varargs. Once toggled, the target VM level should be set to <code>"1.5"</code>
+	 *    and the compliance mode should be <code>"1.5"</code>.</p>
+	 * <p>Source level 1.6 is necessary to enable the computation of stack map tables. Once toggled, the target
+	 *    VM level should be set to <code>"1.6"</code> and the compliance mode should be <code>"1.6"</code>.</p>
+	 * <p>Once the source level 1.7 is toggled, the target VM level should be set to <code>"1.7"</code> and the compliance mode
+	 *    should be <code>"1.7"</code>.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.source"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "1.3", "1.4", "1.5", "1.6", "1.7" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"1.3"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_SOURCE = PLUGIN_ID + ".compiler.source"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Setting Compliance Level.
+	 * <p>Select the compliance level for the compiler. In <code>"1.3"</code> mode, source and target settings
+	 *    should not go beyond <code>"1.3"</code> level.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.compliance"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "1.3", "1.4", "1.5", "1.6", "1.7" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"1.4"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_COMPLIANCE = PLUGIN_ID + ".compiler.compliance"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Defining the Automatic Task Priorities.
+	 * <p>In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
+	 *    of the task markers issued by the compiler.
+	 *    If the default is specified, the priority of each task marker is <code>"NORMAL"</code>.</p>
+	 * <p>Task Priorities and task tags must have the same length. If task priorities are set, then task tags should also
+	 * be set.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.taskPriorities"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;priority&gt;[,&lt;priority&gt;]*" }</code> where <code>&lt;priority&gt;</code> is one of <code>"HIGH"</code>, <code>"NORMAL"</code> or <code>"LOW"</code></dd>
+	 * <dt>Default:</dt><dd><code>"NORMAL,HIGH,NORMAL"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 * @see #COMPILER_TASK_TAGS
+	 */
+	public static final String COMPILER_TASK_PRIORITIES = PLUGIN_ID + ".compiler.taskPriorities"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Defining the Automatic Task Tags.
+	 * <p>When the tag list is not empty, the compiler will issue a task marker whenever it encounters
+	 *    one of the corresponding tags inside any comment in Java source code.</p>
+	 * <p>Generated task messages will start with the tag, and range until the next line separator,
+	 *    comment ending, or tag.</p>
+	 * <p>When a given line of code bears multiple tags, each tag will be reported separately.
+	 *    Moreover, a tag immediately followed by another tag will be reported using the contents of the
+	 *    next non-empty tag of the line, if any.</p>
+	 * <p>Note that tasks messages are trimmed. If a tag is starting with a letter or digit, then it cannot be leaded by
+	 *    another letter or digit to be recognized (<code>"fooToDo"</code> will not be recognized as a task for tag <code>"ToDo"</code>, but <code>"foo#ToDo"</code>
+	 *    will be detected for either tag <code>"ToDo"</code> or <code>"#ToDo"</code>). Respectively, a tag ending with a letter or digit cannot be followed
+	 *    by a letter or digit to be recognized (<code>"ToDofoo"</code> will not be recognized as a task for tag <code>"ToDo"</code>, but <code>"ToDo:foo"</code> will
+	 *    be detected either for tag <code>"ToDo"</code> or <code>"ToDo:"</code>).</p>
+	 * <p>Task Priorities and task tags must have the same length. If task tags are set, then task priorities should also
+	 * be set.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.taskTags"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;tag&gt;[,&lt;tag&gt;]*" }</code> where <code>&lt;tag&gt;</code> is a String without any wild-card or leading/trailing spaces</dd>
+	 * <dt>Default:</dt><dd><code>"TODO,FIXME,XXX"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CompilerOptionID
+	 * @see #COMPILER_TASK_PRIORITIES
+	 */
+	public static final String COMPILER_TASK_TAGS = PLUGIN_ID + ".compiler.taskTags"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Determining whether task tags are case-sensitive.
+	 * <p>When enabled, task tags are considered in a case-sensitive way.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.taskCaseSensitive"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_TASK_CASE_SENSITIVE = PLUGIN_ID + ".compiler.taskCaseSensitive"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Forbidden Reference to Type with Restricted Access.
+	 * <p>When enabled, the compiler will issue an error or a warning when referring to a type that is non accessible, as defined according
+	 *    to the access rule specifications.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.forbiddenReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_FORBIDDEN_REFERENCE = PLUGIN_ID + ".compiler.problem.forbiddenReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Discouraged Reference to Type with Restricted Access.
+	 * <p>When enabled, the compiler will issue an error or a warning when referring to a type with discouraged access, as defined according
+	 *    to the access rule specifications.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.discouragedReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_DISCOURAGED_REFERENCE = PLUGIN_ID + ".compiler.problem.discouragedReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Determining Effect of <code>@SuppressWarnings</code>.
+	 * <p>When enabled, the <code>@SuppressWarnings</code> annotation can be used to suppress some compiler warnings.</p>
+	 * <p>When disabled, all <code>@SupressWarnings</code> annotations are ignored; i.e., warnings are reported.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.suppressWarnings"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SUPPRESS_WARNINGS = PLUGIN_ID + ".compiler.problem.suppressWarnings"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Raise null related errors or warnings arising because of assert statements.
+	 * <p>When enabled, the compiler will flag all null related errors or warnings that have been enabled by the user,
+	 *    irrespective of whether a variable occurred in an assert statement.</p>
+	 * <p>When disabled, the compiler will not flag null related errors or warnings on variables that got marked as maybe or definitely
+	 *    <code>null</code> in an assert statement upstream.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS = PLUGIN_ID + ".compiler.problem.includeNullInfoFromAsserts"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Further Determining the Effect of <code>@SuppressWarnings</code> if also
+	 * {@link #COMPILER_PB_SUPPRESS_WARNINGS} is enabled.
+	 * <p>When enabled, the <code>@SuppressWarnings</code> annotation can additionally be used to suppress 
+	 * optional compiler diagnostics that have been configured as {@link #ERROR}.</p>
+	 * <p>When disabled, all <code>@SuppressWarnings</code> annotations only affects warnings.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.6
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS = PLUGIN_ID + ".compiler.problem.suppressOptionalErrors"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unhandled Warning Token for <code>@SuppressWarnings</code>.
+	 * <p>When enabled, the compiler will issue an error or a warning when encountering a token
+	 *    it cannot handle inside a <code>@SuppressWarnings</code> annotation.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNHANDLED_WARNING_TOKEN = PLUGIN_ID + ".compiler.problem.unhandledWarningToken"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Unnecessary <code>@SuppressWarnings</code>.
+	 * <p>When enabled, the compiler will issue an error or a warning when encountering <code>@SuppressWarnings</code> annotation
+	 *    for which no corresponding warning got detected in the code. This diagnostic is provided to help developers to get
+	 *    rid of transient <code>@SuppressWarnings</code> no longer needed. Note that <code>@SuppressWarnings("all")</code> is still
+	 *    silencing the warning for unnecessary <code>@SuppressWarnings</code>, as it is the master switch to silence ALL warnings.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedWarningToken"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_WARNING_TOKEN = PLUGIN_ID + ".compiler.problem.unusedWarningToken"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Null Dereference.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a
+	 *    variable that is statically known to hold a null value is used to
+	 *    access a field or method.</p>
+	 * <p>Assert statements are ignored unless {@link #COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS}
+	 *    is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.nullReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_NULL_REFERENCE = PLUGIN_ID + ".compiler.problem.nullReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Potential Null Dereference.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a
+	 *    variable that has formerly been tested against null but is not (no more)
+	 *    statically known to hold a non-null value is used to access a field or
+	 *    method.</p>
+	 * <p>Assert statements are ignored unless {@link #COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS}
+	 *    is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.potentialNullReference"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.3
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POTENTIAL_NULL_REFERENCE = PLUGIN_ID + ".compiler.problem.potentialNullReference"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Redundant Null Check.
+	 * <p>When enabled, the compiler will issue an error or a warning whenever a
+	 *    variable that is statically known to hold a null or a non-null value
+	 *    is tested against null.</p>
+	 * <p>Assert statements are ignored unless {@link #COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS}
+	 *    is enabled.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.redundantNullCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.3
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_NULL_CHECK = PLUGIN_ID + ".compiler.problem.redundantNullCheck"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Overriding method that doesn't call the super method invocation.
+	 * <p>When enabled, the compiler will issue an error or a warning if a method is overriding a method without calling
+	 *    the super invocation.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.overridingMethodWithoutSuperInvocation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.3
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_OVERRIDING_METHOD_WITHOUT_SUPER_INVOCATION = PLUGIN_ID + ".compiler.problem.overridingMethodWithoutSuperInvocation"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Redundant Superinterface.
+	 * <p>When enabled, the compiler will issue an error or a warning if a type
+	 *    explicitly implements an interface that is already implemented by any
+	 *    of its supertypes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.4
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_SUPERINTERFACE = PLUGIN_ID + ".compiler.problem.redundantSuperinterface"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Comparison of Identical Expressions.
+	 * <p>When enabled, the compiler will issue an error or a warning if a comparison
+	 * is involving identical operands (e.g <code>'x == x'</code>).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.comparingIdentical"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_COMPARING_IDENTICAL = PLUGIN_ID + ".compiler.problem.comparingIdentical"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Missing Synchronized Modifier On Inherited Method.
+	 * <p>When enabled, the compiler will issue an error or a warning if a method
+	 * overrides a synchronized method without having a synchronized modifier.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD = PLUGIN_ID + ".compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Allocation of an Unused Object.
+	 * <p>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.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.6
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNUSED_OBJECT_ALLOCATION = PLUGIN_ID + ".compiler.problem.unusedObjectAllocation";  //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting redundant specification of type arguments in class instance creation expressions.
+	 * <p>When enabled, the compiler will issue an error or a warning if type arguments are used in a class instance creation,
+	 * when the '&lt;&gt;' operator can be used instead.</p>
+	 * <p>This option only has an effect if the compiler compliance is 1.7 or greater.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.7.1
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS = PLUGIN_ID + ".compiler.problem.redundantSpecificationOfTypeArguments";  //$NON-NLS-1$
+	/**
+	 * Core option ID: Computing Project Build Order.
+	 * <p>Indicate whether JavaCore should enforce the project build order to be based on
+	 *    the classpath prerequisite chain. When requesting to compute, this takes over
+	 *    the platform default order (based on project references).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.computeJavaBuildOrder"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "compute", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Specifying Filters for Resource Copying Control.
+	 * <p>Allow to specify some filters to control the resource copy process.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;name&gt;[,&lt;name&gt;]* }</code> where <code>&lt;name&gt;</code> is a file name pattern (* and ? wild-cards allowed)
+	 *	   or the name of a folder which ends with <code>'/'</code></dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_RESOURCE_COPY_FILTER = PLUGIN_ID + ".builder.resourceCopyExclusionFilter"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Reporting Duplicate Resources.
+	 * <p>Indicate the severity of the problem reported when more than one occurrence
+	 *    of a resource is to be copied into the output location.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.builder.duplicateResourceTask"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_DUPLICATE_RESOURCE = PLUGIN_ID + ".builder.duplicateResourceTask"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Cleaning Output Folder(s).
+	 * <p>Indicate whether the JavaBuilder is allowed to clean the output folders
+	 *    when performing full build operations.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.builder.cleanOutputFolder"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "clean", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"clean"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER = PLUGIN_ID + ".builder.cleanOutputFolder"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Recreate Modified class files in Output Folder.
+	 * <p>Indicate whether the JavaBuilder should check for any changes to .class files
+	 *    in the output folders while performing incremental build operations. If changes
+	 *    are detected to managed .class files, then a full build is performed, otherwise
+	 *    the changes are left as is. Tools further altering generated .class files, like optimizers,
+	 *    should ensure this option remains set in its default state of ignore.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER = PLUGIN_ID + ".builder.recreateModifiedClassFileInOutputFolder"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Reporting Incomplete Classpath.
+	 * <p>Indicate the severity of the problem reported when an entry on the classpath does not exist,
+	 *    is not legitimate or is not visible (for example, a referenced project is closed).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.incompleteClasspath"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning"}</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_INCOMPLETE_CLASSPATH = PLUGIN_ID + ".incompleteClasspath"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Reporting Classpath Cycle.
+	 * <p>Indicate the severity of the problem reported when a project is involved in a cycle.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.circularClasspath"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_CIRCULAR_CLASSPATH = PLUGIN_ID + ".circularClasspath"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Reporting Incompatible JDK Level for Required Binaries.
+	 * <p>Indicate the severity of the problem reported when a project prerequisites another project
+	 *    or library with an incompatible target JDK level (e.g. project targeting 1.1 vm, but compiled against 1.4 libraries).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.incompatibleJDKLevel"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"ignore"</code></dd>
+	 * </dl>
+	 * @since 3.0
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_INCOMPATIBLE_JDK_LEVEL = PLUGIN_ID + ".incompatibleJDKLevel"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Abort if Invalid Classpath.
+	 * <p>Allow to toggle the builder to abort if the classpath is invalid.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.builder.invalidClasspath"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "abort", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"abort"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_JAVA_BUILD_INVALID_CLASSPATH = PLUGIN_ID + ".builder.invalidClasspath"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Default Source Encoding Format.
+	 * <p>Get the default encoding format of source files. This value is
+	 *    immutable and preset to the result of <code>ResourcesPlugin.getEncoding()</code>.</p>
+	 * <p>It is offered as a convenience shortcut only.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.encoding"</code></dd>
+	 * <dt>value:</dt><dd><code>&lt;immutable, platform default value&gt;</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_ENCODING = PLUGIN_ID + ".encoding"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Enabling Usage of Classpath Exclusion Patterns.
+	 * <p>When disabled, no entry on a project classpath can be associated with
+	 *    an exclusion pattern.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.classpath.exclusionPatterns"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS = PLUGIN_ID + ".classpath.exclusionPatterns"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Enabling Usage of Classpath Multiple Output Locations.
+	 * <p>When disabled, no entry on a project classpath can be associated with
+	 *    a specific output location, preventing thus usage of multiple output locations.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.classpath.multipleOutputLocations"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CoreOptionID
+	 */
+	public static final String CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS = PLUGIN_ID + ".classpath.multipleOutputLocations"; //$NON-NLS-1$
+	/**
+	 * Core option ID: Reporting an output location overlapping another source location.
+	 * <p> Indicate the severity of the problem reported when a source entry's output location overlaps another
+	 * source entry.</p>
+	 * 
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "error", "warning", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"error"</code></dd>
+	 * </dl>
+	 * @since 3.6.4
+	 */
+	public static final String CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE = PLUGIN_ID + ".classpath.outputOverlappingAnotherSource";  //$NON-NLS-1$
+	/**
+	 * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc.
+	 * <p>Timeout in milliseconds to retrieve the method's parameter names from javadoc.</p>
+	 * <p>If the value is <code>0</code>, the parameter names are not fetched and the raw names are returned.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.timeoutForParameterNameFromAttachedJavadoc"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>"&lt;n&gt;"</code>, where <code>n</code> is an integer greater than or equal to <code>0</code></dd>
+	 * <dt>Default:</dt><dd><code>"50"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CoreOptionID
+	 */
+	public static final String TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC = PLUGIN_ID + ".timeoutForParameterNameFromAttachedJavadoc"; //$NON-NLS-1$
+
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_BLOCK} ,
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_SWITCH},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_NEWLINE_OPENING_BRACE = PLUGIN_ID + ".formatter.newline.openingBrace"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_NEWLINE_CONTROL = PLUGIN_ID + ".formatter.newline.controlStatement"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMPACT_ELSE_IF} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_NEWLINE_ELSE_IF = PLUGIN_ID + ".formatter.newline.elseIf"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_NEWLINE_EMPTY_BLOCK = PLUGIN_ID + ".formatter.newline.emptyBlock"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_CLEAR_BLANK_LINES = PLUGIN_ID + ".formatter.newline.clearAll"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_LINE_SPLIT} instead
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_LINE_SPLIT = PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_COMPACT_ASSIGNMENT = PLUGIN_ID + ".formatter.style.assignment"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_TAB_CHAR = PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
+	/**
+	 * @since 2.0
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_SIZE} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_TAB_SIZE = PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
+	/**
+	 * @since 2.1
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST} instead.
+	 * @category DeprecatedOptionID
+	 */
+	public static final String FORMATTER_SPACE_CASTEXPRESSION = PLUGIN_ID + ".formatter.space.castexpression"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Visibility Sensitive Completion.
+	 * <p>When active, completion doesn't show that you can not see
+	 *    (for example, you can not see private methods of a super class).</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.visibilityCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_VISIBILITY_CHECK = PLUGIN_ID + ".codeComplete.visibilityCheck"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Deprecation Sensitive Completion.
+	 * <p>When enabled, completion doesn't propose deprecated members and types.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.deprecationCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_DEPRECATION_CHECK = PLUGIN_ID + ".codeComplete.deprecationCheck"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Camel Case Sensitive Completion.
+	 * <p>When enabled, completion shows proposals whose name match the CamelCase
+	 *    pattern.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.camelCaseMatch"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.2
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_CAMEL_CASE_MATCH = PLUGIN_ID + ".codeComplete.camelCaseMatch"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Automatic Qualification of Implicit Members.
+	 * <p>When active, completion automatically qualifies completion on implicit
+	 *    field references and message expressions.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.forceImplicitQualification"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 2.0
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_IMPLICIT_QUALIFICATION = PLUGIN_ID + ".codeComplete.forceImplicitQualification"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Prefixes for Field Name.
+	 * <p>When the prefixes is non empty, completion for field name will begin with
+	 *    one of the proposed prefixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.fieldPrefixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;prefix&gt;[,&lt;prefix&gt;]*" }</code> where <code>&lt;prefix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.fieldPrefixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Prefixes for Static Field Name.
+	 * <p>When the prefixes is non empty, completion for static field name will begin with
+	 *    one of the proposed prefixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;prefix&gt;[,&lt;prefix&gt;]*" }</code> where <code>&lt;prefix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_STATIC_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.staticFieldPrefixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Prefixes for Static Final Field Name.
+	 * <p>When the prefixes is non empty, completion for static final field name will begin with
+	 *    one of the proposed prefixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;prefix&gt;[,&lt;prefix&gt;]*" }</code> where <code>&lt;prefix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_STATIC_FINAL_FIELD_PREFIXES = PLUGIN_ID + ".codeComplete.staticFinalFieldPrefixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Prefixes for Local Variable Name.
+	 * <p>When the prefixes is non empty, completion for local variable name will begin with
+	 *    one of the proposed prefixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.localPrefixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;prefix&gt;[,&lt;prefix&gt;]*" }</code> where <code>&lt;prefix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_LOCAL_PREFIXES = PLUGIN_ID + ".codeComplete.localPrefixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Prefixes for Argument Name.
+	 * <p>When the prefixes is non empty, completion for argument name will begin with
+	 *    one of the proposed prefixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.argumentPrefixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;prefix&gt;[,&lt;prefix&gt;]*" }</code> where <code>&lt;prefix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_ARGUMENT_PREFIXES = PLUGIN_ID + ".codeComplete.argumentPrefixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Suffixes for Field Name.
+	 * <p>When the suffixes is non empty, completion for field name will end with
+	 *    one of the proposed suffixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.fieldSuffixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;suffix&gt;[,&lt;suffix&gt;]*" }</code> where <code>&lt;suffix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.fieldSuffixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Suffixes for Static Field Name.
+	 * <p>When the suffixes is non empty, completion for static field name will end with
+	 *    one of the proposed suffixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;suffix&gt;[,&lt;suffix&gt;]*" }</code>< where <code>&lt;suffix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_STATIC_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.staticFieldSuffixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Suffixes for Static Final Field Name.
+	 * <p>When the suffixes is non empty, completion for static final field name will end with
+	 *    one of the proposed suffixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;suffix&gt;[,&lt;suffix&gt;]*" }</code>< where <code>&lt;suffix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 3.5
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES = PLUGIN_ID + ".codeComplete.staticFinalFieldSuffixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Suffixes for Local Variable Name.
+	 * <p>When the suffixes is non empty, completion for local variable name will end with
+	 *    one of the proposed suffixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.localSuffixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;suffix&gt;[,&lt;suffix&gt;]*" }</code> where <code>&lt;suffix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_LOCAL_SUFFIXES = PLUGIN_ID + ".codeComplete.localSuffixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Define the Suffixes for Argument Name.
+	 * <p>When the suffixes is non empty, completion for argument name will end with
+	 *    one of the proposed suffixes.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.argumentSuffixes"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "&lt;suffix&gt;[,&lt;suffix&gt;]*" }</code> where <code>&lt;suffix&gt;</code> is a String without any wild-card</dd>
+	 * <dt>Default:</dt><dd><code>""</code></dd>
+	 * </dl>
+	 * @since 2.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_ARGUMENT_SUFFIXES = PLUGIN_ID + ".codeComplete.argumentSuffixes"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Forbidden Reference Sensitive Completion.
+	 * <p>When enabled, completion doesn't propose elements which match a
+	 *    forbidden reference rule.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.forbiddenReferenceCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_FORBIDDEN_REFERENCE_CHECK= PLUGIN_ID + ".codeComplete.forbiddenReferenceCheck"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Discouraged Reference Sensitive Completion.
+	 * <p>When enabled, completion doesn't propose elements which match a
+	 *    discouraged reference rule.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @since 3.1
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_DISCOURAGED_REFERENCE_CHECK= PLUGIN_ID + ".codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
+	/**
+	 * Code assist option ID: Activate Suggestion of Static Import.
+	 * <p>When enabled, completion proposals can contain static import
+	 *    pattern.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.codeComplete.suggestStaticImports"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"enabled"</code></dd>
+	 * </dl>
+	 * @since 3.3
+	 * @category CodeAssistOptionID
+	 */
+	public static final String CODEASSIST_SUGGEST_STATIC_IMPORTS= PLUGIN_ID + ".codeComplete.suggestStaticImports"; //$NON-NLS-1$
+	// end configurable option IDs }
+	// Begin configurable option values {
+	/**
+	 * @deprecated Use {@link #DEFAULT_TASK_TAGS} instead.
+	 * @since 2.1
+	 * @category DeprecatedOptionValue
+	 */
+	public static final String DEFAULT_TASK_TAG = "TODO"; //$NON-NLS-1$
+	/**
+	 * @deprecated Use {@link #DEFAULT_TASK_PRIORITIES} instead.
+	 * @since 2.1
+	 * @category DeprecatedOptionValue
+	 */
+	public static final String DEFAULT_TASK_PRIORITY = "NORMAL"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String DEFAULT_TASK_TAGS = "TODO,FIXME,XXX"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String DEFAULT_TASK_PRIORITIES = "NORMAL,HIGH,NORMAL"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String GENERATE = "generate"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String DO_NOT_GENERATE = "do not generate"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String PRESERVE = "preserve"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String OPTIMIZE_OUT = "optimize out"; //$NON-NLS-1$
+	/**
+	 * Configurable option value for {@link #COMPILER_TASK_PRIORITIES}: {@value}.
+	 * @since 2.1
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_TASK_PRIORITY_HIGH = "HIGH"; //$NON-NLS-1$
+	/**
+	 * Configurable option value for {@link #COMPILER_TASK_PRIORITIES}: {@value}.
+	 * @since 2.1
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_TASK_PRIORITY_LOW = "LOW"; //$NON-NLS-1$
+	/**
+	 * Configurable option value for {@link #COMPILER_TASK_PRIORITIES}: {@value}.
+	 * @since 2.1
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_TASK_PRIORITY_NORMAL = "NORMAL"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_1 = "1.1"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_2 = "1.2"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_3 = "1.3"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_4 = "1.4"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_5 = "1.5"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.2
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_6 = "1.6"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.3
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_7 = "1.7"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.9 BETA_JAVA8
+	 * @category OptionValue
+	 */
+	public static final String VERSION_1_8 = "1.8"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.4
+	 * @category OptionValue
+	 */
+	public static final String VERSION_CLDC_1_1 = "cldc1.1"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String ABORT = "abort"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String ERROR = "error"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String WARNING = "warning"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String IGNORE = "ignore"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @category OptionValue
+	 */
+	public static final String COMPUTE = "compute"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String INSERT = "insert"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String DO_NOT_INSERT = "do not insert"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String PRESERVE_ONE = "preserve one"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String CLEAR_ALL = "clear all"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String NORMAL = "normal"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String COMPACT = "compact"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String TAB = "tab"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String SPACE = "space"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String ENABLED = "enabled"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.0
+	 * @category OptionValue
+	 */
+	public static final String DISABLED = "disabled"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 2.1
+	 * @category OptionValue
+	 */
+	public static final String CLEAN = "clean"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String PUBLIC = "public"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String PROTECTED = "protected"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String DEFAULT = "default"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.0
+	 * @category OptionValue
+	 */
+	public static final String PRIVATE = "private"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.1
+	 * @category OptionValue
+	 */
+	public static final String NEVER = "never"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.4
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_NO_TAG = CompilerOptions.NO_TAG;
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.4
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_RETURN_TAG = CompilerOptions.RETURN_TAG;
+	/**
+	 * Configurable option value: {@value}.
+	 * @since 3.4
+	 * @category OptionValue
+	 */
+	public static final String COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_ALL_STANDARD_TAGS = CompilerOptions.ALL_STANDARD_TAGS;
+	// end configurable option values }
+
+	/**
+	 * Value of the content-type for Java source files. Use this value to retrieve the Java content type
+	 * from the content type manager, and to add new Java-like extensions to this content type.
+	 *
+	 * @see org.eclipse.core.runtime.content.IContentTypeManager#getContentType(String)
+	 * @see #getJavaLikeExtensions()
+	 * @since 3.2
+	 */
+	public static final String JAVA_SOURCE_CONTENT_TYPE = JavaCore.PLUGIN_ID+".javaSource" ; //$NON-NLS-1$
+
+	/**
+	 * Creates the Java core plug-in.
+	 * <p>
+	 * The plug-in instance is created automatically by the
+	 * Eclipse platform. Clients must not call.
+	 * </p>
+	 *
+	 * @since 3.0
+	 */
+	public JavaCore() {
+		super();
+		JAVA_CORE_PLUGIN = this;
+	}
+
+	/**
+	 * Adds the given listener for changes to Java elements.
+	 * Has no effect if an identical listener is already registered.
+	 * <p>
+	 * This listener will only be notified during the POST_CHANGE resource change notification
+	 * and any reconcile operation (POST_RECONCILE).
+	 * </p>
+	 * <p>
+	 * For finer control of the notification, use <code>addElementChangedListener(IElementChangedListener,int)</code>,
+	 * which allows to specify a different eventMask.
+	 * </p>
+	 *
+	 * @param listener the listener
+	 * @see ElementChangedEvent
+	 */
+	public static void addElementChangedListener(IElementChangedListener listener) {
+		addElementChangedListener(listener, ElementChangedEvent.POST_CHANGE | ElementChangedEvent.POST_RECONCILE);
+	}
+
+	/**
+	 * Adds the given listener for changes to Java elements.
+	 * Has no effect if an identical listener is already registered.
+	 * After completion of this method, the given listener will be registered for exactly
+	 * the specified events.  If they were previously registered for other events, they
+	 * will be deregistered.
+	 * <p>
+	 * Once registered, a listener starts receiving notification of changes to
+	 * java elements in the model. The listener continues to receive
+	 * notifications until it is replaced or removed.
+	 * </p>
+	 * <p>
+	 * Listeners can listen for several types of event as defined in <code>ElementChangeEvent</code>.
+	 * Clients are free to register for any number of event types however if they register
+	 * for more than one, it is their responsibility to ensure they correctly handle the
+	 * case where the same java element change shows up in multiple notifications.
+	 * Clients are guaranteed to receive only the events for which they are registered.
+	 * </p>
+	 *
+	 * @param listener the listener
+	 * @param eventMask the bit-wise OR of all event types of interest to the listener
+	 * @see IElementChangedListener
+	 * @see ElementChangedEvent
+	 * @see #removeElementChangedListener(IElementChangedListener)
+	 * @since 2.0
+	 */
+	public static void addElementChangedListener(IElementChangedListener listener, int eventMask) {
+		JavaModelManager.getDeltaState().addElementChangedListener(listener, eventMask);
+	}
+
+	/**
+	 * Configures the given marker attribute map for the given Java element.
+	 * Used for markers, which denote a Java element rather than a resource.
+	 *
+	 * @param attributes the mutable marker attribute map (key type: <code>String</code>,
+	 *   value type: <code>String</code>)
+	 * @param element the Java element for which the marker needs to be configured
+	 */
+	public static void addJavaElementMarkerAttributes(
+		Map attributes,
+		IJavaElement element) {
+		if (element instanceof IMember)
+			element = ((IMember) element).getClassFile();
+		if (attributes != null && element != null)
+			attributes.put(ATT_HANDLE_ID, element.getHandleIdentifier());
+	}
+
+	private static void addNonJavaResources(Object[] nonJavaResources,
+			IContainer container,
+			int rootPathSegmentCounts,
+			ArrayList collector) {
+		for (int i = 0, max = nonJavaResources.length; i < max; i++) {
+			Object nonJavaResource = nonJavaResources[i];
+			if (nonJavaResource instanceof IFile) {
+				IFile file = (IFile) nonJavaResource;
+				IPath path = file.getFullPath().removeFirstSegments(rootPathSegmentCounts);
+				IResource member = container.findMember(path);
+				if (member != null && member.exists()) {
+					collector.add(member);
+				}
+			} else if (nonJavaResource instanceof IFolder) {
+				IFolder folder = (IFolder) nonJavaResource;
+				IResource[] members = null;
+				try {
+					members = folder.members();
+				} catch (CoreException e) {
+					// ignore
+				}
+				if (members != null) {
+					addNonJavaResources(members, container, rootPathSegmentCounts, collector);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Adds the given listener for POST_CHANGE resource change events to the Java core.
+	 * The listener is guaranteed to be notified of the POST_CHANGE resource change event before
+	 * the Java core starts processing the resource change event itself.
+	 * <p>
+	 * Has no effect if an identical listener is already registered.
+	 * </p>
+	 *
+	 * @param listener the listener
+	 * @see #removePreProcessingResourceChangedListener(IResourceChangeListener)
+	 * @since 3.0
+	 * @deprecated use addPreProcessingResourceChangedListener(listener, IResourceChangeEvent.POST_CHANGE) instead
+	 */
+	public static void addPreProcessingResourceChangedListener(IResourceChangeListener listener) {
+		addPreProcessingResourceChangedListener(listener, IResourceChangeEvent.POST_CHANGE);
+	}
+
+	/**
+	 * Adds the given listener for resource change events of the given types to the Java core.
+	 * The listener is guaranteed to be notified of the resource change event before
+	 * the Java core starts processing the resource change event itself.
+	 * <p>
+	 * If an identical listener is already registered, the given event types are added to the event types
+	 * of interest to the listener.
+	 * </p>
+	 * <p>
+	 * Supported event types are:
+	 * </p>
+	 * <ul>
+	 * <li>{@link IResourceChangeEvent#PRE_BUILD}</li>
+	 * <li>{@link IResourceChangeEvent#POST_BUILD}</li>
+	 * <li>{@link IResourceChangeEvent#POST_CHANGE}</li>
+	 * <li>{@link IResourceChangeEvent#PRE_DELETE}</li>
+	 * <li>{@link IResourceChangeEvent#PRE_CLOSE}</li>
+	 * </ul>
+	 * This list may increase in the future.
+	 *
+	 * @param listener the listener
+	 * @param eventMask the bit-wise OR of all event types of interest to the
+	 * listener
+	 * @see #removePreProcessingResourceChangedListener(IResourceChangeListener)
+	 * @see IResourceChangeEvent
+	 * @since 3.2
+	 */
+	public static void addPreProcessingResourceChangedListener(IResourceChangeListener listener, int eventMask) {
+		JavaModelManager.getDeltaState().addPreResourceChangedListener(listener, eventMask);
+	}
+
+	/**
+	 * Configures the given marker for the given Java element.
+	 * Used for markers, which denote a Java element rather than a resource.
+	 *
+	 * @param marker the marker to be configured
+	 * @param element the Java element for which the marker needs to be configured
+	 * @exception CoreException if the <code>IMarker.setAttribute</code> on the marker fails
+	 */
+	public void configureJavaElementMarker(IMarker marker, IJavaElement element)
+		throws CoreException {
+		if (element instanceof IMember)
+			element = ((IMember) element).getClassFile();
+		if (marker != null && element != null)
+			marker.setAttribute(ATT_HANDLE_ID, element.getHandleIdentifier());
+	}
+
+	/**
+	 * Returns the Java model element corresponding to the given handle identifier
+	 * generated by <code>IJavaElement.getHandleIdentifier()</code>, or
+	 * <code>null</code> if unable to create the associated element.
+	 *
+	 * @param handleIdentifier the given handle identifier
+	 * @return the Java element corresponding to the handle identifier
+	 */
+	public static IJavaElement create(String handleIdentifier) {
+		return create(handleIdentifier, DefaultWorkingCopyOwner.PRIMARY);
+	}
+
+	/**
+	 * Returns the Java model element corresponding to the given handle identifier
+	 * generated by <code>IJavaElement.getHandleIdentifier()</code>, or
+	 * <code>null</code> if unable to create the associated element.
+	 * If the returned Java element is an <code>ICompilationUnit</code> or an element
+	 * inside a compilation unit, the compilation unit's owner is the given owner if such a
+	 * working copy exists, otherwise the compilation unit is a primary compilation unit.
+	 *
+	 * @param handleIdentifier the given handle identifier
+	 * @param owner the owner of the returned compilation unit, ignored if the returned
+	 *   element is not a compilation unit, or an element inside a compilation unit
+	 * @return the Java element corresponding to the handle identifier
+	 * @since 3.0
+	 */
+	public static IJavaElement create(String handleIdentifier, WorkingCopyOwner owner) {
+		if (handleIdentifier == null) {
+			return null;
+		}
+		if (owner == null)
+			owner = DefaultWorkingCopyOwner.PRIMARY;
+		MementoTokenizer memento = new MementoTokenizer(handleIdentifier);
+		JavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+		return model.getHandleFromMemento(memento, owner);
+	}
+
+	/**
+	 * Returns the Java element corresponding to the given file, or
+	 * <code>null</code> if unable to associate the given file
+	 * with a Java element.
+	 *
+	 * <p>The file must be one of:</p>
+	 *	<ul>
+	 *	<li>a file with one of the {@link JavaCore#getJavaLikeExtensions()
+	 *      Java-like extensions} - the element returned is the corresponding <code>ICompilationUnit</code></li>
+	 *	<li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+	 *	<li>a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.) - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+	 *	</ul>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 * </p>
+	 *
+	 * @param file the given file
+	 * @return the Java element corresponding to the given file, or
+	 * <code>null</code> if unable to associate the given file
+	 * with a Java element
+	 */
+	public static IJavaElement create(IFile file) {
+		return JavaModelManager.create(file, null/*unknown java project*/);
+	}
+	/**
+	 * Returns the package fragment or package fragment root corresponding to the given folder, or
+	 * <code>null</code> if unable to associate the given folder with a Java element.
+	 * <p>
+	 * Note that a package fragment root is returned rather than a default package.
+	 * </p>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 * </p>
+	 *
+	 * @param folder the given folder
+	 * @return the package fragment or package fragment root corresponding to the given folder, or
+	 * <code>null</code> if unable to associate the given folder with a Java element
+	 */
+	public static IJavaElement create(IFolder folder) {
+		return JavaModelManager.create(folder, null/*unknown java project*/);
+	}
+	/**
+	 * Returns the Java project corresponding to the given project.
+	 * <p>
+	 * Creating a Java Project has the side effect of creating and opening all of the
+	 * project's parents if they are not yet open.
+	 * </p>
+	 * <p>
+	 * Note that no check is done at this time on the existence or the java nature of this project.
+	 * </p>
+	 *
+	 * @param project the given project
+	 * @return the Java project corresponding to the given project, null if the given project is null
+	 */
+	public static IJavaProject create(IProject project) {
+		if (project == null) {
+			return null;
+		}
+		JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel();
+		return javaModel.getJavaProject(project);
+	}
+	/**
+	 * Returns the Java element corresponding to the given resource, or
+	 * <code>null</code> if unable to associate the given resource
+	 * with a Java element.
+	 * <p>
+	 * The resource must be one of:
+	 * </p>
+	 *	<ul>
+	 *	<li>a project - the element returned is the corresponding <code>IJavaProject</code></li>
+	 *	<li>a file with one of the {@link JavaCore#getJavaLikeExtensions()
+	 *      Java-like extensions} - the element returned is the corresponding <code>ICompilationUnit</code></li>
+	 *	<li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+	 *	<li>a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.) - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+	 *  <li>a folder - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+	 *    	or <code>IPackageFragment</code></li>
+	 *  <li>the workspace root resource - the element returned is the <code>IJavaModel</code></li>
+	 *	</ul>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 * </p>
+	 *
+	 * @param resource the given resource
+	 * @return the Java element corresponding to the given resource, or
+	 * <code>null</code> if unable to associate the given resource
+	 * with a Java element
+	 */
+	public static IJavaElement create(IResource resource) {
+		return JavaModelManager.create(resource, null/*unknown java project*/);
+	}
+	/**
+	 * Returns the Java element corresponding to the given file, its project being the given
+	 * project. Returns <code>null</code> if unable to associate the given resource
+	 * with a Java element.
+	 * <p>
+	 * The resource must be one of:
+	 * </p>
+	 *	<ul>
+	 *	<li>a project - the element returned is the corresponding <code>IJavaProject</code></li>
+	 *	<li>a file with one of the {@link JavaCore#getJavaLikeExtensions()
+	 *      Java-like extensions} - the element returned is the corresponding <code>ICompilationUnit</code></li>
+	 *	<li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+	 *	<li>a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.) - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+	 *  <li>a folder - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+	 *    	or <code>IPackageFragment</code></li>
+	 *  <li>the workspace root resource - the element returned is the <code>IJavaModel</code></li>
+	 *	</ul>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 * </p>
+	 *
+	 * @param resource the given resource
+	 * @return the Java element corresponding to the given file, or
+	 * <code>null</code> if unable to associate the given file
+	 * with a Java element
+	 * @since 3.3
+	 */
+	public static IJavaElement create(IResource resource, IJavaProject project) {
+		return JavaModelManager.create(resource, project);
+	}
+	/**
+	 * Returns the Java model.
+	 *
+	 * @param root the given root
+	 * @return the Java model, or <code>null</code> if the root is null
+	 */
+	public static IJavaModel create(IWorkspaceRoot root) {
+		if (root == null) {
+			return null;
+		}
+		return JavaModelManager.getJavaModelManager().getJavaModel();
+	}
+	/**
+	 * Creates and returns a class file element for
+	 * the given <code>.class</code> file. Returns <code>null</code> if unable
+	 * to recognize the class file.
+	 *
+	 * @param file the given <code>.class</code> file
+	 * @return a class file element for the given <code>.class</code> file, or <code>null</code> if unable
+	 * to recognize the class file
+	 */
+	public static IClassFile createClassFileFrom(IFile file) {
+		return JavaModelManager.createClassFileFrom(file, null);
+	}
+	/**
+	 * Creates and returns a compilation unit element for
+	 * the given source file (i.e. a file with one of the {@link JavaCore#getJavaLikeExtensions()
+	 * Java-like extensions}). Returns <code>null</code> if unable
+	 * to recognize the compilation unit.
+	 *
+	 * @param file the given source file
+	 * @return a compilation unit element for the given source file, or <code>null</code> if unable
+	 * to recognize the compilation unit
+	 */
+	public static ICompilationUnit createCompilationUnitFrom(IFile file) {
+		return JavaModelManager.createCompilationUnitFrom(file, null/*unknown java project*/);
+	}
+	/**
+	 * Creates and returns a handle for the given JAR file.
+	 * The Java model associated with the JAR's project may be
+	 * created as a side effect.
+	 *
+	 * @param file the given JAR file
+	 * @return a handle for the given JAR file, or <code>null</code> if unable to create a JAR package fragment root.
+	 * (for example, if the JAR file represents a non-Java resource)
+	 */
+	public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file) {
+		return JavaModelManager.createJarPackageFragmentRootFrom(file, null/*unknown java project*/);
+	}
+
+	/**
+	 * Answers the project specific value for a given classpath container.
+	 * In case this container path could not be resolved, then will answer <code>null</code>.
+	 * Both the container path and the project context are supposed to be non-null.
+	 * <p>
+	 * The containerPath is a formed by a first ID segment followed with extra segments, which can be
+	 * used as additional hints for resolution. If no container was ever recorded for this container path
+	 * onto this project (using <code>setClasspathContainer</code>, then a
+	 * <code>ClasspathContainerInitializer</code> will be activated if any was registered for this container
+	 * ID onto the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+	 * </p>
+	 * <p>
+	 * There is no assumption that the returned container must answer the exact same containerPath
+	 * when requested <code>IClasspathContainer#getPath</code>.
+	 * Indeed, the containerPath is just an indication for resolving it to an actual container object.
+	 * </p>
+	 * <p>
+	 * Classpath container values are persisted locally to the workspace, but
+	 * are not preserved from a session to another. It is thus highly recommended to register a
+	 * <code>ClasspathContainerInitializer</code> for each referenced container
+	 * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+	 * </p>
+	 *
+	 * @param containerPath the name of the container, which needs to be resolved
+	 * @param project a specific project in which the container is being resolved
+	 * @return the corresponding classpath container or <code>null</code> if unable to find one.
+	 *
+	 * @exception JavaModelException if an exception occurred while resolving the container, or if the resolved container
+	 *   contains illegal entries (contains CPE_CONTAINER entries or null entries).
+	 *
+	 * @see ClasspathContainerInitializer
+	 * @see IClasspathContainer
+	 * @see #setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+	 * @since 2.0
+	 */
+	public static IClasspathContainer getClasspathContainer(IPath containerPath, IJavaProject project) throws JavaModelException {
+
+	    JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IClasspathContainer container = manager.getClasspathContainer(containerPath, project);
+		if (container == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
+		    return manager.getPreviousSessionContainer(containerPath, project);
+		}
+		return container;
+	}
+
+	/**
+	 * Helper method finding the classpath container initializer registered for a given classpath container ID
+	 * or <code>null</code> if none was found while iterating over the contributions to extension point to
+	 * the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+	 * <p>
+	 * A containerID is the first segment of any container path, used to identify the registered container initializer.
+	 * </p>
+	 * @param containerID - a containerID identifying a registered initializer
+	 * @return ClasspathContainerInitializer - the registered classpath container initializer or <code>null</code> if
+	 * none was found.
+	 * @since 2.1
+	 */
+	public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID) {
+		Hashtable containerInitializersCache = JavaModelManager.getJavaModelManager().containerInitializersCache;
+		ClasspathContainerInitializer initializer = (ClasspathContainerInitializer) containerInitializersCache.get(containerID);
+		if (initializer == null) {
+			initializer = computeClasspathContainerInitializer(containerID);
+			if (initializer == null)
+				return null;
+			containerInitializersCache.put(containerID, initializer);
+		}
+		return initializer;
+	}
+
+	private static ClasspathContainerInitializer computeClasspathContainerInitializer(String containerID) {
+		Plugin jdtCorePlugin = JavaCore.getPlugin();
+		if (jdtCorePlugin == null) return null;
+
+		IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID);
+		if (extension != null) {
+			IExtension[] extensions =  extension.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for(int j = 0; j < configElements.length; j++){
+					IConfigurationElement configurationElement = configElements[j];
+					String initializerID = configurationElement.getAttribute("id"); //$NON-NLS-1$
+					if (initializerID != null && initializerID.equals(containerID)){
+						if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+							verbose_found_container_initializer(containerID, configurationElement);
+						try {
+							Object execExt = configurationElement.createExecutableExtension("class"); //$NON-NLS-1$
+							if (execExt instanceof ClasspathContainerInitializer){
+								return (ClasspathContainerInitializer)execExt;
+							}
+						} catch(CoreException e) {
+							// executable extension could not be created: ignore this initializer
+							if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+								verbose_failed_to_instanciate_container_initializer(containerID, configurationElement);
+								e.printStackTrace();
+							}
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	private static void verbose_failed_to_instanciate_container_initializer(String containerID, IConfigurationElement configurationElement) {
+		Util.verbose(
+			"CPContainer INIT - failed to instanciate initializer\n" + //$NON-NLS-1$
+			"	container ID: " + containerID + '\n' + //$NON-NLS-1$
+			"	class: " + configurationElement.getAttribute("class"), //$NON-NLS-1$ //$NON-NLS-2$
+			System.err);
+	}
+
+	private static void verbose_found_container_initializer(String containerID, IConfigurationElement configurationElement) {
+		Util.verbose(
+			"CPContainer INIT - found initializer\n" + //$NON-NLS-1$
+			"	container ID: " + containerID + '\n' + //$NON-NLS-1$
+			"	class: " + configurationElement.getAttribute("class")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Returns the path held in the given classpath variable.
+	 * Returns <code>null</code> if unable to bind.
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 * <p>
+	 * Note that classpath variables can be contributed registered initializers for,
+	 * using the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+	 * If an initializer is registered for a variable, its persisted value will be ignored:
+	 * its initializer will thus get the opportunity to rebind the variable differently on
+	 * each session.
+	 * </p>
+	 *
+	 * @param variableName the name of the classpath variable
+	 * @return the path, or <code>null</code> if none
+	 * @see #setClasspathVariable(String, IPath)
+	 */
+	public static IPath getClasspathVariable(final String variableName) {
+
+	    JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IPath variablePath = manager.variableGet(variableName);
+		if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS){
+		    return manager.getPreviousSessionVariable(variableName);
+		}
+
+		if (variablePath != null) {
+			if (variablePath == JavaModelManager.CP_ENTRY_IGNORE_PATH)
+				return null;
+			return variablePath;
+		}
+
+		// even if persisted value exists, initializer is given priority, only if no initializer is found the persisted value is reused
+		final ClasspathVariableInitializer initializer = JavaCore.getClasspathVariableInitializer(variableName);
+		if (initializer != null){
+			if (JavaModelManager.CP_RESOLVE_VERBOSE)
+				verbose_triggering_variable_initialization(variableName, initializer);
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_triggering_variable_initialization_invocation_trace();
+			manager.variablePut(variableName, JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS); // avoid initialization cycles
+			boolean ok = false;
+			try {
+				// let OperationCanceledException go through
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59363)
+				initializer.initialize(variableName);
+
+				variablePath = manager.variableGet(variableName); // initializer should have performed side-effect
+				if (variablePath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) return null; // break cycle (initializer did not init or reentering call)
+				if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+					verbose_variable_value_after_initialization(variableName, variablePath);
+				manager.variablesWithInitializer.add(variableName);
+				ok = true;
+			} catch (RuntimeException e) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)
+					e.printStackTrace();
+				throw e;
+			} catch (Error e) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)
+					e.printStackTrace();
+				throw e;
+			} finally {
+				if (!ok) JavaModelManager.getJavaModelManager().variablePut(variableName, null); // flush cache
+			}
+		} else {
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)
+				verbose_no_variable_initializer_found(variableName);
+		}
+		return variablePath;
+	}
+
+	private static void verbose_no_variable_initializer_found(String variableName) {
+		Util.verbose(
+			"CPVariable INIT - no initializer found\n" + //$NON-NLS-1$
+			"	variable: " + variableName); //$NON-NLS-1$
+	}
+
+	private static void verbose_variable_value_after_initialization(String variableName, IPath variablePath) {
+		Util.verbose(
+			"CPVariable INIT - after initialization\n" + //$NON-NLS-1$
+			"	variable: " + variableName +'\n' + //$NON-NLS-1$
+			"	variable path: " + variablePath); //$NON-NLS-1$
+	}
+
+	private static void verbose_triggering_variable_initialization(String variableName, ClasspathVariableInitializer initializer) {
+		Util.verbose(
+			"CPVariable INIT - triggering initialization\n" + //$NON-NLS-1$
+			"	variable: " + variableName + '\n' + //$NON-NLS-1$
+			"	initializer: " + initializer); //$NON-NLS-1$
+	}
+
+	private static void verbose_triggering_variable_initialization_invocation_trace() {
+		Util.verbose(
+			"CPVariable INIT - triggering initialization\n" + //$NON-NLS-1$
+			"	invocation trace:"); //$NON-NLS-1$
+		new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns deprecation message of a given classpath variable.
+	 *
+	 * @param variableName
+	 * @return A string if the classpath variable is deprecated, <code>null</code> otherwise.
+	 * @since 3.3
+	 */
+	public static String getClasspathVariableDeprecationMessage(String variableName) {
+	    JavaModelManager manager = JavaModelManager.getJavaModelManager();
+
+		// Returns the stored deprecation message
+		String message = (String) manager.deprecatedVariables.get(variableName);
+		if (message != null) {
+		    return message;
+		}
+
+	    // If the variable has been already initialized, then there's no deprecation message
+		IPath variablePath = manager.variableGet(variableName);
+		if (variablePath != null && variablePath != JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) {
+			return null;
+		}
+
+		// Search for extension point to get the possible deprecation message
+		Plugin jdtCorePlugin = JavaCore.getPlugin();
+		if (jdtCorePlugin == null) return null;
+
+		IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+		if (extension != null) {
+			IExtension[] extensions =  extension.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for(int j = 0; j < configElements.length; j++){
+					IConfigurationElement configElement = configElements[j];
+					String varAttribute = configElement.getAttribute("variable"); //$NON-NLS-1$
+					if (variableName.equals(varAttribute)) {
+						String deprecatedAttribute = configElement.getAttribute("deprecated"); //$NON-NLS-1$
+						if (deprecatedAttribute != null) {
+							return deprecatedAttribute;
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Helper method finding the classpath variable initializer registered for a given classpath variable name
+	 * or <code>null</code> if none was found while iterating over the contributions to extension point to
+	 * the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+	 *
+ 	 * @param variable the given variable
+ 	 * @return ClasspathVariableInitializer - the registered classpath variable initializer or <code>null</code> if
+	 * none was found.
+	 * @since 2.1
+ 	 */
+	public static ClasspathVariableInitializer getClasspathVariableInitializer(String variable){
+
+		Plugin jdtCorePlugin = JavaCore.getPlugin();
+		if (jdtCorePlugin == null) return null;
+
+		IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+		if (extension != null) {
+			IExtension[] extensions =  extension.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for(int j = 0; j < configElements.length; j++){
+					IConfigurationElement configElement = configElements[j];
+					try {
+						String varAttribute = configElement.getAttribute("variable"); //$NON-NLS-1$
+						if (variable.equals(varAttribute)) {
+							if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+								verbose_found_variable_initializer(variable, configElement);
+							Object execExt = configElement.createExecutableExtension("class"); //$NON-NLS-1$
+							if (execExt instanceof ClasspathVariableInitializer){
+								ClasspathVariableInitializer initializer = (ClasspathVariableInitializer)execExt;
+								String deprecatedAttribute = configElement.getAttribute("deprecated"); //$NON-NLS-1$
+								if (deprecatedAttribute != null) {
+									JavaModelManager.getJavaModelManager().deprecatedVariables.put(variable, deprecatedAttribute);
+								}
+								String readOnlyAttribute = configElement.getAttribute("readOnly"); //$NON-NLS-1$
+								if (JavaModelManager.TRUE.equals(readOnlyAttribute)) {
+									JavaModelManager.getJavaModelManager().readOnlyVariables.add(variable);
+								}
+								return initializer;
+							}
+						}
+					} catch(CoreException e){
+						// executable extension could not be created: ignore this initializer
+						if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+							verbose_failed_to_instanciate_variable_initializer(variable, configElement);
+							e.printStackTrace();
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	private static void verbose_failed_to_instanciate_variable_initializer(String variable, IConfigurationElement configElement) {
+		Util.verbose(
+			"CPContainer INIT - failed to instanciate initializer\n" + //$NON-NLS-1$
+			"	variable: " + variable + '\n' + //$NON-NLS-1$
+			"	class: " + configElement.getAttribute("class"), //$NON-NLS-1$ //$NON-NLS-2$
+			System.err);
+	}
+
+	private static void verbose_found_variable_initializer(String variable, IConfigurationElement configElement) {
+		Util.verbose(
+			"CPVariable INIT - found initializer\n" + //$NON-NLS-1$
+			"	variable: " + variable + '\n' + //$NON-NLS-1$
+			"	class: " + configElement.getAttribute("class")); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Returns the names of all known classpath variables.
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 *
+	 * @return the list of classpath variable names
+	 * @see #setClasspathVariable(String, IPath)
+	 */
+	public static String[] getClasspathVariableNames() {
+		return JavaModelManager.getJavaModelManager().variableNames();
+	}
+
+	/**
+	 * Returns a table of all known configurable options with their default values.
+	 * These options allow to configure the behaviour of the underlying components.
+	 * The client may safely use the result as a template that they can modify and
+	 * then pass to <code>setOptions</code>.
+	 * <p>
+	 * Helper constants have been defined on JavaCore for each of the option IDs
+	 * (categorized in Code assist option ID, Compiler option ID and Core option ID)
+	 * and some of their acceptable values (categorized in Option value). Some
+	 * options accept open value sets beyond the documented constant values.
+	 * </p>
+	 * <p>
+	 * Note: each release may add new options.
+	 * </p>
+	 *
+	 * @return a table of all known configurable options with their default values
+	 */
+	public static Hashtable getDefaultOptions(){
+		return JavaModelManager.getJavaModelManager().getDefaultOptions();
+	}
+
+	/**
+	 * Returns the workspace root default charset encoding.
+	 *
+	 * @return the name of the default charset encoding for workspace root.
+	 * @see IContainer#getDefaultCharset()
+	 * @see ResourcesPlugin#getEncoding()
+	 * @since 3.0
+	 */
+	public static String getEncoding() {
+		try {
+			return ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
+		}
+		catch (IllegalStateException ise) {
+			// happen when there's no workspace (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=216817)
+			// or when it is shutting down (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=60687)
+			return System.getProperty("file.encoding"); //$NON-NLS-1$
+		}
+		catch (CoreException ce) {
+			// fails silently and return plugin global encoding if core exception occurs
+		}
+		return ResourcesPlugin.getEncoding();
+	}
+
+	/**
+	 * Returns an array that contains the resources generated by the Java builder when building the
+	 * compilation units contained in the given region.
+	 * <p>The contents of the array is accurate only if the elements of the given region have been built.</p>
+	 * <p>The given region can contain instances of:</p>
+	 * <ul>
+	 * <li><code>org.eclipse.jdt.core.ICompilationUnit</code></li>
+	 * <li><code>org.eclipse.jdt.core.IPackageFragment</code></li>
+	 * <li><code>org.eclipse.jdt.core.IPackageFragmentRoot</code></li>
+	 * <li><code>org.eclipse.jdt.core.IJavaProject</code></li>
+	 * </ul>
+	 * <p>All other types of <code>org.eclipse.jdt.core.IJavaElement</code> are ignored.</p>
+	 *
+	 * @param region the given region
+	 * @param includesNonJavaResources a flag that indicates if non-java resources should be included
+	 *
+	 * @return an array that contains the resources generated by the Java builder when building the
+	 * compilation units contained in the given region, an empty array if none
+	 * @exception IllegalArgumentException if the given region is <code>null</code>
+	 * @since 3.3
+	 */
+	public static IResource[] getGeneratedResources(IRegion region, boolean includesNonJavaResources) {
+		if (region == null) throw new IllegalArgumentException("region cannot be null"); //$NON-NLS-1$
+		IJavaElement[] elements = region.getElements();
+		HashMap projectsStates = new HashMap();
+		ArrayList collector = new ArrayList();
+		for (int i = 0, max = elements.length; i < max; i++) {
+			// collect all the java project
+			IJavaElement element = elements[i];
+			IJavaProject javaProject = element.getJavaProject();
+			IProject project = javaProject.getProject();
+			State state = null;
+			State currentState = (State) projectsStates.get(project);
+			if (currentState != null) {
+				state = currentState;
+			} else {
+				state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, null);
+				if (state != null) {
+					projectsStates.put(project, state);
+				}
+			}
+			if (state == null) continue;
+			if (element.getElementType() == IJavaElement.JAVA_PROJECT) {
+				IPackageFragmentRoot[] roots = null;
+				try {
+					roots = javaProject.getPackageFragmentRoots();
+				} catch (JavaModelException e) {
+					// ignore
+				}
+				if (roots == null) continue;
+				IRegion region2 = JavaCore.newRegion();
+				for (int j = 0; j < roots.length; j++) {
+					region2.add(roots[j]);
+				}
+				IResource[] res = getGeneratedResources(region2, includesNonJavaResources);
+				for (int j = 0, max2 = res.length; j < max2; j++) {
+					collector.add(res[j]);
+				}
+				continue;
+			}
+			IPath outputLocation = null;
+			try {
+				outputLocation = javaProject.getOutputLocation();
+			} catch (JavaModelException e) {
+				// ignore
+			}
+			IJavaElement root = element;
+			while (root != null && root.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT) {
+				root = root.getParent();
+			}
+			if (root == null) continue;
+			IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) root;
+			int rootPathSegmentCounts = packageFragmentRoot.getPath().segmentCount();
+			try {
+				IClasspathEntry entry = packageFragmentRoot.getRawClasspathEntry();
+				IPath entryOutputLocation = entry.getOutputLocation();
+				if (entryOutputLocation != null) {
+					outputLocation = entryOutputLocation;
+				}
+			} catch (JavaModelException e) {
+				e.printStackTrace();
+			}
+			if (outputLocation == null) continue;
+			IContainer container = (IContainer) project.getWorkspace().getRoot().findMember(outputLocation);
+			switch(element.getElementType()) {
+				case IJavaElement.COMPILATION_UNIT :
+					// get the .class files generated when this element was built
+					ICompilationUnit unit = (ICompilationUnit) element;
+					getGeneratedResource(unit, container, state, rootPathSegmentCounts, collector);
+					break;
+				case IJavaElement.PACKAGE_FRAGMENT :
+					// collect all the .class files generated when all the units in this package were built
+					IPackageFragment fragment = (IPackageFragment) element;
+					ICompilationUnit[] compilationUnits = null;
+					try {
+						compilationUnits = fragment.getCompilationUnits();
+					} catch (JavaModelException e) {
+						// ignore
+					}
+					if (compilationUnits == null) continue;
+					for (int j = 0, max2 = compilationUnits.length; j < max2; j++) {
+						getGeneratedResource(compilationUnits[j], container, state, rootPathSegmentCounts, collector);
+					}
+					if (includesNonJavaResources) {
+						// retrieve all non-java resources from the output location using the package fragment path
+						Object[] nonJavaResources = null;
+						try {
+							nonJavaResources = fragment.getNonJavaResources();
+						} catch (JavaModelException e) {
+							// ignore
+						}
+						if (nonJavaResources != null) {
+							addNonJavaResources(nonJavaResources, container, rootPathSegmentCounts, collector);
+						}
+					}
+					break;
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+					// collect all the .class files generated when all the units in this package were built
+					IPackageFragmentRoot fragmentRoot = (IPackageFragmentRoot) element;
+					if (fragmentRoot.isArchive()) continue;
+					IJavaElement[] children = null;
+					try {
+						children = fragmentRoot.getChildren();
+					} catch (JavaModelException e) {
+						// ignore
+					}
+					if (children == null) continue;
+					for (int j = 0, max2 = children.length; j < max2; j++) {
+						fragment = (IPackageFragment) children[j];
+						ICompilationUnit[] units = null;
+						try {
+							units = fragment.getCompilationUnits();
+						} catch (JavaModelException e) {
+							// ignore
+						}
+						if (units == null) continue;
+						for (int n = 0, max3 = units.length; n < max3; n++) {
+							getGeneratedResource(units[n], container, state, rootPathSegmentCounts, collector);
+						}
+						if (includesNonJavaResources) {
+							// retrieve all non-java resources from the output location using the package fragment path
+							Object[] nonJavaResources = null;
+							try {
+								nonJavaResources = fragment.getNonJavaResources();
+							} catch (JavaModelException e) {
+								// ignore
+							}
+							if (nonJavaResources != null) {
+								addNonJavaResources(nonJavaResources, container, rootPathSegmentCounts, collector);
+							}
+						}
+					}
+					break;
+			}
+		}
+		int size = collector.size();
+		if (size != 0) {
+			IResource[] result = new IResource[size];
+			collector.toArray(result);
+			return result;
+		}
+		return NO_GENERATED_RESOURCES;
+	}
+
+	private static void getGeneratedResource(ICompilationUnit unit,
+			IContainer container,
+			State state,
+			int rootPathSegmentCounts,
+			ArrayList collector) {
+		IResource resource = unit.getResource();
+		char[][] typeNames = state.getDefinedTypeNamesFor(resource.getProjectRelativePath().toString());
+		if (typeNames != null) {
+			IPath path = unit.getPath().removeFirstSegments(rootPathSegmentCounts).removeLastSegments(1);
+			for (int j = 0, max2 = typeNames.length; j < max2; j++) {
+				IPath localPath = path.append(new String(typeNames[j]) + ".class"); //$NON-NLS-1$
+				IResource member = container.findMember(localPath);
+				if (member != null && member.exists()) {
+					collector.add(member);
+				}
+			}
+		} else {
+			IPath path = unit.getPath().removeFirstSegments(rootPathSegmentCounts).removeLastSegments(1);
+			path = path.append(Util.getNameWithoutJavaLikeExtension(unit.getElementName()) + ".class"); //$NON-NLS-1$
+			IResource member = container.findMember(path);
+			if (member != null && member.exists()) {
+				collector.add(member);
+			}
+		}
+	}
+
+	/**
+	 * Returns the single instance of the Java core plug-in runtime class.
+	 * Equivalent to <code>(JavaCore) getPlugin()</code>.
+	 *
+	 * @return the single instance of the Java core plug-in runtime class
+	 */
+	public static JavaCore getJavaCore() {
+		return (JavaCore) getPlugin();
+	}
+
+	/**
+	 * Returns the list of known Java-like extensions.
+	 * Java like extension are defined in the {@link org.eclipse.core.runtime.Platform#getContentTypeManager()
+	 * content type manager} for the {@link #JAVA_SOURCE_CONTENT_TYPE}.
+	 * <p>
+	 * Note that a Java-like extension doesn't include the leading dot ('.').
+	 * Also note that the "java" extension is always defined as a Java-like extension.
+	 * </p>
+	 *
+	 * @return the list of known Java-like extensions.
+	 * @since 3.2
+	 */
+	public static String[] getJavaLikeExtensions() {
+		return CharOperation.toStrings(Util.getJavaLikeExtensions());
+	}
+
+	/**
+	 * Helper method for returning one option value only. Equivalent to <code>(String)JavaCore.getOptions().get(optionName)</code>
+	 * Note that it may answer <code>null</code> if this option does not exist.
+	 * <p>
+	 * Helper constants have been defined on JavaCore for each of the option IDs
+	 * (categorized in Code assist option ID, Compiler option ID and Core option ID)
+	 * and some of their acceptable values (categorized in Option value). Some
+	 * options accept open value sets beyond the documented constant values.
+	 * </p>
+	 * <p>
+	 * Note: each release may add new options.
+	 * </p>
+	 *
+	 * @param optionName the name of an option
+	 * @return the String value of a given option
+	 * @see JavaCore#getDefaultOptions()
+	 * @see JavaCorePreferenceInitializer for changing default settings
+	 * @since 2.0
+	 */
+	public static String getOption(String optionName) {
+		return JavaModelManager.getJavaModelManager().getOption(optionName);
+	}
+
+	/**
+	 * Returns the option that can be used to configure the severity of the
+	 * compiler problem identified by <code>problemID</code> if any,
+	 * <code>null</code> otherwise. Non-null return values are taken from the
+	 * constants defined by this class whose names start with
+	 * <code>COMPILER_PB</code> and for which the possible values of the
+	 * option are defined by <code>{ "error", "warning", "ignore" }</code>. A
+	 * null return value means that the provided problem ID is unknown or that
+	 * it matches a problem whose severity cannot be configured.
+	 * @param problemID one of the problem IDs defined by {@link IProblem}
+	 * @return the option that can be used to configure the severity of the
+	 *         compiler problem identified by <code>problemID</code> if any,
+	 *         <code>null</code> otherwise
+	 * @since 3.4
+	 */
+	public static String getOptionForConfigurableSeverity(int problemID) {
+		return CompilerOptions.optionKeyFromIrritant(ProblemReporter.getIrritant(problemID));
+	}
+
+	/**
+	 * Returns the table of the current options. Initially, all options have their default values,
+	 * and this method returns a table that includes all known options.
+	 * <p>
+	 * Helper constants have been defined on JavaCore for each of the option IDs
+	 * (categorized in Code assist option ID, Compiler option ID and Core option ID)
+	 * and some of their acceptable values (categorized in Option value). Some
+	 * options accept open value sets beyond the documented constant values.
+	 * </p>
+	 * <p>
+	 * Note: each release may add new options.
+	 * </p>
+	 * <p>Returns a default set of options even if the platform is not running.</p>
+	 *
+	 * @return table of current settings of all options
+	 *   (key type: <code>String</code>; value type: <code>String</code>)
+	 * @see #getDefaultOptions()
+	 * @see JavaCorePreferenceInitializer for changing default settings
+	 */
+	public static Hashtable getOptions() {
+		return JavaModelManager.getJavaModelManager().getOptions();
+	}
+
+	/**
+	 * Returns the single instance of the Java core plug-in runtime class.
+	 *
+	 * @return the single instance of the Java core plug-in runtime class
+	 */
+	public static Plugin getPlugin() {
+		return JAVA_CORE_PLUGIN;
+	}
+
+	/**
+	 * This is a helper method, which returns the resolved classpath entry denoted
+	 * by a given entry (if it is a variable entry). It is obtained by resolving the variable
+	 * reference in the first segment. Returns <code>null</code> if unable to resolve using
+	 * the following algorithm:
+	 * <ul>
+	 * <li> if variable segment cannot be resolved, returns <code>null</code></li>
+	 * <li> finds a project, JAR or binary folder in the workspace at the resolved path location</li>
+	 * <li> if none finds an external JAR file or folder outside the workspace at the resolved path location </li>
+	 * <li> if none returns <code>null</code></li>
+	 * </ul>
+	 * <p>
+	 * Variable source attachment path and root path are also resolved and recorded in the resulting classpath entry.
+	 * </p>
+	 * <p>
+	 * NOTE: This helper method does not handle classpath containers, for which should rather be used
+	 * <code>JavaCore#getClasspathContainer(IPath, IJavaProject)</code>.
+	 * </p>
+	 *
+	 * @param entry the given variable entry
+	 * @return the resolved library or project classpath entry, or <code>null</code>
+	 *   if the given variable entry could not be resolved to a valid classpath entry
+	 */
+	public static IClasspathEntry getResolvedClasspathEntry(IClasspathEntry entry) {
+		return JavaModelManager.getJavaModelManager().resolveVariableEntry(entry, false/*don't use previous session value*/);
+	}
+
+
+	/**
+	 * Resolve a variable path (helper method).
+	 *
+	 * @param variablePath the given variable path
+	 * @return the resolved variable path or <code>null</code> if none
+	 */
+	public static IPath getResolvedVariablePath(IPath variablePath) {
+		return JavaModelManager.getJavaModelManager().getResolvedVariablePath(variablePath, false/*don't use previous session value*/);
+	}
+
+	/**
+	 * Answers the shared working copies currently registered for this buffer factory.
+	 * Working copies can be shared by several clients using the same buffer factory,see
+	 * <code>IWorkingCopy.getSharedWorkingCopy</code>.
+	 *
+	 * @param factory the given buffer factory
+	 * @return the list of shared working copies for a given buffer factory
+	 * @since 2.0
+	 * @deprecated Use {@link #getWorkingCopies(WorkingCopyOwner)} instead
+	 */
+	public static IWorkingCopy[] getSharedWorkingCopies(IBufferFactory factory){
+
+		// if factory is null, default factory must be used
+		if (factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory();
+
+		return getWorkingCopies(BufferFactoryWrapper.create(factory));
+	}
+
+	/**
+	 * Returns the names of all defined user libraries. The corresponding classpath container path
+	 * is the name appended to the USER_LIBRARY_CONTAINER_ID.
+	 * @return Return an array containing the names of all known user defined.
+	 * @since 3.0
+	 */
+	public static String[] getUserLibraryNames() {
+		 return JavaModelManager.getUserLibraryManager().getUserLibraryNames();
+	}
+
+	/**
+	 * Returns the working copies that have the given owner.
+	 * Only compilation units in working copy mode are returned.
+	 * If the owner is <code>null</code>, primary working copies are returned.
+	 *
+	 * @param owner the given working copy owner or <code>null</code> for primary working copy owner
+	 * @return the list of working copies for a given owner
+	 * @since 3.0
+	 */
+	public static ICompilationUnit[] getWorkingCopies(WorkingCopyOwner owner){
+
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		if (owner == null) owner = DefaultWorkingCopyOwner.PRIMARY;
+		ICompilationUnit[] result = manager.getWorkingCopies(owner, false/*don't add primary WCs*/);
+		if (result == null) return JavaModelManager.NO_WORKING_COPY;
+		return result;
+	}
+
+	/**
+	 * Initializes JavaCore internal structures to allow subsequent operations (such
+	 * as the ones that need a resolved classpath) to run full speed. A client may
+	 * choose to call this method in a background thread early after the workspace
+	 * has started so that the initialization is transparent to the user.
+	 * <p>
+	 * However calling this method is optional. Services will lazily perform
+	 * initialization when invoked. This is only a way to reduce initialization
+	 * overhead on user actions, if it can be performed before at some
+	 * appropriate moment.
+	 * </p><p>
+	 * This initialization runs across all Java projects in the workspace. Thus the
+	 * workspace root scheduling rule is used during this operation.
+	 * </p><p>
+	 * This method may return before the initialization is complete. The
+	 * initialization will then continue in a background thread.
+	 * </p><p>
+	 * This method can be called concurrently.
+	 * </p>
+	 *
+	 * @param monitor a progress monitor, or <code>null</code> if progress
+	 *    reporting and cancellation are not desired
+	 * @exception CoreException if the initialization fails,
+	 * 		the status of the exception indicates the reason of the failure
+	 * @since 3.1
+	 */
+	public static void initializeAfterLoad(IProgressMonitor monitor) throws CoreException {
+		try {
+			if (monitor != null) {
+				monitor.beginTask(Messages.javamodel_initialization, 100);
+				monitor.subTask(Messages.javamodel_configuring_classpath_containers);
+			}
+
+			// initialize all containers and variables
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			SubProgressMonitor subMonitor = null;
+			try {
+				if (monitor != null) {
+					subMonitor = new SubProgressMonitor(monitor, 50); // 50% of the time is spent in initializing containers and variables
+					subMonitor.beginTask("", 100); //$NON-NLS-1$
+					subMonitor.worked(5); // give feedback to the user that something is happening
+					manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(subMonitor);
+				}
+				if (manager.forceBatchInitializations(true/*initAfterLoad*/)) { // if no other thread has started the batch container initializations
+					manager.getClasspathContainer(Path.EMPTY, null); // force the batch initialization
+				} else { // else wait for the batch initialization to finish
+					while (manager.batchContainerInitializations == JavaModelManager.BATCH_INITIALIZATION_IN_PROGRESS) {
+						if (subMonitor != null) {
+							subMonitor.subTask(manager.batchContainerInitializationsProgress.subTaskName);
+							subMonitor.worked(manager.batchContainerInitializationsProgress.getWorked());
+						}
+						synchronized(manager) {
+							try {
+								manager.wait(100);
+							} catch (InterruptedException e) {
+								// continue
+							}
+						}
+					}
+				}
+			} finally {
+				if (subMonitor != null)
+					subMonitor.done();
+				manager.batchContainerInitializationsProgress.initializeAfterLoadMonitor.set(null);
+			}
+
+			// avoid leaking source attachment properties (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183413 )
+			// and recreate links for external folders if needed
+			if (monitor != null)
+				monitor.subTask(Messages.javamodel_resetting_source_attachment_properties);
+			final IJavaProject[] projects = manager.getJavaModel().getJavaProjects();
+			HashSet visitedPaths = new HashSet();
+			ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
+			for (int i = 0, length = projects.length; i < length; i++) {
+				JavaProject javaProject = (JavaProject) projects[i];
+				IClasspathEntry[] classpath;
+				try {
+					classpath = javaProject.getResolvedClasspath();
+				} catch (JavaModelException e) {
+					// project no longer exist: ignore
+					continue;
+				}
+				if (classpath != null) {
+					for (int j = 0, length2 = classpath.length; j < length2; j++) {
+						IClasspathEntry entry = classpath[j];
+						if (entry.getSourceAttachmentPath() != null) {
+							IPath entryPath = entry.getPath();
+							if (visitedPaths.add(entryPath)) {
+								Util.setSourceAttachmentProperty(entryPath, null);
+							}
+						}
+						// else source might have been attached by IPackageFragmentRoot#attachSource(...), we keep it
+						if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+							IPath entryPath = entry.getPath();
+							if (ExternalFoldersManager.isExternalFolderPath(entryPath) && externalFoldersManager.getFolder(entryPath) == null) {
+								externalFoldersManager.addFolder(entryPath, true);
+							}
+						}
+					}
+				}
+			}
+			try {
+				externalFoldersManager.createPendingFolders(monitor);
+			}
+			catch(JavaModelException jme) {
+				// Creation of external folder project failed. Log it and continue;
+				Util.log(jme, "Error while processing external folders"); //$NON-NLS-1$
+			}
+			// initialize delta state
+			if (monitor != null)
+				monitor.subTask(Messages.javamodel_initializing_delta_state);
+			manager.deltaState.rootsAreStale = true; // in case it was already initialized before we cleaned up the source attachment properties
+			manager.deltaState.initializeRoots(true/*initAfteLoad*/);
+
+			// dummy query for waiting until the indexes are ready
+			if (monitor != null)
+				monitor.subTask(Messages.javamodel_configuring_searchengine);
+			SearchEngine engine = new SearchEngine();
+			IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
+			try {
+				engine.searchAllTypeNames(
+					null,
+					SearchPattern.R_EXACT_MATCH,
+					"!@$#!@".toCharArray(), //$NON-NLS-1$
+					SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
+					IJavaSearchConstants.CLASS,
+					scope,
+					new TypeNameRequestor() {
+						public void acceptType(
+							int modifiers,
+							char[] packageName,
+							char[] simpleTypeName,
+							char[][] enclosingTypeNames,
+							String path) {
+							// no type to accept
+						}
+					},
+					// will not activate index query caches if indexes are not ready, since it would take to long
+					// to wait until indexes are fully rebuild
+					IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
+					monitor == null ? null : new SubProgressMonitor(monitor, 49) // 49% of the time is spent in the dummy search
+				);
+			} catch (JavaModelException e) {
+				// /search failed: ignore
+			} catch (OperationCanceledException e) {
+				if (monitor != null && monitor.isCanceled())
+					throw e;
+				// else indexes were not ready: catch the exception so that jars are still refreshed
+			}
+
+			// check if the build state version number has changed since last session
+			// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98969)
+			if (monitor != null)
+				monitor.subTask(Messages.javamodel_getting_build_state_number);
+			QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "stateVersionNumber"); //$NON-NLS-1$
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			String versionNumber = null;
+			try {
+				versionNumber = root.getPersistentProperty(qName);
+			} catch (CoreException e) {
+				// could not read version number: consider it is new
+			}
+			final JavaModel model = manager.getJavaModel();
+			String newVersionNumber = Byte.toString(State.VERSION);
+			if (!newVersionNumber.equals(versionNumber)) {
+				// build state version number has changed: touch every projects to force a rebuild
+				if (JavaBuilder.DEBUG)
+					System.out.println("Build state version number has changed"); //$NON-NLS-1$
+				IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+					public void run(IProgressMonitor progressMonitor2) throws CoreException {
+						for (int i = 0, length = projects.length; i < length; i++) {
+							IJavaProject project = projects[i];
+							try {
+								if (JavaBuilder.DEBUG)
+									System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$
+								new ClasspathValidation((JavaProject) project).validate(); // https://bugs.eclipse.org/bugs/show_bug.cgi?id=287164
+								project.getProject().touch(progressMonitor2);
+							} catch (CoreException e) {
+								// could not touch this project: ignore
+							}
+						}
+					}
+				};
+				if (monitor != null)
+					monitor.subTask(Messages.javamodel_building_after_upgrade);
+				try {
+					ResourcesPlugin.getWorkspace().run(runnable, monitor);
+				} catch (CoreException e) {
+					// could not touch all projects
+				}
+				try {
+					root.setPersistentProperty(qName, newVersionNumber);
+				} catch (CoreException e) {
+					Util.log(e, "Could not persist build state version number"); //$NON-NLS-1$
+				}
+			}
+
+			// ensure external jars are refreshed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93668)
+			try {
+				if (monitor != null)
+					monitor.subTask(Messages.javamodel_refreshing_external_jars);
+				model.refreshExternalArchives(
+					null/*refresh all projects*/,
+					monitor == null ? null : new SubProgressMonitor(monitor, 1) // 1% of the time is spent in jar refresh
+				);
+			} catch (JavaModelException e) {
+				// refreshing failed: ignore
+			}
+
+		} finally {
+			if (monitor != null) monitor.done();
+		}
+	}
+
+	/**
+	 * Returns whether a given classpath variable is read-only or not.
+	 *
+	 * @param variableName
+	 * @return <code>true</code> if the classpath variable is read-only,
+	 * 	<code>false</code> otherwise.
+	 * @since 3.3
+	 */
+	public static boolean isClasspathVariableReadOnly(String variableName) {
+	    return JavaModelManager.getJavaModelManager().readOnlyVariables.contains(variableName);
+	}
+
+	/**
+	 * Returns whether the given file name's extension is a Java-like extension.
+	 *
+	 * @return whether the given file name's extension is a Java-like extension
+	 * @see #getJavaLikeExtensions()
+	 * @since 3.2
+	 */
+	public static boolean isJavaLikeFileName(String fileName) {
+		return Util.isJavaLikeFileName(fileName);
+	}
+
+	/**
+	 * Returns whether the given marker references the given Java element.
+	 * Used for markers, which denote a Java element rather than a resource.
+	 *
+	 * @param element the element
+	 * @param marker the marker
+	 * @return <code>true</code> if the marker references the element, false otherwise
+	 * @exception CoreException if the <code>IMarker.getAttribute</code> on the marker fails
+	 */
+	public static boolean isReferencedBy(IJavaElement element, IMarker marker) throws CoreException {
+
+		// only match units or classfiles
+		if (element instanceof IMember){
+			IMember member = (IMember) element;
+			if (member.isBinary()){
+				element = member.getClassFile();
+			} else {
+				element = member.getCompilationUnit();
+			}
+		}
+		if (element == null) return false;
+		if (marker == null) return false;
+
+		String markerHandleId = (String)marker.getAttribute(ATT_HANDLE_ID);
+		if (markerHandleId == null) return false;
+
+		IJavaElement markerElement = JavaCore.create(markerHandleId);
+		while (true){
+			if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs.
+
+			// cycle through enclosing types in case marker is associated with a classfile (15568)
+			if (markerElement instanceof IClassFile){
+				IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType();
+				if (enclosingType != null){
+					markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile
+					continue;
+				}
+			}
+			break;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns whether the given marker delta references the given Java element.
+	 * Used for markers deltas, which denote a Java element rather than a resource.
+	 *
+	 * @param element the element
+	 * @param markerDelta the marker delta
+	 * @return <code>true</code> if the marker delta references the element
+	 * @exception CoreException if the  <code>IMarkerDelta.getAttribute</code> on the marker delta fails
+	 */
+	public static boolean isReferencedBy(IJavaElement element, IMarkerDelta markerDelta) throws CoreException {
+
+		// only match units or classfiles
+		if (element instanceof IMember){
+			IMember member = (IMember) element;
+			if (member.isBinary()){
+				element = member.getClassFile();
+			} else {
+				element = member.getCompilationUnit();
+			}
+		}
+		if (element == null) return false;
+		if (markerDelta == null) return false;
+
+		String markerDeltarHandleId = (String)markerDelta.getAttribute(ATT_HANDLE_ID);
+		if (markerDeltarHandleId == null) return false;
+
+		IJavaElement markerElement = JavaCore.create(markerDeltarHandleId);
+		while (true){
+			if (element.equals(markerElement)) return true; // external elements may still be equal with different handleIDs.
+
+			// cycle through enclosing types in case marker is associated with a classfile (15568)
+			if (markerElement instanceof IClassFile){
+				IType enclosingType = ((IClassFile)markerElement).getType().getDeclaringType();
+				if (enclosingType != null){
+					markerElement = enclosingType.getClassFile(); // retry with immediate enclosing classfile
+					continue;
+				}
+			}
+			break;
+		}
+		return false;
+	}
+
+	/**
+	 * Creates and returns a new access rule with the given file pattern and kind.
+	 * <p>
+	 * The rule kind is one of {@link IAccessRule#K_ACCESSIBLE}, {@link IAccessRule#K_DISCOURAGED},
+	 * or {@link IAccessRule#K_NON_ACCESSIBLE}, optionally combined with {@link IAccessRule#IGNORE_IF_BETTER},
+	 * e.g. <code>IAccessRule.K_NON_ACCESSIBLE | IAccessRule.IGNORE_IF_BETTER</code>.
+	 * </p>
+	 *
+	 * @param filePattern the file pattern this access rule should match
+	 * @param kind one of {@link IAccessRule#K_ACCESSIBLE}, {@link IAccessRule#K_DISCOURAGED},
+	 *                     or {@link IAccessRule#K_NON_ACCESSIBLE}, optionally combined with
+	 *                     {@link IAccessRule#IGNORE_IF_BETTER}
+	 * @return a new access rule
+	 * @since 3.1
+	 * 
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	public static IAccessRule newAccessRule(IPath filePattern, int kind) {
+		return new ClasspathAccessRule(filePattern, kind);
+	}
+
+	/**
+	 * Creates and returns a new classpath attribute with the given name and the given value.
+	 *
+	 * @return a new classpath attribute
+	 * @since 3.1
+	 */
+	public static IClasspathAttribute newClasspathAttribute(String name, String value) {
+		return new ClasspathAttribute(name, value);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
+	 * for the given path. This method is fully equivalent to calling
+	 * {@link #newContainerEntry(IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newContainerEntry(containerPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
+	 *
+	 * @param containerPath the path identifying the container, it must be formed of two
+	 * 	segments
+	 * @return a new container classpath entry
+	 *
+	 * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+	 * @since 2.0
+	 */
+	public static IClasspathEntry newContainerEntry(IPath containerPath) {
+		return newContainerEntry(
+		containerPath,
+		ClasspathEntry.NO_ACCESS_RULES,
+		ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+		false/*not exported*/);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
+	 * for the given path. This method is fully equivalent to calling
+	 * {@link #newContainerEntry(IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newContainerEntry(containerPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
+	 *
+	 * @param containerPath the path identifying the container, it must be formed of at least
+	 * 	one segment (ID+hints)
+	 * @param isExported a boolean indicating whether this entry is contributed to dependent
+	 *    projects in addition to the output location
+	 * @return a new container classpath entry
+	 *
+	 * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+	 * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+	 * @since 2.0
+	 */
+	public static IClasspathEntry newContainerEntry(IPath containerPath, boolean isExported) {
+		return newContainerEntry(
+			containerPath,
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			isExported);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
+	 * for the given path. The path of the container will be used during resolution so as to map this
+	 * container entry to a set of other classpath entries the container is acting for.
+	 * <p>
+	 * A container entry allows to express indirect references to a set of libraries, projects and variable entries,
+	 * which can be interpreted differently for each Java project where it is used.
+	 * A classpath container entry can be resolved using <code>JavaCore.getResolvedClasspathContainer</code>,
+	 * and updated with <code>JavaCore.classpathContainerChanged</code>
+	 * </p>
+	 * <p>
+	 * A container is exclusively resolved by a <code>ClasspathContainerInitializer</code> registered onto the
+	 * extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+	 * </p>
+	 * <p>
+	 * A container path must be formed of at least one segment, where:
+	 * </p>
+	 * <ul>
+	 * <li> the first segment is a unique ID identifying the target container, there must be a container initializer registered
+	 * 	onto this ID through the extension point  "org.eclipse.jdt.core.classpathContainerInitializer". </li>
+	 * <li> the remaining segments will be passed onto the initializer, and can be used as additional
+	 * 	hints during the initialization phase. </li>
+	 * </ul>
+	 * <p>
+	 * Example of an ClasspathContainerInitializer for a classpath container denoting a default JDK container:
+	 * </p>
+	 * <pre>
+	 * containerEntry = JavaCore.newContainerEntry(new Path("MyProvidedJDK/default"));
+	 *
+	 * &lt;extension
+	 *    point="org.eclipse.jdt.core.classpathContainerInitializer"&gt;
+	 *    &lt;containerInitializer
+	 *       id="MyProvidedJDK"
+	 *       class="com.example.MyInitializer"/&gt;
+	 * </pre>
+	 * <p>
+	 * The access rules determine the set of accessible source and class files
+	 * in the container. If the list of access rules is empty, then all files
+	 * in this container are accessible.
+	 * See {@link IAccessRule} for a detailed description of access
+	 * rules. Note that if an entry defined by the container defines access rules,
+	 * then these access rules are combined with the given access rules.
+	 * The given access rules are considered first, then the entry's access rules are
+	 * considered.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+	 * Note that this list should not contain any duplicate name.
+	 * </p>
+	 * <p>
+	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
+	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project.
+	 * </p>
+	 * <p>
+	 * Note that this operation does not attempt to validate classpath containers
+	 * or access the resources at the given paths.
+	 * </p>
+	 *
+	 * @param containerPath the path identifying the container, it must be formed of at least
+	 * 	one segment (ID+hints)
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @param isExported a boolean indicating whether this entry is contributed to dependent
+	 *    projects in addition to the output location
+	 * @return a new container classpath entry
+	 *
+	 * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
+	 * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+	 * @see JavaCore#newContainerEntry(IPath, boolean)
+	 * @see JavaCore#newAccessRule(IPath, int)
+	 * @since 3.1
+	 */
+	public static IClasspathEntry newContainerEntry(
+			IPath containerPath,
+			IAccessRule[] accessRules,
+			IClasspathAttribute[] extraAttributes,
+			boolean isExported) {
+
+		if (containerPath == null) {
+			throw new ClasspathEntry.AssertionFailedException("Container path cannot be null"); //$NON-NLS-1$
+		} else if (containerPath.segmentCount() < 1) {
+			throw new ClasspathEntry.AssertionFailedException("Illegal classpath container path: \'" + containerPath.makeRelative().toString() + "\', must have at least one segment (containerID+hints)"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		if (accessRules == null) {
+			accessRules = ClasspathEntry.NO_ACCESS_RULES;
+		}
+		if (extraAttributes == null) {
+			extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+		}
+		return new ClasspathEntry(
+			IPackageFragmentRoot.K_SOURCE,
+			IClasspathEntry.CPE_CONTAINER,
+			containerPath,
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
+			null, // source attachment
+			null, // source attachment root
+			null, // specific output folder
+			isExported,
+			accessRules,
+			true, // combine access rules
+			extraAttributes);
+	}
+
+	/**
+	 * Creates and returns a type hierarchy for all types in the given
+	 * region, considering subtypes within that region and considering types in the
+	 * working copies with the given owner.
+	 * In other words, the owner's working copies will take
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 *
+	 * @param monitor the given progress monitor
+	 * @param region the given region
+	 * @param owner the owner of working copies that take precedence over their original compilation units,
+	 *   or <code>null</code> if the primary working copy owner should be used
+	 * @exception JavaModelException if an element in the region does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @exception IllegalArgumentException if region is <code>null</code>
+	 * @return a type hierarchy for all types in the given
+	 * region, considering subtypes within that region
+	 * @since 3.1
+	 */
+	public static ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+		if (region == null) {
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
+		}
+		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+		CreateTypeHierarchyOperation op =
+			new CreateTypeHierarchyOperation(region, workingCopies, null, true/*compute subtypes*/);
+		op.runOperation(monitor);
+		return op.getResult();
+	}
+
+	/**
+	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_LIBRARY</code> for the
+	 * JAR or folder identified by the given absolute path. This specifies that all package fragments
+	 * within the root will have children of type <code>IClassFile</code>.
+	 * This method is fully equivalent to calling
+	 * {@link #newLibraryEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
+	 *
+	 * @param path the path to the library
+	 * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder,
+	 *    or <code>null</code> if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+	 *    Since 3.4, this path can also denote a path external to the workspace.
+	 *   and will be automatically converted to <code>null</code>.
+	 * @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
+	 *    or <code>null</code> if this location should be automatically detected.
+	 * @return a new library classpath entry
+	 */
+	public static IClasspathEntry newLibraryEntry(
+		IPath path,
+		IPath sourceAttachmentPath,
+		IPath sourceAttachmentRootPath) {
+
+		return newLibraryEntry(
+			path,
+			sourceAttachmentPath,
+			sourceAttachmentRootPath,
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			false/*not exported*/);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_LIBRARY</code> for the JAR or folder
+	 * identified by the given absolute path. This specifies that all package fragments within the root
+	 * will have children of type <code>IClassFile</code>.
+	 * <p>
+	 * This method is fully equivalent to calling
+	 * {@link #newLibraryEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
+	 * </p>
+	 *
+	 * @param path the path to the library
+	 * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder,
+	 *    or <code>null</code> if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+	 *   and will be automatically converted to <code>null</code>. Since 3.4, this path can also denote a path external
+	 *   to the workspace.
+	 * @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
+	 *    or <code>null</code> if this location should be automatically detected.
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new library classpath entry
+	 * @since 2.0
+	 */
+	public static IClasspathEntry newLibraryEntry(
+		IPath path,
+		IPath sourceAttachmentPath,
+		IPath sourceAttachmentRootPath,
+		boolean isExported) {
+
+		return newLibraryEntry(
+			path,
+			sourceAttachmentPath,
+			sourceAttachmentRootPath,
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			isExported);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_LIBRARY</code> for the JAR or folder
+	 * identified by the given absolute path. This specifies that all package fragments within the root
+	 * will have children of type <code>IClassFile</code>.
+	 * <p>
+	 * A library entry is used to denote a prerequisite JAR or root folder containing binaries.
+	 * The target JAR can either be defined internally to the workspace (absolute path relative
+	 * to the workspace root), or externally to the workspace (absolute path in the file system).
+	 * The target root folder can also be defined internally to the workspace (absolute path relative
+	 * to the workspace root), or - since 3.4 - externally to the workspace (absolute path in the file system).
+	 * Since 3.5, the path to the library can also be relative to the project using ".." as the first segment. 
+	 * </p>
+	 * <p>
+	 * e.g. Here are some examples of binary path usage
+	 * </p>
+	 *	<ul>
+	 *	<li><code> "c:\jdk1.2.2\jre\lib\rt.jar" </code> - reference to an external JAR on Windows</li>
+	 *	<li><code> "/Project/someLib.jar" </code> - reference to an internal JAR on Windows or Linux</li>
+	 *	<li><code> "/Project/classes/" </code> - reference to an internal binary folder on Windows or Linux</li>
+	 *	<li><code> "/home/usr/classes" </code> - reference to an external binary folder on Linux</li>
+	 *	<li><code> "../../lib/someLib.jar" </code> - reference to an external JAR that is a sibling of the workspace on either platform</li>
+	 * </ul>
+	 * Note that on non-Windows platform, a path <code>"/some/lib.jar"</code> is ambiguous.
+	 * It can be a path to an external JAR (its file system path being <code>"/some/lib.jar"</code>)
+	 * or it can be a path to an internal JAR (<code>"some"</code> being a project in the workspace).
+	 * Such an ambiguity is solved when the classpath entry is used (e.g. in {@link IJavaProject#getPackageFragmentRoots()}).
+	 * If the resource <code>"lib.jar"</code> exists in project <code>"some"</code>, then it is considered an
+	 * internal JAR. Otherwise it is an external JAR.
+	 * <p>Also note that this operation does not attempt to validate or access the
+	 * resources at the given paths.
+	 * </p><p>
+	 * The access rules determine the set of accessible class files
+	 * in the library. If the list of access rules is empty then all files
+	 * in this library are accessible.
+	 * See {@link IAccessRule} for a detailed description of access
+	 * rules.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+	 * Note that this list should not contain any duplicate name.
+	 * </p>
+	 * <p>
+	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
+	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project.
+	 * </p>
+	 * <p>
+	 * Since 3.5, if the library is a ZIP archive, the "Class-Path" clause (if any) in the "META-INF/MANIFEST.MF" is read
+	 * and referenced ZIP archives are added to the {@link IJavaProject#getResolvedClasspath(boolean) resolved classpath}.
+	 * </p>
+	 *
+	 * @param path the path to the library
+	 * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder,
+	 *    or <code>null</code> if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+	 *   and will be automatically converted to <code>null</code>. Since 3.4, this path can also denote a path external
+	 *   to the workspace.
+	 * @param sourceAttachmentRootPath the location of the root of the source files within the source archive or folder
+	 *    or <code>null</code> if this location should be automatically detected.
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new library classpath entry
+	 * @since 3.1
+	 */
+	public static IClasspathEntry newLibraryEntry(
+			IPath path,
+			IPath sourceAttachmentPath,
+			IPath sourceAttachmentRootPath,
+			IAccessRule[] accessRules,
+			IClasspathAttribute[] extraAttributes,
+			boolean isExported) {
+
+		if (path == null) throw new ClasspathEntry.AssertionFailedException("Library path cannot be null"); //$NON-NLS-1$
+		if (accessRules == null) {
+			accessRules = ClasspathEntry.NO_ACCESS_RULES;
+		}
+		if (extraAttributes == null) {
+			extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+		}
+		boolean hasDotDot = ClasspathEntry.hasDotDot(path);
+		if (!hasDotDot && !path.isAbsolute()) throw new ClasspathEntry.AssertionFailedException("Path for IClasspathEntry must be absolute: " + path); //$NON-NLS-1$
+		if (sourceAttachmentPath != null) {
+			if (sourceAttachmentPath.isEmpty()) {
+				sourceAttachmentPath = null; // treat empty path as none
+			} else if (!sourceAttachmentPath.isAbsolute()) {
+				throw new ClasspathEntry.AssertionFailedException("Source attachment path '" //$NON-NLS-1$
+						+ sourceAttachmentPath
+						+ "' for IClasspathEntry must be absolute"); //$NON-NLS-1$
+			}
+		}
+		return new ClasspathEntry(
+			IPackageFragmentRoot.K_BINARY,
+			IClasspathEntry.CPE_LIBRARY,
+			hasDotDot ? path : JavaProject.canonicalizedPath(path),
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
+			sourceAttachmentPath,
+			sourceAttachmentRootPath,
+			null, // specific output folder
+			isExported,
+			accessRules,
+			false, // no access rules to combine
+			extraAttributes);
+	}
+
+	/**
+	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_PROJECT</code>
+	 * for the project identified by the given absolute path.
+	 * <p>
+	 * This method is fully equivalent to calling
+	 * {@link #newProjectEntry(IPath, IAccessRule[], boolean, IClasspathAttribute[], boolean)
+	 * newProjectEntry(path, new IAccessRule[0], true, new IClasspathAttribute[0], false)}.
+	 * </p>
+	 *
+	 * @param path the absolute path of the binary archive
+	 * @return a new project classpath entry
+	 */
+	public static IClasspathEntry newProjectEntry(IPath path) {
+		return newProjectEntry(path, false);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_PROJECT</code>
+	 * for the project identified by the given absolute path.
+	 * <p>
+	 * This method is fully equivalent to calling
+	 * {@link #newProjectEntry(IPath, IAccessRule[], boolean, IClasspathAttribute[], boolean)
+	 * newProjectEntry(path, new IAccessRule[0], true, new IClasspathAttribute[0], isExported)}.
+	 * </p>
+	 *
+	 * @param path the absolute path of the prerequisite project
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new project classpath entry
+	 * @since 2.0
+	 */
+	public static IClasspathEntry newProjectEntry(IPath path, boolean isExported) {
+
+		if (!path.isAbsolute()) throw new ClasspathEntry.AssertionFailedException("Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+
+		return newProjectEntry(
+			path,
+			ClasspathEntry.NO_ACCESS_RULES,
+			true,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			isExported);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_PROJECT</code>
+	 * for the project identified by the given absolute path.
+	 * <p>
+	 * A project entry is used to denote a prerequisite project on a classpath.
+	 * The referenced project will be contributed as a whole, either as sources (in the Java Model, it
+	 * contributes all its package fragment roots) or as binaries (when building, it contributes its
+	 * whole output location).
+	 * </p>
+	 * <p>
+	 * A project reference allows to indirect through another project, independently from its internal layout.
+	 * </p><p>
+	 * The prerequisite project is referred to using an absolute path relative to the workspace root.
+	 * </p>
+	 * <p>
+	 * The access rules determine the set of accessible class files
+	 * in the project. If the list of access rules is empty then all files
+	 * in this project are accessible.
+	 * See {@link IAccessRule} for a detailed description of access rules.
+	 * </p>
+	 * <p>
+	 * The <code>combineAccessRules</code> flag indicates whether access rules of one (or more)
+	 * exported entry of the project should be combined with the given access rules. If they should
+	 * be combined, the given access rules are considered first, then the entry's access rules are
+	 * considered.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+	 * Note that this list should not contain any duplicate name.
+	 * </p>
+	 * <p>
+	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
+	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project.
+	 * </p>
+	 *
+	 * @param path the absolute path of the prerequisite project
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param combineAccessRules whether the access rules of the project's exported entries should be combined with the given access rules
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new project classpath entry
+	 * @since 3.1
+	 */
+	public static IClasspathEntry newProjectEntry(
+			IPath path,
+			IAccessRule[] accessRules,
+			boolean combineAccessRules,
+			IClasspathAttribute[] extraAttributes,
+			boolean isExported) {
+
+		if (!path.isAbsolute()) throw new ClasspathEntry.AssertionFailedException("Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+		if (accessRules == null) {
+			accessRules = ClasspathEntry.NO_ACCESS_RULES;
+		}
+		if (extraAttributes == null) {
+			extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+		}
+		return new ClasspathEntry(
+			IPackageFragmentRoot.K_SOURCE,
+			IClasspathEntry.CPE_PROJECT,
+			path,
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
+			null, // source attachment
+			null, // source attachment root
+			null, // specific output folder
+			isExported,
+			accessRules,
+			combineAccessRules,
+			extraAttributes);
+	}
+
+	/**
+	 * Returns a new empty region.
+	 *
+	 * @return a new empty region
+	 */
+	public static IRegion newRegion() {
+		return new Region();
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for all files in the project's source folder identified by the given
+	 * absolute workspace-relative path.
+	 * <p>
+	 * The convenience method is fully equivalent to:
+	 * </p>
+	 * <pre>
+	 * newSourceEntry(path, new IPath[] {}, new IPath[] {}, null);
+	 * </pre>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @return a new source classpath entry
+	 * @see #newSourceEntry(IPath, IPath[], IPath[], IPath)
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path) {
+
+		return newSourceEntry(path, ClasspathEntry.INCLUDE_ALL, ClasspathEntry.EXCLUDE_NONE, null /*output location*/);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for the project's source folder identified by the given absolute
+	 * workspace-relative path but excluding all source files with paths
+	 * matching any of the given patterns.
+	 * <p>
+	 * The convenience method is fully equivalent to:
+	 * </p>
+	 * <pre>
+	 * newSourceEntry(path, new IPath[] {}, exclusionPatterns, null);
+	 * </pre>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @param exclusionPatterns the possibly empty list of exclusion patterns
+	 *    represented as relative paths
+	 * @return a new source classpath entry
+	 * @see #newSourceEntry(IPath, IPath[], IPath[], IPath)
+	 * @since 2.1
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns) {
+
+		return newSourceEntry(path, ClasspathEntry.INCLUDE_ALL, exclusionPatterns, null /*output location*/);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for the project's source folder identified by the given absolute
+	 * workspace-relative path but excluding all source files with paths
+	 * matching any of the given patterns, and associated with a specific output location
+	 * (that is, ".class" files are not going to the project default output location).
+	 * <p>
+	 * The convenience method is fully equivalent to:
+	 * </p>
+	 * <pre>
+	 * newSourceEntry(path, new IPath[] {}, exclusionPatterns, specificOutputLocation);
+	 * </pre>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @param exclusionPatterns the possibly empty list of exclusion patterns
+	 *    represented as relative paths
+	 * @param specificOutputLocation the specific output location for this source entry (<code>null</code> if using project default output location)
+	 * @return a new source classpath entry
+	 * @see #newSourceEntry(IPath, IPath[], IPath[], IPath)
+	 * @since 2.1
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] exclusionPatterns, IPath specificOutputLocation) {
+
+	    return newSourceEntry(path, ClasspathEntry.INCLUDE_ALL, exclusionPatterns, specificOutputLocation);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for the project's source folder identified by the given absolute
+	 * workspace-relative path but excluding all source files with paths
+	 * matching any of the given patterns, and associated with a specific output location
+	 * (that is, ".class" files are not going to the project default output location).
+	 * <p>
+	 * The convenience method is fully equivalent to:
+	 * </p>
+	 * <pre>
+	 * newSourceEntry(path, new IPath[] {}, exclusionPatterns, specificOutputLocation, new IClasspathAttribute[] {});
+	 * </pre>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @param inclusionPatterns the possibly empty list of inclusion patterns
+	 *    represented as relative paths
+	 * @param exclusionPatterns the possibly empty list of exclusion patterns
+	 *    represented as relative paths
+	 * @param specificOutputLocation the specific output location for this source entry (<code>null</code> if using project default output location)
+	 * @return a new source classpath entry
+	 * @see #newSourceEntry(IPath, IPath[], IPath[], IPath, IClasspathAttribute[])
+	 * @since 3.0
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation) {
+		return newSourceEntry(path, inclusionPatterns, exclusionPatterns, specificOutputLocation, ClasspathEntry.NO_EXTRA_ATTRIBUTES);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for the project's source folder identified by the given absolute
+	 * workspace-relative path using the given inclusion and exclusion patterns
+	 * to determine which source files are included, and the given output path
+	 * to control the output location of generated files.
+	 * <p>
+	 * The source folder is referred to using an absolute path relative to the
+	 * workspace root, e.g. <code>/Project/src</code>. A project's source
+	 * folders are located with that project. That is, a source classpath
+	 * entry specifying the path <code>/P1/src</code> is only usable for
+	 * project <code>P1</code>.
+	 * </p>
+	 * <p>
+	 * The inclusion patterns determines the initial set of source files that
+	 * are to be included; the exclusion patterns are then used to reduce this
+	 * set. When no inclusion patterns are specified, the initial file set
+	 * includes all relevant files in the resource tree rooted at the source
+	 * entry's path. On the other hand, specifying one or more inclusion
+	 * patterns means that all <b>and only</b> files matching at least one of
+	 * the specified patterns are to be included. If exclusion patterns are
+	 * specified, the initial set of files is then reduced by eliminating files
+	 * matched by at least one of the exclusion patterns. Inclusion and
+	 * exclusion patterns look like relative file paths with wildcards and are
+	 * interpreted relative to the source entry's path. File patterns are
+	 * case-sensitive can contain '**', '*' or '?' wildcards (see
+	 * {@link IClasspathEntry#getExclusionPatterns()} for the full description
+	 * of their syntax and semantics). The resulting set of files are included
+	 * in the corresponding package fragment root; all package fragments within
+	 * the root will have children of type <code>ICompilationUnit</code>.
+	 * </p>
+	 * <p>
+	 * For example, if the source folder path is
+	 * <code>/Project/src</code>, there are no inclusion filters, and the
+	 * exclusion pattern is
+	 * <code>com/xyz/tests/&#42;&#42;</code>, then source files
+	 * like <code>/Project/src/com/xyz/Foo.java</code>
+	 * and <code>/Project/src/com/xyz/utils/Bar.java</code> would be included,
+	 * whereas <code>/Project/src/com/xyz/tests/T1.java</code>
+	 * and <code>/Project/src/com/xyz/tests/quick/T2.java</code> would be
+	 * excluded.
+	 * </p>
+	 * <p>
+	 * Additionally, a source entry can be associated with a specific output location.
+	 * By doing so, the Java builder will ensure that the generated ".class" files will
+	 * be issued inside this output location, as opposed to be generated into the
+	 * project default output location (when output location is <code>null</code>).
+	 * Note that multiple source entries may target the same output location.
+	 * The output location is referred to using an absolute path relative to the
+	 * workspace root, e.g. <code>"/Project/bin"</code>, it must be located inside
+	 * the same project as the source folder.
+	 * </p>
+	 * <p>
+	 * Also note that all sources/binaries inside a project are contributed as
+	 * a whole through a project entry
+	 * (see <code>JavaCore.newProjectEntry</code>). Particular source entries
+	 * cannot be selectively exported.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+	 * Note that this list should not contain any duplicate name.
+	 * </p>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @param inclusionPatterns the possibly empty list of inclusion patterns
+	 *    represented as relative paths
+	 * @param exclusionPatterns the possibly empty list of exclusion patterns
+	 *    represented as relative paths
+	 * @param specificOutputLocation the specific output location for this source entry (<code>null</code> if using project default ouput location)
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @return a new source classpath entry with the given exclusion patterns
+	 * @see IClasspathEntry#getInclusionPatterns()
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 * @see IClasspathEntry#getOutputLocation()
+	 * @since 3.1
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation, IClasspathAttribute[] extraAttributes) {
+
+		if (path == null) throw new ClasspathEntry.AssertionFailedException("Source path cannot be null"); //$NON-NLS-1$
+		if (!path.isAbsolute()) throw new ClasspathEntry.AssertionFailedException("Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
+		if (exclusionPatterns == null) {
+			exclusionPatterns = ClasspathEntry.EXCLUDE_NONE;
+		}
+		if (inclusionPatterns == null) {
+			inclusionPatterns = ClasspathEntry.INCLUDE_ALL;
+		}
+		if (extraAttributes == null) {
+			extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+		}
+		return new ClasspathEntry(
+			IPackageFragmentRoot.K_SOURCE,
+			IClasspathEntry.CPE_SOURCE,
+			path,
+			inclusionPatterns,
+			exclusionPatterns,
+			null, // source attachment
+			null, // source attachment root
+			specificOutputLocation, // custom output location
+			false,
+			null,
+			false, // no access rules to combine
+			extraAttributes);
+	}
+
+	/**
+	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_VARIABLE</code>
+	 * for the given path. This method is fully equivalent to calling
+	 * {@link #newVariableEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
+	 *
+	 * @param variablePath the path of the binary archive; first segment is the
+	 *   name of a classpath variable
+	 * @param variableSourceAttachmentPath the path of the corresponding source archive,
+	 *    or <code>null</code> if none; if present, the first segment is the
+	 *    name of a classpath variable (not necessarily the same variable
+	 *    as the one that begins <code>variablePath</code>)
+	 * @param sourceAttachmentRootPath the location of the root of the source files within the source archive
+	 *    or <code>null</code> if <code>variableSourceAttachmentPath</code> is also <code>null</code>
+	 * @return a new library classpath entry
+	 */
+	public static IClasspathEntry newVariableEntry(
+		IPath variablePath,
+		IPath variableSourceAttachmentPath,
+		IPath sourceAttachmentRootPath) {
+
+		return newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, false);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_VARIABLE</code>
+	 * for the given path. This method is fully equivalent to calling
+	 * {@link #newVariableEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
+	 *
+	 * @param variablePath the path of the binary archive; first segment is the
+	 *   name of a classpath variable
+	 * @param variableSourceAttachmentPath the path of the corresponding source archive,
+	 *    or <code>null</code> if none; if present, the first segment is the
+	 *    name of a classpath variable (not necessarily the same variable
+	 *    as the one that begins <code>variablePath</code>)
+	 * @param variableSourceAttachmentRootPath the location of the root of the source files within the source archive
+	 *    or <code>null</code> if <code>variableSourceAttachmentPath</code> is also <code>null</code>
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new variable classpath entry
+	 * @since 2.0
+	 */
+	public static IClasspathEntry newVariableEntry(
+			IPath variablePath,
+			IPath variableSourceAttachmentPath,
+			IPath variableSourceAttachmentRootPath,
+			boolean isExported) {
+
+		return newVariableEntry(
+			variablePath,
+			variableSourceAttachmentPath,
+			variableSourceAttachmentRootPath,
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			isExported);
+	}
+
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_VARIABLE</code>
+	 * for the given path. The first segment of the path is the name of a classpath variable.
+	 * The trailing segments of the path will be appended to resolved variable path.
+	 * <p>
+	 * A variable entry allows to express indirect references on a classpath to other projects or libraries,
+	 * depending on what the classpath variable is referring.
+	 * </p>
+	 * <p>
+	 * It is possible to register an automatic initializer (<code>ClasspathVariableInitializer</code>),
+	 * which will be invoked through the extension point "org.eclipse.jdt.core.classpathVariableInitializer".
+	 * After resolution, a classpath variable entry may either correspond to a project or a library entry.
+	 * </p>
+	 * <p>
+	 * e.g. Here are some examples of variable path usage
+	 * </p>
+	 * <ul>
+	 * <li> "JDTCORE" where variable <code>JDTCORE</code> is
+	 *		bound to "c:/jars/jdtcore.jar". The resolved classpath entry is denoting the library "c:\jars\jdtcore.jar"</li>
+	 * <li> "JDTCORE" where variable <code>JDTCORE</code> is
+	 *		bound to "/Project_JDTCORE". The resolved classpath entry is denoting the project "/Project_JDTCORE"</li>
+	 * <li> "PLUGINS/com.example/example.jar" where variable <code>PLUGINS</code>
+	 *      is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:\eclipse\plugins\com.example\example.jar"</li>
+	 * </ul>
+	 * <p>
+	 * The access rules determine the set of accessible class files
+	 * in the project or library. If the list of access rules is empty then all files
+	 * in this project or library are accessible.
+	 * See {@link IAccessRule} for a detailed description of access rules.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+	 * Note that this list should not contain any duplicate name.
+	 * </p>
+	 * <p>
+	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
+	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project.
+	 * </p>
+	 * <p>
+	 * Note that this operation does not attempt to validate classpath variables
+	 * or access the resources at the given paths.
+	 * </p>
+	 *
+	 * @param variablePath the path of the binary archive; first segment is the
+	 *   name of a classpath variable
+	 * @param variableSourceAttachmentPath the path of the corresponding source archive,
+	 *    or <code>null</code> if none; if present, the first segment is the
+	 *    name of a classpath variable (not necessarily the same variable
+	 *    as the one that begins <code>variablePath</code>)
+	 * @param variableSourceAttachmentRootPath the location of the root of the source files within the source archive
+	 *    or <code>null</code> if <code>variableSourceAttachmentPath</code> is also <code>null</code>
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
+	 * @return a new variable classpath entry
+	 * @since 3.1
+	 */
+	public static IClasspathEntry newVariableEntry(
+			IPath variablePath,
+			IPath variableSourceAttachmentPath,
+			IPath variableSourceAttachmentRootPath,
+			IAccessRule[] accessRules,
+			IClasspathAttribute[] extraAttributes,
+			boolean isExported) {
+
+		if (variablePath == null) throw new ClasspathEntry.AssertionFailedException("Variable path cannot be null"); //$NON-NLS-1$
+		if (variablePath.segmentCount() < 1) {
+			throw new ClasspathEntry.AssertionFailedException("Illegal classpath variable path: \'" + variablePath.makeRelative().toString() + "\', must have at least one segment"); //$NON-NLS-1$//$NON-NLS-2$
+		}
+		if (accessRules == null) {
+			accessRules = ClasspathEntry.NO_ACCESS_RULES;
+		}
+		if (extraAttributes == null) {
+			extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+		}
+
+		return new ClasspathEntry(
+			IPackageFragmentRoot.K_SOURCE,
+			IClasspathEntry.CPE_VARIABLE,
+			variablePath,
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
+			variableSourceAttachmentPath, // source attachment
+			variableSourceAttachmentRootPath, // source attachment root
+			null, // specific output folder
+			isExported,
+			accessRules,
+			false, // no access rules to combine
+			extraAttributes);
+	}
+	
+	/**
+	 * 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.
+	 * <p> 
+	 * When a non-null project is passed, any additional attributes that may have been stored 
+	 * previously in the project's .classpath file are retrieved and populated in the 
+	 * corresponding referenced entry. If the project is <code>null</code>, the raw referenced
+	 * entries are returned without any persisted attributes. 
+	 * For more details on storing referenced entries, see 
+	 * {@link IJavaProject#setRawClasspath(IClasspathEntry[], IClasspathEntry[], IPath, 
+	 * IProgressMonitor)}. 
+	 * </p>
+	 * 
+	 * @param libraryEntry the library entry whose referenced entries are sought 
+	 * @param project project where the persisted referenced entries to be retrieved from. If <code>null</code>
+	 * 			persisted attributes are not attempted to be retrieved.
+	 * @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) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		return manager.getReferencedClasspathEntries(libraryEntry, project);
+	}
+
+	/**
+	 * Removed the given classpath variable. Does nothing if no value was
+	 * set for this classpath variable.
+	 * <p>
+	 * This functionality cannot be used while the resource tree is locked.
+	 * </p>
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 *
+	 * @param variableName the name of the classpath variable
+	 * @see #setClasspathVariable(String, IPath)
+	 *
+	 * @deprecated Use {@link #removeClasspathVariable(String, IProgressMonitor)} instead
+	 */
+	public static void removeClasspathVariable(String variableName) {
+		removeClasspathVariable(variableName, null);
+	}
+
+	/**
+	 * Removed the given classpath variable. Does nothing if no value was
+	 * set for this classpath variable.
+	 * <p>
+	 * This functionality cannot be used while the resource tree is locked.
+	 * </p>
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 *
+	 * @param variableName the name of the classpath variable
+	 * @param monitor the progress monitor to report progress
+	 * @see #setClasspathVariable(String, IPath)
+	 */
+	public static void removeClasspathVariable(String variableName, IProgressMonitor monitor) {
+		try {
+			SetVariablesOperation operation = new SetVariablesOperation(new String[]{ variableName}, new IPath[]{ null }, true/*update preferences*/);
+			operation.runOperation(monitor);
+		} catch (JavaModelException e) {
+			Util.log(e, "Exception while removing variable " + variableName); //$NON-NLS-1$
+		}
+	}
+
+	/**
+	 * Removes the given element changed listener.
+	 * Has no effect if an identical listener is not registered.
+	 *
+	 * @param listener the listener
+	 */
+	public static void removeElementChangedListener(IElementChangedListener listener) {
+		JavaModelManager.getDeltaState().removeElementChangedListener(listener);
+	}
+
+	/**
+	 * Removes the file extension from the given file name, if it has a Java-like file
+	 * extension. Otherwise the file name itself is returned.
+	 * Note this removes the dot ('.') before the extension as well.
+	 *
+	 * @param fileName the name of a file
+	 * @return the fileName without the Java-like extension
+	 * @since 3.2
+	 */
+	public static String removeJavaLikeExtension(String fileName) {
+		return Util.getNameWithoutJavaLikeExtension(fileName);
+	}
+
+	/**
+	 * Removes the given pre-processing resource changed listener.
+	 * <p>
+	 * Has no effect if an identical listener is not registered.
+	 * </p>
+	 *
+	 * @param listener the listener
+	 * @since 3.0
+	 */
+	public static void removePreProcessingResourceChangedListener(IResourceChangeListener listener) {
+		JavaModelManager.getDeltaState().removePreResourceChangedListener(listener);
+	}
+
+
+
+	/**
+	 * Runs the given action as an atomic Java model operation.
+	 * <p>
+	 * After running a method that modifies java elements,
+	 * registered listeners receive after-the-fact notification of
+	 * what just transpired, in the form of a element changed event.
+	 * This method allows clients to call a number of
+	 * methods that modify java elements and only have element
+	 * changed event notifications reported at the end of the entire
+	 * batch.
+	 * </p>
+	 * <p>
+	 * If this method is called outside the dynamic scope of another such
+	 * call, this method runs the action and then reports a single
+	 * element changed event describing the net effect of all changes
+	 * done to java elements by the action.
+	 * </p>
+	 * <p>
+	 * If this method is called in the dynamic scope of another such
+	 * call, this method simply runs the action.
+	 * </p>
+	 *
+	 * @param action the action to perform
+	 * @param monitor a progress monitor, or <code>null</code> if progress
+	 *    reporting and cancellation are not desired
+	 * @exception CoreException if the operation failed.
+	 * @since 2.1
+	 */
+	public static void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException {
+		run(action, ResourcesPlugin.getWorkspace().getRoot(), monitor);
+	}
+	/**
+	 * Runs the given action as an atomic Java model operation.
+	 * <p>
+	 * After running a method that modifies java elements,
+	 * registered listeners receive after-the-fact notification of
+	 * what just transpired, in the form of a element changed event.
+	 * This method allows clients to call a number of
+	 * methods that modify java elements and only have element
+	 * changed event notifications reported at the end of the entire
+	 * batch.
+	 * </p>
+	 * <p>
+	 * If this method is called outside the dynamic scope of another such
+	 * call, this method runs the action and then reports a single
+	 * element changed event describing the net effect of all changes
+	 * done to java elements by the action.
+	 * </p>
+	 * <p>
+	 * If this method is called in the dynamic scope of another such
+	 * call, this method simply runs the action.
+	 * </p>
+	 * <p>
+ 	 * The supplied scheduling rule is used to determine whether this operation can be
+	 * run simultaneously with workspace changes in other threads. See
+	 * <code>IWorkspace.run(...)</code> for more details.
+ 	 * </p>
+	 *
+	 * @param action the action to perform
+	 * @param rule the scheduling rule to use when running this operation, or
+	 * <code>null</code> if there are no scheduling restrictions for this operation.
+	 * @param monitor a progress monitor, or <code>null</code> if progress
+	 *    reporting and cancellation are not desired
+	 * @exception CoreException if the operation failed.
+	 * @since 3.0
+	 */
+	public static void run(IWorkspaceRunnable action, ISchedulingRule rule, IProgressMonitor monitor) throws CoreException {
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		if (workspace.isTreeLocked()) {
+			new BatchOperation(action).run(monitor);
+		} else {
+			// use IWorkspace.run(...) to ensure that a build will be done in autobuild mode
+			workspace.run(new BatchOperation(action), rule, IWorkspace.AVOID_UPDATE, monitor);
+		}
+	}
+	/**
+	 * Bind a container reference path to some actual containers (<code>IClasspathContainer</code>).
+	 * This API must be invoked whenever changes in container need to be reflected onto the JavaModel.
+	 * Containers can have distinct values in different projects, therefore this API considers a
+	 * set of projects with their respective containers.
+	 * <p>
+	 * <code>containerPath</code> is the path under which these values can be referenced through
+	 * container classpath entries (<code>IClasspathEntry#CPE_CONTAINER</code>). A container path
+	 * is formed by a first ID segment followed with extra segments, which can be used as additional hints
+	 * for the resolution. The container ID is used to identify a <code>ClasspathContainerInitializer</code>
+	 * registered on the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+	 * </p>
+	 * <p>
+	 * There is no assumption that each individual container value passed in argument
+	 * (<code>respectiveContainers</code>) must answer the exact same path when requested
+	 * <code>IClasspathContainer#getPath</code>.
+	 * Indeed, the containerPath is just an indication for resolving it to an actual container object. It can be
+	 * delegated to a <code>ClasspathContainerInitializer</code>, which can be activated through the extension
+	 * point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+	 * </p>
+	 * <p>
+	 * In reaction to changing container values, the JavaModel will be updated to reflect the new
+	 * state of the updated container. A combined Java element delta will be notified to describe the corresponding
+	 * classpath changes resulting from the container update. This operation is batched, and automatically eliminates
+	 * unnecessary updates (new container is same as old one). This operation acquires a lock on the workspace's root.
+	 * </p>
+	 * <p>
+	 * This functionality cannot be used while the workspace is locked, since
+	 * it may create/remove some resource markers.
+	 * </p>
+	 * <p>
+	 * Classpath container values are persisted locally to the workspace, but
+	 * are not preserved from a session to another. It is thus highly recommended to register a
+	 * <code>ClasspathContainerInitializer</code> for each referenced container
+	 * (through the extension point "org.eclipse.jdt.core.ClasspathContainerInitializer").
+	 * </p>
+	 * <p>
+	 * Note: setting a container to <code>null</code> will cause it to be lazily resolved again whenever
+	 * its value is required. In particular, this will cause a registered initializer to be invoked
+	 * again.
+	 * </p>
+	 * @param containerPath - the name of the container reference, which is being updated
+	 * @param affectedProjects - the set of projects for which this container is being bound
+	 * @param respectiveContainers - the set of respective containers for the affected projects
+	 * @param monitor a monitor to report progress
+	 * @throws JavaModelException
+	 * @see ClasspathContainerInitializer
+	 * @see #getClasspathContainer(IPath, IJavaProject)
+	 * @see IClasspathContainer
+	 * @since 2.0
+	 */
+	public static void setClasspathContainer(IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers, IProgressMonitor monitor) throws JavaModelException {
+		if (affectedProjects.length != respectiveContainers.length)
+			throw new ClasspathEntry.AssertionFailedException("Projects and containers collections should have the same size"); //$NON-NLS-1$
+		if (affectedProjects.length == 1) {
+			IClasspathContainer container = respectiveContainers[0];
+			if (container != null) {
+				JavaModelManager manager = JavaModelManager.getJavaModelManager();
+				IJavaProject project = affectedProjects[0];
+				IClasspathContainer existingCointainer = manager.containerGet(project, containerPath);
+				if (existingCointainer == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
+					manager.containerBeingInitializedPut(project, containerPath, container);
+					return;
+				}
+			}
+		}
+		SetContainerOperation operation = new SetContainerOperation(containerPath, affectedProjects, respectiveContainers);
+		operation.runOperation(monitor);
+	}
+
+	/**
+	 * Sets the value of the given classpath variable.
+	 * The path must have at least one segment.
+	 * <p>
+	 * This functionality cannot be used while the resource tree is locked.
+	 * </p>
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 *
+	 * @param variableName the name of the classpath variable
+	 * @param path the path
+	 * @throws JavaModelException
+	 * @see #getClasspathVariable(String)
+	 *
+	 * @deprecated Use {@link #setClasspathVariable(String, IPath, IProgressMonitor)} instead
+	 */
+	public static void setClasspathVariable(String variableName, IPath path)
+		throws JavaModelException {
+
+		setClasspathVariable(variableName, path, null);
+	}
+
+	/**
+	 * Sets the value of the given classpath variable.
+	 * The path must not be null.
+	 * Since 3.5, the path to a library can also be relative to the project using ".." as the first segment. 
+	 * <p>
+	 * This functionality cannot be used while the resource tree is locked.
+	 * </p>
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 * <p>
+	 * Updating a variable with the same value has no effect.
+	 * </p>
+	 *
+	 * @param variableName the name of the classpath variable
+	 * @param path the path
+	 * @param monitor a monitor to report progress
+	 * @throws JavaModelException
+	 * @see #getClasspathVariable(String)
+	 */
+	public static void setClasspathVariable(
+		String variableName,
+		IPath path,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		if (path == null) throw new ClasspathEntry.AssertionFailedException("Variable path cannot be null"); //$NON-NLS-1$
+		setClasspathVariables(new String[]{variableName}, new IPath[]{ path }, monitor);
+	}
+
+	/**
+	 * Sets the values of all the given classpath variables at once.
+	 * Null paths can be used to request corresponding variable removal.
+	 * Since 3.5, the path to a library can also be relative to the project using ".." as the first segment.
+	 * <p>
+	 * A combined Java element delta will be notified to describe the corresponding
+	 * classpath changes resulting from the variables update. This operation is batched,
+	 * and automatically eliminates unnecessary updates (new variable is same as old one).
+	 * This operation acquires a lock on the workspace's root.
+	 * </p>
+	 * <p>
+	 * This functionality cannot be used while the workspace is locked, since
+	 * it may create/remove some resource markers.
+	 * </p>
+	 * <p>
+	 * Classpath variable values are persisted locally to the workspace, and
+	 * are preserved from session to session.
+	 * </p>
+	 * <p>
+	 * Updating a variable with the same value has no effect.
+	 * </p>
+	 *
+	 * @param variableNames an array of names for the updated classpath variables
+	 * @param paths an array of path updates for the modified classpath variables (null
+	 *       meaning that the corresponding value will be removed
+	 * @param monitor a monitor to report progress
+	 * @throws JavaModelException
+	 * @see #getClasspathVariable(String)
+	 * @since 2.0
+	 */
+	public static void setClasspathVariables(
+		String[] variableNames,
+		IPath[] paths,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		if (variableNames.length != paths.length)	throw new ClasspathEntry.AssertionFailedException("Variable names and paths collections should have the same size"); //$NON-NLS-1$
+		SetVariablesOperation operation = new SetVariablesOperation(variableNames, paths, true/*update preferences*/);
+		operation.runOperation(monitor);
+	}
+
+	/**
+	 * Sets the default compiler options inside the given options map according
+	 * to the given compliance.
+	 *
+	 * <p>The given compliance must be one of those supported by the compiler,
+	 * that is one of the acceptable values for option {@link #COMPILER_COMPLIANCE}.</p>
+	 *
+	 * <p>The list of modified options is currently:</p>
+	 * <ul>
+	 * <li>{@link #COMPILER_COMPLIANCE}</li>
+	 * <li>{@link #COMPILER_SOURCE}</li>
+	 * <li>{@link #COMPILER_CODEGEN_TARGET_PLATFORM}</li>
+	 * <li>{@link #COMPILER_PB_ASSERT_IDENTIFIER}</li>
+	 * <li>{@link #COMPILER_PB_ENUM_IDENTIFIER}</li>
+	 * <li>{@link #COMPILER_CODEGEN_INLINE_JSR_BYTECODE} for compliance levels 1.5 and greater</li>
+	 * </ul>
+	 *
+	 * <p>If the given compliance is unknown, the given map is unmodified.</p>
+	 *
+	 * @param compliance the given compliance
+	 * @param options the given options map
+	 * @since 3.3
+	 */
+	public static void setComplianceOptions(String compliance, Map options) {
+		switch((int) (CompilerOptions.versionToJdkLevel(compliance) >>> 16)) {
+			case ClassFileConstants.MAJOR_VERSION_1_3:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_3);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.IGNORE);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.IGNORE);
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_4:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.WARNING);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.WARNING);
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_5:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_6:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_7:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
+				break;
+			case ClassFileConstants.MAJOR_VERSION_1_8:
+				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
+				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
+				options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
+				break;
+		}
+	}
+
+	/**
+	 * Sets the current table of options. All and only the options explicitly
+	 * included in the given table are remembered; all previous option settings
+	 * are forgotten, including ones not explicitly mentioned.
+	 * <p>
+	 * Helper constants have been defined on JavaCore for each of the option IDs
+	 * (categorized in Code assist option ID, Compiler option ID and Core option ID)
+	 * and some of their acceptable values (categorized in Option value). Some
+	 * options accept open value sets beyond the documented constant values.
+	 * </p>
+	 * Note: each release may add new options.
+	 *
+	 * @param newOptions
+	 *            the new options (key type: <code>String</code>; value type:
+	 *            <code>String</code>), or <code>null</code> to reset all
+	 *            options to their default values
+	 * @see JavaCore#getDefaultOptions()
+	 * @see JavaCorePreferenceInitializer for changing default settings
+	 */
+	public static void setOptions(Hashtable newOptions) {
+		JavaModelManager.getJavaModelManager().setOptions(newOptions);
+	}
+
+	/* (non-Javadoc)
+	 * Shutdown the JavaCore plug-in.
+	 * <p>
+	 * De-registers the JavaModelManager as a resource changed listener and save participant.
+	 * </p>
+	 * @see org.eclipse.core.runtime.Plugin#stop(BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		try {
+			JavaModelManager.getJavaModelManager().shutdown();
+		} finally {
+			// ensure we call super.stop as the last thing
+			super.stop(context);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * Startup the JavaCore plug-in.
+	 * <p>
+	 * Registers the JavaModelManager as a resource changed listener and save participant.
+	 * Starts the background indexing, and restore saved classpath variable values.
+	 * </p>
+	 * @throws Exception
+	 * @see org.eclipse.core.runtime.Plugin#start(BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		JavaModelManager.getJavaModelManager().startup();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java
new file mode 100644
index 0000000..bb6d6c4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+import org.eclipse.jdt.internal.core.JavaModelStatus;
+
+/**
+ * A checked exception representing a failure in the Java model.
+ * Java model exceptions contain a Java-specific status object describing the
+ * cause of the exception.
+ * <p>
+ * Instances of this class are automatically created by the Java model
+ * when problems arise, so there is generally no need for clients to create
+ * instances.
+ * </p>
+ *
+ * @see IJavaModelStatus
+ * @see IJavaModelStatusConstants
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class JavaModelException extends CoreException {
+
+	private static final long serialVersionUID = -760398656505871287L; // backward compatible
+
+	CoreException nestedCoreException;
+/**
+ * Creates a Java model exception that wrappers the given <code>Throwable</code>.
+ * The exception contains a Java-specific status object with severity
+ * <code>IStatus.ERROR</code> and the given status code.
+ *
+ * @param e the <code>Throwable</code>
+ * @param code one of the Java-specific status codes declared in
+ *   <code>IJavaModelStatusConstants</code>
+ * @see IJavaModelStatusConstants
+ * @see org.eclipse.core.runtime.IStatus#ERROR
+ */
+public JavaModelException(Throwable e, int code) {
+	this(new JavaModelStatus(code, e));
+}
+/**
+ * Creates a Java model exception for the given <code>CoreException</code>.
+ * Equivalent to
+ * <code>JavaModelException(exception,IJavaModelStatusConstants.CORE_EXCEPTION</code>.
+ *
+ * @param exception the <code>CoreException</code>
+ */
+public JavaModelException(CoreException exception) {
+	super(exception.getStatus());
+	this.nestedCoreException = exception;
+}
+/**
+ * Creates a Java model exception for the given Java-specific status object.
+ *
+ * @param status the Java-specific status object
+ */
+public JavaModelException(IJavaModelStatus status) {
+	super(status);
+}
+/**
+ * Returns the underlying <code>Throwable</code> that caused the failure.
+ *
+ * @return the wrapped <code>Throwable</code>, or <code>null</code> if the
+ *   direct case of the failure was at the Java model layer
+ */
+public Throwable getException() {
+	if (this.nestedCoreException == null) {
+		return getStatus().getException();
+	} else {
+		return this.nestedCoreException;
+	}
+}
+/**
+ * Returns the Java model status object for this exception.
+ * Equivalent to <code>(IJavaModelStatus) getStatus()</code>.
+ *
+ * @return a status object
+ */
+public IJavaModelStatus getJavaModelStatus() {
+	IStatus status = getStatus();
+	if (status instanceof IJavaModelStatus) {
+		return (IJavaModelStatus)status;
+	} else {
+		// A regular IStatus is created only in the case of a CoreException.
+		// See bug 13492 Should handle JavaModelExceptions that contains CoreException more gracefully
+		return new JavaModelStatus(this.nestedCoreException);
+	}
+}
+/**
+ * Returns whether this exception indicates that a Java model element does not
+ * exist. Such exceptions have a status with a code of
+ * <code>IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST</code> or
+ * <code>IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH</code>.
+ * This is a convenience method.
+ *
+ * @return <code>true</code> if this exception indicates that a Java model
+ *   element does not exist
+ * @see IJavaModelStatus#isDoesNotExist()
+ * @see IJavaModelStatusConstants#ELEMENT_DOES_NOT_EXIST
+ * @see IJavaModelStatusConstants#ELEMENT_NOT_ON_CLASSPATH
+ */
+public boolean isDoesNotExist() {
+	IJavaModelStatus javaModelStatus = getJavaModelStatus();
+	return javaModelStatus != null && javaModelStatus.isDoesNotExist();
+}
+
+/**
+ * Prints this exception's stack trace to the given print stream.
+ *
+ * @param output the print stream
+ * @since 3.0
+ */
+public void printStackTrace(PrintStream output) {
+	synchronized(output) {
+		super.printStackTrace(output);
+		Throwable throwable = getException();
+		if (throwable != null) {
+			output.print("Caused by: "); //$NON-NLS-1$
+			throwable.printStackTrace(output);
+		}
+	}
+}
+
+/**
+ * Prints this exception's stack trace to the given print writer.
+ *
+ * @param output the print writer
+ * @since 3.0
+ */
+public void printStackTrace(PrintWriter output) {
+	synchronized(output) {
+		super.printStackTrace(output);
+		Throwable throwable = getException();
+		if (throwable != null) {
+			output.print("Caused by: "); //$NON-NLS-1$
+			throwable.printStackTrace(output);
+		}
+	}
+}
+/*
+ * Returns a printable representation of this exception suitable for debugging
+ * purposes only.
+ */
+public String toString() {
+	StringBuffer buffer= new StringBuffer();
+	buffer.append("Java Model Exception: "); //$NON-NLS-1$
+	if (getException() != null) {
+		if (getException() instanceof CoreException) {
+			CoreException c= (CoreException)getException();
+			buffer.append("Core Exception [code "); //$NON-NLS-1$
+			buffer.append(c.getStatus().getCode());
+			buffer.append("] "); //$NON-NLS-1$
+			buffer.append(c.getStatus().getMessage());
+		} else {
+			buffer.append(getException().toString());
+		}
+	} else {
+		buffer.append(getStatus().toString());
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java
new file mode 100644
index 0000000..f2be23e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java
@@ -0,0 +1,1147 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.core.INamingRequestor;
+import org.eclipse.jdt.internal.core.InternalNamingConventions;
+
+
+/**
+ * Provides methods for computing Java-specific names.
+ * <p>
+ * The behavior of the methods is dependent of several JavaCore options.
+ * <p>
+ * The possible options are :
+ * <ul>
+ * <li> {@link JavaCore#CODEASSIST_FIELD_PREFIXES} : Define the Prefixes for Field Name.</li>
+ * <li> {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} : Define the Suffixes for Field Name.</li>
+ * 
+ * <li> {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES} : Define the Prefixes for Static Field Name.</li>
+ * <li> {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} : Define the Suffixes for Static Field Name.</li>
+ * 
+ * <li> {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_PREFIXES} : Define the Prefixes for Static Final Field Name.</li>
+ * <li> {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES} : Define the Suffixes for Static Final Field Name.</li>
+ * 
+ * <li> {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} : Define the Prefixes for Local Variable Name.</li>
+ * <li> {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES} : Define the Suffixes for Local Variable Name.</li>
+ * 
+ * <li> {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} : Define the Prefixes for Argument Name.</li>
+ * <li> {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES} : Define the Suffixes for Argument Name.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * For a complete description of the configurable options, see {@link JavaCore#getDefaultOptions()}.
+ * To programmatically change these options, see {@link JavaCore#setOptions(java.util.Hashtable)}.
+ * </p>
+ * <p>
+ * This class provides static methods and constants only.
+ * </p>
+ *
+ * @see JavaCore#setOptions(java.util.Hashtable)
+ * @see JavaCore#getDefaultOptions()
+ * @since 2.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class NamingConventions {
+	static class NamingRequestor implements INamingRequestor {
+		private final static int SIZE = 10;
+
+		// for acceptNameWithPrefixAndSuffix
+		private char[][] firstPrefixAndFirstSuffixResults = new char[SIZE][];
+		private int firstPrefixAndFirstSuffixResultsCount = 0;
+		private char[][] firstPrefixAndSuffixResults = new char[SIZE][];
+		private int firstPrefixAndSuffixResultsCount = 0;
+		private char[][] prefixAndFirstSuffixResults = new char[SIZE][];
+		private int prefixAndFirstSuffixResultsCount = 0;
+		private char[][] prefixAndSuffixResults = new char[SIZE][];
+		private int prefixAndSuffixResultsCount = 0;
+
+		// for acceptNameWithPrefix
+		private char[][] firstPrefixResults = new char[SIZE][];
+		private int firstPrefixResultsCount = 0;
+		private char[][] prefixResults = new char[SIZE][];
+		private int prefixResultsCount = 0;
+
+		// for acceptNameWithSuffix
+		private char[][] firstSuffixResults = new char[SIZE][];
+		private int firstSuffixResultsCount = 0;
+		private char[][] suffixResults = new char[SIZE][];
+		private int suffixResultsCount = 0;
+
+		// for acceptNameWithoutPrefixAndSuffix
+		private char[][] otherResults = new char[SIZE][];
+		private int otherResultsCount = 0;
+		public void acceptNameWithoutPrefixAndSuffix(char[] name, int reusedCharacters) {
+			int length = this.otherResults.length;
+			if(length == this.otherResultsCount) {
+				System.arraycopy(
+					this.otherResults,
+					0,
+					this.otherResults = new char[length * 2][],
+					0,
+					length);
+			}
+			this.otherResults[this.otherResultsCount++] = name;
+		}
+
+		public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
+			if(isFirstPrefix) {
+				int length = this.firstPrefixResults.length;
+				if(length == this.firstPrefixResultsCount) {
+					System.arraycopy(
+						this.firstPrefixResults,
+						0,
+						this.firstPrefixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.firstPrefixResults[this.firstPrefixResultsCount++] = name;
+			} else{
+				int length = this.prefixResults.length;
+				if(length == this.prefixResultsCount) {
+					System.arraycopy(
+						this.prefixResults,
+						0,
+						this.prefixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.prefixResults[this.prefixResultsCount++] = name;
+			}
+		}
+
+		public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
+			if(isFirstPrefix && isFirstSuffix) {
+				int length = this.firstPrefixAndFirstSuffixResults.length;
+				if(length == this.firstPrefixAndFirstSuffixResultsCount) {
+					System.arraycopy(
+						this.firstPrefixAndFirstSuffixResults,
+						0,
+						this.firstPrefixAndFirstSuffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.firstPrefixAndFirstSuffixResults[this.firstPrefixAndFirstSuffixResultsCount++] = name;
+			} else if (isFirstPrefix) {
+				int length = this.firstPrefixAndSuffixResults.length;
+				if(length == this.firstPrefixAndSuffixResultsCount) {
+					System.arraycopy(
+						this.firstPrefixAndSuffixResults,
+						0,
+						this.firstPrefixAndSuffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.firstPrefixAndSuffixResults[this.firstPrefixAndSuffixResultsCount++] = name;
+			} else if(isFirstSuffix) {
+				int length = this.prefixAndFirstSuffixResults.length;
+				if(length == this.prefixAndFirstSuffixResultsCount) {
+					System.arraycopy(
+						this.prefixAndFirstSuffixResults,
+						0,
+						this.prefixAndFirstSuffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.prefixAndFirstSuffixResults[this.prefixAndFirstSuffixResultsCount++] = name;
+			} else {
+				int length = this.prefixAndSuffixResults.length;
+				if(length == this.prefixAndSuffixResultsCount) {
+					System.arraycopy(
+						this.prefixAndSuffixResults,
+						0,
+						this.prefixAndSuffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.prefixAndSuffixResults[this.prefixAndSuffixResultsCount++] = name;
+			}
+		}
+
+		public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
+			if(isFirstSuffix) {
+				int length = this.firstSuffixResults.length;
+				if(length == this.firstSuffixResultsCount) {
+					System.arraycopy(
+						this.firstSuffixResults,
+						0,
+						this.firstSuffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.firstSuffixResults[this.firstSuffixResultsCount++] = name;
+			} else {
+				int length = this.suffixResults.length;
+				if(length == this.suffixResultsCount) {
+					System.arraycopy(
+						this.suffixResults,
+						0,
+						this.suffixResults = new char[length * 2][],
+						0,
+						length);
+				}
+				this.suffixResults[this.suffixResultsCount++] = name;
+			}
+		}
+		public char[][] getResults(){
+			int count =
+				this.firstPrefixAndFirstSuffixResultsCount
+				+ this.firstPrefixAndSuffixResultsCount
+				+ this.prefixAndFirstSuffixResultsCount
+				+ this.prefixAndSuffixResultsCount
+				+ this.firstPrefixResultsCount
+				+ this.prefixResultsCount
+				+ this.firstSuffixResultsCount
+				+ this.suffixResultsCount
+				+ this.otherResultsCount;
+
+			char[][] results = new char[count][];
+
+			int index = 0;
+			System.arraycopy(this.firstPrefixAndFirstSuffixResults, 0, results, index, this.firstPrefixAndFirstSuffixResultsCount);
+			index += this.firstPrefixAndFirstSuffixResultsCount;
+			System.arraycopy(this.firstPrefixAndSuffixResults, 0, results, index, this.firstPrefixAndSuffixResultsCount);
+			index += this.firstPrefixAndSuffixResultsCount;
+			System.arraycopy(this.prefixAndFirstSuffixResults, 0, results, index, this.prefixAndFirstSuffixResultsCount);
+			index += this.prefixAndFirstSuffixResultsCount;
+			System.arraycopy(this.prefixAndSuffixResults, 0, results, index, this.prefixAndSuffixResultsCount);
+			index += this.prefixAndSuffixResultsCount;
+			System.arraycopy(this.firstPrefixResults, 0, results, index, this.firstPrefixResultsCount);
+			index += this.firstPrefixResultsCount;
+			System.arraycopy(this.prefixResults, 0, results, index, this.prefixResultsCount);
+			index += this.prefixResultsCount;
+			System.arraycopy(this.firstSuffixResults, 0, results, index, this.firstSuffixResultsCount);
+			index += this.firstSuffixResultsCount;
+			System.arraycopy(this.suffixResults, 0, results, index, this.suffixResultsCount);
+			index += this.suffixResultsCount;
+			System.arraycopy(this.otherResults, 0, results, index, this.otherResultsCount);
+
+			return results;
+		}
+	}
+	private static final char[] GETTER_BOOL_NAME = "is".toCharArray(); //$NON-NLS-1$
+	private static final char[] GETTER_NAME = "get".toCharArray(); //$NON-NLS-1$
+
+	private static final char[] SETTER_NAME = "set".toCharArray(); //$NON-NLS-1$
+
+
+	/**
+	 * Variable kind which represents a static field.
+	 * 
+	 * @since 3.5
+	 */
+	public static final int VK_STATIC_FIELD = InternalNamingConventions.VK_STATIC_FIELD;
+	/**
+	 * Variable kind which represents an instance field.
+	 * 
+	 * @since 3.5
+	 */
+	public static final int VK_INSTANCE_FIELD = InternalNamingConventions.VK_INSTANCE_FIELD;
+	/**
+	 * Variable kind which represents a static final field.
+	 * 
+	 * @since 3.5
+	 */
+	public static final int VK_STATIC_FINAL_FIELD = InternalNamingConventions.VK_STATIC_FINAL_FIELD;
+	/**
+	 * Variable kind which represents an argument.
+	 * 
+	 * @since 3.5
+	 */
+	public static final int VK_PARAMETER = InternalNamingConventions.VK_PARAMETER;
+	/**
+	 * Variable kind which represents a local variable.
+	 * 
+	 * @since 3.5
+	 */
+	public static final int VK_LOCAL = InternalNamingConventions.VK_LOCAL;
+	
+	/**
+	 * The base name associated to this base name kind is a simple name.
+	 * When this base name is used the whole name is considered.
+	 * 
+	 * @see #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int BK_NAME = InternalNamingConventions.BK_SIMPLE_NAME;
+	
+	/**
+	 * The base name associated to this base name kind is a simple type name.
+	 * When this base name is used all the words of the name are considered.
+	 * 
+	 * @see #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int BK_TYPE_NAME = InternalNamingConventions.BK_SIMPLE_TYPE_NAME;
+
+	private static String[] convertCharsToString(char[][] c) {
+		int length = c == null ? 0 : c.length;
+		String[] s = new String[length];
+		for (int i = 0; i < length; i++) {
+			s[i] = String.valueOf(c[i]);
+		}
+		return s;
+	}
+	private static char[][] convertStringToChars(String[] s) {
+		int length = s == null ? 0 : s.length;
+		char[][] c = new char[length][];
+		for (int i = 0; i < length; i++) {
+			if(s[i] == null) {
+				c[i] = CharOperation.NO_CHAR;
+			} else {
+				c[i] = s[i].toCharArray();
+			}
+		}
+		return c;
+	}
+
+	/**
+	 * Remove prefix and suffix from an argument name.
+	 * <p>
+	 * If argument name prefix is <code>pre</code> and argument name suffix is <code>suf</code>
+	 * then for an argument named <code>preArgsuf</code> the result of this method is <code>arg</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preArgsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+ 	 *
+	 * @param javaProject project which contains the argument.
+	 * @param argumentName argument's name.
+	 * @return char[] the name without prefix and suffix.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead with {@link #VK_PARAMETER} as variable kind.
+	 */
+	public static char[] removePrefixAndSuffixForArgumentName(IJavaProject javaProject, char[] argumentName) {
+		return InternalNamingConventions.removeVariablePrefixAndSuffix(VK_PARAMETER, javaProject, argumentName);
+	}
+
+	/**
+	 * Remove prefix and suffix from an argument name.
+	 * <p>
+	 * If argument name prefix is <code>pre</code> and argument name suffix is <code>suf</code>
+	 * then for an argument named <code>preArgsuf</code> the result of this method is <code>arg</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preArgsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+ 	 *
+	 * @param javaProject project which contains the argument.
+	 * @param argumentName argument's name.
+	 * @return char[] the name without prefix and suffix.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead with {@link #VK_PARAMETER} as variable kind.
+	 */
+	public static String removePrefixAndSuffixForArgumentName(IJavaProject javaProject, String argumentName) {
+		return String.valueOf(removePrefixAndSuffixForArgumentName(javaProject, argumentName.toCharArray()));
+	}
+	/**
+	 * Remove prefix and suffix from a field name.
+	 * <p>
+	 * If field name prefix is <code>pre</code> and field name suffix is <code>suf</code>
+	 * then for a field named <code>preFieldsuf</code> the result of this method is <code>field</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preFieldsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options : {@link JavaCore#CODEASSIST_FIELD_PREFIXES} } ,
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the field.
+	 * @param fieldName field's name.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @return char[] the name without prefix and suffix.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead
+	 * with {@link #VK_INSTANCE_FIELD} or {@link #VK_STATIC_FIELD} as variable kind.
+	 */
+	public static char[] removePrefixAndSuffixForFieldName(IJavaProject javaProject, char[] fieldName, int modifiers) {
+		return InternalNamingConventions.removeVariablePrefixAndSuffix(
+				Flags.isStatic(modifiers) ? VK_STATIC_FIELD : VK_INSTANCE_FIELD,
+				javaProject,
+				fieldName);
+	}
+
+	/**
+	 * Remove prefix and suffix from a field name.
+	 * <p>
+	 * If field name prefix is <code>pre</code> and field name suffix is <code>suf</code>
+	 * then for a field named <code>preFieldsuf</code> the result of this method is <code>field</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preFieldsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the field.
+	 * @param fieldName field's name.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @return char[] the name without prefix and suffix.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead
+	 * with {@link #VK_INSTANCE_FIELD} or {@link #VK_STATIC_FIELD} as variable kind.
+	 */
+	public static String removePrefixAndSuffixForFieldName(IJavaProject javaProject, String fieldName, int modifiers) {
+		return String.valueOf(removePrefixAndSuffixForFieldName(javaProject, fieldName.toCharArray(), modifiers));
+	}
+
+	/**
+	 * Remove prefix and suffix from a local variable name.
+	 * <p>
+	 * If local variable name prefix is <code>pre</code> and local variable name suffix is <code>suf</code>
+	 * then for a local variable named <code>preLocalsuf</code> the result of this method is <code>local</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preLocalsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the variable.
+	 * @param localName variable's name.
+	 * @return char[] the name without prefix and suffix.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead with {@link #VK_LOCAL} as variable kind.
+	 */
+	public static char[] removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, char[] localName) {
+		return InternalNamingConventions.removeVariablePrefixAndSuffix(VK_LOCAL, javaProject, localName);
+	}
+
+	/**
+	 * Remove prefix and suffix from a local variable name.
+	 * <p>
+	 * If local variable name prefix is <code>pre</code> and local variable name suffix is <code>suf</code>
+	 * then for a local variable named <code>preLocalsuf</code> the result of this method is <code>local</code>.
+	 * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
+	 * name <code>preLocalsuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the variable.
+	 * @param localName variable's name.
+	 * @return char[] the name without prefix and suffix.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #getBaseName(int, String, IJavaProject)} instead with {@link #VK_LOCAL} as variable kind.
+	 */
+	public static String removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, String localName) {
+		return String.valueOf(removePrefixAndSuffixForLocalVariableName(javaProject, localName.toCharArray()));
+	}
+	
+	/**
+	 * Returns a base name which could be used to generate the given variable name with {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)}.
+	 * <p>
+	 * e.g.<br>
+	 * If the variable is a {@link #VK_LOCAL} and the variable name is <code>variableName</code> then the base name will be <code>variableName</code>.<br>
+	 * If the variable is a {@link #VK_STATIC_FINAL_FIELD} and the variable name is <code>VARIABLE_NAME</code> then the base name will be <code>variableName</code>.<br>
+	 * </p>
+	 * <p>
+	 * Prefixes and suffixes defined in JavaCore options will be also removed from the variable name.<br>
+	 * Each variable kind is affected by the following JavaCore options:
+	 * <ul>
+	 * <li>{@link #VK_PARAMETER}: {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}</li>
+	 * <li>{@link #VK_LOCAL}: {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}</li>
+	 * <li>{@link #VK_INSTANCE_FIELD}: {@link JavaCore#CODEASSIST_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_FIELD_SUFFIXES}</li>
+	 * <li>{@link #VK_STATIC_FIELD}: {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES}</li>
+	 * <li>{@link #VK_STATIC_FINAL_FIELD}: {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES}</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * e.g.<br>
+	 * If the variable is a {@link #VK_LOCAL}, the variable name is <code>preVariableNamesuf</code>, a possible prefix is <code>pre</code> and a possible suffix is <code>suf</code>
+	 * then the base name will be <code>variableName</code>.<br>
+	 * </p>
+	 * 
+	 * @param variableKind specifies what type the variable is: {@link #VK_LOCAL}, {@link #VK_PARAMETER}, {@link #VK_STATIC_FIELD},
+	 * {@link #VK_INSTANCE_FIELD} or {@link #VK_STATIC_FINAL_FIELD}.
+	 * @param variableName a variable name
+	 * @param javaProject project which contains the variable or <code>null</code> to take into account only workspace settings.
+	 * 
+	 * @see #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)
+	 * @since 3.5
+	 */
+	public static String getBaseName(
+			int variableKind,
+			String variableName,
+			IJavaProject javaProject) {
+		return String.valueOf(InternalNamingConventions.getBaseName(variableKind, javaProject, variableName.toCharArray(), true));
+	}
+	
+	private static int getFieldVariableKind(int modifiers) {
+		if (Flags.isStatic(modifiers)) {
+			if (Flags.isFinal(modifiers)) {
+				return VK_STATIC_FINAL_FIELD;
+			}
+			return VK_STATIC_FIELD;
+		}
+		return VK_INSTANCE_FIELD;
+	}
+
+	private static char[] suggestAccessorName(IJavaProject project, char[] fieldName, int modifiers) {
+		char[] name = InternalNamingConventions.getBaseName(getFieldVariableKind(modifiers), project, fieldName, false);
+		if (name.length > 0 && ScannerHelper.isLowerCase(name[0])) {
+			if (name.length == 1 || !ScannerHelper.isUpperCase(name[1])) {
+				name[0] = ScannerHelper.toUpperCase(name[0]);
+			}
+		}
+		return name;
+	}
+
+	/**
+	 * Suggest names for an argument. The name is computed from argument's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the argument is <code>TypeName</code>, the prefix for argument is <code>pre</code>
+	 * and the suffix for argument is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the argument.
+	 * @param packageName package of the argument's type.
+	 * @param qualifiedTypeName argument's type.
+	 * @param dim argument's dimension (0 if the argument is not an array).
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead with {@link #VK_PARAMETER} as variable kind.
+	 */
+	public static char[][] suggestArgumentNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {
+		if(qualifiedTypeName == null || qualifiedTypeName.length == 0)
+			return CharOperation.NO_CHAR_CHAR;
+		
+		char[] typeName = CharOperation.lastSegment(qualifiedTypeName, '.');
+		
+ 		NamingRequestor requestor = new NamingRequestor();
+		InternalNamingConventions.suggestVariableNames(
+				VK_PARAMETER,
+				BK_TYPE_NAME,
+				typeName,
+				javaProject,
+				dim,
+				null,
+				excludedNames,
+				true,
+				requestor);
+ 
+ 		return requestor.getResults();
+	}
+
+	/**
+	 * Suggest names for an argument. The name is computed from argument's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the argument is <code>TypeName</code>, the prefix for argument is <code>pre</code>
+	 * and the suffix for argument is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the argument.
+	 * @param packageName package of the argument's type.
+	 * @param qualifiedTypeName argument's type.
+	 * @param dim argument's dimension (0 if the argument is not an array).
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead with {@link #VK_PARAMETER} as variable kind.
+	 */
+	public static String[] suggestArgumentNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {
+		return convertCharsToString(
+			suggestArgumentNames(
+				javaProject,
+				packageName.toCharArray(),
+				qualifiedTypeName.toCharArray(),
+				dim,
+				convertStringToChars(excludedNames)));
+	}
+
+	/**
+	 * Suggest names for a field. The name is computed from field's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the field is <code>TypeName</code>, the prefix for field is <code>pre</code>
+	 * and the suffix for field is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} and for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the field.
+	 * @param packageName package of the field's type.
+	 * @param qualifiedTypeName field's type.
+	 * @param dim field's dimension (0 if the field is not an array).
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead 
+	 * with {@link #VK_INSTANCE_FIELD} or  {@link #VK_STATIC_FIELD} as variable kind.
+	 */
+	public static char[][] suggestFieldNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, int modifiers, char[][] excludedNames) {
+		if(qualifiedTypeName == null || qualifiedTypeName.length == 0)
+			return CharOperation.NO_CHAR_CHAR;
+		
+		char[] typeName = CharOperation.lastSegment(qualifiedTypeName, '.');
+		
+ 		NamingRequestor requestor = new NamingRequestor();
+		InternalNamingConventions.suggestVariableNames(
+				Flags.isStatic(modifiers) ? VK_STATIC_FIELD : VK_INSTANCE_FIELD,
+				BK_TYPE_NAME,
+				typeName,
+				javaProject,
+				dim,
+				null,
+				excludedNames,
+				true,
+				requestor);
+ 
+ 		return requestor.getResults();
+	}
+
+	/**
+	 * Suggest names for a field. The name is computed from field's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the field is <code>TypeName</code>, the prefix for field is <code>pre</code>
+	 * and the suffix for field is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} and for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the field.
+	 * @param packageName package of the field's type.
+	 * @param qualifiedTypeName field's type.
+	 * @param dim field's dimension (0 if the field is not an array).
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead 
+	 * with {@link #VK_INSTANCE_FIELD} or  {@link #VK_STATIC_FIELD} as variable kind.
+	 */
+	public static String[] suggestFieldNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, int modifiers, String[] excludedNames) {
+		return convertCharsToString(
+			suggestFieldNames(
+				javaProject,
+				packageName.toCharArray(),
+				qualifiedTypeName.toCharArray(),
+				dim,
+				modifiers,
+				convertStringToChars(excludedNames)));
+	}
+	
+	/**
+	 * Suggest name for a getter method. The name is computed from field's name
+	 * and possible prefixes or suffixes are removed.
+	 * <p>
+	 * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
+	 * the suffix for field is <code>suf</code> then the prosposed name is <code>isFieldName</code> for boolean field or
+	 * <code>getFieldName</code> for others. If there is no prefix and suffix the proposal is <code>isPreFieldNamesuf</code>
+	 * for boolean field or <code>getPreFieldNamesuf</code> for others.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param project project which contains the field.
+	 * @param fieldName field's name's.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param isBoolean <code>true</code> if the field's type is boolean
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[] a name.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 */
+	public static char[] suggestGetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) {
+		if (isBoolean) {
+			char[] name = InternalNamingConventions.getBaseName(getFieldVariableKind(modifiers), project, fieldName, false);
+			int prefixLen =  GETTER_BOOL_NAME.length;
+			if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name)
+				&& name.length > prefixLen && ScannerHelper.isUpperCase(name[prefixLen])) {
+				return suggestNewName(name, excludedNames);
+			} else {
+				return suggestNewName(
+					CharOperation.concat(GETTER_BOOL_NAME, suggestAccessorName(project, fieldName, modifiers)),
+					excludedNames
+				);
+			}
+		} else {
+			return suggestNewName(
+				CharOperation.concat(GETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
+				excludedNames
+			);
+		}
+	}
+	/**
+	 * Suggest name for a getter method. The name is computed from field's name
+	 * and possible prefixes or suffixes are removed.
+	 * <p>
+	 * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
+	 * the suffix for field is <code>suf</code> then the prosposed name is <code>isFieldName</code> for boolean field or
+	 * <code>getFieldName</code> for others. If there is no prefix and suffix the proposal is <code>isPreFieldNamesuf</code>
+	 * for boolean field or <code>getPreFieldNamesuf</code> for others.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param project project which contains the field.
+	 * @param fieldName field's name's.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param isBoolean <code>true</code> if the field's type is boolean
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[] a name.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 */
+	public static String suggestGetterName(IJavaProject project, String fieldName, int modifiers, boolean isBoolean, String[] excludedNames) {
+		return String.valueOf(
+			suggestGetterName(
+				project,
+				fieldName.toCharArray(),
+				modifiers,
+				isBoolean,
+				convertStringToChars(excludedNames)));
+	}
+	/**
+	 * Suggest names for a local variable. The name is computed from variable's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the local variable is <code>TypeName</code>, the prefix for local variable is <code>pre</code>
+	 * and the suffix for local variable is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the variable.
+	 * @param packageName package of the variable's type.
+	 * @param qualifiedTypeName variable's type.
+	 * @param dim variable's dimension (0 if the variable is not an array).
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead with {@link #VK_LOCAL} as variable kind.
+	 */
+	public static char[][] suggestLocalVariableNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {
+		if(qualifiedTypeName == null || qualifiedTypeName.length == 0)
+			return CharOperation.NO_CHAR_CHAR;
+		
+		char[] typeName = CharOperation.lastSegment(qualifiedTypeName, '.');
+		
+		NamingRequestor requestor = new NamingRequestor();
+		InternalNamingConventions.suggestVariableNames(
+				VK_LOCAL,
+				BK_TYPE_NAME,
+				typeName,
+				javaProject,
+				dim,
+				null,
+				excludedNames,
+				true,
+				requestor);
+ 
+		return requestor.getResults();
+
+	}
+	/**
+	 * Suggest names for a local variable. The name is computed from variable's type
+	 * and possible prefixes or suffixes are added.
+	 * <p>
+	 * If the type of the local variable is <code>TypeName</code>, the prefix for local variable is <code>pre</code>
+	 * and the suffix for local variable is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
+	 * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
+	 * and <code>name</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and
+	 *  {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param javaProject project which contains the variable.
+	 * @param packageName package of the variable's type.
+	 * @param qualifiedTypeName variable's type.
+	 * @param dim variable's dimension (0 if the variable is not an array).
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[][] an array of names.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @deprecated Use {@link #suggestVariableNames(int, int, String, IJavaProject, int, String[], boolean)} instead with {@link #VK_LOCAL} as variable kind.
+	 */
+	public static String[] suggestLocalVariableNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {
+		return convertCharsToString(
+			suggestLocalVariableNames(
+				javaProject,
+				packageName.toCharArray(),
+				qualifiedTypeName.toCharArray(),
+				dim,
+				convertStringToChars(excludedNames)));
+	}
+	private static char[] suggestNewName(char[] name, char[][] excludedNames){
+		if(excludedNames == null) {
+			return name;
+		}
+
+		char[] newName = name;
+		int count = 2;
+		int i = 0;
+		while (i < excludedNames.length) {
+			if(CharOperation.equals(newName, excludedNames[i], false)) {
+				newName = CharOperation.concat(name, String.valueOf(count++).toCharArray());
+				i = 0;
+			} else {
+				i++;
+			}
+		}
+		return newName;
+	}
+	
+	/**
+	 * Suggest name for a setter method. The name is computed from field's name
+	 * and possible prefixes or suffixes are removed.
+	 * <p>
+	 * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
+	 * the suffix for field is <code>suf</code> then the proposed name is <code>setFieldName</code>.
+	 * If there is no prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param project project which contains the field.
+	 * @param fieldName field's name's.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param isBoolean <code>true</code> if the field's type is boolean
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[] a name.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 */
+	public static char[] suggestSetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) {
+
+		if (isBoolean) {
+			char[] name = InternalNamingConventions.getBaseName(getFieldVariableKind(modifiers), project, fieldName, false);
+			int prefixLen =  GETTER_BOOL_NAME.length;
+			if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name)
+				&& name.length > prefixLen && ScannerHelper.isUpperCase(name[prefixLen])) {
+				name = CharOperation.subarray(name, prefixLen, name.length);
+				return suggestNewName(
+					CharOperation.concat(SETTER_NAME, suggestAccessorName(project, name, modifiers)),
+					excludedNames
+				);
+			} else {
+				return suggestNewName(
+					CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
+					excludedNames
+				);
+			}
+		} else {
+			return suggestNewName(
+				CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
+				excludedNames
+			);
+		}
+	}
+	/**
+	 * Suggest name for a setter method. The name is computed from field's name
+	 * and possible prefixes or suffixes are removed.
+	 * <p>
+	 * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
+	 * the suffix for field is <code>suf</code> then the proposed name is <code>setFieldName</code>.
+	 * If there is no prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
+	 * </p>
+	 * <p>
+	 * This method is affected by the following JavaCore options :  {@link JavaCore#CODEASSIST_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and  {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES},
+	 *  {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field.
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
+	 * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
+	 * </p>
+	 *
+	 * @param project project which contains the field.
+	 * @param fieldName field's name's.
+	 * @param modifiers field's modifiers as defined by the class
+	 * <code>Flags</code>.
+	 * @param isBoolean <code>true</code> if the field's type is boolean
+	 * @param excludedNames a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there is no excluded names.
+	 * @return char[] a name.
+	 * @see Flags
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 */
+	public static String suggestSetterName(IJavaProject project, String fieldName, int modifiers, boolean isBoolean, String[] excludedNames) {
+		return String.valueOf(
+			suggestSetterName(
+				project,
+				fieldName.toCharArray(),
+				modifiers,
+				isBoolean,
+				convertStringToChars(excludedNames)));
+	}
+	
+	/**
+	 * Suggests names for a variable. The name is computed from a base name and possible prefixes or suffixes are added.
+	 *
+	 * <p>
+	 * The base name is used to compute the variable name.
+	 * Some different kinds of base names are possible and each kind is associated to a different heuristic to compute variable names.<br>
+	 * The heuristic depends also on the kind of the variable. Each kind of variable is identified by a constant starting with <code>VK_</code>.<br>
+	 * When a prefix and a suffix can be added then all combinations of prefix and suffix are suggested.
+	 * If the name is <code>name</code>, the prefix is <code>pre</code> and the suffix is <code>suf</code> then the suggested names will be
+	 * <code>prenamesuf</code>, <code>prename</code>, <code>namesuf</code> and <code>name</code>.<br>
+	 * <br>
+	 * The different kinds of base names are:
+	 * <ul>
+	 * <li>{@link #BK_NAME}: the base name is a Java name and the whole base name is considered to compute the variable names. A prefix and a suffix can be added.<br>
+	 * There is a heuristic by variable kind.
+	 * <ul>
+	 * <li>{@link #VK_PARAMETER}, {@link #VK_LOCAL}, {@link #VK_INSTANCE_FIELD} and {@link #VK_STATIC_FIELD}:<br>
+	 * In this case the first word will be converted to lower case and the other characters won't be changed.<br>
+	 * If the base name is <code>SimpleName</code> then the suggested name will be <code>simpleName</code>.<br></li>
+	 * <li>{@link #VK_STATIC_FINAL_FIELD} :<br>
+	 * In this case all letters of the name will be converted to upper case and words will be separated by an underscore (<code>"_"</code>).<br>
+	 * If the base name is <code>SimpleName</code> then the suggested name will be <code>SIMPLE_NAME</code>.</li>
+	 * </ul></li>
+	 * <li>{@link #BK_TYPE_NAME}: the base name is a Java simple type name (e.g. <code>HashMap</code>) and all the words of the base name are considered to compute the variable names. A prefix and a suffix can be added to these names.<br>
+	 * There is a heuristic by variable kind.
+	 * <ul>
+	 * <li>{@link #VK_PARAMETER}, {@link #VK_LOCAL}, {@link #VK_INSTANCE_FIELD} and {@link #VK_STATIC_FIELD}:<br>
+	 * In this case a variable name will contain some words of the base name and the first word will be converted to lower case.<br>
+	 * If the type is <code>TypeName</code> then the suggested names will be <code>typeName</code> and <code>name</code>.</li>
+	 * <li>{@link #VK_STATIC_FINAL_FIELD} :<br>
+	 * In this case a variable name will contain some words of the base name, all letters of the name will be converted to upper case and segments will be separated by a underscore (<code>"_"</code>).<br>
+	 * If the base name is <code>TypeName</code> then the suggested name will be <code>TYPE_NAME</code> and <code>NAME</code>.</li>
+	 * </ul></li>
+	 * </ul>
+	 * Some other kinds could be added in the future.
+	 * </p>
+	 * <p>
+	 * Each variable kind is affected by the following JavaCore options:
+	 * <ul>
+	 * <li>{@link #VK_PARAMETER}: {@link JavaCore#CODEASSIST_ARGUMENT_PREFIXES} and {@link JavaCore#CODEASSIST_ARGUMENT_SUFFIXES}</li>
+	 * <li>{@link #VK_LOCAL}: {@link JavaCore#CODEASSIST_LOCAL_PREFIXES} and {@link JavaCore#CODEASSIST_LOCAL_SUFFIXES}</li>
+	 * <li>{@link #VK_INSTANCE_FIELD}: {@link JavaCore#CODEASSIST_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_FIELD_SUFFIXES}</li>
+	 * <li>{@link #VK_STATIC_FIELD}: {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES}</li>
+	 * <li>{@link #VK_STATIC_FINAL_FIELD}: {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_PREFIXES} and {@link JavaCore#CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES}</li>
+	 * </ul>
+	 * </p>
+	 * <p>
+	 * For a complete description of these configurable options, see {@link JavaCore#getDefaultOptions()}.
+	 * To programmatically change these options, see {@link JavaCore#setOptions(java.util.Hashtable)} and {@link IJavaProject#setOptions(java.util.Map)}
+	 * </p>
+	 * <p>
+	 * Proposed names are sorted by relevance (best proposal first).<br>
+	 * The names are proposed in the following order:
+	 * <ol>
+	 * <li>Names with prefix and suffix. Longer names are proposed first</li>
+	 * <li>Names with prefix. Longer names are proposed first</li>
+	 * <li>Names with suffix. Longer names are proposed first</li>
+	 * <li>Names without prefix and suffix. Longer names are proposed first</li>
+	 * </ol>
+	 * </p>
+	 *
+	 * @param variableKind specifies what type the variable is: {@link #VK_LOCAL}, {@link #VK_PARAMETER}, {@link #VK_STATIC_FIELD},
+	 * {@link #VK_INSTANCE_FIELD} or {@link #VK_STATIC_FINAL_FIELD}.
+	 * @param baseNameKind specifies what type the base name is: {@link #BK_NAME} or {@link #BK_TYPE_NAME}
+	 * @param baseName name used to compute the suggested names.
+	 * @param javaProject project which contains the variable or <code>null</code> to take into account only workspace settings.
+	 * @param dim variable dimension (0 if the field is not an array).
+	 * @param excluded a list of names which cannot be suggested (already used names).
+	 *         Can be <code>null</code> if there are no excluded names.
+	 * @param evaluateDefault if <code>true</code>, the result is guaranteed to contain at least one result. If <code>false</code>, the result can be an empty array.
+	 * @return String[] an array of names.
+	 * @see JavaCore#setOptions(java.util.Hashtable)
+	 * @see JavaCore#getDefaultOptions()
+	 * 
+	 * @since 3.5
+	 */
+	public static String[] suggestVariableNames(
+			int variableKind,
+			int baseNameKind,
+			String baseName,
+			IJavaProject javaProject,
+			int dim,
+			String[] excluded,
+			boolean evaluateDefault) {
+		
+		NamingRequestor requestor = new NamingRequestor();
+		InternalNamingConventions.suggestVariableNames(
+			variableKind,
+			baseNameKind,
+			baseName.toCharArray(),
+			javaProject,
+			dim,
+			null,
+			convertStringToChars(excluded),
+			evaluateDefault,
+			requestor);
+
+		return convertCharsToString(requestor.getResults());
+	}
+	
+	private NamingConventions() {
+		// Not instantiable
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
new file mode 100644
index 0000000..1aa9da9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
@@ -0,0 +1,2907 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     IBM Corporation - added J2SE 1.5 support
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * Provides methods for encoding and decoding type and method signature strings.
+ * <p>
+ * Signatures obtained from parsing source files (i.e. files with one of the
+ * {@link JavaCore#getJavaLikeExtensions() Java-like extensions}) differ subtly
+ * from ones obtained from pre-compiled binary (".class") files in class names are
+ * usually left unresolved in the former. For example, the normal resolved form
+ * of the type "String" embeds the class's package name ("Ljava.lang.String;"
+ * or "Ljava/lang/String;"), whereas the unresolved form contains only what is
+ * written "QString;".
+ * </p>
+ * <p>
+ * Generic types introduce to the Java language in J2SE 1.5 add three new
+ * facets to signatures: type variables, parameterized types with type arguments,
+ * and formal type parameters. <i>Rich</i> signatures containing these facets
+ * only occur when dealing with code that makes overt use of the new language
+ * features. All other code, and certainly all Java code written or compiled
+ * with J2SE 1.4 or earlier, involved only <i>simple</i> signatures.
+ * </p>
+ * <p>
+ * Note that the "Q", "!" and "|" formats are specific to Eclipse; the remainder
+ * are specified in the JVM spec.
+ * </p>
+ * <p>
+ * The syntax for a type signature is:
+ * <pre>
+ * TypeSignature ::=
+ *     "B"  // byte
+ *   | "C"  // char
+ *   | "D"  // double
+ *   | "F"  // float
+ *   | "I"  // int
+ *   | "J"  // long
+ *   | "S"  // short
+ *   | "V"  // void
+ *   | "Z"  // boolean
+ *   | "T" + Identifier + ";" // type variable
+ *   | "[" + TypeSignature  // array X[]
+ *   | "!" + TypeSignature  // capture-of ?
+ *   | "|" + TypeSignature + (":" + TypeSignature)+ // intersection type
+ *   | ResolvedClassTypeSignature
+ *   | UnresolvedClassTypeSignature
+ *
+ * ResolvedClassTypeSignature ::= // resolved named type (in compiled code)
+ *     "L" + Identifier + OptionalTypeArguments
+ *           ( ( "." | "/" ) + Identifier + OptionalTypeArguments )* + ";"
+ *     | OptionalTypeParameters + "L" + Identifier +
+ *           ( ( "." | "/" ) + Identifier )* + ";"
+ *
+ * UnresolvedClassTypeSignature ::= // unresolved named type (in source code)
+ *     "Q" + Identifier + OptionalTypeArguments
+ *           ( ( "." | "/" ) + Identifier + OptionalTypeArguments )* + ";"
+ *     | OptionalTypeParameters "Q" + Identifier +
+ *           ( ( "." | "/" ) + Identifier )* + ";"
+ *
+ * OptionalTypeArguments ::=
+ *     "&lt;" + TypeArgument+ + "&gt;"
+ *   |
+ *
+ * TypeArgument ::=
+ *   | TypeSignature
+ *   | "*" // wildcard ?
+ *   | "+" TypeSignature // wildcard ? extends X
+ *   | "-" TypeSignature // wildcard ? super X
+ *
+ * OptionalTypeParameters ::=
+ *     "&lt;" + FormalTypeParameterSignature+ + "&gt;"
+ *   |
+ * </pre>
+ * </p>
+ * <p>
+ * Examples:
+ * <ul>
+ *   <li><code>"[[I"</code> denotes <code>int[][]</code></li>
+ *   <li><code>"Ljava.lang.String;"</code> denotes <code>java.lang.String</code> in compiled code</li>
+ *   <li><code>"QString;"</code> denotes <code>String</code> in source code</li>
+ *   <li><code>"Qjava.lang.String;"</code> denotes <code>java.lang.String</code> in source code</li>
+ *   <li><code>"[QString;"</code> denotes <code>String[]</code> in source code</li>
+ *   <li><code>"QMap&lt;QString;*&gt;;"</code> denotes <code>Map&lt;String,?&gt;</code> in source code</li>
+ *   <li><code>"Qjava.util.List&ltTV;&gt;;"</code> denotes <code>java.util.List&lt;V&gt;</code> in source code</li>
+ *   <li><code>"&ltE;&gt;Ljava.util.List;"</code> denotes <code>&lt;E&gt;java.util.List</code> in source code</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The syntax for a method signature is:
+ * <pre>
+ * MethodSignature ::= OptionalTypeParameters + "(" + ParamTypeSignature* + ")" + ReturnTypeSignature
+ * ParamTypeSignature ::= TypeSignature
+ * ReturnTypeSignature ::= TypeSignature
+ * </pre>
+ * <p>
+ * Examples:
+ * <ul>
+ *   <li><code>"()I"</code> denotes <code>int foo()</code></li>
+ *   <li><code>"([Ljava.lang.String;)V"</code> denotes <code>void foo(java.lang.String[])</code> in compiled code</li>
+ *   <li><code>"(QString;)QObject;"</code> denotes <code>Object foo(String)</code> in source code</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The syntax for a formal type parameter signature is:
+ * <pre>
+ * FormalTypeParameterSignature ::=
+ *     TypeVariableName + OptionalClassBound + InterfaceBound*
+ * TypeVariableName ::= Identifier
+ * OptionalClassBound ::=
+ *     ":"
+ *   | ":" + TypeSignature
+ * InterfaceBound ::=
+ *     ":" + TypeSignature
+ * </pre>
+ * <p>
+ * Examples:
+ * <ul>
+ *   <li><code>"X:"</code> denotes <code>X</code></li>
+ *   <li><code>"X:QReader;"</code> denotes <code>X extends Reader</code> in source code</li>
+ *   <li><code>"X:QReader;:QSerializable;"</code> denotes <code>X extends Reader & Serializable</code> in source code</li>
+ * </ul>
+ * </p>
+ * <p>
+ * This class provides static methods and constants only.
+ * </p>
+ * <p>Note: An empty signature is considered to be syntactically incorrect. So most methods will throw
+ * an IllegalArgumentException if an empty signature is provided.</p>
+ * 
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Signature {
+
+	/**
+	 * Kind constant for an array type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.0
+	 */
+	public static final int ARRAY_TYPE_SIGNATURE = 4;
+
+	/**
+	 * Kind constant for a base (primitive or void) type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.0
+	 */
+	public static final int BASE_TYPE_SIGNATURE = 2;
+
+	private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
+
+	private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * Character constant indicating an array type in a signature.
+	 * Value is <code>'['</code>.
+	 */
+	public static final char C_ARRAY = org.eclipse.jdt.internal.compiler.util.Util.C_ARRAY;
+
+	/**
+	 * Character constant indicating the primitive type boolean in a signature.
+	 * Value is <code>'Z'</code>.
+	 */
+	public static final char C_BOOLEAN = org.eclipse.jdt.internal.compiler.util.Util.C_BOOLEAN;
+
+	/**
+	 * Character constant indicating the primitive type byte in a signature.
+	 * Value is <code>'B'</code>.
+	 */
+	public static final char C_BYTE = org.eclipse.jdt.internal.compiler.util.Util.C_BYTE;
+
+	/**
+	 * Character constant indicating a capture of a wildcard type in a
+	 * signature. Value is <code>'!'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_CAPTURE = org.eclipse.jdt.internal.compiler.util.Util.C_CAPTURE;
+
+	/**
+	 * Character constant indicating the primitive type char in a signature.
+	 * Value is <code>'C'</code>.
+	 */
+	public static final char C_CHAR = org.eclipse.jdt.internal.compiler.util.Util.C_CHAR;
+
+	/**
+	 * Character constant indicating the colon in a signature.
+	 * Value is <code>':'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_COLON = org.eclipse.jdt.internal.compiler.util.Util.C_COLON;
+
+	/**
+	 * Character constant indicating the dollar in a signature.
+	 * Value is <code>'$'</code>.
+	 */
+	public static final char C_DOLLAR = org.eclipse.jdt.internal.compiler.util.Util.C_DOLLAR;
+
+	/**
+	 * Character constant indicating the dot in a signature.
+	 * Value is <code>'.'</code>.
+	 */
+	public static final char C_DOT = org.eclipse.jdt.internal.compiler.util.Util.C_DOT;
+
+	/**
+	 * Character constant indicating the primitive type double in a signature.
+	 * Value is <code>'D'</code>.
+	 */
+	public static final char C_DOUBLE = org.eclipse.jdt.internal.compiler.util.Util.C_DOUBLE;
+
+	/**
+	 * Character constant indicating an exception in a signature.
+	 * Value is <code>'^'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_EXCEPTION_START = org.eclipse.jdt.internal.compiler.util.Util.C_EXCEPTION_START;
+
+	/**
+	 * Character constant indicating a bound wildcard type argument
+	 * in a signature with extends clause.
+	 * Value is <code>'+'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_EXTENDS = org.eclipse.jdt.internal.compiler.util.Util.C_EXTENDS;
+
+	/**
+	 * Character constant indicating the primitive type float in a signature.
+	 * Value is <code>'F'</code>.
+	 */
+	public static final char C_FLOAT = org.eclipse.jdt.internal.compiler.util.Util.C_FLOAT;
+
+	/**
+	 * Character constant indicating the end of a generic type list in a
+	 * signature. Value is <code>'&gt;'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_GENERIC_END = org.eclipse.jdt.internal.compiler.util.Util.C_GENERIC_END;
+
+	/**
+	 * Character constant indicating the start of a formal type parameter
+	 * (or type argument) list in a signature. Value is <code>'&lt;'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_GENERIC_START = org.eclipse.jdt.internal.compiler.util.Util.C_GENERIC_START;
+
+	/**
+	 * Character constant indicating the primitive type int in a signature.
+	 * Value is <code>'I'</code>.
+	 */
+	public static final char C_INT = org.eclipse.jdt.internal.compiler.util.Util.C_INT;
+
+	/**
+	 * Character constant indicating an intersection type in a
+	 * signature. Value is <code>'|'</code>.
+	 * @since 3.7.1
+	 */
+	public static final char C_INTERSECTION = '|';
+
+	/**
+	 * Character constant indicating the primitive type long in a signature.
+	 * Value is <code>'J'</code>.
+	 */
+	public static final char C_LONG = org.eclipse.jdt.internal.compiler.util.Util.C_LONG;
+
+	/**
+	 * Character constant indicating the end of a named type in a signature.
+	 * Value is <code>';'</code>.
+	 */
+	public static final char C_NAME_END = org.eclipse.jdt.internal.compiler.util.Util.C_NAME_END;
+
+	/**
+	 * Character constant indicating the end of a parameter type list in a
+	 * signature. Value is <code>')'</code>.
+	 */
+	public static final char C_PARAM_END = org.eclipse.jdt.internal.compiler.util.Util.C_PARAM_END;
+
+	/**
+	 * Character constant indicating the start of a parameter type list in a
+	 * signature. Value is <code>'('</code>.
+	 */
+	public static final char C_PARAM_START = org.eclipse.jdt.internal.compiler.util.Util.C_PARAM_START;
+
+	/**
+	 * Character constant indicating the start of a resolved, named type in a
+	 * signature. Value is <code>'L'</code>.
+	 */
+	public static final char C_RESOLVED = org.eclipse.jdt.internal.compiler.util.Util.C_RESOLVED;
+
+	/**
+	 * Character constant indicating the semicolon in a signature.
+	 * Value is <code>';'</code>.
+	 */
+	public static final char C_SEMICOLON = org.eclipse.jdt.internal.compiler.util.Util.C_SEMICOLON;
+
+	/**
+	 * Character constant indicating the primitive type short in a signature.
+	 * Value is <code>'S'</code>.
+	 */
+	public static final char C_SHORT = org.eclipse.jdt.internal.compiler.util.Util.C_SHORT;
+
+	/**
+	 * Character constant indicating an unbound wildcard type argument
+	 * in a signature.
+	 * Value is <code>'*'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_STAR = org.eclipse.jdt.internal.compiler.util.Util.C_STAR;
+
+	/**
+	 * Character constant indicating a bound wildcard type argument
+	 * in a signature with super clause.
+	 * Value is <code>'-'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_SUPER = org.eclipse.jdt.internal.compiler.util.Util.C_SUPER;
+
+	/**
+	 * Character constant indicating the start of a resolved type variable in a
+	 * signature. Value is <code>'T'</code>.
+	 * @since 3.0
+	 */
+	public static final char C_TYPE_VARIABLE = org.eclipse.jdt.internal.compiler.util.Util.C_TYPE_VARIABLE;
+
+	/**
+	 * Character constant indicating the start of an unresolved, named type in a
+	 * signature. Value is <code>'Q'</code>.
+	 */
+	public static final char C_UNRESOLVED = org.eclipse.jdt.internal.compiler.util.Util.C_UNRESOLVED;
+
+	/**
+	 * Character constant indicating result type void in a signature.
+	 * Value is <code>'V'</code>.
+	 */
+	public static final char C_VOID = org.eclipse.jdt.internal.compiler.util.Util.C_VOID;
+
+	private static final char[] CAPTURE = "capture-of".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * Kind constant for the capture of a wildcard type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.1
+	 */
+	public static final int CAPTURE_TYPE_SIGNATURE = 6;
+
+	private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * Kind constant for a class type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.0
+	 */
+	public static final int CLASS_TYPE_SIGNATURE = 1;
+
+	private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
+
+
+	private static final char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
+
+	private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
+
+	private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * Kind constant for the intersection type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.7.1
+	 */
+	public static final int INTERSECTION_TYPE_SIGNATURE = 7;
+
+	private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
+
+	private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * String constant for the signature of the primitive type boolean.
+	 * Value is <code>"Z"</code>.
+	 */
+	public static final String SIG_BOOLEAN 		= "Z"; //$NON-NLS-1$
+	
+	/**
+	 * String constant for the signature of the primitive type byte.
+	 * Value is <code>"B"</code>.
+	 */
+	public static final String SIG_BYTE 		= "B"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type char.
+	 * Value is <code>"C"</code>.
+	 */
+	public static final String SIG_CHAR 		= "C"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type double.
+	 * Value is <code>"D"</code>.
+	 */
+	public static final String SIG_DOUBLE 		= "D"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type float.
+	 * Value is <code>"F"</code>.
+	 */
+	public static final String SIG_FLOAT 		= "F"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type int.
+	 * Value is <code>"I"</code>.
+	 */
+	public static final String SIG_INT 			= "I"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type long.
+	 * Value is <code>"J"</code>.
+	 */
+	public static final String SIG_LONG			= "J"; //$NON-NLS-1$
+	/**
+	 * String constant for the signature of the primitive type short.
+	 * Value is <code>"S"</code>.
+	 */
+	public static final String SIG_SHORT		= "S"; //$NON-NLS-1$
+	/** String constant for the signature of result type void.
+	 * Value is <code>"V"</code>.
+	 */
+	public static final String SIG_VOID			= "V"; //$NON-NLS-1$
+	private static final char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+	/**
+	 * Kind constant for a type variable signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.0
+	 */
+	public static final int TYPE_VARIABLE_SIGNATURE = 3;
+	private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+	/**
+	 * Kind constant for a wildcard type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.1
+	 */
+	public static final int WILDCARD_TYPE_SIGNATURE = 5;
+
+// <x.y.z, a.b<c>.d<e.f>> --> <z,d<f>>
+private static void appendArgumentSimpleNames(char[] name, int start, int end, StringBuffer buffer) {
+	buffer.append('<');
+	int depth = 0;
+	int argumentStart = -1;
+	int argumentCount = 0;
+	for (int i = start; i <= end; i++) {
+		switch(name[i]) {
+			case '<' :
+				depth++;
+				if (depth == 1) {
+					argumentStart = i+1;
+				}
+				break;
+			case '>' :
+				if (depth == 1) {
+					if (argumentCount > 0) buffer.append(',');
+					appendSimpleName(name, argumentStart, i-1, buffer);
+					argumentCount++;
+				}
+				depth--;
+				break;
+			case ',' :
+				if (depth == 1) {
+					if (argumentCount > 0) buffer.append(',');
+					appendSimpleName(name, argumentStart, i-1, buffer);
+					argumentCount++;
+					argumentStart = i+1;
+				}
+				break;
+		}
+	}
+	buffer.append('>');
+}
+
+/**
+ * Scans the given string for an array type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not an array type signature
+ * @see Util#scanArrayTypeSignature(char[], int)
+ */
+private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer, false);
+}
+
+/**
+ * Scans the given string for an array type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param isVarArgs <code>true</code> if the array type must be displayed as a
+ * variable argument, <code>false</code> otherwise
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not an array type signature
+ * @see Util#scanArrayTypeSignature(char[], int)
+ */
+private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) {
+	int length = string.length;
+	// need a minimum 2 char
+	if (start >= length - 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (c != C_ARRAY) {
+		throw new IllegalArgumentException();
+	}
+
+	int index = start;
+	c = string[++index];
+	while(c == C_ARRAY) {
+		// need a minimum 2 char
+		if (index >= length - 1) {
+			throw new IllegalArgumentException();
+		}
+		c = string[++index];
+	}
+
+	int e = appendTypeSignature(string, index, fullyQualifyTypeNames, buffer);
+
+	for(int i = 1, dims = index - start; i < dims; i++) {
+		buffer.append('[').append(']');
+	}
+
+	if (isVarArgs) {
+		buffer.append('.').append('.').append('.');
+	} else {
+		buffer.append('[').append(']');
+	}
+	return e;
+}
+/**
+ * Scans the given string for an capture type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not an array type signature
+ * @see Util#scanArrayTypeSignature(char[], int)
+ */
+private static int appendCaptureTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 2 char
+	if (start >= string.length - 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (c != C_CAPTURE) {
+		throw new IllegalArgumentException();
+	}
+	buffer.append(CAPTURE).append(' ');
+	return appendTypeArgumentSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+}
+/**
+ * Scans the given string for a class type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param buffer the string buffer to append to
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not a class type signature
+ * @see Util#scanClassTypeSignature(char[], int)
+ */
+private static int appendClassTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 3 chars "Lx;"
+	if (start >= string.length - 2) {
+		throw new IllegalArgumentException();
+	}
+	// must start in "L" or "Q"
+	char c = string[start];
+	if (c != C_RESOLVED && c != C_UNRESOLVED) {
+		throw new IllegalArgumentException();
+	}
+	boolean resolved = (c == C_RESOLVED);
+	boolean removePackageQualifiers = !fullyQualifyTypeNames;
+	if (!resolved) {
+		// keep everything in an unresolved name
+		removePackageQualifiers = false;
+	}
+	int p = start + 1;
+	int checkpoint = buffer.length();
+	int innerTypeStart = -1;
+	boolean inAnonymousType = false;
+	while (true) {
+		if (p >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		c = string[p];
+		switch(c) {
+			case C_SEMICOLON :
+				// all done
+				return p;
+			case C_GENERIC_START :
+				int e = appendTypeArgumentSignatures(string, p, fullyQualifyTypeNames, buffer);
+				// once we hit type arguments there are no more package prefixes
+				removePackageQualifiers = false;
+				p = e;
+				break;
+			case C_DOT :
+				if (removePackageQualifiers) {
+					// erase package prefix
+					buffer.setLength(checkpoint);
+				} else {
+					buffer.append('.');
+				}
+				break;
+			 case '/' :
+				if (removePackageQualifiers) {
+					// erase package prefix
+					buffer.setLength(checkpoint);
+				} else {
+					buffer.append('/');
+				}
+				break;
+			 case C_DOLLAR :
+			 	innerTypeStart = buffer.length();
+			 	inAnonymousType = false;
+			 	if (resolved) {
+					// once we hit "$" there are no more package prefixes
+					removePackageQualifiers = false;
+					/**
+					 * Convert '$' in resolved type signatures into '.'.
+					 * NOTE: This assumes that the type signature is an inner type
+					 * signature. This is true in most cases, but someone can define a
+					 * non-inner type name containing a '$'.
+					 */
+					buffer.append('.');
+			 	}
+			 	break;
+			 default :
+				if (innerTypeStart != -1 && !inAnonymousType && Character.isDigit(c)) {
+					inAnonymousType = true;
+					buffer.setLength(innerTypeStart); // remove '.'
+					buffer.insert(checkpoint, "new "); //$NON-NLS-1$
+					buffer.append("(){}"); //$NON-NLS-1$
+				}
+			 	if (!inAnonymousType)
+					buffer.append(c);
+				innerTypeStart = -1;
+		}
+		p++;
+	}
+}
+/**
+ * Scans the given string for an intersection type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not an array type signature
+ * @see Util#scanArrayTypeSignature(char[], int)
+ */
+private static int appendIntersectionTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 2 char
+	if (start >= string.length - 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (c != C_INTERSECTION) {
+		throw new IllegalArgumentException();
+	}
+	start = appendClassTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+	if (start < string.length - 1) {
+		start++;
+		if (string[start] != C_COLON) {
+			throw new IllegalArgumentException("should be a colon at this location"); //$NON-NLS-1$
+		}
+		while (string[start] == C_COLON) {
+			buffer.append(" | "); //$NON-NLS-1$
+			start = appendClassTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+			if (start == string.length - 1) {
+				return start;
+			} else if (start > string.length - 1) {
+				throw new IllegalArgumentException("Should be at the end"); //$NON-NLS-1$
+			}
+			start++;
+		}
+	}
+	return start;
+}
+private static void appendSimpleName(char[] name, int start, int end, StringBuffer buffer) {
+	int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1;
+	int depth = 0;
+	if (name[start] == '?') { // wildcard
+		buffer.append("?"); //$NON-NLS-1$
+		int index = consumeWhitespace(name, start+1, end+1);
+		switch (name[index]) {
+			case 'e' :
+				int checkPos = checkName(EXTENDS, name, index, end);
+			    if (checkPos > 0) {
+			        buffer.append(' ').append(EXTENDS).append(' ');
+			        index = consumeWhitespace(name, checkPos, end+1);
+				}
+				break;
+			case 's' :
+				checkPos = checkName(SUPER, name, index, end+1);
+			    if (checkPos > 0) {
+			        buffer.append(' ').append(SUPER).append(' ');
+			        index = consumeWhitespace(name, checkPos, end+1);
+				}
+				break;
+		}
+		start = index; // leading segment got processed
+	}
+	lastDotLookup: for (int i = end; i >= start; i--) {
+		switch (name[i]) {
+			case '.':
+				if (depth == 0) {
+					lastDot = i;
+					char c = name[start];
+					if (c == C_EXTENDS || c == C_SUPER) {
+						buffer.append(c);
+					}
+					break lastDotLookup;
+				}
+				break;
+			case '<':
+				depth--;
+				if (depth == 0) lastGenericStart = i;
+				break;
+			case '>':
+				if (depth == 0) lastGenericEnd = i;
+				depth++;
+				break;
+		}
+	}
+	int nameStart = lastDot < 0 ? start : lastDot+1;
+	int nameEnd = lastGenericStart < 0 ? end+1 : lastGenericStart;
+	buffer.append(name, nameStart, nameEnd - nameStart);
+	if (lastGenericStart >= 0) {
+		appendArgumentSimpleNames(name, lastGenericStart, lastGenericEnd, buffer);
+		buffer.append(name, lastGenericEnd+1, end - lastGenericEnd); // copy trailing portion, may contain dimensions
+	}
+}
+
+/**
+ * Scans the given string for a type argument signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param buffer the string buffer to append to
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not a type argument signature
+ * @see Util#scanTypeArgumentSignature(char[], int)
+ */
+private static int appendTypeArgumentSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 1 char
+	if (start >= string.length) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	switch(c) {
+		case C_STAR :
+			buffer.append('?');
+			return start;
+		case C_EXTENDS :
+			buffer.append("? extends "); //$NON-NLS-1$
+			return appendTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+		case C_SUPER :
+			buffer.append("? super "); //$NON-NLS-1$
+			return appendTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+		default :
+			return appendTypeSignature(string, start, fullyQualifyTypeNames, buffer);
+	}
+}
+
+/**
+ * Scans the given string for a list of type arguments signature starting at the
+ * given index and appends it to the given buffer, and returns the index of the
+ * last character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param buffer the string buffer to append to
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not a list of type argument
+ * signatures
+ * @see Util#scanTypeArgumentSignatures(char[], int)
+ */
+private static int appendTypeArgumentSignatures(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 2 char "<>"
+	if (start >= string.length - 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (c != C_GENERIC_START) {
+		throw new IllegalArgumentException();
+	}
+	buffer.append('<');
+	int p = start + 1;
+	int count = 0;
+	while (true) {
+		if (p >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		c = string[p];
+		if (c == C_GENERIC_END) {
+			buffer.append('>');
+			return p;
+		}
+		if (count != 0) {
+			buffer.append(',');
+		}
+		int e = appendTypeArgumentSignature(string, p, fullyQualifyTypeNames, buffer);
+		count++;
+		p = e + 1;
+	}
+}
+/**
+ * Scans the given string for a type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param buffer the string buffer to append to
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not a type signature
+ * @see Util#scanTypeSignature(char[], int)
+ */
+private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	return appendTypeSignature(string, start, fullyQualifyTypeNames, buffer, false);
+}
+
+/**
+ * Scans the given string for a type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ *
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param buffer the string buffer to append to
+ * @param isVarArgs <code>true</code> if the type must be displayed as a
+ * variable argument, <code>false</code> otherwise. In this case, the type must be an array type
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not a type signature, or if isVarArgs is <code>true</code>,
+ * and the type is not an array type signature.
+ * @see Util#scanTypeSignature(char[], int)
+ */
+private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) {
+	// need a minimum 1 char
+	if (start >= string.length) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (isVarArgs) {
+		switch (c) {
+			case C_ARRAY :
+				return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer, true);
+			case C_RESOLVED :
+			case C_UNRESOLVED :
+			case C_TYPE_VARIABLE :
+			case C_BOOLEAN :
+			case C_BYTE :
+			case C_CHAR :
+			case C_DOUBLE :
+			case C_FLOAT :
+			case C_INT :
+			case C_LONG :
+			case C_SHORT :
+			case C_VOID :
+			case C_STAR:
+			case C_EXTENDS:
+			case C_SUPER:
+			case C_CAPTURE:
+			case C_INTERSECTION :
+			default:
+				throw new IllegalArgumentException(); // a var args is an array type
+		}
+	} else {
+		switch (c) {
+			case C_ARRAY :
+				return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer);
+			case C_RESOLVED :
+			case C_UNRESOLVED :
+				return appendClassTypeSignature(string, start, fullyQualifyTypeNames, buffer);
+			case C_TYPE_VARIABLE :
+				int e = Util.scanTypeVariableSignature(string, start);
+				buffer.append(string, start + 1, e - start - 1);
+				return e;
+			case C_BOOLEAN :
+				buffer.append(BOOLEAN);
+				return start;
+			case C_BYTE :
+				buffer.append(BYTE);
+				return start;
+			case C_CHAR :
+				buffer.append(CHAR);
+				return start;
+			case C_DOUBLE :
+				buffer.append(DOUBLE);
+				return start;
+			case C_FLOAT :
+				buffer.append(FLOAT);
+				return start;
+			case C_INT :
+				buffer.append(INT);
+				return start;
+			case C_LONG :
+				buffer.append(LONG);
+				return start;
+			case C_SHORT :
+				buffer.append(SHORT);
+				return start;
+			case C_VOID :
+				buffer.append(VOID);
+				return start;
+			case C_CAPTURE :
+				return appendCaptureTypeSignature(string, start, fullyQualifyTypeNames, buffer);
+			case C_INTERSECTION :
+				return appendIntersectionTypeSignature(string, start, fullyQualifyTypeNames, buffer);
+			case C_STAR:
+			case C_EXTENDS:
+			case C_SUPER:
+				return appendTypeArgumentSignature(string, start, fullyQualifyTypeNames, buffer);
+			default :
+				throw new IllegalArgumentException();
+		}
+	}
+}
+
+private static int checkArrayDimension(char[] typeName, int pos, int length) {
+    int genericBalance = 0;
+    while (pos < length) {
+		switch(typeName[pos]) {
+		    case '<' :
+		        genericBalance++;
+		        break;
+		    case ',' :
+			    if (genericBalance == 0) return -1;
+			    break;
+			case '>':
+			    if (genericBalance == 0) return -1;
+			    genericBalance--;
+		        break;
+			case '[':
+			    if (genericBalance == 0) {
+			        return pos;
+			    }
+		}
+		pos++;
+    }
+    return -1;
+}
+private static int checkName(char[] name, char[] typeName, int pos, int length) {
+    if (CharOperation.fragmentEquals(name, typeName, pos, true)) {
+        pos += name.length;
+        if (pos == length) return pos;
+        char currentChar = typeName[pos];
+        switch (currentChar) {
+            case ' ' :
+            case '.' :
+            case '<' :
+            case '>' :
+            case '[' :
+            case ',' :
+                return pos;
+			default:
+			    if (ScannerHelper.isWhitespace(currentChar))
+			    	return pos;
+
+        }
+    }
+    return -1;
+}
+private static int checkNextChar(char[] typeName, char expectedChar, int pos, int length, boolean isOptional) {
+    pos = consumeWhitespace(typeName, pos, length);
+    if (pos < length && typeName[pos] == expectedChar)
+        return pos + 1;
+    if (!isOptional) throw new IllegalArgumentException(new String(typeName));
+    return -1;
+}
+
+private static int consumeWhitespace(char[] typeName, int pos, int length) {
+    while (pos < length) {
+        char currentChar = typeName[pos];
+        if (currentChar != ' ' && !ScannerHelper.isWhitespace(currentChar)) {
+            break;
+        }
+        pos++;
+    }
+    return pos;
+}
+/**
+ * Creates a new type signature with the given amount of array nesting added
+ * to the given type signature.
+ *
+ * @param typeSignature the type signature
+ * @param arrayCount the desired number of levels of array nesting
+ * @return the encoded array type signature
+ *
+ * @since 2.0
+ */
+public static char[] createArraySignature(char[] typeSignature, int arrayCount) {
+	if (arrayCount == 0) return typeSignature;
+	int sigLength = typeSignature.length;
+	char[] result = new char[arrayCount + sigLength];
+	for (int i = 0; i < arrayCount; i++) {
+		result[i] = C_ARRAY;
+	}
+	System.arraycopy(typeSignature, 0, result, arrayCount, sigLength);
+	return result;
+}
+/**
+ * Creates a new type signature with the given amount of array nesting added
+ * to the given type signature.
+ *
+ * @param typeSignature the type signature
+ * @param arrayCount the desired number of levels of array nesting
+ * @return the encoded array type signature
+ */
+public static String createArraySignature(String typeSignature, int arrayCount) {
+	return new String(createArraySignature(typeSignature.toCharArray(), arrayCount));
+}
+
+/**
+ * Creates a new type signature from the given type name encoded as a character
+ * array. The type name may contain primitive types or array types or parameterized types.
+ * This method is equivalent to
+ * <code>createTypeSignature(new String(typeName),isResolved).toCharArray()</code>,
+ * although more efficient for callers with character arrays rather than strings.
+ * If the type name is qualified, then it is expected to be dot-based.
+ *
+ * @param typeName the possibly qualified type name
+ * @param isResolved <code>true</code> if the type name is to be considered
+ *   resolved (for example, a type name from a binary class file), and
+ *   <code>false</code> if the type name is to be considered unresolved
+ *   (for example, a type name found in source code)
+ * @return the encoded type signature
+ * @see #createTypeSignature(java.lang.String,boolean)
+ *
+ * @since 2.0
+ */
+public static char[] createCharArrayTypeSignature(char[] typeName, boolean isResolved) {
+	if (typeName == null) throw new IllegalArgumentException("null"); //$NON-NLS-1$
+	int length = typeName.length;
+	if (length == 0) throw new IllegalArgumentException(new String(typeName));
+	StringBuffer buffer = new StringBuffer(5);
+	int pos = encodeTypeSignature(typeName, 0, isResolved, length, buffer);
+	pos = consumeWhitespace(typeName, pos, length);
+	if (pos < length) throw new IllegalArgumentException(new String(typeName));
+	char[] result = new char[length = buffer.length()];
+	buffer.getChars(0, length, result, 0);
+	return result;
+}
+
+/**
+ * Creates a new intersection type signature from the given type signatures.
+ * 
+ * <p>The encoded type signature is dot-based.</p>
+ *
+ * @param typeSignatures the given type signatures
+ * @return the encoded type signature
+ * @since 3.7.1
+ */
+public static String createIntersectionTypeSignature(char[][] typeSignatures) {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(Signature.C_INTERSECTION);
+	for (int i = 0, max = typeSignatures.length; i < max; i++) {
+		if (i > 0) {
+			buffer.append(Signature.C_COLON);
+		}
+		buffer.append(typeSignatures[i]);
+	}
+	return String.valueOf(buffer);
+}
+
+/**
+ * Creates a new intersection type signature from the given type signatures.
+ * 
+ * <p>The encoded type signature is dot-based.</p>
+ *
+ * @param typeSignatures the given type signatures
+ * @return the encoded type signature
+ * @since 3.7.1
+ */
+public static String createIntersectionTypeSignature(String[] typeSignatures) {
+	int typeSignaturesLenth = typeSignatures.length;
+	char[][] signatures = new char[typeSignaturesLenth][];
+	for (int i = 0; i < typeSignaturesLenth; i++) {
+		signatures[i] = typeSignatures[i].toCharArray();
+	}
+	return createIntersectionTypeSignature(signatures);
+}
+/**
+ * Creates a method signature from the given parameter and return type
+ * signatures. The encoded method signature is dot-based.
+ *
+ * @param parameterTypes the list of parameter type signatures
+ * @param returnType the return type signature
+ * @return the encoded method signature
+ *
+ * @since 2.0
+ */
+public static char[] createMethodSignature(char[][] parameterTypes, char[] returnType) {
+	int parameterTypesLength = parameterTypes.length;
+	int parameterLength = 0;
+	for (int i = 0; i < parameterTypesLength; i++) {
+		parameterLength += parameterTypes[i].length;
+
+	}
+	int returnTypeLength = returnType.length;
+	char[] result = new char[1 + parameterLength + 1 + returnTypeLength];
+	result[0] = C_PARAM_START;
+	int index = 1;
+	for (int i = 0; i < parameterTypesLength; i++) {
+		char[] parameterType = parameterTypes[i];
+		int length = parameterType.length;
+		System.arraycopy(parameterType, 0, result, index, length);
+		index += length;
+	}
+	result[index] = C_PARAM_END;
+	System.arraycopy(returnType, 0, result, index+1, returnTypeLength);
+	return result;
+}
+/**
+ * Creates a method signature from the given parameter and return type
+ * signatures. The encoded method signature is dot-based. This method
+ * is equivalent to
+ * <code>createMethodSignature(parameterTypes, returnType)</code>.
+ *
+ * @param parameterTypes the list of parameter type signatures
+ * @param returnType the return type signature
+ * @return the encoded method signature
+ * @see Signature#createMethodSignature(char[][], char[])
+ */
+public static String createMethodSignature(String[] parameterTypes, String returnType) {
+	int parameterTypesLenth = parameterTypes.length;
+	char[][] parameters = new char[parameterTypesLenth][];
+	for (int i = 0; i < parameterTypesLenth; i++) {
+		parameters[i] = parameterTypes[i].toCharArray();
+	}
+	return new String(createMethodSignature(parameters, returnType.toCharArray()));
+}
+/**
+ * Creates a new type parameter signature with the given name and bounds.
+ *
+ * @param typeParameterName the type parameter name
+ * @param boundSignatures the signatures of associated bounds or empty array if none
+ * @return the encoded type parameter signature
+ *
+ * @since 3.1
+ */
+public static char[] createTypeParameterSignature(char[] typeParameterName, char[][] boundSignatures) {
+	int length = boundSignatures.length;
+	if (length == 0) {
+		return CharOperation.append(typeParameterName, C_COLON); // param signature with no bounds still gets trailing colon
+	}
+	int boundsSize = 0;
+	for (int i = 0; i < length; i++) {
+		boundsSize += boundSignatures[i].length + 1;
+	}
+	int nameLength = typeParameterName.length;
+	char[] result = new char[nameLength + boundsSize];
+	System.arraycopy(typeParameterName, 0, result, 0, nameLength);
+	int index = nameLength;
+	for (int i = 0; i < length; i++) {
+		result[index++] = C_COLON;
+		int boundLength = boundSignatures[i].length;
+		System.arraycopy(boundSignatures[i], 0, result, index, boundLength);
+		index += boundLength;
+	}
+	return result;
+}
+/**
+ * Creates a new type parameter signature with the given name and bounds.
+ *
+ * @param typeParameterName the type parameter name
+ * @param boundSignatures the signatures of associated bounds or empty array if none
+ * @return the encoded type parameter signature
+ *
+ * @since 3.1
+ */
+public static String createTypeParameterSignature(String typeParameterName, String[] boundSignatures) {
+	int length = boundSignatures.length;
+	char[][] boundSignatureChars = new char[length][];
+	for (int i = 0; i < length; i++) {
+		boundSignatureChars[i] = boundSignatures[i].toCharArray();
+	}
+	return new String(createTypeParameterSignature(typeParameterName.toCharArray(), boundSignatureChars));
+}
+
+/**
+ * Creates a new type signature from the given type name encoded as a character
+ * array. The type name may contain primitive types, array types or parameterized types.
+ * This method is equivalent to
+ * <code>createTypeSignature(new String(typeName),isResolved)</code>, although
+ * more efficient for callers with character arrays rather than strings. If the
+ * type name is qualified, then it is expected to be dot-based.
+ *
+ * @param typeName the possibly qualified type name
+ * @param isResolved <code>true</code> if the type name is to be considered
+ *   resolved (for example, a type name from a binary class file), and
+ *   <code>false</code> if the type name is to be considered unresolved
+ *   (for example, a type name found in source code)
+ * @return the encoded type signature
+ * @see #createTypeSignature(java.lang.String,boolean)
+ */
+public static String createTypeSignature(char[] typeName, boolean isResolved) {
+	return new String(createCharArrayTypeSignature(typeName, isResolved));
+}
+
+/**
+ * Creates a new type signature from the given type name. If the type name is qualified,
+ * then it is expected to be dot-based. The type name may contain primitive
+ * types or array types. However, parameterized types are not supported.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * createTypeSignature("int", hucairz) -> "I"
+ * createTypeSignature("java.lang.String", true) -> "Ljava.lang.String;"
+ * createTypeSignature("String", false) -> "QString;"
+ * createTypeSignature("java.lang.String", false) -> "Qjava.lang.String;"
+ * createTypeSignature("int []", false) -> "[I"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeName the possibly qualified type name
+ * @param isResolved <code>true</code> if the type name is to be considered
+ *   resolved (for example, a type name from a binary class file), and
+ *   <code>false</code> if the type name is to be considered unresolved
+ *   (for example, a type name found in source code)
+ * @return the encoded type signature
+ */
+public static String createTypeSignature(String typeName, boolean isResolved) {
+	return createTypeSignature(typeName == null ? null : typeName.toCharArray(), isResolved);
+}
+
+private static int encodeArrayDimension(char[] typeName, int pos, int length, StringBuffer buffer) {
+    int checkPos;
+    while (pos < length && (checkPos = checkNextChar(typeName, '[', pos, length, true)) > 0) {
+        pos = checkNextChar(typeName, ']', checkPos, length, false);
+        buffer.append(C_ARRAY);
+    }
+    return pos;
+}
+
+private static int encodeQualifiedName(char[] typeName, int pos, int length, StringBuffer buffer) {
+    int count = 0;
+    char lastAppendedChar = 0;
+    nameLoop: while (pos < length) {
+	    char currentChar = typeName[pos];
+		switch (currentChar) {
+		    case '<' :
+		    case '>' :
+		    case '[' :
+		    case ',' :
+		        break nameLoop;
+			case '.' :
+			    buffer.append(C_DOT);
+				lastAppendedChar = C_DOT;
+			    count++;
+			    break;
+			default:
+			    if (currentChar == ' ' || ScannerHelper.isWhitespace(currentChar)) {
+			        if (lastAppendedChar == C_DOT) { // allow spaces after a dot
+			            pos = consumeWhitespace(typeName, pos, length) - 1; // will be incremented
+			            break;
+			        }
+			        // allow spaces before a dot
+				    int checkPos = checkNextChar(typeName, '.', pos, length, true);
+				    if (checkPos > 0) {
+				        buffer.append(C_DOT);			// process dot immediately to avoid one iteration
+				        lastAppendedChar = C_DOT;
+				        count++;
+				        pos = checkPos;
+				        break;
+				    }
+				    break nameLoop;
+			    }
+			    buffer.append(currentChar);
+			    lastAppendedChar = currentChar;
+				count++;
+			    break;
+		}
+	    pos++;
+    }
+    if (count == 0) throw new IllegalArgumentException(new String(typeName));
+	return pos;
+}
+
+private static int encodeTypeSignature(char[] typeName, int start, boolean isResolved, int length, StringBuffer buffer) {
+    int pos = start;
+    pos = consumeWhitespace(typeName, pos, length);
+    if (pos >= length) throw new IllegalArgumentException(new String(typeName));
+    int checkPos;
+    char currentChar = typeName[pos];
+    switch (currentChar) {
+		// primitive type?
+		case 'b' :
+		    checkPos = checkName(BOOLEAN, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_BOOLEAN);
+			    return pos;
+			}
+		    checkPos = checkName(BYTE, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_BYTE);
+			    return pos;
+			}
+		    break;
+		case 'd':
+		    checkPos = checkName(DOUBLE, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_DOUBLE);
+			    return pos;
+			}
+		    break;
+		case 'f':
+		    checkPos = checkName(FLOAT, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_FLOAT);
+			    return pos;
+			}
+		    break;
+		case 'i':
+		    checkPos = checkName(INT, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_INT);
+			    return pos;
+			}
+		    break;
+		case 'l':
+		    checkPos = checkName(LONG, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_LONG);
+			    return pos;
+			}
+		    break;
+		case 's':
+		    checkPos = checkName(SHORT, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_SHORT);
+			    return pos;
+			}
+		    break;
+		case 'v':
+		    checkPos = checkName(VOID, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_VOID);
+			    return pos;
+			}
+		    break;
+		case 'c':
+		    checkPos = checkName(CHAR, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_CHAR);
+			    return pos;
+			} else {
+				checkPos = checkName(CAPTURE, typeName, pos, length);
+				if (checkPos > 0) {
+					pos = consumeWhitespace(typeName, checkPos, length);
+					if (typeName[pos] != '?') {
+						break;
+					}
+				} else {
+					break;
+				}
+			}
+			buffer.append(C_CAPTURE);
+			//$FALL-THROUGH$ for wildcard part of capture typecheckPos
+		case '?':
+			// wildcard
+			pos = consumeWhitespace(typeName, pos+1, length);
+			checkPos = checkName(EXTENDS, typeName, pos, length);
+			if (checkPos > 0) {
+				buffer.append(C_EXTENDS);
+				pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+				return pos;
+			}
+			checkPos = checkName(SUPER, typeName, pos, length);
+			if (checkPos > 0) {
+				buffer.append(C_SUPER);
+				pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+				return pos;
+			}
+			buffer.append(C_STAR);
+			return pos;
+    }
+    // non primitive type
+    checkPos = checkArrayDimension(typeName, pos, length);
+	int end;
+	if (checkPos > 0) {
+	    end = encodeArrayDimension(typeName, checkPos, length, buffer);
+	} else {
+	    end = -1;
+	}
+	buffer.append(isResolved ? C_RESOLVED : C_UNRESOLVED);
+	while (true) { // loop on qualifiedName[<args>][.qualifiedName[<args>]*
+	    pos = encodeQualifiedName(typeName, pos, length, buffer);
+		checkPos = checkNextChar(typeName, '<', pos, length, true);
+		if (checkPos > 0) {
+			buffer.append(C_GENERIC_START);
+			// Stop gap fix for <>.
+			if ((pos = checkNextChar(typeName, '>', checkPos, length, true)) > 0) {
+				buffer.append(C_GENERIC_END);
+			} else {
+				pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+				while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) {
+					pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+				}
+				pos = checkNextChar(typeName, '>', pos, length, false);
+				buffer.append(C_GENERIC_END);
+			}
+		}
+		checkPos = checkNextChar(typeName, '.', pos, length, true);
+		if (checkPos > 0) {
+			buffer.append(C_DOT);
+			pos = checkPos;
+		} else {
+			break;
+		}
+	}
+	buffer.append(C_NAME_END);
+	if (end > 0) pos = end; // skip array dimension which were preprocessed
+    return pos;
+}
+
+/**
+ * Returns the array count (array nesting depth) of the given type signature.
+ *
+ * @param typeSignature the type signature
+ * @return the array nesting depth, or 0 if not an array
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ *
+ * @since 2.0
+ */
+public static int getArrayCount(char[] typeSignature) throws IllegalArgumentException {
+	try {
+		int count = 0;
+		while (typeSignature[count] == C_ARRAY) {
+			++count;
+		}
+		return count;
+	} catch (ArrayIndexOutOfBoundsException e) { // signature is syntactically incorrect if last character is C_ARRAY
+		throw new IllegalArgumentException();
+	}
+}
+
+/**
+ * Returns the array count (array nesting depth) of the given type signature.
+ *
+ * @param typeSignature the type signature
+ * @return the array nesting depth, or 0 if not an array
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ */
+public static int getArrayCount(String typeSignature) throws IllegalArgumentException {
+	return getArrayCount(typeSignature.toCharArray());
+}
+
+/**
+ * Returns the type signature without any array nesting.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getElementType({'[', '[', 'I'}) --> {'I'}.
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the type signature without arrays
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ *
+ * @since 2.0
+ */
+public static char[] getElementType(char[] typeSignature) throws IllegalArgumentException {
+	int count = getArrayCount(typeSignature);
+	if (count == 0) return typeSignature;
+	int length = typeSignature.length;
+	char[] result = new char[length-count];
+	System.arraycopy(typeSignature, count, result, 0, length-count);
+	return result;
+}
+
+/**
+ * Returns the type signature without any array nesting.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getElementType("[[I") --> "I".
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the type signature without arrays
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ */
+public static String getElementType(String typeSignature) throws IllegalArgumentException {
+	char[] signature = typeSignature.toCharArray();
+	char[] elementType = getElementType(signature);
+	return signature == elementType ? typeSignature : new String(elementType);
+}
+/**
+ * Extracts the type bounds' signatures from the given intersection type signature.
+ * Returns an empty array if the type signature is not an intersection type signature.
+ *
+ * @param intersectionTypeSignature the intersection type signature
+ * @return the signatures of the type bounds
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 3.7.1
+ */
+public static char[][] getIntersectionTypeBounds(char[] intersectionTypeSignature) throws IllegalArgumentException {
+	if (getTypeSignatureKind(intersectionTypeSignature) != INTERSECTION_TYPE_SIGNATURE) {
+		return CharOperation.NO_CHAR_CHAR;
+	}
+	ArrayList args = new ArrayList();
+	int i = 1; // skip the '|'
+	int length = intersectionTypeSignature.length;
+	for (;;) {
+		int e = Util.scanClassTypeSignature(intersectionTypeSignature, i);
+		if (e < 0) {
+			throw new IllegalArgumentException("Invalid format"); //$NON-NLS-1$
+		}
+		args.add(CharOperation.subarray(intersectionTypeSignature, i, e + 1));
+		if (e == length - 1) {
+			int size = args.size();
+			char[][] result = new char[size][];
+			args.toArray(result);
+			return result;
+		} else if (intersectionTypeSignature[e + 1] != C_COLON) {
+			throw new IllegalArgumentException("Invalid format"); //$NON-NLS-1$
+		}
+		i = e + 2; // add one to skip C_COLON
+	}
+}
+/**
+ * Extracts the type bounds' signatures from the given intersection type signature.
+ * Returns an empty array if the type signature is not an intersection type signature.
+ *
+ * @param intersectionTypeSignature the intersection type signature
+ * @return the signatures of the type bounds
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 3.7.1
+ */
+public static String[] getIntersectionTypeBounds(String intersectionTypeSignature) throws IllegalArgumentException {
+	char[][] args = getIntersectionTypeBounds(intersectionTypeSignature.toCharArray());
+	return CharOperation.toStrings(args);
+}
+/**
+ * Returns the number of parameter types in the given method signature.
+ *
+ * @param methodSignature the method signature
+ * @return the number of parameters
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ * @since 2.0
+ */
+public static int getParameterCount(char[] methodSignature) throws IllegalArgumentException {
+	try {
+		int count = 0;
+		int i = CharOperation.indexOf(C_PARAM_START, methodSignature);
+		if (i < 0) {
+			throw new IllegalArgumentException();
+		} else {
+			i++;
+		}
+		for (;;) {
+			if (methodSignature[i] == C_PARAM_END) {
+				return count;
+			}
+			int e= Util.scanTypeSignature(methodSignature, i);
+			if (e < 0) {
+				throw new IllegalArgumentException();
+			} else {
+				i = e + 1;
+			}
+			count++;
+		}
+	} catch (ArrayIndexOutOfBoundsException e) {
+		throw new IllegalArgumentException();
+	}
+}
+
+/**
+ * Returns the number of parameter types in the given method signature.
+ *
+ * @param methodSignature the method signature
+ * @return the number of parameters
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ */
+public static int getParameterCount(String methodSignature) throws IllegalArgumentException {
+	return getParameterCount(methodSignature.toCharArray());
+}
+
+/**
+ * Extracts the parameter type signatures from the given method signature.
+ * The method signature is expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the list of parameter type signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 2.0
+ */
+public static char[][] getParameterTypes(char[] methodSignature) throws IllegalArgumentException {
+	try {
+		int count = getParameterCount(methodSignature);
+		char[][] result = new char[count][];
+		if (count == 0) {
+			return result;
+		}
+		int i = CharOperation.indexOf(C_PARAM_START, methodSignature);
+		if (i < 0) {
+			throw new IllegalArgumentException();
+		} else {
+			i++;
+		}
+		int t = 0;
+		for (;;) {
+			if (methodSignature[i] == C_PARAM_END) {
+				return result;
+			}
+			int e = Util.scanTypeSignature(methodSignature, i);
+			if (e < 0) {
+				throw new IllegalArgumentException();
+			}
+			result[t] = CharOperation.subarray(methodSignature, i, e + 1);
+			t++;
+			i = e + 1;
+		}
+	} catch (ArrayIndexOutOfBoundsException e) {
+		throw new IllegalArgumentException();
+	}
+}
+/**
+ * Extracts the parameter type signatures from the given method signature.
+ * The method signature is expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the list of parameter type signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ */
+public static String[] getParameterTypes(String methodSignature) throws IllegalArgumentException {
+	char[][] parameterTypes = getParameterTypes(methodSignature.toCharArray());
+	return CharOperation.toStrings(parameterTypes);
+}
+
+/**
+ * Returns a char array containing all but the last segment of the given
+ * dot-separated qualified name. Returns the empty char array if it is not qualified.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getQualifier({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g'}
+ * getQualifier({'O', 'u', 't', 'e', 'r', '.', 'I', 'n', 'n', 'e', 'r'}) -> {'O', 'u', 't', 'e', 'r'}
+ * getQualifier({'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'L', 'i', 's', 't', '<', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', '>'}) -> {'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l'}
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param name the name
+ * @return the qualifier prefix, or the empty char array if the name contains no
+ *   dots
+ * @exception NullPointerException if name is null
+ * @since 2.0
+ */
+public static char[] getQualifier(char[] name) {
+	int firstGenericStart = CharOperation.indexOf(C_GENERIC_START, name);
+	int lastDot = CharOperation.lastIndexOf(C_DOT, name, 0, firstGenericStart == -1 ? name.length-1 : firstGenericStart);
+	if (lastDot == -1) {
+		return CharOperation.NO_CHAR;
+	}
+	return CharOperation.subarray(name, 0, lastDot);
+}
+
+/**
+ * Returns a string containing all but the last segment of the given
+ * dot-separated qualified name. Returns the empty string if it is not qualified.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getQualifier("java.lang.Object") -&gt; "java.lang"
+ * getQualifier("Outer.Inner") -&gt; "Outer"
+ * getQualifier("java.util.List&lt;java.lang.String&gt;") -&gt; "java.util"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param name the name
+ * @return the qualifier prefix, or the empty string if the name contains no
+ *   dots
+ * @exception NullPointerException if name is null
+ */
+public static String getQualifier(String name) {
+	char[] qualifier = getQualifier(name.toCharArray());
+	if (qualifier.length == 0) return org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING;
+	return new String(qualifier);
+}
+
+/**
+ * Extracts the return type from the given method signature. The method signature is
+ * expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the type signature of the return type
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 2.0
+ */
+public static char[] getReturnType(char[] methodSignature) throws IllegalArgumentException {
+	// skip type parameters
+	int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature);
+	if (paren == -1) {
+		throw new IllegalArgumentException();
+	}
+	// there could be thrown exceptions behind, thus scan one type exactly
+	int last = Util.scanTypeSignature(methodSignature, paren+1);
+	return CharOperation.subarray(methodSignature, paren + 1, last+1);
+}
+
+/**
+ * Extracts the return type from the given method signature. The method signature is
+ * expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the type signature of the return type
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ */
+public static String getReturnType(String methodSignature) throws IllegalArgumentException {
+	return new String(getReturnType(methodSignature.toCharArray()));
+}
+
+/**
+ * Returns package fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSignatureQualifier({'L', 'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'M', 'a', 'p', '$', 'E', 'n', 't', 'r', 'y', ';'}) -> {'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l'}
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the package fragment (separators are '.')
+ * @since 3.1
+ */
+public static char[] getSignatureQualifier(char[] typeSignature) {
+	if(typeSignature == null) return CharOperation.NO_CHAR;
+
+	char[] qualifiedType = Signature.toCharArray(typeSignature);
+
+	int dotCount = 0;
+	indexFound: for(int i = 0; i < typeSignature.length; i++) {
+		switch(typeSignature[i]) {
+			case C_DOT:
+				dotCount++;
+				break;
+			case C_GENERIC_START:
+				break indexFound;
+			case C_DOLLAR:
+				break indexFound;
+		}
+	}
+
+	if(dotCount > 0) {
+		for(int i = 0; i < qualifiedType.length; i++) {
+			if(qualifiedType[i] == '.') {
+				dotCount--;
+			}
+			if(dotCount <= 0) {
+				return CharOperation.subarray(qualifiedType, 0, i);
+			}
+		}
+	}
+	return CharOperation.NO_CHAR;
+}
+/**
+ * Returns package fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSignatureQualifier("Ljava.util.Map$Entry") -> "java.util"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the package fragment (separators are '.')
+ * @since 3.1
+ */
+public static String getSignatureQualifier(String typeSignature) {
+	return new String(getSignatureQualifier(typeSignature == null ? null : typeSignature.toCharArray()));
+}
+/**
+ * Returns type fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSignatureSimpleName({'L', 'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'M', 'a', 'p', '$', 'E', 'n', 't', 'r', 'y', ';'}) -> {'M', 'a', 'p', '.', 'E', 'n', 't', 'r', 'y'}
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the type fragment (separators are '.')
+ * @since 3.1
+ */
+public static char[] getSignatureSimpleName(char[] typeSignature) {
+	if(typeSignature == null) return CharOperation.NO_CHAR;
+
+	char[] qualifiedType = Signature.toCharArray(typeSignature);
+
+	int dotCount = 0;
+	indexFound: for(int i = 0; i < typeSignature.length; i++) {
+		switch(typeSignature[i]) {
+			case C_DOT:
+				dotCount++;
+				break;
+			case C_GENERIC_START:
+				break indexFound;
+			case C_DOLLAR:
+				break indexFound;
+		}
+	}
+
+	if(dotCount > 0) {
+		for(int i = 0; i < qualifiedType.length; i++) {
+			if(qualifiedType[i] == '.') {
+				dotCount--;
+			}
+			if(dotCount <= 0) {
+				return CharOperation.subarray(qualifiedType, i + 1, qualifiedType.length);
+			}
+		}
+	}
+	return qualifiedType;
+}
+/**
+ * Returns type fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSignatureSimpleName("Ljava.util.Map$Entry") -> "Map.Entry"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param typeSignature the type signature
+ * @return the type fragment (separators are '.')
+ * @since 3.1
+ */
+public static String getSignatureSimpleName(String typeSignature) {
+	return new String(getSignatureSimpleName(typeSignature == null ? null : typeSignature.toCharArray()));
+}
+/**
+ * Returns the last segment of the given dot-separated qualified name.
+ * Returns the given name if it is not qualified.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSimpleName({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'O', 'b', 'j', 'e', 'c', 't'}
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param name the name
+ * @return the last segment of the qualified name
+ * @exception NullPointerException if name is null
+ * @since 2.0
+ */
+public static char[] getSimpleName(char[] name) {
+
+	int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1;
+	int depth = 0;
+	int length = name.length;
+	lastDotLookup: for (int i = length -1; i >= 0; i--) {
+		switch (name[i]) {
+			case '.':
+				if (depth == 0) {
+					lastDot = i;
+					break lastDotLookup;
+				}
+				break;
+			case '<':
+				depth--;
+				if (depth == 0) lastGenericStart = i;
+				break;
+			case '>':
+				if (depth == 0) lastGenericEnd = i;
+				depth++;
+				break;
+		}
+	}
+	if (lastGenericStart < 0) {
+		if (lastDot < 0) {
+			return name;
+		}
+		return  CharOperation.subarray(name, lastDot + 1, length);
+	}
+	StringBuffer buffer = new StringBuffer(10);
+	int nameStart = lastDot < 0 ? 0 : lastDot+1;
+	buffer.append(name, nameStart, lastGenericStart - nameStart);
+	appendArgumentSimpleNames(name, lastGenericStart, lastGenericEnd, buffer);
+	buffer.append(name, lastGenericEnd+1, length-lastGenericEnd-1); // copy trailing portion, may contain dimensions
+	char[] result = new char[length = buffer.length()];
+	buffer.getChars(0, length, result, 0);
+	return result;
+}
+/**
+ * Returns the last segment of the given dot-separated qualified name.
+ * Returns the given name if it is not qualified.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSimpleName("java.lang.Object") -&gt; "Object"
+ * </code>
+ * <code>
+ * getSimpleName("java.util.Map&lt;java.lang.String, java.lang.Object&gt;") -&gt; "Map&lt;String,Object&gt;"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param name the name
+ * @return the last segment of the qualified name
+ * @exception NullPointerException if name is null
+ */
+public static String getSimpleName(String name) {
+	int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1;
+	int depth = 0;
+	int length = name.length();
+	lastDotLookup: for (int i = length -1; i >= 0; i--) {
+		switch (name.charAt(i)) {
+			case '.':
+				if (depth == 0) {
+					lastDot = i;
+					break lastDotLookup;
+				}
+				break;
+			case '<':
+				depth--;
+				if (depth == 0) lastGenericStart = i;
+				break;
+			case '>':
+				if (depth == 0) lastGenericEnd = i;
+				depth++;
+				break;
+		}
+	}
+	if (lastGenericStart < 0) {
+		if (lastDot < 0) {
+			return name;
+		}
+		return name.substring(lastDot + 1, length);
+	}
+	StringBuffer buffer = new StringBuffer(10);
+	char[] nameChars = name.toCharArray();
+	int nameStart = lastDot < 0 ? 0 : lastDot+1;
+	buffer.append(nameChars, nameStart, lastGenericStart - nameStart);
+	appendArgumentSimpleNames(nameChars, lastGenericStart, lastGenericEnd, buffer);
+	buffer.append(nameChars, lastGenericEnd+1, length-lastGenericEnd-1); // copy trailing portion, may contain dimensions
+	return buffer.toString();
+}
+/**
+ * Returns all segments of the given dot-separated qualified name.
+ * Returns an array with only the given name if it is not qualified.
+ * Returns an empty array if the name is empty.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSimpleNames({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}
+ * getSimpleNames({'O', 'b', 'j', 'e', 'c', 't'}) -> {{'O', 'b', 'j', 'e', 'c', 't'}}
+ * getSimpleNames({}) -> {}
+ * getSimpleNames({'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'L', 'i', 's', 't', '<', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', '>'}) -> {{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'L', 'i', 's', 't', '<', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g'}}
+ * </code>
+ * </pre>
+ *
+ * @param name the name
+ * @return the list of simple names, possibly empty
+ * @exception NullPointerException if name is null
+ * @since 2.0
+ */
+public static char[][] getSimpleNames(char[] name) {
+	int length = name == null ? 0 : name.length;
+	if (length == 0)
+		return CharOperation.NO_CHAR_CHAR;
+
+	int wordCount = 1;
+	countingWords: for (int i = 0; i < length; i++)
+		switch(name[i]) {
+			case C_DOT:
+				wordCount++;
+				break;
+			case C_GENERIC_START:
+				break countingWords;
+		}
+	char[][] split = new char[wordCount][];
+	int last = 0, currentWord = 0;
+	for (int i = 0; i < length; i++) {
+		if (name[i] == C_GENERIC_START) break;
+		if (name[i] == C_DOT) {
+			split[currentWord] = new char[i - last];
+			System.arraycopy(
+				name,
+				last,
+				split[currentWord++],
+				0,
+				i - last);
+			last = i + 1;
+		}
+	}
+	split[currentWord] = new char[length - last];
+	System.arraycopy(name, last, split[currentWord], 0, length - last);
+	return split;
+}
+/**
+ * Returns all segments of the given dot-separated qualified name.
+ * Returns an array with only the given name if it is not qualified.
+ * Returns an empty array if the name is empty.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * getSimpleNames("java.lang.Object") -&gt; {"java", "lang", "Object"}
+ * getSimpleNames("Object") -&gt; {"Object"}
+ * getSimpleNames("") -&gt; {}
+ * getSimpleNames("java.util.List&lt;java.lang.String&gt;") -&gt;
+ *   {"java", "util", "List&lt;java.lang.String&gt;"}
+ * </code>
+ * </pre>
+ *
+ * @param name the name
+ * @return the list of simple names, possibly empty
+ * @exception NullPointerException if name is null
+ */
+public static String[] getSimpleNames(String name) {
+	return CharOperation.toStrings(getSimpleNames(name.toCharArray()));
+}
+
+/**
+ * Extracts the thrown exception type signatures from the given method signature if any
+ * The method signature is expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the list of thrown exception type signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static char[][] getThrownExceptionTypes(char[] methodSignature) throws IllegalArgumentException {
+	// skip type parameters
+	int exceptionStart = CharOperation.indexOf(C_EXCEPTION_START, methodSignature);
+	if (exceptionStart == -1) {
+		int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature);
+		if (paren == -1) {
+			throw new IllegalArgumentException();
+		}
+		// ignore return type
+		exceptionStart = Util.scanTypeSignature(methodSignature, paren+1) + 1;
+		int length = methodSignature.length;
+		if (exceptionStart == length) return CharOperation.NO_CHAR_CHAR;
+		throw new IllegalArgumentException();
+	}
+	int length = methodSignature.length;
+	int i = exceptionStart;
+	ArrayList exceptionList = new ArrayList(1);
+	while (i < length) {
+		if (methodSignature[i] == C_EXCEPTION_START) {
+			exceptionStart++;
+			i++;
+		} else {
+			throw new IllegalArgumentException();
+		}
+		i = Util.scanTypeSignature(methodSignature, i) + 1;
+		exceptionList.add(CharOperation.subarray(methodSignature, exceptionStart,i));
+		exceptionStart = i;
+	}
+	char[][] result;
+	exceptionList.toArray(result = new char[exceptionList.size()][]);
+	return result;
+}
+/**
+ * Extracts the thrown exception type signatures from the given method signature if any
+ * The method signature is expected to be dot-based.
+ *
+ * @param methodSignature the method signature
+ * @return the list of thrown exception type signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static String[] getThrownExceptionTypes(String methodSignature) throws IllegalArgumentException {
+	char[][] parameterTypes = getThrownExceptionTypes(methodSignature.toCharArray());
+	return CharOperation.toStrings(parameterTypes);
+}
+/**
+ * Extracts the type argument signatures from the given type signature.
+ * Returns an empty array if the type signature is not a parameterized type signature.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signatures of the type arguments
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 3.1
+ */
+public static char[][] getTypeArguments(char[] parameterizedTypeSignature) throws IllegalArgumentException {
+	int length = parameterizedTypeSignature.length;
+	if (length < 2 || parameterizedTypeSignature[length-2] != C_GENERIC_END)
+		// cannot have type arguments otherwise signature would end by ">;"
+		return CharOperation.NO_CHAR_CHAR;
+	int count = 1; // start to count generic end/start peers
+	int start = length - 2;
+	while (start >= 0 && count > 0) {
+		switch (parameterizedTypeSignature[--start]) {
+			case C_GENERIC_START:
+				count--;
+				break;
+			case C_GENERIC_END:
+				count++;
+				break;
+		}
+	}
+	if (start < 0) // invalid number of generic start/end
+		throw new IllegalArgumentException();
+	ArrayList args = new ArrayList();
+	int p = start + 1;
+	while (true) {
+		if (p >= parameterizedTypeSignature.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = parameterizedTypeSignature[p];
+		if (c == C_GENERIC_END) {
+			int size = args.size();
+			char[][] result = new char[size][];
+			args.toArray(result);
+			return result;
+		}
+		int e = Util.scanTypeArgumentSignature(parameterizedTypeSignature, p);
+		args.add(CharOperation.subarray(parameterizedTypeSignature, p, e+1));
+		p = e + 1;
+	}
+}
+/**
+ * Extracts the type argument signatures from the given type signature.
+ * Returns an empty array if the type signature is not a parameterized type signature.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signatures of the type arguments
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 3.1
+ */
+public static String[] getTypeArguments(String parameterizedTypeSignature) throws IllegalArgumentException {
+	char[][] args = getTypeArguments(parameterizedTypeSignature.toCharArray());
+	return CharOperation.toStrings(args);
+}
+/**
+ * Extracts the type erasure signature from the given parameterized type signature.
+ * Returns the given type signature if it is not parameterized.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signature of the type erasure
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static char[] getTypeErasure(char[] parameterizedTypeSignature) throws IllegalArgumentException {
+	int end = CharOperation.indexOf(C_GENERIC_START, parameterizedTypeSignature);
+	if (end == -1) return parameterizedTypeSignature;
+	int length = parameterizedTypeSignature.length;
+	char[] result = new char[length];
+	int pos = 0;
+	int start = 0;
+	int deep= 0;
+	for (int idx=end; idx<length; idx++) {
+		switch (parameterizedTypeSignature[idx]) {
+			case C_GENERIC_START:
+				if (deep == 0) {
+					int size = idx-start;
+					System.arraycopy(parameterizedTypeSignature, start, result, pos, size);
+					end = idx;
+					pos += size;
+				}
+				deep++;
+				break;
+			case C_GENERIC_END:
+				deep--;
+				if (deep < 0) throw new IllegalArgumentException();
+				if (deep == 0) start = idx+1;
+				break;
+		}
+	}
+	if (deep > 0) throw new IllegalArgumentException();
+	int size = pos+length-start;
+	char[] resized = new char[size];
+	System.arraycopy(result, 0, resized, 0, pos);
+	System.arraycopy(parameterizedTypeSignature, start, resized, pos, length-start);
+	return resized;
+}
+/**
+ * Extracts the type erasure signature from the given parameterized type signature.
+ * Returns the given type signature if it is not parameterized.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signature of the type erasure
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static String getTypeErasure(String parameterizedTypeSignature) throws IllegalArgumentException {
+	char[] signature = parameterizedTypeSignature.toCharArray();
+	char[] erasure = getTypeErasure(signature);
+	return signature == erasure ? parameterizedTypeSignature : new String(erasure);
+}
+
+/**
+ * Extracts the class and interface bounds from the given formal type
+ * parameter signature. The class bound, if present, is listed before
+ * the interface bounds. The signature is expected to be dot-based.
+ *
+ * @param formalTypeParameterSignature the formal type parameter signature
+ * @return the (possibly empty) list of type signatures for the bounds
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ * @since 3.0
+ */
+public static char[][] getTypeParameterBounds(char[] formalTypeParameterSignature) throws IllegalArgumentException {
+	int p1 = CharOperation.indexOf(C_COLON, formalTypeParameterSignature);
+	if (p1 < 0) {
+		// no ":" means can't be a formal type parameter signature
+		throw new IllegalArgumentException();
+	}
+	if (p1 == formalTypeParameterSignature.length - 1) {
+		// no class or interface bounds
+		return CharOperation.NO_CHAR_CHAR;
+	}
+	int p2 = CharOperation.indexOf(C_COLON, formalTypeParameterSignature, p1 + 1);
+	char[] classBound;
+	if (p2 < 0) {
+		// no interface bounds
+		classBound = CharOperation.subarray(formalTypeParameterSignature, p1 + 1, formalTypeParameterSignature.length);
+		return new char[][] {classBound};
+	}
+	if (p2 == p1 + 1) {
+		// no class bound, but 1 or more interface bounds
+		classBound = null;
+	} else {
+		classBound = CharOperation.subarray(formalTypeParameterSignature, p1 + 1, p2);
+	}
+	char[][] interfaceBounds = CharOperation.splitOn(C_COLON, formalTypeParameterSignature, p2 + 1, formalTypeParameterSignature.length);
+	if (classBound == null) {
+		return interfaceBounds;
+	}
+	int resultLength = interfaceBounds.length + 1;
+	char[][] result = new char[resultLength][];
+	result[0] = classBound;
+	System.arraycopy(interfaceBounds, 0, result, 1, interfaceBounds.length);
+	return result;
+}
+
+/**
+ * Extracts the class and interface bounds from the given formal type
+ * parameter signature. The class bound, if present, is listed before
+ * the interface bounds. The signature is expected to be dot-based.
+ *
+ * @param formalTypeParameterSignature the formal type parameter signature
+ * @return the (possibly empty) list of type signatures for the bounds
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ * @since 3.0
+ */
+public static String[] getTypeParameterBounds(String formalTypeParameterSignature) throws IllegalArgumentException {
+	char[][] bounds = getTypeParameterBounds(formalTypeParameterSignature.toCharArray());
+	return CharOperation.toStrings(bounds);
+}
+
+/**
+ * Extracts the type parameter signatures from the given method or type signature.
+ * The method or type signature is expected to be dot-based.
+ *
+ * @param methodOrTypeSignature the method or type signature
+ * @return the list of type parameter signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static char[][] getTypeParameters(char[] methodOrTypeSignature) throws IllegalArgumentException {
+	try {
+		int length = methodOrTypeSignature.length;
+		if (length == 0) return CharOperation.NO_CHAR_CHAR;
+		if (methodOrTypeSignature[0] != C_GENERIC_START) return CharOperation.NO_CHAR_CHAR;
+
+		ArrayList paramList = new ArrayList(1);
+		int paramStart = 1, i = 1;  // start after leading '<'
+		while (i < length) {
+			if (methodOrTypeSignature[i] == C_GENERIC_END) {
+				int size = paramList.size();
+				if (size == 0) throw new IllegalArgumentException();
+				char[][] result;
+				paramList.toArray(result = new char[size][]);
+				return result;
+			}
+			i = CharOperation.indexOf(C_COLON, methodOrTypeSignature, i);
+			if (i < 0 || i >= length)
+				throw new IllegalArgumentException();
+			// iterate over bounds
+			while (methodOrTypeSignature[i] == ':') {
+				i++; // skip colon
+				switch (methodOrTypeSignature[i]) {
+					case ':':
+						// no class bound
+						break;
+					case C_GENERIC_END:
+						break;
+					case C_RESOLVED:
+						try {
+							i = Util.scanClassTypeSignature(methodOrTypeSignature, i);
+							i++; // position at start of next param if any
+						} catch (IllegalArgumentException e) {
+							// not a class type signature -> it is a new type parameter
+						}
+						break;
+					case C_ARRAY:
+						try {
+							i = Util.scanArrayTypeSignature(methodOrTypeSignature, i);
+							i++; // position at start of next param if any
+						} catch (IllegalArgumentException e) {
+							// not an array type signature -> it is a new type parameter
+						}
+						break;
+					case C_TYPE_VARIABLE:
+						try {
+							i = Util.scanTypeVariableSignature(methodOrTypeSignature, i);
+							i++; // position at start of next param if any
+						} catch (IllegalArgumentException e) {
+							// not a type variable signature -> it is a new type parameter
+						}
+						break;
+					// default: another type parameter is starting
+				}
+			}
+			paramList.add(CharOperation.subarray(methodOrTypeSignature, paramStart, i));
+			paramStart = i; // next param start from here
+		}
+	} catch (ArrayIndexOutOfBoundsException e) {
+		// invalid signature, fall through
+	}
+	throw new IllegalArgumentException();
+}
+/**
+ * Extracts the type parameter signatures from the given method or type signature.
+ * The method or type signature is expected to be dot-based.
+ *
+ * @param methodOrTypeSignature the method or type signature
+ * @return the list of type parameter signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ *
+ * @since 3.1
+ */
+public static String[] getTypeParameters(String methodOrTypeSignature) throws IllegalArgumentException {
+	char[][] params = getTypeParameters(methodOrTypeSignature.toCharArray());
+	return CharOperation.toStrings(params);
+}
+/**
+ * Returns the kind of type signature encoded by the given string.
+ *
+ * @param typeSignature the type signature string
+ * @return the kind of type signature; one of the kind constants:
+ * {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE},
+ * or (since 3.7) {@link #INTERSECTION_TYPE_SIGNATURE}
+ * @exception IllegalArgumentException if this is not a type signature
+ * @since 3.0
+ */
+public static int getTypeSignatureKind(char[] typeSignature) {
+	// need a minimum 1 char
+	if (typeSignature.length < 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = typeSignature[0];
+	if (c == C_GENERIC_START) {
+		int count = 1;
+		for (int i = 1, length = typeSignature.length; i < length; i++) {
+			switch (typeSignature[i]) {
+				case 	C_GENERIC_START:
+					count++;
+					break;
+				case C_GENERIC_END:
+					count--;
+					break;
+			}
+			if (count == 0) {
+				if (i+1 < length)
+					c = typeSignature[i+1];
+				break;
+			}
+		}
+	}
+	switch (c) {
+		case C_ARRAY :
+			return ARRAY_TYPE_SIGNATURE;
+		case C_RESOLVED :
+		case C_UNRESOLVED :
+			return CLASS_TYPE_SIGNATURE;
+		case C_TYPE_VARIABLE :
+			return TYPE_VARIABLE_SIGNATURE;
+		case C_BOOLEAN :
+		case C_BYTE :
+		case C_CHAR :
+		case C_DOUBLE :
+		case C_FLOAT :
+		case C_INT :
+		case C_LONG :
+		case C_SHORT :
+		case C_VOID :
+			return BASE_TYPE_SIGNATURE;
+		case C_STAR :
+		case C_SUPER :
+		case C_EXTENDS :
+			return WILDCARD_TYPE_SIGNATURE;
+		case C_CAPTURE :
+			return CAPTURE_TYPE_SIGNATURE;
+		case C_INTERSECTION :
+			return INTERSECTION_TYPE_SIGNATURE;
+		default :
+			throw new IllegalArgumentException();
+	}
+}
+
+/**
+ * Returns the kind of type signature encoded by the given string.
+ *
+ * @param typeSignature the type signature string
+ * @return the kind of type signature; one of the kind constants:
+ * {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE}
+ * or (since 3.7) {@link #INTERSECTION_TYPE_SIGNATURE}
+ * @exception IllegalArgumentException if this is not a type signature
+ * @since 3.0
+ */
+public static int getTypeSignatureKind(String typeSignature) {
+	return getTypeSignatureKind(typeSignature.toCharArray());
+}
+/**
+ * Extracts the type variable name from the given formal type parameter
+ * signature. The signature is expected to be dot-based.
+ *
+ * @param formalTypeParameterSignature the formal type parameter signature
+ * @return the name of the type variable
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ * @since 3.0
+ */
+public static char[] getTypeVariable(char[] formalTypeParameterSignature) throws IllegalArgumentException {
+	int p = CharOperation.indexOf(C_COLON, formalTypeParameterSignature);
+	if (p < 0) {
+		// no ":" means can't be a formal type parameter signature
+		throw new IllegalArgumentException();
+	}
+	return CharOperation.subarray(formalTypeParameterSignature, 0, p);
+}
+/**
+ * Extracts the type variable name from the given formal type parameter
+ * signature. The signature is expected to be dot-based.
+ *
+ * @param formalTypeParameterSignature the formal type parameter signature
+ * @return the name of the type variable
+ * @exception IllegalArgumentException if the signature is syntactically
+ *   incorrect
+ * @since 3.0
+ */
+public static String getTypeVariable(String formalTypeParameterSignature) throws IllegalArgumentException {
+	return new String(getTypeVariable(formalTypeParameterSignature.toCharArray()));
+}
+/**
+ * Removes any capture information from the given type or method signature
+ * and returns the resulting signature.
+ * Returns the type or method signature itself if no capture information is
+ * present.
+ * <p>
+ * For example (using equivalent string-based method):
+ * <pre>
+ * <code>
+ * removeCapture("LTest&lt;!+Ljava.lang.Throwable;&gt;;")
+ * will return: "LTest&lt;+Ljava.lang.Throwable;&gt;;"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param methodOrTypeSignature the signature which may have been captured
+ * @return a new signature without capture information or the signature itself
+ * 	if no specific capture information is present
+ * @exception NullPointerException if <code>methodOrTypeSignature</code> is null
+ *
+ * @since 3.1
+ */
+public static char[] removeCapture(char[] methodOrTypeSignature) {
+	return CharOperation.remove(methodOrTypeSignature, C_CAPTURE);
+}
+/**
+ * Removes any capture information from the given type or method signature
+ * and returns the resulting signature.
+ * Returns the type or method signature itself if no capture information is
+ * present.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * removeCapture("LTest&lt;!+Ljava.lang.Throwable;&gt;;")
+ * will return: "LTest&lt;+Ljava.lang.Throwable;&gt;;"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param methodOrTypeSignature the signature which may have been captured
+ * @return a new signature without capture information or the signature itself
+ * 	if no specific capture information is present
+ * @exception NullPointerException if <code>methodOrTypeSignature</code> is null
+ *
+ * @since 3.1
+ */
+public static String removeCapture(String methodOrTypeSignature) {
+	char[] array = methodOrTypeSignature.toCharArray();
+	char[] result = removeCapture(array);
+	if (array == result) return methodOrTypeSignature;
+	return new String(result);
+}
+/**
+ * Converts the given type signature to a readable string. The signature is expected to
+ * be dot-based.
+ *
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toString({'[', 'L', 'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', ';'}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'S', 't', 'r', 'i', 'n', 'g', '[', ']'}
+ * toString({'I'}) -> {'i', 'n', 't'}
+ * toString({'+', 'L', 'O', 'b', 'j', 'e', 'c', 't', ';'}) -> {'?', ' ', 'e', 'x', 't', 'e', 'n', 'd', 's', ' ', 'O', 'b', 'j', 'e', 'c', 't'}
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * Note: This method assumes that a type signature containing a <code>'$'</code>
+ * is an inner type signature. While this is correct in most cases, someone could
+ * define a non-inner type name containing a <code>'$'</code>. Handling this
+ * correctly in all cases would have required resolving the signature, which
+ * generally not feasible.
+ * </p>
+ *
+ * @param signature the type signature
+ * @return the string representation of the type
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 2.0
+ */
+public static char[] toCharArray(char[] signature) throws IllegalArgumentException {
+		int sigLength = signature.length;
+		if (sigLength == 0) {
+			throw new IllegalArgumentException();
+		}
+		if (signature[0] == C_PARAM_START || signature[0] == C_GENERIC_START) {
+			return toCharArray(signature, CharOperation.NO_CHAR, null, true, true);
+		}
+
+		StringBuffer buffer = new StringBuffer(signature.length + 10);
+		appendTypeSignature(signature, 0, true, buffer);
+		char[] result = new char[buffer.length()];
+		buffer.getChars(0, buffer.length(), result, 0);
+		return result;
+}
+/**
+ * Converts the given method signature to a readable form. The method signature is expected to
+ * be dot-based.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param methodSignature the method signature to convert
+ * @param methodName the name of the method to insert in the result, or
+ *   <code>null</code> if no method name is to be included
+ * @param parameterNames the parameter names to insert in the result, or
+ *   <code>null</code> if no parameter names are to be included; if supplied,
+ *   the number of parameter names must match that of the method signature
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param includeReturnType <code>true</code> if the return type is to be
+ *   included
+ * @return the char array representation of the method signature
+ * @throws IllegalArgumentException if the method signature is syntactically incorrect
+ * @since 2.0
+ */
+public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) {
+	return toCharArray(methodSignature, methodName, parameterNames, fullyQualifyTypeNames, includeReturnType, false);
+}
+
+/**
+ * Converts the given method signature to a readable form. The method signature is expected to
+ * be dot-based.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toString("([Ljava.lang.String;)V", "main", new String[] {"args"}, false, true) -> "void main(String[] args)"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param methodSignature the method signature to convert
+ * @param methodName the name of the method to insert in the result, or
+ *   <code>null</code> if no method name is to be included
+ * @param parameterNames the parameter names to insert in the result, or
+ *   <code>null</code> if no parameter names are to be included; if supplied,
+ *   the number of parameter names must match that of the method signature
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param includeReturnType <code>true</code> if the return type is to be
+ *   included
+ * @param isVargArgs <code>true</code> if the last argument should be displayed as a
+ * variable argument,  <code>false</code> otherwise.
+ * @return the char array representation of the method signature
+ * @throws IllegalArgumentException if the method signature is syntactically incorrect
+ *
+ * @since 3.1
+ */
+public static char[] toCharArray(char[] methodSignature, char[] methodName, char[][] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType, boolean isVargArgs) {
+	int firstParen = CharOperation.indexOf(C_PARAM_START, methodSignature);
+	if (firstParen == -1) {
+		throw new IllegalArgumentException();
+	}
+
+	StringBuffer buffer = new StringBuffer(methodSignature.length + 10);
+
+	// return type
+	if (includeReturnType) {
+		char[] rts = getReturnType(methodSignature);
+		appendTypeSignature(rts, 0 , fullyQualifyTypeNames, buffer);
+		buffer.append(' ');
+	}
+
+	// selector
+	if (methodName != null) {
+		buffer.append(methodName);
+	}
+
+	// parameters
+	buffer.append('(');
+	char[][] pts = getParameterTypes(methodSignature);
+	// search for the last array in the signature
+	int max = pts.length;
+	int index = max - 1;
+	loop: for (int i = index; i >= 0; i--) {
+		if (pts[i][0] == Signature.C_ARRAY) {
+			break loop;
+		}
+		index--;
+	}
+	for (int i = 0; i < max; i++) {
+		if (i == index) {
+			appendTypeSignature(pts[i], 0 , fullyQualifyTypeNames, buffer, isVargArgs);
+		} else {
+			appendTypeSignature(pts[i], 0 , fullyQualifyTypeNames, buffer);
+		}
+		if (parameterNames != null) {
+			buffer.append(' ');
+			buffer.append(parameterNames[i]);
+		}
+		if (i != pts.length - 1) {
+			buffer.append(',');
+			buffer.append(' ');
+		}
+	}
+	buffer.append(')');
+	char[] result = new char[buffer.length()];
+	buffer.getChars(0, buffer.length(), result, 0);
+	return result;
+}
+
+/**
+ * Converts the given array of qualified name segments to a qualified name.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toQualifiedName({{'j', 'a', 'v', 'a'}, {'l', 'a', 'n', 'g'}, {'O', 'b', 'j', 'e', 'c', 't'}}) -> {'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}
+ * toQualifiedName({{'O', 'b', 'j', 'e', 'c', 't'}}) -> {'O', 'b', 'j', 'e', 'c', 't'}
+ * toQualifiedName({{}}) -> {}
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param segments the list of name segments, possibly empty
+ * @return the dot-separated qualified name, or the empty string
+ *
+ * @since 2.0
+ */
+public static char[] toQualifiedName(char[][] segments) {
+	int length = segments.length;
+	if (length == 0) return CharOperation.NO_CHAR;
+	if (length == 1) return segments[0];
+
+	int resultLength = 0;
+	for (int i = 0; i < length; i++) {
+		resultLength += segments[i].length+1;
+	}
+	resultLength--;
+	char[] result = new char[resultLength];
+	int index = 0;
+	for (int i = 0; i < length; i++) {
+		char[] segment = segments[i];
+		int segmentLength = segment.length;
+		System.arraycopy(segment, 0, result, index, segmentLength);
+		index += segmentLength;
+		if (i != length-1) {
+			result[index++] = C_DOT;
+		}
+	}
+	return result;
+}
+
+/**
+ * Converts the given array of qualified name segments to a qualified name.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toQualifiedName(new String[] {"java", "lang", "Object"}) -> "java.lang.Object"
+ * toQualifiedName(new String[] {"Object"}) -> "Object"
+ * toQualifiedName(new String[0]) -> ""
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param segments the list of name segments, possibly empty
+ * @return the dot-separated qualified name, or the empty string
+ */
+public static String toQualifiedName(String[] segments) {
+	int length = segments.length;
+	char[][] charArrays = new char[length][];
+	for (int i = 0; i < length; i++) {
+		charArrays[i] = segments[i].toCharArray();
+	}
+	return new String(toQualifiedName(charArrays));
+}
+/**
+ * Converts the given type signature to a readable string. The signature is expected to
+ * be dot-based.
+ *
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * toString("[Ljava.lang.String;") -> "java.lang.String[]"
+ * toString("I") -> "int"
+ * toString("+QObject;") -> "? extends Object"
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * Note: This method assumes that a type signature containing a <code>'$'</code>
+ * is an inner type signature. While this is correct in most cases, someone could
+ * define a non-inner type name containing a <code>'$'</code>. Handling this
+ * correctly in all cases would have required resolving the signature, which
+ * generally not feasible.
+ * </p>
+ *
+ * @param signature the type signature
+ * @return the string representation of the type
+ * @exception IllegalArgumentException if the signature is not syntactically
+ *   correct
+ */
+public static String toString(String signature) throws IllegalArgumentException {
+	return new String(toCharArray(signature.toCharArray()));
+}
+/**
+ * Converts the given method signature to a readable string. The method signature is expected to
+ * be dot-based.
+ *
+ * @param methodSignature the method signature to convert
+ * @param methodName the name of the method to insert in the result, or
+ *   <code>null</code> if no method name is to be included
+ * @param parameterNames the parameter names to insert in the result, or
+ *   <code>null</code> if no parameter names are to be included; if supplied,
+ *   the number of parameter names must match that of the method signature
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param includeReturnType <code>true</code> if the return type is to be
+ *   included
+ * @see #toCharArray(char[], char[], char[][], boolean, boolean)
+ * @return the string representation of the method signature
+ */
+public static String toString(String methodSignature, String methodName, String[] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType) {
+	return toString(methodSignature, methodName, parameterNames, fullyQualifyTypeNames, includeReturnType, false);
+}
+/**
+ * Converts the given method signature to a readable string. The method signature is expected to
+ * be dot-based.
+ *
+ * @param methodSignature the method signature to convert
+ * @param methodName the name of the method to insert in the result, or
+ *   <code>null</code> if no method name is to be included
+ * @param parameterNames the parameter names to insert in the result, or
+ *   <code>null</code> if no parameter names are to be included; if supplied,
+ *   the number of parameter names must match that of the method signature
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
+ * @param includeReturnType <code>true</code> if the return type is to be
+ *   included
+ * @param isVarArgs <code>true</code> if the last argument should be displayed as a
+ * variable argument, <code>false</code> otherwise
+ * @see #toCharArray(char[], char[], char[][], boolean, boolean)
+ * @return the string representation of the method signature
+ *
+ * @since 3.1
+ */
+public static String toString(String methodSignature, String methodName, String[] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType, boolean isVarArgs) {
+	char[][] params;
+	if (parameterNames == null) {
+		params = null;
+	} else {
+		int paramLength = parameterNames.length;
+		params = new char[paramLength][];
+		for (int i = 0; i < paramLength; i++) {
+			params[i] = parameterNames[i].toCharArray();
+		}
+	}
+	return new String(toCharArray(methodSignature.toCharArray(), methodName == null ? null : methodName.toCharArray(), params, fullyQualifyTypeNames, includeReturnType, isVarArgs));
+}
+private Signature() {
+	// Not instantiable
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/SourceRange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/SourceRange.java
new file mode 100644
index 0000000..094916d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/SourceRange.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+
+/**
+ * A source range defines an element's source coordinates relative to
+ * its source buffer.
+ *
+ * @see ISourceRange
+ * @since 3.6
+ */
+public final class SourceRange implements ISourceRange {
+
+	/**
+	 * Helper method that answers whether a valid source range is available
+	 * in the given ISourceRange. When an element has no associated source
+	 * code, Java Model APIs may return either <code>null</code> or a range of
+	 * [-1, 0] to indicate an invalid range. This utility method can be used
+	 * to detect that case.
+	 *
+	 * @param range a source range, can be <code>null</code>
+	 * @return <code>true</code> iff range is not null and range.getOffset() is not -1
+	 */
+	public static boolean isAvailable(ISourceRange range) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=130161
+		return range != null && range.getOffset() != -1;
+	}
+
+	private int offset;
+	private int length;
+
+	/**
+	 * Instantiate a new source range using the given offset and the given length.
+	 * 
+	 * @param offset the given offset
+	 * @param length the given length
+	 */
+	public SourceRange(int offset, int length) {
+		this.offset = offset;
+		this.length = length;
+	}
+	/*
+	 * @see Object#equals(Object)
+	 */
+	public boolean equals(Object obj) {
+		if (!(obj instanceof ISourceRange))
+			return false;
+		ISourceRange sourceRange = (ISourceRange) obj;
+		return sourceRange.getOffset() == this.offset && sourceRange.getLength() == this.length;
+	}
+	/**
+	 * @see ISourceRange
+	 */
+	public int getLength() {
+		return this.length;
+	}
+	/**
+	 * @see ISourceRange
+	 */
+	public int getOffset() {
+		return this.offset;
+	}
+
+	/*
+	 * @see Object#hashCode()
+	 */
+	public int hashCode() {
+		return this.length ^ this.offset;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[offset="); //$NON-NLS-1$
+		buffer.append(this.offset);
+		buffer.append(", length="); //$NON-NLS-1$
+		buffer.append(this.length);
+		buffer.append("]"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
new file mode 100644
index 0000000..8a9cf4c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
@@ -0,0 +1,517 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.compiler.IScanner;
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.util.ClassFileReader;
+import org.eclipse.jdt.internal.core.util.Disassembler;
+import org.eclipse.jdt.internal.core.util.PublicScanner;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
+
+/**
+ * Factory for creating various compiler tools, such as scanners, parsers and compilers.
+ * <p>
+ *  This class provides static methods only.
+ * </p>
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ToolFactory {
+
+	/**
+	 * This mode is used for formatting new code when some formatter options should not be used.
+	 * In particular, options that preserve the indentation of comments are not used.
+	 * In the future,  newly added options may be ignored as well.
+	 * <p>Clients that are formatting new code are recommended to use this mode.
+	 * </p>
+	 *
+	 * @see DefaultCodeFormatterConstants#FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN
+	 * @see DefaultCodeFormatterConstants#FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN
+	 * @see #createCodeFormatter(Map, int)
+	 * @since 3.3
+	 */
+	public static final int M_FORMAT_NEW = new Integer(0).intValue();
+
+	/**
+	 * This mode is used for formatting existing code when all formatter options should be used.
+	 * In particular, options that preserve the indentation of comments are used.
+	 * <p>Clients that are formatting existing code are recommended to use this mode.
+	 * </p>
+	 *
+	 * @see DefaultCodeFormatterConstants#FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN
+	 * @see DefaultCodeFormatterConstants#FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN
+	 * @see #createCodeFormatter(Map, int)
+	 * @since 3.3
+	 */
+	public static final int M_FORMAT_EXISTING = new Integer(1).intValue();
+
+	/**
+	 * Create an instance of a code formatter. A code formatter implementation can be contributed via the
+	 * extension point "org.eclipse.jdt.core.codeFormatter". If unable to find a registered extension, the factory
+	 * will default to using the default code formatter.
+	 *
+	 * @return an instance of a code formatter
+	 * @see ICodeFormatter
+	 * @see ToolFactory#createDefaultCodeFormatter(Map)
+	 * @deprecated The extension point has been deprecated, use {@link #createCodeFormatter(Map)} instead.
+	 */
+	public static ICodeFormatter createCodeFormatter(){
+
+			Plugin jdtCorePlugin = JavaCore.getPlugin();
+			if (jdtCorePlugin == null) return null;
+
+			IExtensionPoint extension = jdtCorePlugin.getDescriptor().getExtensionPoint(JavaModelManager.FORMATTER_EXTPOINT_ID);
+			if (extension != null) {
+				IExtension[] extensions =  extension.getExtensions();
+				for(int i = 0; i < extensions.length; i++){
+					IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+					for(int j = 0; j < configElements.length; j++){
+						try {
+							Object execExt = configElements[j].createExecutableExtension("class"); //$NON-NLS-1$
+							if (execExt instanceof ICodeFormatter){
+								// use first contribution found
+								return (ICodeFormatter)execExt;
+							}
+						} catch(CoreException e){
+							// unable to instantiate extension, will answer default formatter instead
+						}
+					}
+				}
+			}
+		// no proper contribution found, use default formatter
+		return createDefaultCodeFormatter(null);
+	}
+
+	/**
+	 * Create an instance of the built-in code formatter.
+	 * <p>The given options should at least provide the source level ({@link JavaCore#COMPILER_SOURCE}),
+	 * the  compiler compliance level ({@link JavaCore#COMPILER_COMPLIANCE}) and the target platform
+	 * ({@link JavaCore#COMPILER_CODEGEN_TARGET_PLATFORM}).
+	 * Without these options, it is not possible for the code formatter to know what kind of source it needs to format.
+	 * </p><p>
+	 * Note this is equivalent to <code>createCodeFormatter(options, M_FORMAT_NEW)</code>. Thus some code formatter options
+	 * may be ignored. See @{link {@link #M_FORMAT_NEW} for more details.
+	 * </p>
+	 * @param options - the options map to use for formatting with the default code formatter. Recognized options
+	 * 	are documented on <code>JavaCore#getDefaultOptions()</code>. If set to <code>null</code>, then use
+	 * 	the current settings from <code>JavaCore#getOptions</code>.
+	 * @return an instance of the built-in code formatter
+	 * @see CodeFormatter
+	 * @see JavaCore#getOptions()
+	 * @since 3.0
+	 */
+	public static CodeFormatter createCodeFormatter(Map options){
+		return createCodeFormatter(options, M_FORMAT_NEW);
+	}
+
+	/**
+	 * Create an instance of the built-in code formatter.
+	 * <p>The given options should at least provide the source level ({@link JavaCore#COMPILER_SOURCE}),
+	 * the  compiler compliance level ({@link JavaCore#COMPILER_COMPLIANCE}) and the target platform
+	 * ({@link JavaCore#COMPILER_CODEGEN_TARGET_PLATFORM}).
+	 * Without these options, it is not possible for the code formatter to know what kind of source it needs to format.
+	 * </p>
+	 * <p>The given mode determines what options should be enabled when formatting the code. It can have the following
+	 * values: {@link #M_FORMAT_NEW}, {@link #M_FORMAT_EXISTING}, but other values may be added in the future.
+	 * </p>
+	 *
+	 * @param options the options map to use for formatting with the default code formatter. Recognized options
+	 * 	are documented on <code>JavaCore#getDefaultOptions()</code>. If set to <code>null</code>, then use
+	 * 	the current settings from <code>JavaCore#getOptions</code>.
+	 * @param mode the given mode to modify the given options.
+	 *
+	 * @return an instance of the built-in code formatter
+	 * @see CodeFormatter
+	 * @see JavaCore#getOptions()
+	 * @since 3.3
+	 */
+	public static CodeFormatter createCodeFormatter(Map options, int mode) {
+		if (options == null) options = JavaCore.getOptions();
+		Map currentOptions = new HashMap(options);
+		if (mode == M_FORMAT_NEW) {
+			// disable the option for not formatting comments starting on first column
+			currentOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.TRUE);
+			// disable the option for not indenting comments starting on first column
+			currentOptions.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.FALSE);
+			currentOptions.put(DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.FALSE);
+		}
+		return new DefaultCodeFormatter(currentOptions);
+	}
+
+	/**
+	 * Create a classfile bytecode disassembler, able to produce a String representation of a given classfile.
+	 *
+	 * @return a classfile bytecode disassembler
+	 * @see ClassFileBytesDisassembler
+	 * @since 2.1
+	 */
+	public static ClassFileBytesDisassembler createDefaultClassFileBytesDisassembler(){
+		return new Disassembler();
+	}
+
+	/**
+	 * Create a classfile bytecode disassembler, able to produce a String representation of a given classfile.
+	 *
+	 * @return a classfile bytecode disassembler
+	 * @see org.eclipse.jdt.core.util.IClassFileDisassembler
+	 * @deprecated Use {@link #createDefaultClassFileBytesDisassembler()} instead
+	 */
+	public static org.eclipse.jdt.core.util.IClassFileDisassembler createDefaultClassFileDisassembler(){
+		class DeprecatedDisassembler extends Disassembler implements org.eclipse.jdt.core.util.IClassFileDisassembler {
+			// for backward compatibility, defines a disassembler which implements IClassFileDisassembler
+		}
+		return new DeprecatedDisassembler();
+	}
+
+	/**
+	 * Create a classfile reader onto a classfile Java element.
+	 * Create a default classfile reader, able to expose the internal representation of a given classfile
+	 * according to the decoding flag used to initialize the reader.
+	 * Answer null if the file named fileName doesn't represent a valid .class file.
+	 *
+	 * The decoding flags are described in IClassFileReader.
+	 *
+	 * @param classfile the classfile element to introspect
+	 * @param decodingFlag the flag used to decode the class file reader.
+	 * @return a default classfile reader
+	 *
+	 * @see IClassFileReader
+	 */
+	public static IClassFileReader createDefaultClassFileReader(IClassFile classfile, int decodingFlag){
+
+		IPackageFragmentRoot root = (IPackageFragmentRoot) classfile.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		if (root != null){
+			try {
+				if (root instanceof JarPackageFragmentRoot) {
+					String archiveName = null;
+					ZipFile jar = null;
+					try {
+						jar = ((JarPackageFragmentRoot)root).getJar();
+						archiveName = jar.getName();
+					} finally {
+						JavaModelManager.getJavaModelManager().closeZipFile(jar);
+					}
+					PackageFragment packageFragment = (PackageFragment) classfile.getParent();
+					String classFileName = classfile.getElementName();
+					String entryName = org.eclipse.jdt.internal.core.util.Util.concatWith(packageFragment.names, classFileName, '/');
+					return createDefaultClassFileReader(archiveName, entryName, decodingFlag);
+				} else {
+					InputStream in = null;
+					try {
+						in = ((IFile) ((JavaElement) classfile).resource()).getContents();
+						return createDefaultClassFileReader(in, decodingFlag);
+					} finally {
+						if (in != null)
+							try {
+								in.close();
+							} catch (IOException e) {
+								// ignore
+							}
+					}
+				}
+			} catch(CoreException e){
+				// unable to read
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Create a default classfile reader, able to expose the internal representation of a given classfile
+	 * according to the decoding flag used to initialize the reader.
+	 * Answer null if the input stream contents cannot be retrieved
+	 *
+	 * The decoding flags are described in IClassFileReader.
+	 *
+	 * @param stream the given input stream to read
+	 * @param decodingFlag the flag used to decode the class file reader.
+	 * @return a default classfile reader
+	 *
+	 * @see IClassFileReader
+	 * @since 3.2
+	 */
+	public static IClassFileReader createDefaultClassFileReader(InputStream stream, int decodingFlag) {
+		try {
+			return new ClassFileReader(Util.getInputStreamAsByteArray(stream, -1), decodingFlag);
+		} catch(ClassFormatException e) {
+			return null;
+		} catch(IOException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Create a default classfile reader, able to expose the internal representation of a given classfile
+	 * according to the decoding flag used to initialize the reader.
+	 * Answer null if the file named fileName doesn't represent a valid .class file.
+	 * The fileName has to be an absolute OS path to the given .class file.
+	 *
+	 * The decoding flags are described in IClassFileReader.
+	 *
+	 * @param fileName the name of the file to be read
+	 * @param decodingFlag the flag used to decode the class file reader.
+	 * @return a default classfile reader
+	 *
+	 * @see IClassFileReader
+	 */
+	public static IClassFileReader createDefaultClassFileReader(String fileName, int decodingFlag){
+		try {
+			return new ClassFileReader(Util.getFileByteContent(new File(fileName)), decodingFlag);
+		} catch(ClassFormatException e) {
+			return null;
+		} catch(IOException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Create a default classfile reader, able to expose the internal representation of a given classfile
+	 * according to the decoding flag used to initialize the reader.
+	 * Answer null if the file named zipFileName doesn't represent a valid zip file or if the zipEntryName
+	 * is not a valid entry name for the specified zip file or if the bytes don't represent a valid
+	 * .class file according to the JVM specifications.
+	 *
+	 * The decoding flags are described in IClassFileReader.
+	 *
+	 * @param zipFileName the name of the zip file
+	 * @param zipEntryName the name of the entry in the zip file to be read
+	 * @param decodingFlag the flag used to decode the class file reader.
+	 * @return a default classfile reader
+	 * @see IClassFileReader
+	 */
+	public static IClassFileReader createDefaultClassFileReader(String zipFileName, String zipEntryName, int decodingFlag){
+		ZipFile zipFile = null;
+		try {
+			if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [ToolFactory.createDefaultClassFileReader()] Creating ZipFile on " + zipFileName); //$NON-NLS-1$	//$NON-NLS-2$
+			}
+			zipFile = new ZipFile(zipFileName);
+			ZipEntry zipEntry = zipFile.getEntry(zipEntryName);
+			if (zipEntry == null) {
+				return null;
+			}
+			if (!zipEntryName.toLowerCase().endsWith(SuffixConstants.SUFFIX_STRING_class)) {
+				return null;
+			}
+			byte classFileBytes[] = Util.getZipEntryByteContent(zipEntry, zipFile);
+			return new ClassFileReader(classFileBytes, decodingFlag);
+		} catch(ClassFormatException e) {
+			return null;
+		} catch(IOException e) {
+			return null;
+		} finally {
+			if (zipFile != null) {
+				try {
+					zipFile.close();
+				} catch(IOException e) {
+					// ignore
+				}
+			}
+		}
+	}
+
+	/**
+	 * Create an instance of the default code formatter.
+	 *
+	 * @param options - the options map to use for formatting with the default code formatter. Recognized options
+	 * 	are documented on <code>JavaCore#getDefaultOptions()</code>. If set to <code>null</code>, then use
+	 * 	the current settings from <code>JavaCore#getOptions</code>.
+	 * @return an instance of the built-in code formatter
+	 * @see ICodeFormatter
+	 * @see ToolFactory#createCodeFormatter()
+	 * @see JavaCore#getOptions()
+	 * @deprecated Use {@link #createCodeFormatter(Map)} instead but note the different options
+	 */
+	public static ICodeFormatter createDefaultCodeFormatter(Map options){
+		if (options == null) options = JavaCore.getOptions();
+		return new org.eclipse.jdt.internal.formatter.old.CodeFormatter(options);
+	}
+
+	/**
+	 * Create a scanner, indicating the level of detail requested for tokenizing. The scanner can then be
+	 * used to tokenize some source in a Java aware way.
+	 * Here is a typical scanning loop:
+	 *
+	 * <code>
+	 * <pre>
+	 *   IScanner scanner = ToolFactory.createScanner(false, false, false, false);
+	 *   scanner.setSource("int i = 0;".toCharArray());
+	 *   while (true) {
+	 *     int token = scanner.getNextToken();
+	 *     if (token == ITerminalSymbols.TokenNameEOF) break;
+	 *     System.out.println(token + " : " + new String(scanner.getCurrentTokenSource()));
+	 *   }
+	 * </pre>
+	 * </code>
+	 *
+	 * <p>By default the compliance used to create the scanner is the workspace's compliance when running inside the IDE
+	 * or 1.4 if running from outside of a headless eclipse.
+	 * </p>
+	 *
+	 * @param tokenizeComments if set to <code>false</code>, comments will be silently consumed
+	 * @param tokenizeWhiteSpace if set to <code>false</code>, white spaces will be silently consumed,
+	 * @param assertMode if set to <code>false</code>, occurrences of 'assert' will be reported as identifiers
+	 * ({@link ITerminalSymbols#TokenNameIdentifier}), whereas if set to <code>true</code>, it
+	 * would report assert keywords ({@link ITerminalSymbols#TokenNameassert}). Java 1.4 has introduced
+	 * a new 'assert' keyword.
+	 * @param recordLineSeparator if set to <code>true</code>, the scanner will record positions of encountered line
+	 * separator ends. In case of multi-character line separators, the last character position is considered. These positions
+	 * can then be extracted using {@link IScanner#getLineEnds()}. Only non-unicode escape sequences are
+	 * considered as valid line separators.
+  	 * @return a scanner
+	 * @see org.eclipse.jdt.core.compiler.IScanner
+	 * @see #createScanner(boolean, boolean, boolean, String, String)
+	 */
+	public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean assertMode, boolean recordLineSeparator){
+		// use default workspace compliance
+		long complianceLevelValue = CompilerOptions.versionToJdkLevel(JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE));
+		if (complianceLevelValue == 0) complianceLevelValue = ClassFileConstants.JDK1_4; // fault-tolerance
+		PublicScanner scanner =
+			new PublicScanner(
+				tokenizeComments,
+				tokenizeWhiteSpace,
+				false/*nls*/,
+				assertMode ? ClassFileConstants.JDK1_4 : ClassFileConstants.JDK1_3/*sourceLevel*/,
+				complianceLevelValue,
+				null/*taskTags*/,
+				null/*taskPriorities*/,
+				true/*taskCaseSensitive*/);
+		scanner.recordLineSeparator = recordLineSeparator;
+		return scanner;
+	}
+
+	/**
+	 * Create a scanner, indicating the level of detail requested for tokenizing. The scanner can then be
+	 * used to tokenize some source in a Java aware way.
+	 * Here is a typical scanning loop:
+	 *
+	 * <code>
+	 * <pre>
+	 *   IScanner scanner = ToolFactory.createScanner(false, false, false, false);
+	 *   scanner.setSource("int i = 0;".toCharArray());
+	 *   while (true) {
+	 *     int token = scanner.getNextToken();
+	 *     if (token == ITerminalSymbols.TokenNameEOF) break;
+	 *     System.out.println(token + " : " + new String(scanner.getCurrentTokenSource()));
+	 *   }
+	 * </pre>
+	 * </code>
+	 *
+	 * <p>By default the compliance used to create the scanner is the workspace's compliance when running inside the IDE
+	 * or 1.4 if running from outside of a headless eclipse.
+	 * </p>
+	 *
+	 * @param tokenizeComments if set to <code>false</code>, comments will be silently consumed
+	 * @param tokenizeWhiteSpace if set to <code>false</code>, white spaces will be silently consumed,
+	 * @param recordLineSeparator if set to <code>true</code>, the scanner will record positions of encountered line
+	 * separator ends. In case of multi-character line separators, the last character position is considered. These positions
+	 * can then be extracted using {@link IScanner#getLineEnds()}. Only non-unicode escape sequences are
+	 * considered as valid line separators.
+	 * @param sourceLevel if set to <code>&quot;1.3&quot;</code> or <code>null</code>, occurrences of 'assert' will be reported as identifiers
+	 * ({@link ITerminalSymbols#TokenNameIdentifier}), whereas if set to <code>&quot;1.4&quot;</code>, it
+	 * would report assert keywords ({@link ITerminalSymbols#TokenNameassert}). Java 1.4 has introduced
+	 * a new 'assert' keyword.
+	 * @return a scanner
+	 * @see org.eclipse.jdt.core.compiler.IScanner
+	 * @see #createScanner(boolean, boolean, boolean, String, String)
+	 * @since 3.0
+	 */
+	public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean recordLineSeparator, String sourceLevel) {
+		// use default workspace compliance
+		long complianceLevelValue = CompilerOptions.versionToJdkLevel(JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE));
+		if (complianceLevelValue == 0) complianceLevelValue = ClassFileConstants.JDK1_4; // fault-tolerance
+		long sourceLevelValue = CompilerOptions.versionToJdkLevel(sourceLevel);
+		if (sourceLevelValue == 0) sourceLevelValue = ClassFileConstants.JDK1_3; // fault-tolerance
+		PublicScanner scanner =
+			new PublicScanner(
+				tokenizeComments,
+				tokenizeWhiteSpace,
+				false/*nls*/,
+				sourceLevelValue /*sourceLevel*/,
+				complianceLevelValue,
+				null/*taskTags*/,
+				null/*taskPriorities*/,
+				true/*taskCaseSensitive*/);
+		scanner.recordLineSeparator = recordLineSeparator;
+		return scanner;
+	}
+
+	/**
+	 * Create a scanner, indicating the level of detail requested for tokenizing. The scanner can then be
+	 * used to tokenize some source in a Java aware way.
+	 * Here is a typical scanning loop:
+	 *
+	 * <code>
+	 * <pre>
+	 *   IScanner scanner = ToolFactory.createScanner(false, false, false, false);
+	 *   scanner.setSource("int i = 0;".toCharArray());
+	 *   while (true) {
+	 *     int token = scanner.getNextToken();
+	 *     if (token == ITerminalSymbols.TokenNameEOF) break;
+	 *     System.out.println(token + " : " + new String(scanner.getCurrentTokenSource()));
+	 *   }
+	 * </pre>
+	 * </code>
+	 *
+	 * @param tokenizeComments if set to <code>false</code>, comments will be silently consumed
+	 * @param tokenizeWhiteSpace if set to <code>false</code>, white spaces will be silently consumed,
+	 * @param recordLineSeparator if set to <code>true</code>, the scanner will record positions of encountered line
+	 * separator ends. In case of multi-character line separators, the last character position is considered. These positions
+	 * can then be extracted using {@link IScanner#getLineEnds()}. Only non-unicode escape sequences are
+	 * considered as valid line separators.
+	 * @param sourceLevel if set to <code>&quot;1.3&quot;</code> or <code>null</code>, occurrences of 'assert' will be reported as identifiers
+	 * ({@link ITerminalSymbols#TokenNameIdentifier}), whereas if set to <code>&quot;1.4&quot;</code>, it
+	 * would report assert keywords ({@link ITerminalSymbols#TokenNameassert}). Java 1.4 has introduced
+	 * a new 'assert' keyword.
+	 * @param complianceLevel This is used to support the Unicode 4.0 character sets. if set to 1.5 or above,
+	 * the Unicode 4.0 is supported, otherwise Unicode 3.0 is supported.
+	 * @return a scanner
+	 * @see org.eclipse.jdt.core.compiler.IScanner
+	 *
+	 * @since 3.1
+	 */
+	public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean recordLineSeparator, String sourceLevel, String complianceLevel) {
+		PublicScanner scanner = null;
+		long sourceLevelValue = CompilerOptions.versionToJdkLevel(sourceLevel);
+		if (sourceLevelValue == 0) sourceLevelValue = ClassFileConstants.JDK1_3; // fault-tolerance
+		long complianceLevelValue = CompilerOptions.versionToJdkLevel(complianceLevel);
+		if (complianceLevelValue == 0) complianceLevelValue = ClassFileConstants.JDK1_4; // fault-tolerance
+		scanner = new PublicScanner(tokenizeComments, tokenizeWhiteSpace, false/*nls*/,sourceLevelValue /*sourceLevel*/, complianceLevelValue, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+		scanner.recordLineSeparator = recordLineSeparator;
+		return scanner;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java
new file mode 100644
index 0000000..46fd1b4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.BufferManager;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
+import org.eclipse.jdt.internal.core.ExternalJavaProject;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+
+/**
+ * The owner of an {@link ICompilationUnit} handle in working copy mode.
+ * An owner is used to identify a working copy and to create its buffer.
+ * <p>
+ * Clients should subclass this class to instantiate a working copy owner that is specific to their need and that
+ * they can pass in to various APIs (e.g. {@link IType#resolveType(String, WorkingCopyOwner)}.
+ * Clients can also override the default implementation of {@link #createBuffer(ICompilationUnit)}.
+ * </p><p>
+ * Note: even though this class has no abstract method, which means that it provides functional default behavior,
+ * it is still an abstract class, as clients are intended to own their owner implementation.
+ * </p>
+ * @see ICompilationUnit#becomeWorkingCopy(org.eclipse.core.runtime.IProgressMonitor)
+ * @see ICompilationUnit#discardWorkingCopy()
+ * @see ICompilationUnit#getWorkingCopy(org.eclipse.core.runtime.IProgressMonitor)
+ * @since 3.0
+ */
+public abstract class WorkingCopyOwner {
+
+	/**
+	 * Sets the buffer provider of the primary working copy owner. Note that even if the
+	 * buffer provider is a working copy owner, only its <code>createBuffer(ICompilationUnit)</code>
+	 * method is used by the primary working copy owner. It doesn't replace the internal primary
+	 * working owner.
+ 	 * <p>
+	 * This method is for internal use by the jdt-related plug-ins.
+	 * Clients outside of the jdt should not reference this method.
+	 * </p>
+	 *
+	 * @param primaryBufferProvider the primary buffer provider
+	 */
+	public static void setPrimaryBufferProvider(WorkingCopyOwner primaryBufferProvider) {
+		DefaultWorkingCopyOwner.PRIMARY.primaryBufferProvider = primaryBufferProvider;
+	}
+
+	/**
+	 * Creates a buffer for the given working copy.
+	 * The new buffer will be initialized with the contents of the underlying file
+	 * if and only if it was not already initialized by the compilation owner (a buffer is
+	 * uninitialized if its content is <code>null</code>).
+	 * <p>
+	 * Note: This buffer will be associated to the working copy for its entire life-cycle. Another
+	 * working copy on same unit but owned by a different owner would not share the same buffer
+	 * unless its owner decided to implement such a sharing behaviour.
+	 * </p>
+	 *
+	 * @param workingCopy the working copy of the buffer
+	 * @return IBuffer the created buffer for the given working copy
+	 * @see IBuffer
+	 */
+	public IBuffer createBuffer(ICompilationUnit workingCopy) {
+
+		return BufferManager.createBuffer(workingCopy);
+	}
+
+	/**
+	 * Returns the problem requestor used by a working copy of this working copy owner.
+	 * <p>
+	 * By default, no problem requestor is configured. Clients can override this
+	 * method to provide a requestor.
+	 * </p>
+	 *
+	 * @param workingCopy The problem requestor used for the given working copy.
+	 * @return the problem requestor to be used by working copies of this working
+	 * copy owner or <code>null</code> if no problem requestor is configured.
+	 *
+	 * @since 3.3
+	 */
+	public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
+		return null;
+	}
+	
+	/**
+	 * Returns the source of the compilation unit that defines the given type in
+	 * the given package, or <code>null</code> if the type is unknown to this
+	 * owner.
+	 * <p>This method is called before the normal lookup (i.e. before looking 
+	 * at the project's classpath and before looking at the working copies of this 
+	 * owner.)</p>
+	 * <p>This allows to provide types that are not normally available, or to hide 
+	 * types that would normally be available by returning an empty source for 
+	 * the given type and package.</p>
+	 * <p>Example of use:
+	 * <pre>
+	 * WorkingCopyOwner owner = new WorkingCopyOwner() {
+	 *   public String findSource(String typeName, String packageName) {
+	 *     if ("to.be".equals(packageName) && "Generated".equals(typeName)) {
+	 *       return
+	 *         "package to.be;\n" +
+	 *         "public class Generated {\n" +
+	 *         "}";
+	 *     }
+	 *     return super.findSource(typeName, packageName);
+	 *   }
+	 *   public boolean isPackage(String[] pkg) {
+	 *     switch (pkg.length) {
+	 *     case 1:
+	 *       return "to".equals(pkg[0]);
+	 *     case 2:
+	 *       return "to".equals(pkg[0]) && "be".equals(pkg[1]);
+	 *     }
+	 *     return false;
+	 *   }
+	 * };
+	 * // Working copy on X.java with the following contents:
+	 * //    public class X extends to.be.Generated {
+	 * //    }
+	 * ICompilationUnit workingCopy = ... 
+	 * ASTParser parser = ASTParser.newParser(AST.JLS3);
+	 * parser.setSource(workingCopy);
+	 * parser.setResolveBindings(true);
+	 * parser.setWorkingCopyOwner(owner);
+	 * CompilationUnit cu = (CompilationUnit) parser.createAST(null);
+	 * assert cu.getProblems().length == 0;
+	 * </pre>
+	 * </p>
+	 * 
+	 * @param typeName the simple name of the type to lookup
+	 * @param packageName the dot-separated name of the package of type
+	 * @return the source of the compilation unit that defines the given type in
+	 * the given package, or <code>null</code> if the type is unknown
+	 * @see #isPackage(String[])
+	 * @since 3.5
+	 */
+	public String findSource(String typeName, String packageName) {
+		return null;
+	}
+	
+	/**
+	 * Returns whether the given package segments represent a package.
+	 * <p>This method is called before the normal lookup (i.e. before looking 
+	 * at the project's classpath and before looking at the working copies of this 
+	 * owner.)</p>
+	 * <p>This allows to provide packages that are not normally available.</p>
+	 * <p>If <code>false</code> is returned, then normal lookup is used on 
+	 * this package.</p>
+	 * 
+	 * @param pkg the segments of a package to lookup
+	 * @return whether the given package segments represent a package.
+	 * @see #findSource(String, String)
+	 * @since 3.5
+	 */
+	public boolean isPackage(String[] pkg) {
+		return false;
+	}
+
+	/**
+	 * Returns a new working copy with the given name using this working copy owner to
+	 * create its buffer.
+	 * <p>
+	 * This working copy always belongs to the default package in a package
+	 * fragment root that corresponds to its Java project, and this Java project never exists.
+	 * However this Java project has the given classpath that is used when resolving names
+	 * in this working copy.
+	 * </p><p>
+	 * A DOM AST created using this working copy will have bindings resolved using the given
+	 * classpath, and problem are reported to the given problem requestor.
+	 * <p></p>
+	 * <code>JavaCore#getOptions()</code> is used to create the DOM AST as it is not
+	 * possible to set the options on the non-existing Java project.
+	 * </p><p>
+	 * When the working copy instance is created, an {@link IJavaElementDelta#ADDED added delta} is
+	 * reported on this working copy.
+	 * </p><p>
+	 * Once done with the working copy, users of this method must discard it using
+	 * {@link ICompilationUnit#discardWorkingCopy()}.
+	 * </p><p>
+	 * Note that when such working copy is committed, only its buffer is saved (see
+	 * {@link IBuffer#save(IProgressMonitor, boolean)}) but no resource is created.
+	 * </p><p>
+	 * This method is not intended to be overriden by clients.
+	 * </p>
+	 *
+	 * @param name the name of the working copy (e.g. "X.java")
+	 * @param classpath the classpath used to resolve names in this working copy
+	 * @param problemRequestor a requestor which will get notified of problems detected during
+	 * 	reconciling as they are discovered. The requestor can be set to <code>null</code> indicating
+	 * 	that the client is not interested in problems.
+	 * @param monitor a progress monitor used to report progress while opening the working copy
+	 * 	or <code>null</code> if no progress should be reported
+	 * @throws JavaModelException if the contents of this working copy can
+	 *   not be determined.
+	 * @return a new working copy
+	 * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
+	 * @since 3.2
+	 *
+	 * @deprecated Use {@link #newWorkingCopy(String, IClasspathEntry[], IProgressMonitor)} instead.
+	 * 	Note that if this deprecated method is used, problems may be reported twice
+	 * 	if the given requestor is not the same as the current working copy owner one.
+	 */
+	public final ICompilationUnit newWorkingCopy(String name, IClasspathEntry[] classpath, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
+		ExternalJavaProject project = new ExternalJavaProject(classpath);
+		IPackageFragment parent = ((PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject())).getPackageFragment(CharOperation.NO_STRINGS);
+		CompilationUnit result = new CompilationUnit((PackageFragment) parent, name, this);
+		result.becomeWorkingCopy(problemRequestor, monitor);
+		return result;
+	}
+
+	/**
+	 * Returns a new working copy with the given name using this working copy owner to
+	 * create its buffer.
+	 * <p>
+	 * This working copy always belongs to the default package in a package
+	 * fragment root that corresponds to its Java project, and this Java project never exists.
+	 * However this Java project has the given classpath that is used when resolving names
+	 * in this working copy.
+	 * </p><p>
+	 * If a DOM AST is created using this working copy, then given classpath will be used
+	 *  if bindings need to be resolved. Problems will be reported to the problem requestor
+	 * of the current working copy owner problem if it is not <code>null</code>.
+	 * <p></p>
+	 * Options used to create the DOM AST are got from {@link JavaCore#getOptions()}
+	 * as it is not possible to set the options on a non-existing Java project.
+	 * </p><p>
+	 * When the working copy instance is created, an {@link IJavaElementDelta#ADDED added delta} is
+	 * reported on this working copy.
+	 * </p><p>
+	 * Once done with the working copy, users of this method must discard it using
+	 * {@link ICompilationUnit#discardWorkingCopy()}.
+	 * </p><p>
+	 * Note that when such working copy is committed, only its buffer is saved (see
+	 * {@link IBuffer#save(IProgressMonitor, boolean)}) but no resource is created.
+	 * </p><p>
+	 * This method is not intended to be overriden by clients.
+	 * </p>
+	 *
+	 * @param name the name of the working copy (e.g. "X.java")
+	 * @param classpath the classpath used to resolve names in this working copy
+	 * @param monitor a progress monitor used to report progress while opening the working copy
+	 * 	or <code>null</code> if no progress should be reported
+	 * @throws JavaModelException if the contents of this working copy can
+	 *   not be determined.
+	 * @return a new working copy
+	 * @see ICompilationUnit#becomeWorkingCopy(IProgressMonitor)
+	 *
+	 * @since 3.3
+	 */
+	public final ICompilationUnit newWorkingCopy(String name, IClasspathEntry[] classpath, IProgressMonitor monitor) throws JavaModelException {
+		ExternalJavaProject project = new ExternalJavaProject(classpath);
+		IPackageFragment parent = ((PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject())).getPackageFragment(CharOperation.NO_STRINGS);
+		CompilationUnit result = new CompilationUnit((PackageFragment) parent, name, this);
+		result.becomeWorkingCopy(getProblemRequestor(result), monitor);
+		return result;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/BuildContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/BuildContext.java
new file mode 100644
index 0000000..abd7117
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/BuildContext.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM Corporation - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.core.resources.IFile;
+
+/**
+ * The context of a build event that is notified to interested compilation
+ * participants when {@link CompilationParticipant#buildStarting(BuildContext[], boolean) a build is starting},
+ * or to annotations processors when {@link CompilationParticipant#processAnnotations(BuildContext[]) a source file has annotations}.
+ *
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class BuildContext {
+
+/**
+ * Returns the contents of the compilation unit.
+ *
+ * @return the contents of the compilation unit
+ */
+public char[] getContents() {
+	return null; // default overridden by concrete implementation
+}
+
+/**
+ * Returns the <code>IFile</code> representing the compilation unit.
+ *
+ * @return the <code>IFile</code> representing the compilation unit
+ */
+public IFile getFile() {
+	return null; // default overridden by concrete implementation
+}
+
+/**
+ * Returns whether the compilation unit contained any annotations when it was compiled.
+ *
+ * NOTE: This is only valid during {@link CompilationParticipant#processAnnotations(BuildContext[])}.
+ *
+ * @return whether the compilation unit contained any annotations when it was compiled
+ */
+public boolean hasAnnotations() {
+	return false; // default overridden by concrete implementation
+}
+
+/**
+ * Record the added/changed generated files that need to be compiled.
+ *
+ * @param addedGeneratedFiles the added/changed files
+ */
+public void recordAddedGeneratedFiles(IFile[] addedGeneratedFiles) {
+	// default overridden by concrete implementation
+}
+
+/**
+ * Record the generated files that need to be deleted.
+ *
+ * @param deletedGeneratedFiles the files that need to be deleted
+ */
+public void recordDeletedGeneratedFiles(IFile[] deletedGeneratedFiles) {
+	// default overridden by concrete implementation
+}
+
+/**
+ * Record the fully-qualified type names of any new dependencies, each name is of the form "p1.p2.A.B".
+ *
+ * @param typeNameDependencies the fully-qualified type names of new dependencies
+ */
+public void recordDependencies(String[] typeNameDependencies) {
+	// default overridden by concrete implementation
+}
+
+/**
+ * Record new problems to report against this compilationUnit.
+ * Markers are persisted for these problems only for the declared managed marker type
+ * (see the 'compilationParticipant' extension point).
+ *
+ * @param newProblems the problems to report
+ */
+public void recordNewProblems(CategorizedProblem[] newProblems) {
+	// default overridden by concrete implementation
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/CompilationParticipant.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/CompilationParticipant.java
new file mode 100644
index 0000000..a2aa851
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/CompilationParticipant.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    mkaufman@bea.com - initial API as ICompilationParticipant
+ *    IBM - changed from interface ICompilationParticipant to abstract class CompilationParticipant
+ *    IBM - rewrote specification
+ *
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.core.IJavaProject;
+
+/**
+ * A compilation participant is notified of events occurring during the compilation process.
+ * The compilation process not only involves generating .class files (i.e. building), it also involves
+ * cleaning the output directory, reconciling a working copy, etc.
+ * So the notified events are the result of a build action, a clean action, a reconcile operation
+ * (for a working copy), etc.
+ * <p>
+ * Code that participates in the build should in general be implemented with a separate Builder,
+ * rather than a CompilationParticipant. It is only necessary to use a CompilationParticipant if
+ * the build step needs to interact with the Java build, for instance by creating additional
+ * Java source files that must themselves in turn be compiled.
+ * <p>
+ * Clients wishing to participate in the compilation process must subclass this class, and implement
+ * {@link #isActive(IJavaProject)}, {@link #aboutToBuild(IJavaProject)},
+ * {@link #reconcile(ReconcileContext)}, etc.
+* </p><p>
+ * This class is intended to be subclassed by clients.
+ * </p>
+ * @since 3.2
+ */
+public abstract class CompilationParticipant {
+
+	public final static int READY_FOR_BUILD = 1;
+	public final static int NEEDS_FULL_BUILD = 2;
+
+/**
+ * Notifies this participant that a build is about to start and provides it the opportunity to
+ * create missing source folders for generated source files. Additional source folders
+ * should be marked as optional so the project can be built when the folders do not exist.
+ * Only sent to participants interested in the project.
+ * <p>
+ * Default is to return <code>READY_FOR_BUILD</code>.
+ * </p>
+ * @see #buildFinished(IJavaProject project)
+ * @param project the project about to build
+ * @return READY_FOR_BUILD or NEEDS_FULL_BUILD
+ */
+public int aboutToBuild(IJavaProject project) {
+	return READY_FOR_BUILD;
+}
+
+/**
+ * Notifies this participant that a build has finished for the project.
+ * This will be sent, even if buildStarting() was not sent when no source files needed to be compiled
+ * or the build failed.
+ * Only sent to participants interested in the project.
+ * @param project the project about to build
+ * @since 3.4
+  */
+public void buildFinished(IJavaProject project) {
+	// do nothing by default
+}
+
+/**
+ * Notifies this participant that a compile operation is about to start and provides it the opportunity to
+ * generate source files based on the source files about to be compiled.
+ * When isBatchBuild is true, then files contains all source files in the project.
+ * Only sent to participants interested in the current build project.
+ *
+ * @param files is an array of BuildContext
+ * @param isBatch identifies when the build is a batch build
+  */
+public void buildStarting(BuildContext[] files, boolean isBatch) {
+	// do nothing by default
+}
+
+/**
+ * Notifies this participant that a clean is about to start and provides it the opportunity to
+ * delete generated source files.
+ * Only sent to participants interested in the project.
+ * @param project the project about to be cleaned
+ */
+public void cleanStarting(IJavaProject project) {
+	// do nothing by default
+}
+
+/**
+ * Returns whether this participant is active for a given project.
+ * <p>
+ * Default is to return <code>false</code>.
+ * </p><p>
+ * For efficiency, participants that are not interested in the
+ * given project should return <code>false</code> for that project.
+ * </p>
+ * @param project the project to participate in
+ * @return whether this participant is active for a given project
+ */
+public boolean isActive(IJavaProject project) {
+	return false;
+}
+
+/**
+ * Returns whether this participant is interested in only Annotations.
+ * <p>
+ * Default is to return <code>false</code>.
+ * </p>
+ * @return whether this participant is interested in only Annotations.
+ */
+public boolean isAnnotationProcessor() {
+	return false;
+}
+
+/**
+ * Notifies this participant that a compile operation has found source files using Annotations.
+ * Only sent to participants interested in the current build project that answer true to isAnnotationProcessor().
+ * Each BuildContext was informed whether its source file currently hasAnnotations().
+ *
+ * @param files is an array of BuildContext
+  */
+public void processAnnotations(BuildContext[] files) {
+	// do nothing by default
+}
+
+/**
+ * Notifies this participant that a reconcile operation is happening. The participant can act on this reconcile
+ * operation by using the given context. Other participant can then see the result of this participation
+ * on this context.
+ * <p>
+ * Note that a participant should not modify the buffer of the working copy that is being reconciled.
+ * </p><p>
+ * Default is to do nothing.
+ * </p>
+ * @param context the reconcile context to act on
+  */
+public void reconcile(ReconcileContext context) {
+	// do nothing by default
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java
new file mode 100644
index 0000000..bbc6585
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+
+ /**
+  * Definition of a Java scanner, as returned by the <code>ToolFactory</code>.
+  * The scanner is responsible for tokenizing a given source, providing information about
+  * the nature of the token read, its positions and source equivalent.
+  * <p>
+  * When the scanner has finished tokenizing, it answers an EOF token (<code>
+  * ITerminalSymbols#TokenNameEOF</code>.
+  * </p><p>
+  * When encountering lexical errors, an <code>InvalidInputException</code> is thrown.
+ * </p>
+  *
+  * @see org.eclipse.jdt.core.ToolFactory
+  * @see ITerminalSymbols
+  * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+  */
+public interface IScanner {
+
+	/**
+	 * Answers the current identifier source, after unicode escape sequences have
+	 * been translated into unicode characters.
+	 * For example, if original source was <code>\\u0061bc</code> then it will answer <code>abc</code>.
+	 *
+	 * @return the current identifier source, after unicode escape sequences have
+	 * been translated into unicode characters
+	 */
+	char[] getCurrentTokenSource();
+
+	/**
+	 * Answers the current identifier source, before unicode escape sequences have
+	 * been translated into unicode characters.
+	 * For example, if original source was <code>\\u0061bc</code> then it will answer <code>\\u0061bc</code>.
+	 *
+	 * @return the current identifier source, before unicode escape sequences have
+	 * been translated into unicode characters
+	 * @since 2.1
+	 */
+	char[] getRawTokenSource();
+
+	/**
+	 * Answers the starting position of the current token inside the original source.
+	 * This position is zero-based and inclusive. It corresponds to the position of the first character
+	 * which is part of this token. If this character was a unicode escape sequence, it points at the first
+	 * character of this sequence.
+	 *
+	 * @return the starting position of the current token inside the original source
+	 */
+	int getCurrentTokenStartPosition();
+
+	/**
+	 * Answers the ending position of the current token inside the original source.
+	 * This position is zero-based and inclusive. It corresponds to the position of the last character
+	 * which is part of this token. If this character was a unicode escape sequence, it points at the last
+	 * character of this sequence.
+	 *
+	 * @return the ending position of the current token inside the original source
+	 */
+	int getCurrentTokenEndPosition();
+
+	/**
+	 * Answers the starting position of a given line number. This line has to have been encountered
+	 * already in the tokenization process (in other words, it cannot be used to compute positions of lines beyond
+	 * current token). Once the entire source has been processed, it can be used without any limit.
+	 * Line starting positions are zero-based, and start immediately after the previous line separator (if any).
+	 *
+	 * @param lineNumber the given line number
+	 * @return the starting position of a given line number
+	 */
+	int getLineStart(int lineNumber);
+
+	/**
+	 * Answers the ending position of a given line number. This line has to have been encountered
+	 * already in the tokenization process (in other words, it cannot be used to compute positions of lines beyond
+	 * current token). Once the entire source has been processed, it can be used without any limit.
+	 * Line ending positions are zero-based, and correspond to the last character of the line separator
+	 * (in case multi-character line separators).
+	 *
+	 * @param lineNumber the given line number
+	 * @return the ending position of a given line number
+	 **/
+	int getLineEnd(int lineNumber);
+
+	/**
+	 * Answers an array of the ending positions of the lines encountered so far. Line ending positions
+	 * are zero-based, and correspond to the last character of the line separator (in case multi-character
+	 * line separators).
+	 *
+	 * @return an array of the ending positions of the lines encountered so far
+	 */
+	int[] getLineEnds();
+
+	/**
+	 * Answers a 1-based line number using the lines which have been encountered so far. If the position
+	 * is located beyond the current scanned line, then the last line number will be answered.
+	 *
+	 * @param charPosition the given character position
+	 * @return a 1-based line number using the lines which have been encountered so far
+	 */
+	int getLineNumber(int charPosition);
+
+	/**
+	 * Read the next token in the source, and answers its ID as specified by <code>ITerminalSymbols</code>.
+	 * Note that the actual token ID values are subject to change if new keywords were added to the language
+	 * (for instance, 'assert' is a keyword in 1.4).
+	 *
+	 * @throws InvalidInputException in case a lexical error was detected while reading the current token
+	 * @return the next token
+	 */
+	int getNextToken() throws InvalidInputException;
+
+	/**
+	 * Answers the original source being processed (not a copy of it).
+	 *
+	 * @return the original source being processed
+	 */
+	char[] getSource();
+
+	/**
+	 * Reposition the scanner on some portion of the original source. The given endPosition is the last valid position.
+	 * Beyond this position, the scanner will answer EOF tokens (<code>ITerminalSymbols.TokenNameEOF</code>).
+	 *
+	 * @param startPosition the given start position
+	 * @param endPosition the given end position
+	 */
+	void resetTo(int startPosition, int endPosition);
+
+	/**
+	 * Set the scanner source to process. By default, the scanner will consider starting at the beginning of the
+	 * source until it reaches its end.
+	 * If the given source is <code>null</code>, this clears the source.
+	 *
+	 * @param source the given source
+	 */
+	void setSource(char[] source);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java
new file mode 100644
index 0000000..8944828
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+/**
+ * Maps each terminal symbol in the java-grammar into a unique integer.
+ * This integer is used to represent the terminal when computing a parsing action.
+ *
+ * @see IScanner
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ITerminalSymbols {
+
+	int TokenNameWHITESPACE = 1000;
+	int TokenNameCOMMENT_LINE = 1001;
+	int TokenNameCOMMENT_BLOCK = 1002;
+	int TokenNameCOMMENT_JAVADOC = 1003;
+
+	int TokenNameIdentifier = 5;
+	int TokenNameabstract = 98;
+
+    /**
+     * "assert" token (added in J2SE 1.4).
+     */
+	int TokenNameassert = 118;
+	int TokenNameboolean = 18;
+	int TokenNamebreak = 119;
+	int TokenNamebyte = 19;
+	int TokenNamecase = 211;
+	int TokenNamecatch = 225;
+	int TokenNamechar = 20;
+	int TokenNameclass = 165;
+	int TokenNamecontinue = 120;
+	int TokenNamedefault = 212;
+	int TokenNamedo = 121;
+	int TokenNamedouble = 21;
+	int TokenNameelse = 213;
+	int TokenNameextends = 243;
+	int TokenNamefalse = 37;
+	int TokenNamefinal = 99;
+	int TokenNamefinally = 226;
+	int TokenNamefloat = 22;
+	int TokenNamefor = 122;
+	int TokenNameif = 123;
+	int TokenNameimplements = 268;
+	int TokenNameimport = 191;
+	int TokenNameinstanceof = 65;
+	int TokenNameint = 23;
+	int TokenNameinterface = 180;
+	int TokenNamelong = 24;
+	int TokenNamenative = 100;
+	int TokenNamenew = 32;
+	int TokenNamenull = 38;
+	int TokenNamepackage = 214;
+	int TokenNameprivate = 101;
+	int TokenNameprotected = 102;
+	int TokenNamepublic = 103;
+	int TokenNamereturn = 124;
+	int TokenNameshort = 25;
+	int TokenNamestatic = 94;
+	int TokenNamestrictfp = 104;
+	int TokenNamesuper = 33;
+	int TokenNameswitch = 125;
+	int TokenNamesynchronized = 85;
+	int TokenNamethis = 34;
+	int TokenNamethrow = 126;
+	int TokenNamethrows = 227;
+	int TokenNametransient = 105;
+	int TokenNametrue = 39;
+	int TokenNametry = 127;
+	int TokenNamevoid = 26;
+	int TokenNamevolatile = 106;
+	int TokenNamewhile = 117;
+	int TokenNameIntegerLiteral = 40;
+	int TokenNameLongLiteral = 41;
+	int TokenNameFloatingPointLiteral = 42;
+	int TokenNameDoubleLiteral = 43;
+	int TokenNameCharacterLiteral = 44;
+	int TokenNameStringLiteral = 45;
+	int TokenNamePLUS_PLUS = 1;
+	int TokenNameMINUS_MINUS = 2;
+	int TokenNameEQUAL_EQUAL = 35;
+	int TokenNameLESS_EQUAL = 66;
+	int TokenNameGREATER_EQUAL = 67;
+	int TokenNameNOT_EQUAL = 36;
+	int TokenNameLEFT_SHIFT = 14;
+	int TokenNameRIGHT_SHIFT = 11;
+	int TokenNameUNSIGNED_RIGHT_SHIFT = 12;
+	int TokenNamePLUS_EQUAL = 168;
+	int TokenNameMINUS_EQUAL = 169;
+	int TokenNameMULTIPLY_EQUAL = 170;
+	int TokenNameDIVIDE_EQUAL = 171;
+	int TokenNameAND_EQUAL = 172;
+	int TokenNameOR_EQUAL = 173;
+	int TokenNameXOR_EQUAL = 174;
+	int TokenNameREMAINDER_EQUAL = 175;
+	int TokenNameLEFT_SHIFT_EQUAL = 176;
+	int TokenNameRIGHT_SHIFT_EQUAL = 177;
+	int TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 178;
+	int TokenNameOR_OR = 80;
+	int TokenNameAND_AND = 79;
+	int TokenNamePLUS = 3;
+	int TokenNameMINUS = 4;
+	int TokenNameNOT = 71;
+	int TokenNameREMAINDER = 9;
+	int TokenNameXOR = 63;
+	int TokenNameAND = 62;
+	int TokenNameMULTIPLY = 8;
+	int TokenNameOR = 70;
+	int TokenNameTWIDDLE = 72;
+	int TokenNameDIVIDE = 10;
+	int TokenNameGREATER = 68;
+	int TokenNameLESS = 69;
+	int TokenNameLPAREN = 7;
+	int TokenNameRPAREN = 86;
+	int TokenNameLBRACE = 110;
+	int TokenNameRBRACE = 95;
+	int TokenNameLBRACKET = 15;
+	int TokenNameRBRACKET = 166;
+	int TokenNameSEMICOLON = 64;
+	int TokenNameQUESTION = 81;
+	int TokenNameCOLON = 154;
+	int TokenNameCOMMA = 90;
+	int TokenNameDOT = 6;
+	int TokenNameEQUAL = 167;
+	int TokenNameEOF = 158;
+	int TokenNameERROR = 309;
+
+    /**
+     * "enum" keyword (added in J2SE 1.5).
+     * @since 3.0
+     */
+	int TokenNameenum = 400;
+
+    /**
+     * "@" token (added in J2SE 1.5).
+     * @since 3.0
+     */
+	int TokenNameAT = 401;
+
+    /**
+     * "..." token (added in J2SE 1.5).
+     * @since 3.0
+     */
+	int TokenNameELLIPSIS = 402;
+
+	/**
+	 * @since 3.1
+	 */
+	int TokenNameconst = 403;
+
+	/**
+	 * @since 3.1
+	 */
+	int TokenNamegoto = 404;  // goto not found in Java ? :)
+
+	/**
+	 * @since 3.9 BETA_JAVA8
+	 */
+	int TokenNameARROW = 405;
+	/**
+	 * @since 3.9 BETA_JAVA8
+	 */
+	int TokenNameCOLON_COLON = 406;
+	
+	
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ReconcileContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ReconcileContext.java
new file mode 100644
index 0000000..34dba48
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ReconcileContext.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    mkaufman@bea.com - initial API and implementation
+ *    IBM - renamed from PreReconcileCompilationResult to ReconcileContext
+ *    IBM - rewrote spec
+ *
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.compiler;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation;
+
+/**
+ * The context of a reconcile event that is notified to interested compilation
+ * participants while a reconcile operation is running.
+ * <p>
+ * A reconcile participant can get the AST for the reconcile-operation using
+ * {@link #getAST4()}. If the participant modifies in any way the AST
+ * (either by modifying the source of the working copy, or modifying another entity
+ * that would result in different bindings for the AST), it is expected to reset the
+ * AST in the context using {@link #resetAST()}.
+ * </p><p>
+ * A reconcile participant can also create and return problems using
+ * {@link #putProblems(String, CategorizedProblem[])}. These problems are then reported
+ * to the problem requestor of the reconcile operation.
+ * </p>
+ *
+ * @see CompilationParticipant#reconcile(ReconcileContext)
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ReconcileContext {
+
+	private ReconcileWorkingCopyOperation operation;
+	private CompilationUnit workingCopy;
+
+/**
+ * Creates a reconcile context for the given reconcile operation.
+ *
+ * @param operation the reconcile operation
+ * @noreference This constructor is not intended to be called by clients.
+ */
+public ReconcileContext(ReconcileWorkingCopyOperation operation, CompilationUnit workingCopy) {
+	this.operation = operation;
+	this.workingCopy = workingCopy;
+}
+
+/**
+ * Returns a resolved AST with {@link AST#JLS3 JLS3} level.
+ * It is created from the current state of the working copy.
+ * Creates one if none exists yet.
+ * Returns <code>null</code> if the current state of the working copy
+ * doesn't allow the AST to be created (e.g. if the working copy's content
+ * cannot be parsed).
+ * <p>
+ * If the AST level requested during reconciling is not {@link AST#JLS3}
+ * or if binding resolutions was not requested, then a different AST is created.
+ * Note that this AST does not become the current AST and it is only valid for
+ * the requestor.
+ * </p>
+ *
+ * @return the AST created from the current state of the working copy,
+ *   or <code>null</code> if none could be created
+ * @exception JavaModelException  if the contents of the working copy
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @deprecated JLS3 has been deprecated. This method has been replaced by {@link #getAST4()} which returns an AST
+ * with JLS4 level.
+ */
+public org.eclipse.jdt.core.dom.CompilationUnit getAST3() throws JavaModelException {
+	if (this.operation.astLevel != AST.JLS3 || !this.operation.resolveBindings) {
+		// create AST (optionally resolving bindings)
+		ASTParser parser = ASTParser.newParser(AST.JLS3);
+		parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true));
+		if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject()))
+			parser.setResolveBindings(true);
+		parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+		parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0);
+		parser.setSource(this.workingCopy);
+		parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0);
+		return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor);
+	}
+	return this.operation.makeConsistent(this.workingCopy);
+}
+/**
+ * Returns a resolved AST with {@link AST#JLS4 JLS4} level.
+ * It is created from the current state of the working copy.
+ * Creates one if none exists yet.
+ * Returns <code>null</code> if the current state of the working copy
+ * doesn't allow the AST to be created (e.g. if the working copy's content
+ * cannot be parsed).
+ * <p>
+ * If the AST level requested during reconciling is not {@link AST#JLS4}
+ * or if binding resolutions was not requested, then a different AST is created.
+ * Note that this AST does not become the current AST and it is only valid for
+ * the requestor.
+ * </p>
+ *
+ * @return the AST created from the current state of the working copy,
+ *   or <code>null</code> if none could be created
+ * @exception JavaModelException  if the contents of the working copy
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @deprecated JLS4 has been deprecated. This method has been replaced by {@link #getAST8()} which returns an AST
+ * with JLS8 level.
+ * @since 3.7.1
+ */
+public org.eclipse.jdt.core.dom.CompilationUnit getAST4() throws JavaModelException {
+	if (this.operation.astLevel != AST.JLS4 || !this.operation.resolveBindings) {
+		// create AST (optionally resolving bindings)
+		ASTParser parser = ASTParser.newParser(AST.JLS4);
+		parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true));
+		if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject()))
+			parser.setResolveBindings(true);
+		parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+		parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0);
+		parser.setSource(this.workingCopy);
+		parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0);
+		return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor);
+	}
+	return this.operation.makeConsistent(this.workingCopy);
+}
+/**
+ * Returns a resolved AST with {@link AST#JLS8 JLS8} level.
+ * It is created from the current state of the working copy.
+ * Creates one if none exists yet.
+ * Returns <code>null</code> if the current state of the working copy
+ * doesn't allow the AST to be created (e.g. if the working copy's content
+ * cannot be parsed).
+ * <p>
+ * If the AST level requested during reconciling is not {@link AST#JLS8}
+ * or if binding resolutions was not requested, then a different AST is created.
+ * Note that this AST does not become the current AST and it is only valid for
+ * the requestor.
+ * </p>
+ *
+ * @return the AST created from the current state of the working copy,
+ *   or <code>null</code> if none could be created
+ * @exception JavaModelException  if the contents of the working copy
+ *		cannot be accessed. Reasons include:
+ * <ul>
+ * <li> The working copy does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * </ul>
+ * @since 3.9 BETA_JAVA8
+ */
+public org.eclipse.jdt.core.dom.CompilationUnit getAST8() throws JavaModelException {
+	if (this.operation.astLevel != AST.JLS8 || !this.operation.resolveBindings) {
+		// create AST (optionally resolving bindings)
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setCompilerOptions(this.workingCopy.getJavaProject().getOptions(true));
+		if (JavaProject.hasJavaNature(this.workingCopy.getJavaProject().getProject()))
+			parser.setResolveBindings(true);
+		parser.setStatementsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+		parser.setBindingsRecovery((this.operation.reconcileFlags & ICompilationUnit.ENABLE_BINDINGS_RECOVERY) != 0);
+		parser.setSource(this.workingCopy);
+		parser.setIgnoreMethodBodies((this.operation.reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0);
+		return (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(this.operation.progressMonitor);
+	}
+	return this.operation.makeConsistent(this.workingCopy);
+}
+
+/**
+ * Returns the AST level requested by the reconcile operation.
+ * It is either {@link ICompilationUnit#NO_AST}, or one of the JLS constants defined on {@link AST}.
+ *
+ * @return the AST level requested by the reconcile operation
+ */
+public int getASTLevel() {
+	return this.operation.astLevel;
+}
+
+/**
+ * Returns whether the reconcile operation is resolving bindings.
+ *
+ * @return whether the reconcile operation is resolving bindings
+ */
+public boolean isResolvingBindings() {
+	return this.operation.resolveBindings;
+}
+/**
+ * Returns the reconcile flag of this context. This flag is a bitwise value of the constant defined
+ * in {@link ICompilationUnit}.
+ *
+ * @return the reconcile flag of this context
+ * @since 3.6
+ *
+ * @see ICompilationUnit#ENABLE_BINDINGS_RECOVERY
+ * @see ICompilationUnit#ENABLE_STATEMENTS_RECOVERY
+ * @see ICompilationUnit#IGNORE_METHOD_BODIES
+ */
+public int getReconcileFlags() {
+	return this.operation.reconcileFlags;
+}
+/**
+ * Returns the delta describing the change to the working copy being reconciled.
+ * Returns <code>null</code> if there is no change.
+ * Note that the delta's AST is not yet positioned at this stage. Use {@link #getAST4()}
+ * to get the current AST.
+ *
+ * @return the delta describing the change, or <code>null</code> if none
+ */
+public IJavaElementDelta getDelta() {
+	return this.operation.deltaBuilder.delta;
+}
+
+/**
+ * Returns the problems to be reported to the problem requestor of the reconcile operation
+ * for the given marker type.
+ * Returns <code>null</code> if no problems need to be reported for this marker type.
+ *
+ * @param markerType the given marker type
+ * @return problems to be reported to the problem requestor
+ */
+public CategorizedProblem[] getProblems(String markerType) {
+	if (this.operation.problems == null) return null;
+	return (CategorizedProblem[]) this.operation.problems.get(markerType);
+}
+
+/**
+ * Returns the working copy this context refers to.
+ *
+ * @return the working copy this context refers to
+ */
+public ICompilationUnit getWorkingCopy() {
+	return this.workingCopy;
+}
+
+/**
+ * Resets the AST carried by this context.
+ * A compilation participant that modifies the environment that would result in different
+ * bindings for the AST is expected to reset the AST on this context, so that other
+ * participants don't get a stale AST.
+ * <p>
+ * Note that resetting the AST will not restart the reconcile process. Only further
+ * participants will see the new AST. Thus participants running before the one that
+ * resets the AST will have a stale view of the AST and its problems. Use
+ * the compilation participant extension point to order the participants.
+ * </p>
+ */
+public void resetAST() {
+	this.operation.ast = null;
+	putProblems(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, null);
+	putProblems(IJavaModelMarker.TASK_MARKER, null);
+}
+
+/**
+ * Sets the problems to be reported to the problem requestor of the reconcile operation
+ * for the given marker type.
+ * <code>null</code> indicates that no problems need to be reported.
+ * <p>
+ * Using this functionality, a participant that resolves problems for a given marker type
+ * can hide those problems since they don't exist any longer.
+ * </p>
+ *
+ * @param markerType the marker type of the given problems
+ * @param problems  the problems to be reported to the problem requestor of the reconcile operation,
+ *   or <code>null</code> if none
+ */
+public void putProblems(String markerType, CategorizedProblem[] problems) {
+	if (this.operation.problems == null)
+		this.operation.problems = new HashMap();
+	this.operation.problems.put(markerType, problems);
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java
new file mode 100644
index 0000000..e4a7a87
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.eval;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jdt.internal.eval.EvaluationConstants;
+
+/**
+ * A code snippet requestor implements a callback interface for installing
+ * the class files for a code snippet on the target and running it.
+ * In addition, it receives compilation problems detected during code snippet
+ * compilation.
+ * <p>
+ * Clients may implement this interface to provide a bridge a running Java VM.
+ * </p>
+ *
+ * @see IEvaluationContext#evaluateCodeSnippet(String, ICodeSnippetRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ * @see IEvaluationContext#evaluateCodeSnippet(String, String[], String[], int[], org.eclipse.jdt.core.IType, boolean, boolean, ICodeSnippetRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public interface ICodeSnippetRequestor {
+
+	/**
+	 * The prefix of fields that represent the local variables in a snippet
+	 * class.
+	 */
+	public static final String LOCAL_VAR_PREFIX = new String(EvaluationConstants.LOCAL_VAR_PREFIX);
+
+	/**
+	 * The name of the field that represent 'this' in a snippet class
+	 * instance.
+	 */
+	public static final String DELEGATE_THIS = new String(EvaluationConstants.DELEGATE_THIS);
+
+	/**
+	 * The name of the instance method in the snippet class that runs the code
+	 * snippet.
+	 */
+	public static final String RUN_METHOD = EvaluationConstants.RUN_METHOD;
+
+	/**
+	 * The name of the field (of type <code>java.lang.Object</code>) on the code
+	 * snippet instance that contains the returned value.
+	 */
+	public static final String RESULT_VALUE_FIELD = EvaluationConstants.RESULT_VALUE_FIELD;
+
+	/**
+	 * The field of type java.lang.Class on the code snippet instance that contains the type of the returned value.
+	 * The name of the field (of type <code>java.lang.Class</code>) on the code
+	 * snippet instance that contains the runtime type of the returned value.
+	 */
+	public static final String RESULT_TYPE_FIELD = EvaluationConstants.RESULT_TYPE_FIELD;
+
+	/*
+	 * REPORTING A PROBLEM OF COMPILATION IN THE CODE SNIPPET
+	 */
+
+	/**
+	 * Indicates a compilation problem related to a global variable.
+	 * <p>
+	 * Note: if the problem is on the type of the variable, the marker
+	 * source line number is -1; if the name of the variable, line number is 0;
+	 * otherwise, the marker source line number is relative to the initializer
+	 * code.
+	 * </p>
+	 *
+	 * @see #acceptProblem(IMarker, String, int)
+	 */
+	public static final int VARIABLE = 1;
+
+	/**
+	 * Indicates a compilation problem related to a code snippet.
+	 *
+	 * @see #acceptProblem(IMarker, String, int)
+	 */
+	public static final int CODE_SNIPPET = 2;
+
+	/**
+	 * Indicates a compilation problem related to an import declaration.
+	 *
+	 * @see #acceptProblem(IMarker, String, int)
+	 */
+	public static final int IMPORT = 3;
+
+	/**
+	 * Indicates a compilation problem related to a package declaration.
+	 *
+	 * @see #acceptProblem(IMarker, String, int)
+	 */
+	public static final int PACKAGE = 4;
+
+	/**
+	 * Indicates an internal problem.
+	 *
+	 * @see #acceptProblem(IMarker, String, int)
+	 */
+	public static final int INTERNAL = 5;
+/**
+ * Sends the given class files to the target and loads them. If the given
+ * class name is not <code>null</code>, run the code snippet with this class
+ * name. Returns whether the code snippet could be deployed. Note it must
+ * return <code>true</code> even if running the code snippet threw an exception.
+ * <p>
+ * The details of sending and loading the class files are left up to
+ * implementations.
+ * </p>
+ * <p>
+ * To run a code snippet, an implementation should create a new instance of
+ * the given code snippet class and call (directly or using another means) its
+ * <code>RUN_METHOD</code>.
+ * </p>
+ * <p>
+ * Also before the call, the implementation should copy the values of the local
+ * variables (if any) into the corresponding fields of the code snippet instance.
+ * A field name is formed of <code>LOCAL_VAR_PREFIX</code>
+ * preceded the name of the local variable. For example, the field name for
+ * local variable <code>"myLocal"</code> is <code>"val$myLocal"</code> (assuming the
+ * value of <code>LOCAL_VAR_PREFIX</code> is "val$"). In the
+ * same way, the implementation should copy the value of the 'this' object into the
+ * field called <code>DELEGATE_THIS</code>.
+ * </p>
+ * <p>
+ * After calling the <code>RUN_METHOD</code>, the values of the local
+ * variables may have been modified. The implementation must copy the
+ * values of the fields back into the local variables.
+ * </p>
+ * <p>
+ * Finally, the overall value returned by the code snippet can be retrieved
+ * from the special field <code>RESULT_VALUE_FIELD</code>
+ * on the code snippet instance.
+ * The <code>Class</code> that is the runtime type of the returned value can be
+ * retrieved from the special field <code>RESULT_TYPE_FIELD</code>.
+ * </p>
+ *
+ * @param classFileBytes the list of class file bytes
+ * @param classFileCompoundNames the corresponding list of class file type
+ *   compound names (example of a compound name: {"java", "lang", "Object"})
+ * @param codeSnippetClassName name of the actual class to instantiate and run,
+ *   or <code>null</code> if none
+ * @return <code>true</code> if the code snippet was successfully deployed
+ */
+public boolean acceptClassFiles(byte[][] classFileBytes, String[][] classFileCompoundNames, String codeSnippetClassName);
+/**
+ * Notifies of an evaluation problem.
+ * Problems can arise for source of the following kinds:
+ * <p>
+ * <ul>
+ *   <li>global variable (<code>VARIABLE</code>) - fragment source is name of
+ *     variable</li>
+ *   <li>code snippet (<code>CODE_SNIPPET</code>) - fragment source is code
+ *     snippet</li>
+ *   <li>import declaration (<code>IMPORT</code>) - fragment source is
+ *     import</li>
+ *   <li>package declaration (<code>PACKAGE</code>) - fragment source is
+ *     package declaration</li>
+ *   <li>other (<code>INTERNAL</code>) - no fragment source is involved, internal error occurred.</li>
+ * </ul>
+ * </p>
+ * @param problemMarker the problem marker (cannot be null)
+ * @param fragmentSource the fragment source
+ * @param fragmentKind the kind of source fragment; one of:
+ *   <code>VARIABLE</code>, <code>CODE_SNIPPET</code>, <code>IMPORT</code>,
+ *   <code>PACKAGE</code>, or <code>INTERNAL</code>
+ */
+public void acceptProblem(IMarker problemMarker, String fragmentSource, int fragmentKind);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
new file mode 100644
index 0000000..42ff349
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
@@ -0,0 +1,567 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.eval;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * An evaluation context supports evaluating code snippets.
+ * <p>
+ * A code snippet is pretty much any valid piece of Java code that could be
+ * pasted into the body of a method and compiled. However, there are two
+ * areas where the rules are slightly more liberal.
+ * <p>
+ * First, a code snippet can return heterogeneous types. Inside the same code
+ * snippet an <code>int</code> could be returned on one line, and a
+ * <code>String</code> on the next, etc. For example, the following would be
+ * considered a valid code snippet:
+ * <pre>
+ * <code>
+ * char c = '3';
+ * switch (c) {
+ *   case '1': return 1;
+ *   case '2': return '2';
+ *   case '3': return "3";
+ *   default: return null;
+ * }
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * Second, if the last statement is only an expression, the <code>return</code>
+ * keyword is implied. For example, the following returns <code>false</code>:
+ * <pre>
+ * <code>
+ * int i = 1;
+ * i == 2
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * Global variables are an additional feature of evaluation contexts. Within an
+ * evaluation context, global variables maintain their value across evaluations.
+ * These variables are particularly useful for storing the result of an
+ * evaluation for use in subsequent evaluations.
+ * </p>
+ * <p>
+ * The evaluation context remembers the name of the package in which code
+ * snippets are run. The user can set this to any package, thereby gaining
+ * access to types that are normally only visible within that package.
+ * </p>
+ * <p>
+ * Finally, the evaluation context remembers a list of import declarations. The
+ * user can import any packages and types so that the code snippets may refer
+ * to types by their shorter simple names.
+ * </p>
+ * <p>
+ * Example of use:
+ * <pre>
+ * <code>
+ * IJavaProject project = getJavaProject();
+ * IEvaluationContext context = project.newEvaluationContext();
+ * String codeSnippet = "int i= 0; i++";
+ * ICodeSnippetRequestor requestor = ...;
+ * context.evaluateCodeSnippet(codeSnippet, requestor, progressMonitor);
+ * </code>
+ * </pre>
+ * </p>
+ * <p>
+ * <code>IJavaProject.newEvaluationContext</code> can be used to obtain an
+ * instance.
+ * </p>
+ *
+ * @see IJavaProject#newEvaluationContext()
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IEvaluationContext {
+	/**
+	 * Returns the global variables declared in this evaluation context.
+	 * The variables are maintained in the order they are created in.
+	 *
+	 * @return the list of global variables
+	 */
+	public IGlobalVariable[] allVariables();
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 2.0
+	 * @deprecated Use {@link #codeComplete(String,int,CompletionRequestor)} instead.
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		ICompletionRequestor requestor)
+		throws JavaModelException;
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 3.0
+	 * @deprecated Use {@link #codeComplete(String,int,CompletionRequestor,WorkingCopyOwner)} instead.
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		ICompletionRequestor requestor,
+		WorkingCopyOwner owner)
+		throws JavaModelException;
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 3.1
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor)
+		throws JavaModelException;
+	
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         fEndTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 3.5
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+	
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 3.1
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner)
+		throws JavaModelException;
+	
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 * <p>
+	 * If {@link IProgressMonitor} is not <code>null</code> then some proposals which
+	 * can be very long to compute are proposed. To avoid that the code assist operation
+	 * take too much time a {@link IProgressMonitor} which automatically cancel the code
+	 * assist operation when a specified amount of time is reached could be used.
+	 * 
+	 * <pre>
+	 * new IProgressMonitor() {
+	 *     private final static int TIMEOUT = 500; //ms
+	 *     private long endTime;
+	 *     public void beginTask(String name, int totalWork) {
+	 *         fEndTime= System.currentTimeMillis() + TIMEOUT;
+	 *     }
+	 *     public boolean isCanceled() {
+	 *         return endTime <= System.currentTimeMillis();
+	 *     }
+	 *     ...
+	 * };
+	 * </pre>
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @since 3.5
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+	
+	/**
+	 * Resolves and returns a collection of Java elements corresponding to the source
+	 * code at the given positions in the given code snippet.
+	 * <p>
+	 * Note that code select does not involve evaluation, and problems are never
+	 * reported.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to resolve in
+	 * @param offset the position in the code snippet of the first character
+	 *   of the code to resolve
+	 * @param length the length of the selected code to resolve
+	 * @return the (possibly empty) list of selection Java elements
+	 * @exception JavaModelException if code resolve could not be performed.
+	 *   Reasons include:
+	 *   <ul>
+	 *	   <li>The position specified is less than -1 or is greater than the snippet's
+	 *	     length (INDEX_OUT_OF_BOUNDS)</li>
+	 *   </ul>
+	 */
+	public IJavaElement[] codeSelect(String codeSnippet, int offset, int length)
+		throws JavaModelException;
+	/**
+	 * Resolves and returns a collection of Java elements corresponding to the source
+	 * code at the given positions in the given code snippet.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * </p>
+	 * <p>
+	 * Note that code select does not involve evaluation, and problems are never
+	 * reported.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to resolve in
+	 * @param offset the position in the code snippet of the first character
+	 *   of the code to resolve
+	 * @param length the length of the selected code to resolve
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @return the (possibly empty) list of selection Java elements
+	 * @exception JavaModelException if code resolve could not be performed.
+	 *   Reasons include:
+	 *   <ul>
+	 *	   <li>The position specified is less than -1 or is greater than the snippet's
+	 *	     length (INDEX_OUT_OF_BOUNDS)</li>
+	 *   </ul>
+	 * @since 3.0
+	 */
+	public IJavaElement[] codeSelect(String codeSnippet, int offset, int length, WorkingCopyOwner owner)
+		throws JavaModelException;
+	/**
+	 * Deletes the given variable from this evaluation context. Does nothing if
+	 * the given variable has already been deleted.
+	 *
+	 * @param variable the global variable
+	 */
+	public void deleteVariable(IGlobalVariable variable);
+	/**
+	 * Evaluates the given code snippet in the context of a suspended thread.
+	 * The code snippet is compiled along with this context's package declaration,
+	 * imports, and global variables. The given requestor's
+	 * <code>acceptProblem</code> method is called for each compilation problem that
+	 * is detected. Then the resulting class files are handed to the given
+	 * requestor's <code>acceptClassFiles</code> method to deploy and run.
+	 * <p>
+	 * The requestor is expected to:
+	 * <ol>
+	 *   <li>send the class files to the target VM,
+	 *   <li>load them (starting with the code snippet class),
+	 *   <li>create a new instance of the code snippet class,
+	 *   <li>run the method <code>run()</code> of the code snippet,
+	 *   <li>retrieve the values of the local variables,
+	 *   <li>retrieve the returned value of the code snippet
+	 * </ol>
+	 * </p>
+	 * <p>
+	 * This method is long-running; progress and cancellation are provided
+	 * by the given progress monitor.
+	 * </p>
+	 *
+	 * @param codeSnippet the code snippet
+	 * @param localVariableTypeNames the dot-separated fully qualified names of the types of the local variables.
+	 * @param localVariableNames the names of the local variables as they are declared in the user's code.
+	 * @param localVariableModifiers the modifiers of the local variables (default modifier or final modifier).
+	 * @param declaringType the type in which the code snippet is evaluated.
+	 * @param isStatic whether the code snippet is evaluated in a static member of the declaring type.
+	 * @param isConstructorCall whether the code snippet is evaluated in a constructor of the declaring type.
+	 * @param requestor the code snippet requestor
+	 * @param progressMonitor a progress monitor
+	 * @exception JavaModelException if a runtime problem occurred or if this
+	 *   context's project has no build state
+	 */
+	public void evaluateCodeSnippet(
+		String codeSnippet,
+		String[] localVariableTypeNames,
+		String[] localVariableNames,
+		int[] localVariableModifiers,
+		IType declaringType,
+		boolean isStatic,
+		boolean isConstructorCall,
+		ICodeSnippetRequestor requestor,
+		IProgressMonitor progressMonitor)
+		throws JavaModelException;
+	/**
+	 * Evaluates the given code snippet. The code snippet is
+	 * compiled along with this context's package declaration, imports, and
+	 * global variables. The given requestor's <code>acceptProblem</code> method
+	 * is called for each compilation problem that is detected. Then the resulting
+	 * class files are handed to the given requestor's <code>acceptClassFiles</code>
+	 * method to deploy and run. The requestor is also responsible for getting the
+	 * result back.
+	 * <p>
+	 * This method is long-running; progress and cancellation are provided
+	 * by the given progress monitor.
+	 * </p>
+	 *
+	 * @param codeSnippet the code snippet
+	 * @param requestor the code snippet requestor
+	 * @param progressMonitor a progress monitor
+	 * @exception JavaModelException if a runtime problem occurred or if this
+	 *   context's project has no build state
+	 */
+	public void evaluateCodeSnippet(
+		String codeSnippet,
+		ICodeSnippetRequestor requestor,
+		IProgressMonitor progressMonitor)
+		throws JavaModelException;
+	/**
+	 * Evaluates the given global variable. During this operation,
+	 * this context's package declaration, imports, and <i>all</i> its declared
+	 * variables are verified. The given requestor's <code>acceptProblem</code>
+	 * method will be called for each problem that is detected.
+	 * <p>
+	 * This method is long-running; progress and cancellation are provided
+	 * by the given progress monitor.
+	 * </p>
+	 *
+	 * @param variable the global variable
+	 * @param requestor the code snippet requestor
+	 * @param progressMonitor a progress monitor
+	 * @exception JavaModelException if a runtime problem occurred or if this
+	 *   context's project has no build state
+	 */
+	public void evaluateVariable(
+		IGlobalVariable variable,
+		ICodeSnippetRequestor requestor,
+		IProgressMonitor progressMonitor)
+		throws JavaModelException;
+	/**
+	 * Returns the import declarations for this evaluation context. Returns and empty
+	 * list if there are no imports (the default if the imports have never been set).
+	 * The syntax for the import corresponds to a fully qualified type name, or to
+	 * an on-demand package name as defined by ImportDeclaration (JLS2 7.5). For
+	 * example, <code>"java.util.Hashtable"</code> or <code>"java.util.*"</code>.
+	 *
+	 * @return the list of import names
+	 */
+	public String[] getImports();
+	/**
+	 * Returns the name of the package in which code snippets are to be compiled and
+	 * run. Returns an empty string for the default package (the default if the
+	 * package name has never been set). For example, <code>"com.example.myapp"</code>.
+	 *
+	 * @return the dot-separated package name, or the empty string indicating the
+	 *   default package
+	 */
+	public String getPackageName();
+	/**
+	 * Returns the Java project this evaluation context was created for.
+	 *
+	 * @return the Java project
+	 */
+	public IJavaProject getProject();
+	/**
+	 * Creates a new global variable with the given name, type, and initializer.
+	 * <p>
+	 * The <code>typeName</code> and <code>initializer</code> are interpreted in
+	 * the context of this context's package and import declarations.
+	 * </p>
+	* <p>
+	 * The syntax for a type name corresponds to Type in Field Declaration (JLS2 8.3).
+	 * </p>
+	 *
+	 * @param typeName the type name
+	 * @param name the name of the global variable
+	 * @param initializer the initializer expression, or <code>null</code> if the
+	 *   variable is not initialized
+	 * @return a new global variable with the given name, type, and initializer
+	 */
+	public IGlobalVariable newVariable(
+		String typeName,
+		String name,
+		String initializer);
+	/**
+	 * Sets the import declarations for this evaluation context. An empty
+	 * list indicates there are no imports. The syntax for the import corresponds to a
+	 * fully qualified type name, or to an on-demand package name as defined by
+	 * ImportDeclaration (JLS2 7.5). For example, <code>"java.util.Hashtable"</code>
+	 * or <code>"java.util.*"</code>.
+	 *
+	 * @param imports the list of import names
+	 */
+	public void setImports(String[] imports);
+	/**
+	 * Sets the dot-separated name of the package in which code snippets are
+	 * to be compiled and run. For example, <code>"com.example.myapp"</code>.
+	 *
+	 * @param packageName the dot-separated package name, or the empty string
+	 *   indicating the default package
+	 */
+	public void setPackageName(String packageName);
+	/**
+	 * Validates this evaluation context's import declarations. The given requestor's
+	 * <code>acceptProblem</code> method is called for each problem that is detected.
+	 *
+	 * @param requestor the code snippet requestor
+	 * @exception JavaModelException if this context's project has no build state
+	 */
+	public void validateImports(ICodeSnippetRequestor requestor)
+		throws JavaModelException;
+
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * <p>
+	 * Note that code completion does not involve evaluation.
+	 * <p>
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  <ul>
+	 *	  <li>The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
+	 *  </ul>
+	 * @deprecated - use codeComplete(String, int, ICompletionRequestor) instead
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		org.eclipse.jdt.core.ICodeCompletionRequestor requestor)
+		throws JavaModelException;
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java
new file mode 100644
index 0000000..befd3c5
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.eval;
+
+/**
+ * A global variable declared in an evaluation context.
+ * <p><code>IEvaluationContext.newVariable</code> can be used to obtain an instance.
+ * </p>
+ *
+ * @see IEvaluationContext#newVariable(String, String, String)
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IGlobalVariable {
+/**
+ * Returns the initializer of this global variable.
+ * The syntax for an initializer corresponds to VariableInitializer (JLS2 8.3).
+ *
+ * @return the initializer expression, or <code>null</code> if this global does
+ *    not have an initializer
+ */
+public String getInitializer();
+/**
+ * Returns the name of this global variable.
+ *
+ * @return the name of the global variable
+ */
+public String getName();
+/**
+ * Returns the fully qualified name of the type of this global
+ * variable, or its simple representation if it is a primitive type
+ * (<code>int</code>, <code>boolean</code>, etc.).
+ * <p>
+ * The syntax for a type name corresponds to Type in Field Declaration (JLS2 8.3).
+ * </p>
+ * @return the type name
+ */
+public String getTypeName();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/package.html b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/package.html
new file mode 100644
index 0000000..0227f4f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/package.html
@@ -0,0 +1,17 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for the evaluation of code snippets
+in a scrapbook or inside the debugger.
+<h2>
+Package Specification</h2>
+This packages provides support for the evaluation of code snippets in a
+scrapbook or inside the debugger.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java
new file mode 100644
index 0000000..da844fb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Unchecked exception thrown when an illegal manipulation of the JDOM is
+ * performed, or when an attempt is made to access/set an attribute of a
+ * JDOM node that source indexes cannot be determined for (in case the source
+ * was syntactically incorrect).
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+public class DOMException extends RuntimeException {
+
+	private static final long serialVersionUID = 2536853590795032028L; // backward compatible
+/**
+ * Creates a new exception with no detail message.
+ */
+public DOMException() {
+	// just create a new DOMException with no detail message
+}
+/**
+ * Creates a new exception with the given detail message.
+ *
+ * @param message the detail message
+ */
+public DOMException(String message) {
+	super(message);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
new file mode 100644
index 0000000..729cd54
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+import org.eclipse.jdt.internal.core.jdom.*;
+
+/**
+ * Standard implementation of <code>IDOMFactory</code>, and the only means
+ * of creating JDOMs and document fragments.
+ * <p>
+ * This class may be instantiated.
+ * </p>
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DOMFactory implements IDOMFactory {
+	String lineSeparator;
+/**
+ * Creates a new DOM factory.
+ */
+public DOMFactory() {
+	// constructor is explicitly API
+	this.lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(null, null/*take the workspace line separator as no project is available*/);
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMCompilationUnit createCompilationUnit() {
+	return (new DOMBuilder()).createCompilationUnit();
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMCompilationUnit createCompilationUnit(char[] sourceCode, String name)  {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new SimpleDOMBuilder()).createCompilationUnit(sourceCode, name.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new SimpleDOMBuilder()).createCompilationUnit(sourceCode.toCharArray(), name.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMField createField() {
+	return createField("Object aField;"+ this.lineSeparator); //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMField createField(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createField(sourceCode.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMImport createImport() {
+	return (new DOMBuilder()).createImport();
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMImport createImport(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createImport(sourceCode.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMInitializer createInitializer() {
+	return createInitializer("static {}"+ this.lineSeparator); //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMInitializer createInitializer(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createInitializer(sourceCode.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMMethod createMethod() {
+	return createMethod("public void newMethod() {"+ this.lineSeparator+"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMMethod createMethod(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createMethod(sourceCode.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMPackage createPackage() {
+	return (new DOMBuilder()).createPackage();
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMPackage createPackage(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createPackage(sourceCode.toCharArray());
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMType createType() {
+	return createType("public class AClass {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMType createClass() {
+	return createType("public class AClass {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMType createInterface() {
+	return createType("public interface AnInterface {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
+}
+/* (non-Javadoc)
+ * Method declared on IDOMFactory.
+ */
+public IDOMType createType(String sourceCode) {
+	if(sourceCode == null) {
+		return null;
+	}
+	return (new DOMBuilder()).createType(sourceCode.toCharArray());
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java
new file mode 100644
index 0000000..8103d83
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents a Java compilation unit (source file with one of the
+ * {@link org.eclipse.jdt.core.JavaCore#getJavaLikeExtensions()
+ * Java-like extensions}).
+ * The corresponding syntactic unit is CompilationUnit (JLS2 7.3).
+ * Allowable child types for a compilation unit are <code>IDOMPackage</code>, <code>IDOMImport</code>,
+ * and <code>IDOMType</code>.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMCompilationUnit extends IDOMNode {
+/**
+ * Returns the header comment for this compilation unit. The header comment
+ * appears before the first declaration in a compilation unit.
+ * The syntax for a comment corresponds to Comments (JLS2 3.7), <b>including</b>
+ * comment delimiters.
+ *
+ * @return the header comment for this compilation unit, or <code>null</code> if
+ *   no header comment is present
+ */
+public String getHeader();
+/**
+ * The <code>IDOMCompilationNode</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this compilation unit.
+ *
+ * <p>The name of a compilation unit is the name of the first top-level public type
+ * defined in the compilation unit, suffixed with one of the
+ * {@link org.eclipse.jdt.core.JavaCore#getJavaLikeExtensions()
+ * Java-like extensions}. For example, if the first
+ * top-level public type defined in this compilation unit has the name "Hanoi",
+ * then name of this compilation unit is "Hanoi.java".</p>
+ *
+ * <p>In the absence of a public top-level type, the name of the first top-level
+ * type is used. In the absence of any type, the name of the compilation unit
+ * is <code>null</code>.</p>
+ *
+ * @return the name of this compilation unit, or <code>null</code> if none
+ */
+public String getName();
+/**
+ * Sets the header comment for this compilation unit. The header comment
+ * appears before the first declaration in a compilation unit.
+ * The syntax for a comment corresponds to Comments (JLS2 3.7), <b>including</b>
+ * comment delimiters.
+ *
+ * @param comment the header comment for this compilation unit, or <code>null</code> if
+ *   indicating no header comment
+ */
+public void setHeader(String comment);
+/**
+ * The <code>IDOMCompilationNode</code> refinement of this <code>IDOMNode</code>
+ * method has no effect (the name is computed from the types declared within it).
+ *
+ * @param name the given name
+ */
+public void setName(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java
new file mode 100644
index 0000000..c4b2d5c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * A factory used to create document fragment (DF) nodes. An
+ * <code>IDOMCompilationUnit</code> represents the root of a complete JDOM (that
+ * is, a source file with one of the
+ * {@link org.eclipse.jdt.core.JavaCore#getJavaLikeExtensions()
+ * Java-like extensions}). Other node types represent fragments of a compilation
+ * unit.
+ * <p>
+ * The factory can be used to create empty DFs or it can create DFs from source
+ * strings. All DFs created empty are assigned default values as required, such
+ * that a call to <code>IDOMNode.getContents</code> will generate a valid source
+ * string. See individual <code>create</code> methods for details on the default
+ * values supplied. The factory does its best to recognize Java structures in
+ * the source provided. If the factory is completely unable to recognize source
+ * constructs, the factory method returns <code>null</code>.
+ * </p>
+ * <p>
+ * Even if a DF is created successfully from source code, it does not guarantee
+ * that the source code will compile error free. Similarly, the contents of a DF
+ * are not guaranteed to compile error free. However, syntactically correct
+ * source code is guaranteed to be recognized and successfully generate a DF.
+ * Similarly, if all of the fragments of a JDOM are syntactically correct, the
+ * contents of the entire document will be correct too.
+ * </p>
+ * <p>
+ * The factory does not perform or provide any code formatting. Document
+ * fragments created on source strings must be pre-formatted. The JDOM attempts
+ * to maintain the formatting of documents as best as possible. For this reason,
+ * document fragments created for nodes that are to be strung together should
+ * end with a new-line character. Failing to do so will result in a document
+ * that has elements strung together on the same line. This is especially
+ * important if a source string ends with a // comment. In this case, it would
+ * be syntactically incorrect to omit the new line character.
+ * </p>
+ *
+ * @see IDOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMFactory {
+/**
+ * Creates and return an empty JDOM. The initial content is an empty string.
+ *
+ * @return the new compilation unit
+ */
+public IDOMCompilationUnit createCompilationUnit();
+/**
+ * Creates a JDOM on the given source code. The syntax for the given source
+ * code corresponds to CompilationUnit (JLS2 7.3).
+ *
+ * @param sourceCode the source code character array, or <code>null</code>
+ * @param name the name of the compilation unit
+ * @return the new compilation unit, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMCompilationUnit createCompilationUnit(char[] sourceCode, String name);
+/**
+ * Creates a JDOM on the given source code. The syntax for the given source
+ * code corresponds to CompilationUnit (JLS2 7.3).
+ *
+ * @param sourceCode the source code string, or <code>null</code>
+ * @param name the name of the compilation unit
+ * @return the new compilation unit, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name);
+/**
+ * Creates a default field document fragment. Initially the field will have
+ * default protection, type <code>"Object"</code>, name <code>"aField"</code>,
+ * no comment, and no initializer.
+ *
+ * @return the new field
+ */
+public IDOMField createField();
+/**
+ * Creates a field document fragment on the given source code. The given source
+ * string corresponds to FieldDeclaration (JLS2 8.3) and ConstantDeclaration
+ * (JLS2 9.3) restricted to a single VariableDeclarator clause.
+ *
+ * @param sourceCode the source code
+ * @return the new field, or <code>null</code> if unable to recognize
+ *   the source code, if the source code is <code>null</code>, or when the source
+ *   contains more than one VariableDeclarator clause
+ */
+public IDOMField createField(String sourceCode);
+/**
+ * Creates an empty import document fragment. Initially the import will have
+ * name <code>"java.lang.*"</code> and be non-static.
+ *
+ * @return the new import
+ */
+public IDOMImport createImport();
+/**
+ * Creates an import document fragment on the given source code. The syntax for
+ * the given source string corresponds to ImportDeclaration (JLS2 7.5).
+ *
+ * @param sourceCode the source code
+ * @return the new import, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMImport createImport(String sourceCode);
+/**
+ * Creates an empty initializer document fragment. Initially the initializer
+ * will be static and have no body or comment.
+ *
+ * @return the new initializer
+ */
+public IDOMInitializer createInitializer();
+/**
+ * Creates an initializer document fragment from the given source code. The
+ * syntax for the given source string corresponds to InstanceInitializer
+ * (JLS2 8.6) and StaticDeclaration (JLS2 8.7).
+ *
+ * @param sourceCode the source code
+ * @return the new initializer, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMInitializer createInitializer(String sourceCode);
+/**
+ * Creates a default method document fragment. Initially the method
+ * will have public visibility, return type <code>"void"</code>, be named
+ * <code>"newMethod"</code>, have no parameters, no comment, and an empty body.
+ *
+ * @return the new method
+ */
+public IDOMMethod createMethod();
+/**
+ * Creates a method document fragment on the given source code. The syntax for
+ * the given source string corresponds to MethodDeclaration (JLS2 8.4),
+ * ConstructorDeclaration (JLS2 8.8), and AbstractMethodDeclaration (JLS2 9.4).
+ *
+ * @param sourceCode the source code
+ * @return the new method, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMMethod createMethod(String sourceCode);
+/**
+ * Creates an empty package document fragment. Initially the package
+ * declaration will have no name.
+ *
+ * @return the new package
+ */
+public IDOMPackage createPackage();
+/**
+ * Creates a package document fragment on the given source code. The syntax for
+ * the given source string corresponds to PackageDeclaration (JLS2 7.4).
+ *
+ * @param sourceCode the source code
+ * @return the new package, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMPackage createPackage(String sourceCode);
+/**
+ * Creates a default type document fragment. Initially the type will be
+ * a public class named <code>"AClass"</code>, with no members or comment.
+ *
+ * @return the new type
+ */
+public IDOMType createType();
+/**
+ * Creates a default type document fragment. Initially the type will be
+ * a public class named <code>"AClass"</code>, with no members or comment.
+ *
+ * @return the new class
+ * @since 2.0
+ */
+public IDOMType createClass();
+/**
+ * Creates a default type document fragment. Initially the type will be
+ * a public interface named <code>"AnInterface"</code>, with no members or comment.
+ *
+ * @return the new interface
+ * @since 2.0
+ */
+public IDOMType createInterface();
+/**
+ * Creates a type document fragment on the given source code. The syntax for the
+ * given source string corresponds to ClassDeclaration (JLS2 8.1) and
+ * InterfaceDeclaration (JLS2 9.1).
+ *
+ * @param sourceCode the source code
+ * @return the new type, or <code>null</code> if unable to recognize
+ *   the source code, or if the source code is <code>null</code>
+ */
+public IDOMType createType(String sourceCode);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java
new file mode 100644
index 0000000..7227edb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents a field declaration. The corresponding
+ * syntactic units are FieldDeclaration (JLS2 8.3) and ConstantDeclaration
+ * (JLS2 9.3) restricted to a single VariableDeclarator clause.
+ * A field has no children. The parent of a field is a type.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMField extends IDOMMember {
+/**
+ * Returns the initializer expression for this field.
+ * The syntax for an initializer corresponds to VariableInitializer (JLS2 8.3).
+ * <p>
+ * Note: The expression does not include a "<code>=</code>".
+ * </p>
+ *
+ * @return the initializer expression, or <code>null</code> if this field does
+ *    not have an initializer
+ */
+public String getInitializer();
+/**
+ * The <code>IDOMField</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this field. The syntax for the name of a field
+ * corresponds to VariableDeclaratorId (JLS2 8.3).
+ *
+ * @return the name of this field
+ */
+public String getName();
+/**
+ * Returns the type name of this field. The syntax for a type name of a field
+ * corresponds to Type in Field Declaration (JLS2 8.3).
+ *
+ * @return the type name
+ */
+public String getType();
+/**
+ * Sets the initializer expression for this field.
+ * The syntax for an initializer corresponds to VariableInitializer (JLS2 8.3).
+ * <p>
+ * Note: The expression does not include a "<code>=</code>".
+ * </p>
+ *
+ * @param initializer the initializer expression, or <code>null</code> indicating
+ *   the field does not have an initializer
+ */
+public void setInitializer(String initializer);
+/**
+ * The <code>IDOMField</code> refinement of this <code>IDOMNode</code>
+ * method sets the name of this field. The syntax for the name of a field
+ * corresponds to VariableDeclaratorId (JLS2 8.3).
+ *
+ * @param name the given name
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setName(String name) throws IllegalArgumentException;
+/**
+ * Sets the type name of this field. The syntax for a type name of a field
+ * corresponds to Type in Field Declaration (JLS2 8.3). Type names must be
+ * specified as they should appear in source code. For example:
+ * <code>"String"</code>, <code>"int[]"</code>, or <code>"java.io.File"</code>.
+ *
+ * @param typeName the type name
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setType(String typeName) throws IllegalArgumentException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
new file mode 100644
index 0000000..f4dde12
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents an import declaration.
+ * The corresponding syntactic unit is ImportDeclaration (JLS2 7.5).
+ * An import has no children and its parent is a compilation unit.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMImport extends IDOMNode {
+/**
+ * The <code>IDOMImport</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this import. The syntax for an import name
+ * corresponds to a fully qualified type name, or to an on-demand package name
+ * as defined by ImportDeclaration (JLS2 7.5).
+ *
+ * @return  the name of this import
+ */
+public String getName();
+/**
+ * Returns whether this import declaration ends with <code>".*"</code>.
+ *
+ * @return <code>true</code> if this in an on-demand import
+ */
+public boolean isOnDemand();
+
+/**
+ * Returns the modifier flags for this import. The flags can be examined using class
+ * <code>Flags</code>. Only the static flag is meaningful for import declarations.
+ * @return the modifier flags for this import
+ * @see org.eclipse.jdt.core.Flags
+ * @since 3.0
+ */
+int getFlags();
+
+/**
+ * Sets the modifier flags for this import. The flags can be examined using class
+ * <code>Flags</code>. Only the static flag is meaningful for import declarations.
+ *
+ * @param flags the modifier flags for this import
+ * @see org.eclipse.jdt.core.Flags
+ * @since 3.0
+ */
+void setFlags(int flags);
+
+/**
+ * The <code>IDOMImport</code> refinement of this <code>IDOMNode</code>
+ * method sets the name of this import. The syntax for an import name
+ * corresponds to a fully qualified type name, or to an on-demand package name
+ * as defined by ImportDeclaration (JLS2 7.5).
+ *
+ * @param name the given name
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setName(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java
new file mode 100644
index 0000000..027f50c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents an initializer. The corresponding syntactic
+ * units are InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7).
+ * An initializer has no children and its parent is a type.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMInitializer extends IDOMMember {
+/**
+ * Returns the body of this initializer. The syntax for a body corresponds to
+ * InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7).
+ *
+ * @return an initializer body, including braces, or <code>null</code> if
+ *   no body is present
+ */
+public String getBody();
+/**
+ * The <code>IDOMInitializer</code> refinement of this <code>IDOMNode</code>
+ * method returns <code>null</code>. An initializer does not have a name.
+ *
+ * @return <code>null</code>
+ */
+public String getName();
+/**
+ * Sets the body of this initializer. The syntax for a body corresponds to
+ * InstanceInitializer (JLS2 8.6) and StaticDeclaration (JLS2 8.7). No formatting
+ * or syntax checking is performed on the body. Braces <b>must</b> be included.
+ *
+ * @param body an initializer body, including braces, or <code>null</code>
+ *   indicating no body
+ */
+public void setBody(String body);
+/**
+ * The <code>IDOMInitializer</code> refinement of this <code>IDOMNode</code>
+ * method does nothing.
+ *
+ * @param name the given name
+ */
+public void setName(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java
new file mode 100644
index 0000000..b5e9202
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * An <code>IDOMMember</code> defines functionality common to nodes, which
+ * can be members of types.
+ *
+ * @see IDOMType
+ * @see IDOMMethod
+ * @see IDOMField
+ * @see IDOMInitializer
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMMember extends IDOMNode {
+/**
+ * Returns the comment associated with this member (including comment delimiters).
+ *
+ * @return the comment, or <code>null</code> if this member has no associated
+ *   comment
+ */
+public String getComment();
+/**
+ * Returns the flags for this member. The flags can be examined using the
+ * <code>Flags</code> class.
+ *
+ * @return the flags
+ * @see org.eclipse.jdt.core.Flags
+ */
+public int getFlags();
+/**
+ * Sets the comment associated with this member. The comment will appear
+ * before the member in the source. The comment must be properly formatted, including
+ * delimiters. A <code>null</code> comment indicates no comment. This member's
+ * deprecated flag is automatically set to reflect the deprecated tag in the
+ * comment.
+ *
+ * @param comment the comment, including comment delimiters, or
+ *   <code>null</code> indicating this member should have no associated comment
+ * @see #setFlags(int)
+ */
+public void setComment(String comment);
+/**
+ * Sets the flags for this member. The flags can be examined using the
+ * <code>Flags</code> class. The deprecated flag passed in is ignored.
+ *
+ * @param flags the flags
+ * @see org.eclipse.jdt.core.Flags
+ */
+public void setFlags(int flags);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java
new file mode 100644
index 0000000..0df8267
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents a method declaration.
+ * The corresponding syntactic units are MethodDeclaration (JLS2 8.4),
+ * ConstructorDeclaration (JLS2 8.8), and AbstractMethodDeclaration (JLS2 9.4).
+ * A method has no children and its parent is a type.
+ * Local classes are considered to be part of the body of a method, not a child.
+ * Annotation type members, added in J2SE 1.5, are represented as methods.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMMethod extends IDOMMember {
+/**
+ * Adds the given exception to the end of the list of exceptions this method
+ * is declared to throw.
+ * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4).
+ * Type names must be specified as they would appear in source code. For
+ * example: <code>"IOException"</code> or <code>"java.io.IOException"</code>.
+ * This is a convenience method for <code>setExceptions</code>.
+ *
+ * @param exceptionType the exception type
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ * @see #setExceptions(String[])
+ */
+public void addException(String exceptionType) throws IllegalArgumentException;
+/**
+ * Adds the given parameter to the end of the parameter list.
+ * This is a convenience method for <code>setParameters</code>.
+ * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1).
+ * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1).
+ * Type names must be specified as they would appear in source code. For
+ * example: <code>"File"</code>, <code>"java.io.File"</code>, or
+ * <code>"int[]"</code>.
+ *
+ * @param type the type name
+ * @param name the parameter name
+ * @exception IllegalArgumentException if <code>null</code> is specified for
+ *   either the type or the name
+ * @see #setParameters(String[], String[])
+ */
+public void addParameter(String type, String name) throws IllegalArgumentException;
+/**
+ * Returns the body of this method. The method body includes all code following
+ * the method declaration, including the enclosing braces.
+ *
+ * @return the body, or <code>null</code> if the method has no body (for
+ *   example, for an abstract or native method)
+ */
+public String getBody();
+
+/**
+ * Sets the default value expression for an annotation type member.
+ *
+ * @param defaultValue the default value expression, or <code>null</code> indicating
+ *   the member does not have a default value
+ * @since 3.0
+ */
+public void setDefault(String defaultValue);
+
+/**
+ * Returns the default value expression for an annotation type member.
+ *
+ * @return the default value expression, or <code>null</code> indicating
+ *   the member does not have a default value
+ * @since 3.0
+ */
+public String getDefault();
+
+/**
+ * Returns the names of the exception types this method throws
+ * in the order in which they are declared in the source, or an empty array
+ * if this method declares no exception types.
+ * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4).
+ * Type names appear as they would in source code. For example:
+ * <code>"IOException"</code> or <code>"java.io.IOException"</code>.
+ *
+ * @return the list of exception types
+ */
+public String[] getExceptions();
+
+/**
+ * Returns the formal type parameters for this method.
+ * Returns an empty array if this method has no formal type parameters.
+ * <p>Formal type parameters are as they appear in the source
+ * code; for example:
+ * <code>"X extends List&lt;String&gt; & Serializable"</code>.
+ * </p>
+ *
+ * @return the formal type parameters of this method,
+ * in the order declared in the source, an empty array if none
+ * @since 3.0
+ */
+String[] getTypeParameters();
+
+/**
+ * The <code>IDOMMethod</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this method. Returns <code>null</code> for
+ * constructors. The syntax for a method  name is defined by Identifier
+ * of MethodDeclarator (JLS2 8.4).
+ *
+ * @return the name of this method or <code>null</code> for constructors
+ */
+public String getName();
+/**
+ * Returns the names of parameters in this method in the order they are declared,
+ * or <code>null</code> if no parameters are declared.
+ * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1).
+ *
+ * @return the list of parameter names, or <code>null</code> if no parameters
+ *  are declared
+ */
+public String[] getParameterNames();
+/**
+ * Returns the type names for the parameters of this method in the order they are declared,
+ * or <code>null</code> if no parameters are declared.
+ * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1).
+ * Type names must be specified as they would appear in source code. For
+ * example: <code>"File"</code>, <code>"java.io.File"</code>, or
+ * <code>"int[]"</code>.
+ *
+ * @return the list of parameter types, or <code>null</code> if no parameters
+ *  are declared
+ */
+public String[] getParameterTypes();
+/**
+ * Returns the return type name, or <code>null</code>.
+ * Returns <code>null</code> for constructors.
+ * The syntax for return type name corresponds to ReturnType in
+ * MethodDeclaration (JLS2 8.4). Names are returned as they appear in the source
+ * code; for example: <code>"File"</code>, <code>"java.io.File"</code>,
+ * <code>"int[]"</code>, or <code>"void"</code>.
+ *
+ * @return the return type
+ */
+public String getReturnType();
+
+/**
+ * Returns whether this method is a constructor.
+ *
+ * @return <code>true</code> for constructors, and <code>false</code> for methods
+ */
+public boolean isConstructor();
+
+/**
+ * Sets the body of this method. The method body includes all code following
+ * the method declaration, including the enclosing braces. No formatting or
+ * syntax checking is performed on the body.
+ *
+ * @param body the body, or <code>null</code> indicating the method has no body (for
+ *   example, for an abstract or native method)
+ */
+public void setBody(String body);
+/**
+ * Sets whether this method represents a constructor.
+ *
+ * @param b <code>true</code> for constructors, and <code>false</code> for methods
+ */
+public void setConstructor(boolean b);
+/**
+ * Sets the names of the exception types this method throws,
+ * in the order in which they are declared in the source. An empty array
+ * indicates this method declares no exception types.
+ * The syntax for an exception type name is defined by Method Throws (JLS2 8.4.4).
+ * Type names must be specified as they would appear in source code. For
+ * example: <code>"IOException"</code> or <code>"java.io.IOException"</code>.
+ *
+ * @param exceptionTypes the list of exception types
+ */
+public void setExceptions(String[] exceptionTypes);
+
+/**
+ * Sets the formal type parameters for this method.
+ * <p>Formal type parameters are given as they appear in the source
+ * code; for example:
+ * <code>"X extends List&lt;String&gt; & Serializable"</code>.
+ * </p>
+ *
+ * @param typeParameters the formal type parameters of this method,
+ * in the order to appear in the source, an empty array if none
+ * @since 3.0
+ */
+void setTypeParameters(String[] typeParameters);
+
+/**
+ * The <code>IDOMMethod</code> refinement of this <code>IDOMNode</code>
+ * method sets the name of this method. The syntax for a method
+ * name is defined by Identifer of MethodDeclarator (JLS2 8.4).
+ * <p>
+ * The name of a constructor is always <code>null</code> and thus it
+ * must not be set.
+ * </p>
+ *
+ * @param name the given name
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setName(String name) throws IllegalArgumentException;
+/**
+ * Sets the types and names of parameters in this method in the order they are
+ * to be declared. If both <code>types</code> and <code>names</code> are <code>null</code>
+ * this indicates that this method has no parameters.
+ * The syntax for parameter names is defined by Formal Parameters (JLS2 8.4.1).
+ * The syntax for type names is defined by Formal Parameters (JLS2 8.4.1).
+ * Type names must be specified as they would appear in source code. For
+ * example: <code>"File"</code>, <code>"java.io.File"</code>, or
+ * <code>"int[]"</code>.
+ *
+ * @param types the list of type names
+ * @param names the list of parameter name
+ * @exception IllegalArgumentException if the number of types and names do not
+ *   match, or if either argument is <code>null</code>
+ */
+public void setParameters(String[] types, String[] names) throws IllegalArgumentException;
+
+/**
+ * Sets the return type name. This has no effect on constructors.
+ * The syntax for return type name corresponds to ReturnType in
+ * MethodDeclaration (JLS2 8.4). Type names are specified as they appear in the
+ * source code; for example: <code>"File"</code>, <code>"java.io.File"</code>,
+ * <code>"int[]"</code>, or <code>"void"</code>.
+ *
+ * @param type the return type
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setReturnType(String type) throws IllegalArgumentException;
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java
new file mode 100644
index 0000000..d193095
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+import java.util.Enumeration;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * Nodes represent structural fragments of a Java source file, also known as document fragments. Their implementation
+ * is known as a DOM (Document Object Model) -  in this case a JDOM (Java DOM). A root node (node
+ * with no parent or siblings) represents the root of a document fragment (DF). A complete Java document is
+ * represented by a compilation unit node (<code>IDOMCompilationUnit</code>). In this way, a DF is
+ * comprised of DFs, and a document itself (compilation unit) is also a DF.
+ * <p>
+ * A DF may be created empty and programmatically filled, or it may be created from
+ * a source code string. The <code>IDOMFactory</code> allows the creation of all kinds
+ * of nodes from source code strings. Manipulations performed on a DF are immediately
+ * reflected in the DF's contents.
+ * </p>
+ * <p>
+ * Children fragments are represented as a linked list of nodes. Children are inserted via their parent node, and
+ * are automatically linked up with previous and next nodes.
+ * </p>
+ * <p>
+ * The contents of any node (DF) may be retrieved at any time. In this way it is possible to retrieve
+ * source code representing fragments of the compilation unit (for example, a type or a method), since
+ * the contents of any node (not just the root node) may be obtained.
+ * </p>
+ * <p>
+ * The following manipulations on DFs are distinct:
+ * <ul>
+ * <li>clone - this creates a stand-alone copy of the DF that is in no way dependent on the DF that it was cloned from</li>
+ * <li>remove - this orphans a DF from its host DF. The removed DF may still be dependent on its previous host
+ *    (perhaps to generate its contents), and hanging onto the fragment means that its previous host is also
+ *    retained in memory.</li>
+ * <li>add/insert - this splices an un-parented DF (one that has been cloned, removed, or created stand-alone),
+ *    into an existing DF such that the newly inserted DF is only dependent on its new host.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Wherever types are specified in DOM APIs, type names must be specified as they would appear
+ * in source code. The DOM does not have a notion of type signatures, only raw text. Example type
+ * names are <code>"Object"</code>, <code>"java.io.File"</code>, and <code>"int[]"</code>.
+ * </p>
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMNode extends Cloneable  {
+
+	/**
+	 * Node type constant indicating a compilation unit.
+	 * Nodes of this type maybe by safely cast to <code>IDOMCompilationUnit</code>.
+	 * @see #getNodeType()
+	 */
+	public static int COMPILATION_UNIT= 1;
+
+	/**
+	 * Node type constant indicating a package declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMPackage</code>.
+	* @see #getNodeType()
+	 */
+	public static int PACKAGE= 2;
+
+	/**
+	 * Node type constant indicating an import declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMImport</code>.
+	 * @see #getNodeType()
+	 */
+	public static int IMPORT= 3;
+
+	/**
+	 * Node type constant indicating a type declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMType</code>.
+	 * @see #getNodeType()
+	 */
+	public static int TYPE= 4;
+
+	/**
+	 * Node type constant indicating a field declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMField</code>.
+	 * @see #getNodeType()
+	 */
+	public static int FIELD= 5;
+
+	/**
+	 * Node type constant indicating a method (or constructor) declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMMethod</code>.
+	 * @see #getNodeType()
+	 */
+	public static int METHOD= 6;
+
+	/**
+	 * Node type constant indicating an initializer declaration.
+	 * Nodes of this type maybe by safely cast to <code>IDOMInitializer</code>.
+	 * @see #getNodeType()
+	 */
+	public static int INITIALIZER= 7;
+
+/**
+ * Adds the given un-parented node (document fragment) as the last child of this node.
+ *
+ * @param child the new child node
+ * @exception DOMException if any of the following conditions hold:<ul>
+ * <li>this node is not allowed to have children,</li>
+ * <li>the child is not of an allowable type</li>
+ * <li>the child already has a parent</li>
+ * <li>the child is an ancestor of this node</li>
+ * </ul>
+ * @exception IllegalArgumentException if the child is <code>null</code>
+ *
+ * @see #insertSibling(IDOMNode)
+ * @see #remove()
+ */
+public void addChild(IDOMNode child) throws DOMException, IllegalArgumentException;
+/**
+ * Returns whether this node is allowed to have children.
+ *
+ * @return <code>true</code> if this node can have children
+ */
+public boolean canHaveChildren();
+/**
+ * Returns a stand-alone copy of the document fragment represented by this node that
+ * is in no way dependent on the document this node is part of.
+ *
+ * @return a copy of type <code>IDOMNode</code>
+ * @see #addChild(IDOMNode)
+ * @see #insertSibling(IDOMNode)
+ * @see #remove()
+ */
+public Object clone();
+/**
+ * Returns the current contents of this document fragment as a character array.
+ * <p>
+ * Note: To obtain complete source for the source file, ask a compilation unit
+ * node for its contents.
+ * </p>
+ *
+ * @return the contents, or <code>null</code> if this node has no contents
+ */
+public char[] getCharacters();
+/**
+ * Returns the first named child of this node with the given name.
+ *
+ * @param name the name
+ * @return the child node, or <code>null</code> if no such child exists
+ */
+public IDOMNode getChild(String name);
+/**
+ * Returns an enumeration of children of this node. Returns an empty enumeration
+ * if this node has no children (including nodes that cannot have children).
+ * Children appear in the order in which they are declared in the source code.
+ *
+ * @return an enumeration of the children
+ */
+public Enumeration getChildren();
+/**
+ * Returns the current contents of this document fragment.
+ * <p>
+ * Note: To obtain complete source for the source file, ask a compilation unit
+ * node for its contents.
+ * </p>
+ *
+ * @return the contents, or <code>null</code> if this node has no contents
+ */
+public String getContents();
+/**
+ * Returns the first child of this node.
+ * Children appear in the order in which they exist in the source code.
+ *
+ * @return the first child, or <code>null</code> if this node has no children
+ * @see #getChildren()
+ */
+public IDOMNode getFirstChild();
+/**
+ * Returns a handle for the Java element associated with this
+ * document fragment, based on the parent Java element.
+ *
+ * @param parent the parent Java element
+ * @exception IllegalArgumentException if the parent element is not
+ *   of a valid parent type for this node
+ * @return a handle for the Java element associated with this
+ *         document fragment, based on the parent Java element
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException;
+/**
+ * Returns the name of this node.
+ * More details are provided in each of the subtypes.
+ *
+ * @return the name, or <code>null</code> if it has no name
+ */
+public String getName();
+/**
+ * Returns the sibling node immediately following this node.
+ *
+ * @return the next node, or <code>null</code> if there is no following node
+ */
+public IDOMNode getNextNode();
+/**
+ * Returns the type of this node.
+ *
+ * @return one of the node type constants defined in <code>IDOMNode</code>
+ */
+public int getNodeType();
+/**
+ * Returns the parent of this node.
+ *
+ * @return the parent node, or <code>null</code> if this node does not have a
+ *   parent
+ */
+public IDOMNode getParent();
+/**
+ * Returns the sibling node immediately preceding this node.
+ *
+ * @return the previous node, or <code>null</code> if there is no preceding node
+ */
+public IDOMNode getPreviousNode();
+/**
+ * Inserts the given un-parented node as a sibling of this node, immediately before
+ * this node.
+ *
+ * @param sibling the new sibling node
+ * @exception DOMException if any of the following conditions hold:<ul>
+ * <li>this node is a document fragment root</li>
+ * <li>the sibling is not of the correct type</li>
+ * <li>the sibling already has a parent</li>
+ * <li>this sibling is an ancestor of this node</li>
+ * </ul>
+ * @exception IllegalArgumentException if the sibling is <code>null</code>
+ *
+ * @see #addChild(IDOMNode)
+ * @see #clone()
+ * @see #remove()
+ */
+public void insertSibling(IDOMNode sibling) throws DOMException, IllegalArgumentException;
+/**
+ * Returns whether the given node is an allowable child for this node.
+ *
+ * @param node the potential child node
+ * @return <code>true</code> if the given node is an allowable child
+ */
+public boolean isAllowableChild(IDOMNode node);
+/**
+ * Returns whether this node's signature is equivalent to the given
+ * node's signature. In other words, if the nodes were siblings,
+ * would the declarations collide because they represent the same declaration.
+ *
+ * @param node the other node
+ * @return <code>true</code> if the nodes have equivalent signatures
+ */
+public boolean isSignatureEqual(IDOMNode node);
+/**
+ * Separates this node from its parent and siblings, maintaining any ties that this node
+ * has to the underlying document fragment. A document fragment that is removed
+ * from its host document may still be dependent on that host document until it is
+ * inserted into a different document. Removing a root node has no effect.
+ *
+ * @see #addChild(IDOMNode)
+ * @see #clone()
+ * @see #insertSibling(IDOMNode)
+ */
+public void remove();
+/**
+ * Sets the name of this node. Name format depends on node type.
+ * More details are provided in each of the subtypes.
+ *
+ * @param name the name, or <code>null</code> to clear the name
+ */
+public void setName(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java
new file mode 100644
index 0000000..0107dbc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+/**
+ * Represents a package declaration.
+ * The corresponding syntactic unit is PackageDeclaration (JLS2 7.4).
+ * A Package has no children, and its parent is a compilation unit.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMPackage extends IDOMNode {
+/**
+ * The <code>IDOMPackage</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this package declaration, or <code>null</code>
+ * if it has none. The syntax for a package name corresponds to PackageName
+ * as defined by PackageDeclaration (JLS2 7.4).
+ *
+ * @return the name of this package declaration, or <code>null</code>
+ *         if it has none
+ */
+public String getName();
+/**
+ * The <code>IDOMPackage</code> refinement of this <code>IDOMNode</code>
+ * method sets the name of this package declaration. The syntax for a package
+ * name corresponds to PackageName as defined by PackageDeclaration (JLS2 7.4).
+ * A <code>null</code> name indicates an empty package declaration; that is,
+ * <code>getContents</code> returns the empty string.
+ *
+ * @param name the given name
+ */
+public void setName(String name);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java
new file mode 100644
index 0000000..3bd2197
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.jdom;
+
+/**
+ * Represents a source type in a compilation unit, either as a top-level type or a member type.
+ * The corresponding syntactic units are ClassDeclaration (JLS2 8.1) and InterfaceDeclaration (JLS2 9.1).
+ * Enumeration types and annotation types, added in J2SE 1.5, are represented as
+ * classes and interfaces, respectively.
+ * <p>
+ * Allowable child types for a type are <code>IDOMType</code>, <code>IDOMField</code>,
+ * <code>IDOMMethod</code>, and <code>IDOMInitializer</code>.
+ * Children are listed in the order in which they appear in the source. The parent of a type
+ * is a type (in the case of a member type) or a compilation unit (in the case of a top-level type).
+ * </p>
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IDOMType extends IDOMMember {
+/**
+ * Adds the given interface name to the names of interfaces that this type implements or extends
+ * (the name will be added after the existing interface names). This is a convenience method.
+ *
+ * For classes, this represents the interfaces that this class implements.
+ * For interfaces, this represents the interfaces that this interface extends.
+ * The name may or may not be fully qualified.
+ *
+ * @param interfaceName the syntax for an interface name is defined by
+ *  Interfaces in ClassDeclaration (JLS2 8.1). Type names must be specified as they would
+ *  appear in source code. For example: "Cloneable", "java.io.Serializable".
+ *
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void addSuperInterface(String interfaceName) throws IllegalArgumentException;
+
+/**
+ * Returns the formal type parameters for this type.
+ * Returns an empty array if this method has no formal type parameters.
+ * <p>Formal type parameters are as they appear in the source
+ * code; for example:
+ * <code>"X extends List&lt;String&gt; & Serializable"</code>.
+ * </p>
+ *
+ * @return the formal type parameters of this type,
+ * in the order declared in the source, an empty array if none
+ * @since 3.0
+ */
+String[] getTypeParameters();
+
+/**
+ * The <code>IDOMType</code> refinement of this <code>IDOMNode</code>
+ * method returns the name of this type. The name of a class is defined by
+ * ClassDeclaration (JLS2 8.1); the name of an interface is defined by
+ * InterfaceDeclaration (JLS2 9.1).
+ *
+ * @return the name of this type
+ */
+public String getName();
+/**
+ * Returns the name of this type's superclass. The syntax for a superclass name
+ * is specified by Super in ClassDeclaration (JLS2 8.1). Type names must be
+ * specified as they would appear in source code. For example:
+ * <code>"Object"</code>, or <code>"java.io.File"</code>.
+ * As of J2SE 1.5, the superclass may also include parameterized
+ * types like <code>"ArrayList&lt;String&gt;"</code>.
+ *
+ * @return the superclass name, or <code>null</code> if this type represents
+ *   an interface or if no superclass has been assigned to this class
+ */
+public String getSuperclass();
+/**
+ * Returns the names of interfaces that this type implements or extends,
+ * in the order in which they are listed in the source, or an empty array
+ * if no superinterfaces are present. The syntax for interface names is
+ * defined by Interfaces in ClassDeclaration (JLS2 8.1). Type names appear
+ * as they would in source code. For example: <code>"Cloneable"</code>,
+ * or <code>"java.io.Serializable"</code>.
+ * As of J2SE 1.5, superinterfaces may also include parameterized
+ * types like <code>"List&lt;String&gt;"</code>.
+ * <p>
+ * For classes, this method returns the interfaces that this class implements.
+ * For interfaces, this method returns the interfaces that this interface extends.
+ * </p>
+ *
+ * @return the list of interface names
+ */
+public String[] getSuperInterfaces();
+/**
+ * Returns whether this type is a class.
+ *
+ * @return <code>true</code> for classes, and <code>false</code> for interfaces
+ */
+public boolean isClass();
+
+/**
+ * Returns whether this type represents an enumeration class ("enum" instead of "class").
+ *
+ * @return true if this type represents an enumeration class, false otherwise
+ * @since 3.0
+ */
+boolean isEnum();
+
+/**
+ * Returns whether this type represents an annotation type ("@interface" instead of "interface").
+ *
+ * @return true if this type represents an annotation type, false otherwise
+ * @since 3.0
+ */
+boolean isAnnotation();
+
+/**
+ * Sets whether this type is a class or an interface. If this type is
+ * a class, and is changed to an interface, this type's superclass
+ * becomes <code>null</code>. When a class becomes an interface or an
+ * interface becomes a class, superinterfaces remain (as part of an
+ * <code>implements</code> clause for classes, or an <code>extends</code>
+ * clause for interfaces).
+ *
+ * @param b <code>true</code> for classes, and <code>false</code> for interfaces
+ */
+public void setClass(boolean b);
+
+/**
+ * Sets whether this type represents an enumeration class.
+ * If this type is a class and is changed to an enum,
+ * this type's superclass becomes <code>null</code>.
+ * If this type is an interface (including an annotation type),
+ * and is changed to an enum, this type is also changed to a class.
+ *
+ * @param b <code>true</code> for enum classes, and <code>false</code> otherwise
+ * @since 3.0
+ */
+public void setEnum(boolean b);
+
+/**
+ * Sets whether this type represents an annotation type ("@interface" instead of "interface").
+ * If this type is a interface and is changed to an enum,
+ * this type's superclass becomes <code>null</code> and its superinterface list
+ * becomes empty. If this type is an class (including an enum),
+ * and is changed to an annotation type, this type is also changed to an interface.
+ *
+ * @param b <code>true</code> for an annotation type, and <code>false</code> otherwise
+ * @since 3.0
+ */
+public void setAnnotation(boolean b);
+
+/**
+ * Sets the formal type parameters for this type.
+ * <p>Formal type parameters are given as they appear in the source
+ * code; for example:
+ * <code>"X extends List&lt;String&gt; & Serializable"</code>.
+ * </p>
+ *
+ * @param typeParameters the formal type parameters of this type,
+ * in the order to appear in the source, an empty array if none
+ * @since 3.0
+ */
+void setTypeParameters(String[] typeParameters);
+
+/**
+ * The <code>IDOMType</code> refinement of this <code>IDOMNode</code>
+ * method sets the name of this type. The name of a class is defined by
+ * ClassDeclaration (JLS2 8.1); the name of an interface is defined by
+ * InterfaceDeclaration (JLS2 9.1).
+ *
+ * @param name the given name
+ * @exception IllegalArgumentException if <code>null</code> is specified
+ */
+public void setName(String name) throws IllegalArgumentException;
+/**
+ * Sets the name of this type's superclass. Has no effect if this type
+ * represents an interface. A <code>null</code> name indicates that no
+ * superclass name (extends clause) should appear in the source code.
+ * The syntax for a superclass name is specified by Super in ClassDeclaration
+ * (JLS2 8.1). Type names must be specified as they would appear in source code.
+ * For example: <code>"Object"</code>, or <code>"java.io.File"</code>.
+ * As of J2SE 1.5, the superclass may also include parameterized
+ * types like <code>"ArrayList&lt;String&gt;"</code>.
+ *
+ * @param superclassName the superclass name, or <code>null</code> if this type
+ *   should have to no explicitly specified superclass
+ */
+public void setSuperclass(String superclassName);
+/**
+ * Sets the names of interfaces that this type implements or extends,
+ * in the order in which they are to be listed in the source. An empty array
+ * parameter indicates that no superinterfaces are present. The syntax for
+ * interface names is defined by Interfaces in ClassDeclaration (JLS2 8.1).
+ * Type names appear as they would in source code. For example:
+ * <code>"Cloneable"</code>, or <code>"java.io.Serializable"</code>.
+ * As of J2SE 1.5, superinterfaces may also include parameterized
+ * types like <code>"List&lt;String&gt;"</code>.
+ * <p>
+ * For classes, this method sets the interfaces that this class implements.
+ * For interfaces, this method sets the interfaces that this interface extends.
+ * </p>
+ *
+ * @param interfaceNames the list of interface names
+ */
+public void setSuperInterfaces(String[] interfaceNames);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/package.html b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/package.html
new file mode 100644
index 0000000..67a0e7c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/package.html
@@ -0,0 +1,24 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="Author" content="IBM">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Package-level Javadoc</title>
+</head>
+
+<body>
+
+Provides a support for Java document manipulation through the JDOM model.
+<h2>Package Specification</h2>
+This package provides a support for Java document manipulation through the JDOM
+model.
+<p>The JDOM was made obsolete by the addition in 2.0 of the more powerful,
+fine-grained DOM/AST API found in the <code>org.eclipse.jdt.core.dom</code>
+package.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/package.html b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/package.html
new file mode 100644
index 0000000..ce96a3e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/package.html
@@ -0,0 +1,27 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+The Java model is the set of classes that model the
+objects associated with creating, editing, and building a Java program.
+<h2>
+Package Specification</h2>
+
+<p><br>This package contains the Java model classes, which implement Java
+specific behaviour for resources and further decompose Java resources into
+model elements.
+</p><p>
+Note that a lot of Java model operations require a Java project's classpath resolution.
+For example IJavaProject#getResolvedClasspath(boolean) or JavaCore#setClasspathContainer()
+will require to resolve the classpath of one or more projects. Client should be aware that
+this resolution may require to take project modification rule 
+(see IResourceRuleFactory#modifyRule(IResource)).
+</p>
+
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java
new file mode 100644
index 0000000..c23af13
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java
@@ -0,0 +1,1508 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Adapter that implements the IBytecodeVisitor. This class is intended to
+ * be subclassed by clients.
+ *
+ * @since 2.0
+ */
+public class ByteCodeVisitorAdapter implements IBytecodeVisitor {
+	/**
+	 * @see IBytecodeVisitor#_aaload(int)
+	 */
+	public void _aaload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aastore(int)
+	 */
+	public void _aastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aconst_null(int)
+	 */
+	public void _aconst_null(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_0(int)
+	 */
+	public void _aload_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_1(int)
+	 */
+	public void _aload_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_2(int)
+	 */
+	public void _aload_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_3(int)
+	 */
+	public void _aload_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload(int, int)
+	 */
+	public void _aload(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_anewarray(int, int, IConstantPoolEntry)
+	 */
+	public void _anewarray(int pc, int index, IConstantPoolEntry constantClass) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_areturn(int)
+	 */
+	public void _areturn(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_arraylength(int)
+	 */
+	public void _arraylength(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_0(int)
+	 */
+	public void _astore_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_1(int)
+	 */
+	public void _astore_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_2(int)
+	 */
+	public void _astore_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_3(int)
+	 */
+	public void _astore_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore(int, int)
+	 */
+	public void _astore(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_athrow(int)
+	 */
+	public void _athrow(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_baload(int)
+	 */
+	public void _baload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_bastore(int)
+	 */
+	public void _bastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_bipush(int, byte)
+	 */
+	public void _bipush(int pc, byte _byte) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_caload(int)
+	 */
+	public void _caload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_castore(int)
+	 */
+	public void _castore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_checkcast(int, int, IConstantPoolEntry)
+	 */
+	public void _checkcast(int pc, int index, IConstantPoolEntry constantClass) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2f(int)
+	 */
+	public void _d2f(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2i(int)
+	 */
+	public void _d2i(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2l(int)
+	 */
+	public void _d2l(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dadd(int)
+	 */
+	public void _dadd(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_daload(int)
+	 */
+	public void _daload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dastore(int)
+	 */
+	public void _dastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dcmpg(int)
+	 */
+	public void _dcmpg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dcmpl(int)
+	 */
+	public void _dcmpl(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dconst_0(int)
+	 */
+	public void _dconst_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dconst_1(int)
+	 */
+	public void _dconst_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ddiv(int)
+	 */
+	public void _ddiv(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_0(int)
+	 */
+	public void _dload_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_1(int)
+	 */
+	public void _dload_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_2(int)
+	 */
+	public void _dload_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_3(int)
+	 */
+	public void _dload_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload(int, int)
+	 */
+	public void _dload(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dmul(int)
+	 */
+	public void _dmul(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dneg(int)
+	 */
+	public void _dneg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_drem(int)
+	 */
+	public void _drem(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dreturn(int)
+	 */
+	public void _dreturn(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_0(int)
+	 */
+	public void _dstore_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_1(int)
+	 */
+	public void _dstore_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_2(int)
+	 */
+	public void _dstore_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_3(int)
+	 */
+	public void _dstore_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore(int, int)
+	 */
+	public void _dstore(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dsub(int)
+	 */
+	public void _dsub(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup_x1(int)
+	 */
+	public void _dup_x1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup_x2(int)
+	 */
+	public void _dup_x2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup(int)
+	 */
+	public void _dup(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2_x1(int)
+	 */
+	public void _dup2_x1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2_x2(int)
+	 */
+	public void _dup2_x2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2(int)
+	 */
+	public void _dup2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2d(int)
+	 */
+	public void _f2d(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2i(int)
+	 */
+	public void _f2i(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2l(int)
+	 */
+	public void _f2l(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fadd(int)
+	 */
+	public void _fadd(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_faload(int)
+	 */
+	public void _faload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fastore(int)
+	 */
+	public void _fastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fcmpg(int)
+	 */
+	public void _fcmpg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fcmpl(int)
+	 */
+	public void _fcmpl(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_0(int)
+	 */
+	public void _fconst_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_1(int)
+	 */
+	public void _fconst_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_2(int)
+	 */
+	public void _fconst_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fdiv(int)
+	 */
+	public void _fdiv(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_0(int)
+	 */
+	public void _fload_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_1(int)
+	 */
+	public void _fload_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_2(int)
+	 */
+	public void _fload_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_3(int)
+	 */
+	public void _fload_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload(int, int)
+	 */
+	public void _fload(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fmul(int)
+	 */
+	public void _fmul(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fneg(int)
+	 */
+	public void _fneg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_frem(int)
+	 */
+	public void _frem(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_freturn(int)
+	 */
+	public void _freturn(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_0(int)
+	 */
+	public void _fstore_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_1(int)
+	 */
+	public void _fstore_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_2(int)
+	 */
+	public void _fstore_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_3(int)
+	 */
+	public void _fstore_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore(int, int)
+	 */
+	public void _fstore(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fsub(int)
+	 */
+	public void _fsub(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_getfield(int, int, IConstantPoolEntry)
+	 */
+	public void _getfield(int pc, int index, IConstantPoolEntry constantFieldref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_getstatic(int, int, IConstantPoolEntry)
+	 */
+	public void _getstatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_goto_w(int, int)
+	 */
+	public void _goto_w(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_goto(int, int)
+	 */
+	public void _goto(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2b(int)
+	 */
+	public void _i2b(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2c(int)
+	 */
+	public void _i2c(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2d(int)
+	 */
+	public void _i2d(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2f(int)
+	 */
+	public void _i2f(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2l(int)
+	 */
+	public void _i2l(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2s(int)
+	 */
+	public void _i2s(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iadd(int)
+	 */
+	public void _iadd(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iaload(int)
+	 */
+	public void _iaload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iand(int)
+	 */
+	public void _iand(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iastore(int)
+	 */
+	public void _iastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_0(int)
+	 */
+	public void _iconst_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_1(int)
+	 */
+	public void _iconst_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_2(int)
+	 */
+	public void _iconst_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_3(int)
+	 */
+	public void _iconst_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_4(int)
+	 */
+	public void _iconst_4(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_5(int)
+	 */
+	public void _iconst_5(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_m1(int)
+	 */
+	public void _iconst_m1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_idiv(int)
+	 */
+	public void _idiv(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_acmpeq(int, int)
+	 */
+	public void _if_acmpeq(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_acmpne(int, int)
+	 */
+	public void _if_acmpne(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpeq(int, int)
+	 */
+	public void _if_icmpeq(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpge(int, int)
+	 */
+	public void _if_icmpge(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpgt(int, int)
+	 */
+	public void _if_icmpgt(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmple(int, int)
+	 */
+	public void _if_icmple(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmplt(int, int)
+	 */
+	public void _if_icmplt(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpne(int, int)
+	 */
+	public void _if_icmpne(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifeq(int, int)
+	 */
+	public void _ifeq(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifge(int, int)
+	 */
+	public void _ifge(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifgt(int, int)
+	 */
+	public void _ifgt(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifle(int, int)
+	 */
+	public void _ifle(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iflt(int, int)
+	 */
+	public void _iflt(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifne(int, int)
+	 */
+	public void _ifne(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifnonnull(int, int)
+	 */
+	public void _ifnonnull(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifnull(int, int)
+	 */
+	public void _ifnull(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iinc(int, int, int)
+	 */
+	public void _iinc(int pc, int index, int _const) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_0(int)
+	 */
+	public void _iload_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_1(int)
+	 */
+	public void _iload_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_2(int)
+	 */
+	public void _iload_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_3(int)
+	 */
+	public void _iload_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload(int, int)
+	 */
+	public void _iload(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_imul(int)
+	 */
+	public void _imul(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ineg(int)
+	 */
+	public void _ineg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_instanceof(int, int, IConstantPoolEntry)
+	 */
+	public void _instanceof(int pc, int index, IConstantPoolEntry constantClass) {
+		// default behavior is to do nothing
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry)
+	 * @since 3.6
+	 * @deprecated This has been replaced with {@link IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)}
+	 */
+	public void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry nameEntry,
+			IConstantPoolEntry descriptorEntry) {
+		// default behavior is to do nothing
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)
+	 * @since 3.8
+	 */
+	public void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry invokeDynamicEntry) {
+		// default behavior is to do nothing
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry)
+	 */
+	public void _invokeinterface(
+		int pc,
+		int index,
+		byte nargs,
+		IConstantPoolEntry constantInterfaceMethodref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_invokespecial(int, int, IConstantPoolEntry)
+	 */
+	public void _invokespecial(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_invokestatic(int, int, IConstantPoolEntry)
+	 */
+	public void _invokestatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_invokevirtual(int, int, IConstantPoolEntry)
+	 */
+	public void _invokevirtual(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ior(int)
+	 */
+	public void _ior(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_irem(int)
+	 */
+	public void _irem(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ireturn(int)
+	 */
+	public void _ireturn(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ishl(int)
+	 */
+	public void _ishl(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ishr(int)
+	 */
+	public void _ishr(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_0(int)
+	 */
+	public void _istore_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_1(int)
+	 */
+	public void _istore_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_2(int)
+	 */
+	public void _istore_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_3(int)
+	 */
+	public void _istore_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore(int, int)
+	 */
+	public void _istore(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_isub(int)
+	 */
+	public void _isub(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iushr(int)
+	 */
+	public void _iushr(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ixor(int)
+	 */
+	public void _ixor(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_jsr_w(int, int)
+	 */
+	public void _jsr_w(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_jsr(int, int)
+	 */
+	public void _jsr(int pc, int branchOffset) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2d(int)
+	 */
+	public void _l2d(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2f(int)
+	 */
+	public void _l2f(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2i(int)
+	 */
+	public void _l2i(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ladd(int)
+	 */
+	public void _ladd(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_laload(int)
+	 */
+	public void _laload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_land(int)
+	 */
+	public void _land(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lastore(int)
+	 */
+	public void _lastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lcmp(int)
+	 */
+	public void _lcmp(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lconst_0(int)
+	 */
+	public void _lconst_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lconst_1(int)
+	 */
+	public void _lconst_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc_w(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc2_w(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc2_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldiv(int)
+	 */
+	public void _ldiv(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_0(int)
+	 */
+	public void _lload_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_1(int)
+	 */
+	public void _lload_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_2(int)
+	 */
+	public void _lload_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_3(int)
+	 */
+	public void _lload_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload(int, int)
+	 */
+	public void _lload(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lmul(int)
+	 */
+	public void _lmul(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lneg(int)
+	 */
+	public void _lneg(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lookupswitch(int, int, int, int[][])
+	 */
+	public void _lookupswitch(
+		int pc,
+		int defaultoffset,
+		int npairs,
+		int[][] offset_pairs) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lor(int)
+	 */
+	public void _lor(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lrem(int)
+	 */
+	public void _lrem(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lreturn(int)
+	 */
+	public void _lreturn(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lshl(int)
+	 */
+	public void _lshl(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lshr(int)
+	 */
+	public void _lshr(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_0(int)
+	 */
+	public void _lstore_0(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_1(int)
+	 */
+	public void _lstore_1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_2(int)
+	 */
+	public void _lstore_2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_3(int)
+	 */
+	public void _lstore_3(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore(int, int)
+	 */
+	public void _lstore(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lsub(int)
+	 */
+	public void _lsub(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lushr(int)
+	 */
+	public void _lushr(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lxor(int)
+	 */
+	public void _lxor(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_monitorenter(int)
+	 */
+	public void _monitorenter(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_monitorexit(int)
+	 */
+	public void _monitorexit(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_multianewarray(int, int, int, IConstantPoolEntry)
+	 */
+	public void _multianewarray(
+		int pc,
+		int index,
+		int dimensions,
+		IConstantPoolEntry constantClass) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_new(int, int, IConstantPoolEntry)
+	 */
+	public void _new(int pc, int index, IConstantPoolEntry constantClass) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_newarray(int, int)
+	 */
+	public void _newarray(int pc, int atype) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_nop(int)
+	 */
+	public void _nop(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_pop(int)
+	 */
+	public void _pop(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_pop2(int)
+	 */
+	public void _pop2(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_putfield(int, int, IConstantPoolEntry)
+	 */
+	public void _putfield(int pc, int index, IConstantPoolEntry constantFieldref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_putstatic(int, int, IConstantPoolEntry)
+	 */
+	public void _putstatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ret(int, int)
+	 */
+	public void _ret(int pc, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_return(int)
+	 */
+	public void _return(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_saload(int)
+	 */
+	public void _saload(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_sastore(int)
+	 */
+	public void _sastore(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_sipush(int, short)
+	 */
+	public void _sipush(int pc, short value) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_swap(int)
+	 */
+	public void _swap(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_tableswitch(int, int, int, int, int[])
+	 */
+	public void _tableswitch(
+		int pc,
+		int defaultoffset,
+		int low,
+		int high,
+		int[] jump_offsets) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_wide(int, int, int, int)
+	 */
+	public void _wide(int pc, int iincopcode, int index, int _const) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_wide(int, int, int)
+	 */
+	public void _wide(int pc, int opcode, int index) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_breakpoint(int)
+	 */
+	public void _breakpoint(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_impdep1(int)
+	 */
+	public void _impdep1(int pc) {
+		// default behavior is to do nothing
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_impdep2(int)
+	 */
+	public void _impdep2(int pc) {
+		// default behavior is to do nothing
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java
new file mode 100644
index 0000000..6f1c3c3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * This class is intended to be subclassed to disassemble
+ * classfile bytes onto a String using the proper line separator.
+ *
+ * @since 2.1
+ */
+public abstract class ClassFileBytesDisassembler {
+
+	/**
+	 * The mode is the detailed mode to disassemble IClassFileReader. It returns the magic
+	 * numbers, the version numbers and field and method descriptors.
+	 */
+	public final static int DETAILED = 1;
+
+	/**
+	 * The mode is the default mode to disassemble IClassFileReader.
+	 */
+	public final static int DEFAULT  = 2;
+
+	/**
+	 * This mode corresponds to the detailed mode plus the constant pool contents and
+	 * any further information that would be useful for debugging purpose.
+	 * @since 3.1
+	 */
+	public final static int SYSTEM = 4;
+
+	/**
+	 * This mode is used to compact the class name to a simple name instead of a qualified name.
+	 * @since 3.1
+	 */
+	public final static int COMPACT = 8;
+
+	/**
+	 * This mode is used to retrive a pseudo code for working copy purpose.
+	 * @since 3.2
+	 */
+	public final static int WORKING_COPY = 16;
+
+	/**
+	 * Answers back the disassembled string of the classfile bytes using the default
+	 * mode.
+	 * This is an output quite similar to the javap tool, using DEFAULT mode.
+	 *
+	 * @param classFileBytes The bytes of the classfile
+	 * @param lineSeparator the line separator to use.
+	 *
+	 * @return the disassembled string of the IClassFileReader using the default mode.
+	 * @exception ClassFormatException if the classfile bytes are ill-formed
+	 */
+	public abstract String disassemble(byte[] classFileBytes, String lineSeparator) throws ClassFormatException;
+
+	/**
+	 * Answers back the disassembled string of the classfile bytes according to the
+	 * mode.
+	 * This is an output quite similar to the javap tool.
+	 *
+	 * @param classFileBytes The bytes of the classfile
+	 * @param lineSeparator the line separator to use.
+	 * @param mode the mode used to disassemble the IClassFileReader
+	 *
+	 * @return the disassembled string of the IClassFileReader according to the mode
+	 * @exception ClassFormatException if the classfile bytes are ill-formed
+	 */
+	public abstract String disassemble(byte[] classFileBytes, String lineSeparator, int mode)  throws ClassFormatException;
+
+	/**
+	 * Answers a readable short description of this disassembler
+	 *
+	 * @return String - a string description of the disassembler
+	 */
+    public abstract String getDescription();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java
new file mode 100644
index 0000000..d29d364
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Exception thrown by a class file reader when encountering a error in decoding
+ * information contained in a .class file.
+ *
+ * @since 2.0
+ */
+public class ClassFormatException extends Exception {
+
+	public static final int ERROR_MALFORMED_UTF8 = 1;
+	public static final int ERROR_TRUNCATED_INPUT = 2;
+	public static final int INVALID_CONSTANT_POOL_ENTRY = 3;
+	public static final int TOO_MANY_BYTES = 4;
+	public static final int INVALID_ARGUMENTS_FOR_INVOKEINTERFACE = 5;
+	public static final int INVALID_BYTECODE = 6;
+
+	/**
+	 * @since 3.0
+	 */
+	public static final int INVALID_TAG_CONSTANT = 7;
+
+	/**
+	 * @since 3.0
+	 */
+	public static final int INVALID_MAGIC_NUMBER = 8;
+
+	private static final long serialVersionUID = 6582900558320612988L; // backward compatible
+
+	/**
+	 * Constructor for ClassFormatException.
+	 * @param errorID the given error ID
+	 */
+	public ClassFormatException(int errorID) {
+		// TODO (olivier) what is the errorID?
+	}
+
+	/**
+	 * Constructor for ClassFormatException.
+	 * @param message the message for the exception
+	 */
+	public ClassFormatException(String message) {
+		super(message);
+	}
+
+	/**
+	 * Constructor for ClassFormatException.
+	 * @param message the message for the exception
+	 * @param  cause  the cause of the exception
+	 * @since 3.5
+	 */
+	public ClassFormatException(String message, Throwable cause) {
+		super(message, cause);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
new file mode 100644
index 0000000..ee049b7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
@@ -0,0 +1,458 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Alex Blewitt - alex_blewitt@yahoo.com https://bugs.eclipse.org/bugs/show_bug.cgi?id=171066
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.util;
+
+import java.util.Comparator;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.core.SortElementsOperation;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+/**
+ * Operation for sorting members within a compilation unit.
+ * <p>
+ * This class provides all functionality via static members.
+ * </p>
+ *
+ * @since 2.1
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class CompilationUnitSorter {
+
+ 	/**
+ 	 * Private constructor to prevent instantiation.
+ 	 */
+	private CompilationUnitSorter() {
+		// Not instantiable
+	}
+
+    /**
+     * @deprecated marking deprecated as it is using deprecated code
+     */
+    private static void checkASTLevel(int level) {
+        switch (level) {
+        case AST.JLS2 :
+        case AST.JLS3 :
+        case AST.JLS4 :
+        case AST.JLS8 :
+            break;
+        default :
+            throw new IllegalArgumentException();
+        }
+    }
+
+	/**
+	 * Name of auxillary property whose value can be used to determine the
+	 * original relative order of two body declarations. This allows a
+	 * comparator to preserve the relative positions of certain kinds of
+	 * body declarations when required.
+	 * <p>
+	 * All body declarations passed to the comparator's <code>compare</code>
+	 * method by <code>CompilationUnitSorter.sort</code> carry an
+	 * Integer-valued property. The body declaration with the lower value
+	 * comes before the one with the higher value. The exact numeric value
+	 * of these properties is unspecified.
+	 * </p>
+	 * <p>
+	 * Example usage:
+	 * <pre>
+	 * BodyDeclaration b1 = (BodyDeclaration) object1;
+	 * BodyDeclaration b2 = (BodyDeclaration) object2;
+	 * Integer i1 = (Integer) b1.getProperty(RELATIVE_ORDER);
+	 * Integer i2 = (Integer) b2.getProperty(RELATIVE_ORDER);
+	 * return i1.intValue() - i2.intValue(); // preserve original order
+	 * </pre>
+	 * </p>
+	 *
+	 * @see #sort(ICompilationUnit, int[], Comparator, int, IProgressMonitor)
+	 * @see org.eclipse.jdt.core.dom.BodyDeclaration
+	 */
+	public static final String RELATIVE_ORDER = "relativeOrder"; //$NON-NLS-1$
+
+	/**
+	 * Reorders the declarations in the given compilation unit according to
+     * JLS2 rules. The caller is
+	 * responsible for arranging in advance that the given compilation unit is
+	 * a working copy, and for saving the changes afterwards.
+	 * <p>
+	 * <b>Note:</b> Reordering the members within a type declaration might be
+	 * more than a cosmetic change and could have potentially serious
+	 * repercussions. Firstly, the order in which the fields of a type are
+	 * initialized is significant in the Java language; reordering fields
+	 * and initializers may result in compilation errors or change the execution
+	 * behavior of the code. Secondly, reordering a class's members may affect
+	 * how its instances are serialized. This operation should therefore be used
+	 * with caution and due concern for potential negative side effects.
+	 * </p>
+	 * <p>
+	 * The optional <code>positions</code> array contains a non-decreasing
+	 * ordered list of character-based source positions within the compilation
+	 * unit's source code string. Upon return from this method, the positions in
+	 * the array reflect the corresponding new locations in the modified source
+	 * code string. Note that this operation modifies the given array in place.
+	 * </p>
+	 * <p>
+	 * The <code>compare</code> method of the given comparator is passed pairs
+	 * of JLS2 AST body declarations (subclasses of <code>BodyDeclaration</code>)
+	 * representing body declarations at the same level. The comparator is
+	 * called on body declarations of nested classes, including anonymous and
+	 * local classes, but always at the same level. Clients need to provide
+	 * a comparator implementation (there is no standard comparator). The
+	 * <code>RELATIVE_ORDER</code> property attached to these AST nodes afforts
+	 * the comparator a way to preserve the original relative order.
+	 * </p>
+	 * <p>
+	 * The body declarations passed as parameters to the comparator
+	 * always carry at least the following minimal signature information:
+	 * <br>
+	 * <table border="1" width="80%" cellpadding="5">
+	 *	  <tr>
+	 *	    <td width="20%"><code>TypeDeclaration</code></td>
+	 *	    <td width="50%"><code>modifiers, isInterface, name, superclass,
+	 *	      superInterfaces<br>
+     *		  RELATIVE_ORDER property</code></td>
+	 *	  </tr>
+	 *	  <tr>
+	 *	    <td width="20%"><code>FieldDeclaration</code></td>
+	 *	    <td width="50%"><code>modifiers, type, fragments
+	 *        (VariableDeclarationFragments
+	 *	      with name only)<br>
+     *		  RELATIVE_ORDER property</code></td>
+	 *	  </tr>
+	 *	  <tr>
+	 *	    <td width="20%"><code>MethodDeclaration</code></td>
+	 *	    <td width="50%"><code>modifiers, isConstructor, returnType, name,
+	 *		  parameters
+	 *	      (SingleVariableDeclarations with name and type only),
+	 *		  thrownExceptions<br>
+     *		  RELATIVE_ORDER property</code></td>
+	 *	  </tr>
+	 *	  <tr>
+	 *	    <td width="20%"><code>Initializer</code></td>
+	 *	    <td width="50%"><code>modifiers<br>
+     *		  RELATIVE_ORDER property</code></td>
+	 *	  </tr>
+	 * </table>
+	 * Clients should not rely on the AST nodes being properly parented or on
+	 * having source range information. (Future releases may provide options
+	 * for requesting additional information like source positions, full ASTs,
+	 * non-recursive sorting, etc.)
+	 * </p>
+	 *
+	 * @param compilationUnit the given compilation unit, which must be a
+	 * working copy
+	 * @param positions an array of source positions to map, or
+	 * <code>null</code> if none. If supplied, the positions must
+	 * character-based source positions within the original source code for
+	 * the given compilation unit, arranged in non-decreasing order.
+	 * The array is updated in place when this method returns to reflect the
+	 * corresponding source positions in the permuted source code string
+	 * (but not necessarily any longer in non-decreasing order).
+	 * @param comparator the comparator capable of ordering
+	 *   <code>BodyDeclaration</code>s; this comparator is passed AST nodes
+     *   from a JLS2 AST
+	 * @param options bitwise-or of option flags; <code>0</code> for default
+	 * behavior (reserved for future growth)
+	 * @param monitor the progress monitor to notify, or <code>null</code> if
+	 * none
+	 * @exception JavaModelException if the compilation unit could not be
+	 * sorted. Reasons include:
+	 * <ul>
+	 * <li> The given compilation unit does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+	 * <li> The given compilation unit is not a working copy (INVALID_ELEMENT_TYPES)</li>
+	 * <li> A <code>CoreException</code> occurred while accessing the underlying
+	 * resource
+	 * </ul>
+	 * @exception IllegalArgumentException if the given compilation unit is null
+	 * or if the given comparator is null.
+	 * @see org.eclipse.jdt.core.dom.BodyDeclaration
+	 * @see #RELATIVE_ORDER
+     * @deprecated Clients should port their code to use the new JLS3 AST API and call
+     *    {@link #sort(int, ICompilationUnit, int[], Comparator, int, IProgressMonitor)
+     *    CompilationUnitSorter.sort(AST.JLS3, compilationUnit, positions, comparator, options, monitor)}
+     *    instead of using this method.
+	 */
+	public static void sort(ICompilationUnit compilationUnit,
+	        int[] positions,
+	        Comparator comparator,
+	        int options,
+	        IProgressMonitor monitor) throws JavaModelException {
+		sort(AST.JLS2, compilationUnit, positions, comparator, options, monitor);
+	}
+
+    /**
+     * Reorders the declarations in the given compilation unit according to
+     * the specified AST level. The caller is responsible for arranging in
+     * advance that the given compilation unit is a working copy, and for
+     * saving the changes afterwards.
+     * <p>
+     * <b>Note:</b> Reordering the members within a type declaration might be
+     * more than a cosmetic change and could have potentially serious
+     * repercussions. Firstly, the order in which the fields of a type are
+     * initialized is significant in the Java language; reordering fields
+     * and initializers may result in compilation errors or change the execution
+     * behavior of the code. Secondly, reordering a class's members may affect
+     * how its instances are serialized. This operation should therefore be used
+     * with caution and due concern for potential negative side effects.
+     * </p>
+     * <p>
+     * The optional <code>positions</code> array contains a non-decreasing
+     * ordered list of character-based source positions within the compilation
+     * unit's source code string. Upon return from this method, the positions in
+     * the array reflect the corresponding new locations in the modified source
+     * code string. Note that this operation modifies the given array in place.
+     * </p>
+     * <p>
+     * The <code>compare</code> method of the given comparator is passed pairs
+     * of body declarations (subclasses of <code>BodyDeclaration</code>)
+     * representing body declarations at the same level. The nodes are from an
+     * AST of the specified level
+     * ({@link org.eclipse.jdt.core.dom.ASTParser#newParser(int)}. Clients
+     * will generally specify the latest available <code>{@link AST}.JLS*</code> constant since that will
+     * cover all constructs found in all version of Java source code.
+     * The comparator is called on body declarations of nested classes, including
+     * anonymous and local classes, but always at the same level. Clients need to provide
+     * a comparator implementation (there is no standard comparator). The
+     * <code>RELATIVE_ORDER</code> property attached to these AST nodes afforts
+     * the comparator a way to preserve the original relative order.
+     * </p>
+     * <p>
+     * The body declarations passed as parameters to the comparator
+     * always carry at least the following minimal signature information:
+     * <br>
+     * <table border="1" width="80%" cellpadding="5">
+     *    <tr>
+     *      <td width="20%"><code>TypeDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, isInterface, name, superclass,
+     *        superInterfaces, typeParameters<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>FieldDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, type, fragments
+     *        (VariableDeclarationFragments
+     *        with name only)<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>MethodDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, isConstructor, returnType, name,
+     *        typeParameters, parameters
+     *        (SingleVariableDeclarations with name, type, and modifiers only),
+     *        thrownExceptions<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>Initializer</code></td>
+     *      <td width="50%"><code>modifiers<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>AnnotationTypeDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, name<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>AnnotationTypeMemberDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, name, type, default<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>EnumDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, name, superInterfaces<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     *    <tr>
+     *      <td width="20%"><code>EnumConstantDeclaration</code></td>
+     *      <td width="50%"><code>modifiers, name, arguments<br>
+     *        RELATIVE_ORDER property</code></td>
+     *    </tr>
+     * </table>
+     * Clients should not rely on the AST nodes being properly parented or on
+     * having source range information. (Future releases may provide options
+     * for requesting additional information like source positions, full ASTs,
+     * non-recursive sorting, etc.)
+     * </p>
+     *
+     * @param level the AST level; one of the <code>{@link AST}.JLS*</code> constants
+     * @param compilationUnit the given compilation unit, which must be a
+     * working copy
+     * @param positions an array of source positions to map, or
+     * <code>null</code> if none. If supplied, the positions must
+     * character-based source positions within the original source code for
+     * the given compilation unit, arranged in non-decreasing order.
+     * The array is updated in place when this method returns to reflect the
+     * corresponding source positions in the permuted source code string
+     * (but not necessarily any longer in non-decreasing order).
+     * @param comparator the comparator capable of ordering
+     *   <code>BodyDeclaration</code>s; this comparator is passed AST nodes
+     *   from an AST of the specified AST level
+     * @param options bitwise-or of option flags; <code>0</code> for default
+     * behavior (reserved for future growth)
+     * @param monitor the progress monitor to notify, or <code>null</code> if
+     * none
+     * @exception JavaModelException if the compilation unit could not be
+     * sorted. Reasons include:
+     * <ul>
+     * <li> The given compilation unit does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+     * <li> The given compilation unit is not a working copy (INVALID_ELEMENT_TYPES)</li>
+     * <li> A <code>CoreException</code> occurred while accessing the underlying
+     * resource
+     * </ul>
+     * @exception IllegalArgumentException if the given compilation unit is null
+     * or if the given comparator is null, or if <code>level</code> is not one of
+     * the AST JLS level constants.
+     * @see org.eclipse.jdt.core.dom.BodyDeclaration
+     * @see #RELATIVE_ORDER
+     * @since 3.1
+     */
+    public static void sort(int level, ICompilationUnit compilationUnit,
+            int[] positions,
+            Comparator comparator,
+            int options,
+            IProgressMonitor monitor) throws JavaModelException {
+        if (compilationUnit == null || comparator == null) {
+            throw new IllegalArgumentException();
+        }
+        checkASTLevel(level);
+        ICompilationUnit[] compilationUnits = new ICompilationUnit[] { compilationUnit };
+        SortElementsOperation operation = new SortElementsOperation(level, compilationUnits, positions, comparator);
+        operation.runOperation(monitor);
+    }
+
+	/**
+	 * Reorders the declarations in the given compilation unit according to the
+	 * specified comparator. The caller is responsible for arranging in advance
+	 * that the given compilation unit is a working copy, and for applying the
+	 * returned TextEdit afterwards.
+	 * <p>
+	 * <b>Note:</b> Reordering the members within a type declaration might be
+	 * more than a cosmetic change and could have potentially serious
+	 * repercussions. Firstly, the order in which the fields of a type are
+	 * initialized is significant in the Java language; reordering fields and
+	 * initializers may result in compilation errors or change the execution
+	 * behavior of the code. Secondly, reordering a class's members may affect
+	 * how its instances are serialized. This operation should therefore be used
+	 * with caution and due concern for potential negative side effects.
+	 * </p>
+	 * <p>
+	 * The <code>compare</code> method of the given comparator is passed pairs
+	 * of body declarations (subclasses of <code>BodyDeclaration</code>)
+	 * representing body declarations at the same level.
+	 * The comparator is called on body declarations of nested classes,
+	 * including anonymous and local classes, but always at the same level.
+	 * Clients need to provide a comparator implementation (there is no standard
+	 * comparator). The <code>RELATIVE_ORDER</code> property attached to these
+	 * AST nodes affords the comparator a way to preserve the original relative
+	 * order.
+	 * </p>
+	 * <p>
+	 * The body declarations passed as parameters to the comparator always carry
+	 * at least the following minimal signature information: <br>
+	 * <table border="1" width="80%" cellpadding="5">
+	 * <tr>
+	 * <td width="20%"><code>TypeDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, isInterface, name, superclass,
+	 *        superInterfaces, typeParameters<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>FieldDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, type, fragments
+	 *        (VariableDeclarationFragments
+	 *        with name only)<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>MethodDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, isConstructor, returnType, name,
+	 *        typeParameters, parameters
+	 *        (SingleVariableDeclarations with name, type, and modifiers only),
+	 *        thrownExceptions<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>Initializer</code></td>
+	 * <td width="50%"><code>modifiers<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>AnnotationTypeDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, name<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>AnnotationTypeMemberDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, name, type, default<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>EnumDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, name, superInterfaces<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * <tr>
+	 * <td width="20%"><code>EnumConstantDeclaration</code></td>
+	 * <td width="50%"><code>modifiers, name, arguments<br>
+	 *        RELATIVE_ORDER property</code></td>
+	 * </tr>
+	 * </table>
+	 * </p>
+	 *
+	 * @param unit
+	 *            the CompilationUnit to sort
+	 * @param comparator
+	 *            the comparator capable of ordering
+	 *            <code>BodyDeclaration</code>s; this comparator is passed
+	 *            AST nodes from an AST of the specified AST level
+	 * @param options
+	 *            bitwise-or of option flags; <code>0</code> for default
+	 *            behavior (reserved for future growth)
+	 * @param group
+	 *            the text edit group to use when generating text edits, or <code>null</code>
+	 * @param monitor
+	 *            the progress monitor to notify, or <code>null</code> if none
+	 * @return a TextEdit describing the required edits to do the sort, or <code>null</code>
+	 *            if sorting is not required
+	 * @exception JavaModelException
+	 *                if the compilation unit could not be sorted. Reasons
+	 *                include:
+	 *                <ul>
+	 *                <li> The given unit was not created from a ICompilationUnit (INVALID_ELEMENT_TYPES)</li>
+	 *                </ul>
+	 * @exception IllegalArgumentException
+	 *                if the given compilation unit is null or if the given
+	 *                comparator is null, or if <code>options</code> is not one
+	 *                of the supported levels.
+	 * @see org.eclipse.jdt.core.dom.BodyDeclaration
+	 * @see #RELATIVE_ORDER
+	 * @since 3.3
+	 */
+	public static TextEdit sort(CompilationUnit unit,
+			Comparator comparator,
+			int options,
+			TextEditGroup group,
+			IProgressMonitor monitor) throws JavaModelException {
+		if (unit == null || comparator == null) {
+			throw new IllegalArgumentException();
+		}
+		SortElementsOperation operation = new SortElementsOperation(unit.getAST().apiLevel(), new IJavaElement[] { unit.getJavaElement() }, null, comparator);
+		return operation.calculateEdit(unit, group);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java
new file mode 100644
index 0000000..d22ce2f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a annotation structure as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IAnnotation {
+	/**
+	 * Answer back the type index as described in the JVM specifications.
+	 *
+	 * @return the type index
+	 */
+	int getTypeIndex();
+
+	/**
+	 * Answer back the type name as described in the JVM specifications.
+	 *
+	 * @return the type name
+	 * @since 3.1
+	 */
+	char[] getTypeName();
+
+	/**
+	 * Answer back the number of components as described in the JVM specifications.
+	 *
+	 * @return the type index
+	 */
+	int getComponentsNumber();
+
+	/**
+	 * Answer back the components as described in the JVM specifications. Answer an
+	 * empty collection if none.
+	 *
+	 * @return the components
+	 */
+	IAnnotationComponent[] getComponents();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java
new file mode 100644
index 0000000..338f5f2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of an annotation component as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IAnnotationComponent {
+	/**
+	 * Answer back the component name index as described in the JVM specifications.
+	 *
+	 * @return the component name index
+	 */
+	int getComponentNameIndex();
+
+	/**
+	 * Answer back the component name as described in the JVM specifications.
+	 *
+	 * @return the component name
+	 */
+	char[] getComponentName();
+
+	/**
+	 * Answer back the component value as described in the JVM specifications.
+	 *
+	 * @return the component value
+	 */
+	IAnnotationComponentValue getComponentValue();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
new file mode 100644
index 0000000..d16fbda
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of an annotation component value as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.1
+ */
+public interface IAnnotationComponentValue {
+
+	/**
+	 * Tag value for a constant of type <code>byte</code>
+	 * @since 3.1
+	 */
+	int BYTE_TAG = 'B';
+	/**
+	 * Tag value for a constant of type <code>char</code>
+	 * @since 3.1
+	 */
+	int CHAR_TAG = 'C';
+	/**
+	 * Tag value for a constant of type <code>double</code>
+	 * @since 3.1
+	 */
+	int DOUBLE_TAG = 'D';
+	/**
+	 * Tag value for a constant of type <code>float</code>
+	 * @since 3.1
+	 */
+	int FLOAT_TAG = 'F';
+	/**
+	 * Tag value for a constant of type <code>int</code>
+	 * @since 3.1
+	 */
+	int INTEGER_TAG = 'I';
+	/**
+	 * Tag value for a constant of type <code>long</code>
+	 * @since 3.1
+	 */
+	int LONG_TAG = 'J';
+	/**
+	 * Tag value for a constant of type <code>short</code>
+	 * @since 3.1
+	 */
+	int SHORT_TAG = 'S';
+	/**
+	 * Tag value for a constant of type <code>boolean</code>
+	 * @since 3.1
+	 */
+	int BOOLEAN_TAG = 'Z';
+	/**
+	 * Tag value for a constant of type <code>java.lang.String</code>
+	 * @since 3.1
+	 */
+	int STRING_TAG = 's';
+	/**
+	 * Tag value for a value that represents an enum constant
+	 * @since 3.1
+	 */
+	int ENUM_TAG = 'e';
+	/**
+	 * Tag value for a value that represents a class
+	 * @since 3.1
+	 */
+	int CLASS_TAG = 'c';
+	/**
+	 * Tag value for a value that represents an annotation
+	 * @since 3.1
+	 */
+	int ANNOTATION_TAG = '@';
+	/**
+	 * Tag value for a value that represents an array
+	 * @since 3.1
+	 */
+	int ARRAY_TAG = '[';
+
+	/**
+	 * Returns the annotation component values as described in the JVM specifications
+	 * if the tag item is '['.
+	 * Returns null otherwise.
+	 *
+	 * @return the annotation component values
+	 */
+	IAnnotationComponentValue[] getAnnotationComponentValues();
+
+	/**
+	 * Returns the annotation value as described in the JVM specifications
+	 * if the tag item is '&#064;'.
+	 * Returns null otherwise.
+	 *
+	 * @return the attribute value
+	 * @since 3.1
+	 */
+	IAnnotation getAnnotationValue();
+
+	/**
+	 * Returns the class info as described in the JVM specifications
+	 * if the tag item is 'c'.
+	 * Returns null otherwise.
+	 *
+	 * @return the class info
+	 */
+	IConstantPoolEntry getClassInfo();
+
+	/**
+	 * Returns the class info index as described in the JVM specifications
+	 * if the tag item is 'c'.
+	 * Returns null otherwise.
+	 *
+	 * @return the class info index
+	 */
+	int getClassInfoIndex();
+
+	/**
+	 * Returns the constant value as described in the JVM specifications
+	 * if the tag item is one of 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', or 's'.
+	 * Returns null otherwise.
+	 *
+	 * @return the constant value
+	 */
+	IConstantPoolEntry getConstantValue();
+
+	/**
+	 * Returns the constant value index as described in the JVM specifications
+	 * if the tag item is one of 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', or 's'.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the constant value index
+	 */
+	int getConstantValueIndex();
+
+	/**
+	 * Returns the simple name of the enum constant represented
+	 * by this annotation component value as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * Returns null otherwise.
+	 *
+	 * @return the enum constant
+	 * @since 3.1
+	 */
+	char[] getEnumConstantName();
+
+	/**
+	 * Returns the utf8 constant index as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the enum constant index
+	 * @since 3.1
+	 */
+	int getEnumConstantNameIndex();
+
+	/**
+	 * Returns the binary name of the type of the enum constant represented
+	 * by this annotation component value as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * Returns null otherwise.
+	 *
+	 * @return the enum constant
+	 * @since 3.1
+	 */
+	char[] getEnumConstantTypeName();
+
+	/**
+	 * Returns the utf8 constant index as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the enum constant index
+	 * @since 3.1
+	 */
+	int getEnumConstantTypeNameIndex();
+
+	/**
+	 * Returns the tag as described in the JVM specifications.
+	 *
+	 * @return the tag
+	 */
+	int getTag();
+
+	/**
+	 * Returns the number of values as described in the JVM specifications
+	 * if the tag item is '['.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the number of values
+	 */
+	int getValuesNumber();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java
new file mode 100644
index 0000000..d1a64dd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a annotation default attribute as described in the JVM
+ * specifications (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IAnnotationDefaultAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the member value as described in the JVM specifications.
+	 *
+	 * @return the member value
+	 */
+	IAnnotationComponentValue getMemberValue();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java
new file mode 100644
index 0000000..056de2b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of attribute names as described in the JVM specifications.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IAttributeNamesConstants {
+	/**
+	 * "Synthetic" attribute.
+	 * <p>Note that prior to JDK 1.5, synthetic elements were always marked
+	 * using an attribute; with 1.5, synthetic elements can also be marked
+	 * using the {@link IModifierConstants#ACC_SYNTHETIC} flag.
+	 * </p>
+	 * @since 2.0
+	 */
+	char[] SYNTHETIC = "Synthetic".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "ConstantValue" attribute.
+	 * @since 2.0
+	 */
+	char[] CONSTANT_VALUE = "ConstantValue".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "LineNumberTable" attribute.
+	 * @since 2.0
+	 */
+	char[] LINE_NUMBER = "LineNumberTable".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "LocalVariableTable" attribute.
+	 * @since 2.0
+	 */
+	char[] LOCAL_VARIABLE = "LocalVariableTable".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "InnerClasses" attribute.
+	 * @since 2.0
+	 */
+	char[] INNER_CLASSES = "InnerClasses".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "Code" attribute.
+	 * @since 2.0
+	 */
+	char[] CODE = "Code".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "Exceptions" attribute.
+	 * @since 2.0
+	 */
+	char[] EXCEPTIONS = "Exceptions".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "SourceFile" attribute.
+	 * @since 2.0
+	 */
+	char[] SOURCE = "SourceFile".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "Deprecated" attribute.
+	 * @since 2.0
+	 */
+	char[] DEPRECATED = "Deprecated".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "Signature" attribute (added in J2SE 1.5).
+	 * Class file readers which support J2SE 1.5 return
+	 * attributes with this name represented by objects
+	 * implementing {@link ISignatureAttribute}.
+	 * @since 3.0
+	 */
+	char[] SIGNATURE = "Signature".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "EnclosingMethod" attribute (added in J2SE 1.5).
+	 * Class file readers which support J2SE 1.5 return
+	 * attributes with this name represented by objects
+	 * implementing {@link IEnclosingMethodAttribute}.
+	 * @since 3.0
+	 */
+	char[] ENCLOSING_METHOD = "EnclosingMethod".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "LocalVariableTypeTable" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "RuntimeVisibleAnnotations" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "RuntimeInvisibleAnnotations" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "RuntimeVisibleParameterAnnotations" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "RuntimeInvisibleParameterAnnotations" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "AnnotationDefault" attribute (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	char[] ANNOTATION_DEFAULT = "AnnotationDefault".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "StackMapTable" attribute (added in J2SE 1.6).
+	 * @since 3.2
+	 */
+	char[] STACK_MAP_TABLE = "StackMapTable".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "StackMap" attribute (added in cldc1.0).
+	 * @since 3.2
+	 */
+	char[] STACK_MAP = "StackMap".toCharArray(); //$NON-NLS-1$
+	
+ 	/**
+	 * "RuntimeVisibleTypeAnnotations" attribute (added in jsr 308).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	char[] RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * "RuntimeInvisibleTypeAnnotations" attribute (added in jsr 308).
+	 * @since 3.9 BETA_JAVA8
+	 */
+	char[] RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations".toCharArray(); //$NON-NLS-1$
+
+
+	/**
+	 * "BootstrapMethods" attribute (added in cldc1.0).
+	 * @since 3.8
+	 */
+	char[] BOOTSTRAP_METHODS = "BootstrapMethods".toCharArray(); //$NON-NLS-1$
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java
new file mode 100644
index 0000000..d7bbd91
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsAttribute.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a bootstrap methods attribute as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IBootstrapMethodsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of bootstrap methods of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the number of bootstrap methods of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getBootstrapMethodsLength();
+
+	/**
+	 * Answer back the bootstrap methods table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none.
+	 *
+	 * @return the bootstrap methods table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none
+	 */
+	IBootstrapMethodsEntry[] getBootstrapMethods();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java
new file mode 100644
index 0000000..4078e85
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBootstrapMethodsEntry.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a bootstrap method table entry as specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IBootstrapMethodsEntry {
+
+	int getBootstrapMethodReference();
+	int[] getBootstrapArguments();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java
new file mode 100644
index 0000000..f36db8c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a Java opcodes visitor. This should be used to walk the opcodes
+ * of a ICodeAttribute.
+ *
+ * Clients must subclass {@link ByteCodeVisitorAdapter} to define an implementation
+ * of this interface.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IBytecodeVisitor {
+
+	void _aaload(int pc);
+	void _aastore(int pc);
+	void _aconst_null(int pc);
+	void _aload(int pc, int index);
+	void _aload_0(int pc);
+	void _aload_1(int pc);
+	void _aload_2(int pc);
+	void _aload_3(int pc);
+	void _anewarray(
+		int pc,
+		int index,
+		IConstantPoolEntry constantClass);
+	void _areturn(int pc);
+	void _arraylength(int pc);
+	void _astore(int pc, int index);
+	void _astore_0(int pc);
+	void _astore_1(int pc);
+	void _astore_2(int pc);
+	void _astore_3(int pc);
+	void _athrow(int pc);
+	void _baload(int pc);
+	void _bastore(int pc);
+	void _bipush(int pc, byte _byte);
+	void _caload(int pc);
+	void _castore(int pc);
+	void _checkcast(
+		int pc,
+		int index,
+		IConstantPoolEntry constantClass);
+	void _d2f(int pc);
+	void _d2i(int pc);
+	void _d2l(int pc);
+	void _dadd(int pc);
+	void _daload(int pc);
+	void _dastore(int pc);
+	void _dcmpg(int pc);
+	void _dcmpl(int pc);
+	void _dconst_0(int pc);
+	void _dconst_1(int pc);
+	void _ddiv(int pc);
+	void _dload(int pc, int index);
+	void _dload_0(int pc);
+	void _dload_1(int pc);
+	void _dload_2(int pc);
+	void _dload_3(int pc);
+	void _dmul(int pc);
+	void _dneg(int pc);
+	void _drem(int pc);
+	void _dreturn(int pc);
+	void _dstore(int pc, int index);
+	void _dstore_0(int pc);
+	void _dstore_1(int pc);
+	void _dstore_2(int pc);
+	void _dstore_3(int pc);
+	void _dsub(int pc);
+	void _dup(int pc);
+	void _dup_x1(int pc);
+	void _dup_x2(int pc);
+	void _dup2(int pc);
+	void _dup2_x1(int pc);
+	void _dup2_x2(int pc);
+	void _f2d(int pc);
+	void _f2i(int pc);
+	void _f2l(int pc);
+	void _fadd(int pc);
+	void _faload(int pc);
+	void _fastore(int pc);
+	void _fcmpg(int pc);
+	void _fcmpl(int pc);
+	void _fconst_0(int pc);
+	void _fconst_1(int pc);
+	void _fconst_2(int pc);
+	void _fdiv(int pc);
+	void _fload(int pc, int index);
+	void _fload_0(int pc);
+	void _fload_1(int pc);
+	void _fload_2(int pc);
+	void _fload_3(int pc);
+	void _fmul(int pc);
+	void _fneg(int pc);
+	void _frem(int pc);
+	void _freturn(int pc);
+	void _fstore(int pc, int index);
+	void _fstore_0(int pc);
+	void _fstore_1(int pc);
+	void _fstore_2(int pc);
+	void _fstore_3(int pc);
+	void _fsub(int pc);
+	void _getfield(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref);
+	void _getstatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref);
+	void _goto(int pc, int branchOffset);
+	void _goto_w(int pc, int branchOffset);
+	void _i2b(int pc);
+	void _i2c(int pc);
+	void _i2d(int pc);
+	void _i2f(int pc);
+	void _i2l(int pc);
+	void _i2s(int pc);
+	void _iadd(int pc);
+	void _iaload(int pc);
+	void _iand(int pc);
+	void _iastore(int pc);
+	void _iconst_m1(int pc);
+	void _iconst_0(int pc);
+	void _iconst_1(int pc);
+	void _iconst_2(int pc);
+	void _iconst_3(int pc);
+	void _iconst_4(int pc);
+	void _iconst_5(int pc);
+	void _idiv(int pc);
+	void _if_acmpeq(int pc, int branchOffset);
+	void _if_acmpne(int pc, int branchOffset);
+	void _if_icmpeq(int pc, int branchOffset);
+	void _if_icmpne(int pc, int branchOffset);
+	void _if_icmplt(int pc, int branchOffset);
+	void _if_icmpge(int pc, int branchOffset);
+	void _if_icmpgt(int pc, int branchOffset);
+	void _if_icmple(int pc, int branchOffset);
+	void _ifeq(int pc, int branchOffset);
+	void _ifne(int pc, int branchOffset);
+	void _iflt(int pc, int branchOffset);
+	void _ifge(int pc, int branchOffset);
+	void _ifgt(int pc, int branchOffset);
+	void _ifle(int pc, int branchOffset);
+	void _ifnonnull(int pc, int branchOffset);
+	void _ifnull(int pc, int branchOffset);
+	void _iinc(int pc, int index, int _const);
+	void _iload(int pc, int index);
+	void _iload_0(int pc);
+	void _iload_1(int pc);
+	void _iload_2(int pc);
+	void _iload_3(int pc);
+	void _imul(int pc);
+	void _ineg(int pc);
+	void _instanceof(
+		int pc,
+		int index,
+		IConstantPoolEntry constantClass);
+	/**
+	 * @since 3.6
+	 * @deprecated This has been replaced with {@link #_invokedynamic(int, int, IConstantPoolEntry)}
+	 */
+	void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry nameEntry,
+			IConstantPoolEntry descriptorEntry);
+	/**
+	 * @since 3.8
+	 */
+	void _invokedynamic(
+			int pc,
+			int index,
+			IConstantPoolEntry invokeDynamic);
+	void _invokeinterface(
+		int pc,
+		int index,
+		byte nargs,
+		IConstantPoolEntry constantInterfaceMethodref);
+	void _invokespecial(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref);
+	void _invokestatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref);
+	void _invokevirtual(
+		int pc,
+		int index,
+		IConstantPoolEntry constantMethodref);
+	void _ior(int pc);
+	void _irem(int pc);
+	void _ireturn(int pc);
+	void _ishl(int pc);
+	void _ishr(int pc);
+	void _istore(int pc, int index);
+	void _istore_0(int pc);
+	void _istore_1(int pc);
+	void _istore_2(int pc);
+	void _istore_3(int pc);
+	void _isub(int pc);
+	void _iushr(int pc);
+	void _ixor(int pc);
+	void _jsr(int pc, int branchOffset);
+	void _jsr_w(int pc, int branchOffset);
+	void _l2d(int pc);
+	void _l2f(int pc);
+	void _l2i(int pc);
+	void _ladd(int pc);
+	void _laload(int pc);
+	void _land(int pc);
+	void _lastore(int pc);
+	void _lcmp(int pc);
+	void _lconst_0(int pc);
+	void _lconst_1(int pc);
+	void _ldc(int pc, int index, IConstantPoolEntry constantPoolEntry);
+	void _ldc_w(int pc, int index, IConstantPoolEntry constantPoolEntry);
+	void _ldc2_w(int pc, int index, IConstantPoolEntry constantPoolEntry);
+	void _ldiv(int pc);
+	void _lload(int pc, int index);
+	void _lload_0(int pc);
+	void _lload_1(int pc);
+	void _lload_2(int pc);
+	void _lload_3(int pc);
+	void _lmul(int pc);
+	void _lneg(int pc);
+	void _lookupswitch(
+		int pc,
+		int defaultoffset,
+		int npairs,
+		int[][] offset_pairs);
+	void _lor(int pc);
+	void _lrem(int pc);
+	void _lreturn(int pc);
+	void _lshl(int pc);
+	void _lshr(int pc);
+	void _lstore(int pc, int index);
+	void _lstore_0(int pc);
+	void _lstore_1(int pc);
+	void _lstore_2(int pc);
+	void _lstore_3(int pc);
+	void _lsub(int pc);
+	void _lushr(int pc);
+	void _lxor(int pc);
+	void _monitorenter(int pc);
+	void _monitorexit(int pc);
+	void _multianewarray(
+		int pc,
+		int index,
+		int dimensions,
+		IConstantPoolEntry constantClass);
+	void _new(
+		int pc,
+		int index,
+		IConstantPoolEntry constantClass);
+	void _newarray(int pc, int atype);
+	void _nop(int pc);
+	void _pop(int pc);
+	void _pop2(int pc);
+	void _putfield(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref);
+	void _putstatic(
+		int pc,
+		int index,
+		IConstantPoolEntry constantFieldref);
+	void _ret(int pc, int index);
+	void _return(int pc);
+	void _saload(int pc);
+	void _sastore(int pc);
+	void _sipush(int pc, short value);
+	void _swap(int pc);
+	void _tableswitch(
+		int pc,
+		int defaultoffset,
+		int low,
+		int high,
+		int[] jump_offsets);
+	void _wide(
+		int pc,
+		int opcode,
+		int index);
+	void _wide(
+		int pc,
+		int iincopcode,
+		int index,
+		int _const);
+	void _breakpoint(int pc);
+	void _impdep1(int pc);
+	void _impdep2(int pc);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java
new file mode 100644
index 0000000..ba6afb5
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * This class represents a generic class file attribute. It is intended to be extended
+ * for any new attribute.
+ *
+ * @since 2.0
+ */
+public interface IClassFileAttribute {
+
+	/**
+	 * Answer back the attribute name index in the constant pool as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the attribute name index in the constant pool
+	 */
+	int getAttributeNameIndex();
+
+	/**
+	 * Answer back the attribute name as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the attribute name
+	 */
+	char[] getAttributeName();
+
+	/**
+	 * Answer back the attribute length as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the attribute length
+	 */
+	long getAttributeLength();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java
new file mode 100644
index 0000000..6eaeb13
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * This interface is intended to be implemented to disassemble
+ * IClassFileReader onto a String using the proper line separator.
+ *
+ * @since 2.0
+ * @deprecated Use {@link ClassFileBytesDisassembler} instead
+ */
+public interface IClassFileDisassembler {
+
+	/**
+	 * The mode is the detailed mode to disassemble IClassFileReader. It returns the magic
+	 * numbers, the version numbers and field and method descriptors.
+	 */
+	int DETAILED = 1;
+
+	/**
+	 * The mode is the default mode to disassemble IClassFileReader.
+	 */
+	int DEFAULT  = 2;
+	/**
+	 * Answers back the disassembled string of the IClassFileReader using the default
+	 * mode.
+	 * This is an output quite similar to the javap tool, using DEFAULT mode.
+	 *
+	 * @param classFileReader The classFileReader to be disassembled
+	 * @param lineSeparator the line separator to use.
+	 *
+	 * @return the disassembled string of the IClassFileReader using the default mode.
+	 */
+	String disassemble(IClassFileReader classFileReader, String lineSeparator);
+
+	/**
+	 * Answers back the disassembled string of the IClassFileReader according to the
+	 * mode.
+	 * This is an output quite similar to the javap tool.
+	 *
+	 * @param classFileReader The classFileReader to be disassembled
+	 * @param lineSeparator the line separator to use.
+	 * @param mode the mode used to disassemble the IClassFileReader
+	 *
+	 * @return the disassembled string of the IClassFileReader according to the mode
+	 */
+	String disassemble(IClassFileReader classFileReader, String lineSeparator, int mode);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java
new file mode 100644
index 0000000..3ce95da
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a .class file. This class reifies the internal structure of a .class
+ * file following the JVM specifications.
+ * <p>
+ * Note that several changes were introduced with J2SE 1.5.
+ * Class file reader implementations should use support these
+ * new class file attributes by returning objects implementing
+ * the appropriate specialized attribute interfaces. Class
+ * file reader clients can search for these new attributes
+ * and downcast to the new interfaces as appropriate.
+ * </p>
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IClassFileReader {
+	/**
+	 * This value should be used to read completely each part of a .class file.
+	 */
+	int ALL 					= 0xFFFF;
+
+	/**
+	 * This value should be used to read only the constant pool entries of a .class file.
+	 */
+	int CONSTANT_POOL 			= 0x0001;
+
+	/**
+	 * This value should be used to read the constant pool entries and
+	 * the method infos of a .class file.
+	 */
+	int METHOD_INFOS 			= 0x0002 + CONSTANT_POOL;
+
+	/**
+	 * This value should be used to read the constant pool entries and
+	 * the field infos of a .class file.
+	 */
+	int FIELD_INFOS 			= 0x0004 + CONSTANT_POOL;
+
+	/**
+	 * This value should be used to read the constant pool entries and
+	 * the super interface names of a .class file.
+	 */
+	int SUPER_INTERFACES 		= 0x0008 + CONSTANT_POOL;
+
+	/**
+	 * This value should be used to read the constant pool entries and
+	 * the attributes of a .class file.
+	 */
+	int CLASSFILE_ATTRIBUTES 	= 0x0010 + CONSTANT_POOL;
+
+	/**
+	 * This value should be used to read the method bodies.
+	 * It has to be used with METHOD_INFOS.
+	 */
+	int METHOD_BODIES 			= 0x0020;
+
+	/**
+	 * This value should be used to read the whole contents of the .class file except the
+	 * method bodies.
+	 */
+	int ALL_BUT_METHOD_BODIES   = ALL & ~METHOD_BODIES;
+
+	/**
+	 * Answer back the access flag of the .class file.
+	 *
+	 * @return the access flag of the .class file
+	 */
+	int getAccessFlags();
+
+	/**
+	 * Answer back the array of field infos of the .class file,
+	 * an empty array if none.
+	 *
+	 * @return the array of field infos of the .class file, an empty array if none
+	 */
+	IFieldInfo[] getFieldInfos();
+
+	/**
+	 * Answer back the names of interfaces implemented by this .class file,
+	 * an empty array if none. The names are returned as described in the
+	 * JVM specifications.
+	 *
+	 * @return the names of interfaces implemented by this .class file, an empty array if none
+	 */
+	char[][] getInterfaceNames();
+
+	/**
+	 * Answer back the indexes in the constant pool of interfaces implemented
+	 * by this .class file, an empty array if none.
+	 *
+	 * @return the indexes in the constant pool of interfaces implemented
+	 * by this .class file, an empty array if none
+	 */
+	int[] getInterfaceIndexes();
+
+	/**
+	 * Answer back the inner classes attribute of this .class file, null if none.
+	 *
+	 * @return the inner classes attribute of this .class file, null if none
+	 */
+	IInnerClassesAttribute getInnerClassesAttribute();
+
+	/**
+	 * Answer back the array of method infos of this .class file,
+	 * an empty array if none.
+	 *
+	 * @return the array of method infos of this .class file,
+	 * an empty array if none
+	 */
+	IMethodInfo[] getMethodInfos();
+
+	/**
+	 * Answer back the qualified name of the .class file.
+	 * The name is returned as described in the JVM specifications.
+	 *
+	 * @return the qualified name of the .class file
+	 */
+	char[] getClassName();
+
+	/**
+	 * Answer back the index of the class name in the constant pool
+	 * of the .class file.
+	 *
+	 * @return the index of the class name in the constant pool
+	 */
+	int getClassIndex();
+
+	/**
+	 * Answer back the qualified name of the superclass of this .class file.
+	 * The name is returned as described in the JVM specifications. Answer null if
+	 * getSuperclassIndex() is zero.
+	 *
+	 * @return the qualified name of the superclass of this .class file, null if getSuperclassIndex() is zero
+	 */
+	char[] getSuperclassName();
+
+	/**
+	 * Answer back the index of the superclass name in the constant pool
+	 * of the .class file. Answer 0 if this .class file represents java.lang.Object.
+	 *
+	 * @return the index of the superclass name in the constant pool
+	 * of the .class file, 0 if this .class file represents java.lang.Object.
+	 */
+	int getSuperclassIndex();
+
+	/**
+	 * Answer true if this .class file represents an class, false otherwise.
+	 *
+	 * @return true if this .class file represents an class, false otherwise
+	 */
+	boolean isClass();
+
+	/**
+	 * Answer true if this .class file represents an interface, false otherwise.
+	 *
+	 * @return true if this .class file represents an interface, false otherwise
+	 */
+	boolean isInterface();
+
+	/**
+	 * Answer the source file attribute, if it exists, null otherwise.
+	 *
+	 * @return the source file attribute, if it exists, null otherwise
+	 */
+	ISourceAttribute getSourceFileAttribute();
+
+	/**
+	 * Answer the constant pool of this .class file.
+	 *
+	 * @return the constant pool of this .class file
+	 */
+	IConstantPool getConstantPool();
+
+	/**
+	 * Answer the minor version of this .class file.
+	 *
+	 * @return the minor version of this .class file
+	 */
+	int getMinorVersion();
+
+	/**
+	 * Answer the major version of this .class file.
+	 *
+	 * @return the major version of this .class file
+	 */
+	int getMajorVersion();
+
+	/**
+	 * Answer back the attribute number of the .class file.
+	 *
+	 * @return the attribute number of the .class file
+	 */
+	int getAttributeCount();
+
+	/**
+	 * Answer back the collection of all attributes of the field info. It
+	 * includes SyntheticAttribute, ConstantValueAttributes, etc. Answers an empty
+	 * array if none.
+	 *
+	 * @return the collection of all attributes of the field info. It
+	 * includes SyntheticAttribute, ConstantValueAttributes, etc. Answers an empty
+	 * array if none
+	 */
+	IClassFileAttribute[] getAttributes();
+
+	/**
+	 * Answer back the magic number.
+	 *
+	 * @return the magic number
+	 */
+	int getMagic();
+
+	/**
+	 * Answer back the number of field infos.
+	 *
+	 * @return the number of field infos
+	 */
+	int getFieldsCount();
+
+	/**
+	 * Answer back the number of method infos.
+	 *
+	 * @return the number of method infos
+	 */
+	int getMethodsCount();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java
new file mode 100644
index 0000000..ee78d8a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a code attribute as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface ICodeAttribute extends IClassFileAttribute {
+	/**
+	 * Answer back the max locals value of the code attribute.
+	 *
+	 * @return the max locals value of the code attribute
+	 */
+	int getMaxLocals();
+
+	/**
+	 * Answer back the max stack value of the code attribute.
+	 *
+	 * @return the max stack value of the code attribute
+	 */
+	int getMaxStack();
+
+	/**
+	 * Answer back the line number attribute, if it exists, null otherwise.
+	 *
+	 * @return the line number attribute, if it exists, null otherwise
+	 */
+	ILineNumberAttribute getLineNumberAttribute();
+
+	/**
+	 * Answer back the local variable attribute, if it exists, null otherwise.
+	 *
+	 * @return the local variable attribute, if it exists, null otherwise
+	 */
+	ILocalVariableAttribute getLocalVariableAttribute();
+
+	/**
+	 * Answer back the array of exception entries, if they are present.
+	 * An empty array otherwise.
+	 *
+	 * @return the array of exception entries, if they are present.
+	 * An empty array otherwise
+	 */
+	IExceptionTableEntry[] getExceptionTable();
+
+	/**
+	 * Answer back the array of bytes, which represents all the opcodes as described
+	 * in the JVM specifications.
+	 *
+	 * @return the array of bytes, which represents all the opcodes as described
+	 * in the JVM specifications
+	 */
+	byte[] getBytecodes();
+
+	/**
+	 * Answer back the length of the bytecode contents.
+	 *
+	 * @return the length of the bytecode contents
+	 */
+	long getCodeLength();
+
+	/**
+	 * Answer back the attribute number of the code attribute.
+	 *
+	 * @return the attribute number of the code attribute
+	 */
+	int getAttributesCount();
+
+	/**
+	 * Answer back the collection of all attributes of the field info. It
+	 * includes the LineNumberAttribute and the LocalVariableTableAttribute.
+	 * Returns an empty collection if none.
+	 *
+	 * @return the collection of all attributes of the field info. It
+	 * includes the LineNumberAttribute and the LocalVariableTableAttribute.
+	 * Returns an empty collection if none
+	 */
+	IClassFileAttribute[] getAttributes();
+
+	/**
+	 * Answer back the exception table length of the code attribute.
+	 *
+	 * @return the exception table length of the code attribute
+	 */
+	int getExceptionTableLength();
+
+	/**
+	 * Define a Java opcodes walker. All actions are defined in the visitor.
+	 * @param visitor The visitor to use to walk the opcodes.
+	 *
+	 * @exception ClassFormatException Exception thrown if the opcodes contain invalid bytes
+	 */
+	void traverse(IBytecodeVisitor visitor) throws ClassFormatException;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java
new file mode 100644
index 0000000..9f57bb1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a constant pool as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IConstantPool {
+
+	/**
+	 * Answer back the number of entries in the constant pool.
+	 *
+	 * @return the number of entries in the constant pool
+	 */
+	int getConstantPoolCount();
+
+	/**
+	 * Answer back the type of the entry at the given index in the constant pool.
+	 *
+	 * @param index the index of the entry in the constant pool
+	 * @return the type of the entry at the index @index in the constant pool
+	 */
+	int getEntryKind(int index);
+
+	/**
+	 * Answer back the entry at the given index in the constant pool.
+	 * 
+	 * <p>The return value can be an instance of {@link IConstantPoolEntry2} if the value returned
+	 * by {@link #getEntryKind(int)} is either {@link IConstantPoolConstant#CONSTANT_MethodHandle},
+	 * {@link IConstantPoolConstant#CONSTANT_MethodType} or {@link IConstantPoolConstant#CONSTANT_InvokeDynamic}.</p>
+	 *
+	 * @param index the index of the entry in the constant pool
+	 * @return the entry at the given index in the constant pool
+	 */
+	IConstantPoolEntry decodeEntry(int index);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java
new file mode 100644
index 0000000..ff6ed22
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of constant pool constants as described in the JVM specifications.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IConstantPoolConstant {
+
+	int CONSTANT_Class = 7;
+	int CONSTANT_Fieldref = 9;
+	int CONSTANT_Methodref = 10;
+	int CONSTANT_InterfaceMethodref = 11;
+	int CONSTANT_String = 8;
+	int CONSTANT_Integer = 3;
+	int CONSTANT_Float = 4;
+	int CONSTANT_Long = 5;
+	int CONSTANT_Double = 6;
+	int CONSTANT_NameAndType = 12;
+	int CONSTANT_Utf8 = 1;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_MethodHandle = 15;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_MethodType = 16;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_InvokeDynamic = 18;
+
+	int CONSTANT_Methodref_SIZE = 5;
+	int CONSTANT_Class_SIZE = 3;
+	int CONSTANT_Double_SIZE = 9;
+	int CONSTANT_Fieldref_SIZE = 5;
+	int CONSTANT_Float_SIZE = 5;
+	int CONSTANT_Integer_SIZE = 5;
+	int CONSTANT_InterfaceMethodref_SIZE = 5;
+	int CONSTANT_Long_SIZE = 9;
+	int CONSTANT_String_SIZE = 3;
+	int CONSTANT_Utf8_SIZE = 3;
+	int CONSTANT_NameAndType_SIZE = 5;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_MethodHandle_SIZE = 4;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_MethodType_SIZE = 3;
+	/**
+	 * @since 3.8
+	 */
+	int CONSTANT_InvokeDynamic_SIZE = 5;
+
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_GetField = 1;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_GetStatic = 2;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_PutField = 3;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_PutStatic = 4;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_InvokeVirtual = 5;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_InvokeStatic = 6;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_InvokeSpecial = 7;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_NewInvokeSpecial = 8;
+	/**
+	 * The constant is described at 5.4.3.5 in the Java 7 VM specification (part 3).
+	 * @since 3.8
+	 */
+	int METHOD_TYPE_REF_InvokeInterface = 9;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java
new file mode 100644
index 0000000..c75bd40
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a constant pool entry as described in the JVM specifications.
+ * Its contents is initialized according to its kind.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IConstantPoolEntry {
+
+	/**
+	 * Returns the type of this entry.
+	 *
+	 * @return the type of this entry
+	 */
+	int getKind();
+
+	/**
+	 * Returns the name index for a CONSTANT_Class type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the name index for a CONSTANT_Class type entry
+	 * @see IConstantPoolConstant#CONSTANT_Class
+	 */
+	int getClassInfoNameIndex();
+
+	/**
+	 * Returns the class index for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the class index for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry
+	 * @see IConstantPoolConstant#CONSTANT_Fieldref
+	 * @see IConstantPoolConstant#CONSTANT_Methodref
+	 * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref
+	 */
+	int getClassIndex();
+
+	/**
+	 * Returns the nameAndType index for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref,
+	 * CONSTANT_InvokeDynamic type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the nameAndType index for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref,
+	 * CONSTANT_InvokeDynamic type entry
+	 * @see IConstantPoolConstant#CONSTANT_Fieldref
+	 * @see IConstantPoolConstant#CONSTANT_Methodref
+	 * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref
+	 * @see IConstantPoolConstant#CONSTANT_InvokeDynamic
+	 */
+	int getNameAndTypeIndex();
+
+	/**
+	 * Returns the string index for a CONSTANT_String type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the string index for a CONSTANT_String type entry
+	 * @see IConstantPoolConstant#CONSTANT_String
+	 */
+	int getStringIndex();
+
+	/**
+	 * Returns the string value for a CONSTANT_String type entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the string value for a CONSTANT_String type entry
+	 * @see IConstantPoolConstant#CONSTANT_String
+	 */
+	String getStringValue();
+
+	/**
+	 * Returns the integer value for a CONSTANT_Integer type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the integer value for a CONSTANT_Integer type entry
+	 * @see IConstantPoolConstant#CONSTANT_Integer
+	 */
+	int getIntegerValue();
+
+	/**
+	 * Returns the float value for a CONSTANT_Float type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the float value for a CONSTANT_Float type entry
+	 * @see IConstantPoolConstant#CONSTANT_Float
+	 */
+	float getFloatValue();
+
+	/**
+	 * Returns the double value for a CONSTANT_Double type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the double value for a CONSTANT_Double type entry
+	 * @see IConstantPoolConstant#CONSTANT_Double
+	 */
+	double getDoubleValue();
+
+	/**
+	 * Returns the long value for a CONSTANT_Long type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the long value for a CONSTANT_Long type entry
+	 * @see IConstantPoolConstant#CONSTANT_Long
+	 */
+	long getLongValue();
+
+	/**
+	 * Returns the descriptor index for a CONSTANT_NameAndType type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the descriptor index for a CONSTANT_NameAndType type entry
+	 * @see IConstantPoolConstant#CONSTANT_NameAndType
+	 */
+	int getNameAndTypeInfoDescriptorIndex();
+
+	/**
+	 * Returns the name index for a CONSTANT_NameAndType type entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the name index for a CONSTANT_NameAndType type entry
+	 * @see IConstantPoolConstant#CONSTANT_NameAndType
+	 */
+	int getNameAndTypeInfoNameIndex();
+
+	/**
+	 * Returns the class name for a CONSTANT_Class type entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the class name for a CONSTANT_Class type entry
+	 * @see IConstantPoolConstant#CONSTANT_Class
+	 */
+	char[] getClassInfoName();
+
+	/**
+	 * Returns the class name for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the class name for a CONSTANT_Fieldref,
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry
+	 * @see IConstantPoolConstant#CONSTANT_Fieldref
+	 * @see IConstantPoolConstant#CONSTANT_Methodref
+	 * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref
+	 */
+	char[] getClassName();
+
+	/**
+	 * Returns the field name for a CONSTANT_Fieldref type entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the field name for a CONSTANT_Fieldref type entry
+	 * @see IConstantPoolConstant#CONSTANT_Fieldref
+	 */
+	char[] getFieldName();
+
+	/**
+	 * Returns the field name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref
+	 * or CONSTANT_InvokeDynamic type entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the method name for a CONSTANT_Methodref, CONSTANT_InterfaceMethodref
+	 * or CONSTANT_InvokeDynamic type entry
+	 * @see IConstantPoolConstant#CONSTANT_Methodref
+	 * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref
+	 * @see IConstantPoolConstant#CONSTANT_InvokeDynamic
+	 */
+	char[] getMethodName();
+
+	/**
+	 * Returns the field descriptor value for a CONSTANT_Fieldref type entry. This value
+	 * is set only when decoding the CONSTANT_Fieldref entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the field descriptor value for a CONSTANT_Fieldref type entry. This value
+	 * is set only when decoding the CONSTANT_Fieldref entry
+	 * @see IConstantPoolConstant#CONSTANT_Fieldref
+	 */
+	char[] getFieldDescriptor();
+
+	/**
+	 * Returns the method descriptor value for a CONSTANT_Methodref or
+	 * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType
+	 * or CONSTANT_InvokeDynamic entry.
+	 * 
+	 * Returns null otherwise.
+	 *
+	 * @return the method descriptor value for a CONSTANT_Methodref,
+	 * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the
+	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, CONSTANT_MethodType
+	 * or CONSTANT_InvokeDynamic entry
+	 *
+	 * @see IConstantPoolConstant#CONSTANT_Methodref
+	 * @see IConstantPoolConstant#CONSTANT_InterfaceMethodref
+	 * @see IConstantPoolConstant#CONSTANT_MethodType
+	 * @see IConstantPoolConstant#CONSTANT_InvokeDynamic
+	 */
+	char[] getMethodDescriptor();
+
+	/**
+	 * Returns the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when
+	 * decoding a UTF8 entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when
+	 * decoding a UTF8 entry
+	 * @see IConstantPoolConstant#CONSTANT_Utf8
+	 */
+	char[] getUtf8Value();
+
+	/**
+	 * Returns the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when
+	 * decoding a UTF8 entry.
+	 * Returns null otherwise.
+	 *
+	 * @return the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when
+	 * decoding a UTF8 entry
+	 * @see IConstantPoolConstant#CONSTANT_Utf8
+	 */
+	int getUtf8Length();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java
new file mode 100644
index 0000000..3b4984b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry2.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of the new constant pool entry as described in the JVM specifications
+ * added for Java 7 support.
+ * Its contents is initialized according to its kind.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.8
+ */
+public interface IConstantPoolEntry2 extends IConstantPoolEntry {
+	/**
+	 * Returns the descriptor index. This value is set only when decoding a MethodType entry.
+	 * The value is unspecified otherwise. The corresponding UTF8 value can be retrieved by using
+	 * {@link #getMethodDescriptor()}.
+	 *
+	 * @return the descriptor index. This value is set only when decoding a MethodType entry.
+	 * @see IConstantPoolConstant#CONSTANT_MethodType
+	 */
+	int getDescriptorIndex();
+
+	/**
+	 * Returns the reference kind. This value is set only when decoding a MethodHandle entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+	 * @see IConstantPoolConstant#CONSTANT_MethodHandle
+	 */
+	int getReferenceKind();
+
+	/**
+	 * Returns the reference index. This value is set only when decoding a MethodHandle entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+	 * @see IConstantPoolConstant#CONSTANT_MethodHandle
+	 */
+	int getReferenceIndex();
+	
+	/**
+	 * Returns the bootstrap method attribute index. This value is set only when decoding a InvokeDynamic entry.
+	 * The value is unspecified otherwise.
+	 *
+	 * @return the reference kind. This value is set only when decoding a MethodHandle entry.
+	 * @see IConstantPoolConstant#CONSTANT_InvokeDynamic
+	 */
+	int getBootstrapMethodAttributeIndex();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java
new file mode 100644
index 0000000..0c9c902
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a constant value attribute as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IConstantValueAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the constant value index.
+	 *
+	 * @return the constant value index
+	 */
+	int getConstantValueIndex();
+
+	/**
+	 * Answer back the constant pool entry that represents the constant
+	 * value of this attribute.
+	 *
+	 * @return the constant pool entry that represents the constant
+	 * value of this attribute
+	 */
+	IConstantPoolEntry getConstantValue();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java
new file mode 100644
index 0000000..90a03b6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of an enclosing method attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IEnclosingMethodAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the enclosing class name as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the enclosing class name as specified
+	 * in the JVM specifications
+	 */
+	char[] getEnclosingClass();
+
+	/**
+	 * Answer back the enclosing class name index.
+	 *
+	 * @return the enclosing class name index
+	 */
+	int getEnclosingClassIndex();
+
+	/**
+	 * Answer back the method descriptor of the enclosing method as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the method descriptor of the enclosing method as specified
+	 * in the JVM specifications
+	 */
+	char[] getMethodDescriptor();
+
+	/**
+	 * Answer back the descriptor index of the enclosing method.
+	 *
+	 * @return the descriptor index of the enclosing method
+	 */
+	int getMethodDescriptorIndex();
+
+	/**
+	 * Answer back the name of the enclosing method as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the name of the enclosing method as specified
+	 * in the JVM specifications
+	 */
+	char[] getMethodName();
+
+	/**
+	 * Answer back the name index of the enclosing method.
+	 *
+	 * @return the name index of the enclosing method
+	 */
+	int getMethodNameIndex();
+
+	/**
+	 * Answer back the name and type index of this attribute.
+	 *
+	 * @return the name and type index of this attribute
+	 */
+	int getMethodNameAndTypeIndex();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java
new file mode 100644
index 0000000..98c4927
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a constant value attribute as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IExceptionAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of exceptions of the exception attribute.
+	 *
+	 * @return the number of exceptions of the exception attribute
+	 */
+	int getExceptionsNumber();
+
+	/**
+	 * Answer back the exception names of the exception attribute. Answers an
+	 * empty collection if none.
+	 *
+	 * @return the exception names of the exception attribute. Answers an
+	 * empty collection if none
+	 */
+	char[][] getExceptionNames();
+
+	/**
+	 * Answer back the exception indexes of the exception attribute. Answers an
+	 * empty collection if none.
+	 *
+	 * @return the exception indexes of the exception attribute. Answers an
+	 * empty collection if none
+	 */
+	int[] getExceptionIndexes();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java
new file mode 100644
index 0000000..8f99387
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * The class represents an entry in the exception table of a ICodeAttribute as
+ * specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IExceptionTableEntry {
+
+	/**
+	 * Answer back the start pc of this entry.
+	 *
+	 * @return the start pc of this entry
+	 */
+	int getStartPC();
+
+	/**
+	 * Answer back the end pc of this entry.
+	 *
+	 * @return the end pc of this entry
+	 */
+	int getEndPC();
+
+	/**
+	 * Answer back the handler pc of this entry.
+	 *
+	 * @return the handler pc of this entry
+	 */
+	int getHandlerPC();
+
+	/**
+	 * Answer back the catch type index in the constant pool.
+	 *
+	 * @return the catch type index in the constant pool
+	 */
+	int getCatchTypeIndex();
+
+	/**
+	 * Answer back the catch type name, null if getCatchTypeIndex() returns 0.
+	 * This is the case for any exception handler.
+	 *
+	 * @return the catch type name, null if getCatchTypeIndex() returns 0.
+	 * This is the case for any exception handler
+	 */
+	char[] getCatchType();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java
new file mode 100644
index 0000000..d6eb7df
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotation.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of an extended annotation structure as described in the JVM specifications
+ * (added in JavaSE-1.8).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+public interface IExtendedAnnotation extends IAnnotation {
+	/**
+	 * Answer back the target type as described in the JVM specifications.
+	 *
+	 * @return the target type
+	 */
+	int getTargetType();
+	
+	/**
+	 * Answer back the offset.
+	 * 
+	 * For a target_type value equals to:
+	 * <table border="1">
+	 * <tr>
+	 * <th>target_type</th>
+	 * <th>offset description</th>
+	 * </tr>
+	 * <tr>
+	 * <td>0x43 (INSTANCE_OF), 0x44 (NEW), 0x45 (CONSTRUCTOR_REFERENCE), 0x46 (METHOD_REFERENCE)</td>
+	 * <td>The offset within the bytecodes of the <code>instanceof</code> bytecode for INSTANCE_OF,
+	 * the <code>new</code> bytecode for NEW and the implementing instruction for either a
+	 * CONSTRUCTOR_REFERENCE or METHOD_REFERENCE.</td>
+	 * </tr>
+	 * <tr>
+	 * <td>0x47 (CAST), 0x48 (CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT), 0x49 (METHOD_INVOCATION_TYPE_ARGUMENT),
+	 * 0x4A (CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT), 0x4B (METHOD_REFERENCE_TYPE_ARGUMENT)</td>
+	 * <td>The offset within the bytecodes of the <code>new</code> bytecode for constructor call, or the
+	 * relevant bytecode for method invocation or method reference. For CAST the offset may
+	 * point to the <code>checkcast</code> or another instruction as it is possible the cast
+	 * may have been discarded by the compiler if it were a no-op.</td>
+	 * </tr>
+	 * </table>
+	 * 
+	 * 
+	 * @return the offset
+	 */
+	int getOffset();
+	
+	/**
+	 * Answer back the exception table index when the target_type is EXCEPTION_PARAMETER.
+	 * 
+	 * @return the exception table index
+	 */
+	int getExceptionTableIndex();
+	
+	/**
+	 * Answer back the local variable reference info table length of this entry as specified in
+	 * the JVM specifications.
+	 * 
+	 * <p>This is defined only for annotations related a local variable.</p>
+	 *
+	 * @return the local variable reference info table length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLocalVariableRefenceInfoLength();
+	
+	/**
+	 * Answer back the local variable reference info table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none.
+	 * 
+	 * <p>This is defined only for annotations related a local variable.</p>
+	 *
+	 * @return the local variable reference info table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none
+	 */
+	ILocalVariableReferenceInfo[] getLocalVariableTable();
+	
+	/**
+	 * Answer back the method parameter index.
+	 * 
+	 * <p>The index is 0-based.</p>
+	 * 
+	 * @return the method parameter index
+	 */
+	int getParameterIndex();
+
+	/**
+	 * Answer back the index of the type parameter of the class or method
+	 * 
+	 * <p>The index is 0-based.</p>
+	 * 
+	 * @return the index of the type parameter of the class or method
+	 */
+	int getTypeParameterIndex();
+
+	/**
+	 * Answer back the index of the bound of the type parameter of the method or class
+	 * 
+	 * <p>The index is 0-based.</p>
+	 * 
+	 * @return the index of the bound of the type parameter of the method or class
+	 */
+	int getTypeParameterBoundIndex();
+
+	/**
+	 * Answer back the index in the given different situations.
+	 * 
+	 * <p>The index is 0-based.</p>
+	 * 
+	 * <table border="1">
+	 * <tr>
+	 * <th>target_type</th>
+	 * <th>offset description</th>
+	 * </tr>
+	 * <tr>
+	 * <td>0x10 (CLASS_EXTENDS)</td>
+	 * <td>the index of the type in the clause: <code>-1 (65535)</code> is used if the annotation is on 
+	 * the superclass type, and the value <code>i</code> is used if the annotation is on the <code>i</code>th
+	 * superinterface type (counting from zero).</td>
+	 * </tr>
+	 * <tr>
+	 * <td>0x17 (THROWS)</td>
+	 * <td>the index of the exception type in the clause: the value <code>i</code> denotes an annotation of the 
+	 * <code>i</code>th exception type (counting from zero).</td>
+	 * </tr>
+	 * <tr>
+	 * <td>0x47 (CAST), 0x48 (CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT), 0x49 (METHOD_INVOCATION_TYPE_ARGUMENT),
+	 * 0x4A (CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT), 0x4B (METHOD_REFERENCE_TYPE_ARGUMENT)</td>
+	 * <td>the type argument index in the expression</td>
+	 * </tr>
+	 * </table>
+	 * @return the index in the given different situations
+	 */
+	int getAnnotationTypeIndex();
+	
+	/**
+	 * Answer back the locations of the annotated type as described in the JVM specifications.
+	 * 
+	 * <p>This is used for parameterized and array types.</p>
+	 *
+	 * @return the locations of the annotated type
+	 */
+	int[][] getTypePath();
+	
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java
new file mode 100644
index 0000000..c849076
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExtendedAnnotationConstants.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
+
+/**
+ * Description of an extended annotation target types constants as described in the JVM specifications
+ * (added in JavaSE-1.8).
+ *
+ * @since 3.9 BETA_JAVA8
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IExtendedAnnotationConstants {
+	
+	int CLASS_TYPE_PARAMETER = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER;
+	int METHOD_TYPE_PARAMETER = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER;
+
+	int CLASS_EXTENDS = AnnotationTargetTypeConstants.CLASS_EXTENDS;
+	int CLASS_TYPE_PARAMETER_BOUND = AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND;
+	int METHOD_TYPE_PARAMETER_BOUND = AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND;
+	int FIELD = AnnotationTargetTypeConstants.FIELD;
+	int METHOD_RETURN = AnnotationTargetTypeConstants.METHOD_RETURN;
+	int METHOD_RECEIVER = AnnotationTargetTypeConstants.METHOD_RECEIVER;
+	int METHOD_FORMAL_PARAMETER = AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER;
+	int THROWS = AnnotationTargetTypeConstants.THROWS;
+
+	int LOCAL_VARIABLE = AnnotationTargetTypeConstants.LOCAL_VARIABLE;
+	int RESOURCE_VARIABLE = AnnotationTargetTypeConstants.RESOURCE_VARIABLE;
+	int EXCEPTION_PARAMETER = AnnotationTargetTypeConstants.EXCEPTION_PARAMETER;
+	int INSTANCEOF = AnnotationTargetTypeConstants.INSTANCEOF;
+	int NEW = AnnotationTargetTypeConstants.NEW;
+	int CONSTRUCTOR_REFERENCE = AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE;
+	int METHOD_REFERENCE = AnnotationTargetTypeConstants.METHOD_REFERENCE;
+	int CAST = AnnotationTargetTypeConstants.CAST;
+	int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = AnnotationTargetTypeConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
+	int METHOD_INVOCATION_TYPE_ARGUMENT = AnnotationTargetTypeConstants.METHOD_INVOCATION_TYPE_ARGUMENT;
+	int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = AnnotationTargetTypeConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
+	int METHOD_REFERENCE_TYPE_ARGUMENT = AnnotationTargetTypeConstants.METHOD_REFERENCE_TYPE_ARGUMENT;
+	
+	// Type path entry kinds
+	int TYPE_PATH_DEEPER_IN_ARRAY = 0;
+	int TYPE_PATH_DEEPER_IN_INNER_TYPE = 1;
+	int TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND = 2;
+	int TYPE_PATH_TYPE_ARGUMENT_INDEX = 3;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java
new file mode 100644
index 0000000..cfca556
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a field info as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IFieldInfo {
+
+	/**
+	 * Answer back the constant value attribute of this field info if specified,
+	 * null otherwise.
+	 *
+	 * @return the constant value attribute of this field info if specified,
+	 * null otherwise
+	 */
+	IConstantValueAttribute getConstantValueAttribute();
+
+	/**
+	 * Answer back the access flag of this field info.
+	 *
+	 * @return the access flag of this field info
+	 */
+	int getAccessFlags();
+
+	/**
+	 * Answer back the name of this field info. The name is returned as
+	 * specified in the JVM specifications.
+	 *
+	 * @return the name of this field info. The name is returned as
+	 * specified in the JVM specifications
+	 */
+	char[] getName();
+
+	/**
+	 * Answer back the name index of this field info.
+	 *
+	 * @return the name index of this field info
+	 */
+	int getNameIndex();
+
+	/**
+	 * Answer back the descriptor of this field info. The descriptor is returned as
+	 * specified in the JVM specifications.
+	 *
+	 * @return the descriptor of this field info. The descriptor is returned as
+	 * specified in the JVM specifications
+	 */
+	char[] getDescriptor();
+
+	/**
+	 * Answer back the descriptor index of this field info.
+	 *
+	 * @return the descriptor index of this field info
+	 */
+	int getDescriptorIndex();
+
+	/**
+	 * Return true if the field info has a constant value attribute, false otherwise.
+	 *
+	 * @return true if the field info has a constant value attribute, false otherwise
+	 */
+	boolean hasConstantValueAttribute();
+
+	/**
+	 * Return true if the field info is synthetic according to the JVM specification, false otherwise.
+	 * <p>Note that prior to JDK 1.5, synthetic fields were always marked using
+	 * an attribute; with 1.5, synthetic fields can also be marked using
+	 * the {@link IModifierConstants#ACC_SYNTHETIC} flag.
+	 * </p>
+	 *
+	 * @return true if the field info is synthetic according to the JVM specification, false otherwise
+	 */
+	boolean isSynthetic();
+
+	/**
+	 * Return true if the field info has a deprecated attribute, false otherwise.
+	 *
+	 * @return true if the field info has a deprecated attribute, false otherwise
+	 */
+	boolean isDeprecated();
+
+	/**
+	 * Answer back the attribute number of the field info.
+	 *
+	 * @return the attribute number of the field info
+	 */
+	int getAttributeCount();
+
+
+	/**
+	 * Answer back the collection of all attributes of the field info. It
+	 * includes SyntheticAttribute, ConstantValueAttributes, etc.
+	 * Returns an empty collection if none.
+	 *
+	 * @return the collection of all attributes of the field info. It
+	 * includes SyntheticAttribute, ConstantValueAttributes, etc.
+	 * Returns an empty collection if none
+	 */
+	IClassFileAttribute[] getAttributes();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java
new file mode 100644
index 0000000..ada85a2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a inner class attribute as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IInnerClassesAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of inner classes infos as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the number of inner classes infos as specified in
+	 * the JVM specifications
+	 */
+	int getNumberOfClasses();
+
+	/**
+	 * Answer back the array of inner attribute entries as specified in
+	 * the JVM specifications, or an empty array if none.
+	 *
+	 * @return the array of inner attribute entries as specified in
+	 * the JVM specifications, or an empty array if none
+	 */
+	IInnerClassesAttributeEntry[] getInnerClassAttributesEntries();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java
new file mode 100644
index 0000000..0d78263
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a inner class info as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IInnerClassesAttributeEntry {
+
+	/**
+	 * Answer back the access flag of this inner classes attribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the access flag of this inner classes attribute as specified in
+	 * the JVM specifications
+	 */
+	int getAccessFlags();
+
+	/**
+	 * Answer back the inner name index of this inner classes attribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the inner name index of this inner classes attribute as specified in
+	 * the JVM specifications
+	 */
+	int getInnerNameIndex();
+
+	/**
+	 * Answer back the outer class name index of this inner classes attribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the outer class name index of this inner classes attribute as specified in
+	 * the JVM specifications
+	 */
+	int getOuterClassNameIndex();
+
+	/**
+	 * Answer back the inner class name index of this inner classes attribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the inner class name index of this inner classes attribute as specified in
+	 * the JVM specifications
+	 */
+	int getInnerClassNameIndex();
+
+	/**
+	 * Answer back the inner name of this inner classes attribute as specified in
+	 * the JVM specifications, null if inner name index is equals to zero.
+	 *
+	 * @return the inner name of this inner classes attribute as specified in
+	 * the JVM specifications, null if inner name index is equals to zero
+	 */
+	char[] getInnerName();
+
+	/**
+	 * Answer back the outer class name of this inner classes attribute as specified in
+	 * the JVM specifications, null if outer class name index is equals to zero.
+	 *
+	 * @return the outer class name of this inner classes attribute as specified in
+	 * the JVM specifications, null if outer class name index is equals to zero
+	 */
+	char[] getOuterClassName();
+
+	/**
+	 * Answer back the inner class name of this inner classes attribute as specified in
+	 * the JVM specifications, null if inner class name index is equals to zero.
+	 *
+	 * @return the inner class name of this inner classes attribute as specified in
+	 * the JVM specifications, null if inner class name index is equals to zero
+	 */
+	char[] getInnerClassName();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java
new file mode 100644
index 0000000..bedff1a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a line number attribute as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface ILineNumberAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the line number table length as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the line number table length as specified in
+	 * the JVM specifications
+	 */
+	int getLineNumberTableLength();
+
+	/**
+	 * Answer back the array of pairs (start pc, line number) as specified in the
+	 * JVM specifications. Answer an empty array if none.
+	 *
+	 * @return the array of pairs (start pc, line number) as specified in the
+	 * JVM specifications. Answer an empty array if none
+	 */
+	int[][] getLineNumberTable();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java
new file mode 100644
index 0000000..6233c6d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a local variable attribute as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface ILocalVariableAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the local variable table length of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the local variable table length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLocalVariableTableLength();
+
+	/**
+	 * Answer back the local variable table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none.
+	 *
+	 * @return the local variable table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none
+	 */
+	ILocalVariableTableEntry[] getLocalVariableTable();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableReferenceInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableReferenceInfo.java
new file mode 100644
index 0000000..f3de2c5
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableReferenceInfo.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a local variable reference info table entry as specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+public interface ILocalVariableReferenceInfo {
+
+	/**
+	 * Answer back the start pc of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the start pc of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getStartPC();
+
+	/**
+	 * Answer back the length of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLength();
+
+	/**
+	 * Answer back the resolved position of the local variable as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the resolved position of the local variable as specified in
+	 * the JVM specifications
+	 */
+	int getIndex();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java
new file mode 100644
index 0000000..0a0ccaa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a local variable table entry as specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface ILocalVariableTableEntry {
+
+	/**
+	 * Answer back the start pc of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the start pc of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getStartPC();
+
+	/**
+	 * Answer back the length of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLength();
+
+	/**
+	 * Answer back the name index in the constant pool of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the name index in the constant pool of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getNameIndex();
+
+	/**
+	 * Answer back the descriptor index in the constant pool of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the descriptor index in the constant pool of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getDescriptorIndex();
+
+	/**
+	 * Answer back the index of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the index of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getIndex();
+
+	/**
+	 * Answer back the name of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the name of this entry as specified in
+	 * the JVM specifications
+	 */
+	char[] getName();
+
+	/**
+	 * Answer back the descriptor of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the descriptor of this entry as specified in
+	 * the JVM specifications
+	 */
+	char[] getDescriptor();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java
new file mode 100644
index 0000000..008a72f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a local variable type attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface ILocalVariableTypeTableAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the local variable type table length of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the local variable type table length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLocalVariableTypeTableLength();
+
+	/**
+	 * Answer back the local variable type table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none.
+	 *
+	 * @return the local variable type table of this entry as specified in
+	 * the JVM specifications. Answer an empty array if none
+	 */
+	ILocalVariableTypeTableEntry[] getLocalVariableTypeTable();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java
new file mode 100644
index 0000000..2456c47
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a local variable type table entry as specified in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface ILocalVariableTypeTableEntry {
+
+	/**
+	 * Answer back the start pc of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the start pc of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getStartPC();
+
+	/**
+	 * Answer back the length of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the length of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getLength();
+
+	/**
+	 * Answer back the name index in the constant pool of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the name index in the constant pool of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getNameIndex();
+
+	/**
+	 * Answer back the signature index in the constant pool of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the signature index in the constant pool of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getSignatureIndex();
+
+	/**
+	 * Answer back the index of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the index of this entry as specified in
+	 * the JVM specifications
+	 */
+	int getIndex();
+
+	/**
+	 * Answer back the name of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the name of this entry as specified in
+	 * the JVM specifications
+	 */
+	char[] getName();
+
+	/**
+	 * Answer back the signature of this entry as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the signature of this entry as specified in
+	 * the JVM specifications
+	 */
+	char[] getSignature();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java
new file mode 100644
index 0000000..e501407
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a method info as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface IMethodInfo {
+
+	/**
+	 * Answer back the method descriptor of this method info as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the method descriptor of this method info as specified
+	 * in the JVM specifications
+	 */
+	char[] getDescriptor();
+
+	/**
+	 * Answer back the descriptor index of this method info.
+	 *
+	 * @return the descriptor index of this method info
+	 */
+	int getDescriptorIndex();
+
+	/**
+	 * Answer back the access flags of this method info as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the access flags of this method info as specified
+	 * in the JVM specifications
+	 */
+	int getAccessFlags();
+
+	/**
+	 * Answer back the name of this method info as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the name of this method info as specified
+	 * in the JVM specifications
+	 */
+	char[] getName();
+
+	/**
+	 * Answer back the name index of this method info.
+	 *
+	 * @return the name index of this method info
+	 */
+	int getNameIndex();
+
+	/**
+	 * Answer true if this method info represents a &lt;clinit&gt; method,
+	 * false otherwise.
+	 *
+	 * @return true if this method info represents a &lt;clinit&gt; method,
+	 * false otherwise
+	 */
+	boolean isClinit();
+
+	/**
+	 * Answer true if this method info represents a constructor,
+	 * false otherwise.
+	 *
+	 * @return true if this method info represents a constructor,
+	 * false otherwise
+	 */
+	boolean isConstructor();
+
+	/**
+	 * Return true if the method info is synthetic according to the JVM specification, false otherwise.
+	 * <p>Note that prior to JDK 1.5, synthetic fields were always marked using
+	 * an attribute; with 1.5, synthetic fields can also be marked using
+	 * the {@link IModifierConstants#ACC_SYNTHETIC} flag.
+	 * </p>
+	 *
+	 * @return true if the method info is synthetic according to the JVM specification, false otherwise
+	 */
+	boolean isSynthetic();
+
+	/**
+	 * Answer true if this method info has a deprecated attribute,
+	 * false otherwise.
+	 *
+	 * @return true if this method info has a deprecated attribute,
+	 * false otherwise
+	 */
+	boolean isDeprecated();
+
+	/**
+	 * Answer the code attribute of this method info, null if none or if the decoding
+	 * flag doesn't include METHOD_BODIES.
+	 *
+	 * @return the code attribute of this method info, null if none or if the decoding
+	 * flag doesn't include METHOD_BODIES
+	 */
+	ICodeAttribute getCodeAttribute();
+
+	/**
+	 * Answer the exception attribute of this method info, null is none.
+	 *
+	 * 	@return the exception attribute of this method info, null is none
+	 */
+	IExceptionAttribute getExceptionAttribute();
+
+	/**
+	 * Answer back the attribute number of the method info. It includes the CodeAttribute
+	 * if any even if the decoding flags doesn't include METHOD_BODIES.
+	 *
+	 * @return the attribute number of the method info. It includes the CodeAttribute
+	 * if any even if the decoding flags doesn't include METHOD_BODIES
+	 */
+	int getAttributeCount();
+
+	/**
+	 * Answer back the collection of all attributes of the method info. It
+	 * includes SyntheticAttribute, CodeAttributes, etc. It doesn't include the
+	 * CodeAttribute if the decoding flags doesn't include METHOD_BODIES.
+	 * Returns an empty collection if none.
+	 *
+	 * @return the collection of all attributes of the method info. It
+	 * includes SyntheticAttribute, CodeAttributes, etc. It doesn't include the
+	 * CodeAttribute if the decoding flags doesn't include METHOD_BODIES.
+	 * Returns an empty collection if none
+	 */
+	IClassFileAttribute[] getAttributes();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java
new file mode 100644
index 0000000..dd64c0b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Definition of the modifier constants as specified in the JVM specifications.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IModifierConstants {
+
+	int ACC_PUBLIC       = 0x0001;
+	int ACC_PRIVATE      = 0x0002;
+	int ACC_PROTECTED    = 0x0004;
+	int ACC_STATIC       = 0x0008;
+	int ACC_FINAL        = 0x0010;
+	int ACC_SUPER        = 0x0020;
+	int ACC_SYNCHRONIZED = 0x0020;
+	int ACC_VOLATILE     = 0x0040;
+
+	/**
+	 * Indicates a bridge method (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	int ACC_BRIDGE       = 0x0040;
+	int ACC_TRANSIENT    = 0x0080;
+
+	/**
+	 * Indicates a variable arity method (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	int ACC_VARARGS      = 0x0080;
+	int ACC_NATIVE       = 0x0100;
+	int ACC_INTERFACE    = 0x0200;
+	int ACC_ABSTRACT     = 0x0400;
+	int ACC_STRICT       = 0x0800;
+	/**
+	 * Indicates a synthetic member.
+	 * @since 3.0
+	 */
+	int ACC_SYNTHETIC    = 0x1000;
+
+	/**
+	 * Indicates an annotation (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	int ACC_ANNOTATION   = 0x2000;
+
+	/**
+	 * Indicates an enum (added in J2SE 1.5).
+	 * @since 3.0
+	 */
+	int ACC_ENUM         = 0x4000;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java
new file mode 100644
index 0000000..06134b1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of each opcode mnemonic according to the JVM specifications.
+ *
+ * @since 2.0
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IOpcodeMnemonics {
+
+	int NOP = 0x00;
+	int ACONST_NULL = 0x01;
+	int ICONST_M1 = 0x02;
+	int ICONST_0 = 0x03;
+	int ICONST_1 = 0x04;
+	int ICONST_2 = 0x05;
+	int ICONST_3 = 0x06;
+	int ICONST_4 = 0x07;
+	int ICONST_5 = 0x08;
+	int LCONST_0 = 0x09;
+	int LCONST_1 = 0x0A;
+	int FCONST_0 = 0x0B;
+	int FCONST_1 = 0x0C;
+	int FCONST_2 = 0x0D;
+	int DCONST_0 = 0x0E;
+	int DCONST_1 = 0x0F;
+	int BIPUSH = 0x10;
+	int SIPUSH = 0x11;
+	int LDC = 0x12;
+	int LDC_W = 0x13;
+	int LDC2_W= 0x14;
+	int ILOAD = 0x15;
+	int LLOAD = 0x16;
+	int FLOAD = 0x17;
+	int DLOAD = 0x18;
+	int ALOAD = 0x19;
+	int ILOAD_0 = 0x1A;
+	int ILOAD_1 = 0x1B;
+	int ILOAD_2 = 0x1C;
+	int ILOAD_3 = 0x1D;
+	int LLOAD_0 = 0x1E;
+	int LLOAD_1 = 0x1F;
+	int LLOAD_2 = 0x20;
+	int LLOAD_3 = 0x21;
+	int FLOAD_0 = 0x22;
+	int FLOAD_1 = 0x23;
+	int FLOAD_2 = 0x24;
+	int FLOAD_3 = 0x25;
+	int DLOAD_0 = 0x26;
+	int DLOAD_1 = 0x27;
+	int DLOAD_2 = 0x28;
+	int DLOAD_3 = 0x29;
+	int ALOAD_0 = 0x2A;
+	int ALOAD_1 = 0x2B;
+	int ALOAD_2 = 0x2C;
+	int ALOAD_3 = 0x2D;
+	int IALOAD = 0x2E;
+	int LALOAD = 0x2F;
+	int FALOAD = 0x30;
+	int DALOAD = 0x31;
+	int AALOAD = 0x32;
+	int BALOAD = 0x33;
+	int CALOAD = 0x34;
+	int SALOAD = 0x35;
+	int ISTORE = 0x36;
+	int LSTORE = 0x37;
+	int FSTORE = 0x38;
+	int DSTORE = 0x39;
+	int ASTORE = 0x3A;
+	int ISTORE_0 = 0x3B;
+	int ISTORE_1 = 0x3C;
+	int ISTORE_2 = 0x3D;
+	int ISTORE_3 = 0x3E;
+	int LSTORE_0 = 0x3F;
+	int LSTORE_1 = 0x40;
+	int LSTORE_2 = 0x41;
+	int LSTORE_3 = 0x42;
+	int FSTORE_0 = 0x43;
+	int FSTORE_1 = 0x44;
+	int FSTORE_2 = 0x45;
+	int FSTORE_3 = 0x46;
+	int DSTORE_0 = 0x47;
+	int DSTORE_1 = 0x48;
+	int DSTORE_2 = 0x49;
+	int DSTORE_3 = 0x4A;
+	int ASTORE_0 = 0x4B;
+	int ASTORE_1 = 0x4C;
+	int ASTORE_2 = 0x4D;
+	int ASTORE_3 = 0x4E;
+	int IASTORE = 0x4F;
+	int LASTORE = 0x50;
+	int FASTORE = 0x51;
+	int DASTORE = 0x52;
+	int AASTORE = 0x53;
+	int BASTORE = 0x54;
+	int CASTORE = 0x55;
+	int SASTORE = 0x56;
+	int POP = 0x57;
+	int POP2 = 0x58;
+	int DUP = 0x59;
+	int DUP_X1 = 0x5A;
+	int DUP_X2 = 0x5B;
+	int DUP2 = 0x5C;
+	int DUP2_X1 = 0x5D;
+	int DUP2_X2 = 0x5E;
+	int SWAP = 0x5F;
+	int IADD = 0x60;
+	int LADD = 0x61;
+	int FADD = 0x62;
+	int DADD = 0x63;
+	int ISUB = 0x64;
+	int LSUB = 0x65;
+	int FSUB = 0x66;
+	int DSUB = 0x67;
+	int IMUL = 0x68;
+	int LMUL = 0x69;
+	int FMUL = 0x6A;
+	int DMUL = 0x6B;
+	int IDIV = 0x6C;
+	int LDIV = 0x6D;
+	int FDIV = 0x6E;
+	int DDIV = 0x6F;
+	int IREM = 0x70;
+	int LREM = 0x71;
+	int FREM = 0x72;
+	int DREM = 0x73;
+	int INEG = 0x74;
+	int LNEG = 0x75;
+	int FNEG = 0x76;
+	int DNEG = 0x77;
+	int ISHL = 0x78;
+	int LSHL = 0x79;
+	int ISHR = 0x7A;
+	int LSHR = 0x7B;
+	int IUSHR = 0x7C;
+	int LUSHR = 0x7D;
+	int IAND = 0x7E;
+	int LAND = 0x7F;
+	int IOR = 0x80;
+	int LOR = 0x81;
+	int IXOR = 0x82;
+	int LXOR = 0x83;
+	int IINC = 0x84;
+	int I2L = 0x85;
+	int I2F = 0x86;
+	int I2D = 0x87;
+	int L2I = 0x88;
+	int L2F = 0x89;
+	int L2D = 0x8A;
+	int F2I = 0x8B;
+	int F2L = 0x8C;
+	int F2D = 0x8D;
+	int D2I = 0x8E;
+	int D2L = 0x8F;
+	int D2F = 0x90;
+	int I2B = 0x91;
+	int I2C = 0x92;
+	int I2S = 0x93;
+	int LCMP = 0x94;
+	int FCMPL = 0x95;
+	int FCMPG = 0x96;
+	int DCMPL = 0x97;
+	int DCMPG = 0x98;
+	int IFEQ = 0x99;
+	int IFNE = 0x9A;
+	int IFLT = 0x9B;
+	int IFGE = 0x9C;
+	int IFGT = 0x9D;
+	int IFLE = 0x9E;
+	int IF_ICMPEQ = 0x9F;
+	int IF_ICMPNE = 0xA0;
+	int IF_ICMPLT = 0xA1;
+	int IF_ICMPGE = 0xA2;
+	int IF_ICMPGT = 0xA3;
+	int IF_ICMPLE = 0xA4;
+	int IF_ACMPEQ = 0xA5;
+	int IF_ACMPNE = 0xA6;
+	int GOTO = 0xA7;
+	int JSR = 0xA8;
+	int RET = 0xA9;
+	int TABLESWITCH = 0xAA;
+	int LOOKUPSWITCH = 0xAB;
+	int IRETURN = 0xAC;
+	int LRETURN = 0xAD;
+	int FRETURN = 0xAE;
+	int DRETURN = 0xAF;
+	int ARETURN = 0xB0;
+	int RETURN = 0xB1;
+	int GETSTATIC = 0xB2;
+	int PUTSTATIC = 0xB3;
+	int GETFIELD = 0xB4;
+	int PUTFIELD = 0xB5;
+	int INVOKEVIRTUAL = 0xB6;
+	int INVOKESPECIAL = 0xB7;
+	int INVOKESTATIC = 0xB8;
+	int INVOKEINTERFACE = 0xB9;
+	/**
+	 * @since 3.6
+	 */
+	int INVOKEDYNAMIC = 0xBA;
+	int NEW = 0xBB;
+	int NEWARRAY = 0xBC;
+	int ANEWARRAY = 0xBD;
+	int ARRAYLENGTH = 0xBE;
+	int ATHROW = 0xBF;
+	int CHECKCAST = 0xC0;
+	int INSTANCEOF = 0xC1;
+	int MONITORENTER = 0xC2;
+	int MONITOREXIT = 0xC3;
+	int WIDE = 0xC4;
+	int MULTIANEWARRAY = 0xC5;
+	int IFNULL = 0xC6;
+	int IFNONNULL = 0xC7;
+	int GOTO_W = 0xC8;
+	int JSR_W = 0xC9;
+
+	int BREAKPOINT = 0xCA;
+	int IMPDEP1 = 0xFE;
+	int IMPDEP2 = 0xFF;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java
new file mode 100644
index 0000000..bbe9f77
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a parameter annotation as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IParameterAnnotation {
+
+	/**
+	 * Answer back the number of annotations as described in the JVM specifications.
+	 *
+	 * @return the number of annotations
+	 */
+	int getAnnotationsNumber();
+
+	/**
+	 * Answer back the annotations as described in the JVM specifications.
+	 * Answers an empty collection if none.
+	 *
+	 * @return the annotations
+	 */
+	IAnnotation[] getAnnotations();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java
new file mode 100644
index 0000000..7c26e9d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime invisible annotations attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IRuntimeInvisibleAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of annotations as described in the JVM specifications.
+	 *
+	 * @return the number of annotations
+	 */
+	int getAnnotationsNumber();
+
+	/**
+	 * Answer back the annotations. Answers an empty collection if none.
+	 *
+	 * @return the annotations
+	 */
+	IAnnotation[] getAnnotations();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java
new file mode 100644
index 0000000..44d7d34
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime invisible parameter annotations attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IRuntimeInvisibleParameterAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of parameters as described in the JVM specifications.
+	 *
+	 * @return the number of parameters
+	 */
+	int getParametersNumber();
+
+	/**
+	 * Answer back the parameter annotations. Answers an empty collection if none.
+	 *
+	 * @return the parameter annotations. Answers an empty collection if none.
+	 */
+	IParameterAnnotation[] getParameterAnnotations();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleTypeAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleTypeAnnotationsAttribute.java
new file mode 100644
index 0000000..f94d105
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleTypeAnnotationsAttribute.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime invisible type annotations attribute as described in the JVM specifications
+ * (added in JavaSE-1.8).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+public interface IRuntimeInvisibleTypeAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of extended annotations as described in the JVM specifications.
+	 *
+	 * @return the number of extended annotations
+	 */
+	int getExtendedAnnotationsNumber();
+
+	/**
+	 * Answer back the extended annotations. Answers an empty collection if none.
+	 *
+	 * @return the extended annotations
+	 */
+	IExtendedAnnotation[] getExtendedAnnotations();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java
new file mode 100644
index 0000000..ef835aa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime visible annotations attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IRuntimeVisibleAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of annotations as described in the JVM specifications.
+	 *
+	 * @return the number of annotations
+	 */
+	int getAnnotationsNumber();
+
+	/**
+	 * Answer back the annotations. Answers an empty collection if none.
+	 *
+	 * @return the annotations. Answers an empty collection if none.
+	 */
+	IAnnotation[] getAnnotations();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java
new file mode 100644
index 0000000..4a64f8b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime visible parameter annotations attribute as described in the JVM specification
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IRuntimeVisibleParameterAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of parameters as described in the JVM specifications.
+	 *
+	 * @return the number of parameters
+	 */
+	int getParametersNumber();
+
+	/**
+	 * Answer back the parameter annotations. Answers an empty collection if none.
+	 *
+	 * @return the parameter annotations. Answers an empty collection if none.
+	 */
+	IParameterAnnotation[] getParameterAnnotations();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleTypeAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleTypeAnnotationsAttribute.java
new file mode 100644
index 0000000..3564599
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleTypeAnnotationsAttribute.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a runtime visible type annotations attribute as described in the JVM specifications
+ * (added in JavaSE-1.8).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.9 BETA_JAVA8
+ */
+public interface IRuntimeVisibleTypeAnnotationsAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of annotations as described in the JVM specifications.
+	 *
+	 * @return the number of annotations
+	 */
+	int getExtendedAnnotationsNumber();
+
+	/**
+	 * Answer back the extended annotations. Answers an empty collection if none.
+	 *
+	 * @return the extended annotations. Answers an empty collection if none.
+	 */
+	IExtendedAnnotation[] getExtendedAnnotations();
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java
new file mode 100644
index 0000000..fbd2551
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a signature attribute as described in the JVM specifications
+ * (added in J2SE 1.5).
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface ISignatureAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the signature index as described in the JVM specifications.
+	 *
+	 * @return the signature index as described in the JVM specifications
+	 */
+	int getSignatureIndex();
+
+	/**
+	 * Answer back the signature as described in the JVM specifications.
+	 *
+	 * @return the signature as described in the JVM specifications
+	 */
+	char[] getSignature();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java
new file mode 100644
index 0000000..cb551fa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a source attribute as described in the JVM
+ * specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 2.0
+ */
+public interface ISourceAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the source file index of this attribute.
+	 *
+	 * @return the source file index of this attribute
+	 */
+	int getSourceFileIndex();
+
+	/**
+	 * Answer back the source file name of this attribute.
+	 *
+	 * @return the source file name of this attribute
+	 */
+	char[] getSourceFileName();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapAttribute.java
new file mode 100644
index 0000000..16b7037
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapAttribute.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * This class represents a stack map attribute.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.2
+ */
+public interface IStackMapAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of stack map frames of this atribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the number of stack map frames of this atribute as specified in
+	 * the JVM specifications
+	 */
+	int getNumberOfEntries();
+
+	/**
+	 * Answer back the stack map frames for this attribute as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the stack map frames for this attribute as specified
+	 * in the JVM specifications
+	 */
+	IStackMapFrame[] getStackMapFrame();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapFrame.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapFrame.java
new file mode 100644
index 0000000..1dd534c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapFrame.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a stack map frame as specified in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.2
+ */
+public interface IStackMapFrame {
+
+	/**
+	 * Answer back the frame type for this entry.
+	 * <table>
+	 * <tr>
+	 * <th align="left">Type</th>
+	 * <th align="left">Range</th>
+	 * </tr>
+	 * <tr>
+	 * <td>SAME</td>
+	 * <td>0-63</td>
+	 * </tr>
+	 * <tr>
+	 * <td>SAME_LOCALS_1_STACK_ITEM</td>
+	 * <td>64-127</td>
+	 * </tr>
+	 * <tr>
+	 * <td>SAME_LOCALS_1_STACK_ITEM_EXTENDED</td>
+	 * <td>247</td>
+	 * </tr>
+	 * <tr>
+	 * <td>CHOP</td>
+	 * <td>248-250</td>
+	 * </tr>
+	 * <tr>
+	 * <td>SAME_FRAME_EXTENDED</td>
+	 * <td>251</td>
+	 * </tr>
+	 * <tr>
+	 * <td>APPEND</td>
+	 * <td>252-254</td>
+	 * </tr>
+	 * <tr>
+	 * <td>FULL_FRAME</td>
+	 * <td>255</td>
+	 * </tr>
+	 * </table>
+	 *
+	 * @return the frame type for this entry
+	 */
+	int getFrameType();
+
+	/**
+	 * Answer back the offset delta.
+	 * <p>This is not defined only for the frame types SAME and SAME_LOCALS_1_STACK_ITEM.</p>
+	 *
+	 * @return the offset delta
+	 */
+	int getOffsetDelta();
+
+	/**
+	 * Answer back the number of locals.
+	 * <p>This is defined only for the frame type FULL_FRAME.</p>
+	 *
+	 * @return the number of locals
+	 */
+	int getNumberOfLocals();
+
+	/**
+	 * Answer back verification infos for the defined locals.
+	 * <p>This is defined only for frame types APPEND and FULL_FRAME.
+	 *
+	 * @return verification infos for the defined locals
+	 */
+	IVerificationTypeInfo[] getLocals();
+
+	/**
+	 * Answer back the number of stack items
+	 * <p>This is defined only for the frame types SAME_LOCALS_1_STACK_ITEM, SAME_LOCALS_1_STACK_ITEM_EXTENDED and FULL_FRAME.
+	 * For SAME_LOCALS_1_STACK_ITEM and SAME_LOCALS_1_STACK_ITEM_EXTENDED, the answer is implicitely 1.</p>
+	 *
+	 * @return the number of stack items
+	 */
+	int getNumberOfStackItems();
+
+	/**
+	 * Answer back the verification infos for the stack items.
+	 *
+	 * @return the verification infos for the stack items
+	 */
+	IVerificationTypeInfo[] getStackItems();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapTableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapTableAttribute.java
new file mode 100644
index 0000000..4847b1e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IStackMapTableAttribute.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * This class represents a stack map table attribute.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.2
+ */
+public interface IStackMapTableAttribute extends IClassFileAttribute {
+
+	/**
+	 * Answer back the number of stack map frames of this atribute as specified in
+	 * the JVM specifications.
+	 *
+	 * @return the number of stack map frames of this atribute as specified in
+	 * the JVM specifications
+	 */
+	int getNumberOfEntries();
+
+	/**
+	 * Answer back the stack map frames for this attribute as specified
+	 * in the JVM specifications.
+	 *
+	 * @return the stack map frames for this attribute as specified
+	 * in the JVM specifications
+	 */
+	IStackMapFrame[] getStackMapFrame();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java
new file mode 100644
index 0000000..083a79f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of a verification type info as described in the JVM specifications.
+ *
+ * This interface may be implemented by clients.
+ *
+ * @since 3.0
+ */
+public interface IVerificationTypeInfo {
+	/**
+	 * The tag value representing top variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_TOP = 0;
+	/**
+	 * The tag value representing integer variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_INTEGER = 1;
+	/**
+	 * The tag value representing float variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_FLOAT = 2;
+	/**
+	 * The tag value representing double variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_DOUBLE = 3;
+	/**
+	 * The tag value representing long variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_LONG = 4;
+	/**
+	 * The tag value representing null variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_NULL = 5;
+	/**
+	 * The tag value representing uninitialized this variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_UNINITIALIZED_THIS = 6;
+	/**
+	 * The tag value representing object variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_OBJECT = 7;
+	/**
+	 * The tag value representing uninitialized variable info
+	 * @since 3.2
+	 */
+	public static final int ITEM_UNINITIALIZED = 8;
+
+	/**
+	 * Answer back the tag of this verification type info as described in the JVM specifications.
+	 * <ul>
+	 * <li>0 for the top type</li>
+	 * <li>1 for the int type</li>
+	 * <li>2 for the float type</li>
+	 * <li>3 for the double type</li>
+	 * <li>4 for the long type</li>
+	 * <li>5 for the null type</li>
+	 * <li>6 for the uninitialized this type</li>
+	 * <li>7 for the object type</li>
+	 * <li>8 for the uninitialized offset type</li>
+	 * </ul>
+	 *
+	 * @return the tag of this verification type info as described in the JVM specifications
+	 * @since 3.0
+	 */
+	int getTag();
+
+	/**
+	 * Answer back the offset of this verification type info as described in the JVM specifications.
+	 * This makes sense only if the tag is 8.
+	 *
+	 * @return the offset of this verification type info as described in the JVM specifications
+	 * @since 3.0
+	 */
+	int getOffset();
+
+	/**
+	 * Answer back the constant pool index of this verification type info as described in the JVM specifications.
+	 * This makes sense only if the tag is 7.
+	 *
+	 * @return the constant pool index of this verification type info as described in the JVM specifications
+	 * @since 3.0
+	 */
+	int getConstantPoolIndex();
+
+	/**
+	 * Answer back the name of the class type referenced by the index in the constant pool
+	 * as described in the JVM specifications.
+	 * This makes sense only if the tag is 7.
+	 *
+	 * @return the name of the class type referenced by the index in the constant pool
+	 * as described in the JVM specifications
+	 * @since 3.0
+	 */
+	char[] getClassTypeName();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java
new file mode 100644
index 0000000..5acd024
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.util;
+
+/**
+ * Description of each opcode mnemonic according to the JVM specifications.
+ *
+ * @since 2.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class OpcodeStringValues implements IOpcodeMnemonics {
+
+	public static final String[] BYTECODE_NAMES = new String[256];
+	static {
+		BYTECODE_NAMES[NOP] = "nop"; //$NON-NLS-1$
+		BYTECODE_NAMES[ACONST_NULL] = "aconst_null"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_M1] = "iconst_m1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_0] = "iconst_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_1] = "iconst_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_2] = "iconst_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_3] = "iconst_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_4] = "iconst_4"; //$NON-NLS-1$
+		BYTECODE_NAMES[ICONST_5] = "iconst_5"; //$NON-NLS-1$
+		BYTECODE_NAMES[LCONST_0] = "lconst_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[LCONST_1] = "lconst_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[FCONST_0] = "fconst_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[FCONST_1] = "fconst_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[FCONST_2] = "fconst_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DCONST_0] = "dconst_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[DCONST_1] = "dconst_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[BIPUSH] = "bipush"; //$NON-NLS-1$
+		BYTECODE_NAMES[SIPUSH] = "sipush"; //$NON-NLS-1$
+		BYTECODE_NAMES[LDC] = "ldc"; //$NON-NLS-1$
+		BYTECODE_NAMES[LDC_W] = "ldc_w"; //$NON-NLS-1$
+		BYTECODE_NAMES[LDC2_W] = "ldc2_w"; //$NON-NLS-1$
+		BYTECODE_NAMES[ILOAD] = "iload"; //$NON-NLS-1$
+		BYTECODE_NAMES[LLOAD] = "lload"; //$NON-NLS-1$
+		BYTECODE_NAMES[FLOAD] = "fload"; //$NON-NLS-1$
+		BYTECODE_NAMES[DLOAD] = "dload"; //$NON-NLS-1$
+		BYTECODE_NAMES[ALOAD] = "aload"; //$NON-NLS-1$
+		BYTECODE_NAMES[ILOAD_0] = "iload_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[ILOAD_1] = "iload_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ILOAD_2] = "iload_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[ILOAD_3] = "iload_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[LLOAD_0] = "lload_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[LLOAD_1] = "lload_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[LLOAD_2] = "lload_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[LLOAD_3] = "lload_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[FLOAD_0] = "fload_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[FLOAD_1] = "fload_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[FLOAD_2] = "fload_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[FLOAD_3] = "fload_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[DLOAD_0] = "dload_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[DLOAD_1] = "dload_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[DLOAD_2] = "dload_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DLOAD_3] = "dload_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[ALOAD_0] = "aload_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[ALOAD_1] = "aload_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ALOAD_2] = "aload_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[ALOAD_3] = "aload_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[IALOAD] = "iaload"; //$NON-NLS-1$
+		BYTECODE_NAMES[LALOAD] = "laload"; //$NON-NLS-1$
+		BYTECODE_NAMES[FALOAD] = "faload"; //$NON-NLS-1$
+		BYTECODE_NAMES[DALOAD] = "daload"; //$NON-NLS-1$
+		BYTECODE_NAMES[AALOAD] = "aaload"; //$NON-NLS-1$
+		BYTECODE_NAMES[BALOAD] = "baload"; //$NON-NLS-1$
+		BYTECODE_NAMES[CALOAD] = "caload"; //$NON-NLS-1$
+		BYTECODE_NAMES[SALOAD] = "saload"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISTORE] = "istore"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSTORE] = "lstore"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSTORE] = "fstore"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSTORE] = "dstore"; //$NON-NLS-1$
+		BYTECODE_NAMES[ASTORE] = "astore"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISTORE_0] = "istore_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISTORE_1] = "istore_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISTORE_2] = "istore_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISTORE_3] = "istore_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSTORE_0] = "lstore_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSTORE_1] = "lstore_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSTORE_2] = "lstore_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSTORE_3] = "lstore_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSTORE_0] = "fstore_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSTORE_1] = "fstore_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSTORE_2] = "fstore_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSTORE_3] = "fstore_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSTORE_0] = "dstore_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSTORE_1] = "dstore_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSTORE_2] = "dstore_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSTORE_3] = "dstore_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[ASTORE_0] = "astore_0"; //$NON-NLS-1$
+		BYTECODE_NAMES[ASTORE_1] = "astore_1"; //$NON-NLS-1$
+		BYTECODE_NAMES[ASTORE_2] = "astore_2"; //$NON-NLS-1$
+		BYTECODE_NAMES[ASTORE_3] = "astore_3"; //$NON-NLS-1$
+		BYTECODE_NAMES[IASTORE] = "iastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[LASTORE] = "lastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[FASTORE] = "fastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[DASTORE] = "dastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[AASTORE] = "aastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[BASTORE] = "bastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[CASTORE] = "castore"; //$NON-NLS-1$
+		BYTECODE_NAMES[SASTORE] = "sastore"; //$NON-NLS-1$
+		BYTECODE_NAMES[POP] = "pop"; //$NON-NLS-1$
+		BYTECODE_NAMES[POP2] = "pop2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP] = "dup"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP_X1] = "dup_x1"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP_X2] = "dup_x2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP2] = "dup2"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP2_X1] = "dup2_x1"; //$NON-NLS-1$
+		BYTECODE_NAMES[DUP2_X2] = "dup2_x2"; //$NON-NLS-1$
+		BYTECODE_NAMES[SWAP] = "swap"; //$NON-NLS-1$
+		BYTECODE_NAMES[IADD] = "iadd"; //$NON-NLS-1$
+		BYTECODE_NAMES[LADD] = "ladd"; //$NON-NLS-1$
+		BYTECODE_NAMES[FADD] = "fadd"; //$NON-NLS-1$
+		BYTECODE_NAMES[DADD] = "dadd"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISUB] = "isub"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSUB] = "lsub"; //$NON-NLS-1$
+		BYTECODE_NAMES[FSUB] = "fsub"; //$NON-NLS-1$
+		BYTECODE_NAMES[DSUB] = "dsub"; //$NON-NLS-1$
+		BYTECODE_NAMES[IMUL] = "imul"; //$NON-NLS-1$
+		BYTECODE_NAMES[LMUL] = "lmul"; //$NON-NLS-1$
+		BYTECODE_NAMES[FMUL] = "fmul"; //$NON-NLS-1$
+		BYTECODE_NAMES[DMUL] = "dmul"; //$NON-NLS-1$
+		BYTECODE_NAMES[IDIV] = "idiv"; //$NON-NLS-1$
+		BYTECODE_NAMES[LDIV] = "ldiv"; //$NON-NLS-1$
+		BYTECODE_NAMES[FDIV] = "fdiv"; //$NON-NLS-1$
+		BYTECODE_NAMES[DDIV] = "ddiv"; //$NON-NLS-1$
+		BYTECODE_NAMES[IREM] = "irem"; //$NON-NLS-1$
+		BYTECODE_NAMES[LREM] = "lrem"; //$NON-NLS-1$
+		BYTECODE_NAMES[FREM] = "frem"; //$NON-NLS-1$
+		BYTECODE_NAMES[DREM] = "drem"; //$NON-NLS-1$
+		BYTECODE_NAMES[INEG] = "ineg"; //$NON-NLS-1$
+		BYTECODE_NAMES[LNEG] = "lneg"; //$NON-NLS-1$
+		BYTECODE_NAMES[FNEG] = "fneg"; //$NON-NLS-1$
+		BYTECODE_NAMES[DNEG] = "dneg"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISHL] = "ishl"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSHL] = "lshl"; //$NON-NLS-1$
+		BYTECODE_NAMES[ISHR] = "ishr"; //$NON-NLS-1$
+		BYTECODE_NAMES[LSHR] = "lshr"; //$NON-NLS-1$
+		BYTECODE_NAMES[IUSHR] = "iushr"; //$NON-NLS-1$
+		BYTECODE_NAMES[LUSHR] = "lushr"; //$NON-NLS-1$
+		BYTECODE_NAMES[IAND] = "iand"; //$NON-NLS-1$
+		BYTECODE_NAMES[LAND] = "land"; //$NON-NLS-1$
+		BYTECODE_NAMES[IOR] = "ior"; //$NON-NLS-1$
+		BYTECODE_NAMES[LOR] = "lor"; //$NON-NLS-1$
+		BYTECODE_NAMES[IXOR] = "ixor"; //$NON-NLS-1$
+		BYTECODE_NAMES[LXOR] = "lxor"; //$NON-NLS-1$
+		BYTECODE_NAMES[IINC] = "iinc"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2L] = "i2l"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2F] = "i2f"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2D] = "i2d"; //$NON-NLS-1$
+		BYTECODE_NAMES[L2I] = "l2i"; //$NON-NLS-1$
+		BYTECODE_NAMES[L2F] = "l2f"; //$NON-NLS-1$
+		BYTECODE_NAMES[L2D] = "l2d"; //$NON-NLS-1$
+		BYTECODE_NAMES[F2I] = "f2i"; //$NON-NLS-1$
+		BYTECODE_NAMES[F2L] = "f2l"; //$NON-NLS-1$
+		BYTECODE_NAMES[F2D] = "f2d"; //$NON-NLS-1$
+		BYTECODE_NAMES[D2I] = "d2i"; //$NON-NLS-1$
+		BYTECODE_NAMES[D2L] = "d2l"; //$NON-NLS-1$
+		BYTECODE_NAMES[D2F] = "d2f"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2B] = "i2b"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2C] = "i2c"; //$NON-NLS-1$
+		BYTECODE_NAMES[I2S] = "i2s"; //$NON-NLS-1$
+		BYTECODE_NAMES[LCMP] = "lcmp"; //$NON-NLS-1$
+		BYTECODE_NAMES[FCMPL] = "fcmpl"; //$NON-NLS-1$
+		BYTECODE_NAMES[FCMPG] = "fcmpg"; //$NON-NLS-1$
+		BYTECODE_NAMES[DCMPL] = "dcmpl"; //$NON-NLS-1$
+		BYTECODE_NAMES[DCMPG] = "dcmpg"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFEQ] = "ifeq"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFNE] = "ifne"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFLT] = "iflt"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFGE] = "ifge"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFGT] = "ifgt"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFLE] = "ifle"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPEQ] = "if_icmpeq"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPNE] = "if_icmpne"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPLT] = "if_icmplt"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPGE] = "if_icmpge"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPGT] = "if_icmpgt"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ICMPLE] = "if_icmple"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ACMPEQ] = "if_acmpeq"; //$NON-NLS-1$
+		BYTECODE_NAMES[IF_ACMPNE] = "if_acmpne"; //$NON-NLS-1$
+		BYTECODE_NAMES[GOTO] = "goto"; //$NON-NLS-1$
+		BYTECODE_NAMES[JSR] = "jsr"; //$NON-NLS-1$
+		BYTECODE_NAMES[RET] = "ret"; //$NON-NLS-1$
+		BYTECODE_NAMES[TABLESWITCH] = "tableswitch"; //$NON-NLS-1$
+		BYTECODE_NAMES[LOOKUPSWITCH] = "lookupswitch"; //$NON-NLS-1$
+		BYTECODE_NAMES[IRETURN] = "ireturn"; //$NON-NLS-1$
+		BYTECODE_NAMES[LRETURN] = "lreturn"; //$NON-NLS-1$
+		BYTECODE_NAMES[FRETURN] = "freturn"; //$NON-NLS-1$
+		BYTECODE_NAMES[DRETURN] = "dreturn"; //$NON-NLS-1$
+		BYTECODE_NAMES[ARETURN] = "areturn"; //$NON-NLS-1$
+		BYTECODE_NAMES[RETURN] = "return"; //$NON-NLS-1$
+		BYTECODE_NAMES[GETSTATIC] = "getstatic"; //$NON-NLS-1$
+		BYTECODE_NAMES[PUTSTATIC] = "putstatic"; //$NON-NLS-1$
+		BYTECODE_NAMES[GETFIELD] = "getfield"; //$NON-NLS-1$
+		BYTECODE_NAMES[PUTFIELD] = "putfield"; //$NON-NLS-1$
+		BYTECODE_NAMES[INVOKEVIRTUAL] = "invokevirtual"; //$NON-NLS-1$
+		BYTECODE_NAMES[INVOKESPECIAL] = "invokespecial"; //$NON-NLS-1$
+		BYTECODE_NAMES[INVOKESTATIC] = "invokestatic"; //$NON-NLS-1$
+		BYTECODE_NAMES[INVOKEINTERFACE] = "invokeinterface"; //$NON-NLS-1$
+		BYTECODE_NAMES[INVOKEDYNAMIC] = "invokedynamic"; //$NON-NLS-1$
+		BYTECODE_NAMES[NEW] = "new"; //$NON-NLS-1$
+		BYTECODE_NAMES[NEWARRAY] = "newarray"; //$NON-NLS-1$
+		BYTECODE_NAMES[ANEWARRAY] = "anewarray"; //$NON-NLS-1$
+		BYTECODE_NAMES[ARRAYLENGTH] = "arraylength"; //$NON-NLS-1$
+		BYTECODE_NAMES[ATHROW] = "athrow"; //$NON-NLS-1$
+		BYTECODE_NAMES[CHECKCAST] = "checkcast"; //$NON-NLS-1$
+		BYTECODE_NAMES[INSTANCEOF] = "instanceof"; //$NON-NLS-1$
+		BYTECODE_NAMES[MONITORENTER] = "monitorenter"; //$NON-NLS-1$
+		BYTECODE_NAMES[MONITOREXIT] = "monitorexit"; //$NON-NLS-1$
+		BYTECODE_NAMES[WIDE] = "wide"; //$NON-NLS-1$
+		BYTECODE_NAMES[MULTIANEWARRAY] = "multianewarray"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFNULL] = "ifnull"; //$NON-NLS-1$
+		BYTECODE_NAMES[IFNONNULL] = "ifnonnull"; //$NON-NLS-1$
+		BYTECODE_NAMES[GOTO_W] = "goto_w"; //$NON-NLS-1$
+		BYTECODE_NAMES[JSR_W] = "jsr_w"; //$NON-NLS-1$
+		BYTECODE_NAMES[BREAKPOINT] = "breakpoint"; //$NON-NLS-1$
+		BYTECODE_NAMES[IMPDEP1] = "impdep1"; //$NON-NLS-1$
+		BYTECODE_NAMES[IMPDEP2] = "impdep2"; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/package.html b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/package.html
new file mode 100644
index 0000000..6bdcaab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/package.html
@@ -0,0 +1,14 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides a set of tools and utilities for manipulating .class files and Java model elements.
+<h2>
+Package Specification</h2>
+This package provides a set of tools and utilities for manipulating .class files and Java model elements.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
new file mode 100644
index 0000000..5ccf4f9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
@@ -0,0 +1,1568 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class DocumentElementParser extends Parser {
+	IDocumentElementRequestor requestor;
+	private int lastFieldEndPosition;
+	private int lastFieldBodyEndPosition;
+	private int typeStartPosition;
+	private long selectorSourcePositions;
+	private int typeDims;
+	private int extendsDim;
+	private int declarationSourceStart;
+
+	/* int[] stack for storing javadoc positions */
+	int[][] intArrayStack;
+	int intArrayPtr;
+
+public DocumentElementParser(
+	final IDocumentElementRequestor requestor,
+	IProblemFactory problemFactory,
+	CompilerOptions options) {
+	super(new ProblemReporter(
+		DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+		options,
+		problemFactory),
+	false);
+	this.requestor = requestor;
+	this.intArrayStack = new int[30][];
+	this.options = options;
+	this.javadocParser.checkDocComment = false;
+
+	setMethodsFullRecovery(false);
+	setStatementsRecovery(false);
+}
+/*
+ * Will clear the comment stack when looking
+ * for a potential JavaDoc which might contain @deprecated.
+ *
+ * Additionally, before investigating for @deprecated, retrieve the positions
+ * of the JavaDoc comments so as to notify requestor with them.
+ */
+public void checkComment() {
+
+	/* persisting javadoc positions */
+	pushOnIntArrayStack(getJavaDocPositions());
+	boolean deprecated = false;
+	int lastCommentIndex = -1;
+	int commentPtr = this.scanner.commentPtr;
+
+	//since jdk1.2 look only in the last java doc comment...
+	nextComment : for (lastCommentIndex = this.scanner.commentPtr; lastCommentIndex >= 0; lastCommentIndex--){
+		// skip all non-javadoc comments or those which are after the last modifier
+		int commentSourceStart = this.scanner.commentStarts[lastCommentIndex];
+		if (commentSourceStart < 0 || // line comment
+			this.scanner.commentStops[lastCommentIndex] < 0 || // block comment
+			(this.modifiersSourceStart != -1 && this.modifiersSourceStart < commentSourceStart)) // the comment is after the modifier
+		{
+			continue nextComment;
+		}
+		// check comment
+		deprecated = this.javadocParser.checkDeprecation(lastCommentIndex);
+		break nextComment;
+	}
+	if (deprecated) {
+		checkAndSetModifiers(ClassFileConstants.AccDeprecated);
+	}
+	// modify the modifier source start to point at the first comment
+	if (commentPtr >= 0) {
+		this.declarationSourceStart = this.scanner.commentStarts[0];
+		if (this.declarationSourceStart < 0) this.declarationSourceStart = -this.declarationSourceStart;
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeCatchFormalParameter() {
+	// FormalParameter ::= Type VariableDeclaratorId ==> false
+	// FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
+	/*
+	astStack :
+	identifierStack : type identifier
+	intStack : dim dim
+	 ==>
+	astStack : Argument
+	identifierStack :
+	intStack :
+	*/
+
+	this.identifierLengthPtr--;
+	char[] parameterName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+	this.intPtr--; // dimension from the variabledeclaratorid
+	TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+	this.intPtr -= 3;
+	Argument arg =
+		new Argument(
+			parameterName,
+			namePositions,
+			type,
+			this.intStack[this.intPtr + 1]);// modifiers
+	arg.bits &= ~ASTNode.IsArgument;
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			arg.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	pushOnAstStack(arg);
+	this.intArrayPtr--;
+}
+protected void consumeClassBodyDeclaration() {
+	// ClassBodyDeclaration ::= Diet Block
+	//push an Initializer
+	//optimize the push/pop
+
+	super.consumeClassBodyDeclaration();
+	Initializer initializer = (Initializer) this.astStack[this.astPtr];
+	this.requestor.acceptInitializer(
+		initializer.declarationSourceStart,
+		initializer.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		0,
+		this.modifiersSourceStart,
+		initializer.block.sourceStart,
+		initializer.block.sourceEnd);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeClassDeclaration() {
+	super.consumeClassDeclaration();
+	// we know that we have a TypeDeclaration on the top of the astStack
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		return;
+	}
+	this.requestor.exitClass(this.endStatementPosition, // '}' is the end of the body
+	 ((TypeDeclaration) this.astStack[this.astPtr]).declarationSourceEnd);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeClassHeader() {
+	//ClassHeader ::= $empty
+	super.consumeClassHeader();
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		this.intArrayPtr--;
+		return;
+	}
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	TypeReference[] superInterfaces = typeDecl.superInterfaces;
+	char[][] interfaceNames = null;
+	int[] interfaceNameStarts = null;
+	int[] interfaceNameEnds = null;
+	if (superInterfaces != null) {
+		int superInterfacesLength = superInterfaces.length;
+		interfaceNames = new char[superInterfacesLength][];
+		interfaceNameStarts = new int[superInterfacesLength];
+		interfaceNameEnds = new int[superInterfacesLength];
+		for (int i = 0; i < superInterfacesLength; i++) {
+			TypeReference superInterface = superInterfaces[i];
+			interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.');
+			interfaceNameStarts[i] = superInterface.sourceStart;
+			interfaceNameEnds[i] = superInterface.sourceEnd;
+		}
+	}
+	// flush the comments related to the class header
+	this.scanner.commentPtr = -1;
+	TypeReference superclass = typeDecl.superclass;
+	if (superclass == null) {
+		this.requestor.enterClass(
+			typeDecl.declarationSourceStart,
+			this.intArrayStack[this.intArrayPtr--],
+			typeDecl.modifiers,
+			typeDecl.modifiersSourceStart,
+			this.typeStartPosition,
+			typeDecl.name,
+			typeDecl.sourceStart,
+			typeDecl.sourceEnd,
+			null,
+			-1,
+			-1,
+			interfaceNames,
+			interfaceNameStarts,
+			interfaceNameEnds,
+			this.scanner.currentPosition - 1);
+	} else {
+		this.requestor.enterClass(
+			typeDecl.declarationSourceStart,
+			this.intArrayStack[this.intArrayPtr--],
+			typeDecl.modifiers,
+			typeDecl.modifiersSourceStart,
+			this.typeStartPosition,
+			typeDecl.name,
+			typeDecl.sourceStart,
+			typeDecl.sourceEnd,
+			CharOperation.concatWith(superclass.getTypeName(), '.'),
+			superclass.sourceStart,
+			superclass.sourceEnd,
+			interfaceNames,
+			interfaceNameStarts,
+			interfaceNameEnds,
+			this.scanner.currentPosition - 1);
+
+	}
+}
+protected void consumeClassHeaderName1() {
+	// ClassHeaderName ::= Modifiersopt 'class' 'Identifier'
+	TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			typeDecl.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		typeDecl.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	typeDecl.sourceEnd = (int) pos;
+	typeDecl.sourceStart = (int) (pos >>> 32);
+	typeDecl.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push an int position
+	this.typeStartPosition = typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--;
+	int declSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiers = this.intStack[this.intPtr--];
+	if (typeDecl.declarationSourceStart > declSourceStart) {
+		typeDecl.declarationSourceStart = declSourceStart;
+	}
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			typeDecl.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
+	pushOnAstStack(typeDecl);
+	// javadoc
+	typeDecl.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeCompilationUnit() {
+	// CompilationUnit ::= EnterCompilationUnit PackageDeclarationopt ImportDeclarationsopt
+	this.requestor.exitCompilationUnit(this.scanner.source.length - 1);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeConstructorDeclaration() {
+	// ConstructorDeclaration ::= ConstructorHeader ConstructorBody
+	super.consumeConstructorDeclaration();
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		return;
+	}
+	ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
+	this.requestor.exitConstructor(this.endStatementPosition, cd.declarationSourceEnd);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeConstructorHeader() {
+	// ConstructorHeader ::= ConstructorHeaderName MethodHeaderParameters MethodHeaderThrowsClauseopt
+	super.consumeConstructorHeader();
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		this.intArrayPtr--;
+		return;
+	}
+	ConstructorDeclaration cd = (ConstructorDeclaration) this.astStack[this.astPtr];
+	Argument[] arguments = cd.arguments;
+	char[][] argumentTypes = null;
+	char[][] argumentNames = null;
+	int[] argumentTypeStarts = null;
+	int[] argumentTypeEnds = null;
+	int[] argumentNameStarts = null;
+	int[] argumentNameEnds = null;
+	if (arguments != null) {
+		int argumentLength = arguments.length;
+		argumentTypes = new char[argumentLength][];
+		argumentNames = new char[argumentLength][];
+		argumentNameStarts = new int[argumentLength];
+		argumentNameEnds = new int[argumentLength];
+		argumentTypeStarts = new int[argumentLength];
+		argumentTypeEnds = new int[argumentLength];
+		for (int i = 0; i < argumentLength; i++) {
+			Argument argument = arguments[i];
+			TypeReference argumentType = argument.type;
+			argumentTypes[i] = returnTypeName(argumentType);
+			argumentNames[i] = argument.name;
+			argumentNameStarts[i] = argument.sourceStart;
+			argumentNameEnds[i] = argument.sourceEnd;
+			argumentTypeStarts[i] = argumentType.sourceStart;
+			argumentTypeEnds[i] = argumentType.sourceEnd;
+		}
+	}
+	TypeReference[] thrownExceptions = cd.thrownExceptions;
+	char[][] exceptionTypes = null;
+	int[] exceptionTypeStarts = null;
+	int[] exceptionTypeEnds = null;
+	if (thrownExceptions != null) {
+		int thrownExceptionLength = thrownExceptions.length;
+		exceptionTypes = new char[thrownExceptionLength][];
+		exceptionTypeStarts = new int[thrownExceptionLength];
+		exceptionTypeEnds = new int[thrownExceptionLength];
+		for (int i = 0; i < thrownExceptionLength; i++) {
+			TypeReference exception = thrownExceptions[i];
+			exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
+			exceptionTypeStarts[i] = exception.sourceStart;
+			exceptionTypeEnds[i] = exception.sourceEnd;
+		}
+	}
+	this.requestor
+		.enterConstructor(
+			cd.declarationSourceStart,
+			this.intArrayStack[this.intArrayPtr--],
+			cd.modifiers,
+			cd.modifiersSourceStart,
+			cd.selector,
+			cd.sourceStart,
+			(int) (this.selectorSourcePositions & 0xFFFFFFFFL),
+			// retrieve the source end of the name
+			argumentTypes,
+			argumentTypeStarts,
+			argumentTypeEnds,
+			argumentNames,
+			argumentNameStarts,
+			argumentNameEnds,
+			this.rParenPos,
+			// right parenthesis
+			exceptionTypes,
+			exceptionTypeStarts,
+			exceptionTypeEnds,
+			this.scanner.currentPosition - 1);
+}
+protected void consumeConstructorHeaderName() {
+	// ConstructorHeaderName ::=  Modifiersopt 'Identifier' '('
+	ConstructorDeclaration cd = new ConstructorDeclaration(this.compilationUnit.compilationResult);
+
+	//name -- this is not really revelant but we do .....
+	cd.selector = this.identifierStack[this.identifierPtr];
+	this.selectorSourcePositions = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//modifiers
+	cd.declarationSourceStart = this.intStack[this.intPtr--];
+	cd.modifiersSourceStart = this.intStack[this.intPtr--];
+	cd.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			cd.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	cd.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at the selector starts
+	cd.sourceStart = (int) (this.selectorSourcePositions >>> 32);
+	pushOnAstStack(cd);
+
+	cd.sourceEnd = this.lParenPos;
+	cd.bodyStart = this.lParenPos + 1;
+}
+protected void consumeDefaultModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(-1);
+	pushOnIntStack(
+		this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.scanner.startPosition);
+	resetModifiers();
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumeDiet() {
+	// Diet ::= $empty
+	super.consumeDiet();
+	/* persisting javadoc positions
+	 * Will be consume in consumeClassBodyDeclaration
+	 */
+	pushOnIntArrayStack(getJavaDocPositions());
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeEnterCompilationUnit() {
+	// EnterCompilationUnit ::= $empty
+	this.requestor.enterCompilationUnit();
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeEnterVariable() {
+	// EnterVariable ::= $empty
+	boolean isLocalDeclaration = isLocalDeclaration();
+	if (!isLocalDeclaration && (this.variablesCounter[this.nestedType] != 0)) {
+		this.requestor.exitField(this.lastFieldBodyEndPosition, this.lastFieldEndPosition);
+	}
+	char[] varName = this.identifierStack[this.identifierPtr];
+	long namePosition = this.identifierPositionStack[this.identifierPtr--];
+	int extendedTypeDimension = this.intStack[this.intPtr--];
+	// pop any annotations on extended dimensions now, so they don't pollute the base dimensions.
+	Annotation [][] annotationsOnExtendedDimensions = extendedTypeDimension == 0 ? null : getAnnotationsOnDimensions(extendedTypeDimension);
+
+
+	AbstractVariableDeclaration declaration;
+	if (this.nestedMethod[this.nestedType] != 0) {
+		// create the local variable declarations
+		declaration =
+			new LocalDeclaration(varName, (int) (namePosition >>> 32), (int) namePosition);
+	} else {
+		// create the field declaration
+		declaration =
+			new FieldDeclaration(varName, (int) (namePosition >>> 32), (int) namePosition);
+	}
+	this.identifierLengthPtr--;
+	TypeReference type;
+	int variableIndex = this.variablesCounter[this.nestedType];
+	int typeDim = 0;
+	if (variableIndex == 0) {
+		// first variable of the declaration (FieldDeclaration or LocalDeclaration)
+		if (this.nestedMethod[this.nestedType] != 0) {
+			// local declaration
+			declaration.declarationSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiersSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiers = this.intStack[this.intPtr--];
+			type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
+			pushOnAstStack(type);
+		} else {
+			// field declaration
+			type = getTypeReference(typeDim = this.intStack[this.intPtr--]); // type dimension
+			pushOnAstStack(type);
+			declaration.declarationSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiersSourceStart = this.intStack[this.intPtr--];
+			declaration.modifiers = this.intStack[this.intPtr--];
+		}
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				declaration.annotations = new Annotation[length],
+				0,
+				length);
+		}
+	} else {
+		type = (TypeReference) this.astStack[this.astPtr - variableIndex];
+		typeDim = type.dimensions();
+		AbstractVariableDeclaration previousVariable =
+			(AbstractVariableDeclaration) this.astStack[this.astPtr];
+		declaration.declarationSourceStart = previousVariable.declarationSourceStart;
+		declaration.modifiers = previousVariable.modifiers;
+		declaration.modifiersSourceStart = previousVariable.modifiersSourceStart;
+		final Annotation[] annotations = previousVariable.annotations;
+		if (annotations != null) {
+			final int annotationsLength = annotations.length;
+			System.arraycopy(annotations, 0, declaration.annotations = new Annotation[annotationsLength], 0, annotationsLength);
+		}
+	}
+
+	if (extendedTypeDimension == 0) {
+		declaration.type = type;
+	} else {
+		int dimension = typeDim + extendedTypeDimension;
+		Annotation [][] annotationsOnAllDimensions = null;
+		Annotation[][] annotationsOnDimensions = type.getAnnotationsOnDimensions();
+		if (annotationsOnDimensions != null || annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(typeDim, annotationsOnDimensions, extendedTypeDimension, annotationsOnExtendedDimensions); 
+		}
+		declaration.type = copyDims(type, dimension, annotationsOnAllDimensions);
+	}
+	this.variablesCounter[this.nestedType]++;
+	this.nestedMethod[this.nestedType]++;
+	pushOnAstStack(declaration);
+
+	int[] javadocPositions = this.intArrayStack[this.intArrayPtr];
+	if (!isLocalDeclaration) {
+		this.requestor
+			.enterField(
+				declaration.declarationSourceStart,
+				javadocPositions,
+				declaration.modifiers,
+				declaration.modifiersSourceStart,
+				returnTypeName(declaration.type),
+				type.sourceStart,
+				type.sourceEnd,
+				this.typeDims,
+				varName,
+				(int) (namePosition >>> 32),
+				(int) namePosition,
+				extendedTypeDimension,
+				extendedTypeDimension == 0 ? -1 : this.endPosition);
+	}
+}
+protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
+	TypeReference type;
+
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePosition = this.identifierPositionStack[this.identifierPtr];
+
+	LocalDeclaration localDeclaration = createLocalDeclaration(identifierName, (int) (namePosition >>> 32), (int) namePosition);
+	localDeclaration.declarationSourceEnd = localDeclaration.declarationEnd;
+
+	int extraDims = this.intStack[this.intPtr--];
+	this.identifierPtr--;
+	this.identifierLengthPtr--;
+	// remove fake modifiers/modifiers start
+	int declarationSourceStart1 = 0;
+	int modifiersSourceStart1 = 0;
+	int modifiersValue  = 0;
+	if (hasModifiers) {
+		declarationSourceStart1 = this.intStack[this.intPtr--];
+		modifiersSourceStart1 = this.intStack[this.intPtr--];
+		modifiersValue = this.intStack[this.intPtr--];
+	} else {
+		this.intPtr-=3;
+	}
+
+	type = getTypeReference(this.intStack[this.intPtr--] + extraDims); // type dimension
+
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--])!= 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			localDeclaration.annotations = new Annotation[length],
+			0,
+			length);
+		localDeclaration.bits |= ASTNode.HasTypeAnnotations;
+	}
+	if (hasModifiers) {
+		localDeclaration.declarationSourceStart = declarationSourceStart1;
+		localDeclaration.modifiersSourceStart = modifiersSourceStart1;
+		localDeclaration.modifiers = modifiersValue;
+	} else {
+		localDeclaration.declarationSourceStart = type.sourceStart;
+	}
+	localDeclaration.type = type;
+	localDeclaration.bits |= (type.bits & ASTNode.HasTypeAnnotations);
+	ForeachStatement iteratorForStatement =
+		new ForeachStatement(
+			localDeclaration,
+			this.intStack[this.intPtr--]);
+	pushOnAstStack(iteratorForStatement);
+
+	iteratorForStatement.sourceEnd = localDeclaration.declarationSourceEnd;
+}
+protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) {
+	// MethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	// AnnotationMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	// RecoveryMethodHeaderName ::= Modifiersopt TypeParameters Type 'Identifier' '('
+	MethodDeclaration md = null;
+	if(isAnnotationMethod) {
+		md = new AnnotationMethodDeclaration(this.compilationUnit.compilationResult);
+		this.recordStringLiterals = false;
+	} else {
+		md = new MethodDeclaration(this.compilationUnit.compilationResult);
+	}
+
+	//name
+	md.selector = this.identifierStack[this.identifierPtr];
+	long selectorSource = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	//type
+	md.returnType = getTypeReference(this.intStack[this.intPtr--]);
+	rejectIllegalLeadingTypeAnnotations(md.returnType);
+	md.bits |= (md.returnType.bits & ASTNode.HasTypeAnnotations);
+	// consume type parameters
+	int length = this.genericsLengthStack[this.genericsLengthPtr--];
+	this.genericsPtr -= length;
+	System.arraycopy(this.genericsStack, this.genericsPtr + 1, md.typeParameters = new TypeParameter[length], 0, length);
+
+	//modifiers
+	md.declarationSourceStart = this.intStack[this.intPtr--];
+	md.modifiersSourceStart = this.intStack[this.intPtr--];
+	md.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			md.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	md.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at selector start
+	md.sourceStart = (int) (selectorSource >>> 32);
+	pushOnAstStack(md);
+	md.sourceEnd = this.lParenPos;
+	md.bodyStart = this.lParenPos+1;
+	this.listLength = 0; // initialize this.listLength before reading parameters/throws
+
+	// recovery
+	if (this.currentElement != null){
+		boolean isType;
+		if ((isType = this.currentElement instanceof RecoveredType)
+			//|| md.modifiers != 0
+			|| (Util.getLineNumber(md.returnType.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr)
+					== Util.getLineNumber(md.sourceStart, this.scanner.lineEnds, 0, this.scanner.linePtr))){
+			if(isType) {
+				((RecoveredType) this.currentElement).pendingTypeParameters = null;
+			}
+			this.lastCheckPoint = md.bodyStart;
+			this.currentElement = this.currentElement.add(md, 0);
+			this.lastIgnoredToken = -1;
+		} else {
+			this.lastCheckPoint = md.sourceStart;
+			this.restartRecovery = true;
+		}
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeExitVariableWithInitialization() {
+	// ExitVariableWithInitialization ::= $empty
+	// the scanner is located after the comma or the semi-colon.
+	// we want to include the comma or the semi-colon
+	super.consumeExitVariableWithInitialization();
+	this.nestedMethod[this.nestedType]--;
+	this.lastFieldEndPosition = this.scanner.currentPosition - 1;
+	this.lastFieldBodyEndPosition = 	((AbstractVariableDeclaration) this.astStack[this.astPtr]).initialization.sourceEnd;
+}
+protected void consumeExitVariableWithoutInitialization() {
+	// ExitVariableWithoutInitialization ::= $empty
+	// do nothing by default
+	super.consumeExitVariableWithoutInitialization();
+	this.nestedMethod[this.nestedType]--;
+	this.lastFieldEndPosition = this.scanner.currentPosition - 1;
+	this.lastFieldBodyEndPosition = this.scanner.startPosition - 1;
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeFieldDeclaration() {
+	// See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
+	// FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
+	// the super.consumeFieldDeclaration will reinitialize the variableCounter[nestedType]
+	int variableIndex = this.variablesCounter[this.nestedType];
+	super.consumeFieldDeclaration();
+	this.intArrayPtr--;
+	if (isLocalDeclaration())
+		return;
+	if (variableIndex != 0) {
+		this.requestor.exitField(this.lastFieldBodyEndPosition, this.lastFieldEndPosition);
+	}
+}
+protected void consumeFormalParameter(boolean isVarArgs) {
+	// FormalParameter ::= Type VariableDeclaratorId ==> false
+	// FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
+	/*
+	astStack :
+	identifierStack : type identifier
+	intStack : dim dim 1||0  // 1 => normal parameter, 0 => this parameter
+	 ==>
+	astStack : Argument
+	identifierStack :
+	intStack :
+	*/
+	NameReference qualifyingNameReference = null;
+    boolean isReceiver = this.intStack[this.intPtr--] == 0;
+    if (isReceiver) {
+    	qualifyingNameReference = (NameReference) this.expressionStack[this.expressionPtr--];
+    	this.expressionLengthPtr --;
+    }
+	this.identifierLengthPtr--;
+	char[] parameterName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+	int extendedDimensions = this.intStack[this.intPtr--];
+	Annotation [][] annotationsOnExtendedDimensions = extendedDimensions == 0 ? null : getAnnotationsOnDimensions(extendedDimensions);
+	int endOfEllipsis = 0;
+	int length;
+	Annotation [] varArgsAnnotations = null;
+	if (isVarArgs) {
+		endOfEllipsis = this.intStack[this.intPtr--];
+		if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.typeAnnotationStack,
+				(this.typeAnnotationPtr -= length) + 1,
+				varArgsAnnotations = new Annotation[length],
+				0,
+				length);
+		} 
+	}
+	int firstDimensions = this.intStack[this.intPtr--];
+	TypeReference type = getTypeReference(firstDimensions);
+
+	final int typeDimensions = firstDimensions + extendedDimensions + (isVarArgs ? 1 : 0);
+	if (typeDimensions != firstDimensions) {
+		// jsr308 type annotations management
+		Annotation [][] annotationsOnFirstDimensions = firstDimensions == 0 ? null : type.getAnnotationsOnDimensions();
+		Annotation [][] annotationsOnAllDimensions = annotationsOnFirstDimensions;
+		if (annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions, annotationsOnFirstDimensions, extendedDimensions, annotationsOnExtendedDimensions); 
+		}
+		if (varArgsAnnotations != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(firstDimensions + extendedDimensions, annotationsOnAllDimensions, 
+																				1, new Annotation[][]{varArgsAnnotations});
+		}
+		type = copyDims(type, typeDimensions, annotationsOnAllDimensions);
+		type.sourceEnd = type.isParameterizedTypeReference() ? this.endStatementPosition : this.endPosition;
+	}
+	if (isVarArgs) {
+		if (extendedDimensions == 0) {
+			type.sourceEnd = endOfEllipsis;
+		}
+		type.bits |= ASTNode.IsVarArgs; // set isVarArgs
+	}
+	this.intPtr -= 3;
+	Argument arg;
+	if (isReceiver) {
+		arg = new Receiver(
+				parameterName, 
+				namePositions, 
+				type,
+				qualifyingNameReference,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated);
+	} else {
+		arg = new Argument(
+			parameterName,
+			namePositions,
+			type,
+			this.intStack[this.intPtr + 1]);// modifiers
+	}
+	// consume annotations
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			arg.annotations = new Annotation[length],
+			0,
+			length);
+		RecoveredType currentRecoveryType = this.currentRecoveryType();
+		if (currentRecoveryType != null)
+			currentRecoveryType.annotationsConsumed(arg.annotations);
+	}
+	pushOnAstStack(arg);
+	this.intArrayPtr--;
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeInterfaceDeclaration() {
+	super.consumeInterfaceDeclaration();
+	// we know that we have a TypeDeclaration on the top of the astStack
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		return;
+	}
+	this.requestor.exitInterface(this.endStatementPosition, // the '}' is the end of the body
+	 ((TypeDeclaration) this.astStack[this.astPtr]).declarationSourceEnd);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeInterfaceHeader() {
+	//InterfaceHeader ::= $empty
+	super.consumeInterfaceHeader();
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		this.intArrayPtr--;
+		return;
+	}
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	TypeReference[] superInterfaces = typeDecl.superInterfaces;
+	char[][] interfaceNames = null;
+	int[] interfaceNameStarts = null;
+	int[] interfacenameEnds = null;
+	int superInterfacesLength = 0;
+	if (superInterfaces != null) {
+		superInterfacesLength = superInterfaces.length;
+		interfaceNames = new char[superInterfacesLength][];
+		interfaceNameStarts = new int[superInterfacesLength];
+		interfacenameEnds = new int[superInterfacesLength];
+	}
+	if (superInterfaces != null) {
+		for (int i = 0; i < superInterfacesLength; i++) {
+			TypeReference superInterface = superInterfaces[i];
+			interfaceNames[i] = CharOperation.concatWith(superInterface.getTypeName(), '.');
+			interfaceNameStarts[i] = superInterface.sourceStart;
+			interfacenameEnds[i] = superInterface.sourceEnd;
+		}
+	}
+	// flush the comments related to the interface header
+	this.scanner.commentPtr = -1;
+	this.requestor.enterInterface(
+		typeDecl.declarationSourceStart,
+		this.intArrayStack[this.intArrayPtr--],
+		typeDecl.modifiers,
+		typeDecl.modifiersSourceStart,
+		this.typeStartPosition,
+		typeDecl.name,
+		typeDecl.sourceStart,
+		typeDecl.sourceEnd,
+		interfaceNames,
+		interfaceNameStarts,
+		interfacenameEnds,
+		this.scanner.currentPosition - 1);
+}
+protected void consumeInterfaceHeaderName1() {
+	// InterfaceHeaderName ::= Modifiersopt 'interface' 'Identifier'
+	TypeDeclaration typeDecl = new TypeDeclaration(this.compilationUnit.compilationResult);
+	if (this.nestedMethod[this.nestedType] == 0) {
+		if (this.nestedType != 0) {
+			typeDecl.bits |= ASTNode.IsMemberType;
+		}
+	} else {
+		// Record that the block has a declaration for local types
+		typeDecl.bits |= ASTNode.IsLocalType;
+		markEnclosingMemberWithLocalType();
+		blockReal();
+	}
+
+	//highlight the name of the type
+	long pos = this.identifierPositionStack[this.identifierPtr];
+	typeDecl.sourceEnd = (int) pos;
+	typeDecl.sourceStart = (int) (pos >>> 32);
+	typeDecl.name = this.identifierStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+
+	//compute the declaration source too
+	// 'class' and 'interface' push an int position
+	this.typeStartPosition = typeDecl.declarationSourceStart = this.intStack[this.intPtr--];
+	this.intPtr--;
+	int declSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiersSourceStart = this.intStack[this.intPtr--];
+	typeDecl.modifiers = this.intStack[this.intPtr--] | ClassFileConstants.AccInterface;
+	if (typeDecl.declarationSourceStart > declSourceStart) {
+		typeDecl.declarationSourceStart = declSourceStart;
+	}
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			typeDecl.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	typeDecl.bodyStart = typeDecl.sourceEnd + 1;
+	pushOnAstStack(typeDecl);
+	// javadoc
+	typeDecl.javadoc = this.javadoc;
+	this.javadoc = null;
+}
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeLocalVariableDeclaration() {
+	// See consumeLocalVariableDeclarationDefaultModifier() in case of change: duplicated code
+	// FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';'
+
+	super.consumeLocalVariableDeclaration();
+	this.intArrayPtr--;
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodDeclaration(boolean isNotAbstract) {
+	// MethodDeclaration ::= MethodHeader MethodBody
+	// AbstractMethodDeclaration ::= MethodHeader ';'
+	super.consumeMethodDeclaration(isNotAbstract);
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		return;
+	}
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	this.requestor.exitMethod(this.endStatementPosition, md.declarationSourceEnd);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodHeader() {
+	// MethodHeader ::= MethodHeaderName MethodHeaderParameters MethodHeaderExtendedDims ThrowsClauseopt
+	super.consumeMethodHeader();
+	if (isLocalDeclaration()) {
+		// we ignore the local variable declarations
+		this.intArrayPtr--;
+		return;
+	}
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+
+	TypeReference returnType = md.returnType;
+	char[] returnTypeName = returnTypeName(returnType);
+	Argument[] arguments = md.arguments;
+	char[][] argumentTypes = null;
+	char[][] argumentNames = null;
+	int[] argumentTypeStarts = null;
+	int[] argumentTypeEnds = null;
+	int[] argumentNameStarts = null;
+	int[] argumentNameEnds = null;
+	if (arguments != null) {
+		int argumentLength = arguments.length;
+		argumentTypes = new char[argumentLength][];
+		argumentNames = new char[argumentLength][];
+		argumentNameStarts = new int[argumentLength];
+		argumentNameEnds = new int[argumentLength];
+		argumentTypeStarts = new int[argumentLength];
+		argumentTypeEnds = new int[argumentLength];
+		for (int i = 0; i < argumentLength; i++) {
+			Argument argument = arguments[i];
+			TypeReference argumentType = argument.type;
+			argumentTypes[i] = returnTypeName(argumentType);
+			argumentNames[i] = argument.name;
+			argumentNameStarts[i] = argument.sourceStart;
+			argumentNameEnds[i] = argument.sourceEnd;
+			argumentTypeStarts[i] = argumentType.sourceStart;
+			argumentTypeEnds[i] = argumentType.sourceEnd;
+		}
+	}
+	TypeReference[] thrownExceptions = md.thrownExceptions;
+	char[][] exceptionTypes = null;
+	int[] exceptionTypeStarts = null;
+	int[] exceptionTypeEnds = null;
+	if (thrownExceptions != null) {
+		int thrownExceptionLength = thrownExceptions.length;
+		exceptionTypeStarts = new int[thrownExceptionLength];
+		exceptionTypeEnds = new int[thrownExceptionLength];
+		exceptionTypes = new char[thrownExceptionLength][];
+		for (int i = 0; i < thrownExceptionLength; i++) {
+			TypeReference exception = thrownExceptions[i];
+			exceptionTypes[i] = CharOperation.concatWith(exception.getTypeName(), '.');
+			exceptionTypeStarts[i] = exception.sourceStart;
+			exceptionTypeEnds[i] = exception.sourceEnd;
+		}
+	}
+	this.requestor
+		.enterMethod(
+			md.declarationSourceStart,
+			this.intArrayStack[this.intArrayPtr--],
+			md.modifiers,
+			md.modifiersSourceStart,
+			returnTypeName,
+			returnType.sourceStart,
+			returnType.sourceEnd,
+			this.typeDims,
+			md.selector,
+			md.sourceStart,
+			(int) (this.selectorSourcePositions & 0xFFFFFFFFL),
+			argumentTypes,
+			argumentTypeStarts,
+			argumentTypeEnds,
+			argumentNames,
+			argumentNameStarts,
+			argumentNameEnds,
+			this.rParenPos,
+			this.extendsDim,
+			this.extendsDim == 0 ? -1 : this.endPosition,
+			exceptionTypes,
+			exceptionTypeStarts,
+			exceptionTypeEnds,
+			this.scanner.currentPosition - 1);
+}
+protected void consumeMethodHeaderExtendedDims() {
+	// MethodHeaderExtendedDims ::= Dimsopt
+	// now we update the returnType of the method
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	int extendedDims = this.intStack[this.intPtr--];
+	this.extendsDim = extendedDims;
+	if (extendedDims != 0) {
+		TypeReference returnType = md.returnType;
+		md.sourceEnd = this.endPosition;
+		int dims = returnType.dimensions() + extendedDims;
+		Annotation [][] annotationsOnDimensions = returnType.getAnnotationsOnDimensions();
+		Annotation [][] annotationsOnExtendedDimensions = getAnnotationsOnDimensions(extendedDims);
+		Annotation [][] annotationsOnAllDimensions = null;
+		if (annotationsOnDimensions != null || annotationsOnExtendedDimensions != null) {
+			annotationsOnAllDimensions = getMergedAnnotationsOnDimensions(returnType.dimensions(), annotationsOnDimensions, extendedDims, annotationsOnExtendedDimensions);
+		}	
+		md.returnType = copyDims(returnType, dims, annotationsOnAllDimensions);
+
+		if (this.currentToken == TokenNameLBRACE) {
+			md.bodyStart = this.endPosition + 1;
+		}
+	}
+}
+protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
+	// MethodHeaderName ::= Modifiersopt Type 'Identifier' '('
+	MethodDeclaration md = null;
+	if(isAnnotationMethod) {
+		md = new AnnotationMethodDeclaration(this.compilationUnit.compilationResult);
+	} else {
+		md = new MethodDeclaration(this.compilationUnit.compilationResult);
+	}
+	//name
+	md.selector = this.identifierStack[this.identifierPtr];
+	this.selectorSourcePositions = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	//type
+	md.returnType = getTypeReference(this.typeDims = this.intStack[this.intPtr--]);
+	//modifiers
+	md.declarationSourceStart = this.intStack[this.intPtr--];
+	md.modifiersSourceStart = this.intStack[this.intPtr--];
+	md.modifiers = this.intStack[this.intPtr--];
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			md.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	// javadoc
+	md.javadoc = this.javadoc;
+	this.javadoc = null;
+
+	//highlight starts at selector start
+	md.sourceStart = (int) (this.selectorSourcePositions >>> 32);
+	pushOnAstStack(md);
+	md.bodyStart = this.scanner.currentPosition-1;
+}
+protected void consumeModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	pushOnIntStack(this.modifiersSourceStart);
+	pushOnIntStack(
+		this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.modifiersSourceStart);
+	resetModifiers();
+}
+protected void consumePackageComment() {
+	// get possible comment for syntax since 1.5
+	if(this.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+		checkComment();
+	} else {
+		pushOnIntArrayStack(getJavaDocPositions());
+	}
+	resetModifiers();
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumePackageDeclarationName() {
+	/*
+	 * Javadoc positions are persisted in consumePackageComment
+	 */
+	super.consumePackageDeclarationName();
+	ImportReference importReference = this.compilationUnit.currentPackage;
+
+	this.requestor.acceptPackage(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart);
+}
+/*
+*
+* INTERNAL USE-ONLY
+*/
+protected void consumePackageDeclarationNameWithModifiers() {
+	super.consumePackageDeclarationNameWithModifiers();
+	ImportReference importReference = this.compilationUnit.currentPackage;
+
+	this.requestor.acceptPackage(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart);
+}
+protected void consumePushModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	if (this.modifiersSourceStart < 0) {
+		pushOnIntStack(-1);
+		pushOnIntStack(
+			this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.scanner.startPosition);
+	} else {
+		pushOnIntStack(this.modifiersSourceStart);
+		pushOnIntStack(
+			this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.modifiersSourceStart);
+	}
+	resetModifiers();
+	pushOnExpressionStackLengthStack(0);
+}
+protected void consumePushRealModifiers() {
+	checkComment(); // might update modifiers with AccDeprecated
+	pushOnIntStack(this.modifiers); // modifiers
+	if (this.modifiersSourceStart < 0) {
+		pushOnIntStack(-1);
+		pushOnIntStack(
+			this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.scanner.startPosition);
+	} else {
+		pushOnIntStack(this.modifiersSourceStart);
+		pushOnIntStack(
+			this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.modifiersSourceStart);
+	}
+	resetModifiers();
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' 'static' Name
+
+	/* persisting javadoc positions */
+	pushOnIntArrayStack(getJavaDocPositions());
+
+	super.consumeSingleStaticImportDeclarationName();
+	ImportReference importReference = (ImportReference) this.astStack[this.astPtr];
+	this.requestor.acceptImport(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart,
+		false,
+		ClassFileConstants.AccStatic);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeSingleTypeImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' Name
+
+	/* persisting javadoc positions */
+	pushOnIntArrayStack(getJavaDocPositions());
+
+	super.consumeSingleTypeImportDeclarationName();
+	ImportReference importReference = (ImportReference) this.astStack[this.astPtr];
+	this.requestor.acceptImport(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart,
+		false,
+		ClassFileConstants.AccDefault);
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' 'static' Name '.' '*'
+
+	/* persisting javadoc positions */
+	pushOnIntArrayStack(getJavaDocPositions());
+
+	super.consumeStaticImportOnDemandDeclarationName();
+	ImportReference importReference = (ImportReference) this.astStack[this.astPtr];
+	this.requestor.acceptImport(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart,
+		true,
+		ClassFileConstants.AccStatic);
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeStaticInitializer() {
+	// StaticInitializer ::=  StaticOnly Block
+	//push an Initializer
+	//optimize the push/pop
+	super.consumeStaticInitializer();
+	Initializer initializer = (Initializer) this.astStack[this.astPtr];
+	this.requestor.acceptInitializer(
+		initializer.declarationSourceStart,
+		initializer.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		ClassFileConstants.AccStatic,
+		this.intStack[this.intPtr--],
+		initializer.block.sourceStart,
+		initializer.declarationSourceEnd);
+}
+protected void consumeStaticOnly() {
+	// StaticOnly ::= 'static'
+	checkComment(); // might update declaration source start
+	pushOnIntStack(this.modifiersSourceStart);
+	pushOnIntStack(this.scanner.currentPosition);
+	pushOnIntStack(
+		this.declarationSourceStart >= 0 ? this.declarationSourceStart : this.modifiersSourceStart);
+	jumpOverMethodBody();
+	this.nestedMethod[this.nestedType]++;
+	resetModifiers();
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeTypeImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
+
+	/* persisting javadoc positions */
+	pushOnIntArrayStack(getJavaDocPositions());
+
+	super.consumeTypeImportOnDemandDeclarationName();
+	ImportReference importReference = (ImportReference) this.astStack[this.astPtr];
+	this.requestor.acceptImport(
+		importReference.declarationSourceStart,
+		importReference.declarationSourceEnd,
+		this.intArrayStack[this.intArrayPtr--],
+		CharOperation.concatWith(importReference.getImportName(), '.'),
+		importReference.sourceStart,
+		true,
+		ClassFileConstants.AccDefault);
+}
+/*
+ * Flush javadocs defined prior to a given positions.
+ *
+ * Note: javadocs are stacked in syntactical order
+ *
+ * Either answer given <position>, or the end position of a comment line
+ * immediately following the <position> (same line)
+ *
+ * e.g.
+ * void foo(){
+ * } // end of method foo
+ */
+
+public int flushCommentsDefinedPriorTo(int position) {
+
+	return this.lastFieldEndPosition = super.flushCommentsDefinedPriorTo(position);
+}
+public CompilationUnitDeclaration endParse(int act) {
+	if (this.scanner.recordLineSeparator) {
+		this.requestor.acceptLineSeparatorPositions(this.scanner.getLineEnds());
+	}
+	return super.endParse(act);
+}
+public void initialize(boolean initializeNLS) {
+	//positionning the parser for a new compilation unit
+	//avoiding stack reallocation and all that....
+	super.initialize(initializeNLS);
+	this.intArrayPtr = -1;
+}
+public void initialize() {
+	//positionning the parser for a new compilation unit
+	//avoiding stack reallocation and all that....
+	super.initialize();
+	this.intArrayPtr = -1;
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+private boolean isLocalDeclaration() {
+	int nestedDepth = this.nestedType;
+	while (nestedDepth >= 0) {
+		if (this.nestedMethod[nestedDepth] != 0) {
+			return true;
+		}
+		nestedDepth--;
+	}
+	return false;
+}
+protected void parse() {
+	this.diet = true;
+	super.parse();
+}
+/*
+ * Investigate one entire unit.
+ */
+public void parseCompilationUnit(ICompilationUnit unit) {
+	char[] regionSource = unit.getContents();
+	try {
+		initialize(true);
+		goForCompilationUnit();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+}
+/*
+ * Investigate one constructor declaration.
+ */
+public void parseConstructor(char[] regionSource) {
+	try {
+		initialize();
+		goForClassBodyDeclarations();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+}
+/*
+ * Investigate one field declaration statement (might have multiple declarations in it).
+ */
+public void parseField(char[] regionSource) {
+	try {
+		initialize();
+		goForFieldDeclaration();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+
+}
+/*
+ * Investigate one import statement declaration.
+ */
+public void parseImport(char[] regionSource) {
+	try {
+		initialize();
+		goForImportDeclaration();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+
+}
+/*
+ * Investigate one initializer declaration.
+ * regionSource need to content exactly an initializer declaration.
+ * e.g: static { i = 4; }
+ * { name = "test"; }
+ */
+public void parseInitializer(char[] regionSource) {
+	try {
+		initialize();
+		goForInitializer();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+
+}
+/*
+ * Investigate one method declaration.
+ */
+public void parseMethod(char[] regionSource) {
+	try {
+		initialize();
+		goForGenericMethodDeclaration();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+}
+/*
+ * Investigate one package statement declaration.
+ */
+public void parsePackage(char[] regionSource) {
+	try {
+		initialize();
+		goForPackageDeclaration();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+
+}
+/*
+ * Investigate one type declaration, its fields, methods and member types.
+ */
+public void parseType(char[] regionSource) {
+	try {
+		initialize();
+		goForTypeDeclaration();
+		this.referenceContext =
+			this.compilationUnit =
+				new CompilationUnitDeclaration(
+					problemReporter(),
+					new CompilationResult(regionSource, 0, 0, this.options.maxProblemsPerUnit),
+					regionSource.length);
+		this.scanner.resetTo(0, regionSource.length);
+		this.scanner.setSource(regionSource);
+		parse();
+	} catch (AbortCompilation ex) {
+		// ignore this exception
+	}
+
+}
+/**
+ * Returns this parser's problem reporter initialized with its reference context.
+ * Also it is assumed that a problem is going to be reported, so initializes
+ * the compilation result's line positions.
+ *
+ * @return ProblemReporter
+ */
+public ProblemReporter problemReporter() {
+	this.problemReporter.referenceContext = this.referenceContext;
+	return this.problemReporter;
+}
+protected void pushOnIntArrayStack(int[] positions) {
+
+	int stackLength = this.intArrayStack.length;
+	if (++this.intArrayPtr >= stackLength) {
+		System.arraycopy(
+			this.intArrayStack, 0,
+			this.intArrayStack = new int[stackLength + StackIncrement][], 0,
+			stackLength);
+	}
+	this.intArrayStack[this.intArrayPtr] = positions;
+}
+protected void resetModifiers() {
+	super.resetModifiers();
+	this.declarationSourceStart = -1;
+}
+/*
+ * Syntax error was detected. Will attempt to perform some recovery action in order
+ * to resume to the regular parse loop.
+ */
+protected boolean resumeOnSyntaxError() {
+	return false;
+}
+/*
+ * Answer a char array representation of the type name formatted like:
+ * - type name + dimensions
+ * Example:
+ * "A[][]".toCharArray()
+ * "java.lang.String".toCharArray()
+ */
+private char[] returnTypeName(TypeReference type) {
+	int dimension = type.dimensions();
+	if (dimension != 0) {
+		char[] dimensionsArray = new char[dimension * 2];
+		for (int i = 0; i < dimension; i++) {
+			dimensionsArray[i*2] = '[';
+			dimensionsArray[(i*2) + 1] = ']';
+		}
+		return CharOperation.concat(
+			CharOperation.concatWith(type.getTypeName(), '.'),
+			dimensionsArray);
+	}
+	return CharOperation.concatWith(type.getTypeName(), '.');
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("intArrayPtr = " + this.intArrayPtr + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+	buffer.append(super.toString());
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ExtraFlags.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ExtraFlags.java
new file mode 100644
index 0000000..3dbf883
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ExtraFlags.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+
+public final class ExtraFlags {
+	public final static int HasNonPrivateStaticMemberTypes = 0x0001;
+	public final static int IsMemberType = 0x0002;
+	public final static int IsLocalType = 0x0004;
+	
+	//internal flags
+	public final static int ParameterTypesStoredAsSignature = 0x0010;
+	
+	public static int getExtraFlags(ClassFileReader reader) {
+		int extraFlags = 0;
+		
+		if (reader.isNestedType()) {
+			extraFlags |= ExtraFlags.IsMemberType;
+		}
+		
+		if (reader.isLocal()) {
+			extraFlags |= ExtraFlags.IsLocalType;
+		}
+		
+		IBinaryNestedType[] memberTypes = reader.getMemberTypes();
+		int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+		if (memberTypeCounter > 0) {
+			done : for (int i = 0; i < memberTypeCounter; i++) {
+				int modifiers = memberTypes[i].getModifiers();
+				// if the member type is static and not private
+				if ((modifiers & ClassFileConstants.AccStatic) != 0 && (modifiers & ClassFileConstants.AccPrivate) == 0) {
+					extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+					break done;
+				}
+			}
+			
+		}
+		
+		return extraFlags;
+	}
+	
+	public static int getExtraFlags(IType type) throws JavaModelException {
+		int extraFlags = 0;
+		
+		if (type.isMember()) {
+			extraFlags |= ExtraFlags.IsMemberType;
+		}
+		
+		if (type.isLocal()) {
+			extraFlags |= ExtraFlags.IsLocalType;
+		}
+		
+		IType[] memberTypes = type.getTypes();
+		int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+		if (memberTypeCounter > 0) {
+			done : for (int i = 0; i < memberTypeCounter; i++) {
+				int flags = memberTypes[i].getFlags();
+				// if the member type is static and not private
+				if ((flags & ClassFileConstants.AccStatic) != 0 && (flags & ClassFileConstants.AccPrivate) == 0 ) {
+					extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+					break done;
+				}
+			}
+		}
+		
+		return extraFlags;
+	}
+	
+	public static int getExtraFlags(TypeDeclaration typeDeclaration) {
+		int extraFlags = 0;
+		
+		if (typeDeclaration.enclosingType != null) {
+			extraFlags |= ExtraFlags.IsMemberType;
+		}
+		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+		int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+		if (memberTypeCounter > 0) {
+			done : for (int i = 0; i < memberTypeCounter; i++) {
+				int modifiers = memberTypes[i].modifiers;
+				// if the member type is static and not private
+				if ((modifiers & ClassFileConstants.AccStatic) != 0 && (modifiers & ClassFileConstants.AccPrivate) == 0) {
+					extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+					break done;
+				}
+			}
+		}
+		
+		return extraFlags;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java
new file mode 100644
index 0000000..2eb34b0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java
@@ -0,0 +1,412 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+
+/**
+ * Part of the source element parser responsible for building the output.
+ * It gets notified of structural information as they are detected, relying
+ * on the requestor to assemble them together, based on the notifications it got.
+ *
+ * The structural investigation includes:
+ * - package statement
+ * - import statements
+ * - top-level types: package member, member types (member types of member types...)
+ * - fields
+ * - methods
+ *
+ * If reference information is requested, then all source constructs are
+ * investigated and type, field & method references are provided as well.
+ *
+ * Any (parsing) problem encountered is also provided.
+ *
+ * All positions are relative to the exact source fed to the parser.
+ *
+ * Elements which are complex are notified in two steps:
+ * - enter<Element> : once the element header has been identified
+ * - exit<Element> : once the element has been fully consumed
+ *
+ * other simpler elements (package, import) are read all at once:
+ * - accept<Element>
+ */
+
+public interface IDocumentElementRequestor {
+/**
+ * @param declarationStart - a source position corresponding to the start of the package
+ *  declaration
+ * @param declarationEnd - a source position corresponding to the end of the package
+ *  declaration
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param name - the name of the package
+ * @param nameStartPosition - a source position corresponding to the first character of the
+ *  name
+ * @param onDemand - a boolean equals to true if the import is an import on demand
+ */
+void acceptImport(
+	int declarationStart,
+	int declarationEnd,
+	int[] javaDocPositions,
+	char[] name,
+	int nameStartPosition,
+	boolean onDemand,
+	int modifiers);
+/**
+ * @param declarationStart - a source position corresponding to the start of the package
+ *  declaration
+ * @param declarationEnd - a source position corresponding to the end of the package
+ *  declaration
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this initializer
+ * @param modifiersStart - a source position corresponding to the start
+ *  of the textual modifiers, is < 0 if there are no textual modifiers
+ * @param bodyStart - the position of the '{'
+ * @param bodyEnd - the position of the '}'
+ */
+void acceptInitializer(
+	int declarationStart,
+	int declarationEnd,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	int bodyStart,
+	int bodyEnd);
+/*
+ * Table of line separator position. This table is passed once at the end
+ * of the parse action, so as to allow computation of normalized ranges.
+ *
+ * A line separator might corresponds to several characters in the source,
+ *
+ */
+void acceptLineSeparatorPositions(int[] positions);
+/**
+ * @param declarationStart - a source position corresponding to the start of the package
+ *  declaration
+ * @param declarationEnd - a source position corresponding to the end of the package
+ *  declaration
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param name - the name of the package
+ * @param nameStartPosition - a source position corresponding to the first character of the
+ *  name
+ */
+void acceptPackage(
+	int declarationStart,
+	int declarationEnd,
+	int[] javaDocPositions,
+	char[] name,
+	int nameStartPosition);
+/**
+ * @param problem - Used to report a problem while running the JDOM
+ */
+void acceptProblem(CategorizedProblem problem);
+/**
+ * @param declarationStart - a source position corresponding to the start
+ *  of this class.
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this class
+ * @param modifiersStart - a source position corresponding to the start
+ *  of the textual modifiers, is < 0 if there are no textual modifiers
+ * @param classStart - a source position corresponding to the start
+ *  of the keyword 'class'
+ * @param name - the name of the class
+ * @param nameStart - a source position corresponding to the start of the name
+ * @param nameEnd - a source position corresponding to the end of the name
+ * @param superclass - the name of the superclass
+ * @param superclassStart - a source position corresponding to the start
+ *  of the superclass name
+ * @param superclassEnd - a source position corresponding to the end of the
+ *  superclass name
+ * @param superinterfaces - the name of the superinterfaces
+ * @param superinterfaceStarts - an array of source positions corresponding
+ *  to the start of their respective superinterface names
+ * @param superinterfaceEnds - an array of source positions corresponding
+ *  to the end of their respective superinterface names
+ * @param bodyStart - a source position corresponding to the open bracket
+ *  of the class body
+ */
+void enterClass(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	int classStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[] superclass,
+	int superclassStart,
+	int superclassEnd,
+	char[][] superinterfaces,
+	int[] superinterfaceStarts,
+	int[] superinterfaceEnds,
+	int bodyStart);
+void enterCompilationUnit();
+/**
+ * @param declarationStart - a source position corresponding to the first character
+ *  of this constructor declaration
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this constructor converted to a flag
+ * @param modifiersStart - a source position corresponding to the first character of the
+ *  textual modifiers
+ * @param name - the name of this constructor
+ * @param nameStart - a source position corresponding to the first character of the name
+ * @param nameEnd - a source position corresponding to the last character of the name
+ * @param parameterTypes - a list of parameter type names
+ * @param parameterTypeStarts - a list of source positions corresponding to the
+ *  first character of each parameter type name
+ * @param parameterTypeEnds - a list of source positions corresponding to the
+ *  last character of each parameter type name
+ * @param parameterNames - a list of the names of the parameters
+ * @param parametersEnd - a source position corresponding to the last character of the
+ *  parameter list
+ * @param exceptionTypes - a list of the exception types
+ * @param exceptionTypeStarts - a list of source positions corresponding to the first
+ *  character of the respective exception types
+ * @param exceptionTypeEnds - a list of source positions corresponding to the last
+ *  character of the respective exception types
+ * @param bodyStart - a source position corresponding to the start of this
+ *  constructor's body
+ */
+void enterConstructor(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] parameterTypes,
+	int [] parameterTypeStarts,
+	int [] parameterTypeEnds,
+	char[][] parameterNames,
+	int [] parameterNameStarts,
+	int [] parameterNameEnds,
+	int parametersEnd,
+	char[][] exceptionTypes,
+	int [] exceptionTypeStarts,
+	int [] exceptionTypeEnds,
+	int bodyStart);
+/**
+ * @param declarationStart - a source position corresponding to the first character
+ *  of this field
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this field converted to a flag
+ * @param modifiersStart - a source position corresponding to the first character of the
+ *  textual modifiers
+ * @param type - the name of the field type
+ * @param typeStart - a source position corresponding to the start of the fields type
+ * @param typeEnd - a source position corresponding to the end of the fields type
+ * @param typeDimensionCount - the array dimension indicated on the type (for example, 'int[] v')
+ * @param name - the name of this constructor
+ * @param nameStart - a source position corresponding to the first character of the name
+ * @param nameEnd - a source position corresponding to the last character of the name
+ * @param extendedTypeDimensionCount - the array dimension indicated on the variable,
+ *  (for example, 'int v[]')
+ * @param extendedTypeDimensionEnd - a source position corresponding to the end of
+ *  the extened type dimension. This position should be -1 in case there is no extended
+ *  dimension for the type.
+ */
+void enterField(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] type,
+	int typeStart,
+	int typeEnd,
+ 	int typeDimensionCount,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	int extendedTypeDimensionCount,
+	int extendedTypeDimensionEnd);
+/**
+ * @param declarationStart - a source position corresponding to the start
+ *  of this class.
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this class
+ * @param modifiersStart - a source position corresponding to the start
+ *  of the textual modifiers, is < 0 if there are no textual modifiers
+ * @param interfaceStart - a source position corresponding to the start
+ *  of the keyword 'interface'
+ * @param name - the name of the class
+ * @param nameStart - a source position corresponding to the start of the name
+ * @param nameEnd - a source position corresponding to the end of the name
+ * @param superinterfaces - the name of the superinterfaces
+ * @param superinterfaceStarts - an array of source positions corresponding
+ *  to the start of their respective superinterface names
+ * @param superinterfaceEnds - an array of source positions corresponding
+ *  to the end of their respective superinterface names
+ * @param bodyStart - a source position corresponding to the open bracket
+ *  of the class body
+ */
+void enterInterface(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	int interfaceStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] superinterfaces,
+	int[] superinterfaceStarts,
+	int[] superinterfaceEnds,
+	int bodyStart);
+/**
+ * @param declarationStart - a source position corresponding to the first character
+ *  of this constructor declaration
+ * @param javaDocPositions - answer back an array of sourceStart/sourceEnd
+ * positions of the available JavaDoc comments. The array is a flattened
+ * structure: 2*n entries with consecutives start and end positions.
+ * If no JavaDoc is available, then null is answered instead of an empty array.
+ * e.g. { 10, 20, 25, 45 }  --> javadoc1 from 10 to 20, javadoc2 from 25 to 45
+ * The array is equals to null if there are no javadoc comments
+ * @param modifiers - the modifiers for this constructor converted to a flag
+ * @param modifiersStart - a source position corresponding to the first character of the
+ *  textual modifiers
+ * @param returnType - the name of the return type
+ * @param returnTypeStart - a source position corresponding to the first character
+ *  of the return type
+ * @param returnTypeEnd - a source position corresponding to the last character
+ *  of the return type
+ * @param returnTypeDimensionCount - the array dimension count as supplied on the
+ *  return type (for example, 'public int[] foo() {}')
+ * @param name - the name of this constructor
+ * @param nameStart - a source position corresponding to the first character of the name
+ * @param nameEnd - a source position corresponding to the last character of the name
+ * @param parameterTypes - a list of parameter type names
+ * @param parameterTypeStarts - a list of source positions corresponding to the
+ *  first character of each parameter type name
+ * @param parameterTypeEnds - a list of source positions corresponding to the
+ *  last character of each parameter type name
+ * @param parameterNames - a list of the names of the parameters
+ * @param parametersEnd - a source position corresponding to the last character of the
+ *  parameter list
+ * @param extendedReturnTypeDimensionCount - the array dimension count as supplied on the
+ *  end of the parameter list (for example, 'public int foo()[] {}')
+ * @param extendedReturnTypeDimensionEnd - a source position corresponding to the last character
+ *  of the extended return type dimension. This position should be -1 in case there is no extended
+ *  dimension for the type.
+ * @param exceptionTypes - a list of the exception types
+ * @param exceptionTypeStarts - a list of source positions corresponding to the first
+ *  character of the respective exception types
+ * @param exceptionTypeEnds - a list of source positions corresponding to the last
+ *  character of the respective exception types
+ * @param bodyStart - a source position corresponding to the start of this
+ *  method's body
+ */
+void enterMethod(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] returnType,
+	int returnTypeStart,
+	int returnTypeEnd,
+ 	int returnTypeDimensionCount,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] parameterTypes,
+	int [] parameterTypeStarts,
+	int [] parameterTypeEnds,
+	char[][] parameterNames,
+	int [] parameterNameStarts,
+	int [] parameterNameEnds,
+	int parametersEnd,
+	int extendedReturnTypeDimensionCount,
+	int extendedReturnTypeDimensionEnd,
+	char[][] exceptionTypes,
+	int [] exceptionTypeStarts,
+	int [] exceptionTypeEnds,
+	int bodyStart);
+/**
+ * @param bodyEnd - a source position corresponding to the closing bracket of the class
+ * @param declarationEnd - a source position corresponding to the end of the class
+ *  declaration.  This can include whitespace and comments following the closing bracket.
+ */
+void exitClass(
+	int bodyEnd,
+	int declarationEnd);
+/**
+ * @param declarationEnd - a source position corresponding to the end of the compilation unit
+ */
+void exitCompilationUnit(
+	int declarationEnd);
+/**
+ * @param bodyEnd - a source position corresponding to the closing bracket of the method
+ * @param declarationEnd - a source position corresponding to the end of the method
+ *  declaration.  This can include whitespace and comments following the closing bracket.
+ */
+void exitConstructor(
+	int bodyEnd,
+	int declarationEnd);
+/**
+ * @param bodyEnd - a source position corresponding to the end of the field.
+ * @param declarationEnd - a source position corresponding to the end of the field.
+ *  This can include whitespace and comments following the semi-colon.
+ */
+void exitField(
+	int bodyEnd,
+	int declarationEnd);
+/**
+ * @param bodyEnd - a source position corresponding to the closing bracket of the interface
+ * @param declarationEnd - a source position corresponding to the end of the interface
+ *  declaration.  This can include whitespace and comments following the closing bracket.
+ */
+void exitInterface(
+	int bodyEnd,
+	int declarationEnd);
+/**
+ * @param bodyEnd - a source position corresponding to the closing bracket of the method
+ * @param declarationEnd - a source position corresponding to the end of the method
+ *  declaration.  This can include whitespace and comments following the closing bracket.
+ */
+void exitMethod(
+	int bodyEnd,
+	int declarationEnd);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
new file mode 100644
index 0000000..be37816
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+
+/*
+ * Part of the source element parser responsible for building the output. It
+ * gets notified of structural information as they are detected, relying on the
+ * requestor to assemble them together, based on the notifications it got.
+ *
+ * The structural investigation includes: - package statement - import
+ * statements - top-level types: package member, member types (member types of
+ * member types...) - fields - methods
+ *
+ * If reference information is requested, then all source constructs are
+ * investigated and type, field & method references are provided as well.
+ *
+ * Any (parsing) problem encountered is also provided.
+ *
+ * All positions are relative to the exact source fed to the parser.
+ *
+ * Elements which are complex are notified in two steps: - enter <Element> :
+ * once the element header has been identified - exit <Element> : once the
+ * element has been fully consumed
+ *
+ * other simpler elements (package, import) are read all at once: - accept
+ * <Element>
+ */
+
+public interface ISourceElementRequestor {
+
+	public static class TypeInfo {
+		public int declarationStart;
+		public int modifiers;
+		public char[] name;
+		public int nameSourceStart;
+		public int nameSourceEnd;
+		public char[] superclass;
+		public char[][] superinterfaces;
+		public TypeParameterInfo[] typeParameters;
+		public char[][] categories;
+		public boolean secondary;
+		public boolean anonymousMember;
+		public Annotation[] annotations;
+		public int extraFlags;
+		public TypeDeclaration node;
+		public HashMap childrenCategories = new HashMap();
+	}
+
+	public static class TypeParameterInfo {
+		public int declarationStart;
+		public int declarationEnd;
+		public char[] name;
+		public int nameSourceStart;
+		public int nameSourceEnd;
+		public char[][] bounds;
+	}
+
+	public static class MethodInfo {
+		public boolean isConstructor;
+		public boolean isAnnotation;
+		public int declarationStart;
+		public int modifiers;
+		public char[] returnType;
+		public char[] name;
+		public int nameSourceStart;
+		public int nameSourceEnd;
+		public char[][] parameterTypes;
+		public char[][] parameterNames;
+		public char[][] exceptionTypes;
+		public TypeParameterInfo[] typeParameters;
+		public char[][] categories;
+		public Annotation[] annotations;
+		public char[] declaringPackageName;
+		public int declaringTypeModifiers;
+		public int extraFlags;
+		public AbstractMethodDeclaration node;
+		public ParameterInfo[] parameterInfos;
+	}
+
+	public static class ParameterInfo {
+		public int modifiers;
+		public int declarationStart;
+		public int declarationEnd;
+		public int nameSourceStart;
+		public int nameSourceEnd;
+		public char[] name;
+	}
+	public static class FieldInfo {
+		public int declarationStart;
+		public int modifiers;
+		public char[] type;
+		public char[] name;
+		public int nameSourceStart;
+		public int nameSourceEnd;
+		public char[][] categories;
+		public Annotation[] annotations;
+		public FieldDeclaration node;
+	}
+
+	void acceptAnnotationTypeReference(char[][] annotation, int sourceStart, int sourceEnd);
+
+	void acceptAnnotationTypeReference(char[] annotation, int sourcePosition);
+
+	void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition);
+
+	void acceptFieldReference(char[] fieldName, int sourcePosition);
+	/**
+	 * @param declarationStart
+	 *                   This is the position of the first character of the import
+	 *                   keyword.
+	 * @param declarationEnd
+	 *                   This is the position of the ';' ending the import statement or
+	 *                   the end of the comment following the import.
+	 * @param nameStart
+	 *                   This is the position of the first character of the import declaration's
+	 *                   name.
+	 * @param nameEnd
+	 *                   This is the position of the last character of the import declaration's
+	 *                   name.
+	 * @param tokens
+	 *                   This are the tokens of the import like specified in the source.
+	 * @param onDemand
+	 *                   set to true if the import is an import on demand (e.g. import
+	 *                   java.io.*). False otherwise.
+	 * @param modifiers
+	 *                   can be set to static from 1.5 on.
+	 */
+	void acceptImport(int declarationStart, int declarationEnd, int nameStart, int nameEnd, char[][] tokens, boolean onDemand, int modifiers);
+
+	/*
+	 * Table of line separator position. This table is passed once at the end of
+	 * the parse action, so as to allow computation of normalized ranges.
+	 *
+	 * A line separator might corresponds to several characters in the source,
+	 *
+	 */
+	void acceptLineSeparatorPositions(int[] positions);
+
+	void acceptMethodReference(char[] methodName, int argCount, int sourcePosition);
+
+	void acceptPackage(ImportReference importReference);
+
+	void acceptProblem(CategorizedProblem problem);
+
+	void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd);
+
+	void acceptTypeReference(char[] typeName, int sourcePosition);
+
+	void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd);
+
+	void acceptUnknownReference(char[] name, int sourcePosition);
+
+	void enterCompilationUnit();
+
+	void enterConstructor(MethodInfo methodInfo);
+
+	void enterField(FieldInfo fieldInfo);
+
+	void enterInitializer(int declarationStart, int modifiers);
+
+	void enterMethod(MethodInfo methodInfo);
+
+	void enterType(TypeInfo typeInfo);
+
+	void exitCompilationUnit(int declarationEnd);
+
+	void exitConstructor(int declarationEnd);
+
+	/*
+	 * initializationStart denotes the source start of the expression used for
+	 * initializing the field if any (-1 if no initialization).
+	 */
+	void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd);
+
+	void exitInitializer(int declarationEnd);
+
+	void exitMethod(int declarationEnd, Expression defaultValue);
+
+	void exitType(int declarationEnd);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java
new file mode 100644
index 0000000..5a48c45
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java
@@ -0,0 +1,796 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.ParameterInfo;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.TypeParameterInfo;
+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.AllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+
+public class SourceElementNotifier {
+	/**
+	 * An ast visitor that visits local type declarations.
+	 */
+	public class LocalDeclarationVisitor extends ASTVisitor {
+		public ImportReference currentPackage;
+		ArrayList declaringTypes;
+		public void pushDeclaringType(TypeDeclaration declaringType) {
+			if (this.declaringTypes == null) {
+				this.declaringTypes = new ArrayList();
+			}
+			this.declaringTypes.add(declaringType);
+		}
+		public void popDeclaringType() {
+			this.declaringTypes.remove(this.declaringTypes.size()-1);
+		}
+		public TypeDeclaration peekDeclaringType() {
+			if (this.declaringTypes == null) return null;
+			int size = this.declaringTypes.size();
+			if (size == 0) return null;
+			return (TypeDeclaration) this.declaringTypes.get(size-1);
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+			notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
+			return false; // don't visit members as this was done during notifySourceElementRequestor(...)
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
+			notifySourceElementRequestor(typeDeclaration, true, peekDeclaringType(), this.currentPackage);
+			return false; // don't visit members as this was done during notifySourceElementRequestor(...)
+		}
+	}
+
+	ISourceElementRequestor requestor;
+	boolean reportReferenceInfo;
+	char[][] typeNames;
+	char[][] superTypeNames;
+	int nestedTypeIndex;
+	LocalDeclarationVisitor localDeclarationVisitor = null;
+
+	HashtableOfObjectToInt sourceEnds;
+	Map nodesToCategories;
+
+	int initialPosition;
+	int eofPosition;
+
+public SourceElementNotifier(ISourceElementRequestor requestor, boolean reportLocalDeclarations) {
+	this.requestor = requestor;
+	if (reportLocalDeclarations) {
+		this.localDeclarationVisitor = new LocalDeclarationVisitor();
+	}
+	this.typeNames = new char[4][];
+	this.superTypeNames = new char[4][];
+	this.nestedTypeIndex = 0;
+}
+protected Object[][] getArgumentInfos(Argument[] arguments) {
+	int argumentLength = arguments.length;
+	char[][] argumentTypes = new char[argumentLength][];
+	char[][] argumentNames = new char[argumentLength][];
+	ParameterInfo[] parameterInfos = new ParameterInfo[argumentLength];
+	for (int i = 0; i < argumentLength; i++) {
+		Argument argument = arguments[i];
+		argumentTypes[i] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.');
+		char[] name = argument.name;
+		argumentNames[i] = name;
+		ParameterInfo parameterInfo = new ParameterInfo();
+		parameterInfo.declarationStart = argument.declarationSourceStart;
+		parameterInfo.declarationEnd = argument.declarationSourceEnd;
+		parameterInfo.nameSourceStart = argument.sourceStart;
+		parameterInfo.nameSourceEnd = argument.sourceEnd;
+		parameterInfo.modifiers = argument.modifiers;
+		parameterInfo.name = name;
+		parameterInfos[i] = parameterInfo;
+	}
+
+	return new Object[][] { parameterInfos, new char[][][] { argumentTypes, argumentNames } };
+}
+protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) {
+	char[][] interfaceNames = null;
+	int superInterfacesLength = 0;
+	TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+	if (superInterfaces != null) {
+		superInterfacesLength = superInterfaces.length;
+		interfaceNames = new char[superInterfacesLength][];
+	} else {
+		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+			// see PR 3442
+			QualifiedAllocationExpression alloc = typeDeclaration.allocation;
+			if (alloc != null && alloc.type != null) {
+				superInterfaces = new TypeReference[] { alloc.type};
+				superInterfacesLength = 1;
+				interfaceNames = new char[1][];
+			}
+		}
+	}
+	if (superInterfaces != null) {
+		for (int i = 0; i < superInterfacesLength; i++) {
+			interfaceNames[i] =
+				CharOperation.concatWith(superInterfaces[i].getParameterizedTypeName(), '.');
+		}
+	}
+	return interfaceNames;
+}
+protected char[] getSuperclassName(TypeDeclaration typeDeclaration) {
+	TypeReference superclass = typeDeclaration.superclass;
+	return superclass != null ? CharOperation.concatWith(superclass.getParameterizedTypeName(), '.') : null;
+}
+protected char[][] getThrownExceptions(AbstractMethodDeclaration methodDeclaration) {
+	char[][] thrownExceptionTypes = null;
+	TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+	if (thrownExceptions != null) {
+		int thrownExceptionLength = thrownExceptions.length;
+		thrownExceptionTypes = new char[thrownExceptionLength][];
+		for (int i = 0; i < thrownExceptionLength; i++) {
+			thrownExceptionTypes[i] =
+				CharOperation.concatWith(thrownExceptions[i].getParameterizedTypeName(), '.');
+		}
+	}
+	return thrownExceptionTypes;
+}
+protected char[][] getTypeParameterBounds(TypeParameter typeParameter) {
+	TypeReference firstBound = typeParameter.type;
+	TypeReference[] otherBounds = typeParameter.bounds;
+	char[][] typeParameterBounds = null;
+	if (firstBound != null) {
+		if (otherBounds != null) {
+			int otherBoundsLength = otherBounds.length;
+			char[][] boundNames = new char[otherBoundsLength+1][];
+			boundNames[0] = CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.');
+			for (int j = 0; j < otherBoundsLength; j++) {
+				boundNames[j+1] =
+					CharOperation.concatWith(otherBounds[j].getParameterizedTypeName(), '.');
+			}
+			typeParameterBounds = boundNames;
+		} else {
+			typeParameterBounds = new char[][] { CharOperation.concatWith(firstBound.getParameterizedTypeName(), '.')};
+		}
+	} else {
+		typeParameterBounds = CharOperation.NO_CHAR_CHAR;
+	}
+
+	return typeParameterBounds;
+}
+private TypeParameterInfo[] getTypeParameterInfos(TypeParameter[] typeParameters) {
+	if (typeParameters == null) return null;
+	int typeParametersLength = typeParameters.length;
+	TypeParameterInfo[] result = new TypeParameterInfo[typeParametersLength];
+	for (int i = 0; i < typeParametersLength; i++) {
+		TypeParameter typeParameter = typeParameters[i];
+		char[][] typeParameterBounds = getTypeParameterBounds(typeParameter);
+		ISourceElementRequestor.TypeParameterInfo typeParameterInfo = new ISourceElementRequestor.TypeParameterInfo();
+		typeParameterInfo.declarationStart = typeParameter.declarationSourceStart;
+		typeParameterInfo.declarationEnd = typeParameter.declarationSourceEnd;
+		typeParameterInfo.name = typeParameter.name;
+		typeParameterInfo.nameSourceStart = typeParameter.sourceStart;
+		typeParameterInfo.nameSourceEnd = typeParameter.sourceEnd;
+		typeParameterInfo.bounds = typeParameterBounds;
+		result[i] = typeParameterInfo;
+	}
+	return result;
+}
+/*
+ * Checks whether one of the annotations is the @Deprecated annotation
+ * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89807)
+ */
+private boolean hasDeprecatedAnnotation(Annotation[] annotations) {
+	if (annotations != null) {
+		for (int i = 0, length = annotations.length; i < length; i++) {
+			Annotation annotation = annotations[i];
+			if (CharOperation.equals(annotation.type.getLastToken(), TypeConstants.JAVA_LANG_DEPRECATED[2])) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/*
+ * Update the bodyStart of the corresponding parse node
+ */
+protected void notifySourceElementRequestor(AbstractMethodDeclaration methodDeclaration, TypeDeclaration declaringType, ImportReference currentPackage) {
+
+	// range check
+	boolean isInRange =
+				this.initialPosition <= methodDeclaration.declarationSourceStart
+				&& this.eofPosition >= methodDeclaration.declarationSourceEnd;
+
+	if (methodDeclaration.isClinit()) {
+		this.visitIfNeeded(methodDeclaration);
+		return;
+	}
+
+	if (methodDeclaration.isDefaultConstructor()) {
+		if (this.reportReferenceInfo) {
+			ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
+			ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
+			if (constructorCall != null) {
+				switch(constructorCall.accessMode) {
+					case ExplicitConstructorCall.This :
+						this.requestor.acceptConstructorReference(
+							this.typeNames[this.nestedTypeIndex-1],
+							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
+							constructorCall.sourceStart);
+						break;
+					case ExplicitConstructorCall.Super :
+					case ExplicitConstructorCall.ImplicitSuper :
+						this.requestor.acceptConstructorReference(
+							this.superTypeNames[this.nestedTypeIndex-1],
+							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
+							constructorCall.sourceStart);
+						break;
+				}
+			}
+		}
+		return;
+	}
+	char[][] argumentTypes = null;
+	char[][] argumentNames = null;
+	boolean isVarArgs = false;
+	Argument[] arguments = methodDeclaration.arguments;
+	ParameterInfo[] parameterInfos = null; 
+	if (arguments != null) {
+		Object[][] argumentInfos = getArgumentInfos(arguments);
+		parameterInfos = (ParameterInfo[]) argumentInfos[0];
+		argumentTypes = (char[][]) argumentInfos[1][0];
+		argumentNames = (char[][]) argumentInfos[1][1];
+
+		isVarArgs = arguments[arguments.length-1].isVarArgs();
+	}
+	char[][] thrownExceptionTypes = getThrownExceptions(methodDeclaration);
+	// by default no selector end position
+	int selectorSourceEnd = -1;
+	if (methodDeclaration.isConstructor()) {
+		selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
+		if (isInRange){
+			int currentModifiers = methodDeclaration.modifiers;
+			currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated;
+			if (isVarArgs)
+				currentModifiers |= ClassFileConstants.AccVarargs;
+			if (hasDeprecatedAnnotation(methodDeclaration.annotations))
+				currentModifiers |= ClassFileConstants.AccDeprecated;
+
+			ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
+			methodInfo.isConstructor = true;
+			methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
+			methodInfo.modifiers = currentModifiers;
+			methodInfo.name = methodDeclaration.selector;
+			methodInfo.nameSourceStart = methodDeclaration.sourceStart;
+			methodInfo.nameSourceEnd = selectorSourceEnd;
+			methodInfo.parameterTypes = argumentTypes;
+			methodInfo.parameterNames = argumentNames;
+			methodInfo.exceptionTypes = thrownExceptionTypes;
+			methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
+			methodInfo.parameterInfos = parameterInfos;
+			methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration);
+			methodInfo.annotations = methodDeclaration.annotations;
+			methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
+			methodInfo.declaringTypeModifiers = declaringType.modifiers;
+			methodInfo.extraFlags = ExtraFlags.getExtraFlags(declaringType);
+			methodInfo.node = methodDeclaration;
+			this.requestor.enterConstructor(methodInfo);
+		}
+		if (this.reportReferenceInfo) {
+			ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) methodDeclaration;
+			ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
+			if (constructorCall != null) {
+				switch(constructorCall.accessMode) {
+					case ExplicitConstructorCall.This :
+						this.requestor.acceptConstructorReference(
+							this.typeNames[this.nestedTypeIndex-1],
+							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
+							constructorCall.sourceStart);
+						break;
+					case ExplicitConstructorCall.Super :
+					case ExplicitConstructorCall.ImplicitSuper :
+						this.requestor.acceptConstructorReference(
+							this.superTypeNames[this.nestedTypeIndex-1],
+							constructorCall.arguments == null ? 0 : constructorCall.arguments.length,
+							constructorCall.sourceStart);
+						break;
+				}
+			}
+		}
+		this.visitIfNeeded(methodDeclaration);
+		if (isInRange){
+			this.requestor.exitConstructor(methodDeclaration.declarationSourceEnd);
+		}
+		return;
+	}
+	selectorSourceEnd = this.sourceEnds.get(methodDeclaration);
+	if (isInRange) {
+		int currentModifiers = methodDeclaration.modifiers;
+		currentModifiers &= ExtraCompilerModifiers.AccJustFlag | ClassFileConstants.AccDeprecated | ClassFileConstants.AccAnnotationDefault | ExtraCompilerModifiers.AccDefaultMethod;
+		if (isVarArgs)
+			currentModifiers |= ClassFileConstants.AccVarargs;
+		if (hasDeprecatedAnnotation(methodDeclaration.annotations))
+			currentModifiers |= ClassFileConstants.AccDeprecated;
+
+		TypeReference returnType = methodDeclaration instanceof MethodDeclaration
+			? ((MethodDeclaration) methodDeclaration).returnType
+			: null;
+		ISourceElementRequestor.MethodInfo methodInfo = new ISourceElementRequestor.MethodInfo();
+		methodInfo.isAnnotation = methodDeclaration instanceof AnnotationMethodDeclaration;
+		methodInfo.declarationStart = methodDeclaration.declarationSourceStart;
+		methodInfo.modifiers = currentModifiers;
+		methodInfo.returnType = returnType == null ? null : CharOperation.concatWith(returnType.getParameterizedTypeName(), '.');
+		methodInfo.name = methodDeclaration.selector;
+		methodInfo.nameSourceStart = methodDeclaration.sourceStart;
+		methodInfo.nameSourceEnd = selectorSourceEnd;
+		methodInfo.parameterTypes = argumentTypes;
+		methodInfo.parameterNames = argumentNames;
+		methodInfo.exceptionTypes = thrownExceptionTypes;
+		methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters());
+		methodInfo.parameterInfos = parameterInfos;
+		methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration);
+		methodInfo.annotations = methodDeclaration.annotations;
+		methodInfo.node = methodDeclaration;
+		this.requestor.enterMethod(methodInfo);
+	}
+
+	this.visitIfNeeded(methodDeclaration);
+
+	if (isInRange) {
+		if (methodDeclaration instanceof AnnotationMethodDeclaration) {
+			AnnotationMethodDeclaration annotationMethodDeclaration = (AnnotationMethodDeclaration) methodDeclaration;
+			Expression expression = annotationMethodDeclaration.defaultValue;
+			if (expression != null) {
+				this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, expression);
+				return;
+			}
+		}
+		this.requestor.exitMethod(methodDeclaration.declarationSourceEnd, null);
+	}
+}
+
+/*
+ * Update the bodyStart of the corresponding parse node
+ */
+public void notifySourceElementRequestor(
+		CompilationUnitDeclaration parsedUnit,
+		int sourceStart,
+		int sourceEnd,
+		boolean reportReference,
+		HashtableOfObjectToInt sourceEndsMap,
+		Map nodesToCategoriesMap) {
+
+	this.initialPosition = sourceStart;
+	this.eofPosition = sourceEnd;
+
+	this.reportReferenceInfo = reportReference;
+	this.sourceEnds = sourceEndsMap;
+	this.nodesToCategories = nodesToCategoriesMap;
+
+	try {
+		// range check
+		boolean isInRange =
+					this.initialPosition <= parsedUnit.sourceStart
+					&& this.eofPosition >= parsedUnit.sourceEnd;
+
+		// collect the top level ast nodes
+		int length = 0;
+		ASTNode[] nodes = null;
+		if (isInRange) {
+			this.requestor.enterCompilationUnit();
+		}
+		ImportReference currentPackage = parsedUnit.currentPackage;
+		if (this.localDeclarationVisitor !=  null) {
+			this.localDeclarationVisitor.currentPackage = currentPackage;
+		}
+		ImportReference[] imports = parsedUnit.imports;
+		TypeDeclaration[] types = parsedUnit.types;
+		length =
+			(currentPackage == null ? 0 : 1)
+			+ (imports == null ? 0 : imports.length)
+			+ (types == null ? 0 : types.length);
+		nodes = new ASTNode[length];
+		int index = 0;
+		if (currentPackage != null) {
+			nodes[index++] = currentPackage;
+		}
+		if (imports != null) {
+			for (int i = 0, max = imports.length; i < max; i++) {
+				nodes[index++] = imports[i];
+			}
+		}
+		if (types != null) {
+			for (int i = 0, max = types.length; i < max; i++) {
+				nodes[index++] = types[i];
+			}
+		}
+
+		// notify the nodes in the syntactical order
+		if (length > 0) {
+			quickSort(nodes, 0, length-1);
+			for (int i=0;i<length;i++) {
+				ASTNode node = nodes[i];
+				if (node instanceof ImportReference) {
+					ImportReference importRef = (ImportReference)node;
+					if (node == parsedUnit.currentPackage) {
+						notifySourceElementRequestor(importRef, true);
+					} else {
+						notifySourceElementRequestor(importRef, false);
+					}
+				} else { // instanceof TypeDeclaration
+					notifySourceElementRequestor((TypeDeclaration)node, true, null, currentPackage);
+				}
+			}
+		}
+
+		if (isInRange) {
+			this.requestor.exitCompilationUnit(parsedUnit.sourceEnd);
+		}
+	} finally {
+		reset();
+	}
+}
+
+/*
+* Update the bodyStart of the corresponding parse node
+*/
+protected void notifySourceElementRequestor(FieldDeclaration fieldDeclaration, TypeDeclaration declaringType) {
+
+	// range check
+	boolean isInRange =
+				this.initialPosition <= fieldDeclaration.declarationSourceStart
+				&& this.eofPosition >= fieldDeclaration.declarationSourceEnd;
+
+	switch(fieldDeclaration.getKind()) {
+		case AbstractVariableDeclaration.ENUM_CONSTANT:
+			if (this.reportReferenceInfo) {
+				// accept constructor reference for enum constant
+				if (fieldDeclaration.initialization instanceof AllocationExpression) {
+					AllocationExpression alloc = (AllocationExpression) fieldDeclaration.initialization;
+					this.requestor.acceptConstructorReference(
+						declaringType.name,
+						alloc.arguments == null ? 0 : alloc.arguments.length,
+						alloc.sourceStart);
+				}
+			}
+			// $FALL-THROUGH$
+		case AbstractVariableDeclaration.FIELD:
+			int fieldEndPosition = this.sourceEnds.get(fieldDeclaration);
+			if (fieldEndPosition == -1) {
+				// use the declaration source end by default
+				fieldEndPosition = fieldDeclaration.declarationSourceEnd;
+			}
+			if (isInRange) {
+				int currentModifiers = fieldDeclaration.modifiers;
+
+				// remember deprecation so as to not lose it below
+				boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(fieldDeclaration.annotations);
+
+				char[] typeName = null;
+				if (fieldDeclaration.type == null) {
+					// enum constant
+					typeName = declaringType.name;
+					currentModifiers |= ClassFileConstants.AccEnum;
+				} else {
+					// regular field
+					typeName = CharOperation.concatWith(fieldDeclaration.type.getParameterizedTypeName(), '.');
+				}
+				ISourceElementRequestor.FieldInfo fieldInfo = new ISourceElementRequestor.FieldInfo();
+				fieldInfo.declarationStart = fieldDeclaration.declarationSourceStart;
+				fieldInfo.name = fieldDeclaration.name;
+				fieldInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
+				fieldInfo.type = typeName;
+				fieldInfo.nameSourceStart = fieldDeclaration.sourceStart;
+				fieldInfo.nameSourceEnd = fieldDeclaration.sourceEnd;
+				fieldInfo.categories = (char[][]) this.nodesToCategories.get(fieldDeclaration);
+				fieldInfo.annotations = fieldDeclaration.annotations;
+				fieldInfo.node = fieldDeclaration;
+				this.requestor.enterField(fieldInfo);
+			}
+			this.visitIfNeeded(fieldDeclaration, declaringType);
+			if (isInRange){
+				this.requestor.exitField(
+					// filter out initializations that are not a constant (simple check)
+					(fieldDeclaration.initialization == null
+							|| fieldDeclaration.initialization instanceof ArrayInitializer
+							|| fieldDeclaration.initialization instanceof AllocationExpression
+							|| fieldDeclaration.initialization instanceof ArrayAllocationExpression
+							|| fieldDeclaration.initialization instanceof Assignment
+							|| fieldDeclaration.initialization instanceof ClassLiteralAccess
+							|| fieldDeclaration.initialization instanceof MessageSend
+							|| fieldDeclaration.initialization instanceof ArrayReference
+							|| fieldDeclaration.initialization instanceof ThisReference) ?
+						-1 :
+						fieldDeclaration.initialization.sourceStart,
+					fieldEndPosition,
+					fieldDeclaration.declarationSourceEnd);
+			}
+			break;
+		case AbstractVariableDeclaration.INITIALIZER:
+			if (isInRange){
+				this.requestor.enterInitializer(
+					fieldDeclaration.declarationSourceStart,
+					fieldDeclaration.modifiers);
+			}
+			this.visitIfNeeded((Initializer)fieldDeclaration);
+			if (isInRange){
+				this.requestor.exitInitializer(fieldDeclaration.declarationSourceEnd);
+			}
+			break;
+	}
+}
+protected void notifySourceElementRequestor(
+	ImportReference importReference,
+	boolean isPackage) {
+	if (isPackage) {
+		this.requestor.acceptPackage(importReference);
+	} else {
+		final boolean onDemand = (importReference.bits & ASTNode.OnDemand) != 0;
+		this.requestor.acceptImport(
+			importReference.declarationSourceStart,
+			importReference.declarationSourceEnd,
+			importReference.sourceStart,
+			onDemand ? importReference.trailingStarPosition : importReference.sourceEnd,
+			importReference.tokens,
+			onDemand,
+			importReference.modifiers);
+	}
+}
+protected void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType, ImportReference currentPackage) {
+
+	if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return;
+
+	// range check
+	boolean isInRange =
+		this.initialPosition <= typeDeclaration.declarationSourceStart
+		&& this.eofPosition >= typeDeclaration.declarationSourceEnd;
+
+	FieldDeclaration[] fields = typeDeclaration.fields;
+	AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+	TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
+	int fieldCounter = fields == null ? 0 : fields.length;
+	int methodCounter = methods == null ? 0 : methods.length;
+	int memberTypeCounter = memberTypes == null ? 0 : memberTypes.length;
+	int fieldIndex = 0;
+	int methodIndex = 0;
+	int memberTypeIndex = 0;
+
+	if (notifyTypePresence){
+		char[][] interfaceNames = getInterfaceNames(typeDeclaration);
+		int kind = TypeDeclaration.kind(typeDeclaration.modifiers);
+		char[] implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
+		if (isInRange) {
+			int currentModifiers = typeDeclaration.modifiers;
+
+			// remember deprecation so as to not lose it below
+			boolean deprecated = (currentModifiers & ClassFileConstants.AccDeprecated) != 0 || hasDeprecatedAnnotation(typeDeclaration.annotations);
+
+			boolean isEnumInit = typeDeclaration.allocation != null && typeDeclaration.allocation.enumConstant != null;
+			char[] superclassName;
+			if (isEnumInit) {
+				currentModifiers |= ClassFileConstants.AccEnum;
+				superclassName = declaringType.name;
+			} else {
+				superclassName = getSuperclassName(typeDeclaration);
+			}
+			ISourceElementRequestor.TypeInfo typeInfo = new ISourceElementRequestor.TypeInfo();
+			if (typeDeclaration.allocation == null) {
+				typeInfo.declarationStart = typeDeclaration.declarationSourceStart;
+			} else if (isEnumInit) {
+				typeInfo.declarationStart = typeDeclaration.allocation.enumConstant.sourceStart;
+			} else {
+				typeInfo.declarationStart = typeDeclaration.allocation.sourceStart;
+			}
+			typeInfo.modifiers = deprecated ? (currentModifiers & ExtraCompilerModifiers.AccJustFlag) | ClassFileConstants.AccDeprecated : currentModifiers & ExtraCompilerModifiers.AccJustFlag;
+			typeInfo.name = typeDeclaration.name;
+			typeInfo.nameSourceStart = isEnumInit ? typeDeclaration.allocation.enumConstant.sourceStart : typeDeclaration.sourceStart;
+			typeInfo.nameSourceEnd = sourceEnd(typeDeclaration);
+			typeInfo.superclass = superclassName;
+			typeInfo.superinterfaces = interfaceNames;
+			typeInfo.typeParameters = getTypeParameterInfos(typeDeclaration.typeParameters);
+			typeInfo.categories = (char[][]) this.nodesToCategories.get(typeDeclaration);
+			typeInfo.secondary = typeDeclaration.isSecondary();
+			typeInfo.anonymousMember = typeDeclaration.allocation != null && typeDeclaration.allocation.enclosingInstance != null;
+			typeInfo.annotations = typeDeclaration.annotations;
+			typeInfo.extraFlags = ExtraFlags.getExtraFlags(typeDeclaration);
+			typeInfo.node = typeDeclaration;
+			this.requestor.enterType(typeInfo);
+			switch (kind) {
+				case TypeDeclaration.CLASS_DECL :
+					if (superclassName != null)
+						implicitSuperclassName = superclassName;
+					break;
+				case TypeDeclaration.INTERFACE_DECL :
+					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_OBJECT;
+					break;
+				case TypeDeclaration.ENUM_DECL :
+					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ENUM;
+					break;
+				case TypeDeclaration.ANNOTATION_TYPE_DECL :
+					implicitSuperclassName = TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION;
+					break;
+			}
+		}
+		if (this.nestedTypeIndex == this.typeNames.length) {
+			// need a resize
+			System.arraycopy(this.typeNames, 0, (this.typeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
+			System.arraycopy(this.superTypeNames, 0, (this.superTypeNames = new char[this.nestedTypeIndex * 2][]), 0, this.nestedTypeIndex);
+		}
+		this.typeNames[this.nestedTypeIndex] = typeDeclaration.name;
+		this.superTypeNames[this.nestedTypeIndex++] = implicitSuperclassName;
+	}
+	while ((fieldIndex < fieldCounter)
+			|| (memberTypeIndex < memberTypeCounter)
+			|| (methodIndex < methodCounter)) {
+		FieldDeclaration nextFieldDeclaration = null;
+		AbstractMethodDeclaration nextMethodDeclaration = null;
+		TypeDeclaration nextMemberDeclaration = null;
+
+		int position = Integer.MAX_VALUE;
+		int nextDeclarationType = -1;
+		if (fieldIndex < fieldCounter) {
+			nextFieldDeclaration = fields[fieldIndex];
+			if (nextFieldDeclaration.declarationSourceStart < position) {
+				position = nextFieldDeclaration.declarationSourceStart;
+				nextDeclarationType = 0; // FIELD
+			}
+		}
+		if (methodIndex < methodCounter) {
+			nextMethodDeclaration = methods[methodIndex];
+			if (nextMethodDeclaration.declarationSourceStart < position) {
+				position = nextMethodDeclaration.declarationSourceStart;
+				nextDeclarationType = 1; // METHOD
+			}
+		}
+		if (memberTypeIndex < memberTypeCounter) {
+			nextMemberDeclaration = memberTypes[memberTypeIndex];
+			if (nextMemberDeclaration.declarationSourceStart < position) {
+				position = nextMemberDeclaration.declarationSourceStart;
+				nextDeclarationType = 2; // MEMBER
+			}
+		}
+		switch (nextDeclarationType) {
+			case 0 :
+				fieldIndex++;
+				notifySourceElementRequestor(nextFieldDeclaration, typeDeclaration);
+				break;
+			case 1 :
+				methodIndex++;
+				notifySourceElementRequestor(nextMethodDeclaration, typeDeclaration, currentPackage);
+				break;
+			case 2 :
+				memberTypeIndex++;
+				notifySourceElementRequestor(nextMemberDeclaration, true, null, currentPackage);
+		}
+	}
+	if (notifyTypePresence){
+		if (isInRange){
+			this.requestor.exitType(typeDeclaration.declarationSourceEnd);
+		}
+		this.nestedTypeIndex--;
+	}
+}
+/*
+ * Sort the given ast nodes by their positions.
+ */
+private static void quickSort(ASTNode[] sortedCollection, int left, int right) {
+	int original_left = left;
+	int original_right = right;
+	ASTNode mid = sortedCollection[left +  (right - left) / 2];
+	do {
+		while (sortedCollection[left].sourceStart < mid.sourceStart) {
+			left++;
+		}
+		while (mid.sourceStart < sortedCollection[right].sourceStart) {
+			right--;
+		}
+		if (left <= right) {
+			ASTNode tmp = sortedCollection[left];
+			sortedCollection[left] = sortedCollection[right];
+			sortedCollection[right] = tmp;
+			left++;
+			right--;
+		}
+	} while (left <= right);
+	if (original_left < right) {
+		quickSort(sortedCollection, original_left, right);
+	}
+	if (left < original_right) {
+		quickSort(sortedCollection, left, original_right);
+	}
+}
+private void reset() {
+	this.typeNames = new char[4][];
+	this.superTypeNames = new char[4][];
+	this.nestedTypeIndex = 0;
+
+	this.sourceEnds = null;
+}
+private int sourceEnd(TypeDeclaration typeDeclaration) {
+	if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+		QualifiedAllocationExpression allocation = typeDeclaration.allocation;
+		if (allocation.enumConstant != null) // case of enum constant body
+			return allocation.enumConstant.sourceEnd;
+		return allocation.type.sourceEnd;
+	} else {
+		return typeDeclaration.sourceEnd;
+	}
+}
+private void visitIfNeeded(AbstractMethodDeclaration method) {
+	if (this.localDeclarationVisitor != null
+		&& (method.bits & ASTNode.HasLocalType) != 0) {
+			if (method instanceof ConstructorDeclaration) {
+				ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method;
+				if (constructorDeclaration.constructorCall != null) {
+					constructorDeclaration.constructorCall.traverse(this.localDeclarationVisitor, method.scope);
+				}
+			}
+			if (method.statements != null) {
+				int statementsLength = method.statements.length;
+				for (int i = 0; i < statementsLength; i++)
+					method.statements[i].traverse(this.localDeclarationVisitor, method.scope);
+			}
+	}
+}
+
+private void visitIfNeeded(FieldDeclaration field, TypeDeclaration declaringType) {
+	if (this.localDeclarationVisitor != null
+		&& (field.bits & ASTNode.HasLocalType) != 0) {
+			if (field.initialization != null) {
+				try {
+					this.localDeclarationVisitor.pushDeclaringType(declaringType);
+					field.initialization.traverse(this.localDeclarationVisitor, (MethodScope) null);
+				} finally {
+					this.localDeclarationVisitor.popDeclaringType();
+				}
+			}
+	}
+}
+
+private void visitIfNeeded(Initializer initializer) {
+	if (this.localDeclarationVisitor != null
+		&& (initializer.bits & ASTNode.HasLocalType) != 0) {
+			if (initializer.block != null) {
+				initializer.block.traverse(this.localDeclarationVisitor, null);
+			}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
new file mode 100644
index 0000000..c5dc415
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -0,0 +1,998 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * A source element parser extracts structural and reference information
+ * from a piece of source.
+ *
+ * also see @ISourceElementRequestor
+ *
+ * The structural investigation includes:
+ * - the package statement
+ * - import statements
+ * - top-level types: package member, member types (member types of member types...)
+ * - fields
+ * - methods
+ *
+ * If reference information is requested, then all source constructs are
+ * investigated and type, field & method references are provided as well.
+ *
+ * Any (parsing) problem encountered is also provided.
+ */
+public class SourceElementParser extends CommentRecorderParser {
+
+	ISourceElementRequestor requestor;
+	boolean reportReferenceInfo;
+	boolean reportLocalDeclarations;
+	HashtableOfObjectToInt sourceEnds = new HashtableOfObjectToInt();
+	HashMap nodesToCategories = new HashMap(); // a map from ASTNode to char[][]
+	boolean useSourceJavadocParser = true;
+
+	SourceElementNotifier notifier;
+
+public SourceElementParser(
+		final ISourceElementRequestor requestor,
+		IProblemFactory problemFactory,
+		CompilerOptions options,
+		boolean reportLocalDeclarations,
+		boolean optimizeStringLiterals) {
+	this(requestor, problemFactory, options, reportLocalDeclarations, optimizeStringLiterals, true/* use SourceJavadocParser */);
+}
+
+public SourceElementParser(
+		ISourceElementRequestor requestor,
+		IProblemFactory problemFactory,
+		CompilerOptions options,
+		boolean reportLocalDeclarations,
+		boolean optimizeStringLiterals,
+		boolean useSourceJavadocParser) {
+
+	super(
+		new ProblemReporter(
+			DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+			options,
+			problemFactory),
+		optimizeStringLiterals);
+
+	this.reportLocalDeclarations = reportLocalDeclarations;
+
+	// we want to notify all syntax error with the acceptProblem API
+	// To do so, we define the record method of the ProblemReporter
+	this.problemReporter = new ProblemReporter(
+		DefaultErrorHandlingPolicies.exitAfterAllProblems(),
+		options,
+		problemFactory) {
+		public void record(CategorizedProblem problem, CompilationResult unitResult, ReferenceContext context, boolean mandatoryError) {
+			unitResult.record(problem, context, mandatoryError); // TODO (jerome) clients are trapping problems either through factory or requestor... is result storing needed?
+			SourceElementParser.this.requestor.acceptProblem(problem);
+		}
+	};
+	this.requestor = requestor;
+	this.options = options;
+
+	this.notifier = new SourceElementNotifier(this.requestor, reportLocalDeclarations);
+
+	// set specific javadoc parser
+	this.useSourceJavadocParser = useSourceJavadocParser;
+	if (useSourceJavadocParser) {
+		this.javadocParser = new SourceJavadocParser(this);
+	}
+}
+private void acceptJavadocTypeReference(Expression expression) {
+	if (expression instanceof JavadocSingleTypeReference) {
+		JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) expression;
+		this.requestor.acceptTypeReference(singleRef.token, singleRef.sourceStart);
+	} else if (expression instanceof JavadocQualifiedTypeReference) {
+		JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) expression;
+		this.requestor.acceptTypeReference(qualifiedRef.tokens, qualifiedRef.sourceStart, qualifiedRef.sourceEnd);
+	}
+}
+public void addUnknownRef(NameReference nameRef) {
+	// Note that:
+	// - the only requestor interested in references is the SourceIndexerRequestor
+	// - a name reference can become a type reference only during the cast case, it is then tagged later with the Binding.TYPE bit
+	// However since the indexer doesn't make the distinction between name reference and type reference, there is no need
+	// to report a type reference in the SourceElementParser.
+	// This gained 3.7% in the indexing performance test.
+	if (nameRef instanceof SingleNameReference) {
+		this.requestor.acceptUnknownReference(((SingleNameReference) nameRef).token, nameRef.sourceStart);
+	} else {
+		//QualifiedNameReference
+		this.requestor.acceptUnknownReference(((QualifiedNameReference) nameRef).tokens, nameRef.sourceStart, nameRef.sourceEnd);
+	}
+}
+public void checkComment() {
+	// discard obsolete comments while inside methods or fields initializer (see bug 74369)
+	if (!(this.diet && this.dietInt==0) && this.scanner.commentPtr >= 0) {
+		flushCommentsDefinedPriorTo(this.endStatementPosition);
+	}
+
+	int lastComment = this.scanner.commentPtr;
+
+	if (this.modifiersSourceStart >= 0) {
+		// eliminate comments located after modifierSourceStart if positionned
+		while (lastComment >= 0) {
+			int commentSourceStart = this.scanner.commentStarts[lastComment];
+			if (commentSourceStart < 0) commentSourceStart = -commentSourceStart;
+			if (commentSourceStart <= this.modifiersSourceStart) break;
+			lastComment--;
+		}
+	}
+	if (lastComment >= 0) {
+		// consider all remaining leading comments to be part of current declaration
+		this.modifiersSourceStart = this.scanner.commentStarts[0];
+		if (this.modifiersSourceStart < 0) this.modifiersSourceStart = -this.modifiersSourceStart;
+
+		// check deprecation in last comment if javadoc (can be followed by non-javadoc comments which are simply ignored)
+		while (lastComment >= 0 && this.scanner.commentStops[lastComment] < 0) lastComment--; // non javadoc comment have negative end positions
+		if (lastComment >= 0 && this.javadocParser != null) {
+			int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over
+			// do not report problem before last parsed comment while recovering code...
+			if (this.javadocParser.shouldReportProblems) {
+				this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
+			} else {
+				this.javadocParser.reportProblems = false;
+			}
+			if (this.javadocParser.checkDeprecation(lastComment)) {
+				checkAndSetModifiers(ClassFileConstants.AccDeprecated);
+			}
+			this.javadoc = this.javadocParser.docComment;	// null if check javadoc is not activated
+			if (this.currentElement == null) this.lastJavadocEnd = commentEnd;
+		}
+	}
+
+	if (this.reportReferenceInfo && this.javadocParser.checkDocComment && this.javadoc != null) {
+		// Report reference info in javadoc comment @throws/@exception tags
+		TypeReference[] thrownExceptions = this.javadoc.exceptionReferences;
+		if (thrownExceptions != null) {
+			for (int i = 0, max=thrownExceptions.length; i < max; i++) {
+				TypeReference typeRef = thrownExceptions[i];
+				if (typeRef instanceof JavadocSingleTypeReference) {
+					JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef;
+					this.requestor.acceptTypeReference(singleRef.token, singleRef.sourceStart);
+				} else if (typeRef instanceof JavadocQualifiedTypeReference) {
+					JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) typeRef;
+					this.requestor.acceptTypeReference(qualifiedRef.tokens, qualifiedRef.sourceStart, qualifiedRef.sourceEnd);
+				}
+			}
+		}
+
+		// Report reference info in javadoc comment @see tags
+		Expression[] references = this.javadoc.seeReferences;
+		if (references != null) {
+			for (int i = 0, max=references.length; i < max; i++) {
+				Expression reference = references[i];
+				acceptJavadocTypeReference(reference);
+				if (reference instanceof JavadocFieldReference) {
+					JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
+					this.requestor.acceptFieldReference(fieldRef.token, fieldRef.sourceStart);
+					if (fieldRef.receiver != null && !fieldRef.receiver.isThis()) {
+						acceptJavadocTypeReference(fieldRef.receiver);
+					}
+				} else if (reference instanceof JavadocMessageSend) {
+					JavadocMessageSend messageSend = (JavadocMessageSend) reference;
+					int argCount = messageSend.arguments == null ? 0 : messageSend.arguments.length;
+					this.requestor.acceptMethodReference(messageSend.selector, argCount, messageSend.sourceStart);
+					this.requestor.acceptConstructorReference(messageSend.selector, argCount, messageSend.sourceStart);
+					if (messageSend.receiver != null && !messageSend.receiver.isThis()) {
+						acceptJavadocTypeReference(messageSend.receiver);
+					}
+				} else if (reference instanceof JavadocAllocationExpression) {
+					JavadocAllocationExpression constructor = (JavadocAllocationExpression) reference;
+					int argCount = constructor.arguments == null ? 0 : constructor.arguments.length;
+					if (constructor.type != null) {
+						char[][] compoundName = constructor.type.getParameterizedTypeName();
+						this.requestor.acceptConstructorReference(compoundName[compoundName.length-1], argCount, constructor.sourceStart);
+						if (!constructor.type.isThis()) {
+							acceptJavadocTypeReference(constructor.type);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+protected void classInstanceCreation(boolean alwaysQualified) {
+
+	boolean previousFlag = this.reportReferenceInfo;
+	this.reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
+	super.classInstanceCreation(alwaysQualified);
+	this.reportReferenceInfo = previousFlag;
+	if (this.reportReferenceInfo){
+		AllocationExpression alloc = (AllocationExpression)this.expressionStack[this.expressionPtr];
+		TypeReference typeRef = alloc.type;
+		this.requestor.acceptConstructorReference(
+			typeRef instanceof SingleTypeReference
+				? ((SingleTypeReference) typeRef).token
+				: CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
+			alloc.arguments == null ? 0 : alloc.arguments.length,
+			alloc.sourceStart);
+	}
+}
+protected void consumeAnnotationAsModifier() {
+	super.consumeAnnotationAsModifier();
+	Annotation annotation = (Annotation)this.expressionStack[this.expressionPtr];
+	if (this.reportReferenceInfo) { // accept annotation type reference
+		this.requestor.acceptAnnotationTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
+	}
+}
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	boolean previousFlag = this.reportReferenceInfo;
+	this.reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
+	super.consumeClassInstanceCreationExpressionQualifiedWithTypeArguments();
+	this.reportReferenceInfo = previousFlag;
+	if (this.reportReferenceInfo){
+		AllocationExpression alloc = (AllocationExpression)this.expressionStack[this.expressionPtr];
+		TypeReference typeRef = alloc.type;
+		this.requestor.acceptConstructorReference(
+			typeRef instanceof SingleTypeReference
+				? ((SingleTypeReference) typeRef).token
+				: CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
+			alloc.arguments == null ? 0 : alloc.arguments.length,
+			alloc.sourceStart);
+	}
+}
+protected void consumeAnnotationTypeDeclarationHeaderName() {
+	int currentAstPtr = this.astPtr;
+	super.consumeAnnotationTypeDeclarationHeaderName();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() {
+	int currentAstPtr = this.astPtr;
+	super.consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeCatchFormalParameter() {
+	super.consumeCatchFormalParameter();
+
+	// Flush comments prior to this formal parameter so the declarationSourceStart of the following parameter
+	// is correctly set (see bug 80904)
+	// Note that this could be done in the Parser itself, but this would slow down all parsers, when they don't need
+	// the declarationSourceStart to be set
+	flushCommentsDefinedPriorTo(this.scanner.currentPosition);
+}
+protected void consumeClassHeaderName1() {
+	int currentAstPtr = this.astPtr;
+	super.consumeClassHeaderName1();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	boolean previousFlag = this.reportReferenceInfo;
+	this.reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	this.reportReferenceInfo = previousFlag;
+	if (this.reportReferenceInfo){
+		AllocationExpression alloc = (AllocationExpression)this.expressionStack[this.expressionPtr];
+		TypeReference typeRef = alloc.type;
+		this.requestor.acceptConstructorReference(
+			typeRef instanceof SingleTypeReference
+				? ((SingleTypeReference) typeRef).token
+				: CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
+			alloc.arguments == null ? 0 : alloc.arguments.length,
+			alloc.sourceStart);
+	}
+}
+protected void consumeConstructorHeaderName() {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	super.consumeConstructorHeaderName();
+	if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+		rememberCategories();
+	}
+}
+protected void consumeConstructorHeaderNameWithTypeParameters() {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	super.consumeConstructorHeaderNameWithTypeParameters();
+	if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+		rememberCategories();
+	}
+}
+protected void consumeEnumConstantWithClassBody() {
+	super.consumeEnumConstantWithClassBody();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		rememberCategories();
+	}
+}
+protected void consumeEnumConstantNoClassBody() {
+	super.consumeEnumConstantNoClassBody();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		rememberCategories();
+	}
+}
+protected void consumeEnumHeaderName() {
+	int currentAstPtr = this.astPtr;
+	super.consumeEnumHeaderName();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeEnumHeaderNameWithTypeParameters() {
+	int currentAstPtr = this.astPtr;
+	super.consumeEnumHeaderNameWithTypeParameters();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeExitVariableWithInitialization() {
+	// ExitVariableWithInitialization ::= $empty
+	// the scanner is located after the comma or the semi-colon.
+	// we want to include the comma or the semi-colon
+	super.consumeExitVariableWithInitialization();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		rememberCategories();
+	}
+}
+protected void consumeExitVariableWithoutInitialization() {
+	// ExitVariableWithoutInitialization ::= $empty
+	// do nothing by default
+	super.consumeExitVariableWithoutInitialization();
+	if ((this.currentToken == TokenNameCOMMA || this.currentToken == TokenNameSEMICOLON)
+			&& this.astStack[this.astPtr] instanceof FieldDeclaration) {
+		this.sourceEnds.put(this.astStack[this.astPtr], this.scanner.currentPosition - 1);
+		rememberCategories();
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	// FieldAccess ::= Primary '.' 'Identifier'
+	// FieldAccess ::= 'super' '.' 'Identifier'
+	super.consumeFieldAccess(isSuperAccess);
+	FieldReference fr = (FieldReference) this.expressionStack[this.expressionPtr];
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptFieldReference(fr.token, fr.sourceStart);
+	}
+}
+protected void consumeFormalParameter(boolean isVarArgs) {
+	super.consumeFormalParameter(isVarArgs);
+
+	// Flush comments prior to this formal parameter so the declarationSourceStart of the following parameter
+	// is correctly set (see bug 80904)
+	// Note that this could be done in the Parser itself, but this would slow down all parsers, when they don't need
+	// the declarationSourceStart to be set
+	flushCommentsDefinedPriorTo(this.scanner.currentPosition);
+}
+protected void consumeInterfaceHeaderName1() {
+	int currentAstPtr = this.astPtr;
+	super.consumeInterfaceHeaderName1();
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		rememberCategories();
+}
+protected void consumeMemberValuePair() {
+	super.consumeMemberValuePair();
+	MemberValuePair memberValuepair = (MemberValuePair) this.astStack[this.astPtr];
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(memberValuepair.name, 0, memberValuepair.sourceStart);
+	}
+}
+protected void consumeMarkerAnnotation(boolean isTypeAnnotation) {
+	super.consumeMarkerAnnotation(isTypeAnnotation);
+	Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+	if (this.reportReferenceInfo) { // accept annotation type reference
+		this.requestor.acceptAnnotationTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
+	}
+}
+protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	super.consumeMethodHeaderName(isAnnotationMethod);
+	if (this.astPtr > currentAstPtr) { // if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+		rememberCategories();
+	}
+}
+
+protected void consumeMethodHeaderNameWithTypeParameters(boolean isAnnotationMethod) {
+	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
+	int selectorSourceEnd = (int) selectorSourcePositions;
+	int currentAstPtr = this.astPtr;
+	super.consumeMethodHeaderNameWithTypeParameters(isAnnotationMethod);
+	if (this.astPtr > currentAstPtr) // if ast node was pushed on the ast stack
+		this.sourceEnds.put(this.astStack[this.astPtr], selectorSourceEnd);
+		rememberCategories();
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodInvocationName() {
+	// MethodInvocation ::= Name '(' ArgumentListopt ')'
+	super.consumeMethodInvocationName();
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	// MethodInvocation ::= Name '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+	super.consumeMethodInvocationNameWithTypeArguments();
+
+	// when the name is only an identifier...we have a message send to "this" (implicit)
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodInvocationPrimary() {
+	super.consumeMethodInvocationPrimary();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+	super.consumeMethodInvocationPrimaryWithTypeArguments();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+/*
+ *
+ * INTERNAL USE-ONLY
+ */
+protected void consumeMethodInvocationSuper() {
+	// MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')'
+	super.consumeMethodInvocationSuper();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	// MethodInvocation ::= 'super' '.' TypeArguments 'Identifier' '(' ArgumentListopt ')'
+	super.consumeMethodInvocationSuperWithTypeArguments();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	Expression[] args = messageSend.arguments;
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(
+			messageSend.selector,
+			args == null ? 0 : args.length,
+			(int)(messageSend.nameSourcePosition >>> 32));
+	}
+}
+protected void consumeNormalAnnotation(boolean isTypeAnnotation) {
+	super.consumeNormalAnnotation(isTypeAnnotation);
+	Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+	if (this.reportReferenceInfo) { // accept annotation type reference
+		this.requestor.acceptAnnotationTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
+	}
+}
+protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) {
+	super.consumeSingleMemberAnnotation(isTypeAnnotation);
+	SingleMemberAnnotation member = (SingleMemberAnnotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptMethodReference(TypeConstants.VALUE, 0, member.sourceStart);
+	}
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' 'static' Name
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = newImportReference(tokens, positions, false, ClassFileConstants.AccStatic));
+
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
+		problemReporter().invalidUsageOfStaticImports(impt);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	if (this.reportReferenceInfo) {
+		// Name for static import is TypeName '.' Identifier
+		// => accept unknown ref on identifier
+		int tokensLength = impt.tokens.length-1;
+		int start = (int) (impt.sourcePositions[tokensLength] >>> 32);
+		char[] last = impt.tokens[tokensLength];
+		// accept all possible kind for last name, index users will have to select the right one...
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=86901
+		this.requestor.acceptFieldReference(last, start);
+		this.requestor.acceptMethodReference(last, 0,start);
+		this.requestor.acceptTypeReference(last, start);
+		// accept type name
+		if (tokensLength > 0) {
+			char[][] compoundName = new char[tokensLength][];
+			System.arraycopy(impt.tokens, 0, compoundName, 0, tokensLength);
+			int end = (int) impt.sourcePositions[tokensLength-1];
+			this.requestor.acceptTypeReference(compoundName, impt.sourceStart, end);
+		}
+	}
+}
+
+protected void consumeSingleTypeImportDeclarationName() {
+	// SingleTypeImportDeclarationName ::= 'import' Name
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = newImportReference(tokens, positions, false, ClassFileConstants.AccDefault));
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
+	}
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' 'static' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccStatic));
+
+	// star end position
+	impt.trailingStarPosition = this.intStack[this.intPtr--];
+	this.modifiers = ClassFileConstants.AccDefault;
+	this.modifiersSourceStart = -1; // <-- see comment into modifiersFlag(int)
+
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	if(!this.statementRecoveryActivated &&
+			this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
+			this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
+		impt.modifiers = ClassFileConstants.AccDefault; // convert the static import reference to a non-static importe reference
+		problemReporter().invalidUsageOfStaticImports(impt);
+	}
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptTypeReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
+	}
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
+	/* push an ImportRef build from the last name
+	stored in the identifier stack. */
+
+	ImportReference impt;
+	int length;
+	char[][] tokens = new char[length = this.identifierLengthStack[this.identifierLengthPtr--]][];
+	this.identifierPtr -= length;
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	pushOnAstStack(impt = new ImportReference(tokens, positions, true, ClassFileConstants.AccDefault));
+
+	// star end position
+	impt.trailingStarPosition = this.intStack[this.intPtr--];
+	if (this.currentToken == TokenNameSEMICOLON){
+		impt.declarationSourceEnd = this.scanner.currentPosition - 1;
+	} else {
+		impt.declarationSourceEnd = impt.sourceEnd;
+	}
+	impt.declarationEnd = impt.declarationSourceEnd;
+	//this.endPosition is just before the ;
+	impt.declarationSourceStart = this.intStack[this.intPtr--];
+
+	// recovery
+	if (this.currentElement != null){
+		this.lastCheckPoint = impt.declarationSourceEnd+1;
+		this.currentElement = this.currentElement.add(impt, 0);
+		this.lastIgnoredToken = -1;
+		this.restartRecovery = true; // used to avoid branching back into the regular automaton
+	}
+	if (this.reportReferenceInfo) {
+		this.requestor.acceptUnknownReference(impt.tokens, impt.sourceStart, impt.sourceEnd);
+	}
+}
+public MethodDeclaration convertToMethodDeclaration(ConstructorDeclaration c, CompilationResult compilationResult) {
+	MethodDeclaration methodDeclaration = super.convertToMethodDeclaration(c, compilationResult);
+	int selectorSourceEnd = this.sourceEnds.removeKey(c);
+	if (selectorSourceEnd != -1)
+		this.sourceEnds.put(methodDeclaration, selectorSourceEnd);
+	char[][] categories =  (char[][]) this.nodesToCategories.remove(c);
+	if (categories != null)
+		this.nodesToCategories.put(methodDeclaration, categories);
+
+	return methodDeclaration;
+}
+protected CompilationUnitDeclaration endParse(int act) {
+	if (this.scanner.recordLineSeparator) {
+		this.requestor.acceptLineSeparatorPositions(this.scanner.getLineEnds());
+	}
+	if (this.compilationUnit != null) {
+		CompilationUnitDeclaration result = super.endParse(act);
+		return result;
+	} else {
+		return null;
+	}
+}
+public TypeReference getTypeReference(int dim) {
+	/* build a Reference on a variable that may be qualified or not
+	 * This variable is a type reference and dim will be its dimensions
+	 */
+	Annotation [][] annotationsOnDimensions = null;
+	TypeReference ref;
+	int length = this.identifierLengthStack[this.identifierLengthPtr--];
+	if (length < 0) { //flag for precompiled type reference on base types
+		annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+		ref = TypeReference.baseTypeReference(-length, dim, annotationsOnDimensions);
+		ref.sourceStart = this.intStack[this.intPtr--];
+		if (dim == 0) {
+			ref.sourceEnd = this.intStack[this.intPtr--];
+		} else {
+			this.intPtr--; // no need to use this position as it is an array
+			ref.sourceEnd = this.endPosition;
+		}
+		if (this.reportReferenceInfo){
+				this.requestor.acceptTypeReference(ref.getParameterizedTypeName(), ref.sourceStart, ref.sourceEnd);
+		}
+	} else {
+		int numberOfIdentifiers = this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr--];
+		if (length != numberOfIdentifiers || this.genericsLengthStack[this.genericsLengthPtr] != 0) {
+			// generic type
+			ref = getTypeReferenceForGenericType(dim, length, numberOfIdentifiers);
+			if (this.reportReferenceInfo) {
+				if (length == 1 && numberOfIdentifiers == 1) {
+					ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) ref;
+					this.requestor.acceptTypeReference(parameterizedSingleTypeReference.token, parameterizedSingleTypeReference.sourceStart);
+				} else {
+					ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference = (ParameterizedQualifiedTypeReference) ref;
+					this.requestor.acceptTypeReference(parameterizedQualifiedTypeReference.tokens, parameterizedQualifiedTypeReference.sourceStart, parameterizedQualifiedTypeReference.sourceEnd);
+				}
+			}
+		} else if (length == 1) {
+			// single type reference
+			this.genericsLengthPtr--; // pop the 0
+			if (dim == 0) {
+				ref =
+					new SingleTypeReference(
+						this.identifierStack[this.identifierPtr],
+						this.identifierPositionStack[this.identifierPtr--]);
+				if (this.reportReferenceInfo) {
+					this.requestor.acceptTypeReference(((SingleTypeReference)ref).token, ref.sourceStart);
+				}
+			} else {
+				annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+				ref =
+					new ArrayTypeReference(
+						this.identifierStack[this.identifierPtr],
+						dim,
+						annotationsOnDimensions,
+						this.identifierPositionStack[this.identifierPtr--]);
+				ref.sourceEnd = this.endPosition;
+				if (annotationsOnDimensions != null) {
+					ref.bits |= ASTNode.HasTypeAnnotations;
+				}
+				if (this.reportReferenceInfo) {
+					this.requestor.acceptTypeReference(((ArrayTypeReference)ref).token, ref.sourceStart);
+				}
+			}
+		} else { // Qualified type reference
+			this.genericsLengthPtr--;
+			char[][] tokens = new char[length][];
+			this.identifierPtr -= length;
+			long[] positions = new long[length];
+			System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+			System.arraycopy(
+				this.identifierPositionStack,
+				this.identifierPtr + 1,
+				positions,
+				0,
+				length);
+			if (dim == 0) {
+				ref = new QualifiedTypeReference(tokens, positions);
+				if (this.reportReferenceInfo) {
+					this.requestor.acceptTypeReference(((QualifiedTypeReference)ref).tokens, ref.sourceStart, ref.sourceEnd);
+				}
+			} else {
+				annotationsOnDimensions = getAnnotationsOnDimensions(dim);
+				ref =
+					new ArrayQualifiedTypeReference(tokens, dim, annotationsOnDimensions, positions);
+				ref.sourceEnd = this.endPosition;
+				if (annotationsOnDimensions != null) {
+					ref.bits |= ASTNode.HasTypeAnnotations;
+				}
+				if (this.reportReferenceInfo) {
+					this.requestor.acceptTypeReference(((ArrayQualifiedTypeReference)ref).tokens, ref.sourceStart, ref.sourceEnd);
+				}
+			}
+		}
+	}
+	int levels = ref.getAnnotatableLevels();
+	for (int i = levels - 1; i >= 0; i--) {
+		if ((length = this.typeAnnotationLengthStack[this.typeAnnotationLengthPtr--]) != 0) {
+			if (ref.annotations == null)
+				ref.annotations = new Annotation[levels][];
+			System.arraycopy(
+					this.typeAnnotationStack,
+					(this.typeAnnotationPtr -= length) + 1,
+					ref.annotations[i] = new Annotation[length],
+					0,
+					length);
+			if (i == 0) {
+				ref.sourceStart = ref.annotations[0][0].sourceStart;
+			}
+			ref.bits |= ASTNode.HasTypeAnnotations;
+		}
+	}
+	return ref;
+}
+public NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	/* build a (unspecified) NameReference which may be qualified*/
+    if (rejectTypeAnnotations) {
+    	consumeNonTypeUseName();
+    }
+	int length;
+	if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+		// single variable reference
+		SingleNameReference ref =
+			newSingleNameReference(
+				this.identifierStack[this.identifierPtr],
+				this.identifierPositionStack[this.identifierPtr--]);
+		if (this.reportReferenceInfo) {
+			addUnknownRef(ref);
+		}
+		return ref;
+	} else {
+		//Qualified variable reference
+		char[][] tokens = new char[length][];
+		this.identifierPtr -= length;
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+		long[] positions = new long[length];
+		System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+		QualifiedNameReference ref =
+			newQualifiedNameReference(
+				tokens,
+				positions,
+				(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+				(int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
+		if (this.reportReferenceInfo) {
+			addUnknownRef(ref);
+		}
+		return ref;
+	}
+}
+public NameReference getUnspecifiedReferenceOptimized() {
+	/* build a (unspecified) NameReference which may be qualified
+	The optimization occurs for qualified reference while we are
+	certain in this case the last item of the qualified name is
+	a field access. This optimization is IMPORTANT while it results
+	that when a NameReference is build, the type checker should always
+	look for that it is not a type reference */
+	consumeNonTypeUseName();
+	int length;
+	if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+		// single variable reference
+		SingleNameReference ref =
+			newSingleNameReference(
+				this.identifierStack[this.identifierPtr],
+				this.identifierPositionStack[this.identifierPtr--]);
+		ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+		ref.bits |= Binding.LOCAL | Binding.FIELD;
+		if (this.reportReferenceInfo) {
+			addUnknownRef(ref);
+		}
+		return ref;
+	}
+
+	//Qualified-variable-reference
+	//In fact it is variable-reference DOT field-ref , but it would result in a type
+	//conflict tha can be only reduce by making a superclass (or inetrface ) between
+	//nameReference and FiledReference or putting FieldReference under NameReference
+	//or else..........This optimisation is not really relevant so just leave as it is
+
+	char[][] tokens = new char[length][];
+	this.identifierPtr -= length;
+	System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+	long[] positions = new long[length];
+	System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+	QualifiedNameReference ref =
+		newQualifiedNameReference(
+			tokens,
+			positions,
+			(int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32),
+	// sourceStart
+	 (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
+	ref.bits &= ~ASTNode.RestrictiveFlagMASK;
+	ref.bits |= Binding.LOCAL | Binding.FIELD;
+	if (this.reportReferenceInfo) {
+		addUnknownRef(ref);
+	}
+	return ref;
+}
+protected ImportReference newImportReference(char[][] tokens, long[] positions, boolean onDemand, int mod) {
+	return new ImportReference(tokens, positions, onDemand, mod);
+}
+protected QualifiedNameReference newQualifiedNameReference(char[][] tokens, long[] positions, int sourceStart, int sourceEnd) {
+	return new QualifiedNameReference(tokens, positions, sourceStart, sourceEnd);
+}
+protected SingleNameReference newSingleNameReference(char[] source, long positions) {
+	return new SingleNameReference(source, positions);
+}
+public CompilationUnitDeclaration parseCompilationUnit(
+	ICompilationUnit unit,
+	boolean fullParse,
+	IProgressMonitor pm) {
+
+	boolean old = this.diet;
+	CompilationUnitDeclaration parsedUnit = null;
+	try {
+		this.diet = true;
+		this.reportReferenceInfo = fullParse;
+		CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
+		parsedUnit = parse(unit, compilationUnitResult);
+		if (pm != null && pm.isCanceled())
+			throw new OperationCanceledException(Messages.operation_cancelled);
+		if (this.scanner.recordLineSeparator) {
+			this.requestor.acceptLineSeparatorPositions(compilationUnitResult.getLineSeparatorPositions());
+		}
+		int initialStart = this.scanner.initialPosition;
+		int initialEnd = this.scanner.eofPosition;
+		if (this.reportLocalDeclarations || fullParse){
+			this.diet = false;
+			getMethodBodies(parsedUnit);
+		}
+		this.scanner.resetTo(initialStart, initialEnd);
+		this.notifier.notifySourceElementRequestor(
+				parsedUnit,
+				this.scanner.initialPosition,
+				this.scanner.eofPosition,
+				this.reportReferenceInfo,
+				this.sourceEnds,
+				this.nodesToCategories);
+		return parsedUnit;
+	} catch (AbortCompilation e) {
+		// ignore this exception
+	} finally {
+		this.diet = old;
+		reset();
+	}
+	return parsedUnit;
+}
+private void rememberCategories() {
+	if (this.useSourceJavadocParser) {
+		SourceJavadocParser sourceJavadocParser = (SourceJavadocParser) this.javadocParser;
+		char[][] categories =  sourceJavadocParser.categories;
+		if (categories.length > 0) {
+			this.nodesToCategories.put(this.astStack[this.astPtr], categories);
+			sourceJavadocParser.categories = CharOperation.NO_CHAR_CHAR;
+		}
+	}
+}
+private void reset() {
+	this.sourceEnds = new HashtableOfObjectToInt();
+	this.nodesToCategories = new HashMap();
+}
+public void setRequestor(ISourceElementRequestor requestor) {
+	this.requestor = requestor;
+	this.notifier.requestor = requestor;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
new file mode 100644
index 0000000..9e81daa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class SourceElementRequestorAdapter implements ISourceElementRequestor {
+
+	/**
+	 * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[][], int, int)
+	 */
+	public void acceptAnnotationTypeReference(
+		char[][] typeName,
+		int sourceStart,
+		int sourceEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[], int)
+	 */
+	public void acceptAnnotationTypeReference(char[] typeName, int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
+	 */
+	public void acceptConstructorReference(
+		char[] typeName,
+		int argCount,
+		int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptFieldReference(char[], int)
+	 */
+	public void acceptFieldReference(char[] fieldName, int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptImport(int, int, int, int, char[][], boolean, int)
+	 */
+	public void acceptImport(
+		int declarationStart,
+		int declarationEnd,
+		int nameStart,
+		int nameEnd,
+		char[][] tokens,
+		boolean onDemand,
+		int modifiers) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
+	 */
+	public void acceptLineSeparatorPositions(int[] positions) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptMethodReference(char[], int, int)
+	 */
+	public void acceptMethodReference(
+		char[] methodName,
+		int argCount,
+		int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptPackage(ImportReference)
+	 */
+	public void acceptPackage(ImportReference importReference) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptProblem(CategorizedProblem)
+	 */
+	public void acceptProblem(CategorizedProblem problem) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int)
+	 */
+	public void acceptTypeReference(
+		char[][] typeName,
+		int sourceStart,
+		int sourceEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptTypeReference(char[], int)
+	 */
+	public void acceptTypeReference(char[] typeName, int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int)
+	 */
+	public void acceptUnknownReference(
+		char[][] name,
+		int sourceStart,
+		int sourceEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#acceptUnknownReference(char[], int)
+	 */
+	public void acceptUnknownReference(char[] name, int sourcePosition) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#enterCompilationUnit()
+	 */
+	public void enterCompilationUnit() {
+		// default implementation: do nothing
+	}
+
+	public void enterConstructor(MethodInfo methodInfo) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#enterField(ISourceElementRequestor.FieldInfo)
+	 */
+	public void enterField(FieldInfo fieldInfo) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#enterInitializer(int, int)
+	 */
+	public void enterInitializer(int declarationStart, int modifiers) {
+		// default implementation: do nothing
+	}
+
+	public void enterMethod(MethodInfo methodInfo) {
+		// default implementation: do nothing
+	}
+
+	public void enterType(TypeInfo typeInfo) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitCompilationUnit(int)
+	 */
+	public void exitCompilationUnit(int declarationEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitConstructor(int)
+	 */
+	public void exitConstructor(int declarationEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitField(int, int, int)
+	 */
+	public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitInitializer(int)
+	 */
+	public void exitInitializer(int declarationEnd) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitMethod(int, Expression)
+	 */
+	public void exitMethod(int declarationEnd, Expression defaultValue) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor#exitType(int)
+	 */
+	public void exitType(int declarationEnd) {
+		// default implementation: do nothing
+	}
+
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java
new file mode 100644
index 0000000..00461e7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceJavadocParser.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+
+public class SourceJavadocParser extends JavadocParser {
+
+	// Store categories identifiers parsed in javadoc
+	int categoriesPtr = -1;
+	char[][] categories = CharOperation.NO_CHAR_CHAR;
+
+public SourceJavadocParser(Parser sourceParser) {
+	super(sourceParser);
+	this.kind = SOURCE_PARSER | TEXT_VERIF;
+}
+
+public boolean checkDeprecation(int commentPtr) {
+	this.categoriesPtr = -1;
+	boolean result = super.checkDeprecation(commentPtr);
+	if (this.categoriesPtr > -1) {
+		System.arraycopy(this.categories, 0, this.categories = new char[this.categoriesPtr+1][], 0, this.categoriesPtr+1);
+	} else {
+		this.categories = CharOperation.NO_CHAR_CHAR;
+	}
+	return result;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseIdentifierTag()
+ */
+protected boolean parseIdentifierTag(boolean report) {
+	int end = this.lineEnd+1;
+	if (super.parseIdentifierTag(report) && this.index <= end) {
+		if (this.tagValue == TAG_CATEGORY_VALUE) {
+			// Store first category id
+			int length = this.categories.length;
+			if (++this.categoriesPtr >= length) {
+				System.arraycopy(this.categories, 0, this.categories = new char[length+5][], 0, length);
+				length += 5;
+			}
+			this.categories[this.categoriesPtr] = this.identifierStack[this.identifierPtr--];
+			// Store optional additional category identifiers
+			consumeToken();
+			while (this.index < end) {
+				if (readTokenSafely() == TerminalTokens.TokenNameIdentifier && (this.scanner.currentCharacter == ' ' || ScannerHelper.isWhitespace(this.scanner.currentCharacter))) {
+					if (this.index > (this.lineEnd+1)) break;
+					// valid additional identifier
+					if (++this.categoriesPtr >= length) {
+						System.arraycopy(this.categories, 0, this.categories = new char[length+5][], 0, length);
+						length += 5;
+					}
+					this.categories[this.categoriesPtr] = this.scanner.getCurrentIdentifierSource();
+					consumeToken();
+				} else {
+					// TODO (frederic) raise warning for invalid syntax when javadoc spec will be finalized...
+					break;
+				}
+			}
+			// Reset position to end of line
+			this.index = end;
+			this.scanner.currentPosition = end;
+			consumeToken();
+		}
+		return true;
+	}
+	return false;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseSimpleTag()
+ */
+protected void parseSimpleTag() {
+
+	// Read first char
+	// readChar() code is inlined to balance additional method call in checkDeprectation(int)
+	char first = this.source[this.index++];
+	if (first == '\\' && this.source[this.index] == 'u') {
+		int c1, c2, c3, c4;
+		int pos = this.index;
+		this.index++;
+		while (this.source[this.index] == 'u')
+			this.index++;
+		if (!(((c1 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c1 < 0)
+				|| ((c2 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c2 < 0)
+				|| ((c3 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c3 < 0)
+				|| ((c4 = ScannerHelper.getHexadecimalValue(this.source[this.index++])) > 15 || c4 < 0))) {
+			first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+		} else {
+			this.index = pos;
+		}
+	}
+
+	// switch on first tag char
+	switch (first) {
+		case 'd': // perhaps @deprecated tag?
+	        if ((readChar() == 'e') &&
+					(readChar() == 'p') && (readChar() == 'r') &&
+					(readChar() == 'e') && (readChar() == 'c') &&
+					(readChar() == 'a') && (readChar() == 't') &&
+					(readChar() == 'e') && (readChar() == 'd')) {
+				// ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
+				char c = readChar();
+				if (ScannerHelper.isWhitespace(c) || c == '*') {
+					this.tagValue = TAG_DEPRECATED_VALUE;
+					this.deprecated = true;
+				}
+	        }
+			break;
+		case 'c': // perhaps @category tag?
+	        if ((readChar() == 'a') &&
+					(readChar() == 't') && (readChar() == 'e') &&
+					(readChar() == 'g') && (readChar() == 'o') &&
+					(readChar() == 'r') && (readChar() == 'y')) {
+				// ensure the tag is properly ended: either followed by a space, a tab, line end or asterisk.
+				char c = readChar();
+				if (ScannerHelper.isWhitespace(c) || c == '*') {
+					this.tagValue = TAG_CATEGORY_VALUE;
+					if (this.scanner.source == null) {
+						this.scanner.setSource(this.source);
+					}
+					this.scanner.resetTo(this.index, this.scanner.eofPosition);
+					parseIdentifierTag(false); // Do not report missing identifier
+				}
+	        }
+			break;
+	}
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
new file mode 100644
index 0000000..ffae433
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
@@ -0,0 +1,645 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     								Bug 320841 - TypeConverters don't set enclosingType
+ *     								Bug 353474 - type converters should include more annotations
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+/**
+ * Converter from source element type to parsed compilation unit.
+ *
+ * Limitation:
+ * | The source element field does not carry any information for its constant part, thus
+ * | the converted parse tree will not include any field initializations.
+ * | Therefore, any binary produced by compiling against converted source elements will
+ * | not take advantage of remote field constant inlining.
+ * | Given the intended purpose of the conversion is to resolve references, this is not
+ * | a problem.
+ *
+ */
+
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.*;
+
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class SourceTypeConverter extends TypeConverter {
+
+	/*
+	 * Exception thrown while converting an anonymous type of a member type
+	 * in this case, we must parse the source as the enclosing instance cannot be recreated
+	 * from the model
+	 */
+	static class AnonymousMemberFound extends RuntimeException {
+		private static final long serialVersionUID = 1L;
+	}
+
+	public static final int FIELD = 0x01;
+	public static final int CONSTRUCTOR = 0x02;
+	public static final int METHOD = 0x04;
+	public static final int MEMBER_TYPE = 0x08;
+	public static final int FIELD_INITIALIZATION = 0x10;
+	public static final int FIELD_AND_METHOD = FIELD | CONSTRUCTOR | METHOD;
+	public static final int LOCAL_TYPE = 0x20;
+	public static final int NONE = 0;
+
+	private int flags;
+	private CompilationUnitDeclaration unit;
+	private Parser parser;
+	private ICompilationUnit cu;
+	private char[] source;
+
+	private SourceTypeConverter(int flags, ProblemReporter problemReporter) {
+		super(problemReporter, Signature.C_DOT);
+		this.flags = flags;
+	}
+
+	/*
+	 * Convert a set of source element types into a parsed compilation unit declaration
+	 * The argument types are then all grouped in the same unit. The argument types must
+	 * at least contain one type.
+	 * Can optionally ignore fields & methods or member types or field initialization
+	 */
+	public static CompilationUnitDeclaration buildCompilationUnit(
+		ISourceType[] sourceTypes,
+		int flags,
+		ProblemReporter problemReporter,
+		CompilationResult compilationResult) {
+
+//		long start = System.currentTimeMillis();
+		SourceTypeConverter converter = new SourceTypeConverter(flags, problemReporter);
+		try {
+			return converter.convert(sourceTypes, compilationResult);
+		} catch (JavaModelException e) {
+			return null;
+/*		} finally {
+			System.out.println("Spent " + (System.currentTimeMillis() - start) + "ms to convert " + ((JavaElement) converter.cu).toStringWithAncestors());
+*/		}
+	}
+
+	/*
+	 * Convert a set of source element types into a parsed compilation unit declaration
+	 * The argument types are then all grouped in the same unit. The argument types must
+	 * at least contain one type.
+	 */
+	private CompilationUnitDeclaration convert(ISourceType[] sourceTypes, CompilationResult compilationResult) throws JavaModelException {
+		this.unit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
+		// not filled at this point
+
+		if (sourceTypes.length == 0) return this.unit;
+		SourceTypeElementInfo topLevelTypeInfo = (SourceTypeElementInfo) sourceTypes[0];
+		org.eclipse.jdt.core.ICompilationUnit cuHandle = topLevelTypeInfo.getHandle().getCompilationUnit();
+		this.cu = (ICompilationUnit) cuHandle;
+
+		if (this.has1_5Compliance && ((CompilationUnitElementInfo) ((JavaElement) this.cu).getElementInfo()).annotationNumber > 10) { // experimental value
+			// If more than 10 annotations, diet parse as this is faster, but not if
+			// the client wants local and anonymous types to be converted (https://bugs.eclipse.org/bugs/show_bug.cgi?id=254738) 
+			if ((this.flags & LOCAL_TYPE) == 0) {
+				return new Parser(this.problemReporter, true).dietParse(this.cu, compilationResult);
+			}
+		}
+
+		/* only positions available */
+		int start = topLevelTypeInfo.getNameSourceStart();
+		int end = topLevelTypeInfo.getNameSourceEnd();
+
+		/* convert package and imports */
+		String[] packageName = ((PackageFragment) cuHandle.getParent()).names;
+		if (packageName.length > 0)
+			// if its null then it is defined in the default package
+			this.unit.currentPackage =
+				createImportReference(packageName, start, end, false, ClassFileConstants.AccDefault);
+		IImportDeclaration[] importDeclarations = topLevelTypeInfo.getHandle().getCompilationUnit().getImports();
+		int importCount = importDeclarations.length;
+		this.unit.imports = new ImportReference[importCount];
+		for (int i = 0; i < importCount; i++) {
+			ImportDeclaration importDeclaration = (ImportDeclaration) importDeclarations[i];
+			ISourceImport sourceImport = (ISourceImport) importDeclaration.getElementInfo();
+			String nameWithoutStar = importDeclaration.getNameWithoutStar();
+			this.unit.imports[i] = createImportReference(
+				Util.splitOn('.', nameWithoutStar, 0, nameWithoutStar.length()),
+				sourceImport.getDeclarationSourceStart(),
+				sourceImport.getDeclarationSourceEnd(),
+				importDeclaration.isOnDemand(),
+				sourceImport.getModifiers());
+		}
+		/* convert type(s) */
+		try {
+			int typeCount = sourceTypes.length;
+			final TypeDeclaration[] types = new TypeDeclaration[typeCount];
+			/*
+			 * We used a temporary types collection to prevent this.unit.types from being null during a call to
+			 * convert(...) when the source is syntactically incorrect and the parser is flushing the unit's types.
+			 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97466
+			 */
+			for (int i = 0; i < typeCount; i++) {
+				SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) sourceTypes[i];
+				types[i] = convert((SourceType) typeInfo.getHandle(), compilationResult);
+			}
+			this.unit.types = types;
+			return this.unit;
+		} catch (AnonymousMemberFound e) {
+			return new Parser(this.problemReporter, true).parse(this.cu, compilationResult);
+		}
+	}
+
+	/*
+	 * Convert an initializerinfo into a parsed initializer declaration
+	 */
+	private Initializer convert(InitializerElementInfo initializerInfo, CompilationResult compilationResult) throws JavaModelException {
+
+		Block block = new Block(0);
+		Initializer initializer = new Initializer(block, ClassFileConstants.AccDefault);
+
+		int start = initializerInfo.getDeclarationSourceStart();
+		int end = initializerInfo.getDeclarationSourceEnd();
+
+		initializer.sourceStart = initializer.declarationSourceStart = start;
+		initializer.sourceEnd = initializer.declarationSourceEnd = end;
+		initializer.modifiers = initializerInfo.getModifiers();
+
+		/* convert local and anonymous types */
+		IJavaElement[] children = initializerInfo.getChildren();
+		int typesLength = children.length;
+		if (typesLength > 0) {
+			Statement[] statements = new Statement[typesLength];
+			for (int i = 0; i < typesLength; i++) {
+				SourceType type = (SourceType) children[i];
+				TypeDeclaration localType = convert(type, compilationResult);
+				if ((localType.bits & ASTNode.IsAnonymousType) != 0) {
+					QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
+					expression.type = localType.superclass;
+					localType.superclass = null;
+					localType.superInterfaces = null;
+					localType.allocation = expression;
+					statements[i] = expression;
+				} else {
+					statements[i] = localType;
+				}
+			}
+			block.statements = statements;
+		}
+
+		return initializer;
+	}
+
+	/*
+	 * Convert a field source element into a parsed field declaration
+	 */
+	private FieldDeclaration convert(SourceField fieldHandle, TypeDeclaration type, CompilationResult compilationResult) throws JavaModelException {
+
+		SourceFieldElementInfo fieldInfo = (SourceFieldElementInfo) fieldHandle.getElementInfo();
+		FieldDeclaration field = new FieldDeclaration();
+
+		int start = fieldInfo.getNameSourceStart();
+		int end = fieldInfo.getNameSourceEnd();
+
+		field.name = fieldHandle.getElementName().toCharArray();
+		field.sourceStart = start;
+		field.sourceEnd = end;
+		field.declarationSourceStart = fieldInfo.getDeclarationSourceStart();
+		field.declarationSourceEnd = fieldInfo.getDeclarationSourceEnd();
+		int modifiers = fieldInfo.getModifiers();
+		boolean isEnumConstant = (modifiers & ClassFileConstants.AccEnum) != 0;
+		if (isEnumConstant) {
+			field.modifiers = modifiers & ~ClassFileConstants.AccEnum; // clear AccEnum bit onto AST (binding will add it)
+		} else {
+			field.modifiers = modifiers;
+			field.type = createTypeReference(fieldInfo.getTypeName(), start, end);
+		}
+
+		// convert 1.5 specific constructs only if compliance is 1.5 or above
+		if (this.has1_5Compliance) {
+			/* convert annotations */
+			field.annotations = convertAnnotations(fieldHandle);
+		}
+
+		/* conversion of field constant */
+		if ((this.flags & FIELD_INITIALIZATION) != 0) {
+			char[] initializationSource = fieldInfo.getInitializationSource();
+			if (initializationSource != null) {
+				if (this.parser == null) {
+					this.parser = new Parser(this.problemReporter, true);
+				}
+				this.parser.parse(field, type, this.unit, initializationSource);
+			}
+		}
+
+		/* conversion of local and anonymous types */
+		if ((this.flags & LOCAL_TYPE) != 0) {
+			IJavaElement[] children = fieldInfo.getChildren();
+			int childrenLength = children.length;
+			if (childrenLength == 1) {
+				field.initialization = convert(children[0], isEnumConstant ? field : null, compilationResult);
+			} else if (childrenLength > 1) {
+				ArrayInitializer initializer = new ArrayInitializer();
+				field.initialization = initializer;
+				Expression[] expressions = new Expression[childrenLength];
+				initializer.expressions = expressions;
+				for (int i = 0; i < childrenLength; i++) {
+					expressions[i] = convert(children[i], isEnumConstant ? field : null, compilationResult);
+				}
+			}
+		}
+		return field;
+	}
+
+	private QualifiedAllocationExpression convert(IJavaElement localType, FieldDeclaration enumConstant, CompilationResult compilationResult) throws JavaModelException {
+		TypeDeclaration anonymousLocalTypeDeclaration = convert((SourceType) localType, compilationResult);
+		QualifiedAllocationExpression expression = new QualifiedAllocationExpression(anonymousLocalTypeDeclaration);
+		expression.type = anonymousLocalTypeDeclaration.superclass;
+		anonymousLocalTypeDeclaration.superclass = null;
+		anonymousLocalTypeDeclaration.superInterfaces = null;
+		anonymousLocalTypeDeclaration.allocation = expression;
+		if (enumConstant != null) {
+			anonymousLocalTypeDeclaration.modifiers &= ~ClassFileConstants.AccEnum;
+			expression.enumConstant = enumConstant;
+			expression.type = null;
+		}
+		return expression;
+	}
+
+	/*
+	 * Convert a method source element into a parsed method/constructor declaration
+	 */
+	private AbstractMethodDeclaration convert(SourceMethod methodHandle, SourceMethodElementInfo methodInfo, CompilationResult compilationResult) throws JavaModelException {
+		AbstractMethodDeclaration method;
+
+		/* only source positions available */
+		int start = methodInfo.getNameSourceStart();
+		int end = methodInfo.getNameSourceEnd();
+
+		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Even when this type is being constructed
+		   on behalf of a 1.4 project we must internalize type variables properly in order to be able to
+		   recognize usages of them in the method signature, to apply substitutions and thus to be able to
+		   detect overriding in the presence of generics. If we simply drop them, when the method signature
+		   refers to the type parameter, we won't know it should be bound to the type parameter and perform
+		   incorrect lookup and may mistakenly end up with missing types
+		 */
+		TypeParameter[] typeParams = null;
+		char[][] typeParameterNames = methodInfo.getTypeParameterNames();
+		if (typeParameterNames != null) {
+			int parameterCount = typeParameterNames.length;
+			if (parameterCount > 0) { // method's type parameters must be null if no type parameter
+				char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
+				typeParams = new TypeParameter[parameterCount];
+				for (int i = 0; i < parameterCount; i++) {
+					typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+				}
+			}
+		}
+
+		int modifiers = methodInfo.getModifiers();
+		if (methodInfo.isConstructor()) {
+			ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
+			decl.bits &= ~ASTNode.IsDefaultConstructor;
+			method = decl;
+			decl.typeParameters = typeParams;
+		} else {
+			MethodDeclaration decl;
+			if (methodInfo.isAnnotationMethod()) {
+				AnnotationMethodDeclaration annotationMethodDeclaration = new AnnotationMethodDeclaration(compilationResult);
+
+				/* conversion of default value */
+				SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) methodInfo;
+				boolean hasDefaultValue = annotationMethodInfo.defaultValueStart != -1 || annotationMethodInfo.defaultValueEnd != -1;
+				if ((this.flags & FIELD_INITIALIZATION) != 0) {
+					if (hasDefaultValue) {
+						char[] defaultValueSource = CharOperation.subarray(getSource(), annotationMethodInfo.defaultValueStart, annotationMethodInfo.defaultValueEnd+1);
+						if (defaultValueSource != null) {
+    						Expression expression =  parseMemberValue(defaultValueSource);
+    						if (expression != null) {
+    							annotationMethodDeclaration.defaultValue = expression;
+    						}
+						} else {
+							// could not retrieve the default value
+							hasDefaultValue = false;
+						}
+					}
+				}
+				if (hasDefaultValue)
+					modifiers |= ClassFileConstants.AccAnnotationDefault;
+				decl = annotationMethodDeclaration;
+			} else {
+				decl = new MethodDeclaration(compilationResult);
+			}
+
+			// convert return type
+			decl.returnType = createTypeReference(methodInfo.getReturnTypeName(), start, end);
+
+			// type parameters
+			decl.typeParameters = typeParams;
+
+			method = decl;
+		}
+		method.selector = methodHandle.getElementName().toCharArray();
+		boolean isVarargs = (modifiers & ClassFileConstants.AccVarargs) != 0;
+		method.modifiers = modifiers & ~ClassFileConstants.AccVarargs;
+		method.sourceStart = start;
+		method.sourceEnd = end;
+		method.declarationSourceStart = methodInfo.getDeclarationSourceStart();
+		method.declarationSourceEnd = methodInfo.getDeclarationSourceEnd();
+
+		// convert 1.5 specific constructs only if compliance is 1.5 or above
+		if (this.has1_5Compliance) {
+			/* convert annotations */
+			method.annotations = convertAnnotations(methodHandle);
+		}
+
+		/* convert arguments */
+		String[] argumentTypeSignatures = methodHandle.getParameterTypes();
+		char[][] argumentNames = methodInfo.getArgumentNames();
+		int argumentCount = argumentTypeSignatures == null ? 0 : argumentTypeSignatures.length;
+		if (argumentCount > 0) {
+			ILocalVariable[] parameters = methodHandle.getParameters();
+			long position = ((long) start << 32) + end;
+			method.arguments = new Argument[argumentCount];
+			for (int i = 0; i < argumentCount; i++) {
+				TypeReference typeReference = createTypeReference(argumentTypeSignatures[i], start, end);
+				if (isVarargs && i == argumentCount-1) {
+					typeReference.bits |= ASTNode.IsVarArgs;
+				}
+				method.arguments[i] =
+					new Argument(
+						argumentNames[i],
+						position,
+						typeReference,
+						ClassFileConstants.AccDefault);
+				// do not care whether was final or not
+				// convert 1.5 specific constructs only if compliance is 1.5 or above
+				if (this.has1_5Compliance) {
+					/* convert annotations */
+					method.arguments[i].annotations = convertAnnotations(parameters[i]);
+				}
+			}
+		}
+
+		/* convert thrown exceptions */
+		char[][] exceptionTypeNames = methodInfo.getExceptionTypeNames();
+		int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
+		if (exceptionCount > 0) {
+			method.thrownExceptions = new TypeReference[exceptionCount];
+			for (int i = 0; i < exceptionCount; i++) {
+				method.thrownExceptions[i] =
+					createTypeReference(exceptionTypeNames[i], start, end);
+			}
+		}
+
+		/* convert local and anonymous types */
+		if ((this.flags & LOCAL_TYPE) != 0) {
+			IJavaElement[] children = methodInfo.getChildren();
+			int typesLength = children.length;
+			if (typesLength != 0) {
+				Statement[] statements = new Statement[typesLength];
+				for (int i = 0; i < typesLength; i++) {
+					SourceType type = (SourceType) children[i];
+					TypeDeclaration localType = convert(type, compilationResult);
+					if ((localType.bits & ASTNode.IsAnonymousType) != 0) {
+						QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
+						expression.type = localType.superclass;
+						localType.superclass = null;
+						localType.superInterfaces = null;
+						localType.allocation = expression;
+						statements[i] = expression;
+					} else {
+						statements[i] = localType;
+					}
+				}
+				method.statements = statements;
+			}
+		}
+
+		return method;
+	}
+
+	/*
+	 * Convert a source element type into a parsed type declaration
+	 */
+	private TypeDeclaration convert(SourceType typeHandle, CompilationResult compilationResult) throws JavaModelException {
+		SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) typeHandle.getElementInfo();
+		if (typeInfo.isAnonymousMember())
+			throw new AnonymousMemberFound();
+		/* create type declaration - can be member type */
+		TypeDeclaration type = new TypeDeclaration(compilationResult);
+		if (typeInfo.getEnclosingType() == null) {
+			if (typeHandle.isAnonymous()) {
+				type.name = CharOperation.NO_CHAR;
+				type.bits |= (ASTNode.IsAnonymousType|ASTNode.IsLocalType);
+			} else {
+				if (typeHandle.isLocal()) {
+					type.bits |= ASTNode.IsLocalType;
+				}
+			}
+		}  else {
+			type.bits |= ASTNode.IsMemberType;
+		}
+		if ((type.bits & ASTNode.IsAnonymousType) == 0) {
+			type.name = typeInfo.getName();
+		}
+		type.name = typeInfo.getName();
+		int start, end; // only positions available
+		type.sourceStart = start = typeInfo.getNameSourceStart();
+		type.sourceEnd = end = typeInfo.getNameSourceEnd();
+		type.modifiers = typeInfo.getModifiers();
+		type.declarationSourceStart = typeInfo.getDeclarationSourceStart();
+		type.declarationSourceEnd = typeInfo.getDeclarationSourceEnd();
+		type.bodyEnd = type.declarationSourceEnd;
+
+		// convert 1.5 specific constructs only if compliance is 1.5 or above
+		if (this.has1_5Compliance) {
+			/* convert annotations */
+			type.annotations = convertAnnotations(typeHandle);
+		}
+		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we
+		   must internalize type variables and observe any parameterization of super class
+		   and/or super interfaces in order to be able to detect overriding in the presence
+		   of generics.
+		 */
+		char[][] typeParameterNames = typeInfo.getTypeParameterNames();
+		if (typeParameterNames.length > 0) {
+			int parameterCount = typeParameterNames.length;
+			char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds();
+			type.typeParameters = new TypeParameter[parameterCount];
+			for (int i = 0; i < parameterCount; i++) {
+				type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+			}
+		}
+
+		/* set superclass and superinterfaces */
+		if (typeInfo.getSuperclassName() != null) {
+			type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end, true /* include generics */);
+			type.superclass.bits |= ASTNode.IsSuperType;
+		}
+		char[][] interfaceNames = typeInfo.getInterfaceNames();
+		int interfaceCount = interfaceNames == null ? 0 : interfaceNames.length;
+		if (interfaceCount > 0) {
+			type.superInterfaces = new TypeReference[interfaceCount];
+			for (int i = 0; i < interfaceCount; i++) {
+				type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end, true /* include generics */);
+				type.superInterfaces[i].bits |= ASTNode.IsSuperType;
+			}
+		}
+		/* convert member types */
+		if ((this.flags & MEMBER_TYPE) != 0) {
+			SourceType[] sourceMemberTypes = typeInfo.getMemberTypeHandles();
+			int sourceMemberTypeCount = sourceMemberTypes.length;
+			type.memberTypes = new TypeDeclaration[sourceMemberTypeCount];
+			for (int i = 0; i < sourceMemberTypeCount; i++) {
+				type.memberTypes[i] = convert(sourceMemberTypes[i], compilationResult);
+				type.memberTypes[i].enclosingType = type;
+			}
+		}
+
+		/* convert intializers and fields*/
+		InitializerElementInfo[] initializers = null;
+		int initializerCount = 0;
+		if ((this.flags & LOCAL_TYPE) != 0) {
+			initializers = typeInfo.getInitializers();
+			initializerCount = initializers.length;
+		}
+		SourceField[] sourceFields = null;
+		int sourceFieldCount = 0;
+		if ((this.flags & FIELD) != 0) {
+			sourceFields = typeInfo.getFieldHandles();
+			sourceFieldCount = sourceFields.length;
+		}
+		int length = initializerCount + sourceFieldCount;
+		if (length > 0) {
+			type.fields = new FieldDeclaration[length];
+			for (int i = 0; i < initializerCount; i++) {
+				type.fields[i] = convert(initializers[i], compilationResult);
+			}
+			int index = 0;
+			for (int i = initializerCount; i < length; i++) {
+				type.fields[i] = convert(sourceFields[index++], type, compilationResult);
+			}
+		}
+
+		/* convert methods - need to add default constructor if necessary */
+		boolean needConstructor = (this.flags & CONSTRUCTOR) != 0;
+		boolean needMethod = (this.flags & METHOD) != 0;
+		if (needConstructor || needMethod) {
+
+			SourceMethod[] sourceMethods = typeInfo.getMethodHandles();
+			int sourceMethodCount = sourceMethods.length;
+
+			/* source type has a constructor ?           */
+			/* by default, we assume that one is needed. */
+			int extraConstructor = 0;
+			int methodCount = 0;
+			int kind = TypeDeclaration.kind(type.modifiers);
+			boolean isAbstract = kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
+			if (!isAbstract) {
+				extraConstructor = needConstructor ? 1 : 0;
+				for (int i = 0; i < sourceMethodCount; i++) {
+					if (sourceMethods[i].isConstructor()) {
+						if (needConstructor) {
+							extraConstructor = 0; // Does not need the extra constructor since one constructor already exists.
+							methodCount++;
+						}
+					} else if (needMethod) {
+						methodCount++;
+					}
+				}
+			} else {
+				methodCount = needMethod ? sourceMethodCount : 0;
+			}
+			type.methods = new AbstractMethodDeclaration[methodCount + extraConstructor];
+			if (extraConstructor != 0) { // add default constructor in first position
+				type.methods[0] = type.createDefaultConstructor(false, false);
+			}
+			int index = 0;
+			boolean hasAbstractMethods = false;
+			for (int i = 0; i < sourceMethodCount; i++) {
+				SourceMethod sourceMethod = sourceMethods[i];
+				SourceMethodElementInfo methodInfo = (SourceMethodElementInfo)sourceMethod.getElementInfo();
+				boolean isConstructor = methodInfo.isConstructor();
+				if ((methodInfo.getModifiers() & ClassFileConstants.AccAbstract) != 0) {
+					hasAbstractMethods = true;
+				}
+				if ((isConstructor && needConstructor) || (!isConstructor && needMethod)) {
+					AbstractMethodDeclaration method = convert(sourceMethod, methodInfo, compilationResult);
+					if (isAbstract || method.isAbstract()) { // fix-up flag
+						method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+					}
+					type.methods[extraConstructor + index++] = method;
+				}
+			}
+			if (hasAbstractMethods) type.bits |= ASTNode.HasAbstractMethods;
+		}
+
+		return type;
+	}
+
+	private Annotation[] convertAnnotations(IAnnotatable element) throws JavaModelException {
+		IAnnotation[] annotations = element.getAnnotations();
+		int length = annotations.length;
+		Annotation[] astAnnotations = new Annotation[length];
+		if (length > 0) {
+			char[] cuSource = getSource();
+			int recordedAnnotations = 0;
+			for (int i = 0; i < length; i++) {
+				ISourceRange positions = annotations[i].getSourceRange();
+				int start = positions.getOffset();
+				int end = start + positions.getLength();
+				char[] annotationSource = CharOperation.subarray(cuSource, start, end);
+				if (annotationSource != null) {
+	    			Expression expression = parseMemberValue(annotationSource);
+	    			/*
+	    			 * expression can be null or not an annotation if the source has changed between
+	    			 * the moment where the annotation source positions have been retrieved and the moment were
+	    			 * this parsing occurred.
+	    			 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=90916
+	    			 */
+	    			if (expression instanceof Annotation) {
+	    				astAnnotations[recordedAnnotations++] = (Annotation) expression;
+	    			}
+				}
+			}
+			if (length != recordedAnnotations) {
+				// resize to remove null annotations
+				System.arraycopy(astAnnotations, 0, (astAnnotations = new Annotation[recordedAnnotations]), 0, recordedAnnotations);
+			}
+		}
+		return astAnnotations;
+	}
+
+	private char[] getSource() {
+		if (this.source == null)
+			this.source = this.cu.getContents();
+		return this.source;
+	}
+
+	private Expression parseMemberValue(char[] memberValue) {
+		// memberValue must not be null
+		if (this.parser == null) {
+			this.parser = new Parser(this.problemReporter, true);
+		}
+		return this.parser.parseMemberValue(memberValue, 0, memberValue.length, this.unit);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
new file mode 100644
index 0000000..27c1765
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java
@@ -0,0 +1,590 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+public abstract class TypeConverter {
+
+	int namePos;
+
+	protected ProblemReporter problemReporter;
+	protected boolean has1_5Compliance;
+	private char memberTypeSeparator;
+
+	protected TypeConverter(ProblemReporter problemReporter, char memberTypeSeparator) {
+		this.problemReporter = problemReporter;
+		this.has1_5Compliance = problemReporter.options.originalComplianceLevel >= ClassFileConstants.JDK1_5;
+		this.memberTypeSeparator = memberTypeSeparator;
+	}
+
+	private void addIdentifiers(String typeSignature, int start, int endExclusive, int identCount, ArrayList fragments) {
+		if (identCount == 1) {
+			char[] identifier;
+			typeSignature.getChars(start, endExclusive, identifier = new char[endExclusive-start], 0);
+			fragments.add(identifier);
+		} else
+			fragments.add(extractIdentifiers(typeSignature, start, endExclusive-1, identCount));
+	}
+
+	/*
+	 * Build an import reference from an import name, e.g. java.lang.*
+	 */
+	protected ImportReference createImportReference(
+		String[] importName,
+		int start,
+		int end,
+		boolean onDemand,
+		int modifiers) {
+
+		int length = importName.length;
+		long[] positions = new long[length];
+		long position = ((long) start << 32) + end;
+		char[][] qImportName = new char[length][];
+		for (int i = 0; i < length; i++) {
+			qImportName[i] = importName[i].toCharArray();
+			positions[i] = position; // dummy positions
+		}
+		return new ImportReference(
+			qImportName,
+			positions,
+			onDemand,
+			modifiers);
+	}
+
+	protected TypeParameter createTypeParameter(char[] typeParameterName, char[][] typeParameterBounds, int start, int end) {
+
+		TypeParameter parameter = new TypeParameter();
+		parameter.name = typeParameterName;
+		parameter.sourceStart = start;
+		parameter.sourceEnd = end;
+		if (typeParameterBounds != null) {
+			int length = typeParameterBounds.length;
+			if (length > 0) {
+				parameter.type = createTypeReference(typeParameterBounds[0], start, end);
+				if (length > 1) {
+					parameter.bounds = new TypeReference[length-1];
+					for (int i = 1; i < length; i++) {
+						TypeReference bound = createTypeReference(typeParameterBounds[i], start, end);
+						bound.bits |= ASTNode.IsSuperType;
+						parameter.bounds[i-1] = bound;
+					}
+				}
+			}
+		}
+		return parameter;
+	}
+
+	/*
+	 * Build a type reference from a readable name, e.g. java.lang.Object[][]
+	 */
+	protected TypeReference createTypeReference(
+		char[] typeName,
+		int start,
+		int end,
+		boolean includeGenericsAnyway) {
+
+		int length = typeName.length;
+		this.namePos = 0;
+		return decodeType(typeName, length, start, end, true);
+	}
+
+	/*
+	 * Build a type reference from a readable name, e.g. java.lang.Object[][]
+	 */
+	protected TypeReference createTypeReference(
+		char[] typeName,
+		int start,
+		int end) {
+
+		int length = typeName.length;
+		this.namePos = 0;
+		return decodeType(typeName, length, start, end, false);
+	}
+
+	/*
+	 * Build a type reference from a type signature, e.g. Ljava.lang.Object;
+	 */
+	protected TypeReference createTypeReference(
+			String typeSignature,
+			int start,
+			int end) {
+
+		int length = typeSignature.length();
+		this.namePos = 0;
+		return decodeType(typeSignature, length, start, end);
+	}
+
+	private TypeReference decodeType(String typeSignature, int length, int start, int end) {
+		int identCount = 1;
+		int dim = 0;
+		int nameFragmentStart = this.namePos, nameFragmentEnd = -1;
+		boolean nameStarted = false;
+		ArrayList fragments = null;
+		typeLoop: while (this.namePos < length) {
+			char currentChar = typeSignature.charAt(this.namePos);
+			switch (currentChar) {
+				case Signature.C_BOOLEAN :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.BOOLEAN.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.BOOLEAN.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_BYTE :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.BYTE.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.BYTE.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_CHAR :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.CHAR.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.CHAR.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_DOUBLE :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.DOUBLE.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.DOUBLE.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_FLOAT :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.FLOAT.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.FLOAT.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_INT :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.INT.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.INT.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_LONG :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.LONG.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.LONG.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_SHORT :
+					if (!nameStarted) {
+						this.namePos++;
+						if (dim == 0)
+							return new SingleTypeReference(TypeBinding.SHORT.simpleName, ((long) start << 32) + end);
+						else
+							return new ArrayTypeReference(TypeBinding.SHORT.simpleName, dim, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_VOID :
+					if (!nameStarted) {
+						this.namePos++;
+						return new SingleTypeReference(TypeBinding.VOID.simpleName, ((long) start << 32) + end);
+					}
+					break;
+				case Signature.C_RESOLVED :
+				case Signature.C_UNRESOLVED :
+				case Signature.C_TYPE_VARIABLE :
+					if (!nameStarted) {
+						nameFragmentStart = this.namePos+1;
+						nameStarted = true;
+					}
+					break;
+				case Signature.C_STAR:
+					this.namePos++;
+					Wildcard result = new Wildcard(Wildcard.UNBOUND);
+					result.sourceStart = start;
+					result.sourceEnd = end;
+					return result;
+				case Signature.C_EXTENDS:
+					this.namePos++;
+					result = new Wildcard(Wildcard.EXTENDS);
+					result.bound = decodeType(typeSignature, length, start, end);
+					result.sourceStart = start;
+					result.sourceEnd = end;
+					return result;
+				case Signature.C_SUPER:
+					this.namePos++;
+					result = new Wildcard(Wildcard.SUPER);
+					result.bound = decodeType(typeSignature, length, start, end);
+					result.sourceStart = start;
+					result.sourceEnd = end;
+					return result;
+				case Signature.C_ARRAY :
+					dim++;
+					break;
+				case Signature.C_GENERIC_END :
+				case Signature.C_SEMICOLON :
+					nameFragmentEnd = this.namePos-1;
+					this.namePos++;
+					break typeLoop;
+				case Signature.C_DOLLAR:
+					if (this.memberTypeSeparator != Signature.C_DOLLAR)
+						break;
+					// $FALL-THROUGH$
+				case Signature.C_DOT :
+					if (!nameStarted) {
+						nameFragmentStart = this.namePos+1;
+						nameStarted = true;
+					} else if (this.namePos > nameFragmentStart) // handle name starting with a $ (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=91709)
+						identCount ++;
+					break;
+				case Signature.C_GENERIC_START :
+					nameFragmentEnd = this.namePos-1;
+					// convert 1.5 specific constructs only if compliance is 1.5 or above
+					if (!this.has1_5Compliance)
+						break typeLoop;
+					if (fragments == null) fragments = new ArrayList(2);
+					addIdentifiers(typeSignature, nameFragmentStart, nameFragmentEnd + 1, identCount, fragments);
+					this.namePos++; // skip '<'
+					TypeReference[] arguments = decodeTypeArguments(typeSignature, length, start, end); // positionned on '>' at end
+					fragments.add(arguments);
+					identCount = 1;
+					nameStarted = false;
+					// next increment will skip '>'
+					break;
+			}
+			this.namePos++;
+		}
+		if (fragments == null) { // non parameterized
+			/* rebuild identifiers and dimensions */
+			if (identCount == 1) { // simple type reference
+				if (dim == 0) {
+					char[] nameFragment = new char[nameFragmentEnd - nameFragmentStart + 1];
+					typeSignature.getChars(nameFragmentStart, nameFragmentEnd +1, nameFragment, 0);
+					return new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+				} else {
+					char[] nameFragment = new char[nameFragmentEnd - nameFragmentStart + 1];
+					typeSignature.getChars(nameFragmentStart, nameFragmentEnd +1, nameFragment, 0);
+					return new ArrayTypeReference(nameFragment, dim, ((long) start << 32) + end);
+				}
+			} else { // qualified type reference
+				long[] positions = new long[identCount];
+				long pos = ((long) start << 32) + end;
+				for (int i = 0; i < identCount; i++) {
+					positions[i] = pos;
+				}
+				char[][] identifiers = extractIdentifiers(typeSignature, nameFragmentStart, nameFragmentEnd, identCount);
+				if (dim == 0) {
+					return new QualifiedTypeReference(identifiers, positions);
+				} else {
+					return new ArrayQualifiedTypeReference(identifiers, dim, positions);
+				}
+			}
+		} else { // parameterized
+			// rebuild type reference from available fragments: char[][], arguments, char[][], arguments...
+			// check trailing qualified name
+			if (nameStarted) {
+				addIdentifiers(typeSignature, nameFragmentStart, nameFragmentEnd + 1, identCount, fragments);
+			}
+			int fragmentLength = fragments.size();
+			if (fragmentLength == 2) {
+				Object firstFragment = fragments.get(0);
+				if (firstFragment instanceof char[]) {
+					// parameterized single type
+					return new ParameterizedSingleTypeReference((char[]) firstFragment, (TypeReference[]) fragments.get(1), dim, ((long) start << 32) + end);
+				}
+			}
+			// parameterized qualified type
+			identCount = 0;
+			for (int i = 0; i < fragmentLength; i ++) {
+				Object element = fragments.get(i);
+				if (element instanceof char[][]) {
+					identCount += ((char[][])element).length;
+				} else if (element instanceof char[])
+					identCount++;
+			}
+			char[][] tokens = new char[identCount][];
+			TypeReference[][] arguments = new TypeReference[identCount][];
+			int index = 0;
+			for (int i = 0; i < fragmentLength; i ++) {
+				Object element = fragments.get(i);
+				if (element instanceof char[][]) {
+					char[][] fragmentTokens = (char[][]) element;
+					int fragmentTokenLength = fragmentTokens.length;
+					System.arraycopy(fragmentTokens, 0, tokens, index, fragmentTokenLength);
+					index += fragmentTokenLength;
+				} else if (element instanceof char[]) {
+					tokens[index++] = (char[]) element;
+				} else {
+					arguments[index-1] = (TypeReference[]) element;
+				}
+			}
+			long[] positions = new long[identCount];
+			long pos = ((long) start << 32) + end;
+			for (int i = 0; i < identCount; i++) {
+				positions[i] = pos;
+			}
+			return new ParameterizedQualifiedTypeReference(tokens, arguments, dim, positions);
+		}
+	}
+
+	private TypeReference decodeType(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) {
+		int identCount = 1;
+		int dim = 0;
+		int nameFragmentStart = this.namePos, nameFragmentEnd = -1;
+		ArrayList fragments = null;
+		typeLoop: while (this.namePos < length) {
+			char currentChar = typeName[this.namePos];
+			switch (currentChar) {
+				case '?' :
+					this.namePos++; // skip '?'
+					while (typeName[this.namePos] == ' ') this.namePos++;
+					switch(typeName[this.namePos]) {
+						case 's' :
+							checkSuper: {
+								int max = TypeConstants.WILDCARD_SUPER.length-1;
+								for (int ahead = 1; ahead < max; ahead++) {
+									if (typeName[this.namePos+ahead] != TypeConstants.WILDCARD_SUPER[ahead+1]) {
+										break checkSuper;
+									}
+								}
+								this.namePos += max;
+								Wildcard result = new Wildcard(Wildcard.SUPER);
+								result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway);
+								result.sourceStart = start;
+								result.sourceEnd = end;
+								return result;
+							}
+							break;
+						case 'e' :
+							checkExtends: {
+								int max = TypeConstants.WILDCARD_EXTENDS.length-1;
+								for (int ahead = 1; ahead < max; ahead++) {
+									if (typeName[this.namePos+ahead] != TypeConstants.WILDCARD_EXTENDS[ahead+1]) {
+										break checkExtends;
+									}
+								}
+								this.namePos += max;
+								Wildcard result = new Wildcard(Wildcard.EXTENDS);
+								result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway);
+								result.sourceStart = start;
+								result.sourceEnd = end;
+								return result;
+							}
+							break;
+					}
+					Wildcard result = new Wildcard(Wildcard.UNBOUND);
+					result.sourceStart = start;
+					result.sourceEnd = end;
+					return result;
+				case '[' :
+					if (dim == 0 && nameFragmentEnd < 0) nameFragmentEnd = this.namePos-1;
+					dim++;
+					break;
+				case ']' :
+					break;
+				case '>' :
+				case ',' :
+					break typeLoop;
+				case '.' :
+					if (nameFragmentStart < 0) nameFragmentStart = this.namePos+1; // member type name
+					identCount ++;
+					break;
+				case '<' :
+					/* We need to convert and preserve 1.5 specific constructs either if compliance is 1.5 or above,
+					   or the caller has explicitly requested generics to be included. The parameter includeGenericsAnyway
+					   should be used by the caller to signal that in the calling context generics information must be 
+					   internalized even when the requesting project is 1.4. But in all cases, we must skip over them to
+					   see if there are any applicable type fragments after the type parameters: i.e we just aren't done
+					   having seen a '<' in 1.4 mode. 
+					   
+					   Because of the way type signatures are encoded, TypeConverter.decodeType(String, int, int, int) is immune
+					   to this problem. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633
+					 */
+					if (this.has1_5Compliance || includeGenericsAnyway) {
+						if (fragments == null) fragments = new ArrayList(2);
+					}
+					nameFragmentEnd = this.namePos-1;
+					if (this.has1_5Compliance || includeGenericsAnyway) {
+						char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, this.namePos);
+						fragments.add(identifiers);
+					}
+					this.namePos++; // skip '<'
+					TypeReference[] arguments = decodeTypeArguments(typeName, length, start, end, includeGenericsAnyway); // positionned on '>' at end
+					if (this.has1_5Compliance || includeGenericsAnyway) {
+						fragments.add(arguments);
+						identCount = 0;
+						nameFragmentStart = -1;
+						nameFragmentEnd = -1;
+					}
+					// next increment will skip '>'
+					break;
+			}
+			this.namePos++;
+		}
+		if (nameFragmentEnd < 0) nameFragmentEnd = this.namePos-1;
+		if (fragments == null) { // non parameterized
+			/* rebuild identifiers and dimensions */
+			if (identCount == 1) { // simple type reference
+				if (dim == 0) {
+					char[] nameFragment;
+					if (nameFragmentStart != 0 || nameFragmentEnd >= 0) {
+						int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+						System.arraycopy(typeName, nameFragmentStart, nameFragment = new char[nameFragmentLength], 0, nameFragmentLength);
+					} else {
+						nameFragment = typeName;
+					}
+					return new SingleTypeReference(nameFragment, ((long) start << 32) + end);
+				} else {
+					int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1;
+					char[] nameFragment = new char[nameFragmentLength];
+					System.arraycopy(typeName, nameFragmentStart, nameFragment, 0, nameFragmentLength);
+					return new ArrayTypeReference(nameFragment, dim, ((long) start << 32) + end);
+				}
+			} else { // qualified type reference
+				long[] positions = new long[identCount];
+				long pos = ((long) start << 32) + end;
+				for (int i = 0; i < identCount; i++) {
+					positions[i] = pos;
+				}
+				char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, nameFragmentEnd+1);
+				if (dim == 0) {
+					return new QualifiedTypeReference(identifiers, positions);
+				} else {
+					return new ArrayQualifiedTypeReference(identifiers, dim, positions);
+				}
+			}
+		} else { // parameterized
+			// rebuild type reference from available fragments: char[][], arguments, char[][], arguments...
+			// check trailing qualified name
+			if (nameFragmentStart > 0 && nameFragmentStart < length) {
+				char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, nameFragmentEnd+1);
+				fragments.add(identifiers);
+			}
+			int fragmentLength = fragments.size();
+			if (fragmentLength == 2) {
+				char[][] firstFragment = (char[][]) fragments.get(0);
+				if (firstFragment.length == 1) {
+					// parameterized single type
+					return new ParameterizedSingleTypeReference(firstFragment[0], (TypeReference[]) fragments.get(1), dim, ((long) start << 32) + end);
+				}
+			}
+			// parameterized qualified type
+			identCount = 0;
+			for (int i = 0; i < fragmentLength; i ++) {
+				Object element = fragments.get(i);
+				if (element instanceof char[][]) {
+					identCount += ((char[][])element).length;
+				}
+			}
+			char[][] tokens = new char[identCount][];
+			TypeReference[][] arguments = new TypeReference[identCount][];
+			int index = 0;
+			for (int i = 0; i < fragmentLength; i ++) {
+				Object element = fragments.get(i);
+				if (element instanceof char[][]) {
+					char[][] fragmentTokens = (char[][]) element;
+					int fragmentTokenLength = fragmentTokens.length;
+					System.arraycopy(fragmentTokens, 0, tokens, index, fragmentTokenLength);
+					index += fragmentTokenLength;
+				} else {
+					arguments[index-1] = (TypeReference[]) element;
+				}
+			}
+			long[] positions = new long[identCount];
+			long pos = ((long) start << 32) + end;
+			for (int i = 0; i < identCount; i++) {
+				positions[i] = pos;
+			}
+			return new ParameterizedQualifiedTypeReference(tokens, arguments, dim, positions);
+		}
+	}
+
+	private TypeReference[] decodeTypeArguments(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) {
+		ArrayList argumentList = new ArrayList(1);
+		int count = 0;
+		argumentsLoop: while (this.namePos < length) {
+			TypeReference argument = decodeType(typeName, length, start, end, includeGenericsAnyway);
+			count++;
+			argumentList.add(argument);
+			if (this.namePos >= length) break argumentsLoop;
+			if (typeName[this.namePos] == '>') {
+				break argumentsLoop;
+			}
+			this.namePos++; // skip ','
+		}
+		TypeReference[] typeArguments = new TypeReference[count];
+		argumentList.toArray(typeArguments);
+		return typeArguments;
+	}
+
+	private TypeReference[] decodeTypeArguments(String typeSignature, int length, int start, int end) {
+		ArrayList argumentList = new ArrayList(1);
+		int count = 0;
+		argumentsLoop: while (this.namePos < length) {
+			TypeReference argument = decodeType(typeSignature, length, start, end);
+			count++;
+			argumentList.add(argument);
+			if (this.namePos >= length) break argumentsLoop;
+			if (typeSignature.charAt(this.namePos) == Signature.C_GENERIC_END) {
+				break argumentsLoop;
+			}
+		}
+		TypeReference[] typeArguments = new TypeReference[count];
+		argumentList.toArray(typeArguments);
+		return typeArguments;
+	}
+
+	private char[][] extractIdentifiers(String typeSignature, int start, int endInclusive, int identCount) {
+		char[][] result = new char[identCount][];
+		int charIndex = start;
+		int i = 0;
+		while (charIndex < endInclusive) {
+			char currentChar;
+			if ((currentChar = typeSignature.charAt(charIndex)) == this.memberTypeSeparator || currentChar == Signature.C_DOT) {
+				typeSignature.getChars(start, charIndex, result[i++] = new char[charIndex - start], 0);
+				start = ++charIndex;
+			} else
+				charIndex++;
+		}
+		typeSignature.getChars(start, charIndex + 1, result[i++] = new char[charIndex - start + 1], 0);
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java
new file mode 100644
index 0000000..ec91dc1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+public class ASTHolderCUInfo extends CompilationUnitElementInfo {
+	int astLevel;
+	boolean resolveBindings;
+	int reconcileFlags;
+	HashMap problems = null;
+	CompilationUnit ast;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotatableInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotatableInfo.java
new file mode 100644
index 0000000..0ee1ce1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotatableInfo.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.SourceRange;
+
+public class AnnotatableInfo extends MemberElementInfo {
+
+	/*
+	 * The annotations of this annotatble. Empty if none.
+	 */
+	protected IAnnotation[] annotations = Annotation.NO_ANNOTATIONS;
+
+	/**
+	 * The start position of this member's name in the its
+	 * openable's buffer.
+	 */
+	protected int nameStart= -1;
+
+	/**
+	 * The last position of this member's name in the its
+	 * openable's buffer.
+	 */
+	protected int nameEnd= -1;
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceEnd()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceEnd()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceEnd()
+	 */
+	public int getNameSourceEnd() {
+		return this.nameEnd;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceStart()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceStart()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceStart()
+	 */
+	public int getNameSourceStart() {
+		return this.nameStart;
+	}
+	/**
+	 * Sets the last position of this member's name, relative
+	 * to its openable's source buffer.
+	 */
+	protected void setNameSourceEnd(int end) {
+		this.nameEnd= end;
+	}
+	/**
+	 * Sets the start position of this member's name, relative
+	 * to its openable's source buffer.
+	 */
+	protected void setNameSourceStart(int start) {
+		this.nameStart= start;
+	}
+	protected ISourceRange getNameRange() {
+		return new SourceRange(this.nameStart, this.nameEnd - this.nameStart + 1);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java
new file mode 100644
index 0000000..2601848
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class Annotation extends SourceRefElement implements IAnnotation {
+
+	public static final IAnnotation[] NO_ANNOTATIONS = new IAnnotation[0];
+	public static final IMemberValuePair[] NO_MEMBER_VALUE_PAIRS = new IMemberValuePair[0];
+
+	protected String name;
+	// require to distinguish same annotations in different member value pairs
+	protected String memberValuePairName;
+
+	public Annotation(JavaElement parent, String name) {
+		this(parent, name, null);
+	}
+
+	public Annotation(JavaElement parent, String name, String memberValuePairName) {
+		super(parent);
+		this.name = name;
+		this.memberValuePairName = memberValuePairName;
+	}
+
+	public boolean equals(Object o) {
+		if (!(o instanceof Annotation)) {
+			return false;
+		}
+		Annotation other = (Annotation) o;
+		if (this.memberValuePairName == null) {
+			if (other.memberValuePairName != null)
+				return false;
+		} else if (!this.memberValuePairName.equals(other.memberValuePairName)) {
+			return false;
+		}
+		// name equality is checked as part of the super.equals(..)
+		return super.equals(o);
+	}
+
+	public IMember getDeclaringMember() {
+		return (IMember) getParent();
+	}
+
+	public String getElementName() {
+		return this.name;
+	}
+
+	public int getElementType() {
+		return ANNOTATION;
+	}
+
+	protected char getHandleMementoDelimiter() {
+		return JavaElement.JEM_ANNOTATION;
+	}
+
+	public IMemberValuePair[] getMemberValuePairs() throws JavaModelException {
+		Object info = getElementInfo();
+		if (info instanceof AnnotationInfo)
+			return ((AnnotationInfo) info).members;
+		IBinaryElementValuePair[] binaryAnnotations = ((IBinaryAnnotation) info).getElementValuePairs();
+		int length = binaryAnnotations.length;
+		IMemberValuePair[] result = new IMemberValuePair[length];
+		for (int i = 0; i < length; i++) {
+			IBinaryElementValuePair binaryAnnotation = binaryAnnotations[i];
+			MemberValuePair memberValuePair = new MemberValuePair(new String(binaryAnnotation.getName()));
+			memberValuePair.value = Util.getAnnotationMemberValue(this, memberValuePair, binaryAnnotation.getValue());
+			result[i] = memberValuePair;
+		}
+		return result;
+	}
+
+	public ISourceRange getNameRange() throws JavaModelException {
+		SourceMapper mapper= getSourceMapper();
+		if (mapper != null) {
+			ClassFile classFile = (ClassFile)getClassFile();
+			if (classFile != null) {
+				// ensure the class file's buffer is open so that source ranges are computed
+				classFile.getBuffer();
+				return mapper.getNameRange(this);
+			}
+		}
+		Object info = getElementInfo();
+		if (info instanceof AnnotationInfo) {
+			AnnotationInfo annotationInfo = (AnnotationInfo) info;
+			return new SourceRange(annotationInfo.nameStart, annotationInfo.nameEnd - annotationInfo.nameStart + 1);
+		}
+		return null;
+	}
+
+	/*
+	 * @see ISourceReference
+	 */
+	public ISourceRange getSourceRange() throws JavaModelException {
+		SourceMapper mapper= getSourceMapper();
+		if (mapper != null) {
+			// ensure the class file's buffer is open so that source ranges are computed
+			ClassFile classFile = (ClassFile)getClassFile();
+			if (classFile != null) {
+				classFile.getBuffer();
+				return mapper.getSourceRange(this);
+			}
+		}
+		return super.getSourceRange();
+	}
+
+	public IClassFile getClassFile() {
+		return ((JavaElement)getParent()).getClassFile();
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((this.memberValuePairName == null) ? 0 : this.memberValuePairName.hashCode());
+		result = prime * result + this.name.hashCode();
+		return result;
+	}
+
+	protected void toStringName(StringBuffer buffer) {
+		buffer.append('@');
+		buffer.append(getElementName());
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotationInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotationInfo.java
new file mode 100644
index 0000000..0511694
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AnnotationInfo.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IMemberValuePair;
+
+/*
+ * Element info for an IAnnotation element that originated from source.
+ */
+public class AnnotationInfo extends SourceRefElementInfo {
+
+	/*
+	 * The start position of this annotation's name in the its
+	 * openable's buffer.
+	 */
+	public int nameStart= -1;
+
+	/*
+	 * The last position of this annotation in the its
+	 * openable's buffer.
+	 */
+	public int nameEnd= -1;
+
+	/*
+	 * The member-value pairs of this annotation.
+	 */
+	public IMemberValuePair[] members;
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java
new file mode 100644
index 0000000..11cdaa3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * A basic implementation of <code>ICompilationUnit</code>
+ * for use in the <code>SourceMapper</code>.
+ * @see ICompilationUnit
+ */
+public class BasicCompilationUnit implements ICompilationUnit {
+	protected char[] contents;
+
+	// Note that if this compiler ICompilationUnit's content is known in advance, the fileName is not used to retrieve this content.
+	// Instead it is used to keep enough information to recreate the IJavaElement corresponding to this compiler ICompilationUnit.
+	// Thus the fileName can be a path to a .class file, or even a path in a .jar to a .class file.
+	// (e.g. /P/lib/mylib.jar|org/eclipse/test/X.class)
+	protected char[] fileName;
+
+	protected char[][] packageName;
+	protected char[] mainTypeName;
+	protected String encoding;
+
+public BasicCompilationUnit(char[] contents, char[][] packageName, String fileName) {
+	this.contents = contents;
+	this.fileName = fileName.toCharArray();
+	this.packageName = packageName;
+}
+
+public BasicCompilationUnit(char[] contents, char[][] packageName, String fileName, String encoding) {
+	this(contents, packageName, fileName);
+	this.encoding = encoding;
+}
+
+public BasicCompilationUnit(char[] contents, char[][] packageName, String fileName, IJavaElement javaElement) {
+	this(contents, packageName, fileName);
+	initEncoding(javaElement);
+}
+
+/*
+ * Initialize compilation unit encoding.
+ * If we have a project, then get file name corresponding IFile and retrieve its encoding using
+ * new API for encoding.
+ * In case of a class file, then go through project in order to let the possibility to retrieve
+ * a corresponding source file resource.
+ * If we have a compilation unit, then get encoding from its resource directly...
+ */
+private void initEncoding(IJavaElement javaElement) {
+	if (javaElement != null) {
+		try {
+			IJavaProject javaProject = javaElement.getJavaProject();
+			switch (javaElement.getElementType()) {
+				case IJavaElement.COMPILATION_UNIT:
+					IFile file = (IFile) javaElement.getResource();
+					if (file != null) {
+						this.encoding = file.getCharset();
+						break;
+					}
+					// if no file, then get project encoding
+					// $FALL-THROUGH$
+				default:
+					IProject project = (IProject) javaProject.getResource();
+					if (project != null) {
+						this.encoding = project.getDefaultCharset();
+					}
+					break;
+			}
+		} catch (CoreException e1) {
+			this.encoding = null;
+		}
+	} else  {
+		this.encoding = null;
+	}
+}
+
+public char[] getContents() {
+	if (this.contents != null)
+		return this.contents;   // answer the cached source
+
+	// otherwise retrieve it
+	try {
+		return Util.getFileCharContent(new File(new String(this.fileName)), this.encoding);
+	} catch (IOException e) {
+		// could not read file: returns an empty array
+	}
+	return CharOperation.NO_CHAR;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.fileName;
+}
+public char[] getMainTypeName() {
+	if (this.mainTypeName == null) {
+		int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
+		if (start == 0 || start < CharOperation.lastIndexOf('\\', this.fileName))
+			start = CharOperation.lastIndexOf('\\', this.fileName) + 1;
+		int separator = CharOperation.indexOf('|', this.fileName) + 1;
+		if (separator > start) // case of a .class file in a default package in a jar
+			start = separator;
+
+		int end = CharOperation.lastIndexOf('$', this.fileName);
+		if (end == -1 || !Util.isClassFileName(this.fileName)) {
+			end = CharOperation.lastIndexOf('.', this.fileName);
+			if (end == -1)
+				end = this.fileName.length;
+		}
+
+		this.mainTypeName = CharOperation.subarray(this.fileName, start, end);
+	}
+	return this.mainTypeName;
+}
+public char[][] getPackageName() {
+	return this.packageName;
+}
+public boolean ignoreOptionalProblems() {
+	return false;
+}
+public String toString(){
+	return "CompilationUnit: "+new String(this.fileName); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchInitializationMonitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchInitializationMonitor.java
new file mode 100644
index 0000000..1dabe5d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchInitializationMonitor.java
@@ -0,0 +1,85 @@
+package org.eclipse.jdt.internal.core;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+public class BatchInitializationMonitor implements IProgressMonitor {
+
+	public ThreadLocal initializeAfterLoadMonitor = new ThreadLocal();
+
+	public String subTaskName = ""; //$NON-NLS-1$
+	public int worked = 0;
+
+	private IProgressMonitor getMonitor() {
+		return (IProgressMonitor) this.initializeAfterLoadMonitor.get();
+	}
+
+	public void beginTask(String name, int totalWork) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.beginTask(name, totalWork);
+	}
+
+	public void done() {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.done();
+		this.worked = 0;
+		this.subTaskName = ""; //$NON-NLS-1$
+	}
+
+	public void internalWorked(double work) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.internalWorked(work);
+	}
+
+	public boolean isCanceled() {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			return monitor.isCanceled();
+		return false;
+	}
+
+	public void setCanceled(boolean value) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.setCanceled(value);
+	}
+
+	public void setTaskName(String name) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.setTaskName(name);
+	}
+
+	public void subTask(String name) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.subTask(name);
+		this.subTaskName = name;
+	}
+
+	public void worked(int work) {
+		IProgressMonitor monitor = getMonitor();
+		if (monitor != null)
+			monitor.worked(work);
+		synchronized(this) {
+			this.worked += work;
+		}
+	}
+
+	public synchronized int getWorked() {
+		int result = this.worked;
+		this.worked = 0;
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java
new file mode 100644
index 0000000..318e8e7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * An operation created as a result of a call to JavaCore.run(IWorkspaceRunnable, IProgressMonitor)
+ * that encapsulates a user defined IWorkspaceRunnable.
+ */
+public class BatchOperation extends JavaModelOperation {
+	protected IWorkspaceRunnable runnable;
+	public BatchOperation(IWorkspaceRunnable runnable) {
+		this.runnable = runnable;
+	}
+
+	protected boolean canModifyRoots() {
+		// anything in the workspace runnable can modify the roots
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.JavaModelOperation#executeOperation()
+	 */
+	protected void executeOperation() throws JavaModelException {
+		try {
+			this.runnable.run(this.progressMonitor);
+		} catch (CoreException ce) {
+			if (ce instanceof JavaModelException) {
+				throw (JavaModelException)ce;
+			} else {
+				if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
+					Throwable e= ce.getStatus().getException();
+					if (e instanceof JavaModelException) {
+						throw (JavaModelException) e;
+					}
+				}
+				throw new JavaModelException(ce);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.JavaModelOperation#verify()
+	 */
+	protected IJavaModelStatus verify() {
+		// cannot verify user defined operation
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
new file mode 100644
index 0000000..7f5be9a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Switch and ICompilationUnit to working copy mode
+ * and signal the working copy addition through a delta.
+ */
+public class BecomeWorkingCopyOperation extends JavaModelOperation {
+
+	IProblemRequestor problemRequestor;
+
+	/*
+	 * Creates a BecomeWorkingCopyOperation for the given working copy.
+	 * perOwnerWorkingCopies map is not null if the working copy is a shared working copy.
+	 */
+	public BecomeWorkingCopyOperation(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
+		super(new IJavaElement[] {workingCopy});
+		this.problemRequestor = problemRequestor;
+	}
+	protected void executeOperation() throws JavaModelException {
+
+		// open the working copy now to ensure contents are that of the current state of this element
+		CompilationUnit workingCopy = getWorkingCopy();
+		JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(workingCopy, true/*create if needed*/, true/*record usage*/, this.problemRequestor);
+		workingCopy.openWhenClosed(workingCopy.createElementInfo(), true, this.progressMonitor);
+
+		if (!workingCopy.isPrimary()) {
+			// report added java delta for a non-primary working copy
+			JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+			delta.added(workingCopy);
+			addDelta(delta);
+		} else {
+			if (workingCopy.getResource().isAccessible()) {
+				// report a F_PRIMARY_WORKING_COPY change delta for a primary working copy
+				JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+				delta.changed(workingCopy, IJavaElementDelta.F_PRIMARY_WORKING_COPY);
+				addDelta(delta);
+			} else {
+				// report an ADDED delta
+				JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+				delta.added(workingCopy, IJavaElementDelta.F_PRIMARY_WORKING_COPY);
+				addDelta(delta);
+			}
+		}
+
+		this.resultElements = new IJavaElement[] {workingCopy};
+	}
+	/*
+	 * Returns the working copy this operation is working on.
+	 */
+	protected CompilationUnit getWorkingCopy() {
+		return (CompilationUnit)getElementToProcess();
+	}
+	/*
+	 * @see JavaModelOperation#isReadOnly
+	 */
+	public boolean isReadOnly() {
+		return true;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
new file mode 100644
index 0000000..9d20e5c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+
+/**
+ * @see IField
+ */
+
+/* package */ class BinaryField extends BinaryMember implements IField {
+
+/*
+ * Constructs a handle to the field with the given name in the specified type.
+ */
+protected BinaryField(JavaElement parent, String name) {
+	super(parent, name);
+}
+public boolean equals(Object o) {
+	if (!(o instanceof BinaryField)) return false;
+	return super.equals(o);
+}
+public IAnnotation[] getAnnotations() throws JavaModelException {
+	IBinaryField info = (IBinaryField) getElementInfo();
+	IBinaryAnnotation[] binaryAnnotations = info.getAnnotations();
+	return getAnnotations(binaryAnnotations, info.getTagBits());
+}
+/*
+ * @see IField
+ */
+public Object getConstant() throws JavaModelException {
+	IBinaryField info = (IBinaryField) getElementInfo();
+	return convertConstant(info.getConstant());
+}
+/*
+ * @see IMember
+ */
+public int getFlags() throws JavaModelException {
+	IBinaryField info = (IBinaryField) getElementInfo();
+	return info.getModifiers();
+}
+/*
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return FIELD;
+}
+/*
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_FIELD;
+}
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, forceOpen);
+}
+/*
+ * @see IField
+ */
+public String getTypeSignature() throws JavaModelException {
+	IBinaryField info = (IBinaryField) getElementInfo();
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature != null) {
+		return new String(ClassFile.translatedName(genericSignature));
+	}
+	return new String(ClassFile.translatedName(info.getTypeName()));
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isEnumConstant()
+ */public boolean isEnumConstant() throws JavaModelException {
+	return Flags.isEnum(getFlags());
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryField(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
+/*
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		toStringName(buffer);
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		toStringName(buffer);
+	} else {
+		try {
+			buffer.append(Signature.toString(getTypeSignature()));
+			buffer.append(" "); //$NON-NLS-1$
+			toStringName(buffer);
+		} catch (JavaModelException e) {
+			buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
+		}
+	}
+}
+public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+	JavadocContents javadocContents = ((BinaryType) this.getDeclaringType()).getJavadocContents(monitor);
+	if (javadocContents == null) return null;
+	return javadocContents.getFieldDoc(this);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java
new file mode 100644
index 0000000..3f6d742
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Common functionality for Binary member handles.
+ */
+public abstract class BinaryMember extends NamedMember {
+		
+/*
+ * Constructs a binary member.
+ */
+protected BinaryMember(JavaElement parent, String name) {
+	super(parent, name);
+}
+/*
+ * @see ISourceManipulation
+ */
+public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+protected IAnnotation[] getAnnotations(IBinaryAnnotation[] binaryAnnotations, long tagBits) {
+	IAnnotation[] standardAnnotations = getStandardAnnotations(tagBits);
+	if (binaryAnnotations == null)
+		return standardAnnotations;
+	int length = binaryAnnotations.length;
+	int standardLength = standardAnnotations.length;
+	int fullLength = length + standardLength;
+	if (fullLength == 0) {
+		return Annotation.NO_ANNOTATIONS;
+	}
+	IAnnotation[] annotations = new IAnnotation[fullLength];
+	for (int i = 0; i < length; i++) {
+		annotations[i] = Util.getAnnotation(this, binaryAnnotations[i], null);
+	}
+	System.arraycopy(standardAnnotations, 0, annotations, length, standardLength);
+	return annotations;
+}
+private IAnnotation getAnnotation(char[][] annotationName) {
+	return new Annotation(this, new String(CharOperation.concatWith(annotationName, '.')));
+}
+protected IAnnotation[] getStandardAnnotations(long tagBits) {
+	if ((tagBits & TagBits.AllStandardAnnotationsMask) == 0)
+		return Annotation.NO_ANNOTATIONS;
+	ArrayList annotations = new ArrayList();
+
+	if ((tagBits & TagBits.AnnotationTargetMASK) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_TARGET));
+	}
+	if ((tagBits & TagBits.AnnotationRetentionMASK) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_RETENTION));
+	}
+	if ((tagBits & TagBits.AnnotationDeprecated) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_DEPRECATED));
+	}
+	if ((tagBits & TagBits.AnnotationDocumented) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED));
+	}
+	if ((tagBits & TagBits.AnnotationInherited) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_ANNOTATION_INHERITED));
+	}
+	if ((tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE));
+	}
+	if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) {
+		annotations.add(getAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS));
+	}
+	// note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries
+	return (IAnnotation[]) annotations.toArray(new IAnnotation[annotations.size()]);
+}
+
+public String[] getCategories() throws JavaModelException {
+	SourceMapper mapper= getSourceMapper();
+	if (mapper != null) {
+		// ensure the class file's buffer is open so that categories are computed
+		((ClassFile)getClassFile()).getBuffer();
+
+		if (mapper.categories != null) {
+			String[] categories = (String[]) mapper.categories.get(this);
+			if (categories != null)
+				return categories;
+		}
+	}
+	return CharOperation.NO_STRINGS;
+}
+public String getKey() {
+	try {
+		return getKey(false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()
+ */
+public abstract String getKey(boolean forceOpen) throws JavaModelException;
+/*
+ * @see ISourceReference
+ */
+public ISourceRange getNameRange() throws JavaModelException {
+	SourceMapper mapper= getSourceMapper();
+	if (mapper != null) {
+		// ensure the class file's buffer is open so that source ranges are computed
+		((ClassFile)getClassFile()).getBuffer();
+
+		return mapper.getNameRange(this);
+	} else {
+		return SourceMapper.UNKNOWN_RANGE;
+	}
+}
+/*
+ * @see ISourceReference
+ */
+public ISourceRange getSourceRange() throws JavaModelException {
+	SourceMapper mapper= getSourceMapper();
+	if (mapper != null) {
+		// ensure the class file's buffer is open so that source ranges are computed
+		((ClassFile)getClassFile()).getBuffer();
+
+		return mapper.getSourceRange(this);
+	} else {
+		return SourceMapper.UNKNOWN_RANGE;
+	}
+}
+/*
+ * @see IMember
+ */
+public boolean isBinary() {
+	return true;
+}
+/*
+ * @see IJavaElement
+ */
+public boolean isStructureKnown() throws JavaModelException {
+	return ((IJavaElement)getOpenableParent()).isStructureKnown();
+}
+/*
+ * @see ISourceManipulation
+ */
+public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/*
+ * @see ISourceManipulation
+ */
+public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/*
+ * Sets the contents of this element.
+ * Throws an exception as this element is read only.
+ */
+public void setContents(String contents, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
new file mode 100644
index 0000000..b128087
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
@@ -0,0 +1,681 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IMethod
+ */
+
+/* package */ class BinaryMethod extends BinaryMember implements IMethod {
+	/**
+	 * The parameter type signatures of the method - stored locally
+	 * to perform equality test. <code>CharOperation.NO_STRINGS</code> indicates no
+	 * parameters.
+	 */
+	protected String[] parameterTypes;
+	protected String [] erasedParamaterTypes; // lazily initialized via call to getErasedParameterTypes
+	
+	/**
+	 * The parameter names for the method.
+	 */
+	protected String[] parameterNames;
+
+	protected String[] exceptionTypes;
+	protected String returnType;
+
+protected BinaryMethod(JavaElement parent, String name, String[] paramTypes) {
+	super(parent, name);
+	// Assertion disabled since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=179011
+	// Assert.isTrue(name.indexOf('.') == -1);
+	if (paramTypes == null) {
+		this.parameterTypes= CharOperation.NO_STRINGS;
+	} else {
+		this.parameterTypes= paramTypes;
+	}
+}
+public boolean equals(Object o) {
+	if (!(o instanceof BinaryMethod)) return false;
+	return super.equals(o) && Util.equalArraysOrNull(getErasedParameterTypes(), ((BinaryMethod)o).getErasedParameterTypes());
+}
+public IAnnotation[] getAnnotations() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	IBinaryAnnotation[] binaryAnnotations = info.getAnnotations();
+	return getAnnotations(binaryAnnotations, info.getTagBits());
+}
+public ILocalVariable[] getParameters() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	int length = this.parameterTypes.length;
+	if (length == 0) {
+		return LocalVariable.NO_LOCAL_VARIABLES;
+	}
+	ILocalVariable[] localVariables = new ILocalVariable[length];
+	char[][] argumentNames = info.getArgumentNames();
+	if (argumentNames == null || argumentNames.length < length) {
+		argumentNames = new char[length][];
+		for (int j = 0; j < length; j++) {
+			argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$
+		}
+	}
+	int startIndex = 0;
+	try {
+		if (isConstructor()) {
+			IType declaringType = this.getDeclaringType();
+			if (declaringType.isEnum()) {
+				startIndex = 2;
+			} else if (declaringType.isMember()
+					&& !Flags.isStatic(declaringType.getFlags())) {
+				startIndex = 1;
+			}
+		}
+	} catch(JavaModelException e) {
+		// ignore
+	}
+	for (int i= 0; i < length; i++) {
+		if (i < startIndex) {
+			LocalVariable localVariable = new LocalVariable(
+					this,
+					new String(argumentNames[i]),
+					0,
+					-1,
+					0,
+					-1,
+					this.parameterTypes[i],
+					null,
+					-1,
+					true);
+			localVariables[i] = localVariable;
+			localVariable.annotations = Annotation.NO_ANNOTATIONS;
+		} else {
+			LocalVariable localVariable = new LocalVariable(
+					this,
+					new String(argumentNames[i]),
+					0,
+					-1,
+					0,
+					-1,
+					this.parameterTypes[i],
+					null,
+					-1,
+					true);
+			localVariables[i] = localVariable;
+			IAnnotation[] annotations = getAnnotations(localVariable, info.getParameterAnnotations(i - startIndex));
+			localVariable.annotations = annotations;
+		}
+	}
+	return localVariables;
+}
+private IAnnotation[] getAnnotations(JavaElement annotationParent, IBinaryAnnotation[] binaryAnnotations) {
+	if (binaryAnnotations == null) return Annotation.NO_ANNOTATIONS;
+	int length = binaryAnnotations.length;
+	IAnnotation[] annotations = new IAnnotation[length];
+	for (int i = 0; i < length; i++) {
+		annotations[i] = Util.getAnnotation(annotationParent, binaryAnnotations[i], null);
+	}
+	return annotations;
+}
+public IMemberValuePair getDefaultValue() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	Object defaultValue = info.getDefaultValue();
+	if (defaultValue == null)
+		return null;
+	MemberValuePair memberValuePair = new MemberValuePair(getElementName());
+	memberValuePair.value = Util.getAnnotationMemberValue(this, memberValuePair, defaultValue);
+	return memberValuePair;
+}
+/*
+ * @see IMethod
+ */
+public String[] getExceptionTypes() throws JavaModelException {
+	if (this.exceptionTypes == null) {
+		IBinaryMethod info = (IBinaryMethod) getElementInfo();
+		char[] genericSignature = info.getGenericSignature();
+		if (genericSignature != null) {
+			char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
+			this.exceptionTypes = Signature.getThrownExceptionTypes(new String(dotBasedSignature));
+		}
+		if (this.exceptionTypes == null || this.exceptionTypes.length == 0) {
+			char[][] eTypeNames = info.getExceptionTypeNames();
+			if (eTypeNames == null || eTypeNames.length == 0) {
+				this.exceptionTypes = CharOperation.NO_STRINGS;
+			} else {
+				eTypeNames = ClassFile.translatedNames(eTypeNames);
+				this.exceptionTypes = new String[eTypeNames.length];
+				for (int j = 0, length = eTypeNames.length; j < length; j++) {
+					// 1G01HRY: ITPJCORE:WINNT - method.getExceptionType not in correct format
+					int nameLength = eTypeNames[j].length;
+					char[] convertedName = new char[nameLength + 2];
+					System.arraycopy(eTypeNames[j], 0, convertedName, 1, nameLength);
+					convertedName[0] = 'L';
+					convertedName[nameLength + 1] = ';';
+					this.exceptionTypes[j] = new String(convertedName);
+				}
+			}
+		}
+	}
+	return this.exceptionTypes;
+}
+/*
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return METHOD;
+}
+/*
+ * @see IMember
+ */
+public int getFlags() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	int modifiers = info.getModifiers();
+	if (((IType) this.parent).isInterface() && (modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccStatic)) == 0)
+		modifiers |= ExtraCompilerModifiers.AccDefaultMethod;
+	return modifiers;
+}
+/*
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	((JavaElement) getParent()).getHandleMemento(buff);
+	char delimiter = getHandleMementoDelimiter();
+	buff.append(delimiter);
+	escapeMementoName(buff, getElementName());
+	for (int i = 0; i < this.parameterTypes.length; i++) {
+		buff.append(delimiter);
+		escapeMementoName(buff, this.parameterTypes[i]);
+	}
+	if (this.occurrenceCount > 1) {
+		buff.append(JEM_COUNT);
+		buff.append(this.occurrenceCount);
+	}
+}
+/*
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_METHOD;
+}
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, forceOpen);
+}
+/*
+ * @see IMethod
+ */
+public int getNumberOfParameters() {
+	return this.parameterTypes == null ? 0 : this.parameterTypes.length;
+}
+/*
+ * @see IMethod
+ * Look for source attachment information to retrieve the actual parameter names as stated in source.
+ */
+public String[] getParameterNames() throws JavaModelException {
+	if (this.parameterNames != null)
+		return this.parameterNames;
+
+	// force source mapping if not already done
+	IType type = (IType) getParent();
+	SourceMapper mapper = getSourceMapper();
+	if (mapper != null) {
+		char[][] paramNames = mapper.getMethodParameterNames(this);
+
+		// map source and try to find parameter names
+		if(paramNames == null) {
+			IBinaryType info = (IBinaryType) ((BinaryType) getDeclaringType()).getElementInfo();
+			char[] source = mapper.findSource(type, info);
+			if (source != null){
+				mapper.mapSource(type, source, info);
+			}
+			paramNames = mapper.getMethodParameterNames(this);
+		}
+
+		// if parameter names exist, convert parameter names to String array
+		if(paramNames != null) {
+			String[] names = new String[paramNames.length];
+			for (int i = 0; i < paramNames.length; i++) {
+				names[i] = new String(paramNames[i]);
+			}
+			return this.parameterNames = names;
+		}
+	}
+
+	// try to see if we can retrieve the names from the attached javadoc
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937
+	// Use Signature#getParameterCount() only if the argument names are not already available.
+	int paramCount = Signature.getParameterCount(new String(info.getMethodDescriptor()));
+	if (this.isConstructor()) {
+		final IType declaringType = this.getDeclaringType();
+		if (declaringType.isMember()
+				&& !Flags.isStatic(declaringType.getFlags())) {
+			paramCount--; // remove synthetic argument from constructor param count
+		}
+	}
+
+	if (paramCount != 0) {
+		// don't try to look for javadoc for synthetic methods
+		int modifiers = getFlags();
+		if ((modifiers & ClassFileConstants.AccSynthetic) != 0) {
+			return this.parameterNames = getRawParameterNames(paramCount);
+		}
+		JavadocContents javadocContents = null;
+		IType declaringType = getDeclaringType();
+		PerProjectInfo projectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject());
+		synchronized (projectInfo.javadocCache) {
+			javadocContents = (JavadocContents) projectInfo.javadocCache.get(declaringType);
+			if (javadocContents == null) {
+				projectInfo.javadocCache.put(declaringType, BinaryType.EMPTY_JAVADOC);
+			}
+		}
+		
+		String methodDoc = null;
+		if (javadocContents == null) {
+			long timeOut = 50; // default value
+			try {
+				String option = getJavaProject().getOption(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, true);
+				if (option != null) {
+					timeOut = Long.parseLong(option);
+				}
+			} catch(NumberFormatException e) {
+				// ignore
+			}
+			if (timeOut == 0) {
+				// don't try to fetch the values and don't cache either (https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671)
+				return getRawParameterNames(paramCount);
+			}
+			final class ParametersNameCollector {
+				String javadoc;
+				public void setJavadoc(String s) {
+					this.javadoc = s;
+				}
+				public String getJavadoc() {
+					return this.javadoc;
+				}
+			}
+			/*
+			 * The declaring type is not in the cache yet. The thread wil retrieve the javadoc contents
+			 */
+			final ParametersNameCollector nameCollector = new ParametersNameCollector();
+			Thread collect = new Thread() {
+				public void run() {
+					try {
+						// this call has a side-effect on the per project info cache
+						nameCollector.setJavadoc(BinaryMethod.this.getAttachedJavadoc(null));
+					} catch (JavaModelException e) {
+						// ignore
+					}
+					synchronized(nameCollector) {
+						nameCollector.notify();
+					}
+				}
+			};
+			collect.start();
+			synchronized(nameCollector) {
+				try {
+					nameCollector.wait(timeOut);
+				} catch (InterruptedException e) {
+					// ignore
+				}
+			}
+			methodDoc = nameCollector.getJavadoc();
+		} else if (javadocContents != BinaryType.EMPTY_JAVADOC){
+			// need to extract the part relative to the binary method since javadoc contains the javadoc for the declaring type
+			try {
+				methodDoc = javadocContents.getMethodDoc(this);
+			} catch(JavaModelException e) {
+				javadocContents = null;
+			}
+		}
+		if (methodDoc != null) {
+			final int indexOfOpenParen = methodDoc.indexOf('(');
+			if (indexOfOpenParen != -1) {
+				final int indexOfClosingParen = methodDoc.indexOf(')', indexOfOpenParen);
+				if (indexOfClosingParen != -1) {
+					final char[] paramsSource =
+						CharOperation.replace(
+							methodDoc.substring(indexOfOpenParen + 1, indexOfClosingParen).toCharArray(),
+							"&nbsp;".toCharArray(), //$NON-NLS-1$
+							new char[] {' '});
+					final char[][] params = splitParameters(paramsSource, paramCount);
+					final int paramsLength = params.length;
+					String[] names = new String[paramsLength];
+					for (int i = 0; i < paramsLength; i++) {
+						final char[] param = params[i];
+						int indexOfSpace = CharOperation.lastIndexOf(' ', param);
+						if (indexOfSpace != -1) {
+							names[i] = String.valueOf(param, indexOfSpace + 1, param.length - indexOfSpace -1);
+						} else {
+							names[i] = "arg" + i; //$NON-NLS-1$
+						}
+					}
+					return this.parameterNames = names;
+				}
+			}
+		}
+		// let's see if we can retrieve them from the debug infos
+		char[][] argumentNames = info.getArgumentNames();
+		if (argumentNames != null && argumentNames.length == paramCount) {
+			String[] names = new String[paramCount];
+			for (int i = 0; i < paramCount; i++) {
+				names[i] = new String(argumentNames[i]);
+			}
+			return this.parameterNames = names;
+		}
+	}
+	// If still no parameter names, produce fake ones, but don't cache them (https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671)
+	return getRawParameterNames(paramCount);
+}
+private char[][] splitParameters(char[] parametersSource, int paramCount) {
+	// we have generic types as one of the parameter types
+	char[][] params = new char[paramCount][];
+	int paramIndex = 0;
+	int index = 0;
+	int balance = 0;
+	int length = parametersSource.length;
+	int start = 0;
+	while(index < length) {
+		switch (parametersSource[index]) {
+			case '<':
+				balance++;
+				index++;
+				while(index < length && parametersSource[index] != '>') {
+					index++;
+				}
+				break;
+			case '>' :
+				balance--;
+				index++;
+				break;
+			case ',' :
+				if (balance == 0 && paramIndex < paramCount) {
+					params[paramIndex++] = CharOperation.subarray(parametersSource, start, index);
+					start = index + 1;
+				}
+				index++;
+				break;
+			case '&' :
+				if ((index + 4) < length) {
+					if (parametersSource[index + 1] == 'l'
+							&& parametersSource[index + 2] == 't'
+							&& parametersSource[index + 3] == ';') {
+						balance++;
+						index += 4;
+					} else if (parametersSource[index + 1] == 'g'
+							&& parametersSource[index + 2] == 't'
+							&& parametersSource[index + 3] == ';') {
+						balance--;
+						index += 4;
+					} else {
+						index++;
+					}
+				} else {
+					index++;
+				}
+				break;
+			default:
+				index++;
+		}
+	}
+	if (paramIndex < paramCount) {
+		params[paramIndex++] = CharOperation.subarray(parametersSource, start, index);
+	}
+	if (paramIndex != paramCount) {
+		// happens only for constructors with synthetic enclosing type in the signature
+		System.arraycopy(params, 0, (params = new char[paramIndex][]), 0, paramIndex);
+	}
+	return params;
+}
+/*
+ * @see IMethod
+ */
+public String[] getParameterTypes() {
+	return this.parameterTypes;
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=299384
+private String [] getErasedParameterTypes() {
+	if (this.erasedParamaterTypes == null) {
+		int paramCount = this.parameterTypes.length;
+		String [] erasedTypes = new String [paramCount];
+		boolean erasureNeeded = false;
+		for (int i = 0; i < paramCount; i++) {
+			String parameterType = this.parameterTypes[i];
+			if ((erasedTypes[i] = Signature.getTypeErasure(parameterType)) != parameterType)
+				erasureNeeded = true;
+		}
+		this.erasedParamaterTypes = erasureNeeded ? erasedTypes : this.parameterTypes;
+	}
+	return this.erasedParamaterTypes;
+}
+private String getErasedParameterType(int index) {
+	return getErasedParameterTypes()[index];
+}
+
+public ITypeParameter getTypeParameter(String typeParameterName) {
+	return new TypeParameter(this, typeParameterName);
+}
+
+public ITypeParameter[] getTypeParameters() throws JavaModelException {
+	String[] typeParameterSignatures = getTypeParameterSignatures();
+	int length = typeParameterSignatures.length;
+	if (length == 0) return TypeParameter.NO_TYPE_PARAMETERS;
+	ITypeParameter[] typeParameters = new ITypeParameter[length];
+	for (int i = 0; i < typeParameterSignatures.length; i++) {
+		String typeParameterName = Signature.getTypeVariable(typeParameterSignatures[i]);
+		typeParameters[i] = new TypeParameter(this, typeParameterName);
+	}
+	return typeParameters;
+}
+
+/**
+ * @see IMethod#getTypeParameterSignatures()
+ * @since 3.0
+ * @deprecated
+ */
+public String[] getTypeParameterSignatures() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature == null)
+		return CharOperation.NO_STRINGS;
+	char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
+	char[][] typeParams = Signature.getTypeParameters(dotBasedSignature);
+	return CharOperation.toStrings(typeParams);
+}
+
+public String[] getRawParameterNames() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	int paramCount = Signature.getParameterCount(new String(info.getMethodDescriptor()));
+	return getRawParameterNames(paramCount);
+}
+private String[] getRawParameterNames(int paramCount) {
+	String[] result = new String[paramCount];
+	for (int i = 0; i < paramCount; i++) {
+		result[i] = "arg" + i; //$NON-NLS-1$
+	}
+	return result;
+}
+
+/*
+ * @see IMethod
+ */
+public String getReturnType() throws JavaModelException {
+	if (this.returnType == null) {
+		IBinaryMethod info = (IBinaryMethod) getElementInfo();
+		this.returnType = getReturnType(info);
+	}
+	return this.returnType;
+}
+private String getReturnType(IBinaryMethod info) {
+	char[] genericSignature = info.getGenericSignature();
+	char[] signature = genericSignature == null ? info.getMethodDescriptor() : genericSignature;
+	char[] dotBasedSignature = CharOperation.replaceOnCopy(signature, '/', '.');
+	String returnTypeName= Signature.getReturnType(new String(dotBasedSignature));
+	return new String(ClassFile.translatedName(returnTypeName.toCharArray()));
+}
+/*
+ * @see IMethod
+ */
+public String getSignature() throws JavaModelException {
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	return new String(info.getMethodDescriptor());
+}
+/**
+ * @see org.eclipse.jdt.internal.core.JavaElement#hashCode()
+ */
+public int hashCode() {
+   int hash = super.hashCode();
+	for (int i = 0, length = this.parameterTypes.length; i < length; i++) {
+	    hash = Util.combineHashCodes(hash, getErasedParameterType(i).hashCode());
+	}
+	return hash;
+}
+/*
+ * @see IMethod
+ */
+public boolean isConstructor() throws JavaModelException {
+	if (!getElementName().equals(this.parent.getElementName())) {
+		// faster than reaching the info
+		return false;
+	}
+	IBinaryMethod info = (IBinaryMethod) getElementInfo();
+	return info.isConstructor();
+}
+/*
+ * @see IMethod#isMainMethod()
+ */
+public boolean isMainMethod() throws JavaModelException {
+	return this.isMainMethod(this);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+/*
+ * @see IMethod#isSimilar(IMethod)
+ */
+public boolean isSimilar(IMethod method) {
+	return
+		areSimilarMethods(
+			getElementName(), getParameterTypes(),
+			method.getElementName(), method.getParameterTypes(),
+			null);
+}
+
+public String readableName() {
+
+	StringBuffer buffer = new StringBuffer(super.readableName());
+	buffer.append("("); //$NON-NLS-1$
+	String[] paramTypes = this.parameterTypes;
+	int length;
+	if (paramTypes != null && (length = paramTypes.length) > 0) {
+		for (int i = 0; i < length; i++) {
+			buffer.append(Signature.toString(paramTypes[i]));
+			if (i < length - 1) {
+				buffer.append(", "); //$NON-NLS-1$
+			}
+		}
+	}
+	buffer.append(")"); //$NON-NLS-1$
+	return buffer.toString();
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryMethod(this.parent, this.name, this.parameterTypes, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}/*
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		toStringName(buffer);
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		toStringName(buffer);
+	} else {
+		IBinaryMethod methodInfo = (IBinaryMethod) info;
+		int flags = methodInfo.getModifiers();
+		if (Flags.isStatic(flags)) {
+			buffer.append("static "); //$NON-NLS-1$
+		}
+		if (!methodInfo.isConstructor()) {
+			buffer.append(Signature.toString(getReturnType(methodInfo)));
+			buffer.append(' ');
+		}
+		toStringName(buffer, flags);
+	}
+}
+protected void toStringName(StringBuffer buffer) {
+	toStringName(buffer, 0);
+}
+protected void toStringName(StringBuffer buffer, int flags) {
+	buffer.append(getElementName());
+	buffer.append('(');
+	String[] parameters = getParameterTypes();
+	int length;
+	if (parameters != null && (length = parameters.length) > 0) {
+		boolean isVarargs = Flags.isVarargs(flags);
+		for (int i = 0; i < length; i++) {
+			try {
+				if (i < length - 1) {
+					buffer.append(Signature.toString(parameters[i]));
+					buffer.append(", "); //$NON-NLS-1$
+				} else if (isVarargs) {
+					// remove array from signature
+					String parameter = parameters[i].substring(1);
+					buffer.append(Signature.toString(parameter));
+					buffer.append(" ..."); //$NON-NLS-1$
+				} else {
+					buffer.append(Signature.toString(parameters[i]));
+				}
+			} catch (IllegalArgumentException e) {
+				// parameter signature is malformed
+				buffer.append("*** invalid signature: "); //$NON-NLS-1$
+				buffer.append(parameters[i]);
+			}
+		}
+	}
+	buffer.append(')');
+	if (this.occurrenceCount > 1) {
+		buffer.append("#"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+	}
+}
+public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+	JavadocContents javadocContents = ((BinaryType) this.getDeclaringType()).getJavadocContents(monitor);
+	if (javadocContents == null) return null;
+	return javadocContents.getMethodDoc(this);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
new file mode 100644
index 0000000..b87d99a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
@@ -0,0 +1,1044 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Parent is an IClassFile.
+ *
+ * @see IType
+ */
+
+public class BinaryType extends BinaryMember implements IType, SuffixConstants {
+
+	private static final IField[] NO_FIELDS = new IField[0];
+	private static final IMethod[] NO_METHODS = new IMethod[0];
+	private static final IType[] NO_TYPES = new IType[0];
+	private static final IInitializer[] NO_INITIALIZERS = new IInitializer[0];
+	public static final JavadocContents EMPTY_JAVADOC = new JavadocContents(null, org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING);
+
+protected BinaryType(JavaElement parent, String name) {
+	super(parent, name);
+}
+/*
+ * Remove my cached children from the Java Model
+ */
+protected void closing(Object info) throws JavaModelException {
+	ClassFileInfo cfi = getClassFileInfo();
+	cfi.removeBinaryChildren();
+}
+
+/**
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor)
+ * @deprecated
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+
+/**
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner)
+ * @deprecated
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), owner);
+}
+/*
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor)
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/*
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, IProgressMonitor)
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner)
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, owner, null);
+}
+/*
+ * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner, IProgressMonitor)
+ */
+public void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	JavaProject project = (JavaProject) getJavaProject();
+	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
+	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
+
+	String source = getClassFile().getSource();
+	if (source != null && insertion > -1 && insertion < source.length()) {
+		// code complete
+
+		char[] prefix = CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[]{'{'});
+		char[] suffix =  CharOperation.concat(new char[]{'}'}, source.substring(insertion).toCharArray());
+		char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
+
+		BasicCompilationUnit cu =
+			new BasicCompilationUnit(
+				fakeSource,
+				null,
+				getElementName(),
+				project); // use project to retrieve corresponding .java IFile
+
+		engine.complete(cu, prefix.length + position, prefix.length, null/*extended context isn't computed*/);
+	} else {
+		engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+	}
+	if (NameLookup.VERBOSE) {
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
+
+/*
+ * @see IType#createField(String, IJavaElement, boolean, IProgressMonitor)
+ */
+public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/*
+ * @see IType#createInitializer(String, IJavaElement, IProgressMonitor)
+ */
+public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/*
+ * @see IType#createMethod(String, IJavaElement, boolean, IProgressMonitor)
+ */
+public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/*
+ * @see IType#createType(String, IJavaElement, boolean, IProgressMonitor)
+ */
+public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+public boolean equals(Object o) {
+	if (!(o instanceof BinaryType)) return false;
+	return super.equals(o);
+}
+/*
+ * @see IType#findMethods(IMethod)
+ */
+public IMethod[] findMethods(IMethod method) {
+	try {
+		return findMethods(method, getMethods());
+	} catch (JavaModelException e) {
+		// if type doesn't exist, no matching method can exist
+		return null;
+	}
+}
+public IAnnotation[] getAnnotations() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	IBinaryAnnotation[] binaryAnnotations = info.getAnnotations();
+	return getAnnotations(binaryAnnotations, info.getTagBits());
+}
+/*
+ * @see IParent#getChildren()
+ */
+public IJavaElement[] getChildren() throws JavaModelException {
+	ClassFileInfo cfi = getClassFileInfo();
+	return cfi.binaryChildren;
+}
+public IJavaElement[] getChildrenForCategory(String category) throws JavaModelException {
+	IJavaElement[] children = getChildren();
+	int length = children.length;
+	if (length == 0) return children;
+	SourceMapper mapper= getSourceMapper();
+	if (mapper != null) {
+		// ensure the class file's buffer is open so that categories are computed
+		((ClassFile)getClassFile()).getBuffer();
+
+		HashMap categories = mapper.categories;
+		IJavaElement[] result = new IJavaElement[length];
+		int index = 0;
+		if (categories != null) {
+			for (int i = 0; i < length; i++) {
+				IJavaElement child = children[i];
+				String[] cats = (String[]) categories.get(child);
+				if (cats != null) {
+					for (int j = 0, length2 = cats.length; j < length2; j++) {
+						if (cats[j].equals(category)) {
+							result[index++] = child;
+							break;
+						}
+					}
+				}
+			}
+		}
+		if (index < length)
+			System.arraycopy(result, 0, result = new IJavaElement[index], 0, index);
+		return result;
+	}
+	return NO_ELEMENTS;
+}
+protected ClassFileInfo getClassFileInfo() throws JavaModelException {
+	ClassFile cf = (ClassFile)this.parent;
+	return (ClassFileInfo) cf.getElementInfo();
+}
+/*
+ * @see IMember#getDeclaringType()
+ */
+public IType getDeclaringType() {
+	IClassFile classFile = getClassFile();
+	if (classFile.isOpen()) {
+		try {
+			char[] enclosingTypeName = ((IBinaryType) getElementInfo()).getEnclosingTypeName();
+			if (enclosingTypeName == null) {
+				return null;
+			}
+		 	enclosingTypeName = ClassFile.unqualifiedName(enclosingTypeName);
+
+			// workaround problem with class files compiled with javac 1.1.*
+			// that return a non-null enclosing type name for local types defined in anonymous (e.g. A$1$B)
+			if (classFile.getElementName().length() > enclosingTypeName.length+1
+					&& Character.isDigit(classFile.getElementName().charAt(enclosingTypeName.length+1))) {
+				return null;
+			}
+
+			return getPackageFragment().getClassFile(new String(enclosingTypeName) + SUFFIX_STRING_class).getType();
+		} catch (JavaModelException npe) {
+			return null;
+		}
+	} else {
+		// cannot access .class file without opening it
+		// and getDeclaringType() is supposed to be a handle-only method,
+		// so default to assuming $ is an enclosing type separator
+		String classFileName = classFile.getElementName();
+		int lastDollar = -1;
+		for (int i = 0, length = classFileName.length(); i < length; i++) {
+			char c = classFileName.charAt(i);
+			if (Character.isDigit(c) && lastDollar == i-1) {
+				// anonymous or local type
+				return null;
+			} else if (c == '$') {
+				lastDollar = i;
+			}
+		}
+		if (lastDollar == -1) {
+			return null;
+		} else {
+			String enclosingName = classFileName.substring(0, lastDollar);
+			String enclosingClassFileName = enclosingName + SUFFIX_STRING_class;
+			return
+				new BinaryType(
+					(JavaElement)getPackageFragment().getClassFile(enclosingClassFileName),
+					Util.localTypeName(enclosingName, enclosingName.lastIndexOf('$'), enclosingName.length()));
+		}
+	}
+}
+public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	Object info = manager.getInfo(this);
+	if (info != null && info != JavaModelCache.NON_EXISTING_JAR_TYPE_INFO) return info;
+	return openWhenClosed(createElementInfo(), false, monitor);
+}
+/*
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return TYPE;
+}
+/*
+ * @see IType#getField(String name)
+ */
+public IField getField(String fieldName) {
+	return new BinaryField(this, fieldName);
+}
+/*
+ * @see IType#getFields()
+ */
+public IField[] getFields() throws JavaModelException {
+	ArrayList list = getChildrenOfType(FIELD);
+	int size;
+	if ((size = list.size()) == 0) {
+		return NO_FIELDS;
+	} else {
+		IField[] array= new IField[size];
+		list.toArray(array);
+		return array;
+	}
+}
+/*
+ * @see IMember#getFlags()
+ */
+public int getFlags() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return info.getModifiers() & ~ClassFileConstants.AccSuper;
+}
+/*
+ * @see IType#getFullyQualifiedName()
+ */
+public String getFullyQualifiedName() {
+	return this.getFullyQualifiedName('$');
+}
+/*
+ * @see IType#getFullyQualifiedName(char enclosingTypeSeparator)
+ */
+public String getFullyQualifiedName(char enclosingTypeSeparator) {
+	try {
+		return getFullyQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/);
+	} catch (JavaModelException e) {
+		// exception thrown only when showing parameters
+		return null;
+	}
+}
+
+/*
+ * @see IType#getFullyQualifiedParameterizedName()
+ */
+public String getFullyQualifiedParameterizedName() throws JavaModelException {
+	return getFullyQualifiedName('.', true/*show parameters*/);
+}
+
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_COUNT:
+			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
+		case JEM_FIELD:
+			if (!memento.hasMoreTokens()) return this;
+			String fieldName = memento.nextToken();
+			JavaElement field = (JavaElement)getField(fieldName);
+			return field.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_INITIALIZER:
+			if (!memento.hasMoreTokens()) return this;
+			String count = memento.nextToken();
+			JavaElement initializer = (JavaElement)getInitializer(Integer.parseInt(count));
+			return initializer.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_METHOD:
+			if (!memento.hasMoreTokens()) return this;
+			String selector = memento.nextToken();
+			ArrayList params = new ArrayList();
+			nextParam: while (memento.hasMoreTokens()) {
+				token = memento.nextToken();
+				switch (token.charAt(0)) {
+					case JEM_TYPE:
+					case JEM_TYPE_PARAMETER:
+					case JEM_ANNOTATION:
+						break nextParam;
+					case JEM_METHOD:
+						if (!memento.hasMoreTokens()) return this;
+						String param = memento.nextToken();
+						StringBuffer buffer = new StringBuffer();
+						while (param.length() == 1 && Signature.C_ARRAY == param.charAt(0)) { // backward compatible with 3.0 mementos
+							buffer.append(Signature.C_ARRAY);
+							if (!memento.hasMoreTokens()) return this;
+							param = memento.nextToken();
+						}
+						params.add(buffer.toString() + param);
+						break;
+					default:
+						break nextParam;
+				}
+			}
+			String[] parameters = new String[params.size()];
+			params.toArray(parameters);
+			JavaElement method = (JavaElement)getMethod(selector, parameters);
+			switch (token.charAt(0)) {
+				case JEM_TYPE:
+				case JEM_TYPE_PARAMETER:
+				case JEM_LOCALVARIABLE:
+				case JEM_ANNOTATION:
+					return method.getHandleFromMemento(token, memento, workingCopyOwner);
+				default:
+					return method;
+			}
+		case JEM_TYPE:
+			String typeName;
+			if (memento.hasMoreTokens()) {
+				typeName = memento.nextToken();
+				char firstChar = typeName.charAt(0);
+				if (firstChar == JEM_FIELD || firstChar == JEM_INITIALIZER || firstChar == JEM_METHOD || firstChar == JEM_TYPE || firstChar == JEM_COUNT) {
+					token = typeName;
+					typeName = ""; //$NON-NLS-1$
+				} else {
+					token = null;
+				}
+			} else {
+				typeName = ""; //$NON-NLS-1$
+				token = null;
+			}
+			JavaElement type = (JavaElement)getType(typeName);
+			if (token == null) {
+				return type.getHandleFromMemento(memento, workingCopyOwner);
+			} else {
+				return type.getHandleFromMemento(token, memento, workingCopyOwner);
+			}
+		case JEM_TYPE_PARAMETER:
+			if (!memento.hasMoreTokens()) return this;
+			String typeParameterName = memento.nextToken();
+			JavaElement typeParameter = new TypeParameter(this, typeParameterName);
+			return typeParameter.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_ANNOTATION:
+			if (!memento.hasMoreTokens()) return this;
+			String annotationName = memento.nextToken();
+			JavaElement annotation = new Annotation(this, annotationName);
+			return annotation.getHandleFromMemento(memento, workingCopyOwner);
+	}
+	return null;
+}
+/*
+ * @see IType#getInitializer(int occurrenceCount)
+ */
+public IInitializer getInitializer(int count) {
+	return new Initializer(this, count);
+}
+/*
+ * @see IType#getInitializers()
+ */
+public IInitializer[] getInitializers() {
+	return NO_INITIALIZERS;
+}
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, forceOpen);
+}
+/*
+ * @see IType#getMethod(String name, String[] parameterTypeSignatures)
+ */
+public IMethod getMethod(String selector, String[] parameterTypeSignatures) {
+	return new BinaryMethod(this, selector, parameterTypeSignatures);
+}
+/*
+ * @see IType#getMethods()
+ */
+public IMethod[] getMethods() throws JavaModelException {
+	ArrayList list = getChildrenOfType(METHOD);
+	int size;
+	if ((size = list.size()) == 0) {
+		return NO_METHODS;
+	} else {
+		IMethod[] array= new IMethod[size];
+		list.toArray(array);
+		return array;
+	}
+}
+/*
+ * @see IType#getPackageFragment()
+ */
+public IPackageFragment getPackageFragment() {
+	IJavaElement parentElement = this.parent;
+	while (parentElement != null) {
+		if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+			return (IPackageFragment)parentElement;
+		}
+		else {
+			parentElement = parentElement.getParent();
+		}
+	}
+	Assert.isTrue(false);  // should not happen
+	return null;
+}
+
+/**
+ * @see IType#getSuperclassTypeSignature()
+ * @since 3.0
+ */
+public String getSuperclassTypeSignature() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature != null) {
+		int signatureLength = genericSignature.length;
+		// skip type parameters
+		int index = 0;
+		if (genericSignature[0] == '<') {
+			int count = 1;
+			while (count > 0 && ++index < signatureLength) {
+				switch (genericSignature[index]) {
+					case '<':
+						count++;
+						break;
+					case '>':
+						count--;
+						break;
+				}
+			}
+			index++;
+		}
+		int start = index;
+		index = org.eclipse.jdt.internal.compiler.util.Util.scanClassTypeSignature(genericSignature, start) + 1;
+		char[] superclassSig = CharOperation.subarray(genericSignature, start, index);
+		return new String(ClassFile.translatedName(superclassSig));
+	} else {
+		char[] superclassName = info.getSuperclassName();
+		if (superclassName == null) {
+			return null;
+		}
+		return new String(Signature.createTypeSignature(ClassFile.translatedName(superclassName), true));
+	}
+}
+
+public String getSourceFileName(IBinaryType info) {
+	if (info == null) {
+		try {
+			info = (IBinaryType) getElementInfo();
+		} catch (JavaModelException e) {
+			// default to using the outer most declaring type name
+			IType type = this;
+			IType enclosingType = getDeclaringType();
+			while (enclosingType != null) {
+				type = enclosingType;
+				enclosingType = type.getDeclaringType();
+			}
+			return type.getElementName() + Util.defaultJavaExtension();
+		}
+	}
+	return sourceFileName(info);
+}
+
+/*
+ * @see IType#getSuperclassName()
+ */
+public String getSuperclassName() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	char[] superclassName = info.getSuperclassName();
+	if (superclassName == null) {
+		return null;
+	}
+	return new String(ClassFile.translatedName(superclassName));
+}
+/*
+ * @see IType#getSuperInterfaceNames()
+ */
+public String[] getSuperInterfaceNames() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	char[][] names= info.getInterfaceNames();
+	int length;
+	if (names == null || (length = names.length) == 0) {
+		return CharOperation.NO_STRINGS;
+	}
+	names= ClassFile.translatedNames(names);
+	String[] strings= new String[length];
+	for (int i= 0; i < length; i++) {
+		strings[i]= new String(names[i]);
+	}
+	return strings;
+}
+
+/**
+ * @see IType#getSuperInterfaceTypeSignatures()
+ * @since 3.0
+ */
+public String[] getSuperInterfaceTypeSignatures() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature != null) {
+		ArrayList interfaces = new ArrayList();
+		int signatureLength = genericSignature.length;
+		// skip type parameters
+		int index = 0;
+		if (genericSignature[0] == '<') {
+			int count = 1;
+			while (count > 0 && ++index < signatureLength) {
+				switch (genericSignature[index]) {
+					case '<':
+						count++;
+						break;
+					case '>':
+						count--;
+						break;
+				}
+			}
+			index++;
+		}
+		// skip superclass
+		index = org.eclipse.jdt.internal.compiler.util.Util.scanClassTypeSignature(genericSignature, index) + 1;
+		while (index  < signatureLength) {
+			int start = index;
+			index = org.eclipse.jdt.internal.compiler.util.Util.scanClassTypeSignature(genericSignature, start) + 1;
+			char[] interfaceSig = CharOperation.subarray(genericSignature, start, index);
+			interfaces.add(new String(ClassFile.translatedName(interfaceSig)));
+		}
+		int size = interfaces.size();
+		String[] result = new String[size];
+		interfaces.toArray(result);
+		return result;
+	} else {
+		char[][] names= info.getInterfaceNames();
+		int length;
+		if (names == null || (length = names.length) == 0) {
+			return CharOperation.NO_STRINGS;
+		}
+		names= ClassFile.translatedNames(names);
+		String[] strings= new String[length];
+		for (int i= 0; i < length; i++) {
+			strings[i]= new String(Signature.createTypeSignature(names[i], true));
+		}
+		return strings;
+	}
+}
+
+public ITypeParameter[] getTypeParameters() throws JavaModelException {
+	String[] typeParameterSignatures = getTypeParameterSignatures();
+	int length = typeParameterSignatures.length;
+	if (length == 0) return TypeParameter.NO_TYPE_PARAMETERS;
+	ITypeParameter[] typeParameters = new ITypeParameter[length];
+	for (int i = 0; i < typeParameterSignatures.length; i++) {
+		String typeParameterName = Signature.getTypeVariable(typeParameterSignatures[i]);
+		typeParameters[i] = new TypeParameter(this, typeParameterName);
+	}
+	return typeParameters;
+}
+
+/**
+ * @see IType#getTypeParameterSignatures()
+ * @since 3.0
+ */
+public String[] getTypeParameterSignatures() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature == null)
+		return CharOperation.NO_STRINGS;
+
+	char[] dotBaseSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
+	char[][] typeParams = Signature.getTypeParameters(dotBaseSignature);
+	return CharOperation.toStrings(typeParams);
+}
+
+/*
+ * @see IType#getType(String)
+ */
+public IType getType(String typeName) {
+	IClassFile classFile= getPackageFragment().getClassFile(getTypeQualifiedName() + "$" + typeName + SUFFIX_STRING_class); //$NON-NLS-1$
+	return new BinaryType((JavaElement)classFile, typeName);
+}
+public ITypeParameter getTypeParameter(String typeParameterName) {
+	return new TypeParameter(this, typeParameterName);
+}
+/*
+ * @see IType#getTypeQualifiedName()
+ */
+public String getTypeQualifiedName() {
+	return this.getTypeQualifiedName('$');
+}
+/*
+ * @see IType#getTypeQualifiedName(char)
+ */
+public String getTypeQualifiedName(char enclosingTypeSeparator) {
+	try {
+		return getTypeQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/);
+	} catch (JavaModelException e) {
+		// exception thrown only when showing parameters
+		return null;
+	}
+}
+/*
+ * @see IType#getTypes()
+ */
+public IType[] getTypes() throws JavaModelException {
+	ArrayList list = getChildrenOfType(TYPE);
+	int size;
+	if ((size = list.size()) == 0) {
+		return NO_TYPES;
+	} else {
+		IType[] array= new IType[size];
+		list.toArray(array);
+		return array;
+	}
+}
+
+/*
+ * @see IType#isAnonymous()
+ */
+public boolean isAnonymous() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return info.isAnonymous();
+}
+/*
+ * @see IType#isClass()
+ */
+public boolean isClass() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.CLASS_DECL;
+
+}
+
+/**
+ * @see IType#isEnum()
+ * @since 3.0
+ */
+public boolean isEnum() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ENUM_DECL;
+}
+
+/*
+ * @see IType#isInterface()
+ */
+public boolean isInterface() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	switch (TypeDeclaration.kind(info.getModifiers())) {
+		case TypeDeclaration.INTERFACE_DECL:
+		case TypeDeclaration.ANNOTATION_TYPE_DECL: // annotation is interface too
+			return true;
+	}
+	return false;
+}
+/**
+ * @see IType#isAnnotation()
+ * @since 3.0
+ */
+public boolean isAnnotation() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ANNOTATION_TYPE_DECL;
+}
+
+/*
+ * @see IType#isLocal()
+ */
+public boolean isLocal() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return info.isLocal();
+}
+/*
+ * @see IType#isMember()
+ */
+public boolean isMember() throws JavaModelException {
+	IBinaryType info = (IBinaryType) getElementInfo();
+	return info.isMember();
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+/*
+ * @see IType
+ */
+public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException {
+	return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType
+ */
+public ITypeHierarchy loadTypeHierachy(InputStream input, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	return TypeHierarchy.load(this, input, owner);
+}
+/*
+ * @see IType#newSupertypeHierarchy(IProgressMonitor monitor)
+ */
+public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
+	return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ *@see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor monitor)
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	ICompilationUnit[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @param workingCopies the working copies that take precedence over their original compilation units
+ * @param monitor the given progress monitor
+ * @return a type hierarchy for this type containing this type and all of its supertypes
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ *
+ * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
+ * @deprecated
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	IWorkingCopy[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] copies;
+	if (workingCopies == null) {
+		copies = null;
+	} else {
+		int length = workingCopies.length;
+		System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
+	}
+	return newSupertypeHierarchy(copies, monitor);
+}
+/*
+ * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	WorkingCopyOwner owner,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/*
+ * @see IType#newTypeHierarchy(IJavaProject, IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException {
+	return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	if (project == null) {
+		throw new IllegalArgumentException(Messages.hierarchy_nullProject);
+	}
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	ICompilationUnit[] projectWCs = null;
+	if (workingCopies != null) {
+		int length = workingCopies.length;
+		projectWCs = new ICompilationUnit[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			ICompilationUnit wc = workingCopies[i];
+			if (project.equals(wc.getJavaProject())) {
+				projectWCs[index++] = wc;
+			}
+		}
+		if (index != length) {
+			System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index], 0, index);
+		}
+	}
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
+		this,
+		projectWCs,
+		project,
+		true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @param monitor the given progress monitor
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @return a type hierarchy for this type containing
+ *
+ * @see IType#newTypeHierarchy(IProgressMonitor monitor)
+ * @deprecated
+ */
+public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=228845, consider any
+	// changes that may exist on primary working copies.
+	return newTypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(
+	ICompilationUnit[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
+ * @deprecated
+ */
+public ITypeHierarchy newTypeHierarchy(
+	IWorkingCopy[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] copies;
+	if (workingCopies == null) {
+		copies = null;
+	} else {
+		int length = workingCopies.length;
+		System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
+	}
+	return newTypeHierarchy(copies, monitor);
+}
+/*
+ * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(
+	WorkingCopyOwner owner,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryType(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
+/*
+ * Returns the source file name as defined in the given info.
+ * If not present in the info, infers it from this type.
+ */
+public String sourceFileName(IBinaryType info) {
+	char[] sourceFileName = info.sourceFileName();
+	if (sourceFileName == null) {
+		/*
+		 * We assume that this type has been compiled from a file with its name
+		 * For example, A.class comes from A.java and p.A.class comes from a file A.java
+		 * in the folder p.
+		 */
+		if (info.isMember()) {
+			IType enclosingType = getDeclaringType();
+			if (enclosingType == null) return null; // play it safe
+			while (enclosingType.getDeclaringType() != null) {
+				enclosingType = enclosingType.getDeclaringType();
+			}
+			return enclosingType.getElementName() + Util.defaultJavaExtension();
+		} else if (info.isLocal() || info.isAnonymous()){
+			String typeQualifiedName = getTypeQualifiedName();
+			int dollar = typeQualifiedName.indexOf('$');
+			if (dollar == -1) {
+				// malformed inner type: name doesn't contain a dollar
+				return getElementName() + Util.defaultJavaExtension();
+			}
+			return typeQualifiedName.substring(0, dollar) + Util.defaultJavaExtension();
+		} else {
+			return getElementName() + Util.defaultJavaExtension();
+		}
+	} else {
+		int index = CharOperation.lastIndexOf('/', sourceFileName);
+		return new String(sourceFileName, index + 1, sourceFileName.length - index - 1);
+	}
+}
+/*
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		toStringName(buffer);
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		toStringName(buffer);
+	} else {
+		try {
+			if (isAnnotation()) {
+				buffer.append("@interface "); //$NON-NLS-1$
+			} else if (isEnum()) {
+				buffer.append("enum "); //$NON-NLS-1$
+			} else if (isInterface()) {
+				buffer.append("interface "); //$NON-NLS-1$
+			} else {
+				buffer.append("class "); //$NON-NLS-1$
+			}
+			toStringName(buffer);
+		} catch (JavaModelException e) {
+			buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
+		}
+	}
+}
+protected void toStringName(StringBuffer buffer) {
+	if (getElementName().length() > 0)
+		super.toStringName(buffer);
+	else
+		buffer.append("<anonymous>"); //$NON-NLS-1$
+}
+public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+	JavadocContents javadocContents = getJavadocContents(monitor);
+	if (javadocContents == null) return null;
+	return javadocContents.getTypeDoc();
+}
+public JavadocContents getJavadocContents(IProgressMonitor monitor) throws JavaModelException {
+	PerProjectInfo projectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject());
+	JavadocContents cachedJavadoc = null;
+	synchronized (projectInfo.javadocCache) {
+		cachedJavadoc = (JavadocContents) projectInfo.javadocCache.get(this);
+	}
+	
+	if (cachedJavadoc != null && cachedJavadoc != EMPTY_JAVADOC) {
+		return cachedJavadoc;
+	}
+	URL baseLocation= getJavadocBaseLocation();
+	if (baseLocation == null) {
+		return null;
+	}
+	StringBuffer pathBuffer = new StringBuffer(baseLocation.toExternalForm());
+
+	if (!(pathBuffer.charAt(pathBuffer.length() - 1) == '/')) {
+		pathBuffer.append('/');
+	}
+	IPackageFragment pack= getPackageFragment();
+	String typeQualifiedName = null;
+	if (isMember()) {
+		IType currentType = this;
+		StringBuffer typeName = new StringBuffer();
+		while (currentType != null) {
+			typeName.insert(0, currentType.getElementName());
+			currentType = currentType.getDeclaringType();
+			if (currentType != null) {
+				typeName.insert(0, '.');
+			}
+		}
+		typeQualifiedName = new String(typeName.toString());
+	} else {
+		typeQualifiedName = getElementName();
+	}
+
+	pathBuffer.append(pack.getElementName().replace('.', '/')).append('/').append(typeQualifiedName).append(JavadocConstants.HTML_EXTENSION);
+	if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+	final String contents = getURLContents(String.valueOf(pathBuffer));
+	JavadocContents javadocContents = new JavadocContents(this, contents);
+	synchronized (projectInfo.javadocCache) {
+		projectInfo.javadocCache.put(this, javadocContents);
+	}
+	return javadocContents;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java
new file mode 100644
index 0000000..e56e4ae
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - TypeConverters don't set enclosingType - https://bugs.eclipse.org/bugs/show_bug.cgi?id=320841
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.parser.TypeConverter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.util.HashSetOfCharArrayArray;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Converter from a binary type to an AST type declaration.
+ */
+public class BinaryTypeConverter extends TypeConverter {
+
+	private CompilationResult compilationResult;
+	private HashSetOfCharArrayArray typeNames;
+
+	public BinaryTypeConverter(ProblemReporter problemReporter, CompilationResult compilationResult, HashSetOfCharArrayArray typeNames) {
+		super(problemReporter, Signature.C_DOLLAR);
+		this.compilationResult = compilationResult;
+		this.typeNames = typeNames;
+	}
+
+	public ImportReference[] buildImports(ClassFileReader reader) {
+		// add remaining references to the list of type names
+		// (code extracted from BinaryIndexer#extractReferenceFromConstantPool(...))
+		int[] constantPoolOffsets = reader.getConstantPoolOffsets();
+		int constantPoolCount = constantPoolOffsets.length;
+		for (int i = 0; i < constantPoolCount; i++) {
+			int tag = reader.u1At(constantPoolOffsets[i]);
+			char[] name = null;
+			switch (tag) {
+				case ClassFileConstants.MethodRefTag :
+				case ClassFileConstants.InterfaceMethodRefTag :
+					int constantPoolIndex = reader.u2At(constantPoolOffsets[i] + 3);
+					int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[constantPoolIndex] + 3)];
+					name = reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+					break;
+				case ClassFileConstants.ClassTag :
+					utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[i] + 1)];
+					name = reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+					break;
+			}
+			if (name == null || (name.length > 0 && name[0] == '['))
+				break; // skip over array references
+			this.typeNames.add(CharOperation.splitOn('/', name));
+		}
+
+		// convert type names into import references
+		int typeNamesLength = this.typeNames.size();
+		ImportReference[] imports = new ImportReference[typeNamesLength];
+		char[][][] set = this.typeNames.set;
+		int index = 0;
+		for (int i = 0, length = set.length; i < length; i++) {
+			char[][] typeName = set[i];
+			if (typeName != null) {
+				imports[index++] = new ImportReference(typeName, new long[typeName.length]/*dummy positions*/, false/*not on demand*/, 0);
+			}
+		}
+		return imports;
+	}
+
+	/**
+	 * Convert a binary type into an AST type declaration and put it in the given compilation unit.
+	 */
+	public TypeDeclaration buildTypeDeclaration(IType type, CompilationUnitDeclaration compilationUnit)  throws JavaModelException {
+		PackageFragment pkg = (PackageFragment) type.getPackageFragment();
+		char[][] packageName = Util.toCharArrays(pkg.names);
+
+		if (packageName.length > 0) {
+			compilationUnit.currentPackage = new ImportReference(packageName, new long[]{0}, false, ClassFileConstants.AccDefault);
+		}
+
+		/* convert type */
+		TypeDeclaration typeDeclaration = convert(type, null, null);
+
+		IType alreadyComputedMember = type;
+		IType parent = type.getDeclaringType();
+		TypeDeclaration previousDeclaration = typeDeclaration;
+		while(parent != null) {
+			TypeDeclaration declaration = convert(parent, alreadyComputedMember, previousDeclaration);
+
+			alreadyComputedMember = parent;
+			previousDeclaration = declaration;
+			parent = parent.getDeclaringType();
+		}
+
+		compilationUnit.types = new TypeDeclaration[]{previousDeclaration};
+
+		return typeDeclaration;
+	}
+
+	private FieldDeclaration convert(IField field, IType type) throws JavaModelException {
+		TypeReference typeReference = createTypeReference(field.getTypeSignature());
+		if (typeReference == null) return null;
+		FieldDeclaration fieldDeclaration = new FieldDeclaration();
+
+		fieldDeclaration.name = field.getElementName().toCharArray();
+		fieldDeclaration.type = typeReference;
+		fieldDeclaration.modifiers = field.getFlags();
+
+		return fieldDeclaration;
+	}
+
+	private AbstractMethodDeclaration convert(IMethod method, IType type) throws JavaModelException {
+
+		AbstractMethodDeclaration methodDeclaration;
+
+		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParams = null;
+
+		// convert 1.5 specific constructs only if compliance is 1.5 or above
+		if (this.has1_5Compliance) {
+			/* convert type parameters */
+			ITypeParameter[] typeParameters = method.getTypeParameters();
+			if (typeParameters != null && typeParameters.length > 0) {
+				int parameterCount = typeParameters.length;
+				typeParams = new org.eclipse.jdt.internal.compiler.ast.TypeParameter[parameterCount];
+				for (int i = 0; i < parameterCount; i++) {
+					ITypeParameter typeParameter = typeParameters[i];
+					typeParams[i] =
+						createTypeParameter(
+								typeParameter.getElementName().toCharArray(),
+								stringArrayToCharArray(typeParameter.getBounds()),
+								0,
+								0);
+				}
+			}
+		}
+
+		if (method.isConstructor()) {
+			ConstructorDeclaration decl = new ConstructorDeclaration(this.compilationResult);
+			decl.bits &= ~ASTNode.IsDefaultConstructor;
+			decl.typeParameters = typeParams;
+			methodDeclaration = decl;
+		} else {
+			MethodDeclaration decl = type.isAnnotation() ? new AnnotationMethodDeclaration(this.compilationResult) : new MethodDeclaration(this.compilationResult);
+			/* convert return type */
+			TypeReference typeReference = createTypeReference(method.getReturnType());
+			if (typeReference == null) return null;
+			decl.returnType = typeReference;
+			decl.typeParameters = typeParams;
+			methodDeclaration = decl;
+		}
+		methodDeclaration.selector = method.getElementName().toCharArray();
+		int flags = method.getFlags();
+		boolean isVarargs = Flags.isVarargs(flags);
+		methodDeclaration.modifiers = flags & ~Flags.AccVarargs;
+
+		/* convert arguments */
+		String[] argumentTypeNames = method.getParameterTypes();
+		String[] argumentNames = method.getParameterNames();
+		int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
+		// Ignore synthetic arguments (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212224)
+		int startIndex = (method.isConstructor() && type.isMember() && !Flags.isStatic(type.getFlags())) ? 1 : 0;
+		argumentCount -= startIndex;
+		methodDeclaration.arguments = new Argument[argumentCount];
+		for (int i = 0; i < argumentCount; i++) {
+			String argumentTypeName = argumentTypeNames[startIndex+i];
+			TypeReference typeReference = createTypeReference(argumentTypeName);
+			if (typeReference == null) return null;
+			if (isVarargs && i == argumentCount-1) {
+				typeReference.bits |= ASTNode.IsVarArgs;
+			}
+			methodDeclaration.arguments[i] = new Argument(
+				argumentNames[i].toCharArray(),
+				0,
+				typeReference,
+				ClassFileConstants.AccDefault);
+			// do not care whether was final or not
+		}
+
+		/* convert thrown exceptions */
+		String[] exceptionTypeNames = method.getExceptionTypes();
+		int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
+		if(exceptionCount > 0) {
+			methodDeclaration.thrownExceptions = new TypeReference[exceptionCount];
+			for (int i = 0; i < exceptionCount; i++) {
+				TypeReference typeReference = createTypeReference(exceptionTypeNames[i]);
+				if (typeReference == null) return null;
+				methodDeclaration.thrownExceptions[i] = typeReference;
+			}
+		}
+		return methodDeclaration;
+	}
+
+	private TypeDeclaration convert(IType type, IType alreadyComputedMember,TypeDeclaration alreadyComputedMemberDeclaration) throws JavaModelException {
+		/* create type declaration - can be member type */
+		TypeDeclaration typeDeclaration = new TypeDeclaration(this.compilationResult);
+
+		if (type.getDeclaringType() != null) {
+			typeDeclaration.bits |= ASTNode.IsMemberType;
+		}
+		typeDeclaration.name = type.getElementName().toCharArray();
+		typeDeclaration.modifiers = type.getFlags();
+
+
+		/* set superclass and superinterfaces */
+		if (type.getSuperclassName() != null) {
+			TypeReference typeReference = createTypeReference(type.getSuperclassTypeSignature());
+			if (typeReference != null) {
+				typeDeclaration.superclass = typeReference;
+				typeDeclaration.superclass.bits |= ASTNode.IsSuperType;
+			}
+		}
+
+		String[] interfaceTypes = type.getSuperInterfaceTypeSignatures();
+		int interfaceCount = interfaceTypes == null ? 0 : interfaceTypes.length;
+		typeDeclaration.superInterfaces = new TypeReference[interfaceCount];
+		int count = 0;
+		for (int i = 0; i < interfaceCount; i++) {
+			TypeReference typeReference = createTypeReference(interfaceTypes[i]);
+			if (typeReference != null) {
+				typeDeclaration.superInterfaces[count] = typeReference;
+				typeDeclaration.superInterfaces[count++].bits |= ASTNode.IsSuperType;
+			}
+		}
+		if (count != interfaceCount) {
+			System.arraycopy(typeDeclaration.fields, 0, typeDeclaration.superInterfaces = new TypeReference[interfaceCount], 0, interfaceCount);
+		}
+
+		// convert 1.5 specific constructs only if compliance is 1.5 or above
+		if (this.has1_5Compliance) {
+
+			/* convert type parameters */
+			ITypeParameter[] typeParameters = type.getTypeParameters();
+			if (typeParameters != null && typeParameters.length > 0) {
+				int parameterCount = typeParameters.length;
+				org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParams = new org.eclipse.jdt.internal.compiler.ast.TypeParameter[parameterCount];
+				for (int i = 0; i < parameterCount; i++) {
+					ITypeParameter typeParameter = typeParameters[i];
+					typeParams[i] =
+						createTypeParameter(
+								typeParameter.getElementName().toCharArray(),
+								stringArrayToCharArray(typeParameter.getBounds()),
+								0,
+								0);
+				}
+
+				typeDeclaration.typeParameters = typeParams;
+			}
+		}
+
+		/* convert member types */
+		IType[] memberTypes = type.getTypes();
+		int memberTypeCount =	memberTypes == null ? 0 : memberTypes.length;
+		typeDeclaration.memberTypes = new TypeDeclaration[memberTypeCount];
+		for (int i = 0; i < memberTypeCount; i++) {
+			if(alreadyComputedMember != null && alreadyComputedMember.getFullyQualifiedName().equals(memberTypes[i].getFullyQualifiedName())) {
+				typeDeclaration.memberTypes[i] = alreadyComputedMemberDeclaration;
+			} else {
+				typeDeclaration.memberTypes[i] = convert(memberTypes[i], null, null);
+			}
+			typeDeclaration.memberTypes[i].enclosingType = typeDeclaration;
+		}
+
+		/* convert fields */
+		IField[] fields = type.getFields();
+		int fieldCount = fields == null ? 0 : fields.length;
+		typeDeclaration.fields = new FieldDeclaration[fieldCount];
+		count = 0;
+		for (int i = 0; i < fieldCount; i++) {
+			FieldDeclaration fieldDeclaration = convert(fields[i], type);
+			if (fieldDeclaration != null) {
+				typeDeclaration.fields[count++] = fieldDeclaration;
+			}
+		}
+		if (count != fieldCount) {
+			System.arraycopy(typeDeclaration.fields, 0, typeDeclaration.fields = new FieldDeclaration[count], 0, count);
+		}
+
+		/* convert methods - need to add default constructor if necessary */
+		IMethod[] methods = type.getMethods();
+		int methodCount = methods == null ? 0 : methods.length;
+
+		/* source type has a constructor ?           */
+		/* by default, we assume that one is needed. */
+		int neededCount = 1;
+		for (int i = 0; i < methodCount; i++) {
+			if (methods[i].isConstructor()) {
+				neededCount = 0;
+				// Does not need the extra constructor since one constructor already exists.
+				break;
+			}
+		}
+		boolean isInterface = type.isInterface();
+		neededCount = isInterface ? 0 : neededCount;
+		typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount];
+		if (neededCount != 0) { // add default constructor in first position
+			typeDeclaration.methods[0] = typeDeclaration.createDefaultConstructor(false, false);
+		}
+		boolean hasAbstractMethods = false;
+		count = 0;
+		for (int i = 0; i < methodCount; i++) {
+			AbstractMethodDeclaration method = convert(methods[i], type);
+			if (method != null) {
+				boolean isAbstract;
+				if ((isAbstract = method.isAbstract()) || isInterface) { // fix-up flag
+					method.modifiers |= ExtraCompilerModifiers.AccSemicolonBody;
+				}
+				if (isAbstract) {
+					hasAbstractMethods = true;
+				}
+				typeDeclaration.methods[neededCount + (count++)] = method;
+			}
+		}
+		if (count != methodCount) {
+			System.arraycopy(typeDeclaration.methods, 0, typeDeclaration.methods = new AbstractMethodDeclaration[count + neededCount], 0, count + neededCount);
+		}
+		if (hasAbstractMethods) {
+			typeDeclaration.bits |= ASTNode.HasAbstractMethods;
+		}
+		return typeDeclaration;
+	}
+
+	private static char[][] stringArrayToCharArray(String[] strings) {
+		if (strings == null) return null;
+
+		int length = strings.length;
+		if (length == 0) return CharOperation.NO_CHAR_CHAR;
+
+		char[][] result = new char [length][];
+		for (int i = 0; i < length; i++) {
+			result[i] = strings[i].toCharArray();
+		}
+
+		return result;
+	}
+
+	private TypeReference createTypeReference(String typeSignature) {
+		TypeReference result = createTypeReference(typeSignature, 0, 0);
+		if (this.typeNames != null && result instanceof QualifiedTypeReference) {
+			this.typeNames.add(((QualifiedTypeReference)result).tokens);
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java
new file mode 100644
index 0000000..4740662
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java
@@ -0,0 +1,479 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Tim Hanson (thanson@bea.com) - patch for https://bugs.eclipse.org/bugs/show_bug.cgi?id=126673
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IBuffer
+ */
+public class Buffer implements IBuffer {
+	protected IFile file;
+	protected int flags;
+	protected char[] contents;
+	protected ArrayList changeListeners;
+	protected IOpenable owner;
+	protected int gapStart = -1;
+	protected int gapEnd = -1;
+
+	protected Object lock = new Object();
+
+	protected static final int F_HAS_UNSAVED_CHANGES = 1;
+	protected static final int F_IS_READ_ONLY = 2;
+	protected static final int F_IS_CLOSED = 4;
+
+/**
+ * Creates a new buffer on an underlying resource.
+ */
+protected Buffer(IFile file, IOpenable owner, boolean readOnly) {
+	this.file = file;
+	this.owner = owner;
+	if (file == null) {
+		setReadOnly(readOnly);
+	}
+}
+/**
+ * @see IBuffer
+ */
+public synchronized void addBufferChangedListener(IBufferChangedListener listener) {
+	if (this.changeListeners == null) {
+		this.changeListeners = new ArrayList(5);
+	}
+	if (!this.changeListeners.contains(listener)) {
+		this.changeListeners.add(listener);
+	}
+}
+/**
+ * Append the <code>text</code> to the actual content, the gap is moved
+ * to the end of the <code>text</code>.
+ */
+public void append(char[] text) {
+	if (!isReadOnly()) {
+		if (text == null || text.length == 0) {
+			return;
+		}
+		int length = getLength();
+		synchronized(this.lock) {
+			if (this.contents == null) return;
+			moveAndResizeGap(length, text.length);
+			System.arraycopy(text, 0, this.contents, length, text.length);
+			this.gapStart += text.length;
+			this.flags |= F_HAS_UNSAVED_CHANGES;
+		}
+		notifyChanged(new BufferChangedEvent(this, length, 0, new String(text)));
+	}
+}
+/**
+ * Append the <code>text</code> to the actual content, the gap is moved
+ * to the end of the <code>text</code>.
+ */
+public void append(String text) {
+	if (text == null) {
+		return;
+	}
+	this.append(text.toCharArray());
+}
+/**
+ * @see IBuffer
+ */
+public void close() {
+	BufferChangedEvent event = null;
+	synchronized (this.lock) {
+		if (isClosed())
+			return;
+		event = new BufferChangedEvent(this, 0, 0, null);
+		this.contents = null;
+		this.flags |= F_IS_CLOSED;
+	}
+	notifyChanged(event); // notify outside of synchronized block
+	synchronized(this) { // ensure that no other thread is adding/removing a listener at the same time (https://bugs.eclipse.org/bugs/show_bug.cgi?id=126673)
+		this.changeListeners = null;
+	}
+}
+/**
+ * @see IBuffer
+ */
+public char getChar(int position) {
+	synchronized (this.lock) {
+	    if (this.contents == null) return Character.MIN_VALUE;
+		if (position < this.gapStart) {
+			return this.contents[position];
+		}
+		int gapLength = this.gapEnd - this.gapStart;
+		return this.contents[position + gapLength];
+	}
+}
+/**
+ * @see IBuffer
+ */
+public char[] getCharacters() {
+	synchronized (this.lock) {
+		if (this.contents == null) return null;
+		if (this.gapStart < 0) {
+			return this.contents;
+		}
+		int length = this.contents.length;
+		char[] newContents = new char[length - this.gapEnd + this.gapStart];
+		System.arraycopy(this.contents, 0, newContents, 0, this.gapStart);
+		System.arraycopy(this.contents, this.gapEnd, newContents, this.gapStart, length - this.gapEnd);
+		return newContents;
+	}
+}
+/**
+ * @see IBuffer
+ */
+public String getContents() {
+	char[] chars = getCharacters();
+	if (chars == null) return null;
+	return new String(chars);
+}
+/**
+ * @see IBuffer
+ */
+public int getLength() {
+	synchronized (this.lock) {
+		if (this.contents == null) return -1;
+		int length = this.gapEnd - this.gapStart;
+		return (this.contents.length - length);
+	}
+}
+/**
+ * @see IBuffer
+ */
+public IOpenable getOwner() {
+	return this.owner;
+}
+/**
+ * @see IBuffer
+ */
+public String getText(int offset, int length) {
+	synchronized (this.lock) {
+		if (this.contents == null) return ""; //$NON-NLS-1$
+		if (offset + length < this.gapStart)
+			return new String(this.contents, offset, length);
+		if (this.gapStart < offset) {
+			int gapLength = this.gapEnd - this.gapStart;
+			return new String(this.contents, offset + gapLength, length);
+		}
+		StringBuffer buf = new StringBuffer();
+		buf.append(this.contents, offset, this.gapStart - offset);
+		buf.append(this.contents, this.gapEnd, offset + length - this.gapStart);
+		return buf.toString();
+	}
+}
+/**
+ * @see IBuffer
+ */
+public IResource getUnderlyingResource() {
+	return this.file;
+}
+/**
+ * @see IBuffer
+ */
+public boolean hasUnsavedChanges() {
+	return (this.flags & F_HAS_UNSAVED_CHANGES) != 0;
+}
+/**
+ * @see IBuffer
+ */
+public boolean isClosed() {
+	return (this.flags & F_IS_CLOSED) != 0;
+}
+/**
+ * @see IBuffer
+ */
+public boolean isReadOnly() {
+	return (this.flags & F_IS_READ_ONLY) != 0;
+}
+/**
+ * Moves the gap to location and adjust its size to the
+ * anticipated change size. The size represents the expected
+ * range of the gap that will be filled after the gap has been moved.
+ * Thus the gap is resized to actual size + the specified size and
+ * moved to the given position.
+ */
+protected void moveAndResizeGap(int position, int size) {
+	char[] content = null;
+	int oldSize = this.gapEnd - this.gapStart;
+	if (size < 0) {
+		if (oldSize > 0) {
+			content = new char[this.contents.length - oldSize];
+			System.arraycopy(this.contents, 0, content, 0, this.gapStart);
+			System.arraycopy(this.contents, this.gapEnd, content, this.gapStart, content.length - this.gapStart);
+			this.contents = content;
+		}
+		this.gapStart = this.gapEnd = position;
+		return;
+	}
+	content = new char[this.contents.length + (size - oldSize)];
+	int newGapStart = position;
+	int newGapEnd = newGapStart + size;
+	if (oldSize == 0) {
+		System.arraycopy(this.contents, 0, content, 0, newGapStart);
+		System.arraycopy(this.contents, newGapStart, content, newGapEnd, content.length - newGapEnd);
+	} else
+		if (newGapStart < this.gapStart) {
+			int delta = this.gapStart - newGapStart;
+			System.arraycopy(this.contents, 0, content, 0, newGapStart);
+			System.arraycopy(this.contents, newGapStart, content, newGapEnd, delta);
+			System.arraycopy(this.contents, this.gapEnd, content, newGapEnd + delta, this.contents.length - this.gapEnd);
+		} else {
+			int delta = newGapStart - this.gapStart;
+			System.arraycopy(this.contents, 0, content, 0, this.gapStart);
+			System.arraycopy(this.contents, this.gapEnd, content, this.gapStart, delta);
+			System.arraycopy(this.contents, this.gapEnd + delta, content, newGapEnd, content.length - newGapEnd);
+		}
+	this.contents = content;
+	this.gapStart = newGapStart;
+	this.gapEnd = newGapEnd;
+}
+/**
+ * Notify the listeners that this buffer has changed.
+ * To avoid deadlock, this should not be called in a synchronized block.
+ */
+protected void notifyChanged(final BufferChangedEvent event) {
+	ArrayList listeners = this.changeListeners;
+	if (listeners != null) {
+		for (int i = 0, size = listeners.size(); i < size; ++i) {
+			final IBufferChangedListener listener = (IBufferChangedListener) listeners.get(i);
+			SafeRunner.run(new ISafeRunnable() {
+				public void handleException(Throwable exception) {
+					Util.log(exception, "Exception occurred in listener of buffer change notification"); //$NON-NLS-1$
+				}
+				public void run() throws Exception {
+					listener.bufferChanged(event);
+				}
+			});
+
+		}
+	}
+}
+/**
+ * @see IBuffer
+ */
+public synchronized void removeBufferChangedListener(IBufferChangedListener listener) {
+	if (this.changeListeners != null) {
+		this.changeListeners.remove(listener);
+		if (this.changeListeners.size() == 0) {
+			this.changeListeners = null;
+		}
+	}
+}
+/**
+ * Replaces <code>length</code> characters starting from <code>position</code> with <code>text<code>.
+ * After that operation, the gap is placed at the end of the
+ * inserted <code>text</code>.
+ */
+public void replace(int position, int length, char[] text) {
+	if (!isReadOnly()) {
+		int textLength = text == null ? 0 : text.length;
+		synchronized (this.lock) {
+			if (this.contents == null) return;
+
+			// move gap
+			moveAndResizeGap(position + length, textLength - length);
+
+			// overwrite
+			int min = Math.min(textLength, length);
+			if (min > 0) {
+				System.arraycopy(text, 0, this.contents, position, min);
+			}
+			if (length > textLength) {
+				// enlarge the gap
+				this.gapStart -= length - textLength;
+			} else if (textLength > length) {
+				// shrink gap
+				this.gapStart += textLength - length;
+				System.arraycopy(text, 0, this.contents, position, textLength);
+			}
+			this.flags |= F_HAS_UNSAVED_CHANGES;
+		}
+		String string = null;
+		if (textLength > 0) {
+			string = new String(text);
+		}
+		notifyChanged(new BufferChangedEvent(this, position, length, string));
+	}
+}
+/**
+ * Replaces <code>length</code> characters starting from <code>position</code> with <code>text<code>.
+ * After that operation, the gap is placed at the end of the
+ * inserted <code>text</code>.
+ */
+public void replace(int position, int length, String text) {
+	this.replace(position, length, text == null ? null : text.toCharArray());
+}
+/**
+ * @see IBuffer
+ */
+public void save(IProgressMonitor progress, boolean force) throws JavaModelException {
+
+	// determine if saving is required
+	if (isReadOnly() || this.file == null) {
+		return;
+	}
+	if (!hasUnsavedChanges())
+		return;
+
+	// use a platform operation to update the resource contents
+	try {
+		String stringContents = getContents();
+		if (stringContents == null) return;
+
+		// Get encoding
+		String encoding = null;
+		try {
+			encoding = this.file.getCharset();
+		}
+		catch (CoreException ce) {
+			// use no encoding
+		}
+
+		// Create bytes array
+		byte[] bytes = encoding == null
+			? stringContents.getBytes()
+			: stringContents.getBytes(encoding);
+
+		// Special case for UTF-8 BOM files
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=110576
+		if (encoding != null && encoding.equals(org.eclipse.jdt.internal.compiler.util.Util.UTF_8)) {
+			IContentDescription description;
+			try {
+				description = this.file.getContentDescription();
+			} catch (CoreException e) {
+				if (e.getStatus().getCode() != IResourceStatus.RESOURCE_NOT_FOUND)
+					throw e;
+				// file no longer exist (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=234307 )
+				description = null;
+			}
+			if (description != null && description.getProperty(IContentDescription.BYTE_ORDER_MARK) != null) {
+				int bomLength= IContentDescription.BOM_UTF_8.length;
+				byte[] bytesWithBOM= new byte[bytes.length + bomLength];
+				System.arraycopy(IContentDescription.BOM_UTF_8, 0, bytesWithBOM, 0, bomLength);
+				System.arraycopy(bytes, 0, bytesWithBOM, bomLength, bytes.length);
+				bytes= bytesWithBOM;
+			}
+		}
+
+		// Set file contents
+		ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+		if (this.file.exists()) {
+			this.file.setContents(
+				stream,
+				force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+				null);
+		} else {
+			this.file.create(stream, force, null);
+		}
+	} catch (IOException e) {
+		throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+	} catch (CoreException e) {
+		throw new JavaModelException(e);
+	}
+
+	// the resource no longer has unsaved changes
+	this.flags &= ~ (F_HAS_UNSAVED_CHANGES);
+}
+/**
+ * @see IBuffer
+ */
+public void setContents(char[] newContents) {
+	// allow special case for first initialization
+	// after creation by buffer factory
+	if (this.contents == null) {
+		synchronized (this.lock) {
+			this.contents = newContents;
+			this.flags &= ~ (F_HAS_UNSAVED_CHANGES);
+		}
+		return;
+	}
+
+	if (!isReadOnly()) {
+		String string = null;
+		if (newContents != null) {
+			string = new String(newContents);
+		}
+		synchronized (this.lock) {
+			if (this.contents == null) return; // ignore if buffer is closed (as per spec)
+			this.contents = newContents;
+			this.flags |= F_HAS_UNSAVED_CHANGES;
+			this.gapStart = -1;
+			this.gapEnd = -1;
+		}
+		BufferChangedEvent event = new BufferChangedEvent(this, 0, getLength(), string);
+		notifyChanged(event);
+	}
+}
+/**
+ * @see IBuffer
+ */
+public void setContents(String newContents) {
+	this.setContents(newContents.toCharArray());
+}
+/**
+ * Sets this <code>Buffer</code> to be read only.
+ */
+protected void setReadOnly(boolean readOnly) {
+	if (readOnly) {
+		this.flags |= F_IS_READ_ONLY;
+	} else {
+		this.flags &= ~(F_IS_READ_ONLY);
+	}
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("Owner: " + ((JavaElement)this.owner).toStringWithAncestors()); //$NON-NLS-1$
+	buffer.append("\nHas unsaved changes: " + hasUnsavedChanges()); //$NON-NLS-1$
+	buffer.append("\nIs readonly: " + isReadOnly()); //$NON-NLS-1$
+	buffer.append("\nIs closed: " + isClosed()); //$NON-NLS-1$
+	buffer.append("\nContents:\n"); //$NON-NLS-1$
+	char[] charContents = getCharacters();
+	if (charContents == null) {
+		buffer.append("<null>"); //$NON-NLS-1$
+	} else {
+		int length = charContents.length;
+		for (int i = 0; i < length; i++) {
+			char c = charContents[i];
+			switch (c) {
+				case '\n':
+					buffer.append("\\n\n"); //$NON-NLS-1$
+					break;
+				case '\r':
+					if (i < length-1 && this.contents[i+1] == '\n') {
+						buffer.append("\\r\\n\n"); //$NON-NLS-1$
+						i++;
+					} else {
+						buffer.append("\\r\n"); //$NON-NLS-1$
+					}
+					break;
+				default:
+					buffer.append(c);
+					break;
+			}
+		}
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java
new file mode 100644
index 0000000..0f22216
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.internal.core.util.LRUCache;
+
+/**
+ * An LRU cache of <code>IBuffers</code>.
+ */
+public class BufferCache extends OverflowingLRUCache {
+
+	private ThreadLocal buffersToClose = new ThreadLocal();
+/**
+ * Constructs a new buffer cache of the given size.
+ */
+public BufferCache(int size) {
+	super(size);
+}
+/**
+ * Constructs a new buffer cache of the given size.
+ */
+public BufferCache(int size, int overflow) {
+	super(size, overflow);
+}
+/**
+ * Returns true if the buffer is successfully closed and
+ * removed from the cache, otherwise false.
+ *
+ * <p>NOTE: this triggers an external removal of this buffer
+ * by closing the buffer.
+ */
+protected boolean close(LRUCacheEntry entry) {
+	IBuffer buffer= (IBuffer) entry.value;
+
+	// prevent buffer that have unsaved changes or working copy buffer to be removed
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=39311
+	if (!((Openable)buffer.getOwner()).canBufferBeRemovedFromCache(buffer)) {
+		return false;
+	} else {
+		ArrayList buffers = (ArrayList) this.buffersToClose.get();
+		if (buffers == null) {
+			buffers = new ArrayList();
+			this.buffersToClose.set(buffers);
+		}
+		buffers.add(buffer);
+		return true;
+	}
+}
+
+void closeBuffers() {
+	ArrayList buffers = (ArrayList) this.buffersToClose.get();
+	if (buffers == null)
+		return;
+	this.buffersToClose.set(null);
+	for (int i = 0, length = buffers.size(); i < length; i++) {
+		((IBuffer) buffers.get(i)).close();
+	}
+}
+	/**
+	 * Returns a new instance of the reciever.
+	 */
+	protected LRUCache newInstance(int size, int newOverflow) {
+		return new BufferCache(size, newOverflow);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java
new file mode 100644
index 0000000..256696f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+
+/**
+ * Wraps an IBufferFactory.
+ * TODO remove when removing IBufferFactory
+ * @deprecated
+ */
+public class BufferFactoryWrapper extends WorkingCopyOwner {
+
+	public org.eclipse.jdt.core.IBufferFactory factory;
+
+	private BufferFactoryWrapper(org.eclipse.jdt.core.IBufferFactory factory) {
+		this.factory = factory;
+	}
+
+	public static WorkingCopyOwner create(org.eclipse.jdt.core.IBufferFactory factory) {
+		return new BufferFactoryWrapper(factory);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.WorkingCopyOwner#createBuffer(org.eclipse.jdt.core.ICompilationUnit)
+	 */
+	public IBuffer createBuffer(ICompilationUnit workingCopy) {
+		if (this.factory == null) return super.createBuffer(workingCopy);
+		return this.factory.createBuffer(workingCopy);
+	}
+
+	public boolean equals(Object obj) {
+		if (!(obj instanceof BufferFactoryWrapper)) return false;
+		BufferFactoryWrapper other = (BufferFactoryWrapper)obj;
+		if (this.factory == null) return other.factory == null;
+		return this.factory.equals(other.factory);
+	}
+	public int hashCode() {
+		if (this.factory == null) return 0;
+		return this.factory.hashCode();
+	}
+	public String toString() {
+		return "FactoryWrapper for " + this.factory; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java
new file mode 100644
index 0000000..a1658a0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.text.NumberFormat;
+import java.util.Enumeration;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.IOpenable;
+
+/**
+ * The buffer manager manages the set of open buffers.
+ * It implements an LRU cache of buffers.
+ */
+public class BufferManager {
+
+	protected static BufferManager DEFAULT_BUFFER_MANAGER;
+	protected static boolean VERBOSE;
+
+	/**
+	 * LRU cache of buffers. The key and value for an entry
+	 * in the table is the identical buffer.
+	 */
+	private BufferCache openBuffers = new BufferCache(60);
+
+	/**
+	 * @deprecated
+	 */
+	protected org.eclipse.jdt.core.IBufferFactory defaultBufferFactory = new org.eclipse.jdt.core.IBufferFactory() {
+	    /**
+	     * @deprecated
+	     */
+		public IBuffer createBuffer(IOpenable owner) {
+			return BufferManager.createBuffer(owner);
+		}
+	};
+
+/**
+ * Adds a buffer to the table of open buffers.
+ */
+protected void addBuffer(IBuffer buffer) {
+	if (VERBOSE) {
+		String owner = ((Openable)buffer.getOwner()).toStringWithAncestors();
+		System.out.println("Adding buffer for " + owner); //$NON-NLS-1$
+	}
+	synchronized (this.openBuffers) {
+		this.openBuffers.put(buffer.getOwner(), buffer);
+	}
+	// close buffers that were removed from the cache if space was needed
+	this.openBuffers.closeBuffers();
+	if (VERBOSE) {
+		System.out.println("-> Buffer cache filling ratio = " + NumberFormat.getInstance().format(this.openBuffers.fillingRatio()) + "%"); //$NON-NLS-1$//$NON-NLS-2$
+	}
+}
+public static IBuffer createBuffer(IOpenable owner) {
+	JavaElement element = (JavaElement) owner;
+	IResource resource = element.resource();
+	return
+		new Buffer(
+			resource instanceof IFile ? (IFile)resource : null,
+			owner,
+			element.isReadOnly());
+}
+public static IBuffer createNullBuffer(IOpenable owner) {
+	JavaElement element = (JavaElement) owner;
+	IResource resource = element.resource();
+	return
+		new NullBuffer(
+			resource instanceof IFile ? (IFile)resource : null,
+			owner,
+			element.isReadOnly());
+}
+/**
+ * Returns the open buffer associated with the given owner,
+ * or <code>null</code> if the owner does not have an open
+ * buffer associated with it.
+ */
+public IBuffer getBuffer(IOpenable owner) {
+	synchronized (this.openBuffers) {
+		return (IBuffer)this.openBuffers.get(owner);
+	}
+}
+/**
+ * Returns the default buffer manager.
+ */
+public synchronized static BufferManager getDefaultBufferManager() {
+	if (DEFAULT_BUFFER_MANAGER == null) {
+		DEFAULT_BUFFER_MANAGER = new BufferManager();
+	}
+	return DEFAULT_BUFFER_MANAGER;
+}
+/**
+ * Returns the default buffer factory.
+ * @deprecated
+ */
+public org.eclipse.jdt.core.IBufferFactory getDefaultBufferFactory() {
+	return this.defaultBufferFactory;
+}
+/**
+ * Returns an enumeration of all open buffers.
+ * <p>
+ * The <code>Enumeration</code> answered is thread safe.
+ *
+ * @see OverflowingLRUCache
+ * @return Enumeration of IBuffer
+ */
+public Enumeration getOpenBuffers() {
+	Enumeration result;
+	synchronized (this.openBuffers) {
+		this.openBuffers.shrink();
+		result = this.openBuffers.elements();
+	}
+	// close buffers that were removed from the cache if space was needed
+	this.openBuffers.closeBuffers();
+	return result;
+}
+
+/**
+ * Removes a buffer from the table of open buffers.
+ */
+protected void removeBuffer(IBuffer buffer) {
+	if (VERBOSE) {
+		String owner = ((Openable)buffer.getOwner()).toStringWithAncestors();
+		System.out.println("Removing buffer for " + owner); //$NON-NLS-1$
+	}
+	synchronized (this.openBuffers) {
+		this.openBuffers.remove(buffer.getOwner());
+	}
+	// close buffers that were removed from the cache (should be only one)
+	this.openBuffers.closeBuffers();
+	if (VERBOSE) {
+		System.out.println("-> Buffer cache filling ratio = " + NumberFormat.getInstance().format(this.openBuffers.fillingRatio()) + "%"); //$NON-NLS-1$//$NON-NLS-2$
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
new file mode 100644
index 0000000..b1ac5e0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.codeassist.ISearchRequestor;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+
+
+public class CancelableNameEnvironment extends SearchableEnvironment implements INameEnvironmentWithProgress {
+	private IProgressMonitor monitor;
+
+	public CancelableNameEnvironment(JavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+		super(project, owner);
+		setMonitor(monitor);
+	}
+
+	private void checkCanceled() {
+		if (this.monitor != null && this.monitor.isCanceled()) {
+			if (NameLookup.VERBOSE)
+				System.out.println(Thread.currentThread() + " CANCELLING LOOKUP "); //$NON-NLS-1$
+			throw new AbortCompilation(true/*silent*/, new OperationCanceledException());
+		}
+	}
+
+	public void findPackages(char[] prefix, ISearchRequestor requestor) {
+		checkCanceled();
+		super.findPackages(prefix, requestor);
+	}
+
+	public NameEnvironmentAnswer findType(char[] name, char[][] packageName) {
+		checkCanceled();
+		return super.findType(name, packageName);
+	}
+
+	public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
+		checkCanceled();
+		return super.findType(compoundTypeName);
+	}
+
+	public void findTypes(char[] prefix, boolean findMembers, boolean camelCaseMatch, int searchFor, ISearchRequestor storage, IProgressMonitor progressMonitor) {
+		checkCanceled();
+		super.findTypes(prefix, findMembers, camelCaseMatch, searchFor, storage, progressMonitor);
+	}
+	
+	public void setMonitor(IProgressMonitor monitor) {
+		this.monitor = monitor;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java
new file mode 100644
index 0000000..543f9ba
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+
+
+public class CancelableProblemFactory extends DefaultProblemFactory {
+	public IProgressMonitor monitor;
+
+	public CancelableProblemFactory(IProgressMonitor monitor) {
+		super();
+		this.monitor = monitor;
+	}
+
+	public CategorizedProblem createProblem(char[] originatingFileName, int problemId, String[] problemArguments, String[] messageArguments, int severity, int startPosition, int endPosition, int lineNumber, int columnNumber) {
+		if (this.monitor != null && this.monitor.isCanceled())
+			throw new AbortCompilation(true/*silent*/, new OperationCanceledException());
+		return super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
+	}
+
+	public CategorizedProblem createProblem(char[] originatingFileName, int problemId, String[] problemArguments, int elaborationId, String[] messageArguments, int severity, int startPosition, int endPosition, int lineNumber, int columnNumber) {
+		if (this.monitor != null && this.monitor.isCanceled())
+			throw new AbortCompilation(true/*silent*/, new OperationCanceledException());
+		return super.createProblem(originatingFileName, problemId, problemArguments, elaborationId, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java
new file mode 100644
index 0000000..9e8b329
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+
+/*
+ * Abstract class for operations that change the classpath
+ */
+public abstract class ChangeClasspathOperation extends JavaModelOperation {
+
+	protected boolean canChangeResources;
+
+	public ChangeClasspathOperation(IJavaElement[] elements, boolean canChangeResources) {
+		super(elements);
+		this.canChangeResources = canChangeResources;
+	}
+
+	protected boolean canModifyRoots() {
+		// changing the classpath can modify roots
+		return true;
+	}
+
+	/*
+	 * The resolved classpath of the given project may have changed:
+	 * - generate a delta
+	 * - trigger indexing
+	 * - update project references
+	 * - create resolved classpath markers
+	 */
+	protected void classpathChanged(ClasspathChange change, boolean refreshExternalFolder) throws JavaModelException {
+		// reset the project's caches early since some clients rely on the project's caches being up-to-date when run inside an IWorkspaceRunnable
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769#c5 )
+		JavaProject project = change.project;
+		project.resetCaches();
+
+		if (this.canChangeResources) {
+			// workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=177922
+			if (isTopLevelOperation() && !ResourcesPlugin.getWorkspace().isTreeLocked()) {
+				new ClasspathValidation(project).validate();
+			}
+
+			// delta, indexing and classpath markers are going to be created by the delta processor
+			// while handling the resource change (either .classpath change, or project touched)
+
+			// however ensure project references are updated
+			// since some clients rely on the project references when run inside an IWorkspaceRunnable
+			new ProjectReferenceChange(project, change.oldResolvedClasspath).updateProjectReferencesIfNecessary();
+
+			// and ensure that external folders are updated as well
+			new ExternalFolderChange(project, change.oldResolvedClasspath).updateExternalFoldersIfNecessary(refreshExternalFolder, null);
+
+		} else {
+			DeltaProcessingState state = JavaModelManager.getDeltaState();
+			JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+			int result = change.generateDelta(delta, true/*add classpath change*/);
+			if ((result & ClasspathChange.HAS_DELTA) != 0) {
+				// create delta
+				addDelta(delta);
+
+				// need to recompute root infos
+				state.rootsAreStale = true;
+
+				// ensure indexes are updated
+				change.requestIndexing();
+
+				// ensure classpath is validated on next build
+				state.addClasspathValidation(project);
+			}
+			if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) {
+				// ensure project references are updated on next build
+				state.addProjectReferenceChange(project, change.oldResolvedClasspath);
+			}
+			if ((result & ClasspathChange.HAS_LIBRARY_CHANGE) != 0) {
+				// ensure external folders are updated on next build
+				state.addExternalFolderChange(project, change.oldResolvedClasspath);
+			}
+		}
+	}
+
+	protected ISchedulingRule getSchedulingRule() {
+		return null; // no lock taken while changing classpath
+	}
+
+	public boolean isReadOnly() {
+		return !this.canChangeResources;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
new file mode 100644
index 0000000..d4a1d9c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -0,0 +1,835 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.IDependent;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IClassFile
+ */
+
+public class ClassFile extends Openable implements IClassFile, SuffixConstants {
+
+	protected String name;
+	protected BinaryType binaryType = null;
+
+/*
+ * Creates a handle to a class file.
+ */
+protected ClassFile(PackageFragment parent, String nameWithoutExtension) {
+	super(parent);
+	this.name = nameWithoutExtension;
+}
+
+/*
+ * @see IClassFile#becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)
+ */
+public ICompilationUnit becomeWorkingCopy(IProblemRequestor problemRequestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	CompilationUnit workingCopy = new ClassFileWorkingCopy(this, owner == null ? DefaultWorkingCopyOwner.PRIMARY : owner);
+	JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true /*record usage*/, null/*no problem requestor needed*/);
+	if (perWorkingCopyInfo == null) {
+		// close cu and its children
+		close();
+
+		BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
+		operation.runOperation(monitor);
+
+		return workingCopy;
+	}
+	return perWorkingCopyInfo.workingCopy;
+}
+
+/**
+ * Creates the children elements for this class file adding the resulting
+ * new handles and info objects to the newElements table. Returns true
+ * if successful, or false if an error is encountered parsing the class file.
+ *
+ * @see Openable
+ * @see Signature
+ */
+protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+	IBinaryType typeInfo = getBinaryTypeInfo((IFile) underlyingResource);
+	if (typeInfo == null) {
+		// The structure of a class file is unknown if a class file format errors occurred
+		//during the creation of the diet class file representative of this ClassFile.
+		info.setChildren(new IJavaElement[] {});
+		return false;
+	}
+
+	// Make the type
+	IType type = getType();
+	info.setChildren(new IJavaElement[] {type});
+	newElements.put(type, typeInfo);
+
+	// Read children
+	((ClassFileInfo) info).readBinaryChildren(this, (HashMap) newElements, typeInfo);
+
+	return true;
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
+ * @deprecated
+ */
+public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICompletionRequestor, WorkingCopyOwner)
+ * @deprecated
+ */
+public void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	codeComplete(offset, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), owner);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	codeComplete(offset, requestor, owner, null);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	String source = getSource();
+	if (source != null) {
+		BinaryType type = (BinaryType) getType();
+		BasicCompilationUnit cu =
+			new BasicCompilationUnit(
+				getSource().toCharArray(),
+				null,
+				type.sourceFileName((IBinaryType) type.getElementInfo()),
+				getJavaProject()); // use project to retrieve corresponding .java IFile
+		codeComplete(cu, cu, offset, requestor, owner, null/*extended context isn't computed*/, monitor);
+	}
+}
+
+/**
+ * @see ICodeAssist#codeSelect(int, int)
+ */
+public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
+	return codeSelect(offset, length, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see ICodeAssist#codeSelect(int, int, WorkingCopyOwner)
+ */
+public IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner owner) throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	char[] contents;
+	if (buffer != null && (contents = buffer.getCharacters()) != null) {
+	    BinaryType type = (BinaryType) getType();
+		BasicCompilationUnit cu = new BasicCompilationUnit(contents, null, type.sourceFileName((IBinaryType) type.getElementInfo()));
+		return super.codeSelect(cu, offset, length, owner);
+	} else {
+		//has no associated souce
+		return new IJavaElement[] {};
+	}
+}
+/**
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return new ClassFileInfo();
+}
+public boolean equals(Object o) {
+	if (!(o instanceof ClassFile)) return false;
+	ClassFile other = (ClassFile) o;
+	return this.name.equals(other.name) && this.parent.equals(other.parent);
+}
+public boolean existsUsingJarTypeCache() {
+	if (getPackageFragmentRoot().isArchive()) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IType type = getType();
+		Object info = manager.getInfo(type);
+		if (info == JavaModelCache.NON_EXISTING_JAR_TYPE_INFO)
+			return false;
+		else if (info != null)
+			return true;
+		// info is null
+		JavaElementInfo parentInfo = (JavaElementInfo) manager.getInfo(getParent());
+		if (parentInfo != null) {
+			// if parent is open, this class file must be in its children
+			IJavaElement[] children = parentInfo.getChildren();
+			for (int i = 0, length = children.length; i < length; i++) {
+				if (this.name.equals(((ClassFile) children[i]).name))
+					return true;
+			}
+			return false;
+		}
+		try {
+			info = getJarBinaryTypeInfo((PackageFragment) getParent(), true/*fully initialize so as to not keep a reference to the byte array*/);
+		} catch (CoreException e) {
+			// leave info null
+		} catch (IOException e) {
+			// leave info null
+		} catch (ClassFormatException e) {
+			// leave info null
+		}
+		manager.putJarTypeInfo(type, info == null ? JavaModelCache.NON_EXISTING_JAR_TYPE_INFO : info);
+		return info != null;
+	} else
+		return exists();
+}
+
+/**
+ * Finds the deepest <code>IJavaElement</code> in the hierarchy of
+ * <code>elt</elt>'s children (including <code>elt</code> itself)
+ * which has a source range that encloses <code>position</code>
+ * according to <code>mapper</code>.
+ */
+protected IJavaElement findElement(IJavaElement elt, int position, SourceMapper mapper) {
+	SourceRange range = mapper.getSourceRange(elt);
+	if (range == null || position < range.getOffset() || range.getOffset() + range.getLength() - 1 < position) {
+		return null;
+	}
+	if (elt instanceof IParent) {
+		try {
+			IJavaElement[] children = ((IParent) elt).getChildren();
+			for (int i = 0; i < children.length; i++) {
+				IJavaElement match = findElement(children[i], position, mapper);
+				if (match != null) {
+					return match;
+				}
+			}
+		} catch (JavaModelException npe) {
+			// elt doesn't exist: return the element
+		}
+	}
+	return elt;
+}
+/**
+ * @see ITypeRoot#findPrimaryType()
+ */
+public IType findPrimaryType() {
+	IType primaryType= getType();
+	if (primaryType.exists()) {
+		return primaryType;
+	}
+	return null;
+}
+public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+	return getType().getAttachedJavadoc(monitor);
+}
+/**
+ * Returns the <code>ClassFileReader</code>specific for this IClassFile, based
+ * on its underlying resource, or <code>null</code> if unable to create
+ * the diet class file.
+ * There are two cases to consider:<ul>
+ * <li>a class file corresponding to an IFile resource</li>
+ * <li>a class file corresponding to a zip entry in a JAR</li>
+ * </ul>
+ *
+ * @exception JavaModelException when the IFile resource or JAR is not available
+ * or when this class file is not present in the JAR
+ */
+public IBinaryType getBinaryTypeInfo(IFile file) throws JavaModelException {
+	return getBinaryTypeInfo(file, true/*fully initialize so as to not keep a reference to the byte array*/);
+}
+public IBinaryType getBinaryTypeInfo(IFile file, boolean fullyInitialize) throws JavaModelException {
+	JavaElement pkg = (JavaElement) getParent();
+	if (pkg instanceof JarPackageFragment) {
+		try {
+			IBinaryType info = getJarBinaryTypeInfo((PackageFragment) pkg, fullyInitialize);
+			if (info == null) {
+				throw newNotPresentException();
+			}
+			return info;
+		} catch (ClassFormatException cfe) {
+			//the structure remains unknown
+			if (JavaCore.getPlugin().isDebugging()) {
+				cfe.printStackTrace(System.err);
+			}
+			return null;
+		} catch (IOException ioe) {
+			throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION);
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException) {
+				throw (JavaModelException)e;
+			} else {
+				throw new JavaModelException(e);
+			}
+		}
+	} else {
+		byte[] contents = Util.getResourceContentsAsByteArray(file);
+		try {
+			return new ClassFileReader(contents, file.getFullPath().toString().toCharArray(), fullyInitialize);
+		} catch (ClassFormatException cfe) {
+			//the structure remains unknown
+			return null;
+		}
+	}
+}
+
+public byte[] getBytes() throws JavaModelException {
+	JavaElement pkg = (JavaElement) getParent();
+	if (pkg instanceof JarPackageFragment) {
+		JarPackageFragmentRoot root = (JarPackageFragmentRoot) pkg.getParent();
+		ZipFile zip = null;
+		try {
+			zip = root.getJar();
+			String entryName = Util.concatWith(((PackageFragment) pkg).names, getElementName(), '/');
+			ZipEntry ze = zip.getEntry(entryName);
+			if (ze != null) {
+				return org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
+			}
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this));
+		} catch (IOException ioe) {
+			throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION);
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException) {
+				throw (JavaModelException)e;
+			} else {
+				throw new JavaModelException(e);
+			}
+		} finally {
+			JavaModelManager.getJavaModelManager().closeZipFile(zip);
+		}
+	} else {
+		IFile file = (IFile) resource();
+		return Util.getResourceContentsAsByteArray(file);
+	}
+}
+private IBinaryType getJarBinaryTypeInfo(PackageFragment pkg, boolean fullyInitialize) throws CoreException, IOException, ClassFormatException {
+	JarPackageFragmentRoot root = (JarPackageFragmentRoot) pkg.getParent();
+	ZipFile zip = null;
+	try {
+		zip = root.getJar();
+		String entryName = Util.concatWith(pkg.names, getElementName(), '/');
+		ZipEntry ze = zip.getEntry(entryName);
+		if (ze != null) {
+			byte contents[] = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
+			String fileName = root.getHandleIdentifier() + IDependent.JAR_FILE_ENTRY_SEPARATOR + entryName;
+			return new ClassFileReader(contents, fileName.toCharArray(), fullyInitialize);
+		}
+	} finally {
+		JavaModelManager.getJavaModelManager().closeZipFile(zip);
+	}
+	return null;
+}
+public IBuffer getBuffer() throws JavaModelException {
+	IStatus status = validateClassFile();
+	if (status.isOK()) {
+		return super.getBuffer();
+	} else {
+		switch (status.getCode()) {
+		case IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH: // don't throw a JavaModelException to be able to open .class file outside the classpath (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138507 )
+		case IJavaModelStatusConstants.INVALID_ELEMENT_TYPES: // don't throw a JavaModelException to be able to open .class file in proj==src case without source (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=221904 )
+			return null;
+		default:
+			throw new JavaModelException((IJavaModelStatus) status);
+		}
+	}
+}
+/**
+ * @see IMember
+ */
+public IClassFile getClassFile() {
+	return this;
+}
+/**
+ * @see IMember#getTypeRoot()
+ */
+public ITypeRoot getTypeRoot() {
+	return this;
+}
+/**
+ * A class file has a corresponding resource unless it is contained
+ * in a jar.
+ *
+ * @see IJavaElement
+ */
+public IResource getCorrespondingResource() throws JavaModelException {
+	IPackageFragmentRoot root= (IPackageFragmentRoot)getParent().getParent();
+	if (root.isArchive()) {
+		return null;
+	} else {
+		return getUnderlyingResource();
+	}
+}
+/**
+ * @see IClassFile
+ */
+public IJavaElement getElementAt(int position) throws JavaModelException {
+	IJavaElement parentElement = getParent();
+	while (parentElement.getElementType() != IJavaElement.PACKAGE_FRAGMENT_ROOT) {
+		parentElement = parentElement.getParent();
+	}
+	PackageFragmentRoot root = (PackageFragmentRoot) parentElement;
+	SourceMapper mapper = root.getSourceMapper();
+	if (mapper == null) {
+		return null;
+	} else {
+		// ensure this class file's buffer is open so that source ranges are computed
+		getBuffer();
+
+		IType type = getType();
+		return findElement(type, position, mapper);
+	}
+}
+public IJavaElement getElementAtConsideringSibling(int position) throws JavaModelException {
+	IPackageFragment fragment = (IPackageFragment)getParent();
+	PackageFragmentRoot root = (PackageFragmentRoot) fragment.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+	SourceMapper mapper = root.getSourceMapper();
+	if (mapper == null) {
+		return null;
+	} else {
+		int index = this.name.indexOf('$');
+		int prefixLength = index < 0 ? this.name.length() : index;
+
+		IType type = null;
+		int start = -1;
+		int end = Integer.MAX_VALUE;
+		IJavaElement[] children = fragment.getChildren();
+		for (int i = 0; i < children.length; i++) {
+			String childName = children[i].getElementName();
+
+			int childIndex = childName.indexOf('$');
+			int childPrefixLength = childIndex < 0 ? childName.indexOf('.') : childIndex;
+			if (prefixLength == childPrefixLength && this.name.regionMatches(0, childName, 0, prefixLength)) {
+				IClassFile classFile = (IClassFile) children[i];
+
+				// ensure this class file's buffer is open so that source ranges are computed
+				classFile.getBuffer();
+
+				SourceRange range = mapper.getSourceRange(classFile.getType());
+				if (range == SourceMapper.UNKNOWN_RANGE) continue;
+				int newStart = range.getOffset();
+				int newEnd = newStart + range.getLength() - 1;
+				if(newStart > start && newEnd < end
+						&& newStart <= position && newEnd >= position) {
+					type = classFile.getType();
+					start = newStart;
+					end = newEnd;
+				}
+			}
+		}
+		if(type != null) {
+			return findElement(type, position, mapper);
+		}
+		return null;
+	}
+}
+public String getElementName() {
+	return this.name + SuffixConstants.SUFFIX_STRING_class;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return CLASS_FILE;
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+	switch (token.charAt(0)) {
+		case JEM_TYPE:
+			if (!memento.hasMoreTokens()) return this;
+			String typeName = memento.nextToken();
+			JavaElement type = new BinaryType(this, typeName);
+			return type.getHandleFromMemento(memento, owner);
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_CLASSFILE;
+}
+/*
+ * @see IJavaElement
+ */
+public IPath getPath() {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root.isArchive()) {
+		return root.getPath();
+	} else {
+		return getParent().getPath().append(getElementName());
+	}
+}
+/*
+ * @see IJavaElement
+ */
+public IResource resource(PackageFragmentRoot root) {
+	return ((IContainer) ((Openable) this.parent).resource(root)).getFile(new Path(getElementName()));
+}
+/**
+ * @see ISourceReference
+ */
+public String getSource() throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	if (buffer == null) {
+		return null;
+	}
+	return buffer.getContents();
+}
+/**
+ * @see ISourceReference
+ */
+public ISourceRange getSourceRange() throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	if (buffer != null) {
+		String contents = buffer.getContents();
+		if (contents == null) return null;
+		return new SourceRange(0, contents.length());
+	} else {
+		return null;
+	}
+}
+/*
+ * Returns the name of the toplevel type of this class file.
+ */
+public String getTopLevelTypeName() {
+    String topLevelTypeName = getElementName();
+    int firstDollar = topLevelTypeName.indexOf('$');
+    if (firstDollar != -1) {
+        topLevelTypeName = topLevelTypeName.substring(0, firstDollar);
+    } else {
+        topLevelTypeName = topLevelTypeName.substring(0, topLevelTypeName.length()-SUFFIX_CLASS.length);
+    }
+    return topLevelTypeName;
+}
+/**
+ * @see IClassFile
+ */
+public IType getType() {
+	if (this.binaryType == null) {
+		this.binaryType = new BinaryType(this, getTypeName());
+	}
+	return this.binaryType;
+}
+public String getTypeName() {
+	// Internal class file name doesn't contain ".class" file extension
+	int lastDollar = this.name.lastIndexOf('$');
+	return lastDollar > -1 ? Util.localTypeName(this.name, lastDollar, this.name.length()) : this.name;
+}
+/*
+ * @see IClassFile
+ */
+public ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	CompilationUnit workingCopy = new ClassFileWorkingCopy(this, owner == null ? DefaultWorkingCopyOwner.PRIMARY : owner);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
+		manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true/*record usage*/, null/*not used since don't create*/);
+	if (perWorkingCopyInfo != null) {
+		return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
+	}
+	BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, null);
+	op.runOperation(monitor);
+	return workingCopy;
+}
+/**
+ * @see IClassFile
+ * @deprecated
+ */
+public IJavaElement getWorkingCopy(IProgressMonitor monitor, org.eclipse.jdt.core.IBufferFactory factory) throws JavaModelException {
+	return getWorkingCopy(BufferFactoryWrapper.create(factory), monitor);
+}
+/**
+ * @see Openable
+ */
+protected boolean hasBuffer() {
+	return true;
+}
+public int hashCode() {
+	return Util.combineHashCodes(this.name.hashCode(), this.parent.hashCode());
+}
+/**
+ * @see IClassFile
+ */
+public boolean isClass() throws JavaModelException {
+	return getType().isClass();
+}
+/**
+ * @see IClassFile
+ */
+public boolean isInterface() throws JavaModelException {
+	return getType().isInterface();
+}
+/**
+ * Returns true - class files are always read only.
+ */
+public boolean isReadOnly() {
+	return true;
+}
+private IStatus validateClassFile() {
+	IPackageFragmentRoot root = getPackageFragmentRoot();
+	try {
+		if (root.getKind() != IPackageFragmentRoot.K_BINARY)
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, root);
+	} catch (JavaModelException e) {
+		return e.getJavaModelStatus();
+	}
+	IJavaProject project = getJavaProject();
+	return JavaConventions.validateClassFileName(getElementName(), project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
+}
+/**
+ * Opens and returns buffer on the source code associated with this class file.
+ * Maps the source code to the children elements of this class file.
+ * If no source code is associated with this class file,
+ * <code>null</code> is returned.
+ *
+ * @see Openable
+ */
+protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
+	// Check the cache for the top-level type first
+	IType outerMostEnclosingType = getOuterMostEnclosingType();
+	IBuffer buffer = getBufferManager().getBuffer(outerMostEnclosingType.getClassFile());
+	if (buffer == null) {
+		SourceMapper mapper = getSourceMapper();
+		IBinaryType typeInfo = info instanceof IBinaryType ? (IBinaryType) info : null;
+		if (mapper != null) {
+			buffer = mapSource(mapper, typeInfo, outerMostEnclosingType.getClassFile());
+		}
+	}
+	return buffer;
+}
+/** Loads the buffer via SourceMapper, and maps it in SourceMapper */
+private IBuffer mapSource(SourceMapper mapper, IBinaryType info, IClassFile bufferOwner) {
+	char[] contents = mapper.findSource(getType(), info);
+	if (contents != null) {
+		// create buffer
+		IBuffer buffer = BufferManager.createBuffer(bufferOwner);
+		if (buffer == null) return null;
+		BufferManager bufManager = getBufferManager();
+		bufManager.addBuffer(buffer);
+
+		// set the buffer source
+		if (buffer.getCharacters() == null){
+			buffer.setContents(contents);
+		}
+
+		// listen to buffer changes
+		buffer.addBufferChangedListener(this);
+
+		// do the source mapping
+		mapper.mapSource(getOuterMostEnclosingType(), contents, info);
+
+		return buffer;
+	} else {
+		// create buffer
+		IBuffer buffer = BufferManager.createNullBuffer(bufferOwner);
+		if (buffer == null) return null;
+		BufferManager bufManager = getBufferManager();
+		bufManager.addBuffer(buffer);
+
+		// listen to buffer changes
+		buffer.addBufferChangedListener(this);
+		return buffer;
+	}
+}
+/* package */ static String simpleName(char[] className) {
+	if (className == null)
+		return null;
+	String simpleName = new String(unqualifiedName(className));
+	int lastDollar = simpleName.lastIndexOf('$');
+	if (lastDollar != -1)
+		return Util.localTypeName(simpleName, lastDollar, simpleName.length());
+	else
+		return simpleName;
+}
+
+/** Returns the type of the top-level declaring class used to find the source code */
+private IType getOuterMostEnclosingType() {
+	IType type = getType();
+	IType enclosingType = type.getDeclaringType();
+	while (enclosingType != null) {
+		type = enclosingType;
+		enclosingType = type.getDeclaringType();
+	}
+	return type;
+}
+
+/**
+ * Returns the Java Model representation of the given name
+ * which is provided in diet class file format, or <code>null</code>
+ * if the given name is <code>null</code>.
+ *
+ * <p><code>ClassFileReader</code> format is similar to "java/lang/Object",
+ * and corresponding Java Model format is "java.lang.Object".
+ */
+
+public static char[] translatedName(char[] name) {
+	if (name == null)
+		return null;
+	int nameLength = name.length;
+	char[] newName= new char[nameLength];
+	for (int i= 0; i < nameLength; i++) {
+		if (name[i] == '/') {
+			newName[i]= '.';
+		} else {
+			newName[i]= name[i];
+		}
+	}
+	return newName;
+}
+/**
+ * Returns the Java Model representation of the given names
+ * which are provided in diet class file format, or <code>null</code>
+ * if the given names are <code>null</code>.
+ *
+ * <p><code>ClassFileReader</code> format is similar to "java/lang/Object",
+ * and corresponding Java Model format is "java.lang.Object".
+ */
+
+/* package */ static char[][] translatedNames(char[][] names) {
+	if (names == null)
+		return null;
+	int length = names.length;
+	char[][] newNames = new char[length][];
+	for(int i = 0; i < length; i++) {
+		newNames[i] = translatedName(names[i]);
+	}
+	return newNames;
+}
+/**
+ * Returns the Java Model format of the unqualified class name for the
+ * given className which is provided in diet class file format,
+ * or <code>null</code> if the given className is <code>null</code>.
+ * (This removes the package name, but not enclosing type names).
+ *
+ * <p><code>ClassFileReader</code> format is similar to "java/lang/Object",
+ * and corresponding Java Model simple name format is "Object".
+ */
+
+/* package */ static char[] unqualifiedName(char[] className) {
+	if (className == null)
+		return null;
+	int count = 0;
+	for (int i = className.length - 1; i > -1; i--) {
+		if (className[i] == '/') {
+			char[] name = new char[count];
+			System.arraycopy(className, i + 1, name, 0, count);
+			return name;
+		}
+		count++;
+	}
+	return className;
+}
+
+/**
+ * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
+ * @deprecated - should use codeComplete(int, ICompletionRequestor) instead
+ */
+public void codeComplete(int offset, final org.eclipse.jdt.core.ICodeCompletionRequestor requestor) throws JavaModelException {
+
+	if (requestor == null){
+		codeComplete(offset, (ICompletionRequestor)null);
+		return;
+	}
+	codeComplete(
+		offset,
+		new ICompletionRequestor(){
+			public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName, char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+				// ignore
+			}
+			public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptError(IProblem error) {
+				// was disabled in 1.0
+			}
+			public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptField(declaringTypePackageName, declaringTypeName, fieldName, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+				requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptKeyword(keywordName, completionStart, completionEnd);
+			}
+			public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptLabel(labelName, completionStart, completionEnd);
+			}
+			public void acceptLocalVariable(char[] localVarName,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// skip parameter names
+				requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptModifier(modifierName, completionStart, completionEnd);
+			}
+			public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
+			}
+			public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
+			}
+			public void acceptVariableName(char[] typePackageName,char[] typeName,char[] varName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+		});
+}
+
+protected IStatus validateExistence(IResource underlyingResource) {
+	// check whether the class file can be opened
+	IStatus status = validateClassFile();
+	if (!status.isOK())
+		return status;
+	if (underlyingResource != null) {
+		if (!underlyingResource.isAccessible())
+			return newDoesNotExistStatus();
+		PackageFragmentRoot root;
+		if ((underlyingResource instanceof IFolder) && (root = getPackageFragmentRoot()).isArchive()) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=204652
+			return root.newDoesNotExistStatus();
+		}
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+public ISourceRange getNameRange() {
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java
new file mode 100644
index 0000000..f3ed0ee
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
+import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+
+/**
+ * Element info for <code>ClassFile</code> handles.
+ */
+
+/* package */ class ClassFileInfo extends OpenableElementInfo implements SuffixConstants {
+	/**
+	 * The children of the <code>BinaryType</code> corresponding to our
+	 * <code>ClassFile</code>. These are kept here because we don't have
+	 * access to the <code>BinaryType</code> info (<code>ClassFileReader</code>).
+	 */
+	protected JavaElement[] binaryChildren = null;
+	/*
+	 * The type parameters in this class file.
+	 */
+	protected ITypeParameter[] typeParameters;
+
+private void generateAnnotationsInfos(JavaElement member, IBinaryAnnotation[] binaryAnnotations, long tagBits, HashMap newElements) {
+	generateAnnotationsInfos(member, null, binaryAnnotations, tagBits, newElements);
+}
+/**
+ * Creates the handles and infos for the annotations of the given binary member.
+ * Adds new handles to the given vector.
+ */
+private void generateAnnotationsInfos(JavaElement member, char[] parameterName, IBinaryAnnotation[] binaryAnnotations, long tagBits, HashMap newElements) {
+	if (binaryAnnotations != null) {
+		for (int i = 0, length = binaryAnnotations.length; i < length; i++) {
+			IBinaryAnnotation annotationInfo = binaryAnnotations[i];
+			generateAnnotationInfo(member, parameterName, newElements, annotationInfo, null);
+		}
+	}
+	generateStandardAnnotationsInfos(member, parameterName, tagBits, newElements);
+}
+private void generateAnnotationInfo(JavaElement parent, HashMap newElements, IBinaryAnnotation annotationInfo, String memberValuePairName) {
+	generateAnnotationInfo(parent, null, newElements, annotationInfo, memberValuePairName);
+}
+private void generateAnnotationInfo(JavaElement parent, char[] parameterName, HashMap newElements, IBinaryAnnotation annotationInfo, String memberValuePairName) {
+	char[] typeName = org.eclipse.jdt.core.Signature.toCharArray(CharOperation.replaceOnCopy(annotationInfo.getTypeName(), '/', '.'));
+	Annotation annotation = new Annotation(parent, new String(typeName), memberValuePairName);
+	while (newElements.containsKey(annotation)) {
+		annotation.occurrenceCount++;
+	}
+	newElements.put(annotation, annotationInfo);
+	IBinaryElementValuePair[] pairs = annotationInfo.getElementValuePairs();
+	for (int i = 0, length = pairs.length; i < length; i++) {
+		Object value = pairs[i].getValue();
+		if (value instanceof IBinaryAnnotation) {
+			generateAnnotationInfo(annotation, newElements, (IBinaryAnnotation) value, new String(pairs[i].getName()));
+		} else if (value instanceof Object[]) {
+			// if the value is an array, it can have no more than 1 dimension - no need to recurse
+			Object[] valueArray = (Object[]) value;
+			for (int j = 0, valueArrayLength = valueArray.length; j < valueArrayLength; j++) {
+				Object nestedValue = valueArray[j];
+				if (nestedValue instanceof IBinaryAnnotation) {
+					generateAnnotationInfo(annotation, newElements, (IBinaryAnnotation) nestedValue, new String(pairs[i].getName()));
+				}
+			}
+		}
+	}
+}
+private void generateStandardAnnotationsInfos(JavaElement javaElement, char[] parameterName, long tagBits, HashMap newElements) {
+	if ((tagBits & TagBits.AllStandardAnnotationsMask) == 0)
+		return;
+	if ((tagBits & TagBits.AnnotationTargetMASK) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_TARGET, getTargetElementTypes(tagBits), newElements);
+	}
+	if ((tagBits & TagBits.AnnotationRetentionMASK) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, getRetentionPolicy(tagBits), newElements);
+	}
+	if ((tagBits & TagBits.AnnotationDeprecated) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_DEPRECATED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements);
+	}
+	if ((tagBits & TagBits.AnnotationDocumented) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements);
+	}
+	if ((tagBits & TagBits.AnnotationInherited) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements);
+	}
+	if ((tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, Annotation.NO_MEMBER_VALUE_PAIRS, newElements);
+	}
+	if ((tagBits & TagBits.AnnotationSafeVarargs) != 0) {
+		generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_SAFEVARARGS, Annotation.NO_MEMBER_VALUE_PAIRS, newElements);
+	}
+	// note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries
+}
+
+private void generateStandardAnnotation(JavaElement javaElement, char[][] typeName, IMemberValuePair[] members, HashMap newElements) {
+	IAnnotation annotation = new Annotation(javaElement, new String(CharOperation.concatWith(typeName, '.')));
+	AnnotationInfo annotationInfo = new AnnotationInfo();
+	annotationInfo.members = members;
+	newElements.put(annotation, annotationInfo);
+}
+
+private IMemberValuePair[] getTargetElementTypes(long tagBits) {
+	ArrayList values = new ArrayList();
+	String elementType = new String(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, '.')) + '.';
+	if ((tagBits & TagBits.AnnotationForType) != 0) {
+		values.add(elementType + new String(TypeConstants.TYPE));
+	}
+	if ((tagBits & TagBits.AnnotationForField) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_FIELD));
+	}
+	if ((tagBits & TagBits.AnnotationForMethod) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_METHOD));
+	}
+	if ((tagBits & TagBits.AnnotationForParameter) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_PARAMETER));
+	}
+	if ((tagBits & TagBits.AnnotationForConstructor) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_CONSTRUCTOR));
+	}
+	if ((tagBits & TagBits.AnnotationForLocalVariable) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_LOCAL_VARIABLE));
+	}
+	if ((tagBits & TagBits.AnnotationForAnnotationType) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_ANNOTATION_TYPE));
+	}
+	if ((tagBits & TagBits.AnnotationForPackage) != 0) {
+		values.add(elementType + new String(TypeConstants.UPPER_PACKAGE));
+	}
+	final Object value;
+	if (values.size() == 0) {
+		if ((tagBits & TagBits.AnnotationTarget) != 0)
+			value = CharOperation.NO_STRINGS;
+		else
+			return Annotation.NO_MEMBER_VALUE_PAIRS;
+	} else if (values.size() == 1) {
+		value = values.get(0);
+	} else {
+		value = values.toArray(new String[values.size()]);
+	}
+	return new IMemberValuePair[] {
+		new IMemberValuePair() {
+			public int getValueKind() {
+				return IMemberValuePair.K_QUALIFIED_NAME;
+			}
+			public Object getValue() {
+				return value;
+			}
+			public String getMemberName() {
+				return new String(TypeConstants.VALUE);
+			}
+		}
+	};
+}
+
+private IMemberValuePair[] getRetentionPolicy(long tagBits) {
+	if ((tagBits & TagBits.AnnotationRetentionMASK) == 0)
+		return Annotation.NO_MEMBER_VALUE_PAIRS;
+	String retention = null;
+	if ((tagBits & TagBits.AnnotationRuntimeRetention) == TagBits.AnnotationRuntimeRetention) {
+		// TagBits.AnnotationRuntimeRetention combines both TagBits.AnnotationClassRetention & TagBits.AnnotationSourceRetention
+		retention = new String(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.')) + '.' + new String(TypeConstants.UPPER_RUNTIME);
+	} else if ((tagBits & TagBits.AnnotationSourceRetention) != 0) {
+		retention = new String(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.')) + '.' + new String(TypeConstants.UPPER_SOURCE);
+	} else {
+		retention = new String(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.')) + '.' + new String(TypeConstants.UPPER_CLASS);
+	}
+	final String value = retention;
+	return 
+		new IMemberValuePair[] {
+			new IMemberValuePair() {
+				public int getValueKind() {
+					return IMemberValuePair.K_QUALIFIED_NAME;
+				}
+				public Object getValue() {
+					return value;
+				}
+				public String getMemberName() {
+					return new String(TypeConstants.VALUE);
+				}
+			}
+		};
+}
+
+/**
+ * Creates the handles and infos for the fields of the given binary type.
+ * Adds new handles to the given vector.
+ */
+private void generateFieldInfos(IType type, IBinaryType typeInfo, HashMap newElements, ArrayList childrenHandles) {
+	// Make the fields
+	IBinaryField[] fields = typeInfo.getFields();
+	if (fields == null) {
+		return;
+	}
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	for (int i = 0, fieldCount = fields.length; i < fieldCount; i++) {
+		IBinaryField fieldInfo = fields[i];
+		BinaryField field = new BinaryField((JavaElement)type, manager.intern(new String(fieldInfo.getName())));
+		newElements.put(field, fieldInfo);
+		childrenHandles.add(field);
+		generateAnnotationsInfos(field, fieldInfo.getAnnotations(), fieldInfo.getTagBits(), newElements);
+	}
+}
+/**
+ * Creates the handles for the inner types of the given binary type.
+ * Adds new handles to the given vector.
+ */
+private void generateInnerClassHandles(IType type, IBinaryType typeInfo, ArrayList childrenHandles) {
+	// Add inner types
+	// If the current type is an inner type, innerClasses returns
+	// an extra entry for the current type.  This entry must be removed.
+	// Can also return an entry for the enclosing type of an inner type.
+	IBinaryNestedType[] innerTypes = typeInfo.getMemberTypes();
+	if (innerTypes != null) {
+		IPackageFragment pkg = (IPackageFragment) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
+		for (int i = 0, typeCount = innerTypes.length; i < typeCount; i++) {
+			IBinaryNestedType binaryType = innerTypes[i];
+			IClassFile parentClassFile= pkg.getClassFile(new String(ClassFile.unqualifiedName(binaryType.getName())) + SUFFIX_STRING_class);
+			IType innerType = new BinaryType((JavaElement) parentClassFile, ClassFile.simpleName(binaryType.getName()));
+			childrenHandles.add(innerType);
+		}
+	}
+}
+/**
+ * Creates the handles and infos for the methods of the given binary type.
+ * Adds new handles to the given vector.
+ */
+private void generateMethodInfos(IType type, IBinaryType typeInfo, HashMap newElements, ArrayList childrenHandles, ArrayList typeParameterHandles) {
+	IBinaryMethod[] methods = typeInfo.getMethods();
+	if (methods == null) {
+		return;
+	}
+	for (int i = 0, methodCount = methods.length; i < methodCount; i++) {
+		IBinaryMethod methodInfo = methods[i];
+		// TODO (jerome) filter out synthetic members
+		//                        indexer should not index them as well
+		// if ((methodInfo.getModifiers() & IConstants.AccSynthetic) != 0) continue; // skip synthetic
+		boolean useGenericSignature = true;
+		char[] signature = methodInfo.getGenericSignature();
+		if (signature == null) {
+			useGenericSignature = false;
+			signature = methodInfo.getMethodDescriptor();
+		}
+		String selector = new String(methodInfo.getSelector());
+		final boolean isConstructor = methodInfo.isConstructor();
+		if (isConstructor) {
+			selector = type.getElementName();
+		}
+		String[] pNames = null;
+		try {
+			pNames = Signature.getParameterTypes(new String(signature));
+			if (isConstructor
+					&& useGenericSignature
+					&& type.isMember()
+					&& !Flags.isStatic(type.getFlags())) {
+				int length = pNames.length;
+				System.arraycopy(pNames, 0, (pNames = new String[length + 1]), 1, length);
+				char[] descriptor = methodInfo.getMethodDescriptor();
+				final String[] parameterTypes = Signature.getParameterTypes(new String(descriptor));
+				pNames[0] = parameterTypes[0];
+			}
+		} catch (IllegalArgumentException e) {
+			// protect against malformed .class file (e.g. com/sun/crypto/provider/SunJCE_b.class has a 'a' generic signature)
+			signature = methodInfo.getMethodDescriptor();
+			pNames = Signature.getParameterTypes(new String(signature));
+		} catch (JavaModelException e) {
+			// protect against malformed .class file (e.g. com/sun/crypto/provider/SunJCE_b.class has a 'a' generic signature)
+			signature = methodInfo.getMethodDescriptor();
+			pNames = Signature.getParameterTypes(new String(signature));
+		}
+		char[][] paramNames= new char[pNames.length][];
+		for (int j= 0; j < pNames.length; j++) {
+			paramNames[j]= pNames[j].toCharArray();
+		}
+		char[][] parameterTypes = ClassFile.translatedNames(paramNames);
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		selector =  manager.intern(selector);
+		for (int j= 0; j < pNames.length; j++) {
+			pNames[j]= manager.intern(new String(parameterTypes[j]));
+		}
+		BinaryMethod method = new BinaryMethod((JavaElement)type, selector, pNames);
+		childrenHandles.add(method);
+
+		// ensure that 2 binary methods with the same signature but with different return types have different occurrence counts.
+		// (case of bridge methods in 1.5)
+		while (newElements.containsKey(method))
+			method.occurrenceCount++;
+
+		newElements.put(method, methodInfo);
+
+		int max = pNames.length;
+		char[][] argumentNames = methodInfo.getArgumentNames();
+		if (argumentNames == null || argumentNames.length < max) {
+			argumentNames = new char[max][];
+			for (int j = 0; j < max; j++) {
+				argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$
+			}
+		}
+		int startIndex = 0;
+		try {
+			if (isConstructor) {
+				if (type.isEnum()) {
+					startIndex = 2;
+				} else if (type.isMember()
+						&& !Flags.isStatic(type.getFlags())) {
+					startIndex = 1;
+				}
+			}
+		} catch(JavaModelException e) {
+			// ignore
+		}
+		for (int j = startIndex; j < max; j++) {
+			IBinaryAnnotation[] parameterAnnotations = methodInfo.getParameterAnnotations(j - startIndex);
+			if (parameterAnnotations != null) {
+				LocalVariable localVariable = new LocalVariable(
+						method,
+						new String(argumentNames[j]),
+						0,
+						-1,
+						0,
+						-1,
+						method.parameterTypes[j],
+						null,
+						-1,
+						true);
+				generateAnnotationsInfos(localVariable, argumentNames[j], parameterAnnotations, methodInfo.getTagBits(), newElements);
+			}
+		}
+		generateTypeParameterInfos(method, signature, newElements, typeParameterHandles);
+		generateAnnotationsInfos(method, methodInfo.getAnnotations(), methodInfo.getTagBits(), newElements);
+		Object defaultValue = methodInfo.getDefaultValue();
+		if (defaultValue instanceof IBinaryAnnotation) {
+			generateAnnotationInfo(method, newElements, (IBinaryAnnotation) defaultValue, new String(methodInfo.getSelector()));
+		}
+	}
+}
+/**
+ * Creates the handles and infos for the type parameter of the given binary member.
+ * Adds new handles to the given vector.
+ */
+private void generateTypeParameterInfos(BinaryMember parent, char[] signature, HashMap newElements, ArrayList typeParameterHandles) {
+	if (signature == null) return;
+	char[][] typeParameterSignatures = Signature.getTypeParameters(signature);
+	for (int i = 0, typeParameterCount = typeParameterSignatures.length; i < typeParameterCount; i++) {
+		char[] typeParameterSignature = typeParameterSignatures[i];
+		char[] typeParameterName = Signature.getTypeVariable(typeParameterSignature);
+		CharOperation.replace(typeParameterSignature, '/', '.');
+		char[][] typeParameterBoundSignatures = Signature.getTypeParameterBounds(typeParameterSignature);
+		int boundLength = typeParameterBoundSignatures.length;
+		char[][] typeParameterBounds = new char[boundLength][];
+		for (int j = 0; j < boundLength; j++) {
+			typeParameterBounds[j] = Signature.toCharArray(typeParameterBoundSignatures[j]);
+		}
+		TypeParameter typeParameter = new TypeParameter(parent, new String(typeParameterName));
+		TypeParameterElementInfo info = new TypeParameterElementInfo();
+		info.bounds = typeParameterBounds;
+		info.boundsSignatures = typeParameterBoundSignatures;
+		typeParameterHandles.add(typeParameter);
+
+		// ensure that 2 binary methods with the same signature but with different return types have different occurence counts.
+		// (case of bridge methods in 1.5)
+		while (newElements.containsKey(typeParameter))
+			typeParameter.occurrenceCount++;
+
+		newElements.put(typeParameter, info);
+	}
+}
+/**
+ * Returns true iff the <code>readBinaryChildren</code> has already
+ * been called.
+ */
+boolean hasReadBinaryChildren() {
+	return this.binaryChildren != null;
+}
+/**
+ * Creates the handles for <code>BinaryMember</code>s defined in this
+ * <code>ClassFile</code> and adds them to the
+ * <code>JavaModelManager</code>'s cache.
+ */
+protected void readBinaryChildren(ClassFile classFile, HashMap newElements, IBinaryType typeInfo) {
+	ArrayList childrenHandles = new ArrayList();
+	BinaryType type = (BinaryType) classFile.getType();
+	ArrayList typeParameterHandles = new ArrayList();
+	if (typeInfo != null) { //may not be a valid class file
+		generateAnnotationsInfos(type, typeInfo.getAnnotations(), typeInfo.getTagBits(), newElements);
+		generateTypeParameterInfos(type, typeInfo.getGenericSignature(), newElements, typeParameterHandles);
+		generateFieldInfos(type, typeInfo, newElements, childrenHandles);
+		generateMethodInfos(type, typeInfo, newElements, childrenHandles, typeParameterHandles);
+		generateInnerClassHandles(type, typeInfo, childrenHandles); // Note inner class are separate openables that are not opened here: no need to pass in newElements
+	}
+
+	this.binaryChildren = new JavaElement[childrenHandles.size()];
+	childrenHandles.toArray(this.binaryChildren);
+	int typeParameterHandleSize = typeParameterHandles.size();
+	if (typeParameterHandleSize == 0) {
+		this.typeParameters = TypeParameter.NO_TYPE_PARAMETERS;
+	} else {
+		this.typeParameters = new ITypeParameter[typeParameterHandleSize];
+		typeParameterHandles.toArray(this.typeParameters);
+	}
+}
+/**
+ * Removes the binary children handles and remove their infos from
+ * the <code>JavaModelManager</code>'s cache.
+ */
+void removeBinaryChildren() throws JavaModelException {
+	if (this.binaryChildren != null) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		for (int i = 0; i <this.binaryChildren.length; i++) {
+			JavaElement child = this.binaryChildren[i];
+			if (child instanceof BinaryType) {
+				manager.removeInfoAndChildren((JavaElement)child.getParent());
+			} else {
+				manager.removeInfoAndChildren(child);
+			}
+		}
+		this.binaryChildren = JavaElement.NO_ELEMENTS;
+	}
+	if (this.typeParameters != null) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		for (int i = 0; i <this.typeParameters.length; i++) {
+			TypeParameter typeParameter = (TypeParameter) this.typeParameters[i];
+			manager.removeInfoAndChildren(typeParameter);
+		}
+		this.typeParameters = TypeParameter.NO_TYPE_PARAMETERS;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java
new file mode 100644
index 0000000..4c085ce
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for Bug 337935 - Test failures when run as an IDE (org.eclipse.sdk.ide)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.internal.core.util.Disassembler;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A working copy on an <code>IClassFile</code>.
+ */
+public class ClassFileWorkingCopy extends CompilationUnit {
+
+	public ClassFile classFile;
+
+public ClassFileWorkingCopy(ClassFile classFile, WorkingCopyOwner owner) {
+	super((PackageFragment) classFile.getParent(), ((BinaryType) classFile.getType()).getSourceFileName(null/*no info available*/), owner);
+	this.classFile = classFile;
+}
+
+public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
+}
+
+public IBuffer getBuffer() throws JavaModelException {
+	if (isWorkingCopy())
+		return super.getBuffer();
+	else
+		return this.classFile.getBuffer();
+}
+
+public char[] getContents() {
+	try {
+		IBuffer buffer = getBuffer();
+		if (buffer == null) return CharOperation.NO_CHAR;
+		char[] characters = buffer.getCharacters();
+		if (characters == null) return CharOperation.NO_CHAR;
+		return characters;
+	} catch (JavaModelException e) {
+		return CharOperation.NO_CHAR;
+	}
+}
+
+public IPath getPath() {
+	return this.classFile.getPath();
+}
+
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner && isPrimary()) return this;
+	return new ClassFileWorkingCopy(this.classFile, DefaultWorkingCopyOwner.PRIMARY);
+}
+
+public IResource resource(PackageFragmentRoot root) {
+	if (root.isArchive())
+		return root.resource(root);
+	return this.classFile.resource(root);
+}
+
+/**
+ * @see Openable#openBuffer(IProgressMonitor, Object)
+ */
+protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
+
+	// create buffer
+	IBuffer buffer = BufferManager.createBuffer(this);
+
+	// set the buffer source
+	IBuffer classFileBuffer = this.classFile.getBuffer();
+	if (classFileBuffer != null) {
+		buffer.setContents(classFileBuffer.getCharacters());
+	} else {
+		// Disassemble
+		IClassFileReader reader = ToolFactory.createDefaultClassFileReader(this.classFile, IClassFileReader.ALL);
+		Disassembler disassembler = new Disassembler();
+		String contents = disassembler.disassemble(reader, Util.getLineSeparator("", getJavaProject()), ClassFileBytesDisassembler.WORKING_COPY); //$NON-NLS-1$
+		buffer.setContents(contents);
+	}
+
+	// add buffer to buffer cache
+	BufferManager bufManager = getBufferManager();
+	bufManager.addBuffer(buffer);
+
+	// listen to buffer changes
+	buffer.addBufferChangedListener(this);
+
+	return buffer;
+}
+
+protected void toStringName(StringBuffer buffer) {
+	buffer.append(this.classFile.getElementName());
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java
new file mode 100644
index 0000000..199fde3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+
+public class ClasspathAccessRule extends AccessRule implements IAccessRule {
+
+	public ClasspathAccessRule(IPath pattern, int kind) {
+		this(pattern.toString().toCharArray(), toProblemId(kind));
+	}
+
+	public ClasspathAccessRule(char[] pattern, int problemId) {
+		super(pattern, problemId);
+	}
+
+	private static int toProblemId(int kind) {
+		boolean ignoreIfBetter = (kind & IAccessRule.IGNORE_IF_BETTER) != 0;
+		switch (kind & ~IAccessRule.IGNORE_IF_BETTER) {
+			case K_NON_ACCESSIBLE:
+				return ignoreIfBetter ? IProblem.ForbiddenReference | AccessRule.IgnoreIfBetter : IProblem.ForbiddenReference;
+			case K_DISCOURAGED:
+				return ignoreIfBetter ? IProblem.DiscouragedReference | AccessRule.IgnoreIfBetter : IProblem.DiscouragedReference;
+			default:
+				return ignoreIfBetter ? AccessRule.IgnoreIfBetter : 0;
+		}
+	}
+
+	public IPath getPattern() {
+		return new Path(new String(this.pattern));
+	}
+
+	public int getKind() {
+		switch (getProblemId()) {
+			case IProblem.ForbiddenReference:
+				return K_NON_ACCESSIBLE;
+			case IProblem.DiscouragedReference:
+				return K_DISCOURAGED;
+			default:
+				return K_ACCESSIBLE;
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java
new file mode 100644
index 0000000..b1f1b36
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathAttribute implements IClasspathAttribute {
+
+	private String name;
+	private String value;
+
+	public ClasspathAttribute(String name, String value) {
+		this.name = name;
+		this.value = value;
+	}
+
+	public boolean equals(Object obj) {
+		if (!(obj instanceof ClasspathAttribute)) return false;
+		ClasspathAttribute other = (ClasspathAttribute) obj;
+		return this.name.equals(other.name) && this.value.equals(other.value);
+	}
+
+    public String getName() {
+		return this.name;
+    }
+
+    public String getValue() {
+		return this.value;
+    }
+
+    public int hashCode() {
+     	return Util.combineHashCodes(this.name.hashCode(), this.value.hashCode());
+    }
+
+    public String toString() {
+    	return this.name + "=" + this.value; //$NON-NLS-1$
+    }
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java
new file mode 100644
index 0000000..7a461df
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathChange.java
@@ -0,0 +1,561 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.core.DeltaProcessor.RootInfo;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathChange {
+	public static final int NO_DELTA = 0x00;
+	public static final int HAS_DELTA = 0x01;
+	public static final int HAS_PROJECT_CHANGE = 0x02;
+	public static final int HAS_LIBRARY_CHANGE = 0x04;
+
+	JavaProject project;
+	IClasspathEntry[] oldRawClasspath;
+	IPath oldOutputLocation;
+	IClasspathEntry[] oldResolvedClasspath;
+
+	public ClasspathChange(JavaProject project, IClasspathEntry[] oldRawClasspath, IPath oldOutputLocation, IClasspathEntry[] oldResolvedClasspath) {
+		this.project = project;
+		this.oldRawClasspath = oldRawClasspath;
+		this.oldOutputLocation = oldOutputLocation;
+		this.oldResolvedClasspath = oldResolvedClasspath;
+	}
+
+	private void addClasspathDeltas(JavaElementDelta delta, IPackageFragmentRoot[] roots, int flag) {
+		for (int i = 0; i < roots.length; i++) {
+			IPackageFragmentRoot root = roots[i];
+			delta.changed(root, flag);
+			if ((flag & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0
+					|| (flag & IJavaElementDelta.F_SOURCEATTACHED) != 0
+					|| (flag & IJavaElementDelta.F_SOURCEDETACHED) != 0){
+				try {
+					root.close();
+				} catch (JavaModelException e) {
+					// ignore
+				}
+			}
+		}
+	}
+
+	/*
+	 * Returns the index of the item in the list if the given list contains the specified entry. If the list does
+	 * not contain the entry, -1 is returned.
+	 */
+	private int classpathContains(IClasspathEntry[] list, IClasspathEntry entry) {
+		IPath[] exclusionPatterns = entry.getExclusionPatterns();
+		IPath[] inclusionPatterns = entry.getInclusionPatterns();
+		int listLen = list == null ? 0 : list.length;
+		nextEntry: for (int i = 0; i < listLen; i++) {
+			IClasspathEntry other = list[i];
+			if (other.getContentKind() == entry.getContentKind()
+				&& other.getEntryKind() == entry.getEntryKind()
+				&& other.isExported() == entry.isExported()
+				&& other.getPath().equals(entry.getPath())) {
+					// check custom outputs
+					IPath entryOutput = entry.getOutputLocation();
+					IPath otherOutput = other.getOutputLocation();
+					if (entryOutput == null) {
+						if (otherOutput != null)
+							continue;
+					} else {
+						if (!entryOutput.equals(otherOutput))
+							continue;
+					}
+
+					// check inclusion patterns
+					IPath[] otherIncludes = other.getInclusionPatterns();
+					if (inclusionPatterns != otherIncludes) {
+					    if (inclusionPatterns == null) continue;
+						int includeLength = inclusionPatterns.length;
+						if (otherIncludes == null || otherIncludes.length != includeLength)
+							continue;
+						for (int j = 0; j < includeLength; j++) {
+							// compare toStrings instead of IPaths
+							// since IPath.equals is specified to ignore trailing separators
+							if (!inclusionPatterns[j].toString().equals(otherIncludes[j].toString()))
+								continue nextEntry;
+						}
+					}
+					// check exclusion patterns
+					IPath[] otherExcludes = other.getExclusionPatterns();
+					if (exclusionPatterns != otherExcludes) {
+					    if (exclusionPatterns == null) continue;
+						int excludeLength = exclusionPatterns.length;
+						if (otherExcludes == null || otherExcludes.length != excludeLength)
+							continue;
+						for (int j = 0; j < excludeLength; j++) {
+							// compare toStrings instead of IPaths
+							// since IPath.equals is specified to ignore trailing separators
+							if (!exclusionPatterns[j].toString().equals(otherExcludes[j].toString()))
+								continue nextEntry;
+						}
+					}
+					return i;
+			}
+		}
+		return -1;
+	}
+
+	/*
+	 * Recursively adds all subfolders of <code>folder</code> to the given collection.
+	 */
+	private void collectAllSubfolders(IFolder folder, ArrayList collection) throws JavaModelException {
+		try {
+			IResource[] members= folder.members();
+			for (int i = 0, max = members.length; i < max; i++) {
+				IResource r= members[i];
+				if (r.getType() == IResource.FOLDER) {
+					collection.add(r);
+					collectAllSubfolders((IFolder)r, collection);
+				}
+			}
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+
+	/*
+	 * Returns a collection of package fragments that have been added/removed
+	 * as the result of changing the output location to/from the given
+	 * location. The collection is empty if no package fragments are
+	 * affected.
+	 */
+	private ArrayList determineAffectedPackageFragments(IPath location) throws JavaModelException {
+		ArrayList fragments = new ArrayList();
+
+		// see if this will cause any package fragments to be affected
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		IResource resource = null;
+		if (location != null) {
+			resource = workspace.getRoot().findMember(location);
+		}
+		if (resource != null && resource.getType() == IResource.FOLDER) {
+			IFolder folder = (IFolder) resource;
+			// only changes if it actually existed
+			IClasspathEntry[] classpath = this.project.getExpandedClasspath();
+			for (int i = 0; i < classpath.length; i++) {
+				IClasspathEntry entry = classpath[i];
+				IPath path = classpath[i].getPath();
+				if (entry.getEntryKind() != IClasspathEntry.CPE_PROJECT && path.isPrefixOf(location) && !path.equals(location)) {
+					IPackageFragmentRoot[] roots = this.project.computePackageFragmentRoots(classpath[i]);
+					PackageFragmentRoot root = (PackageFragmentRoot) roots[0];
+					// now the output location becomes a package fragment - along with any subfolders
+					ArrayList folders = new ArrayList();
+					folders.add(folder);
+					collectAllSubfolders(folder, folders);
+					Iterator elements = folders.iterator();
+					int segments = path.segmentCount();
+					while (elements.hasNext()) {
+						IFolder f = (IFolder) elements.next();
+						IPath relativePath = f.getFullPath().removeFirstSegments(segments);
+						String[] pkgName = relativePath.segments();
+						IPackageFragment pkg = root.getPackageFragment(pkgName);
+						if (!Util.isExcluded(pkg))
+							fragments.add(pkg);
+					}
+				}
+			}
+		}
+		return fragments;
+	}
+
+	public boolean equals(Object obj) {
+		if (!(obj instanceof ClasspathChange))
+			return false;
+		return this.project.equals(((ClasspathChange) obj).project);
+	}
+
+	/*
+	 * Generates a classpath change delta for this classpath change.
+	 * Returns whether a delta was generated, and whether project reference have changed.
+	 */
+	public int generateDelta(JavaElementDelta delta, boolean addClasspathChange) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		DeltaProcessingState state = manager.deltaState;
+		if (state.findJavaProject(this.project.getElementName()) == null)
+			// project doesn't exist yet (we're in an IWorkspaceRunnable)
+			// no need to create a delta here and no need to index (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=133334)
+			// the delta processor will create an ADDED project delta, and index the project
+			return NO_DELTA;
+
+		DeltaProcessor deltaProcessor = state.getDeltaProcessor();
+		IClasspathEntry[] newResolvedClasspath = null;
+		IPath newOutputLocation = null;
+		int result = NO_DELTA;
+		try {
+			PerProjectInfo perProjectInfo = this.project.getPerProjectInfo();
+
+			// get new info
+			this.project.resolveClasspath(perProjectInfo, false/*don't use previous session values*/, addClasspathChange);
+			IClasspathEntry[] newRawClasspath;
+
+			// use synchronized block to ensure consistency
+			synchronized (perProjectInfo) {
+				newRawClasspath = perProjectInfo.rawClasspath;
+				newResolvedClasspath = perProjectInfo.getResolvedClasspath();
+				newOutputLocation = perProjectInfo.outputLocation;
+			}
+
+			if (newResolvedClasspath == null) {
+				// another thread reset the resolved classpath, use a temporary PerProjectInfo
+				PerProjectInfo temporaryInfo = this.project.newTemporaryInfo();
+				this.project.resolveClasspath(temporaryInfo, false/*don't use previous session values*/, addClasspathChange);
+				newRawClasspath = temporaryInfo.rawClasspath;
+				newResolvedClasspath = temporaryInfo.getResolvedClasspath();
+				newOutputLocation = temporaryInfo.outputLocation;
+			}
+
+			// check if raw classpath has changed
+			if (this.oldRawClasspath != null && !JavaProject.areClasspathsEqual(this.oldRawClasspath, newRawClasspath, this.oldOutputLocation, newOutputLocation)) {
+				delta.changed(this.project, IJavaElementDelta.F_CLASSPATH_CHANGED);
+				result |= HAS_DELTA;
+
+				// reset containers that are no longer on the classpath
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=139446)
+				for (int i = 0, length = this.oldRawClasspath.length; i < length; i++) {
+					IClasspathEntry entry = this.oldRawClasspath[i];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+						if (classpathContains(newRawClasspath, entry) == -1)
+							manager.containerPut(this.project, entry.getPath(), null);
+					}
+				}
+			}
+
+			// if no changes to resolved classpath, nothing more to do
+			if (this.oldResolvedClasspath != null && JavaProject.areClasspathsEqual(this.oldResolvedClasspath, newResolvedClasspath, this.oldOutputLocation, newOutputLocation))
+				return result;
+
+			// close cached info
+			this.project.close();
+
+			// ensure caches of dependent projects are reset as well (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=207890)
+			deltaProcessor.projectCachesToReset.add(this.project);
+		} catch (JavaModelException e) {
+			if (DeltaProcessor.VERBOSE) {
+				e.printStackTrace();
+			}
+			// project no longer exist
+			return result;
+		}
+
+		if (this.oldResolvedClasspath == null)
+			return result;
+
+		delta.changed(this.project, IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED);
+		result |= HAS_DELTA;
+
+		state.addForRefresh(this.project); // ensure external jars are refreshed for this project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769 )
+
+		Map removedRoots = null;
+		IPackageFragmentRoot[] roots = null;
+		Map allOldRoots ;
+		if ((allOldRoots = deltaProcessor.oldRoots) != null) {
+	 		roots = (IPackageFragmentRoot[]) allOldRoots.get(this.project);
+		}
+		if (roots != null) {
+			removedRoots = new HashMap();
+			for (int i = 0; i < roots.length; i++) {
+				IPackageFragmentRoot root = roots[i];
+				removedRoots.put(root.getPath(), root);
+			}
+		}
+
+		int newLength = newResolvedClasspath.length;
+		int oldLength = this.oldResolvedClasspath.length;
+		for (int i = 0; i < oldLength; i++) {
+			int index = classpathContains(newResolvedClasspath, this.oldResolvedClasspath[i]);
+			if (index == -1) {
+				// remote project changes
+				int entryKind = this.oldResolvedClasspath[i].getEntryKind();
+				if (entryKind == IClasspathEntry.CPE_PROJECT) {
+					result |= HAS_PROJECT_CHANGE;
+					continue;
+				}
+				if (entryKind == IClasspathEntry.CPE_LIBRARY) {
+					result |= HAS_LIBRARY_CHANGE;
+				}
+
+				IPackageFragmentRoot[] pkgFragmentRoots = null;
+				if (removedRoots != null) {
+					PackageFragmentRoot oldRoot = (PackageFragmentRoot)  removedRoots.get(this.oldResolvedClasspath[i].getPath());
+					if (oldRoot != null) { // use old root if any (could be none if entry wasn't bound)
+						pkgFragmentRoots = new PackageFragmentRoot[] { oldRoot };
+					}
+				}
+				if (pkgFragmentRoots == null) {
+					try {
+						ObjectVector accumulatedRoots = new ObjectVector();
+						HashSet rootIDs = new HashSet(5);
+						rootIDs.add(this.project.rootID());
+						this.project.computePackageFragmentRoots(
+							this.oldResolvedClasspath[i],
+							accumulatedRoots,
+							rootIDs,
+							null, // inside original project
+							false, // don't retrieve exported roots
+							null); /*no reverse map*/
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=335986
+						// When a package fragment's corresponding resource is removed from the project, 
+						// IJavaProject#computePackageFragmentRoots() doesn't include that entry. Hence 
+						// the cache become necessary in such cases. Add the cache to the accumulatedRoots 
+						// only when it's not already present.
+						RootInfo rootInfo = (RootInfo) state.oldRoots.get(this.oldResolvedClasspath[i].getPath());
+						if (rootInfo != null && rootInfo.cache != null) {
+							IPackageFragmentRoot oldRoot = rootInfo.cache;
+							boolean found = false;
+							for (int j = 0; j < accumulatedRoots.size(); j++) {
+								IPackageFragmentRoot root = (IPackageFragmentRoot) accumulatedRoots.elementAt(j);
+								if (root.getPath().equals(oldRoot.getPath())) {
+									found = true;
+									break;
+								}
+							}
+							if (!found)
+								accumulatedRoots.add(oldRoot);
+						}
+
+						pkgFragmentRoots = new PackageFragmentRoot[accumulatedRoots.size()];
+						accumulatedRoots.copyInto(pkgFragmentRoots);
+					} catch (JavaModelException e) {
+						pkgFragmentRoots =  new PackageFragmentRoot[] {};
+					}
+				}
+				addClasspathDeltas(delta, pkgFragmentRoots, IJavaElementDelta.F_REMOVED_FROM_CLASSPATH);
+			} else {
+				// remote project changes
+				if (this.oldResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+					result |= HAS_PROJECT_CHANGE;
+					continue;
+				}
+				if (index != i) { //reordering of the classpath
+					addClasspathDeltas(delta, this.project.computePackageFragmentRoots(this.oldResolvedClasspath[i]),	IJavaElementDelta.F_REORDER);
+				}
+
+				// check source attachment
+				IPath newSourcePath = newResolvedClasspath[index].getSourceAttachmentPath();
+				int sourceAttachmentFlags = getSourceAttachmentDeltaFlag(this.oldResolvedClasspath[i].getSourceAttachmentPath(), newSourcePath);
+				IPath oldRootPath = this.oldResolvedClasspath[i].getSourceAttachmentRootPath();
+				IPath newRootPath = newResolvedClasspath[index].getSourceAttachmentRootPath();
+				int sourceAttachmentRootFlags = getSourceAttachmentDeltaFlag(oldRootPath, newRootPath);
+				int flags = sourceAttachmentFlags | sourceAttachmentRootFlags;
+				if (flags != 0) {
+					addClasspathDeltas(delta, this.project.computePackageFragmentRoots(this.oldResolvedClasspath[i]), flags);
+				} else {
+					if (oldRootPath == null && newRootPath == null) {
+						// if source path is specified and no root path, it needs to be recomputed dynamically
+						// force detach source on jar package fragment roots (source will be lazily computed when needed)
+						IPackageFragmentRoot[] computedRoots = this.project.computePackageFragmentRoots(this.oldResolvedClasspath[i]);
+						for (int j = 0; j < computedRoots.length; j++) {
+							IPackageFragmentRoot root = computedRoots[j];
+							// force detach source on jar package fragment roots (source will be lazily computed when needed)
+							try {
+								root.close();
+							} catch (JavaModelException e) {
+								// ignore
+							}
+						}
+					}
+				}
+			}
+		}
+
+		for (int i = 0; i < newLength; i++) {
+			int index = classpathContains(this.oldResolvedClasspath, newResolvedClasspath[i]);
+			if (index == -1) {
+				// remote project changes
+				int entryKind = newResolvedClasspath[i].getEntryKind();
+				if (entryKind == IClasspathEntry.CPE_PROJECT) {
+					result |= HAS_PROJECT_CHANGE;
+					continue;
+				}
+				if (entryKind == IClasspathEntry.CPE_LIBRARY) {
+					result |= HAS_LIBRARY_CHANGE;
+				}
+				addClasspathDeltas(delta, this.project.computePackageFragmentRoots(newResolvedClasspath[i]), IJavaElementDelta.F_ADDED_TO_CLASSPATH);
+			} // classpath reordering has already been generated in previous loop
+		}
+
+		// see if a change in output location will cause any package fragments to be added/removed
+		if ((newOutputLocation == null && this.oldOutputLocation != null)
+				|| (newOutputLocation != null && !newOutputLocation.equals(this.oldOutputLocation))) {
+			try {
+				ArrayList added = determineAffectedPackageFragments(this.oldOutputLocation);
+				Iterator iter = added.iterator();
+				while (iter.hasNext()){
+					IPackageFragment frag= (IPackageFragment)iter.next();
+					((IPackageFragmentRoot)frag.getParent()).close();
+					delta.added(frag);
+				}
+
+				// see if this will cause any package fragments to be removed
+				ArrayList removed = determineAffectedPackageFragments(newOutputLocation);
+				iter = removed.iterator();
+				while (iter.hasNext()) {
+					IPackageFragment frag= (IPackageFragment)iter.next();
+					((IPackageFragmentRoot)frag.getParent()).close();
+					delta.removed(frag);
+				}
+			} catch (JavaModelException e) {
+				if (DeltaProcessor.VERBOSE)
+					e.printStackTrace();
+			}
+		}
+
+		return result;
+	}
+
+	/*
+	 * Returns the source attachment flag for the delta between the 2 give source paths.
+	 * Returns either F_SOURCEATTACHED, F_SOURCEDETACHED, F_SOURCEATTACHED | F_SOURCEDETACHED
+	 * or 0 if there is no difference.
+	 */
+	private int getSourceAttachmentDeltaFlag(IPath oldPath, IPath newPath) {
+		if (oldPath == null) {
+			if (newPath != null) {
+				return IJavaElementDelta.F_SOURCEATTACHED;
+			} else {
+				return 0;
+			}
+		} else if (newPath == null) {
+			return IJavaElementDelta.F_SOURCEDETACHED;
+		} else if (!oldPath.equals(newPath)) {
+			return IJavaElementDelta.F_SOURCEATTACHED | IJavaElementDelta.F_SOURCEDETACHED;
+		} else {
+			return 0;
+		}
+	}
+
+	public int hashCode() {
+		return this.project.hashCode();
+	}
+
+	/*
+	 * Request the indexing of entries that have been added, and remove the index for removed entries.
+	 */
+	public void requestIndexing() {
+		IClasspathEntry[] newResolvedClasspath = null;
+		try {
+			newResolvedClasspath = this.project.getResolvedClasspath();
+		} catch (JavaModelException e) {
+			// project doesn't exist
+			return;
+		}
+
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IndexManager indexManager = manager.indexManager;
+		if (indexManager == null)
+			return;
+		DeltaProcessingState state = manager.deltaState;
+
+		int newLength = newResolvedClasspath.length;
+		int oldLength = this.oldResolvedClasspath == null ? 0 : this.oldResolvedClasspath.length;
+		for (int i = 0; i < oldLength; i++) {
+			int index = classpathContains(newResolvedClasspath, this.oldResolvedClasspath[i]);
+			if (index == -1) {
+				// remote projects are not indexed in this project
+				if (this.oldResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
+					continue;
+				}
+
+				// Remove the .java files from the index for a source folder
+				// For a lib folder or a .jar file, remove the corresponding index if not shared.
+				IClasspathEntry oldEntry = this.oldResolvedClasspath[i];
+				final IPath path = oldEntry.getPath();
+				int changeKind = this.oldResolvedClasspath[i].getEntryKind();
+				switch (changeKind) {
+					case IClasspathEntry.CPE_SOURCE:
+						char[][] inclusionPatterns = ((ClasspathEntry)oldEntry).fullInclusionPatternChars();
+						char[][] exclusionPatterns = ((ClasspathEntry)oldEntry).fullExclusionPatternChars();
+						indexManager.removeSourceFolderFromIndex(this.project, path, inclusionPatterns, exclusionPatterns);
+						break;
+					case IClasspathEntry.CPE_LIBRARY:
+						if (state.otherRoots.get(path) == null) { // if root was not shared
+							indexManager.discardJobs(path.toString());
+							indexManager.removeIndex(path);
+							// TODO (kent) we could just remove the in-memory index and have the indexing check for timestamps
+						}
+						break;
+				}
+			}
+		}
+
+		for (int i = 0; i < newLength; i++) {
+			int index = classpathContains(this.oldResolvedClasspath, newResolvedClasspath[i]);
+			if (index == -1 || newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+				// remote projects are not indexed in this project
+				if (newResolvedClasspath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT){
+					continue;
+				}
+
+				// Request indexing
+				int entryKind = newResolvedClasspath[i].getEntryKind();
+				URL newurl = ((ClasspathEntry)newResolvedClasspath[i]).getLibraryIndexLocation();
+				switch (entryKind) {
+					case IClasspathEntry.CPE_LIBRARY:
+						boolean pathHasChanged = true;
+						IPath newPath = newResolvedClasspath[i].getPath();
+						for (int j = 0; j < oldLength; j++) {
+							IClasspathEntry oldEntry = this.oldResolvedClasspath[j];
+							if (oldEntry.getPath().equals(newPath)) {
+								URL oldurl = ((ClasspathEntry)oldEntry).getLibraryIndexLocation();
+								if (oldurl == null && newurl == null) {
+									pathHasChanged = false;
+								} else if (oldurl != null && newurl != null) {
+									pathHasChanged = !(newurl.equals(oldurl));
+								} else if (oldurl != null) {
+									indexManager.removeIndex(newPath);
+								}
+								break;
+							}
+						}
+						if (pathHasChanged) {
+							indexManager.indexLibrary(newPath, this.project.getProject(), newurl);
+						}
+						break;
+					case IClasspathEntry.CPE_SOURCE:
+						IClasspathEntry entry = newResolvedClasspath[i];
+						IPath path = entry.getPath();
+						char[][] inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
+						char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
+						indexManager.indexSourceFolder(this.project, path, inclusionPatterns, exclusionPatterns);
+						break;
+				}
+			}
+		}
+	}
+
+	public String toString() {
+		return "ClasspathChange: " + this.project.getElementName(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
new file mode 100644
index 0000000..ee35713
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -0,0 +1,2245 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * @see IClasspathEntry
+ */
+public class ClasspathEntry implements IClasspathEntry {
+	
+	public static class AssertionFailedException extends RuntimeException {
+		
+		private static final long serialVersionUID = -171699380721189572L;
+
+		public AssertionFailedException(String message) {
+			super(message);
+		}
+	}
+
+	public static final String TAG_CLASSPATH = "classpath"; //$NON-NLS-1$
+	public static final String TAG_CLASSPATHENTRY = "classpathentry"; //$NON-NLS-1$
+	public static final String TAG_REFERENCED_ENTRY = "referencedentry"; //$NON-NLS-1$
+	public static final String TAG_OUTPUT = "output"; //$NON-NLS-1$
+	public static final String TAG_KIND = "kind"; //$NON-NLS-1$
+	public static final String TAG_PATH = "path"; //$NON-NLS-1$
+	public static final String TAG_SOURCEPATH = "sourcepath"; //$NON-NLS-1$
+	public static final String TAG_ROOTPATH = "rootpath"; //$NON-NLS-1$
+	public static final String TAG_EXPORTED = "exported"; //$NON-NLS-1$
+	public static final String TAG_INCLUDING = "including"; //$NON-NLS-1$
+	public static final String TAG_EXCLUDING = "excluding"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
+	public static final String TAG_COMBINE_ACCESS_RULES = "combineaccessrules"; //$NON-NLS-1$
+	public static final String TAG_ACCESS_RULES = "accessrules"; //$NON-NLS-1$
+	public static final String TAG_ACCESS_RULE = "accessrule"; //$NON-NLS-1$
+	public static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
+	public static final String TAG_ACCESSIBLE = "accessible"; //$NON-NLS-1$
+	public static final String TAG_NON_ACCESSIBLE = "nonaccessible"; //$NON-NLS-1$
+	public static final String TAG_DISCOURAGED = "discouraged"; //$NON-NLS-1$
+	public static final String TAG_IGNORE_IF_BETTER = "ignoreifbetter"; //$NON-NLS-1$
+
+	/**
+	 * Describes the kind of classpath entry - one of
+	 * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE or CPE_CONTAINER
+	 */
+	public int entryKind;
+
+	/**
+	 * Describes the kind of package fragment roots found on
+	 * this classpath entry - either K_BINARY or K_SOURCE or
+	 * K_OUTPUT.
+	 */
+	public int contentKind;
+
+	/**
+	 * The meaning of the path of a classpath entry depends on its entry kind:<ul>
+	 *	<li>Source code in the current project (<code>CPE_SOURCE</code>) -
+	 *      The path associated with this entry is the absolute path to the root folder. </li>
+	 *	<li>A binary library in the current project (<code>CPE_LIBRARY</code>) - the path
+	 *		associated with this entry is the absolute path to the JAR (or root folder), and
+	 *		in case it refers to an external JAR, then there is no associated resource in
+	 *		the workbench.
+	 *	<li>A required project (<code>CPE_PROJECT</code>) - the path of the entry denotes the
+	 *		path to the corresponding project resource.</li>
+	 *  <li>A variable entry (<code>CPE_VARIABLE</code>) - the first segment of the path
+	 *      is the name of a classpath variable. If this classpath variable
+	 *		is bound to the path <it>P</it>, the path of the corresponding classpath entry
+	 *		is computed by appending to <it>P</it> the segments of the returned
+	 *		path without the variable.</li>
+	 *  <li> A container entry (<code>CPE_CONTAINER</code>) - the first segment of the path is denoting
+	 *     the unique container identifier (for which a <code>ClasspathContainerInitializer</code> could be
+	 * 	registered), and the remaining segments are used as additional hints for resolving the container entry to
+	 * 	an actual <code>IClasspathContainer</code>.</li>
+	 */
+	public IPath path;
+
+	/**
+	 * Patterns allowing to include/exclude portions of the resource tree denoted by this entry path.
+	 */
+	private IPath[] inclusionPatterns;
+	private char[][] fullInclusionPatternChars;
+	private IPath[] exclusionPatterns;
+	private char[][] fullExclusionPatternChars;
+	private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$
+	public final static ClasspathEntry[] NO_ENTRIES = new ClasspathEntry[0];
+	private final static IPath[] NO_PATHS = new IPath[0];
+	private final static IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+	private boolean combineAccessRules;
+
+	private String rootID;
+	private AccessRuleSet accessRuleSet;
+
+
+	static class UnknownXmlElements {
+		String[] attributes;
+		ArrayList children;
+	}
+
+	/*
+	 * Default inclusion pattern set
+	 */
+	public final static IPath[] INCLUDE_ALL = {};
+
+	/*
+	 * Default exclusion pattern set
+	 */
+	public final static IPath[] EXCLUDE_NONE = {};
+
+	/*
+	 * Default extra attributes
+	 */
+	public final static IClasspathAttribute[] NO_EXTRA_ATTRIBUTES = {};
+
+	/*
+	 * Default access rules
+	 */
+	public final static IAccessRule[] NO_ACCESS_RULES = {};
+
+	/**
+	 * Describes the path to the source archive associated with this
+	 * classpath entry, or <code>null</code> if this classpath entry has no
+	 * source attachment.
+	 * <p>
+	 * Only library and variable classpath entries may have source attachments.
+	 * For library classpath entries, the result path (if present) locates a source
+	 * archive. For variable classpath entries, the result path (if present) has
+	 * an analogous form and meaning as the variable path, namely the first segment
+	 * is the name of a classpath variable.
+	 */
+	public IPath sourceAttachmentPath;
+
+	/**
+	 * Describes the path within the source archive where package fragments
+	 * are located. An empty path indicates that packages are located at
+	 * the root of the source archive. Returns a non-<code>null</code> value
+	 * if and only if <code>getSourceAttachmentPath</code> returns
+	 * a non-<code>null</code> value.
+	 */
+	public IPath sourceAttachmentRootPath;
+	
+	/**
+	 * See {@link IClasspathEntry#getReferencingEntry()}
+	 */
+	public IClasspathEntry referencingEntry;
+
+	/**
+	 * Specific output location (for this source entry)
+	 */
+	public IPath specificOutputLocation;
+
+	/**
+	 * A constant indicating an output location.
+	 */
+	public static final int K_OUTPUT = 10;
+	
+	public static final String DOT_DOT = ".."; //$NON-NLS-1$
+
+	/**
+	 * The export flag
+	 */
+	public boolean isExported;
+
+	/**
+	 * The extra attributes
+	 */
+	public IClasspathAttribute[] extraAttributes;
+
+	public ClasspathEntry(
+			int contentKind,
+			int entryKind,
+			IPath path,
+			IPath[] inclusionPatterns,
+			IPath[] exclusionPatterns,
+			IPath sourceAttachmentPath,
+			IPath sourceAttachmentRootPath,
+			IPath specificOutputLocation,
+			boolean isExported,
+			IAccessRule[] accessRules,
+			boolean combineAccessRules,
+			IClasspathAttribute[] extraAttributes) {
+
+		this(	contentKind, 
+				entryKind, 
+				path, 
+				inclusionPatterns, 
+				exclusionPatterns, 
+				sourceAttachmentPath, 
+				sourceAttachmentRootPath, 
+				specificOutputLocation,
+				null,
+				isExported,
+				accessRules,
+				combineAccessRules,
+				extraAttributes);
+	}
+	
+	/**
+	 * Creates a class path entry of the specified kind with the given path.
+	 */
+	public ClasspathEntry(
+		int contentKind,
+		int entryKind,
+		IPath path,
+		IPath[] inclusionPatterns,
+		IPath[] exclusionPatterns,
+		IPath sourceAttachmentPath,
+		IPath sourceAttachmentRootPath,
+		IPath specificOutputLocation,
+		IClasspathEntry referencingEntry,
+		boolean isExported,
+		IAccessRule[] accessRules,
+		boolean combineAccessRules,
+		IClasspathAttribute[] extraAttributes) {
+
+		this.contentKind = contentKind;
+		this.entryKind = entryKind;
+		this.path = path;
+		this.inclusionPatterns = inclusionPatterns;
+		this.exclusionPatterns = exclusionPatterns;
+		this.referencingEntry = referencingEntry;
+		
+		int length;
+		if (accessRules != null && (length = accessRules.length) > 0) {
+			AccessRule[] rules = new AccessRule[length];
+			System.arraycopy(accessRules, 0, rules, 0, length);
+			byte classpathEntryType;
+			String classpathEntryName;
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			if (this.entryKind == CPE_PROJECT || this.entryKind == CPE_SOURCE) { // can be remote source entry when reconciling
+				classpathEntryType = AccessRestriction.PROJECT;
+				classpathEntryName = manager.intern(getPath().segment(0));
+			} else {
+				classpathEntryType = AccessRestriction.LIBRARY;
+				Object target = JavaModel.getWorkspaceTarget(path);
+				if (target == null) {
+					classpathEntryName = manager.intern(path.toOSString());
+				} else {
+					classpathEntryName = manager.intern(path.makeRelative().toString());
+				}
+			}
+			this.accessRuleSet = new AccessRuleSet(rules, classpathEntryType, classpathEntryName);
+		}
+//		else { -- implicit!
+//			this.accessRuleSet = null;
+//		}
+
+		this.combineAccessRules = combineAccessRules;
+		this.extraAttributes = extraAttributes;
+
+	    if (inclusionPatterns != INCLUDE_ALL && inclusionPatterns.length > 0) {
+			this.fullInclusionPatternChars = UNINIT_PATTERNS;
+	    }
+	    if (exclusionPatterns.length > 0) {
+			this.fullExclusionPatternChars = UNINIT_PATTERNS;
+	    }
+		this.sourceAttachmentPath = sourceAttachmentPath;
+		this.sourceAttachmentRootPath = sourceAttachmentRootPath;
+		this.specificOutputLocation = specificOutputLocation;
+		this.isExported = isExported;
+	}
+
+	public boolean combineAccessRules() {
+		return this.combineAccessRules;
+	}
+
+	/**
+	 * Used to perform export/restriction propagation across referring projects/containers
+	 */
+	public ClasspathEntry combineWith(ClasspathEntry referringEntry) {
+		if (referringEntry == null) return this;
+		if (referringEntry.isExported() || referringEntry.getAccessRuleSet() != null ) {
+			boolean combine = this.entryKind == CPE_SOURCE || referringEntry.combineAccessRules();
+			return new ClasspathEntry(
+								getContentKind(),
+								getEntryKind(),
+								getPath(),
+								this.inclusionPatterns,
+								this.exclusionPatterns,
+								getSourceAttachmentPath(),
+								getSourceAttachmentRootPath(),
+								getOutputLocation(),
+								referringEntry.isExported() || this.isExported, // duplicate container entry for tagging it as exported
+								combine(referringEntry.getAccessRules(), getAccessRules(), combine),
+								this.combineAccessRules,
+								this.extraAttributes);
+		}
+		// no need to clone
+		return this;
+	}
+
+	private IAccessRule[] combine(IAccessRule[] referringRules, IAccessRule[] rules, boolean combine) {
+		if (!combine) return rules;
+		if (rules == null || rules.length == 0) return referringRules;
+
+		// concat access rules
+		int referringRulesLength = referringRules.length;
+		int accessRulesLength = rules.length;
+		int rulesLength = referringRulesLength + accessRulesLength;
+		IAccessRule[] result = new IAccessRule[rulesLength];
+		System.arraycopy(referringRules, 0, result, 0, referringRulesLength);
+		System.arraycopy(rules, 0, result, referringRulesLength, accessRulesLength);
+
+		return result;
+	}
+
+	static IClasspathAttribute[] decodeExtraAttributes(NodeList attributes) {
+		if (attributes == null) return NO_EXTRA_ATTRIBUTES;
+		int length = attributes.getLength();
+		if (length == 0) return NO_EXTRA_ATTRIBUTES;
+		IClasspathAttribute[] result = new IClasspathAttribute[length];
+		int index = 0;
+		for (int i = 0; i < length; ++i) {
+			Node node = attributes.item(i);
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				Element attribute = (Element)node;
+				String name = attribute.getAttribute(TAG_ATTRIBUTE_NAME);
+				if (name == null) continue;
+				String value = attribute.getAttribute(TAG_ATTRIBUTE_VALUE);
+				if (value == null) continue;
+				result[index++] = new ClasspathAttribute(name, value);
+			}
+		}
+		if (index != length)
+			System.arraycopy(result, 0, result = new IClasspathAttribute[index], 0, index);
+		return result;
+	}
+
+	static IAccessRule[] decodeAccessRules(NodeList list) {
+		if (list == null) return null;
+		int length = list.getLength();
+		if (length == 0) return null;
+		IAccessRule[] result = new IAccessRule[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			Node accessRule = list.item(i);
+			if (accessRule.getNodeType() == Node.ELEMENT_NODE) {
+				Element elementAccessRule = (Element) accessRule;
+				String pattern = elementAccessRule.getAttribute(TAG_PATTERN);
+				if (pattern == null) continue;
+				String tagKind =  elementAccessRule.getAttribute(TAG_KIND);
+				int kind;
+				if (TAG_ACCESSIBLE.equals(tagKind))
+					kind = IAccessRule.K_ACCESSIBLE;
+				else if (TAG_NON_ACCESSIBLE.equals(tagKind))
+					kind = IAccessRule.K_NON_ACCESSIBLE;
+				else if (TAG_DISCOURAGED.equals(tagKind))
+					kind = IAccessRule.K_DISCOURAGED;
+				else
+					continue;
+				boolean ignoreIfBetter = "true".equals(elementAccessRule.getAttribute(TAG_IGNORE_IF_BETTER)); //$NON-NLS-1$
+				result[index++] = new ClasspathAccessRule(new Path(pattern), ignoreIfBetter ? kind | IAccessRule.IGNORE_IF_BETTER : kind);
+			}
+		}
+		if (index != length)
+			System.arraycopy(result, 0, result = new IAccessRule[index], 0, index);
+		return result;
+	}
+
+	/**
+	 * Decode some element tag containing a sequence of patterns into IPath[]
+	 */
+	private static IPath[] decodePatterns(NamedNodeMap nodeMap, String tag) {
+		String sequence = removeAttribute(tag, nodeMap);
+		if (!sequence.equals("")) { //$NON-NLS-1$
+			char[][] patterns = CharOperation.splitOn('|', sequence.toCharArray());
+			int patternCount;
+			if ((patternCount = patterns.length) > 0) {
+				IPath[] paths = new IPath[patternCount];
+				int index = 0;
+				for (int j = 0; j < patternCount; j++) {
+					char[] pattern = patterns[j];
+					if (pattern.length == 0) continue; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=105581
+					paths[index++] = new Path(new String(pattern));
+				}
+				if (index < patternCount)
+					System.arraycopy(paths, 0, paths = new IPath[index], 0, index);
+				return paths;
+			}
+		}
+		return null;
+	}
+
+	private static void decodeUnknownNode(Node node, StringBuffer buffer, IJavaProject project) {
+		ByteArrayOutputStream s = new ByteArrayOutputStream();
+		OutputStreamWriter writer;
+		try {
+			writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
+			XMLWriter xmlWriter = new XMLWriter(writer, project, false/*don't print XML version*/);
+			decodeUnknownNode(node, xmlWriter, true/*insert new line*/);
+			xmlWriter.flush();
+			xmlWriter.close();
+			buffer.append(s.toString("UTF8")); //$NON-NLS-1$
+		} catch (UnsupportedEncodingException e) {
+			// ignore (UTF8 is always supported)
+		}
+	}
+
+	private static void decodeUnknownNode(Node node, XMLWriter xmlWriter, boolean insertNewLine) {
+		switch (node.getNodeType()) {
+		case Node.ELEMENT_NODE:
+			NamedNodeMap attributes;
+			HashMap parameters = null;
+			if ((attributes = node.getAttributes()) != null) {
+				int length = attributes.getLength();
+				if (length > 0) {
+					parameters = new HashMap();
+					for (int i = 0; i < length; i++) {
+						Node attribute = attributes.item(i);
+						parameters.put(attribute.getNodeName(), attribute.getNodeValue());
+					}
+				}
+			}
+			NodeList children = node.getChildNodes();
+			int childrenLength = children.getLength();
+			String nodeName = node.getNodeName();
+			xmlWriter.printTag(nodeName, parameters, false/*don't insert tab*/, false/*don't insert new line*/, childrenLength == 0/*close tag if no children*/);
+			if (childrenLength > 0) {
+				for (int i = 0; i < childrenLength; i++) {
+					decodeUnknownNode(children.item(i), xmlWriter, false/*don't insert new line*/);
+				}
+				xmlWriter.endTag(nodeName, false/*don't insert tab*/, insertNewLine);
+			}
+			break;
+		case Node.TEXT_NODE:
+			String data = ((Text) node).getData();
+			xmlWriter.printString(data, false/*don't insert tab*/, false/*don't insert new line*/);
+			break;
+		}
+	}
+
+	/*
+	 * Returns a char based representation of the exclusions patterns full path.
+	 */
+	public char[][] fullExclusionPatternChars() {
+
+		if (this.fullExclusionPatternChars == UNINIT_PATTERNS) {
+			int length = this.exclusionPatterns.length;
+			this.fullExclusionPatternChars = new char[length][];
+			IPath prefixPath = this.path.removeTrailingSeparator();
+			for (int i = 0; i < length; i++) {
+				this.fullExclusionPatternChars[i] =
+					prefixPath.append(this.exclusionPatterns[i]).toString().toCharArray();
+			}
+		}
+		return this.fullExclusionPatternChars;
+	}
+
+	/*
+	 * Returns a char based representation of the exclusions patterns full path.
+	 */
+	public char[][] fullInclusionPatternChars() {
+
+		if (this.fullInclusionPatternChars == UNINIT_PATTERNS) {
+			int length = this.inclusionPatterns.length;
+			this.fullInclusionPatternChars = new char[length][];
+			IPath prefixPath = this.path.removeTrailingSeparator();
+			for (int i = 0; i < length; i++) {
+				this.fullInclusionPatternChars[i] =
+					prefixPath.append(this.inclusionPatterns[i]).toString().toCharArray();
+			}
+		}
+		return this.fullInclusionPatternChars;
+	}
+
+	/**
+	 * Returns the XML encoding of the class path.
+	 */
+	public void elementEncode(XMLWriter writer, IPath projectPath, boolean indent, boolean newLine, Map unknownElements, boolean isReferencedEntry) {
+		HashMap parameters = new HashMap();
+
+		parameters.put(TAG_KIND, ClasspathEntry.kindToString(this.entryKind));
+
+		IPath xmlPath = this.path;
+		if (this.entryKind != IClasspathEntry.CPE_VARIABLE && this.entryKind != IClasspathEntry.CPE_CONTAINER) {
+			// translate to project relative from absolute (unless a device path)
+			if (xmlPath.isAbsolute()) {
+				if (projectPath != null && projectPath.isPrefixOf(xmlPath)) {
+					if (xmlPath.segment(0).equals(projectPath.segment(0))) {
+						xmlPath = xmlPath.removeFirstSegments(1);
+						xmlPath = xmlPath.makeRelative();
+					} else {
+						xmlPath = xmlPath.makeAbsolute();
+					}
+				}
+			}
+		}
+		parameters.put(TAG_PATH, String.valueOf(xmlPath));
+
+		if (this.sourceAttachmentPath != null) {
+			xmlPath = this.sourceAttachmentPath;
+			// translate to project relative from absolute
+			if (this.entryKind != IClasspathEntry.CPE_VARIABLE && projectPath != null && projectPath.isPrefixOf(xmlPath)) {
+				if (xmlPath.segment(0).equals(projectPath.segment(0))) {
+					xmlPath = xmlPath.removeFirstSegments(1);
+					xmlPath = xmlPath.makeRelative();
+				}
+			}
+			parameters.put(TAG_SOURCEPATH, String.valueOf(xmlPath));
+		}
+		if (this.sourceAttachmentRootPath != null) {
+			parameters.put(TAG_ROOTPATH, String.valueOf(this.sourceAttachmentRootPath));
+		}
+		if (this.isExported) {
+			parameters.put(TAG_EXPORTED, "true");//$NON-NLS-1$
+		}
+		encodePatterns(this.inclusionPatterns, TAG_INCLUDING, parameters);
+		encodePatterns(this.exclusionPatterns, TAG_EXCLUDING, parameters);
+		if (this.entryKind == CPE_PROJECT && !this.combineAccessRules)
+			parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$
+
+
+		// unknown attributes
+		UnknownXmlElements unknownXmlElements = unknownElements == null ? null : (UnknownXmlElements) unknownElements.get(this.path);
+		String[] unknownAttributes;
+		if (unknownXmlElements != null && (unknownAttributes = unknownXmlElements.attributes) != null)
+			for (int i = 0, length = unknownAttributes.length; i < length; i+=2) {
+				String tagName = unknownAttributes[i];
+				String tagValue = unknownAttributes[i+1];
+				parameters.put(tagName, tagValue);
+			}
+
+		if (this.specificOutputLocation != null) {
+			IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1);
+			outputLocation = outputLocation.makeRelative();
+			parameters.put(TAG_OUTPUT, String.valueOf(outputLocation));
+		}
+
+		boolean hasExtraAttributes = this.extraAttributes.length != 0;
+		boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules
+		ArrayList unknownChildren = unknownXmlElements != null ? unknownXmlElements.children : null;
+		boolean hasUnknownChildren = unknownChildren != null;
+		
+		/* close tag if no extra attributes, no restriction and no unknown children */
+		String tagName = isReferencedEntry ? TAG_REFERENCED_ENTRY : TAG_CLASSPATHENTRY; 
+		writer.printTag(
+			tagName,
+			parameters,
+			indent,
+			newLine,
+			!hasExtraAttributes && !hasRestrictions && !hasUnknownChildren);
+
+		if (hasExtraAttributes)
+			encodeExtraAttributes(writer, indent, newLine);
+
+		if (hasRestrictions)
+			encodeAccessRules(writer, indent, newLine);
+
+		if (hasUnknownChildren)
+			encodeUnknownChildren(writer, indent, newLine, unknownChildren);
+
+		if (hasExtraAttributes || hasRestrictions || hasUnknownChildren)
+			writer.endTag(tagName, indent, true/*insert new line*/);
+	}
+
+	void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
+		writer.startTag(TAG_ATTRIBUTES, indent);
+		for (int i = 0; i < this.extraAttributes.length; i++) {
+			IClasspathAttribute attribute = this.extraAttributes[i];
+			HashMap parameters = new HashMap();
+	    	parameters.put(TAG_ATTRIBUTE_NAME, attribute.getName());
+			parameters.put(TAG_ATTRIBUTE_VALUE, attribute.getValue());
+			writer.printTag(TAG_ATTRIBUTE, parameters, indent, newLine, true);
+		}
+		writer.endTag(TAG_ATTRIBUTES, indent, true/*insert new line*/);
+	}
+
+	void encodeAccessRules(XMLWriter writer, boolean indent, boolean newLine) {
+
+		writer.startTag(TAG_ACCESS_RULES, indent);
+		AccessRule[] rules = getAccessRuleSet().getAccessRules();
+		for (int i = 0, length = rules.length; i < length; i++) {
+			encodeAccessRule(rules[i], writer, indent, newLine);
+		}
+		writer.endTag(TAG_ACCESS_RULES, indent, true/*insert new line*/);
+	}
+
+	private void encodeAccessRule(AccessRule accessRule, XMLWriter writer, boolean indent, boolean newLine) {
+
+		HashMap parameters = new HashMap();
+		parameters.put(TAG_PATTERN, new String(accessRule.pattern));
+
+		switch (accessRule.getProblemId()) {
+			case IProblem.ForbiddenReference:
+				parameters.put(TAG_KIND, TAG_NON_ACCESSIBLE);
+				break;
+			case IProblem.DiscouragedReference:
+				parameters.put(TAG_KIND, TAG_DISCOURAGED);
+				break;
+			default:
+				parameters.put(TAG_KIND, TAG_ACCESSIBLE);
+				break;
+		}
+		if (accessRule.ignoreIfBetter())
+			parameters.put(TAG_IGNORE_IF_BETTER, "true"); //$NON-NLS-1$
+
+		writer.printTag(TAG_ACCESS_RULE, parameters, indent, newLine, true);
+
+	}
+
+	private void encodeUnknownChildren(XMLWriter writer, boolean indent, boolean newLine, ArrayList unknownChildren) {
+		for (int i = 0, length = unknownChildren.size(); i < length; i++) {
+			String child = (String) unknownChildren.get(i);
+			writer.printString(child, indent, false/*don't insert new line*/);
+		}
+	}
+
+	public static IClasspathEntry elementDecode(Element element, IJavaProject project, Map unknownElements) {
+
+		IPath projectPath = project.getProject().getFullPath();
+		NamedNodeMap attributes = element.getAttributes();
+		NodeList children = element.getChildNodes();
+		boolean[] foundChildren = new boolean[children.getLength()];
+		String kindAttr = removeAttribute(TAG_KIND, attributes);
+		String pathAttr = removeAttribute(TAG_PATH, attributes);
+
+		// ensure path is absolute
+		IPath path = new Path(pathAttr);
+		int kind = kindFromString(kindAttr);
+		if (kind != IClasspathEntry.CPE_VARIABLE && kind != IClasspathEntry.CPE_CONTAINER && !path.isAbsolute()) {
+			if (!(path.segmentCount() > 0 && path.segment(0).equals(ClasspathEntry.DOT_DOT))) {
+				path = projectPath.append(path);
+			}
+		}
+		// source attachment info (optional)
+		IPath sourceAttachmentPath =
+			element.hasAttribute(TAG_SOURCEPATH)
+			? new Path(removeAttribute(TAG_SOURCEPATH, attributes))
+			: null;
+		if (kind != IClasspathEntry.CPE_VARIABLE && sourceAttachmentPath != null && !sourceAttachmentPath.isAbsolute()) {
+			sourceAttachmentPath = projectPath.append(sourceAttachmentPath);
+		}
+		IPath sourceAttachmentRootPath =
+			element.hasAttribute(TAG_ROOTPATH)
+			? new Path(removeAttribute(TAG_ROOTPATH, attributes))
+			: null;
+
+		// exported flag (optional)
+		boolean isExported = removeAttribute(TAG_EXPORTED, attributes).equals("true"); //$NON-NLS-1$
+
+		// inclusion patterns (optional)
+		IPath[] inclusionPatterns = decodePatterns(attributes, TAG_INCLUDING);
+		if (inclusionPatterns == null) inclusionPatterns = INCLUDE_ALL;
+
+		// exclusion patterns (optional)
+		IPath[] exclusionPatterns = decodePatterns(attributes, TAG_EXCLUDING);
+		if (exclusionPatterns == null) exclusionPatterns = EXCLUDE_NONE;
+
+		// access rules (optional)
+		NodeList attributeList = getChildAttributes(TAG_ACCESS_RULES, children, foundChildren);
+		IAccessRule[] accessRules = decodeAccessRules(attributeList);
+
+		// backward compatibility
+		if (accessRules == null) {
+			accessRules = getAccessRules(inclusionPatterns, exclusionPatterns);
+		}
+
+		// combine access rules (optional)
+		boolean combineAccessRestrictions = !removeAttribute(TAG_COMBINE_ACCESS_RULES, attributes).equals("false"); //$NON-NLS-1$
+
+		// extra attributes (optional)
+		attributeList = getChildAttributes(TAG_ATTRIBUTES, children, foundChildren);
+		IClasspathAttribute[] extraAttributes = decodeExtraAttributes(attributeList);
+
+		// custom output location
+		IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(removeAttribute(TAG_OUTPUT, attributes)) : null;
+
+		String[] unknownAttributes = null;
+		ArrayList unknownChildren = null;
+
+		if (unknownElements != null) {
+			// unknown attributes
+			int unknownAttributeLength = attributes.getLength();
+			if (unknownAttributeLength != 0) {
+				unknownAttributes = new String[unknownAttributeLength*2];
+				for (int i = 0; i < unknownAttributeLength; i++) {
+					Node attribute = attributes.item(i);
+					unknownAttributes[i*2] = attribute.getNodeName();
+					unknownAttributes[i*2 + 1] = attribute.getNodeValue();
+				}
+			}
+
+			// unknown children
+			for (int i = 0, length = foundChildren.length; i < length; i++) {
+				if (!foundChildren[i]) {
+					Node node = children.item(i);
+					if (node.getNodeType() != Node.ELEMENT_NODE) continue;
+					if (unknownChildren == null)
+						unknownChildren = new ArrayList();
+					StringBuffer buffer = new StringBuffer();
+					decodeUnknownNode(node, buffer, project);
+					unknownChildren.add(buffer.toString());
+				}
+			}
+		}
+
+		// recreate the CP entry
+		IClasspathEntry entry = null;
+		switch (kind) {
+
+			case IClasspathEntry.CPE_PROJECT :
+				entry = new ClasspathEntry(
+												IPackageFragmentRoot.K_SOURCE,
+												IClasspathEntry.CPE_PROJECT,
+												path,
+												ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+												ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
+												null, // source attachment
+												null, // source attachment root
+												null, // specific output folder
+												isExported,
+												accessRules,
+												combineAccessRestrictions,
+												extraAttributes);
+				break;
+			case IClasspathEntry.CPE_LIBRARY :
+				entry = JavaCore.newLibraryEntry(
+												path,
+												sourceAttachmentPath,
+												sourceAttachmentRootPath,
+												accessRules,
+												extraAttributes,
+												isExported);
+				break;
+			case IClasspathEntry.CPE_SOURCE :
+				// must be an entry in this project or specify another project
+				String projSegment = path.segment(0);
+				if (projSegment != null && projSegment.equals(project.getElementName())) { // this project
+					entry = JavaCore.newSourceEntry(
+												path, 
+												inclusionPatterns, 
+												exclusionPatterns, 
+												outputLocation, 
+												extraAttributes);
+				} else {
+					if (path.segmentCount() == 1) {
+						// another project
+						entry = JavaCore.newProjectEntry(
+												path,
+												accessRules,
+												combineAccessRestrictions,
+												extraAttributes,
+												isExported);
+					} else {
+						// an invalid source folder
+						entry = JavaCore.newSourceEntry(
+												path, 
+												inclusionPatterns, 
+												exclusionPatterns, 
+												outputLocation, 
+												extraAttributes);
+					}
+				}
+				break;
+			case IClasspathEntry.CPE_VARIABLE :
+				entry = JavaCore.newVariableEntry(
+												path,
+												sourceAttachmentPath,
+												sourceAttachmentRootPath,
+												accessRules,
+												extraAttributes,
+												isExported);
+				break;
+			case IClasspathEntry.CPE_CONTAINER :
+				entry = JavaCore.newContainerEntry(
+												path,
+												accessRules,
+												extraAttributes,
+												isExported);
+				break;
+			case ClasspathEntry.K_OUTPUT :
+				if (!path.isAbsolute()) return null;
+				entry = new ClasspathEntry(
+												ClasspathEntry.K_OUTPUT,
+												IClasspathEntry.CPE_LIBRARY,
+												path,
+												INCLUDE_ALL,
+												EXCLUDE_NONE,
+												null, // source attachment
+												null, // source attachment root
+												null, // custom output location
+												false,
+												null, // no access rules
+												false, // no accessible files to combine
+												NO_EXTRA_ATTRIBUTES);
+				break;
+			default :
+				throw new AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr));
+		}
+
+		if (unknownAttributes != null || unknownChildren != null) {
+			UnknownXmlElements unknownXmlElements = new UnknownXmlElements();
+			unknownXmlElements.attributes = unknownAttributes;
+			unknownXmlElements.children = unknownChildren;
+			unknownElements.put(path, unknownXmlElements);
+		}
+
+		return entry;
+	}
+	
+	/*
+	 * Returns whether the given path as a ".." segment
+	 */
+	public static boolean hasDotDot(IPath path) {
+		for (int i = 0, length = path.segmentCount(); i < length; i++) {
+			if (DOT_DOT.equals(path.segment(i)))
+				return true;
+		}
+		return false;
+	}
+
+	public static NodeList getChildAttributes(String childName, NodeList children, boolean[] foundChildren) {
+		for (int i = 0, length = foundChildren.length; i < length; i++) {
+			Node node = children.item(i);
+			if (childName.equals(node.getNodeName())) {
+				foundChildren[i] = true;
+				return node.getChildNodes();
+			}
+		}
+		return null;
+	}
+
+
+	private static String removeAttribute(String nodeName, NamedNodeMap nodeMap) {
+		Node node = removeNode(nodeName, nodeMap);
+		if (node == null)
+			return ""; // //$NON-NLS-1$
+		return node.getNodeValue();
+	}
+
+	private static Node removeNode(String nodeName, NamedNodeMap nodeMap) {
+		try {
+			return nodeMap.removeNamedItem(nodeName);
+		} catch (DOMException e) {
+			if (e.code != DOMException.NOT_FOUND_ERR)
+				throw e;
+			return null;
+		}
+	}
+
+	/*
+	 * Read the Class-Path clause of the manifest of the jar pointed by this path, and return
+	 * the corresponding paths.
+	 */
+	public static IPath[] resolvedChainedLibraries(IPath jarPath) {
+		ArrayList result = new ArrayList();
+		resolvedChainedLibraries(jarPath, new HashSet(), result);
+		if (result.size() == 0)
+			return NO_PATHS;
+		return (IPath[]) result.toArray(new IPath[result.size()]);
+	}
+	
+	private static void resolvedChainedLibraries(IPath jarPath, HashSet visited, ArrayList result) {
+		if (visited.contains( jarPath))
+			return;
+		visited.add(jarPath);
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		if (manager.isNonChainingJar(jarPath))
+			return;
+		List calledFileNames = getCalledFileNames(jarPath);
+		if (calledFileNames == null) {
+			manager.addNonChainingJar(jarPath);
+		} else {
+			Iterator calledFilesIterator = calledFileNames.iterator();
+			IPath directoryPath = jarPath.removeLastSegments(1);
+			while (calledFilesIterator.hasNext()) {
+				String calledFileName = (String) calledFilesIterator.next();
+				if (!directoryPath.isValidPath(calledFileName)) {
+					if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+						Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+				} else {
+					IPath calledJar = directoryPath.append(new Path(calledFileName));
+					// Ignore if segment count is Zero (https://bugs.eclipse.org/bugs/show_bug.cgi?id=308150)
+					if (calledJar.segmentCount() == 0) {
+						if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+							Util.verbose("Invalid Class-Path entry " + calledFileName + " in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+						}
+						continue;
+					}
+					resolvedChainedLibraries(calledJar, visited, result);
+					result.add(calledJar);
+				}
+			}
+		}
+	}
+
+	private static List getCalledFileNames(IPath jarPath) {
+		Object target = JavaModel.getTarget(jarPath, true/*check existence, otherwise the manifest cannot be read*/);
+		if (!(target instanceof IFile || target instanceof File))
+			return null;
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		ZipFile zip = null;
+		InputStream inputStream = null;
+		List calledFileNames = null;
+		try {
+			zip = manager.getZipFile(jarPath);
+			ZipEntry manifest = zip.getEntry("META-INF/MANIFEST.MF"); //$NON-NLS-1$
+			if (manifest == null) 
+				return null;
+			// non-null implies regular file
+			ManifestAnalyzer analyzer = new ManifestAnalyzer();
+			inputStream = zip.getInputStream(manifest);
+			boolean success = analyzer.analyzeManifestContents(inputStream);
+			calledFileNames = analyzer.getCalledFileNames();
+			if (!success || analyzer.getClasspathSectionsCount() == 1 && calledFileNames == null) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+					Util.verbose("Invalid Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
+				}
+				return null;
+			} else if (analyzer.getClasspathSectionsCount() > 1) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+					Util.verbose("Multiple Class-Path headers in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
+				}
+				return null;
+			}
+		} catch (CoreException e) {
+			// not a zip file
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+				Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
+				e.printStackTrace();
+			}
+		} catch (IOException e) {
+			// not a zip file
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+				Util.verbose("Could not read Class-Path header in manifest of jar file: " + jarPath.toOSString()); //$NON-NLS-1$
+				e.printStackTrace();
+			}
+		} finally {
+			if (inputStream != null) {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+					// best effort
+				}
+			}
+			manager.closeZipFile(zip);
+		}
+		return calledFileNames;
+	}
+	
+	/*
+	 * Resolves the ".." in the given path. Returns the given path if it contains no ".." segment.
+	 */
+	public static IPath resolveDotDot(IPath reference, IPath path) {
+		IPath newPath = null;
+		IPath workspaceLocation = workspaceRoot.getLocation();
+		if (reference == null || workspaceLocation.isPrefixOf(reference)) {
+			for (int i = 0, length = path.segmentCount(); i < length; i++) {
+				String segment = path.segment(i);
+				if (DOT_DOT.equals(segment)) {
+					if (newPath == null) {
+						if (i == 0) {
+							newPath = workspaceLocation;
+						} else {
+							newPath = path.removeFirstSegments(i);
+						}
+					} else {
+						if (newPath.segmentCount() > 0) {
+							newPath = newPath.removeLastSegments(1);
+						} else {
+							newPath = workspaceLocation;
+						}
+					}
+				} else if (newPath != null) {
+					if (newPath.equals(workspaceLocation) && workspaceRoot.getProject(segment).isAccessible()) {
+						newPath = new Path(segment).makeAbsolute();
+					} else {
+						newPath = newPath.append(segment);
+					}
+				}
+			}
+		}
+		else {
+			for (int i = 0, length = path.segmentCount(); i < length; i++) {
+				String segment = path.segment(i);
+				if (DOT_DOT.equals(segment)) {
+					if (newPath == null){
+						newPath = reference;
+					}
+					if (newPath.segmentCount() > 0) {
+						newPath = newPath.removeLastSegments(1);
+	 				}
+				} else if (newPath != null) {
+					newPath = newPath.append(segment);
+	 			}
+			}
+		}
+		if (newPath == null)
+			return path;
+		return newPath;
+	}
+
+	/**
+	 * Encode some patterns into XML parameter tag
+	 */
+	private static void encodePatterns(IPath[] patterns, String tag, Map parameters) {
+		if (patterns != null && patterns.length > 0) {
+			StringBuffer rule = new StringBuffer(10);
+			for (int i = 0, max = patterns.length; i < max; i++){
+				if (i > 0) rule.append('|');
+				rule.append(patterns[i]);
+			}
+			parameters.put(tag, String.valueOf(rule));
+		}
+	}
+
+	/**
+	 * Returns true if the given object is a classpath entry
+	 * with equivalent attributes.
+	 */
+	public boolean equals(Object object) {
+		if (this == object)
+			return true;
+		if (object instanceof ClasspathEntry) {
+			ClasspathEntry otherEntry = (ClasspathEntry) object;
+
+			if (this.contentKind != otherEntry.getContentKind())
+				return false;
+
+			if (this.entryKind != otherEntry.getEntryKind())
+				return false;
+
+			if (this.isExported != otherEntry.isExported())
+				return false;
+
+			if (!this.path.equals(otherEntry.getPath()))
+				return false;
+
+			IPath otherPath = otherEntry.getSourceAttachmentPath();
+			if (this.sourceAttachmentPath == null) {
+				if (otherPath != null)
+					return false;
+			} else {
+				if (!this.sourceAttachmentPath.equals(otherPath))
+					return false;
+			}
+
+			otherPath = otherEntry.getSourceAttachmentRootPath();
+			if (this.sourceAttachmentRootPath == null) {
+				if (otherPath != null)
+					return false;
+			} else {
+				if (!this.sourceAttachmentRootPath.equals(otherPath))
+					return false;
+			}
+
+			if (!equalPatterns(this.inclusionPatterns, otherEntry.getInclusionPatterns()))
+				return false;
+			if (!equalPatterns(this.exclusionPatterns, otherEntry.getExclusionPatterns()))
+				return false;
+			AccessRuleSet otherRuleSet = otherEntry.getAccessRuleSet();
+			if (getAccessRuleSet() != null) {
+				if (!getAccessRuleSet().equals(otherRuleSet))
+					return false;
+			} else if (otherRuleSet != null)
+				return false;
+			if (this.combineAccessRules != otherEntry.combineAccessRules())
+				return false;
+			otherPath = otherEntry.getOutputLocation();
+			if (this.specificOutputLocation == null) {
+				if (otherPath != null)
+					return false;
+			} else {
+				if (!this.specificOutputLocation.equals(otherPath))
+					return false;
+			}
+			if (!equalAttributes(this.extraAttributes, otherEntry.getExtraAttributes()))
+				return false;
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	private static boolean equalAttributes(IClasspathAttribute[] firstAttributes, IClasspathAttribute[] secondAttributes) {
+		if (firstAttributes != secondAttributes){
+		    if (firstAttributes == null) return false;
+			int length = firstAttributes.length;
+			if (secondAttributes == null || secondAttributes.length != length)
+				return false;
+			for (int i = 0; i < length; i++) {
+				if (!firstAttributes[i].equals(secondAttributes[i]))
+					return false;
+			}
+		}
+		return true;
+	}
+
+	private static boolean equalPatterns(IPath[] firstPatterns, IPath[] secondPatterns) {
+		if (firstPatterns != secondPatterns){
+		    if (firstPatterns == null) return false;
+			int length = firstPatterns.length;
+			if (secondPatterns == null || secondPatterns.length != length)
+				return false;
+			for (int i = 0; i < length; i++) {
+				// compare toStrings instead of IPaths
+				// since IPath.equals is specified to ignore trailing separators
+				if (!firstPatterns[i].toString().equals(secondPatterns[i].toString()))
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @see IClasspathEntry#getAccessRules()
+	 */
+	public IAccessRule[] getAccessRules() {
+		if (this.accessRuleSet == null) return NO_ACCESS_RULES;
+		AccessRule[] rules = this.accessRuleSet.getAccessRules();
+		int length = rules.length;
+		if (length == 0) return NO_ACCESS_RULES;
+		IAccessRule[] result = new IAccessRule[length];
+		System.arraycopy(rules, 0, result, 0, length);
+		return result;
+	}
+
+	public AccessRuleSet getAccessRuleSet() {
+		return this.accessRuleSet;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 */
+	public int getContentKind() {
+		return this.contentKind;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 */
+	public int getEntryKind() {
+		return this.entryKind;
+	}
+
+	/**
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	public IPath[] getExclusionPatterns() {
+		return this.exclusionPatterns;
+	}
+
+	public IClasspathAttribute[] getExtraAttributes() {
+		return this.extraAttributes;
+	}
+
+	/**
+	 * @see IClasspathEntry#getExclusionPatterns()
+	 */
+	public IPath[] getInclusionPatterns() {
+		return this.inclusionPatterns;
+	}
+
+	/**
+	 * @see IClasspathEntry#getOutputLocation()
+	 */
+	public IPath getOutputLocation() {
+		return this.specificOutputLocation;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 */
+	public IPath getPath() {
+		return this.path;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 */
+	public IPath getSourceAttachmentPath() {
+		return this.sourceAttachmentPath;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 */
+	public IPath getSourceAttachmentRootPath() {
+		return this.sourceAttachmentRootPath;
+	}
+
+
+	public IClasspathEntry getReferencingEntry() {
+		return this.referencingEntry;
+	}
+
+	/**
+	 * Returns the hash code for this classpath entry
+	 */
+	public int hashCode() {
+		return this.path.hashCode();
+	}
+
+	/**
+	 * @see IClasspathEntry#isExported()
+	 */
+	public boolean isExported() {
+		return this.isExported;
+	}
+
+	public boolean isOptional() {
+		for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
+			IClasspathAttribute attribute = this.extraAttributes[i];
+			if (IClasspathAttribute.OPTIONAL.equals(attribute.getName()) && "true".equals(attribute.getValue())) //$NON-NLS-1$
+				return true;
+		}
+		return false;
+	}
+
+	public String getSourceAttachmentEncoding() {
+		for (int i = 0, length = this.extraAttributes.length; i < length; i++) {
+			IClasspathAttribute attribute = this.extraAttributes[i];
+			if (IClasspathAttribute.SOURCE_ATTACHMENT_ENCODING.equals(attribute.getName()))
+				return attribute.getValue();
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the kind of a <code>PackageFragmentRoot</code> from its <code>String</code> form.
+	 */
+	static int kindFromString(String kindStr) {
+
+		if (kindStr.equalsIgnoreCase("prj")) //$NON-NLS-1$
+			return IClasspathEntry.CPE_PROJECT;
+		if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$
+			return IClasspathEntry.CPE_VARIABLE;
+		if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$
+			return IClasspathEntry.CPE_CONTAINER;
+		if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$
+			return IClasspathEntry.CPE_SOURCE;
+		if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$
+			return IClasspathEntry.CPE_LIBRARY;
+		if (kindStr.equalsIgnoreCase("output")) //$NON-NLS-1$
+			return ClasspathEntry.K_OUTPUT;
+		return -1;
+	}
+
+	/**
+	 * Returns a <code>String</code> for the kind of a class path entry.
+	 */
+	static String kindToString(int kind) {
+
+		switch (kind) {
+			case IClasspathEntry.CPE_PROJECT :
+				return "src"; // backward compatibility //$NON-NLS-1$
+			case IClasspathEntry.CPE_SOURCE :
+				return "src"; //$NON-NLS-1$
+			case IClasspathEntry.CPE_LIBRARY :
+				return "lib"; //$NON-NLS-1$
+			case IClasspathEntry.CPE_VARIABLE :
+				return "var"; //$NON-NLS-1$
+			case IClasspathEntry.CPE_CONTAINER :
+				return "con"; //$NON-NLS-1$
+			case ClasspathEntry.K_OUTPUT :
+				return "output"; //$NON-NLS-1$
+			default :
+				return "unknown"; //$NON-NLS-1$
+		}
+	}
+
+	/*
+	 * Backward compatibility: only accessible and non-accessible files are suported.
+	 */
+	public static IAccessRule[] getAccessRules(IPath[] accessibleFiles, IPath[] nonAccessibleFiles) {
+		int accessibleFilesLength = accessibleFiles == null ? 0 : accessibleFiles.length;
+		int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0 : nonAccessibleFiles.length;
+		int length = accessibleFilesLength + nonAccessibleFilesLength;
+		if (length == 0) return null;
+		IAccessRule[] accessRules = new IAccessRule[length];
+		for (int i = 0; i < accessibleFilesLength; i++) {
+			accessRules[i] = JavaCore.newAccessRule(accessibleFiles[i], IAccessRule.K_ACCESSIBLE);
+		}
+		for (int i = 0; i < nonAccessibleFilesLength; i++) {
+			accessRules[accessibleFilesLength + i] = JavaCore.newAccessRule(nonAccessibleFiles[i], IAccessRule.K_NON_ACCESSIBLE);
+		}
+		return accessRules;
+	}
+
+	/**
+	 * Returns a printable representation of this classpath entry.
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		Object target = JavaModel.getTarget(getPath(), true);
+		if (target instanceof File)
+			buffer.append(getPath().toOSString());
+		else
+			buffer.append(String.valueOf(getPath()));
+		buffer.append('[');
+		switch (getEntryKind()) {
+			case IClasspathEntry.CPE_LIBRARY :
+				buffer.append("CPE_LIBRARY"); //$NON-NLS-1$
+				break;
+			case IClasspathEntry.CPE_PROJECT :
+				buffer.append("CPE_PROJECT"); //$NON-NLS-1$
+				break;
+			case IClasspathEntry.CPE_SOURCE :
+				buffer.append("CPE_SOURCE"); //$NON-NLS-1$
+				break;
+			case IClasspathEntry.CPE_VARIABLE :
+				buffer.append("CPE_VARIABLE"); //$NON-NLS-1$
+				break;
+			case IClasspathEntry.CPE_CONTAINER :
+				buffer.append("CPE_CONTAINER"); //$NON-NLS-1$
+				break;
+		}
+		buffer.append("]["); //$NON-NLS-1$
+		switch (getContentKind()) {
+			case IPackageFragmentRoot.K_BINARY :
+				buffer.append("K_BINARY"); //$NON-NLS-1$
+				break;
+			case IPackageFragmentRoot.K_SOURCE :
+				buffer.append("K_SOURCE"); //$NON-NLS-1$
+				break;
+			case ClasspathEntry.K_OUTPUT :
+				buffer.append("K_OUTPUT"); //$NON-NLS-1$
+				break;
+		}
+		buffer.append(']');
+		if (getSourceAttachmentPath() != null) {
+			buffer.append("[sourcePath:"); //$NON-NLS-1$
+			buffer.append(getSourceAttachmentPath());
+			buffer.append(']');
+		}
+		if (getSourceAttachmentRootPath() != null) {
+			buffer.append("[rootPath:"); //$NON-NLS-1$
+			buffer.append(getSourceAttachmentRootPath());
+			buffer.append(']');
+		}
+		buffer.append("[isExported:"); //$NON-NLS-1$
+		buffer.append(this.isExported);
+		buffer.append(']');
+		IPath[] patterns = this.inclusionPatterns;
+		int length;
+		if ((length = patterns == null ? 0 : patterns.length) > 0) {
+			buffer.append("[including:"); //$NON-NLS-1$
+			for (int i = 0; i < length; i++) {
+				buffer.append(patterns[i]);
+				if (i != length-1) {
+					buffer.append('|');
+				}
+			}
+			buffer.append(']');
+		}
+		patterns = this.exclusionPatterns;
+		if ((length = patterns == null ? 0 : patterns.length) > 0) {
+			buffer.append("[excluding:"); //$NON-NLS-1$
+			for (int i = 0; i < length; i++) {
+				buffer.append(patterns[i]);
+				if (i != length-1) {
+					buffer.append('|');
+				}
+			}
+			buffer.append(']');
+		}
+		if (this.accessRuleSet != null) {
+			buffer.append('[');
+			buffer.append(this.accessRuleSet.toString(false/*on one line*/));
+			buffer.append(']');
+		}
+		if (this.entryKind == CPE_PROJECT) {
+			buffer.append("[combine access rules:"); //$NON-NLS-1$
+			buffer.append(this.combineAccessRules);
+			buffer.append(']');
+		}
+		if (getOutputLocation() != null) {
+			buffer.append("[output:"); //$NON-NLS-1$
+			buffer.append(getOutputLocation());
+			buffer.append(']');
+		}
+		if ((length = this.extraAttributes == null ? 0 : this.extraAttributes.length) > 0) {
+			buffer.append("[attributes:"); //$NON-NLS-1$
+			for (int i = 0; i < length; i++) {
+				buffer.append(this.extraAttributes[i]);
+				if (i != length-1) {
+					buffer.append(',');
+				}
+			}
+			buffer.append(']');
+		}
+		return buffer.toString();
+	}
+	
+	public ClasspathEntry resolvedDotDot(IPath reference) {
+		IPath resolvedPath = resolveDotDot(reference, this.path);
+		if (resolvedPath == this.path)
+			return this;
+		return new ClasspathEntry(
+							getContentKind(),
+							getEntryKind(),
+							resolvedPath,
+							this.inclusionPatterns,
+							this.exclusionPatterns,
+							getSourceAttachmentPath(),
+							getSourceAttachmentRootPath(),
+							getOutputLocation(),
+							this.getReferencingEntry(),
+							this.isExported,
+							getAccessRules(),
+							this.combineAccessRules,
+							this.extraAttributes);
+	}
+	
+	/*
+	 * Read the Class-Path clause of the manifest of the jar pointed by this entry, and return
+	 * the corresponding library entries.
+	 */
+	public ClasspathEntry[] resolvedChainedLibraries() {
+		IPath[] paths = resolvedChainedLibraries(getPath());
+		int length = paths.length;
+		if (length == 0)
+			return NO_ENTRIES;
+		ClasspathEntry[] result = new ClasspathEntry[length];
+		for (int i = 0; i < length; i++) {
+			// Chained(referenced) libraries can have their own attachment path. Hence, set them to null
+			result[i] = new ClasspathEntry(
+					getContentKind(),
+					getEntryKind(),
+					paths[i],
+					this.inclusionPatterns,
+					this.exclusionPatterns,
+					null,
+					null,
+					getOutputLocation(),
+					this,
+					this.isExported,
+					getAccessRules(),
+					this.combineAccessRules,
+					NO_EXTRA_ATTRIBUTES);
+		}
+		return result;
+	}
+	
+	/**
+	 * Answers an ID which is used to distinguish entries during package
+	 * fragment root computations
+	 */
+	public String rootID(){
+
+		if (this.rootID == null) {
+			switch(this.entryKind){
+				case IClasspathEntry.CPE_LIBRARY :
+					this.rootID = "[LIB]"+this.path;  //$NON-NLS-1$
+					break;
+				case IClasspathEntry.CPE_PROJECT :
+					this.rootID = "[PRJ]"+this.path;  //$NON-NLS-1$
+					break;
+				case IClasspathEntry.CPE_SOURCE :
+					this.rootID = "[SRC]"+this.path;  //$NON-NLS-1$
+					break;
+				case IClasspathEntry.CPE_VARIABLE :
+					this.rootID = "[VAR]"+this.path;  //$NON-NLS-1$
+					break;
+				case IClasspathEntry.CPE_CONTAINER :
+					this.rootID = "[CON]"+this.path;  //$NON-NLS-1$
+					break;
+				default :
+					this.rootID = "";  //$NON-NLS-1$
+					break;
+			}
+		}
+		return this.rootID;
+	}
+
+	/**
+	 * @see IClasspathEntry
+	 * @deprecated
+	 */
+	public IClasspathEntry getResolvedEntry() {
+
+		return JavaCore.getResolvedClasspathEntry(this);
+	}
+	
+	/**
+	 * This function computes the URL of the index location for this classpath entry. It returns null if the URL is
+	 * invalid.
+	 */
+	public URL getLibraryIndexLocation() {
+		switch(getEntryKind()) {
+			case IClasspathEntry.CPE_LIBRARY :
+			case IClasspathEntry.CPE_VARIABLE :
+				break;
+			default :
+				return null;
+		}
+		if (this.extraAttributes == null) return null;
+		for (int i= 0; i < this.extraAttributes.length; i++) {
+			IClasspathAttribute attrib= this.extraAttributes[i];
+			if (IClasspathAttribute.INDEX_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
+				String value = attrib.getValue();
+				try {
+					return new URL(value);
+				} catch (MalformedURLException e) {
+					return null;
+				}
+			}
+		}
+		return null;
+	}
+
+	public boolean ignoreOptionalProblems() {
+		if (this.entryKind == IClasspathEntry.CPE_SOURCE) {
+			for (int i = 0; i < this.extraAttributes.length; i++) {
+				IClasspathAttribute attrib = this.extraAttributes[i];
+				if (IClasspathAttribute.IGNORE_OPTIONAL_PROBLEMS.equals(attrib.getName())) {
+					return "true".equals(attrib.getValue()); //$NON-NLS-1$
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Validate a given classpath and output location for a project, using the following rules:
+	 * <ul>
+	 *   <li> Classpath entries cannot collide with each other; that is, all entry paths must be unique.
+	 *   <li> The project output location path cannot be null, must be absolute and located inside the project.
+	 *   <li> Specific output locations (specified on source entries) can be null, if not they must be located inside the project,
+	 *   <li> A project entry cannot refer to itself directly (that is, a project cannot prerequisite itself).
+	 *   <li> Classpath entries or output locations cannot coincidate or be nested in each other, except for the following scenario listed below:
+	 *      <ul><li> A source folder can coincidate with its own output location, in which case this output can then contain library archives.
+	 *                     However, a specific output location cannot coincidate with any library or a distinct source folder than the one referring to it. </li>
+	 *              <li> A source/library folder can be nested in any source folder as long as the nested folder is excluded from the enclosing one. </li>
+	 * 			<li> An output location can be nested in a source folder, if the source folder coincidates with the project itself, or if the output
+	 * 					location is excluded from the source folder. </li>
+	 *      </ul>
+	 * </ul>
+	 *
+	 *  Note that the classpath entries are not validated automatically. Only bound variables or containers are considered
+	 *  in the checking process (this allows to perform a consistency check on a classpath which has references to
+	 *  yet non existing projects, folders, ...).
+	 *  <p>
+	 *  This validation is intended to anticipate classpath issues prior to assigning it to a project. In particular, it will automatically
+	 *  be performed during the classpath setting operation (if validation fails, the classpath setting will not complete).
+	 *  <p>
+	 * @param javaProject the given java project
+	 * @param rawClasspath a given classpath
+	 * @param projectOutputLocation a given output location
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given classpath and output location are compatible, otherwise a status
+	 *		object indicating what is wrong with the classpath or output location
+	 */
+	public static IJavaModelStatus validateClasspath(IJavaProject javaProject, IClasspathEntry[] rawClasspath, IPath projectOutputLocation) {
+
+		IProject project = javaProject.getProject();
+		IPath projectPath= project.getFullPath();
+		String projectName = javaProject.getElementName();
+
+		/* validate output location */
+		if (projectOutputLocation == null) {
+			return new JavaModelStatus(IJavaModelStatusConstants.NULL_PATH);
+		}
+		if (projectOutputLocation.isAbsolute()) {
+			if (!projectPath.isPrefixOf(projectOutputLocation)) {
+				return new JavaModelStatus(IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT, javaProject, projectOutputLocation.toString());
+			}
+		} else {
+			return new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, projectOutputLocation);
+		}
+
+		boolean hasSource = false;
+		boolean hasLibFolder = false;
+
+
+		// tolerate null path, it will be reset to default
+		if (rawClasspath == null)
+			return JavaModelStatus.VERIFIED_OK;
+
+		// check duplicate entries on raw classpath only (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=175226 )
+		int rawLength = rawClasspath.length;
+		HashSet pathes = new HashSet(rawLength);
+		for (int i = 0 ; i < rawLength; i++) {
+			IPath entryPath = rawClasspath[i].getPath();
+			if (!pathes.add(entryPath)){
+				String entryPathMsg = projectName.equals(entryPath.segment(0)) ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString();
+				return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryPath, new String[] {entryPathMsg, projectName}));
+			}
+		}
+
+		// retrieve resolved classpath
+		IClasspathEntry[] classpath;
+		try {
+			// don't resolve chained libraries: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=259685
+			classpath = ((JavaProject)javaProject).resolveClasspath(rawClasspath, false/*don't use previous session*/, false/*don't resolve chained libraries*/).resolvedClasspath;
+		} catch(JavaModelException e){
+			return e.getJavaModelStatus();
+		}
+		int length = classpath.length;
+
+		int outputCount = 1;
+		IPath[] outputLocations	= new IPath[length+1];
+		boolean[] allowNestingInOutputLocations = new boolean[length+1];
+		outputLocations[0] = projectOutputLocation;
+
+		// retrieve and check output locations
+		IPath potentialNestedOutput = null; // for error reporting purpose
+		int sourceEntryCount = 0;
+		boolean disableExclusionPatterns = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, true));
+		boolean disableCustomOutputLocations = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, true));
+
+		for (int i = 0 ; i < length; i++) {
+			IClasspathEntry resolvedEntry = classpath[i];
+			if (disableExclusionPatterns &&
+			        ((resolvedEntry.getInclusionPatterns() != null && resolvedEntry.getInclusionPatterns().length > 0)
+			        || (resolvedEntry.getExclusionPatterns() != null && resolvedEntry.getExclusionPatterns().length > 0))) {
+				return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS, javaProject, resolvedEntry.getPath());
+			}
+			switch(resolvedEntry.getEntryKind()){
+				case IClasspathEntry.CPE_SOURCE :
+					sourceEntryCount++;
+
+					IPath customOutput;
+					if ((customOutput = resolvedEntry.getOutputLocation()) != null) {
+
+						if (disableCustomOutputLocations) {
+							return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS, javaProject, resolvedEntry.getPath());
+						}
+						// ensure custom output is in project
+						if (customOutput.isAbsolute()) {
+							if (!javaProject.getPath().isPrefixOf(customOutput)) {
+								return new JavaModelStatus(IJavaModelStatusConstants.PATH_OUTSIDE_PROJECT, javaProject, customOutput.toString());
+							}
+						} else {
+							return new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, customOutput);
+						}
+
+						// ensure custom output doesn't conflict with other outputs
+						// check exact match
+						if (Util.indexOfMatchingPath(customOutput, outputLocations, outputCount) != -1) {
+							continue; // already found
+						}
+						// accumulate all outputs, will check nesting once all available (to handle ordering issues)
+						outputLocations[outputCount++] = customOutput;
+					}
+			}
+		}
+		// check nesting across output locations
+		for (int i = 1 /*no check for default output*/ ; i < outputCount; i++) {
+			IPath customOutput = outputLocations[i];
+			int index;
+			// check nesting
+			if ((index = Util.indexOfEnclosingPath(customOutput, outputLocations, outputCount)) != -1 && index != i) {
+				if (index == 0) {
+					// custom output is nested in project's output: need to check if all source entries have a custom
+					// output before complaining
+					if (potentialNestedOutput == null) potentialNestedOutput = customOutput;
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {customOutput.makeRelative().toString(), outputLocations[index].makeRelative().toString()}));
+				}
+			}
+		}
+		// allow custom output nesting in project's output if all source entries have a custom output
+		if (sourceEntryCount <= outputCount-1) {
+		    allowNestingInOutputLocations[0] = true;
+		} else if (potentialNestedOutput != null) {
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {potentialNestedOutput.makeRelative().toString(), outputLocations[0].makeRelative().toString()}));
+		}
+
+		for (int i = 0 ; i < length; i++) {
+			IClasspathEntry resolvedEntry = classpath[i];
+			IPath path = resolvedEntry.getPath();
+			int index;
+			switch(resolvedEntry.getEntryKind()){
+
+				case IClasspathEntry.CPE_SOURCE :
+					hasSource = true;
+					if ((index = Util.indexOfMatchingPath(path, outputLocations, outputCount)) != -1){
+						allowNestingInOutputLocations[index] = true;
+					}
+					break;
+
+				case IClasspathEntry.CPE_LIBRARY:
+					Object target = JavaModel.getTarget(path, false/*don't check resource existence*/);
+					hasLibFolder |= target instanceof IContainer;
+					if ((index = Util.indexOfMatchingPath(path, outputLocations, outputCount)) != -1){
+						allowNestingInOutputLocations[index] = true;
+					}
+					break;
+			}
+		}
+		if (!hasSource && !hasLibFolder) { // if no source and no lib folder, then allowed
+			for (int i = 0; i < outputCount; i++) allowNestingInOutputLocations[i] = true;
+		}
+
+		// check all entries
+		for (int i = 0 ; i < length; i++) {
+			IClasspathEntry entry = classpath[i];
+			if (entry == null) continue;
+			IPath entryPath = entry.getPath();
+			int kind = entry.getEntryKind();
+
+			// no further check if entry coincidates with project or output location
+			if (entryPath.equals(projectPath)){
+				// complain if self-referring project entry
+				if (kind == IClasspathEntry.CPE_PROJECT){
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Messages.bind(Messages.classpath_cannotReferToItself, entryPath.makeRelative().toString()));
+				}
+				// tolerate nesting output in src if src==prj
+				continue;
+			}
+
+			// allow nesting source entries in each other as long as the outer entry excludes the inner one
+			if (kind == IClasspathEntry.CPE_SOURCE
+					|| (kind == IClasspathEntry.CPE_LIBRARY && (JavaModel.getTarget(entryPath, false/*don't check existence*/) instanceof IContainer))) {
+				for (int j = 0; j < classpath.length; j++){
+					IClasspathEntry otherEntry = classpath[j];
+					if (otherEntry == null) continue;
+					int otherKind = otherEntry.getEntryKind();
+					IPath otherPath = otherEntry.getPath();
+					if (entry != otherEntry
+						&& (otherKind == IClasspathEntry.CPE_SOURCE
+								|| (otherKind == IClasspathEntry.CPE_LIBRARY
+										&& (JavaModel.getTarget(otherPath, false/*don't check existence*/) instanceof IContainer)))) {
+						char[][] inclusionPatterns, exclusionPatterns;
+						if (otherPath.isPrefixOf(entryPath)
+								&& !otherPath.equals(entryPath)
+								&& !Util.isExcluded(entryPath.append("*"), inclusionPatterns = ((ClasspathEntry)otherEntry).fullInclusionPatternChars(), exclusionPatterns = ((ClasspathEntry)otherEntry).fullExclusionPatternChars(), false)) { //$NON-NLS-1$
+							String exclusionPattern = entryPath.removeFirstSegments(otherPath.segmentCount()).segment(0);
+							if (Util.isExcluded(entryPath, inclusionPatterns, exclusionPatterns, false)) {
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_mustEndWithSlash, new String[] {exclusionPattern, entryPath.makeRelative().toString()}));
+							} else {
+								if (otherKind == IClasspathEntry.CPE_SOURCE) {
+									exclusionPattern += '/';
+									if (!disableExclusionPatterns) {
+										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInEntry, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern}));
+									} else {
+										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInEntryNoExclusion, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern}));
+									}
+								} else {
+									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInLibrary, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString()}));
+								}
+							}
+						}
+					}
+				}
+			}
+
+			// prevent nesting output location inside entry unless enclosing is a source entry which explicitly exclude the output location
+			char[][] inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
+			char[][] exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
+			for (int j = 0; j < outputCount; j++){
+				IPath currentOutput = outputLocations[j];
+				if (entryPath.equals(currentOutput)) continue;
+				if (entryPath.isPrefixOf(currentOutput)) {
+				    if (kind != IClasspathEntry.CPE_SOURCE || !Util.isExcluded(currentOutput, inclusionPatterns, exclusionPatterns, true)) {
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInEntry, new String[] {currentOutput.makeRelative().toString(), entryPath.makeRelative().toString()}));
+				    }
+				}
+			}
+
+			// prevent nesting entry inside output location - when distinct from project or a source folder
+			for (int j = 0; j < outputCount; j++){
+				if (allowNestingInOutputLocations[j]) continue;
+				IPath currentOutput = outputLocations[j];
+				if (currentOutput.isPrefixOf(entryPath)) {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInOutput, new String[] {entryPath.makeRelative().toString(), currentOutput.makeRelative().toString()}));
+				}
+			}
+		}
+		// ensure that no specific output is coincidating with another source folder (only allowed if matching current source folder)
+		// 36465 - for 2.0 backward compatibility, only check specific output locations (the default can still coincidate)
+		// perform one separate iteration so as to not take precedence over previously checked scenarii (in particular should
+		// diagnose nesting source folder issue before this one, for example, [src]"Project/", [src]"Project/source/" and output="Project/" should
+		// first complain about missing exclusion pattern
+		IJavaModelStatus cachedStatus = null;
+		for (int i = 0 ; i < length; i++) {
+			IClasspathEntry entry = classpath[i];
+			if (entry == null) continue;
+			IPath entryPath = entry.getPath();
+			int kind = entry.getEntryKind();
+
+			// Build some common strings for status message
+			boolean isProjectRelative = projectName.equals(entryPath.segment(0));
+			String entryPathMsg = isProjectRelative ? entryPath.removeFirstSegments(1).toString() : entryPath.makeRelative().toString();
+
+			if (kind == IClasspathEntry.CPE_SOURCE) {
+				IPath output = entry.getOutputLocation();
+				if (output == null) output = projectOutputLocation; // if no specific output, still need to check using default output (this line would check default output)
+				for (int j = 0; j < length; j++) {
+					IClasspathEntry otherEntry = classpath[j];
+					if (otherEntry == entry) continue;
+
+					switch (otherEntry.getEntryKind()) {
+						case IClasspathEntry.CPE_SOURCE :
+							// Bug 287164 : Report errors of overlapping output locations only if the user sets the corresponding preference.
+							// The check is required for backward compatibility with bug-fix 36465.
+							String option = javaProject.getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true);
+							if (otherEntry.getPath().equals(output) 
+									&& !JavaCore.IGNORE.equals(option)) {
+								boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0));
+								String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString();
+								if (JavaCore.ERROR.equals(option)) {
+									return new JavaModelStatus(IStatus.ERROR, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, 
+											Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {
+											entryPathMsg, otherPathMsg, projectName }));
+								}
+								if (cachedStatus == null) {
+									// Note that the isOK() is being overridden to return true. This is an exceptional scenario
+									cachedStatus = new JavaModelStatus(IStatus.OK, IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, 
+										Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {
+										entryPathMsg, otherPathMsg, projectName })){
+										public boolean isOK() {
+											return true;
+										}
+									};
+								}
+							}
+							break;
+						case IClasspathEntry.CPE_LIBRARY :
+							if (output != projectOutputLocation && otherEntry.getPath().equals(output)) {
+								boolean opStartsWithProject = projectName.equals(otherEntry.getPath().segment(0));
+								String otherPathMsg = opStartsWithProject ? otherEntry.getPath().removeFirstSegments(1).toString() : otherEntry.getPath().makeRelative().toString();
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName}));
+							}
+					}
+				}
+			}
+		}
+
+		// NOTE: The above code that checks for IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, can be configured to return
+		// a WARNING status and hence should be at the end of this validation method. Any other code that might return a more severe ERROR should be 
+		// inserted before the mentioned code.
+		if (cachedStatus != null) return cachedStatus;
+
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	/**
+	 * Returns a Java model status describing the problem related to this classpath entry if any,
+	 * a status object with code <code>IStatus.OK</code> if the entry is fine (that is, if the
+	 * given classpath entry denotes a valid element to be referenced onto a classpath).
+	 *
+	 * @param project the given java project
+	 * @param entry the given classpath entry
+	 * @param checkSourceAttachment a flag to determine if source attachment should be checked
+	 * @param referredByContainer flag indicating whether the given entry is referred by a classpath container
+	 * @return a java model status describing the problem related to this classpath entry if any, a status object with code <code>IStatus.OK</code> if the entry is fine
+	 */
+	public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment, boolean referredByContainer){
+		if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+			JavaModelManager.getJavaModelManager().removeFromInvalidArchiveCache(entry.getPath());
+		}
+		IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, referredByContainer);
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171136 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=300136
+		// Ignore class path errors from optional entries.
+		int statusCode = status.getCode();
+		if ( (statusCode == IJavaModelStatusConstants.INVALID_CLASSPATH || 
+				statusCode == IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND ||
+				statusCode == IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND ||
+				statusCode == IJavaModelStatusConstants.INVALID_PATH) &&
+				((ClasspathEntry) entry).isOptional())
+			return JavaModelStatus.VERIFIED_OK;
+		return status;
+	}
+	
+	private static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, IClasspathContainer entryContainer, boolean checkSourceAttachment, boolean referredByContainer){
+
+		IPath path = entry.getPath();
+
+		// Build some common strings for status message
+		String projectName = project.getElementName();
+		String entryPathMsg = projectName.equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();
+
+		switch(entry.getEntryKind()){
+
+			// container entry check
+			case IClasspathEntry.CPE_CONTAINER :
+				if (path.segmentCount() >= 1){
+					try {
+						IJavaModelStatus status = null;
+						// Validate extra attributes
+						IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
+						if (extraAttributes != null) {
+							int length = extraAttributes.length;
+							HashSet set = new HashSet(length);
+							for (int i=0; i<length; i++) {
+								String attName = extraAttributes[i].getName();
+								if (!set.add(attName)) {
+									status = new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
+									break;
+								}
+							}
+						}
+						IClasspathContainer container = JavaModelManager.getJavaModelManager().getClasspathContainer(path, project);
+						// container retrieval is performing validation check on container entry kinds.
+						if (container == null) {
+							if (status != null)
+								return status;
+							return new JavaModelStatus(IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND, project, path);
+						} else if (container == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
+							// don't create a marker if initialization is in progress (case of cp initialization batching)
+							return JavaModelStatus.VERIFIED_OK;
+						}
+						IClasspathEntry[] containerEntries = container.getClasspathEntries();
+						if (containerEntries != null){
+							for (int i = 0, length = containerEntries.length; i < length; i++){
+								IClasspathEntry containerEntry = containerEntries[i];
+								int kind = containerEntry == null ? 0 : containerEntry.getEntryKind();
+								if (containerEntry == null
+									|| kind == IClasspathEntry.CPE_SOURCE
+									|| kind == IClasspathEntry.CPE_VARIABLE
+									|| kind == IClasspathEntry.CPE_CONTAINER){
+										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CP_CONTAINER_ENTRY, project, path);
+								}
+								IJavaModelStatus containerEntryStatus = validateClasspathEntry(project, containerEntry, container, checkSourceAttachment, true/*referred by container*/);
+								if (!containerEntryStatus.isOK()){
+									return containerEntryStatus;
+								}
+							}
+						}
+					} catch(JavaModelException e){
+						return new JavaModelStatus(e);
+					}
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalContainerPath, new String[] {entryPathMsg, projectName}));
+				}
+				break;
+
+			// variable entry check
+			case IClasspathEntry.CPE_VARIABLE :
+				if (path.segmentCount() >= 1){
+					try {
+						entry = JavaCore.getResolvedClasspathEntry(entry);
+					} catch (AssertionFailedException e) {
+						// Catch the assertion failure and throw java model exception instead
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
+					}
+					if (entry == null){
+						return new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, project, path);
+					}
+
+					// get validation status
+					IJavaModelStatus status = validateClasspathEntry(project, entry, null, checkSourceAttachment, false/*not referred by container*/);
+					if (!status.isOK()) return status;
+
+					// return deprecation status if any
+					String variableName = path.segment(0);
+					String deprecatedMessage = JavaCore.getClasspathVariableDeprecationMessage(variableName);
+					if (deprecatedMessage != null) {
+						return new JavaModelStatus(IStatus.WARNING, IJavaModelStatusConstants.DEPRECATED_VARIABLE, project, path, deprecatedMessage);
+					}
+					return status;
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName}));
+				}
+
+			// library entry check
+			case IClasspathEntry.CPE_LIBRARY :
+				path = ClasspathEntry.resolveDotDot(project.getProject().getLocation(), path);
+				
+				// do not validate entries from Class-Path: in manifest
+				// (these entries are considered optional since the user cannot act on them)
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=252392
+				
+				String containerInfo = null;
+				if (entryContainer != null) {
+					if (entryContainer instanceof UserLibraryClasspathContainer) {
+						containerInfo = Messages.bind(Messages.classpath_userLibraryInfo, new String[] {entryContainer.getDescription()});
+					} else {
+						containerInfo = Messages.bind(Messages.classpath_containerInfo, new String[] {entryContainer.getDescription()});
+					}
+				}
+				IJavaModelStatus status = validateLibraryEntry(path, project, containerInfo, checkSourceAttachment ? entry.getSourceAttachmentPath() : null, entryPathMsg);
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171136, ignore class path errors from optional entries
+				if (status.getCode() == IJavaModelStatusConstants.INVALID_CLASSPATH && ((ClasspathEntry) entry).isOptional())
+					status = JavaModelStatus.VERIFIED_OK;
+				if (!status.isOK())
+					return status;
+				break;
+
+			// project entry check
+			case IClasspathEntry.CPE_PROJECT :
+				if (path.isAbsolute() && path.segmentCount() == 1) {
+					IProject prereqProjectRsc = workspaceRoot.getProject(path.segment(0));
+					IJavaProject prereqProject = JavaCore.create(prereqProjectRsc);
+					try {
+						if (!prereqProjectRsc.exists() || !prereqProjectRsc.hasNature(JavaCore.NATURE_ID)){
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName}));
+						}
+						if (!prereqProjectRsc.isOpen()){
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_closedProject, new String[] {path.segment(0)}));
+						}
+						if (!JavaCore.IGNORE.equals(project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true))) {
+							long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
+							long prereqProjectTargetJDK = CompilerOptions.versionToJdkLevel(prereqProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
+							if (prereqProjectTargetJDK > projectTargetJDK) {
+								return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
+										project, path, 
+										Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel,
+												new String[] {
+													project.getElementName(),
+													CompilerOptions.versionFromJdkLevel(projectTargetJDK), 
+													path.makeRelative().toString(),
+													CompilerOptions.versionFromJdkLevel(prereqProjectTargetJDK)}));
+							}
+						}
+					} catch (CoreException e){
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName}));
+					}
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalProjectPath, new String[] {path.toString(), projectName}));
+				}
+				break;
+
+			// project source folder
+			case IClasspathEntry.CPE_SOURCE :
+				if (((entry.getInclusionPatterns() != null && entry.getInclusionPatterns().length > 0)
+						|| (entry.getExclusionPatterns() != null && entry.getExclusionPatterns().length > 0))
+						&& JavaCore.DISABLED.equals(project.getOption(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, true))) {
+					return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_EXCLUSION_PATTERNS, project, path);
+				}
+				if (entry.getOutputLocation() != null && JavaCore.DISABLED.equals(project.getOption(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, true))) {
+					return new JavaModelStatus(IJavaModelStatusConstants.DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS, project, path);
+				}
+				if (path.isAbsolute() && !path.isEmpty()) {
+					IPath projectPath= project.getProject().getFullPath();
+					if (!projectPath.isPrefixOf(path) || JavaModel.getTarget(path, true) == null){
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceFolder, new String[] {entryPathMsg, projectName}));
+					}
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalSourceFolderPath, new String[] {entryPathMsg, projectName}));
+				}
+				break;
+		}
+
+		// Validate extra attributes
+		IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
+		if (extraAttributes != null) {
+			int length = extraAttributes.length;
+			HashSet set = new HashSet(length);
+			for (int i=0; i<length; i++) {
+				String attName = extraAttributes[i].getName();
+				if (!set.add(attName)) {
+					return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
+				}
+			}
+		}
+
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=232816, Now we have the facility to include a container
+	// name in diagnostics. If the parameter ``container'' is not null, it is used to point to the library
+	// more fully.
+	private static IJavaModelStatus validateLibraryEntry(IPath path, IJavaProject project, String container, IPath sourceAttachment, String entryPathMsg) {
+		if (path.isAbsolute() && !path.isEmpty()) {
+			Object target = JavaModel.getTarget(path, true);
+			if (target == null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=248661
+				IPath workspaceLocation = workspaceRoot.getLocation(); 
+				if (workspaceLocation.isPrefixOf(path)) {
+					target = JavaModel.getTarget(path.makeRelativeTo(workspaceLocation).makeAbsolute(), true);
+				}
+			}
+			if (target != null && !JavaCore.IGNORE.equals(project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true))) {
+				long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
+				long libraryJDK = Util.getJdkLevel(target);
+				if (libraryJDK != 0 && libraryJDK > projectTargetJDK) {
+					if (container != null) {
+						return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
+								project, path,
+								Messages.bind(Messages.classpath_incompatibleLibraryJDKLevelInContainer,
+										new String [] {
+											project.getElementName(),
+											CompilerOptions.versionFromJdkLevel(projectTargetJDK),
+											path.makeRelative().toString(),
+											container,
+											CompilerOptions.versionFromJdkLevel(libraryJDK)}));
+					} else {
+						return new JavaModelStatus(IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL,
+								project, path, 
+								Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel,
+										new String[] {
+											project.getElementName(),
+											CompilerOptions.versionFromJdkLevel(projectTargetJDK), 
+											path.makeRelative().toString(),
+											CompilerOptions.versionFromJdkLevel(libraryJDK)}));
+					}
+				}
+			}
+			if (target instanceof IResource){
+				IResource resolvedResource = (IResource) target;
+				switch(resolvedResource.getType()){
+					case IResource.FILE :
+						if (sourceAttachment != null
+							&& !sourceAttachment.isEmpty()
+							&& JavaModel.getTarget(sourceAttachment, true) == null){
+							if (container != null) {
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toString(), container}));
+							} else {
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), project.getElementName()}));
+							}
+						}
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042
+						// Validate the contents of the archive
+						IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg);
+						if (status != JavaModelStatus.VERIFIED_OK) 
+							return status;
+						break;
+					case IResource.FOLDER :	// internal binary folder
+						if (sourceAttachment != null
+							&& !sourceAttachment.isEmpty()
+							&& JavaModel.getTarget(sourceAttachment, true) == null){
+							if (container != null) {
+								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toString(), container}));
+							} else {
+								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), project.getElementName()}));
+							}
+						}
+				}
+			} else if (target instanceof File){
+				File file = JavaModel.getFile(target);
+				if (file == null) {
+					if (container != null) {
+						return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolderInContainer, new String[] {path.toOSString(), container}));
+					} else {
+						return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolder, new String[] {path.toOSString(), project.getElementName()}));
+					}
+				} else {
+					if (sourceAttachment != null
+							&& !sourceAttachment.isEmpty()
+							&& JavaModel.getTarget(sourceAttachment, true) == null){
+						if (container != null) {
+							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachmentInContainedLibrary, new String [] {sourceAttachment.toString(), path.toOSString(), container}));
+						} else {
+							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toOSString(), project.getElementName()}));
+						}
+					}
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042
+					// Validate the contents of the archive
+					if(file.isFile()) {
+						IJavaModelStatus status = validateLibraryContents(path, project, entryPathMsg);
+						if (status != JavaModelStatus.VERIFIED_OK) 
+							return status;
+					}
+				}
+			} else {
+				boolean isExternal = path.getDevice() != null || !ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0)).exists();
+				if (isExternal) {
+					if (container != null) {
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibraryInContainer, new String[] {path.toOSString(), container}));
+					} else {
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {path.toOSString(), project.getElementName()}));	
+					}
+				} else {
+					if (entryPathMsg == null) 
+						entryPathMsg = 	project.getElementName().equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();
+					if (container!= null) {	
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibraryInContainer, new String[] {entryPathMsg, container}));
+					} else {
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {entryPathMsg, project.getElementName()}));
+					}
+				}
+			}
+		} else {
+			if (entryPathMsg == null) 
+				entryPathMsg = 	project.getElementName().equals(path.segment(0)) ? path.removeFirstSegments(1).makeRelative().toString() : path.toString();
+				if (container != null) {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryPathInContainer, new String[] {entryPathMsg, container}));
+				} else {
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryPath, new String[] {entryPathMsg, project.getElementName()}));
+				}
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	private static IJavaModelStatus validateLibraryContents(IPath path, IJavaProject project, String entryPathMsg) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		try {
+			manager.verifyArchiveContent(path);
+		} catch (CoreException e) {
+			if (e.getStatus().getMessage() == Messages.status_IOException) {
+				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(
+						Messages.classpath_archiveReadError,
+						new String[] {entryPathMsg, project.getElementName()}));
+			}
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java
new file mode 100644
index 0000000..345535a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathValidation.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+
+/*
+ * Validates the raw classpath format and the resolved classpath of this project,
+ * updating markers if necessary.
+ */
+public class ClasspathValidation {
+
+	private JavaProject project;
+
+	public ClasspathValidation(JavaProject project) {
+		this.project = project;
+	}
+
+	public void validate() {
+		JavaModelManager.PerProjectInfo perProjectInfo;
+		try {
+			perProjectInfo = this.project.getPerProjectInfo();
+		} catch (JavaModelException e) {
+			// project doesn't exist
+			IProject resource = this.project.getProject();
+			if (resource.isAccessible()) {
+				this.project.flushClasspathProblemMarkers(true/*flush cycle markers*/, true/*flush classpath format markers*/, true /*flush overlapping output markers*/);
+
+				// remove problems and tasks created  by the builder
+				JavaBuilder.removeProblemsAndTasksFor(resource);
+			}
+			return;
+		}
+
+		// use synchronized block to ensure consistency
+		IClasspathEntry[] rawClasspath;
+		IPath outputLocation;
+		IJavaModelStatus status;
+		synchronized (perProjectInfo) {
+			rawClasspath = perProjectInfo.rawClasspath;
+			outputLocation = perProjectInfo.outputLocation;
+			status = perProjectInfo.rawClasspathStatus; // status has been set during POST_CHANGE
+		}
+
+		// update classpath format problems
+		this.project.flushClasspathProblemMarkers(false/*cycle*/, true/*format*/, false/*overlapping*/);
+		if (!status.isOK())
+			this.project.createClasspathProblemMarker(status);
+
+		// update overlapping output problem markers 
+		this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, true/*overlapping*/);
+		
+		// update resolved classpath problems
+		this.project.flushClasspathProblemMarkers(false/*cycle*/, false/*format*/, false/*overlapping*/);
+
+		if (rawClasspath != JavaProject.INVALID_CLASSPATH && outputLocation != null) {
+		 	for (int i = 0; i < rawClasspath.length; i++) {
+				status = ClasspathEntry.validateClasspathEntry(this.project, rawClasspath[i], false/*src attach*/, false /*not referred by a container*/);
+				if (!status.isOK()) {
+					this.project.createClasspathProblemMarker(status);
+				}
+			 }
+			status = ClasspathEntry.validateClasspath(this.project, rawClasspath, outputLocation);
+			if (status.getCode() != IStatus.OK)
+				this.project.createClasspathProblemMarker(status);
+		 }
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java
new file mode 100644
index 0000000..b1accab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Commits the contents of a working copy compilation
+ * unit to its original element and resource, bringing
+ * the Java Model up-to-date with the current contents of the working
+ * copy.
+ *
+ * <p>It is possible that the contents of the
+ * original resource have changed since the working copy was created,
+ * in which case there is an update conflict. This operation allows
+ * for two settings to resolve conflict set by the <code>fForce</code> flag:<ul>
+ * <li>force flag is <code>false</code> - in this case an <code>JavaModelException</code>
+ * 	is thrown</li>
+ * <li>force flag is <code>true</code> - in this case the contents of
+ * 	the working copy are applied to the underlying resource even though
+ * 	the working copy was created before a subsequent change in the
+ * 	resource</li>
+ * </ul>
+ *
+ * <p>The default conflict resolution setting is the force flag is <code>false</code>
+ *
+ * A JavaModelOperation exception is thrown either if the commit could not
+ * be performed or if the new content of the compilation unit violates some Java Model
+ * constraint (e.g. if the new package declaration doesn't match the name of the folder
+ * containing the compilation unit).
+ */
+public class CommitWorkingCopyOperation extends JavaModelOperation {
+	/**
+	 * Constructs an operation to commit the contents of a working copy
+	 * to its original compilation unit.
+	 */
+	public CommitWorkingCopyOperation(ICompilationUnit element, boolean force) {
+		super(new IJavaElement[] {element}, force);
+	}
+	/**
+	 * @exception JavaModelException if setting the source
+	 * 	of the original compilation unit fails
+	 */
+	protected void executeOperation() throws JavaModelException {
+		try {
+			beginTask(Messages.workingCopy_commit, 2);
+			CompilationUnit workingCopy = getCompilationUnit();
+
+			if (ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(workingCopy.getJavaProject().getElementName())) {
+				// case of a working copy without a resource
+				workingCopy.getBuffer().save(this.progressMonitor, this.force);
+				return;
+			}
+
+			ICompilationUnit primary = workingCopy.getPrimary();
+			boolean isPrimary = workingCopy.isPrimary();
+
+			JavaElementDeltaBuilder deltaBuilder = null;
+			PackageFragmentRoot root = (PackageFragmentRoot)workingCopy.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			boolean isIncluded = !Util.isExcluded(workingCopy);
+			IFile resource = (IFile)workingCopy.getResource();
+			IJavaProject project = root.getJavaProject();
+			if (isPrimary || (root.validateOnClasspath().isOK() && isIncluded && resource.isAccessible() && Util.isValidCompilationUnitName(workingCopy.getElementName(), project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true)))) {
+
+				// force opening so that the delta builder can get the old info
+				if (!isPrimary && !primary.isOpen()) {
+					primary.open(null);
+				}
+
+				// creates the delta builder (this remembers the content of the cu) if:
+				// - it is not excluded
+				// - and it is not a primary or it is a non-consistent primary
+				if (isIncluded && (!isPrimary || !workingCopy.isConsistent())) {
+					deltaBuilder = new JavaElementDeltaBuilder(primary);
+				}
+
+				// save the cu
+				IBuffer primaryBuffer = primary.getBuffer();
+				if (!isPrimary) {
+					if (primaryBuffer == null) return;
+					char[] primaryContents = primaryBuffer.getCharacters();
+					boolean hasSaved = false;
+					try {
+						IBuffer workingCopyBuffer = workingCopy.getBuffer();
+						if (workingCopyBuffer == null) return;
+						primaryBuffer.setContents(workingCopyBuffer.getCharacters());
+						primaryBuffer.save(this.progressMonitor, this.force);
+						primary.makeConsistent(this);
+						hasSaved = true;
+					} finally {
+						if (!hasSaved){
+							// restore original buffer contents since something went wrong
+							primaryBuffer.setContents(primaryContents);
+						}
+					}
+				} else {
+					// for a primary working copy no need to set the content of the buffer again
+					primaryBuffer.save(this.progressMonitor, this.force);
+					primary.makeConsistent(this);
+				}
+			} else {
+				// working copy on cu outside classpath OR resource doesn't exist yet
+				String encoding = null;
+				try {
+					encoding = resource.getCharset();
+				}
+				catch (CoreException ce) {
+					// use no encoding
+				}
+				String contents = workingCopy.getSource();
+				if (contents == null) return;
+				try {
+					byte[] bytes = encoding == null
+						? contents.getBytes()
+						: contents.getBytes(encoding);
+					ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+					if (resource.exists()) {
+						resource.setContents(
+							stream,
+							this.force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+							null);
+					} else {
+						resource.create(
+							stream,
+							this.force,
+							this.progressMonitor);
+					}
+				} catch (CoreException e) {
+					throw new JavaModelException(e);
+				} catch (UnsupportedEncodingException e) {
+					throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+				}
+
+			}
+
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+
+			// make sure working copy is in sync
+			workingCopy.updateTimeStamp((CompilationUnit)primary);
+			workingCopy.makeConsistent(this);
+			worked(1);
+
+			// build the deltas
+			if (deltaBuilder != null) {
+				deltaBuilder.buildDeltas();
+
+				// add the deltas to the list of deltas created during this operation
+				if (deltaBuilder.delta != null) {
+					addDelta(deltaBuilder.delta);
+				}
+			}
+			worked(1);
+		} finally {
+			done();
+		}
+	}
+	/**
+	 * Returns the compilation unit this operation is working on.
+	 */
+	protected CompilationUnit getCompilationUnit() {
+		return (CompilationUnit)getElementToProcess();
+	}
+	protected ISchedulingRule getSchedulingRule() {
+		IResource resource = getElementToProcess().getResource();
+		if (resource == null) return null;
+		IWorkspace workspace = resource.getWorkspace();
+		if (resource.exists()) {
+			return workspace.getRuleFactory().modifyRule(resource);
+		} else {
+			return workspace.getRuleFactory().createRule(resource);
+		}
+	}
+	/**
+	 * Possible failures: <ul>
+	 *	<li>INVALID_ELEMENT_TYPES - the compilation unit supplied to this
+	 *		operation is not a working copy
+	 *  <li>ELEMENT_NOT_PRESENT - the compilation unit the working copy is
+	 *		based on no longer exists.
+	 *  <li>UPDATE_CONFLICT - the original compilation unit has changed since
+	 *		the working copy was created and the operation specifies no force
+	 *  <li>READ_ONLY - the original compilation unit is in read-only mode
+	 *  </ul>
+	 */
+	public IJavaModelStatus verify() {
+		CompilationUnit cu = getCompilationUnit();
+		if (!cu.isWorkingCopy()) {
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, cu);
+		}
+		if (cu.hasResourceChanged() && !this.force) {
+			return new JavaModelStatus(IJavaModelStatusConstants.UPDATE_CONFLICT);
+		}
+		// no read-only check, since some repository adapters can change the flag on save
+		// operation.
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
new file mode 100644
index 0000000..984e775
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
@@ -0,0 +1,1349 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Alex Smirnoff (alexsmr@sympatico.ca) - part of the changes to support Java-like extension
+ *                                                            (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=71460)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.IOException;
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.UndoEdit;
+
+/**
+ * @see ICompilationUnit
+ */
+public class CompilationUnit extends Openable implements ICompilationUnit, org.eclipse.jdt.internal.compiler.env.ICompilationUnit, SuffixConstants {
+	/**
+	 * Internal synonym for deprecated constant AST.JSL2
+	 * to alleviate deprecation warnings.
+	 * @deprecated
+	 */
+	/*package*/ static final int JLS2_INTERNAL = AST.JLS2;
+
+	private static final IImportDeclaration[] NO_IMPORTS = new IImportDeclaration[0];
+
+	protected String name;
+	public WorkingCopyOwner owner;
+
+/**
+ * Constructs a handle to a compilation unit with the given name in the
+ * specified package for the specified owner
+ */
+public CompilationUnit(PackageFragment parent, String name, WorkingCopyOwner owner) {
+	super(parent);
+	this.name = name;
+	this.owner = owner;
+}
+
+
+/*
+ * @see ICompilationUnit#applyTextEdit(TextEdit, IProgressMonitor)
+ */
+public UndoEdit applyTextEdit(TextEdit edit, IProgressMonitor monitor) throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	if (buffer instanceof IBuffer.ITextEditCapability) {
+		return ((IBuffer.ITextEditCapability) buffer).applyTextEdit(edit, monitor);
+	} else if (buffer != null) {
+		IDocument document = buffer instanceof IDocument ? (IDocument) buffer : new DocumentAdapter(buffer);
+		try {
+			UndoEdit undoEdit= edit.apply(document);
+			return undoEdit;
+		} catch (MalformedTreeException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.BAD_TEXT_EDIT_LOCATION);
+		} catch (BadLocationException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.BAD_TEXT_EDIT_LOCATION);
+		}
+	}
+	return null; // can not happen, there are no compilation units without buffer
+}
+
+/*
+ * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)
+ */
+public void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = manager.getPerWorkingCopyInfo(this, false/*don't create*/, true /*record usage*/, null/*no problem requestor needed*/);
+	if (perWorkingCopyInfo == null) {
+		// close cu and its children
+		close();
+
+		BecomeWorkingCopyOperation operation = new BecomeWorkingCopyOperation(this, problemRequestor);
+		operation.runOperation(monitor);
+	}
+}
+/*
+ * @see ICompilationUnit#becomeWorkingCopy(IProgressMonitor)
+ */
+public void becomeWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
+	IProblemRequestor requestor = this.owner == null ? null : this.owner.getProblemRequestor(this);
+	becomeWorkingCopy(requestor, monitor);
+}
+protected boolean buildStructure(OpenableElementInfo info, final IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+	CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info;
+
+	// ensure buffer is opened
+	IBuffer buffer = getBufferManager().getBuffer(CompilationUnit.this);
+	if (buffer == null) {
+		openBuffer(pm, unitInfo); // open buffer independently from the info, since we are building the info
+	}
+
+	// generate structure and compute syntax problems if needed
+	CompilationUnitStructureRequestor requestor = new CompilationUnitStructureRequestor(this, unitInfo, newElements);
+	JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo();
+	IJavaProject project = getJavaProject();
+
+	boolean createAST;
+	boolean resolveBindings;
+	int reconcileFlags;
+	HashMap problems;
+	if (info instanceof ASTHolderCUInfo) {
+		ASTHolderCUInfo astHolder = (ASTHolderCUInfo) info;
+		createAST = astHolder.astLevel != NO_AST;
+		resolveBindings = astHolder.resolveBindings;
+		reconcileFlags = astHolder.reconcileFlags;
+		problems = astHolder.problems;
+	} else {
+		createAST = false;
+		resolveBindings = false;
+		reconcileFlags = 0;
+		problems = null;
+	}
+
+	boolean computeProblems = perWorkingCopyInfo != null && perWorkingCopyInfo.isActive() && project != null && JavaProject.hasJavaNature(project.getProject());
+	IProblemFactory problemFactory = new DefaultProblemFactory();
+	Map options = project == null ? JavaCore.getOptions() : project.getOptions(true);
+	if (!computeProblems) {
+		// disable task tags checking to speed up parsing
+		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+	}
+	CompilerOptions compilerOptions = new CompilerOptions(options);
+	compilerOptions.ignoreMethodBodies = (reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+	SourceElementParser parser = new SourceElementParser(
+		requestor,
+		problemFactory,
+		compilerOptions,
+		true/*report local declarations*/,
+		!createAST /*optimize string literals only if not creating a DOM AST*/);
+	parser.reportOnlyOneSyntaxError = !computeProblems;
+	parser.setMethodsFullRecovery(true);
+	parser.setStatementsRecovery((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0);
+
+	if (!computeProblems && !resolveBindings && !createAST) // disable javadoc parsing if not computing problems, not resolving and not creating ast
+		parser.javadocParser.checkDocComment = false;
+	requestor.parser = parser;
+
+	// update timestamp (might be IResource.NULL_STAMP if original does not exist)
+	if (underlyingResource == null) {
+		underlyingResource = getResource();
+	}
+	// underlying resource is null in the case of a working copy on a class file in a jar
+	if (underlyingResource != null)
+		unitInfo.timestamp = ((IFile)underlyingResource).getModificationStamp();
+
+	// compute other problems if needed
+	CompilationUnitDeclaration compilationUnitDeclaration = null;
+	CompilationUnit source = cloneCachingContents();
+	try {
+		if (computeProblems) {
+			if (problems == null) {
+				// report problems to the problem requestor
+				problems = new HashMap();
+				compilationUnitDeclaration = CompilationUnitProblemFinder.process(source, parser, this.owner, problems, createAST, reconcileFlags, pm);
+				try {
+					perWorkingCopyInfo.beginReporting();
+					for (Iterator iteraror = problems.values().iterator(); iteraror.hasNext();) {
+						CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next();
+						if (categorizedProblems == null) continue;
+						for (int i = 0, length = categorizedProblems.length; i < length; i++) {
+							perWorkingCopyInfo.acceptProblem(categorizedProblems[i]);
+						}
+					}
+				} finally {
+					perWorkingCopyInfo.endReporting();
+				}
+			} else {
+				// collect problems
+				compilationUnitDeclaration = CompilationUnitProblemFinder.process(source, parser, this.owner, problems, createAST, reconcileFlags, pm);
+			}
+		} else {
+			compilationUnitDeclaration = parser.parseCompilationUnit(source, true /*full parse to find local elements*/, pm);
+		}
+
+		if (createAST) {
+			int astLevel = ((ASTHolderCUInfo) info).astLevel;
+			org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, compilationUnitDeclaration, options, computeProblems, source, reconcileFlags, pm);
+			((ASTHolderCUInfo) info).ast = cu;
+		}
+	} finally {
+	    if (compilationUnitDeclaration != null) {
+	        compilationUnitDeclaration.cleanUp();
+	    }
+	}
+
+	return unitInfo.isStructureKnown();
+}
+/*
+ * Clone this handle so that it caches its contents in memory.
+ * DO NOT PASS TO CLIENTS
+ */
+public CompilationUnit cloneCachingContents() {
+	return new CompilationUnit((PackageFragment) this.parent, this.name, this.owner) {
+		private char[] cachedContents;
+		public char[] getContents() {
+			if (this.cachedContents == null)
+				this.cachedContents = CompilationUnit.this.getContents();
+			return this.cachedContents;
+		}
+		public CompilationUnit originalFromClone() {
+			return CompilationUnit.this;
+		}
+	};
+}
+/*
+ * @see Openable#canBeRemovedFromCache
+ */
+public boolean canBeRemovedFromCache() {
+	if (getPerWorkingCopyInfo() != null) return false; // working copies should remain in the cache until they are destroyed
+	return super.canBeRemovedFromCache();
+}
+/*
+ * @see Openable#canBufferBeRemovedFromCache
+ */
+public boolean canBufferBeRemovedFromCache(IBuffer buffer) {
+	if (getPerWorkingCopyInfo() != null) return false; // working copy buffers should remain in the cache until working copy is destroyed
+	return super.canBufferBeRemovedFromCache(buffer);
+}/*
+ * @see IOpenable#close
+ */
+public void close() throws JavaModelException {
+	if (getPerWorkingCopyInfo() != null) return; // a working copy must remain opened until it is discarded
+	super.close();
+}
+/*
+ * @see Openable#closing
+ */
+protected void closing(Object info) {
+	if (getPerWorkingCopyInfo() == null) {
+		super.closing(info);
+	} // else the buffer of a working copy must remain open for the lifetime of the working copy
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICompletionRequestor)
+ * @deprecated
+ */
+public void codeComplete(int offset, ICompletionRequestor requestor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICompletionRequestor, WorkingCopyOwner)
+ * @deprecated
+ */
+public void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner workingCopyOwner) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	codeComplete(offset, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), workingCopyOwner);
+}
+/**
+ * @see ICodeAssist#codeComplete(int, ICodeCompletionRequestor)
+ * @deprecated - use codeComplete(int, ICompletionRequestor)
+ */
+public void codeComplete(int offset, final ICodeCompletionRequestor requestor) throws JavaModelException {
+
+	if (requestor == null){
+		codeComplete(offset, (ICompletionRequestor)null);
+		return;
+	}
+	codeComplete(
+		offset,
+		new ICompletionRequestor(){
+			public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptError(IProblem error) {
+				// was disabled in 1.0
+			}
+			public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptField(declaringTypePackageName, declaringTypeName, fieldName, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+				requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptKeyword(keywordName, completionStart, completionEnd);
+			}
+			public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptLabel(labelName, completionStart, completionEnd);
+			}
+			public void acceptLocalVariable(char[] localVarName,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// skip parameter names
+				requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptModifier(modifierName, completionStart, completionEnd);
+			}
+			public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
+			}
+			public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
+			}
+			public void acceptVariableName(char[] typePackageName,char[] typeName,char[] varName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+		});
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner) throws JavaModelException {
+	codeComplete(offset, requestor, workingCopyOwner, null);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner, org.eclipse.core.runtime.IProgressMonitor)
+ */
+public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(
+			this,
+			isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
+			offset,
+			requestor,
+			workingCopyOwner,
+			this,
+			monitor);
+}
+
+/**
+ * @see ICodeAssist#codeSelect(int, int)
+ */
+public IJavaElement[] codeSelect(int offset, int length) throws JavaModelException {
+	return codeSelect(offset, length, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see ICodeAssist#codeSelect(int, int, WorkingCopyOwner)
+ */
+public IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner workingCopyOwner) throws JavaModelException {
+	return super.codeSelect(this, offset, length, workingCopyOwner);
+}
+/**
+ * @see IWorkingCopy#commit(boolean, IProgressMonitor)
+ * @deprecated
+ */
+public void commit(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	commitWorkingCopy(force, monitor);
+}
+/**
+ * @see ICompilationUnit#commitWorkingCopy(boolean, IProgressMonitor)
+ */
+public void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force);
+	op.runOperation(monitor);
+}
+/**
+ * @see ISourceManipulation#copy(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements = new IJavaElement[] {this};
+	IJavaElement[] containers = new IJavaElement[] {container};
+	String[] renamings = null;
+	if (rename != null) {
+		renamings = new String[] {rename};
+	}
+	getJavaModel().copy(elements, containers, null, renamings, force, monitor);
+}
+/**
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return new CompilationUnitElementInfo();
+}
+/**
+ * @see ICompilationUnit#createImport(String, IJavaElement, IProgressMonitor)
+ */
+public IImportDeclaration createImport(String importName, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
+	return createImport(importName, sibling, Flags.AccDefault, monitor);
+}
+
+/**
+ * @see ICompilationUnit#createImport(String, IJavaElement, int, IProgressMonitor)
+ * @since 3.0
+ */
+public IImportDeclaration createImport(String importName, IJavaElement sibling, int flags, IProgressMonitor monitor) throws JavaModelException {
+	CreateImportOperation op = new CreateImportOperation(importName, this, flags);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return getImport(importName);
+}
+
+/**
+ * @see ICompilationUnit#createPackageDeclaration(String, IProgressMonitor)
+ */
+public IPackageDeclaration createPackageDeclaration(String pkg, IProgressMonitor monitor) throws JavaModelException {
+
+	CreatePackageDeclarationOperation op= new CreatePackageDeclarationOperation(pkg, this);
+	op.runOperation(monitor);
+	return getPackageDeclaration(pkg);
+}
+/**
+ * @see ICompilationUnit#createType(String, IJavaElement, boolean, IProgressMonitor)
+ */
+public IType createType(String content, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (!exists()) {
+		//autogenerate this compilation unit
+		IPackageFragment pkg = (IPackageFragment) getParent();
+		String source = ""; //$NON-NLS-1$
+		if (!pkg.isDefaultPackage()) {
+			//not the default package...add the package declaration
+			String lineSeparator = Util.getLineSeparator(null/*no existing source*/, getJavaProject());
+			source = "package " + pkg.getElementName() + ";"  + lineSeparator + lineSeparator; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, this.name, source, force);
+		op.runOperation(monitor);
+	}
+	CreateTypeOperation op = new CreateTypeOperation(this, content, force);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return (IType) op.getResultElements()[0];
+}
+/**
+ * @see ISourceManipulation#delete(boolean, IProgressMonitor)
+ */
+public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	IJavaElement[] elements= new IJavaElement[] {this};
+	getJavaModel().delete(elements, force, monitor);
+}
+/**
+ * @see IWorkingCopy#destroy()
+ * @deprecated
+ */
+public void destroy() {
+	try {
+		discardWorkingCopy();
+	} catch (JavaModelException e) {
+		if (JavaModelManager.VERBOSE)
+			e.printStackTrace();
+	}
+}
+/*
+ * @see ICompilationUnit#discardWorkingCopy
+ */
+public void discardWorkingCopy() throws JavaModelException {
+	// discard working copy and its children
+	DiscardWorkingCopyOperation op = new DiscardWorkingCopyOperation(this);
+	op.runOperation(null);
+}
+/**
+ * Returns true if this handle represents the same Java element
+ * as the given handle.
+ *
+ * @see Object#equals(java.lang.Object)
+ */
+public boolean equals(Object obj) {
+	if (!(obj instanceof CompilationUnit)) return false;
+	CompilationUnit other = (CompilationUnit)obj;
+	return this.owner.equals(other.owner) && super.equals(obj);
+}
+/**
+ * @see ICompilationUnit#findElements(IJavaElement)
+ */
+public IJavaElement[] findElements(IJavaElement element) {
+	ArrayList children = new ArrayList();
+	while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
+		children.add(element);
+		element = element.getParent();
+	}
+	if (element == null) return null;
+	IJavaElement currentElement = this;
+	for (int i = children.size()-1; i >= 0; i--) {
+		SourceRefElement child = (SourceRefElement)children.get(i);
+		switch (child.getElementType()) {
+			case IJavaElement.PACKAGE_DECLARATION:
+				currentElement = ((ICompilationUnit)currentElement).getPackageDeclaration(child.getElementName());
+				break;
+			case IJavaElement.IMPORT_CONTAINER:
+				currentElement = ((ICompilationUnit)currentElement).getImportContainer();
+				break;
+			case IJavaElement.IMPORT_DECLARATION:
+				currentElement = ((IImportContainer)currentElement).getImport(child.getElementName());
+				break;
+			case IJavaElement.TYPE:
+				switch (currentElement.getElementType()) {
+					case IJavaElement.COMPILATION_UNIT:
+						currentElement = ((ICompilationUnit)currentElement).getType(child.getElementName());
+						break;
+					case IJavaElement.TYPE:
+						currentElement = ((IType)currentElement).getType(child.getElementName());
+						break;
+					case IJavaElement.FIELD:
+					case IJavaElement.INITIALIZER:
+					case IJavaElement.METHOD:
+						currentElement =  ((IMember)currentElement).getType(child.getElementName(), child.occurrenceCount);
+						break;
+				}
+				break;
+			case IJavaElement.INITIALIZER:
+				currentElement = ((IType)currentElement).getInitializer(child.occurrenceCount);
+				break;
+			case IJavaElement.FIELD:
+				currentElement = ((IType)currentElement).getField(child.getElementName());
+				break;
+			case IJavaElement.METHOD:
+				currentElement = ((IType)currentElement).getMethod(child.getElementName(), ((IMethod)child).getParameterTypes());
+				break;
+		}
+
+	}
+	if (currentElement != null && currentElement.exists()) {
+		return new IJavaElement[] {currentElement};
+	} else {
+		return null;
+	}
+}
+/**
+ * @see ICompilationUnit#findPrimaryType()
+ */
+public IType findPrimaryType() {
+	String typeName = Util.getNameWithoutJavaLikeExtension(getElementName());
+	IType primaryType= getType(typeName);
+	if (primaryType.exists()) {
+		return primaryType;
+	}
+	return null;
+}
+
+/**
+ * @see IWorkingCopy#findSharedWorkingCopy(IBufferFactory)
+ * @deprecated
+ */
+public IJavaElement findSharedWorkingCopy(IBufferFactory factory) {
+
+	// if factory is null, default factory must be used
+	if (factory == null) factory = getBufferManager().getDefaultBufferFactory();
+
+	return findWorkingCopy(BufferFactoryWrapper.create(factory));
+}
+
+/**
+ * @see ICompilationUnit#findWorkingCopy(WorkingCopyOwner)
+ */
+public ICompilationUnit findWorkingCopy(WorkingCopyOwner workingCopyOwner) {
+	CompilationUnit cu = new CompilationUnit((PackageFragment)this.parent, getElementName(), workingCopyOwner);
+	if (workingCopyOwner == DefaultWorkingCopyOwner.PRIMARY) {
+		return cu;
+	} else {
+		// must be a working copy
+		JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = cu.getPerWorkingCopyInfo();
+		if (perWorkingCopyInfo != null) {
+			return perWorkingCopyInfo.getWorkingCopy();
+		} else {
+			return null;
+		}
+	}
+}
+/**
+ * @see ICompilationUnit#getAllTypes()
+ */
+public IType[] getAllTypes() throws JavaModelException {
+	IJavaElement[] types = getTypes();
+	int i;
+	ArrayList allTypes = new ArrayList(types.length);
+	ArrayList typesToTraverse = new ArrayList(types.length);
+	for (i = 0; i < types.length; i++) {
+		typesToTraverse.add(types[i]);
+	}
+	while (!typesToTraverse.isEmpty()) {
+		IType type = (IType) typesToTraverse.get(0);
+		typesToTraverse.remove(type);
+		allTypes.add(type);
+		types = type.getTypes();
+		for (i = 0; i < types.length; i++) {
+			typesToTraverse.add(types[i]);
+		}
+	}
+	IType[] arrayOfAllTypes = new IType[allTypes.size()];
+	allTypes.toArray(arrayOfAllTypes);
+	return arrayOfAllTypes;
+}
+/**
+ * @see IMember#getCompilationUnit()
+ */
+public ICompilationUnit getCompilationUnit() {
+	return this;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getContents()
+ */
+public char[] getContents() {
+	IBuffer buffer = getBufferManager().getBuffer(this);
+	if (buffer == null) {
+		// no need to force opening of CU to get the content
+		// also this cannot be a working copy, as its buffer is never closed while the working copy is alive
+		IFile file = (IFile) getResource();
+		// Get encoding from file
+		String encoding;
+		try {
+			encoding = file.getCharset();
+		} catch(CoreException ce) {
+			// do not use any encoding
+			encoding = null;
+		}
+		try {
+			return Util.getResourceContentsAsCharArray(file, encoding);
+		} catch (JavaModelException e) {
+			if (JavaModelManager.getJavaModelManager().abortOnMissingSource.get() == Boolean.TRUE) {
+				IOException ioException =
+					e.getJavaModelStatus().getCode() == IJavaModelStatusConstants.IO_EXCEPTION ?
+						(IOException)e.getException() :
+						new IOException(e.getMessage());
+				throw new AbortCompilationUnit(null, ioException, encoding);
+			} else {
+				Util.log(e, Messages.bind(Messages.file_notFound, file.getFullPath().toString()));
+			}
+			return CharOperation.NO_CHAR;
+		}
+	}
+	char[] contents = buffer.getCharacters();
+	if (contents == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=129814
+		if (JavaModelManager.getJavaModelManager().abortOnMissingSource.get() == Boolean.TRUE) {
+			IOException ioException = new IOException(Messages.buffer_closed);
+			IFile file = (IFile) getResource();
+			// Get encoding from file
+			String encoding;
+			try {
+				encoding = file.getCharset();
+			} catch(CoreException ce) {
+				// do not use any encoding
+				encoding = null;
+			}
+			throw new AbortCompilationUnit(null, ioException, encoding);
+		}
+		return CharOperation.NO_CHAR;
+	}
+	return contents;
+}
+/**
+ * A compilation unit has a corresponding resource unless it is contained
+ * in a jar.
+ *
+ * @see IJavaElement#getCorrespondingResource()
+ */
+public IResource getCorrespondingResource() throws JavaModelException {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root == null || root.isArchive()) {
+		return null;
+	} else {
+		return getUnderlyingResource();
+	}
+}
+/**
+ * @see ICompilationUnit#getElementAt(int)
+ */
+public IJavaElement getElementAt(int position) throws JavaModelException {
+
+	IJavaElement e= getSourceElementAt(position);
+	if (e == this) {
+		return null;
+	} else {
+		return e;
+	}
+}
+public String getElementName() {
+	return this.name;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return COMPILATION_UNIT;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName(){
+	return getPath().toString().toCharArray();
+}
+
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_IMPORTDECLARATION:
+			JavaElement container = (JavaElement)getImportContainer();
+			return container.getHandleFromMemento(token, memento, workingCopyOwner);
+		case JEM_PACKAGEDECLARATION:
+			if (!memento.hasMoreTokens()) return this;
+			String pkgName = memento.nextToken();
+			JavaElement pkgDecl = (JavaElement)getPackageDeclaration(pkgName);
+			return pkgDecl.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_TYPE:
+			if (!memento.hasMoreTokens()) return this;
+			String typeName = memento.nextToken();
+			JavaElement type = (JavaElement)getType(typeName);
+			return type.getHandleFromMemento(memento, workingCopyOwner);
+	}
+	return null;
+}
+
+/**
+ * @see JavaElement#getHandleMementoDelimiter()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_COMPILATIONUNIT;
+}
+/**
+ * @see ICompilationUnit#getImport(String)
+ */
+public IImportDeclaration getImport(String importName) {
+	return getImportContainer().getImport(importName);
+}
+/**
+ * @see ICompilationUnit#getImportContainer()
+ */
+public IImportContainer getImportContainer() {
+	return new ImportContainer(this);
+}
+
+
+/**
+ * @see ICompilationUnit#getImports()
+ */
+public IImportDeclaration[] getImports() throws JavaModelException {
+	IImportContainer container= getImportContainer();
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	Object info = manager.getInfo(container);
+	if (info == null) {
+		if (manager.getInfo(this) != null)
+			// CU was opened, but no import container, then no imports
+			return NO_IMPORTS;
+		else {
+			open(null); // force opening of CU
+			info = manager.getInfo(container);
+			if (info == null)
+				// after opening, if no import container, then no imports
+				return NO_IMPORTS;
+		}
+	}
+	IJavaElement[] elements = ((ImportContainerInfo) info).children;
+	int length = elements.length;
+	IImportDeclaration[] imports = new IImportDeclaration[length];
+	System.arraycopy(elements, 0, imports, 0, length);
+	return imports;
+}
+/**
+ * @see IMember#getTypeRoot()
+ */
+public ITypeRoot getTypeRoot() {
+	return this;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
+ */
+public char[] getMainTypeName(){
+	return Util.getNameWithoutJavaLikeExtension(getElementName()).toCharArray();
+}
+/**
+ * @see IWorkingCopy#getOriginal(IJavaElement)
+ * @deprecated
+ */
+public IJavaElement getOriginal(IJavaElement workingCopyElement) {
+	// backward compatibility
+	if (!isWorkingCopy()) return null;
+	CompilationUnit cu = (CompilationUnit)workingCopyElement.getAncestor(COMPILATION_UNIT);
+	if (cu == null || !this.owner.equals(cu.owner)) {
+		return null;
+	}
+
+	return workingCopyElement.getPrimaryElement();
+}
+/**
+ * @see IWorkingCopy#getOriginalElement()
+ * @deprecated
+ */
+public IJavaElement getOriginalElement() {
+	// backward compatibility
+	if (!isWorkingCopy()) return null;
+
+	return getPrimaryElement();
+}
+/*
+ * @see ICompilationUnit#getOwner()
+ */
+public WorkingCopyOwner getOwner() {
+	return isPrimary() || !isWorkingCopy() ? null : this.owner;
+}
+/**
+ * @see ICompilationUnit#getPackageDeclaration(String)
+ */
+public IPackageDeclaration getPackageDeclaration(String pkg) {
+	return new PackageDeclaration(this, pkg);
+}
+/**
+ * @see ICompilationUnit#getPackageDeclarations()
+ */
+public IPackageDeclaration[] getPackageDeclarations() throws JavaModelException {
+	ArrayList list = getChildrenOfType(PACKAGE_DECLARATION);
+	IPackageDeclaration[] array= new IPackageDeclaration[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getPackageName()
+ */
+public char[][] getPackageName() {
+	PackageFragment packageFragment = (PackageFragment) getParent();
+	if (packageFragment == null) return CharOperation.NO_CHAR_CHAR;
+	return Util.toCharArrays(packageFragment.names);
+}
+
+/**
+ * @see IJavaElement#getPath()
+ */
+public IPath getPath() {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root == null) return new Path(getElementName()); // working copy not in workspace
+	if (root.isArchive()) {
+		return root.getPath();
+	} else {
+		return getParent().getPath().append(getElementName());
+	}
+}
+/*
+ * Returns the per working copy info for the receiver, or null if none exist.
+ * Note: the use count of the per working copy info is NOT incremented.
+ */
+public JavaModelManager.PerWorkingCopyInfo getPerWorkingCopyInfo() {
+	return JavaModelManager.getJavaModelManager().getPerWorkingCopyInfo(this, false/*don't create*/, false/*don't record usage*/, null/*no problem requestor needed*/);
+}
+/*
+ * @see ICompilationUnit#getPrimary()
+ */
+public ICompilationUnit getPrimary() {
+	return (ICompilationUnit)getPrimaryElement(true);
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner && isPrimary()) return this;
+	return new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY);
+}
+/*
+ * @see Openable#resource(PackageFragmentRoot)
+ */
+public IResource resource(PackageFragmentRoot root) {
+	if (root == null) return null; // working copy not in workspace
+	return ((IContainer) ((Openable) this.parent).resource(root)).getFile(new Path(getElementName()));
+}
+/**
+ * @see ISourceReference#getSource()
+ */
+public String getSource() throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	if (buffer == null) return ""; //$NON-NLS-1$
+	return buffer.getContents();
+}
+/**
+ * @see ISourceReference#getSourceRange()
+ */
+public ISourceRange getSourceRange() throws JavaModelException {
+	return ((CompilationUnitElementInfo) getElementInfo()).getSourceRange();
+}
+/**
+ * @see ICompilationUnit#getType(String)
+ */
+public IType getType(String typeName) {
+	return new SourceType(this, typeName);
+}
+/**
+ * @see ICompilationUnit#getTypes()
+ */
+public IType[] getTypes() throws JavaModelException {
+	ArrayList list = getChildrenOfType(TYPE);
+	IType[] array= new IType[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+	if (isWorkingCopy() && !isPrimary()) return null;
+	return super.getUnderlyingResource();
+}
+/**
+ * @see IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
+ * @deprecated
+ */
+public IJavaElement getSharedWorkingCopy(IProgressMonitor pm, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
+
+	// if factory is null, default factory must be used
+	if (factory == null) factory = getBufferManager().getDefaultBufferFactory();
+
+	return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, pm);
+}
+/**
+ * @see IWorkingCopy#getWorkingCopy()
+ * @deprecated
+ */
+public IJavaElement getWorkingCopy() throws JavaModelException {
+	return getWorkingCopy(null);
+}
+/**
+ * @see ICompilationUnit#getWorkingCopy(IProgressMonitor)
+ */
+public ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException {
+	return getWorkingCopy(new WorkingCopyOwner() {/*non shared working copy*/}, null/*no problem requestor*/, monitor);
+}
+/**
+ * @see ITypeRoot#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)
+ */
+public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor) throws JavaModelException {
+	return getWorkingCopy(workingCopyOwner, null, monitor);
+}
+/**
+ * @see IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)
+ * @deprecated
+ */
+public IJavaElement getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor problemRequestor) throws JavaModelException {
+	return getWorkingCopy(BufferFactoryWrapper.create(factory), problemRequestor, monitor);
+}
+/**
+ * @see ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
+ * @deprecated
+ */
+public ICompilationUnit getWorkingCopy(WorkingCopyOwner workingCopyOwner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException {
+	if (!isPrimary()) return this;
+
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+
+	CompilationUnit workingCopy = new CompilationUnit((PackageFragment)getParent(), getElementName(), workingCopyOwner);
+	JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo =
+		manager.getPerWorkingCopyInfo(workingCopy, false/*don't create*/, true/*record usage*/, null/*not used since don't create*/);
+	if (perWorkingCopyInfo != null) {
+		return perWorkingCopyInfo.getWorkingCopy(); // return existing handle instead of the one created above
+	}
+	BecomeWorkingCopyOperation op = new BecomeWorkingCopyOperation(workingCopy, problemRequestor);
+	op.runOperation(monitor);
+	return workingCopy;
+}
+/**
+ * @see Openable#hasBuffer()
+ */
+protected boolean hasBuffer() {
+	return true;
+}
+/*
+ * @see ICompilationUnit#hasResourceChanged()
+ */
+public boolean hasResourceChanged() {
+	if (!isWorkingCopy()) return false;
+
+	// if resource got deleted, then #getModificationStamp() will answer IResource.NULL_STAMP, which is always different from the cached
+	// timestamp
+	Object info = JavaModelManager.getJavaModelManager().getInfo(this);
+	if (info == null) return false;
+	IResource resource = getResource();
+	if (resource == null) return false;
+	return ((CompilationUnitElementInfo)info).timestamp != resource.getModificationStamp();
+}
+public boolean ignoreOptionalProblems() {
+	return getPackageFragmentRoot().ignoreOptionalProblems();
+}
+/**
+ * @see IWorkingCopy#isBasedOn(IResource)
+ * @deprecated
+ */
+public boolean isBasedOn(IResource resource) {
+	if (!isWorkingCopy()) return false;
+	if (!getResource().equals(resource)) return false;
+	return !hasResourceChanged();
+}
+/**
+ * @see IOpenable#isConsistent()
+ */
+public boolean isConsistent() {
+	return !JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().contains(this);
+}
+public boolean isPrimary() {
+	return this.owner == DefaultWorkingCopyOwner.PRIMARY;
+}
+/**
+ * @see Openable#isSourceElement()
+ */
+protected boolean isSourceElement() {
+	return true;
+}
+protected IStatus validateCompilationUnit(IResource resource) {
+	IPackageFragmentRoot root = getPackageFragmentRoot();
+	// root never null as validation is not done for working copies
+	try {
+		if (root.getKind() != IPackageFragmentRoot.K_SOURCE)
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, root);
+	} catch (JavaModelException e) {
+		return e.getJavaModelStatus();
+	}
+	if (resource != null) {
+		char[][] inclusionPatterns = ((PackageFragmentRoot)root).fullInclusionPatternChars();
+		char[][] exclusionPatterns = ((PackageFragmentRoot)root).fullExclusionPatternChars();
+		if (Util.isExcluded(resource, inclusionPatterns, exclusionPatterns))
+			return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH, this);
+		if (!resource.isAccessible())
+			return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this);
+	}
+	IJavaProject project = getJavaProject();
+	return JavaConventions.validateCompilationUnitName(getElementName(),project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
+}
+/*
+ * @see ICompilationUnit#isWorkingCopy()
+ */
+public boolean isWorkingCopy() {
+	// For backward compatibility, non primary working copies are always returning true; in removal
+	// delta, clients can still check that element was a working copy before being discarded.
+	return !isPrimary() || getPerWorkingCopyInfo() != null;
+}
+/**
+ * @see IOpenable#makeConsistent(IProgressMonitor)
+ */
+public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
+	makeConsistent(NO_AST, false/*don't resolve bindings*/, 0 /* don't perform statements recovery */, null/*don't collect problems but report them*/, monitor);
+}
+public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(int astLevel, boolean resolveBindings, int reconcileFlags, HashMap problems, IProgressMonitor monitor) throws JavaModelException {
+	if (isConsistent()) return null;
+
+	try {
+		JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
+		// create a new info and make it the current info
+		// (this will remove the info and its children just before storing the new infos)
+		if (astLevel != NO_AST || problems != null) {
+			ASTHolderCUInfo info = new ASTHolderCUInfo();
+			info.astLevel = astLevel;
+			info.resolveBindings = resolveBindings;
+			info.reconcileFlags = reconcileFlags;
+			info.problems = problems;
+			openWhenClosed(info, true, monitor);
+			org.eclipse.jdt.core.dom.CompilationUnit result = info.ast;
+			info.ast = null;
+			return result;
+		} else {
+			openWhenClosed(createElementInfo(), true, monitor);
+			return null;
+		}
+	} finally {
+		JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
+	}
+}
+/**
+ * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] containers= new IJavaElement[] {container};
+
+	String[] renamings= null;
+	if (rename != null) {
+		renamings= new String[] {rename};
+	}
+	getJavaModel().move(elements, containers, null, renamings, force, monitor);
+}
+
+/**
+ * @see Openable#openBuffer(IProgressMonitor, Object)
+ */
+protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
+
+	// create buffer
+	BufferManager bufManager = getBufferManager();
+	boolean isWorkingCopy = isWorkingCopy();
+	IBuffer buffer =
+		isWorkingCopy
+			? this.owner.createBuffer(this)
+			: BufferManager.createBuffer(this);
+	if (buffer == null) return null;
+	
+	ICompilationUnit original = null;
+	boolean mustSetToOriginalContent = false;
+	if (isWorkingCopy) {
+		// ensure that isOpen() is called outside the bufManager synchronized block
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=237772
+		mustSetToOriginalContent = !isPrimary() && (original = new CompilationUnit((PackageFragment)getParent(), getElementName(), DefaultWorkingCopyOwner.PRIMARY)).isOpen() ;
+	}
+
+	// synchronize to ensure that 2 threads are not putting 2 different buffers at the same time
+	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=146331
+	synchronized(bufManager) {
+		IBuffer existingBuffer = bufManager.getBuffer(this);
+		if (existingBuffer != null)
+			return existingBuffer;
+
+		// set the buffer source
+		if (buffer.getCharacters() == null) {
+			if (isWorkingCopy) {
+				if (mustSetToOriginalContent) {
+					buffer.setContents(original.getSource());
+				} else {
+					IFile file = (IFile)getResource();
+					if (file == null || !file.exists()) {
+						// initialize buffer with empty contents
+						buffer.setContents(CharOperation.NO_CHAR);
+					} else {
+						buffer.setContents(Util.getResourceContentsAsCharArray(file));
+					}
+				}
+			} else {
+				IFile file = (IFile)getResource();
+				if (file == null || !file.exists()) throw newNotPresentException();
+				buffer.setContents(Util.getResourceContentsAsCharArray(file));
+			}
+		}
+
+		// add buffer to buffer cache
+		// note this may cause existing buffers to be removed from the buffer cache, but only primary compilation unit's buffer
+		// can be closed, thus no call to a client's IBuffer#close() can be done in this synchronized block.
+		bufManager.addBuffer(buffer);
+
+		// listen to buffer changes
+		buffer.addBufferChangedListener(this);
+	}
+	return buffer;
+}
+protected void openAncestors(HashMap newElements, IProgressMonitor monitor) throws JavaModelException {
+	if (!isWorkingCopy()) {
+		super.openAncestors(newElements, monitor);
+	}
+	// else don't open ancestors for a working copy to speed up the first becomeWorkingCopy
+	// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89411)
+}
+/*
+ * @see #cloneCachingContents()
+ */
+public CompilationUnit originalFromClone() {
+	return this;
+}
+/**
+ * @see ICompilationUnit#reconcile()
+ * @deprecated
+ */
+public IMarker[] reconcile() throws JavaModelException {
+	reconcile(NO_AST, false/*don't force problem detection*/, false, null/*use primary owner*/, null/*no progress monitor*/);
+	return null;
+}
+/**
+ * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
+ */
+public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws JavaModelException {
+	reconcile(NO_AST, forceProblemDetection? ICompilationUnit.FORCE_PROBLEM_DETECTION : 0, null/*use primary owner*/, monitor);
+}
+
+/**
+ * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
+ * @since 3.0
+ */
+public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
+		int astLevel,
+		boolean forceProblemDetection,
+		WorkingCopyOwner workingCopyOwner,
+		IProgressMonitor monitor) throws JavaModelException {
+	return reconcile(astLevel, forceProblemDetection? ICompilationUnit.FORCE_PROBLEM_DETECTION : 0, workingCopyOwner, monitor);
+}
+
+/**
+ * @see ICompilationUnit#reconcile(int, boolean, WorkingCopyOwner, IProgressMonitor)
+ * @since 3.0
+ */
+public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
+		int astLevel,
+		boolean forceProblemDetection,
+		boolean enableStatementsRecovery,
+		WorkingCopyOwner workingCopyOwner,
+		IProgressMonitor monitor) throws JavaModelException {
+	int flags = 0;
+	if (forceProblemDetection) flags |= ICompilationUnit.FORCE_PROBLEM_DETECTION;
+	if (enableStatementsRecovery) flags |= ICompilationUnit.ENABLE_STATEMENTS_RECOVERY;
+	return reconcile(astLevel, flags, workingCopyOwner, monitor);
+}
+
+public org.eclipse.jdt.core.dom.CompilationUnit reconcile(
+		int astLevel,
+		int reconcileFlags,
+		WorkingCopyOwner workingCopyOwner,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+	if (!isWorkingCopy()) return null; // Reconciling is not supported on non working copies
+	if (workingCopyOwner == null) workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
+
+
+	PerformanceStats stats = null;
+	if(ReconcileWorkingCopyOperation.PERF) {
+		stats = PerformanceStats.getStats(JavaModelManager.RECONCILE_PERF, this);
+		stats.startRun(new String(getFileName()));
+	}
+	ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, astLevel, reconcileFlags, workingCopyOwner);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	try {
+		manager.cacheZipFiles(this); // cache zip files for performance (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=134172)
+		op.runOperation(monitor);
+	} finally {
+		manager.flushZipFiles(this);
+	}
+	if(ReconcileWorkingCopyOperation.PERF) {
+		stats.endRun();
+	}
+	return op.ast;
+}
+
+/**
+ * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
+ */
+public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (newName == null) {
+		throw new IllegalArgumentException(Messages.operation_nullName);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] dests= new IJavaElement[] {getParent()};
+	String[] renamings= new String[] {newName};
+	getJavaModel().rename(elements, dests, renamings, force, monitor);
+}
+/*
+ * @see ICompilationUnit
+ */
+public void restore() throws JavaModelException {
+
+	if (!isWorkingCopy()) return;
+
+	CompilationUnit original = (CompilationUnit) getOriginalElement();
+	IBuffer buffer = getBuffer();
+	if (buffer == null) return;
+	buffer.setContents(original.getContents());
+	updateTimeStamp(original);
+	makeConsistent(null);
+}
+/**
+ * @see IOpenable
+ */
+public void save(IProgressMonitor pm, boolean force) throws JavaModelException {
+	if (isWorkingCopy()) {
+		// no need to save the buffer for a working copy (this is a noop)
+		reconcile();   // not simply makeConsistent, also computes fine-grain deltas
+								// in case the working copy is being reconciled already (if not it would miss
+								// one iteration of deltas).
+	} else {
+		super.save(pm, force);
+	}
+}
+/**
+ * Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	if (!isPrimary()) {
+		buffer.append(tabString(tab));
+		buffer.append("[Working copy] "); //$NON-NLS-1$
+		toStringName(buffer);
+	} else {
+		if (isWorkingCopy()) {
+			buffer.append(tabString(tab));
+			buffer.append("[Working copy] "); //$NON-NLS-1$
+			toStringName(buffer);
+			if (info == null) {
+				buffer.append(" (not open)"); //$NON-NLS-1$
+			}
+		} else {
+			super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		}
+	}
+}
+/*
+ * Assume that this is a working copy
+ */
+protected void updateTimeStamp(CompilationUnit original) throws JavaModelException {
+	long timeStamp =
+		((IFile) original.getResource()).getModificationStamp();
+	if (timeStamp == IResource.NULL_STAMP) {
+		throw new JavaModelException(
+			new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE));
+	}
+	((CompilationUnitElementInfo) getElementInfo()).timestamp = timeStamp;
+}
+
+protected IStatus validateExistence(IResource underlyingResource) {
+	// check if this compilation unit can be opened
+	if (!isWorkingCopy()) { // no check is done on root kind or exclusion pattern for working copies
+		IStatus status = validateCompilationUnit(underlyingResource);
+		if (!status.isOK())
+			return status;
+	}
+
+	// prevents reopening of non-primary working copies (they are closed when they are discarded and should not be reopened)
+	if (!isPrimary() && getPerWorkingCopyInfo() == null) {
+		return newDoesNotExistStatus();
+	}
+
+	return JavaModelStatus.VERIFIED_OK;
+}
+
+public ISourceRange getNameRange() {
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java
new file mode 100644
index 0000000..6229d32
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.SourceRange;
+
+public class CompilationUnitElementInfo extends OpenableElementInfo {
+
+	/**
+	 * The length of this compilation unit's source code <code>String</code>
+	 */
+	protected int sourceLength;
+
+	/**
+	 * Timestamp of original resource at the time this element
+	 * was opened or last updated.
+	 */
+	protected long timestamp;
+
+	/*
+	 * Number of annotations in this compilation unit
+	 */
+	public int annotationNumber = 0;
+
+/**
+ * Returns the length of the source string.
+ */
+public int getSourceLength() {
+	return this.sourceLength;
+}
+protected ISourceRange getSourceRange() {
+	return new SourceRange(0, this.sourceLength);
+}
+/**
+ * Sets the length of the source string.
+ */
+public void setSourceLength(int newSourceLength) {
+	this.sourceLength = newSourceLength;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java
new file mode 100644
index 0000000..9e4510e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Responsible for resolving types inside a compilation unit being reconciled,
+ * reporting the discovered problems to a given IProblemRequestor.
+ */
+public class CompilationUnitProblemFinder extends Compiler {
+
+	/**
+	 * Answer a new CompilationUnitVisitor using the given name environment and compiler options.
+	 * The environment and options will be in effect for the lifetime of the compiler.
+	 * When the compiler is run, compilation results are sent to the given requestor.
+	 *
+	 *  @param environment org.eclipse.jdt.internal.compiler.api.env.INameEnvironment
+	 *      Environment used by the compiler in order to resolve type and package
+	 *      names. The name environment implements the actual connection of the compiler
+	 *      to the outside world (e.g. in batch mode the name environment is performing
+	 *      pure file accesses, reuse previous build state or connection to repositories).
+	 *      Note: the name environment is responsible for implementing the actual classpath
+	 *            rules.
+	 *
+	 *  @param policy org.eclipse.jdt.internal.compiler.api.problem.IErrorHandlingPolicy
+	 *      Configurable part for problem handling, allowing the compiler client to
+	 *      specify the rules for handling problems (stop on first error or accumulate
+	 *      them all) and at the same time perform some actions such as opening a dialog
+	 *      in UI when compiling interactively.
+	 *      @see org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies
+	 *
+	 *	@param compilerOptions The compiler options to use for the resolution.
+	 *
+	 *  @param requestor org.eclipse.jdt.internal.compiler.api.ICompilerRequestor
+	 *      Component which will receive and persist all compilation results and is intended
+	 *      to consume them as they are produced. Typically, in a batch compiler, it is
+	 *      responsible for writing out the actual .class files to the file system.
+	 *      @see org.eclipse.jdt.internal.compiler.CompilationResult
+	 *
+	 *  @param problemFactory org.eclipse.jdt.internal.compiler.api.problem.IProblemFactory
+	 *      Factory used inside the compiler to create problem descriptors. It allows the
+	 *      compiler client to supply its own representation of compilation problems in
+	 *      order to avoid object conversions. Note that the factory is not supposed
+	 *      to accumulate the created problems, the compiler will gather them all and hand
+	 *      them back as part of the compilation unit result.
+	 */
+	protected CompilationUnitProblemFinder(
+		INameEnvironment environment,
+		IErrorHandlingPolicy policy,
+		CompilerOptions compilerOptions,
+		ICompilerRequestor requestor,
+		IProblemFactory problemFactory) {
+
+		super(environment,
+			policy,
+			compilerOptions,
+			requestor,
+			problemFactory
+		);
+	}
+
+	/**
+	 * Add additional source types
+	 */
+	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+		// ensure to jump back to toplevel type for first one (could be a member)
+		while (sourceTypes[0].getEnclosingType() != null) {
+			sourceTypes[0] = sourceTypes[0].getEnclosingType();
+		}
+
+		CompilationResult result =
+			new CompilationResult(sourceTypes[0].getFileName(), 1, 1, this.options.maxProblemsPerUnit);
+		
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259, build the compilation unit in its own sand box.
+		final long savedComplianceLevel = this.options.complianceLevel;
+		final long savedSourceLevel = this.options.sourceLevel;
+		
+		try {
+			IJavaProject project = ((SourceTypeElementInfo) sourceTypes[0]).getHandle().getJavaProject();
+			this.options.complianceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_COMPLIANCE, true));
+			this.options.sourceLevel = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_SOURCE, true));
+
+			// need to hold onto this
+			CompilationUnitDeclaration unit =
+				SourceTypeConverter.buildCompilationUnit(
+						sourceTypes,//sourceTypes[0] is always toplevel here
+						SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+						| SourceTypeConverter.MEMBER_TYPE // need member types
+						| SourceTypeConverter.FIELD_INITIALIZATION, // need field initialization
+						this.lookupEnvironment.problemReporter,
+						result);
+
+			if (unit != null) {
+				this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
+				this.lookupEnvironment.completeTypeBindings(unit);
+			}
+		} finally {
+			this.options.complianceLevel = savedComplianceLevel;
+			this.options.sourceLevel = savedSourceLevel;
+		}
+	}
+
+	protected static CompilerOptions getCompilerOptions(Map settings, boolean creatingAST, boolean statementsRecovery) {
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		compilerOptions.performMethodsFullRecovery = statementsRecovery;
+		compilerOptions.performStatementsRecovery = statementsRecovery;
+		compilerOptions.parseLiteralExpressionsAsConstants = !creatingAST; /*parse literal expressions as constants only if not creating a DOM AST*/
+		compilerOptions.storeAnnotations = creatingAST; /*store annotations in the bindings if creating a DOM AST*/
+		return compilerOptions;
+	}
+
+	/*
+	 *  Low-level API performing the actual compilation
+	 */
+	protected static IErrorHandlingPolicy getHandlingPolicy() {
+		return DefaultErrorHandlingPolicies.proceedWithAllProblems();
+	}
+
+	/*
+	 * Answer the component to which will be handed back compilation results from the compiler
+	 */
+	protected static ICompilerRequestor getRequestor() {
+		return new ICompilerRequestor() {
+			public void acceptResult(CompilationResult compilationResult) {
+				// default requestor doesn't handle compilation results back
+			}
+		};
+	}
+
+	/*
+	 * Can return null if the process was aborted or canceled 
+	 */
+	public static CompilationUnitDeclaration process(
+			CompilationUnit unitElement,
+			SourceElementParser parser,
+			WorkingCopyOwner workingCopyOwner,
+			HashMap problems,
+			boolean creatingAST,
+			int reconcileFlags,
+			IProgressMonitor monitor)
+		throws JavaModelException {
+
+		JavaProject project = (JavaProject) unitElement.getJavaProject();
+		CancelableNameEnvironment environment = null;
+		CancelableProblemFactory problemFactory = null;
+		CompilationUnitProblemFinder problemFinder = null;
+		CompilationUnitDeclaration unit = null;
+		try {
+			environment = new CancelableNameEnvironment(project, workingCopyOwner, monitor);
+			problemFactory = new CancelableProblemFactory(monitor);
+			CompilerOptions compilerOptions = getCompilerOptions(project.getOptions(true), creatingAST, ((reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0));
+			boolean ignoreMethodBodies = (reconcileFlags & ICompilationUnit.IGNORE_METHOD_BODIES) != 0;
+			compilerOptions.ignoreMethodBodies = ignoreMethodBodies;
+			problemFinder = new CompilationUnitProblemFinder(
+				environment,
+				getHandlingPolicy(),
+				compilerOptions,
+				getRequestor(),
+				problemFactory);
+			boolean analyzeAndGenerateCode = true;
+			if (ignoreMethodBodies) {
+				analyzeAndGenerateCode = false;
+			}
+			try {
+				if (parser != null) {
+					problemFinder.parser = parser;
+					unit = parser.parseCompilationUnit(unitElement, true/*full parse*/, monitor);
+					problemFinder.resolve(
+						unit,
+						unitElement,
+						true, // verify methods
+						analyzeAndGenerateCode, // analyze code
+						analyzeAndGenerateCode); // generate code
+				} else {
+					unit =
+						problemFinder.resolve(
+							unitElement,
+							true, // verify methods
+							analyzeAndGenerateCode, // analyze code
+							analyzeAndGenerateCode); // generate code
+				}
+			} catch (AbortCompilation e) {
+				problemFinder.handleInternalException(e, unit);
+			}
+			if (unit != null) {
+				CompilationResult unitResult = unit.compilationResult;
+				CategorizedProblem[] unitProblems = unitResult.getCUProblems();
+				int length = unitProblems == null ? 0 : unitProblems.length;
+				if (length > 0) {
+					CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
+					System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
+					problems.put(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, categorizedProblems);
+				}
+				unitProblems = unitResult.getTasks();
+				length = unitProblems == null ? 0 : unitProblems.length;
+				if (length > 0) {
+					CategorizedProblem[] categorizedProblems = new CategorizedProblem[length];
+					System.arraycopy(unitProblems, 0, categorizedProblems, 0, length);
+					problems.put(IJavaModelMarker.TASK_MARKER, categorizedProblems);
+				}
+				if (NameLookup.VERBOSE) {
+					System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+					System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		} catch (OperationCanceledException e) {
+			// catch this exception so as to not enter the catch(RuntimeException e) below
+			throw e;
+		} catch(RuntimeException e) {
+			// avoid breaking other tools due to internal compiler failure (40334)
+			String lineDelimiter = unitElement.findRecommendedLineSeparator();
+			StringBuffer message = new StringBuffer("Exception occurred during problem detection:");  //$NON-NLS-1$
+			message.append(lineDelimiter);
+			message.append("----------------------------------- SOURCE BEGIN -------------------------------------"); //$NON-NLS-1$
+			message.append(lineDelimiter);
+			message.append(unitElement.getSource());
+			message.append(lineDelimiter);
+			message.append("----------------------------------- SOURCE END -------------------------------------"); //$NON-NLS-1$
+			Util.log(e, message.toString());
+			throw new JavaModelException(e, IJavaModelStatusConstants.COMPILER_FAILURE);
+		} finally {
+			if (environment != null)
+				environment.setMonitor(null); // don't hold a reference to this external object
+			if (problemFactory != null)
+				problemFactory.monitor = null; // don't hold a reference to this external object
+			// NB: unit.cleanUp() is done by caller
+			if (problemFinder != null && !creatingAST)
+				problemFinder.lookupEnvironment.reset();
+		}
+		return unit;
+	}
+
+	public static CompilationUnitDeclaration process(
+			CompilationUnit unitElement,
+			WorkingCopyOwner workingCopyOwner,
+			HashMap problems,
+			boolean creatingAST,
+			int reconcileFlags,
+			IProgressMonitor monitor)
+			throws JavaModelException {
+
+		return process(unitElement, null/*use default Parser*/, workingCopyOwner, problems, creatingAST, reconcileFlags, monitor);
+	}
+
+	/* (non-Javadoc)
+	 * Fix for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=60689.
+	 * @see org.eclipse.jdt.internal.compiler.Compiler#initializeParser()
+	 */
+	public void initializeParser() {
+		this.parser = new CommentRecorderParser(this.problemReporter, this.options.parseLiteralExpressionsAsConstants);
+	}
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java
new file mode 100644
index 0000000..5a78737
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java
@@ -0,0 +1,817 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Stack;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.Literal;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * A requestor for the fuzzy parser, used to compute the children of an ICompilationUnit.
+ */
+public class CompilationUnitStructureRequestor extends ReferenceInfoAdapter implements ISourceElementRequestor {
+	
+	/**
+	 * The handle to the compilation unit being parsed
+	 */
+	protected ICompilationUnit unit;
+
+	/**
+	 * The info object for the compilation unit being parsed
+	 */
+	protected CompilationUnitElementInfo unitInfo;
+
+	/**
+	 * The import container info - null until created
+	 */
+	protected ImportContainerInfo importContainerInfo = null;
+	protected ImportContainer importContainer;
+
+	/**
+	 * Hashtable of children elements of the compilation unit.
+	 * Children are added to the table as they are found by
+	 * the parser. Keys are handles, values are corresponding
+	 * info objects.
+	 */
+	protected Map newElements;
+
+	/*
+	 * A table from a handle (with occurenceCount == 1) to the current occurence count for this handle
+	 */
+	private HashtableOfObjectToInt occurenceCounts;
+
+	/*
+	 * A table to store the occurrence count of anonymous types. The key will be the handle to the
+	 * enclosing type of the anonymous.
+	 */
+	private HashtableOfObjectToInt localOccurrenceCounts;
+
+	/**
+	 * Stack of parent scope info objects. The info on the
+	 * top of the stack is the parent of the next element found.
+	 * For example, when we locate a method, the parent info object
+	 * will be the type the method is contained in.
+	 */
+	protected Stack infoStack;
+
+	/*
+	 * Map from info to of ArrayList of IJavaElement representing the children
+	 * of the given info.
+	 */
+	protected HashMap children;
+
+	/**
+	 * Stack of parent handles, corresponding to the info stack. We
+	 * keep both, since info objects do not have back pointers to
+	 * handles.
+	 */
+	protected Stack handleStack;
+
+	/**
+	 * The number of references reported thus far. Used to
+	 * expand the arrays of reference kinds and names.
+	 */
+	protected int referenceCount= 0;
+
+	/**
+	 * Problem requestor which will get notified of discovered problems
+	 */
+	protected boolean hasSyntaxErrors = false;
+
+	/*
+	 * The parser this requestor is using.
+	 */
+	protected Parser parser;
+
+	protected HashtableOfObject fieldRefCache;
+	protected HashtableOfObject messageRefCache;
+	protected HashtableOfObject typeRefCache;
+	protected HashtableOfObject unknownRefCache;
+
+protected CompilationUnitStructureRequestor(ICompilationUnit unit, CompilationUnitElementInfo unitInfo, Map newElements) {
+	this.unit = unit;
+	this.unitInfo = unitInfo;
+	this.newElements = newElements;
+	this.occurenceCounts = new HashtableOfObjectToInt();
+	this.localOccurrenceCounts = new HashtableOfObjectToInt(5);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void acceptImport(int declarationStart, int declarationEnd, int nameSourceStart, int nameSourceEnd, char[][] tokens, boolean onDemand, int modifiers) {
+	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+	if (!(parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT)) {
+		Assert.isTrue(false); // Should not happen
+	}
+
+	ICompilationUnit parentCU= (ICompilationUnit)parentHandle;
+	//create the import container and its info
+	if (this.importContainer == null) {
+		this.importContainer = createImportContainer(parentCU);
+		this.importContainerInfo = new ImportContainerInfo();
+		Object parentInfo = this.infoStack.peek();
+		addToChildren(parentInfo, this.importContainer);
+		this.newElements.put(this.importContainer, this.importContainerInfo);
+	}
+
+	String elementName = JavaModelManager.getJavaModelManager().intern(new String(CharOperation.concatWith(tokens, '.')));
+	ImportDeclaration handle = createImportDeclaration(this.importContainer, elementName, onDemand);
+	resolveDuplicates(handle);
+
+	ImportDeclarationElementInfo info = new ImportDeclarationElementInfo();
+	info.setSourceRangeStart(declarationStart);
+	info.setSourceRangeEnd(declarationEnd);
+	info.setNameSourceStart(nameSourceStart);
+	info.setNameSourceEnd(nameSourceEnd);
+	info.setFlags(modifiers);
+
+	addToChildren(this.importContainerInfo, handle);
+	this.newElements.put(handle, info);
+}
+/*
+ * Table of line separator position. This table is passed once at the end
+ * of the parse action, so as to allow computation of normalized ranges.
+ *
+ * A line separator might corresponds to several characters in the source,
+ *
+ */
+public void acceptLineSeparatorPositions(int[] positions) {
+	// ignore line separator positions
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void acceptPackage(ImportReference importReference) {
+
+		Object parentInfo = this.infoStack.peek();
+		JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+		PackageDeclaration handle = null;
+
+		if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) {
+			char[] name = CharOperation.concatWith(importReference.getImportName(), '.');
+			handle = createPackageDeclaration(parentHandle, new String(name));
+		}
+		else {
+			Assert.isTrue(false); // Should not happen
+		}
+		resolveDuplicates(handle);
+
+		AnnotatableInfo info = new AnnotatableInfo();
+		info.setSourceRangeStart(importReference.declarationSourceStart);
+		info.setSourceRangeEnd(importReference.declarationSourceEnd);
+		info.setNameSourceStart(importReference.sourceStart);
+		info.setNameSourceEnd(importReference.sourceEnd);
+
+		addToChildren(parentInfo, handle);
+		this.newElements.put(handle, info);
+
+		if (importReference.annotations != null) {
+			for (int i = 0, length = importReference.annotations.length; i < length; i++) {
+				org.eclipse.jdt.internal.compiler.ast.Annotation annotation = importReference.annotations[i];
+				acceptAnnotation(annotation, info, handle);
+			}
+		}
+}
+public void acceptProblem(CategorizedProblem problem) {
+	if ((problem.getID() & IProblem.Syntax) != 0){
+		this.hasSyntaxErrors = true;
+	}
+}
+private void addToChildren(Object parentInfo, JavaElement handle) {
+	ArrayList childrenList = (ArrayList) this.children.get(parentInfo);
+	if (childrenList == null)
+		this.children.put(parentInfo, childrenList = new ArrayList());
+	childrenList.add(handle);
+}
+protected Annotation createAnnotation(JavaElement parent, String name) {
+	return new Annotation(parent, name);
+}
+protected SourceField createField(JavaElement parent, FieldInfo fieldInfo) {
+	String fieldName = JavaModelManager.getJavaModelManager().intern(new String(fieldInfo.name));
+	return new SourceField(parent, fieldName);
+}
+protected ImportContainer createImportContainer(ICompilationUnit parent) {
+	return (ImportContainer)parent.getImportContainer();
+}
+protected ImportDeclaration createImportDeclaration(ImportContainer parent, String name, boolean onDemand) {
+	return new ImportDeclaration(parent, name, onDemand);
+}
+protected Initializer createInitializer(JavaElement parent) {
+	return new Initializer(parent, 1);
+}
+protected SourceMethod createMethodHandle(JavaElement parent, MethodInfo methodInfo) {
+	String selector = JavaModelManager.getJavaModelManager().intern(new String(methodInfo.name));
+	String[] parameterTypeSigs = convertTypeNamesToSigs(methodInfo.parameterTypes);
+	return new SourceMethod(parent, selector, parameterTypeSigs);
+}
+protected PackageDeclaration createPackageDeclaration(JavaElement parent, String name) {
+	return new PackageDeclaration((CompilationUnit) parent, name);
+}
+protected SourceType createTypeHandle(JavaElement parent, TypeInfo typeInfo) {
+	String nameString= new String(typeInfo.name);
+	return new SourceType(parent, nameString);
+}
+protected TypeParameter createTypeParameter(JavaElement parent, String name) {
+	return new TypeParameter(parent, name);
+}
+/**
+ * Convert these type names to signatures.
+ * @see Signature
+ */
+protected static String[] convertTypeNamesToSigs(char[][] typeNames) {
+	if (typeNames == null)
+		return CharOperation.NO_STRINGS;
+	int n = typeNames.length;
+	if (n == 0)
+		return CharOperation.NO_STRINGS;
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	String[] typeSigs = new String[n];
+	for (int i = 0; i < n; ++i) {
+		typeSigs[i] = manager.intern(Signature.createTypeSignature(typeNames[i], false));
+	}
+	return typeSigs;
+}
+protected IAnnotation acceptAnnotation(org.eclipse.jdt.internal.compiler.ast.Annotation annotation, AnnotatableInfo parentInfo, JavaElement parentHandle) {
+	String nameString = new String(CharOperation.concatWith(annotation.type.getTypeName(), '.'));
+	Annotation handle = createAnnotation(parentHandle, nameString); //NB: occurenceCount is computed in resolveDuplicates
+	resolveDuplicates(handle);
+
+	AnnotationInfo info = new AnnotationInfo();
+
+	// populate the maps here as getValue(...) below may need them
+	this.newElements.put(handle, info);
+	this.handleStack.push(handle);
+
+	info.setSourceRangeStart(annotation.sourceStart());
+	info.nameStart = annotation.type.sourceStart();
+	info.nameEnd = annotation.type.sourceEnd();
+	MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+	int membersLength = memberValuePairs.length;
+	if (membersLength == 0) {
+		info.members = Annotation.NO_MEMBER_VALUE_PAIRS;
+	} else {
+		info.members = getMemberValuePairs(memberValuePairs);
+	}
+
+	if (parentInfo != null) {
+		IAnnotation[] annotations = parentInfo.annotations;
+		int length = annotations.length;
+		System.arraycopy(annotations, 0, annotations = new IAnnotation[length+1], 0, length);
+		annotations[length] = handle;
+		parentInfo.annotations = annotations;
+	}
+	info.setSourceRangeEnd(annotation.declarationSourceEnd);
+	this.handleStack.pop();
+	return handle;
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterCompilationUnit() {
+	this.infoStack = new Stack();
+	this.children = new HashMap();
+	this.handleStack= new Stack();
+	this.infoStack.push(this.unitInfo);
+	this.handleStack.push(this.unit);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterConstructor(MethodInfo methodInfo) {
+	enterMethod(methodInfo);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterField(FieldInfo fieldInfo) {
+
+	TypeInfo parentInfo = (TypeInfo) this.infoStack.peek();
+	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+	SourceField handle = null;
+	if (parentHandle.getElementType() == IJavaElement.TYPE) {
+		handle = createField(parentHandle, fieldInfo);
+	}
+	else {
+		Assert.isTrue(false); // Should not happen
+	}
+	resolveDuplicates(handle);
+
+	addToChildren(parentInfo, handle);
+	parentInfo.childrenCategories.put(handle, fieldInfo.categories);
+
+	this.infoStack.push(fieldInfo);
+	this.handleStack.push(handle);
+
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterInitializer(int declarationSourceStart, int modifiers) {
+	Object parentInfo = this.infoStack.peek();
+	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+	Initializer handle = null;
+
+	if (parentHandle.getElementType() == IJavaElement.TYPE) {
+		handle = createInitializer(parentHandle);
+	}
+	else {
+		Assert.isTrue(false); // Should not happen
+	}
+	resolveDuplicates(handle);
+	
+	addToChildren(parentInfo, handle);
+
+	this.infoStack.push(new int[] {declarationSourceStart, modifiers});
+	this.handleStack.push(handle);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterMethod(MethodInfo methodInfo) {
+
+	TypeInfo parentInfo = (TypeInfo) this.infoStack.peek();
+	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+	SourceMethod handle = null;
+
+	// translate nulls to empty arrays
+	if (methodInfo.parameterTypes == null) {
+		methodInfo.parameterTypes= CharOperation.NO_CHAR_CHAR;
+	}
+	if (methodInfo.parameterNames == null) {
+		methodInfo.parameterNames= CharOperation.NO_CHAR_CHAR;
+	}
+	if (methodInfo.exceptionTypes == null) {
+		methodInfo.exceptionTypes= CharOperation.NO_CHAR_CHAR;
+	}
+
+	if (parentHandle.getElementType() == IJavaElement.TYPE) {
+		handle = createMethodHandle(parentHandle, methodInfo);
+	}
+	else {
+		Assert.isTrue(false); // Should not happen
+	}
+	resolveDuplicates(handle);
+
+	this.infoStack.push(methodInfo);
+	this.handleStack.push(handle);
+	
+	addToChildren(parentInfo, handle);
+	parentInfo.childrenCategories.put(handle, methodInfo.categories);
+}
+private SourceMethodElementInfo createMethodInfo(MethodInfo methodInfo, SourceMethod handle) {
+	IJavaElement[] elements = getChildren(methodInfo);
+	SourceMethodElementInfo info;
+	if (methodInfo.isConstructor) {
+		info = elements.length == 0 ? new SourceConstructorInfo() : new SourceConstructorWithChildrenInfo(elements);
+	} else if (methodInfo.isAnnotation) {
+		info = new SourceAnnotationMethodInfo();
+	} else {
+		info = elements.length == 0 ? new SourceMethodInfo() : new SourceMethodWithChildrenInfo(elements);
+	}
+	info.setSourceRangeStart(methodInfo.declarationStart);
+	int flags = methodInfo.modifiers;
+	info.setNameSourceStart(methodInfo.nameSourceStart);
+	info.setNameSourceEnd(methodInfo.nameSourceEnd);
+	info.setFlags(flags);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	char[][] parameterNames = methodInfo.parameterNames;
+	for (int i = 0, length = parameterNames.length; i < length; i++)
+		parameterNames[i] = manager.intern(parameterNames[i]);
+	info.setArgumentNames(parameterNames);
+	char[] returnType = methodInfo.returnType == null ? new char[]{'v', 'o','i', 'd'} : methodInfo.returnType;
+	info.setReturnType(manager.intern(returnType));
+	char[][] exceptionTypes = methodInfo.exceptionTypes;
+	info.setExceptionTypeNames(exceptionTypes);
+	for (int i = 0, length = exceptionTypes.length; i < length; i++)
+		exceptionTypes[i] = manager.intern(exceptionTypes[i]);
+	this.newElements.put(handle, info);
+
+	if (methodInfo.typeParameters != null) {
+		for (int i = 0, length = methodInfo.typeParameters.length; i < length; i++) {
+			TypeParameterInfo typeParameterInfo = methodInfo.typeParameters[i];
+			acceptTypeParameter(typeParameterInfo, info);
+		}
+	}
+	if (methodInfo.annotations != null) {
+		int length = methodInfo.annotations.length;
+		this.unitInfo.annotationNumber += length;
+		for (int i = 0; i < length; i++) {
+			org.eclipse.jdt.internal.compiler.ast.Annotation annotation = methodInfo.annotations[i];
+			acceptAnnotation(annotation, info, handle);
+		}
+	}
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783
+	// Process the parameter annotations from the arguments
+	if (methodInfo.node != null && methodInfo.node.arguments != null) {
+		info.arguments = acceptMethodParameters(methodInfo.node.arguments, handle, methodInfo);
+	}
+	return info;
+}
+private LocalVariable[] acceptMethodParameters(Argument[] arguments, JavaElement methodHandle, MethodInfo methodInfo) {
+	if (arguments == null) return null;
+	LocalVariable[] result = new LocalVariable[arguments.length];
+	Annotation[][] paramAnnotations = new Annotation[arguments.length][];
+	for(int i = 0; i < arguments.length; i++) {
+		Argument argument = arguments[i];
+		AnnotatableInfo localVarInfo = new AnnotatableInfo();
+		localVarInfo.setSourceRangeStart(argument.declarationSourceStart);
+		localVarInfo.setSourceRangeEnd(argument.declarationSourceStart);
+		localVarInfo.setNameSourceStart(argument.sourceStart);
+		localVarInfo.setNameSourceEnd(argument.sourceEnd);
+		
+		String paramTypeSig = JavaModelManager.getJavaModelManager().intern(Signature.createTypeSignature(methodInfo.parameterTypes[i], false));
+		result[i] = new LocalVariable(
+				methodHandle,
+				new String(argument.name),
+				argument.declarationSourceStart,
+				argument.declarationSourceEnd,
+				argument.sourceStart,
+				argument.sourceEnd,
+				paramTypeSig,
+				argument.annotations,
+				argument.modifiers, 
+				true);
+		this.newElements.put(result[i], localVarInfo);
+		this.infoStack.push(localVarInfo);
+		this.handleStack.push(result[i]);
+		if (argument.annotations != null) {
+			paramAnnotations[i] = new Annotation[argument.annotations.length];
+			for (int  j = 0; j < argument.annotations.length; j++ ) {
+				org.eclipse.jdt.internal.compiler.ast.Annotation annotation = argument.annotations[j];
+				acceptAnnotation(annotation, localVarInfo, result[i]);
+			}
+		}
+		this.infoStack.pop();
+		this.handleStack.pop();
+	}
+	return result;
+}
+
+/**
+ * @see ISourceElementRequestor
+ */
+public void enterType(TypeInfo typeInfo) {
+
+	Object parentInfo = this.infoStack.peek();
+	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
+	SourceType handle = createTypeHandle(parentHandle, typeInfo); //NB: occurenceCount is computed in resolveDuplicates
+	resolveDuplicates(handle);
+
+	this.infoStack.push(typeInfo);
+	this.handleStack.push(handle);
+
+	if (parentHandle.getElementType() == IJavaElement.TYPE)
+		((TypeInfo) parentInfo).childrenCategories.put(handle, typeInfo.categories);
+	addToChildren(parentInfo, handle);
+}
+private SourceTypeElementInfo createTypeInfo(TypeInfo typeInfo, SourceType handle) {
+	SourceTypeElementInfo info =
+		typeInfo.anonymousMember ?
+			new SourceTypeElementInfo() {
+				public boolean isAnonymousMember() {
+					return true;
+				}
+			} :
+		new SourceTypeElementInfo();
+	info.setHandle(handle);
+	info.setSourceRangeStart(typeInfo.declarationStart);
+	info.setFlags(typeInfo.modifiers);
+	info.setNameSourceStart(typeInfo.nameSourceStart);
+	info.setNameSourceEnd(typeInfo.nameSourceEnd);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	char[] superclass = typeInfo.superclass;
+	info.setSuperclassName(superclass == null ? null : manager.intern(superclass));
+	char[][] superinterfaces = typeInfo.superinterfaces;
+	for (int i = 0, length = superinterfaces == null ? 0 : superinterfaces.length; i < length; i++)
+		superinterfaces[i] = manager.intern(superinterfaces[i]);
+	info.setSuperInterfaceNames(superinterfaces);
+	info.addCategories(handle, typeInfo.categories);
+	this.newElements.put(handle, info);
+
+	if (typeInfo.typeParameters != null) {
+		for (int i = 0, length = typeInfo.typeParameters.length; i < length; i++) {
+			TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
+			acceptTypeParameter(typeParameterInfo, info);
+		}
+	}
+	if (typeInfo.annotations != null) {
+		int length = typeInfo.annotations.length;
+		this.unitInfo.annotationNumber += length;
+		for (int i = 0; i < length; i++) {
+			org.eclipse.jdt.internal.compiler.ast.Annotation annotation = typeInfo.annotations[i];
+			acceptAnnotation(annotation, info, handle);
+		}
+	}
+	if (typeInfo.childrenCategories != null) {
+		Iterator iterator = typeInfo.childrenCategories.entrySet().iterator();
+		while (iterator.hasNext()) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			info.addCategories((IJavaElement) entry.getKey(), (char[][]) entry.getValue());
+		}
+		
+	}
+	return info;
+}
+protected void acceptTypeParameter(TypeParameterInfo typeParameterInfo, JavaElementInfo parentInfo) {
+	JavaElement parentHandle = (JavaElement) this.handleStack.peek();
+	String nameString = new String(typeParameterInfo.name);
+	TypeParameter handle = createTypeParameter(parentHandle, nameString); //NB: occurenceCount is computed in resolveDuplicates
+	resolveDuplicates(handle);
+
+	TypeParameterElementInfo info = new TypeParameterElementInfo();
+	info.setSourceRangeStart(typeParameterInfo.declarationStart);
+	info.nameStart = typeParameterInfo.nameSourceStart;
+	info.nameEnd = typeParameterInfo.nameSourceEnd;
+	info.bounds = typeParameterInfo.bounds;
+	if (parentInfo instanceof SourceTypeElementInfo) {
+		SourceTypeElementInfo elementInfo = (SourceTypeElementInfo) parentInfo;
+		ITypeParameter[] typeParameters = elementInfo.typeParameters;
+		int length = typeParameters.length;
+		System.arraycopy(typeParameters, 0, typeParameters = new ITypeParameter[length+1], 0, length);
+		typeParameters[length] = handle;
+		elementInfo.typeParameters = typeParameters;
+	} else {
+		SourceMethodElementInfo elementInfo = (SourceMethodElementInfo) parentInfo;
+		ITypeParameter[] typeParameters = elementInfo.typeParameters;
+		int length = typeParameters.length;
+		System.arraycopy(typeParameters, 0, typeParameters = new ITypeParameter[length+1], 0, length);
+		typeParameters[length] = handle;
+		elementInfo.typeParameters = typeParameters;
+	}
+	this.newElements.put(handle, info);
+	info.setSourceRangeEnd(typeParameterInfo.declarationEnd);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitCompilationUnit(int declarationEnd) {
+	// set import container children
+	if (this.importContainerInfo != null) {
+		this.importContainerInfo.children = getChildren(this.importContainerInfo);
+	}
+
+	this.unitInfo.children = getChildren(this.unitInfo);
+	this.unitInfo.setSourceLength(declarationEnd + 1);
+
+	// determine if there were any parsing errors
+	this.unitInfo.setIsStructureKnown(!this.hasSyntaxErrors);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitConstructor(int declarationEnd) {
+	exitMethod(declarationEnd, null);
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
+	JavaElement handle = (JavaElement) this.handleStack.peek();
+	FieldInfo fieldInfo = (FieldInfo) this.infoStack.peek();
+	IJavaElement[] elements = getChildren(fieldInfo);
+	SourceFieldElementInfo info = elements.length == 0 ? new SourceFieldElementInfo() : new SourceFieldWithChildrenInfo(elements);
+	info.setNameSourceStart(fieldInfo.nameSourceStart);
+	info.setNameSourceEnd(fieldInfo.nameSourceEnd);
+	info.setSourceRangeStart(fieldInfo.declarationStart);
+	info.setFlags(fieldInfo.modifiers);
+	char[] typeName = JavaModelManager.getJavaModelManager().intern(fieldInfo.type);
+	info.setTypeName(typeName);
+	this.newElements.put(handle, info);
+
+	if (fieldInfo.annotations != null) {
+		int length = fieldInfo.annotations.length;
+		this.unitInfo.annotationNumber += length;
+		for (int i = 0; i < length; i++) {
+			org.eclipse.jdt.internal.compiler.ast.Annotation annotation = fieldInfo.annotations[i];
+			acceptAnnotation(annotation, info, handle);
+		}
+	}
+	info.setSourceRangeEnd(declarationSourceEnd);
+	this.handleStack.pop();
+	this.infoStack.pop();
+	
+	// remember initializer source if field is a constant
+	if (initializationStart != -1) {
+		int flags = info.flags;
+		Object typeInfo;
+		if (Flags.isStatic(flags) && Flags.isFinal(flags)
+				|| ((typeInfo = this.infoStack.peek()) instanceof TypeInfo
+					 && (Flags.isInterface(((TypeInfo)typeInfo).modifiers)))) {
+			int length = declarationEnd - initializationStart;
+			if (length > 0) {
+				char[] initializer = new char[length];
+				System.arraycopy(this.parser.scanner.source, initializationStart, initializer, 0, length);
+				info.initializationSource = initializer;
+			}
+		}
+	}
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitInitializer(int declarationEnd) {
+	JavaElement handle = (JavaElement) this.handleStack.peek();
+	int[] initializerInfo = (int[]) this.infoStack.peek();
+	IJavaElement[] elements = getChildren(initializerInfo);
+	
+	InitializerElementInfo info = elements.length == 0 ? new InitializerElementInfo() : new InitializerWithChildrenInfo(elements);
+	info.setSourceRangeStart(initializerInfo[0]);
+	info.setFlags(initializerInfo[1]);
+	info.setSourceRangeEnd(declarationEnd);
+
+	this.newElements.put(handle, info);
+	
+	this.handleStack.pop();
+	this.infoStack.pop();
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitMethod(int declarationEnd, Expression defaultValue) {
+	SourceMethod handle = (SourceMethod) this.handleStack.peek();
+	MethodInfo methodInfo = (MethodInfo) this.infoStack.peek();
+	
+	SourceMethodElementInfo info = createMethodInfo(methodInfo, handle);
+	info.setSourceRangeEnd(declarationEnd);
+	
+	// remember default value of annotation method
+	if (info.isAnnotationMethod() && defaultValue != null) {
+		SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) info;
+		annotationMethodInfo.defaultValueStart = defaultValue.sourceStart;
+		annotationMethodInfo.defaultValueEnd = defaultValue.sourceEnd;
+		JavaElement element = (JavaElement) this.handleStack.peek();
+		org.eclipse.jdt.internal.core.MemberValuePair defaultMemberValuePair = new org.eclipse.jdt.internal.core.MemberValuePair(element.getElementName());
+		defaultMemberValuePair.value = getMemberValue(defaultMemberValuePair, defaultValue);
+		annotationMethodInfo.defaultValue = defaultMemberValuePair;
+	}
+	
+	this.handleStack.pop();
+	this.infoStack.pop();
+}
+/**
+ * @see ISourceElementRequestor
+ */
+public void exitType(int declarationEnd) {
+	SourceType handle = (SourceType) this.handleStack.peek();
+	TypeInfo typeInfo = (TypeInfo) this.infoStack.peek();
+	SourceTypeElementInfo info = createTypeInfo(typeInfo, handle);
+	info.setSourceRangeEnd(declarationEnd);
+	info.children = getChildren(typeInfo);
+	
+	this.handleStack.pop();
+	this.infoStack.pop();
+}
+/**
+ * Resolves duplicate handles by incrementing the occurrence count
+ * of the handle being created.
+ */
+protected void resolveDuplicates(SourceRefElement handle) {
+	int occurenceCount = this.occurenceCounts.get(handle);
+	if (occurenceCount == -1)
+		this.occurenceCounts.put(handle, 1);
+	else {
+		this.occurenceCounts.put(handle, ++occurenceCount);
+		handle.occurrenceCount = occurenceCount;
+	}
+
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=342393
+	// For anonymous source types, the occurrence count should be in the context
+	// of the enclosing type.
+	if (handle instanceof SourceType && handle.getElementName().length() == 0) {
+		Object key = handle.getParent().getAncestor(IJavaElement.TYPE);
+		occurenceCount = this.localOccurrenceCounts.get(key);
+		if (occurenceCount == -1)
+			this.localOccurrenceCounts.put(key, 1);
+		else {
+			this.localOccurrenceCounts.put(key, ++occurenceCount);
+			((SourceType)handle).localOccurrenceCount = occurenceCount;
+		}
+	}
+}
+protected IMemberValuePair getMemberValuePair(MemberValuePair memberValuePair) {
+	String memberName = new String(memberValuePair.name);
+	org.eclipse.jdt.internal.core.MemberValuePair result = new org.eclipse.jdt.internal.core.MemberValuePair(memberName);
+	result.value = getMemberValue(result, memberValuePair.value);
+	return result;
+}
+protected IMemberValuePair[] getMemberValuePairs(MemberValuePair[] memberValuePairs) {
+	int membersLength = memberValuePairs.length;
+	IMemberValuePair[] members = new IMemberValuePair[membersLength];
+	for (int j = 0; j < membersLength; j++) {
+		members[j] = getMemberValuePair(memberValuePairs[j]);
+	}
+	return members;
+}
+private IJavaElement[] getChildren(Object info) {
+	ArrayList childrenList = (ArrayList) this.children.get(info);
+	if (childrenList != null) {
+		return (IJavaElement[]) childrenList.toArray(new IJavaElement[childrenList.size()]);
+	}
+	return JavaElement.NO_ELEMENTS;
+}
+/*
+ * Creates the value from the given expression, and sets the valueKind on the given memberValuePair
+ */
+protected Object getMemberValue(org.eclipse.jdt.internal.core.MemberValuePair memberValuePair, Expression expression) {
+	if (expression instanceof NullLiteral) {
+		return null;
+	} else if (expression instanceof Literal) {
+		((Literal) expression).computeConstant();
+		return Util.getAnnotationMemberValue(memberValuePair, expression.constant);
+	} else if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
+		org.eclipse.jdt.internal.compiler.ast.Annotation annotation = (org.eclipse.jdt.internal.compiler.ast.Annotation) expression;
+		Object handle = acceptAnnotation(annotation, null, (JavaElement) this.handleStack.peek());
+		memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION;
+		return handle;
+	} else if (expression instanceof ClassLiteralAccess) {
+		ClassLiteralAccess classLiteral = (ClassLiteralAccess) expression;
+		char[] name = CharOperation.concatWith(classLiteral.type.getTypeName(), '.');
+		memberValuePair.valueKind = IMemberValuePair.K_CLASS;
+		return new String(name);
+	} else if (expression instanceof QualifiedNameReference) {
+		char[] qualifiedName = CharOperation.concatWith(((QualifiedNameReference) expression).tokens, '.');
+		memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME;
+		return new String(qualifiedName);
+	} else if (expression instanceof SingleNameReference) {
+		char[] simpleName = ((SingleNameReference) expression).token;
+		if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) {
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		}
+		memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME;
+		return new String(simpleName);
+	} else if (expression instanceof ArrayInitializer) {
+		memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...)
+		Expression[] expressions = ((ArrayInitializer) expression).expressions;
+		int length = expressions == null ? 0 : expressions.length;
+		Object[] values = new Object[length];
+		for (int i = 0; i < length; i++) {
+			int previousValueKind = memberValuePair.valueKind;
+			Object value = getMemberValue(memberValuePair, expressions[i]);
+			if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) {
+				// values are heterogeneous, value kind is thus unknown
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			}
+			values[i] = value;
+		}
+		if (memberValuePair.valueKind == -1)
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+		return values;
+	} else if (expression instanceof UnaryExpression) {			// to deal with negative numerals (see bug - 248312)
+		UnaryExpression unaryExpression = (UnaryExpression) expression;
+		if ((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.MINUS) {
+			if (unaryExpression.expression instanceof Literal) {
+				Literal subExpression = (Literal) unaryExpression.expression;
+				subExpression.computeConstant();
+				return Util.getNegativeAnnotationMemberValue(memberValuePair, subExpression.constant);
+			}
+		}
+		memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+		return null;
+	} else {
+		memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+		return null;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
new file mode 100644
index 0000000..27aa306
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation copies/moves a collection of elements from their current
+ * container to a new container, optionally renaming the
+ * elements.
+ * <p>Notes:<ul>
+ *    <li>If there is already an element with the same name in
+ *    the new container, the operation either overwrites or aborts,
+ *    depending on the collision policy setting. The default setting is
+ *	  abort.
+ *
+ *    <li>When constructors are copied to a type, the constructors
+ *    are automatically renamed to the name of the destination
+ *    type.
+ *
+ *	  <li>When main types are renamed (move within the same parent),
+ *		the compilation unit and constructors are automatically renamed
+ *
+ *    <li>The collection of elements being copied must all share the
+ *    same type of container (for example, must all be type members).
+ *
+ *    <li>The elements are inserted in the new container in the order given.
+ *
+ *    <li>The elements can be positioned in the new container - see #setInsertBefore.
+ *    By default, the elements are inserted based on the default positions as specified in
+ * 	the creation operation for that element type.
+ *
+ *    <li>This operation can be used to copy and rename elements within
+ *    the same container.
+ *
+ *    <li>This operation only copies elements contained within compilation units.
+ * </ul>
+ *
+ */
+public class CopyElementsOperation extends MultiOperation implements SuffixConstants {
+
+
+	private Map sources = new HashMap();
+/**
+ * When executed, this operation will copy the given elements to the
+ * given containers.  The elements and destination containers must be in
+ * the correct order. If there is > 1 destination, the number of destinations
+ * must be the same as the number of elements being copied/moved/renamed.
+ */
+public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement[] destContainers, boolean force) {
+	super(elementsToCopy, destContainers, force);
+}
+/**
+ * When executed, this operation will copy the given elements to the
+ * given container.
+ */
+public CopyElementsOperation(IJavaElement[] elementsToCopy, IJavaElement destContainer, boolean force) {
+	this(elementsToCopy, new IJavaElement[]{destContainer}, force);
+}
+/**
+ * Returns the <code>String</code> to use as the main task name
+ * for progress monitoring.
+ */
+protected String getMainTaskName() {
+	return Messages.operation_copyElementProgress;
+}
+/**
+ * Returns the nested operation to use for processing this element
+ */
+protected JavaModelOperation getNestedOperation(IJavaElement element) {
+	try {
+		IJavaElement dest = getDestinationParent(element);
+		switch (element.getElementType()) {
+			case IJavaElement.PACKAGE_DECLARATION :
+				return new CreatePackageDeclarationOperation(element.getElementName(), (ICompilationUnit) dest);
+			case IJavaElement.IMPORT_DECLARATION :
+				IImportDeclaration importDeclaration = (IImportDeclaration) element;
+				return new CreateImportOperation(element.getElementName(), (ICompilationUnit) dest, importDeclaration.getFlags());
+			case IJavaElement.TYPE :
+				if (isRenamingMainType(element, dest)) {
+					IPath path = element.getPath();
+					String extension = path.getFileExtension();
+					return new RenameResourceElementsOperation(new IJavaElement[] {dest}, new IJavaElement[] {dest.getParent()}, new String[]{getNewNameFor(element) + '.' + extension}, this.force);
+				} else {
+					String source = getSourceFor(element);
+					String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+					return new CreateTypeOperation(dest, source + lineSeparator, this.force);
+				}
+			case IJavaElement.METHOD :
+				String source = getSourceFor(element);
+				String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+				return new CreateMethodOperation((IType) dest, source + lineSeparator, this.force);
+			case IJavaElement.FIELD :
+				source = getSourceFor(element);
+				lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+				return new CreateFieldOperation((IType) dest, source + lineSeparator, this.force);
+			case IJavaElement.INITIALIZER :
+				source = getSourceFor(element);
+				lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+				return new CreateInitializerOperation((IType) dest, source + lineSeparator);
+			default :
+				return null;
+		}
+	} catch (JavaModelException npe) {
+		return null;
+	}
+}
+/**
+ * Returns the cached source for this element or compute it if not already cached.
+ */
+private String getSourceFor(IJavaElement element) throws JavaModelException {
+	String source = (String) this.sources.get(element);
+	if (source == null && element instanceof IMember) {
+		source = ((IMember)element).getSource();
+		this.sources.put(element, source);
+	}
+	return source;
+}
+/**
+ * Returns <code>true</code> if this element is the main type of its compilation unit.
+ */
+protected boolean isRenamingMainType(IJavaElement element, IJavaElement dest) throws JavaModelException {
+	if ((isRename() || getNewNameFor(element) != null)
+		&& dest.getElementType() == IJavaElement.COMPILATION_UNIT) {
+		String typeName = dest.getElementName();
+		typeName = org.eclipse.jdt.internal.core.util.Util.getNameWithoutJavaLikeExtension(typeName);
+		return element.getElementName().equals(typeName) && element.getParent().equals(dest);
+	}
+	return false;
+}
+/**
+ * Copy/move the element from the source to destination, renaming
+ * the elements as specified, honoring the collision policy.
+ *
+ * @exception JavaModelException if the operation is unable to
+ * be completed
+ */
+protected void processElement(IJavaElement element) throws JavaModelException {
+	JavaModelOperation op = getNestedOperation(element);
+	boolean createElementInCUOperation =op instanceof CreateElementInCUOperation;
+	if (op == null) {
+		return;
+	}
+	if (createElementInCUOperation) {
+		IJavaElement sibling = (IJavaElement) this.insertBeforeElements.get(element);
+		if (sibling != null) {
+			((CreateElementInCUOperation) op).setRelativePosition(sibling, CreateElementInCUOperation.INSERT_BEFORE);
+		} else
+			if (isRename()) {
+				IJavaElement anchor = resolveRenameAnchor(element);
+				if (anchor != null) {
+					((CreateElementInCUOperation) op).setRelativePosition(anchor, CreateElementInCUOperation.INSERT_AFTER); // insert after so that the anchor is found before when deleted below
+				}
+			}
+		String newName = getNewNameFor(element);
+		if (newName != null) {
+			((CreateElementInCUOperation) op).setAlteredName(newName);
+		}
+	}
+	executeNestedOperation(op, 1);
+
+	JavaElement destination = (JavaElement) getDestinationParent(element);
+	ICompilationUnit unit= destination.getCompilationUnit();
+	if (!unit.isWorkingCopy()) {
+		unit.close();
+	}
+
+	if (createElementInCUOperation && isMove() && !isRenamingMainType(element, destination)) {
+		JavaModelOperation deleteOp = new DeleteElementsOperation(new IJavaElement[] { element }, this.force);
+		executeNestedOperation(deleteOp, 1);
+	}
+}
+/**
+ * Returns the anchor used for positioning in the destination for
+ * the element being renamed. For renaming, if no anchor has
+ * explicitly been provided, the element is anchored in the same position.
+ */
+private IJavaElement resolveRenameAnchor(IJavaElement element) throws JavaModelException {
+	IParent parent = (IParent) element.getParent();
+	IJavaElement[] children = parent.getChildren();
+	for (int i = 0; i < children.length; i++) {
+		IJavaElement child = children[i];
+		if (child.equals(element)) {
+			return child;
+		}
+	}
+	return null;
+}
+/**
+ * Possible failures:
+ * <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation
+ *	<li>INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the operation
+ *		does not match the number of elements that were supplied.
+ * </ul>
+ */
+protected IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (!status.isOK()) {
+		return status;
+	}
+	if (this.renamingsList != null && this.renamingsList.length != this.elementsToProcess.length) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS);
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+/**
+ * @see MultiOperation
+ *
+ * Possible failure codes:
+ * <ul>
+ *
+ *	<li>ELEMENT_DOES_NOT_EXIST - <code>element</code> or its specified destination is
+ *		is <code>null</code> or does not exist. If a <code>null</code> element is
+ *		supplied, no element is provided in the status, otherwise, the non-existant element
+ *		is supplied in the status.
+ *	<li>INVALID_ELEMENT_TYPES - <code>element</code> is not contained within a compilation unit.
+ *		This operation only operates on elements contained within compilation units.
+ *  <li>READ_ONLY - <code>element</code> is read only.
+ *	<li>INVALID_DESTINATION - The destination parent specified for <code>element</code>
+ *		is of an incompatible type. The destination for a package declaration or import declaration must
+ *		be a compilation unit; the destination for a type must be a type or compilation
+ *		unit; the destination for any type member (other than a type) must be a type. When
+ *		this error occurs, the element provided in the operation status is the <code>element</code>.
+ *	<li>INVALID_NAME - the new name for <code>element</code> does not have valid syntax.
+ *      In this case the element and name are provided in the status.
+
+ * </ul>
+ */
+protected void verify(IJavaElement element) throws JavaModelException {
+	if (element == null || !element.exists())
+		error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
+
+	if (element.getElementType() < IJavaElement.TYPE)
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+
+	if (element.isReadOnly())
+		error(IJavaModelStatusConstants.READ_ONLY, element);
+
+	IJavaElement dest = getDestinationParent(element);
+	verifyDestination(element, dest);
+	verifySibling(element, dest);
+	if (this.renamingsList != null) {
+		verifyRenaming(element);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java
new file mode 100644
index 0000000..185a303
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java
@@ -0,0 +1,261 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+public class CopyPackageFragmentRootOperation extends JavaModelOperation {
+	IPath destination;
+	int updateResourceFlags;
+	int updateModelFlags;
+	IClasspathEntry sibling;
+
+	public CopyPackageFragmentRootOperation(
+		IPackageFragmentRoot root,
+		IPath destination,
+		int updateResourceFlags,
+		int updateModelFlags,
+		IClasspathEntry sibling) {
+
+		super(root);
+		this.destination = destination;
+		this.updateResourceFlags = updateResourceFlags;
+		this.updateModelFlags = updateModelFlags;
+		this.sibling = sibling;
+	}
+	protected void executeOperation() throws JavaModelException {
+
+		IPackageFragmentRoot root = (IPackageFragmentRoot)getElementToProcess();
+		IClasspathEntry rootEntry = root.getRawClasspathEntry();
+		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+		// copy resource
+		if (!root.isExternal() && (this.updateModelFlags & IPackageFragmentRoot.NO_RESOURCE_MODIFICATION) == 0) {
+			copyResource(root, rootEntry, workspaceRoot);
+		}
+
+		// update classpath if needed
+		if ((this.updateModelFlags & IPackageFragmentRoot.DESTINATION_PROJECT_CLASSPATH) != 0) {
+			addEntryToClasspath(rootEntry, workspaceRoot);
+		}
+	}
+	protected void copyResource(
+		IPackageFragmentRoot root,
+		IClasspathEntry rootEntry,
+		final IWorkspaceRoot workspaceRoot)
+		throws JavaModelException {
+		final char[][] exclusionPatterns = ((ClasspathEntry)rootEntry).fullExclusionPatternChars();
+		IResource rootResource = ((JavaElement) root).resource();
+		if (root.getKind() == IPackageFragmentRoot.K_BINARY || exclusionPatterns == null) {
+			try {
+				IResource destRes;
+				if ((this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0) {
+					if (rootEntry.getPath().equals(this.destination)) return;
+					if ((destRes = workspaceRoot.findMember(this.destination)) != null) {
+						destRes.delete(this.updateResourceFlags, this.progressMonitor);
+					}
+				}
+				rootResource.copy(this.destination, this.updateResourceFlags, this.progressMonitor);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		} else {
+			final int sourceSegmentCount = rootEntry.getPath().segmentCount();
+			final IFolder destFolder = workspaceRoot.getFolder(this.destination);
+			final IPath[] nestedFolders = getNestedFolders(root);
+			IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+				public boolean visit(IResourceProxy proxy) throws CoreException {
+					if (proxy.getType() == IResource.FOLDER) {
+						IPath path = proxy.requestFullPath();
+						if (prefixesOneOf(path, nestedFolders)) {
+							if (equalsOneOf(path, nestedFolders)) {
+								// nested source folder
+								return false;
+							} else {
+								// folder containing nested source folder
+								IFolder folder = destFolder.getFolder(path.removeFirstSegments(sourceSegmentCount));
+								if ((CopyPackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+										&& folder.exists()) {
+									return true;
+								}
+								folder.create(CopyPackageFragmentRootOperation.this.updateResourceFlags, true, CopyPackageFragmentRootOperation.this.progressMonitor);
+								return true;
+							}
+						} else {
+							// subtree doesn't contain any nested source folders
+							IPath destPath = CopyPackageFragmentRootOperation.this.destination.append(path.removeFirstSegments(sourceSegmentCount));
+							IResource destRes;
+							if ((CopyPackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+									&& (destRes = workspaceRoot.findMember(destPath)) != null) {
+								destRes.delete(CopyPackageFragmentRootOperation.this.updateResourceFlags, CopyPackageFragmentRootOperation.this.progressMonitor);
+							}
+							proxy.requestResource().copy(destPath, CopyPackageFragmentRootOperation.this.updateResourceFlags, CopyPackageFragmentRootOperation.this.progressMonitor);
+							return false;
+						}
+					} else {
+						IPath path = proxy.requestFullPath();
+						IPath destPath = CopyPackageFragmentRootOperation.this.destination.append(path.removeFirstSegments(sourceSegmentCount));
+						IResource destRes;
+						if ((CopyPackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+								&& (destRes = workspaceRoot.findMember(destPath)) != null) {
+							destRes.delete(CopyPackageFragmentRootOperation.this.updateResourceFlags, CopyPackageFragmentRootOperation.this.progressMonitor);
+						}
+						proxy.requestResource().copy(destPath, CopyPackageFragmentRootOperation.this.updateResourceFlags, CopyPackageFragmentRootOperation.this.progressMonitor);
+						return false;
+					}
+				}
+			};
+			try {
+				rootResource.accept(visitor, IResource.NONE);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		}
+		setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+	}
+	protected void addEntryToClasspath(IClasspathEntry rootEntry, IWorkspaceRoot workspaceRoot) throws JavaModelException {
+
+		IProject destProject = workspaceRoot.getProject(this.destination.segment(0));
+		IJavaProject jProject = JavaCore.create(destProject);
+		IClasspathEntry[] classpath = jProject.getRawClasspath();
+		int length = classpath.length;
+		IClasspathEntry[] newClasspath;
+
+		// case of existing entry and REPLACE was specified
+		if ((this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0) {
+			// find existing entry
+			for (int i = 0; i < length; i++) {
+				if (this.destination.equals(classpath[i].getPath())) {
+					newClasspath = new IClasspathEntry[length];
+					System.arraycopy(classpath, 0, newClasspath, 0, length);
+					newClasspath[i] = copy(rootEntry);
+					jProject.setRawClasspath(newClasspath, this.progressMonitor);
+					return;
+				}
+			}
+		}
+
+		// other cases
+		int position;
+		if (this.sibling == null) {
+			// insert at the end
+			position = length;
+		} else {
+			// insert before sibling
+			position = -1;
+			for (int i = 0; i < length; i++) {
+				if (this.sibling.equals(classpath[i])) {
+					position = i;
+					break;
+				}
+			}
+		}
+		if (position == -1) {
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, this.sibling.toString()));
+		}
+		newClasspath = new IClasspathEntry[length+1];
+		if (position != 0) {
+			System.arraycopy(classpath, 0, newClasspath, 0, position);
+		}
+		if (position != length) {
+			System.arraycopy(classpath, position, newClasspath, position+1, length-position);
+		}
+		IClasspathEntry newEntry = copy(rootEntry);
+		newClasspath[position] = newEntry;
+		jProject.setRawClasspath(newClasspath, this.progressMonitor);
+	}
+	/*
+	 * Copies the given classpath entry replacing its path with the destination path
+	 * if it is a source folder or a library.
+	 */
+	protected IClasspathEntry copy(IClasspathEntry entry) throws JavaModelException {
+		switch (entry.getEntryKind()) {
+			case IClasspathEntry.CPE_CONTAINER:
+				return JavaCore.newContainerEntry(entry.getPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
+			case IClasspathEntry.CPE_LIBRARY:
+				try {
+					return JavaCore.newLibraryEntry(this.destination, entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
+				} catch (ClasspathEntry.AssertionFailedException e) {
+					IJavaModelStatus status = new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
+					throw new JavaModelException(status);
+				}
+			case IClasspathEntry.CPE_PROJECT:
+				return JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(), entry.getExtraAttributes(), entry.isExported());
+			case IClasspathEntry.CPE_SOURCE:
+				return JavaCore.newSourceEntry(this.destination, entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.getOutputLocation(), entry.getExtraAttributes());
+			case IClasspathEntry.CPE_VARIABLE:
+				try {
+					return JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
+				} catch (ClasspathEntry.AssertionFailedException e) {
+					IJavaModelStatus status = new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
+					throw new JavaModelException(status);
+				}
+			default:
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, getElementToProcess()));
+		}
+	}
+	public IJavaModelStatus verify() {
+		IJavaModelStatus status = super.verify();
+		if (!status.isOK()) {
+			return status;
+		}
+		PackageFragmentRoot root = (PackageFragmentRoot)getElementToProcess();
+		if (root == null || !root.exists()) {
+			return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, root);
+		}
+
+		IResource resource = root.resource();
+		if (resource instanceof IFolder) {
+			if (resource.isLinked()) {
+				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE, root);
+			}
+		}
+
+		if ((this.updateModelFlags & IPackageFragmentRoot.DESTINATION_PROJECT_CLASSPATH) != 0) {
+			String destProjectName = this.destination.segment(0);
+			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(destProjectName);
+			if (JavaProject.hasJavaNature(project)) {
+				try {
+					IJavaProject destProject = JavaCore.create(project);
+					IClasspathEntry[] destClasspath = destProject.getRawClasspath();
+					boolean foundSibling = false;
+					boolean foundExistingEntry = false;
+					for (int i = 0, length = destClasspath.length; i < length; i++) {
+						IClasspathEntry entry = destClasspath[i];
+						if (entry.equals(this.sibling)) {
+							foundSibling = true;
+							break;
+						}
+						if (entry.getPath().equals(this.destination)) {
+							foundExistingEntry = true;
+						}
+					}
+					if (this.sibling != null && !foundSibling) {
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, this.sibling.toString());
+					}
+					if (foundExistingEntry && (this.updateModelFlags & IPackageFragmentRoot.REPLACE) == 0) {
+						return new JavaModelStatus(
+							IJavaModelStatusConstants.NAME_COLLISION,
+							Messages.bind(Messages.status_nameCollision, new String[] {this.destination.toString()}));
+					}
+				} catch (JavaModelException e) {
+					return e.getJavaModelStatus();
+				}
+			}
+		}
+
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
new file mode 100644
index 0000000..409a1d4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
@@ -0,0 +1,791 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Javadoc;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This operation copies/moves/renames a collection of resources from their current
+ * container to a new container, optionally renaming the
+ * elements.
+ * <p>Notes:<ul>
+ *    <li>If there is already an resource with the same name in
+ *    the new container, the operation either overwrites or aborts,
+ *    depending on the collision policy setting. The default setting is
+ *	  abort.
+ *
+ *    <li>When a compilation unit is copied to a new package, the
+ *    package declaration in the compilation unit is automatically updated.
+ *
+ *    <li>The collection of elements being copied must all share the
+ *    same type of container.
+ *
+ *    <li>This operation can be used to copy and rename elements within
+ *    the same container.
+ *
+ *    <li>This operation only copies compilation units and package fragments.
+ *    It does not copy package fragment roots - a platform operation must be used for that.
+ * </ul>
+ *
+ */
+public class CopyResourceElementsOperation extends MultiOperation implements SuffixConstants {
+	/**
+	 * The list of new resources created during this operation.
+	 */
+	protected ArrayList createdElements;
+	/**
+	 * Table specifying deltas for elements being
+	 * copied/moved/renamed. Keyed by elements' project(s), and
+	 * values are the corresponding deltas.
+	 */
+	protected Map deltasPerProject = new HashMap(1);
+	/**
+	 * The <code>ASTParser</code> used to manipulate the source code of
+	 * <code>ICompilationUnit</code>.
+	 */
+	protected ASTParser parser;
+	/**
+	 * When executed, this operation will copy the given resources to the
+	 * given containers.  The resources and destination containers must be in
+	 * the correct order. If there is > 1 destination, the number of destinations
+	 * must be the same as the number of resources being copied/moved.
+	 */
+	public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement[] destContainers, boolean force) {
+		super(resourcesToCopy, destContainers, force);
+		initializeASTParser();
+	}
+	private void initializeASTParser() {
+		this.parser = ASTParser.newParser(AST.JLS8);
+	}
+	/**
+	 * Returns the children of <code>source</code> which are affected by this operation.
+	 * If <code>source</code> is a <code>K_SOURCE</code>, these are the <code>.java</code>
+	 * files, if it is a <code>K_BINARY</code>, they are the <code>.class</code> files.
+	 */
+	private IResource[] collectResourcesOfInterest(IPackageFragment source) throws JavaModelException {
+		IJavaElement[] children = source.getChildren();
+		int childOfInterest = IJavaElement.COMPILATION_UNIT;
+		if (source.getKind() == IPackageFragmentRoot.K_BINARY) {
+			childOfInterest = IJavaElement.CLASS_FILE;
+		}
+		ArrayList correctKindChildren = new ArrayList(children.length);
+		for (int i = 0; i < children.length; i++) {
+			IJavaElement child = children[i];
+			if (child.getElementType() == childOfInterest) {
+				correctKindChildren.add(((JavaElement) child).resource());
+			}
+		}
+		// Gather non-java resources
+		Object[] nonJavaResources = source.getNonJavaResources();
+		int actualNonJavaResourceCount = 0;
+		for (int i = 0, max = nonJavaResources.length; i < max; i++){
+			if (nonJavaResources[i] instanceof IResource) actualNonJavaResourceCount++;
+		}
+		IResource[] actualNonJavaResources = new IResource[actualNonJavaResourceCount];
+		for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++){
+			if (nonJavaResources[i] instanceof IResource) actualNonJavaResources[index++] = (IResource)nonJavaResources[i];
+		}
+
+		if (actualNonJavaResourceCount != 0) {
+			int correctKindChildrenSize = correctKindChildren.size();
+			IResource[] result = new IResource[correctKindChildrenSize + actualNonJavaResourceCount];
+			correctKindChildren.toArray(result);
+			System.arraycopy(actualNonJavaResources, 0, result, correctKindChildrenSize, actualNonJavaResourceCount);
+			return result;
+		} else {
+			IResource[] result = new IResource[correctKindChildren.size()];
+			correctKindChildren.toArray(result);
+			return result;
+		}
+	}
+	/**
+	 * Creates any destination package fragment(s) which do not exists yet.
+	 * Return true if a read-only package fragment has been found among package fragments, false otherwise
+	 */
+	private boolean createNeededPackageFragments(IContainer sourceFolder, PackageFragmentRoot root, String[] newFragName, boolean moveFolder) throws JavaModelException {
+		boolean containsReadOnlyPackageFragment = false;
+		IContainer parentFolder = (IContainer) root.resource();
+		JavaElementDelta projectDelta = null;
+		String[] sideEffectPackageName = null;
+		char[][] inclusionPatterns = root.fullInclusionPatternChars();
+		char[][] exclusionPatterns = root.fullExclusionPatternChars();
+		for (int i = 0; i < newFragName.length; i++) {
+			String subFolderName = newFragName[i];
+			sideEffectPackageName = Util.arrayConcat(sideEffectPackageName, subFolderName);
+			IResource subFolder = parentFolder.findMember(subFolderName);
+			if (subFolder == null) {
+				// create deepest folder only if not a move (folder will be moved in processPackageFragmentResource)
+				if (!(moveFolder && i == newFragName.length-1)) {
+					createFolder(parentFolder, subFolderName, this.force);
+				}
+				parentFolder = parentFolder.getFolder(new Path(subFolderName));
+				sourceFolder = sourceFolder.getFolder(new Path(subFolderName));
+				if (Util.isReadOnly(sourceFolder)) {
+					containsReadOnlyPackageFragment = true;
+				}
+				IPackageFragment sideEffectPackage = root.getPackageFragment(sideEffectPackageName);
+				if (i < newFragName.length - 1 // all but the last one are side effect packages
+						&& !Util.isExcluded(parentFolder, inclusionPatterns, exclusionPatterns)) {
+					if (projectDelta == null) {
+						projectDelta = getDeltaFor(root.getJavaProject());
+					}
+					projectDelta.added(sideEffectPackage);
+				}
+				this.createdElements.add(sideEffectPackage);
+			} else {
+				parentFolder = (IContainer) subFolder;
+			}
+		}
+		return containsReadOnlyPackageFragment;
+	}
+
+	/**
+	 * Returns the <code>JavaElementDelta</code> for <code>javaProject</code>,
+	 * creating it and putting it in <code>fDeltasPerProject</code> if
+	 * it does not exist yet.
+	 */
+	private JavaElementDelta getDeltaFor(IJavaProject javaProject) {
+		JavaElementDelta delta = (JavaElementDelta) this.deltasPerProject.get(javaProject);
+		if (delta == null) {
+			delta = new JavaElementDelta(javaProject);
+			this.deltasPerProject.put(javaProject, delta);
+		}
+		return delta;
+	}
+	/**
+	 * @see MultiOperation
+	 */
+	protected String getMainTaskName() {
+		return Messages.operation_copyResourceProgress;
+	}
+	protected ISchedulingRule getSchedulingRule() {
+		if (this.elementsToProcess == null)
+			return null;
+		int length = this.elementsToProcess.length;
+		if (length == 1)
+			return getSchedulingRule(this.elementsToProcess[0]);
+		ISchedulingRule[] rules = new ISchedulingRule[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			ISchedulingRule rule = getSchedulingRule(this.elementsToProcess[i]);
+			if (rule != null) {
+				rules[index++] = rule;
+			}
+		}
+		if (index != length)
+			System.arraycopy(rules, 0, rules = new ISchedulingRule[index], 0, index);
+		return new MultiRule(rules);
+	}
+	private ISchedulingRule getSchedulingRule(IJavaElement element) {
+		if (element == null)
+			return null;
+		IResource sourceResource = getResource(element);
+		IResource destContainer = getResource(getDestinationParent(element));
+		if (!(destContainer instanceof IContainer)) {
+			return null;
+		}
+		String newName;
+		try {
+			newName = getNewNameFor(element);
+		} catch (JavaModelException e) {
+			return null;
+		}
+		if (newName == null)
+			newName = element.getElementName();
+		IResource destResource;
+		String sourceEncoding = null;
+		if (sourceResource.getType() == IResource.FILE) {
+			destResource = ((IContainer) destContainer).getFile(new Path(newName));
+			try {
+				sourceEncoding = ((IFile) sourceResource).getCharset(false);
+			} catch (CoreException ce) {
+				// use default encoding
+			}
+		} else {
+			destResource = ((IContainer) destContainer).getFolder(new Path(newName));
+		}
+		IResourceRuleFactory factory = ResourcesPlugin.getWorkspace().getRuleFactory();
+		ISchedulingRule rule;
+		if (isMove()) {
+			rule = factory.moveRule(sourceResource, destResource);
+		} else {
+			rule = factory.copyRule(sourceResource, destResource);
+		}
+		if (sourceEncoding != null) {
+			rule = new MultiRule(new ISchedulingRule[] {rule, factory.charsetRule(destResource)});
+		}
+		return rule;
+	}
+	private IResource getResource(IJavaElement element) {
+		if (element == null)
+			return null;
+		if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+			String pkgName = element.getElementName();
+			int firstDot = pkgName.indexOf('.');
+			if (firstDot != -1) {
+				element = ((IPackageFragmentRoot) element.getParent()).getPackageFragment(pkgName.substring(0, firstDot));
+			}
+		}
+		return element.getResource();
+	}
+	/**
+	 * Sets the deltas to register the changes resulting from this operation
+	 * for this source element and its destination.
+	 * If the operation is a cross project operation<ul>
+	 * <li>On a copy, the delta should be rooted in the dest project
+	 * <li>On a move, two deltas are generated<ul>
+	 * 			<li>one rooted in the source project
+	 *			<li>one rooted in the destination project
+	 * <li> When a CU is being overwritten, the delta on the destination will be of type F_CONTENT </ul></ul>
+	 * If the operation is rooted in a single project, the delta is rooted in that project
+	 *
+	 */
+	protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove, boolean overWriteCU) {
+		if (Util.isExcluded(sourceElement) || Util.isExcluded(destinationElement)) return;
+		
+		IJavaProject destProject = destinationElement.getJavaProject();
+		if (isMove) {
+			IJavaProject sourceProject = sourceElement.getJavaProject();
+			getDeltaFor(sourceProject).movedFrom(sourceElement, destinationElement);
+			if (!overWriteCU) {
+				getDeltaFor(destProject).movedTo(destinationElement, sourceElement);
+				return;
+			}
+		} else {
+			if (!overWriteCU) {
+				getDeltaFor(destProject).added(destinationElement);
+				return;
+			}
+		}
+		getDeltaFor(destinationElement.getJavaProject()).changed(destinationElement, IJavaElementDelta.F_CONTENT);
+	}
+	/**
+	 * Copies/moves a compilation unit with the name <code>newCUName</code>
+	 * to the destination package.<br>
+	 * The package statement in the compilation unit is updated if necessary.
+	 * The main type of the compilation unit is renamed if necessary.
+	 *
+	 * @exception JavaModelException if the operation is unable to
+	 * complete
+	 */
+	private void processCompilationUnitResource(ICompilationUnit source, PackageFragment dest) throws JavaModelException {
+		String newCUName = getNewNameFor(source);
+		String destName = (newCUName != null) ? newCUName : source.getElementName();
+		TextEdit edit = updateContent(source, dest, newCUName); // null if unchanged
+
+		// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
+		// store encoding (fix bug 66898)
+		IFile sourceResource = (IFile)source.getResource();
+		String sourceEncoding = null;
+		try {
+			sourceEncoding = sourceResource.getCharset(false);
+		}
+		catch (CoreException ce) {
+			// no problem, use default encoding
+		}
+		// end todo
+		// copy resource
+		IContainer destFolder = (IContainer)dest.getResource(); // can be an IFolder or an IProject
+		IFile destFile = destFolder.getFile(new Path(destName));
+		org.eclipse.jdt.internal.core.CompilationUnit destCU = new org.eclipse.jdt.internal.core.CompilationUnit(dest, destName, DefaultWorkingCopyOwner.PRIMARY);
+		if (!destFile.equals(sourceResource)) {
+			try {
+				if (!destCU.isWorkingCopy()) {
+					if (destFile.exists()) {
+						if (this.force) {
+							// we can remove it
+							deleteResource(destFile, IResource.KEEP_HISTORY);
+							destCU.close(); // ensure the in-memory buffer for the dest CU is closed
+						} else {
+							// abort
+							throw new JavaModelException(new JavaModelStatus(
+								IJavaModelStatusConstants.NAME_COLLISION,
+								Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString())));
+						}
+					}
+					int flags = this.force ? IResource.FORCE : IResource.NONE;
+					if (isMove()) {
+						flags |= IResource.KEEP_HISTORY;
+						sourceResource.move(destFile.getFullPath(), flags, getSubProgressMonitor(1));
+					} else {
+						if (edit != null) flags |= IResource.KEEP_HISTORY;
+						sourceResource.copy(destFile.getFullPath(), flags, getSubProgressMonitor(1));
+					}
+					setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+				} else {
+					destCU.getBuffer().setContents(source.getBuffer().getContents());
+				}
+			} catch (JavaModelException e) {
+				throw e;
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+
+			// update new resource content
+			if (edit != null){
+				boolean wasReadOnly = destFile.isReadOnly();
+				try {
+					saveContent(dest, destName, edit, sourceEncoding, destFile);
+				} catch (CoreException e) {
+					if (e instanceof JavaModelException) throw (JavaModelException) e;
+					throw new JavaModelException(e);
+				} finally {
+					Util.setReadOnly(destFile, wasReadOnly);
+				}
+			}
+
+			// register the correct change deltas
+			boolean contentChanged = this.force && destFile.exists();
+			prepareDeltas(source, destCU, isMove(), contentChanged);
+			
+			if (newCUName != null) {
+				//the main type has been renamed
+				String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName());
+				String newName = Util.getNameWithoutJavaLikeExtension(newCUName);
+				prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove(), false);
+			}
+		} else {
+			if (!this.force) {
+				throw new JavaModelException(new JavaModelStatus(
+					IJavaModelStatusConstants.NAME_COLLISION,
+					Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString())));
+			}
+			// update new resource content
+			// in case we do a saveas on the same resource we have to simply update the contents
+			// see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
+			if (edit != null){
+				saveContent(dest, destName, edit, sourceEncoding, destFile);
+			}
+		}
+	}
+	/**
+	 * Process all of the changed deltas generated by this operation.
+	 */
+	protected void processDeltas() {
+		for (Iterator deltas = this.deltasPerProject.values().iterator(); deltas.hasNext();){
+			addDelta((IJavaElementDelta) deltas.next());
+		}
+	}
+	/**
+	 * @see MultiOperation
+	 * This method delegates to <code>processCompilationUnitResource</code> or
+	 * <code>processPackageFragmentResource</code>, depending on the type of
+	 * <code>element</code>.
+	 */
+	protected void processElement(IJavaElement element) throws JavaModelException {
+		IJavaElement dest = getDestinationParent(element);
+		switch (element.getElementType()) {
+			case IJavaElement.COMPILATION_UNIT :
+				processCompilationUnitResource((ICompilationUnit) element, (PackageFragment) dest);
+				this.createdElements.add(((IPackageFragment) dest).getCompilationUnit(element.getElementName()));
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT :
+				processPackageFragmentResource((PackageFragment) element, (PackageFragmentRoot) dest, getNewNameFor(element));
+				break;
+			default :
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element));
+		}
+	}
+	/**
+	 * @see MultiOperation
+	 * Overridden to allow special processing of <code>JavaElementDelta</code>s
+	 * and <code>fResultElements</code>.
+	 */
+	protected void processElements() throws JavaModelException {
+		this.createdElements = new ArrayList(this.elementsToProcess.length);
+		try {
+			super.processElements();
+		} catch (JavaModelException jme) {
+			throw jme;
+		} finally {
+			this.resultElements = new IJavaElement[this.createdElements.size()];
+			this.createdElements.toArray(this.resultElements);
+			processDeltas();
+		}
+	}
+	/**
+	 * Copies/moves a package fragment with the name <code>newName</code>
+	 * to the destination package.<br>
+	 *
+	 * @exception JavaModelException if the operation is unable to
+	 * complete
+	 */
+	private void processPackageFragmentResource(PackageFragment source, PackageFragmentRoot root, String newName) throws JavaModelException {
+		try {
+			String[] newFragName = (newName == null) ? source.names : Util.getTrimmedSimpleNames(newName);
+			PackageFragment newFrag = root.getPackageFragment(newFragName);
+			IResource[] resources = collectResourcesOfInterest(source);
+
+			// if isMove() can we move the folder itself ? (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458)
+			boolean shouldMoveFolder = isMove() && !newFrag.resource().exists(); // if new pkg fragment exists, it is an override
+			IFolder srcFolder = (IFolder)source.resource();
+			IPath destPath = newFrag.getPath();
+			if (shouldMoveFolder) {
+				// check if destination is not included in source
+				if (srcFolder.getFullPath().isPrefixOf(destPath)) {
+					shouldMoveFolder = false;
+				} else {
+					// check if there are no sub-packages
+					IResource[] members = srcFolder.members();
+					for (int i = 0; i < members.length; i++) {
+						if ( members[i] instanceof IFolder) {
+							shouldMoveFolder = false;
+							break;
+						}
+					}
+				}
+			}
+			boolean containsReadOnlySubPackageFragments = createNeededPackageFragments((IContainer) source.parent.resource(), root, newFragName, shouldMoveFolder);
+			boolean sourceIsReadOnly = Util.isReadOnly(srcFolder);
+
+			// Process resources
+			if (shouldMoveFolder) {
+				// move underlying resource
+				// TODO Revisit once bug 43044 is fixed
+				if (sourceIsReadOnly) {
+					Util.setReadOnly(srcFolder, false);
+				}
+				srcFolder.move(destPath, this.force, true /* keep history */, getSubProgressMonitor(1));
+				if (sourceIsReadOnly) {
+					Util.setReadOnly(srcFolder, true);
+				}
+				setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+			} else {
+				// process the leaf resources
+				if (resources.length > 0) {
+					if (isRename()) {
+						if (! destPath.equals(source.getPath())) {
+							moveResources(resources, destPath);
+						}
+					} else if (isMove()) {
+						// we need to delete this resource if this operation wants to override existing resources
+						for (int i = 0, max = resources.length; i < max; i++) {
+							IResource destinationResource = ResourcesPlugin.getWorkspace().getRoot().findMember(destPath.append(resources[i].getName()));
+							if (destinationResource != null) {
+								if (this.force) {
+									deleteResource(destinationResource, IResource.KEEP_HISTORY);
+								} else {
+									throw new JavaModelException(new JavaModelStatus(
+										IJavaModelStatusConstants.NAME_COLLISION,
+										Messages.bind(Messages.status_nameCollision, destinationResource.getFullPath().toString())));
+								}
+							}
+						}
+						moveResources(resources, destPath);
+					} else {
+						// we need to delete this resource if this operation wants to override existing resources
+						for (int i = 0, max = resources.length; i < max; i++) {
+							IResource destinationResource = ResourcesPlugin.getWorkspace().getRoot().findMember(destPath.append(resources[i].getName()));
+							if (destinationResource != null) {
+								if (this.force) {
+									// we need to delete this resource if this operation wants to override existing resources
+									deleteResource(destinationResource, IResource.KEEP_HISTORY);
+								} else {
+									throw new JavaModelException(new JavaModelStatus(
+										IJavaModelStatusConstants.NAME_COLLISION,
+										Messages.bind(Messages.status_nameCollision, destinationResource.getFullPath().toString())));
+								}
+							}
+						}
+						copyResources(resources, destPath);
+					}
+				}
+			}
+
+			// Update package statement in compilation unit if needed
+			if (!Util.equalArraysOrNull(newFragName, source.names)) { // if package has been renamed, update the compilation units
+				char[][] inclusionPatterns = root.fullInclusionPatternChars();
+				char[][] exclusionPatterns = root.fullExclusionPatternChars();
+				for (int i = 0; i < resources.length; i++) {
+					String resourceName = resources[i].getName();
+					if (Util.isJavaLikeFileName(resourceName)) {
+						// we only consider potential compilation units
+						ICompilationUnit cu = newFrag.getCompilationUnit(resourceName);
+						if (Util.isExcluded(cu.getPath(), inclusionPatterns, exclusionPatterns, false/*not a folder*/)) continue;
+						this.parser.setSource(cu);
+						CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+						AST ast = astCU.getAST();
+						ASTRewrite rewrite = ASTRewrite.create(ast);
+						updatePackageStatement(astCU, newFragName, rewrite, cu);
+						TextEdit edits = rewrite.rewriteAST();
+						applyTextEdit(cu, edits);
+						cu.save(null, false);
+					}
+				}
+			}
+
+			// Discard empty old package (if still empty after the rename)
+			boolean isEmpty = true;
+			if (isMove()) {
+				// delete remaining files in this package (.class file in the case where Proj=src=bin)
+				// in case of a copy
+				updateReadOnlyPackageFragmentsForMove((IContainer) source.parent.resource(), root, newFragName, sourceIsReadOnly);
+				if (srcFolder.exists()) {
+					IResource[] remaining = srcFolder.members();
+					for (int i = 0, length = remaining.length; i < length; i++) {
+						IResource file = remaining[i];
+						if (file instanceof IFile) {
+							if (Util.isReadOnly(file)) {
+								Util.setReadOnly(file, false);
+							}
+							deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY);
+						} else {
+							isEmpty = false;
+						}
+					}
+				}
+				if (isEmpty) {
+					IResource rootResource;
+					// check if source is included in destination
+					if (destPath.isPrefixOf(srcFolder.getFullPath())) {
+						rootResource = newFrag.resource();
+					} else {
+						rootResource =  source.parent.resource();
+					}
+
+					// delete recursively empty folders
+					deleteEmptyPackageFragment(source, false, rootResource);
+				}
+			} else if (containsReadOnlySubPackageFragments) {
+				// in case of a copy
+				updateReadOnlyPackageFragmentsForCopy((IContainer) source.parent.resource(), root, newFragName);
+			}
+			// workaround for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=24505
+			if (isEmpty && isMove() && !(Util.isExcluded(source) || Util.isExcluded(newFrag))) {
+				IJavaProject sourceProject = source.getJavaProject();
+				getDeltaFor(sourceProject).movedFrom(source, newFrag);
+				IJavaProject destProject = newFrag.getJavaProject();
+				getDeltaFor(destProject).movedTo(newFrag, source);
+			}
+		} catch (JavaModelException e) {
+			throw e;
+		} catch (CoreException ce) {
+			throw new JavaModelException(ce);
+		}
+	}
+	private void saveContent(PackageFragment dest, String destName, TextEdit edits, String sourceEncoding, IFile destFile) throws JavaModelException {
+		try {
+			// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
+			// fix bug 66898
+			if (sourceEncoding != null) destFile.setCharset(sourceEncoding, this.progressMonitor);
+			// end todo
+		}
+		catch (CoreException ce) {
+			// use no encoding
+		}
+		// when the file was copied, its read-only flag was preserved -> temporary set it to false
+		// note this doesn't interfere with repository providers as this is a new resource that cannot be under
+		// version control yet
+		Util.setReadOnly(destFile, false);
+		ICompilationUnit destCU = dest.getCompilationUnit(destName);
+		applyTextEdit(destCU, edits);
+		destCU.save(getSubProgressMonitor(1), this.force);
+	}
+	/**
+	 * Updates the content of <code>cu</code>, modifying the type name and/or package
+	 * declaration as necessary.
+	 *
+	 * @return an AST rewrite or null if no rewrite needed
+	 */
+	private TextEdit updateContent(ICompilationUnit cu, PackageFragment dest, String newName) throws JavaModelException {
+		String[] currPackageName = ((PackageFragment) cu.getParent()).names;
+		String[] destPackageName = dest.names;
+		if (Util.equalArraysOrNull(currPackageName, destPackageName) && newName == null) {
+			return null; //nothing to change
+		} else {
+			// ensure cu is consistent (noop if already consistent)
+			cu.makeConsistent(this.progressMonitor);
+			this.parser.setSource(cu);
+			CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+			AST ast = astCU.getAST();
+			ASTRewrite rewrite = ASTRewrite.create(ast);
+			updateTypeName(cu, astCU, cu.getElementName(), newName, rewrite);
+			updatePackageStatement(astCU, destPackageName, rewrite, cu);
+			return rewrite.rewriteAST();
+		}
+	}
+	private void updatePackageStatement(CompilationUnit astCU, String[] pkgName, ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+		boolean defaultPackage = pkgName.length == 0;
+		AST ast = astCU.getAST();
+		if (defaultPackage) {
+			// remove existing package statement
+			PackageDeclaration pkg = astCU.getPackage();
+			if (pkg != null) {
+				int pkgStart;
+				Javadoc javadoc = pkg.getJavadoc();
+				if (javadoc != null) {
+					pkgStart = javadoc.getStartPosition() + javadoc.getLength() + 1;
+				} else {
+					pkgStart = pkg.getStartPosition();
+				}
+				int extendedStart = astCU.getExtendedStartPosition(pkg);
+				if (pkgStart != extendedStart) {
+					// keep the comments associated with package declaration
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757
+					String commentSource = cu.getSource().substring(extendedStart, pkgStart);
+					ASTNode comment = rewriter.createStringPlaceholder(commentSource, ASTNode.PACKAGE_DECLARATION);
+					rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, comment, null);
+				} else {
+					rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, null, null);
+				}
+			}
+		} else {
+			org.eclipse.jdt.core.dom.PackageDeclaration pkg = astCU.getPackage();
+			if (pkg != null) {
+				// rename package statement
+				Name name = ast.newName(pkgName);
+				rewriter.set(pkg, PackageDeclaration.NAME_PROPERTY, name, null);
+			} else {
+				// create new package statement
+				pkg = ast.newPackageDeclaration();
+				pkg.setName(ast.newName(pkgName));
+				rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, pkg, null);
+			}
+		}
+	}
+
+	private void updateReadOnlyPackageFragmentsForCopy(IContainer sourceFolder, PackageFragmentRoot root, String[] newFragName) {
+		IContainer parentFolder = (IContainer) root.resource();
+		for (int i = 0, length = newFragName.length; i <length; i++) {
+			String subFolderName = newFragName[i];
+			parentFolder = parentFolder.getFolder(new Path(subFolderName));
+			sourceFolder = sourceFolder.getFolder(new Path(subFolderName));
+			if (sourceFolder.exists() && Util.isReadOnly(sourceFolder)) {
+				Util.setReadOnly(parentFolder, true);
+			}
+		}
+	}
+
+	private void updateReadOnlyPackageFragmentsForMove(IContainer sourceFolder, PackageFragmentRoot root, String[] newFragName, boolean sourceFolderIsReadOnly) {
+		IContainer parentFolder = (IContainer) root.resource();
+		for (int i = 0, length = newFragName.length; i < length; i++) {
+			String subFolderName = newFragName[i];
+			parentFolder = parentFolder.getFolder(new Path(subFolderName));
+			sourceFolder = sourceFolder.getFolder(new Path(subFolderName));
+			if ((sourceFolder.exists() && Util.isReadOnly(sourceFolder)) || (i == length - 1 && sourceFolderIsReadOnly)) {
+				Util.setReadOnly(parentFolder, true);
+				// the source folder will be deleted anyway (move operation)
+				Util.setReadOnly(sourceFolder, false);
+			}
+		}
+	}
+			/**
+		 * Renames the main type in <code>cu</code>.
+		 */
+		private void updateTypeName(ICompilationUnit cu, CompilationUnit astCU, String oldName, String newName, ASTRewrite rewriter) throws JavaModelException {
+			if (newName != null) {
+				String oldTypeName= Util.getNameWithoutJavaLikeExtension(oldName);
+				String newTypeName= Util.getNameWithoutJavaLikeExtension(newName);
+				AST ast = astCU.getAST();
+				// update main type name
+				IType[] types = cu.getTypes();
+				for (int i = 0, max = types.length; i < max; i++) {
+					IType currentType = types[i];
+					if (currentType.getElementName().equals(oldTypeName)) {
+						AbstractTypeDeclaration typeNode = (AbstractTypeDeclaration) ((JavaElement) currentType).findNode(astCU);
+						if (typeNode != null) {
+							// rename type
+							rewriter.replace(typeNode.getName(), ast.newSimpleName(newTypeName), null);
+							// rename constructors
+							Iterator bodyDeclarations = typeNode.bodyDeclarations().iterator();
+							while (bodyDeclarations.hasNext()) {
+								Object bodyDeclaration = bodyDeclarations.next();
+								if (bodyDeclaration instanceof MethodDeclaration) {
+									MethodDeclaration methodDeclaration = (MethodDeclaration) bodyDeclaration;
+									if (methodDeclaration.isConstructor()) {
+										SimpleName methodName = methodDeclaration.getName();
+										if (methodName.getIdentifier().equals(oldTypeName)) {
+											rewriter.replace(methodName, ast.newSimpleName(newTypeName), null);
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	/**
+	 * Possible failures:
+	 * <ul>
+	 *  <li>NO_ELEMENTS_TO_PROCESS - no elements supplied to the operation
+	 *	<li>INDEX_OUT_OF_BOUNDS - the number of renamings supplied to the operation
+	 *		does not match the number of elements that were supplied.
+	 * </ul>
+	 */
+	protected IJavaModelStatus verify() {
+		IJavaModelStatus status = super.verify();
+		if (!status.isOK()) {
+			return status;
+		}
+
+		if (this.renamingsList != null && this.renamingsList.length != this.elementsToProcess.length) {
+			return new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS);
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+	/**
+	 * @see MultiOperation
+	 */
+	protected void verify(IJavaElement element) throws JavaModelException {
+		if (element == null || !element.exists())
+			error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
+
+		if (element.isReadOnly() && (isRename() || isMove()))
+			error(IJavaModelStatusConstants.READ_ONLY, element);
+
+		IResource resource = ((JavaElement) element).resource();
+		if (resource instanceof IFolder) {
+			if (resource.isLinked()) {
+				error(IJavaModelStatusConstants.INVALID_RESOURCE, element);
+			}
+		}
+
+		int elementType = element.getElementType();
+
+		if (elementType == IJavaElement.COMPILATION_UNIT) {
+			org.eclipse.jdt.internal.core.CompilationUnit compilationUnit = (org.eclipse.jdt.internal.core.CompilationUnit) element;
+			if (isMove() && compilationUnit.isWorkingCopy() && !compilationUnit.isPrimary())
+				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+		} else if (elementType != IJavaElement.PACKAGE_FRAGMENT) {
+			error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+		}
+
+		JavaElement dest = (JavaElement) getDestinationParent(element);
+		verifyDestination(element, dest);
+		if (this.renamings != null) {
+			verifyRenaming(element);
+		}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
new file mode 100644
index 0000000..43c6646
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * <p>This operation creates a compilation unit (CU).
+ * If the CU doesn't exist yet, a new compilation unit will be created with the content provided.
+ * Otherwise the operation will override the contents of an existing CU with the new content.
+ *
+ * <p>Note: It is possible to create a CU automatically when creating a
+ * class or interface. Thus, the preferred method of creating a CU is
+ * to perform a create type operation rather than
+ * first creating a CU and secondly creating a type inside the CU.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>The package fragment in which to create the compilation unit.
+ *  <li>The name of the compilation unit.
+ *      Do not include the <code>".java"</code> suffix (ex. <code>"Object"</code> -
+ * 		the <code>".java"</code> will be added for the name of the compilation unit.)
+ *  <li>
+  * </ul>
+ */
+public class CreateCompilationUnitOperation extends JavaModelOperation {
+
+	/**
+	 * The name of the compilation unit being created.
+	 */
+	protected String name;
+	/**
+	 * The source code to use when creating the element.
+	 */
+	protected String source= null;
+/**
+ * When executed, this operation will create a compilation unit with the given name.
+ * The name should have the ".java" suffix.
+ */
+public CreateCompilationUnitOperation(IPackageFragment parentElement, String name, String source, boolean force) {
+	super(null, new IJavaElement[] {parentElement}, force);
+	this.name = name;
+	this.source = source;
+}
+/**
+ * Creates a compilation unit.
+ *
+ * @exception JavaModelException if unable to create the compilation unit.
+ */
+protected void executeOperation() throws JavaModelException {
+	try {
+		beginTask(Messages.operation_createUnitProgress, 2);
+		JavaElementDelta delta = newJavaElementDelta();
+		ICompilationUnit unit = getCompilationUnit();
+		IPackageFragment pkg = (IPackageFragment) getParentElement();
+		IContainer folder = (IContainer) pkg.getResource();
+		worked(1);
+		IFile compilationUnitFile = folder.getFile(new Path(this.name));
+		if (compilationUnitFile.exists()) {
+			// update the contents of the existing unit if fForce is true
+			if (this.force) {
+				IBuffer buffer = unit.getBuffer();
+				if (buffer == null) return;
+				buffer.setContents(this.source);
+				unit.save(new NullProgressMonitor(), false);
+				this.resultElements = new IJavaElement[] {unit};
+				if (!Util.isExcluded(unit)
+						&& unit.getParent().exists()) {
+					for (int i = 0; i < this.resultElements.length; i++) {
+						delta.changed(this.resultElements[i], IJavaElementDelta.F_CONTENT);
+					}
+					addDelta(delta);
+				}
+			} else {
+				throw new JavaModelException(new JavaModelStatus(
+					IJavaModelStatusConstants.NAME_COLLISION,
+					Messages.bind(Messages.status_nameCollision, compilationUnitFile.getFullPath().toString())));
+			}
+		} else {
+			try {
+				String encoding = null;
+				try {
+					encoding = folder.getDefaultCharset(); // get folder encoding as file is not accessible
+				}
+				catch (CoreException ce) {
+					// use no encoding
+				}
+				InputStream stream = new ByteArrayInputStream(encoding == null ? this.source.getBytes() : this.source.getBytes(encoding));
+				createFile(folder, unit.getElementName(), stream, this.force);
+				this.resultElements = new IJavaElement[] {unit};
+				if (!Util.isExcluded(unit)
+						&& unit.getParent().exists()) {
+					for (int i = 0; i < this.resultElements.length; i++) {
+						delta.added(this.resultElements[i]);
+					}
+					addDelta(delta);
+				}
+			} catch (IOException e) {
+				throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+			}
+		}
+		worked(1);
+	} finally {
+		done();
+	}
+}
+/**
+ * @see CreateElementInCUOperation#getCompilationUnit()
+ */
+protected ICompilationUnit getCompilationUnit() {
+	return ((IPackageFragment)getParentElement()).getCompilationUnit(this.name);
+}
+protected ISchedulingRule getSchedulingRule() {
+	IResource resource  = getCompilationUnit().getResource();
+	IWorkspace workspace = resource.getWorkspace();
+	if (resource.exists()) {
+		return workspace.getRuleFactory().modifyRule(resource);
+	} else {
+		return workspace.getRuleFactory().createRule(resource);
+	}
+}
+/**
+ * Possible failures: <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - the package fragment supplied to the operation is
+ * 		<code>null</code>.
+ *	<li>INVALID_NAME - the compilation unit name provided to the operation
+ * 		is <code>null</code> or has an invalid syntax
+ *  <li>INVALID_CONTENTS - the source specified for the compiliation unit is null
+ * </ul>
+ */
+public IJavaModelStatus verify() {
+	if (getParentElement() == null) {
+		return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+	}
+	IJavaProject project = getParentElement().getJavaProject();
+	if (JavaConventions.validateCompilationUnitName(this.name, project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true)).getSeverity() == IStatus.ERROR) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, this.name);
+	}
+	if (this.source == null) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS);
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java
new file mode 100644
index 0000000..cbb38db
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * <p>This abstract class implements behavior common to <code>CreateElementInCUOperations</code>.
+ * To create a compilation unit, or an element contained in a compilation unit, the
+ * source code for the entire compilation unit is updated and saved.
+ *
+ * <p>The element being created can be positioned relative to an existing
+ * element in the compilation unit via the methods <code>#createAfter</code>
+ * and <code>#createBefore</code>. By default, the new element is positioned
+ * as the last child of its parent element.
+ *
+ */
+public abstract class CreateElementInCUOperation extends JavaModelOperation {
+	/**
+	 * The compilation unit AST used for this operation
+	 */
+	protected CompilationUnit cuAST;
+	/**
+	 * A constant meaning to position the new element
+	 * as the last child of its parent element.
+	 */
+	protected static final int INSERT_LAST = 1;
+	/**
+	 * A constant meaning to position the new element
+	 * after the element defined by <code>fAnchorElement</code>.
+	 */
+	protected static final int INSERT_AFTER = 2;
+
+	/**
+	 * A constant meaning to position the new element
+	 * before the element defined by <code>fAnchorElement</code>.
+	 */
+	protected static final int INSERT_BEFORE = 3;
+	/**
+	 * One of the position constants, describing where
+	 * to position the newly created element.
+	 */
+	protected int insertionPolicy = INSERT_LAST;
+	/**
+	 * The element that the newly created element is
+	 * positioned relative to, as described by
+	 * <code>fInsertPosition</code>, or <code>null</code>
+	 * if the newly created element will be positioned
+	 * last.
+	 */
+	protected IJavaElement anchorElement = null;
+	/**
+	 * A flag indicating whether creation of a new element occurred.
+	 * A request for creating a duplicate element would request in this
+	 * flag being set to <code>false</code>. Ensures that no deltas are generated
+	 * when creation does not occur.
+	 */
+	protected boolean creationOccurred = true;
+	/**
+	 * Constructs an operation that creates a Java Language Element with
+	 * the specified parent, contained within a compilation unit.
+	 */
+	public CreateElementInCUOperation(IJavaElement parentElement) {
+		super(null, new IJavaElement[]{parentElement});
+		initializeDefaultPosition();
+	}
+	/**
+	 * Only allow cancelling if this operation is not nested.
+	 */
+	protected void checkCanceled() {
+		if (!this.isNested) {
+			super.checkCanceled();
+		}
+	}
+	/**
+	 * Instructs this operation to position the new element after
+	 * the given sibling, or to add the new element as the last child
+	 * of its parent if <code>null</code>.
+	 */
+	public void createAfter(IJavaElement sibling) {
+		setRelativePosition(sibling, INSERT_AFTER);
+	}
+	/**
+	 * Instructs this operation to position the new element before
+	 * the given sibling, or to add the new element as the last child
+	 * of its parent if <code>null</code>.
+	 */
+	public void createBefore(IJavaElement sibling) {
+		setRelativePosition(sibling, INSERT_BEFORE);
+	}
+	/**
+	 * Execute the operation - generate new source for the compilation unit
+	 * and save the results.
+	 *
+	 * @exception JavaModelException if the operation is unable to complete
+	 */
+	protected void executeOperation() throws JavaModelException {
+		try {
+			beginTask(getMainTaskName(), getMainAmountOfWork());
+			JavaElementDelta delta = newJavaElementDelta();
+			ICompilationUnit unit = getCompilationUnit();
+			generateNewCompilationUnitAST(unit);
+			if (this.creationOccurred) {
+				//a change has really occurred
+				unit.save(null, false);
+				boolean isWorkingCopy = unit.isWorkingCopy();
+				if (!isWorkingCopy)
+					setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+				worked(1);
+				this.resultElements = generateResultHandles();
+				if (!isWorkingCopy // if unit is working copy, then save will have already fired the delta
+						&& !Util.isExcluded(unit)
+						&& unit.getParent().exists()) {
+					for (int i = 0; i < this.resultElements.length; i++) {
+						delta.added(this.resultElements[i]);
+					}
+					addDelta(delta);
+				} // else unit is created outside classpath
+				  // non-java resource delta will be notified by delta processor
+			}
+		} finally {
+			done();
+		}
+	}
+
+	/*
+	 * Returns the property descriptor for the element being created.
+	 */
+	protected abstract StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent);
+
+	/*
+	 * Returns an AST node for the element being created.
+	 */
+	protected abstract ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException;
+	/*
+	 * Generates a new AST for this operation and applies it to the given cu
+	 */
+	protected void generateNewCompilationUnitAST(ICompilationUnit cu) throws JavaModelException {
+		this.cuAST = parse(cu);
+
+		AST ast = this.cuAST.getAST();
+		ASTRewrite rewriter = ASTRewrite.create(ast);
+		ASTNode child = generateElementAST(rewriter, cu);
+		if (child != null) {
+			ASTNode parent = ((JavaElement) getParentElement()).findNode(this.cuAST);
+			if (parent == null)
+				parent = this.cuAST;
+			insertASTNode(rewriter, parent, child);
+			TextEdit edits = rewriter.rewriteAST();
+			applyTextEdit(cu, edits);
+		}
+		worked(1);
+	}
+	/**
+	 * Creates and returns the handle for the element this operation created.
+	 */
+	protected abstract IJavaElement generateResultHandle();
+	/**
+	 * Creates and returns the handles for the elements this operation created.
+	 */
+	protected IJavaElement[] generateResultHandles() {
+		return new IJavaElement[]{generateResultHandle()};
+	}
+	/**
+	 * Returns the compilation unit in which the new element is being created.
+	 */
+	protected ICompilationUnit getCompilationUnit() {
+		return getCompilationUnitFor(getParentElement());
+	}
+	/**
+	 * Returns the amount of work for the main task of this operation for
+	 * progress reporting.
+	 */
+	protected int getMainAmountOfWork(){
+		return 2;
+	}
+	/**
+	 * Returns the name of the main task of this operation for
+	 * progress reporting.
+	 */
+	public abstract String getMainTaskName();
+
+	protected ISchedulingRule getSchedulingRule() {
+		IResource resource = getCompilationUnit().getResource();
+		IWorkspace workspace = resource.getWorkspace();
+		return workspace.getRuleFactory().modifyRule(resource);
+	}
+	/**
+	 * Sets the default position in which to create the new type
+	 * member.
+	 * Operations that require a different default position must
+	 * override this method.
+	 */
+	protected void initializeDefaultPosition() {
+		// By default, the new element is positioned as the
+		// last child of the parent element in which it is created.
+	}
+	/**
+	 * Inserts the given child into the given AST,
+	 * based on the position settings of this operation.
+	 *
+	 * @see #createAfter(IJavaElement)
+	 * @see #createBefore(IJavaElement)
+	 */
+	protected void insertASTNode(ASTRewrite rewriter, ASTNode parent, ASTNode child) throws JavaModelException {
+		StructuralPropertyDescriptor propertyDescriptor = getChildPropertyDescriptor(parent);
+		if (propertyDescriptor instanceof ChildListPropertyDescriptor) {
+			ChildListPropertyDescriptor childListPropertyDescriptor = (ChildListPropertyDescriptor) propertyDescriptor;
+	 		ListRewrite rewrite = rewriter.getListRewrite(parent, childListPropertyDescriptor);
+	 		switch (this.insertionPolicy) {
+	 			case INSERT_BEFORE:
+	 				ASTNode element = ((JavaElement) this.anchorElement).findNode(this.cuAST);
+	 				if (childListPropertyDescriptor.getElementType().isAssignableFrom(element.getClass()))
+		 				rewrite.insertBefore(child, element, null);
+	 				else
+	 					// case of an empty import list: the anchor element is the top level type and cannot be used in insertBefore as it is not the same type
+	 					rewrite.insertLast(child, null);
+	 				break;
+	 			case INSERT_AFTER:
+	 				element = ((JavaElement) this.anchorElement).findNode(this.cuAST);
+	 				if (childListPropertyDescriptor.getElementType().isAssignableFrom(element.getClass()))
+		 				rewrite.insertAfter(child, element, null);
+	 				else
+	 					// case of an empty import list: the anchor element is the top level type and cannot be used in insertAfter as it is not the same type
+	 					rewrite.insertLast(child, null);
+	 				break;
+	 			case INSERT_LAST:
+	 				rewrite.insertLast(child, null);
+	 				break;
+	 		}
+		} else {
+			rewriter.set(parent, propertyDescriptor, child, null);
+		}
+ 	}
+	protected CompilationUnit parse(ICompilationUnit cu) throws JavaModelException {
+		// ensure cu is consistent (noop if already consistent)
+		cu.makeConsistent(this.progressMonitor);
+		// create an AST for the compilation unit
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setSource(cu);
+		return (CompilationUnit) parser.createAST(this.progressMonitor);
+	}
+	/**
+	 * Sets the name of the <code>DOMNode</code> that will be used to
+	 * create this new element.
+	 * Used by the <code>CopyElementsOperation</code> for renaming.
+	 * Only used for <code>CreateTypeMemberOperation</code>
+	 */
+	protected void setAlteredName(String newName) {
+		// implementation in CreateTypeMemberOperation
+	}
+	/**
+	 * Instructs this operation to position the new element relative
+	 * to the given sibling, or to add the new element as the last child
+	 * of its parent if <code>null</code>. The <code>position</code>
+	 * must be one of the position constants.
+	 */
+	protected void setRelativePosition(IJavaElement sibling, int policy) throws IllegalArgumentException {
+		if (sibling == null) {
+			this.anchorElement = null;
+			this.insertionPolicy = INSERT_LAST;
+		} else {
+			this.anchorElement = sibling;
+			this.insertionPolicy = policy;
+		}
+	}
+	/**
+	 * Possible failures: <ul>
+	 *  <li>NO_ELEMENTS_TO_PROCESS - the compilation unit supplied to the operation is
+	 * 		<code>null</code>.
+	 *  <li>INVALID_NAME - no name, a name was null or not a valid
+	 * 		import declaration name.
+	 *  <li>INVALID_SIBLING - the sibling provided for positioning is not valid.
+	 * </ul>
+	 * @see IJavaModelStatus
+	 * @see org.eclipse.jdt.core.JavaConventions
+	 */
+	public IJavaModelStatus verify() {
+		if (getParentElement() == null) {
+			return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+		}
+		if (this.anchorElement != null) {
+			IJavaElement domPresentParent = this.anchorElement.getParent();
+			if (domPresentParent.getElementType() == IJavaElement.IMPORT_CONTAINER) {
+				domPresentParent = domPresentParent.getParent();
+			}
+			if (!domPresentParent.equals(getParentElement())) {
+				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, this.anchorElement);
+			}
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
new file mode 100644
index 0000000..3f854c2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Iterator;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * <p>This operation creates a field declaration in a type.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Containing Type
+ *  <li>The source code for the declaration. No verification of the source is
+ *      performed.
+ * </ul>
+ */
+public class CreateFieldOperation extends CreateTypeMemberOperation {
+/**
+ * When executed, this operation will create a field with the given name
+ * in the given type with the specified source.
+ *
+ * <p>By default the new field is positioned after the last existing field
+ * declaration, or as the first member in the type if there are no
+ * field declarations.
+ */
+public CreateFieldOperation(IType parentElement, String source, boolean force) {
+	super(parentElement, source, force);
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, cu);
+	if (node.getNodeType() != ASTNode.FIELD_DECLARATION)
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+	return node;
+}
+/**
+ * @see CreateElementInCUOperation#generateResultHandle
+ */
+protected IJavaElement generateResultHandle() {
+	return getType().getField(getASTNodeName());
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createFieldProgress;
+}
+private VariableDeclarationFragment getFragment(ASTNode node) {
+	Iterator fragments =  ((FieldDeclaration) node).fragments().iterator();
+	if (this.anchorElement != null) {
+		VariableDeclarationFragment fragment = null;
+		String fragmentName = this.anchorElement.getElementName();
+		while (fragments.hasNext()) {
+			fragment = (VariableDeclarationFragment) fragments.next();
+			if (fragment.getName().getIdentifier().equals(fragmentName)) {
+				return fragment;
+			}
+		}
+		return fragment;
+	} else {
+		return (VariableDeclarationFragment) fragments.next();
+	}
+}
+/**
+ * By default the new field is positioned after the last existing field
+ * declaration, or as the first member in the type if there are no
+ * field declarations.
+ */
+protected void initializeDefaultPosition() {
+	IType parentElement = getType();
+	try {
+		IField[] fields = parentElement.getFields();
+		if (fields != null && fields.length > 0) {
+			final IField lastField = fields[fields.length - 1];
+			if (parentElement.isEnum()) {
+				IField field = lastField;
+				if (!field.isEnumConstant()) {
+					createAfter(lastField);
+				}
+			} else {
+				createAfter(lastField);
+			}
+		} else {
+			IJavaElement[] elements = parentElement.getChildren();
+			if (elements != null && elements.length > 0) {
+				createBefore(elements[0]);
+			}
+		}
+	} catch (JavaModelException e) {
+		// type doesn't exist: ignore
+	}
+}
+/**
+ * @see CreateTypeMemberOperation#verifyNameCollision
+ */
+protected IJavaModelStatus verifyNameCollision() {
+	if (this.createdNode != null) {
+		IType type= getType();
+		String fieldName = getASTNodeName();
+		if (type.getField(fieldName).exists()) {
+			return new JavaModelStatus(
+				IJavaModelStatusConstants.NAME_COLLISION,
+				Messages.bind(Messages.status_nameCollision, fieldName));
+		}
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+private String getASTNodeName() {
+	if (this.alteredName != null) return this.alteredName;
+	return getFragment(this.createdNode).getName().getIdentifier();
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	VariableDeclarationFragment fragment = getFragment(node);
+	SimpleName oldName = fragment.getName();
+	fragment.setName(newName);
+	return oldName;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java
new file mode 100644
index 0000000..e240711
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * <p>This operation adds an import declaration to an existing compilation unit.
+ * If the compilation unit already includes the specified import declaration,
+ * the import is not generated (it does not generate duplicates).
+ * Note that it is valid to specify both a single-type import and an on-demand import
+ * for the same package, for example <code>"java.io.File"</code> and
+ * <code>"java.io.*"</code>, in which case both are preserved since the semantics
+ * of this are not the same as just importing <code>"java.io.*"</code>.
+ * Importing <code>"java.lang.*"</code>, or the package in which the compilation unit
+ * is defined, are not treated as special cases.  If they are specified, they are
+ * included in the result.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Compilation unit
+ *  <li>Import name - the name of the import to add to the
+ *      compilation unit. For example: <code>"java.io.File"</code> or <code>"java.awt.*"</code>
+ * </ul>
+ */
+public class CreateImportOperation extends CreateElementInCUOperation {
+
+	/*
+	 * The name of the import to be created.
+	 */
+	protected String importName;
+
+	/*
+	 * The flags of the import to be created (either Flags#AccDefault or Flags#AccStatic)
+	 */
+	protected int flags;
+
+/**
+ * When executed, this operation will add an import to the given compilation unit.
+ */
+public CreateImportOperation(String importName, ICompilationUnit parentElement, int flags) {
+	super(parentElement);
+	this.importName = importName;
+	this.flags = flags;
+}
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	return CompilationUnit.IMPORTS_PROPERTY;
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	// ensure no duplicate
+	Iterator imports = this.cuAST.imports().iterator();
+	boolean onDemand = this.importName.endsWith(".*"); //$NON-NLS-1$
+	String importActualName = this.importName;
+	if (onDemand) {
+		importActualName = this.importName.substring(0, this.importName.length() - 2);
+	}
+	while (imports.hasNext()) {
+		ImportDeclaration importDeclaration = (ImportDeclaration) imports.next();
+		if (importActualName.equals(importDeclaration.getName().getFullyQualifiedName())
+				&& (onDemand == importDeclaration.isOnDemand())
+				&& (Flags.isStatic(this.flags) == importDeclaration.isStatic())) {
+			this.creationOccurred = false;
+			return null;
+		}
+	}
+
+	AST ast = this.cuAST.getAST();
+	ImportDeclaration importDeclaration = ast.newImportDeclaration();
+	importDeclaration.setStatic(Flags.isStatic(this.flags));
+	// split import name into individual fragments, checking for on demand imports
+	char[][] charFragments = CharOperation.splitOn('.', importActualName.toCharArray(), 0, importActualName.length());
+	int length = charFragments.length;
+	String[] strFragments = new String[length];
+	for (int i = 0; i < length; i++) {
+		strFragments[i] = String.valueOf(charFragments[i]);
+	}
+	Name name = ast.newName(strFragments);
+	importDeclaration.setName(name);
+	if (onDemand) importDeclaration.setOnDemand(true);
+	return importDeclaration;
+}
+/**
+ * @see CreateElementInCUOperation#generateResultHandle
+ */
+protected IJavaElement generateResultHandle() {
+	return getCompilationUnit().getImport(this.importName);
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createImportsProgress;
+}
+/**
+ * Sets the correct position for the new import:<ul>
+ * <li> after the last import
+ * <li> if no imports, before the first type
+ * <li> if no type, after the package statement
+ * <li> and if no package statement - first thing in the CU
+ */
+protected void initializeDefaultPosition() {
+	try {
+		ICompilationUnit cu = getCompilationUnit();
+		IImportDeclaration[] imports = cu.getImports();
+		if (imports.length > 0) {
+			createAfter(imports[imports.length - 1]);
+			return;
+		}
+		IType[] types = cu.getTypes();
+		if (types.length > 0) {
+			createBefore(types[0]);
+			return;
+		}
+		IJavaElement[] children = cu.getChildren();
+		//look for the package declaration
+		for (int i = 0; i < children.length; i++) {
+			if (children[i].getElementType() == IJavaElement.PACKAGE_DECLARATION) {
+				createAfter(children[i]);
+				return;
+			}
+		}
+	} catch (JavaModelException e) {
+		// cu doesn't exit: ignore
+	}
+}
+/**
+ * Possible failures: <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - the compilation unit supplied to the operation is
+ * 		<code>null</code>.
+ *  <li>INVALID_NAME - not a valid import declaration name.
+ * </ul>
+ * @see IJavaModelStatus
+ * @see JavaConventions
+ */
+public IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (!status.isOK()) {
+		return status;
+	}
+	IJavaProject project = getParentElement().getJavaProject();
+	if (JavaConventions.validateImportDeclaration(this.importName, project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true)).getSeverity() == IStatus.ERROR) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, this.importName);
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java
new file mode 100644
index 0000000..cb2600f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * <p>This operation creates a initializer in a type.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Containing Type
+ *  <li>The source code for the initializer. No verification of the source is
+ *      performed.
+ * </ul>
+ */
+public class CreateInitializerOperation extends CreateTypeMemberOperation {
+	/**
+	 * The current number of initializers in the parent type.
+	 * Used to retrieve the handle of the newly created initializer.
+	 */
+	protected int numberOfInitializers= 1;
+/**
+ * When executed, this operation will create an initializer with the given name
+ * in the given type with the specified source.
+ *
+ * <p>By default the new initializer is positioned after the last existing initializer
+ * declaration, or as the first member in the type if there are no
+ * initializers.
+ */
+public CreateInitializerOperation(IType parentElement, String source) {
+	super(parentElement, source, false);
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, cu);
+	if (node.getNodeType() != ASTNode.INITIALIZER)
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+	return node;
+}
+/**
+ * @see CreateElementInCUOperation#generateResultHandle
+ */
+protected IJavaElement generateResultHandle() {
+	try {
+		//update the children to be current
+		getType().getCompilationUnit().close();
+		if (this.anchorElement == null) {
+			return getType().getInitializer(this.numberOfInitializers);
+		} else {
+			IJavaElement[] children = getType().getChildren();
+			int count = 0;
+			for (int i = 0; i < children.length; i++) {
+				IJavaElement child = children[i];
+				if (child.equals(this.anchorElement)) {
+					if (child .getElementType() == IJavaElement.INITIALIZER && this.insertionPolicy == CreateElementInCUOperation.INSERT_AFTER) {
+						count++;
+					}
+					return getType().getInitializer(count);
+				} else
+					if (child.getElementType() == IJavaElement.INITIALIZER) {
+						count++;
+					}
+			}
+		}
+	} catch (JavaModelException e) {
+		// type doesn't exist: ignore
+	}
+	return null;
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createInitializerProgress;
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	return null; // intializer cannot be renamed
+}
+/**
+ * By default the new initializer is positioned after the last existing initializer
+ * declaration, or as the first member in the type if there are no
+ * initializers.
+ */
+protected void initializeDefaultPosition() {
+	IType parentElement = getType();
+	try {
+		IJavaElement[] elements = parentElement.getInitializers();
+		if (elements != null && elements.length > 0) {
+			this.numberOfInitializers = elements.length;
+			createAfter(elements[elements.length - 1]);
+		} else {
+			elements = parentElement.getChildren();
+			if (elements != null && elements.length > 0) {
+				createBefore(elements[0]);
+			}
+		}
+	} catch (JavaModelException e) {
+		// type doesn't exist: ignore
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
new file mode 100644
index 0000000..bfe7d56
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * <p>This operation creates an instance method.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Containing type
+ *  <li>The source code for the method. No verification of the source is
+ *      performed.
+ * </ul>
+ */
+public class CreateMethodOperation extends CreateTypeMemberOperation {
+
+	protected String[] parameterTypes;
+
+/**
+ * When executed, this operation will create a method
+ * in the given type with the specified source.
+ */
+public CreateMethodOperation(IType parentElement, String source, boolean force) {
+	super(parentElement, source, force);
+}
+/**
+ * Returns the type signatures of the parameter types of the
+ * current <code>MethodDeclaration</code>
+ */
+protected String[] convertASTMethodTypesToSignatures() {
+	if (this.parameterTypes == null) {
+		if (this.createdNode != null) {
+			MethodDeclaration methodDeclaration = (MethodDeclaration) this.createdNode;
+			List parameters = methodDeclaration.parameters();
+			int size = parameters.size();
+			this.parameterTypes = new String[size];
+			Iterator iterator = parameters.iterator();
+			// convert the AST types to signatures
+			for (int i = 0; i < size; i++) {
+				SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
+				String typeSig = Util.getSignature(parameter.getType());
+				int extraDimensions = parameter.getExtraDimensions();
+				if (methodDeclaration.isVarargs() && i == size-1)
+					extraDimensions++;
+				this.parameterTypes[i] = Signature.createArraySignature(typeSig, extraDimensions);
+			}
+		}
+	}
+	return this.parameterTypes;
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, cu);
+	if (node.getNodeType() != ASTNode.METHOD_DECLARATION)
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+	return node;
+}
+/**
+ * @see CreateElementInCUOperation#generateResultHandle
+ */
+protected IJavaElement generateResultHandle() {
+	String[] types = convertASTMethodTypesToSignatures();
+	String name = getASTNodeName();
+	return getType().getMethod(name, types);
+}
+private String getASTNodeName() {
+	return ((MethodDeclaration) this.createdNode).getName().getIdentifier();
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createMethodProgress;
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	MethodDeclaration method = (MethodDeclaration) node;
+	SimpleName oldName = method.getName();
+	method.setName(newName);
+	return oldName;
+}
+/**
+ * @see CreateTypeMemberOperation#verifyNameCollision
+ */
+protected IJavaModelStatus verifyNameCollision() {
+	if (this.createdNode != null) {
+		IType type = getType();
+		String name;
+		if (((MethodDeclaration) this.createdNode).isConstructor())
+			name = type.getElementName();
+		else
+			name = getASTNodeName();
+		String[] types = convertASTMethodTypesToSignatures();
+		if (type.getMethod(name, types).exists()) {
+			return new JavaModelStatus(
+				IJavaModelStatusConstants.NAME_COLLISION,
+				Messages.bind(Messages.status_nameCollision, name));
+		}
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java
new file mode 100644
index 0000000..9b3d75a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IImportDeclaration;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * <p>This operation adds/replaces a package declaration in an existing compilation unit.
+ * If the compilation unit already includes the specified package declaration,
+ * it is not generated (it does not generate duplicates).
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Compilation unit element
+ *  <li>Package name
+ * </ul>
+ */
+public class CreatePackageDeclarationOperation extends CreateElementInCUOperation {
+	/**
+	 * The name of the package declaration being created
+	 */
+	protected String name = null;
+/**
+ * When executed, this operation will add a package declaration to the given compilation unit.
+ */
+public CreatePackageDeclarationOperation(String name, ICompilationUnit parentElement) {
+	super(parentElement);
+	this.name= name;
+}
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	return CompilationUnit.PACKAGE_PROPERTY;
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	//look for an existing package declaration
+	IJavaElement[] children = getCompilationUnit().getChildren();
+	for (int i = 0; i < children.length; i++) {
+		if (children[i].getElementType() ==  IJavaElement.PACKAGE_DECLARATION && this.name.equals(children[i].getElementName())) {
+			//equivalent package declaration already exists
+			this.creationOccurred = false;
+			return null;
+		}
+	}
+	AST ast = this.cuAST.getAST();
+	PackageDeclaration pkgDeclaration = ast.newPackageDeclaration();
+	Name astName = ast.newName(this.name);
+	pkgDeclaration.setName(astName);
+	return pkgDeclaration;
+}
+/**
+ * Creates and returns the handle for the element this operation created.
+ */
+protected IJavaElement generateResultHandle() {
+	return getCompilationUnit().getPackageDeclaration(this.name);
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createPackageProgress;
+}
+/**
+ * Sets the correct position for new package declaration:<ul>
+ * <li> before the first import
+ * <li> if no imports, before the first type
+ * <li> if no type - first thing in the CU
+ * <li>
+ */
+protected void initializeDefaultPosition() {
+	try {
+		ICompilationUnit cu = getCompilationUnit();
+		IImportDeclaration[] imports = cu.getImports();
+		if (imports.length > 0) {
+			createBefore(imports[0]);
+			return;
+		}
+		IType[] types = cu.getTypes();
+		if (types.length > 0) {
+			createBefore(types[0]);
+			return;
+		}
+	} catch (JavaModelException e) {
+		// cu doesn't exist: ignore
+	}
+}
+/**
+ * Possible failures: <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - no compilation unit was supplied to the operation
+ *  <li>INVALID_NAME - a name supplied to the operation was not a valid
+ * 		package declaration name.
+ * </ul>
+ * @see IJavaModelStatus
+ * @see JavaConventions
+ */
+public IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (!status.isOK()) {
+		return status;
+	}
+	IJavaProject project = getParentElement().getJavaProject();
+	if (JavaConventions.validatePackageName(this.name, project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true)).getSeverity() == IStatus.ERROR) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, this.name);
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java
new file mode 100644
index 0000000..4786528
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * This operation creates a new package fragment under a given package fragment root.
+ * The following must be specified: <ul>
+ * <li>the package fragment root
+ * <li>the package name
+ * </ul>
+ * <p>Any needed folders/package fragments are created.
+ * If the package fragment already exists, this operation has no effect.
+ * The result elements include the <code>IPackageFragment</code> created and any side effect
+ * package fragments that were created.
+ *
+ * <p>NOTE: A default package fragment exists by default for a given root.
+ *
+ * <p>Possible exception conditions: <ul>
+ *  <li>Package fragment root is read-only
+ *  <li>Package fragment's name is taken by a simple (non-folder) resource
+ * </ul>
+ */
+public class CreatePackageFragmentOperation extends JavaModelOperation {
+	/**
+	 * The fully qualified, dot-delimited, package name.
+	 */
+	protected String[] pkgName;
+/**
+ * When executed, this operation will create a package fragment with the given name
+ * under the given package fragment root. The dot-separated name is broken into
+ * segments. Intermediate folders are created as required for each segment.
+ * If the folders already exist, this operation has no effect.
+ */
+public CreatePackageFragmentOperation(IPackageFragmentRoot parentElement, String packageName, boolean force) {
+	super(null, new IJavaElement[]{parentElement}, force);
+	this.pkgName = packageName == null ? null : Util.getTrimmedSimpleNames(packageName);
+}
+/**
+ * Execute the operation - creates the new package fragment and any
+ * side effect package fragments.
+ *
+ * @exception JavaModelException if the operation is unable to complete
+ */
+protected void executeOperation() throws JavaModelException {
+	try {
+		JavaElementDelta delta = null;
+		PackageFragmentRoot root = (PackageFragmentRoot) getParentElement();
+		beginTask(Messages.operation_createPackageFragmentProgress, this.pkgName.length);
+		IContainer parentFolder = (IContainer) root.resource();
+		String[] sideEffectPackageName = CharOperation.NO_STRINGS;
+		ArrayList results = new ArrayList(this.pkgName.length);
+		char[][] inclusionPatterns = root.fullInclusionPatternChars();
+		char[][] exclusionPatterns = root.fullExclusionPatternChars();
+		int i;
+		for (i = 0; i < this.pkgName.length; i++) {
+			String subFolderName = this.pkgName[i];
+			sideEffectPackageName = Util.arrayConcat(sideEffectPackageName, subFolderName);
+			IResource subFolder = parentFolder.findMember(subFolderName);
+			if (subFolder == null) {
+				createFolder(parentFolder, subFolderName, this.force);
+				parentFolder = parentFolder.getFolder(new Path(subFolderName));
+				IPackageFragment addedFrag = root.getPackageFragment(sideEffectPackageName);
+				if (!Util.isExcluded(parentFolder, inclusionPatterns, exclusionPatterns)) {
+					if (delta == null) {
+						delta = newJavaElementDelta();
+					}
+					delta.added(addedFrag);
+				}
+				results.add(addedFrag);
+			} else {
+				parentFolder = (IContainer) subFolder;
+			}
+			worked(1);
+		}
+		if (results.size() > 0) {
+			this.resultElements = new IJavaElement[results.size()];
+			results.toArray(this.resultElements);
+			if (delta != null) {
+				addDelta(delta);
+			}
+		}
+	} finally {
+		done();
+	}
+}
+protected ISchedulingRule getSchedulingRule() {
+	if (this.pkgName.length == 0)
+		return null; // no resource is going to be created
+	IResource parentResource = ((JavaElement) getParentElement()).resource();
+	IResource resource = ((IContainer) parentResource).getFolder(new Path(this.pkgName[0]));
+	return resource.getWorkspace().getRuleFactory().createRule(resource);
+}
+/**
+ * Possible failures: <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - the root supplied to the operation is
+ * 		<code>null</code>.
+ *	<li>INVALID_NAME - the name provided to the operation
+ * 		is <code>null</code> or is not a valid package fragment name.
+ *	<li>READ_ONLY - the root provided to this operation is read only.
+ *	<li>NAME_COLLISION - there is a pre-existing resource (file)
+ * 		with the same name as a folder in the package fragment's hierarchy.
+ *	<li>ELEMENT_NOT_PRESENT - the underlying resource for the root is missing
+ * </ul>
+ * @see IJavaModelStatus
+ * @see JavaConventions
+ */
+public IJavaModelStatus verify() {
+	IJavaElement parentElement = getParentElement();
+	if (parentElement == null) {
+		return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+	}
+
+	String packageName = this.pkgName == null ? null : Util.concatWith(this.pkgName, '.');
+	IJavaProject project = parentElement.getJavaProject();
+	if (this.pkgName == null || (this.pkgName.length > 0 && JavaConventions.validatePackageName(packageName, project.getOption(JavaCore.COMPILER_SOURCE, true), project.getOption(JavaCore.COMPILER_COMPLIANCE, true)).getSeverity() == IStatus.ERROR)) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, packageName);
+	}
+	IJavaElement root = getParentElement();
+	if (root.isReadOnly()) {
+		return new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, root);
+	}
+	IContainer parentFolder = (IContainer) ((JavaElement) root).resource();
+	int i;
+	for (i = 0; i < this.pkgName.length; i++) {
+		IResource subFolder = parentFolder.findMember(this.pkgName[i]);
+		if (subFolder != null) {
+			if (subFolder.getType() != IResource.FOLDER) {
+				return new JavaModelStatus(
+					IJavaModelStatusConstants.NAME_COLLISION,
+					Messages.bind(Messages.status_nameCollision, subFolder.getFullPath().toString()));
+			}
+			parentFolder = (IContainer) subFolder;
+		}
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java
new file mode 100644
index 0000000..a355c65
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.internal.core.hierarchy.RegionBasedTypeHierarchy;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+
+/**
+ * This operation creates an <code>ITypeHierarchy</code> for a specific type within
+ * a specified region, or for all types within a region. The specified
+ * region limits the number of resolved subtypes (to the subset of
+ * types in the specified region). The resolved supertypes may go outside
+ * of the specified region in order to reach the root(s) of the type
+ * hierarchy. A Java Project is required to provide a context (classpath)
+ * to use while resolving supertypes and subtypes.
+ *
+ * @see ITypeHierarchy
+ */
+
+public class CreateTypeHierarchyOperation extends JavaModelOperation {
+	/**
+	 * The generated type hierarchy
+	 */
+	protected TypeHierarchy typeHierarchy;
+
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type within the specified region, in the context of
+ * the given project.
+ */
+public CreateTypeHierarchyOperation(IRegion region, ICompilationUnit[] workingCopies, IType element, boolean computeSubtypes) {
+	super(element);
+	this.typeHierarchy = new RegionBasedTypeHierarchy(region, workingCopies, element, computeSubtypes);
+}
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type and working copies.
+ */
+public CreateTypeHierarchyOperation(IType element, ICompilationUnit[] workingCopies, IJavaSearchScope scope, boolean computeSubtypes) {
+	super(element);
+	ICompilationUnit[] copies;
+	if (workingCopies != null) {
+		int length = workingCopies.length;
+		copies = new ICompilationUnit[length];
+		System.arraycopy(workingCopies, 0, copies, 0, length);
+	} else {
+		copies = null;
+	}
+	this.typeHierarchy = new TypeHierarchy(element, copies, scope, computeSubtypes);
+}
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type and working copies.
+ */
+public CreateTypeHierarchyOperation(IType element, ICompilationUnit[] workingCopies, IJavaProject project, boolean computeSubtypes) {
+	super(element);
+	ICompilationUnit[] copies;
+	if (workingCopies != null) {
+		int length = workingCopies.length;
+		copies = new ICompilationUnit[length];
+		System.arraycopy(workingCopies, 0, copies, 0, length);
+	} else {
+		copies = null;
+	}
+	this.typeHierarchy = new TypeHierarchy(element, copies, project, computeSubtypes);
+}
+/**
+ * Performs the operation - creates the type hierarchy
+ * @exception JavaModelException The operation has failed.
+ */
+protected void executeOperation() throws JavaModelException {
+	this.typeHierarchy.refresh(this);
+}
+/**
+ * Returns the generated type hierarchy.
+ */
+public ITypeHierarchy getResult() {
+	return this.typeHierarchy;
+}
+/**
+ * @see JavaModelOperation
+ */
+public boolean isReadOnly() {
+	return true;
+}
+/**
+ * Possible failures: <ul>
+ *	<li>NO_ELEMENTS_TO_PROCESS - at least one of a type or region must
+ *			be provided to generate a type hierarchy.
+ *	<li>ELEMENT_NOT_PRESENT - the provided type or type's project does not exist
+ * </ul>
+ */
+public IJavaModelStatus verify() {
+	IJavaElement elementToProcess= getElementToProcess();
+	if (elementToProcess == null && !(this.typeHierarchy instanceof RegionBasedTypeHierarchy)) {
+		return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+	}
+	if (elementToProcess != null && !elementToProcess.exists()) {
+		return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, elementToProcess);
+	}
+	IJavaProject project = this.typeHierarchy.javaProject();
+	if (project != null && !project.exists()) {
+		return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, project);
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
new file mode 100644
index 0000000..0824286
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * Implements functionality common to
+ * operations that create type members.
+ */
+public abstract class CreateTypeMemberOperation extends CreateElementInCUOperation {
+	/**
+	 * The source code for the new member.
+	 */
+	protected String source = null;
+	/**
+	 * The name of the <code>ASTNode</code> that may be used to
+	 * create this new element.
+	 * Used by the <code>CopyElementsOperation</code> for renaming
+	 */
+	protected String alteredName;
+	/**
+	 * The AST node representing the element that
+	 * this operation created.
+	 */
+	 protected ASTNode createdNode;
+/**
+ * When executed, this operation will create a type member
+ * in the given parent element with the specified source.
+ */
+public CreateTypeMemberOperation(IJavaElement parentElement, String source, boolean force) {
+	super(parentElement);
+	this.source = source;
+	this.force = force;
+}
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	switch (parent.getNodeType()) {
+		case ASTNode.COMPILATION_UNIT:
+			return CompilationUnit.TYPES_PROPERTY;
+		case ASTNode.ENUM_DECLARATION:
+			return EnumDeclaration.BODY_DECLARATIONS_PROPERTY;
+		case ASTNode.ANNOTATION_TYPE_DECLARATION:
+			return AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY;
+		default:
+			return TypeDeclaration.BODY_DECLARATIONS_PROPERTY;
+	}
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	if (this.createdNode == null) {
+		this.source = removeIndentAndNewLines(this.source, cu);
+		ASTParser parser = ASTParser.newParser(AST.JLS8);
+		parser.setSource(this.source.toCharArray());
+		parser.setProject(getCompilationUnit().getJavaProject());
+		parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);
+		ASTNode node = parser.createAST(this.progressMonitor);
+		String createdNodeSource;
+		if (node.getNodeType() != ASTNode.TYPE_DECLARATION) {
+			createdNodeSource = generateSyntaxIncorrectAST();
+			if (this.createdNode == null)
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+		} else {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) node;
+			if ((typeDeclaration.getFlags() & ASTNode.MALFORMED) != 0) {
+				createdNodeSource = generateSyntaxIncorrectAST();
+				if (this.createdNode == null)
+					throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+			} else {
+				List bodyDeclarations = typeDeclaration.bodyDeclarations();
+				if (bodyDeclarations.size() == 0) {
+					throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+				}
+				this.createdNode = (ASTNode) bodyDeclarations.iterator().next();
+				createdNodeSource = this.source;
+			}
+		}
+		if (this.alteredName != null) {
+			SimpleName newName = this.createdNode.getAST().newSimpleName(this.alteredName);
+			SimpleName oldName = rename(this.createdNode, newName);
+			int nameStart = oldName.getStartPosition();
+			int nameEnd = nameStart + oldName.getLength();
+			StringBuffer newSource = new StringBuffer();
+			if (this.source.equals(createdNodeSource)) {
+				newSource.append(createdNodeSource.substring(0, nameStart));
+				newSource.append(this.alteredName);
+				newSource.append(createdNodeSource.substring(nameEnd));
+			} else {
+				// syntactically incorrect source
+				int createdNodeStart = this.createdNode.getStartPosition();
+				int createdNodeEnd = createdNodeStart + this.createdNode.getLength();
+				newSource.append(createdNodeSource.substring(createdNodeStart, nameStart));
+				newSource.append(this.alteredName);
+				newSource.append(createdNodeSource.substring(nameEnd, createdNodeEnd));
+
+			}
+			this.source = newSource.toString();
+		}
+	}
+	if (rewriter == null) return this.createdNode;
+	// return a string place holder (instead of the created node) so has to not lose comments and formatting
+	return rewriter.createStringPlaceholder(this.source, this.createdNode.getNodeType());
+}
+private String removeIndentAndNewLines(String code, ICompilationUnit cu) throws JavaModelException {
+	IJavaProject project = cu.getJavaProject();
+	Map options = project.getOptions(true/*inherit JavaCore options*/);
+	int tabWidth = IndentManipulation.getTabWidth(options);
+	int indentWidth = IndentManipulation.getIndentWidth(options);
+	int indent = IndentManipulation.measureIndentUnits(code, tabWidth, indentWidth);
+	int firstNonWhiteSpace = -1;
+	int length = code.length();
+	while (firstNonWhiteSpace < length-1)
+		if (!ScannerHelper.isWhitespace(code.charAt(++firstNonWhiteSpace)))
+			break;
+	int lastNonWhiteSpace = length;
+	while (lastNonWhiteSpace > 0)
+		if (!ScannerHelper.isWhitespace(code.charAt(--lastNonWhiteSpace)))
+			break;
+	String lineDelimiter = cu.findRecommendedLineSeparator();
+	return IndentManipulation.changeIndent(code.substring(firstNonWhiteSpace, lastNonWhiteSpace+1), indent, tabWidth, indentWidth, "", lineDelimiter); //$NON-NLS-1$
+}
+/*
+ * Renames the given node to the given name.
+ * Returns the old name.
+ */
+protected abstract SimpleName rename(ASTNode node, SimpleName newName);
+/**
+ * Generates an <code>ASTNode</code> based on the source of this operation
+ * when there is likely a syntax error in the source.
+ * Returns the source used to generate this node.
+ */
+protected String generateSyntaxIncorrectAST() {
+	//create some dummy source to generate an ast node
+	StringBuffer buff = new StringBuffer();
+	IType type = getType();
+	String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(this.source, type == null ? null : type.getJavaProject());
+	buff.append(lineSeparator + " public class A {" + lineSeparator); //$NON-NLS-1$
+	buff.append(this.source);
+	buff.append(lineSeparator).append('}');
+	ASTParser parser = ASTParser.newParser(AST.JLS8);
+	parser.setSource(buff.toString().toCharArray());
+	CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
+	TypeDeclaration typeDeclaration = (TypeDeclaration) compilationUnit.types().iterator().next();
+	List bodyDeclarations = typeDeclaration.bodyDeclarations();
+	if (bodyDeclarations.size() != 0)
+		this.createdNode = (ASTNode) bodyDeclarations.iterator().next();
+	return buff.toString();
+}
+/**
+ * Returns the IType the member is to be created in.
+ */
+protected IType getType() {
+	return (IType)getParentElement();
+}
+/**
+ * Sets the name of the <code>ASTNode</code> that will be used to
+ * create this new element.
+ * Used by the <code>CopyElementsOperation</code> for renaming
+ */
+protected void setAlteredName(String newName) {
+	this.alteredName = newName;
+}
+/**
+ * Possible failures: <ul>
+ *  <li>NO_ELEMENTS_TO_PROCESS - the parent element supplied to the operation is
+ * 		<code>null</code>.
+ *	<li>INVALID_CONTENTS - The source is <code>null</code> or has serious syntax errors.
+  *	<li>NAME_COLLISION - A name collision occurred in the destination
+ * </ul>
+ */
+public IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (!status.isOK()) {
+		return status;
+	}
+	if (this.source == null) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS);
+	}
+	if (!this.force) {
+		//check for name collisions
+		try {
+			ICompilationUnit cu = getCompilationUnit();
+			generateElementAST(null, cu);
+		} catch (JavaModelException jme) {
+			return jme.getJavaModelStatus();
+		}
+		return verifyNameCollision();
+	}
+
+	return JavaModelStatus.VERIFIED_OK;
+}
+/**
+ * Verify for a name collision in the destination container.
+ */
+protected IJavaModelStatus verifyNameCollision() {
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java
new file mode 100644
index 0000000..f9f6eb3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * <p>This operation creates a class or interface.
+ *
+ * <p>Required Attributes:<ul>
+ *  <li>Parent element - must be a compilation unit, or type.
+ *  <li>The source code for the type. No verification of the source is
+ *      performed.
+ * </ul>
+ */
+public class CreateTypeOperation extends CreateTypeMemberOperation {
+/**
+ * When executed, this operation will create a type unit
+ * in the given parent element (a compilation unit, type)
+ */
+public CreateTypeOperation(IJavaElement parentElement, String source, boolean force) {
+	super(parentElement, source, force);
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, cu);
+	if (!(node instanceof AbstractTypeDeclaration))
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+	return node;
+}
+
+/**
+ * @see CreateElementInCUOperation#generateResultHandle()
+ */
+protected IJavaElement generateResultHandle() {
+	IJavaElement parent= getParentElement();
+	switch (parent.getElementType()) {
+		case IJavaElement.COMPILATION_UNIT:
+			return ((ICompilationUnit)parent).getType(getASTNodeName());
+		case IJavaElement.TYPE:
+			return ((IType)parent).getType(getASTNodeName());
+		// Note: creating local/anonymous type is not supported
+	}
+	return null;
+}
+/**
+ * @see CreateElementInCUOperation#getMainTaskName()
+ */
+public String getMainTaskName(){
+	return Messages.operation_createTypeProgress;
+}
+/**
+ * Returns the <code>IType</code> the member is to be created in.
+ */
+protected IType getType() {
+	IJavaElement parent = getParentElement();
+	if (parent.getElementType() == IJavaElement.TYPE) {
+		return (IType) parent;
+	}
+	return null;
+}
+/**
+ * @see CreateTypeMemberOperation#verifyNameCollision
+ */
+protected IJavaModelStatus verifyNameCollision() {
+	IJavaElement parent = getParentElement();
+	switch (parent.getElementType()) {
+		case IJavaElement.COMPILATION_UNIT:
+			String typeName = getASTNodeName();
+			if (((ICompilationUnit) parent).getType(typeName).exists()) {
+				return new JavaModelStatus(
+					IJavaModelStatusConstants.NAME_COLLISION,
+					Messages.bind(Messages.status_nameCollision, typeName));
+			}
+			break;
+		case IJavaElement.TYPE:
+			typeName = getASTNodeName();
+			if (((IType) parent).getType(typeName).exists()) {
+				return new JavaModelStatus(
+					IJavaModelStatusConstants.NAME_COLLISION,
+					Messages.bind(Messages.status_nameCollision, typeName));
+			}
+			break;
+		// Note: creating local/anonymous type is not supported
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+public IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (!status.isOK())
+		return status;
+	try {
+		IJavaElement parent = getParentElement();
+		if (this.anchorElement != null && this.anchorElement.getElementType() == IJavaElement.FIELD
+				&& parent.getElementType() == IJavaElement.TYPE && ((IType)parent).isEnum())
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, this.anchorElement);
+	} catch (JavaModelException e) {
+		return e.getJavaModelStatus();
+	}
+	return JavaModelStatus.VERIFIED_OK;
+}
+private String getASTNodeName() {
+	return ((AbstractTypeDeclaration) this.createdNode).getName().getIdentifier();
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	AbstractTypeDeclaration type = (AbstractTypeDeclaration) node;
+	SimpleName oldName = type.getName();
+	type.setName(newName);
+	return oldName;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java
new file mode 100644
index 0000000..ec607df
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+
+/**
+ * A working copy owner that creates internal buffers.
+ * It also defines the PRIMARY working copy owner that is used by JDT/Core.
+ */
+public class DefaultWorkingCopyOwner extends WorkingCopyOwner {
+
+	public WorkingCopyOwner primaryBufferProvider;
+
+	public static final DefaultWorkingCopyOwner PRIMARY =  new DefaultWorkingCopyOwner();
+
+	private DefaultWorkingCopyOwner() {
+		// only one instance can be created
+	}
+
+	public IBuffer createBuffer(ICompilationUnit workingCopy) {
+		if (this.primaryBufferProvider != null) return this.primaryBufferProvider.createBuffer(workingCopy);
+		return super.createBuffer(workingCopy);
+	}
+	public String toString() {
+		return "Primary owner"; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java
new file mode 100644
index 0000000..c4df538
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * This operation deletes a collection of elements (and
+ * all of their children).
+ * If an element does not exist, it is ignored.
+ *
+ * <p>NOTE: This operation only deletes elements contained within leaf resources -
+ * that is, elements within compilation units. To delete a compilation unit or
+ * a package, etc (which have an actual resource), a DeleteResourcesOperation
+ * should be used.
+ */
+public class DeleteElementsOperation extends MultiOperation {
+	/**
+	 * The elements this operation processes grouped by compilation unit
+	 * @see #processElements() Keys are compilation units,
+	 * values are <code>IRegion</code>s of elements to be processed in each
+	 * compilation unit.
+	 */
+	protected Map childrenToRemove;
+	/**
+	 * The <code>ASTParser</code> used to manipulate the source code of
+	 * <code>ICompilationUnit</code>.
+	 */
+	protected ASTParser parser;
+	/**
+	 * When executed, this operation will delete the given elements. The elements
+	 * to delete cannot be <code>null</code> or empty, and must be contained within a
+	 * compilation unit.
+	 */
+	public DeleteElementsOperation(IJavaElement[] elementsToDelete, boolean force) {
+		super(elementsToDelete, force);
+		initASTParser();
+	}
+
+	private void deleteElement(IJavaElement elementToRemove, ICompilationUnit cu) throws JavaModelException {
+		// ensure cu is consistent (noop if already consistent)
+		cu.makeConsistent(this.progressMonitor);
+		this.parser.setSource(cu);
+		CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+		ASTNode node = ((JavaElement) elementToRemove).findNode(astCU);
+		if (node == null)
+			Assert.isTrue(false, "Failed to locate " + elementToRemove.getElementName() + " in " + cu.getElementName()); //$NON-NLS-1$//$NON-NLS-2$
+		AST ast = astCU.getAST();
+		ASTRewrite rewriter = ASTRewrite.create(ast);
+		rewriter.remove(node, null);
+ 		TextEdit edits = rewriter.rewriteAST();
+ 		applyTextEdit(cu, edits);
+	}
+
+	private void initASTParser() {
+		this.parser = ASTParser.newParser(AST.JLS8);
+	}
+
+	/**
+	 * @see MultiOperation
+	 */
+	protected String getMainTaskName() {
+		return Messages.operation_deleteElementProgress;
+	}
+	protected ISchedulingRule getSchedulingRule() {
+		if (this.elementsToProcess != null && this.elementsToProcess.length == 1) {
+			IResource resource = this.elementsToProcess[0].getResource();
+			if (resource != null)
+				return ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(resource);
+		}
+		return super.getSchedulingRule();
+	}
+	/**
+	 * Groups the elements to be processed by their compilation unit.
+	 * If parent/child combinations are present, children are
+	 * discarded (only the parents are processed). Removes any
+	 * duplicates specified in elements to be processed.
+	 */
+	protected void groupElements() throws JavaModelException {
+		this.childrenToRemove = new HashMap(1);
+		int uniqueCUs = 0;
+		for (int i = 0, length = this.elementsToProcess.length; i < length; i++) {
+			IJavaElement e = this.elementsToProcess[i];
+			ICompilationUnit cu = getCompilationUnitFor(e);
+			if (cu == null) {
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, e));
+			} else {
+				IRegion region = (IRegion) this.childrenToRemove.get(cu);
+				if (region == null) {
+					region = new Region();
+					this.childrenToRemove.put(cu, region);
+					uniqueCUs += 1;
+				}
+				region.add(e);
+			}
+		}
+		this.elementsToProcess = new IJavaElement[uniqueCUs];
+		Iterator iter = this.childrenToRemove.keySet().iterator();
+		int i = 0;
+		while (iter.hasNext()) {
+			this.elementsToProcess[i++] = (IJavaElement) iter.next();
+		}
+	}
+	/**
+	 * Deletes this element from its compilation unit.
+	 * @see MultiOperation
+	 */
+	protected void processElement(IJavaElement element) throws JavaModelException {
+		ICompilationUnit cu = (ICompilationUnit) element;
+
+		// keep track of the import statements - if all are removed, delete
+		// the import container (and report it in the delta)
+		int numberOfImports = cu.getImports().length;
+
+		JavaElementDelta delta = new JavaElementDelta(cu);
+		IJavaElement[] cuElements = ((IRegion) this.childrenToRemove.get(cu)).getElements();
+		for (int i = 0, length = cuElements.length; i < length; i++) {
+			IJavaElement e = cuElements[i];
+			if (e.exists()) {
+				deleteElement(e, cu);
+				delta.removed(e);
+				if (e.getElementType() == IJavaElement.IMPORT_DECLARATION) {
+					numberOfImports--;
+					if (numberOfImports == 0) {
+						delta.removed(cu.getImportContainer());
+					}
+				}
+			}
+		}
+		if (delta.getAffectedChildren().length > 0) {
+			cu.save(getSubProgressMonitor(1), this.force);
+			if (!cu.isWorkingCopy()) { // if unit is working copy, then save will have already fired the delta
+				addDelta(delta);
+				setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+			}
+		}
+	}
+	/**
+	 * @see MultiOperation
+	 * This method first group the elements by <code>ICompilationUnit</code>,
+	 * and then processes the <code>ICompilationUnit</code>.
+	 */
+	protected void processElements() throws JavaModelException {
+		groupElements();
+		super.processElements();
+	}
+	/**
+	 * @see MultiOperation
+	 */
+	protected void verify(IJavaElement element) throws JavaModelException {
+		IJavaElement[] children = ((IRegion) this.childrenToRemove.get(element)).getElements();
+		for (int i = 0; i < children.length; i++) {
+			IJavaElement child = children[i];
+			if (child.getCorrespondingResource() != null)
+				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, child);
+
+			if (child.isReadOnly())
+				error(IJavaModelStatusConstants.READ_ONLY, child);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java
new file mode 100644
index 0000000..7e0eff4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+
+public class DeletePackageFragmentRootOperation extends JavaModelOperation {
+
+	int updateResourceFlags;
+	int updateModelFlags;
+
+	public DeletePackageFragmentRootOperation(
+		IPackageFragmentRoot root,
+		int updateResourceFlags,
+		int updateModelFlags) {
+
+		super(root);
+		this.updateResourceFlags = updateResourceFlags;
+		this.updateModelFlags = updateModelFlags;
+	}
+
+	protected void executeOperation() throws JavaModelException {
+
+		IPackageFragmentRoot root = (IPackageFragmentRoot)getElementToProcess();
+		IClasspathEntry rootEntry = root.getRawClasspathEntry();
+
+		// remember olds roots
+		DeltaProcessor deltaProcessor = JavaModelManager.getJavaModelManager().getDeltaProcessor();
+		if (deltaProcessor.oldRoots == null)
+			deltaProcessor.oldRoots = new HashMap();
+
+		// update classpath if needed
+		if ((this.updateModelFlags & IPackageFragmentRoot.ORIGINATING_PROJECT_CLASSPATH) != 0) {
+			updateProjectClasspath(rootEntry.getPath(), root.getJavaProject(), deltaProcessor.oldRoots);
+		}
+		if ((this.updateModelFlags & IPackageFragmentRoot.OTHER_REFERRING_PROJECTS_CLASSPATH) != 0) {
+			updateReferringProjectClasspaths(rootEntry.getPath(), root.getJavaProject(), deltaProcessor.oldRoots);
+		}
+
+		// delete resource
+		if (!root.isExternal() && (this.updateModelFlags & IPackageFragmentRoot.NO_RESOURCE_MODIFICATION) == 0) {
+			deleteResource(root, rootEntry);
+		}
+	}
+
+	protected void deleteResource(
+		IPackageFragmentRoot root,
+		IClasspathEntry rootEntry)
+		throws JavaModelException {
+		final char[][] exclusionPatterns = ((ClasspathEntry)rootEntry).fullExclusionPatternChars();
+		IResource rootResource = ((JavaElement) root).resource();
+		if (rootEntry.getEntryKind() != IClasspathEntry.CPE_SOURCE || exclusionPatterns == null) {
+			try {
+				rootResource.delete(this.updateResourceFlags, this.progressMonitor);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		} else {
+			final IPath[] nestedFolders = getNestedFolders(root);
+			IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+				public boolean visit(IResourceProxy proxy) throws CoreException {
+					if (proxy.getType() == IResource.FOLDER) {
+						IPath path = proxy.requestFullPath();
+						if (prefixesOneOf(path, nestedFolders)) {
+							// equals if nested source folder
+							return !equalsOneOf(path, nestedFolders);
+						} else {
+							// subtree doesn't contain any nested source folders
+							proxy.requestResource().delete(DeletePackageFragmentRootOperation.this.updateResourceFlags, DeletePackageFragmentRootOperation.this.progressMonitor);
+							return false;
+						}
+					} else {
+						proxy.requestResource().delete(DeletePackageFragmentRootOperation.this.updateResourceFlags, DeletePackageFragmentRootOperation.this.progressMonitor);
+						return false;
+					}
+				}
+			};
+			try {
+				rootResource.accept(visitor, IResource.NONE);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		}
+		setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+	}
+
+
+	/*
+	 * Deletes the classpath entries equals to the given rootPath from all Java projects.
+	 */
+	protected void updateReferringProjectClasspaths(IPath rootPath, IJavaProject projectOfRoot, Map oldRoots) throws JavaModelException {
+		IJavaModel model = getJavaModel();
+		IJavaProject[] projects = model.getJavaProjects();
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IJavaProject project = projects[i];
+			if (project.equals(projectOfRoot)) continue;
+			updateProjectClasspath(rootPath, project, oldRoots);
+		}
+	}
+
+	/*
+	 * Deletes the classpath entries equals to the given rootPath from the given project.
+	 */
+	protected void updateProjectClasspath(IPath rootPath, IJavaProject project, Map oldRoots) throws JavaModelException {
+		// remember old roots
+		oldRoots.put(project, project.getPackageFragmentRoots());
+
+		IClasspathEntry[] classpath = project.getRawClasspath();
+		IClasspathEntry[] newClasspath = null;
+		int cpLength = classpath.length;
+		int newCPIndex = -1;
+		for (int j = 0; j < cpLength; j++) {
+			IClasspathEntry entry = classpath[j];
+			if (rootPath.equals(entry.getPath())) {
+				if (newClasspath == null) {
+					newClasspath = new IClasspathEntry[cpLength-1];
+					System.arraycopy(classpath, 0, newClasspath, 0, j);
+					newCPIndex = j;
+				}
+			} else if (newClasspath != null) {
+				newClasspath[newCPIndex++] = entry;
+			}
+		}
+		if (newClasspath != null) {
+			if (newCPIndex < newClasspath.length) {
+				System.arraycopy(newClasspath, 0, newClasspath = new IClasspathEntry[newCPIndex], 0, newCPIndex);
+			}
+			project.setRawClasspath(newClasspath, this.progressMonitor);
+		}
+	}
+	protected IJavaModelStatus verify() {
+		IJavaModelStatus status = super.verify();
+		if (!status.isOK()) {
+			return status;
+		}
+		IJavaElement root = getElementToProcess();
+		if (root == null || !root.exists()) {
+			return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, root);
+		}
+
+		IResource resource = ((JavaElement) root).resource();
+		if (resource instanceof IFolder) {
+			if (resource.isLinked()) {
+				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE, root);
+			}
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java
new file mode 100644
index 0000000..7709a4d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IOpenable;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation deletes a collection of resources and all of their children.
+ * It does not delete resources which do not belong to the Java Model
+ * (eg GIF files).
+ */
+public class DeleteResourceElementsOperation extends MultiOperation {
+/**
+ * When executed, this operation will delete the given elements. The elements
+ * to delete cannot be <code>null</code> or empty, and must have a corresponding
+ * resource.
+ */
+protected DeleteResourceElementsOperation(IJavaElement[] elementsToProcess, boolean force) {
+	super(elementsToProcess, force);
+}
+/**
+ * Deletes the direct children of <code>frag</code> corresponding to its kind
+ * (K_SOURCE or K_BINARY), and deletes the corresponding folder if it is then
+ * empty.
+ */
+private void deletePackageFragment(IPackageFragment frag)
+	throws JavaModelException {
+	IResource res = ((JavaElement) frag).resource();
+	if (res != null) {
+		// collect the children to remove
+		IJavaElement[] childrenOfInterest = frag.getChildren();
+		if (childrenOfInterest.length > 0) {
+			IResource[] resources = new IResource[childrenOfInterest.length];
+			// remove the children
+			for (int i = 0; i < childrenOfInterest.length; i++) {
+				resources[i] = ((JavaElement) childrenOfInterest[i]).resource();
+			}
+			deleteResources(resources, this.force);
+		}
+
+		// Discard non-java resources
+		Object[] nonJavaResources = frag.getNonJavaResources();
+		int actualResourceCount = 0;
+		for (int i = 0, max = nonJavaResources.length; i < max; i++){
+			if (nonJavaResources[i] instanceof IResource) actualResourceCount++;
+		}
+		IResource[] actualNonJavaResources = new IResource[actualResourceCount];
+		for (int i = 0, max = nonJavaResources.length, index = 0; i < max; i++){
+			if (nonJavaResources[i] instanceof IResource) actualNonJavaResources[index++] = (IResource)nonJavaResources[i];
+		}
+		deleteResources(actualNonJavaResources, this.force);
+
+		// delete remaining files in this package (.class file in the case where Proj=src=bin)
+		IResource[] remainingFiles;
+		try {
+			remainingFiles = ((IContainer) res).members();
+		} catch (CoreException ce) {
+			throw new JavaModelException(ce);
+		}
+		boolean isEmpty = true;
+		for (int i = 0, length = remainingFiles.length; i < length; i++) {
+			IResource file = remainingFiles[i];
+			if (file instanceof IFile && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(file.getName())) {
+				deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY);
+			} else {
+				isEmpty = false;
+			}
+		}
+		if (isEmpty && !frag.isDefaultPackage()/*don't delete default package's folder: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38450*/) {
+			// delete recursively empty folders
+			IResource fragResource =  ((JavaElement) frag).resource();
+			if (fragResource != null) {
+				deleteEmptyPackageFragment(frag, false, fragResource.getParent());
+			}
+		}
+	}
+}
+/**
+ * @see MultiOperation
+ */
+protected String getMainTaskName() {
+	return Messages.operation_deleteResourceProgress;
+}
+/**
+ * @see MultiOperation This method delegate to <code>deleteResource</code> or
+ * <code>deletePackageFragment</code> depending on the type of <code>element</code>.
+ */
+protected void processElement(IJavaElement element) throws JavaModelException {
+	switch (element.getElementType()) {
+		case IJavaElement.CLASS_FILE :
+		case IJavaElement.COMPILATION_UNIT :
+			deleteResource(element.getResource(), this.force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT :
+			deletePackageFragment((IPackageFragment) element);
+			break;
+		default :
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element));
+	}
+	// ensure the element is closed
+	if (element instanceof IOpenable) {
+		((IOpenable)element).close();
+	}
+}
+/**
+ * @see MultiOperation
+ */
+protected void verify(IJavaElement element) throws JavaModelException {
+	if (element == null || !element.exists())
+		error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
+
+	int type = element.getElementType();
+	if (type <= IJavaElement.PACKAGE_FRAGMENT_ROOT || type > IJavaElement.COMPILATION_UNIT)
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+	else if (type == IJavaElement.PACKAGE_FRAGMENT && element instanceof JarPackageFragment)
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+	IResource resource = ((JavaElement) element).resource();
+	if (resource instanceof IFolder) {
+		if (resource.isLinked()) {
+			error(IJavaModelStatusConstants.INVALID_RESOURCE, element);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
new file mode 100644
index 0000000..6f94386
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
@@ -0,0 +1,639 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Keep the global states used during Java element delta processing.
+ */
+public class DeltaProcessingState implements IResourceChangeListener {
+
+	/*
+	 * Collection of listeners for Java element deltas
+	 */
+	public IElementChangedListener[] elementChangedListeners = new IElementChangedListener[5];
+	public int[] elementChangedListenerMasks = new int[5];
+	public int elementChangedListenerCount = 0;
+
+	/*
+	 * Collection of pre Java resource change listeners
+	 */
+	public IResourceChangeListener[] preResourceChangeListeners = new IResourceChangeListener[1];
+	public int[] preResourceChangeEventMasks = new int[1];
+	public int preResourceChangeListenerCount = 0;
+
+	/*
+	 * The delta processor for the current thread.
+	 */
+	private ThreadLocal deltaProcessors = new ThreadLocal();
+	
+	public void doNotUse() {
+		// reset the delta processor of the current thread to avoid to keep it in memory
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=269476
+		this.deltaProcessors.set(null);
+	}
+
+	/* A table from IPath (from a classpath entry) to DeltaProcessor.RootInfo */
+	public HashMap roots = new HashMap();
+
+	/* A table from IPath (from a classpath entry) to ArrayList of DeltaProcessor.RootInfo
+	 * Used when an IPath corresponds to more than one root */
+	public HashMap otherRoots = new HashMap();
+
+	/* A table from IPath (from a classpath entry) to DeltaProcessor.RootInfo
+	 * from the last time the delta processor was invoked. */
+	public HashMap oldRoots = new HashMap();
+
+	/* A table from IPath (from a classpath entry) to ArrayList of DeltaProcessor.RootInfo
+	 * from the last time the delta processor was invoked.
+	 * Used when an IPath corresponds to more than one root */
+	public HashMap oldOtherRoots = new HashMap();
+
+	/* A table from IPath (a source attachment path from a classpath entry) to IPath (a root path) */
+	public HashMap sourceAttachments = new HashMap();
+
+	/* A table from IJavaProject to IJavaProject[] (the list of direct dependent of the key) */
+	public HashMap projectDependencies = new HashMap();
+
+	/* Whether the roots tables should be recomputed */
+	public boolean rootsAreStale = true;
+
+	/* Threads that are currently running initializeRoots() */
+	private Set initializingThreads = Collections.synchronizedSet(new HashSet());
+
+	/* A table from file system absoulte path (String) to timestamp (Long) */
+	public Hashtable externalTimeStamps;
+
+	/*
+	 * Map from IProject to ClasspathChange
+	 * Note these changes need to be kept on the delta processing state to ensure we don't loose them
+	 * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=271102 Java model corrupt after switching target platform)
+	 */
+	private HashMap classpathChanges = new HashMap();
+
+	/* A table from JavaProject to ClasspathValidation */
+	private HashMap classpathValidations = new HashMap();
+
+	/* A table from JavaProject to ProjectReferenceChange */
+	private HashMap projectReferenceChanges = new HashMap();
+
+	/* A table from JavaProject to ExternalFolderChange */
+	private HashMap externalFolderChanges = new HashMap();
+
+	/**
+	 * Workaround for bug 15168 circular errors not reported
+	 * This is a cache of the projects before any project addition/deletion has started.
+	 */
+	private HashSet javaProjectNamesCache;
+
+	/*
+	 * A list of IJavaElement used as a scope for external archives refresh during POST_CHANGE.
+	 * This is null if no refresh is needed.
+	 */
+	private HashSet externalElementsToRefresh;
+
+	/*
+	 * Need to clone defensively the listener information, in case some listener is reacting to some notification iteration by adding/changing/removing
+	 * any of the other (for example, if it deregisters itself).
+	 */
+	public synchronized void addElementChangedListener(IElementChangedListener listener, int eventMask) {
+		for (int i = 0; i < this.elementChangedListenerCount; i++){
+			if (this.elementChangedListeners[i] == listener){
+
+				// only clone the masks, since we could be in the middle of notifications and one listener decide to change
+				// any event mask of another listeners (yet not notified).
+				int cloneLength = this.elementChangedListenerMasks.length;
+				System.arraycopy(this.elementChangedListenerMasks, 0, this.elementChangedListenerMasks = new int[cloneLength], 0, cloneLength);
+				this.elementChangedListenerMasks[i] |= eventMask; // could be different
+				return;
+			}
+		}
+		// may need to grow, no need to clone, since iterators will have cached original arrays and max boundary and we only add to the end.
+		int length;
+		if ((length = this.elementChangedListeners.length) == this.elementChangedListenerCount){
+			System.arraycopy(this.elementChangedListeners, 0, this.elementChangedListeners = new IElementChangedListener[length*2], 0, length);
+			System.arraycopy(this.elementChangedListenerMasks, 0, this.elementChangedListenerMasks = new int[length*2], 0, length);
+		}
+		this.elementChangedListeners[this.elementChangedListenerCount] = listener;
+		this.elementChangedListenerMasks[this.elementChangedListenerCount] = eventMask;
+		this.elementChangedListenerCount++;
+	}
+
+	/*
+	 * Adds the given element to the list of elements used as a scope for external jars refresh.
+	 */
+	public synchronized void addForRefresh(IJavaElement externalElement) {
+		if (this.externalElementsToRefresh == null) {
+			this.externalElementsToRefresh = new HashSet();
+		}
+		this.externalElementsToRefresh.add(externalElement);
+	}
+
+	public synchronized void addPreResourceChangedListener(IResourceChangeListener listener, int eventMask) {
+		for (int i = 0; i < this.preResourceChangeListenerCount; i++){
+			if (this.preResourceChangeListeners[i] == listener) {
+				this.preResourceChangeEventMasks[i] |= eventMask;
+				return;
+			}
+		}
+		// may need to grow, no need to clone, since iterators will have cached original arrays and max boundary and we only add to the end.
+		int length;
+		if ((length = this.preResourceChangeListeners.length) == this.preResourceChangeListenerCount) {
+			System.arraycopy(this.preResourceChangeListeners, 0, this.preResourceChangeListeners = new IResourceChangeListener[length*2], 0, length);
+			System.arraycopy(this.preResourceChangeEventMasks, 0, this.preResourceChangeEventMasks = new int[length*2], 0, length);
+		}
+		this.preResourceChangeListeners[this.preResourceChangeListenerCount] = listener;
+		this.preResourceChangeEventMasks[this.preResourceChangeListenerCount] = eventMask;
+		this.preResourceChangeListenerCount++;
+	}
+
+	public DeltaProcessor getDeltaProcessor() {
+		DeltaProcessor deltaProcessor = (DeltaProcessor)this.deltaProcessors.get();
+		if (deltaProcessor != null) return deltaProcessor;
+		deltaProcessor = new DeltaProcessor(this, JavaModelManager.getJavaModelManager());
+		this.deltaProcessors.set(deltaProcessor);
+		return deltaProcessor;
+	}
+
+	public synchronized ClasspathChange addClasspathChange(IProject project, IClasspathEntry[] oldRawClasspath, IPath oldOutputLocation, IClasspathEntry[] oldResolvedClasspath) {
+		ClasspathChange change = (ClasspathChange) this.classpathChanges.get(project);
+		if (change == null) {
+			change = new ClasspathChange((JavaProject) JavaModelManager.getJavaModelManager().getJavaModel().getJavaProject(project), oldRawClasspath, oldOutputLocation, oldResolvedClasspath);
+			this.classpathChanges.put(project, change);
+		} else {
+			if (change.oldRawClasspath == null)
+				change.oldRawClasspath = oldRawClasspath;
+			if (change.oldOutputLocation == null)
+				change.oldOutputLocation = oldOutputLocation;
+			if (change.oldResolvedClasspath == null)
+				change.oldResolvedClasspath = oldResolvedClasspath;
+		}
+		return change;
+	}
+	
+	public synchronized ClasspathChange getClasspathChange(IProject project) {
+		return (ClasspathChange) this.classpathChanges.get(project);
+	}
+	
+	public synchronized HashMap removeAllClasspathChanges() {
+		HashMap result = this.classpathChanges;
+		this.classpathChanges = new HashMap(result.size());
+		return result;
+	}
+
+	public synchronized ClasspathValidation addClasspathValidation(JavaProject project) {
+		ClasspathValidation validation = (ClasspathValidation) this.classpathValidations.get(project);
+		if (validation == null) {
+			validation = new ClasspathValidation(project);
+			this.classpathValidations.put(project, validation);
+	    }
+		return validation;
+	}
+
+	public synchronized void addExternalFolderChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
+		ExternalFolderChange change = (ExternalFolderChange) this.externalFolderChanges.get(project);
+		if (change == null) {
+			change = new ExternalFolderChange(project, oldResolvedClasspath);
+			this.externalFolderChanges.put(project, change);
+	    }
+	}
+
+	public synchronized void addProjectReferenceChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
+		ProjectReferenceChange change = (ProjectReferenceChange) this.projectReferenceChanges.get(project);
+		if (change == null) {
+			change = new ProjectReferenceChange(project, oldResolvedClasspath);
+			this.projectReferenceChanges.put(project, change);
+	    }
+	}
+
+	public void initializeRoots(boolean initAfterLoad) {
+
+		// recompute root infos only if necessary
+		HashMap[] rootInfos = null;
+		if (this.rootsAreStale) {
+			Thread currentThread = Thread.currentThread();
+			boolean addedCurrentThread = false;
+			try {
+				// if reentering initialization (through a container initializer for example) no need to compute roots again
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=47213
+				if (!this.initializingThreads.add(currentThread)) return;
+				addedCurrentThread = true;
+
+				// all classpaths in the workspace are going to be resolved
+				// ensure that containers are initialized in one batch
+				JavaModelManager.getJavaModelManager().forceBatchInitializations(initAfterLoad);
+
+				rootInfos = getRootInfos(false/*don't use previous session values*/);
+
+			} finally {
+				if (addedCurrentThread) {
+					this.initializingThreads.remove(currentThread);
+				}
+			}
+		}
+		synchronized(this) {
+			this.oldRoots = this.roots;
+			this.oldOtherRoots = this.otherRoots;
+			if (this.rootsAreStale && rootInfos != null) { // double check again
+				this.roots = rootInfos[0];
+				this.otherRoots = rootInfos[1];
+				this.sourceAttachments = rootInfos[2];
+				this.projectDependencies = rootInfos[3];
+				this.rootsAreStale = false;
+			}
+		}
+	}
+
+	synchronized void initializeRootsWithPreviousSession() {
+		HashMap[] rootInfos = getRootInfos(true/*use previous session values*/);
+		if (rootInfos != null) {
+			this.roots = rootInfos[0];
+			this.otherRoots = rootInfos[1];
+			this.sourceAttachments = rootInfos[2];
+			this.projectDependencies = rootInfos[3];
+			this.rootsAreStale = false;
+		}
+	}
+
+	private HashMap[] getRootInfos(boolean usePreviousSession) {
+		HashMap newRoots = new HashMap();
+		HashMap newOtherRoots = new HashMap();
+		HashMap newSourceAttachments = new HashMap();
+		HashMap newProjectDependencies = new HashMap();
+
+		IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+		IJavaProject[] projects;
+		try {
+			projects = model.getJavaProjects();
+		} catch (JavaModelException e) {
+			// nothing can be done
+			return null;
+		}
+		for (int i = 0, length = projects.length; i < length; i++) {
+			JavaProject project = (JavaProject) projects[i];
+			IClasspathEntry[] classpath;
+			try {
+				if (usePreviousSession) {
+					PerProjectInfo perProjectInfo = project.getPerProjectInfo();
+					project.resolveClasspath(perProjectInfo, true/*use previous session values*/, false/*don't add classpath change*/);
+					classpath = perProjectInfo.resolvedClasspath;
+				} else {
+					classpath = project.getResolvedClasspath();
+				}
+			} catch (JavaModelException e) {
+				// continue with next project
+				continue;
+			}
+			for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) {
+				IClasspathEntry entry = classpath[j];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+					IJavaProject key = model.getJavaProject(entry.getPath().segment(0)); // TODO (jerome) reuse handle
+					IJavaProject[] dependents = (IJavaProject[]) newProjectDependencies.get(key);
+					if (dependents == null) {
+						dependents = new IJavaProject[] {project};
+					} else {
+						int dependentsLength = dependents.length;
+						System.arraycopy(dependents, 0, dependents = new IJavaProject[dependentsLength+1], 0, dependentsLength);
+						dependents[dependentsLength] = project;
+					}
+					newProjectDependencies.put(key, dependents);
+					continue;
+				}
+
+				// root path
+				IPath path = entry.getPath();
+				if (newRoots.get(path) == null) {
+					newRoots.put(path, new DeltaProcessor.RootInfo(project, path, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), entry.getEntryKind()));
+				} else {
+					ArrayList rootList = (ArrayList)newOtherRoots.get(path);
+					if (rootList == null) {
+						rootList = new ArrayList();
+						newOtherRoots.put(path, rootList);
+					}
+					rootList.add(new DeltaProcessor.RootInfo(project, path, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), entry.getEntryKind()));
+				}
+
+				// source attachment path
+				if (entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY) continue;
+				String propertyString = null;
+				try {
+					propertyString = Util.getSourceAttachmentProperty(path);
+				} catch (JavaModelException e) {
+					e.printStackTrace();
+				}
+				IPath sourceAttachmentPath;
+				if (propertyString != null) {
+					int index= propertyString.lastIndexOf(PackageFragmentRoot.ATTACHMENT_PROPERTY_DELIMITER);
+					sourceAttachmentPath = (index < 0) ?  new Path(propertyString) : new Path(propertyString.substring(0, index));
+				} else {
+					sourceAttachmentPath = entry.getSourceAttachmentPath();
+				}
+				if (sourceAttachmentPath != null) {
+					newSourceAttachments.put(sourceAttachmentPath, path);
+				}
+			}
+		}
+		return new HashMap[] {newRoots, newOtherRoots, newSourceAttachments, newProjectDependencies};
+	}
+
+	public synchronized ClasspathValidation[] removeClasspathValidations() {
+	    int length = this.classpathValidations.size();
+	    if (length == 0) return null;
+	    ClasspathValidation[]  validations = new ClasspathValidation[length];
+	    this.classpathValidations.values().toArray(validations);
+	    this.classpathValidations.clear();
+	    return validations;
+	}
+
+	public synchronized ExternalFolderChange[] removeExternalFolderChanges() {
+	    int length = this.externalFolderChanges.size();
+	    if (length == 0) return null;
+	    ExternalFolderChange[]  updates = new ExternalFolderChange[length];
+	    this.externalFolderChanges.values().toArray(updates);
+	    this.externalFolderChanges.clear();
+	    return updates;
+	}
+
+	public synchronized ProjectReferenceChange[] removeProjectReferenceChanges() {
+	    int length = this.projectReferenceChanges.size();
+	    if (length == 0) return null;
+	    ProjectReferenceChange[]  updates = new ProjectReferenceChange[length];
+	    this.projectReferenceChanges.values().toArray(updates);
+	    this.projectReferenceChanges.clear();
+	    return updates;
+	}
+
+	public synchronized HashSet removeExternalElementsToRefresh() {
+		HashSet result = this.externalElementsToRefresh;
+		this.externalElementsToRefresh = null;
+		return result;
+	}
+
+	public synchronized void removeElementChangedListener(IElementChangedListener listener) {
+
+		for (int i = 0; i < this.elementChangedListenerCount; i++){
+
+			if (this.elementChangedListeners[i] == listener){
+
+				// need to clone defensively since we might be in the middle of listener notifications (#fire)
+				int length = this.elementChangedListeners.length;
+				IElementChangedListener[] newListeners = new IElementChangedListener[length];
+				System.arraycopy(this.elementChangedListeners, 0, newListeners, 0, i);
+				int[] newMasks = new int[length];
+				System.arraycopy(this.elementChangedListenerMasks, 0, newMasks, 0, i);
+
+				// copy trailing listeners
+				int trailingLength = this.elementChangedListenerCount - i - 1;
+				if (trailingLength > 0){
+					System.arraycopy(this.elementChangedListeners, i+1, newListeners, i, trailingLength);
+					System.arraycopy(this.elementChangedListenerMasks, i+1, newMasks, i, trailingLength);
+				}
+
+				// update manager listener state (#fire need to iterate over original listeners through a local variable to hold onto
+				// the original ones)
+				this.elementChangedListeners = newListeners;
+				this.elementChangedListenerMasks = newMasks;
+				this.elementChangedListenerCount--;
+				return;
+			}
+		}
+	}
+
+	public synchronized void removePreResourceChangedListener(IResourceChangeListener listener) {
+
+		for (int i = 0; i < this.preResourceChangeListenerCount; i++){
+
+			if (this.preResourceChangeListeners[i] == listener){
+
+				// need to clone defensively since we might be in the middle of listener notifications (#fire)
+				int length = this.preResourceChangeListeners.length;
+				IResourceChangeListener[] newListeners = new IResourceChangeListener[length];
+				int[] newEventMasks = new int[length];
+				System.arraycopy(this.preResourceChangeListeners, 0, newListeners, 0, i);
+				System.arraycopy(this.preResourceChangeEventMasks, 0, newEventMasks, 0, i);
+
+				// copy trailing listeners
+				int trailingLength = this.preResourceChangeListenerCount - i - 1;
+				if (trailingLength > 0) {
+					System.arraycopy(this.preResourceChangeListeners, i+1, newListeners, i, trailingLength);
+					System.arraycopy(this.preResourceChangeEventMasks, i+1, newEventMasks, i, trailingLength);
+				}
+
+				// update manager listener state (#fire need to iterate over original listeners through a local variable to hold onto
+				// the original ones)
+				this.preResourceChangeListeners = newListeners;
+				this.preResourceChangeEventMasks = newEventMasks;
+				this.preResourceChangeListenerCount--;
+				return;
+			}
+		}
+	}
+
+	public void resourceChanged(final IResourceChangeEvent event) {
+		for (int i = 0; i < this.preResourceChangeListenerCount; i++) {
+			// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+			final IResourceChangeListener listener = this.preResourceChangeListeners[i];
+			if ((this.preResourceChangeEventMasks[i] & event.getType()) != 0)
+				SafeRunner.run(new ISafeRunnable() {
+					public void handleException(Throwable exception) {
+						Util.log(exception, "Exception occurred in listener of pre Java resource change notification"); //$NON-NLS-1$
+					}
+					public void run() throws Exception {
+						listener.resourceChanged(event);
+					}
+				});
+		}
+		try {
+			getDeltaProcessor().resourceChanged(event);
+		} finally {
+			// TODO (jerome) see 47631, may want to get rid of following so as to reuse delta processor ?
+			if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
+				this.deltaProcessors.set(null);
+			} else {
+				// If we are going to reuse the delta processor of this thread, don't hang on to state
+				// that isn't meant to be reused. https://bugs.eclipse.org/bugs/show_bug.cgi?id=273385
+				getDeltaProcessor().overridenEventType = -1;
+			}
+		}
+
+	}
+
+	public Hashtable getExternalLibTimeStamps() {
+		if (this.externalTimeStamps == null) {
+			Hashtable timeStamps = new Hashtable();
+			File timestampsFile = getTimeStampsFile();
+			DataInputStream in = null;
+			try {
+				in = new DataInputStream(new BufferedInputStream(new FileInputStream(timestampsFile)));
+				int size = in.readInt();
+				while (size-- > 0) {
+					String key = in.readUTF();
+					long timestamp = in.readLong();
+					timeStamps.put(Path.fromPortableString(key), new Long(timestamp));
+				}
+			} catch (IOException e) {
+				if (timestampsFile.exists())
+					Util.log(e, "Unable to read external time stamps"); //$NON-NLS-1$
+			} finally {
+				if (in != null) {
+					try {
+						in.close();
+					} catch (IOException e) {
+						// nothing we can do: ignore
+					}
+				}
+			}
+			this.externalTimeStamps = timeStamps;
+		}
+		return this.externalTimeStamps;
+	}
+
+	public IJavaProject findJavaProject(String name) {
+		if (getOldJavaProjecNames().contains(name))
+			return JavaModelManager.getJavaModelManager().getJavaModel().getJavaProject(name);
+		return null;
+	}
+
+	/*
+	 * Workaround for bug 15168 circular errors not reported
+	 * Returns the list of java projects before resource delta processing
+	 * has started.
+	 */
+	public synchronized HashSet getOldJavaProjecNames() {
+		if (this.javaProjectNamesCache == null) {
+			HashSet result = new HashSet();
+			IJavaProject[] projects;
+			try {
+				projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+			} catch (JavaModelException e) {
+				return this.javaProjectNamesCache;
+			}
+			for (int i = 0, length = projects.length; i < length; i++) {
+				IJavaProject project = projects[i];
+				result.add(project.getElementName());
+			}
+			return this.javaProjectNamesCache = result;
+		}
+		return this.javaProjectNamesCache;
+	}
+
+	public synchronized void resetOldJavaProjectNames() {
+		this.javaProjectNamesCache = null;
+	}
+
+	private File getTimeStampsFile() {
+		return JavaCore.getPlugin().getStateLocation().append("externalLibsTimeStamps").toFile(); //$NON-NLS-1$
+	}
+
+	public void saveExternalLibTimeStamps() throws CoreException {
+		if (this.externalTimeStamps == null) return;
+		
+		// cleanup to avoid any leak ( https://bugs.eclipse.org/bugs/show_bug.cgi?id=244849 )
+		HashSet toRemove = new HashSet();
+		if (this.roots != null) {
+			Enumeration keys = this.externalTimeStamps.keys();
+			while (keys.hasMoreElements()) {
+				Object key = keys.nextElement();
+				if (this.roots.get(key) == null) {
+					toRemove.add(key);
+				}
+			}
+		}
+		
+		File timestamps = getTimeStampsFile();
+		DataOutputStream out = null;
+		try {
+			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(timestamps)));
+			out.writeInt(this.externalTimeStamps.size() - toRemove.size());
+			Iterator entries = this.externalTimeStamps.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry) entries.next();
+				IPath key = (IPath) entry.getKey();
+				if (!toRemove.contains(key)) {
+					out.writeUTF(key.toPortableString());
+					Long timestamp = (Long) entry.getValue();
+					out.writeLong(timestamp.longValue());
+				}
+			}
+		} catch (IOException e) {
+			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving timestamps", e); //$NON-NLS-1$
+			throw new CoreException(status);
+		} finally {
+			if (out != null) {
+				try {
+					out.close();
+				} catch (IOException e) {
+					// nothing we can do: ignore
+				}
+			}
+		}
+	}
+
+	/*
+	 * Update the roots that are affected by the addition or the removal of the given container resource.
+	 */
+	public synchronized void updateRoots(IPath containerPath, IResourceDelta containerDelta, DeltaProcessor deltaProcessor) {
+		Map updatedRoots;
+		Map otherUpdatedRoots;
+		if (containerDelta.getKind() == IResourceDelta.REMOVED) {
+			updatedRoots = this.oldRoots;
+			otherUpdatedRoots = this.oldOtherRoots;
+		} else {
+			updatedRoots = this.roots;
+			otherUpdatedRoots = this.otherRoots;
+		}
+		int containerSegmentCount = containerPath.segmentCount();
+		boolean containerIsProject = containerSegmentCount == 1;
+		Iterator iterator = updatedRoots.entrySet().iterator();
+		while (iterator.hasNext()) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			IPath path = (IPath) entry.getKey();
+			if (containerPath.isPrefixOf(path) && !containerPath.equals(path)) {
+				IResourceDelta rootDelta = containerDelta.findMember(path.removeFirstSegments(containerSegmentCount));
+				if (rootDelta == null) continue;
+				DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) entry.getValue();
+
+				if (!containerIsProject
+						|| !rootInfo.project.getPath().isPrefixOf(path)) { // only consider folder roots that are not included in the container
+					deltaProcessor.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
+				}
+
+				ArrayList rootList = (ArrayList)otherUpdatedRoots.get(path);
+				if (rootList != null) {
+					Iterator otherProjects = rootList.iterator();
+					while (otherProjects.hasNext()) {
+						rootInfo = (DeltaProcessor.RootInfo)otherProjects.next();
+						if (!containerIsProject
+								|| !rootInfo.project.getPath().isPrefixOf(path)) { // only consider folder roots that are not included in the container
+							deltaProcessor.updateCurrentDeltaAndIndex(rootDelta, IJavaElement.PACKAGE_FRAGMENT_ROOT, rootInfo);
+						}
+					}
+				}
+			}
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
new file mode 100644
index 0000000..8accbb6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -0,0 +1,2784 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Terry Parker <tparker@google.com> - DeltaProcessor exhibits O(N^2) behavior, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=354332
+ *     Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
+import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * This class is used by <code>JavaModelManager</code> to convert
+ * <code>IResourceDelta</code>s into <code>IJavaElementDelta</code>s.
+ * It also does some processing on the <code>JavaElement</code>s involved
+ * (e.g. closing them or updating classpaths).
+ * <p>
+ * High level summary of what the delta processor does:
+ * <ul>
+ * <li>reacts to resource deltas</li>
+ * <li>fires corresponding Java element deltas</li>
+ * <li>deltas also contain non-Java resources changes</li>
+ * <li>updates the model to reflect the Java element changes</li>
+ * <li>notifies type hierarchies of the changes</li>
+ * <li>triggers indexing of the changed elements</li>
+ * <li>refresh external archives (delta, model update, indexing)</li>
+ * <li>is thread safe (one delta processor instance per thread, see DeltaProcessingState#resourceChanged(...))</li>
+ * <li>handles .classpath changes (updates package fragment roots, update project references, validate classpath (.classpath format,
+ * 		resolved classpath, cycles))</li>
+ * </ul>
+ */
+public class DeltaProcessor {
+
+	static class OutputsInfo {
+		int outputCount;
+		IPath[] paths;
+		int[] traverseModes;
+		OutputsInfo(IPath[] paths, int[] traverseModes, int outputCount) {
+			this.paths = paths;
+			this.traverseModes = traverseModes;
+			this.outputCount = outputCount;
+		}
+		public String toString() {
+			if (this.paths == null) return "<none>"; //$NON-NLS-1$
+			StringBuffer buffer = new StringBuffer();
+			for (int i = 0; i < this.outputCount; i++) {
+				buffer.append("path="); //$NON-NLS-1$
+				buffer.append(this.paths[i].toString());
+				buffer.append("\n->traverse="); //$NON-NLS-1$
+				switch (this.traverseModes[i]) {
+					case BINARY:
+						buffer.append("BINARY"); //$NON-NLS-1$
+						break;
+					case IGNORE:
+						buffer.append("IGNORE"); //$NON-NLS-1$
+						break;
+					case SOURCE:
+						buffer.append("SOURCE"); //$NON-NLS-1$
+						break;
+					default:
+						buffer.append("<unknown>"); //$NON-NLS-1$
+				}
+				if (i+1 < this.outputCount) {
+					buffer.append('\n');
+				}
+			}
+			return buffer.toString();
+		}
+	}
+
+	public static class RootInfo {
+		char[][] inclusionPatterns;
+		char[][] exclusionPatterns;
+		public JavaProject project;
+		IPath rootPath;
+		int entryKind;
+		IPackageFragmentRoot root;
+		IPackageFragmentRoot cache;
+		RootInfo(JavaProject project, IPath rootPath, char[][] inclusionPatterns, char[][] exclusionPatterns, int entryKind) {
+			this.project = project;
+			this.rootPath = rootPath;
+			this.inclusionPatterns = inclusionPatterns;
+			this.exclusionPatterns = exclusionPatterns;
+			this.entryKind = entryKind;
+			this.cache = getPackageFragmentRoot();
+		}
+		public IPackageFragmentRoot getPackageFragmentRoot() {
+			IPackageFragmentRoot tRoot = null;
+			Object target = JavaModel.getTarget(this.rootPath, false/*don't check existence*/);
+			if (target instanceof IResource) {
+				tRoot = this.project.getPackageFragmentRoot((IResource)target);
+			} else {
+				tRoot = this.project.getPackageFragmentRoot(this.rootPath.toOSString());
+			}
+			return tRoot;
+		}
+		public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
+			if (this.root == null) {
+				if (resource != null) {
+					this.root = this.project.getPackageFragmentRoot(resource);
+				} else {
+					this.root = getPackageFragmentRoot();
+				}
+			}
+			if (this.root != null) 
+				this.cache = this.root;
+			return this.root;
+		}
+		boolean isRootOfProject(IPath path) {
+			return this.rootPath.equals(path) && this.project.getProject().getFullPath().isPrefixOf(path);
+		}
+		public String toString() {
+			StringBuffer buffer = new StringBuffer("project="); //$NON-NLS-1$
+			if (this.project == null) {
+				buffer.append("null"); //$NON-NLS-1$
+			} else {
+				buffer.append(this.project.getElementName());
+			}
+			buffer.append("\npath="); //$NON-NLS-1$
+			if (this.rootPath == null) {
+				buffer.append("null"); //$NON-NLS-1$
+			} else {
+				buffer.append(this.rootPath.toString());
+			}
+			buffer.append("\nincluding="); //$NON-NLS-1$
+			if (this.inclusionPatterns == null) {
+				buffer.append("null"); //$NON-NLS-1$
+			} else {
+				for (int i = 0, length = this.inclusionPatterns.length; i < length; i++) {
+					buffer.append(new String(this.inclusionPatterns[i]));
+					if (i < length-1) {
+						buffer.append("|"); //$NON-NLS-1$
+					}
+				}
+			}
+			buffer.append("\nexcluding="); //$NON-NLS-1$
+			if (this.exclusionPatterns == null) {
+				buffer.append("null"); //$NON-NLS-1$
+			} else {
+				for (int i = 0, length = this.exclusionPatterns.length; i < length; i++) {
+					buffer.append(new String(this.exclusionPatterns[i]));
+					if (i < length-1) {
+						buffer.append("|"); //$NON-NLS-1$
+					}
+				}
+			}
+			return buffer.toString();
+		}
+	}
+
+	private final static int IGNORE = 0;
+	private final static int SOURCE = 1;
+	private final static int BINARY = 2;
+
+	private final static String EXTERNAL_JAR_ADDED = "external jar added"; //$NON-NLS-1$
+	private final static String EXTERNAL_JAR_CHANGED = "external jar changed"; //$NON-NLS-1$
+	private final static String EXTERNAL_JAR_REMOVED = "external jar removed"; //$NON-NLS-1$
+	private final static String EXTERNAL_JAR_UNCHANGED = "external jar unchanged"; //$NON-NLS-1$
+	private final static String INTERNAL_JAR_IGNORE = "internal jar ignore"; //$NON-NLS-1$
+
+	private final static int NON_JAVA_RESOURCE = -1;
+	public static boolean DEBUG = false;
+	public static boolean VERBOSE = false;
+	public static boolean PERF = false;
+
+	public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks
+
+	/*
+	 * Answer a combination of the lastModified stamp and the size.
+	 * Used for detecting external JAR changes
+	 */
+	public static long getTimeStamp(File file) {
+		return file.lastModified() + file.length();
+	}
+
+	/*
+	 * The global state of delta processing.
+	 */
+	private DeltaProcessingState state;
+
+	/*
+	 * The Java model manager
+	 */
+	JavaModelManager manager;
+
+	/*
+	 * The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
+	 */
+	private JavaElementDelta currentDelta;
+
+	/* The java element that was last created (see createElement(IResource)).
+	 * This is used as a stack of java elements (using getParent() to pop it, and
+	 * using the various get*(...) to push it. */
+	private Openable currentElement;
+
+	/*
+	 * Queue of deltas created explicily by the Java Model that
+	 * have yet to be fired.
+	 */
+	public ArrayList javaModelDeltas= new ArrayList();
+
+	/*
+	 * Queue of reconcile deltas on working copies that have yet to be fired.
+	 * This is a table form IWorkingCopy to IJavaElementDelta
+	 */
+	public HashMap reconcileDeltas = new HashMap();
+
+	/*
+	 * Turns delta firing on/off. By default it is on.
+	 */
+	private boolean isFiring= true;
+
+	/*
+	 * Used to update the JavaModel for <code>IJavaElementDelta</code>s.
+	 */
+	private final ModelUpdater modelUpdater = new ModelUpdater();
+
+	/* A set of IJavaProject whose caches need to be reset */
+	public HashSet projectCachesToReset = new HashSet();
+
+	/* A table from IJavaProject to an array of IPackageFragmentRoot.
+	 * This table contains the pkg fragment roots of the project that are being deleted.
+	 */
+	public Map oldRoots;
+
+	/*
+	 * Type of event that should be processed no matter what the real event type is.
+	 */
+	public int overridenEventType = -1;
+
+	/*
+	 * Cache SourceElementParser for the project being visited
+	 */
+	private SourceElementParser sourceElementParserCache;
+
+	public DeltaProcessor(DeltaProcessingState state, JavaModelManager manager) {
+		this.state = state;
+		this.manager = manager;
+	}
+
+	/*
+	 * Adds the dependents of the given project to the list of the projects
+	 * to update.
+	 */
+	private void addDependentProjects(IJavaProject project, HashMap projectDependencies, HashSet result) {
+		IJavaProject[] dependents = (IJavaProject[]) projectDependencies.get(project);
+		if (dependents == null) return;
+		for (int i = 0, length = dependents.length; i < length; i++) {
+			IJavaProject dependent = dependents[i];
+			if (result.contains(dependent))
+				continue; // no need to go further as the project is already known
+			result.add(dependent);
+			addDependentProjects(dependent, projectDependencies, result);
+		}
+	}
+	/*
+	 * Adds the given child handle to its parent's cache of children.
+	 */
+	private void addToParentInfo(Openable child) {
+		Openable parent = (Openable) child.getParent();
+		if (parent != null && parent.isOpen()) {
+			try {
+				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006
+				// Insert the package fragment roots in the same order as the classpath order.
+				if (child instanceof IPackageFragmentRoot)
+					addPackageFragmentRoot(info, (IPackageFragmentRoot) child);
+				else
+					info.addChild(child);
+ 			} catch (JavaModelException e) {
+				// do nothing - we already checked if open
+			}
+		}
+	}
+	
+	private void addPackageFragmentRoot(OpenableElementInfo parent, IPackageFragmentRoot child)
+			throws JavaModelException {
+
+		IJavaElement[] roots = parent.getChildren();
+		if (roots.length > 0) {
+			IClasspathEntry[] resolvedClasspath = ((JavaProject) child.getJavaProject()).getResolvedClasspath();
+			IPath currentEntryPath = child.getResolvedClasspathEntry().getPath();
+			int indexToInsert = -1;
+			int lastComparedIndex = -1;
+			int i = 0, j = 0;
+			for (; i < roots.length && j < resolvedClasspath.length;) {
+
+				IClasspathEntry classpathEntry = resolvedClasspath[j];
+				if (lastComparedIndex != j && currentEntryPath.equals(classpathEntry.getPath())) {
+					indexToInsert = i;
+					break;
+				}
+				lastComparedIndex = j;
+
+				IClasspathEntry rootEntry = ((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry();
+				if (rootEntry.getPath().equals(classpathEntry.getPath()))
+					i++;
+				else
+					j++;
+			}
+
+			for (; i < roots.length; i++) {
+				// If the new root is already among the children, no need to proceed further. Just return.
+				if (roots[i].equals(child)) {
+					return;
+				}
+				// If we start seeing root's classpath entry different from the child's entry, then the child can't
+				// be present further down the roots array.
+				if (!((IPackageFragmentRoot) roots[i]).getResolvedClasspathEntry().getPath()
+						.equals(currentEntryPath))
+					break;
+			}
+
+			if (indexToInsert >= 0) {
+				int newSize = roots.length + 1;
+				IPackageFragmentRoot[] newChildren = new IPackageFragmentRoot[newSize];
+
+				if (indexToInsert > 0)
+					System.arraycopy(roots, 0, newChildren, 0, indexToInsert);
+
+				newChildren[indexToInsert] = child;
+				System.arraycopy(roots, indexToInsert, newChildren, indexToInsert + 1, (newSize - indexToInsert - 1));
+				parent.setChildren(newChildren);
+				return;
+			}
+		}
+		parent.addChild(child);
+	}
+	/*
+	 * Process the given delta and look for projects being added, opened, closed or
+	 * with a java nature being added or removed.
+	 * Note that projects being deleted are checked in deleting(IProject).
+	 * In all cases, add the project's dependents to the list of projects to update
+	 * so that the classpath related markers can be updated.
+	 */
+	private void checkProjectsAndClasspathChanges(IResourceDelta delta) {
+		IResource resource = delta.getResource();
+		IResourceDelta[] children = null;
+
+		switch (resource.getType()) {
+			case IResource.ROOT :
+				// workaround for bug 15168 circular errors not reported
+				this.state.getOldJavaProjecNames(); // force list to be computed
+				children = delta.getAffectedChildren();
+				break;
+			case IResource.PROJECT :
+				// NB: No need to check project's nature as if the project is not a java project:
+				//     - if the project is added or changed this is a noop for projectsBeingDeleted
+				//     - if the project is closed, it has already lost its java nature
+				IProject project = (IProject)resource;
+				JavaProject javaProject = (JavaProject)JavaCore.create(project);
+				switch (delta.getKind()) {
+					case IResourceDelta.ADDED :
+						this.manager.forceBatchInitializations(false/*not initAfterLoad*/);
+
+						// remember that the project's cache must be reset
+						this.projectCachesToReset.add(javaProject);
+
+						// workaround for bug 15168 circular errors not reported
+						if (JavaProject.hasJavaNature(project)) {
+							addToParentInfo(javaProject);
+							readRawClasspath(javaProject);
+							// ensure project references are updated (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=121569)
+							checkProjectReferenceChange(project, javaProject);
+							// and external folders as well
+							checkExternalFolderChange(project, javaProject);
+						}
+
+						this.state.rootsAreStale = true;
+						break;
+
+					case IResourceDelta.CHANGED :
+							if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
+								this.manager.forceBatchInitializations(false/*not initAfterLoad*/);
+
+								// remember that the project's cache must be reset
+								this.projectCachesToReset.add(javaProject);
+
+								// workaround for bug 15168 circular errors not reported
+								if (project.isOpen()) {
+									if (JavaProject.hasJavaNature(project)) {
+										addToParentInfo(javaProject);
+										readRawClasspath(javaProject);
+										// ensure project references are updated
+										checkProjectReferenceChange(project, javaProject);
+										// and external folders as well
+										checkExternalFolderChange(project, javaProject);
+									}
+								} else {
+									try {
+										javaProject.close();
+									} catch (JavaModelException e) {
+										// java project doesn't exist: ignore
+									}
+									removeFromParentInfo(javaProject);
+									this.manager.removePerProjectInfo(javaProject, false /* don't remove index files and timestamp info of external jar */);
+									this.manager.containerRemove(javaProject);
+								}
+								this.state.rootsAreStale = true;
+							} else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
+								boolean wasJavaProject = this.state.findJavaProject(project.getName()) != null;
+								boolean isJavaProject = JavaProject.hasJavaNature(project);
+								if (wasJavaProject != isJavaProject) {
+									this.manager.forceBatchInitializations(false/*not initAfterLoad*/);
+
+									// java nature added or removed: remember that the project's cache must be reset
+									this.projectCachesToReset.add(javaProject);
+
+									// workaround for bug 15168 circular errors not reported
+									if (isJavaProject) {
+										addToParentInfo(javaProject);
+										readRawClasspath(javaProject);
+										// ensure project references are updated (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172666)
+										checkProjectReferenceChange(project, javaProject);
+										// and external folders as well
+										checkExternalFolderChange(project, javaProject);
+									} else {
+										// remove classpath cache so that initializeRoots() will not consider the project has a classpath
+										this.manager.removePerProjectInfo(javaProject, true /* remove external jar files indexes and timestamps */);
+										// remove container cache for this project
+										this.manager.containerRemove(javaProject);
+										// close project
+										try {
+											javaProject.close();
+										} catch (JavaModelException e) {
+											// java project doesn't exist: ignore
+										}
+										removeFromParentInfo(javaProject);
+									}
+									this.state.rootsAreStale = true;
+								} else {
+									// in case the project was removed then added then changed (see bug 19799)
+									if (isJavaProject) { // need nature check - 18698
+										addToParentInfo(javaProject);
+										children = delta.getAffectedChildren();
+									}
+								}
+							} else {
+								// workaround for bug 15168 circular errors not reported
+								// in case the project was removed then added then changed
+								if (JavaProject.hasJavaNature(project)) { // need nature check - 18698
+									addToParentInfo(javaProject);
+									children = delta.getAffectedChildren();
+								}
+							}
+							break;
+
+					case IResourceDelta.REMOVED :
+						this.manager.forceBatchInitializations(false/*not initAfterLoad*/);
+
+						// remove classpath cache so that initializeRoots() will not consider the project has a classpath
+						this.manager.removePerProjectInfo(javaProject, true /* remove external jar files indexes and timestamps*/);
+						// remove container cache for this project
+						this.manager.containerRemove(javaProject);
+
+						this.state.rootsAreStale = true;
+						break;
+				}
+
+				break;
+			case IResource.FOLDER:
+				if (delta.getKind() == IResourceDelta.CHANGED) { // look for .jar file change to update classpath
+					children = delta.getAffectedChildren();
+				}
+				break;
+			case IResource.FILE :
+				IFile file = (IFile) resource;
+				int kind = delta.getKind();
+				RootInfo rootInfo;
+				if (file.getName().equals(JavaProject.CLASSPATH_FILENAME)) {
+					/* classpath file change */
+					this.manager.forceBatchInitializations(false/*not initAfterLoad*/);
+					switch (kind) {
+						case IResourceDelta.CHANGED :
+							int flags = delta.getFlags();
+							if ((flags & IResourceDelta.CONTENT) == 0  // only consider content change
+								&& (flags & IResourceDelta.ENCODING) == 0 // and encoding change
+								&& (flags & IResourceDelta.MOVED_FROM) == 0) {// and also move and overide scenario (see http://dev.eclipse.org/bugs/show_bug.cgi?id=21420)
+								break;
+							}
+						//$FALL-THROUGH$
+						case IResourceDelta.ADDED :
+						case IResourceDelta.REMOVED :
+							javaProject = (JavaProject)JavaCore.create(file.getProject());
+
+							// force to (re)read the .classpath file
+							// in case of removal (IResourceDelta.REMOVED) this will reset the classpath to its default and create the right delta
+							// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=211290)
+							readRawClasspath(javaProject);
+							break;
+					}
+					this.state.rootsAreStale = true;
+				} else if ((rootInfo = rootInfo(file.getFullPath(), kind)) != null && rootInfo.entryKind == IClasspathEntry.CPE_LIBRARY) {
+					javaProject = (JavaProject)JavaCore.create(file.getProject());
+					javaProject.resetResolvedClasspath();
+					this.state.rootsAreStale = true;
+				}
+				break;
+
+		}
+		if (children != null) {
+			for (int i = 0; i < children.length; i++) {
+				checkProjectsAndClasspathChanges(children[i]);
+			}
+		}
+	}
+
+	private void checkExternalFolderChange(IProject project, JavaProject javaProject) {
+		ClasspathChange change = this.state.getClasspathChange(project);
+		this.state.addExternalFolderChange(javaProject, change == null ? null : change.oldResolvedClasspath);
+	}
+
+	private void checkProjectReferenceChange(IProject project, JavaProject javaProject) {
+		ClasspathChange change = this.state.getClasspathChange(project);
+		this.state.addProjectReferenceChange(javaProject, change == null ? null : change.oldResolvedClasspath);
+	}
+
+	private void readRawClasspath(JavaProject javaProject) {
+		// force to (re)read the .classpath file
+		try {
+			PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
+			if (!perProjectInfo.writtingRawClasspath) // to avoid deadlock, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=221680
+				perProjectInfo.readAndCacheClasspath(javaProject);
+		} catch (JavaModelException e) {
+			if (VERBOSE) {
+				e.printStackTrace();
+			}
+		}
+	}
+	private void checkSourceAttachmentChange(IResourceDelta delta, IResource res) {
+		IPath rootPath = (IPath)this.state.sourceAttachments.get(externalPath(res));
+		if (rootPath != null) {
+			RootInfo rootInfo = rootInfo(rootPath, delta.getKind());
+			if (rootInfo != null) {
+				IJavaProject projectOfRoot = rootInfo.project;
+				IPackageFragmentRoot root = null;
+				try {
+					// close the root so that source attachment cache is flushed
+					root = projectOfRoot.findPackageFragmentRoot(rootPath);
+					if (root != null) {
+						root.close();
+					}
+				} catch (JavaModelException e) {
+					// root doesn't exist: ignore
+				}
+				if (root == null) return;
+				switch (delta.getKind()) {
+					case IResourceDelta.ADDED:
+						currentDelta().sourceAttached(root);
+						break;
+					case IResourceDelta.CHANGED:
+						currentDelta().sourceDetached(root);
+						currentDelta().sourceAttached(root);
+						break;
+					case IResourceDelta.REMOVED:
+						currentDelta().sourceDetached(root);
+						break;
+				}
+			}
+		}
+	}
+	/*
+	 * Closes the given element, which removes it from the cache of open elements.
+	 */
+	private void close(Openable element) {
+		try {
+			element.close();
+		} catch (JavaModelException e) {
+			// do nothing
+		}
+	}
+	/*
+	 * Generic processing for elements with changed contents:<ul>
+	 * <li>The element is closed such that any subsequent accesses will re-open
+	 * the element reflecting its new structure.
+	 * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
+	 * </ul>
+	 * Delta argument could be null if processing an external JAR change
+	 */
+	private void contentChanged(Openable element) {
+
+		boolean isPrimary = false;
+		boolean isPrimaryWorkingCopy = false;
+		if (element.getElementType() == IJavaElement.COMPILATION_UNIT) {
+			CompilationUnit cu = (CompilationUnit)element;
+			isPrimary = cu.isPrimary();
+			isPrimaryWorkingCopy = isPrimary && cu.isWorkingCopy();
+		}
+		if (isPrimaryWorkingCopy) {
+			// filter out changes to primary compilation unit in working copy mode
+			// just report a change to the resource (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59500)
+			currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE);
+		} else {
+			close(element);
+			int flags = IJavaElementDelta.F_CONTENT;
+			if (element instanceof JarPackageFragmentRoot){
+				flags |= IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED;
+				// need also to reset project cache otherwise it will be out-of-date
+				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=162621
+				this.projectCachesToReset.add(element.getJavaProject());
+			}
+			if (isPrimary) {
+				flags |= IJavaElementDelta.F_PRIMARY_RESOURCE;
+			}
+			currentDelta().changed(element, flags);
+		}
+	}
+	/*
+	 * Creates the openables corresponding to this resource.
+	 * Returns null if none was found.
+	 */
+	private Openable createElement(IResource resource, int elementType, RootInfo rootInfo) {
+		if (resource == null) return null;
+
+		IPath path = resource.getFullPath();
+		IJavaElement element = null;
+		switch (elementType) {
+
+			case IJavaElement.JAVA_PROJECT:
+
+				// note that non-java resources rooted at the project level will also enter this code with
+				// an elementType JAVA_PROJECT (see #elementType(...)).
+				if (resource instanceof IProject){
+
+					popUntilPrefixOf(path);
+
+					if (this.currentElement != null
+						&& this.currentElement.getElementType() == IJavaElement.JAVA_PROJECT
+						&& ((IJavaProject)this.currentElement).getProject().equals(resource)) {
+						return this.currentElement;
+					}
+					if  (rootInfo != null && rootInfo.project.getProject().equals(resource)){
+						element = rootInfo.project;
+						break;
+					}
+					IProject proj = (IProject)resource;
+					if (JavaProject.hasJavaNature(proj)) {
+						element = JavaCore.create(proj);
+					} else {
+						// java project may have been been closed or removed (look for
+						// element amongst old java project s list).
+						element =  this.state.findJavaProject(proj.getName());
+					}
+				}
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+				element = rootInfo == null ? JavaCore.create(resource) : rootInfo.getPackageFragmentRoot(resource);
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT:
+				if (rootInfo != null) {
+					if (rootInfo.project.contains(resource)) {
+						PackageFragmentRoot root = (PackageFragmentRoot) rootInfo.getPackageFragmentRoot(null);
+						// create package handle
+						IPath pkgPath = path.removeFirstSegments(root.resource().getFullPath().segmentCount());
+						String[] pkgName = pkgPath.segments();
+						element = root.getPackageFragment(pkgName);
+					}
+				} else {
+					// find the element that encloses the resource
+					popUntilPrefixOf(path);
+
+					if (this.currentElement == null) {
+						element = JavaCore.create(resource);
+					} else {
+						// find the root
+						PackageFragmentRoot root = this.currentElement.getPackageFragmentRoot();
+						if (root == null) {
+							element =  JavaCore.create(resource);
+						} else if (((JavaProject)root.getJavaProject()).contains(resource)) {
+							// create package handle
+							IPath pkgPath = path.removeFirstSegments(root.getPath().segmentCount());
+							String[] pkgName = pkgPath.segments();
+							element = root.getPackageFragment(pkgName);
+						}
+					}
+				}
+				break;
+			case IJavaElement.COMPILATION_UNIT:
+			case IJavaElement.CLASS_FILE:
+				// find the element that encloses the resource
+				popUntilPrefixOf(path);
+
+				if (this.currentElement == null) {
+					element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+				} else {
+					// find the package
+					IPackageFragment pkgFragment = null;
+					switch (this.currentElement.getElementType()) {
+						case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+							PackageFragmentRoot root = (PackageFragmentRoot)this.currentElement;
+							IPath rootPath = root.getPath();
+							IPath pkgPath = path.removeLastSegments(1);
+							String[] pkgName = pkgPath.removeFirstSegments(rootPath.segmentCount()).segments();
+							pkgFragment = root.getPackageFragment(pkgName);
+							break;
+						case IJavaElement.PACKAGE_FRAGMENT:
+							Openable pkg = this.currentElement;
+							if (pkg.getPath().equals(path.removeLastSegments(1))) {
+								pkgFragment = (IPackageFragment)pkg;
+							} // else case of package x which is a prefix of x.y
+							break;
+						case IJavaElement.COMPILATION_UNIT:
+						case IJavaElement.CLASS_FILE:
+							pkgFragment = (IPackageFragment)this.currentElement.getParent();
+							break;
+					}
+					if (pkgFragment == null) {
+						element =  rootInfo == null ? JavaCore.create(resource) : JavaModelManager.create(resource, rootInfo.project);
+					} else {
+						if (elementType == IJavaElement.COMPILATION_UNIT) {
+							// create compilation unit handle
+							// fileName validation has been done in elementType(IResourceDelta, int, boolean)
+							String fileName = path.lastSegment();
+							element = pkgFragment.getCompilationUnit(fileName);
+						} else {
+							// create class file handle
+							// fileName validation has been done in elementType(IResourceDelta, int, boolean)
+							String fileName = path.lastSegment();
+							element = pkgFragment.getClassFile(fileName);
+						}
+					}
+				}
+				break;
+		}
+		if (element == null) return null;
+		this.currentElement = (Openable)element;
+		return this.currentElement;
+	}
+	
+	public void checkExternalArchiveChanges(IJavaElement[] elementsScope,  IProgressMonitor monitor) throws JavaModelException {
+		checkExternalArchiveChanges(elementsScope, false, monitor);
+	}
+	/*
+	 * Check all external archive (referenced by given roots, projects or model) status and issue a corresponding root delta.
+	 * Also triggers index updates
+	 */
+	private void checkExternalArchiveChanges(IJavaElement[] elementsScope, boolean asynchronous, IProgressMonitor monitor) throws JavaModelException {
+		if (monitor != null && monitor.isCanceled())
+			throw new OperationCanceledException();
+		try {
+			if (monitor != null) monitor.beginTask("", 1); //$NON-NLS-1$
+
+			boolean hasExternalWorkingCopyProject = false;
+			for (int i = 0, length = elementsScope.length; i < length; i++) {
+				IJavaElement element = elementsScope[i];
+				this.state.addForRefresh(elementsScope[i]);
+				if (element.getElementType() == IJavaElement.JAVA_MODEL) {
+					// ensure external working copies' projects' caches are reset
+					HashSet projects = JavaModelManager.getJavaModelManager().getExternalWorkingCopyProjects();
+					if (projects != null) {
+						hasExternalWorkingCopyProject = true;
+						Iterator iterator = projects.iterator();
+						while (iterator.hasNext()) {
+							JavaProject project = (JavaProject) iterator.next();
+							project.resetCaches();
+						}
+					}
+				}
+			}
+			HashSet elementsToRefresh = this.state.removeExternalElementsToRefresh();
+			boolean hasDelta = elementsToRefresh != null && createExternalArchiveDelta(elementsToRefresh, monitor);
+			if (hasDelta){
+				IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren();
+				final int length = projectDeltas.length;
+				final IProject[] projectsToTouch = new IProject[length];
+				for (int i = 0; i < length; i++) {
+					IJavaElementDelta delta = projectDeltas[i];
+					JavaProject javaProject = (JavaProject)delta.getElement();
+					projectsToTouch[i] = javaProject.getProject();
+				}
+				if (projectsToTouch.length > 0) {
+					if (asynchronous){
+						WorkspaceJob touchJob = new WorkspaceJob(Messages.updating_external_archives_jobName) {
+							
+							public IStatus runInWorkspace(IProgressMonitor progressMonitor) throws CoreException {
+								try {
+									if (progressMonitor != null)
+										progressMonitor.beginTask("", projectsToTouch.length); //$NON-NLS-1$
+									touchProjects(projectsToTouch, progressMonitor);
+								}
+								finally {
+									if (progressMonitor != null)
+										progressMonitor.done();
+								}
+								return Status.OK_STATUS;
+							}
+							
+							public boolean belongsTo(Object family) {
+								return ResourcesPlugin.FAMILY_MANUAL_REFRESH == family;
+							}
+						};
+						touchJob.schedule();
+					}
+					else {
+						// touch the projects to force them to be recompiled while taking the workspace lock
+						//	 so that there is no concurrency with the Java builder
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=96575
+						IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+							public void run(IProgressMonitor progressMonitor) throws CoreException {
+								for (int i = 0; i < projectsToTouch.length; i++) {
+									IProject project = projectsToTouch[i];
+
+									// touch to force a build of this project
+									if (JavaBuilder.DEBUG)
+										System.out.println("Touching project " + project.getName() + " due to external jar file change"); //$NON-NLS-1$ //$NON-NLS-2$
+									project.touch(progressMonitor);
+								}
+							}
+						};
+						try {
+							ResourcesPlugin.getWorkspace().run(runnable, monitor);
+						} catch (CoreException e) {
+							throw new JavaModelException(e);
+						}
+					}
+				}
+
+				if (this.currentDelta != null) { // if delta has not been fired while creating markers
+					fire(this.currentDelta, DEFAULT_CHANGE_EVENT);
+				}
+			} else if (hasExternalWorkingCopyProject) {
+				// flush jar type cache
+				JavaModelManager.getJavaModelManager().resetJarTypeCache();
+			}
+		} finally {
+			this.currentDelta = null;
+			if (monitor != null) monitor.done();
+		}
+	}
+
+	protected void touchProjects(final IProject[] projectsToTouch, IProgressMonitor progressMonitor)
+			throws CoreException {
+		for (int i = 0; i < projectsToTouch.length; i++) {
+			IProgressMonitor monitor = progressMonitor == null ? null: new SubProgressMonitor(progressMonitor, 1);
+			IProject project = projectsToTouch[i];
+			// touch to force a build of this project
+			if (JavaBuilder.DEBUG)
+				System.out.println("Touching project " + project.getName() + " due to external jar file change"); //$NON-NLS-1$ //$NON-NLS-2$
+			project.touch(monitor);
+		}
+	}
+
+	/*
+	 * Check if external archives have changed for the given elements and create the corresponding deltas.
+	 * Returns whether at least one delta was created.
+	 */
+	private boolean createExternalArchiveDelta(HashSet refreshedElements, IProgressMonitor monitor) {
+
+		HashMap externalArchivesStatus = new HashMap();
+		boolean hasDelta = false;
+
+		// find JARs to refresh
+		HashSet archivePathsToRefresh = new HashSet();
+		Iterator iterator = refreshedElements.iterator();
+		while (iterator.hasNext()) {
+			IJavaElement element = (IJavaElement)iterator.next();
+			switch(element.getElementType()){
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+					archivePathsToRefresh.add(element.getPath());
+					break;
+				case IJavaElement.JAVA_PROJECT :
+					JavaProject javaProject = (JavaProject) element;
+					if (!JavaProject.hasJavaNature(javaProject.getProject())) {
+						// project is not accessible or has lost its Java nature
+						break;
+					}
+					IClasspathEntry[] classpath;
+					try {
+						classpath = javaProject.getResolvedClasspath();
+						for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
+							if (classpath[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
+								archivePathsToRefresh.add(classpath[j].getPath());
+							}
+						}
+					} catch (JavaModelException e) {
+						// project doesn't exist -> ignore
+					}
+					break;
+				case IJavaElement.JAVA_MODEL :
+					Iterator projectNames = this.state.getOldJavaProjecNames().iterator();
+					while (projectNames.hasNext()) {
+						String projectName = (String) projectNames.next();
+						IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+						if (!JavaProject.hasJavaNature(project)) {
+							// project is not accessible or has lost its Java nature
+							continue;
+						}
+						javaProject = (JavaProject) JavaCore.create(project);
+						try {
+							classpath = javaProject.getResolvedClasspath();
+							for (int k = 0, cpLength = classpath.length; k < cpLength; k++){
+								if (classpath[k].getEntryKind() == IClasspathEntry.CPE_LIBRARY){
+									archivePathsToRefresh.add(classpath[k].getPath());
+								}
+							}
+						} catch (JavaModelException e2) {
+							// project doesn't exist -> ignore
+							continue;
+						}
+					}
+					break;
+			}
+		}
+
+		// perform refresh
+		Iterator projectNames = this.state.getOldJavaProjecNames().iterator();
+		IWorkspaceRoot wksRoot = ResourcesPlugin.getWorkspace().getRoot();
+		while (projectNames.hasNext()) {
+
+			if (monitor != null && monitor.isCanceled()) break;
+
+			String projectName = (String) projectNames.next();
+			IProject project = wksRoot.getProject(projectName);
+			if (!JavaProject.hasJavaNature(project)) {
+				// project is not accessible or has lost its Java nature
+				continue;
+			}
+			JavaProject javaProject = (JavaProject) JavaCore.create(project);
+			IClasspathEntry[] entries;
+			try {
+				entries = javaProject.getResolvedClasspath();
+			} catch (JavaModelException e1) {
+				// project does not exist -> ignore
+				continue;
+			}
+			boolean deltaContainsModifiedJar = false;
+			for (int j = 0; j < entries.length; j++){
+				if (entries[j].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+					IPath entryPath = entries[j].getPath();
+
+					if (!archivePathsToRefresh.contains(entryPath)) continue; // not supposed to be refreshed
+
+					String status = (String)externalArchivesStatus.get(entryPath);
+					if (status == null){
+
+						// compute shared status
+						Object targetLibrary = JavaModel.getTarget(entryPath, true);
+
+						if (targetLibrary == null){ // missing JAR
+							if (this.state.getExternalLibTimeStamps().remove(entryPath) != null /* file was known*/
+									&& this.state.roots.get(entryPath) != null /* and it was on the classpath*/) {
+								externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
+								// the jar was physically removed: remove the index
+								this.manager.indexManager.removeIndex(entryPath);
+							}
+
+						} else if (targetLibrary instanceof File){ // external JAR
+
+							File externalFile = (File)targetLibrary;
+
+							// check timestamp to figure if JAR has changed in some way
+							Long oldTimestamp =(Long) this.state.getExternalLibTimeStamps().get(entryPath);
+							long newTimeStamp = getTimeStamp(externalFile);
+							if (oldTimestamp != null){
+
+								if (newTimeStamp == 0){ // file doesn't exist
+									externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
+									this.state.getExternalLibTimeStamps().remove(entryPath);
+									// remove the index
+									this.manager.indexManager.removeIndex(entryPath);
+
+								} else if (oldTimestamp.longValue() != newTimeStamp){
+									externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
+									this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp));
+									// first remove the index so that it is forced to be re-indexed
+									this.manager.indexManager.removeIndex(entryPath);
+									// then index the jar
+									this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation(), true);
+								} else {
+									URL indexLocation = ((ClasspathEntry)entries[j]).getLibraryIndexLocation();
+									if (indexLocation != null) { // force reindexing, this could be faster rather than maintaining the list
+										this.manager.indexManager.indexLibrary(entryPath, project.getProject(), indexLocation);
+									}
+									externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
+								}
+							} else {
+								if (newTimeStamp == 0){ // jar still doesn't exist
+									externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
+								} else {
+									externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
+									this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp));
+									// index the new jar
+									this.manager.indexManager.removeIndex(entryPath);
+									this.manager.indexManager.indexLibrary(entryPath, project.getProject(), ((ClasspathEntry)entries[j]).getLibraryIndexLocation());
+								}
+							}
+						} else { // internal JAR
+							externalArchivesStatus.put(entryPath, INTERNAL_JAR_IGNORE);
+						}
+					}
+					// according to computed status, generate a delta
+					status = (String)externalArchivesStatus.get(entryPath);
+					if (status != null){
+						if (status == EXTERNAL_JAR_ADDED){
+							PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString());
+							if (VERBOSE){
+								System.out.println("- External JAR ADDED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+							}
+							elementAdded(root, null, null);
+							deltaContainsModifiedJar = true;
+							this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733
+							hasDelta = true;
+						} else if (status == EXTERNAL_JAR_CHANGED) {
+							PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString());
+							if (VERBOSE){
+								System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+							}
+							contentChanged(root);
+							deltaContainsModifiedJar = true;
+							hasDelta = true;
+						} else if (status == EXTERNAL_JAR_REMOVED) {
+							PackageFragmentRoot root = (PackageFragmentRoot) javaProject.getPackageFragmentRoot(entryPath.toString());
+							if (VERBOSE){
+								System.out.println("- External JAR REMOVED, affecting root: "+root.getElementName()); //$NON-NLS-1$
+							}
+							elementRemoved(root, null, null);
+							deltaContainsModifiedJar = true;
+							this.state.addClasspathValidation(javaProject); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185733
+							hasDelta = true;
+						}
+					}
+				}
+			}
+			
+			if (deltaContainsModifiedJar) {
+				javaProject.resetResolvedClasspath();
+			}
+		}
+		// ensure the external file cache is reset so that if a .jar file is deleted but no longer on the classpath, it won't appear as changed next time it is added
+		JavaModel.flushExternalFileCache();
+
+		if (hasDelta){
+			// flush jar type cache
+			JavaModelManager.getJavaModelManager().resetJarTypeCache();
+		}
+		return hasDelta;
+	}
+	private JavaElementDelta currentDelta() {
+		if (this.currentDelta == null) {
+			this.currentDelta = new JavaElementDelta(this.manager.getJavaModel());
+		}
+		return this.currentDelta;
+	}
+	/*
+	 * Note that the project is about to be deleted.
+	 */
+	private void deleting(IProject project) {
+
+		try {
+			// discard indexing jobs that belong to this project so that the project can be
+			// deleted without interferences from the index manager
+			this.manager.indexManager.discardJobs(project.getName());
+
+			JavaProject javaProject = (JavaProject)JavaCore.create(project);
+
+			// remember roots of this project
+			if (this.oldRoots == null) {
+				this.oldRoots = new HashMap();
+			}
+			if (javaProject.isOpen()) {
+				this.oldRoots.put(javaProject, javaProject.getPackageFragmentRoots());
+			} else {
+				// compute roots without opening project
+				this.oldRoots.put(
+					javaProject,
+					javaProject.computePackageFragmentRoots(
+						javaProject.getResolvedClasspath(),
+						false,
+						null /*no reverse map*/));
+			}
+
+			javaProject.close();
+
+			// workaround for bug 15168 circular errors not reported
+			this.state.getOldJavaProjecNames(); // foce list to be computed
+
+			removeFromParentInfo(javaProject);
+
+			// remove preferences from per project info
+			this.manager.resetProjectPreferences(javaProject);
+		} catch (JavaModelException e) {
+			// java project doesn't exist: ignore
+		}
+	}
+	/*
+	 * Processing for an element that has been added:<ul>
+	 * <li>If the element is a project, do nothing, and do not process
+	 * children, as when a project is created it does not yet have any
+	 * natures - specifically a java nature.
+	 * <li>If the elemet is not a project, process it as added (see
+	 * <code>basicElementAdded</code>.
+	 * </ul>
+	 * Delta argument could be null if processing an external JAR change
+	 */
+	private void elementAdded(Openable element, IResourceDelta delta, RootInfo rootInfo) {
+		int elementType = element.getElementType();
+
+		if (elementType == IJavaElement.JAVA_PROJECT) {
+			// project add is handled by JavaProject.configure() because
+			// when a project is created, it does not yet have a java nature
+			IProject project;
+			if (delta != null && JavaProject.hasJavaNature(project = (IProject)delta.getResource())) {
+				addToParentInfo(element);
+				this.manager.getPerProjectInfo(project, true /*create info if needed*/).rememberExternalLibTimestamps();
+				if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
+					Openable movedFromElement = (Openable)element.getJavaModel().getJavaProject(delta.getMovedFromPath().lastSegment());
+					currentDelta().movedTo(element, movedFromElement);
+				} else {
+					// Force the project to be closed as it might have been opened
+					// before the resource modification came in and it might have a new child
+					// For example, in an IWorkspaceRunnable:
+					// 1. create a Java project P (where P=src)
+					// 2. open project P
+					// 3. add folder f in P's pkg fragment root
+					// When the resource delta comes in, only the addition of P is notified,
+					// but the pkg fragment root of project P is already opened, thus its children are not recomputed
+					// and it appears to contain only the default package.
+					close(element);
+
+					currentDelta().added(element);
+				}
+				this.state.updateRoots(element.getPath(), delta, this);
+
+				// remember that the project's cache must be reset
+				this.projectCachesToReset.add(element);
+			}
+		} else {
+			if (delta == null || (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) {
+				// regular element addition
+				if (isPrimaryWorkingCopy(element, elementType) ) {
+					// filter out changes to primary compilation unit in working copy mode
+					// just report a change to the resource (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59500)
+					currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE);
+				} else {
+					addToParentInfo(element);
+
+					// Force the element to be closed as it might have been opened
+					// before the resource modification came in and it might have a new child
+					// For example, in an IWorkspaceRunnable:
+					// 1. create a package fragment p using a java model operation
+					// 2. open package p
+					// 3. add file X.java in folder p
+					// When the resource delta comes in, only the addition of p is notified,
+					// but the package p is already opened, thus its children are not recomputed
+					// and it appears empty.
+					close(element);
+
+					currentDelta().added(element);
+				}
+			} else {
+				// element is moved
+				addToParentInfo(element);
+				close(element);
+
+				IPath movedFromPath = delta.getMovedFromPath();
+				IResource res = delta.getResource();
+				IResource movedFromRes;
+				if (res instanceof IFile) {
+					movedFromRes = res.getWorkspace().getRoot().getFile(movedFromPath);
+				} else {
+					movedFromRes = res.getWorkspace().getRoot().getFolder(movedFromPath);
+				}
+
+				// find the element type of the moved from element
+				IPath rootPath = externalPath(movedFromRes);
+				RootInfo movedFromInfo = enclosingRootInfo(rootPath, IResourceDelta.REMOVED);
+				int movedFromType =
+					elementType(
+						movedFromRes,
+						IResourceDelta.REMOVED,
+						element.getParent().getElementType(),
+						movedFromInfo);
+
+				// reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
+				this.currentElement = null;
+
+				// create the moved from element
+				Openable movedFromElement =
+					elementType != IJavaElement.JAVA_PROJECT && movedFromType == IJavaElement.JAVA_PROJECT ?
+						null : // outside classpath
+						createElement(movedFromRes, movedFromType, movedFromInfo);
+				if (movedFromElement == null) {
+					// moved from outside classpath
+					currentDelta().added(element);
+				} else {
+					currentDelta().movedTo(element, movedFromElement);
+				}
+			}
+
+			switch (elementType) {
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+					// when a root is added, and is on the classpath, the project must be updated
+					JavaProject project = (JavaProject) element.getJavaProject();
+
+					// remember that the project's cache must be reset
+					this.projectCachesToReset.add(project);
+
+					break;
+				case IJavaElement.PACKAGE_FRAGMENT :
+					// reset project's package fragment cache
+					project = (JavaProject) element.getJavaProject();
+					this.projectCachesToReset.add(project);
+
+					break;
+			}
+		}
+	}
+	/*
+	 * Generic processing for a removed element:<ul>
+	 * <li>Close the element, removing its structure from the cache
+	 * <li>Remove the element from its parent's cache of children
+	 * <li>Add a REMOVED entry in the delta
+	 * </ul>
+	 * Delta argument could be null if processing an external JAR change
+	 */
+	private void elementRemoved(Openable element, IResourceDelta delta, RootInfo rootInfo) {
+
+		int elementType = element.getElementType();
+		if (delta == null || (delta.getFlags() & IResourceDelta.MOVED_TO) == 0) {
+			// regular element removal
+			if (isPrimaryWorkingCopy(element, elementType) ) {
+				// filter out changes to primary compilation unit in working copy mode
+				// just report a change to the resource (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59500)
+				currentDelta().changed(element, IJavaElementDelta.F_PRIMARY_RESOURCE);
+			} else {
+				close(element);
+				removeFromParentInfo(element);
+				currentDelta().removed(element);
+			}
+		} else {
+			// element is moved
+			close(element);
+			removeFromParentInfo(element);
+			IPath movedToPath = delta.getMovedToPath();
+			IResource res = delta.getResource();
+			IResource movedToRes;
+			switch (res.getType()) {
+				case IResource.PROJECT:
+					movedToRes = res.getWorkspace().getRoot().getProject(movedToPath.lastSegment());
+					break;
+				case IResource.FOLDER:
+					movedToRes = res.getWorkspace().getRoot().getFolder(movedToPath);
+					break;
+				case IResource.FILE:
+					movedToRes = res.getWorkspace().getRoot().getFile(movedToPath);
+					break;
+				default:
+					return;
+			}
+
+			// find the element type of the moved from element
+			IPath rootPath = externalPath(movedToRes);
+			RootInfo movedToInfo = enclosingRootInfo(rootPath, IResourceDelta.ADDED);
+			int movedToType =
+				elementType(
+					movedToRes,
+					IResourceDelta.ADDED,
+					element.getParent().getElementType(),
+					movedToInfo);
+
+			// reset current element as it might be inside a nested root (popUntilPrefixOf() may use the outer root)
+			this.currentElement = null;
+
+			// create the moved To element
+			Openable movedToElement =
+				elementType != IJavaElement.JAVA_PROJECT && movedToType == IJavaElement.JAVA_PROJECT ?
+					null : // outside classpath
+					createElement(movedToRes, movedToType, movedToInfo);
+			if (movedToElement == null) {
+				// moved outside classpath
+				currentDelta().removed(element);
+			} else {
+				currentDelta().movedFrom(element, movedToElement);
+			}
+		}
+
+		switch (elementType) {
+			case IJavaElement.JAVA_MODEL :
+				this.manager.indexManager.reset();
+				break;
+			case IJavaElement.JAVA_PROJECT :
+				this.state.updateRoots(element.getPath(), delta, this);
+
+				// remember that the project's cache must be reset
+				this.projectCachesToReset.add(element);
+
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+				JavaProject project = (JavaProject) element.getJavaProject();
+
+				// remember that the project's cache must be reset
+				this.projectCachesToReset.add(project);
+
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT :
+				// reset package fragment cache
+				project = (JavaProject) element.getJavaProject();
+				this.projectCachesToReset.add(project);
+
+				break;
+		}
+	}
+	/*
+	 * Returns the type of the java element the given delta matches to.
+	 * Returns NON_JAVA_RESOURCE if unknown (e.g. a non-java resource or excluded .java file)
+	 */
+	private int elementType(IResource res, int kind, int parentType, RootInfo rootInfo) {
+		switch (parentType) {
+			case IJavaElement.JAVA_MODEL:
+				// case of a movedTo or movedFrom project (other cases are handled in processResourceDelta(...)
+				return IJavaElement.JAVA_PROJECT;
+
+			case NON_JAVA_RESOURCE:
+			case IJavaElement.JAVA_PROJECT:
+				if (rootInfo == null) {
+					rootInfo = enclosingRootInfo(res.getFullPath(), kind);
+				}
+				if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
+					return IJavaElement.PACKAGE_FRAGMENT_ROOT;
+				}
+				// not yet in a package fragment root or root of another project
+				// or package fragment to be included (see below)
+				// $FALL-THROUGH$
+
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			case IJavaElement.PACKAGE_FRAGMENT:
+				if (rootInfo == null) {
+					IPath rootPath = externalPath(res);
+					rootInfo = enclosingRootInfo(rootPath, kind);
+				}
+				if (rootInfo == null) {
+					return NON_JAVA_RESOURCE;
+				}
+				if (Util.isExcluded(res, rootInfo.inclusionPatterns, rootInfo.exclusionPatterns)) {
+					return NON_JAVA_RESOURCE;
+				}
+				if (res.getType() == IResource.FOLDER) {
+					if (parentType == NON_JAVA_RESOURCE && !Util.isExcluded(res.getParent(), rootInfo.inclusionPatterns, rootInfo.exclusionPatterns)) {
+						// parent is a non-Java resource because it doesn't have a valid package name (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=130982)
+						return NON_JAVA_RESOURCE;
+					}
+					String sourceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_SOURCE, true);
+					String complianceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+					if (Util.isValidFolderNameForPackage(res.getName(), sourceLevel, complianceLevel)) {
+						return IJavaElement.PACKAGE_FRAGMENT;
+					}
+					return NON_JAVA_RESOURCE;
+				}
+				String fileName = res.getName();
+				String sourceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_SOURCE, true);
+				String complianceLevel = rootInfo.project == null ? null : rootInfo.project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+				if (Util.isValidCompilationUnitName(fileName, sourceLevel, complianceLevel)) {
+					return IJavaElement.COMPILATION_UNIT;
+				} else if (Util.isValidClassFileName(fileName, sourceLevel, complianceLevel)) {
+					return IJavaElement.CLASS_FILE;
+				} else {
+					IPath rootPath = externalPath(res);
+					if ((rootInfo = rootInfo(rootPath, kind)) != null
+							&& rootInfo.project.getProject().getFullPath().isPrefixOf(rootPath) /*ensure root is a root of its project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185310) */) {
+						// case of proj=src=bin and resource is a jar file on the classpath
+						return IJavaElement.PACKAGE_FRAGMENT_ROOT;
+					} else {
+						return NON_JAVA_RESOURCE;
+					}
+				}
+
+			default:
+				return NON_JAVA_RESOURCE;
+		}
+	}
+	/*
+	 * Flushes all deltas without firing them.
+	 */
+	public void flush() {
+		this.javaModelDeltas = new ArrayList();
+	}
+
+	private SourceElementParser getSourceElementParser(Openable element) {
+		if (this.sourceElementParserCache == null)
+			this.sourceElementParserCache = this.manager.indexManager.getSourceElementParser(element.getJavaProject(), null/*requestor will be set by indexer*/);
+		return this.sourceElementParserCache;
+	}
+	/*
+	 * Finds the root info this path is included in.
+	 * Returns null if not found.
+	 */
+	private RootInfo enclosingRootInfo(IPath path, int kind) {
+		while (path != null && path.segmentCount() > 0) {
+			RootInfo rootInfo =  rootInfo(path, kind);
+			if (rootInfo != null) return rootInfo;
+			path = path.removeLastSegments(1);
+		}
+		return null;
+	}
+
+	private IPath externalPath(IResource res) {
+		IPath resourcePath = res.getFullPath();
+		if (ExternalFoldersManager.isInternalPathForExternalFolder(resourcePath))
+			return res.getLocation();
+		return resourcePath;
+	}
+
+	/*
+	 * Fire Java Model delta, flushing them after the fact after post_change notification.
+	 * If the firing mode has been turned off, this has no effect.
+	 */
+	public void fire(IJavaElementDelta customDelta, int eventType) {
+		if (!this.isFiring) return;
+
+		if (DEBUG) {
+			System.out.println("-----------------------------------------------------------------------------------------------------------------------");//$NON-NLS-1$
+		}
+
+		IJavaElementDelta deltaToNotify;
+		if (customDelta == null){
+			deltaToNotify = mergeDeltas(this.javaModelDeltas);
+		} else {
+			deltaToNotify = customDelta;
+		}
+
+		// Refresh internal scopes
+		if (deltaToNotify != null) {
+			Iterator scopes = this.manager.searchScopes.keySet().iterator();
+			while (scopes.hasNext()) {
+				AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
+				scope.processDelta(deltaToNotify, eventType);
+			}
+			JavaWorkspaceScope workspaceScope = this.manager.workspaceScope;
+			if (workspaceScope != null)
+				workspaceScope.processDelta(deltaToNotify, eventType);
+		}
+
+		// Notification
+
+		// Important: if any listener reacts to notification by updating the listeners list or mask, these lists will
+		// be duplicated, so it is necessary to remember original lists in a variable (since field values may change under us)
+		IElementChangedListener[] listeners;
+		int[] listenerMask;
+		int listenerCount;
+		synchronized (this.state) {
+			listeners = this.state.elementChangedListeners;
+			listenerMask = this.state.elementChangedListenerMasks;
+			listenerCount = this.state.elementChangedListenerCount;
+		}
+
+		switch (eventType) {
+			case DEFAULT_CHANGE_EVENT:
+			case ElementChangedEvent.POST_CHANGE:
+				firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
+				fireReconcileDelta(listeners, listenerMask, listenerCount);
+				break;
+		}
+	}
+
+	private void firePostChangeDelta(
+		IJavaElementDelta deltaToNotify,
+		IElementChangedListener[] listeners,
+		int[] listenerMask,
+		int listenerCount) {
+
+		// post change deltas
+		if (DEBUG){
+			System.out.println("FIRING POST_CHANGE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
+			System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+		}
+		if (deltaToNotify != null) {
+			// flush now so as to keep listener reactions to post their own deltas for subsequent iteration
+			flush();
+
+			// mark the operation stack has not modifying resources since resource deltas are being fired
+			JavaModelOperation.setAttribute(JavaModelOperation.HAS_MODIFIED_RESOURCE_ATTR, null);
+
+			notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount);
+		}
+	}
+	private void fireReconcileDelta(
+		IElementChangedListener[] listeners,
+		int[] listenerMask,
+		int listenerCount) {
+
+
+		IJavaElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values());
+		if (DEBUG){
+			System.out.println("FIRING POST_RECONCILE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
+			System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
+		}
+		if (deltaToNotify != null) {
+			// flush now so as to keep listener reactions to post their own deltas for subsequent iteration
+			this.reconcileDeltas = new HashMap();
+
+			notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount);
+		}
+	}
+	/*
+	 * Returns whether a given delta contains some information relevant to the JavaModel,
+	 * in particular it will not consider SYNC or MARKER only deltas.
+	 */
+	private boolean isAffectedBy(IResourceDelta rootDelta){
+		//if (rootDelta == null) System.out.println("NULL DELTA");
+		//long start = System.currentTimeMillis();
+		if (rootDelta != null) {
+			// use local exception to quickly escape from delta traversal
+			class FoundRelevantDeltaException extends RuntimeException {
+				private static final long serialVersionUID = 7137113252936111022L; // backward compatible
+				// only the class name is used (to differenciate from other RuntimeExceptions)
+			}
+			try {
+				rootDelta.accept(new IResourceDeltaVisitor() {
+					public boolean visit(IResourceDelta delta) /* throws CoreException */ {
+						switch (delta.getKind()){
+							case IResourceDelta.ADDED :
+							case IResourceDelta.REMOVED :
+								throw new FoundRelevantDeltaException();
+							case IResourceDelta.CHANGED :
+								// if any flag is set but SYNC or MARKER, this delta should be considered
+								if (delta.getAffectedChildren().length == 0 // only check leaf delta nodes
+										&& (delta.getFlags() & ~(IResourceDelta.SYNC | IResourceDelta.MARKERS)) != 0) {
+									throw new FoundRelevantDeltaException();
+								}
+						}
+						return true;
+					}
+				},
+				IContainer.INCLUDE_HIDDEN);
+			} catch(FoundRelevantDeltaException e) {
+				//System.out.println("RELEVANT DELTA detected in: "+ (System.currentTimeMillis() - start));
+				return true;
+			} catch(CoreException e) { // ignore delta if not able to traverse
+			}
+		}
+		//System.out.println("IGNORE SYNC DELTA took: "+ (System.currentTimeMillis() - start));
+		return false;
+	}
+	/*
+	 * Returns whether the given element is a primary compilation unit in working copy mode.
+	 */
+	private boolean isPrimaryWorkingCopy(IJavaElement element, int elementType) {
+		if (elementType == IJavaElement.COMPILATION_UNIT) {
+			CompilationUnit cu = (CompilationUnit)element;
+			return cu.isPrimary() && cu.isWorkingCopy();
+		}
+		return false;
+	}
+	/*
+	 * Returns whether the given resource is in one of the given output folders and if
+	 * it is filtered out from this output folder.
+	 */
+	private boolean isResFilteredFromOutput(RootInfo rootInfo, OutputsInfo info, IResource res, int elementType) {
+		if (info != null) {
+			JavaProject javaProject = null;
+			String sourceLevel = null;
+			String complianceLevel = null;
+			IPath resPath = res.getFullPath();
+			for (int i = 0;  i < info.outputCount; i++) {
+				if (info.paths[i].isPrefixOf(resPath)) {
+					if (info.traverseModes[i] != IGNORE) {
+						// case of bin=src
+						if (info.traverseModes[i] == SOURCE && elementType == IJavaElement.CLASS_FILE) {
+							return true;
+						}
+						// case of .class file under project and no source folder
+						// proj=bin
+						if (elementType == IJavaElement.JAVA_PROJECT && res instanceof IFile) {
+							if (sourceLevel == null) {
+								// Get java project to use its source and compliance levels
+								javaProject = rootInfo == null ?
+									(JavaProject)createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) :
+									rootInfo.project;
+								if (javaProject != null) {
+									sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+									complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+								}
+							}
+							if (Util.isValidClassFileName(res.getName(), sourceLevel, complianceLevel)) {
+								return true;
+							}
+						}
+					} else {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+	/*
+	 * Merges all awaiting deltas.
+	 */
+	private IJavaElementDelta mergeDeltas(Collection deltas) {
+		if (deltas.size() == 0) return null;
+		if (deltas.size() == 1) return (IJavaElementDelta)deltas.iterator().next();
+
+		if (VERBOSE) {
+			System.out.println("MERGING " + deltas.size() + " DELTAS ["+Thread.currentThread()+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+
+		Iterator iterator = deltas.iterator();
+		JavaElementDelta rootDelta = new JavaElementDelta(this.manager.javaModel);
+		boolean insertedTree = false;
+		while (iterator.hasNext()) {
+			JavaElementDelta delta = (JavaElementDelta)iterator.next();
+			if (VERBOSE) {
+				System.out.println(delta.toString());
+			}
+			IJavaElement element = delta.getElement();
+			if (this.manager.javaModel.equals(element)) {
+				IJavaElementDelta[] children = delta.getAffectedChildren();
+				for (int j = 0; j < children.length; j++) {
+					JavaElementDelta projectDelta = (JavaElementDelta) children[j];
+					rootDelta.insertDeltaTree(projectDelta.getElement(), projectDelta);
+					insertedTree = true;
+				}
+				IResourceDelta[] resourceDeltas = delta.getResourceDeltas();
+				if (resourceDeltas != null) {
+					for (int i = 0, length = resourceDeltas.length; i < length; i++) {
+						rootDelta.addResourceDelta(resourceDeltas[i]);
+						insertedTree = true;
+					}
+				}
+			} else {
+				rootDelta.insertDeltaTree(element, delta);
+				insertedTree = true;
+			}
+		}
+		if (insertedTree) return rootDelta;
+		return null;
+	}
+	private void notifyListeners(IJavaElementDelta deltaToNotify, int eventType, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
+		final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
+		for (int i= 0; i < listenerCount; i++) {
+			if ((listenerMask[i] & eventType) != 0){
+				final IElementChangedListener listener = listeners[i];
+				long start = -1;
+				if (VERBOSE) {
+					System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
+					start = System.currentTimeMillis();
+				}
+				// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+				SafeRunner.run(new ISafeRunnable() {
+					public void handleException(Throwable exception) {
+						Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+					}
+					public void run() throws Exception {
+						PerformanceStats stats = null;
+						if(PERF) {
+							stats = PerformanceStats.getStats(JavaModelManager.DELTA_LISTENER_PERF, listener);
+							stats.startRun();
+						}
+						listener.elementChanged(extraEvent);
+						if(PERF) {
+							stats.endRun();
+						}
+					}
+				});
+				if (VERBOSE) {
+					System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		}
+	}
+	private void notifyTypeHierarchies(IElementChangedListener[] listeners, int listenerCount) {
+		for (int i= 0; i < listenerCount; i++) {
+			final IElementChangedListener listener = listeners[i];
+			if (!(listener instanceof TypeHierarchy)) continue;
+
+			// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
+			SafeRunner.run(new ISafeRunnable() {
+				public void handleException(Throwable exception) {
+					Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
+				}
+				public void run() throws Exception {
+					TypeHierarchy typeHierarchy = (TypeHierarchy)listener;
+					if (typeHierarchy.hasFineGrainChanges()) {
+						// case of changes in primary working copies
+						typeHierarchy.needsRefresh = true;
+						typeHierarchy.fireChange();
+					}
+				}
+			});
+		}
+	}
+	/*
+	 * Generic processing for elements with changed contents:<ul>
+	 * <li>The element is closed such that any subsequent accesses will re-open
+	 * the element reflecting its new structure.
+	 * <li>An entry is made in the delta reporting a content change (K_CHANGE with F_CONTENT flag set).
+	 * </ul>
+	 */
+	private void nonJavaResourcesChanged(Openable element, IResourceDelta delta) 	throws JavaModelException {
+		// reset non-java resources if element was open
+		if (element.isOpen()) {
+			JavaElementInfo info = (JavaElementInfo)element.getElementInfo();
+			switch (element.getElementType()) {
+				case IJavaElement.JAVA_MODEL :
+					((JavaModelInfo) info).nonJavaResources = null;
+					if (!ExternalFoldersManager.isInternalPathForExternalFolder(delta.getFullPath()))
+						currentDelta().addResourceDelta(delta);
+					return;
+				case IJavaElement.JAVA_PROJECT :
+					((JavaProjectElementInfo) info).setNonJavaResources(null);
+
+					// if a package fragment root is the project, clear it too
+					JavaProject project = (JavaProject) element;
+					PackageFragmentRoot projectRoot =
+						(PackageFragmentRoot) project.getPackageFragmentRoot(project.getProject());
+					if (projectRoot.isOpen()) {
+						((PackageFragmentRootInfo) projectRoot.getElementInfo()).setNonJavaResources(null);
+					}
+					break;
+				case IJavaElement.PACKAGE_FRAGMENT :
+					 ((PackageFragmentInfo) info).setNonJavaResources(null);
+					break;
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+					 ((PackageFragmentRootInfo) info).setNonJavaResources(null);
+			}
+		}
+
+		JavaElementDelta current = currentDelta();
+		JavaElementDelta elementDelta = current.find(element);
+		if (elementDelta == null) {
+			// don't use find after creating the delta as it can be null (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63434)
+			elementDelta = current.changed(element, IJavaElementDelta.F_CONTENT);
+		}
+		if (!ExternalFoldersManager.isInternalPathForExternalFolder(delta.getFullPath()))
+			elementDelta.addResourceDelta(delta);
+	}
+	/*
+	 * Returns the old root info for the given path and project.
+	 */
+	private RootInfo oldRootInfo(IPath path, JavaProject project) {
+		RootInfo oldInfo = (RootInfo) this.state.oldRoots.get(path);
+		if (oldInfo == null)
+			return null;
+		if (oldInfo.project.equals(project))
+			return oldInfo;
+		ArrayList oldInfos = (ArrayList) this.state.oldOtherRoots.get(path);
+		if (oldInfos == null)
+			return null;
+		for (int i = 0, length = oldInfos.size(); i < length; i++) {
+			oldInfo = (RootInfo) oldInfos.get(i);
+			if (oldInfo.project.equals(project))
+				return oldInfo;
+		}
+		return null;
+	}
+	/*
+	 * Returns the other root infos for the given path. Look in the old other roots table if kind is REMOVED.
+	 */
+	private ArrayList otherRootsInfo(IPath path, int kind) {
+		if (kind == IResourceDelta.REMOVED) {
+			return (ArrayList)this.state.oldOtherRoots.get(path);
+		}
+		return (ArrayList)this.state.otherRoots.get(path);
+	}
+
+	private OutputsInfo outputsInfo(RootInfo rootInfo, IResource res) {
+		try {
+			JavaProject proj =
+				rootInfo == null ?
+					(JavaProject)createElement(res.getProject(), IJavaElement.JAVA_PROJECT, null) :
+					rootInfo.project;
+			if (proj != null) {
+				IPath projectOutput = proj.getOutputLocation();
+				int traverseMode = IGNORE;
+				if (proj.getProject().getFullPath().equals(projectOutput)){ // case of proj==bin==src
+					return new OutputsInfo(new IPath[] {projectOutput}, new int[] {SOURCE}, 1);
+				}
+				IClasspathEntry[] classpath = proj.getResolvedClasspath();
+				IPath[] outputs = new IPath[classpath.length+1];
+				int[] traverseModes = new int[classpath.length+1];
+				int outputCount = 1;
+				outputs[0] = projectOutput;
+				traverseModes[0] = traverseMode;
+				for (int i = 0, length = classpath.length; i < length; i++) {
+					IClasspathEntry entry = classpath[i];
+					IPath entryPath = entry.getPath();
+					IPath output = entry.getOutputLocation();
+					if (output != null) {
+						outputs[outputCount] = output;
+						// check case of src==bin
+						if (entryPath.equals(output)) {
+							traverseModes[outputCount++] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
+						} else {
+							traverseModes[outputCount++] = IGNORE;
+						}
+					}
+
+					// check case of src==bin
+					if (entryPath.equals(projectOutput)) {
+						traverseModes[0] = (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) ? SOURCE : BINARY;
+					}
+				}
+				return new OutputsInfo(outputs, traverseModes, outputCount);
+			}
+		} catch (JavaModelException e) {
+			// java project doesn't exist: ignore
+		}
+		return null;
+	}
+	private void popUntilPrefixOf(IPath path) {
+		while (this.currentElement != null) {
+			IPath currentElementPath = null;
+			if (this.currentElement instanceof IPackageFragmentRoot) {
+				currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath();
+			} else {
+				IResource currentElementResource = this.currentElement.resource();
+				if (currentElementResource != null) {
+					currentElementPath = currentElementResource.getFullPath();
+				}
+			}
+			if (currentElementPath != null) {
+				if (this.currentElement instanceof IPackageFragment
+					&& ((IPackageFragment) this.currentElement).isDefaultPackage()
+					&& currentElementPath.segmentCount() != path.segmentCount()-1) {
+						// default package and path is not a direct child
+						this.currentElement = (Openable)this.currentElement.getParent();
+				}
+				if (currentElementPath.isPrefixOf(path)) {
+					return;
+				}
+			}
+			this.currentElement = (Openable)this.currentElement.getParent();
+		}
+	}
+	/*
+	 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
+	 * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
+	 * relevant <code>JavaModel</code>s.
+	 */
+	private IJavaElementDelta processResourceDelta(IResourceDelta changes) {
+
+		try {
+			IJavaModel model = this.manager.getJavaModel();
+			if (!model.isOpen()) {
+				// force opening of java model so that java element delta are reported
+				try {
+					model.open(null);
+				} catch (JavaModelException e) {
+					if (VERBOSE) {
+						e.printStackTrace();
+					}
+					return null;
+				}
+			}
+			this.state.initializeRoots(false/*not initiAfterLoad*/);
+			this.currentElement = null;
+
+			// get the workspace delta, and start processing there.
+			IResourceDelta[] deltas = changes.getAffectedChildren(IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED, IContainer.INCLUDE_HIDDEN);
+			for (int i = 0; i < deltas.length; i++) {
+				IResourceDelta delta = deltas[i];
+				IResource res = delta.getResource();
+
+				// find out the element type
+				RootInfo rootInfo = null;
+				int elementType;
+				IProject proj = (IProject)res;
+				boolean wasJavaProject = this.state.findJavaProject(proj.getName()) != null;
+				boolean isJavaProject = JavaProject.hasJavaNature(proj);
+				if (!wasJavaProject && !isJavaProject) {
+					elementType = NON_JAVA_RESOURCE;
+				} else {
+					IPath rootPath = externalPath(res);
+					rootInfo = enclosingRootInfo(rootPath, delta.getKind());
+					if (rootInfo != null && rootInfo.isRootOfProject(rootPath)) {
+						elementType = IJavaElement.PACKAGE_FRAGMENT_ROOT;
+					} else {
+						elementType = IJavaElement.JAVA_PROJECT;
+					}
+				}
+
+				// traverse delta
+				traverseDelta(delta, elementType, rootInfo, null);
+
+				if (elementType == NON_JAVA_RESOURCE
+						|| (wasJavaProject != isJavaProject && (delta.getKind()) == IResourceDelta.CHANGED)) { // project has changed nature (description or open/closed)
+					try {
+						// add child as non java resource
+						nonJavaResourcesChanged((JavaModel)model, delta);
+					} catch (JavaModelException e) {
+						// java model could not be opened
+					}
+				}
+
+			}
+			resetProjectCaches();
+
+			return this.currentDelta;
+		} finally {
+			this.currentDelta = null;
+		}
+	}
+	/*
+	 * Traverse the set of projects which have changed namespace, and reset their
+	 * caches and their dependents
+	 */
+	public void resetProjectCaches() {
+		if (this.projectCachesToReset.size() == 0)
+			return;
+
+		JavaModelManager.getJavaModelManager().resetJarTypeCache();
+
+		Iterator iterator = this.projectCachesToReset.iterator();
+		HashMap projectDepencies = this.state.projectDependencies;
+		HashSet affectedDependents = new HashSet();
+		while (iterator.hasNext()) {
+			JavaProject project = (JavaProject)iterator.next();
+			project.resetCaches();
+			addDependentProjects(project, projectDepencies, affectedDependents);
+		}
+		// reset caches of dependent projects
+		iterator = affectedDependents.iterator();
+		while (iterator.hasNext()) {
+			JavaProject project = (JavaProject) iterator.next();
+			project.resetCaches();
+		}
+
+		this.projectCachesToReset.clear();
+	}
+	/*
+	 * Registers the given delta with this delta processor.
+	 */
+	public void registerJavaModelDelta(IJavaElementDelta delta) {
+		this.javaModelDeltas.add(delta);
+	}
+	/*
+	 * Removes the given element from its parents cache of children. If the
+	 * element does not have a parent, or the parent is not currently open,
+	 * this has no effect.
+	 */
+	private void removeFromParentInfo(Openable child) {
+
+		Openable parent = (Openable) child.getParent();
+		if (parent != null && parent.isOpen()) {
+			try {
+				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
+				info.removeChild(child);
+			} catch (JavaModelException e) {
+				// do nothing - we already checked if open
+			}
+		}
+	}
+	/*
+	 * Notification that some resource changes have happened
+	 * on the platform, and that the Java Model should update any required
+	 * internal structures such that its elements remain consistent.
+	 * Translates <code>IResourceDeltas</code> into <code>IJavaElementDeltas</code>.
+	 *
+	 * @see IResourceDelta
+	 * @see IResource
+	 */
+	public void resourceChanged(IResourceChangeEvent event) {
+
+		int eventType = this.overridenEventType == -1 ? event.getType() : this.overridenEventType;
+		IResource resource = event.getResource();
+		IResourceDelta delta = event.getDelta();
+
+		switch(eventType){
+			case IResourceChangeEvent.PRE_DELETE :
+				try {
+					if(resource.getType() == IResource.PROJECT
+						&& ((IProject) resource).hasNature(JavaCore.NATURE_ID)) {
+
+						deleting((IProject)resource);
+					}
+				} catch(CoreException e){
+					// project doesn't exist or is not open: ignore
+				}
+				return;
+
+			case IResourceChangeEvent.PRE_REFRESH:
+				IProject [] projects = null;
+				Object o = event.getSource();
+				if (o instanceof IProject) {
+					projects = new IProject[] { (IProject) o };
+				} else if (o instanceof IWorkspace) {
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=261594. The single workspace refresh
+					// notification we see, implies that all projects are about to be refreshed.
+					 projects = ((IWorkspace) o).getRoot().getProjects(IContainer.INCLUDE_HIDDEN);
+				}
+				//https://bugs.eclipse.org/bugs/show_bug.cgi?id=302295
+				// Refresh all project references together in a single job
+				JavaModelManager.getExternalManager().refreshReferences(projects, null);
+				
+				IJavaProject[] javaElements = new IJavaProject[projects.length];
+				for (int index = 0; index < projects.length; index++) {
+					javaElements[index] = JavaCore.create(projects[index]);
+				}
+				try {
+					checkExternalArchiveChanges(javaElements, true, null);
+				} catch (JavaModelException e) {
+		        	if (!e.isDoesNotExist())
+		        		Util.log(e, "Exception while updating external archives"); //$NON-NLS-1$
+				}
+				return;
+
+			case IResourceChangeEvent.POST_CHANGE :
+				HashSet elementsToRefresh = this.state.removeExternalElementsToRefresh();
+				if (isAffectedBy(delta) // avoid populating for SYNC or MARKER deltas
+						|| elementsToRefresh != null) {
+					try {
+						try {
+							stopDeltas();
+							checkProjectsAndClasspathChanges(delta);
+
+							// generate external archive change deltas
+							if (elementsToRefresh != null) {
+								createExternalArchiveDelta(elementsToRefresh, null);
+							}
+
+							// generate classpath change deltas
+							HashMap classpathChanges = this.state.removeAllClasspathChanges();
+							if (classpathChanges.size() > 0) {
+								boolean hasDelta = this.currentDelta != null;
+								JavaElementDelta javaDelta = currentDelta();
+								Iterator changes = classpathChanges.values().iterator();
+								while (changes.hasNext()) {
+									ClasspathChange change = (ClasspathChange) changes.next();
+									int result = change.generateDelta(javaDelta, false/*don't add classpath change*/);
+									if ((result & ClasspathChange.HAS_DELTA) != 0) {
+										hasDelta = true;
+
+										// need to recompute root infos
+										this.state.rootsAreStale = true;
+
+										change.requestIndexing();
+										this.state.addClasspathValidation(change.project);
+									}
+									if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) {
+										this.state.addProjectReferenceChange(change.project, change.oldResolvedClasspath);
+									}
+									if ((result & ClasspathChange.HAS_LIBRARY_CHANGE) != 0) {
+										this.state.addExternalFolderChange(change.project, change.oldResolvedClasspath);
+									}
+								}
+								// process late coming external elements to refresh (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769 )
+								elementsToRefresh = this.state.removeExternalElementsToRefresh();
+								if (elementsToRefresh != null) {
+									hasDelta |= createExternalArchiveDelta(elementsToRefresh, null);
+								}
+								if (!hasDelta)
+									this.currentDelta = null;
+							}
+
+							// generate Java deltas from resource changes
+							IJavaElementDelta translatedDelta = processResourceDelta(delta);
+							if (translatedDelta != null) {
+								registerJavaModelDelta(translatedDelta);
+							}
+						} finally {
+							this.sourceElementParserCache = null; // don't hold onto parser longer than necessary
+							startDeltas();
+						}
+						IElementChangedListener[] listeners;
+						int listenerCount;
+						synchronized (this.state) {
+							listeners = this.state.elementChangedListeners;
+							listenerCount = this.state.elementChangedListenerCount;
+						}
+						notifyTypeHierarchies(listeners, listenerCount);
+						fire(null, ElementChangedEvent.POST_CHANGE);
+					} finally {
+						// workaround for bug 15168 circular errors not reported
+						this.state.resetOldJavaProjectNames();
+						this.oldRoots = null;
+					}
+				}
+				return;
+
+			case IResourceChangeEvent.PRE_BUILD :
+				// force initialization of roots before builders run to avoid deadlock in another thread
+				// (note this is no-op if already initialized)
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241751
+				this.state.initializeRoots(false/*not initiAfterLoad*/);
+				
+				boolean isAffected = isAffectedBy(delta);
+				boolean needCycleValidation = isAffected && validateClasspaths(delta);
+
+				// update external folders if necessary
+			    ExternalFolderChange[] folderChanges = this.state.removeExternalFolderChanges();
+				if (folderChanges != null) {
+				    for (int i = 0, length = folderChanges.length; i < length; i++) {
+				        try {
+					        folderChanges[i].updateExternalFoldersIfNecessary(false/*do not refresh since we are not in the thread that added the external folder to the classpath*/, null);
+				        } catch (JavaModelException e) {
+				        	if (!e.isDoesNotExist())
+				        		Util.log(e, "Exception while updating external folders"); //$NON-NLS-1$
+				        }
+				    }
+				}
+
+				// create classpath markers if necessary
+				ClasspathValidation[] validations = this.state.removeClasspathValidations();
+				if (validations != null) {
+					for (int i = 0, length = validations.length; i < length; i++) {
+						ClasspathValidation validation = validations[i];
+						validation.validate();
+					}
+				}
+
+				// update project references if necessary
+			    ProjectReferenceChange[] projectRefChanges = this.state.removeProjectReferenceChanges();
+				if (projectRefChanges != null) {
+				    for (int i = 0, length = projectRefChanges.length; i < length; i++) {
+				        try {
+					        projectRefChanges[i].updateProjectReferencesIfNecessary();
+				        } catch(JavaModelException e) {
+				            // project doesn't exist any longer, continue with next one
+				        	if (!e.isDoesNotExist())
+				        		Util.log(e, "Exception while updating project references"); //$NON-NLS-1$
+				        }
+				    }
+				}
+
+				if (needCycleValidation || projectRefChanges != null) {
+					// update all cycle markers since the project references changes may have affected cycles
+					try {
+						JavaProject.validateCycles(null);
+					} catch (JavaModelException e) {
+						// a project no longer exists
+					}
+				}
+
+				if (isAffected) {
+					JavaModel.flushExternalFileCache();
+					JavaBuilder.buildStarting();
+				}
+
+				// does not fire any deltas
+				return;
+
+			case IResourceChangeEvent.POST_BUILD :
+				JavaBuilder.buildFinished();
+				return;
+		}
+	}
+
+	/*
+	 * Returns the root info for the given path. Look in the old roots table if kind is REMOVED.
+	 */
+	private RootInfo rootInfo(IPath path, int kind) {
+		if (kind == IResourceDelta.REMOVED) {
+			return (RootInfo)this.state.oldRoots.get(path);
+		}
+		return (RootInfo)this.state.roots.get(path);
+	}
+	/*
+	 * Turns the firing mode to on. That is, deltas that are/have been
+	 * registered will be fired.
+	 */
+	private void startDeltas() {
+		this.isFiring= true;
+	}
+	/*
+	 * Turns the firing mode to off. That is, deltas that are/have been
+	 * registered will not be fired until deltas are started again.
+	 */
+	private void stopDeltas() {
+		this.isFiring= false;
+	}
+	/*
+	 * Converts an <code>IResourceDelta</code> and its children into
+	 * the corresponding <code>IJavaElementDelta</code>s.
+	 */
+	private void traverseDelta(
+		IResourceDelta delta,
+		int elementType,
+		RootInfo rootInfo,
+		OutputsInfo outputsInfo) {
+
+		IResource res = delta.getResource();
+
+		// set stack of elements
+		if (this.currentElement == null && rootInfo != null) {
+			this.currentElement = rootInfo.project;
+		}
+
+		// process current delta
+		boolean processChildren = true;
+		if (res instanceof IProject) {
+			// reset source element parser cache
+			this.sourceElementParserCache = null;
+
+			processChildren =
+				updateCurrentDeltaAndIndex(
+					delta,
+					elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT ?
+						IJavaElement.JAVA_PROJECT : // case of prj=src
+						elementType,
+					rootInfo);
+		} else if (rootInfo != null) {
+			processChildren = updateCurrentDeltaAndIndex(delta, elementType, rootInfo);
+		} else {
+			// not yet inside a package fragment root
+			processChildren = true;
+		}
+
+		// get the project's output locations and traverse mode
+		if (outputsInfo == null) outputsInfo = outputsInfo(rootInfo, res);
+
+		// process children if needed
+		if (processChildren) {
+			IResourceDelta[] children = delta.getAffectedChildren();
+			boolean oneChildOnClasspath = false;
+			int length = children.length;
+			IResourceDelta[] orphanChildren = null;
+			Openable parent = null;
+			boolean isValidParent = true;
+			for (int i = 0; i < length; i++) {
+				IResourceDelta child = children[i];
+				IResource childRes = child.getResource();
+
+				// check source attachment change
+				checkSourceAttachmentChange(child, childRes);
+
+				// find out whether the child is a package fragment root of the current project
+				IPath childPath = externalPath(childRes);
+				int childKind = child.getKind();
+				RootInfo childRootInfo = rootInfo(childPath, childKind);
+				RootInfo originalChildRootInfo = childRootInfo;
+				if (childRootInfo != null && !childRootInfo.isRootOfProject(childPath)) {
+					// package fragment root of another project (dealt with later)
+					childRootInfo = null;
+				}
+
+				// compute child type
+				int childType =
+					elementType(
+						childRes,
+						childKind,
+						elementType,
+						rootInfo == null ? childRootInfo : rootInfo
+					);
+
+				// is childRes in the output folder and is it filtered out ?
+				boolean isResFilteredFromOutput = isResFilteredFromOutput(rootInfo, outputsInfo, childRes, childType);
+
+				boolean isNestedRoot = rootInfo != null && childRootInfo != null;
+				if (!isResFilteredFromOutput
+						&& !isNestedRoot) { // do not treat as non-java rsc if nested root
+
+					traverseDelta(child, childType, rootInfo == null ? childRootInfo : rootInfo, outputsInfo); // traverse delta for child in the same project
+
+					if (childType == NON_JAVA_RESOURCE) {
+						if (rootInfo != null) { // if inside a package fragment root
+							if (!isValidParent) continue;
+							if (parent == null) {
+								// find the parent of the non-java resource to attach to
+								if (this.currentElement == null
+										|| !rootInfo.project.equals(this.currentElement.getJavaProject())) { // note if currentElement is the IJavaModel, getJavaProject() is null
+									// force the currentProject to be used
+									this.currentElement = rootInfo.project;
+								}
+								if (elementType == IJavaElement.JAVA_PROJECT
+									|| (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT
+										&& res instanceof IProject)) {
+									// NB: attach non-java resource to project (not to its package fragment root)
+									parent = rootInfo.project;
+								} else {
+									parent = createElement(res, elementType, rootInfo);
+								}
+								if (parent == null) {
+									isValidParent = false;
+									continue;
+								}
+							}
+							// add child as non java resource
+							try {
+								nonJavaResourcesChanged(parent, child);
+							} catch (JavaModelException e) {
+								// ignore
+							}
+						} else {
+							// the non-java resource (or its parent folder) will be attached to the java project
+							if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
+							orphanChildren[i] = child;
+						}
+					} else {
+						if (rootInfo == null && childRootInfo == null) {
+							// the non-java resource (or its parent folder) will be attached to the java project
+							if (orphanChildren == null) orphanChildren = new IResourceDelta[length];
+							orphanChildren[i] = child;
+						}
+					}
+				} else {
+					oneChildOnClasspath = true; // to avoid reporting child delta as non-java resource delta
+				}
+
+				// if child is a nested root
+				// or if it is not a package fragment root of the current project
+				// but it is a package fragment root of another project, traverse delta too
+				if (isNestedRoot
+						|| (childRootInfo == null && originalChildRootInfo != null)) {
+					traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, originalChildRootInfo, null); // binary output of childRootInfo.project cannot be this root
+				}
+
+				// if the child is a package fragment root of one or several other projects
+				ArrayList rootList;
+				if ((rootList = otherRootsInfo(childPath, childKind)) != null) {
+					Iterator iterator = rootList.iterator();
+					while (iterator.hasNext()) {
+						originalChildRootInfo = (RootInfo) iterator.next();
+						this.currentElement = null; // ensure that 2 roots refering to the same resource don't share the current element (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210746 )
+						traverseDelta(child, IJavaElement.PACKAGE_FRAGMENT_ROOT, originalChildRootInfo, null); // binary output of childRootInfo.project cannot be this root
+					}
+				}
+			}
+			if (orphanChildren != null
+					&& (oneChildOnClasspath // orphan children are siblings of a package fragment root
+						|| res instanceof IProject)) { // non-java resource directly under a project
+
+				// attach orphan children
+				IProject rscProject = res.getProject();
+				JavaProject adoptiveProject = (JavaProject)JavaCore.create(rscProject);
+				if (adoptiveProject != null
+						&& JavaProject.hasJavaNature(rscProject)) { // delta iff Java project (18698)
+					for (int i = 0; i < length; i++) {
+						if (orphanChildren[i] != null) {
+							try {
+								nonJavaResourcesChanged(adoptiveProject, orphanChildren[i]);
+							} catch (JavaModelException e) {
+								// ignore
+							}
+						}
+					}
+				}
+			} // else resource delta will be added by parent
+		} // else resource delta will be added by parent
+	}
+
+	private void validateClasspaths(IResourceDelta delta, HashSet affectedProjects) {
+		IResource resource = delta.getResource();
+		boolean processChildren = false;
+		switch (resource.getType()) {
+			case IResource.ROOT :
+				if (delta.getKind() == IResourceDelta.CHANGED) {
+					processChildren = true;
+				}
+				break;
+			case IResource.PROJECT :
+				IProject project = (IProject)resource;
+				int kind = delta.getKind();
+				boolean isJavaProject = JavaProject.hasJavaNature(project);
+				switch (kind) {
+					case IResourceDelta.ADDED:
+						processChildren = isJavaProject;
+						affectedProjects.add(project.getFullPath());
+						break;
+					case IResourceDelta.CHANGED:
+						processChildren = isJavaProject;
+						if ((delta.getFlags() & IResourceDelta.OPEN) != 0) {
+							// project opened or closed
+							if (isJavaProject) {
+								JavaProject javaProject = (JavaProject)JavaCore.create(project);
+								this.state.addClasspathValidation(javaProject); // in case .classpath got modified while closed
+							}
+							affectedProjects.add(project.getFullPath());
+						} else if ((delta.getFlags() & IResourceDelta.DESCRIPTION) != 0) {
+							boolean wasJavaProject = this.state.findJavaProject(project.getName()) != null;
+							if (wasJavaProject  != isJavaProject) {
+								// project gained or lost Java nature
+								JavaProject javaProject = (JavaProject)JavaCore.create(project);
+								this.state.addClasspathValidation(javaProject); // add/remove classpath markers
+								affectedProjects.add(project.getFullPath());
+							}
+						}
+						break;
+					case IResourceDelta.REMOVED:
+						affectedProjects.add(project.getFullPath());
+						break;
+				}
+				break;
+			case IResource.FILE :
+				/* check classpath or prefs files change */
+				IFile file = (IFile) resource;
+				String fileName = file.getName();
+				RootInfo rootInfo = null;
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042
+				// Mark a validation if a library with package fragment root in the project has changed
+				if (fileName.equals(JavaProject.CLASSPATH_FILENAME)
+						|| ((rootInfo = rootInfo(file.getFullPath(), delta.getKind())) != null && rootInfo.entryKind == IClasspathEntry.CPE_LIBRARY)) {
+					JavaProject javaProject = (JavaProject)JavaCore.create(file.getProject());
+					this.state.addClasspathValidation(javaProject);
+					affectedProjects.add(file.getProject().getFullPath());
+				}
+				break;
+		}
+		if (processChildren) {
+			IResourceDelta[] children = delta.getAffectedChildren();
+			for (int i = 0; i < children.length; i++) {
+				validateClasspaths(children[i], affectedProjects);
+			}
+		}
+	}
+
+	/*
+	 * Validate the classpaths of the projects affected by the given delta.
+	 * Create markers if necessary.
+	 * Returns whether cycle markers should be recomputed.
+	 */
+	private boolean validateClasspaths(IResourceDelta delta) {
+		HashSet affectedProjects = new HashSet(5);
+		validateClasspaths(delta, affectedProjects);
+		boolean needCycleValidation = false;
+
+		// validate classpaths of affected projects (dependent projects
+		// or projects that reference a library in one of the projects that have changed)
+		if (!affectedProjects.isEmpty()) {
+			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+			IProject[] projects = workspaceRoot.getProjects();
+			int length = projects.length;
+			for (int i = 0; i < length; i++){
+				IProject project = projects[i];
+				JavaProject javaProject = (JavaProject)JavaCore.create(project);
+				try {
+					IPath projectPath = project.getFullPath();
+					IClasspathEntry[] classpath = javaProject.getResolvedClasspath(); // allowed to reuse model cache
+					for (int j = 0, cpLength = classpath.length; j < cpLength; j++) {
+						IClasspathEntry entry = classpath[j];
+						switch (entry.getEntryKind()) {
+							case IClasspathEntry.CPE_PROJECT:
+								if (affectedProjects.contains(entry.getPath())) {
+									this.state.addClasspathValidation(javaProject);
+									needCycleValidation = true;
+								}
+								break;
+							case IClasspathEntry.CPE_LIBRARY:
+								IPath entryPath = entry.getPath();
+								IPath libProjectPath = entryPath.removeLastSegments(entryPath.segmentCount()-1);
+								if (!libProjectPath.equals(projectPath) // if library contained in another project
+										&& affectedProjects.contains(libProjectPath)) {
+									this.state.addClasspathValidation(javaProject);
+								}
+								break;
+						}
+					}
+				} catch(JavaModelException e) {
+						// project no longer exists
+				}
+			}
+		}
+		return needCycleValidation;
+	}
+
+	/*
+	 * Update the current delta (i.e. add/remove/change the given element) and update the correponding index.
+	 * Returns whether the children of the given delta must be processed.
+	 * @throws a JavaModelException if the delta doesn't correspond to a java element of the given type.
+	 */
+	public boolean updateCurrentDeltaAndIndex(IResourceDelta delta, int elementType, RootInfo rootInfo) {
+		Openable element;
+		switch (delta.getKind()) {
+			case IResourceDelta.ADDED :
+				IResource deltaRes = delta.getResource();
+				element = createElement(deltaRes, elementType, rootInfo);
+				if (element == null) {
+					// resource might be containing shared roots (see bug 19058)
+					this.state.updateRoots(deltaRes.getFullPath(), delta, this);
+					return rootInfo != null && rootInfo.inclusionPatterns != null;
+				}
+				updateIndex(element, delta);
+				elementAdded(element, delta, rootInfo);
+				if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT)
+					this.state.addClasspathValidation(rootInfo.project);
+				return elementType == IJavaElement.PACKAGE_FRAGMENT;
+			case IResourceDelta.REMOVED :
+				deltaRes = delta.getResource();
+				element = createElement(deltaRes, elementType, rootInfo);
+				if (element == null) {
+					// resource might be containing shared roots (see bug 19058)
+					this.state.updateRoots(deltaRes.getFullPath(), delta, this);
+					return rootInfo != null && rootInfo.inclusionPatterns != null;
+				}
+				updateIndex(element, delta);
+				elementRemoved(element, delta, rootInfo);
+				if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT)
+					this.state.addClasspathValidation(rootInfo.project);
+
+				if (deltaRes.getType() == IResource.PROJECT){
+					// reset the corresponding project built state, since cannot reuse if added back
+					if (JavaBuilder.DEBUG)
+						System.out.println("Clearing last state for removed project : " + deltaRes); //$NON-NLS-1$
+					this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
+
+					// clean up previous session containers (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89850)
+					this.manager.previousSessionContainers.remove(element);
+				}
+				return elementType == IJavaElement.PACKAGE_FRAGMENT;
+			case IResourceDelta.CHANGED :
+				int flags = delta.getFlags();
+				if (elementType == IJavaElement.PACKAGE_FRAGMENT_ROOT && (flags & IResourceDelta.LOCAL_CHANGED) != 0) {
+					// external folder added or removed
+					if (oldRootInfo(rootInfo.rootPath, rootInfo.project) == null) {
+						// root just added to the classpath
+						break;
+					}
+					deltaRes = delta.getResource();
+					Object target = JavaModel.getExternalTarget(deltaRes.getLocation(), true/*check resource existence*/);
+					element = createElement(deltaRes, elementType, rootInfo);
+					updateIndex(element, delta);
+					if (target != null) {
+						// external folder added
+						elementAdded(element, delta, rootInfo);
+					} else {
+						// external folder removed
+						elementRemoved(element, delta, rootInfo);
+					}
+					this.state.addClasspathValidation(rootInfo.project);
+				} else if ((flags & IResourceDelta.CONTENT) != 0 || (flags & IResourceDelta.ENCODING) != 0) {
+					// content or encoding has changed
+					element = createElement(delta.getResource(), elementType, rootInfo);
+					if (element == null) return false;
+					updateIndex(element, delta);
+					contentChanged(element);
+				} else if (elementType == IJavaElement.JAVA_PROJECT) {
+					if ((flags & IResourceDelta.OPEN) != 0) {
+						// project has been opened or closed
+						IProject res = (IProject)delta.getResource();
+						element = createElement(res, elementType, rootInfo);
+						if (element == null) {
+							// resource might be containing shared roots (see bug 19058)
+							this.state.updateRoots(res.getFullPath(), delta, this);
+							return false;
+						}
+						if (res.isOpen()) {
+							if (JavaProject.hasJavaNature(res)) {
+								addToParentInfo(element);
+								currentDelta().opened(element);
+								this.state.updateRoots(element.getPath(), delta, this);
+
+								// remember that the project's cache must be reset
+								this.projectCachesToReset.add(element);
+
+								this.manager.indexManager.indexAll(res);
+							}
+						} else {
+							boolean wasJavaProject = this.state.findJavaProject(res.getName()) != null;
+							if (wasJavaProject) {
+								close(element);
+								removeFromParentInfo(element);
+								currentDelta().closed(element);
+								this.manager.indexManager.discardJobs(element.getElementName());
+								this.manager.indexManager.removeIndexFamily(res.getFullPath());
+							}
+						}
+						return false; // when a project is open/closed don't process children
+					}
+					if ((flags & IResourceDelta.DESCRIPTION) != 0) {
+						IProject res = (IProject)delta.getResource();
+						boolean wasJavaProject = this.state.findJavaProject(res.getName()) != null;
+						boolean isJavaProject = JavaProject.hasJavaNature(res);
+						if (wasJavaProject != isJavaProject) {
+							// project's nature has been added or removed
+							element = createElement(res, elementType, rootInfo);
+							if (element == null) return false; // note its resources are still visible as roots to other projects
+							if (isJavaProject) {
+								elementAdded(element, delta, rootInfo);
+								this.manager.indexManager.indexAll(res);
+							} else {
+								elementRemoved(element, delta, rootInfo);
+								this.manager.indexManager.discardJobs(element.getElementName());
+								this.manager.indexManager.removeIndexFamily(res.getFullPath());
+								// reset the corresponding project built state, since cannot reuse if added back
+								if (JavaBuilder.DEBUG)
+									System.out.println("Clearing last state for project loosing Java nature: " + res); //$NON-NLS-1$
+								this.manager.setLastBuiltState(res, null /*no state*/);
+							}
+							return false; // when a project's nature is added/removed don't process children
+						}
+					}
+				}
+				return true;
+		}
+		return true;
+	}
+	private void updateIndex(Openable element, IResourceDelta delta) {
+
+		IndexManager indexManager = this.manager.indexManager;
+		if (indexManager == null)
+			return;
+
+		switch (element.getElementType()) {
+			case IJavaElement.JAVA_PROJECT :
+				switch (delta.getKind()) {
+					case IResourceDelta.ADDED :
+						indexManager.indexAll(element.getJavaProject().getProject());
+						break;
+					case IResourceDelta.REMOVED :
+						indexManager.removeIndexFamily(element.getJavaProject().getProject().getFullPath());
+						// NB: Discarding index jobs belonging to this project was done during PRE_DELETE
+						break;
+					// NB: Update of index if project is opened, closed, or its java nature is added or removed
+					//     is done in updateCurrentDeltaAndIndex
+				}
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+				if (element instanceof JarPackageFragmentRoot) {
+					JarPackageFragmentRoot root = (JarPackageFragmentRoot)element;
+					// index jar file only once (if the root is in its declaring project)
+					IPath jarPath = root.getPath();
+					switch (delta.getKind()) {
+						case IResourceDelta.ADDED:
+							// index the new jar
+							indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath());
+							break;
+						case IResourceDelta.CHANGED:
+							// first remove the index so that it is forced to be re-indexed
+							indexManager.removeIndex(jarPath);
+							// then index the jar
+							indexManager.indexLibrary(jarPath, root.getJavaProject().getProject(), root.getIndexPath());
+							break;
+						case IResourceDelta.REMOVED:
+							// the jar was physically removed: remove the index
+							indexManager.discardJobs(jarPath.toString());
+							indexManager.removeIndex(jarPath);
+							break;
+					}
+					break;
+				}
+				int kind = delta.getKind();
+				if (kind == IResourceDelta.ADDED || kind == IResourceDelta.REMOVED || (kind == IResourceDelta.CHANGED && (delta.getFlags() & IResourceDelta.LOCAL_CHANGED) != 0)) {
+					PackageFragmentRoot root = (PackageFragmentRoot)element;
+					updateRootIndex(root, CharOperation.NO_STRINGS, delta);
+					break;
+				}
+				// don't break as packages of the package fragment root can be indexed below
+				// $FALL-THROUGH$
+			case IJavaElement.PACKAGE_FRAGMENT :
+				switch (delta.getKind()) {
+					case IResourceDelta.CHANGED:
+						if ((delta.getFlags() & IResourceDelta.LOCAL_CHANGED) == 0)
+							break;
+						// $FALL-THROUGH$
+					case IResourceDelta.ADDED:
+					case IResourceDelta.REMOVED:
+						IPackageFragment pkg = null;
+						if (element instanceof IPackageFragmentRoot) {
+							PackageFragmentRoot root = (PackageFragmentRoot)element;
+							pkg = root.getPackageFragment(CharOperation.NO_STRINGS);
+						} else {
+							pkg = (IPackageFragment)element;
+						}
+						RootInfo rootInfo = rootInfo(pkg.getParent().getPath(), delta.getKind());
+						boolean isSource =
+							rootInfo == null // if null, defaults to source
+							|| rootInfo.entryKind == IClasspathEntry.CPE_SOURCE;
+						IResourceDelta[] children = delta.getAffectedChildren();
+						for (int i = 0, length = children.length; i < length; i++) {
+							IResourceDelta child = children[i];
+							IResource resource = child.getResource();
+							// TODO (philippe) Why do this? Every child is added anyway as the delta is walked
+							if (resource instanceof IFile) {
+								String name = resource.getName();
+								if (isSource) {
+									if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) {
+										Openable cu = (Openable)pkg.getCompilationUnit(name);
+										updateIndex(cu, child);
+									}
+								} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
+									Openable classFile = (Openable)pkg.getClassFile(name);
+									updateIndex(classFile, child);
+								}
+							}
+						}
+						break;
+				}
+				break;
+			case IJavaElement.CLASS_FILE :
+				IFile file = (IFile) delta.getResource();
+				IJavaProject project = element.getJavaProject();
+				PackageFragmentRoot root = element.getPackageFragmentRoot();
+				IPath binaryFolderPath = root.isExternal() && !root.isArchive() ? root.resource().getFullPath() : root.getPath();
+				// if the class file is part of the binary output, it has been created by
+				// the java builder -> ignore
+				try {
+					if (binaryFolderPath.equals(project.getOutputLocation())) {
+						break;
+					}
+				} catch (JavaModelException e) {
+					// project doesn't exist: ignore
+				}
+				switch (delta.getKind()) {
+					case IResourceDelta.CHANGED :
+						// no need to index if the content has not changed
+						int flags = delta.getFlags();
+						if ((flags & IResourceDelta.CONTENT) == 0 && (flags & IResourceDelta.ENCODING) == 0)
+							break;
+						// $FALL-THROUGH$
+					case IResourceDelta.ADDED :
+						indexManager.addBinary(file, binaryFolderPath);
+						break;
+					case IResourceDelta.REMOVED :
+						String containerRelativePath = Util.relativePath(file.getFullPath(), binaryFolderPath.segmentCount());
+						indexManager.remove(containerRelativePath, binaryFolderPath);
+						break;
+				}
+				break;
+			case IJavaElement.COMPILATION_UNIT :
+				file = (IFile) delta.getResource();
+				switch (delta.getKind()) {
+					case IResourceDelta.CHANGED :
+						// no need to index if the content has not changed
+						int flags = delta.getFlags();
+						if ((flags & IResourceDelta.CONTENT) == 0 && (flags & IResourceDelta.ENCODING) == 0)
+							break;
+						// $FALL-THROUGH$
+					case IResourceDelta.ADDED :
+						indexManager.addSource(file, file.getProject().getFullPath(), getSourceElementParser(element));
+						// Clean file from secondary types cache but do not update indexing secondary type cache as it will be updated through indexing itself
+						this.manager.secondaryTypesRemoving(file, false);
+						break;
+					case IResourceDelta.REMOVED :
+						indexManager.remove(Util.relativePath(file.getFullPath(), 1/*remove project segment*/), file.getProject().getFullPath());
+						// Clean file from secondary types cache and update indexing secondary type cache as indexing cannot remove secondary types from cache
+						this.manager.secondaryTypesRemoving(file, true);
+						break;
+				}
+		}
+	}
+	/*
+	 * Update Java Model given some delta
+	 */
+	public void updateJavaModel(IJavaElementDelta customDelta) {
+
+		if (customDelta == null){
+			for (int i = 0, length = this.javaModelDeltas.size(); i < length; i++){
+				IJavaElementDelta delta = (IJavaElementDelta)this.javaModelDeltas.get(i);
+				this.modelUpdater.processJavaDelta(delta);
+			}
+		} else {
+			this.modelUpdater.processJavaDelta(customDelta);
+		}
+	}
+	/*
+	 * Updates the index of the given root (assuming it's an addition or a removal).
+	 * This is done recusively, pkg being the current package.
+	 */
+	private void updateRootIndex(PackageFragmentRoot root, String[] pkgName, IResourceDelta delta) {
+		Openable pkg = root.getPackageFragment(pkgName);
+		updateIndex(pkg, delta);
+		IResourceDelta[] children = delta.getAffectedChildren();
+		for (int i = 0, length = children.length; i < length; i++) {
+			IResourceDelta child = children[i];
+			IResource resource = child.getResource();
+			if (resource instanceof IFolder) {
+				String[] subpkgName = Util.arrayConcat(pkgName, resource.getName());
+				updateRootIndex(root, subpkgName, child);
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java
new file mode 100644
index 0000000..4e3409d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Discards a working copy (decrement its use count and remove its working copy info if the use count is 0)
+ * and signal its removal through a delta.
+ */
+public class DiscardWorkingCopyOperation extends JavaModelOperation {
+
+	public DiscardWorkingCopyOperation(IJavaElement workingCopy) {
+		super(new IJavaElement[] {workingCopy});
+	}
+	protected void executeOperation() throws JavaModelException {
+		CompilationUnit workingCopy = getWorkingCopy();
+
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		int useCount = manager.discardPerWorkingCopyInfo(workingCopy);
+		if (useCount == 0) {
+			IJavaProject javaProject = workingCopy.getJavaProject();
+			if (ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(javaProject.getElementName())) {
+				manager.removePerProjectInfo((JavaProject) javaProject, true /* remove external jar files indexes and timestamps*/);
+				manager.containerRemove(javaProject);
+			}
+			if (!workingCopy.isPrimary()) {
+				// report removed java delta for a non-primary working copy
+				JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+				delta.removed(workingCopy);
+				addDelta(delta);
+				removeReconcileDelta(workingCopy);
+			} else {
+				if (workingCopy.getResource().isAccessible()) {
+					// report a F_PRIMARY_WORKING_COPY change delta for a primary working copy
+					JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+					delta.changed(workingCopy, IJavaElementDelta.F_PRIMARY_WORKING_COPY);
+					addDelta(delta);
+				} else {
+					// report a REMOVED delta
+					JavaElementDelta delta = new JavaElementDelta(getJavaModel());
+					delta.removed(workingCopy, IJavaElementDelta.F_PRIMARY_WORKING_COPY);
+					addDelta(delta);
+				}
+			}
+		}
+	}
+	/**
+	 * Returns the working copy this operation is working on.
+	 */
+	protected CompilationUnit getWorkingCopy() {
+		return (CompilationUnit)getElementToProcess();
+	}
+	/**
+	 * @see JavaModelOperation#isReadOnly
+	 */
+	public boolean isReadOnly() {
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java
new file mode 100644
index 0000000..a7858b9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+
+/*
+ * Adapts an IBuffer to IDocument
+ */
+public class DocumentAdapter extends Document {
+
+	private IBuffer buffer;
+
+	public DocumentAdapter(IBuffer buffer) {
+		super(buffer.getContents());
+		this.buffer = buffer;
+	}
+
+	public void set(String text) {
+		super.set(text);
+		this.buffer.setContents(text);
+	}
+
+	public void replace(int offset, int length, String text) throws BadLocationException {
+		super.replace(offset, length, text);
+		this.buffer.replace(offset, length, text);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java
new file mode 100644
index 0000000..ab9e38a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.LRUCache;
+
+/**
+ * An LRU cache of <code>JavaElements</code>.
+ */
+public class ElementCache extends OverflowingLRUCache {
+
+	IJavaElement spaceLimitParent = null;
+
+/**
+ * Constructs a new element cache of the given size.
+ */
+public ElementCache(int size) {
+	super(size);
+}
+/**
+ * Constructs a new element cache of the given size.
+ */
+public ElementCache(int size, int overflow) {
+	super(size, overflow);
+}
+/**
+ * Returns true if the element is successfully closed and
+ * removed from the cache, otherwise false.
+ *
+ * <p>NOTE: this triggers an external removal of this element
+ * by closing the element.
+ */
+protected boolean close(LRUCacheEntry entry) {
+	Openable element = (Openable) entry.key;
+	try {
+		if (!element.canBeRemovedFromCache()) {
+			return false;
+		} else {
+			element.close();
+			return true;
+		}
+	} catch (JavaModelException npe) {
+		return false;
+	}
+}
+
+/*
+ * Ensures that there is enough room for adding the children of the given info.
+ * If the space limit must be increased, record the parent that needed this space limit.
+ */
+protected void ensureSpaceLimit(Object info, IJavaElement parent) {
+	// ensure the children can be put without closing other elements
+	int childrenSize = ((JavaElementInfo) info).getChildren().length;
+	int spaceNeeded = 1 + (int)((1 + this.loadFactor) * (childrenSize + this.overflow));
+	if (this.spaceLimit < spaceNeeded) {
+		// parent is being opened with more children than the space limit
+		shrink(); // remove overflow
+		setSpaceLimit(spaceNeeded);
+		this.spaceLimitParent = parent;
+	}
+}
+
+/*
+ * Returns a new instance of the receiver.
+ */
+protected LRUCache newInstance(int size, int newOverflow) {
+	return new ElementCache(size, newOverflow);
+}
+
+/*
+ * If the given parent was the one that increased the space limit, reset
+ * the space limit to the given default value.
+ */
+protected void resetSpaceLimit(int defaultLimit, IJavaElement parent) {
+	if (parent.equals(this.spaceLimitParent)) {
+		setSpaceLimit(defaultLimit);
+		this.spaceLimitParent = null;
+	}
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFolderChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFolderChange.java
new file mode 100644
index 0000000..1f4c26a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFolderChange.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - inconsistent initialization of classpath container backed by external class folder, see https://bugs.eclipse.org/320618
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class ExternalFolderChange {
+
+	private JavaProject project;
+	private IClasspathEntry[] oldResolvedClasspath;
+
+	public ExternalFolderChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
+		this.project = project;
+		this.oldResolvedClasspath = oldResolvedClasspath;
+	}
+
+	/*
+	 * Update external folders
+	 */
+	public void updateExternalFoldersIfNecessary(boolean refreshIfExistAlready, IProgressMonitor monitor) throws JavaModelException {
+		HashSet oldFolders = ExternalFoldersManager.getExternalFolders(this.oldResolvedClasspath);
+		IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath();
+		HashSet newFolders = ExternalFoldersManager.getExternalFolders(newResolvedClasspath);
+		if (newFolders == null)
+			return;
+		ExternalFoldersManager foldersManager = JavaModelManager.getExternalManager();
+		Iterator iterator = newFolders.iterator();
+		while (iterator.hasNext()) {
+			Object folderPath = iterator.next();
+			if (oldFolders == null || !oldFolders.remove(folderPath) || foldersManager.removePendingFolder(folderPath)) {
+				try {
+					foldersManager.createLinkFolder((IPath) folderPath, refreshIfExistAlready, monitor);
+				} catch (CoreException e) {
+					throw new JavaModelException(e);
+				}
+			}
+		}
+		// removal of linked folders is done during save
+	}
+	public String toString() {
+		return "ExternalFolderChange: " + this.project.getElementName(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
new file mode 100644
index 0000000..6b86780
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
@@ -0,0 +1,473 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - inconsistent initialization of classpath container backed by external class folder, see https://bugs.eclipse.org/320618
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceStatus;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ExternalFoldersManager {
+	private static final String EXTERNAL_PROJECT_NAME = ".org.eclipse.jdt.core.external.folders"; //$NON-NLS-1$
+	private static final String LINKED_FOLDER_NAME = ".link"; //$NON-NLS-1$
+	private Map folders;
+	private Set pendingFolders; // subset of keys of 'folders', for which linked folders haven't been created yet.
+	private int counter = 0;
+	/* Singleton instance */
+	private static ExternalFoldersManager MANAGER;
+
+	private ExternalFoldersManager() {
+		// Prevent instantiation
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=377806
+		if (Platform.isRunning()) {
+			getFolders();
+		}
+	}
+	
+	public static synchronized ExternalFoldersManager getExternalFoldersManager() {
+		if (MANAGER == null) {
+			 MANAGER = new ExternalFoldersManager();
+		}
+		return MANAGER;
+	}
+	
+	/*
+	 * Returns a set of external path to external folders referred to on the given classpath.
+	 * Returns null if none.
+	 */
+	public static HashSet getExternalFolders(IClasspathEntry[] classpath) {
+		if (classpath == null)
+			return null;
+		HashSet folders = null;
+		for (int i = 0; i < classpath.length; i++) {
+			IClasspathEntry entry = classpath[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+				IPath entryPath = entry.getPath();
+				if (isExternalFolderPath(entryPath)) {
+					if (folders == null)
+						folders = new HashSet();
+					folders.add(entryPath);
+				}
+				IPath attachmentPath = entry.getSourceAttachmentPath();
+				if (isExternalFolderPath(attachmentPath)) {
+					if (folders == null)
+						folders = new HashSet();
+					folders.add(attachmentPath);
+				}
+			}
+		}
+		return folders;
+	}
+
+
+	public static boolean isExternalFolderPath(IPath externalPath) {
+		if (externalPath == null)
+			return false;
+		String firstSegment = externalPath.segment(0);
+		if (firstSegment != null && ResourcesPlugin.getWorkspace().getRoot().getProject(firstSegment).exists())
+			return false;
+		File externalFolder = externalPath.toFile();
+		if (externalFolder.isFile())
+			return false;
+		if (externalPath.getFileExtension() != null/*likely a .jar, .zip, .rar or other file*/ && !externalFolder.exists())
+			return false;
+		return true;
+	}
+
+	public static boolean isInternalPathForExternalFolder(IPath resourcePath) {
+		return EXTERNAL_PROJECT_NAME.equals(resourcePath.segment(0));
+	}
+
+	public IFolder addFolder(IPath externalFolderPath, boolean scheduleForCreation) {
+		return addFolder(externalFolderPath, getExternalFoldersProject(), scheduleForCreation);
+	}
+
+	private IFolder addFolder(IPath externalFolderPath, IProject externalFoldersProject, boolean scheduleForCreation) {
+		Map knownFolders = getFolders();
+		Object existing = knownFolders.get(externalFolderPath);
+		if (existing != null) {
+			return (IFolder) existing;
+		}
+		IFolder result;
+		do {
+			result = externalFoldersProject.getFolder(LINKED_FOLDER_NAME + this.counter++);
+		} while (result.exists());
+		if (scheduleForCreation) {
+			synchronized(this) {
+				if (this.pendingFolders == null)
+					this.pendingFolders = Collections.synchronizedSet(new HashSet());
+			}
+			this.pendingFolders.add(externalFolderPath);
+		}
+		knownFolders.put(externalFolderPath, result);
+		return result;
+	}
+	
+	/** 
+	 * Try to remove the argument from the list of folders pending for creation.
+	 * @param externalPath to link to
+	 * @return true if the argument was found in the list of pending folders and could be removed from it.
+	 */
+	public synchronized boolean removePendingFolder(Object externalPath) {
+		if (this.pendingFolders == null)
+			return false;
+		return this.pendingFolders.remove(externalPath);
+	}
+
+	public IFolder createLinkFolder(IPath externalFolderPath, boolean refreshIfExistAlready, IProgressMonitor monitor) throws CoreException {
+		IProject externalFoldersProject = createExternalFoldersProject(monitor); // run outside synchronized as this can create a resource
+		return createLinkFolder(externalFolderPath, refreshIfExistAlready, externalFoldersProject, monitor);
+	}
+
+	private IFolder createLinkFolder(IPath externalFolderPath, boolean refreshIfExistAlready,
+									IProject externalFoldersProject, IProgressMonitor monitor) throws CoreException {
+		
+		IFolder result = addFolder(externalFolderPath, externalFoldersProject, false);
+		if (!result.exists())
+			result.createLink(externalFolderPath, IResource.ALLOW_MISSING_LOCAL, monitor);
+		else if (refreshIfExistAlready)
+			result.refreshLocal(IResource.DEPTH_INFINITE,  monitor);
+		return result;
+	}
+
+	public void createPendingFolders(IProgressMonitor monitor) throws JavaModelException{
+		synchronized (this) {
+			if (this.pendingFolders == null || this.pendingFolders.isEmpty()) return;
+		}
+		
+		IProject externalFoldersProject = null;
+		try {
+			externalFoldersProject = createExternalFoldersProject(monitor);
+		}
+		catch(CoreException e) {
+			throw new JavaModelException(e);
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=368152
+		// To avoid race condition (from addFolder and removeFolder, load the map elements into an array and clear the map immediately.
+		// The createLinkFolder being in the synchronized block can cause a deadlock and hence keep it out of the synchronized block. 
+		Object[] arrayOfFolders = null;
+		synchronized (this.pendingFolders) {
+			arrayOfFolders = this.pendingFolders.toArray();
+			this.pendingFolders.clear();
+		}
+
+		for (int i=0; i < arrayOfFolders.length; i++) {
+			try {
+				createLinkFolder((IPath) arrayOfFolders[i], false, externalFoldersProject, monitor);
+			} catch (CoreException e) {
+				Util.log(e, "Error while creating a link for external folder :" + arrayOfFolders[i]); //$NON-NLS-1$
+			}
+		}
+	}
+	
+	public void cleanUp(IProgressMonitor monitor) throws CoreException {
+		ArrayList toDelete = getFoldersToCleanUp(monitor);
+		if (toDelete == null)
+			return;
+		for (Iterator iterator = toDelete.iterator(); iterator.hasNext();) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			IFolder folder = (IFolder) entry.getValue();
+			folder.delete(true, monitor);
+			IPath key = (IPath) entry.getKey();
+			this.folders.remove(key);
+		}
+		IProject project = getExternalFoldersProject();
+		if (project.isAccessible() && project.members().length == 1/*remaining member is .project*/)
+			project.delete(true, monitor);
+	}
+
+	private ArrayList getFoldersToCleanUp(IProgressMonitor monitor) throws CoreException {
+		DeltaProcessingState state = JavaModelManager.getDeltaState();
+		HashMap roots = state.roots;
+		HashMap sourceAttachments = state.sourceAttachments;
+		if (roots == null && sourceAttachments == null)
+			return null;
+		Map knownFolders = getFolders();
+		ArrayList result = null;
+		synchronized (knownFolders) {
+			Iterator iterator = knownFolders.entrySet().iterator();
+			while (iterator.hasNext()) {
+				Map.Entry entry = (Map.Entry) iterator.next();
+				IPath path = (IPath) entry.getKey();
+				if ((roots != null && !roots.containsKey(path))
+						&& (sourceAttachments != null && !sourceAttachments.containsKey(path))) {
+					if (entry.getValue() != null) {
+						if (result == null)
+							result = new ArrayList();
+						result.add(entry);
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	public IProject getExternalFoldersProject() {
+		return ResourcesPlugin.getWorkspace().getRoot().getProject(EXTERNAL_PROJECT_NAME);
+	}
+	public IProject createExternalFoldersProject(IProgressMonitor monitor) throws CoreException {
+		IProject project = getExternalFoldersProject();
+		if (!project.isAccessible()) {
+			if (!project.exists()) {
+				createExternalFoldersProject(project, monitor);
+			}
+			openExternalFoldersProject(project, monitor);
+		}
+		return project;
+	}
+
+	/*
+	 * Attempt to open the given project (assuming it exists).
+	 * If failing to open, make all attempts to recreate the missing pieces.
+	 */
+	private void openExternalFoldersProject(IProject project, IProgressMonitor monitor) throws CoreException {
+		try {
+			project.open(monitor);
+		} catch (CoreException e1) {
+			if (e1.getStatus().getCode() == IResourceStatus.FAILED_READ_METADATA) {
+				// workspace was moved 
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241400 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=252571 )
+				project.delete(false/*don't delete content*/, true/*force*/, monitor);
+				createExternalFoldersProject(project, monitor);
+			} else {
+				// .project or folder on disk have been deleted, recreate them
+				IPath stateLocation = JavaCore.getPlugin().getStateLocation();
+				IPath projectPath = stateLocation.append(EXTERNAL_PROJECT_NAME);
+				projectPath.toFile().mkdirs();
+				try {
+				    FileOutputStream output = new FileOutputStream(projectPath.append(".project").toOSString()); //$NON-NLS-1$
+				    try {
+				        output.write((
+				        		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + //$NON-NLS-1$
+				        		"<projectDescription>\n" + //$NON-NLS-1$
+				        		"	<name>" + EXTERNAL_PROJECT_NAME + "</name>\n" + //$NON-NLS-1$ //$NON-NLS-2$
+				        		"	<comment></comment>\n" + //$NON-NLS-1$
+				        		"	<projects>\n" + //$NON-NLS-1$
+				        		"	</projects>\n" + //$NON-NLS-1$
+				        		"	<buildSpec>\n" + //$NON-NLS-1$
+				        		"	</buildSpec>\n" + //$NON-NLS-1$
+				        		"	<natures>\n" + //$NON-NLS-1$
+				        		"	</natures>\n" + //$NON-NLS-1$
+				        		"</projectDescription>").getBytes()); //$NON-NLS-1$
+				    } finally {
+				        output.close();
+				    }
+				} catch (IOException e) {
+					// fallback to re-creating the project
+					project.delete(false/*don't delete content*/, true/*force*/, monitor);
+					createExternalFoldersProject(project, monitor);
+				}
+			}
+			project.open(monitor);
+		}
+	}
+
+
+	private void createExternalFoldersProject(IProject project, IProgressMonitor monitor) throws CoreException {
+		IProjectDescription desc = project.getWorkspace().newProjectDescription(project.getName());
+		IPath stateLocation = JavaCore.getPlugin().getStateLocation();
+		desc.setLocation(stateLocation.append(EXTERNAL_PROJECT_NAME));
+		project.create(desc, IResource.HIDDEN, monitor);
+	}
+
+	public IFolder getFolder(IPath externalFolderPath) {
+		return (IFolder) getFolders().get(externalFolderPath);
+	}
+
+	private Map getFolders() {
+		if (this.folders == null) {
+			Map tempFolders = new HashMap();
+			IProject project = getExternalFoldersProject();
+			try {
+				if (!project.isAccessible()) {
+					if (project.exists()) {
+						// workspace was moved (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=252571 )
+						openExternalFoldersProject(project, null/*no progress*/);
+					} else {
+						// if project doesn't exist, do not open and recreate it as it means that there are no external folders
+						return this.folders = Collections.synchronizedMap(tempFolders);
+					}
+				}
+				IResource[] members = project.members();
+				for (int i = 0, length = members.length; i < length; i++) {
+					IResource member = members[i];
+					if (member.getType() == IResource.FOLDER && member.isLinked() && member.getName().startsWith(LINKED_FOLDER_NAME)) {
+						IPath externalFolderPath = member.getLocation();
+						tempFolders.put(externalFolderPath, member);
+					}
+				}
+			} catch (CoreException e) {
+				Util.log(e, "Exception while initializing external folders"); //$NON-NLS-1$
+			}
+			this.folders = Collections.synchronizedMap(tempFolders);
+		}
+		return this.folders;
+	}
+	
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=313153
+	// Use the same RefreshJob if the job is still available
+	private void runRefreshJob(Collection paths) {
+		Job[] jobs = Job.getJobManager().find(ResourcesPlugin.FAMILY_MANUAL_REFRESH);
+		RefreshJob refreshJob = null;
+		if (jobs != null) {
+			for (int index = 0; index < jobs.length; index++) {
+				// We are only concerned about ExternalFolderManager.RefreshJob
+				if(jobs[index] instanceof RefreshJob) {
+					refreshJob =  (RefreshJob) jobs[index];
+					refreshJob.addFoldersToRefresh(paths);
+					if (refreshJob.getState() == Job.NONE) {
+						refreshJob.schedule();
+					}
+					break;
+				}
+			}
+		}
+		if (refreshJob == null) {
+			refreshJob = new RefreshJob(new Vector(paths));
+			refreshJob.schedule();
+		}
+	}
+	/*
+	 * Refreshes the external folders referenced on the classpath of the given source project
+	 */
+	public void refreshReferences(final IProject[] sourceProjects, IProgressMonitor monitor) {
+		IProject externalProject = getExternalFoldersProject();
+		try {
+			HashSet externalFolders = null;
+			for (int index = 0; index < sourceProjects.length; index++) {
+				if (sourceProjects[index].equals(externalProject))
+					continue;
+				if (!JavaProject.hasJavaNature(sourceProjects[index]))
+					continue;
+
+				HashSet foldersInProject = getExternalFolders(((JavaProject) JavaCore.create(sourceProjects[index])).getResolvedClasspath());
+				
+				if (foldersInProject == null || foldersInProject.size() == 0)
+					continue;
+				if (externalFolders == null)
+					externalFolders = new HashSet();
+				
+				externalFolders.addAll(foldersInProject);
+			}
+			if (externalFolders == null) 
+				return;
+
+			runRefreshJob(externalFolders);
+
+		} catch (CoreException e) {
+			Util.log(e, "Exception while refreshing external project"); //$NON-NLS-1$
+		}
+		return;
+	}
+	public void refreshReferences(IProject source, IProgressMonitor monitor) {
+		IProject externalProject = getExternalFoldersProject();
+		if (source.equals(externalProject))
+			return;
+		if (!JavaProject.hasJavaNature(source))
+			return;
+		try {
+			HashSet externalFolders = getExternalFolders(((JavaProject) JavaCore.create(source)).getResolvedClasspath());
+			if (externalFolders == null)
+				return;
+			
+			runRefreshJob(externalFolders);
+		} catch (CoreException e) {
+			Util.log(e, "Exception while refreshing external project"); //$NON-NLS-1$
+		}
+		return;
+	}
+
+	public IFolder removeFolder(IPath externalFolderPath) {
+		return (IFolder) getFolders().remove(externalFolderPath);
+	}
+
+	class RefreshJob extends Job {
+		Vector externalFolders = null;
+		RefreshJob(Vector externalFolders){
+			super(Messages.refreshing_external_folders);
+			this.externalFolders = externalFolders;
+		}
+		
+		public boolean belongsTo(Object family) {
+			return family == ResourcesPlugin.FAMILY_MANUAL_REFRESH;
+		}
+		
+		/*
+		 * Add the collection of paths to be refreshed to the already 
+		 * existing list of paths.  
+		 */
+		public void addFoldersToRefresh(Collection paths) {
+			if (!paths.isEmpty() && this.externalFolders == null) {
+				this.externalFolders = new Vector(); 
+			}
+			Iterator it = paths.iterator();
+			while(it.hasNext()) {
+				Object path = it.next();
+				if (!this.externalFolders.contains(path)) {
+					this.externalFolders.add(path);
+				}
+			}
+		}
+		
+		protected IStatus run(IProgressMonitor pm) {
+			try {
+				if (this.externalFolders == null) 
+					return Status.OK_STATUS;
+				IPath externalPath = null;
+				for (int index = 0; index < this.externalFolders.size(); index++ ) {
+					if ((externalPath = (IPath)this.externalFolders.get(index)) != null) {
+						IFolder folder = getFolder(externalPath);
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=321358
+						if (folder != null)
+							folder.refreshLocal(IResource.DEPTH_INFINITE, pm);
+					}
+					// Set the processed ones to null instead of removing the element altogether,
+					// so that they will not be considered as duplicates.
+					// This will also avoid elements being shifted to the left every time an element
+					// is removed. However, there is a risk of Collection size to be increased more often.
+					this.externalFolders.setElementAt(null, index);
+				}
+			} catch (CoreException e) {
+				return e.getStatus();
+			}
+			return Status.OK_STATUS;
+		}
+	}
+	
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalJavaProject.java
new file mode 100644
index 0000000..5e842d8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalJavaProject.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+public class ExternalJavaProject extends JavaProject {
+
+	/*
+	 * Note this name can be surfaced in the UI (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=128258)
+	 */
+	public static final String EXTERNAL_PROJECT_NAME = " "; //$NON-NLS-1$
+
+	public ExternalJavaProject(IClasspathEntry[] rawClasspath) {
+		super(ResourcesPlugin.getWorkspace().getRoot().getProject(EXTERNAL_PROJECT_NAME), JavaModelManager.getJavaModelManager().getJavaModel());
+		try {
+			getPerProjectInfo().setRawClasspath(rawClasspath, defaultOutputLocation(), JavaModelStatus.VERIFIED_OK/*no .classpath format problem*/);
+		} catch (JavaModelException e) {
+			// getPerProjectInfo() never throws JavaModelException for an ExternalJavaProject
+		}
+	}
+
+	public boolean equals(Object o) {
+		return this == o;
+	}
+
+	public boolean exists() {
+		// external project never exists
+		return false;
+	}
+
+	public String getOption(String optionName, boolean inheritJavaCoreOptions) {
+		if (JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE.equals(optionName)
+				|| JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE.equals(optionName))
+			return JavaCore.IGNORE;
+		return super.getOption(optionName, inheritJavaCoreOptions);
+	}
+
+	public boolean isOnClasspath(IJavaElement element) {
+		// since project is external, no element is on classpath (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=61013#c16)
+		return false;
+	}
+
+	public boolean isOnClasspath(IResource resource) {
+		// since project is external, no resource is on classpath (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=61013#c16)
+		return false;
+	}
+
+	protected IStatus validateExistence(IResource underlyingResource) {
+		// allow opening of external project
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalPackageFragmentRoot.java
new file mode 100644
index 0000000..8471f03
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalPackageFragmentRoot.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * A package fragment root that corresponds to an external class folder.
+ *
+ * <p>NOTE: An external package fragment root never has an associated resource.
+ *
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot
+ * @see org.eclipse.jdt.internal.core.PackageFragmentRootInfo
+ */
+public class ExternalPackageFragmentRoot extends PackageFragmentRoot {
+
+	/**
+	 * The path to the external folder
+	 * (an OS path)
+	 */
+	protected final IPath externalPath;
+
+	/**
+	 * Constructs a package fragment root which is the root of the Java package directory hierarchy
+	 * based on an external folder that is not contained in a <code>IJavaProject</code> and
+	 * does not have an associated <code>IResource</code>.
+	 */
+	protected ExternalPackageFragmentRoot(IPath externalPath, JavaProject project) {
+		super(null, project);
+		this.externalPath = externalPath;
+	}
+
+	protected ExternalPackageFragmentRoot(IResource linkedFolder, IPath externalPath, JavaProject project) {
+		super(linkedFolder, project);
+		this.externalPath = externalPath == null ? linkedFolder.getLocation() : externalPath;
+	}
+
+	/**
+	 * An external class folder is always K_BINARY.
+	 */
+	protected int determineKind(IResource underlyingResource) {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	/**
+	 * Returns true if this handle represents the same external folder
+	 * as the given handle.
+	 *
+	 * @see Object#equals
+	 */
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o instanceof ExternalPackageFragmentRoot) {
+			ExternalPackageFragmentRoot other= (ExternalPackageFragmentRoot) o;
+			return this.externalPath.equals(other.externalPath);
+		}
+		return false;
+	}
+	public String getElementName() {
+		return this.externalPath.lastSegment();
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public int getKind() {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	int internalKind() throws JavaModelException {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public IPath getPath() {
+		return this.externalPath;
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IResource getUnderlyingResource() throws JavaModelException {
+		return null;
+	}
+	public int hashCode() {
+		return this.externalPath.hashCode();
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public boolean isExternal() {
+		return true;
+	}
+
+	public IResource resource(PackageFragmentRoot root) {
+		if (this.resource == null)
+			return this.resource = JavaModelManager.getExternalManager().getFolder(this.externalPath);
+		return super.resource(root);
+	}
+
+	protected boolean resourceExists(IResource underlyingResource) {
+		if (underlyingResource == null)
+			return false;
+		IPath location = underlyingResource.getLocation();
+		if (location == null)
+			return false;
+		File file = location.toFile();
+		if (file == null)
+			return false;
+		return file.exists();
+	}
+
+	protected void toStringAncestors(StringBuffer buffer) {
+		// don't show project as it is irrelevant for external folders.
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java
new file mode 100644
index 0000000..f054045
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+
+/**
+ * This interface is used by IRequestorNameLookup. As results
+ * are found by IRequestorNameLookup, they are reported to this
+ * interface. An IJavaElementRequestor is able to cancel
+ * at any time (that is, stop receiving results), by responding
+ * <code>true</code> to <code>#isCancelled</code>.
+ */
+public interface IJavaElementRequestor {
+public void acceptField(IField field);
+public void acceptInitializer(IInitializer initializer);
+public void acceptMemberType(IType type);
+public void acceptMethod(IMethod method);
+public void acceptPackageFragment(IPackageFragment packageFragment);
+public void acceptType(IType type);
+/**
+ * Returns <code>true</code> if this IJavaElementRequestor does
+ * not want to receive any more results.
+ */
+boolean isCanceled();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INameEnvironmentWithProgress.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INameEnvironmentWithProgress.java
new file mode 100644
index 0000000..82e1770
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INameEnvironmentWithProgress.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+
+/**
+ * The name environment provides a callback API that the compiler
+ * can use to look up types, compilation units, and packages in the
+ * current environment.  The name environment is passed to the compiler
+ * on creation.
+ * 
+ * This name environment can be canceled using the monitor passed as an argument to
+ * {@link #setMonitor(IProgressMonitor)}.
+ * 
+ * @since 3.6
+ */
+public interface INameEnvironmentWithProgress extends INameEnvironment {
+	
+	/**
+	 * Set the monitor for the given name environment. In order to be able to cancel this name environment calls,
+	 * a non-null monitor should be given. 
+	 * 
+	 * @param monitor the given monitor
+	 */
+	void setMonitor(IProgressMonitor monitor);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java
new file mode 100644
index 0000000..bf37134
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+public interface INamingRequestor {
+	void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters);
+	void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters);
+	void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters);
+	void acceptNameWithoutPrefixAndSuffix(char[] name, int reusedCharacters);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java
new file mode 100644
index 0000000..f96b7fc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+public interface IPathRequestor {
+	void acceptPath(String path, boolean containsLocalTypes);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
new file mode 100644
index 0000000..c1cf002
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+
+/**
+ * @see IImportContainer
+ */
+public class ImportContainer extends SourceRefElement implements IImportContainer {
+protected ImportContainer(CompilationUnit parent) {
+	super(parent);
+}
+public boolean equals(Object o) {
+	if (!(o instanceof ImportContainer)) return false;
+	return super.equals(o);
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return IMPORT_CONTAINER;
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_COUNT:
+			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
+		case JEM_IMPORTDECLARATION:
+			if (memento.hasMoreTokens()) {
+				String importName = memento.nextToken();
+				JavaElement importDecl = (JavaElement)getImport(importName);
+				return importDecl.getHandleFromMemento(memento, workingCopyOwner);
+			} else {
+				return this;
+			}
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_IMPORTDECLARATION;
+}
+/**
+ * @see IImportContainer
+ */
+public IImportDeclaration getImport(String importName) {
+	int index = importName.indexOf(".*"); ///$NON-NLS-1$
+	boolean isOnDemand = index != -1;
+	if (isOnDemand)
+		// make sure to copy the string (so that it doesn't hold on the underlying char[] that might be much bigger than necessary)
+		importName = new String(importName.substring(0, index));
+	return getImport(importName, isOnDemand);
+}
+protected IImportDeclaration getImport(String importName, boolean isOnDemand) {
+	return new ImportDeclaration(this, importName, isOnDemand);
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	CompilationUnit cu = (CompilationUnit)this.parent;
+	if (checkOwner && cu.isPrimary()) return this;
+	return cu.getImportContainer();
+}
+/**
+ * @see ISourceReference
+ */
+public ISourceRange getSourceRange() throws JavaModelException {
+	IJavaElement[] imports= getChildren();
+	ISourceRange firstRange= ((ISourceReference)imports[0]).getSourceRange();
+	ISourceRange lastRange= ((ISourceReference)imports[imports.length - 1]).getSourceRange();
+	SourceRange range= new SourceRange(firstRange.getOffset(), lastRange.getOffset() + lastRange.getLength() - firstRange.getOffset());
+	return range;
+}
+/**
+ */
+public String readableName() {
+
+	return null;
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toString(int tab, StringBuffer buffer) {
+	Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this);
+	if (info == null || !(info instanceof JavaElementInfo)) return;
+	IJavaElement[] children = ((JavaElementInfo)info).getChildren();
+	for (int i = 0; i < children.length; i++) {
+		if (i > 0) buffer.append("\n"); //$NON-NLS-1$
+		((JavaElement)children[i]).toString(tab, buffer);
+	}
+}
+/**
+ *  Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	buffer.append("<import container>"); //$NON-NLS-1$
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	}
+}
+public ISourceRange getNameRange() {
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainerInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainerInfo.java
new file mode 100644
index 0000000..0726481
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainerInfo.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public class ImportContainerInfo extends JavaElementInfo {
+
+	protected IJavaElement[] children = JavaElement.NO_ELEMENTS;
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
new file mode 100644
index 0000000..c85bf12
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jdt.core.*;
+
+/**
+ * Handle for an import declaration. Info object is a ImportDeclarationElementInfo.
+ * @see IImportDeclaration
+ */
+
+public class ImportDeclaration extends SourceRefElement implements IImportDeclaration {
+
+	protected String name;
+	protected boolean isOnDemand;
+
+/**
+ * Constructs an ImportDeclaration in the given import container
+ * with the given name.
+ */
+protected ImportDeclaration(ImportContainer parent, String name, boolean isOnDemand) {
+	super(parent);
+	this.name = name;
+	this.isOnDemand = isOnDemand;
+}
+public boolean equals(Object o) {
+	if (!(o instanceof ImportDeclaration)) return false;
+	return super.equals(o);
+}
+public String getElementName() {
+	if (this.isOnDemand)
+		return this.name + ".*"; //$NON-NLS-1$
+	return this.name;
+}
+public String getNameWithoutStar() {
+	return this.name;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return IMPORT_DECLARATION;
+}
+/**
+ * @see org.eclipse.jdt.core.IImportDeclaration#getFlags()
+ */
+public int getFlags() throws JavaModelException {
+	ImportDeclarationElementInfo info = (ImportDeclarationElementInfo)getElementInfo();
+	return info.getModifiers();
+}
+/**
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ * For import declarations, the handle delimiter is associated to the import container already
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	((JavaElement)getParent()).getHandleMemento(buff);
+	escapeMementoName(buff, getElementName());
+	if (this.occurrenceCount > 1) {
+		buff.append(JEM_COUNT);
+		buff.append(this.occurrenceCount);
+	}
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	// For import declarations, the handle delimiter is associated to the import container already
+	Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
+	return 0;
+}
+public ISourceRange getNameRange() throws JavaModelException {
+	ImportDeclarationElementInfo info = (ImportDeclarationElementInfo) getElementInfo();
+	return info.getNameRange();
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	CompilationUnit cu = (CompilationUnit)this.parent.getParent();
+	if (checkOwner && cu.isPrimary()) return this;
+	return cu.getImport(getElementName());
+}
+/**
+ * Returns true if the import is on-demand (ends with ".*")
+ */
+public boolean isOnDemand() {
+	return this.isOnDemand;
+}
+/**
+ */
+public String readableName() {
+
+	return null;
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	buffer.append("import "); //$NON-NLS-1$
+	toStringName(buffer);
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java
new file mode 100644
index 0000000..4ae68ed
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.internal.compiler.env.ISourceImport;
+
+/**
+ * Element info for IImportDeclaration elements.
+ * @see org.eclipse.jdt.core.IImportDeclaration
+ */
+public class ImportDeclarationElementInfo extends MemberElementInfo implements ISourceImport{
+
+	/**
+	 * The start position of this import declaration's name in the its
+	 * openable's buffer.
+	 */
+	protected int nameStart= -1;
+
+	/**
+	 * The last position of this import declaration's name in the its
+	 * openable's buffer.
+	 */
+	protected int nameEnd= -1;
+
+	/**
+	 * Sets the last position of this import declaration's name, relative
+	 * to its openable's source buffer.
+	 */
+	protected void setNameSourceEnd(int end) {
+		this.nameEnd= end;
+	}
+	/**
+	 * Sets the start position of this import declaration's name, relative
+	 * to its openable's source buffer.
+	 */
+	protected void setNameSourceStart(int start) {
+		this.nameStart= start;
+	}
+
+	protected ISourceRange getNameRange() {
+		return new SourceRange(this.nameStart, this.nameEnd - this.nameStart + 1);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
new file mode 100644
index 0000000..346bb06
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IInitializer
+ */
+
+public class Initializer extends Member implements IInitializer {
+
+protected Initializer(JavaElement parent, int count) {
+	super(parent);
+	// 0 is not valid: this first occurrence is occurrence 1.
+	if (count <= 0)
+		throw new IllegalArgumentException();
+	this.occurrenceCount = count;
+}
+public boolean equals(Object o) {
+	if (!(o instanceof Initializer)) return false;
+	return super.equals(o);
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return INITIALIZER;
+}
+/**
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	((JavaElement)getParent()).getHandleMemento(buff);
+	buff.append(getHandleMementoDelimiter());
+	buff.append(this.occurrenceCount);
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_INITIALIZER;
+}
+public int hashCode() {
+	return Util.combineHashCodes(this.parent.hashCode(), this.occurrenceCount);
+}
+/**
+ */
+public String readableName() {
+
+	return ((JavaElement)getDeclaringType()).readableName();
+}
+/**
+ * @see ISourceManipulation
+ */
+public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
+}
+/**
+ * @see IMember
+ */
+public ISourceRange getNameRange() {
+	return null;
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner) {
+		CompilationUnit cu = (CompilationUnit)getAncestor(COMPILATION_UNIT);
+		if (cu == null || cu.isPrimary()) return this;
+	}
+	IJavaElement primaryParent = this.parent.getPrimaryElement(false);
+	return ((IType)primaryParent).getInitializer(this.occurrenceCount);
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		buffer.append("<initializer #"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+		buffer.append("> (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		buffer.append("<initializer #"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+		buffer.append(">"); //$NON-NLS-1$
+	} else {
+		try {
+			buffer.append("<"); //$NON-NLS-1$
+			if (Flags.isStatic(getFlags())) {
+				buffer.append("static "); //$NON-NLS-1$
+			}
+		buffer.append("initializer #"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+		buffer.append(">"); //$NON-NLS-1$
+		} catch (JavaModelException e) {
+			buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java
new file mode 100644
index 0000000..80e7f51
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Element info for IInitializer elements.
+ */
+public class InitializerElementInfo extends MemberElementInfo {
+	// used only as a marker class: contains no methods
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerWithChildrenInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerWithChildrenInfo.java
new file mode 100644
index 0000000..a832244
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerWithChildrenInfo.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public class InitializerWithChildrenInfo extends InitializerElementInfo {
+
+	protected IJavaElement[] children;
+	
+	public InitializerWithChildrenInfo(IJavaElement[] children) {
+		this.children = children;
+	}
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java
new file mode 100644
index 0000000..e9ce1a2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java
@@ -0,0 +1,834 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.codeassist.impl.AssistOptions;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
+
+public class InternalNamingConventions {
+	private static final char[] DEFAULT_NAME = "name".toCharArray(); //$NON-NLS-1$
+
+	private static Scanner getNameScanner(CompilerOptions compilerOptions) {
+		return
+			new Scanner(
+				false /*comment*/,
+				false /*whitespace*/,
+				false /*nls*/,
+				compilerOptions.sourceLevel /*sourceLevel*/,
+				null /*taskTags*/,
+				null/*taskPriorities*/,
+				true/*taskCaseSensitive*/);
+	}
+
+	private static void acceptName(
+		char[] name,
+		char[] prefix,
+		char[] suffix,
+		boolean isFirstPrefix,
+		boolean isFirstSuffix,
+		int reusedCharacters,
+		INamingRequestor requestor) {
+		if(prefix.length > 0 && suffix.length > 0) {
+			requestor.acceptNameWithPrefixAndSuffix(name, isFirstPrefix, isFirstSuffix, reusedCharacters);
+		} else if(prefix.length > 0){
+			requestor.acceptNameWithPrefix(name, isFirstPrefix, reusedCharacters);
+		} else if(suffix.length > 0){
+			requestor.acceptNameWithSuffix(name, isFirstSuffix, reusedCharacters);
+		} else {
+			requestor.acceptNameWithoutPrefixAndSuffix(name, reusedCharacters);
+		}
+	}
+
+	private static char[][] computeBaseTypeNames(char[] typeName, boolean isConstantField, char[][] excludedNames){
+		if (isConstantField) {
+			return computeNonBaseTypeNames(typeName, isConstantField, false);
+		} else {
+			char[] name = computeBaseTypeNames(typeName[0], excludedNames);
+			if(name != null) {
+				return new char[][]{name};
+			} else {
+				// compute variable name like from non base type
+				return computeNonBaseTypeNames(typeName, isConstantField, false);
+			}
+		}
+	}
+	private static char[] computeBaseTypeNames(char firstName, char[][] excludedNames){
+		char[] name = new char[]{firstName};
+
+		for(int i = 0 ; i < excludedNames.length ; i++){
+			if(CharOperation.equals(name, excludedNames[i], false)) {
+				name[0]++;
+				if(name[0] > 'z')
+					name[0] = 'a';
+				if(name[0] == firstName)
+					return null;
+				i = 0;
+			}
+		}
+
+		return name;
+	}
+
+	private static char[][] computeNonBaseTypeNames(char[] sourceName, boolean isConstantField, boolean onlyLongest){
+		int length = sourceName.length;
+		
+		if (length == 0) {
+			return CharOperation.NO_CHAR_CHAR;
+		}
+		
+		if (length == 1) {
+			if (isConstantField) {
+				return generateConstantName(new char[][]{CharOperation.toLowerCase(sourceName)}, 0, onlyLongest);
+			} else {
+				return generateNonConstantName(new char[][]{CharOperation.toLowerCase(sourceName)}, 0, onlyLongest);
+			}
+		}
+		
+		char[][] nameParts = new char[length][];
+		int namePartsPtr = -1;
+		
+		int endIndex = length;
+		char c = sourceName[length - 1];
+		
+		final int IS_LOWER_CASE = 1;
+		final int IS_UPPER_CASE = 2;
+		final int IS_UNDERSCORE = 3;
+		final int IS_OTHER = 4;
+		
+		int previousCharKind =
+			ScannerHelper.isLowerCase(c) ? IS_LOWER_CASE :
+				ScannerHelper.isUpperCase(c) ? IS_UPPER_CASE :
+					c == '_' ? IS_UNDERSCORE : IS_OTHER;
+		
+		for(int i = length - 1 ; i >= 0 ; i--){
+			c = sourceName[i];
+			
+			int charKind =
+				ScannerHelper.isLowerCase(c) ? IS_LOWER_CASE :
+					ScannerHelper.isUpperCase(c) ? IS_UPPER_CASE :
+						c == '_' ? IS_UNDERSCORE : IS_OTHER;
+			
+			switch (charKind) {
+				case IS_LOWER_CASE:
+					if (previousCharKind == IS_UPPER_CASE) {
+						nameParts[++namePartsPtr] = CharOperation.subarray(sourceName, i + 1, endIndex);
+						endIndex = i + 1;
+					}
+					previousCharKind = IS_LOWER_CASE;
+					break;
+				case IS_UPPER_CASE:
+					if (previousCharKind == IS_LOWER_CASE) {
+						nameParts[++namePartsPtr] = CharOperation.subarray(sourceName, i, endIndex);
+						if (i > 0) {
+							char pc = sourceName[i - 1];
+							previousCharKind =
+								ScannerHelper.isLowerCase(pc) ? IS_LOWER_CASE :
+									ScannerHelper.isUpperCase(pc) ? IS_UPPER_CASE :
+										pc == '_' ? IS_UNDERSCORE : IS_OTHER;
+						}
+						endIndex = i;
+					} else {
+						previousCharKind = IS_UPPER_CASE;
+					}
+					break;
+				case IS_UNDERSCORE:
+					switch (previousCharKind) {
+						case IS_UNDERSCORE:
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=283539
+							// Process consecutive underscores only for constant types 
+							if (isConstantField) {
+								if (i > 0) {
+									char pc = sourceName[i - 1];
+									previousCharKind =
+										ScannerHelper.isLowerCase(pc) ? IS_LOWER_CASE :
+											ScannerHelper.isUpperCase(pc) ? IS_UPPER_CASE :
+												pc == '_' ? IS_UNDERSCORE : IS_OTHER;
+								}
+								endIndex = i;
+							}
+							break;
+						case IS_LOWER_CASE:
+						case IS_UPPER_CASE:
+							nameParts[++namePartsPtr] = CharOperation.subarray(sourceName, i + 1, endIndex);
+							if (i > 0) {
+								char pc = sourceName[i - 1];
+								previousCharKind =
+									ScannerHelper.isLowerCase(pc) ? IS_LOWER_CASE :
+										ScannerHelper.isUpperCase(pc) ? IS_UPPER_CASE :
+											pc == '_' ? IS_UNDERSCORE : IS_OTHER;
+							}
+							// Include the '_' also. E.g. My_word -> "My_" and "word".
+							endIndex = i+1;
+							break;
+						default:
+							previousCharKind = IS_UNDERSCORE;
+							break;
+					}
+					break;
+				default:
+					previousCharKind = IS_OTHER;
+					break;
+			}
+		}
+		if (endIndex > 0) {
+			nameParts[++namePartsPtr] = CharOperation.subarray(sourceName, 0, endIndex);
+		}
+		if (namePartsPtr == -1) {
+			return new char[][] { sourceName };
+		}
+		
+		if (isConstantField) {
+			return generateConstantName(nameParts, namePartsPtr, onlyLongest);
+		} else {
+			return generateNonConstantName(nameParts, namePartsPtr, onlyLongest);
+		}
+	}
+	
+	
+
+	private static char[] excludeNames(
+		char[] suffixName,
+		char[] prefixName,
+		char[] suffix,
+		char[][] excludedNames) {
+		int count = 2;
+		int m = 0;
+		while (m < excludedNames.length) {
+			if(CharOperation.equals(suffixName, excludedNames[m], false)) {
+				suffixName = CharOperation.concat(
+					prefixName,
+					String.valueOf(count++).toCharArray(),
+					suffix
+				);
+				m = 0;
+			} else {
+				m++;
+			}
+		}
+		return suffixName;
+	}
+	
+	private static char[][] generateNonConstantName(char[][] nameParts, int namePartsPtr, boolean onlyLongest) {
+		char[][] names;
+		if (onlyLongest) {
+			names = new char[1][];
+		} else {
+			names = new char[namePartsPtr + 1][];
+		}
+		
+		char[] namePart = nameParts[0];
+		
+		char[] name = CharOperation.toLowerCase(namePart);
+		
+		if (!onlyLongest) {
+			names[namePartsPtr] = name;
+		}
+		
+		char[] nameSuffix = namePart;
+		
+		for (int i = 1; i <= namePartsPtr; i++) {
+			namePart = nameParts[i];
+			
+			name = CharOperation.concat(CharOperation.toLowerCase(namePart), nameSuffix);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=283539
+			// Only the first word is converted to lower case and the rest of them are not changed for non-constants
+			
+			if (!onlyLongest) {
+				names[namePartsPtr - i] = name;
+			}
+			
+			nameSuffix = CharOperation.concat(namePart, nameSuffix);
+		}
+		if (onlyLongest) {
+			names[0] = name;
+		}
+		return names;
+	}
+
+	private static char[][] generateConstantName(char[][] nameParts, int namePartsPtr, boolean onlyLongest) {
+		char[][] names;
+		if (onlyLongest) {
+			names = new char[1][];
+		} else {
+			names = new char[namePartsPtr + 1][];
+		}
+		
+		char[] namePart = CharOperation.toUpperCase(nameParts[0]);
+		int namePartLength = namePart.length;
+		System.arraycopy(namePart, 0, namePart, 0, namePartLength);
+		
+		char[] name = namePart;
+		
+		if (!onlyLongest) {
+			names[namePartsPtr] = name;
+		}
+		
+		for (int i = 1; i <= namePartsPtr; i++) {
+			namePart = CharOperation.toUpperCase(nameParts[i]);
+			namePartLength = namePart.length;
+			if (namePart[namePartLength - 1] != '_') {
+				name = CharOperation.concat(namePart, name, '_');
+			} else {
+				name = CharOperation.concat(namePart, name);
+			}
+			
+			if (!onlyLongest) {
+				names[namePartsPtr - i] = name;
+			}
+		}
+		if (onlyLongest) {
+			names[0] = name;
+		}
+		return names;
+	}
+	
+	public static char[] getBaseName(
+			int variableKind,
+			IJavaProject javaProject,
+			char[] name,
+			boolean updateFirstCharacter) {
+		
+		AssistOptions assistOptions;
+		if (javaProject != null) {
+			assistOptions = new AssistOptions(javaProject.getOptions(true));
+		} else {
+			assistOptions = new AssistOptions(JavaCore.getOptions());
+		}
+		
+		char[][] prefixes = null;
+		char[][] suffixes = null;
+		switch (variableKind) {
+			case VK_INSTANCE_FIELD:
+				prefixes = assistOptions.fieldPrefixes;
+				suffixes = assistOptions.fieldSuffixes;
+				break;
+			case VK_STATIC_FIELD:
+				prefixes = assistOptions.staticFieldPrefixes;
+				suffixes = assistOptions.staticFieldSuffixes;
+				break;
+			case VK_STATIC_FINAL_FIELD:
+				prefixes = assistOptions.staticFinalFieldPrefixes;
+				suffixes = assistOptions.staticFinalFieldSuffixes;
+				break;
+			case VK_LOCAL:
+				prefixes = assistOptions.localPrefixes;
+				suffixes = assistOptions.localSuffixes;
+				break;
+			case VK_PARAMETER:
+				prefixes = assistOptions.argumentPrefixes;
+				suffixes = assistOptions.argumentSuffixes;
+				break;
+		}
+		
+		
+		return getBaseName(name, prefixes, suffixes, variableKind == VK_STATIC_FINAL_FIELD, updateFirstCharacter);
+	}
+
+	private static char[] getBaseName(char[] name, char[][] prefixes, char[][] suffixes, boolean isConstant, boolean updateFirstCharacter) {
+		char[] nameWithoutPrefixAndSiffix = removeVariablePrefixAndSuffix(name, prefixes, suffixes, updateFirstCharacter);
+		
+		char[] baseName;
+		if (isConstant) {
+			int length = nameWithoutPrefixAndSiffix.length;
+			baseName = new char[length];
+			int baseNamePtr = -1;
+			
+			boolean previousIsUnderscore = false;
+			for (int i = 0; i < length; i++) {
+				char c = nameWithoutPrefixAndSiffix[i];
+				if (c != '_') {
+					if (previousIsUnderscore) {
+						baseName[++baseNamePtr] = ScannerHelper.toUpperCase(c);
+						previousIsUnderscore = false;
+					} else {
+						baseName[++baseNamePtr] = ScannerHelper.toLowerCase(c);
+					}
+				} else {
+					previousIsUnderscore = true;
+				}
+			}
+			System.arraycopy(baseName, 0, baseName = new char[baseNamePtr + 1], 0, baseNamePtr + 1);
+		} else {
+			baseName = nameWithoutPrefixAndSiffix;
+		}
+		
+		return baseName;
+	}
+	
+	public static char[] removeVariablePrefixAndSuffix(
+			int variableKind,
+			IJavaProject javaProject,
+			char[] name) {
+		AssistOptions assistOptions;
+		if (javaProject != null) {
+			assistOptions = new AssistOptions(javaProject.getOptions(true));
+		} else {
+			assistOptions = new AssistOptions(JavaCore.getOptions());
+		}
+		
+		char[][] prefixes = null;
+		char[][] suffixes = null;
+		switch (variableKind) {
+			case VK_INSTANCE_FIELD:
+				prefixes = assistOptions.fieldPrefixes;
+				suffixes = assistOptions.fieldSuffixes;
+				break;
+			case VK_STATIC_FIELD:
+				prefixes = assistOptions.staticFieldPrefixes;
+				suffixes = assistOptions.staticFieldSuffixes;
+				break;
+			case VK_STATIC_FINAL_FIELD:
+				prefixes = assistOptions.staticFinalFieldPrefixes;
+				suffixes = assistOptions.staticFinalFieldSuffixes;
+				break;
+			case VK_LOCAL:
+				prefixes = assistOptions.localPrefixes;
+				suffixes = assistOptions.localSuffixes;
+				break;
+			case VK_PARAMETER:
+				prefixes = assistOptions.argumentPrefixes;
+				suffixes = assistOptions.argumentSuffixes;
+				break;
+		}
+		
+		return InternalNamingConventions.removeVariablePrefixAndSuffix(name, prefixes, suffixes, true);
+	}
+	
+	private static char[] removeVariablePrefixAndSuffix(char[] name, char[][] prefixes, char[][] suffixes, boolean updateFirstCharacter) {
+		// remove longer prefix
+		char[] withoutPrefixName = name;
+		if (prefixes != null) {
+			int bestLength = 0;
+			for (int i= 0; i < prefixes.length; i++) {
+				char[] prefix = prefixes[i];
+				if (CharOperation.prefixEquals(prefix, name)) {
+					int currLen = prefix.length;
+					boolean lastCharIsLetter = ScannerHelper.isLetter(prefix[currLen - 1]);
+					if(!lastCharIsLetter || (lastCharIsLetter && name.length > currLen && ScannerHelper.isUpperCase(name[currLen]))) {
+						if (bestLength < currLen && name.length != currLen) {
+							withoutPrefixName = CharOperation.subarray(name, currLen, name.length);
+							bestLength = currLen;
+						}
+					}
+				}
+			}
+		}
+
+		// remove longer suffix
+		char[] withoutSuffixName = withoutPrefixName;
+		if(suffixes != null) {
+			int bestLength = 0;
+			for (int i = 0; i < suffixes.length; i++) {
+				char[] suffix = suffixes[i];
+				if(CharOperation.endsWith(withoutPrefixName, suffix)) {
+					int currLen = suffix.length;
+					if(bestLength < currLen && withoutPrefixName.length != currLen) {
+						withoutSuffixName = CharOperation.subarray(withoutPrefixName, 0, withoutPrefixName.length - currLen);
+						bestLength = currLen;
+					}
+				}
+			}
+		}
+
+		if (updateFirstCharacter) withoutSuffixName[0] = ScannerHelper.toLowerCase(withoutSuffixName[0]);
+		return withoutSuffixName;
+	}
+
+	private static char[] removePrefix(char[] name, char[][] prefixes) {
+		// remove longer prefix
+		char[] withoutPrefixName = name;
+		if (prefixes != null) {
+			int bestLength = 0;
+			int nameLength = name.length;
+			for (int i= 0; i < prefixes.length; i++) {
+				char[] prefix = prefixes[i];
+
+				int prefixLength = prefix.length;
+				if(prefixLength <= nameLength) {
+					if(CharOperation.prefixEquals(prefix, name, false)) {
+						if (prefixLength > bestLength) {
+							bestLength = prefixLength;
+						}
+					}
+				} else {
+					int currLen = 0;
+					for (; currLen < nameLength; currLen++) {
+						if(ScannerHelper.toLowerCase(prefix[currLen]) != ScannerHelper.toLowerCase(name[currLen])) {
+							if (currLen > bestLength) {
+								bestLength = currLen;
+							}
+							break;
+						}
+					}
+					if(currLen == nameLength && currLen > bestLength) {
+						bestLength = currLen;
+					}
+				}
+			}
+			if(bestLength > 0) {
+				if(bestLength == nameLength) {
+					withoutPrefixName = CharOperation.NO_CHAR;
+				} else {
+					withoutPrefixName = CharOperation.subarray(name, bestLength, nameLength);
+				}
+			}
+		}
+//
+//
+//		// remove longer prefix
+//		char[] withoutPrefixName = name;
+//		if (prefixes != null) {
+//			int bestLength = 0;
+//			for (int i= 0; i < prefixes.length; i++) {
+//				char[] prefix = prefixes[i];
+//				int max = prefix.length < name.length ? prefix.length : name.length;
+//				int currLen = 0;
+//				for (; currLen < max; currLen++) {
+//					if(Character.toLowerCase(prefix[currLen]) != Character.toLowerCase(name[currLen])) {
+//						if (currLen > bestLength) {
+//							bestLength = currLen;
+//						}
+//						break;
+//					}
+//				}
+//				if(currLen == max && currLen > bestLength) {
+//					bestLength = max;
+//				}
+//			}
+//			if(bestLength > 0) {
+//				if(bestLength == name.length) {
+//					withoutPrefixName = CharOperation.NO_CHAR;
+//				} else {
+//					withoutPrefixName = CharOperation.subarray(name, bestLength, name.length);
+//				}
+//			}
+//		}
+
+		return withoutPrefixName;
+	}
+	
+	public static final int VK_STATIC_FIELD = 1;
+	public static final int VK_INSTANCE_FIELD = 2;
+	public static final int VK_STATIC_FINAL_FIELD = 3;
+	public static final int VK_PARAMETER = 4;
+	public static final int VK_LOCAL = 5;
+	
+	public static final int BK_SIMPLE_NAME = 1;
+	public static final int BK_SIMPLE_TYPE_NAME = 2;
+
+	public static void suggestVariableNames(
+			int variableKind,
+			int baseNameKind,
+			char[] baseName,
+			IJavaProject javaProject,
+			int dim,
+			char[] internalPrefix,
+			char[][] excluded,
+			boolean evaluateDefault,
+			INamingRequestor requestor) {
+		
+		if(baseName == null || baseName.length == 0)
+			return;
+		
+		Map options;
+		if (javaProject != null) {
+			options = javaProject.getOptions(true);
+		} else {
+			options = JavaCore.getOptions();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(options);
+		AssistOptions assistOptions = new AssistOptions(options);
+		
+		boolean isConstantField = false;
+		
+		char[][] prefixes = null;
+		char[][] suffixes = null;
+		switch (variableKind) {
+			case VK_INSTANCE_FIELD:
+				prefixes = assistOptions.fieldPrefixes;
+				suffixes = assistOptions.fieldSuffixes;
+				break;
+			case VK_STATIC_FIELD:
+				prefixes = assistOptions.staticFieldPrefixes;
+				suffixes = assistOptions.staticFieldSuffixes;
+				break;
+			case VK_STATIC_FINAL_FIELD:
+				isConstantField = true;
+				prefixes = assistOptions.staticFinalFieldPrefixes;
+				suffixes = assistOptions.staticFinalFieldSuffixes;
+				break;
+			case VK_LOCAL:
+				prefixes = assistOptions.localPrefixes;
+				suffixes = assistOptions.localSuffixes;
+				break;
+			case VK_PARAMETER:
+				prefixes = assistOptions.argumentPrefixes;
+				suffixes = assistOptions.argumentSuffixes;
+				break;
+		}
+		
+		if(prefixes == null || prefixes.length == 0) {
+			prefixes = new char[1][0];
+		} else {
+			int length = prefixes.length;
+			System.arraycopy(prefixes, 0, prefixes = new char[length+1][], 0, length);
+			prefixes[length] = CharOperation.NO_CHAR;
+		}
+
+		if(suffixes == null || suffixes.length == 0) {
+			suffixes = new char[1][0];
+		} else {
+			int length = suffixes.length;
+			System.arraycopy(suffixes, 0, suffixes = new char[length+1][], 0, length);
+			suffixes[length] = CharOperation.NO_CHAR;
+		}
+		
+		if(internalPrefix == null) {
+			internalPrefix = CharOperation.NO_CHAR;
+		} else {
+			internalPrefix = removePrefix(internalPrefix, prefixes);
+		}
+
+		char[][] tempNames = null;
+		
+		Scanner nameScanner = getNameScanner(compilerOptions);
+		if (baseNameKind == BK_SIMPLE_TYPE_NAME) {
+			boolean isBaseType = false;
+			
+			try{
+				nameScanner.setSource(baseName);
+				switch (nameScanner.getNextToken()) {
+					case TerminalTokens.TokenNameint :
+					case TerminalTokens.TokenNamebyte :
+					case TerminalTokens.TokenNameshort :
+					case TerminalTokens.TokenNamechar :
+					case TerminalTokens.TokenNamelong :
+					case TerminalTokens.TokenNamefloat :
+					case TerminalTokens.TokenNamedouble :
+					case TerminalTokens.TokenNameboolean :
+						isBaseType = true;
+						break;
+				}
+			} catch(InvalidInputException e){
+				// ignore
+			}
+			if (isBaseType) {
+				// compute variable name from base type
+				if (internalPrefix.length > 0) return;
+	
+				tempNames = computeBaseTypeNames(baseName, isConstantField, excluded);
+			} else {
+				// compute variable name for non base type
+				tempNames = computeNonBaseTypeNames(baseName, isConstantField, false);
+			}
+		} else {
+			tempNames = computeNonBaseTypeNames(baseName, isConstantField, true);
+		}
+
+		boolean acceptDefaultName = true;
+		SimpleSetOfCharArray foundNames = new SimpleSetOfCharArray();
+
+		for (int i = 0; i < tempNames.length; i++) {
+			char[] tempName = tempNames[i];
+			
+			// add English plural form is necessary
+			if(dim > 0) {
+				int length = tempName.length;
+				
+				if (isConstantField) {
+					if (tempName[length-1] == 'S'){
+						if(tempName.length > 1 && tempName[length-2] == 'S') {
+							System.arraycopy(tempName, 0, tempName = new char[length + 2], 0, length);
+							tempName[length] = 'E';
+							tempName[length+1] = 'S';
+						}
+					} else if(tempName[length-1] == 'Y') {
+						boolean precededByAVowel = false;
+						if(tempName.length > 1) {
+							switch (tempName[length-2]) {
+								case 'A':
+								case 'E':
+								case 'I':
+								case 'O':
+								case 'U':
+									precededByAVowel = true;
+									break;
+							}
+						}
+						if (precededByAVowel) {
+							System.arraycopy(tempName, 0, tempName = new char[length + 1], 0, length);
+							tempName[length] = 'S';
+						} else {
+							System.arraycopy(tempName, 0, tempName = new char[length + 2], 0, length);
+							tempName[length-1] = 'I';
+							tempName[length] = 'E';
+							tempName[length+1] = 'S';
+						}
+					} else {
+						System.arraycopy(tempName, 0, tempName = new char[length + 1], 0, length);
+						tempName[length] = 'S';
+					}
+				} else {
+					if (tempName[length-1] == 's'){
+						if(tempName.length > 1 && tempName[length-2] == 's') {
+							System.arraycopy(tempName, 0, tempName = new char[length + 2], 0, length);
+							tempName[length] = 'e';
+							tempName[length+1] = 's';
+						}
+					} else if(tempName[length-1] == 'y') {
+						boolean precededByAVowel = false;
+						if(tempName.length > 1) {
+							switch (tempName[length-2]) {
+								case 'a':
+								case 'e':
+								case 'i':
+								case 'o':
+								case 'u':
+									precededByAVowel = true;
+									break;
+							}
+						}
+						if (precededByAVowel) {
+							System.arraycopy(tempName, 0, tempName = new char[length + 1], 0, length);
+							tempName[length] = 's';
+						} else {
+							System.arraycopy(tempName, 0, tempName = new char[length + 2], 0, length);
+							tempName[length-1] = 'i';
+							tempName[length] = 'e';
+							tempName[length+1] = 's';
+						}
+					} else {
+						System.arraycopy(tempName, 0, tempName = new char[length + 1], 0, length);
+						tempName[length] = 's';
+					}
+				}
+			}
+			
+			char[] unprefixedName = tempName;
+			
+			int matchingIndex = -1;
+			if (!isConstantField) {
+				unprefixedName[0] = ScannerHelper.toUpperCase(unprefixedName[0]);
+				
+				done : for (int j = 0; j <= internalPrefix.length; j++) {
+					if(j == internalPrefix.length ||
+							CharOperation.prefixEquals(CharOperation.subarray(internalPrefix, j, -1), unprefixedName, j != 0 /*do not check case when there is no prefix*/)) {
+						matchingIndex = j;
+						break done;
+					}
+				}
+			} else {
+				done : for (int j = 0; j <= internalPrefix.length; j++) {
+					if(j == internalPrefix.length) {
+						matchingIndex = j;
+						break done;
+					} else if(CharOperation.prefixEquals(CharOperation.subarray(internalPrefix, j, -1), unprefixedName, j != 0 /*do not check case when there is no prefix*/)) {
+						if (j == 0 || internalPrefix[j - 1] == '_') {
+							matchingIndex = j;
+							break done;
+						}
+						
+					}
+				}
+			}
+
+			if(matchingIndex > -1) {
+				if (!isConstantField) {
+					tempName = CharOperation.concat(CharOperation.subarray(internalPrefix, 0, matchingIndex), unprefixedName);
+					if(matchingIndex == 0) tempName[0] = ScannerHelper.toLowerCase(tempName[0]);
+				} else {
+					if(matchingIndex != 0 && tempName[0] != '_' && internalPrefix[matchingIndex - 1] != '_') {
+						tempName = CharOperation.concat(CharOperation.subarray(CharOperation.toUpperCase(internalPrefix), 0, matchingIndex), unprefixedName, '_');
+					} else {
+						tempName = CharOperation.concat(CharOperation.subarray(CharOperation.toUpperCase(internalPrefix), 0, matchingIndex), unprefixedName);
+					}
+				}
+				
+				for (int k = 0; k < prefixes.length; k++) {
+					if (!isConstantField) {
+						if(prefixes[k].length > 0
+							&& ScannerHelper.isLetterOrDigit(prefixes[k][prefixes[k].length - 1])) {
+							tempName[0] = ScannerHelper.toUpperCase(tempName[0]);
+						} else {
+							tempName[0] = ScannerHelper.toLowerCase(tempName[0]);
+						}
+					}
+					char[] prefixName = CharOperation.concat(prefixes[k], tempName);
+					for (int l = 0; l < suffixes.length; l++) {
+						char[] suffixName = CharOperation.concat(prefixName, suffixes[l]);
+						suffixName =
+							excludeNames(
+								suffixName,
+								prefixName,
+								suffixes[l],
+								excluded);
+						try{
+							nameScanner.setSource(suffixName);
+							switch (nameScanner.getNextToken()) {
+								case TerminalTokens.TokenNameIdentifier :
+									int token = nameScanner.getNextToken();
+									if (token == TerminalTokens.TokenNameEOF && nameScanner.startPosition == suffixName.length) {
+										if (!foundNames.includes(suffixName)) {
+											acceptName(suffixName, prefixes[k], suffixes[l],  k == 0, l == 0, internalPrefix.length - matchingIndex, requestor);
+											foundNames.add(suffixName);
+											acceptDefaultName = false;
+										}
+									}
+									break;
+								default:
+									suffixName = CharOperation.concat(
+										prefixName,
+										String.valueOf(1).toCharArray(),
+										suffixes[l]
+									);
+									suffixName =
+										excludeNames(
+											suffixName,
+											prefixName,
+											suffixes[l],
+											excluded);
+									nameScanner.setSource(suffixName);
+									switch (nameScanner.getNextToken()) {
+										case TerminalTokens.TokenNameIdentifier :
+											token = nameScanner.getNextToken();
+											if (token == TerminalTokens.TokenNameEOF && nameScanner.startPosition == suffixName.length) {
+												if (!foundNames.includes(suffixName)) {
+													acceptName(suffixName, prefixes[k], suffixes[l], k == 0, l == 0, internalPrefix.length - matchingIndex, requestor);
+													foundNames.add(suffixName);
+													acceptDefaultName = false;
+												}
+											}
+									}
+							}
+						} catch(InvalidInputException e){
+							// ignore
+						}
+					}
+				}
+			}
+		}
+		// if no names were found
+		if(evaluateDefault && acceptDefaultName) {
+			char[] name = excludeNames(DEFAULT_NAME, DEFAULT_NAME, CharOperation.NO_CHAR, excluded);
+			requestor.acceptNameWithoutPrefixAndSuffix(name, 0);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryDirectory.java
new file mode 100644
index 0000000..cb04892
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryDirectory.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJarEntryResource;
+
+public class JarEntryDirectory extends JarEntryResource {
+	private IJarEntryResource[] children;
+
+	public JarEntryDirectory(String simpleName) {
+		super(simpleName);
+	}
+
+	public JarEntryResource clone(Object newParent) {
+		JarEntryDirectory dir = new JarEntryDirectory(this.simpleName);
+		dir.setParent(newParent);
+		int length = this.children.length;
+		if (length > 0) {
+			IJarEntryResource[] newChildren = new IJarEntryResource[length];
+			for (int i = 0; i < length; i++) {
+				JarEntryResource child = (JarEntryResource) this.children[i];
+				newChildren[i] = child.clone(dir);
+			}
+			dir.setChildren(newChildren);
+		}
+		return dir;
+	}
+
+	public IJarEntryResource[] getChildren() {
+		return this.children;
+	}
+
+	public InputStream getContents() throws CoreException {
+		return new ByteArrayInputStream(new byte[0]);
+	}
+
+	public boolean isFile() {
+		return false;
+	}
+
+	public void setChildren(IJarEntryResource[] children) {
+		this.children = children;
+	}
+
+	public String toString() {
+		return "JarEntryDirectory["+getEntryName()+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
new file mode 100644
index 0000000..21af1eb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * A jar entry that represents a non-java file found in a JAR.
+ *
+ * @see IStorage
+ */
+public class JarEntryFile  extends JarEntryResource {
+	private static final IJarEntryResource[] NO_CHILDREN = new IJarEntryResource[0];
+
+	public JarEntryFile(String simpleName) {
+		super(simpleName);
+	}
+
+	public JarEntryResource clone(Object newParent) {
+		JarEntryFile file = new JarEntryFile(this.simpleName);
+		file.setParent(newParent);
+		return file;
+	}
+
+	public InputStream getContents() throws CoreException {
+		ZipFile zipFile = null;
+		try {
+			zipFile = getZipFile();
+			if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [JarEntryFile.getContents()] Creating ZipFile on " +zipFile.getName()); //$NON-NLS-1$	//$NON-NLS-2$
+			}
+			String entryName = getEntryName();
+			ZipEntry zipEntry = zipFile.getEntry(entryName);
+			if (zipEntry == null){
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, entryName));
+			}
+			byte[] contents = Util.getZipEntryByteContent(zipEntry, zipFile);
+			return new ByteArrayInputStream(contents);
+		} catch (IOException e){
+			throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+		} finally {
+			// avoid leaking ZipFiles
+			JavaModelManager.getJavaModelManager().closeZipFile(zipFile);
+		}
+	}
+
+	public IJarEntryResource[] getChildren() {
+		return NO_CHILDREN;
+	}
+
+	public boolean isFile() {
+		return true;
+	}
+
+	public String toString() {
+		return "JarEntryFile["+getEntryName()+"]"; //$NON-NLS-2$ //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryResource.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryResource.java
new file mode 100644
index 0000000..57a2775
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryResource.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public abstract class JarEntryResource  extends PlatformObject implements IJarEntryResource {
+
+	protected Object parent;
+	protected String simpleName;
+
+	public JarEntryResource(String simpleName) {
+		this.simpleName = simpleName;
+	}
+
+	public abstract JarEntryResource clone(Object newParent);
+
+	public boolean equals(Object obj) {
+		if (! (obj instanceof JarEntryResource))
+			return false;
+		JarEntryResource other = (JarEntryResource) obj;
+		return this.parent.equals(other.parent) && this.simpleName.equals(other.simpleName);
+	}
+
+	protected String getEntryName() {
+		String parentEntryName;
+		if (this.parent instanceof IPackageFragment) {
+			String elementName = ((IPackageFragment) this.parent).getElementName();
+			parentEntryName = elementName.length() == 0 ? "" : elementName .replace('.', '/') + '/'; //$NON-NLS-1$
+		} else if (this.parent instanceof IPackageFragmentRoot) {
+			parentEntryName = ""; //$NON-NLS-1$
+		} else {
+			parentEntryName = ((JarEntryDirectory) this.parent).getEntryName() + '/';
+		}
+		return parentEntryName + this.simpleName;
+	}
+
+	public IPath getFullPath() {
+		return new Path(getEntryName()).makeAbsolute();
+	}
+
+	public String getName() {
+		return this.simpleName;
+	}
+
+	public Object getParent() {
+		return this.parent;
+	}
+
+	public IPackageFragmentRoot getPackageFragmentRoot() {
+		if (this.parent instanceof IPackageFragment) {
+			return (IPackageFragmentRoot) ((IPackageFragment) this.parent).getParent();
+		} else if (this.parent instanceof IPackageFragmentRoot) {
+			return (IPackageFragmentRoot) this.parent;
+		} else {
+			return ((JarEntryDirectory) this.parent).getPackageFragmentRoot();
+		}
+	}
+
+	protected ZipFile getZipFile() throws CoreException {
+		if (this.parent instanceof IPackageFragment) {
+			JarPackageFragmentRoot root = (JarPackageFragmentRoot) ((IPackageFragment) this.parent).getParent();
+			return root.getJar();
+		} else if (this.parent instanceof JarPackageFragmentRoot) {
+			return ((JarPackageFragmentRoot) this.parent).getJar();
+		} else
+			return ((JarEntryDirectory) this.parent).getZipFile();
+	}
+
+	public int hashCode() {
+		return Util.combineHashCodes(this.simpleName.hashCode(), this.parent.hashCode());
+	}
+
+	public boolean isReadOnly() {
+		return true;
+	}
+
+	public void setParent(Object parent) {
+		this.parent = parent;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
new file mode 100644
index 0000000..ca43b54
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A package fragment that represents a package fragment found in a JAR.
+ *
+ * @see org.eclipse.jdt.core.IPackageFragment
+ */
+class JarPackageFragment extends PackageFragment {
+/**
+ * Constructs a package fragment that is contained within a jar or a zip.
+ */
+protected JarPackageFragment(PackageFragmentRoot root, String[] names) {
+	super(root, names);
+}
+/**
+ * @see Openable
+ */
+protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+	JarPackageFragmentRoot root = (JarPackageFragmentRoot) getParent();
+	JarPackageFragmentRootInfo parentInfo = (JarPackageFragmentRootInfo) root.getElementInfo();
+	ArrayList[] entries = (ArrayList[]) parentInfo.rawPackageInfo.get(this.names);
+	if (entries == null)
+		throw newNotPresentException();
+	JarPackageFragmentInfo fragInfo = (JarPackageFragmentInfo) info;
+
+	// compute children
+	fragInfo.setChildren(computeChildren(entries[0/*class files*/]));
+
+	// compute non-Java resources
+	fragInfo.setNonJavaResources(computeNonJavaResources(entries[1/*non Java resources*/]));
+
+	newElements.put(this, fragInfo);
+	return true;
+}
+/**
+ * Compute the children of this package fragment. Children of jar package fragments
+ * can only be IClassFile (representing .class files).
+ */
+private IJavaElement[] computeChildren(ArrayList namesWithoutExtension) {
+	int size = namesWithoutExtension.size();
+	if (size == 0)
+		return NO_ELEMENTS;
+	IJavaElement[] children = new IJavaElement[size];
+	for (int i = 0; i < size; i++) {
+		String nameWithoutExtension = (String) namesWithoutExtension.get(i);
+		children[i] = new ClassFile(this, nameWithoutExtension);
+	}
+	return children;
+}
+/**
+ * Compute all the non-java resources according to the given entry names.
+ */
+private Object[] computeNonJavaResources(ArrayList entryNames) {
+	int length = entryNames.size();
+	if (length == 0)
+		return JavaElementInfo.NO_NON_JAVA_RESOURCES;
+	HashMap jarEntries = new HashMap(); // map from IPath to IJarEntryResource
+	HashMap childrenMap = new HashMap(); // map from IPath to ArrayList<IJarEntryResource>
+	ArrayList topJarEntries = new ArrayList();
+	for (int i = 0; i < length; i++) {
+		String resName = (String) entryNames.get(i);
+		// consider that a .java file is not a non-java resource (see bug 12246 Packages view shows .class and .java files when JAR has source)
+		if (!Util.isJavaLikeFileName(resName)) {
+			IPath filePath = new Path(resName);
+			IPath childPath = filePath.removeFirstSegments(this.names.length);
+			if (jarEntries.containsKey(childPath)) {
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=222665
+				continue;
+			}
+			JarEntryFile file = new JarEntryFile(filePath.lastSegment());
+			jarEntries.put(childPath, file);
+			if (childPath.segmentCount() == 1) {
+				file.setParent(this);
+				topJarEntries.add(file);
+			} else {
+				IPath parentPath = childPath.removeLastSegments(1);
+				while (parentPath.segmentCount() > 0) {
+					ArrayList parentChildren = (ArrayList) childrenMap.get(parentPath);
+					if (parentChildren == null) {
+						Object dir = new JarEntryDirectory(parentPath.lastSegment());
+						jarEntries.put(parentPath, dir);
+						childrenMap.put(parentPath, parentChildren = new ArrayList());
+						parentChildren.add(childPath);
+						if (parentPath.segmentCount() == 1) {
+							topJarEntries.add(dir);
+							break;
+						}
+						childPath = parentPath;
+						parentPath = childPath.removeLastSegments(1);
+					} else {
+						parentChildren.add(childPath);
+						break; // all parents are already registered
+					}
+				}
+			}
+		}
+	}
+	Iterator entries = childrenMap.entrySet().iterator();
+	while (entries.hasNext()) {
+		Map.Entry entry = (Map.Entry) entries.next();
+		IPath entryPath = (IPath) entry.getKey();
+		ArrayList entryValue =  (ArrayList) entry.getValue();
+		JarEntryDirectory jarEntryDirectory = (JarEntryDirectory) jarEntries.get(entryPath);
+		int size = entryValue.size();
+		IJarEntryResource[] children = new IJarEntryResource[size];
+		for (int i = 0; i < size; i++) {
+			JarEntryResource child = (JarEntryResource) jarEntries.get(entryValue.get(i));
+			child.setParent(jarEntryDirectory);
+			children[i] = child;
+		}
+		jarEntryDirectory.setChildren(children);
+		if (entryPath.segmentCount() == 1) {
+			jarEntryDirectory.setParent(this);
+		}
+	}
+	return topJarEntries.toArray(new Object[topJarEntries.size()]);
+}
+/**
+ * Returns true if this fragment contains at least one java resource.
+ * Returns false otherwise.
+ */
+public boolean containsJavaResources() throws JavaModelException {
+	return ((JarPackageFragmentInfo) getElementInfo()).containsJavaResources();
+}
+/**
+ * @see org.eclipse.jdt.core.IPackageFragment
+ */
+public ICompilationUnit createCompilationUnit(String cuName, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+}
+/**
+ * @see JavaElement
+ */
+protected Object createElementInfo() {
+	return new JarPackageFragmentInfo();
+}
+/**
+ * @see org.eclipse.jdt.core.IPackageFragment
+ */
+public IClassFile[] getClassFiles() throws JavaModelException {
+	ArrayList list = getChildrenOfType(CLASS_FILE);
+	IClassFile[] array= new IClassFile[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * A jar package fragment never contains compilation units.
+ * @see org.eclipse.jdt.core.IPackageFragment
+ */
+public ICompilationUnit[] getCompilationUnits() {
+	return NO_COMPILATION_UNITS;
+}
+/**
+ * A package fragment in a jar has no corresponding resource.
+ *
+ * @see IJavaElement
+ */
+public IResource getCorrespondingResource() {
+	return null;
+}
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+public Object[] getNonJavaResources() throws JavaModelException {
+	if (isDefaultPackage()) {
+		// We don't want to show non java resources of the default package (see PR #1G58NB8)
+		return JavaElementInfo.NO_NON_JAVA_RESOURCES;
+	} else {
+		return storedNonJavaResources();
+	}
+}
+/**
+ * Jars and jar entries are all read only
+ */
+public boolean isReadOnly() {
+	return true;
+}
+protected Object[] storedNonJavaResources() throws JavaModelException {
+	return ((JarPackageFragmentInfo) getElementInfo()).getNonJavaResources();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
new file mode 100644
index 0000000..6a406d2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Element info for JarPackageFragments.
+ */
+class JarPackageFragmentInfo extends PackageFragmentInfo {
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+Object[] getNonJavaResources() {
+	return this.nonJavaResources;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
new file mode 100644
index 0000000..0ca7ac6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.net.URL;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A package fragment root that corresponds to a .jar or .zip.
+ *
+ * <p>NOTE: The only visible entries from a .jar or .zip package fragment root
+ * are .class files.
+ * <p>NOTE: A jar package fragment root may or may not have an associated resource.
+ *
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot
+ * @see org.eclipse.jdt.internal.core.JarPackageFragmentRootInfo
+ */
+public class JarPackageFragmentRoot extends PackageFragmentRoot {
+
+	private final static ArrayList EMPTY_LIST = new ArrayList();
+
+	/**
+	 * The path to the jar file
+	 * (a workspace relative path if the jar is internal,
+	 * or an OS path if the jar is external)
+	 */
+	protected final IPath jarPath;
+
+	/**
+	 * Constructs a package fragment root which is the root of the Java package directory hierarchy
+	 * based on a JAR file that is not contained in a <code>IJavaProject</code> and
+	 * does not have an associated <code>IResource</code>.
+	 */
+	protected JarPackageFragmentRoot(IPath externalJarPath, JavaProject project) {
+		super(null, project);
+		this.jarPath = externalJarPath;
+	}
+	/**
+	 * Constructs a package fragment root which is the root of the Java package directory hierarchy
+	 * based on a JAR file.
+	 */
+	protected JarPackageFragmentRoot(IResource resource, JavaProject project) {
+		super(resource, project);
+		this.jarPath = resource.getFullPath();
+	}
+
+	/**
+	 * Compute the package fragment children of this package fragment root.
+	 * These are all of the directory zip entries, and any directories implied
+	 * by the path of class files contained in the jar of this package fragment root.
+	 */
+	protected boolean computeChildren(OpenableElementInfo info, IResource underlyingResource) throws JavaModelException {
+		HashtableOfArrayToObject rawPackageInfo = new HashtableOfArrayToObject();
+		IJavaElement[] children;
+		ZipFile jar = null;
+		try {
+			IJavaProject project = getJavaProject();
+			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+			String compliance = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			jar = getJar();
+
+			// always create the default package
+			rawPackageInfo.put(CharOperation.NO_STRINGS, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
+
+			for (Enumeration e= jar.entries(); e.hasMoreElements();) {
+				ZipEntry member= (ZipEntry) e.nextElement();
+				initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory(), sourceLevel, compliance);
+			}
+
+			// loop through all of referenced packages, creating package fragments if necessary
+			// and cache the entry names in the rawPackageInfo table
+			children = new IJavaElement[rawPackageInfo.size()];
+			int index = 0;
+			for (int i = 0, length = rawPackageInfo.keyTable.length; i < length; i++) {
+				String[] pkgName = (String[]) rawPackageInfo.keyTable[i];
+				if (pkgName == null) continue;
+				children[index++] = getPackageFragment(pkgName);
+			}
+		} catch (CoreException e) {
+			if (e.getCause() instanceof ZipException) {
+				// not a ZIP archive, leave the children empty
+				Util.log(IStatus.ERROR, "Invalid ZIP archive: " + toStringWithAncestors()); //$NON-NLS-1$
+				children = NO_ELEMENTS;
+			} else if (e instanceof JavaModelException) {
+				throw (JavaModelException)e;
+			} else {
+				throw new JavaModelException(e);
+			}
+		} finally {
+			JavaModelManager.getJavaModelManager().closeZipFile(jar);
+		}
+
+		info.setChildren(children);
+		((JarPackageFragmentRootInfo) info).rawPackageInfo = rawPackageInfo;
+		return true;
+	}
+	/**
+	 * Returns a new element info for this element.
+	 */
+	protected Object createElementInfo() {
+		return new JarPackageFragmentRootInfo();
+	}
+	/**
+	 * A Jar is always K_BINARY.
+	 */
+	protected int determineKind(IResource underlyingResource) {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	/**
+	 * Returns true if this handle represents the same jar
+	 * as the given handle. Two jars are equal if they share
+	 * the same zip file.
+	 *
+	 * @see Object#equals
+	 */
+	public boolean equals(Object o) {
+		if (this == o)
+			return true;
+		if (o instanceof JarPackageFragmentRoot) {
+			JarPackageFragmentRoot other= (JarPackageFragmentRoot) o;
+			return this.jarPath.equals(other.jarPath);
+		}
+		return false;
+	}
+	public String getElementName() {
+		return this.jarPath.lastSegment();
+	}
+	/**
+	 * Returns the underlying ZipFile for this Jar package fragment root.
+	 *
+	 * @exception CoreException if an error occurs accessing the jar
+	 */
+	public ZipFile getJar() throws CoreException {
+		return JavaModelManager.getJavaModelManager().getZipFile(getPath());
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public int getKind() {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	int internalKind() throws JavaModelException {
+		return IPackageFragmentRoot.K_BINARY;
+	}
+	/**
+	 * Returns an array of non-java resources contained in the receiver.
+	 */
+	public Object[] getNonJavaResources() throws JavaModelException {
+		// We want to show non java resources of the default package at the root (see PR #1G58NB8)
+		Object[] defaultPkgResources =  ((JarPackageFragment) getPackageFragment(CharOperation.NO_STRINGS)).storedNonJavaResources();
+		int length = defaultPkgResources.length;
+		if (length == 0)
+			return defaultPkgResources;
+		Object[] nonJavaResources = new Object[length];
+		for (int i = 0; i < length; i++) {
+			JarEntryResource nonJavaResource = (JarEntryResource) defaultPkgResources[i];
+			nonJavaResources[i] = nonJavaResource.clone(this);
+		}
+		return nonJavaResources;
+	}
+	public PackageFragment getPackageFragment(String[] pkgName) {
+		return new JarPackageFragment(this, pkgName);
+	}
+	public IPath internalPath() {
+		if (isExternal()) {
+			return this.jarPath;
+		} else {
+			return super.internalPath();
+		}
+	}
+	public IResource resource(PackageFragmentRoot root) {
+		if (this.resource == null) {
+			// external jar
+			return null;
+		}
+		return super.resource(root);
+	}
+
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IResource getUnderlyingResource() throws JavaModelException {
+		if (isExternal()) {
+			if (!exists()) throw newNotPresentException();
+			return null;
+		} else {
+			return super.getUnderlyingResource();
+		}
+	}
+	public int hashCode() {
+		return this.jarPath.hashCode();
+	}
+	private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory, String sourceLevel, String compliance) {
+		int lastSeparator = isDirectory ? entryName.length()-1 : entryName.lastIndexOf('/');
+		String[] pkgName = Util.splitOn('/', entryName, 0, lastSeparator);
+		String[] existing = null;
+		int length = pkgName.length;
+		int existingLength = length;
+		while (existingLength >= 0) {
+			existing = (String[]) rawPackageInfo.getKey(pkgName, existingLength);
+			if (existing != null) break;
+			existingLength--;
+		}
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		for (int i = existingLength; i < length; i++) {
+			if (Util.isValidFolderNameForPackage(pkgName[i], sourceLevel, compliance)) {
+				System.arraycopy(existing, 0, existing = new String[i+1], 0, i);
+				existing[i] = manager.intern(pkgName[i]);
+				rawPackageInfo.put(existing, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
+			} else {
+				// non-Java resource folder
+				if (!isDirectory) {
+					ArrayList[] children = (ArrayList[]) rawPackageInfo.get(existing);
+					if (children[1/*NON_JAVA*/] == EMPTY_LIST) children[1/*NON_JAVA*/] = new ArrayList();
+					children[1/*NON_JAVA*/].add(entryName);
+				}
+				return;
+			}
+		}
+		if (isDirectory)
+			return;
+
+		// add classfile info amongst children
+		ArrayList[] children = (ArrayList[]) rawPackageInfo.get(pkgName);
+		if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(entryName)) {
+			if (children[0/*JAVA*/] == EMPTY_LIST) children[0/*JAVA*/] = new ArrayList();
+			String nameWithoutExtension = entryName.substring(lastSeparator + 1, entryName.length() - 6);
+			children[0/*JAVA*/].add(nameWithoutExtension);
+		} else {
+			if (children[1/*NON_JAVA*/] == EMPTY_LIST) children[1/*NON_JAVA*/] = new ArrayList();
+			children[1/*NON_JAVA*/].add(entryName);
+		}
+
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public boolean isArchive() {
+		return true;
+	}
+	/**
+	 * @see IPackageFragmentRoot
+	 */
+	public boolean isExternal() {
+		return resource() == null;
+	}
+	/**
+	 * Jars and jar entries are all read only
+	 */
+	public boolean isReadOnly() {
+		return true;
+	}
+
+	/**
+	 * Returns whether the corresponding resource or associated file exists
+	 */
+	protected boolean resourceExists(IResource underlyingResource) {
+		if (underlyingResource == null) {
+			return
+				JavaModel.getExternalTarget(
+					getPath()/*don't make the path relative as this is an external archive*/,
+					true/*check existence*/) != null;
+		} else {
+			return super.resourceExists(underlyingResource);
+		}
+	}
+
+	protected void toStringAncestors(StringBuffer buffer) {
+		if (isExternal())
+			// don't show project as it is irrelevant for external jar files.
+			// also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=146615
+			return;
+		super.toStringAncestors(buffer);
+	}
+
+	public URL getIndexPath() {
+		try {
+			IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath());
+			if (entry != null) return ((ClasspathEntry)entry).getLibraryIndexLocation();	
+		} catch (JavaModelException e) {
+			// ignore exception
+		}
+		return null;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java
new file mode 100644
index 0000000..7955b08
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+
+/**
+ * The element info for <code>JarPackageFragmentRoot</code>s.
+ */
+class JarPackageFragmentRootInfo extends PackageFragmentRootInfo {
+	// a map from package name (String[]) to a size-2 array of Array<String>, the first element being the .class file names, and the second element being the non-Java resource names
+	HashtableOfArrayToObject rawPackageInfo;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
new file mode 100644
index 0000000..8fea5d7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.*;
+
+import org.eclipse.core.runtime.preferences.*;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * JavaCore eclipse preferences initializer.
+ * Initially done in JavaCore.initializeDefaultPreferences which was deprecated
+ * with new eclipse preferences mechanism.
+ */
+public class JavaCorePreferenceInitializer extends AbstractPreferenceInitializer {
+
+	/**
+	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+	 */
+	public void initializeDefaultPreferences() {
+		// If modified, also modify the method JavaModelManager#getDefaultOptionsNoInitialization()
+		// and also consider updating org.eclipse.jdt.internal.compiler.batch.Main#initializeWarnings(String)
+		// Get options names set
+		HashSet optionNames = JavaModelManager.getJavaModelManager().optionNames;
+
+		// Compiler settings
+		Map defaultOptionsMap = new CompilerOptions().getMap(); // compiler defaults
+
+		// Override some compiler defaults
+		defaultOptionsMap.put(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.GENERATE);
+		defaultOptionsMap.put(JavaCore.COMPILER_CODEGEN_UNUSED_LOCAL, JavaCore.PRESERVE);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_TAGS, JavaCore.DEFAULT_TASK_TAGS);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_PRIORITIES, JavaCore.DEFAULT_TASK_PRIORITIES);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_CASE_SENSITIVE, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
+
+		// Builder settings
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.ABORT);
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, JavaCore.WARNING);
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, JavaCore.CLEAN);
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER, JavaCore.IGNORE);
+
+		// JavaCore settings
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_ORDER, JavaCore.IGNORE);
+		defaultOptionsMap.put(JavaCore.CORE_INCOMPLETE_CLASSPATH, JavaCore.ERROR);
+		defaultOptionsMap.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.ERROR);
+		defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE);
+		defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR);
+
+		// encoding setting comes from resource plug-in
+		optionNames.add(JavaCore.CORE_ENCODING);
+
+		// Formatter settings
+		Map codeFormatterOptionsMap = DefaultCodeFormatterConstants.getEclipseDefaultSettings(); // code formatter defaults
+		for (Iterator iter = codeFormatterOptionsMap.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			String optionName = (String) entry.getKey();
+			defaultOptionsMap.put(optionName, entry.getValue());
+			optionNames.add(optionName);
+		}
+
+		// CodeAssist settings
+		defaultOptionsMap.put(JavaCore.CODEASSIST_VISIBILITY_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_DEPRECATION_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_IMPLICIT_QUALIFICATION, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
+
+		// Time out for parameter names
+		defaultOptionsMap.put(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, "50"); //$NON-NLS-1$
+
+		// Store default values to default preferences
+	 	IEclipsePreferences defaultPreferences = DefaultScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+		for (Iterator iter = defaultOptionsMap.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			String optionName = (String) entry.getKey();
+			defaultPreferences.put(optionName, (String)entry.getValue());
+			optionNames.add(optionName);
+		}
+
+		// Initialize deprecated options
+		initializeDeprecatedOptions();
+	}
+
+	/**
+	 * @deprecated As using deprecated options
+	 */
+	private void initializeDeprecatedOptions() {
+		Map deprecatedOptions = JavaModelManager.getJavaModelManager().deprecatedOptions;
+		deprecatedOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER,
+			new String[] {
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE
+			});
+		deprecatedOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION,
+			new String[] {
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE,
+				DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER
+			});
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java
new file mode 100644
index 0000000..5fb1012
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.core.runtime.preferences.PreferenceModifyListener;
+import org.eclipse.jdt.core.*;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+public class JavaCorePreferenceModifyListener extends PreferenceModifyListener {
+
+	static int PREFIX_LENGTH = JavaModelManager.CP_CONTAINER_PREFERENCES_PREFIX.length();
+	JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel();
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.runtime.preferences.PreferenceModifyListener#preApply(org.eclipse.core.runtime.preferences.IEclipsePreferences)
+	 */
+	public IEclipsePreferences preApply(IEclipsePreferences node) {
+		Preferences instance = node.node(InstanceScope.SCOPE);
+		cleanJavaCore(instance.node(JavaCore.PLUGIN_ID));
+		return super.preApply(node);
+	}
+
+	/**
+	 * Clean imported preferences from obsolete keys.
+	 *
+	 * @param preferences JavaCore preferences.
+	 */
+	void cleanJavaCore(Preferences preferences) {
+		try {
+			String[] keys = preferences.keys();
+			for (int k = 0, kl= keys.length; k<kl; k++) {
+				String key = keys[k];
+				if (key.startsWith(JavaModelManager.CP_CONTAINER_PREFERENCES_PREFIX) && !isJavaProjectAccessible(key)) {
+					preferences.remove(key);
+				}
+			}
+		} catch (BackingStoreException e) {
+			// do nothing
+		}
+	}
+
+	/**
+	 * Returns whether a java project referenced in property key
+	 * is still longer accessible or not.
+	 *
+	 * @param propertyName
+	 * @return true if a project is referenced in given key and this project
+	 * 	is still accessible, false otherwise.
+	 */
+	boolean isJavaProjectAccessible(String propertyName) {
+		int index = propertyName.indexOf('|', PREFIX_LENGTH);
+		if (index > 0) {
+			final String projectName = propertyName.substring(PREFIX_LENGTH, index).trim();
+			JavaProject project = (JavaProject) this.javaModel.getJavaProject(projectName);
+			if (project.getProject().isAccessible()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
new file mode 100644
index 0000000..2316cd7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
@@ -0,0 +1,858 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Root of Java element handle hierarchy.
+ *
+ * @see IJavaElement
+ */
+public abstract class JavaElement extends PlatformObject implements IJavaElement {
+//	private static final QualifiedName PROJECT_JAVADOC= new QualifiedName(JavaCore.PLUGIN_ID, "project_javadoc_location"); //$NON-NLS-1$
+
+	private static final byte[] CLOSING_DOUBLE_QUOTE = new byte[] { 34 };
+	/* To handle the pre - HTML 5 format: <META http-equiv="Content-Type" content="text/html; charset=UTF-8">  */
+	private static final byte[] CHARSET = new byte[] { 99, 104, 97, 114, 115, 101, 116, 61 };
+	/* To handle the HTML 5 format: <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"> */
+	private static final byte[] CHARSET_HTML5 = new byte[] { 99, 104, 97, 114, 115, 101, 116, 61, 34 };
+	private static final byte[] META_START = new byte[] { 60, 109, 101, 116, 97 };
+	private static final byte[] META_END = new byte[] { 34, 62 };
+	public static final char JEM_ESCAPE = '\\';
+	public static final char JEM_JAVAPROJECT = '=';
+	public static final char JEM_PACKAGEFRAGMENTROOT = '/';
+	public static final char JEM_PACKAGEFRAGMENT = '<';
+	public static final char JEM_FIELD = '^';
+	public static final char JEM_METHOD = '~';
+	public static final char JEM_INITIALIZER = '|';
+	public static final char JEM_COMPILATIONUNIT = '{';
+	public static final char JEM_CLASSFILE = '(';
+	public static final char JEM_TYPE = '[';
+	public static final char JEM_PACKAGEDECLARATION = '%';
+	public static final char JEM_IMPORTDECLARATION = '#';
+	public static final char JEM_COUNT = '!';
+	public static final char JEM_LOCALVARIABLE = '@';
+	public static final char JEM_TYPE_PARAMETER = ']';
+	public static final char JEM_ANNOTATION = '}';
+
+	/**
+	 * This element's parent, or <code>null</code> if this
+	 * element does not have a parent.
+	 */
+	protected JavaElement parent;
+
+	protected static final JavaElement[] NO_ELEMENTS = new JavaElement[0];
+	protected static final Object NO_INFO = new Object();
+
+	/**
+	 * Constructs a handle for a java element with
+	 * the given parent element.
+	 *
+	 * @param parent The parent of java element
+	 *
+	 * @exception IllegalArgumentException if the type is not one of the valid
+	 *		Java element type constants
+	 *
+	 */
+	protected JavaElement(JavaElement parent) throws IllegalArgumentException {
+		this.parent = parent;
+	}
+	/**
+	 * @see IOpenable
+	 */
+	public void close() throws JavaModelException {
+		JavaModelManager.getJavaModelManager().removeInfoAndChildren(this);
+	}
+	/**
+	 * This element is being closed.  Do any necessary cleanup.
+	 */
+	protected abstract void closing(Object info) throws JavaModelException;
+	/*
+	 * Returns a new element info for this element.
+	 */
+	protected abstract Object createElementInfo();
+	/**
+	 * Returns true if this handle represents the same Java element
+	 * as the given handle. By default, two handles represent the same
+	 * element if they are identical or if they represent the same type
+	 * of element, have equal names, parents, and occurrence counts.
+	 *
+	 * <p>If a subclass has other requirements for equality, this method
+	 * must be overridden.
+	 *
+	 * @see Object#equals
+	 */
+	public boolean equals(Object o) {
+
+		if (this == o) return true;
+
+		// Java model parent is null
+		if (this.parent == null) return super.equals(o);
+
+		// assume instanceof check is done in subclass
+		JavaElement other = (JavaElement) o;
+		return getElementName().equals(other.getElementName()) &&
+				this.parent.equals(other.parent);
+	}
+	protected void escapeMementoName(StringBuffer buffer, String mementoName) {
+		for (int i = 0, length = mementoName.length(); i < length; i++) {
+			char character = mementoName.charAt(i);
+			switch (character) {
+				case JEM_ESCAPE:
+				case JEM_COUNT:
+				case JEM_JAVAPROJECT:
+				case JEM_PACKAGEFRAGMENTROOT:
+				case JEM_PACKAGEFRAGMENT:
+				case JEM_FIELD:
+				case JEM_METHOD:
+				case JEM_INITIALIZER:
+				case JEM_COMPILATIONUNIT:
+				case JEM_CLASSFILE:
+				case JEM_TYPE:
+				case JEM_PACKAGEDECLARATION:
+				case JEM_IMPORTDECLARATION:
+				case JEM_LOCALVARIABLE:
+				case JEM_TYPE_PARAMETER:
+				case JEM_ANNOTATION:
+					buffer.append(JEM_ESCAPE);
+			}
+			buffer.append(character);
+		}
+	}
+	/**
+	 * @see IJavaElement
+	 */
+	public boolean exists() {
+
+		try {
+			getElementInfo();
+			return true;
+		} catch (JavaModelException e) {
+			// element doesn't exist: return false
+		}
+		return false;
+	}
+
+	/**
+	 * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
+	 * or <code>null</code> if there is no corresponding node.
+	 */
+	public ASTNode findNode(CompilationUnit ast) {
+		return null; // works only inside a compilation unit
+	}
+	/**
+	 * Generates the element infos for this element, its ancestors (if they are not opened) and its children (if it is an Openable).
+	 * Puts the newly created element info in the given map.
+	 */
+	protected abstract void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) throws JavaModelException;
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IJavaElement getAncestor(int ancestorType) {
+
+		IJavaElement element = this;
+		while (element != null) {
+			if (element.getElementType() == ancestorType)  return element;
+			element= element.getParent();
+		}
+		return null;
+	}
+	/**
+	 * @see IParent
+	 */
+	public IJavaElement[] getChildren() throws JavaModelException {
+		Object elementInfo = getElementInfo();
+		if (elementInfo instanceof JavaElementInfo) {
+			return ((JavaElementInfo)elementInfo).getChildren();
+		} else {
+			return NO_ELEMENTS;
+		}
+	}
+	/**
+	 * Returns a collection of (immediate) children of this node of the
+	 * specified type.
+	 *
+	 * @param type - one of the JEM_* constants defined by JavaElement
+	 */
+	public ArrayList getChildrenOfType(int type) throws JavaModelException {
+		IJavaElement[] children = getChildren();
+		int size = children.length;
+		ArrayList list = new ArrayList(size);
+		for (int i = 0; i < size; ++i) {
+			JavaElement elt = (JavaElement)children[i];
+			if (elt.getElementType() == type) {
+				list.add(elt);
+			}
+		}
+		return list;
+	}
+	/**
+	 * @see IMember
+	 */
+	public IClassFile getClassFile() {
+		return null;
+	}
+	/**
+	 * @see IMember
+	 */
+	public ICompilationUnit getCompilationUnit() {
+		return null;
+	}
+	/**
+	 * Returns the info for this handle.
+	 * If this element is not already open, it and all of its parents are opened.
+	 * Does not return null.
+	 * NOTE: BinaryType infos are NOT rooted under JavaElementInfo.
+	 * @exception JavaModelException if the element is not present or not accessible
+	 */
+	public Object getElementInfo() throws JavaModelException {
+		return getElementInfo(null);
+	}
+	/**
+	 * Returns the info for this handle.
+	 * If this element is not already open, it and all of its parents are opened.
+	 * Does not return null.
+	 * NOTE: BinaryType infos are NOT rooted under JavaElementInfo.
+	 * @exception JavaModelException if the element is not present or not accessible
+	 */
+	public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException {
+
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		Object info = manager.getInfo(this);
+		if (info != null) return info;
+		return openWhenClosed(createElementInfo(), false, monitor);
+	}
+	/**
+	 * @see IAdaptable
+	 */
+	public String getElementName() {
+		return ""; //$NON-NLS-1$
+	}
+	/*
+	 * Creates a Java element handle from the given memento.
+	 * The given token is the current delimiter indicating the type of the next token(s).
+	 * The given working copy owner is used only for compilation unit handles.
+	 */
+	public abstract IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner);
+	/*
+	 * Creates a Java element handle from the given memento.
+	 * The given working copy owner is used only for compilation unit handles.
+	 */
+	public IJavaElement getHandleFromMemento(MementoTokenizer memento, WorkingCopyOwner owner) {
+		if (!memento.hasMoreTokens()) return this;
+		String token = memento.nextToken();
+		return getHandleFromMemento(token, memento, owner);
+	}
+	/**
+	 * @see IJavaElement
+	 */
+	public String getHandleIdentifier() {
+		return getHandleMemento();
+	}
+	/**
+	 * @see JavaElement#getHandleMemento()
+	 */
+	public String getHandleMemento(){
+		StringBuffer buff = new StringBuffer();
+		getHandleMemento(buff);
+		return buff.toString();
+	}
+	protected void getHandleMemento(StringBuffer buff) {
+		((JavaElement)getParent()).getHandleMemento(buff);
+		buff.append(getHandleMementoDelimiter());
+		escapeMementoName(buff, getElementName());
+	}
+	/**
+	 * Returns the <code>char</code> that marks the start of this handles
+	 * contribution to a memento.
+	 */
+	protected abstract char getHandleMementoDelimiter();
+	/**
+	 * @see IJavaElement
+	 */
+	public IJavaModel getJavaModel() {
+		IJavaElement current = this;
+		do {
+			if (current instanceof IJavaModel) return (IJavaModel) current;
+		} while ((current = current.getParent()) != null);
+		return null;
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IJavaProject getJavaProject() {
+		IJavaElement current = this;
+		do {
+			if (current instanceof IJavaProject) return (IJavaProject) current;
+		} while ((current = current.getParent()) != null);
+		return null;
+	}
+	/*
+	 * @see IJavaElement
+	 */
+	public IOpenable getOpenable() {
+		return getOpenableParent();
+	}
+	/**
+	 * Return the first instance of IOpenable in the parent
+	 * hierarchy of this element.
+	 *
+	 * <p>Subclasses that are not IOpenable's must override this method.
+	 */
+	public IOpenable getOpenableParent() {
+		return (IOpenable)this.parent;
+	}
+	/**
+	 * @see IJavaElement
+	 */
+	public IJavaElement getParent() {
+		return this.parent;
+	}
+	/*
+	 * @see IJavaElement#getPrimaryElement()
+	 */
+	public IJavaElement getPrimaryElement() {
+		return getPrimaryElement(true);
+	}
+	/*
+	 * Returns the primary element. If checkOwner, and the cu owner is primary,
+	 * return this element.
+	 */
+	public IJavaElement getPrimaryElement(boolean checkOwner) {
+		return this;
+	}
+	public IResource getResource() {
+		return resource();
+	}
+	public abstract IResource resource();
+	/**
+	 * Returns the element that is located at the given source position
+	 * in this element.  This is a helper method for <code>ICompilationUnit#getElementAt</code>,
+	 * and only works on compilation units and types. The position given is
+	 * known to be within this element's source range already, and if no finer
+	 * grained element is found at the position, this element is returned.
+	 */
+	protected IJavaElement getSourceElementAt(int position) throws JavaModelException {
+		if (this instanceof ISourceReference) {
+			IJavaElement[] children = getChildren();
+			for (int i = children.length-1; i >= 0; i--) {
+				IJavaElement aChild = children[i];
+				if (aChild instanceof SourceRefElement) {
+					SourceRefElement child = (SourceRefElement) children[i];
+					ISourceRange range = child.getSourceRange();
+					int start = range.getOffset();
+					int end = start + range.getLength();
+					if (start <= position && position <= end) {
+						if (child instanceof IField) {
+							// check muti-declaration case (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=39943)
+							int declarationStart = start;
+							SourceRefElement candidate = null;
+							do {
+								// check name range
+								range = ((IField)child).getNameRange();
+								if (position <= range.getOffset() + range.getLength()) {
+									candidate = child;
+								} else {
+									return candidate == null ? child.getSourceElementAt(position) : candidate.getSourceElementAt(position);
+								}
+								child = --i>=0 ? (SourceRefElement) children[i] : null;
+							} while (child != null && child.getSourceRange().getOffset() == declarationStart);
+							// position in field's type: use first field
+							return candidate.getSourceElementAt(position);
+						} else if (child instanceof IParent) {
+							return child.getSourceElementAt(position);
+						} else {
+							return child;
+						}
+					}
+				}
+			}
+		} else {
+			// should not happen
+			Assert.isTrue(false);
+		}
+		return this;
+	}
+	/**
+	 * Returns the SourceMapper facility for this element, or
+	 * <code>null</code> if this element does not have a
+	 * SourceMapper.
+	 */
+	public SourceMapper getSourceMapper() {
+		return ((JavaElement)getParent()).getSourceMapper();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IJavaElement#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		IResource resource = resource();
+		if (resource == null) {
+			class NoResourceSchedulingRule implements ISchedulingRule {
+				public IPath path;
+				public NoResourceSchedulingRule(IPath path) {
+					this.path = path;
+				}
+				public boolean contains(ISchedulingRule rule) {
+					if (rule instanceof NoResourceSchedulingRule) {
+						return this.path.isPrefixOf(((NoResourceSchedulingRule)rule).path);
+					} else {
+						return false;
+					}
+				}
+				public boolean isConflicting(ISchedulingRule rule) {
+					if (rule instanceof NoResourceSchedulingRule) {
+						IPath otherPath = ((NoResourceSchedulingRule)rule).path;
+						return this.path.isPrefixOf(otherPath) || otherPath.isPrefixOf(this.path);
+					} else {
+						return false;
+					}
+				}
+			}
+			return new NoResourceSchedulingRule(getPath());
+		} else {
+			return resource;
+		}
+	}
+	/**
+	 * @see IParent
+	 */
+	public boolean hasChildren() throws JavaModelException {
+		// if I am not open, return true to avoid opening (case of a Java project, a compilation unit or a class file).
+		// also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52474
+		Object elementInfo = JavaModelManager.getJavaModelManager().getInfo(this);
+		if (elementInfo instanceof JavaElementInfo) {
+			return ((JavaElementInfo)elementInfo).getChildren().length > 0;
+		} else {
+			return true;
+		}
+	}
+
+	/**
+	 * Returns the hash code for this Java element. By default,
+	 * the hash code for an element is a combination of its name
+	 * and parent's hash code. Elements with other requirements must
+	 * override this method.
+	 */
+	public int hashCode() {
+		if (this.parent == null) return super.hashCode();
+		return Util.combineHashCodes(getElementName().hashCode(), this.parent.hashCode());
+	}
+	/**
+	 * Returns true if this element is an ancestor of the given element,
+	 * otherwise false.
+	 */
+	public boolean isAncestorOf(IJavaElement e) {
+		IJavaElement parentElement= e.getParent();
+		while (parentElement != null && !parentElement.equals(this)) {
+			parentElement= parentElement.getParent();
+		}
+		return parentElement != null;
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public boolean isReadOnly() {
+		return false;
+	}
+	/**
+	 * Creates and returns a new not present exception for this element.
+	 */
+	public JavaModelException newNotPresentException() {
+		return new JavaModelException(newDoesNotExistStatus());
+	}
+	protected JavaModelStatus newDoesNotExistStatus() {
+		return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this);
+	}
+	/**
+	 * Creates and returns a new Java model exception for this element with the given status.
+	 */
+	public JavaModelException newJavaModelException(IStatus status) {
+		if (status instanceof IJavaModelStatus)
+			return new JavaModelException((IJavaModelStatus) status);
+		else
+			return new JavaModelException(new JavaModelStatus(status.getSeverity(), status.getCode(), status.getMessage()));
+	}
+	/*
+	 * Opens an <code>Openable</code> that is known to be closed (no check for <code>isOpen()</code>).
+	 * Returns the created element info.
+	 */
+	protected Object openWhenClosed(Object info, boolean forceAdd, IProgressMonitor monitor) throws JavaModelException {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		boolean hadTemporaryCache = manager.hasTemporaryCache();
+		try {
+			HashMap newElements = manager.getTemporaryCache();
+			generateInfos(info, newElements, monitor);
+			if (info == null) {
+				info = newElements.get(this);
+			}
+			if (info == null) { // a source ref element could not be opened
+				// close the buffer that was opened for the openable parent
+			    // close only the openable's buffer (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=62854)
+			    Openable openable = (Openable) getOpenable();
+			    if (newElements.containsKey(openable)) {
+			        openable.closeBuffer();
+			    }
+				throw newNotPresentException();
+			}
+			if (!hadTemporaryCache) {
+				info = manager.putInfos(this, info, forceAdd, newElements);
+			}
+		} finally {
+			if (!hadTemporaryCache) {
+				manager.resetTemporaryCache();
+			}
+		}
+		return info;
+	}
+	/**
+	 */
+	public String readableName() {
+		return getElementName();
+	}
+	public JavaElement resolved(Binding binding) {
+		return this;
+	}
+	public JavaElement unresolved() {
+		return this;
+	}
+	protected String tabString(int tab) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = tab; i > 0; i--)
+			buffer.append("  "); //$NON-NLS-1$
+		return buffer.toString();
+	}
+	/**
+	 * Debugging purposes
+	 */
+	public String toDebugString() {
+		StringBuffer buffer = new StringBuffer();
+		this.toStringInfo(0, buffer, NO_INFO, true/*show resolved info*/);
+		return buffer.toString();
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		toString(0, buffer);
+		return buffer.toString();
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	protected void toString(int tab, StringBuffer buffer) {
+		Object info = this.toStringInfo(tab, buffer);
+		if (tab == 0) {
+			toStringAncestors(buffer);
+		}
+		toStringChildren(tab, buffer, info);
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	public String toStringWithAncestors() {
+		return toStringWithAncestors(true/*show resolved info*/);
+	}
+		/**
+	 *  Debugging purposes
+	 */
+	public String toStringWithAncestors(boolean showResolvedInfo) {
+		StringBuffer buffer = new StringBuffer();
+		this.toStringInfo(0, buffer, NO_INFO, showResolvedInfo);
+		toStringAncestors(buffer);
+		return buffer.toString();
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	protected void toStringAncestors(StringBuffer buffer) {
+		JavaElement parentElement = (JavaElement)getParent();
+		if (parentElement != null && parentElement.getParent() != null) {
+			buffer.append(" [in "); //$NON-NLS-1$
+			parentElement.toStringInfo(0, buffer, NO_INFO, false/*don't show resolved info*/);
+			parentElement.toStringAncestors(buffer);
+			buffer.append("]"); //$NON-NLS-1$
+		}
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	protected void toStringChildren(int tab, StringBuffer buffer, Object info) {
+		if (info == null || !(info instanceof JavaElementInfo)) return;
+		IJavaElement[] children = ((JavaElementInfo)info).getChildren();
+		for (int i = 0; i < children.length; i++) {
+			buffer.append("\n"); //$NON-NLS-1$
+			((JavaElement)children[i]).toString(tab + 1, buffer);
+		}
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	public Object toStringInfo(int tab, StringBuffer buffer) {
+		Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this);
+		this.toStringInfo(tab, buffer, info, true/*show resolved info*/);
+		return info;
+	}
+	/**
+	 *  Debugging purposes
+	 * @param showResolvedInfo TODO
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		buffer.append(tabString(tab));
+		toStringName(buffer);
+		if (info == null) {
+			buffer.append(" (not open)"); //$NON-NLS-1$
+		}
+	}
+	/**
+	 *  Debugging purposes
+	 */
+	protected void toStringName(StringBuffer buffer) {
+		buffer.append(getElementName());
+	}
+
+	protected URL getJavadocBaseLocation() throws JavaModelException {
+		IPackageFragmentRoot root= (IPackageFragmentRoot) getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		if (root == null) {
+			return null;
+		}
+
+		if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
+			IClasspathEntry entry= null;
+			try {
+				entry= root.getResolvedClasspathEntry();
+				URL url = getLibraryJavadocLocation(entry);
+				if (url != null) {
+					return url;
+				}
+			}
+			catch(JavaModelException jme) {
+				// Proceed with raw classpath
+			}
+			
+			entry= root.getRawClasspathEntry();
+			switch (entry.getEntryKind()) {
+				case IClasspathEntry.CPE_LIBRARY:
+				case IClasspathEntry.CPE_VARIABLE:
+					return getLibraryJavadocLocation(entry);
+				default:
+					return null;
+			}			
+		}
+		return null;
+	}
+
+	protected static URL getLibraryJavadocLocation(IClasspathEntry entry) throws JavaModelException {
+		switch(entry.getEntryKind()) {
+			case IClasspathEntry.CPE_LIBRARY :
+			case IClasspathEntry.CPE_VARIABLE :
+				break;
+			default :
+				throw new IllegalArgumentException("Entry must be of kind CPE_LIBRARY or CPE_VARIABLE"); //$NON-NLS-1$
+		}
+
+		IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
+		for (int i= 0; i < extraAttributes.length; i++) {
+			IClasspathAttribute attrib= extraAttributes[i];
+			if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
+				String value = attrib.getValue();
+				try {
+					return new URL(value);
+				} catch (MalformedURLException e) {
+					throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, value));
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * @see IJavaElement#getAttachedJavadoc(IProgressMonitor)
+	 */
+	public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+		return null;
+	}
+
+	int getIndexOf(byte[] array, byte[] toBeFound, int start, int end) {
+		if (array == null || toBeFound == null)
+			return -1;
+		final int toBeFoundLength = toBeFound.length;
+		final int arrayLength = (end != -1 && end < array.length) ? end : array.length;
+		if (arrayLength < toBeFoundLength)
+			return -1;
+		loop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
+			if (array[i] == toBeFound[0]) {
+				for (int j = 1; j < toBeFoundLength; j++) {
+					if (array[i + j] != toBeFound[j])
+						continue loop;
+				}
+				return i;
+			}
+		}
+		return -1;
+	}
+	/*
+	 * We don't use getContentEncoding() on the URL connection, because it might leave open streams behind.
+	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=117890
+	 */
+	protected String getURLContents(String docUrlValue) throws JavaModelException {
+		InputStream stream = null;
+		JarURLConnection connection2 = null;
+		try {
+			URL docUrl = new URL(docUrlValue);
+			URLConnection connection = docUrl.openConnection();
+			Class[] parameterTypes = new Class[]{int.class};
+			Integer timeoutVal = new Integer(10000);
+			// set the connect and read timeouts using reflection since these methods are not available in java 1.4
+			Class URLClass = connection.getClass();
+			try {
+				Method connectTimeoutMethod = URLClass.getDeclaredMethod("setConnectTimeout", parameterTypes); //$NON-NLS-1$
+				Method readTimeoutMethod = URLClass.getDeclaredMethod("setReadTimeout", parameterTypes); //$NON-NLS-1$
+				connectTimeoutMethod.invoke(connection, new Object[]{timeoutVal});
+				readTimeoutMethod.invoke(connection, new Object[]{timeoutVal});
+			} catch (SecurityException e) {
+				// ignore
+			} catch (IllegalArgumentException e) {
+				// ignore
+			} catch (NoSuchMethodException e) {
+				// ignore
+			} catch (IllegalAccessException e) {
+				// ignore
+			} catch (InvocationTargetException e) {
+				// ignore
+			}
+			
+			if (connection instanceof JarURLConnection) {
+				connection2 = (JarURLConnection) connection;
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=156307
+				connection.setUseCaches(false);
+			}
+			try {
+				stream = new BufferedInputStream(connection.getInputStream());
+			} catch (IllegalArgumentException e) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304316
+				return null;
+			} catch (NullPointerException e) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304316
+				return null;
+			}
+			String encoding = connection.getContentEncoding();
+			byte[] contents = org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, connection.getContentLength());
+			if (encoding == null) {
+				int index = getIndexOf(contents, META_START, 0, -1);
+				if (index != -1) {
+					int end = getIndexOf(contents, META_END, index, -1);
+					if (end != -1) {
+						if ((end + 1) <= contents.length) end++;
+						int charsetIndex = getIndexOf(contents, CHARSET_HTML5, index, end);
+						if (charsetIndex == -1) {
+							charsetIndex = getIndexOf(contents, CHARSET, index, end);
+							if (charsetIndex != -1)
+								charsetIndex = charsetIndex + CHARSET.length;
+						} else {
+							charsetIndex = charsetIndex + CHARSET_HTML5.length;
+						}
+						if (charsetIndex != -1) {
+							end = getIndexOf(contents, CLOSING_DOUBLE_QUOTE, charsetIndex, end);
+							encoding = new String(contents, charsetIndex, end - charsetIndex, org.eclipse.jdt.internal.compiler.util.Util.UTF_8);
+						}
+					}
+				}
+			}
+			try {
+				if (encoding == null) {
+					encoding = getJavaProject().getProject().getDefaultCharset();
+				}
+			} catch (CoreException e) {
+				// ignore
+			}
+			if (contents != null) {
+				if (encoding != null) {
+					return new String(contents, encoding);
+				} else {
+					// platform encoding is used
+					return new String(contents);
+				}
+			}
+		} catch (SocketTimeoutException e) {
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT, this));
+		} catch (MalformedURLException e) {
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC, this));
+		} catch (FileNotFoundException e) {
+			// Ignore, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=120559 &
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=403036
+		} catch (SocketException e) {
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=247845 &
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=400060
+			throw new JavaModelException(e, IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC);
+		} catch (UnknownHostException e) {
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=247845 &
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=400060
+			throw new JavaModelException(e, IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC);
+		} catch (ProtocolException e) {
+			// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=247845 &
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=400060
+			throw new JavaModelException(e, IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC);
+		} catch (IOException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+		} finally {
+			if (stream != null) {
+				try {
+					stream.close();
+				} catch (IOException e) {
+					// ignore
+				}
+			}
+			if (connection2 != null) {
+				try {
+					connection2.getJarFile().close();
+				} catch(IOException e) {
+					// ignore
+				} catch(IllegalStateException e) {
+					/*
+					 * ignore. Can happen in case the stream.close() did close the jar file
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=140750
+					 */
+				}
+ 			}
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
new file mode 100644
index 0000000..ee0d715
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
@@ -0,0 +1,757 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+/**
+ * @see IJavaElementDelta
+ */
+public class JavaElementDelta extends SimpleDelta implements IJavaElementDelta {
+	/**
+	 * @see #getAffectedChildren()
+	 */
+	IJavaElementDelta[] affectedChildren = EMPTY_DELTA;
+
+	/*
+	 * The AST created during the last reconcile operation.
+	 * Non-null only iff:
+	 * - in a POST_RECONCILE event
+	 * - an AST was requested during the last reconcile operation
+	 * - the changed element is an ICompilationUnit in working copy mode
+	 */
+	CompilationUnit ast = null;
+
+	/*
+	 * The element that this delta describes the change to.
+	 */
+	IJavaElement changedElement;
+
+	/**
+	 * Collection of resource deltas that correspond to non java resources deltas.
+	 */
+	IResourceDelta[] resourceDeltas = null;
+
+	/**
+	 * Counter of resource deltas
+	 */
+	int resourceDeltasCounter;
+
+	/**
+	 * @see #getMovedFromElement()
+	 */
+	IJavaElement movedFromHandle = null;
+
+	/**
+	 * @see #getMovedToElement()
+	 */
+	IJavaElement movedToHandle = null;
+
+	IJavaElementDelta[] annotationDeltas = EMPTY_DELTA;
+
+	/**
+	 * Empty array of IJavaElementDelta
+	 */
+	static  IJavaElementDelta[] EMPTY_DELTA= new IJavaElementDelta[] {};
+/**
+ * Creates the root delta. To create the nested delta
+ * hierarchies use the following convenience methods. The root
+ * delta can be created at any level (for example: project, package root,
+ * package fragment...).
+ * <ul>
+ * <li><code>added(IJavaElement)</code>
+ * <li><code>changed(IJavaElement)</code>
+ * <li><code>moved(IJavaElement, IJavaElement)</code>
+ * <li><code>removed(IJavaElement)</code>
+ * <li><code>renamed(IJavaElement, IJavaElement)</code>
+ * </ul>
+ */
+public JavaElementDelta(IJavaElement element) {
+	this.changedElement = element;
+}
+/**
+ * Adds the child delta to the collection of affected children.  If the
+ * child is already in the collection, walk down the hierarchy.
+ */
+protected void addAffectedChild(JavaElementDelta child) {
+	switch (this.kind) {
+		case ADDED:
+		case REMOVED:
+			// no need to add a child if this parent is added or removed
+			return;
+		case CHANGED:
+			this.changeFlags |= F_CHILDREN;
+			break;
+		default:
+			this.kind = CHANGED;
+			this.changeFlags |= F_CHILDREN;
+	}
+
+	// if a child delta is added to a compilation unit delta or below,
+	// it's a fine grained delta
+	if (this.changedElement.getElementType() >= IJavaElement.COMPILATION_UNIT) {
+		fineGrained();
+	}
+
+	if (this.affectedChildren == null || this.affectedChildren.length == 0) {
+		this.affectedChildren = new IJavaElementDelta[] {child};
+		return;
+	}
+	JavaElementDelta existingChild = null;
+	int existingChildIndex = -1;
+	for (int i = 0; i < this.affectedChildren.length; i++) {
+		if (equalsAndSameParent(this.affectedChildren[i].getElement(), child.getElement())) { // handle case of two jars that can be equals but not in the same project
+			existingChild = (JavaElementDelta)this.affectedChildren[i];
+			existingChildIndex = i;
+			break;
+		}
+	}
+	if (existingChild == null) { //new affected child
+		this.affectedChildren= growAndAddToArray(this.affectedChildren, child);
+	} else {
+		switch (existingChild.getKind()) {
+			case ADDED:
+				switch (child.getKind()) {
+					case ADDED: // child was added then added -> it is added
+					case CHANGED: // child was added then changed -> it is added
+						return;
+					case REMOVED: // child was added then removed -> noop
+						this.affectedChildren = removeAndShrinkArray(this.affectedChildren, existingChildIndex);
+						return;
+				}
+				break;
+			case REMOVED:
+				switch (child.getKind()) {
+					case ADDED: // child was removed then added -> it is changed
+						child.kind = CHANGED;
+						this.affectedChildren[existingChildIndex] = child;
+						return;
+					case CHANGED: // child was removed then changed -> it is removed
+					case REMOVED: // child was removed then removed -> it is removed
+						return;
+				}
+				break;
+			case CHANGED:
+				switch (child.getKind()) {
+					case ADDED: // child was changed then added -> it is added
+					case REMOVED: // child was changed then removed -> it is removed
+						this.affectedChildren[existingChildIndex] = child;
+						return;
+					case CHANGED: // child was changed then changed -> it is changed
+						IJavaElementDelta[] children = child.getAffectedChildren();
+						for (int i = 0; i < children.length; i++) {
+							JavaElementDelta childsChild = (JavaElementDelta) children[i];
+							existingChild.addAffectedChild(childsChild);
+						}
+
+						// update flags
+						boolean childHadContentFlag = (child.changeFlags & F_CONTENT) != 0;
+						boolean existingChildHadChildrenFlag = (existingChild.changeFlags & F_CHILDREN) != 0;
+						existingChild.changeFlags |= child.changeFlags;
+
+						// remove F_CONTENT flag if existing child had F_CHILDREN flag set
+						// (case of fine grained delta (existing child) and delta coming from
+						// DeltaProcessor (child))
+						if (childHadContentFlag && existingChildHadChildrenFlag) {
+							existingChild.changeFlags &= ~F_CONTENT;
+						}
+
+						// add the non-java resource deltas if needed
+						// note that the child delta always takes precedence over this existing child delta
+						// as non-java resource deltas are always created last (by the DeltaProcessor)
+						IResourceDelta[] resDeltas = child.getResourceDeltas();
+						if (resDeltas != null) {
+							existingChild.resourceDeltas = resDeltas;
+							existingChild.resourceDeltasCounter = child.resourceDeltasCounter;
+						}
+
+						return;
+				}
+				break;
+			default:
+				// unknown -> existing child becomes the child with the existing child's flags
+				int flags = existingChild.getFlags();
+				this.affectedChildren[existingChildIndex] = child;
+				child.changeFlags |= flags;
+		}
+	}
+}
+/**
+ * Creates the nested deltas resulting from an add operation.
+ * Convenience method for creating add deltas.
+ * The constructor should be used to create the root delta
+ * and then an add operation should call this method.
+ */
+public void added(IJavaElement element) {
+	added(element, 0);
+}
+public void added(IJavaElement element, int flags) {
+	JavaElementDelta addedDelta = new JavaElementDelta(element);
+	addedDelta.added();
+	addedDelta.changeFlags |= flags;
+	insertDeltaTree(element, addedDelta);
+}
+/**
+ * Adds the child delta to the collection of affected children.  If the
+ * child is already in the collection, walk down the hierarchy.
+ */
+protected void addResourceDelta(IResourceDelta child) {
+	switch (this.kind) {
+		case ADDED:
+		case REMOVED:
+			// no need to add a child if this parent is added or removed
+			return;
+		case CHANGED:
+			this.changeFlags |= F_CONTENT;
+			break;
+		default:
+			this.kind = CHANGED;
+			this.changeFlags |= F_CONTENT;
+	}
+	if (this.resourceDeltas == null) {
+		this.resourceDeltas = new IResourceDelta[5];
+		this.resourceDeltas[this.resourceDeltasCounter++] = child;
+		return;
+	}
+	if (this.resourceDeltas.length == this.resourceDeltasCounter) {
+		// need a resize
+		System.arraycopy(this.resourceDeltas, 0, (this.resourceDeltas = new IResourceDelta[this.resourceDeltasCounter * 2]), 0, this.resourceDeltasCounter);
+	}
+	this.resourceDeltas[this.resourceDeltasCounter++] = child;
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta
+ * and then a change operation should call this method.
+ */
+public JavaElementDelta changed(IJavaElement element, int changeFlag) {
+	JavaElementDelta changedDelta = new JavaElementDelta(element);
+	changedDelta.changed(changeFlag);
+	insertDeltaTree(element, changedDelta);
+	return changedDelta;
+}
+/*
+ * Records the last changed AST  .
+ */
+public void changedAST(CompilationUnit changedAST) {
+	this.ast = changedAST;
+	changed(F_AST_AFFECTED);
+}
+/**
+ * Mark this delta as a content changed delta.
+ */
+public void contentChanged() {
+	this.changeFlags |= F_CONTENT;
+}
+/**
+ * Creates the nested deltas for a closed element.
+ */
+public void closed(IJavaElement element) {
+	JavaElementDelta delta = new JavaElementDelta(element);
+	delta.changed(F_CLOSED);
+	insertDeltaTree(element, delta);
+}
+/**
+ * Creates the nested delta deltas based on the affected element
+ * its delta, and the root of this delta tree. Returns the root
+ * of the created delta tree.
+ */
+protected JavaElementDelta createDeltaTree(IJavaElement element, JavaElementDelta delta) {
+	JavaElementDelta childDelta = delta;
+	ArrayList ancestors= getAncestors(element);
+	if (ancestors == null) {
+		if (equalsAndSameParent(delta.getElement(), getElement())) { // handle case of two jars that can be equals but not in the same project
+			// the element being changed is the root element
+			this.kind= delta.kind;
+			this.changeFlags = delta.changeFlags;
+			this.movedToHandle = delta.movedToHandle;
+			this.movedFromHandle = delta.movedFromHandle;
+		}
+	} else {
+		for (int i = 0, size = ancestors.size(); i < size; i++) {
+			IJavaElement ancestor = (IJavaElement) ancestors.get(i);
+			JavaElementDelta ancestorDelta = new JavaElementDelta(ancestor);
+			ancestorDelta.addAffectedChild(childDelta);
+			childDelta = ancestorDelta;
+		}
+	}
+	return childDelta;
+}
+/**
+ * Returns whether the two java elements are equals and have the same parent.
+ */
+protected boolean equalsAndSameParent(IJavaElement e1, IJavaElement e2) {
+	IJavaElement parent1;
+	return e1.equals(e2) && ((parent1 = e1.getParent()) != null) && parent1.equals(e2.getParent());
+}
+/**
+ * Returns the <code>JavaElementDelta</code> for the given element
+ * in the delta tree, or null, if no delta for the given element is found.
+ */
+protected JavaElementDelta find(IJavaElement e) {
+	if (equalsAndSameParent(this.changedElement, e)) { // handle case of two jars that can be equals but not in the same project
+		return this;
+	} else {
+		for (int i = 0; i < this.affectedChildren.length; i++) {
+			JavaElementDelta delta = ((JavaElementDelta)this.affectedChildren[i]).find(e);
+			if (delta != null) {
+				return delta;
+			}
+		}
+	}
+	return null;
+}
+/**
+ * Mark this delta as a fine-grained delta.
+ */
+public void fineGrained() {
+	changed(F_FINE_GRAINED);
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getAddedChildren() {
+	return getChildrenOfType(ADDED);
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getAffectedChildren() {
+	return this.affectedChildren;
+}
+/**
+ * Returns a collection of all the parents of this element up to (but
+ * not including) the root of this tree in bottom-up order. If the given
+ * element is not a descendant of the root of this tree, <code>null</code>
+ * is returned.
+ */
+private ArrayList getAncestors(IJavaElement element) {
+	IJavaElement parent = element.getParent();
+	if (parent == null) {
+		return null;
+	}
+	ArrayList parents = new ArrayList();
+	while (!parent.equals(this.changedElement)) {
+		parents.add(parent);
+		parent = parent.getParent();
+		if (parent == null) {
+			return null;
+		}
+	}
+	parents.trimToSize();
+	return parents;
+}
+public CompilationUnit getCompilationUnitAST() {
+	return this.ast;
+}
+public IJavaElementDelta[] getAnnotationDeltas() {
+	return this.annotationDeltas;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getChangedChildren() {
+	return getChildrenOfType(CHANGED);
+}
+/**
+ * @see IJavaElementDelta
+ */
+protected IJavaElementDelta[] getChildrenOfType(int type) {
+	int length = this.affectedChildren.length;
+	if (length == 0) {
+		return new IJavaElementDelta[] {};
+	}
+	ArrayList children= new ArrayList(length);
+	for (int i = 0; i < length; i++) {
+		if (this.affectedChildren[i].getKind() == type) {
+			children.add(this.affectedChildren[i]);
+		}
+	}
+
+	IJavaElementDelta[] childrenOfType = new IJavaElementDelta[children.size()];
+	children.toArray(childrenOfType);
+
+	return childrenOfType;
+}
+/**
+ * Returns the delta for a given element.  Only looks below this
+ * delta.
+ */
+protected JavaElementDelta getDeltaFor(IJavaElement element) {
+	if (equalsAndSameParent(getElement(), element)) // handle case of two jars that can be equals but not in the same project
+		return this;
+	if (this.affectedChildren.length == 0)
+		return null;
+	int childrenCount = this.affectedChildren.length;
+	for (int i = 0; i < childrenCount; i++) {
+		JavaElementDelta delta = (JavaElementDelta)this.affectedChildren[i];
+		if (equalsAndSameParent(delta.getElement(), element)) { // handle case of two jars that can be equals but not in the same project
+			return delta;
+		} else {
+			delta = delta.getDeltaFor(element);
+			if (delta != null)
+				return delta;
+		}
+	}
+	return null;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getElement() {
+	return this.changedElement;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getMovedFromElement() {
+	return this.movedFromHandle;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElement getMovedToElement() {
+	return this.movedToHandle;
+}
+/**
+ * @see IJavaElementDelta
+ */
+public IJavaElementDelta[] getRemovedChildren() {
+	return getChildrenOfType(REMOVED);
+}
+/**
+ * Return the collection of resource deltas. Return null if none.
+ */
+public IResourceDelta[] getResourceDeltas() {
+	if (this.resourceDeltas == null) return null;
+	if (this.resourceDeltas.length != this.resourceDeltasCounter) {
+		System.arraycopy(this.resourceDeltas, 0, this.resourceDeltas = new IResourceDelta[this.resourceDeltasCounter], 0, this.resourceDeltasCounter);
+	}
+	return this.resourceDeltas;
+}
+/**
+ * Adds the new element to a new array that contains all of the elements of the old array.
+ * Returns the new array.
+ */
+protected IJavaElementDelta[] growAndAddToArray(IJavaElementDelta[] array, IJavaElementDelta addition) {
+	IJavaElementDelta[] old = array;
+	array = new IJavaElementDelta[old.length + 1];
+	System.arraycopy(old, 0, array, 0, old.length);
+	array[old.length] = addition;
+	return array;
+}
+/**
+ * Creates the delta tree for the given element and delta, and then
+ * inserts the tree as an affected child of this node.
+ */
+protected void insertDeltaTree(IJavaElement element, JavaElementDelta delta) {
+	JavaElementDelta childDelta= createDeltaTree(element, delta);
+	if (!equalsAndSameParent(element, getElement())) { // handle case of two jars that can be equals but not in the same project
+		addAffectedChild(childDelta);
+	}
+}
+/**
+ * Creates the nested deltas resulting from an move operation.
+ * Convenience method for creating the "move from" delta.
+ * The constructor should be used to create the root delta
+ * and then the move operation should call this method.
+ */
+public void movedFrom(IJavaElement movedFromElement, IJavaElement movedToElement) {
+	JavaElementDelta removedDelta = new JavaElementDelta(movedFromElement);
+	removedDelta.kind = REMOVED;
+	removedDelta.changeFlags |= F_MOVED_TO;
+	removedDelta.movedToHandle = movedToElement;
+	insertDeltaTree(movedFromElement, removedDelta);
+}
+/**
+ * Creates the nested deltas resulting from an move operation.
+ * Convenience method for creating the "move to" delta.
+ * The constructor should be used to create the root delta
+ * and then the move operation should call this method.
+ */
+public void movedTo(IJavaElement movedToElement, IJavaElement movedFromElement) {
+	JavaElementDelta addedDelta = new JavaElementDelta(movedToElement);
+	addedDelta.kind = ADDED;
+	addedDelta.changeFlags |= F_MOVED_FROM;
+	addedDelta.movedFromHandle = movedFromElement;
+	insertDeltaTree(movedToElement, addedDelta);
+}
+/**
+ * Creates the nested deltas for an opened element.
+ */
+public void opened(IJavaElement element) {
+	JavaElementDelta delta = new JavaElementDelta(element);
+	delta.changed(F_OPENED);
+	insertDeltaTree(element, delta);
+}
+/**
+ * Removes the child delta from the collection of affected children.
+ */
+protected void removeAffectedChild(JavaElementDelta child) {
+	int index = -1;
+	if (this.affectedChildren != null) {
+		for (int i = 0; i < this.affectedChildren.length; i++) {
+			if (equalsAndSameParent(this.affectedChildren[i].getElement(), child.getElement())) { // handle case of two jars that can be equals but not in the same project
+				index = i;
+				break;
+			}
+		}
+	}
+	if (index >= 0) {
+		this.affectedChildren= removeAndShrinkArray(this.affectedChildren, index);
+	}
+}
+/**
+ * Removes the element from the array.
+ * Returns the a new array which has shrunk.
+ */
+protected IJavaElementDelta[] removeAndShrinkArray(IJavaElementDelta[] old, int index) {
+	IJavaElementDelta[] array = new IJavaElementDelta[old.length - 1];
+	if (index > 0)
+		System.arraycopy(old, 0, array, 0, index);
+	int rest = old.length - index - 1;
+	if (rest > 0)
+		System.arraycopy(old, index + 1, array, index, rest);
+	return array;
+}
+/**
+ * Creates the nested deltas resulting from an delete operation.
+ * Convenience method for creating removed deltas.
+ * The constructor should be used to create the root delta
+ * and then the delete operation should call this method.
+ */
+public void removed(IJavaElement element) {
+	removed(element, 0);
+}
+public void removed(IJavaElement element, int flags) {
+	JavaElementDelta removedDelta= new JavaElementDelta(element);
+	insertDeltaTree(element, removedDelta);
+	JavaElementDelta actualDelta = getDeltaFor(element);
+	if (actualDelta != null) {
+		actualDelta.removed();
+		actualDelta.changeFlags |= flags;
+		actualDelta.affectedChildren = EMPTY_DELTA;
+	}
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta
+ * and then a change operation should call this method.
+ */
+public void sourceAttached(IJavaElement element) {
+	JavaElementDelta attachedDelta = new JavaElementDelta(element);
+	attachedDelta.changed(F_SOURCEATTACHED);
+	insertDeltaTree(element, attachedDelta);
+}
+/**
+ * Creates the nested deltas resulting from a change operation.
+ * Convenience method for creating change deltas.
+ * The constructor should be used to create the root delta
+ * and then a change operation should call this method.
+ */
+public void sourceDetached(IJavaElement element) {
+	JavaElementDelta detachedDelta = new JavaElementDelta(element);
+	detachedDelta.changed(F_SOURCEDETACHED);
+	insertDeltaTree(element, detachedDelta);
+}
+/**
+ * Returns a string representation of this delta's
+ * structure suitable for debug purposes.
+ *
+ * @see #toString()
+ */
+public String toDebugString(int depth) {
+	StringBuffer buffer = new StringBuffer();
+	for (int i= 0; i < depth; i++) {
+		buffer.append('\t');
+	}
+	buffer.append(((JavaElement)getElement()).toDebugString());
+	toDebugString(buffer);
+	IJavaElementDelta[] children = getAffectedChildren();
+	if (children != null) {
+		for (int i = 0; i < children.length; ++i) {
+			buffer.append("\n"); //$NON-NLS-1$
+			buffer.append(((JavaElementDelta) children[i]).toDebugString(depth + 1));
+		}
+	}
+	for (int i = 0; i < this.resourceDeltasCounter; i++) {
+		buffer.append("\n");//$NON-NLS-1$
+		for (int j = 0; j < depth+1; j++) {
+			buffer.append('\t');
+		}
+		IResourceDelta resourceDelta = this.resourceDeltas[i];
+		buffer.append(resourceDelta.toString());
+		buffer.append("["); //$NON-NLS-1$
+		switch (resourceDelta.getKind()) {
+			case IResourceDelta.ADDED :
+				buffer.append('+');
+				break;
+			case IResourceDelta.REMOVED :
+				buffer.append('-');
+				break;
+			case IResourceDelta.CHANGED :
+				buffer.append('*');
+				break;
+			default :
+				buffer.append('?');
+				break;
+		}
+		buffer.append("]"); //$NON-NLS-1$
+	}
+	IJavaElementDelta[] annotations = getAnnotationDeltas();
+	if (annotations != null) {
+		for (int i = 0; i < annotations.length; ++i) {
+			buffer.append("\n"); //$NON-NLS-1$
+			buffer.append(((JavaElementDelta) annotations[i]).toDebugString(depth + 1));
+		}
+	}
+	return buffer.toString();
+}
+protected boolean toDebugString(StringBuffer buffer, int flags) {
+	boolean prev = super.toDebugString(buffer, flags);
+
+	if ((flags & IJavaElementDelta.F_CHILDREN) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("CHILDREN"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_CONTENT) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("CONTENT"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_MOVED_FROM) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("MOVED_FROM(" + ((JavaElement)getMovedFromElement()).toStringWithAncestors() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_MOVED_TO) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("MOVED_TO(" + ((JavaElement)getMovedToElement()).toStringWithAncestors() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("ADDED TO CLASSPATH"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("REMOVED FROM CLASSPATH"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_REORDER) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("REORDERED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("ARCHIVE CONTENT CHANGED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_SOURCEATTACHED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("SOURCE ATTACHED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_SOURCEDETACHED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("SOURCE DETACHED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_FINE_GRAINED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("FINE GRAINED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_PRIMARY_WORKING_COPY) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("PRIMARY WORKING COPY"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_CLASSPATH_CHANGED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("RAW CLASSPATH CHANGED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_RESOLVED_CLASSPATH_CHANGED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("RESOLVED CLASSPATH CHANGED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_PRIMARY_RESOURCE) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("PRIMARY RESOURCE"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_OPENED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("OPENED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_CLOSED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("CLOSED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_AST_AFFECTED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("AST AFFECTED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_CATEGORIES) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("CATEGORIES"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_ANNOTATIONS) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("ANNOTATIONS"); //$NON-NLS-1$
+		prev = true;
+	}
+	return prev;
+}
+/**
+ * Returns a string representation of this delta's
+ * structure suitable for debug purposes.
+ */
+public String toString() {
+	return toDebugString(0);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java
new file mode 100644
index 0000000..5f83434
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java
@@ -0,0 +1,503 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A java element delta builder creates a java element delta on
+ * a java element between the version of the java element
+ * at the time the comparator was created and the current version
+ * of the java element.
+ *
+ * It performs this operation by locally caching the contents of
+ * the java element when it is created. When the method
+ * createDeltas() is called, it creates a delta over the cached
+ * contents and the new contents.
+ */
+public class JavaElementDeltaBuilder {
+	/**
+	 * The java element handle
+	 */
+	IJavaElement javaElement;
+
+	/**
+	 * The maximum depth in the java element children we should look into
+	 */
+	int maxDepth = Integer.MAX_VALUE;
+
+	/**
+	 * The old handle to info relationships
+	 */
+	Map infos;
+	Map annotationInfos;
+
+	/**
+	 * The old position info
+	 */
+	Map oldPositions;
+
+	/**
+	 * The new position info
+	 */
+	Map newPositions;
+
+	/**
+	 * Change delta
+	 */
+	public JavaElementDelta delta = null;
+
+	/**
+	 * List of added elements
+	 */
+	HashSet added;
+
+	/**
+	 * List of removed elements
+	 */
+	HashSet removed;
+
+	/**
+	 * Doubly linked list item
+	 */
+	static class ListItem {
+		public IJavaElement previous;
+		public IJavaElement next;
+
+		public ListItem(IJavaElement previous, IJavaElement next) {
+			this.previous = previous;
+			this.next = next;
+		}
+	}
+/**
+ * Creates a java element comparator on a java element
+ * looking as deep as necessary.
+ */
+public JavaElementDeltaBuilder(IJavaElement javaElement) {
+	this.javaElement = javaElement;
+	initialize();
+	recordElementInfo(
+		javaElement,
+		(JavaModel)this.javaElement.getJavaModel(),
+		0);
+}
+/**
+ * Creates a java element comparator on a java element
+ * looking only 'maxDepth' levels deep.
+ */
+public JavaElementDeltaBuilder(IJavaElement javaElement, int maxDepth) {
+	this.javaElement = javaElement;
+	this.maxDepth = maxDepth;
+	initialize();
+	recordElementInfo(
+		javaElement,
+		(JavaModel)this.javaElement.getJavaModel(),
+		0);
+}
+/**
+ * Repairs the positioning information
+ * after an element has been added
+ */
+private void added(IJavaElement element) {
+	this.added.add(element);
+	ListItem current = getNewPosition(element);
+	ListItem previous = null, next = null;
+	if (current.previous != null)
+		previous = getNewPosition(current.previous);
+	if (current.next != null)
+		next = getNewPosition(current.next);
+	if (previous != null)
+		previous.next = current.next;
+	if (next != null)
+		next.previous = current.previous;
+}
+/**
+ * Builds the java element deltas between the old content of the compilation
+ * unit and its new content.
+ */
+public void buildDeltas() {
+	this.delta = new JavaElementDelta(this.javaElement);
+	// if building a delta on a compilation unit or below,
+	// it's a fine grained delta
+	if (this.javaElement.getElementType() >= IJavaElement.COMPILATION_UNIT) {
+		this.delta.fineGrained();
+	}
+	recordNewPositions(this.javaElement, 0);
+	findAdditions(this.javaElement, 0);
+	findDeletions();
+	findChangesInPositioning(this.javaElement, 0);
+	trimDelta(this.delta);
+	if (this.delta.getAffectedChildren().length == 0) {
+		// this is a fine grained but not children affected -> mark as content changed
+		this.delta.contentChanged();
+	}
+}
+private boolean equals(char[][][] first, char[][][] second) {
+	if (first == second)
+		return true;
+	if (first == null || second == null)
+		return false;
+	if (first.length != second.length)
+		return false;
+
+	for (int i = first.length; --i >= 0;)
+		if (!CharOperation.equals(first[i], second[i]))
+			return false;
+	return true;
+}
+/**
+ * Finds elements which have been added or changed.
+ */
+private void findAdditions(IJavaElement newElement, int depth) {
+	JavaElementInfo oldInfo = getElementInfo(newElement);
+	if (oldInfo == null && depth < this.maxDepth) {
+		this.delta.added(newElement);
+		added(newElement);
+	} else {
+		removeElementInfo(newElement);
+	}
+
+	if (depth >= this.maxDepth) {
+		// mark element as changed
+		this.delta.changed(newElement, IJavaElementDelta.F_CONTENT);
+		return;
+	}
+
+	JavaElementInfo newInfo = null;
+	try {
+		newInfo = (JavaElementInfo)((JavaElement)newElement).getElementInfo();
+	} catch (JavaModelException npe) {
+		return;
+	}
+
+	findContentChange(oldInfo, newInfo, newElement);
+
+	if (oldInfo != null && newElement instanceof IParent) {
+
+		IJavaElement[] children = newInfo.getChildren();
+		if (children != null) {
+			int length = children.length;
+			for(int i = 0; i < length; i++) {
+				findAdditions(children[i], depth + 1);
+			}
+		}
+	}
+}
+/**
+ * Looks for changed positioning of elements.
+ */
+private void findChangesInPositioning(IJavaElement element, int depth) {
+	if (depth >= this.maxDepth || this.added.contains(element) || this.removed.contains(element))
+		return;
+
+	if (!isPositionedCorrectly(element)) {
+		this.delta.changed(element, IJavaElementDelta.F_REORDER);
+	}
+
+	if (element instanceof IParent) {
+		JavaElementInfo info = null;
+		try {
+			info = (JavaElementInfo)((JavaElement)element).getElementInfo();
+		} catch (JavaModelException npe) {
+			return;
+		}
+
+		IJavaElement[] children = info.getChildren();
+		if (children != null) {
+			int length = children.length;
+			for(int i = 0; i < length; i++) {
+				findChangesInPositioning(children[i], depth + 1);
+			}
+		}
+	}
+}
+private void findAnnotationChanges(IAnnotation[] oldAnnotations, IAnnotation[] newAnnotations, IJavaElement parent) {
+	ArrayList annotationDeltas = null;
+	for (int i = 0, length = newAnnotations.length; i < length; i++) {
+		IAnnotation newAnnotation = newAnnotations[i];
+		Object oldInfo = this.annotationInfos.remove(newAnnotation);
+		if (oldInfo == null) {
+			JavaElementDelta annotationDelta = new JavaElementDelta(newAnnotation);
+			annotationDelta.added();
+			if (annotationDeltas == null) annotationDeltas = new ArrayList();
+			annotationDeltas.add(annotationDelta);
+			continue;
+		} else {
+			AnnotationInfo newInfo = null;
+			try {
+				newInfo = (AnnotationInfo) ((JavaElement) newAnnotation).getElementInfo();
+			} catch (JavaModelException npe) {
+				return;
+			}
+			if (!Util.equalArraysOrNull(((AnnotationInfo) oldInfo).members, newInfo.members)) {
+				JavaElementDelta annotationDelta = new JavaElementDelta(newAnnotation);
+				annotationDelta.changed(IJavaElementDelta.F_CONTENT);
+				if (annotationDeltas == null) annotationDeltas = new ArrayList();
+				annotationDeltas.add(annotationDelta);
+			}
+		}
+	}
+	for (int i = 0, length = oldAnnotations.length; i < length; i++) {
+		IAnnotation oldAnnotation = oldAnnotations[i];
+		if (this.annotationInfos.remove(oldAnnotation) != null) {
+			JavaElementDelta annotationDelta = new JavaElementDelta(oldAnnotation);
+			annotationDelta.removed();
+			if (annotationDeltas == null) annotationDeltas = new ArrayList();
+			annotationDeltas.add(annotationDelta);		}
+	}
+	if (annotationDeltas == null)
+		return;
+	int size = annotationDeltas.size();
+	if (size > 0) {
+		JavaElementDelta parentDelta = this.delta.changed(parent, IJavaElementDelta.F_ANNOTATIONS);
+		parentDelta.annotationDeltas = (IJavaElementDelta[]) annotationDeltas.toArray(new IJavaElementDelta[size]);
+	}
+}
+/**
+ * The elements are equivalent, but might have content changes.
+ */
+private void findContentChange(JavaElementInfo oldInfo, JavaElementInfo newInfo, IJavaElement newElement) {
+	if (oldInfo instanceof MemberElementInfo && newInfo instanceof MemberElementInfo) {
+		if (((MemberElementInfo)oldInfo).getModifiers() != ((MemberElementInfo)newInfo).getModifiers()) {
+			this.delta.changed(newElement, IJavaElementDelta.F_MODIFIERS);
+		}
+		if (oldInfo instanceof AnnotatableInfo && newInfo instanceof AnnotatableInfo) {
+			findAnnotationChanges(((AnnotatableInfo) oldInfo).annotations, ((AnnotatableInfo) newInfo).annotations, newElement);
+		}
+		if (oldInfo instanceof SourceMethodElementInfo && newInfo instanceof SourceMethodElementInfo) {
+			SourceMethodElementInfo oldSourceMethodInfo = (SourceMethodElementInfo)oldInfo;
+			SourceMethodElementInfo newSourceMethodInfo = (SourceMethodElementInfo)newInfo;
+			if (!CharOperation.equals(oldSourceMethodInfo.getReturnTypeName(), newSourceMethodInfo.getReturnTypeName())
+					|| !CharOperation.equals(oldSourceMethodInfo.getTypeParameterNames(), newSourceMethodInfo.getTypeParameterNames())
+					|| !equals(oldSourceMethodInfo.getTypeParameterBounds(), newSourceMethodInfo.getTypeParameterBounds())) {
+				this.delta.changed(newElement, IJavaElementDelta.F_CONTENT);
+			}
+		} else if (oldInfo instanceof SourceFieldElementInfo && newInfo instanceof SourceFieldElementInfo) {
+			if (!CharOperation.equals(
+					((SourceFieldElementInfo)oldInfo).getTypeName(),
+					((SourceFieldElementInfo)newInfo).getTypeName())) {
+				this.delta.changed(newElement, IJavaElementDelta.F_CONTENT);
+			}
+		} else if (oldInfo instanceof SourceTypeElementInfo && newInfo instanceof SourceTypeElementInfo) {
+			SourceTypeElementInfo oldSourceTypeInfo = (SourceTypeElementInfo)oldInfo;
+			SourceTypeElementInfo newSourceTypeInfo = (SourceTypeElementInfo)newInfo;
+			if (!CharOperation.equals(oldSourceTypeInfo.getSuperclassName(), newSourceTypeInfo.getSuperclassName())
+					|| !CharOperation.equals(oldSourceTypeInfo.getInterfaceNames(), newSourceTypeInfo.getInterfaceNames())) {
+				this.delta.changed(newElement, IJavaElementDelta.F_SUPER_TYPES);
+			}
+			if (!CharOperation.equals(oldSourceTypeInfo.getTypeParameterNames(), newSourceTypeInfo.getTypeParameterNames())
+					|| !equals(oldSourceTypeInfo.getTypeParameterBounds(), newSourceTypeInfo.getTypeParameterBounds())) {
+				this.delta.changed(newElement, IJavaElementDelta.F_CONTENT);
+			}
+			HashMap oldTypeCategories = oldSourceTypeInfo.categories;
+			HashMap newTypeCategories = newSourceTypeInfo.categories;
+			if (oldTypeCategories != null) {
+				// take the union of old and new categories elements (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=125675)
+				Set elements;
+				if (newTypeCategories != null) {
+					elements = new HashSet(oldTypeCategories.keySet());
+					elements.addAll(newTypeCategories.keySet());
+				} else
+					elements = oldTypeCategories.keySet();
+				Iterator iterator = elements.iterator();
+				while (iterator.hasNext()) {
+					IJavaElement element = (IJavaElement) iterator.next();
+					String[] oldCategories = (String[]) oldTypeCategories.get(element);
+					String[] newCategories = newTypeCategories == null ? null : (String[]) newTypeCategories.get(element);
+					if (!Util.equalArraysOrNull(oldCategories, newCategories)) {
+						this.delta.changed(element, IJavaElementDelta.F_CATEGORIES);
+					}
+				}
+			} else if (newTypeCategories != null) {
+				Iterator elements = newTypeCategories.keySet().iterator();
+				while (elements.hasNext()) {
+					IJavaElement element = (IJavaElement) elements.next();
+					this.delta.changed(element, IJavaElementDelta.F_CATEGORIES); // all categories for this element were removed
+				}
+			}
+		}
+	}
+}
+/**
+ * Adds removed deltas for any handles left in the table
+ */
+private void findDeletions() {
+	Iterator iter = this.infos.keySet().iterator();
+	while(iter.hasNext()) {
+		IJavaElement element = (IJavaElement)iter.next();
+		this.delta.removed(element);
+		removed(element);
+	}
+}
+private JavaElementInfo getElementInfo(IJavaElement element) {
+	return (JavaElementInfo)this.infos.get(element);
+}
+private ListItem getNewPosition(IJavaElement element) {
+	return (ListItem)this.newPositions.get(element);
+}
+private ListItem getOldPosition(IJavaElement element) {
+	return (ListItem)this.oldPositions.get(element);
+}
+private void initialize() {
+	this.infos = new HashMap(20);
+	this.oldPositions = new HashMap(20);
+	this.newPositions = new HashMap(20);
+	this.oldPositions.put(this.javaElement, new ListItem(null, null));
+	this.newPositions.put(this.javaElement, new ListItem(null, null));
+	this.added = new HashSet(5);
+	this.removed = new HashSet(5);
+}
+/**
+ * Inserts position information for the elements into the new or old positions table
+ */
+private void insertPositions(IJavaElement[] elements, boolean isNew) {
+	int length = elements.length;
+	IJavaElement previous = null, current = null, next = (length > 0) ? elements[0] : null;
+	for(int i = 0; i < length; i++) {
+		previous = current;
+		current = next;
+		next = (i + 1 < length) ? elements[i + 1] : null;
+		if (isNew) {
+			this.newPositions.put(current, new ListItem(previous, next));
+		} else {
+			this.oldPositions.put(current, new ListItem(previous, next));
+		}
+	}
+}
+/**
+ * Returns whether the elements position has not changed.
+ */
+private boolean isPositionedCorrectly(IJavaElement element) {
+	ListItem oldListItem = getOldPosition(element);
+	if (oldListItem == null) return false;
+
+	ListItem newListItem = getNewPosition(element);
+	if (newListItem == null) return false;
+
+	IJavaElement oldPrevious = oldListItem.previous;
+	IJavaElement newPrevious = newListItem.previous;
+	if (oldPrevious == null) {
+		return newPrevious == null;
+	} else {
+		return oldPrevious.equals(newPrevious);
+	}
+}
+/**
+ * Records this elements info, and attempts
+ * to record the info for the children.
+ */
+private void recordElementInfo(IJavaElement element, JavaModel model, int depth) {
+	if (depth >= this.maxDepth) {
+		return;
+	}
+	JavaElementInfo info = (JavaElementInfo)JavaModelManager.getJavaModelManager().getInfo(element);
+	if (info == null) // no longer in the java model.
+		return;
+	this.infos.put(element, info);
+
+	if (element instanceof IParent) {
+		IJavaElement[] children = info.getChildren();
+		if (children != null) {
+			insertPositions(children, false);
+			for(int i = 0, length = children.length; i < length; i++)
+				recordElementInfo(children[i], model, depth + 1);
+		}
+	}
+	IAnnotation[] annotations = null;
+	if (info instanceof AnnotatableInfo)
+		annotations = ((AnnotatableInfo) info).annotations;
+	if (annotations != null) {
+		if (this.annotationInfos == null)
+			this.annotationInfos = new HashMap();
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		for (int i = 0, length = annotations.length; i < length; i++) {
+			this.annotationInfos.put(annotations[i], manager.getInfo(annotations[i]));
+		}
+	}
+}
+/**
+ * Fills the newPositions hashtable with the new position information
+ */
+private void recordNewPositions(IJavaElement newElement, int depth) {
+	if (depth < this.maxDepth && newElement instanceof IParent) {
+		JavaElementInfo info = null;
+		try {
+			info = (JavaElementInfo)((JavaElement)newElement).getElementInfo();
+		} catch (JavaModelException npe) {
+			return;
+		}
+
+		IJavaElement[] children = info.getChildren();
+		if (children != null) {
+			insertPositions(children, true);
+			for(int i = 0, length = children.length; i < length; i++) {
+				recordNewPositions(children[i], depth + 1);
+			}
+		}
+	}
+}
+/**
+ * Repairs the positioning information
+ * after an element has been removed
+ */
+private void removed(IJavaElement element) {
+	this.removed.add(element);
+	ListItem current = getOldPosition(element);
+	ListItem previous = null, next = null;
+	if (current.previous != null)
+		previous = getOldPosition(current.previous);
+	if (current.next != null)
+		next = getOldPosition(current.next);
+	if (previous != null)
+		previous.next = current.next;
+	if (next != null)
+		next.previous = current.previous;
+
+}
+private void removeElementInfo(IJavaElement element) {
+	this.infos.remove(element);
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("Built delta:\n"); //$NON-NLS-1$
+	buffer.append(this.delta == null ? "<null>" : this.delta.toString()); //$NON-NLS-1$
+	return buffer.toString();
+}
+/**
+ * Trims deletion deltas to only report the highest level of deletion
+ */
+private void trimDelta(JavaElementDelta elementDelta) {
+	if (elementDelta.getKind() == IJavaElementDelta.REMOVED) {
+		IJavaElementDelta[] children = elementDelta.getAffectedChildren();
+		for(int i = 0, length = children.length; i < length; i++) {
+			elementDelta.removeAffectedChild((JavaElementDelta)children[i]);
+		}
+	} else {
+		IJavaElementDelta[] children = elementDelta.getAffectedChildren();
+		for(int i = 0, length = children.length; i < length; i++) {
+			trimDelta((JavaElementDelta)children[i]);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java
new file mode 100644
index 0000000..0250d5d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * Holds cached structure and properties for a Java element.
+ * Subclassed to carry properties for specific kinds of elements.
+ */
+public class JavaElementInfo implements Cloneable {
+
+	/**
+	 * Shared empty collection used for efficiency.
+	 */
+	static Object[] NO_NON_JAVA_RESOURCES = new Object[] {};
+
+	public Object clone() {
+		try {
+			return super.clone();
+		}
+		catch (CloneNotSupportedException e) {
+			throw new Error();
+		}
+	}
+	public IJavaElement[] getChildren() {
+		return JavaElement.NO_ELEMENTS;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java
new file mode 100644
index 0000000..a1bf00b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+
+/**
+ * @see IJavaElementRequestor
+ */
+
+public class JavaElementRequestor implements IJavaElementRequestor {
+	/**
+	 * True if this requestor no longer wants to receive
+	 * results from its <code>IRequestorNameLookup</code>.
+	 */
+	protected boolean canceled= false;
+
+	/**
+	 * A collection of the resulting fields, or <code>null</code>
+	 * if no field results have been received.
+	 */
+	protected ArrayList fields= null;
+
+	/**
+	 * A collection of the resulting initializers, or <code>null</code>
+	 * if no initializer results have been received.
+	 */
+	protected ArrayList initializers= null;
+
+	/**
+	 * A collection of the resulting member types, or <code>null</code>
+	 * if no member type results have been received.
+	 */
+	protected ArrayList memberTypes= null;
+
+	/**
+	 * A collection of the resulting methods, or <code>null</code>
+	 * if no method results have been received.
+	 */
+	protected ArrayList methods= null;
+
+	/**
+	 * A collection of the resulting package fragments, or <code>null</code>
+	 * if no package fragment results have been received.
+	 */
+	protected ArrayList packageFragments= null;
+
+	/**
+	 * A collection of the resulting types, or <code>null</code>
+	 * if no type results have been received.
+	 */
+	protected ArrayList types= null;
+
+	/**
+	 * Empty arrays used for efficiency
+	 */
+	protected static final IField[] EMPTY_FIELD_ARRAY= new IField[0];
+	protected static final IInitializer[] EMPTY_INITIALIZER_ARRAY= new IInitializer[0];
+	protected static final IType[] EMPTY_TYPE_ARRAY= new IType[0];
+	protected static final IPackageFragment[] EMPTY_PACKAGE_FRAGMENT_ARRAY= new IPackageFragment[0];
+	protected static final IMethod[] EMPTY_METHOD_ARRAY= new IMethod[0];
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptField(IField field) {
+	if (this.fields == null) {
+		this.fields= new ArrayList();
+	}
+	this.fields.add(field);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptInitializer(IInitializer initializer) {
+	if (this.initializers == null) {
+		this.initializers= new ArrayList();
+	}
+	this.initializers.add(initializer);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptMemberType(IType type) {
+	if (this.memberTypes == null) {
+		this.memberTypes= new ArrayList();
+	}
+	this.memberTypes.add(type);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptMethod(IMethod method) {
+	if (this.methods == null) {
+		this.methods = new ArrayList();
+	}
+	this.methods.add(method);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptPackageFragment(IPackageFragment packageFragment) {
+	if (this.packageFragments== null) {
+		this.packageFragments= new ArrayList();
+	}
+	this.packageFragments.add(packageFragment);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptType(IType type) {
+	if (this.types == null) {
+		this.types= new ArrayList();
+	}
+	this.types.add(type);
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IField[] getFields() {
+	if (this.fields == null) {
+		return EMPTY_FIELD_ARRAY;
+	}
+	int size = this.fields.size();
+	IField[] results = new IField[size];
+	this.fields.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IInitializer[] getInitializers() {
+	if (this.initializers == null) {
+		return EMPTY_INITIALIZER_ARRAY;
+	}
+	int size = this.initializers.size();
+	IInitializer[] results = new IInitializer[size];
+	this.initializers.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IType[] getMemberTypes() {
+	if (this.memberTypes == null) {
+		return EMPTY_TYPE_ARRAY;
+	}
+	int size = this.memberTypes.size();
+	IType[] results = new IType[size];
+	this.memberTypes.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IMethod[] getMethods() {
+	if (this.methods == null) {
+		return EMPTY_METHOD_ARRAY;
+	}
+	int size = this.methods.size();
+	IMethod[] results = new IMethod[size];
+	this.methods.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IPackageFragment[] getPackageFragments() {
+	if (this.packageFragments== null) {
+		return EMPTY_PACKAGE_FRAGMENT_ARRAY;
+	}
+	int size = this.packageFragments.size();
+	IPackageFragment[] results = new IPackageFragment[size];
+	this.packageFragments.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public IType[] getTypes() {
+	if (this.types== null) {
+		return EMPTY_TYPE_ARRAY;
+	}
+	int size = this.types.size();
+	IType[] results = new IType[size];
+	this.types.toArray(results);
+	return results;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public boolean isCanceled() {
+	return this.canceled;
+}
+/**
+ * Reset the state of this requestor.
+ */
+public void reset() {
+	this.canceled = false;
+	this.fields = null;
+	this.initializers = null;
+	this.memberTypes = null;
+	this.methods = null;
+	this.packageFragments = null;
+	this.types = null;
+}
+/**
+ * Sets the #isCanceled state of this requestor to true or false.
+ */
+public void setCanceled(boolean b) {
+	this.canceled= b;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
new file mode 100644
index 0000000..d2e6aba
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * Implementation of {@link IJavaModel}. The Java Model maintains a cache of active
+ * {@link IJavaProject}s in a workspace. A Java Model is specific to a workspace.
+ * To retrieve a workspace's model, use the
+ * {@link IJavaElement#getJavaModel() #getJavaModel()} method.
+ *
+ * @see IJavaModel
+ */
+public class JavaModel extends Openable implements IJavaModel {
+
+	/**
+	 * A set of java.io.Files used as a cache of external jars that
+	 * are known to be existing.
+	 * Note this cache is kept for the whole session.
+	 */
+	public static HashSet existingExternalFiles = new HashSet();
+
+	/**
+	 * A set of external files ({@link #existingExternalFiles}) which have
+	 * been confirmed as file (i.e. which returns true to {@link java.io.File#isFile()}.
+	 * Note this cache is kept for the whole session.
+	 */
+	public static HashSet existingExternalConfirmedFiles = new HashSet();
+
+/**
+ * Constructs a new Java Model on the given workspace.
+ * Note that only one instance of JavaModel handle should ever be created.
+ * One should only indirect through JavaModelManager#getJavaModel() to get
+ * access to it.
+ *
+ * @exception Error if called more than once
+ */
+protected JavaModel() throws Error {
+	super(null);
+}
+protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource)	/*throws JavaModelException*/ {
+
+	// determine my children
+	IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+	int length = projects.length;
+	IJavaElement[] children = new IJavaElement[length];
+	int index = 0;
+	for (int i = 0; i < length; i++) {
+		IProject project = projects[i];
+		if (JavaProject.hasJavaNature(project)) {
+			children[index++] = getJavaProject(project);
+		}
+	}
+	if (index < length)
+		System.arraycopy(children, 0, children = new IJavaElement[index], 0, index);
+	info.setChildren(children);
+
+	newElements.put(this, info);
+
+	return true;
+}
+/*
+ * @see IJavaModel
+ */
+public boolean contains(IResource resource) {
+	switch (resource.getType()) {
+		case IResource.ROOT:
+		case IResource.PROJECT:
+			return true;
+	}
+	// file or folder
+	IJavaProject[] projects;
+	try {
+		projects = getJavaProjects();
+	} catch (JavaModelException e) {
+		return false;
+	}
+	for (int i = 0, length = projects.length; i < length; i++) {
+		JavaProject project = (JavaProject)projects[i];
+		if (!project.contains(resource)) {
+			return false;
+		}
+	}
+	return true;
+}
+/**
+ * @see IJavaModel
+ */
+public void copy(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+		runOperation(new CopyResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+	} else {
+		runOperation(new CopyElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+	}
+}
+/**
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return new JavaModelInfo();
+}
+
+/**
+ * @see IJavaModel
+ */
+public void delete(IJavaElement[] elements, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+		new DeleteResourceElementsOperation(elements, force).runOperation(monitor);
+	} else {
+		new DeleteElementsOperation(elements, force).runOperation(monitor);
+	}
+}
+public boolean equals(Object o) {
+	if (!(o instanceof JavaModel)) return false;
+	return super.equals(o);
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return JAVA_MODEL;
+}
+/**
+ * Flushes the cache of external files known to be existing.
+ */
+public static void flushExternalFileCache() {
+	existingExternalFiles = new HashSet();
+	existingExternalConfirmedFiles = new HashSet();
+}
+
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+	switch (token.charAt(0)) {
+		case JEM_JAVAPROJECT:
+			if (!memento.hasMoreTokens()) return this;
+			String projectName = memento.nextToken();
+			JavaElement project = (JavaElement)getJavaProject(projectName);
+			return project.getHandleFromMemento(memento, owner);
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	buff.append(getElementName());
+}
+/**
+ * Returns the <code>char</code> that marks the start of this handles
+ * contribution to a memento.
+ */
+protected char getHandleMementoDelimiter(){
+	Assert.isTrue(false, "Should not be called"); //$NON-NLS-1$
+	return 0;
+}
+/**
+ * @see IJavaModel
+ */
+public IJavaProject getJavaProject(String projectName) {
+	return new JavaProject(ResourcesPlugin.getWorkspace().getRoot().getProject(projectName), this);
+}
+/**
+ * Returns the active Java project associated with the specified
+ * resource, or <code>null</code> if no Java project yet exists
+ * for the resource.
+ *
+ * @exception IllegalArgumentException if the given resource
+ * is not one of an IProject, IFolder, or IFile.
+ */
+public IJavaProject getJavaProject(IResource resource) {
+	switch(resource.getType()){
+		case IResource.FOLDER:
+			return new JavaProject(((IFolder)resource).getProject(), this);
+		case IResource.FILE:
+			return new JavaProject(((IFile)resource).getProject(), this);
+		case IResource.PROJECT:
+			return new JavaProject((IProject)resource, this);
+		default:
+			throw new IllegalArgumentException(Messages.element_invalidResourceForProject);
+	}
+}
+/**
+ * @see IJavaModel
+ */
+public IJavaProject[] getJavaProjects() throws JavaModelException {
+	ArrayList list = getChildrenOfType(JAVA_PROJECT);
+	IJavaProject[] array= new IJavaProject[list.size()];
+	list.toArray(array);
+	return array;
+
+}
+/**
+ * @see IJavaModel
+ */
+public Object[] getNonJavaResources() throws JavaModelException {
+		return ((JavaModelInfo) getElementInfo()).getNonJavaResources();
+}
+
+/*
+ * @see IJavaElement
+ */
+public IPath getPath() {
+	return Path.ROOT;
+}
+/*
+ * @see IJavaElement
+ */
+public IResource resource(PackageFragmentRoot root) {
+	return ResourcesPlugin.getWorkspace().getRoot();
+}
+/**
+ * @see IOpenable
+ */
+public IResource getUnderlyingResource() {
+	return null;
+}
+/**
+ * Returns the workbench associated with this object.
+ */
+public IWorkspace getWorkspace() {
+	return ResourcesPlugin.getWorkspace();
+}
+
+/**
+ * @see IJavaModel
+ */
+public void move(IJavaElement[] elements, IJavaElement[] containers, IJavaElement[] siblings, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+		runOperation(new MoveResourceElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+	} else {
+		runOperation(new MoveElementsOperation(elements, containers, force), elements, siblings, renamings, monitor);
+	}
+}
+
+/**
+ * @see IJavaModel#refreshExternalArchives(IJavaElement[], IProgressMonitor)
+ */
+public void refreshExternalArchives(IJavaElement[] elementsScope, IProgressMonitor monitor) throws JavaModelException {
+	if (elementsScope == null){
+		elementsScope = new IJavaElement[] { this };
+	}
+	JavaModelManager.getJavaModelManager().getDeltaProcessor().checkExternalArchiveChanges(elementsScope, monitor);
+}
+
+/**
+ * @see IJavaModel
+ */
+public void rename(IJavaElement[] elements, IJavaElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	MultiOperation op;
+	if (elements != null && elements.length > 0 && elements[0] != null && elements[0].getElementType() < IJavaElement.TYPE) {
+		op = new RenameResourceElementsOperation(elements, destinations, renamings, force);
+	} else {
+		op = new RenameElementsOperation(elements, destinations, renamings, force);
+	}
+
+	op.runOperation(monitor);
+}
+/**
+ * Configures and runs the <code>MultiOperation</code>.
+ */
+protected void runOperation(MultiOperation op, IJavaElement[] elements, IJavaElement[] siblings, String[] renamings, IProgressMonitor monitor) throws JavaModelException {
+	op.setRenamings(renamings);
+	if (siblings != null) {
+		for (int i = 0; i < elements.length; i++) {
+			op.setInsertBefore(elements[i], siblings[i]);
+		}
+	}
+	op.runOperation(monitor);
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	buffer.append("Java Model"); //$NON-NLS-1$
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	}
+}
+
+/**
+ * Helper method - returns the targeted item (IResource if internal or java.io.File if external),
+ * or null if unbound
+ * Internal items must be referred to using container relative paths.
+ */
+public static Object getTarget(IPath path, boolean checkResourceExistence) {
+	Object target = getWorkspaceTarget(path); // Implicitly checks resource existence
+	if (target != null)
+		return target;
+	return getExternalTarget(path, checkResourceExistence);
+}
+public static IResource getWorkspaceTarget(IPath path) {
+	if (path == null || path.getDevice() != null)
+		return null;
+	IWorkspace workspace = ResourcesPlugin.getWorkspace();
+	if (workspace == null)
+		return null;
+	return workspace.getRoot().findMember(path);
+}
+public static Object getExternalTarget(IPath path, boolean checkResourceExistence) {
+	if (path == null)
+		return null;
+	ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
+	Object linkedFolder = externalFoldersManager.getFolder(path);
+	if (linkedFolder != null) {
+		if (checkResourceExistence) {
+			// check if external folder is present
+			File externalFile = new File(path.toOSString());
+			if (!externalFile.isDirectory()) {
+				return null;
+			}
+		}
+		return linkedFolder;
+	}
+	File externalFile = new File(path.toOSString());
+	if (!checkResourceExistence) {
+		return externalFile;
+	} else if (existingExternalFilesContains(externalFile)) {
+		return externalFile;
+	} else {
+		if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+			System.out.println("(" + Thread.currentThread() + ") [JavaModel.getTarget(...)] Checking existence of " + path.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		if (externalFile.isFile()) { // isFile() checks for existence (it returns false if a directory)
+			// cache external file
+			existingExternalFilesAdd(externalFile);
+			return externalFile;
+		}
+	}
+	return null;
+}
+private synchronized static void existingExternalFilesAdd(File externalFile) {
+	existingExternalFiles.add(externalFile);
+}
+private synchronized static boolean existingExternalFilesContains(File externalFile) {
+	return existingExternalFiles.contains(externalFile);
+}
+
+/**
+ * Helper method - returns whether an object is afile (i.e. which returns true to {@link java.io.File#isFile()}.
+ */
+public static boolean isFile(Object target) {
+	return getFile(target) != null;
+}
+
+/**
+ * Helper method - returns the file item (i.e. which returns true to {@link java.io.File#isFile()},
+ * or null if unbound
+ */
+public static synchronized File getFile(Object target) {
+	if (existingExternalConfirmedFiles.contains(target))
+		return (File) target;
+	if (target instanceof File) {
+		File f = (File) target;
+		if (f.isFile()) {
+			existingExternalConfirmedFiles.add(f);
+			return f;
+		}
+	}
+
+	return null;
+}
+
+protected IStatus validateExistence(IResource underlyingResource) {
+	// Java model always exists
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java
new file mode 100644
index 0000000..5997bc3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Terry Parker <tparker@google.com> (Google Inc.)  https://bugs.eclipse.org/365499
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.core.util.LRUCache;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * The cache of java elements to their respective info.
+ */
+public class JavaModelCache {
+	public static boolean VERBOSE = false;
+
+	public static final int DEFAULT_PROJECT_SIZE = 5;  // average 25552 bytes per project.
+	public static final int DEFAULT_ROOT_SIZE = 50; // average 2590 bytes per root -> maximum size : 25900*BASE_VALUE bytes
+	public static final int DEFAULT_PKG_SIZE = 500; // average 1782 bytes per pkg -> maximum size : 178200*BASE_VALUE bytes
+	public static final int DEFAULT_OPENABLE_SIZE = 250; // average 6629 bytes per openable (includes children) -> maximum size : 662900*BASE_VALUE bytes
+	public static final int DEFAULT_CHILDREN_SIZE = 250*20; // average 20 children per openable
+	public static final String RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.ratio"; //$NON-NLS-1$
+	public static final String JAR_TYPE_RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.jartyperatio"; //$NON-NLS-1$
+	
+	public static final Object NON_EXISTING_JAR_TYPE_INFO = new Object();
+
+	/*
+	 * The memory ratio that should be applied to the above constants.
+	 */
+	protected double memoryRatio = -1;
+
+	/**
+	 * Active Java Model Info
+	 */
+	protected Object modelInfo;
+
+	/**
+	 * Cache of open projects.
+	 */
+	protected HashMap projectCache;
+
+	/**
+	 * Cache of open package fragment roots.
+	 */
+	protected ElementCache rootCache;
+
+	/**
+	 * Cache of open package fragments
+	 */
+	protected ElementCache pkgCache;
+
+	/**
+	 * Cache of open compilation unit and class files
+	 */
+	protected ElementCache openableCache;
+
+	/**
+	 * Cache of open children of openable Java Model Java elements
+	 */
+	protected Map childrenCache;
+
+	/*
+	 * Cache of open binary type (inside a jar) that have a non-open parent
+	 */
+	protected LRUCache jarTypeCache;
+
+public JavaModelCache() {
+	// set the size of the caches as a function of the maximum amount of memory available
+	double ratio = getMemoryRatio();
+	// adjust the size of the openable cache using the RATIO_PROPERTY property
+	double openableRatio = getOpenableRatio();
+	this.projectCache = new HashMap(DEFAULT_PROJECT_SIZE); // NB: Don't use a LRUCache for projects as they are constantly reopened (e.g. during delta processing)
+	if (VERBOSE) {
+		this.rootCache = new VerboseElementCache((int) (DEFAULT_ROOT_SIZE * ratio), "Root cache"); //$NON-NLS-1$
+		this.pkgCache = new VerboseElementCache((int) (DEFAULT_PKG_SIZE * ratio), "Package cache"); //$NON-NLS-1$
+		this.openableCache = new VerboseElementCache((int) (DEFAULT_OPENABLE_SIZE * ratio * openableRatio), "Openable cache"); //$NON-NLS-1$
+	} else {
+		this.rootCache = new ElementCache((int) (DEFAULT_ROOT_SIZE * ratio));
+		this.pkgCache = new ElementCache((int) (DEFAULT_PKG_SIZE * ratio));
+		this.openableCache = new ElementCache((int) (DEFAULT_OPENABLE_SIZE * ratio * openableRatio));
+	}
+	this.childrenCache = new HashMap((int) (DEFAULT_CHILDREN_SIZE * ratio * openableRatio));
+	resetJarTypeCache();
+}
+
+private double getOpenableRatio() {
+	return getRatioForProperty(RATIO_PROPERTY);
+}
+
+private double getJarTypeRatio() {
+	return getRatioForProperty(JAR_TYPE_RATIO_PROPERTY);
+}
+
+private double getRatioForProperty(String propertyName) {
+	String property = System.getProperty(propertyName);
+	if (property != null) {
+		try {
+			return Double.parseDouble(property);
+		} catch (NumberFormatException e) {
+			// ignore
+			Util.log(e, "Could not parse value for " + propertyName + ": " + property); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	return 1.0;
+}
+
+/**
+ *  Returns the info for the element.
+ */
+public Object getInfo(IJavaElement element) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			return this.modelInfo;
+		case IJavaElement.JAVA_PROJECT:
+			return this.projectCache.get(element);
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			return this.rootCache.get(element);
+		case IJavaElement.PACKAGE_FRAGMENT:
+			return this.pkgCache.get(element);
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			return this.openableCache.get(element);
+		case IJavaElement.TYPE:
+			Object result = this.jarTypeCache.get(element);
+			if (result != null)
+				return result;
+			else
+				return this.childrenCache.get(element);
+		default:
+			return this.childrenCache.get(element);
+	}
+}
+
+/*
+ *  Returns the existing element that is equal to the given element if present in the cache.
+ *  Returns the given element otherwise.
+ */
+public IJavaElement getExistingElement(IJavaElement element) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			return element;
+		case IJavaElement.JAVA_PROJECT:
+			return element; // projectCache is a Hashtable and Hashtables don't support getKey(...)
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			return (IJavaElement) this.rootCache.getKey(element);
+		case IJavaElement.PACKAGE_FRAGMENT:
+			return (IJavaElement) this.pkgCache.getKey(element);
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			return (IJavaElement) this.openableCache.getKey(element);
+		case IJavaElement.TYPE:
+			return element; // jarTypeCache or childrenCache are Hashtables and Hashtables don't support getKey(...)
+		default:
+			return element; // childrenCache is a Hashtable and Hashtables don't support getKey(...)
+	}
+}
+
+protected double getMemoryRatio() {
+	if ((int) this.memoryRatio == -1) {
+		long maxMemory = Runtime.getRuntime().maxMemory();
+		// if max memory is infinite, set the ratio to 4d which corresponds to the 256MB that Eclipse defaults to
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=111299)
+		this.memoryRatio = maxMemory == Long.MAX_VALUE ? 4d : ((double) maxMemory) / (64 * 0x100000); // 64MB is the base memory for most JVM
+	}
+	return this.memoryRatio;
+}
+
+/**
+ *  Returns the info for this element without
+ *  disturbing the cache ordering.
+ */
+protected Object peekAtInfo(IJavaElement element) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			return this.modelInfo;
+		case IJavaElement.JAVA_PROJECT:
+			return this.projectCache.get(element);
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			return this.rootCache.peek(element);
+		case IJavaElement.PACKAGE_FRAGMENT:
+			return this.pkgCache.peek(element);
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			return this.openableCache.peek(element);
+		case IJavaElement.TYPE:
+			Object result = this.jarTypeCache.peek(element);
+			if (result != null)
+				return result;
+			else
+				return this.childrenCache.get(element);
+		default:
+			return this.childrenCache.get(element);
+	}
+}
+
+/**
+ * Remember the info for the element.
+ */
+protected void putInfo(IJavaElement element, Object info) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			this.modelInfo = info;
+			break;
+		case IJavaElement.JAVA_PROJECT:
+			this.projectCache.put(element, info);
+			this.rootCache.ensureSpaceLimit(info, element);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			this.rootCache.put(element, info);
+			this.pkgCache.ensureSpaceLimit(info, element);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT:
+			this.pkgCache.put(element, info);
+			this.openableCache.ensureSpaceLimit(info, element);
+			break;
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			this.openableCache.put(element, info);
+			break;
+		default:
+			this.childrenCache.put(element, info);
+	}
+}
+/**
+ * Removes the info of the element from the cache.
+ */
+protected void removeInfo(JavaElement element) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			this.modelInfo = null;
+			break;
+		case IJavaElement.JAVA_PROJECT:
+			this.projectCache.remove(element);
+			this.rootCache.resetSpaceLimit((int) (DEFAULT_ROOT_SIZE * getMemoryRatio()), element);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			this.rootCache.remove(element);
+			this.pkgCache.resetSpaceLimit((int) (DEFAULT_PKG_SIZE * getMemoryRatio()), element);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT:
+			this.pkgCache.remove(element);
+			this.openableCache.resetSpaceLimit((int) (DEFAULT_OPENABLE_SIZE * getMemoryRatio() * getOpenableRatio()), element);
+			break;
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			this.openableCache.remove(element);
+			break;
+		default:
+			this.childrenCache.remove(element);
+	}
+}
+protected void resetJarTypeCache() {
+	this.jarTypeCache = new LRUCache((int) (DEFAULT_OPENABLE_SIZE * getMemoryRatio() * getJarTypeRatio()));
+}
+public String toString() {
+	return toStringFillingRation(""); //$NON-NLS-1$
+}
+public String toStringFillingRation(String prefix) {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(prefix);
+	buffer.append("Project cache: "); //$NON-NLS-1$
+	buffer.append(this.projectCache.size());
+	buffer.append(" projects\n"); //$NON-NLS-1$
+	buffer.append(prefix);
+	buffer.append(this.rootCache.toStringFillingRation("Root cache")); //$NON-NLS-1$
+	buffer.append('\n');
+	buffer.append(prefix);
+	buffer.append(this.pkgCache.toStringFillingRation("Package cache")); //$NON-NLS-1$
+	buffer.append('\n');
+	buffer.append(prefix);
+	buffer.append(this.openableCache.toStringFillingRation("Openable cache")); //$NON-NLS-1$
+	buffer.append('\n');
+	buffer.append(prefix);
+	buffer.append(this.jarTypeCache.toStringFillingRation("Jar type cache")); //$NON-NLS-1$
+	buffer.append('\n');
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java
new file mode 100644
index 0000000..3f020e2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+/**
+ * Implementation of IJavaModel. A Java Model is specific to a
+ * workspace.
+ *
+ * @see org.eclipse.jdt.core.IJavaModel
+ */
+public class JavaModelInfo extends OpenableElementInfo {
+
+	/**
+	 * A array with all the non-java projects contained by this model
+	 */
+	Object[] nonJavaResources;
+
+/**
+ * Compute the non-java resources contained in this java project.
+ */
+private Object[] computeNonJavaResources() {
+	IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+	int length = projects.length;
+	Object[] resources = null;
+	int index = 0;
+	for (int i = 0; i < length; i++) {
+		IProject project = projects[i];
+		if (!JavaProject.hasJavaNature(project)) {
+			if (resources == null) {
+				resources = new Object[length];
+			}
+			resources[index++] = project;
+		}
+	}
+	if (index == 0) return NO_NON_JAVA_RESOURCES;
+	if (index < length) {
+		System.arraycopy(resources, 0, resources = new Object[index], 0, index);
+	}
+	return resources;
+}
+
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+Object[] getNonJavaResources() {
+
+	if (this.nonJavaResources == null) {
+		this.nonJavaResources = computeNonJavaResources();
+	}
+	return this.nonJavaResources;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
new file mode 100644
index 0000000..caf1999
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -0,0 +1,5172 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Theodora Yeung (tyeung@bea.com) - ensure that JarPackageFragmentRoot make it into cache
+ *                                                           before its contents
+ *                                                           (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=102422)
+ *     Stephan Herrmann - Contribution for Bug 346010 - [model] strange initialization dependency in OptionTests
+ *     Terry Parker <tparker@google.com> - DeltaProcessor misses state changes in archive files, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=357425
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.*;
+import java.net.URI;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEvent;
+import org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeChangeListener;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.CompilationParticipant;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.core.dom.SourceRangeVerifier;
+import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor;
+import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+import org.eclipse.jdt.internal.core.util.LRUCache;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.WeakHashSet;
+import org.eclipse.jdt.internal.core.util.WeakHashSetOfCharArray;
+import org.eclipse.jdt.internal.core.util.LRUCache.Stats;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter;
+import org.osgi.service.prefs.BackingStoreException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * The <code>JavaModelManager</code> manages instances of <code>IJavaModel</code>.
+ * <code>IElementChangedListener</code>s register with the <code>JavaModelManager</code>,
+ * and receive <code>ElementChangedEvent</code>s for all <code>IJavaModel</code>s.
+ * <p>
+ * The single instance of <code>JavaModelManager</code> is available from
+ * the static method <code>JavaModelManager.getJavaModelManager()</code>.
+ */
+public class JavaModelManager implements ISaveParticipant, IContentTypeChangeListener {
+
+	private static final String NON_CHAINING_JARS_CACHE = "nonChainingJarsCache"; //$NON-NLS-1$
+	private static final String INVALID_ARCHIVES_CACHE = "invalidArchivesCache";  //$NON-NLS-1$
+
+	/**
+	 * Define a zip cache object.
+	 */
+	static class ZipCache {
+		private Map map;
+		Object owner;
+
+		ZipCache(Object owner) {
+			this.map = new HashMap();
+			this.owner = owner;
+		}
+
+		public void flush() {
+			Thread currentThread = Thread.currentThread();
+			Iterator iterator = this.map.values().iterator();
+			while (iterator.hasNext()) {
+				try {
+					ZipFile zipFile = (ZipFile)iterator.next();
+					if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+						System.out.println("(" + currentThread + ") [JavaModelManager.flushZipFiles()] Closing ZipFile on " +zipFile.getName()); //$NON-NLS-1$//$NON-NLS-2$
+					}
+					zipFile.close();
+				} catch (IOException e) {
+					// problem occured closing zip file: cannot do much more
+				}
+			}
+		}
+
+		public ZipFile getCache(IPath path) {
+			return (ZipFile) this.map.get(path);
+		}
+
+		public void setCache(IPath path, ZipFile zipFile) {
+			this.map.put(path, zipFile);
+		}
+	}
+	/**
+	 * Unique handle onto the JavaModel
+	 */
+	final JavaModel javaModel = new JavaModel();
+
+	/**
+	 * Classpath variables pool
+	 */
+	public HashMap variables = new HashMap(5);
+	public HashSet variablesWithInitializer = new HashSet(5);
+	public HashMap deprecatedVariables = new HashMap(5);
+	public HashSet readOnlyVariables = new HashSet(5);
+	public HashMap previousSessionVariables = new HashMap(5);
+	private ThreadLocal variableInitializationInProgress = new ThreadLocal();
+
+	/**
+	 * Classpath containers pool
+	 */
+	public HashMap containers = new HashMap(5);
+	public HashMap previousSessionContainers = new HashMap(5);
+	private ThreadLocal containerInitializationInProgress = new ThreadLocal();
+	ThreadLocal containersBeingInitialized = new ThreadLocal();
+	
+	public static final int NO_BATCH_INITIALIZATION = 0;
+	public static final int NEED_BATCH_INITIALIZATION = 1;
+	public static final int BATCH_INITIALIZATION_IN_PROGRESS = 2;
+	public static final int BATCH_INITIALIZATION_FINISHED = 3;
+	public int batchContainerInitializations = NO_BATCH_INITIALIZATION;
+
+	public BatchInitializationMonitor batchContainerInitializationsProgress = new BatchInitializationMonitor();
+	public Hashtable containerInitializersCache = new Hashtable(5);
+
+	/*
+	 * A HashSet that contains the IJavaProject whose classpath is being resolved.
+	 */
+	private ThreadLocal classpathsBeingResolved = new ThreadLocal();
+
+	/*
+	 * The unique workspace scope
+	 */
+	public JavaWorkspaceScope workspaceScope;
+
+	/*
+	 * Pools of symbols used in the Java model.
+	 * Used as a replacement for String#intern() that could prevent garbage collection of strings on some VMs.
+	 */
+	private WeakHashSet stringSymbols = new WeakHashSet(5);
+	private WeakHashSetOfCharArray charArraySymbols = new WeakHashSetOfCharArray(5);
+
+	/*
+	 * Extension used to construct Java 6 annotation processor managers
+	 */
+	private IConfigurationElement annotationProcessorManagerFactory = null;
+
+	/*
+	 * Map from a package fragment root's path to a source attachment property (source path + ATTACHMENT_PROPERTY_DELIMITER + source root path)
+	 */
+	public Map rootPathToAttachments = new Hashtable();
+
+	public final static String CP_VARIABLE_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$
+	public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
+	public final static String CP_USERLIBRARY_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".userLibrary."; //$NON-NLS-1$
+	public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
+	public final static IPath CP_ENTRY_IGNORE_PATH = new Path(CP_ENTRY_IGNORE);
+	public final static String TRUE = "true"; //$NON-NLS-1$
+
+	private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 2;
+
+	/**
+	 * Name of the extension point for contributing classpath variable initializers
+	 */
+	public static final String CPVARIABLE_INITIALIZER_EXTPOINT_ID = "classpathVariableInitializer" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the extension point for contributing classpath container initializers
+	 */
+	public static final String CPCONTAINER_INITIALIZER_EXTPOINT_ID = "classpathContainerInitializer" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the extension point for contributing a source code formatter
+	 */
+	public static final String FORMATTER_EXTPOINT_ID = "codeFormatter" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the extension point for contributing a compilation participant
+	 */
+	public static final String COMPILATION_PARTICIPANT_EXTPOINT_ID = "compilationParticipant" ; //$NON-NLS-1$
+
+	/**
+	 * Name of the extension point for contributing the Java 6 annotation processor manager
+	 */
+	public static final String ANNOTATION_PROCESSOR_MANAGER_EXTPOINT_ID = "annotationProcessorManager" ;  //$NON-NLS-1$
+
+	/**
+	 * Name of the JVM parameter to specify whether or not referenced JAR should be resolved for container libraries.
+	 */
+	private static final String RESOLVE_REFERENCED_LIBRARIES_FOR_CONTAINERS = "resolveReferencedLibrariesForContainers"; //$NON-NLS-1$
+	
+	/**
+	 * Name of the JVM parameter to specify how many compilation units must be handled at once by the builder.
+	 * The default value is represented by <code>AbstractImageBuilder#MAX_AT_ONCE</code>.
+	 */
+	public static final String MAX_COMPILED_UNITS_AT_ONCE = "maxCompiledUnitsAtOnce"; //$NON-NLS-1$
+
+	/**
+	 * Special value used for recognizing ongoing initialization and breaking initialization cycles
+	 */
+	public final static IPath VARIABLE_INITIALIZATION_IN_PROGRESS = new Path("Variable Initialization In Progress"); //$NON-NLS-1$
+	public final static IClasspathContainer CONTAINER_INITIALIZATION_IN_PROGRESS = new IClasspathContainer() {
+		public IClasspathEntry[] getClasspathEntries() { return null; }
+		public String getDescription() { return "Container Initialization In Progress"; } //$NON-NLS-1$
+		public int getKind() { return 0; }
+		public IPath getPath() { return null; }
+		public String toString() { return getDescription(); }
+	};
+
+	private static final String BUFFER_MANAGER_DEBUG = JavaCore.PLUGIN_ID + "/debug/buffermanager" ; //$NON-NLS-1$
+	private static final String INDEX_MANAGER_DEBUG = JavaCore.PLUGIN_ID + "/debug/indexmanager" ; //$NON-NLS-1$
+	private static final String INDEX_MANAGER_ADVANCED_DEBUG = JavaCore.PLUGIN_ID + "/debug/indexmanager/advanced" ; //$NON-NLS-1$
+	private static final String COMPILER_DEBUG = JavaCore.PLUGIN_ID + "/debug/compiler" ; //$NON-NLS-1$
+	private static final String JAVAMODEL_DEBUG = JavaCore.PLUGIN_ID + "/debug/javamodel" ; //$NON-NLS-1$
+	private static final String JAVAMODELCACHE_DEBUG = JavaCore.PLUGIN_ID + "/debug/javamodel/cache" ; //$NON-NLS-1$
+	private static final String CP_RESOLVE_DEBUG = JavaCore.PLUGIN_ID + "/debug/cpresolution" ; //$NON-NLS-1$
+	private static final String CP_RESOLVE_ADVANCED_DEBUG = JavaCore.PLUGIN_ID + "/debug/cpresolution/advanced" ; //$NON-NLS-1$
+	private static final String CP_RESOLVE_FAILURE_DEBUG = JavaCore.PLUGIN_ID + "/debug/cpresolution/failure" ; //$NON-NLS-1$
+	private static final String ZIP_ACCESS_DEBUG = JavaCore.PLUGIN_ID + "/debug/zipaccess" ; //$NON-NLS-1$
+	private static final String DELTA_DEBUG =JavaCore.PLUGIN_ID + "/debug/javadelta" ; //$NON-NLS-1$
+	private static final String DELTA_DEBUG_VERBOSE =JavaCore.PLUGIN_ID + "/debug/javadelta/verbose" ; //$NON-NLS-1$
+	private static final String DOM_AST_DEBUG = JavaCore.PLUGIN_ID + "/debug/dom/ast" ; //$NON-NLS-1$
+	private static final String DOM_AST_DEBUG_THROW = JavaCore.PLUGIN_ID + "/debug/dom/ast/throw" ; //$NON-NLS-1$
+	private static final String DOM_REWRITE_DEBUG = JavaCore.PLUGIN_ID + "/debug/dom/rewrite" ; //$NON-NLS-1$
+	private static final String HIERARCHY_DEBUG = JavaCore.PLUGIN_ID + "/debug/hierarchy" ; //$NON-NLS-1$
+	private static final String POST_ACTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/postaction" ; //$NON-NLS-1$
+	private static final String BUILDER_DEBUG = JavaCore.PLUGIN_ID + "/debug/builder" ; //$NON-NLS-1$
+	private static final String BUILDER_STATS_DEBUG = JavaCore.PLUGIN_ID + "/debug/builder/stats" ; //$NON-NLS-1$
+	private static final String COMPLETION_DEBUG = JavaCore.PLUGIN_ID + "/debug/completion" ; //$NON-NLS-1$
+	private static final String RESOLUTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/resolution" ; //$NON-NLS-1$
+	private static final String SELECTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/selection" ; //$NON-NLS-1$
+	private static final String SEARCH_DEBUG = JavaCore.PLUGIN_ID + "/debug/search" ; //$NON-NLS-1$
+	private static final String SOURCE_MAPPER_DEBUG_VERBOSE = JavaCore.PLUGIN_ID + "/debug/sourcemapper" ; //$NON-NLS-1$
+	private static final String FORMATTER_DEBUG = JavaCore.PLUGIN_ID + "/debug/formatter" ; //$NON-NLS-1$
+
+	public static final String COMPLETION_PERF = JavaCore.PLUGIN_ID + "/perf/completion" ; //$NON-NLS-1$
+	public static final String SELECTION_PERF = JavaCore.PLUGIN_ID + "/perf/selection" ; //$NON-NLS-1$
+	public static final String DELTA_LISTENER_PERF = JavaCore.PLUGIN_ID + "/perf/javadeltalistener" ; //$NON-NLS-1$
+	public static final String VARIABLE_INITIALIZER_PERF = JavaCore.PLUGIN_ID + "/perf/variableinitializer" ; //$NON-NLS-1$
+	public static final String CONTAINER_INITIALIZER_PERF = JavaCore.PLUGIN_ID + "/perf/containerinitializer" ; //$NON-NLS-1$
+	public static final String RECONCILE_PERF = JavaCore.PLUGIN_ID + "/perf/reconcile" ; //$NON-NLS-1$
+
+	private final static String INDEXED_SECONDARY_TYPES = "#@*_indexing secondary cache_*@#"; //$NON-NLS-1$
+
+	public static boolean PERF_VARIABLE_INITIALIZER = false;
+	public static boolean PERF_CONTAINER_INITIALIZER = false;
+	// Non-static, which will give it a chance to retain the default when and if JavaModelManager is restarted.
+	boolean resolveReferencedLibrariesForContainers = false;
+
+	public final static ICompilationUnit[] NO_WORKING_COPY = new ICompilationUnit[0];
+
+	// Options
+	private final static int UNKNOWN_OPTION = 0;
+	private final static int DEPRECATED_OPTION = 1;
+	private final static int VALID_OPTION = 2;
+	HashSet optionNames = new HashSet(20);
+	Map deprecatedOptions = new HashMap();
+	Hashtable optionsCache;
+
+	// Preferences
+	public final IEclipsePreferences[] preferencesLookup = new IEclipsePreferences[2];
+	static final int PREF_INSTANCE = 0;
+	static final int PREF_DEFAULT = 1;
+
+	static final Object[][] NO_PARTICIPANTS = new Object[0][];
+
+	public static class CompilationParticipants {
+
+		private final static int MAX_SOURCE_LEVEL = 8; // 1.1 to 1.8
+
+		/*
+		 * The registered compilation participants (a table from int (source level) to Object[])
+		 * The Object array contains first IConfigurationElements when not resolved yet, then
+		 * it contains CompilationParticipants.
+		 */
+		private Object[][] registeredParticipants = null;
+		private HashSet managedMarkerTypes;
+
+		public CompilationParticipant[] getCompilationParticipants(IJavaProject project) {
+			final Object[][] participantsPerSource = getRegisteredParticipants();
+			if (participantsPerSource == NO_PARTICIPANTS)
+				return null;
+			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true/*inherit options*/);
+			final int sourceLevelIndex = indexForSourceLevel(sourceLevel);
+			final Object[] participants = participantsPerSource[sourceLevelIndex];
+			int length = participants.length;
+			CompilationParticipant[] result = new CompilationParticipant[length];
+			int index = 0;
+			for (int i = 0; i < length; i++) {
+				if (participants[i] instanceof IConfigurationElement) {
+					final IConfigurationElement configElement = (IConfigurationElement) participants[i];
+					final int participantIndex = i;
+					SafeRunner.run(new ISafeRunnable() {
+						public void handleException(Throwable exception) {
+							Util.log(exception, "Exception occurred while creating compilation participant"); //$NON-NLS-1$
+						}
+						public void run() throws Exception {
+							Object executableExtension = configElement.createExecutableExtension("class"); //$NON-NLS-1$
+							for (int j = sourceLevelIndex; j < MAX_SOURCE_LEVEL; j++)
+								participantsPerSource[j][participantIndex] = executableExtension;
+						}
+					});
+				}
+				CompilationParticipant participant;
+				if ((participants[i] instanceof CompilationParticipant) && (participant = (CompilationParticipant) participants[i]).isActive(project))
+					result[index++] = participant;
+			}
+			if (index == 0)
+				return null;
+			if (index < length)
+				System.arraycopy(result, 0, result = new CompilationParticipant[index], 0, index);
+			return result;
+		}
+
+		public HashSet managedMarkerTypes() {
+			if (this.managedMarkerTypes == null) {
+				// force extension points to be read
+				getRegisteredParticipants();
+			}
+			return this.managedMarkerTypes;
+		}
+
+		private synchronized Object[][] getRegisteredParticipants() {
+			if (this.registeredParticipants != null) {
+				return this.registeredParticipants;
+			}
+			this.managedMarkerTypes = new HashSet();
+			IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, COMPILATION_PARTICIPANT_EXTPOINT_ID);
+			if (extension == null)
+				return this.registeredParticipants = NO_PARTICIPANTS;
+			final ArrayList modifyingEnv = new ArrayList();
+			final ArrayList creatingProblems = new ArrayList();
+			final ArrayList others = new ArrayList();
+			IExtension[] extensions = extension.getExtensions();
+			// for all extensions of this point...
+			for(int i = 0; i < extensions.length; i++) {
+				IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+				// for all config elements named "compilationParticipant"
+				for(int j = 0; j < configElements.length; j++) {
+					final IConfigurationElement configElement = configElements[j];
+					String elementName =configElement.getName();
+					if (!("compilationParticipant".equals(elementName))) { //$NON-NLS-1$
+						continue;
+					}
+					// add config element in the group it belongs to
+					if (TRUE.equals(configElement.getAttribute("modifiesEnvironment"))) //$NON-NLS-1$
+						modifyingEnv.add(configElement);
+					else if (TRUE.equals(configElement.getAttribute("createsProblems"))) //$NON-NLS-1$
+						creatingProblems.add(configElement);
+					else
+						others.add(configElement);
+					// add managed marker types
+					IConfigurationElement[] managedMarkers = configElement.getChildren("managedMarker"); //$NON-NLS-1$
+					for (int k = 0, length = managedMarkers.length; k < length; k++) {
+						IConfigurationElement element = managedMarkers[k];
+						String markerType = element.getAttribute("markerType"); //$NON-NLS-1$
+						if (markerType != null)
+							this.managedMarkerTypes.add(markerType);
+					}
+				}
+			}
+			int size = modifyingEnv.size() + creatingProblems.size() + others.size();
+			if (size == 0)
+				return this.registeredParticipants = NO_PARTICIPANTS;
+
+			// sort config elements in each group
+			IConfigurationElement[] configElements = new IConfigurationElement[size];
+			int index = 0;
+			index = sortParticipants(modifyingEnv, configElements, index);
+			index = sortParticipants(creatingProblems, configElements, index);
+			index = sortParticipants(others, configElements, index);
+
+			// create result table
+			Object[][] result = new Object[MAX_SOURCE_LEVEL][];
+			int length = configElements.length;
+			for (int i = 0; i < MAX_SOURCE_LEVEL; i++) {
+				result[i] = new Object[length];
+			}
+			for (int i = 0; i < length; i++) {
+				String sourceLevel = configElements[i].getAttribute("requiredSourceLevel"); //$NON-NLS-1$
+				int sourceLevelIndex = indexForSourceLevel(sourceLevel);
+				for (int j = sourceLevelIndex; j < MAX_SOURCE_LEVEL; j++) {
+					result[j][i] = configElements[i];
+				}
+			}
+			return this.registeredParticipants = result;
+		}
+
+		/*
+		 * 1.1 -> 0
+		 * 1.2 -> 1
+		 * ...
+		 * 1.6 -> 5
+		 * 1.7 -> 6
+		 * null -> 0
+		 */
+		private int indexForSourceLevel(String sourceLevel) {
+			if (sourceLevel == null) return 0;
+			int majVersion = (int) (CompilerOptions.versionToJdkLevel(sourceLevel) >>> 16);
+			switch (majVersion) {
+				case ClassFileConstants.MAJOR_VERSION_1_2:
+					return 1;
+				case ClassFileConstants.MAJOR_VERSION_1_3:
+					return 2;
+				case ClassFileConstants.MAJOR_VERSION_1_4:
+					return 3;
+				case ClassFileConstants.MAJOR_VERSION_1_5:
+					return 4;
+				case ClassFileConstants.MAJOR_VERSION_1_6:
+					return 5;
+				case ClassFileConstants.MAJOR_VERSION_1_7:
+					return 6;
+				case ClassFileConstants.MAJOR_VERSION_1_8:
+					return 7;
+				default:
+					// all other cases including ClassFileConstants.MAJOR_VERSION_1_1
+					return 0;
+			}
+		}
+
+		private int sortParticipants(ArrayList group, IConfigurationElement[] configElements, int index) {
+			int size = group.size();
+			if (size == 0) return index;
+			Object[] elements = group.toArray();
+			Util.sort(elements, new Util.Comparer() {
+				public int compare(Object a, Object b) {
+					if (a == b) return 0;
+					String id = ((IConfigurationElement) a).getAttribute("id"); //$NON-NLS-1$
+					if (id == null) return -1;
+					IConfigurationElement[] requiredElements = ((IConfigurationElement) b).getChildren("requires"); //$NON-NLS-1$
+					for (int i = 0, length = requiredElements.length; i < length; i++) {
+						IConfigurationElement required = requiredElements[i];
+						if (id.equals(required.getAttribute("id"))) //$NON-NLS-1$
+							return 1;
+					}
+					return -1;
+				}
+			});
+			for (int i = 0; i < size; i++)
+				configElements[index+i] = (IConfigurationElement) elements[i];
+			return index + size;
+		}
+	}
+
+	public final CompilationParticipants compilationParticipants = new CompilationParticipants();
+
+	/* whether an AbortCompilationUnit should be thrown when the source of a compilation unit cannot be retrieved */
+	public ThreadLocal abortOnMissingSource = new ThreadLocal();
+
+	private ExternalFoldersManager externalFoldersManager = ExternalFoldersManager.getExternalFoldersManager();
+
+	/**
+	 * Returns whether the given full path (for a package) conflicts with the output location
+	 * of the given project.
+	 */
+	public static boolean conflictsWithOutputLocation(IPath folderPath, JavaProject project) {
+		try {
+			IPath outputLocation = project.getOutputLocation();
+			if (outputLocation == null) {
+				// in doubt, there is a conflict
+				return true;
+			}
+			if (outputLocation.isPrefixOf(folderPath)) {
+				// only allow nesting in project's output if there is a corresponding source folder
+				// or if the project's output is not used (in other words, if all source folders have their custom output)
+				IClasspathEntry[] classpath = project.getResolvedClasspath();
+				boolean isOutputUsed = false;
+				for (int i = 0, length = classpath.length; i < length; i++) {
+					IClasspathEntry entry = classpath[i];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+						if (entry.getPath().equals(outputLocation)) {
+							return false;
+						}
+						if (entry.getOutputLocation() == null) {
+							isOutputUsed = true;
+						}
+					}
+				}
+				return isOutputUsed;
+			}
+			return false;
+		} catch (JavaModelException e) {
+			// in doubt, there is a conflict
+			return true;
+		}
+	}
+
+	public synchronized IClasspathContainer containerGet(IJavaProject project, IPath containerPath) {
+		// check initialization in progress first
+		if (containerIsInitializationInProgress(project, containerPath)) {
+			return CONTAINER_INITIALIZATION_IN_PROGRESS;
+		}
+
+		Map projectContainers = (Map)this.containers.get(project);
+		if (projectContainers == null){
+			return null;
+		}
+		IClasspathContainer container = (IClasspathContainer)projectContainers.get(containerPath);
+		return container;
+	}
+
+	public synchronized IClasspathContainer containerGetDefaultToPreviousSession(IJavaProject project, IPath containerPath) {
+		Map projectContainers = (Map)this.containers.get(project);
+		if (projectContainers == null)
+			return getPreviousSessionContainer(containerPath, project);
+		IClasspathContainer container = (IClasspathContainer)projectContainers.get(containerPath);
+		if (container == null)
+			return getPreviousSessionContainer(containerPath, project);
+		return container;
+	}
+
+	private boolean containerIsInitializationInProgress(IJavaProject project, IPath containerPath) {
+		Map initializations = (Map)this.containerInitializationInProgress.get();
+		if (initializations == null)
+			return false;
+		HashSet projectInitializations = (HashSet) initializations.get(project);
+		if (projectInitializations == null)
+			return false;
+		return projectInitializations.contains(containerPath);
+	}
+
+	private void containerAddInitializationInProgress(IJavaProject project, IPath containerPath) {
+		Map initializations = (Map)this.containerInitializationInProgress.get();
+		if (initializations == null)
+			this.containerInitializationInProgress.set(initializations = new HashMap());
+		HashSet projectInitializations = (HashSet) initializations.get(project);
+		if (projectInitializations == null)
+			initializations.put(project, projectInitializations = new HashSet());
+		projectInitializations.add(containerPath);
+	}
+	
+	public void containerBeingInitializedPut(IJavaProject project, IPath containerPath, IClasspathContainer container) {
+		Map perProjectContainers = (Map)this.containersBeingInitialized.get();
+		if (perProjectContainers == null)
+			this.containersBeingInitialized.set(perProjectContainers = new HashMap());
+		HashMap perPathContainers = (HashMap) perProjectContainers.get(project);
+		if (perPathContainers == null)
+			perProjectContainers.put(project, perPathContainers = new HashMap());
+		perPathContainers.put(containerPath, container);
+	}
+
+	public IClasspathContainer containerBeingInitializedGet(IJavaProject project, IPath containerPath) {
+		Map perProjectContainers = (Map)this.containersBeingInitialized.get();
+		if (perProjectContainers == null)
+			return null;
+		HashMap perPathContainers = (HashMap) perProjectContainers.get(project);
+		if (perPathContainers == null)
+			return null;
+		return (IClasspathContainer) perPathContainers.get(containerPath);
+	}
+
+	public IClasspathContainer containerBeingInitializedRemove(IJavaProject project, IPath containerPath) {
+		Map perProjectContainers = (Map)this.containersBeingInitialized.get();
+		if (perProjectContainers == null)
+			return null;
+		HashMap perPathContainers = (HashMap) perProjectContainers.get(project);
+		if (perPathContainers == null)
+			return null;
+		IClasspathContainer container = (IClasspathContainer) perPathContainers.remove(containerPath);
+		if (perPathContainers.size() == 0)
+			perPathContainers.remove(project);
+		if (perProjectContainers.size() == 0)
+			this.containersBeingInitialized.set(null);
+		return container;
+	}
+
+	public synchronized void containerPut(IJavaProject project, IPath containerPath, IClasspathContainer container){
+
+		// set/unset the initialization in progress
+		if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
+			containerAddInitializationInProgress(project, containerPath);
+
+			// do not write out intermediate initialization value
+			return;
+		} else {
+			containerRemoveInitializationInProgress(project, containerPath);
+
+			Map projectContainers = (Map)this.containers.get(project);
+ 			if (projectContainers == null){
+				projectContainers = new HashMap(1);
+				this.containers.put(project, projectContainers);
+			}
+
+			if (container == null) {
+				projectContainers.remove(containerPath);
+			} else {
+  				projectContainers.put(containerPath, container);
+			}
+			// discard obsoleted information about previous session
+			Map previousContainers = (Map)this.previousSessionContainers.get(project);
+			if (previousContainers != null){
+				previousContainers.remove(containerPath);
+			}
+		}
+		// container values are persisted in preferences during save operations, see #saving(ISaveContext)
+	}
+
+	/*
+	 * The given project is being removed. Remove all containers for this project from the cache.
+	 */
+	public synchronized void containerRemove(IJavaProject project) {
+		Map initializations = (Map) this.containerInitializationInProgress.get();
+		if (initializations != null) {
+			initializations.remove(project);
+		}
+		this.containers.remove(project);
+	}
+
+	public boolean containerPutIfInitializingWithSameEntries(IPath containerPath, IJavaProject[] projects, IClasspathContainer[] respectiveContainers) {
+		int projectLength = projects.length;
+		if (projectLength != 1)
+			return false;
+		final IClasspathContainer container = respectiveContainers[0];
+		IJavaProject project = projects[0];
+		// optimize only if initializing, otherwise we are in a regular setContainer(...) call
+		if (!containerIsInitializationInProgress(project, containerPath))
+			return false;
+		IClasspathContainer previousContainer = containerGetDefaultToPreviousSession(project, containerPath);
+		if (container == null) {
+			if (previousContainer == null) {
+				containerPut(project, containerPath, null);
+				return true;
+			}
+			return false;
+		}
+		final IClasspathEntry[] newEntries = container.getClasspathEntries();
+		if (previousContainer == null)
+			if (newEntries.length == 0) {
+				containerPut(project, containerPath, container);
+				return true;
+			} else {
+				if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+					verbose_missbehaving_container(containerPath, projects, respectiveContainers, container, newEntries, null/*no old entries*/);
+				return false;
+			}
+		final IClasspathEntry[] oldEntries = previousContainer.getClasspathEntries();
+		if (oldEntries.length != newEntries.length) {
+			if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+				verbose_missbehaving_container(containerPath, projects, respectiveContainers, container, newEntries, oldEntries);
+			return false;
+		}
+		for (int i = 0, length = newEntries.length; i < length; i++) {
+			if (newEntries[i] == null) {
+				if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+					verbose_missbehaving_container(project, containerPath, newEntries);
+				return false;
+			}
+			if (!newEntries[i].equals(oldEntries[i])) {
+				if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+					verbose_missbehaving_container(containerPath, projects, respectiveContainers, container, newEntries, oldEntries);
+				return false;
+			}
+		}
+		containerPut(project, containerPath, container);
+		return true;
+	}
+
+	private void verbose_missbehaving_container(
+			IPath containerPath,
+			IJavaProject[] projects,
+			IClasspathContainer[] respectiveContainers,
+			final IClasspathContainer container,
+			final IClasspathEntry[] newEntries,
+			final IClasspathEntry[] oldEntries) {
+		Util.verbose(
+			"CPContainer SET  - missbehaving container\n" + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	projects: {" +//$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				projects,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) { return ((IJavaProject) o).getElementName(); }
+				}) +
+			"}\n	values on previous session: {\n"  +//$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				respectiveContainers,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) {
+						StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+						if (o == null) {
+							buffer.append("<null>"); //$NON-NLS-1$
+							return buffer.toString();
+						}
+						buffer.append(container.getDescription());
+						buffer.append(" {\n"); //$NON-NLS-1$
+						if (oldEntries == null) {
+							buffer.append(" 			"); //$NON-NLS-1$
+							buffer.append("<null>\n"); //$NON-NLS-1$
+						} else {
+							for (int j = 0; j < oldEntries.length; j++){
+								buffer.append(" 			"); //$NON-NLS-1$
+								buffer.append(oldEntries[j]);
+								buffer.append('\n');
+							}
+						}
+						buffer.append(" 		}"); //$NON-NLS-1$
+						return buffer.toString();
+					}
+				}) +
+			"}\n	new values: {\n"  +//$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				respectiveContainers,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) {
+						StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+						if (o == null) {
+							buffer.append("<null>"); //$NON-NLS-1$
+							return buffer.toString();
+						}
+						buffer.append(container.getDescription());
+						buffer.append(" {\n"); //$NON-NLS-1$
+						for (int j = 0; j < newEntries.length; j++){
+							buffer.append(" 			"); //$NON-NLS-1$
+							buffer.append(newEntries[j]);
+							buffer.append('\n');
+						}
+						buffer.append(" 		}"); //$NON-NLS-1$
+						return buffer.toString();
+					}
+				}) +
+			"\n	}"); //$NON-NLS-1$
+	}
+
+	void verbose_missbehaving_container(IJavaProject project, IPath containerPath, IClasspathEntry[] classpathEntries) {
+		Util.verbose(
+			"CPContainer GET - missbehaving container (returning null classpath entry)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	classpath entries: {\n" + //$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				classpathEntries,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) {
+						StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+						if (o == null) {
+							buffer.append("<null>"); //$NON-NLS-1$
+							return buffer.toString();
+						}
+						buffer.append(o);
+						return buffer.toString();
+					}
+				}) +
+			"\n	}" //$NON-NLS-1$
+		);
+	}
+
+	void verbose_missbehaving_container_null_entries(IJavaProject project, IPath containerPath) {
+		Util.verbose(
+			"CPContainer GET - missbehaving container (returning null as classpath entries)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	classpath entries: <null>" //$NON-NLS-1$
+		);
+	}
+
+	private void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
+		Map initializations = (Map)this.containerInitializationInProgress.get();
+		if (initializations == null)
+			return;
+		HashSet projectInitializations = (HashSet) initializations.get(project);
+		if (projectInitializations == null)
+			return;
+		projectInitializations.remove(containerPath);
+		if (projectInitializations.size() == 0)
+			initializations.remove(project);
+		if (initializations.size() == 0)
+			this.containerInitializationInProgress.set(null);
+	}
+
+	private synchronized void containersReset(String[] containerIDs) {
+		for (int i = 0; i < containerIDs.length; i++) {
+			String containerID = containerIDs[i];
+			Iterator projectIterator = this.containers.values().iterator();
+			while (projectIterator.hasNext()){
+				Map projectContainers = (Map) projectIterator.next();
+				if (projectContainers != null){
+					Iterator containerIterator = projectContainers.keySet().iterator();
+					while (containerIterator.hasNext()){
+						IPath containerPath = (IPath)containerIterator.next();
+						if (containerID.equals(containerPath.segment(0))) { // registered container
+							projectContainers.put(containerPath, null); // reset container value, but leave entry in Map
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the Java element corresponding to the given resource, or
+	 * <code>null</code> if unable to associate the given resource
+	 * with a Java element.
+	 * <p>
+	 * The resource must be one of:<ul>
+	 *	<li>a project - the element returned is the corresponding <code>IJavaProject</code></li>
+	 *	<li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+	 *	<li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+	 *	<li>a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.) - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+	 *  <li>a folder - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+	 *			or <code>IPackageFragment</code></li>
+	 *  <li>the workspace root resource - the element returned is the <code>IJavaModel</code></li>
+	 *	</ul>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 */
+	public static IJavaElement create(IResource resource, IJavaProject project) {
+		if (resource == null) {
+			return null;
+		}
+		int type = resource.getType();
+		switch (type) {
+			case IResource.PROJECT :
+				return JavaCore.create((IProject) resource);
+			case IResource.FILE :
+				return create((IFile) resource, project);
+			case IResource.FOLDER :
+				return create((IFolder) resource, project);
+			case IResource.ROOT :
+				return JavaCore.create((IWorkspaceRoot) resource);
+			default :
+				return null;
+		}
+	}
+
+	/**
+	 * Returns the Java element corresponding to the given file, its project being the given
+	 * project.
+	 * Returns <code>null</code> if unable to associate the given file
+	 * with a Java element.
+	 *
+	 * <p>The file must be one of:<ul>
+	 *	<li>a <code>.java</code> file - the element returned is the corresponding <code>ICompilationUnit</code></li>
+	 *	<li>a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code></li>
+	 *	<li>a ZIP archive (e.g. a <code>.jar</code>, a <code>.zip</code> file, etc.) - the element returned is the corresponding <code>IPackageFragmentRoot</code></li>
+	 *	</ul>
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 */
+	public static IJavaElement create(IFile file, IJavaProject project) {
+		if (file == null) {
+			return null;
+		}
+		if (project == null) {
+			project = JavaCore.create(file.getProject());
+		}
+
+		if (file.getFileExtension() != null) {
+			String name = file.getName();
+			if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name))
+				return createCompilationUnitFrom(file, project);
+			if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name))
+				return createClassFileFrom(file, project);
+			return createJarPackageFragmentRootFrom(file, project);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the package fragment or package fragment root corresponding to the given folder,
+	 * its parent or great parent being the given project.
+	 * or <code>null</code> if unable to associate the given folder with a Java element.
+	 * <p>
+	 * Note that a package fragment root is returned rather than a default package.
+	 * <p>
+	 * Creating a Java element has the side effect of creating and opening all of the
+	 * element's parents if they are not yet open.
+	 */
+	public static IJavaElement create(IFolder folder, IJavaProject project) {
+		if (folder == null) {
+			return null;
+		}
+		IJavaElement element;
+		if (project == null) {
+			project = JavaCore.create(folder.getProject());
+			element = determineIfOnClasspath(folder, project);
+			if (element == null) {
+				// walk all projects and find one that have the given folder on its classpath
+				IJavaProject[] projects;
+				try {
+					projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+				} catch (JavaModelException e) {
+					return null;
+				}
+				for (int i = 0, length = projects.length; i < length; i++) {
+					project = projects[i];
+					element = determineIfOnClasspath(folder, project);
+					if (element != null)
+						break;
+				}
+			}
+		} else {
+			element = determineIfOnClasspath(folder, project);
+		}
+		return element;
+	}
+
+	/**
+	 * Creates and returns a class file element for the given <code>.class</code> file,
+	 * its project being the given project. Returns <code>null</code> if unable
+	 * to recognize the class file.
+	 */
+	public static IClassFile createClassFileFrom(IFile file, IJavaProject project ) {
+		if (file == null) {
+			return null;
+		}
+		if (project == null) {
+			project = JavaCore.create(file.getProject());
+		}
+		IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
+		if (pkg == null) {
+			// fix for 1FVS7WE
+			// not on classpath - make the root its folder, and a default package
+			PackageFragmentRoot root = (PackageFragmentRoot) project.getPackageFragmentRoot(file.getParent());
+			pkg = root.getPackageFragment(CharOperation.NO_STRINGS);
+		}
+		return pkg.getClassFile(file.getName());
+	}
+
+	/**
+	 * Creates and returns a compilation unit element for the given <code>.java</code>
+	 * file, its project being the given project. Returns <code>null</code> if unable
+	 * to recognize the compilation unit.
+	 */
+	public static ICompilationUnit createCompilationUnitFrom(IFile file, IJavaProject project) {
+
+		if (file == null) return null;
+
+		if (project == null) {
+			project = JavaCore.create(file.getProject());
+		}
+		IPackageFragment pkg = (IPackageFragment) determineIfOnClasspath(file, project);
+		if (pkg == null) {
+			// not on classpath - make the root its folder, and a default package
+			PackageFragmentRoot root = (PackageFragmentRoot) project.getPackageFragmentRoot(file.getParent());
+			pkg = root.getPackageFragment(CharOperation.NO_STRINGS);
+
+			if (VERBOSE){
+				System.out.println("WARNING : creating unit element outside classpath ("+ Thread.currentThread()+"): " + file.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+			}
+		}
+		return pkg.getCompilationUnit(file.getName());
+	}
+
+	/**
+	 * Creates and returns a handle for the given JAR file, its project being the given project.
+	 * The Java model associated with the JAR's project may be
+	 * created as a side effect.
+	 * Returns <code>null</code> if unable to create a JAR package fragment root.
+	 * (for example, if the JAR file represents a non-Java resource)
+	 */
+	public static IPackageFragmentRoot createJarPackageFragmentRootFrom(IFile file, IJavaProject project) {
+		if (file == null) {
+			return null;
+		}
+		if (project == null) {
+			project = JavaCore.create(file.getProject());
+		}
+
+		// Create a jar package fragment root only if on the classpath
+		IPath resourcePath = file.getFullPath();
+		try {
+			IClasspathEntry entry = ((JavaProject)project).getClasspathEntryFor(resourcePath);
+			if (entry != null) {
+				return project.getPackageFragmentRoot(file);
+			}
+		} catch (JavaModelException e) {
+			// project doesn't exist: return null
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the package fragment root represented by the resource, or
+	 * the package fragment the given resource is located in, or <code>null</code>
+	 * if the given resource is not on the classpath of the given project.
+	 */
+	public static IJavaElement determineIfOnClasspath(IResource resource, IJavaProject project) {
+		IPath resourcePath = resource.getFullPath();
+		boolean isExternal = ExternalFoldersManager.isInternalPathForExternalFolder(resourcePath);
+		if (isExternal)
+			resourcePath = resource.getLocation();
+
+		try {
+			JavaProjectElementInfo projectInfo = (JavaProjectElementInfo) getJavaModelManager().getInfo(project);
+			ProjectCache projectCache = projectInfo == null ? null : projectInfo.projectCache;
+			HashtableOfArrayToObject allPkgFragmentsCache = projectCache == null ? null : projectCache.allPkgFragmentsCache;
+			boolean isJavaLike = org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourcePath.lastSegment());
+			IClasspathEntry[] entries = isJavaLike ? project.getRawClasspath() // JAVA file can only live inside SRC folder (on the raw path)
+					: ((JavaProject)project).getResolvedClasspath();
+
+			int length	= entries.length;
+			if (length > 0) {
+				String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+				String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+				for (int i = 0; i < length; i++) {
+					IClasspathEntry entry = entries[i];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
+					IPath rootPath = entry.getPath();
+					if (rootPath.equals(resourcePath)) {
+						if (isJavaLike) 
+							return null;
+						return project.getPackageFragmentRoot(resource);
+					} else if (rootPath.isPrefixOf(resourcePath)) {
+						// allow creation of package fragment if it contains a .java file that is included
+						if (!Util.isExcluded(resource, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars())) {
+							// given we have a resource child of the root, it cannot be a JAR pkg root
+							PackageFragmentRoot root =
+								isExternal ?
+									new ExternalPackageFragmentRoot(rootPath, (JavaProject) project) :
+									(PackageFragmentRoot) ((JavaProject) project).getFolderPackageFragmentRoot(rootPath);
+							if (root == null) return null;
+							IPath pkgPath = resourcePath.removeFirstSegments(rootPath.segmentCount());
+
+							if (resource.getType() == IResource.FILE) {
+								// if the resource is a file, then remove the last segment which
+								// is the file name in the package
+								pkgPath = pkgPath.removeLastSegments(1);
+							}
+							String[] pkgName = pkgPath.segments();
+
+							// if package name is in the cache, then it has already been validated
+							// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=133141)
+							if (allPkgFragmentsCache != null && allPkgFragmentsCache.containsKey(pkgName))
+								return root.getPackageFragment(pkgName);
+
+							if (pkgName.length != 0 && JavaConventions.validatePackageName(Util.packageName(pkgPath, sourceLevel, complianceLevel), sourceLevel, complianceLevel).getSeverity() == IStatus.ERROR) {
+								return null;
+							}
+							return root.getPackageFragment(pkgName);
+						}
+					}
+				}
+			}
+		} catch (JavaModelException npe) {
+			return null;
+		}
+		return null;
+	}
+
+	/**
+	 * The singleton manager
+	 */
+	private static JavaModelManager MANAGER= new JavaModelManager();
+
+	/**
+	 * Infos cache.
+	 */
+	private JavaModelCache cache;
+
+	/*
+	 * Temporary cache of newly opened elements
+	 */
+	private ThreadLocal temporaryCache = new ThreadLocal();
+
+	/**
+	 * Set of elements which are out of sync with their buffers.
+	 */
+	protected HashSet elementsOutOfSynchWithBuffers = new HashSet(11);
+
+	/**
+	 * Holds the state used for delta processing.
+	 */
+	public DeltaProcessingState deltaState = new DeltaProcessingState();
+
+	public IndexManager indexManager = null;
+
+	/**
+	 * Table from IProject to PerProjectInfo.
+	 * NOTE: this object itself is used as a lock to synchronize creation/removal of per project infos
+	 */
+	protected Map perProjectInfos = new HashMap(5);
+
+	/**
+	 * Table from WorkingCopyOwner to a table of ICompilationUnit (working copy handle) to PerWorkingCopyInfo.
+	 * NOTE: this object itself is used as a lock to synchronize creation/removal of per working copy infos
+	 */
+	protected Map perWorkingCopyInfos = new HashMap(5);
+
+	/**
+	 * A weak set of the known search scopes.
+	 */
+	protected WeakHashMap searchScopes = new WeakHashMap();
+
+	public static class PerProjectInfo {
+		private static final int JAVADOC_CACHE_INITIAL_SIZE = 10;
+
+		static final IJavaModelStatus NEED_RESOLUTION = new JavaModelStatus();
+
+		public IProject project;
+		public Object savedState;
+		public boolean triedRead;
+		public IClasspathEntry[] rawClasspath;
+		public IClasspathEntry[] referencedEntries;
+		public IJavaModelStatus rawClasspathStatus;
+		public int rawTimeStamp = 0;
+		public boolean writtingRawClasspath = false;
+		public IClasspathEntry[] resolvedClasspath;
+		public IJavaModelStatus unresolvedEntryStatus;
+		public Map rootPathToRawEntries; // reverse map from a package fragment root's path to the raw entry
+		public Map rootPathToResolvedEntries; // map from a package fragment root's path to the resolved entry
+		public IPath outputLocation;
+
+		public IEclipsePreferences preferences;
+		public Hashtable options;
+		public Hashtable secondaryTypes;
+		public LRUCache javadocCache;
+
+		public PerProjectInfo(IProject project) {
+
+			this.triedRead = false;
+			this.savedState = null;
+			this.project = project;
+			this.javadocCache = new LRUCache(JAVADOC_CACHE_INITIAL_SIZE);
+		}
+
+		public synchronized IClasspathEntry[] getResolvedClasspath() {
+			if (this.unresolvedEntryStatus == NEED_RESOLUTION)
+				return null;
+			return this.resolvedClasspath;
+		}
+		
+		public void forgetExternalTimestampsAndIndexes() {
+			IClasspathEntry[] classpath = this.resolvedClasspath;
+			if (classpath == null) return;
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			IndexManager indexManager = manager.indexManager;
+			Map externalTimeStamps = manager.deltaState.getExternalLibTimeStamps();
+			HashMap rootInfos = JavaModelManager.getDeltaState().otherRoots;
+			for (int i = 0, length = classpath.length; i < length; i++) {
+				IClasspathEntry entry = classpath[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+					IPath path = entry.getPath();
+					if (rootInfos.get(path) == null) {
+						externalTimeStamps.remove(path);
+						indexManager.removeIndex(path); // force reindexing on next reference (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=250083 )
+					}
+				}
+			}
+		}
+
+		public void rememberExternalLibTimestamps() {
+			IClasspathEntry[] classpath = this.resolvedClasspath;
+			if (classpath == null) return;
+			Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaState.getExternalLibTimeStamps();
+			for (int i = 0, length = classpath.length; i < length; i++) {
+				IClasspathEntry entry = classpath[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+					IPath path = entry.getPath();
+					if (externalTimeStamps.get(path) == null) {
+						Object target = JavaModel.getExternalTarget(path, true);
+						if (target instanceof File) {
+							long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target);
+							externalTimeStamps.put(path, new Long(timestamp));
+						}
+					}
+				}
+			}
+		}
+
+		public synchronized ClasspathChange resetResolvedClasspath() {
+			// clear non-chaining jars cache and invalid jars cache
+			JavaModelManager.getJavaModelManager().resetClasspathListCache();
+			
+			// null out resolved information
+			return setResolvedClasspath(null, null, null, null, this.rawTimeStamp, true/*add classpath change*/);
+		}
+
+		private ClasspathChange setClasspath(IClasspathEntry[] newRawClasspath, IClasspathEntry[] referencedEntries, IPath newOutputLocation, IJavaModelStatus newRawClasspathStatus, IClasspathEntry[] newResolvedClasspath, Map newRootPathToRawEntries, Map newRootPathToResolvedEntries, IJavaModelStatus newUnresolvedEntryStatus, boolean addClasspathChange) {
+			ClasspathChange classpathChange = addClasspathChange ? addClasspathChange() : null;
+
+			if (referencedEntries != null)	this.referencedEntries = referencedEntries;
+			if (this.referencedEntries == null) this.referencedEntries = ClasspathEntry.NO_ENTRIES;
+			this.rawClasspath = newRawClasspath;
+			this.outputLocation = newOutputLocation;
+			this.rawClasspathStatus = newRawClasspathStatus;
+			this.resolvedClasspath = newResolvedClasspath;
+			this.rootPathToRawEntries = newRootPathToRawEntries;
+			this.rootPathToResolvedEntries = newRootPathToResolvedEntries;
+			this.unresolvedEntryStatus = newUnresolvedEntryStatus;
+			this.javadocCache = new LRUCache(JAVADOC_CACHE_INITIAL_SIZE);
+
+			return classpathChange;
+		}
+
+		protected ClasspathChange addClasspathChange() {
+			// remember old info
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			ClasspathChange classpathChange = manager.deltaState.addClasspathChange(this.project, this.rawClasspath, this.outputLocation, this.resolvedClasspath);
+			return classpathChange;
+		}
+
+		public ClasspathChange setRawClasspath(IClasspathEntry[] newRawClasspath, IPath newOutputLocation, IJavaModelStatus newRawClasspathStatus) {
+			return setRawClasspath(newRawClasspath, null, newOutputLocation, newRawClasspathStatus);
+		}
+
+		public synchronized ClasspathChange setRawClasspath(IClasspathEntry[] newRawClasspath, IClasspathEntry[] referencedEntries, IPath newOutputLocation, IJavaModelStatus newRawClasspathStatus) {
+			this.rawTimeStamp++;
+			return setClasspath(newRawClasspath, referencedEntries, newOutputLocation, newRawClasspathStatus, null/*resolved classpath*/, null/*root to raw map*/, null/*root to resolved map*/, null/*unresolved status*/, true/*add classpath change*/);
+		}
+
+		public ClasspathChange setResolvedClasspath(IClasspathEntry[] newResolvedClasspath, Map newRootPathToRawEntries, Map newRootPathToResolvedEntries, IJavaModelStatus newUnresolvedEntryStatus, int timeStamp, boolean addClasspathChange) {
+			return setResolvedClasspath(newResolvedClasspath, null, newRootPathToRawEntries, newRootPathToResolvedEntries, newUnresolvedEntryStatus, timeStamp, addClasspathChange);
+		}
+		
+		public synchronized ClasspathChange setResolvedClasspath(IClasspathEntry[] newResolvedClasspath, IClasspathEntry[] referencedEntries, Map newRootPathToRawEntries, Map newRootPathToResolvedEntries, IJavaModelStatus newUnresolvedEntryStatus, int timeStamp, boolean addClasspathChange) {
+			if (this.rawTimeStamp != timeStamp)
+				return null;
+			return setClasspath(this.rawClasspath, referencedEntries, this.outputLocation, this.rawClasspathStatus, newResolvedClasspath, newRootPathToRawEntries, newRootPathToResolvedEntries, newUnresolvedEntryStatus, addClasspathChange);
+		}
+
+		/**
+		 * Reads the classpath and caches the entries. Returns a two-dimensional array, where the number of elements in the row is fixed to 2.
+		 * The first element is an array of raw classpath entries and the second element is an array of referenced entries that may have been stored
+		 * by the client earlier. See {@link IJavaProject#getReferencedClasspathEntries()} for more details. 
+		 * 
+		 */		
+		public synchronized IClasspathEntry[][] readAndCacheClasspath(JavaProject javaProject) {
+			// read file entries and update status
+			IClasspathEntry[][] classpath;
+			IJavaModelStatus status;
+			try {
+				classpath = javaProject.readFileEntriesWithException(null/*not interested in unknown elements*/);
+				status = JavaModelStatus.VERIFIED_OK;
+			} catch (CoreException e) {
+				classpath = new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+				status =
+					new JavaModelStatus(
+						IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+						Messages.bind(Messages.classpath_cannotReadClasspathFile, javaProject.getElementName()));
+			} catch (IOException e) {
+				classpath = new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+				if (Messages.file_badFormat.equals(e.getMessage()))
+					status =
+						new JavaModelStatus(
+							IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+							Messages.bind(Messages.classpath_xmlFormatError, javaProject.getElementName(), Messages.file_badFormat));
+				else
+					status =
+						new JavaModelStatus(
+							IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+							Messages.bind(Messages.classpath_cannotReadClasspathFile, javaProject.getElementName()));
+			} catch (ClasspathEntry.AssertionFailedException e) {
+				classpath = new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+				status =
+					new JavaModelStatus(
+						IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
+						Messages.bind(Messages.classpath_illegalEntryInClasspathFile, new String[] {javaProject.getElementName(), e.getMessage()}));
+			}
+
+			// extract out the output location
+			int rawClasspathLength = classpath[0].length;
+			IPath output = null;
+			if (rawClasspathLength > 0) {
+				IClasspathEntry entry = classpath[0][rawClasspathLength - 1];
+				if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+					output = entry.getPath();
+					IClasspathEntry[] copy = new IClasspathEntry[rawClasspathLength - 1];
+					System.arraycopy(classpath[0], 0, copy, 0, copy.length);
+					classpath[0] = copy;
+				}
+			}
+
+			// store new raw classpath, new output and new status, and null out resolved info
+			setRawClasspath(classpath[0], classpath[1], output, status);
+
+			return classpath;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("Info for "); //$NON-NLS-1$
+			buffer.append(this.project.getFullPath());
+			buffer.append("\nRaw classpath:\n"); //$NON-NLS-1$
+			if (this.rawClasspath == null) {
+				buffer.append("  <null>\n"); //$NON-NLS-1$
+			} else {
+				for (int i = 0, length = this.rawClasspath.length; i < length; i++) {
+					buffer.append("  "); //$NON-NLS-1$
+					buffer.append(this.rawClasspath[i]);
+					buffer.append('\n');
+				}
+			}
+			buffer.append("Resolved classpath:\n"); //$NON-NLS-1$
+			IClasspathEntry[] resolvedCP = this.resolvedClasspath;
+			if (resolvedCP == null) {
+				buffer.append("  <null>\n"); //$NON-NLS-1$
+			} else {
+				for (int i = 0, length = resolvedCP.length; i < length; i++) {
+					buffer.append("  "); //$NON-NLS-1$
+					buffer.append(resolvedCP[i]);
+					buffer.append('\n');
+				}
+			}
+			buffer.append("Resolved classpath status: "); //$NON-NLS-1$
+			if (this.unresolvedEntryStatus == NEED_RESOLUTION)
+				buffer.append("NEED RESOLUTION"); //$NON-NLS-1$
+			else
+				buffer.append(this.unresolvedEntryStatus == null ? "<null>\n" : this.unresolvedEntryStatus.toString()); //$NON-NLS-1$
+			buffer.append("Output location:\n  "); //$NON-NLS-1$
+			if (this.outputLocation == null) {
+				buffer.append("<null>"); //$NON-NLS-1$
+			} else {
+				buffer.append(this.outputLocation);
+			}
+			return buffer.toString();
+		}
+
+		public boolean writeAndCacheClasspath(
+				JavaProject javaProject, 
+				final IClasspathEntry[] newRawClasspath, 
+				IClasspathEntry[] newReferencedEntries,
+				final IPath newOutputLocation) throws JavaModelException {
+			try {
+				this.writtingRawClasspath = true;
+				if (newReferencedEntries == null) newReferencedEntries = this.referencedEntries;
+				
+				// write .classpath
+				if (!javaProject.writeFileEntries(newRawClasspath, newReferencedEntries,  newOutputLocation)) {
+					return false;
+				}
+				// store new raw classpath, new output and new status, and null out resolved info
+				setRawClasspath(newRawClasspath, newReferencedEntries, newOutputLocation, JavaModelStatus.VERIFIED_OK);
+			} finally {
+				this.writtingRawClasspath = false;
+			}
+			return true;
+		}
+		
+		public boolean writeAndCacheClasspath(JavaProject javaProject, final IClasspathEntry[] newRawClasspath, final IPath newOutputLocation) throws JavaModelException {
+			return writeAndCacheClasspath(javaProject, newRawClasspath, null, newOutputLocation);
+		}
+
+	}
+
+	public static class PerWorkingCopyInfo implements IProblemRequestor {
+		int useCount = 0;
+		IProblemRequestor problemRequestor;
+		CompilationUnit workingCopy;
+		public PerWorkingCopyInfo(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
+			this.workingCopy = workingCopy;
+			this.problemRequestor = problemRequestor;
+		}
+		public void acceptProblem(IProblem problem) {
+			IProblemRequestor requestor = getProblemRequestor();
+			if (requestor == null) return;
+			requestor.acceptProblem(problem);
+		}
+		public void beginReporting() {
+			IProblemRequestor requestor = getProblemRequestor();
+			if (requestor == null) return;
+			requestor.beginReporting();
+		}
+		public void endReporting() {
+			IProblemRequestor requestor = getProblemRequestor();
+			if (requestor == null) return;
+			requestor.endReporting();
+		}
+		public IProblemRequestor getProblemRequestor() {
+			if (this.problemRequestor == null && this.workingCopy.owner != null) {
+				return this.workingCopy.owner.getProblemRequestor(this.workingCopy);
+			}
+			return this.problemRequestor;
+		}
+		public ICompilationUnit getWorkingCopy() {
+			return this.workingCopy;
+		}
+		public boolean isActive() {
+			IProblemRequestor requestor = getProblemRequestor();
+			return requestor != null && requestor.isActive();
+		}
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append("Info for "); //$NON-NLS-1$
+			buffer.append(((JavaElement)this.workingCopy).toStringWithAncestors());
+			buffer.append("\nUse count = "); //$NON-NLS-1$
+			buffer.append(this.useCount);
+			buffer.append("\nProblem requestor:\n  "); //$NON-NLS-1$
+			buffer.append(this.problemRequestor);
+			if (this.problemRequestor == null) {
+				IProblemRequestor requestor = getProblemRequestor();
+				buffer.append("\nOwner problem requestor:\n  "); //$NON-NLS-1$
+				buffer.append(requestor);
+			}
+			return buffer.toString();
+		}
+	}
+
+	public static boolean VERBOSE = false;
+	public static boolean CP_RESOLVE_VERBOSE = false;
+	public static boolean CP_RESOLVE_VERBOSE_ADVANCED = false;
+	public static boolean CP_RESOLVE_VERBOSE_FAILURE = false;
+	public static boolean ZIP_ACCESS_VERBOSE = false;
+	
+	/**
+	 * A cache of opened zip files per thread.
+	 * (for a given thread, the object value is a HashMap from IPath to java.io.ZipFile)
+	 */
+	private ThreadLocal zipFiles = new ThreadLocal();
+
+	private UserLibraryManager userLibraryManager;
+	
+	/*
+	 * List of IPath of jars that are known to not contain a chaining (through MANIFEST.MF) to another library
+	 */
+	private Set nonChainingJars;
+	
+	/*
+	 * List of IPath of jars that are known to be invalid - such as not being a valid/known format
+	 */
+	private Set invalidArchives;
+
+	/**
+	 * Update the classpath variable cache
+	 */
+	public static class EclipsePreferencesListener implements IEclipsePreferences.IPreferenceChangeListener {
+		/**
+         * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent)
+         */
+        public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) {
+        	String propertyName = event.getKey();
+        	if (propertyName.startsWith(JavaCore.PLUGIN_ID)) {
+	        	if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) {
+	        		String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length());
+	        		JavaModelManager manager = getJavaModelManager();
+	        		if (manager.variablesWithInitializer.contains(varName)) {
+	        			// revert preference value as we will not apply it to JavaCore classpath variable
+	        			String oldValue = (String) event.getOldValue();
+	        			if (oldValue == null) {
+	        				// unexpected old value => remove variable from set
+	        				manager.variablesWithInitializer.remove(varName);
+	        			} else {
+	        				manager.getInstancePreferences().put(varName, oldValue);
+	        			}
+	        		} else {
+	        			String newValue = (String)event.getNewValue();
+	        			IPath newPath;
+	        			if (newValue != null && !(newValue = newValue.trim()).equals(CP_ENTRY_IGNORE)) {
+	        				newPath = new Path(newValue);
+	        			} else {
+	        				newPath = null;
+	        			}
+	        			try {
+	        				SetVariablesOperation operation = new SetVariablesOperation(new String[] {varName}, new IPath[] {newPath}, false/*don't update preferences*/);
+	        				operation.runOperation(null/*no progress available*/);
+	        			} catch (JavaModelException e) {
+	        				Util.log(e, "Could not set classpath variable " + varName + " to " + newPath); //$NON-NLS-1$ //$NON-NLS-2$
+	        			}
+	        		}
+	        	} else if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)) {
+	        		recreatePersistedContainer(propertyName, (String)event.getNewValue(), false);
+	        	} else if (propertyName.equals(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER) ||
+					propertyName.equals(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER) ||
+					propertyName.equals(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE) ||
+					propertyName.equals(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER) ||
+					propertyName.equals(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH) ||
+					propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS) ||
+					propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) ||
+					propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) ||
+					propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) ||
+					propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) ||
+					propertyName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM) ||
+					propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE)) {
+					JavaModelManager manager = JavaModelManager.getJavaModelManager();
+					IJavaModel model = manager.getJavaModel();
+					IJavaProject[] projects;
+					try {
+						projects = model.getJavaProjects();
+						for (int i = 0, pl = projects.length; i < pl; i++) {
+							JavaProject javaProject = (JavaProject) projects[i];
+							manager.deltaState.addClasspathValidation(javaProject);
+							try {
+								// need to touch the project to force validation by DeltaProcessor
+					            javaProject.getProject().touch(null);
+					        } catch (CoreException e) {
+					            // skip
+					        }
+						}
+					} catch (JavaModelException e) {
+						// skip
+					}
+	        	} else if (propertyName.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) {
+					String libName = propertyName.substring(CP_USERLIBRARY_PREFERENCES_PREFIX.length());
+					UserLibraryManager manager = JavaModelManager.getUserLibraryManager();
+	        		manager.updateUserLibrary(libName, (String)event.getNewValue());
+	        	}
+	        }
+        	// Reset all project caches (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568 )
+        	try {
+        		IJavaProject[] projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+	        	for (int i = 0, length = projects.length; i < length; i++) {
+					((JavaProject) projects[i]).resetCaches();
+				}
+        	} catch (JavaModelException e) {
+        		// cannot retrieve Java projects
+        	}
+        }
+	}
+	/**
+	 * Listener on eclipse preferences changes.
+	 */
+	EclipsePreferencesListener instancePreferencesListener = new EclipsePreferencesListener();
+	/**
+	 * Listener on eclipse preferences default/instance node changes.
+	 */
+	IEclipsePreferences.INodeChangeListener instanceNodeListener = new IEclipsePreferences.INodeChangeListener() {
+		public void added(IEclipsePreferences.NodeChangeEvent event) {
+			// do nothing
+		}
+		public void removed(IEclipsePreferences.NodeChangeEvent event) {
+			if (event.getChild() == JavaModelManager.this.preferencesLookup[PREF_INSTANCE]) {
+				JavaModelManager.this.preferencesLookup[PREF_INSTANCE] = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+				JavaModelManager.this.preferencesLookup[PREF_INSTANCE].addPreferenceChangeListener(new EclipsePreferencesListener());
+			}
+		}
+	};
+	IEclipsePreferences.INodeChangeListener defaultNodeListener = new IEclipsePreferences.INodeChangeListener() {
+		public void added(IEclipsePreferences.NodeChangeEvent event) {
+			// do nothing
+		}
+		public void removed(IEclipsePreferences.NodeChangeEvent event) {
+			if (event.getChild() == JavaModelManager.this.preferencesLookup[PREF_DEFAULT]) {
+				JavaModelManager.this.preferencesLookup[PREF_DEFAULT] = DefaultScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+			}
+		}
+	};
+	/**
+	 * Listener on properties changes.
+	 */
+	IEclipsePreferences.IPreferenceChangeListener propertyListener;
+	IEclipsePreferences.IPreferenceChangeListener resourcesPropertyListener;
+
+	/**
+	 * Constructs a new JavaModelManager
+	 */
+	private JavaModelManager() {
+		// singleton: prevent others from creating a new instance
+		/*
+		 * It is required to initialize all fields that depends on a headless environment
+		 * only if the platform is running. Otherwise this breaks the ability to use
+		 * ASTParser in a non-headless environment.
+		 */
+		if (Platform.isRunning()) {
+			this.indexManager = new IndexManager();
+			this.nonChainingJars = loadClasspathListCache(NON_CHAINING_JARS_CACHE);
+			this.invalidArchives = loadClasspathListCache(INVALID_ARCHIVES_CACHE);
+			String includeContainerReferencedLib = System.getProperty(RESOLVE_REFERENCED_LIBRARIES_FOR_CONTAINERS);
+			this.resolveReferencedLibrariesForContainers = TRUE.equalsIgnoreCase(includeContainerReferencedLib);
+		}
+	}
+
+	/**
+	 * @deprecated
+	 */
+	private void addDeprecatedOptions(Hashtable options) {
+		options.put(JavaCore.COMPILER_PB_INVALID_IMPORT, JavaCore.ERROR);
+		options.put(JavaCore.COMPILER_PB_UNREACHABLE_CODE, JavaCore.ERROR);
+	}
+	
+	public void addNonChainingJar(IPath path) {
+		if (this.nonChainingJars != null)
+			this.nonChainingJars.add(path);
+	}
+	
+	public void addInvalidArchive(IPath path) {
+		// unlikely to be null
+		if (this.invalidArchives == null) {
+			this.invalidArchives = Collections.synchronizedSet(new HashSet());
+		}
+		if(this.invalidArchives != null) {
+			this.invalidArchives.add(path);
+		}
+	}
+
+	/**
+	 * Starts caching ZipFiles.
+	 * Ignores if there are already clients.
+	 */
+	public void cacheZipFiles(Object owner) {
+		ZipCache zipCache = (ZipCache) this.zipFiles.get();
+		if (zipCache != null) {
+			return;
+		}
+		// the owner will be responsible for flushing the cache
+		this.zipFiles.set(new ZipCache(owner));
+	}
+
+	public void closeZipFile(ZipFile zipFile) {
+		if (zipFile == null) return;
+		if (this.zipFiles.get() != null) {
+			return; // zip file will be closed by call to flushZipFiles
+		}
+		try {
+			if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [JavaModelManager.closeZipFile(ZipFile)] Closing ZipFile on " +zipFile.getName()); //$NON-NLS-1$	//$NON-NLS-2$
+			}
+			zipFile.close();
+		} catch (IOException e) {
+			// problem occured closing zip file: cannot do much more
+		}
+	}
+
+	/**
+	 * Configure the plugin with respect to option settings defined in ".options" file
+	 */
+	public void configurePluginDebugOptions(){
+		if(JavaCore.getPlugin().isDebugging()){
+			String option = Platform.getDebugOption(BUFFER_MANAGER_DEBUG);
+			if(option != null) BufferManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(BUILDER_DEBUG);
+			if(option != null) JavaBuilder.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(COMPILER_DEBUG);
+			if(option != null) Compiler.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(BUILDER_STATS_DEBUG);
+			if(option != null) JavaBuilder.SHOW_STATS = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(COMPLETION_DEBUG);
+			if(option != null) CompletionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(CP_RESOLVE_DEBUG);
+			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(CP_RESOLVE_ADVANCED_DEBUG);
+			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(CP_RESOLVE_FAILURE_DEBUG);
+			if(option != null) JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(DELTA_DEBUG);
+			if(option != null) DeltaProcessor.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(DELTA_DEBUG_VERBOSE);
+			if(option != null) DeltaProcessor.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(DOM_AST_DEBUG);
+			if(option != null) SourceRangeVerifier.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(DOM_AST_DEBUG_THROW);
+			if(option != null) {
+				SourceRangeVerifier.DEBUG_THROW = option.equalsIgnoreCase(TRUE) ;
+				SourceRangeVerifier.DEBUG |= SourceRangeVerifier.DEBUG_THROW;
+			}
+			
+			option = Platform.getDebugOption(DOM_REWRITE_DEBUG);
+			if(option != null) RewriteEventStore.DEBUG = option.equalsIgnoreCase(TRUE) ;
+			
+			option = Platform.getDebugOption(HIERARCHY_DEBUG);
+			if(option != null) TypeHierarchy.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(INDEX_MANAGER_DEBUG);
+			if(option != null) JobManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(INDEX_MANAGER_ADVANCED_DEBUG);
+			if(option != null) IndexManager.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(JAVAMODEL_DEBUG);
+			if(option != null) JavaModelManager.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(JAVAMODELCACHE_DEBUG);
+			if(option != null) JavaModelCache.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(POST_ACTION_DEBUG);
+			if(option != null) JavaModelOperation.POST_ACTION_VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(RESOLUTION_DEBUG);
+			if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(SEARCH_DEBUG);
+			if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(SELECTION_DEBUG);
+			if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
+			if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE);
+			if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase(TRUE) ;
+
+			option = Platform.getDebugOption(FORMATTER_DEBUG);
+			if(option != null) DefaultCodeFormatter.DEBUG = option.equalsIgnoreCase(TRUE) ;
+		}
+
+		// configure performance options
+		if(PerformanceStats.ENABLED) {
+			CompletionEngine.PERF = PerformanceStats.isEnabled(COMPLETION_PERF);
+			SelectionEngine.PERF = PerformanceStats.isEnabled(SELECTION_PERF);
+			DeltaProcessor.PERF = PerformanceStats.isEnabled(DELTA_LISTENER_PERF);
+			JavaModelManager.PERF_VARIABLE_INITIALIZER = PerformanceStats.isEnabled(VARIABLE_INITIALIZER_PERF);
+			JavaModelManager.PERF_CONTAINER_INITIALIZER = PerformanceStats.isEnabled(CONTAINER_INITIALIZER_PERF);
+			ReconcileWorkingCopyOperation.PERF = PerformanceStats.isEnabled(RECONCILE_PERF);
+		}
+	}
+
+	/*
+	 * Return a new Java 6 annotation processor manager.  The manager will need to
+	 * be configured before it can be used.  Returns null if a manager cannot be
+	 * created, i.e. if the current VM does not support Java 6 annotation processing.
+	 */
+	public AbstractAnnotationProcessorManager createAnnotationProcessorManager() {
+		synchronized(this) {
+			if (this.annotationProcessorManagerFactory == null) {
+				IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, ANNOTATION_PROCESSOR_MANAGER_EXTPOINT_ID);
+				if (extension == null)
+					return null;
+				IExtension[] extensions = extension.getExtensions();
+				for(int i = 0; i < extensions.length; i++) {
+					if (i > 0) {
+						Util.log(null, "An annotation processor manager is already registered: ignoring " + extensions[i].getUniqueIdentifier()); //$NON-NLS-1$
+						break;
+					}
+					IConfigurationElement[] configElements = extensions[i].getConfigurationElements();
+					for(int j = 0; j < configElements.length; j++) {
+						final IConfigurationElement configElement = configElements[j];
+						if ("annotationProcessorManager".equals(configElement.getName())) { //$NON-NLS-1$
+							this.annotationProcessorManagerFactory = configElement;
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		if (this.annotationProcessorManagerFactory == null) {
+			return null;
+		}
+		final AbstractAnnotationProcessorManager[] apm = new AbstractAnnotationProcessorManager[1];
+		apm[0] = null;
+		final IConfigurationElement factory = this.annotationProcessorManagerFactory;
+		SafeRunner.run(new ISafeRunnable() {
+			public void handleException(Throwable exception) {
+				Util.log(exception, "Exception occurred while loading annotation processor manager"); //$NON-NLS-1$
+			}
+			public void run() throws Exception {
+				Object executableExtension = factory.createExecutableExtension("class"); //$NON-NLS-1$
+				if (executableExtension instanceof AbstractAnnotationProcessorManager) {
+					apm[0] = (AbstractAnnotationProcessorManager) executableExtension;
+				}
+			}
+		});
+		return apm[0];
+	}
+
+	/*
+	 * Discards the per working copy info for the given working copy (making it a compilation unit)
+	 * if its use count was 1. Otherwise, just decrement the use count.
+	 * If the working copy is primary, computes the delta between its state and the original compilation unit
+	 * and register it.
+	 * Close the working copy, its buffer and remove it from the shared working copy table.
+	 * Ignore if no per-working copy info existed.
+	 * NOTE: it must NOT be synchronized as it may interact with the element info cache (if useCount is decremented to 0), see bug 50667.
+	 * Returns the new use count (or -1 if it didn't exist).
+	 */
+	public int discardPerWorkingCopyInfo(CompilationUnit workingCopy) throws JavaModelException {
+
+		// create the delta builder (this remembers the current content of the working copy)
+		// outside the perWorkingCopyInfos lock (see bug 50667)
+		JavaElementDeltaBuilder deltaBuilder = null;
+		if (workingCopy.isPrimary() && workingCopy.hasUnsavedChanges()) {
+			deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
+		}
+		PerWorkingCopyInfo info = null;
+		synchronized(this.perWorkingCopyInfos) {
+			WorkingCopyOwner owner = workingCopy.owner;
+			Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner);
+			if (workingCopyToInfos == null) return -1;
+
+			info = (PerWorkingCopyInfo)workingCopyToInfos.get(workingCopy);
+			if (info == null) return -1;
+
+			if (--info.useCount == 0) {
+				// remove per working copy info
+				workingCopyToInfos.remove(workingCopy);
+				if (workingCopyToInfos.isEmpty()) {
+					this.perWorkingCopyInfos.remove(owner);
+				}
+			}
+		}
+		if (info.useCount == 0) { // info cannot be null here (check was done above)
+			// remove infos + close buffer (since no longer working copy)
+			// outside the perWorkingCopyInfos lock (see bug 50667)
+			removeInfoAndChildren(workingCopy);
+			workingCopy.closeBuffer();
+
+			// compute the delta if needed and register it if there are changes
+			if (deltaBuilder != null) {
+				deltaBuilder.buildDeltas();
+				if (deltaBuilder.delta != null) {
+					getDeltaProcessor().registerJavaModelDelta(deltaBuilder.delta);
+				}
+			}
+		}
+		return info.useCount;
+	}
+
+	/**
+	 * @see ISaveParticipant
+	 */
+	public void doneSaving(ISaveContext context){
+		// nothing to do for jdt.core
+	}
+
+	/**
+	 * Flushes ZipFiles cache if there are no more clients.
+	 */
+	public void flushZipFiles(Object owner) {
+		ZipCache zipCache = (ZipCache)this.zipFiles.get();
+		if (zipCache == null) {
+			return;
+		}
+		// the owner will be responsible for flushing the cache
+		// we want to check object identity to make sure this is the owner that created the cache
+		if (zipCache.owner == owner) {
+			this.zipFiles.set(null);
+			zipCache.flush();
+		}
+	}
+
+	/*
+	 * Returns true if forcing batch initialization was successful.
+	 * Returns false if batch initialization is already running.
+	 */
+	public synchronized boolean forceBatchInitializations(boolean initAfterLoad) {
+		switch (this.batchContainerInitializations) {
+		case NO_BATCH_INITIALIZATION:
+			this.batchContainerInitializations = NEED_BATCH_INITIALIZATION;
+			return true;
+		case BATCH_INITIALIZATION_FINISHED:
+			if (initAfterLoad)
+				return false; // no need to initialize again
+			this.batchContainerInitializations = NEED_BATCH_INITIALIZATION;
+			return true;
+		}
+		return false;
+	}
+
+	private synchronized boolean batchContainerInitializations() {
+		switch (this.batchContainerInitializations) {
+		case NEED_BATCH_INITIALIZATION:
+			this.batchContainerInitializations = BATCH_INITIALIZATION_IN_PROGRESS;
+			return true;
+		case BATCH_INITIALIZATION_IN_PROGRESS:
+			return true;
+		}
+		return false;
+	}
+
+	private synchronized void batchInitializationFinished() {
+		this.batchContainerInitializations = BATCH_INITIALIZATION_FINISHED;
+	}
+
+	public IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException {
+
+		IClasspathContainer container = containerGet(project, containerPath);
+
+		if (container == null) {
+			if (batchContainerInitializations()) {
+				// avoid deep recursion while initializing container on workspace restart
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=60437)
+				try {
+					container = initializeAllContainers(project, containerPath);
+				} finally {
+					batchInitializationFinished();
+				}
+			} else {
+				container = initializeContainer(project, containerPath);
+				containerBeingInitializedRemove(project, containerPath);
+				SetContainerOperation operation = new SetContainerOperation(containerPath, new IJavaProject[] {project}, new IClasspathContainer[] {container});
+				operation.runOperation(null);
+			}
+		}
+		return container;
+	}
+
+	public IClasspathEntry[] getReferencedClasspathEntries(IClasspathEntry libraryEntry, IJavaProject project) {
+		
+		IClasspathEntry[] referencedEntries = ((ClasspathEntry)libraryEntry).resolvedChainedLibraries();
+		
+		if (project == null)
+			return referencedEntries;
+		
+		PerProjectInfo perProjectInfo = getPerProjectInfo(project.getProject(), false);
+		if(perProjectInfo == null) 
+			return referencedEntries;
+		
+		List pathToReferencedEntries = new ArrayList(referencedEntries.length);
+		for (int index = 0; index < referencedEntries.length; index++) {
+
+			if (pathToReferencedEntries.contains(referencedEntries[index].getPath()))
+				continue;
+
+			IClasspathEntry persistedEntry = null;
+			if ((persistedEntry = (IClasspathEntry)perProjectInfo.rootPathToResolvedEntries.get(referencedEntries[index].getPath())) != null) {
+				// TODO: reconsider this - may want to copy the values instead of reference assignment?
+				referencedEntries[index] = persistedEntry;
+			}
+			pathToReferencedEntries.add(referencedEntries[index].getPath());
+		}
+		return referencedEntries;
+	}
+	
+	public DeltaProcessor getDeltaProcessor() {
+		return this.deltaState.getDeltaProcessor();
+	}
+
+	public static DeltaProcessingState getDeltaState() {
+		return MANAGER.deltaState;
+	}
+
+	/**
+	 * Returns the set of elements which are out of synch with their buffers.
+	 */
+	protected HashSet getElementsOutOfSynchWithBuffers() {
+		return this.elementsOutOfSynchWithBuffers;
+	}
+
+	public static ExternalFoldersManager getExternalManager() {
+		return MANAGER.externalFoldersManager;
+	}
+
+	public static IndexManager getIndexManager() {
+		return MANAGER.indexManager;
+	}
+
+	/**
+	 *  Returns the info for the element.
+	 */
+	public synchronized Object getInfo(IJavaElement element) {
+		HashMap tempCache = (HashMap)this.temporaryCache.get();
+		if (tempCache != null) {
+			Object result = tempCache.get(element);
+			if (result != null) {
+				return result;
+			}
+		}
+		return this.cache.getInfo(element);
+	}
+
+	/**
+	 *  Returns the existing element in the cache that is equal to the given element.
+	 */
+	public synchronized IJavaElement getExistingElement(IJavaElement element) {
+		return this.cache.getExistingElement(element);
+	}
+
+	public HashSet getExternalWorkingCopyProjects() {
+		synchronized (this.perWorkingCopyInfos) {
+			HashSet result = null;
+			Iterator values = this.perWorkingCopyInfos.values().iterator();
+			while (values.hasNext()) {
+				Map ownerCopies = (Map) values.next();
+				Iterator workingCopies = ownerCopies.keySet().iterator();
+				while (workingCopies.hasNext()) {
+					ICompilationUnit workingCopy = (ICompilationUnit) workingCopies.next();
+					IJavaProject project = workingCopy.getJavaProject();
+					if (project.getElementName().equals(ExternalJavaProject.EXTERNAL_PROJECT_NAME)) {
+						if (result == null)
+							result = new HashSet();
+						result.add(project);
+					}
+				}
+			}
+			return result;
+		}
+	}
+
+	/**
+	 * Get workspace eclipse preference for JavaCore plug-in.
+	 */
+	public IEclipsePreferences getInstancePreferences() {
+		return this.preferencesLookup[PREF_INSTANCE];
+	}
+
+	// If modified, also modify the method getDefaultOptionsNoInitialization()
+	public Hashtable getDefaultOptions(){
+
+		Hashtable defaultOptions = new Hashtable(10);
+
+		// see JavaCorePreferenceInitializer#initializeDefaultPluginPreferences() for changing default settings
+		// If modified, also modify the method getDefaultOptionsNoInitialization()
+		IEclipsePreferences defaultPreferences = getDefaultPreferences();
+
+		// initialize preferences to their default
+		Iterator iterator = this.optionNames.iterator();
+		while (iterator.hasNext()) {
+		    String propertyName = (String) iterator.next();
+		    String value = defaultPreferences.get(propertyName, null);
+		    if (value != null) defaultOptions.put(propertyName, value);
+		}
+		// get encoding through resource plugin
+		defaultOptions.put(JavaCore.CORE_ENCODING, JavaCore.getEncoding());
+		// backward compatibility
+		addDeprecatedOptions(defaultOptions);
+
+		return defaultOptions;
+	}
+
+	/**
+	 * Get default eclipse preference for JavaCore plugin.
+	 */
+	public IEclipsePreferences getDefaultPreferences() {
+		return this.preferencesLookup[PREF_DEFAULT];
+	}
+
+	/**
+	 * Returns the handle to the active Java Model.
+	 */
+	public final JavaModel getJavaModel() {
+		return this.javaModel;
+	}
+
+	/**
+	 * Returns the singleton JavaModelManager
+	 */
+	public final static JavaModelManager getJavaModelManager() {
+		return MANAGER;
+	}
+
+	/**
+	 * Returns the last built state for the given project, or null if there is none.
+	 * Deserializes the state if necessary.
+	 *
+	 * For use by image builder and evaluation support only
+	 */
+	public Object getLastBuiltState(IProject project, IProgressMonitor monitor) {
+		if (!JavaProject.hasJavaNature(project)) {
+			if (JavaBuilder.DEBUG)
+				System.out.println(project + " is not a Java project"); //$NON-NLS-1$
+			return null; // should never be requested on non-Java projects
+		}
+		PerProjectInfo info = getPerProjectInfo(project, true/*create if missing*/);
+		if (!info.triedRead) {
+			info.triedRead = true;
+			try {
+				if (monitor != null)
+					monitor.subTask(Messages.bind(Messages.build_readStateProgress, project.getName()));
+				info.savedState = readState(project);
+			} catch (CoreException e) {
+				e.printStackTrace();
+			}
+		}
+		return info.savedState;
+	}
+
+	public String getOption(String optionName) {
+
+		if (JavaCore.CORE_ENCODING.equals(optionName)){
+			return JavaCore.getEncoding();
+		}
+		// backward compatibility
+		if (isDeprecatedOption(optionName)) {
+			return JavaCore.ERROR;
+		}
+		int optionLevel = getOptionLevel(optionName);
+		if (optionLevel != UNKNOWN_OPTION){
+			IPreferencesService service = Platform.getPreferencesService();
+			String value = service.get(optionName, null, this.preferencesLookup);
+			if (value == null && optionLevel == DEPRECATED_OPTION) {
+				// May be a deprecated option, retrieve the new value in compatible options
+				String[] compatibleOptions = (String[]) this.deprecatedOptions.get(optionName);
+				value = service.get(compatibleOptions[0], null, this.preferencesLookup);
+			}
+			return value==null ? null : value.trim();
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the value of the given option for the given Eclipse preferences.
+	 * If no value was already set, then inherits from the global options if specified.
+	 *
+	 * @param optionName The name of the option
+	 * @param inheritJavaCoreOptions Tells whether the value can be inherited from global JavaCore options
+	 * @param projectPreferences The eclipse preferences from which to get the value
+	 * @return The value of the option. May be <code>null</code>
+	 */
+	public String getOption(String optionName, boolean inheritJavaCoreOptions, IEclipsePreferences projectPreferences) {
+		// Return the option value depending on its level
+		switch (getOptionLevel(optionName)) {
+			case VALID_OPTION:
+				// Valid option, return the preference value
+				String javaCoreDefault = inheritJavaCoreOptions ? JavaCore.getOption(optionName) : null;
+				if (projectPreferences == null) return javaCoreDefault;
+				String value = projectPreferences.get(optionName, javaCoreDefault);
+				return value == null ? null : value.trim();
+			case DEPRECATED_OPTION:
+				// Return the deprecated option value if it was already set
+				String oldValue = projectPreferences.get(optionName, null);
+				if (oldValue != null) {
+					return oldValue.trim();
+				}
+				// Get the new compatible value
+				String[] compatibleOptions = (String[]) this.deprecatedOptions.get(optionName);
+				String newDefault = inheritJavaCoreOptions ? JavaCore.getOption(compatibleOptions[0]) : null;
+				String newValue = projectPreferences.get(compatibleOptions[0], newDefault);
+				return newValue == null ? null : newValue.trim();
+		}
+		return null;
+	}
+
+	/**
+	 * Returns whether an option name is known or not.
+	 * 
+	 * @param optionName The name of the option
+	 * @return <code>true</code> when the option name is either
+	 * {@link #VALID_OPTION valid} or {@link #DEPRECATED_OPTION deprecated},
+	 * <code>false</code> otherwise.
+	 */
+	public boolean knowsOption(String optionName) {
+		boolean knownOption = this.optionNames.contains(optionName);
+		if (!knownOption) {
+			knownOption = this.deprecatedOptions.get(optionName) != null;
+		}
+		return knownOption;
+	}
+
+	/**
+	 * Returns the level of the given option.
+	 * 
+	 * @param optionName The name of the option
+	 * @return The level of the option as an int which may have the following
+	 * values:
+	 * <ul>
+	 * <li>{@link #UNKNOWN_OPTION}: the given option is unknown</li>
+	 * <li>{@link #DEPRECATED_OPTION}: the given option is deprecated</li>
+	 * <li>{@link #VALID_OPTION}: the given option is valid</li>
+	 * </ul>
+	 */
+	public int getOptionLevel(String optionName) {
+		if (this.optionNames.contains(optionName)) {
+			return VALID_OPTION;
+		}
+		if (this.deprecatedOptions.get(optionName) != null) {
+			return DEPRECATED_OPTION;
+		}
+		return UNKNOWN_OPTION;
+	}
+
+	public Hashtable getOptions() {
+
+		// return cached options if already computed
+		Hashtable cachedOptions; // use a local variable to avoid race condition (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=256329 )
+		if ((cachedOptions = this.optionsCache) != null) {
+			return new Hashtable(cachedOptions);
+		}
+		if (!Platform.isRunning()) {
+			this.optionsCache = getDefaultOptionsNoInitialization();
+			return new Hashtable(this.optionsCache);
+		}
+		// init
+		Hashtable options = new Hashtable(10);
+		IPreferencesService service = Platform.getPreferencesService();
+
+		// set options using preferences service lookup
+		Iterator iterator = this.optionNames.iterator();
+		while (iterator.hasNext()) {
+			String propertyName = (String) iterator.next();
+			String propertyValue = service.get(propertyName, null, this.preferencesLookup);
+			if (propertyValue != null) {
+				options.put(propertyName, propertyValue);
+			}
+		}
+
+		// set deprecated options using preferences service lookup
+		Iterator deprecatedEntries = this.deprecatedOptions.entrySet().iterator();
+		while (deprecatedEntries.hasNext()) {
+			Entry entry = (Entry) deprecatedEntries.next();
+			String propertyName = (String) entry.getKey();
+			String propertyValue = service.get(propertyName, null, this.preferencesLookup);
+			if (propertyValue != null) {
+				options.put(propertyName, propertyValue);
+				String[] compatibleOptions = (String[]) entry.getValue();
+				for (int co=0, length=compatibleOptions.length; co < length; co++) {
+					String compatibleOption = compatibleOptions[co];
+					if (!options.containsKey(compatibleOption))
+						options.put(compatibleOption, propertyValue);
+				}
+			}
+		}
+
+		// get encoding through resource plugin
+		options.put(JavaCore.CORE_ENCODING, JavaCore.getEncoding());
+
+		// backward compatibility
+		addDeprecatedOptions(options);
+
+		Util.fixTaskTags(options);
+		// store built map in cache
+		this.optionsCache = new Hashtable(options);
+		// return built map
+		return options;
+	}
+
+	// Do not modify without modifying getDefaultOptions()
+	private Hashtable getDefaultOptionsNoInitialization() {
+		Map defaultOptionsMap = new CompilerOptions().getMap(); // compiler defaults
+
+		// Override some compiler defaults
+		defaultOptionsMap.put(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.GENERATE);
+		defaultOptionsMap.put(JavaCore.COMPILER_CODEGEN_UNUSED_LOCAL, JavaCore.PRESERVE);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_TAGS, JavaCore.DEFAULT_TASK_TAGS);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_PRIORITIES, JavaCore.DEFAULT_TASK_PRIORITIES);
+		defaultOptionsMap.put(JavaCore.COMPILER_TASK_CASE_SENSITIVE, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
+
+		// Builder settings
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, JavaCore.ABORT);
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, JavaCore.WARNING);
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, JavaCore.CLEAN);
+
+		// JavaCore settings
+		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_ORDER, JavaCore.IGNORE);
+		defaultOptionsMap.put(JavaCore.CORE_INCOMPLETE_CLASSPATH, JavaCore.ERROR);
+		defaultOptionsMap.put(JavaCore.CORE_CIRCULAR_CLASSPATH, JavaCore.ERROR);
+		defaultOptionsMap.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.IGNORE); 
+		defaultOptionsMap.put(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, JavaCore.ERROR);
+		defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS, JavaCore.ENABLED);
+
+		// Formatter settings
+		defaultOptionsMap.putAll(DefaultCodeFormatterConstants.getEclipseDefaultSettings());
+
+		// CodeAssist settings
+		defaultOptionsMap.put(JavaCore.CODEASSIST_VISIBILITY_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_DEPRECATION_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_IMPLICIT_QUALIFICATION, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_CAMEL_CASE_MATCH, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS, JavaCore.ENABLED);
+
+		// Time out for parameter names
+		defaultOptionsMap.put(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, "50"); //$NON-NLS-1$
+
+		return new Hashtable(defaultOptionsMap);
+	}
+
+	/*
+	 * Returns the per-project info for the given project. If specified, create the info if the info doesn't exist.
+	 */
+	public PerProjectInfo getPerProjectInfo(IProject project, boolean create) {
+		synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock
+			PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project);
+			if (info == null && create) {
+				info= new PerProjectInfo(project);
+				this.perProjectInfos.put(project, info);
+			}
+			return info;
+		}
+	}
+
+	/*
+	 * Returns  the per-project info for the given project.
+	 * If the info doesn't exist, check for the project existence and create the info.
+	 * @throws JavaModelException if the project doesn't exist.
+	 */
+	public PerProjectInfo getPerProjectInfoCheckExistence(IProject project) throws JavaModelException {
+		JavaModelManager.PerProjectInfo info = getPerProjectInfo(project, false /* don't create info */);
+		if (info == null) {
+			if (!JavaProject.hasJavaNature(project)) {
+				throw ((JavaProject)JavaCore.create(project)).newNotPresentException();
+			}
+			info = getPerProjectInfo(project, true /* create info */);
+		}
+		return info;
+	}
+
+	/*
+	 * Returns the per-working copy info for the given working copy at the given path.
+	 * If it doesn't exist and if create, add a new per-working copy info with the given problem requestor.
+	 * If recordUsage, increment the per-working copy info's use count.
+	 * Returns null if it doesn't exist and not create.
+	 */
+	public PerWorkingCopyInfo getPerWorkingCopyInfo(CompilationUnit workingCopy,boolean create, boolean recordUsage, IProblemRequestor problemRequestor) {
+		synchronized(this.perWorkingCopyInfos) { // use the perWorkingCopyInfo collection as its own lock
+			WorkingCopyOwner owner = workingCopy.owner;
+			Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner);
+			if (workingCopyToInfos == null && create) {
+				workingCopyToInfos = new HashMap();
+				this.perWorkingCopyInfos.put(owner, workingCopyToInfos);
+			}
+
+			PerWorkingCopyInfo info = workingCopyToInfos == null ? null : (PerWorkingCopyInfo) workingCopyToInfos.get(workingCopy);
+			if (info == null && create) {
+				info= new PerWorkingCopyInfo(workingCopy, problemRequestor);
+				workingCopyToInfos.put(workingCopy, info);
+			}
+			if (info != null && recordUsage) info.useCount++;
+			return info;
+		}
+	}
+
+	/**
+	 * Returns a persisted container from previous session if any. Note that it is not the original container from previous
+	 * session (i.e. it did not get serialized) but rather a summary of its entries recreated for CP initialization purpose.
+	 * As such it should not be stored into container caches.
+	 */
+	public IClasspathContainer getPreviousSessionContainer(IPath containerPath, IJavaProject project) {
+			Map previousContainerValues = (Map)this.previousSessionContainers.get(project);
+			if (previousContainerValues != null){
+			    IClasspathContainer previousContainer = (IClasspathContainer)previousContainerValues.get(containerPath);
+			    if (previousContainer != null) {
+					if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+						verbose_reentering_project_container_access(containerPath, project, previousContainer);
+					return previousContainer;
+			    }
+			}
+		    return null; // break cycle if none found
+	}
+
+	private void verbose_reentering_project_container_access(	IPath containerPath, IJavaProject project, IClasspathContainer previousContainer) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("CPContainer INIT - reentering access to project container during its initialization, will see previous value\n"); //$NON-NLS-1$
+		buffer.append("	project: " + project.getElementName() + '\n'); //$NON-NLS-1$
+		buffer.append("	container path: " + containerPath + '\n'); //$NON-NLS-1$
+		buffer.append("	previous value: "); //$NON-NLS-1$
+		buffer.append(previousContainer.getDescription());
+		buffer.append(" {\n"); //$NON-NLS-1$
+		IClasspathEntry[] entries = previousContainer.getClasspathEntries();
+		if (entries != null){
+			for (int j = 0; j < entries.length; j++){
+				buffer.append(" 		"); //$NON-NLS-1$
+				buffer.append(entries[j]);
+				buffer.append('\n');
+			}
+		}
+		buffer.append(" 	}"); //$NON-NLS-1$
+		Util.verbose(buffer.toString());
+		new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns a persisted container from previous session if any
+	 */
+	public IPath getPreviousSessionVariable(String variableName) {
+		IPath previousPath = (IPath)this.previousSessionVariables.get(variableName);
+		if (previousPath != null){
+			if (CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_reentering_variable_access(variableName, previousPath);
+			return previousPath;
+		}
+	    return null; // break cycle
+	}
+
+	private void verbose_reentering_variable_access(String variableName, IPath previousPath) {
+		Util.verbose(
+			"CPVariable INIT - reentering access to variable during its initialization, will see previous value\n" + //$NON-NLS-1$
+			"	variable: "+ variableName + '\n' + //$NON-NLS-1$
+			"	previous value: " + previousPath); //$NON-NLS-1$
+		new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the temporary cache for newly opened elements for the current thread.
+	 * Creates it if not already created.
+	 */
+	public HashMap getTemporaryCache() {
+		HashMap result = (HashMap)this.temporaryCache.get();
+		if (result == null) {
+			result = new HashMap();
+			this.temporaryCache.set(result);
+		}
+		return result;
+	}
+
+	private File getVariableAndContainersFile() {
+		return JavaCore.getPlugin().getStateLocation().append("variablesAndContainers.dat").toFile(); //$NON-NLS-1$
+	}
+
+	/**
+ 	 * Returns the name of the variables for which an CP variable initializer is registered through an extension point
+ 	 */
+	public static String[] getRegisteredVariableNames(){
+
+		Plugin jdtCorePlugin = JavaCore.getPlugin();
+		if (jdtCorePlugin == null) return null;
+
+		ArrayList variableList = new ArrayList(5);
+		IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.CPVARIABLE_INITIALIZER_EXTPOINT_ID);
+		if (extension != null) {
+			IExtension[] extensions =  extension.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for(int j = 0; j < configElements.length; j++){
+					String varAttribute = configElements[j].getAttribute("variable"); //$NON-NLS-1$
+					if (varAttribute != null) variableList.add(varAttribute);
+				}
+			}
+		}
+		String[] variableNames = new String[variableList.size()];
+		variableList.toArray(variableNames);
+		return variableNames;
+	}
+
+	/**
+ 	 * Returns the name of the container IDs for which an CP container initializer is registered through an extension point
+ 	 */
+	public static String[] getRegisteredContainerIDs(){
+
+		Plugin jdtCorePlugin = JavaCore.getPlugin();
+		if (jdtCorePlugin == null) return null;
+
+		ArrayList containerIDList = new ArrayList(5);
+		IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(JavaCore.PLUGIN_ID, JavaModelManager.CPCONTAINER_INITIALIZER_EXTPOINT_ID);
+		if (extension != null) {
+			IExtension[] extensions =  extension.getExtensions();
+			for(int i = 0; i < extensions.length; i++){
+				IConfigurationElement [] configElements = extensions[i].getConfigurationElements();
+				for(int j = 0; j < configElements.length; j++){
+					String idAttribute = configElements[j].getAttribute("id"); //$NON-NLS-1$
+					if (idAttribute != null) containerIDList.add(idAttribute);
+				}
+			}
+		}
+		String[] containerIDs = new String[containerIDList.size()];
+		containerIDList.toArray(containerIDs);
+		return containerIDs;
+	}
+
+	public IClasspathEntry resolveVariableEntry(IClasspathEntry entry, boolean usePreviousSession) {
+
+		if (entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE)
+			return entry;
+
+		IPath resolvedPath = getResolvedVariablePath(entry.getPath(), usePreviousSession);
+		if (resolvedPath == null)
+			return null;
+		// By passing a null reference path, we keep it relative to workspace root.
+		resolvedPath = ClasspathEntry.resolveDotDot(null, resolvedPath);
+
+		Object target = JavaModel.getTarget(resolvedPath, false);
+		if (target == null)
+			return null;
+
+		// inside the workspace
+		if (target instanceof IResource) {
+			IResource resolvedResource = (IResource) target;
+			switch (resolvedResource.getType()) {
+
+				case IResource.PROJECT :
+					// internal project
+					return JavaCore.newProjectEntry(
+							resolvedPath,
+							entry.getAccessRules(),
+							entry.combineAccessRules(),
+							entry.getExtraAttributes(),
+							entry.isExported());
+				case IResource.FILE :
+					// internal binary archive
+					return JavaCore.newLibraryEntry(
+							resolvedPath,
+							getResolvedVariablePath(entry.getSourceAttachmentPath(), usePreviousSession),
+							getResolvedVariablePath(entry.getSourceAttachmentRootPath(), usePreviousSession),
+							entry.getAccessRules(),
+							entry.getExtraAttributes(),
+							entry.isExported());
+				case IResource.FOLDER :
+					// internal binary folder
+					return JavaCore.newLibraryEntry(
+							resolvedPath,
+							getResolvedVariablePath(entry.getSourceAttachmentPath(), usePreviousSession),
+							getResolvedVariablePath(entry.getSourceAttachmentRootPath(), usePreviousSession),
+							entry.getAccessRules(),
+							entry.getExtraAttributes(),
+							entry.isExported());
+			}
+		}
+		if (target instanceof File) {
+			File externalFile = JavaModel.getFile(target);
+			if (externalFile != null) {
+				// external binary archive
+				return JavaCore.newLibraryEntry(
+						resolvedPath,
+						getResolvedVariablePath(entry.getSourceAttachmentPath(), usePreviousSession),
+						getResolvedVariablePath(entry.getSourceAttachmentRootPath(), usePreviousSession),
+						entry.getAccessRules(),
+						entry.getExtraAttributes(),
+						entry.isExported());
+			} else {
+				// non-existing file
+				if (resolvedPath.isAbsolute()){
+					return JavaCore.newLibraryEntry(
+							resolvedPath,
+							getResolvedVariablePath(entry.getSourceAttachmentPath(), usePreviousSession),
+							getResolvedVariablePath(entry.getSourceAttachmentRootPath(), usePreviousSession),
+							entry.getAccessRules(),
+							entry.getExtraAttributes(),
+							entry.isExported());
+				}
+			}
+		}
+		return null;
+	}
+
+	public IPath getResolvedVariablePath(IPath variablePath, boolean usePreviousSession) {
+
+		if (variablePath == null)
+			return null;
+		int count = variablePath.segmentCount();
+		if (count == 0)
+			return null;
+
+		// lookup variable
+		String variableName = variablePath.segment(0);
+		IPath resolvedPath = usePreviousSession ? getPreviousSessionVariable(variableName) : JavaCore.getClasspathVariable(variableName);
+		if (resolvedPath == null)
+			return null;
+
+		// append path suffix
+		if (count > 1) {
+			resolvedPath = resolvedPath.append(variablePath.removeFirstSegments(1));
+		}
+		return resolvedPath;
+	}
+
+	/**
+	 * Returns the File to use for saving and restoring the last built state for the given project.
+	 */
+	private File getSerializationFile(IProject project) {
+		if (!project.exists()) return null;
+		IPath workingLocation = project.getWorkingLocation(JavaCore.PLUGIN_ID);
+		return workingLocation.append("state.dat").toFile(); //$NON-NLS-1$
+	}
+
+	public static UserLibraryManager getUserLibraryManager() {
+		if (MANAGER.userLibraryManager == null) {
+			UserLibraryManager libraryManager = new UserLibraryManager();
+			synchronized(MANAGER) {
+				if (MANAGER.userLibraryManager == null) { // ensure another library manager was not set while creating the instance above
+					MANAGER.userLibraryManager = libraryManager;
+				}
+			}
+		}
+		return MANAGER.userLibraryManager;
+	}
+
+	/*
+	 * Returns all the working copies which have the given owner.
+	 * Adds the working copies of the primary owner if specified.
+	 * Returns null if it has none.
+	 */
+	public ICompilationUnit[] getWorkingCopies(WorkingCopyOwner owner, boolean addPrimary) {
+		synchronized(this.perWorkingCopyInfos) {
+			ICompilationUnit[] primaryWCs = addPrimary && owner != DefaultWorkingCopyOwner.PRIMARY
+				? getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false)
+				: null;
+			Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner);
+			if (workingCopyToInfos == null) return primaryWCs;
+			int primaryLength = primaryWCs == null ? 0 : primaryWCs.length;
+			int size = workingCopyToInfos.size(); // note size is > 0 otherwise pathToPerWorkingCopyInfos would be null
+			ICompilationUnit[] result = new ICompilationUnit[primaryLength + size];
+			int index = 0;
+			if (primaryWCs != null) {
+				for (int i = 0; i < primaryLength; i++) {
+					ICompilationUnit primaryWorkingCopy = primaryWCs[i];
+					ICompilationUnit workingCopy = new CompilationUnit((PackageFragment) primaryWorkingCopy.getParent(), primaryWorkingCopy.getElementName(), owner);
+					if (!workingCopyToInfos.containsKey(workingCopy))
+						result[index++] = primaryWorkingCopy;
+				}
+				if (index != primaryLength)
+					System.arraycopy(result, 0, result = new ICompilationUnit[index+size], 0, index);
+			}
+			Iterator iterator = workingCopyToInfos.values().iterator();
+			while(iterator.hasNext()) {
+				result[index++] = ((JavaModelManager.PerWorkingCopyInfo)iterator.next()).getWorkingCopy();
+			}
+			return result;
+		}
+	}
+
+	public JavaWorkspaceScope getWorkspaceScope() {
+		if (this.workspaceScope == null) {
+			this.workspaceScope = new JavaWorkspaceScope();
+		}
+		return this.workspaceScope;
+	}
+
+	public void verifyArchiveContent(IPath path) throws CoreException {
+		if (isInvalidArchive(path)) {
+			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, new ZipException()));			
+		}
+		ZipFile file = getZipFile(path);
+		closeZipFile(file);
+	}
+	
+	/**
+	 * Returns the open ZipFile at the given path. If the ZipFile
+	 * does not yet exist, it is created, opened, and added to the cache
+	 * of open ZipFiles.
+	 *
+	 * The path must be a file system path if representing an external
+	 * zip/jar, or it must be an absolute workspace relative path if
+	 * representing a zip/jar inside the workspace.
+	 *
+	 * @exception CoreException If unable to create/open the ZipFile
+	 */
+	public ZipFile getZipFile(IPath path) throws CoreException {
+
+		if (isInvalidArchive(path))
+			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, new ZipException()));
+		
+		ZipCache zipCache;
+		ZipFile zipFile;
+		if ((zipCache = (ZipCache)this.zipFiles.get()) != null
+				&& (zipFile = zipCache.getCache(path)) != null) {
+			return zipFile;
+		}
+		File localFile = null;
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IResource file = root.findMember(path);
+		if (file != null) {
+			// internal resource
+			URI location;
+			if (file.getType() != IResource.FILE || (location = file.getLocationURI()) == null) {
+				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.file_notFound, path.toString()), null));
+			}
+			localFile = Util.toLocalFile(location, null/*no progress availaible*/);
+			if (localFile == null)
+				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.file_notFound, path.toString()), null));
+		} else {
+			// external resource -> it is ok to use toFile()
+			localFile= path.toFile();
+		}
+
+		try {
+			if (ZIP_ACCESS_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [JavaModelManager.getZipFile(IPath)] Creating ZipFile on " + localFile ); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			zipFile = new ZipFile(localFile);
+			if (zipCache != null) {
+				zipCache.setCache(path, zipFile);
+			}
+			return zipFile;
+		} catch (IOException e) {
+			addInvalidArchive(path);
+			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, e));
+		}
+	}
+
+	/*
+	 * Returns whether there is a temporary cache for the current thread.
+	 */
+	public boolean hasTemporaryCache() {
+		return this.temporaryCache.get() != null;
+	}
+
+	/*
+	 * Initialize all container at the same time as the given container.
+	 * Return the container for the given path and project.
+	 */
+	private IClasspathContainer initializeAllContainers(IJavaProject javaProjectToInit, IPath containerToInit) throws JavaModelException {
+		if (CP_RESOLVE_VERBOSE_ADVANCED)
+			verbose_batching_containers_initialization(javaProjectToInit, containerToInit);
+
+		// collect all container paths
+		final HashMap allContainerPaths = new HashMap();
+		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IProject project = projects[i];
+			if (!JavaProject.hasJavaNature(project)) continue;
+			IJavaProject javaProject = new JavaProject(project, getJavaModel());
+			HashSet paths = (HashSet) allContainerPaths.get(javaProject);
+			IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
+			for (int j = 0, length2 = rawClasspath.length; j < length2; j++) {
+				IClasspathEntry entry = rawClasspath[j];
+				IPath path = entry.getPath();
+				if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER
+						&& containerGet(javaProject, path) == null) {
+					if (paths == null) {
+						paths = new HashSet();
+						allContainerPaths.put(javaProject, paths);
+					}
+					paths.add(path);
+				}
+			}
+			/* TODO (frederic) put back when JDT/UI dummy project will be thrown away...
+			 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97524
+			 *
+			if (javaProject.equals(javaProjectToInit)) {
+				if (paths == null) {
+					paths = new HashSet();
+					allContainerPaths.put(javaProject, paths);
+				}
+				paths.add(containerToInit);
+			}
+			*/
+		}
+		// TODO (frederic) remove following block when JDT/UI dummy project will be thrown away...
+		if (javaProjectToInit != null) {
+			HashSet containerPaths = (HashSet) allContainerPaths.get(javaProjectToInit);
+			if (containerPaths == null) {
+				containerPaths = new HashSet();
+				allContainerPaths.put(javaProjectToInit, containerPaths);
+			}
+			containerPaths.add(containerToInit);
+		}
+		// end block
+
+		// initialize all containers
+		boolean ok = false;
+		try {
+			// if possible run inside an IWokspaceRunnable with AVOID_UPATE to avoid unwanted builds
+			// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=118507)
+			IWorkspaceRunnable runnable =
+				new IWorkspaceRunnable() {
+					public void run(IProgressMonitor monitor) throws CoreException {
+						try {
+							// Collect all containers
+							Set entrySet = allContainerPaths.entrySet();
+							int length = entrySet.size();
+							if (monitor != null)
+								monitor.beginTask("", length); //$NON-NLS-1$
+							Map.Entry[] entries = new Map.Entry[length]; // clone as the following will have a side effect
+							entrySet.toArray(entries);
+							for (int i = 0; i < length; i++) {
+								Map.Entry entry = entries[i];
+								IJavaProject javaProject = (IJavaProject) entry.getKey();
+								HashSet pathSet = (HashSet) entry.getValue();
+								if (pathSet == null) continue;
+								int length2 = pathSet.size();
+								IPath[] paths = new IPath[length2];
+								pathSet.toArray(paths); // clone as the following will have a side effect
+								for (int j = 0; j < length2; j++) {
+									IPath path = paths[j];
+									initializeContainer(javaProject, path);
+									IClasspathContainer container = containerBeingInitializedGet(javaProject, path);
+									if (container != null) {
+										containerPut(javaProject, path, container);
+									}
+								}
+								if (monitor != null)
+									monitor.worked(1);
+							}
+							
+							// Set all containers
+							Map perProjectContainers = (Map) JavaModelManager.this.containersBeingInitialized.get();
+							if (perProjectContainers != null) {
+								Iterator entriesIterator = perProjectContainers.entrySet().iterator();
+								while (entriesIterator.hasNext()) {
+									Map.Entry entry = (Map.Entry) entriesIterator.next();
+									IJavaProject project = (IJavaProject) entry.getKey();
+									HashMap perPathContainers = (HashMap) entry.getValue();
+									Iterator containersIterator = perPathContainers.entrySet().iterator();
+									while (containersIterator.hasNext()) {
+										Map.Entry containerEntry = (Map.Entry) containersIterator.next();
+										IPath containerPath = (IPath) containerEntry.getKey();
+										IClasspathContainer container = (IClasspathContainer) containerEntry.getValue();
+										SetContainerOperation operation = new SetContainerOperation(containerPath, new IJavaProject[] {project}, new IClasspathContainer[] {container});
+										operation.runOperation(monitor);
+									}
+								}
+								JavaModelManager.this.containersBeingInitialized.set(null);
+							}
+						} finally {
+							if (monitor != null)
+								monitor.done();
+						}
+					}
+				};
+			IProgressMonitor monitor = this.batchContainerInitializationsProgress;
+			IWorkspace workspace = ResourcesPlugin.getWorkspace();
+			if (workspace.isTreeLocked())
+				runnable.run(monitor);
+			else
+				workspace.run(
+					runnable,
+					null/*don't take any lock*/,
+					IWorkspace.AVOID_UPDATE,
+					monitor);
+			ok = true;
+		} catch (CoreException e) {
+			// ignore
+			Util.log(e, "Exception while initializing all containers"); //$NON-NLS-1$
+		} finally {
+			if (!ok) {
+				// if we're being traversed by an exception, ensure that that containers are
+				// no longer marked as initialization in progress
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=66437)
+				this.containerInitializationInProgress.set(null);
+			}
+		}
+
+		return containerGet(javaProjectToInit, containerToInit);
+	}
+
+	private void verbose_batching_containers_initialization(IJavaProject javaProjectToInit, IPath containerToInit) {
+		Util.verbose(
+			"CPContainer INIT - batching containers initialization\n" + //$NON-NLS-1$
+			"	project to init: " + (javaProjectToInit == null ? "null" : javaProjectToInit.getElementName()) + '\n' + //$NON-NLS-1$ //$NON-NLS-2$
+			"	container path to init: " + containerToInit); //$NON-NLS-1$
+	}
+
+	IClasspathContainer initializeContainer(IJavaProject project, IPath containerPath) throws JavaModelException {
+
+		IProgressMonitor monitor = this.batchContainerInitializationsProgress;
+		if (monitor != null && monitor.isCanceled())
+			throw new OperationCanceledException();
+
+		IClasspathContainer container = null;
+		final ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(containerPath.segment(0));
+		if (initializer != null){
+			if (CP_RESOLVE_VERBOSE)
+				verbose_triggering_container_initialization(project, containerPath, initializer);
+			if (CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_triggering_container_initialization_invocation_trace();
+			PerformanceStats stats = null;
+			if(JavaModelManager.PERF_CONTAINER_INITIALIZER) {
+				stats = PerformanceStats.getStats(JavaModelManager.CONTAINER_INITIALIZER_PERF, this);
+				stats.startRun(containerPath + " of " + project.getPath()); //$NON-NLS-1$
+			}
+			containerPut(project, containerPath, CONTAINER_INITIALIZATION_IN_PROGRESS); // avoid initialization cycles
+			boolean ok = false;
+			try {
+				if (monitor != null)
+					monitor.subTask(Messages.bind(Messages.javamodel_configuring, initializer.getDescription(containerPath, project)));
+
+				// let OperationCanceledException go through
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59363)
+				initializer.initialize(containerPath, project);
+
+				if (monitor != null)
+					monitor.subTask(""); //$NON-NLS-1$
+
+				// retrieve value (if initialization was successful)
+				container = containerBeingInitializedGet(project, containerPath);
+				if (container == null && containerGet(project, containerPath) == CONTAINER_INITIALIZATION_IN_PROGRESS) {
+					// initializer failed to do its job: redirect to the failure container
+					container = initializer.getFailureContainer(containerPath, project);
+					if (container == null) {
+						if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+							verbose_container_null_failure_container(project, containerPath, initializer);
+						return null; // break cycle
+					}
+					if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+						verbose_container_using_failure_container(project, containerPath, initializer);
+					containerPut(project, containerPath, container);
+				}
+				ok = true;
+			} catch (CoreException e) {
+				if (e instanceof JavaModelException) {
+					throw (JavaModelException) e;
+				} else {
+					throw new JavaModelException(e);
+				}
+			} catch (RuntimeException e) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+					e.printStackTrace();
+				throw e;
+			} catch (Error e) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+					e.printStackTrace();
+				throw e;
+			} finally {
+				if(JavaModelManager.PERF_CONTAINER_INITIALIZER) {
+					stats.endRun();
+				}
+				if (!ok) {
+					// just remove initialization in progress and keep previous session container so as to avoid a full build
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=92588
+					containerRemoveInitializationInProgress(project, containerPath);
+					if (CP_RESOLVE_VERBOSE || CP_RESOLVE_VERBOSE_FAILURE)
+						verbose_container_initialization_failed(project, containerPath, container, initializer);
+				}
+			}
+			if (CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_container_value_after_initialization(project, containerPath, container);
+		} else {
+			// create a dummy initializer and get the default failure container
+			container = (new ClasspathContainerInitializer() {
+				public void initialize(IPath path, IJavaProject javaProject) throws CoreException {
+					// not used
+				}
+			}).getFailureContainer(containerPath, project);
+			if (CP_RESOLVE_VERBOSE_ADVANCED || CP_RESOLVE_VERBOSE_FAILURE)
+				verbose_no_container_initializer_found(project, containerPath);
+		}
+		return container;
+	}
+
+	private void verbose_no_container_initializer_found(IJavaProject project, IPath containerPath) {
+		Util.verbose(
+			"CPContainer INIT - no initializer found\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath); //$NON-NLS-1$
+	}
+
+	private void verbose_container_value_after_initialization(IJavaProject project, IPath containerPath, IClasspathContainer container) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("CPContainer INIT - after resolution\n"); //$NON-NLS-1$
+		buffer.append("	project: " + project.getElementName() + '\n'); //$NON-NLS-1$
+		buffer.append("	container path: " + containerPath + '\n'); //$NON-NLS-1$
+		if (container != null){
+			buffer.append("	container: "+container.getDescription()+" {\n"); //$NON-NLS-2$//$NON-NLS-1$
+			IClasspathEntry[] entries = container.getClasspathEntries();
+			if (entries != null){
+				for (int i = 0; i < entries.length; i++) {
+					buffer.append("		" + entries[i] + '\n'); //$NON-NLS-1$
+				}
+			}
+			buffer.append("	}");//$NON-NLS-1$
+		} else {
+			buffer.append("	container: {unbound}");//$NON-NLS-1$
+		}
+		Util.verbose(buffer.toString());
+	}
+
+	private void verbose_container_initialization_failed(IJavaProject project, IPath containerPath, IClasspathContainer container, ClasspathContainerInitializer initializer) {
+		if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
+			Util.verbose(
+				"CPContainer INIT - FAILED (initializer did not initialize container)\n" + //$NON-NLS-1$
+				"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+				"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+				"	initializer: " + initializer); //$NON-NLS-1$
+
+		} else {
+			Util.verbose(
+				"CPContainer INIT - FAILED (see exception above)\n" + //$NON-NLS-1$
+				"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+				"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+				"	initializer: " + initializer); //$NON-NLS-1$
+		}
+	}
+
+	private void verbose_container_null_failure_container(IJavaProject project, IPath containerPath,  ClasspathContainerInitializer initializer) {
+		Util.verbose(
+			"CPContainer INIT - FAILED (and failure container is null)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	initializer: " + initializer); //$NON-NLS-1$
+	}
+
+	private void verbose_container_using_failure_container(IJavaProject project, IPath containerPath,  ClasspathContainerInitializer initializer) {
+		Util.verbose(
+			"CPContainer INIT - FAILED (using failure container)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	initializer: " + initializer); //$NON-NLS-1$
+	}
+
+	private void verbose_triggering_container_initialization(IJavaProject project, IPath containerPath,  ClasspathContainerInitializer initializer) {
+		Util.verbose(
+			"CPContainer INIT - triggering initialization\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+			"	initializer: " + initializer); //$NON-NLS-1$
+	}
+
+	private void verbose_triggering_container_initialization_invocation_trace() {
+		Util.verbose(
+			"CPContainer INIT - triggering initialization\n" + //$NON-NLS-1$
+			"	invocation trace:"); //$NON-NLS-1$
+		new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+	/**
+	 * Initialize preferences lookups for JavaCore plug-in.
+	 */
+	public void initializePreferences() {
+
+		// Create lookups
+		this.preferencesLookup[PREF_INSTANCE] = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+		this.preferencesLookup[PREF_DEFAULT] = DefaultScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+
+		// Listen to instance preferences node removal from parent in order to refresh stored one
+		this.instanceNodeListener = new IEclipsePreferences.INodeChangeListener() {
+			public void added(IEclipsePreferences.NodeChangeEvent event) {
+				// do nothing
+			}
+			public void removed(IEclipsePreferences.NodeChangeEvent event) {
+				if (event.getChild() == JavaModelManager.this.preferencesLookup[PREF_INSTANCE]) {
+					JavaModelManager.this.preferencesLookup[PREF_INSTANCE] = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+					JavaModelManager.this.preferencesLookup[PREF_INSTANCE].addPreferenceChangeListener(new EclipsePreferencesListener());
+				}
+			}
+		};
+		((IEclipsePreferences) this.preferencesLookup[PREF_INSTANCE].parent()).addNodeChangeListener(this.instanceNodeListener);
+		this.preferencesLookup[PREF_INSTANCE].addPreferenceChangeListener(this.instancePreferencesListener = new EclipsePreferencesListener());
+
+		// Listen to default preferences node removal from parent in order to refresh stored one
+		this.defaultNodeListener = new IEclipsePreferences.INodeChangeListener() {
+			public void added(IEclipsePreferences.NodeChangeEvent event) {
+				// do nothing
+			}
+			public void removed(IEclipsePreferences.NodeChangeEvent event) {
+				if (event.getChild() == JavaModelManager.this.preferencesLookup[PREF_DEFAULT]) {
+					JavaModelManager.this.preferencesLookup[PREF_DEFAULT] = DefaultScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+				}
+			}
+		};
+		((IEclipsePreferences) this.preferencesLookup[PREF_DEFAULT].parent()).addNodeChangeListener(this.defaultNodeListener);
+	}
+
+	public synchronized char[] intern(char[] array) {
+		return this.charArraySymbols.add(array);
+	}
+
+	public synchronized String intern(String s) {
+		// make sure to copy the string (so that it doesn't hold on the underlying char[] that might be much bigger than necessary)
+		return (String) this.stringSymbols.add(new String(s));
+
+		// Note1: String#intern() cannot be used as on some VMs this prevents the string from being garbage collected
+		// Note 2: Instead of using a WeakHashset, one could use a WeakHashMap with the following implementation
+		// 			   This would costs more per entry (one Entry object and one WeakReference more))
+
+		/*
+		WeakReference reference = (WeakReference) this.symbols.get(s);
+		String existing;
+		if (reference != null && (existing = (String) reference.get()) != null)
+			return existing;
+		this.symbols.put(s, new WeakReference(s));
+		return s;
+		*/
+	}
+
+	private HashSet getClasspathBeingResolved() {
+	    HashSet result = (HashSet) this.classpathsBeingResolved.get();
+	    if (result == null) {
+	        result = new HashSet();
+	        this.classpathsBeingResolved.set(result);
+	    }
+	    return result;
+	}
+
+	public boolean isClasspathBeingResolved(IJavaProject project) {
+	    return getClasspathBeingResolved().contains(project);
+	}
+
+	/**
+	 * @deprecated
+	 */
+	private boolean isDeprecatedOption(String optionName) {
+		return JavaCore.COMPILER_PB_INVALID_IMPORT.equals(optionName)
+				|| JavaCore.COMPILER_PB_UNREACHABLE_CODE.equals(optionName);
+	}
+	
+	public boolean isNonChainingJar(IPath path) {
+		return this.nonChainingJars != null && this.nonChainingJars.contains(path);
+	}
+	
+	public boolean isInvalidArchive(IPath path) {
+		return this.invalidArchives != null && this.invalidArchives.contains(path);
+	}
+
+	public void removeFromInvalidArchiveCache(IPath path) {
+		if (this.invalidArchives != null) {
+			this.invalidArchives.remove(path);
+		}
+	}
+
+	public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) {
+	    if (classpathIsResolved) {
+	        getClasspathBeingResolved().add(project);
+	    } else {
+	        getClasspathBeingResolved().remove(project);
+	    }
+	}
+	
+	private Set loadClasspathListCache(String cacheName) {
+		Set pathCache = new HashSet();
+		File cacheFile = getClasspathListFile(cacheName);
+		DataInputStream in = null;
+		try {
+			in = new DataInputStream(new BufferedInputStream(new FileInputStream(cacheFile)));
+			int size = in.readInt();
+			while (size-- > 0) {
+				String path = in.readUTF();
+				pathCache.add(Path.fromPortableString(path));
+			}
+		} catch (IOException e) {
+			if (cacheFile.exists())
+				Util.log(e, "Unable to read non-chaining jar cache file"); //$NON-NLS-1$
+		} finally {
+			if (in != null) {
+				try {
+					in.close();
+				} catch (IOException e) {
+					// nothing we can do: ignore
+				}
+			}
+		}
+		return Collections.synchronizedSet(pathCache);
+	}
+	
+	private File getClasspathListFile(String fileName) {
+		return JavaCore.getPlugin().getStateLocation().append(fileName).toFile(); 
+	}
+	
+	private Set getNonChainingJarsCache() throws CoreException {
+		// Even if there is one entry in the cache, just return it. It may not be 
+		// the complete cache, but avoid going through all the projects to populate the cache.
+		if (this.nonChainingJars != null && this.nonChainingJars.size() > 0) {
+			return this.nonChainingJars;
+		}
+		Set result = new HashSet();
+		IJavaProject[] projects = getJavaModel().getJavaProjects();
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IJavaProject javaProject = projects[i];
+			IClasspathEntry[] classpath = ((JavaProject) javaProject).getResolvedClasspath();
+			for (int j = 0, length2 = classpath.length; j < length2; j++) {
+				IClasspathEntry entry = classpath[j];
+				IPath path;
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY 
+					&& !result.contains(path = entry.getPath())
+					&& ClasspathEntry.resolvedChainedLibraries(path).length == 0) {
+						result.add(path);
+				}
+			}
+		}
+		this.nonChainingJars = Collections.synchronizedSet(result);
+		return this.nonChainingJars;
+	}
+	
+	private Set getClasspathListCache(String cacheName) throws CoreException {
+		if (cacheName == NON_CHAINING_JARS_CACHE) 
+			return getNonChainingJarsCache();
+		else if (cacheName == INVALID_ARCHIVES_CACHE)
+			return this.invalidArchives;
+		else 
+			return null;
+	}
+	
+	public void loadVariablesAndContainers() throws CoreException {
+		// backward compatibility, consider persistent property
+		QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$
+		String xmlString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
+
+		try {
+			if (xmlString != null){
+				StringReader reader = new StringReader(xmlString);
+				Element cpElement;
+				try {
+					DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+					cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+				} catch(SAXException e) {
+					return;
+				} catch(ParserConfigurationException e){
+					return;
+				} finally {
+					reader.close();
+				}
+				if (cpElement == null) return;
+				if (!cpElement.getNodeName().equalsIgnoreCase("variables")) { //$NON-NLS-1$
+					return;
+				}
+
+				NodeList list= cpElement.getChildNodes();
+				int length= list.getLength();
+				for (int i= 0; i < length; ++i) {
+					Node node= list.item(i);
+					short type= node.getNodeType();
+					if (type == Node.ELEMENT_NODE) {
+						Element element= (Element) node;
+						if (element.getNodeName().equalsIgnoreCase("variable")) { //$NON-NLS-1$
+							variablePut(
+								element.getAttribute("name"), //$NON-NLS-1$
+								new Path(element.getAttribute("path"))); //$NON-NLS-1$
+						}
+					}
+				}
+			}
+		} catch(IOException e){
+			// problem loading xml file: nothing we can do
+		} finally {
+			if (xmlString != null){
+				ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(qName, null); // flush old one
+			}
+		}
+
+		// backward compatibility, load variables and containers from preferences into cache
+		loadVariablesAndContainers(getDefaultPreferences());
+		loadVariablesAndContainers(getInstancePreferences());
+
+		// load variables and containers from saved file into cache
+		File file = getVariableAndContainersFile();
+		DataInputStream in = null;
+		try {
+			in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+			switch (in.readInt()) {
+				case 2 :
+					new VariablesAndContainersLoadHelper(in).load();
+					break;
+				case 1 : // backward compatibility, load old format
+					// variables
+					int size = in.readInt();
+					while (size-- > 0) {
+						String varName = in.readUTF();
+						String pathString = in.readUTF();
+						if (CP_ENTRY_IGNORE.equals(pathString))
+							continue;
+						IPath varPath = Path.fromPortableString(pathString);
+						this.variables.put(varName, varPath);
+						this.previousSessionVariables.put(varName, varPath);
+					}
+
+					// containers
+					IJavaModel model = getJavaModel();
+					int projectSize = in.readInt();
+					while (projectSize-- > 0) {
+						String projectName = in.readUTF();
+						IJavaProject project = model.getJavaProject(projectName);
+						int containerSize = in.readInt();
+						while (containerSize-- > 0) {
+							IPath containerPath = Path.fromPortableString(in.readUTF());
+							int length = in.readInt();
+							byte[] containerString = new byte[length];
+							in.readFully(containerString);
+							recreatePersistedContainer(project, containerPath, new String(containerString), true/*add to container values*/);
+						}
+					}
+					break;
+			}
+		} catch (IOException e) {
+			if (file.exists())
+				Util.log(e, "Unable to read variable and containers file"); //$NON-NLS-1$
+		} catch (RuntimeException e) {
+			if (file.exists())
+				Util.log(e, "Unable to read variable and containers file (file is corrupt)"); //$NON-NLS-1$
+		} finally {
+			if (in != null) {
+				try {
+					in.close();
+				} catch (IOException e) {
+					// nothing we can do: ignore
+				}
+			}
+		}
+
+		// override persisted values for variables which have a registered initializer
+		String[] registeredVariables = getRegisteredVariableNames();
+		for (int i = 0; i < registeredVariables.length; i++) {
+			String varName = registeredVariables[i];
+			this.variables.put(varName, null); // reset variable, but leave its entry in the Map, so it will be part of variable names.
+		}
+		// override persisted values for containers which have a registered initializer
+		containersReset(getRegisteredContainerIDs());
+	}
+
+	private void loadVariablesAndContainers(IEclipsePreferences preferences) {
+		try {
+			// only get variable from preferences not set to their default
+			String[] propertyNames = preferences.keys();
+			int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length();
+			for (int i = 0; i < propertyNames.length; i++){
+				String propertyName = propertyNames[i];
+				if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)){
+					String varName = propertyName.substring(variablePrefixLength);
+					String propertyValue = preferences.get(propertyName, null);
+					if (propertyValue != null) {
+						String pathString = propertyValue.trim();
+
+						if (CP_ENTRY_IGNORE.equals(pathString)) {
+							// cleanup old preferences
+							preferences.remove(propertyName);
+							continue;
+						}
+
+						// add variable to table
+						IPath varPath = new Path(pathString);
+						this.variables.put(varName, varPath);
+						this.previousSessionVariables.put(varName, varPath);
+					}
+				} else if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){
+					String propertyValue = preferences.get(propertyName, null);
+					if (propertyValue != null) {
+						// cleanup old preferences
+						preferences.remove(propertyName);
+
+						// recreate container
+						recreatePersistedContainer(propertyName, propertyValue, true/*add to container values*/);
+					}
+				}
+			}
+		} catch (BackingStoreException e1) {
+			// TODO (frederic) see if it's necessary to report this failure...
+		}
+	}
+
+	private static final class PersistedClasspathContainer implements
+			IClasspathContainer {
+
+		private final IPath containerPath;
+
+		private final IClasspathEntry[] entries;
+
+		private final IJavaProject project;
+
+		PersistedClasspathContainer(IJavaProject project, IPath containerPath,
+				IClasspathEntry[] entries) {
+			super();
+			this.containerPath = containerPath;
+			this.entries = entries;
+			this.project = project;
+		}
+
+		public IClasspathEntry[] getClasspathEntries() {
+			return this.entries;
+		}
+
+		public String getDescription() {
+			return "Persisted container [" + this.containerPath //$NON-NLS-1$
+					+ " for project [" + this.project.getElementName() //$NON-NLS-1$
+					+ "]]"; //$NON-NLS-1$
+		}
+
+		public int getKind() {
+			return 0;
+		}
+
+		public IPath getPath() {
+			return this.containerPath;
+		}
+
+		public String toString() {
+			return getDescription();
+		}
+	}
+
+	private final class VariablesAndContainersLoadHelper {
+
+		private static final int ARRAY_INCREMENT = 200;
+
+		private IClasspathEntry[] allClasspathEntries;
+		private int allClasspathEntryCount;
+
+		private final Map allPaths; // String -> IPath
+
+		private String[] allStrings;
+		private int allStringsCount;
+
+		private final DataInputStream in;
+
+		VariablesAndContainersLoadHelper(DataInputStream in) {
+			super();
+			this.allClasspathEntries = null;
+			this.allClasspathEntryCount = 0;
+			this.allPaths = new HashMap();
+			this.allStrings = null;
+			this.allStringsCount = 0;
+			this.in = in;
+		}
+
+		void load() throws IOException {
+			loadProjects(getJavaModel());
+			loadVariables();
+		}
+
+		private IAccessRule loadAccessRule() throws IOException {
+			int problemId = loadInt();
+			IPath pattern = loadPath();
+			return new ClasspathAccessRule(pattern.toString().toCharArray(), problemId);
+		}
+
+		private IAccessRule[] loadAccessRules() throws IOException {
+			int count = loadInt();
+
+			if (count == 0)
+				return ClasspathEntry.NO_ACCESS_RULES;
+
+			IAccessRule[] rules = new IAccessRule[count];
+
+			for (int i = 0; i < count; ++i)
+				rules[i] = loadAccessRule();
+
+			return rules;
+		}
+
+		private IClasspathAttribute loadAttribute() throws IOException {
+			String name = loadString();
+			String value = loadString();
+
+			return new ClasspathAttribute(name, value);
+		}
+
+		private IClasspathAttribute[] loadAttributes() throws IOException {
+			int count = loadInt();
+
+			if (count == 0)
+				return ClasspathEntry.NO_EXTRA_ATTRIBUTES;
+
+			IClasspathAttribute[] attributes = new IClasspathAttribute[count];
+
+			for (int i = 0; i < count; ++i)
+				attributes[i] = loadAttribute();
+
+			return attributes;
+		}
+
+		private boolean loadBoolean() throws IOException {
+			return this.in.readBoolean();
+		}
+
+		private IClasspathEntry[] loadClasspathEntries() throws IOException {
+			int count = loadInt();
+			IClasspathEntry[] entries = new IClasspathEntry[count];
+
+			for (int i = 0; i < count; ++i)
+				entries[i] = loadClasspathEntry();
+
+			return entries;
+		}
+
+		private IClasspathEntry loadClasspathEntry() throws IOException {
+			int id = loadInt();
+
+			if (id < 0 || id > this.allClasspathEntryCount)
+				throw new IOException("Unexpected classpathentry id"); //$NON-NLS-1$
+
+			if (id < this.allClasspathEntryCount)
+				return this.allClasspathEntries[id];
+
+			int contentKind = loadInt();
+			int entryKind = loadInt();
+			IPath path = loadPath();
+			IPath[] inclusionPatterns = loadPaths();
+			IPath[] exclusionPatterns = loadPaths();
+			IPath sourceAttachmentPath = loadPath();
+			IPath sourceAttachmentRootPath = loadPath();
+			IPath specificOutputLocation = loadPath();
+			boolean isExported = loadBoolean();
+			IAccessRule[] accessRules = loadAccessRules();
+			boolean combineAccessRules = loadBoolean();
+			IClasspathAttribute[] extraAttributes = loadAttributes();
+
+			IClasspathEntry entry = new ClasspathEntry(contentKind, entryKind,
+					path, inclusionPatterns, exclusionPatterns,
+					sourceAttachmentPath, sourceAttachmentRootPath,
+					specificOutputLocation, isExported, accessRules,
+					combineAccessRules, extraAttributes);
+
+			IClasspathEntry[] array = this.allClasspathEntries;
+
+			if (array == null || id == array.length) {
+				array = new IClasspathEntry[id + ARRAY_INCREMENT];
+
+				if (id != 0)
+					System.arraycopy(this.allClasspathEntries, 0, array, 0, id);
+
+				this.allClasspathEntries = array;
+			}
+
+			array[id] = entry;
+			this.allClasspathEntryCount = id + 1;
+
+			return entry;
+		}
+
+		private void loadContainers(IJavaProject project) throws IOException {
+			boolean projectIsAccessible = project.getProject().isAccessible();
+			int count = loadInt();
+			for (int i = 0; i < count; ++i) {
+				IPath path = loadPath();
+				IClasspathEntry[] entries = loadClasspathEntries();
+
+				if (!projectIsAccessible)
+					// avoid leaking deleted project's persisted container,
+					// but still read the container as it is is part of the file format
+					continue;
+
+				IClasspathContainer container = new PersistedClasspathContainer(project, path, entries);
+
+				containerPut(project, path, container);
+
+				Map oldContainers = (Map) JavaModelManager.this.previousSessionContainers.get(project);
+
+				if (oldContainers == null) {
+					oldContainers = new HashMap();
+					JavaModelManager.this.previousSessionContainers.put(project, oldContainers);
+				}
+
+				oldContainers.put(path, container);
+			}
+		}
+
+		private int loadInt() throws IOException {
+			return this.in.readInt();
+		}
+
+		private IPath loadPath() throws IOException {
+			if (loadBoolean())
+				return null;
+
+			String portableString = loadString();
+			IPath path = (IPath) this.allPaths.get(portableString);
+
+			if (path == null) {
+				path = Path.fromPortableString(portableString);
+				this.allPaths.put(portableString, path);
+			}
+
+			return path;
+		}
+
+		private IPath[] loadPaths() throws IOException {
+			int count = loadInt();
+			IPath[] pathArray = new IPath[count];
+
+			for (int i = 0; i < count; ++i)
+				pathArray[i] = loadPath();
+
+			return pathArray;
+		}
+
+		private void loadProjects(IJavaModel model) throws IOException {
+			int count = loadInt();
+
+			for (int i = 0; i < count; ++i) {
+				String projectName = loadString();
+
+				loadContainers(model.getJavaProject(projectName));
+			}
+		}
+
+		private String loadString() throws IOException {
+			int id = loadInt();
+
+			if (id < 0 || id > this.allStringsCount)
+				throw new IOException("Unexpected string id"); //$NON-NLS-1$
+
+			if (id < this.allStringsCount)
+				return this.allStrings[id];
+
+			String string = this.in.readUTF();
+			String[] array = this.allStrings;
+
+			if (array == null || id == array.length) {
+				array = new String[id + ARRAY_INCREMENT];
+
+				if (id != 0)
+					System.arraycopy(this.allStrings, 0, array, 0, id);
+
+				this.allStrings = array;
+			}
+
+			array[id] = string;
+			this.allStringsCount = id + 1;
+
+			return string;
+		}
+
+		private void loadVariables() throws IOException {
+			int size = loadInt();
+			Map loadedVars = new HashMap(size);
+
+			for (int i = 0; i < size; ++i) {
+				String varName = loadString();
+				IPath varPath = loadPath();
+
+				if (varPath != null)
+					loadedVars.put(varName, varPath);
+			}
+
+			JavaModelManager.this.previousSessionVariables.putAll(loadedVars);
+			JavaModelManager.this.variables.putAll(loadedVars);
+		}
+	}
+
+	/**
+	 *  Returns the info for this element without
+	 *  disturbing the cache ordering.
+	 */
+	protected synchronized Object peekAtInfo(IJavaElement element) {
+		HashMap tempCache = (HashMap)this.temporaryCache.get();
+		if (tempCache != null) {
+			Object result = tempCache.get(element);
+			if (result != null) {
+				return result;
+			}
+		}
+		return this.cache.peekAtInfo(element);
+	}
+
+	/**
+	 * @see ISaveParticipant
+	 */
+	public void prepareToSave(ISaveContext context) /*throws CoreException*/ {
+		// nothing to do
+	}
+	/*
+	 * Puts the infos in the given map (keys are IJavaElements and values are JavaElementInfos)
+	 * in the Java model cache in an atomic way if the info is not already present in the cache. 
+	 * If the info is already present in the cache, it depends upon the forceAdd parameter.
+	 * If forceAdd is false it just returns the existing info and if true, this element and it's children are closed and then 
+	 * this particular info is added to the cache.
+	 */
+	protected synchronized Object putInfos(IJavaElement openedElement, Object newInfo, boolean forceAdd, Map newElements) {
+		// remove existing children as the are replaced with the new children contained in newElements
+		Object existingInfo = this.cache.peekAtInfo(openedElement);
+		if (existingInfo != null && !forceAdd) {
+			// If forceAdd is false, then it could mean that the particular element 
+			// wasn't in cache at that point of time, but would have got added through 
+			// another thread. In that case, removing the children could remove it's own
+			// children. So, we should not remove the children but return the already existing 
+			// info.
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=372687
+			return existingInfo;
+		}
+		if (openedElement instanceof IParent) {
+			closeChildren(existingInfo);
+		}
+
+		// Need to put any JarPackageFragmentRoot in first.
+		// This is due to the way the LRU cache flushes entries.
+		// When a JarPackageFragment is flushed from the LRU cache, the entire
+		// jar is flushed by removing the JarPackageFragmentRoot and all of its
+		// children (see ElementCache.close()). If we flush the JarPackageFragment
+		// when its JarPackageFragmentRoot is not in the cache and the root is about to be
+		// added (during the 'while' loop), we will end up in an inconsistent state.
+		// Subsequent resolution against package in the jar would fail as a result.
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=102422
+		// (theodora)
+		for(Iterator it = newElements.entrySet().iterator(); it.hasNext(); ) {
+			Map.Entry entry = (Map.Entry)it.next();
+			IJavaElement element = (IJavaElement)entry.getKey();
+			if (element instanceof JarPackageFragmentRoot) {
+				Object info = entry.getValue();
+				it.remove();
+				this.cache.putInfo(element, info);
+			}
+		}
+
+		Iterator iterator = newElements.entrySet().iterator();
+		while (iterator.hasNext()) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			this.cache.putInfo((IJavaElement) entry.getKey(), entry.getValue());
+		}
+		return newInfo;
+	}
+
+	private void closeChildren(Object info) {
+		if (info instanceof JavaElementInfo) {
+			IJavaElement[] children = ((JavaElementInfo)info).getChildren();
+			for (int i = 0, size = children.length; i < size; ++i) {
+				JavaElement child = (JavaElement) children[i];
+				try {
+					child.close();
+				} catch (JavaModelException e) {
+					// ignore
+				}
+			}
+		}
+	}
+
+	/*
+	 * Remember the info for the jar binary type
+	 */
+	protected synchronized void putJarTypeInfo(IJavaElement type, Object info) {
+		this.cache.jarTypeCache.put(type, info);
+	}
+
+	/**
+	 * Reads the build state for the relevant project.
+	 */
+	protected Object readState(IProject project) throws CoreException {
+		File file = getSerializationFile(project);
+		if (file != null && file.exists()) {
+			try {
+				DataInputStream in= new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+				try {
+					String pluginID= in.readUTF();
+					if (!pluginID.equals(JavaCore.PLUGIN_ID))
+						throw new IOException(Messages.build_wrongFileFormat);
+					String kind= in.readUTF();
+					if (!kind.equals("STATE")) //$NON-NLS-1$
+						throw new IOException(Messages.build_wrongFileFormat);
+					if (in.readBoolean())
+						return JavaBuilder.readState(project, in);
+					if (JavaBuilder.DEBUG)
+						System.out.println("Saved state thinks last build failed for " + project.getName()); //$NON-NLS-1$
+				} finally {
+					in.close();
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$
+			}
+		} else if (JavaBuilder.DEBUG) {
+			if (file == null)
+				System.out.println("Project does not exist: " + project); //$NON-NLS-1$
+			else
+				System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return null;
+	}
+
+	public static void recreatePersistedContainer(String propertyName, String containerString, boolean addToContainerValues) {
+		int containerPrefixLength = CP_CONTAINER_PREFERENCES_PREFIX.length();
+		int index = propertyName.indexOf('|', containerPrefixLength);
+		if (containerString != null) containerString = containerString.trim();
+		if (index > 0) {
+			String projectName = propertyName.substring(containerPrefixLength, index).trim();
+			IJavaProject project = getJavaModelManager().getJavaModel().getJavaProject(projectName);
+			IPath containerPath = new Path(propertyName.substring(index+1).trim());
+			recreatePersistedContainer(project, containerPath, containerString, addToContainerValues);
+		}
+	}
+
+	private static void recreatePersistedContainer(final IJavaProject project, final IPath containerPath, String containerString, boolean addToContainerValues) {
+		if (!project.getProject().isAccessible()) return; // avoid leaking deleted project's persisted container
+		if (containerString == null) {
+			getJavaModelManager().containerPut(project, containerPath, null);
+		} else {
+			IClasspathEntry[] entries;
+			try {
+				entries = ((JavaProject) project).decodeClasspath(containerString, null/*not interested in unknown elements*/)[0];
+			} catch (IOException e) {
+				Util.log(e, "Could not recreate persisted container: \n" + containerString); //$NON-NLS-1$
+				entries = JavaProject.INVALID_CLASSPATH;
+			}
+			if (entries != JavaProject.INVALID_CLASSPATH) {
+				final IClasspathEntry[] containerEntries = entries;
+				IClasspathContainer container = new IClasspathContainer() {
+					public IClasspathEntry[] getClasspathEntries() {
+						return containerEntries;
+					}
+					public String getDescription() {
+						return "Persisted container ["+containerPath+" for project ["+ project.getElementName()+"]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+					}
+					public int getKind() {
+						return 0;
+					}
+					public IPath getPath() {
+						return containerPath;
+					}
+					public String toString() {
+						return getDescription();
+					}
+
+				};
+				if (addToContainerValues) {
+					getJavaModelManager().containerPut(project, containerPath, container);
+				}
+				Map projectContainers = (Map)getJavaModelManager().previousSessionContainers.get(project);
+				if (projectContainers == null){
+					projectContainers = new HashMap(1);
+					getJavaModelManager().previousSessionContainers.put(project, projectContainers);
+				}
+				projectContainers.put(containerPath, container);
+			}
+		}
+	}
+
+	/**
+	 * Remembers the given scope in a weak set
+	 * (so no need to remove it: it will be removed by the garbage collector)
+	 */
+	public void rememberScope(AbstractSearchScope scope) {
+		// NB: The value has to be null so as to not create a strong reference on the scope
+		this.searchScopes.put(scope, null);
+	}
+
+	/*
+	 * Removes all cached info for the given element (including all children)
+	 * from the cache.
+	 * Returns the info for the given element, or null if it was closed.
+	 */
+	public synchronized Object removeInfoAndChildren(JavaElement element) throws JavaModelException {
+		Object info = this.cache.peekAtInfo(element);
+		if (info != null) {
+			boolean wasVerbose = false;
+			try {
+				if (JavaModelCache.VERBOSE) {
+					String elementType;
+					switch (element.getElementType()) {
+						case IJavaElement.JAVA_PROJECT:
+							elementType = "project"; //$NON-NLS-1$
+							break;
+						case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+							elementType = "root"; //$NON-NLS-1$
+							break;
+						case IJavaElement.PACKAGE_FRAGMENT:
+							elementType = "package"; //$NON-NLS-1$
+							break;
+						case IJavaElement.CLASS_FILE:
+							elementType = "class file"; //$NON-NLS-1$
+							break;
+						case IJavaElement.COMPILATION_UNIT:
+							elementType = "compilation unit"; //$NON-NLS-1$
+							break;
+						default:
+							elementType = "element"; //$NON-NLS-1$
+					}
+					System.out.println(Thread.currentThread() + " CLOSING "+ elementType + " " + element.toStringWithAncestors());  //$NON-NLS-1$//$NON-NLS-2$
+					wasVerbose = true;
+					JavaModelCache.VERBOSE = false;
+				}
+				element.closing(info);
+				if (element instanceof IParent) {
+					closeChildren(info);
+				}
+				this.cache.removeInfo(element);
+				if (wasVerbose) {
+					System.out.println(this.cache.toStringFillingRation("-> ")); //$NON-NLS-1$
+				}
+			} finally {
+				JavaModelCache.VERBOSE = wasVerbose;
+			}
+			return info;
+		}
+		return null;
+	}
+
+	public void removePerProjectInfo(JavaProject javaProject, boolean removeExtJarInfo) {
+		synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock
+			IProject project = javaProject.getProject();
+			PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project);
+			if (info != null) {
+				this.perProjectInfos.remove(project);
+				if (removeExtJarInfo) {
+					info.forgetExternalTimestampsAndIndexes();
+				}
+			}
+		}
+		resetClasspathListCache();
+	}
+
+	/*
+	 * Reset project options stored in info cache.
+	 */
+	public void resetProjectOptions(JavaProject javaProject) {
+		synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock
+			IProject project = javaProject.getProject();
+			PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project);
+			if (info != null) {
+				info.options = null;
+			}
+		}
+	}
+
+	/*
+	 * Reset project preferences stored in info cache.
+	 */
+	public void resetProjectPreferences(JavaProject javaProject) {
+		synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock
+			IProject project = javaProject.getProject();
+			PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project);
+			if (info != null) {
+				info.preferences = null;
+			}
+		}
+	}
+
+	public static final void doNotUse() {
+		// used by tests to simulate a startup
+		MANAGER.deltaState.doNotUse();
+		MANAGER = new JavaModelManager();
+	}
+
+	/*
+	 * Resets the cache that holds on binary type in jar files
+	 */
+	protected synchronized void resetJarTypeCache() {
+		this.cache.resetJarTypeCache();
+	}
+	
+	public void resetClasspathListCache() {
+		if (this.nonChainingJars != null) 
+			this.nonChainingJars.clear();
+		if (this.invalidArchives != null) 
+			this.invalidArchives.clear();
+	}
+
+	/*
+	 * Resets the temporary cache for newly created elements to null.
+	 */
+	public void resetTemporaryCache() {
+		this.temporaryCache.set(null);
+	}
+
+	/**
+	 * @see ISaveParticipant
+	 */
+	public void rollback(ISaveContext context){
+		// nothing to do
+	}
+
+	private void saveState(PerProjectInfo info, ISaveContext context) throws CoreException {
+
+		// passed this point, save actions are non trivial
+		if (context.getKind() == ISaveContext.SNAPSHOT) return;
+
+		// save built state
+		if (info.triedRead) saveBuiltState(info);
+	}
+
+	/**
+	 * Saves the built state for the project.
+	 */
+	private void saveBuiltState(PerProjectInfo info) throws CoreException {
+		if (JavaBuilder.DEBUG)
+			System.out.println(Messages.bind(Messages.build_saveStateProgress, info.project.getName()));
+		File file = getSerializationFile(info.project);
+		if (file == null) return;
+		long t = System.currentTimeMillis();
+		try {
+			DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+			try {
+				out.writeUTF(JavaCore.PLUGIN_ID);
+				out.writeUTF("STATE"); //$NON-NLS-1$
+				if (info.savedState == null) {
+					out.writeBoolean(false);
+				} else {
+					out.writeBoolean(true);
+					JavaBuilder.writeState(info.savedState, out);
+				}
+			} finally {
+				out.close();
+			}
+		} catch (RuntimeException e) {
+			try {
+				file.delete();
+			} catch(SecurityException se) {
+				// could not delete file: cannot do much more
+			}
+			throw new CoreException(
+				new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+					Messages.bind(Messages.build_cannotSaveState, info.project.getName()), e));
+		} catch (IOException e) {
+			try {
+				file.delete();
+			} catch(SecurityException se) {
+				// could not delete file: cannot do much more
+			}
+			throw new CoreException(
+				new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
+					Messages.bind(Messages.build_cannotSaveState, info.project.getName()), e));
+		}
+		if (JavaBuilder.DEBUG) {
+			t = System.currentTimeMillis() - t;
+			System.out.println(Messages.bind(Messages.build_saveStateComplete, String.valueOf(t)));
+		}
+	}
+
+	private void saveClasspathListCache(String cacheName) throws CoreException {
+		File file = getClasspathListFile(cacheName);
+		DataOutputStream out = null;
+		try {
+			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+			Set pathCache = getClasspathListCache(cacheName);
+			synchronized (pathCache) {
+				out.writeInt(pathCache.size());
+				Iterator entries = pathCache.iterator();
+				while (entries.hasNext()) {
+					IPath path = (IPath) entries.next();
+					out.writeUTF(path.toPortableString());
+				}
+			}
+		} catch (IOException e) {
+			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving non-chaining jar cache", e); //$NON-NLS-1$
+			throw new CoreException(status);
+		} finally {
+			if (out != null) {
+				try {
+					out.close();
+				} catch (IOException e) {
+					// nothing we can do: ignore
+				}
+			}
+		}
+	}
+	
+	private void saveVariablesAndContainers(ISaveContext context) throws CoreException {
+		File file = getVariableAndContainersFile();
+		DataOutputStream out = null;
+		try {
+			out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+			out.writeInt(VARIABLES_AND_CONTAINERS_FILE_VERSION);
+			new VariablesAndContainersSaveHelper(out).save(context);
+		} catch (IOException e) {
+			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving variables and containers", e); //$NON-NLS-1$
+			throw new CoreException(status);
+		} finally {
+			if (out != null) {
+				try {
+					out.close();
+				} catch (IOException e) {
+					// nothing we can do: ignore
+				}
+			}
+		}
+	}
+
+	private final class VariablesAndContainersSaveHelper {
+
+		private final HashtableOfObjectToInt classpathEntryIds; // IClasspathEntry -> int
+		private final DataOutputStream out;
+		private final HashtableOfObjectToInt stringIds; // Strings -> int
+
+		VariablesAndContainersSaveHelper(DataOutputStream out) {
+			super();
+			this.classpathEntryIds = new HashtableOfObjectToInt();
+			this.out = out;
+			this.stringIds = new HashtableOfObjectToInt();
+		}
+
+		void save(ISaveContext context) throws IOException, JavaModelException {
+			saveProjects(getJavaModel().getJavaProjects());
+			// remove variables that should not be saved
+			HashMap varsToSave = null;
+			Iterator iterator = JavaModelManager.this.variables.entrySet().iterator();
+			IEclipsePreferences defaultPreferences = getDefaultPreferences();
+			while (iterator.hasNext()) {
+				Map.Entry entry = (Map.Entry) iterator.next();
+				String varName = (String) entry.getKey();
+				if (defaultPreferences.get(CP_VARIABLE_PREFERENCES_PREFIX + varName, null) != null // don't save classpath variables from the default preferences as there is no delta if they are removed
+						|| CP_ENTRY_IGNORE_PATH.equals(entry.getValue())) {
+
+					if (varsToSave == null)
+						varsToSave = new HashMap(JavaModelManager.this.variables);
+					varsToSave.remove(varName);
+				}
+			}
+			saveVariables(varsToSave != null ? varsToSave : JavaModelManager.this.variables);
+		}
+
+		private void saveAccessRule(ClasspathAccessRule rule) throws IOException {
+			saveInt(rule.problemId);
+			savePath(rule.getPattern());
+		}
+
+		private void saveAccessRules(IAccessRule[] rules) throws IOException {
+			int count = rules == null ? 0 : rules.length;
+
+			saveInt(count);
+			for (int i = 0; i < count; ++i)
+				saveAccessRule((ClasspathAccessRule) rules[i]);
+		}
+
+		private void saveAttribute(IClasspathAttribute attribute)
+				throws IOException {
+			saveString(attribute.getName());
+			saveString(attribute.getValue());
+		}
+
+		private void saveAttributes(IClasspathAttribute[] attributes)
+				throws IOException {
+			int count = attributes == null ? 0 : attributes.length;
+
+			saveInt(count);
+			for (int i = 0; i < count; ++i)
+				saveAttribute(attributes[i]);
+		}
+
+		private void saveClasspathEntries(IClasspathEntry[] entries)
+				throws IOException {
+			int count = entries == null ? 0 : entries.length;
+
+			saveInt(count);
+			for (int i = 0; i < count; ++i)
+				saveClasspathEntry(entries[i]);
+		}
+
+		private void saveClasspathEntry(IClasspathEntry entry)
+				throws IOException {
+			if (saveNewId(entry, this.classpathEntryIds)) {
+				saveInt(entry.getContentKind());
+				saveInt(entry.getEntryKind());
+				savePath(entry.getPath());
+				savePaths(entry.getInclusionPatterns());
+				savePaths(entry.getExclusionPatterns());
+				savePath(entry.getSourceAttachmentPath());
+				savePath(entry.getSourceAttachmentRootPath());
+				savePath(entry.getOutputLocation());
+				this.out.writeBoolean(entry.isExported());
+				saveAccessRules(entry.getAccessRules());
+				this.out.writeBoolean(entry.combineAccessRules());
+				saveAttributes(entry.getExtraAttributes());
+			}
+		}
+
+		private void saveContainers(IJavaProject project, Map containerMap)
+				throws IOException {
+			saveInt(containerMap.size());
+
+			for (Iterator i = containerMap.entrySet().iterator(); i.hasNext();) {
+				Entry entry = (Entry) i.next();
+				IPath path = (IPath) entry.getKey();
+				IClasspathContainer container = (IClasspathContainer) entry.getValue();
+				IClasspathEntry[] cpEntries = null;
+
+				if (container == null) {
+					// container has not been initialized yet, use previous
+					// session value
+					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=73969)
+					container = getPreviousSessionContainer(path, project);
+				}
+
+				if (container != null)
+					cpEntries = container.getClasspathEntries();
+
+				savePath(path);
+				saveClasspathEntries(cpEntries);
+			}
+		}
+
+		private void saveInt(int value) throws IOException {
+			this.out.writeInt(value);
+		}
+
+		private boolean saveNewId(Object key, HashtableOfObjectToInt map) throws IOException {
+			int id = map.get(key);
+
+			if (id == -1) {
+				int newId = map.size();
+
+				map.put(key, newId);
+
+				saveInt(newId);
+
+				return true;
+			} else {
+				saveInt(id);
+
+				return false;
+			}
+		}
+
+		private void savePath(IPath path) throws IOException {
+			if (path == null) {
+				this.out.writeBoolean(true);
+			} else {
+				this.out.writeBoolean(false);
+				saveString(path.toPortableString());
+			}
+		}
+
+		private void savePaths(IPath[] paths) throws IOException {
+			int count = paths == null ? 0 : paths.length;
+
+			saveInt(count);
+			for (int i = 0; i < count; ++i)
+				savePath(paths[i]);
+		}
+
+		private void saveProjects(IJavaProject[] projects) throws IOException,
+				JavaModelException {
+			int count = projects.length;
+
+			saveInt(count);
+
+			for (int i = 0; i < count; ++i) {
+				IJavaProject project = projects[i];
+
+				saveString(project.getElementName());
+
+				Map containerMap = (Map) JavaModelManager.this.containers.get(project);
+
+				if (containerMap == null) {
+					containerMap = Collections.EMPTY_MAP;
+				} else {
+					// clone while iterating
+					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
+					containerMap = new HashMap(containerMap);
+				}
+
+				saveContainers(project, containerMap);
+			}
+		}
+
+		private void saveString(String string) throws IOException {
+			if (saveNewId(string, this.stringIds))
+				this.out.writeUTF(string);
+		}
+
+		private void saveVariables(Map map) throws IOException {
+			saveInt(map.size());
+
+			for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
+				Entry entry = (Entry) i.next();
+				String varName = (String) entry.getKey();
+				IPath varPath = (IPath) entry.getValue();
+
+				saveString(varName);
+				savePath(varPath);
+			}
+		}
+	}
+
+	private void traceVariableAndContainers(String action, long start) {
+
+		Long delta = new Long(System.currentTimeMillis() - start);
+		Long length = new Long(getVariableAndContainersFile().length());
+		String pattern = "{0} {1} bytes in variablesAndContainers.dat in {2}ms"; //$NON-NLS-1$
+		String message = MessageFormat.format(pattern, new Object[]{action, length, delta});
+
+		System.out.println(message);
+	}
+
+	/**
+	 * @see ISaveParticipant
+	 */
+	public void saving(ISaveContext context) throws CoreException {
+
+	    long start = -1;
+		if (VERBOSE)
+			start = System.currentTimeMillis();
+
+		// save variable and container values on snapshot/full save
+		saveVariablesAndContainers(context);
+		
+		if (VERBOSE)
+			traceVariableAndContainers("Saved", start); //$NON-NLS-1$
+
+		switch(context.getKind()) {
+			case ISaveContext.FULL_SAVE : {
+				// save non-chaining jar and invalid jar caches on full save
+				saveClasspathListCache(NON_CHAINING_JARS_CACHE);
+				saveClasspathListCache(INVALID_ARCHIVES_CACHE);
+	
+				// will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658)
+				context.needDelta();
+	
+				// clean up indexes on workspace full save
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52347)
+				IndexManager manager = this.indexManager;
+				if (manager != null
+						// don't force initialization of workspace scope as we could be shutting down
+						// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93941)
+						&& this.workspaceScope != null) {
+					manager.cleanUpIndexes();
+				}
+			}
+			//$FALL-THROUGH$
+			case ISaveContext.SNAPSHOT : {
+				// clean up external folders on full save or snapshot
+				this.externalFoldersManager.cleanUp(null);
+			}
+		}
+
+		IProject savedProject = context.getProject();
+		if (savedProject != null) {
+			if (!JavaProject.hasJavaNature(savedProject)) return; // ignore
+			PerProjectInfo info = getPerProjectInfo(savedProject, true /* create info */);
+			saveState(info, context);
+			return;
+		}
+
+		ArrayList vStats= null; // lazy initialized
+		ArrayList values = null;
+		synchronized(this.perProjectInfos) {
+			values = new ArrayList(this.perProjectInfos.values());
+		}
+		Iterator iterator = values.iterator();
+		while (iterator.hasNext()) {
+			try {
+				PerProjectInfo info = (PerProjectInfo) iterator.next();
+				saveState(info, context);
+			} catch (CoreException e) {
+				if (vStats == null)
+					vStats= new ArrayList();
+				vStats.add(e.getStatus());
+			}
+		}
+		if (vStats != null) {
+			IStatus[] stats= new IStatus[vStats.size()];
+			vStats.toArray(stats);
+			throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Messages.build_cannotSaveStates, null));
+		}
+
+		// save external libs timestamps
+		this.deltaState.saveExternalLibTimeStamps();
+
+	}
+
+	/**
+	 * Add a secondary type in temporary indexing cache for a project got from given path.
+	 *
+	 * Current secondary types cache is not modified as we want to wait that indexing
+	 * was finished before taking new secondary types into account.
+	 *
+	 * Indexing cache is a specific entry in secondary types cache which key is
+	 * {@link #INDEXED_SECONDARY_TYPES } and value a map with same structure than
+	 * secondary types cache itself.
+	 *
+	 * @see #secondaryTypes(IJavaProject, boolean, IProgressMonitor)
+	 */
+	public void secondaryTypeAdding(String path, char[] typeName, char[] packageName) {
+		if (VERBOSE) {
+			StringBuffer buffer = new StringBuffer("JavaModelManager.addSecondaryType("); //$NON-NLS-1$
+			buffer.append(path);
+			buffer.append(',');
+			buffer.append('[');
+			buffer.append(new String(packageName));
+			buffer.append('.');
+			buffer.append(new String(typeName));
+			buffer.append(']');
+			buffer.append(')');
+			Util.verbose(buffer.toString());
+		}
+		IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot();
+		IResource resource = wRoot.findMember(path);
+		if (resource != null) {
+			if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(path) && resource.getType() == IResource.FILE) {
+				IProject project = resource.getProject();
+				try {
+					PerProjectInfo projectInfo = getPerProjectInfoCheckExistence(project);
+					// Get or create map to cache secondary types while indexing (can be not synchronized as indexing insure a non-concurrent usage)
+					HashMap indexedSecondaryTypes = null;
+					if (projectInfo.secondaryTypes == null) {
+						projectInfo.secondaryTypes = new Hashtable(3);
+						indexedSecondaryTypes = new HashMap(3);
+						projectInfo.secondaryTypes.put(INDEXED_SECONDARY_TYPES, indexedSecondaryTypes);
+					} else {
+						indexedSecondaryTypes = (HashMap) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES);
+						if (indexedSecondaryTypes == null) {
+							indexedSecondaryTypes = new HashMap(3);
+							projectInfo.secondaryTypes.put(INDEXED_SECONDARY_TYPES, indexedSecondaryTypes);
+						}
+					}
+					// Store the secondary type in temporary cache (these are just handles => no problem to create it now...)
+					HashMap allTypes = (HashMap) indexedSecondaryTypes.get(resource);
+					if (allTypes == null) {
+						allTypes = new HashMap(3);
+						indexedSecondaryTypes.put(resource, allTypes);
+					}
+					ICompilationUnit unit = JavaModelManager.createCompilationUnitFrom((IFile)resource, null);
+					if (unit != null) {
+						String typeString = new String(typeName);
+						IType type = unit.getType(typeString);
+						// String packageString = new String(packageName);
+						// use package fragment name instead of parameter as it may be invalid...
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=186781
+						String packageString = type.getPackageFragment().getElementName();
+						HashMap packageTypes = (HashMap) allTypes.get(packageString);
+						if (packageTypes == null) {
+							packageTypes = new HashMap(3);
+							allTypes.put(packageString, packageTypes);
+						}
+						packageTypes.put(typeString, type);
+					}
+					if (VERBOSE) {
+						Util.verbose("	- indexing cache:"); //$NON-NLS-1$
+						Iterator entries = indexedSecondaryTypes.entrySet().iterator();
+						while (entries.hasNext()) {
+							Map.Entry entry = (Map.Entry) entries.next();
+							IFile file = (IFile) entry.getKey();
+							Util.verbose("		+ "+file.getFullPath()+':'+ entry.getValue()); //$NON-NLS-1$
+						}
+					}
+				}
+				catch (JavaModelException jme) {
+					// do nothing
+				}
+			}
+		}
+	}
+
+	/**
+	 * Get all secondary types for a project and store result in per project info cache.
+	 * <p>
+	 * This cache is an <code>Hashtable&lt;String, HashMap&lt;String, IType&gt;&gt;</code>:
+	 *  <ul>
+	 * 	<li>key: package name
+	 * 	<li>value:
+	 * 		<ul>
+	 * 		<li>key: type name
+	 * 		<li>value: java model handle for the secondary type
+	 * 		</ul>
+	 * </ul>
+	 * Hashtable was used to protect callers from possible concurrent access.
+	 * </p>
+	 * Note that this map may have a specific entry which key is {@link #INDEXED_SECONDARY_TYPES }
+	 * and value is a map containing all secondary types created during indexing.
+	 * When this key is in cache and indexing is finished, returned map is merged
+	 * with the value of this special key. If indexing is not finished and caller does
+	 * not wait for the end of indexing, returned map is the current secondary
+	 * types cache content which may be invalid...
+	 *
+	 * @param project Project we want get secondary types from
+	 * @return HashMap Table of secondary type names->path for given project
+	 */
+	public Map secondaryTypes(IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor) throws JavaModelException {
+		if (VERBOSE) {
+			StringBuffer buffer = new StringBuffer("JavaModelManager.secondaryTypes("); //$NON-NLS-1$
+			buffer.append(project.getElementName());
+			buffer.append(',');
+			buffer.append(waitForIndexes);
+			buffer.append(')');
+			Util.verbose(buffer.toString());
+		}
+
+		// Return cache if not empty and there's no new secondary types created during indexing
+		final PerProjectInfo projectInfo = getPerProjectInfoCheckExistence(project.getProject());
+		Map indexingSecondaryCache = projectInfo.secondaryTypes == null ? null : (Map) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES);
+		if (projectInfo.secondaryTypes != null && indexingSecondaryCache == null) {
+			return projectInfo.secondaryTypes;
+		}
+
+		// Perform search request only if secondary types cache is not initialized yet (this will happen only once!)
+		if (projectInfo.secondaryTypes == null) {
+			return secondaryTypesSearching(project, waitForIndexes, monitor, projectInfo);
+		}
+
+		// New secondary types have been created while indexing secondary types cache
+		// => need to know whether the indexing is finished or not
+		boolean indexing = this.indexManager.awaitingJobsCount() > 0;
+		if (indexing) {
+			if (!waitForIndexes)  {
+				// Indexing is running but caller cannot wait => return current cache
+				return projectInfo.secondaryTypes;
+			}
+
+			// Wait for the end of indexing or a cancel
+			while (this.indexManager.awaitingJobsCount() > 0) {
+				if (monitor != null && monitor.isCanceled()) {
+					return projectInfo.secondaryTypes;
+				}
+				try {
+					Thread.sleep(10);
+				} catch (InterruptedException e) {
+					return projectInfo.secondaryTypes;
+				}
+			}
+		}
+
+		// Indexing is finished => merge caches and return result
+		return secondaryTypesMerging(projectInfo.secondaryTypes);
+	}
+
+	/*
+	 * Return secondary types cache merged with new secondary types created while indexing
+	 * Note that merge result is directly stored in given parameter map.
+	 */
+	private Hashtable secondaryTypesMerging(Hashtable secondaryTypes) {
+		if (VERBOSE) {
+			Util.verbose("JavaModelManager.getSecondaryTypesMerged()"); //$NON-NLS-1$
+			Util.verbose("	- current cache to merge:"); //$NON-NLS-1$
+			Iterator entries = secondaryTypes.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry) entries.next();
+				String packName = (String) entry.getKey();
+				Util.verbose("		+ "+packName+':'+ entry.getValue() ); //$NON-NLS-1$
+			}
+		}
+
+		// Return current cache if there's no indexing cache (double check, this should not happen)
+		HashMap indexedSecondaryTypes = (HashMap) secondaryTypes.remove(INDEXED_SECONDARY_TYPES);
+		if (indexedSecondaryTypes == null) {
+			return secondaryTypes;
+		}
+
+		// Merge indexing cache in secondary types one
+		Iterator entries = indexedSecondaryTypes.entrySet().iterator();
+		while (entries.hasNext()) {
+			Map.Entry entry = (Map.Entry) entries.next();
+			IFile file = (IFile) entry.getKey();
+
+			// Remove all secondary types of indexed file from cache
+			secondaryTypesRemoving(secondaryTypes, file);
+
+			// Add all indexing file secondary types in given secondary types cache
+			HashMap fileSecondaryTypes = (HashMap) entry.getValue();
+			Iterator entries2 = fileSecondaryTypes.entrySet().iterator();
+			while (entries2.hasNext()) {
+				Map.Entry entry2 = (Map.Entry) entries2.next();
+				String packageName = (String) entry2.getKey();
+				HashMap cachedTypes = (HashMap) secondaryTypes.get(packageName);
+				if (cachedTypes == null) {
+					secondaryTypes.put(packageName, entry2.getValue());
+				} else {
+					HashMap types = (HashMap) entry2.getValue();
+					Iterator entries3 = types.entrySet().iterator();
+					while (entries3.hasNext()) {
+						Map.Entry entry3 = (Map.Entry) entries3.next();
+						String typeName = (String) entry3.getKey();
+						cachedTypes.put(typeName, entry3.getValue());
+					}
+				}
+			}
+		}
+		if (VERBOSE) {
+			Util.verbose("	- secondary types cache merged:"); //$NON-NLS-1$
+			entries = secondaryTypes.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry) entries.next();
+				String packName = (String) entry.getKey();
+				Util.verbose("		+ "+packName+':'+ entry.getValue()); //$NON-NLS-1$
+			}
+		}
+		return secondaryTypes;
+	}
+
+	/*
+	 * Perform search request to get all secondary types of a given project.
+	 * If not waiting for indexes and indexing is running, will return types found in current built indexes...
+	 */
+	private Map secondaryTypesSearching(IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor, final PerProjectInfo projectInfo) throws JavaModelException {
+		if (VERBOSE || BasicSearchEngine.VERBOSE) {
+			StringBuffer buffer = new StringBuffer("JavaModelManager.secondaryTypesSearch("); //$NON-NLS-1$
+			buffer.append(project.getElementName());
+			buffer.append(',');
+			buffer.append(waitForIndexes);
+			buffer.append(')');
+			Util.verbose(buffer.toString());
+		}
+
+		final Hashtable secondaryTypes = new Hashtable(3);
+		IRestrictedAccessTypeRequestor nameRequestor = new IRestrictedAccessTypeRequestor() {
+			public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+				String key = packageName==null ? "" : new String(packageName); //$NON-NLS-1$
+				HashMap types = (HashMap) secondaryTypes.get(key);
+				if (types == null) types = new HashMap(3);
+				types.put(new String(simpleTypeName), path);
+				secondaryTypes.put(key, types);
+			}
+		};
+
+		// Build scope using prereq projects but only source folders
+		IPackageFragmentRoot[] allRoots = project.getAllPackageFragmentRoots();
+		int length = allRoots.length, size = 0;
+		IPackageFragmentRoot[] allSourceFolders = new IPackageFragmentRoot[length];
+		for (int i=0; i<length; i++) {
+			if (allRoots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
+				allSourceFolders[size++] = allRoots[i];
+			}
+		}
+		if (size < length) {
+			System.arraycopy(allSourceFolders, 0, allSourceFolders = new IPackageFragmentRoot[size], 0, size);
+		}
+
+		// Search all secondary types on scope
+		new BasicSearchEngine().searchAllSecondaryTypeNames(allSourceFolders, nameRequestor, waitForIndexes, monitor);
+
+		// Build types from paths
+		Iterator packages = secondaryTypes.values().iterator();
+		while (packages.hasNext()) {
+			HashMap types = (HashMap) packages.next();
+			Iterator names = types.entrySet().iterator();
+			while (names.hasNext()) {
+				Map.Entry entry = (Map.Entry) names.next();
+				String typeName = (String) entry.getKey();
+				String path = (String) entry.getValue();
+				if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(path)) {
+					IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
+					ICompilationUnit unit = JavaModelManager.createCompilationUnitFrom(file, null);
+					IType type = unit.getType(typeName);
+					types.put(typeName, type); // replace stored path with type itself
+				} else {
+					names.remove();
+				}
+			}
+		}
+
+		// Store result in per project info cache if still null or there's still an indexing cache (may have been set by another thread...)
+		if (projectInfo.secondaryTypes == null || projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES) != null) {
+			projectInfo.secondaryTypes = secondaryTypes;
+			if (VERBOSE || BasicSearchEngine.VERBOSE) {
+				System.out.print(Thread.currentThread() + "	-> secondary paths stored in cache: ");  //$NON-NLS-1$
+				System.out.println();
+				Iterator entries = secondaryTypes.entrySet().iterator();
+				while (entries.hasNext()) {
+					Map.Entry entry = (Map.Entry) entries.next();
+					String qualifiedName = (String) entry.getKey();
+					Util.verbose("		- "+qualifiedName+'-'+ entry.getValue()); //$NON-NLS-1$
+				}
+			}
+		}
+		return projectInfo.secondaryTypes;
+	}
+
+	/**
+	 * Remove from secondary types cache all types belonging to a given file.
+	 * Clean secondary types cache built while indexing if requested.
+	 *
+	 * Project's secondary types cache is found using file location.
+	 *
+	 * @param file File to remove
+	 */
+	public void secondaryTypesRemoving(IFile file, boolean cleanIndexCache) {
+		if (VERBOSE) {
+			StringBuffer buffer = new StringBuffer("JavaModelManager.removeFromSecondaryTypesCache("); //$NON-NLS-1$
+			buffer.append(file.getName());
+			buffer.append(')');
+			Util.verbose(buffer.toString());
+		}
+		if (file != null) {
+			PerProjectInfo projectInfo = getPerProjectInfo(file.getProject(), false);
+			if (projectInfo != null && projectInfo.secondaryTypes != null) {
+				if (VERBOSE) {
+					Util.verbose("-> remove file from cache of project: "+file.getProject().getName()); //$NON-NLS-1$
+				}
+
+				// Clean current cache
+				secondaryTypesRemoving(projectInfo.secondaryTypes, file);
+
+				// Clean indexing cache if necessary
+				HashMap indexingCache = (HashMap) projectInfo.secondaryTypes.get(INDEXED_SECONDARY_TYPES);
+				if (!cleanIndexCache) {
+					if (indexingCache == null) {
+						// Need to signify that secondary types indexing will happen before any request happens
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=152841
+						projectInfo.secondaryTypes.put(INDEXED_SECONDARY_TYPES, new HashMap());
+					}
+					return;
+				}
+				if (indexingCache != null) {
+					Set keys = indexingCache.keySet();
+					int filesSize = keys.size(), filesCount = 0;
+					IFile[] removed = null;
+					Iterator cachedFiles = keys.iterator();
+					while (cachedFiles.hasNext()) {
+						IFile cachedFile = (IFile) cachedFiles.next();
+						if (file.equals(cachedFile)) {
+							if (removed == null) removed = new IFile[filesSize];
+							filesSize--;
+							removed[filesCount++] = cachedFile;
+						}
+					}
+					if (removed != null) {
+						for (int i=0; i<filesCount; i++) {
+							indexingCache.remove(removed[i]);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/*
+	 * Remove from a given cache map all secondary types belonging to a given file.
+	 * Note that there can have several secondary types per file...
+	 */
+	private void secondaryTypesRemoving(Hashtable secondaryTypesMap, IFile file) {
+		if (VERBOSE) {
+			StringBuffer buffer = new StringBuffer("JavaModelManager.removeSecondaryTypesFromMap("); //$NON-NLS-1$
+			Iterator entries = secondaryTypesMap.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry) entries.next();
+				String qualifiedName = (String) entry.getKey();
+				buffer.append(qualifiedName+':'+ entry.getValue());
+			}
+			buffer.append(',');
+			buffer.append(file.getFullPath());
+			buffer.append(')');
+			Util.verbose(buffer.toString());
+		}
+		Set packageEntries = secondaryTypesMap.entrySet();
+		int packagesSize = packageEntries.size(), removedPackagesCount = 0;
+		String[] removedPackages = null;
+		Iterator packages = packageEntries.iterator();
+		while (packages.hasNext()) {
+			Map.Entry entry = (Map.Entry) packages.next();
+			String packName = (String) entry.getKey();
+			if (packName != INDEXED_SECONDARY_TYPES) { // skip indexing cache entry if present (!= is intentional)
+				HashMap types = (HashMap) entry.getValue();
+				Set nameEntries = types.entrySet();
+				int namesSize = nameEntries.size(), removedNamesCount = 0;
+				String[] removedNames = null;
+				Iterator names = nameEntries.iterator();
+				while (names.hasNext()) {
+					Map.Entry entry2 = (Map.Entry) names.next();
+					String typeName = (String) entry2.getKey();
+					JavaElement type = (JavaElement) entry2.getValue();
+					if (file.equals(type.resource())) {
+						if (removedNames == null) removedNames = new String[namesSize];
+						namesSize--;
+						removedNames[removedNamesCount++] = typeName;
+					}
+				}
+				if (removedNames != null) {
+					for (int i=0; i<removedNamesCount; i++) {
+						types.remove(removedNames[i]);
+					}
+				}
+				if (types.size() == 0) {
+					if (removedPackages == null) removedPackages = new String[packagesSize];
+					packagesSize--;
+					removedPackages[removedPackagesCount++] = packName;
+				}
+			}
+		}
+		if (removedPackages != null) {
+			for (int i=0; i<removedPackagesCount; i++) {
+				secondaryTypesMap.remove(removedPackages[i]);
+			}
+		}
+		if (VERBOSE) {
+			Util.verbose("	- new secondary types map:"); //$NON-NLS-1$
+			Iterator entries = secondaryTypesMap.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry) entries.next();
+				String qualifiedName = (String) entry.getKey();
+				Util.verbose("		+ "+qualifiedName+':'+ entry.getValue()); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * Record the order in which to build the java projects (batch build). This order is based
+	 * on the projects classpath settings.
+	 */
+	protected void setBuildOrder(String[] javaBuildOrder) throws JavaModelException {
+
+		// optional behaviour
+		// possible value of index 0 is Compute
+		if (!JavaCore.COMPUTE.equals(JavaCore.getOption(JavaCore.CORE_JAVA_BUILD_ORDER))) return; // cannot be customized at project level
+
+		if (javaBuildOrder == null || javaBuildOrder.length <= 1) return;
+
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		IWorkspaceDescription description = workspace.getDescription();
+		String[] wksBuildOrder = description.getBuildOrder();
+
+		String[] newOrder;
+		if (wksBuildOrder == null){
+			newOrder = javaBuildOrder;
+		} else {
+			// remove projects which are already mentionned in java builder order
+			int javaCount = javaBuildOrder.length;
+			HashMap newSet = new HashMap(javaCount); // create a set for fast check
+			for (int i = 0; i < javaCount; i++){
+				newSet.put(javaBuildOrder[i], javaBuildOrder[i]);
+			}
+			int removed = 0;
+			int oldCount = wksBuildOrder.length;
+			for (int i = 0; i < oldCount; i++){
+				if (newSet.containsKey(wksBuildOrder[i])){
+					wksBuildOrder[i] = null;
+					removed++;
+				}
+			}
+			// add Java ones first
+			newOrder = new String[oldCount - removed + javaCount];
+			System.arraycopy(javaBuildOrder, 0, newOrder, 0, javaCount); // java projects are built first
+
+			// copy previous items in their respective order
+			int index = javaCount;
+			for (int i = 0; i < oldCount; i++){
+				if (wksBuildOrder[i] != null){
+					newOrder[index++] = wksBuildOrder[i];
+				}
+			}
+		}
+		// commit the new build order out
+		description.setBuildOrder(newOrder);
+		try {
+			workspace.setDescription(description);
+		} catch(CoreException e){
+			throw new JavaModelException(e);
+		}
+	}
+
+	/**
+	 * Sets the last built state for the given project, or null to reset it.
+	 */
+	public void setLastBuiltState(IProject project, Object state) {
+		if (JavaProject.hasJavaNature(project)) {
+			// should never be requested on non-Java projects
+			PerProjectInfo info = getPerProjectInfo(project, true /*create if missing*/);
+			info.triedRead = true; // no point trying to re-read once using setter
+			info.savedState = state;
+		}
+		if (state == null) { // delete state file to ensure a full build happens if the workspace crashes
+			try {
+				File file = getSerializationFile(project);
+				if (file != null && file.exists())
+					file.delete();
+			} catch(SecurityException se) {
+				// could not delete file: cannot do much more
+			}
+		}
+	}
+
+	/**
+	 * Store the preferences value for the given option name.
+	 *
+	 * @param optionName The name of the option
+	 * @param optionValue The value of the option. If <code>null</code>, then
+	 * 	the option will be removed from the preferences instead.
+	 * @param eclipsePreferences The eclipse preferences to be updated
+	 * @param otherOptions more options being stored, used to avoid conflict between deprecated option and its compatible
+	 * @return <code>true</code> if the preferences have been changed,
+	 * 	<code>false</code> otherwise.
+	 */
+	public boolean storePreference(String optionName, String optionValue, IEclipsePreferences eclipsePreferences, Map otherOptions) {
+		int optionLevel = this.getOptionLevel(optionName);
+		if (optionLevel == UNKNOWN_OPTION) return false; // unrecognized option
+		
+		// Store option value
+		switch (optionLevel) {
+			case JavaModelManager.VALID_OPTION:
+				if (optionValue == null) {
+					eclipsePreferences.remove(optionName);
+				} else {
+					eclipsePreferences.put(optionName, optionValue);
+				}
+				break;
+			case JavaModelManager.DEPRECATED_OPTION:
+				// Try to migrate deprecated option
+				eclipsePreferences.remove(optionName); // get rid off old preference
+				String[] compatibleOptions = (String[]) this.deprecatedOptions.get(optionName);
+				for (int co=0, length=compatibleOptions.length; co < length; co++) {
+					if (otherOptions != null && otherOptions.containsKey(compatibleOptions[co]))
+						continue; // don't overwrite explicit value of otherOptions at compatibleOptions[co]
+					if (optionValue == null) {
+						eclipsePreferences.remove(compatibleOptions[co]);
+					} else {
+						eclipsePreferences.put(compatibleOptions[co], optionValue);
+					}
+				}
+				break;
+			default:
+				return false;
+		}
+		return true;
+	}
+
+	public void setOptions(Hashtable newOptions) {
+		Hashtable cachedValue = newOptions == null ? null : new Hashtable(newOptions);
+		IEclipsePreferences defaultPreferences = getDefaultPreferences();
+		IEclipsePreferences instancePreferences = getInstancePreferences();
+
+		if (newOptions == null){
+			try {
+				instancePreferences.clear();
+			} catch(BackingStoreException e) {
+				// ignore
+			}
+		} else {
+			Enumeration keys = newOptions.keys();
+			while (keys.hasMoreElements()){
+				String key = (String)keys.nextElement();
+				int optionLevel = getOptionLevel(key);
+				if (optionLevel == UNKNOWN_OPTION) continue; // unrecognized option
+				if (key.equals(JavaCore.CORE_ENCODING)) {
+					if (cachedValue != null) {
+						cachedValue.put(key, JavaCore.getEncoding());
+					}
+					continue; // skipped, contributed by resource prefs
+				}
+				String value = (String) newOptions.get(key);
+				String defaultValue = defaultPreferences.get(key, null);
+				// Store value in preferences
+				if (defaultValue != null && defaultValue.equals(value)) {
+					value = null;
+				}
+				storePreference(key, value, instancePreferences, newOptions);
+			}
+			try {
+				// persist options
+				instancePreferences.flush();
+			} catch(BackingStoreException e) {
+				// ignore
+			}
+		}
+		// update cache
+		Util.fixTaskTags(cachedValue);
+		this.optionsCache = cachedValue;
+	}
+
+	public void startup() throws CoreException {
+		try {
+			configurePluginDebugOptions();
+
+			// initialize Java model cache
+			this.cache = new JavaModelCache();
+
+			// request state folder creation (workaround 19885)
+			JavaCore.getPlugin().getStateLocation();
+
+			// Initialize eclipse preferences
+			initializePreferences();
+
+			// Listen to preference changes
+			this.propertyListener = new IEclipsePreferences.IPreferenceChangeListener() {
+				public void preferenceChange(PreferenceChangeEvent event) {
+					JavaModelManager.this.optionsCache = null;
+				}
+			};
+			InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID).addPreferenceChangeListener(this.propertyListener);
+			
+			// listen for encoding changes (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=255501 )
+			this.resourcesPropertyListener = new IEclipsePreferences.IPreferenceChangeListener() {
+				public void preferenceChange(PreferenceChangeEvent event) {
+					if (ResourcesPlugin.PREF_ENCODING.equals(event.getKey())) {
+						JavaModelManager.this.optionsCache = null;
+					}
+				}
+			};
+			String resourcesPluginId = ResourcesPlugin.getPlugin().getBundle().getSymbolicName();
+			InstanceScope.INSTANCE.getNode(resourcesPluginId).addPreferenceChangeListener(this.resourcesPropertyListener);
+
+			// Listen to content-type changes
+			 Platform.getContentTypeManager().addContentTypeChangeListener(this);
+
+			// retrieve variable values
+			long start = -1;
+			if (VERBOSE)
+				start = System.currentTimeMillis();
+			loadVariablesAndContainers();
+			if (VERBOSE)
+				traceVariableAndContainers("Loaded", start); //$NON-NLS-1$
+
+			// listen for resource changes
+			this.deltaState.initializeRootsWithPreviousSession();
+			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+			workspace.addResourceChangeListener(
+				this.deltaState,
+				/* update spec in JavaCore#addPreProcessingResourceChangedListener(...) if adding more event types */
+				IResourceChangeEvent.PRE_BUILD
+					| IResourceChangeEvent.POST_BUILD
+					| IResourceChangeEvent.POST_CHANGE
+					| IResourceChangeEvent.PRE_DELETE
+					| IResourceChangeEvent.PRE_CLOSE
+					| IResourceChangeEvent.PRE_REFRESH);
+
+			startIndexing();
+
+			// process deltas since last activated in indexer thread so that indexes are up-to-date.
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658
+			Job processSavedState = new Job(Messages.savedState_jobName) {
+				protected IStatus run(IProgressMonitor monitor) {
+					try {
+						// add save participant and process delta atomically
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59937
+						workspace.run(
+							new IWorkspaceRunnable() {
+								public void run(IProgressMonitor progress) throws CoreException {
+									ISavedState savedState = workspace.addSaveParticipant(JavaCore.PLUGIN_ID, JavaModelManager.this);
+									if (savedState != null) {
+										// the event type coming from the saved state is always POST_AUTO_BUILD
+										// force it to be POST_CHANGE so that the delta processor can handle it
+										JavaModelManager.this.deltaState.getDeltaProcessor().overridenEventType = IResourceChangeEvent.POST_CHANGE;
+										savedState.processResourceChangeEvents(JavaModelManager.this.deltaState);
+									}
+								}
+							},
+							monitor);
+					} catch (CoreException e) {
+						return e.getStatus();
+					}
+					return Status.OK_STATUS;
+				}
+			};
+			processSavedState.setSystem(true);
+			processSavedState.setPriority(Job.SHORT); // process asap
+			processSavedState.schedule();
+		} catch (RuntimeException e) {
+			shutdown();
+			throw e;
+		}
+	}
+
+	/**
+	 * Initiate the background indexing process.
+	 * This should be deferred after the plug-in activation.
+	 */
+	private void startIndexing() {
+		if (this.indexManager != null) this.indexManager.reset();
+	}
+
+	public void shutdown () {
+		IEclipsePreferences preferences = InstanceScope.INSTANCE.getNode(JavaCore.PLUGIN_ID);
+		try {
+			preferences.flush();
+		} catch (BackingStoreException e) {
+			Util.log(e, "Could not save JavaCore preferences"); //$NON-NLS-1$
+		}
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		workspace.removeResourceChangeListener(this.deltaState);
+		workspace.removeSaveParticipant(JavaCore.PLUGIN_ID);
+
+		// Stop listening to content-type changes
+		Platform.getContentTypeManager().removeContentTypeChangeListener(this);
+
+		// Stop indexing
+		if (this.indexManager != null) {
+			this.indexManager.shutdown();
+		}
+
+		// Stop listening to preferences changes
+		preferences.removePreferenceChangeListener(this.propertyListener);
+		((IEclipsePreferences) this.preferencesLookup[PREF_DEFAULT].parent()).removeNodeChangeListener(this.defaultNodeListener);
+		this.preferencesLookup[PREF_DEFAULT] = null;
+		((IEclipsePreferences) this.preferencesLookup[PREF_INSTANCE].parent()).removeNodeChangeListener(this.instanceNodeListener);
+		this.preferencesLookup[PREF_INSTANCE].removePreferenceChangeListener(this.instancePreferencesListener);
+		this.preferencesLookup[PREF_INSTANCE] = null;
+		String resourcesPluginId = ResourcesPlugin.getPlugin().getBundle().getSymbolicName();
+		InstanceScope.INSTANCE.getNode(resourcesPluginId).removePreferenceChangeListener(this.resourcesPropertyListener);
+
+		// wait for the initialization job to finish
+		try {
+			Job.getJobManager().join(JavaCore.PLUGIN_ID, null);
+		} catch (InterruptedException e) {
+			// ignore
+		}
+
+		// Note: no need to close the Java model as this just removes Java element infos from the Java model cache
+	}
+
+	public synchronized IPath variableGet(String variableName){
+		// check initialization in progress first
+		HashSet initializations = variableInitializationInProgress();
+		if (initializations.contains(variableName)) {
+			return VARIABLE_INITIALIZATION_IN_PROGRESS;
+		}
+		return (IPath)this.variables.get(variableName);
+	}
+
+	private synchronized IPath variableGetDefaultToPreviousSession(String variableName){
+		IPath variablePath = (IPath)this.variables.get(variableName);
+		if (variablePath == null)
+			return getPreviousSessionVariable(variableName);
+		return variablePath;
+	}
+
+	/*
+	 * Returns the set of variable names that are being initialized in the current thread.
+	 */
+	private HashSet variableInitializationInProgress() {
+		HashSet initializations = (HashSet)this.variableInitializationInProgress.get();
+		if (initializations == null) {
+			initializations = new HashSet();
+			this.variableInitializationInProgress.set(initializations);
+		}
+		return initializations;
+	}
+
+	public synchronized String[] variableNames(){
+		int length = this.variables.size();
+		String[] result = new String[length];
+		Iterator vars = this.variables.keySet().iterator();
+		int index = 0;
+		while (vars.hasNext()) {
+			result[index++] = (String) vars.next();
+		}
+		return result;
+	}
+
+	public synchronized void variablePut(String variableName, IPath variablePath){
+
+		// set/unset the initialization in progress
+		HashSet initializations = variableInitializationInProgress();
+		if (variablePath == VARIABLE_INITIALIZATION_IN_PROGRESS) {
+			initializations.add(variableName);
+
+			// do not write out intermediate initialization value
+			return;
+		} else {
+			initializations.remove(variableName);
+
+			// update cache - do not only rely on listener refresh
+			if (variablePath == null) {
+				// if path is null, record that the variable was removed to avoid asking the initializer to initialize it again
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=112609
+				this.variables.put(variableName, CP_ENTRY_IGNORE_PATH);
+				// clean other variables caches
+				this.variablesWithInitializer.remove(variableName);
+				this.deprecatedVariables.remove(variableName);
+			} else {
+				this.variables.put(variableName, variablePath);
+			}
+			// discard obsoleted information about previous session
+			this.previousSessionVariables.remove(variableName);
+		}
+	}
+
+	public void variablePreferencesPut(String variableName, IPath variablePath) {
+		String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
+		if (variablePath == null) {
+			getInstancePreferences().remove(variableKey);
+		} else {
+			getInstancePreferences().put(variableKey, variablePath.toString());
+		}
+		try {
+			getInstancePreferences().flush();
+		} catch (BackingStoreException e) {
+			// ignore exception
+		}
+	}
+
+	/*
+	 * Optimize startup case where 1 variable is initialized at a time with the same value as on shutdown.
+	 */
+	public boolean variablePutIfInitializingWithSameValue(String[] variableNames, IPath[] variablePaths) {
+		if (variableNames.length != 1)
+			return false;
+		String variableName = variableNames[0];
+		IPath oldPath = variableGetDefaultToPreviousSession(variableName);
+		if (oldPath == null)
+			return false;
+		IPath newPath = variablePaths[0];
+		if (!oldPath.equals(newPath))
+			return false;
+		variablePut(variableName, newPath);
+		return true;
+	}
+
+	public void contentTypeChanged(ContentTypeChangeEvent event) {
+		Util.resetJavaLikeExtensions();
+
+		// Walk through projects to reset their secondary types cache
+		IJavaProject[] projects;
+		try {
+			projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+		} catch (JavaModelException e) {
+			return;
+		}
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IJavaProject project = projects[i];
+			final PerProjectInfo projectInfo = getPerProjectInfo(project.getProject(), false /* don't create info */);
+			if (projectInfo != null) {
+				projectInfo.secondaryTypes = null;
+			}
+		}
+	}
+
+	public synchronized String cacheToString(String prefix) {
+		return this.cache.toStringFillingRation(prefix);
+	}
+	
+	public Stats debugNewOpenableCacheStats() {
+		return this.cache.openableCache.new Stats();
+	}
+	
+	public int getOpenableCacheSize() {
+		return this.cache.openableCache.getSpaceLimit();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
new file mode 100644
index 0000000..08c4b60
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
@@ -0,0 +1,885 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Defines behavior common to all Java Model operations
+ */
+public abstract class JavaModelOperation implements IWorkspaceRunnable, IProgressMonitor {
+	protected interface IPostAction {
+		/*
+		 * Returns the id of this action.
+		 * @see JavaModelOperation#postAction
+		 */
+		String getID();
+		/*
+		 * Run this action.
+		 */
+		void run() throws JavaModelException;
+	}
+	/*
+	 * Constants controlling the insertion mode of an action.
+	 * @see JavaModelOperation#postAction
+	 */
+	protected static final int APPEND = 1; // insert at the end
+	protected static final int REMOVEALL_APPEND = 2; // remove all existing ones with same ID, and add new one at the end
+	protected static final int KEEP_EXISTING = 3; // do not insert if already existing with same ID
+
+	/*
+	 * Whether tracing post actions is enabled.
+	 */
+	protected static boolean POST_ACTION_VERBOSE;
+
+	/*
+	 * A list of IPostActions.
+	 */
+	protected IPostAction[] actions;
+	protected int actionsStart = 0;
+	protected int actionsEnd = -1;
+	/*
+	 * A HashMap of attributes that can be used by operations
+	 */
+	protected HashMap attributes;
+
+	public static final String HAS_MODIFIED_RESOURCE_ATTR = "hasModifiedResource"; //$NON-NLS-1$
+	public static final String TRUE = JavaModelManager.TRUE;
+	//public static final String FALSE = "false";
+
+	/**
+	 * The elements this operation operates on,
+	 * or <code>null</code> if this operation
+	 * does not operate on specific elements.
+	 */
+	protected IJavaElement[] elementsToProcess;
+	/**
+	 * The parent elements this operation operates with
+	 * or <code>null</code> if this operation
+	 * does not operate with specific parent elements.
+	 */
+	protected IJavaElement[] parentElements;
+	/**
+	 * An empty collection of <code>IJavaElement</code>s - the common
+	 * empty result if no elements are created, or if this
+	 * operation is not actually executed.
+	 */
+	protected static final IJavaElement[] NO_ELEMENTS= new IJavaElement[] {};
+
+
+	/**
+	 * The elements created by this operation - empty
+	 * until the operation actually creates elements.
+	 */
+	protected IJavaElement[] resultElements= NO_ELEMENTS;
+
+	/**
+	 * The progress monitor passed into this operation
+	 */
+	public IProgressMonitor progressMonitor= null;
+	/**
+	 * A flag indicating whether this operation is nested.
+	 */
+	protected boolean isNested = false;
+	/**
+	 * Conflict resolution policy - by default do not force (fail on a conflict).
+	 */
+	protected boolean force = false;
+
+	/*
+	 * A per thread stack of java model operations (PerThreadObject of ArrayList).
+	 */
+	protected static final ThreadLocal OPERATION_STACKS = new ThreadLocal();
+	protected JavaModelOperation() {
+		// default constructor used in subclasses
+	}
+	/**
+	 * A common constructor for all Java Model operations.
+	 */
+	protected JavaModelOperation(IJavaElement[] elements) {
+		this.elementsToProcess = elements;
+	}
+	/**
+	 * Common constructor for all Java Model operations.
+	 */
+	protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements) {
+		this.elementsToProcess = elementsToProcess;
+		this.parentElements= parentElements;
+	}
+	/**
+	 * A common constructor for all Java Model operations.
+	 */
+	protected JavaModelOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) {
+		this.elementsToProcess = elementsToProcess;
+		this.parentElements= parentElements;
+		this.force= force;
+	}
+	/**
+	 * A common constructor for all Java Model operations.
+	 */
+	protected JavaModelOperation(IJavaElement[] elements, boolean force) {
+		this.elementsToProcess = elements;
+		this.force= force;
+	}
+
+	/**
+	 * Common constructor for all Java Model operations.
+	 */
+	protected JavaModelOperation(IJavaElement element) {
+		this.elementsToProcess = new IJavaElement[]{element};
+	}
+
+	/*
+	 * Registers the given action at the end of the list of actions to run.
+	 */
+	protected void addAction(IPostAction action) {
+		int length = this.actions.length;
+		if (length == ++this.actionsEnd) {
+			System.arraycopy(this.actions, 0, this.actions = new IPostAction[length*2], 0, length);
+		}
+		this.actions[this.actionsEnd] = action;
+	}
+	/*
+	 * Registers the given delta with the Java Model Manager.
+	 */
+	protected void addDelta(IJavaElementDelta delta) {
+		JavaModelManager.getJavaModelManager().getDeltaProcessor().registerJavaModelDelta(delta);
+	}
+	/*
+	 * Registers the given reconcile delta with the Java Model Manager.
+	 */
+	protected void addReconcileDelta(ICompilationUnit workingCopy, IJavaElementDelta delta) {
+		HashMap reconcileDeltas = JavaModelManager.getJavaModelManager().getDeltaProcessor().reconcileDeltas;
+		JavaElementDelta previousDelta = (JavaElementDelta)reconcileDeltas.get(workingCopy);
+		if (previousDelta != null) {
+			IJavaElementDelta[] children = delta.getAffectedChildren();
+			for (int i = 0, length = children.length; i < length; i++) {
+				JavaElementDelta child = (JavaElementDelta)children[i];
+				previousDelta.insertDeltaTree(child.getElement(), child);
+			}
+			// note that the last delta's AST always takes precedence over the existing delta's AST
+			// since it is the result of the last reconcile operation
+			if ((delta.getFlags() & IJavaElementDelta.F_AST_AFFECTED) != 0) {
+				previousDelta.changedAST(delta.getCompilationUnitAST());
+			}
+
+		} else {
+			reconcileDeltas.put(workingCopy, delta);
+		}
+	}
+	/*
+	 * Deregister the reconcile delta for the given working copy
+	 */
+	protected void removeReconcileDelta(ICompilationUnit workingCopy) {
+		JavaModelManager.getJavaModelManager().getDeltaProcessor().reconcileDeltas.remove(workingCopy);
+	}
+	protected void applyTextEdit(ICompilationUnit cu, TextEdit edits) throws JavaModelException {
+		try {
+			edits.apply(getDocument(cu));
+		} catch (BadLocationException e) {
+			// content changed under us
+			throw new JavaModelException(e, IJavaModelStatusConstants.INVALID_CONTENTS);
+		}
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void beginTask(String name, int totalWork) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.beginTask(name, totalWork);
+		}
+	}
+	/*
+	 * Returns whether this operation can modify the package fragment roots.
+	 */
+	protected boolean canModifyRoots() {
+		return false;
+	}
+	/**
+	 * Checks with the progress monitor to see whether this operation
+	 * should be canceled. An operation should regularly call this method
+	 * during its operation so that the user can cancel it.
+	 *
+	 * @exception OperationCanceledException if cancelling the operation has been requested
+	 * @see IProgressMonitor#isCanceled
+	 */
+	protected void checkCanceled() {
+		if (isCanceled()) {
+			throw new OperationCanceledException(Messages.operation_cancelled);
+		}
+	}
+	/**
+	 * Common code used to verify the elements this operation is processing.
+	 * @see JavaModelOperation#verify()
+	 */
+	protected IJavaModelStatus commonVerify() {
+		if (this.elementsToProcess == null || this.elementsToProcess.length == 0) {
+			return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+		}
+		for (int i = 0; i < this.elementsToProcess.length; i++) {
+			if (this.elementsToProcess[i] == null) {
+				return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+			}
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+	/**
+	 * Convenience method to copy resources
+	 */
+	protected void copyResources(IResource[] resources, IPath container) throws JavaModelException {
+		IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
+		IWorkspaceRoot root =  ResourcesPlugin.getWorkspace().getRoot();
+		try {
+			for (int i = 0, length = resources.length; i < length; i++) {
+				IResource resource = resources[i];
+				IPath destination = container.append(resource.getName());
+				if (root.findMember(destination) == null) {
+					resource.copy(destination, false, subProgressMonitor);
+				}
+			}
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Convenience method to create a file
+	 */
+	protected void createFile(IContainer folder, String name, InputStream contents, boolean forceFlag) throws JavaModelException {
+		IFile file= folder.getFile(new Path(name));
+		try {
+			file.create(
+				contents,
+				forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+				getSubProgressMonitor(1));
+				setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Convenience method to create a folder
+	 */
+	protected void createFolder(IContainer parentFolder, String name, boolean forceFlag) throws JavaModelException {
+		IFolder folder= parentFolder.getFolder(new Path(name));
+		try {
+			// we should use true to create the file locally. Only VCM should use tru/false
+			folder.create(
+				forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+				true, // local
+				getSubProgressMonitor(1));
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Convenience method to delete an empty package fragment
+	 */
+	protected void deleteEmptyPackageFragment(
+		IPackageFragment fragment,
+		boolean forceFlag,
+		IResource rootResource)
+		throws JavaModelException {
+
+		IContainer resource = (IContainer) ((JavaElement)fragment).resource();
+
+		try {
+			resource.delete(
+				forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+				getSubProgressMonitor(1));
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+			while (resource instanceof IFolder) {
+				// deleting a package: delete the parent if it is empty (e.g. deleting x.y where folder x doesn't have resources but y)
+				// without deleting the package fragment root
+				resource = resource.getParent();
+				if (!resource.equals(rootResource) && resource.members().length == 0) {
+					resource.delete(
+						forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+						getSubProgressMonitor(1));
+					setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+				}
+			}
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Convenience method to delete a resource
+	 */
+	protected void deleteResource(IResource resource,int flags) throws JavaModelException {
+		try {
+			resource.delete(flags, getSubProgressMonitor(1));
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Convenience method to delete resources
+	 */
+	protected void deleteResources(IResource[] resources, boolean forceFlag) throws JavaModelException {
+		if (resources == null || resources.length == 0) return;
+		IProgressMonitor subProgressMonitor = getSubProgressMonitor(resources.length);
+		IWorkspace workspace = resources[0].getWorkspace();
+		try {
+			workspace.delete(
+				resources,
+				forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
+				subProgressMonitor);
+				setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void done() {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.done();
+		}
+	}
+	/*
+	 * Returns whether the given path is equals to one of the given other paths.
+	 */
+	protected boolean equalsOneOf(IPath path, IPath[] otherPaths) {
+		for (int i = 0, length = otherPaths.length; i < length; i++) {
+			if (path.equals(otherPaths[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+	/**
+	 * Convenience method to run an operation within this operation
+	 */
+	public void executeNestedOperation(JavaModelOperation operation, int subWorkAmount) throws JavaModelException {
+		IJavaModelStatus status= operation.verify();
+		if (!status.isOK()) {
+			throw new JavaModelException(status);
+		}
+		IProgressMonitor subProgressMonitor = getSubProgressMonitor(subWorkAmount);
+		// fix for 1FW7IKC, part (1)
+		try {
+			operation.setNested(true);
+			operation.run(subProgressMonitor);
+		} catch (CoreException ce) {
+			if (ce instanceof JavaModelException) {
+				throw (JavaModelException)ce;
+			} else {
+				// translate the core exception to a java model exception
+				if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
+					Throwable e = ce.getStatus().getException();
+					if (e instanceof JavaModelException) {
+						throw (JavaModelException) e;
+					}
+				}
+				throw new JavaModelException(ce);
+			}
+		}
+	}
+	/**
+	 * Performs the operation specific behavior. Subclasses must override.
+	 */
+	protected abstract void executeOperation() throws JavaModelException;
+	/*
+	 * Returns the attribute registered at the given key with the top level operation.
+	 * Returns null if no such attribute is found.
+	 */
+	protected static Object getAttribute(Object key) {
+		ArrayList stack = getCurrentOperationStack();
+		if (stack.size() == 0) return null;
+		JavaModelOperation topLevelOp = (JavaModelOperation)stack.get(0);
+		if (topLevelOp.attributes == null) {
+			return null;
+		} else {
+			return topLevelOp.attributes.get(key);
+		}
+	}
+	/**
+	 * Returns the compilation unit the given element is contained in,
+	 * or the element itself (if it is a compilation unit),
+	 * otherwise <code>null</code>.
+	 */
+	protected ICompilationUnit getCompilationUnitFor(IJavaElement element) {
+
+		return ((JavaElement)element).getCompilationUnit();
+	}
+	/*
+	 * Returns the stack of operations running in the current thread.
+	 * Returns an empty stack if no operations are currently running in this thread.
+	 */
+	protected static ArrayList getCurrentOperationStack() {
+		ArrayList stack = (ArrayList)OPERATION_STACKS.get();
+		if (stack == null) {
+			stack = new ArrayList();
+			OPERATION_STACKS.set(stack);
+		}
+		return stack;
+	}
+	/*
+	 * Returns the existing document for the given cu, or a DocumentAdapter if none.
+	 */
+	protected IDocument getDocument(ICompilationUnit cu) throws JavaModelException {
+		IBuffer buffer = cu.getBuffer();
+		if (buffer instanceof IDocument)
+			return (IDocument) buffer;
+		return new DocumentAdapter(buffer);
+	}
+	/**
+	 * Returns the element to which this operation applies,
+	 * or <code>null</code> if not applicable.
+	 */
+	protected IJavaElement getElementToProcess() {
+		if (this.elementsToProcess == null || this.elementsToProcess.length == 0) {
+			return null;
+		}
+		return this.elementsToProcess[0];
+	}
+	/**
+	 * Returns the Java Model this operation is operating in.
+	 */
+	public IJavaModel getJavaModel() {
+		return JavaModelManager.getJavaModelManager().getJavaModel();
+	}
+	protected IPath[] getNestedFolders(IPackageFragmentRoot root) throws JavaModelException {
+		IPath rootPath = root.getPath();
+		IClasspathEntry[] classpath = root.getJavaProject().getRawClasspath();
+		int length = classpath.length;
+		IPath[] result = new IPath[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			IPath path = classpath[i].getPath();
+			if (rootPath.isPrefixOf(path) && !rootPath.equals(path)) {
+				result[index++] = path;
+			}
+		}
+		if (index < length) {
+			System.arraycopy(result, 0, result = new IPath[index], 0, index);
+		}
+		return result;
+	}
+	/**
+	 * Returns the parent element to which this operation applies,
+	 * or <code>null</code> if not applicable.
+	 */
+	protected IJavaElement getParentElement() {
+		if (this.parentElements == null || this.parentElements.length == 0) {
+			return null;
+		}
+		return this.parentElements[0];
+	}
+	/**
+	 * Returns the parent elements to which this operation applies,
+	 * or <code>null</code> if not applicable.
+	 */
+	protected IJavaElement[] getParentElements() {
+		return this.parentElements;
+	}
+	/**
+	 * Returns the elements created by this operation.
+	 */
+	public IJavaElement[] getResultElements() {
+		return this.resultElements;
+	}
+	/*
+	 * Returns the scheduling rule for this operation (i.e. the resource that needs to be locked
+	 * while this operation is running.
+	 * Subclasses can override.
+	 */
+	protected ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+	/**
+	 * Creates and returns a subprogress monitor if appropriate.
+	 */
+	protected IProgressMonitor getSubProgressMonitor(int workAmount) {
+		IProgressMonitor sub = null;
+		if (this.progressMonitor != null) {
+			sub = new SubProgressMonitor(this.progressMonitor, workAmount, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+		}
+		return sub;
+	}
+
+	/**
+	 * Returns whether this operation has performed any resource modifications.
+	 * Returns false if this operation has not been executed yet.
+	 */
+	public boolean hasModifiedResource() {
+		return !isReadOnly() && getAttribute(HAS_MODIFIED_RESOURCE_ATTR) == TRUE;
+	}
+	public void internalWorked(double work) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.internalWorked(work);
+		}
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public boolean isCanceled() {
+		if (this.progressMonitor != null) {
+			return this.progressMonitor.isCanceled();
+		}
+		return false;
+	}
+	/**
+	 * Returns <code>true</code> if this operation performs no resource modifications,
+	 * otherwise <code>false</code>. Subclasses must override.
+	 */
+	public boolean isReadOnly() {
+		return false;
+	}
+	/*
+	 * Returns whether this operation is the first operation to run in the current thread.
+	 */
+	protected boolean isTopLevelOperation() {
+		ArrayList stack;
+		return
+			(stack = getCurrentOperationStack()).size() > 0
+			&& stack.get(0) == this;
+	}
+	/*
+	 * Returns the index of the first registered action with the given id, starting from a given position.
+	 * Returns -1 if not found.
+	 */
+	protected int firstActionWithID(String id, int start) {
+		for (int i = start; i <= this.actionsEnd; i++) {
+			if (this.actions[i].getID().equals(id)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Convenience method to move resources
+	 */
+	protected void moveResources(IResource[] resources, IPath container) throws JavaModelException {
+		IProgressMonitor subProgressMonitor = null;
+		if (this.progressMonitor != null) {
+			subProgressMonitor = new SubProgressMonitor(this.progressMonitor, resources.length, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+		}
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		try {
+			for (int i = 0, length = resources.length; i < length; i++) {
+				IResource resource = resources[i];
+				IPath destination = container.append(resource.getName());
+				if (root.findMember(destination) == null) {
+					resource.move(destination, false, subProgressMonitor);
+				}
+			}
+			setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	/**
+	 * Creates and returns a new <code>IJavaElementDelta</code>
+	 * on the Java Model.
+	 */
+	public JavaElementDelta newJavaElementDelta() {
+		return new JavaElementDelta(getJavaModel());
+	}
+	/*
+	 * Removes the last pushed operation from the stack of running operations.
+	 * Returns the poped operation or null if the stack was empty.
+	 */
+	protected JavaModelOperation popOperation() {
+		ArrayList stack = getCurrentOperationStack();
+		int size = stack.size();
+		if (size > 0) {
+			if (size == 1) { // top level operation
+				OPERATION_STACKS.set(null); // release reference (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927)
+			}
+			return (JavaModelOperation)stack.remove(size-1);
+		} else {
+			return null;
+		}
+	}
+	/*
+	 * Registers the given action to be run when the outer most java model operation has finished.
+	 * The insertion mode controls whether:
+	 * - the action should discard all existing actions with the same id, and be queued at the end (REMOVEALL_APPEND),
+	 * - the action should be ignored if there is already an action with the same id (KEEP_EXISTING),
+	 * - the action should be queued at the end without looking at existing actions (APPEND)
+	 */
+	protected void postAction(IPostAction action, int insertionMode) {
+		if (POST_ACTION_VERBOSE) {
+			System.out.print("(" + Thread.currentThread() + ") [JavaModelOperation.postAction(IPostAction, int)] Posting action " + action.getID()); //$NON-NLS-1$ //$NON-NLS-2$
+			switch(insertionMode) {
+				case REMOVEALL_APPEND:
+					System.out.println(" (REMOVEALL_APPEND)"); //$NON-NLS-1$
+					break;
+				case KEEP_EXISTING:
+					System.out.println(" (KEEP_EXISTING)"); //$NON-NLS-1$
+					break;
+				case APPEND:
+					System.out.println(" (APPEND)"); //$NON-NLS-1$
+					break;
+			}
+		}
+
+		JavaModelOperation topLevelOp = (JavaModelOperation)getCurrentOperationStack().get(0);
+		IPostAction[] postActions = topLevelOp.actions;
+		if (postActions == null) {
+			topLevelOp.actions = postActions = new IPostAction[1];
+			postActions[0] = action;
+			topLevelOp.actionsEnd = 0;
+		} else {
+			String id = action.getID();
+			switch (insertionMode) {
+				case REMOVEALL_APPEND :
+					int index = this.actionsStart-1;
+					while ((index = topLevelOp.firstActionWithID(id, index+1)) >= 0) {
+						// remove action[index]
+						System.arraycopy(postActions, index+1, postActions, index, topLevelOp.actionsEnd - index);
+						postActions[topLevelOp.actionsEnd--] = null;
+					}
+					topLevelOp.addAction(action);
+					break;
+				case KEEP_EXISTING:
+					if (topLevelOp.firstActionWithID(id, 0) < 0) {
+						topLevelOp.addAction(action);
+					}
+					break;
+				case APPEND:
+					topLevelOp.addAction(action);
+					break;
+			}
+		}
+	}
+	/*
+	 * Returns whether the given path is the prefix of one of the given other paths.
+	 */
+	protected boolean prefixesOneOf(IPath path, IPath[] otherPaths) {
+		for (int i = 0, length = otherPaths.length; i < length; i++) {
+			if (path.isPrefixOf(otherPaths[i])) {
+				return true;
+			}
+		}
+		return false;
+	}
+	/*
+	 * Pushes the given operation on the stack of operations currently running in this thread.
+	 */
+	protected void pushOperation(JavaModelOperation operation) {
+		getCurrentOperationStack().add(operation);
+	}
+	/*
+	 * Removes all actions with the given id from the queue of post actions.
+	 * Does nothing if no such action is in the queue.
+	 */
+	protected void removeAllPostAction(String actionID) {
+		if (POST_ACTION_VERBOSE) {
+			System.out.println("(" + Thread.currentThread() + ") [JavaModelOperation.removeAllPostAction(String)] Removing actions " + actionID); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		JavaModelOperation topLevelOp = (JavaModelOperation)getCurrentOperationStack().get(0);
+		IPostAction[] postActions = topLevelOp.actions;
+		if (postActions == null) return;
+		int index = this.actionsStart-1;
+		while ((index = topLevelOp.firstActionWithID(actionID, index+1)) >= 0) {
+			// remove action[index]
+			System.arraycopy(postActions, index+1, postActions, index, topLevelOp.actionsEnd - index);
+			postActions[topLevelOp.actionsEnd--] = null;
+		}
+	}
+
+	/**
+	 * Runs this operation and registers any deltas created.
+	 *
+	 * @see IWorkspaceRunnable
+	 * @exception CoreException if the operation fails
+	 */
+	public void run(IProgressMonitor monitor) throws CoreException {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		DeltaProcessor deltaProcessor = manager.getDeltaProcessor();
+		int previousDeltaCount = deltaProcessor.javaModelDeltas.size();
+		try {
+			this.progressMonitor = monitor;
+			pushOperation(this);
+			try {
+				if (canModifyRoots()) {
+					// computes the root infos before executing the operation
+					// noop if aready initialized
+					JavaModelManager.getDeltaState().initializeRoots(false/*not initiAfterLoad*/);
+				}
+
+				executeOperation();
+			} finally {
+				if (isTopLevelOperation()) {
+					runPostActions();
+				}
+			}
+		} finally {
+			try {
+				// reacquire delta processor as it can have been reset during executeOperation()
+				deltaProcessor = manager.getDeltaProcessor();
+
+				// update JavaModel using deltas that were recorded during this operation
+				for (int i = previousDeltaCount, size = deltaProcessor.javaModelDeltas.size(); i < size; i++) {
+					deltaProcessor.updateJavaModel((IJavaElementDelta)deltaProcessor.javaModelDeltas.get(i));
+				}
+
+				// close the parents of the created elements and reset their project's cache (in case we are in an
+				// IWorkspaceRunnable and the clients wants to use the created element's parent)
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83646
+				for (int i = 0, length = this.resultElements.length; i < length; i++) {
+					IJavaElement element = this.resultElements[i];
+					Openable openable = (Openable) element.getOpenable();
+					if (!(openable instanceof CompilationUnit) || !((CompilationUnit) openable).isWorkingCopy()) { // a working copy must remain a child of its parent even after a move
+						((JavaElement) openable.getParent()).close();
+					}
+					switch (element.getElementType()) {
+						case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+						case IJavaElement.PACKAGE_FRAGMENT:
+							deltaProcessor.projectCachesToReset.add(element.getJavaProject());
+							break;
+					}
+				}
+				deltaProcessor.resetProjectCaches();
+
+				// fire only iff:
+				// - the operation is a top level operation
+				// - the operation did produce some delta(s)
+				// - but the operation has not modified any resource
+				if (isTopLevelOperation()) {
+					if ((deltaProcessor.javaModelDeltas.size() > previousDeltaCount || !deltaProcessor.reconcileDeltas.isEmpty())
+							&& !hasModifiedResource()) {
+						deltaProcessor.fire(null, DeltaProcessor.DEFAULT_CHANGE_EVENT);
+					} // else deltas are fired while processing the resource delta
+				}
+			} finally {
+				popOperation();
+			}
+		}
+	}
+	/**
+	 * Main entry point for Java Model operations. Runs a Java Model Operation as an IWorkspaceRunnable
+	 * if not read-only.
+	 */
+	public void runOperation(IProgressMonitor monitor) throws JavaModelException {
+		IJavaModelStatus status= verify();
+		if (!status.isOK()) {
+			throw new JavaModelException(status);
+		}
+		try {
+			if (isReadOnly()) {
+				run(monitor);
+			} else {
+				// Use IWorkspace.run(...) to ensure that resource changes are batched
+				// Note that if the tree is locked, this will throw a CoreException, but this is ok
+				// as this operation is modifying the tree (not read-only) and a CoreException will be thrown anyway.
+				ResourcesPlugin.getWorkspace().run(this, getSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor);
+			}
+		} catch (CoreException ce) {
+			if (ce instanceof JavaModelException) {
+				throw (JavaModelException)ce;
+			} else {
+				if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) {
+					Throwable e= ce.getStatus().getException();
+					if (e instanceof JavaModelException) {
+						throw (JavaModelException) e;
+					}
+				}
+				throw new JavaModelException(ce);
+			}
+		}
+	}
+	protected void runPostActions() throws JavaModelException {
+		while (this.actionsStart <= this.actionsEnd) {
+			IPostAction postAction = this.actions[this.actionsStart++];
+			if (POST_ACTION_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [JavaModelOperation.runPostActions()] Running action " + postAction.getID()); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			postAction.run();
+		}
+	}
+	/*
+	 * Registers the given attribute at the given key with the top level operation.
+	 */
+	protected static void setAttribute(Object key, Object attribute) {
+		ArrayList operationStack = getCurrentOperationStack();
+		if (operationStack.size() == 0)
+			return;
+		JavaModelOperation topLevelOp = (JavaModelOperation) operationStack.get(0);
+		if (topLevelOp.attributes == null) {
+			topLevelOp.attributes = new HashMap();
+		}
+		topLevelOp.attributes.put(key, attribute);
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void setCanceled(boolean b) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.setCanceled(b);
+		}
+	}
+	/**
+	 * Sets whether this operation is nested or not.
+	 * @see CreateElementInCUOperation#checkCanceled
+	 */
+	protected void setNested(boolean nested) {
+		this.isNested = nested;
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void setTaskName(String name) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.setTaskName(name);
+		}
+	}
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void subTask(String name) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.subTask(name);
+		}
+	}
+	/**
+	 * Returns a status indicating if there is any known reason
+	 * this operation will fail.  Operations are verified before they
+	 * are run.
+	 *
+	 * Subclasses must override if they have any conditions to verify
+	 * before this operation executes.
+	 *
+	 * @see IJavaModelStatus
+	 */
+	protected IJavaModelStatus verify() {
+		return commonVerify();
+	}
+
+	/**
+	 * @see IProgressMonitor
+	 */
+	public void worked(int work) {
+		if (this.progressMonitor != null) {
+			this.progressMonitor.worked(work);
+			checkCanceled();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java
new file mode 100644
index 0000000..1a00353
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java
@@ -0,0 +1,506 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * @see IJavaModelStatus
+ */
+
+public class JavaModelStatus extends Status implements IJavaModelStatus, IJavaModelStatusConstants {
+
+	/**
+	 * The elements related to the failure, or <code>null</code>
+	 * if no elements are involved.
+	 */
+	protected IJavaElement[] elements = new IJavaElement[0];
+	/**
+	 * The path related to the failure, or <code>null</code>
+	 * if no path is involved.
+	 */
+	protected IPath path;
+	/**
+	 * The <code>String</code> related to the failure, or <code>null</code>
+	 * if no <code>String</code> is involved.
+	 */
+	protected String string;
+	/**
+	 * Empty children
+	 */
+	protected final static IStatus[] NO_CHILDREN = new IStatus[] {};
+	protected IStatus[] children= NO_CHILDREN;
+
+	/**
+	 * Singleton OK object
+	 */
+	public static final IJavaModelStatus VERIFIED_OK = new JavaModelStatus(OK, OK, Messages.status_OK);
+
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus() {
+		// no code for an multi-status
+		super(ERROR, JavaCore.PLUGIN_ID, 0, "JavaModelStatus", null); //$NON-NLS-1$
+	}
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(int code) {
+		super(ERROR, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
+		this.elements= JavaElement.NO_ELEMENTS;
+	}
+	/**
+	 * Constructs an Java model status with the given corresponding
+	 * elements.
+	 */
+	public JavaModelStatus(int code, IJavaElement[] elements) {
+		super(ERROR, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
+		this.elements= elements;
+		this.path= null;
+	}
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(int code, String string) {
+		this(ERROR, code, string);
+	}
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(int severity, int code, String string) {
+		super(severity, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
+		this.elements= JavaElement.NO_ELEMENTS;
+		this.path= null;
+		this.string = string;
+	}
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(int code, Throwable throwable) {
+		super(ERROR, JavaCore.PLUGIN_ID, code, "JavaModelStatus", throwable); //$NON-NLS-1$
+		this.elements= JavaElement.NO_ELEMENTS;
+	}
+	/**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(int code, IPath path) {
+		super(ERROR, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
+		this.elements= JavaElement.NO_ELEMENTS;
+		this.path= path;
+	}
+	/**
+	 * Constructs an Java model status with the given corresponding
+	 * element.
+	 */
+	public JavaModelStatus(int code, IJavaElement element) {
+		this(code, new IJavaElement[]{element});
+	}
+	/**
+	 * Constructs an Java model status with the given corresponding
+	 * element and string
+	 */
+	public JavaModelStatus(int code, IJavaElement element, String string) {
+		this(code, new IJavaElement[]{element});
+		this.string = string;
+	}
+
+	/**
+	 * Constructs an Java model status with the given corresponding
+	 * element and path
+	 */
+	public JavaModelStatus(int code, IJavaElement element, IPath path) {
+		this(code, new IJavaElement[]{element});
+		this.path = path;
+	}
+
+	/**
+	 * Constructs an Java model status with the given corresponding
+	 * element, path and string
+	 */
+	public JavaModelStatus(int code, IJavaElement element, IPath path, String string) {
+		this(code, new IJavaElement[]{element});
+		this.path = path;
+		this.string = string;
+	}
+
+	/**
+     * Constructs an Java model status with the given corresponding
+     * element and path
+     */
+    public JavaModelStatus(int severity, int code, IJavaElement element, IPath path, String msg) {
+    	super(severity, JavaCore.PLUGIN_ID, code, "JavaModelStatus", null); //$NON-NLS-1$
+    	this.elements= new IJavaElement[]{element};
+    	this.path = path;
+    	this.string = msg;
+    }
+
+    /**
+	 * Constructs an Java model status with no corresponding elements.
+	 */
+	public JavaModelStatus(CoreException coreException) {
+		super(ERROR, JavaCore.PLUGIN_ID, CORE_EXCEPTION, "JavaModelStatus", coreException); //$NON-NLS-1$
+		this.elements= JavaElement.NO_ELEMENTS;
+	}
+	protected int getBits() {
+		int severity = 1 << (getCode() % 100 / 33);
+		int category = 1 << ((getCode() / 100) + 3);
+		return severity | category;
+	}
+	/**
+	 * @see IStatus
+	 */
+	public IStatus[] getChildren() {
+		return this.children;
+	}
+	/**
+	 * @see IJavaModelStatus
+	 */
+	public IJavaElement[] getElements() {
+		return this.elements;
+	}
+	/**
+	 * Returns the message that is relevant to the code of this status.
+	 */
+	public String getMessage() {
+		Throwable exception = getException();
+		if (exception == null) {
+			switch (getCode()) {
+				case CORE_EXCEPTION :
+					return Messages.status_coreException;
+
+				case BUILDER_INITIALIZATION_ERROR:
+					return Messages.build_initializationError;
+
+				case BUILDER_SERIALIZATION_ERROR:
+					return Messages.build_serializationError;
+
+				case DEVICE_PATH:
+					return Messages.bind(Messages.status_cannotUseDeviceOnPath, getPath().toString());
+
+				case DOM_EXCEPTION:
+					return Messages.status_JDOMError;
+
+				case ELEMENT_DOES_NOT_EXIST:
+					return Messages.bind(Messages.element_doesNotExist, ((JavaElement)this.elements[0]).toStringWithAncestors());
+
+				case ELEMENT_NOT_ON_CLASSPATH:
+					return Messages.bind(Messages.element_notOnClasspath, ((JavaElement)this.elements[0]).toStringWithAncestors());
+
+				case EVALUATION_ERROR:
+					return Messages.bind(Messages.status_evaluationError, this.string);
+
+				case INDEX_OUT_OF_BOUNDS:
+					return Messages.status_indexOutOfBounds;
+
+				case INVALID_CONTENTS:
+					return Messages.status_invalidContents;
+
+				case INVALID_DESTINATION:
+					return Messages.bind(Messages.status_invalidDestination, ((JavaElement)this.elements[0]).toStringWithAncestors());
+
+				case INVALID_ELEMENT_TYPES:
+					StringBuffer buff= new StringBuffer(Messages.operation_notSupported);
+					for (int i= 0; i < this.elements.length; i++) {
+						if (i > 0) {
+							buff.append(", "); //$NON-NLS-1$
+						}
+						buff.append(((JavaElement)this.elements[i]).toStringWithAncestors());
+					}
+					return buff.toString();
+
+				case INVALID_NAME:
+					return Messages.bind(Messages.status_invalidName, this.string);
+
+				case INVALID_PACKAGE:
+					return Messages.bind(Messages.status_invalidPackage, this.string);
+
+				case INVALID_PATH:
+					if (this.string != null) {
+						return this.string;
+					} else {
+						return Messages.bind(
+							Messages.status_invalidPath,
+							new String[] {getPath() == null ? "null" : getPath().toString()} //$NON-NLS-1$
+						);
+					}
+
+				case INVALID_PROJECT:
+					return Messages.bind(Messages.status_invalidProject, this.string);
+
+				case INVALID_RESOURCE:
+					return Messages.bind(Messages.status_invalidResource, this.string);
+
+				case INVALID_RESOURCE_TYPE:
+					return Messages.bind(Messages.status_invalidResourceType, this.string);
+
+				case INVALID_SIBLING:
+					if (this.string != null) {
+						return Messages.bind(Messages.status_invalidSibling, this.string);
+					} else {
+						return Messages.bind(Messages.status_invalidSibling, ((JavaElement)this.elements[0]).toStringWithAncestors());
+					}
+
+				case IO_EXCEPTION:
+					return Messages.status_IOException;
+
+				case NAME_COLLISION:
+					if (this.elements != null && this.elements.length > 0) {
+						IJavaElement element = this.elements[0];
+						if (element instanceof PackageFragment && ((PackageFragment) element).isDefaultPackage()) {
+							return Messages.operation_cannotRenameDefaultPackage;
+						}
+					}
+					if (this.string != null) {
+						return this.string;
+					} else {
+						return Messages.bind(Messages.status_nameCollision, "");  //$NON-NLS-1$
+					}
+				case NO_ELEMENTS_TO_PROCESS:
+					return Messages.operation_needElements;
+
+				case NULL_NAME:
+					return Messages.operation_needName;
+
+				case NULL_PATH:
+					return Messages.operation_needPath;
+
+				case NULL_STRING:
+					return Messages.operation_needString;
+
+				case PATH_OUTSIDE_PROJECT:
+					return Messages.bind(Messages.operation_pathOutsideProject, new String[] {this.string, ((JavaElement)this.elements[0]).toStringWithAncestors()});
+
+				case READ_ONLY:
+					IJavaElement element = this.elements[0];
+					String name = element.getElementName();
+					if (element instanceof IPackageFragment && name.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
+						return Messages.status_defaultPackageReadOnly;
+					}
+					return Messages.bind(Messages.status_readOnly, name);
+
+				case RELATIVE_PATH:
+					return Messages.bind(Messages.operation_needAbsolutePath, getPath().toString());
+
+				case TARGET_EXCEPTION:
+					return Messages.status_targetException;
+
+				case UPDATE_CONFLICT:
+					return Messages.status_updateConflict;
+
+				case NO_LOCAL_CONTENTS :
+					return Messages.bind(Messages.status_noLocalContents, getPath().toString());
+
+				case CP_CONTAINER_PATH_UNBOUND:
+					IJavaProject javaProject = (IJavaProject)this.elements[0];
+					ClasspathContainerInitializer initializer = JavaCore.getClasspathContainerInitializer(this.path.segment(0));
+					String description = null;
+					if (initializer != null) description = initializer.getDescription(this.path, javaProject);
+					if (description == null) description = this.path.makeRelative().toString();
+					return Messages.bind(Messages.classpath_unboundContainerPath, new String[] {description, javaProject.getElementName()});
+
+				case INVALID_CP_CONTAINER_ENTRY:
+					javaProject = (IJavaProject)this.elements[0];
+					IClasspathContainer container = null;
+					description = null;
+					try {
+						container = JavaCore.getClasspathContainer(this.path, javaProject);
+					} catch(JavaModelException e){
+						// project doesn't exist: ignore
+					}
+					if (container == null) {
+						 initializer = JavaCore.getClasspathContainerInitializer(this.path.segment(0));
+						if (initializer != null) description = initializer.getDescription(this.path, javaProject);
+					} else {
+						description = container.getDescription();
+					}
+					if (description == null) description = this.path.makeRelative().toString();
+					return Messages.bind(Messages.classpath_invalidContainer, new String[] {description, javaProject.getElementName()});
+
+				case CP_VARIABLE_PATH_UNBOUND:
+					javaProject = (IJavaProject)this.elements[0];
+					return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {this.path.makeRelative().toString(), javaProject.getElementName()});
+
+				case CLASSPATH_CYCLE:
+					javaProject = (IJavaProject)this.elements[0];
+					return Messages.bind(Messages.classpath_cycle, new String[] {javaProject.getElementName(), this.string});
+
+				case DISABLED_CP_EXCLUSION_PATTERNS:
+					javaProject = (IJavaProject)this.elements[0];
+					String projectName = javaProject.getElementName();
+					IPath newPath = this.path;
+					if (this.path.segment(0).toString().equals(projectName)) {
+						newPath = this.path.removeFirstSegments(1);
+					}
+					return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName});
+
+				case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS:
+					javaProject = (IJavaProject)this.elements[0];
+					projectName = javaProject.getElementName();
+					newPath = this.path;
+					if (this.path.segment(0).toString().equals(projectName)) {
+						newPath = this.path.removeFirstSegments(1);
+					}
+					return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName});
+
+				case CANNOT_RETRIEVE_ATTACHED_JAVADOC :
+					if (this.elements != null && this.elements.length == 1) {
+						if (this.string != null) {
+							return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)this.elements[0]).toStringWithAncestors(), this.string);
+						}
+						return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, ((JavaElement)this.elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$
+					}
+					if (this.string != null) {
+						return Messages.bind(Messages.status_cannot_retrieve_attached_javadoc, this.string, "");//$NON-NLS-1$
+					}
+					break;
+					
+				case CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT :
+					if (this.elements != null && this.elements.length == 1) {
+						if (this.string != null) {
+							return Messages.bind(Messages.status_timeout_javadoc, ((JavaElement)this.elements[0]).toStringWithAncestors(), this.string);
+						}
+						return Messages.bind(Messages.status_timeout_javadoc, ((JavaElement)this.elements[0]).toStringWithAncestors(), ""); //$NON-NLS-1$
+					}
+					if (this.string != null) {
+						return Messages.bind(Messages.status_timeout_javadoc, this.string, "");//$NON-NLS-1$
+					}
+					break;
+
+				case UNKNOWN_JAVADOC_FORMAT :
+					return Messages.bind(Messages.status_unknown_javadoc_format, ((JavaElement)this.elements[0]).toStringWithAncestors());
+
+				case DEPRECATED_VARIABLE :
+					javaProject = (IJavaProject)this.elements[0];
+					return Messages.bind(Messages.classpath_deprecated_variable, new String[] {this.path.segment(0).toString(), javaProject.getElementName(), this.string});
+			}
+			if (this.string != null) {
+				return this.string;
+			} else {
+				return ""; //$NON-NLS-1$
+			}
+		} else {
+			String message = exception.getMessage();
+			if (message != null) {
+				return message;
+			} else {
+				return exception.toString();
+			}
+		}
+	}
+	/**
+	 * @see IJavaModelStatus#getPath()
+	 */
+	public IPath getPath() {
+		return this.path;
+	}
+	/**
+	 * @see IStatus#getSeverity()
+	 */
+	public int getSeverity() {
+		if (this.children == NO_CHILDREN) return super.getSeverity();
+		int severity = -1;
+		for (int i = 0, max = this.children.length; i < max; i++) {
+			int childrenSeverity = this.children[i].getSeverity();
+			if (childrenSeverity > severity) {
+				severity = childrenSeverity;
+			}
+		}
+		return severity;
+	}
+	/**
+	 * @see IJavaModelStatus#getString()
+	 * @deprecated
+	 */
+	public String getString() {
+		return this.string;
+	}
+	/**
+	 * @see IJavaModelStatus#isDoesNotExist()
+	 */
+	public boolean isDoesNotExist() {
+		int code = getCode();
+		return code == ELEMENT_DOES_NOT_EXIST || code == ELEMENT_NOT_ON_CLASSPATH;
+	}
+	/**
+	 * @see IStatus#isMultiStatus()
+	 */
+	public boolean isMultiStatus() {
+		return this.children != NO_CHILDREN;
+	}
+	/**
+	 * @see IStatus#isOK()
+	 */
+	public boolean isOK() {
+		return getCode() == OK;
+	}
+	/**
+	 * @see IStatus#matches(int)
+	 */
+	public boolean matches(int mask) {
+		if (! isMultiStatus()) {
+			return matches(this, mask);
+		} else {
+			for (int i = 0, max = this.children.length; i < max; i++) {
+				if (matches((JavaModelStatus) this.children[i], mask))
+					return true;
+			}
+			return false;
+		}
+	}
+	/**
+	 * Helper for matches(int).
+	 */
+	protected boolean matches(JavaModelStatus status, int mask) {
+		int severityMask = mask & 0x7;
+		int categoryMask = mask & ~0x7;
+		int bits = status.getBits();
+		return ((severityMask == 0) || (bits & severityMask) != 0) && ((categoryMask == 0) || (bits & categoryMask) != 0);
+	}
+	/**
+	 * Creates and returns a new <code>IJavaModelStatus</code> that is a
+	 * a multi-status status.
+	 *
+	 * @see IStatus#isMultiStatus()
+	 */
+	public static IJavaModelStatus newMultiStatus(IJavaModelStatus[] children) {
+		JavaModelStatus jms = new JavaModelStatus();
+		jms.children = children;
+		return jms;
+	}
+	/**
+	 * Returns a printable representation of this exception for debugging
+	 * purposes.
+	 */
+	public String toString() {
+		if (this == VERIFIED_OK){
+			return "JavaModelStatus[OK]"; //$NON-NLS-1$
+		}
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Java Model Status ["); //$NON-NLS-1$
+		buffer.append(getMessage());
+		buffer.append("]"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
new file mode 100644
index 0000000..4ac2ed7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -0,0 +1,3240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ *     						Bug 320618 - inconsistent initialization of classpath container backed by external class folder
+ *     						Bug 346010 - [model] strange initialization dependency in OptionTests
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.*;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.eval.IEvaluationContext;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper;
+import org.eclipse.jdt.internal.core.util.JavaElementFinder;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.eval.EvaluationContext;
+import org.osgi.service.prefs.BackingStoreException;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Handle for a Java Project.
+ *
+ * <p>A Java Project internally maintains a devpath that corresponds
+ * to the project's classpath. The classpath may include source folders
+ * from the current project; jars in the current project, other projects,
+ * and the local file system; and binary folders (output location) of other
+ * projects. The Java Model presents source elements corresponding to output
+ * .class files in other projects, and thus uses the devpath rather than
+ * the classpath (which is really a compilation path). The devpath mimics
+ * the classpath, except has source folder entries in place of output
+ * locations in external projects.
+ *
+ * <p>Each JavaProject has a NameLookup facility that locates elements
+ * on by name, based on the devpath.
+ *
+ * @see IJavaProject
+ */
+public class JavaProject
+	extends Openable
+	implements IJavaProject, IProjectNature, SuffixConstants {
+
+	/**
+	 * Name of file containing project classpath
+	 */
+	public static final String CLASSPATH_FILENAME = IJavaProject.CLASSPATH_FILE_NAME;
+
+	/**
+	 * Value of the project's raw classpath if the .classpath file contains invalid entries.
+	 */
+	public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0];
+
+	/**
+	 * Whether the underlying file system is case sensitive.
+	 */
+	protected static final boolean IS_CASE_SENSITIVE = !new File("Temp").equals(new File("temp")); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/**
+	 * An empty array of strings indicating that a project doesn't have any prerequesite projects.
+	 */
+	protected static final String[] NO_PREREQUISITES = CharOperation.NO_STRINGS;
+
+	/**
+	 * Name of file containing custom project preferences
+	 * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59258">bug 59258</a>
+	 */
+	private static final String PREF_FILENAME = ".jprefs";  //$NON-NLS-1$
+
+	/**
+	 * Name of directory containing preferences file
+	 */
+	public static final String DEFAULT_PREFERENCES_DIRNAME = ".settings"; //$NON-NLS-1$
+
+	/**
+	 * Extension for file containing custom project preferences
+	 */
+	public static final String JAVA_CORE_PREFS_FILE = JavaCore.PLUGIN_ID+".prefs"; //$NON-NLS-1$
+
+	/*
+	 * Value of project's resolved classpath while it is being resolved
+	 */
+	private static final IClasspathEntry[] RESOLUTION_IN_PROGRESS = new IClasspathEntry[0];
+
+	/*
+	 * For testing purpose only
+	 */
+	private static ArrayList CP_RESOLUTION_BP_LISTENERS;
+	public static class ClasspathResolutionBreakpointListener {
+		public void breakpoint(int bp) {
+			// override in listener implementation
+		}
+	}
+
+	/**
+	 * The platform project this <code>IJavaProject</code> is based on
+	 */
+	protected IProject project;
+
+	/**
+	 * Preferences listeners
+	 */
+	private IEclipsePreferences.INodeChangeListener preferencesNodeListener;
+	private IEclipsePreferences.IPreferenceChangeListener preferencesChangeListener;
+
+	/**
+	 * Constructor needed for <code>IProject.getNature()</code> and <code>IProject.addNature()</code>.
+	 *
+	 * @see #setProject(IProject)
+	 */
+	public JavaProject() {
+		super(null);
+	}
+
+	public JavaProject(IProject project, JavaElement parent) {
+		super(parent);
+		this.project = project;
+	}
+
+	/*
+	 * For testing purpose only
+	 */
+	public static synchronized void addCPResolutionBPListener(ClasspathResolutionBreakpointListener listener) {
+		if (CP_RESOLUTION_BP_LISTENERS == null)
+			CP_RESOLUTION_BP_LISTENERS = new ArrayList();
+		CP_RESOLUTION_BP_LISTENERS.add(listener);
+	}
+
+	/*
+	 * For testing purpose only
+	 */
+	public static synchronized void removeCPResolutionBPListener(ClasspathResolutionBreakpointListener listener) {
+		if (CP_RESOLUTION_BP_LISTENERS == null)
+			return;
+		CP_RESOLUTION_BP_LISTENERS.remove(listener);
+		if (CP_RESOLUTION_BP_LISTENERS.size() == 0)
+			CP_RESOLUTION_BP_LISTENERS = null;
+	}
+
+	private static synchronized ClasspathResolutionBreakpointListener[] getBPListeners() {
+		if (CP_RESOLUTION_BP_LISTENERS == null)
+			return null;
+		return (ClasspathResolutionBreakpointListener[]) CP_RESOLUTION_BP_LISTENERS.toArray(new ClasspathResolutionBreakpointListener[CP_RESOLUTION_BP_LISTENERS.size()]);
+	}
+
+	private static void breakpoint(int bp, JavaProject project) {
+		ClasspathResolutionBreakpointListener[] listeners = getBPListeners();
+		if (listeners == null)
+			return;
+		for (int j = 0, length = listeners.length; j < length; j++) {
+			listeners[j].breakpoint(bp);
+		}
+	}
+
+	public static boolean areClasspathsEqual(
+			IClasspathEntry[] firstClasspath, IClasspathEntry[] secondClasspath,
+			IPath firstOutputLocation, IPath secondOutputLocation) {
+		int length = firstClasspath.length;
+		if (length != secondClasspath.length) return false;
+		for (int i = 0; i < length; i++) {
+			if (!firstClasspath[i].equals(secondClasspath[i]))
+				return false;
+		}
+		if (firstOutputLocation == null)
+			return secondOutputLocation == null;
+		return firstOutputLocation.equals(secondOutputLocation);
+	}
+
+	/**
+	 * Compare current classpath with given one to see if any different.
+	 * Note that the argument classpath contains its binary output.
+	 * @param newClasspath IClasspathEntry[]
+	 * @param newOutputLocation IPath
+	 * @param otherClasspathWithOutput IClasspathEntry[]
+	 * @return boolean
+	 */
+	private static boolean areClasspathsEqual(IClasspathEntry[] newClasspath, IPath newOutputLocation, IClasspathEntry[] otherClasspathWithOutput) {
+
+		if (otherClasspathWithOutput == null || otherClasspathWithOutput.length == 0)
+			return false;
+
+		int length = otherClasspathWithOutput.length;
+		if (length != newClasspath.length + 1)
+				// output is amongst file entries (last one)
+				return false;
+
+
+		// compare classpath entries
+		for (int i = 0; i < length - 1; i++) {
+			if (!otherClasspathWithOutput[i].equals(newClasspath[i]))
+				return false;
+		}
+		// compare binary outputs
+		IClasspathEntry output = otherClasspathWithOutput[length - 1];
+		if (output.getContentKind() != ClasspathEntry.K_OUTPUT
+				|| !output.getPath().equals(newOutputLocation))
+			return false;
+		return true;
+	}
+	
+	private static boolean areClasspathsEqual(IClasspathEntry[] first, IClasspathEntry[] second) {
+		if (first != second){
+		    if (first == null) return false;
+			int length = first.length;
+			if (second == null || second.length != length)
+				return false;
+			for (int i = 0; i < length; i++) {
+				if (!first[i].equals(second[i]))
+					return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Returns a canonicalized path from the given external path.
+	 * Note that the return path contains the same number of segments
+	 * and it contains a device only if the given path contained one.
+	 * @param externalPath IPath
+	 * @see java.io.File for the definition of a canonicalized path
+	 * @return IPath
+	 */
+	public static IPath canonicalizedPath(IPath externalPath) {
+
+		if (externalPath == null)
+			return null;
+
+		if (IS_CASE_SENSITIVE) {
+			return externalPath;
+		}
+		
+		// if not external path, return original path
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		if (workspace == null) return externalPath; // protection during shutdown (30487)
+		if (workspace.getRoot().findMember(externalPath) != null) {
+			return externalPath;
+		}
+
+		IPath canonicalPath = null;
+		try {
+			canonicalPath =
+				new Path(new File(externalPath.toOSString()).getCanonicalPath());
+		} catch (IOException e) {
+			// default to original path
+			return externalPath;
+		}
+
+		IPath result;
+		int canonicalLength = canonicalPath.segmentCount();
+		if (canonicalLength == 0) {
+			// the java.io.File canonicalization failed
+			return externalPath;
+		} else if (externalPath.isAbsolute()) {
+			result = canonicalPath;
+		} else {
+			// if path is relative, remove the first segments that were added by the java.io.File canonicalization
+			// e.g. 'lib/classes.zip' was converted to 'd:/myfolder/lib/classes.zip'
+			int externalLength = externalPath.segmentCount();
+			if (canonicalLength >= externalLength) {
+				result = canonicalPath.removeFirstSegments(canonicalLength - externalLength);
+			} else {
+				return externalPath;
+			}
+		}
+
+		// keep device only if it was specified (this is because File.getCanonicalPath() converts '/lib/classes.zip' to 'd:/lib/classes/zip')
+		if (externalPath.getDevice() == null) {
+			result = result.setDevice(null);
+		}
+		// keep trailing separator only if it was specified (this is because File.getCanonicalPath() converts 'd:/lib/classes/' to 'd:/lib/classes')
+		if (externalPath.hasTrailingSeparator()) {
+			result = result.addTrailingSeparator();
+		}
+		return result;
+	}
+
+	/**
+	 * Returns true if the given project is accessible and it has
+	 * a java nature, otherwise false.
+	 * @param project IProject
+	 * @return boolean
+	 */
+	public static boolean hasJavaNature(IProject project) {
+		try {
+			return project.hasNature(JavaCore.NATURE_ID);
+		} catch (CoreException e) {
+			if (ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(project.getName()))
+				return true;
+			// project does not exist or is not open
+		}
+		return false;
+	}
+
+	/*
+	 * Detect cycles in the classpath of the workspace's projects
+	 * and create markers if necessary.
+	 * @param preferredClasspaths Map
+	 * @throws JavaModelException
+	 */
+	public static void validateCycles(Map preferredClasspaths) throws JavaModelException {
+
+		//long start = System.currentTimeMillis();
+
+		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+		IProject[] rscProjects = workspaceRoot.getProjects();
+		int length = rscProjects.length;
+		JavaProject[] projects = new JavaProject[length];
+
+		LinkedHashSet cycleParticipants = new LinkedHashSet();
+		HashSet traversed = new HashSet();
+
+		// compute cycle participants
+		ArrayList prereqChain = new ArrayList();
+		for (int i = 0; i < length; i++){
+			if (hasJavaNature(rscProjects[i])) {
+				JavaProject project = (projects[i] = (JavaProject)JavaCore.create(rscProjects[i]));
+				if (!traversed.contains(project.getPath())){
+					prereqChain.clear();
+					project.updateCycleParticipants(prereqChain, cycleParticipants, workspaceRoot, traversed, preferredClasspaths);
+				}
+			}
+		}
+		//System.out.println("updateAllCycleMarkers: " + (System.currentTimeMillis() - start) + " ms");
+
+		for (int i = 0; i < length; i++){
+			JavaProject project = projects[i];
+			if (project != null) {
+				if (cycleParticipants.contains(project.getPath())){
+					IMarker cycleMarker = project.getCycleMarker();
+					String circularCPOption = project.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true);
+					int circularCPSeverity = JavaCore.ERROR.equals(circularCPOption) ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING;
+					if (cycleMarker != null) {
+						// update existing cycle marker if needed
+						try {
+							int existingSeverity = ((Integer)cycleMarker.getAttribute(IMarker.SEVERITY)).intValue();
+							if (existingSeverity != circularCPSeverity) {
+								cycleMarker.setAttribute(IMarker.SEVERITY, circularCPSeverity);
+							}
+						} catch (CoreException e) {
+							throw new JavaModelException(e);
+						}
+					} else {
+						IJavaProject[] projectsInCycle;
+						String cycleString = "";	 //$NON-NLS-1$
+						if (cycleParticipants.isEmpty()) {
+							projectsInCycle = null;
+						} else {
+							projectsInCycle = new IJavaProject[cycleParticipants.size()];
+							Iterator it = cycleParticipants.iterator();
+							int k = 0;
+							while (it.hasNext()) {
+								//projectsInCycle[i++] = (IPath) it.next();
+								IResource member = workspaceRoot.findMember((IPath) it.next());
+								if (member != null && member.getType() == IResource.PROJECT){
+									projectsInCycle[k] = JavaCore.create((IProject)member);
+									if (projectsInCycle[k] != null) {
+										if (k != 0) cycleString += ", "; //$NON-NLS-1$
+										cycleString += projectsInCycle[k++].getElementName();
+									}
+								}
+							}
+						}
+						// create new marker
+						project.createClasspathProblemMarker(
+							new JavaModelStatus(IJavaModelStatusConstants.CLASSPATH_CYCLE, project, cycleString));
+					}
+				} else {
+					project.flushClasspathProblemMarkers(true, false, false);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Adds a builder to the build spec for the given project.
+	 */
+	protected void addToBuildSpec(String builderID) throws CoreException {
+
+		IProjectDescription description = this.project.getDescription();
+		int javaCommandIndex = getJavaCommandIndex(description.getBuildSpec());
+
+		if (javaCommandIndex == -1) {
+
+			// Add a Java command to the build spec
+			ICommand command = description.newCommand();
+			command.setBuilderName(builderID);
+			setJavaCommand(description, command);
+		}
+	}
+	/**
+	 * @see Openable
+	 */
+	protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+		// cannot refresh cp markers on opening (emulate cp check on startup) since can create deadlocks (see bug 37274)
+		IClasspathEntry[] resolvedClasspath = getResolvedClasspath();
+
+		// compute the pkg fragment roots
+		info.setChildren(computePackageFragmentRoots(resolvedClasspath, false, null /*no reverse map*/));
+
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.JavaElement#close()
+	 */
+	public void close() throws JavaModelException {
+		if (JavaProject.hasJavaNature(this.project)) {
+			// Get cached preferences if exist
+			JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(this.project, false);
+			if (perProjectInfo != null && perProjectInfo.preferences != null) {
+				IEclipsePreferences eclipseParentPreferences = (IEclipsePreferences) perProjectInfo.preferences.parent();
+				if (this.preferencesNodeListener != null) {
+					eclipseParentPreferences.removeNodeChangeListener(this.preferencesNodeListener);
+					this.preferencesNodeListener = null;
+				}
+				if (this.preferencesChangeListener != null) {
+					perProjectInfo.preferences.removePreferenceChangeListener(this.preferencesChangeListener);
+					this.preferencesChangeListener = null;
+				}
+			}
+		}
+		super.close();
+	}
+
+	/**
+	 * Internal computation of an expanded classpath. It will eliminate duplicates, and produce copies
+	 * of exported or restricted classpath entries to avoid possible side-effects ever after.
+	 */
+	private void computeExpandedClasspath(
+		ClasspathEntry referringEntry,
+		HashSet rootIDs,
+		ObjectVector accumulatedEntries) throws JavaModelException {
+
+		String projectRootId = rootID();
+		if (rootIDs.contains(projectRootId)){
+			return; // break cycles if any
+		}
+		rootIDs.add(projectRootId);
+
+		IClasspathEntry[] resolvedClasspath = getResolvedClasspath();
+
+		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+		boolean isInitialProject = referringEntry == null;
+		for (int i = 0, length = resolvedClasspath.length; i < length; i++){
+			ClasspathEntry entry = (ClasspathEntry) resolvedClasspath[i];
+			if (isInitialProject || entry.isExported()){
+				String rootID = entry.rootID();
+				if (rootIDs.contains(rootID)) {
+					continue;
+				}
+				// combine restrictions along the project chain
+				ClasspathEntry combinedEntry = entry.combineWith(referringEntry);
+				accumulatedEntries.add(combinedEntry);
+
+				// recurse in project to get all its indirect exports (only consider exported entries from there on)
+				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+					IResource member = workspaceRoot.findMember(entry.getPath());
+					if (member != null && member.getType() == IResource.PROJECT){ // double check if bound to project (23977)
+						IProject projRsc = (IProject) member;
+						if (JavaProject.hasJavaNature(projRsc)) {
+							JavaProject javaProject = (JavaProject) JavaCore.create(projRsc);
+							javaProject.computeExpandedClasspath(
+								combinedEntry,
+								rootIDs,
+								accumulatedEntries);
+						}
+					}
+				} else {
+					rootIDs.add(rootID);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Computes the package fragment roots identified by the given entry.
+	 * Only works with resolved entry
+	 * @param resolvedEntry IClasspathEntry
+	 * @return IPackageFragmentRoot[]
+	 */
+	public IPackageFragmentRoot[] computePackageFragmentRoots(IClasspathEntry resolvedEntry) {
+		try {
+			return
+				computePackageFragmentRoots(
+					new IClasspathEntry[]{ resolvedEntry },
+					false, // don't retrieve exported roots
+					null /* no reverse map */
+				);
+		} catch (JavaModelException e) {
+			return new IPackageFragmentRoot[] {};
+		}
+	}
+
+	/**
+	 * Returns the package fragment roots identified by the given entry. In case it refers to
+	 * a project, it will follow its classpath so as to find exported roots as well.
+	 * Only works with resolved entry
+	 * @param resolvedEntry IClasspathEntry
+	 * @param accumulatedRoots ObjectVector
+	 * @param rootIDs HashSet
+	 * @param referringEntry the CP entry (project) referring to this entry, or null if initial project
+	 * @param retrieveExportedRoots boolean
+	 * @throws JavaModelException
+	 */
+	public void computePackageFragmentRoots(
+		IClasspathEntry resolvedEntry,
+		ObjectVector accumulatedRoots,
+		HashSet rootIDs,
+		IClasspathEntry referringEntry,
+		boolean retrieveExportedRoots,
+		Map rootToResolvedEntries) throws JavaModelException {
+
+		String rootID = ((ClasspathEntry)resolvedEntry).rootID();
+		if (rootIDs.contains(rootID)) return;
+
+		IPath projectPath = this.project.getFullPath();
+		IPath entryPath = resolvedEntry.getPath();
+		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+		IPackageFragmentRoot root = null;
+
+		switch(resolvedEntry.getEntryKind()){
+
+			// source folder
+			case IClasspathEntry.CPE_SOURCE :
+
+				if (projectPath.isPrefixOf(entryPath)){
+					Object target = JavaModel.getTarget(entryPath, true/*check existency*/);
+					if (target == null) return;
+
+					if (target instanceof IFolder || target instanceof IProject){
+						root = getPackageFragmentRoot((IResource)target);
+					}
+				}
+				break;
+
+			// internal/external JAR or folder
+			case IClasspathEntry.CPE_LIBRARY :
+				if (referringEntry != null  && !resolvedEntry.isExported())
+					return;
+				Object target = JavaModel.getTarget(entryPath, true/*check existency*/);
+				if (target == null)
+					return;
+
+				if (target instanceof IResource){
+					// internal target
+					root = getPackageFragmentRoot((IResource) target, entryPath);
+				} else if (target instanceof File) {
+					// external target
+					if (JavaModel.isFile(target)) {
+						root = new JarPackageFragmentRoot(entryPath, this);
+					} else if (((File) target).isDirectory()) {
+						root = new ExternalPackageFragmentRoot(entryPath, this);
+					}
+				}
+				break;
+
+			// recurse into required project
+			case IClasspathEntry.CPE_PROJECT :
+
+				if (!retrieveExportedRoots) return;
+				if (referringEntry != null && !resolvedEntry.isExported()) return;
+
+				IResource member = workspaceRoot.findMember(entryPath);
+				if (member != null && member.getType() == IResource.PROJECT){// double check if bound to project (23977)
+					IProject requiredProjectRsc = (IProject) member;
+					if (JavaProject.hasJavaNature(requiredProjectRsc)){ // special builder binary output
+						rootIDs.add(rootID);
+						JavaProject requiredProject = (JavaProject)JavaCore.create(requiredProjectRsc);
+						requiredProject.computePackageFragmentRoots(
+							requiredProject.getResolvedClasspath(),
+							accumulatedRoots,
+							rootIDs,
+							rootToResolvedEntries == null ? resolvedEntry : ((ClasspathEntry)resolvedEntry).combineWith((ClasspathEntry) referringEntry), // only combine if need to build the reverse map
+							retrieveExportedRoots,
+							rootToResolvedEntries);
+					}
+				break;
+			}
+		}
+		if (root != null) {
+			accumulatedRoots.add(root);
+			rootIDs.add(rootID);
+			if (rootToResolvedEntries != null) rootToResolvedEntries.put(root, ((ClasspathEntry)resolvedEntry).combineWith((ClasspathEntry) referringEntry));
+		}
+	}
+
+	/**
+	 * Returns (local/all) the package fragment roots identified by the given project's classpath.
+	 * Note: this follows project classpath references to find required project contributions,
+	 * eliminating duplicates silently.
+	 * Only works with resolved entries
+	 * @param resolvedClasspath IClasspathEntry[]
+	 * @param retrieveExportedRoots boolean
+	 * @return IPackageFragmentRoot[]
+	 * @throws JavaModelException
+	 */
+	public IPackageFragmentRoot[] computePackageFragmentRoots(
+					IClasspathEntry[] resolvedClasspath,
+					boolean retrieveExportedRoots,
+					Map rootToResolvedEntries) throws JavaModelException {
+
+		ObjectVector accumulatedRoots = new ObjectVector();
+		computePackageFragmentRoots(
+			resolvedClasspath,
+			accumulatedRoots,
+			new HashSet(5), // rootIDs
+			null, // inside original project
+			retrieveExportedRoots,
+			rootToResolvedEntries);
+		IPackageFragmentRoot[] rootArray = new IPackageFragmentRoot[accumulatedRoots.size()];
+		accumulatedRoots.copyInto(rootArray);
+		return rootArray;
+	}
+
+	/**
+	 * Returns (local/all) the package fragment roots identified by the given project's classpath.
+	 * Note: this follows project classpath references to find required project contributions,
+	 * eliminating duplicates silently.
+	 * Only works with resolved entries
+	 * @param resolvedClasspath IClasspathEntry[]
+	 * @param accumulatedRoots ObjectVector
+	 * @param rootIDs HashSet
+	 * @param referringEntry project entry referring to this CP or null if initial project
+	 * @param retrieveExportedRoots boolean
+	 * @throws JavaModelException
+	 */
+	public void computePackageFragmentRoots(
+		IClasspathEntry[] resolvedClasspath,
+		ObjectVector accumulatedRoots,
+		HashSet rootIDs,
+		IClasspathEntry referringEntry,
+		boolean retrieveExportedRoots,
+		Map rootToResolvedEntries) throws JavaModelException {
+
+		if (referringEntry == null){
+			rootIDs.add(rootID());
+		}
+		for (int i = 0, length = resolvedClasspath.length; i < length; i++){
+			computePackageFragmentRoots(
+				resolvedClasspath[i],
+				accumulatedRoots,
+				rootIDs,
+				referringEntry,
+				retrieveExportedRoots,
+				rootToResolvedEntries);
+		}
+	}
+	/**
+	 * Compute the file name to use for a given shared property
+	 * @param qName QualifiedName
+	 * @return String
+	 */
+	public String computeSharedPropertyFileName(QualifiedName qName) {
+
+		return '.' + qName.getLocalName();
+	}
+
+	/**
+	 * Configure the project with Java nature.
+	 */
+	public void configure() throws CoreException {
+
+		// register Java builder
+		addToBuildSpec(JavaCore.BUILDER_ID);
+	}
+
+	/*
+	 * Returns whether the given resource is accessible through the children or the non-Java resources of this project.
+	 * Returns true if the resource is not in the project.
+	 * Assumes that the resource is a folder or a file.
+	 */
+	public boolean contains(IResource resource) {
+
+		IClasspathEntry[] classpath;
+		IPath output;
+		try {
+			classpath = getResolvedClasspath();
+			output = getOutputLocation();
+		} catch (JavaModelException e) {
+			return false;
+		}
+
+		IPath fullPath = resource.getFullPath();
+		IPath innerMostOutput = output.isPrefixOf(fullPath) ? output : null;
+		IClasspathEntry innerMostEntry = null;
+		ExternalFoldersManager foldersManager = JavaModelManager.getExternalManager();
+		for (int j = 0, cpLength = classpath.length; j < cpLength; j++) {
+			IClasspathEntry entry = classpath[j];
+
+			IPath entryPath = entry.getPath();
+			if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+				IResource linkedFolder = foldersManager.getFolder(entryPath);
+				if (linkedFolder != null)
+					entryPath = linkedFolder.getFullPath();
+			}
+			if ((innerMostEntry == null || innerMostEntry.getPath().isPrefixOf(entryPath))
+					&& entryPath.isPrefixOf(fullPath)) {
+				innerMostEntry = entry;
+			}
+			IPath entryOutput = classpath[j].getOutputLocation();
+			if (entryOutput != null && entryOutput.isPrefixOf(fullPath)) {
+				innerMostOutput = entryOutput;
+			}
+		}
+		if (innerMostEntry != null) {
+			// special case prj==src and nested output location
+			if (innerMostOutput != null && innerMostOutput.segmentCount() > 1 // output isn't project
+					&& innerMostEntry.getPath().segmentCount() == 1) { // 1 segment must be project name
+				return false;
+			}
+			if  (resource instanceof IFolder) {
+				 // folders are always included in src/lib entries
+				 return true;
+			}
+			switch (innerMostEntry.getEntryKind()) {
+				case IClasspathEntry.CPE_SOURCE:
+					// .class files are not visible in source folders
+					return !org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(fullPath.lastSegment());
+				case IClasspathEntry.CPE_LIBRARY:
+					// .java files are not visible in library folders
+					return !org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(fullPath.lastSegment());
+			}
+		}
+		if (innerMostOutput != null) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Record a new marker denoting a classpath problem
+	 */
+	public void createClasspathProblemMarker(IJavaModelStatus status) {
+
+		IMarker marker = null;
+		int severity;
+		String[] arguments = CharOperation.NO_STRINGS;
+		boolean isCycleProblem = false, isClasspathFileFormatProblem = false, isOutputOverlapping = false;
+		switch (status.getCode()) {
+
+			case  IJavaModelStatusConstants.CLASSPATH_CYCLE :
+				isCycleProblem = true;
+				if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
+					severity = IMarker.SEVERITY_ERROR;
+				} else {
+					severity = IMarker.SEVERITY_WARNING;
+				}
+				break;
+
+			case  IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT :
+				isClasspathFileFormatProblem = true;
+				severity = IMarker.SEVERITY_ERROR;
+				break;
+
+			case  IJavaModelStatusConstants.INCOMPATIBLE_JDK_LEVEL :
+				String setting = getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true);
+				if (JavaCore.ERROR.equals(setting)) {
+					severity = IMarker.SEVERITY_ERROR;
+				} else if (JavaCore.WARNING.equals(setting)) {
+					severity = IMarker.SEVERITY_WARNING;
+				} else {
+					return; // setting == IGNORE
+				}
+				break;
+			case IJavaModelStatusConstants.OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE :
+				isOutputOverlapping = true;
+				setting = getOption(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE, true);
+				if (JavaCore.ERROR.equals(setting)) {
+					severity = IMarker.SEVERITY_ERROR;
+				} else if (JavaCore.WARNING.equals(setting)) {
+					severity = IMarker.SEVERITY_WARNING;
+				} else {
+					return; // setting == IGNORE
+				}
+				break;
+			default:
+				IPath path = status.getPath();
+				if (path != null) arguments = new String[] { path.toString() };
+				if (JavaCore.ERROR.equals(getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true)) &&
+					status.getSeverity() != IStatus.WARNING) {
+					severity = IMarker.SEVERITY_ERROR;
+				} else {
+					severity = IMarker.SEVERITY_WARNING;
+				}
+				break;
+		}
+
+		try {
+			marker = this.project.createMarker(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER);
+			marker.setAttributes(
+				new String[] {
+					IMarker.MESSAGE,
+					IMarker.SEVERITY,
+					IMarker.LOCATION,
+					IJavaModelMarker.CYCLE_DETECTED,
+					IJavaModelMarker.CLASSPATH_FILE_FORMAT,
+					IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE,
+					IJavaModelMarker.ID,
+					IJavaModelMarker.ARGUMENTS ,
+					IJavaModelMarker.CATEGORY_ID,
+					IMarker.SOURCE_ID,
+				},
+				new Object[] {
+					status.getMessage(),
+					new Integer(severity),
+					Messages.classpath_buildPath,
+					isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
+					isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
+					isOutputOverlapping ? "true" : "false", //$NON-NLS-1$ //$NON-NLS-2$
+					new Integer(status.getCode()),
+					Util.getProblemArgumentsForMarker(arguments) ,
+					new Integer(CategorizedProblem.CAT_BUILDPATH),
+					JavaBuilder.SOURCE_ID,
+				}
+			);
+		} catch (CoreException e) {
+			// could not create marker: cannot do much
+			if (JavaModelManager.VERBOSE) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Returns a new element info for this element.
+	 */
+	protected Object createElementInfo() {
+		return new JavaProjectElementInfo();
+	}
+
+	/**
+	 * Reads and decode an XML classpath string. Returns a two-dimensional array, where the number of elements in the row is fixed to 2.
+	 * The first element is an array of raw classpath entries and the second element is an array of referenced entries that may have been stored
+	 * by the client earlier. See {@link IJavaProject#getReferencedClasspathEntries()} for more details. 
+	 * 
+	 */
+	public IClasspathEntry[][] decodeClasspath(String xmlClasspath, Map unknownElements) throws IOException, ClasspathEntry.AssertionFailedException {
+
+		ArrayList paths = new ArrayList();
+		IClasspathEntry defaultOutput = null;
+		StringReader reader = new StringReader(xmlClasspath);
+		Element cpElement;
+		try {
+			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+		} catch (SAXException e) {
+			throw new IOException(Messages.file_badFormat);
+		} catch (ParserConfigurationException e) {
+			throw new IOException(Messages.file_badFormat);
+		} finally {
+			reader.close();
+		}
+
+		if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
+			throw new IOException(Messages.file_badFormat);
+		}
+		NodeList list = cpElement.getElementsByTagName(ClasspathEntry.TAG_CLASSPATHENTRY);
+		int length = list.getLength();
+
+		for (int i = 0; i < length; ++i) {
+			Node node = list.item(i);
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this, unknownElements);
+				if (entry != null){
+					if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+						defaultOutput = entry; // separate output
+					} else {
+						paths.add(entry);
+					}
+				}
+			}
+		}
+		int pathSize = paths.size();
+		IClasspathEntry[][] entries = new IClasspathEntry[2][];
+		entries[0] = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
+		paths.toArray(entries[0]);
+		if (defaultOutput != null) entries[0][pathSize] = defaultOutput; // ensure output is last item
+		
+		paths.clear();
+		list = cpElement.getElementsByTagName(ClasspathEntry.TAG_REFERENCED_ENTRY);
+		length = list.getLength();
+
+		for (int i = 0; i < length; ++i) {
+			Node node = list.item(i);
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				IClasspathEntry entry = ClasspathEntry.elementDecode((Element)node, this, unknownElements);
+				if (entry != null){
+					paths.add(entry);
+				}
+			}
+		}
+		entries[1] = new IClasspathEntry[paths.size()];
+		paths.toArray(entries[1]);
+
+		return entries;
+	}
+
+	public IClasspathEntry decodeClasspathEntry(String encodedEntry) {
+
+		try {
+			if (encodedEntry == null) return null;
+			StringReader reader = new StringReader(encodedEntry);
+			Element node;
+
+			try {
+				DocumentBuilder parser =
+					DocumentBuilderFactory.newInstance().newDocumentBuilder();
+				node = parser.parse(new InputSource(reader)).getDocumentElement();
+			} catch (SAXException e) {
+				return null;
+			} catch (ParserConfigurationException e) {
+				return null;
+			} finally {
+				reader.close();
+			}
+
+			if (!node.getNodeName().equalsIgnoreCase(ClasspathEntry.TAG_CLASSPATHENTRY)
+					|| node.getNodeType() != Node.ELEMENT_NODE) {
+				return null;
+			}
+			return ClasspathEntry.elementDecode(node, this, null/*not interested in unknown elements*/);
+		} catch (IOException e) {
+			// bad format
+			return null;
+		}
+	}
+
+	/**
+	/**
+	 * Removes the Java nature from the project.
+	 */
+	public void deconfigure() throws CoreException {
+
+		// deregister Java builder
+		removeFromBuildSpec(JavaCore.BUILDER_ID);
+
+		// remove .classpath file
+//		getProject().getFile(ClasspathHelper.CLASSPATH_FILENAME).delete(false, null);
+	}
+
+	/**
+	 * Returns a default class path.
+	 * This is the root of the project
+	 */
+	protected IClasspathEntry[] defaultClasspath() {
+
+		return new IClasspathEntry[] {
+			 JavaCore.newSourceEntry(this.project.getFullPath())};
+	}
+
+	/**
+	 * Returns a default output location.
+	 * This is the project bin folder
+	 */
+	protected IPath defaultOutputLocation() {
+		return this.project.getFullPath().append("bin"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the XML String encoding of the class path.
+	 */
+	protected String encodeClasspath(IClasspathEntry[] classpath, IClasspathEntry[] referencedEntries, IPath outputLocation, boolean indent, Map unknownElements) throws JavaModelException {
+		try {
+			ByteArrayOutputStream s = new ByteArrayOutputStream();
+			OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
+			XMLWriter xmlWriter = new XMLWriter(writer, this, true/*print XML version*/);
+
+			xmlWriter.startTag(ClasspathEntry.TAG_CLASSPATH, indent);
+			for (int i = 0; i < classpath.length; ++i) {
+				((ClasspathEntry)classpath[i]).elementEncode(xmlWriter, this.project.getFullPath(), indent, true, unknownElements, false);
+			}
+
+			if (outputLocation != null) {
+				outputLocation = outputLocation.removeFirstSegments(1);
+				outputLocation = outputLocation.makeRelative();
+				HashMap parameters = new HashMap();
+				parameters.put(ClasspathEntry.TAG_KIND, ClasspathEntry.kindToString(ClasspathEntry.K_OUTPUT));
+				parameters.put(ClasspathEntry.TAG_PATH, String.valueOf(outputLocation));
+				xmlWriter.printTag(ClasspathEntry.TAG_CLASSPATHENTRY, parameters, indent, true, true);
+			}
+
+			if (referencedEntries != null) {
+				for (int i = 0; i < referencedEntries.length; ++i) {
+					((ClasspathEntry) referencedEntries[i]).elementEncode(xmlWriter, this.project.getFullPath(), indent, true, unknownElements, true);
+				}
+			}
+			
+			xmlWriter.endTag(ClasspathEntry.TAG_CLASSPATH, indent, true/*insert new line*/);
+			writer.flush();
+			writer.close();
+			return s.toString("UTF8");//$NON-NLS-1$
+		} catch (IOException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+		}
+	}
+
+	public String encodeClasspathEntry(IClasspathEntry classpathEntry) {
+		try {
+			ByteArrayOutputStream s = new ByteArrayOutputStream();
+			OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
+			XMLWriter xmlWriter = new XMLWriter(writer, this, false/*don't print XML version*/);
+
+			((ClasspathEntry)classpathEntry).elementEncode(xmlWriter, this.project.getFullPath(), true/*indent*/, true/*insert new line*/, null/*not interested in unknown elements*/, (classpathEntry.getReferencingEntry() != null));
+
+			writer.flush();
+			writer.close();
+			return s.toString("UTF8");//$NON-NLS-1$
+		} catch (IOException e) {
+			return null; // never happens since all is done in memory
+		}
+	}
+
+	/**
+	 * Returns true if this handle represents the same Java project
+	 * as the given handle. Two handles represent the same
+	 * project if they are identical or if they represent a project with
+	 * the same underlying resource and occurrence counts.
+	 *
+	 * @see JavaElement#equals(Object)
+	 */
+	public boolean equals(Object o) {
+
+		if (this == o)
+			return true;
+
+		if (!(o instanceof JavaProject))
+			return false;
+
+		JavaProject other = (JavaProject) o;
+		return this.project.equals(other.getProject());
+	}
+
+	/**
+	 * @see IJavaProject#findElement(IPath)
+	 */
+	public IJavaElement findElement(IPath path) throws JavaModelException {
+		return findElement(path, DefaultWorkingCopyOwner.PRIMARY);
+	}
+
+	/**
+	 * @see IJavaProject#findElement(IPath, WorkingCopyOwner)
+	 */
+	public IJavaElement findElement(IPath path, WorkingCopyOwner owner) throws JavaModelException {
+
+		if (path == null || path.isAbsolute()) {
+			throw new JavaModelException(
+				new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, path));
+		}
+		try {
+
+			String extension = path.getFileExtension();
+			if (extension == null) {
+				String packageName = path.toString().replace(IPath.SEPARATOR, '.');
+				return findPackageFragment(packageName);
+			} else if (Util.isJavaLikeFileName(path.lastSegment())
+					|| extension.equalsIgnoreCase(EXTENSION_class)) {
+				IPath packagePath = path.removeLastSegments(1);
+				String packageName = packagePath.toString().replace(IPath.SEPARATOR, '.');
+				String typeName = path.lastSegment();
+				typeName = typeName.substring(0, typeName.length() - extension.length() - 1);
+				String qualifiedName = null;
+				if (packageName.length() > 0) {
+					qualifiedName = packageName + "." + typeName; //$NON-NLS-1$
+				} else {
+					qualifiedName = typeName;
+				}
+
+				// lookup type
+				NameLookup lookup = newNameLookup(owner);
+				NameLookup.Answer answer = lookup.findType(
+					qualifiedName,
+					false,
+					NameLookup.ACCEPT_ALL,
+					true/* consider secondary types */,
+					false/* do NOT wait for indexes */,
+					false/*don't check restrictions*/,
+					null);
+
+				if (answer != null) {
+					return answer.type.getParent();
+				} else {
+					return null;
+				}
+			} else {
+				// unsupported extension
+				return null;
+			}
+		} catch (JavaModelException e) {
+			if (e.getStatus().getCode()
+				== IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) {
+				return null;
+			} else {
+				throw e;
+			}
+		}
+	}
+
+	public IJavaElement findPackageFragment(String packageName)
+			throws JavaModelException {
+		NameLookup lookup = newNameLookup((WorkingCopyOwner)null/*no need to look at working copies for pkgs*/);
+		IPackageFragment[] pkgFragments = lookup.findPackageFragments(packageName, false);
+		if (pkgFragments == null) {
+			return null;
+
+		} else {
+			// try to return one that is a child of this project
+			for (int i = 0, length = pkgFragments.length; i < length; i++) {
+
+				IPackageFragment pkgFragment = pkgFragments[i];
+				if (equals(pkgFragment.getParent().getParent())) {
+					return pkgFragment;
+				}
+			}
+			// default to the first one
+			return pkgFragments[0];
+		}
+	}
+
+	public IJavaElement findElement(String bindingKey, WorkingCopyOwner owner) throws JavaModelException {
+		JavaElementFinder elementFinder = new JavaElementFinder(bindingKey, this, owner);
+		elementFinder.parse();
+		if (elementFinder.exception != null)
+			throw elementFinder.exception;
+		return elementFinder.element;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragment findPackageFragment(IPath path)
+		throws JavaModelException {
+
+		return findPackageFragment0(JavaProject.canonicalizedPath(path));
+	}
+	/*
+	 * non path canonicalizing version
+	 */
+	private IPackageFragment findPackageFragment0(IPath path)
+		throws JavaModelException {
+
+		NameLookup lookup = newNameLookup((WorkingCopyOwner)null/*no need to look at working copies for pkgs*/);
+		return lookup.findPackageFragment(path);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot findPackageFragmentRoot(IPath path)
+		throws JavaModelException {
+
+		return findPackageFragmentRoot0(JavaProject.canonicalizedPath(path));
+	}
+	/*
+	 * no path canonicalization
+	 */
+	public IPackageFragmentRoot findPackageFragmentRoot0(IPath path)
+		throws JavaModelException {
+
+		IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots();
+		if (!path.isAbsolute()) {
+			throw new IllegalArgumentException(Messages.path_mustBeAbsolute);
+		}
+		for (int i= 0; i < allRoots.length; i++) {
+			IPackageFragmentRoot classpathRoot= allRoots[i];
+			if (classpathRoot.getPath().equals(path)) {
+				return classpathRoot;
+			}
+		}
+		return null;
+	}
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) {
+		try {
+			IClasspathEntry[] classpath = getRawClasspath();
+			for (int i = 0, length = classpath.length; i < length; i++) {
+				if (classpath[i].equals(entry)) { // entry may need to be resolved
+					return
+						computePackageFragmentRoots(
+							resolveClasspath(new IClasspathEntry[] {entry}),
+							false, // don't retrieve exported roots
+							null); /*no reverse map*/
+				}
+			}
+		} catch (JavaModelException e) {
+			// project doesn't exist: return an empty array
+		}
+		return new IPackageFragmentRoot[] {};
+	}
+	/**
+	 * @see IJavaProject#findType(String)
+	 */
+	public IType findType(String fullyQualifiedName) throws JavaModelException {
+		return findType(fullyQualifiedName, DefaultWorkingCopyOwner.PRIMARY);
+	}
+	/**
+	 * @see IJavaProject#findType(String, IProgressMonitor)
+	 */
+	public IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException {
+		return findType(fullyQualifiedName, DefaultWorkingCopyOwner.PRIMARY, progressMonitor);
+	}
+
+	/*
+	 * Internal findType with instanciated name lookup
+	 */
+	IType findType(String fullyQualifiedName, NameLookup lookup, boolean considerSecondaryTypes, IProgressMonitor progressMonitor) throws JavaModelException {
+		NameLookup.Answer answer = lookup.findType(
+			fullyQualifiedName,
+			false,
+			NameLookup.ACCEPT_ALL,
+			considerSecondaryTypes,
+			true, /* wait for indexes (only if consider secondary types)*/
+			false/*don't check restrictions*/,
+			progressMonitor);
+		if (answer == null) {
+			// try to find enclosing type
+			int lastDot = fullyQualifiedName.lastIndexOf('.');
+			if (lastDot == -1) return null;
+			IType type = findType(fullyQualifiedName.substring(0, lastDot), lookup, considerSecondaryTypes, progressMonitor);
+			if (type != null) {
+				type = type.getType(fullyQualifiedName.substring(lastDot+1));
+				if (!type.exists()) {
+					return null;
+				}
+			}
+			return type;
+		}
+		return answer.type;
+	}
+	/**
+	 * @see IJavaProject#findType(String, String)
+	 */
+	public IType findType(String packageName, String typeQualifiedName) throws JavaModelException {
+		return findType(packageName, typeQualifiedName, DefaultWorkingCopyOwner.PRIMARY);
+	}
+	/**
+	 * @see IJavaProject#findType(String, String, IProgressMonitor)
+	 */
+	public IType findType(String packageName, String typeQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException {
+		return findType(packageName, typeQualifiedName, DefaultWorkingCopyOwner.PRIMARY, progressMonitor);
+	}
+	/*
+	 * Internal findType with instanciated name lookup
+	 */
+	IType findType(String packageName, String typeQualifiedName, NameLookup lookup, boolean considerSecondaryTypes, IProgressMonitor progressMonitor) throws JavaModelException {
+		NameLookup.Answer answer = lookup.findType(
+			typeQualifiedName,
+			packageName,
+			false,
+			NameLookup.ACCEPT_ALL,
+			considerSecondaryTypes,
+			true, // wait for indexes (in case we need to consider secondary types)
+			false/*don't check restrictions*/,
+			progressMonitor);
+		return answer == null ? null : answer.type;
+	}
+	/**
+	 * @see IJavaProject#findType(String, String, WorkingCopyOwner)
+	 */
+	public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner) throws JavaModelException {
+		NameLookup lookup = newNameLookup(owner);
+		return findType(
+			packageName,
+			typeQualifiedName,
+			lookup,
+			false, // do not consider secondary types
+			null);
+	}
+
+	/**
+	 * @see IJavaProject#findType(String, String, WorkingCopyOwner, IProgressMonitor)
+	 */
+	public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException {
+		NameLookup lookup = newNameLookup(owner);
+		return findType(
+			packageName,
+			typeQualifiedName,
+			lookup,
+			true, // consider secondary types
+			progressMonitor);
+	}
+
+	/**
+	 * @see IJavaProject#findType(String, WorkingCopyOwner)
+	 */
+	public IType findType(String fullyQualifiedName, WorkingCopyOwner owner) throws JavaModelException {
+		NameLookup lookup = newNameLookup(owner);
+		return findType(fullyQualifiedName, lookup, false, null);
+	}
+
+	/**
+	 * @see IJavaProject#findType(String, WorkingCopyOwner, IProgressMonitor)
+	 */
+	public IType findType(String fullyQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException {
+		NameLookup lookup = newNameLookup(owner);
+		return findType(fullyQualifiedName, lookup, true, progressMonitor);
+	}
+
+	/**
+	 * Remove all markers denoting classpath problems
+	 */ //TODO (philippe) should improve to use a bitmask instead of booleans (CYCLE, FORMAT, VALID)
+	protected void flushClasspathProblemMarkers(boolean flushCycleMarkers, boolean flushClasspathFormatMarkers, boolean flushOverlappingOutputMarkers) {
+		try {
+			if (this.project.isAccessible()) {
+				IMarker[] markers = this.project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+				for (int i = 0, length = markers.length; i < length; i++) {
+					IMarker marker = markers[i];
+					if (flushCycleMarkers && flushClasspathFormatMarkers && flushOverlappingOutputMarkers) {
+						marker.delete();
+					} else {
+						String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
+						String classpathFileFormatAttr =  (String)marker.getAttribute(IJavaModelMarker.CLASSPATH_FILE_FORMAT);
+						String overlappingOutputAttr = (String) marker.getAttribute(IJavaModelMarker.OUTPUT_OVERLAPPING_SOURCE);
+						if ((flushCycleMarkers == (cycleAttr != null && cycleAttr.equals("true"))) //$NON-NLS-1$
+							&& (flushOverlappingOutputMarkers == (overlappingOutputAttr != null && overlappingOutputAttr.equals("true"))) //$NON-NLS-1$
+							&& (flushClasspathFormatMarkers == (classpathFileFormatAttr != null && classpathFileFormatAttr.equals("true")))){ //$NON-NLS-1$
+							marker.delete();
+						}
+					}
+				}
+			}
+		} catch (CoreException e) {
+			// could not flush markers: not much we can do
+			if (JavaModelManager.VERBOSE) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Returns the set of patterns corresponding to this project visibility given rules
+	 * @return an array of IPath or null if none
+	 */
+	public IPath[] getAccessRestrictions(String optionName) {
+		String sequence = getOption(optionName, true); // inherit from workspace
+		if (sequence == null || sequence.length() == 0) return null;
+		IPath[] rules = null;
+		char[][] patterns = CharOperation.splitOn('|', sequence.toCharArray());
+		int patternCount;
+		if ((patternCount  = patterns.length) > 0) {
+			rules = new IPath[patternCount];
+			for (int j = 0; j < patterns.length; j++){
+				rules[j] = new Path(new String(patterns[j]));
+			}
+		}
+		return rules;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot[] getAllPackageFragmentRoots()
+		throws JavaModelException {
+
+		return getAllPackageFragmentRoots(null /*no reverse map*/);
+	}
+
+	public IPackageFragmentRoot[] getAllPackageFragmentRoots(Map rootToResolvedEntries) throws JavaModelException {
+
+		return computePackageFragmentRoots(getResolvedClasspath(), true/*retrieveExportedRoots*/, rootToResolvedEntries);
+	}
+
+	/**
+	 * Returns the classpath entry that refers to the given path
+	 * or <code>null</code> if there is no reference to the path.
+	 * @param path IPath
+	 * @return IClasspathEntry
+	 * @throws JavaModelException
+	 */
+	public IClasspathEntry getClasspathEntryFor(IPath path) throws JavaModelException {
+		getResolvedClasspath(); // force resolution
+		PerProjectInfo perProjectInfo = getPerProjectInfo();
+		if (perProjectInfo == null)
+			return null;
+		Map rootPathToResolvedEntries = perProjectInfo.rootPathToResolvedEntries;
+		if (rootPathToResolvedEntries == null)
+			return null;
+		IClasspathEntry classpathEntry = (IClasspathEntry) rootPathToResolvedEntries.get(path);
+		if (classpathEntry == null) {
+			path = getProject().getWorkspace().getRoot().getLocation().append(path);
+			classpathEntry = (IClasspathEntry) rootPathToResolvedEntries.get(path);
+		}
+		return classpathEntry;
+	}
+
+	/*
+	 * Returns the cycle marker associated with this project or null if none.
+	 */
+	public IMarker getCycleMarker(){
+		try {
+			if (this.project.isAccessible()) {
+				IMarker[] markers = this.project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+				for (int i = 0, length = markers.length; i < length; i++) {
+					IMarker marker = markers[i];
+					String cycleAttr = (String)marker.getAttribute(IJavaModelMarker.CYCLE_DETECTED);
+					if (cycleAttr != null && cycleAttr.equals("true")){ //$NON-NLS-1$
+						return marker;
+					}
+				}
+			}
+		} catch (CoreException e) {
+			// could not get markers: return null
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the project custom preference pool.
+	 * Project preferences may include custom encoding.
+	 * @return IEclipsePreferences or <code>null</code> if the project
+	 * 	does not have a java nature.
+	 */
+	public IEclipsePreferences getEclipsePreferences() {
+		if (!JavaProject.hasJavaNature(this.project)) return null;
+		// Get cached preferences if exist
+		JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(this.project, true);
+		if (perProjectInfo.preferences != null) return perProjectInfo.preferences;
+		// Init project preferences
+		IScopeContext context = new ProjectScope(getProject());
+		final IEclipsePreferences eclipsePreferences = context.getNode(JavaCore.PLUGIN_ID);
+		updatePreferences(eclipsePreferences);
+		perProjectInfo.preferences = eclipsePreferences;
+
+		// Listen to new preferences node
+		final IEclipsePreferences eclipseParentPreferences = (IEclipsePreferences) eclipsePreferences.parent();
+		if (eclipseParentPreferences != null) {
+			if (this.preferencesNodeListener != null) {
+				eclipseParentPreferences.removeNodeChangeListener(this.preferencesNodeListener);
+			}
+			this.preferencesNodeListener = new IEclipsePreferences.INodeChangeListener() {
+				public void added(IEclipsePreferences.NodeChangeEvent event) {
+					// do nothing
+				}
+				public void removed(IEclipsePreferences.NodeChangeEvent event) {
+					if (event.getChild() == eclipsePreferences) {
+						JavaModelManager.getJavaModelManager().resetProjectPreferences(JavaProject.this);
+					}
+				}
+			};
+			eclipseParentPreferences.addNodeChangeListener(this.preferencesNodeListener);
+		}
+
+		// Listen to preferences changes
+		if (this.preferencesChangeListener != null) {
+			eclipsePreferences.removePreferenceChangeListener(this.preferencesChangeListener);
+		}
+		this.preferencesChangeListener = new IEclipsePreferences.IPreferenceChangeListener() {
+			public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) {
+				String propertyName = event.getKey();
+				JavaModelManager manager = JavaModelManager.getJavaModelManager();
+				if (propertyName.startsWith(JavaCore.PLUGIN_ID)) {
+					if (propertyName.equals(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER) ||
+						propertyName.equals(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER) ||
+						propertyName.equals(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE) ||
+						propertyName.equals(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER) ||
+						propertyName.equals(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH) ||
+						propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_EXCLUSION_PATTERNS) ||
+						propertyName.equals(JavaCore.CORE_ENABLE_CLASSPATH_MULTIPLE_OUTPUT_LOCATIONS) ||
+						propertyName.equals(JavaCore.CORE_INCOMPLETE_CLASSPATH) ||
+						propertyName.equals(JavaCore.CORE_CIRCULAR_CLASSPATH) ||
+						propertyName.equals(JavaCore.CORE_OUTPUT_LOCATION_OVERLAPPING_ANOTHER_SOURCE) ||
+						propertyName.equals(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL) ||
+						propertyName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM))
+					{
+						manager.deltaState.addClasspathValidation(JavaProject.this);
+					}
+					manager.resetProjectOptions(JavaProject.this);
+					JavaProject.this.resetCaches(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=233568
+				}
+			}
+		};
+		eclipsePreferences.addPreferenceChangeListener(this.preferencesChangeListener);
+		return eclipsePreferences;
+	}
+
+	public String getElementName() {
+		return this.project.getName();
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public int getElementType() {
+		return JAVA_PROJECT;
+	}
+
+	/**
+	 * This is a helper method returning the expanded classpath for the project, as a list of classpath entries,
+	 * where all classpath variable entries have been resolved and substituted with their final target entries.
+	 * All project exports have been appended to project entries.
+	 * @return IClasspathEntry[]
+	 * @throws JavaModelException
+	 */
+	public IClasspathEntry[] getExpandedClasspath()	throws JavaModelException {
+
+			ObjectVector accumulatedEntries = new ObjectVector();
+			computeExpandedClasspath(null, new HashSet(5), accumulatedEntries);
+
+			IClasspathEntry[] expandedPath = new IClasspathEntry[accumulatedEntries.size()];
+			accumulatedEntries.copyInto(expandedPath);
+
+			return expandedPath;
+	}
+
+	/**
+	 * The path is known to match a source/library folder entry.
+	 * @param path IPath
+	 * @return IPackageFragmentRoot
+	 */
+	public IPackageFragmentRoot getFolderPackageFragmentRoot(IPath path) {
+		if (path.segmentCount() == 1) { // default project root
+			return getPackageFragmentRoot(this.project);
+		}
+		return getPackageFragmentRoot(this.project.getWorkspace().getRoot().getFolder(path));
+	}
+
+	/*
+	 * @see JavaElement
+	 */
+	public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+		switch (token.charAt(0)) {
+			case JEM_PACKAGEFRAGMENTROOT:
+				String rootPath = IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
+				token = null;
+				while (memento.hasMoreTokens()) {
+					token = memento.nextToken();
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331821
+					if (token == MementoTokenizer.PACKAGEFRAGMENT || token == MementoTokenizer.COUNT) {
+						break;
+					}
+					rootPath += token;
+				}
+				JavaElement root = (JavaElement)getPackageFragmentRoot(new Path(rootPath));
+				if (token != null && token.charAt(0) == JEM_PACKAGEFRAGMENT) {
+					return root.getHandleFromMemento(token, memento, owner);
+				} else {
+					return root.getHandleFromMemento(memento, owner);
+				}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the <code>char</code> that marks the start of this handles
+	 * contribution to a memento.
+	 */
+	protected char getHandleMementoDelimiter() {
+
+		return JEM_JAVAPROJECT;
+	}
+
+	/**
+	 * Find the specific Java command amongst the given build spec
+	 * and return its index or -1 if not found.
+	 */
+	private int getJavaCommandIndex(ICommand[] buildSpec) {
+
+		for (int i = 0; i < buildSpec.length; ++i) {
+			if (buildSpec[i].getBuilderName().equals(JavaCore.BUILDER_ID)) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Convenience method that returns the specific type of info for a Java project.
+	 */
+	protected JavaProjectElementInfo getJavaProjectElementInfo()
+		throws JavaModelException {
+
+		return (JavaProjectElementInfo) getElementInfo();
+	}
+
+	/**
+	 * Returns an array of non-java resources contained in the receiver.
+	 */
+	public Object[] getNonJavaResources() throws JavaModelException {
+
+		return ((JavaProjectElementInfo) getElementInfo()).getNonJavaResources(this);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.IJavaProject#getOption(String, boolean)
+	 */
+	public String getOption(String optionName, boolean inheritJavaCoreOptions) {
+		return JavaModelManager.getJavaModelManager().getOption(optionName, inheritJavaCoreOptions, getEclipsePreferences());
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
+	 */
+	public Map getOptions(boolean inheritJavaCoreOptions) {
+
+		// initialize to the defaults from JavaCore options pool
+		Map options = inheritJavaCoreOptions ? JavaCore.getOptions() : new Hashtable(5);
+
+		// Get project specific options
+		JavaModelManager.PerProjectInfo perProjectInfo = null;
+		Hashtable projectOptions = null;
+		JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
+		HashSet optionNames = javaModelManager.optionNames;
+		try {
+			perProjectInfo = getPerProjectInfo();
+			projectOptions = perProjectInfo.options;
+			if (projectOptions == null) {
+				// get eclipse preferences
+				IEclipsePreferences projectPreferences= getEclipsePreferences();
+				if (projectPreferences == null) return options; // cannot do better (non-Java project)
+				// create project options
+				String[] propertyNames = projectPreferences.keys();
+				projectOptions = new Hashtable(propertyNames.length);
+				for (int i = 0; i < propertyNames.length; i++){
+					String propertyName = propertyNames[i];
+					String value = projectPreferences.get(propertyName, null);
+					if (value != null) {
+						value = value.trim();
+						// Keep the option value, even if it's deprecated
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=324987
+						projectOptions.put(propertyName, value);
+						if (!optionNames.contains(propertyName)) {
+							// try to migrate deprecated options
+							String[] compatibleOptions = (String[]) javaModelManager.deprecatedOptions.get(propertyName);
+							if (compatibleOptions != null) {
+								for (int co=0, length=compatibleOptions.length; co < length; co++) {
+									String compatibleOption = compatibleOptions[co];
+									if (!projectOptions.containsKey(compatibleOption))
+										projectOptions.put(compatibleOption, value);
+								}
+							}
+						}
+					}
+				}
+				// cache project options
+				perProjectInfo.options = projectOptions;
+			}
+		} catch (JavaModelException jme) {
+			projectOptions = new Hashtable();
+		} catch (BackingStoreException e) {
+			projectOptions = new Hashtable();
+		}
+
+		// Inherit from JavaCore options if specified
+		if (inheritJavaCoreOptions) {
+			Iterator propertyNames = projectOptions.entrySet().iterator();
+			while (propertyNames.hasNext()) {
+				Map.Entry entry = (Map.Entry) propertyNames.next();
+				String propertyName = (String) entry.getKey();
+				String propertyValue = (String) entry.getValue();
+				if (propertyValue != null && javaModelManager.knowsOption(propertyName)){
+					options.put(propertyName, propertyValue.trim());
+				}
+			}
+			Util.fixTaskTags(options);
+			return options;
+		}
+		Util.fixTaskTags(projectOptions);
+		return projectOptions;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPath getOutputLocation() throws JavaModelException {
+		// Do not create marker while getting output location
+		JavaModelManager.PerProjectInfo perProjectInfo = getPerProjectInfo();
+		IPath outputLocation = perProjectInfo.outputLocation;
+		if (outputLocation != null) return outputLocation;
+
+		// force to read classpath - will position output location as well
+		getRawClasspath();
+
+		outputLocation = perProjectInfo.outputLocation;
+		if (outputLocation == null) {
+			return defaultOutputLocation();
+		}
+		return outputLocation;
+	}
+
+	/**
+	 * @param path IPath
+	 * @return A handle to the package fragment root identified by the given path.
+	 * This method is handle-only and the element may or may not exist. Returns
+	 * <code>null</code> if unable to generate a handle from the path (for example,
+	 * an absolute path that has less than 1 segment. The path may be relative or
+	 * absolute.
+	 */
+	public IPackageFragmentRoot getPackageFragmentRoot(IPath path) {
+		if (!path.isAbsolute()) {
+			path = getPath().append(path);
+		}
+		int segmentCount = path.segmentCount();
+		if (segmentCount == 0) {
+			return null;
+		}
+		if (path.getDevice() != null || JavaModel.getExternalTarget(path, true/*check existence*/) != null) {
+			// external path
+			return getPackageFragmentRoot0(path);
+		}
+		IWorkspaceRoot workspaceRoot = this.project.getWorkspace().getRoot();
+		IResource resource = workspaceRoot.findMember(path);
+		if (resource == null) {
+			// resource doesn't exist in workspace
+			if (path.getFileExtension() != null) {
+				if (!workspaceRoot.getProject(path.segment(0)).exists()) {
+					// assume it is an external ZIP archive
+					return getPackageFragmentRoot0(path);
+				} else {
+					// assume it is an internal ZIP archive
+					resource = workspaceRoot.getFile(path);
+				}
+			} else if (segmentCount == 1) {
+				// assume it is a project
+				String projectName = path.segment(0);
+				if (getElementName().equals(projectName)) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=75814
+					// default root
+					resource = this.project;
+				} else {
+					// lib being another project
+					resource = workspaceRoot.getProject(projectName);
+				}
+			} else {
+				// assume it is an internal folder
+				resource = workspaceRoot.getFolder(path);
+			}
+		}
+		return getPackageFragmentRoot(resource);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
+		return getPackageFragmentRoot(resource, null/*no entry path*/);
+	}
+
+	private IPackageFragmentRoot getPackageFragmentRoot(IResource resource, IPath entryPath) {
+		switch (resource.getType()) {
+			case IResource.FILE:
+				return new JarPackageFragmentRoot(resource, this);
+			case IResource.FOLDER:
+				if (ExternalFoldersManager.isInternalPathForExternalFolder(resource.getFullPath()))
+					return new ExternalPackageFragmentRoot(resource, entryPath, this);
+				return new PackageFragmentRoot(resource, this);
+			case IResource.PROJECT:
+				return new PackageFragmentRoot(resource, this);
+			default:
+				return null;
+		}
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot getPackageFragmentRoot(String externalLibraryPath) {
+		return getPackageFragmentRoot0(JavaProject.canonicalizedPath(new Path(externalLibraryPath)));
+	}
+
+	/*
+	 * no path canonicalization
+	 */
+	public IPackageFragmentRoot getPackageFragmentRoot0(IPath externalLibraryPath) {
+		IFolder linkedFolder = JavaModelManager.getExternalManager().getFolder(externalLibraryPath);
+		if (linkedFolder != null)
+			return new ExternalPackageFragmentRoot(linkedFolder, externalLibraryPath, this);
+		return new JarPackageFragmentRoot(externalLibraryPath, this);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragmentRoot[] getPackageFragmentRoots()
+		throws JavaModelException {
+
+		Object[] children;
+		int length;
+		IPackageFragmentRoot[] roots;
+
+		System.arraycopy(
+			children = getChildren(),
+			0,
+			roots = new IPackageFragmentRoot[length = children.length],
+			0,
+			length);
+
+		return roots;
+	}
+
+	/**
+	 * @see IJavaProject
+	 * @deprecated
+	 */
+	public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) {
+		return findPackageFragmentRoots(entry);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPackageFragment[] getPackageFragments() throws JavaModelException {
+
+		IPackageFragmentRoot[] roots = getPackageFragmentRoots();
+		return getPackageFragmentsInRoots(roots);
+	}
+
+	/**
+	 * Returns all the package fragments found in the specified
+	 * package fragment roots.
+	 * @param roots IPackageFragmentRoot[]
+	 * @return IPackageFragment[]
+	 */
+	public IPackageFragment[] getPackageFragmentsInRoots(IPackageFragmentRoot[] roots) {
+
+		ArrayList frags = new ArrayList();
+		for (int i = 0; i < roots.length; i++) {
+			IPackageFragmentRoot root = roots[i];
+			try {
+				IJavaElement[] rootFragments = root.getChildren();
+				for (int j = 0; j < rootFragments.length; j++) {
+					frags.add(rootFragments[j]);
+				}
+			} catch (JavaModelException e) {
+				// do nothing
+			}
+		}
+		IPackageFragment[] fragments = new IPackageFragment[frags.size()];
+		frags.toArray(fragments);
+		return fragments;
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IPath getPath() {
+		return this.project.getFullPath();
+	}
+
+	public JavaModelManager.PerProjectInfo getPerProjectInfo() throws JavaModelException {
+		return JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(this.project);
+	}
+
+	private IPath getPluginWorkingLocation() {
+		return this.project.getWorkingLocation(JavaCore.PLUGIN_ID);
+	}
+
+	/**
+	 * @see IJavaProject#getProject()
+	 */
+	public IProject getProject() {
+		return this.project;
+	}
+
+	public ProjectCache getProjectCache() throws JavaModelException {
+		return ((JavaProjectElementInfo) getElementInfo()).getProjectCache(this);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IClasspathEntry[] getRawClasspath() throws JavaModelException {
+		JavaModelManager.PerProjectInfo perProjectInfo = getPerProjectInfo();
+		IClasspathEntry[] classpath = perProjectInfo.rawClasspath;
+		if (classpath != null) return classpath;
+
+		classpath = perProjectInfo.readAndCacheClasspath(this)[0];
+
+		if (classpath == JavaProject.INVALID_CLASSPATH)
+			return defaultClasspath();
+
+		return classpath;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IClasspathEntry[] getReferencedClasspathEntries() throws JavaModelException {
+		return getPerProjectInfo().referencedEntries;
+	}
+	
+	/**
+	 * @see IJavaProject#getRequiredProjectNames()
+	 */
+	public String[] getRequiredProjectNames() throws JavaModelException {
+
+		return projectPrerequisites(getResolvedClasspath());
+	}
+
+	public IClasspathEntry[] getResolvedClasspath() throws JavaModelException {
+		PerProjectInfo perProjectInfo = getPerProjectInfo();
+		IClasspathEntry[] resolvedClasspath = perProjectInfo.getResolvedClasspath();
+		if (resolvedClasspath == null) {
+			resolveClasspath(perProjectInfo, false/*don't use previous session values*/, true/*add classpath change*/);
+			resolvedClasspath = perProjectInfo.getResolvedClasspath();
+			if (resolvedClasspath == null) {
+				// another thread reset the resolved classpath, use a temporary PerProjectInfo
+				PerProjectInfo temporaryInfo = newTemporaryInfo();
+				resolveClasspath(temporaryInfo, false/*don't use previous session values*/, true/*add classpath change*/);
+				resolvedClasspath = temporaryInfo.getResolvedClasspath();
+			}
+		}
+		return resolvedClasspath;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry) throws JavaModelException {
+		if  (JavaModelManager.getJavaModelManager().isClasspathBeingResolved(this)) {
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_reentering_classpath_resolution();
+		    return RESOLUTION_IN_PROGRESS;
+		}
+		PerProjectInfo perProjectInfo = getPerProjectInfo();
+
+		// use synchronized block to ensure consistency
+		IClasspathEntry[] resolvedClasspath;
+		IJavaModelStatus unresolvedEntryStatus;
+		synchronized (perProjectInfo) {
+			resolvedClasspath = perProjectInfo.getResolvedClasspath();
+			unresolvedEntryStatus = perProjectInfo.unresolvedEntryStatus;
+		}
+
+		if (resolvedClasspath == null
+				|| (unresolvedEntryStatus != null && !unresolvedEntryStatus.isOK())) { // force resolution to ensure initializers are run again
+			resolveClasspath(perProjectInfo, false/*don't use previous session values*/, true/*add classpath change*/);
+			synchronized (perProjectInfo) {
+				resolvedClasspath = perProjectInfo.getResolvedClasspath();
+				unresolvedEntryStatus = perProjectInfo.unresolvedEntryStatus;
+			}
+			if (resolvedClasspath == null) {
+				// another thread reset the resolved classpath, use a temporary PerProjectInfo
+				PerProjectInfo temporaryInfo = newTemporaryInfo();
+				resolveClasspath(temporaryInfo, false/*don't use previous session values*/, true/*add classpath change*/);
+				resolvedClasspath = temporaryInfo.getResolvedClasspath();
+				unresolvedEntryStatus = temporaryInfo.unresolvedEntryStatus;
+			}
+		}
+		if (!ignoreUnresolvedEntry && unresolvedEntryStatus != null && !unresolvedEntryStatus.isOK())
+			throw new JavaModelException(unresolvedEntryStatus);
+		return resolvedClasspath;
+	}
+
+	private void verbose_reentering_classpath_resolution() {
+		Util.verbose(
+			"CPResolution: reentering raw classpath resolution, will use empty classpath instead" + //$NON-NLS-1$
+			"	project: " + getElementName() + '\n' + //$NON-NLS-1$
+			"	invocation stack trace:"); //$NON-NLS-1$
+		new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IResource resource(PackageFragmentRoot root) {
+		return this.project;
+	}
+
+	/**
+	 * Retrieve a shared property on a project. If the property is not defined, answers null.
+	 * Note that it is orthogonal to IResource persistent properties, and client code has to decide
+	 * which form of storage to use appropriately. Shared properties produce real resource files which
+	 * can be shared through a VCM onto a server. Persistent properties are not shareable.
+	 *
+	 * @param key String
+	 * @see JavaProject#setSharedProperty(String, String)
+	 * @return String
+	 * @throws CoreException
+	 */
+	public String getSharedProperty(String key) throws CoreException {
+
+		String property = null;
+		IFile rscFile = this.project.getFile(key);
+		if (rscFile.exists()) {
+			byte[] bytes = Util.getResourceContentsAsByteArray(rscFile);
+			try {
+				property = new String(bytes, org.eclipse.jdt.internal.compiler.util.Util.UTF_8); // .classpath always encoded with UTF-8
+			} catch (UnsupportedEncodingException e) {
+				Util.log(e, "Could not read .classpath with UTF-8 encoding"); //$NON-NLS-1$
+				// fallback to default
+				property = new String(bytes);
+			}
+		} else {
+			// when a project is imported, we get a first delta for the addition of the .project, but the .classpath is not accessible
+			// so default to using java.io.File
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=96258
+			URI location = rscFile.getLocationURI();
+			if (location != null) {
+				File file = Util.toLocalFile(location, null/*no progress monitor available*/);
+				if (file != null && file.exists()) {
+					byte[] bytes;
+					try {
+						bytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file);
+					} catch (IOException e) {
+						return null;
+					}
+					try {
+						property = new String(bytes, org.eclipse.jdt.internal.compiler.util.Util.UTF_8); // .classpath always encoded with UTF-8
+					} catch (UnsupportedEncodingException e) {
+						Util.log(e, "Could not read .classpath with UTF-8 encoding"); //$NON-NLS-1$
+						// fallback to default
+						property = new String(bytes);
+					}
+				}
+			}
+		}
+		return property;
+	}
+
+	/**
+	 * @see JavaElement
+	 */
+	public SourceMapper getSourceMapper() {
+
+		return null;
+	}
+
+	/**
+	 * @see IJavaElement
+	 */
+	public IResource getUnderlyingResource() throws JavaModelException {
+		if (!exists()) throw newNotPresentException();
+		return this.project;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public boolean hasBuildState() {
+
+		return JavaModelManager.getJavaModelManager().getLastBuiltState(this.project, null) != null;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public boolean hasClasspathCycle(IClasspathEntry[] preferredClasspath) {
+		LinkedHashSet cycleParticipants = new LinkedHashSet();
+		HashMap preferredClasspaths = new HashMap(1);
+		preferredClasspaths.put(this, preferredClasspath);
+		updateCycleParticipants(new ArrayList(2), cycleParticipants, ResourcesPlugin.getWorkspace().getRoot(), new HashSet(2), preferredClasspaths);
+		return !cycleParticipants.isEmpty();
+	}
+
+	public boolean hasCycleMarker(){
+		return getCycleMarker() != null;
+	}
+
+	public int hashCode() {
+		return this.project.hashCode();
+	}
+	
+	private boolean hasUTF8BOM(byte[] bytes) {
+		if (bytes.length > IContentDescription.BOM_UTF_8.length) {
+			for (int i = 0, length = IContentDescription.BOM_UTF_8.length; i < length; i++) {
+				if (IContentDescription.BOM_UTF_8[i] != bytes[i])
+					return false;
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Answers true if the project potentially contains any source. A project which has no source is immutable.
+	 * @return boolean
+	 */
+	public boolean hasSource() {
+
+		// look if any source folder on the classpath
+		// no need for resolved path given source folder cannot be abstracted
+		IClasspathEntry[] entries;
+		try {
+			entries = getRawClasspath();
+		} catch (JavaModelException e) {
+			return true; // unsure
+		}
+		for (int i = 0, max = entries.length; i < max; i++) {
+			if (entries[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+
+	/*
+	 * @see IJavaProject
+	 */
+	public boolean isOnClasspath(IJavaElement element) {
+		IClasspathEntry[] rawClasspath;
+		try {
+			rawClasspath = getRawClasspath();
+		} catch(JavaModelException e){
+			return false; // not a Java project
+		}
+		int elementType = element.getElementType();
+		boolean isPackageFragmentRoot = false;
+		boolean isFolderPath = false;
+		boolean isSource = false;
+		switch (elementType) {
+			case IJavaElement.JAVA_MODEL:
+				return false;
+			case IJavaElement.JAVA_PROJECT:
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+				isPackageFragmentRoot = true;
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT:
+				isFolderPath = !((IPackageFragmentRoot)element.getParent()).isArchive();
+				break;
+			case IJavaElement.COMPILATION_UNIT:
+				isSource = true;
+				break;
+			default:
+				isSource = element.getAncestor(IJavaElement.COMPILATION_UNIT) != null;
+				break;
+		}
+		IPath elementPath = element.getPath();
+
+		// first look at unresolved entries
+		int length = rawClasspath.length;
+		for (int i = 0; i < length; i++) {
+			IClasspathEntry entry = rawClasspath[i];
+			switch (entry.getEntryKind()) {
+				case IClasspathEntry.CPE_LIBRARY:
+				case IClasspathEntry.CPE_PROJECT:
+				case IClasspathEntry.CPE_SOURCE:
+					if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, entry))
+						return true;
+					break;
+			}
+		}
+
+		// no need to go further for compilation units and elements inside a compilation unit
+		// it can only be in a source folder, thus on the raw classpath
+		if (isSource)
+			return false;
+
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304081
+		// All the resolved classpath entries need to be considered, including the referenced classpath entries
+		IClasspathEntry[] resolvedClasspath = null;
+		try {
+			resolvedClasspath = getResolvedClasspath();
+		} catch (JavaModelException e) {
+			return false; // Perhaps, not a Java project
+		}
+
+		for (int index = 0; index < resolvedClasspath.length; index++) {
+			if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, resolvedClasspath[index]))
+				return true;
+		}
+		
+		return false;
+	}
+
+	/*
+	 * @see IJavaProject
+	 */
+	public boolean isOnClasspath(IResource resource) {
+		IPath exactPath = resource.getFullPath();
+		IPath path = exactPath;
+
+		// ensure that folders are only excluded if all of their children are excluded
+		int resourceType = resource.getType();
+		boolean isFolderPath = resourceType == IResource.FOLDER || resourceType == IResource.PROJECT;
+
+		IClasspathEntry[] classpath;
+		try {
+			classpath = this.getResolvedClasspath();
+		} catch(JavaModelException e){
+			return false; // not a Java project
+		}
+		for (int i = 0; i < classpath.length; i++) {
+			IClasspathEntry entry = classpath[i];
+			IPath entryPath = entry.getPath();
+			if (entryPath.equals(exactPath)) { // package fragment roots must match exactly entry pathes (no exclusion there)
+				return true;
+			}
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=276373
+			// When a classpath entry is absolute, convert the resource's relative path to a file system path and compare
+			// e.g - /P/lib/variableLib.jar and /home/P/lib/variableLib.jar when compared should return true
+			if (entryPath.isAbsolute()
+					&& entryPath.equals(ResourcesPlugin.getWorkspace().getRoot().getLocation().append(exactPath))) {
+				return true;
+			}
+			if (entryPath.isPrefixOf(path)
+					&& !Util.isExcluded(path, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), isFolderPath)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean isOnClasspathEntry(IPath elementPath, boolean isFolderPath, boolean isPackageFragmentRoot, IClasspathEntry entry) {
+		IPath entryPath = entry.getPath();
+		if (isPackageFragmentRoot) {
+			// package fragment roots must match exactly entry pathes (no exclusion there)
+			if (entryPath.equals(elementPath))
+				return true;
+		} else {
+			if (entryPath.isPrefixOf(elementPath)
+					&& !Util.isExcluded(elementPath, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), isFolderPath))
+				return true;
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=276373
+		if (entryPath.isAbsolute()
+				&& entryPath.equals(ResourcesPlugin.getWorkspace().getRoot().getLocation().append(elementPath))) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * load preferences from a shareable format (VCM-wise)
+	 */
+	 private IEclipsePreferences loadPreferences() {
+
+	 	IEclipsePreferences preferences = null;
+	 	IPath projectMetaLocation = getPluginWorkingLocation();
+		if (projectMetaLocation != null) {
+			File prefFile = projectMetaLocation.append(PREF_FILENAME).toFile();
+			if (prefFile.exists()) { // load preferences from file
+				InputStream in = null;
+				try {
+					in = new BufferedInputStream(new FileInputStream(prefFile));
+					preferences = Platform.getPreferencesService().readPreferences(in);
+				} catch (CoreException e) { // problems loading preference store - quietly ignore
+				} catch (IOException e) { // problems loading preference store - quietly ignore
+				} finally {
+					if (in != null) {
+						try {
+							in.close();
+						} catch (IOException e) { // ignore problems with close
+						}
+					}
+				}
+				// one shot read, delete old preferences
+				prefFile.delete();
+				return preferences;
+			}
+		}
+		return null;
+	 }
+
+	/**
+	 * @see IJavaProject#newEvaluationContext()
+	 */
+	public IEvaluationContext newEvaluationContext() {
+		EvaluationContext context = new EvaluationContext();
+		context.setLineSeparator(Util.getLineSeparator(null/*no existing source*/, this));
+		return new EvaluationContextWrapper(context, this);
+	}
+
+	/*
+	 * Returns a new name lookup. This name lookup first looks in the given working copies.
+	 */
+	public NameLookup newNameLookup(ICompilationUnit[] workingCopies) throws JavaModelException {
+		return getJavaProjectElementInfo().newNameLookup(this, workingCopies);
+	}
+
+	/*
+	 * Returns a new name lookup. This name lookup first looks in the working copies of the given owner.
+	 */
+	public NameLookup newNameLookup(WorkingCopyOwner owner) throws JavaModelException {
+
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		ICompilationUnit[] workingCopies = owner == null ? null : manager.getWorkingCopies(owner, true/*add primary WCs*/);
+		return newNameLookup(workingCopies);
+	}
+
+	/*
+	 * Returns a new search name environment for this project. This name environment first looks in the given working copies.
+	 */
+	public SearchableEnvironment newSearchableNameEnvironment(ICompilationUnit[] workingCopies) throws JavaModelException {
+		return new SearchableEnvironment(this, workingCopies);
+	}
+
+	/*
+	 * Returns a new search name environment for this project. This name environment first looks in the working copies
+	 * of the given owner.
+	 */
+	public SearchableEnvironment newSearchableNameEnvironment(WorkingCopyOwner owner) throws JavaModelException {
+		return new SearchableEnvironment(this, owner);
+	}
+
+	/*
+	 * Returns a PerProjectInfo that doesn't register classpath change
+	 * and that should be used as a temporary info.
+	 */
+	public PerProjectInfo newTemporaryInfo() {
+		return 
+			new PerProjectInfo(this.project.getProject()) {
+				protected ClasspathChange addClasspathChange() {
+					return null;
+				}
+		};
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public ITypeHierarchy newTypeHierarchy(
+		IRegion region,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		return newTypeHierarchy(region, DefaultWorkingCopyOwner.PRIMARY, monitor);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public ITypeHierarchy newTypeHierarchy(
+		IRegion region,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		if (region == null) {
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
+		}
+		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+		CreateTypeHierarchyOperation op =
+			new CreateTypeHierarchyOperation(region, workingCopies, null, true);
+		op.runOperation(monitor);
+		return op.getResult();
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public ITypeHierarchy newTypeHierarchy(
+		IType type,
+		IRegion region,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		return newTypeHierarchy(type, region, DefaultWorkingCopyOwner.PRIMARY, monitor);
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public ITypeHierarchy newTypeHierarchy(
+		IType type,
+		IRegion region,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		if (type == null) {
+			throw new IllegalArgumentException(Messages.hierarchy_nullFocusType);
+		}
+		if (region == null) {
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
+		}
+		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+		CreateTypeHierarchyOperation op =
+			new CreateTypeHierarchyOperation(region, workingCopies, type, true/*compute subtypes*/);
+		op.runOperation(monitor);
+		return op.getResult();
+	}
+	public String[] projectPrerequisites(IClasspathEntry[] resolvedClasspath)
+		throws JavaModelException {
+
+		ArrayList prerequisites = new ArrayList();
+		for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
+			IClasspathEntry entry = resolvedClasspath[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+				prerequisites.add(entry.getPath().lastSegment());
+			}
+		}
+		int size = prerequisites.size();
+		if (size == 0) {
+			return NO_PREREQUISITES;
+		} else {
+			String[] result = new String[size];
+			prerequisites.toArray(result);
+			return result;
+		}
+	}
+	/**
+	 * Reads the classpath file entries of this project's .classpath file.
+	 * Returns a two-dimensional array, where the number of elements in the row is fixed to 2.
+	 * The first element is an array of raw classpath entries, which includes the output entry,
+	 * and the second element is an array of referenced entries that may have been stored 
+	 * by the client earlier. 
+	 * See {@link IJavaProject#getReferencedClasspathEntries()} for more details.
+	 * As a side effect, unknown elements are stored in the given map (if not null)
+	 * Throws exceptions if the file cannot be accessed or is malformed.
+	 */
+	public IClasspathEntry[][] readFileEntriesWithException(Map unknownElements) throws CoreException, IOException, ClasspathEntry.AssertionFailedException {
+		IFile rscFile = this.project.getFile(JavaProject.CLASSPATH_FILENAME);
+		byte[] bytes;
+		if (rscFile.exists()) {
+			bytes = Util.getResourceContentsAsByteArray(rscFile);
+		} else {
+			// when a project is imported, we get a first delta for the addition of the .project, but the .classpath is not accessible
+			// so default to using java.io.File
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=96258
+			URI location = rscFile.getLocationURI();
+			if (location == null)
+				throw new IOException("Cannot obtain a location URI for " + rscFile); //$NON-NLS-1$
+			File file = Util.toLocalFile(location, null/*no progress monitor available*/);
+			if (file == null)
+				throw new IOException("Unable to fetch file from " + location); //$NON-NLS-1$
+			try {
+				bytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file);
+			} catch (IOException e) {
+				if (!file.exists())
+					return new IClasspathEntry[][]{defaultClasspath(), ClasspathEntry.NO_ENTRIES};
+				throw e;
+			}
+		}
+		if (hasUTF8BOM(bytes)) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=240034
+			int length = bytes.length-IContentDescription.BOM_UTF_8.length;
+			System.arraycopy(bytes, IContentDescription.BOM_UTF_8.length, bytes = new byte[length], 0, length);
+		}
+		String xmlClasspath;
+		try {
+			xmlClasspath = new String(bytes, org.eclipse.jdt.internal.compiler.util.Util.UTF_8); // .classpath always encoded with UTF-8
+		} catch (UnsupportedEncodingException e) {
+			Util.log(e, "Could not read .classpath with UTF-8 encoding"); //$NON-NLS-1$
+			// fallback to default
+			xmlClasspath = new String(bytes);
+		}
+		return decodeClasspath(xmlClasspath, unknownElements);
+	}
+
+	/*
+	 * Reads the classpath file entries of this project's .classpath file.
+	 * This includes the output entry.
+	 * As a side effect, unknown elements are stored in the given map (if not null)
+	 */
+	private IClasspathEntry[][] readFileEntries(Map unkwownElements) {
+		try {
+			return readFileEntriesWithException(unkwownElements);
+		} catch (CoreException e) {
+			Util.log(e, "Exception while reading " + getPath().append(JavaProject.CLASSPATH_FILENAME)); //$NON-NLS-1$
+			return new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+		} catch (IOException e) {
+			Util.log(e, "Exception while reading " + getPath().append(JavaProject.CLASSPATH_FILENAME)); //$NON-NLS-1$
+			return new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+		} catch (ClasspathEntry.AssertionFailedException e) {
+			Util.log(e, "Exception while reading " + getPath().append(JavaProject.CLASSPATH_FILENAME)); //$NON-NLS-1$
+			return new IClasspathEntry[][]{JavaProject.INVALID_CLASSPATH, ClasspathEntry.NO_ENTRIES};
+		}
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IPath readOutputLocation() {
+		// Read classpath file without creating markers nor logging problems
+		IClasspathEntry[][] classpath = readFileEntries(null/*not interested in unknown elements*/);
+		if (classpath[0] == JavaProject.INVALID_CLASSPATH)
+			return defaultOutputLocation();
+
+		// extract the output location
+		IPath outputLocation = null;
+		if (classpath[0].length > 0) {
+			IClasspathEntry entry = classpath[0][classpath[0].length - 1];
+			if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+				outputLocation = entry.getPath();
+			}
+		}
+		return outputLocation;
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public IClasspathEntry[] readRawClasspath() {
+		// Read classpath file without creating markers nor logging problems
+		IClasspathEntry[][] classpath = readFileEntries(null/*not interested in unknown elements*/);
+		if (classpath[0] == JavaProject.INVALID_CLASSPATH)
+			return defaultClasspath();
+
+		// discard the output location
+		if (classpath[0].length > 0) {
+			IClasspathEntry entry = classpath[0][classpath[0].length - 1];
+			if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
+				IClasspathEntry[] copy = new IClasspathEntry[classpath[0].length - 1];
+				System.arraycopy(classpath[0], 0, copy, 0, copy.length);
+				classpath[0] = copy;
+			}
+		}
+		return classpath[0];
+	}
+
+	/**
+	 * Removes the given builder from the build spec for the given project.
+	 */
+	protected void removeFromBuildSpec(String builderID) throws CoreException {
+
+		IProjectDescription description = this.project.getDescription();
+		ICommand[] commands = description.getBuildSpec();
+		for (int i = 0; i < commands.length; ++i) {
+			if (commands[i].getBuilderName().equals(builderID)) {
+				ICommand[] newCommands = new ICommand[commands.length - 1];
+				System.arraycopy(commands, 0, newCommands, 0, i);
+				System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
+				description.setBuildSpec(newCommands);
+				this.project.setDescription(description, null);
+				return;
+			}
+		}
+	}
+
+	/*
+	 * Resets this project's caches
+	 */
+	public void resetCaches() {
+		JavaProjectElementInfo info = (JavaProjectElementInfo) JavaModelManager.getJavaModelManager().peekAtInfo(this);
+		if (info != null){
+			info.resetCaches();
+		}
+	}
+
+	public ClasspathChange resetResolvedClasspath() {
+		try {
+			return getPerProjectInfo().resetResolvedClasspath();
+		} catch (JavaModelException e) {
+			// project doesn't exist
+			return null;
+		}
+	}		
+	
+	/*
+	 * Resolve the given raw classpath.
+	 */
+	public IClasspathEntry[] resolveClasspath(IClasspathEntry[] rawClasspath) throws JavaModelException {
+		return resolveClasspath(rawClasspath, false/*don't use previous session*/, true/*resolve chained libraries*/).resolvedClasspath;
+	}
+	
+	static class ResolvedClasspath {
+		IClasspathEntry[] resolvedClasspath;
+		IJavaModelStatus unresolvedEntryStatus = JavaModelStatus.VERIFIED_OK;
+		HashMap rawReverseMap = new HashMap();
+		Map rootPathToResolvedEntries = new HashMap();
+		IClasspathEntry[] referencedEntries = null;
+	}
+	
+	public ResolvedClasspath resolveClasspath(IClasspathEntry[] rawClasspath, boolean usePreviousSession, boolean resolveChainedLibraries) throws JavaModelException {
+		return resolveClasspath(rawClasspath, null, usePreviousSession, resolveChainedLibraries);
+	}
+
+	public ResolvedClasspath resolveClasspath(IClasspathEntry[] rawClasspath, IClasspathEntry[] referencedEntries, boolean usePreviousSession, boolean resolveChainedLibraries) throws JavaModelException {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
+		ResolvedClasspath result = new ResolvedClasspath();
+		Map knownDrives = new HashMap();
+
+		Map referencedEntriesMap = new HashMap();
+		List rawLibrariesPath = new ArrayList();
+		LinkedHashSet resolvedEntries = new LinkedHashSet();
+		
+		if(resolveChainedLibraries) {
+			for (int index = 0; index < rawClasspath.length; index++) {
+				IClasspathEntry currentEntry = rawClasspath[index]; 
+				if (currentEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+					rawLibrariesPath.add(ClasspathEntry.resolveDotDot(getProject().getLocation(), currentEntry.getPath()));
+				}
+			}
+			if (referencedEntries != null) {
+				// The Set is required to keep the order intact while the referencedEntriesMap (Map)
+				// is used to map the referenced entries with path
+				LinkedHashSet referencedEntriesSet = new LinkedHashSet();
+				for (int index = 0; index < referencedEntries.length; index++) {
+					IPath path = referencedEntries[index].getPath();
+					if (!rawLibrariesPath.contains(path) && referencedEntriesMap.get(path) == null) {
+						referencedEntriesMap.put(path, referencedEntries[index]);
+						referencedEntriesSet.add(referencedEntries[index]);
+					}
+				}
+				if (referencedEntriesSet.size() > 0) {
+					result.referencedEntries = new IClasspathEntry[referencedEntriesSet.size()];
+					referencedEntriesSet.toArray(result.referencedEntries);
+				}
+			}
+		}
+		
+		int length = rawClasspath.length;
+		for (int i = 0; i < length; i++) {
+
+			IClasspathEntry rawEntry = rawClasspath[i];
+			IClasspathEntry resolvedEntry = rawEntry;
+
+			switch (rawEntry.getEntryKind()){
+
+				case IClasspathEntry.CPE_VARIABLE :
+					try {
+						resolvedEntry = manager.resolveVariableEntry(rawEntry, usePreviousSession);
+					} catch (ClasspathEntry.AssertionFailedException e) {
+						// Catch the assertion failure and set status instead
+						// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=55992
+						result.unresolvedEntryStatus = new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
+						break;
+					}
+					if (resolvedEntry == null) {
+						result.unresolvedEntryStatus = new JavaModelStatus(IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND, this, rawEntry.getPath());
+					} else {
+						// If the entry is already present in the rawReversetMap, it means the entry and the chained libraries
+						// have already been processed. So, skip it.
+						if (resolveChainedLibraries && resolvedEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY
+													&& result.rawReverseMap.get(resolvedEntry.getPath()) == null) {
+							// resolve Class-Path: in manifest
+							ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
+							for (int j = 0, length2 = extraEntries.length; j < length2; j++) {
+								if (!rawLibrariesPath.contains(extraEntries[j].getPath())) {
+									// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305037
+									// referenced entries for variable entries could also be persisted with extra attributes, so addAsChainedEntry = true
+									addToResult(rawEntry, extraEntries[j], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
+								}
+							}
+						}
+						addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
+					}
+					break;
+
+				case IClasspathEntry.CPE_CONTAINER :
+					IClasspathContainer container = usePreviousSession ? manager.getPreviousSessionContainer(rawEntry.getPath(), this) : JavaCore.getClasspathContainer(rawEntry.getPath(), this);
+					if (container == null){
+						result.unresolvedEntryStatus = new JavaModelStatus(IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND, this, rawEntry.getPath());
+						break;
+					}
+
+					IClasspathEntry[] containerEntries = container.getClasspathEntries();
+					if (containerEntries == null) {
+						if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+							JavaModelManager.getJavaModelManager().verbose_missbehaving_container_null_entries(this, rawEntry.getPath());
+						}
+						break;
+					}
+
+					// container was bound
+					for (int j = 0, containerLength = containerEntries.length; j < containerLength; j++){
+						ClasspathEntry cEntry = (ClasspathEntry) containerEntries[j];
+						if (cEntry == null) {
+							if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+								JavaModelManager.getJavaModelManager().verbose_missbehaving_container(this, rawEntry.getPath(), containerEntries);
+							}
+							break;
+						}
+						// if container is exported or restricted, then its nested entries must in turn be exported  (21749) and/or propagate restrictions
+						cEntry = cEntry.combineWith((ClasspathEntry) rawEntry);
+						
+						if (cEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+							// resolve ".." in library path
+							cEntry = cEntry.resolvedDotDot(getProject().getLocation());
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=313965
+							// Do not resolve if the system attribute is set to false	
+							if (resolveChainedLibraries
+									&& JavaModelManager.getJavaModelManager().resolveReferencedLibrariesForContainers
+									&& result.rawReverseMap.get(cEntry.getPath()) == null) {
+								// resolve Class-Path: in manifest
+								ClasspathEntry[] extraEntries = cEntry.resolvedChainedLibraries();
+								for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
+									if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
+										addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
+									}
+								}
+							}
+						}
+						addToResult(rawEntry, cEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
+					}
+					break;
+
+				case IClasspathEntry.CPE_LIBRARY:
+					// resolve ".." in library path
+					resolvedEntry = ((ClasspathEntry) rawEntry).resolvedDotDot(getProject().getLocation());
+					
+					if (resolveChainedLibraries && result.rawReverseMap.get(resolvedEntry.getPath()) == null) {
+						// resolve Class-Path: in manifest
+						ClasspathEntry[] extraEntries = ((ClasspathEntry) resolvedEntry).resolvedChainedLibraries();
+						for (int k = 0, length2 = extraEntries.length; k < length2; k++) {
+							if (!rawLibrariesPath.contains(extraEntries[k].getPath())) {
+								addToResult(rawEntry, extraEntries[k], result, resolvedEntries, externalFoldersManager, referencedEntriesMap, true, knownDrives);
+							}
+						}
+					}
+
+					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
+					break;
+				default :
+					addToResult(rawEntry, resolvedEntry, result, resolvedEntries, externalFoldersManager, referencedEntriesMap, false, knownDrives);
+					break;
+			}
+		}
+		result.resolvedClasspath = new IClasspathEntry[resolvedEntries.size()];
+		resolvedEntries.toArray(result.resolvedClasspath);
+		return result;
+	}
+
+	private void addToResult(IClasspathEntry rawEntry, IClasspathEntry resolvedEntry, ResolvedClasspath result,
+			LinkedHashSet resolvedEntries, ExternalFoldersManager externalFoldersManager,
+			Map oldChainedEntriesMap, boolean addAsChainedEntry, Map knownDrives) {
+
+		IPath resolvedPath;
+		// If it's already been resolved, do not add to resolvedEntries
+		if (result.rawReverseMap.get(resolvedPath = resolvedEntry.getPath()) == null) {
+			result.rawReverseMap.put(resolvedPath, rawEntry);
+			result.rootPathToResolvedEntries.put(resolvedPath, resolvedEntry);
+			resolvedEntries.add(resolvedEntry);
+			if (addAsChainedEntry) {
+				IClasspathEntry chainedEntry = null;
+				chainedEntry = (ClasspathEntry) oldChainedEntriesMap.get(resolvedPath);
+				if (chainedEntry != null) {
+					// This is required to keep the attributes if any added by the user in
+					// the previous session such as source attachment path etc.
+					copyFromOldChainedEntry((ClasspathEntry) resolvedEntry, (ClasspathEntry) chainedEntry);
+				}
+			}
+		}
+		if (resolvedEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && ExternalFoldersManager.isExternalFolderPath(resolvedPath)) {
+			externalFoldersManager.addFolder(resolvedPath, true/*scheduleForCreation*/); // no-op if not an external folder or if already registered
+		}
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=336046
+		// The source attachment path could be external too and in which case, must be added.
+		IPath sourcePath = resolvedEntry.getSourceAttachmentPath();
+		if (sourcePath != null && driveExists(sourcePath, knownDrives) && ExternalFoldersManager.isExternalFolderPath(sourcePath)) {
+			externalFoldersManager.addFolder(sourcePath, true);
+		}
+	}
+
+	private void copyFromOldChainedEntry(ClasspathEntry resolvedEntry, ClasspathEntry chainedEntry) {
+		IPath path = chainedEntry.getSourceAttachmentPath();
+		if ( path != null) {
+			resolvedEntry.sourceAttachmentPath = path;
+		}
+		path = chainedEntry.getSourceAttachmentRootPath();
+		if (path != null) {
+			resolvedEntry.sourceAttachmentRootPath = path;
+		}
+		IClasspathAttribute[] attributes = chainedEntry.getExtraAttributes();
+		if (attributes != null) {
+			resolvedEntry.extraAttributes = attributes;
+		}
+	}
+	
+	/*
+	 * File#exists() takes lot of time for an unmapped drive. Hence, cache the info.
+	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649
+	 */
+	private boolean driveExists(IPath sourcePath, Map knownDrives) {	
+		String drive = sourcePath.getDevice();
+		if (drive == null) return true;
+		Boolean good = (Boolean)knownDrives.get(drive);
+		if (good == null) {
+			if (new File(drive).exists()) {
+				knownDrives.put(drive, Boolean.TRUE);
+				return true;
+			} else {
+				knownDrives.put(drive, Boolean.FALSE);
+				return false;
+			}
+		}
+		return good.booleanValue();
+	}
+	
+	/*
+	 * Resolve the given perProjectInfo's raw classpath and store the resolved classpath in the perProjectInfo.
+	 */
+	public void resolveClasspath(PerProjectInfo perProjectInfo, boolean usePreviousSession, boolean addClasspathChange) throws JavaModelException {
+		if (CP_RESOLUTION_BP_LISTENERS != null)
+			breakpoint(1, this);
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		boolean isClasspathBeingResolved = manager.isClasspathBeingResolved(this);
+		try {
+			if (!isClasspathBeingResolved) {
+				manager.setClasspathBeingResolved(this, true);
+			}
+
+			// get raw info inside a synchronized block to ensure that it is consistent
+			IClasspathEntry[][] classpath = new IClasspathEntry[2][];
+			int timeStamp;
+			synchronized (perProjectInfo) {
+				classpath[0] = perProjectInfo.rawClasspath;
+				classpath[1] = perProjectInfo.referencedEntries;
+				// Checking null only for rawClasspath enough
+				if (classpath[0] == null)
+					classpath = perProjectInfo.readAndCacheClasspath(this);
+				timeStamp = perProjectInfo.rawTimeStamp;
+			}
+
+			ResolvedClasspath result = resolveClasspath(classpath[0], classpath[1], usePreviousSession, true/*resolve chained libraries*/);
+			
+			if (CP_RESOLUTION_BP_LISTENERS != null)
+				breakpoint(2, this);
+
+			// store resolved info along with the raw info to ensure consistency
+			perProjectInfo.setResolvedClasspath(result.resolvedClasspath, result.referencedEntries, result.rawReverseMap, result.rootPathToResolvedEntries, usePreviousSession ? PerProjectInfo.NEED_RESOLUTION : result.unresolvedEntryStatus, timeStamp, addClasspathChange);
+		} finally {
+			if (!isClasspathBeingResolved) {
+				manager.setClasspathBeingResolved(this, false);
+			}
+			if (CP_RESOLUTION_BP_LISTENERS != null)
+				breakpoint(3, this);
+		}
+	}
+	
+	/**
+	 * Answers an ID which is used to distinguish project/entries during package
+	 * fragment root computations
+	 * @return String
+	 */
+	public String rootID(){
+		return "[PRJ]"+this.project.getFullPath(); //$NON-NLS-1$
+	}
+
+	/**
+	 * Writes the classpath in a sharable format (VCM-wise) only when necessary, that is, if  it is semantically different
+	 * from the existing one in file. Will never write an identical one.
+	 *
+	 * @param newClasspath IClasspathEntry[]
+	 * @param newOutputLocation IPath
+	 * @return boolean Return whether the .classpath file was modified.
+	 * @throws JavaModelException
+	 */
+	public boolean writeFileEntries(IClasspathEntry[] newClasspath, IClasspathEntry[] referencedEntries, IPath newOutputLocation) throws JavaModelException {
+
+		if (!this.project.isAccessible()) return false;
+
+		Map unknownElements = new HashMap();
+		IClasspathEntry[][] fileEntries = readFileEntries(unknownElements);
+		if (fileEntries[0] != JavaProject.INVALID_CLASSPATH && 
+				areClasspathsEqual(newClasspath, newOutputLocation, fileEntries[0])
+				&& (referencedEntries == null || areClasspathsEqual(referencedEntries, fileEntries[1])) ) {
+			// no need to save it, it is the same
+			return false;
+		}
+
+		// actual file saving
+		try {
+			setSharedProperty(JavaProject.CLASSPATH_FILENAME, encodeClasspath(newClasspath, referencedEntries, newOutputLocation, true, unknownElements));
+			return true;
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+	}
+	public boolean writeFileEntries(IClasspathEntry[] newClasspath, IPath newOutputLocation) throws JavaModelException {
+		return writeFileEntries(newClasspath, ClasspathEntry.NO_ENTRIES, newOutputLocation);
+	}
+
+	/**
+	 * Update the Java command in the build spec (replace existing one if present,
+	 * add one first if none).
+	 */
+	private void setJavaCommand(
+		IProjectDescription description,
+		ICommand newCommand)
+		throws CoreException {
+
+		ICommand[] oldBuildSpec = description.getBuildSpec();
+		int oldJavaCommandIndex = getJavaCommandIndex(oldBuildSpec);
+		ICommand[] newCommands;
+
+		if (oldJavaCommandIndex == -1) {
+			// Add a Java build spec before other builders (1FWJK7I)
+			newCommands = new ICommand[oldBuildSpec.length + 1];
+			System.arraycopy(oldBuildSpec, 0, newCommands, 1, oldBuildSpec.length);
+			newCommands[0] = newCommand;
+		} else {
+		    oldBuildSpec[oldJavaCommandIndex] = newCommand;
+			newCommands = oldBuildSpec;
+		}
+
+		// Commit the spec change into the project
+		description.setBuildSpec(newCommands);
+		this.project.setDescription(description, null);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.IJavaProject#setOption(java.lang.String, java.lang.String)
+	 */
+	public void setOption(String optionName, String optionValue) {
+		// Store option value
+		IEclipsePreferences projectPreferences = getEclipsePreferences();
+		boolean modified = JavaModelManager.getJavaModelManager().storePreference(optionName, optionValue, projectPreferences, null);
+
+		// Write changes
+		if (modified) {
+			try {
+				projectPreferences.flush();
+			} catch (BackingStoreException e) {
+				// problem with pref store - quietly ignore
+			}
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.IJavaProject#setOptions(Map)
+	 */
+	public void setOptions(Map newOptions) {
+
+		IEclipsePreferences projectPreferences = getEclipsePreferences();
+		if (projectPreferences == null) return;
+		try {
+			if (newOptions == null){
+				projectPreferences.clear();
+			} else {
+				Iterator entries = newOptions.entrySet().iterator();
+				JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
+				while (entries.hasNext()){
+					Map.Entry entry = (Map.Entry) entries.next();
+					String key = (String) entry.getKey();
+					String value = (String) entry.getValue();
+					javaModelManager.storePreference(key, value, projectPreferences, newOptions);
+				}
+
+				// reset to default all options not in new map
+				// @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=26255
+				// @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49691
+				String[] pNames = projectPreferences.keys();
+				int ln = pNames.length;
+				for (int i=0; i<ln; i++) {
+					String key = pNames[i];
+					if (!newOptions.containsKey(key)) {
+						projectPreferences.remove(key); // old preferences => remove from preferences table
+					}
+				}
+			}
+
+			// persist options
+			projectPreferences.flush();
+
+			// flush cache immediately
+			try {
+				getPerProjectInfo().options = null;
+			} catch (JavaModelException e) {
+				// do nothing
+			}
+		} catch (BackingStoreException e) {
+			// problem with pref store - quietly ignore
+		}
+	}
+	/**
+	 * @see IJavaProject
+	 */
+	public void setOutputLocation(IPath path, IProgressMonitor monitor) throws JavaModelException {
+		if (path == null) {
+			throw new IllegalArgumentException(Messages.path_nullPath);
+		}
+		if (path.equals(getOutputLocation())) {
+			return;
+		}
+		setRawClasspath(getRawClasspath(), path, monitor);
+	}
+
+	/**
+	 * Sets the underlying kernel project of this Java project,
+	 * and fills in its parent and name.
+	 * Called by IProject.getNature().
+	 *
+	 * @see IProjectNature#setProject(IProject)
+	 */
+	public void setProject(IProject project) {
+
+		this.project = project;
+		this.parent = JavaModelManager.getJavaModelManager().getJavaModel();
+	}
+
+	/**
+	 * @see IJavaProject#setRawClasspath(IClasspathEntry[],boolean,IProgressMonitor)
+	 */
+	public void setRawClasspath(
+		IClasspathEntry[] entries,
+		boolean canModifyResources,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		setRawClasspath(
+			entries,
+			getOutputLocation()/*don't change output*/,
+			canModifyResources,
+			monitor);
+	}
+
+	/**
+	 * @see IJavaProject#setRawClasspath(IClasspathEntry[],IPath,boolean,IProgressMonitor)
+	 */
+	public void setRawClasspath(
+			IClasspathEntry[] newRawClasspath,
+			IPath newOutputLocation,
+			boolean canModifyResources,
+			IProgressMonitor monitor)
+			throws JavaModelException {
+		setRawClasspath(newRawClasspath, null, newOutputLocation, canModifyResources, monitor);
+	}
+
+	/**
+	 * @see IJavaProject#setRawClasspath(IClasspathEntry[],IPath,IProgressMonitor)
+	 */
+	public void setRawClasspath(
+		IClasspathEntry[] entries,
+		IPath outputLocation,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		setRawClasspath(
+			entries,
+			outputLocation,
+			true/*can change resource (as per API contract)*/,
+			monitor);
+	}
+	
+	public void setRawClasspath(IClasspathEntry[] entries, IClasspathEntry[] referencedEntries, IPath outputLocation,
+			IProgressMonitor monitor) throws JavaModelException {
+		setRawClasspath(entries, referencedEntries, outputLocation, true, monitor);
+	}
+	
+	protected void setRawClasspath(IClasspathEntry[] newRawClasspath, IClasspathEntry[] referencedEntries, IPath newOutputLocation,
+			boolean canModifyResources,	IProgressMonitor monitor) throws JavaModelException {
+
+		try {
+			if (newRawClasspath == null) //are we already with the default classpath
+				newRawClasspath = defaultClasspath();
+
+			SetClasspathOperation op =
+				new SetClasspathOperation(
+					this,
+					newRawClasspath,
+					referencedEntries,
+					newOutputLocation,
+					canModifyResources);
+			op.runOperation(monitor);
+		} catch (JavaModelException e) {
+			JavaModelManager.getJavaModelManager().getDeltaProcessor().flush();
+			throw e;
+		}
+	}
+
+	/**
+	 * @see IJavaProject
+	 */
+	public void setRawClasspath(
+		IClasspathEntry[] entries,
+		IProgressMonitor monitor)
+		throws JavaModelException {
+
+		setRawClasspath(
+			entries,
+			getOutputLocation()/*don't change output*/,
+			true/*can change resource (as per API contract)*/,
+			monitor);
+	}
+
+	/**
+	 * Record a shared persistent property onto a project.
+	 * Note that it is orthogonal to IResource persistent properties, and client code has to decide
+	 * which form of storage to use appropriately. Shared properties produce real resource files which
+	 * can be shared through a VCM onto a server. Persistent properties are not shareable.
+	 * <p>
+	 * Shared properties end up in resource files, and thus cannot be modified during
+	 * delta notifications (a CoreException would then be thrown).
+	 *
+	 * @param key String
+	 * @param value String
+	 * @see JavaProject#getSharedProperty(String key)
+	 * @throws CoreException
+	 */
+	public void setSharedProperty(String key, String value) throws CoreException {
+
+		IFile rscFile = this.project.getFile(key);
+		byte[] bytes = null;
+		try {
+			bytes = value.getBytes(org.eclipse.jdt.internal.compiler.util.Util.UTF_8); // .classpath always encoded with UTF-8
+		} catch (UnsupportedEncodingException e) {
+			Util.log(e, "Could not write .classpath with UTF-8 encoding "); //$NON-NLS-1$
+			// fallback to default
+			bytes = value.getBytes();
+		}
+		InputStream inputStream = new ByteArrayInputStream(bytes);
+		// update the resource content
+		if (rscFile.exists()) {
+			if (rscFile.isReadOnly()) {
+				// provide opportunity to checkout read-only .classpath file (23984)
+				ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, IWorkspace.VALIDATE_PROMPT);
+			}
+			rscFile.setContents(inputStream, IResource.FORCE, null);
+		} else {
+			rscFile.create(inputStream, IResource.FORCE, null);
+		}
+	}
+
+	/**
+	 * If a cycle is detected, then cycleParticipants contains all the paths of projects involved in this cycle (directly and indirectly),
+	 * no cycle if the set is empty (and started empty)
+	 * @param prereqChain ArrayList
+	 * @param cycleParticipants HashSet
+	 * @param workspaceRoot IWorkspaceRoot
+	 * @param traversed HashSet
+	 * @param preferredClasspaths Map
+	 */
+	public void updateCycleParticipants(
+			ArrayList prereqChain,
+			LinkedHashSet cycleParticipants,
+			IWorkspaceRoot workspaceRoot,
+			HashSet traversed,
+			Map preferredClasspaths){
+
+		IPath path = getPath();
+		prereqChain.add(path);
+		traversed.add(path);
+		try {
+			IClasspathEntry[] classpath = null;
+			if (preferredClasspaths != null) classpath = (IClasspathEntry[])preferredClasspaths.get(this);
+			if (classpath == null) classpath = getResolvedClasspath();
+			for (int i = 0, length = classpath.length; i < length; i++) {
+				IClasspathEntry entry = classpath[i];
+
+				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT){
+					IPath prereqProjectPath = entry.getPath();
+					int index = cycleParticipants.contains(prereqProjectPath) ? 0 : prereqChain.indexOf(prereqProjectPath);
+					if (index >= 0) { // refer to cycle, or in cycle itself
+						for (int size = prereqChain.size(); index < size; index++) {
+							cycleParticipants.add(prereqChain.get(index));
+						}
+					} else {
+						if (!traversed.contains(prereqProjectPath)) {
+							IResource member = workspaceRoot.findMember(prereqProjectPath);
+							if (member != null && member.getType() == IResource.PROJECT){
+								JavaProject javaProject = (JavaProject)JavaCore.create((IProject)member);
+								javaProject.updateCycleParticipants(prereqChain, cycleParticipants, workspaceRoot, traversed, preferredClasspaths);
+							}
+						}
+					}
+				}
+			}
+		} catch(JavaModelException e){
+			// project doesn't exist: ignore
+		}
+		prereqChain.remove(path);
+	}
+
+	/*
+	 * Update eclipse preferences from old preferences.
+	 */
+	 private void updatePreferences(IEclipsePreferences preferences) {
+
+	 	IEclipsePreferences oldPreferences = loadPreferences();
+	 	if (oldPreferences != null) {
+			try {
+		 		String[] propertyNames = oldPreferences.childrenNames();
+				for (int i = 0; i < propertyNames.length; i++){
+					String propertyName = propertyNames[i];
+				    String propertyValue = oldPreferences.get(propertyName, ""); //$NON-NLS-1$
+				    if (!"".equals(propertyValue)) { //$NON-NLS-1$
+					    preferences.put(propertyName, propertyValue);
+				    }
+				}
+				// save immediately new preferences
+				preferences.flush();
+			} catch (BackingStoreException e) {
+				// fails silently
+			}
+		}
+	 }
+
+	protected IStatus validateExistence(IResource underlyingResource) {
+		// check whether the java project can be opened
+		try {
+			if (!((IProject) underlyingResource).hasNature(JavaCore.NATURE_ID))
+				return newDoesNotExistStatus();
+		} catch (CoreException e) {
+			return newDoesNotExistStatus();
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java
new file mode 100644
index 0000000..b32dd46
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.HashSetOfArray;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+
+/**
+ * Info for IJavaProject.
+ * <p>
+ * Note: <code>getChildren()</code> returns all of the <code>IPackageFragmentRoots</code>
+ * specified on the classpath for the project.  This can include roots external to the
+ * project. See <code>JavaProject#getAllPackageFragmentRoots()</code> and
+ * <code>JavaProject#getPackageFragmentRoots()</code>.  To get only the <code>IPackageFragmentRoots</code>
+ * that are internal to the project, use <code>JavaProject#getChildren()</code>.
+ */
+
+/* package */
+class JavaProjectElementInfo extends OpenableElementInfo {
+
+	static final IPackageFragmentRoot[] NO_ROOTS = new IPackageFragmentRoot[0];
+
+	static class ProjectCache {
+		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, Map rootToResolvedEntries, Map pkgFragmentsCaches) {
+			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
+			this.rootToResolvedEntries = rootToResolvedEntries;
+			this.pkgFragmentsCaches = pkgFragmentsCaches;
+		}
+
+		/*
+		 * A cache of all package fragment roots of this project.
+		 */
+		public IPackageFragmentRoot[] allPkgFragmentRootsCache;
+
+		/*
+		 * A cache of all package fragments in this project.
+		 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name))
+		 */
+		public HashtableOfArrayToObject allPkgFragmentsCache;
+
+		/*
+		 * A cache of package fragments for each package fragment root of this project
+		 * (a map from IPackageFragmentRoot to a set of String[] (the package name))
+		 */
+		public Map pkgFragmentsCaches;
+
+		public Map rootToResolvedEntries;
+	}
+
+	/**
+	 * A array with all the non-java resources contained by this PackageFragment
+	 */
+	private Object[] nonJavaResources;
+
+	ProjectCache projectCache;
+
+	/*
+	 * Adds the given name and its super names to the given set
+	 * (e.g. for {"a", "b", "c"}, adds {"a", "b", "c"}, {"a", "b"}, and {"a"})
+	 */
+	static void addSuperPackageNames(String[] pkgName, HashtableOfArrayToObject packageFragments) {
+		for (int i = pkgName.length-1; i > 0; i--) {
+			if (packageFragments.getKey(pkgName, i) == null) {
+				System.arraycopy(pkgName, 0, pkgName = new String[i], 0, i);
+				packageFragments.put(pkgName, NO_ROOTS);
+			}
+		}
+	}
+
+	/**
+	 * Create and initialize a new instance of the receiver
+	 */
+	public JavaProjectElementInfo() {
+		this.nonJavaResources = null;
+	}
+
+	/**
+	 * Compute the non-java resources contained in this java project.
+	 */
+	private Object[] computeNonJavaResources(JavaProject project) {
+
+		// determine if src == project and/or if bin == project
+		IPath projectPath = project.getProject().getFullPath();
+		boolean srcIsProject = false;
+		boolean binIsProject = false;
+		char[][] inclusionPatterns = null;
+		char[][] exclusionPatterns = null;
+		IPath projectOutput = null;
+		boolean isClasspathResolved = true;
+		try {
+			IClasspathEntry entry = project.getClasspathEntryFor(projectPath);
+			if (entry != null) {
+				srcIsProject = true;
+				inclusionPatterns = ((ClasspathEntry)entry).fullInclusionPatternChars();
+				exclusionPatterns = ((ClasspathEntry)entry).fullExclusionPatternChars();
+			}
+			projectOutput = project.getOutputLocation();
+			binIsProject = projectPath.equals(projectOutput);
+		} catch (JavaModelException e) {
+			isClasspathResolved = false;
+		}
+
+		Object[] resources = new IResource[5];
+		int resourcesCounter = 0;
+		try {
+			IResource[] members = ((IContainer) project.getResource()).members();
+			int length = members.length;
+			if (length > 0) {
+				String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+				String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+				IClasspathEntry[] classpath = project.getResolvedClasspath();
+				for (int i = 0; i < length; i++) {
+					IResource res = members[i];
+					switch (res.getType()) {
+						case IResource.FILE :
+							IPath resFullPath = res.getFullPath();
+							String resName = res.getName();
+
+							// ignore a jar file on the classpath
+							if (isClasspathResolved && 
+									isClasspathEntryOrOutputLocation(resFullPath, res.getLocation()/* see https://bugs.eclipse.org/bugs/show_bug.cgi?id=244406 */, classpath, projectOutput)) {
+								break;
+							}
+							// ignore .java file if src == project
+							if (srcIsProject
+									&& Util.isValidCompilationUnitName(resName, sourceLevel, complianceLevel)
+									&& !Util.isExcluded(res, inclusionPatterns, exclusionPatterns)) {
+								break;
+							}
+							// ignore .class file if bin == project
+							if (binIsProject && Util.isValidClassFileName(resName, sourceLevel, complianceLevel)) {
+								break;
+							}
+							// else add non java resource
+							if (resources.length == resourcesCounter) {
+								// resize
+								System.arraycopy(
+										resources,
+										0,
+										(resources = new IResource[resourcesCounter * 2]),
+										0,
+										resourcesCounter);
+							}
+							resources[resourcesCounter++] = res;
+							break;
+						case IResource.FOLDER :
+							resFullPath = res.getFullPath();
+
+							// ignore non-excluded folders on the classpath or that correspond to an output location
+							if ((srcIsProject && !Util.isExcluded(res, inclusionPatterns, exclusionPatterns) && Util.isValidFolderNameForPackage(res.getName(), sourceLevel, complianceLevel))
+									|| (isClasspathResolved && isClasspathEntryOrOutputLocation(resFullPath, res.getLocation(), classpath, projectOutput))) {
+								break;
+							}
+							// else add non java resource
+							if (resources.length == resourcesCounter) {
+								// resize
+								System.arraycopy(
+										resources,
+										0,
+										(resources = new IResource[resourcesCounter * 2]),
+										0,
+										resourcesCounter);
+							}
+							resources[resourcesCounter++] = res;
+					}
+				}
+			}
+			if (resources.length != resourcesCounter) {
+				System.arraycopy(
+					resources,
+					0,
+					(resources = new IResource[resourcesCounter]),
+					0,
+					resourcesCounter);
+			}
+		} catch (CoreException e) {
+			resources = NO_NON_JAVA_RESOURCES;
+			resourcesCounter = 0;
+		}
+		return resources;
+	}
+
+	ProjectCache getProjectCache(JavaProject project) {
+		ProjectCache cache = this.projectCache;
+		if (cache == null) {
+			IPackageFragmentRoot[] roots;
+			Map reverseMap = new HashMap(3);
+			try {
+				roots = project.getAllPackageFragmentRoots(reverseMap);
+			} catch (JavaModelException e) {
+				// project does not exist: cannot happen since this is the info of the project
+				roots = new IPackageFragmentRoot[0];
+				reverseMap.clear();
+			}
+
+			HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
+			HashMap pkgFragmentsCaches = new HashMap();
+			int length = roots.length;
+			JavaModelManager  manager = JavaModelManager.getJavaModelManager();
+			for (int i = 0; i < length; i++) {
+				IPackageFragmentRoot root = roots[i];
+				DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
+				if (rootInfo == null || rootInfo.project.equals(project)) {
+					// ensure that an identical root is used (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=217059 )
+					roots[i] = root = (IPackageFragmentRoot) manager.getExistingElement(root);
+					// compute fragment cache
+					HashSetOfArray fragmentsCache = new HashSetOfArray();
+					initializePackageNames(root, fragmentsCache);
+					pkgFragmentsCaches.put(root, fragmentsCache);
+				}
+			}
+
+			cache = new ProjectCache(roots, reverseMap, pkgFragmentsCaches);
+			this.projectCache = cache;
+		}
+		return cache;
+	}
+
+	/**
+	 * Returns an array of non-java resources contained in the receiver.
+	 */
+	Object[] getNonJavaResources(JavaProject project) {
+
+		if (this.nonJavaResources == null) {
+			this.nonJavaResources = computeNonJavaResources(project);
+		}
+		return this.nonJavaResources;
+	}
+
+	private void initializePackageNames(IPackageFragmentRoot root, HashSetOfArray fragmentsCache) {
+		IJavaElement[] frags = null;
+		try {
+			if (!root.isOpen()) {
+				PackageFragmentRootInfo info = root.isArchive() ? new JarPackageFragmentRootInfo() : new PackageFragmentRootInfo();
+				((PackageFragmentRoot) root).computeChildren(info, ((JavaElement) root).resource());
+				frags = info.children;
+			} else
+				frags = root.getChildren();
+		} catch (JavaModelException e) {
+			// root doesn't exist: ignore
+			return;
+		}
+		for (int j = 0, length = frags.length; j < length; j++) {
+			fragmentsCache.add(((PackageFragment) frags[j]).names);
+		}
+	}
+
+	/*
+	 * Returns whether the given path is a classpath entry or an output location.
+	 */
+	private boolean isClasspathEntryOrOutputLocation(IPath path, IPath location, IClasspathEntry[] resolvedClasspath, IPath projectOutput) {
+		if (projectOutput.equals(path)) return true;
+		for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
+			IClasspathEntry entry = resolvedClasspath[i];
+			IPath entryPath;
+			if ((entryPath = entry.getPath()).equals(path) || entryPath.equals(location)) {
+				return true;
+			}
+			IPath output;
+			if ((output = entry.getOutputLocation()) != null && output.equals(path)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * Creates a new name lookup for this project info.
+	 * The given project is assumed to be the handle of this info.
+	 * This name lookup first looks in the given working copies.
+	 */
+	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
+		ProjectCache cache = getProjectCache(project);
+		HashtableOfArrayToObject allPkgFragmentsCache = cache.allPkgFragmentsCache;
+		if (allPkgFragmentsCache == null) {
+			HashMap rootInfos = JavaModelManager.getJavaModelManager().deltaState.roots;
+			IPackageFragmentRoot[] allRoots = cache.allPkgFragmentRootsCache;
+			int length = allRoots.length;
+			allPkgFragmentsCache = new HashtableOfArrayToObject();
+			for (int i = 0; i < length; i++) {
+				IPackageFragmentRoot root = allRoots[i];
+				DeltaProcessor.RootInfo rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(root.getPath());
+				JavaProject rootProject = rootInfo == null ? project : rootInfo.project;
+				HashSetOfArray fragmentsCache;
+				if (rootProject.equals(project)) {
+					// retrieve package fragments cache from this project
+					fragmentsCache = (HashSetOfArray) cache.pkgFragmentsCaches.get(root);
+				} else {
+					// retrieve package fragments  cache from the root's project
+					ProjectCache rootProjectCache;
+					try {
+						rootProjectCache = rootProject.getProjectCache();
+					} catch (JavaModelException e) {
+						// project doesn't exit
+						continue;
+					}
+					fragmentsCache = (HashSetOfArray) rootProjectCache.pkgFragmentsCaches.get(root);
+				}
+				if (fragmentsCache == null) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=183833
+					fragmentsCache = new HashSetOfArray();
+					initializePackageNames(root, fragmentsCache);
+				}
+				Object[][] set = fragmentsCache.set;
+				for (int j = 0, length2 = set.length; j < length2; j++) {
+					String[] pkgName = (String[]) set[j];
+					if (pkgName == null)
+						continue;
+					Object existing = allPkgFragmentsCache.get(pkgName);
+					if (existing == null || existing == NO_ROOTS) {
+						allPkgFragmentsCache.put(pkgName, root);
+						// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
+						// are also in the map
+						addSuperPackageNames(pkgName, allPkgFragmentsCache);
+					} else {
+						if (existing instanceof PackageFragmentRoot) {
+							allPkgFragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
+						} else {
+							IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
+							int rootLength = roots.length;
+							System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
+							roots[rootLength] = root;
+							allPkgFragmentsCache.put(pkgName, roots);
+						}
+					}
+				}
+			}
+			cache.allPkgFragmentsCache = allPkgFragmentsCache;
+		}
+		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries);
+	}
+
+	/*
+	 * Reset the package fragment roots and package fragment caches
+	 */
+	void resetCaches() {
+		this.projectCache = null;
+	}
+
+	/**
+	 * Set the fNonJavaResources to res value
+	 */
+	void setNonJavaResources(Object[] resources) {
+
+		this.nonJavaResources = resources;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocConstants.java
new file mode 100644
index 0000000..6c1eb77
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocConstants.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+public interface JavadocConstants {
+
+	String ANCHOR_PREFIX_END = "\""; //$NON-NLS-1$
+	char[] ANCHOR_PREFIX_START = "<A NAME=\"".toCharArray(); //$NON-NLS-1$
+	int ANCHOR_PREFIX_START_LENGHT = ANCHOR_PREFIX_START.length;
+	char[] ANCHOR_SUFFIX = "</A>".toCharArray(); //$NON-NLS-1$
+	int ANCHOR_SUFFIX_LENGTH = JavadocConstants.ANCHOR_SUFFIX.length;
+	char[] CONSTRUCTOR_DETAIL = "<!-- ========= CONSTRUCTOR DETAIL ======== -->".toCharArray(); //$NON-NLS-1$
+	char[] CONSTRUCTOR_SUMMARY = "<!-- ======== CONSTRUCTOR SUMMARY ======== -->".toCharArray(); //$NON-NLS-1$
+	char[] FIELD_DETAIL= "<!-- ============ FIELD DETAIL =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] FIELD_SUMMARY = "<!-- =========== FIELD SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] ENUM_CONSTANT_SUMMARY = "<!-- =========== ENUM CONSTANT SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY = "<!-- =========== ANNOTATION TYPE REQUIRED MEMBER SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION_TYPE_OPTIONAL_MEMBER_SUMMARY = "<!-- =========== ANNOTATION TYPE OPTIONAL MEMBER SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] END_OF_CLASS_DATA = "<!-- ========= END OF CLASS DATA ========= -->".toCharArray(); //$NON-NLS-1$
+	String HTML_EXTENSION = ".html"; //$NON-NLS-1$
+	String INDEX_FILE_NAME = "index.html"; //$NON-NLS-1$
+	char[] METHOD_DETAIL = "<!-- ============ METHOD DETAIL ========== -->".toCharArray(); //$NON-NLS-1$
+	char[] METHOD_SUMMARY = "<!-- ========== METHOD SUMMARY =========== -->".toCharArray(); //$NON-NLS-1$
+	char[] NESTED_CLASS_SUMMARY = "<!-- ======== NESTED CLASS SUMMARY ======== -->".toCharArray(); //$NON-NLS-1$
+	String PACKAGE_FILE_NAME = "package-summary.html"; //$NON-NLS-1$
+	char[] PACKAGE_DESCRIPTION_START = "name=\"package_description\"".toCharArray(); //$NON-NLS-1$
+	char[] H2_PREFIX = "<H2".toCharArray(); //$NON-NLS-1$
+	char[] H2_SUFFIX = "</H2>".toCharArray(); //$NON-NLS-1$
+	int H2_SUFFIX_LENGTH = H2_SUFFIX.length;
+	char[] BOTTOM_NAVBAR = "<!-- ======= START OF BOTTOM NAVBAR ====== -->".toCharArray(); //$NON-NLS-1$
+	char[] SEPARATOR_START = "<!-- =".toCharArray(); //$NON-NLS-1$
+	char[] START_OF_CLASS_DATA = "<!-- ======== START OF CLASS DATA ======== -->".toCharArray(); //$NON-NLS-1$
+	int START_OF_CLASS_DATA_LENGTH = JavadocConstants.START_OF_CLASS_DATA.length;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java
new file mode 100644
index 0000000..b0df379
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavadocContents.java
@@ -0,0 +1,493 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToIntArray;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class JavadocContents {
+	private static final int[] UNKNOWN_FORMAT = new int[0]; 
+	
+	private BinaryType type;
+	private char[] content;
+	
+	private int childrenStart;
+	
+	private boolean hasComputedChildrenSections = false;
+	private int indexOfFieldDetails;
+	private int indexOfConstructorDetails;
+	private int indexOfMethodDetails;
+	private int indexOfEndOfClassData;
+	
+	private int indexOfFieldsBottom;
+	private int indexOfAllMethodsTop;
+	private int indexOfAllMethodsBottom;
+	
+	private int[] typeDocRange;
+	private HashtableOfObjectToIntArray fieldDocRanges;
+	private HashtableOfObjectToIntArray methodDocRanges;
+	
+	private int[] fieldAnchorIndexes;
+	private int fieldAnchorIndexesCount;
+	private int fieldLastAnchorFoundIndex;
+	private int[] methodAnchorIndexes;
+	private int methodAnchorIndexesCount;
+	private int methodLastAnchorFoundIndex;
+	private int[] unknownFormatAnchorIndexes;
+	private int unknownFormatAnchorIndexesCount;
+	private int unknownFormatLastAnchorFoundIndex;
+	private int[] tempAnchorIndexes;
+	private int tempAnchorIndexesCount;
+	private int tempLastAnchorFoundIndex;
+	
+	public JavadocContents(BinaryType type, String content) {
+		this(content);
+		this.type = type;
+	}
+	
+	public JavadocContents(String content) {
+		this.content = content != null ? content.toCharArray() : null;
+	}
+	/*
+	 * Returns the part of the javadoc that describe the type
+	 */
+	public String getTypeDoc() throws JavaModelException {
+		if (this.content == null) return null;
+		
+		synchronized (this) {
+			if (this.typeDocRange == null) {
+				computeTypeRange();
+			}
+		}
+		
+		if (this.typeDocRange != null) {
+			if (this.typeDocRange == UNKNOWN_FORMAT) throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, this.type));
+			return String.valueOf(CharOperation.subarray(this.content, this.typeDocRange[0], this.typeDocRange[1]));
+		}
+		return null;
+	}
+	
+	public String getPackageDoc() throws JavaModelException {
+		if (this.content == null) return null;
+		int[] range = null;
+		int index = CharOperation.indexOf(JavadocConstants.PACKAGE_DESCRIPTION_START, this.content, false, 0);
+		if (index == -1) return null;
+		index = CharOperation.indexOf(JavadocConstants.ANCHOR_SUFFIX, this.content, false, index);
+		if (index == -1) return null;
+		
+		int start = CharOperation.indexOf(JavadocConstants.H2_PREFIX, this.content, false, index);
+		if (start != -1) {
+			start = CharOperation.indexOf(JavadocConstants.H2_SUFFIX, this.content, false, start);
+			if (start != -1) index = start + JavadocConstants.H2_SUFFIX_LENGTH;
+		}
+		if (index != -1) {
+			int end = CharOperation.indexOf(JavadocConstants.BOTTOM_NAVBAR, this.content, false, index);
+			if (end == -1) end = this.content.length -1;
+			range = new int[]{index, end};
+			return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
+		}
+		return null;
+	}
+	
+	/*
+	 * Returns the part of the javadoc that describe a field of the type
+	 */
+	public String getFieldDoc(IField child) throws JavaModelException {
+		if (this.content == null) return null;
+		
+		int[] range = null;
+		synchronized (this) {
+			if (this.fieldDocRanges == null) {
+				this.fieldDocRanges = new HashtableOfObjectToIntArray();
+			} else {
+				range = this.fieldDocRanges.get(child);
+			}
+			
+			if (range == null) {
+				range = computeFieldRange(child);
+				this.fieldDocRanges.put(child, range);
+			}
+		}
+		
+		if (range != null) {
+			if (range == UNKNOWN_FORMAT) throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, child));
+			return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
+		}
+		return null;
+	}
+	
+	/*
+	 * Returns the part of the javadoc that describe a method of the type
+	 */
+	public String getMethodDoc(IMethod child) throws JavaModelException {
+		if (this.content == null) return null;
+		
+		int[] range = null;
+		synchronized (this) {
+			if (this.methodDocRanges == null) {
+				this.methodDocRanges = new HashtableOfObjectToIntArray();
+			} else {
+				range = this.methodDocRanges.get(child);
+			}
+			
+			if (range == null) {
+				range = computeMethodRange(child);
+				this.methodDocRanges.put(child, range);
+			}
+		}
+		
+		if (range != null) {
+			if (range == UNKNOWN_FORMAT) {
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, child));
+			}
+			return String.valueOf(CharOperation.subarray(this.content, range[0], range[1]));
+		}
+		return null;
+	}
+	
+	/*
+	 * Compute the ranges of the parts of the javadoc that describe each method of the type
+	 */
+	private int[] computeChildRange(char[] anchor, int indexOfSectionBottom) throws JavaModelException {
+		
+		// checks each known anchor locations
+		if (this.tempAnchorIndexesCount > 0) {
+			for (int i = 0; i < this.tempAnchorIndexesCount; i++) {
+				int anchorEndStart = this.tempAnchorIndexes[i];
+				
+				if (anchorEndStart != -1 && CharOperation.prefixEquals(anchor, this.content, false, anchorEndStart)) {
+					
+					this.tempAnchorIndexes[i] = -1;
+					
+					return computeChildRange(anchorEndStart, anchor, indexOfSectionBottom);
+				}
+			}
+		}
+		
+		int fromIndex = this.tempLastAnchorFoundIndex;
+		int index;
+		
+		// check each next unknown anchor locations
+		while ((index = CharOperation.indexOf(JavadocConstants.ANCHOR_PREFIX_START, this.content, false, fromIndex)) != -1 && (index < indexOfSectionBottom || indexOfSectionBottom == -1)) {
+			fromIndex = index + 1;
+			
+			int anchorEndStart = index + JavadocConstants.ANCHOR_PREFIX_START_LENGHT;
+			
+			this.tempLastAnchorFoundIndex = anchorEndStart;
+			
+			if (CharOperation.prefixEquals(anchor, this.content, false, anchorEndStart)) {
+				return computeChildRange(anchorEndStart, anchor, indexOfSectionBottom);
+			} else {
+				if (this.tempAnchorIndexes.length == this.tempAnchorIndexesCount) {
+					System.arraycopy(this.tempAnchorIndexes, 0, this.tempAnchorIndexes = new int[this.tempAnchorIndexesCount + 20], 0, this.tempAnchorIndexesCount);
+				}
+				
+				this.tempAnchorIndexes[this.tempAnchorIndexesCount++] = anchorEndStart;
+			}
+		}
+		
+		return null;
+	}
+	
+	private int[] computeChildRange(int anchorEndStart, char[] anchor, int indexOfBottom) {
+		int[] range = null;
+				
+		// try to find the bottom of the section
+		if (indexOfBottom != -1) {
+			// try to find the end of the anchor
+			int indexOfEndLink = CharOperation.indexOf(JavadocConstants.ANCHOR_SUFFIX, this.content, false, anchorEndStart + anchor.length);
+			if (indexOfEndLink != -1) {
+				// try to find the next anchor
+				int indexOfNextElement = CharOperation.indexOf(JavadocConstants.ANCHOR_PREFIX_START, this.content, false, indexOfEndLink);
+				
+				int javadocStart = indexOfEndLink + JavadocConstants.ANCHOR_SUFFIX_LENGTH;
+				int javadocEnd = indexOfNextElement == -1 ? indexOfBottom : Math.min(indexOfNextElement, indexOfBottom);
+				range = new int[]{javadocStart, javadocEnd};
+			} else {
+				// the anchor has no suffix
+				range = UNKNOWN_FORMAT;
+			}
+		} else {
+			// the detail section has no bottom
+			range = UNKNOWN_FORMAT;
+		}
+		
+		return range;
+	}
+
+	private void computeChildrenSections() {
+		// try to find the next separator part
+		int lastIndex = CharOperation.indexOf(JavadocConstants.SEPARATOR_START, this.content, false, this.childrenStart);
+		lastIndex = lastIndex == -1 ? this.childrenStart : lastIndex;
+
+		// try to find field detail start
+		this.indexOfFieldDetails = CharOperation.indexOf(JavadocConstants.FIELD_DETAIL, this.content, false, lastIndex);
+		lastIndex = this.indexOfFieldDetails == -1 ? lastIndex : this.indexOfFieldDetails;
+		
+		// try to find constructor detail start
+		this.indexOfConstructorDetails = CharOperation.indexOf(JavadocConstants.CONSTRUCTOR_DETAIL, this.content, false, lastIndex);
+		lastIndex = this.indexOfConstructorDetails == -1 ? lastIndex : this.indexOfConstructorDetails;
+		
+		// try to find method detail start
+		this.indexOfMethodDetails = CharOperation.indexOf(JavadocConstants.METHOD_DETAIL, this.content, false, lastIndex);
+		lastIndex = this.indexOfMethodDetails == -1 ? lastIndex : this.indexOfMethodDetails;
+		
+		// we take the end of class data
+		this.indexOfEndOfClassData = CharOperation.indexOf(JavadocConstants.END_OF_CLASS_DATA, this.content, false, lastIndex);
+		
+		// try to find the field detail end
+		this.indexOfFieldsBottom =
+			this.indexOfConstructorDetails != -1 ? this.indexOfConstructorDetails :
+				this.indexOfMethodDetails != -1 ? this.indexOfMethodDetails:
+					this.indexOfEndOfClassData;
+		
+		this.indexOfAllMethodsTop =
+			this.indexOfConstructorDetails != -1 ?
+					this.indexOfConstructorDetails :
+						this.indexOfMethodDetails;
+		
+		this.indexOfAllMethodsBottom = this.indexOfEndOfClassData;
+	
+		this.hasComputedChildrenSections = true;
+	}
+
+	/*
+	 * Compute the ranges of the parts of the javadoc that describe each child of the type (fields, methods)
+	 */
+	private int[] computeFieldRange(IField field) throws JavaModelException {
+		if (!this.hasComputedChildrenSections) {
+			computeChildrenSections();
+		}
+		
+		StringBuffer buffer = new StringBuffer(field.getElementName());
+		buffer.append(JavadocConstants.ANCHOR_PREFIX_END);
+		char[] anchor = String.valueOf(buffer).toCharArray();
+		
+		int[] range = null;
+		
+		if (this.indexOfFieldDetails == -1 || this.indexOfFieldsBottom == -1) {
+			// the detail section has no top or bottom, so the doc has an unknown format
+			if (this.unknownFormatAnchorIndexes == null) {
+				this.unknownFormatAnchorIndexes = new int[this.type.getChildren().length];
+				this.unknownFormatAnchorIndexesCount = 0;
+				this.unknownFormatLastAnchorFoundIndex = this.childrenStart;
+			}
+			
+			this.tempAnchorIndexes = this.unknownFormatAnchorIndexes;
+			this.tempAnchorIndexesCount = this.unknownFormatAnchorIndexesCount;
+			this.tempLastAnchorFoundIndex = this.unknownFormatLastAnchorFoundIndex;
+			
+			range = computeChildRange(anchor, this.indexOfFieldsBottom);
+			
+			this.unknownFormatLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
+			this.unknownFormatAnchorIndexesCount = this.tempAnchorIndexesCount;
+			this.unknownFormatAnchorIndexes = this.tempAnchorIndexes;
+		} else {
+			if (this.fieldAnchorIndexes == null) {
+				this.fieldAnchorIndexes = new int[this.type.getFields().length];
+				this.fieldAnchorIndexesCount = 0;
+				this.fieldLastAnchorFoundIndex = this.indexOfFieldDetails;
+			}
+			
+			this.tempAnchorIndexes = this.fieldAnchorIndexes;
+			this.tempAnchorIndexesCount = this.fieldAnchorIndexesCount;
+			this.tempLastAnchorFoundIndex = this.fieldLastAnchorFoundIndex;
+			
+			range = computeChildRange(anchor, this.indexOfFieldsBottom);
+			
+			this.fieldLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
+			this.fieldAnchorIndexesCount = this.tempAnchorIndexesCount;
+			this.fieldAnchorIndexes = this.tempAnchorIndexes;
+		}
+		
+		return range;
+	}
+	
+	/*
+	 * Compute the ranges of the parts of the javadoc that describe each method of the type
+	 */
+	private int[] computeMethodRange(IMethod method) throws JavaModelException {
+		if (!this.hasComputedChildrenSections) {
+			computeChildrenSections();
+		}
+		
+		char[] anchor = computeMethodAnchorPrefixEnd((BinaryMethod)method).toCharArray();
+		
+		int[] range = null;
+		
+		if (this.indexOfAllMethodsTop == -1 || this.indexOfAllMethodsBottom == -1) {
+			// the detail section has no top or bottom, so the doc has an unknown format
+			if (this.unknownFormatAnchorIndexes == null) {
+				this.unknownFormatAnchorIndexes = new int[this.type.getChildren().length];
+				this.unknownFormatAnchorIndexesCount = 0;
+				this.unknownFormatLastAnchorFoundIndex = this.childrenStart;
+			}
+			
+			this.tempAnchorIndexes = this.unknownFormatAnchorIndexes;
+			this.tempAnchorIndexesCount = this.unknownFormatAnchorIndexesCount;
+			this.tempLastAnchorFoundIndex = this.unknownFormatLastAnchorFoundIndex;
+			
+			range = computeChildRange(anchor, this.indexOfFieldsBottom);
+			
+			this.unknownFormatLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
+			this.unknownFormatAnchorIndexesCount = this.tempAnchorIndexesCount;
+			this.unknownFormatAnchorIndexes = this.tempAnchorIndexes;
+		} else {			
+			if (this.methodAnchorIndexes == null) {
+				this.methodAnchorIndexes = new int[this.type.getFields().length];
+				this.methodAnchorIndexesCount = 0;
+				this.methodLastAnchorFoundIndex = this.indexOfAllMethodsTop;
+			}
+			
+			this.tempAnchorIndexes = this.methodAnchorIndexes;
+			this.tempAnchorIndexesCount = this.methodAnchorIndexesCount;
+			this.tempLastAnchorFoundIndex = this.methodLastAnchorFoundIndex;
+			
+			range = computeChildRange(anchor, this.indexOfAllMethodsBottom);
+			
+			this.methodLastAnchorFoundIndex = this.tempLastAnchorFoundIndex;
+			this.methodAnchorIndexesCount = this.tempAnchorIndexesCount;
+			this.methodAnchorIndexes = this.tempAnchorIndexes;
+		}
+		
+		return range;
+	}
+	
+	private String computeMethodAnchorPrefixEnd(BinaryMethod method) throws JavaModelException {
+		String typeQualifiedName = null;
+		if (this.type.isMember()) {
+			IType currentType = this.type;
+			StringBuffer buffer = new StringBuffer();
+			while (currentType != null) {
+				buffer.insert(0, currentType.getElementName());
+				currentType = currentType.getDeclaringType();
+				if (currentType != null) {
+					buffer.insert(0, '.');
+				}
+			}
+			typeQualifiedName = new String(buffer.toString());
+		} else {
+			typeQualifiedName = this.type.getElementName();
+		}
+		
+		String methodName = method.getElementName();
+		if (method.isConstructor()) {
+			methodName = typeQualifiedName;
+		}
+		IBinaryMethod info = (IBinaryMethod) method.getElementInfo();
+
+		char[] genericSignature = info.getGenericSignature();
+		String anchor = null;
+		if (genericSignature != null) {
+			genericSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.');
+			anchor = Util.toAnchor(0, genericSignature, methodName, Flags.isVarargs(method.getFlags()));
+			if (anchor == null) throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, method));
+		} else {
+			anchor = Signature.toString(method.getSignature().replace('/', '.'), methodName, null, true, false, Flags.isVarargs(method.getFlags()));
+		}
+		IType declaringType = this.type;
+		if (declaringType.isMember()) {
+			// might need to remove a part of the signature corresponding to the synthetic argument (only for constructor)
+			if (method.isConstructor() && !Flags.isStatic(declaringType.getFlags())) {
+				int indexOfOpeningParen = anchor.indexOf('(');
+				if (indexOfOpeningParen == -1) {
+					// should not happen as this is a method signature
+					return null;
+				}
+				int index = indexOfOpeningParen;
+				indexOfOpeningParen++;
+				int indexOfComma = anchor.indexOf(',', index);
+				if (indexOfComma != -1) {
+					index = indexOfComma + 2;
+				} else {
+					// no argument, but a synthetic argument
+					index = anchor.indexOf(')', index);
+				}
+				anchor = anchor.substring(0, indexOfOpeningParen) + anchor.substring(index);
+			}
+		}
+		return anchor + JavadocConstants.ANCHOR_PREFIX_END;
+	}
+	
+	/*
+	 * Compute the range of the part of the javadoc that describe the type
+	 */
+	private void computeTypeRange() throws JavaModelException {
+		final int indexOfStartOfClassData = CharOperation.indexOf(JavadocConstants.START_OF_CLASS_DATA, this.content, false);
+		if (indexOfStartOfClassData == -1) {
+			this.typeDocRange = UNKNOWN_FORMAT;
+			return;
+		}
+		int indexOfNextSeparator = CharOperation.indexOf(JavadocConstants.SEPARATOR_START, this.content, false, indexOfStartOfClassData);
+		if (indexOfNextSeparator == -1) {
+			this.typeDocRange = UNKNOWN_FORMAT;
+			return;
+		}
+		int indexOfNextSummary = CharOperation.indexOf(JavadocConstants.NESTED_CLASS_SUMMARY, this.content, false, indexOfNextSeparator);
+		if (indexOfNextSummary == -1 && this.type.isEnum()) {
+			// try to find enum constant summary start
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ENUM_CONSTANT_SUMMARY, this.content, false, indexOfNextSeparator);
+		}
+		if (indexOfNextSummary == -1 && this.type.isAnnotation()) {
+			// try to find required enum constant summary start
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ANNOTATION_TYPE_REQUIRED_MEMBER_SUMMARY, this.content, false, indexOfNextSeparator);
+			if (indexOfNextSummary == -1) {
+				// try to find optional enum constant summary start
+				indexOfNextSummary = CharOperation.indexOf(JavadocConstants.ANNOTATION_TYPE_OPTIONAL_MEMBER_SUMMARY, this.content, false, indexOfNextSeparator);
+			}
+		}
+		if (indexOfNextSummary == -1) {
+			// try to find field summary start
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.FIELD_SUMMARY, this.content, false, indexOfNextSeparator);
+		}
+		if (indexOfNextSummary == -1) {
+			// try to find constructor summary start
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.CONSTRUCTOR_SUMMARY, this.content, false, indexOfNextSeparator);
+		}
+		if (indexOfNextSummary == -1) {
+			// try to find method summary start
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.METHOD_SUMMARY, this.content, false, indexOfNextSeparator);
+		}
+		
+		if (indexOfNextSummary == -1) {
+			// we take the end of class data
+			indexOfNextSummary = CharOperation.indexOf(JavadocConstants.END_OF_CLASS_DATA, this.content, false, indexOfNextSeparator);
+		} else {
+			// improve performance of computation of children ranges
+			this.childrenStart = indexOfNextSummary + 1;
+		}
+		
+		if (indexOfNextSummary == -1) {
+			this.typeDocRange = UNKNOWN_FORMAT;
+			return;
+		}
+		/*
+		 * Check out to cut off the hierarchy see 119844
+		 * We remove what the contents between the start of class data and the first <P>
+		 */
+		int start = indexOfStartOfClassData + JavadocConstants.START_OF_CLASS_DATA_LENGTH;
+		int indexOfFirstParagraph = CharOperation.indexOf("<P>".toCharArray(), this.content, false, start); //$NON-NLS-1$
+		if (indexOfFirstParagraph != -1 && indexOfFirstParagraph < indexOfNextSummary) {
+			start = indexOfFirstParagraph;
+		}
+		
+		this.typeDocRange = new int[]{start, indexOfNextSummary};
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java
new file mode 100644
index 0000000..d8807a1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Enumeration;
+
+/**
+ *	The <code>LRUCacheEnumerator</code> returns its elements in
+ *	the order they are found in the <code>LRUCache</code>, with the
+ *	most recent elements first.
+ *
+ *	Once the enumerator is created, elements which are later added
+ *	to the cache are not returned by the enumerator.  However,
+ *	elements returned from the enumerator could have been closed
+ *	by the cache.
+ */
+public class LRUCacheEnumerator implements Enumeration {
+	/**
+	 *	Current element;
+	 */
+	protected LRUEnumeratorElement elementQueue;
+
+	public static class LRUEnumeratorElement {
+		/**
+		 *	Value returned by <code>nextElement()</code>;
+		 */
+		public Object value;
+
+		/**
+		 *	Next element
+		 */
+		public LRUEnumeratorElement next;
+
+		/**
+		 * Constructor
+		 */
+		public LRUEnumeratorElement(Object value) {
+			this.value = value;
+		}
+	}
+/**
+ *	Creates a CacheEnumerator on the list of <code>LRUEnumeratorElements</code>.
+ */
+public LRUCacheEnumerator(LRUEnumeratorElement firstElement) {
+	this.elementQueue = firstElement;
+}
+/**
+ * Returns true if more elements exist.
+ */
+public boolean hasMoreElements() {
+	return this.elementQueue != null;
+}
+/**
+ * Returns the next element.
+ */
+public Object nextElement() {
+	Object temp = this.elementQueue.value;
+	this.elementQueue = this.elementQueue.next;
+	return temp;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
new file mode 100644
index 0000000..cc8bb58
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
@@ -0,0 +1,441 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.Literal;
+import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
+import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
+import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Util;
+
+
+public class LocalVariable extends SourceRefElement implements ILocalVariable {
+
+	public static final ILocalVariable[] NO_LOCAL_VARIABLES = new ILocalVariable[0];
+	
+	String name;
+	public int declarationSourceStart, declarationSourceEnd;
+	public int nameStart, nameEnd;
+	String typeSignature;
+	public IAnnotation[] annotations;
+	private int flags;
+	private boolean isParameter;
+
+	public LocalVariable(
+			JavaElement parent,
+			String name,
+			int declarationSourceStart,
+			int declarationSourceEnd,
+			int nameStart,
+			int nameEnd,
+			String typeSignature,
+			org.eclipse.jdt.internal.compiler.ast.Annotation[] astAnnotations,
+			int flags,
+			boolean isParameter) {
+
+		super(parent);
+		this.name = name;
+		this.declarationSourceStart = declarationSourceStart;
+		this.declarationSourceEnd = declarationSourceEnd;
+		this.nameStart = nameStart;
+		this.nameEnd = nameEnd;
+		this.typeSignature = typeSignature;
+		this.annotations = getAnnotations(astAnnotations);
+		this.flags = flags;
+		this.isParameter = isParameter;
+	}
+
+	protected void closing(Object info) {
+		// a local variable has no info
+	}
+
+	protected Object createElementInfo() {
+		// a local variable has no info
+		return null;
+	}
+
+	public boolean equals(Object o) {
+		if (!(o instanceof LocalVariable)) return false;
+		LocalVariable other = (LocalVariable)o;
+		return
+			this.declarationSourceStart == other.declarationSourceStart
+			&& this.declarationSourceEnd == other.declarationSourceEnd
+			&& this.nameStart == other.nameStart
+			&& this.nameEnd == other.nameEnd
+			&& super.equals(o);
+	}
+
+	public boolean exists() {
+		return this.parent.exists(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=46192
+	}
+
+	protected void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) {
+		// a local variable has no info
+	}
+
+	public IAnnotation getAnnotation(String annotationName) {
+		for (int i = 0, length = this.annotations.length; i < length; i++) {
+			IAnnotation annotation = this.annotations[i];
+			if (annotation.getElementName().equals(annotationName))
+				return annotation;
+		}
+		return super.getAnnotation(annotationName);
+	}
+
+	public IAnnotation[] getAnnotations() throws JavaModelException {
+		return this.annotations;
+	}
+
+	private IAnnotation[] getAnnotations(org.eclipse.jdt.internal.compiler.ast.Annotation[] astAnnotations) {
+		int length;
+		if (astAnnotations == null || (length = astAnnotations.length) == 0)
+			return Annotation.NO_ANNOTATIONS;
+		IAnnotation[] result = new IAnnotation[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = getAnnotation(astAnnotations[i], this);
+		}
+		return result;
+	}
+
+	private IAnnotation getAnnotation(final org.eclipse.jdt.internal.compiler.ast.Annotation annotation, JavaElement parentElement) {
+		final int typeStart = annotation.type.sourceStart();
+		final int typeEnd = annotation.type.sourceEnd();
+		final int sourceStart = annotation.sourceStart();
+		final int sourceEnd = annotation.declarationSourceEnd;
+		class LocalVarAnnotation extends Annotation {
+			IMemberValuePair[] memberValuePairs;
+			public LocalVarAnnotation(JavaElement localVar, String elementName) {
+				super(localVar, elementName);
+			}
+			public IMemberValuePair[] getMemberValuePairs() throws JavaModelException {
+				return this.memberValuePairs;
+			}
+			public ISourceRange getNameRange() throws JavaModelException {
+				return new SourceRange(typeStart, typeEnd - typeStart + 1);
+			}
+			public ISourceRange getSourceRange() throws JavaModelException {
+				return new SourceRange(sourceStart, sourceEnd - sourceStart + 1);
+			}
+			public boolean exists() {
+				return this.parent.exists();
+			}
+		}
+		String annotationName = new String(CharOperation.concatWith(annotation.type.getTypeName(), '.'));
+		LocalVarAnnotation localVarAnnotation = new LocalVarAnnotation(parentElement, annotationName);
+		org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] astMemberValuePairs = annotation.memberValuePairs();
+		int length;
+		IMemberValuePair[] memberValuePairs;
+		if (astMemberValuePairs == null || (length = astMemberValuePairs.length) == 0) {
+			memberValuePairs = Annotation.NO_MEMBER_VALUE_PAIRS;
+		} else {
+			memberValuePairs = new IMemberValuePair[length];
+			for (int i = 0; i < length; i++) {
+				org.eclipse.jdt.internal.compiler.ast.MemberValuePair astMemberValuePair = astMemberValuePairs[i];
+				MemberValuePair memberValuePair = new MemberValuePair(new String(astMemberValuePair.name));
+				memberValuePair.value = getAnnotationMemberValue(memberValuePair, astMemberValuePair.value, localVarAnnotation);
+				memberValuePairs[i] = memberValuePair;
+			}
+		}
+		localVarAnnotation.memberValuePairs = memberValuePairs;
+		return localVarAnnotation;
+	}
+
+	/*
+	 * Creates the value wrapper from the given expression, and sets the valueKind on the given memberValuePair
+	 */
+	private Object getAnnotationMemberValue(MemberValuePair memberValuePair, Expression expression, JavaElement parentElement) {
+		if (expression instanceof NullLiteral) {
+			return null;
+		} else if (expression instanceof Literal) {
+			((Literal) expression).computeConstant();
+			return Util.getAnnotationMemberValue(memberValuePair, expression.constant);
+		} else if (expression instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) {
+			memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION;
+			return getAnnotation((org.eclipse.jdt.internal.compiler.ast.Annotation) expression, parentElement);
+		} else if (expression instanceof ClassLiteralAccess) {
+			ClassLiteralAccess classLiteral = (ClassLiteralAccess) expression;
+			char[] typeName = CharOperation.concatWith(classLiteral.type.getTypeName(), '.');
+			memberValuePair.valueKind = IMemberValuePair.K_CLASS;
+			return new String(typeName);
+		} else if (expression instanceof QualifiedNameReference) {
+			char[] qualifiedName = CharOperation.concatWith(((QualifiedNameReference) expression).tokens, '.');
+			memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME;
+			return new String(qualifiedName);
+		} else if (expression instanceof SingleNameReference) {
+			char[] simpleName = ((SingleNameReference) expression).token;
+			if (simpleName == RecoveryScanner.FAKE_IDENTIFIER) {
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+				return null;
+			}
+			memberValuePair.valueKind = IMemberValuePair.K_SIMPLE_NAME;
+			return new String(simpleName);
+		} else if (expression instanceof ArrayInitializer) {
+			memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...)
+			Expression[] expressions = ((ArrayInitializer) expression).expressions;
+			int length = expressions == null ? 0 : expressions.length;
+			Object[] values = new Object[length];
+			for (int i = 0; i < length; i++) {
+				int previousValueKind = memberValuePair.valueKind;
+				Object value = getAnnotationMemberValue(memberValuePair, expressions[i], parentElement);
+				if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) {
+					// values are heterogeneous, value kind is thus unknown
+					memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+				}
+				values[i] = value;
+			}
+			if (memberValuePair.valueKind == -1)
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return values;
+		} else if (expression instanceof UnaryExpression) {			//to deal with negative numerals (see bug - 248312)
+			UnaryExpression unaryExpression = (UnaryExpression) expression;
+			if ((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OperatorIds.MINUS) {
+				if (unaryExpression.expression instanceof Literal) {
+					Literal subExpression = (Literal) unaryExpression.expression;
+					subExpression.computeConstant();
+					return Util.getNegativeAnnotationMemberValue(memberValuePair, subExpression.constant);
+				}
+			}
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		} else {
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		}
+	}
+
+	public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+		switch (token.charAt(0)) {
+			case JEM_COUNT:
+				return getHandleUpdatingCountFromMemento(memento, owner);
+		}
+		return this;
+	}
+
+	/*
+	 * @see JavaElement#getHandleMemento(StringBuffer)
+	 */
+	protected void getHandleMemento(StringBuffer buff) {
+		((JavaElement)getParent()).getHandleMemento(buff);
+		buff.append(getHandleMementoDelimiter());
+		buff.append(this.name);
+		buff.append(JEM_COUNT);
+		buff.append(this.declarationSourceStart);
+		buff.append(JEM_COUNT);
+		buff.append(this.declarationSourceEnd);
+		buff.append(JEM_COUNT);
+		buff.append(this.nameStart);
+		buff.append(JEM_COUNT);
+		buff.append(this.nameEnd);
+		buff.append(JEM_COUNT);
+		escapeMementoName(buff, this.typeSignature);
+		buff.append(JEM_COUNT);
+		buff.append(this.flags);
+		buff.append(JEM_COUNT);
+		buff.append(this.isParameter);
+		if (this.occurrenceCount > 1) {
+			buff.append(JEM_COUNT);
+			buff.append(this.occurrenceCount);
+		}
+	}
+
+	protected char getHandleMementoDelimiter() {
+		return JavaElement.JEM_LOCALVARIABLE;
+	}
+
+	public IResource getCorrespondingResource() {
+		return null;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public IMember getDeclaringMember() {
+		return (IMember) this.parent;
+	}
+
+	public String getElementName() {
+		return this.name;
+	}
+
+	public int getElementType() {
+		return LOCAL_VARIABLE;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public int getFlags() {
+		if (this.flags == -1) {
+			SourceMapper mapper= getSourceMapper();
+			if (mapper != null) {
+				try {
+					// ensure the class file's buffer is open so that source ranges are computed
+					ClassFile classFile = (ClassFile)getClassFile();
+					if (classFile != null) {
+						classFile.getBuffer();
+						return mapper.getFlags(this);
+					}
+				} catch(JavaModelException e) {
+					// ignore
+				}
+			}
+			return 0;
+		}
+		return this.flags & ExtraCompilerModifiers.AccJustFlag;
+	}
+
+	/**
+	 * @see IMember#getClassFile()
+	 */
+	public IClassFile getClassFile() {
+		IJavaElement element = getParent();
+		while (element instanceof IMember) {
+			element= element.getParent();
+		}
+		if (element instanceof IClassFile) {
+			return (IClassFile) element;
+		}
+		return null;
+	}
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public ISourceRange getNameRange() {
+		if (this.nameEnd == -1) {
+			SourceMapper mapper= getSourceMapper();
+			if (mapper != null) {
+				try {
+					// ensure the class file's buffer is open so that source ranges are computed
+					ClassFile classFile = (ClassFile)getClassFile();
+					if (classFile != null) {
+						classFile.getBuffer();
+						return mapper.getNameRange(this);
+					}
+				} catch(JavaModelException e) {
+					// ignore
+				}
+			}
+			return SourceMapper.UNKNOWN_RANGE;
+		}
+		return new SourceRange(this.nameStart, this.nameEnd-this.nameStart+1);
+	}
+
+	public IPath getPath() {
+		return this.parent.getPath();
+	}
+
+	public IResource resource() {
+		return this.parent.resource();
+	}
+
+	/**
+	 * @see ISourceReference
+	 */
+	public String getSource() throws JavaModelException {
+		IOpenable openable = this.parent.getOpenableParent();
+		IBuffer buffer = openable.getBuffer();
+		if (buffer == null) {
+			return null;
+		}
+		ISourceRange range = getSourceRange();
+		int offset = range.getOffset();
+		int length = range.getLength();
+		if (offset == -1 || length == 0 ) {
+			return null;
+		}
+		try {
+			return buffer.getText(offset, length);
+		} catch(RuntimeException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public ISourceRange getSourceRange() throws JavaModelException {
+		if (this.declarationSourceEnd == -1) {
+			SourceMapper mapper= getSourceMapper();
+			if (mapper != null) {
+				// ensure the class file's buffer is open so that source ranges are computed
+				ClassFile classFile = (ClassFile)getClassFile();
+				if (classFile != null) {
+					classFile.getBuffer();
+					return mapper.getSourceRange(this);
+				}
+			}
+			return SourceMapper.UNKNOWN_RANGE;
+		}
+		return new SourceRange(this.declarationSourceStart, this.declarationSourceEnd-this.declarationSourceStart+1);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public ITypeRoot getTypeRoot() {
+		return this.getDeclaringMember().getTypeRoot();
+	}
+
+	public String getTypeSignature() {
+		return this.typeSignature;
+	}
+
+	public IResource getUnderlyingResource() throws JavaModelException {
+		return this.parent.getUnderlyingResource();
+	}
+
+	public int hashCode() {
+		return Util.combineHashCodes(this.parent.hashCode(), this.nameStart);
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public boolean isParameter() {
+		return this.isParameter;
+	}
+
+	public boolean isStructureKnown() throws JavaModelException {
+		return true;
+	}
+
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		buffer.append(tabString(tab));
+		if (info != NO_INFO) {
+			buffer.append(Signature.toString(getTypeSignature()));
+			buffer.append(" "); //$NON-NLS-1$
+		}
+		toStringName(buffer);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
new file mode 100644
index 0000000..d17bf1f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IScanner;
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+
+/**
+ * @see IMember
+ */
+
+public abstract class Member extends SourceRefElement implements IMember {
+
+protected Member(JavaElement parent) {
+	super(parent);
+}
+protected static boolean areSimilarMethods(
+	String name1, String[] params1,
+	String name2, String[] params2,
+	String[] simpleNames1) {
+
+	if (name1.equals(name2)) {
+		int params1Length = params1.length;
+		if (params1Length == params2.length) {
+			for (int i = 0; i < params1Length; i++) {
+				String simpleName1 =
+					simpleNames1 == null ?
+						Signature.getSimpleName(Signature.toString(Signature.getTypeErasure(params1[i]))) :
+						simpleNames1[i];
+				String simpleName2 = Signature.getSimpleName(Signature.toString(Signature.getTypeErasure(params2[i])));
+				if (!simpleName1.equals(simpleName2)) {
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+	return false;
+}
+/**
+ * Converts a field constant from the compiler's representation
+ * to the Java Model constant representation (Number or String).
+ */
+protected static Object convertConstant(Constant constant) {
+	if (constant == null)
+		return null;
+	if (constant == Constant.NotAConstant) {
+		return null;
+	}
+	switch (constant.typeID()) {
+		case TypeIds.T_boolean :
+			return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE;
+		case TypeIds.T_byte :
+			return new Byte(constant.byteValue());
+		case TypeIds.T_char :
+			return new Character(constant.charValue());
+		case TypeIds.T_double :
+			return new Double(constant.doubleValue());
+		case TypeIds.T_float :
+			return new Float(constant.floatValue());
+		case TypeIds.T_int :
+			return new Integer(constant.intValue());
+		case TypeIds.T_long :
+			return new Long(constant.longValue());
+		case TypeIds.T_short :
+			return new Short(constant.shortValue());
+		case TypeIds.T_JavaLangString :
+			return constant.stringValue();
+		default :
+			return null;
+	}
+}
+/*
+ * Helper method for SourceType.findMethods and BinaryType.findMethods
+ */
+public static IMethod[] findMethods(IMethod method, IMethod[] methods) {
+	String elementName = method.getElementName();
+	String[] parameters = method.getParameterTypes();
+	int paramLength = parameters.length;
+	String[] simpleNames = new String[paramLength];
+	for (int i = 0; i < paramLength; i++) {
+		String erasure = Signature.getTypeErasure(parameters[i]);
+		simpleNames[i] = Signature.getSimpleName(Signature.toString(erasure));
+	}
+	ArrayList list = new ArrayList();
+	for (int i = 0, length = methods.length; i < length; i++) {
+		IMethod existingMethod = methods[i];
+		if (areSimilarMethods(
+				elementName,
+				parameters,
+				existingMethod.getElementName(),
+				existingMethod.getParameterTypes(),
+				simpleNames)) {
+			list.add(existingMethod);
+		}
+	}
+	int size = list.size();
+	if (size == 0) {
+		return null;
+	} else {
+		IMethod[] result = new IMethod[size];
+		list.toArray(result);
+		return result;
+	}
+}
+public String[] getCategories() throws JavaModelException {
+	IType type = (IType) getAncestor(IJavaElement.TYPE);
+	if (type == null) return CharOperation.NO_STRINGS;
+	if (type.isBinary()) {
+		return CharOperation.NO_STRINGS;
+	} else {
+		SourceTypeElementInfo info = (SourceTypeElementInfo) ((SourceType) type).getElementInfo();
+		HashMap map = info.getCategories();
+		if (map == null) return CharOperation.NO_STRINGS;
+		String[] categories = (String[]) map.get(this);
+		if (categories == null) return CharOperation.NO_STRINGS;
+		return categories;
+	}
+}
+/**
+ * @see IMember
+ */
+public IClassFile getClassFile() {
+	IJavaElement element = getParent();
+	while (element instanceof IMember) {
+		element= element.getParent();
+	}
+	if (element instanceof IClassFile) {
+		return (IClassFile) element;
+	}
+	return null;
+}
+/**
+ * @see IMember
+ */
+public IType getDeclaringType() {
+	JavaElement parentElement = (JavaElement)getParent();
+	if (parentElement.getElementType() == TYPE) {
+		return (IType) parentElement;
+	}
+	return null;
+}
+/**
+ * @see IMember
+ */
+public int getFlags() throws JavaModelException {
+	MemberElementInfo info = (MemberElementInfo) getElementInfo();
+	return info.getModifiers();
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_COUNT:
+			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
+		case JEM_TYPE:
+			String typeName;
+			if (memento.hasMoreTokens()) {
+				typeName = memento.nextToken();
+				char firstChar = typeName.charAt(0);
+				if (firstChar == JEM_FIELD || firstChar == JEM_INITIALIZER || firstChar == JEM_METHOD || firstChar == JEM_TYPE || firstChar == JEM_COUNT) {
+					token = typeName;
+					typeName = ""; //$NON-NLS-1$
+				} else {
+					token = null;
+				}
+			} else {
+				typeName = ""; //$NON-NLS-1$
+				token = null;
+			}
+			JavaElement type = (JavaElement)getType(typeName, 1);
+			if (token == null) {
+				return type.getHandleFromMemento(memento, workingCopyOwner);
+			} else {
+				return type.getHandleFromMemento(token, memento, workingCopyOwner);
+			}
+		case JEM_LOCALVARIABLE:
+			if (!memento.hasMoreTokens()) return this;
+			String varName = memento.nextToken();
+			if (!memento.hasMoreTokens()) return this;
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			int declarationStart = Integer.parseInt(memento.nextToken());
+			if (!memento.hasMoreTokens()) return this;
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			int declarationEnd = Integer.parseInt(memento.nextToken());
+			if (!memento.hasMoreTokens()) return this;
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			int nameStart = Integer.parseInt(memento.nextToken());
+			if (!memento.hasMoreTokens()) return this;
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			int nameEnd = Integer.parseInt(memento.nextToken());
+			if (!memento.hasMoreTokens()) return this;
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			String typeSignature = memento.nextToken();
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			int flags = Integer.parseInt(memento.nextToken());
+			memento.nextToken(); // JEM_COUNT
+			if (!memento.hasMoreTokens()) return this;
+			boolean isParameter = Boolean.valueOf(memento.nextToken()).booleanValue();
+			return new LocalVariable(this, varName, declarationStart, declarationEnd, nameStart, nameEnd, typeSignature, null, flags, isParameter);
+		case JEM_TYPE_PARAMETER:
+			if (!memento.hasMoreTokens()) return this;
+			String typeParameterName = memento.nextToken();
+			JavaElement typeParameter = new TypeParameter(this, typeParameterName);
+			return typeParameter.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_ANNOTATION:
+			if (!memento.hasMoreTokens()) return this;
+			String annotationName = memento.nextToken();
+			JavaElement annotation = new Annotation(this, annotationName);
+			return annotation.getHandleFromMemento(memento, workingCopyOwner);
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_TYPE;
+}
+/*
+ * Returns the outermost context defining a local element. Per construction, it can only be a
+ * method/field/initializarer member; thus, returns null if this member is already a top-level type or member type.
+ * e.g for X.java/X/Y/foo()/Z/bar()/T, it will return X.java/X/Y/foo()
+ */
+public Member getOuterMostLocalContext() {
+	IJavaElement current = this;
+	Member lastLocalContext = null;
+	parentLoop: while (true) {
+		switch (current.getElementType()) {
+			case CLASS_FILE:
+			case COMPILATION_UNIT:
+				break parentLoop; // done recursing
+			case TYPE:
+				// cannot be a local context
+				break;
+			case INITIALIZER:
+			case FIELD:
+			case METHOD:
+				 // these elements can define local members
+				lastLocalContext = (Member) current;
+				break;
+		}
+		current = current.getParent();
+	}
+	return lastLocalContext;
+}
+public ISourceRange getJavadocRange() throws JavaModelException {
+	ISourceRange range= getSourceRange();
+	if (range == null) return null;
+	IBuffer buf= null;
+	if (isBinary()) {
+		buf = getClassFile().getBuffer();
+	} else {
+		ICompilationUnit compilationUnit = getCompilationUnit();
+		if (!compilationUnit.isConsistent()) {
+			return null;
+		}
+		buf = compilationUnit.getBuffer();
+	}
+	final int start= range.getOffset();
+	final int length= range.getLength();
+	if (length > 0 && buf.getChar(start) == '/') {
+		IScanner scanner= ToolFactory.createScanner(true, false, false, false);
+		try {
+			scanner.setSource(buf.getText(start, length).toCharArray());
+			int docOffset= -1;
+			int docEnd= -1;
+
+			int terminal= scanner.getNextToken();
+			loop: while (true) {
+				switch(terminal) {
+					case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
+						docOffset= scanner.getCurrentTokenStartPosition();
+						docEnd= scanner.getCurrentTokenEndPosition() + 1;
+						terminal= scanner.getNextToken();
+						break;
+					case ITerminalSymbols.TokenNameCOMMENT_LINE :
+					case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
+						terminal= scanner.getNextToken();
+						continue loop;
+					default :
+						break loop;
+				}
+			}
+			if (docOffset != -1) {
+				return new SourceRange(docOffset + start, docEnd - docOffset);
+			}
+		} catch (InvalidInputException ex) {
+			// try if there is inherited Javadoc
+		} catch (IndexOutOfBoundsException e) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305001
+		}
+	}
+	return null;
+}
+/**
+ * @see IMember
+ */
+public ISourceRange getNameRange() throws JavaModelException {
+	MemberElementInfo info= (MemberElementInfo)getElementInfo();
+	return new SourceRange(info.getNameSourceStart(), info.getNameSourceEnd() - info.getNameSourceStart() + 1);
+}
+/**
+ * @see IMember
+ */
+public IType getType(String typeName, int count) {
+	if (isBinary()) {
+		throw new IllegalArgumentException("Not a source member " + toStringWithAncestors()); //$NON-NLS-1$
+	} else {
+		SourceType type = new SourceType(this, typeName);
+		type.occurrenceCount = count;
+		return type;
+	}
+}
+/**
+ * @see IMember#getTypeRoot()
+ */
+public ITypeRoot getTypeRoot() {
+	IJavaElement element = getParent();
+	while (element instanceof IMember) {
+		element= element.getParent();
+	}
+	return (ITypeRoot) element;
+}
+/**
+ * @see IMember
+ */
+public boolean isBinary() {
+	return false;
+}
+protected boolean isMainMethod(IMethod method) throws JavaModelException {
+	if ("main".equals(method.getElementName()) && Signature.SIG_VOID.equals(method.getReturnType())) { //$NON-NLS-1$
+		int flags= method.getFlags();
+		if (Flags.isStatic(flags) && Flags.isPublic(flags)) {
+			String[] paramTypes= method.getParameterTypes();
+			if (paramTypes.length == 1) {
+				String typeSignature=  Signature.toString(paramTypes[0]);
+				return "String[]".equals(Signature.getSimpleName(typeSignature)); //$NON-NLS-1$
+			}
+		}
+	}
+	return false;
+}
+/**
+ * @see IJavaElement
+ */
+public boolean isReadOnly() {
+	return getClassFile() != null;
+}
+/**
+ */
+public String readableName() {
+
+	IJavaElement declaringType = getDeclaringType();
+	if (declaringType != null) {
+		String declaringName = ((JavaElement) getDeclaringType()).readableName();
+		StringBuffer buffer = new StringBuffer(declaringName);
+		buffer.append('.');
+		buffer.append(getElementName());
+		return buffer.toString();
+	} else {
+		return super.readableName();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java
new file mode 100644
index 0000000..09fc4cf
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ *Element info for IMember elements.
+ */
+/* package */ abstract class MemberElementInfo extends SourceRefElementInfo {
+	/**
+	 * The modifiers associated with this member.
+	 *
+	 * @see org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants
+	 */
+	protected int flags;
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceEnd()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceEnd()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceEnd()
+	 */
+	public int getNameSourceEnd() {
+		return -1;
+	}
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getNameSourceStart()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getNameSourceStart()
+	 * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getNameSourceStart()
+	 */
+	public int getNameSourceStart() {
+		return -1;
+	}
+	
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.IGenericType#getModifiers()
+	 * @see org.eclipse.jdt.internal.compiler.env.IGenericMethod#getModifiers()
+	 * @see org.eclipse.jdt.internal.compiler.env.IGenericField#getModifiers()
+	 */
+	public int getModifiers() {
+		return this.flags;
+	}
+	protected void setFlags(int flags) {
+		this.flags = flags;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberValuePair.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberValuePair.java
new file mode 100644
index 0000000..3e8fc20
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberValuePair.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class MemberValuePair implements IMemberValuePair {
+
+	String memberName;
+	public Object value;
+	public int valueKind = K_UNKNOWN;
+
+	public MemberValuePair(String memberName) {
+		this.memberName = memberName;
+	}
+
+	public MemberValuePair(String memberName, Object value, int valueKind) {
+		this(memberName);
+		this.value = value;
+		this.valueKind = valueKind;
+	}
+
+	public boolean equals(Object obj) {
+		if (!(obj instanceof MemberValuePair)) {
+			return false;
+		}
+		MemberValuePair other = (MemberValuePair) obj;
+		return
+			this.valueKind == other.valueKind
+			&& this.memberName.equals(other.memberName)
+			&& (this.value == other.value
+				|| (this.value != null && this.value.equals(other.value))
+				|| (this.value instanceof Object[] && other.value instanceof Object[] && Util.equalArraysOrNull((Object[])this.value, (Object[]) other.value)));
+	}
+
+	public String getMemberName() {
+		return this.memberName;
+	}
+
+	public Object getValue() {
+		return this.value;
+	}
+
+	public int getValueKind() {
+		return this.valueKind;
+	}
+
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((this.memberName == null) ? 0 : this.memberName.hashCode());
+		result = prime * result + ((this.value == null) ? 0 : this.value.hashCode());
+		result = prime * result + this.valueKind;
+		return result;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java
new file mode 100644
index 0000000..2996543
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.jdt.core.*;
+
+/**
+ * This class is used by <code>JavaModelManager</code> to update the JavaModel
+ * based on some <code>IJavaElementDelta</code>s.
+ */
+public class ModelUpdater {
+
+	HashSet projectsToUpdate = new HashSet();
+
+	/**
+	 * Adds the given child handle to its parent's cache of children.
+	 */
+	protected void addToParentInfo(Openable child) {
+
+		Openable parent = (Openable) child.getParent();
+		if (parent != null && parent.isOpen()) {
+			try {
+				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
+				info.addChild(child);
+			} catch (JavaModelException e) {
+				// do nothing - we already checked if open
+			}
+		}
+	}
+
+	/**
+	 * Closes the given element, which removes it from the cache of open elements.
+	 */
+	protected static void close(Openable element) {
+
+		try {
+			element.close();
+		} catch (JavaModelException e) {
+			// do nothing
+		}
+	}
+
+	/**
+	 * Processing for an element that has been added:<ul>
+	 * <li>If the element is a project, do nothing, and do not process
+	 * children, as when a project is created it does not yet have any
+	 * natures - specifically a java nature.
+	 * <li>If the elemet is not a project, process it as added (see
+	 * <code>basicElementAdded</code>.
+	 * </ul>
+	 */
+	protected void elementAdded(Openable element) {
+
+		int elementType = element.getElementType();
+		if (elementType == IJavaElement.JAVA_PROJECT) {
+			// project add is handled by JavaProject.configure() because
+			// when a project is created, it does not yet have a java nature
+			addToParentInfo(element);
+			this.projectsToUpdate.add(element);
+		} else {
+			addToParentInfo(element);
+
+			// Force the element to be closed as it might have been opened
+			// before the resource modification came in and it might have a new child
+			// For example, in an IWorkspaceRunnable:
+			// 1. create a package fragment p using a java model operation
+			// 2. open package p
+			// 3. add file X.java in folder p
+			// When the resource delta comes in, only the addition of p is notified,
+			// but the package p is already opened, thus its children are not recomputed
+			// and it appears empty.
+			close(element);
+		}
+
+		switch (elementType) {
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+				// when a root is added, and is on the classpath, the project must be updated
+				this.projectsToUpdate.add(element.getJavaProject());
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT :
+				// get rid of package fragment cache
+				JavaProject project = (JavaProject) element.getJavaProject();
+				project.resetCaches();
+				break;
+		}
+	}
+
+	/**
+	 * Generic processing for elements with changed contents:<ul>
+	 * <li>The element is closed such that any subsequent accesses will re-open
+	 * the element reflecting its new structure.
+	 * </ul>
+	 */
+	protected void elementChanged(Openable element) {
+
+		close(element);
+	}
+
+	/**
+	 * Generic processing for a removed element:<ul>
+	 * <li>Close the element, removing its structure from the cache
+	 * <li>Remove the element from its parent's cache of children
+	 * <li>Add a REMOVED entry in the delta
+	 * </ul>
+	 */
+	protected void elementRemoved(Openable element) {
+
+		if (element.isOpen()) {
+			close(element);
+		}
+		removeFromParentInfo(element);
+		int elementType = element.getElementType();
+
+		switch (elementType) {
+			case IJavaElement.JAVA_MODEL :
+				JavaModelManager.getIndexManager().reset();
+				break;
+			case IJavaElement.JAVA_PROJECT :
+				JavaModelManager manager = JavaModelManager.getJavaModelManager();
+				JavaProject javaProject = (JavaProject) element;
+				manager.removePerProjectInfo(javaProject, true /* remove external jar files indexes and timestamps*/);
+				manager.containerRemove(javaProject);
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+				this.projectsToUpdate.add(element.getJavaProject());
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT :
+				// get rid of package fragment cache
+				JavaProject project = (JavaProject) element.getJavaProject();
+				project.resetCaches();
+				break;
+		}
+	}
+
+	/**
+	 * Converts a <code>IResourceDelta</code> rooted in a <code>Workspace</code> into
+	 * the corresponding set of <code>IJavaElementDelta</code>, rooted in the
+	 * relevant <code>JavaModel</code>s.
+	 */
+	public void processJavaDelta(IJavaElementDelta delta) {
+		try {
+			traverseDelta(delta, null, null); // traverse delta
+
+			// reset project caches of projects that were affected
+			Iterator iterator = this.projectsToUpdate.iterator();
+			while (iterator.hasNext()) {
+				JavaProject project = (JavaProject) iterator.next();
+				project.resetCaches();
+			}
+		} finally {
+			this.projectsToUpdate = new HashSet();
+		}
+	}
+
+	/**
+	 * Removes the given element from its parents cache of children. If the
+	 * element does not have a parent, or the parent is not currently open,
+	 * this has no effect.
+	 */
+	protected void removeFromParentInfo(Openable child) {
+
+		Openable parent = (Openable) child.getParent();
+		if (parent != null && parent.isOpen()) {
+			try {
+				OpenableElementInfo info = (OpenableElementInfo) parent.getElementInfo();
+				info.removeChild(child);
+			} catch (JavaModelException e) {
+				// do nothing - we already checked if open
+			}
+		}
+	}
+
+	/**
+	 * Converts an <code>IResourceDelta</code> and its children into
+	 * the corresponding <code>IJavaElementDelta</code>s.
+	 * Return whether the delta corresponds to a resource on the classpath.
+	 * If it is not a resource on the classpath, it will be added as a non-java
+	 * resource by the sender of this method.
+	 */
+	protected void traverseDelta(
+		IJavaElementDelta delta,
+		IPackageFragmentRoot root,
+		IJavaProject project) {
+
+		boolean processChildren = true;
+
+		Openable element = (Openable) delta.getElement();
+		switch (element.getElementType()) {
+			case IJavaElement.JAVA_PROJECT :
+				project = (IJavaProject) element;
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+				root = (IPackageFragmentRoot) element;
+				break;
+			case IJavaElement.COMPILATION_UNIT :
+				// filter out working copies that are not primary (we don't want to add/remove them to/from the package fragment
+				CompilationUnit cu = (CompilationUnit)element;
+				if (cu.isWorkingCopy() && !cu.isPrimary()) {
+					return;
+				}
+				// $FALL-THROUGH$
+			case IJavaElement.CLASS_FILE :
+				processChildren = false;
+				break;
+		}
+
+		switch (delta.getKind()) {
+			case IJavaElementDelta.ADDED :
+				elementAdded(element);
+				break;
+			case IJavaElementDelta.REMOVED :
+				elementRemoved(element);
+				break;
+			case IJavaElementDelta.CHANGED :
+				if ((delta.getFlags() & IJavaElementDelta.F_CONTENT) != 0){
+					elementChanged(element);
+				}
+				break;
+		}
+		if (processChildren) {
+			IJavaElementDelta[] children = delta.getAffectedChildren();
+			for (int i = 0; i < children.length; i++) {
+				IJavaElementDelta childDelta = children[i];
+				traverseDelta(childDelta, root, project);
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java
new file mode 100644
index 0000000..7a89115
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation moves elements from their current
+ * container to a specified destination container, optionally renaming the
+ * elements.
+ * A move operation is equivalent to a copy operation, where
+ * the source elements are deleted after the copy.
+ * <p>This operation can be used for reorganizing elements within the same container.
+ *
+ * @see CopyElementsOperation
+ */
+public class MoveElementsOperation extends CopyElementsOperation {
+/**
+ * When executed, this operation will move the given elements to the given containers.
+ */
+public MoveElementsOperation(IJavaElement[] elementsToMove, IJavaElement[] destContainers, boolean force) {
+	super(elementsToMove, destContainers, force);
+}
+/**
+ * Returns the <code>String</code> to use as the main task name
+ * for progress monitoring.
+ */
+protected String getMainTaskName() {
+	return Messages.operation_moveElementProgress;
+}
+/**
+ * @see CopyElementsOperation#isMove()
+ */
+protected boolean isMove() {
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java
new file mode 100644
index 0000000..fe1c8eb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+
+public class MovePackageFragmentRootOperation extends CopyPackageFragmentRootOperation {
+	/*
+	 * Renames the classpath entries equal to the given path in the given project.
+	 * If an entry with the destination path already existed, remove it.
+	 */
+	protected void renameEntryInClasspath(IPath rootPath, IJavaProject project) throws JavaModelException {
+
+		IClasspathEntry[] classpath = project.getRawClasspath();
+		IClasspathEntry[] newClasspath = null;
+		int cpLength = classpath.length;
+		int newCPIndex = -1;
+
+		for (int i = 0; i < cpLength; i++) {
+			IClasspathEntry entry = classpath[i];
+			IPath entryPath = entry.getPath();
+			if (rootPath.equals(entryPath)) {
+				// rename entry
+				if (newClasspath == null) {
+					newClasspath = new IClasspathEntry[cpLength];
+					System.arraycopy(classpath, 0, newClasspath, 0, i);
+					newCPIndex = i;
+				}
+				newClasspath[newCPIndex++] = copy(entry);
+			} else if (this.destination.equals(entryPath)) {
+				// remove entry equals to destination
+				if (newClasspath == null) {
+					newClasspath = new IClasspathEntry[cpLength];
+					System.arraycopy(classpath, 0, newClasspath, 0, i);
+					newCPIndex = i;
+				}
+			} else if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+				// update exclusion/inclusion patterns
+				IPath projectRelativePath = rootPath.removeFirstSegments(1);
+				IPath[] newExclusionPatterns = renamePatterns(projectRelativePath, entry.getExclusionPatterns());
+				IPath[] newInclusionPatterns = renamePatterns(projectRelativePath, entry.getInclusionPatterns());
+				if (newExclusionPatterns != null || newInclusionPatterns != null) {
+					if (newClasspath == null) {
+						newClasspath = new IClasspathEntry[cpLength];
+						System.arraycopy(classpath, 0, newClasspath, 0, i);
+						newCPIndex = i;
+					}
+					newClasspath[newCPIndex++] =
+						JavaCore.newSourceEntry(
+							entry.getPath(),
+							newInclusionPatterns == null ? entry.getInclusionPatterns() : newInclusionPatterns,
+							newExclusionPatterns == null ? entry.getExclusionPatterns() : newExclusionPatterns,
+							entry.getOutputLocation(),
+							entry.getExtraAttributes());
+				} else if (newClasspath != null) {
+					newClasspath[newCPIndex++] = entry;
+				}
+			} else if (newClasspath != null) {
+				newClasspath[newCPIndex++] = entry;
+			}
+		}
+
+		if (newClasspath != null) {
+			if (newCPIndex < newClasspath.length) {
+				System.arraycopy(newClasspath, 0, newClasspath = new IClasspathEntry[newCPIndex], 0, newCPIndex);
+			}
+			IJavaModelStatus status = JavaConventions.validateClasspath(project, newClasspath, project.getOutputLocation());
+			if (status.isOK())
+				project.setRawClasspath(newClasspath, this.progressMonitor);
+			// don't update classpath if status is not ok to avoid JavaModelException (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=129991)
+		}
+	}
+
+	private IPath[] renamePatterns(IPath rootPath, IPath[] patterns) {
+		IPath[] newPatterns = null;
+		int newPatternsIndex = -1;
+		for (int i = 0, length = patterns.length; i < length; i++) {
+			IPath pattern = patterns[i];
+			if (pattern.equals(rootPath)) {
+				if (newPatterns == null) {
+					newPatterns = new IPath[length];
+					System.arraycopy(patterns, 0, newPatterns, 0, i);
+					newPatternsIndex = i;
+				}
+				IPath newPattern = this.destination.removeFirstSegments(1);
+				if (pattern.hasTrailingSeparator())
+					newPattern = newPattern.addTrailingSeparator();
+				newPatterns[newPatternsIndex++] = newPattern;
+			}
+		}
+		return newPatterns;
+	}
+
+	public MovePackageFragmentRootOperation(
+		IPackageFragmentRoot root,
+		IPath destination,
+		int updateResourceFlags,
+		int updateModelFlags,
+		IClasspathEntry sibling) {
+
+		super(
+			root,
+			destination,
+			updateResourceFlags,
+			updateModelFlags,
+			sibling);
+	}
+	protected void executeOperation() throws JavaModelException {
+
+		IPackageFragmentRoot root = (IPackageFragmentRoot) getElementToProcess();
+		IClasspathEntry rootEntry = root.getRawClasspathEntry();
+		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+		// move resource
+		if (!root.isExternal() && (this.updateModelFlags & IPackageFragmentRoot.NO_RESOURCE_MODIFICATION) == 0) {
+			moveResource(root, rootEntry, workspaceRoot);
+		}
+
+		// update refering projects classpath excluding orignating project
+		IJavaProject originatingProject = root.getJavaProject();
+		if ((this.updateModelFlags & IPackageFragmentRoot.OTHER_REFERRING_PROJECTS_CLASSPATH) != 0) {
+			updateReferringProjectClasspaths(rootEntry.getPath(), originatingProject);
+		}
+
+		boolean isRename = this.destination.segment(0).equals(originatingProject.getElementName());
+		boolean updateOriginating = (this.updateModelFlags & IPackageFragmentRoot.ORIGINATING_PROJECT_CLASSPATH) != 0;
+		boolean updateDestination = (this.updateModelFlags & IPackageFragmentRoot.DESTINATION_PROJECT_CLASSPATH) != 0;
+
+		// update originating classpath
+		if (updateOriginating) {
+			if (isRename && updateDestination) {
+				renameEntryInClasspath(rootEntry.getPath(), originatingProject);
+			} else {
+				removeEntryFromClasspath(rootEntry.getPath(), originatingProject);
+			}
+		}
+
+		// update destination classpath
+		if (updateDestination) {
+			if (!isRename || !updateOriginating) {
+				addEntryToClasspath(rootEntry, workspaceRoot);
+			}  // else reference has been updated when updating originating project classpath
+		}
+	}
+	protected void moveResource(
+		IPackageFragmentRoot root,
+		IClasspathEntry rootEntry,
+		final IWorkspaceRoot workspaceRoot)
+		throws JavaModelException {
+
+		final char[][] exclusionPatterns = ((ClasspathEntry)rootEntry).fullExclusionPatternChars();
+		IResource rootResource = ((JavaElement) root).resource();
+		if (rootEntry.getEntryKind() != IClasspathEntry.CPE_SOURCE || exclusionPatterns == null) {
+			try {
+				IResource destRes;
+				if ((this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+						&& (destRes = workspaceRoot.findMember(this.destination)) != null) {
+					destRes.delete(this.updateResourceFlags, this.progressMonitor);
+				}
+				rootResource.move(this.destination, this.updateResourceFlags, this.progressMonitor);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		} else {
+			final int sourceSegmentCount = rootEntry.getPath().segmentCount();
+			final IFolder destFolder = workspaceRoot.getFolder(this.destination);
+			final IPath[] nestedFolders = getNestedFolders(root);
+			IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+				public boolean visit(IResourceProxy proxy) throws CoreException {
+					if (proxy.getType() == IResource.FOLDER) {
+						IPath path = proxy.requestFullPath();
+						if (prefixesOneOf(path, nestedFolders)) {
+							if (equalsOneOf(path, nestedFolders)) {
+								// nested source folder
+								return false;
+							} else {
+								// folder containing nested source folder
+								IFolder folder = destFolder.getFolder(path.removeFirstSegments(sourceSegmentCount));
+								if ((MovePackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+										&& folder.exists()) {
+									return true;
+								}
+								folder.create(MovePackageFragmentRootOperation.this.updateResourceFlags, true, MovePackageFragmentRootOperation.this.progressMonitor);
+								return true;
+							}
+						} else {
+							// subtree doesn't contain any nested source folders
+							IPath destPath = MovePackageFragmentRootOperation.this.destination.append(path.removeFirstSegments(sourceSegmentCount));
+							IResource destRes;
+							if ((MovePackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+									&& (destRes = workspaceRoot.findMember(destPath)) != null) {
+								destRes.delete(MovePackageFragmentRootOperation.this.updateResourceFlags, MovePackageFragmentRootOperation.this.progressMonitor);
+							}
+							proxy.requestResource().move(destPath, MovePackageFragmentRootOperation.this.updateResourceFlags, MovePackageFragmentRootOperation.this.progressMonitor);
+							return false;
+						}
+					} else {
+						IPath path = proxy.requestFullPath();
+						IPath destPath = MovePackageFragmentRootOperation.this.destination.append(path.removeFirstSegments(sourceSegmentCount));
+						IResource destRes;
+						if ((MovePackageFragmentRootOperation.this.updateModelFlags & IPackageFragmentRoot.REPLACE) != 0
+								&& (destRes = workspaceRoot.findMember(destPath)) != null) {
+							destRes.delete(MovePackageFragmentRootOperation.this.updateResourceFlags, MovePackageFragmentRootOperation.this.progressMonitor);
+						}
+						proxy.requestResource().move(destPath, MovePackageFragmentRootOperation.this.updateResourceFlags, MovePackageFragmentRootOperation.this.progressMonitor);
+						return false;
+					}
+				}
+			};
+			try {
+				rootResource.accept(visitor, IResource.NONE);
+			} catch (CoreException e) {
+				throw new JavaModelException(e);
+			}
+		}
+		setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+	}
+	/*
+	 * Renames the classpath entries equal to the given path in all Java projects.
+	 */
+	protected void updateReferringProjectClasspaths(IPath rootPath, IJavaProject projectOfRoot) throws JavaModelException {
+		IJavaModel model = getJavaModel();
+		IJavaProject[] projects = model.getJavaProjects();
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IJavaProject project = projects[i];
+			if (project.equals(projectOfRoot)) continue;
+			renameEntryInClasspath(rootPath, project);
+		}
+	}
+	/*
+	 * Removes the classpath entry equal to the given path from the given project's classpath.
+	 */
+	protected void removeEntryFromClasspath(IPath rootPath, IJavaProject project) throws JavaModelException {
+
+		IClasspathEntry[] classpath = project.getRawClasspath();
+		IClasspathEntry[] newClasspath = null;
+		int cpLength = classpath.length;
+		int newCPIndex = -1;
+
+		for (int i = 0; i < cpLength; i++) {
+			IClasspathEntry entry = classpath[i];
+			if (rootPath.equals(entry.getPath())) {
+				if (newClasspath == null) {
+					newClasspath = new IClasspathEntry[cpLength];
+					System.arraycopy(classpath, 0, newClasspath, 0, i);
+					newCPIndex = i;
+				}
+			} else if (newClasspath != null) {
+				newClasspath[newCPIndex++] = entry;
+			}
+		}
+
+		if (newClasspath != null) {
+			if (newCPIndex < newClasspath.length) {
+				System.arraycopy(newClasspath, 0, newClasspath = new IClasspathEntry[newCPIndex], 0, newCPIndex);
+			}
+			project.setRawClasspath(newClasspath, this.progressMonitor);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java
new file mode 100644
index 0000000..a58d176
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation moves resources (package fragments and compilation units) from their current
+ * container to a specified destination container, optionally renaming the
+ * elements.
+ * A move resource operation is equivalent to a copy resource operation, where
+ * the source resources are deleted after the copy.
+ * <p>This operation can be used for reorganizing resources within the same container.
+ *
+ * @see CopyResourceElementsOperation
+ */
+public class MoveResourceElementsOperation extends CopyResourceElementsOperation {
+/**
+ * When executed, this operation will move the given elements to the given containers.
+ */
+public MoveResourceElementsOperation(IJavaElement[] elementsToMove, IJavaElement[] destContainers, boolean force) {
+	super(elementsToMove, destContainers, force);
+}
+/**
+ * @see MultiOperation
+ */
+protected String getMainTaskName() {
+	return Messages.operation_moveResourceProgress;
+}
+/**
+ * @see CopyResourceElementsOperation#isMove()
+ */
+protected boolean isMove() {
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java
new file mode 100644
index 0000000..1848026
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.*;
+
+/**
+ * This class is used to perform operations on multiple <code>IJavaElement</code>.
+ * It is responible for running each operation in turn, collecting
+ * the errors and merging the corresponding <code>JavaElementDelta</code>s.
+ * <p>
+ * If several errors occured, they are collected in a multi-status
+ * <code>JavaModelStatus</code>. Otherwise, a simple <code>JavaModelStatus</code>
+ * is thrown.
+ */
+public abstract class MultiOperation extends JavaModelOperation {
+	/**
+	 * Table specifying insertion positions for elements being
+	 * copied/moved/renamed. Keyed by elements being processed, and
+	 * values are the corresponding insertion point.
+	 * @see #processElements()
+	 */
+	protected Map insertBeforeElements = new HashMap(1);
+	/**
+	 * Table specifying the new parent for elements being
+	 * copied/moved/renamed.
+	 * Keyed by elements being processed, and
+	 * values are the corresponding destination parent.
+	 */
+	protected Map newParents;
+	/**
+	 * This table presents the data in <code>fRenamingList</code> in a more
+	 * convenient way.
+	 */
+	protected Map renamings;
+	/**
+	 * The list of renamings supplied to the operation
+	 */
+	protected String[] renamingsList = null;
+	/**
+	 * Creates a new <code>MultiOperation</code> on <code>elementsToProcess</code>.
+	 */
+	protected MultiOperation(IJavaElement[] elementsToProcess, boolean force) {
+		super(elementsToProcess, force);
+	}
+	/**
+	 * Creates a new <code>MultiOperation</code>.
+	 */
+	protected MultiOperation(IJavaElement[] elementsToProcess, IJavaElement[] parentElements, boolean force) {
+		super(elementsToProcess, parentElements, force);
+		this.newParents = new HashMap(elementsToProcess.length);
+		if (elementsToProcess.length == parentElements.length) {
+			for (int i = 0; i < elementsToProcess.length; i++) {
+				this.newParents.put(elementsToProcess[i], parentElements[i]);
+			}
+		} else { //same destination for all elements to be moved/copied/renamed
+			for (int i = 0; i < elementsToProcess.length; i++) {
+				this.newParents.put(elementsToProcess[i], parentElements[0]);
+			}
+		}
+
+	}
+	/**
+	 * Convenience method to create a <code>JavaModelException</code>
+	 * embending a <code>JavaModelStatus</code>.
+	 */
+	protected void error(int code, IJavaElement element) throws JavaModelException {
+		throw new JavaModelException(new JavaModelStatus(code, element));
+	}
+	/**
+	 * Executes the operation.
+	 *
+	 * @exception JavaModelException if one or several errors occured during the operation.
+	 * If multiple errors occured, the corresponding <code>JavaModelStatus</code> is a
+	 * multi-status. Otherwise, it is a simple one.
+	 */
+	protected void executeOperation() throws JavaModelException {
+		processElements();
+	}
+	/**
+	 * Returns the parent of the element being copied/moved/renamed.
+	 */
+	protected IJavaElement getDestinationParent(IJavaElement child) {
+		return (IJavaElement)this.newParents.get(child);
+	}
+	/**
+	 * Returns the name to be used by the progress monitor.
+	 */
+	protected abstract String getMainTaskName();
+	/**
+	 * Returns the new name for <code>element</code>, or <code>null</code>
+	 * if there are no renamings specified.
+	 */
+	protected String getNewNameFor(IJavaElement element) throws JavaModelException {
+		String newName = null;
+		if (this.renamings != null)
+			newName = (String) this.renamings.get(element);
+		if (newName == null && element instanceof IMethod && ((IMethod) element).isConstructor())
+			newName = getDestinationParent(element).getElementName();
+		return newName;
+	}
+	/**
+	 * Sets up the renamings hashtable - keys are the elements and
+	 * values are the new name.
+	 */
+	private void initializeRenamings() {
+		if (this.renamingsList != null && this.renamingsList.length == this.elementsToProcess.length) {
+			this.renamings = new HashMap(this.renamingsList.length);
+			for (int i = 0; i < this.renamingsList.length; i++) {
+				if (this.renamingsList[i] != null) {
+					this.renamings.put(this.elementsToProcess[i], this.renamingsList[i]);
+				}
+			}
+		}
+	}
+	/**
+	 * Returns <code>true</code> if this operation represents a move or rename, <code>false</code>
+	 * if this operation represents a copy.<br>
+	 * Note: a rename is just a move within the same parent with a name change.
+	 */
+	protected boolean isMove() {
+		return false;
+	}
+	/**
+	 * Returns <code>true</code> if this operation represents a rename, <code>false</code>
+	 * if this operation represents a copy or move.
+	 */
+	protected boolean isRename() {
+		return false;
+	}
+
+	/**
+	 * Subclasses must implement this method to process a given <code>IJavaElement</code>.
+	 */
+	protected abstract void processElement(IJavaElement element) throws JavaModelException;
+	/**
+	 * Processes all the <code>IJavaElement</code>s in turn, collecting errors
+	 * and updating the progress monitor.
+	 *
+	 * @exception JavaModelException if one or several operation(s) was unable to
+	 * be completed.
+	 */
+	protected void processElements() throws JavaModelException {
+		try {
+			beginTask(getMainTaskName(), this.elementsToProcess.length);
+			IJavaModelStatus[] errors = new IJavaModelStatus[3];
+			int errorsCounter = 0;
+			for (int i = 0; i < this.elementsToProcess.length; i++) {
+				try {
+					verify(this.elementsToProcess[i]);
+					processElement(this.elementsToProcess[i]);
+				} catch (JavaModelException jme) {
+					if (errorsCounter == errors.length) {
+						// resize
+						System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter*2]), 0, errorsCounter);
+					}
+					errors[errorsCounter++] = jme.getJavaModelStatus();
+				} finally {
+					worked(1);
+				}
+			}
+			if (errorsCounter == 1) {
+				throw new JavaModelException(errors[0]);
+			} else if (errorsCounter > 1) {
+				if (errorsCounter != errors.length) {
+					// resize
+					System.arraycopy(errors, 0, (errors = new IJavaModelStatus[errorsCounter]), 0, errorsCounter);
+				}
+				throw new JavaModelException(JavaModelStatus.newMultiStatus(errors));
+			}
+		} finally {
+			done();
+		}
+	}
+	/**
+	 * Sets the insertion position in the new container for the modified element. The element
+	 * being modified will be inserted before the specified new sibling. The given sibling
+	 * must be a child of the destination container specified for the modified element.
+	 * The default is <code>null</code>, which indicates that the element is to be
+	 * inserted at the end of the container.
+	 */
+	public void setInsertBefore(IJavaElement modifiedElement, IJavaElement newSibling) {
+		this.insertBeforeElements.put(modifiedElement, newSibling);
+	}
+	/**
+	 * Sets the new names to use for each element being copied. The renamings
+	 * correspond to the elements being processed, and the number of
+	 * renamings must match the number of elements being processed.
+	 * A <code>null</code> entry in the list indicates that an element
+	 * is not to be renamed.
+	 *
+	 * <p>Note that some renamings may not be used.  If both a parent
+	 * and a child have been selected for copy/move, only the parent
+	 * is changed.  Therefore, if a new name is specified for the child,
+	 * the child's name will not be changed.
+	 */
+	public void setRenamings(String[] renamingsList) {
+		this.renamingsList = renamingsList;
+		initializeRenamings();
+	}
+	/**
+	 * This method is called for each <code>IJavaElement</code> before
+	 * <code>processElement</code>. It should check that this <code>element</code>
+	 * can be processed.
+	 */
+	protected abstract void verify(IJavaElement element) throws JavaModelException;
+	/**
+	 * Verifies that the <code>destination</code> specified for the <code>element</code> is valid for the types of the
+	 * <code>element</code> and <code>destination</code>.
+	 */
+	protected void verifyDestination(IJavaElement element, IJavaElement destination) throws JavaModelException {
+		if (destination == null || !destination.exists())
+			error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, destination);
+
+		int destType = destination.getElementType();
+		switch (element.getElementType()) {
+			case IJavaElement.PACKAGE_DECLARATION :
+			case IJavaElement.IMPORT_DECLARATION :
+				if (destType != IJavaElement.COMPILATION_UNIT)
+					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
+				break;
+			case IJavaElement.TYPE :
+				if (destType != IJavaElement.COMPILATION_UNIT && destType != IJavaElement.TYPE)
+					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
+				break;
+			case IJavaElement.METHOD :
+			case IJavaElement.FIELD :
+			case IJavaElement.INITIALIZER :
+				if (destType != IJavaElement.TYPE || destination instanceof BinaryType)
+					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
+				break;
+			case IJavaElement.COMPILATION_UNIT :
+				if (destType != IJavaElement.PACKAGE_FRAGMENT)
+					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
+				else {
+					CompilationUnit cu = (CompilationUnit)element;
+					if (isMove() && cu.isWorkingCopy() && !cu.isPrimary())
+						error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+				}
+				break;
+			case IJavaElement.PACKAGE_FRAGMENT :
+				IPackageFragment fragment = (IPackageFragment) element;
+				IJavaElement parent = fragment.getParent();
+				if (parent.isReadOnly())
+					error(IJavaModelStatusConstants.READ_ONLY, element);
+				else if (destType != IJavaElement.PACKAGE_FRAGMENT_ROOT)
+					error(IJavaModelStatusConstants.INVALID_DESTINATION, element);
+				break;
+			default :
+				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+		}
+	}
+	/**
+	 * Verify that the new name specified for <code>element</code> is
+	 * valid for that type of Java element.
+	 */
+	protected void verifyRenaming(IJavaElement element) throws JavaModelException {
+		String newName = getNewNameFor(element);
+		boolean isValid = true;
+	    IJavaProject project = element.getJavaProject();
+	    String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+	    String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+		switch (element.getElementType()) {
+			case IJavaElement.PACKAGE_FRAGMENT :
+				if (((IPackageFragment) element).isDefaultPackage()) {
+					// don't allow renaming of default package (see PR #1G47GUM)
+					throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, element));
+				}
+				isValid = JavaConventions.validatePackageName(newName, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+				break;
+			case IJavaElement.COMPILATION_UNIT :
+				isValid = JavaConventions.validateCompilationUnitName(newName,sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+				break;
+			case IJavaElement.INITIALIZER :
+				isValid = false; //cannot rename initializers
+				break;
+			default :
+				isValid = JavaConventions.validateIdentifier(newName, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+				break;
+		}
+
+		if (!isValid) {
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, element, newName));
+		}
+	}
+	/**
+	 * Verifies that the positioning sibling specified for the <code>element</code> is exists and
+	 * its parent is the destination container of this <code>element</code>.
+	 */
+	protected void verifySibling(IJavaElement element, IJavaElement destination) throws JavaModelException {
+		IJavaElement insertBeforeElement = (IJavaElement) this.insertBeforeElements.get(element);
+		if (insertBeforeElement != null) {
+			if (!insertBeforeElement.exists() || !insertBeforeElement.getParent().equals(destination)) {
+				error(IJavaModelStatusConstants.INVALID_SIBLING, insertBeforeElement);
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
new file mode 100644
index 0000000..ebfb67b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -0,0 +1,1251 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.File;
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A <code>NameLookup</code> provides name resolution within a Java project.
+ * The name lookup facility uses the project's classpath to prioritize the
+ * order in which package fragments are searched when resolving a name.
+ *
+ * <p>Name lookup only returns a handle when the named element actually
+ * exists in the model; otherwise <code>null</code> is returned.
+ *
+ * <p>There are two logical sets of methods within this interface.  Methods
+ * which start with <code>find*</code> are intended to be convenience methods for quickly
+ * finding an element within another element; for instance, for finding a class within a
+ * package.  The other set of methods all begin with <code>seek*</code>.  These methods
+ * do comprehensive searches of the <code>IJavaProject</code> returning hits
+ * in real time through an <code>IJavaElementRequestor</code>.
+ *
+ */
+public class NameLookup implements SuffixConstants {
+	public static class Answer {
+		public IType type;
+		AccessRestriction restriction;
+		Answer(IType type, AccessRestriction restriction) {
+			this.type = type;
+			this.restriction = restriction;
+		}
+		public boolean ignoreIfBetter() {
+			return this.restriction != null && this.restriction.ignoreIfBetter();
+		}
+		/*
+		 * Returns whether this answer is better than the other awswer.
+		 * (accessible is better than discouraged, which is better than
+		 * non-accessible)
+		 */
+		public boolean isBetter(Answer otherAnswer) {
+			if (otherAnswer == null) return true;
+			if (this.restriction == null) return true;
+			return otherAnswer.restriction != null
+				&& this.restriction.getProblemId() < otherAnswer.restriction.getProblemId();
+		}
+	}
+
+	// TODO (jerome) suppress the accept flags (qualified name is sufficient to find a type)
+	/**
+	 * Accept flag for specifying classes.
+	 */
+	public static final int ACCEPT_CLASSES = ASTNode.Bit2;
+
+	/**
+	 * Accept flag for specifying interfaces.
+	 */
+	public static final int ACCEPT_INTERFACES = ASTNode.Bit3;
+
+	/**
+	 * Accept flag for specifying enums.
+	 */
+	public static final int ACCEPT_ENUMS = ASTNode.Bit4;
+
+	/**
+	 * Accept flag for specifying annotations.
+	 */
+	public static final int ACCEPT_ANNOTATIONS = ASTNode.Bit5;
+
+	/*
+	 * Accept flag for all kinds of types
+	 */
+	public static final int ACCEPT_ALL = ACCEPT_CLASSES | ACCEPT_INTERFACES | ACCEPT_ENUMS | ACCEPT_ANNOTATIONS;
+
+	public static boolean VERBOSE = false;
+
+	private static final IType[] NO_TYPES = {};
+
+	/**
+	 * The <code>IPackageFragmentRoot</code>'s associated
+	 * with the classpath of this NameLookup facility's
+	 * project.
+	 */
+	protected IPackageFragmentRoot[] packageFragmentRoots;
+
+	/**
+	 * Table that maps package names to lists of package fragment roots
+	 * that contain such a package known by this name lookup facility.
+	 * To allow > 1 package fragment with the same name, values are
+	 * arrays of package fragment roots ordered as they appear on the
+	 * classpath.
+	 * Note if the list is of size 1, then the IPackageFragmentRoot object
+	 * replaces the array.
+	 */
+	protected HashtableOfArrayToObject packageFragments;
+
+	/**
+	 * Reverse map from root path to corresponding resolved CP entry
+	 * (so as to be able to figure inclusion/exclusion rules)
+	 */
+	protected Map rootToResolvedEntries;
+
+	/**
+	 * A map from package handles to a map from type name to an IType or an IType[].
+	 * Allows working copies to take precedence over compilation units.
+	 */
+	protected HashMap typesInWorkingCopies;
+
+	public long timeSpentInSeekTypesInSourcePackage = 0;
+	public long timeSpentInSeekTypesInBinaryPackage = 0;
+
+	public NameLookup(
+			IPackageFragmentRoot[] packageFragmentRoots,
+			HashtableOfArrayToObject packageFragments,
+			ICompilationUnit[] workingCopies,
+			Map rootToResolvedEntries) {
+		long start = -1;
+		if (VERBOSE) {
+			Util.verbose(" BUILDING NameLoopkup");  //$NON-NLS-1$
+			Util.verbose(" -> pkg roots size: " + (packageFragmentRoots == null ? 0 : packageFragmentRoots.length));  //$NON-NLS-1$
+			Util.verbose(" -> pkgs size: " + (packageFragments == null ? 0 : packageFragments.size()));  //$NON-NLS-1$
+			Util.verbose(" -> working copy size: " + (workingCopies == null ? 0 : workingCopies.length));  //$NON-NLS-1$
+			start = System.currentTimeMillis();
+		}
+		this.packageFragmentRoots = packageFragmentRoots;
+		if (workingCopies == null) {
+			this.packageFragments = packageFragments;
+		} else {
+			// clone tables as we're adding packages from working copies
+			try {
+				this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone();
+			} catch (CloneNotSupportedException e1) {
+				// ignore (implementation of HashtableOfArrayToObject supports cloning)
+			}
+			this.typesInWorkingCopies = new HashMap();
+			HashtableOfObjectToInt rootPositions = new HashtableOfObjectToInt();
+			for (int i = 0, length = packageFragmentRoots.length; i < length; i++) {
+				rootPositions.put(packageFragmentRoots[i], i);
+			}
+			for (int i = 0, length = workingCopies.length; i < length; i++) {
+				ICompilationUnit workingCopy = workingCopies[i];
+				PackageFragment pkg = (PackageFragment) workingCopy.getParent();
+				IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
+				int rootPosition = rootPositions.get(root);
+				if (rootPosition == -1)
+					continue; // working copy is not visible from this project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=169970)
+				HashMap typeMap = (HashMap) this.typesInWorkingCopies.get(pkg);
+				if (typeMap == null) {
+					typeMap = new HashMap();
+					this.typesInWorkingCopies.put(pkg, typeMap);
+				}
+				try {
+					IType[] types = workingCopy.getTypes();
+					int typeLength = types.length;
+					if (typeLength == 0) {
+						String typeName = Util.getNameWithoutJavaLikeExtension(workingCopy.getElementName());
+						typeMap.put(typeName, NO_TYPES);
+					} else {
+						for (int j = 0; j < typeLength; j++) {
+							IType type = types[j];
+							String typeName = type.getElementName();
+							Object existing = typeMap.get(typeName);
+							if (existing == null) {
+								typeMap.put(typeName, type);
+							} else if (existing instanceof IType) {
+								typeMap.put(typeName, new IType[] {(IType) existing, type});
+							} else {
+								IType[] existingTypes = (IType[]) existing;
+								int existingTypeLength = existingTypes.length;
+								System.arraycopy(existingTypes, 0, existingTypes = new IType[existingTypeLength+1], 0, existingTypeLength);
+								existingTypes[existingTypeLength] = type;
+								typeMap.put(typeName, existingTypes);
+							}
+						}
+					}
+				} catch (JavaModelException e) {
+					// working copy doesn't exist -> ignore
+				}
+
+				// add root of package fragment to cache
+				String[] pkgName = pkg.names;
+				Object existing = this.packageFragments.get(pkgName);
+				if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) {
+					this.packageFragments.put(pkgName, root);
+					// ensure super packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161)
+					// are also in the map
+					JavaProjectElementInfo.addSuperPackageNames(pkgName, this.packageFragments);
+				} else {
+					if (existing instanceof PackageFragmentRoot) {
+						int exisitingPosition = rootPositions.get(existing);
+						if (rootPosition != exisitingPosition) { // if not equal
+							this.packageFragments.put(
+								pkgName,
+								exisitingPosition < rootPosition ?
+									new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root} :
+									new IPackageFragmentRoot[] {root, (PackageFragmentRoot) existing});
+						}
+					} else {
+						// insert root in the existing list
+						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
+						int rootLength = roots.length;
+						int insertionIndex = 0;
+						for (int j = 0; j < rootLength; j++) {
+							int existingPosition = rootPositions.get(roots[j]);
+							if (rootPosition > existingPosition) {
+								// root is after this index
+								insertionIndex = j;
+							} else if (rootPosition == existingPosition) {
+								 // root already in the existing list
+								insertionIndex = -1;
+								break;
+							} else if (rootPosition < existingPosition) {
+								// root is before this index (thus it is at the insertion index)
+								break;
+							}
+						}
+						if (insertionIndex != -1) {
+							IPackageFragmentRoot[] newRoots = new IPackageFragmentRoot[rootLength+1];
+							System.arraycopy(roots, 0, newRoots, 0, insertionIndex);
+							newRoots[insertionIndex] = root;
+							System.arraycopy(roots, insertionIndex, newRoots, insertionIndex+1, rootLength-insertionIndex);
+							this.packageFragments.put(pkgName, newRoots);
+						}
+					}
+				}
+			}
+		}
+
+		this.rootToResolvedEntries = rootToResolvedEntries;
+        if (VERBOSE) {
+            Util.verbose(" -> spent: " + (System.currentTimeMillis() - start) + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+        }
+	}
+
+	/**
+	 * Returns true if:<ul>
+	 *  <li>the given type is an existing class and the flag's <code>ACCEPT_CLASSES</code>
+	 *      bit is on
+	 *  <li>the given type is an existing interface and the <code>ACCEPT_INTERFACES</code>
+	 *      bit is on
+	 *  <li>neither the <code>ACCEPT_CLASSES</code> or <code>ACCEPT_INTERFACES</code>
+	 *      bit is on
+	 *  </ul>
+	 * Otherwise, false is returned.
+	 */
+	protected boolean acceptType(IType type, int acceptFlags, boolean isSourceType) {
+		if (acceptFlags == 0 || acceptFlags == ACCEPT_ALL)
+			return true; // no flags or all flags, always accepted
+		try {
+			int kind = isSourceType
+					? TypeDeclaration.kind(((SourceTypeElementInfo) ((SourceType) type).getElementInfo()).getModifiers())
+					: TypeDeclaration.kind(((IBinaryType) ((BinaryType) type).getElementInfo()).getModifiers());
+			switch (kind) {
+				case TypeDeclaration.CLASS_DECL :
+					return (acceptFlags & ACCEPT_CLASSES) != 0;
+				case TypeDeclaration.INTERFACE_DECL :
+					return (acceptFlags & ACCEPT_INTERFACES) != 0;
+				case TypeDeclaration.ENUM_DECL :
+					return (acceptFlags & ACCEPT_ENUMS) != 0;
+				default:
+					//case IGenericType.ANNOTATION_TYPE :
+					return (acceptFlags & ACCEPT_ANNOTATIONS) != 0;
+			}
+		} catch (JavaModelException npe) {
+			return false; // the class is not present, do not accept.
+		}
+	}
+
+	/**
+	 * Finds every type in the project whose simple name matches
+	 * the prefix, informing the requestor of each hit. The requestor
+	 * is polled for cancellation at regular intervals.
+	 *
+	 * <p>The <code>partialMatch</code> argument indicates partial matches
+	 * should be considered.
+	 */
+	private void findAllTypes(String prefix, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) {
+		int count= this.packageFragmentRoots.length;
+		for (int i= 0; i < count; i++) {
+			if (requestor.isCanceled())
+				return;
+			IPackageFragmentRoot root= this.packageFragmentRoots[i];
+			IJavaElement[] packages= null;
+			try {
+				packages= root.getChildren();
+			} catch (JavaModelException npe) {
+				continue; // the root is not present, continue;
+			}
+			if (packages != null) {
+				for (int j= 0, packageCount= packages.length; j < packageCount; j++) {
+					if (requestor.isCanceled())
+						return;
+					seekTypes(prefix, (IPackageFragment) packages[j], partialMatch, acceptFlags, requestor);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns the <code>ICompilationUnit</code> which defines the type
+	 * named <code>qualifiedTypeName</code>, or <code>null</code> if
+	 * none exists. The domain of the search is bounded by the classpath
+	 * of the <code>IJavaProject</code> this <code>NameLookup</code> was
+	 * obtained from.
+	 * <p>
+	 * The name must be fully qualified (eg "java.lang.Object", "java.util.Hashtable$Entry")
+	 */
+	public ICompilationUnit findCompilationUnit(String qualifiedTypeName) {
+		String[] pkgName = CharOperation.NO_STRINGS;
+		String cuName = qualifiedTypeName;
+
+		int index= qualifiedTypeName.lastIndexOf('.');
+		if (index != -1) {
+			pkgName= Util.splitOn('.', qualifiedTypeName, 0, index);
+			cuName= qualifiedTypeName.substring(index + 1);
+		}
+		index= cuName.indexOf('$');
+		if (index != -1) {
+			cuName= cuName.substring(0, index);
+		}
+		int pkgIndex = this.packageFragments.getIndex(pkgName);
+		if (pkgIndex != -1) {
+			Object value = this.packageFragments.valueTable[pkgIndex];
+			// reuse existing String[]
+			pkgName = (String[]) this.packageFragments.keyTable[pkgIndex];
+			if (value instanceof PackageFragmentRoot) {
+				return findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) value);
+			} else {
+				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+				for (int i= 0; i < roots.length; i++) {
+					PackageFragmentRoot root= (PackageFragmentRoot) roots[i];
+					ICompilationUnit cu = findCompilationUnit(pkgName, cuName, root);
+					if (cu != null)
+						return cu;
+				}
+			}
+		}
+		return null;
+	}
+
+	private ICompilationUnit findCompilationUnit(String[] pkgName, String cuName, PackageFragmentRoot root) {
+		if (!root.isArchive()) {
+			IPackageFragment pkg = root.getPackageFragment(pkgName);
+			try {
+				ICompilationUnit[] cus = pkg.getCompilationUnits();
+				for (int j = 0, length = cus.length; j < length; j++) {
+					ICompilationUnit cu = cus[j];
+					if (Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), cuName))
+						return cu;
+				}
+			} catch (JavaModelException e) {
+				// pkg does not exist
+				// -> try next package
+			}
+		}
+		return null;
+}
+
+	/**
+	 * Returns the package fragment whose path matches the given
+	 * (absolute) path, or <code>null</code> if none exist. The domain of
+	 * the search is bounded by the classpath of the <code>IJavaProject</code>
+	 * this <code>NameLookup</code> was obtained from.
+	 * The path can be:
+	 * 	- internal to the workbench: "/Project/src"
+	 *  - external to the workbench: "c:/jdk/classes.zip/java/lang"
+	 */
+	public IPackageFragment findPackageFragment(IPath path) {
+		if (!path.isAbsolute()) {
+			throw new IllegalArgumentException(Messages.path_mustBeAbsolute);
+		}
+/*
+ * TODO (jerome) this code should rather use the package fragment map to find the candidate package, then
+ * check if the respective enclosing root maps to the one on this given IPath.
+ */
+		IResource possibleFragment = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
+		if (possibleFragment == null) {
+			//external jar
+			for (int i = 0; i < this.packageFragmentRoots.length; i++) {
+				IPackageFragmentRoot root = this.packageFragmentRoots[i];
+				if (!root.isExternal()) {
+					continue;
+				}
+				IPath rootPath = root.getPath();
+				if (rootPath.isPrefixOf(path)) {
+					String name = path.toOSString();
+					// + 1 is for the File.separatorChar
+					name = name.substring(rootPath.toOSString().length() + 1, name.length());
+					name = name.replace(File.separatorChar, '.');
+					IJavaElement[] list = null;
+					try {
+						list = root.getChildren();
+					} catch (JavaModelException npe) {
+						continue; // the package fragment root is not present;
+					}
+					int elementCount = list.length;
+					for (int j = 0; j < elementCount; j++) {
+						IPackageFragment packageFragment = (IPackageFragment) list[j];
+						if (nameMatches(name, packageFragment, false)) {
+							return packageFragment;
+						}
+					}
+				}
+			}
+		} else {
+			IJavaElement fromFactory = JavaCore.create(possibleFragment);
+			if (fromFactory == null) {
+				return null;
+			}
+			switch (fromFactory.getElementType()) {
+				case IJavaElement.PACKAGE_FRAGMENT:
+					return (IPackageFragment) fromFactory;
+				case IJavaElement.JAVA_PROJECT:
+					// default package in a default root
+					JavaProject project = (JavaProject) fromFactory;
+					try {
+						IClasspathEntry entry = project.getClasspathEntryFor(path);
+						if (entry != null) {
+							IPackageFragmentRoot root =
+								project.getPackageFragmentRoot(project.getResource());
+							Object defaultPkgRoot = this.packageFragments.get(CharOperation.NO_STRINGS);
+							if (defaultPkgRoot == null) {
+								return null;
+							}
+							if (defaultPkgRoot instanceof PackageFragmentRoot && defaultPkgRoot.equals(root))
+								return  ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS);
+							else {
+								IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) defaultPkgRoot;
+								for (int i = 0; i < roots.length; i++) {
+									if (roots[i].equals(root)) {
+										return  ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS);
+									}
+								}
+							}
+						}
+					} catch (JavaModelException e) {
+						return null;
+					}
+					return null;
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+					return ((PackageFragmentRoot)fromFactory).getPackageFragment(CharOperation.NO_STRINGS);
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the package fragments whose name matches the given
+	 * (qualified) name, or <code>null</code> if none exist.
+	 *
+	 * The name can be:
+	 * <ul>
+	 *		<li>empty: ""</li>
+	 *		<li>qualified: "pack.pack1.pack2"</li>
+	 * </ul>
+	 * @param partialMatch partial name matches qualify when <code>true</code>,
+	 *	only exact name matches qualify when <code>false</code>
+	 */
+	public IPackageFragment[] findPackageFragments(String name, boolean partialMatch) {
+		return findPackageFragments(name, partialMatch, false);
+	}
+
+	/**
+	 * Returns the package fragments whose name matches the given
+	 * (qualified) name or pattern, or <code>null</code> if none exist.
+	 *
+	 * The name can be:
+	 * <ul>
+	 *		<li>empty: ""</li>
+	 *		<li>qualified: "pack.pack1.pack2"</li>
+	 * 	<li>a pattern: "pack.*.util"</li>
+	 * </ul>
+	 * @param partialMatch partial name matches qualify when <code>true</code>,
+	 * @param patternMatch <code>true</code> when the given name might be a pattern,
+	 *		<code>false</code> otherwise.
+	 */
+	public IPackageFragment[] findPackageFragments(String name, boolean partialMatch, boolean patternMatch) {
+		boolean isStarPattern = name.equals("*"); //$NON-NLS-1$
+		boolean hasPatternChars = isStarPattern || (patternMatch && (name.indexOf('*') >= 0 || name.indexOf('?') >= 0));
+		if (partialMatch || hasPatternChars) {
+			String[] splittedName = Util.splitOn('.', name, 0, name.length());
+			IPackageFragment[] oneFragment = null;
+			ArrayList pkgs = null;
+			char[] lowercaseName = hasPatternChars && !isStarPattern ? name.toLowerCase().toCharArray() : null;
+			Object[][] keys = this.packageFragments.keyTable;
+			for (int i = 0, length = keys.length; i < length; i++) {
+				String[] pkgName = (String[]) keys[i];
+				if (pkgName != null) {
+					boolean match = isStarPattern || (hasPatternChars
+						? CharOperation.match(lowercaseName, Util.concatCompoundNameToCharArray(pkgName), false)
+						: Util.startsWithIgnoreCase(pkgName, splittedName, partialMatch));
+					if (match) {
+						Object value = this.packageFragments.valueTable[i];
+						if (value instanceof PackageFragmentRoot) {
+							IPackageFragment pkg = ((PackageFragmentRoot) value).getPackageFragment(pkgName);
+							if (oneFragment == null) {
+								oneFragment = new IPackageFragment[] {pkg};
+							} else {
+								if (pkgs == null) {
+									pkgs = new ArrayList();
+									pkgs.add(oneFragment[0]);
+								}
+								pkgs.add(pkg);
+							}
+						} else {
+							IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+							for (int j = 0, length2 = roots.length; j < length2; j++) {
+								PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
+								IPackageFragment pkg = root.getPackageFragment(pkgName);
+								if (oneFragment == null) {
+									oneFragment = new IPackageFragment[] {pkg};
+								} else {
+									if (pkgs == null) {
+										pkgs = new ArrayList();
+										pkgs.add(oneFragment[0]);
+									}
+									pkgs.add(pkg);
+								}
+							}
+						}
+					}
+				}
+			}
+			if (pkgs == null) return oneFragment;
+			int resultLength = pkgs.size();
+			IPackageFragment[] result = new IPackageFragment[resultLength];
+			pkgs.toArray(result);
+			return result;
+		} else {
+			String[] splittedName = Util.splitOn('.', name, 0, name.length());
+			int pkgIndex = this.packageFragments.getIndex(splittedName);
+			if (pkgIndex == -1)
+				return null;
+			Object value = this.packageFragments.valueTable[pkgIndex];
+			// reuse existing String[]
+			String[] pkgName = (String[]) this.packageFragments.keyTable[pkgIndex];
+			if (value instanceof PackageFragmentRoot) {
+				return new IPackageFragment[] {((PackageFragmentRoot) value).getPackageFragment(pkgName)};
+			} else {
+				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+				IPackageFragment[] result = new IPackageFragment[roots.length];
+				for (int i= 0; i < roots.length; i++) {
+					result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(pkgName);
+				}
+				return result;
+			}
+		}
+	}
+
+	/*
+	 * Find secondary type for a project.
+	 */
+	private IType findSecondaryType(String packageName, String typeName, IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor) {
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		try {
+			IJavaProject javaProject = project;
+			Map secondaryTypePaths = manager.secondaryTypes(javaProject, waitForIndexes, monitor);
+			if (secondaryTypePaths.size() > 0) {
+				Map types = (Map) secondaryTypePaths.get(packageName==null?"":packageName); //$NON-NLS-1$
+				if (types != null && types.size() > 0) {
+					IType type = (IType) types.get(typeName);
+					if (type != null) {
+						if (JavaModelManager.VERBOSE) {
+							Util.verbose("NameLookup FIND SECONDARY TYPES:"); //$NON-NLS-1$
+							Util.verbose(" -> pkg name: " + packageName);  //$NON-NLS-1$
+							Util.verbose(" -> type name: " + typeName);  //$NON-NLS-1$
+							Util.verbose(" -> project: "+project.getElementName()); //$NON-NLS-1$
+							Util.verbose(" -> type: " + type.getElementName());  //$NON-NLS-1$
+						}
+						return type;
+					}
+				}
+			}
+		}
+		catch (JavaModelException jme) {
+			// give up
+		}
+		return null;
+	}
+
+	/**
+	 * Find type considering secondary types but without waiting for indexes.
+	 * It means that secondary types may be not found under certain circumstances...
+	 * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=118789"
+	 */
+	public Answer findType(String typeName, String packageName, boolean partialMatch, int acceptFlags, boolean checkRestrictions) {
+		return findType(typeName,
+			packageName,
+			partialMatch,
+			acceptFlags,
+			true/* consider secondary types */,
+			false/* do NOT wait for indexes */,
+			checkRestrictions,
+			null);
+	}
+
+	/**
+	 * Find type. Considering secondary types and waiting for indexes depends on given corresponding parameters.
+	 */
+	public Answer findType(
+			String typeName,
+			String packageName,
+			boolean partialMatch,
+			int acceptFlags,
+			boolean considerSecondaryTypes,
+			boolean waitForIndexes,
+			boolean checkRestrictions,
+			IProgressMonitor monitor) {
+		if (packageName == null || packageName.length() == 0) {
+			packageName= IPackageFragment.DEFAULT_PACKAGE_NAME;
+		} else if (typeName.length() > 0 && ScannerHelper.isLowerCase(typeName.charAt(0))) {
+			// see if this is a known package and not a type
+			if (findPackageFragments(packageName + "." + typeName, false) != null) return null; //$NON-NLS-1$
+		}
+
+		// Look for concerned package fragments
+		JavaElementRequestor elementRequestor = new JavaElementRequestor();
+		seekPackageFragments(packageName, false, elementRequestor);
+		IPackageFragment[] packages= elementRequestor.getPackageFragments();
+
+		// Try to find type in package fragments list
+		IType type = null;
+		int length= packages.length;
+		HashSet projects = null;
+		IJavaProject javaProject = null;
+		Answer suggestedAnswer = null;
+		for (int i= 0; i < length; i++) {
+			type = findType(typeName, packages[i], partialMatch, acceptFlags);
+			if (type != null) {
+				AccessRestriction accessRestriction = null;
+				if (checkRestrictions) {
+					accessRestriction = getViolatedRestriction(typeName, packageName, type, accessRestriction);
+				}
+				Answer answer = new Answer(type, accessRestriction);
+				if (!answer.ignoreIfBetter()) {
+					if (answer.isBetter(suggestedAnswer))
+						return answer;
+				} else if (answer.isBetter(suggestedAnswer))
+					// remember suggestion and keep looking
+					suggestedAnswer = answer;
+			}
+			else if (suggestedAnswer == null && considerSecondaryTypes) {
+				if (javaProject == null) {
+					javaProject = packages[i].getJavaProject();
+				} else if (projects == null)  {
+					if (!javaProject.equals(packages[i].getJavaProject())) {
+						projects = new HashSet(3);
+						projects.add(javaProject);
+						projects.add(packages[i].getJavaProject());
+					}
+				} else {
+					projects.add(packages[i].getJavaProject());
+				}
+			}
+		}
+		if (suggestedAnswer != null)
+			// no better answer was found
+			return suggestedAnswer;
+
+		// If type was not found, try to find it as secondary in source folders
+		if (considerSecondaryTypes && javaProject != null) {
+			if (projects == null) {
+				type = findSecondaryType(packageName, typeName, javaProject, waitForIndexes, monitor);
+			} else {
+				Iterator allProjects = projects.iterator();
+				while (type == null && allProjects.hasNext()) {
+					type = findSecondaryType(packageName, typeName, (IJavaProject) allProjects.next(), waitForIndexes, monitor);
+				}
+			}
+		}
+		return type == null ? null : new Answer(type, null);
+	}
+
+	private AccessRestriction getViolatedRestriction(String typeName, String packageName, IType type, AccessRestriction accessRestriction) {
+		PackageFragmentRoot root = (PackageFragmentRoot) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		ClasspathEntry entry = (ClasspathEntry) this.rootToResolvedEntries.get(root);
+		if (entry != null) { // reverse map always contains resolved CP entry
+			AccessRuleSet accessRuleSet = entry.getAccessRuleSet();
+			if (accessRuleSet != null) {
+				// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
+				char[][] packageChars = CharOperation.splitOn('.', packageName.toCharArray());
+				char[] typeChars = typeName.toCharArray();
+				accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, typeChars, '/'));
+			}
+		}
+		return accessRestriction;
+	}
+
+	/**
+	 * Returns the first type in the given package whose name
+	 * matches the given (unqualified) name, or <code>null</code> if none
+	 * exist. Specifying a <code>null</code> package will result in no matches.
+	 * The domain of the search is bounded by the Java project from which
+	 * this name lookup was obtained.
+	 *
+	 * @param name the name of the type to find
+	 * @param pkg the package to search
+	 * @param partialMatch partial name matches qualify when <code>true</code>,
+	 *	only exact name matches qualify when <code>false</code>
+	 * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces
+	 * 	are desired results. If no flags are specified, all types are returned.
+	 * @param considerSecondaryTypes flag to know whether secondary types has to be considered
+	 * 	during the search
+	 *
+	 * @see #ACCEPT_CLASSES
+	 * @see #ACCEPT_INTERFACES
+	 * @see #ACCEPT_ENUMS
+	 * @see #ACCEPT_ANNOTATIONS
+	 */
+	public IType findType(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, boolean considerSecondaryTypes) {
+		IType type = findType(name, pkg, partialMatch, acceptFlags);
+		if (type == null && considerSecondaryTypes) {
+			type = findSecondaryType(pkg.getElementName(), name, pkg.getJavaProject(), false, null);
+		}
+		return type;
+	}
+
+	/**
+	 * Returns the first type in the given package whose name
+	 * matches the given (unqualified) name, or <code>null</code> if none
+	 * exist. Specifying a <code>null</code> package will result in no matches.
+	 * The domain of the search is bounded by the Java project from which
+	 * this name lookup was obtained.
+	 * <br>
+	 *	Note that this method does not find secondary types.
+	 * <br>
+	 * @param name the name of the type to find
+	 * @param pkg the package to search
+	 * @param partialMatch partial name matches qualify when <code>true</code>,
+	 *	only exact name matches qualify when <code>false</code>
+	 * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces
+	 * 	are desired results. If no flags are specified, all types are returned.
+	 *
+	 * @see #ACCEPT_CLASSES
+	 * @see #ACCEPT_INTERFACES
+	 * @see #ACCEPT_ENUMS
+	 * @see #ACCEPT_ANNOTATIONS
+	 */
+	public IType findType(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags) {
+		if (pkg == null) return null;
+
+		// Return first found (ignore duplicates).
+		SingleTypeRequestor typeRequestor = new SingleTypeRequestor();
+		seekTypes(name, pkg, partialMatch, acceptFlags, typeRequestor);
+		return typeRequestor.getType();
+	}
+
+	/**
+	 * Returns the type specified by the qualified name, or <code>null</code>
+	 * if none exist. The domain of
+	 * the search is bounded by the Java project from which this name lookup was obtained.
+	 *
+	 * @param name the name of the type to find
+	 * @param partialMatch partial name matches qualify when <code>true</code>,
+	 *	only exact name matches qualify when <code>false</code>
+	 * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces
+	 * 	are desired results. If no flags are specified, all types are returned.
+	 *
+	 * @see #ACCEPT_CLASSES
+	 * @see #ACCEPT_INTERFACES
+	 * @see #ACCEPT_ENUMS
+	 * @see #ACCEPT_ANNOTATIONS
+	 */
+	public IType findType(String name, boolean partialMatch, int acceptFlags) {
+		NameLookup.Answer answer = findType(name, partialMatch, acceptFlags, false/*don't check restrictions*/);
+		return answer == null ? null : answer.type;
+	}
+
+	public Answer findType(String name, boolean partialMatch, int acceptFlags, boolean checkRestrictions) {
+		return findType(name, partialMatch, acceptFlags, true/*consider secondary types*/, true/*wait for indexes*/, checkRestrictions, null);
+	}
+	public Answer findType(String name, boolean partialMatch, int acceptFlags, boolean considerSecondaryTypes, boolean waitForIndexes, boolean checkRestrictions, IProgressMonitor monitor) {
+		int index= name.lastIndexOf('.');
+		String className= null, packageName= null;
+		if (index == -1) {
+			packageName= IPackageFragment.DEFAULT_PACKAGE_NAME;
+			className= name;
+		} else {
+			packageName= name.substring(0, index);
+			className= name.substring(index + 1);
+		}
+		return findType(className, packageName, partialMatch, acceptFlags, considerSecondaryTypes, waitForIndexes, checkRestrictions, monitor);
+	}
+
+	private IType getMemberType(IType type, String name, int dot) {
+		while (dot != -1) {
+			int start = dot+1;
+			dot = name.indexOf('.', start);
+			String typeName = name.substring(start, dot == -1 ? name.length() : dot);
+			type = type.getType(typeName);
+		}
+		return type;
+	}
+
+	public boolean isPackage(String[] pkgName) {
+		return this.packageFragments.get(pkgName) != null;
+	}
+
+	/**
+	 * Returns true if the given element's name matches the
+	 * specified <code>searchName</code>, otherwise false.
+	 *
+	 * <p>The <code>partialMatch</code> argument indicates partial matches
+	 * should be considered.
+	 * NOTE: in partialMatch mode, the case will be ignored, and the searchName must already have
+	 *          been lowercased.
+	 */
+	protected boolean nameMatches(String searchName, IJavaElement element, boolean partialMatch) {
+		if (partialMatch) {
+			// partial matches are used in completion mode, thus case insensitive mode
+			return element.getElementName().toLowerCase().startsWith(searchName);
+		} else {
+			return element.getElementName().equals(searchName);
+		}
+	}
+
+	/**
+	 * Returns true if the given cu's name matches the
+	 * specified <code>searchName</code>, otherwise false.
+	 *
+	 * <p>The <code>partialMatch</code> argument indicates partial matches
+	 * should be considered.
+	 * NOTE: in partialMatch mode, the case will be ignored, and the searchName must already have
+	 *          been lowercased.
+	 */
+	protected boolean nameMatches(String searchName, ICompilationUnit cu, boolean partialMatch) {
+		if (partialMatch) {
+			// partial matches are used in completion mode, thus case insensitive mode
+			return cu.getElementName().toLowerCase().startsWith(searchName);
+		} else {
+			return Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), searchName);
+		}
+	}
+
+	/**
+	 * Notifies the given requestor of all package fragments with the
+	 * given name. Checks the requestor at regular intervals to see if the
+	 * requestor has canceled. The domain of
+	 * the search is bounded by the <code>IJavaProject</code>
+	 * this <code>NameLookup</code> was obtained from.
+	 *
+	 * @param partialMatch partial name matches qualify when <code>true</code>;
+	 *	only exact name matches qualify when <code>false</code>
+	 */
+	public void seekPackageFragments(String name, boolean partialMatch, IJavaElementRequestor requestor) {
+/*		if (VERBOSE) {
+			Util.verbose(" SEEKING PACKAGE FRAGMENTS");  //$NON-NLS-1$
+			Util.verbose(" -> name: " + name);  //$NON-NLS-1$
+			Util.verbose(" -> partial match:" + partialMatch);  //$NON-NLS-1$
+		}
+*/		if (partialMatch) {
+			String[] splittedName = Util.splitOn('.', name, 0, name.length());
+			Object[][] keys = this.packageFragments.keyTable;
+			for (int i = 0, length = keys.length; i < length; i++) {
+				if (requestor.isCanceled())
+					return;
+				String[] pkgName = (String[]) keys[i];
+				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName, partialMatch)) {
+					Object value = this.packageFragments.valueTable[i];
+					if (value instanceof PackageFragmentRoot) {
+						PackageFragmentRoot root = (PackageFragmentRoot) value;
+						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));
+					} else {
+						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+						for (int j = 0, length2 = roots.length; j < length2; j++) {
+							if (requestor.isCanceled())
+								return;
+							PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
+							requestor.acceptPackageFragment(root.getPackageFragment(pkgName));
+						}
+					}
+				}
+			}
+		} else {
+			String[] splittedName = Util.splitOn('.', name, 0, name.length());
+			int pkgIndex = this.packageFragments.getIndex(splittedName);
+			if (pkgIndex != -1) {
+				Object value = this.packageFragments.valueTable[pkgIndex];
+				// reuse existing String[]
+				String[] pkgName = (String[]) this.packageFragments.keyTable[pkgIndex];
+				if (value instanceof PackageFragmentRoot) {
+					requestor.acceptPackageFragment(((PackageFragmentRoot) value).getPackageFragment(pkgName));
+				} else {
+					IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+					if (roots != null) {
+						for (int i = 0, length = roots.length; i < length; i++) {
+							if (requestor.isCanceled())
+								return;
+							PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
+							requestor.acceptPackageFragment(root.getPackageFragment(pkgName));
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Notifies the given requestor of all types (classes and interfaces) in the
+	 * given package fragment with the given (unqualified) name.
+	 * Checks the requestor at regular intervals to see if the requestor
+	 * has canceled. If the given package fragment is <code>null</code>, all types in the
+	 * project whose simple name matches the given name are found.
+	 *
+	 * @param name The name to search
+	 * @param pkg The corresponding package fragment
+	 * @param partialMatch partial name matches qualify when <code>true</code>;
+	 *	only exact name matches qualify when <code>false</code>
+	 * @param acceptFlags a bit mask describing if classes, interfaces or both classes and interfaces
+	 * 	are desired results. If no flags are specified, all types are returned.
+	 * @param requestor The requestor that collects the result
+	 *
+	 * @see #ACCEPT_CLASSES
+	 * @see #ACCEPT_INTERFACES
+	 * @see #ACCEPT_ENUMS
+	 * @see #ACCEPT_ANNOTATIONS
+	 */
+	public void seekTypes(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) {
+/*		if (VERBOSE) {
+			Util.verbose(" SEEKING TYPES");  //$NON-NLS-1$
+			Util.verbose(" -> name: " + name);  //$NON-NLS-1$
+			Util.verbose(" -> pkg: " + ((JavaElement) pkg).toStringWithAncestors());  //$NON-NLS-1$
+			Util.verbose(" -> partial match:" + partialMatch);  //$NON-NLS-1$
+		}
+*/
+		String matchName= partialMatch ? name.toLowerCase() : name;
+		if (pkg == null) {
+			findAllTypes(matchName, partialMatch, acceptFlags, requestor);
+			return;
+		}
+		PackageFragmentRoot root= (PackageFragmentRoot) pkg.getParent();
+		try {
+
+			// look in working copies first
+			int firstDot = -1;
+			String topLevelTypeName = null;
+			int packageFlavor= root.internalKind();
+			if (this.typesInWorkingCopies != null || packageFlavor == IPackageFragmentRoot.K_SOURCE) {
+				firstDot = matchName.indexOf('.');
+				if (!partialMatch)
+					topLevelTypeName = firstDot == -1 ? matchName : matchName.substring(0, firstDot);
+			}
+			if (this.typesInWorkingCopies != null) {
+				if (seekTypesInWorkingCopies(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor))
+					return;
+			}
+
+			// look in model
+			switch (packageFlavor) {
+				case IPackageFragmentRoot.K_BINARY :
+					matchName= matchName.replace('.', '$');
+					seekTypesInBinaryPackage(matchName, pkg, partialMatch, acceptFlags, requestor);
+					break;
+				case IPackageFragmentRoot.K_SOURCE :
+					seekTypesInSourcePackage(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor);
+					if (matchName.indexOf('$') != -1) {
+						matchName= matchName.replace('$', '.');
+						firstDot = matchName.indexOf('.');
+						if (!partialMatch)
+							topLevelTypeName = firstDot == -1 ? matchName : matchName.substring(0, firstDot);
+						seekTypesInSourcePackage(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor);
+					}
+					break;
+				default :
+					return;
+			}
+		} catch (JavaModelException e) {
+			return;
+		}
+	}
+
+	/**
+	 * Performs type search in a binary package.
+	 */
+	protected void seekTypesInBinaryPackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) {
+		long start = -1;
+		if (VERBOSE)
+			start = System.currentTimeMillis();
+		try {
+			if (!partialMatch) {
+				// exact match
+				if (requestor.isCanceled()) return;
+				ClassFile classFile =  new ClassFile((PackageFragment) pkg, name);
+				if (classFile.existsUsingJarTypeCache()) {
+					IType type = classFile.getType();
+					if (acceptType(type, acceptFlags, false/*not a source type*/)) {
+						requestor.acceptType(type);
+					}
+				}
+			} else {
+				IJavaElement[] classFiles= null;
+				try {
+					classFiles= pkg.getChildren();
+				} catch (JavaModelException npe) {
+					return; // the package is not present
+				}
+				int length= classFiles.length;
+				String unqualifiedName = name;
+				int index = name.lastIndexOf('$');
+				if (index != -1) {
+					//the type name of the inner type
+					unqualifiedName = Util.localTypeName(name, index, name.length());
+					// unqualifiedName is empty if the name ends with a '$' sign.
+					// See http://dev.eclipse.org/bugs/show_bug.cgi?id=14642
+				}
+				int matchLength = name.length();
+				for (int i = 0; i < length; i++) {
+					if (requestor.isCanceled())
+						return;
+					IJavaElement classFile= classFiles[i];
+					// MatchName will never have the extension ".class" and the elementName always will.
+					String elementName = classFile.getElementName();
+					if (elementName.regionMatches(true /*ignore case*/, 0, name, 0, matchLength)) {
+						IType type = ((ClassFile) classFile).getType();
+						String typeName = type.getElementName();
+						if (typeName.length() > 0 && !Character.isDigit(typeName.charAt(0))) { //not an anonymous type
+							if (nameMatches(unqualifiedName, type, true/*partial match*/) && acceptType(type, acceptFlags, false/*not a source type*/))
+								requestor.acceptType(type);
+						}
+					}
+				}
+			}
+		} finally {
+			if (VERBOSE)
+				this.timeSpentInSeekTypesInBinaryPackage += System.currentTimeMillis()-start;
+		}
+	}
+
+	/**
+	 * Performs type search in a source package.
+	 */
+	protected void seekTypesInSourcePackage(
+			String name,
+			IPackageFragment pkg,
+			int firstDot,
+			boolean partialMatch,
+			String topLevelTypeName,
+			int acceptFlags,
+			IJavaElementRequestor requestor) {
+
+		long start = -1;
+		if (VERBOSE)
+			start = System.currentTimeMillis();
+		try {
+			if (!partialMatch) {
+				try {
+					IJavaElement[] compilationUnits = pkg.getChildren();
+					for (int i = 0, length = compilationUnits.length; i < length; i++) {
+						if (requestor.isCanceled())
+							return;
+						IJavaElement cu = compilationUnits[i];
+						String cuName = cu.getElementName();
+						int lastDot = cuName.lastIndexOf('.');
+						if (lastDot != topLevelTypeName.length() || !topLevelTypeName.regionMatches(0, cuName, 0, lastDot))
+							continue;
+
+						// https://bugs.eclipse.org/bugs/show_bug.cgi?id=351697
+						// If we are looking at source location, just ignore binary types
+						if (!(cu instanceof ICompilationUnit))
+							continue;
+						IType type = ((ICompilationUnit) cu).getType(topLevelTypeName);
+						type = getMemberType(type, name, firstDot);
+						if (acceptType(type, acceptFlags, true/*a source type*/)) { // accept type checks for existence
+							requestor.acceptType(type);
+							break;  // since an exact match was requested, no other matching type can exist
+						}
+					}
+				} catch (JavaModelException e) {
+					// package doesn't exist -> ignore
+				}
+			} else {
+				try {
+					String cuPrefix = firstDot == -1 ? name : name.substring(0, firstDot);
+					IJavaElement[] compilationUnits = pkg.getChildren();
+					for (int i = 0, length = compilationUnits.length; i < length; i++) {
+						if (requestor.isCanceled())
+							return;
+						IJavaElement cu = compilationUnits[i];
+						if (!cu.getElementName().toLowerCase().startsWith(cuPrefix))
+							continue;
+						try {
+							IType[] types = ((ICompilationUnit) cu).getTypes();
+							for (int j = 0, typeLength = types.length; j < typeLength; j++)
+								seekTypesInTopLevelType(name, firstDot, types[j], requestor, acceptFlags);
+						} catch (JavaModelException e) {
+							// cu doesn't exist -> ignore
+						}
+					}
+				} catch (JavaModelException e) {
+					// package doesn't exist -> ignore
+				}
+			}
+		} finally {
+			if (VERBOSE)
+				this.timeSpentInSeekTypesInSourcePackage += System.currentTimeMillis()-start;
+		}
+	}
+
+	/**
+	 * Notifies the given requestor of all types (classes and interfaces) in the
+	 * given type with the given (possibly qualified) name. Checks
+	 * the requestor at regular intervals to see if the requestor
+	 * has canceled.
+	 */
+	protected boolean seekTypesInType(String prefix, int firstDot, IType type, IJavaElementRequestor requestor, int acceptFlags) {
+		IType[] types= null;
+		try {
+			types= type.getTypes();
+		} catch (JavaModelException npe) {
+			return false; // the enclosing type is not present
+		}
+		int length= types.length;
+		if (length == 0) return false;
+
+		String memberPrefix = prefix;
+		boolean isMemberTypePrefix = false;
+		if (firstDot != -1) {
+			memberPrefix= prefix.substring(0, firstDot);
+			isMemberTypePrefix = true;
+		}
+		for (int i= 0; i < length; i++) {
+			if (requestor.isCanceled())
+				return false;
+			IType memberType= types[i];
+			if (memberType.getElementName().toLowerCase().startsWith(memberPrefix))
+				if (isMemberTypePrefix) {
+					String subPrefix = prefix.substring(firstDot + 1, prefix.length());
+					return seekTypesInType(subPrefix, subPrefix.indexOf('.'), memberType, requestor, acceptFlags);
+				} else {
+					if (acceptType(memberType, acceptFlags, true/*a source type*/)) {
+						requestor.acceptMemberType(memberType);
+						return true;
+					}
+				}
+		}
+		return false;
+	}
+
+	protected boolean seekTypesInTopLevelType(String prefix, int firstDot, IType topLevelType, IJavaElementRequestor requestor, int acceptFlags) {
+		if (!topLevelType.getElementName().toLowerCase().startsWith(prefix))
+			return false;
+		if (firstDot == -1) {
+			if (acceptType(topLevelType, acceptFlags, true/*a source type*/)) {
+				requestor.acceptType(topLevelType);
+				return true;
+			}
+		} else {
+			return seekTypesInType(prefix, firstDot, topLevelType, requestor, acceptFlags);
+		}
+		return false;
+	}
+
+	/*
+	 * Seeks the type with the given name in the map of types with precedence (coming from working copies)
+	 * Return whether a type has been found.
+	 */
+	protected boolean seekTypesInWorkingCopies(
+			String name,
+			IPackageFragment pkg,
+			int firstDot,
+			boolean partialMatch,
+			String topLevelTypeName,
+			int acceptFlags,
+			IJavaElementRequestor requestor) {
+
+		if (!partialMatch) {
+			HashMap typeMap = (HashMap) (this.typesInWorkingCopies == null ? null : this.typesInWorkingCopies.get(pkg));
+			if (typeMap != null) {
+				Object object = typeMap.get(topLevelTypeName);
+				if (object instanceof IType) {
+					IType type = getMemberType((IType) object, name, firstDot);
+					if (acceptType(type, acceptFlags, true/*a source type*/)) {
+						requestor.acceptType(type);
+						return true; // don't continue with compilation unit
+					}
+				} else if (object instanceof IType[]) {
+					if (object == NO_TYPES) {
+						// all types where deleted -> type is hidden, OR it is the fake type package-info
+						String packageInfoName = String.valueOf(TypeConstants.PACKAGE_INFO_NAME);
+						if (packageInfoName.equals(name))
+							requestor.acceptType(pkg.getCompilationUnit(packageInfoName.concat(SUFFIX_STRING_java)).getType(name));
+						return true;
+					}
+					IType[] topLevelTypes = (IType[]) object;
+					for (int i = 0, length = topLevelTypes.length; i < length; i++) {
+						if (requestor.isCanceled())
+							return false;
+						IType type = getMemberType(topLevelTypes[i], name, firstDot);
+						if (acceptType(type, acceptFlags, true/*a source type*/)) {
+							requestor.acceptType(type);
+							return true; // return the first one
+						}
+					}
+				}
+			}
+		} else {
+			HashMap typeMap = (HashMap) (this.typesInWorkingCopies == null ? null : this.typesInWorkingCopies.get(pkg));
+			if (typeMap != null) {
+				Iterator iterator = typeMap.values().iterator();
+				while (iterator.hasNext()) {
+					if (requestor.isCanceled())
+						return false;
+					Object object = iterator.next();
+					if (object instanceof IType) {
+						seekTypesInTopLevelType(name, firstDot, (IType) object, requestor, acceptFlags);
+					} else if (object instanceof IType[]) {
+						IType[] topLevelTypes = (IType[]) object;
+						for (int i = 0, length = topLevelTypes.length; i < length; i++)
+							seekTypesInTopLevelType(name, firstDot, topLevelTypes[i], requestor, acceptFlags);
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
new file mode 100644
index 0000000..ef819df
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+
+public abstract class NamedMember extends Member {
+
+	/*
+	 * This element's name, or an empty <code>String</code> if this
+	 * element does not have a name.
+	 */
+	protected String name;
+
+	public NamedMember(JavaElement parent, String name) {
+		super(parent);
+		this.name = name;
+	}
+
+	private void appendTypeParameters(StringBuffer buffer) throws JavaModelException {
+		ITypeParameter[] typeParameters = getTypeParameters();
+		int length = typeParameters.length;
+		if (length == 0) return;
+		buffer.append('<');
+		for (int i = 0; i < length; i++) {
+			ITypeParameter typeParameter = typeParameters[i];
+			buffer.append(typeParameter.getElementName());
+			String[] bounds = typeParameter.getBounds();
+			int boundsLength = bounds.length;
+			if (boundsLength > 0) {
+				buffer.append(" extends "); //$NON-NLS-1$
+				for (int j = 0; j < boundsLength; j++) {
+					buffer.append(bounds[j]);
+					if (j < boundsLength-1)
+						buffer.append(" & "); //$NON-NLS-1$
+				}
+			}
+			if (i < length-1)
+				buffer.append(", "); //$NON-NLS-1$
+		}
+		buffer.append('>');
+	}
+
+	public String getElementName() {
+		return this.name;
+	}
+
+	protected String getKey(IField field, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+
+		// declaring class
+		String declaringKey = getKey((IType) field.getParent(), forceOpen);
+		key.append(declaringKey);
+
+		// field name
+		key.append('.');
+		key.append(field.getElementName());
+
+		return key.toString();
+	}
+
+	protected String getKey(IMethod method, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+
+		// declaring class
+		String declaringKey = getKey((IType) method.getParent(), forceOpen);
+		key.append(declaringKey);
+
+		// selector
+		key.append('.');
+		String selector = method.getElementName();
+		key.append(selector);
+
+		// type parameters
+		if (forceOpen) {
+			ITypeParameter[] typeParameters = method.getTypeParameters();
+			int length = typeParameters.length;
+			if (length > 0) {
+				key.append('<');
+				for (int i = 0; i < length; i++) {
+					ITypeParameter typeParameter = typeParameters[i];
+					String[] bounds = typeParameter.getBounds();
+					int boundsLength = bounds.length;
+					char[][] boundSignatures = new char[boundsLength][];
+					for (int j = 0; j < boundsLength; j++) {
+						boundSignatures[j] = Signature.createCharArrayTypeSignature(bounds[j].toCharArray(), method.isBinary());
+						CharOperation.replace(boundSignatures[j], '.', '/');
+					}
+					char[] sig = Signature.createTypeParameterSignature(typeParameter.getElementName().toCharArray(), boundSignatures);
+					key.append(sig);
+				}
+				key.append('>');
+			}
+		}
+
+		// parameters
+		key.append('(');
+		String[] parameters = method.getParameterTypes();
+		for (int i = 0, length = parameters.length; i < length; i++)
+			key.append(parameters[i].replace('.', '/'));
+		key.append(')');
+
+		// return type
+		if (forceOpen)
+			key.append(method.getReturnType().replace('.', '/'));
+		else
+			key.append('V');
+
+		return key.toString();
+	}
+
+	protected String getKey(IType type, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+		key.append('L');
+		String packageName = type.getPackageFragment().getElementName();
+		key.append(packageName.replace('.', '/'));
+		if (packageName.length() > 0)
+			key.append('/');
+		String typeQualifiedName = type.getTypeQualifiedName('$');
+		ICompilationUnit cu = (ICompilationUnit) type.getAncestor(IJavaElement.COMPILATION_UNIT);
+		if (cu != null) {
+			String cuName = cu.getElementName();
+			String mainTypeName = cuName.substring(0, cuName.lastIndexOf('.'));
+			int end = typeQualifiedName.indexOf('$');
+			if (end == -1)
+				end = typeQualifiedName.length();
+			String topLevelTypeName = typeQualifiedName.substring(0, end);
+			if (!mainTypeName.equals(topLevelTypeName)) {
+				key.append(mainTypeName);
+				key.append('~');
+			}
+		}
+		key.append(typeQualifiedName);
+		key.append(';');
+		return key.toString();
+	}
+
+	protected String getFullyQualifiedParameterizedName(String fullyQualifiedName, String uniqueKey) throws JavaModelException {
+		String[] typeArguments = new BindingKey(uniqueKey).getTypeArguments();
+		int length = typeArguments.length;
+		if (length == 0) return fullyQualifiedName;
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(fullyQualifiedName);
+		buffer.append('<');
+		for (int i = 0; i < length; i++) {
+			String typeArgument = typeArguments[i];
+			buffer.append(Signature.toString(typeArgument));
+			if (i < length-1)
+				buffer.append(',');
+		}
+		buffer.append('>');
+		return buffer.toString();
+	}
+
+	protected IPackageFragment getPackageFragment() {
+		return null;
+	}
+
+	public String getFullyQualifiedName(char enclosingTypeSeparator, boolean showParameters) throws JavaModelException {
+		String packageName = getPackageFragment().getElementName();
+		if (packageName.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
+			return getTypeQualifiedName(enclosingTypeSeparator, showParameters);
+		}
+		return packageName + '.' + getTypeQualifiedName(enclosingTypeSeparator, showParameters);
+	}
+
+	public String getTypeQualifiedName(char enclosingTypeSeparator, boolean showParameters) throws JavaModelException {
+		NamedMember declaringType;
+		switch (this.parent.getElementType()) {
+			case IJavaElement.COMPILATION_UNIT:
+				if (showParameters) {
+					StringBuffer buffer = new StringBuffer(this.name);
+					appendTypeParameters(buffer);
+					return buffer.toString();
+				}
+				return this.name;
+			case IJavaElement.CLASS_FILE:
+				String classFileName = this.parent.getElementName();
+				String typeName;
+				if (classFileName.indexOf('$') == -1) {
+					// top level class file: name of type is same as name of class file
+					typeName = this.name;
+				} else {
+					// anonymous or local class file
+					typeName = classFileName.substring(0, classFileName.lastIndexOf('.'))/*remove .class*/.replace('$', enclosingTypeSeparator);
+				}
+				if (showParameters) {
+					StringBuffer buffer = new StringBuffer(typeName);
+					appendTypeParameters(buffer);
+					return buffer.toString();
+				}
+				return typeName;
+			case IJavaElement.TYPE:
+				declaringType = (NamedMember) this.parent;
+				break;
+			case IJavaElement.FIELD:
+			case IJavaElement.INITIALIZER:
+			case IJavaElement.METHOD:
+				declaringType = (NamedMember) ((IMember) this.parent).getDeclaringType();
+				break;
+			default:
+				return null;
+		}
+		StringBuffer buffer = new StringBuffer(declaringType.getTypeQualifiedName(enclosingTypeSeparator, showParameters));
+		buffer.append(enclosingTypeSeparator);
+		String simpleName = this.name.length() == 0 ? getOccurrenceCountSignature() : this.name;
+		buffer.append(simpleName);
+		if (showParameters) {
+			appendTypeParameters(buffer);
+		}
+		return buffer.toString();
+	}
+	/*
+	 * Returns the String representation of the occurrence count for this element.
+	 * The occurrence count is a unique number representation to identify the particular element.
+	 *
+	 * @return the occurrence count for this element in the form of String
+	 */
+	protected String getOccurrenceCountSignature() {
+		return Integer.toString(this.occurrenceCount);
+	}
+	protected ITypeParameter[] getTypeParameters() throws JavaModelException {
+		return null;
+	}
+
+	/**
+	 * @see IType#resolveType(String)
+	 */
+	public String[][] resolveType(String typeName) throws JavaModelException {
+		return resolveType(typeName, DefaultWorkingCopyOwner.PRIMARY);
+	}
+
+	/**
+	 * @see IType#resolveType(String, WorkingCopyOwner)
+	 */
+	public String[][] resolveType(String typeName, WorkingCopyOwner owner) throws JavaModelException {
+		JavaProject project = (JavaProject) getJavaProject();
+		SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
+
+		class TypeResolveRequestor implements ISelectionRequestor {
+			String[][] answers = null;
+			public void acceptType(char[] packageName, char[] tName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+				String[] answer = new String[]  {new String(packageName), new String(tName) };
+				if (this.answers == null) {
+					this.answers = new String[][]{ answer };
+				} else {
+					// grow
+					int length = this.answers.length;
+					System.arraycopy(this.answers, 0, this.answers = new String[length+1][], 0, length);
+					this.answers[length] = answer;
+				}
+			}
+			public void acceptError(CategorizedProblem error) {
+				// ignore
+			}
+			public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+				// ignore
+			}
+			public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, char[][] typeParameterNames, char[][][] typeParameterBoundNames, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+				// ignore
+			}
+			public void acceptPackage(char[] packageName){
+				// ignore
+			}
+			public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
+				// ignore
+			}
+			public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, int selectorStart, int selcetorEnd, char[] typeParameterName, boolean isDeclaration, int start, int end) {
+				// ignore
+			}
+
+		}
+		TypeResolveRequestor requestor = new TypeResolveRequestor();
+		SelectionEngine engine =
+			new SelectionEngine(environment, requestor, project.getOptions(true), owner);
+
+		engine.selectType(typeName.toCharArray(), (IType) this);
+		if (NameLookup.VERBOSE) {
+			System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return requestor.answers;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NonJavaResource.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NonJavaResource.java
new file mode 100644
index 0000000..7c9a3b0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NonJavaResource.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jdt.core.IJarEntryResource;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class NonJavaResource  extends PlatformObject implements IJarEntryResource {
+
+	private static final IJarEntryResource[] NO_CHILDREN = new IJarEntryResource[0];
+	protected Object parent;
+	protected IResource resource;
+
+	public NonJavaResource(Object parent, IResource resource) {
+		this.parent = parent;
+		this.resource = resource;
+	}
+
+	public boolean equals(Object obj) {
+		if (! (obj instanceof NonJavaResource))
+			return false;
+		NonJavaResource other = (NonJavaResource) obj;
+		return this.parent.equals(other.parent) && this.resource.equals(other.resource);
+	}
+
+	public IJarEntryResource[] getChildren() {
+		if (this.resource instanceof IContainer) {
+			IResource[] members;
+			try {
+				members = ((IContainer) this.resource).members();
+			} catch (CoreException e) {
+				Util.log(e, "Could not retrieve children of " + this.resource.getFullPath()); //$NON-NLS-1$
+				return NO_CHILDREN;
+			}
+			int length = members.length;
+			if (length == 0)
+				return NO_CHILDREN;
+			IJarEntryResource[] children = new IJarEntryResource[length];
+			for (int i = 0; i < length; i++) {
+				children[i] = new NonJavaResource(this, members[i]);
+			}
+			return children;
+		}
+		return NO_CHILDREN;
+	}
+
+	public InputStream getContents() throws CoreException {
+		if (this.resource instanceof IFile)
+			return ((IFile) this.resource).getContents();
+		return null;
+	}
+
+	protected String getEntryName() {
+		String parentEntryName;
+		if (this.parent instanceof IPackageFragment) {
+			String elementName = ((IPackageFragment) this.parent).getElementName();
+			parentEntryName = elementName.length() == 0 ? "" : elementName .replace('.', '/') + '/'; //$NON-NLS-1$
+		} else if (this.parent instanceof IPackageFragmentRoot) {
+			parentEntryName = ""; //$NON-NLS-1$
+		} else {
+			parentEntryName = ((NonJavaResource) this.parent).getEntryName() + '/';
+		}
+		return parentEntryName + getName();
+	}
+
+	public IPath getFullPath() {
+		return new Path(getEntryName()).makeAbsolute();
+	}
+
+	public String getName() {
+		return this.resource.getName();
+	}
+
+	public IPackageFragmentRoot getPackageFragmentRoot() {
+		if (this.parent instanceof IPackageFragment) {
+			return (IPackageFragmentRoot) ((IPackageFragment) this.parent).getParent();
+		} else if (this.parent instanceof IPackageFragmentRoot) {
+			return (IPackageFragmentRoot) this.parent;
+		} else {
+			return ((NonJavaResource) this.parent).getPackageFragmentRoot();
+		}
+	}
+
+	public Object getParent() {
+		return this.parent;
+	}
+
+	public int hashCode() {
+		return Util.combineHashCodes(this.resource.hashCode(), this.parent.hashCode());
+	}
+
+	public boolean isFile() {
+		return this.resource instanceof IFile;
+	}
+
+	public boolean isReadOnly() {
+		return true;
+	}
+
+	public String toString() {
+		return "NonJavaResource["+getEntryName()+"]"; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NullBuffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NullBuffer.java
new file mode 100644
index 0000000..a6cd755
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NullBuffer.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.IOpenable;
+
+/**
+ * This class represents a null buffer. This buffer is used to represent a buffer for a class file
+ * that has no source attached.
+ */
+public class NullBuffer extends Buffer {
+	/**
+	 * Creates a new null buffer on an underlying resource.
+	 */
+	public NullBuffer(IFile file, IOpenable owner, boolean readOnly) {
+		super(file, owner, readOnly);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java
new file mode 100644
index 0000000..1497587
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.PerformanceStats;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.core.util.Util;
+
+
+/**
+ * Abstract class for implementations of java elements which are IOpenable.
+ *
+ * @see IJavaElement
+ * @see IOpenable
+ */
+public abstract class Openable extends JavaElement implements IOpenable, IBufferChangedListener {
+
+protected Openable(JavaElement parent) {
+	super(parent);
+}
+/**
+ * The buffer associated with this element has changed. Registers
+ * this element as being out of synch with its buffer's contents.
+ * If the buffer has been closed, this element is set as NOT out of
+ * synch with the contents.
+ *
+ * @see IBufferChangedListener
+ */
+public void bufferChanged(BufferChangedEvent event) {
+	if (event.getBuffer().isClosed()) {
+		JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+		getBufferManager().removeBuffer(event.getBuffer());
+	} else {
+		JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().add(this);
+	}
+}
+/**
+ * Builds this element's structure and properties in the given
+ * info object, based on this element's current contents (reuse buffer
+ * contents if this element has an open buffer, or resource contents
+ * if this element does not have an open buffer). Children
+ * are placed in the given newElements table (note, this element
+ * has already been placed in the newElements table). Returns true
+ * if successful, or false if an error is encountered while determining
+ * the structure of this element.
+ */
+protected abstract boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException;
+/*
+ * Returns whether this element can be removed from the Java model cache to make space.
+ */
+public boolean canBeRemovedFromCache() {
+	try {
+		return !hasUnsavedChanges();
+	} catch (JavaModelException e) {
+		return false;
+	}
+}
+/*
+ * Returns whether the buffer of this element can be removed from the Java model cache to make space.
+ */
+public boolean canBufferBeRemovedFromCache(IBuffer buffer) {
+	return !buffer.hasUnsavedChanges();
+}
+/**
+ * Close the buffer associated with this element, if any.
+ */
+protected void closeBuffer() {
+	if (!hasBuffer()) return; // nothing to do
+	IBuffer buffer = getBufferManager().getBuffer(this);
+	if (buffer != null) {
+		buffer.close();
+		buffer.removeBufferChangedListener(this);
+	}
+}
+/**
+ * This element is being closed.  Do any necessary cleanup.
+ */
+protected void closing(Object info) {
+	closeBuffer();
+}
+protected void codeComplete(
+		org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu,
+		org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip,
+		int position, CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		ITypeRoot typeRoot,
+		IProgressMonitor monitor) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	PerformanceStats performanceStats = CompletionEngine.PERF
+		? PerformanceStats.getStats(JavaModelManager.COMPLETION_PERF, this)
+		: null;
+	if(performanceStats != null) {
+		performanceStats.startRun(new String(cu.getFileName()) + " at " + position); //$NON-NLS-1$
+	}
+	IBuffer buffer = getBuffer();
+	if (buffer == null) {
+		return;
+	}
+	if (position < -1 || position > buffer.getLength()) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS));
+	}
+	JavaProject project = (JavaProject) getJavaProject();
+	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
+
+	// set unit to skip
+	environment.unitToSkip = unitToSkip;
+
+	// code complete
+	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
+	engine.complete(cu, position, 0, typeRoot);
+	if(performanceStats != null) {
+		performanceStats.endRun();
+	}
+	if (NameLookup.VERBOSE) {
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
+protected IJavaElement[] codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, WorkingCopyOwner owner) throws JavaModelException {
+	PerformanceStats performanceStats = SelectionEngine.PERF
+		? PerformanceStats.getStats(JavaModelManager.SELECTION_PERF, this)
+		: null;
+	if(performanceStats != null) {
+		performanceStats.startRun(new String(cu.getFileName()) + " at [" + offset + "," + length + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	}
+
+	JavaProject project = (JavaProject)getJavaProject();
+	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
+
+	SelectionRequestor requestor= new SelectionRequestor(environment.nameLookup, this);
+	IBuffer buffer = getBuffer();
+	if (buffer == null) {
+		return requestor.getElements();
+	}
+	int end= buffer.getLength();
+	if (offset < 0 || length < 0 || offset + length > end ) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS));
+	}
+
+	// fix for 1FVXGDK
+	SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true), owner);
+	engine.select(cu, offset, offset + length - 1);
+
+	if(performanceStats != null) {
+		performanceStats.endRun();
+	}
+	if (NameLookup.VERBOSE) {
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	return requestor.getElements();
+}
+/*
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return new OpenableElementInfo();
+}
+/**
+ * @see IJavaElement
+ */
+public boolean exists() {
+	if (JavaModelManager.getJavaModelManager().getInfo(this) != null)
+		return true;
+	switch (getElementType()) {
+		case IJavaElement.PACKAGE_FRAGMENT:
+			PackageFragmentRoot root = getPackageFragmentRoot();
+			if (root.isArchive()) {
+				// pkg in a jar -> need to open root to know if this pkg exists
+				JarPackageFragmentRootInfo rootInfo;
+				try {
+					rootInfo = (JarPackageFragmentRootInfo) root.getElementInfo();
+				} catch (JavaModelException e) {
+					return false;
+				}
+				return rootInfo.rawPackageInfo.containsKey(((PackageFragment) this).names);
+			}
+			break;
+		case IJavaElement.CLASS_FILE:
+			if (getPackageFragmentRoot().isArchive()) {
+				// class file in a jar -> need to open this class file to know if it exists
+				return super.exists();
+			}
+			break;
+	}
+	return validateExistence(resource()).isOK();
+}
+public String findRecommendedLineSeparator() throws JavaModelException {
+	IBuffer buffer = getBuffer();
+	String source = buffer == null ? null : buffer.getContents();
+	return Util.getLineSeparator(source, getJavaProject());
+}
+protected void generateInfos(Object info, HashMap newElements, IProgressMonitor monitor) throws JavaModelException {
+
+	if (JavaModelCache.VERBOSE){
+		String element;
+		switch (getElementType()) {
+			case JAVA_PROJECT:
+				element = "project"; //$NON-NLS-1$
+				break;
+			case PACKAGE_FRAGMENT_ROOT:
+				element = "root"; //$NON-NLS-1$
+				break;
+			case PACKAGE_FRAGMENT:
+				element = "package"; //$NON-NLS-1$
+				break;
+			case CLASS_FILE:
+				element = "class file"; //$NON-NLS-1$
+				break;
+			case COMPILATION_UNIT:
+				element = "compilation unit"; //$NON-NLS-1$
+				break;
+			default:
+				element = "element"; //$NON-NLS-1$
+		}
+		System.out.println(Thread.currentThread() +" OPENING " + element + " " + this.toStringWithAncestors()); //$NON-NLS-1$//$NON-NLS-2$
+	}
+
+	// open its ancestors if needed
+	openAncestors(newElements, monitor);
+
+	// validate existence
+	IResource underlResource = resource();
+	IStatus status = validateExistence(underlResource);
+	if (!status.isOK())
+		throw newJavaModelException(status);
+
+	if (monitor != null && monitor.isCanceled())
+		throw new OperationCanceledException();
+
+	 // puts the info before building the structure so that questions to the handle behave as if the element existed
+	 // (case of compilation units becoming working copies)
+	newElements.put(this, info);
+
+	// build the structure of the openable (this will open the buffer if needed)
+	try {
+		OpenableElementInfo openableElementInfo = (OpenableElementInfo)info;
+		boolean isStructureKnown = buildStructure(openableElementInfo, monitor, newElements, underlResource);
+		openableElementInfo.setIsStructureKnown(isStructureKnown);
+	} catch (JavaModelException e) {
+		newElements.remove(this);
+		throw e;
+	}
+
+	// remove out of sync buffer for this element
+	JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().remove(this);
+
+	if (JavaModelCache.VERBOSE) {
+		System.out.println(JavaModelManager.getJavaModelManager().cacheToString("-> ")); //$NON-NLS-1$
+	}
+}
+/**
+ * Note: a buffer with no unsaved changes can be closed by the Java Model
+ * since it has a finite number of buffers allowed open at one time. If this
+ * is the first time a request is being made for the buffer, an attempt is
+ * made to create and fill this element's buffer. If the buffer has been
+ * closed since it was first opened, the buffer is re-created.
+ *
+ * @see IOpenable
+ */
+public IBuffer getBuffer() throws JavaModelException {
+	if (hasBuffer()) {
+		// ensure element is open
+		Object info = getElementInfo();
+		IBuffer buffer = getBufferManager().getBuffer(this);
+		if (buffer == null) {
+			// try to (re)open a buffer
+			buffer = openBuffer(null, info);
+		}
+		if (buffer instanceof NullBuffer) {
+			return null;
+		}
+		return buffer;
+	} else {
+		return null;
+	}
+}
+/**
+ * Answers the buffer factory to use for creating new buffers
+ * @deprecated
+ */
+public IBufferFactory getBufferFactory(){
+	return getBufferManager().getDefaultBufferFactory();
+}
+
+/**
+ * Returns the buffer manager for this element.
+ */
+protected BufferManager getBufferManager() {
+	return BufferManager.getDefaultBufferManager();
+}
+/**
+ * Return my underlying resource. Elements that may not have a
+ * corresponding resource must override this method.
+ *
+ * @see IJavaElement
+ */
+public IResource getCorrespondingResource() throws JavaModelException {
+	return getUnderlyingResource();
+}
+/*
+ * @see IJavaElement
+ */
+public IOpenable getOpenable() {
+	return this;
+}
+
+
+
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+	IResource parentResource = this.parent.getUnderlyingResource();
+	if (parentResource == null) {
+		return null;
+	}
+	int type = parentResource.getType();
+	if (type == IResource.FOLDER || type == IResource.PROJECT) {
+		IContainer folder = (IContainer) parentResource;
+		IResource resource = folder.findMember(getElementName());
+		if (resource == null) {
+			throw newNotPresentException();
+		} else {
+			return resource;
+		}
+	} else {
+		return parentResource;
+	}
+}
+
+/**
+ * Returns true if this element may have an associated source buffer,
+ * otherwise false. Subclasses must override as required.
+ */
+protected boolean hasBuffer() {
+	return false;
+}
+/**
+ * @see IOpenable
+ */
+public boolean hasUnsavedChanges() throws JavaModelException{
+
+	if (isReadOnly() || !isOpen()) {
+		return false;
+	}
+	IBuffer buf = getBuffer();
+	if (buf != null && buf.hasUnsavedChanges()) {
+		return true;
+	}
+	// for package fragments, package fragment roots, and projects must check open buffers
+	// to see if they have an child with unsaved changes
+	int elementType = getElementType();
+	if (elementType == PACKAGE_FRAGMENT ||
+		elementType == PACKAGE_FRAGMENT_ROOT ||
+		elementType == JAVA_PROJECT ||
+		elementType == JAVA_MODEL) { // fix for 1FWNMHH
+		Enumeration openBuffers= getBufferManager().getOpenBuffers();
+		while (openBuffers.hasMoreElements()) {
+			IBuffer buffer= (IBuffer)openBuffers.nextElement();
+			if (buffer.hasUnsavedChanges()) {
+				IJavaElement owner= (IJavaElement)buffer.getOwner();
+				if (isAncestorOf(owner)) {
+					return true;
+				}
+			}
+		}
+	}
+
+	return false;
+}
+/**
+ * Subclasses must override as required.
+ *
+ * @see IOpenable
+ */
+public boolean isConsistent() {
+	return true;
+}
+/**
+ *
+ * @see IOpenable
+ */
+public boolean isOpen() {
+	return JavaModelManager.getJavaModelManager().getInfo(this) != null;
+}
+/**
+ * Returns true if this represents a source element.
+ * Openable source elements have an associated buffer created
+ * when they are opened.
+ */
+protected boolean isSourceElement() {
+	return false;
+}
+/**
+ * @see IJavaElement
+ */
+public boolean isStructureKnown() throws JavaModelException {
+	return ((OpenableElementInfo)getElementInfo()).isStructureKnown();
+}
+/**
+ * @see IOpenable
+ */
+public void makeConsistent(IProgressMonitor monitor) throws JavaModelException {
+	// only compilation units can be inconsistent
+	// other openables cannot be inconsistent so default is to do nothing
+}
+/**
+ * @see IOpenable
+ */
+public void open(IProgressMonitor pm) throws JavaModelException {
+	getElementInfo(pm);
+}
+
+/**
+ * Opens a buffer on the contents of this element, and returns
+ * the buffer, or returns <code>null</code> if opening fails.
+ * By default, do nothing - subclasses that have buffers
+ * must override as required.
+ */
+protected IBuffer openBuffer(IProgressMonitor pm, Object info) throws JavaModelException {
+	return null;
+}
+
+public IResource getResource() {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root != null) {
+		if (root.isExternal())
+			return null;
+		if (root.isArchive())
+			return root.resource(root);
+	}
+	return resource(root);
+}
+
+public IResource resource() {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root != null && root.isArchive())
+		return root.resource(root);
+	return resource(root);
+}
+
+protected abstract IResource resource(PackageFragmentRoot root);
+
+/**
+ * Returns whether the corresponding resource or associated file exists
+ */
+protected boolean resourceExists(IResource underlyingResource) {
+	return underlyingResource.isAccessible();
+}
+
+/**
+ * @see IOpenable
+ */
+public void save(IProgressMonitor pm, boolean force) throws JavaModelException {
+	if (isReadOnly()) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this));
+	}
+	IBuffer buf = getBuffer();
+	if (buf != null) { // some Openables (like a JavaProject) don't have a buffer
+		buf.save(pm, force);
+		makeConsistent(pm); // update the element info of this element
+	}
+}
+
+/**
+ * Find enclosing package fragment root if any
+ */
+public PackageFragmentRoot getPackageFragmentRoot() {
+	return (PackageFragmentRoot) getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+}
+
+/*
+ * Validates the existence of this openable. Returns a non ok status if it doesn't exist.
+ */
+abstract protected IStatus validateExistence(IResource underlyingResource);
+
+/*
+ * Opens the ancestors of this openable that are not yet opened, validating their existence.
+ */
+protected void openAncestors(HashMap newElements, IProgressMonitor monitor) throws JavaModelException {
+	Openable openableParent = (Openable)getOpenableParent();
+	if (openableParent != null && !openableParent.isOpen()) {
+		openableParent.generateInfos(openableParent.createElementInfo(), newElements, monitor);
+	}
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java
new file mode 100644
index 0000000..de533a9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/** Element info for IOpenable elements. */
+public class OpenableElementInfo extends JavaElementInfo {
+
+	/**
+	 * Collection of handles of immediate children of this
+	 * object. This is an empty array if this element has
+	 * no children.
+	 */
+	protected IJavaElement[] children = JavaElement.NO_ELEMENTS;
+	
+	/**
+	 * Is the structure of this element known
+	 * @see IJavaElement#isStructureKnown()
+	 */
+	protected boolean isStructureKnown = false;
+
+	public void addChild(IJavaElement child) {
+		int length = this.children.length;
+		if (length == 0) {
+			this.children = new IJavaElement[] {child};
+		} else {
+			for (int i = 0; i < length; i++) {
+				if (this.children[i].equals(child))
+					return; // already included
+			}
+			System.arraycopy(this.children, 0, this.children = new IJavaElement[length+1], 0, length);
+			this.children[length] = child;
+		}
+	}
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+	
+	/**
+	 * @see IJavaElement#isStructureKnown()
+	 */
+	public boolean isStructureKnown() {
+		return this.isStructureKnown;
+	}
+
+	public void removeChild(IJavaElement child) {
+		for (int i = 0, length = this.children.length; i < length; i++) {
+			IJavaElement element = this.children[i];
+			if (element.equals(child)) {
+				if (length == 1) {
+					this.children = JavaElement.NO_ELEMENTS;
+				} else {
+					IJavaElement[] newChildren = new IJavaElement[length-1];
+					System.arraycopy(this.children, 0, newChildren , 0, i);
+					if (i < length-1)
+						System.arraycopy(this.children, i+1, newChildren, i, length-1-i);
+					this.children = newChildren;
+				}
+				break;
+			}
+		}
+	}
+
+	public void setChildren(IJavaElement[] children) {
+		this.children = children;
+	}
+
+	/**
+	 * Sets whether the structure of this element known
+	 * @see IJavaElement#isStructureKnown()
+	 */
+	public void setIsStructureKnown(boolean newIsStructureKnown) {
+		this.isStructureKnown = newIsStructureKnown;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java
new file mode 100644
index 0000000..d0ec155
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java
@@ -0,0 +1,417 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import org.eclipse.jdt.internal.core.util.LRUCache;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ *	The <code>OverflowingLRUCache</code> is an LRUCache which attempts
+ *	to maintain a size equal or less than its <code>fSpaceLimit</code>
+ *	by removing the least recently used elements.
+ *
+ *	<p>The cache will remove elements which successfully close and all
+ *	elements which are explicitly removed.
+ *
+ *	<p>If the cache cannot remove enough old elements to add new elements
+ *	it will grow beyond <code>fSpaceLimit</code>. Later, it will attempt to
+ *	shink back to the maximum space limit.
+ *
+ *	The method <code>close</code> should attempt to close the element.  If
+ *	the element is successfully closed it will return true and the element will
+ *	be removed from the cache.  Otherwise the element will remain in the cache.
+ *
+ *	<p>The cache implicitly attempts shrinks on calls to <code>put</code>and
+ *	<code>setSpaceLimit</code>.  Explicitly calling the <code>shrink</code> method
+ *	will also cause the cache to attempt to shrink.
+ *
+ *	<p>The cache calculates the used space of all elements which implement
+ *	<code>ILRUCacheable</code>.  All other elements are assumed to be of size one.
+ *
+ *	<p>Use the <code>#peek(Object)</code> and <code>#disableTimestamps()</code> method to
+ *	circumvent the timestamp feature of the cache.  This feature is intended to be used
+ *	only when the <code>#close(LRUCacheEntry)</code> method causes changes to the cache.
+ *	For example, if a parent closes its children when </code>#close(LRUCacheEntry)</code> is called,
+ *	it should be careful not to change the LRU linked list.  It can be sure it is not causing
+ *	problems by calling <code>#peek(Object)</code> instead of <code>#get(Object)</code> method.
+ *
+ *	@see LRUCache
+ */
+public abstract class OverflowingLRUCache extends LRUCache {
+	/**
+	 * Indicates if the cache has been over filled and by how much.
+	 */
+	protected int overflow = 0;
+	/**
+	 *	Indicates whether or not timestamps should be updated
+	 */
+	protected boolean timestampsOn = true;
+	/**
+	 *	Indicates how much space should be reclaimed when the cache overflows.
+	 *	Inital load factor of one third.
+	 */
+	protected double loadFactor = 0.333;
+/**
+ * Creates a OverflowingLRUCache.
+ * @param size Size limit of cache.
+ */
+public OverflowingLRUCache(int size) {
+	this(size, 0);
+}
+/**
+ * Creates a OverflowingLRUCache.
+ * @param size Size limit of cache.
+ * @param overflow Size of the overflow.
+ */
+public OverflowingLRUCache(int size, int overflow) {
+	super(size);
+	this.overflow = overflow;
+}
+	/**
+	 * Returns a new cache containing the same contents.
+	 *
+	 * @return New copy of this object.
+	 */
+	public Object clone() {
+
+		OverflowingLRUCache newCache = (OverflowingLRUCache)newInstance(this.spaceLimit, this.overflow);
+		LRUCacheEntry qEntry;
+
+		/* Preserve order of entries by copying from oldest to newest */
+		qEntry = this.entryQueueTail;
+		while (qEntry != null) {
+			newCache.privateAdd (qEntry.key, qEntry.value, qEntry.space);
+			qEntry = qEntry.previous;
+		}
+		return newCache;
+	}
+/**
+ * Returns true if the element is successfully closed and
+ * removed from the cache, otherwise false.
+ *
+ * <p>NOTE: this triggers an external remove from the cache
+ * by closing the obejct.
+ *
+ */
+protected abstract boolean close(LRUCacheEntry entry);
+	/**
+	 *	Returns an enumerator of the values in the cache with the most
+	 *	recently used first.
+	 */
+	public Enumeration elements() {
+		if (this.entryQueue == null)
+			return new LRUCacheEnumerator(null);
+		LRUCacheEnumerator.LRUEnumeratorElement head =
+			new LRUCacheEnumerator.LRUEnumeratorElement(this.entryQueue.value);
+		LRUCacheEntry currentEntry = this.entryQueue.next;
+		LRUCacheEnumerator.LRUEnumeratorElement currentElement = head;
+		while(currentEntry != null) {
+			currentElement.next = new LRUCacheEnumerator.LRUEnumeratorElement(currentEntry.value);
+			currentElement = currentElement.next;
+
+			currentEntry = currentEntry.next;
+		}
+		return new LRUCacheEnumerator(head);
+	}
+	public double fillingRatio() {
+		return (this.currentSpace + this.overflow) * 100.0 / this.spaceLimit;
+	}
+	/**
+	 * For internal testing only.
+	 * This method exposed only for testing purposes!
+	 *
+	 * @return Hashtable of entries
+	 */
+	public java.util.Hashtable getEntryTable() {
+		return this.entryTable;
+	}
+/**
+ * Returns the load factor for the cache.  The load factor determines how
+ * much space is reclaimed when the cache exceeds its space limit.
+ * @return double
+ */
+public double getLoadFactor() {
+	return this.loadFactor;
+}
+	/**
+	 *	@return The space by which the cache has overflown.
+	 */
+	public int getOverflow() {
+		return this.overflow;
+	}
+	/**
+	 * Ensures there is the specified amount of free space in the receiver,
+	 * by removing old entries if necessary.  Returns true if the requested space was
+	 * made available, false otherwise.  May not be able to free enough space
+	 * since some elements cannot be removed until they are saved.
+	 *
+	 * @param space Amount of space to free up
+	 */
+	protected boolean makeSpace(int space) {
+
+		int limit = this.spaceLimit;
+		if (this.overflow == 0 && this.currentSpace + space <= limit) {
+			/* if space is already available */
+			return true;
+		}
+
+		/* Free up space by removing oldest entries */
+		int spaceNeeded = (int)((1 - this.loadFactor) * limit);
+		spaceNeeded = (spaceNeeded > space) ? spaceNeeded : space;
+		LRUCacheEntry entry = this.entryQueueTail;
+
+		try {
+			// disable timestamps update while making space so that the previous and next links are not changed
+			// (by a call to get(Object) for example)
+			this.timestampsOn = false;
+
+			while (this.currentSpace + spaceNeeded > limit && entry != null) {
+				this.privateRemoveEntry(entry, false, false);
+				entry = entry.previous;
+			}
+		} finally {
+			this.timestampsOn = true;
+		}
+
+		/* check again, since we may have aquired enough space */
+		if (this.currentSpace + space <= limit) {
+			this.overflow = 0;
+			return true;
+		}
+
+		/* update fOverflow */
+		this.overflow = this.currentSpace + space - limit;
+		return false;
+	}
+	/**
+	 * Returns a new instance of the reciever.
+	 */
+	protected abstract LRUCache newInstance(int size, int newOverflow);
+/**
+ * For testing purposes only
+ */
+public void printStats() {
+	int forwardListLength = 0;
+	LRUCacheEntry entry = this.entryQueue;
+	while(entry != null) {
+		forwardListLength++;
+		entry = entry.next;
+	}
+	System.out.println("Forward length: " + forwardListLength); //$NON-NLS-1$
+
+	int backwardListLength = 0;
+	entry = this.entryQueueTail;
+	while(entry != null) {
+		backwardListLength++;
+		entry = entry.previous;
+	}
+	System.out.println("Backward length: " + backwardListLength); //$NON-NLS-1$
+
+	Enumeration keys = this.entryTable.keys();
+	class Temp {
+		public Class clazz;
+		public int count;
+		public Temp(Class aClass) {
+			this.clazz = aClass;
+			this.count = 1;
+		}
+		public String toString() {
+			return "Class: " + this.clazz + " has " + this.count + " entries."; //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$
+		}
+	}
+	java.util.HashMap h = new java.util.HashMap();
+	while(keys.hasMoreElements()) {
+		entry = (LRUCacheEntry)this.entryTable.get(keys.nextElement());
+		Class key = entry.value.getClass();
+		Temp t = (Temp)h.get(key);
+		if (t == null) {
+			h.put(key, new Temp(key));
+		} else {
+			t.count++;
+		}
+	}
+
+	for (Iterator iter = h.values().iterator(); iter.hasNext();){
+		System.out.println(iter.next());
+	}
+}
+	/**
+	 *	Removes the entry from the entry queue.
+	 *	Calls <code>privateRemoveEntry</code> with the external functionality enabled.
+	 *
+	 * @param shuffle indicates whether we are just shuffling the queue
+	 * (in which case, the entry table is not modified).
+	 */
+	protected void privateRemoveEntry (LRUCacheEntry entry, boolean shuffle) {
+		privateRemoveEntry(entry, shuffle, true);
+	}
+/**
+ *	Removes the entry from the entry queue.  If <i>external</i> is true, the entry is removed
+ *	without checking if it can be removed.  It is assumed that the client has already closed
+ *	the element it is trying to remove (or will close it promptly).
+ *
+ *	If <i>external</i> is false, and the entry could not be closed, it is not removed and the
+ *	pointers are not changed.
+ *
+ *	@param shuffle indicates whether we are just shuffling the queue
+ *	(in which case, the entry table is not modified).
+ */
+protected void privateRemoveEntry(LRUCacheEntry entry, boolean shuffle, boolean external) {
+
+	if (!shuffle) {
+		if (external) {
+			this.entryTable.remove(entry.key);
+			this.currentSpace -= entry.space;
+		} else {
+			if (!close(entry)) return;
+			// buffer close will recursively call #privateRemoveEntry with external==true
+			// thus entry will already be removed if reaching this point.
+			if (this.entryTable.get(entry.key) == null){
+				return;
+			} else {
+				// basic removal
+				this.entryTable.remove(entry.key);
+				this.currentSpace -= entry.space;
+			}
+		}
+	}
+	LRUCacheEntry previous = entry.previous;
+	LRUCacheEntry next = entry.next;
+
+	/* if this was the first entry */
+	if (previous == null) {
+		this.entryQueue = next;
+	} else {
+		previous.next = next;
+	}
+	/* if this was the last entry */
+	if (next == null) {
+		this.entryQueueTail = previous;
+	} else {
+		next.previous = previous;
+	}
+}
+	/**
+	 * Sets the value in the cache at the given key. Returns the value.
+	 *
+	 * @param key Key of object to add.
+	 * @param value Value of object to add.
+	 * @return added value.
+	 */
+	public Object put(Object key, Object value) {
+		/* attempt to rid ourselves of the overflow, if there is any */
+		if (this.overflow > 0)
+			shrink();
+
+		/* Check whether there's an entry in the cache */
+		int newSpace = spaceFor(value);
+		LRUCacheEntry entry = (LRUCacheEntry) this.entryTable.get (key);
+
+		if (entry != null) {
+
+			/**
+			 * Replace the entry in the cache if it would not overflow
+			 * the cache.  Otherwise flush the entry and re-add it so as
+			 * to keep cache within budget
+			 */
+			int oldSpace = entry.space;
+			int newTotal = this.currentSpace - oldSpace + newSpace;
+			if (newTotal <= this.spaceLimit) {
+				updateTimestamp (entry);
+				entry.value = value;
+				entry.space = newSpace;
+				this.currentSpace = newTotal;
+				this.overflow = 0;
+				return value;
+			} else {
+				privateRemoveEntry (entry, false, false);
+			}
+		}
+
+		// attempt to make new space
+		makeSpace(newSpace);
+
+		// add without worring about space, it will
+		// be handled later in a makeSpace call
+		privateAdd (key, value, newSpace);
+
+		return value;
+	}
+	/**
+	 * Removes and returns the value in the cache for the given key.
+	 * If the key is not in the cache, returns null.
+	 *
+	 * @param key Key of object to remove from cache.
+	 * @return Value removed from cache.
+	 */
+	public Object remove(Object key) {
+		return removeKey(key);
+	}
+/**
+ * Sets the load factor for the cache.  The load factor determines how
+ * much space is reclaimed when the cache exceeds its space limit.
+ * @param newLoadFactor double
+ * @throws IllegalArgumentException when the new load factor is not in (0.0, 1.0]
+ */
+public void setLoadFactor(double newLoadFactor) throws IllegalArgumentException {
+	if(newLoadFactor <= 1.0 && newLoadFactor > 0.0)
+		this.loadFactor = newLoadFactor;
+	else
+		throw new IllegalArgumentException(Messages.cache_invalidLoadFactor);
+}
+	/**
+	 * Sets the maximum amount of space that the cache can store
+	 *
+	 * @param limit Number of units of cache space
+	 */
+	public void setSpaceLimit(int limit) {
+		if (limit < this.spaceLimit) {
+			makeSpace(this.spaceLimit - limit);
+		}
+		this.spaceLimit = limit;
+	}
+	/**
+	 * Attempts to shrink the cache if it has overflown.
+	 * Returns true if the cache shrinks to less than or equal to <code>fSpaceLimit</code>.
+	 */
+	public boolean shrink() {
+		if (this.overflow > 0)
+			return makeSpace(0);
+		return true;
+	}
+/**
+ * Returns a String that represents the value of this object.  This method
+ * is for debugging purposes only.
+ */
+public String toString() {
+	return
+		toStringFillingRation("OverflowingLRUCache ") + //$NON-NLS-1$
+		toStringContents();
+}
+/**
+ * Updates the timestamp for the given entry, ensuring that the queue is
+ * kept in correct order.  The entry must exist.
+ *
+ * <p>This method will do nothing if timestamps have been disabled.
+ */
+protected void updateTimestamp(LRUCacheEntry entry) {
+	if (this.timestampsOn) {
+		entry.timestamp = this.timestampCounter++;
+		if (this.entryQueue != entry) {
+			this.privateRemoveEntry(entry, true);
+			privateAddEntry(entry, true);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
new file mode 100644
index 0000000..df8a752
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+
+/**
+ * @see IPackageDeclaration
+ */
+
+public class PackageDeclaration extends SourceRefElement implements IPackageDeclaration {
+
+	String name;
+
+protected PackageDeclaration(CompilationUnit parent, String name) {
+	super(parent);
+	this.name = name;
+}
+public boolean equals(Object o) {
+	if (!(o instanceof PackageDeclaration)) return false;
+	return super.equals(o);
+}
+public String getElementName() {
+	return this.name;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return PACKAGE_DECLARATION;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_PACKAGEDECLARATION;
+}
+/**
+ * @see IPackageDeclaration#getNameRange()
+ */
+public ISourceRange getNameRange() throws JavaModelException {
+	AnnotatableInfo info = (AnnotatableInfo) getElementInfo();
+	return info.getNameRange();
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	CompilationUnit cu = (CompilationUnit)getAncestor(COMPILATION_UNIT);
+	if (checkOwner && cu.isPrimary()) return this;
+	return cu.getPackageDeclaration(this.name);
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	buffer.append("package "); //$NON-NLS-1$
+	toStringName(buffer);
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
new file mode 100644
index 0000000..5408aef
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
@@ -0,0 +1,517 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.ISourceManipulation;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IPackageFragment
+ */
+public class PackageFragment extends Openable implements IPackageFragment, SuffixConstants {
+	/**
+	 * Constant empty list of class files
+	 */
+	protected static final IClassFile[] NO_CLASSFILES = new IClassFile[] {};
+	/**
+	 * Constant empty list of compilation units
+	 */
+	protected static final ICompilationUnit[] NO_COMPILATION_UNITS = new ICompilationUnit[] {};
+
+	public String[] names;
+
+protected PackageFragment(PackageFragmentRoot root, String[] names) {
+	super(root);
+	this.names = names;
+}
+/**
+ * @see Openable
+ */
+protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+	// add compilation units/class files from resources
+	HashSet vChildren = new HashSet();
+	int kind = getKind();
+	try {
+	    PackageFragmentRoot root = getPackageFragmentRoot();
+		char[][] inclusionPatterns = root.fullInclusionPatternChars();
+		char[][] exclusionPatterns = root.fullExclusionPatternChars();
+		IResource[] members = ((IContainer) underlyingResource).members();
+		int length = members.length;
+		if (length > 0) {
+			IJavaProject project = getJavaProject();
+			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+			String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			for (int i = 0; i < length; i++) {
+				IResource child = members[i];
+				if (child.getType() != IResource.FOLDER
+						&& !Util.isExcluded(child, inclusionPatterns, exclusionPatterns)) {
+					IJavaElement childElement;
+					if (kind == IPackageFragmentRoot.K_SOURCE && Util.isValidCompilationUnitName(child.getName(), sourceLevel, complianceLevel)) {
+						childElement = new CompilationUnit(this, child.getName(), DefaultWorkingCopyOwner.PRIMARY);
+						vChildren.add(childElement);
+					} else if (kind == IPackageFragmentRoot.K_BINARY && Util.isValidClassFileName(child.getName(), sourceLevel, complianceLevel)) {
+						childElement = getClassFile(child.getName());
+						vChildren.add(childElement);
+					}
+				}
+			}
+		}
+	} catch (CoreException e) {
+		throw new JavaModelException(e);
+	}
+
+	if (kind == IPackageFragmentRoot.K_SOURCE) {
+		// add primary compilation units
+		ICompilationUnit[] primaryCompilationUnits = getCompilationUnits(DefaultWorkingCopyOwner.PRIMARY);
+		for (int i = 0, length = primaryCompilationUnits.length; i < length; i++) {
+			ICompilationUnit primary = primaryCompilationUnits[i];
+			vChildren.add(primary);
+		}
+	}
+
+	IJavaElement[] children = new IJavaElement[vChildren.size()];
+	vChildren.toArray(children);
+	info.setChildren(children);
+	return true;
+}
+/**
+ * Returns true if this fragment contains at least one java resource.
+ * Returns false otherwise.
+ */
+public boolean containsJavaResources() throws JavaModelException {
+	return ((PackageFragmentInfo) getElementInfo()).containsJavaResources();
+}
+/**
+ * @see ISourceManipulation
+ */
+public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] containers= new IJavaElement[] {container};
+	IJavaElement[] siblings= null;
+	if (sibling != null) {
+		siblings= new IJavaElement[] {sibling};
+	}
+	String[] renamings= null;
+	if (rename != null) {
+		renamings= new String[] {rename};
+	}
+	getJavaModel().copy(elements, containers, siblings, renamings, force, monitor);
+}
+/**
+ * @see IPackageFragment
+ */
+public ICompilationUnit createCompilationUnit(String cuName, String contents, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CreateCompilationUnitOperation op= new CreateCompilationUnitOperation(this, cuName, contents, force);
+	op.runOperation(monitor);
+	return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see JavaElement
+ */
+protected Object createElementInfo() {
+	return new PackageFragmentInfo();
+}
+/**
+ * @see ISourceManipulation
+ */
+public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	IJavaElement[] elements = new IJavaElement[] {this};
+	getJavaModel().delete(elements, force, monitor);
+}
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof PackageFragment)) return false;
+
+	PackageFragment other = (PackageFragment) o;
+	return Util.equalArraysOrNull(this.names, other.names) &&
+			this.parent.equals(other.parent);
+}
+public boolean exists() {
+	// super.exist() only checks for the parent and the resource existence
+	// so also ensure that:
+	//  - the package is not excluded (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138577)
+	//  - its name is valide (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=108456)
+	return super.exists() && !Util.isExcluded(this) && isValidPackageName();
+}
+/**
+ * @see IPackageFragment#getClassFile(String)
+ * @exception IllegalArgumentException if the name does not end with ".class"
+ */
+public IClassFile getClassFile(String classFileName) {
+	if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(classFileName)) {
+		throw new IllegalArgumentException(Messages.bind(Messages.element_invalidClassFileName, classFileName));
+	}
+	// don't hold on the .class file extension to save memory
+	// also make sure to not use substring as the resulting String may hold on the underlying char[] which might be much bigger than necessary
+	int length = classFileName.length() - 6;
+	char[] nameWithoutExtension = new char[length];
+	classFileName.getChars(0, length, nameWithoutExtension, 0);
+	return new ClassFile(this, new String(nameWithoutExtension));
+}
+/**
+ * Returns a the collection of class files in this - a folder package fragment which has a root
+ * that has its kind set to <code>IPackageFragmentRoot.K_Source</code> does not
+ * recognize class files.
+ *
+ * @see IPackageFragment#getClassFiles()
+ */
+public IClassFile[] getClassFiles() throws JavaModelException {
+	if (getKind() == IPackageFragmentRoot.K_SOURCE) {
+		return NO_CLASSFILES;
+	}
+
+	ArrayList list = getChildrenOfType(CLASS_FILE);
+	IClassFile[] array= new IClassFile[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IPackageFragment#getCompilationUnit(String)
+ * @exception IllegalArgumentException if the name does not end with ".java"
+ */
+public ICompilationUnit getCompilationUnit(String cuName) {
+	if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(cuName)) {
+		throw new IllegalArgumentException(Messages.convention_unit_notJavaName);
+	}
+	return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see IPackageFragment#getCompilationUnits()
+ */
+public ICompilationUnit[] getCompilationUnits() throws JavaModelException {
+	if (getKind() == IPackageFragmentRoot.K_BINARY) {
+		return NO_COMPILATION_UNITS;
+	}
+
+	ArrayList list = getChildrenOfType(COMPILATION_UNIT);
+	ICompilationUnit[] array= new ICompilationUnit[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IPackageFragment#getCompilationUnits(WorkingCopyOwner)
+ */
+public ICompilationUnit[] getCompilationUnits(WorkingCopyOwner owner) {
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, false/*don't add primary*/);
+	if (workingCopies == null) return JavaModelManager.NO_WORKING_COPY;
+	int length = workingCopies.length;
+	ICompilationUnit[] result = new ICompilationUnit[length];
+	int index = 0;
+	for (int i = 0; i < length; i++) {
+		ICompilationUnit wc = workingCopies[i];
+		if (equals(wc.getParent()) && !Util.isExcluded(wc)) { // 59933 - excluded wc shouldn't be answered back
+			result[index++] = wc;
+		}
+	}
+	if (index != length) {
+		System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index);
+	}
+	return result;
+}
+public String getElementName() {
+	if (this.names.length == 0)
+		return DEFAULT_PACKAGE_NAME;
+	return Util.concatWith(this.names, '.');
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return PACKAGE_FRAGMENT;
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+	switch (token.charAt(0)) {
+		case JEM_CLASSFILE:
+			if (!memento.hasMoreTokens()) return this;
+			String classFileName = memento.nextToken();
+			JavaElement classFile = (JavaElement)getClassFile(classFileName);
+			return classFile.getHandleFromMemento(memento, owner);
+		case JEM_COMPILATIONUNIT:
+			if (!memento.hasMoreTokens()) return this;
+			String cuName = memento.nextToken();
+			JavaElement cu = new CompilationUnit(this, cuName, owner);
+			return cu.getHandleFromMemento(memento, owner);
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMementoDelimiter()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_PACKAGEFRAGMENT;
+}
+/**
+ * @see IPackageFragment#getKind()
+ */
+public int getKind() throws JavaModelException {
+	return ((IPackageFragmentRoot)getParent()).getKind();
+}
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+public Object[] getNonJavaResources() throws JavaModelException {
+	if (isDefaultPackage()) {
+		// We don't want to show non java resources of the default package (see PR #1G58NB8)
+		return JavaElementInfo.NO_NON_JAVA_RESOURCES;
+	} else {
+		return ((PackageFragmentInfo) getElementInfo()).getNonJavaResources(resource(), getPackageFragmentRoot());
+	}
+}
+/**
+ * @see IJavaElement#getPath()
+ */
+public IPath getPath() {
+	PackageFragmentRoot root = getPackageFragmentRoot();
+	if (root.isArchive()) {
+		return root.getPath();
+	} else {
+		IPath path = root.getPath();
+		for (int i = 0, length = this.names.length; i < length; i++) {
+			String name = this.names[i];
+			path = path.append(name);
+		}
+		return path;
+	}
+}
+/**
+ * @see JavaElement#resource()
+ */
+public IResource resource(PackageFragmentRoot root) {
+	int length = this.names.length;
+	if (length == 0) {
+		return root.resource(root);
+	} else {
+		IPath path = new Path(this.names[0]);
+		for (int i = 1; i < length; i++)
+			path = path.append(this.names[i]);
+		return ((IContainer)root.resource(root)).getFolder(path);
+	}
+}
+/**
+ * @see IJavaElement#getUnderlyingResource()
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+	IResource rootResource = this.parent.getUnderlyingResource();
+	if (rootResource == null) {
+		//jar package fragment root that has no associated resource
+		return null;
+	}
+	// the underlying resource may be a folder or a project (in the case that the project folder
+	// is atually the package fragment root)
+	if (rootResource.getType() == IResource.FOLDER || rootResource.getType() == IResource.PROJECT) {
+		IContainer folder = (IContainer) rootResource;
+		String[] segs = this.names;
+		for (int i = 0; i < segs.length; ++i) {
+			IResource child = folder.findMember(segs[i]);
+			if (child == null || child.getType() != IResource.FOLDER) {
+				throw newNotPresentException();
+			}
+			folder = (IFolder) child;
+		}
+		return folder;
+	} else {
+		return rootResource;
+	}
+}
+public int hashCode() {
+	int hash = this.parent.hashCode();
+	for (int i = 0, length = this.names.length; i < length; i++)
+		hash = Util.combineHashCodes(this.names[i].hashCode(), hash);
+	return hash;
+}
+/**
+ * @see IParent
+ */
+public boolean hasChildren() throws JavaModelException {
+	return getChildren().length > 0;
+}
+/**
+ * @see IPackageFragment#hasSubpackages()
+ */
+public boolean hasSubpackages() throws JavaModelException {
+	IJavaElement[] packages= ((IPackageFragmentRoot)getParent()).getChildren();
+	int namesLength = this.names.length;
+	nextPackage: for (int i= 0, length = packages.length; i < length; i++) {
+		String[] otherNames = ((PackageFragment) packages[i]).names;
+		if (otherNames.length <= namesLength) continue nextPackage;
+		for (int j = 0; j < namesLength; j++)
+			if (!this.names[j].equals(otherNames[j]))
+				continue nextPackage;
+		return true;
+	}
+	return false;
+}
+/**
+ * @see IPackageFragment#isDefaultPackage()
+ */
+public boolean isDefaultPackage() {
+	return this.names.length == 0;
+}
+private boolean isValidPackageName() {
+	JavaProject javaProject = (JavaProject) getJavaProject();
+	String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+	String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+	for (int i = 0, length = this.names.length; i < length; i++) {
+		if (!Util.isValidFolderNameForPackage(this.names[i], sourceLevel, complianceLevel))
+			return false;
+	}
+	return true;
+}
+/**
+ * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor)
+ */
+public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] containers= new IJavaElement[] {container};
+	IJavaElement[] siblings= null;
+	if (sibling != null) {
+		siblings= new IJavaElement[] {sibling};
+	}
+	String[] renamings= null;
+	if (rename != null) {
+		renamings= new String[] {rename};
+	}
+	getJavaModel().move(elements, containers, siblings, renamings, force, monitor);
+}
+/**
+ * @see ISourceManipulation#rename(String, boolean, IProgressMonitor)
+ */
+public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (newName == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] dests= new IJavaElement[] {getParent()};
+	String[] renamings= new String[] {newName};
+	getJavaModel().rename(elements, dests, renamings, force, monitor);
+}
+/**
+ * Debugging purposes
+ */
+protected void toStringChildren(int tab, StringBuffer buffer, Object info) {
+	if (tab == 0) {
+		super.toStringChildren(tab, buffer, info);
+	}
+}
+/**
+ * Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (this.names.length == 0) {
+		buffer.append("<default>"); //$NON-NLS-1$
+	} else {
+		toStringName(buffer);
+	}
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else {
+		if (tab > 0) {
+			buffer.append(" (...)"); //$NON-NLS-1$
+		}
+	}
+}
+/*
+ * @see IJavaElement#getAttachedJavadoc(IProgressMonitor)
+ */
+public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+	PerProjectInfo projectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject());
+	String cachedJavadoc = null;
+	synchronized (projectInfo.javadocCache) {
+		cachedJavadoc = (String) projectInfo.javadocCache.get(this);
+	}
+	if (cachedJavadoc != null) {
+		return cachedJavadoc;
+	}
+	URL baseLocation= getJavadocBaseLocation();
+	if (baseLocation == null) {
+		return null;
+	}
+	StringBuffer pathBuffer = new StringBuffer(baseLocation.toExternalForm());
+
+	if (!(pathBuffer.charAt(pathBuffer.length() - 1) == '/')) {
+		pathBuffer.append('/');
+	}
+	String packPath= getElementName().replace('.', '/');
+	pathBuffer.append(packPath).append('/').append(JavadocConstants.PACKAGE_FILE_NAME);
+
+	if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+	String contents = getURLContents(String.valueOf(pathBuffer));
+	if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+	if (contents == null) return null;
+	
+	contents = (new JavadocContents(contents)).getPackageDoc();
+	if (contents == null) contents = ""; //$NON-NLS-1$
+	synchronized (projectInfo.javadocCache) {
+		projectInfo.javadocCache.put(this, contents);
+	}
+	return contents;
+}
+
+protected IStatus validateExistence(IResource underlyingResource) {
+	// check that the name of the package is valid (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=108456)
+	if (!isValidPackageName())
+		return newDoesNotExistStatus();
+
+	// check whether this pkg can be opened
+	if (underlyingResource != null && !resourceExists(underlyingResource))
+		return newDoesNotExistStatus();
+
+	// check that it is not excluded (https://bugs.eclipse.org/bugs/show_bug.cgi?id=138577)
+	int kind;
+	try {
+		kind = getKind();
+	} catch (JavaModelException e) {
+		return e.getStatus();
+	}
+	if (kind == IPackageFragmentRoot.K_SOURCE && Util.isExcluded(this))
+		return newDoesNotExistStatus();
+
+	return JavaModelStatus.VERIFIED_OK;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java
new file mode 100644
index 0000000..ec159b6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Element info for PackageFragments.
+ */
+class PackageFragmentInfo extends OpenableElementInfo {
+
+	/**
+	 * A array with all the non-java resources contained by this PackageFragment
+	 */
+	protected Object[] nonJavaResources;
+
+/**
+ * Create and initialize a new instance of the receiver
+ */
+public PackageFragmentInfo() {
+	this.nonJavaResources = null;
+}
+/**
+ */
+boolean containsJavaResources() {
+	return this.children.length != 0;
+}
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+Object[] getNonJavaResources(IResource underlyingResource, PackageFragmentRoot rootHandle) {
+	if (this.nonJavaResources == null) {
+		try {
+			this.nonJavaResources =
+				PackageFragmentRootInfo.computeFolderNonJavaResources(
+					rootHandle,
+					(IContainer)underlyingResource,
+					rootHandle.fullInclusionPatternChars(),
+					rootHandle.fullExclusionPatternChars());
+		} catch (JavaModelException e) {
+			// root doesn't exist: consider package has no nonJavaResources
+			this.nonJavaResources = NO_NON_JAVA_RESOURCES;
+		}
+	}
+	return this.nonJavaResources;
+}
+/**
+ * Set the nonJavaResources to res value
+ */
+void setNonJavaResources(Object[] resources) {
+	this.nonJavaResources = resources;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
new file mode 100644
index 0000000..a2be223
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -0,0 +1,822 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public class PackageFragmentRoot extends Openable implements IPackageFragmentRoot {
+
+	/**
+	 * The delimiter between the source path and root path in the
+	 * attachment server property.
+	 */
+	protected final static char ATTACHMENT_PROPERTY_DELIMITER= '*';
+	/*
+	 * No source attachment property
+	 */
+	public final static String NO_SOURCE_ATTACHMENT = ""; //$NON-NLS-1$
+
+	/**
+	 * The resource associated with this root (null for external jar)
+	 */
+	protected IResource resource;
+
+/**
+ * Constructs a package fragment root which is the root of the java package
+ * directory hierarchy.
+ */
+protected PackageFragmentRoot(IResource resource, JavaProject project) {
+	super(project);
+	this.resource = resource;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public void attachSource(IPath sourcePath, IPath rootPath, IProgressMonitor monitor) throws JavaModelException {
+	try {
+		verifyAttachSource(sourcePath);
+		if (monitor != null) {
+			monitor.beginTask(Messages.element_attachingSource, 2);
+		}
+		SourceMapper oldMapper= getSourceMapper();
+		boolean rootNeedsToBeClosed= false;
+
+		if (sourcePath == null) {
+			//source being detached
+			rootNeedsToBeClosed= true;
+			setSourceMapper(null);
+		/* Disable deltas (see 1GDTUSD)
+			// fire a delta to notify the UI about the source detachement.
+			JavaModelManager manager = (JavaModelManager) JavaModelManager.getJavaModelManager();
+			JavaModel model = (JavaModel) getJavaModel();
+			JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
+			attachedSourceDelta .sourceDetached(this); // this would be a PackageFragmentRoot
+			manager.registerResourceDelta(attachedSourceDelta );
+			manager.fire(); // maybe you want to fire the change later. Let us know about it.
+		*/
+		} else {
+		/*
+			// fire a delta to notify the UI about the source attachment.
+			JavaModelManager manager = (JavaModelManager) JavaModelManager.getJavaModelManager();
+			JavaModel model = (JavaModel) getJavaModel();
+			JavaElementDelta attachedSourceDelta = new JavaElementDelta(model);
+			attachedSourceDelta .sourceAttached(this); // this would be a PackageFragmentRoot
+			manager.registerResourceDelta(attachedSourceDelta );
+			manager.fire(); // maybe you want to fire the change later. Let us know about it.
+		 */
+
+			//check if different from the current attachment
+			IPath storedSourcePath= getSourceAttachmentPath();
+			IPath storedRootPath= getSourceAttachmentRootPath();
+			if (monitor != null) {
+				monitor.worked(1);
+			}
+			if (storedSourcePath != null) {
+				if (!(storedSourcePath.equals(sourcePath) && (rootPath != null && rootPath.equals(storedRootPath)) || storedRootPath == null)) {
+					rootNeedsToBeClosed= true;
+				}
+			}
+			// check if source path is valid
+			Object target = JavaModel.getTarget(sourcePath, false);
+			if (target == null) {
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, sourcePath));
+			}
+			SourceMapper mapper = createSourceMapper(sourcePath, rootPath);
+			if (rootPath == null && mapper.rootPath != null) {
+				// as a side effect of calling the SourceMapper constructor, the root path was computed
+				rootPath = new Path(mapper.rootPath);
+			}
+			setSourceMapper(mapper);
+		}
+		if (sourcePath == null) {
+			Util.setSourceAttachmentProperty(getPath(), null); //remove the property
+		} else {
+			//set the property to the path of the mapped source
+			Util.setSourceAttachmentProperty(
+				getPath(),
+				sourcePath.toString()
+				+ (rootPath == null ? "" : (ATTACHMENT_PROPERTY_DELIMITER + rootPath.toString()))); //$NON-NLS-1$
+		}
+		if (rootNeedsToBeClosed) {
+			if (oldMapper != null) {
+				oldMapper.close();
+			}
+			BufferManager manager= BufferManager.getDefaultBufferManager();
+			Enumeration openBuffers= manager.getOpenBuffers();
+			while (openBuffers.hasMoreElements()) {
+				IBuffer buffer= (IBuffer) openBuffers.nextElement();
+				IOpenable possibleMember= buffer.getOwner();
+				if (isAncestorOf((IJavaElement) possibleMember)) {
+					buffer.close();
+				}
+			}
+			if (monitor != null) {
+				monitor.worked(1);
+			}
+		}
+	} catch (JavaModelException e) {
+		Util.setSourceAttachmentProperty(getPath(), null); // loose info - will be recomputed
+		throw e;
+	} finally {
+		if (monitor != null) {
+			monitor.done();
+		}
+	}
+}
+
+/**
+ * @see Openable
+ */
+protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException {
+	((PackageFragmentRootInfo) info).setRootKind(determineKind(underlyingResource));
+	return computeChildren(info, underlyingResource);
+}
+
+SourceMapper createSourceMapper(IPath sourcePath, IPath rootPath) throws JavaModelException {
+	IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(getPath());
+	String encoding = (entry== null) ? null : ((ClasspathEntry) entry).getSourceAttachmentEncoding();
+	SourceMapper mapper = new SourceMapper(
+		sourcePath,
+		rootPath == null ? null : rootPath.toOSString(),
+		getJavaProject().getOptions(true),// cannot use workspace options if external jar is 1.5 jar and workspace options are 1.4 options
+		encoding);
+
+	return mapper;
+}
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#delete
+ */
+public void delete(
+	int updateResourceFlags,
+	int updateModelFlags,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	DeletePackageFragmentRootOperation op = new DeletePackageFragmentRootOperation(this, updateResourceFlags, updateModelFlags);
+	op.runOperation(monitor);
+}
+
+/**
+ * Compute the package fragment children of this package fragment root.
+ *
+ * @exception JavaModelException  The resource associated with this package fragment root does not exist
+ */
+protected boolean computeChildren(OpenableElementInfo info, IResource underlyingResource) throws JavaModelException {
+	// Note the children are not opened (so not added to newElements) for a regular package fragment root
+	// However they are opened for a Jar package fragment root (see JarPackageFragmentRoot#computeChildren)
+	try {
+		// the underlying resource may be a folder or a project (in the case that the project folder
+		// is actually the package fragment root)
+		if (underlyingResource.getType() == IResource.FOLDER || underlyingResource.getType() == IResource.PROJECT) {
+			ArrayList vChildren = new ArrayList(5);
+			IContainer rootFolder = (IContainer) underlyingResource;
+			char[][] inclusionPatterns = fullInclusionPatternChars();
+			char[][] exclusionPatterns = fullExclusionPatternChars();
+			computeFolderChildren(rootFolder, !Util.isExcluded(rootFolder, inclusionPatterns, exclusionPatterns), CharOperation.NO_STRINGS, vChildren, inclusionPatterns, exclusionPatterns);
+			IJavaElement[] children = new IJavaElement[vChildren.size()];
+			vChildren.toArray(children);
+			info.setChildren(children);
+		}
+	} catch (JavaModelException e) {
+		//problem resolving children; structure remains unknown
+		info.setChildren(new IJavaElement[]{});
+		throw e;
+	}
+	return true;
+}
+
+/**
+ * Starting at this folder, create package fragments and add the fragments that are not exclused
+ * to the collection of children.
+ *
+ * @exception JavaModelException  The resource associated with this package fragment does not exist
+ */
+protected void computeFolderChildren(IContainer folder, boolean isIncluded, String[] pkgName, ArrayList vChildren, char[][] inclusionPatterns, char[][] exclusionPatterns) throws JavaModelException {
+
+	if (isIncluded) {
+	    IPackageFragment pkg = getPackageFragment(pkgName);
+		vChildren.add(pkg);
+	}
+	try {
+		JavaProject javaProject = (JavaProject)getJavaProject();
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IResource[] members = folder.members();
+		boolean hasIncluded = isIncluded;
+		int length = members.length;
+		if (length >0) {
+			String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+			String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			for (int i = 0; i < length; i++) {
+				IResource member = members[i];
+				String memberName = member.getName();
+
+				switch(member.getType()) {
+
+			    	case IResource.FOLDER:
+			    		// recurse into sub folders even even parent not included as a sub folder could be included
+			    		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=65637)
+			    		if (Util.isValidFolderNameForPackage(memberName, sourceLevel, complianceLevel)) {
+			    			// eliminate binary output only if nested inside direct subfolders
+			    			if (javaProject.contains(member)) {
+			    				String[] newNames = Util.arrayConcat(pkgName, manager.intern(memberName));
+			    				boolean isMemberIncluded = !Util.isExcluded(member, inclusionPatterns, exclusionPatterns);
+			    				computeFolderChildren((IFolder) member, isMemberIncluded, newNames, vChildren, inclusionPatterns, exclusionPatterns);
+			    			}
+			    		}
+			    		break;
+			    	case IResource.FILE:
+			    		// inclusion filter may only include files, in which case we still want to include the immediate parent package (lazily)
+			    		if (!hasIncluded
+			    				&& Util.isValidCompilationUnitName(memberName, sourceLevel, complianceLevel)
+								&& !Util.isExcluded(member, inclusionPatterns, exclusionPatterns)) {
+			    			hasIncluded = true;
+			    			IPackageFragment pkg = getPackageFragment(pkgName);
+			    			vChildren.add(pkg);
+			    		}
+			    		break;
+				}
+			}
+		}
+	} catch(IllegalArgumentException e){
+		throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST); // could be thrown by ElementTree when path is not found
+	} catch (CoreException e) {
+		throw new JavaModelException(e);
+	}
+}
+
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#copy
+ */
+public void copy(
+	IPath destination,
+	int updateResourceFlags,
+	int updateModelFlags,
+	IClasspathEntry sibling,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	CopyPackageFragmentRootOperation op =
+		new CopyPackageFragmentRootOperation(this, destination, updateResourceFlags, updateModelFlags, sibling);
+	op.runOperation(monitor);
+}
+
+/**
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return new PackageFragmentRootInfo();
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public IPackageFragment createPackageFragment(String pkgName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CreatePackageFragmentOperation op = new CreatePackageFragmentOperation(this, pkgName, force);
+	op.runOperation(monitor);
+	return getPackageFragment(op.pkgName);
+}
+
+/**
+ * Returns the root's kind - K_SOURCE or K_BINARY, defaults
+ * to K_SOURCE if it is not on the classpath.
+ *
+ * @exception JavaModelException if the project and root do
+ * 		not exist.
+ */
+protected int determineKind(IResource underlyingResource) throws JavaModelException {
+	IClasspathEntry entry = ((JavaProject)getJavaProject()).getClasspathEntryFor(underlyingResource.getFullPath());
+	if (entry != null) {
+		return entry.getContentKind();
+	}
+	return IPackageFragmentRoot.K_SOURCE;
+}
+
+/**
+ * Compares two objects for equality;
+ * for <code>PackageFragmentRoot</code>s, equality is having the
+ * same parent, same resources, and occurrence count.
+ *
+ */
+public boolean equals(Object o) {
+	if (this == o)
+		return true;
+	if (!(o instanceof PackageFragmentRoot))
+		return false;
+	PackageFragmentRoot other = (PackageFragmentRoot) o;
+	return resource().equals(other.resource()) &&
+			this.parent.equals(other.parent);
+}
+
+private IClasspathEntry findSourceAttachmentRecommendation() {
+	try {
+		IPath rootPath = getPath();
+		IClasspathEntry entry;
+
+		// try on enclosing project first
+		JavaProject parentProject = (JavaProject) getJavaProject();
+		try {
+			entry = parentProject.getClasspathEntryFor(rootPath);
+			if (entry != null) {
+				Object target = JavaModel.getTarget(entry.getSourceAttachmentPath(), true);
+				if (target != null) {
+					return entry;
+				}
+			}
+		} catch(JavaModelException e){
+			// ignore
+		}
+
+		// iterate over all projects
+		IJavaModel model = getJavaModel();
+		IJavaProject[] jProjects = model.getJavaProjects();
+		for (int i = 0, max = jProjects.length; i < max; i++){
+			JavaProject jProject = (JavaProject) jProjects[i];
+			if (jProject == parentProject) continue; // already done
+			try {
+				entry = jProject.getClasspathEntryFor(rootPath);
+				if (entry != null){
+					Object target = JavaModel.getTarget(entry.getSourceAttachmentPath(), true);
+					if (target != null) {
+						return entry;
+					}
+				}
+			} catch(JavaModelException e){
+				// ignore
+			}
+		}
+	} catch(JavaModelException e){
+		// ignore
+	}
+
+	return null;
+}
+
+/*
+ * Returns the exclusion patterns from the classpath entry associated with this root.
+ */
+public char[][] fullExclusionPatternChars() {
+	try {
+		if (isOpen() && getKind() != IPackageFragmentRoot.K_SOURCE) return null;
+		ClasspathEntry entry = (ClasspathEntry) getRawClasspathEntry();
+		if (entry == null) {
+			return null;
+		} else {
+			return entry.fullExclusionPatternChars();
+		}
+	} catch (JavaModelException e) {
+		return null;
+	}
+}
+
+/*
+ * Returns the inclusion patterns from the classpath entry associated with this root.
+ */
+public char[][] fullInclusionPatternChars() {
+	try {
+		if (isOpen() && getKind() != IPackageFragmentRoot.K_SOURCE) return null;
+		ClasspathEntry entry = (ClasspathEntry)getRawClasspathEntry();
+		if (entry == null) {
+			return null;
+		} else {
+			return entry.fullInclusionPatternChars();
+		}
+	} catch (JavaModelException e) {
+		return null;
+	}
+}
+public String getElementName() {
+	IResource res = resource();
+	if (res instanceof IFolder)
+		return ((IFolder) res).getName();
+	return ""; //$NON-NLS-1$
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return PACKAGE_FRAGMENT_ROOT;
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_PACKAGEFRAGMENTROOT;
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner owner) {
+	switch (token.charAt(0)) {
+		case JEM_PACKAGEFRAGMENT:
+			String[] pkgName;
+			if (memento.hasMoreTokens()) {
+				token = memento.nextToken();
+				char firstChar = token.charAt(0);
+				if (firstChar == JEM_CLASSFILE || firstChar == JEM_COMPILATIONUNIT || firstChar == JEM_COUNT) {
+					pkgName = CharOperation.NO_STRINGS;
+				} else {
+					pkgName = Util.splitOn('.', token, 0, token.length());
+					token = null;
+				}
+			} else {
+				pkgName = CharOperation.NO_STRINGS;
+				token = null;
+			}
+			JavaElement pkg = getPackageFragment(pkgName);
+			if (token == null) {
+				return pkg.getHandleFromMemento(memento, owner);
+			} else {
+				return pkg.getHandleFromMemento(token, memento, owner);
+			}
+	}
+	return null;
+}
+/**
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	IPath path;
+	IResource underlyingResource = getResource();
+	if (underlyingResource != null) {
+		// internal jar or regular root
+		if (resource().getProject().equals(getJavaProject().getProject())) {
+			path = underlyingResource.getProjectRelativePath();
+		} else {
+			path = underlyingResource.getFullPath();
+		}
+	} else {
+		// external jar
+		path = getPath();
+	}
+	((JavaElement)getParent()).getHandleMemento(buff);
+	buff.append(getHandleMementoDelimiter());
+	escapeMementoName(buff, path.toString());
+}
+/**
+ * @see IPackageFragmentRoot
+ */
+public int getKind() throws JavaModelException {
+	return ((PackageFragmentRootInfo)getElementInfo()).getRootKind();
+}
+
+/*
+ * A version of getKind() that doesn't update the timestamp of the info in the Java model cache
+ * to speed things up
+ */
+int internalKind() throws JavaModelException {
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	PackageFragmentRootInfo info = (PackageFragmentRootInfo) manager.peekAtInfo(this);
+	if (info == null) {
+		info = (PackageFragmentRootInfo) openWhenClosed(createElementInfo(), false, null);
+	}
+	return info.getRootKind();
+}
+
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+public Object[] getNonJavaResources() throws JavaModelException {
+	return ((PackageFragmentRootInfo) getElementInfo()).getNonJavaResources(getJavaProject(), resource(), this);
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public IPackageFragment getPackageFragment(String packageName) {
+	// tolerate package names with spaces (e.g. 'x . y') (http://bugs.eclipse.org/bugs/show_bug.cgi?id=21957)
+	String[] pkgName = Util.getTrimmedSimpleNames(packageName);
+	return getPackageFragment(pkgName);
+}
+public PackageFragment getPackageFragment(String[] pkgName) {
+	return new PackageFragment(this, pkgName);
+}
+/**
+ * Returns the package name for the given folder
+ * (which is a decendent of this root).
+ */
+protected String getPackageName(IFolder folder) {
+	IPath myPath= getPath();
+	IPath pkgPath= folder.getFullPath();
+	int mySegmentCount= myPath.segmentCount();
+	int pkgSegmentCount= pkgPath.segmentCount();
+	StringBuffer pkgName = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME);
+	for (int i= mySegmentCount; i < pkgSegmentCount; i++) {
+		if (i > mySegmentCount) {
+			pkgName.append('.');
+		}
+		pkgName.append(pkgPath.segment(i));
+	}
+	return pkgName.toString();
+}
+
+/**
+ * @see IJavaElement
+ */
+public IPath getPath() {
+	return internalPath();
+}
+
+public IPath internalPath() {
+	return resource().getFullPath();
+}
+/*
+ * @see IPackageFragmentRoot
+ */
+public IClasspathEntry getRawClasspathEntry() throws JavaModelException {
+
+	IClasspathEntry rawEntry = null;
+	JavaProject project = (JavaProject)getJavaProject();
+	project.getResolvedClasspath(); // force the reverse rawEntry cache to be populated
+	Map rootPathToRawEntries = project.getPerProjectInfo().rootPathToRawEntries;
+	if (rootPathToRawEntries != null) {
+		rawEntry = (IClasspathEntry) rootPathToRawEntries.get(getPath());
+	}
+	if (rawEntry == null) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH, this));
+	}
+	return rawEntry;
+}
+/*
+ * @see IPackageFragmentRoot
+ */
+public IClasspathEntry getResolvedClasspathEntry() throws JavaModelException {
+	IClasspathEntry resolvedEntry = null;
+	JavaProject project = (JavaProject)getJavaProject();
+	project.getResolvedClasspath(); // force the resolved entry cache to be populated
+	Map rootPathToResolvedEntries = project.getPerProjectInfo().rootPathToResolvedEntries;
+	if (rootPathToResolvedEntries != null) {
+		resolvedEntry = (IClasspathEntry) rootPathToResolvedEntries.get(getPath());
+	}
+	if (resolvedEntry == null) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH, this));
+	}
+	return resolvedEntry;
+}
+
+
+public IResource resource() {
+	if (this.resource != null) // perf improvement to avoid message send in resource()
+		return this.resource;
+	return super.resource();
+}
+/*
+ * @see IJavaElement
+ */
+public IResource resource(PackageFragmentRoot root) {
+	return this.resource;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public IPath getSourceAttachmentPath() throws JavaModelException {
+	if (getKind() != K_BINARY) return null;
+
+	// 1) look source attachment property (set iff attachSource(...) was called
+	IPath path = getPath();
+	String serverPathString= Util.getSourceAttachmentProperty(path);
+	if (serverPathString != null) {
+		int index= serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
+		if (index < 0) {
+			// no root path specified
+			return new Path(serverPathString);
+		} else {
+			String serverSourcePathString= serverPathString.substring(0, index);
+			return new Path(serverSourcePathString);
+		}
+	}
+
+	// 2) look at classpath entry
+	IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(path);
+	IPath sourceAttachmentPath;
+	if (entry != null && (sourceAttachmentPath = entry.getSourceAttachmentPath()) != null)
+		return sourceAttachmentPath;
+
+	// 3) look for a recommendation
+	entry = findSourceAttachmentRecommendation();
+	if (entry != null && (sourceAttachmentPath = entry.getSourceAttachmentPath()) != null) {
+		return sourceAttachmentPath;
+	}
+
+	return null;
+}
+
+/**
+ * For use by <code>AttachSourceOperation</code> only.
+ * Sets the source mapper associated with this root.
+ */
+public void setSourceMapper(SourceMapper mapper) throws JavaModelException {
+	((PackageFragmentRootInfo) getElementInfo()).setSourceMapper(mapper);
+}
+
+
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public IPath getSourceAttachmentRootPath() throws JavaModelException {
+	if (getKind() != K_BINARY) return null;
+
+	// 1) look source attachment property (set iff attachSource(...) was called
+	IPath path = getPath();
+	String serverPathString= Util.getSourceAttachmentProperty(path);
+	if (serverPathString != null) {
+		int index = serverPathString.lastIndexOf(ATTACHMENT_PROPERTY_DELIMITER);
+		if (index == -1) return null;
+		String serverRootPathString= IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH;
+		if (index != serverPathString.length() - 1) {
+			serverRootPathString= serverPathString.substring(index + 1);
+		}
+		return new Path(serverRootPathString);
+	}
+
+	// 2) look at classpath entry
+	IClasspathEntry entry = ((JavaProject) getParent()).getClasspathEntryFor(path);
+	IPath sourceAttachmentRootPath;
+	if (entry != null && (sourceAttachmentRootPath = entry.getSourceAttachmentRootPath()) != null)
+		return sourceAttachmentRootPath;
+
+	// 3) look for a recomendation
+	entry = findSourceAttachmentRecommendation();
+	if (entry != null && (sourceAttachmentRootPath = entry.getSourceAttachmentRootPath()) != null)
+		return sourceAttachmentRootPath;
+
+	return null;
+}
+
+/**
+ * @see JavaElement
+ */
+public SourceMapper getSourceMapper() {
+	SourceMapper mapper;
+	try {
+		PackageFragmentRootInfo rootInfo = (PackageFragmentRootInfo) getElementInfo();
+		mapper = rootInfo.getSourceMapper();
+		if (mapper == null) {
+			// first call to this method
+			IPath sourcePath= getSourceAttachmentPath();
+			IPath rootPath= getSourceAttachmentRootPath();
+			if (sourcePath == null)
+				mapper = createSourceMapper(getPath(), rootPath); // attach root to itself
+			else
+				mapper = createSourceMapper(sourcePath, rootPath);
+			rootInfo.setSourceMapper(mapper);
+		}
+	} catch (JavaModelException e) {
+		// no source can be attached
+		mapper = null;
+	}
+	return mapper;
+}
+
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+	if (!exists()) throw newNotPresentException();
+	return resource();
+}
+
+/**
+ * @see IParent
+ */
+public boolean hasChildren() throws JavaModelException {
+	// a package fragment root always has the default package as a child
+	return true;
+}
+
+public int hashCode() {
+	return resource().hashCode();
+}
+
+public boolean ignoreOptionalProblems() {
+	try {
+		return ((PackageFragmentRootInfo) getElementInfo()).ignoreOptionalProblems(this);
+	} catch (JavaModelException e) {
+		return false;
+	}
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public boolean isArchive() {
+	return false;
+}
+
+/**
+ * @see IPackageFragmentRoot
+ */
+public boolean isExternal() {
+	return false;
+}
+
+/*
+ * Validate whether this package fragment root is on the classpath of its project.
+ */
+protected IStatus validateOnClasspath() {
+
+	IPath path = getPath();
+	try {
+		// check package fragment root on classpath of its project
+		JavaProject project = (JavaProject) getJavaProject();
+		IClasspathEntry entry = project.getClasspathEntryFor(path);
+		if (entry != null) {
+			return Status.OK_STATUS;
+		}
+	} catch(JavaModelException e){
+		// could not read classpath, then assume it is outside
+		return e.getJavaModelStatus();
+	}
+	return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_NOT_ON_CLASSPATH, this);
+}
+/*
+ * @see org.eclipse.jdt.core.IPackageFragmentRoot#move
+ */
+public void move(
+	IPath destination,
+	int updateResourceFlags,
+	int updateModelFlags,
+	IClasspathEntry sibling,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	MovePackageFragmentRootOperation op =
+		new MovePackageFragmentRootOperation(this, destination, updateResourceFlags, updateModelFlags, sibling);
+	op.runOperation(monitor);
+}
+
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	IPath path = getPath();
+	if (isExternal()) {
+		buffer.append(path.toOSString());
+	} else if (getJavaProject().getElementName().equals(path.segment(0))) {
+	    if (path.segmentCount() == 1) {
+			buffer.append("<project root>"); //$NON-NLS-1$
+	    } else {
+			buffer.append(path.removeFirstSegments(1).makeRelative());
+	    }
+	} else {
+		buffer.append(path);
+	}
+	if (info == null) {
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	}
+}
+
+protected IStatus validateExistence(IResource underlyingResource) {
+	// check whether this pkg fragment root can be opened
+	IStatus status = validateOnClasspath();
+	if (!status.isOK())
+		return status;
+	if (!resourceExists(underlyingResource))
+		return newDoesNotExistStatus();
+	return JavaModelStatus.VERIFIED_OK;
+}
+
+/**
+ * Possible failures: <ul>
+ *  <li>ELEMENT_NOT_PRESENT - the root supplied to the operation
+ *      does not exist
+ *  <li>INVALID_ELEMENT_TYPES - the root is not of kind K_BINARY
+ *   <li>RELATIVE_PATH - the path supplied to this operation must be
+ *      an absolute path
+ *  </ul>
+ */
+protected void verifyAttachSource(IPath sourcePath) throws JavaModelException {
+	if (!exists()) {
+		throw newNotPresentException();
+	} else if (getKind() != K_BINARY) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this));
+	} else if (sourcePath != null && !sourcePath.isAbsolute()) {
+		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.RELATIVE_PATH, sourcePath));
+	}
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
new file mode 100644
index 0000000..431b9c7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * The element info for <code>PackageFragmentRoot</code>s.
+ */
+class PackageFragmentRootInfo extends OpenableElementInfo {
+
+	/**
+	 * The SourceMapper for this JAR (or <code>null</code> if
+	 * this JAR does not have source attached).
+	 */
+	protected SourceMapper sourceMapper = null;
+
+	/**
+	 * The kind of the root associated with this info.
+	 * Valid kinds are: <ul>
+	 * <li><code>IPackageFragmentRoot.K_SOURCE</code>
+	 * <li><code>IPackageFragmentRoot.K_BINARY</code></ul>
+	 */
+	protected int rootKind= IPackageFragmentRoot.K_SOURCE;
+
+	/**
+	 * A array with all the non-java resources contained by this PackageFragment
+	 */
+	protected Object[] nonJavaResources;
+
+	private boolean ignoreOptionalProblems;
+	private boolean initialized;
+/**
+ * Create and initialize a new instance of the receiver
+ */
+public PackageFragmentRootInfo() {
+	this.nonJavaResources = null;
+	this.initialized = false;
+}
+/**
+ * Starting at this folder, create non-java resources for this package fragment root
+ * and add them to the non-java resources collection.
+ *
+ * @exception JavaModelException  The resource associated with this package fragment does not exist
+ */
+static Object[] computeFolderNonJavaResources(IPackageFragmentRoot root, IContainer folder, char[][] inclusionPatterns, char[][] exclusionPatterns) throws JavaModelException {
+	IResource[] nonJavaResources = new IResource[5];
+	int nonJavaResourcesCounter = 0;
+	JavaProject project = (JavaProject) root.getJavaProject();
+	try {
+		IClasspathEntry[] classpath = project.getResolvedClasspath();
+		IResource[] members = folder.members();
+		int length = members.length;
+		if (length > 0) {
+			String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+			String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+			nextResource: for (int i = 0; i < length; i++) {
+				IResource member = members[i];
+				switch (member.getType()) {
+					case IResource.FILE :
+						String fileName = member.getName();
+
+						// ignore .java files that are not excluded
+						if (Util.isValidCompilationUnitName(fileName, sourceLevel, complianceLevel) && !Util.isExcluded(member, inclusionPatterns, exclusionPatterns))
+							continue nextResource;
+						// ignore .class files
+						if (Util.isValidClassFileName(fileName, sourceLevel, complianceLevel))
+							continue nextResource;
+						// ignore .zip or .jar file on classpath
+						if (isClasspathEntry(member.getFullPath(), classpath))
+							continue nextResource;
+						break;
+
+					case IResource.FOLDER :
+						// ignore valid packages or excluded folders that correspond to a nested pkg fragment root
+						if (Util.isValidFolderNameForPackage(member.getName(), sourceLevel, complianceLevel)
+								&& (!Util.isExcluded(member, inclusionPatterns, exclusionPatterns)
+										|| isClasspathEntry(member.getFullPath(), classpath)))
+							continue nextResource;
+						break;
+				}
+				if (nonJavaResources.length == nonJavaResourcesCounter) {
+					// resize
+					System.arraycopy(nonJavaResources, 0, (nonJavaResources = new IResource[nonJavaResourcesCounter * 2]), 0, nonJavaResourcesCounter);
+				}
+				nonJavaResources[nonJavaResourcesCounter++] = member;
+			}
+		}
+		if (ExternalFoldersManager.isInternalPathForExternalFolder(folder.getFullPath())) {
+			IJarEntryResource[] jarEntryResources = new IJarEntryResource[nonJavaResourcesCounter];
+			for (int i = 0; i < nonJavaResourcesCounter; i++) {
+				jarEntryResources[i] = new NonJavaResource(root, nonJavaResources[i]);
+			}
+			return jarEntryResources;
+		} else if (nonJavaResources.length != nonJavaResourcesCounter) {
+			System.arraycopy(nonJavaResources, 0, (nonJavaResources = new IResource[nonJavaResourcesCounter]), 0, nonJavaResourcesCounter);
+		}
+		return nonJavaResources;
+	} catch (CoreException e) {
+		throw new JavaModelException(e);
+	}
+}
+/**
+ * Compute the non-package resources of this package fragment root.
+ */
+private Object[] computeNonJavaResources(IResource underlyingResource, PackageFragmentRoot handle) {
+	Object[] resources = NO_NON_JAVA_RESOURCES;
+	try {
+		// the underlying resource may be a folder or a project (in the case that the project folder
+		// is actually the package fragment root)
+		if (underlyingResource.getType() == IResource.FOLDER || underlyingResource.getType() == IResource.PROJECT) {
+			resources =
+				computeFolderNonJavaResources(
+					handle,
+					(IContainer) underlyingResource,
+					handle.fullInclusionPatternChars(),
+					handle.fullExclusionPatternChars());
+		}
+	} catch (JavaModelException e) {
+		// ignore
+	}
+	return resources;
+}
+/**
+ * Returns an array of non-java resources contained in the receiver.
+ */
+synchronized Object[] getNonJavaResources(IJavaProject project, IResource underlyingResource, PackageFragmentRoot handle) {
+	Object[] resources = this.nonJavaResources;
+	if (resources == null) {
+		resources = computeNonJavaResources(underlyingResource, handle);
+		this.nonJavaResources = resources;
+	}
+	return resources;
+}
+/**
+ * Returns the kind of this root.
+ */
+public int getRootKind() {
+	return this.rootKind;
+}
+/**
+ * Retuns the SourceMapper for this root, or <code>null</code>
+ * if this root does not have attached source.
+ */
+protected SourceMapper getSourceMapper() {
+	return this.sourceMapper;
+}
+boolean ignoreOptionalProblems(PackageFragmentRoot packageFragmentRoot) throws JavaModelException {
+	if (this.initialized == false) {
+		this.ignoreOptionalProblems = ((ClasspathEntry) packageFragmentRoot.getRawClasspathEntry()).ignoreOptionalProblems();
+		this.initialized = true;
+	}
+	return this.ignoreOptionalProblems;
+}
+private static boolean isClasspathEntry(IPath path, IClasspathEntry[] resolvedClasspath) {
+	for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
+		IClasspathEntry entry = resolvedClasspath[i];
+		if (entry.getPath().equals(path)) {
+			return true;
+		}
+	}
+	return false;
+}
+/**
+ * Set the fNonJavaResources to res value
+ */
+void setNonJavaResources(Object[] resources) {
+	this.nonJavaResources = resources;
+}
+/**
+ * Sets the kind of this root.
+ */
+protected void setRootKind(int newRootKind) {
+	this.rootKind = newRootKind;
+}
+/**
+ * Sets the SourceMapper for this root.
+ */
+protected void setSourceMapper(SourceMapper mapper) {
+	this.sourceMapper= mapper;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java
new file mode 100644
index 0000000..266411b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ProjectReferenceChange {
+
+	private JavaProject project;
+	private IClasspathEntry[] oldResolvedClasspath;
+
+	public ProjectReferenceChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
+		this.project = project;
+		this.oldResolvedClasspath = oldResolvedClasspath;
+	}
+
+	/*
+	 * Update projects references so that the build order is consistent with the classpath
+	 */
+	public void updateProjectReferencesIfNecessary() throws JavaModelException {
+		
+		String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath);
+		IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath();
+		String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath);
+		final IProject projectResource = this.project.getProject();
+		
+		try {
+			IProject[] projectReferences = projectResource.getDescription().getDynamicReferences();
+			
+			HashSet oldReferences = new HashSet(projectReferences.length);
+			for (int i = 0; i < projectReferences.length; i++){
+				String projectName = projectReferences[i].getName();
+				oldReferences.add(projectName);
+			}
+			HashSet newReferences = (HashSet)oldReferences.clone();
+	
+			for (int i = 0; i < oldRequired.length; i++){
+				String projectName = oldRequired[i];
+				newReferences.remove(projectName);
+			}
+			for (int i = 0; i < newRequired.length; i++){
+				String projectName = newRequired[i];
+				newReferences.add(projectName);
+			}
+	
+			Iterator iter;
+			int newSize = newReferences.size();
+			
+			checkIdentity: {
+				if (oldReferences.size() == newSize){
+					iter = newReferences.iterator();
+					while (iter.hasNext()){
+						if (!oldReferences.contains(iter.next())){
+							break checkIdentity;
+						}
+					}
+					return;
+				}
+			}
+			String[] requiredProjectNames = new String[newSize];
+			int index = 0;
+			iter = newReferences.iterator();
+			while (iter.hasNext()){
+				requiredProjectNames[index++] = (String)iter.next();
+			}
+			Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent
+			
+			final IProject[] requiredProjectArray = new IProject[newSize];
+			IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot();
+			for (int i = 0; i < newSize; i++){
+				requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]);
+			}
+				
+			// ensure that a scheduling rule is used so that the project description is not modified by another thread while we update it
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214981
+			// also ensure that if no change (checkIdentify block returned above) we don't reach here
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241751
+			IWorkspace workspace = projectResource.getWorkspace();
+			ISchedulingRule rule = workspace.getRuleFactory().modifyRule(projectResource); // scheduling rule for modifying the project
+			IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+				public void run(IProgressMonitor monitor) throws CoreException {
+					IProjectDescription description = projectResource.getDescription();
+					description.setDynamicReferences(requiredProjectArray);
+					projectResource.setDescription(description, IResource.AVOID_NATURE_CONFIG, null);
+				}
+			};
+			workspace.run(runnable, rule, IWorkspace.AVOID_UPDATE, null);
+		} catch(CoreException e){
+			if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(this.project.getElementName()))
+				throw new JavaModelException(e);
+		}
+	}
+	public String toString() {
+		return "ProjectRefenceChange: " + this.project.getElementName(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
new file mode 100644
index 0000000..8095a3d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CompilationParticipant;
+import org.eclipse.jdt.core.compiler.ReconcileContext;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Reconcile a working copy and signal the changes through a delta.
+ * <p>
+ * High level summmary of what a reconcile does:
+ * <ul>
+ * <li>populates the model with the new working copy contents</li>
+ * <li>fires a fine grained delta (flag F_FINE_GRAINED) describing the difference between the previous content
+ *      and the new content (which method was added/removed, which field was changed, etc.)</li>
+ * <li>computes problems and reports them to the IProblemRequestor (begingReporting(), n x acceptProblem(...), endReporting()) iff
+ *     	(working copy is not consistent with its buffer || forceProblemDetection is set)
+ * 		&& problem requestor is active
+ * </li>
+ * <li>produces a DOM AST (either JLS_2, JLS_3 or NO_AST) that is resolved if flag is set</li>
+ * <li>notifies compilation participants of the reconcile allowing them to participate in this operation and report problems</li>
+ * </ul>
+ */
+public class ReconcileWorkingCopyOperation extends JavaModelOperation {
+	public static boolean PERF = false;
+
+	public int astLevel;
+	public boolean resolveBindings;
+	public HashMap problems;
+	public int reconcileFlags;
+	WorkingCopyOwner workingCopyOwner;
+	public org.eclipse.jdt.core.dom.CompilationUnit ast;
+	public JavaElementDeltaBuilder deltaBuilder;
+	public boolean requestorIsActive;
+
+	public ReconcileWorkingCopyOperation(IJavaElement workingCopy, int astLevel, int reconcileFlags, WorkingCopyOwner workingCopyOwner) {
+		super(new IJavaElement[] {workingCopy});
+		this.astLevel = astLevel;
+		this.reconcileFlags = reconcileFlags;
+		this.workingCopyOwner = workingCopyOwner;
+	}
+
+	/**
+	 * @exception JavaModelException if setting the source
+	 * 	of the original compilation unit fails
+	 */
+	protected void executeOperation() throws JavaModelException {
+		checkCanceled();
+		try {
+			beginTask(Messages.element_reconciling, 2);
+
+			CompilationUnit workingCopy = getWorkingCopy();
+			boolean wasConsistent = workingCopy.isConsistent();
+
+			// check is problem requestor is active
+			IProblemRequestor problemRequestor = workingCopy.getPerWorkingCopyInfo();
+			if (problemRequestor != null)
+				problemRequestor =  ((JavaModelManager.PerWorkingCopyInfo)problemRequestor).getProblemRequestor();
+			boolean defaultRequestorIsActive = problemRequestor != null && problemRequestor.isActive();
+			IProblemRequestor ownerProblemRequestor = this.workingCopyOwner.getProblemRequestor(workingCopy);
+			boolean ownerRequestorIsActive = ownerProblemRequestor != null && ownerProblemRequestor != problemRequestor && ownerProblemRequestor.isActive();
+			this.requestorIsActive = defaultRequestorIsActive || ownerRequestorIsActive;
+
+			// create the delta builder (this remembers the current content of the cu)
+			this.deltaBuilder = new JavaElementDeltaBuilder(workingCopy);
+
+			// make working copy consistent if needed and compute AST if needed
+			makeConsistent(workingCopy);
+
+			// notify reconcile participants only if working copy was not consistent or if forcing problem detection
+			// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=177319)
+			if (!wasConsistent || ((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0)) {
+				notifyParticipants(workingCopy);
+
+				// recreate ast if one participant reset it
+				if (this.ast == null)
+					makeConsistent(workingCopy);
+			}
+
+			// report problems
+			if (this.problems != null && (((this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) || !wasConsistent)) {
+				if (defaultRequestorIsActive) {
+					reportProblems(workingCopy, problemRequestor);
+				}
+				if (ownerRequestorIsActive) {
+					reportProblems(workingCopy, ownerProblemRequestor);
+				}
+			}
+
+			// report delta
+			JavaElementDelta delta = this.deltaBuilder.delta;
+			if (delta != null) {
+				addReconcileDelta(workingCopy, delta);
+			}
+		} finally {
+			done();
+		}
+	}
+
+	/**
+	 * Report working copy problems to a given requestor.
+	 *
+	 * @param workingCopy
+	 * @param problemRequestor
+	 */
+	private void reportProblems(CompilationUnit workingCopy, IProblemRequestor problemRequestor) {
+		try {
+			problemRequestor.beginReporting();
+			for (Iterator iteraror = this.problems.values().iterator(); iteraror.hasNext();) {
+				CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next();
+				if (categorizedProblems == null) continue;
+				for (int i = 0, length = categorizedProblems.length; i < length; i++) {
+					CategorizedProblem problem = categorizedProblems[i];
+					if (JavaModelManager.VERBOSE){
+						System.out.println("PROBLEM FOUND while reconciling : " + problem.getMessage());//$NON-NLS-1$
+					}
+					if (this.progressMonitor != null && this.progressMonitor.isCanceled()) break;
+					problemRequestor.acceptProblem(problem);
+				}
+			}
+		} finally {
+			problemRequestor.endReporting();
+		}
+	}
+
+	/**
+	 * Returns the working copy this operation is working on.
+	 */
+	protected CompilationUnit getWorkingCopy() {
+		return (CompilationUnit)getElementToProcess();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.JavaModelOperation#isReadOnly()
+	 */
+	public boolean isReadOnly() {
+		return true;
+	}
+
+	/*
+	 * Makes the given working copy consistent, computes the delta and computes an AST if needed.
+	 * Returns the AST.
+	 */
+	public org.eclipse.jdt.core.dom.CompilationUnit makeConsistent(CompilationUnit workingCopy) throws JavaModelException {
+		if (!workingCopy.isConsistent()) {
+			// make working copy consistent
+			if (this.problems == null) this.problems = new HashMap();
+			this.resolveBindings = this.requestorIsActive;
+			this.ast = workingCopy.makeConsistent(this.astLevel, this.resolveBindings, this.reconcileFlags, this.problems, this.progressMonitor);
+			this.deltaBuilder.buildDeltas();
+			if (this.ast != null && this.deltaBuilder.delta != null)
+				this.deltaBuilder.delta.changedAST(this.ast);
+			return this.ast;
+		}
+		if (this.ast != null)
+			return this.ast; // no need to recompute AST if known already
+
+		CompilationUnitDeclaration unit = null;
+		try {
+			JavaModelManager.getJavaModelManager().abortOnMissingSource.set(Boolean.TRUE);
+			CompilationUnit source = workingCopy.cloneCachingContents();
+			// find problems if needed
+			if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject())
+					&& (this.reconcileFlags & ICompilationUnit.FORCE_PROBLEM_DETECTION) != 0) {
+				this.resolveBindings = this.requestorIsActive;
+				if (this.problems == null)
+					this.problems = new HashMap();
+				unit =
+					CompilationUnitProblemFinder.process(
+						source,
+						this.workingCopyOwner,
+						this.problems,
+						this.astLevel != ICompilationUnit.NO_AST/*creating AST if level is not NO_AST */,
+						this.reconcileFlags,
+						this.progressMonitor);
+				if (this.progressMonitor != null) this.progressMonitor.worked(1);
+			}
+
+			// create AST if needed
+			if (this.astLevel != ICompilationUnit.NO_AST
+					&& unit !=null/*unit is null if working copy is consistent && (problem detection not forced || non-Java project) -> don't create AST as per API*/) {
+				Map options = workingCopy.getJavaProject().getOptions(true);
+				// convert AST
+				this.ast =
+					AST.convertCompilationUnit(
+						this.astLevel,
+						unit,
+						options,
+						this.resolveBindings,
+						source,
+						this.reconcileFlags,
+						this.progressMonitor);
+				if (this.ast != null) {
+					if (this.deltaBuilder.delta == null) {
+						this.deltaBuilder.delta = new JavaElementDelta(workingCopy);
+					}
+					this.deltaBuilder.delta.changedAST(this.ast);
+				}
+				if (this.progressMonitor != null) this.progressMonitor.worked(1);
+			}
+	    } catch (JavaModelException e) {
+	    	if (JavaProject.hasJavaNature(workingCopy.getJavaProject().getProject()))
+	    		throw e;
+	    	// else JavaProject has lost its nature (or most likely was closed/deleted) while reconciling -> ignore
+	    	// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100919)
+	    } finally {
+			JavaModelManager.getJavaModelManager().abortOnMissingSource.set(null);
+	        if (unit != null) {
+	            unit.cleanUp();
+	        }
+	    }
+		return this.ast;
+	}
+
+	private void notifyParticipants(final CompilationUnit workingCopy) {
+		IJavaProject javaProject = getWorkingCopy().getJavaProject();
+		CompilationParticipant[] participants = JavaModelManager.getJavaModelManager().compilationParticipants.getCompilationParticipants(javaProject);
+		if (participants == null) return;
+
+		final ReconcileContext context = new ReconcileContext(this, workingCopy);
+		for (int i = 0, length = participants.length; i < length; i++) {
+			final CompilationParticipant participant = participants[i];
+			SafeRunner.run(new ISafeRunnable() {
+				public void handleException(Throwable exception) {
+					if (exception instanceof Error) {
+						throw (Error) exception; // errors are not supposed to be caught
+					} else if (exception instanceof OperationCanceledException)
+						throw (OperationCanceledException) exception;
+					else if (exception instanceof UnsupportedOperationException) {
+						// might want to disable participant as it tried to modify the buffer of the working copy being reconciled
+						Util.log(exception, "Reconcile participant attempted to modify the buffer of the working copy being reconciled"); //$NON-NLS-1$
+					} else
+						Util.log(exception, "Exception occurred in reconcile participant"); //$NON-NLS-1$
+				}
+				public void run() throws Exception {
+					participant.reconcile(context);
+				}
+			});
+		}
+	}
+
+	protected IJavaModelStatus verify() {
+		IJavaModelStatus status = super.verify();
+		if (!status.isOK()) {
+			return status;
+		}
+		CompilationUnit workingCopy = getWorkingCopy();
+		if (!workingCopy.isWorkingCopy()) {
+			return new JavaModelStatus(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed
+		}
+		return status;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java
new file mode 100644
index 0000000..e7de845
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IParent;
+import org.eclipse.jdt.core.IRegion;
+
+/**
+ * @see IRegion
+ */
+
+public class Region implements IRegion {
+
+	/**
+	 * A collection of the top level elements
+	 * that have been added to the region
+	 */
+	protected ArrayList rootElements;
+/**
+ * Creates an empty region.
+ *
+ * @see IRegion
+ */
+public Region() {
+	this.rootElements = new ArrayList(1);
+}
+/**
+ * @see IRegion#add(IJavaElement)
+ */
+public void add(IJavaElement element) {
+	if (!contains(element)) {
+		//"new" element added to region
+		removeAllChildren(element);
+		this.rootElements.add(element);
+		this.rootElements.trimToSize();
+	}
+}
+/**
+ * @see IRegion
+ */
+public boolean contains(IJavaElement element) {
+
+	int size = this.rootElements.size();
+	ArrayList parents = getAncestors(element);
+
+	for (int i = 0; i < size; i++) {
+		IJavaElement aTop = (IJavaElement) this.rootElements.get(i);
+		if (aTop.equals(element)) {
+			return true;
+		}
+		for (int j = 0, pSize = parents.size(); j < pSize; j++) {
+			if (aTop.equals(parents.get(j))) {
+				//an ancestor is already included
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/**
+ * Returns a collection of all the parents of this element
+ * in bottom-up order.
+ *
+ */
+private ArrayList getAncestors(IJavaElement element) {
+	ArrayList parents = new ArrayList();
+	IJavaElement parent = element.getParent();
+	while (parent != null) {
+		parents.add(parent);
+		parent = parent.getParent();
+	}
+	parents.trimToSize();
+	return parents;
+}
+/**
+ * @see IRegion
+ */
+public IJavaElement[] getElements() {
+	int size= this.rootElements.size();
+	IJavaElement[] roots= new IJavaElement[size];
+	for (int i = 0; i < size; i++) {
+		roots[i]= (IJavaElement) this.rootElements.get(i);
+	}
+
+	return roots;
+}
+/**
+ * @see IRegion#remove(IJavaElement)
+ */
+public boolean remove(IJavaElement element) {
+
+	removeAllChildren(element);
+	return this.rootElements.remove(element);
+}
+/**
+ * Removes any children of this element that are contained within this
+ * region as this parent is about to be added to the region.
+ *
+ * <p>Children are all children, not just direct children.
+ */
+protected void removeAllChildren(IJavaElement element) {
+	if (element instanceof IParent) {
+		ArrayList newRootElements = new ArrayList();
+		for (int i = 0, size = this.rootElements.size(); i < size; i++) {
+			IJavaElement currentRoot = (IJavaElement)this.rootElements.get(i);
+			//walk the current root hierarchy
+			IJavaElement parent = currentRoot.getParent();
+			boolean isChild= false;
+			while (parent != null) {
+				if (parent.equals(element)) {
+					isChild= true;
+					break;
+				}
+				parent = parent.getParent();
+			}
+			if (!isChild) {
+				newRootElements.add(currentRoot);
+			}
+		}
+		this.rootElements= newRootElements;
+	}
+}
+/**
+ * Returns a printable representation of this region.
+ */
+public String toString() {
+	StringBuffer buffer= new StringBuffer();
+	IJavaElement[] roots= getElements();
+	buffer.append('[');
+	for (int i= 0; i < roots.length; i++) {
+		buffer.append(roots[i].getElementName());
+		if (i < (roots.length - 1)) {
+			buffer.append(", "); //$NON-NLS-1$
+		}
+	}
+	buffer.append(']');
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java
new file mode 100644
index 0000000..dc6b6ca
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.ISourceReference;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation renames elements.
+ *
+ * <p>Notes:<ul>
+ * <li>Resource rename is not supported - this operation only renames
+ *	   elements contained in compilation units.
+ * <li>When a main type is renamed, its compilation unit and constructors are renamed.
+ * <li>Constructors cannot be renamed.
+ * </ul>
+ */
+public class RenameElementsOperation extends MoveElementsOperation {
+/**
+ * When executed, this operation will rename the specified elements with the given names in the
+ * corresponding destinations.
+ */
+public RenameElementsOperation(IJavaElement[] elements, IJavaElement[] destinations, String[] newNames, boolean force) {
+	//a rename is a move to the same parent with a new name specified
+	//these elements are from different parents
+	super(elements, destinations, force);
+	setRenamings(newNames);
+}
+/**
+ * @see MultiOperation
+ */
+protected String getMainTaskName() {
+	return Messages.operation_renameElementProgress;
+}
+/**
+ * @see CopyElementsOperation#isRename()
+ */
+protected boolean isRename() {
+	return true;
+}
+/**
+ * @see MultiOperation
+ */
+protected IJavaModelStatus verify() {
+	IJavaModelStatus status = super.verify();
+	if (! status.isOK())
+		return status;
+	if (this.renamingsList == null || this.renamingsList.length == 0)
+		return new JavaModelStatus(IJavaModelStatusConstants.NULL_NAME);
+	return JavaModelStatus.VERIFIED_OK;
+}
+/**
+ * @see MultiOperation
+ */
+protected void verify(IJavaElement element) throws JavaModelException {
+	if (element == null || !element.exists())
+		error(IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST, element);
+
+	if (element.isReadOnly())
+		error(IJavaModelStatusConstants.READ_ONLY, element);
+
+	if (!(element instanceof ISourceReference))
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+
+	int elementType = element.getElementType();
+	if (elementType < IJavaElement.TYPE || elementType == IJavaElement.INITIALIZER)
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+
+	verifyRenaming(element);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java
new file mode 100644
index 0000000..f9579e1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * This operation renames resources (Package fragments and compilation units).
+ *
+ * <p>Notes:<ul>
+ * <li>When a compilation unit is renamed, its main type and the constructors of the
+ * 		main type are renamed.
+ * </ul>
+ */
+public class RenameResourceElementsOperation extends MoveResourceElementsOperation {
+/**
+ * When executed, this operation will rename the specified elements with the given names in the
+ * corresponding destinations.
+ */
+public RenameResourceElementsOperation(IJavaElement[] elements, IJavaElement[] destinations, String[] newNames, boolean force) {
+	//a rename is a move to the same parent with a new name specified
+	//these elements are from different parents
+	super(elements, destinations, force);
+	setRenamings(newNames);
+}
+/**
+ * @see MultiOperation
+ */
+protected String getMainTaskName() {
+	return Messages.operation_renameResourceProgress;
+}
+/**
+ * @see CopyResourceElementsOperation#isRename()
+ */
+protected boolean isRename() {
+	return true;
+}
+/**
+ * @see MultiOperation
+ */
+protected void verify(IJavaElement element) throws JavaModelException {
+	super.verify(element);
+
+	int elementType = element.getElementType();
+
+	if (!(elementType == IJavaElement.COMPILATION_UNIT || elementType == IJavaElement.PACKAGE_FRAGMENT)) {
+		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+	}
+	if (elementType == IJavaElement.COMPILATION_UNIT) {
+		CompilationUnit cu = (CompilationUnit)element;
+		if (cu.isWorkingCopy() && !cu.isPrimary()) {
+			error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
+		}
+	}
+	verifyRenaming(element);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
new file mode 100644
index 0000000..78f79aa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a binary field that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved field. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryField extends BinaryField {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryField(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryField#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IField#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.uniqueKey);
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceRefElement handle = new BinaryField(this.parent, this.name);
+		handle.occurrenceCount = this.occurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
new file mode 100644
index 0000000..d36c8d4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a binary method that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved method. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryMethod extends BinaryMethod {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
+		super(parent, name, parameterTypes);
+		this.uniqueKey = uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryMethod#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IMethod#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.uniqueKey);
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceRefElement handle = new BinaryMethod(this.parent, this.name, this.parameterTypes);
+		handle.occurrenceCount = this.occurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
new file mode 100644
index 0000000..1c5d2e7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Handle representing a binary type that is resolved.
+ * The uniqueKey contains the genericTypeSignature of the resolved type. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryType extends BinaryType {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryType(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+
+	public String getFullyQualifiedParameterizedName() throws JavaModelException {
+		return getFullyQualifiedParameterizedName(getFullyQualifiedName('.'), this.uniqueKey);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryType#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryType#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.uniqueKey);
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceRefElement handle = new BinaryType(this.parent, this.name);
+		handle.occurrenceCount = this.occurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
new file mode 100644
index 0000000..89826b1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a source field that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved field. Use BindingKey to decode it.
+ */
+public class ResolvedSourceField extends SourceField {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceField(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceField#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IField#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.getKey());
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceRefElement handle = new SourceField(this.parent, this.name);
+		handle.occurrenceCount = this.occurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
new file mode 100644
index 0000000..415c44b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a source method that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved method. Use BindingKey to decode it.
+ */
+public class ResolvedSourceMethod extends SourceMethod {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
+		super(parent, name, parameterTypes);
+		this.uniqueKey = uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceMethod#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IMethod#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.getKey());
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceRefElement handle = new SourceMethod(this.parent, this.name, this.parameterTypes);
+		handle.occurrenceCount = this.occurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
new file mode 100644
index 0000000..4a02dd4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Handle representing a source type that is resolved.
+ * The uniqueKey contains the genericTypeSignature of the resolved type. Use BindingKey to decode it.
+ */
+public class ResolvedSourceType extends SourceType {
+
+	private String uniqueKey;
+
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceType(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+
+	public String getFullyQualifiedParameterizedName() throws JavaModelException {
+		return getFullyQualifiedParameterizedName(getFullyQualifiedName('.'), this.uniqueKey);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceType#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceType#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+		super.toStringInfo(tab, buffer, info, showResolvedInfo);
+		if (showResolvedInfo) {
+			buffer.append(" {key="); //$NON-NLS-1$
+			buffer.append(this.getKey());
+			buffer.append("}"); //$NON-NLS-1$
+		}
+	}
+
+	public JavaElement unresolved() {
+		SourceType handle = new SourceType(this.parent, this.name);
+		handle.occurrenceCount = this.occurrenceCount;
+		handle.localOccurrenceCount = this.localOccurrenceCount;
+		return handle;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
new file mode 100644
index 0000000..913f3e7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -0,0 +1,709 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.codeassist.ISearchRequestor;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.IRestrictedAccessConstructorRequestor;
+import org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ *	This class provides a <code>SearchableBuilderEnvironment</code> for code assist which
+ *	uses the Java model as a search tool.
+ */
+public class SearchableEnvironment
+	implements INameEnvironment, IJavaSearchConstants {
+
+	public NameLookup nameLookup;
+	protected ICompilationUnit unitToSkip;
+	protected org.eclipse.jdt.core.ICompilationUnit[] workingCopies;
+	protected WorkingCopyOwner owner;
+
+	protected JavaProject project;
+	protected IJavaSearchScope searchScope;
+
+	protected boolean checkAccessRestrictions;
+
+	/**
+	 * Creates a SearchableEnvironment on the given project
+	 */
+	public SearchableEnvironment(JavaProject project, org.eclipse.jdt.core.ICompilationUnit[] workingCopies) throws JavaModelException {
+		this.project = project;
+		this.checkAccessRestrictions =
+			!JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+			|| !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true));
+		this.workingCopies = workingCopies;
+		this.nameLookup = project.newNameLookup(workingCopies);
+	}
+
+	/**
+	 * Creates a SearchableEnvironment on the given project
+	 */
+	public SearchableEnvironment(JavaProject project, WorkingCopyOwner owner) throws JavaModelException {
+		this(project, owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary WCs*/));
+		this.owner = owner;
+	}
+
+	private static int convertSearchFilterToModelFilter(int searchFilter) {
+		switch (searchFilter) {
+			case IJavaSearchConstants.CLASS:
+				return NameLookup.ACCEPT_CLASSES;
+			case IJavaSearchConstants.INTERFACE:
+				return NameLookup.ACCEPT_INTERFACES;
+			case IJavaSearchConstants.ENUM:
+				return NameLookup.ACCEPT_ENUMS;
+			case IJavaSearchConstants.ANNOTATION_TYPE:
+				return NameLookup.ACCEPT_ANNOTATIONS;
+			case IJavaSearchConstants.CLASS_AND_ENUM:
+				return NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_ENUMS;
+			case IJavaSearchConstants.CLASS_AND_INTERFACE:
+				return NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES;
+			default:
+				return NameLookup.ACCEPT_ALL;
+		}
+	}
+	/**
+	 * Returns the given type in the the given package if it exists,
+	 * otherwise <code>null</code>.
+	 */
+	protected NameEnvironmentAnswer find(String typeName, String packageName) {
+		if (packageName == null)
+			packageName = IPackageFragment.DEFAULT_PACKAGE_NAME;
+		if (this.owner != null) {
+			String source = this.owner.findSource(typeName, packageName);
+			if (source != null) {
+				ICompilationUnit cu = new BasicCompilationUnit(source.toCharArray(), CharOperation.splitOn('.', packageName.toCharArray()), typeName + Util.defaultJavaExtension());
+				return new NameEnvironmentAnswer(cu, null);
+			}
+		}
+		NameLookup.Answer answer =
+			this.nameLookup.findType(
+				typeName,
+				packageName,
+				false/*exact match*/,
+				NameLookup.ACCEPT_ALL,
+				this.checkAccessRestrictions);
+		if (answer != null) {
+			// construct name env answer
+			if (answer.type instanceof BinaryType) { // BinaryType
+				try {
+					return new NameEnvironmentAnswer((IBinaryType) ((BinaryType) answer.type).getElementInfo(), answer.restriction);
+				} catch (JavaModelException npe) {
+					// fall back to using owner
+				}
+			} else { //SourceType
+				try {
+					// retrieve the requested type
+					SourceTypeElementInfo sourceType = (SourceTypeElementInfo)((SourceType) answer.type).getElementInfo();
+					ISourceType topLevelType = sourceType;
+					while (topLevelType.getEnclosingType() != null) {
+						topLevelType = topLevelType.getEnclosingType();
+					}
+					// find all siblings (other types declared in same unit, since may be used for name resolution)
+					IType[] types = sourceType.getHandle().getCompilationUnit().getTypes();
+					ISourceType[] sourceTypes = new ISourceType[types.length];
+
+					// in the resulting collection, ensure the requested type is the first one
+					sourceTypes[0] = sourceType;
+					int length = types.length;
+					for (int i = 0, index = 1; i < length; i++) {
+						ISourceType otherType =
+							(ISourceType) ((JavaElement) types[i]).getElementInfo();
+						if (!otherType.equals(topLevelType) && index < length) // check that the index is in bounds (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=62861)
+							sourceTypes[index++] = otherType;
+					}
+					return new NameEnvironmentAnswer(sourceTypes, answer.restriction);
+				} catch (JavaModelException jme) {
+					if (jme.isDoesNotExist() && String.valueOf(TypeConstants.PACKAGE_INFO_NAME).equals(typeName)) {
+						// in case of package-info.java the type doesn't exist in the model,
+						// but the CU may still help in order to fetch package level annotations.
+						return new NameEnvironmentAnswer((ICompilationUnit)answer.type.getParent(), answer.restriction);
+					}
+					// no usable answer
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Find the packages that start with the given prefix.
+	 * A valid prefix is a qualified name separated by periods
+	 * (ex. java.util).
+	 * The packages found are passed to:
+	 *    ISearchRequestor.acceptPackage(char[][] packageName)
+	 */
+	public void findPackages(char[] prefix, ISearchRequestor requestor) {
+		this.nameLookup.seekPackageFragments(
+			new String(prefix),
+			true,
+			new SearchableEnvironmentRequestor(requestor));
+	}
+
+	/**
+	 * Find the top-level types that are defined
+	 * in the current environment and whose simple name matches the given name.
+	 *
+	 * The types found are passed to one of the following methods (if additional
+	 * information is known about the types):
+	 *    ISearchRequestor.acceptType(char[][] packageName, char[] typeName)
+	 *    ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers)
+	 *    ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers)
+	 *
+	 * This method can not be used to find member types... member
+	 * types are found relative to their enclosing type.
+	 */
+	public void findExactTypes(char[] name, final boolean findMembers, int searchFor, final ISearchRequestor storage) {
+
+		try {
+			final String excludePath;
+			if (this.unitToSkip != null) {
+				if (!(this.unitToSkip instanceof IJavaElement)) {
+					// revert to model investigation
+					findExactTypes(
+						new String(name),
+						storage,
+						convertSearchFilterToModelFilter(searchFor));
+					return;
+				}
+				excludePath = ((IJavaElement) this.unitToSkip).getPath().toString();
+			} else {
+				excludePath = null;
+			}
+
+			IProgressMonitor progressMonitor = new IProgressMonitor() {
+				boolean isCanceled = false;
+				public void beginTask(String n, int totalWork) {
+					// implements interface method
+				}
+				public void done() {
+					// implements interface method
+				}
+				public void internalWorked(double work) {
+					// implements interface method
+				}
+				public boolean isCanceled() {
+					return this.isCanceled;
+				}
+				public void setCanceled(boolean value) {
+					this.isCanceled = value;
+				}
+				public void setTaskName(String n) {
+					// implements interface method
+				}
+				public void subTask(String n) {
+					// implements interface method
+				}
+				public void worked(int work) {
+					// implements interface method
+				}
+			};
+			IRestrictedAccessTypeRequestor typeRequestor = new IRestrictedAccessTypeRequestor() {
+				public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+					if (excludePath != null && excludePath.equals(path))
+						return;
+					if (!findMembers && enclosingTypeNames != null && enclosingTypeNames.length > 0)
+						return; // accept only top level types
+					storage.acceptType(packageName, simpleTypeName, enclosingTypeNames, modifiers, access);
+				}
+			};
+			try {
+				new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
+					null,
+					SearchPattern.R_EXACT_MATCH,
+					name,
+					SearchPattern.R_EXACT_MATCH,
+					searchFor,
+					getSearchScope(),
+					typeRequestor,
+					CANCEL_IF_NOT_READY_TO_SEARCH,
+					progressMonitor);
+			} catch (OperationCanceledException e) {
+				findExactTypes(
+					new String(name),
+					storage,
+					convertSearchFilterToModelFilter(searchFor));
+			}
+		} catch (JavaModelException e) {
+			findExactTypes(
+				new String(name),
+				storage,
+				convertSearchFilterToModelFilter(searchFor));
+		}
+	}
+
+	/**
+	 * Returns all types whose simple name matches with the given <code>name</code>.
+	 */
+	private void findExactTypes(String name, ISearchRequestor storage, int type) {
+		SearchableEnvironmentRequestor requestor =
+			new SearchableEnvironmentRequestor(storage, this.unitToSkip, this.project, this.nameLookup);
+		this.nameLookup.seekTypes(name, null, false, type, requestor);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[][])
+	 */
+	public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
+		if (compoundTypeName == null) return null;
+
+		int length = compoundTypeName.length;
+		if (length <= 1) {
+			if (length == 0) return null;
+			return find(new String(compoundTypeName[0]), null);
+		}
+
+		int lengthM1 = length - 1;
+		char[][] packageName = new char[lengthM1][];
+		System.arraycopy(compoundTypeName, 0, packageName, 0, lengthM1);
+
+		return find(
+			new String(compoundTypeName[lengthM1]),
+			CharOperation.toString(packageName));
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#findType(char[], char[][])
+	 */
+	public NameEnvironmentAnswer findType(char[] name, char[][] packageName) {
+		if (name == null) return null;
+
+		return find(
+			new String(name),
+			packageName == null || packageName.length == 0 ? null : CharOperation.toString(packageName));
+	}
+
+	/**
+	 * Find the top-level types that are defined
+	 * in the current environment and whose name starts with the
+	 * given prefix. The prefix is a qualified name separated by periods
+	 * or a simple name (ex. java.util.V or V).
+	 *
+	 * The types found are passed to one of the following methods (if additional
+	 * information is known about the types):
+	 *    ISearchRequestor.acceptType(char[][] packageName, char[] typeName)
+	 *    ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers)
+	 *    ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers)
+	 *
+	 * This method can not be used to find member types... member
+	 * types are found relative to their enclosing type.
+	 */
+	public void findTypes(char[] prefix, final boolean findMembers, boolean camelCaseMatch, int searchFor, final ISearchRequestor storage) {
+		findTypes(prefix, findMembers, camelCaseMatch, searchFor, storage, null);
+	}
+	/**
+	 * Must be used only by CompletionEngine.
+	 * The progress monitor is used to be able to cancel completion operations
+	 * 
+	 * Find the top-level types that are defined
+	 * in the current environment and whose name starts with the
+	 * given prefix. The prefix is a qualified name separated by periods
+	 * or a simple name (ex. java.util.V or V).
+	 *
+	 * The types found are passed to one of the following methods (if additional
+	 * information is known about the types):
+	 *    ISearchRequestor.acceptType(char[][] packageName, char[] typeName)
+	 *    ISearchRequestor.acceptClass(char[][] packageName, char[] typeName, int modifiers)
+	 *    ISearchRequestor.acceptInterface(char[][] packageName, char[] typeName, int modifiers)
+	 *
+	 * This method can not be used to find member types... member
+	 * types are found relative to their enclosing type.
+	 */
+	public void findTypes(char[] prefix, final boolean findMembers, boolean camelCaseMatch, int searchFor, final ISearchRequestor storage, IProgressMonitor monitor) {
+		
+		/*
+			if (true){
+				findTypes(new String(prefix), storage, NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
+				return;
+			}
+		*/
+		try {
+			final String excludePath;
+			if (this.unitToSkip != null) {
+				if (!(this.unitToSkip instanceof IJavaElement)) {
+					// revert to model investigation
+					findTypes(
+						new String(prefix),
+						storage,
+						convertSearchFilterToModelFilter(searchFor));
+					return;
+				}
+				excludePath = ((IJavaElement) this.unitToSkip).getPath().toString();
+			} else {
+				excludePath = null;
+			}
+			int lastDotIndex = CharOperation.lastIndexOf('.', prefix);
+			char[] qualification, simpleName;
+			if (lastDotIndex < 0) {
+				qualification = null;
+				if (camelCaseMatch) {
+					simpleName = prefix;
+				} else {
+					simpleName = CharOperation.toLowerCase(prefix);
+				}
+			} else {
+				qualification = CharOperation.subarray(prefix, 0, lastDotIndex);
+				if (camelCaseMatch) {
+					simpleName = CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length);
+				} else {
+					simpleName =
+						CharOperation.toLowerCase(
+							CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length));
+				}
+			}
+
+			IProgressMonitor progressMonitor = new IProgressMonitor() {
+				boolean isCanceled = false;
+				public void beginTask(String name, int totalWork) {
+					// implements interface method
+				}
+				public void done() {
+					// implements interface method
+				}
+				public void internalWorked(double work) {
+					// implements interface method
+				}
+				public boolean isCanceled() {
+					return this.isCanceled;
+				}
+				public void setCanceled(boolean value) {
+					this.isCanceled = value;
+				}
+				public void setTaskName(String name) {
+					// implements interface method
+				}
+				public void subTask(String name) {
+					// implements interface method
+				}
+				public void worked(int work) {
+					// implements interface method
+				}
+			};
+			IRestrictedAccessTypeRequestor typeRequestor = new IRestrictedAccessTypeRequestor() {
+				public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+					if (excludePath != null && excludePath.equals(path))
+						return;
+					if (!findMembers && enclosingTypeNames != null && enclosingTypeNames.length > 0)
+						return; // accept only top level types
+					storage.acceptType(packageName, simpleTypeName, enclosingTypeNames, modifiers, access);
+				}
+			};
+			
+			int matchRule = SearchPattern.R_PREFIX_MATCH;
+			if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH;
+			if (monitor != null) {
+				IndexManager indexManager = JavaModelManager.getIndexManager();
+				if (indexManager.awaitingJobsCount() == 0) {
+					// indexes were already there, so perform an immediate search to avoid any index rebuilt
+					new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
+						qualification,
+						SearchPattern.R_EXACT_MATCH,
+						simpleName,
+						matchRule, // not case sensitive
+						searchFor,
+						getSearchScope(),
+						typeRequestor,
+						FORCE_IMMEDIATE_SEARCH,
+						progressMonitor);
+				} else {
+					// indexes were not ready, give the indexing a chance to finish small jobs by sleeping 100ms...
+					try {
+						Thread.sleep(100);
+					} catch (InterruptedException e) {
+						// Do nothing
+					}
+					if (monitor.isCanceled()) {
+						throw new OperationCanceledException();
+					}
+					if (indexManager.awaitingJobsCount() == 0) {
+						// indexes are now ready, so perform an immediate search to avoid any index rebuilt
+						new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
+							qualification,
+							SearchPattern.R_EXACT_MATCH,
+							simpleName,
+							matchRule, // not case sensitive
+							searchFor,
+							getSearchScope(),
+							typeRequestor,
+							FORCE_IMMEDIATE_SEARCH,
+							progressMonitor);
+					} else {
+						// Indexes are still not ready, so look for types in the model instead of a search request
+						findTypes(
+							new String(prefix),
+							storage,
+							convertSearchFilterToModelFilter(searchFor));
+					}
+				}
+			} else {
+				try {
+					new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
+						qualification,
+						SearchPattern.R_EXACT_MATCH,
+						simpleName,
+						matchRule, // not case sensitive
+						searchFor,
+						getSearchScope(),
+						typeRequestor,
+						CANCEL_IF_NOT_READY_TO_SEARCH,
+						progressMonitor);
+				} catch (OperationCanceledException e) {
+					findTypes(
+						new String(prefix),
+						storage,
+						convertSearchFilterToModelFilter(searchFor));
+				}
+			}
+		} catch (JavaModelException e) {
+			findTypes(
+				new String(prefix),
+				storage,
+				convertSearchFilterToModelFilter(searchFor));
+		}
+	}
+	
+	/**
+	 * Must be used only by CompletionEngine.
+	 * The progress monitor is used to be able to cancel completion operations
+	 * 
+	 * Find constructor declarations that are defined
+	 * in the current environment and whose name starts with the
+	 * given prefix. The prefix is a qualified name separated by periods
+	 * or a simple name (ex. java.util.V or V).
+	 *
+	 * The constructors found are passed to one of the following methods:
+	 *    ISearchRequestor.acceptConstructor(...)
+	 */
+	public void findConstructorDeclarations(char[] prefix, boolean camelCaseMatch, final ISearchRequestor storage, IProgressMonitor monitor) {
+		try {
+			final String excludePath;
+			if (this.unitToSkip != null && this.unitToSkip instanceof IJavaElement) {
+				excludePath = ((IJavaElement) this.unitToSkip).getPath().toString();
+			} else {
+				excludePath = null;
+			}
+			
+			int lastDotIndex = CharOperation.lastIndexOf('.', prefix);
+			char[] qualification, simpleName;
+			if (lastDotIndex < 0) {
+				qualification = null;
+				if (camelCaseMatch) {
+					simpleName = prefix;
+				} else {
+					simpleName = CharOperation.toLowerCase(prefix);
+				}
+			} else {
+				qualification = CharOperation.subarray(prefix, 0, lastDotIndex);
+				if (camelCaseMatch) {
+					simpleName = CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length);
+				} else {
+					simpleName =
+						CharOperation.toLowerCase(
+							CharOperation.subarray(prefix, lastDotIndex + 1, prefix.length));
+				}
+			}
+
+			IProgressMonitor progressMonitor = new IProgressMonitor() {
+				boolean isCanceled = false;
+				public void beginTask(String name, int totalWork) {
+					// implements interface method
+				}
+				public void done() {
+					// implements interface method
+				}
+				public void internalWorked(double work) {
+					// implements interface method
+				}
+				public boolean isCanceled() {
+					return this.isCanceled;
+				}
+				public void setCanceled(boolean value) {
+					this.isCanceled = value;
+				}
+				public void setTaskName(String name) {
+					// implements interface method
+				}
+				public void subTask(String name) {
+					// implements interface method
+				}
+				public void worked(int work) {
+					// implements interface method
+				}
+			};
+			
+			IRestrictedAccessConstructorRequestor constructorRequestor = new IRestrictedAccessConstructorRequestor() {
+				public void acceptConstructor(
+						int modifiers,
+						char[] simpleTypeName,
+						int parameterCount,
+						char[] signature,
+						char[][] parameterTypes,
+						char[][] parameterNames,
+						int typeModifiers,
+						char[] packageName,
+						int extraFlags,
+						String path,
+						AccessRestriction access) {
+					if (excludePath != null && excludePath.equals(path))
+						return;
+					
+					storage.acceptConstructor(
+							modifiers,
+							simpleTypeName,
+							parameterCount,
+							signature,
+							parameterTypes,
+							parameterNames, 
+							typeModifiers,
+							packageName,
+							extraFlags,
+							path,
+							access);
+				}
+			};
+			
+			int matchRule = SearchPattern.R_PREFIX_MATCH;
+			if (camelCaseMatch) matchRule |= SearchPattern.R_CAMELCASE_MATCH;
+			if (monitor != null) {
+				IndexManager indexManager = JavaModelManager.getIndexManager();
+				while (indexManager.awaitingJobsCount() > 0) {
+					try {
+						Thread.sleep(50); // indexes are not ready,  sleep 50ms...
+					} catch (InterruptedException e) {
+						// Do nothing
+					}
+					if (monitor.isCanceled()) {
+						throw new OperationCanceledException();
+					}
+				}
+				new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations(
+						qualification,
+						simpleName,
+						matchRule,
+						getSearchScope(),
+						constructorRequestor,
+						FORCE_IMMEDIATE_SEARCH,
+						progressMonitor);
+			} else {
+				try {
+					new BasicSearchEngine(this.workingCopies).searchAllConstructorDeclarations(
+							qualification,
+							simpleName,
+							matchRule,
+							getSearchScope(),
+							constructorRequestor,
+							CANCEL_IF_NOT_READY_TO_SEARCH,
+							progressMonitor);
+				} catch (OperationCanceledException e) {
+					// Do nothing
+				}
+			}
+		} catch (JavaModelException e) {
+			// Do nothing
+		}
+	}
+
+	/**
+	 * Returns all types whose name starts with the given (qualified) <code>prefix</code>.
+	 *
+	 * If the <code>prefix</code> is unqualified, all types whose simple name matches
+	 * the <code>prefix</code> are returned.
+	 */
+	private void findTypes(String prefix, ISearchRequestor storage, int type) {
+		//TODO (david) should add camel case support
+		SearchableEnvironmentRequestor requestor =
+			new SearchableEnvironmentRequestor(storage, this.unitToSkip, this.project, this.nameLookup);
+		int index = prefix.lastIndexOf('.');
+		if (index == -1) {
+			this.nameLookup.seekTypes(prefix, null, true, type, requestor);
+		} else {
+			String packageName = prefix.substring(0, index);
+			JavaElementRequestor elementRequestor = new JavaElementRequestor();
+			this.nameLookup.seekPackageFragments(packageName, false, elementRequestor);
+			IPackageFragment[] fragments = elementRequestor.getPackageFragments();
+			if (fragments != null) {
+				String className = prefix.substring(index + 1);
+				for (int i = 0, length = fragments.length; i < length; i++)
+					if (fragments[i] != null)
+						this.nameLookup.seekTypes(className, fragments[i], true, type, requestor);
+			}
+		}
+	}
+
+	private IJavaSearchScope getSearchScope() {
+		if (this.searchScope == null) {
+			// Create search scope with visible entry on the project's classpath
+			if(this.checkAccessRestrictions) {
+				this.searchScope = BasicSearchEngine.createJavaSearchScope(new IJavaElement[] {this.project});
+			} else {
+				this.searchScope = BasicSearchEngine.createJavaSearchScope(this.nameLookup.packageFragmentRoots);
+			}
+		}
+		return this.searchScope;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#isPackage(char[][], char[])
+	 */
+	public boolean isPackage(char[][] parentPackageName, char[] subPackageName) {
+		String[] pkgName;
+		if (parentPackageName == null)
+			pkgName = new String[] {new String(subPackageName)};
+		else {
+			int length = parentPackageName.length;
+			pkgName = new String[length+1];
+			for (int i = 0; i < length; i++)
+				pkgName[i] = new String(parentPackageName[i]);
+			pkgName[length] = new String(subPackageName);
+		}
+		return 
+			(this.owner != null && this.owner.isPackage(pkgName))
+			|| this.nameLookup.isPackage(pkgName);
+	}
+
+	/**
+	 * Returns a printable string for the array.
+	 */
+	protected String toStringChar(char[] name) {
+		return "["  //$NON-NLS-1$
+		+ new String(name) + "]" ; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns a printable string for the array.
+	 */
+	protected String toStringCharChar(char[][] names) {
+		StringBuffer result = new StringBuffer();
+		for (int i = 0; i < names.length; i++) {
+			result.append(toStringChar(names[i]));
+		}
+		return result.toString();
+	}
+
+	public void cleanup() {
+		// nothing to do
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
new file mode 100644
index 0000000..49bfd18
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.codeassist.ISearchRequestor;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * Implements <code>IJavaElementRequestor</code>, wrappering and forwarding
+ * results onto a <code>org.eclipse.jdt.internal.codeassist.api.ISearchRequestor</code>.
+ */
+class SearchableEnvironmentRequestor extends JavaElementRequestor {
+	/**
+	 * The <code>ISearchRequestor</code> this JavaElementRequestor wraps
+	 * and forwards results to.
+	 */
+	protected ISearchRequestor requestor;
+	/**
+	 * The <code>ICompilationUNit</code> this JavaElementRequestor will not
+	 * accept types within.
+	 */
+	protected ICompilationUnit unitToSkip;
+
+	protected IJavaProject project;
+
+	protected NameLookup nameLookup;
+
+	protected boolean checkAccessRestrictions;
+/**
+ * Constructs a SearchableEnvironmentRequestor that wraps the
+ * given SearchRequestor.
+ */
+public SearchableEnvironmentRequestor(ISearchRequestor requestor) {
+	this.requestor = requestor;
+	this.unitToSkip= null;
+	this.project= null;
+	this.nameLookup= null;
+	this.checkAccessRestrictions = false;
+
+}
+/**
+ * Constructs a SearchableEnvironmentRequestor that wraps the
+ * given SearchRequestor.  The requestor will not accept types in
+ * the <code>unitToSkip</code>.
+ */
+public SearchableEnvironmentRequestor(ISearchRequestor requestor, ICompilationUnit unitToSkip, IJavaProject project, NameLookup nameLookup) {
+	this.requestor = requestor;
+	this.unitToSkip= unitToSkip;
+	this.project= project;
+	this.nameLookup = nameLookup;
+	this.checkAccessRestrictions =
+		!JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+		|| !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true));
+}
+/**
+ * Do nothing, a SearchRequestor does not accept initializers
+ * so there is no need to forward this results.
+ *
+ * @see IJavaElementRequestor
+ */
+public void acceptInitializer(IInitializer initializer) {
+	// implements interface method
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptPackageFragment(IPackageFragment packageFragment) {
+	this.requestor.acceptPackage(packageFragment.getElementName().toCharArray());
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptType(IType type) {
+	try {
+		if (this.unitToSkip != null && this.unitToSkip.equals(type.getCompilationUnit())){
+			return;
+		}
+		char[] packageName = type.getPackageFragment().getElementName().toCharArray();
+		boolean isBinary = type instanceof BinaryType;
+
+		// determine associated access restriction
+		AccessRestriction accessRestriction = null;
+
+		if (this.checkAccessRestrictions && (isBinary || !type.getJavaProject().equals(this.project))) {
+			PackageFragmentRoot root = (PackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			ClasspathEntry entry = (ClasspathEntry) this.nameLookup.rootToResolvedEntries.get(root);
+			if (entry != null) { // reverse map always contains resolved CP entry
+				AccessRuleSet accessRuleSet = entry.getAccessRuleSet();
+				if (accessRuleSet != null) {
+					// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
+					char[][] packageChars = CharOperation.splitOn('.', packageName);
+					char[] fileWithoutExtension = type.getElementName().toCharArray();
+					accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, fileWithoutExtension, '/'));
+				}
+			}
+		}
+		this.requestor.acceptType(packageName, type.getElementName().toCharArray(), null, type.getFlags(), accessRestriction);
+	} catch (JavaModelException jme) {
+		// ignore
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
new file mode 100644
index 0000000..7accbff
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
@@ -0,0 +1,1027 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.core.util.HandleFactory;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Implementation of <code>ISelectionRequestor</code> to assist with
+ * code resolve in a compilation unit. Translates names to elements.
+ */
+public class SelectionRequestor implements ISelectionRequestor {
+	/*
+	 * The name lookup facility used to resolve packages
+	 */
+	protected NameLookup nameLookup;
+
+	/*
+	 * The compilation unit or class file we are resolving in
+	 */
+	protected Openable openable;
+
+	/*
+	 * The collection of resolved elements.
+	 */
+	protected IJavaElement[] elements = JavaElement.NO_ELEMENTS;
+	protected int elementIndex = -1;
+
+	protected HandleFactory handleFactory = new HandleFactory();
+
+/**
+ * Creates a selection requestor that uses that given
+ * name lookup facility to resolve names.
+ *
+ * Fix for 1FVXGDK
+ */
+public SelectionRequestor(NameLookup nameLookup, Openable openable) {
+	super();
+	this.nameLookup = nameLookup;
+	this.openable = openable;
+}
+private void acceptBinaryMethod(
+		IType type,
+		IMethod method,
+		char[] uniqueKey,
+		boolean isConstructor) {
+	try {
+		if(!isConstructor || ((JavaElement)method).getClassFile().getBuffer() == null) {
+			if (uniqueKey != null) {
+				ResolvedBinaryMethod resolvedMethod = new ResolvedBinaryMethod(
+						(JavaElement)method.getParent(),
+						method.getElementName(),
+						method.getParameterTypes(),
+						new String(uniqueKey));
+				resolvedMethod.occurrenceCount = method.getOccurrenceCount();
+				method = resolvedMethod;
+			}
+
+			addElement(method);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+				System.out.print(method.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		} else {
+			ISourceRange range = method.getSourceRange();
+			if (range.getOffset() != -1 && range.getLength() != 0 ) {
+				if (uniqueKey != null) {
+					ResolvedBinaryMethod resolvedMethod = new ResolvedBinaryMethod(
+							(JavaElement)method.getParent(),
+							method.getElementName(),
+							method.getParameterTypes(),
+							new String(uniqueKey));
+					resolvedMethod.occurrenceCount = method.getOccurrenceCount();
+					method = resolvedMethod;
+				}
+				addElement(method);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+					System.out.print(method.toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+			} else {
+				// no range was actually found, but a method was originally given -> default constructor
+				addElement(type);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+					System.out.print(type.toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+			}
+		}
+	} catch (JavaModelException e) {
+		// an exception occurs, return nothing
+	}
+}
+/**
+ * Resolve the binary method
+ *
+ * fix for 1FWFT6Q
+ */
+protected void acceptBinaryMethod(
+		IType type,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		String[] parameterSignatures,
+		char[][] typeParameterNames,
+		char[][][] typeParameterBoundNames,
+		char[] uniqueKey,
+		boolean isConstructor) {
+	IMethod method= type.getMethod(new String(selector), parameterSignatures);
+
+	if (method.exists()) {
+		if (typeParameterNames != null && typeParameterNames.length != 0) {
+			IMethod[] methods = type.findMethods(method);
+			if (methods != null && methods.length > 1) {
+				for (int i = 0; i < methods.length; i++) {
+					if (areTypeParametersCompatible(methods[i], typeParameterNames, typeParameterBoundNames)) {
+						acceptBinaryMethod(type, method, uniqueKey, isConstructor);
+					}
+				}
+				return;
+			}
+		}
+		acceptBinaryMethod(type, method, uniqueKey, isConstructor);
+	}
+}
+/**
+ * Resolve the type.
+ */
+public void acceptType(char[] packageName, char[] typeName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+	int acceptFlags = 0;
+	int kind = modifiers & (ClassFileConstants.AccInterface|ClassFileConstants.AccEnum|ClassFileConstants.AccAnnotation);
+	switch (kind) {
+		case ClassFileConstants.AccAnnotation:
+		case ClassFileConstants.AccAnnotation|ClassFileConstants.AccInterface:
+			acceptFlags = NameLookup.ACCEPT_ANNOTATIONS;
+			break;
+		case ClassFileConstants.AccEnum:
+			acceptFlags = NameLookup.ACCEPT_ENUMS;
+			break;
+		case ClassFileConstants.AccInterface:
+			acceptFlags = NameLookup.ACCEPT_INTERFACES;
+			break;
+		default:
+			acceptFlags = NameLookup.ACCEPT_CLASSES;
+			break;
+	}
+	IType type = null;
+	if(isDeclaration) {
+		type = resolveTypeByLocation(packageName, typeName, acceptFlags, start, end);
+	} else {
+		type = resolveType(packageName, typeName, acceptFlags);
+		if(type != null ) {
+			String key = uniqueKey == null ? type.getKey() : new String(uniqueKey);
+			if(type.isBinary()) {
+				ResolvedBinaryType resolvedType = new ResolvedBinaryType((JavaElement)type.getParent(), type.getElementName(), key);
+				resolvedType.occurrenceCount = type.getOccurrenceCount();
+				type = resolvedType;
+			} else {
+				ResolvedSourceType resolvedType = new ResolvedSourceType((JavaElement)type.getParent(), type.getElementName(), key);
+				resolvedType.occurrenceCount = type.getOccurrenceCount();
+				type = resolvedType;
+			}
+		}
+	}
+
+	if (type != null) {
+		addElement(type);
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+			System.out.print(type.toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+	}
+}
+/**
+ * Resolve the type.
+ */
+public void acceptType(IType type) {
+	String key = type.getKey();
+	if(type.isBinary()) {
+		ResolvedBinaryType resolvedType = new ResolvedBinaryType((JavaElement)type.getParent(), type.getElementName(), key);
+		resolvedType.occurrenceCount = type.getOccurrenceCount();
+		type = resolvedType;
+	} else {
+		ResolvedSourceType resolvedType = new ResolvedSourceType((JavaElement)type.getParent(), type.getElementName(), key);
+		resolvedType.occurrenceCount = type.getOccurrenceCount();
+		type = resolvedType;
+	}
+
+	addElement(type);
+	if(SelectionEngine.DEBUG){
+		System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+		System.out.print(type.toString());
+		System.out.println(")"); //$NON-NLS-1$
+	}
+}
+/**
+ * @see ISelectionRequestor#acceptError
+ */
+public void acceptError(CategorizedProblem error) {
+	// do nothing
+}
+/**
+ * Resolve the field.
+ */
+public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+	if(isDeclaration) {
+		IType type= resolveTypeByLocation(declaringTypePackageName, declaringTypeName,
+				NameLookup.ACCEPT_ALL,
+				start, end);
+		if(type != null) {
+			try {
+				IField[] fields = type.getFields();
+				for (int i = 0; i < fields.length; i++) {
+					IField field = fields[i];
+					ISourceRange range = field.getNameRange();
+					if(range.getOffset() <= start
+							&& range.getOffset() + range.getLength() >= end
+							&& field.getElementName().equals(new String(name))) {
+						addElement(fields[i]);
+						if(SelectionEngine.DEBUG){
+							System.out.print("SELECTION - accept field("); //$NON-NLS-1$
+							System.out.print(field.toString());
+							System.out.println(")"); //$NON-NLS-1$
+						}
+						return; // only one method is possible
+					}
+				}
+			} catch (JavaModelException e) {
+				return;
+			}
+		}
+	} else {
+		IType type= resolveType(declaringTypePackageName, declaringTypeName, NameLookup.ACCEPT_ALL);
+		if (type != null) {
+			IField field= type.getField(new String(name));
+			if (field.exists()) {
+				if (uniqueKey != null) {
+					if(field.isBinary()) {
+						ResolvedBinaryField resolvedField = new ResolvedBinaryField(
+								(JavaElement)field.getParent(),
+								field.getElementName(),
+								new String(uniqueKey));
+						resolvedField.occurrenceCount = field.getOccurrenceCount();
+						field = resolvedField;
+					} else {
+						ResolvedSourceField resolvedField = new ResolvedSourceField(
+								(JavaElement)field.getParent(),
+								field.getElementName(),
+								new String(uniqueKey));
+						resolvedField.occurrenceCount = field.getOccurrenceCount();
+						field = resolvedField;
+					}
+				}
+				addElement(field);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept field("); //$NON-NLS-1$
+					System.out.print(field.toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+			}
+		}
+	}
+}
+public void acceptLocalField(FieldBinding fieldBinding) {
+	IJavaElement res;
+	if(fieldBinding.declaringClass instanceof ParameterizedTypeBinding) {
+		LocalTypeBinding localTypeBinding = (LocalTypeBinding)((ParameterizedTypeBinding)fieldBinding.declaringClass).genericType();
+		res = findLocalElement(localTypeBinding.sourceStart());
+	} else {
+		SourceTypeBinding typeBinding = (SourceTypeBinding)fieldBinding.declaringClass;
+		res = findLocalElement(typeBinding.sourceStart());
+	}
+	if (res != null && res.getElementType() == IJavaElement.TYPE) {
+		IType type = (IType) res;
+		IField field= type.getField(new String(fieldBinding.name));
+		if (field.exists()) {
+			char[] uniqueKey = fieldBinding.computeUniqueKey();
+			if(field.isBinary()) {
+				ResolvedBinaryField resolvedField = new ResolvedBinaryField(
+						(JavaElement)field.getParent(),
+						field.getElementName(),
+						new String(uniqueKey));
+				resolvedField.occurrenceCount = field.getOccurrenceCount();
+				field = resolvedField;
+			} else {
+				ResolvedSourceField resolvedField = new ResolvedSourceField(
+						(JavaElement)field.getParent(),
+						field.getElementName(),
+						new String(uniqueKey));
+				resolvedField.occurrenceCount = field.getOccurrenceCount();
+				field = resolvedField;
+			}
+			addElement(field);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept field("); //$NON-NLS-1$
+				System.out.print(field.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+public void acceptLocalMethod(MethodBinding methodBinding) {
+	IJavaElement res = findLocalElement(methodBinding.original().sourceStart());
+	if(res != null) {
+		if(res.getElementType() == IJavaElement.METHOD) {
+			IMethod method = (IMethod) res;
+
+			char[] uniqueKey = methodBinding.computeUniqueKey();
+			if(method.isBinary()) {
+				ResolvedBinaryMethod resolvedRes = new ResolvedBinaryMethod(
+						(JavaElement)res.getParent(),
+						method.getElementName(),
+						method.getParameterTypes(),
+						new String(uniqueKey));
+				resolvedRes.occurrenceCount = method.getOccurrenceCount();
+				res = resolvedRes;
+			} else {
+				ResolvedSourceMethod resolvedRes = new ResolvedSourceMethod(
+						(JavaElement)res.getParent(),
+						method.getElementName(),
+						method.getParameterTypes(),
+						new String(uniqueKey));
+				resolvedRes.occurrenceCount = method.getOccurrenceCount();
+				res = resolvedRes;
+			}
+			addElement(res);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+				System.out.print(res.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		} else if(methodBinding.selector == TypeConstants.INIT && res.getElementType() == IJavaElement.TYPE) {
+			// it's a default constructor
+			res = ((JavaElement)res).resolved(methodBinding.declaringClass);
+			addElement(res);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+				System.out.print(res.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+public void acceptLocalType(TypeBinding typeBinding) {
+	IJavaElement res =  null;
+	if(typeBinding instanceof ParameterizedTypeBinding) {
+		LocalTypeBinding localTypeBinding = (LocalTypeBinding)((ParameterizedTypeBinding)typeBinding).genericType();
+		res = findLocalElement(localTypeBinding.sourceStart());
+	} else if(typeBinding instanceof SourceTypeBinding) {
+		res = findLocalElement(((SourceTypeBinding)typeBinding).sourceStart());
+	}
+	if(res != null && res.getElementType() == IJavaElement.TYPE) {
+		res = ((JavaElement)res).resolved(typeBinding);
+		addElement(res);
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+			System.out.print(res.toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+	}
+}
+public void acceptLocalTypeParameter(TypeVariableBinding typeVariableBinding) {
+	IJavaElement res;
+	if(typeVariableBinding.declaringElement instanceof ParameterizedTypeBinding) {
+		LocalTypeBinding localTypeBinding = (LocalTypeBinding)((ParameterizedTypeBinding)typeVariableBinding.declaringElement).genericType();
+		res = findLocalElement(localTypeBinding.sourceStart());
+	} else {
+		SourceTypeBinding typeBinding = (SourceTypeBinding)typeVariableBinding.declaringElement;
+		res = findLocalElement(typeBinding.sourceStart());
+	}
+	if (res != null && res.getElementType() == IJavaElement.TYPE) {
+		IType type = (IType) res;
+		ITypeParameter typeParameter = type.getTypeParameter(new String(typeVariableBinding.sourceName));
+		if (typeParameter.exists()) {
+			addElement(typeParameter);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type parameter("); //$NON-NLS-1$
+				System.out.print(typeParameter.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+public void acceptLocalMethodTypeParameter(TypeVariableBinding typeVariableBinding) {
+	MethodBinding methodBinding = (MethodBinding)typeVariableBinding.declaringElement;
+	IJavaElement res = findLocalElement(methodBinding.sourceStart());
+	if(res != null && res.getElementType() == IJavaElement.METHOD) {
+		IMethod method = (IMethod) res;
+
+		ITypeParameter typeParameter = method.getTypeParameter(new String(typeVariableBinding.sourceName));
+		if (typeParameter.exists()) {
+			addElement(typeParameter);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type parameter("); //$NON-NLS-1$
+				System.out.print(typeParameter.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+public void acceptLocalVariable(LocalVariableBinding binding) {
+	LocalDeclaration local = binding.declaration;
+	IJavaElement parent = findLocalElement(local.sourceStart); // findLocalElement() cannot find local variable
+	LocalVariable localVar = null;
+	if(parent != null) {
+		localVar = new LocalVariable(
+				(JavaElement)parent,
+				new String(local.name),
+				local.declarationSourceStart,
+				local.declarationSourceEnd,
+				local.sourceStart,
+				local.sourceEnd,
+				Util.typeSignature(local.type),
+				local.annotations,
+				local.modifiers,
+				local.getKind() == AbstractVariableDeclaration.PARAMETER);
+	}
+	if (localVar != null) {
+		addElement(localVar);
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept local variable("); //$NON-NLS-1$
+			System.out.print(localVar.toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+	}
+}
+/**
+ * Resolve the method
+ */
+public void acceptMethod(
+		char[] declaringTypePackageName,
+		char[] declaringTypeName,
+		String enclosingDeclaringTypeSignature,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		String[] parameterSignatures,
+		char[][] typeParameterNames,
+		char[][][] typeParameterBoundNames,
+		boolean isConstructor,
+		boolean isDeclaration,
+		char[] uniqueKey,
+		int start,
+		int end) {
+	IJavaElement[] previousElement = this.elements;
+	int previousElementIndex = this.elementIndex;
+	this.elements = JavaElement.NO_ELEMENTS;
+	this.elementIndex = -1;
+
+	if(isDeclaration) {
+		IType type = resolveTypeByLocation(declaringTypePackageName, declaringTypeName,
+				NameLookup.ACCEPT_ALL,
+				start, end);
+
+		if(type != null) {
+			acceptMethodDeclaration(type, selector, start, end);
+		}
+	} else {
+		IType type = resolveType(declaringTypePackageName, declaringTypeName,
+			NameLookup.ACCEPT_ALL);
+		// fix for 1FWFT6Q
+		if (type != null) {
+			if (type.isBinary()) {
+
+				// need to add a paramater for constructor in binary type
+				IType declaringDeclaringType = type.getDeclaringType();
+
+				boolean isStatic = false;
+				try {
+					isStatic = Flags.isStatic(type.getFlags());
+				} catch (JavaModelException e) {
+					// isStatic == false
+				}
+
+				if(declaringDeclaringType != null && isConstructor	&& !isStatic) {
+					int length = parameterPackageNames.length;
+					System.arraycopy(parameterPackageNames, 0, parameterPackageNames = new char[length+1][], 1, length);
+					System.arraycopy(parameterTypeNames, 0, parameterTypeNames = new char[length+1][], 1, length);
+					System.arraycopy(parameterSignatures, 0, parameterSignatures = new String[length+1], 1, length);
+
+					parameterPackageNames[0] = declaringDeclaringType.getPackageFragment().getElementName().toCharArray();
+					parameterTypeNames[0] = declaringDeclaringType.getTypeQualifiedName().toCharArray();
+					parameterSignatures[0] = Signature.getTypeErasure(enclosingDeclaringTypeSignature);
+				}
+
+				acceptBinaryMethod(type, selector, parameterPackageNames, parameterTypeNames, parameterSignatures, typeParameterNames, typeParameterBoundNames, uniqueKey, isConstructor);
+			} else {
+				acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames, parameterSignatures, typeParameterNames, typeParameterBoundNames, uniqueKey);
+			}
+		}
+	}
+
+	if(previousElementIndex > -1) {
+		int elementsLength = this.elementIndex + previousElementIndex + 2;
+		if(elementsLength > this.elements.length) {
+			System.arraycopy(this.elements, 0, this.elements = new IJavaElement[elementsLength * 2 + 1], 0, this.elementIndex + 1);
+		}
+		System.arraycopy(previousElement, 0, this.elements, this.elementIndex + 1, previousElementIndex + 1);
+		this.elementIndex += previousElementIndex + 1;
+	}
+}
+/**
+ * Resolve the package
+ */
+public void acceptPackage(char[] packageName) {
+	IPackageFragment[] pkgs = this.nameLookup.findPackageFragments(new String(packageName), false);
+	if (pkgs != null) {
+		for (int i = 0, length = pkgs.length; i < length; i++) {
+			addElement(pkgs[i]);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept package("); //$NON-NLS-1$
+				System.out.print(pkgs[i].toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+/**
+ * Resolve the source method
+ *
+ * fix for 1FWFT6Q
+ */
+protected void acceptSourceMethod(
+		IType type,
+		char[] selector,
+		char[][] parameterPackageNames,
+		char[][] parameterTypeNames,
+		String[] parameterSignatures,
+		char[][] typeParameterNames,
+		char[][][] typeParameterBoundNames,
+		char[] uniqueKey) {
+
+	String name = new String(selector);
+	IMethod[] methods = null;
+	try {
+		methods = type.getMethods();
+		for (int i = 0; i < methods.length; i++) {
+			if (methods[i].getElementName().equals(name)
+					&& methods[i].getParameterTypes().length == parameterTypeNames.length) {
+				IMethod method = methods[i];
+				if (uniqueKey != null) {
+					ResolvedSourceMethod resolvedMethod = new ResolvedSourceMethod(
+						(JavaElement)method.getParent(),
+						method.getElementName(),
+						method.getParameterTypes(),
+						new String(uniqueKey));
+					resolvedMethod.occurrenceCount = method.getOccurrenceCount();
+					method = resolvedMethod;
+				}
+				addElement(method);
+			}
+		}
+	} catch (JavaModelException e) {
+		return;
+	}
+
+	// if no matches, nothing to report
+	if (this.elementIndex == -1) {
+		// no match was actually found, but a method was originally given -> default constructor
+		addElement(type);
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+			System.out.print(type.toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+		return;
+	}
+
+	// if there is only one match, we've got it
+	if (this.elementIndex == 0) {
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+			System.out.print(this.elements[0].toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+		return;
+	}
+
+	// more than one match - must match simple parameter types
+	IJavaElement[] matches = this.elements;
+	int matchesIndex = this.elementIndex;
+	this.elements = JavaElement.NO_ELEMENTS;
+	this.elementIndex = -1;
+	for (int i = 0; i <= matchesIndex; i++) {
+		IMethod method= (IMethod)matches[i];
+		String[] signatures = method.getParameterTypes();
+		boolean match= true;
+		for (int p = 0; p < signatures.length; p++) {
+			String simpleName= Signature.getSimpleName(Signature.toString(Signature.getTypeErasure(signatures[p])));
+			char[] simpleParameterName = CharOperation.lastSegment(parameterTypeNames[p], '.');
+			if (!simpleName.equals(new String(simpleParameterName))) {
+				match = false;
+				break;
+			}
+		}
+
+		if (match && !areTypeParametersCompatible(method, typeParameterNames, typeParameterBoundNames)) {
+			match = false;
+		}
+
+		if (match) {
+			addElement(method);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+				System.out.print(method.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+
+}
+protected void acceptMethodDeclaration(IType type, char[] selector, int start, int end) {
+	String name = new String(selector);
+	IMethod[] methods = null;
+	try {
+		methods = type.getMethods();
+		for (int i = 0; i < methods.length; i++) {
+			ISourceRange range = methods[i].getNameRange();
+			if(range.getOffset() <= start
+					&& range.getOffset() + range.getLength() >= end
+					&& methods[i].getElementName().equals(name)) {
+				addElement(methods[i]);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+					System.out.print(this.elements[0].toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+				return; // only one method is possible
+			}
+		}
+	} catch (JavaModelException e) {
+		return;
+	}
+
+	// no match was actually found
+	addElement(type);
+	if(SelectionEngine.DEBUG){
+		System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+		System.out.print(type.toString());
+		System.out.println(")"); //$NON-NLS-1$
+	}
+	return;
+}
+public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
+	IType type;
+	if(isDeclaration) {
+		type = resolveTypeByLocation(declaringTypePackageName, declaringTypeName,
+				NameLookup.ACCEPT_ALL,
+				start, end);
+	} else {
+		type = resolveType(declaringTypePackageName, declaringTypeName,
+				NameLookup.ACCEPT_ALL);
+	}
+
+	if(type != null) {
+		ITypeParameter typeParameter = type.getTypeParameter(new String(typeParameterName));
+		if(typeParameter == null) {
+			addElement(type);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+				System.out.print(type.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		} else {
+			addElement(typeParameter);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type parameter("); //$NON-NLS-1$
+				System.out.print(typeParameter.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		}
+	}
+}
+public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector,int selectorStart, int selectorEnd, char[] typeParameterName, boolean isDeclaration, int start, int end) {
+	IType type = resolveTypeByLocation(declaringTypePackageName, declaringTypeName,
+			NameLookup.ACCEPT_ALL,
+			selectorStart, selectorEnd);
+
+	if(type != null) {
+		IMethod method = null;
+
+		String name = new String(selector);
+		IMethod[] methods = null;
+
+		try {
+			methods = type.getMethods();
+			done : for (int i = 0; i < methods.length; i++) {
+				ISourceRange range = methods[i].getNameRange();
+				if(range.getOffset() >= selectorStart
+						&& range.getOffset() + range.getLength() <= selectorEnd
+						&& methods[i].getElementName().equals(name)) {
+					method = methods[i];
+					break done;
+				}
+			}
+		} catch (JavaModelException e) {
+			//nothing to do
+		}
+
+		if(method == null) {
+			addElement(type);
+			if(SelectionEngine.DEBUG){
+				System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+				System.out.print(type.toString());
+				System.out.println(")"); //$NON-NLS-1$
+			}
+		} else {
+			ITypeParameter typeParameter = method.getTypeParameter(new String(typeParameterName));
+			if(typeParameter == null) {
+				addElement(method);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept method("); //$NON-NLS-1$
+					System.out.print(method.toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+			} else {
+				addElement(typeParameter);
+				if(SelectionEngine.DEBUG){
+					System.out.print("SELECTION - accept method type parameter("); //$NON-NLS-1$
+					System.out.print(typeParameter.toString());
+					System.out.println(")"); //$NON-NLS-1$
+				}
+			}
+		}
+	}
+}
+/*
+ * Adds the given element to the list of resolved elements.
+ */
+protected void addElement(IJavaElement element) {
+	int elementLength = this.elementIndex + 1;
+
+	for (int i = 0; i < elementLength; i++) {
+		if (this.elements[i].equals(element)) {
+			return;
+		}
+	}
+
+	if (elementLength == this.elements.length) {
+		System.arraycopy(this.elements, 0, this.elements = new IJavaElement[(elementLength*2) + 1], 0, elementLength);
+	}
+	this.elements[++this.elementIndex] = element;
+}
+private boolean areTypeParametersCompatible(IMethod method, char[][] typeParameterNames, char[][][] typeParameterBoundNames) {
+	try {
+		ITypeParameter[] typeParameters = method.getTypeParameters();
+		int length1 = typeParameters == null ? 0 : typeParameters.length;
+		int length2 = typeParameterNames == null ? 0 : typeParameterNames.length;
+		if (length1 != length2) {
+			return false;
+		} else {
+			for (int j = 0; j < length1; j++) {
+				ITypeParameter typeParameter = typeParameters[j];
+				String typeParameterName = typeParameter.getElementName();
+				if (!typeParameterName.equals(new String(typeParameterNames[j]))) {
+					return false;
+				}
+
+				String[] bounds = typeParameter.getBounds();
+				int boundCount = typeParameterBoundNames[j] == null ? 0 : typeParameterBoundNames[j].length;
+
+				if (bounds.length != boundCount) {
+					return false;
+				} else {
+					for (int k = 0; k < boundCount; k++) {
+						String simpleName = Signature.getSimpleName(bounds[k]);
+						int index = simpleName.indexOf('<');
+						if (index != -1) {
+							simpleName = simpleName.substring(0, index);
+						}
+						if (!simpleName.equals(new String(typeParameterBoundNames[j][k]))) {
+							return false;
+						}
+					}
+				}
+			}
+		}
+	} catch (JavaModelException e) {
+		return false;
+	}
+	return true;
+}
+/*
+ * findLocalElement() cannot find local variable
+ */
+protected IJavaElement findLocalElement(int pos) {
+	IJavaElement res = null;
+	if(this.openable instanceof ICompilationUnit) {
+		ICompilationUnit cu = (ICompilationUnit) this.openable;
+		try {
+			res = cu.getElementAt(pos);
+		} catch (JavaModelException e) {
+			// do nothing
+		}
+	} else if (this.openable instanceof ClassFile) {
+		ClassFile cf = (ClassFile) this.openable;
+		try {
+			 res = cf.getElementAtConsideringSibling(pos);
+		} catch (JavaModelException e) {
+			// do nothing
+		}
+	}
+	return res;
+}
+
+/**
+ * This method returns an IMethod element from the given method and declaring type bindings. However,
+ * unlike {@link Util#findMethod(IType, char[], String[], boolean)} , this does not require an IType to get 
+ * the IMethod element.
+ * @param method the given method binding
+ * @param signatures the type signatures of the method arguments
+ * @param declaringClass the binding of the method's declaring class
+ * @return an IMethod corresponding to the method binding given, or null if none is found.
+ */
+public IJavaElement findMethodFromBinding(MethodBinding method, String[] signatures, ReferenceBinding declaringClass) {
+	IType foundType = this.resolveType(declaringClass.qualifiedPackageName(), declaringClass.qualifiedSourceName(), NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES);
+	if (foundType != null) {
+		if (foundType instanceof BinaryType) {
+			try {
+				return Util.findMethod(foundType, method.selector, signatures, method.isConstructor());
+			} catch (JavaModelException e) {
+				return null;
+			}
+		} else {
+			return foundType.getMethod(new String(method.selector), signatures);
+		}
+	}
+	return null;
+}
+/**
+ * Returns the resolved elements.
+ */
+public IJavaElement[] getElements() {
+	int elementLength = this.elementIndex + 1;
+	if (this.elements.length != elementLength) {
+		System.arraycopy(this.elements, 0, this.elements = new IJavaElement[elementLength], 0, elementLength);
+	}
+	return this.elements;
+}
+/**
+ * Resolve the type
+ */
+protected IType resolveType(char[] packageName, char[] typeName, int acceptFlags) {
+
+	IType type= null;
+
+	if (this.openable instanceof CompilationUnit && ((CompilationUnit)this.openable).isWorkingCopy()) {
+		CompilationUnit wc = (CompilationUnit) this.openable;
+		try {
+			if(((packageName == null || packageName.length == 0) && wc.getPackageDeclarations().length == 0) ||
+				(!(packageName == null || packageName.length == 0) && wc.getPackageDeclaration(new String(packageName)).exists())) {
+
+				char[][] compoundName = CharOperation.splitOn('.', typeName);
+				if(compoundName.length > 0) {
+					type = wc.getType(new String(compoundName[0]));
+					for (int i = 1, length = compoundName.length; i < length; i++) {
+						type = type.getType(new String(compoundName[i]));
+					}
+				}
+
+				if(type != null && !type.exists()) {
+					type = null;
+				}
+			}
+		}catch (JavaModelException e) {
+			// type is null
+		}
+	}
+
+	if(type == null) {
+		IPackageFragment[] pkgs = this.nameLookup.findPackageFragments(
+			(packageName == null || packageName.length == 0) ? IPackageFragment.DEFAULT_PACKAGE_NAME : new String(packageName),
+			false);
+		// iterate type lookup in each package fragment
+		for (int i = 0, length = pkgs == null ? 0 : pkgs.length; i < length; i++) {
+			type= this.nameLookup.findType(new String(typeName), pkgs[i], false, acceptFlags, true/*consider secondary types*/);
+			if (type != null) break;
+		}
+		if (type == null) {
+			String pName= IPackageFragment.DEFAULT_PACKAGE_NAME;
+			if (packageName != null) {
+				pName = new String(packageName);
+			}
+			if (this.openable != null && this.openable.getParent().getElementName().equals(pName)) {
+				// look inside the type in which we are resolving in
+				String tName= new String(typeName);
+				tName = tName.replace('.','$');
+				IType[] allTypes= null;
+				try {
+					ArrayList list = this.openable.getChildrenOfType(IJavaElement.TYPE);
+					allTypes = new IType[list.size()];
+					list.toArray(allTypes);
+				} catch (JavaModelException e) {
+					return null;
+				}
+				for (int i= 0; i < allTypes.length; i++) {
+					if (allTypes[i].getTypeQualifiedName().equals(tName)) {
+						return allTypes[i];
+					}
+				}
+			}
+		}
+	}
+	return type;
+}
+protected IType resolveTypeByLocation(char[] packageName, char[] typeName, int acceptFlags, int start, int end) {
+
+	IType type= null;
+
+	// TODO (david) post 3.0 should remove isOpen check, and investigate reusing ICompilationUnit#getElementAt. may need to optimize #getElementAt to remove recursions
+	if (this.openable instanceof CompilationUnit && ((CompilationUnit)this.openable).isOpen()) {
+		CompilationUnit wc = (CompilationUnit) this.openable;
+		try {
+			if(((packageName == null || packageName.length == 0) && wc.getPackageDeclarations().length == 0) ||
+				(!(packageName == null || packageName.length == 0) && wc.getPackageDeclaration(new String(packageName)).exists())) {
+
+				char[][] compoundName = CharOperation.splitOn('.', typeName);
+				if(compoundName.length > 0) {
+
+					IType[] tTypes = wc.getTypes();
+					int i = 0;
+					int depth = 0;
+					done : while(i < tTypes.length) {
+						ISourceRange range = tTypes[i].getSourceRange();
+						if(range.getOffset() <= start
+								&& range.getOffset() + range.getLength() >= end
+								&& tTypes[i].getElementName().equals(new String(compoundName[depth]))) {
+							if(depth == compoundName.length - 1) {
+								type = tTypes[i];
+								break done;
+							}
+							tTypes = tTypes[i].getTypes();
+							i = 0;
+							depth++;
+							continue done;
+						}
+						i++;
+					}
+				}
+
+				if(type != null && !type.exists()) {
+					type = null;
+				}
+			}
+		}catch (JavaModelException e) {
+			// type is null
+		}
+	}
+
+	if(type == null) {
+		IPackageFragment[] pkgs = this.nameLookup.findPackageFragments(
+			(packageName == null || packageName.length == 0) ? IPackageFragment.DEFAULT_PACKAGE_NAME : new String(packageName),
+			false);
+		// iterate type lookup in each package fragment
+		for (int i = 0, length = pkgs == null ? 0 : pkgs.length; i < length; i++) {
+			type= this.nameLookup.findType(new String(typeName), pkgs[i], false, acceptFlags, true/*consider secondary types*/);
+			if (type != null) break;
+		}
+		if (type == null) {
+			String pName= IPackageFragment.DEFAULT_PACKAGE_NAME;
+			if (packageName != null) {
+				pName = new String(packageName);
+			}
+			if (this.openable != null && this.openable.getParent().getElementName().equals(pName)) {
+				// look inside the type in which we are resolving in
+				String tName= new String(typeName);
+				tName = tName.replace('.','$');
+				IType[] allTypes= null;
+				try {
+					ArrayList list = this.openable.getChildrenOfType(IJavaElement.TYPE);
+					allTypes = new IType[list.size()];
+					list.toArray(allTypes);
+				} catch (JavaModelException e) {
+					return null;
+				}
+				for (int i= 0; i < allTypes.length; i++) {
+					if (allTypes[i].getTypeQualifiedName().equals(tName)) {
+						return allTypes[i];
+					}
+				}
+			}
+		}
+	}
+	return type;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java
new file mode 100644
index 0000000..c8cff4e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
+
+/**
+ * This operation sets an <code>IJavaProject</code>'s classpath.
+ *
+ * @see IJavaProject
+ */
+public class SetClasspathOperation extends ChangeClasspathOperation {
+
+	IClasspathEntry[] newRawClasspath;
+	IClasspathEntry[] referencedEntries;
+	IPath newOutputLocation;
+	JavaProject project;
+
+	public SetClasspathOperation(
+		JavaProject project,
+		IClasspathEntry[] newRawClasspath,
+		IPath newOutputLocation,
+		boolean canChangeResource) {
+
+		this(project, newRawClasspath, null, newOutputLocation, canChangeResource);
+	}
+	
+	/**
+	 * When executed, this operation sets the raw classpath and output location of the given project.
+	 */
+	public SetClasspathOperation(
+		JavaProject project,
+		IClasspathEntry[] newRawClasspath,
+		IClasspathEntry[] referencedEntries,
+		IPath newOutputLocation,
+		boolean canChangeResource) {
+
+		super(new IJavaElement[] { project }, canChangeResource);
+		this.project = project;
+		this.newRawClasspath = newRawClasspath;
+		this.referencedEntries = referencedEntries;
+		this.newOutputLocation = newOutputLocation;
+	}
+
+	/**
+	 * Sets the classpath of the pre-specified project.
+	 */
+	protected void executeOperation() throws JavaModelException {
+		checkCanceled();
+		try {
+			// set raw classpath and null out resolved info
+			PerProjectInfo perProjectInfo = this.project.getPerProjectInfo();
+			ClasspathChange classpathChange = perProjectInfo.setRawClasspath(this.newRawClasspath, this.referencedEntries, this.newOutputLocation, JavaModelStatus.VERIFIED_OK/*format is ok*/);
+
+			// if needed, generate delta, update project ref, create markers, ...
+			classpathChanged(classpathChange, true/*refresh if external linked folder already exists*/);
+
+			// write .classpath file
+			if (this.canChangeResources && perProjectInfo.writeAndCacheClasspath(this.project, this.newRawClasspath, this.newOutputLocation))
+				setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
+		} finally {
+			done();
+		}
+	}
+	
+	protected ISchedulingRule getSchedulingRule() {
+		if (this.canChangeResources) {
+			IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
+			return new MultiRule(new ISchedulingRule[] {
+				// use project modification rule as this is needed to create the .classpath file if it doesn't exist yet, or to update project references
+				ruleFactory.modifyRule(this.project.getProject()),
+				
+				// and external project modification rule in case the external folders are modified
+				ruleFactory.modifyRule(JavaModelManager.getExternalManager().getExternalFoldersProject())
+			});
+		}
+		return super.getSchedulingRule();
+	}
+
+	public String toString(){
+		StringBuffer buffer = new StringBuffer(20);
+		buffer.append("SetClasspathOperation\n"); //$NON-NLS-1$
+		buffer.append(" - classpath : "); //$NON-NLS-1$
+		buffer.append("{"); //$NON-NLS-1$
+		for (int i = 0; i < this.newRawClasspath.length; i++) {
+			if (i > 0) buffer.append(","); //$NON-NLS-1$
+			IClasspathEntry element = this.newRawClasspath[i];
+			buffer.append(" ").append(element.toString()); //$NON-NLS-1$
+		}
+		buffer.append("\n - output location : ");  //$NON-NLS-1$
+		buffer.append(this.newOutputLocation.toString());
+		return buffer.toString();
+	}
+
+	public IJavaModelStatus verify() {
+		IJavaModelStatus status = super.verify();
+		if (!status.isOK())
+			return status;
+		this.project.flushClasspathProblemMarkers(false, false, true);
+		return ClasspathEntry.validateClasspath(this.project, this.newRawClasspath, this.newOutputLocation);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetContainerOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetContainerOperation.java
new file mode 100644
index 0000000..4a498fb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetContainerOperation.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class SetContainerOperation extends ChangeClasspathOperation {
+
+	IPath containerPath;
+	IJavaProject[] affectedProjects;
+	IClasspathContainer[] respectiveContainers;
+
+	/*
+	 * Creates a new SetContainerOperation.
+	 */
+	public SetContainerOperation(IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer[] respectiveContainers) {
+		super(new IJavaElement[] {JavaModelManager.getJavaModelManager().getJavaModel()}, !ResourcesPlugin.getWorkspace().isTreeLocked());
+		this.containerPath = containerPath;
+		this.affectedProjects = affectedProjects;
+		this.respectiveContainers = respectiveContainers;
+	}
+
+	protected void executeOperation() throws JavaModelException {
+		checkCanceled();
+		try {
+			beginTask("", 1); //$NON-NLS-1$
+			if (JavaModelManager.CP_RESOLVE_VERBOSE)
+				verbose_set_container();
+			if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+				verbose_set_container_invocation_trace();
+
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			if (manager.containerPutIfInitializingWithSameEntries(this.containerPath, this.affectedProjects, this.respectiveContainers))
+				return;
+
+			final int projectLength = this.affectedProjects.length;
+			final IJavaProject[] modifiedProjects;
+			System.arraycopy(this.affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength);
+
+			// filter out unmodified project containers
+			int remaining = 0;
+			for (int i = 0; i < projectLength; i++){
+				if (isCanceled())
+					return;
+				JavaProject affectedProject = (JavaProject) this.affectedProjects[i];
+				IClasspathContainer newContainer = this.respectiveContainers[i];
+				if (newContainer == null) newContainer = JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS; // 30920 - prevent infinite loop
+				boolean found = false;
+				if (JavaProject.hasJavaNature(affectedProject.getProject())){
+					IClasspathEntry[] rawClasspath = affectedProject.getRawClasspath();
+					for (int j = 0, cpLength = rawClasspath.length; j <cpLength; j++) {
+						IClasspathEntry entry = rawClasspath[j];
+						if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().equals(this.containerPath)){
+							found = true;
+							break;
+						}
+					}
+				}
+				if (!found) {
+					modifiedProjects[i] = null; // filter out this project - does not reference the container path, or isnt't yet Java project
+					manager.containerPut(affectedProject, this.containerPath, newContainer);
+					continue;
+				}
+				IClasspathContainer oldContainer = manager.containerGet(affectedProject, this.containerPath);
+				if (oldContainer == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
+					oldContainer = null;
+				}
+				if ((oldContainer != null && oldContainer.equals(this.respectiveContainers[i]))
+						|| (oldContainer == this.respectiveContainers[i])/*handle case where old and new containers are null (see bug 149043*/) {
+					modifiedProjects[i] = null; // filter out this project - container did not change
+					continue;
+				}
+				remaining++;
+				manager.containerPut(affectedProject, this.containerPath, newContainer);
+			}
+
+			if (remaining == 0) return;
+
+			// trigger model refresh
+			try {
+				for(int i = 0; i < projectLength; i++){
+					if (isCanceled())
+						return;
+
+					JavaProject affectedProject = (JavaProject)modifiedProjects[i];
+					if (affectedProject == null) continue; // was filtered out
+					if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+						verbose_update_project(affectedProject);
+
+					// force resolved classpath to be recomputed
+					ClasspathChange classpathChange = affectedProject.getPerProjectInfo().resetResolvedClasspath();
+
+					// if needed, generate delta, update project ref, create markers, ...
+					classpathChanged(classpathChange, i==0/*refresh external linked folder only once*/);
+
+					if (this.canChangeResources) {
+						// touch project to force a build if needed
+						try {
+							affectedProject.getProject().touch(this.progressMonitor);
+						} catch (CoreException e) {
+							// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=148970
+							if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(affectedProject.getElementName()))
+								throw e;
+						}
+					}
+				}
+			} catch(CoreException e) {
+				if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)
+					verbose_failure(e);
+				if (e instanceof JavaModelException) {
+					throw (JavaModelException)e;
+				} else {
+					throw new JavaModelException(e);
+				}
+			} finally {
+				for (int i = 0; i < projectLength; i++) {
+					if (this.respectiveContainers[i] == null) {
+						manager.containerPut(this.affectedProjects[i], this.containerPath, null); // reset init in progress marker
+					}
+				}
+			}
+		} finally {
+			done();
+		}
+	}
+
+	private void verbose_failure(CoreException e) {
+		Util.verbose(
+			"CPContainer SET  - FAILED DUE TO EXCEPTION\n" + //$NON-NLS-1$
+			"	container path: " + this.containerPath, //$NON-NLS-1$
+			System.err);
+		e.printStackTrace();
+	}
+
+	private void verbose_update_project(JavaProject affectedProject) {
+		Util.verbose(
+			"CPContainer SET  - updating affected project due to setting container\n" + //$NON-NLS-1$
+			"	project: " + affectedProject.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + this.containerPath); //$NON-NLS-1$
+	}
+
+	private void verbose_set_container() {
+		Util.verbose(
+			"CPContainer SET  - setting container\n" + //$NON-NLS-1$
+			"	container path: " + this.containerPath + '\n' + //$NON-NLS-1$
+			"	projects: {" +//$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				this.affectedProjects,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) { return ((IJavaProject) o).getElementName(); }
+				}) +
+			"}\n	values: {\n"  +//$NON-NLS-1$
+			org.eclipse.jdt.internal.compiler.util.Util.toString(
+				this.respectiveContainers,
+				new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){
+					public String displayString(Object o) {
+						StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+						if (o == null) {
+							buffer.append("<null>"); //$NON-NLS-1$
+							return buffer.toString();
+						}
+						IClasspathContainer container = (IClasspathContainer) o;
+						buffer.append(container.getDescription());
+						buffer.append(" {\n"); //$NON-NLS-1$
+						IClasspathEntry[] entries = container.getClasspathEntries();
+						if (entries != null){
+							for (int i = 0; i < entries.length; i++){
+								buffer.append(" 			"); //$NON-NLS-1$
+								buffer.append(entries[i]);
+								buffer.append('\n');
+							}
+						}
+						buffer.append(" 		}"); //$NON-NLS-1$
+						return buffer.toString();
+					}
+				}) +
+			"\n	}");//$NON-NLS-1$
+	}
+
+	private void verbose_set_container_invocation_trace() {
+		Util.verbose(
+			"CPContainer SET  - setting container\n" + //$NON-NLS-1$
+			"	invocation stack trace:"); //$NON-NLS-1$
+			new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetVariablesOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetVariablesOperation.java
new file mode 100644
index 0000000..e4dfc5c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetVariablesOperation.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class SetVariablesOperation extends ChangeClasspathOperation {
+
+	String[] variableNames;
+	IPath[] variablePaths;
+	boolean updatePreferences;
+
+	/*
+	 * Creates a new SetVariablesOperation for the given variable values (null path meaning removal), allowing to change multiple variable values at once.
+	 */
+	public SetVariablesOperation(String[] variableNames, IPath[] variablePaths, boolean updatePreferences) {
+		super(new IJavaElement[] {JavaModelManager.getJavaModelManager().getJavaModel()}, !ResourcesPlugin.getWorkspace().isTreeLocked());
+		this.variableNames = variableNames;
+		this.variablePaths = variablePaths;
+		this.updatePreferences = updatePreferences;
+	}
+
+	protected void executeOperation() throws JavaModelException {
+		checkCanceled();
+		try {
+			beginTask("", 1); //$NON-NLS-1$
+			if (JavaModelManager.CP_RESOLVE_VERBOSE)
+				verbose_set_variables();
+
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			if (manager.variablePutIfInitializingWithSameValue(this.variableNames, this.variablePaths))
+				return;
+
+			int varLength = this.variableNames.length;
+
+			// gather classpath information for updating
+			final HashMap affectedProjectClasspaths = new HashMap(5);
+			IJavaModel model = getJavaModel();
+
+			// filter out unmodified variables
+			int discardCount = 0;
+			for (int i = 0; i < varLength; i++){
+				String variableName = this.variableNames[i];
+				IPath oldPath = manager.variableGet(variableName); // if reentering will provide previous session value
+				if (oldPath == JavaModelManager.VARIABLE_INITIALIZATION_IN_PROGRESS) {
+					oldPath = null;  //33695 - cannot filter out restored variable, must update affected project to reset cached CP
+				}
+				if (oldPath != null && oldPath.equals(this.variablePaths[i])){
+					this.variableNames[i] = null;
+					discardCount++;
+				}
+			}
+			if (discardCount > 0){
+				if (discardCount == varLength) return;
+				int changedLength = varLength - discardCount;
+				String[] changedVariableNames = new String[changedLength];
+				IPath[] changedVariablePaths = new IPath[changedLength];
+				for (int i = 0, index = 0; i < varLength; i++){
+					if (this.variableNames[i] != null){
+						changedVariableNames[index] = this.variableNames[i];
+						changedVariablePaths[index] = this.variablePaths[i];
+						index++;
+					}
+				}
+				this.variableNames = changedVariableNames;
+				this.variablePaths = changedVariablePaths;
+				varLength = changedLength;
+			}
+
+			if (isCanceled())
+				return;
+
+			IJavaProject[] projects = model.getJavaProjects();
+			nextProject : for (int i = 0, projectLength = projects.length; i < projectLength; i++){
+				JavaProject project = (JavaProject) projects[i];
+
+				// check to see if any of the modified variables is present on the classpath
+				IClasspathEntry[] classpath = project.getRawClasspath();
+				for (int j = 0, cpLength = classpath.length; j < cpLength; j++){
+
+					IClasspathEntry entry = classpath[j];
+					for (int k = 0; k < varLength; k++){
+
+						String variableName = this.variableNames[k];
+						if (entry.getEntryKind() ==  IClasspathEntry.CPE_VARIABLE){
+
+							if (variableName.equals(entry.getPath().segment(0))){
+								affectedProjectClasspaths.put(project, project.getResolvedClasspath());
+								continue nextProject;
+							}
+							IPath sourcePath, sourceRootPath;
+							if (((sourcePath = entry.getSourceAttachmentPath()) != null	&& variableName.equals(sourcePath.segment(0)))
+								|| ((sourceRootPath = entry.getSourceAttachmentRootPath()) != null	&& variableName.equals(sourceRootPath.segment(0)))) {
+
+								affectedProjectClasspaths.put(project, project.getResolvedClasspath());
+								continue nextProject;
+							}
+						}
+					}
+				}
+			}
+
+			// update variables
+			for (int i = 0; i < varLength; i++){
+				manager.variablePut(this.variableNames[i], this.variablePaths[i]);
+				if (this.updatePreferences)
+					manager.variablePreferencesPut(this.variableNames[i], this.variablePaths[i]);
+			}
+
+			// update affected project classpaths
+			if (!affectedProjectClasspaths.isEmpty()) {
+				String[] dbgVariableNames = this.variableNames;
+				try {
+					// propagate classpath change
+					Iterator projectsToUpdate = affectedProjectClasspaths.keySet().iterator();
+					while (projectsToUpdate.hasNext()) {
+
+						if (this.progressMonitor != null && this.progressMonitor.isCanceled()) return;
+
+						JavaProject affectedProject = (JavaProject) projectsToUpdate.next();
+
+						// force resolved classpath to be recomputed
+						if (JavaModelManager.CP_RESOLVE_VERBOSE_ADVANCED)
+							verbose_update_project(dbgVariableNames, affectedProject);
+						ClasspathChange classpathChange = affectedProject.getPerProjectInfo().resetResolvedClasspath();
+
+						// if needed, generate delta, update project ref, create markers, ...
+						classpathChanged(classpathChange, true/*refresh if external linked folder already exists*/);
+
+						if (this.canChangeResources) {
+							// touch project to force a build if needed
+							affectedProject.getProject().touch(this.progressMonitor);
+						}
+					}
+				} catch (CoreException e) {
+					if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE){
+						verbose_failure(dbgVariableNames);
+						e.printStackTrace();
+					}
+					if (e instanceof JavaModelException) {
+						throw (JavaModelException)e;
+					} else {
+						throw new JavaModelException(e);
+					}
+				}
+			}
+		} finally {
+			done();
+		}
+	}
+
+	private void verbose_failure(String[] dbgVariableNames) {
+		Util.verbose(
+			"CPVariable SET  - FAILED DUE TO EXCEPTION\n" + //$NON-NLS-1$
+			"	variables: " + org.eclipse.jdt.internal.compiler.util.Util.toString(dbgVariableNames), //$NON-NLS-1$
+			System.err);
+	}
+
+	private void verbose_update_project(String[] dbgVariableNames,
+			JavaProject affectedProject) {
+		Util.verbose(
+			"CPVariable SET  - updating affected project due to setting variables\n" + //$NON-NLS-1$
+			"	project: " + affectedProject.getElementName() + '\n' + //$NON-NLS-1$
+			"	variables: " + org.eclipse.jdt.internal.compiler.util.Util.toString(dbgVariableNames)); //$NON-NLS-1$
+	}
+
+	private void verbose_set_variables() {
+		Util.verbose(
+			"CPVariable SET  - setting variables\n" + //$NON-NLS-1$
+			"	variables: " + org.eclipse.jdt.internal.compiler.util.Util.toString(this.variableNames) + '\n' +//$NON-NLS-1$
+			"	values: " + org.eclipse.jdt.internal.compiler.util.Util.toString(this.variablePaths)); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java
new file mode 100644
index 0000000..119ee91
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElementDelta;
+
+/**
+ * A simple Java element delta that remembers the kind of changes only.
+ */
+public class SimpleDelta {
+
+	/*
+	 * @see IJavaElementDelta#getKind()
+	 */
+	protected int kind = 0;
+
+	/*
+	 * @see IJavaElementDelta#getFlags()
+	 */
+	protected int changeFlags = 0;
+
+	/*
+	 * Marks this delta as added
+	 */
+	public void added() {
+		this.kind = IJavaElementDelta.ADDED;
+	}
+
+	/*
+	 * Marks this delta as changed with the given change flag
+	 */
+	public void changed(int flags) {
+		this.kind = IJavaElementDelta.CHANGED;
+		this.changeFlags |= flags;
+	}
+
+	/*
+	 * @see IJavaElementDelta#getFlags()
+	 */
+	public int getFlags() {
+		return this.changeFlags;
+	}
+
+	/*
+	 * @see IJavaElementDelta#getKind()
+	 */
+	public int getKind() {
+		return this.kind;
+	}
+
+	/*
+	 * Mark this delta has a having a modifiers change
+	 */
+	public void modifiers() {
+		changed(IJavaElementDelta.F_MODIFIERS);
+	}
+
+	/*
+	 * Marks this delta as removed
+	 */
+	public void removed() {
+		this.kind = IJavaElementDelta.REMOVED;
+		this.changeFlags = 0;
+	}
+
+	/*
+	 * Mark this delta has a having a super type change
+	 */
+	public void superTypes() {
+		changed(IJavaElementDelta.F_SUPER_TYPES);
+	}
+
+	protected void toDebugString(StringBuffer buffer) {
+		buffer.append("["); //$NON-NLS-1$
+		switch (getKind()) {
+			case IJavaElementDelta.ADDED :
+				buffer.append('+');
+				break;
+			case IJavaElementDelta.REMOVED :
+				buffer.append('-');
+				break;
+			case IJavaElementDelta.CHANGED :
+				buffer.append('*');
+				break;
+			default :
+				buffer.append('?');
+				break;
+		}
+		buffer.append("]: {"); //$NON-NLS-1$
+		toDebugString(buffer, getFlags());
+		buffer.append("}"); //$NON-NLS-1$
+	}
+
+	protected boolean toDebugString(StringBuffer buffer, int flags) {
+		boolean prev = false;
+		if ((flags & IJavaElementDelta.F_MODIFIERS) != 0) {
+			if (prev)
+				buffer.append(" | "); //$NON-NLS-1$
+			buffer.append("MODIFIERS CHANGED"); //$NON-NLS-1$
+			prev = true;
+		}
+		if ((flags & IJavaElementDelta.F_SUPER_TYPES) != 0) {
+			if (prev)
+				buffer.append(" | "); //$NON-NLS-1$
+			buffer.append("SUPER TYPES CHANGED"); //$NON-NLS-1$
+			prev = true;
+		}
+		return prev;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		toDebugString(buffer);
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java
new file mode 100644
index 0000000..4be663f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+
+/**
+ * The SingleTypeRequestor is an IJavaElementRequestor that
+ * only accepts one result element and then cancels.
+ */
+/* package */ class SingleTypeRequestor implements IJavaElementRequestor {
+	/**
+	 * The single accepted element
+	 */
+	protected IType element= null;
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptField(IField field) {
+	// implements interface method
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptInitializer(IInitializer initializer) {
+	// implements interface method
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptMemberType(IType type) {
+	this.element= type;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptMethod(IMethod method) {
+	// implements interface method
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptPackageFragment(IPackageFragment packageFragment) {
+	// implements interface method
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public void acceptType(IType type) {
+	this.element= type;
+}
+/**
+ * Returns the type accepted by this requestor, or <code>null</code>
+ * if no type has been accepted.
+ */
+public IType getType() {
+	return this.element;
+}
+/**
+ * @see IJavaElementRequestor
+ */
+public boolean isCanceled() {
+	return this.element != null;
+}
+/**
+ * Reset the state of this requestor
+ */
+public void reset() {
+	this.element= null;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
new file mode 100644
index 0000000..98c83b1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
@@ -0,0 +1,386 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Alex Blewitt - alex_blewitt@yahoo.com https://bugs.eclipse.org/bugs/show_bug.cgi?id=171066
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatus;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.core.util.CompilationUnitSorter;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.text.edits.RangeMarker;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+/**
+ * This operation is used to sort elements in a compilation unit according to
+ * certain criteria.
+ *
+ * @since 2.1
+ */
+public class SortElementsOperation extends JavaModelOperation {
+	public static final String CONTAINS_MALFORMED_NODES = "malformed"; //$NON-NLS-1$
+
+	Comparator comparator;
+	int[] positions;
+    int apiLevel;
+
+	/**
+	 * Constructor for SortElementsOperation.
+     *
+     * @param level the AST API level; one of the AST LEVEL constants
+	 * @param elements
+	 * @param positions
+	 * @param comparator
+	 */
+	public SortElementsOperation(int level, IJavaElement[] elements, int[] positions, Comparator comparator) {
+		super(elements);
+		this.comparator = comparator;
+        this.positions = positions;
+        this.apiLevel = level;
+	}
+
+	/**
+	 * Returns the amount of work for the main task of this operation for
+	 * progress reporting.
+	 */
+	protected int getMainAmountOfWork(){
+		return this.elementsToProcess.length;
+	}
+
+	boolean checkMalformedNodes(ASTNode node) {
+		Object property = node.getProperty(CONTAINS_MALFORMED_NODES);
+		if (property == null) return false;
+		return ((Boolean) property).booleanValue();
+	}
+
+	protected boolean isMalformed(ASTNode node) {
+		return (node.getFlags() & ASTNode.MALFORMED) != 0;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.core.JavaModelOperation#executeOperation()
+	 */
+	protected void executeOperation() throws JavaModelException {
+		try {
+			beginTask(Messages.operation_sortelements, getMainAmountOfWork());
+			CompilationUnit copy = (CompilationUnit) this.elementsToProcess[0];
+			ICompilationUnit unit = copy.getPrimary();
+			IBuffer buffer = copy.getBuffer();
+			if (buffer  == null) {
+				return;
+			}
+			char[] bufferContents = buffer.getCharacters();
+			String result = processElement(unit, bufferContents);
+			if (!CharOperation.equals(result.toCharArray(), bufferContents)) {
+				copy.getBuffer().setContents(result);
+			}
+			worked(1);
+		} finally {
+			done();
+		}
+	}
+
+	/**
+	 * Calculates the required text edits to sort the <code>unit</code>
+	 * @param group
+	 * @return the edit or null if no sorting is required
+	 */
+	public TextEdit calculateEdit(org.eclipse.jdt.core.dom.CompilationUnit unit, TextEditGroup group) throws JavaModelException {
+		if (this.elementsToProcess.length != 1)
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS));
+
+		if (!(this.elementsToProcess[0] instanceof ICompilationUnit))
+			throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this.elementsToProcess[0]));
+
+		try {
+			beginTask(Messages.operation_sortelements, getMainAmountOfWork());
+
+			ICompilationUnit cu= (ICompilationUnit)this.elementsToProcess[0];
+			String content= cu.getBuffer().getContents();
+			ASTRewrite rewrite= sortCompilationUnit(unit, group);
+			if (rewrite == null) {
+				return null;
+			}
+
+			Document document= new Document(content);
+			return rewrite.rewriteAST(document, cu.getJavaProject().getOptions(true));
+		} finally {
+			done();
+		}
+	}
+
+	/**
+	 * Method processElement.
+	 * @param unit
+	 * @param source
+	 */
+	private String processElement(ICompilationUnit unit, char[] source) {
+		Document document = new Document(new String(source));
+		CompilerOptions options = new CompilerOptions(unit.getJavaProject().getOptions(true));
+		ASTParser parser = ASTParser.newParser(this.apiLevel);
+		parser.setCompilerOptions(options.getMap());
+		parser.setSource(source);
+		parser.setKind(ASTParser.K_COMPILATION_UNIT);
+		parser.setResolveBindings(false);
+		org.eclipse.jdt.core.dom.CompilationUnit ast = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+
+		ASTRewrite rewriter= sortCompilationUnit(ast, null);
+		if (rewriter == null)
+			return document.get();
+
+		TextEdit edits = rewriter.rewriteAST(document, unit.getJavaProject().getOptions(true));
+
+		RangeMarker[] markers = null;
+		if (this.positions != null) {
+			markers = new RangeMarker[this.positions.length];
+			for (int i = 0, max = this.positions.length; i < max; i++) {
+				markers[i]= new RangeMarker(this.positions[i], 0);
+				insert(edits, markers[i]);
+			}
+		}
+		try {
+			edits.apply(document, TextEdit.UPDATE_REGIONS);
+			if (this.positions != null) {
+				for (int i= 0, max = markers.length; i < max; i++) {
+					this.positions[i]= markers[i].getOffset();
+				}
+			}
+		} catch (BadLocationException e) {
+			// ignore
+		}
+		return document.get();
+	}
+
+
+	private ASTRewrite sortCompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit ast, final TextEditGroup group) {
+		ast.accept(new ASTVisitor() {
+			public boolean visit(org.eclipse.jdt.core.dom.CompilationUnit compilationUnit) {
+				List types = compilationUnit.types();
+				for (Iterator iter = types.iterator(); iter.hasNext();) {
+					AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration) iter.next();
+					typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(typeDeclaration.getStartPosition()));
+					compilationUnit.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(typeDeclaration)));
+				}
+				return true;
+			}
+			public boolean visit(AnnotationTypeDeclaration annotationTypeDeclaration) {
+				List bodyDeclarations = annotationTypeDeclaration.bodyDeclarations();
+				for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+					BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+					bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+					annotationTypeDeclaration.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(bodyDeclaration)));
+				}
+				return true;
+			}
+
+			public boolean visit(AnonymousClassDeclaration anonymousClassDeclaration) {
+				List bodyDeclarations = anonymousClassDeclaration.bodyDeclarations();
+				for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+					BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+					bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+					anonymousClassDeclaration.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(bodyDeclaration)));
+				}
+				return true;
+			}
+
+			public boolean visit(TypeDeclaration typeDeclaration) {
+				List bodyDeclarations = typeDeclaration.bodyDeclarations();
+				for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+					BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+					bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+					typeDeclaration.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(bodyDeclaration)));
+				}
+				return true;
+			}
+
+			public boolean visit(EnumDeclaration enumDeclaration) {
+				List bodyDeclarations = enumDeclaration.bodyDeclarations();
+				for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+					BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+					bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+					enumDeclaration.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(bodyDeclaration)));
+				}
+				List enumConstants = enumDeclaration.enumConstants();
+				for (Iterator iter = enumConstants.iterator(); iter.hasNext();) {
+					EnumConstantDeclaration enumConstantDeclaration = (EnumConstantDeclaration) iter.next();
+					enumConstantDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(enumConstantDeclaration.getStartPosition()));
+					enumDeclaration.setProperty(CONTAINS_MALFORMED_NODES, Boolean.valueOf(isMalformed(enumConstantDeclaration)));
+				}
+				return true;
+			}
+		});
+
+		final ASTRewrite rewriter= ASTRewrite.create(ast.getAST());
+		final boolean[] hasChanges= new boolean[] {false};
+
+		ast.accept(new ASTVisitor() {
+
+			private void sortElements(List elements, ListRewrite listRewrite) {
+				if (elements.size() == 0)
+					return;
+
+				final List myCopy = new ArrayList();
+				myCopy.addAll(elements);
+				Collections.sort(myCopy, SortElementsOperation.this.comparator);
+
+				for (int i = 0; i < elements.size(); i++) {
+					ASTNode oldNode= (ASTNode) elements.get(i);
+					ASTNode newNode= (ASTNode) myCopy.get(i);
+					if (oldNode != newNode) {
+						listRewrite.replace(oldNode, rewriter.createMoveTarget(newNode), group);
+						hasChanges[0]= true;
+					}
+				}
+			}
+
+			public boolean visit(org.eclipse.jdt.core.dom.CompilationUnit compilationUnit) {
+				if (checkMalformedNodes(compilationUnit)) {
+					return true; // abort sorting of current element
+				}
+
+				sortElements(compilationUnit.types(), rewriter.getListRewrite(compilationUnit, org.eclipse.jdt.core.dom.CompilationUnit.TYPES_PROPERTY));
+				return true;
+			}
+
+			public boolean visit(AnnotationTypeDeclaration annotationTypeDeclaration) {
+				if (checkMalformedNodes(annotationTypeDeclaration)) {
+					return true; // abort sorting of current element
+				}
+
+				sortElements(annotationTypeDeclaration.bodyDeclarations(), rewriter.getListRewrite(annotationTypeDeclaration, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY));
+				return true;
+			}
+
+			public boolean visit(AnonymousClassDeclaration anonymousClassDeclaration) {
+				if (checkMalformedNodes(anonymousClassDeclaration)) {
+					return true; // abort sorting of current element
+				}
+
+				sortElements(anonymousClassDeclaration.bodyDeclarations(), rewriter.getListRewrite(anonymousClassDeclaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY));
+				return true;
+			}
+
+			public boolean visit(TypeDeclaration typeDeclaration) {
+				if (checkMalformedNodes(typeDeclaration)) {
+					return true; // abort sorting of current element
+				}
+
+				sortElements(typeDeclaration.bodyDeclarations(), rewriter.getListRewrite(typeDeclaration, TypeDeclaration.BODY_DECLARATIONS_PROPERTY));
+				return true;
+			}
+
+			public boolean visit(EnumDeclaration enumDeclaration) {
+				if (checkMalformedNodes(enumDeclaration)) {
+					return true; // abort sorting of current element
+				}
+
+				sortElements(enumDeclaration.bodyDeclarations(), rewriter.getListRewrite(enumDeclaration, EnumDeclaration.BODY_DECLARATIONS_PROPERTY));
+				sortElements(enumDeclaration.enumConstants(), rewriter.getListRewrite(enumDeclaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY));
+				return true;
+			}
+		});
+
+		if (!hasChanges[0])
+			return null;
+
+		return rewriter;
+	}
+
+	/**
+	 * Possible failures:
+	 * <ul>
+	 *  <li>NO_ELEMENTS_TO_PROCESS - the compilation unit supplied to the operation is <code>null</code></li>.
+	 *  <li>INVALID_ELEMENT_TYPES - the supplied elements are not an instance of IWorkingCopy</li>.
+	 * </ul>
+	 * @return IJavaModelStatus
+	 */
+	public IJavaModelStatus verify() {
+		if (this.elementsToProcess.length != 1) {
+			return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+		}
+		if (this.elementsToProcess[0] == null) {
+			return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+		}
+		if (!(this.elementsToProcess[0] instanceof ICompilationUnit) || !((ICompilationUnit) this.elementsToProcess[0]).isWorkingCopy()) {
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, this.elementsToProcess[0]);
+		}
+		return JavaModelStatus.VERIFIED_OK;
+	}
+
+	public static void insert(TextEdit parent, TextEdit edit) {
+		if (!parent.hasChildren()) {
+			parent.addChild(edit);
+			return;
+		}
+		TextEdit[] children= parent.getChildren();
+		// First dive down to find the right parent.
+		for (int i= 0; i < children.length; i++) {
+			TextEdit child= children[i];
+			if (covers(child, edit)) {
+				insert(child, edit);
+				return;
+			}
+		}
+		// We have the right parent. Now check if some of the children have to
+		// be moved under the new edit since it is covering it.
+		for (int i= children.length - 1; i >= 0; i--) {
+			TextEdit child= children[i];
+			if (covers(edit, child)) {
+				parent.removeChild(i);
+				edit.addChild(child);
+			}
+		}
+		parent.addChild(edit);
+	}
+
+	private static boolean covers(TextEdit thisEdit, TextEdit otherEdit) {
+		if (thisEdit.getLength() == 0) {
+			return false;
+		}
+
+		int thisOffset= thisEdit.getOffset();
+		int thisEnd= thisEdit.getExclusiveEnd();
+		if (otherEdit.getLength() == 0) {
+			int otherOffset= otherEdit.getOffset();
+			return thisOffset <= otherOffset && otherOffset < thisEnd;
+		} else {
+			int otherOffset= otherEdit.getOffset();
+			int otherEnd= otherEdit.getExclusiveEnd();
+			return thisOffset <= otherOffset && otherEnd <= thisEnd;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java
new file mode 100644
index 0000000..456e518
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IMemberValuePair;
+
+/*
+ * Element info for annotation method from source.
+ */
+public class SourceAnnotationMethodInfo extends SourceMethodInfo {
+
+	/*
+	 * The positions of a default member value of an annotation method.
+	 * These are {-1, -1} if the method is an annotation method with no default value.
+	 * Otherwise these are the start and end (inclusive) of the expression representing the default value.
+	 */
+	public int defaultValueStart = -1;
+	public int defaultValueEnd = -1;
+
+	public IMemberValuePair defaultValue;
+
+	public boolean isAnnotationMethod() {
+		return true;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java
new file mode 100644
index 0000000..5961fdd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/*
+ * Element info for constructor from source.
+ */
+public class SourceConstructorInfo extends SourceMethodElementInfo {
+
+	private static final char[] RETURN_TYPE_NAME = new char[]{'v', 'o','i', 'd'};
+
+	public boolean isAnnotationMethod() {
+		// a constructor cannot be an annotation method
+		return false;
+	}
+
+	public boolean isConstructor() {
+		return true;
+	}
+
+	public char[] getReturnTypeName() {
+		return RETURN_TYPE_NAME;
+	}
+
+	protected void setReturnType(char[] type) {
+		// ignore (always void)
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorWithChildrenInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorWithChildrenInfo.java
new file mode 100644
index 0000000..67a5d8d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorWithChildrenInfo.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public class SourceConstructorWithChildrenInfo extends SourceConstructorInfo {
+
+	protected IJavaElement[] children;
+	
+	public SourceConstructorWithChildrenInfo(IJavaElement[] children) {
+		this.children = children;
+	}
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
new file mode 100644
index 0000000..0634cf1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+
+/**
+ * @see IField
+ */
+
+public class SourceField extends NamedMember implements IField {
+
+/**
+ * Constructs a handle to the field with the given name in the specified type.
+ */
+protected SourceField(JavaElement parent, String name) {
+	super(parent, name);
+}
+public boolean equals(Object o) {
+	if (!(o instanceof SourceField)) return false;
+	return super.equals(o);
+}
+public ASTNode findNode(org.eclipse.jdt.core.dom.CompilationUnit ast) {
+	// For field declarations, a variable declaration fragment is returned
+	// Return the FieldDeclaration instead
+	// For enum constant declaration, we return the node directly
+	ASTNode node = super.findNode(ast);
+	if (node == null) return null;
+	if (node.getNodeType() == ASTNode.ENUM_CONSTANT_DECLARATION) {
+		return node;
+	}
+	return node.getParent();
+}
+/**
+ * @see IField
+ */
+public Object getConstant() throws JavaModelException {
+	Object constant = null;
+	SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo();
+	final char[] constantSourceChars = info.initializationSource;
+	if (constantSourceChars == null) {
+		return null;
+	}
+
+	String constantSource = new String(constantSourceChars);
+	String signature = info.getTypeSignature();
+	try {
+		if (signature.equals(Signature.SIG_INT)) {
+			constant = new Integer(constantSource);
+		} else if (signature.equals(Signature.SIG_SHORT)) {
+			constant = new Short(constantSource);
+		} else if (signature.equals(Signature.SIG_BYTE)) {
+			constant = new Byte(constantSource);
+		} else if (signature.equals(Signature.SIG_BOOLEAN)) {
+			constant = Boolean.valueOf(constantSource);
+		} else if (signature.equals(Signature.SIG_CHAR)) {
+			if (constantSourceChars.length != 3) {
+				return null;
+			}
+			constant = new Character(constantSourceChars[1]);
+		} else if (signature.equals(Signature.SIG_DOUBLE)) {
+			constant = new Double(constantSource);
+		} else if (signature.equals(Signature.SIG_FLOAT)) {
+			constant = new Float(constantSource);
+		} else if (signature.equals(Signature.SIG_LONG)) {
+			if (constantSource.endsWith("L") || constantSource.endsWith("l")) { //$NON-NLS-1$ //$NON-NLS-2$
+				int index = constantSource.lastIndexOf("L");//$NON-NLS-1$
+				if (index != -1) {
+					constant = new Long(constantSource.substring(0, index));
+				} else {
+					constant = new Long(constantSource.substring(0, constantSource.lastIndexOf("l")));//$NON-NLS-1$
+				}
+			} else {
+				constant = new Long(constantSource);
+			}
+		} else if (signature.equals("QString;")) {//$NON-NLS-1$
+			constant = constantSource;
+		} else if (signature.equals("Qjava.lang.String;")) {//$NON-NLS-1$
+			constant = constantSource;
+		}
+	} catch (NumberFormatException e) {
+		// not a parsable constant
+		return null;
+	}
+	return constant;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return FIELD;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_FIELD;
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner) {
+		CompilationUnit cu = (CompilationUnit)getAncestor(COMPILATION_UNIT);
+		if (cu.isPrimary()) return this;
+	}
+	IJavaElement primaryParent =this.parent.getPrimaryElement(false);
+	return ((IType)primaryParent).getField(this.name);
+}
+/**
+ * @see IField
+ */
+public String getTypeSignature() throws JavaModelException {
+	SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo();
+	return info.getTypeSignature();
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isEnumConstant()
+ */public boolean isEnumConstant() throws JavaModelException {
+	return Flags.isEnum(getFlags());
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedSourceField(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		toStringName(buffer);
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		toStringName(buffer);
+	} else {
+		try {
+			buffer.append(Signature.toString(getTypeSignature()));
+			buffer.append(" "); //$NON-NLS-1$
+			toStringName(buffer);
+		} catch (JavaModelException e) {
+			buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java
new file mode 100644
index 0000000..2ee8282
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.internal.compiler.env.ISourceField;
+
+/**
+ * Element info for IField elements.
+ */
+
+public class SourceFieldElementInfo extends AnnotatableInfo implements ISourceField {
+
+	/**
+	 * The type name of this field.
+	 */
+	protected char[] typeName;
+
+	/**
+	 * The field's initializer string (if the field is a constant).
+	 */
+	protected char[] initializationSource;
+
+/*
+ * Returns the initialization source for this field.
+ * Returns null if the field is not a constant or if it has no initialization.
+ */
+public char[] getInitializationSource() {
+	return this.initializationSource;
+}
+/**
+ * Returns the type name of the field.
+ */
+public char[] getTypeName() {
+	return this.typeName;
+}
+/**
+ * Returns the type signature of the field.
+ *
+ * @see Signature
+ */
+protected String getTypeSignature() {
+	return Signature.createTypeSignature(this.typeName, false);
+}
+
+/**
+ * Sets the type name of the field.
+ */
+protected void setTypeName(char[] typeName) {
+	this.typeName = typeName;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldWithChildrenInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldWithChildrenInfo.java
new file mode 100644
index 0000000..11ae9d4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldWithChildrenInfo.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public class SourceFieldWithChildrenInfo extends SourceFieldElementInfo {
+
+	protected IJavaElement[] children;
+	
+	public SourceFieldWithChildrenInfo(IJavaElement[] children) {
+		this.children = children;
+	}
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
new file mode 100644
index 0000000..7dbd06c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -0,0 +1,1539 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Kelly Campbell <kellyc@google.com> - Hangs in SourceMapper during java proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=281575
+ *     Stephan Herrmann - Contribution for Bug 380048 - error popup when navigating to source files
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IField;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaConventions;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.SourceRange;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter;
+
+/**
+ * A SourceMapper maps source code in a ZIP file to binary types in
+ * a JAR. The SourceMapper uses the fuzzy parser to identify source
+ * fragments in a .java file, and attempts to match the source code
+ * with children in a binary type. A SourceMapper is associated
+ * with a JarPackageFragment by an AttachSourceOperation.
+ *
+ * @see org.eclipse.jdt.internal.core.JarPackageFragment
+ */
+public class SourceMapper
+	extends ReferenceInfoAdapter
+	implements ISourceElementRequestor, SuffixConstants {
+
+	public static class LocalVariableElementKey {
+		String parent;
+		String name;
+		
+		public LocalVariableElementKey(IJavaElement method, String name) {
+			StringBuffer buffer = new StringBuffer();
+			buffer
+				.append(method.getParent().getHandleIdentifier())
+				.append('#')
+				.append(method.getElementName())
+				.append('(');
+			if (method.getElementType() == IJavaElement.METHOD) {
+				String[] parameterTypes = ((IMethod) method).getParameterTypes();
+				for (int i = 0, max = parameterTypes.length; i < max; i++) {
+					if (i > 0) {
+						buffer.append(',');
+					}
+					buffer.append(Signature.getSignatureSimpleName(parameterTypes[i]));
+				}
+			}
+			buffer.append(')');
+			this.parent = String.valueOf(buffer);
+			this.name = name;
+		}
+
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
+			result = prime * result + ((this.parent == null) ? 0 : this.parent.hashCode());
+			return result;
+		}
+
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			LocalVariableElementKey other = (LocalVariableElementKey) obj;
+			if (this.name == null) {
+				if (other.name != null)
+					return false;
+			} else if (!this.name.equals(other.name))
+				return false;
+			if (this.parent == null) {
+				if (other.parent != null)
+					return false;
+			} else if (!this.parent.equals(other.parent))
+				return false;
+			return true;
+		}
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append('(').append(this.parent).append('.').append(this.name).append(')');
+			return String.valueOf(buffer);
+		}
+	}
+
+	public static boolean VERBOSE = false;
+	/**
+	 * Specifies the location of the package fragment roots within
+	 * the zip (empty specifies the default root). <code>null</code> is
+	 * not a valid root path.
+	 */
+	protected ArrayList rootPaths;
+
+	/**
+	 * The binary type source is being mapped for
+	 */
+	protected BinaryType binaryType;
+
+	/**
+	 * The location of the zip file containing source.
+	 */
+	protected IPath sourcePath;
+	/**
+	 * Specifies the location of the package fragment root within
+	 * the zip (empty specifies the default root). <code>null</code> is
+	 * not a valid root path.
+	 */
+	protected String rootPath = ""; //$NON-NLS-1$
+
+	/**
+	 * Table that maps a binary method to its parameter names.
+	 * Keys are the method handles, entries are <code>char[][]</code>.
+	 */
+	protected HashMap parameterNames;
+
+	/**
+	 * Table that maps a binary element to its <code>SourceRange</code>s.
+	 * Keys are the element handles, entries are <code>SourceRange[]</code> which
+	 * is a two element array; the first being source range, the second
+	 * being name range.
+	 */
+	protected HashMap sourceRanges;
+
+	/*
+	 * A map from IJavaElement to String[]
+	 */
+	protected HashMap categories;
+
+	/**
+	 * Table that contains all source ranges for local variables.
+	 * Keys are the special local variable elements, entries are <code>char[][]</code>.
+	 */
+	protected HashMap parametersRanges;
+	
+	/**
+	 * Set that contains all final local variables.
+	 */
+	protected HashSet finalParameters;
+
+	/**
+	 * The unknown source range {-1, 0}
+	 */
+	public static final SourceRange UNKNOWN_RANGE = new SourceRange(-1, 0);
+
+	/**
+	 * The position within the source of the start of the
+	 * current member element, or -1 if we are outside a member.
+	 */
+	protected int[] memberDeclarationStart;
+	/**
+	 * The <code>SourceRange</code> of the name of the current member element.
+	 */
+	protected SourceRange[] memberNameRange;
+	/**
+	 * The name of the current member element.
+	 */
+	protected String[] memberName;
+
+	/**
+	 * The parameter names for the current member method element.
+	 */
+	protected char[][][] methodParameterNames;
+
+	/**
+	 * The parameter types for the current member method element.
+	 */
+	protected char[][][] methodParameterTypes;
+
+
+	/**
+	 * The element searched for
+	 */
+	protected IJavaElement searchedElement;
+
+	/**
+	 * imports references
+	 */
+	private HashMap importsTable;
+	private HashMap importsCounterTable;
+
+	/**
+	 * Enclosing type information
+	 */
+	IType[] types;
+	int[] typeDeclarationStarts;
+	SourceRange[] typeNameRanges;
+	int[] typeModifiers;
+	int typeDepth;
+
+	/**
+	 *  Anonymous counter in case we want to map the source of an anonymous class.
+	 */
+	int anonymousCounter;
+	int anonymousClassName;
+
+	String encoding;
+	String defaultEncoding;
+	/**
+	 *Options to be used
+	 */
+	Map options;
+
+	/**
+	 * Use to handle root paths inference
+	 */
+	private boolean areRootPathsComputed;
+
+	public SourceMapper() {
+		this.areRootPathsComputed = false;
+	}
+
+	public SourceMapper(IPath sourcePath, String rootPath, Map options) {
+		this(sourcePath, rootPath, options, null);
+	}
+	/**
+	 * Creates a <code>SourceMapper</code> that locates source in the zip file
+	 * at the given location in the specified package fragment root.
+	 */
+	public SourceMapper(IPath sourcePath, String rootPath, Map options, String encoding) {
+		this.areRootPathsComputed = false;
+		this.options = options;
+		this.encoding = encoding;
+		try {
+			this.defaultEncoding = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
+		} catch (CoreException e) {
+			// use no encoding
+		}
+		if (rootPath != null) {
+			this.rootPaths = new ArrayList();
+			this.rootPaths.add(rootPath);
+		}
+		this.sourcePath = sourcePath;
+		this.sourceRanges = new HashMap();
+		this.parametersRanges = new HashMap();
+		this.parameterNames = new HashMap();
+		this.importsTable = new HashMap();
+		this.importsCounterTable = new HashMap();
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void acceptImport(
+			int declarationStart,
+			int declarationEnd,
+			int nameStart,
+			int nameEnd,
+			char[][] tokens,
+			boolean onDemand,
+			int modifiers) {
+		char[][] imports = (char[][]) this.importsTable.get(this.binaryType);
+		int importsCounter;
+		if (imports == null) {
+			imports = new char[5][];
+			importsCounter = 0;
+		} else {
+			importsCounter = ((Integer) this.importsCounterTable.get(this.binaryType)).intValue();
+		}
+		if (imports.length == importsCounter) {
+			System.arraycopy(
+				imports,
+				0,
+				(imports = new char[importsCounter * 2][]),
+				0,
+				importsCounter);
+		}
+		char[] name = CharOperation.concatWith(tokens, '.');
+		if (onDemand) {
+			int nameLength = name.length;
+			System.arraycopy(name, 0, (name = new char[nameLength + 2]), 0, nameLength);
+			name[nameLength] = '.';
+			name[nameLength + 1] = '*';
+		}
+		imports[importsCounter++] = name;
+		this.importsTable.put(this.binaryType, imports);
+		this.importsCounterTable.put(this.binaryType, new Integer(importsCounter));
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void acceptLineSeparatorPositions(int[] positions) {
+		//do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void acceptPackage(ImportReference importReference) {
+		//do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void acceptProblem(CategorizedProblem problem) {
+		//do nothing
+	}
+
+	private void addCategories(IJavaElement element, char[][] elementCategories) {
+		if (elementCategories == null) return;
+		if (this.categories == null)
+			this.categories = new HashMap();
+		this.categories.put(element, CharOperation.toStrings(elementCategories));
+	}
+
+	/**
+	 * Closes this <code>SourceMapper</code>'s zip file. Once this is done, this
+	 * <code>SourceMapper</code> cannot be used again.
+	 */
+	public void close() {
+		this.sourceRanges = null;
+		this.parameterNames = null;
+		this.parametersRanges = null;
+		this.finalParameters = null;
+	}
+
+	/**
+	 * NOT API, public only for access by Unit tests.
+	 * Converts these type names to unqualified signatures. This needs to be done in order to be consistent
+	 * with the way the source range is retrieved.
+	 * @see SourceMapper#getUnqualifiedMethodHandle
+	 * @see Signature
+	 */
+	public String[] convertTypeNamesToSigs(char[][] typeNames) {
+		if (typeNames == null)
+			return CharOperation.NO_STRINGS;
+		int n = typeNames.length;
+		if (n == 0)
+			return CharOperation.NO_STRINGS;
+		String[] typeSigs = new String[n];
+		for (int i = 0; i < n; ++i) {
+			char[] typeSig = Signature.createCharArrayTypeSignature(typeNames[i], false);
+
+			// transforms signatures that contains a qualification into unqualified signatures
+			// e.g. "QX<+QMap.Entry;>;" becomes "QX<+QEntry;>;"
+			StringBuffer simpleTypeSig = null;
+			int start = 0;
+			int dot = -1;
+			int length = typeSig.length;
+			for (int j = 0; j < length; j++) {
+				switch (typeSig[j]) {
+					case Signature.C_UNRESOLVED:
+						if (simpleTypeSig != null)
+							simpleTypeSig.append(typeSig, start, j-start);
+						start = j;
+						break;
+					case Signature.C_DOT:
+						dot = j;
+						break;
+					case Signature.C_GENERIC_START:
+						int matchingEnd = findMatchingGenericEnd(typeSig, j+1);
+						if (matchingEnd > 0 && matchingEnd+1 < length && typeSig[matchingEnd+1] == Signature.C_DOT) {
+							// found Head<Param>.Tail -> discard everything except Tail
+							if (simpleTypeSig == null)
+								simpleTypeSig = new StringBuffer().append(typeSig, 0, start);
+							simpleTypeSig.append(Signature.C_UNRESOLVED);
+							start = j = matchingEnd+2;
+							break;
+						}
+						//$FALL-THROUGH$
+					case Signature.C_NAME_END:
+						if (dot > start) {
+							if (simpleTypeSig == null)
+								simpleTypeSig = new StringBuffer().append(typeSig, 0, start);
+							simpleTypeSig.append(Signature.C_UNRESOLVED);
+							simpleTypeSig.append(typeSig, dot+1, j-dot-1);
+							start = j;
+						}
+						break;
+				}
+			}
+			if (simpleTypeSig == null) {
+				typeSigs[i] = new String(typeSig);
+			} else {
+				simpleTypeSig.append(typeSig, start, length-start);
+				typeSigs[i] = simpleTypeSig.toString();
+			}
+		}
+		return typeSigs;
+	}
+
+	private int findMatchingGenericEnd(char[] sig, int start) {
+		int nesting = 0;
+		int length = sig.length;
+		for (int i=start; i < length; i++) {
+			switch (sig[i]) {
+				case Signature.C_GENERIC_START:
+					nesting++;
+					break;
+				case Signature.C_GENERIC_END:
+					if (nesting == 0)
+						return i;
+					nesting--;
+					break;
+			}
+		}
+		return -1;
+	}
+
+	private synchronized void computeAllRootPaths(IType type) {
+		if (this.areRootPathsComputed) {
+			return;
+		}
+		IPackageFragmentRoot root = (IPackageFragmentRoot) type.getPackageFragment().getParent();
+		IPath pkgFragmentRootPath = root.getPath();
+		final HashSet tempRoots = new HashSet();
+		long time = 0;
+		if (VERBOSE) {
+			System.out.println("compute all root paths for " + root.getElementName()); //$NON-NLS-1$
+			time = System.currentTimeMillis();
+		}
+		final HashSet firstLevelPackageNames = new HashSet();
+		boolean containsADefaultPackage = false;
+		boolean containsJavaSource = !pkgFragmentRootPath.equals(this.sourcePath); // used to optimize zip file reading only if source path and root path are equals, otherwise assume that attachment contains Java source
+
+		String sourceLevel = null;
+		String complianceLevel = null;
+		if (root.isArchive()) {
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			ZipFile zip = null;
+			try {
+				zip = manager.getZipFile(pkgFragmentRootPath);
+				for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
+					ZipEntry entry = (ZipEntry) entries.nextElement();
+					String entryName = entry.getName();
+					if (!entry.isDirectory()) {
+						if (Util.isClassFileName(entryName)) {
+							int index = entryName.indexOf('/');
+							if (index != -1) {
+								String firstLevelPackageName = entryName.substring(0, index);
+								if (!firstLevelPackageNames.contains(firstLevelPackageName)) {
+									if (sourceLevel == null) {
+										IJavaProject project = root.getJavaProject();
+										sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+										complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+									}
+									IStatus status = JavaConventions.validatePackageName(firstLevelPackageName, sourceLevel, complianceLevel);
+									if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
+										firstLevelPackageNames.add(firstLevelPackageName);
+									}
+								}
+							} else {
+								containsADefaultPackage = true;
+							}
+						} else if (!containsJavaSource && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(entryName)) {
+							containsJavaSource = true;
+						}
+					}
+				}
+			} catch (CoreException e) {
+				// ignore
+			} finally {
+				manager.closeZipFile(zip); // handle null case
+			}
+		} else {
+			Object target = JavaModel.getTarget(root.getPath(), true);
+			if (target instanceof IResource) {
+				IResource resource = (IResource) target;
+				if (resource instanceof IContainer) {
+					try {
+						IResource[] members = ((IContainer) resource).members();
+						for (int i = 0, max = members.length; i < max; i++) {
+							IResource member = members[i];
+							String resourceName = member.getName();
+							if (member.getType() == IResource.FOLDER) {
+								if (sourceLevel == null) {
+									IJavaProject project = root.getJavaProject();
+									sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true);
+									complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+								}
+								IStatus status = JavaConventions.validatePackageName(resourceName, sourceLevel, complianceLevel);
+								if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
+									firstLevelPackageNames.add(resourceName);
+								}
+							} else if (Util.isClassFileName(resourceName)) {
+								containsADefaultPackage = true;
+							} else if (!containsJavaSource && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)) {
+								containsJavaSource = true;
+							}
+						}
+					} catch (CoreException e) {
+						// ignore
+					}
+				}
+			}
+		}
+
+		if (containsJavaSource) { // no need to read source attachment if it contains no Java source (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190840 )
+			Object target = JavaModel.getTarget(this.sourcePath, true);
+			if (target instanceof IContainer) {
+				IContainer folder = (IContainer)target;
+				computeRootPath(folder, firstLevelPackageNames, containsADefaultPackage, tempRoots, folder.getFullPath().segmentCount()/*if external folder, this is the linked folder path*/);
+			} else {
+				JavaModelManager manager = JavaModelManager.getJavaModelManager();
+				ZipFile zip = null;
+				try {
+					zip = manager.getZipFile(this.sourcePath);
+					for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
+						ZipEntry entry = (ZipEntry) entries.nextElement();
+						String entryName;
+						if (!entry.isDirectory() && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(entryName = entry.getName())) {
+							IPath path = new Path(entryName);
+							int segmentCount = path.segmentCount();
+							if (segmentCount > 1) {
+								for (int i = 0, max = path.segmentCount() - 1; i < max; i++) {
+									if (firstLevelPackageNames.contains(path.segment(i))) {
+										tempRoots.add(path.uptoSegment(i));
+										// don't break here as this path could contain other first level package names (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=74014)
+									}
+									if (i == max - 1 && containsADefaultPackage) {
+										tempRoots.add(path.uptoSegment(max));
+									}
+								}
+							} else if (containsADefaultPackage) {
+								tempRoots.add(new Path("")); //$NON-NLS-1$
+							}
+						}
+					}
+				} catch (CoreException e) {
+					// ignore
+				} finally {
+					manager.closeZipFile(zip); // handle null case
+				}
+			}
+		}
+		int size = tempRoots.size();
+		if (this.rootPaths != null) {
+			for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) {
+				tempRoots.add(new Path((String) iterator.next()));
+			}
+			this.rootPaths.clear();
+		} else {
+			this.rootPaths = new ArrayList(size);
+		}
+		size = tempRoots.size();
+		if (size > 0) {
+			ArrayList sortedRoots = new ArrayList(tempRoots);
+			if (size > 1) {
+				Collections.sort(sortedRoots, new Comparator() {
+					public int compare(Object o1, Object o2) {
+						IPath path1 = (IPath) o1;
+						IPath path2 = (IPath) o2;
+						return path1.segmentCount() - path2.segmentCount();
+					}
+				});
+			}
+			for (Iterator iter = sortedRoots.iterator(); iter.hasNext();) {
+				IPath path = (IPath) iter.next();
+				this.rootPaths.add(path.toString());
+			}
+		}
+		this.areRootPathsComputed = true;
+		if (VERBOSE) {
+			System.out.println("Spent " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+			System.out.println("Found " + size + " root paths");	//$NON-NLS-1$ //$NON-NLS-2$
+			int i = 0;
+			for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext();) {
+				System.out.println("root[" + i + "]=" + ((String) iterator.next()));//$NON-NLS-1$ //$NON-NLS-2$
+				i++;
+			}
+		}
+	}
+
+	private void computeRootPath(IContainer container, HashSet firstLevelPackageNames, boolean hasDefaultPackage, Set set, int sourcePathSegmentCount) {
+		try {
+			IResource[] resources = container.members();
+			for (int i = 0, max = resources.length; i < max; i++) {
+				IResource resource = resources[i];
+				if (resource.getType() == IResource.FOLDER) {
+					if (firstLevelPackageNames.contains(resource.getName())) {
+						IPath fullPath = container.getFullPath();
+						IPath rootPathEntry = fullPath.removeFirstSegments(sourcePathSegmentCount).setDevice(null);
+						if (rootPathEntry.segmentCount() >= 1) {
+							set.add(rootPathEntry);
+						}
+						computeRootPath((IFolder) resource, firstLevelPackageNames, hasDefaultPackage, set, sourcePathSegmentCount);
+					} else {
+						computeRootPath((IFolder) resource, firstLevelPackageNames, hasDefaultPackage, set, sourcePathSegmentCount);
+					}
+				}
+				if (i == max - 1 && hasDefaultPackage) {
+					// check if one member is a .java file
+					boolean hasJavaSourceFile = false;
+					for (int j = 0; j < max; j++) {
+						if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resources[i].getName())) {
+							hasJavaSourceFile = true;
+							break;
+						}
+					}
+					if (hasJavaSourceFile) {
+						IPath fullPath = container.getFullPath();
+						IPath rootPathEntry = fullPath.removeFirstSegments(sourcePathSegmentCount).setDevice(null);
+						set.add(rootPathEntry);
+					}
+				}
+			}
+		} catch (CoreException e) {
+			// ignore
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterType(TypeInfo typeInfo) {
+
+		this.typeDepth++;
+		if (this.typeDepth == this.types.length) { // need to grow
+			System.arraycopy(
+				this.types,
+				0,
+				this.types = new IType[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.typeNameRanges,
+				0,
+				this.typeNameRanges = new SourceRange[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.typeDeclarationStarts,
+				0,
+				this.typeDeclarationStarts = new int[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.memberName,
+				0,
+				this.memberName = new String[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.memberDeclarationStart,
+				0,
+				this.memberDeclarationStart = new int[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.memberNameRange,
+				0,
+				this.memberNameRange = new SourceRange[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.methodParameterTypes,
+				0,
+				this.methodParameterTypes = new char[this.typeDepth * 2][][],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.methodParameterNames,
+				0,
+				this.methodParameterNames = new char[this.typeDepth * 2][][],
+				0,
+				this.typeDepth);
+			System.arraycopy(
+				this.typeModifiers,
+				0,
+				this.typeModifiers = new int[this.typeDepth * 2],
+				0,
+				this.typeDepth);
+		}
+		if (typeInfo.name.length == 0) {
+			this.anonymousCounter++;
+			if (this.anonymousCounter == this.anonymousClassName) {
+				this.types[this.typeDepth] = getType(this.binaryType.getElementName());
+			} else {
+				this.types[this.typeDepth] = getType(new String(typeInfo.name));
+			}
+		} else {
+			this.types[this.typeDepth] = getType(new String(typeInfo.name));
+		}
+		this.typeNameRanges[this.typeDepth] =
+			new SourceRange(typeInfo.nameSourceStart, typeInfo.nameSourceEnd - typeInfo.nameSourceStart + 1);
+		this.typeDeclarationStarts[this.typeDepth] = typeInfo.declarationStart;
+
+		IType currentType = this.types[this.typeDepth];
+
+		// type parameters
+		if (typeInfo.typeParameters != null) {
+			for (int i = 0, length = typeInfo.typeParameters.length; i < length; i++) {
+				TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
+				ITypeParameter typeParameter = currentType.getTypeParameter(new String(typeParameterInfo.name));
+				setSourceRange(
+					typeParameter,
+					new SourceRange(
+						typeParameterInfo.declarationStart,
+						typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
+					new SourceRange(
+						typeParameterInfo.nameSourceStart,
+						typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
+			}
+		}
+
+		// type modifiers
+		this.typeModifiers[this.typeDepth] = typeInfo.modifiers;
+
+		// categories
+		addCategories(currentType, typeInfo.categories);
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterCompilationUnit() {
+		// do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterConstructor(MethodInfo methodInfo) {
+		enterAbstractMethod(methodInfo);
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterField(FieldInfo fieldInfo) {
+		if (this.typeDepth >= 0) {
+			this.memberDeclarationStart[this.typeDepth] = fieldInfo.declarationStart;
+			this.memberNameRange[this.typeDepth] =
+				new SourceRange(fieldInfo.nameSourceStart, fieldInfo.nameSourceEnd - fieldInfo.nameSourceStart + 1);
+			String fieldName = new String(fieldInfo.name);
+			this.memberName[this.typeDepth] = fieldName;
+
+			// categories
+			IType currentType = this.types[this.typeDepth];
+			IField field = currentType.getField(fieldName);
+			addCategories(field, fieldInfo.categories);
+		}
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterInitializer(
+		int declarationSourceStart,
+		int modifiers) {
+		//do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void enterMethod(MethodInfo methodInfo) {
+		enterAbstractMethod(methodInfo);
+	}
+	private void enterAbstractMethod(MethodInfo methodInfo) {
+		if (this.typeDepth >= 0) {
+			this.memberName[this.typeDepth] = new String(methodInfo.name);
+			this.memberNameRange[this.typeDepth] =
+				new SourceRange(methodInfo.nameSourceStart, methodInfo.nameSourceEnd - methodInfo.nameSourceStart + 1);
+			this.memberDeclarationStart[this.typeDepth] = methodInfo.declarationStart;
+			IType currentType = this.types[this.typeDepth];
+			int currenTypeModifiers = this.typeModifiers[this.typeDepth];
+			char[][] parameterTypes = methodInfo.parameterTypes;
+			if (methodInfo.isConstructor && currentType.getDeclaringType() != null && !Flags.isStatic(currenTypeModifiers)) {
+				IType declaringType = currentType.getDeclaringType();
+				String declaringTypeName = declaringType.getElementName();
+				if (declaringTypeName.length() == 0) {
+					IClassFile classFile = declaringType.getClassFile();
+					int length = parameterTypes != null ? parameterTypes.length : 0;
+					char[][] newParameterTypes = new char[length+1][];
+					declaringTypeName = classFile.getElementName();
+					declaringTypeName = declaringTypeName.substring(0, declaringTypeName.indexOf('.'));
+					newParameterTypes[0] = declaringTypeName.toCharArray();
+					if (length != 0) {
+						System.arraycopy(parameterTypes, 0, newParameterTypes, 1, length);
+					}
+					this.methodParameterTypes[this.typeDepth] = newParameterTypes;
+				} else {
+					int length = parameterTypes != null ? parameterTypes.length : 0;
+					char[][] newParameterTypes = new char[length+1][];
+					newParameterTypes[0] = declaringTypeName.toCharArray();
+					if (length != 0) {
+						System.arraycopy(parameterTypes, 0, newParameterTypes, 1, length);
+					}
+					this.methodParameterTypes[this.typeDepth] = newParameterTypes;
+				}
+			} else {
+				this.methodParameterTypes[this.typeDepth] = parameterTypes;
+			}
+			this.methodParameterNames[this.typeDepth] = methodInfo.parameterNames;
+
+			IMethod method = currentType.getMethod(
+					this.memberName[this.typeDepth],
+					convertTypeNamesToSigs(this.methodParameterTypes[this.typeDepth]));
+
+			// type parameters
+			if (methodInfo.typeParameters != null) {
+				for (int i = 0, length = methodInfo.typeParameters.length; i < length; i++) {
+					TypeParameterInfo typeParameterInfo = methodInfo.typeParameters[i];
+					ITypeParameter typeParameter = method.getTypeParameter(new String(typeParameterInfo.name));
+					setSourceRange(
+						typeParameter,
+						new SourceRange(
+							typeParameterInfo.declarationStart,
+							typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
+						new SourceRange(
+							typeParameterInfo.nameSourceStart,
+							typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
+				}
+			}
+			// parameters infos
+			if (methodInfo.parameterInfos != null) {
+				for (int i = 0, length = methodInfo.parameterInfos.length; i < length; i++) {
+					ParameterInfo parameterInfo = methodInfo.parameterInfos[i];
+					LocalVariableElementKey key = new LocalVariableElementKey(method, new String(parameterInfo.name));
+					SourceRange[] allRanges = new SourceRange[] {
+						new SourceRange(
+							parameterInfo.declarationStart,
+							parameterInfo.declarationEnd - parameterInfo.declarationStart + 1),
+						new SourceRange(
+							parameterInfo.nameSourceStart,
+							parameterInfo.nameSourceEnd - parameterInfo.nameSourceStart + 1)
+					};
+					this.parametersRanges.put(
+						key,
+						allRanges);
+					if (parameterInfo.modifiers != 0) {
+						if (this.finalParameters == null) {
+							this.finalParameters = new HashSet();
+						}
+						this.finalParameters.add(key);
+					}
+				}
+			}
+
+			// categories
+			addCategories(method, methodInfo.categories);
+		}
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitType(int declarationEnd) {
+		if (this.typeDepth >= 0) {
+			IType currentType = this.types[this.typeDepth];
+			setSourceRange(
+				currentType,
+				new SourceRange(
+					this.typeDeclarationStarts[this.typeDepth],
+					declarationEnd - this.typeDeclarationStarts[this.typeDepth] + 1),
+				this.typeNameRanges[this.typeDepth]);
+			this.typeDepth--;
+		}
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitCompilationUnit(int declarationEnd) {
+		//do nothing
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitConstructor(int declarationEnd) {
+		exitAbstractMethod(declarationEnd);
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
+		if (this.typeDepth >= 0) {
+			IType currentType = this.types[this.typeDepth];
+			setSourceRange(
+				currentType.getField(this.memberName[this.typeDepth]),
+				new SourceRange(
+					this.memberDeclarationStart[this.typeDepth],
+					declarationEnd - this.memberDeclarationStart[this.typeDepth] + 1),
+				this.memberNameRange[this.typeDepth]);
+		}
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitInitializer(int declarationEnd) {
+		// implements abstract method
+	}
+
+	/**
+	 * @see ISourceElementRequestor
+	 */
+	public void exitMethod(int declarationEnd, Expression defaultValue) {
+		exitAbstractMethod(declarationEnd);
+	}
+	private void exitAbstractMethod(int declarationEnd) {
+		if (this.typeDepth >= 0) {
+			IType currentType = this.types[this.typeDepth];
+			SourceRange sourceRange =
+				new SourceRange(
+					this.memberDeclarationStart[this.typeDepth],
+					declarationEnd - this.memberDeclarationStart[this.typeDepth] + 1);
+			IMethod method = currentType.getMethod(
+					this.memberName[this.typeDepth],
+					convertTypeNamesToSigs(this.methodParameterTypes[this.typeDepth]));
+			setSourceRange(
+				method,
+				sourceRange,
+				this.memberNameRange[this.typeDepth]);
+			setMethodParameterNames(
+				method,
+				this.methodParameterNames[this.typeDepth]);
+		}
+	}
+
+	/**
+	 * Locates and returns source code for the given (binary) type, in this
+	 * SourceMapper's ZIP file, or returns <code>null</code> if source
+	 * code cannot be found.
+	 */
+	public char[] findSource(IType type, IBinaryType info) {
+		if (!type.isBinary()) {
+			return null;
+		}
+		String simpleSourceFileName = ((BinaryType) type).getSourceFileName(info);
+		if (simpleSourceFileName == null) {
+			return null;
+		}
+		return findSource(type, simpleSourceFileName);
+	}
+
+	/**
+	 * Locates and returns source code for the given (binary) type, in this
+	 * SourceMapper's ZIP file, or returns <code>null</code> if source
+	 * code cannot be found.
+	 * The given simpleSourceFileName is the .java file name (without the enclosing
+	 * folder) used to create the given type (e.g. "A.java" for x/y/A$Inner.class)
+	 */
+	public char[] findSource(IType type, String simpleSourceFileName) {
+		long time = 0;
+		if (VERBOSE) {
+			time = System.currentTimeMillis();
+		}
+		PackageFragment pkgFrag = (PackageFragment) type.getPackageFragment();
+		String name = org.eclipse.jdt.internal.core.util.Util.concatWith(pkgFrag.names, simpleSourceFileName, '/');
+
+		char[] source = null;
+
+		JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
+		try {
+			javaModelManager.cacheZipFiles(this); // Cache any zip files we open during this operation
+
+			if (this.rootPath != null) {
+				source = getSourceForRootPath(this.rootPath, name);
+			}
+	
+			if (source == null) {
+				computeAllRootPaths(type);
+				if (this.rootPaths != null) {
+					loop: for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) {
+						String currentRootPath = (String) iterator.next();
+						if (!currentRootPath.equals(this.rootPath)) {
+							source = getSourceForRootPath(currentRootPath, name);
+							if (source != null) {
+								// remember right root path
+								this.rootPath = currentRootPath;
+								break loop;
+							}
+						}
+					}
+				}
+			}
+		} finally {
+			javaModelManager.flushZipFiles(this); // clean up cached zip files.
+		}
+		if (VERBOSE) {
+			System.out.println("spent " + (System.currentTimeMillis() - time) + "ms for " + type.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return source;
+	}
+
+	private char[] getSourceForRootPath(String currentRootPath, String name) {
+		String newFullName;
+		if (!currentRootPath.equals(IPackageFragmentRoot.DEFAULT_PACKAGEROOT_PATH)) {
+			if (currentRootPath.endsWith("/")) { //$NON-NLS-1$
+				newFullName = currentRootPath + name;
+			} else {
+				newFullName = currentRootPath + '/' + name;
+			}
+		} else {
+			newFullName = name;
+		}
+		return this.findSource(newFullName);
+	}
+
+	public char[] findSource(String fullName) {
+		char[] source = null;
+		Object target = JavaModel.getTarget(this.sourcePath, true);
+		String charSet = null;
+		if (target instanceof IContainer) {
+			IResource res = ((IContainer)target).findMember(fullName);
+			if (res instanceof IFile) {
+				try {
+					// Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order
+					try {
+						// Use the implicit encoding only when the source attachment's encoding hasn't been explicitly set.
+						charSet = ((IFile) res).getCharset(this.encoding == null);
+					} catch (CoreException e) {
+						// Ignore
+					}
+					source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile) res,
+									charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet);
+				} catch (JavaModelException e) {
+					// Ignore
+				}
+			}
+		} else {
+			try {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511
+				// For a resource inside the workspace, use the encoding set on the resource
+				if (target instanceof IFile)
+					charSet = ((IFile)target).getCharset(this.encoding == null);
+			} catch (CoreException e) {
+				// Ignore
+			}
+			
+			// try to get the entry
+			ZipEntry entry = null;
+			ZipFile zip = null;
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			try {
+				zip = manager.getZipFile(this.sourcePath);
+				entry = zip.getEntry(fullName);
+				if (entry != null) {
+					// now read the source code
+					source = readSource(entry, zip, charSet);
+				}
+			} catch (CoreException e) {
+				return null;
+			} finally {
+				manager.closeZipFile(zip); // handle null case
+			}
+		}
+		return source;
+	}
+
+
+	public int getFlags(IJavaElement element) {
+		switch(element.getElementType()) {
+			case IJavaElement.LOCAL_VARIABLE :
+				LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+				if (this.finalParameters != null && this.finalParameters.contains(key)) {
+					return Flags.AccFinal;
+				}
+		}
+		return 0;
+	}
+
+	/**
+	 * Returns the SourceRange for the name of the given element, or
+	 * {-1, -1} if no source range is known for the name of the element.
+	 */
+	public SourceRange getNameRange(IJavaElement element) {
+		switch(element.getElementType()) {
+			case IJavaElement.METHOD :
+				if (((IMember) element).isBinary()) {
+					IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
+					if(el[1] != null && this.sourceRanges.get(el[0]) == null) {
+						element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
+					} else {
+						element = el[0];
+					}
+				}
+				break;
+			case IJavaElement.TYPE_PARAMETER :
+				IJavaElement parent = element.getParent();
+				if (parent.getElementType() == IJavaElement.METHOD) {
+					IMethod method = (IMethod) parent;
+					if (method.isBinary()) {
+						IJavaElement[] el = getUnqualifiedMethodHandle(method, false);
+						if(el[1] != null && this.sourceRanges.get(el[0]) == null) {
+							method = (IMethod) getUnqualifiedMethodHandle(method, true)[0];
+						} else {
+							method = (IMethod) el[0];
+						}
+						element = method.getTypeParameter(element.getElementName());
+					}
+				}
+				break;
+			case IJavaElement.LOCAL_VARIABLE :
+				LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+				SourceRange[] ranges = (SourceRange[]) this.parametersRanges.get(key);
+				if (ranges == null) {
+					return UNKNOWN_RANGE;
+				} else {
+					return ranges[1];
+				}
+		}
+		SourceRange[] ranges = (SourceRange[]) this.sourceRanges.get(element);
+		if (ranges == null) {
+			return UNKNOWN_RANGE;
+		} else {
+			return ranges[1];
+		}
+	}
+
+	/**
+	 * Returns parameters names for the given method, or
+	 * null if no parameter names are known for the method.
+	 */
+	public char[][] getMethodParameterNames(IMethod method) {
+		if (method.isBinary()) {
+			IJavaElement[] el = getUnqualifiedMethodHandle(method, false);
+			if(el[1] != null && this.parameterNames.get(el[0]) == null) {
+				method = (IMethod) getUnqualifiedMethodHandle(method, true)[0];
+			} else {
+				method = (IMethod) el[0];
+			}
+		}
+		char[][] parameters = (char[][]) this.parameterNames.get(method);
+		if (parameters == null) {
+			return null;
+		} else {
+			return parameters;
+		}
+	}
+
+	/**
+	 * Returns the <code>SourceRange</code> for the given element, or
+	 * {-1, -1} if no source range is known for the element.
+	 */
+	public SourceRange getSourceRange(IJavaElement element) {
+		switch(element.getElementType()) {
+			case IJavaElement.METHOD :
+				if (((IMember) element).isBinary()) {
+					IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
+					if(el[1] != null && this.sourceRanges.get(el[0]) == null) {
+						element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
+					} else {
+						element = el[0];
+					}
+				}
+				break;
+			case IJavaElement.TYPE_PARAMETER :
+				IJavaElement parent = element.getParent();
+				if (parent.getElementType() == IJavaElement.METHOD) {
+					IMethod method = (IMethod) parent;
+					if (method.isBinary()) {
+						IJavaElement[] el = getUnqualifiedMethodHandle(method, false);
+						if(el[1] != null && this.sourceRanges.get(el[0]) == null) {
+							method = (IMethod) getUnqualifiedMethodHandle(method, true)[0];
+						} else {
+							method = (IMethod) el[0];
+						}
+						element = method.getTypeParameter(element.getElementName());
+					}
+				}
+				break;
+			case IJavaElement.LOCAL_VARIABLE :
+				LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+				SourceRange[] ranges = (SourceRange[]) this.parametersRanges.get(key);
+				if (ranges == null) {
+					return UNKNOWN_RANGE;
+				} else {
+					return ranges[0];
+				}
+		}
+		SourceRange[] ranges = (SourceRange[]) this.sourceRanges.get(element);
+		if (ranges == null) {
+			return UNKNOWN_RANGE;
+		} else {
+			return ranges[0];
+		}
+	}
+
+	/**
+	 * Returns the type with the given <code>typeName</code>.  Returns inner classes
+	 * as well.
+	 */
+	protected IType getType(String typeName) {
+		if (typeName.length() == 0) {
+			IJavaElement classFile = this.binaryType.getParent();
+			String classFileName = classFile.getElementName();
+			StringBuffer newClassFileName = new StringBuffer();
+			int lastDollar = classFileName.lastIndexOf('$');
+			for (int i = 0; i <= lastDollar; i++)
+				newClassFileName.append(classFileName.charAt(i));
+			newClassFileName.append(Integer.toString(this.anonymousCounter));
+			PackageFragment pkg = (PackageFragment) classFile.getParent();
+			return new BinaryType(new ClassFile(pkg, newClassFileName.toString()), typeName);
+		} else if (this.binaryType.getElementName().equals(typeName))
+			return this.binaryType;
+		else
+			return this.binaryType.getType(typeName);
+	}
+
+	/**
+	 * Creates a handle that has parameter types that are not
+	 * fully qualified so that the correct source is found.
+	 */
+	protected IJavaElement[] getUnqualifiedMethodHandle(IMethod method, boolean noDollar) {
+		boolean hasDollar = false;
+		String[] qualifiedParameterTypes = method.getParameterTypes();
+		String[] unqualifiedParameterTypes = new String[qualifiedParameterTypes.length];
+		for (int i = 0; i < qualifiedParameterTypes.length; i++) {
+			StringBuffer unqualifiedTypeSig = new StringBuffer();
+			getUnqualifiedTypeSignature(qualifiedParameterTypes[i], 0/*start*/, qualifiedParameterTypes[i].length(), unqualifiedTypeSig, noDollar);
+			unqualifiedParameterTypes[i] = unqualifiedTypeSig.toString();
+			hasDollar |= unqualifiedParameterTypes[i].lastIndexOf('$') != -1;
+		}
+
+		IJavaElement[] result = new IJavaElement[2];
+		result[0] = ((IType) method.getParent()).getMethod(
+			method.getElementName(),
+			unqualifiedParameterTypes);
+		if(hasDollar) {
+			result[1] = result[0];
+		}
+		return result;
+	}
+
+	private int getUnqualifiedTypeSignature(String qualifiedTypeSig, int start, int length, StringBuffer unqualifiedTypeSig, boolean noDollar) {
+		char firstChar = qualifiedTypeSig.charAt(start);
+		int end = start + 1;
+		boolean sigStart = false;
+		firstPass: for (int i = start; i < length; i++) {
+			char current = qualifiedTypeSig.charAt(i);
+			switch (current) {
+				case Signature.C_ARRAY :
+				case Signature.C_SUPER:
+				case Signature.C_EXTENDS:
+					unqualifiedTypeSig.append(current);
+					start = i + 1;
+					end = start + 1;
+					firstChar = qualifiedTypeSig.charAt(start);
+					break;
+				case Signature.C_RESOLVED :
+				case Signature.C_UNRESOLVED :
+				case Signature.C_TYPE_VARIABLE :
+					if (!sigStart) {
+						start = ++i;
+						sigStart = true;
+					}
+					break;
+				case Signature.C_NAME_END:
+				case Signature.C_GENERIC_START :
+					end = i;
+					break firstPass;
+				case Signature.C_STAR :
+					unqualifiedTypeSig.append(current);
+					start = i + 1;
+					end = start + 1;
+					firstChar = qualifiedTypeSig.charAt(start);
+					break;
+				case Signature.C_GENERIC_END :
+					return i;
+				case Signature.C_DOT:
+					start = ++i;
+					break;
+				case Signature.C_BOOLEAN :
+				case Signature.C_BYTE :
+				case Signature.C_CHAR :
+				case Signature.C_DOUBLE :
+				case Signature.C_FLOAT :
+				case Signature.C_INT :
+				case Signature.C_LONG :
+				case Signature.C_SHORT :
+					if (!sigStart) {
+						unqualifiedTypeSig.append(current);
+						return i+1;
+					}
+			}
+		}
+		switch (firstChar) {
+			case Signature.C_RESOLVED :
+			case Signature.C_UNRESOLVED :
+			case Signature.C_TYPE_VARIABLE :
+				unqualifiedTypeSig.append(Signature.C_UNRESOLVED);
+				if (noDollar) {
+					int lastDollar = qualifiedTypeSig.lastIndexOf('$', end);
+					if (lastDollar > start)
+						start = lastDollar + 1;
+				}
+				for (int i = start; i < length; i++) {
+					char current = qualifiedTypeSig.charAt(i);
+					switch (current) {
+						case Signature.C_GENERIC_START:
+							unqualifiedTypeSig.append(current);
+							i++;
+							do {
+								i = getUnqualifiedTypeSignature(qualifiedTypeSig, i, length, unqualifiedTypeSig, noDollar);
+							} while (qualifiedTypeSig.charAt(i) != Signature.C_GENERIC_END);
+							unqualifiedTypeSig.append(Signature.C_GENERIC_END);
+							break;
+						case Signature.C_NAME_END:
+							unqualifiedTypeSig.append(current);
+							return i + 1;
+						default:
+							unqualifiedTypeSig.append(current);
+							break;
+					}
+				}
+				return length;
+			default :
+				// primitive type or wildcard
+				unqualifiedTypeSig.append(qualifiedTypeSig.substring(start, end));
+				return end;
+		}
+	}
+
+	/**
+	 * Maps the given source code to the given binary type and its children.
+	 */
+	public void mapSource(IType type, char[] contents, IBinaryType info) {
+		this.mapSource(type, contents, info, null);
+	}
+
+	/**
+	 * Maps the given source code to the given binary type and its children.
+	 * If a non-null java element is passed, finds the name range for the
+	 * given java element without storing it.
+	 */
+	public synchronized ISourceRange mapSource(
+		IType type,
+		char[] contents,
+		IBinaryType info,
+		IJavaElement elementToFind) {
+
+		this.binaryType = (BinaryType) type;
+
+		// check whether it is already mapped
+		if (this.sourceRanges.get(type) != null) return (elementToFind != null) ? getNameRange(elementToFind) : null;
+
+		this.importsTable.remove(this.binaryType);
+		this.importsCounterTable.remove(this.binaryType);
+		this.searchedElement = elementToFind;
+		this.types = new IType[1];
+		this.typeDeclarationStarts = new int[1];
+		this.typeNameRanges = new SourceRange[1];
+		this.typeModifiers = new int[1];
+		this.typeDepth = -1;
+		this.memberDeclarationStart = new int[1];
+		this.memberName = new String[1];
+		this.memberNameRange = new SourceRange[1];
+		this.methodParameterTypes = new char[1][][];
+		this.methodParameterNames = new char[1][][];
+		this.anonymousCounter = 0;
+
+		HashMap oldSourceRanges = null;
+		if (elementToFind != null) {
+			oldSourceRanges = (HashMap) this.sourceRanges.clone();
+		}
+		try {
+			IProblemFactory factory = new DefaultProblemFactory();
+			SourceElementParser parser = null;
+			this.anonymousClassName = 0;
+			if (info == null) {
+				try {
+					info = (IBinaryType) this.binaryType.getElementInfo();
+				} catch(JavaModelException e) {
+					return null;
+				}
+			}
+			boolean isAnonymousClass = info.isAnonymous();
+			char[] fullName = info.getName();
+			if (isAnonymousClass) {
+				String eltName = this.binaryType.getParent().getElementName();
+				eltName = eltName.substring(eltName.lastIndexOf('$') + 1, eltName.length());
+				try {
+					this.anonymousClassName = Integer.parseInt(eltName);
+				} catch(NumberFormatException e) {
+					// ignore
+				}
+			}
+			boolean doFullParse = hasToRetrieveSourceRangesForLocalClass(fullName);
+			parser = new SourceElementParser(this, factory, new CompilerOptions(this.options), doFullParse, true/*optimize string literals*/);
+			parser.javadocParser.checkDocComment = false; // disable javadoc parsing
+			IJavaElement javaElement = this.binaryType.getCompilationUnit();
+			if (javaElement == null) javaElement = this.binaryType.getParent();
+			parser.parseCompilationUnit(
+				new BasicCompilationUnit(contents, null, this.binaryType.sourceFileName(info), javaElement),
+				doFullParse,
+				null/*no progress*/);
+			if (elementToFind != null) {
+				ISourceRange range = getNameRange(elementToFind);
+				return range;
+			} else {
+				return null;
+			}
+		} finally {
+			if (elementToFind != null) {
+				this.sourceRanges = oldSourceRanges;
+			}
+			this.binaryType = null;
+			this.searchedElement = null;
+			this.types = null;
+			this.typeDeclarationStarts = null;
+			this.typeNameRanges = null;
+			this.typeDepth = -1;
+		}
+	}
+	private char[] readSource(ZipEntry entry, ZipFile zip, String charSet) {
+		try {
+			byte[] bytes = Util.getZipEntryByteContent(entry, zip);
+			if (bytes != null) {
+				// Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order
+				return Util.bytesToChar(bytes, charSet == null ? (this.encoding == null ? this.defaultEncoding : this.encoding) : charSet);
+			}
+		} catch (IOException e) {
+			// ignore
+		}
+		return null;
+	}
+
+	/**
+	 * Sets the mapping for this method to its parameter names.
+	 *
+	 * @see #parameterNames
+	 */
+	protected void setMethodParameterNames(
+		IMethod method,
+		char[][] parameterNames) {
+		if (parameterNames == null) {
+			parameterNames = CharOperation.NO_CHAR_CHAR;
+		}
+		this.parameterNames.put(method, parameterNames);
+	}
+
+	/**
+	 * Sets the mapping for this element to its source ranges for its source range
+	 * and name range.
+	 *
+	 * @see #sourceRanges
+	 */
+	protected void setSourceRange(
+		IJavaElement element,
+		SourceRange sourceRange,
+		SourceRange nameRange) {
+		this.sourceRanges.put(element, new SourceRange[] { sourceRange, nameRange });
+	}
+
+	/**
+	 * Return a char[][] array containing the imports of the attached source for the binary type
+	 */
+	public char[][] getImports(BinaryType type) {
+		char[][] imports = (char[][]) this.importsTable.get(type);
+		if (imports != null) {
+			int importsCounter = ((Integer) this.importsCounterTable.get(type)).intValue();
+			if (imports.length != importsCounter) {
+				System.arraycopy(
+					imports,
+					0,
+					(imports = new char[importsCounter][]),
+					0,
+					importsCounter);
+			}
+			this.importsTable.put(type, imports);
+		}
+		return imports;
+	}
+
+	private boolean hasToRetrieveSourceRangesForLocalClass(char[] eltName) {
+		/*
+		 * A$1$B$2 : true
+		 * A$B$B$2 : true
+		 * A$C$B$D : false
+		 * A$F$B$D$1$F : true
+		 * A$F$B$D$1F : true
+		 * A$1 : true
+		 * A$B : false
+		 */
+		if (eltName == null) return false;
+		int length = eltName.length;
+		int dollarIndex = CharOperation.indexOf('$', eltName, 0);
+		while (dollarIndex != -1) {
+			int nameStart = dollarIndex+1;
+			if (nameStart == length) return false;
+			if (Character.isDigit(eltName[nameStart]))
+				return true;
+			dollarIndex = CharOperation.indexOf('$', eltName, nameStart);
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
new file mode 100644
index 0000000..00026ab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see IMethod
+ */
+
+public class SourceMethod extends NamedMember implements IMethod {
+
+	/**
+	 * The parameter type signatures of the method - stored locally
+	 * to perform equality test. <code>null</code> indicates no
+	 * parameters.
+	 */
+	protected String[] parameterTypes;
+
+protected SourceMethod(JavaElement parent, String name, String[] parameterTypes) {
+	super(parent, name);
+	// Assertion disabled since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=179011
+	// Assert.isTrue(name.indexOf('.') == -1);
+	if (parameterTypes == null) {
+		this.parameterTypes= CharOperation.NO_STRINGS;
+	} else {
+		this.parameterTypes= parameterTypes;
+	}
+}
+protected void closing(Object info) throws JavaModelException {
+	super.closing(info);
+	SourceMethodElementInfo elementInfo = (SourceMethodElementInfo) info;
+	ITypeParameter[] typeParameters = elementInfo.typeParameters;
+	for (int i = 0, length = typeParameters.length; i < length; i++) {
+		((TypeParameter) typeParameters[i]).close();
+	}
+}
+public boolean equals(Object o) {
+	if (!(o instanceof SourceMethod)) return false;
+	return super.equals(o) && Util.equalArraysOrNull(this.parameterTypes, ((SourceMethod)o).parameterTypes);
+}
+public IMemberValuePair getDefaultValue() throws JavaModelException {
+	SourceMethodElementInfo sourceMethodInfo = (SourceMethodElementInfo) getElementInfo();
+	if (sourceMethodInfo.isAnnotationMethod()) {
+		return ((SourceAnnotationMethodInfo) sourceMethodInfo).defaultValue;
+	}
+	return null;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return METHOD;
+}
+/**
+ * @see IMethod
+ */
+public String[] getExceptionTypes() throws JavaModelException {
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	char[][] exs= info.getExceptionTypeNames();
+	return CompilationUnitStructureRequestor.convertTypeNamesToSigs(exs);
+}
+/**
+ * @see JavaElement#getHandleMemento(StringBuffer)
+ */
+protected void getHandleMemento(StringBuffer buff) {
+	((JavaElement) getParent()).getHandleMemento(buff);
+	char delimiter = getHandleMementoDelimiter();
+	buff.append(delimiter);
+	escapeMementoName(buff, getElementName());
+	for (int i = 0; i < this.parameterTypes.length; i++) {
+		buff.append(delimiter);
+		escapeMementoName(buff, this.parameterTypes[i]);
+	}
+	if (this.occurrenceCount > 1) {
+		buff.append(JEM_COUNT);
+		buff.append(this.occurrenceCount);
+	}
+}
+/**
+ * @see JavaElement#getHandleMemento()
+ */
+protected char getHandleMementoDelimiter() {
+	return JavaElement.JEM_METHOD;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
+/**
+ * @see IMethod
+ */
+public int getNumberOfParameters() {
+	return this.parameterTypes == null ? 0 : this.parameterTypes.length;
+}
+/**
+ * @see IMethod
+ */
+public String[] getParameterNames() throws JavaModelException {
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	char[][] names= info.getArgumentNames();
+	return CharOperation.toStrings(names);
+}
+/**
+ * @see IMethod
+ */
+public String[] getParameterTypes() {
+	return this.parameterTypes;
+}
+
+public ITypeParameter getTypeParameter(String typeParameterName) {
+	return new TypeParameter(this, typeParameterName);
+}
+
+public ITypeParameter[] getTypeParameters() throws JavaModelException {
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	return info.typeParameters;
+}
+public ILocalVariable[] getParameters() throws JavaModelException {
+	ILocalVariable[] arguments = ((SourceMethodElementInfo) getElementInfo()).arguments;
+	if (arguments == null)
+		return LocalVariable.NO_LOCAL_VARIABLES;
+	return arguments;
+}
+/**
+ * @see IMethod#getTypeParameterSignatures()
+ * @since 3.0
+ * @deprecated
+ */
+public String[] getTypeParameterSignatures() throws JavaModelException {
+	ITypeParameter[] typeParameters = getTypeParameters();
+	int length = typeParameters.length;
+	String[] typeParameterSignatures = new String[length];
+	for (int i = 0; i < length; i++) {
+		TypeParameter typeParameter = (TypeParameter) typeParameters[i];
+		TypeParameterElementInfo info = (TypeParameterElementInfo) typeParameter.getElementInfo();
+		char[][] bounds = info.bounds;
+		if (bounds == null) {
+			typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameter.getElementName(), CharOperation.NO_STRINGS);
+		} else {
+			int boundsLength = bounds.length;
+			char[][] boundSignatures = new char[boundsLength][];
+			for (int j = 0; j < boundsLength; j++) {
+				boundSignatures[j] = Signature.createCharArrayTypeSignature(bounds[j], false);
+			}
+			typeParameterSignatures[i] = new String(Signature.createTypeParameterSignature(typeParameter.getElementName().toCharArray(), boundSignatures));
+		}
+	}
+	return typeParameterSignatures;
+}
+
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner) {
+		CompilationUnit cu = (CompilationUnit)getAncestor(COMPILATION_UNIT);
+		if (cu.isPrimary()) return this;
+	}
+	IJavaElement primaryParent = this.parent.getPrimaryElement(false);
+	return ((IType)primaryParent).getMethod(this.name, this.parameterTypes);
+}
+public String[] getRawParameterNames() throws JavaModelException {
+	return getParameterNames();
+}
+/**
+ * @see IMethod
+ */
+public String getReturnType() throws JavaModelException {
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	return Signature.createTypeSignature(info.getReturnTypeName(), false);
+}
+/**
+ * @see IMethod
+ */
+public String getSignature() throws JavaModelException {
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	return Signature.createMethodSignature(this.parameterTypes, Signature.createTypeSignature(info.getReturnTypeName(), false));
+}
+/**
+ * @see org.eclipse.jdt.internal.core.JavaElement#hashCode()
+ */
+public int hashCode() {
+   int hash = super.hashCode();
+	for (int i = 0, length = this.parameterTypes.length; i < length; i++) {
+	    hash = Util.combineHashCodes(hash, this.parameterTypes[i].hashCode());
+	}
+	return hash;
+}
+/**
+ * @see IMethod
+ */
+public boolean isConstructor() throws JavaModelException {
+	if (!getElementName().equals(this.parent.getElementName())) {
+		// faster than reaching the info
+		return false;
+	}
+	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
+	return info.isConstructor();
+}
+/**
+ * @see IMethod#isMainMethod()
+ */
+public boolean isMainMethod() throws JavaModelException {
+	return this.isMainMethod(this);
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+/**
+ * @see IMethod#isSimilar(IMethod)
+ */
+public boolean isSimilar(IMethod method) {
+	return
+		areSimilarMethods(
+			getElementName(), getParameterTypes(),
+			method.getElementName(), method.getParameterTypes(),
+			null);
+}
+
+/**
+ */
+public String readableName() {
+
+	StringBuffer buffer = new StringBuffer(super.readableName());
+	buffer.append('(');
+	int length;
+	if (this.parameterTypes != null && (length = this.parameterTypes.length) > 0) {
+		for (int i = 0; i < length; i++) {
+			buffer.append(Signature.toString(this.parameterTypes[i]));
+			if (i < length - 1) {
+				buffer.append(", "); //$NON-NLS-1$
+			}
+		}
+	}
+	buffer.append(')');
+	return buffer.toString();
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedSourceMethod(this.parent, this.name, this.parameterTypes, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		toStringName(buffer);
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		toStringName(buffer);
+	} else {
+		SourceMethodElementInfo methodInfo = (SourceMethodElementInfo) info;
+		int flags = methodInfo.getModifiers();
+		if (Flags.isStatic(flags)) {
+			buffer.append("static "); //$NON-NLS-1$
+		}
+		if (!methodInfo.isConstructor()) {
+			buffer.append(methodInfo.getReturnTypeName());
+			buffer.append(' ');
+		}
+		toStringName(buffer, flags);
+	}
+}
+protected void toStringName(StringBuffer buffer) {
+	toStringName(buffer, 0);
+}
+protected void toStringName(StringBuffer buffer, int flags) {
+	buffer.append(getElementName());
+	buffer.append('(');
+	String[] parameters = getParameterTypes();
+	int length;
+	if (parameters != null && (length = parameters.length) > 0) {
+		boolean isVarargs = Flags.isVarargs(flags);
+		for (int i = 0; i < length; i++) {
+			try {
+				if (i < length - 1) {
+					buffer.append(Signature.toString(parameters[i]));
+					buffer.append(", "); //$NON-NLS-1$
+				} else if (isVarargs) {
+					// remove array from signature
+					String parameter = parameters[i].substring(1);
+					buffer.append(Signature.toString(parameter));
+					buffer.append(" ..."); //$NON-NLS-1$
+				} else {
+					buffer.append(Signature.toString(parameters[i]));
+				}
+			} catch (IllegalArgumentException e) {
+				// parameter signature is malformed
+				buffer.append("*** invalid signature: "); //$NON-NLS-1$
+				buffer.append(parameters[i]);
+			}
+		}
+	}
+	buffer.append(')');
+	if (this.occurrenceCount > 1) {
+		buffer.append("#"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
new file mode 100644
index 0000000..a85cfaa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ISourceMethod;
+
+/**
+ * Element info for IMethod elements.
+ */
+public abstract class SourceMethodElementInfo extends AnnotatableInfo implements ISourceMethod {
+
+	/**
+	 * For a source method (that is, a method contained in a compilation unit)
+	 * this is a collection of the names of the parameters for this method,
+	 * in the order the parameters are delcared. For a binary method (that is,
+	 * a method declared in a binary type), these names are invented as
+	 * "arg"i where i starts at 1. This is an empty array if this method
+	 * has no parameters.
+	 */
+	protected char[][] argumentNames;
+
+	/**
+	 * A collection of type names of the exceptions this
+	 * method throws, or an empty collection if this method
+	 * does not declare to throw any exceptions. A name is a simple
+	 * name or a qualified, dot separated name.
+	 * For example, Hashtable or java.util.Hashtable.
+	 */
+	protected char[][] exceptionTypes;
+	
+	protected ILocalVariable[] arguments;
+
+	/*
+	 * The type parameters of this source type. Empty if none.
+	 */
+	protected ITypeParameter[] typeParameters = TypeParameter.NO_TYPE_PARAMETERS;
+
+public char[][] getArgumentNames() {
+	return this.argumentNames;
+}
+public char[][] getExceptionTypeNames() {
+	return this.exceptionTypes;
+}
+public abstract char[] getReturnTypeName();
+
+public char[][][] getTypeParameterBounds() {
+	int length = this.typeParameters.length;
+	char[][][] typeParameterBounds = new char[length][][];
+	for (int i = 0; i < length; i++) {
+		try {
+			TypeParameterElementInfo info = (TypeParameterElementInfo) ((JavaElement)this.typeParameters[i]).getElementInfo();
+			typeParameterBounds[i] = info.bounds;
+		} catch (JavaModelException e) {
+			// type parameter does not exist: ignore
+		}
+	}
+	return typeParameterBounds;
+}
+public char[][] getTypeParameterNames() {
+	int length = this.typeParameters.length;
+	if (length == 0) return CharOperation.NO_CHAR_CHAR;
+	char[][] typeParameterNames = new char[length][];
+	for (int i = 0; i < length; i++) {
+		typeParameterNames[i] = this.typeParameters[i].getElementName().toCharArray();
+	}
+	return typeParameterNames;
+}
+public abstract boolean isConstructor();
+public abstract boolean isAnnotationMethod();
+protected void setArgumentNames(char[][] names) {
+	this.argumentNames = names;
+}
+protected void setExceptionTypeNames(char[][] types) {
+	this.exceptionTypes = types;
+}
+protected abstract void setReturnType(char[] type);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java
new file mode 100644
index 0000000..597afbe
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/*
+ * Element info for method from source.
+ */
+public class SourceMethodInfo extends SourceMethodElementInfo {
+
+	/*
+	 * Return type name for this method. The return type of
+	 * constructors is equivalent to void.
+	 */
+	protected char[] returnType;
+
+	public boolean isAnnotationMethod() {
+		return false;
+	}
+
+	public boolean isConstructor() {
+		return false;
+	}
+
+	public char[] getReturnTypeName() {
+		return this.returnType;
+	}
+
+	protected void setReturnType(char[] type) {
+		this.returnType = type;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodWithChildrenInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodWithChildrenInfo.java
new file mode 100644
index 0000000..012ae0e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodWithChildrenInfo.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+public class SourceMethodWithChildrenInfo extends SourceMethodInfo {
+
+	protected IJavaElement[] children;
+	
+	public SourceMethodWithChildrenInfo(IJavaElement[] children) {
+		this.children = children;
+	}
+
+	public IJavaElement[] getChildren() {
+		return this.children;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java
new file mode 100644
index 0000000..240d906
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.core.util.DOMFinder;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * Abstract class for Java elements which implement ISourceReference.
+ */
+public abstract class SourceRefElement extends JavaElement implements ISourceReference {
+	/*
+	 * A count to uniquely identify this element in the case
+	 * that a duplicate named element exists. For example, if
+	 * there are two fields in a compilation unit with the
+	 * same name, the occurrence count is used to distinguish
+	 * them.  The occurrence count starts at 1 (thus the first
+	 * occurrence is occurrence 1, not occurrence 0).
+	 */
+	public int occurrenceCount = 1;
+
+protected SourceRefElement(JavaElement parent) {
+	super(parent);
+}
+/**
+ * This element is being closed.  Do any necessary cleanup.
+ */
+protected void closing(Object info) throws JavaModelException {
+	// Do any necessary cleanup
+}
+/**
+ * Returns a new element info for this element.
+ */
+protected Object createElementInfo() {
+	return null; // not used for source ref elements
+}
+/**
+ * @see ISourceManipulation
+ */
+public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] containers= new IJavaElement[] {container};
+	IJavaElement[] siblings= null;
+	if (sibling != null) {
+		siblings= new IJavaElement[] {sibling};
+	}
+	String[] renamings= null;
+	if (rename != null) {
+		renamings= new String[] {rename};
+	}
+	getJavaModel().copy(elements, containers, siblings, renamings, force, monitor);
+}
+/**
+ * @see ISourceManipulation
+ */
+public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException {
+	IJavaElement[] elements = new IJavaElement[] {this};
+	getJavaModel().delete(elements, force, monitor);
+}
+public boolean equals(Object o) {
+	if (!(o instanceof SourceRefElement)) return false;
+	return this.occurrenceCount == ((SourceRefElement)o).occurrenceCount &&
+			super.equals(o);
+}
+/**
+ * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
+ * or <code>null</code> if there is no corresponding node.
+ */
+public ASTNode findNode(CompilationUnit ast) {
+	DOMFinder finder = new DOMFinder(ast, this, false);
+	try {
+		return finder.search();
+	} catch (JavaModelException e) {
+		// receiver doesn't exist
+		return null;
+	}
+}
+/*
+ * @see JavaElement#generateInfos
+ */
+protected void generateInfos(Object info, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
+	Openable openableParent = (Openable)getOpenableParent();
+	if (openableParent == null) return;
+
+	JavaElementInfo openableParentInfo = (JavaElementInfo) JavaModelManager.getJavaModelManager().getInfo(openableParent);
+	if (openableParentInfo == null) {
+		openableParent.generateInfos(openableParent.createElementInfo(), newElements, pm);
+	}
+}
+public IAnnotation getAnnotation(String name) {
+	return new Annotation(this, name);
+}
+public IAnnotation[] getAnnotations() throws JavaModelException {
+	AnnotatableInfo info = (AnnotatableInfo) getElementInfo();
+	return info.annotations;
+}
+/**
+ * @see IMember
+ */
+public ICompilationUnit getCompilationUnit() {
+	return (ICompilationUnit) getAncestor(COMPILATION_UNIT);
+}
+/**
+ * Elements within compilation units and class files have no
+ * corresponding resource.
+ *
+ * @see IJavaElement
+ */
+public IResource getCorrespondingResource() throws JavaModelException {
+	if (!exists()) throw newNotPresentException();
+	return null;
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_COUNT:
+			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
+	}
+	return this;
+}
+protected void getHandleMemento(StringBuffer buff) {
+	super.getHandleMemento(buff);
+	if (this.occurrenceCount > 1) {
+		buff.append(JEM_COUNT);
+		buff.append(this.occurrenceCount);
+	}
+}
+/*
+ * Update the occurence count of the receiver and creates a Java element handle from the given memento.
+ * The given working copy owner is used only for compilation unit handles.
+ */
+public IJavaElement getHandleUpdatingCountFromMemento(MementoTokenizer memento, WorkingCopyOwner owner) {
+	if (!memento.hasMoreTokens()) return this;
+	this.occurrenceCount = Integer.parseInt(memento.nextToken());
+	if (!memento.hasMoreTokens()) return this;
+	String token = memento.nextToken();
+	return getHandleFromMemento(token, memento, owner);
+}
+/*
+ * @see IMember#getOccurrenceCount()
+ */
+public int getOccurrenceCount() {
+	return this.occurrenceCount;
+}
+/**
+ * Return the first instance of IOpenable in the hierarchy of this
+ * type (going up the hierarchy from this type);
+ */
+public IOpenable getOpenableParent() {
+	IJavaElement current = getParent();
+	while (current != null){
+		if (current instanceof IOpenable){
+			return (IOpenable) current;
+		}
+		current = current.getParent();
+	}
+	return null;
+}
+/*
+ * @see IJavaElement
+ */
+public IPath getPath() {
+	return getParent().getPath();
+}
+/*
+ * @see IJavaElement
+ */
+public IResource resource() {
+	return this.parent.resource();
+}
+/**
+ * @see ISourceReference
+ */
+public String getSource() throws JavaModelException {
+	IOpenable openable = getOpenableParent();
+	IBuffer buffer = openable.getBuffer();
+	if (buffer == null) {
+		return null;
+	}
+	ISourceRange range = getSourceRange();
+	int offset = range.getOffset();
+	int length = range.getLength();
+	if (offset == -1 || length == 0 ) {
+		return null;
+	}
+	try {
+		return buffer.getText(offset, length);
+	} catch(RuntimeException e) {
+		return null;
+	}
+}
+/**
+ * @see ISourceReference
+ */
+public ISourceRange getSourceRange() throws JavaModelException {
+	SourceRefElementInfo info = (SourceRefElementInfo) getElementInfo();
+	return info.getSourceRange();
+}
+/**
+ * @see IJavaElement
+ */
+public IResource getUnderlyingResource() throws JavaModelException {
+	if (!exists()) throw newNotPresentException();
+	return getParent().getUnderlyingResource();
+}
+/**
+ * @see IParent
+ */
+public boolean hasChildren() throws JavaModelException {
+	return getChildren().length > 0;
+}
+/**
+ * @see IJavaElement
+ */
+public boolean isStructureKnown() throws JavaModelException {
+	// structure is always known inside an openable
+	return true;
+}
+/**
+ * @see ISourceManipulation
+ */
+public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (container == null) {
+		throw new IllegalArgumentException(Messages.operation_nullContainer);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] containers= new IJavaElement[] {container};
+	IJavaElement[] siblings= null;
+	if (sibling != null) {
+		siblings= new IJavaElement[] {sibling};
+	}
+	String[] renamings= null;
+	if (rename != null) {
+		renamings= new String[] {rename};
+	}
+	getJavaModel().move(elements, containers, siblings, renamings, force, monitor);
+}
+/**
+ * @see ISourceManipulation
+ */
+public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	if (newName == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	}
+	IJavaElement[] elements= new IJavaElement[] {this};
+	IJavaElement[] dests= new IJavaElement[] {getParent()};
+	String[] renamings= new String[] {newName};
+	getJavaModel().rename(elements, dests, renamings, force, monitor);
+}
+protected void toStringName(StringBuffer buffer) {
+	super.toStringName(buffer);
+	if (this.occurrenceCount > 1) {
+		buffer.append("#"); //$NON-NLS-1$
+		buffer.append(this.occurrenceCount);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java
new file mode 100644
index 0000000..dc5ff84
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.SourceRange;
+
+/**
+ * Element info for ISourceReference elements.
+ */
+/* package */ class SourceRefElementInfo extends JavaElementInfo {
+	protected int sourceRangeStart, sourceRangeEnd;
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getDeclarationSourceEnd()
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getDeclarationSourceEnd()
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getDeclarationSourceEnd()
+ */
+public int getDeclarationSourceEnd() {
+	return this.sourceRangeEnd;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getDeclarationSourceStart()
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceMethod#getDeclarationSourceStart()
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceField#getDeclarationSourceStart()
+ */
+public int getDeclarationSourceStart() {
+	return this.sourceRangeStart;
+}
+protected ISourceRange getSourceRange() {
+	return new SourceRange(this.sourceRangeStart, this.sourceRangeEnd - this.sourceRangeStart + 1);
+}
+protected void setSourceRangeEnd(int end) {
+	this.sourceRangeEnd = end;
+}
+protected void setSourceRangeStart(int start) {
+	this.sourceRangeStart = start;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
new file mode 100644
index 0000000..98263ec
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
@@ -0,0 +1,884 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.codeassist.CompletionEngine;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * Handle for a source type. Info object is a SourceTypeElementInfo.
+ *
+ * Note: Parent is either an IClassFile, an ICompilationUnit or an IType.
+ *
+ * @see IType
+ */
+
+public class SourceType extends NamedMember implements IType {
+
+/*
+ * A count to uniquely identify this element within the context of the enclosing type.
+ * Currently this is computed and used only for anonymous types.
+ */
+public int localOccurrenceCount = 1;
+
+protected SourceType(JavaElement parent, String name) {
+	super(parent, name);
+}
+protected void closing(Object info) throws JavaModelException {
+	super.closing(info);
+	SourceTypeElementInfo elementInfo = (SourceTypeElementInfo) info;
+	ITypeParameter[] typeParameters = elementInfo.typeParameters;
+	for (int i = 0, length = typeParameters.length; i < length; i++) {
+		((TypeParameter) typeParameters[i]).close();
+	}
+}
+/**
+ * @see IType
+ * @deprecated
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see IType
+ * @deprecated
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), owner);
+
+}
+/**
+ * @see IType
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see IType
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/**
+ * @see IType
+ */
+public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, owner, null);
+}
+/**
+ * @see IType
+ */
+public void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+
+	JavaProject project = (JavaProject) getJavaProject();
+	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
+	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
+
+	String source = getCompilationUnit().getSource();
+	if (source != null && insertion > -1 && insertion < source.length()) {
+
+		char[] prefix = CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[]{'{'});
+		char[] suffix = CharOperation.concat(new char[]{'}'}, source.substring(insertion).toCharArray());
+		char[] fakeSource = CharOperation.concat(prefix, snippet, suffix);
+
+		BasicCompilationUnit cu =
+			new BasicCompilationUnit(
+				fakeSource,
+				null,
+				getElementName(),
+				getParent());
+
+		engine.complete(cu, prefix.length + position, prefix.length, null/*extended context isn't computed*/);
+	} else {
+		engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+	}
+	if (NameLookup.VERBOSE) {
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
+/**
+ * @see IType
+ */
+public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CreateFieldOperation op = new CreateFieldOperation(this, contents, force);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return (IField) op.getResultElements()[0];
+}
+/**
+ * @see IType
+ */
+public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException {
+	CreateInitializerOperation op = new CreateInitializerOperation(this, contents);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return (IInitializer) op.getResultElements()[0];
+}
+/**
+ * @see IType
+ */
+public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CreateMethodOperation op = new CreateMethodOperation(this, contents, force);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return (IMethod) op.getResultElements()[0];
+}
+/**
+ * @see IType
+ */
+public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException {
+	CreateTypeOperation op = new CreateTypeOperation(this, contents, force);
+	if (sibling != null) {
+		op.createBefore(sibling);
+	}
+	op.runOperation(monitor);
+	return (IType) op.getResultElements()[0];
+}
+public boolean equals(Object o) {
+	if (!(o instanceof SourceType)) return false;
+	return super.equals(o);
+}
+/*
+ * @see IType
+ */
+public IMethod[] findMethods(IMethod method) {
+	try {
+		return findMethods(method, getMethods());
+	} catch (JavaModelException e) {
+		// if type doesn't exist, no matching method can exist
+		return null;
+	}
+}
+public IAnnotation[] getAnnotations() throws JavaModelException {
+	AnnotatableInfo info = (AnnotatableInfo) getElementInfo();
+	return info.annotations;
+}
+public IJavaElement[] getChildrenForCategory(String category) throws JavaModelException {
+	IJavaElement[] children = getChildren();
+	int length = children.length;
+	if (length == 0) return NO_ELEMENTS;
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	HashMap categories = info.getCategories();
+	if (categories == null) return NO_ELEMENTS;
+	IJavaElement[] result = new IJavaElement[length];
+	int index = 0;
+	for (int i = 0; i < length; i++) {
+		IJavaElement child = children[i];
+		String[] elementCategories = (String[]) categories.get(child);
+		if (elementCategories != null)
+			for (int j = 0, length2 = elementCategories.length; j < length2; j++) {
+				if (elementCategories[j].equals(category))
+					result[index++] = child;
+			}
+	}
+	if (index == 0) return NO_ELEMENTS;
+	if (index < length)
+		System.arraycopy(result, 0, result = new IJavaElement[index], 0, index);
+	return result;
+}
+/**
+ * @see IMember
+ */
+public IType getDeclaringType() {
+	IJavaElement parentElement = getParent();
+	while (parentElement != null) {
+		if (parentElement.getElementType() == IJavaElement.TYPE) {
+			return (IType) parentElement;
+		} else
+			if (parentElement instanceof IMember) {
+				parentElement = parentElement.getParent();
+			} else {
+				return null;
+			}
+	}
+	return null;
+}
+/**
+ * @see IJavaElement
+ */
+public int getElementType() {
+	return TYPE;
+}
+/**
+ * @see IType#getField
+ */
+public IField getField(String fieldName) {
+	return new SourceField(this, fieldName);
+}
+/**
+ * @see IType
+ */
+public IField[] getFields() throws JavaModelException {
+	ArrayList list = getChildrenOfType(FIELD);
+	IField[] array= new IField[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IType#getFullyQualifiedName()
+ */
+public String getFullyQualifiedName() {
+	return this.getFullyQualifiedName('$');
+}
+/**
+ * @see IType#getFullyQualifiedName(char)
+ */
+public String getFullyQualifiedName(char enclosingTypeSeparator) {
+	try {
+		return getFullyQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/);
+	} catch (JavaModelException e) {
+		// exception thrown only when showing parameters
+		return null;
+	}
+}
+/*
+ * @see IType#getFullyQualifiedParameterizedName()
+ */
+public String getFullyQualifiedParameterizedName() throws JavaModelException {
+	return getFullyQualifiedName('.', true/*show parameters*/);
+}
+/*
+ * For source types, the occurrence count is the one computed in the context of the immediately enclosing type.
+ *
+ */
+protected String getOccurrenceCountSignature() {
+	return Integer.toString(this.localOccurrenceCount);
+}
+/*
+ * @see JavaElement
+ */
+public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) {
+	switch (token.charAt(0)) {
+		case JEM_COUNT:
+			return getHandleUpdatingCountFromMemento(memento, workingCopyOwner);
+		case JEM_FIELD:
+			if (!memento.hasMoreTokens()) return this;
+			String fieldName = memento.nextToken();
+			JavaElement field = (JavaElement)getField(fieldName);
+			return field.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_INITIALIZER:
+			if (!memento.hasMoreTokens()) return this;
+			String count = memento.nextToken();
+			JavaElement initializer = (JavaElement)getInitializer(Integer.parseInt(count));
+			return initializer.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_METHOD:
+			if (!memento.hasMoreTokens()) return this;
+			String selector = memento.nextToken();
+			ArrayList params = new ArrayList();
+			nextParam: while (memento.hasMoreTokens()) {
+				token = memento.nextToken();
+				switch (token.charAt(0)) {
+					case JEM_TYPE:
+					case JEM_TYPE_PARAMETER:
+					case JEM_ANNOTATION:
+						break nextParam;
+					case JEM_METHOD:
+						if (!memento.hasMoreTokens()) return this;
+						String param = memento.nextToken();
+						StringBuffer buffer = new StringBuffer();
+						while (param.length() == 1 && Signature.C_ARRAY == param.charAt(0)) { // backward compatible with 3.0 mementos
+							buffer.append(Signature.C_ARRAY);
+							if (!memento.hasMoreTokens()) return this;
+							param = memento.nextToken();
+						}
+						params.add(buffer.toString() + param);
+						break;
+					default:
+						break nextParam;
+				}
+			}
+			String[] parameters = new String[params.size()];
+			params.toArray(parameters);
+			JavaElement method = (JavaElement)getMethod(selector, parameters);
+			switch (token.charAt(0)) {
+				case JEM_TYPE:
+				case JEM_TYPE_PARAMETER:
+				case JEM_LOCALVARIABLE:
+				case JEM_ANNOTATION:
+					return method.getHandleFromMemento(token, memento, workingCopyOwner);
+				default:
+					return method;
+			}
+		case JEM_TYPE:
+			String typeName;
+			if (memento.hasMoreTokens()) {
+				typeName = memento.nextToken();
+				char firstChar = typeName.charAt(0);
+				if (firstChar == JEM_FIELD || firstChar == JEM_INITIALIZER || firstChar == JEM_METHOD || firstChar == JEM_TYPE || firstChar == JEM_COUNT) {
+					token = typeName;
+					typeName = ""; //$NON-NLS-1$
+				} else {
+					token = null;
+				}
+			} else {
+				typeName = ""; //$NON-NLS-1$
+				token = null;
+			}
+			JavaElement type = (JavaElement)getType(typeName);
+			if (token == null) {
+				return type.getHandleFromMemento(memento, workingCopyOwner);
+			} else {
+				return type.getHandleFromMemento(token, memento, workingCopyOwner);
+			}
+		case JEM_TYPE_PARAMETER:
+			if (!memento.hasMoreTokens()) return this;
+			String typeParameterName = memento.nextToken();
+			JavaElement typeParameter = new TypeParameter(this, typeParameterName);
+			return typeParameter.getHandleFromMemento(memento, workingCopyOwner);
+		case JEM_ANNOTATION:
+			if (!memento.hasMoreTokens()) return this;
+			String annotationName = memento.nextToken();
+			JavaElement annotation = new Annotation(this, annotationName);
+			return annotation.getHandleFromMemento(memento, workingCopyOwner);
+	}
+	return null;
+}
+/**
+ * @see IType
+ */
+public IInitializer getInitializer(int count) {
+	return new Initializer(this, count);
+}
+/**
+ * @see IType
+ */
+public IInitializer[] getInitializers() throws JavaModelException {
+	ArrayList list = getChildrenOfType(INITIALIZER);
+	IInitializer[] array= new IInitializer[list.size()];
+	list.toArray(array);
+	return array;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
+/**
+ * @see IType#getMethod
+ */
+public IMethod getMethod(String selector, String[] parameterTypeSignatures) {
+	return new SourceMethod(this, selector, parameterTypeSignatures);
+}
+/**
+ * @see IType
+ */
+public IMethod[] getMethods() throws JavaModelException {
+	ArrayList list = getChildrenOfType(METHOD);
+	IMethod[] array= new IMethod[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IType
+ */
+public IPackageFragment getPackageFragment() {
+	IJavaElement parentElement = this.parent;
+	while (parentElement != null) {
+		if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+			return (IPackageFragment)parentElement;
+		}
+		else {
+			parentElement = parentElement.getParent();
+		}
+	}
+	Assert.isTrue(false);  // should not happen
+	return null;
+}
+/*
+ * @see JavaElement#getPrimaryElement(boolean)
+ */
+public IJavaElement getPrimaryElement(boolean checkOwner) {
+	if (checkOwner) {
+		CompilationUnit cu = (CompilationUnit)getAncestor(COMPILATION_UNIT);
+		if (cu.isPrimary()) return this;
+	}
+	IJavaElement primaryParent = this.parent.getPrimaryElement(false);
+	switch (primaryParent.getElementType()) {
+		case IJavaElement.COMPILATION_UNIT:
+			return ((ICompilationUnit)primaryParent).getType(this.name);
+		case IJavaElement.TYPE:
+			return ((IType)primaryParent).getType(this.name);
+		case IJavaElement.FIELD:
+		case IJavaElement.INITIALIZER:
+		case IJavaElement.METHOD:
+			return ((IMember)primaryParent).getType(this.name, this.occurrenceCount);
+	}
+	return this;
+}
+/**
+ * @see IType
+ */
+public String getSuperclassName() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	char[] superclassName= info.getSuperclassName();
+	if (superclassName == null) {
+		return null;
+	}
+	return new String(superclassName);
+}
+
+/**
+ * @see IType#getSuperclassTypeSignature()
+ * @since 3.0
+ */
+public String getSuperclassTypeSignature() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	char[] superclassName= info.getSuperclassName();
+	if (superclassName == null) {
+		return null;
+	}
+	return new String(Signature.createTypeSignature(superclassName, false));
+}
+
+/**
+ * @see IType
+ */
+public String[] getSuperInterfaceNames() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	char[][] names= info.getInterfaceNames();
+	return CharOperation.toStrings(names);
+}
+
+/**
+ * @see IType#getSuperInterfaceTypeSignatures()
+ * @since 3.0
+ */
+public String[] getSuperInterfaceTypeSignatures() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	char[][] names= info.getInterfaceNames();
+	if (names == null) {
+		return CharOperation.NO_STRINGS;
+	}
+	String[] strings= new String[names.length];
+	for (int i= 0; i < names.length; i++) {
+		strings[i]= new String(Signature.createTypeSignature(names[i], false));
+	}
+	return strings;
+}
+
+public ITypeParameter[] getTypeParameters() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	return info.typeParameters;
+}
+
+/**
+ * @see IType#getTypeParameterSignatures()
+ * @since 3.0
+ */
+public String[] getTypeParameterSignatures() throws JavaModelException {
+	ITypeParameter[] typeParameters = getTypeParameters();
+	int length = typeParameters.length;
+	String[] typeParameterSignatures = new String[length];
+	for (int i = 0; i < length; i++) {
+		TypeParameter typeParameter = (TypeParameter) typeParameters[i];
+		TypeParameterElementInfo info = (TypeParameterElementInfo) typeParameter.getElementInfo();
+		char[][] bounds = info.bounds;
+		if (bounds == null) {
+			typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameter.getElementName(), CharOperation.NO_STRINGS);
+		} else {
+			int boundsLength = bounds.length;
+			char[][] boundSignatures = new char[boundsLength][];
+			for (int j = 0; j < boundsLength; j++) {
+				boundSignatures[j] = Signature.createCharArrayTypeSignature(bounds[j], false);
+			}
+			typeParameterSignatures[i] = new String(Signature.createTypeParameterSignature(typeParameter.getElementName().toCharArray(), boundSignatures));
+		}
+	}
+	return typeParameterSignatures;
+}
+
+/**
+ * @see IType
+ */
+public IType getType(String typeName) {
+	return new SourceType(this, typeName);
+}
+public ITypeParameter getTypeParameter(String typeParameterName) {
+	return new TypeParameter(this, typeParameterName);
+}
+/**
+ * @see IType#getTypeQualifiedName()
+ */
+public String getTypeQualifiedName() {
+	return this.getTypeQualifiedName('$');
+}
+/**
+ * @see IType#getTypeQualifiedName(char)
+ */
+public String getTypeQualifiedName(char enclosingTypeSeparator) {
+	try {
+		return getTypeQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/);
+	} catch (JavaModelException e) {
+		// exception thrown only when showing parameters
+		return null;
+	}
+}
+
+/**
+ * @see IType
+ */
+public IType[] getTypes() throws JavaModelException {
+	ArrayList list= getChildrenOfType(TYPE);
+	IType[] array= new IType[list.size()];
+	list.toArray(array);
+	return array;
+}
+/**
+ * @see IType#isAnonymous()
+ */
+public boolean isAnonymous() {
+	return this.name.length() == 0;
+}
+
+/**
+ * @see IType
+ */
+public boolean isClass() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.CLASS_DECL;
+}
+
+/**
+ * @see IType#isEnum()
+ * @since 3.0
+ */
+public boolean isEnum() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ENUM_DECL;
+}
+
+/**
+ * @see IType
+ */
+public boolean isInterface() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	switch (TypeDeclaration.kind(info.getModifiers())) {
+		case TypeDeclaration.INTERFACE_DECL:
+		case TypeDeclaration.ANNOTATION_TYPE_DECL: // annotation is interface too
+			return true;
+	}
+	return false;
+}
+
+/**
+ * @see IType#isAnnotation()
+ * @since 3.0
+ */
+public boolean isAnnotation() throws JavaModelException {
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ANNOTATION_TYPE_DECL;
+}
+
+/**
+ * @see IType#isLocal()
+ */
+public boolean isLocal() {
+	switch (this.parent.getElementType()) {
+		case IJavaElement.METHOD:
+		case IJavaElement.INITIALIZER:
+		case IJavaElement.FIELD:
+			return true;
+		default:
+			return false;
+	}
+}
+/**
+ * @see IType#isMember()
+ */
+public boolean isMember() {
+	return getDeclaringType() != null;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+/**
+ * @see IType
+ */
+public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException {
+	return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/**
+ * NOTE: This method is not part of the API has it is not clear clients would easily use it: they would need to
+ * first make sure all working copies for the given owner exist before calling it. This is especially har at startup
+ * time.
+ * In case clients want this API, here is how it should be specified:
+ * <p>
+ * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
+ * be stored using ITypeHierachy#store(OutputStream). A compilation unit of a
+ * loaded type has the given owner if such a working copy exists, otherwise the type's
+ * compilation unit is a primary compilation unit.
+ *
+ * Only hierarchies originally created by the following methods can be loaded:
+ * <ul>
+ * <li>IType#newSupertypeHierarchy(IProgressMonitor)</li>
+ * <li>IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(IJavaProject, IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(IProgressMonitor)</li>
+ * <li>IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)</li>
+ * </u>
+ *
+ * @param input stream where hierarchy will be read
+ * @param monitor the given progress monitor
+ * @return the stored hierarchy
+ * @exception JavaModelException if the hierarchy could not be restored, reasons include:
+ *      - type is not the focus of the hierarchy or
+ *		- unable to read the input stream (wrong format, IOException during reading, ...)
+ * @see ITypeHierarchy#store(java.io.OutputStream, IProgressMonitor)
+ * @since 3.0
+ */
+public ITypeHierarchy loadTypeHierachy(InputStream input, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	// TODO monitor should be passed to TypeHierarchy.load(...)
+	return TypeHierarchy.load(this, input, owner);
+}
+/**
+ * @see IType
+ */
+public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
+	return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor)
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	ICompilationUnit[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @param workingCopies the working copies that take precedence over their original compilation units
+ * @param monitor the given progress monitor
+ * @return a type hierarchy for this type containing this type and all of its supertypes
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ *
+ * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor)
+ * @deprecated
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	IWorkingCopy[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] copies;
+	if (workingCopies == null) {
+		copies = null;
+	} else {
+		int length = workingCopies.length;
+		System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
+	}
+	return newSupertypeHierarchy(copies, monitor);
+}
+/**
+ * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newSupertypeHierarchy(
+	WorkingCopyOwner owner,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @see IType
+ */
+public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException {
+	return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/**
+ * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+	if (project == null) {
+		throw new IllegalArgumentException(Messages.hierarchy_nullProject);
+	}
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	ICompilationUnit[] projectWCs = null;
+	if (workingCopies != null) {
+		int length = workingCopies.length;
+		projectWCs = new ICompilationUnit[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			ICompilationUnit wc = workingCopies[i];
+			if (project.equals(wc.getJavaProject())) {
+				projectWCs[index++] = wc;
+			}
+		}
+		if (index != length) {
+			System.arraycopy(projectWCs, 0, projectWCs = new ICompilationUnit[index], 0, index);
+		}
+	}
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(
+		this,
+		projectWCs,
+		project,
+		true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @see IType
+ */
+public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException {
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=228845, The new type hierarchy should consider changes in primary
+	// working copy. 
+	return newTypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
+}
+/*
+ * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(
+	ICompilationUnit[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+/**
+ * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor)
+ * @deprecated
+ */
+public ITypeHierarchy newTypeHierarchy(
+	IWorkingCopy[] workingCopies,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] copies;
+	if (workingCopies == null) {
+		copies = null;
+	} else {
+		int length = workingCopies.length;
+		System.arraycopy(workingCopies, 0, copies = new ICompilationUnit[length], 0, length);
+	}
+	return newTypeHierarchy(copies, monitor);
+}
+/**
+ * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor)
+ */
+public ITypeHierarchy newTypeHierarchy(
+	WorkingCopyOwner owner,
+	IProgressMonitor monitor)
+	throws JavaModelException {
+
+	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+	CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true);
+	op.runOperation(monitor);
+	return op.getResult();
+}
+public JavaElement resolved(Binding binding) {
+	ResolvedSourceType resolvedHandle = new ResolvedSourceType(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	resolvedHandle.localOccurrenceCount = this.localOccurrenceCount;
+	return resolvedHandle;
+}
+/**
+ * @private Debugging purposes
+ */
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+	buffer.append(tabString(tab));
+	if (info == null) {
+		String elementName = getElementName();
+		if (elementName.length() == 0) {
+			buffer.append("<anonymous #"); //$NON-NLS-1$
+			buffer.append(this.occurrenceCount);
+			buffer.append(">"); //$NON-NLS-1$
+		} else {
+			toStringName(buffer);
+		}
+		buffer.append(" (not open)"); //$NON-NLS-1$
+	} else if (info == NO_INFO) {
+		String elementName = getElementName();
+		if (elementName.length() == 0) {
+			buffer.append("<anonymous #"); //$NON-NLS-1$
+			buffer.append(this.occurrenceCount);
+			buffer.append(">"); //$NON-NLS-1$
+		} else {
+			toStringName(buffer);
+		}
+	} else {
+		try {
+			if (isEnum()) {
+				buffer.append("enum "); //$NON-NLS-1$
+			} else if (isAnnotation()) {
+				buffer.append("@interface "); //$NON-NLS-1$
+			} else if (isInterface()) {
+				buffer.append("interface "); //$NON-NLS-1$
+			} else {
+				buffer.append("class "); //$NON-NLS-1$
+			}
+			String elementName = getElementName();
+			if (elementName.length() == 0) {
+				buffer.append("<anonymous #"); //$NON-NLS-1$
+				buffer.append(this.occurrenceCount);
+				buffer.append(">"); //$NON-NLS-1$
+			} else {
+				toStringName(buffer);
+			}
+		} catch (JavaModelException e) {
+			buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
new file mode 100644
index 0000000..2793a18
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.util.HashMap;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ISourceField;
+import org.eclipse.jdt.internal.compiler.env.ISourceImport;
+import org.eclipse.jdt.internal.compiler.env.ISourceMethod;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+
+/**
+ * Element info for an IType element that originated from source.
+ */
+public class SourceTypeElementInfo extends AnnotatableInfo implements ISourceType {
+
+	protected static final ISourceImport[] NO_IMPORTS = new ISourceImport[0];
+	protected static final InitializerElementInfo[] NO_INITIALIZERS = new InitializerElementInfo[0];
+	protected static final SourceField[] NO_FIELDS = new SourceField[0];
+	protected static final SourceMethod[] NO_METHODS = new SourceMethod[0];
+	protected static final SourceType[] NO_TYPES = new SourceType[0];
+
+	protected IJavaElement[] children = JavaElement.NO_ELEMENTS;
+	
+	/**
+	 * The name of the superclass for this type. This name
+	 * is fully qualified for binary types and is NOT
+	 * fully qualified for source types.
+	 */
+	protected char[] superclassName;
+
+	/**
+	 * The names of the interfaces this type implements or
+	 * extends. These names are fully qualified in the case
+	 * of a binary type, and are NOT fully qualified in the
+	 * case of a source type
+	 */
+	protected char[][] superInterfaceNames;
+
+	/**
+	 * Backpointer to my type handle - useful for translation
+	 * from info to handle.
+	 */
+	protected IType handle = null;
+
+	/*
+	 * The type parameters of this source type. Empty if none.
+	 */
+	protected ITypeParameter[] typeParameters = TypeParameter.NO_TYPE_PARAMETERS;
+
+	/*
+	 * A map from an IJavaElement (this type or a child of this type) to a String[] (the categories of this element)
+	 */
+	protected HashMap categories;
+
+protected void addCategories(IJavaElement element, char[][] elementCategories) {
+	if (elementCategories == null) return;
+	if (this.categories == null)
+		this.categories = new HashMap();
+	this.categories.put(element, CharOperation.toStrings(elementCategories));
+}
+
+/*
+ * Return a map from an IJavaElement (this type or a child of this type) to a String[] (the categories of this element)
+ */
+public HashMap getCategories() {
+	return this.categories;
+}
+
+public IJavaElement[] getChildren() {
+	return this.children;
+}
+
+/**
+ * Returns the ISourceType that is the enclosing type for this
+ * type, or <code>null</code> if this type is a top level type.
+ */
+public ISourceType getEnclosingType() {
+	IJavaElement parent= this.handle.getParent();
+	if (parent != null && parent.getElementType() == IJavaElement.TYPE) {
+		try {
+			return (ISourceType)((JavaElement)parent).getElementInfo();
+		} catch (JavaModelException e) {
+			return null;
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * @see ISourceType
+ */
+public ISourceField[] getFields() {
+	SourceField[] fieldHandles = getFieldHandles();
+	int length = fieldHandles.length;
+	ISourceField[] fields = new ISourceField[length];
+	for (int i = 0; i < length; i++) {
+		try {
+			ISourceField field = (ISourceField) fieldHandles[i].getElementInfo();
+			fields[i] = field;
+		} catch (JavaModelException e) {
+			// ignore
+		}
+	}
+	return fields;
+}
+public SourceField[] getFieldHandles() {
+	int length = this.children.length;
+	if (length == 0) return NO_FIELDS;
+	SourceField[] fields = new SourceField[length];
+	int fieldIndex = 0;
+	for (int i = 0; i < length; i++) {
+		IJavaElement child = this.children[i];
+		if (child instanceof SourceField)
+			fields[fieldIndex++] = (SourceField) child;
+	}
+	if (fieldIndex == 0) return NO_FIELDS;
+	if (fieldIndex < length)
+		System.arraycopy(fields, 0, fields = new SourceField[fieldIndex], 0, fieldIndex);
+	return fields;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.handle.getPath().toString().toCharArray();
+}
+/**
+ * Returns the handle for this type info
+ */
+public IType getHandle() {
+	return this.handle;
+}
+/*
+ * Returns the InitializerElementInfos for this type.
+ * Returns an empty array if none.
+ */
+public InitializerElementInfo[] getInitializers() {
+	int length = this.children.length;
+	if (length == 0) return NO_INITIALIZERS;
+	InitializerElementInfo[] initializers = new InitializerElementInfo[length];
+	int initializerIndex = 0;
+	for (int i = 0; i < length; i++) {
+		IJavaElement child = this.children[i];
+		if (child instanceof Initializer) {
+			try {
+				InitializerElementInfo initializer = (InitializerElementInfo)((Initializer)child).getElementInfo();
+				initializers[initializerIndex++] = initializer;
+			} catch (JavaModelException e) {
+				// ignore
+			}
+		}
+	}
+	if (initializerIndex == 0) return NO_INITIALIZERS;
+	System.arraycopy(initializers, 0, initializers = new InitializerElementInfo[initializerIndex], 0, initializerIndex);
+	return initializers;
+}
+/**
+ * @see ISourceType
+ */
+public char[][] getInterfaceNames() {
+	if (this.handle.getElementName().length() == 0) { // if anonymous type
+		return null;
+	}
+	return this.superInterfaceNames;
+}
+
+/**
+ * @see ISourceType
+ */
+public ISourceType[] getMemberTypes() {
+	SourceType[] memberTypeHandles = getMemberTypeHandles();
+	int length = memberTypeHandles.length;
+	ISourceType[] memberTypes = new ISourceType[length];
+	for (int i = 0; i < length; i++) {
+		try {
+			ISourceType type = (ISourceType) memberTypeHandles[i].getElementInfo();
+			memberTypes[i] = type;
+		} catch (JavaModelException e) {
+			// ignore
+		}
+	}
+	return memberTypes;
+}
+public SourceType[] getMemberTypeHandles() {
+	int length = this.children.length;
+	if (length == 0) return NO_TYPES;
+	SourceType[] memberTypes = new SourceType[length];
+	int typeIndex = 0;
+	for (int i = 0; i < length; i++) {
+		IJavaElement child = this.children[i];
+		if (child instanceof SourceType)
+			memberTypes[typeIndex++] = (SourceType)child;
+	}
+	if (typeIndex == 0) return NO_TYPES;
+	if (typeIndex < length)
+		System.arraycopy(memberTypes, 0, memberTypes = new SourceType[typeIndex], 0, typeIndex);
+	return memberTypes;
+}
+/**
+ * @see ISourceType
+ */
+public ISourceMethod[] getMethods() {
+	SourceMethod[] methodHandles = getMethodHandles();
+	int length = methodHandles.length;
+	ISourceMethod[] methods = new ISourceMethod[length];
+	int methodIndex = 0;
+	for (int i = 0; i < length; i++) {
+		try {
+			ISourceMethod method = (ISourceMethod) methodHandles[i].getElementInfo();
+			methods[methodIndex++] = method;
+		} catch (JavaModelException e) {
+			// ignore
+		}
+	}
+	return methods;
+}
+public SourceMethod[] getMethodHandles() {
+	int length = this.children.length;
+	if (length == 0) return NO_METHODS;
+	SourceMethod[] methods = new SourceMethod[length];
+	int methodIndex = 0;
+	for (int i = 0; i < length; i++) {
+		IJavaElement child = this.children[i];
+		if (child instanceof SourceMethod)
+			methods[methodIndex++] = (SourceMethod) child;
+	}
+	if (methodIndex == 0) return NO_METHODS;
+	if (methodIndex < length)
+		System.arraycopy(methods, 0, methods = new SourceMethod[methodIndex], 0, methodIndex);
+	return methods;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.ISourceType#getName()
+ */
+public char[] getName() {
+	return this.handle.getElementName().toCharArray();
+}
+/**
+ * @see ISourceType
+ */
+public char[] getSuperclassName() {
+	if (this.handle.getElementName().length() == 0) { // if anonymous type
+		char[][] interfaceNames = this.superInterfaceNames;
+		if (interfaceNames != null && interfaceNames.length > 0) {
+			return interfaceNames[0];
+		}
+	}
+	return this.superclassName;
+}
+public char[][][] getTypeParameterBounds() {
+	int length = this.typeParameters.length;
+	char[][][] typeParameterBounds = new char[length][][];
+	for (int i = 0; i < length; i++) {
+		try {
+			TypeParameterElementInfo info = (TypeParameterElementInfo) ((JavaElement)this.typeParameters[i]).getElementInfo();
+			typeParameterBounds[i] = info.bounds;
+		} catch (JavaModelException e) {
+			// type parameter does not exist: ignore
+		}
+	}
+	return typeParameterBounds;
+}
+public char[][] getTypeParameterNames() {
+	int length = this.typeParameters.length;
+	if (length == 0) return CharOperation.NO_CHAR_CHAR;
+	char[][] typeParameterNames = new char[length][];
+	for (int i = 0; i < length; i++) {
+		typeParameterNames[i] = this.typeParameters[i].getElementName().toCharArray();
+	}
+	return typeParameterNames;
+}
+/**
+ * @see ISourceType
+ */
+public boolean isBinaryType() {
+	return false;
+}
+/*
+ * Returns whether the source type is an anonymous type of a member type.
+ */
+public boolean isAnonymousMember() {
+	return false;
+}
+/**
+ * Sets the handle for this type info
+ */
+protected void setHandle(IType handle) {
+	this.handle = handle;
+}
+/**
+ * Sets the (unqualified) name of this type's superclass
+ */
+protected void setSuperclassName(char[] superclassName) {
+	this.superclassName = superclassName;
+}
+/**
+ * Sets the (unqualified) names of the interfaces this type implements or extends
+ */
+protected void setSuperInterfaceNames(char[][] superInterfaceNames) {
+	this.superInterfaceNames = superInterfaceNames;
+}
+public String toString() {
+	return "Info for " + this.handle.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
new file mode 100644
index 0000000..dade34b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class TypeParameter extends SourceRefElement implements ITypeParameter {
+
+	static final ITypeParameter[] NO_TYPE_PARAMETERS = new ITypeParameter[0];
+
+	protected String name;
+
+	public TypeParameter(JavaElement parent, String name) {
+		super(parent);
+		this.name = name;
+	}
+
+	public boolean equals(Object o) {
+		if (!(o instanceof TypeParameter)) return false;
+		return super.equals(o);
+	}
+
+	public String[] getBounds() throws JavaModelException {
+		TypeParameterElementInfo info = (TypeParameterElementInfo) getElementInfo();
+		return CharOperation.toStrings(info.bounds);
+	}
+	
+	public String[] getBoundsSignatures() throws JavaModelException {
+		
+		String[] boundSignatures = null;
+		TypeParameterElementInfo info = (TypeParameterElementInfo) this.getElementInfo();
+		
+		// For a binary type or method, the signature is already available from the .class file.
+		// No need to construct again
+		if (this.parent instanceof BinaryMember) {
+			char[][] boundsSignatures = info.boundsSignatures;
+			if (boundsSignatures == null || boundsSignatures.length == 0) {
+				return CharOperation.NO_STRINGS;	
+			}
+			return CharOperation.toStrings(info.boundsSignatures);
+		}
+		
+		char[][] bounds = info.bounds;
+		if (bounds == null || bounds.length == 0) {
+			return CharOperation.NO_STRINGS;
+		}
+	
+		int boundsLength = bounds.length;
+		boundSignatures = new String[boundsLength];
+		for (int i = 0; i < boundsLength; i++) {
+			boundSignatures[i] = new String(Signature.createCharArrayTypeSignature(bounds[i], false));
+		}
+		return boundSignatures;
+	}
+	
+	public IMember getDeclaringMember() {
+		return (IMember) getParent();
+	}
+
+	public String getElementName() {
+		return this.name;
+	}
+
+	public int getElementType() {
+		return TYPE_PARAMETER;
+	}
+
+	protected char getHandleMementoDelimiter() {
+		return JavaElement.JEM_TYPE_PARAMETER;
+	}
+
+	public ISourceRange getNameRange() throws JavaModelException {
+		SourceMapper mapper= getSourceMapper();
+		if (mapper != null) {
+			// ensure the class file's buffer is open so that source ranges are computed
+			ClassFile classFile = (ClassFile)getClassFile();
+			if (classFile != null) {
+				classFile.getBuffer();
+				return mapper.getNameRange(this);
+			}
+		}
+		TypeParameterElementInfo info = (TypeParameterElementInfo) getElementInfo();
+		return new SourceRange(info.nameStart, info.nameEnd - info.nameStart + 1);
+	}
+
+	/*
+	 * @see ISourceReference
+	 */
+	public ISourceRange getSourceRange() throws JavaModelException {
+		SourceMapper mapper= getSourceMapper();
+		if (mapper != null) {
+			// ensure the class file's buffer is open so that source ranges are computed
+			ClassFile classFile = (ClassFile)getClassFile();
+			if (classFile != null) {
+				classFile.getBuffer();
+				return mapper.getSourceRange(this);
+			}
+		}
+		return super.getSourceRange();
+	}
+
+	public IClassFile getClassFile() {
+		return ((JavaElement)getParent()).getClassFile();
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 * @since 3.7
+	 */
+	public ITypeRoot getTypeRoot() {
+		return this.getDeclaringMember().getTypeRoot();
+	}
+
+	protected void toStringName(StringBuffer buffer) {
+		buffer.append('<');
+		buffer.append(getElementName());
+		buffer.append('>');
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java
new file mode 100644
index 0000000..401ba0f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+public class TypeParameterElementInfo extends SourceRefElementInfo {
+
+	/*
+	 * The start position of this type parameter's name in the its
+	 * openable's buffer.
+	 */
+	public int nameStart= -1;
+
+	/*
+	 * The last position of this type parameter name in the its
+	 * openable's buffer.
+	 */
+	public int nameEnd= -1;
+
+	/*
+	 * The bounds names of this type parameter.
+	 */
+	public char[][] bounds;
+	
+	/*
+	 * The bounds' signatures for this type parameter. 
+	 */
+	public char[][] boundsSignatures;
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
new file mode 100644
index 0000000..1c871ba
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IType;
+
+public final class TypeVector {
+	static int INITIAL_SIZE = 10;
+
+	public int size;
+	int maxSize;
+	IType[] elements;
+
+	public final static IType[] NoElements = new IType[0];
+
+public TypeVector() {
+	this.maxSize = INITIAL_SIZE;
+	this.size = 0;
+	this.elements = new IType[this.maxSize];
+}
+public TypeVector(IType[] types) {
+	this.size = types.length;
+	this.maxSize = this.size + 1; // when an element is added, it assumes that the length is > 0
+	this.elements = new IType[this.maxSize];
+	System.arraycopy(types, 0, this.elements, 0, this.size);
+}
+public TypeVector(IType type) {
+	this.maxSize = INITIAL_SIZE;
+	this.size = 1;
+	this.elements = new IType[this.maxSize];
+	this.elements[0] = type;
+}
+public void add(IType newElement) {
+	if (this.size == this.maxSize)	// knows that size starts <= maxSize
+		System.arraycopy(this.elements, 0, (this.elements = new IType[this.maxSize *= 2]), 0, this.size);
+	this.elements[this.size++] = newElement;
+}
+public void addAll(IType[] newElements) {
+	if (this.size + newElements.length >= this.maxSize) {
+		this.maxSize = this.size + newElements.length;	// assume no more elements will be added
+		System.arraycopy(this.elements, 0, (this.elements = new IType[this.maxSize]), 0, this.size);
+	}
+	System.arraycopy(newElements, 0, this.elements, this.size, newElements.length);
+	this.size += newElements.length;
+}
+public boolean contains(IType element) {
+	for (int i = this.size; --i >= 0;)
+		if (element.equals(this.elements[i]))
+			return true;
+	return false;
+}
+public TypeVector copy() {
+	TypeVector clone = new TypeVector();
+	int length = this.elements.length;
+	System.arraycopy(this.elements, 0, clone.elements = new IType[length], 0, length);
+	clone.size = this.size;
+	clone.maxSize = this.maxSize;
+	return clone;
+}
+public IType elementAt(int index) {
+	return this.elements[index];
+}
+public IType[] elements() {
+
+	// do not resize to 0 if empty since may add more elements later
+	if (this.size == 0) return NoElements;
+
+	if (this.size < this.maxSize) {
+		this.maxSize = this.size;
+		System.arraycopy(this.elements, 0, (this.elements = new IType[this.maxSize]), 0, this.size);
+	}
+	return this.elements;
+}
+public IType find(IType element) {
+	for (int i = this.size; --i >= 0;)
+		if (element == this.elements[i])
+			return this.elements[i];
+	return null;
+}
+public IType remove(IType element) {
+	// assumes only one occurrence of the element exists
+	for (int i = this.size; --i >= 0;)
+		if (element == this.elements[i]) {
+			// shift the remaining elements down one spot
+			System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i);
+			this.elements[this.size] = null;
+			return element;
+		}
+	return null;
+}
+public void removeAll() {
+	for (int i = this.size; --i >= 0;)
+		this.elements[i] = null;
+	this.size = 0;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer("["); //$NON-NLS-1$
+	for (int i = 0; i < this.size; i++) {
+		buffer.append("\n"); //$NON-NLS-1$
+		buffer.append(this.elements[i]);
+	}
+	buffer.append("\n]"); //$NON-NLS-1$
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
new file mode 100644
index 0000000..bd94a5f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Internal model element to represent a user library and code to serialize / deserialize.
+ */
+public class UserLibrary {
+
+	private static final String VERSION_ONE = "1"; //$NON-NLS-1$
+	private static final String CURRENT_VERSION= "2"; //$NON-NLS-1$
+
+	private static final String TAG_VERSION= "version"; //$NON-NLS-1$
+	private static final String TAG_USERLIBRARY= "userlibrary"; //$NON-NLS-1$
+	private static final String TAG_SOURCEATTACHMENT= "sourceattachment"; //$NON-NLS-1$
+	private static final String TAG_SOURCEATTACHMENTROOT= "sourceattachmentroot"; //$NON-NLS-1$
+	private static final String TAG_PATH= "path"; //$NON-NLS-1$
+	private static final String TAG_ARCHIVE= "archive"; //$NON-NLS-1$
+	private static final String TAG_SYSTEMLIBRARY= "systemlibrary"; //$NON-NLS-1$
+
+	private boolean isSystemLibrary;
+	private IClasspathEntry[] entries;
+
+	public UserLibrary(IClasspathEntry[] entries, boolean isSystemLibrary) {
+		Assert.isNotNull(entries);
+		this.entries= entries;
+		this.isSystemLibrary= isSystemLibrary;
+	}
+
+	public IClasspathEntry[] getEntries() {
+		return this.entries;
+	}
+
+	public boolean isSystemLibrary() {
+		return this.isSystemLibrary;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		if (obj != null && obj.getClass() == getClass()) {
+			UserLibrary other= (UserLibrary) obj;
+			if (this.entries.length == other.entries.length && this.isSystemLibrary == other.isSystemLibrary) {
+				for (int i= 0; i < this.entries.length; i++) {
+					if (!this.entries[i].equals(other.entries[i])) {
+						return false;
+					}
+				}
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		int hashCode= 0;
+		if (this.isSystemLibrary) {
+			hashCode++;
+		}
+		for (int i= 0; i < this.entries.length; i++) {
+			hashCode= hashCode * 17 + this.entries.hashCode();
+		}
+		return hashCode;
+	}
+
+	public static String serialize(IClasspathEntry[] entries, boolean isSystemLibrary) throws IOException {
+		ByteArrayOutputStream s = new ByteArrayOutputStream();
+		OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
+		XMLWriter xmlWriter = new XMLWriter(writer, null/*use the workspace line delimiter*/, true/*print XML version*/);
+
+		HashMap library = new HashMap();
+		library.put(TAG_VERSION, String.valueOf(CURRENT_VERSION));
+		library.put(TAG_SYSTEMLIBRARY, String.valueOf(isSystemLibrary));
+		xmlWriter.printTag(TAG_USERLIBRARY, library, true, true, false);
+
+		for (int i = 0, length = entries.length; i < length; ++i) {
+			ClasspathEntry cpEntry = (ClasspathEntry) entries[i];
+
+			HashMap archive = new HashMap();
+			archive.put(TAG_PATH, cpEntry.getPath().toPortableString());
+			IPath sourceAttach= cpEntry.getSourceAttachmentPath();
+			if (sourceAttach != null)
+				archive.put(TAG_SOURCEATTACHMENT, sourceAttach.toPortableString());
+			IPath sourceAttachRoot= cpEntry.getSourceAttachmentRootPath();
+			if (sourceAttachRoot != null)
+				archive.put(TAG_SOURCEATTACHMENTROOT, sourceAttachRoot.toPortableString());
+
+			boolean hasExtraAttributes = cpEntry.extraAttributes != null && cpEntry.extraAttributes.length != 0;
+			boolean hasRestrictions = cpEntry.getAccessRuleSet() != null; // access rule set is null if no access rules
+			xmlWriter.printTag(TAG_ARCHIVE, archive, true, true, !(hasExtraAttributes || hasRestrictions));
+
+			// write extra attributes if necessary
+			if (hasExtraAttributes) {
+				cpEntry.encodeExtraAttributes(xmlWriter, true, true);
+			}
+
+			// write extra attributes and restriction if necessary
+			if (hasRestrictions) {
+				cpEntry.encodeAccessRules(xmlWriter, true, true);
+			}
+
+			// write archive end tag if necessary
+			if (hasExtraAttributes || hasRestrictions) {
+				xmlWriter.endTag(TAG_ARCHIVE, true/*insert tab*/, true/*insert new line*/);
+			}
+		}
+		xmlWriter.endTag(TAG_USERLIBRARY, true/*insert tab*/, true/*insert new line*/);
+		writer.flush();
+		writer.close();
+		return s.toString("UTF8");//$NON-NLS-1$
+	}
+
+	public static UserLibrary createFromString(Reader reader) throws IOException {
+		Element cpElement;
+		try {
+			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
+		} catch (SAXException e) {
+			throw new IOException(Messages.file_badFormat);
+		} catch (ParserConfigurationException e) {
+			throw new IOException(Messages.file_badFormat);
+		} finally {
+			reader.close();
+		}
+
+		if (!cpElement.getNodeName().equalsIgnoreCase(TAG_USERLIBRARY)) {
+			throw new IOException(Messages.file_badFormat);
+		}
+		String version= cpElement.getAttribute(TAG_VERSION);
+		boolean isSystem= Boolean.valueOf(cpElement.getAttribute(TAG_SYSTEMLIBRARY)).booleanValue();
+
+		NodeList list= cpElement.getChildNodes();
+		int length = list.getLength();
+
+		ArrayList res= new ArrayList(length);
+		for (int i = 0; i < length; ++i) {
+			Node node = list.item(i);
+
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				Element element= (Element) node;
+				if (element.getNodeName().equals(TAG_ARCHIVE)) {
+					String pathString = element.getAttribute(TAG_PATH);
+					String sourceAttachString = element.hasAttribute(TAG_SOURCEATTACHMENT) ? element.getAttribute(TAG_SOURCEATTACHMENT) : null;
+					String sourceAttachRootString = element.hasAttribute(TAG_SOURCEATTACHMENTROOT) ? element.getAttribute(TAG_SOURCEATTACHMENTROOT) : null;
+					IPath entryPath = null; 
+					IPath sourceAttachPath = null;
+					IPath sourceAttachRootPath = null;
+					if (version.equals(VERSION_ONE)) {
+						entryPath = Path.fromOSString(pathString);
+						if (sourceAttachString != null) sourceAttachPath = Path.fromOSString(sourceAttachString);
+						if (sourceAttachRootString != null) sourceAttachRootPath = Path.fromOSString(sourceAttachRootString);
+					}
+					else {
+						entryPath = Path.fromPortableString(pathString);
+						if (sourceAttachString != null) sourceAttachPath = Path.fromPortableString(sourceAttachString);
+						if (sourceAttachRootString != null) sourceAttachRootPath = Path.fromPortableString(sourceAttachRootString);
+					}
+
+					NodeList children = element.getElementsByTagName("*"); //$NON-NLS-1$
+					boolean[] foundChildren = new boolean[children.getLength()];
+					NodeList attributeList = ClasspathEntry.getChildAttributes(ClasspathEntry.TAG_ATTRIBUTES, children, foundChildren);
+					IClasspathAttribute[] extraAttributes = ClasspathEntry.decodeExtraAttributes(attributeList);
+					attributeList = ClasspathEntry.getChildAttributes(ClasspathEntry.TAG_ACCESS_RULES, children, foundChildren);
+					IAccessRule[] accessRules = ClasspathEntry.decodeAccessRules(attributeList);
+					IClasspathEntry entry = JavaCore.newLibraryEntry(entryPath, sourceAttachPath, sourceAttachRootPath, accessRules, extraAttributes, false/*not exported*/);
+					res.add(entry);
+				}
+			}
+		}
+
+		IClasspathEntry[] entries= (IClasspathEntry[]) res.toArray(new IClasspathEntry[res.size()]);
+
+		return new UserLibrary(entries, isSystem);
+	}
+
+	public String toString() {
+		if (this.entries == null)
+			return "null"; //$NON-NLS-1$
+		StringBuffer buffer = new StringBuffer();
+		int length = this.entries.length;
+		for (int i=0; i<length; i++) {
+			buffer.append(this.entries[i].toString()+'\n');
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java
new file mode 100644
index 0000000..95ba66d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ *
+ */
+public class UserLibraryClasspathContainer implements IClasspathContainer {
+
+	private String name;
+
+	public UserLibraryClasspathContainer(String name) {
+		this.name = name;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IClasspathContainer#getClasspathEntries()
+	 */
+	public IClasspathEntry[] getClasspathEntries() {
+		UserLibrary library= getUserLibrary();
+		if (library != null) {
+			return library.getEntries();
+		}
+		return new IClasspathEntry[0];
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IClasspathContainer#getDescription()
+	 */
+	public String getDescription() {
+		return this.name;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IClasspathContainer#getKind()
+	 */
+	public int getKind() {
+		UserLibrary library= getUserLibrary();
+		if (library != null && library.isSystemLibrary()) {
+			return K_SYSTEM;
+		}
+		return K_APPLICATION;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IClasspathContainer#getPath()
+	 */
+	public IPath getPath() {
+		return new Path(JavaCore.USER_LIBRARY_CONTAINER_ID).append(this.name);
+	}
+
+	private UserLibrary getUserLibrary() {
+		UserLibrary userLibrary = JavaModelManager.getUserLibraryManager().getUserLibrary(this.name);
+		if (userLibrary == null && (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE)) {
+			verbose_no_user_library_found(this.name);
+		}
+		return userLibrary;
+	}
+
+	private void verbose_no_user_library_found(String userLibraryName) {
+		Util.verbose(
+			"UserLibrary INIT - FAILED (no user library found)\n" + //$NON-NLS-1$
+			"	userLibraryName: " + userLibraryName); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java
new file mode 100644
index 0000000..474077a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.ClasspathContainerInitializer;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ *
+ */
+public class UserLibraryClasspathContainerInitializer extends ClasspathContainerInitializer {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#canUpdateClasspathContainer(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
+	 */
+	public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
+		return isUserLibraryContainer(containerPath);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getComparisonID(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
+	 */
+	public Object getComparisonID(IPath containerPath, IJavaProject project) {
+		return containerPath;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#getDescription(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject)
+	 */
+	public String getDescription(IPath containerPath, IJavaProject project) {
+		if (isUserLibraryContainer(containerPath)) {
+			return containerPath.segment(1);
+		}
+		return super.getDescription(containerPath, project);
+	}
+
+	public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
+		if (isUserLibraryContainer(containerPath)) {
+			String userLibName = containerPath.segment(1);
+			UserLibrary userLibrary = JavaModelManager.getUserLibraryManager().getUserLibrary(userLibName);
+			if (userLibrary != null) {
+				UserLibraryClasspathContainer container = new UserLibraryClasspathContainer(userLibName);
+				JavaCore.setClasspathContainer(containerPath, new IJavaProject[] { project }, new IClasspathContainer[] { container }, null);
+			} else if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+				verbose_no_user_library_found(project, userLibName);
+			}
+		} else if (JavaModelManager.CP_RESOLVE_VERBOSE || JavaModelManager.CP_RESOLVE_VERBOSE_FAILURE) {
+			verbose_not_a_user_library(project, containerPath);
+		}
+	}
+
+	private boolean isUserLibraryContainer(IPath path) {
+		return path != null && path.segmentCount() == 2 && JavaCore.USER_LIBRARY_CONTAINER_ID.equals(path.segment(0));
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.ClasspathContainerInitializer#requestClasspathContainerUpdate(org.eclipse.core.runtime.IPath, org.eclipse.jdt.core.IJavaProject, org.eclipse.jdt.core.IClasspathContainer)
+	 */
+	public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException {
+		if (isUserLibraryContainer(containerPath)) {
+			String name = containerPath.segment(1);
+			if (containerSuggestion != null) {
+				JavaModelManager.getUserLibraryManager().setUserLibrary(name, containerSuggestion.getClasspathEntries(), containerSuggestion.getKind() == IClasspathContainer.K_SYSTEM);
+			} else {
+				JavaModelManager.getUserLibraryManager().removeUserLibrary(name);
+			}
+			// update of affected projects was done as a consequence of setUserLibrary() or removeUserLibrary()
+		}
+	}
+
+	private void verbose_no_user_library_found(IJavaProject project, String userLibraryName) {
+		Util.verbose(
+			"UserLibrary INIT - FAILED (no user library found)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	userLibraryName: " + userLibraryName); //$NON-NLS-1$
+	}
+
+	private void verbose_not_a_user_library(IJavaProject project, IPath containerPath) {
+		Util.verbose(
+			"UserLibrary INIT - FAILED (not a user library)\n" + //$NON-NLS-1$
+			"	project: " + project.getElementName() + '\n' + //$NON-NLS-1$
+			"	container path: " + containerPath); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java
new file mode 100644
index 0000000..bb0ec08
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Util;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ *
+ */
+public class UserLibraryManager {
+
+	public final static String CP_USERLIBRARY_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".userLibrary."; //$NON-NLS-1$
+
+	private Map userLibraries;
+
+	public UserLibraryManager() {
+		initialize();
+	}
+
+	/*
+	 * Gets the library for a given name or <code>null</code> if no such library exists.
+	 */
+	public synchronized UserLibrary getUserLibrary(String libName) {
+		return (UserLibrary) this.userLibraries.get(libName);
+	}
+
+	/*
+	 * Returns the names of all defined user libraries. The corresponding classpath container path
+	 * is the name appended to the CONTAINER_ID.
+	 */
+	public synchronized String[] getUserLibraryNames() {
+		Set set = this.userLibraries.keySet();
+		return (String[]) set.toArray(new String[set.size()]);
+	}
+
+	private void initialize() {
+		this.userLibraries = new HashMap();
+		IEclipsePreferences instancePreferences = JavaModelManager.getJavaModelManager().getInstancePreferences();
+		String[] propertyNames;
+		try {
+			propertyNames = instancePreferences.keys();
+		} catch (BackingStoreException e) {
+			Util.log(e, "Exception while initializing user libraries"); //$NON-NLS-1$
+			return;
+		}
+
+		boolean preferencesNeedFlush = false;
+		for (int i = 0, length = propertyNames.length; i < length; i++) {
+			String propertyName = propertyNames[i];
+			if (propertyName.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) {
+				String propertyValue = instancePreferences.get(propertyName, null);
+				if (propertyValue != null) {
+					String libName= propertyName.substring(CP_USERLIBRARY_PREFERENCES_PREFIX.length());
+					StringReader reader = new StringReader(propertyValue);
+					UserLibrary library;
+					try {
+						library = UserLibrary.createFromString(reader);
+					} catch (IOException e) {
+						Util.log(e, "Exception while initializing user library " + libName); //$NON-NLS-1$
+						instancePreferences.remove(propertyName);
+						preferencesNeedFlush = true;
+						continue;
+					} catch (ClasspathEntry.AssertionFailedException e) {
+						Util.log(e, "Exception while initializing user library " + libName); //$NON-NLS-1$
+						instancePreferences.remove(propertyName);
+						preferencesNeedFlush = true;
+						continue;
+					}
+					this.userLibraries.put(libName, library);
+				}
+			}
+		}
+		if (preferencesNeedFlush) {
+			try {
+				instancePreferences.flush();
+			} catch (BackingStoreException e) {
+				Util.log(e, "Exception while flusing instance preferences"); //$NON-NLS-1$
+			}
+		}
+	}
+
+	public void updateUserLibrary(String libName, String encodedUserLibrary) {
+		try {
+			// find affected projects
+			IPath containerPath = new Path(JavaCore.USER_LIBRARY_CONTAINER_ID).append(libName);
+			IJavaProject[] allJavaProjects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()).getJavaProjects();
+			ArrayList affectedProjects = new ArrayList();
+			for (int i= 0; i < allJavaProjects.length; i++) {
+				IJavaProject javaProject = allJavaProjects[i];
+				IClasspathEntry[] entries= javaProject.getRawClasspath();
+				for (int j= 0; j < entries.length; j++) {
+					IClasspathEntry entry = entries[j];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+						if (containerPath.equals(entry.getPath())) {
+							affectedProjects.add(javaProject);
+							break;
+						}
+					}
+				}
+			}
+
+			// decode user library
+			UserLibrary userLibrary = encodedUserLibrary == null ? null : UserLibrary.createFromString(new StringReader(encodedUserLibrary));
+
+			synchronized (this) {
+				// update user libraries map
+				if (userLibrary != null) {
+					this.userLibraries.put(libName, userLibrary);
+				} else {
+					this.userLibraries.remove(libName);
+				}
+			}
+
+			// update affected projects
+			int length = affectedProjects.size();
+			if (length == 0)
+				return;
+			IJavaProject[] projects = new IJavaProject[length];
+			affectedProjects.toArray(projects);
+			IClasspathContainer[] containers = new IClasspathContainer[length];
+			if (userLibrary != null) {
+				UserLibraryClasspathContainer container = new UserLibraryClasspathContainer(libName);
+				for (int i = 0; i < length; i++) {
+					containers[i] = container;
+				}
+			}
+			JavaCore.setClasspathContainer(containerPath, projects, containers, null);
+		} catch (IOException e) {
+			Util.log(e, "Exception while decoding user library '"+ libName +"'."); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (JavaModelException e) {
+			Util.log(e, "Exception while setting user library '"+ libName +"'."); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (ClasspathEntry.AssertionFailedException ase) {
+			Util.log(ase, "Exception while decoding user library '"+ libName +"'."); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		
+	}
+
+	public void removeUserLibrary(String libName)  {
+		synchronized (this.userLibraries) {
+			IEclipsePreferences instancePreferences = JavaModelManager.getJavaModelManager().getInstancePreferences();
+			String propertyName = CP_USERLIBRARY_PREFERENCES_PREFIX+libName;
+			instancePreferences.remove(propertyName);
+			try {
+				instancePreferences.flush();
+			} catch (BackingStoreException e) {
+				Util.log(e, "Exception while removing user library " + libName); //$NON-NLS-1$
+			}
+		}
+		// this.userLibraries was updated during the PreferenceChangeEvent (see preferenceChange(...))
+	}
+
+	public void setUserLibrary(String libName, IClasspathEntry[] entries, boolean isSystemLibrary)  {
+		synchronized (this.userLibraries) {
+			IEclipsePreferences instancePreferences = JavaModelManager.getJavaModelManager().getInstancePreferences();
+			String propertyName = CP_USERLIBRARY_PREFERENCES_PREFIX+libName;
+			try {
+				String propertyValue = UserLibrary.serialize(entries, isSystemLibrary);
+				instancePreferences.put(propertyName, propertyValue); // sends out a PreferenceChangeEvent (see preferenceChange(...))
+			} catch (IOException e) {
+				Util.log(e, "Exception while serializing user library " + libName); //$NON-NLS-1$
+				return;
+			}
+			try {
+				instancePreferences.flush();
+			} catch (BackingStoreException e) {
+				Util.log(e, "Exception while saving user library " + libName); //$NON-NLS-1$
+			}
+		}
+		// this.userLibraries was updated during the PreferenceChangeEvent (see preferenceChange(...))
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/VerboseElementCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/VerboseElementCache.java
new file mode 100644
index 0000000..84dd737
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/VerboseElementCache.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import java.text.NumberFormat;
+import java.util.Date;
+
+public class VerboseElementCache extends ElementCache {
+
+	private Object beingAdded;
+	private String name;
+
+	public VerboseElementCache(int size, String name) {
+		super(size);
+		this.name = name;
+	}
+
+	protected boolean makeSpace(int space) {
+		if (this.beingAdded == null) return super.makeSpace(space);
+		String fillingRatio = toStringFillingRation(this.name);
+		boolean result = super.makeSpace(space);
+		String newFillingRatio = toStringFillingRation(this.name);
+		if (!fillingRatio.equals(newFillingRatio)) {
+			System.out.println(Thread.currentThread() + " " + new Date(System.currentTimeMillis()).toString()); //$NON-NLS-1$
+			System.out.println(Thread.currentThread() + " MADE SPACE FOR " + fillingRatio + " (NOW " + NumberFormat.getInstance().format(fillingRatio()) + "% full)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			System.out.println(Thread.currentThread() + " WHILE OPENING "+ ((JavaElement) this.beingAdded).toStringWithAncestors());  //$NON-NLS-1$
+			System.out.println();
+		}
+		return result;
+	}
+
+	public Object put(Object key, Object value) {
+		try {
+			if (this.beingAdded == null)
+				this.beingAdded = key;
+			return super.put(key, value);
+		} finally {
+			if (key.equals(this.beingAdded))
+				this.beingAdded = null;
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
new file mode 100644
index 0000000..cc41dd8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+import java.io.Writer;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * @since 3.0
+ */
+class XMLWriter extends GenericXMLWriter {
+
+	public XMLWriter(Writer writer, IJavaProject project, boolean printXmlVersion) {
+		super(writer, Util.getLineSeparator((String) null, project), printXmlVersion);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java
new file mode 100644
index 0000000..2f314c8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+/**
+ * Exception thrown when an incremental builder cannot find a .class file.
+ * Its possible the type can no longer be found because it was renamed inside its existing
+ * source file.
+ */
+public class AbortIncrementalBuildException extends RuntimeException {
+
+protected String qualifiedTypeName;
+private static final long serialVersionUID = -8874662133883858502L; // backward compatible
+
+public AbortIncrementalBuildException(String qualifiedTypeName) {
+	this.qualifiedTypeName = qualifiedTypeName;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
new file mode 100644
index 0000000..465ba5e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
@@ -0,0 +1,882 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.resources.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * The abstract superclass of Java builders.
+ * Provides the building and compilation mechanism
+ * in common with the batch and incremental builders.
+ */
+public abstract class AbstractImageBuilder implements ICompilerRequestor, ICompilationUnitLocator {
+
+protected JavaBuilder javaBuilder;
+protected State newState;
+
+// local copies
+protected NameEnvironment nameEnvironment;
+protected ClasspathMultiDirectory[] sourceLocations;
+protected BuildNotifier notifier;
+
+protected Compiler compiler;
+protected WorkQueue workQueue;
+protected ArrayList problemSourceFiles;
+protected boolean compiledAllAtOnce;
+
+private boolean inCompiler;
+
+protected boolean keepStoringProblemMarkers;
+protected SimpleSet filesWithAnnotations = null;
+
+//2000 is best compromise between space used and speed
+public static int MAX_AT_ONCE = Integer.getInteger(JavaModelManager.MAX_COMPILED_UNITS_AT_ONCE, 2000).intValue();
+public final static String[] JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES = {
+	IMarker.MESSAGE,
+	IMarker.SEVERITY,
+	IJavaModelMarker.ID,
+	IMarker.CHAR_START,
+	IMarker.CHAR_END,
+	IMarker.LINE_NUMBER,
+	IJavaModelMarker.ARGUMENTS,
+	IJavaModelMarker.CATEGORY_ID,
+};
+public final static String[] JAVA_TASK_MARKER_ATTRIBUTE_NAMES = {
+	IMarker.MESSAGE,
+	IMarker.PRIORITY,
+	IJavaModelMarker.ID,
+	IMarker.CHAR_START,
+	IMarker.CHAR_END,
+	IMarker.LINE_NUMBER,
+	IMarker.USER_EDITABLE,
+	IMarker.SOURCE_ID,
+};
+public final static Integer S_ERROR = new Integer(IMarker.SEVERITY_ERROR);
+public final static Integer S_WARNING = new Integer(IMarker.SEVERITY_WARNING);
+public final static Integer P_HIGH = new Integer(IMarker.PRIORITY_HIGH);
+public final static Integer P_NORMAL = new Integer(IMarker.PRIORITY_NORMAL);
+public final static Integer P_LOW = new Integer(IMarker.PRIORITY_LOW);
+
+protected AbstractImageBuilder(JavaBuilder javaBuilder, boolean buildStarting, State newState) {
+	// local copies
+	this.javaBuilder = javaBuilder;
+	this.nameEnvironment = javaBuilder.nameEnvironment;
+	this.sourceLocations = this.nameEnvironment.sourceLocations;
+	this.notifier = javaBuilder.notifier;
+	this.keepStoringProblemMarkers = true; // may get disabled when missing classfiles are encountered
+
+	if (buildStarting) {
+		this.newState = newState == null ? new State(javaBuilder) : newState;
+		this.compiler = newCompiler();
+		this.workQueue = new WorkQueue();
+		this.problemSourceFiles = new ArrayList(3);
+
+		if (this.javaBuilder.participants != null) {
+			for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++) {
+				if (this.javaBuilder.participants[i].isAnnotationProcessor()) {
+					// initialize this set so the builder knows to gather CUs that define Annotation types
+					// each Annotation processor participant is then asked to process these files AFTER
+					// the compile loop. The normal dependency loop will then recompile all affected types
+					this.filesWithAnnotations = new SimpleSet(1);
+					break;
+				}
+			}
+		}
+	}
+}
+
+public void acceptResult(CompilationResult result) {
+	// In Batch mode, we write out the class files, hold onto the dependency info
+	// & additional types and report problems.
+
+	// In Incremental mode, when writing out a class file we need to compare it
+	// against the previous file, remembering if structural changes occured.
+	// Before reporting the new problems, we need to update the problem count &
+	// remove the old problems. Plus delete additional class files that no longer exist.
+
+	SourceFile compilationUnit = (SourceFile) result.getCompilationUnit(); // go directly back to the sourceFile
+	if (!this.workQueue.isCompiled(compilationUnit)) {
+		this.workQueue.finished(compilationUnit);
+
+		try {
+			updateProblemsFor(compilationUnit, result); // record compilation problems before potentially adding duplicate errors
+			updateTasksFor(compilationUnit, result); // record tasks
+		} catch (CoreException e) {
+			throw internalException(e);
+		}
+
+		if (result.hasInconsistentToplevelHierarchies)
+			// ensure that this file is always retrieved from source for the rest of the build
+			if (!this.problemSourceFiles.contains(compilationUnit))
+				this.problemSourceFiles.add(compilationUnit);
+
+		IType mainType = null;
+		String mainTypeName = null;
+		String typeLocator = compilationUnit.typeLocator();
+		ClassFile[] classFiles = result.getClassFiles();
+		int length = classFiles.length;
+		ArrayList duplicateTypeNames = null;
+		ArrayList definedTypeNames = new ArrayList(length);
+		for (int i = 0; i < length; i++) {
+			ClassFile classFile = classFiles[i];
+
+			char[][] compoundName = classFile.getCompoundName();
+			char[] typeName = compoundName[compoundName.length - 1];
+			boolean isNestedType = classFile.isNestedType;
+
+			// Look for a possible collision, if one exists, report an error but do not write the class file
+			if (isNestedType) {
+				String qualifiedTypeName = new String(classFile.outerMostEnclosingClassFile().fileName());
+				if (this.newState.isDuplicateLocator(qualifiedTypeName, typeLocator))
+					continue;
+			} else {
+				String qualifiedTypeName = new String(classFile.fileName()); // the qualified type name "p1/p2/A"
+				if (this.newState.isDuplicateLocator(qualifiedTypeName, typeLocator)) {
+					if (duplicateTypeNames == null)
+						duplicateTypeNames = new ArrayList();
+					duplicateTypeNames.add(compoundName);
+					if (mainType == null) {
+						try {
+							mainTypeName = compilationUnit.initialTypeName; // slash separated qualified name "p1/p1/A"
+							mainType = this.javaBuilder.javaProject.findType(mainTypeName.replace('/', '.'));
+						} catch (JavaModelException e) {
+							// ignore
+						}
+					}
+					IType type;
+					if (qualifiedTypeName.equals(mainTypeName)) {
+						type = mainType;
+					} else {
+						String simpleName = qualifiedTypeName.substring(qualifiedTypeName.lastIndexOf('/')+1);
+						type = mainType == null ? null : mainType.getCompilationUnit().getType(simpleName);
+					}
+					createProblemFor(compilationUnit.resource, type, Messages.bind(Messages.build_duplicateClassFile, new String(typeName)), JavaCore.ERROR);
+					continue;
+				}
+				this.newState.recordLocatorForType(qualifiedTypeName, typeLocator);
+				if (result.checkSecondaryTypes && !qualifiedTypeName.equals(compilationUnit.initialTypeName))
+					acceptSecondaryType(classFile);
+			}
+			try {
+				definedTypeNames.add(writeClassFile(classFile, compilationUnit, !isNestedType));
+			} catch (CoreException e) {
+				Util.log(e, "JavaBuilder handling CoreException"); //$NON-NLS-1$
+				if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS)
+					createProblemFor(compilationUnit.resource, null, Messages.bind(Messages.build_classFileCollision, e.getMessage()), JavaCore.ERROR);
+				else
+					createProblemFor(compilationUnit.resource, null, Messages.build_inconsistentClassFile, JavaCore.ERROR);
+			}
+		}
+		if (result.hasAnnotations && this.filesWithAnnotations != null) // only initialized if an annotation processor is attached
+			this.filesWithAnnotations.add(compilationUnit);
+
+		this.compiler.lookupEnvironment.releaseClassFiles(classFiles);
+		finishedWith(typeLocator, result, compilationUnit.getMainTypeName(), definedTypeNames, duplicateTypeNames);
+		this.notifier.compiled(compilationUnit);
+	}
+}
+
+protected void acceptSecondaryType(ClassFile classFile) {
+	// noop
+}
+
+protected void addAllSourceFiles(final ArrayList sourceFiles) throws CoreException {
+	for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+		final ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
+		final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
+		final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
+		final boolean isAlsoProject = sourceLocation.sourceFolder.equals(this.javaBuilder.currentProject);
+		final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
+		final IContainer outputFolder = sourceLocation.binaryFolder;
+		final boolean isOutputFolder = sourceLocation.sourceFolder.equals(outputFolder);
+		sourceLocation.sourceFolder.accept(
+			new IResourceProxyVisitor() {
+				public boolean visit(IResourceProxy proxy) throws CoreException {
+					switch(proxy.getType()) {
+						case IResource.FILE :
+							if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+								IResource resource = proxy.requestResource();
+								if (exclusionPatterns != null || inclusionPatterns != null)
+									if (Util.isExcluded(resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
+										return false;
+								sourceFiles.add(new SourceFile((IFile) resource, sourceLocation));
+							}
+							return false;
+						case IResource.FOLDER :
+							IPath folderPath = null;
+							if (isAlsoProject)
+								if (isExcludedFromProject(folderPath = proxy.requestFullPath()))
+									return false;
+							if (exclusionPatterns != null) {
+								if (folderPath == null)
+									folderPath = proxy.requestFullPath();
+								if (Util.isExcluded(folderPath, inclusionPatterns, exclusionPatterns, true)) {
+									// must walk children if inclusionPatterns != null, can skip them if == null
+									// but folder is excluded so do not create it in the output folder
+									return inclusionPatterns != null;
+								}
+							}
+							if (!isOutputFolder) {
+								if (folderPath == null)
+									folderPath = proxy.requestFullPath();
+								String packageName = folderPath.lastSegment();
+								if (packageName.length() > 0) {
+									String sourceLevel = AbstractImageBuilder.this.javaBuilder.javaProject.getOption(JavaCore.COMPILER_SOURCE, true);
+									String complianceLevel = AbstractImageBuilder.this.javaBuilder.javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
+									if (JavaConventions.validatePackageName(packageName, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR)
+										createFolder(folderPath.removeFirstSegments(segmentCount), outputFolder);
+								}
+							}
+					}
+					return true;
+				}
+			},
+			IResource.NONE
+		);
+		this.notifier.checkCancel();
+	}
+}
+
+protected void cleanUp() {
+	this.nameEnvironment.cleanup();
+
+	this.javaBuilder = null;
+	this.nameEnvironment = null;
+	this.sourceLocations = null;
+	this.notifier = null;
+	this.compiler = null;
+	this.workQueue = null;
+	this.problemSourceFiles = null;
+}
+
+/* Compile the given elements, adding more elements to the work queue
+* if they are affected by the changes.
+*/
+protected void compile(SourceFile[] units) {
+	if (this.filesWithAnnotations != null && this.filesWithAnnotations.elementSize > 0)
+		// will add files that have annotations in acceptResult() & then processAnnotations() before exitting this method
+		this.filesWithAnnotations.clear();
+
+	// notify CompilationParticipants which source files are about to be compiled
+	CompilationParticipantResult[] participantResults = this.javaBuilder.participants == null ? null : notifyParticipants(units);
+	if (participantResults != null && participantResults.length > units.length) {
+		units = new SourceFile[participantResults.length];
+		for (int i = participantResults.length; --i >= 0;)
+			units[i] = participantResults[i].sourceFile;
+	}
+
+	int unitsLength = units.length;
+	this.compiledAllAtOnce = MAX_AT_ONCE == 0 || unitsLength <= MAX_AT_ONCE;
+	if (this.compiledAllAtOnce) {
+		// do them all now
+		if (JavaBuilder.DEBUG)
+			for (int i = 0; i < unitsLength; i++)
+				System.out.println("About to compile " + units[i].typeLocator()); //$NON-NLS-1$
+		compile(units, null, true);
+	} else {
+		SourceFile[] remainingUnits = new SourceFile[unitsLength]; // copy of units, removing units when about to compile
+		System.arraycopy(units, 0, remainingUnits, 0, unitsLength);
+		int doNow = unitsLength < MAX_AT_ONCE ? unitsLength : MAX_AT_ONCE;
+		SourceFile[] toCompile = new SourceFile[doNow];
+		int remainingIndex = 0;
+		boolean compilingFirstGroup = true;
+		while (remainingIndex < unitsLength) {
+			int count = 0;
+			while (remainingIndex < unitsLength && count < doNow) {
+				// Although it needed compiling when this method was called, it may have
+				// already been compiled when it was referenced by another unit.
+				SourceFile unit = remainingUnits[remainingIndex];
+				if (unit != null && (compilingFirstGroup || this.workQueue.isWaiting(unit))) {
+					if (JavaBuilder.DEBUG)
+						System.out.println("About to compile #" + remainingIndex + " : "+ unit.typeLocator()); //$NON-NLS-1$ //$NON-NLS-2$
+					toCompile[count++] = unit;
+				}
+				remainingUnits[remainingIndex++] = null;
+			}
+			if (count < doNow)
+				System.arraycopy(toCompile, 0, toCompile = new SourceFile[count], 0, count);
+			if (!compilingFirstGroup)
+				for (int a = remainingIndex; a < unitsLength; a++)
+					if (remainingUnits[a] != null && this.workQueue.isCompiled(remainingUnits[a]))
+						remainingUnits[a] = null; // use the class file for this source file since its been compiled
+			compile(toCompile, remainingUnits, compilingFirstGroup);
+			compilingFirstGroup = false;
+		}
+	}
+
+	if (participantResults != null) {
+		for (int i = participantResults.length; --i >= 0;)
+			if (participantResults[i] != null)
+				recordParticipantResult(participantResults[i]);
+
+		processAnnotations(participantResults);
+	}
+}
+
+protected void compile(SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) {
+	if (units.length == 0) return;
+	this.notifier.aboutToCompile(units[0]); // just to change the message
+
+	// extend additionalFilenames with all hierarchical problem types found during this entire build
+	if (!this.problemSourceFiles.isEmpty()) {
+		int toAdd = this.problemSourceFiles.size();
+		int length = additionalUnits == null ? 0 : additionalUnits.length;
+		if (length == 0)
+			additionalUnits = new SourceFile[toAdd];
+		else
+			System.arraycopy(additionalUnits, 0, additionalUnits = new SourceFile[length + toAdd], 0, length);
+		for (int i = 0; i < toAdd; i++)
+			additionalUnits[length + i] = (SourceFile) this.problemSourceFiles.get(i);
+	}
+	String[] initialTypeNames = new String[units.length];
+	for (int i = 0, l = units.length; i < l; i++)
+		initialTypeNames[i] = units[i].initialTypeName;
+	this.nameEnvironment.setNames(initialTypeNames, additionalUnits);
+	this.notifier.checkCancel();
+	try {
+		this.inCompiler = true;
+		this.compiler.compile(units);
+	} catch (AbortCompilation ignored) {
+		// ignore the AbortCompilcation coming from BuildNotifier.checkCancelWithinCompiler()
+		// the Compiler failed after the user has chose to cancel... likely due to an OutOfMemory error
+	} finally {
+		this.inCompiler = false;
+	}
+	// Check for cancel immediately after a compile, because the compiler may
+	// have been cancelled but without propagating the correct exception
+	this.notifier.checkCancel();
+}
+
+protected void copyResource(IResource source, IResource destination) throws CoreException {
+	IPath destPath = destination.getFullPath();
+	try {
+		source.copy(destPath, IResource.FORCE | IResource.DERIVED, null);
+	} catch (CoreException e) {
+		// handle the case when the source resource is deleted
+		source.refreshLocal(0, null);
+		if (!source.exists()) return; // source resource was deleted so skip it
+		throw e;
+	}
+	Util.setReadOnly(destination, false); // just in case the original was read only
+}
+
+protected void createProblemFor(IResource resource, IMember javaElement, String message, String problemSeverity) {
+	try {
+		IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+		int severity = problemSeverity.equals(JavaCore.WARNING) ? IMarker.SEVERITY_WARNING : IMarker.SEVERITY_ERROR;
+
+		ISourceRange range = null;
+		if (javaElement != null) {
+			try {
+				range = javaElement.getNameRange();
+			} catch (JavaModelException e) {
+				if (e.getJavaModelStatus().getCode() != IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST) {
+					throw e;
+				}
+				if (!CharOperation.equals(javaElement.getElementName().toCharArray(), TypeConstants.PACKAGE_INFO_NAME)) {
+					throw e;
+				}
+				// else silently swallow the exception as the synthetic interface type package-info has no
+				// source range really. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=258145
+			}
+		}
+		int start = range == null ? 0 : range.getOffset();
+		int end = range == null ? 1 : start + range.getLength();
+		marker.setAttributes(
+			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.CHAR_START, IMarker.CHAR_END, IMarker.SOURCE_ID},
+			new Object[] {message, new Integer(severity), new Integer(start), new Integer(end), JavaBuilder.SOURCE_ID});
+	} catch (CoreException e) {
+		throw internalException(e);
+	}
+}
+
+protected void deleteGeneratedFiles(IFile[] deletedGeneratedFiles) {
+	// no op by default
+}
+
+protected SourceFile findSourceFile(IFile file, boolean mustExist) {
+	if (mustExist && !file.exists()) return null;
+
+	// assumes the file exists in at least one of the source folders & is not excluded
+	ClasspathMultiDirectory md = this.sourceLocations[0];
+	if (this.sourceLocations.length > 1) {
+		IPath sourceFileFullPath = file.getFullPath();
+		for (int j = 0, m = this.sourceLocations.length; j < m; j++) {
+			if (this.sourceLocations[j].sourceFolder.getFullPath().isPrefixOf(sourceFileFullPath)) {
+				md = this.sourceLocations[j];
+				if (md.exclusionPatterns == null && md.inclusionPatterns == null)
+					break;
+				if (!Util.isExcluded(file, md.inclusionPatterns, md.exclusionPatterns))
+					break;
+			}
+		}
+	}
+	return new SourceFile(file, md);
+}
+
+protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) {
+	if (duplicateTypeNames == null) {
+		this.newState.record(sourceLocator, result.qualifiedReferences, result.simpleNameReferences, result.rootReferences, mainTypeName, definedTypeNames);
+		return;
+	}
+
+	char[][] simpleRefs = result.simpleNameReferences;
+	// for each duplicate type p1.p2.A, add the type name A (package was already added)
+	next : for (int i = 0, l = duplicateTypeNames.size(); i < l; i++) {
+		char[][] compoundName = (char[][]) duplicateTypeNames.get(i);
+		char[] typeName = compoundName[compoundName.length - 1];
+		int sLength = simpleRefs.length;
+		for (int j = 0; j < sLength; j++)
+			if (CharOperation.equals(simpleRefs[j], typeName))
+				continue next;
+		System.arraycopy(simpleRefs, 0, simpleRefs = new char[sLength + 1][], 0, sLength);
+		simpleRefs[sLength] = typeName;
+	}
+	this.newState.record(sourceLocator, result.qualifiedReferences, simpleRefs, result.rootReferences, mainTypeName, definedTypeNames);
+}
+
+protected IContainer createFolder(IPath packagePath, IContainer outputFolder) throws CoreException {
+	if (packagePath.isEmpty()) return outputFolder;
+	IFolder folder = outputFolder.getFolder(packagePath);
+	if (!folder.exists()) {
+		createFolder(packagePath.removeLastSegments(1), outputFolder);
+		folder.create(IResource.FORCE | IResource.DERIVED, true, null);
+	}
+	return folder;
+}
+
+
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.builder.ICompilationUnitLocator#fromIFile(org.eclipse.core.resources.IFile)
+ */
+public ICompilationUnit fromIFile(IFile file) {
+	return findSourceFile(file, true);
+}
+
+protected void initializeAnnotationProcessorManager(Compiler newCompiler) {
+	AbstractAnnotationProcessorManager annotationManager = JavaModelManager.getJavaModelManager().createAnnotationProcessorManager();
+	if (annotationManager != null) {
+		annotationManager.configureFromPlatform(newCompiler, this, this.javaBuilder.javaProject);
+		annotationManager.setErr(new PrintWriter(System.err));
+		annotationManager.setOut(new PrintWriter(System.out));
+	}
+	newCompiler.annotationProcessorManager = annotationManager;
+}
+
+protected RuntimeException internalException(CoreException t) {
+	ImageBuilderInternalException imageBuilderException = new ImageBuilderInternalException(t);
+	if (this.inCompiler)
+		return new AbortCompilation(true, imageBuilderException);
+	return imageBuilderException;
+}
+
+protected boolean isExcludedFromProject(IPath childPath) throws JavaModelException {
+	// answer whether the folder should be ignored when walking the project as a source folder
+	if (childPath.segmentCount() > 2) return false; // is a subfolder of a package
+
+	for (int j = 0, k = this.sourceLocations.length; j < k; j++) {
+		if (childPath.equals(this.sourceLocations[j].binaryFolder.getFullPath())) return true;
+		if (childPath.equals(this.sourceLocations[j].sourceFolder.getFullPath())) return true;
+	}
+	// skip default output folder which may not be used by any source folder
+	return childPath.equals(this.javaBuilder.javaProject.getOutputLocation());
+}
+
+protected Compiler newCompiler() {
+	// disable entire javadoc support if not interested in diagnostics
+	Map projectOptions = this.javaBuilder.javaProject.getOptions(true);
+	String option = (String) projectOptions.get(JavaCore.COMPILER_PB_INVALID_JAVADOC);
+	if (option == null || option.equals(JavaCore.IGNORE)) { // TODO (frederic) see why option is null sometimes while running model tests!?
+		option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS);
+		if (option == null || option.equals(JavaCore.IGNORE)) {
+			option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS);
+			if (option == null || option.equals(JavaCore.IGNORE)) {
+				option = (String) projectOptions.get(JavaCore.COMPILER_PB_UNUSED_IMPORT);
+				if (option == null || option.equals(JavaCore.IGNORE)) { // Unused import need also to look inside javadoc comment
+					projectOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.DISABLED);
+				}
+			}
+		}
+	}
+
+	// called once when the builder is initialized... can override if needed
+	CompilerOptions compilerOptions = new CompilerOptions(projectOptions);
+	compilerOptions.performMethodsFullRecovery = true;
+	compilerOptions.performStatementsRecovery = true;
+	Compiler newCompiler = new Compiler(
+		this.nameEnvironment,
+		DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+		compilerOptions,
+		this,
+		ProblemFactory.getProblemFactory(Locale.getDefault()));
+	CompilerOptions options = newCompiler.options;
+	// temporary code to allow the compiler to revert to a single thread
+	String setting = System.getProperty("jdt.compiler.useSingleThread"); //$NON-NLS-1$
+	newCompiler.useSingleThread = setting != null && setting.equals("true"); //$NON-NLS-1$
+
+	// enable the compiler reference info support
+	options.produceReferenceInfo = true;
+
+	if (options.complianceLevel >= ClassFileConstants.JDK1_6
+			&& options.processAnnotations) {
+		// support for Java 6 annotation processors
+		initializeAnnotationProcessorManager(newCompiler);
+	}
+
+	return newCompiler;
+}
+
+protected CompilationParticipantResult[] notifyParticipants(SourceFile[] unitsAboutToCompile) {
+	CompilationParticipantResult[] results = new CompilationParticipantResult[unitsAboutToCompile.length];
+	for (int i = unitsAboutToCompile.length; --i >= 0;)
+		results[i] = new CompilationParticipantResult(unitsAboutToCompile[i]);
+
+	// TODO (kent) do we expect to have more than one participant?
+	// and if so should we pass the generated files from the each processor to the others to process?
+	// and what happens if some participants do not expect to be called with only a few files, after seeing 'all' the files?
+	for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++)
+		this.javaBuilder.participants[i].buildStarting(results, this instanceof BatchImageBuilder);
+
+	SimpleSet uniqueFiles = null;
+	CompilationParticipantResult[] toAdd = null;
+	int added = 0;
+	for (int i = results.length; --i >= 0;) {
+		CompilationParticipantResult result = results[i];
+		if (result == null) continue;
+
+		IFile[] deletedGeneratedFiles = result.deletedFiles;
+		if (deletedGeneratedFiles != null)
+			deleteGeneratedFiles(deletedGeneratedFiles);
+
+		IFile[] addedGeneratedFiles = result.addedFiles;
+		if (addedGeneratedFiles != null) {
+			for (int j = addedGeneratedFiles.length; --j >= 0;) {
+				SourceFile sourceFile = findSourceFile(addedGeneratedFiles[j], true);
+				if (sourceFile == null) continue;
+				if (uniqueFiles == null) {
+					uniqueFiles = new SimpleSet(unitsAboutToCompile.length + 3);
+					for (int f = unitsAboutToCompile.length; --f >= 0;)
+						uniqueFiles.add(unitsAboutToCompile[f]);
+				}
+				if (uniqueFiles.addIfNotIncluded(sourceFile) == sourceFile) {
+					CompilationParticipantResult newResult = new CompilationParticipantResult(sourceFile);
+					// is there enough room to add all the addedGeneratedFiles.length ?
+					if (toAdd == null) {
+						toAdd = new CompilationParticipantResult[addedGeneratedFiles.length];
+					} else {
+						int length = toAdd.length;
+						if (added == length)
+							System.arraycopy(toAdd, 0, toAdd = new CompilationParticipantResult[length + addedGeneratedFiles.length], 0, length);
+					}
+					toAdd[added++] = newResult;
+				}
+			}
+		}
+	}
+
+	if (added >0 ) {
+		int length = results.length;
+		System.arraycopy(results, 0, results = new CompilationParticipantResult[length + added], 0 , length);
+		System.arraycopy(toAdd, 0, results, length, added);
+	}
+	return results;
+}
+
+protected abstract void processAnnotationResults(CompilationParticipantResult[] results);
+
+protected void processAnnotations(CompilationParticipantResult[] results) {
+	boolean hasAnnotationProcessor = false;
+	for (int i = 0, l = this.javaBuilder.participants.length; !hasAnnotationProcessor && i < l; i++)
+		hasAnnotationProcessor = this.javaBuilder.participants[i].isAnnotationProcessor();
+	if (!hasAnnotationProcessor) return;
+
+	boolean foundAnnotations = this.filesWithAnnotations != null && this.filesWithAnnotations.elementSize > 0;
+	for (int i = results.length; --i >= 0;)
+		results[i].reset(foundAnnotations && this.filesWithAnnotations.includes(results[i].sourceFile));
+
+	// even if no files have annotations, must still tell every annotation processor in case the file used to have them
+	for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++)
+		if (this.javaBuilder.participants[i].isAnnotationProcessor())
+			this.javaBuilder.participants[i].processAnnotations(results);
+	processAnnotationResults(results);
+}
+
+protected void recordParticipantResult(CompilationParticipantResult result) {
+	// any added/changed/deleted generated files have already been taken care
+	// just record the problems and dependencies - do not expect there to be many
+	// must be called after we're finished with the compilation unit results but before incremental loop adds affected files
+	CategorizedProblem[] problems = result.problems;
+	if (problems != null && problems.length > 0) {
+		// existing problems have already been removed so just add these as new problems
+		this.notifier.updateProblemCounts(problems);
+		try {
+			storeProblemsFor(result.sourceFile, problems);
+		} catch (CoreException e) {
+			// must continue with compile loop so just log the CoreException
+			Util.log(e, "JavaBuilder logging CompilationParticipant's CoreException to help debugging"); //$NON-NLS-1$
+		}
+	}
+
+	String[] dependencies = result.dependencies;
+	if (dependencies != null) {
+		ReferenceCollection refs = (ReferenceCollection) this.newState.references.get(result.sourceFile.typeLocator());
+		if (refs != null)
+			refs.addDependencies(dependencies);
+	}
+}
+
+/**
+ * Creates a marker from each problem and adds it to the resource.
+ * The marker is as follows:
+ *   - its type is T_PROBLEM
+ *   - its plugin ID is the JavaBuilder's plugin ID
+ *	 - its message is the problem's message
+ *	 - its priority reflects the severity of the problem
+ *	 - its range is the problem's range
+ *	 - it has an extra attribute "ID" which holds the problem's id
+ *   - it's {@link IMarker#SOURCE_ID} attribute is positioned to {@link JavaBuilder#SOURCE_ID} if
+ *     the problem was generated by JDT; else the {@link IMarker#SOURCE_ID} attribute is
+ *     carried from the problem to the marker in extra attributes, if present.
+ */
+protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] problems) throws CoreException {
+	if (sourceFile == null || problems == null || problems.length == 0) return;
+	 // once a classpath error is found, ignore all other problems for this project so the user can see the main error
+	// but still try to compile as many source files as possible to help the case when the base libraries are in source
+	if (!this.keepStoringProblemMarkers) return; // only want the one error recorded on this source file
+
+	HashSet managedMarkerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
+	problems: for (int i = 0, l = problems.length; i < l; i++) {
+		CategorizedProblem problem = problems[i];
+		int id = problem.getID();
+		// we may use a different resource for certain problems such as IProblem.MissingNonNullByDefaultAnnotationOnPackage
+		// but at the start of the next problem we should reset it to the source file's resource
+		IResource resource = sourceFile.resource;
+		
+		// handle missing classfile situation
+		if (id == IProblem.IsClassPathCorrect) {
+			String missingClassfileName = problem.getArguments()[0];
+			if (JavaBuilder.DEBUG)
+				System.out.println(Messages.bind(Messages.build_incompleteClassPath, missingClassfileName));
+			boolean isInvalidClasspathError = JavaCore.ERROR.equals(this.javaBuilder.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true));
+			// insert extra classpath problem, and make it the only problem for this project (optional)
+			if (isInvalidClasspathError && JavaCore.ABORT.equals(this.javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true))) {
+				JavaBuilder.removeProblemsAndTasksFor(this.javaBuilder.currentProject); // make this the only problem for this project
+				this.keepStoringProblemMarkers = false;
+			}
+			IMarker marker = this.javaBuilder.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+			marker.setAttributes(
+				new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
+				new Object[] {
+					Messages.bind(Messages.build_incompleteClassPath, missingClassfileName),
+					new Integer(isInvalidClasspathError ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING),
+					new Integer(CategorizedProblem.CAT_BUILDPATH),
+					JavaBuilder.SOURCE_ID
+				}
+			);
+			// even if we're not keeping more markers, still fall through rest of the problem reporting, so that offending
+			// IsClassPathCorrect problem gets recorded since it may help locate the offending reference
+		}
+
+		String markerType = problem.getMarkerType();
+		boolean managedProblem = false;
+		if (IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER.equals(markerType)
+				|| (managedProblem = managedMarkerTypes.contains(markerType))) {
+			if (id == IProblem.MissingNonNullByDefaultAnnotationOnPackage && !(CharOperation.equals(sourceFile.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME))) {
+				// for this kind of problem, marker needs to be created on the package instead of on the source file
+				// see bug 372012
+				char[] fileName = sourceFile.getFileName();
+				int pkgEnd = CharOperation.lastIndexOf('/', fileName);
+				if (pkgEnd == -1)
+					pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName);
+				PackageFragment pkg = null;
+				if (pkgEnd != -1)
+					pkg = (PackageFragment) Util.getPackageFragment(sourceFile.getFileName(), pkgEnd, -1 /*no jar separator for java files*/);
+				
+				if (pkg != null) {
+					try {
+						IMarker[] existingMarkers = pkg.resource().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+						int len = existingMarkers.length;
+						for (int j=0; j < len; j++) {
+							if (((Integer)existingMarkers[j].getAttribute(IJavaModelMarker.ID)).intValue() == IProblem.MissingNonNullByDefaultAnnotationOnPackage) {
+								continue problems; // marker already present
+							}
+						}
+					} catch (CoreException e) {
+						// marker retrieval failed, cannot do much
+						if (JavaModelManager.VERBOSE) {
+							e.printStackTrace();
+						}
+					}
+					IResource tempRes = pkg.resource();
+					if (tempRes != null) {
+						resource = tempRes;
+					}
+				}
+			}
+			IMarker marker = resource.createMarker(markerType);
+
+			String[] attributeNames = JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES;
+			int standardLength = attributeNames.length;
+			String[] allNames = attributeNames;
+			int managedLength = managedProblem ? 0 : 1;
+			String[] extraAttributeNames = problem.getExtraMarkerAttributeNames();
+			int extraLength = extraAttributeNames == null ? 0 : extraAttributeNames.length;
+			if (managedLength > 0 || extraLength > 0) {
+				allNames = new String[standardLength + managedLength + extraLength];
+				System.arraycopy(attributeNames, 0, allNames, 0, standardLength);
+				if (managedLength > 0)
+					allNames[standardLength] = IMarker.SOURCE_ID;
+				System.arraycopy(extraAttributeNames, 0, allNames, standardLength + managedLength, extraLength);
+			}
+
+			Object[] allValues = new Object[allNames.length];
+			// standard attributes
+			int index = 0;
+			allValues[index++] = problem.getMessage(); // message
+			allValues[index++] = problem.isError() ? S_ERROR : S_WARNING; // severity
+			allValues[index++] = new Integer(id); // ID
+			allValues[index++] = new Integer(problem.getSourceStart()); // start
+			allValues[index++] = new Integer(problem.getSourceEnd() + 1); // end
+			allValues[index++] = new Integer(problem.getSourceLineNumber()); // line
+			allValues[index++] = Util.getProblemArgumentsForMarker(problem.getArguments()); // arguments
+			allValues[index++] = new Integer(problem.getCategoryID()); // category ID
+			// SOURCE_ID attribute for JDT problems
+			if (managedLength > 0)
+				allValues[index++] = JavaBuilder.SOURCE_ID;
+			// optional extra attributes
+			if (extraLength > 0)
+				System.arraycopy(problem.getExtraMarkerAttributeValues(), 0, allValues, index, extraLength);
+
+			marker.setAttributes(allNames, allValues);
+
+			if (!this.keepStoringProblemMarkers) return; // only want the one error recorded on this source file
+		}
+	}
+}
+
+protected void storeTasksFor(SourceFile sourceFile, CategorizedProblem[] tasks) throws CoreException {
+	if (sourceFile == null || tasks == null || tasks.length == 0) return;
+
+	IResource resource = sourceFile.resource;
+	for (int i = 0, l = tasks.length; i < l; i++) {
+		CategorizedProblem task = tasks[i];
+		if (task.getID() == IProblem.Task) {
+			IMarker marker = resource.createMarker(IJavaModelMarker.TASK_MARKER);
+			Integer priority = P_NORMAL;
+			String compilerPriority = task.getArguments()[2];
+			if (JavaCore.COMPILER_TASK_PRIORITY_HIGH.equals(compilerPriority))
+				priority = P_HIGH;
+			else if (JavaCore.COMPILER_TASK_PRIORITY_LOW.equals(compilerPriority))
+				priority = P_LOW;
+
+			String[] attributeNames = JAVA_TASK_MARKER_ATTRIBUTE_NAMES;
+			int standardLength = attributeNames.length;
+			String[] allNames = attributeNames;
+			String[] extraAttributeNames = task.getExtraMarkerAttributeNames();
+			int extraLength = extraAttributeNames == null ? 0 : extraAttributeNames.length;
+			if (extraLength > 0) {
+				allNames = new String[standardLength + extraLength];
+				System.arraycopy(attributeNames, 0, allNames, 0, standardLength);
+				System.arraycopy(extraAttributeNames, 0, allNames, standardLength, extraLength);
+			}
+
+			Object[] allValues = new Object[allNames.length];
+			// standard attributes
+			int index = 0;
+			allValues[index++] = task.getMessage();
+			allValues[index++] = priority;
+			allValues[index++] = new Integer(task.getID());
+			allValues[index++] = new Integer(task.getSourceStart());
+			allValues[index++] = new Integer(task.getSourceEnd() + 1);
+			allValues[index++] = new Integer(task.getSourceLineNumber());
+			allValues[index++] = Boolean.FALSE;
+			allValues[index++] = JavaBuilder.SOURCE_ID;
+			// optional extra attributes
+			if (extraLength > 0)
+				System.arraycopy(task.getExtraMarkerAttributeValues(), 0, allValues, index, extraLength);
+
+			marker.setAttributes(allNames, allValues);
+		}
+	}
+}
+
+protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
+	CategorizedProblem[] problems = result.getProblems();
+	if (problems == null || problems.length == 0) return;
+
+	this.notifier.updateProblemCounts(problems);
+	storeProblemsFor(sourceFile, problems);
+}
+
+protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
+	CategorizedProblem[] tasks = result.getTasks();
+	if (tasks == null || tasks.length == 0) return;
+
+	storeTasksFor(sourceFile, tasks);
+}
+
+protected char[] writeClassFile(ClassFile classFile, SourceFile compilationUnit, boolean isTopLevelType) throws CoreException {
+	String fileName = new String(classFile.fileName()); // the qualified type name "p1/p2/A"
+	IPath filePath = new Path(fileName);
+	IContainer outputFolder = compilationUnit.sourceLocation.binaryFolder;
+	IContainer container = outputFolder;
+	if (filePath.segmentCount() > 1) {
+		container = createFolder(filePath.removeLastSegments(1), outputFolder);
+		filePath = new Path(filePath.lastSegment());
+	}
+
+	IFile file = container.getFile(filePath.addFileExtension(SuffixConstants.EXTENSION_class));
+	writeClassFileContents(classFile, file, fileName, isTopLevelType, compilationUnit);
+	// answer the name of the class file as in Y or Y$M
+	return filePath.lastSegment().toCharArray();
+}
+
+protected void writeClassFileContents(ClassFile classFile, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException {
+//	InputStream input = new SequenceInputStream(
+//			new ByteArrayInputStream(classFile.header, 0, classFile.headerOffset),
+//			new ByteArrayInputStream(classFile.contents, 0, classFile.contentsOffset));
+	InputStream input = new ByteArrayInputStream(classFile.getBytes());
+	if (file.exists()) {
+		// Deal with shared output folders... last one wins... no collision cases detected
+		if (JavaBuilder.DEBUG)
+			System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$
+		if (!file.isDerived())
+			file.setDerived(true, null);
+		file.setContents(input, true, false, null);
+	} else {
+		// Default implementation just writes out the bytes for the new class file...
+		if (JavaBuilder.DEBUG)
+			System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$
+		file.create(input, IResource.FORCE | IResource.DERIVED, null);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java
new file mode 100644
index 0000000..9bf892b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+public class AdditionalTypeCollection extends ReferenceCollection {
+
+char[][] definedTypeNames;
+
+protected AdditionalTypeCollection(char[][] definedTypeNames, char[][][] qualifiedReferences, char[][] simpleNameReferences, char[][] rootReferences) {
+	super(qualifiedReferences, simpleNameReferences, rootReferences);
+	this.definedTypeNames = definedTypeNames; // do not bother interning member type names (i.e. 'A$M')
+}
+}
+
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
new file mode 100644
index 0000000..5893e38
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.impl.CompilerStats;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import java.util.*;
+
+public class BatchImageBuilder extends AbstractImageBuilder {
+
+	IncrementalImageBuilder incrementalBuilder; // if annotations or secondary types have to be processed after the compile loop
+	ArrayList secondaryTypes; // qualified names for all secondary types found during batch compile
+	StringSet typeLocatorsWithUndefinedTypes; // type locators for all source files with errors that may be caused by 'not found' secondary types
+
+protected BatchImageBuilder(JavaBuilder javaBuilder, boolean buildStarting) {
+	super(javaBuilder, buildStarting, null);
+	this.nameEnvironment.isIncrementalBuild = false;
+	this.incrementalBuilder = null;
+	this.secondaryTypes = null;
+	this.typeLocatorsWithUndefinedTypes = null;
+}
+
+public void build() {
+	if (JavaBuilder.DEBUG)
+		System.out.println("FULL build"); //$NON-NLS-1$
+
+	try {
+		this.notifier.subTask(Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
+		JavaBuilder.removeProblemsAndTasksFor(this.javaBuilder.currentProject);
+		cleanOutputFolders(true);
+		this.notifier.updateProgressDelta(0.05f);
+
+		this.notifier.subTask(Messages.build_analyzingSources);
+		ArrayList sourceFiles = new ArrayList(33);
+		addAllSourceFiles(sourceFiles);
+		this.notifier.updateProgressDelta(0.10f);
+
+		if (sourceFiles.size() > 0) {
+			SourceFile[] allSourceFiles = new SourceFile[sourceFiles.size()];
+			sourceFiles.toArray(allSourceFiles);
+
+			this.notifier.setProgressPerCompilationUnit(0.75f / allSourceFiles.length);
+			this.workQueue.addAll(allSourceFiles);
+			compile(allSourceFiles);
+
+			if (this.typeLocatorsWithUndefinedTypes != null)
+				if (this.secondaryTypes != null && !this.secondaryTypes.isEmpty())
+					rebuildTypesAffectedBySecondaryTypes();
+			if (this.incrementalBuilder != null)
+				this.incrementalBuilder.buildAfterBatchBuild();
+		}
+
+		if (this.javaBuilder.javaProject.hasCycleMarker())
+			this.javaBuilder.mustPropagateStructuralChanges();
+	} catch (CoreException e) {
+		throw internalException(e);
+	} finally {
+		if (JavaBuilder.SHOW_STATS)
+			printStats();
+		cleanUp();
+	}
+}
+
+protected void acceptSecondaryType(ClassFile classFile) {
+	if (this.secondaryTypes != null)
+		this.secondaryTypes.add(classFile.fileName());
+}
+
+protected void cleanOutputFolders(boolean copyBack) throws CoreException {
+	boolean deleteAll = JavaCore.CLEAN.equals(
+		this.javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER, true));
+	if (deleteAll) {
+		if (this.javaBuilder.participants != null)
+			for (int i = 0, l = this.javaBuilder.participants.length; i < l; i++)
+				this.javaBuilder.participants[i].cleanStarting(this.javaBuilder.javaProject);
+
+		ArrayList visited = new ArrayList(this.sourceLocations.length);
+		for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+			this.notifier.subTask(Messages.bind(Messages.build_cleaningOutput, this.javaBuilder.currentProject.getName()));
+			ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
+			if (sourceLocation.hasIndependentOutputFolder) {
+				IContainer outputFolder = sourceLocation.binaryFolder;
+				if (!visited.contains(outputFolder)) {
+					visited.add(outputFolder);
+					IResource[] members = outputFolder.members();
+					for (int j = 0, m = members.length; j < m; j++) {
+						IResource member = members[j];
+						if (!member.isDerived()) {
+							member.accept(
+								new IResourceVisitor() {
+									public boolean visit(IResource resource) throws CoreException {
+										resource.setDerived(true, null);
+										return resource.getType() != IResource.FILE;
+									}
+								}
+							);
+						}
+						member.delete(IResource.FORCE, null);
+					}
+				}
+				this.notifier.checkCancel();
+				if (copyBack)
+					copyExtraResourcesBack(sourceLocation, true);
+			} else {
+				boolean isOutputFolder = sourceLocation.sourceFolder.equals(sourceLocation.binaryFolder);
+				final char[][] exclusionPatterns =
+					isOutputFolder
+						? sourceLocation.exclusionPatterns
+						: null; // ignore exclusionPatterns if output folder == another source folder... not this one
+				final char[][] inclusionPatterns =
+					isOutputFolder
+						? sourceLocation.inclusionPatterns
+						: null; // ignore inclusionPatterns if output folder == another source folder... not this one
+				sourceLocation.binaryFolder.accept(
+					new IResourceProxyVisitor() {
+						public boolean visit(IResourceProxy proxy) throws CoreException {
+							if (proxy.getType() == IResource.FILE) {
+								if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
+									IResource resource = proxy.requestResource();
+									if (exclusionPatterns != null || inclusionPatterns != null)
+										if (Util.isExcluded(resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
+											return false;
+									if (!resource.isDerived())
+										resource.setDerived(true, null);
+									resource.delete(IResource.FORCE, null);
+								}
+								return false;
+							}
+							if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null
+								if (Util.isExcluded(proxy.requestFullPath(), null, exclusionPatterns, true))
+									return false;
+							BatchImageBuilder.this.notifier.checkCancel();
+							return true;
+						}
+					},
+					IResource.NONE
+				);
+				this.notifier.checkCancel();
+			}
+			this.notifier.checkCancel();
+		}
+	} else if (copyBack) {
+		for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+			ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
+			if (sourceLocation.hasIndependentOutputFolder)
+				copyExtraResourcesBack(sourceLocation, false);
+			this.notifier.checkCancel();
+		}
+	}
+}
+
+protected void cleanUp() {
+	this.incrementalBuilder = null;
+	this.secondaryTypes = null;
+	this.typeLocatorsWithUndefinedTypes = null;
+	super.cleanUp();
+}
+
+protected void compile(SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) {
+	if (additionalUnits != null && this.secondaryTypes == null)
+		this.secondaryTypes = new ArrayList(7);
+	super.compile(units, additionalUnits, compilingFirstGroup);
+}
+
+protected void copyExtraResourcesBack(ClasspathMultiDirectory sourceLocation, final boolean deletedAll) throws CoreException {
+	// When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
+	// If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
+
+	this.notifier.subTask(Messages.build_copyingResources);
+	final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
+	final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
+	final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
+	final IContainer outputFolder = sourceLocation.binaryFolder;
+	final boolean isAlsoProject = sourceLocation.sourceFolder.equals(this.javaBuilder.currentProject);
+	sourceLocation.sourceFolder.accept(
+		new IResourceProxyVisitor() {
+			public boolean visit(IResourceProxy proxy) throws CoreException {
+				IResource resource = null;
+				switch(proxy.getType()) {
+					case IResource.FILE :
+						if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName()) ||
+							org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) return false;
+
+						resource = proxy.requestResource();
+						if (BatchImageBuilder.this.javaBuilder.filterExtraResource(resource)) return false;
+						if (exclusionPatterns != null || inclusionPatterns != null)
+							if (Util.isExcluded(resource.getFullPath(), inclusionPatterns, exclusionPatterns, false))
+								return false;
+
+						IPath partialPath = resource.getFullPath().removeFirstSegments(segmentCount);
+						IResource copiedResource = outputFolder.getFile(partialPath);
+						if (copiedResource.exists()) {
+							if (deletedAll) {
+								IResource originalResource = findOriginalResource(partialPath);
+								String id = originalResource.getFullPath().removeFirstSegments(1).toString();
+								createProblemFor(
+									resource,
+									null,
+									Messages.bind(Messages.build_duplicateResource, id),
+									BatchImageBuilder.this.javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
+								return false;
+							}
+							copiedResource.delete(IResource.FORCE, null); // last one wins
+						}
+						createFolder(partialPath.removeLastSegments(1), outputFolder); // ensure package folder exists
+						copyResource(resource, copiedResource);
+						return false;
+					case IResource.FOLDER :
+						resource = proxy.requestResource();
+						if (BatchImageBuilder.this.javaBuilder.filterExtraResource(resource)) return false;
+						if (isAlsoProject && isExcludedFromProject(resource.getFullPath())) return false; // the sourceFolder == project
+						if (exclusionPatterns != null && inclusionPatterns == null) // must walk children if inclusionPatterns != null
+							if (Util.isExcluded(resource.getFullPath(), null, exclusionPatterns, true))
+								return false;
+				}
+				return true;
+			}
+		},
+		IResource.NONE
+	);
+}
+
+protected IResource findOriginalResource(IPath partialPath) {
+	for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+		ClasspathMultiDirectory sourceLocation = this.sourceLocations[i];
+		if (sourceLocation.hasIndependentOutputFolder) {
+			IResource originalResource = sourceLocation.sourceFolder.getFile(partialPath);
+			if (originalResource.exists()) return originalResource;
+		}
+	}
+	return null;
+}
+
+private void printStats() {
+	if (this.compiler == null) return;
+	CompilerStats compilerStats = this.compiler.stats;
+	long time = compilerStats.elapsedTime();
+	long lineCount = compilerStats.lineCount;
+	double speed = ((int) (lineCount * 10000.0 / time)) / 10.0;
+	System.out.println(">FULL BUILD STATS for: "+this.javaBuilder.javaProject.getElementName()); //$NON-NLS-1$
+	System.out.println(">   compiled " + lineCount + " lines in " + time + "ms:" + speed + "lines/s"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+	System.out.print(">   parse: " + compilerStats.parseTime + " ms (" + ((int) (compilerStats.parseTime * 1000.0 / time)) / 10.0 + "%)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	System.out.print(", resolve: " + compilerStats.resolveTime + " ms (" + ((int) (compilerStats.resolveTime * 1000.0 / time)) / 10.0 + "%)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	System.out.print(", analyze: " + compilerStats.analyzeTime + " ms (" + ((int) (compilerStats.analyzeTime * 1000.0 / time)) / 10.0 + "%)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	System.out.println(", generate: " + compilerStats.generateTime + " ms (" + ((int) (compilerStats.generateTime * 1000.0 / time)) / 10.0 + "%)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+}
+
+protected void processAnnotationResults(CompilationParticipantResult[] results) {
+	// to compile the compilation participant results, we need to incrementally recompile all affected types
+	// whenever the generated types are initially added or structurally changed
+	if (this.incrementalBuilder == null)
+		this.incrementalBuilder = new IncrementalImageBuilder(this);
+	this.incrementalBuilder.processAnnotationResults(results);
+}
+
+protected void rebuildTypesAffectedBySecondaryTypes() {
+	// to compile types that could not find 'missing' secondary types because of multiple
+	// compile groups, we need to incrementally recompile all affected types as if the missing
+	// secondary types have just been added, see bug 146324
+	if (this.incrementalBuilder == null)
+		this.incrementalBuilder = new IncrementalImageBuilder(this);
+
+	int count = this.secondaryTypes.size();
+	StringSet qualifiedNames = new StringSet(count * 2);
+	StringSet simpleNames = new StringSet(count);
+	StringSet rootNames = new StringSet(3);
+	while (--count >=0) {
+		char[] secondaryTypeName = (char[]) this.secondaryTypes.get(count);
+		IPath path = new Path(null, new String(secondaryTypeName));
+		this.incrementalBuilder.addDependentsOf(path, false, qualifiedNames, simpleNames, rootNames);
+	}
+	this.incrementalBuilder.addAffectedSourceFiles(
+		qualifiedNames,
+		simpleNames,
+		rootNames,
+		this.typeLocatorsWithUndefinedTypes);
+}
+
+protected void storeProblemsFor(SourceFile sourceFile, CategorizedProblem[] problems) throws CoreException {
+	if (sourceFile == null || problems == null || problems.length == 0) return;
+
+	for (int i = problems.length; --i >= 0;) {
+		CategorizedProblem problem = problems[i];
+		if (problem != null && problem.getID() == IProblem.UndefinedType) {
+			if (this.typeLocatorsWithUndefinedTypes == null)
+				this.typeLocatorsWithUndefinedTypes = new StringSet(3);
+			this.typeLocatorsWithUndefinedTypes.add(sourceFile.typeLocator());
+			break;
+		}
+	}
+
+	super.storeProblemsFor(sourceFile, problems);
+}
+
+public String toString() {
+	return "batch image builder for:\n\tnew state: " + this.newState; //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java
new file mode 100644
index 0000000..ab72fde
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+public class BuildNotifier {
+
+protected IProgressMonitor monitor;
+protected boolean cancelling;
+protected float percentComplete;
+protected float progressPerCompilationUnit;
+protected int newErrorCount;
+protected int fixedErrorCount;
+protected int newWarningCount;
+protected int fixedWarningCount;
+protected int workDone;
+protected int totalWork;
+protected String previousSubtask;
+
+public static int NewErrorCount = 0;
+public static int FixedErrorCount = 0;
+public static int NewWarningCount = 0;
+public static int FixedWarningCount = 0;
+
+public static void resetProblemCounters() {
+	NewErrorCount = 0;
+	FixedErrorCount = 0;
+	NewWarningCount = 0;
+	FixedWarningCount = 0;
+}
+
+public BuildNotifier(IProgressMonitor monitor, IProject project) {
+	this.monitor = monitor;
+	this.cancelling = false;
+	this.newErrorCount = NewErrorCount;
+	this.fixedErrorCount = FixedErrorCount;
+	this.newWarningCount = NewWarningCount;
+	this.fixedWarningCount = FixedWarningCount;
+	this.workDone = 0;
+	this.totalWork = 1000000;
+}
+
+/**
+ * Notification before a compile that a unit is about to be compiled.
+ */
+public void aboutToCompile(SourceFile unit) {
+	String message = Messages.bind(Messages.build_compiling, unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString());
+	subTask(message);
+}
+
+public void begin() {
+	if (this.monitor != null)
+		this.monitor.beginTask("", this.totalWork); //$NON-NLS-1$
+	this.previousSubtask = null;
+}
+
+/**
+ * Check whether the build has been canceled.
+ */
+public void checkCancel() {
+	if (this.monitor != null && this.monitor.isCanceled())
+		throw new OperationCanceledException();
+}
+
+/**
+ * Check whether the build has been canceled.
+ * Must use this call instead of checkCancel() when within the compiler.
+ */
+public void checkCancelWithinCompiler() {
+	if (this.monitor != null && this.monitor.isCanceled() && !this.cancelling) {
+		// Once the compiler has been canceled, don't check again.
+		setCancelling(true);
+		// Only AbortCompilation can stop the compiler cleanly.
+		// We check cancelation again following the call to compile.
+		throw new AbortCompilation(true, null);
+	}
+}
+
+/**
+ * Notification while within a compile that a unit has finished being compiled.
+ */
+public void compiled(SourceFile unit) {
+	String message = Messages.bind(Messages.build_compiling, unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString());
+	subTask(message);
+	updateProgressDelta(this.progressPerCompilationUnit);
+	checkCancelWithinCompiler();
+}
+
+public void done() {
+	NewErrorCount = this.newErrorCount;
+	FixedErrorCount = this.fixedErrorCount;
+	NewWarningCount = this.newWarningCount;
+	FixedWarningCount = this.fixedWarningCount;
+
+	updateProgress(1.0f);
+	subTask(Messages.build_done);
+	if (this.monitor != null)
+		this.monitor.done();
+	this.previousSubtask = null;
+}
+
+/**
+ * Returns a string describing the problems.
+ */
+protected String problemsMessage() {
+	int numNew = this.newErrorCount + this.newWarningCount;
+	int numFixed = this.fixedErrorCount + this.fixedWarningCount;
+	if (numNew == 0 && numFixed == 0) return ""; //$NON-NLS-1$
+
+	boolean displayBoth = numNew > 0 && numFixed > 0;
+	StringBuffer buffer = new StringBuffer();
+	buffer.append('(');
+	if (numNew > 0) {
+		// (Found x errors + y warnings)
+		buffer.append(Messages.build_foundHeader);
+		buffer.append(' ');
+		if (displayBoth || this.newErrorCount > 0) {
+			if (this.newErrorCount == 1)
+				buffer.append(Messages.build_oneError);
+			else
+				buffer.append(Messages.bind(Messages.build_multipleErrors, String.valueOf(this.newErrorCount)));
+			if (displayBoth || this.newWarningCount > 0)
+				buffer.append(" + "); //$NON-NLS-1$
+		}
+		if (displayBoth || this.newWarningCount > 0) {
+			if (this.newWarningCount == 1)
+				buffer.append(Messages.build_oneWarning);
+			else
+				buffer.append(Messages.bind(Messages.build_multipleWarnings, String.valueOf(this.newWarningCount)));
+		}
+		if (numFixed > 0)
+			buffer.append(", "); //$NON-NLS-1$
+	}
+	if (numFixed > 0) {
+		// (Fixed x errors + y warnings) or (Found x errors + y warnings, Fixed x + y)
+		buffer.append(Messages.build_fixedHeader);
+		buffer.append(' ');
+		if (displayBoth) {
+			buffer.append(String.valueOf(this.fixedErrorCount));
+			buffer.append(" + "); //$NON-NLS-1$
+			buffer.append(String.valueOf(this.fixedWarningCount));
+		} else {
+			if (this.fixedErrorCount > 0) {
+				if (this.fixedErrorCount == 1)
+					buffer.append(Messages.build_oneError);
+				else
+					buffer.append(Messages.bind(Messages.build_multipleErrors, String.valueOf(this.fixedErrorCount)));
+				if (this.fixedWarningCount > 0)
+					buffer.append(" + "); //$NON-NLS-1$
+			}
+			if (this.fixedWarningCount > 0) {
+				if (this.fixedWarningCount == 1)
+					buffer.append(Messages.build_oneWarning);
+				else
+					buffer.append(Messages.bind(Messages.build_multipleWarnings, String.valueOf(this.fixedWarningCount)));
+			}
+		}
+	}
+	buffer.append(')');
+	return buffer.toString();
+}
+
+/**
+ * Sets the cancelling flag, which indicates we are in the middle
+ * of being cancelled.  Certain places (those callable indirectly from the compiler)
+ * should not check cancel again while this is true, to avoid OperationCanceledException
+ * being thrown at an inopportune time.
+ */
+public void setCancelling(boolean cancelling) {
+	this.cancelling = cancelling;
+}
+
+/**
+ * Sets the amount of progress to report for compiling each compilation unit.
+ */
+public void setProgressPerCompilationUnit(float progress) {
+	this.progressPerCompilationUnit = progress;
+}
+
+public void subTask(String message) {
+	String pm = problemsMessage();
+	String msg = pm.length() == 0 ? message : pm + " " + message; //$NON-NLS-1$
+
+	if (msg.equals(this.previousSubtask)) return; // avoid refreshing with same one
+	//if (JavaBuilder.DEBUG) System.out.println(msg);
+	if (this.monitor != null)
+		this.monitor.subTask(msg);
+
+	this.previousSubtask = msg;
+}
+
+protected void updateProblemCounts(CategorizedProblem[] newProblems) {
+	for (int i = 0, l = newProblems.length; i < l; i++)
+		if (newProblems[i].isError()) this.newErrorCount++; else this.newWarningCount++;
+}
+
+/**
+ * Update the problem counts from one compilation result given the old and new problems,
+ * either of which may be null.
+ */
+protected void updateProblemCounts(IMarker[] oldProblems, CategorizedProblem[] newProblems) {
+	if (newProblems != null) {
+		next : for (int i = 0, l = newProblems.length; i < l; i++) {
+			CategorizedProblem newProblem = newProblems[i];
+			if (newProblem.getID() == IProblem.Task) continue; // skip task
+			boolean isError = newProblem.isError();
+			String message = newProblem.getMessage();
+
+			if (oldProblems != null) {
+				for (int j = 0, m = oldProblems.length; j < m; j++) {
+					IMarker pb = oldProblems[j];
+					if (pb == null) continue; // already matched up with a new problem
+					boolean wasError = IMarker.SEVERITY_ERROR
+						== pb.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+					if (isError == wasError && message.equals(pb.getAttribute(IMarker.MESSAGE, ""))) { //$NON-NLS-1$
+						oldProblems[j] = null;
+						continue next;
+					}
+				}
+			}
+			if (isError) this.newErrorCount++; else this.newWarningCount++;
+		}
+	}
+	if (oldProblems != null) {
+		next : for (int i = 0, l = oldProblems.length; i < l; i++) {
+			IMarker oldProblem = oldProblems[i];
+			if (oldProblem == null) continue next; // already matched up with a new problem
+			boolean wasError = IMarker.SEVERITY_ERROR
+				== oldProblem.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+			String message = oldProblem.getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$
+
+			if (newProblems != null) {
+				for (int j = 0, m = newProblems.length; j < m; j++) {
+					CategorizedProblem pb = newProblems[j];
+					if (pb.getID() == IProblem.Task) continue; // skip task
+					if (wasError == pb.isError() && message.equals(pb.getMessage()))
+						continue next;
+				}
+			}
+			if (wasError) this.fixedErrorCount++; else this.fixedWarningCount++;
+		}
+	}
+}
+
+public void updateProgress(float newPercentComplete) {
+	if (newPercentComplete > this.percentComplete) {
+		this.percentComplete = Math.min(newPercentComplete, 1.0f);
+		int work = Math.round(this.percentComplete * this.totalWork);
+		if (work > this.workDone) {
+			if (this.monitor != null)
+				this.monitor.worked(work - this.workDone);
+			//if (JavaBuilder.DEBUG)
+				//System.out.println(java.text.NumberFormat.getPercentInstance().format(this.percentComplete));
+			this.workDone = work;
+		}
+	}
+}
+
+public void updateProgressDelta(float percentWorked) {
+	updateProgress(this.percentComplete + percentWorked);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
new file mode 100644
index 0000000..63c8de7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathDirectory extends ClasspathLocation {
+
+IContainer binaryFolder; // includes .class files for a single directory
+boolean isOutputFolder;
+SimpleLookupTable directoryCache;
+String[] missingPackageHolder = new String[1];
+AccessRuleSet accessRuleSet;
+
+ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder, AccessRuleSet accessRuleSet) {
+	this.binaryFolder = binaryFolder;
+	this.isOutputFolder = isOutputFolder || binaryFolder.getProjectRelativePath().isEmpty(); // if binaryFolder == project, then treat it as an outputFolder
+	this.directoryCache = new SimpleLookupTable(5);
+	this.accessRuleSet = accessRuleSet;
+}
+
+public void cleanup() {
+	this.directoryCache = null;
+}
+
+String[] directoryList(String qualifiedPackageName) {
+	String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
+	if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
+	if (dirList != null) return dirList;
+
+	try {
+		IResource container = this.binaryFolder.findMember(qualifiedPackageName); // this is a case-sensitive check
+		if (container instanceof IContainer) {
+			IResource[] members = ((IContainer) container).members();
+			dirList = new String[members.length];
+			int index = 0;
+			for (int i = 0, l = members.length; i < l; i++) {
+				IResource m = members[i];
+				if (m.getType() == IResource.FILE && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(m.getName()))
+					// add exclusion pattern check here if we want to hide .class files
+					dirList[index++] = m.getName();
+			}
+			if (index < dirList.length)
+				System.arraycopy(dirList, 0, dirList = new String[index], 0, index);
+			this.directoryCache.put(qualifiedPackageName, dirList);
+			return dirList;
+		}
+	} catch(CoreException ignored) {
+		// ignore
+	}
+	this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
+	return null;
+}
+
+boolean doesFileExist(String fileName, String qualifiedPackageName, String qualifiedFullName) {
+	String[] dirList = directoryList(qualifiedPackageName);
+	if (dirList == null) return false; // most common case
+
+	for (int i = dirList.length; --i >= 0;)
+		if (fileName.equals(dirList[i]))
+			return true;
+	return false;
+}
+
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof ClasspathDirectory)) return false;
+
+	ClasspathDirectory dir = (ClasspathDirectory) o;
+	if (this.accessRuleSet != dir.accessRuleSet)
+		if (this.accessRuleSet == null || !this.accessRuleSet.equals(dir.accessRuleSet))
+			return false;
+	return this.binaryFolder.equals(dir.binaryFolder);
+}
+
+public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	if (!doesFileExist(binaryFileName, qualifiedPackageName, qualifiedBinaryFileName)) return null; // most common case
+
+	ClassFileReader reader = null;
+	try {
+		reader = Util.newClassFileReader(this.binaryFolder.getFile(new Path(qualifiedBinaryFileName)));
+	} catch (CoreException e) {
+		return null;
+	} catch (ClassFormatException e) {
+		return null;
+	} catch (IOException e) {
+		return null;
+	}
+	if (reader != null) {
+		if (this.accessRuleSet == null)
+			return new NameEnvironmentAnswer(reader, null);
+		String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+		return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()));
+	}
+	return null;
+}
+
+public IPath getProjectRelativePath() {
+	return this.binaryFolder.getProjectRelativePath();
+}
+
+public int hashCode() {
+	return this.binaryFolder == null ? super.hashCode() : this.binaryFolder.hashCode();
+}
+
+protected boolean isExcluded(IResource resource) {
+	return false;
+}
+
+public boolean isOutputFolder() {
+	return this.isOutputFolder;
+}
+
+public boolean isPackage(String qualifiedPackageName) {
+	return directoryList(qualifiedPackageName) != null;
+}
+
+public void reset() {
+	this.directoryCache = new SimpleLookupTable(5);
+}
+
+public String toString() {
+	String start = "Binary classpath directory " + this.binaryFolder.getFullPath().toString(); //$NON-NLS-1$
+	if (this.accessRuleSet == null)
+		return start;
+	return start + " with " + this.accessRuleSet; //$NON-NLS-1$
+}
+
+public String debugPathString() {
+	return this.binaryFolder.getFullPath().toString();
+}
+
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
new file mode 100644
index 0000000..3268b4c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Tal Lev-Ami - added package cache for zip files
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+public class ClasspathJar extends ClasspathLocation {
+
+static class PackageCacheEntry {
+	long lastModified;
+	long fileSize;
+	SimpleSet packageSet;
+
+	PackageCacheEntry(long lastModified, long fileSize, SimpleSet packageSet) {
+		this.lastModified = lastModified;
+		this.fileSize = fileSize;
+		this.packageSet = packageSet;
+	}
+}
+
+static SimpleLookupTable PackageCache = new SimpleLookupTable();
+
+/**
+ * Calculate and cache the package list available in the zipFile.
+ * @param jar The ClasspathJar to use
+ * @return A SimpleSet with the all the package names in the zipFile.
+ */
+static SimpleSet findPackageSet(ClasspathJar jar) {
+	String zipFileName = jar.zipFilename;
+	long lastModified = jar.lastModified();
+	long fileSize = new File(zipFileName).length();
+	PackageCacheEntry cacheEntry = (PackageCacheEntry) PackageCache.get(zipFileName);
+	if (cacheEntry != null && cacheEntry.lastModified == lastModified && cacheEntry.fileSize == fileSize)
+		return cacheEntry.packageSet;
+
+	SimpleSet packageSet = new SimpleSet(41);
+	packageSet.add(""); //$NON-NLS-1$
+	nextEntry : for (Enumeration e = jar.zipFile.entries(); e.hasMoreElements(); ) {
+		String fileName = ((ZipEntry) e.nextElement()).getName();
+
+		// add the package name & all of its parent packages
+		int last = fileName.lastIndexOf('/');
+		while (last > 0) {
+			// extract the package name
+			String packageName = fileName.substring(0, last);
+			if (packageSet.addIfNotIncluded(packageName) == null)
+				continue nextEntry; // already existed
+			last = packageName.lastIndexOf('/');
+		}
+	}
+
+	PackageCache.put(zipFileName, new PackageCacheEntry(lastModified, fileSize, packageSet));
+	return packageSet;
+}
+
+
+String zipFilename; // keep for equals
+IFile resource;
+ZipFile zipFile;
+long lastModified;
+boolean closeZipFileAtEnd;
+SimpleSet knownPackageNames;
+AccessRuleSet accessRuleSet;
+
+ClasspathJar(IFile resource, AccessRuleSet accessRuleSet) {
+	this.resource = resource;
+	try {
+		java.net.URI location = resource.getLocationURI();
+		if (location == null) {
+			this.zipFilename = ""; //$NON-NLS-1$
+		} else {
+			File localFile = Util.toLocalFile(location, null);
+			this.zipFilename = localFile.getPath();
+		}
+	} catch (CoreException e) {
+		// ignore
+	}
+	this.zipFile = null;
+	this.knownPackageNames = null;
+	this.accessRuleSet = accessRuleSet;
+}
+
+ClasspathJar(String zipFilename, long lastModified, AccessRuleSet accessRuleSet) {
+	this.zipFilename = zipFilename;
+	this.lastModified = lastModified;
+	this.zipFile = null;
+	this.knownPackageNames = null;
+	this.accessRuleSet = accessRuleSet;
+}
+
+public ClasspathJar(ZipFile zipFile, AccessRuleSet accessRuleSet) {
+	this.zipFilename = zipFile.getName();
+	this.zipFile = zipFile;
+	this.closeZipFileAtEnd = false;
+	this.knownPackageNames = null;
+	this.accessRuleSet = accessRuleSet;
+}
+
+public void cleanup() {
+	if (this.zipFile != null && this.closeZipFileAtEnd) {
+		try {
+			this.zipFile.close();
+		} catch(IOException e) { // ignore it
+		}
+		this.zipFile = null;
+	}
+	this.knownPackageNames = null;
+}
+
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof ClasspathJar)) return false;
+
+	ClasspathJar jar = (ClasspathJar) o;
+	if (this.accessRuleSet != jar.accessRuleSet)
+		if (this.accessRuleSet == null || !this.accessRuleSet.equals(jar.accessRuleSet))
+			return false;
+	return this.zipFilename.equals(jar.zipFilename) && lastModified() == jar.lastModified();
+}
+
+public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName) {
+	if (!isPackage(qualifiedPackageName)) return null; // most common case
+
+	try {
+		ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
+		if (reader != null) {
+			if (this.accessRuleSet == null)
+				return new NameEnvironmentAnswer(reader, null);
+			String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+			return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()));
+		}
+	} catch (IOException e) { // treat as if class file is missing
+	} catch (ClassFormatException e) { // treat as if class file is missing
+	}
+	return null;
+}
+
+public IPath getProjectRelativePath() {
+	if (this.resource == null) return null;
+	return	this.resource.getProjectRelativePath();
+}
+
+public int hashCode() {
+	return this.zipFilename == null ? super.hashCode() : this.zipFilename.hashCode();
+}
+
+public boolean isPackage(String qualifiedPackageName) {
+	if (this.knownPackageNames != null)
+		return this.knownPackageNames.includes(qualifiedPackageName);
+
+	try {
+		if (this.zipFile == null) {
+			if (org.eclipse.jdt.internal.core.JavaModelManager.ZIP_ACCESS_VERBOSE) {
+				System.out.println("(" + Thread.currentThread() + ") [ClasspathJar.isPackage(String)] Creating ZipFile on " + this.zipFilename); //$NON-NLS-1$	//$NON-NLS-2$
+			}
+			this.zipFile = new ZipFile(this.zipFilename);
+			this.closeZipFileAtEnd = true;
+		}
+		this.knownPackageNames = findPackageSet(this);
+	} catch(Exception e) {
+		this.knownPackageNames = new SimpleSet(); // assume for this build the zipFile is empty
+	}
+	return this.knownPackageNames.includes(qualifiedPackageName);
+}
+
+public long lastModified() {
+	if (this.lastModified == 0)
+		this.lastModified = new File(this.zipFilename).lastModified();
+	return this.lastModified;
+}
+
+public String toString() {
+	String start = "Classpath jar file " + this.zipFilename; //$NON-NLS-1$
+	if (this.accessRuleSet == null)
+		return start;
+	return start + " with " + this.accessRuleSet; //$NON-NLS-1$
+}
+
+public String debugPathString() {
+	long time = lastModified();
+	if (time == 0)
+		return this.zipFilename;
+	return this.zipFilename + '(' + (new Date(time)) + " : " + time + ')'; //$NON-NLS-1$
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
new file mode 100644
index 0000000..aef33e1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+
+public abstract class ClasspathLocation {
+
+static ClasspathLocation forSourceFolder(IContainer sourceFolder, IContainer outputFolder, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean ignoreOptionalProblems) {
+	return new ClasspathMultiDirectory(sourceFolder, outputFolder, inclusionPatterns, exclusionPatterns, ignoreOptionalProblems);
+}
+
+public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder, AccessRuleSet accessRuleSet) {
+	return new ClasspathDirectory(binaryFolder, isOutputFolder, accessRuleSet);
+}
+
+static ClasspathLocation forLibrary(String libraryPathname, long lastModified, AccessRuleSet accessRuleSet) {
+	return new ClasspathJar(libraryPathname, lastModified, accessRuleSet);
+}
+
+static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRuleSet) {
+	return forLibrary(libraryPathname, 0, accessRuleSet);
+}
+
+static ClasspathLocation forLibrary(IFile library, AccessRuleSet accessRuleSet) {
+	return new ClasspathJar(library, accessRuleSet);
+}
+
+public abstract NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName);
+
+public abstract IPath getProjectRelativePath();
+
+public boolean isOutputFolder() {
+	return false;
+}
+
+public abstract boolean isPackage(String qualifiedPackageName);
+
+public void cleanup() {
+	// free anything which is not required when the state is saved
+}
+public void reset() {
+	// reset any internal caches before another compile loop starts
+}
+
+public abstract String debugPathString();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
new file mode 100644
index 0000000..3d41e08
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathMultiDirectory extends ClasspathDirectory {
+
+IContainer sourceFolder;
+char[][] inclusionPatterns; // used by builders when walking source folders
+char[][] exclusionPatterns; // used by builders when walking source folders
+boolean hasIndependentOutputFolder; // if output folder is not equal to any of the source folders
+public boolean ignoreOptionalProblems;
+
+ClasspathMultiDirectory(IContainer sourceFolder, IContainer binaryFolder, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean ignoreOptionalProblems) {
+	super(binaryFolder, true, null);
+
+	this.sourceFolder = sourceFolder;
+	this.inclusionPatterns = inclusionPatterns;
+	this.exclusionPatterns = exclusionPatterns;
+	this.hasIndependentOutputFolder = false;
+	this.ignoreOptionalProblems = ignoreOptionalProblems;
+
+	// handle the case when a state rebuilds a source folder
+	if (this.inclusionPatterns != null && this.inclusionPatterns.length == 0)
+		this.inclusionPatterns = null;
+	if (this.exclusionPatterns != null && this.exclusionPatterns.length == 0)
+		this.exclusionPatterns = null;
+}
+
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof ClasspathMultiDirectory)) return false;
+
+	ClasspathMultiDirectory md = (ClasspathMultiDirectory) o;
+	return this.ignoreOptionalProblems == md.ignoreOptionalProblems 
+		&& this.sourceFolder.equals(md.sourceFolder) && this.binaryFolder.equals(md.binaryFolder)
+		&& CharOperation.equals(this.inclusionPatterns, md.inclusionPatterns)
+		&& CharOperation.equals(this.exclusionPatterns, md.exclusionPatterns);
+}
+
+protected boolean isExcluded(IResource resource) {
+	if (this.exclusionPatterns != null || this.inclusionPatterns != null)
+		if (this.sourceFolder.equals(this.binaryFolder))
+			return Util.isExcluded(resource, this.inclusionPatterns, this.exclusionPatterns);
+	return false;
+}
+
+public String toString() {
+	return "Source classpath directory " + this.sourceFolder.getFullPath().toString() + //$NON-NLS-1$
+		" with " + super.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/CompilationParticipantResult.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/CompilationParticipantResult.java
new file mode 100644
index 0000000..a399712
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/CompilationParticipantResult.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    IBM - rewrote spec
+ *
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.core.compiler.*;
+
+public class CompilationParticipantResult extends BuildContext {
+	protected SourceFile sourceFile;
+	protected boolean hasAnnotations; // only set during processAnnotations
+	protected IFile[] addedFiles; // added/changed generated source files that need to be compiled
+	protected IFile[] deletedFiles; // previously generated source files that should be deleted
+	protected CategorizedProblem[] problems; // new problems to report against this compilationUnit
+	protected String[] dependencies; // fully-qualified type names of any new dependencies, each name is of the form 'p1.p2.A.B'
+
+protected CompilationParticipantResult(SourceFile sourceFile) {
+	this.sourceFile = sourceFile;
+	this.hasAnnotations = false;
+	this.addedFiles = null;
+	this.deletedFiles = null;
+	this.problems = null;
+	this.dependencies = null;
+}
+
+/**
+ * Returns the contents of the compilation unit.
+ *
+ * @return the contents of the compilation unit
+ */
+public char[] getContents() {
+	return this.sourceFile.getContents();
+}
+
+/**
+ * Returns the <code>IFile</code> representing the compilation unit.
+ *
+ * @return the <code>IFile</code> representing the compilation unit
+ */
+public IFile getFile() {
+	return this.sourceFile.resource;
+}
+
+/**
+ * Returns whether the compilation unit contained any annotations when it was compiled.
+ *
+ * NOTE: This is only valid during {@link CompilationParticipant#processAnnotations(BuildContext[])}.
+ *
+ * @return whether the compilation unit contained any annotations when it was compiled
+ */
+public boolean hasAnnotations() {
+	return this.hasAnnotations; // only set during processAnnotations
+}
+
+/**
+ * Record the added/changed generated files that need to be compiled.
+ *
+ * @param addedGeneratedFiles the added/changed files
+ */
+public void recordAddedGeneratedFiles(IFile[] addedGeneratedFiles) {
+	int length2 = addedGeneratedFiles.length;
+	if (length2 == 0) return;
+
+	int length1 = this.addedFiles == null ? 0 : this.addedFiles.length;
+	IFile[] merged = new IFile[length1 + length2];
+	if (length1 > 0) // always make a copy even if currently empty
+		System.arraycopy(this.addedFiles, 0, merged, 0, length1);
+	System.arraycopy(addedGeneratedFiles, 0, merged, length1, length2);
+	this.addedFiles = merged;
+}
+
+/**
+ * Record the generated files that need to be deleted.
+ *
+ * @param deletedGeneratedFiles the files that need to be deleted
+ */
+public void recordDeletedGeneratedFiles(IFile[] deletedGeneratedFiles) {
+	int length2 = deletedGeneratedFiles.length;
+	if (length2 == 0) return;
+
+	int length1 = this.deletedFiles == null ? 0 : this.deletedFiles.length;
+	IFile[] merged = new IFile[length1 + length2];
+	if (length1 > 0) // always make a copy even if currently empty
+		System.arraycopy(this.deletedFiles, 0, merged, 0, length1);
+	System.arraycopy(deletedGeneratedFiles, 0, merged, length1, length2);
+	this.deletedFiles = merged;
+}
+
+/**
+ * Record the fully-qualified type names of any new dependencies, each name is of the form "p1.p2.A.B".
+ *
+ * @param typeNameDependencies the fully-qualified type names of new dependencies
+ */
+public void recordDependencies(String[] typeNameDependencies) {
+	int length2 = typeNameDependencies.length;
+	if (length2 == 0) return;
+
+	int length1 = this.dependencies == null ? 0 : this.dependencies.length;
+	String[] merged = new String[length1 + length2];
+	if (length1 > 0) // always make a copy even if currently empty
+		System.arraycopy(this.dependencies, 0, merged, 0, length1);
+	System.arraycopy(typeNameDependencies, 0, merged, length1, length2);
+	this.dependencies = merged;
+}
+
+/**
+ * Record new problems to report against this compilationUnit.
+ * Markers are persisted for these problems only for the declared managed marker type
+ * (see the 'compilationParticipant' extension point).
+ *
+ * @param newProblems the problems to report
+ */
+public void recordNewProblems(CategorizedProblem[] newProblems) {
+	int length2 = newProblems.length;
+	if (length2 == 0) return;
+
+	int length1 = this.problems == null ? 0 : this.problems.length;
+	CategorizedProblem[] merged = new CategorizedProblem[length1 + length2];
+	if (length1 > 0) // always make a copy even if currently empty
+		System.arraycopy(this.problems, 0, merged, 0, length1);
+	System.arraycopy(newProblems, 0, merged, length1, length2);
+	this.problems = merged;
+}
+
+void reset(boolean detectedAnnotations) {
+	// called prior to processAnnotations
+	this.hasAnnotations = detectedAnnotations;
+	this.addedFiles = null;
+	this.deletedFiles = null;
+	this.problems = null;
+	this.dependencies = null;
+}
+
+public String toString() {
+	return this.sourceFile.toString();
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ICompilationUnitLocator.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ICompilationUnitLocator.java
new file mode 100644
index 0000000..aea9f0e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ICompilationUnitLocator.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    wharley@bea.com - initial API and implementation
+ *
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+
+/**
+ * Used to convert an IFile into an ICompilationUnit,
+ * for clients outside of this package.
+ * @since 3.3
+ */
+public interface ICompilationUnitLocator {
+	public ICompilationUnit fromIFile(IFile file);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java
new file mode 100644
index 0000000..e59cb11
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * Exception thrown when there is an internal error in the image builder.
+ * May wrapper another exception.
+ */
+public class ImageBuilderInternalException extends RuntimeException {
+
+private static final long serialVersionUID = 28252254530437336L; // backward compatible
+protected CoreException coreException;
+
+public ImageBuilderInternalException(CoreException e) {
+	this.coreException = e;
+}
+
+public CoreException getThrowable() {
+	return this.coreException;
+}
+
+public void printStackTrace() {
+	if (this.coreException != null) {
+		System.err.println(this);
+		System.err.println("Stack trace of embedded core exception:"); //$NON-NLS-1$
+		this.coreException.printStackTrace();
+	} else {
+		super.printStackTrace();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
new file mode 100644
index 0000000..a7e07fd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
@@ -0,0 +1,948 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.*;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+
+/**
+ * The incremental image builder
+ */
+public class IncrementalImageBuilder extends AbstractImageBuilder {
+
+protected ArrayList sourceFiles;
+protected ArrayList previousSourceFiles;
+protected StringSet qualifiedStrings;
+protected StringSet simpleStrings;
+protected StringSet rootStrings;
+protected SimpleLookupTable secondaryTypesToRemove;
+protected boolean hasStructuralChanges;
+protected int compileLoop;
+protected boolean makeOutputFolderConsistent;
+
+public static int MaxCompileLoop = 5; // perform a full build if it takes more than ? incremental compile loops
+
+protected IncrementalImageBuilder(JavaBuilder javaBuilder, State buildState) {
+	super(javaBuilder, true, buildState);
+	this.nameEnvironment.isIncrementalBuild = true;
+	this.makeOutputFolderConsistent = JavaCore.ENABLED.equals(
+		javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_RECREATE_MODIFIED_CLASS_FILES_IN_OUTPUT_FOLDER, true));
+}
+
+protected IncrementalImageBuilder(JavaBuilder javaBuilder) {
+	this(javaBuilder, null);
+	this.newState.copyFrom(javaBuilder.lastState);
+}
+
+protected IncrementalImageBuilder(BatchImageBuilder batchBuilder) {
+	this(batchBuilder.javaBuilder, batchBuilder.newState);
+	resetCollections();
+}
+
+public boolean build(SimpleLookupTable deltas) {
+	// initialize builder
+	// walk this project's deltas, find changed source files
+	// walk prereq projects' deltas, find changed class files & add affected source files
+	//   use the build state # to skip the deltas for certain prereq projects
+	//   ignore changed zip/jar files since they caused a full build
+	// compile the source files & acceptResult()
+	// compare the produced class files against the existing ones on disk
+	// recompile all dependent source files of any type with structural changes or new/removed secondary type
+	// keep a loop counter to abort & perform a full build
+
+	if (JavaBuilder.DEBUG)
+		System.out.println("INCREMENTAL build"); //$NON-NLS-1$
+
+	try {
+		resetCollections();
+
+		this.notifier.subTask(Messages.build_analyzingDeltas);
+		if (this.javaBuilder.hasBuildpathErrors()) {
+			// if a mssing class file was detected in the last build, a build state was saved since its no longer fatal
+			// but we need to rebuild every source file since problems were not recorded
+			// AND to avoid the infinite build scenario if this project is involved in a cycle, see bug 160550
+			// we need to avoid unnecessary deltas caused by doing a full build in this case
+			if (JavaBuilder.DEBUG)
+				System.out.println("COMPILING all source files since the buildpath has errors "); //$NON-NLS-1$
+			this.javaBuilder.currentProject.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+			addAllSourceFiles(this.sourceFiles);
+			this.notifier.updateProgressDelta(0.25f);
+		} else {
+			IResourceDelta sourceDelta = (IResourceDelta) deltas.get(this.javaBuilder.currentProject);
+			if (sourceDelta != null)
+				if (!findSourceFiles(sourceDelta)) return false;
+			this.notifier.updateProgressDelta(0.10f);
+
+			Object[] keyTable = deltas.keyTable;
+			Object[] valueTable = deltas.valueTable;
+			for (int i = 0, l = valueTable.length; i < l; i++) {
+				IResourceDelta delta = (IResourceDelta) valueTable[i];
+				if (delta != null) {
+					IProject p = (IProject) keyTable[i];
+					ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) this.javaBuilder.binaryLocationsPerProject.get(p);
+					if (classFoldersAndJars != null)
+						if (!findAffectedSourceFiles(delta, classFoldersAndJars, p)) return false;
+				}
+			}
+			this.notifier.updateProgressDelta(0.10f);
+
+			this.notifier.subTask(Messages.build_analyzingSources);
+			addAffectedSourceFiles();
+			this.notifier.updateProgressDelta(0.05f);
+		}
+
+		this.compileLoop = 0;
+		float increment = 0.40f;
+		while (this.sourceFiles.size() > 0) { // added to in acceptResult
+			if (++this.compileLoop > MaxCompileLoop) {
+				if (JavaBuilder.DEBUG)
+					System.out.println("ABORTING incremental build... exceeded loop count"); //$NON-NLS-1$
+				return false;
+			}
+			this.notifier.checkCancel();
+
+			SourceFile[] allSourceFiles = new SourceFile[this.sourceFiles.size()];
+			this.sourceFiles.toArray(allSourceFiles);
+			resetCollections();
+
+			this.workQueue.addAll(allSourceFiles);
+			this.notifier.setProgressPerCompilationUnit(increment / allSourceFiles.length);
+			increment = increment / 2;
+			compile(allSourceFiles);
+			removeSecondaryTypes();
+			addAffectedSourceFiles();
+		}
+		if (this.hasStructuralChanges && this.javaBuilder.javaProject.hasCycleMarker())
+			this.javaBuilder.mustPropagateStructuralChanges();
+	} catch (AbortIncrementalBuildException e) {
+		// abort the incremental build and let the batch builder handle the problem
+		if (JavaBuilder.DEBUG)
+			System.out.println("ABORTING incremental build... problem with " + e.qualifiedTypeName + //$NON-NLS-1$
+				". Likely renamed inside its existing source file."); //$NON-NLS-1$
+		return false;
+	} catch (CoreException e) {
+		throw internalException(e);
+	} finally {
+		cleanUp();
+	}
+	return true;
+}
+
+protected void buildAfterBatchBuild() {
+	// called from a batch builder once all source files have been compiled AND some changes
+	// need to be propagated incrementally (annotations, missing secondary types)
+
+	if (JavaBuilder.DEBUG)
+		System.out.println("INCREMENTAL build after batch build @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+
+	// this is a copy of the incremental build loop
+	try {
+		addAffectedSourceFiles();
+		while (this.sourceFiles.size() > 0) {
+			this.notifier.checkCancel();
+			SourceFile[] allSourceFiles = new SourceFile[this.sourceFiles.size()];
+			this.sourceFiles.toArray(allSourceFiles);
+			resetCollections();
+			this.notifier.setProgressPerCompilationUnit(0.08f / allSourceFiles.length);
+			this.workQueue.addAll(allSourceFiles);
+			compile(allSourceFiles);
+			removeSecondaryTypes();
+			addAffectedSourceFiles();
+		}
+	} catch (CoreException e) {
+		throw internalException(e);
+	} finally {
+		cleanUp();
+	}
+}
+
+protected void addAffectedSourceFiles() {
+	if (this.qualifiedStrings.elementSize == 0 && this.simpleStrings.elementSize == 0) return;
+
+	addAffectedSourceFiles(this.qualifiedStrings, this.simpleStrings, this.rootStrings, null);
+}
+
+protected void addAffectedSourceFiles(StringSet qualifiedSet, StringSet simpleSet, StringSet rootSet, StringSet affectedTypes) {
+	// the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
+	char[][][] internedQualifiedNames = ReferenceCollection.internQualifiedNames(qualifiedSet);
+	// if a well known qualified name was found then we can skip over these
+	if (internedQualifiedNames.length < qualifiedSet.elementSize)
+		internedQualifiedNames = null;
+	char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(simpleSet, true);
+	// if a well known name was found then we can skip over these
+	if (internedSimpleNames.length < simpleSet.elementSize)
+		internedSimpleNames = null;
+	char[][] internedRootNames = ReferenceCollection.internSimpleNames(rootSet, false);
+
+	Object[] keyTable = this.newState.references.keyTable;
+	Object[] valueTable = this.newState.references.valueTable;
+	next : for (int i = 0, l = valueTable.length; i < l; i++) {
+		String typeLocator = (String) keyTable[i];
+		if (typeLocator != null) {
+			if (affectedTypes != null && !affectedTypes.includes(typeLocator)) continue next;
+			ReferenceCollection refs = (ReferenceCollection) valueTable[i];
+			if (refs.includes(internedQualifiedNames, internedSimpleNames, internedRootNames)) {
+				IFile file = this.javaBuilder.currentProject.getFile(typeLocator);
+				SourceFile sourceFile = findSourceFile(file, true);
+				if (sourceFile == null) continue next;
+				if (this.sourceFiles.contains(sourceFile)) continue next;
+				if (this.compiledAllAtOnce && this.previousSourceFiles != null && this.previousSourceFiles.contains(sourceFile))
+					continue next; // can skip previously compiled files since already saw hierarchy related problems
+
+				if (JavaBuilder.DEBUG)
+					System.out.println("  adding affected source file " + typeLocator); //$NON-NLS-1$
+				this.sourceFiles.add(sourceFile);
+			}
+		}
+	}
+}
+
+protected void addDependentsOf(IPath path, boolean isStructuralChange) {
+	addDependentsOf(path, isStructuralChange, this.qualifiedStrings, this.simpleStrings, this.rootStrings);
+}
+
+protected void addDependentsOf(IPath path, boolean isStructuralChange, StringSet qualifiedNames, StringSet simpleNames, StringSet rootNames) {
+	path = path.setDevice(null);
+	if (isStructuralChange) {
+		String last = path.lastSegment();
+		if (last.length() == TypeConstants.PACKAGE_INFO_NAME.length)
+			if (CharOperation.equals(last.toCharArray(), TypeConstants.PACKAGE_INFO_NAME)) {
+				path = path.removeLastSegments(1); // the package-info file has changed so blame the package itself
+				/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=323785, in the case of default package,
+				   there is no need to blame the package itself as there can be no annotations or documentation
+				   comment tags in the package-info file that can influence the rest of the package. Just bail out
+				   so we don't touch null objects below.
+				 */
+				if (path.isEmpty())
+					return;
+			}
+	}
+
+	if (isStructuralChange && !this.hasStructuralChanges) {
+		this.newState.tagAsStructurallyChanged();
+		this.hasStructuralChanges = true;
+	}
+	// the qualifiedStrings are of the form 'p1/p2' & the simpleStrings are just 'X'
+	rootNames.add(path.segment(0));
+	String packageName = path.removeLastSegments(1).toString();
+	boolean wasNew = qualifiedNames.add(packageName);
+	String typeName = path.lastSegment();
+	int memberIndex = typeName.indexOf('$');
+	if (memberIndex > 0)
+		typeName = typeName.substring(0, memberIndex);
+	wasNew = simpleNames.add(typeName) | wasNew;
+	if (wasNew && JavaBuilder.DEBUG)
+		System.out.println("  will look for dependents of " //$NON-NLS-1$
+			+ typeName + " in " + packageName); //$NON-NLS-1$
+}
+
+protected boolean checkForClassFileChanges(IResourceDelta binaryDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
+	IResource resource = binaryDelta.getResource();
+	// remember that if inclusion & exclusion patterns change then a full build is done
+	boolean isExcluded = (md.exclusionPatterns != null || md.inclusionPatterns != null)
+		&& Util.isExcluded(resource, md.inclusionPatterns, md.exclusionPatterns);
+	switch(resource.getType()) {
+		case IResource.FOLDER :
+			if (isExcluded && md.inclusionPatterns == null)
+		        return true; // no need to go further with this delta since its children cannot be included
+
+			IResourceDelta[] children = binaryDelta.getAffectedChildren();
+			for (int i = 0, l = children.length; i < l; i++)
+				if (!checkForClassFileChanges(children[i], md, segmentCount))
+					return false;
+			return true;
+		case IResource.FILE :
+			if (!isExcluded && org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(resource.getName())) {
+				// perform full build if a managed class file has been changed
+				IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
+				if (this.newState.isKnownType(typePath.toString())) {
+					if (JavaBuilder.DEBUG)
+						System.out.println("MUST DO FULL BUILD. Found change to class file " + typePath); //$NON-NLS-1$
+					return false;
+				}
+				return true;
+			}
+	}
+	return true;
+}
+
+protected void cleanUp() {
+	super.cleanUp();
+
+	this.sourceFiles = null;
+	this.previousSourceFiles = null;
+	this.qualifiedStrings = null;
+	this.simpleStrings = null;
+	this.rootStrings = null;
+	this.secondaryTypesToRemove = null;
+	this.hasStructuralChanges = false;
+	this.compileLoop = 0;
+}
+
+protected void compile(SourceFile[] units, SourceFile[] additionalUnits, boolean compilingFirstGroup) {
+	if (compilingFirstGroup && additionalUnits != null) {
+		// add any source file from additionalUnits to units if it defines secondary types
+		// otherwise its possible during testing with MAX_AT_ONCE == 1 that a secondary type
+		// can cause an infinite loop as it alternates between not found and defined, see bug 146324
+		ArrayList extras = null;
+		for (int i = 0, l = additionalUnits.length; i < l; i++) {
+			SourceFile unit = additionalUnits[i];
+			if (unit != null && this.newState.getDefinedTypeNamesFor(unit.typeLocator()) != null) {
+				if (JavaBuilder.DEBUG)
+					System.out.println("About to compile file with secondary types "+ unit.typeLocator()); //$NON-NLS-1$
+				if (extras == null)
+					extras = new ArrayList(3);
+				extras.add(unit);
+			}
+		}
+		if (extras != null) {
+			int oldLength = units.length;
+			int toAdd = extras.size();
+			System.arraycopy(units, 0, units = new SourceFile[oldLength + toAdd], 0, oldLength);
+			for (int i = 0; i < toAdd; i++)
+				units[oldLength++] = (SourceFile) extras.get(i);
+		}
+	}
+	super.compile(units, additionalUnits, compilingFirstGroup);
+}
+
+protected void deleteGeneratedFiles(IFile[] deletedGeneratedFiles) {
+	// delete generated files and recompile any affected source files
+	try {
+		for (int j = deletedGeneratedFiles.length; --j >= 0;) {
+			IFile deletedFile = deletedGeneratedFiles[j];
+			if (deletedFile.exists()) continue; // only delete .class files for source files that were actually deleted
+
+			SourceFile sourceFile = findSourceFile(deletedFile, false);
+			String typeLocator = sourceFile.typeLocator();
+			int mdSegmentCount = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount();
+			IPath typePath = sourceFile.resource.getFullPath().removeFirstSegments(mdSegmentCount).removeFileExtension();
+			addDependentsOf(typePath, true); // add dependents of the source file since its now deleted
+			this.previousSourceFiles = null; // existing source files did not see it as deleted since they were compiled before it was
+			char[][] definedTypeNames = this.newState.getDefinedTypeNamesFor(typeLocator);
+			if (definedTypeNames == null) { // defined a single type matching typePath
+				removeClassFile(typePath, sourceFile.sourceLocation.binaryFolder);
+			} else {
+				if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type
+					IPath packagePath = typePath.removeLastSegments(1);
+					for (int d = 0, l = definedTypeNames.length; d < l; d++)
+						removeClassFile(packagePath.append(new String(definedTypeNames[d])), sourceFile.sourceLocation.binaryFolder);
+				}
+			}
+			this.newState.removeLocator(typeLocator);
+		}
+	} catch (CoreException e) {
+		// must continue with compile loop so just log the CoreException
+		Util.log(e, "JavaBuilder logging CompilationParticipant's CoreException to help debugging"); //$NON-NLS-1$
+	}
+}
+
+protected boolean findAffectedSourceFiles(IResourceDelta delta, ClasspathLocation[] classFoldersAndJars, IProject prereqProject) {
+	for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
+		ClasspathLocation bLocation = classFoldersAndJars[i];
+		// either a .class file folder or a zip/jar file
+		if (bLocation != null) { // skip unchanged output folder
+			IPath p = bLocation.getProjectRelativePath();
+			if (p != null) {
+				IResourceDelta binaryDelta = delta.findMember(p);
+				if (binaryDelta != null) {
+					if (bLocation instanceof ClasspathJar) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("ABORTING incremental build... found delta to jar/zip file"); //$NON-NLS-1$
+						return false; // do full build since jar file was changed (added/removed were caught as classpath change)
+					}
+					if (binaryDelta.getKind() == IResourceDelta.ADDED || binaryDelta.getKind() == IResourceDelta.REMOVED) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("ABORTING incremental build... found added/removed binary folder"); //$NON-NLS-1$
+						return false; // added/removed binary folder should not make it here (classpath change), but handle anyways
+					}
+					int segmentCount = binaryDelta.getFullPath().segmentCount();
+					IResourceDelta[] children = binaryDelta.getAffectedChildren(); // .class files from class folder
+					StringSet structurallyChangedTypes = null;
+					if (bLocation.isOutputFolder())
+						structurallyChangedTypes = this.newState.getStructurallyChangedTypes(this.javaBuilder.getLastState(prereqProject));
+					for (int j = 0, m = children.length; j < m; j++)
+						findAffectedSourceFiles(children[j], segmentCount, structurallyChangedTypes);
+					this.notifier.checkCancel();
+				}
+			}
+		}
+	}
+	return true;
+}
+
+protected void findAffectedSourceFiles(IResourceDelta binaryDelta, int segmentCount, StringSet structurallyChangedTypes) {
+	// When a package becomes a type or vice versa, expect 2 deltas,
+	// one on the folder & one on the class file
+	IResource resource = binaryDelta.getResource();
+	switch(resource.getType()) {
+		case IResource.FOLDER :
+			switch (binaryDelta.getKind()) {
+				case IResourceDelta.ADDED :
+				case IResourceDelta.REMOVED :
+					IPath packagePath = resource.getFullPath().removeFirstSegments(segmentCount);
+					String packageName = packagePath.toString();
+					if (binaryDelta.getKind() == IResourceDelta.ADDED) {
+						// see if any known source file is from the same package... classpath already includes new package
+						if (!this.newState.isKnownPackage(packageName)) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Found added package " + packageName); //$NON-NLS-1$
+							addDependentsOf(packagePath, false);
+							return;
+						}
+						if (JavaBuilder.DEBUG)
+							System.out.println("Skipped dependents of added package " + packageName); //$NON-NLS-1$
+					} else {
+						// see if the package still exists on the classpath
+						if (!this.nameEnvironment.isPackage(packageName)) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Found removed package " + packageName); //$NON-NLS-1$
+							addDependentsOf(packagePath, false);
+							return;
+						}
+						if (JavaBuilder.DEBUG)
+							System.out.println("Skipped dependents of removed package " + packageName); //$NON-NLS-1$
+					}
+					//$FALL-THROUGH$ traverse the sub-packages and .class files
+				case IResourceDelta.CHANGED :
+					IResourceDelta[] children = binaryDelta.getAffectedChildren();
+					for (int i = 0, l = children.length; i < l; i++)
+						findAffectedSourceFiles(children[i], segmentCount, structurallyChangedTypes);
+			}
+			return;
+		case IResource.FILE :
+			if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(resource.getName())) {
+				IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
+				switch (binaryDelta.getKind()) {
+					case IResourceDelta.ADDED :
+					case IResourceDelta.REMOVED :
+						if (JavaBuilder.DEBUG)
+							System.out.println("Found added/removed class file " + typePath); //$NON-NLS-1$
+						addDependentsOf(typePath, false);
+						return;
+					case IResourceDelta.CHANGED :
+						if ((binaryDelta.getFlags() & IResourceDelta.CONTENT) == 0)
+							return; // skip it since it really isn't changed
+						if (structurallyChangedTypes != null && !structurallyChangedTypes.includes(typePath.toString()))
+							return; // skip since it wasn't a structural change
+						if (JavaBuilder.DEBUG)
+							System.out.println("Found changed class file " + typePath); //$NON-NLS-1$
+						addDependentsOf(typePath, false);
+				}
+				return;
+			}
+	}
+}
+
+protected boolean findSourceFiles(IResourceDelta delta) throws CoreException {
+	ArrayList visited = this.makeOutputFolderConsistent ? new ArrayList(this.sourceLocations.length) : null;
+	for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+		ClasspathMultiDirectory md = this.sourceLocations[i];
+		if (this.makeOutputFolderConsistent && md.hasIndependentOutputFolder && !visited.contains(md.binaryFolder)) {
+			// even a project which acts as its own source folder can have an independent/nested output folder
+			visited.add(md.binaryFolder);
+			IResourceDelta binaryDelta = delta.findMember(md.binaryFolder.getProjectRelativePath());
+			if (binaryDelta != null) {
+				int segmentCount = binaryDelta.getFullPath().segmentCount();
+				IResourceDelta[] children = binaryDelta.getAffectedChildren();
+				for (int j = 0, m = children.length; j < m; j++)
+					if (!checkForClassFileChanges(children[j], md, segmentCount))
+						return false;
+			}
+		}
+		if (md.sourceFolder.equals(this.javaBuilder.currentProject)) {
+			// skip nested source & output folders when the project is a source folder
+			int segmentCount = delta.getFullPath().segmentCount();
+			IResourceDelta[] children = delta.getAffectedChildren();
+			for (int j = 0, m = children.length; j < m; j++)
+				if (!isExcludedFromProject(children[j].getFullPath()))
+					if (!findSourceFiles(children[j], md, segmentCount))
+						return false;
+		} else {
+			IResourceDelta sourceDelta = delta.findMember(md.sourceFolder.getProjectRelativePath());
+			if (sourceDelta != null) {
+				if (sourceDelta.getKind() == IResourceDelta.REMOVED) {
+					if (JavaBuilder.DEBUG)
+						System.out.println("ABORTING incremental build... found removed source folder"); //$NON-NLS-1$
+					return false; // removed source folder should not make it here, but handle anyways (ADDED is supported)
+				}
+				int segmentCount = sourceDelta.getFullPath().segmentCount();
+				IResourceDelta[] children = sourceDelta.getAffectedChildren();
+				try {
+					for (int j = 0, m = children.length; j < m; j++)
+						if (!findSourceFiles(children[j], md, segmentCount))
+							return false;
+				} catch (CoreException e) {
+					// catch the case that a package has been renamed and collides on disk with an as-yet-to-be-deleted package
+					if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("ABORTING incremental build... found renamed package"); //$NON-NLS-1$
+						return false;
+					}
+					throw e; // rethrow
+				}
+			}
+		}
+		this.notifier.checkCancel();
+	}
+	return true;
+}
+
+protected boolean findSourceFiles(IResourceDelta sourceDelta, ClasspathMultiDirectory md, int segmentCount) throws CoreException {
+	// When a package becomes a type or vice versa, expect 2 deltas,
+	// one on the folder & one on the source file
+	IResource resource = sourceDelta.getResource();
+	// remember that if inclusion & exclusion patterns change then a full build is done
+	boolean isExcluded = (md.exclusionPatterns != null || md.inclusionPatterns != null)
+		&& Util.isExcluded(resource, md.inclusionPatterns, md.exclusionPatterns);
+	switch(resource.getType()) {
+		case IResource.FOLDER :
+			if (isExcluded && md.inclusionPatterns == null)
+		        return true; // no need to go further with this delta since its children cannot be included
+
+			switch (sourceDelta.getKind()) {
+				case IResourceDelta.ADDED :
+				    if (!isExcluded) {
+						IPath addedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
+						createFolder(addedPackagePath, md.binaryFolder); // ensure package exists in the output folder
+						// see if any known source file is from the same package... classpath already includes new package
+						if (this.sourceLocations.length > 1 && this.newState.isKnownPackage(addedPackagePath.toString())) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Skipped dependents of added package " + addedPackagePath); //$NON-NLS-1$
+						} else {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Found added package " + addedPackagePath); //$NON-NLS-1$
+							addDependentsOf(addedPackagePath, true);
+						}
+				    }
+					//$FALL-THROUGH$ collect all the source files
+				case IResourceDelta.CHANGED :
+					IResourceDelta[] children = sourceDelta.getAffectedChildren();
+					for (int i = 0, l = children.length; i < l; i++)
+						if (!findSourceFiles(children[i], md, segmentCount))
+							return false;
+					return true;
+				case IResourceDelta.REMOVED :
+				    if (isExcluded) {
+				    	// since this folder is excluded then there is nothing to delete (from this md), but must walk any included subfolders
+						children = sourceDelta.getAffectedChildren();
+						for (int i = 0, l = children.length; i < l; i++)
+							if (!findSourceFiles(children[i], md, segmentCount))
+								return false;
+						return true;
+				    }
+					IPath removedPackagePath = resource.getFullPath().removeFirstSegments(segmentCount);
+					if (this.sourceLocations.length > 1) {
+						for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+							if (this.sourceLocations[i].sourceFolder.getFolder(removedPackagePath).exists()) {
+								// only a package fragment was removed, same as removing multiple source files
+								if (md.hasIndependentOutputFolder)
+									createFolder(removedPackagePath, md.binaryFolder); // ensure package exists in the output folder
+								IResourceDelta[] removedChildren = sourceDelta.getAffectedChildren();
+								for (int j = 0, m = removedChildren.length; j < m; j++)
+									if (!findSourceFiles(removedChildren[j], md, segmentCount))
+										return false;
+								return true;
+							}
+						}
+					}
+					if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+						// same idea as moving a source file
+						// see bug 163200
+						IResource movedFolder = this.javaBuilder.workspaceRoot.getFolder(sourceDelta.getMovedToPath());
+						JavaBuilder.removeProblemsAndTasksFor(movedFolder);
+					}
+					IFolder removedPackageFolder = md.binaryFolder.getFolder(removedPackagePath);
+					if (removedPackageFolder.exists())
+						removedPackageFolder.delete(IResource.FORCE, null);
+					// add dependents even when the package thinks it does not exist to be on the safe side
+					if (JavaBuilder.DEBUG)
+						System.out.println("Found removed package " + removedPackagePath); //$NON-NLS-1$
+					addDependentsOf(removedPackagePath, true);
+					this.newState.removePackage(sourceDelta);
+			}
+			return true;
+		case IResource.FILE :
+			if (isExcluded) return true;
+
+			String resourceName = resource.getName();
+			if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)) {
+				IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
+				String typeLocator = resource.getProjectRelativePath().toString();
+				switch (sourceDelta.getKind()) {
+					case IResourceDelta.ADDED :
+						if (JavaBuilder.DEBUG)
+							System.out.println("Compile this added source file " + typeLocator); //$NON-NLS-1$
+						this.sourceFiles.add(new SourceFile((IFile) resource, md, true));
+						String typeName = typePath.toString();
+						if (!this.newState.isDuplicateLocator(typeName, typeLocator)) { // adding dependents results in 2 duplicate errors
+							if (JavaBuilder.DEBUG)
+								System.out.println("Found added source file " + typeName); //$NON-NLS-1$
+							addDependentsOf(typePath, true);
+						}
+						return true;
+					case IResourceDelta.REMOVED :
+						char[][] definedTypeNames = this.newState.getDefinedTypeNamesFor(typeLocator);
+						if (definedTypeNames == null) { // defined a single type matching typePath
+							removeClassFile(typePath, md.binaryFolder);
+							if ((sourceDelta.getFlags() & IResourceDelta.MOVED_TO) != 0) {
+								// remove problems and tasks for a compilation unit that is being moved (to another package or renamed)
+								// if the target file is a compilation unit, the new cu will be recompiled
+								// if the target file is a non-java resource, then markers are removed
+								// see bug 2857
+								IResource movedFile = this.javaBuilder.workspaceRoot.getFile(sourceDelta.getMovedToPath());
+								JavaBuilder.removeProblemsAndTasksFor(movedFile);
+							}
+						} else {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Found removed source file " + typePath.toString()); //$NON-NLS-1$
+							addDependentsOf(typePath, true); // add dependents of the source file since it may be involved in a name collision
+							if (definedTypeNames.length > 0) { // skip it if it failed to successfully define a type
+								IPath packagePath = typePath.removeLastSegments(1);
+								for (int i = 0, l = definedTypeNames.length; i < l; i++)
+									removeClassFile(packagePath.append(new String(definedTypeNames[i])), md.binaryFolder);
+							}
+						}
+						this.newState.removeLocator(typeLocator);
+						return true;
+					case IResourceDelta.CHANGED :
+						if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0
+								&& (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0)
+							return true; // skip it since it really isn't changed
+						if (JavaBuilder.DEBUG)
+							System.out.println("Compile this changed source file " + typeLocator); //$NON-NLS-1$
+						this.sourceFiles.add(new SourceFile((IFile) resource, md, true));
+				}
+				return true;
+			} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(resourceName)) {
+				// perform full build if a managed class file has been changed
+				if (this.makeOutputFolderConsistent) {
+					IPath typePath = resource.getFullPath().removeFirstSegments(segmentCount).removeFileExtension();
+					if (this.newState.isKnownType(typePath.toString())) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("MUST DO FULL BUILD. Found change to class file " + typePath); //$NON-NLS-1$
+						return false;
+					}
+				}
+				return true;
+			} else if (md.hasIndependentOutputFolder) {
+				if (this.javaBuilder.filterExtraResource(resource)) return true;
+
+				// copy all other resource deltas to the output folder
+				IPath resourcePath = resource.getFullPath().removeFirstSegments(segmentCount);
+				IResource outputFile = md.binaryFolder.getFile(resourcePath);
+				switch (sourceDelta.getKind()) {
+					case IResourceDelta.ADDED :
+						if (outputFile.exists()) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
+							outputFile.delete(IResource.FORCE, null);
+						}
+						if (JavaBuilder.DEBUG)
+							System.out.println("Copying added file " + resourcePath); //$NON-NLS-1$
+						createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
+						copyResource(resource, outputFile);
+						return true;
+					case IResourceDelta.REMOVED :
+						if (outputFile.exists()) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Deleting removed file " + resourcePath); //$NON-NLS-1$
+							outputFile.delete(IResource.FORCE, null);
+						}
+						return true;
+					case IResourceDelta.CHANGED :
+						if ((sourceDelta.getFlags() & IResourceDelta.CONTENT) == 0
+								&& (sourceDelta.getFlags() & IResourceDelta.ENCODING) == 0)
+							return true; // skip it since it really isn't changed
+						if (outputFile.exists()) {
+							if (JavaBuilder.DEBUG)
+								System.out.println("Deleting existing file " + resourcePath); //$NON-NLS-1$
+							outputFile.delete(IResource.FORCE, null);
+						}
+						if (JavaBuilder.DEBUG)
+							System.out.println("Copying changed file " + resourcePath); //$NON-NLS-1$
+						createFolder(resourcePath.removeLastSegments(1), md.binaryFolder); // ensure package exists in the output folder
+						copyResource(resource, outputFile);
+				}
+				return true;
+			}
+	}
+	return true;
+}
+
+protected void finishedWith(String sourceLocator, CompilationResult result, char[] mainTypeName, ArrayList definedTypeNames, ArrayList duplicateTypeNames) {
+	char[][] previousTypeNames = this.newState.getDefinedTypeNamesFor(sourceLocator);
+	if (previousTypeNames == null)
+		previousTypeNames = new char[][] {mainTypeName};
+	IPath packagePath = null;
+	next : for (int i = 0, l = previousTypeNames.length; i < l; i++) {
+		char[] previous = previousTypeNames[i];
+		for (int j = 0, m = definedTypeNames.size(); j < m; j++)
+			if (CharOperation.equals(previous, (char[]) definedTypeNames.get(j)))
+				continue next;
+
+		SourceFile sourceFile = (SourceFile) result.getCompilationUnit();
+		if (packagePath == null) {
+			int count = sourceFile.sourceLocation.sourceFolder.getFullPath().segmentCount();
+			packagePath = sourceFile.resource.getFullPath().removeFirstSegments(count).removeLastSegments(1);
+		}
+		if (this.secondaryTypesToRemove == null)
+			this.secondaryTypesToRemove = new SimpleLookupTable();
+		ArrayList types = (ArrayList) this.secondaryTypesToRemove.get(sourceFile.sourceLocation.binaryFolder);
+		if (types == null)
+			types = new ArrayList(definedTypeNames.size());
+		types.add(packagePath.append(new String(previous)));
+		this.secondaryTypesToRemove.put(sourceFile.sourceLocation.binaryFolder, types);
+	}
+	super.finishedWith(sourceLocator, result, mainTypeName, definedTypeNames, duplicateTypeNames);
+}
+
+protected void processAnnotationResults(CompilationParticipantResult[] results) {
+	for (int i = results.length; --i >= 0;) {
+		CompilationParticipantResult result = results[i];
+		if (result == null) continue;
+
+		IFile[] deletedGeneratedFiles = result.deletedFiles;
+		if (deletedGeneratedFiles != null)
+			deleteGeneratedFiles(deletedGeneratedFiles);
+
+		IFile[] addedGeneratedFiles = result.addedFiles;
+		if (addedGeneratedFiles != null) {
+			for (int j = addedGeneratedFiles.length; --j >= 0;) {
+				SourceFile sourceFile = findSourceFile(addedGeneratedFiles[j], true);
+				if (sourceFile != null && !this.sourceFiles.contains(sourceFile))
+					this.sourceFiles.add(sourceFile);
+			}
+		}
+
+		recordParticipantResult(result);
+	}
+}
+
+protected void removeClassFile(IPath typePath, IContainer outputFolder) throws CoreException {
+	if (typePath.lastSegment().indexOf('$') == -1) { // is not a nested type
+		this.newState.removeQualifiedTypeName(typePath.toString());
+		// add dependents even when the type thinks it does not exist to be on the safe side
+		if (JavaBuilder.DEBUG)
+			System.out.println("Found removed type " + typePath); //$NON-NLS-1$
+		addDependentsOf(typePath, true); // when member types are removed, their enclosing type is structurally changed
+	}
+	IFile classFile = outputFolder.getFile(typePath.addFileExtension(SuffixConstants.EXTENSION_class));
+	if (classFile.exists()) {
+		if (JavaBuilder.DEBUG)
+			System.out.println("Deleting class file of removed type " + typePath); //$NON-NLS-1$
+		classFile.delete(IResource.FORCE, null);
+	}
+}
+
+protected void removeSecondaryTypes() throws CoreException {
+	if (this.secondaryTypesToRemove != null) { // delayed deleting secondary types until the end of the compile loop
+		Object[] keyTable = this.secondaryTypesToRemove.keyTable;
+		Object[] valueTable = this.secondaryTypesToRemove.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			IContainer outputFolder = (IContainer) keyTable[i];
+			if (outputFolder != null) {
+				ArrayList paths = (ArrayList) valueTable[i];
+				for (int j = 0, m = paths.size(); j < m; j++)
+					removeClassFile((IPath) paths.get(j), outputFolder);
+			}
+		}
+		this.secondaryTypesToRemove = null;
+		if (this.previousSourceFiles != null)
+			this.previousSourceFiles = null; // cannot optimize recompile case when a secondary type is deleted, see 181269
+	}
+}
+
+protected void resetCollections() {
+	if (this.sourceFiles == null) {
+		this.sourceFiles = new ArrayList(33);
+		this.previousSourceFiles = null;
+		this.qualifiedStrings = new StringSet(3);
+		this.simpleStrings = new StringSet(3);
+		this.rootStrings = new StringSet(3);
+		this.hasStructuralChanges = false;
+		this.compileLoop = 0;
+	} else {
+		this.previousSourceFiles = this.sourceFiles.isEmpty() ? null : (ArrayList) this.sourceFiles.clone();
+
+		this.sourceFiles.clear();
+		this.qualifiedStrings.clear();
+		this.simpleStrings.clear();
+		this.rootStrings.clear();
+		this.workQueue.clear();
+	}
+}
+
+protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
+	if (CharOperation.equals(sourceFile.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
+		IResource pkgResource = sourceFile.resource.getParent();
+		pkgResource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+	}
+	IMarker[] markers = JavaBuilder.getProblemsFor(sourceFile.resource);
+	CategorizedProblem[] problems = result.getProblems();
+	if (problems == null && markers.length == 0) return;
+
+	this.notifier.updateProblemCounts(markers, problems);
+	JavaBuilder.removeProblemsFor(sourceFile.resource);
+	storeProblemsFor(sourceFile, problems);
+}
+
+protected void updateTasksFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
+	IMarker[] markers = JavaBuilder.getTasksFor(sourceFile.resource);
+	CategorizedProblem[] tasks = result.getTasks();
+	if (tasks == null && markers.length == 0) return;
+
+	JavaBuilder.removeTasksFor(sourceFile.resource);
+	storeTasksFor(sourceFile, tasks);
+}
+
+/**
+ * @see org.eclipse.jdt.internal.core.builder.AbstractImageBuilder#writeClassFileContents(org.eclipse.jdt.internal.compiler.ClassFile, org.eclipse.core.resources.IFile, java.lang.String, boolean, org.eclipse.jdt.internal.core.builder.SourceFile)
+ */
+protected void writeClassFileContents(ClassFile classfile, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException {
+	// Before writing out the class file, compare it to the previous file
+	// If structural changes occurred then add dependent source files
+	byte[] bytes = classfile.getBytes();
+	if (file.exists()) {
+		if (writeClassFileCheck(file, qualifiedFileName, bytes) || compilationUnit.updateClassFile) { // see 46093
+			if (JavaBuilder.DEBUG)
+				System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$
+			if (!file.isDerived())
+				file.setDerived(true, null);
+			file.setContents(new ByteArrayInputStream(bytes), true, false, null);
+		} else if (JavaBuilder.DEBUG) {
+			System.out.println("Skipped over unchanged class file " + file.getName());//$NON-NLS-1$
+		}
+	} else {
+		if (isTopLevelType)
+			addDependentsOf(new Path(qualifiedFileName), true); // new type
+		if (JavaBuilder.DEBUG)
+			System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$
+		try {
+			file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null);
+		} catch (CoreException e) {
+			if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
+				IStatus status = e.getStatus();
+				if (status instanceof IResourceStatus) {
+					IPath oldFilePath = ((IResourceStatus) status).getPath();
+					char[] oldTypeName = oldFilePath.removeFileExtension().lastSegment().toCharArray();
+					char[][] previousTypeNames = this.newState.getDefinedTypeNamesFor(compilationUnit.typeLocator());
+					boolean fromSameFile = false;
+					if (previousTypeNames == null) {
+						fromSameFile = CharOperation.equals(compilationUnit.getMainTypeName(), oldTypeName);
+					} else {
+						for (int i = 0, l = previousTypeNames.length; i < l; i++) {
+							if (CharOperation.equals(previousTypeNames[i], oldTypeName)) {
+								fromSameFile = true;
+								break;
+							}
+						}
+					}
+					if (fromSameFile) {
+						// file is defined by the same compilationUnit, but won't be deleted until later so do it now
+						IFile collision = file.getParent().getFile(new Path(oldFilePath.lastSegment()));
+						collision.delete(true, false, null);
+						boolean success = false;
+						try {
+							file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null);
+							success = true;
+						} catch (CoreException ignored) {
+							// ignore the second exception
+						}
+						if (success) return;
+					}
+				}
+				// catch the case that a type has been renamed and collides on disk with an as-yet-to-be-deleted type
+				throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedFileName));
+			}
+			throw e; // rethrow
+		}
+	}
+}
+
+protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes) throws CoreException {
+	try {
+		byte[] oldBytes = Util.getResourceContentsAsByteArray(file);
+		notEqual : if (newBytes.length == oldBytes.length) {
+			for (int i = newBytes.length; --i >= 0;)
+				if (newBytes[i] != oldBytes[i]) break notEqual;
+			return false; // bytes are identical so skip them
+		}
+		URI location = file.getLocationURI();
+		if (location == null) return false; // unable to determine location of this class file
+		String filePath = location.getSchemeSpecificPart();
+		ClassFileReader reader = new ClassFileReader(oldBytes, filePath.toCharArray());
+		// ignore local types since they're only visible inside a single method
+		if (!(reader.isLocal() || reader.isAnonymous()) && reader.hasStructuralChanges(newBytes)) {
+			if (JavaBuilder.DEBUG)
+				System.out.println("Type has structural changes " + fileName); //$NON-NLS-1$
+			addDependentsOf(new Path(fileName), true);
+			this.newState.wasStructurallyChanged(fileName);
+		}
+	} catch (ClassFormatException e) {
+		addDependentsOf(new Path(fileName), true);
+		this.newState.wasStructurallyChanged(fileName);
+	}
+	return true;
+}
+
+public String toString() {
+	return "incremental image builder for:\n\tnew state: " + this.newState; //$NON-NLS-1$
+}
+
+
+/* Debug helper
+
+static void dump(IResourceDelta delta) {
+	StringBuffer buffer = new StringBuffer();
+	IPath path = delta.getFullPath();
+	for (int i = path.segmentCount(); --i > 0;)
+		buffer.append("  ");
+	switch (delta.getKind()) {
+		case IResourceDelta.ADDED:
+			buffer.append('+');
+			break;
+		case IResourceDelta.REMOVED:
+			buffer.append('-');
+			break;
+		case IResourceDelta.CHANGED:
+			buffer.append('*');
+			break;
+		case IResourceDelta.NO_CHANGE:
+			buffer.append('=');
+			break;
+		default:
+			buffer.append('?');
+			break;
+	}
+	buffer.append(path);
+	System.out.println(buffer.toString());
+	IResourceDelta[] children = delta.getAffectedChildren();
+	for (int i = 0, l = children.length; i < l; i++)
+		dump(children[i]);
+}
+*/
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
new file mode 100644
index 0000000..a97dc6d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -0,0 +1,769 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+import java.io.*;
+import java.util.*;
+
+public class JavaBuilder extends IncrementalProjectBuilder {
+
+IProject currentProject;
+JavaProject javaProject;
+IWorkspaceRoot workspaceRoot;
+CompilationParticipant[] participants;
+NameEnvironment nameEnvironment;
+SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary resources (output folders, class folders, zip/jar files)
+public State lastState;
+BuildNotifier notifier;
+char[][] extraResourceFileFilters;
+String[] extraResourceFolderFilters;
+public static final String SOURCE_ID = "JDT"; //$NON-NLS-1$
+
+public static boolean DEBUG = false;
+public static boolean SHOW_STATS = false;
+
+/**
+ * A list of project names that have been built.
+ * This list is used to reset the JavaModel.existingExternalFiles cache when a build cycle begins
+ * so that deleted external jars are discovered.
+ */
+static ArrayList builtProjects = null;
+
+public static IMarker[] getProblemsFor(IResource resource) {
+	try {
+		if (resource != null && resource.exists()) {
+			IMarker[] markers = resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
+			if (markerTypes.isEmpty()) return markers;
+			ArrayList markerList = new ArrayList(5);
+			for (int i = 0, length = markers.length; i < length; i++) {
+				markerList.add(markers[i]);
+			}
+			Iterator iterator = markerTypes.iterator();
+			while (iterator.hasNext()) {
+				markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
+				for (int i = 0, length = markers.length; i < length; i++) {
+					markerList.add(markers[i]);
+				}
+			}
+			IMarker[] result;
+			markerList.toArray(result = new IMarker[markerList.size()]);
+			return result;
+		}
+	} catch (CoreException e) {
+		// assume there are no problems
+	}
+	return new IMarker[0];
+}
+
+public static IMarker[] getTasksFor(IResource resource) {
+	try {
+		if (resource != null && resource.exists())
+			return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+	} catch (CoreException e) {
+		// assume there are no tasks
+	}
+	return new IMarker[0];
+}
+
+/**
+ * Hook allowing to initialize some static state before a complete build iteration.
+ * This hook is invoked during PRE_AUTO_BUILD notification
+ */
+public static void buildStarting() {
+	// build is about to start
+}
+
+/**
+ * Hook allowing to reset some static state after a complete build iteration.
+ * This hook is invoked during POST_AUTO_BUILD notification
+ */
+public static void buildFinished() {
+	BuildNotifier.resetProblemCounters();
+}
+
+public static void removeProblemsFor(IResource resource) {
+	try {
+		if (resource != null && resource.exists()) {
+			resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+
+			// delete managed markers
+			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
+			if (markerTypes.size() == 0) return;
+			Iterator iterator = markerTypes.iterator();
+			while (iterator.hasNext())
+				resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
+		}
+	} catch (CoreException e) {
+		// assume there were no problems
+	}
+}
+
+public static void removeTasksFor(IResource resource) {
+	try {
+		if (resource != null && resource.exists())
+			resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+	} catch (CoreException e) {
+		// assume there were no problems
+	}
+}
+
+public static void removeProblemsAndTasksFor(IResource resource) {
+	try {
+		if (resource != null && resource.exists()) {
+			resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
+			resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
+
+			// delete managed markers
+			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
+			if (markerTypes.size() == 0) return;
+			Iterator iterator = markerTypes.iterator();
+			while (iterator.hasNext())
+				resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
+		}
+	} catch (CoreException e) {
+		// assume there were no problems
+	}
+}
+
+public static State readState(IProject project, DataInputStream in) throws IOException {
+	return State.read(project, in);
+}
+
+public static void writeState(Object state, DataOutputStream out) throws IOException {
+	((State) state).write(out);
+}
+
+protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
+	this.currentProject = getProject();
+	if (this.currentProject == null || !this.currentProject.isAccessible()) return new IProject[0];
+
+	if (DEBUG)
+		System.out.println("\nStarting build of " + this.currentProject.getName() //$NON-NLS-1$
+			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+	this.notifier = new BuildNotifier(monitor, this.currentProject);
+	this.notifier.begin();
+	boolean ok = false;
+	try {
+		this.notifier.checkCancel();
+		kind = initializeBuilder(kind, true);
+
+		if (isWorthBuilding()) {
+			if (kind == FULL_BUILD) {
+				if (DEBUG)
+					System.out.println("Performing full build as requested by user"); //$NON-NLS-1$
+				buildAll();
+			} else {
+				if ((this.lastState = getLastState(this.currentProject)) == null) {
+					if (DEBUG)
+						System.out.println("Performing full build since last saved state was not found"); //$NON-NLS-1$
+					buildAll();
+				} else if (hasClasspathChanged()) {
+					// if the output location changes, do not delete the binary files from old location
+					// the user may be trying something
+					if (DEBUG)
+						System.out.println("Performing full build since classpath has changed"); //$NON-NLS-1$
+					buildAll();
+				} else if (this.nameEnvironment.sourceLocations.length > 0) {
+					// if there is no source to compile & no classpath changes then we are done
+					SimpleLookupTable deltas = findDeltas();
+					if (deltas == null) {
+						if (DEBUG)
+							System.out.println("Performing full build since deltas are missing after incremental request"); //$NON-NLS-1$
+						buildAll();
+					} else if (deltas.elementSize > 0) {
+						buildDeltas(deltas);
+					} else if (DEBUG) {
+						System.out.println("Nothing to build since deltas were empty"); //$NON-NLS-1$
+					}
+				} else {
+					if (hasStructuralDelta()) { // double check that a jar file didn't get replaced in a binary project
+						if (DEBUG)
+							System.out.println("Performing full build since there are structural deltas"); //$NON-NLS-1$
+						buildAll();
+					} else {
+						if (DEBUG)
+							System.out.println("Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
+						this.lastState.tagAsNoopBuild();
+					}
+				}
+			}
+			ok = true;
+		}
+	} catch (CoreException e) {
+		Util.log(e, "JavaBuilder handling CoreException while building: " + this.currentProject.getName()); //$NON-NLS-1$
+		createInconsistentBuildMarker(e);
+	} catch (ImageBuilderInternalException e) {
+		Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException while building: " + this.currentProject.getName()); //$NON-NLS-1$
+		createInconsistentBuildMarker(e.coreException);
+	} catch (MissingSourceFileException e) {
+		// do not log this exception since its thrown to handle aborted compiles because of missing source files
+		if (DEBUG)
+			System.out.println(Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile));
+		removeProblemsAndTasksFor(this.currentProject); // make this the only problem for this project
+		IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+		marker.setAttributes(
+			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.SOURCE_ID},
+			new Object[] {
+				Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile),
+				new Integer(IMarker.SEVERITY_ERROR),
+				JavaBuilder.SOURCE_ID
+			}
+		);
+	} finally {
+		for (int i = 0, l = this.participants == null ? 0 : this.participants.length; i < l; i++)
+			this.participants[i].buildFinished(this.javaProject);
+		if (!ok)
+			// If the build failed, clear the previously built state, forcing a full build next time.
+			clearLastState();
+		this.notifier.done();
+		cleanup();
+	}
+	IProject[] requiredProjects = getRequiredProjects(true);
+	if (DEBUG)
+		System.out.println("Finished build of " + this.currentProject.getName() //$NON-NLS-1$
+			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+	return requiredProjects;
+}
+
+private void buildAll() {
+	this.notifier.checkCancel();
+	this.notifier.subTask(Messages.bind(Messages.build_preparingBuild, this.currentProject.getName()));
+	if (DEBUG && this.lastState != null)
+		System.out.println("Clearing last state : " + this.lastState); //$NON-NLS-1$
+	clearLastState();
+	BatchImageBuilder imageBuilder = new BatchImageBuilder(this, true);
+	imageBuilder.build();
+	recordNewState(imageBuilder.newState);
+}
+
+private void buildDeltas(SimpleLookupTable deltas) {
+	this.notifier.checkCancel();
+	this.notifier.subTask(Messages.bind(Messages.build_preparingBuild, this.currentProject.getName()));
+	if (DEBUG && this.lastState != null)
+		System.out.println("Clearing last state : " + this.lastState); //$NON-NLS-1$
+	clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time
+	IncrementalImageBuilder imageBuilder = new IncrementalImageBuilder(this);
+	if (imageBuilder.build(deltas)) {
+		recordNewState(imageBuilder.newState);
+	} else {
+		if (DEBUG)
+			System.out.println("Performing full build since incremental build failed"); //$NON-NLS-1$
+		buildAll();
+	}
+}
+
+protected void clean(IProgressMonitor monitor) throws CoreException {
+	this.currentProject = getProject();
+	if (this.currentProject == null || !this.currentProject.isAccessible()) return;
+
+	if (DEBUG)
+		System.out.println("\nCleaning " + this.currentProject.getName() //$NON-NLS-1$
+			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+	this.notifier = new BuildNotifier(monitor, this.currentProject);
+	this.notifier.begin();
+	try {
+		this.notifier.checkCancel();
+
+		initializeBuilder(CLEAN_BUILD, true);
+		if (DEBUG)
+			System.out.println("Clearing last state as part of clean : " + this.lastState); //$NON-NLS-1$
+		clearLastState();
+		removeProblemsAndTasksFor(this.currentProject);
+		new BatchImageBuilder(this, false).cleanOutputFolders(false);
+	} catch (CoreException e) {
+		Util.log(e, "JavaBuilder handling CoreException while cleaning: " + this.currentProject.getName()); //$NON-NLS-1$
+		createInconsistentBuildMarker(e);
+	} finally {
+		this.notifier.done();
+		cleanup();
+	}
+	if (DEBUG)
+		System.out.println("Finished cleaning " + this.currentProject.getName() //$NON-NLS-1$
+			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
+}
+
+private void createInconsistentBuildMarker(CoreException coreException) throws CoreException {
+	String message = null;
+	IStatus status = coreException.getStatus();
+ 	if (status.isMultiStatus()) {
+ 		IStatus[] children = status.getChildren();
+ 		if (children != null && children.length > 0)
+ 		    message = children[0].getMessage();
+ 	}
+ 	if (message == null)
+ 		message = coreException.getMessage();
+
+	IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+	marker.setAttributes(
+		new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
+		new Object[] {
+			Messages.bind(Messages.build_inconsistentProject, message),
+			new Integer(IMarker.SEVERITY_ERROR),
+			new Integer(CategorizedProblem.CAT_BUILDPATH),
+			JavaBuilder.SOURCE_ID
+		}
+	);
+}
+
+private void cleanup() {
+	this.participants = null;
+	this.nameEnvironment = null;
+	this.binaryLocationsPerProject = null;
+	this.lastState = null;
+	this.notifier = null;
+	this.extraResourceFileFilters = null;
+	this.extraResourceFolderFilters = null;
+}
+
+private void clearLastState() {
+	JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, null);
+}
+
+boolean filterExtraResource(IResource resource) {
+	if (this.extraResourceFileFilters != null) {
+		char[] name = resource.getName().toCharArray();
+		for (int i = 0, l = this.extraResourceFileFilters.length; i < l; i++)
+			if (CharOperation.match(this.extraResourceFileFilters[i], name, true))
+				return true;
+	}
+	if (this.extraResourceFolderFilters != null) {
+		IPath path = resource.getProjectRelativePath();
+		String pathName = path.toString();
+		int count = path.segmentCount();
+		if (resource.getType() == IResource.FILE) count--;
+		for (int i = 0, l = this.extraResourceFolderFilters.length; i < l; i++)
+			if (pathName.indexOf(this.extraResourceFolderFilters[i]) != -1)
+				for (int j = 0; j < count; j++)
+					if (this.extraResourceFolderFilters[i].equals(path.segment(j)))
+						return true;
+	}
+	return false;
+}
+
+private SimpleLookupTable findDeltas() {
+	this.notifier.subTask(Messages.bind(Messages.build_readingDelta, this.currentProject.getName()));
+	IResourceDelta delta = getDelta(this.currentProject);
+	SimpleLookupTable deltas = new SimpleLookupTable(3);
+	if (delta != null) {
+		if (delta.getKind() != IResourceDelta.NO_CHANGE) {
+			if (DEBUG)
+				System.out.println("Found source delta for: " + this.currentProject.getName()); //$NON-NLS-1$
+			deltas.put(this.currentProject, delta);
+		}
+	} else {
+		if (DEBUG)
+			System.out.println("Missing delta for: " + this.currentProject.getName()); //$NON-NLS-1$
+		this.notifier.subTask(""); //$NON-NLS-1$
+		return null;
+	}
+
+	Object[] keyTable = this.binaryLocationsPerProject.keyTable;
+	Object[] valueTable = this.binaryLocationsPerProject.valueTable;
+	nextProject : for (int i = 0, l = keyTable.length; i < l; i++) {
+		IProject p = (IProject) keyTable[i];
+		if (p != null && p != this.currentProject) {
+			State s = getLastState(p);
+			if (!this.lastState.wasStructurallyChanged(p, s)) { // see if we can skip its delta
+				if (s.wasNoopBuild())
+					continue nextProject; // project has no source folders and can be skipped
+				ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) valueTable[i];
+				boolean canSkip = true;
+				for (int j = 0, m = classFoldersAndJars.length; j < m; j++) {
+					if (classFoldersAndJars[j].isOutputFolder())
+						classFoldersAndJars[j] = null; // can ignore output folder since project was not structurally changed
+					else
+						canSkip = false;
+				}
+				if (canSkip) continue nextProject; // project has no structural changes in its output folders
+			}
+
+			this.notifier.subTask(Messages.bind(Messages.build_readingDelta, p.getName()));
+			delta = getDelta(p);
+			if (delta != null) {
+				if (delta.getKind() != IResourceDelta.NO_CHANGE) {
+					if (DEBUG)
+						System.out.println("Found binary delta for: " + p.getName()); //$NON-NLS-1$
+					deltas.put(p, delta);
+				}
+			} else {
+				if (DEBUG)
+					System.out.println("Missing delta for: " + p.getName());	 //$NON-NLS-1$
+				this.notifier.subTask(""); //$NON-NLS-1$
+				return null;
+			}
+		}
+	}
+	this.notifier.subTask(""); //$NON-NLS-1$
+	return deltas;
+}
+
+public State getLastState(IProject project) {
+	return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, this.notifier.monitor);
+}
+
+/* Return the list of projects for which it requires a resource delta. This builder's project
+* is implicitly included and need not be specified. Builders must re-specify the list
+* of interesting projects every time they are run as this is not carried forward
+* beyond the next build. Missing projects should be specified but will be ignored until
+* they are added to the workspace.
+*/
+private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) {
+	if (this.javaProject == null || this.workspaceRoot == null) return new IProject[0];
+
+	ArrayList projects = new ArrayList();
+	ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
+	try {
+		IClasspathEntry[] entries = this.javaProject.getExpandedClasspath();
+		for (int i = 0, l = entries.length; i < l; i++) {
+			IClasspathEntry entry = entries[i];
+			IPath path = entry.getPath();
+			IProject p = null;
+			switch (entry.getEntryKind()) {
+				case IClasspathEntry.CPE_PROJECT :
+					p = this.workspaceRoot.getProject(path.lastSegment()); // missing projects are considered too
+					if (((ClasspathEntry) entry).isOptional() && !JavaProject.hasJavaNature(p)) // except if entry is optional
+						p = null;
+					break;
+				case IClasspathEntry.CPE_LIBRARY :
+					if (includeBinaryPrerequisites && path.segmentCount() > 0) {
+						// some binary resources on the class path can come from projects that are not included in the project references
+						IResource resource = this.workspaceRoot.findMember(path.segment(0));
+						if (resource instanceof IProject) {
+							p = (IProject) resource;
+						} else {
+							resource = externalFoldersManager.getFolder(path);
+							if (resource != null)
+								p = resource.getProject();
+						}
+					}
+			}
+			if (p != null && !projects.contains(p))
+				projects.add(p);
+		}
+	} catch(JavaModelException e) {
+		return new IProject[0];
+	}
+	IProject[] result = new IProject[projects.size()];
+	projects.toArray(result);
+	return result;
+}
+
+boolean hasBuildpathErrors() throws CoreException {
+	IMarker[] markers = this.currentProject.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+	for (int i = 0, l = markers.length; i < l; i++)
+		if (markers[i].getAttribute(IJavaModelMarker.CATEGORY_ID, -1) == CategorizedProblem.CAT_BUILDPATH)
+			return true;
+	return false;
+}
+
+private boolean hasClasspathChanged() {
+	ClasspathMultiDirectory[] newSourceLocations = this.nameEnvironment.sourceLocations;
+	ClasspathMultiDirectory[] oldSourceLocations = this.lastState.sourceLocations;
+	int newLength = newSourceLocations.length;
+	int oldLength = oldSourceLocations.length;
+	int n, o;
+	for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
+		if (newSourceLocations[n].equals(oldSourceLocations[o])) continue; // checks source & output folders
+		try {
+			if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
+				o--;
+				continue;
+			} else if (this.lastState.isSourceFolderEmpty(oldSourceLocations[o].sourceFolder)) {
+				n--;
+				continue;
+			}
+		} catch (CoreException ignore) { // skip it
+		}
+		if (DEBUG) {
+			System.out.println("New location: " + newSourceLocations[n] + "\n!= old location: " + oldSourceLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
+			printLocations(newSourceLocations, oldSourceLocations);
+		}
+		return true;
+	}
+	while (n < newLength) {
+		try {
+			if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
+				n++;
+				continue;
+			}
+		} catch (CoreException ignore) { // skip it
+		}
+		if (DEBUG) {
+			System.out.println("Added non-empty source folder"); //$NON-NLS-1$
+			printLocations(newSourceLocations, oldSourceLocations);
+		}
+		return true;
+	}
+	while (o < oldLength) {
+		if (this.lastState.isSourceFolderEmpty(oldSourceLocations[o].sourceFolder)) {
+			o++;
+			continue;
+		}
+		if (DEBUG) {
+			System.out.println("Removed non-empty source folder"); //$NON-NLS-1$
+			printLocations(newSourceLocations, oldSourceLocations);
+		}
+		return true;
+	}
+
+	ClasspathLocation[] newBinaryLocations = this.nameEnvironment.binaryLocations;
+	ClasspathLocation[] oldBinaryLocations = this.lastState.binaryLocations;
+	newLength = newBinaryLocations.length;
+	oldLength = oldBinaryLocations.length;
+	for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
+		if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
+		if (DEBUG) {
+			System.out.println("New location: " + newBinaryLocations[n] + "\n!= old location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
+			printLocations(newBinaryLocations, oldBinaryLocations);
+		}
+		return true;
+	}
+	if (n < newLength || o < oldLength) {
+		if (DEBUG) {
+			System.out.println("Number of binary folders/jar files has changed:"); //$NON-NLS-1$
+			printLocations(newBinaryLocations, oldBinaryLocations);
+		}
+		return true;
+	}
+	return false;
+}
+
+private boolean hasJavaBuilder(IProject project) throws CoreException {
+	ICommand[] buildCommands = project.getDescription().getBuildSpec();
+	for (int i = 0, l = buildCommands.length; i < l; i++)
+		if (buildCommands[i].getBuilderName().equals(JavaCore.BUILDER_ID))
+			return true;
+	return false;
+}
+
+private boolean hasStructuralDelta() {
+	// handle case when currentProject has only .class file folders and/or jar files... no source/output folders
+	IResourceDelta delta = getDelta(this.currentProject);
+	if (delta != null && delta.getKind() != IResourceDelta.NO_CHANGE) {
+		ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) this.binaryLocationsPerProject.get(this.currentProject);
+		if (classFoldersAndJars != null) {
+			for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
+				ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either a .class file folder or a zip/jar file
+				if (classFolderOrJar != null) {
+					IPath p = classFolderOrJar.getProjectRelativePath();
+					if (p != null) {
+						IResourceDelta binaryDelta = delta.findMember(p);
+						if (binaryDelta != null && binaryDelta.getKind() != IResourceDelta.NO_CHANGE)
+							return true;
+					}
+				}
+			}
+		}
+	}
+	return false;
+}
+
+private int initializeBuilder(int kind, boolean forBuild) throws CoreException {
+	// some calls just need the nameEnvironment initialized so skip the rest
+	this.javaProject = (JavaProject) JavaCore.create(this.currentProject);
+	this.workspaceRoot = this.currentProject.getWorkspace().getRoot();
+
+	if (forBuild) {
+		// cache the known participants for this project
+		this.participants = JavaModelManager.getJavaModelManager().compilationParticipants.getCompilationParticipants(this.javaProject);
+		if (this.participants != null)
+			for (int i = 0, l = this.participants.length; i < l; i++)
+				if (this.participants[i].aboutToBuild(this.javaProject) == CompilationParticipant.NEEDS_FULL_BUILD)
+					kind = FULL_BUILD;
+
+		// Flush the existing external files cache if this is the beginning of a build cycle
+		String projectName = this.currentProject.getName();
+		if (builtProjects == null || builtProjects.contains(projectName)) {
+			JavaModel.flushExternalFileCache();
+			builtProjects = new ArrayList();
+		}
+		builtProjects.add(projectName);
+	}
+
+	this.binaryLocationsPerProject = new SimpleLookupTable(3);
+	this.nameEnvironment = new NameEnvironment(this.workspaceRoot, this.javaProject, this.binaryLocationsPerProject, this.notifier);
+
+	if (forBuild) {
+		String filterSequence = this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true);
+		char[][] filters = filterSequence != null && filterSequence.length() > 0
+			? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray())
+			: null;
+		if (filters == null) {
+			this.extraResourceFileFilters = null;
+			this.extraResourceFolderFilters = null;
+		} else {
+			int fileCount = 0, folderCount = 0;
+			for (int i = 0, l = filters.length; i < l; i++) {
+				char[] f = filters[i];
+				if (f.length == 0) continue;
+				if (f[f.length - 1] == '/') folderCount++; else fileCount++;
+			}
+			this.extraResourceFileFilters = new char[fileCount][];
+			this.extraResourceFolderFilters = new String[folderCount];
+			for (int i = 0, l = filters.length; i < l; i++) {
+				char[] f = filters[i];
+				if (f.length == 0) continue;
+				if (f[f.length - 1] == '/')
+					this.extraResourceFolderFilters[--folderCount] = new String(f, 0, f.length - 1);
+				else
+					this.extraResourceFileFilters[--fileCount] = f;
+			}
+		}
+	}
+	return kind;
+}
+
+private boolean isClasspathBroken(IClasspathEntry[] classpath, IProject p) throws CoreException {
+	IMarker[] markers = p.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
+	for (int i = 0, l = markers.length; i < l; i++)
+		if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR)
+			return true;
+	return false;
+}
+
+private boolean isWorthBuilding() throws CoreException {
+	boolean abortBuilds =
+		JavaCore.ABORT.equals(this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true));
+	if (!abortBuilds) return true;
+
+	// Abort build only if there are classpath errors
+	if (isClasspathBroken(this.javaProject.getRawClasspath(), this.currentProject)) {
+		if (DEBUG)
+			System.out.println("Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$
+
+		removeProblemsAndTasksFor(this.currentProject); // remove all compilation problems
+
+		IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+		marker.setAttributes(
+			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
+			new Object[] {
+				Messages.build_abortDueToClasspathProblems,
+				new Integer(IMarker.SEVERITY_ERROR),
+				new Integer(CategorizedProblem.CAT_BUILDPATH),
+				JavaBuilder.SOURCE_ID
+			}
+		);
+		return false;
+	}
+
+	if (JavaCore.WARNING.equals(this.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true)))
+		return true;
+
+	// make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states
+	// except for projects involved in a 'warning' cycle (see below)
+	IProject[] requiredProjects = getRequiredProjects(false);
+	for (int i = 0, l = requiredProjects.length; i < l; i++) {
+		IProject p = requiredProjects[i];
+		if (getLastState(p) == null)  {
+			// The prereq project has no build state: if this prereq project has a 'warning' cycle marker then allow build (see bug id 23357)
+			JavaProject prereq = (JavaProject) JavaCore.create(p);
+			if (prereq.hasCycleMarker() && JavaCore.WARNING.equals(this.javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
+				if (DEBUG)
+					System.out.println("Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
+						+ " was not built since its part of a cycle"); //$NON-NLS-1$
+				continue;
+			}
+			if (!hasJavaBuilder(p)) {
+				if (DEBUG)
+					System.out.println("Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
+						+ " is not built by JavaBuilder"); //$NON-NLS-1$
+				continue;
+			}
+			if (DEBUG)
+				System.out.println("Aborted build because prereq project " + p.getName() //$NON-NLS-1$
+					+ " was not built"); //$NON-NLS-1$
+
+			removeProblemsAndTasksFor(this.currentProject); // make this the only problem for this project
+			IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
+			marker.setAttributes(
+				new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
+				new Object[] {
+					isClasspathBroken(prereq.getRawClasspath(), p)
+						? Messages.bind(Messages.build_prereqProjectHasClasspathProblems, p.getName())
+						: Messages.bind(Messages.build_prereqProjectMustBeRebuilt, p.getName()),
+					new Integer(IMarker.SEVERITY_ERROR),
+					new Integer(CategorizedProblem.CAT_BUILDPATH),
+					JavaBuilder.SOURCE_ID
+				}
+			);
+			return false;
+		}
+	}
+	return true;
+}
+
+/*
+ * Instruct the build manager that this project is involved in a cycle and
+ * needs to propagate structural changes to the other projects in the cycle.
+ */
+void mustPropagateStructuralChanges() {
+	LinkedHashSet cycleParticipants = new LinkedHashSet(3);
+	this.javaProject.updateCycleParticipants(new ArrayList(), cycleParticipants, this.workspaceRoot, new HashSet(3), null);
+	IPath currentPath = this.javaProject.getPath();
+	Iterator i= cycleParticipants.iterator();
+	while (i.hasNext()) {
+		IPath participantPath = (IPath) i.next();
+		if (participantPath != currentPath) {
+			IProject project = this.workspaceRoot.getProject(participantPath.segment(0));
+			if (hasBeenBuilt(project)) {
+				if (DEBUG)
+					System.out.println("Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$
+						+ " has not yet seen some structural changes"); //$NON-NLS-1$
+				needRebuild();
+				return;
+			}
+		}
+	}
+}
+
+private void printLocations(ClasspathLocation[] newLocations, ClasspathLocation[] oldLocations) {
+	System.out.println("New locations:"); //$NON-NLS-1$
+	for (int i = 0, length = newLocations.length; i < length; i++)
+		System.out.println("    " + newLocations[i].debugPathString()); //$NON-NLS-1$
+	System.out.println("Old locations:"); //$NON-NLS-1$
+	for (int i = 0, length = oldLocations.length; i < length; i++)
+		System.out.println("    " + oldLocations[i].debugPathString()); //$NON-NLS-1$
+}
+
+private void recordNewState(State state) {
+	Object[] keyTable = this.binaryLocationsPerProject.keyTable;
+	for (int i = 0, l = keyTable.length; i < l; i++) {
+		IProject prereqProject = (IProject) keyTable[i];
+		if (prereqProject != null && prereqProject != this.currentProject)
+			state.recordStructuralDependency(prereqProject, getLastState(prereqProject));
+	}
+
+	if (DEBUG)
+		System.out.println("Recording new state : " + state); //$NON-NLS-1$
+	// state.dump();
+	JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, state);
+}
+
+/**
+ * String representation for debugging purposes
+ */
+public String toString() {
+	return this.currentProject == null
+		? "JavaBuilder for unknown project" //$NON-NLS-1$
+		: "JavaBuilder for " + this.currentProject.getName(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java
new file mode 100644
index 0000000..9f45dfe
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+/**
+ * Exception thrown when the build should be aborted because a source file is missing/empty.
+ */
+public class MissingSourceFileException extends RuntimeException {
+
+	protected String missingSourceFile;
+	private static final long serialVersionUID = -1416609004971115719L; // backward compatible
+
+public MissingSourceFileException(String missingSourceFile) {
+	this.missingSourceFile = missingSourceFile;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
new file mode 100644
index 0000000..981e27b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Terry Parker <tparker@google.com> 
+ *           - Contribution for https://bugs.eclipse.org/bugs/show_bug.cgi?id=372418
+ *           -  Another problem with inner classes referenced from jars or class folders: "The type ... cannot be resolved"
+ *     Stephan Herrmann - Contribution for
+ *								Bug 392727 - Cannot compile project when a java file contains $ in its file name
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.*;
+
+import java.io.*;
+import java.util.*;
+
+public class NameEnvironment implements INameEnvironment, SuffixConstants {
+
+boolean isIncrementalBuild;
+ClasspathMultiDirectory[] sourceLocations;
+ClasspathLocation[] binaryLocations;
+BuildNotifier notifier;
+
+SimpleSet initialTypeNames; // assumed that each name is of the form "a/b/ClassName"
+SimpleLookupTable additionalUnits;
+
+NameEnvironment(IWorkspaceRoot root, JavaProject javaProject, SimpleLookupTable binaryLocationsPerProject, BuildNotifier notifier) throws CoreException {
+	this.isIncrementalBuild = false;
+	this.notifier = notifier;
+	computeClasspathLocations(root, javaProject, binaryLocationsPerProject);
+	setNames(null, null);
+}
+
+public NameEnvironment(IJavaProject javaProject) {
+	this.isIncrementalBuild = false;
+	try {
+		computeClasspathLocations(javaProject.getProject().getWorkspace().getRoot(), (JavaProject) javaProject, null);
+	} catch(CoreException e) {
+		this.sourceLocations = new ClasspathMultiDirectory[0];
+		this.binaryLocations = new ClasspathLocation[0];
+	}
+	setNames(null, null);
+}
+
+/* Some examples of resolved class path entries.
+* Remember to search class path in the order that it was defined.
+*
+* 1a. typical project with no source folders:
+*   /Test[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test
+* 1b. project with source folders:
+*   /Test/src1[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src1
+*   /Test/src2[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src2
+*  NOTE: These can be in any order & separated by prereq projects or libraries
+* 1c. project external to workspace (only detectable using getLocation()):
+*   /Test/src[CPE_SOURCE][K_SOURCE] -> d:/eclipse.zzz/src
+*  Need to search source folder & output folder
+*
+* 2. zip files:
+*   D:/j9/lib/jclMax/classes.zip[CPE_LIBRARY][K_BINARY][sourcePath:d:/j9/lib/jclMax/source/source.zip]
+*      -> D:/j9/lib/jclMax/classes.zip
+*  ALWAYS want to take the library path as is
+*
+* 3a. prereq project (regardless of whether it has a source or output folder):
+*   /Test[CPE_PROJECT][K_SOURCE] -> D:/eclipse.test/Test
+*  ALWAYS want to append the output folder & ONLY search for .class files
+*/
+private void computeClasspathLocations(
+	IWorkspaceRoot root,
+	JavaProject javaProject,
+	SimpleLookupTable binaryLocationsPerProject) throws CoreException {
+
+	/* Update cycle marker */
+	IMarker cycleMarker = javaProject.getCycleMarker();
+	if (cycleMarker != null) {
+		int severity = JavaCore.ERROR.equals(javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))
+			? IMarker.SEVERITY_ERROR
+			: IMarker.SEVERITY_WARNING;
+		if (severity != cycleMarker.getAttribute(IMarker.SEVERITY, severity))
+			cycleMarker.setAttribute(IMarker.SEVERITY, severity);
+	}
+
+	IClasspathEntry[] classpathEntries = javaProject.getExpandedClasspath();
+	ArrayList sLocations = new ArrayList(classpathEntries.length);
+	ArrayList bLocations = new ArrayList(classpathEntries.length);
+	nextEntry : for (int i = 0, l = classpathEntries.length; i < l; i++) {
+		ClasspathEntry entry = (ClasspathEntry) classpathEntries[i];
+		IPath path = entry.getPath();
+		Object target = JavaModel.getTarget(path, true);
+		if (target == null) continue nextEntry;
+
+		switch(entry.getEntryKind()) {
+			case IClasspathEntry.CPE_SOURCE :
+				if (!(target instanceof IContainer)) continue nextEntry;
+				IPath outputPath = entry.getOutputLocation() != null
+					? entry.getOutputLocation()
+					: javaProject.getOutputLocation();
+				IContainer outputFolder;
+				if (outputPath.segmentCount() == 1) {
+					outputFolder = javaProject.getProject();
+				} else {
+					outputFolder = root.getFolder(outputPath);
+					if (!outputFolder.exists())
+						createOutputFolder(outputFolder);
+				}
+				sLocations.add(
+					ClasspathLocation.forSourceFolder((IContainer) target, outputFolder, entry.fullInclusionPatternChars(), entry.fullExclusionPatternChars(), entry.ignoreOptionalProblems()));
+				continue nextEntry;
+
+			case IClasspathEntry.CPE_PROJECT :
+				if (!(target instanceof IProject)) continue nextEntry;
+				IProject prereqProject = (IProject) target;
+				if (!JavaProject.hasJavaNature(prereqProject)) continue nextEntry; // if project doesn't have java nature or is not accessible
+
+				JavaProject prereqJavaProject = (JavaProject) JavaCore.create(prereqProject);
+				IClasspathEntry[] prereqClasspathEntries = prereqJavaProject.getRawClasspath();
+				ArrayList seen = new ArrayList();
+				nextPrereqEntry: for (int j = 0, m = prereqClasspathEntries.length; j < m; j++) {
+					IClasspathEntry prereqEntry = prereqClasspathEntries[j];
+					if (prereqEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+						Object prereqTarget = JavaModel.getTarget(prereqEntry.getPath(), true);
+						if (!(prereqTarget instanceof IContainer)) continue nextPrereqEntry;
+						IPath prereqOutputPath = prereqEntry.getOutputLocation() != null
+							? prereqEntry.getOutputLocation()
+							: prereqJavaProject.getOutputLocation();
+						IContainer binaryFolder = prereqOutputPath.segmentCount() == 1
+							? (IContainer) prereqProject
+							: (IContainer) root.getFolder(prereqOutputPath);
+						if (binaryFolder.exists() && !seen.contains(binaryFolder)) {
+							seen.add(binaryFolder);
+							ClasspathLocation bLocation = ClasspathLocation.forBinaryFolder(binaryFolder, true, entry.getAccessRuleSet());
+							bLocations.add(bLocation);
+							if (binaryLocationsPerProject != null) { // normal builder mode
+								ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(prereqProject);
+								if (existingLocations == null) {
+									existingLocations = new ClasspathLocation[] {bLocation};
+								} else {
+									int size = existingLocations.length;
+									System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size);
+									existingLocations[size] = bLocation;
+								}
+								binaryLocationsPerProject.put(prereqProject, existingLocations);
+							}
+						}
+					}
+				}
+				continue nextEntry;
+
+			case IClasspathEntry.CPE_LIBRARY :
+				if (target instanceof IResource) {
+					IResource resource = (IResource) target;
+					ClasspathLocation bLocation = null;
+					if (resource instanceof IFile) {
+						AccessRuleSet accessRuleSet =
+							(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+						bLocation = ClasspathLocation.forLibrary((IFile) resource, accessRuleSet);
+					} else if (resource instanceof IContainer) {
+						AccessRuleSet accessRuleSet =
+							(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+						bLocation = ClasspathLocation.forBinaryFolder((IContainer) target, false, accessRuleSet);	 // is library folder not output folder
+					}
+					bLocations.add(bLocation);
+					if (binaryLocationsPerProject != null) { // normal builder mode
+						IProject p = resource.getProject(); // can be the project being built
+						ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(p);
+						if (existingLocations == null) {
+							existingLocations = new ClasspathLocation[] {bLocation};
+						} else {
+							int size = existingLocations.length;
+							System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size);
+							existingLocations[size] = bLocation;
+						}
+						binaryLocationsPerProject.put(p, existingLocations);
+					}
+				} else if (target instanceof File) {
+					AccessRuleSet accessRuleSet =
+						(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+					bLocations.add(ClasspathLocation.forLibrary(path.toString(), accessRuleSet));
+				}
+				continue nextEntry;
+		}
+	}
+
+	// now split the classpath locations... place the output folders ahead of the other .class file folders & jars
+	ArrayList outputFolders = new ArrayList(1);
+	this.sourceLocations = new ClasspathMultiDirectory[sLocations.size()];
+	if (!sLocations.isEmpty()) {
+		sLocations.toArray(this.sourceLocations);
+
+		// collect the output folders, skipping duplicates
+		next : for (int i = 0, l = this.sourceLocations.length; i < l; i++) {
+			ClasspathMultiDirectory md = this.sourceLocations[i];
+			IPath outputPath = md.binaryFolder.getFullPath();
+			for (int j = 0; j < i; j++) { // compare against previously walked source folders
+				if (outputPath.equals(this.sourceLocations[j].binaryFolder.getFullPath())) {
+					md.hasIndependentOutputFolder = this.sourceLocations[j].hasIndependentOutputFolder;
+					continue next;
+				}
+			}
+			outputFolders.add(md);
+
+			// also tag each source folder whose output folder is an independent folder & is not also a source folder
+			for (int j = 0, m = this.sourceLocations.length; j < m; j++)
+				if (outputPath.equals(this.sourceLocations[j].sourceFolder.getFullPath()))
+					continue next;
+			md.hasIndependentOutputFolder = true;
+		}
+	}
+
+	// combine the output folders with the binary folders & jars... place the output folders before other .class file folders & jars
+	this.binaryLocations = new ClasspathLocation[outputFolders.size() + bLocations.size()];
+	int index = 0;
+	for (int i = 0, l = outputFolders.size(); i < l; i++)
+		this.binaryLocations[index++] = (ClasspathLocation) outputFolders.get(i);
+	for (int i = 0, l = bLocations.size(); i < l; i++)
+		this.binaryLocations[index++] = (ClasspathLocation) bLocations.get(i);
+}
+
+public void cleanup() {
+	this.initialTypeNames = null;
+	this.additionalUnits = null;
+	for (int i = 0, l = this.sourceLocations.length; i < l; i++)
+		this.sourceLocations[i].cleanup();
+	for (int i = 0, l = this.binaryLocations.length; i < l; i++)
+		this.binaryLocations[i].cleanup();
+}
+
+private void createOutputFolder(IContainer outputFolder) throws CoreException {
+	createParentFolder(outputFolder.getParent());
+	((IFolder) outputFolder).create(IResource.FORCE | IResource.DERIVED, true, null);
+}
+
+private void createParentFolder(IContainer parent) throws CoreException {
+	if (!parent.exists()) {
+		createParentFolder(parent.getParent());
+		((IFolder) parent).create(true, true, null);
+	}
+}
+
+private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName) {
+	if (this.notifier != null)
+		this.notifier.checkCancelWithinCompiler();
+
+	if (this.initialTypeNames != null && this.initialTypeNames.includes(qualifiedTypeName)) {
+		if (this.isIncrementalBuild)
+			// catch the case that a type inside a source file has been renamed but other class files are looking for it
+			throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedTypeName));
+		return null; // looking for a file which we know was provided at the beginning of the compilation
+	}
+
+	if (this.additionalUnits != null && this.sourceLocations.length > 0) {
+		// if an additional source file is waiting to be compiled, answer it BUT not if this is a secondary type search
+		// if we answer X.java & it no longer defines Y then the binary type looking for Y will think the class path is wrong
+		// let the recompile loop fix up dependents when the secondary type Y has been deleted from X.java
+		// Only enclosing type names are present in the additional units table, so strip off inner class specifications
+		// when doing the lookup (https://bugs.eclipse.org/372418). 
+		// Also take care of $ in the name of the class (https://bugs.eclipse.org/377401)
+		// and prefer name with '$' if unit exists rather than failing to search for nested class (https://bugs.eclipse.org/392727)
+		SourceFile unit = (SourceFile) this.additionalUnits.get(qualifiedTypeName); // doesn't have file extension
+		if (unit != null)
+			return new NameEnvironmentAnswer(unit, null /*no access restriction*/);
+		int index = qualifiedTypeName.indexOf('$');
+		if (index > 0) {
+			String enclosingTypeName = qualifiedTypeName.substring(0, index);
+			unit = (SourceFile) this.additionalUnits.get(enclosingTypeName); // doesn't have file extension
+			if (unit != null)
+				return new NameEnvironmentAnswer(unit, null /*no access restriction*/);
+		}
+	}
+
+	String qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+	String binaryFileName = qBinaryFileName;
+	String qPackageName =  ""; //$NON-NLS-1$
+	if (qualifiedTypeName.length() > typeName.length) {
+		int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
+		qPackageName =  qBinaryFileName.substring(0, typeNameStart - 1);
+		binaryFileName = qBinaryFileName.substring(typeNameStart);
+	}
+
+	// NOTE: the output folders are added at the beginning of the binaryLocations
+	NameEnvironmentAnswer suggestedAnswer = null;
+	for (int i = 0, l = this.binaryLocations.length; i < l; i++) {
+		NameEnvironmentAnswer answer = this.binaryLocations[i].findClass(binaryFileName, qPackageName, qBinaryFileName);
+		if (answer != null) {
+			if (!answer.ignoreIfBetter()) {
+				if (answer.isBetter(suggestedAnswer))
+					return answer;
+			} else if (answer.isBetter(suggestedAnswer))
+				// remember suggestion and keep looking
+				suggestedAnswer = answer;
+		}
+	}
+	if (suggestedAnswer != null)
+		// no better answer was found
+		return suggestedAnswer;
+	return null;
+}
+
+public NameEnvironmentAnswer findType(char[][] compoundName) {
+	if (compoundName != null)
+		return findClass(
+			new String(CharOperation.concatWith(compoundName, '/')),
+			compoundName[compoundName.length - 1]);
+	return null;
+}
+
+public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+	if (typeName != null)
+		return findClass(
+			new String(CharOperation.concatWith(packageName, typeName, '/')),
+			typeName);
+	return null;
+}
+
+public boolean isPackage(char[][] compoundName, char[] packageName) {
+	return isPackage(new String(CharOperation.concatWith(compoundName, packageName, '/')));
+}
+
+public boolean isPackage(String qualifiedPackageName) {
+	// NOTE: the output folders are added at the beginning of the binaryLocations
+	for (int i = 0, l = this.binaryLocations.length; i < l; i++)
+		if (this.binaryLocations[i].isPackage(qualifiedPackageName))
+			return true;
+	return false;
+}
+
+void setNames(String[] typeNames, SourceFile[] additionalFiles) {
+	// convert the initial typeNames to a set
+	if (typeNames == null) {
+		this.initialTypeNames = null;
+	} else {
+		this.initialTypeNames = new SimpleSet(typeNames.length);
+		for (int i = 0, l = typeNames.length; i < l; i++)
+			this.initialTypeNames.add(typeNames[i]);
+	}
+	// map the additional source files by qualified type name
+	if (additionalFiles == null) {
+		this.additionalUnits = null;
+	} else {
+		this.additionalUnits = new SimpleLookupTable(additionalFiles.length);
+		for (int i = 0, l = additionalFiles.length; i < l; i++) {
+			SourceFile additionalUnit = additionalFiles[i];
+			if (additionalUnit != null)
+				this.additionalUnits.put(additionalUnit.initialTypeName, additionalFiles[i]);
+		}
+	}
+
+	for (int i = 0, l = this.sourceLocations.length; i < l; i++)
+		this.sourceLocations[i].reset();
+	for (int i = 0, l = this.binaryLocations.length; i < l; i++)
+		this.binaryLocations[i].reset();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java
new file mode 100644
index 0000000..4cd5d4e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public final class NameSet {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public char[][] names;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public NameSet(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.names = new char[extraRoom][];
+}
+
+public char[] add(char[] name) {
+	int length = this.names.length;
+	int index = CharOperation.hashCode(name) % length;
+	char[] current;
+	while ((current = this.names[index]) != null) {
+		if (CharOperation.equals(current, name)) return current;
+		if (++index == length) index = 0;
+	}
+	this.names[index] = name;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return name;
+}
+
+private void rehash() {
+	NameSet newSet = new NameSet(this.elementSize * 2); // double the number of expected elements
+	char[] current;
+	for (int i = this.names.length; --i >= 0;)
+		if ((current = this.names[i]) != null)
+			newSet.add(current);
+
+	this.names = newSet.names;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	char[] name;
+	for (int i = 0, l = this.names.length; i < l; i++)
+		if ((name = this.names[i]) != null)
+			s += new String(name) + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java
new file mode 100644
index 0000000..da2281c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+import java.util.*;
+
+public class ProblemFactory extends DefaultProblemFactory {
+
+static SimpleLookupTable factories = new SimpleLookupTable(5);
+
+private ProblemFactory(Locale locale) {
+	super(locale);
+}
+
+public static ProblemFactory getProblemFactory(Locale locale) {
+	ProblemFactory factory = (ProblemFactory) factories.get(locale);
+	if (factory == null)
+		factories.put(locale, factory = new ProblemFactory(locale));
+	return factory;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java
new file mode 100644
index 0000000..e2bc1b4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public class QualifiedNameSet {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public char[][][] qualifiedNames;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public QualifiedNameSet(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.qualifiedNames = new char[extraRoom][][];
+}
+
+public char[][] add(char[][] qualifiedName) {
+	int qLength = qualifiedName.length;
+	if (qLength == 0) return CharOperation.NO_CHAR_CHAR;
+
+	int length = this.qualifiedNames.length;
+	int index = CharOperation.hashCode(qualifiedName[qLength - 1]) % length;
+	char[][] current;
+	while ((current = this.qualifiedNames[index]) != null) {
+		if (CharOperation.equals(current, qualifiedName)) return current;
+		if (++index == length) index = 0;
+	}
+	this.qualifiedNames[index] = qualifiedName;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return qualifiedName;
+}
+
+private void rehash() {
+	QualifiedNameSet newSet = new QualifiedNameSet(this.elementSize * 2); // double the number of expected elements
+	char[][] current;
+	for (int i = this.qualifiedNames.length; --i >= 0;)
+		if ((current = this.qualifiedNames[i]) != null)
+			newSet.add(current);
+
+	this.qualifiedNames = newSet.qualifiedNames;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	char[][] qualifiedName;
+	for (int i = 0, l = this.qualifiedNames.length; i < l; i++)
+		if ((qualifiedName = this.qualifiedNames[i]) != null)
+			s += CharOperation.toString(qualifiedName) + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java
new file mode 100644
index 0000000..6d8410b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Tim Hanson <thanson@bea.com> - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=137634
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+public class ReferenceCollection {
+
+char[][][] qualifiedNameReferences; // contains no simple names as in just 'a' which is kept in simpleNameReferences instead
+char[][] simpleNameReferences;
+char[][] rootReferences;
+
+protected ReferenceCollection(char[][][] qualifiedNameReferences, char[][] simpleNameReferences, char[][] rootReferences) {
+	this.qualifiedNameReferences = internQualifiedNames(qualifiedNameReferences, false);
+	this.simpleNameReferences = internSimpleNames(simpleNameReferences, true);
+	this.rootReferences = internSimpleNames(rootReferences, false);
+}
+
+public void addDependencies(String[] typeNameDependencies) {
+	// if each qualified type name is already known then all of its subNames can be skipped
+	// and its expected that very few qualified names in typeNameDependencies need to be added
+	// but could always take 'p1.p2.p3.X' and make all qualified names 'p1' 'p1.p2' 'p1.p2.p3' 'p1.p2.p3.X', then intern
+	char[][][] qNames = new char[typeNameDependencies.length][][];
+	for (int i = typeNameDependencies.length; --i >= 0;)
+		qNames[i] = CharOperation.splitOn('.', typeNameDependencies[i].toCharArray());
+	qNames = internQualifiedNames(qNames, false);
+
+	next : for (int i = qNames.length; --i >= 0;) {
+		char[][] qualifiedTypeName = qNames[i];
+		while (!includes(qualifiedTypeName)) {
+			if (!includes(qualifiedTypeName[qualifiedTypeName.length - 1])) {
+				int length = this.simpleNameReferences.length;
+				System.arraycopy(this.simpleNameReferences, 0, this.simpleNameReferences = new char[length + 1][], 0, length);
+				this.simpleNameReferences[length] = qualifiedTypeName[qualifiedTypeName.length - 1];
+			}
+			if (!insideRoot(qualifiedTypeName[0])) {
+				int length = this.rootReferences.length;
+				System.arraycopy(this.rootReferences, 0, this.rootReferences = new char[length + 1][], 0, length);
+				this.rootReferences[length] = qualifiedTypeName[0];
+			}
+			int length = this.qualifiedNameReferences.length;
+			System.arraycopy(this.qualifiedNameReferences, 0, this.qualifiedNameReferences = new char[length + 1][][], 0, length);
+			this.qualifiedNameReferences[length] = qualifiedTypeName;
+
+			qualifiedTypeName = CharOperation.subarray(qualifiedTypeName, 0, qualifiedTypeName.length - 1);
+			char[][][] temp = internQualifiedNames(new char[][][] {qualifiedTypeName}, false);
+			if (temp == EmptyQualifiedNames)
+				continue next; // qualifiedTypeName is a well known name
+			qualifiedTypeName = temp[0];
+		}
+	}
+}
+
+public boolean includes(char[] simpleName) {
+	for (int i = 0, l = this.simpleNameReferences.length; i < l; i++)
+		if (simpleName == this.simpleNameReferences[i]) return true;
+	return false;
+}
+
+public boolean includes(char[][] qualifiedName) {
+	for (int i = 0, l = this.qualifiedNameReferences.length; i < l; i++)
+		if (qualifiedName == this.qualifiedNameReferences[i]) return true;
+	return false;
+}
+
+/**
+ * @deprecated
+ */
+public boolean includes(char[][][] qualifiedNames, char[][] simpleNames) {
+	return includes(qualifiedNames, simpleNames, null);
+}
+
+public boolean includes(char[][][] qualifiedNames, char[][] simpleNames, char[][] rootNames) {
+	// if either collection of names is null, it means it contained a well known name so we know it already has a match
+	if (rootNames != null) {
+		boolean foundRoot = false;
+		for (int i = 0, l = rootNames.length; !foundRoot && i < l; i++)
+			foundRoot = insideRoot(rootNames[i]);
+		if (!foundRoot)
+			return false;
+	}
+	if (simpleNames == null || qualifiedNames == null) {
+		if (simpleNames == null && qualifiedNames == null) {
+			if (JavaBuilder.DEBUG)
+				System.out.println("Found well known match"); //$NON-NLS-1$
+			return true;
+		} else if (qualifiedNames == null) {
+			for (int i = 0, l = simpleNames.length; i < l; i++) {
+				if (includes(simpleNames[i])) {
+					if (JavaBuilder.DEBUG)
+						System.out.println("Found match in well known package to " + new String(simpleNames[i])); //$NON-NLS-1$
+					return true;
+				}
+			}
+		} else {
+			for (int i = 0, l = qualifiedNames.length; i < l; i++) {
+				char[][] qualifiedName = qualifiedNames[i];
+				if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) {
+					if (JavaBuilder.DEBUG)
+						System.out.println("Found well known match in " + CharOperation.toString(qualifiedName)); //$NON-NLS-1$
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	int sLength = simpleNames.length;
+	int qLength = qualifiedNames.length;
+	if (sLength <= qLength) {
+		for (int i = 0; i < sLength; i++) {
+			if (includes(simpleNames[i])) {
+				for (int j = 0; j < qLength; j++) {
+					char[][] qualifiedName = qualifiedNames[j];
+					if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("Found match in " + CharOperation.toString(qualifiedName) //$NON-NLS-1$
+								+ " to " + new String(simpleNames[i])); //$NON-NLS-1$
+						return true;
+					}
+				}
+				return false;
+			}
+		}
+	} else {
+		for (int i = 0; i < qLength; i++) {
+			char[][] qualifiedName = qualifiedNames[i];
+			if (qualifiedName.length == 1 ? includes(qualifiedName[0]) : includes(qualifiedName)) {
+				for (int j = 0; j < sLength; j++) {
+					if (includes(simpleNames[j])) {
+						if (JavaBuilder.DEBUG)
+							System.out.println("Found match in " + CharOperation.toString(qualifiedName) //$NON-NLS-1$
+								+ " to " + new String(simpleNames[j])); //$NON-NLS-1$
+						return true;
+					}
+				}
+				return false;
+			}
+		}
+	}
+	return false;
+}
+
+public boolean insideRoot(char[] rootName) {
+	for (int i = 0, l = this.rootReferences.length; i < l; i++)
+		if (rootName == this.rootReferences[i]) return true;
+	return false;
+}
+
+
+// When any type is compiled, its methods are verified for certain problems
+// the MethodVerifier requests 3 well known types which end up in the reference collection
+// having WellKnownQualifiedNames & WellKnownSimpleNames, saves every type 40 bytes
+// NOTE: These collections are sorted by length
+static final char[][][] WellKnownQualifiedNames = new char[][][] {
+	TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION,
+	TypeConstants.JAVA_LANG_THROWABLE,
+	TypeConstants.JAVA_LANG_OBJECT,
+	TypeConstants.JAVA_LANG,
+	new char[][] {TypeConstants.JAVA},
+	new char[][] {new char[] {'o', 'r', 'g'}},
+	new char[][] {new char[] {'c', 'o', 'm'}},
+	CharOperation.NO_CHAR_CHAR}; // default package
+static final char[][] WellKnownSimpleNames = new char[][] {
+	TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION[2],
+	TypeConstants.JAVA_LANG_THROWABLE[2],
+	TypeConstants.JAVA_LANG_OBJECT[2],
+	TypeConstants.JAVA,
+	TypeConstants.LANG,
+	new char[] {'o', 'r', 'g'},
+	new char[] {'c', 'o', 'm'}};
+
+static final char[][][] EmptyQualifiedNames = new char[0][][];
+static final char[][] EmptySimpleNames = CharOperation.NO_CHAR_CHAR;
+
+// each array contains qualified char[][], one for size 2, 3, 4, 5, 6, 7 & the rest
+static final int MaxQualifiedNames = 7;
+static QualifiedNameSet[] InternedQualifiedNames = new QualifiedNameSet[MaxQualifiedNames];
+// each array contains simple char[], one for size 1 to 29 & the rest
+static final int MaxSimpleNames = 30;
+static NameSet[] InternedSimpleNames = new NameSet[MaxSimpleNames];
+static {
+	for (int i = 0; i < MaxQualifiedNames; i++)
+		InternedQualifiedNames[i] = new QualifiedNameSet(37);
+	for (int i = 0; i < MaxSimpleNames; i++)
+		InternedSimpleNames[i] = new NameSet(37);
+}
+
+public static char[][][] internQualifiedNames(StringSet qualifiedStrings) {
+	if (qualifiedStrings == null) return EmptyQualifiedNames;
+	int length = qualifiedStrings.elementSize;
+	if (length == 0) return EmptyQualifiedNames;
+
+	char[][][] result = new char[length][][];
+	String[] strings = qualifiedStrings.values;
+	for (int i = 0, l = strings.length; i < l; i++)
+		if (strings[i] != null)
+			result[--length] = CharOperation.splitOn('/', strings[i].toCharArray());
+	return internQualifiedNames(result, false);
+}
+
+public static char[][][] internQualifiedNames(char[][][] qualifiedNames) {
+	return internQualifiedNames(qualifiedNames, false);
+}
+
+public static char[][][] internQualifiedNames(char[][][] qualifiedNames, boolean keepWellKnown) {
+	if (qualifiedNames == null) return EmptyQualifiedNames;
+	int length = qualifiedNames.length;
+	if (length == 0) return EmptyQualifiedNames;
+
+	char[][][] keepers = new char[length][][];
+	int index = 0;
+	next : for (int i = 0; i < length; i++) {
+		char[][] qualifiedName = qualifiedNames[i];
+		int qLength = qualifiedName.length;
+		for (int j = 0, m = WellKnownQualifiedNames.length; j < m; j++) {
+			char[][] wellKnownName = WellKnownQualifiedNames[j];
+			if (qLength > wellKnownName.length)
+				break; // all remaining well known names are shorter
+			if (CharOperation.equals(qualifiedName, wellKnownName)) {
+				if (keepWellKnown) {
+					keepers[index++] = wellKnownName;
+				}
+				continue next;
+			}
+		}
+
+		// InternedQualifiedNames[0] is for the rest (> 7 & 1)
+		// InternedQualifiedNames[1] is for size 2...
+		// InternedQualifiedNames[6] is for size 7
+		QualifiedNameSet internedNames = InternedQualifiedNames[qLength <= MaxQualifiedNames ? qLength - 1 : 0];
+		qualifiedName = internSimpleNames(qualifiedName, false);
+		keepers[index++] = internedNames.add(qualifiedName);
+	}
+	if (length > index) {
+		if (index == 0) return EmptyQualifiedNames;
+		System.arraycopy(keepers, 0, keepers = new char[index][][], 0, index);
+	}
+	return keepers;
+}
+
+/**
+ * @deprecated
+ */
+public static char[][] internSimpleNames(StringSet simpleStrings) {
+	return internSimpleNames(simpleStrings, true);
+}
+
+public static char[][] internSimpleNames(StringSet simpleStrings, boolean removeWellKnown) {
+	if (simpleStrings == null) return EmptySimpleNames;
+	int length = simpleStrings.elementSize;
+	if (length == 0) return EmptySimpleNames;
+
+	char[][] result = new char[length][];
+	String[] strings = simpleStrings.values;
+	for (int i = 0, l = strings.length; i < l; i++)
+		if (strings[i] != null)
+			result[--length] = strings[i].toCharArray();
+	return internSimpleNames(result, removeWellKnown);
+}
+
+public static char[][] internSimpleNames(char[][] simpleNames, boolean removeWellKnown) {
+	if (simpleNames == null) return EmptySimpleNames;
+	int length = simpleNames.length;
+	if (length == 0) return EmptySimpleNames;
+
+	char[][] keepers = new char[length][];
+	int index = 0;
+	next : for (int i = 0; i < length; i++) {
+		char[] name = simpleNames[i];
+		int sLength = name.length;
+		for (int j = 0, m = WellKnownSimpleNames.length; j < m; j++) {
+			char[] wellKnownName = WellKnownSimpleNames[j];
+			if (sLength > wellKnownName.length)
+				break; // all remaining well known names are shorter
+			if (CharOperation.equals(name, wellKnownName)) {
+				if (!removeWellKnown)
+					keepers[index++] = WellKnownSimpleNames[j];
+				continue next;
+			}
+		}
+
+		// InternedSimpleNames[0] is for the rest (> 29)
+		// InternedSimpleNames[1] is for size 1...
+		// InternedSimpleNames[29] is for size 29
+		NameSet internedNames = InternedSimpleNames[sLength < MaxSimpleNames ? sLength : 0];
+		keepers[index++] = internedNames.add(name);
+	}
+	if (length > index) {
+		if (index == 0) return EmptySimpleNames;
+		System.arraycopy(keepers, 0, keepers = new char[index][], 0, index);
+	}
+	return keepers;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java
new file mode 100644
index 0000000..4a5b04d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class SourceFile implements ICompilationUnit {
+
+public IFile resource;
+ClasspathMultiDirectory sourceLocation;
+String initialTypeName;
+boolean updateClassFile;
+
+public SourceFile(IFile resource, ClasspathMultiDirectory sourceLocation) {
+	this.resource = resource;
+	this.sourceLocation = sourceLocation;
+	this.initialTypeName = extractTypeName();
+	this.updateClassFile = false;
+}
+
+public SourceFile(IFile resource, ClasspathMultiDirectory sourceLocation, boolean updateClassFile) {
+	this(resource, sourceLocation);
+
+	this.updateClassFile = updateClassFile;
+}
+
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof SourceFile)) return false;
+
+	SourceFile f = (SourceFile) o;
+	return this.sourceLocation == f.sourceLocation && this.resource.getFullPath().equals(f.resource.getFullPath());
+}
+
+String extractTypeName() {
+	// answer a String with the qualified type name for the source file in the form: 'p1/p2/A'
+	IPath fullPath = this.resource.getFullPath();
+	int resourceSegmentCount = fullPath.segmentCount();
+	int sourceFolderSegmentCount = this.sourceLocation.sourceFolder.getFullPath().segmentCount();
+	int charCount = (resourceSegmentCount - sourceFolderSegmentCount - 1);
+	resourceSegmentCount--; // deal with the last segment separately
+	for (int i = sourceFolderSegmentCount; i < resourceSegmentCount; i++)
+		charCount += fullPath.segment(i).length();
+	String lastSegment = fullPath.segment(resourceSegmentCount);
+	int extensionIndex = Util.indexOfJavaLikeExtension(lastSegment);
+	charCount += extensionIndex;
+
+	char[] result = new char[charCount];
+	int offset = 0;
+	for (int i = sourceFolderSegmentCount; i < resourceSegmentCount; i++) {
+		String segment = fullPath.segment(i);
+		int size = segment.length();
+		segment.getChars(0, size, result, offset);
+		offset += size;
+		result[offset++] = '/';
+	}
+	lastSegment.getChars(0, extensionIndex, result, offset);
+	return new String(result);
+}
+
+public char[] getContents() {
+
+	try {
+		return Util.getResourceContentsAsCharArray(this.resource);
+	} catch (CoreException e) {
+		throw new AbortCompilation(true, new MissingSourceFileException(this.resource.getFullPath().toString()));
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.resource.getFullPath().toString().toCharArray(); // do not know what you want to return here
+}
+
+public char[] getMainTypeName() {
+	char[] typeName = this.initialTypeName.toCharArray();
+	int lastIndex = CharOperation.lastIndexOf('/', typeName);
+	return CharOperation.subarray(typeName, lastIndex + 1, -1);
+}
+
+public char[][] getPackageName() {
+	char[] typeName = this.initialTypeName.toCharArray();
+	int lastIndex = CharOperation.lastIndexOf('/', typeName);
+	return CharOperation.splitOn('/', typeName, 0, lastIndex);
+}
+public int hashCode() {
+	return this.initialTypeName.hashCode();
+}
+public boolean ignoreOptionalProblems() {
+	return this.sourceLocation.ignoreOptionalProblems;
+}
+String typeLocator() {
+	return this.resource.getProjectRelativePath().toString();
+}
+
+public String toString() {
+	return "SourceFile[" //$NON-NLS-1$
+		+ this.resource.getFullPath() + "]";  //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
new file mode 100644
index 0000000..6dfb1ec
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
@@ -0,0 +1,766 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.ClasspathAccessRule;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+
+import java.io.*;
+import java.util.*;
+
+public class State {
+// NOTE: this state cannot contain types that are not defined in this project
+
+String javaProjectName;
+public ClasspathMultiDirectory[] sourceLocations;
+ClasspathLocation[] binaryLocations;
+// keyed by the project relative path of the type (i.e. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection
+SimpleLookupTable references;
+// keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java"
+public SimpleLookupTable typeLocators;
+
+int buildNumber;
+long lastStructuralBuildTime;
+SimpleLookupTable structuralBuildTimes;
+
+private String[] knownPackageNames; // of the form "p1/p2"
+
+private long previousStructuralBuildTime;
+private StringSet structurallyChangedTypes;
+public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed
+
+public static final byte VERSION = 0x001B;
+
+static final byte SOURCE_FOLDER = 1;
+static final byte BINARY_FOLDER = 2;
+static final byte EXTERNAL_JAR = 3;
+static final byte INTERNAL_JAR = 4;
+
+State() {
+	// constructor with no argument
+}
+
+protected State(JavaBuilder javaBuilder) {
+	this.knownPackageNames = null;
+	this.previousStructuralBuildTime = -1;
+	this.structurallyChangedTypes = null;
+	this.javaProjectName = javaBuilder.currentProject.getName();
+	this.sourceLocations = javaBuilder.nameEnvironment.sourceLocations;
+	this.binaryLocations = javaBuilder.nameEnvironment.binaryLocations;
+	this.references = new SimpleLookupTable(7);
+	this.typeLocators = new SimpleLookupTable(7);
+
+	this.buildNumber = 0; // indicates a full build
+	this.lastStructuralBuildTime = computeStructuralBuildTime(javaBuilder.lastState == null ? 0 : javaBuilder.lastState.lastStructuralBuildTime);
+	this.structuralBuildTimes = new SimpleLookupTable(3);
+}
+
+long computeStructuralBuildTime(long previousTime) {
+	long newTime = System.currentTimeMillis();
+	if (newTime <= previousTime)
+		newTime = previousTime + 1;
+	return newTime;
+}
+
+void copyFrom(State lastState) {
+	this.knownPackageNames = null;
+	this.previousStructuralBuildTime = lastState.previousStructuralBuildTime;
+	this.structurallyChangedTypes = lastState.structurallyChangedTypes;
+	this.buildNumber = lastState.buildNumber + 1;
+	this.lastStructuralBuildTime = lastState.lastStructuralBuildTime;
+	this.structuralBuildTimes = lastState.structuralBuildTimes;
+
+	try {
+		this.references = (SimpleLookupTable) lastState.references.clone();
+		this.typeLocators = (SimpleLookupTable) lastState.typeLocators.clone();
+	} catch (CloneNotSupportedException e) {
+		this.references = new SimpleLookupTable(lastState.references.elementSize);
+		Object[] keyTable = lastState.references.keyTable;
+		Object[] valueTable = lastState.references.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++)
+			if (keyTable[i] != null)
+				this.references.put(keyTable[i], valueTable[i]);
+
+		this.typeLocators = new SimpleLookupTable(lastState.typeLocators.elementSize);
+		keyTable = lastState.typeLocators.keyTable;
+		valueTable = lastState.typeLocators.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++)
+			if (keyTable[i] != null)
+				this.typeLocators.put(keyTable[i], valueTable[i]);
+	}
+}
+public char[][] getDefinedTypeNamesFor(String typeLocator) {
+	Object c = this.references.get(typeLocator);
+	if (c instanceof AdditionalTypeCollection)
+		return ((AdditionalTypeCollection) c).definedTypeNames;
+	return null; // means only one type is defined with the same name as the file... saves space
+}
+
+public SimpleLookupTable getReferences() {
+	return this.references;
+}
+
+StringSet getStructurallyChangedTypes(State prereqState) {
+	if (prereqState != null && prereqState.previousStructuralBuildTime > 0) {
+		Object o = this.structuralBuildTimes.get(prereqState.javaProjectName);
+		long previous = o == null ? 0 : ((Long) o).longValue();
+		if (previous == prereqState.previousStructuralBuildTime)
+			return prereqState.structurallyChangedTypes;
+	}
+	return null;
+}
+
+public boolean isDuplicateLocator(String qualifiedTypeName, String typeLocator) {
+	String existing = (String) this.typeLocators.get(qualifiedTypeName);
+	return existing != null && !existing.equals(typeLocator);
+}
+
+public boolean isKnownPackage(String qualifiedPackageName) {
+	if (this.knownPackageNames == null) {
+		ArrayList names = new ArrayList(this.typeLocators.elementSize);
+		Object[] keyTable = this.typeLocators.keyTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				String packageName = (String) keyTable[i]; // is a type name of the form p1/p2/A
+				int last = packageName.lastIndexOf('/');
+				packageName = last == -1 ? null : packageName.substring(0, last);
+				while (packageName != null && !names.contains(packageName)) {
+					names.add(packageName);
+					last = packageName.lastIndexOf('/');
+					packageName = last == -1 ? null : packageName.substring(0, last);
+				}
+			}
+		}
+		this.knownPackageNames = new String[names.size()];
+		names.toArray(this.knownPackageNames);
+	}
+	for (int i = 0, l = this.knownPackageNames.length; i < l; i++)
+		if (this.knownPackageNames[i].equals(qualifiedPackageName))
+			return true;
+	return false;
+}
+
+public boolean isKnownType(String qualifiedTypeName) {
+	return this.typeLocators.containsKey(qualifiedTypeName);
+}
+
+boolean isSourceFolderEmpty(IContainer sourceFolder) {
+	String sourceFolderName = sourceFolder.getProjectRelativePath().addTrailingSeparator().toString();
+	Object[] table = this.typeLocators.valueTable;
+	for (int i = 0, l = table.length; i < l; i++)
+		if (table[i] != null && ((String) table[i]).startsWith(sourceFolderName))
+			return false;
+	return true;
+}
+
+void record(String typeLocator, char[][][] qualifiedRefs, char[][] simpleRefs, char[][] rootRefs, char[] mainTypeName, ArrayList typeNames) {
+	if (typeNames.size() == 1 && CharOperation.equals(mainTypeName, (char[]) typeNames.get(0))) {
+		this.references.put(typeLocator, new ReferenceCollection(qualifiedRefs, simpleRefs, rootRefs));
+	} else {
+		char[][] definedTypeNames = new char[typeNames.size()][]; // can be empty when no types are defined
+		typeNames.toArray(definedTypeNames);
+		this.references.put(typeLocator, new AdditionalTypeCollection(definedTypeNames, qualifiedRefs, simpleRefs, rootRefs));
+	}
+}
+
+void recordLocatorForType(String qualifiedTypeName, String typeLocator) {
+	this.knownPackageNames = null;
+	// in the common case, the qualifiedTypeName is a substring of the typeLocator so share the char[] by using String.substring()
+	int start = typeLocator.indexOf(qualifiedTypeName, 0);
+	if (start > 0)
+		qualifiedTypeName = typeLocator.substring(start, start + qualifiedTypeName.length());
+	this.typeLocators.put(qualifiedTypeName, typeLocator);
+}
+
+void recordStructuralDependency(IProject prereqProject, State prereqState) {
+	if (prereqState != null)
+		if (prereqState.lastStructuralBuildTime > 0) // can skip if 0 (full build) since its assumed to be 0 if unknown
+			this.structuralBuildTimes.put(prereqProject.getName(), new Long(prereqState.lastStructuralBuildTime));
+}
+
+void removeLocator(String typeLocatorToRemove) {
+	this.knownPackageNames = null;
+	this.references.removeKey(typeLocatorToRemove);
+	this.typeLocators.removeValue(typeLocatorToRemove);
+}
+
+void removePackage(IResourceDelta sourceDelta) {
+	IResource resource = sourceDelta.getResource();
+	switch(resource.getType()) {
+		case IResource.FOLDER :
+			IResourceDelta[] children = sourceDelta.getAffectedChildren();
+			for (int i = 0, l = children.length; i < l; i++)
+				removePackage(children[i]);
+			return;
+		case IResource.FILE :
+			IPath typeLocatorPath = resource.getProjectRelativePath();
+			if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(typeLocatorPath.lastSegment()))
+				removeLocator(typeLocatorPath.toString());
+	}
+}
+
+void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
+	this.knownPackageNames = null;
+	this.typeLocators.removeKey(qualifiedTypeNameToRemove);
+}
+
+static State read(IProject project, DataInputStream in) throws IOException {
+	if (JavaBuilder.DEBUG)
+		System.out.println("About to read state " + project.getName()); //$NON-NLS-1$
+	if (VERSION != in.readByte()) {
+		if (JavaBuilder.DEBUG)
+			System.out.println("Found non-compatible state version... answered null for " + project.getName()); //$NON-NLS-1$
+		return null;
+	}
+
+	State newState = new State();
+	newState.javaProjectName = in.readUTF();
+	if (!project.getName().equals(newState.javaProjectName)) {
+		if (JavaBuilder.DEBUG)
+			System.out.println("Project's name does not match... answered null"); //$NON-NLS-1$
+		return null;
+	}
+	newState.buildNumber = in.readInt();
+	newState.lastStructuralBuildTime = in.readLong();
+
+	int length = in.readInt();
+	newState.sourceLocations = new ClasspathMultiDirectory[length];
+	for (int i = 0; i < length; i++) {
+		IContainer sourceFolder = project, outputFolder = project;
+		String folderName;
+		if ((folderName = in.readUTF()).length() > 0) sourceFolder = project.getFolder(folderName);
+		if ((folderName = in.readUTF()).length() > 0) outputFolder = project.getFolder(folderName);
+		ClasspathMultiDirectory md =
+			(ClasspathMultiDirectory) ClasspathLocation.forSourceFolder(sourceFolder, outputFolder, readNames(in), readNames(in), in.readBoolean());
+		if (in.readBoolean())
+			md.hasIndependentOutputFolder = true;
+		newState.sourceLocations[i] = md;
+	}
+
+	length = in.readInt();
+	newState.binaryLocations = new ClasspathLocation[length];
+	IWorkspaceRoot root = project.getWorkspace().getRoot();
+	for (int i = 0; i < length; i++) {
+		switch (in.readByte()) {
+			case SOURCE_FOLDER :
+				newState.binaryLocations[i] = newState.sourceLocations[in.readInt()];
+				break;
+			case BINARY_FOLDER :
+				IPath path = new Path(in.readUTF());
+				IContainer outputFolder = path.segmentCount() == 1
+					? (IContainer) root.getProject(path.toString())
+					: (IContainer) root.getFolder(path);
+				newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(), readRestriction(in));
+				break;
+			case EXTERNAL_JAR :
+				newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF(), in.readLong(), readRestriction(in));
+				break;
+			case INTERNAL_JAR :
+				newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())), readRestriction(in));
+		}
+	}
+
+	newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt());
+	for (int i = 0; i < length; i++)
+		newState.structuralBuildTimes.put(in.readUTF(), new Long(in.readLong()));
+
+	String[] internedTypeLocators = new String[length = in.readInt()];
+	for (int i = 0; i < length; i++)
+		internedTypeLocators[i] = in.readUTF();
+
+	newState.typeLocators = new SimpleLookupTable(length = in.readInt());
+	for (int i = 0; i < length; i++)
+		newState.recordLocatorForType(in.readUTF(), internedTypeLocators[in.readInt()]);
+
+	char[][] internedRootNames = ReferenceCollection.internSimpleNames(readNames(in), false);
+	char[][] internedSimpleNames = ReferenceCollection.internSimpleNames(readNames(in), false);
+	char[][][] internedQualifiedNames = new char[length = in.readInt()][][];
+	for (int i = 0; i < length; i++) {
+		int qLength = in.readInt();
+		char[][] qName = new char[qLength][];
+		for (int j = 0; j < qLength; j++)
+			qName[j] = internedSimpleNames[in.readInt()];
+		internedQualifiedNames[i] = qName;
+	}
+	internedQualifiedNames = ReferenceCollection.internQualifiedNames(internedQualifiedNames, false);
+
+	newState.references = new SimpleLookupTable(length = in.readInt());
+	for (int i = 0; i < length; i++) {
+		String typeLocator = internedTypeLocators[in.readInt()];
+		ReferenceCollection collection = null;
+		switch (in.readByte()) {
+			case 1 :
+				char[][] additionalTypeNames = readNames(in);
+				char[][][] qualifiedNames = new char[in.readInt()][][];
+				for (int j = 0, m = qualifiedNames.length; j < m; j++)
+					qualifiedNames[j] = internedQualifiedNames[in.readInt()];
+				char[][] simpleNames = new char[in.readInt()][];
+				for (int j = 0, m = simpleNames.length; j < m; j++)
+					simpleNames[j] = internedSimpleNames[in.readInt()];
+				char[][] rootNames = new char[in.readInt()][];
+				for (int j = 0, m = rootNames.length; j < m; j++)
+					rootNames[j] = internedRootNames[in.readInt()];
+				collection = new AdditionalTypeCollection(additionalTypeNames, qualifiedNames, simpleNames, rootNames);
+				break;
+			case 2 :
+				char[][][] qNames = new char[in.readInt()][][];
+				for (int j = 0, m = qNames.length; j < m; j++)
+					qNames[j] = internedQualifiedNames[in.readInt()];
+				char[][] sNames = new char[in.readInt()][];
+				for (int j = 0, m = sNames.length; j < m; j++)
+					sNames[j] = internedSimpleNames[in.readInt()];
+				char[][] rNames = new char[in.readInt()][];
+				for (int j = 0, m = rNames.length; j < m; j++)
+					rNames[j] = internedRootNames[in.readInt()];
+				collection = new ReferenceCollection(qNames, sNames, rNames);
+		}
+		newState.references.put(typeLocator, collection);
+	}
+	if (JavaBuilder.DEBUG)
+		System.out.println("Successfully read state for " + newState.javaProjectName); //$NON-NLS-1$
+	return newState;
+}
+
+private static char[] readName(DataInputStream in) throws IOException {
+	int nLength = in.readInt();
+	char[] name = new char[nLength];
+	for (int j = 0; j < nLength; j++)
+		name[j] = in.readChar();
+	return name;
+}
+
+private static char[][] readNames(DataInputStream in) throws IOException {
+	int length = in.readInt();
+	char[][] names = new char[length][];
+	for (int i = 0; i < length; i++)
+		names[i] = readName(in);
+	return names;
+}
+
+private static AccessRuleSet readRestriction(DataInputStream in) throws IOException {
+	int length = in.readInt();
+	if (length == 0) return null; // no restriction specified
+	AccessRule[] accessRules = new AccessRule[length];
+	for (int i = 0; i < length; i++) {
+		char[] pattern = readName(in);
+		int problemId = in.readInt();
+		accessRules[i] = new ClasspathAccessRule(pattern, problemId);
+	}
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	return new AccessRuleSet(accessRules, in.readByte(), manager.intern(in.readUTF()));
+}
+
+void tagAsNoopBuild() {
+	this.buildNumber = -1; // tag the project since it has no source folders and can be skipped
+}
+
+boolean wasNoopBuild() {
+	return this.buildNumber == -1;
+}
+
+void tagAsStructurallyChanged() {
+	this.previousStructuralBuildTime = this.lastStructuralBuildTime;
+	this.structurallyChangedTypes = new StringSet(7);
+	this.lastStructuralBuildTime = computeStructuralBuildTime(this.previousStructuralBuildTime);
+}
+
+boolean wasStructurallyChanged(IProject prereqProject, State prereqState) {
+	if (prereqState != null) {
+		Object o = this.structuralBuildTimes.get(prereqProject.getName());
+		long previous = o == null ? 0 : ((Long) o).longValue();
+		if (previous == prereqState.lastStructuralBuildTime) return false;
+	}
+	return true;
+}
+
+void wasStructurallyChanged(String typeName) {
+	if (this.structurallyChangedTypes != null) {
+		if (this.structurallyChangedTypes.elementSize > MaxStructurallyChangedTypes)
+			this.structurallyChangedTypes = null; // too many to keep track of
+		else
+			this.structurallyChangedTypes.add(typeName);
+	}
+}
+
+void write(DataOutputStream out) throws IOException {
+	int length;
+	Object[] keyTable;
+	Object[] valueTable;
+
+/*
+ * byte		VERSION
+ * String		project name
+ * int			build number
+ * int			last structural build number
+*/
+	out.writeByte(VERSION);
+	out.writeUTF(this.javaProjectName);
+	out.writeInt(this.buildNumber);
+	out.writeLong(this.lastStructuralBuildTime);
+
+/*
+ * ClasspathMultiDirectory[]
+ * int			id
+ * String		path(s)
+*/
+	out.writeInt(length = this.sourceLocations.length);
+	for (int i = 0; i < length; i++) {
+		ClasspathMultiDirectory md = this.sourceLocations[i];
+		out.writeUTF(md.sourceFolder.getProjectRelativePath().toString());
+		out.writeUTF(md.binaryFolder.getProjectRelativePath().toString());
+		writeNames(md.inclusionPatterns, out);
+		writeNames(md.exclusionPatterns, out);
+		out.writeBoolean(md.ignoreOptionalProblems);
+		out.writeBoolean(md.hasIndependentOutputFolder);
+	}
+
+/*
+ * ClasspathLocation[]
+ * int			id
+ * String		path(s)
+*/
+	out.writeInt(length = this.binaryLocations.length);
+	next : for (int i = 0; i < length; i++) {
+		ClasspathLocation c = this.binaryLocations[i];
+		if (c instanceof ClasspathMultiDirectory) {
+			out.writeByte(SOURCE_FOLDER);
+			for (int j = 0, m = this.sourceLocations.length; j < m; j++) {
+				if (this.sourceLocations[j] == c) {
+					out.writeInt(j);
+					continue next;
+				}
+			}
+		} else if (c instanceof ClasspathDirectory) {
+			out.writeByte(BINARY_FOLDER);
+			ClasspathDirectory cd = (ClasspathDirectory) c;
+			out.writeUTF(cd.binaryFolder.getFullPath().toString());
+			out.writeBoolean(cd.isOutputFolder);
+			writeRestriction(cd.accessRuleSet, out);
+		} else {
+			ClasspathJar jar = (ClasspathJar) c;
+			if (jar.resource == null) {
+				out.writeByte(EXTERNAL_JAR);
+				out.writeUTF(jar.zipFilename);
+				out.writeLong(jar.lastModified());
+			} else {
+				out.writeByte(INTERNAL_JAR);
+				out.writeUTF(jar.resource.getFullPath().toString());
+			}
+			writeRestriction(jar.accessRuleSet, out);
+		}
+	}
+
+/*
+ * Structural build numbers table
+ * String		prereq project name
+ * int			last structural build number
+*/
+	out.writeInt(length = this.structuralBuildTimes.elementSize);
+	if (length > 0) {
+		keyTable = this.structuralBuildTimes.keyTable;
+		valueTable = this.structuralBuildTimes.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				length--;
+				out.writeUTF((String) keyTable[i]);
+				out.writeLong(((Long) valueTable[i]).longValue());
+			}
+		}
+		if (JavaBuilder.DEBUG && length != 0)
+			System.out.println("structuralBuildNumbers table is inconsistent"); //$NON-NLS-1$
+	}
+
+/*
+ * String[]	Interned type locators
+ */
+	out.writeInt(length = this.references.elementSize);
+	SimpleLookupTable internedTypeLocators = new SimpleLookupTable(length);
+	if (length > 0) {
+		keyTable = this.references.keyTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				length--;
+				String key = (String) keyTable[i];
+				out.writeUTF(key);
+				internedTypeLocators.put(key, new Integer(internedTypeLocators.elementSize));
+			}
+		}
+		if (JavaBuilder.DEBUG && length != 0)
+			System.out.println("references table is inconsistent"); //$NON-NLS-1$
+	}
+
+/*
+ * Type locators table
+ * String		type name
+ * int			interned locator id
+ */
+	out.writeInt(length = this.typeLocators.elementSize);
+	if (length > 0) {
+		keyTable = this.typeLocators.keyTable;
+		valueTable = this.typeLocators.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				length--;
+				out.writeUTF((String) keyTable[i]);
+				Integer index = (Integer) internedTypeLocators.get(valueTable[i]);
+				out.writeInt(index.intValue());
+			}
+		}
+		if (JavaBuilder.DEBUG && length != 0)
+			System.out.println("typeLocators table is inconsistent"); //$NON-NLS-1$
+	}
+
+/*
+ * char[][]	Interned root names
+ * char[][][]	Interned qualified names
+ * char[][]	Interned simple names
+ */
+	SimpleLookupTable internedRootNames = new SimpleLookupTable(3);
+	SimpleLookupTable internedQualifiedNames = new SimpleLookupTable(31);
+	SimpleLookupTable internedSimpleNames = new SimpleLookupTable(31);
+	valueTable = this.references.valueTable;
+	for (int i = 0, l = valueTable.length; i < l; i++) {
+		if (valueTable[i] != null) {
+			ReferenceCollection collection = (ReferenceCollection) valueTable[i];
+			char[][] rNames = collection.rootReferences;
+			for (int j = 0, m = rNames.length; j < m; j++) {
+				char[] rName = rNames[j];
+				if (!internedRootNames.containsKey(rName)) // remember the names have been interned
+					internedRootNames.put(rName, new Integer(internedRootNames.elementSize));
+			}
+			char[][][] qNames = collection.qualifiedNameReferences;
+			for (int j = 0, m = qNames.length; j < m; j++) {
+				char[][] qName = qNames[j];
+				if (!internedQualifiedNames.containsKey(qName)) { // remember the names have been interned
+					internedQualifiedNames.put(qName, new Integer(internedQualifiedNames.elementSize));
+					for (int k = 0, n = qName.length; k < n; k++) {
+						char[] sName = qName[k];
+						if (!internedSimpleNames.containsKey(sName)) // remember the names have been interned
+							internedSimpleNames.put(sName, new Integer(internedSimpleNames.elementSize));
+					}
+				}
+			}
+			char[][] sNames = collection.simpleNameReferences;
+			for (int j = 0, m = sNames.length; j < m; j++) {
+				char[] sName = sNames[j];
+				if (!internedSimpleNames.containsKey(sName)) // remember the names have been interned
+					internedSimpleNames.put(sName, new Integer(internedSimpleNames.elementSize));
+			}
+		}
+	}
+	char[][] internedArray = new char[internedRootNames.elementSize][];
+	Object[] rootNames = internedRootNames.keyTable;
+	Object[] positions = internedRootNames.valueTable;
+	for (int i = positions.length; --i >= 0; ) {
+		if (positions[i] != null) {
+			int index = ((Integer) positions[i]).intValue();
+			internedArray[index] = (char[]) rootNames[i];
+		}
+	}
+	writeNames(internedArray, out);
+	// now write the interned simple names
+	internedArray = new char[internedSimpleNames.elementSize][];
+	Object[] simpleNames = internedSimpleNames.keyTable;
+	positions = internedSimpleNames.valueTable;
+	for (int i = positions.length; --i >= 0; ) {
+		if (positions[i] != null) {
+			int index = ((Integer) positions[i]).intValue();
+			internedArray[index] = (char[]) simpleNames[i];
+		}
+	}
+	writeNames(internedArray, out);
+	// now write the interned qualified names as arrays of interned simple names
+	char[][][] internedQArray = new char[internedQualifiedNames.elementSize][][];
+	Object[] qualifiedNames = internedQualifiedNames.keyTable;
+	positions = internedQualifiedNames.valueTable;
+	for (int i = positions.length; --i >= 0; ) {
+		if (positions[i] != null) {
+			int index = ((Integer) positions[i]).intValue();
+			internedQArray[index] = (char[][]) qualifiedNames[i];
+		}
+	}
+	out.writeInt(length = internedQArray.length);
+	for (int i = 0; i < length; i++) {
+		char[][] qName = internedQArray[i];
+		int qLength = qName.length;
+		out.writeInt(qLength);
+		for (int j = 0; j < qLength; j++) {
+			Integer index = (Integer) internedSimpleNames.get(qName[j]);
+			out.writeInt(index.intValue());
+		}
+	}
+
+/*
+ * References table
+ * int		interned locator id
+ * ReferenceCollection
+*/
+	out.writeInt(length = this.references.elementSize);
+	if (length > 0) {
+		keyTable = this.references.keyTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				length--;
+				Integer index = (Integer) internedTypeLocators.get(keyTable[i]);
+				out.writeInt(index.intValue());
+				ReferenceCollection collection = (ReferenceCollection) valueTable[i];
+				if (collection instanceof AdditionalTypeCollection) {
+					out.writeByte(1);
+					AdditionalTypeCollection atc = (AdditionalTypeCollection) collection;
+					writeNames(atc.definedTypeNames, out);
+				} else {
+					out.writeByte(2);
+				}
+				char[][][] qNames = collection.qualifiedNameReferences;
+				int qLength = qNames.length;
+				out.writeInt(qLength);
+				for (int j = 0; j < qLength; j++) {
+					index = (Integer) internedQualifiedNames.get(qNames[j]);
+					out.writeInt(index.intValue());
+				}
+				char[][] sNames = collection.simpleNameReferences;
+				int sLength = sNames.length;
+				out.writeInt(sLength);
+				for (int j = 0; j < sLength; j++) {
+					index = (Integer) internedSimpleNames.get(sNames[j]);
+					out.writeInt(index.intValue());
+				}
+				char[][] rNames = collection.rootReferences;
+				int rLength = rNames.length;
+				out.writeInt(rLength);
+				for (int j = 0; j < rLength; j++) {
+					index = (Integer) internedRootNames.get(rNames[j]);
+					out.writeInt(index.intValue());
+				}
+			}
+		}
+		if (JavaBuilder.DEBUG && length != 0)
+			System.out.println("references table is inconsistent"); //$NON-NLS-1$
+	}
+}
+
+private void writeName(char[] name, DataOutputStream out) throws IOException {
+	int nLength = name.length;
+	out.writeInt(nLength);
+	for (int j = 0; j < nLength; j++)
+		out.writeChar(name[j]);
+}
+
+private void writeNames(char[][] names, DataOutputStream out) throws IOException {
+	int length = names == null ? 0 : names.length;
+	out.writeInt(length);
+	for (int i = 0; i < length; i++)
+		writeName(names[i], out);
+}
+
+private void writeRestriction(AccessRuleSet accessRuleSet, DataOutputStream out) throws IOException {
+	if (accessRuleSet == null) {
+		out.writeInt(0);
+	} else {
+		AccessRule[] accessRules = accessRuleSet.getAccessRules();
+		int length = accessRules.length;
+		out.writeInt(length);
+		if (length != 0) {
+			for (int i = 0; i < length; i++) {
+				AccessRule accessRule = accessRules[i];
+				writeName(accessRule.pattern, out);
+				out.writeInt(accessRule.problemId);
+			}
+			out.writeByte(accessRuleSet.classpathEntryType);
+			out.writeUTF(accessRuleSet.classpathEntryName);
+		}
+	}
+}
+
+/**
+ * Returns a string representation of the receiver.
+ */
+public String toString() {
+	return "State for " + this.javaProjectName //$NON-NLS-1$
+		+ " (#" + this.buildNumber //$NON-NLS-1$
+			+ " @ " + new Date(this.lastStructuralBuildTime) //$NON-NLS-1$
+				+ ")"; //$NON-NLS-1$
+}
+
+/* Debug helper
+void dump() {
+	System.out.println("State for " + javaProjectName + " (" + buildNumber + " @ " + new Date(lastStructuralBuildTime) + ")");
+	System.out.println("\tClass path source locations:");
+	for (int i = 0, l = sourceLocations.length; i < l; i++)
+		System.out.println("\t\t" + sourceLocations[i]);
+	System.out.println("\tClass path binary locations:");
+	for (int i = 0, l = binaryLocations.length; i < l; i++)
+		System.out.println("\t\t" + binaryLocations[i]);
+
+	System.out.print("\tStructural build numbers table:");
+	if (structuralBuildTimes.elementSize == 0) {
+		System.out.print(" <empty>");
+	} else {
+		Object[] keyTable = structuralBuildTimes.keyTable;
+		Object[] valueTable = structuralBuildTimes.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++)
+			if (keyTable[i] != null)
+				System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
+	}
+
+	System.out.print("\tType locators table:");
+	if (typeLocators.elementSize == 0) {
+		System.out.print(" <empty>");
+	} else {
+		Object[] keyTable = typeLocators.keyTable;
+		Object[] valueTable = typeLocators.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++)
+			if (keyTable[i] != null)
+				System.out.print("\n\t\t" + keyTable[i].toString() + " -> " + valueTable[i].toString());
+	}
+
+	System.out.print("\n\tReferences table:");
+	if (references.elementSize == 0) {
+		System.out.print(" <empty>");
+	} else {
+		Object[] keyTable = references.keyTable;
+		Object[] valueTable = references.valueTable;
+		for (int i = 0, l = keyTable.length; i < l; i++) {
+			if (keyTable[i] != null) {
+				System.out.print("\n\t\t" + keyTable[i].toString());
+				ReferenceCollection c = (ReferenceCollection) valueTable[i];
+				char[][][] qRefs = c.qualifiedNameReferences;
+				System.out.print("\n\t\t\tqualified:");
+				if (qRefs.length == 0)
+					System.out.print(" <empty>");
+				else for (int j = 0, m = qRefs.length; j < m; j++)
+						System.out.print("  '" + CharOperation.toString(qRefs[j]) + "'");
+				char[][] sRefs = c.simpleNameReferences;
+				System.out.print("\n\t\t\tsimple:");
+				if (sRefs.length == 0)
+					System.out.print(" <empty>");
+				else for (int j = 0, m = sRefs.length; j < m; j++)
+						System.out.print("  " + new String(sRefs[j]));
+				if (c instanceof AdditionalTypeCollection) {
+					char[][] names = ((AdditionalTypeCollection) c).definedTypeNames;
+					System.out.print("\n\t\t\tadditional type names:");
+					for (int j = 0, m = names.length; j < m; j++)
+						System.out.print("  " + new String(names[j]));
+				}
+			}
+		}
+	}
+	System.out.print("\n\n");
+}
+*/
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java
new file mode 100644
index 0000000..dea22ce
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+public class StringSet {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public String[] values;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public StringSet(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.values = new String[extraRoom];
+}
+
+public boolean add(String value) {
+	int length = this.values.length;
+	int index = (value.hashCode() & 0x7FFFFFFF) % length;
+	String current;
+	while ((current = this.values[index]) != null) {
+		if (value.equals(current)) return false; // did not add it since it already existed
+		if (++index == length) index = 0;
+	}
+	this.values[index] = value;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return true;
+}
+
+public void clear() {
+	for (int i = this.values.length; --i >= 0;)
+		this.values[i] = null;
+	this.elementSize = 0;
+}
+
+public boolean includes(String value) {
+	int length = this.values.length;
+	int index = (value.hashCode() & 0x7FFFFFFF) % length;
+	String current;
+	while ((current = this.values[index]) != null) {
+		if (value.equals(current)) return true;
+		if (++index == length) index = 0;
+	}
+	return false;
+}
+
+private void rehash() {
+	StringSet newSet = new StringSet(this.elementSize * 2); // double the number of expected elements
+	String current;
+	for (int i = this.values.length; --i >= 0;)
+		if ((current = this.values[i]) != null)
+			newSet.add(current);
+
+	this.values = newSet.values;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+
+public String toString() {
+	String s = ""; //$NON-NLS-1$
+	String value;
+	for (int i = 0, l = this.values.length; i < l; i++)
+		if ((value = this.values[i]) != null)
+			s += value + "\n"; //$NON-NLS-1$
+	return s;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java
new file mode 100644
index 0000000..73cfb45
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class WorkQueue {
+
+private SimpleSet needsCompileList;
+private SimpleSet compiledList;
+
+public WorkQueue() {
+	this.needsCompileList = new SimpleSet();
+	this.compiledList = new SimpleSet();
+}
+
+public void add(SourceFile element) {
+	this.needsCompileList.add(element);
+}
+
+public void addAll(SourceFile[] elements) {
+	for (int i = 0, l = elements.length; i < l; i++)
+		add(elements[i]);
+}
+
+public void clear() {
+	this.needsCompileList.clear();
+	this.compiledList.clear();
+}
+
+public void finished(SourceFile element) {
+	this.needsCompileList.remove(element);
+	this.compiledList.add(element);
+}
+
+public boolean isCompiled(SourceFile element) {
+	return this.compiledList.includes(element);
+}
+
+public boolean isWaiting(SourceFile element) {
+	return this.needsCompileList.includes(element);
+}
+
+public String toString() {
+	return "WorkQueue: " + this.needsCompileList; //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
new file mode 100644
index 0000000..6c31c8f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
@@ -0,0 +1,440 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.eval;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
+import org.eclipse.jdt.core.eval.IEvaluationContext;
+import org.eclipse.jdt.core.eval.IGlobalVariable;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.builder.NameEnvironment;
+import org.eclipse.jdt.internal.core.builder.ProblemFactory;
+import org.eclipse.jdt.internal.eval.EvaluationContext;
+import org.eclipse.jdt.internal.eval.GlobalVariable;
+import org.eclipse.jdt.internal.eval.IRequestor;
+import org.eclipse.jdt.internal.eval.InstallException;
+
+/**
+ * A wrapper around the infrastructure evaluation context.
+ */
+public class EvaluationContextWrapper implements IEvaluationContext {
+	protected EvaluationContext context;
+	protected JavaProject project;
+/**
+ * Creates a new wrapper around the given infrastructure evaluation context
+ * and project.
+ */
+public EvaluationContextWrapper(EvaluationContext context, JavaProject project) {
+	this.context = context;
+	this.project = project;
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#allVariables()
+ */
+public IGlobalVariable[] allVariables() {
+	GlobalVariable[] vars = this.context.allVariables();
+	int length = vars.length;
+	GlobalVariableWrapper[] result = new GlobalVariableWrapper[length];
+	for (int i = 0; i < length; i++) {
+		result[i] = new GlobalVariableWrapper(vars[i]);
+	}
+	return result;
+}
+/**
+ * Checks to ensure that there is a previously built state.
+ */
+protected void checkBuilderState() {
+
+	return;
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, ICompletionRequestor)
+ * @deprecated
+ */
+public void codeComplete(String codeSnippet, int position, ICompletionRequestor requestor) throws JavaModelException {
+	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, ICompletionRequestor, WorkingCopyOwner)
+ * @deprecated
+ */
+public void codeComplete(String codeSnippet, int position, ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	if (requestor == null) {
+		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
+	}
+	codeComplete(codeSnippet, position, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper(requestor), owner);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor)
+ */
+public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor) throws JavaModelException {
+	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, IProgressMonitor)
+ */
+public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY, null);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, WorkingCopyOwner)
+ */
+public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
+	codeComplete(codeSnippet, position, requestor, owner, null);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, WorkingCopyOwner, IProgressMonitor)
+ */
+public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor) throws JavaModelException {
+	SearchableEnvironment environment = this.project.newSearchableNameEnvironment(owner);
+	this.context.complete(
+		codeSnippet.toCharArray(),
+		position,
+		environment,
+		requestor,
+		this.project.getOptions(true),
+		this.project,
+		owner,
+		monitor
+	);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeSelect(String, int, int)
+ */
+public IJavaElement[] codeSelect(String codeSnippet, int offset, int length) throws JavaModelException {
+	return codeSelect(codeSnippet, offset, length, DefaultWorkingCopyOwner.PRIMARY);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeSelect(String, int, int, WorkingCopyOwner)
+ */
+public IJavaElement[] codeSelect(String codeSnippet, int offset, int length, WorkingCopyOwner owner) throws JavaModelException {
+	SearchableEnvironment environment = this.project.newSearchableNameEnvironment(owner);
+	SelectionRequestor requestor= new SelectionRequestor(environment.nameLookup, null); // null because there is no need to look inside the code snippet itself
+	this.context.select(
+		codeSnippet.toCharArray(),
+		offset,
+		offset + length - 1,
+		environment,
+		requestor,
+		this.project.getOptions(true),
+		owner
+	);
+	return requestor.getElements();
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#deleteVariable(IGlobalVariable)
+ */
+public void deleteVariable(IGlobalVariable variable) {
+	if (variable instanceof GlobalVariableWrapper) {
+		GlobalVariableWrapper wrapper = (GlobalVariableWrapper)variable;
+		this.context.deleteVariable(wrapper.variable);
+	} else {
+		throw new Error("Unknown implementation of IGlobalVariable"); //$NON-NLS-1$
+	}
+}
+/**
+ * @see IEvaluationContext#evaluateCodeSnippet(String, String[], String[], int[], IType, boolean, boolean, ICodeSnippetRequestor, IProgressMonitor)
+ */
+public void evaluateCodeSnippet(
+	String codeSnippet,
+	String[] localVariableTypeNames,
+	String[] localVariableNames,
+	int[] localVariableModifiers,
+	IType declaringType,
+	boolean isStatic,
+	boolean isConstructorCall,
+	ICodeSnippetRequestor requestor,
+	IProgressMonitor progressMonitor) throws org.eclipse.jdt.core.JavaModelException {
+
+	checkBuilderState();
+
+	int length = localVariableTypeNames.length;
+	char[][] varTypeNames = new char[length][];
+	for (int i = 0; i < length; i++){
+		varTypeNames[i] = localVariableTypeNames[i].toCharArray();
+	}
+
+	length = localVariableNames.length;
+	char[][] varNames = new char[length][];
+	for (int i = 0; i < length; i++){
+		varNames[i] = localVariableNames[i].toCharArray();
+	}
+
+	Map options = this.project.getOptions(true);
+	// transfer the imports of the IType to the evaluation context
+	if (declaringType != null) {
+		// retrieves the package statement
+		this.context.setPackageName(declaringType.getPackageFragment().getElementName().toCharArray());
+		ICompilationUnit compilationUnit = declaringType.getCompilationUnit();
+		if (compilationUnit != null) {
+			// retrieves the import statement
+			IImportDeclaration[] imports = compilationUnit.getImports();
+			int importsLength = imports.length;
+			if (importsLength != 0) {
+				char[][] importsNames = new char[importsLength][];
+				for (int i = 0; i < importsLength; i++) {
+					importsNames[i] = imports[i].getElementName().toCharArray();
+				}
+				this.context.setImports(importsNames);
+				// turn off import complaints for implicitly added ones
+				options.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
+			}
+		} else {
+			// try to retrieve imports from the source
+			SourceMapper sourceMapper = ((ClassFile) declaringType.getClassFile()).getSourceMapper();
+			if (sourceMapper != null) {
+				char[][] imports = sourceMapper.getImports((BinaryType) declaringType);
+				if (imports != null) {
+					this.context.setImports(imports);
+					// turn off import complaints for implicitly added ones
+					options.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
+				}
+			}
+		}
+	}
+	INameEnvironment environment = null;
+	try {
+		this.context.evaluate(
+			codeSnippet.toCharArray(),
+			varTypeNames,
+			varNames,
+			localVariableModifiers,
+			declaringType == null? null : declaringType.getFullyQualifiedName().toCharArray(),
+			isStatic,
+			isConstructorCall,
+			environment = getBuildNameEnvironment(),
+			options,
+			getInfrastructureEvaluationRequestor(requestor),
+			getProblemFactory());
+	} catch (InstallException e) {
+		handleInstallException(e);
+	} finally {
+		if (environment != null) environment.cleanup();
+	}
+}
+/**
+ * @see IEvaluationContext#evaluateCodeSnippet(String, ICodeSnippetRequestor, IProgressMonitor)
+ */
+public void evaluateCodeSnippet(String codeSnippet, ICodeSnippetRequestor requestor, IProgressMonitor progressMonitor) throws JavaModelException {
+
+	checkBuilderState();
+	INameEnvironment environment = null;
+	try {
+		this.context.evaluate(
+			codeSnippet.toCharArray(),
+			environment = getBuildNameEnvironment(),
+			this.project.getOptions(true),
+			getInfrastructureEvaluationRequestor(requestor),
+			getProblemFactory());
+	} catch (InstallException e) {
+		handleInstallException(e);
+	} finally {
+		if (environment != null) environment.cleanup();
+	}
+}
+/**
+ * @see IEvaluationContext#evaluateVariable(IGlobalVariable, ICodeSnippetRequestor, IProgressMonitor)
+ */
+public void evaluateVariable(IGlobalVariable variable, ICodeSnippetRequestor requestor, IProgressMonitor progressMonitor) throws JavaModelException {
+
+	checkBuilderState();
+	INameEnvironment environment = null;
+	try {
+		this.context.evaluateVariable(
+			((GlobalVariableWrapper)variable).variable,
+			environment = getBuildNameEnvironment(),
+			this.project.getOptions(true),
+			getInfrastructureEvaluationRequestor(requestor),
+			getProblemFactory());
+	} catch (InstallException e) {
+		handleInstallException(e);
+	} finally {
+		if (environment != null) environment.cleanup();
+	}
+}
+/**
+ * Returns a name environment for the last built state.
+ */
+protected INameEnvironment getBuildNameEnvironment() {
+	return new NameEnvironment(getProject());
+}
+public char[] getVarClassName() {
+	return this.context.getVarClassName();
+}
+
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#getImports()
+ */
+public String[] getImports() {
+	char[][] imports = this.context.getImports();
+	int length = imports.length;
+	String[] result = new String[length];
+	for (int i = 0; i < length; i++) {
+		result[i] = new String(imports[i]);
+	}
+	return result;
+}
+/**
+ * Returns the infrastructure evaluation context.
+ */
+public EvaluationContext getInfrastructureEvaluationContext() {
+	return this.context;
+}
+/**
+ * Returns a new infrastructure evaluation requestor instance.
+ */
+protected IRequestor getInfrastructureEvaluationRequestor(ICodeSnippetRequestor requestor) {
+	return new RequestorWrapper(requestor);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#getPackageName()
+ */
+public String getPackageName() {
+	return new String(this.context.getPackageName());
+}
+/**
+ * Returns the problem factory to be used during evaluation.
+ */
+protected IProblemFactory getProblemFactory() {
+	return ProblemFactory.getProblemFactory(Locale.getDefault());
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#getProject()
+ */
+public IJavaProject getProject() {
+	return this.project;
+}
+/**
+ * Handles an install exception by throwing a Java Model exception.
+ */
+protected void handleInstallException(InstallException e) throws JavaModelException {
+	throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.EVALUATION_ERROR, e.toString()));
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#newVariable(String, String, String)
+ */
+public IGlobalVariable newVariable(String typeName, String name, String initializer) {
+	GlobalVariable newVar =
+		this.context.newVariable(
+			typeName.toCharArray(),
+			name.toCharArray(),
+			(initializer == null) ?
+				null :
+				initializer.toCharArray());
+	return new GlobalVariableWrapper(newVar);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#setImports(String[])
+ */
+public void setImports(String[] imports) {
+	int length = imports.length;
+	char[][] result = new char[length][];
+	for (int i = 0; i < length; i++) {
+		result[i] = imports[i].toCharArray();
+	}
+	this.context.setImports(result);
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IEvaluationContext#setPackageName(String)
+ */
+public void setPackageName(String packageName) {
+	this.context.setPackageName(packageName.toCharArray());
+}
+/**
+ * @see IEvaluationContext#validateImports(ICodeSnippetRequestor)
+ */
+public void validateImports(ICodeSnippetRequestor requestor) {
+
+	checkBuilderState();
+	INameEnvironment environment = null;
+	try {
+		this.context.evaluateImports(
+			environment = getBuildNameEnvironment(),
+			getInfrastructureEvaluationRequestor(requestor),
+			getProblemFactory());
+	} finally {
+		if (environment != null) environment.cleanup();
+	}
+}
+/**
+ * @see IEvaluationContext#codeComplete(String, int, ICodeCompletionRequestor)
+ * @deprecated - use codeComplete(String, int, ICompletionRequestor) instead
+ */
+public void codeComplete(String codeSnippet, int position, final org.eclipse.jdt.core.ICodeCompletionRequestor requestor) throws JavaModelException {
+
+	if (requestor == null){
+		codeComplete(codeSnippet, position, (ICompletionRequestor)null);
+		return;
+	}
+	codeComplete(
+		codeSnippet,
+		position,
+		new ICompletionRequestor(){
+			public void acceptAnonymousType(char[] superTypePackageName,char[] superTypeName,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+				// implements interface method
+			}
+			public void acceptClass(char[] packageName, char[] className, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptClass(packageName, className, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptError(IProblem error) {
+				// was disabled in 1.0
+			}
+
+			public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, char[] typePackageName, char[] typeName, char[] completionName, int modifiers, int completionStart, int completionEnd, int relevance) {
+				requestor.acceptField(declaringTypePackageName, declaringTypeName, name, typePackageName, typeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptInterface(char[] packageName,char[] interfaceName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance) {
+				requestor.acceptInterface(packageName, interfaceName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptKeyword(char[] keywordName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptKeyword(keywordName, completionStart, completionEnd);
+			}
+			public void acceptLabel(char[] labelName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptLabel(labelName, completionStart, completionEnd);
+			}
+			public void acceptLocalVariable(char[] name,char[] typePackageName,char[] typeName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptMethod(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// skip parameter names
+				requestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, returnTypePackageName, returnTypeName, completionName, modifiers, completionStart, completionEnd);
+			}
+			public void acceptMethodDeclaration(char[] declaringTypePackageName,char[] declaringTypeName,char[] selector,char[][] parameterPackageNames,char[][] parameterTypeNames,char[][] parameterNames,char[] returnTypePackageName,char[] returnTypeName,char[] completionName,int modifiers,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+			public void acceptModifier(char[] modifierName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptModifier(modifierName, completionStart, completionEnd);
+			}
+			public void acceptPackage(char[] packageName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptPackage(packageName, completionName, completionStart, completionEnd);
+			}
+			public void acceptType(char[] packageName,char[] typeName,char[] completionName,int completionStart,int completionEnd, int relevance){
+				requestor.acceptType(packageName, typeName, completionName, completionStart, completionEnd);
+			}
+			public void acceptVariableName(char[] typePackageName,char[] typeName,char[] name,char[] completionName,int completionStart,int completionEnd, int relevance){
+				// ignore
+			}
+		});
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java
new file mode 100644
index 0000000..a924b27
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.eval;
+
+import org.eclipse.jdt.core.eval.IGlobalVariable;
+import org.eclipse.jdt.internal.eval.GlobalVariable;
+
+/**
+ * A wrapper around the infrastructure global variable.
+ */
+class GlobalVariableWrapper implements IGlobalVariable {
+	GlobalVariable variable;
+/**
+ * Creates a new wrapper around the given infrastructure global variable.
+ */
+GlobalVariableWrapper(GlobalVariable variable) {
+	this.variable = variable;
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IGlobalVariable#getInitializer
+ */
+public String getInitializer() {
+	char[] initializer = this.variable.getInitializer();
+	if (initializer != null) {
+		return new String(initializer);
+	} else {
+		return null;
+	}
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IGlobalVariable#getName
+ */
+public String getName() {
+	return new String(this.variable.getName());
+}
+/**
+ * @see org.eclipse.jdt.core.eval.IGlobalVariable#getTypeName
+ */
+public String getTypeName() {
+	return new String(this.variable.getTypeName());
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java
new file mode 100644
index 0000000..9eda025
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.eval;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaModelMarker;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.eval.IRequestor;
+
+public class RequestorWrapper implements IRequestor {
+
+	ICodeSnippetRequestor requestor;
+
+public RequestorWrapper(ICodeSnippetRequestor requestor) {
+	this.requestor = requestor;
+}
+/**
+ * @see ICodeSnippetRequestor
+ */
+public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
+	int length = classFiles.length;
+	byte[][] classFileBytes = new byte[length][];
+	String[][] compoundNames = new String[length][];
+	for (int i = 0; i < length; i++) {
+		ClassFile classFile = classFiles[i];
+		classFileBytes[i] = classFile.getBytes();
+		char[][] classFileCompundName = classFile.getCompoundName();
+		int length2 = classFileCompundName.length;
+		String[] compoundName = new String[length2];
+		for (int j = 0; j < length2; j++){
+			compoundName[j] = new String(classFileCompundName[j]);
+		}
+		compoundNames[i] = compoundName;
+	}
+	return this.requestor.acceptClassFiles(classFileBytes, compoundNames, codeSnippetClassName == null ? null : new String(codeSnippetClassName));
+}
+/**
+ * @see ICodeSnippetRequestor
+ */
+public void acceptProblem(CategorizedProblem problem, char[] fragmentSource, int fragmentKind) {
+	try {
+		IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker(IJavaModelMarker.TRANSIENT_PROBLEM);
+		marker.setAttribute(IJavaModelMarker.ID, problem.getID());
+		marker.setAttribute(IMarker.CHAR_START, problem.getSourceStart());
+		marker.setAttribute(IMarker.CHAR_END, problem.getSourceEnd() + 1);
+		marker.setAttribute(IMarker.LINE_NUMBER, problem.getSourceLineNumber());
+		//marker.setAttribute(IMarker.LOCATION, "#" + problem.getSourceLineNumber());
+		marker.setAttribute(IMarker.MESSAGE, problem.getMessage());
+		marker.setAttribute(IMarker.SEVERITY, (problem.isWarning() ? IMarker.SEVERITY_WARNING : IMarker.SEVERITY_ERROR));
+		marker.setAttribute(IMarker.SOURCE_ID, JavaBuilder.SOURCE_ID);
+		this.requestor.acceptProblem(marker, new String(fragmentSource), fragmentKind);
+	} catch (CoreException e) {
+		e.printStackTrace();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
new file mode 100644
index 0000000..6bc0990
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
@@ -0,0 +1,443 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.SimpleDelta;
+
+/*
+ * Collects changes (reported through fine-grained deltas) that can affect a type hierarchy.
+ */
+public class ChangeCollector {
+
+	/*
+	 * A table from ITypes to TypeDeltas
+	 */
+	HashMap changes = new HashMap();
+
+	TypeHierarchy hierarchy;
+
+	public ChangeCollector(TypeHierarchy hierarchy) {
+		this.hierarchy = hierarchy;
+	}
+
+	/*
+	 * Adds the children of the given delta to the list of changes.
+	 */
+	private void addAffectedChildren(IJavaElementDelta delta) throws JavaModelException {
+		IJavaElementDelta[] children = delta.getAffectedChildren();
+		for (int i = 0, length = children.length; i < length; i++) {
+			IJavaElementDelta child = children[i];
+			IJavaElement childElement = child.getElement();
+			switch (childElement.getElementType()) {
+				case IJavaElement.IMPORT_CONTAINER:
+					addChange((IImportContainer)childElement, child);
+					break;
+				case IJavaElement.IMPORT_DECLARATION:
+					addChange((IImportDeclaration)childElement, child);
+					break;
+				case IJavaElement.TYPE:
+					addChange((IType)childElement, child);
+					break;
+				case IJavaElement.INITIALIZER:
+				case IJavaElement.FIELD:
+				case IJavaElement.METHOD:
+					addChange((IMember)childElement, child);
+					break;
+			}
+		}
+	}
+
+	/*
+	 * Adds the given delta on a compilation unit to the list of changes.
+	 */
+	public void addChange(ICompilationUnit cu, IJavaElementDelta newDelta) throws JavaModelException {
+		int newKind = newDelta.getKind();
+		switch (newKind) {
+			case IJavaElementDelta.ADDED:
+				ArrayList allTypes = new ArrayList();
+				getAllTypesFromElement(cu, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType type = (IType)allTypes.get(i);
+					addTypeAddition(type, (SimpleDelta)this.changes.get(type));
+				}
+				break;
+			case IJavaElementDelta.REMOVED:
+				allTypes = new ArrayList();
+				getAllTypesFromHierarchy((JavaElement)cu, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType type = (IType)allTypes.get(i);
+					addTypeRemoval(type, (SimpleDelta)this.changes.get(type));
+				}
+				break;
+			case IJavaElementDelta.CHANGED:
+				addAffectedChildren(newDelta);
+				break;
+		}
+	}
+
+	private void addChange(IImportContainer importContainer, IJavaElementDelta newDelta) throws JavaModelException {
+		int newKind = newDelta.getKind();
+		if (newKind == IJavaElementDelta.CHANGED) {
+			addAffectedChildren(newDelta);
+			return;
+		}
+		SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importContainer);
+		if (existingDelta != null) {
+			switch (newKind) {
+				case IJavaElementDelta.ADDED:
+					if (existingDelta.getKind() == IJavaElementDelta.REMOVED) {
+						// REMOVED then ADDED
+						this.changes.remove(importContainer);
+					}
+					break;
+				case IJavaElementDelta.REMOVED:
+					if (existingDelta.getKind() == IJavaElementDelta.ADDED) {
+						// ADDED then REMOVED
+						this.changes.remove(importContainer);
+					}
+					break;
+					// CHANGED handled above
+			}
+		} else {
+			SimpleDelta delta = new SimpleDelta();
+			switch (newKind) {
+				case IJavaElementDelta.ADDED:
+					delta.added();
+					break;
+				case IJavaElementDelta.REMOVED:
+					delta.removed();
+					break;
+			}
+			this.changes.put(importContainer, delta);
+		}
+	}
+
+	private void addChange(IImportDeclaration importDecl, IJavaElementDelta newDelta) {
+		SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importDecl);
+		int newKind = newDelta.getKind();
+		if (existingDelta != null) {
+			switch (newKind) {
+				case IJavaElementDelta.ADDED:
+					if (existingDelta.getKind() == IJavaElementDelta.REMOVED) {
+						// REMOVED then ADDED
+						this.changes.remove(importDecl);
+					}
+					break;
+				case IJavaElementDelta.REMOVED:
+					if (existingDelta.getKind() == IJavaElementDelta.ADDED) {
+						// ADDED then REMOVED
+						this.changes.remove(importDecl);
+					}
+					break;
+				// CHANGED cannot happen for import declaration
+			}
+		} else {
+			SimpleDelta delta = new SimpleDelta();
+			switch (newKind) {
+				case IJavaElementDelta.ADDED:
+					delta.added();
+					break;
+				case IJavaElementDelta.REMOVED:
+					delta.removed();
+					break;
+			}
+			this.changes.put(importDecl, delta);
+		}
+	}
+
+	/*
+	 * Adds a change for the given member (a method, a field or an initializer) and the types it defines.
+	 */
+	private void addChange(IMember member, IJavaElementDelta newDelta) throws JavaModelException {
+		int newKind = newDelta.getKind();
+		switch (newKind) {
+			case IJavaElementDelta.ADDED:
+				ArrayList allTypes = new ArrayList();
+				getAllTypesFromElement(member, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType innerType = (IType)allTypes.get(i);
+					addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType));
+				}
+				break;
+			case IJavaElementDelta.REMOVED:
+				allTypes = new ArrayList();
+				getAllTypesFromHierarchy((JavaElement)member, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType type = (IType)allTypes.get(i);
+					addTypeRemoval(type, (SimpleDelta)this.changes.get(type));
+				}
+				break;
+			case IJavaElementDelta.CHANGED:
+				addAffectedChildren(newDelta);
+				break;
+		}
+	}
+
+	/*
+	 * Adds a change for the given type and the types it defines.
+	 */
+	private void addChange(IType type, IJavaElementDelta newDelta) throws JavaModelException {
+		 int newKind = newDelta.getKind();
+		SimpleDelta existingDelta = (SimpleDelta)this.changes.get(type);
+		switch (newKind) {
+			case IJavaElementDelta.ADDED:
+				addTypeAddition(type, existingDelta);
+				ArrayList allTypes = new ArrayList();
+				getAllTypesFromElement(type, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType innerType = (IType)allTypes.get(i);
+					addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType));
+				}
+				break;
+			case IJavaElementDelta.REMOVED:
+				addTypeRemoval(type, existingDelta);
+				allTypes = new ArrayList();
+				getAllTypesFromHierarchy((JavaElement)type, allTypes);
+				for (int i = 0, length = allTypes.size(); i < length; i++) {
+					IType innerType = (IType)allTypes.get(i);
+					addTypeRemoval(innerType, (SimpleDelta)this.changes.get(innerType));
+				}
+				break;
+			case IJavaElementDelta.CHANGED:
+				addTypeChange(type, newDelta.getFlags(), existingDelta);
+				addAffectedChildren(newDelta);
+				break;
+		}
+	}
+
+	private void addTypeAddition(IType type, SimpleDelta existingDelta) throws JavaModelException {
+		if (existingDelta != null) {
+			switch (existingDelta.getKind()) {
+				case IJavaElementDelta.REMOVED:
+					// REMOVED then ADDED
+					boolean hasChange = false;
+					if (hasSuperTypeChange(type)) {
+						existingDelta.superTypes();
+						hasChange = true;
+					}
+					if (hasVisibilityChange(type)) {
+						existingDelta.modifiers();
+						hasChange = true;
+					}
+					if (!hasChange) {
+						this.changes.remove(type);
+					}
+					break;
+					// CHANGED then ADDED
+					// or ADDED then ADDED: should not happen
+			}
+		} else {
+			// check whether the type addition affects the hierarchy
+			String typeName = type.getElementName();
+			if (this.hierarchy.hasSupertype(typeName)
+					|| this.hierarchy.subtypesIncludeSupertypeOf(type)
+					|| this.hierarchy.missingTypes.contains(typeName)) {
+				SimpleDelta delta = new SimpleDelta();
+				delta.added();
+				this.changes.put(type, delta);
+			}
+		}
+	}
+
+	private void addTypeChange(IType type, int newFlags, SimpleDelta existingDelta) throws JavaModelException {
+		if (existingDelta != null) {
+			switch (existingDelta.getKind()) {
+				case IJavaElementDelta.CHANGED:
+					// CHANGED then CHANGED
+					int existingFlags = existingDelta.getFlags();
+					boolean hasChange = false;
+					if ((existingFlags & IJavaElementDelta.F_SUPER_TYPES) != 0
+							&& hasSuperTypeChange(type)) {
+						existingDelta.superTypes();
+						hasChange = true;
+					}
+					if ((existingFlags & IJavaElementDelta.F_MODIFIERS) != 0
+							&& hasVisibilityChange(type)) {
+						existingDelta.modifiers();
+						hasChange = true;
+					}
+					if (!hasChange) {
+						// super types and visibility are back to the ones in the existing hierarchy
+						this.changes.remove(type);
+					}
+					break;
+					// ADDED then CHANGED: leave it as ADDED
+					// REMOVED then CHANGED: should not happen
+			}
+		} else {
+			// check whether the type change affects the hierarchy
+			SimpleDelta typeDelta = null;
+			if ((newFlags & IJavaElementDelta.F_SUPER_TYPES) != 0
+					&& this.hierarchy.includesTypeOrSupertype(type)) {
+				typeDelta = new SimpleDelta();
+				typeDelta.superTypes();
+			}
+			if ((newFlags & IJavaElementDelta.F_MODIFIERS) != 0
+					&& (this.hierarchy.hasSupertype(type.getElementName())
+						|| type.equals(this.hierarchy.focusType))) {
+				if (typeDelta == null) {
+					typeDelta = new SimpleDelta();
+				}
+				typeDelta.modifiers();
+			}
+			if (typeDelta != null) {
+				this.changes.put(type, typeDelta);
+			}
+		}
+	}
+
+	private void addTypeRemoval(IType type, SimpleDelta existingDelta) {
+		if (existingDelta != null) {
+			switch (existingDelta.getKind()) {
+				case IJavaElementDelta.ADDED:
+					// ADDED then REMOVED
+					this.changes.remove(type);
+					break;
+				case IJavaElementDelta.CHANGED:
+					// CHANGED then REMOVED
+					existingDelta.removed();
+					break;
+					// REMOVED then REMOVED: should not happen
+			}
+		} else {
+			// check whether the type removal affects the hierarchy
+			if (this.hierarchy.contains(type)) {
+				SimpleDelta typeDelta = new SimpleDelta();
+				typeDelta.removed();
+				this.changes.put(type, typeDelta);
+			}
+		}
+	}
+
+	/*
+	 * Returns all types defined in the given element excluding the given element.
+	 */
+	private void getAllTypesFromElement(IJavaElement element, ArrayList allTypes) throws JavaModelException {
+		switch (element.getElementType()) {
+			case IJavaElement.COMPILATION_UNIT:
+				IType[] types = ((ICompilationUnit)element).getTypes();
+				for (int i = 0, length = types.length; i < length; i++) {
+					IType type = types[i];
+					allTypes.add(type);
+					getAllTypesFromElement(type, allTypes);
+				}
+				break;
+			case IJavaElement.TYPE:
+				types = ((IType)element).getTypes();
+				for (int i = 0, length = types.length; i < length; i++) {
+					IType type = types[i];
+					allTypes.add(type);
+					getAllTypesFromElement(type, allTypes);
+				}
+				break;
+			case IJavaElement.INITIALIZER:
+			case IJavaElement.FIELD:
+			case IJavaElement.METHOD:
+				IJavaElement[] children = ((IMember)element).getChildren();
+				for (int i = 0, length = children.length; i < length; i++) {
+					IType type = (IType)children[i];
+					allTypes.add(type);
+					getAllTypesFromElement(type, allTypes);
+				}
+				break;
+		}
+	}
+
+	/*
+	 * Returns all types in the existing hierarchy that have the given element as a parent.
+	 */
+	private void getAllTypesFromHierarchy(JavaElement element, ArrayList allTypes) {
+		switch (element.getElementType()) {
+			case IJavaElement.COMPILATION_UNIT:
+				ArrayList types = (ArrayList)this.hierarchy.files.get(element);
+				if (types != null) {
+					allTypes.addAll(types);
+				}
+				break;
+			case IJavaElement.TYPE:
+			case IJavaElement.INITIALIZER:
+			case IJavaElement.FIELD:
+			case IJavaElement.METHOD:
+				types = (ArrayList)this.hierarchy.files.get(((IMember)element).getCompilationUnit());
+				if (types != null) {
+					for (int i = 0, length = types.size(); i < length; i++) {
+						IType type = (IType)types.get(i);
+						if (element.isAncestorOf(type)) {
+							allTypes.add(type);
+						}
+					}
+				}
+				break;
+		}
+	}
+
+	private boolean hasSuperTypeChange(IType type) throws JavaModelException {
+		// check super class
+		IType superclass = this.hierarchy.getSuperclass(type);
+		String existingSuperclassName = superclass == null ? null : superclass.getElementName();
+		String newSuperclassName = type.getSuperclassName();
+		if (existingSuperclassName != null && !existingSuperclassName.equals(newSuperclassName)) {
+			return true;
+		}
+
+		// check super interfaces
+		IType[] existingSuperInterfaces = this.hierarchy.getSuperInterfaces(type);
+		String[] newSuperInterfaces = type.getSuperInterfaceNames();
+		if (existingSuperInterfaces.length != newSuperInterfaces.length) {
+			return true;
+		}
+		for (int i = 0, length = newSuperInterfaces.length; i < length; i++) {
+			String superInterfaceName = newSuperInterfaces[i];
+			if (!superInterfaceName.equals(newSuperInterfaces[i])) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	private boolean hasVisibilityChange(IType type) throws JavaModelException {
+		int existingFlags = this.hierarchy.getCachedFlags(type);
+		int newFlags = type.getFlags();
+		return existingFlags != newFlags;
+	}
+
+	/*
+	 * Whether the hierarchy needs refresh according to the changes collected so far.
+	 */
+	public boolean needsRefresh() {
+		return this.changes.size() != 0;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		Iterator iterator = this.changes.entrySet().iterator();
+		while (iterator.hasNext()) {
+			Map.Entry entry = (Map.Entry)iterator.next();
+			buffer.append(((JavaElement)entry.getKey()).toDebugString());
+			buffer.append(entry.getValue());
+			if (iterator.hasNext()) {
+				buffer.append('\n');
+			}
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
new file mode 100644
index 0000000..b90fa25
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class HierarchyBinaryType implements IBinaryType {
+	private int modifiers;
+	private char[] sourceName;
+	private char[] name;
+	private char[] enclosingTypeName;
+	private char[] superclass;
+	private char[][] superInterfaces = NoInterface;
+	private char[][] typeParameterSignatures;
+	private char[] genericSignature;
+
+public HierarchyBinaryType(int modifiers, char[] qualification, char[] sourceName, char[] enclosingTypeName, char[][] typeParameterSignatures, char typeSuffix){
+
+	this.modifiers = modifiers;
+	this.sourceName = sourceName;
+	if (enclosingTypeName == null){
+		this.name = CharOperation.concat(qualification, sourceName, '/');
+	} else {
+		this.name = CharOperation.concat(qualification, '/', enclosingTypeName, '$', sourceName); //rebuild A$B name
+		this.enclosingTypeName = CharOperation.concat(qualification, enclosingTypeName,'/');
+		CharOperation.replace(this.enclosingTypeName, '.', '/');
+	}
+	this.typeParameterSignatures = typeParameterSignatures;
+	CharOperation.replace(this.name, '.', '/');
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IBinaryType
+ */
+public IBinaryAnnotation[] getAnnotations() {
+	return null;
+}
+public char[] getEnclosingMethod() {
+	return null;
+}
+/**
+ * Answer the resolved name of the enclosing type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the receiver is a top level type.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+public char[] getEnclosingTypeName() {
+	return this.enclosingTypeName;
+}
+/**
+ * Answer the receiver's fields or null if the array is empty.
+ */
+public IBinaryField[] getFields() {
+	return null;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return null;
+}
+public char[] getGenericSignature() {
+	if (this.typeParameterSignatures != null && this.genericSignature == null) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append('<');
+		for (int i = 0, length = this.typeParameterSignatures.length; i < length; i++) {
+			buffer.append(this.typeParameterSignatures[i]);
+		}
+		buffer.append('>');
+		if (this.superclass == null)
+			buffer.append(Signature.createTypeSignature("java.lang.Object", true/*resolved*/)); //$NON-NLS-1$
+		else
+			buffer.append(Signature.createTypeSignature(this.superclass, true/*resolved*/));
+		if (this.superInterfaces != null)
+			for (int i = 0, length = this.superInterfaces.length; i < length; i++)
+				buffer.append(Signature.createTypeSignature(this.superInterfaces[i], true/*resolved*/));
+		this.genericSignature = buffer.toString().toCharArray();
+		CharOperation.replace(this.genericSignature, '.', '/');
+	}
+	return this.genericSignature;
+}
+/**
+ * Answer the resolved names of the receiver's interfaces in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if the array is empty.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+public char[][] getInterfaceNames() {
+	return this.superInterfaces;
+}
+/**
+ * Answer the receiver's nested types or null if the array is empty.
+ *
+ * This nested type info is extracted from the inner class attributes.
+ * Ask the name environment to find a member type using its compound name.
+ */
+public IBinaryNestedType[] getMemberTypes() {
+	return null;
+}
+/**
+ * Answer the receiver's methods or null if the array is empty.
+ */
+public IBinaryMethod[] getMethods() {
+	return null;
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IBinaryType#getMissingTypeNames()
+ */
+public char[][][] getMissingTypeNames() {
+	return null;
+}
+
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+public int getModifiers() {
+	return this.modifiers;
+}
+
+/**
+ * Answer the resolved name of the type in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+public char[] getName() {
+	return this.name;
+}
+
+public char[] getSourceName() {
+	return this.sourceName;
+}
+/**
+ * Answer the resolved name of the receiver's superclass in the
+ * class file format as specified in section 4.2 of the Java 2 VM spec
+ * or null if it does not have one.
+ *
+ * For example, java.lang.String is java/lang/String.
+ */
+public char[] getSuperclassName() {
+	return this.superclass;
+}
+
+// TODO (jerome) please verify that we don't need the tagbits for the receiver
+public long getTagBits() {
+	return 0;
+}
+public boolean isAnonymous() {
+	return false; // index did not record this information (since unused for hierarchies)
+}
+/**
+ * Answer whether the receiver contains the resolved binary form
+ * or the unresolved source form of the type.
+ */
+public boolean isBinaryType() {
+	return true;
+}
+
+public boolean isLocal() {
+	return false;  // index did not record this information (since unused for hierarchies)
+}
+public boolean isMember() {
+	return false;  // index did not record this information (since unused for hierarchies)
+}
+
+public void recordSuperType(char[] superTypeName, char[] superQualification, char superClassOrInterface){
+
+	// index encoding of p.A$B was B/p.A$, rebuild the proper name
+	if (superQualification != null){
+		int length = superQualification.length;
+		if (superQualification[length-1] == '$'){
+			char[] enclosingSuperName = CharOperation.lastSegment(superQualification, '.');
+			superTypeName = CharOperation.concat(enclosingSuperName, superTypeName);
+			superQualification = CharOperation.subarray(superQualification, 0, length - enclosingSuperName.length - 1);
+		}
+	}
+
+	if (superClassOrInterface == IIndexConstants.CLASS_SUFFIX){
+		// interfaces are indexed as having superclass references to Object by default,
+		// this is an artifact used for being able to query them only.
+		if (TypeDeclaration.kind(this.modifiers) == TypeDeclaration.INTERFACE_DECL) return;
+		char[] encodedName = CharOperation.concat(superQualification, superTypeName, '/');
+		CharOperation.replace(encodedName, '.', '/');
+		this.superclass = encodedName;
+	} else {
+		char[] encodedName = CharOperation.concat(superQualification, superTypeName, '/');
+		CharOperation.replace(encodedName, '.', '/');
+		if (this.superInterfaces == NoInterface){
+			this.superInterfaces = new char[][] { encodedName };
+		} else {
+			int length = this.superInterfaces.length;
+			System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new char[length+1][], 0, length);
+			this.superInterfaces[length] = encodedName;
+		}
+	}
+}
+
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IBinaryType
+ */
+public char[] sourceFileName() {
+	return null;
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	if (this.modifiers == ClassFileConstants.AccPublic) {
+		buffer.append("public "); //$NON-NLS-1$
+	}
+	switch (TypeDeclaration.kind(this.modifiers)) {
+		case TypeDeclaration.CLASS_DECL :
+			buffer.append("class "); //$NON-NLS-1$
+			break;
+		case TypeDeclaration.INTERFACE_DECL :
+			buffer.append("interface "); //$NON-NLS-1$
+			break;
+		case TypeDeclaration.ENUM_DECL :
+			buffer.append("enum "); //$NON-NLS-1$
+			break;
+	}
+	if (this.name != null) {
+		buffer.append(this.name);
+	}
+	if (this.superclass != null) {
+		buffer.append("\n  extends "); //$NON-NLS-1$
+		buffer.append(this.superclass);
+	}
+	int length;
+	if (this.superInterfaces != null && (length = this.superInterfaces.length) != 0) {
+		buffer.append("\n implements "); //$NON-NLS-1$
+		for (int i = 0; i < length; i++) {
+			buffer.append(this.superInterfaces[i]);
+			if (i != length - 1) {
+				buffer.append(", "); //$NON-NLS-1$
+			}
+		}
+	}
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java
new file mode 100644
index 0000000..03a1abc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java
@@ -0,0 +1,335 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.ResourceCompilationUnit;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public abstract class HierarchyBuilder {
+	/**
+	 * The hierarchy being built.
+	 */
+	protected TypeHierarchy hierarchy;
+	/**
+	 * @see NameLookup
+	 */
+	protected NameLookup nameLookup;
+	/**
+	 * The resolver used to resolve type hierarchies
+	 * @see HierarchyResolver
+	 */
+	protected HierarchyResolver hierarchyResolver;
+	/**
+	 * A temporary cache of infos to handles to speed info
+	 * to handle translation - it only contains the entries
+	 * for the types in the region (in other words, it contains
+	 * no supertypes outside the region).
+	 */
+	protected Map infoToHandle;
+	/*
+	 * The dot-separated fully qualified name of the focus type, or null of none.
+	 */
+	protected String focusQualifiedName;
+
+	public HierarchyBuilder(TypeHierarchy hierarchy) throws JavaModelException {
+
+		this.hierarchy = hierarchy;
+		JavaProject project = (JavaProject) hierarchy.javaProject();
+
+		IType focusType = hierarchy.getType();
+		org.eclipse.jdt.core.ICompilationUnit unitToLookInside = focusType == null ? null : focusType.getCompilationUnit();
+		org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.hierarchy.workingCopies;
+		org.eclipse.jdt.core.ICompilationUnit[] unitsToLookInside;
+		if (unitToLookInside != null) {
+			int wcLength = workingCopies == null ? 0 : workingCopies.length;
+			if (wcLength == 0) {
+				unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[] {unitToLookInside};
+			} else {
+				unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[wcLength+1];
+				unitsToLookInside[0] = unitToLookInside;
+				System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
+			}
+		} else {
+			unitsToLookInside = workingCopies;
+		}
+		if (project != null) {
+			SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
+			this.nameLookup = searchableEnvironment.nameLookup;
+			this.hierarchyResolver =
+				new HierarchyResolver(
+					searchableEnvironment,
+					project.getOptions(true),
+					this,
+					new DefaultProblemFactory());
+		}
+		this.infoToHandle = new HashMap(5);
+		this.focusQualifiedName = focusType == null ? null : focusType.getFullyQualifiedName();
+	}
+
+	public abstract void build(boolean computeSubtypes)
+		throws JavaModelException, CoreException;
+	/**
+	 * Configure this type hierarchy by computing the supertypes only.
+	 */
+	protected void buildSupertypes() {
+		IType focusType = getType();
+		if (focusType == null)
+			return;
+		// get generic type from focus type
+		IGenericType type;
+		try {
+			type = (IGenericType) ((JavaElement) focusType).getElementInfo();
+		} catch (JavaModelException e) {
+			// if the focus type is not present, or if cannot get workbench path
+			// we cannot create the hierarchy
+			return;
+		}
+		//NB: no need to set focus type on hierarchy resolver since no other type is injected
+		//    in the hierarchy resolver, thus there is no need to check that a type is
+		//    a sub or super type of the focus type.
+		this.hierarchyResolver.resolve(type);
+
+		// Add focus if not already in (case of a type with no explicit super type)
+		if (!this.hierarchy.contains(focusType)) {
+			this.hierarchy.addRootClass(focusType);
+		}
+	}
+	/**
+	 * Connect the supplied type to its superclass & superinterfaces.
+	 * The superclass & superinterfaces are the identical binary or source types as
+	 * supplied by the name environment.
+	 */
+	public void connect(
+		IGenericType type,
+		IType typeHandle,
+		IType superclassHandle,
+		IType[] superinterfaceHandles) {
+
+		/*
+		 * Temporary workaround for 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class
+		 */
+		if (typeHandle == null)
+			return;
+		if (TypeHierarchy.DEBUG) {
+			System.out.println(
+				"Connecting: " + ((JavaElement) typeHandle).toStringWithAncestors()); //$NON-NLS-1$
+			System.out.println(
+				"  to superclass: " //$NON-NLS-1$
+					+ (superclassHandle == null
+						? "<None>" //$NON-NLS-1$
+						: ((JavaElement) superclassHandle).toStringWithAncestors()));
+			System.out.print("  and superinterfaces:"); //$NON-NLS-1$
+			if (superinterfaceHandles == null || superinterfaceHandles.length == 0) {
+				System.out.println(" <None>"); //$NON-NLS-1$
+			} else {
+				System.out.println();
+				for (int i = 0, length = superinterfaceHandles.length; i < length; i++) {
+					if (superinterfaceHandles[i] == null) continue;
+					System.out.println(
+						"    " + ((JavaElement) superinterfaceHandles[i]).toStringWithAncestors()); //$NON-NLS-1$
+				}
+			}
+		}
+		// now do the caching
+		switch (TypeDeclaration.kind(type.getModifiers())) {
+			case TypeDeclaration.CLASS_DECL :
+			case TypeDeclaration.ENUM_DECL :
+				if (superclassHandle == null) {
+					this.hierarchy.addRootClass(typeHandle);
+				} else {
+					this.hierarchy.cacheSuperclass(typeHandle, superclassHandle);
+				}
+				break;
+			case TypeDeclaration.INTERFACE_DECL :
+			case TypeDeclaration.ANNOTATION_TYPE_DECL :
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=329663
+				if (this.hierarchy.typeToSuperInterfaces.get(typeHandle) == null)
+					this.hierarchy.addInterface(typeHandle);
+				break;
+		}
+		if (superinterfaceHandles == null) {
+			superinterfaceHandles = TypeHierarchy.NO_TYPE;
+		}
+		this.hierarchy.cacheSuperInterfaces(typeHandle, superinterfaceHandles);
+
+		// record flags
+		this.hierarchy.cacheFlags(typeHandle, type.getModifiers());
+	}
+	/**
+	 * Returns a handle for the given generic type or null if not found.
+	 */
+	protected IType getHandle(IGenericType genericType, ReferenceBinding binding) {
+		if (genericType == null)
+			return null;
+		if (genericType instanceof HierarchyType) {
+			IType handle = (IType)this.infoToHandle.get(genericType);
+			if (handle == null) {
+				handle = ((HierarchyType)genericType).typeHandle;
+				handle = (IType) ((JavaElement) handle).resolved(binding);
+				this.infoToHandle.put(genericType, handle);
+			}
+			return handle;
+		} else if (genericType.isBinaryType()) {
+			ClassFile classFile = (ClassFile) this.infoToHandle.get(genericType);
+			// if it's null, it's from outside the region, so do lookup
+			if (classFile == null) {
+				IType handle = lookupBinaryHandle((IBinaryType) genericType);
+				if (handle == null)
+					return null;
+				// case of an anonymous type (see 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class)
+				// optimization: remember the handle for next call (case of java.io.Serializable that a lot of classes implement)
+				classFile = (ClassFile) handle.getParent();
+				this.infoToHandle.put(genericType, classFile);
+			}
+			return new ResolvedBinaryType(classFile, classFile.getTypeName(), new String(binding.computeUniqueKey()));
+		} else if (genericType instanceof SourceTypeElementInfo) {
+			IType handle = ((SourceTypeElementInfo) genericType).getHandle();
+			return (IType) ((JavaElement) handle).resolved(binding);
+		} else
+			return null;
+	}
+	protected IType getType() {
+		return this.hierarchy.getType();
+	}
+	/**
+	 * Looks up and returns a handle for the given binary info.
+	 */
+	protected IType lookupBinaryHandle(IBinaryType typeInfo) {
+		int flag;
+		String qualifiedName;
+		switch (TypeDeclaration.kind(typeInfo.getModifiers())) {
+			case TypeDeclaration.CLASS_DECL :
+				flag = NameLookup.ACCEPT_CLASSES;
+				break;
+			case TypeDeclaration.INTERFACE_DECL :
+				flag = NameLookup.ACCEPT_INTERFACES;
+				break;
+			case TypeDeclaration.ENUM_DECL :
+				flag = NameLookup.ACCEPT_ENUMS;
+				break;
+			default:
+				//case IGenericType.ANNOTATION :
+				flag = NameLookup.ACCEPT_ANNOTATIONS;
+				break;
+		}
+		char[] bName = typeInfo.getName();
+		qualifiedName = new String(ClassFile.translatedName(bName));
+		if (qualifiedName.equals(this.focusQualifiedName)) return getType();
+		NameLookup.Answer answer = this.nameLookup.findType(qualifiedName,
+			false,
+			flag,
+			true/* consider secondary types */,
+			false/* do NOT wait for indexes */,
+			false/*don't check restrictions*/,
+			null);
+		return answer == null || answer.type == null || !answer.type.isBinary() ? null : answer.type;
+
+	}
+	protected void worked(IProgressMonitor monitor, int work) {
+		if (monitor != null) {
+			if (monitor.isCanceled()) {
+				throw new OperationCanceledException();
+			} else {
+				monitor.worked(work);
+			}
+		}
+	}
+/**
+ * Create an ICompilationUnit info from the given compilation unit on disk.
+ */
+protected ICompilationUnit createCompilationUnitFromPath(Openable handle, IFile file) {
+	final char[] elementName = handle.getElementName().toCharArray();
+	return new ResourceCompilationUnit(file, file.getLocationURI()) {
+		public char[] getFileName() {
+			return elementName;
+		}
+	};
+}
+	/**
+ * Creates the type info from the given class file on disk and
+ * adds it to the given list of infos.
+ */
+protected IBinaryType createInfoFromClassFile(Openable handle, IResource file) {
+	IBinaryType info = null;
+	try {
+		info = Util.newClassFileReader(file);
+	} catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	} catch (java.io.IOException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	} catch (CoreException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	this.infoToHandle.put(info, handle);
+	return info;
+}
+	/**
+ * Create a type info from the given class file in a jar and adds it to the given list of infos.
+ */
+protected IBinaryType createInfoFromClassFileInJar(Openable classFile) {
+	PackageFragment pkg = (PackageFragment) classFile.getParent();
+	String classFilePath = Util.concatWith(pkg.names, classFile.getElementName(), '/');
+	IBinaryType info = null;
+	java.util.zip.ZipFile zipFile = null;
+	try {
+		zipFile = ((JarPackageFragmentRoot)pkg.getParent()).getJar();
+		info = org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader.read(
+			zipFile,
+			classFilePath);
+	} catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	} catch (java.io.IOException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	} catch (CoreException e) {
+		if (TypeHierarchy.DEBUG) {
+			e.printStackTrace();
+		}
+		return null;
+	} finally {
+		JavaModelManager.getJavaModelManager().closeZipFile(zipFile);
+	}
+	this.infoToHandle.put(info, classFile);
+	return info;
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
new file mode 100644
index 0000000..30ee201
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
@@ -0,0 +1,893 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+/**
+ * This is the public entry point to resolve type hierarchies.
+ *
+ * When requesting additional types from the name environment, the resolver
+ * accepts all forms (binary, source & compilation unit) for additional types.
+ *
+ * Side notes: Binary types already know their resolved supertypes so this
+ * only makes sense for source types. Even though the compiler finds all binary
+ * types to complete the hierarchy of a given source type, is there any reason
+ * why the requestor should be informed that binary type X subclasses Y &
+ * implements I & J?
+ */
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
+import org.eclipse.jdt.internal.core.util.HandleFactory;
+
+public class HierarchyResolver implements ITypeRequestor {
+
+	private ReferenceBinding focusType;
+	private boolean superTypesOnly;
+	private boolean hasMissingSuperClass;
+	LookupEnvironment lookupEnvironment;
+	private CompilerOptions options;
+	HierarchyBuilder builder;
+	private ReferenceBinding[] typeBindings;
+
+	private int typeIndex;
+	private IGenericType[] typeModels;
+
+	private static final CompilationUnitDeclaration FakeUnit;
+	static {
+		IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
+		ProblemReporter problemReporter = new ProblemReporter(policy, new CompilerOptions(), new DefaultProblemFactory());
+		CompilationResult result = new CompilationResult(CharOperation.NO_CHAR, 0, 0, 0);
+		FakeUnit = new CompilationUnitDeclaration(problemReporter, result, 0);
+	}
+
+public HierarchyResolver(INameEnvironment nameEnvironment, Map settings, HierarchyBuilder builder, IProblemFactory problemFactory) {
+	// create a problem handler with the 'exit after all problems' handling policy
+	this.options = new CompilerOptions(settings);
+	IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
+	ProblemReporter problemReporter = new ProblemReporter(policy, this.options, problemFactory);
+
+	LookupEnvironment environment = new LookupEnvironment(this, this.options, problemReporter, nameEnvironment);
+	environment.mayTolerateMissingType = true;
+	setEnvironment(environment, builder);
+}
+public HierarchyResolver(LookupEnvironment lookupEnvironment, HierarchyBuilder builder) {
+	setEnvironment(lookupEnvironment, builder);
+}
+
+/**
+ * Add an additional binary type
+ * @param binaryType
+ * @param packageBinding
+ */
+public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+	IProgressMonitor progressMonitor = this.builder.hierarchy.progressMonitor;
+	if (progressMonitor != null && progressMonitor.isCanceled())
+		throw new OperationCanceledException();
+
+	BinaryTypeBinding typeBinding = this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
+	try {
+		this.remember(binaryType, typeBinding);
+	} catch (AbortCompilation e) {
+		// ignore
+	}
+}
+
+/**
+ * Add an additional compilation unit.
+ * @param sourceUnit
+ */
+public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+	//System.out.println("Cannot accept compilation units inside the HierarchyResolver.");
+	this.lookupEnvironment.problemReporter.abortDueToInternalError(
+		new StringBuffer(Messages.accept_cannot)
+			.append(sourceUnit.getFileName())
+			.toString());
+}
+
+/**
+ * Add additional source types
+ * @param sourceTypes
+ * @param packageBinding
+ */
+public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+	IProgressMonitor progressMonitor = this.builder.hierarchy.progressMonitor;
+	if (progressMonitor != null && progressMonitor.isCanceled())
+		throw new OperationCanceledException();
+
+	// find most enclosing type first (needed when explicit askForType(...) is done
+	// with a member type (e.g. p.A$B))
+	ISourceType sourceType = sourceTypes[0];
+	while (sourceType.getEnclosingType() != null)
+		sourceType = sourceType.getEnclosingType();
+
+	// build corresponding compilation unit
+	CompilationResult result = new CompilationResult(sourceType.getFileName(), 1, 1, this.options.maxProblemsPerUnit);
+	CompilationUnitDeclaration unit =
+		SourceTypeConverter.buildCompilationUnit(
+			new ISourceType[] {sourceType}, // ignore secondary types, to improve laziness
+			SourceTypeConverter.MEMBER_TYPE, // need member types
+			// no need for field initialization
+			this.lookupEnvironment.problemReporter,
+			result);
+
+	// build bindings
+	if (unit != null) {
+		try {
+			this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
+
+			org.eclipse.jdt.core.ICompilationUnit cu = ((SourceTypeElementInfo)sourceType).getHandle().getCompilationUnit();
+			rememberAllTypes(unit, cu, false);
+
+			this.lookupEnvironment.completeTypeBindings(unit, true/*build constructor only*/);
+		} catch (AbortCompilation e) {
+			// missing 'java.lang' package: ignore
+		}
+	}
+}
+/*
+ * Creates the super class handle of the given type.
+ * Returns null if the type has no super class.
+ * Adds the simple name to the hierarchy missing types if the class is not found and returns null.
+ */
+private IType findSuperClass(IGenericType type, ReferenceBinding typeBinding) {
+	ReferenceBinding superBinding = typeBinding.superclass();
+
+	if (superBinding != null) {
+		superBinding = (ReferenceBinding) superBinding.erasure();
+		if (typeBinding.isHierarchyInconsistent()) {
+			if (superBinding.problemId() == ProblemReasons.NotFound) {
+				this.hasMissingSuperClass = true;
+				this.builder.hierarchy.missingTypes.add(new String(superBinding.sourceName)); // note: this could be Map$Entry
+				return null;
+			} else if ((superBinding.id == TypeIds.T_JavaLangObject)) {
+				char[] superclassName;
+				char separator;
+				if (type instanceof IBinaryType) {
+					superclassName = ((IBinaryType)type).getSuperclassName();
+					separator = '/';
+				} else if (type instanceof ISourceType) {
+					superclassName = ((ISourceType)type).getSuperclassName();
+					separator = '.';
+				} else if (type instanceof HierarchyType) {
+					superclassName = ((HierarchyType)type).superclassName;
+					separator = '.';
+				} else {
+					return null;
+				}
+
+				if (superclassName != null) { // check whether subclass of Object due to broken hierarchy (as opposed to explicitly extending it)
+					int lastSeparator = CharOperation.lastIndexOf(separator, superclassName);
+					char[] simpleName = lastSeparator == -1 ? superclassName : CharOperation.subarray(superclassName, lastSeparator+1, superclassName.length);
+					if (!CharOperation.equals(simpleName, TypeConstants.OBJECT)) {
+						this.hasMissingSuperClass = true;
+						this.builder.hierarchy.missingTypes.add(new String(simpleName));
+						return null;
+					}
+				}
+			}
+		}
+		for (int t = this.typeIndex; t >= 0; t--) {
+			if (this.typeBindings[t] == superBinding) {
+				return this.builder.getHandle(this.typeModels[t], superBinding);
+			}
+		}
+	}
+	return null;
+}
+/*
+ * Returns the handles of the super interfaces of the given type.
+ * Adds the simple name to the hierarchy missing types if an interface is not found (but don't put null in the returned array)
+ */
+private IType[] findSuperInterfaces(IGenericType type, ReferenceBinding typeBinding) {
+	char[][] superInterfaceNames;
+	char separator;
+	if (type instanceof IBinaryType) {
+		superInterfaceNames = ((IBinaryType)type).getInterfaceNames();
+		separator = '/';
+	} else if (type instanceof ISourceType) {
+		ISourceType sourceType = (ISourceType)type;
+		if (sourceType.getName().length == 0) { // if anonymous type
+			if (typeBinding.superInterfaces() != null && typeBinding.superInterfaces().length > 0) {
+				superInterfaceNames = new char[][] {sourceType.getSuperclassName()};
+			} else {
+				superInterfaceNames = sourceType.getInterfaceNames();
+			}
+		} else {
+			if (TypeDeclaration.kind(sourceType.getModifiers()) == TypeDeclaration.ANNOTATION_TYPE_DECL)
+				superInterfaceNames = new char[][] {TypeConstants.CharArray_JAVA_LANG_ANNOTATION_ANNOTATION};
+			else
+				superInterfaceNames = sourceType.getInterfaceNames();
+		}
+		separator = '.';
+	} else if (type instanceof HierarchyType) {
+		HierarchyType hierarchyType = (HierarchyType)type;
+		if (hierarchyType.name.length == 0) { // if anonymous type
+			if (typeBinding.superInterfaces() != null && typeBinding.superInterfaces().length > 0) {
+				superInterfaceNames = new char[][] {hierarchyType.superclassName};
+			} else {
+				superInterfaceNames = hierarchyType.superInterfaceNames;
+			}
+		} else {
+			superInterfaceNames = hierarchyType.superInterfaceNames;
+		}
+		separator = '.';
+	} else{
+		return null;
+	}
+
+	ReferenceBinding[] interfaceBindings = typeBinding.superInterfaces();
+	int bindingIndex = 0;
+	int bindingLength = interfaceBindings == null ? 0 : interfaceBindings.length;
+	int length = superInterfaceNames == null ? 0 : superInterfaceNames.length;
+	IType[] superinterfaces = new IType[length];
+	int index = 0;
+	next : for (int i = 0; i < length; i++) {
+		char[] superInterfaceName = superInterfaceNames[i];
+		int end = superInterfaceName.length;
+
+		// find the end of simple name
+		int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, superInterfaceName);
+		if (genericStart != -1) end = genericStart;
+
+		// find the start of simple name
+		int lastSeparator = CharOperation.lastIndexOf(separator, superInterfaceName, 0, end);
+		int start = lastSeparator + 1;
+
+		// case of binary inner type -> take the last part
+		int lastDollar = CharOperation.lastIndexOf('$', superInterfaceName, start);
+		if (lastDollar != -1) start = lastDollar + 1;
+
+		char[] simpleName = CharOperation.subarray(superInterfaceName, start, end);
+
+		if (bindingIndex < bindingLength) {
+			ReferenceBinding interfaceBinding = (ReferenceBinding) interfaceBindings[bindingIndex].erasure();
+
+			// ensure that the binding corresponds to the interface defined by the user
+			if (CharOperation.equals(simpleName, interfaceBinding.sourceName)) {
+				bindingIndex++;
+				for (int t = this.typeIndex; t >= 0; t--) {
+					if (this.typeBindings[t] == interfaceBinding) {
+						IType handle = this.builder.getHandle(this.typeModels[t], interfaceBinding);
+						if (handle != null) {
+							superinterfaces[index++] = handle;
+							continue next;
+						}
+					}
+				}
+			}
+		}
+		this.builder.hierarchy.missingTypes.add(new String(simpleName));
+	}
+	if (index != length)
+		System.arraycopy(superinterfaces, 0, superinterfaces = new IType[index], 0, index);
+	return superinterfaces;
+}
+/*
+ * For all type bindings that have hierarchy problems, artificially fix their superclass/superInterfaces so that the connection
+ * can be made.
+ */
+private void fixSupertypeBindings() {
+	for (int current = this.typeIndex; current >= 0; current--) {
+		ReferenceBinding typeBinding = this.typeBindings[current];
+		if ((typeBinding.tagBits & TagBits.HierarchyHasProblems) == 0)
+			continue;
+
+		if (typeBinding instanceof SourceTypeBinding) {
+			if (typeBinding instanceof LocalTypeBinding) {
+				LocalTypeBinding localTypeBinding = (LocalTypeBinding) typeBinding;
+				QualifiedAllocationExpression allocationExpression = localTypeBinding.scope.referenceContext.allocation;
+				TypeReference type;
+				if (allocationExpression != null && (type = allocationExpression.type) != null && type.resolvedType != null) {
+					localTypeBinding.superclass = (ReferenceBinding) type.resolvedType;
+					continue;
+				}
+			}
+			ClassScope scope = ((SourceTypeBinding) typeBinding).scope;
+			if (scope != null) {
+				TypeDeclaration typeDeclaration = scope.referenceContext;
+				TypeReference superclassRef = typeDeclaration == null ? null : typeDeclaration.superclass;
+				TypeBinding superclass = superclassRef == null ? null : superclassRef.resolvedType;
+				if (superclass != null) {
+					superclass = superclass.closestMatch();
+				}
+				if (superclass instanceof ReferenceBinding) {
+					// ensure we are not creating a cycle (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=215681 )
+					if (!(subTypeOfType((ReferenceBinding) superclass, typeBinding))) {
+						((SourceTypeBinding) typeBinding).superclass = (ReferenceBinding) superclass;
+					}
+				}
+
+				TypeReference[] superInterfaces = typeDeclaration == null ? null : typeDeclaration.superInterfaces;
+				int length;
+				ReferenceBinding[] interfaceBindings = typeBinding.superInterfaces();
+				if (superInterfaces != null && (length = superInterfaces.length) > (interfaceBindings == null ? 0 : interfaceBindings.length)) { // check for interfaceBindings being null (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=139689)
+					interfaceBindings = new ReferenceBinding[length];
+					int index = 0;
+					for (int i = 0; i < length; i++) {
+						TypeBinding superInterface = superInterfaces[i].resolvedType;
+						if (superInterface != null) {
+							superInterface = superInterface.closestMatch();
+						}
+						if (superInterface instanceof ReferenceBinding) {
+							// ensure we are not creating a cycle (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=215681 )
+							if (!(subTypeOfType((ReferenceBinding) superInterface, typeBinding))) {
+								interfaceBindings[index++] = (ReferenceBinding) superInterface;
+							}
+						}
+					}
+					if (index < length)
+						System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[index], 0 , index);
+					((SourceTypeBinding) typeBinding).superInterfaces = interfaceBindings;
+				}
+			}
+		} else if (typeBinding instanceof BinaryTypeBinding) {
+			try {
+				typeBinding.superclass();
+			} catch (AbortCompilation e) {
+				// allow subsequent call to superclass() to succeed so that we don't have to catch AbortCompilation everywhere
+				((BinaryTypeBinding) typeBinding).tagBits &= ~TagBits.HasUnresolvedSuperclass;
+				this.builder.hierarchy.missingTypes.add(new String(typeBinding.superclass().sourceName()));
+				this.hasMissingSuperClass = true;
+			}
+			try {
+				typeBinding.superInterfaces();
+			} catch (AbortCompilation e) {
+				// allow subsequent call to superInterfaces() to succeed so that we don't have to catch AbortCompilation everywhere
+				((BinaryTypeBinding) typeBinding).tagBits &= ~TagBits.HasUnresolvedSuperinterfaces;
+			}
+		}
+	}
+}
+private void remember(IGenericType suppliedType, ReferenceBinding typeBinding) {
+	if (typeBinding == null) return;
+
+	if (++this.typeIndex == this.typeModels.length) {
+		System.arraycopy(this.typeModels, 0, this.typeModels = new IGenericType[this.typeIndex * 2], 0, this.typeIndex);
+		System.arraycopy(this.typeBindings, 0, this.typeBindings = new ReferenceBinding[this.typeIndex * 2], 0, this.typeIndex);
+	}
+	this.typeModels[this.typeIndex] = suppliedType;
+	this.typeBindings[this.typeIndex] = typeBinding;
+}
+private void remember(IType type, ReferenceBinding typeBinding) {
+	if (((CompilationUnit)type.getCompilationUnit()).isOpen()) {
+		try {
+			IGenericType genericType = (IGenericType)((JavaElement)type).getElementInfo();
+			remember(genericType, typeBinding);
+		} catch (JavaModelException e) {
+			// cannot happen since element is open
+			return;
+		}
+	} else {
+		if (typeBinding == null) return;
+
+		TypeDeclaration typeDeclaration = ((SourceTypeBinding)typeBinding).scope.referenceType();
+
+		// simple super class name
+		char[] superclassName = null;
+		TypeReference superclass;
+		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+			superclass = typeDeclaration.allocation.type;
+		} else {
+			superclass = typeDeclaration.superclass;
+		}
+		if (superclass != null) {
+			char[][] typeName = superclass.getTypeName();
+			superclassName = typeName == null ? null : typeName[typeName.length-1];
+		}
+
+		// simple super interface names
+		char[][] superInterfaceNames = null;
+		TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+		if (superInterfaces != null) {
+			int length = superInterfaces.length;
+			superInterfaceNames = new char[length][];
+			for (int i = 0; i < length; i++) {
+				TypeReference superInterface = superInterfaces[i];
+				char[][] typeName = superInterface.getTypeName();
+				superInterfaceNames[i] = typeName[typeName.length-1];
+			}
+		}
+
+		HierarchyType hierarchyType = new HierarchyType(
+			type,
+			typeDeclaration.name,
+			typeDeclaration.binding.modifiers,
+			superclassName,
+			superInterfaceNames);
+		remember(hierarchyType, typeDeclaration.binding);
+	}
+
+}
+/*
+ * Remembers all type bindings defined in the given parsed unit, adding local/anonymous types if specified.
+ */
+private void rememberAllTypes(CompilationUnitDeclaration parsedUnit, org.eclipse.jdt.core.ICompilationUnit cu, boolean includeLocalTypes) {
+	TypeDeclaration[] types = parsedUnit.types;
+	if (types != null) {
+		for (int i = 0, length = types.length; i < length; i++) {
+			TypeDeclaration type = types[i];
+			rememberWithMemberTypes(type, cu.getType(new String(type.name)));
+		}
+	}
+	if (includeLocalTypes && parsedUnit.localTypes != null) {
+		HandleFactory factory = new HandleFactory();
+		HashSet existingElements = new HashSet(parsedUnit.localTypeCount);
+		HashMap knownScopes = new HashMap(parsedUnit.localTypeCount);
+		for (int i = 0; i < parsedUnit.localTypeCount; i++) {
+			LocalTypeBinding localType = parsedUnit.localTypes[i];
+			ClassScope classScope = localType.scope;
+			TypeDeclaration typeDecl = classScope.referenceType();
+			IType typeHandle = (IType)factory.createElement(classScope, cu, existingElements, knownScopes);
+			rememberWithMemberTypes(typeDecl, typeHandle);
+		}
+	}
+}
+private void rememberWithMemberTypes(TypeDeclaration typeDecl, IType typeHandle) {
+	remember(typeHandle, typeDecl.binding);
+
+	TypeDeclaration[] memberTypes = typeDecl.memberTypes;
+	if (memberTypes != null) {
+		for (int i = 0, length = memberTypes.length; i < length; i++) {
+			TypeDeclaration memberType = memberTypes[i];
+			rememberWithMemberTypes(memberType, typeHandle.getType(new String(memberType.name)));
+		}
+	}
+}
+/*
+ * Reports the hierarchy from the remembered bindings.
+ * Note that 'binaryTypeBinding' is null if focus type is a source type.
+ */
+private void reportHierarchy(IType focus, TypeDeclaration focusLocalType, ReferenceBinding binaryTypeBinding) {
+
+	// set focus type binding
+	if (focus != null) {
+		if (binaryTypeBinding != null) {
+			// binary type
+			this.focusType = binaryTypeBinding;
+		} else {
+			// source type
+			if (focusLocalType != null) {
+				// anonymous or local type
+				this.focusType = focusLocalType.binding;
+			} else {
+				// top level or member type
+				char[] fullyQualifiedName = focus.getFullyQualifiedName().toCharArray();
+				setFocusType(CharOperation.splitOn('.', fullyQualifiedName));
+			}
+		}
+	}
+
+	// be resilient and fix super type bindings
+	fixSupertypeBindings();
+
+	int objectIndex = -1;
+	IProgressMonitor progressMonitor = this.builder.hierarchy.progressMonitor;
+	for (int current = this.typeIndex; current >= 0; current--) {
+		if (progressMonitor != null && progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+		
+		ReferenceBinding typeBinding = this.typeBindings[current];
+
+		// java.lang.Object treated at the end
+		if (typeBinding.id == TypeIds.T_JavaLangObject) {
+			objectIndex = current;
+			continue;
+		}
+
+		IGenericType suppliedType = this.typeModels[current];
+
+		if (!subOrSuperOfFocus(typeBinding)) {
+			continue; // ignore types outside of hierarchy
+		}
+
+		IType superclass;
+		if (typeBinding.isInterface()){ // do not connect interfaces to Object
+			superclass = null;
+		} else {
+			superclass = findSuperClass(suppliedType, typeBinding);
+		}
+		IType[] superinterfaces = findSuperInterfaces(suppliedType, typeBinding);
+
+		this.builder.connect(suppliedType, this.builder.getHandle(suppliedType, typeBinding), superclass, superinterfaces);
+	}
+	// add java.lang.Object only if the super class is not missing
+	if (objectIndex > -1 && (!this.hasMissingSuperClass || this.focusType == null)) {
+		IGenericType objectType = this.typeModels[objectIndex];
+		this.builder.connect(objectType, this.builder.getHandle(objectType, this.typeBindings[objectIndex]), null, null);
+	}
+}
+private void reset(){
+	this.lookupEnvironment.reset();
+
+	this.focusType = null;
+	this.superTypesOnly = false;
+	this.typeIndex = -1;
+	this.typeModels = new IGenericType[5];
+	this.typeBindings = new ReferenceBinding[5];
+}
+
+/**
+ * Resolve the supertypes for the supplied source type.
+ * Inform the requestor of the resolved supertypes using:
+ *    connect(ISourceType suppliedType, IGenericType superclass, IGenericType[] superinterfaces)
+ * @param suppliedType
+ */
+public void resolve(IGenericType suppliedType) {
+	try {
+		if (suppliedType.isBinaryType()) {
+			BinaryTypeBinding binaryTypeBinding = this.lookupEnvironment.cacheBinaryType((IBinaryType) suppliedType, false/*don't need field and method (bug 125067)*/, null /*no access restriction*/);
+			remember(suppliedType, binaryTypeBinding);
+			// We still need to add superclasses and superinterfaces bindings (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53095)
+			int startIndex = this.typeIndex;
+			for (int i = startIndex; i <= this.typeIndex; i++) {
+				IGenericType igType = this.typeModels[i];
+				if (igType != null && igType.isBinaryType()) {
+					CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
+					// fault in its hierarchy...
+					try {
+						// ensure that unitBeingCompleted is set so that we don't get an AbortCompilation for a missing type
+						// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=213249 )
+						if (previousUnitBeingCompleted == null) {
+							this.lookupEnvironment.unitBeingCompleted = FakeUnit;
+						}
+						ReferenceBinding typeBinding = this.typeBindings[i];
+						typeBinding.superclass();
+						typeBinding.superInterfaces();
+					} catch (AbortCompilation e) {
+						// classpath problem for this type: ignore
+					} finally {
+						this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
+					}
+				}
+			}
+			this.superTypesOnly = true;
+			reportHierarchy(this.builder.getType(), null, binaryTypeBinding);
+		} else {
+			org.eclipse.jdt.core.ICompilationUnit cu = ((SourceTypeElementInfo)suppliedType).getHandle().getCompilationUnit();
+			HashSet localTypes = new HashSet();
+			localTypes.add(cu.getPath().toString());
+			this.superTypesOnly = true;
+			resolve(new Openable[] {(Openable)cu}, localTypes, null);
+		}
+	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+	} finally {
+		reset();
+	}
+}
+
+/**
+ * Resolve the supertypes for the types contained in the given openables (ICompilationUnits and/or IClassFiles).
+ * Inform the requestor of the resolved supertypes for each
+ * supplied source type using:
+ *    connect(ISourceType suppliedType, IGenericType superclass, IGenericType[] superinterfaces)
+ *
+ * Also inform the requestor of the supertypes of each
+ * additional requested super type which is also a source type
+ * instead of a binary type.
+ * @param openables
+ * @param localTypes
+ * @param monitor
+ */
+public void resolve(Openable[] openables, HashSet localTypes, IProgressMonitor monitor) {
+	try {
+		int openablesLength = openables.length;
+		CompilationUnitDeclaration[] parsedUnits = new CompilationUnitDeclaration[openablesLength];
+		boolean[] hasLocalType = new boolean[openablesLength];
+		org.eclipse.jdt.core.ICompilationUnit[] cus = new org.eclipse.jdt.core.ICompilationUnit[openablesLength];
+		int unitsIndex = 0;
+
+		CompilationUnitDeclaration focusUnit = null;
+		ReferenceBinding focusBinaryBinding = null;
+		IType focus = this.builder.getType();
+		Openable focusOpenable = null;
+		if (focus != null) {
+			if (focus.isBinary()) {
+				focusOpenable = (Openable)focus.getClassFile();
+			} else {
+				focusOpenable = (Openable)focus.getCompilationUnit();
+			}
+		}
+
+		// build type bindings
+		Parser parser = new Parser(this.lookupEnvironment.problemReporter, true);
+		for (int i = 0; i < openablesLength; i++) {
+			Openable openable = openables[i];
+			if (openable instanceof org.eclipse.jdt.core.ICompilationUnit) {
+				org.eclipse.jdt.core.ICompilationUnit cu = (org.eclipse.jdt.core.ICompilationUnit)openable;
+
+				// contains a potential subtype as a local or anonymous type?
+				boolean containsLocalType = false;
+				if (localTypes == null) { // case of hierarchy on region
+					containsLocalType = true;
+				} else {
+					IPath path = cu.getPath();
+					containsLocalType = localTypes.contains(path.toString());
+				}
+
+				// build parsed unit
+				CompilationUnitDeclaration parsedUnit = null;
+				if (cu.isOpen()) {
+					// create parsed unit from source element infos
+					CompilationResult result = new CompilationResult((ICompilationUnit)cu, i, openablesLength, this.options.maxProblemsPerUnit);
+					SourceTypeElementInfo[] typeInfos = null;
+					try {
+						IType[] topLevelTypes = cu.getTypes();
+						int topLevelLength = topLevelTypes.length;
+						if (topLevelLength == 0) continue; // empty cu: no need to parse (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=65677)
+						typeInfos = new SourceTypeElementInfo[topLevelLength];
+						for (int j = 0; j < topLevelLength; j++) {
+							IType topLevelType = topLevelTypes[j];
+							typeInfos[j] = (SourceTypeElementInfo)((JavaElement)topLevelType).getElementInfo();
+						}
+					} catch (JavaModelException e) {
+						// types/cu exist since cu is opened
+					}
+					int flags = !containsLocalType
+						? SourceTypeConverter.MEMBER_TYPE
+						: SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE | SourceTypeConverter.LOCAL_TYPE;
+					parsedUnit =
+						SourceTypeConverter.buildCompilationUnit(
+							typeInfos,
+							flags,
+							this.lookupEnvironment.problemReporter,
+							result);
+					
+					// We would have got all the necessary local types by now and hence there is no further need 
+					// to parse the method bodies. Parser.getMethodBodies, which is called latter in this function, 
+					// will not parse the method statements if ASTNode.HasAllMethodBodies is set. 
+					if (containsLocalType) 	parsedUnit.bits |= ASTNode.HasAllMethodBodies;
+				} else {
+					// create parsed unit from file
+					IFile file = (IFile) cu.getResource();
+					ICompilationUnit sourceUnit = this.builder.createCompilationUnitFromPath(openable, file);
+
+					CompilationResult unitResult = new CompilationResult(sourceUnit, i, openablesLength, this.options.maxProblemsPerUnit);
+					parsedUnit = parser.dietParse(sourceUnit, unitResult);
+				}
+
+				if (parsedUnit != null) {
+					hasLocalType[unitsIndex] = containsLocalType;
+					cus[unitsIndex] = cu;
+					parsedUnits[unitsIndex++] = parsedUnit;
+					try {
+						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+						if (openable.equals(focusOpenable)) {
+							focusUnit = parsedUnit;
+						}
+					} catch (AbortCompilation e) {
+						// classpath problem for this type: ignore
+					}
+				}
+			} else {
+				// cache binary type binding
+				ClassFile classFile = (ClassFile)openable;
+				IBinaryType binaryType = (IBinaryType) JavaModelManager.getJavaModelManager().getInfo(classFile.getType());
+				if (binaryType == null) {
+					// create binary type from file
+					if (classFile.getPackageFragmentRoot().isArchive()) {
+						binaryType = this.builder.createInfoFromClassFileInJar(classFile);
+					} else {
+						IResource file = classFile.resource();
+						binaryType = this.builder.createInfoFromClassFile(classFile, file);
+					}
+				}
+				if (binaryType != null) {
+					try {
+						BinaryTypeBinding binaryTypeBinding = this.lookupEnvironment.cacheBinaryType(binaryType, false/*don't need field and method (bug 125067)*/, null /*no access restriction*/);
+						remember(binaryType, binaryTypeBinding);
+						if (openable.equals(focusOpenable)) {
+							focusBinaryBinding = binaryTypeBinding;
+						}
+					} catch (AbortCompilation e) {
+						// classpath problem for this type: ignore
+					}
+				}
+			}
+		}
+
+		// remember type declaration of focus if local/anonymous early (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=210498)
+		TypeDeclaration focusLocalType = null;
+		if (focus != null && focusBinaryBinding == null && focusUnit != null && ((Member)focus).getOuterMostLocalContext() != null) {
+			focusLocalType = new ASTNodeFinder(focusUnit).findType(focus);
+		}
+
+
+		for (int i = 0; i <= this.typeIndex; i++) {
+			IGenericType suppliedType = this.typeModels[i];
+			if (suppliedType != null && suppliedType.isBinaryType()) {
+				CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
+				// fault in its hierarchy...
+				try {
+					// ensure that unitBeingCompleted is set so that we don't get an AbortCompilation for a missing type
+					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=213249 )
+					if (previousUnitBeingCompleted == null) {
+						this.lookupEnvironment.unitBeingCompleted = FakeUnit;
+					}
+					ReferenceBinding typeBinding = this.typeBindings[i];
+					typeBinding.superclass();
+					typeBinding.superInterfaces();
+				} catch (AbortCompilation e) {
+					// classpath problem for this type: ignore
+				} finally {
+					this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
+				}
+			}
+		}
+
+		// complete type bindings (i.e. connect super types)
+		for (int i = 0; i < unitsIndex; i++) {
+			CompilationUnitDeclaration parsedUnit = parsedUnits[i];
+			if (parsedUnit != null) {
+				try {
+					if (hasLocalType[i]) { // NB: no-op if method bodies have been already parsed
+						if (monitor != null && monitor.isCanceled())
+							throw new OperationCanceledException();
+						parser.getMethodBodies(parsedUnit);
+					}
+				} catch (AbortCompilation e) {
+					// classpath problem for this type: don't try to resolve (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49809)
+					hasLocalType[i] = false;
+				}
+			}
+		}
+		// complete type bindings and build fields and methods only for local types
+		// (in this case the constructor is needed when resolving local types)
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=145333)
+		try {
+			this.lookupEnvironment.completeTypeBindings(parsedUnits, hasLocalType, unitsIndex);
+			// remember type bindings
+			for (int i = 0; i < unitsIndex; i++) {
+				CompilationUnitDeclaration parsedUnit = parsedUnits[i];
+				if (parsedUnit != null && !parsedUnit.hasErrors()) {
+					boolean containsLocalType = hasLocalType[i];
+					if (containsLocalType) {
+						if (monitor != null && monitor.isCanceled())
+							throw new OperationCanceledException();
+						parsedUnit.scope.faultInTypes();
+						parsedUnit.resolve();
+					}
+					
+					rememberAllTypes(parsedUnit, cus[i], containsLocalType);
+				}
+			}
+		} catch (AbortCompilation e) {
+			// skip it silently
+		}
+		worked(monitor, 1);
+
+
+		// if no potential subtype was a real subtype of the binary focus type, no need to go further
+		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=54043)
+		if (focusBinaryBinding == null && focus != null && focus.isBinary()) {
+			char[] fullyQualifiedName = focus.getFullyQualifiedName().toCharArray();
+			focusBinaryBinding = this.lookupEnvironment.getCachedType(CharOperation.splitOn('.', fullyQualifiedName));
+			if (focusBinaryBinding == null)
+				return;
+		}
+
+		reportHierarchy(focus, focusLocalType, focusBinaryBinding);
+
+	} catch (ClassCastException e){ // work-around for 1GF5W1S - can happen in case duplicates are fed to the hierarchy with binaries hiding sources
+	} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+		if (TypeHierarchy.DEBUG)
+			e.printStackTrace();
+	} finally {
+		reset();
+	}
+}
+private void setEnvironment(LookupEnvironment lookupEnvironment, HierarchyBuilder builder) {
+	this.lookupEnvironment = lookupEnvironment;
+	this.builder = builder;
+
+	this.typeIndex = -1;
+	this.typeModels = new IGenericType[5];
+	this.typeBindings = new ReferenceBinding[5];
+}
+
+/*
+ * Set the focus type (i.e. the type that this resolver is computing the hierarch for.
+ * Returns the binding of this focus type or null if it could not be found.
+ */
+public ReferenceBinding setFocusType(char[][] compoundName) {
+	if (compoundName == null || this.lookupEnvironment == null) return null;
+	this.focusType = this.lookupEnvironment.getCachedType(compoundName);
+	if (this.focusType == null) {
+		this.focusType = this.lookupEnvironment.askForType(compoundName);
+		if (this.focusType == null) {
+			int length = compoundName.length;
+			char[] typeName = compoundName[length-1];
+			int firstDollar = CharOperation.indexOf('$', typeName);
+			if (firstDollar != -1) {
+				compoundName[length-1] = CharOperation.subarray(typeName, 0, firstDollar);
+				this.focusType = this.lookupEnvironment.askForType(compoundName);
+				if (this.focusType != null) {
+					char[][] memberTypeNames = CharOperation.splitOn('$', typeName, firstDollar+1, typeName.length);
+					for (int i = 0; i < memberTypeNames.length; i++) {
+						this.focusType = this.focusType.getMemberType(memberTypeNames[i]);
+						if (this.focusType == null)
+							return null;
+					}
+				}
+			}
+		}
+	}
+	return this.focusType;
+}
+public boolean subOrSuperOfFocus(ReferenceBinding typeBinding) {
+	if (this.focusType == null) return true; // accept all types (case of hierarchy in a region)
+	try {
+		if (subTypeOfType(this.focusType, typeBinding)) return true;
+		if (!this.superTypesOnly && subTypeOfType(typeBinding, this.focusType)) return true;
+	} catch (AbortCompilation e) {
+		// unresolved superclass/superinterface -> ignore
+	}
+	return false;
+}
+private boolean subTypeOfType(ReferenceBinding subType, ReferenceBinding typeBinding) {
+	if (typeBinding == null || subType == null) return false;
+	if (subType == typeBinding) return true;
+	ReferenceBinding superclass = subType.superclass();
+	if (superclass != null) superclass = (ReferenceBinding) superclass.erasure();
+//	if (superclass != null && superclass.id == TypeIds.T_JavaLangObject && subType.isHierarchyInconsistent()) return false;
+	if (subTypeOfType(superclass, typeBinding)) return true;
+	ReferenceBinding[] superInterfaces = subType.superInterfaces();
+	if (superInterfaces != null) {
+		for (int i = 0, length = superInterfaces.length; i < length; i++) {
+			ReferenceBinding superInterface = (ReferenceBinding) superInterfaces[i].erasure();
+			if (subTypeOfType(superInterface, typeBinding)) return true;
+		}
+	}
+	return false;
+}
+protected void worked(IProgressMonitor monitor, int work) {
+	if (monitor != null) {
+		if (monitor.isCanceled()) {
+			throw new OperationCanceledException();
+		} else {
+			monitor.worked(work);
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java
new file mode 100644
index 0000000..ef674ae
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.internal.compiler.env.IGenericType;
+
+/**
+ *
+ * Partial implementation of an IGenericType used to
+ * answer hierarchies.
+ */
+public class HierarchyType implements IGenericType {
+
+	public IType typeHandle;
+	public char[] name;
+	public int modifiers;
+	public char[] superclassName;
+	public char[][] superInterfaceNames;
+
+public HierarchyType(
+	IType typeHandle,
+	char[] name,
+	int modifiers,
+	char[] superclassName,
+	char[][] superInterfaceNames) {
+
+	this.typeHandle = typeHandle;
+	this.name = name;
+	this.modifiers = modifiers;
+	this.superclassName = superclassName;
+	this.superInterfaceNames = superInterfaceNames;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.typeHandle.getCompilationUnit().getElementName().toCharArray();
+}
+
+/**
+ * Answer an int whose bits are set according the access constants
+ * defined by the VM spec.
+ */
+public int getModifiers() {
+	return this.modifiers;
+}
+/**
+ * Answer whether the receiver contains the resolved binary form
+ * or the unresolved source form of the type.
+ */
+public boolean isBinaryType() {
+	return false;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
new file mode 100644
index 0000000..bf54a70
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
@@ -0,0 +1,547 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.util.*;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.JavaSearchParticipant;
+import org.eclipse.jdt.internal.core.search.SubTypeSearchJob;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+import org.eclipse.jdt.internal.core.search.matching.SuperTypeReferencePattern;
+import org.eclipse.jdt.internal.core.util.HandleFactory;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class IndexBasedHierarchyBuilder extends HierarchyBuilder implements SuffixConstants {
+	public static final int MAXTICKS = 800; // heuristic so that there still progress for deep hierachies
+	/**
+	 * A temporary cache of compilation units to handles to speed info
+	 * to handle translation - it only contains the entries
+	 * for the types in the region (in other words, it contains no supertypes outside
+	 * the region).
+	 */
+	protected Map cuToHandle;
+
+	/**
+	 * The scope this hierarchy builder should restrain results to.
+	 */
+	protected IJavaSearchScope scope;
+
+	/**
+	 * Cache used to record binaries recreated from index matches
+	 */
+	protected Map binariesFromIndexMatches;
+
+	/**
+	 * Collection used to queue subtype index queries
+	 */
+	static class Queue {
+		public char[][] names = new char[10][];
+		public int start = 0;
+		public int end = -1;
+		public void add(char[] name){
+			if (++this.end == this.names.length){
+				this.end -= this.start;
+				System.arraycopy(this.names, this.start, this.names = new char[this.end*2][], 0, this.end);
+				this.start = 0;
+			}
+			this.names[this.end] = name;
+		}
+		public char[] retrieve(){
+			if (this.start > this.end) return null; // none
+
+			char[] name = this.names[this.start++];
+			if (this.start > this.end){
+				this.start = 0;
+				this.end = -1;
+			}
+			return name;
+		}
+		public String toString(){
+			StringBuffer buffer = new StringBuffer("Queue:\n"); //$NON-NLS-1$
+			for (int i = this.start; i <= this.end; i++){
+				buffer.append(this.names[i]).append('\n');
+			}
+			return buffer.toString();
+		}
+	}
+public IndexBasedHierarchyBuilder(TypeHierarchy hierarchy, IJavaSearchScope scope) throws JavaModelException {
+	super(hierarchy);
+	this.cuToHandle = new HashMap(5);
+	this.binariesFromIndexMatches = new HashMap(10);
+	this.scope = scope;
+}
+public void build(boolean computeSubtypes) {
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	try {
+		// optimize access to zip files while building hierarchy
+		manager.cacheZipFiles(this);
+
+		if (computeSubtypes) {
+			// Note by construction there always is a focus type here
+			IType focusType = getType();
+			boolean focusIsObject = focusType.getElementName().equals(new String(IIndexConstants.OBJECT));
+			int amountOfWorkForSubtypes = focusIsObject ? 5 : 80; // percentage of work needed to get possible subtypes
+			IProgressMonitor possibleSubtypesMonitor =
+				this.hierarchy.progressMonitor == null ?
+					null :
+					new SubProgressMonitor(this.hierarchy.progressMonitor, amountOfWorkForSubtypes);
+			HashSet localTypes = new HashSet(10); // contains the paths that have potential subtypes that are local/anonymous types
+			String[] allPossibleSubtypes;
+			if (((Member)focusType).getOuterMostLocalContext() == null) {
+				// top level or member type
+				allPossibleSubtypes = determinePossibleSubTypes(localTypes, possibleSubtypesMonitor);
+			} else {
+				// local or anonymous type
+				allPossibleSubtypes = CharOperation.NO_STRINGS;
+			}
+			if (allPossibleSubtypes != null) {
+				IProgressMonitor buildMonitor =
+					this.hierarchy.progressMonitor == null ?
+						null :
+						new SubProgressMonitor(this.hierarchy.progressMonitor, 100 - amountOfWorkForSubtypes);
+				this.hierarchy.initialize(allPossibleSubtypes.length);
+				buildFromPotentialSubtypes(allPossibleSubtypes, localTypes, buildMonitor);
+			}
+		} else {
+			this.hierarchy.initialize(1);
+			buildSupertypes();
+		}
+	} finally {
+		manager.flushZipFiles(this);
+	}
+}
+private void buildForProject(JavaProject project, ArrayList potentialSubtypes, org.eclipse.jdt.core.ICompilationUnit[] workingCopies, HashSet localTypes, IProgressMonitor monitor) throws JavaModelException {
+	// resolve
+	int openablesLength = potentialSubtypes.size();
+	if (openablesLength > 0) {
+		// copy vectors into arrays
+		Openable[] openables = new Openable[openablesLength];
+		potentialSubtypes.toArray(openables);
+
+		// sort in the order of roots and in reverse alphabetical order for .class file
+		// since requesting top level types in the process of caching an enclosing type is
+		// not supported by the lookup environment
+		IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
+		int rootsLength = roots.length;
+		final HashtableOfObjectToInt indexes = new HashtableOfObjectToInt(openablesLength);
+		for (int i = 0; i < openablesLength; i++) {
+			IJavaElement root = openables[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			int index;
+			for (index = 0; index < rootsLength; index++) {
+				if (roots[index].equals(root))
+					break;
+			}
+			indexes.put(openables[i], index);
+		}
+		Arrays.sort(openables, new Comparator() {
+			public int compare(Object a, Object b) {
+				int aIndex = indexes.get(a);
+				int bIndex = indexes.get(b);
+				if (aIndex != bIndex)
+					return aIndex - bIndex;
+				return ((Openable) b).getElementName().compareTo(((Openable) a).getElementName());
+			}
+		});
+
+		IType focusType = getType();
+		boolean inProjectOfFocusType = focusType != null && focusType.getJavaProject().equals(project);
+		org.eclipse.jdt.core.ICompilationUnit[] unitsToLookInside = null;
+		if (inProjectOfFocusType) {
+			org.eclipse.jdt.core.ICompilationUnit unitToLookInside = focusType.getCompilationUnit();
+			if (unitToLookInside != null) {
+				int wcLength = workingCopies == null ? 0 : workingCopies.length;
+				if (wcLength == 0) {
+					unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[] {unitToLookInside};
+				} else {
+					unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[wcLength+1];
+					unitsToLookInside[0] = unitToLookInside;
+					System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
+				}
+			} else {
+				unitsToLookInside = workingCopies;
+			}
+		}
+
+		SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
+		this.nameLookup = searchableEnvironment.nameLookup;
+		Map options = project.getOptions(true);
+		// disable task tags to speed up parsing
+		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+		this.hierarchyResolver =
+			new HierarchyResolver(searchableEnvironment, options, this, new DefaultProblemFactory());
+		if (focusType != null) {
+			Member declaringMember = ((Member)focusType).getOuterMostLocalContext();
+			if (declaringMember == null) {
+				// top level or member type
+				if (!inProjectOfFocusType) {
+					char[] typeQualifiedName = focusType.getTypeQualifiedName('.').toCharArray();
+					String[] packageName = ((PackageFragment) focusType.getPackageFragment()).names;
+					if (searchableEnvironment.findType(typeQualifiedName, Util.toCharArrays(packageName)) == null) {
+						// focus type is not visible in this project: no need to go further
+						return;
+					}
+				}
+			} else {
+				// local or anonymous type
+				Openable openable;
+				if (declaringMember.isBinary()) {
+					openable = (Openable)declaringMember.getClassFile();
+				} else {
+					openable = (Openable)declaringMember.getCompilationUnit();
+				}
+				localTypes = new HashSet();
+				localTypes.add(openable.getPath().toString());
+				this.hierarchyResolver.resolve(new Openable[] {openable}, localTypes, monitor);
+				return;
+			}
+		}
+		this.hierarchyResolver.resolve(openables, localTypes, monitor);
+	}
+}
+/**
+ * Configure this type hierarchy based on the given potential subtypes.
+ */
+private void buildFromPotentialSubtypes(String[] allPotentialSubTypes, HashSet localTypes, IProgressMonitor monitor) {
+	IType focusType = getType();
+
+	// substitute compilation units with working copies
+	HashMap wcPaths = new HashMap(); // a map from path to working copies
+	int wcLength;
+	org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.hierarchy.workingCopies;
+	if (workingCopies != null && (wcLength = workingCopies.length) > 0) {
+		String[] newPaths = new String[wcLength];
+		for (int i = 0; i < wcLength; i++) {
+			org.eclipse.jdt.core.ICompilationUnit workingCopy = workingCopies[i];
+			String path = workingCopy.getPath().toString();
+			wcPaths.put(path, workingCopy);
+			newPaths[i] = path;
+		}
+		int potentialSubtypesLength = allPotentialSubTypes.length;
+		System.arraycopy(allPotentialSubTypes, 0, allPotentialSubTypes = new String[potentialSubtypesLength+wcLength], 0, potentialSubtypesLength);
+		System.arraycopy(newPaths, 0, allPotentialSubTypes, potentialSubtypesLength, wcLength);
+	}
+
+	int length = allPotentialSubTypes.length;
+
+	// inject the compilation unit of the focus type (so that types in
+	// this cu have special visibility permission (this is also usefull
+	// when the cu is a working copy)
+	Openable focusCU = (Openable)focusType.getCompilationUnit();
+	String focusPath = null;
+	if (focusCU != null) {
+		focusPath = focusCU.getPath().toString();
+		if (length > 0) {
+			System.arraycopy(allPotentialSubTypes, 0, allPotentialSubTypes = new String[length+1], 0, length);
+			allPotentialSubTypes[length] = focusPath;
+		} else {
+			allPotentialSubTypes = new String[] {focusPath};
+		}
+		length++;
+	}
+
+	/*
+	 * Sort in alphabetical order so that potential subtypes are grouped per project
+	 */
+	Arrays.sort(allPotentialSubTypes);
+
+	ArrayList potentialSubtypes = new ArrayList();
+	try {
+		// create element infos for subtypes
+		HandleFactory factory = new HandleFactory();
+		IJavaProject currentProject = null;
+		if (monitor != null) monitor.beginTask("", length*2 /* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
+		for (int i = 0; i < length; i++) {
+			try {
+				String resourcePath = allPotentialSubTypes[i];
+
+				// skip duplicate paths (e.g. if focus path was injected when it was already a potential subtype)
+				if (i > 0 && resourcePath.equals(allPotentialSubTypes[i-1])) continue;
+
+				Openable handle;
+				org.eclipse.jdt.core.ICompilationUnit workingCopy = (org.eclipse.jdt.core.ICompilationUnit)wcPaths.get(resourcePath);
+				if (workingCopy != null) {
+					handle = (Openable)workingCopy;
+				} else {
+					handle =
+						resourcePath.equals(focusPath) ?
+							focusCU :
+							factory.createOpenable(resourcePath, this.scope);
+					if (handle == null) continue; // match is outside classpath
+				}
+
+				IJavaProject project = handle.getJavaProject();
+				if (currentProject == null) {
+					currentProject = project;
+					potentialSubtypes = new ArrayList(5);
+				} else if (!currentProject.equals(project)) {
+					// build current project
+					buildForProject((JavaProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+					currentProject = project;
+					potentialSubtypes = new ArrayList(5);
+				}
+
+				potentialSubtypes.add(handle);
+			} catch (JavaModelException e) {
+				continue;
+			}
+		}
+
+		// build last project
+		try {
+			if (currentProject == null) {
+				// case of no potential subtypes
+				currentProject = focusType.getJavaProject();
+				if (focusType.isBinary()) {
+					potentialSubtypes.add(focusType.getClassFile());
+				} else {
+					potentialSubtypes.add(focusType.getCompilationUnit());
+				}
+			}
+			buildForProject((JavaProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+		} catch (JavaModelException e) {
+			// ignore
+		}
+
+		// Compute hierarchy of focus type if not already done (case of a type with potential subtypes that are not real subtypes)
+		if (!this.hierarchy.contains(focusType)) {
+			try {
+				currentProject = focusType.getJavaProject();
+				potentialSubtypes = new ArrayList();
+				if (focusType.isBinary()) {
+					potentialSubtypes.add(focusType.getClassFile());
+				} else {
+					potentialSubtypes.add(focusType.getCompilationUnit());
+				}
+				buildForProject((JavaProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+			} catch (JavaModelException e) {
+				// ignore
+			}
+		}
+
+		// Add focus if not already in (case of a type with no explicit super type)
+		if (!this.hierarchy.contains(focusType)) {
+			this.hierarchy.addRootClass(focusType);
+		}
+	} finally {
+		if (monitor != null) monitor.done();
+	}
+}
+protected ICompilationUnit createCompilationUnitFromPath(Openable handle, IFile file) {
+	ICompilationUnit unit = super.createCompilationUnitFromPath(handle, file);
+	this.cuToHandle.put(unit, handle);
+	return unit;
+}
+protected IBinaryType createInfoFromClassFile(Openable classFile, IResource file) {
+	String documentPath = classFile.getPath().toString();
+	IBinaryType binaryType = (IBinaryType)this.binariesFromIndexMatches.get(documentPath);
+	if (binaryType != null) {
+		this.infoToHandle.put(binaryType, classFile);
+		return binaryType;
+	} else {
+		return super.createInfoFromClassFile(classFile, file);
+	}
+}
+protected IBinaryType createInfoFromClassFileInJar(Openable classFile) {
+	String filePath = (((ClassFile)classFile).getType().getFullyQualifiedName('$')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
+	IPackageFragmentRoot root = classFile.getPackageFragmentRoot();
+	IPath path = root.getPath();
+	// take the OS path for external jars, and the forward slash path for internal jars
+	String rootPath = path.getDevice() == null ? path.toString() : path.toOSString();
+	String documentPath = rootPath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + filePath;
+	IBinaryType binaryType = (IBinaryType)this.binariesFromIndexMatches.get(documentPath);
+	if (binaryType != null) {
+		this.infoToHandle.put(binaryType, classFile);
+		return binaryType;
+	} else {
+		return super.createInfoFromClassFileInJar(classFile);
+	}
+}
+/**
+ * Returns all of the possible subtypes of this type hierarchy.
+ * Returns null if they could not be determine.
+ */
+private String[] determinePossibleSubTypes(final HashSet localTypes, IProgressMonitor monitor) {
+
+	class PathCollector implements IPathRequestor {
+		HashSet paths = new HashSet(10);
+		public void acceptPath(String path, boolean containsLocalTypes) {
+			this.paths.add(path);
+			if (containsLocalTypes) {
+				localTypes.add(path);
+			}
+		}
+	}
+	PathCollector collector = new PathCollector();
+
+	try {
+		if (monitor != null) monitor.beginTask("", MAXTICKS); //$NON-NLS-1$
+		searchAllPossibleSubTypes(
+			getType(),
+			this.scope,
+			this.binariesFromIndexMatches,
+			collector,
+			IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+			monitor);
+	} finally {
+		if (monitor != null) monitor.done();
+	}
+
+	HashSet paths = collector.paths;
+	int length = paths.size();
+	String[] result = new String[length];
+	int count = 0;
+	for (Iterator iter = paths.iterator(); iter.hasNext();) {
+		result[count++] = (String) iter.next();
+	}
+	return result;
+}
+
+/**
+ * Find the set of candidate subtypes of a given type.
+ *
+ * The requestor is notified of super type references (with actual path of
+ * its occurrence) for all types which are potentially involved inside a particular
+ * hierarchy.
+ * The match locator is not used here to narrow down the results, the type hierarchy
+ * resolver is rather used to compute the whole hierarchy at once.
+ * @param type
+ * @param scope
+ * @param binariesFromIndexMatches
+ * @param pathRequestor
+ * @param waitingPolicy
+ * @param progressMonitor
+ */
+public static void searchAllPossibleSubTypes(
+	IType type,
+	IJavaSearchScope scope,
+	final Map binariesFromIndexMatches,
+	final IPathRequestor pathRequestor,
+	int waitingPolicy,	// WaitUntilReadyToSearch | ForceImmediateSearch | CancelIfNotReadyToSearch
+	final IProgressMonitor progressMonitor) {
+
+	/* embed constructs inside arrays so as to pass them to (inner) collector */
+	final Queue queue = new Queue();
+	final HashtableOfObject foundSuperNames = new HashtableOfObject(5);
+
+	IndexManager indexManager = JavaModelManager.getIndexManager();
+
+	/* use a special collector to collect paths and queue new subtype names */
+	IndexQueryRequestor searchRequestor = new IndexQueryRequestor() {
+		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+			SuperTypeReferencePattern record = (SuperTypeReferencePattern)indexRecord;
+			boolean isLocalOrAnonymous = record.enclosingTypeName == IIndexConstants.ONE_ZERO;
+			pathRequestor.acceptPath(documentPath, isLocalOrAnonymous);
+			char[] typeName = record.simpleName;
+			if (documentPath.toLowerCase().endsWith(SUFFIX_STRING_class)) {
+			    int suffix = documentPath.length()-SUFFIX_STRING_class.length();
+				HierarchyBinaryType binaryType = (HierarchyBinaryType)binariesFromIndexMatches.get(documentPath);
+				if (binaryType == null){
+					char[] enclosingTypeName = record.enclosingTypeName;
+					if (isLocalOrAnonymous) {
+						int lastSlash = documentPath.lastIndexOf('/');
+						int lastDollar = documentPath.lastIndexOf('$');
+						if (lastDollar == -1) {
+							// malformed local or anonymous type: it doesn't contain a $ in its name
+							// treat it as a top level type
+							enclosingTypeName = null;
+							typeName = documentPath.substring(lastSlash+1, suffix).toCharArray();
+						} else {
+							enclosingTypeName = documentPath.substring(lastSlash+1, lastDollar).toCharArray();
+							typeName = documentPath.substring(lastDollar+1, suffix).toCharArray();
+						}
+					}
+					binaryType = new HierarchyBinaryType(record.modifiers, record.pkgName, typeName, enclosingTypeName, record.typeParameterSignatures, record.classOrInterface);
+					binariesFromIndexMatches.put(documentPath, binaryType);
+				}
+				binaryType.recordSuperType(record.superSimpleName, record.superQualification, record.superClassOrInterface);
+			}
+			if (!isLocalOrAnonymous // local or anonymous types cannot have subtypes outside the cu that define them
+					&& !foundSuperNames.containsKey(typeName)){
+				foundSuperNames.put(typeName, typeName);
+				queue.add(typeName);
+			}
+			return true;
+		}
+	};
+
+	int superRefKind;
+	try {
+		superRefKind = type.isClass() ? SuperTypeReferencePattern.ONLY_SUPER_CLASSES : SuperTypeReferencePattern.ALL_SUPER_TYPES;
+	} catch (JavaModelException e) {
+		superRefKind = SuperTypeReferencePattern.ALL_SUPER_TYPES;
+	}
+	SuperTypeReferencePattern pattern =
+		new SuperTypeReferencePattern(null, null, superRefKind, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
+	MatchLocator.setFocus(pattern, type);
+	SubTypeSearchJob job = new SubTypeSearchJob(
+		pattern,
+		new JavaSearchParticipant(), // java search only
+		scope,
+		searchRequestor);
+
+	int ticks = 0;
+	queue.add(type.getElementName().toCharArray());
+	try {
+		while (queue.start <= queue.end) {
+			if (progressMonitor != null && progressMonitor.isCanceled()) return;
+
+			// all subclasses of OBJECT are actually all types
+			char[] currentTypeName = queue.retrieve();
+			if (CharOperation.equals(currentTypeName, IIndexConstants.OBJECT))
+				currentTypeName = null;
+
+			// search all index references to a given supertype
+			pattern.superSimpleName = currentTypeName;
+			indexManager.performConcurrentJob(job, waitingPolicy, progressMonitor == null ? null : new NullProgressMonitor() {
+				// don't report progress since this is too costly for deep hierarchies (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=34078 )
+				// just handle isCanceled() (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=179511 )
+				public void setCanceled(boolean value) {
+					progressMonitor.setCanceled(value);
+				}
+				public boolean isCanceled() {
+					return progressMonitor.isCanceled();
+				}
+				// and handle subTask(...) (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=34078 )
+				public void subTask(String name) {
+					progressMonitor.subTask(name);
+				}
+			});
+			if (progressMonitor != null && ++ticks <= MAXTICKS)
+				progressMonitor.worked(1);
+
+			// in case, we search all subtypes, no need to search further
+			if (currentTypeName == null) break;
+		}
+	} finally {
+		job.finished();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
new file mode 100644
index 0000000..a4aa822
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.Openable;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+
+public class RegionBasedHierarchyBuilder extends HierarchyBuilder {
+
+	public RegionBasedHierarchyBuilder(TypeHierarchy hierarchy)
+		throws JavaModelException {
+
+		super(hierarchy);
+	}
+
+public void build(boolean computeSubtypes) {
+
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	try {
+		// optimize access to zip files while building hierarchy
+		manager.cacheZipFiles(this);
+
+		if (this.hierarchy.focusType == null || computeSubtypes) {
+			IProgressMonitor typeInRegionMonitor =
+				this.hierarchy.progressMonitor == null ?
+					null :
+					new SubProgressMonitor(this.hierarchy.progressMonitor, 30);
+			HashMap allOpenablesInRegion = determineOpenablesInRegion(typeInRegionMonitor);
+			this.hierarchy.initialize(allOpenablesInRegion.size());
+			IProgressMonitor buildMonitor =
+				this.hierarchy.progressMonitor == null ?
+					null :
+					new SubProgressMonitor(this.hierarchy.progressMonitor, 70);
+			createTypeHierarchyBasedOnRegion(allOpenablesInRegion, buildMonitor);
+			((RegionBasedTypeHierarchy)this.hierarchy).pruneDeadBranches();
+		} else {
+			this.hierarchy.initialize(1);
+			buildSupertypes();
+		}
+	} finally {
+		manager.flushZipFiles(this);
+	}
+}
+/**
+ * Configure this type hierarchy that is based on a region.
+ */
+private void createTypeHierarchyBasedOnRegion(HashMap allOpenablesInRegion, IProgressMonitor monitor) {
+
+	try {
+		int size = allOpenablesInRegion.size();
+		if (monitor != null) monitor.beginTask("", size * 2/* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
+		this.infoToHandle = new HashMap(size);
+		Iterator javaProjects = allOpenablesInRegion.entrySet().iterator();
+		while (javaProjects.hasNext()) {
+			Map.Entry entry = (Map.Entry) javaProjects.next();
+			JavaProject project = (JavaProject) entry.getKey();
+			ArrayList allOpenables = (ArrayList) entry.getValue();
+			Openable[] openables = new Openable[allOpenables.size()];
+			allOpenables.toArray(openables);
+
+			try {
+				// resolve
+				SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.hierarchy.workingCopies);
+				this.nameLookup = searchableEnvironment.nameLookup;
+				this.hierarchyResolver.resolve(openables, null, monitor);
+			} catch (JavaModelException e) {
+				// project doesn't exit: ignore
+			}
+		}
+	} finally {
+		if (monitor != null) monitor.done();
+	}
+}
+
+	/**
+	 * Returns all of the openables defined in the region of this type hierarchy.
+	 * Returns a map from IJavaProject to ArrayList of Openable
+	 */
+	private HashMap determineOpenablesInRegion(IProgressMonitor monitor) {
+
+		try {
+			HashMap allOpenables = new HashMap();
+			IJavaElement[] roots =
+				((RegionBasedTypeHierarchy) this.hierarchy).region.getElements();
+			int length = roots.length;
+			if (monitor != null) monitor.beginTask("", length); //$NON-NLS-1$
+			for (int i = 0; i <length; i++) {
+				IJavaElement root = roots[i];
+				IJavaProject javaProject = root.getJavaProject();
+				ArrayList openables = (ArrayList) allOpenables.get(javaProject);
+				if (openables == null) {
+					openables = new ArrayList();
+					allOpenables.put(javaProject, openables);
+				}
+				switch (root.getElementType()) {
+					case IJavaElement.JAVA_PROJECT :
+						injectAllOpenablesForJavaProject((IJavaProject) root, openables);
+						break;
+					case IJavaElement.PACKAGE_FRAGMENT_ROOT :
+						injectAllOpenablesForPackageFragmentRoot((IPackageFragmentRoot) root, openables);
+						break;
+					case IJavaElement.PACKAGE_FRAGMENT :
+						injectAllOpenablesForPackageFragment((IPackageFragment) root, openables);
+						break;
+					case IJavaElement.CLASS_FILE :
+					case IJavaElement.COMPILATION_UNIT :
+						openables.add(root);
+						break;
+					case IJavaElement.TYPE :
+						IType type = (IType)root;
+						if (type.isBinary()) {
+							openables.add(type.getClassFile());
+						} else {
+							openables.add(type.getCompilationUnit());
+						}
+						break;
+					default :
+						break;
+				}
+				worked(monitor, 1);
+			}
+			return allOpenables;
+		} finally {
+			if (monitor != null) monitor.done();
+		}
+	}
+
+	/**
+	 * Adds all of the openables defined within this java project to the
+	 * list.
+	 */
+	private void injectAllOpenablesForJavaProject(
+		IJavaProject project,
+		ArrayList openables) {
+		try {
+			IPackageFragmentRoot[] devPathRoots =
+				((JavaProject) project).getPackageFragmentRoots();
+			if (devPathRoots == null) {
+				return;
+			}
+			for (int j = 0; j < devPathRoots.length; j++) {
+				IPackageFragmentRoot root = devPathRoots[j];
+				injectAllOpenablesForPackageFragmentRoot(root, openables);
+			}
+		} catch (JavaModelException e) {
+			// ignore
+		}
+	}
+
+	/**
+	 * Adds all of the openables defined within this package fragment to the
+	 * list.
+	 */
+	private void injectAllOpenablesForPackageFragment(
+		IPackageFragment packFrag,
+		ArrayList openables) {
+
+		try {
+			IPackageFragmentRoot root = (IPackageFragmentRoot) packFrag.getParent();
+			int kind = root.getKind();
+			if (kind != 0) {
+				boolean isSourcePackageFragment = (kind == IPackageFragmentRoot.K_SOURCE);
+				if (isSourcePackageFragment) {
+					ICompilationUnit[] cus = packFrag.getCompilationUnits();
+					for (int i = 0, length = cus.length; i < length; i++) {
+						openables.add(cus[i]);
+					}
+				} else {
+					IClassFile[] classFiles = packFrag.getClassFiles();
+					for (int i = 0, length = classFiles.length; i < length; i++) {
+						openables.add(classFiles[i]);
+					}
+				}
+			}
+		} catch (JavaModelException e) {
+			// ignore
+		}
+	}
+
+	/**
+	 * Adds all of the openables defined within this package fragment root to the
+	 * list.
+	 */
+	private void injectAllOpenablesForPackageFragmentRoot(
+		IPackageFragmentRoot root,
+		ArrayList openables) {
+		try {
+			IJavaElement[] packFrags = root.getChildren();
+			for (int k = 0; k < packFrags.length; k++) {
+				IPackageFragment packFrag = (IPackageFragment) packFrags[k];
+				injectAllOpenablesForPackageFragment(packFrag, openables);
+			}
+		} catch (JavaModelException e) {
+			return;
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
new file mode 100644
index 0000000..dc9b901
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.Openable;
+import org.eclipse.jdt.internal.core.Region;
+import org.eclipse.jdt.internal.core.TypeVector;
+
+public class RegionBasedTypeHierarchy extends TypeHierarchy {
+	/**
+	 * The region of types for which to build the hierarchy
+	 */
+	protected IRegion region;
+
+/**
+ * Creates a TypeHierarchy on the types in the specified region,
+ * considering first the given working copies,
+ * using the projects in the given region for a name lookup context. If a specific
+ * type is also specified, the type hierarchy is pruned to only
+ * contain the branch including the specified type.
+ */
+public RegionBasedTypeHierarchy(IRegion region, ICompilationUnit[] workingCopies, IType type, boolean computeSubtypes) {
+	super(type, workingCopies, (IJavaSearchScope)null, computeSubtypes);
+
+	Region newRegion = new Region() {
+		public void add(IJavaElement element) {
+			if (!contains(element)) {
+				//"new" element added to region
+				removeAllChildren(element);
+				this.rootElements.add(element);
+				if (element.getElementType() == IJavaElement.JAVA_PROJECT) {
+					// add jar roots as well so that jars don't rely on their parent to know
+					// if they are contained in the region
+					// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=146615)
+					try {
+						IPackageFragmentRoot[] roots = ((IJavaProject) element).getPackageFragmentRoots();
+						for (int i = 0, length = roots.length; i < length; i++) {
+							if (roots[i].isArchive() && !this.rootElements.contains(roots[i]))
+								this.rootElements.add(roots[i]);
+						}
+					} catch (JavaModelException e) {
+						// project doesn't exist
+					}
+				}
+				this.rootElements.trimToSize();
+			}
+		}
+	};
+	IJavaElement[] elements = region.getElements();
+	for (int i = 0, length = elements.length; i < length; i++) {
+		newRegion.add(elements[i]);
+
+	}
+	this.region = newRegion;
+	if (elements.length > 0)
+		this.project = elements[0].getJavaProject();
+}
+/*
+ * @see TypeHierarchy#initializeRegions
+ */
+protected void initializeRegions() {
+	super.initializeRegions();
+	IJavaElement[] roots = this.region.getElements();
+	for (int i = 0; i < roots.length; i++) {
+		IJavaElement root = roots[i];
+		if (root instanceof IOpenable) {
+			this.files.put(root, new ArrayList());
+		} else {
+			Openable o = (Openable) ((JavaElement) root).getOpenableParent();
+			if (o != null) {
+				this.files.put(o, new ArrayList());
+			}
+		}
+		checkCanceled();
+	}
+}
+/**
+ * Compute this type hierarchy.
+ */
+protected void compute() throws JavaModelException, CoreException {
+	HierarchyBuilder builder = new RegionBasedHierarchyBuilder(this);
+	builder.build(this.computeSubtypes);
+}
+protected boolean isAffectedByOpenable(IJavaElementDelta delta, IJavaElement element, int eventType) {
+	// change to working copy
+	if (element instanceof CompilationUnit && ((CompilationUnit)element).isWorkingCopy()) {
+		return super.isAffectedByOpenable(delta, element, eventType);
+	}
+
+	// if no focus, hierarchy is affected if the element is part of the region
+	if (this.focusType == null) {
+		return this.region.contains(element);
+	} else {
+		return super.isAffectedByOpenable(delta, element, eventType);
+	}
+}
+/**
+ * Returns the java project this hierarchy was created in.
+ */
+public IJavaProject javaProject() {
+	return this.project;
+}
+public void pruneDeadBranches() {
+	pruneDeadBranches(getRootClasses());
+	pruneDeadBranches(getRootInterfaces());
+}
+/*
+ * Returns whether all subtypes of the given type have been pruned.
+ */
+private boolean pruneDeadBranches(IType type) {
+	TypeVector subtypes = (TypeVector)this.typeToSubtypes.get(type);
+	if (subtypes == null) return true;
+	pruneDeadBranches(subtypes.copy().elements());
+	subtypes = (TypeVector)this.typeToSubtypes.get(type);
+	return (subtypes == null || subtypes.size == 0);
+}
+private void pruneDeadBranches(IType[] types) {
+	for (int i = 0, length = types.length; i < length; i++) {
+		IType type = types[i];
+		if (pruneDeadBranches(type) && !this.region.contains(type)) {
+			removeType(type);
+		}
+	}
+}
+/**
+ * Removes all the subtypes of the given type from the type hierarchy,
+ * removes its superclass entry and removes the references from its super types.
+ */
+protected void removeType(IType type) {
+	IType[] subtypes = getSubtypes(type);
+	this.typeToSubtypes.remove(type);
+	if (subtypes != null) {
+		for (int i= 0; i < subtypes.length; i++) {
+			removeType(subtypes[i]);
+		}
+	}
+	IType superclass = (IType)this.classToSuperclass.remove(type);
+	if (superclass != null) {
+		TypeVector types = (TypeVector)this.typeToSubtypes.get(superclass);
+		if (types != null) types.remove(type);
+	}
+	IType[] superinterfaces = (IType[])this.typeToSuperInterfaces.remove(type);
+	if (superinterfaces != null) {
+		for (int i = 0, length = superinterfaces.length; i < length; i++) {
+			IType superinterface = superinterfaces[i];
+			TypeVector types = (TypeVector)this.typeToSubtypes.get(superinterface);
+			if (types != null) types.remove(type);
+		}
+	}
+	this.interfaces.remove(type);
+}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
new file mode 100644
index 0000000..0cafa95
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
@@ -0,0 +1,1571 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.hierarchy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * @see ITypeHierarchy
+ */
+public class TypeHierarchy implements ITypeHierarchy, IElementChangedListener {
+
+	public static boolean DEBUG = false;
+
+	static final byte VERSION = 0x0000;
+	// SEPARATOR
+	static final byte SEPARATOR1 = '\n';
+	static final byte SEPARATOR2 = ',';
+	static final byte SEPARATOR3 = '>';
+	static final byte SEPARATOR4 = '\r';
+	// general info
+	static final byte COMPUTE_SUBTYPES = 0x0001;
+
+	// type info
+	static final byte CLASS = 0x0000;
+	static final byte INTERFACE = 0x0001;
+	static final byte COMPUTED_FOR = 0x0002;
+	static final byte ROOT = 0x0004;
+
+	// cst
+	static final byte[] NO_FLAGS = new byte[]{};
+	static final int SIZE = 10;
+
+	/**
+	 * The Java Project in which the hierarchy is being built - this
+	 * provides the context for determining a classpath and namelookup rules.
+	 * Possibly null.
+	 */
+	protected IJavaProject project;
+	/**
+	 * The type the hierarchy was specifically computed for,
+	 * possibly null.
+	 */
+	protected IType focusType;
+
+	/*
+	 * The working copies that take precedence over original compilation units
+	 */
+	protected ICompilationUnit[] workingCopies;
+
+	protected Map classToSuperclass;
+	protected Map typeToSuperInterfaces;
+	protected Map typeToSubtypes;
+	protected Map typeFlags;
+	protected TypeVector rootClasses = new TypeVector();
+	protected ArrayList interfaces = new ArrayList(10);
+	public ArrayList missingTypes = new ArrayList(4);
+
+	protected static final IType[] NO_TYPE = new IType[0];
+
+	/**
+	 * The progress monitor to report work completed too.
+	 */
+	protected IProgressMonitor progressMonitor = null;
+
+	/**
+	 * Change listeners - null if no one is listening.
+	 */
+	protected ArrayList changeListeners = null;
+
+	/*
+	 * A map from Openables to ArrayLists of ITypes
+	 */
+	public Map files = null;
+
+	/**
+	 * A region describing the packages considered by this
+	 * hierarchy. Null if not activated.
+	 */
+	protected Region packageRegion = null;
+
+	/**
+	 * A region describing the projects considered by this
+	 * hierarchy. Null if not activated.
+	 */
+	protected Region projectRegion = null;
+
+	/**
+	 * Whether this hierarchy should contains subtypes.
+	 */
+	protected boolean computeSubtypes;
+
+	/**
+	 * The scope this hierarchy should restrain itsef in.
+	 */
+	IJavaSearchScope scope;
+
+	/*
+	 * Whether this hierarchy needs refresh
+	 */
+	public boolean needsRefresh = true;
+
+	/*
+	 * Collects changes to types
+	 */
+	protected ChangeCollector changeCollector;
+
+/**
+ * Creates an empty TypeHierarchy
+ */
+public TypeHierarchy() {
+	// Creates an empty TypeHierarchy
+}
+/**
+ * Creates a TypeHierarchy on the given type.
+ */
+public TypeHierarchy(IType type, ICompilationUnit[] workingCopies, IJavaProject project, boolean computeSubtypes) {
+	this(type, workingCopies, SearchEngine.createJavaSearchScope(new IJavaElement[] {project}), computeSubtypes);
+	this.project = project;
+}
+/**
+ * Creates a TypeHierarchy on the given type.
+ */
+public TypeHierarchy(IType type, ICompilationUnit[] workingCopies, IJavaSearchScope scope, boolean computeSubtypes) {
+	this.focusType = type == null ? null : (IType) ((JavaElement) type).unresolved(); // unsure the focus type is unresolved (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=92357)
+	this.workingCopies = workingCopies;
+	this.computeSubtypes = computeSubtypes;
+	this.scope = scope;
+}
+/**
+ * Initializes the file, package and project regions
+ */
+protected void initializeRegions() {
+
+	IType[] allTypes = getAllTypes();
+	for (int i = 0; i < allTypes.length; i++) {
+		IType type = allTypes[i];
+		Openable o = (Openable) ((JavaElement) type).getOpenableParent();
+		if (o != null) {
+			ArrayList types = (ArrayList)this.files.get(o);
+			if (types == null) {
+				types = new ArrayList();
+				this.files.put(o, types);
+			}
+			types.add(type);
+		}
+		IPackageFragment pkg = type.getPackageFragment();
+		this.packageRegion.add(pkg);
+		IJavaProject declaringProject = type.getJavaProject();
+		if (declaringProject != null) {
+			this.projectRegion.add(declaringProject);
+		}
+		checkCanceled();
+	}
+}
+/**
+ * Adds all of the elements in the collection to the list if the
+ * element is not already in the list.
+ */
+private void addAllCheckingDuplicates(ArrayList list, IType[] collection) {
+	for (int i = 0; i < collection.length; i++) {
+		IType element = collection[i];
+		if (!list.contains(element)) {
+			list.add(element);
+		}
+	}
+}
+/**
+ * Adds the type to the collection of interfaces.
+ */
+protected void addInterface(IType type) {
+	this.interfaces.add(type);
+}
+/**
+ * Adds the type to the collection of root classes
+ * if the classes is not already present in the collection.
+ */
+protected void addRootClass(IType type) {
+	if (this.rootClasses.contains(type)) return;
+	this.rootClasses.add(type);
+}
+/**
+ * Adds the given subtype to the type.
+ */
+protected void addSubtype(IType type, IType subtype) {
+	TypeVector subtypes = (TypeVector)this.typeToSubtypes.get(type);
+	if (subtypes == null) {
+		subtypes = new TypeVector();
+		this.typeToSubtypes.put(type, subtypes);
+	}
+	if (!subtypes.contains(subtype)) {
+		subtypes.add(subtype);
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public synchronized void addTypeHierarchyChangedListener(ITypeHierarchyChangedListener listener) {
+	ArrayList listeners = this.changeListeners;
+	if (listeners == null) {
+		this.changeListeners = listeners = new ArrayList();
+	}
+
+	// register with JavaCore to get Java element delta on first listener added
+	if (listeners.size() == 0) {
+		JavaCore.addElementChangedListener(this);
+	}
+
+	// add listener only if it is not already present
+	if (listeners.indexOf(listener) == -1) {
+		listeners.add(listener);
+	}
+}
+private static Integer bytesToFlags(byte[] bytes){
+	if(bytes != null && bytes.length > 0) {
+		return new Integer(new String(bytes));
+	} else {
+		return null;
+	}
+}
+/**
+ * cacheFlags.
+ */
+public void cacheFlags(IType type, int flags) {
+	this.typeFlags.put(type, new Integer(flags));
+}
+/**
+ * Caches the handle of the superclass for the specified type.
+ * As a side effect cache this type as a subtype of the superclass.
+ */
+protected void cacheSuperclass(IType type, IType superclass) {
+	if (superclass != null) {
+		this.classToSuperclass.put(type, superclass);
+		addSubtype(superclass, type);
+	}
+}
+/**
+ * Caches all of the superinterfaces that are specified for the
+ * type.
+ */
+protected void cacheSuperInterfaces(IType type, IType[] superinterfaces) {
+	this.typeToSuperInterfaces.put(type, superinterfaces);
+	for (int i = 0; i < superinterfaces.length; i++) {
+		IType superinterface = superinterfaces[i];
+		if (superinterface != null) {
+			addSubtype(superinterface, type);
+		}
+	}
+}
+/**
+ * Checks with the progress monitor to see whether the creation of the type hierarchy
+ * should be canceled. Should be regularly called
+ * so that the user can cancel.
+ *
+ * @exception OperationCanceledException if cancelling the operation has been requested
+ * @see IProgressMonitor#isCanceled
+ */
+protected void checkCanceled() {
+	if (this.progressMonitor != null && this.progressMonitor.isCanceled()) {
+		throw new OperationCanceledException();
+	}
+}
+/**
+ * Compute this type hierarchy.
+ */
+protected void compute() throws JavaModelException, CoreException {
+	if (this.focusType != null) {
+		HierarchyBuilder builder =
+			new IndexBasedHierarchyBuilder(
+				this,
+				this.scope);
+		builder.build(this.computeSubtypes);
+	} // else a RegionBasedTypeHierarchy should be used
+}
+/**
+ * @see ITypeHierarchy
+ */
+public boolean contains(IType type) {
+	// classes
+	if (this.classToSuperclass.get(type) != null) {
+		return true;
+	}
+
+	// root classes
+	if (this.rootClasses.contains(type)) return true;
+
+	// interfaces
+	if (this.interfaces.contains(type)) return true;
+
+	return false;
+}
+/**
+ * Determines if the change affects this hierarchy, and fires
+ * change notification if required.
+ */
+public void elementChanged(ElementChangedEvent event) {
+	// type hierarchy change has already been fired
+	if (this.needsRefresh) return;
+
+	if (isAffected(event.getDelta(), event.getType())) {
+		this.needsRefresh = true;
+		fireChange();
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public boolean exists() {
+	if (!this.needsRefresh) return true;
+
+	return (this.focusType == null || this.focusType.exists()) && javaProject().exists();
+}
+/**
+ * Notifies listeners that this hierarchy has changed and needs
+ * refreshing. Note that listeners can be removed as we iterate
+ * through the list.
+ */
+public void fireChange() {
+	ArrayList listeners = getClonedChangeListeners(); // clone so that a listener cannot have a side-effect on this list when being notified
+	if (listeners == null) {
+		return;
+	}
+	if (DEBUG) {
+		System.out.println("FIRING hierarchy change ["+Thread.currentThread()+"]"); //$NON-NLS-1$ //$NON-NLS-2$
+		if (this.focusType != null) {
+			System.out.println("    for hierarchy focused on " + ((JavaElement)this.focusType).toStringWithAncestors()); //$NON-NLS-1$
+		}
+	}
+	
+	for (int i= 0; i < listeners.size(); i++) {
+		final ITypeHierarchyChangedListener listener= (ITypeHierarchyChangedListener)listeners.get(i);
+		SafeRunner.run(new ISafeRunnable() {
+			public void handleException(Throwable exception) {
+				Util.log(exception, "Exception occurred in listener of Type hierarchy change notification"); //$NON-NLS-1$
+			}
+			public void run() throws Exception {
+				listener.typeHierarchyChanged(TypeHierarchy.this);
+			}
+		});
+	}
+}
+private synchronized ArrayList getClonedChangeListeners() {
+	ArrayList listeners = this.changeListeners;
+	if (listeners == null) {
+		return null;
+	}
+	return (ArrayList) listeners.clone();
+}
+private static byte[] flagsToBytes(Integer flags){
+	if(flags != null) {
+		return flags.toString().getBytes();
+	} else {
+		return NO_FLAGS;
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllClasses() {
+
+	TypeVector classes = this.rootClasses.copy();
+	for (Iterator iter = this.classToSuperclass.keySet().iterator(); iter.hasNext();){
+		classes.add((IType)iter.next());
+	}
+	return classes.elements();
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllInterfaces() {
+	IType[] collection= new IType[this.interfaces.size()];
+	this.interfaces.toArray(collection);
+	return collection;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[]  getAllSubtypes(IType type) {
+	return getAllSubtypesForType(type);
+}
+/**
+ * @see #getAllSubtypes(IType)
+ */
+private IType[] getAllSubtypesForType(IType type) {
+	ArrayList subTypes = new ArrayList();
+	getAllSubtypesForType0(type, subTypes);
+	IType[] subClasses = new IType[subTypes.size()];
+	subTypes.toArray(subClasses);
+	return subClasses;
+}
+/**
+ */
+private void getAllSubtypesForType0(IType type, ArrayList subs) {
+	IType[] subTypes = getSubtypesForType(type);
+	if (subTypes.length != 0) {
+		for (int i = 0; i < subTypes.length; i++) {
+			IType subType = subTypes[i];
+			subs.add(subType);
+			getAllSubtypesForType0(subType, subs);
+		}
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllSuperclasses(IType type) {
+	IType superclass = getSuperclass(type);
+	TypeVector supers = new TypeVector();
+	while (superclass != null) {
+		supers.add(superclass);
+		superclass = getSuperclass(superclass);
+	}
+	return supers.elements();
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllSuperInterfaces(IType type) {
+	ArrayList supers = getAllSuperInterfaces0(type, null);
+	if (supers == null)
+		return NO_TYPE;
+	IType[] superinterfaces = new IType[supers.size()];
+	supers.toArray(superinterfaces);
+	return superinterfaces;
+}
+private ArrayList getAllSuperInterfaces0(IType type, ArrayList supers) {
+	IType[] superinterfaces = (IType[]) this.typeToSuperInterfaces.get(type);
+	if (superinterfaces == null) // type is not part of the hierarchy
+		return supers;
+	if (superinterfaces.length != 0) {
+		if (supers == null)
+			supers = new ArrayList();
+		addAllCheckingDuplicates(supers, superinterfaces);
+		for (int i = 0; i < superinterfaces.length; i++) {
+			supers = getAllSuperInterfaces0(superinterfaces[i], supers);
+		}
+	}
+	IType superclass = (IType) this.classToSuperclass.get(type);
+	if (superclass != null) {
+		supers = getAllSuperInterfaces0(superclass, supers);
+	}
+	return supers;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllSupertypes(IType type) {
+	ArrayList supers = getAllSupertypes0(type, null);
+	if (supers == null)
+		return NO_TYPE;
+	IType[] supertypes = new IType[supers.size()];
+	supers.toArray(supertypes);
+	return supertypes;
+}
+private ArrayList getAllSupertypes0(IType type, ArrayList supers) {
+	IType[] superinterfaces = (IType[]) this.typeToSuperInterfaces.get(type);
+	if (superinterfaces == null) // type is not part of the hierarchy
+		return supers;
+	if (superinterfaces.length != 0) {
+		if (supers == null)
+			supers = new ArrayList();
+		addAllCheckingDuplicates(supers, superinterfaces);
+		for (int i = 0; i < superinterfaces.length; i++) {
+			supers = getAllSuperInterfaces0(superinterfaces[i], supers);
+		}
+	}
+	IType superclass = (IType) this.classToSuperclass.get(type);
+	if (superclass != null) {
+		if (supers == null)
+			supers = new ArrayList();
+		supers.add(superclass);
+		supers = getAllSupertypes0(superclass, supers);
+	}
+	return supers;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getAllTypes() {
+	IType[] classes = getAllClasses();
+	int classesLength = classes.length;
+	IType[] allInterfaces = getAllInterfaces();
+	int interfacesLength = allInterfaces.length;
+	IType[] all = new IType[classesLength + interfacesLength];
+	System.arraycopy(classes, 0, all, 0, classesLength);
+	System.arraycopy(allInterfaces, 0, all, classesLength, interfacesLength);
+	return all;
+}
+
+/**
+ * @see ITypeHierarchy#getCachedFlags(IType)
+ */
+public int getCachedFlags(IType type) {
+	Integer flagObject = (Integer) this.typeFlags.get(type);
+	if (flagObject != null){
+		return flagObject.intValue();
+	}
+	return -1;
+}
+
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getExtendingInterfaces(IType type) {
+	if (!isInterface(type)) return NO_TYPE;
+	return getExtendingInterfaces0(type);
+}
+/**
+ * Assumes that the type is an interface
+ * @see #getExtendingInterfaces
+ */
+private IType[] getExtendingInterfaces0(IType extendedInterface) {
+	Iterator iter = this.typeToSuperInterfaces.entrySet().iterator();
+	ArrayList interfaceList = new ArrayList();
+	while (iter.hasNext()) {
+		Map.Entry entry = (Map.Entry) iter.next();
+		IType type = (IType) entry.getKey();
+		if (!isInterface(type)) {
+			continue;
+		}
+		IType[] superInterfaces = (IType[]) entry.getValue();
+		if (superInterfaces != null) {
+			for (int i = 0; i < superInterfaces.length; i++) {
+				IType superInterface = superInterfaces[i];
+				if (superInterface.equals(extendedInterface)) {
+					interfaceList.add(type);
+				}
+			}
+		}
+	}
+	IType[] extendingInterfaces = new IType[interfaceList.size()];
+	interfaceList.toArray(extendingInterfaces);
+	return extendingInterfaces;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getImplementingClasses(IType type) {
+	if (!isInterface(type)) {
+		return NO_TYPE;
+	}
+	return getImplementingClasses0(type);
+}
+/**
+ * Assumes that the type is an interface
+ * @see #getImplementingClasses
+ */
+private IType[] getImplementingClasses0(IType interfce) {
+
+	Iterator iter = this.typeToSuperInterfaces.entrySet().iterator();
+	ArrayList iMenters = new ArrayList();
+	while (iter.hasNext()) {
+		Map.Entry entry = (Map.Entry) iter.next();
+		IType type = (IType) entry.getKey();
+		if (isInterface(type)) {
+			continue;
+		}
+		IType[] types = (IType[]) entry.getValue();
+		for (int i = 0; i < types.length; i++) {
+			IType iFace = types[i];
+			if (iFace.equals(interfce)) {
+				iMenters.add(type);
+			}
+		}
+	}
+	IType[] implementers = new IType[iMenters.size()];
+	iMenters.toArray(implementers);
+	return implementers;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getRootClasses() {
+	return this.rootClasses.elements();
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getRootInterfaces() {
+	IType[] allInterfaces = getAllInterfaces();
+	IType[] roots = new IType[allInterfaces.length];
+	int rootNumber = 0;
+	for (int i = 0; i < allInterfaces.length; i++) {
+		IType[] superInterfaces = getSuperInterfaces(allInterfaces[i]);
+		if (superInterfaces == null || superInterfaces.length == 0) {
+			roots[rootNumber++] = allInterfaces[i];
+		}
+	}
+	IType[] result = new IType[rootNumber];
+	if (result.length > 0) {
+		System.arraycopy(roots, 0, result, 0, rootNumber);
+	}
+	return result;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getSubclasses(IType type) {
+	if (isInterface(type)) {
+		return NO_TYPE;
+	}
+	TypeVector vector = (TypeVector)this.typeToSubtypes.get(type);
+	if (vector == null)
+		return NO_TYPE;
+	else
+		return vector.elements();
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getSubtypes(IType type) {
+	return getSubtypesForType(type);
+}
+/**
+ * Returns an array of subtypes for the given type - will never return null.
+ */
+private IType[] getSubtypesForType(IType type) {
+	TypeVector vector = (TypeVector)this.typeToSubtypes.get(type);
+	if (vector == null)
+		return NO_TYPE;
+	else
+		return vector.elements();
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType getSuperclass(IType type) {
+	if (isInterface(type)) {
+		return null;
+	}
+	return (IType) this.classToSuperclass.get(type);
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getSuperInterfaces(IType type) {
+	IType[] types = (IType[]) this.typeToSuperInterfaces.get(type);
+	if (types == null) {
+		return NO_TYPE;
+	}
+	return types;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType[] getSupertypes(IType type) {
+	IType superclass = getSuperclass(type);
+	if (superclass == null) {
+		return getSuperInterfaces(type);
+	} else {
+		TypeVector superTypes = new TypeVector(getSuperInterfaces(type));
+		superTypes.add(superclass);
+		return superTypes.elements();
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public IType getType() {
+	return this.focusType;
+}
+/**
+ * Adds the new elements to a new array that contains all of the elements of the old array.
+ * Returns the new array.
+ */
+protected IType[] growAndAddToArray(IType[] array, IType[] additions) {
+	if (array == null || array.length == 0) {
+		return additions;
+	}
+	IType[] old = array;
+	array = new IType[old.length + additions.length];
+	System.arraycopy(old, 0, array, 0, old.length);
+	System.arraycopy(additions, 0, array, old.length, additions.length);
+	return array;
+}
+/**
+ * Adds the new element to a new array that contains all of the elements of the old array.
+ * Returns the new array.
+ */
+protected IType[] growAndAddToArray(IType[] array, IType addition) {
+	if (array == null || array.length == 0) {
+		return new IType[] {addition};
+	}
+	IType[] old = array;
+	array = new IType[old.length + 1];
+	System.arraycopy(old, 0, array, 0, old.length);
+	array[old.length] = addition;
+	return array;
+}
+/*
+ * Whether fine-grained deltas where collected and affects this hierarchy.
+ */
+public boolean hasFineGrainChanges() {
+    ChangeCollector collector = this.changeCollector;
+	return collector != null && collector.needsRefresh();
+}
+/**
+ * Returns whether this type or one of the subtypes in this hierarchy has the
+ * same simple name as the given name.
+ */
+private boolean hasSubtypeNamed(String name) {
+	int idx = -1;
+	String rawName = (idx = name.indexOf('<')) > -1 ? name.substring(0, idx) : name;
+	String simpleName = (idx = rawName.lastIndexOf('.')) > -1 ? rawName.substring(idx + 1) : rawName;
+
+	if (this.focusType != null && this.focusType.getElementName().equals(simpleName)) {
+		return true;
+	}
+	IType[] types = this.focusType == null ? getAllTypes() : getAllSubtypes(this.focusType);
+	for (int i = 0, length = types.length; i < length; i++) {
+		if (types[i].getElementName().equals(simpleName)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns whether one of the types in this hierarchy has the given simple name.
+ */
+private boolean hasTypeNamed(String simpleName) {
+	IType[] types = getAllTypes();
+	for (int i = 0, length = types.length; i < length; i++) {
+		if (types[i].getElementName().equals(simpleName)) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Returns whether the simple name of the given type or one of its supertypes is
+ * the simple name of one of the types in this hierarchy.
+ */
+boolean includesTypeOrSupertype(IType type) {
+	try {
+		// check type
+		if (hasTypeNamed(type.getElementName())) return true;
+
+		// check superclass
+		String superclassName = type.getSuperclassName();
+		if (superclassName != null) {
+			int lastSeparator = superclassName.lastIndexOf('.');
+			String simpleName = superclassName.substring(lastSeparator+1);
+			if (hasTypeNamed(simpleName)) return true;
+		}
+
+		// check superinterfaces
+		String[] superinterfaceNames = type.getSuperInterfaceNames();
+		if (superinterfaceNames != null) {
+			for (int i = 0, length = superinterfaceNames.length; i < length; i++) {
+				String superinterfaceName = superinterfaceNames[i];
+				int lastSeparator = superinterfaceName.lastIndexOf('.');
+				String simpleName = superinterfaceName.substring(lastSeparator+1);
+				if (hasTypeNamed(simpleName)) return true;
+			}
+		}
+	} catch (JavaModelException e) {
+		// ignore
+	}
+	return false;
+}
+/**
+ * Initializes this hierarchy's internal tables with the given size.
+ */
+protected void initialize(int size) {
+	if (size < 10) {
+		size = 10;
+	}
+	int smallSize = (size / 2);
+	this.classToSuperclass = new HashMap(size);
+	this.interfaces = new ArrayList(smallSize);
+	this.missingTypes = new ArrayList(smallSize);
+	this.rootClasses = new TypeVector();
+	this.typeToSubtypes = new HashMap(smallSize);
+	this.typeToSuperInterfaces = new HashMap(smallSize);
+	this.typeFlags = new HashMap(smallSize);
+
+	this.projectRegion = new Region();
+	this.packageRegion = new Region();
+	this.files = new HashMap(5);
+}
+/**
+ * Returns true if the given delta could change this type hierarchy
+ * @param eventType TODO
+ */
+public synchronized boolean isAffected(IJavaElementDelta delta, int eventType) {
+	IJavaElement element= delta.getElement();
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			return isAffectedByJavaModel(delta, element, eventType);
+		case IJavaElement.JAVA_PROJECT:
+			return isAffectedByJavaProject(delta, element, eventType);
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			return isAffectedByPackageFragmentRoot(delta, element, eventType);
+		case IJavaElement.PACKAGE_FRAGMENT:
+			return isAffectedByPackageFragment(delta, (PackageFragment) element, eventType);
+		case IJavaElement.CLASS_FILE:
+		case IJavaElement.COMPILATION_UNIT:
+			return isAffectedByOpenable(delta, element, eventType);
+	}
+	return false;
+}
+/**
+ * Returns true if any of the children of a project, package
+ * fragment root, or package fragment have changed in a way that
+ * affects this type hierarchy.
+ * @param eventType TODO
+ */
+private boolean isAffectedByChildren(IJavaElementDelta delta, int eventType) {
+	if ((delta.getFlags() & IJavaElementDelta.F_CHILDREN) > 0) {
+		IJavaElementDelta[] children= delta.getAffectedChildren();
+		for (int i= 0; i < children.length; i++) {
+			if (isAffected(children[i], eventType)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+/**
+ * Returns true if the given java model delta could affect this type hierarchy
+ * @param eventType TODO
+ */
+private boolean isAffectedByJavaModel(IJavaElementDelta delta, IJavaElement element, int eventType) {
+	switch (delta.getKind()) {
+		case IJavaElementDelta.ADDED :
+		case IJavaElementDelta.REMOVED :
+			return element.equals(javaProject().getJavaModel());
+		case IJavaElementDelta.CHANGED :
+			return isAffectedByChildren(delta, eventType);
+	}
+	return false;
+}
+/**
+ * Returns true if the given java project delta could affect this type hierarchy
+ * @param eventType TODO
+ */
+private boolean isAffectedByJavaProject(IJavaElementDelta delta, IJavaElement element, int eventType) {
+    int kind = delta.getKind();
+    int flags = delta.getFlags();
+    if ((flags & IJavaElementDelta.F_OPENED) != 0) {
+        kind = IJavaElementDelta.ADDED; // affected in the same way
+    }
+    if ((flags & IJavaElementDelta.F_CLOSED) != 0) {
+        kind = IJavaElementDelta.REMOVED; // affected in the same way
+    }
+	switch (kind) {
+		case IJavaElementDelta.ADDED :
+			try {
+				// if the added project is on the classpath, then the hierarchy has changed
+				IClasspathEntry[] classpath = ((JavaProject)javaProject()).getExpandedClasspath();
+				for (int i = 0; i < classpath.length; i++) {
+					if (classpath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT
+							&& classpath[i].getPath().equals(element.getPath())) {
+						return true;
+					}
+				}
+				if (this.focusType != null) {
+					// if the hierarchy's project is on the added project classpath, then the hierarchy has changed
+					classpath = ((JavaProject)element).getExpandedClasspath();
+					IPath hierarchyProject = javaProject().getPath();
+					for (int i = 0; i < classpath.length; i++) {
+						if (classpath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT
+								&& classpath[i].getPath().equals(hierarchyProject)) {
+							return true;
+						}
+					}
+				}
+				return false;
+			} catch (JavaModelException e) {
+				return false;
+			}
+		case IJavaElementDelta.REMOVED :
+			// removed project - if it contains packages we are interested in
+			// then the type hierarchy has changed
+			IJavaElement[] pkgs = this.packageRegion.getElements();
+			for (int i = 0; i < pkgs.length; i++) {
+				IJavaProject javaProject = pkgs[i].getJavaProject();
+				if (javaProject != null && javaProject.equals(element)) {
+					return true;
+				}
+			}
+			return false;
+		case IJavaElementDelta.CHANGED :
+			return isAffectedByChildren(delta, eventType);
+	}
+	return false;
+}
+/**
+ * Returns true if the given package fragment delta could affect this type hierarchy
+ * @param eventType TODO
+ */
+private boolean isAffectedByPackageFragment(IJavaElementDelta delta, PackageFragment element, int eventType) {
+	switch (delta.getKind()) {
+		case IJavaElementDelta.ADDED :
+			// if the package fragment is in the projects being considered, this could
+			// introduce new types, changing the hierarchy
+			return this.projectRegion.contains(element);
+		case IJavaElementDelta.REMOVED :
+			// is a change if the package fragment contains types in this hierarchy
+			return packageRegionContainsSamePackageFragment(element);
+		case IJavaElementDelta.CHANGED :
+			// look at the files in the package fragment
+			return isAffectedByChildren(delta, eventType);
+	}
+	return false;
+}
+/**
+ * Returns true if the given package fragment root delta could affect this type hierarchy
+ * @param eventType TODO
+ */
+private boolean isAffectedByPackageFragmentRoot(IJavaElementDelta delta, IJavaElement element, int eventType) {
+	switch (delta.getKind()) {
+		case IJavaElementDelta.ADDED :
+			return this.projectRegion.contains(element);
+		case IJavaElementDelta.REMOVED :
+		case IJavaElementDelta.CHANGED :
+			int flags = delta.getFlags();
+			if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0) {
+				// check if the root is in the classpath of one of the projects of this hierarchy
+				if (this.projectRegion != null) {
+					IPackageFragmentRoot root = (IPackageFragmentRoot)element;
+					IPath rootPath = root.getPath();
+					IJavaElement[] elements = this.projectRegion.getElements();
+					for (int i = 0; i < elements.length; i++) {
+						JavaProject javaProject = (JavaProject)elements[i];
+						try {
+							IClasspathEntry entry = javaProject.getClasspathEntryFor(rootPath);
+							if (entry != null) {
+								return true;
+							}
+						} catch (JavaModelException e) {
+							// igmore this project
+						}
+					}
+				}
+			}
+			if ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0 || (flags & IJavaElementDelta.F_ARCHIVE_CONTENT_CHANGED) > 0) {
+				// 1. removed from classpath - if it contains packages we are interested in
+				// the the type hierarchy has changed
+				// 2. content of a jar changed - if it contains packages we are interested in
+				// then the type hierarchy has changed
+				IJavaElement[] pkgs = this.packageRegion.getElements();
+				for (int i = 0; i < pkgs.length; i++) {
+					if (pkgs[i].getParent().equals(element)) {
+						return true;
+					}
+				}
+				return false;
+			}
+	}
+	return isAffectedByChildren(delta, eventType);
+}
+/**
+ * Returns true if the given type delta (a compilation unit delta or a class file delta)
+ * could affect this type hierarchy.
+ * @param eventType TODO
+ */
+protected boolean isAffectedByOpenable(IJavaElementDelta delta, IJavaElement element, int eventType) {
+	if (element instanceof CompilationUnit) {
+		CompilationUnit cu = (CompilationUnit)element;
+		ICompilationUnit focusCU = 
+			this.focusType != null ? this.focusType.getCompilationUnit() : null;
+		if (focusCU != null && focusCU.getOwner() != cu.getOwner())
+			return false;
+		//ADDED delta arising from getWorkingCopy() should be ignored
+		if (eventType != ElementChangedEvent.POST_RECONCILE && !cu.isPrimary() &&
+				delta.getKind() == IJavaElementDelta.ADDED)
+			return false;
+		ChangeCollector collector = this.changeCollector;
+		if (collector == null) {
+		    collector = new ChangeCollector(this);
+		}
+		try {
+			collector.addChange(cu, delta);
+		} catch (JavaModelException e) {
+			if (DEBUG)
+				e.printStackTrace();
+		}
+		if (cu.isWorkingCopy() && eventType == ElementChangedEvent.POST_RECONCILE) {
+			// changes to working copies are batched
+			this.changeCollector = collector;
+			return false;
+		} else {
+			return collector.needsRefresh();
+		}
+	} else if (element instanceof ClassFile) {
+		switch (delta.getKind()) {
+			case IJavaElementDelta.REMOVED:
+				return this.files.get(element) != null;
+			case IJavaElementDelta.ADDED:
+				IType type = ((ClassFile)element).getType();
+				String typeName = type.getElementName();
+				if (hasSupertype(typeName)
+					|| subtypesIncludeSupertypeOf(type)
+					|| this.missingTypes.contains(typeName)) {
+
+					return true;
+				}
+				break;
+			case IJavaElementDelta.CHANGED:
+				IJavaElementDelta[] children = delta.getAffectedChildren();
+				for (int i = 0, length = children.length; i < length; i++) {
+					IJavaElementDelta child = children[i];
+					IJavaElement childElement = child.getElement();
+					if (childElement instanceof IType) {
+						type = (IType)childElement;
+						boolean hasVisibilityChange = (delta.getFlags() & IJavaElementDelta.F_MODIFIERS) > 0;
+						boolean hasSupertypeChange = (delta.getFlags() & IJavaElementDelta.F_SUPER_TYPES) > 0;
+						if ((hasVisibilityChange && hasSupertype(type.getElementName()))
+								|| (hasSupertypeChange && includesTypeOrSupertype(type))) {
+							return true;
+						}
+					}
+				}
+				break;
+		}
+	}
+	return false;
+}
+private boolean isInterface(IType type) {
+	int flags = getCachedFlags(type);
+	if (flags == -1) {
+		try {
+			return type.isInterface();
+		} catch (JavaModelException e) {
+			return false;
+		}
+	} else {
+		return Flags.isInterface(flags);
+	}
+}
+/**
+ * Returns the java project this hierarchy was created in.
+ */
+public IJavaProject javaProject() {
+	return this.focusType.getJavaProject();
+}
+protected static byte[] readUntil(InputStream input, byte separator) throws JavaModelException, IOException{
+	return readUntil(input, separator, 0);
+}
+protected static byte[] readUntil(InputStream input, byte separator, int offset) throws IOException, JavaModelException{
+	int length = 0;
+	byte[] bytes = new byte[SIZE];
+	byte b;
+	while((b = (byte)input.read()) != separator && b != -1) {
+		if(bytes.length == length) {
+			System.arraycopy(bytes, 0, bytes = new byte[length*2], 0, length);
+		}
+		bytes[length++] = b;
+	}
+	if(b == -1) {
+		throw new JavaModelException(new JavaModelStatus(IStatus.ERROR));
+	}
+	System.arraycopy(bytes, 0, bytes = new byte[length + offset], offset, length);
+	return bytes;
+}
+public static ITypeHierarchy load(IType type, InputStream input, WorkingCopyOwner owner) throws JavaModelException {
+	try {
+		TypeHierarchy typeHierarchy = new TypeHierarchy();
+		typeHierarchy.initialize(1);
+
+		IType[] types = new IType[SIZE];
+		int typeCount = 0;
+
+		byte version = (byte)input.read();
+
+		if(version != VERSION) {
+			throw new JavaModelException(new JavaModelStatus(IStatus.ERROR));
+		}
+		byte generalInfo = (byte)input.read();
+		if((generalInfo & COMPUTE_SUBTYPES) != 0) {
+			typeHierarchy.computeSubtypes = true;
+		}
+
+		byte b;
+		byte[] bytes;
+
+		// read project
+		bytes = readUntil(input, SEPARATOR1);
+		if(bytes.length > 0) {
+			typeHierarchy.project = (IJavaProject)JavaCore.create(new String(bytes));
+			typeHierarchy.scope = SearchEngine.createJavaSearchScope(new IJavaElement[] {typeHierarchy.project});
+		} else {
+			typeHierarchy.project = null;
+			typeHierarchy.scope = SearchEngine.createWorkspaceScope();
+		}
+
+		// read missing type
+		{
+			bytes = readUntil(input, SEPARATOR1);
+			byte[] missing;
+			int j = 0;
+			int length = bytes.length;
+			for (int i = 0; i < length; i++) {
+				b = bytes[i];
+				if(b == SEPARATOR2) {
+					missing = new byte[i - j];
+					System.arraycopy(bytes, j, missing, 0, i - j);
+					typeHierarchy.missingTypes.add(new String(missing));
+					j = i + 1;
+				}
+			}
+			System.arraycopy(bytes, j, missing = new byte[length - j], 0, length - j);
+			typeHierarchy.missingTypes.add(new String(missing));
+		}
+
+		// read types
+		while((b = (byte)input.read()) != SEPARATOR1 && b != -1) {
+			bytes = readUntil(input, SEPARATOR4, 1);
+			bytes[0] = b;
+			IType element = (IType)JavaCore.create(new String(bytes), owner);
+
+			if(types.length == typeCount) {
+				System.arraycopy(types, 0, types = new IType[typeCount * 2], 0, typeCount);
+			}
+			types[typeCount++] = element;
+
+			// read flags
+			bytes = readUntil(input, SEPARATOR4);
+			Integer flags = bytesToFlags(bytes);
+			if(flags != null) {
+				typeHierarchy.cacheFlags(element, flags.intValue());
+			}
+
+			// read info
+			byte info = (byte)input.read();
+
+			if((info & INTERFACE) != 0) {
+				typeHierarchy.addInterface(element);
+			}
+			if((info & COMPUTED_FOR) != 0) {
+				if(!element.equals(type)) {
+					throw new JavaModelException(new JavaModelStatus(IStatus.ERROR));
+				}
+				typeHierarchy.focusType = element;
+			}
+			if((info & ROOT) != 0) {
+				typeHierarchy.addRootClass(element);
+			}
+		}
+
+		// read super class
+		while((b = (byte)input.read()) != SEPARATOR1 && b != -1) {
+			bytes = readUntil(input, SEPARATOR3, 1);
+			bytes[0] = b;
+			int subClass = new Integer(new String(bytes)).intValue();
+
+			// read super type
+			bytes = readUntil(input, SEPARATOR1);
+			int superClass = new Integer(new String(bytes)).intValue();
+
+			typeHierarchy.cacheSuperclass(
+				types[subClass],
+				types[superClass]);
+		}
+
+		// read super interface
+		while((b = (byte)input.read()) != SEPARATOR1 && b != -1) {
+			bytes = readUntil(input, SEPARATOR3, 1);
+			bytes[0] = b;
+			int subClass = new Integer(new String(bytes)).intValue();
+
+			// read super interface
+			bytes = readUntil(input, SEPARATOR1);
+			IType[] superInterfaces = new IType[(bytes.length / 2) + 1];
+			int interfaceCount = 0;
+
+			int j = 0;
+			byte[] b2;
+			for (int i = 0; i < bytes.length; i++) {
+				if(bytes[i] == SEPARATOR2){
+					b2 = new byte[i - j];
+					System.arraycopy(bytes, j, b2, 0, i - j);
+					j = i + 1;
+					superInterfaces[interfaceCount++] = types[new Integer(new String(b2)).intValue()];
+				}
+			}
+			b2 = new byte[bytes.length - j];
+			System.arraycopy(bytes, j, b2, 0, bytes.length - j);
+			superInterfaces[interfaceCount++] = types[new Integer(new String(b2)).intValue()];
+			System.arraycopy(superInterfaces, 0, superInterfaces = new IType[interfaceCount], 0, interfaceCount);
+
+			typeHierarchy.cacheSuperInterfaces(
+				types[subClass],
+				superInterfaces);
+		}
+		if(b == -1) {
+			throw new JavaModelException(new JavaModelStatus(IStatus.ERROR));
+		}
+		return typeHierarchy;
+	} catch(IOException e){
+		throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+	}
+}
+/**
+ * Returns <code>true</code> if an equivalent package fragment is included in the package
+ * region. Package fragments are equivalent if they both have the same name.
+ */
+protected boolean packageRegionContainsSamePackageFragment(PackageFragment element) {
+	IJavaElement[] pkgs = this.packageRegion.getElements();
+	for (int i = 0; i < pkgs.length; i++) {
+		PackageFragment pkg = (PackageFragment) pkgs[i];
+		if (Util.equalArraysOrNull(pkg.names, element.names))
+			return true;
+	}
+	return false;
+}
+
+/**
+ * @see ITypeHierarchy
+ * TODO (jerome) should use a PerThreadObject to build the hierarchy instead of synchronizing
+ * (see also isAffected(IJavaElementDelta))
+ */
+public synchronized void refresh(IProgressMonitor monitor) throws JavaModelException {
+	try {
+		this.progressMonitor = monitor;
+		if (monitor != null) {
+			monitor.beginTask(
+					this.focusType != null ?
+							Messages.bind(Messages.hierarchy_creatingOnType, this.focusType.getFullyQualifiedName()) :
+							Messages.hierarchy_creating,
+					100);
+		}
+		long start = -1;
+		if (DEBUG) {
+			start = System.currentTimeMillis();
+			if (this.computeSubtypes) {
+				System.out.println("CREATING TYPE HIERARCHY [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				System.out.println("CREATING SUPER TYPE HIERARCHY [" + Thread.currentThread() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			if (this.focusType != null) {
+				System.out.println("  on type " + ((JavaElement)this.focusType).toStringWithAncestors()); //$NON-NLS-1$
+			}
+		}
+
+		compute();
+		initializeRegions();
+		this.needsRefresh = false;
+		this.changeCollector = null;
+
+		if (DEBUG) {
+			if (this.computeSubtypes) {
+				System.out.println("CREATED TYPE HIERARCHY in " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				System.out.println("CREATED SUPER TYPE HIERARCHY in " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			System.out.println(this.toString());
+		}
+	} catch (JavaModelException e) {
+		throw e;
+	} catch (CoreException e) {
+		throw new JavaModelException(e);
+	} finally {
+		if (monitor != null) {
+			monitor.done();
+		}
+		this.progressMonitor = null;
+	}
+}
+
+/**
+ * @see ITypeHierarchy
+ */
+public synchronized void removeTypeHierarchyChangedListener(ITypeHierarchyChangedListener listener) {
+	ArrayList listeners = this.changeListeners;
+	if (listeners == null) {
+		return;
+	}
+	listeners.remove(listener);
+
+	// deregister from JavaCore on last listener removed
+	if (listeners.isEmpty()) {
+		JavaCore.removeElementChangedListener(this);
+	}
+}
+/**
+ * @see ITypeHierarchy
+ */
+public void store(OutputStream output, IProgressMonitor monitor) throws JavaModelException {
+	try {
+		// compute types in hierarchy
+		Hashtable hashtable = new Hashtable();
+		Hashtable hashtable2 = new Hashtable();
+		int count = 0;
+
+		if(this.focusType != null) {
+			Integer index = new Integer(count++);
+			hashtable.put(this.focusType, index);
+			hashtable2.put(index, this.focusType);
+		}
+		Object[] types = this.classToSuperclass.entrySet().toArray();
+		for (int i = 0; i < types.length; i++) {
+			Map.Entry entry = (Map.Entry) types[i];
+			Object t = entry.getKey();
+			if(hashtable.get(t) == null) {
+				Integer index = new Integer(count++);
+				hashtable.put(t, index);
+				hashtable2.put(index, t);
+			}
+			Object superClass = entry.getValue();
+			if(superClass != null && hashtable.get(superClass) == null) {
+				Integer index = new Integer(count++);
+				hashtable.put(superClass, index);
+				hashtable2.put(index, superClass);
+			}
+		}
+		types = this.typeToSuperInterfaces.entrySet().toArray();
+		for (int i = 0; i < types.length; i++) {
+			Map.Entry entry = (Map.Entry) types[i];
+			Object t = entry.getKey();
+			if(hashtable.get(t) == null) {
+				Integer index = new Integer(count++);
+				hashtable.put(t, index);
+				hashtable2.put(index, t);
+			}
+			Object[] sp = (Object[]) entry.getValue();
+			if(sp != null) {
+				for (int j = 0; j < sp.length; j++) {
+					Object superInterface = sp[j];
+					if(sp[j] != null && hashtable.get(superInterface) == null) {
+						Integer index = new Integer(count++);
+						hashtable.put(superInterface, index);
+						hashtable2.put(index, superInterface);
+					}
+				}
+			}
+		}
+		// save version of the hierarchy format
+		output.write(VERSION);
+
+		// save general info
+		byte generalInfo = 0;
+		if(this.computeSubtypes) {
+			generalInfo |= COMPUTE_SUBTYPES;
+		}
+		output.write(generalInfo);
+
+		// save project
+		if(this.project != null) {
+			output.write(this.project.getHandleIdentifier().getBytes());
+		}
+		output.write(SEPARATOR1);
+
+		// save missing types
+		for (int i = 0; i < this.missingTypes.size(); i++) {
+			if(i != 0) {
+				output.write(SEPARATOR2);
+			}
+			output.write(((String)this.missingTypes.get(i)).getBytes());
+
+		}
+		output.write(SEPARATOR1);
+
+		// save types
+		for (int i = 0; i < count ; i++) {
+			IType t = (IType)hashtable2.get(new Integer(i));
+
+			// n bytes
+			output.write(t.getHandleIdentifier().getBytes());
+			output.write(SEPARATOR4);
+			output.write(flagsToBytes((Integer)this.typeFlags.get(t)));
+			output.write(SEPARATOR4);
+			byte info = CLASS;
+			if(this.focusType != null && this.focusType.equals(t)) {
+				info |= COMPUTED_FOR;
+			}
+			if(this.interfaces.contains(t)) {
+				info |= INTERFACE;
+			}
+			if(this.rootClasses.contains(t)) {
+				info |= ROOT;
+			}
+			output.write(info);
+		}
+		output.write(SEPARATOR1);
+
+		// save superclasses
+		types = this.classToSuperclass.entrySet().toArray();
+		for (int i = 0; i < types.length; i++) {
+			Map.Entry entry = (Map.Entry) types[i];
+			IJavaElement key = (IJavaElement) entry.getKey();
+			IJavaElement value = (IJavaElement) entry.getValue();
+
+			output.write(((Integer)hashtable.get(key)).toString().getBytes());
+			output.write('>');
+			output.write(((Integer)hashtable.get(value)).toString().getBytes());
+			output.write(SEPARATOR1);
+		}
+		output.write(SEPARATOR1);
+
+		// save superinterfaces
+		types = this.typeToSuperInterfaces.entrySet().toArray();
+		for (int i = 0; i < types.length; i++) {
+			Map.Entry entry = (Map.Entry) types[i];
+			IJavaElement key = (IJavaElement) entry.getKey();
+			IJavaElement[] values = (IJavaElement[]) entry.getValue();
+
+			if(values.length > 0) {
+				output.write(((Integer)hashtable.get(key)).toString().getBytes());
+				output.write(SEPARATOR3);
+				for (int j = 0; j < values.length; j++) {
+					IJavaElement value = values[j];
+					if(j != 0) output.write(SEPARATOR2);
+					output.write(((Integer)hashtable.get(value)).toString().getBytes());
+				}
+				output.write(SEPARATOR1);
+			}
+		}
+		output.write(SEPARATOR1);
+	} catch(IOException e) {
+		throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+	}
+}
+/**
+ * Returns whether the simple name of a supertype of the given type is
+ * the simple name of one of the subtypes in this hierarchy or the
+ * simple name of this type.
+ */
+boolean subtypesIncludeSupertypeOf(IType type) {
+	// look for superclass
+	String superclassName = null;
+	try {
+		superclassName = type.getSuperclassName();
+	} catch (JavaModelException e) {
+		if (DEBUG) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+	if (superclassName == null) {
+		superclassName = "Object"; //$NON-NLS-1$
+	}
+	if (hasSubtypeNamed(superclassName)) {
+		return true;
+	}
+
+	// look for super interfaces
+	String[] interfaceNames = null;
+	try {
+		interfaceNames = type.getSuperInterfaceNames();
+	} catch (JavaModelException e) {
+		if (DEBUG)
+			e.printStackTrace();
+		return false;
+	}
+	for (int i = 0, length = interfaceNames.length; i < length; i++) {
+		String interfaceName = interfaceNames[i];
+		if (hasSubtypeNamed(interfaceName)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+/**
+ * @see ITypeHierarchy
+ */
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	buffer.append("Focus: "); //$NON-NLS-1$
+	if (this.focusType == null) {
+		buffer.append("<NONE>\n"); //$NON-NLS-1$
+	} else {
+		toString(buffer, this.focusType, 0);
+	}
+	if (exists()) {
+		if (this.focusType != null) {
+			buffer.append("Super types:\n"); //$NON-NLS-1$
+			toString(buffer, this.focusType, 0, true);
+			buffer.append("Sub types:\n"); //$NON-NLS-1$
+			toString(buffer, this.focusType, 0, false);
+		} else {
+			if (this.rootClasses.size > 0) {
+				IJavaElement[] roots = Util.sortCopy(getRootClasses());
+				buffer.append("Super types of root classes:\n"); //$NON-NLS-1$
+				int length = roots.length;
+				for (int i = 0; i < length; i++) {
+					IJavaElement root = roots[i];
+					toString(buffer, root, 1);
+					toString(buffer, root, 1, true);
+				}
+				buffer.append("Sub types of root classes:\n"); //$NON-NLS-1$
+				for (int i = 0; i < length; i++) {
+					IJavaElement root = roots[i];
+					toString(buffer, root, 1);
+					toString(buffer, root, 1, false);
+				}
+			} else if (this.rootClasses.size == 0) {
+				// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=24691
+				buffer.append("No root classes"); //$NON-NLS-1$
+			}
+		}
+	} else {
+		buffer.append("(Hierarchy became stale)"); //$NON-NLS-1$
+	}
+	return buffer.toString();
+}
+/**
+ * Append a String to the given buffer representing the hierarchy for the type,
+ * beginning with the specified indentation level.
+ * If ascendant, shows the super types, otherwise show the sub types.
+ */
+private void toString(StringBuffer buffer, IJavaElement type, int indent, boolean ascendant) {
+	IType[] types= ascendant ? getSupertypes((IType) type) : getSubtypes((IType) type);
+	IJavaElement[] sortedTypes = Util.sortCopy(types);
+	for (int i= 0; i < sortedTypes.length; i++) {
+		toString(buffer, sortedTypes[i], indent + 1);
+		toString(buffer, sortedTypes[i], indent + 1, ascendant);
+	}
+}
+private void toString(StringBuffer buffer, IJavaElement type, int indent) {
+	for (int j= 0; j < indent; j++) {
+		buffer.append("  "); //$NON-NLS-1$
+	}
+	buffer.append(((JavaElement) type).toStringWithAncestors(false/*don't show key*/));
+	buffer.append('\n');
+}
+/**
+ * Returns whether one of the types in this hierarchy has a supertype whose simple
+ * name is the given simple name.
+ */
+boolean hasSupertype(String simpleName) {
+	for(Iterator iter = this.classToSuperclass.values().iterator(); iter.hasNext();){
+		IType superType = (IType)iter.next();
+		if (superType.getElementName().equals(simpleName)) {
+			return true;
+		}
+	}
+	return false;
+}
+/**
+ * @see IProgressMonitor
+ */
+protected void worked(int work) {
+	if (this.progressMonitor != null) {
+		this.progressMonitor.worked(work);
+		checkCanceled();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java
new file mode 100644
index 0000000..adbea47
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Stack;
+
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter;
+
+/**
+ * An abstract DOM builder that contains shared functionality of DOMBuilder and SimpleDOMBuilder.
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+public class AbstractDOMBuilder extends ReferenceInfoAdapter implements ILineStartFinder {
+	/**
+	 * Set to true when an error is encounterd while
+	 * fuzzy parsing
+	 */
+	protected boolean fAbort;
+
+	/**
+	 * True when a compilation unit is being constructed.
+	 * False when any other type of document fragment is
+	 * being constructed.
+	 */
+	protected boolean fBuildingCU = false;
+
+	/**
+	 * True when a compilation unit or type is being
+	 * constructed. False when any other type of document
+	 * fragment is being constructed.
+	 */
+	protected boolean fBuildingType= false;
+
+	/**
+	 * The String on which the JDOM is being created.
+	 */
+	protected char[] fDocument= null;
+
+	/**
+	 * The source positions of all of the line separators in the document.
+	 */
+	protected int[] fLineStartPositions = new int[] { 0 };
+
+	/**
+	 * A stack of enclosing scopes used when constructing
+	 * a compilation unit or type. The top of the stack
+	 * is the document fragment that children are added to.
+	 */
+	protected Stack fStack = null;
+
+	/**
+	 * The number of fields constructed in the current
+	 * document. This is used when building a single
+	 * field document fragment, since the DOMBuilder only
+	 * accepts documents with one field declaration.
+	 */
+	protected int fFieldCount;
+
+	/**
+	 * The current node being constructed.
+	 */
+	protected DOMNode fNode;
+/**
+ * AbstractDOMBuilder constructor.
+ */
+public AbstractDOMBuilder() {
+	super();
+}
+/**
+ * Accepts the line separator table and converts it into a line start table.
+ *
+ * <p>A line separator might corresponds to several characters in the source.
+ *
+ * @see org.eclipse.jdt.internal.compiler.IDocumentElementRequestor#acceptLineSeparatorPositions(int[])
+ */
+public void acceptLineSeparatorPositions(int[] positions) {
+	if (positions != null) {
+		int length = positions.length;
+		if (length > 0) {
+			this.fLineStartPositions = new int[length + 1];
+			this.fLineStartPositions[0] = 0;
+			int documentLength = this.fDocument.length;
+			for (int i = 0; i < length; i++) {
+				int iPlusOne = i + 1;
+				int positionPlusOne = positions[i] + 1;
+				if (positionPlusOne < documentLength) {
+					if (iPlusOne < length) {
+						// more separators
+						this.fLineStartPositions[iPlusOne] = positionPlusOne;
+					} else {
+						// no more separators
+						if (this.fDocument[positionPlusOne] == '\n') {
+							this.fLineStartPositions[iPlusOne] = positionPlusOne + 1;
+						} else {
+							this.fLineStartPositions[iPlusOne] = positionPlusOne;
+						}
+					}
+				} else {
+					this.fLineStartPositions[iPlusOne] = positionPlusOne;
+				}
+			}
+		}
+	}
+}
+/**
+ * Adds the given node to the current enclosing scope, building the JDOM
+ * tree. Nodes are only added to an enclosing scope when a compilation unit or type
+ * is being built (since those are the only nodes that have children).
+ *
+ * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
+ * the nodes in the newly created JDOM are not fragmented.
+ */
+protected void addChild(IDOMNode child) {
+	if (this.fStack.size() > 0) {
+		DOMNode parent = (DOMNode) this.fStack.peek();
+		if (this.fBuildingCU || this.fBuildingType) {
+			parent.basicAddChild(child);
+		}
+	}
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(char[] contents, char[] name) {
+	return createCompilationUnit(new CompilationUnit(contents, name));
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
+	if (this.fAbort) {
+		return null;
+	}
+	this.fNode.normalize(this);
+	return (IDOMCompilationUnit)this.fNode;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.IDocumentElementRequestor#enterClass(int, int[], int, int, int, char[], int, int, char[], int, int, char[][], int[], int[], int)
+ */
+public void enterCompilationUnit() {
+ 	if (this.fBuildingCU) {
+ 		IDOMCompilationUnit cu= new DOMCompilationUnit(this.fDocument, new int[] {0, this.fDocument.length - 1});
+ 		this.fStack.push(cu);
+ 	}
+}
+/**
+ * Finishes the configuration of the compilation unit DOM object which
+ * was created by a previous enterCompilationUnit call.
+ *
+ * @see org.eclipse.jdt.internal.compiler.IDocumentElementRequestor#exitCompilationUnit(int)
+ */
+public void exitCompilationUnit(int declarationEnd) {
+	DOMCompilationUnit cu = (DOMCompilationUnit) this.fStack.pop();
+	cu.setSourceRangeEnd(declarationEnd);
+	this.fNode = cu;
+}
+/**
+ * Finishes the configuration of the class and interface DOM objects.
+ *
+ * @param bodyEnd - a source position corresponding to the closing bracket of the class
+ * @param declarationEnd - a source position corresponding to the end of the class
+ *		declaration.  This can include whitespace and comments following the closing bracket.
+ */
+protected void exitType(int bodyEnd, int declarationEnd) {
+	DOMType type = (DOMType)this.fStack.pop();
+	type.setSourceRangeEnd(declarationEnd);
+	type.setCloseBodyRangeStart(bodyEnd);
+	type.setCloseBodyRangeEnd(bodyEnd);
+	this.fNode = type;
+}
+/**
+ * @see ILineStartFinder#getLineStart(int)
+ */
+public int getLineStart(int position) {
+	int lineSeparatorCount = this.fLineStartPositions.length;
+	// reverse traversal intentional.
+	for(int i = lineSeparatorCount - 1; i >= 0; i--) {
+		if (this.fLineStartPositions[i] <= position)
+			return this.fLineStartPositions[i];
+	}
+	return 0;
+}
+/**
+ * Initializes the builder to create a document fragment.
+ *
+ * @param sourceCode - the document containing the source code to be analyzed
+ * @param buildingCompilationUnit - true if a the document is being analyzed to
+ *		create a compilation unit, otherwise false
+ * @param buildingType - true if the document is being analyzed to create a
+ *		type or compilation unit
+ */
+protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType) {
+	this.fBuildingCU = buildingCompilationUnit;
+	this.fBuildingType = buildingType;
+	this.fStack = new Stack();
+	this.fDocument = sourceCode;
+	this.fFieldCount = 0;
+	this.fAbort = false;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java
new file mode 100644
index 0000000..c00aa48
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+
+/**
+ * Implements a very simple version of the ICompilationUnit.
+ *
+ * <p>Please do not use outside of jdom.</p>
+ */
+public class CompilationUnit implements ICompilationUnit {
+	protected char[] fContents;
+	protected char[] fFileName;
+	protected char[] fMainTypeName;
+public CompilationUnit(char[] contents, char[] filename) {
+	this.fContents = contents;
+	this.fFileName = filename;
+
+	String file = new String(filename);
+	int start = file.lastIndexOf("/") + 1; //$NON-NLS-1$
+	if (start == 0 || start < file.lastIndexOf("\\")) //$NON-NLS-1$
+		start = file.lastIndexOf("\\") + 1; //$NON-NLS-1$
+
+	int end = file.lastIndexOf("."); //$NON-NLS-1$
+	if (end == -1)
+		end = file.length();
+
+	this.fMainTypeName = file.substring(start, end).toCharArray();
+}
+public char[] getContents() {
+	return this.fContents;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ */
+public char[] getFileName() {
+	return this.fFileName;
+}
+public char[] getMainTypeName() {
+	return this.fMainTypeName;
+}
+public char[][] getPackageName() {
+	return null;
+}
+public boolean ignoreOptionalProblems() {
+	return false;
+}
+public String toString() {
+	return "CompilationUnit[" + new String(this.fFileName) + "]";  //$NON-NLS-2$ //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java
new file mode 100644
index 0000000..cba3d66
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java
@@ -0,0 +1,720 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.DocumentElementParser;
+import org.eclipse.jdt.internal.compiler.IDocumentElementRequestor;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+/**
+ * The DOMBuilder constructs each type of JDOM document fragment,
+ * for the DOMFactory. The DOMBuilder has been separated from the
+ * DOMFactory to hide the implmentation of node creation and the
+ * public Requestor API methods.
+ *
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+public class DOMBuilder extends AbstractDOMBuilder implements IDocumentElementRequestor {
+
+	/**
+	 * True when parsing a single member - ignore any problems
+	 * encountered after the member.
+	 */
+	protected boolean fBuildingSingleMember= false;
+
+	/**
+	 * True when the single member being built has been
+	 * exited.
+	 */
+	protected boolean fFinishedSingleMember = false;
+
+	/**
+	 * Collection of multiple fields in one declaration
+	 */
+	protected ArrayList fFields;
+
+	Map options = JavaCore.getOptions();
+
+/**
+ * Creates a new DOMBuilder
+ */
+public DOMBuilder() {
+	// Creates a new DOMBuilder
+}
+/**
+ * @see IDocumentElementRequestor#acceptImport(int, int, int[], char[], int, boolean, int)
+ */
+public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name,
+	int nameStart, boolean onDemand, int modifiers) {
+	int[] sourceRange = {declarationStart, declarationEnd};
+	int[] nameRange = {nameStart, declarationEnd - 1};
+
+	/* See 1FVII1P */
+	String importName = new String(this.fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]);
+
+	this.fNode= new DOMImport(this.fDocument, sourceRange, importName, nameRange, onDemand, modifiers);
+	addChild(this.fNode);
+	if (this.fBuildingSingleMember) {
+		this.fFinishedSingleMember= true;
+	}
+}
+/**
+ * @see IDocumentElementRequestor#acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd)
+ */
+public void acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers,
+	int modifiersStart, int bodyStart, int bodyEnd) {
+	int[] sourceRange = {declarationStart, declarationEnd};
+	int[] commentRange = {-1, -1};
+	if (javaDocPositions != null) {
+		int length = javaDocPositions.length;
+		commentRange[0] = javaDocPositions[length - 2];
+		commentRange[1] = javaDocPositions[length - 1];
+	}
+
+	int[] modifiersRange = {-1, -1};
+	if (modifiersStart >= declarationStart) {
+		modifiersRange[0] = modifiersStart;
+		modifiersRange[1] = bodyStart - 1;
+	}
+	this.fNode = new DOMInitializer(this.fDocument, sourceRange, commentRange, modifiers,
+		modifiersRange, bodyStart);
+	addChild(this.fNode);
+	if (this.fBuildingSingleMember) {
+		this.fFinishedSingleMember= true;
+	}
+}
+/**
+ * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition)
+ */
+public void acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name,
+	int nameStartPosition) {
+	int[] sourceRange = null;
+	if (javaDocPositions != null) {
+		int length = javaDocPositions.length;
+		// get last javadoc comment (see bug 68772)
+		sourceRange = new int[] {javaDocPositions[length - 2], declarationEnd};
+	} else {
+		sourceRange = new int[] {declarationStart, declarationEnd};
+	}
+	int[] nameRange = {nameStartPosition, declarationEnd - 1};
+	this.fNode= new DOMPackage(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange);
+	addChild(this.fNode);
+	if (this.fBuildingSingleMember) {
+		this.fFinishedSingleMember= true;
+	}
+}
+/**
+ * Sets the abort flag to true. The parser has encountered an error
+ * in the current document. If we are only building a single member, and
+ * we are done with the member - don't worry about the error.
+ *
+ * @see IDocumentElementRequestor
+ */
+public void acceptProblem(CategorizedProblem problem){
+	if (this.fBuildingSingleMember && this.fFinishedSingleMember) {
+		return;
+	}
+	this.fAbort= true;
+}
+/**
+ * Adds the given node to the current enclosing scope, building the JDOM
+ * tree. Nodes are only added to an enclosing scope when a compilation unit or type
+ * is being built (since those are the only nodes that have children).
+ *
+ * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
+ * the nodes in the newly created JDOM are not fragmented.
+ */
+protected void addChild(IDOMNode child) {
+	super.addChild(child);
+	if (this.fStack.isEmpty() && this.fFields != null) {
+		this.fFields.add(child);
+	}
+}
+/**
+ * @see IDOMFactory#createCompilationUnit()
+ */
+public IDOMCompilationUnit createCompilationUnit() {
+	return new DOMCompilationUnit();
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
+	initializeBuild(compilationUnit.getContents(), true, true, false);
+	getParser(this.options).parseCompilationUnit(compilationUnit);
+	return super.createCompilationUnit(compilationUnit);
+}
+/**
+ * @see IDOMFactory#createField(String)
+ */
+public IDOMField createField(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, true);
+	getParser(this.options).parseField(sourceCode);
+	if (this.fAbort || this.fNode == null) {
+		return null;
+	}
+
+	// we only accept field declarations with one field
+	if (this.fFieldCount > 1) {
+		return null;
+	}
+
+	this.fNode.normalize(this);
+	return (IDOMField)this.fNode;
+}
+/**
+ *
+ */
+public IDOMField[] createFields(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, false);
+	this.fFields= new ArrayList();
+	getParser(this.options).parseField(sourceCode);
+	if (this.fAbort) {
+		return null;
+	}
+	IDOMField[] fields= new IDOMField[this.fFields.size()];
+	this.fFields.toArray(fields);
+	for (int i= 0; i < fields.length; i++) {
+		DOMNode node= (DOMNode)fields[i];
+		if (i < (fields.length - 1)) {
+			DOMNode next= (DOMNode)fields[i + 1];
+			node.fNextNode= next;
+			next.fPreviousNode= node;
+		}
+		((DOMNode)fields[i]).normalize(this);
+	}
+	return fields;
+}
+/**
+ * @see IDOMFactory#createImport()
+ */
+public IDOMImport createImport() {
+	return new DOMImport();
+}
+/**
+ * @see IDOMFactory#createImport(String)
+ */
+public IDOMImport createImport(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, true);
+	getParser(this.options).parseImport(sourceCode);
+	if (this.fAbort || this.fNode == null) {
+		return null;
+	}
+	this.fNode.normalize(this);
+	return (IDOMImport)this.fNode;
+}
+/**
+ * Creates an INITIALIZER document fragment from the given source.
+ *
+ * @see IDOMFactory#createInitializer(String)
+ */
+public IDOMInitializer createInitializer(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, true);
+	getParser(this.options).parseInitializer(sourceCode);
+	if (this.fAbort || this.fNode == null || !(this.fNode instanceof IDOMInitializer)) {
+		return null;
+	}
+	this.fNode.normalize(this);
+	return (IDOMInitializer)this.fNode;
+}
+/**
+ * @see IDOMFactory#createMethod(String)
+ */
+public IDOMMethod createMethod(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, true);
+	getParser(this.options).parseMethod(sourceCode);
+	if (this.fAbort || this.fNode == null) {
+		return null;
+	}
+	this.fNode.normalize(this);
+	return (IDOMMethod)this.fNode;
+}
+/**
+ * @see IDOMFactory#createPackage()
+ */
+public IDOMPackage createPackage() {
+	return new DOMPackage();
+}
+/**
+ * @see IDOMFactory#createPackage(String)
+ */
+public IDOMPackage createPackage(char[] sourceCode) {
+	initializeBuild(sourceCode, false, false, true);
+	getParser(this.options).parsePackage(sourceCode);
+	if (this.fAbort || this.fNode == null) {
+		return null;
+	}
+	this.fNode.normalize(this);
+	return (IDOMPackage)this.fNode;
+}
+/**
+ * @see IDOMFactory#createType(String)
+ */
+public IDOMType createType(char[] sourceCode) {
+	initializeBuild(sourceCode, false, true, false);
+	getParser(this.options).parseType(sourceCode);
+	if (this.fAbort) {
+		return null;
+	}
+	if (this.fNode != null) this.fNode.normalize(this);
+	if (this.fNode instanceof IDOMType) {
+		return (IDOMType) this.fNode;
+	}
+	return null;
+}
+/**
+ * Creates a new DOMMethod and inizializes.
+ *
+ * @param declarationStart - a source position corresponding to the first character
+ *		of this constructor declaration
+ * @param modifiers - the modifiers for this constructor converted to a flag
+ * @param modifiersStart - a source position corresponding to the first character of the
+ *		textual modifiers
+ * @param returnType - the name of the return type
+ * @param returnTypeStart - a source position corresponding to the first character
+ *		of the return type
+ * @param returnTypeEnd - a source position corresponding to the last character
+ *		of the return type
+ * @param returnTypeDimensionCount - the array dimension count as supplied on the
+ *		return type (for instance, 'public int[] foo() {}')
+ * @param name - the name of this constructor
+ * @param nameStart - a source position corresponding to the first character of the name
+ * @param nameEnd - a source position corresponding to the last character of the name
+ * @param parameterTypes - a list of parameter type names
+ * @param parameterTypeStarts - a list of source positions corresponding to the
+ *		first character of each parameter type name
+ * @param parameterTypeEnds - a list of source positions corresponding to the
+ *		last character of each parameter type name
+ * @param parameterNames - a list of the names of the parameters
+ * @param parametersEnd - a source position corresponding to the last character of the
+ *		parameter list
+ * @extendedReturnTypeDimensionCount - the array dimension count as supplied on the
+ *		end of the parameter list (for instance, 'public int foo()[] {}')
+ * @extendedReturnTypeDimensionEnd - a source position corresponding to the last character
+ *		of the extended return type dimension
+ * @param exceptionTypes - a list of the exception types
+ * @param exceptionTypeStarts - a list of source positions corresponding to the first
+ *		character of the respective exception types
+ * @param exceptionTypeEnds - a list of source positions corresponding to the last
+ *		character of the respective exception types
+ * @param bodyStart - a source position corresponding to the start of this
+ *		constructor's body
+ */
+protected void enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
+	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount,
+	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
+	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts,
+	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount,
+	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts,
+	int[] exceptionTypeEnds, int bodyStart, boolean isConstructor) {
+	int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit
+	int[] nameRange = {nameStart, nameEnd};
+	int[] commentRange = {-1, -1};
+	if (javaDocPositions != null) {
+		int length = javaDocPositions.length;
+		commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
+		commentRange[1] = javaDocPositions[length - 1];
+	}
+	int[] modifiersRange = {-1, -1};
+	if (modifiersStart > -1) {
+		modifiersRange[0] = modifiersStart;
+		if (isConstructor) {
+			modifiersRange[1] = nameStart - 1;
+		} else {
+			modifiersRange[1] = returnTypeStart - 1;
+		}
+	}
+	int[] returnTypeRange = null;
+
+	if (extendedReturnTypeDimensionCount > 0)
+		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd,
+			parametersEnd + 1, extendedReturnTypeDimensionEnd};
+	else
+		returnTypeRange = new int[] {returnTypeStart, returnTypeEnd};
+	int[] parameterRange = {nameEnd + 1, parametersEnd};
+	int[] exceptionRange = {-1, -1};
+	if (exceptionTypes != null && exceptionTypes.length > 0) {
+		int exceptionCount = exceptionTypes.length;
+		exceptionRange[0] = exceptionTypeStarts[0];
+		exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1];
+	}
+	int[] bodyRange = null;
+	if (exceptionRange[1] > -1) {
+		bodyRange = new int[] {exceptionRange[1] + 1, -1}; // will be fixed up on exit
+	} else {
+		bodyRange = new int[] {parametersEnd + 1, -1};
+	}
+	this.fNode = new DOMMethod(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange, modifiers,
+		modifiersRange, isConstructor, CharOperation.charToString(returnType), returnTypeRange,
+		CharOperation.charArrayToStringArray(parameterTypes),
+		CharOperation.charArrayToStringArray(parameterNames),
+		parameterRange, CharOperation.charArrayToStringArray(exceptionTypes), exceptionRange, bodyRange);
+	addChild(this.fNode);
+	this.fStack.push(this.fNode);
+}
+/**
+ * @see IDocumentElementRequestor#enterClass(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	int classStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[] superclass,
+	int superclassStart,
+	int superclassEnd,
+	char[][] superinterfaces,
+	int[] superinterfaceStarts,
+	int[] superinterfaceEnds,
+	int bodyStart)
+ */
+public void enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
+	char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart,
+	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts,
+	int[] superinterfaceEnds, int bodyStart) {
+
+	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
+		name, nameStart, nameEnd, superclass, superclassStart,
+		superclassEnd, superinterfaces, superinterfaceStarts,
+		superinterfaceEnds, bodyStart, true);
+}
+/**
+ * @see IDocumentElementRequestor#enterConstructor(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] parameterTypes,
+	int [] parameterTypeStarts,
+	int [] parameterTypeEnds,
+	char[][] parameterNames,
+	int [] parameterNameStarts,
+	int [] parameterNameEnds,
+	int parametersEnd,
+	char[][] exceptionTypes,
+	int [] exceptionTypeStarts,
+	int [] exceptionTypeEnds,
+	int bodyStart)
+ */
+public void enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
+	char[] name, int nameStart, int nameEnd, char[][] parameterTypes,
+	int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames,
+	int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd,
+	char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds,
+	int bodyStart) {
+
+	/* see 1FVIIQZ */
+	String nameString = new String(this.fDocument, nameStart, nameEnd - nameStart);
+	int openParenPosition = nameString.indexOf('(');
+	if (openParenPosition > -1)
+		nameEnd = nameStart + openParenPosition - 1;
+
+	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart,
+		null, -1, -1, 0,
+		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts,
+		parameterTypeEnds, parameterNames, parameterNameStarts,
+		parameterNameEnds, parametersEnd, 0,
+		-1, exceptionTypes, exceptionTypeStarts,
+		exceptionTypeEnds, bodyStart,true);
+}
+/**
+ * @see IDocumentElementRequestor#enterField(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] type,
+	int typeStart,
+	int typeEnd,
+ 	int typeDimensionCount,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	int extendedTypeDimensionCount,
+	int extendedTypeDimensionEnd)
+ */
+public void enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
+	char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name,
+	int nameStart, int nameEnd, int extendedTypeDimensionCount,
+	int extendedTypeDimensionEnd) {
+	int[] sourceRange = {declarationStart,
+		(extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd : nameEnd};
+	int[] nameRange = {nameStart, nameEnd};
+	int[] commentRange = {-1, -1};
+	if (javaDocPositions != null) {
+		int length = javaDocPositions.length;
+		commentRange[0] = javaDocPositions[length - 2]; // get last javadoc comment (see bug 68772)
+		commentRange[1] = javaDocPositions[length - 1];
+	}
+	int[] modifiersRange = {-1, -1};
+	if (modifiersStart > -1) {
+		modifiersRange[0] = modifiersStart;
+		modifiersRange[1] = typeStart - 1;
+	}
+	int[] typeRange = {typeStart, typeEnd};
+	boolean hasInitializer = false; // fixed on exitField
+	int[] initializerRange = {-1, -1}; // fixed on exitField
+	boolean isVariableDeclarator = false;
+	if (this.fNode instanceof DOMField) {
+		DOMField field = (DOMField)this.fNode;
+		if (field.fTypeRange[0] == typeStart)
+			isVariableDeclarator = true;
+	}
+	this.fNode = new DOMField(this.fDocument, sourceRange, CharOperation.charToString(name), nameRange, commentRange,
+		modifiers, modifiersRange, typeRange, CharOperation.charToString(type), hasInitializer,
+		initializerRange, isVariableDeclarator);
+	addChild(this.fNode);
+	this.fStack.push(this.fNode);
+}
+/**
+ * @see IDocumentElementRequestor#enterInterface(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	int interfaceStart,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] superinterfaces,
+	int[] superinterfaceStarts,
+	int[] superinterfaceEnds,
+	int bodyStart)
+ */
+public void enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
+	char[] name, int nameStart, int nameEnd, char[][] superinterfaces,
+	int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {
+
+	enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
+		name, nameStart, nameEnd, null, -1, -1, superinterfaces,
+		superinterfaceStarts, superinterfaceEnds, bodyStart, false);
+}
+/**
+ * @see IDocumentElementRequestor#enterMethod(
+	int declarationStart,
+	int[] javaDocPositions,
+	int modifiers,
+	int modifiersStart,
+	char[] returnType,
+	int returnTypeStart,
+	int returnTypeEnd,
+ 	int returnTypeDimensionCount,
+	char[] name,
+	int nameStart,
+	int nameEnd,
+	char[][] parameterTypes,
+	int [] parameterTypeStarts,
+	int [] parameterTypeEnds,
+	char[][] parameterNames,
+	int [] parameterNameStarts,
+	int [] parameterNameEnds,
+	int parametersEnd,
+	int extendedReturnTypeDimensionCount,
+	int extendedReturnTypeDimensionEnd,
+	char[][] exceptionTypes,
+	int [] exceptionTypeStarts,
+	int [] exceptionTypeEnds,
+	int bodyStart)
+ */
+public void enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart,
+	char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount,
+	char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
+	int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts,
+	int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount,
+	int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts,
+	int[] exceptionTypeEnds, int bodyStart) {
+	enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart,
+		returnType, returnTypeStart, returnTypeEnd, returnTypeDimensionCount,
+		name, nameStart, nameEnd, parameterTypes, parameterTypeStarts,
+		parameterTypeEnds, parameterNames, parameterNameStarts,
+		parameterNameEnds, parametersEnd, extendedReturnTypeDimensionCount,
+		extendedReturnTypeDimensionEnd, exceptionTypes, exceptionTypeStarts,
+		exceptionTypeEnds, bodyStart,false);
+}
+
+protected void enterType(int declarationStart, int[] javaDocPositions,
+	int modifiers, int modifiersStart, int keywordStart, char[] name,
+	int nameStart, int nameEnd, char[] superclass, int superclassStart,
+	int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts,
+	int[] superinterfaceEnds, int bodyStart, boolean isClass) {
+	if (this.fBuildingType) {
+		int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit
+		int[] commentRange = {-1, -1};
+		if (javaDocPositions != null) {
+			int length = javaDocPositions.length;
+			commentRange[0] = javaDocPositions[length - 2];  // get last javadoc comment (see bug 68772)
+			commentRange[1] = javaDocPositions[length - 1];
+		}
+		int[] modifiersRange = {-1, -1};
+		if (modifiersStart > -1) {
+			modifiersRange[0] = modifiersStart;
+			modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1 : -1;
+		}
+		int[] typeKeywordRange = {keywordStart, nameStart - 1};
+		int[] nameRange = new int[] {nameStart, nameEnd};
+		int[] extendsKeywordRange = {-1, -1};
+		int[] superclassRange = {-1, -1};
+		int[] implementsKeywordRange = {-1, -1};
+		int[] interfacesRange = {-1, -1};
+		if (isClass) {
+			if (superclass != null) {
+				extendsKeywordRange[0] = nameEnd + 1;
+				extendsKeywordRange[1] = superclassStart - 1;
+				superclassRange[0] = superclassStart;
+				superclassRange[1] = superclassEnd;
+			}
+			if (superinterfaces != null && superinterfaces.length > 0) {
+				superclassRange[1] = superclassEnd;
+				if (superclassEnd > -1) {
+					implementsKeywordRange[0] = superclassEnd + 1;
+				} else {
+					implementsKeywordRange[0] = nameEnd + 1;
+				}
+				implementsKeywordRange[1] = superinterfaceStarts[0] - 1;
+				interfacesRange[0] = superinterfaceStarts[0];
+				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
+			}
+		} else {
+			if (superinterfaces != null && superinterfaces.length > 0) {
+				extendsKeywordRange[0] = nameEnd + 1;
+				extendsKeywordRange[1] = superinterfaceStarts[0] - 1;
+				interfacesRange[0] = superinterfaceStarts[0];
+				interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
+			}
+		}
+		int[] openBodyRange = {bodyStart, -1}; // fixed by setTypeRanges(DOMNode)
+		int[] closeBodyRange = {-1, -1}; // will be fixed in exit
+		this.fNode = new DOMType(this.fDocument, sourceRange, new String(name), nameRange, commentRange,
+			modifiers, modifiersRange, typeKeywordRange, superclassRange, extendsKeywordRange,
+			CharOperation.charArrayToStringArray(superinterfaces), interfacesRange,
+			implementsKeywordRange, openBodyRange,
+			closeBodyRange, isClass);
+		addChild(this.fNode);
+		this.fStack.push(this.fNode);
+	}
+}
+/**
+ * Finishes the configuration of the constructors and methods.
+ *
+ * @param bodyEnd - a source position corresponding to the closing bracket of the method
+ * @param declarationEnd - a source position corresponding to the end of the method
+ *		declaration.  This can include whitespace and comments following the closing bracket.
+ */
+protected void exitAbstractMethod(int bodyEnd, int declarationEnd) {
+	DOMMethod method = (DOMMethod) this.fStack.pop();
+	method.setSourceRangeEnd(declarationEnd);
+	method.setBodyRangeEnd(bodyEnd + 1);
+	this.fNode = method;
+	if (this.fBuildingSingleMember) {
+		this.fFinishedSingleMember= true;
+	}
+}
+/**
+ * Finishes the configuration of the class DOM object which
+ * was created by a previous enterClass call.
+ *
+ * @see IDocumentElementRequestor#exitClass(int, int)
+ */
+public void exitClass(int bodyEnd, int declarationEnd) {
+	exitType(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the method DOM object which
+ * was created by a previous enterConstructor call.
+ *
+ * @see IDocumentElementRequestor#exitConstructor(int, int)
+ */
+public void exitConstructor(int bodyEnd, int declarationEnd) {
+	exitAbstractMethod(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the field DOM object which
+ * was created by a previous enterField call.
+ *
+ * @see IDocumentElementRequestor#exitField(int, int)
+ */
+public void exitField(int bodyEnd, int declarationEnd) {
+	DOMField field = (DOMField)this.fStack.pop();
+	if (field.getEndPosition() < declarationEnd) {
+		field.setSourceRangeEnd(declarationEnd);
+		int nameEnd = field.fNameRange[1];
+		if (nameEnd < bodyEnd) {
+			/* see 1FVIIV8 - obtain initializer range */
+			String initializer = new String(this.fDocument, nameEnd + 1, bodyEnd - nameEnd);
+			int index = initializer.indexOf('=');
+			if (index > -1) {
+				field.setHasInitializer(true);
+				field.setInitializerRange(nameEnd + index + 2, bodyEnd);
+			}
+		}
+	}
+	this.fFieldCount++;
+	this.fNode = field;
+	if (this.fBuildingSingleMember) {
+		this.fFinishedSingleMember= true;
+	}
+}
+/**
+ * Finishes the configuration of the interface DOM object which
+ * was created by a previous enterInterface call.
+ *
+ * @see IDocumentElementRequestor#exitInterface(int, int)
+ */
+public void exitInterface(int bodyEnd, int declarationEnd) {
+	exitType(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the method DOM object which
+ * was created by a previous enterMethod call.
+ *
+ * @see IDocumentElementRequestor#exitMethod(int, int)
+ */
+public void exitMethod(int bodyEnd, int declarationEnd) {
+	exitAbstractMethod(bodyEnd, declarationEnd);
+}
+/**
+ * Creates a new parser.
+ */
+protected DocumentElementParser getParser(Map settings) {
+	return new DocumentElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings));
+}
+/**
+ * Initializes the builder to create a document fragment.
+ *
+ * @param sourceCode - the document containing the source code to be analyzed
+ * @param buildingCompilationUnit - true if a the document is being analyzed to
+ *		create a compilation unit, otherwise false
+ * @param buildingType - true if the document is being analyzed to create a
+ *		type or compilation unit
+ * @param singleMember - true if building a single member
+ */
+protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember) {
+	super.initializeBuild(sourceCode, buildingCompilationUnit, buildingType);
+	this.fBuildingSingleMember= singleMember;
+	this.fFinishedSingleMember= false;
+
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java
new file mode 100644
index 0000000..e82398a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * DOMCompilation unit provides an implementation of IDOMCompilationUnit.
+ *
+ * @see IDOMCompilationUnit
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+class DOMCompilationUnit extends DOMNode implements IDOMCompilationUnit, SuffixConstants {
+
+	/**
+	 * The comment and/or whitespace preceding the
+	 * first document fragment in this compilation
+	 * unit.
+	 */
+	protected String fHeader;
+/**
+ * Creates a new empty COMPILATION_UNIT document fragment.
+ */
+DOMCompilationUnit() {
+	this.fHeader=""; //$NON-NLS-1$
+}
+/**
+ * Creates a new COMPILATION_UNIT on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		A compilation unit's source range is the entire document -
+ *		the first integer is zero, and the second integer is the position
+ *		of the last character in the document.
+ */
+DOMCompilationUnit(char[] document, int[] sourceRange) {
+	super(document, sourceRange, null, new int[]{-1, -1});
+	this.fHeader = ""; //$NON-NLS-1$
+}
+/**
+ * @see DOMNode#appendContents(CharArrayBuffer)
+ */
+protected void appendFragmentedContents(CharArrayBuffer buffer) {
+	buffer.append(getHeader());
+	appendContentsOfChildren(buffer);
+}
+/**
+ * @see IDOMNode#canHaveChildren()
+ */
+public boolean canHaveChildren() {
+	return true;
+}
+/**
+ * @see IDOMCompilationUnit#getHeader()
+ */
+public String getHeader() {
+	return this.fHeader;
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
+		return ((IPackageFragment)parent).getCompilationUnit(getName());
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see IDOMCompilationUnit#getName()
+ */
+public String getName() {
+	IDOMType topLevelType= null;
+	IDOMType firstType= null;
+	IDOMNode child= this.fFirstChild;
+	while (child != null) {
+		if (child.getNodeType() == IDOMNode.TYPE) {
+			IDOMType type= (IDOMType)child;
+			if (firstType == null) {
+				firstType= type;
+			}
+			if (Flags.isPublic(type.getFlags())) {
+				topLevelType= type;
+				break;
+			}
+		}
+		child= child.getNextNode();
+	}
+	if (topLevelType == null) {
+		topLevelType= firstType;
+	}
+	if (topLevelType != null) {
+		return topLevelType.getName() + Util.defaultJavaExtension();
+	} else {
+		return null;
+	}
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.COMPILATION_UNIT;
+}
+/**
+ * Sets the header
+ */
+protected void initalizeHeader() {
+	DOMNode child = (DOMNode)getFirstChild();
+	if (child != null) {
+		int childStart = child.getStartPosition();
+		if (childStart > 1) {
+			setHeader(new String(this.fDocument, 0, childStart));
+		}
+	}
+}
+/**
+ * @see IDOMNode#isAllowableChild(IDOMNode)
+ */
+public boolean isAllowableChild(IDOMNode node) {
+	if (node != null) {
+		int type= node.getNodeType();
+		return type == IDOMNode.PACKAGE || type == IDOMNode.IMPORT || type == IDOMNode.TYPE;
+	} else {
+		return false;
+	}
+
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMCompilationUnit();
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s source positions to include whitespace preceeding
+ * the node on the line on which the node starts, and all whitespace after the node up to
+ * the next node's start
+ */
+void normalize(ILineStartFinder finder) {
+	super.normalize(finder);
+	initalizeHeader();
+}
+/**
+ * @see IDOMCompilationUnit#setHeader(String)
+ */
+public void setHeader(String comment) {
+	this.fHeader= comment;
+	fragment();
+}
+/**
+ * @see IDOMCompilationUnit#setName(String)
+ */
+public void setName(String name) {
+	// nothing to do
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	this.fHeader= ((DOMCompilationUnit)node).fHeader;
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "COMPILATION_UNIT: " + getName(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
new file mode 100644
index 0000000..85848bb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
@@ -0,0 +1,622 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Enumeration;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * DOMField provides an implementation of IDOMField.
+ *
+ * @see IDOMField
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+class DOMField extends DOMMember implements IDOMField {
+
+	/**
+	 * Contains the type of the field when the type
+	 * has been altered from the contents in the
+	 * document, otherwise <code>null</code>.
+	 */
+	protected String fType;
+
+	/**
+	 * The original inclusive source range of the
+	 * field's type in the document.
+	 */
+	protected int[] fTypeRange;
+
+	/**
+	 * The contents of the initializer when the
+	 * initializer has been altered from the
+	 * original state in the document, otherwise
+	 * <code>null</code>.
+	 */
+	protected String fInitializer;
+
+	/**
+	 * The original inclusive source range of the
+	 * initializer in the document.
+	 */
+	protected int[] fInitializerRange;
+
+/**
+ * Constructs an empty field node.
+ */
+DOMField() {
+	// Constructs an empty field node
+}
+/**
+ * Creates a new detailed FIELD document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this field,
+ * 		corresponding to VariableDeclaratorId (JLS 8.3).
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might follow the name.
+ * @param commentRange - a two element array describing the comments that precede
+ *		the member declaration. The first matches the start of this node's
+ *		sourceRange, and the second is the new-line or first non-whitespace
+ *		character following the last comment. If no comments are present,
+ *		this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *		modifiers for this member within its source range. The first integer
+ *		is the first character of the first modifier for this member, and
+ *		the second integer is the last whitespace character preceeding the
+ *		next part of this member declaration. If there are no modifiers present
+ *		in this node's source code (that is, package default visibility), this array
+ *		contains two -1's.
+ * @param typeRange - a two element array describing the location of the
+ *		typeName in the document - the positions of the first and last characters
+ *		of the typeName.
+ * @param type - the type of the field, in normalized form, as defined in
+ *      Type in Field Declaration (JLS 8.3)
+ * @param hasInitializer - true if this field declaration includes an initializer,
+ *		otherwise false
+ * @param initRange - a two element array describing the location of the initializer
+ *		in the declaration. The first integer is the position of the character
+ *		following the equals sign, and the position of the last character is the last
+ *		in the initializer. If this field has no initializer, this array contains
+ *		two -1's.
+ * @param isVariableDeclarator - true if the field is a seconday variable declarator
+ * 		for a previous field declaration.
+ */
+DOMField(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, String type, boolean hasInitializer, int[] initRange, boolean isVariableDeclarator) {
+	super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange);
+
+	this.fType= type;
+	this.fTypeRange= typeRange;
+	setHasInitializer(hasInitializer);
+	this.fInitializerRange= initRange;
+	setIsVariableDeclarator(isVariableDeclarator);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+
+}
+/**
+ * Creates a new simple FIELD document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this field,
+ * 		corresponding to VariableDeclaratorId (JLS 8.3).
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might follow the name.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param type - the type of the field, in normalized form, as defined in
+ *      Type in Field Declaration (JLS 8.3)
+ * @param isVariableDeclarator - true if the field is a seconday variable declarator
+ * 		for a previous field declaration.
+ */
+DOMField(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String type, boolean isVariableDeclarator) {
+	this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, new int[] {-1, -1}, type, false, new int[] {-1, -1}, isVariableDeclarator);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * Appends this member's body contents to the given CharArrayBuffer.
+ * Body contents include the member body and any trailing whitespace.
+ *
+ * <p>A field does not have a body.
+ *
+ * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
+ */
+protected void appendMemberBodyContents(CharArrayBuffer buffer) {
+	// nothing to do
+}
+/**
+ * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer)
+ */
+protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {
+
+	if (isVariableDeclarator()) {
+		buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+	} else {
+		buffer
+			.append(getTypeContents())
+			.append(this.fDocument, this.fTypeRange[1] + 1, this.fNameRange[0] - this.fTypeRange[1] - 1);
+	}
+
+	buffer.append(getNameContents());
+	if (hasInitializer()) {
+		if (this.fInitializerRange[0] < 0) {
+			buffer
+				.append('=')
+				.append(this.fInitializer)
+				.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+		} else {
+			buffer
+				.append(this.fDocument, this.fNameRange[1] + 1, this.fInitializerRange[0] - this.fNameRange[1] - 1)
+				.append(getInitializer())
+				.append(this.fDocument, this.fInitializerRange[1] + 1, this.fSourceRange[1] - this.fInitializerRange[1]);
+		}
+	} else {
+		if (this.fInitializerRange[0] < 0) {
+			buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+		} else {
+			buffer.append(this.fDocument, this.fInitializerRange[1] + 1, this.fSourceRange[1] - this.fInitializerRange[1]);
+		}
+	}
+
+}
+/**
+ * Appends this member's header contents to the given CharArrayBuffer.
+ * Header contents include any preceding comments and modifiers.
+ *
+ * <p>If this field is a secondary variable declarator, there is no header.
+ *
+ * @see DOMMember#appendMemberHeaderFragment(CharArrayBuffer)
+ */
+protected void appendMemberHeaderFragment(CharArrayBuffer buffer) {
+
+	if (isVariableDeclarator()) {
+		return;
+	} else {
+		super.appendMemberHeaderFragment(buffer);
+	}
+
+}
+/**
+ * @see DOMMember#appendSimpleContents(CharArrayBuffer)
+ */
+protected void appendSimpleContents(CharArrayBuffer buffer) {
+	// append eveything before my name
+	buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+	// append my name
+	buffer.append(this.fName);
+	// append everything after my name
+	buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+}
+/**
+ * Generates detailed source indexes for this node if possible.
+ *
+ * @exception DOMException if unable to generate detailed source indexes
+ * 	for this node
+ */
+protected void becomeDetailed() throws DOMException {
+	if (!isDetailed()) {
+		if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
+			DOMNode first = getFirstFieldDeclaration();
+			DOMNode last = getLastFieldDeclaration();
+			DOMNode node= first;
+			String source= first.getContents();
+			while (node != last) {
+				node= node.fNextNode;
+				source+=node.getContents();
+			}
+			DOMBuilder builder = new DOMBuilder();
+			IDOMField[] details= builder.createFields(source.toCharArray());
+			if (details.length == 0) {
+				throw new DOMException(Messages.dom_cannotDetail);
+			} else {
+				node= this;
+				for (int i= 0; i < details.length; i++) {
+					node.shareContents((DOMNode)details[i]);
+					node= node.fNextNode;
+				}
+			}
+		} else {
+			super.becomeDetailed();
+		}
+
+	}
+}
+/**
+ * @see IDOMNode#clone()
+ */
+public Object clone() {
+	if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
+		return getFactory().createField(new String(getSingleVariableDeclaratorContents()));
+	} else {
+		return super.clone();
+	}
+}
+/**
+ * Expands all variable declarators in this field declaration into
+ * stand-alone field declarations.
+ */
+protected void expand() {
+	if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
+		Enumeration siblings= new SiblingEnumeration(getFirstFieldDeclaration());
+		DOMField field= (DOMField)siblings.nextElement();
+		DOMNode next= field.fNextNode;
+		while (siblings.hasMoreElements() && (next instanceof DOMField) && (((DOMField)next).isVariableDeclarator())) {
+			field.localizeContents();
+			if (field.fParent != null) {
+				field.fParent.fragment();
+			}
+			field= (DOMField)siblings.nextElement();
+			next= field.fNextNode;
+		}
+		field.localizeContents();
+	}
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	if (isVariableDeclarator() || hasMultipleVariableDeclarators()) {
+		return (DOMNode)getFactory().createField(new String(getSingleVariableDeclaratorContents()));
+	} else {
+		return (DOMNode)getFactory().createField(getContents());
+	}
+}
+/**
+ * Returns the first field document fragment that defines
+ * the type for this variable declarator.
+ */
+protected DOMField getFirstFieldDeclaration() {
+	if (isVariableDeclarator()) {
+		return ((DOMField)this.fPreviousNode).getFirstFieldDeclaration();
+	} else {
+		return this;
+	}
+}
+/**
+ * @see IDOMField#getInitializer()
+ */
+public String getInitializer() {
+	becomeDetailed();
+	if (hasInitializer()) {
+		if (this.fInitializer != null) {
+			return this.fInitializer;
+		} else {
+			return new String(this.fDocument, this.fInitializerRange[0], this.fInitializerRange[1] + 1 - this.fInitializerRange[0]);
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.TYPE) {
+		return ((IType)parent).getField(getName());
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * Returns the last field document fragment in this muli-declarator statement.
+ */
+protected DOMField getLastFieldDeclaration() {
+	DOMField field = this;
+	while (field.isVariableDeclarator() || field.hasMultipleVariableDeclarators()) {
+		if (field.fNextNode instanceof DOMField && ((DOMField)field.fNextNode).isVariableDeclarator()) {
+			field= (DOMField)field.fNextNode;
+		} else {
+			break;
+		}
+	}
+	return field;
+}
+/**
+ * @see DOMMember#getMemberDeclarationStartPosition()
+ */
+protected int getMemberDeclarationStartPosition() {
+	return this.fTypeRange[0];
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.FIELD;
+}
+/**
+ * Returns a String representing this field declaration as a field
+ * declaration with one variable declarator.
+ */
+protected char[] getSingleVariableDeclaratorContents() {
+
+
+	CharArrayBuffer buffer= new CharArrayBuffer();
+	DOMField first= getFirstFieldDeclaration();
+	if (first.isDetailed()) {
+		first.appendMemberHeaderFragment(buffer);
+		buffer.append(getType());
+		if (isVariableDeclarator()) {
+			buffer.append(' ');
+		} else {
+			buffer.append(this.fDocument, this.fTypeRange[1] + 1, this.fNameRange[0] - this.fTypeRange[1] - 1);
+		}
+	} else {
+		buffer.append(first.fDocument, first.fSourceRange[0], first.fNameRange[0] - first.fSourceRange[0]);
+	}
+
+	buffer.append(getName());
+	if (hasInitializer()) {
+		if (this.fInitializerRange[0] < 0) {
+			buffer
+				.append('=')
+				.append(this.fInitializer)
+				.append(';')
+				.append(Util.getLineSeparator(buffer.toString(), null));
+		} else {
+			buffer
+				.append(this.fDocument, this.fNameRange[1] + 1, this.fInitializerRange[0] - this.fNameRange[1] - 1)
+				.append(getInitializer())
+				.append(';')
+				.append(Util.getLineSeparator(buffer.toString(), null));
+		}
+	} else {
+		buffer.append(';').append(Util.getLineSeparator(buffer.toString(), null));
+	}
+	return buffer.getContents();
+}
+/**
+ * @see IDOMField#getType()
+ */
+public String getType() {
+	return this.fType;
+}
+/**
+ * Returns the souce code to be used for this
+ * field's type.
+ */
+protected char[] getTypeContents() {
+	if (isTypeAltered()) {
+		return this.fType.toCharArray();
+	} else {
+		return CharOperation.subarray(this.fDocument, this.fTypeRange[0], this.fTypeRange[1] + 1);
+	}
+}
+/**
+ * Returns true if this field has an initializer expression,
+ * otherwise false.
+ */
+protected boolean hasInitializer() {
+	return getMask(MASK_FIELD_HAS_INITIALIZER);
+}
+/**
+ * Returns true is this field declarations has more than one
+ * variable declarator, otherwise false;
+ */
+protected boolean hasMultipleVariableDeclarators() {
+	return this.fNextNode != null && (this.fNextNode instanceof DOMField) &&
+		((DOMField)this.fNextNode).isVariableDeclarator();
+}
+/**
+ * Inserts the given un-parented node as a sibling of this node, immediately before
+ * this node. Once inserted, the sibling is only dependent on this document fragment.
+ *
+ * <p>When a sibling is inserted before a variable declarator, it must first
+ * be expanded.
+ *
+ * @see IDOMNode#insertSibling(IDOMNode)
+ */
+public void insertSibling(IDOMNode sibling) throws IllegalArgumentException, DOMException {
+	if (isVariableDeclarator()) {
+		expand();
+	}
+	super.insertSibling(sibling);
+}
+/**
+ * Returns true if this field's type has been altered
+ * from the original document contents.
+ */
+protected boolean isTypeAltered() {
+	return getMask(MASK_FIELD_TYPE_ALTERED);
+}
+/**
+ * Returns true if this field is declared as a secondary variable
+ * declarator for a previous field declaration.
+ */
+protected boolean isVariableDeclarator() {
+	return getMask(MASK_FIELD_IS_VARIABLE_DECLARATOR);
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMField();
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s end position.
+ */
+void normalizeEndPosition(ILineStartFinder finder, DOMNode next) {
+	if (next == null) {
+		// this node's end position includes all of the characters up
+		// to the end of the enclosing node
+		DOMNode parent = (DOMNode) getParent();
+		if (parent == null || parent instanceof DOMCompilationUnit) {
+			setSourceRangeEnd(this.fDocument.length - 1);
+		} else {
+			// parent is a type
+			int temp = ((DOMType)parent).getCloseBodyPosition() - 1;
+			setSourceRangeEnd(temp);
+			this.fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
+		}
+	} else {
+		// this node's end position is just before the start of the next node
+		// unless the next node is a field that is declared along with this one
+		int temp = next.getStartPosition() - 1;
+		this.fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
+
+		next.normalizeStartPosition(getEndPosition(), finder);
+		if (next instanceof DOMField) {
+			DOMField field = (DOMField) next;
+			if (field.isVariableDeclarator() && this.fTypeRange[0] == field.fTypeRange[0])
+				return;
+		}
+		setSourceRangeEnd(next.getStartPosition() - 1);
+	}
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s start position.
+ */
+void normalizeStartPosition(int endPosition, ILineStartFinder finder) {
+	if (isVariableDeclarator()) {
+		// start position is end of last element
+		setStartPosition(this.fPreviousNode.getEndPosition() + 1);
+	} else {
+		super.normalizeStartPosition(endPosition, finder);
+	}
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	super.offset(offset);
+	offsetRange(this.fInitializerRange, offset);
+	offsetRange(this.fTypeRange, offset);
+}
+/**
+ * Separates this node from its parent and siblings, maintaining any ties that
+ * this node has to the underlying document fragment.
+ *
+ * <p>When a field with multiple declarators is removed, its declaration
+ * must first be expanded.
+ *
+ * @see IDOMNode#remove()
+ */
+public void remove() {
+	expand();
+	super.remove();
+}
+/**
+ * @see IDOMMember#setComment(String)
+ */
+public void setComment(String comment) {
+	expand();
+	super.setComment(comment);
+}
+/**
+ * @see IDOMMember#setFlags(int)
+ */
+public void setFlags(int flags) {
+	expand();
+	super.setFlags(flags);
+}
+/**
+ * Sets the state of this field declaration as having
+ * an initializer expression.
+ */
+protected void setHasInitializer(boolean hasInitializer) {
+	setMask(MASK_FIELD_HAS_INITIALIZER, hasInitializer);
+}
+/**
+ * @see IDOMField#setInitializer(String)
+ */
+public void setInitializer(String initializer) {
+	becomeDetailed();
+	fragment();
+	setHasInitializer(initializer != null);
+	this.fInitializer= initializer;
+}
+/**
+ * Sets the initializer range.
+ */
+void setInitializerRange(int start, int end) {
+	this.fInitializerRange[0] = start;
+	this.fInitializerRange[1] = end;
+}
+/**
+ * Sets the state of this field declaration as being a
+ * secondary variable declarator for a previous field
+ * declaration.
+ */
+protected void setIsVariableDeclarator(boolean isVariableDeclarator) {
+	setMask(MASK_FIELD_IS_VARIABLE_DECLARATOR, isVariableDeclarator);
+}
+/**
+ * @see IDOMField#setName(String)
+ */
+public void setName(String name) throws IllegalArgumentException {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	} else {
+		super.setName(name);
+		setTypeAltered(true);
+	}
+}
+/**
+ * @see IDOMField#setType(String)
+ */
+public void setType(String typeName) throws IllegalArgumentException {
+	if (typeName == null) {
+		throw new IllegalArgumentException(Messages.element_nullType);
+	}
+	becomeDetailed();
+	expand();
+	fragment();
+	setTypeAltered(true);
+	setNameAltered(true);
+	this.fType= typeName;
+}
+/**
+ * Sets the state of this field declaration as having
+ * the field type altered from the original document.
+ */
+protected void setTypeAltered(boolean typeAltered) {
+	setMask(MASK_FIELD_TYPE_ALTERED, typeAltered);
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	DOMField field= (DOMField)node;
+	this.fInitializer= field.fInitializer;
+	this.fInitializerRange= rangeCopy(field.fInitializerRange);
+	this.fType= field.fType;
+	this.fTypeRange= rangeCopy(field.fTypeRange);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "FIELD: " + getName(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
new file mode 100644
index 0000000..a11e25f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * DOMImport provides an implementation of IDOMImport.
+ *
+ * @see IDOMImport
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+// TODO (jerome) - add implementation support for 1.5 features
+class DOMImport extends DOMNode implements IDOMImport {
+
+	/**
+	 * Indicates if this import is an on demand type import
+	 */
+	protected boolean fOnDemand;
+
+	/**
+	 * Modifiers for this import.
+	 * @since 3.0
+	 */
+	protected int fFlags = Flags.AccDefault;
+
+/**
+ * Creates a new empty IMPORT node.
+ */
+DOMImport() {
+	this.fName = "java.lang.*"; //$NON-NLS-1$
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+}
+/**
+ * Creates a new detailed IMPORT document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ * @param onDemand - indicates if this import is an on demand style import
+ */
+DOMImport(char[] document, int[] sourceRange, String name, int[] nameRange, boolean onDemand, int modifiers) {
+	super(document, sourceRange, name, nameRange);
+	this.fOnDemand = onDemand;
+	this.fFlags = modifiers;
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+}
+/**
+ * Creates a new simple IMPORT document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param onDemand - indicates if this import is an on demand style import
+ */
+DOMImport(char[] document, int[] sourceRange, String name, boolean onDemand, int modifiers) {
+	this(document, sourceRange, name, new int[] {-1, -1}, onDemand, modifiers);
+	this.fOnDemand = onDemand;
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * @see DOMNode#appendFragmentedContents(CharArrayBuffer)
+ */
+protected void appendFragmentedContents(CharArrayBuffer buffer) {
+	if (this.fNameRange[0] < 0) {
+		buffer
+			.append("import ") //$NON-NLS-1$
+			.append(this.fName)
+			.append(';')
+			.append(Util.getLineSeparator(buffer.toString(), null));
+	} else {
+		buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+		//buffer.append(fDocument, fNameRange[0], fNameRange[1] - fNameRange[0] + 1);
+		buffer.append(this.fName);
+		buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+	}
+}
+/**
+ * @see IDOMNode#getContents()
+ */
+public String getContents() {
+	if (this.fName == null) {
+		return null;
+	} else {
+		return super.getContents();
+	}
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	return (DOMNode)getFactory().createImport(getContents());
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
+		return ((ICompilationUnit)parent).getImport(getName());
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.IMPORT;
+}
+/**
+ * @see IDOMImport#isOnDemand()
+ */
+public boolean isOnDemand() {
+	return this.fOnDemand;
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMImport();
+}
+/**
+ * @see IDOMNode#setName(String)
+ */
+public void setName(String name) {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	}
+	becomeDetailed();
+	super.setName(name);
+	this.fOnDemand = name.endsWith(".*"); //$NON-NLS-1$
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "IMPORT: " + getName(); //$NON-NLS-1$
+}
+
+/**
+ * @see IDOMImport#getFlags()
+ * @since 3.0
+ */
+public int getFlags() {
+	return this.fFlags;
+}
+
+/**
+ * @see IDOMImport#setFlags(int)
+ * @since 3.0
+ */
+public void setFlags(int flags) {
+	this.fFlags = flags;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
new file mode 100644
index 0000000..085b38c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * DOMInitializer provides an implementation of IDOMInitializer.
+ *
+ * @see IDOMInitializer
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+class DOMInitializer extends DOMMember implements IDOMInitializer {
+
+	/**
+	 * The contents of the initializer's body when the
+	 * body has been altered from the contents in the
+	 * document, otherwise <code>null</code>.
+	 */
+	protected String fBody;
+
+	/**
+	 * The original inclusive source range of the
+	 * body in the document.
+	 */
+	protected int[]  fBodyRange;
+
+/**
+ * Constructs an empty initializer node.
+ */
+DOMInitializer() {
+	// Constructs an empty initializer node
+}
+/**
+ * Creates a new detailed INITIALIZER document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param commentRange - a two element array describing the comments that precede
+ *		the member declaration. The first matches the start of this node's
+ *		sourceRange, and the second is the new-line or first non-whitespace
+ *		character following the last comment. If no comments are present,
+ *		this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *		modifiers for this member within its source range. The first integer
+ *		is the first character of the first modifier for this member, and
+ *		the second integer is the last whitespace character preceeding the
+ *		next part of this member declaration. If there are no modifiers present
+ *		in this node's source code (that is, package default visibility), this array
+ *		contains two -1's.
+ * @param bodyStartPosition - the position of the open brace of the body
+ * 		of this initialzer.
+ */
+DOMInitializer(char[] document, int[] sourceRange, int[] commentRange, int flags, int[] modifierRange, int bodyStartPosition) {
+	super(document, sourceRange, null, new int[]{-1, -1}, commentRange, flags, modifierRange);
+	this.fBodyRange= new int[2];
+	this.fBodyRange[0]= bodyStartPosition;
+	this.fBodyRange[1]= sourceRange[1];
+	setHasBody(true);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+}
+/**
+ * Creates a new simple INITIALIZER document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ */
+DOMInitializer(char[] document, int[] sourceRange, int flags) {
+	this(document, sourceRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, -1);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+
+}
+/**
+ * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
+ */
+protected void appendMemberBodyContents(CharArrayBuffer buffer) {
+	if (hasBody()) {
+		buffer
+			.append(getBody())
+			.append(this.fDocument, this.fBodyRange[1] + 1, this.fSourceRange[1] - this.fBodyRange[1]);
+	} else {
+		buffer.append("{}").append(Util.getLineSeparator(buffer.toString(), null)); //$NON-NLS-1$
+	}
+}
+/**
+ * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer)
+ */
+protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {
+	// nothing to do
+}
+/**
+ * @see DOMMember#appendSimpleContents(CharArrayBuffer)
+ */
+protected void appendSimpleContents(CharArrayBuffer buffer) {
+	// append eveything before my name
+	buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+	// append my name
+	buffer.append(this.fName);
+	// append everything after my name
+	buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+}
+/**
+ * @see IDOMInitializer#getBody()
+ */
+public String getBody() {
+	becomeDetailed();
+	if (hasBody()) {
+		if (this.fBody != null) {
+			return this.fBody;
+		} else {
+			return new String(this.fDocument, this.fBodyRange[0], this.fBodyRange[1] + 1 - this.fBodyRange[0]);
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	return (DOMNode)getFactory().createInitializer(getContents());
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.TYPE) {
+		int count = 1;
+		IDOMNode previousNode = getPreviousNode();
+		while (previousNode != null) {
+			if (previousNode instanceof DOMInitializer) {
+				count++;
+			}
+			previousNode = previousNode.getPreviousNode();
+		}
+		return ((IType) parent).getInitializer(count);
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see DOMMember#getMemberDeclarationStartPosition()
+ */
+protected int getMemberDeclarationStartPosition() {
+	return this.fBodyRange[0];
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.INITIALIZER;
+}
+/**
+ * @see IDOMNode#isSignatureEqual(IDOMNode)
+ *
+ * <p>This method always answers false since an initializer
+ * does not have a signature.
+ */
+public boolean isSignatureEqual(IDOMNode node) {
+	return false;
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMInitializer();
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	super.offset(offset);
+	offsetRange(this.fBodyRange, offset);
+}
+/**
+ * @see IDOMInitializer#setBody(String)
+ */
+public void setBody(String body) {
+	becomeDetailed();
+	this.fBody= body;
+	setHasBody(body != null);
+	fragment();
+}
+/**
+ * @see IDOMInitializer#setName(String)
+ */
+public void setName(String name) {
+	// initializers have no name
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	DOMInitializer init= (DOMInitializer)node;
+	this.fBody= init.fBody;
+	this.fBodyRange= rangeCopy(init.fBodyRange);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "INITIALIZER"; //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java
new file mode 100644
index 0000000..ee8c7f8
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+/**
+ * DOMMember provides an implementation of IDOMMember.
+ *
+ * @see IDOMMember
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+abstract class DOMMember extends DOMNode implements IDOMMember {
+
+	/**
+	 * The modifier flags for this member that can be
+	 * analyzed with org.eclipse.jdt.core.Flags
+	 */
+	protected int    fFlags= 0;
+
+	/**
+	 * The member's comments when it has been altered from
+	 * the contents in the document, otherwise <code>null</code>.
+	 */
+	protected String fComment= null;
+
+	/**
+	 * The original inclusive source range of the
+	 * member's preceding comments in the document,
+	 * or -1's if the member did not originally have a
+	 * comment.
+	 */
+	 protected int[] fCommentRange;
+
+
+	/**
+	 * The member's modifiers textual representation when
+	 * the modifiers (flags) have been altered from
+	 * their original contents, otherwise <code>null</code>.
+	 */
+	 protected char[] fModifiers= null;
+
+	/**
+	 * The original inclusive source range of the
+	 * member's modifiers in the document, or -1's if
+	 * the member did not originally have modifiers in
+	 * the source code (that is, package default visibility).
+	 */
+	 protected int[] fModifierRange;
+
+/**
+ * Constructs an empty member node.
+ */
+DOMMember() {
+	// Constructs an empty member node
+}
+/**
+ * Creates a new member document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name.
+ * @param commentRange - a two element array describing the comments that precede
+ *		the member declaration. The first matches the start of this node's
+ *		sourceRange, and the second is the new-line or first non-whitespace
+ *		character following the last comment. If no comments are present,
+ *		this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *		modifiers for this member within its source range. The first integer
+ *		is the first character of the first modifier for this member, and
+ *		the second integer is the last whitespace character preceeding the
+ *		next part of this member declaration. If there are no modifiers present
+ *		in this node's source code (that is, package default visibility), this array
+ *		contains two -1's.
+ */
+DOMMember(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange) {
+	super(document, sourceRange, name, nameRange);
+	this.fFlags= flags;
+	this.fComment= null;
+	this.fCommentRange= commentRange;
+	this.fModifierRange= modifierRange;
+	setHasComment(commentRange[0] >= 0);
+}
+/**
+ * Appends the contents of this node to the given CharArrayBuffer, using
+ * the original document and indicies as a form for the current attribute values
+ * of this node.
+ *
+ * <p>To facilitate the implementation of generating contents for members,
+ * the content of members is split into three sections - the header,
+ * declaration, and body sections. The header section includes any preceding
+ * comments and modifiers. The declaration section includes the portion of
+ * the member declaration that follows any modifiers and precedes the
+ * member body. The body section includes the member body and any trailing
+ * whitespace.
+ *
+ * @see DOMNode#appendFragmentedContents(CharArrayBuffer)
+ */
+protected void appendFragmentedContents(CharArrayBuffer buffer) {
+	if (isDetailed()) {
+		appendMemberHeaderFragment(buffer);
+		appendMemberDeclarationContents(buffer);
+		appendMemberBodyContents(buffer);
+	} else {
+		appendSimpleContents(buffer);
+	}
+}
+/**
+ * Appends this member's body contents to the given CharArrayBuffer.
+ * Body contents include the member body and any trailing whitespace.
+ */
+protected abstract void appendMemberBodyContents(CharArrayBuffer buffer);
+/**
+ * Appends this member's declaration contents to the given CharArrayBuffer.
+ * The declaration contents includes the portion of this member that
+ * appears after any modifiers and precedes the body.
+ */
+protected abstract void appendMemberDeclarationContents(CharArrayBuffer buffer);
+/**
+ * Appends this member's header contents to the given CharArrayBuffer.
+ * Header contents include any preceding comments and modifiers.
+ */
+protected void appendMemberHeaderFragment(CharArrayBuffer buffer) {
+
+	int spaceStart, spaceEnd;
+
+	// space before comment
+	if (hasComment()) {
+		spaceStart= this.fSourceRange[0];
+		spaceEnd= this.fCommentRange[0];
+		if (spaceEnd > 0) {
+			buffer.append(this.fDocument, spaceStart, spaceEnd - spaceStart);
+		}
+	}
+
+	String fragment= getComment();
+	if (fragment != null) {
+		buffer.append(fragment);
+	}
+
+	if (this.fCommentRange[1] >= 0) {
+		spaceStart= this.fCommentRange[1] + 1;
+	} else {
+		spaceStart= this.fSourceRange[0];
+	}
+	if (this.fModifierRange[0] >= 0) {
+		spaceEnd= this.fModifierRange[0] - 1;
+	} else {
+		spaceEnd= getMemberDeclarationStartPosition() - 1;
+	}
+
+	if (spaceEnd >= spaceStart) {
+		buffer.append(this.fDocument, spaceStart, spaceEnd + 1 - spaceStart);
+	}
+	buffer.append(getModifiersText());
+
+}
+/**
+ * Appends the contents of this node to the given CharArrayBuffer, using
+ * the original document and indicies as a form for the current attribute values
+ * of this node. This method is called when this node is know not to have
+ * detailed source indexes.
+ */
+protected abstract void appendSimpleContents(CharArrayBuffer buffer);
+/**
+ * Returns a copy of the given array with the new element appended
+ * to the end of the array.
+ */
+protected String[] appendString(String[] list, String element) {
+	String[] copy= new String[list.length + 1];
+	System.arraycopy(list, 0, copy, 0, list.length);
+	copy[list.length]= element;
+	return copy;
+}
+/**
+ * Returns a <code>String</code> describing the modifiers for this member,
+ * ending with whitespace (if not empty). This value serves as a replacement
+ * value for the member's modifier range when the modifiers have been altered
+ * from their original contents.
+ */
+protected char[] generateFlags() {
+	char[] flags= Flags.toString(getFlags()).toCharArray();
+	if (flags.length == 0) {
+		return flags;
+	} else {
+		return CharOperation.concat(flags, new char[] {' '});
+	}
+}
+/**
+ * @see IDOMMember#getComment()
+ */
+public String getComment() {
+	becomeDetailed();
+	if (hasComment()) {
+		if (this.fComment != null) {
+			return this.fComment;
+		} else {
+			return new String(this.fDocument, this.fCommentRange[0], this.fCommentRange[1] + 1 - this.fCommentRange[0]);
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * @see IDOMMember#getFlags()
+ */
+public int getFlags() {
+	return this.fFlags;
+}
+/**
+ * Returns the location of the first character in the member's declaration
+ * section.
+ */
+protected abstract int getMemberDeclarationStartPosition();
+/**
+ * Returns the String to be used for this member's flags when
+ * generating contents - either the original contents in the document
+ * or the replacement value.
+ */
+protected char[] getModifiersText() {
+	if (this.fModifiers == null) {
+		if (this.fModifierRange[0] < 0) {
+			return null;
+		} else {
+			return CharOperation.subarray(this.fDocument, this.fModifierRange[0], this.fModifierRange[1] + 1);
+		}
+	} else {
+		return this.fModifiers;
+	}
+}
+/**
+ * Returns true if this member currently has a body.
+ */
+protected boolean hasBody() {
+	return getMask(MASK_HAS_BODY);
+}
+/**
+ * Returns true if this member currently has a comment.
+ */
+protected boolean hasComment() {
+	return getMask(MASK_HAS_COMMENT);
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	super.offset(offset);
+	offsetRange(this.fCommentRange, offset);
+	offsetRange(this.fModifierRange, offset);
+}
+/**
+ * @see IDOMMember#setComment(String)
+ */
+public void setComment(String comment) {
+	becomeDetailed();
+	this.fComment= comment;
+	fragment();
+	setHasComment(comment != null);
+	/* see 1FVIJAH */
+	if (comment != null && comment.indexOf("@deprecated") >= 0) { //$NON-NLS-1$
+		this.fFlags= this.fFlags | ClassFileConstants.AccDeprecated;
+		return;
+	}
+	this.fFlags= this.fFlags & (~ClassFileConstants.AccDeprecated);
+}
+/**
+ * @see IDOMMember#setFlags(int)
+ */
+public void setFlags(int flags) {
+	becomeDetailed();
+	if (Flags.isDeprecated(this.fFlags)) {
+		this.fFlags= flags | ClassFileConstants.AccDeprecated;
+	} else {
+		this.fFlags= flags & (~ClassFileConstants.AccDeprecated);
+	}
+	fragment();
+	this.fModifiers= generateFlags();
+}
+/**
+ * Sets the state of this member declaration as having
+ * a body.
+ */
+protected void setHasBody(boolean hasBody) {
+	setMask(MASK_HAS_BODY, hasBody);
+}
+/**
+ * Sets the state of this member declaration as having
+ * a preceding comment.
+ */
+protected void setHasComment(boolean hasComment) {
+	setMask(MASK_HAS_COMMENT, hasComment);
+}
+/**
+ * Sets the original position of the first character of this node's contents
+ * in its document. This method is only used during DOM creation while
+ * normalizing the source range of each node.
+ *
+ * Synchronize the start of the comment position with the start of the
+ * node.
+ */
+protected void setStartPosition(int start) {
+	if (this.fCommentRange[0] >= 0) {
+		this.fCommentRange[0]= start;
+	}
+	super.setStartPosition(start);
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	DOMMember member= (DOMMember)node;
+	this.fComment= member.fComment;
+	this.fCommentRange= rangeCopy(member.fCommentRange);
+	this.fFlags= member.fFlags;
+	this.fModifiers= member.fModifiers;
+	this.fModifierRange= rangeCopy(member.fModifierRange);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
new file mode 100644
index 0000000..a7020d6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
+/**
+ * DOMMethod provides an implementation of IDOMMethod.
+ *
+ * @see IDOMMethod
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+// TODO (jerome) - add implementation support for 1.5 features
+class DOMMethod extends DOMMember implements IDOMMethod {
+
+	/**
+	 * Contains the return type of the method when the
+	 * return type has been altered from the contents
+	 * in the document, otherwise <code>null</code>.
+	 */
+	protected String fReturnType;
+
+	/**
+	 * The original inclusive source range of the
+	 * method's return type in the document, or -1's
+	 * if no return type is present in the document.
+	 * If the return type of this method is qualified with
+	 * '[]' following the parameter list, this array has
+	 * four entries. In this case, the last two entries
+	 * of the array are the inclusive source range of
+	 * the array qualifiers.
+	 */
+	protected int[]  fReturnTypeRange;
+
+	/**
+	 * Contains the textual representation of the method's
+	 * parameter list, including open and closing parentheses
+	 * when the parameters had been altered from the contents
+	 * in the document, otherwise <code>null</code>.
+	 */
+	protected char[] fParameterList;
+
+	/**
+	 * The original inclusive source range of the
+	 * method's parameter list in the document.
+	 */
+	protected int[]  fParameterRange;
+
+	/**
+	 * Contains the textual representation of the method's
+	 * exception list when the exceptions had been altered
+	 * from the contents in the document, otherwise
+	 * <code>null</code>. The exception list is a comment
+	 * delimited list of exceptions, not including the "throws"
+	 * keyword.
+	 */
+	protected char[] fExceptionList;
+
+	/**
+	 * The original inclusive source range of the
+	 * method's exception list in the document.
+	 */
+	protected int[]  fExceptionRange;
+
+	/**
+	 * Contains the method's body when the body has
+	 * been altered from the contents in the document,
+	 * otherwise <code>null</code>. The body includes everything
+	 * between and including the enclosing braces, and trailing
+	 * whitespace.
+	 */
+	protected String fBody;
+
+	/**
+	 * The original inclusive source range of the
+	 * method's body.
+	 */
+	protected int[]  fBodyRange;
+
+
+	/**
+	 * Names of parameters in the method parameter list,
+	 * or <code>null</code> if the method has no parameters.
+	 */
+	protected String[] fParameterNames;
+
+	/**
+	 * Types of parameters in the method parameter list,
+	 * or <code>null</code> if the method has no parameters.
+	 */
+	protected String[] fParameterTypes;
+
+	/**
+	 * The exceptions the method throws, or <code>null</code>
+	 * if the method throws no exceptions.
+	 */
+	protected String[] fExceptions;
+
+	/**
+	 * The formal type parameters.
+	 * @since 3.0
+	 */
+	protected String[] fTypeParameters = CharOperation.NO_STRINGS;
+
+	/**
+	 * Default value for this attotation type member (only),
+	 * or <code>null</code> if none.
+	 * @since 3.0
+	 */
+	protected String fDefaultValue = null;
+
+/**
+ * Constructs an empty method node.
+ */
+DOMMethod() {
+	// Constructs an empty method node
+}
+/**
+ * Creates a new detailed METHOD document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ * @param commentRange - a two element array describing the comments that precede
+ *		the member declaration. The first matches the start of this node's
+ *		sourceRange, and the second is the new-line or first non-whitespace
+ *		character following the last comment. If no comments are present,
+ *		this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *		modifiers for this member within its source range. The first integer
+ *		is the first character of the first modifier for this member, and
+ *		the second integer is the last whitespace character preceeding the
+ *		next part of this member declaration. If there are no modifiers present
+ *		in this node's source code (that is, package default visibility), this array
+ *		contains two -1's.
+ * @param isConstructor - true if the method is a contructor, otherwise false
+ * @param returnType - the normalized return type of this method
+ * @param returnTypeRange - a two element array describing the location of the
+ *		return type within the method's source range. The first integer is is
+ *		the position of the first character in the return type, and the second
+ *		integer is the position of the last character in the return type.
+ *		For constructors, the contents of this array are -1's.
+ * 		If the return type of this method is qualified with '[]' following the
+ *		parameter list, this array has four entries. In this case, the last
+ *		two entries of the array are the inclusive source range of the array
+ *		qualifiers.
+ * @param parameterTypes - an array of parameter types in the method declaration
+ * 		or <code>null</code> if the method has no parameters
+ * @param parameterNames - an array of parameter names in the method declaration
+ * 		or <code>null</code> if the method has no parameters
+ * @param parameterRange - a two element array describing the location of the
+ * 		parameter list in the method. The first integer is the location of the
+ *		open parenthesis and the second integer is the location of the closing
+ *		parenthesis.
+ * @param exceptions - an array of the names of exceptions thrown by this method
+ *		or <code>null</code> if the method throws no exceptions
+ * @param exceptionRange - a two element array describing the location of the
+ * 		exception list in the method declaration. The first integer is the position
+ * 		of the first character in the first exception the method throws, and the
+ *		second integer is the position of the last character of the last exception
+ *		this method throws.
+ * @param bodyRange - a two element array describing the location of the method's body.
+ *		The first integer is the first character following the method's
+ *		parameter list, or exception list (if present). The second integer is the location
+ * 		of the last character in the method's source range.
+ */
+DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, boolean isConstructor, String returnType, int[] returnTypeRange, String[] parameterTypes, String[] parameterNames, int[] parameterRange, String[] exceptions, int[] exceptionRange, int[] bodyRange) {
+	super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange);
+
+	setMask(MASK_IS_CONSTRUCTOR, isConstructor);
+	this.fReturnType= returnType;
+	this.fReturnTypeRange= returnTypeRange;
+	this.fParameterTypes= parameterTypes;
+	this.fParameterNames= parameterNames;
+	this.fParameterRange= parameterRange;
+	this.fExceptionRange= exceptionRange;
+	this.fExceptions= exceptions;
+	setHasBody(true);
+	this.fBodyRange= bodyRange;
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+
+}
+/**
+ * Creates a new simple METHOD document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param isConstructor - true if the method is a contructor, otherwise false
+ * @param returnType - the normalized return type of this method
+ * @param parameterTypes - an array of parameter types in the method declaration
+ * 		or <code>null</code> if the method has no parameters
+ * @param parameterNames - an array of parameter names in the method declaration
+ * 		or <code>null</code> if the method has no parameters
+ * @param exceptions - an array of the names of exceptions thrown by this method
+ *		or <code>null</code> if the method throws no exceptions
+ */
+DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, boolean isConstructor, String returnType, String[] parameterTypes, String[] parameterNames, String[] exceptions) {
+	this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, new int[] {-1, -1}, isConstructor, returnType, new int[] {-1, -1}, parameterTypes, parameterNames, new int[] {-1, -1}, exceptions, new int[] {-1, -1}, new int[] {-1, -1});
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * @see IDOMMethod#addException(String)
+ */
+public void addException(String name) throws IllegalArgumentException {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.dom_nullExceptionType);
+	}
+	if (this.fExceptions == null) {
+		this.fExceptions= new String[1];
+		this.fExceptions[0]= name;
+	} else {
+		this.fExceptions= appendString(this.fExceptions, name);
+	}
+	setExceptions(this.fExceptions);
+}
+/**
+ * @see IDOMMethod#addParameter(String, String)
+ */
+public void addParameter(String type, String name) throws IllegalArgumentException {
+	if (type == null) {
+		throw new IllegalArgumentException(Messages.dom_nullTypeParameter);
+	}
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.dom_nullNameParameter);
+	}
+	if (this.fParameterNames == null) {
+		this.fParameterNames= new String[1];
+		this.fParameterNames[0]= name;
+	} else {
+		this.fParameterNames= appendString(this.fParameterNames, name);
+	}
+	if (this.fParameterTypes == null) {
+		this.fParameterTypes= new String[1];
+		this.fParameterTypes[0]= type;
+	} else {
+		this.fParameterTypes= appendString(this.fParameterTypes, type);
+	}
+	setParameters(this.fParameterTypes, this.fParameterNames);
+}
+/**
+ * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
+ */
+protected void appendMemberBodyContents(CharArrayBuffer buffer) {
+	if (this.fBody != null) {
+		buffer.append(this.fBody);
+	} else {
+		buffer.append(this.fDocument, this.fBodyRange[0], this.fBodyRange[1] + 1 - this.fBodyRange[0]);
+	}
+}
+/**
+ * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer)
+ */
+protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {
+
+	if (isConstructor()) {
+		buffer
+			.append(getConstructorName())
+			.append(this.fDocument, this.fNameRange[1] + 1, this.fParameterRange[0] - this.fNameRange[1] - 1);
+	} else {
+		buffer.append(getReturnTypeContents());
+		if (this.fReturnTypeRange[0] >= 0) {
+			buffer.append(this.fDocument, this.fReturnTypeRange[1] + 1, this.fNameRange[0] - this.fReturnTypeRange[1] - 1);
+		} else {
+			buffer.append(' ');
+		}
+		buffer
+			.append(getNameContents())
+			.append(this.fDocument, this.fNameRange[1] + 1, this.fParameterRange[0] - this.fNameRange[1] - 1);
+	}
+	if (this.fParameterList != null) {
+		buffer.append(this.fParameterList);
+	} else {
+		buffer.append(this.fDocument, this.fParameterRange[0], this.fParameterRange[1] + 1 - this.fParameterRange[0]);
+	}
+	int start;
+	if (hasTrailingArrayQualifier() && isReturnTypeAltered()) {
+		start= this.fReturnTypeRange[3] + 1;
+	} else {
+		start= this.fParameterRange[1] + 1;
+	}
+	if (this.fExceptions != null) {
+		// add 'throws' keyword
+		if (this.fExceptionRange[0] >= 0) {
+			buffer.append(this.fDocument, start, this.fExceptionRange[0] - start);
+		} else {
+			buffer.append(" throws "); //$NON-NLS-1$
+		}
+		// add exception list
+		if (this.fExceptionList != null) {
+			buffer.append(this.fExceptionList);
+			// add space before body
+			if (this.fExceptionRange[0] >= 0) {
+				buffer.append(this.fDocument, this.fExceptionRange[1] + 1, this.fBodyRange[0] - this.fExceptionRange[1] - 1);
+			} else {
+				buffer.append(this.fDocument, this.fParameterRange[1] + 1, this.fBodyRange[0] - this.fParameterRange[1] - 1);
+			}
+		} else {
+			// add list and space before body
+			buffer.append(this.fDocument, this.fExceptionRange[0], this.fBodyRange[0] - this.fExceptionRange[0]);
+		}
+	} else {
+		// add space before body
+		if (this.fExceptionRange[0] >= 0) {
+			buffer.append(this.fDocument, this.fExceptionRange[1] + 1, this.fBodyRange[0] - this.fExceptionRange[1] - 1);
+		} else {
+			buffer.append(this.fDocument, start, this.fBodyRange[0] - start);
+		}
+	}
+
+}
+/**
+ * @see DOMMember#appendSimpleContents(CharArrayBuffer)
+ */
+protected void appendSimpleContents(CharArrayBuffer buffer) {
+	// append eveything before my name
+	buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+	// append my name
+	if (isConstructor()) {
+		buffer.append(getConstructorName());
+	} else {
+		buffer.append(this.fName);
+	}
+	// append everything after my name
+	buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+}
+/**
+ * @see IDOMMethod#getBody()
+ */
+public String getBody() {
+	becomeDetailed();
+	if (hasBody()) {
+		if (this.fBody != null) {
+			return this.fBody;
+		} else {
+			return new String(this.fDocument, this.fBodyRange[0], this.fBodyRange[1] + 1 - this.fBodyRange[0]);
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * Returns the simple name of the enclsoing type for this constructor.
+ * If the constuctor is not currently enclosed in a type, the original
+ * name of the constructor as found in the documnent is returned.
+ */
+protected String getConstructorName() {
+
+	if (isConstructor()) {
+		if (getParent() != null) {
+			return getParent().getName();
+		} else {
+			// If there is no parent use the original name
+			return new String(getNameContents());
+		}
+	} else {
+		return null;
+	}
+
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	return (DOMNode)getFactory().createMethod(getContents());
+}
+/**
+ * @see IDOMMethod#getExceptions()
+ */
+public String[] getExceptions() {
+	return this.fExceptions;
+}
+protected char[] generateFlags() {
+	char[] flags= Flags.toString(getFlags() & ~Flags.AccVarargs).toCharArray();
+	if (flags.length == 0) {
+		return flags;
+	} else {
+		return CharOperation.concat(flags, new char[] {' '});
+	}
+}/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.TYPE) {
+		// translate parameter types to signatures
+		String[] sigs= null;
+		if (this.fParameterTypes != null) {
+			sigs= new String[this.fParameterTypes.length];
+			int i;
+			for (i= 0; i < this.fParameterTypes.length; i++) {
+				sigs[i]= Signature.createTypeSignature(this.fParameterTypes[i].toCharArray(), false);
+			}
+		}
+		String name= null;
+		if (isConstructor()) {
+			name= getConstructorName();
+		} else {
+			name= getName();
+		}
+		return ((IType)parent).getMethod(name, sigs);
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see DOMMember#getMemberDeclarationStartPosition()
+ */
+protected int getMemberDeclarationStartPosition() {
+	if (this.fReturnTypeRange[0] >= 0) {
+		return this.fReturnTypeRange[0];
+	} else {
+		return this.fNameRange[0];
+	}
+}
+/**
+ * @see IDOMNode#getName()
+ */
+public String getName() {
+	if (isConstructor()) {
+		return null;
+	} else {
+		return super.getName();
+	}
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.METHOD;
+}
+/**
+ * @see IDOMMethod#getParameterNames()
+ */
+public String[] getParameterNames() {
+	return this.fParameterNames;
+}
+/**
+ * @see IDOMMethod#getParameterTypes()
+ */
+public String[] getParameterTypes() {
+	return this.fParameterTypes;
+}
+/**
+ * @see IDOMMethod#getReturnType()
+ */
+public String getReturnType() {
+	if (isConstructor()) {
+		return null;
+	} else {
+		return this.fReturnType;
+	}
+}
+/**
+ * Returns the source code to be used for this method's return type
+ */
+protected char[] getReturnTypeContents() {
+	if (isConstructor()) {
+		return null;
+	} else {
+		if (isReturnTypeAltered()) {
+			return this.fReturnType.toCharArray();
+		} else {
+			return CharOperation.subarray(this.fDocument, this.fReturnTypeRange[0], this.fReturnTypeRange[1] + 1);
+		}
+
+	}
+}
+/**
+ * Returns true if this method's return type has
+ * array qualifiers ('[]') following the parameter list.
+ */
+protected boolean hasTrailingArrayQualifier() {
+	return this.fReturnTypeRange.length > 2;
+}
+/**
+ * @see IDOMMethod#isConstructor()
+ */
+public boolean isConstructor() {
+	return getMask(MASK_IS_CONSTRUCTOR);
+}
+/**
+ * Returns true if this method's return type has been altered
+ * from the original document contents.
+ */
+protected boolean isReturnTypeAltered() {
+	return getMask(MASK_RETURN_TYPE_ALTERED);
+}
+/**
+ * @see IDOMNode#isSignatureEqual(IDOMNode)
+ *
+ * <p>Two methods have equal signatures if there names are the same
+ * and their parameter types are the same.
+ */
+public boolean isSignatureEqual(IDOMNode node) {
+	boolean ok= node.getNodeType() == getNodeType();
+	if (ok) {
+		IDOMMethod method= (IDOMMethod)node;
+		ok = (isConstructor() && method.isConstructor()) ||
+			(!isConstructor() && !method.isConstructor());
+		if (ok && !isConstructor()) {
+			ok= getName().equals(method.getName());
+		}
+		if (!ok) {
+			return false;
+		}
+
+		String[] types= method.getParameterTypes();
+		if (this.fParameterTypes == null || this.fParameterTypes.length == 0) {
+			// this method has no parameters
+			if (types == null || types.length == 0) {
+				// the other method has no parameters either
+				return true;
+			}
+		} else {
+			// this method has parameters
+			if (types == null || types.length == 0) {
+				// the other method has no parameters
+				return false;
+			}
+			if (this.fParameterTypes.length != types.length) {
+				// the methods have a different number of parameters
+				return false;
+			}
+			int i;
+			for (i= 0; i < types.length; i++) {
+				if (!this.fParameterTypes[i].equals(types[i])) {
+					return false;
+				}
+			}
+			return true;
+		}
+	}
+	return false;
+
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMMethod();
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	super.offset(offset);
+	offsetRange(this.fBodyRange, offset);
+	offsetRange(this.fExceptionRange, offset);
+	offsetRange(this.fParameterRange, offset);
+	offsetRange(this.fReturnTypeRange, offset);
+}
+/**
+ * @see IDOMMethod#setBody
+ */
+public void setBody(String body) {
+	becomeDetailed();
+	fragment();
+	this.fBody= body;
+	setHasBody(body != null);
+	if (!hasBody()) {
+		this.fBody= ";" + Util.getLineSeparator(body, null); //$NON-NLS-1$
+	}
+}
+/**
+ * Sets the end of the body range
+ */
+void setBodyRangeEnd(int end) {
+	this.fBodyRange[1] = end;
+}
+/**
+ * @see IDOMMethod#setConstructor(boolean)
+ */
+public void setConstructor(boolean b) {
+	becomeDetailed();
+	setMask(MASK_IS_CONSTRUCTOR, b);
+	fragment();
+}
+/**
+ * @see IDOMMethod#setExceptions(String[])
+ */
+public void setExceptions(String[] names) {
+	becomeDetailed();
+	if (names == null || names.length == 0) {
+		this.fExceptions= null;
+	} else {
+		this.fExceptions= names;
+		CharArrayBuffer buffer = new CharArrayBuffer();
+		char[] comma = new char[] {',', ' '};
+		for (int i = 0, length = names.length; i < length; i++) {
+			if (i > 0)
+				buffer.append(comma);
+			buffer.append(names[i]);
+		}
+		this.fExceptionList= buffer.getContents();
+	}
+	fragment();
+}
+/**
+ * @see IDOMMethod#setName
+ */
+public void setName(String name) {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	} else {
+		super.setName(name);
+	}
+}
+/**
+ * @see IDOMMethod#setParameters(String[], String[])
+ */
+public void setParameters(String[] types, String[] names) throws IllegalArgumentException {
+	becomeDetailed();
+	if (types== null || names == null) {
+		if (types == null && names == null) {
+			this.fParameterTypes= null;
+			this.fParameterNames= null;
+			this.fParameterList= new char[] {'(',')'};
+		} else {
+			throw new IllegalArgumentException(Messages.dom_mismatchArgNamesAndTypes);
+		}
+	} else if (names.length != types.length) {
+		throw new IllegalArgumentException(Messages.dom_mismatchArgNamesAndTypes);
+	} else if (names.length == 0) {
+		setParameters(null, null);
+	} else {
+		this.fParameterNames= names;
+		this.fParameterTypes= types;
+		CharArrayBuffer parametersBuffer = new CharArrayBuffer();
+		parametersBuffer.append("("); //$NON-NLS-1$
+		char[] comma = new char[] {',', ' '};
+		for (int i = 0; i < names.length; i++) {
+			if (i > 0) {
+				parametersBuffer.append(comma);
+			}
+			parametersBuffer
+				.append(types[i])
+				.append(' ')
+				.append(names[i]);
+		}
+		parametersBuffer.append(')');
+		this.fParameterList= parametersBuffer.getContents();
+	}
+	fragment();
+}
+/**
+ * @see IDOMMethod#setReturnType(String)
+ */
+public void setReturnType(String name) throws IllegalArgumentException {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.dom_nullReturnType);
+	}
+	becomeDetailed();
+	fragment();
+	setReturnTypeAltered(true);
+	this.fReturnType= name;
+}
+/**
+ * Sets the state of this method declaration as having
+ * the return type altered from the original document.
+ */
+protected void setReturnTypeAltered(boolean typeAltered) {
+	setMask(MASK_RETURN_TYPE_ALTERED, typeAltered);
+}
+/**
+ */
+protected void setSourceRangeEnd(int end) {
+	super.setSourceRangeEnd(end);
+	this.fBodyRange[1]= end;
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	DOMMethod method= (DOMMethod)node;
+	this.fBody= method.fBody;
+	this.fBodyRange= rangeCopy(method.fBodyRange);
+	this.fExceptionList= method.fExceptionList;
+	this.fExceptionRange= rangeCopy(method.fExceptionRange);
+	this.fExceptions= method.fExceptions;
+	this.fParameterList= method.fParameterList;
+	this.fParameterNames= method.fParameterNames;
+	this.fParameterRange= rangeCopy(method.fParameterRange);
+	this.fParameterTypes= method.fParameterTypes;
+	this.fReturnType= method.fReturnType;
+	this.fReturnTypeRange= rangeCopy(method.fReturnTypeRange);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	if (isConstructor()) {
+		return "CONSTRUCTOR"; //$NON-NLS-1$
+	} else {
+		return "METHOD: " + getName(); //$NON-NLS-1$
+	}
+}
+
+/**
+ * @see IDOMMethod#setDefault(java.lang.String)
+ * @since 3.0
+ */
+public void setDefault(String defaultValue) {
+	this.fDefaultValue =  defaultValue;
+}
+
+/**
+ * @see IDOMMethod#getDefault()
+ * @since 3.0
+ */
+public String getDefault() {
+	return this.fDefaultValue;
+}
+
+/**
+ * @see IDOMMethod#getTypeParameters()
+ * @since 3.0
+ */
+public String[] getTypeParameters() {
+	return this.fTypeParameters;
+}
+
+/**
+ * @see IDOMMethod#setTypeParameters(java.lang.String[])
+ * @since 3.0
+ */
+public void setTypeParameters(String[] typeParameters) {
+	this.fTypeParameters = typeParameters;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java
new file mode 100644
index 0000000..c495929
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java
@@ -0,0 +1,969 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Enumeration;
+
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Messages;
+
+/**
+ * DOMNode provides an implementation for <code>IDOMNode</code>.
+ *
+ * <p>A node represents a document fragment. When a node is created, its
+ * contents are located in a contiguous range of a shared document. A shared
+ * document is a char array, and is shared in the sense that the contents of other
+ * document fragments may also be contained in the array.
+ *
+ * <p>A node maintains indicies of relevant portions of its contents
+ * in the shared document. Thus the original document and indicies create a
+ * form from which to generate the contents of the document fragment. As attributes
+ * of a node are changed, the node attempts to maintain the original formatting
+ * by only replacing relevant portions of the shared document with the value
+ * of new attributes (that is, filling in the form with replacement values).
+ *
+ * <p>When a node is first created, it is considered unfragmented. When any
+ * attribute of the node is altered, the node is then considered fragmented
+ * from that point on. A node is also considered fragmented if any of its
+ * descendants are fragmented. When a node is unfragmented, the contents of the
+ * node can be efficiently generated from the original shared document. When
+ * a node is fragmented, the contents of the node must be created using the
+ * original document and indicies as a form, filling in replacement values
+ * as required.
+ *
+ * <p>Generally, a node's contents consists of complete lines in a shared document.
+ * The contents of the node are normalized on creation to include any whitespace
+ * preceding the node on the line where the node begins, and to include and trailing
+ * whitespace up to the line where the next node begins. Any trailing // comments
+ * that begin on the line where the current node ends, are considered part of that
+ * node.
+ *
+ * @see IDOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+public abstract class DOMNode implements IDOMNode {
+
+	/**
+	 * The first child of this node - <code>null</code>
+	 * when this node has no children. (Children of a node
+	 * are implemented as a doubly linked list).
+	 */
+	protected DOMNode fFirstChild= null;
+
+	/**
+	 * The last child of this node - <code>null</code>
+	 * when this node has no children. Used for efficient
+	 * access to the last child when adding new children
+	 * at the end of the linked list of children.
+	 */
+	protected DOMNode fLastChild= null;
+
+	/**
+	 * The sibling node following this node - <code>null</code>
+	 * for the last node in the sibling list.
+	 */
+	protected DOMNode fNextNode= null;
+
+	/**
+	 * The parent of this node. A <code>null</code>
+	 * parent indicates that this node is a root
+	 * node of a document fragment.
+	 */
+	protected DOMNode fParent= null;
+
+	/**
+	 * The sibling node preceding this node - <code>null</code>
+	 * for the first node in the sibling list.
+	 */
+	protected DOMNode fPreviousNode= null;
+
+	/**
+	 * True when this node has attributes that have
+	 * been altered from their original state in the
+	 * shared document, or when the attributes of a
+	 * descendant have been altered. False when the
+	 * contents of this node and all descendants are
+	 * consistent with the content of the shared
+	 * document.
+	 */
+	protected boolean fIsFragmented= false;
+
+	/**
+	 * The name of this node. For efficiency, the
+	 * name of a node is duplicated in this variable
+	 * on creation, rather than always having to fetch
+	 * the name from the shared document.
+	 */
+	protected String  fName= null;
+
+	/**
+	 * The original inclusive indicies of this node's name in
+	 * the shared document. Values of -1 indiciate the name
+	 * does not exist in the document.
+	 */
+	protected int[]	  fNameRange;
+
+	/**
+	 * The shared document that the contents for this node
+	 * are contained in. Attribute indicies are positions
+	 * in this character array.
+	 */
+	protected char[]  fDocument= null;
+
+	/**
+	 * The original entire inclusive range of this node's contents
+	 * within its document. Values of -1 indicate the contents
+	 * of this node do not exist in the document.
+	 */
+	protected int[] fSourceRange;
+
+	/**
+	 * The current state of bit masks defined by this node.
+	 * Initially all bit flags are turned off. All bit masks
+	 * are defined by this class to avoid overlap, although
+	 * bit masks are node type specific.
+	 *
+	 * @see #setMask
+	 * @see #getMask
+	 */
+	protected int fStateMask= 0;
+
+	/**
+	 * This position is the position of the end of the last line separator before the closing brace starting
+	 * position of the receiver.
+	 */
+	protected int fInsertionPosition;
+
+	/**
+	 * A bit mask indicating this field has an initializer
+	 * expression
+	 */
+	protected static final int MASK_FIELD_HAS_INITIALIZER= 0x00000001;
+
+	/**
+	 * A bit mask indicating this field is a secondary variable
+	 * declarator for a previous field declaration.
+	 */
+	protected static final int MASK_FIELD_IS_VARIABLE_DECLARATOR= 0x00000002;
+
+	/**
+	 * A bit mask indicating this field's type has been
+	 * altered from its original contents in the document.
+	 */
+	protected static final int MASK_FIELD_TYPE_ALTERED= 0x00000004;
+
+	/**
+	 * A bit mask indicating this node's name has been
+	 * altered from its original contents in the document.
+	 */
+	protected static final int MASK_NAME_ALTERED= 0x00000008;
+
+	/**
+	 * A bit mask indicating this node currently has a
+	 * body.
+	 */
+	protected static final int MASK_HAS_BODY= 0x00000010;
+
+	/**
+	 * A bit mask indicating this node currently has a
+	 * preceding comment.
+	 */
+	protected static final int MASK_HAS_COMMENT= 0x00000020;
+
+	/**
+	 * A bit mask indicating this method is a constructor.
+	 */
+	protected static final int MASK_IS_CONSTRUCTOR= 0x00000040;
+
+	/**
+	 * A bit mask indicating this type is a class.
+	 */
+	protected static final int MASK_TYPE_IS_CLASS= 0x00000080;
+
+	/**
+	 * A bit mask indicating this type has a superclass
+	 * (requires or has an 'extends' clause).
+	 */
+	protected static final int MASK_TYPE_HAS_SUPERCLASS= 0x00000100;
+
+	/**
+	 * A bit mask indicating this type implements
+	 * or extends some interfaces
+	 */
+	protected static final int MASK_TYPE_HAS_INTERFACES= 0x00000200;
+
+	/**
+	 * A bit mask indicating this return type of this method has
+	 * been altered from the original contents.
+	 */
+	protected static final int MASK_RETURN_TYPE_ALTERED= 0x00000400;
+
+	/**
+	 * A bit mask indicating this node has detailed source indexes
+	 */
+	protected static final int MASK_DETAILED_SOURCE_INDEXES = 0x00000800;
+
+/**
+ * Creates a new empty document fragment.
+ */
+DOMNode() {
+	this.fName= null;
+	this.fDocument= null;
+	this.fSourceRange= new int[]{-1, -1};
+	this.fNameRange= new int[]{-1, -1};
+	fragment();
+}
+/**
+ * Creates a new document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ */
+DOMNode(char[] document, int[] sourceRange, String name, int[] nameRange) {
+	super();
+	this.fDocument= document;
+	this.fSourceRange= sourceRange;
+	this.fName= name;
+	this.fNameRange= nameRange;
+
+}
+/**
+ * Adds the given un-parented node (document fragment) as the last child of
+ * this node.
+ *
+ * <p>When a child is added, this node must be considered fragmented such that
+ * the contents of this node are properly generated.
+ *
+ * @see IDOMNode#addChild(IDOMNode)
+ */
+public void addChild(IDOMNode child) throws IllegalArgumentException, DOMException {
+	basicAddChild(child);
+
+	// if the node is a constructor, it must also be fragmented to update the constructor's name
+	if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) {
+		((DOMNode)child).fragment();
+	} else {
+		fragment();
+	}
+}
+/**
+ * Appends the current contents of this document fragment
+ * to the given <code>CharArrayBuffer</code>.
+ *
+ * <p>If this node is fragmented, contents must be generated by
+ * using the original document and indicies as a form for the current
+ * attribute values of this node. If this node not fragmented, the
+ * contents can be obtained from the document.
+ *
+ */
+protected void appendContents(CharArrayBuffer buffer) {
+	if (isFragmented()) {
+		appendFragmentedContents(buffer);
+	} else {
+		buffer.append(this.fDocument, this.fSourceRange[0], this.fSourceRange[1] + 1 - this.fSourceRange[0]);
+	}
+}
+/**
+ * Appends the contents of all children of this node to the
+ * given <code>CharArrayBuffer</code>.
+ *
+ * <p>This algorithm used minimizes String generation by merging
+ * adjacent unfragmented children into one substring operation.
+ *
+ */
+protected void appendContentsOfChildren(CharArrayBuffer buffer) {
+	DOMNode child= this.fFirstChild;
+	DOMNode sibling;
+
+	int start= 0, end= 0;
+	if (child != null) {
+		start= child.getStartPosition();
+		end= child.getEndPosition();
+	}
+	while (child != null) {
+		sibling= child.fNextNode;
+		if (sibling != null) {
+			if (sibling.isContentMergableWith(child)) {
+				end= sibling.getEndPosition();
+			} else {
+				if (child.isFragmented()) {
+					child.appendContents(buffer);
+				} else {
+					buffer.append(child.getDocument(), start, end + 1 - start);
+				}
+				start= sibling.getStartPosition();
+				end= sibling.getEndPosition();
+			}
+		} else {
+			if (child.isFragmented()) {
+				child.appendContents(buffer);
+			} else {
+				buffer.append(child.getDocument(), start, end + 1 - start);
+			}
+		}
+		child= sibling;
+	}
+}
+/**
+ * Appends the contents of this node to the given <code>CharArrayBufer</code>, using
+ * the original document and indicies as a form for the current attribute
+ * values of this node.
+ */
+protected abstract void appendFragmentedContents(CharArrayBuffer buffer);
+/**
+ * Adds the given un-parented node (document fragment) as the last child of
+ * this node without setting this node's 'fragmented' flag. This
+ * method is only used by the <code>DOMBuilder</code> when creating a new DOM such
+ * that a new DOM is unfragmented.
+ */
+void basicAddChild(IDOMNode child) throws IllegalArgumentException, DOMException {
+	// verify child may be added
+	if (!canHaveChildren()) {
+		throw new DOMException(Messages.dom_unableAddChild);
+	}
+	if (child == null) {
+		throw new IllegalArgumentException(Messages.dom_addNullChild);
+	}
+	if (!isAllowableChild(child)) {
+		throw new DOMException(Messages.dom_addIncompatibleChild);
+	}
+	if (child.getParent() != null) {
+		throw new DOMException(Messages.dom_addChildWithParent);
+	}
+	/* NOTE: To test if the child is an ancestor of this node, we
+	 * need only test if the root of this node is the child (the child
+	 * is already a root since we have just guarenteed it has no parent).
+	 */
+	if (child == getRoot()) {
+		throw new DOMException(Messages.dom_addAncestorAsChild);
+	}
+
+	DOMNode node= (DOMNode)child;
+
+	// if the child is not already part of this document, localize its contents
+	// before adding it to the tree
+	if (node.getDocument() != getDocument()) {
+		node.localizeContents();
+	}
+
+	// add the child last
+	if (this.fFirstChild == null) {
+		// this is the first and only child
+		this.fFirstChild= node;
+	} else {
+		this.fLastChild.fNextNode= node;
+		node.fPreviousNode= this.fLastChild;
+	}
+	this.fLastChild= node;
+	node.fParent= this;
+}
+/**
+ * Generates detailed source indexes for this node if possible.
+ *
+ * @exception DOMException if unable to generate detailed source indexes
+ * 	for this node
+ */
+protected void becomeDetailed() throws DOMException {
+	if (!isDetailed()) {
+		DOMNode detailed= getDetailedNode();
+		if (detailed == null) {
+			throw new DOMException(Messages.dom_cannotDetail);
+		}
+		if (detailed != this) {
+			shareContents(detailed);
+		}
+	}
+}
+/**
+ * Returns true if this node is allowed to have children, otherwise false.
+ *
+ * <p>Default implementation of <code>IDOMNode</code> interface method returns false; this
+ * method must be overridden by subclasses that implement nodes that allow
+ * children.
+ *
+ * @see IDOMNode#canHaveChildren()
+ */
+public boolean canHaveChildren() {
+	return false;
+}
+/**
+ * @see IDOMNode#clone()
+ */
+public Object clone() {
+
+	// create a new buffer with all my contents and children contents
+	int length= 0;
+	char[] buffer= null;
+	int offset= this.fSourceRange[0];
+
+	if (offset >= 0) {
+		length= this.fSourceRange[1] - offset + 1;
+		buffer= new char[length];
+		System.arraycopy(this.fDocument, offset, buffer, 0, length);
+	}
+	DOMNode clone= newDOMNode();
+	clone.shareContents(this);
+	clone.fDocument = buffer;
+
+	if (offset > 0) {
+		clone.offset(0 - offset);
+	}
+
+	// clone my children
+	if (canHaveChildren()) {
+		Enumeration children= getChildren();
+		while (children.hasMoreElements()) {
+			DOMNode child= (DOMNode)children.nextElement();
+			if (child.fDocument == this.fDocument) {
+				DOMNode childClone= child.cloneSharingDocument(buffer, offset);
+				clone.basicAddChild(childClone);
+			} else {
+				DOMNode childClone= (DOMNode)child.clone();
+				clone.addChild(childClone);
+			}
+
+		}
+	}
+
+	return clone;
+}
+private DOMNode cloneSharingDocument(char[] document, int rootOffset) {
+
+	DOMNode clone = newDOMNode();
+	clone.shareContents(this);
+	clone.fDocument = document;
+	if (rootOffset > 0) {
+		clone.offset(0 - rootOffset);
+	}
+
+	if (canHaveChildren()) {
+		Enumeration children = getChildren();
+		while (children.hasMoreElements()) {
+			DOMNode child = (DOMNode) children.nextElement();
+			if (child.fDocument == this.fDocument) {
+				DOMNode childClone= child.cloneSharingDocument(document, rootOffset);
+				clone.basicAddChild(childClone);
+			} else {
+				DOMNode childClone= (DOMNode)child.clone();
+				clone.addChild(childClone);
+			}
+		}
+	}
+	return clone;
+}
+/**
+ * Sets this node's fragmented flag and all ancestor fragmented flags
+ * to <code>true<code>. This happens when an attribute of this node or a descendant
+ * node has been altered. When a node is fragmented, its contents must
+ * be generated from its attributes and original "form" rather than
+ * from the original contents in the document.
+ */
+protected void fragment() {
+	if (!isFragmented()) {
+		this.fIsFragmented= true;
+		if (this.fParent != null) {
+			this.fParent.fragment();
+		}
+	}
+}
+/**
+ * @see IDOMNode#getCharacters()
+ */
+public char[] getCharacters() {
+	CharArrayBuffer buffer= new CharArrayBuffer();
+	appendContents(buffer);
+	return buffer.getContents();
+}
+/**
+ * @see IDOMNode#getChild(String)
+ */
+public IDOMNode getChild(String name) {
+	DOMNode child = this.fFirstChild;
+	while (child != null) {
+		String n = child.getName();
+		if (name == null) {
+			if (n == null) {
+				return child;
+			}
+		} else {
+			if (name.equals(n)) {
+				return child;
+			}
+		}
+		child = child.fNextNode;
+	}
+	return null;
+}
+/**
+ * @see IDOMNode#getChildren()
+ */
+public Enumeration getChildren() {
+	return new SiblingEnumeration(this.fFirstChild);
+}
+/**
+ * Returns the current contents of this document fragment,
+ * or <code>null</code> if this node has no contents.
+ *
+ * <p>If this node is fragmented, contents must be generated by
+ * using the original document and indicies as a form for the current
+ * attribute values of this node. If this node not fragmented, the
+ * contents can be obtained from the document.
+ *
+ * @see IDOMNode#getContents()
+ */
+public String getContents() {
+	CharArrayBuffer buffer= new CharArrayBuffer();
+	appendContents(buffer);
+	return buffer.toString();
+}
+/**
+ * Returns a new document fragment representing this node with
+ * detailed source indexes. Subclasses that provide a detailed
+ * implementation must override this method.
+ */
+protected DOMNode getDetailedNode() {
+	return this;
+}
+/**
+ * Returns the document containing this node's original contents.
+ * The document may be shared by other nodes.
+ */
+protected char[] getDocument() {
+	return this.fDocument;
+}
+/**
+ * Returns the original position of the last character of this
+ * node's contents in its document.
+ */
+public int getEndPosition() {
+	return this.fSourceRange[1];
+}
+/**
+ * Returns a factory with which to create new document fragments.
+ */
+protected IDOMFactory getFactory() {
+	return new DOMFactory();
+}
+/**
+ * @see IDOMNode#getFirstChild()
+ */
+public IDOMNode getFirstChild() {
+	return this.fFirstChild;
+}
+/**
+ * Returns the position at which the first child of this node should be inserted.
+ */
+public int getInsertionPosition() {
+	return this.fInsertionPosition;
+}
+/**
+ * Returns <code>true</code> if the given mask of this node's state flag
+ * is turned on, otherwise <code>false</code>.
+ */
+protected boolean getMask(int mask) {
+	return (this.fStateMask & mask) > 0;
+}
+/**
+ * @see IDOMNode#getName()
+ */
+public String getName() {
+	return this.fName;
+}
+/**
+ * Returns the source code to be used for this node's name.
+ */
+protected char[] getNameContents() {
+	if (isNameAltered()) {
+		return this.fName.toCharArray();
+	} else {
+		if (this.fName == null || this.fNameRange[0] < 0) {
+			return null;
+		} else {
+			int length = this.fNameRange[1] + 1 - this.fNameRange[0];
+			char[] result = new char[length];
+			System.arraycopy(this.fDocument, this.fNameRange[0], result, 0, length);
+			return result;
+		}
+	}
+}
+/**
+ * @see IDOMNode#getNextNode()
+ */
+public IDOMNode getNextNode() {
+	return this.fNextNode;
+}
+/**
+ * @see IDOMNode#getParent()
+ */
+public IDOMNode getParent() {
+	return this.fParent;
+}
+/**
+ * Answers a source position which corresponds to the end of the parent
+ * element's declaration.
+ */
+protected int getParentEndDeclaration() {
+	IDOMNode parent = getParent();
+	if (parent == null) {
+		return 0;
+	} else {
+		if (parent instanceof IDOMCompilationUnit) {
+			return 0;
+		} else {
+			return ((DOMType)parent).getOpenBodyEnd();
+		}
+	}
+}
+/**
+ * @see IDOMNode#getPreviousNode()
+ */
+public IDOMNode getPreviousNode() {
+	return this.fPreviousNode;
+}
+/**
+ * Returns the root node of this document fragment.
+ */
+protected IDOMNode getRoot() {
+	if (this.fParent == null) {
+		return this;
+	} else {
+		return this.fParent.getRoot();
+	}
+}
+/**
+ * Returns the original position of the first character of this
+ * node's contents in its document.
+ */
+public int getStartPosition() {
+	return this.fSourceRange[0];
+}
+/**
+ * @see IDOMNode#insertSibling(IDOMNode)
+ */
+public void insertSibling(IDOMNode sibling) throws IllegalArgumentException, DOMException {
+	// verify sibling may be added
+	if (sibling == null) {
+		throw new IllegalArgumentException(Messages.dom_addNullSibling);
+	}
+	if (this.fParent == null) {
+		throw new DOMException(Messages.dom_addSiblingBeforeRoot);
+	}
+	if (!this.fParent.isAllowableChild(sibling)) {
+		throw new DOMException(Messages.dom_addIncompatibleSibling);
+	}
+	if (sibling.getParent() != null) {
+		throw new DOMException(Messages.dom_addSiblingWithParent);
+	}
+	/* NOTE: To test if the sibling is an ancestor of this node, we
+	 * need only test if the root of this node is the child (the sibling
+	 * is already a root since we have just guaranteed it has no parent).
+	 */
+	if (sibling == getRoot()) {
+		throw new DOMException(Messages.dom_addAncestorAsSibling);
+	}
+
+	DOMNode node= (DOMNode)sibling;
+
+	// if the sibling is not already part of this document, localize its contents
+	// before inserting it into the tree
+	if (node.getDocument() != getDocument()) {
+		node.localizeContents();
+	}
+
+	// insert the node
+	if (this.fPreviousNode == null) {
+		this.fParent.fFirstChild= node;
+	} else {
+		this.fPreviousNode.fNextNode= node;
+	}
+	node.fParent= this.fParent;
+	node.fPreviousNode= this.fPreviousNode;
+	node.fNextNode= this;
+	this.fPreviousNode= node;
+
+	// if the node is a constructor, it must also be fragmented to update the constructor's name
+	if (node.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)node).isConstructor()) {
+		node.fragment();
+	} else {
+		this.fParent.fragment();
+	}
+}
+/**
+ * @see IDOMNode
+ */
+public boolean isAllowableChild(IDOMNode node) {
+	return false;
+}
+/**
+ * Returns <code>true</code> if the contents of this node are from the same document as
+ * the given node, the contents of this node immediately follow the contents
+ * of the given node, and neither this node or the given node are fragmented -
+ * otherwise <code>false</code>.
+ */
+protected boolean isContentMergableWith(DOMNode node) {
+	return !node.isFragmented() && !isFragmented() && node.getDocument() == getDocument() &&
+		node.getEndPosition() + 1 == getStartPosition();
+}
+/**
+ * Returns <code>true</code> if this node has detailed source index information,
+ * or <code>false</code> if this node has limited source index information. To
+ * perform some manipulations, detailed indexes are required.
+ */
+protected boolean isDetailed() {
+	return getMask(MASK_DETAILED_SOURCE_INDEXES);
+}
+/**
+ * Returns <code>true</code> if this node's or a descendant node's contents
+ * have been altered since this node was created. This indicates
+ * that the contents of this node are no longer consistent with
+ * the contents of this node's document.
+ */
+protected boolean isFragmented() {
+	return this.fIsFragmented;
+}
+/**
+ * Returns <code>true</code> if this noed's name has been altered
+ * from the original document contents.
+ */
+protected boolean isNameAltered() {
+	return getMask(MASK_NAME_ALTERED);
+}
+/**
+ * @see IDOMNode#isSignatureEqual(IDOMNode)
+ *
+ * <p>By default, the signatures of two nodes are equal if their
+ * type and names are equal. Node types that have other requirements
+ * for equality must override this method.
+ */
+public boolean isSignatureEqual(IDOMNode node) {
+	return getNodeType() == node.getNodeType() && getName().equals(node.getName());
+}
+/**
+ * Localizes the contents of this node and all descendant nodes,
+ * such that this node is no longer dependent on its original
+ * document in order to generate its contents. This node and all
+ * descendant nodes become unfragmented and share a new
+ * document.
+ */
+protected void localizeContents() {
+
+	DOMNode clone= (DOMNode)clone();
+	shareContents(clone);
+
+}
+/**
+ * Returns a new empty <code>DOMNode</code> for this instance.
+ */
+protected abstract DOMNode newDOMNode();
+/**
+ * Normalizes this <code>DOMNode</code>'s source positions to include whitespace preceeding
+ * the node on the line on which the node starts, and all whitespace after the node up to
+ * the next node's start
+ */
+void normalize(ILineStartFinder finder) {
+	if (getPreviousNode() == null)
+		normalizeStartPosition(getParentEndDeclaration(), finder);
+
+	// Set the children's position
+	if (canHaveChildren()) {
+		Enumeration children = getChildren();
+		while(children.hasMoreElements())
+			((DOMNode)children.nextElement()).normalize(finder);
+	}
+
+	normalizeEndPosition(finder, (DOMNode)getNextNode());
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s end position.
+ */
+void normalizeEndPosition(ILineStartFinder finder, DOMNode next) {
+	if (next == null) {
+		// this node's end position includes all of the characters up
+		// to the end of the enclosing node
+		DOMNode parent = (DOMNode) getParent();
+		if (parent == null || parent instanceof DOMCompilationUnit) {
+			setSourceRangeEnd(this.fDocument.length - 1);
+		} else {
+			// parent is a type
+			int temp = ((DOMType)parent).getCloseBodyPosition() - 1;
+			setSourceRangeEnd(temp);
+			this.fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
+		}
+	} else {
+		// this node's end position is just before the start of the next node
+		int temp = next.getStartPosition() - 1;
+		this.fInsertionPosition = Math.max(finder.getLineStart(temp + 1), getEndPosition());
+		next.normalizeStartPosition(getEndPosition(), finder);
+		setSourceRangeEnd(next.getStartPosition() - 1);
+	}
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s start position.
+ */
+void normalizeStartPosition(int previousEnd, ILineStartFinder finder) {
+	int nodeStart = getStartPosition();
+	int lineStart = finder.getLineStart(nodeStart);
+	if (nodeStart > lineStart && (lineStart > previousEnd || (previousEnd == 0 && lineStart == 0)))
+		setStartPosition(lineStart);
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	offsetRange(this.fNameRange, offset);
+	offsetRange(this.fSourceRange, offset);
+}
+/**
+ * Offsets the source range by the given amount
+ */
+protected void offsetRange(int[] range, int offset) {
+	for (int i= 0; i < range.length; i++) {
+		range[i]+=offset;
+		if (range[i] < 0) {
+			range[i]= -1;
+		}
+	}
+}
+/**
+ * Returns a copy of the given range.
+ */
+protected int[] rangeCopy(int[] range) {
+	int[] copy= new int[range.length];
+	for (int i= 0; i < range.length; i++) {
+		copy[i]= range[i];
+	}
+	return copy;
+}
+/**
+ * Separates this node from its parent and siblings, maintaining any ties that
+ * this node has to the underlying document fragment.
+ *
+ * <p>When a child is removed, its parent is fragmented such that it properly
+ * generates its contents.
+ *
+ * @see IDOMNode#remove()
+ */
+public void remove() {
+
+	if (this.fParent != null) {
+		this.fParent.fragment();
+	}
+
+	// link siblings
+	if (this.fNextNode != null) {
+		this.fNextNode.fPreviousNode= this.fPreviousNode;
+	}
+	if (this.fPreviousNode != null) {
+		this.fPreviousNode.fNextNode= this.fNextNode;
+	}
+	// fix parent's pointers
+	if (this.fParent != null) {
+		if (this.fParent.fFirstChild == this) {
+			this.fParent.fFirstChild= this.fNextNode;
+		}
+		if (this.fParent.fLastChild == this) {
+			this.fParent.fLastChild= this.fPreviousNode;
+		}
+	}
+	// remove myself
+	this.fParent= null;
+	this.fNextNode= null;
+	this.fPreviousNode= null;
+}
+/**
+ * Sets the specified mask of this node's state mask on or off
+ * based on the boolean value - true -> on, false -> off.
+ */
+protected void setMask(int mask, boolean on) {
+	if (on) {
+		this.fStateMask |= mask;
+	} else {
+		this.fStateMask &= ~mask;
+	}
+}
+/**
+ * @see IDOMNode#setName
+ */
+public void setName(String name) {
+	this.fName= name;
+	setNameAltered(true);
+	fragment();
+}
+/**
+ * Sets the state of this node as having
+ * its name attribute altered from the original
+ * document contents.
+ */
+protected void setNameAltered(boolean altered) {
+	setMask(MASK_NAME_ALTERED, altered);
+}
+/**
+ * Sets the original position of the last character of this node's contents
+ * in its document. This method is only used during DOM creation while
+ * normalizing the source range of each node.
+ */
+protected void setSourceRangeEnd(int end) {
+	this.fSourceRange[1]= end;
+}
+/**
+ * Sets the original position of the first character of this node's contents
+ * in its document. This method is only used during DOM creation while
+ * normalizing the source range of each node.
+ */
+protected void setStartPosition(int start) {
+	this.fSourceRange[0]= start;
+}
+/**
+ * Sets the contents of this node and descendant nodes to be the
+ * (identical) contents of the given node and its descendants. This
+ * does not effect this node's parent and sibling configuration,
+ * only the contents of this node. This is used only to localize
+ * the contents of this node.
+ */
+protected void shareContents(DOMNode node) {
+	this.fDocument= node.fDocument;
+	this.fIsFragmented= node.fIsFragmented;
+	this.fName= node.fName;
+	this.fNameRange= rangeCopy(node.fNameRange);
+	this.fSourceRange= rangeCopy(node.fSourceRange);
+	this.fStateMask= node.fStateMask;
+
+
+	if (canHaveChildren()) {
+		Enumeration myChildren= getChildren();
+		Enumeration otherChildren= node.getChildren();
+		DOMNode myChild, otherChild;
+		while (myChildren.hasMoreElements()) {
+			myChild= (DOMNode)myChildren.nextElement();
+			otherChild= (DOMNode)otherChildren.nextElement();
+			myChild.shareContents(otherChild);
+		}
+	}
+}
+/**
+ * Returns a <code>String</code> representing this node - for Debug purposes only.
+ */
+public abstract String toString();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
new file mode 100644
index 0000000..27672c5
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * DOMPackage provides an implementation of IDOMPackage.
+ *
+ * @see IDOMPackage
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+class DOMPackage extends DOMNode implements IDOMPackage {
+
+/**
+ * Creates an empty PACKAGE node.
+ */
+DOMPackage() {
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+}
+/**
+ * Creates a new simple PACKAGE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ */
+DOMPackage(char[] document, int[] sourceRange, String name) {
+	super(document, sourceRange, name, new int[] {-1, -1});
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * Creates a new detailed PACKAGE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ */
+DOMPackage(char[] document, int[] sourceRange, String name, int[] nameRange) {
+	super(document, sourceRange, name, nameRange);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+}
+/**
+ * @see DOMNode#appendFragmentedContents(CharArrayBuffer)
+ */
+protected void appendFragmentedContents(CharArrayBuffer buffer) {
+	if (this.fNameRange[0] < 0) {
+		String lineSeparator = Util.getLineSeparator(buffer.toString(), null);
+		buffer
+			.append("package ") //$NON-NLS-1$
+			.append(this.fName)
+			.append(';')
+			.append(lineSeparator)
+			.append(lineSeparator);
+	} else {
+		buffer
+			.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0])
+			.append(this.fName)
+			.append(this.fDocument, this.fNameRange[1] + 1, this.fSourceRange[1] - this.fNameRange[1]);
+	}
+}
+/**
+ * @see IDOMNode#getContents()
+ */
+public String getContents() {
+	if (this.fName == null) {
+		return null;
+	} else {
+		return super.getContents();
+	}
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	return (DOMNode)getFactory().createPackage(getContents());
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
+		return ((ICompilationUnit)parent).getPackageDeclaration(getName());
+	} else {
+		throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.PACKAGE;
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMPackage();
+}
+/**
+ * @see IDOMNode#setName
+ */
+public void setName(String name) {
+	becomeDetailed();
+	super.setName(name);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "PACKAGE: " + getName(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java
new file mode 100644
index 0000000..ecaf7c7
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java
@@ -0,0 +1,801 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Enumeration;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Messages;
+/**
+ * DOMType provides an implementation of IDOMType.
+ *
+ * @see IDOMType
+ * @see DOMNode
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+// TODO (jerome) - add implementation support for 1.5 features
+/* package */ class DOMType extends DOMMember implements IDOMType {
+	/**
+	 * The 'class' or 'interface' keyword if altered
+	 * from the documents contents, otherwise <code>null</code>.
+	 */
+	protected String fTypeKeyword;
+
+	/**
+	 * The original inclusive source range of the 'class'
+	 * or 'interface' keyword in the document.
+	 */
+	protected int[]	 fTypeRange;
+
+	/**
+	 * The superclass name for the class declaration
+	 * if altered from the document's contents, otherwise
+	 * <code>null</code>. Also <code>null</code> when this
+	 * type represents an interface.
+	 */
+	protected String fSuperclass;
+
+	/**
+	 * The original inclusive source range of the superclass
+	 * name in the document, or -1's of no superclass was
+	 * specified in the document.
+	 */
+	protected int[]  fSuperclassRange;
+
+
+	/**
+	 * The original inclusive souce range of the 'extends' keyword
+	 * in the document, including surrounding whitespace, or -1's if
+	 * the keyword was not present in the document.
+	 */
+	protected int[]	 fExtendsRange;
+
+	/**
+	 * The original inclusive souce range of the 'implements' keyword
+	 * in the document, including surrounding whitespace, or -1's if
+	 * the keyword was not present in the document.
+	 */
+	protected int[]	 fImplementsRange;
+
+	/**
+	 * The comma delimited list of interfaces this type implements
+	 * or extends, if altered from the document's contents, otherwise
+	 * <code>null</code>. Also <code>null</code> if this type does
+	 * not implement or extend any interfaces.
+	 */
+	protected char[] fInterfaces;
+
+	/**
+	 * The original inclusive source range of the list of interfaces this
+	 * type implements or extends, not including any surrouding whitespace.
+	 * If the document did not specify interfaces, this array contains -1's.
+	 */
+	protected int[]  fInterfacesRange;
+
+
+
+	/**
+	 * The original source range of the first character following the
+	 * type name superclass name, or interface list, up to and including
+	 * the first character before the first type member.
+	 */
+	protected int[]  fOpenBodyRange;
+
+	/**
+	 * The original source range of the first new line or non whitespace
+	 * character preceding the close brace of the type's body, up to the
+	 * and including the first character before the next node (if there are
+	 * no following nodes, the range ends at the position of the last
+	 * character in the document).
+	 */
+	protected int[]  fCloseBodyRange;
+
+	/**
+	 * A list of interfaces this type extends or implements.
+	 * <code>null</code> when this type does not extend
+	 * or implement any interfaces.
+	 */
+	protected String[] fSuperInterfaces= CharOperation.NO_STRINGS;
+
+	/**
+	 * The formal type parameters.
+	 * @since 3.0
+	 */
+	protected String[] fTypeParameters = CharOperation.NO_STRINGS;
+
+	/**
+	 * Indicates this type is an enum class.
+	 * @since 3.0
+	 */
+	protected boolean fIsEnum= false;
+
+	/**
+	 * Indicates this type is an annotatation type (interface).
+	 * @since 3.0
+	 */
+	protected boolean fIsAnnotation= false;
+
+	/**
+	 * This position is the position of the end of the last line separator before the closing brace starting
+	 * position of the receiver.
+	 */
+//	protected int fInsertionPosition;
+
+/**
+ * Constructs an empty type node.
+ */
+DOMType() {
+	// Constructs an empty type node
+}
+/**
+ * Creates a new detailed TYPE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ * @param commentRange - a two element array describing the comments that precede
+ *		the member declaration. The first matches the start of this node's
+ *		sourceRange, and the second is the new-line or first non-whitespace
+ *		character following the last comment. If no comments are present,
+ *		this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *		modifiers for this member within its source range. The first integer
+ *		is the first character of the first modifier for this member, and
+ *		the second integer is the last whitespace character preceeding the
+ *		next part of this member declaration. If there are no modifiers present
+ *		in this node's source code (that is, package default visibility), this array
+ *		contains two -1's.
+ * @param typeRange - a two element array describing the location of the 'class'
+ *		or 'interface' keyword in the type declaration - first and last character
+ *		positions.
+ * @param superclassRange - a two element array describing the location of the
+ *		superclass name in the type declaration - first and last character
+ *		positions or two -1's if a superclass is not present in the document.
+ * @param extendsRange - a two element array describing the location of the
+ *		'extends' keyword in the type declaration, including any surrounding
+ *		whitespace, or -1's if the 'extends' keyword is not present in the document.
+ * @param implementsList - an array of names of the interfaces this type implements
+ *		or extends, or <code>null</code> if this type does not implement or extend
+ *		any interfaces.
+ * @param implementsRange - a two element array describing the location of the
+ *		comment delimited list of interfaces this type implements or extends,
+ *		not including any surrounding whitespace, or -1's if no interface list
+ *		is present in the document.
+ * @param implementsKeywordRange - a two element array describing the location of the
+ *		'implements' keyword, including any surrounding whitespace, or -1's if no
+ * 		'implements' keyword is present in the document.
+ * @param openBodyRange - a two element array describing the location of the
+ *      open brace of the type's body and whitespace following the type declaration
+ *		and preceeding the first member in the type.
+ * @param closeBodyRange - a two element array describing the source range of the
+ *		first new line or non whitespace character preceeding the close brace of the
+ *		type's body, up to the close brace
+ * @param isClass - true is the type is a class, false if it is an interface
+ */
+DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, int[] superclassRange, int[] extendsRange, String[] implementsList, int[] implementsRange, int[] implementsKeywordRange, int[] openBodyRange, int[] closeBodyRange, boolean isClass) {
+	super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange);
+
+	this.fTypeRange= typeRange;
+	setMask(MASK_TYPE_IS_CLASS, isClass);
+
+	this.fExtendsRange= extendsRange;
+	this.fImplementsRange= implementsKeywordRange;
+	this.fSuperclassRange= superclassRange;
+	this.fInterfacesRange= implementsRange;
+	this.fCloseBodyRange= closeBodyRange;
+	setMask(MASK_TYPE_HAS_SUPERCLASS, superclassRange[0] > 0);
+	setMask(MASK_TYPE_HAS_INTERFACES, implementsList != null);
+	this.fSuperInterfaces= implementsList;
+	this.fOpenBodyRange= openBodyRange;
+	this.fCloseBodyRange= closeBodyRange;
+	setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+
+}
+/**
+ * Creates a new simple TYPE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *		entire inclusive source range of this node within its document.
+ * 		Contents start on and include the character at the first position.
+ *		Contents end on and include the character at the last position.
+ *		An array of -1's indicates this node's contents do not exist
+ *		in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *		<code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *		entire inclusive source range of this node's name within its document,
+ *		including any array qualifiers that might immediately follow the name
+ *		or -1's if this node does not have a name.
+ * @param flags - an integer representing the modifiers for this member. The
+ *		integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param implementsList - an array of names of the interfaces this type implements
+ *		or extends, or <code>null</code> if this type does not implement or extend
+ *		any interfaces.
+ * @param isClass - true is the type is a class, false if it is an interface
+ */
+DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String[] implementsList, boolean isClass) {
+	this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags,
+		new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1},
+		implementsList, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {sourceRange[1], sourceRange[1]}, isClass);
+	setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * @see IDOMType#addSuperInterface(String)
+ */
+public void addSuperInterface(String name) throws IllegalArgumentException {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.dom_addNullInterface);
+	}
+	if (this.fSuperInterfaces == null) {
+		this.fSuperInterfaces= new String[1];
+		this.fSuperInterfaces[0]= name;
+	} else {
+		this.fSuperInterfaces= appendString(this.fSuperInterfaces, name);
+	}
+	setSuperInterfaces(this.fSuperInterfaces);
+}
+/**
+ * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
+ */
+protected void appendMemberBodyContents(CharArrayBuffer buffer) {
+	buffer.append(this.fDocument, this.fOpenBodyRange[0], this.fOpenBodyRange[1] + 1 - this.fOpenBodyRange[0]);
+	appendContentsOfChildren(buffer);
+	buffer.append(this.fDocument, this.fCloseBodyRange[0], this.fCloseBodyRange[1] + 1 - this.fCloseBodyRange[0]);
+	buffer.append(this.fDocument, this.fCloseBodyRange[1] + 1, this.fSourceRange[1] - this.fCloseBodyRange[1]);
+}
+/**
+ * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer )
+ */
+protected void appendMemberDeclarationContents(CharArrayBuffer  buffer) {
+
+	if (this.fTypeKeyword != null) {
+		buffer.append(this.fTypeKeyword);
+		buffer.append(this.fDocument, this.fTypeRange[1], this.fNameRange[0] - this.fTypeRange[1] );
+	} else {
+		buffer.append(this.fDocument, this.fTypeRange[0], this.fTypeRange[1] + 1 - this.fTypeRange[0]);
+	}
+
+	buffer.append(getName());
+
+	if (isClass()) {
+		boolean hasInterfaces = false;
+		if (getMask(MASK_TYPE_HAS_SUPERCLASS)) {
+			if (this.fExtendsRange[0] < 0) {
+				buffer.append(" extends "); //$NON-NLS-1$
+			} else {
+				buffer.append(this.fDocument, this.fExtendsRange[0], this.fExtendsRange[1] + 1 - this.fExtendsRange[0]);
+			}
+			if (this.fSuperclass != null) {
+				buffer.append(this.fSuperclass);
+			} else {
+				buffer.append(this.fDocument, this.fSuperclassRange[0], this.fSuperclassRange[1] + 1 - this.fSuperclassRange[0]);
+			}
+		}
+		if (getMask(MASK_TYPE_HAS_INTERFACES)) {
+			hasInterfaces = true;
+			if (this.fImplementsRange[0] < 0) {
+				buffer.append(" implements "); //$NON-NLS-1$
+			} else {
+				buffer.append(this.fDocument, this.fImplementsRange[0], this.fImplementsRange[1] + 1 - this.fImplementsRange[0]);
+			}
+			if (this.fInterfaces != null) {
+				buffer.append(this.fInterfaces);
+			} else {
+				buffer.append(this.fDocument, this.fInterfacesRange[0], this.fInterfacesRange[1] + 1 - this.fInterfacesRange[0]);
+			}
+		}
+		if (hasInterfaces) {
+			if (this.fImplementsRange[0] < 0) {
+				buffer.append(' ');
+			} else {
+				buffer.append(this.fDocument, this.fInterfacesRange[1] + 1, this.fOpenBodyRange[0] - this.fInterfacesRange[1] - 1);
+			}
+		} else {
+			if (this.fSuperclassRange[0] < 0) {
+				buffer.append(' ');
+			} else if (this.fImplementsRange[0] > 0) {
+				buffer.append(this.fDocument, this.fSuperclassRange[1] + 1, this.fImplementsRange[0] - this.fSuperclassRange[1] - 1);
+				buffer.append(this.fDocument, this.fInterfacesRange[1] + 1, this.fOpenBodyRange[0] - this.fInterfacesRange[1] - 1);
+			} else {
+				buffer.append(this.fDocument, this.fSuperclassRange[1] + 1, this.fOpenBodyRange[0] - this.fSuperclassRange[1] - 1);
+			}
+		}
+	} else {
+		if (getMask(MASK_TYPE_HAS_INTERFACES)) {
+			if (this.fExtendsRange[0] < 0) {
+				buffer.append(" extends "); //$NON-NLS-1$
+			} else {
+				buffer.append(this.fDocument, this.fExtendsRange[0], this.fExtendsRange[1] + 1 - this.fExtendsRange[0]);
+			}
+			if (this.fInterfaces != null) {
+				buffer.append(this.fInterfaces);
+				buffer.append(' ');
+			} else {
+				buffer.append(this.fDocument, this.fInterfacesRange[0], this.fInterfacesRange[1] + 1 - this.fInterfacesRange[0]);
+			}
+		} else {
+			if (this.fImplementsRange[0] < 0) {
+				buffer.append(' ');
+			} else {
+				buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fOpenBodyRange[0] - this.fNameRange[1] - 1);
+			}
+		}
+	}
+
+}
+/**
+ * @see DOMMember#appendSimpleContents(CharArrayBuffer)
+ */
+protected void appendSimpleContents(CharArrayBuffer buffer) {
+	// append eveything before my name
+	buffer.append(this.fDocument, this.fSourceRange[0], this.fNameRange[0] - this.fSourceRange[0]);
+	// append my name
+	buffer.append(this.fName);
+
+
+	// append everything after my name and before my first child
+	buffer.append(this.fDocument, this.fNameRange[1] + 1, this.fOpenBodyRange[1] - this.fNameRange[1]);
+	// append my children
+	appendContentsOfChildren(buffer);
+	// append from my last child to my end
+	buffer.append(this.fDocument, this.fCloseBodyRange[0], this.fSourceRange[1] - this.fCloseBodyRange[0] + 1);
+
+
+}
+/**
+ * @see IDOMNode#canHaveChildren()
+ */
+public boolean canHaveChildren() {
+	return true;
+}
+/**
+ * Returns the position of the closing brace for the body of this type.
+ * This value this method returns is only valid before the type has
+ * been normalized and is present only for normalization.
+ */
+int getCloseBodyPosition() {
+	return this.fCloseBodyRange[0];
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+protected DOMNode getDetailedNode() {
+	return (DOMNode)getFactory().createType(getContents());
+}
+/**
+ * @see DOMNode#getInsertionPosition()
+ */
+public int getInsertionPosition() {
+	// this should return the position of the end of the last line separator before the closing brace of the type
+	// See PR 1GELSDQ: ITPJUI:WINNT - JDOM: IType.createMethod does not insert nicely for inner types
+	return this.fInsertionPosition;
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+	switch (parent.getElementType()) {
+		case IJavaElement.COMPILATION_UNIT:
+			return ((ICompilationUnit)parent).getType(getName());
+		case IJavaElement.TYPE:
+			return ((IType)parent).getType(getName());
+		// Note: creating local/anonymous type is not supported
+		default:
+			throw new IllegalArgumentException(Messages.element_illegalParent);
+	}
+}
+/**
+ * @see DOMMember#getMemberDeclarationStartPosition()
+ */
+protected int getMemberDeclarationStartPosition() {
+	return this.fTypeRange[0];
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+	return IDOMNode.TYPE;
+}
+/**
+ * Answers the open body range end position.
+ */
+int getOpenBodyEnd() {
+	return this.fOpenBodyRange[1];
+}
+/**
+ * @see IDOMType#getSuperclass()
+ */
+public String getSuperclass() {
+	becomeDetailed();
+	if (getMask(MASK_TYPE_HAS_SUPERCLASS)) {
+		if (this.fSuperclass != null) {
+			return this.fSuperclass;
+		} else {
+			return new String(this.fDocument, this.fSuperclassRange[0], this.fSuperclassRange[1] + 1 - this.fSuperclassRange[0]);
+		}
+	} else {
+		return null;
+	}
+}
+/**
+ * @see IDOMType#getSuperInterfaces()
+ */
+public String[] getSuperInterfaces() {
+	return this.fSuperInterfaces;
+}
+/**
+ * @see IDOMNode
+ */
+public boolean isAllowableChild(IDOMNode node) {
+	if (node != null) {
+		int type= node.getNodeType();
+		return type == IDOMNode.TYPE || type == IDOMNode.FIELD|| type == IDOMNode.METHOD ||
+			type == IDOMNode.INITIALIZER;
+	} else {
+		return false;
+	}
+
+}
+/**
+ * @see IDOMType#isClass()
+ */
+public boolean isClass() {
+	return getMask(MASK_TYPE_IS_CLASS);
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+	return new DOMType();
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s source positions to include whitespace preceeding
+ * the node on the line on which the node starts, and all whitespace after the node up to
+ * the next node's start
+ */
+void normalize(ILineStartFinder finder) {
+	// perform final changes to the open and close body ranges
+	int openBodyEnd, openBodyStart, closeBodyStart, closeBodyEnd;
+	DOMNode first = (DOMNode) getFirstChild();
+	DOMNode lastNode = null;
+	// look for the open body
+	Scanner scanner = new Scanner();
+	scanner.setSource(this.fDocument);
+	scanner.resetTo(this.fNameRange[1] + 1, this.fDocument.length);
+
+	try {
+		int currentToken = scanner.getNextToken();
+		while(currentToken != TerminalTokens.TokenNameLBRACE &&
+				currentToken != TerminalTokens.TokenNameEOF) {
+			currentToken = scanner.getNextToken();
+		}
+		if(currentToken == TerminalTokens.TokenNameLBRACE) {
+			openBodyEnd = scanner.currentPosition - 1;
+			openBodyStart = scanner.startPosition;
+		} else {
+			openBodyEnd = this.fDocument.length;
+			openBodyStart = this.fDocument.length;
+		}
+	} catch(InvalidInputException e) {
+		openBodyEnd = this.fDocument.length;
+		openBodyStart = this.fDocument.length;
+	}
+	if (first != null) {
+		int lineStart = finder.getLineStart(first.getStartPosition());
+		if (lineStart > openBodyEnd) {
+			openBodyEnd = lineStart - 1;
+		} else {
+			openBodyEnd = first.getStartPosition() - 1;
+		}
+		lastNode = (DOMNode) first.getNextNode();
+		if (lastNode == null) {
+			lastNode = first;
+		} else {
+			while (lastNode.getNextNode() != null) {
+				lastNode = (DOMNode) lastNode.getNextNode();
+			}
+		}
+		scanner.setSource(this.fDocument);
+		scanner.resetTo(lastNode.getEndPosition() + 1, this.fDocument.length);
+		try {
+			int currentToken = scanner.getNextToken();
+			while(currentToken != TerminalTokens.TokenNameRBRACE &&
+					currentToken != TerminalTokens.TokenNameEOF) {
+				currentToken = scanner.getNextToken();
+			}
+			if(currentToken == TerminalTokens.TokenNameRBRACE) {
+				closeBodyStart = scanner.startPosition;
+				closeBodyEnd = scanner.currentPosition - 1;
+			} else {
+				closeBodyStart = this.fDocument.length;
+				closeBodyEnd = this.fDocument.length;
+			}
+		} catch(InvalidInputException e) {
+			closeBodyStart = this.fDocument.length;
+			closeBodyEnd = this.fDocument.length;
+		}
+	} else {
+		scanner.resetTo(openBodyEnd, this.fDocument.length);
+		try {
+			int currentToken = scanner.getNextToken();
+			while(currentToken != TerminalTokens.TokenNameRBRACE &&
+					currentToken != TerminalTokens.TokenNameEOF) {
+				currentToken = scanner.getNextToken();
+			}
+			if(currentToken == TerminalTokens.TokenNameRBRACE) {
+				closeBodyStart = scanner.startPosition;
+				closeBodyEnd = scanner.currentPosition - 1;
+			} else {
+				closeBodyStart = this.fDocument.length;
+				closeBodyEnd = this.fDocument.length;
+			}
+		} catch(InvalidInputException e) {
+			closeBodyStart = this.fDocument.length;
+			closeBodyEnd = this.fDocument.length;
+		}
+		openBodyEnd = closeBodyEnd - 1;
+	}
+	setOpenBodyRangeEnd(openBodyEnd);
+	setOpenBodyRangeStart(openBodyStart);
+	setCloseBodyRangeStart(closeBodyStart);
+	setCloseBodyRangeEnd(closeBodyEnd);
+	this.fInsertionPosition = finder.getLineStart(closeBodyStart);
+	if (lastNode != null && this.fInsertionPosition < lastNode.getEndPosition()) {
+		this.fInsertionPosition = getCloseBodyPosition();
+	}
+	if (this.fInsertionPosition <= openBodyEnd) {
+		this.fInsertionPosition = getCloseBodyPosition();
+	}
+	super.normalize(finder);
+}
+
+/**
+ * Normalizes this <code>DOMNode</code>'s end position.
+ */
+void normalizeEndPosition(ILineStartFinder finder, DOMNode next) {
+	if (next == null) {
+		// this node's end position includes all of the characters up
+		// to the end of the enclosing node
+		DOMNode parent = (DOMNode) getParent();
+		if (parent == null || parent instanceof DOMCompilationUnit) {
+			setSourceRangeEnd(this.fDocument.length - 1);
+		} else {
+			// parent is a type
+			setSourceRangeEnd(((DOMType)parent).getCloseBodyPosition() - 1);
+		}
+	} else {
+		// this node's end position is just before the start of the next node
+		next.normalizeStartPosition(getEndPosition(), finder);
+		setSourceRangeEnd(next.getStartPosition() - 1);
+	}
+}
+
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+	super.offset(offset);
+	offsetRange(this.fCloseBodyRange, offset);
+	offsetRange(this.fExtendsRange, offset);
+	offsetRange(this.fImplementsRange, offset);
+	offsetRange(this.fInterfacesRange, offset);
+	offsetRange(this.fOpenBodyRange, offset);
+	offsetRange(this.fSuperclassRange, offset);
+	offsetRange(this.fTypeRange, offset);
+}
+/**
+ * @see IDOMType#setClass(boolean)
+ */
+public void setClass(boolean b) {
+	becomeDetailed();
+	fragment();
+	setMask(MASK_TYPE_IS_CLASS, b);
+	if (b) {
+		this.fTypeKeyword= "class"; //$NON-NLS-1$
+	} else {
+		this.fTypeKeyword= "interface"; //$NON-NLS-1$
+		setSuperclass(null);
+	}
+}
+/**
+ * Sets the end of the close body range
+ */
+void setCloseBodyRangeEnd(int end) {
+	this.fCloseBodyRange[1] = end;
+}
+/**
+ * Sets the start of the close body range
+ */
+void setCloseBodyRangeStart(int start) {
+	this.fCloseBodyRange[0] = start;
+}
+/**
+ * Sets the name of this node.
+ *
+ * <p>When the name of a type is set, all of its constructors must be marked
+ * as fragmented, since the names of the constructors must reflect the name
+ * of this type.
+ *
+ * @see IDOMNode#setName(String)
+ */
+public void setName(String name) throws IllegalArgumentException {
+	if (name == null) {
+		throw new IllegalArgumentException(Messages.element_nullName);
+	}
+	super.setName(name);
+	Enumeration children= getChildren();
+	while (children.hasMoreElements()) {
+		IDOMNode child= (IDOMNode)children.nextElement();
+		if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) {
+			((DOMNode)child).fragment();
+		}
+	}
+}
+/**
+ * Sets the end of the open body range
+ */
+void setOpenBodyRangeEnd(int end) {
+	this.fOpenBodyRange[1] = end;
+}
+/**
+ * Sets the start of the open body range
+ */
+void setOpenBodyRangeStart(int start) {
+	this.fOpenBodyRange[0] = start;
+}
+/**
+ * @see IDOMType#setSuperclass(String)
+ */
+public void setSuperclass(String superclassName) {
+	becomeDetailed();
+	fragment();
+	this.fSuperclass= superclassName;
+	setMask(MASK_TYPE_HAS_SUPERCLASS, superclassName != null);
+}
+/**
+ * @see IDOMType#setSuperInterfaces(String[])
+ */
+public void setSuperInterfaces(String[] names) {
+	becomeDetailed();
+	if (names == null) {
+		throw new IllegalArgumentException(Messages.dom_nullInterfaces);
+	}
+	fragment();
+	this.fSuperInterfaces= names;
+	if (names.length == 0) {
+		this.fInterfaces= null;
+		this.fSuperInterfaces= CharOperation.NO_STRINGS;
+		setMask(MASK_TYPE_HAS_INTERFACES, false);
+	} else {
+		setMask(MASK_TYPE_HAS_INTERFACES, true);
+		CharArrayBuffer buffer = new CharArrayBuffer();
+		for (int i = 0; i < names.length; i++) {
+			if (i > 0) {
+				buffer.append(", "); //$NON-NLS-1$
+			}
+			buffer.append(names[i]);
+		}
+		this.fInterfaces = buffer.getContents();
+	}
+}
+/**
+ * Sets the type keyword
+ */
+void setTypeKeyword(String keyword) {
+	this.fTypeKeyword = keyword;
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+	super.shareContents(node);
+	DOMType type= (DOMType)node;
+	this.fCloseBodyRange= rangeCopy(type.fCloseBodyRange);
+	this.fExtendsRange= type.fExtendsRange;
+	this.fImplementsRange= rangeCopy(type.fImplementsRange);
+	this.fInterfaces= type.fInterfaces;
+	this.fInterfacesRange= rangeCopy(type.fInterfacesRange);
+	this.fOpenBodyRange= rangeCopy(type.fOpenBodyRange);
+	this.fSuperclass= type.fSuperclass;
+	this.fSuperclassRange= rangeCopy(type.fSuperclassRange);
+	this.fSuperInterfaces= type.fSuperInterfaces;
+	this.fTypeKeyword= type.fTypeKeyword;
+	this.fTypeRange= rangeCopy(type.fTypeRange);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+	return "TYPE: " + getName(); //$NON-NLS-1$
+}
+
+/**
+ * @see IDOMType#getTypeParameters()
+ * @since 3.0
+ */
+public String[] getTypeParameters() {
+	return this.fTypeParameters;
+}
+
+/**
+ * @see IDOMType#isEnum()
+ * @since 3.0
+ */
+public boolean isEnum() {
+	return this.fIsEnum;
+}
+
+/**
+ * @see IDOMType#isAnnotation()
+ * @since 3.0
+ */
+public boolean isAnnotation() {
+	return this.fIsAnnotation;
+}
+
+/**
+ * @see IDOMType#setEnum(boolean)
+ * @since 3.0
+ */
+public void setEnum(boolean b) {
+	this.fIsEnum = b;
+	if (this.fIsEnum) {
+		// enums are always classes with no superclass
+		setClass(true);
+		setSuperclass(null);
+	}
+}
+
+/**
+ * @see IDOMType#setAnnotation(boolean)
+ * @since 3.0
+ */
+public void setAnnotation(boolean b) {
+	this.fIsAnnotation= b;
+	if (this.fIsAnnotation) {
+		// annotation types are always interface with no superclass or superinterfaces
+		setClass(false);
+		setSuperclass(null);
+		setSuperInterfaces(CharOperation.NO_STRINGS);
+	}
+}
+
+/**
+ * @see IDOMType#setTypeParameters(java.lang.String[])
+ * @since 3.0
+ */
+public void setTypeParameters(String[] typeParameters) {
+	this.fTypeParameters = typeParameters;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java
new file mode 100644
index 0000000..db9bcba
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+/**
+ * The <coe>ILineSeparatorFinder</code> finds previous and next line separators
+ * in source.
+ */
+public interface ILineStartFinder {
+/**
+ * Returns the position of the start of the line at or before the given source position.
+ *
+ * <p>This defaults to zero if the position corresponds to a position on the first line
+ * of the source.
+ */
+public int getLineStart(int position);
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java
new file mode 100644
index 0000000..9cb867f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Enumeration;
+
+import org.eclipse.jdt.core.jdom.*;
+
+/**
+ * SiblingEnumeration provides an enumeration on a linked list
+ * of sibling DOM nodes.
+ *
+ * @see java.util.Enumeration
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+/* package */ class SiblingEnumeration implements Enumeration {
+
+	/**
+	 * The current location in the linked list
+	 * of DOM nodes.
+	 */
+	protected IDOMNode fCurrentElement;
+/**
+ * Creates an enumeration of silbings starting at the given node.
+ * If the given node is <code>null</code> the enumeration is empty.
+ */
+SiblingEnumeration(IDOMNode child) {
+	this.fCurrentElement= child;
+}
+/**
+ * @see java.util.Enumeration#hasMoreElements()
+ */
+public boolean hasMoreElements() {
+	return this.fCurrentElement != null;
+}
+/**
+ * @see java.util.Enumeration#nextElement()
+ */
+public Object nextElement() {
+	IDOMNode curr=  this.fCurrentElement;
+	if (curr != null) {
+		this.fCurrentElement= this.fCurrentElement.getNextNode();
+	}
+	return curr;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java
new file mode 100644
index 0000000..c7d7cdd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.jdom;
+
+import java.util.Map;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+/**
+ * A DOM builder that uses the SourceElementParser
+ * @deprecated The JDOM was made obsolete by the addition in 2.0 of the more
+ * powerful, fine-grained DOM/AST API found in the
+ * org.eclipse.jdt.core.dom package.
+ */
+public class SimpleDOMBuilder extends AbstractDOMBuilder implements ISourceElementRequestor {
+
+/**
+ * Does nothing.
+ */
+public void acceptProblem(CategorizedProblem problem) {
+	// nothing to do
+}
+
+public void acceptImport(int declarationStart, int declarationEnd, int nameStart, int nameEnd, char[][] tokens, boolean onDemand, int modifiers) {
+	int[] sourceRange = {declarationStart, declarationEnd};
+	String importName = new String(CharOperation.concatWith(tokens, '.'));
+	/** name is set to contain the '*' */
+	if (onDemand) {
+		importName+=".*"; //$NON-NLS-1$
+	}
+	this.fNode= new DOMImport(this.fDocument, sourceRange, importName, onDemand, modifiers);
+	addChild(this.fNode);
+}
+public void acceptPackage(ImportReference importReference) {
+	int[] sourceRange= new int[] {importReference.declarationSourceStart, importReference.declarationSourceEnd};
+	char[] name = CharOperation.concatWith(importReference.getImportName(), '.');
+	this.fNode= new DOMPackage(this.fDocument, sourceRange, new String(name));
+	addChild(this.fNode);
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(String sourceCode, String name) {
+	return createCompilationUnit(sourceCode.toCharArray(), name.toCharArray());
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
+	initializeBuild(compilationUnit.getContents(), true, true);
+	getParser(JavaCore.getOptions()).parseCompilationUnit(compilationUnit, false/*diet parse*/, null/*no progress*/);
+	return super.createCompilationUnit(compilationUnit);
+}
+/**
+ * Creates a new DOMMethod and inizializes.
+ */
+protected void enterAbstractMethod(MethodInfo methodInfo) {
+
+	int[] sourceRange = {methodInfo.declarationStart, -1}; // will be fixed up on exit
+	int[] nameRange = {methodInfo.nameSourceStart, methodInfo.nameSourceEnd};
+	this.fNode = new DOMMethod(this.fDocument, sourceRange, CharOperation.charToString(methodInfo.name), nameRange, methodInfo.modifiers,
+		methodInfo.isConstructor, CharOperation.charToString(methodInfo.returnType),
+		CharOperation.charArrayToStringArray(methodInfo.parameterTypes),
+		CharOperation.charArrayToStringArray(methodInfo.parameterNames),
+		CharOperation.charArrayToStringArray(methodInfo.exceptionTypes));
+	addChild(this.fNode);
+	this.fStack.push(this.fNode);
+
+	// type parameters not supported by JDOM
+}
+/**
+ */
+public void enterConstructor(MethodInfo methodInfo) {
+	/* see 1FVIIQZ */
+	String nameString = new String(this.fDocument, methodInfo.nameSourceStart, methodInfo.nameSourceEnd - methodInfo.nameSourceStart);
+	int openParenPosition = nameString.indexOf('(');
+	if (openParenPosition > -1)
+		methodInfo.nameSourceEnd = methodInfo.nameSourceStart + openParenPosition - 1;
+
+	enterAbstractMethod(methodInfo);
+}
+/**
+ */
+public void enterField(FieldInfo fieldInfo) {
+
+	int[] sourceRange = {fieldInfo.declarationStart, -1};
+	int[] nameRange = {fieldInfo.nameSourceStart, fieldInfo.nameSourceEnd};
+	boolean isSecondary= false;
+	if (this.fNode instanceof DOMField) {
+		isSecondary = fieldInfo.declarationStart == this.fNode.fSourceRange[0];
+	}
+	this.fNode = new DOMField(this.fDocument, sourceRange, CharOperation.charToString(fieldInfo.name), nameRange,
+		fieldInfo.modifiers, CharOperation.charToString(fieldInfo.type), isSecondary);
+	addChild(this.fNode);
+	this.fStack.push(this.fNode);
+}
+/**
+
+ */
+public void enterInitializer(int declarationSourceStart, int modifiers) {
+	int[] sourceRange = {declarationSourceStart, -1};
+	this.fNode = new DOMInitializer(this.fDocument, sourceRange, modifiers);
+	addChild(this.fNode);
+	this.fStack.push(this.fNode);
+}
+/**
+ */
+public void enterMethod(MethodInfo methodInfo) {
+	enterAbstractMethod(methodInfo);
+}
+/**
+ */
+public void enterType(TypeInfo typeInfo) {
+	if (this.fBuildingType) {
+		int[] sourceRange = {typeInfo.declarationStart, -1}; // will be fixed in the exit
+		int[] nameRange = new int[] {typeInfo.nameSourceStart, typeInfo.nameSourceEnd};
+		this.fNode = new DOMType(this.fDocument, sourceRange, new String(typeInfo.name), nameRange,
+			typeInfo.modifiers, CharOperation.charArrayToStringArray(typeInfo.superinterfaces), TypeDeclaration.kind(typeInfo.modifiers) == TypeDeclaration.CLASS_DECL); // TODO (jerome) should pass in kind
+		addChild(this.fNode);
+		this.fStack.push(this.fNode);
+
+		// type parameters not supported by JDOM
+	}
+}
+/**
+ * Finishes the configuration of the method DOM object which
+ * was created by a previous enterConstructor call.
+ *
+ * @see ISourceElementRequestor#exitConstructor(int)
+ */
+public void exitConstructor(int declarationEnd) {
+	exitMember(declarationEnd);
+}
+/**
+ */
+public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
+	exitMember(declarationEnd);
+}
+/**
+ */
+public void exitInitializer(int declarationEnd) {
+	exitMember(declarationEnd);
+}
+/**
+ * Finishes the configuration of the member.
+ *
+ * @param declarationEnd - a source position corresponding to the end of the method
+ *		declaration.  This can include whitespace and comments following the closing bracket.
+ */
+protected void exitMember(int declarationEnd) {
+	DOMMember m= (DOMMember) this.fStack.pop();
+	m.setSourceRangeEnd(declarationEnd);
+	this.fNode = m;
+}
+/**
+ */
+public void exitMethod(int declarationEnd, Expression defaultValue) {
+	exitMember(declarationEnd);
+}
+/**
+ * @see AbstractDOMBuilder#exitType
+ *
+ * @param declarationEnd - a source position corresponding to the end of the class
+ *		declaration.  This can include whitespace and comments following the closing bracket.
+ */
+public void exitType(int declarationEnd) {
+	exitType(declarationEnd, declarationEnd);
+}
+/**
+ * Creates a new parser.
+ */
+protected SourceElementParser getParser(Map settings) {
+	return new SourceElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings), false/*don't report local declarations*/, true/*optimize string literals*/);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java
new file mode 100644
index 0000000..59300e1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.core.SourceRefElement;
+import org.eclipse.jdt.internal.core.SourceType;
+
+/**
+ * Finds an ASTNode given an IJavaElement in a CompilationUnitDeclaration
+ */
+public class ASTNodeFinder {
+	private CompilationUnitDeclaration unit;
+
+	public ASTNodeFinder(CompilationUnitDeclaration unit) {
+		this.unit = unit;
+	}
+
+	/*
+	 * Finds the FieldDeclaration in the given ast corresponding to the given field handle.
+	 * Returns null if not found.
+	 */
+	public FieldDeclaration findField(IField fieldHandle) {
+		TypeDeclaration typeDecl = findType((IType)fieldHandle.getParent());
+		if (typeDecl == null) return null;
+		FieldDeclaration[] fields = typeDecl.fields;
+		if (fields != null) {
+			char[] fieldName = fieldHandle.getElementName().toCharArray();
+			for (int i = 0, length = fields.length; i < length; i++) {
+				FieldDeclaration field = fields[i];
+				if (CharOperation.equals(fieldName, field.name)) {
+					return field;
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Finds the Initializer in the given ast corresponding to the given initializer handle.
+	 * Returns null if not found.
+	 */
+	public Initializer findInitializer(IInitializer initializerHandle) {
+		TypeDeclaration typeDecl = findType((IType)initializerHandle.getParent());
+		if (typeDecl == null) return null;
+		FieldDeclaration[] fields = typeDecl.fields;
+		if (fields != null) {
+			int occurenceCount = ((SourceRefElement)initializerHandle).occurrenceCount;
+			for (int i = 0, length = fields.length; i < length; i++) {
+				FieldDeclaration field = fields[i];
+				if (field instanceof Initializer && --occurenceCount == 0) {
+					return (Initializer)field;
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Finds the AbstractMethodDeclaration in the given ast corresponding to the given method handle.
+	 * Returns null if not found.
+	 */
+	public AbstractMethodDeclaration findMethod(IMethod methodHandle) {
+		TypeDeclaration typeDecl = findType((IType)methodHandle.getParent());
+		if (typeDecl == null) return null;
+		AbstractMethodDeclaration[] methods = typeDecl.methods;
+		if (methods != null) {
+			char[] selector = methodHandle.getElementName().toCharArray();
+			String[] parameterTypeSignatures = methodHandle.getParameterTypes();
+			int parameterCount = parameterTypeSignatures.length;
+			nextMethod: for (int i = 0, length = methods.length; i < length; i++) {
+				AbstractMethodDeclaration method = methods[i];
+				if (CharOperation.equals(selector, method.selector)) {
+					Argument[] args = method.arguments;
+					int argsLength = args == null ? 0 : args.length;
+					if (argsLength == parameterCount) {
+						for (int j = 0; j < parameterCount; j++) {
+							TypeReference type = args[j].type;
+							String signature = Util.typeSignature(type);
+							if (!signature.equals(parameterTypeSignatures[j])) {
+								continue nextMethod;
+							}
+						}
+						return method;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Finds the TypeDeclaration in the given ast corresponding to the given type handle.
+	 * Returns null if not found.
+	 */
+	public TypeDeclaration findType(IType typeHandle) {
+		IJavaElement parent = typeHandle.getParent();
+		final char[] typeName = typeHandle.getElementName().toCharArray();
+		final int occurenceCount = ((SourceType)typeHandle).occurrenceCount;
+		final boolean findAnonymous = typeName.length == 0;
+		class Visitor extends ASTVisitor {
+			TypeDeclaration result;
+			int count = 0;
+			public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+				if (this.result != null) return false;
+				if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+					if (findAnonymous && ++this.count == occurenceCount) {
+						this.result = typeDeclaration;
+					}
+				} else {
+					if (!findAnonymous && CharOperation.equals(typeName, typeDeclaration.name)) {
+						this.result = typeDeclaration;
+					}
+				}
+				return false; // visit only one level
+			}
+		}
+		switch (parent.getElementType()) {
+			case IJavaElement.COMPILATION_UNIT:
+				TypeDeclaration[] types = this.unit.types;
+				if (types != null) {
+					for (int i = 0, length = types.length; i < length; i++) {
+						TypeDeclaration type = types[i];
+						if (CharOperation.equals(typeName, type.name)) {
+							return type;
+						}
+					}
+				}
+				break;
+			case IJavaElement.TYPE:
+				TypeDeclaration parentDecl = findType((IType)parent);
+				if (parentDecl == null) return null;
+				types = parentDecl.memberTypes;
+				if (types != null) {
+					for (int i = 0, length = types.length; i < length; i++) {
+						TypeDeclaration type = types[i];
+						if (CharOperation.equals(typeName, type.name)) {
+							return type;
+						}
+					}
+				}
+				break;
+			case IJavaElement.FIELD:
+				FieldDeclaration fieldDecl = findField((IField)parent);
+				if (fieldDecl == null) return null;
+				Visitor visitor = new Visitor();
+				fieldDecl.traverse(visitor, null);
+				return visitor.result;
+			case IJavaElement.INITIALIZER:
+				Initializer initializer = findInitializer((IInitializer)parent);
+				if (initializer == null) return null;
+				visitor = new Visitor();
+				initializer.traverse(visitor, null);
+				return visitor.result;
+			case IJavaElement.METHOD:
+				AbstractMethodDeclaration methodDecl = findMethod((IMethod)parent);
+				if (methodDecl == null) return null;
+				visitor = new Visitor();
+				methodDecl.traverse(visitor, (ClassScope)null);
+				return visitor.result;
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java
new file mode 100644
index 0000000..e4c41ef
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotation;
+import org.eclipse.jdt.core.util.IAnnotationComponent;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IAnnotation
+ */
+public class Annotation extends ClassFileStruct implements IAnnotation {
+
+	private static final IAnnotationComponent[] NO_ENTRIES = new IAnnotationComponent[0];
+
+	private int typeIndex;
+	private char[] typeName;
+	private int componentsNumber;
+	private IAnnotationComponent[] components;
+	private int readOffset;
+
+	/**
+	 * Constructor for Annotation.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public Annotation(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+
+		final int index = u2At(classFileBytes, 0, offset);
+		this.typeIndex = index;
+		if (index != 0) {
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.typeName = constantPoolEntry.getUtf8Value();
+		} else {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		final int length = u2At(classFileBytes, 2, offset);
+		this.componentsNumber = length;
+		this.readOffset = 4;
+		if (length != 0) {
+			this.components = new IAnnotationComponent[length];
+			for (int i = 0; i < length; i++) {
+				AnnotationComponent component = new AnnotationComponent(classFileBytes, constantPool, offset + this.readOffset);
+				this.components[i] = component;
+				this.readOffset += component.sizeInBytes();
+			}
+		} else {
+			this.components = NO_ENTRIES;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getTypeIndex()
+	 */
+	public int getTypeIndex() {
+		return this.typeIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getComponentsNumber()
+	 */
+	public int getComponentsNumber() {
+		return this.componentsNumber;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getComponents()
+	 */
+	public IAnnotationComponent[] getComponents() {
+		return this.components;
+	}
+
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getTypeName()
+	 */
+	public char[] getTypeName() {
+		return this.typeName;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java
new file mode 100644
index 0000000..f1a8bd0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotationComponent;
+import org.eclipse.jdt.core.util.IAnnotationComponentValue;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IAnnotationComponent
+ */
+public class AnnotationComponent extends ClassFileStruct implements IAnnotationComponent {
+
+	private int componentNameIndex;
+	private char[] componentName;
+	private IAnnotationComponentValue componentValue;
+	private int readOffset;
+
+	public AnnotationComponent(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		final int nameIndex = u2At(classFileBytes, 0, offset);
+		this.componentNameIndex = nameIndex;
+		if (nameIndex != 0) {
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(nameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.componentName = constantPoolEntry.getUtf8Value();
+		}
+		this.readOffset = 2;
+		AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + this.readOffset);
+		this.componentValue = value;
+		this.readOffset += value.sizeInBytes();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentNameIndex()
+	 */
+	public int getComponentNameIndex() {
+		return this.componentNameIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentName()
+	 */
+	public char[] getComponentName() {
+		return this.componentName;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentValue()
+	 */
+	public IAnnotationComponentValue getComponentValue() {
+		return this.componentValue;
+	}
+
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java
new file mode 100644
index 0000000..ecaff8c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotation;
+import org.eclipse.jdt.core.util.IAnnotationComponentValue;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IAnnotationComponent
+ */
+public class AnnotationComponentValue extends ClassFileStruct implements IAnnotationComponentValue {
+	private static final IAnnotationComponentValue[] NO_VALUES = new AnnotationComponentValue[0];
+
+	private IAnnotationComponentValue[] annotationComponentValues;
+	private IAnnotation annotationValue;
+	private IConstantPoolEntry classInfo;
+	private int classFileInfoIndex;
+	private IConstantPoolEntry constantValue;
+	private int constantValueIndex;
+	private int enumConstantTypeNameIndex;
+	private int enumConstantNameIndex;
+	private char[] enumConstantTypeName;
+	private char[] enumConstantName;
+
+	private int readOffset;
+	private int tag;
+	private int valuesNumber;
+
+	public AnnotationComponentValue(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		this.classFileInfoIndex = -1;
+		this.constantValueIndex = -1;
+		this.enumConstantTypeNameIndex = -1;
+		this.enumConstantNameIndex = -1;
+		final int t = u1At(classFileBytes, 0, offset);
+		this.tag = t;
+		this.readOffset = 1;
+		switch(t) {
+			case 'B' :
+			case 'C' :
+			case 'D' :
+			case 'F' :
+			case 'I' :
+			case 'J' :
+			case 'S' :
+			case 'Z' :
+			case 's' :
+				final int constantIndex = u2At(classFileBytes, this.readOffset, offset);
+				this.constantValueIndex = constantIndex;
+				if (constantIndex != 0) {
+					IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(constantIndex);
+					switch(constantPoolEntry.getKind()) {
+						case IConstantPoolConstant.CONSTANT_Long :
+						case IConstantPoolConstant.CONSTANT_Float :
+						case IConstantPoolConstant.CONSTANT_Double :
+						case IConstantPoolConstant.CONSTANT_Integer :
+						case IConstantPoolConstant.CONSTANT_Utf8 :
+							break;
+						default :
+							throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					this.constantValue = constantPoolEntry;
+				}
+				this.readOffset += 2;
+				break;
+			case 'e' :
+				int index = u2At(classFileBytes, this.readOffset, offset);
+				this.enumConstantTypeNameIndex = index;
+				if (index != 0) {
+					IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					this.enumConstantTypeName = constantPoolEntry.getUtf8Value();
+				}
+				this.readOffset += 2;
+				index = u2At(classFileBytes, this.readOffset, offset);
+				this.enumConstantNameIndex = index;
+				if (index != 0) {
+					IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					this.enumConstantName = constantPoolEntry.getUtf8Value();
+				}
+				this.readOffset += 2;
+				break;
+			case 'c' :
+				final int classFileIndex = u2At(classFileBytes, this.readOffset, offset);
+				this.classFileInfoIndex = classFileIndex;
+				if (classFileIndex != 0) {
+					IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(classFileIndex);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					this.classInfo = constantPoolEntry;
+				}
+				this.readOffset += 2;
+				break;
+			case '@' :
+				Annotation annotation = new Annotation(classFileBytes, constantPool, this.readOffset + offset);
+				this.annotationValue = annotation;
+				this.readOffset += annotation.sizeInBytes();
+				break;
+			case '[' :
+				final int numberOfValues = u2At(classFileBytes, this.readOffset, offset);
+				this.valuesNumber = numberOfValues;
+				this.readOffset += 2;
+				if (numberOfValues != 0) {
+					this.annotationComponentValues = new IAnnotationComponentValue[numberOfValues];
+					for (int i = 0; i < numberOfValues; i++) {
+						AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + this.readOffset);
+						this.annotationComponentValues[i] = value;
+						this.readOffset += value.sizeInBytes();
+					}
+				} else {
+					this.annotationComponentValues = NO_VALUES;
+				}
+				break;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationComponentValues()
+	 */
+	public IAnnotationComponentValue[] getAnnotationComponentValues() {
+		return this.annotationComponentValues;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationValue()
+	 */
+	public IAnnotation getAnnotationValue() {
+		return this.annotationValue;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo()
+	 */
+	public IConstantPoolEntry getClassInfo() {
+		return this.classInfo;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfoIndex()
+	 */
+	public int getClassInfoIndex() {
+		return this.classFileInfoIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValue()
+	 */
+	public IConstantPoolEntry getConstantValue() {
+		return this.constantValue;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValueIndex()
+	 */
+	public int getConstantValueIndex() {
+		return this.constantValueIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantName()
+	 */
+	public char[] getEnumConstantName() {
+		return this.enumConstantName;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantNameIndex()
+	 */
+	public int getEnumConstantNameIndex() {
+		return this.enumConstantNameIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeName()
+	 */
+	public char[] getEnumConstantTypeName() {
+		return this.enumConstantTypeName;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeNameIndex()
+	 */
+	public int getEnumConstantTypeNameIndex() {
+		return this.enumConstantTypeNameIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getTag()
+	 */
+	public int getTag() {
+		return this.tag;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getValuesNumber()
+	 */
+	public int getValuesNumber() {
+		return this.valuesNumber;
+	}
+
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java
new file mode 100644
index 0000000..8951460
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotationComponentValue;
+import org.eclipse.jdt.core.util.IAnnotationDefaultAttribute;
+import org.eclipse.jdt.core.util.IConstantPool;
+
+/**
+ * Default implementation of AnnotationDefaultAttribute.
+ *
+ * @since 3.0
+ */
+public class AnnotationDefaultAttribute extends ClassFileAttribute
+		implements
+			IAnnotationDefaultAttribute {
+
+	private IAnnotationComponentValue memberValue;
+
+	/**
+	 * Constructor for AnnotationDefaultAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public AnnotationDefaultAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset)
+			throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.memberValue = new AnnotationComponentValue(classFileBytes, constantPool, offset + 6);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotationDefaultAttribute#getMemberValue()
+	 */
+	public IAnnotationComponentValue getMemberValue() {
+		return this.memberValue;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
new file mode 100644
index 0000000..aacd3e1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
@@ -0,0 +1,1025 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+public class BindingKeyParser {
+
+	int keyStart;
+
+	static final char C_THROWN = '|';
+
+	static class Scanner {
+		static final int PACKAGE = 0;
+		static final int TYPE = 1;
+		static final int FIELD = 2;
+		static final int METHOD = 3;
+		static final int ARRAY = 4;
+		static final int LOCAL_VAR = 5;
+		static final int FLAGS = 6;
+		static final int WILDCARD = 7;
+		static final int CAPTURE = 8;
+		static final int BASE_TYPE = 9;
+		static final int END = 10;
+
+		static final int START = -1;
+
+		int index = 0, start;
+		char[] source;
+		int token = START;
+
+		Scanner(char[] source) {
+			this.source = source;
+		}
+
+		char[] getTokenSource() {
+			int length = this.index-this.start;
+			char[] result = new char[length];
+			System.arraycopy(this.source, this.start, result, 0, length);
+			return result;
+		}
+
+		boolean isAtAnnotationStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '@';
+		}
+
+		boolean isAtCaptureStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '!';
+		}
+
+		boolean isAtFieldOrMethodStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '.';
+		}
+
+		boolean isAtLocalVariableStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '#';
+		}
+
+		boolean isAtMemberTypeStart() {
+			return
+				this.index < this.source.length
+				&& (this.source[this.index] == '$'
+					|| (this.source[this.index] == '.' && this.source[this.index-1] == '>'));
+		}
+
+		boolean isAtParametersEnd() {
+			return
+				this.index < this.source.length
+					&& this.source[this.index] == '>';
+		}
+
+		boolean isAtParametersStart() {
+			char currentChar;
+			return
+				this.index > 0
+				&& this.index < this.source.length
+				&& ((currentChar = this.source[this.index]) == '<'
+					|| currentChar == '%');
+		}
+
+		boolean isAtRawTypeEnd() {
+			return
+				this.index > 0
+				&& this.index < this.source.length
+				&& this.source[this.index] == '>';
+		}
+
+		boolean isAtSecondaryTypeStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '~';
+		}
+
+		boolean isAtWildcardStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '{';   // e.g {1}+Ljava/lang/String;
+		}
+
+		boolean isAtTypeParameterStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == 'T';
+		}
+
+		boolean isAtTypeArgumentStart() {
+			return this.index < this.source.length && "LIZVCDBFJS[!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
+		}
+
+		boolean isAtThrownStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == C_THROWN;
+		}
+
+		boolean isAtTypeVariableStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == ':';
+		}
+
+		boolean isAtTypeWithCaptureStart() {
+			return
+				this.index < this.source.length
+				&& this.source[this.index] == '&';
+		}
+
+		int nextToken() {
+			int previousTokenEnd = this.index;
+			this.start = this.index;
+			int dollarIndex = -1;
+			int length = this.source.length;
+			while (this.index <= length) {
+				char currentChar = this.index == length ? Character.MIN_VALUE : this.source[this.index];
+				switch (currentChar) {
+					case 'B':
+					case 'C':
+					case 'D':
+					case 'F':
+					case 'I':
+					case 'J':
+					case 'N':
+					case 'S':
+					case 'V':
+					case 'Z':
+						// base type
+						if (this.index == previousTokenEnd
+								&& (this.index == 0 || this.source[this.index-1] != '.')) { // case of field or method starting with one of the character above
+							this.index++;
+							this.token = BASE_TYPE;
+							return this.token;
+						}
+						break;
+					case 'L':
+					case 'T':
+						if (this.index == previousTokenEnd
+								&& (this.index == 0 || this.source[this.index-1] != '.')) { // case of field or method starting with one of the character above
+							this.start = this.index+1;
+							dollarIndex = -1;
+						}
+						break;
+					case ';':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							dollarIndex = -1;
+							previousTokenEnd = this.start;
+						} else {
+							if (dollarIndex != -1) this.index = dollarIndex;
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case '$':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							dollarIndex = -1;
+						} else {
+							if (dollarIndex == -1) {
+								dollarIndex = this.index;
+								break;
+							}
+							this.index = dollarIndex;
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case '~':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							dollarIndex = -1;
+						} else {
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case '.':
+					case '%':
+					case ':':
+					case '>':
+					case '@':
+						this.start = this.index+1;
+						dollarIndex = -1;
+						previousTokenEnd = this.start;
+						break;
+					case '[':
+						while (this.index < length && this.source[this.index] == '[')
+							this.index++;
+						this.token = ARRAY;
+						return this.token;
+					case '<':
+						if (this.start > 0) {
+							switch (this.source[this.start-1]) {
+								case '.':
+									if (this.source[this.start-2] == '>') {
+										// case of member type where enclosing type is parameterized
+										if (dollarIndex != -1) this.index = dollarIndex;
+										this.token = TYPE;
+									} else {
+										this.token = METHOD;
+									}
+									return this.token;
+								default:
+									if (this.index == previousTokenEnd) {
+										this.start = this.index+1;
+										dollarIndex = -1;
+										previousTokenEnd = this.start;
+									} else {
+										if (dollarIndex != -1) this.index = dollarIndex;
+										this.token = TYPE;
+										return this.token;
+									}
+							}
+						}
+						break;
+					case '(':
+						this.token = METHOD;
+						return this.token;
+					case ')':
+						if (this.token == TYPE) {
+							this.token = FIELD;
+							return this.token;
+						}
+						this.start = this.index+1;
+						dollarIndex = -1;
+						previousTokenEnd = this.start;
+						break;
+					case '#':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							dollarIndex = -1;
+							previousTokenEnd = this.start;
+						} else {
+							this.token = LOCAL_VAR;
+							return this.token;
+						}
+						break;
+					case Character.MIN_VALUE:
+						switch (this.token) {
+							case START:
+								this.token = PACKAGE;
+								break;
+							case METHOD:
+							case LOCAL_VAR:
+								this.token = LOCAL_VAR;
+								break;
+							case TYPE:
+								if (this.index > this.start && this.source[this.start-1] == '.')
+									this.token = FIELD;
+								else
+									this.token = END;
+								break;
+							case WILDCARD:
+								this.token = TYPE;
+								break;
+							default:
+								this.token = END;
+								break;
+						}
+						return this.token;
+					case '*':
+					case '+':
+					case '-':
+						this.index++;
+						this.token = WILDCARD;
+						return this.token;
+					case '!':
+					case '&':
+						this.index++;
+						this.token = CAPTURE;
+						return this.token;
+				}
+				this.index++;
+			}
+			this.token = END;
+			return this.token;
+		}
+
+		void skipMethodSignature() {
+			this.start = this.index;
+			int braket = 0;
+			while (this.index < this.source.length) {
+				switch (this.source[this.index]) {
+					case '#':
+					case '%':
+					case '@':
+					case C_THROWN:
+						return;
+					case ':':
+						if (braket == 0)
+							return;
+						break;
+					case '<':
+					case '(':
+						braket++;
+						break;
+					case '>':
+					case ')':
+						braket--;
+						break;
+				}
+				this.index++;
+			}
+		}
+
+		void skipRank() {
+			this.start = this.index;
+			while (this.index < this.source.length && "0123456789".indexOf(this.source[this.index]) != -1) //$NON-NLS-1$
+				this.index++;
+		}
+		
+		void skipThrownStart() {
+			while (this.index < this.source.length && this.source[this.index] == C_THROWN)
+				this.index++;
+		}
+
+		void skipParametersStart() {
+			while (this.index < this.source.length && (this.source[this.index] == '<' || this.source[this.index] == '%'))
+				this.index++;
+		}
+
+		void skipParametersEnd() {
+			while (this.index < this.source.length && this.source[this.index] != '>')
+				this.index++;
+			this.index++;
+		}
+
+		void skipTypeEnd() {
+			if (this.index < this.source.length && this.source[this.index] == ';')
+				this.index++;
+		}
+		
+		void skipRankStart() {
+			if (this.index < this.source.length && this.source[this.index] == '{')
+				this.index++;
+		}
+		
+		void skipRankEnd() {
+			if (this.index < this.source.length && this.source[this.index] == '}')
+				this.index++;
+			this.start = this.index;
+		}
+
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			switch (this.token) {
+				case START:
+					buffer.append("START: "); //$NON-NLS-1$
+					break;
+				case PACKAGE:
+					buffer.append("PACKAGE: "); //$NON-NLS-1$
+					break;
+				case TYPE:
+					buffer.append("TYPE: "); //$NON-NLS-1$
+					break;
+				case FIELD:
+					buffer.append("FIELD: "); //$NON-NLS-1$
+					break;
+				case METHOD:
+					buffer.append("METHOD: "); //$NON-NLS-1$
+					break;
+				case ARRAY:
+					buffer.append("ARRAY: "); //$NON-NLS-1$
+					break;
+				case LOCAL_VAR:
+					buffer.append("LOCAL VAR: "); //$NON-NLS-1$
+					break;
+				case FLAGS:
+					buffer.append("MODIFIERS: "); //$NON-NLS-1$
+					break;
+				case WILDCARD:
+					buffer.append("WILDCARD: "); //$NON-NLS-1$
+					break;
+				case CAPTURE:
+					buffer.append("CAPTURE: "); //$NON-NLS-1$
+					break;
+				case BASE_TYPE:
+					buffer.append("BASE TYPE: "); //$NON-NLS-1$
+					break;
+				case END:
+					buffer.append("END: "); //$NON-NLS-1$
+					break;
+			}
+			if (this.index < 0) {
+				buffer.append("**"); //$NON-NLS-1$
+				buffer.append(this.source);
+			} else if (this.index <= this.source.length) {
+				buffer.append(this.source, 0, this.start);
+				buffer.append('*');
+				if (this.start <= this.index) {
+					buffer.append(this.source, this.start, this.index - this.start);
+					buffer.append('*');
+					buffer.append(this.source, this.index, this.source.length - this.index);
+				} else {
+					buffer.append('*');
+					buffer.append(this.source, this.start, this.source.length - this.start);
+				}
+			} else {
+				buffer.append(this.source);
+				buffer.append("**"); //$NON-NLS-1$
+			}
+			return buffer.toString();
+		}
+	}
+	private boolean parsingPaused;
+
+	private Scanner scanner;
+
+	private boolean hasTypeName = true;
+
+	private boolean isMalformed;
+	
+	private boolean isParsingThrownExceptions = false;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=336451
+
+	public BindingKeyParser(BindingKeyParser parser) {
+		this(""); //$NON-NLS-1$
+		this.scanner = parser.scanner;
+	}
+
+	public BindingKeyParser(String key) {
+		this.scanner = new Scanner(key.toCharArray());
+	}
+
+	public void consumeAnnotation() {
+		// default is to do nothing
+	}
+
+	public void consumeArrayDimension(char[] brakets) {
+		// default is to do nothing
+	}
+
+	public void consumeBaseType(char[] baseTypeSig) {
+		// default is to do nothing
+	}
+
+	public void consumeCapture(int position) {
+		// default is to do nothing
+	}
+
+	public void consumeException() {
+		// default is to do nothing
+	}
+
+	public void consumeField(char[] fieldName) {
+		// default is to do nothing
+	}
+
+	public void consumeParameterizedGenericMethod() {
+		// default is to do nothing
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+		// default is to do nothing
+	}
+
+	public void consumeLocalVar(char[] varName, int occurrenceCount) {
+		// default is to do nothing
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		// default is to do nothing
+	}
+
+	public void consumeModifiers(char[] modifiers) {
+		// default is to do nothing
+	}
+
+	public void consumeNonGenericType() {
+		// default is to do nothing
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		// default is to do nothing
+	}
+
+	public void consumePackage(char[] pkgName) {
+		// default is to do nothing
+	}
+
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		// default is to do nothing
+	}
+
+	public void consumeParser(BindingKeyParser parser) {
+		// default is to do nothing
+	}
+
+	public void consumeRawType() {
+		// default is to do nothing
+	}
+
+	public void consumeScope(int scopeNumber) {
+		// default is to do nothing
+	}
+
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		// default is to do nothing
+	}
+
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		// default is to do nothing
+	}
+
+	public void consumeKey() {
+		// default is to do nothing
+	}
+
+	public void consumeTopLevelType() {
+		// default is to do nothing
+	}
+
+	public void consumeType() {
+		// default is to do nothing
+	}
+
+	public void consumeTypeParameter(char[] typeParameterName) {
+		// default is to do nothing
+	}
+
+	public void consumeTypeVariable(char[] position, char[] typeVariableName) {
+		// default is to do nothing
+	}
+
+	public void consumeTypeWithCapture() {
+		// default is to do nothing
+	}
+
+	public void consumeWildCard(int kind) {
+		// default is to do nothing
+	}
+	
+	public void consumeWildcardRank(int rank) {
+		// default is to do nothing
+	}
+
+	/*
+	 * Returns the string that this binding key wraps.
+	 */
+	public String getKey() {
+		return new String(this.scanner.source);
+	}
+
+	public boolean hasTypeName() {
+		return this.hasTypeName;
+	}
+
+	public void malformedKey() {
+		this.isMalformed = true;
+	}
+
+	public BindingKeyParser newParser() {
+		return new BindingKeyParser(this);
+	}
+
+	public void parse() {
+		parse(false/*don't pause after fully qualified name*/);
+	}
+
+	public void parse(boolean pauseAfterFullyQualifiedName) {
+		if (!this.parsingPaused) {
+			// fully qualified name
+			parseFullyQualifiedName();
+			parseSecondaryType();
+			if (pauseAfterFullyQualifiedName) {
+				this.parsingPaused = true;
+				return;
+			}
+		}
+		if (!hasTypeName()) {
+			consumeKey();
+			return;
+		}
+		consumeTopLevelType();
+		parseInnerType();
+
+		if (this.scanner.isAtParametersStart()) {
+			this.scanner.skipParametersStart();
+			if (this.scanner.isAtTypeParameterStart())	{
+				// generic type
+				parseGenericType();
+			 	// skip ";>"
+			 	this.scanner.skipParametersEnd();
+				// local type in generic type
+				parseInnerType();
+			} else if (this.scanner.isAtTypeArgumentStart())
+				// parameterized type
+				parseParameterizedType(null/*top level type or member type with raw enclosing type*/, false/*no raw*/);
+			else if (this.scanner.isAtRawTypeEnd())
+				// raw type
+				parseRawType();
+		} else {
+			// non-generic type
+			consumeNonGenericType();
+		}
+
+		consumeType();
+		this.scanner.skipTypeEnd();
+
+		if (this.scanner.isAtFieldOrMethodStart()) {
+			switch (this.scanner.nextToken()) {
+				case Scanner.FIELD:
+					parseField();
+					if (this.scanner.isAtAnnotationStart()) {
+						parseAnnotation();
+					}
+					return;
+				case Scanner.METHOD:
+					parseMethod();
+					if (this.scanner.isAtLocalVariableStart()) {
+						parseLocalVariable();
+					} else if (this.scanner.isAtTypeVariableStart()) {
+						parseTypeVariable();
+					} else if (this.scanner.isAtAnnotationStart()) {
+						parseAnnotation();
+					}
+			 		break;
+				default:
+					malformedKey();
+					return;
+			}
+		} else if (!this.isParsingThrownExceptions && this.scanner.isAtTypeVariableStart()) {
+			parseTypeVariable();
+		} else if (this.scanner.isAtWildcardStart()) {
+			parseWildcard();
+		} else if (this.scanner.isAtTypeWithCaptureStart()) {
+			parseTypeWithCapture();
+		} else if (this.scanner.isAtAnnotationStart()) {
+			parseAnnotation();
+		}
+
+		consumeKey();
+	}
+
+	private void parseFullyQualifiedName() {
+		if (this.scanner.isAtCaptureStart()) {
+			parseCapture();
+			this.hasTypeName = false;
+			return;
+		}
+		switch(this.scanner.nextToken()) {
+			case Scanner.PACKAGE:
+				this.keyStart = 0;
+				consumePackage(this.scanner.getTokenSource());
+				this.hasTypeName = false;
+				return;
+			case Scanner.TYPE:
+				this.keyStart = this.scanner.start-1;
+				consumeFullyQualifiedName(this.scanner.getTokenSource());
+				break;
+			case Scanner.BASE_TYPE:
+				this.keyStart = this.scanner.start-1;
+				consumeBaseType(this.scanner.getTokenSource());
+				this.hasTypeName = false;
+				break;
+			case Scanner.ARRAY:
+				this.keyStart = this.scanner.start;
+				consumeArrayDimension(this.scanner.getTokenSource());
+				switch (this.scanner.nextToken()) {
+					case Scanner.TYPE:
+						consumeFullyQualifiedName(this.scanner.getTokenSource());
+						break;
+					case Scanner.BASE_TYPE:
+						consumeBaseType(this.scanner.getTokenSource());
+						this.hasTypeName = false;
+						break;
+					default:
+						malformedKey();
+						return;
+				}
+				break;
+			case Scanner.WILDCARD:
+				// support the '-' in "Lpack/package-info;", see bug 398920
+				if (!CharOperation.endsWith(this.scanner.getTokenSource(), new char[] {'/', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '-'})) {
+					malformedKey();
+					return;
+				}
+				
+				int start = this.scanner.start;
+				if (this.scanner.nextToken() == Scanner.TYPE) {
+					if (!CharOperation.equals(this.scanner.getTokenSource(), new char[] {'i', 'n', 'f', 'o'})) {
+						malformedKey();
+						return;
+					}
+					this.scanner.start = start;
+					this.keyStart = start-1;
+					consumeFullyQualifiedName(this.scanner.getTokenSource());
+					break;
+				}
+				break;
+			default:
+				malformedKey();
+				return;
+		}
+	}
+
+	private void parseParameterizedMethod() {
+		this.scanner.skipParametersStart();
+		while (!this.scanner.isAtParametersEnd() && !this.isMalformed) {
+			parseTypeArgument();
+		}
+		consumeParameterizedGenericMethod();
+	}
+
+	private void parseGenericType() {
+		while (!this.scanner.isAtParametersEnd() && !this.isMalformed) {
+			if (this.scanner.nextToken() != Scanner.TYPE) {
+				malformedKey();
+				return;
+			}
+			consumeTypeParameter(this.scanner.getTokenSource());
+			this.scanner.skipTypeEnd();
+		}
+	}
+
+	private void parseInnerType() {
+		if (!this.scanner.isAtMemberTypeStart() || this.scanner.nextToken() != Scanner.TYPE)
+			return;
+		char[] typeName = this.scanner.getTokenSource();
+		// Might not actually be an inner type but came here as a consequence of '$' being present in type name
+		if (typeName.length == 0)
+			return;
+		if (Character.isDigit(typeName[0])) {
+			// anonymous or local type
+			int nextToken = Scanner.TYPE;
+			while (this.scanner.isAtMemberTypeStart() && !this.isMalformed)
+				nextToken = this.scanner.nextToken();
+			typeName = nextToken == Scanner.END ? this.scanner.source : CharOperation.subarray(this.scanner.source, this.keyStart, this.scanner.index+1);
+			consumeLocalType(typeName);
+		} else {
+			consumeMemberType(typeName);
+			parseInnerType();
+		}
+	}
+
+	private void parseLocalVariable() {
+		if (this.scanner.nextToken() != Scanner.LOCAL_VAR) {
+			malformedKey();
+			return;
+		}
+		char[] varName = this.scanner.getTokenSource();
+		if (Character.isDigit(varName[0])) {
+			int index = Integer.parseInt(new String(varName));
+			consumeScope(index);
+			if (!this.scanner.isAtLocalVariableStart()) {
+				malformedKey();
+				return;
+			}
+			parseLocalVariable();
+		} else {
+			int occurrenceCount = 0;
+			if (this.scanner.isAtLocalVariableStart()) {
+				if (this.scanner.nextToken() != Scanner.LOCAL_VAR) {
+					malformedKey();
+					return;
+				}
+				char[] occurrence = this.scanner.getTokenSource();
+				occurrenceCount = Integer.parseInt(new String(occurrence));
+			}
+			consumeLocalVar(varName, occurrenceCount);
+		}
+	}
+
+	private void parseMethod() {
+		char[] selector = this.scanner.getTokenSource();
+		this.scanner.skipMethodSignature();
+		char[] signature = this.scanner.getTokenSource();
+		consumeMethod(selector, signature);
+		if (this.scanner.isAtThrownStart()) {
+			parseThrownExceptions();
+		}
+		if (this.scanner.isAtParametersStart())
+			parseParameterizedMethod();
+	}
+
+	private void parseAnnotation() {
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		consumeAnnotation();
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+	private void parseCapture() {
+		if (this.scanner.nextToken() != Scanner.CAPTURE) return;
+		parseCaptureWildcard();
+		if (this.scanner.nextToken() != Scanner.TYPE) {
+			malformedKey();
+			return;
+		}
+		char[] positionChars = this.scanner.getTokenSource();
+		int position = Integer.parseInt(new String(positionChars));
+		consumeCapture(position);
+		this.scanner.skipTypeEnd();
+	}
+
+	private void parseCaptureWildcard() {
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+	private void parseField() {
+		char[] fieldName = this.scanner.getTokenSource();
+		parseReturnType();
+ 		consumeField(fieldName);
+	}
+
+	private void parseThrownExceptions() {
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		while (this.scanner.isAtThrownStart() && !this.isMalformed) {
+			this.scanner.skipThrownStart();
+			BindingKeyParser parser = newParser();
+			parser.isParsingThrownExceptions = true;
+			parser.parse();
+			consumeParser(parser);
+			consumeException();
+			this.isMalformed = parser.isMalformed;
+		}
+		this.scanner.token = token;
+	}
+
+	private void parseParameterizedType(char[] typeName, boolean isRaw) {
+		if (!isRaw) {
+			while (!this.scanner.isAtParametersEnd() && !this.isMalformed) {
+				parseTypeArgument();
+			}
+		}
+	 	// skip ";>"
+	 	this.scanner.skipParametersEnd();
+		consumeParameterizedType(typeName, isRaw);
+		this.scanner.skipTypeEnd();
+	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
+	 		typeName = this.scanner.getTokenSource();
+			if (this.scanner.isAtParametersStart()) {
+				this.scanner.skipParametersStart();
+		 		parseParameterizedType(typeName, this.scanner.isAtRawTypeEnd());
+			} else
+				consumeParameterizedType(typeName, true/*raw*/);
+	 	}
+	}
+
+	private void parseRawType() {
+		this.scanner.skipParametersEnd();
+		consumeRawType();
+		this.scanner.skipTypeEnd();
+	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
+	 		char[] typeName = this.scanner.getTokenSource();
+			if (this.scanner.isAtParametersStart()) {
+				this.scanner.skipParametersStart();
+		 		parseParameterizedType(typeName, this.scanner.isAtRawTypeEnd());
+			} else
+				consumeParameterizedType(typeName, true/*raw*/);
+	 	}
+	}
+
+	private void parseReturnType() {
+		this.scanner.index++; // skip ')'
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+	private void parseSecondaryType() {
+		if (!this.scanner.isAtSecondaryTypeStart() || this.scanner.nextToken() != Scanner.TYPE) return;
+		consumeSecondaryType(this.scanner.getTokenSource());
+	}
+
+	private void parseTypeArgument() {
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+	private void parseTypeWithCapture() {
+		if (this.scanner.nextToken() != Scanner.CAPTURE) return;
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		consumeTypeWithCapture();
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+	private void parseTypeVariable() {
+		if (this.scanner.nextToken() != Scanner.TYPE) {
+			malformedKey();
+			return;
+		}
+		char[] typeVariableName = this.scanner.getTokenSource();
+		char[] position;
+		int length = typeVariableName.length;
+		if (length > 0 && Character.isDigit(typeVariableName[0])) {
+			int firstT = CharOperation.indexOf('T', typeVariableName);
+			position = CharOperation.subarray(typeVariableName, 0, firstT);
+			typeVariableName = CharOperation.subarray(typeVariableName, firstT+1, typeVariableName.length);
+		} else {
+			position = CharOperation.NO_CHAR;
+		}
+		consumeTypeVariable(position, typeVariableName);
+		this.scanner.skipTypeEnd();
+	}
+
+	private void parseWildcard() {
+		parseWildcardRank();
+		if (this.scanner.nextToken() != Scanner.WILDCARD) return;
+		char[] source = this.scanner.getTokenSource();
+		if (source.length == 0) {
+			malformedKey();
+			return;
+		}
+		int kind = -1;
+		switch (source[0]) {
+			case '*':
+				kind = Wildcard.UNBOUND;
+				break;
+			case '+':
+				kind = Wildcard.EXTENDS;
+				break;
+			case '-':
+				kind = Wildcard.SUPER;
+				break;
+		}
+		if (kind == -1) {
+			malformedKey();
+			return;
+		}
+		if (kind != Wildcard.UNBOUND)
+			parseWildcardBound();
+		consumeWildCard(kind);
+	}
+
+	private void parseWildcardRank() {
+		this.scanner.skipRankStart();
+		this.scanner.skipRank();
+		char[] source = this.scanner.getTokenSource();
+		consumeWildcardRank(Integer.parseInt(new String(source)));
+		this.scanner.skipRankEnd();
+	}
+	
+	private void parseWildcardBound() {
+		/*
+		 * The call parser.parse() might have a side-effect on the current token type
+		 * See bug 264443
+		 */
+		int token = this.scanner.token;
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+		this.isMalformed = parser.isMalformed;
+		this.scanner.token = token;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
new file mode 100644
index 0000000..2230e8e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
@@ -0,0 +1,660 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+
+public class BindingKeyResolver extends BindingKeyParser {
+	Compiler compiler;
+	Binding compilerBinding;
+
+	char[][] compoundName;
+	int dimension;
+	LookupEnvironment environment;
+	ReferenceBinding genericType;
+	MethodBinding methodBinding;
+	AnnotationBinding annotationBinding;
+
+	char[] secondarySimpleName;
+	CompilationUnitDeclaration parsedUnit;
+	BlockScope scope;
+	TypeBinding typeBinding;
+	TypeDeclaration typeDeclaration;
+	ArrayList types = new ArrayList();
+	
+	int wildcardRank;
+
+	CompilationUnitDeclaration outerMostParsedUnit;
+
+	/*
+	 * A hash set of the file names of already resolved units
+	 */
+	HashtableOfObject resolvedUnits;
+
+	private BindingKeyResolver(BindingKeyParser parser, Compiler compiler, LookupEnvironment environment, CompilationUnitDeclaration outerMostParsedUnit, HashtableOfObject parsedUnits) {
+		super(parser);
+		this.compiler = compiler;
+		this.environment = environment;
+		this.outerMostParsedUnit = outerMostParsedUnit;
+		this.resolvedUnits = parsedUnits;
+	}
+
+	public BindingKeyResolver(String key, Compiler compiler, LookupEnvironment environment) {
+		super(key);
+		this.compiler = compiler;
+		this.environment = environment;
+		this.resolvedUnits = new HashtableOfObject();
+	}
+
+	/*
+	 * If not already cached, computes and cache the compound name (pkg name + top level name) of this key.
+	 * Returns the package name if key is a pkg key.
+	 * Returns an empty array if malformed.
+	 * This key's scanner should be positioned on the package or type token.
+	 */
+	public char[][] compoundName() {
+		return this.compoundName;
+	}
+
+	public void consumeAnnotation() {
+		int size = this.types.size();
+		if (size == 0) return;
+		Binding annotationType = ((BindingKeyResolver) this.types.get(size-1)).compilerBinding;
+		AnnotationBinding[] annotationBindings;
+		if (this.compilerBinding == null && this.typeBinding instanceof ReferenceBinding) {
+			annotationBindings = ((ReferenceBinding) this.typeBinding).getAnnotations();
+		} else if (this.compilerBinding instanceof MethodBinding) {
+			annotationBindings = ((MethodBinding) this.compilerBinding).getAnnotations();
+		} else if (this.compilerBinding instanceof VariableBinding) {
+			annotationBindings = ((VariableBinding) this.compilerBinding).getAnnotations();
+		} else {
+			return;
+		}
+		for (int i = 0, length = annotationBindings.length; i < length; i++) {
+			AnnotationBinding binding = annotationBindings[i];
+			if (binding.getAnnotationType() == annotationType) {
+				this.annotationBinding = binding;
+				break;
+			}
+		}
+	}
+
+	public void consumeArrayDimension(char[] brakets) {
+		this.dimension = brakets.length;
+	}
+
+	public void consumeBaseType(char[] baseTypeSig) {
+		this.compoundName = new char[][] {getKey().toCharArray()};
+		TypeBinding baseTypeBinding = getBaseTypeBinding(baseTypeSig);
+		if (baseTypeBinding != null) {
+			this.typeBinding = baseTypeBinding;
+		}
+	}
+
+	public void consumeCapture(final int position) {
+		CompilationUnitDeclaration outerParsedUnit = this.outerMostParsedUnit == null ? this.parsedUnit : this.outerMostParsedUnit;
+		if (outerParsedUnit == null) return;
+		final Binding wildcardBinding = ((BindingKeyResolver) this.types.get(0)).compilerBinding;
+		class CaptureFinder extends ASTVisitor {
+			CaptureBinding capture;
+			boolean checkType(TypeBinding binding) {
+				if (binding == null)
+					return false;
+				switch (binding.kind()) {
+					case Binding.PARAMETERIZED_TYPE:
+						TypeBinding[] arguments = ((ParameterizedTypeBinding) binding).arguments;
+						if (arguments == null) return false;
+						for (int i = 0, length = arguments.length; i < length; i++) {
+							if (checkType(arguments[i]))
+								return true;
+						}
+						break;
+					case Binding.WILDCARD_TYPE:
+						return checkType(((WildcardBinding) binding).bound);
+					case Binding.INTERSECTION_TYPE:
+						if (checkType(((WildcardBinding) binding).bound))
+							return true;
+						TypeBinding[] otherBounds = ((WildcardBinding) binding).otherBounds;
+						// per construction, otherBounds is never null
+						for (int i = 0, length = otherBounds.length; i < length; i++) {
+							if (checkType(otherBounds[i]))
+								return true;
+						}
+						break;
+					case Binding.ARRAY_TYPE:
+						return checkType(((ArrayBinding) binding).leafComponentType);
+					case Binding.TYPE_PARAMETER:
+						if (binding.isCapture()) {
+							CaptureBinding captureBinding = (CaptureBinding) binding;
+							if (captureBinding.position == position && captureBinding.wildcard == wildcardBinding) {
+								this.capture = captureBinding;
+								return true;
+							}
+						}
+						break;
+				}
+				return false;
+			}
+			public boolean visit(SingleNameReference singleNameReference, BlockScope blockScope) {
+				if (checkType(singleNameReference.resolvedType))
+					return false;
+				return super.visit(singleNameReference, blockScope);
+			}
+			public boolean visit(QualifiedNameReference qualifiedNameReference, BlockScope blockScope) {
+				if (checkType(qualifiedNameReference.resolvedType))
+					return false;
+				return super.visit(qualifiedNameReference, blockScope);
+			}
+			public boolean visit(MessageSend messageSend, BlockScope blockScope) {
+				if (checkType(messageSend.resolvedType))
+					return false;
+				return super.visit(messageSend, blockScope);
+			}
+			public boolean visit(FieldReference fieldReference, BlockScope blockScope) {
+				if (checkType(fieldReference.resolvedType))
+					return false;
+				return super.visit(fieldReference, blockScope);
+			}
+			public boolean visit(ConditionalExpression conditionalExpression, BlockScope blockScope) {
+				if (checkType(conditionalExpression.resolvedType))
+					return false;
+				return super.visit(conditionalExpression, blockScope);
+			}
+			public boolean visit(CastExpression castExpression, BlockScope blockScope) {
+				if (checkType(castExpression.resolvedType))
+					return false;
+				return super.visit(castExpression, blockScope);
+			}
+			public boolean visit(Assignment assignment, BlockScope blockScope) {
+				if (checkType(assignment.resolvedType))
+					return false;
+				return super.visit(assignment, blockScope);
+			}
+			public boolean visit(ArrayReference arrayReference, BlockScope blockScope) {
+				if (checkType(arrayReference.resolvedType))
+					return false;
+				return super.visit(arrayReference, blockScope);
+			}
+		}
+		CaptureFinder captureFinder = new CaptureFinder();
+		outerParsedUnit.traverse(captureFinder, outerParsedUnit.scope);
+		this.typeBinding = captureFinder.capture;
+	}
+
+	public void consumeException() {
+		this.types = new ArrayList();
+	}
+
+	public void consumeField(char[] fieldName) {
+		if (this.typeBinding == null)
+			return;
+		FieldBinding[] fields = ((ReferenceBinding) this.typeBinding).availableFields(); // resilience
+	 	for (int i = 0, length = fields.length; i < length; i++) {
+			FieldBinding field = fields[i];
+			if (CharOperation.equals(fieldName, field.name)) {
+				this.typeBinding = null;
+				this.compilerBinding = field;
+				return;
+			}
+		}
+	}
+
+	public void consumeParameterizedGenericMethod() {
+		if (this.methodBinding == null)
+			return;
+		TypeBinding[] arguments = getTypeBindingArguments();
+		if (arguments == null) {
+			this.methodBinding = null;
+			this.compilerBinding = null;
+			return;
+		}
+		if (arguments.length != this.methodBinding.typeVariables().length)
+			this.methodBinding = this.environment.createParameterizedGenericMethod(this.methodBinding, (RawTypeBinding) null);
+		else
+	 		this.methodBinding = this.environment.createParameterizedGenericMethod(this.methodBinding, arguments);
+		this.compilerBinding = this.methodBinding;
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+ 		LocalTypeBinding[] localTypeBindings  = this.parsedUnit.localTypes;
+ 		for (int i = 0; i < this.parsedUnit.localTypeCount; i++)
+ 			if (CharOperation.equals(uniqueKey, localTypeBindings[i].computeUniqueKey(false/*not a leaf*/))) {
+ 				this.typeBinding = localTypeBindings[i];
+ 				return;
+ 			}
+	}
+
+	public void consumeLocalVar(char[] varName, int occurrenceCount) {
+		if (this.scope == null) {
+			if (this.methodBinding == null)
+				return;
+			this.scope = this.methodBinding.sourceMethod().scope;
+		}
+	 	for (int i = 0; i < this.scope.localIndex; i++) {
+			LocalVariableBinding local = this.scope.locals[i];
+			if (CharOperation.equals(local.name, varName)
+					&& occurrenceCount-- == 0) {
+				this.methodBinding = null;
+				this.compilerBinding = local;
+				return;
+			}
+		}
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		if (this.typeBinding == null)
+			return;
+		MethodBinding[] methods = ((ReferenceBinding) this.typeBinding).availableMethods(); // resilience
+	 	for (int i = 0, methodLength = methods.length; i < methodLength; i++) {
+			MethodBinding method = methods[i];
+			if (CharOperation.equals(selector, method.selector) || (selector.length == 0 && method.isConstructor())) {
+				char[] methodSignature = method.genericSignature();
+				if (methodSignature == null)
+					methodSignature = method.signature();
+				if (CharOperation.equals(signature, methodSignature)) {
+					this.typeBinding = null;
+					this.methodBinding = method;
+					this.compilerBinding = this.methodBinding;
+					return;
+				} else if ((method.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+					this.typeBinding = null;
+					char[][] typeParameters = Signature.getParameterTypes(signature);
+					int length = typeParameters.length;
+					TypeBinding[] parameterTypes = new TypeBinding[length];
+					for (int j = 0; j < length; j++) {
+						parameterTypes[j] = getType(typeParameters[j]);
+					}
+					PolymorphicMethodBinding polymorphicMethod = this.environment.createPolymorphicMethod(method, parameterTypes);
+					this.methodBinding = polymorphicMethod;
+					this.methodBinding = this.environment.updatePolymorphicMethodReturnType(
+							polymorphicMethod,
+							getType(Signature.getReturnType(signature)));
+					this.compilerBinding = this.methodBinding;
+					return;
+				}
+			}
+		}
+	}
+
+	private TypeBinding getType(char[] type) {
+		TypeBinding binding = null;
+		int length = type.length;
+		switch(length) {
+			case 1 :
+				switch (type[0]) {
+					case 'I' :
+						binding = TypeBinding.INT;
+						break;
+					case 'Z' :
+						binding = TypeBinding.BOOLEAN;
+						break;
+					case 'V' :
+						binding = TypeBinding.VOID;
+						break;
+					case 'C' :
+						binding = TypeBinding.CHAR;
+						break;
+					case 'D' :
+						binding = TypeBinding.DOUBLE;
+						break;
+					case 'B' :
+						binding = TypeBinding.BYTE;
+						break;
+					case 'F' :
+						binding = TypeBinding.FLOAT;
+						break;
+					case 'J' :
+						binding = TypeBinding.LONG;
+						break;
+					case 'S' :
+						binding = TypeBinding.SHORT;
+						break;
+				}
+				break;
+			default:
+				int dimensions = 0;
+				int start = 0;
+				while (type[start] == '[') {
+					start++;
+					dimensions++;
+				}
+				binding = this.environment.getType(CharOperation.splitOn('/', type, start + 1, length - 1));
+				if (dimensions != 0) {
+					binding = this.environment.createArrayType(binding, dimensions);
+				}
+		}
+		return binding;
+	}
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.typeBinding = getTypeBinding(simpleTypeName);
+	}
+
+	public void consumePackage(char[] pkgName) {
+		this.compoundName = CharOperation.splitOn('/', pkgName);
+		this.compilerBinding = new PackageBinding(this.compoundName, null, this.environment);
+	}
+
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		if (this.typeBinding == null)
+			return;
+		TypeBinding[] arguments = getTypeBindingArguments();
+		if (arguments == null) {
+			this.typeBinding = null;
+			this.genericType = null;
+			return;
+		}
+		if (simpleTypeName != null) {
+			if (this.genericType == null) {
+				// parameterized member type with raw enclosing type
+				this.genericType = ((ReferenceBinding) this.typeBinding).getMemberType(simpleTypeName);
+			} else {
+				// parameterized member type with parameterized enclosing type
+				this.genericType = this.genericType.getMemberType(simpleTypeName);
+			}
+			if (!isRaw)
+				this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, (ReferenceBinding) this.typeBinding);
+			else
+				// raw type
+				this.typeBinding = this.environment.createRawType(this.genericType, (ReferenceBinding) this.typeBinding);
+		} else {
+			// parameterized top level type or parameterized member type with raw enclosing type
+			this.genericType = (ReferenceBinding) this.typeBinding;
+			ReferenceBinding enclosing = this.genericType.enclosingType();
+			if (enclosing != null) enclosing = (ReferenceBinding) this.environment.convertToRawType(enclosing, false /*do not force conversion of enclosing types*/);
+			this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, enclosing);
+		}
+	}
+
+
+	public void consumeParser(BindingKeyParser parser) {
+		this.types.add(parser);
+	}
+
+	public void consumeScope(int scopeNumber) {
+		if (this.scope == null) {
+			if (this.methodBinding == null)
+				return;
+			this.scope = this.methodBinding.sourceMethod().scope;
+		}
+		if (scopeNumber >= this.scope.subscopeCount)
+			return; // malformed key
+		this.scope = (BlockScope) this.scope.subscopes[scopeNumber];
+	}
+
+	public void consumeRawType() {
+		if (this.typeBinding == null) return;
+		this.typeBinding = this.environment.convertToRawType(this.typeBinding, false /*do not force conversion of enclosing types*/);
+	}
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		this.secondarySimpleName = simpleTypeName;
+	}
+
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		this.compoundName = CharOperation.splitOn('/', fullyQualifiedName);
+	}
+
+	public void consumeTopLevelType() {
+		char[] fileName;
+		this.parsedUnit = getCompilationUnitDeclaration();
+		if (this.parsedUnit != null && this.compiler != null && !this.resolvedUnits.containsKey(fileName = this.parsedUnit.getFileName())) {
+			this.compiler.process(this.parsedUnit, this.compiler.totalUnits+1); // unit is resolved only once thanks to the resolvedUnits protection
+			this.resolvedUnits.put(fileName, fileName);
+		}
+		if (this.parsedUnit == null) {
+			this.typeBinding = getBinaryBinding();
+		} else {
+			char[] typeName = this.secondarySimpleName == null ? this.compoundName[this.compoundName.length-1] : this.secondarySimpleName;
+			this.typeBinding = getTypeBinding(typeName);
+		}
+	}
+
+	public void consumeKey() {
+		if (this.typeBinding != null) {
+			this.typeBinding = getArrayBinding(this.dimension, this.typeBinding);
+			this.compilerBinding = this.typeBinding;
+		}
+	}
+
+	public void consumeTypeVariable(char[] position, char[] typeVariableName) {
+		if (position.length > 0) {
+			if (this.typeBinding == null)
+				return;
+			int pos = Integer.parseInt(new String(position));
+			MethodBinding[] methods = ((ReferenceBinding) this.typeBinding).availableMethods(); // resilience
+			if (methods != null && pos < methods.length) {
+				this.methodBinding = methods[pos];
+			}
+		}
+	 	TypeVariableBinding[] typeVariableBindings;
+	 	if (this.methodBinding != null) {
+	 		typeVariableBindings = this.methodBinding.typeVariables();
+	 	} else if (this.typeBinding != null) {
+	 		typeVariableBindings = this.typeBinding.typeVariables();
+	 	} else {
+	 		return;
+	 	}
+	 	for (int i = 0, length = typeVariableBindings.length; i < length; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariableBindings[i];
+			if (CharOperation.equals(typeVariableName, typeVariableBinding.sourceName())) {
+				this.typeBinding = typeVariableBinding;
+				return;
+			}
+		}
+	}
+
+	public void consumeTypeWithCapture() {
+		BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(0);
+		this.typeBinding =(TypeBinding) resolver.compilerBinding;
+	}
+
+	public void consumeWildcardRank(int aRank) {
+		this.wildcardRank = aRank;
+	}
+	
+	public void consumeWildCard(int kind) {
+		switch (kind) {
+			case Wildcard.EXTENDS:
+			case Wildcard.SUPER:
+				BindingKeyResolver boundResolver = (BindingKeyResolver) this.types.get(0);
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=157847, do not allow creation of
+				// internally inconsistent wildcards of the form '? super <null>' or '? extends <null>'
+				final Binding boundBinding = boundResolver.compilerBinding;
+				if (boundBinding instanceof TypeBinding) {
+					this.typeBinding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, this.wildcardRank, (TypeBinding) boundBinding, null /*no extra bound*/, kind);
+				} else {
+					this.typeBinding = null;
+				}
+				break;
+			case Wildcard.UNBOUND:
+				this.typeBinding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, this.wildcardRank, null/*no bound*/, null /*no extra bound*/, kind);
+				break;
+		}
+	}
+
+	public AnnotationBinding getAnnotationBinding() {
+		return this.annotationBinding;
+	}
+
+	/*
+	 * If the given dimension is greater than 0 returns an array binding for the given type binding.
+	 * Otherwise return the given type binding.
+	 * Returns null if the given type binding is null.
+	 */
+	private TypeBinding getArrayBinding(int dim, TypeBinding binding) {
+		if (binding == null) return null;
+		if (dim == 0) return binding;
+		return this.environment.createArrayType(binding, dim);
+	}
+
+	private TypeBinding getBaseTypeBinding(char[] signature) {
+		switch (signature[0]) {
+			case 'I' :
+				return TypeBinding.INT;
+			case 'Z' :
+				return TypeBinding.BOOLEAN;
+			case 'V' :
+				return TypeBinding.VOID;
+			case 'C' :
+				return TypeBinding.CHAR;
+			case 'D' :
+				return TypeBinding.DOUBLE;
+			case 'B' :
+				return TypeBinding.BYTE;
+			case 'F' :
+				return TypeBinding.FLOAT;
+			case 'J' :
+				return TypeBinding.LONG;
+			case 'S' :
+				return TypeBinding.SHORT;
+			case 'N':
+				return TypeBinding.NULL;
+			default :
+				return null;
+		}
+	}
+
+	/*
+	 * Returns a binary binding corresonding to this key's compound name.
+	 * Returns null if not found.
+	 */
+	private TypeBinding getBinaryBinding() {
+		if (this.compoundName.length == 0) return null;
+		return this.environment.getType(this.compoundName);
+	}
+
+	/*
+	 * Finds the compilation unit declaration corresponding to the key in the given lookup environment.
+	 * Returns null if no compilation unit declaration could be found.
+	 * This key's scanner should be positioned on the package token.
+	 */
+	public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+		char[][] name = this.compoundName;
+		if (name.length == 0) return null;
+		if (this.environment == null) return null;
+		ReferenceBinding binding = this.environment.getType(name);
+		if (!(binding instanceof SourceTypeBinding)) {
+			if (this.secondarySimpleName == null)
+				return null;
+			// case of a secondary type with no primary type (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=177115)
+			int length = name.length;
+			System.arraycopy(name, 0, name = new char[length][], 0, length-1);
+			name[length-1] = this.secondarySimpleName;
+			binding = this.environment.getType(name);
+			if (!(binding instanceof SourceTypeBinding))
+				return null;
+		}
+		SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding;
+		if (sourceTypeBinding.scope == null)
+			return null;
+		return sourceTypeBinding.scope.compilationUnitScope().referenceContext;
+	}
+
+	/*
+	 * Returns the compiler binding corresponding to this key.
+	 * Returns null is malformed.
+	 * This key's scanner should be positioned on the package token.
+	 */
+	public Binding getCompilerBinding() {
+		try {
+			parse();
+			return this.compilerBinding;
+		} catch (RuntimeException e) {
+			Util.log(e, "Could not create binding from binding key: " + getKey()); //$NON-NLS-1$
+			return null;
+		}
+	}
+
+	private TypeBinding getTypeBinding(char[] simpleTypeName) {
+		if (this.typeBinding instanceof ReferenceBinding) {
+			return ((ReferenceBinding) this.typeBinding).getMemberType(simpleTypeName);
+		}
+		TypeDeclaration[] typeDeclarations =
+			this.typeDeclaration == null ?
+				(this.parsedUnit == null ? null : this.parsedUnit.types) :
+				this.typeDeclaration.memberTypes;
+		if (typeDeclarations == null) return null;
+		for (int i = 0, length = typeDeclarations.length; i < length; i++) {
+			TypeDeclaration declaration = typeDeclarations[i];
+			if (CharOperation.equals(simpleTypeName, declaration.name)) {
+				this.typeDeclaration = declaration;
+				return declaration.binding;
+			}
+		}
+		return null;
+	}
+
+	private TypeBinding[] getTypeBindingArguments() {
+		int size = this.types.size();
+		TypeBinding[] arguments = new TypeBinding[size];
+		for (int i = 0; i < size; i++) {
+			BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(i);
+			TypeBinding compilerBinding2 = (TypeBinding) resolver.compilerBinding;
+			if (compilerBinding2 == null) {
+				this.types = new ArrayList();
+				return null;
+			}
+			arguments[i] = compilerBinding2;
+		}
+		this.types = new ArrayList();
+		return arguments;
+	}
+
+	public void malformedKey() {
+		this.compoundName = CharOperation.NO_CHAR_CHAR;
+	}
+
+	public BindingKeyParser newParser() {
+		return new BindingKeyResolver(this, this.compiler, this.environment, this.outerMostParsedUnit == null ? this.parsedUnit : this.outerMostParsedUnit, this.resolvedUnits);
+	}
+
+	public String toString() {
+		return getKey();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java
new file mode 100644
index 0000000..2a7b376
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsAttribute.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IBootstrapMethodsAttribute;
+import org.eclipse.jdt.core.util.IBootstrapMethodsEntry;
+import org.eclipse.jdt.core.util.IConstantPool;
+
+/**
+ * Default implementation of IBootstrapMethodsAttribute.
+ */
+public class BootstrapMethodsAttribute extends ClassFileAttribute implements IBootstrapMethodsAttribute {
+	private static final IBootstrapMethodsEntry[] NO_ENTRIES = new IBootstrapMethodsEntry[0];
+
+	private IBootstrapMethodsEntry[] entries;
+	private int numberOfBootstrapMethods;
+
+	/**
+	 * Constructor for BootstrapMethodsAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public BootstrapMethodsAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.numberOfBootstrapMethods = u2At(classFileBytes, 6, offset);
+		final int length = this.numberOfBootstrapMethods;
+		if (length != 0) {
+			int readOffset = 8;
+			this.entries = new IBootstrapMethodsEntry[length];
+			BootstrapMethodsEntry entry;
+			for (int i = 0; i < length; i++) {
+				this.entries[i] = entry = new BootstrapMethodsEntry(classFileBytes, constantPool, offset + readOffset);
+				readOffset += 4 + 2 * entry.getBootstrapArguments().length; 
+			}
+		} else {
+			this.entries = NO_ENTRIES;
+		}
+	}
+
+	/**
+	 * @see IBootstrapMethodsAttribute#getBootstrapMethods()
+	 */
+	public IBootstrapMethodsEntry[] getBootstrapMethods() {
+		return this.entries;
+	}
+	
+	public int getBootstrapMethodsLength() {
+		return this.numberOfBootstrapMethods;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java
new file mode 100644
index 0000000..e444dbd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BootstrapMethodsEntry.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IBootstrapMethodsEntry;
+import org.eclipse.jdt.core.util.IConstantPool;
+
+/**
+ * Default implementation of {@link IBootstrapMethodsEntry}
+ */
+public class BootstrapMethodsEntry
+	extends ClassFileStruct
+	implements IBootstrapMethodsEntry {
+
+	private int bootstrapMethodReference;
+	private int[] bootstrapArguments;
+
+	public BootstrapMethodsEntry(byte classFileBytes[], IConstantPool constantPool, int offset) throws ClassFormatException {
+		this.bootstrapMethodReference = u2At(classFileBytes, 0, offset);
+		int length = u2At(classFileBytes, 2, offset);
+		int[] arguments = new int[length];
+		int position = 4;
+		for (int i = 0; i < length; i++) {
+			arguments[i] = u2At(classFileBytes, position, offset);
+			position += 2;
+		}
+		this.bootstrapArguments = arguments;
+	}
+
+	/**
+	 * @see IBootstrapMethodsEntry#getBootstrapArguments()
+	 */
+	public int[] getBootstrapArguments() {
+		return this.bootstrapArguments;
+	}
+
+	/**
+	 * @see IBootstrapMethodsEntry#getBootstrapMethodReference()
+	 */
+	public int getBootstrapMethodReference() {
+		return this.bootstrapMethodReference;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java
new file mode 100644
index 0000000..5fdd855
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+/**
+ * The <code>CharArrayBuffer</code> is intended as a lightweight partial implementation
+ * of the StringBuffer class, but using <code>char[]'s</code> instead of Strings.
+ *
+ * <p>The <code>CharArrayBuffer</code> maintains a list of <code>char[]'s</code>
+ * which don't get appended until the user asks for them.  The following
+ * code illustrates how to use the class.
+ *
+ * <code>
+ * CharArrayBuffer buffer = new CharArrayBuffer(myCharArray);
+ * buffer.append(moreBytes, 0, someLength);
+ * myCharArray = buffer.getContents();
+ * </code>
+ *
+ * <p>NOTE: This class is not Thread safe!
+ */
+public class CharArrayBuffer {
+	/**
+	 * This is the buffer of char arrays which must be appended together
+	 * during the getContents method.
+	 */
+	protected char[][] buffer;
+
+	/**
+	 * The default buffer size.
+	 */
+	public static final int DEFAULT_BUFFER_SIZE = 10;
+
+	/**
+	 * The end of the buffer
+	 */
+	protected int end;
+
+	/**
+	 * The current size of the buffer.
+	 */
+	protected int size;
+
+	/**
+	 * A buffer of ranges which is maintained along with
+	 * the buffer.  Ranges are of the form {start, length}.
+	 * Enables append(char[] array, int start, int end).
+	 */
+	protected int[][] ranges;
+/**
+ * Creates a <code>CharArrayBuffer</code> with the default buffer size (10).
+ */
+public CharArrayBuffer() {
+	this(null, DEFAULT_BUFFER_SIZE);
+}
+/**
+ * Creates a <code>CharArrayBuffer</code> with the default buffer size,
+ * and sets the first element in the buffer to be the given char[].
+ *
+ * @param first - the first element to be placed in the buffer, ignored if null
+ */
+public CharArrayBuffer(char[] first) {
+	this(first, DEFAULT_BUFFER_SIZE);
+}
+/**
+ * Creates a <code>CharArrayBuffer</code> with the given buffer size,
+ * and sets the first element in the buffer to be the given char array.
+ *
+ * @param first - the first element of the buffer, ignored if null.
+ * @param size - the buffer size, if less than 1, set to the DEFAULT_BUFFER_SIZE.
+ */
+public CharArrayBuffer(char[] first, int size) {
+	this.size = (size > 0) ? size : DEFAULT_BUFFER_SIZE;
+	this.buffer = new char[this.size][];
+	this.ranges = new int[this.size][];
+	this.end = 0;
+	if (first != null)
+		append(first, 0, first.length);
+}
+/**
+ * Creates a <code>CharArrayBuffer</code> with the given buffer size.
+ *
+ * @param size - the size of the buffer.
+ */
+public CharArrayBuffer(int size) {
+	this(null, size);
+}
+/**
+ * Appends the entire given char array.  Given for convenience.
+ *
+ * @param src - a char array which is appended to the end of the buffer.
+ */
+public CharArrayBuffer append(char[] src) {
+	if (src != null)
+		append(src, 0, src.length);
+	return this;
+}
+/**
+ * Appends a sub array of the given array to the buffer.
+ *
+ * @param src - the next array of characters to be appended to the buffer, ignored if null
+ * @param start - the start index in the src array.
+ * @param length - the number of characters from start to be appended
+ *
+ * @throws ArrayIndexOutOfBoundsException - if arguments specify an array index out of bounds.
+ */
+public CharArrayBuffer append(char[] src, int start, int length) {
+	if (start < 0) throw new ArrayIndexOutOfBoundsException();
+	if (length < 0) throw new ArrayIndexOutOfBoundsException();
+	if (src != null) {
+		int srcLength = src.length;
+		if (start > srcLength) throw new ArrayIndexOutOfBoundsException();
+		if (length + start > srcLength) throw new ArrayIndexOutOfBoundsException();
+		/** do length check here to allow exceptions to be thrown */
+		if (length > 0) {
+			if (this.end == this.size) {
+				int size2 = this.size * 2;
+				System.arraycopy(this.buffer, 0, (this.buffer = new char[size2][]), 0, this.size);
+				System.arraycopy(this.ranges, 0, (this.ranges = new int[size2][]), 0, this.size);
+				this.size *= 2;
+			}
+			this.buffer[this.end] = src;
+			this.ranges[this.end] = new int[] {start, length};
+			this.end++;
+		}
+	}
+	return this;
+}
+/**
+ * Appends the given char.  Given for convenience.
+ *
+ * @param c - a char which is appended to the end of the buffer.
+ */
+public CharArrayBuffer append(char c) {
+	append(new char[] {c}, 0, 1);
+	return this;
+}
+/**
+ * Appends the given String to the buffer.  Given for convenience, use
+ * #append(char[]) if possible
+ *
+ * @param src - a char array which is appended to the end of the buffer.
+ */
+public CharArrayBuffer append(String src) {
+	if (src != null)
+		append(src.toCharArray(), 0, src.length());
+	return this;
+}
+/**
+ * Returns the entire contents of the buffer as one
+ * char[] or null if nothing has been put in the buffer.
+ */
+public char[] getContents() {
+	if (this.end == 0)
+		return null;
+
+	// determine the length of the array
+	int length = 0;
+	for (int i = 0; i < this.end; i++)
+		length += this.ranges[i][1];
+
+	if (length > 0) {
+		char[] result = new char[length];
+		int current = 0;
+		// copy the results
+		for(int i = 0; i < this.end; i++) {
+			int[] range = this.ranges[i];
+			int length2 = range[1];
+			System.arraycopy(this.buffer[i], range[0], result, current, length2);
+			current += length2;
+		}
+		return result;
+	}
+	return null;
+}
+/**
+ * Returns the contents of the buffer as a String, or
+ * an empty string if the buffer is empty.
+ */
+public String toString() {
+	char[] contents = getContents();
+	return (contents != null) ? new String(contents) : Util.EMPTY_STRING;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java
new file mode 100644
index 0000000..1cb1910
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IClassFileAttribute
+ */
+public class ClassFileAttribute extends ClassFileStruct implements IClassFileAttribute {
+	public static final IClassFileAttribute[] NO_ATTRIBUTES = new IClassFileAttribute[0];
+	private long attributeLength;
+	private int attributeNameIndex;
+	private char[] attributeName;
+
+	public ClassFileAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		this.attributeNameIndex = u2At(classFileBytes, 0, offset);
+		this.attributeLength = u4At(classFileBytes, 2, offset);
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.attributeNameIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.attributeName = constantPoolEntry.getUtf8Value();
+	}
+
+	public int getAttributeNameIndex() {
+		return this.attributeNameIndex;
+	}
+
+	/**
+	 * @see IClassFileAttribute#getAttributeName()
+	 */
+	public char[] getAttributeName() {
+		return this.attributeName;
+	}
+
+	/**
+	 * @see IClassFileAttribute#getAttributeLength()
+	 */
+	public long getAttributeLength() {
+		return this.attributeLength;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java
new file mode 100644
index 0000000..9460f88
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java
@@ -0,0 +1,458 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * Default implementation of IClassFileReader.
+ */
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAttributeNamesConstants;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IFieldInfo;
+import org.eclipse.jdt.core.util.IInnerClassesAttribute;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.core.util.IModifierConstants;
+import org.eclipse.jdt.core.util.ISourceAttribute;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClassFileReader extends ClassFileStruct implements IClassFileReader {
+	private static final IFieldInfo[] NO_FIELD_INFOS = new IFieldInfo[0];
+	private static final char[][] NO_INTERFACES_NAMES = CharOperation.NO_CHAR_CHAR;
+	private static final IMethodInfo[] NO_METHOD_INFOS = new IMethodInfo[0];
+	private int accessFlags;
+	private IClassFileAttribute[] attributes;
+	private int attributesCount;
+	private char[] className;
+	private int classNameIndex;
+
+	private IConstantPool constantPool;
+	private IFieldInfo[] fields;
+	private int fieldsCount;
+	private IInnerClassesAttribute innerClassesAttribute;
+	private int[] interfaceIndexes;
+	private char[][] interfaceNames;
+	private int interfacesCount;
+	private int magicNumber;
+	private int majorVersion;
+	private IMethodInfo[] methods;
+	private int methodsCount;
+	private int minorVersion;
+	private ISourceAttribute sourceFileAttribute;
+	private char[] superclassName;
+	private int superclassNameIndex;
+
+	/**
+	 * Constructor for ClassFileReader.
+	 *
+	 * @param classFileBytes the raw bytes of the .class file
+	 * @param decodingFlags the decoding flags
+	 *
+	 * @see IClassFileReader#ALL
+	 * @see IClassFileReader#CLASSFILE_ATTRIBUTES
+	 * @see IClassFileReader#CONSTANT_POOL
+	 * @see IClassFileReader#FIELD_INFOS
+	 */
+	public ClassFileReader(byte[] classFileBytes, int decodingFlags) throws ClassFormatException {
+
+		// This method looks ugly but is actually quite simple, the constantPool is constructed
+		// in 3 passes.  All non-primitive constant pool members that usually refer to other members
+		// by index are tweaked to have their value in inst vars, this minor cost at read-time makes
+		// all subsequent uses of the constant pool element faster.
+		int constantPoolCount;
+		int[] constantPoolOffsets;
+		try {
+			this.magicNumber = (int) u4At(classFileBytes, 0, 0);
+			if (this.magicNumber != 0xCAFEBABE) {
+				throw new ClassFormatException(ClassFormatException.INVALID_MAGIC_NUMBER);
+			}
+
+			int readOffset = 10;
+			this.minorVersion = u2At(classFileBytes, 4, 0);
+			this.majorVersion = u2At(classFileBytes, 6, 0);
+
+			if ((decodingFlags & IClassFileReader.CONSTANT_POOL) == 0) {
+				// no need to go further
+				return;
+			}
+
+			constantPoolCount = u2At(classFileBytes, 8, 0);
+			// Pass #1 - Fill in all primitive constants
+			constantPoolOffsets = new int[constantPoolCount];
+			for (int i = 1; i < constantPoolCount; i++) {
+				int tag = u1At(classFileBytes, readOffset, 0);
+				switch (tag) {
+					case IConstantPoolConstant.CONSTANT_Utf8 :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += u2At(classFileBytes, readOffset + 1, 0);
+						readOffset += IConstantPoolConstant.CONSTANT_Utf8_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_Integer :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Integer_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_Float :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Float_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_Long :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Long_SIZE;
+						i++;
+						break;
+					case IConstantPoolConstant.CONSTANT_Double :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Double_SIZE;
+						i++;
+						break;
+					case IConstantPoolConstant.CONSTANT_Class :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Class_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_String :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_String_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_Fieldref :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Fieldref_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_Methodref :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_Methodref_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_InterfaceMethodref_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_NameAndType :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_NameAndType_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_MethodHandle :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_MethodHandle_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_MethodType :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_MethodType_SIZE;
+						break;
+					case IConstantPoolConstant.CONSTANT_InvokeDynamic :
+						constantPoolOffsets[i] = readOffset;
+						readOffset += IConstantPoolConstant.CONSTANT_InvokeDynamic_SIZE;
+						break;
+					default:
+						throw new ClassFormatException(ClassFormatException.INVALID_TAG_CONSTANT);
+				}
+			}
+
+			this.constantPool = new ConstantPool(classFileBytes, constantPoolOffsets);
+			// Read and validate access flags
+			this.accessFlags = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+
+			// Read the classname, use exception handlers to catch bad format
+			this.classNameIndex = u2At(classFileBytes, readOffset, 0);
+			this.className = getConstantClassNameAt(classFileBytes, constantPoolOffsets, this.classNameIndex);
+			readOffset += 2;
+
+			// Read the superclass name, can be zero for java.lang.Object
+			this.superclassNameIndex = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+			// if superclassNameIndex is equals to 0 there is no need to set a value for the
+			// field this.superclassName. null is fine.
+			if (this.superclassNameIndex != 0) {
+				this.superclassName = getConstantClassNameAt(classFileBytes, constantPoolOffsets, this.superclassNameIndex);
+			}
+
+			// Read the interfaces, use exception handlers to catch bad format
+			this.interfacesCount = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+			this.interfaceNames = NO_INTERFACES_NAMES;
+			this.interfaceIndexes = Util.EMPTY_INT_ARRAY;
+			if (this.interfacesCount != 0) {
+				if ((decodingFlags & IClassFileReader.SUPER_INTERFACES) != IClassFileReader.CONSTANT_POOL) {
+					this.interfaceNames = new char[this.interfacesCount][];
+					this.interfaceIndexes = new int[this.interfacesCount];
+					for (int i = 0; i < this.interfacesCount; i++) {
+						this.interfaceIndexes[i] = u2At(classFileBytes, readOffset, 0);
+						this.interfaceNames[i] = getConstantClassNameAt(classFileBytes, constantPoolOffsets, this.interfaceIndexes[i]);
+						readOffset += 2;
+					}
+				} else {
+					readOffset += (2 * this.interfacesCount);
+				}
+			}
+			// Read the this.fields, use exception handlers to catch bad format
+			this.fieldsCount = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+			this.fields = NO_FIELD_INFOS;
+			if (this.fieldsCount != 0) {
+				if ((decodingFlags & IClassFileReader.FIELD_INFOS) != IClassFileReader.CONSTANT_POOL) {
+					FieldInfo field;
+					this.fields = new FieldInfo[this.fieldsCount];
+					for (int i = 0; i < this.fieldsCount; i++) {
+						field = new FieldInfo(classFileBytes, this.constantPool, readOffset);
+						this.fields[i] = field;
+						readOffset += field.sizeInBytes();
+					}
+				} else {
+					for (int i = 0; i < this.fieldsCount; i++) {
+						int attributeCountForField = u2At(classFileBytes, 6, readOffset);
+						readOffset += 8;
+						if (attributeCountForField != 0) {
+							for (int j = 0; j < attributeCountForField; j++) {
+								int attributeLength = (int) u4At(classFileBytes, 2, readOffset);
+								readOffset += (6 + attributeLength);
+							}
+						}
+					}
+				}
+			}
+			// Read the this.methods
+			this.methodsCount = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+			this.methods = NO_METHOD_INFOS;
+			if (this.methodsCount != 0) {
+				if ((decodingFlags & IClassFileReader.METHOD_INFOS) != IClassFileReader.CONSTANT_POOL) {
+					this.methods = new MethodInfo[this.methodsCount];
+					MethodInfo method;
+					for (int i = 0; i < this.methodsCount; i++) {
+						method = new MethodInfo(classFileBytes, this.constantPool, readOffset, decodingFlags);
+						this.methods[i] = method;
+						readOffset += method.sizeInBytes();
+					}
+				} else {
+					for (int i = 0; i < this.methodsCount; i++) {
+						int attributeCountForMethod = u2At(classFileBytes, 6, readOffset);
+						readOffset += 8;
+						if (attributeCountForMethod != 0) {
+							for (int j = 0; j < attributeCountForMethod; j++) {
+								int attributeLength = (int) u4At(classFileBytes, 2, readOffset);
+								readOffset += (6 + attributeLength);
+							}
+						}
+					}
+				}
+			}
+
+			// Read the attributes
+			this.attributesCount = u2At(classFileBytes, readOffset, 0);
+			readOffset += 2;
+
+			int attributesIndex = 0;
+			this.attributes = ClassFileAttribute.NO_ATTRIBUTES;
+			if (this.attributesCount != 0) {
+				if ((decodingFlags & IClassFileReader.CLASSFILE_ATTRIBUTES) != IClassFileReader.CONSTANT_POOL) {
+					this.attributes = new IClassFileAttribute[this.attributesCount];
+					for (int i = 0; i < this.attributesCount; i++) {
+						int utf8Offset = constantPoolOffsets[u2At(classFileBytes, readOffset, 0)];
+						char[] attributeName = utf8At(classFileBytes, utf8Offset + 3, 0, u2At(classFileBytes, utf8Offset + 1, 0));
+						if (equals(attributeName, IAttributeNamesConstants.INNER_CLASSES)) {
+							this.innerClassesAttribute = new InnerClassesAttribute(classFileBytes, this.constantPool, readOffset);
+							this.attributes[attributesIndex++] = this.innerClassesAttribute;
+						} else if (equals(attributeName, IAttributeNamesConstants.SOURCE)) {
+							this.sourceFileAttribute = new SourceFileAttribute(classFileBytes, this.constantPool, readOffset);
+							this.attributes[attributesIndex++] = this.sourceFileAttribute;
+						} else if (equals(attributeName, IAttributeNamesConstants.ENCLOSING_METHOD)) {
+							this.attributes[attributesIndex++] = new EnclosingMethodAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) {
+							this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) {
+							this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) {
+							this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.BOOTSTRAP_METHODS)) {
+							this.attributes[attributesIndex++] = new BootstrapMethodsAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+							this.attributes[attributesIndex++] = new RuntimeVisibleTypeAnnotationsAttribute(classFileBytes, this.constantPool, readOffset);
+						} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+							this.attributes[attributesIndex++] = new RuntimeInvisibleTypeAnnotationsAttribute(classFileBytes, this.constantPool, readOffset);
+						} else {
+							this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset);
+						}
+						readOffset += (6 + u4At(classFileBytes, readOffset + 2, 0));
+					}
+				} else {
+					for (int i = 0; i < this.attributesCount; i++) {
+						readOffset += (6 + u4At(classFileBytes, readOffset + 2, 0));
+					}
+				}
+			}
+			if (readOffset != classFileBytes.length) {
+				throw new ClassFormatException(ClassFormatException.TOO_MANY_BYTES);
+			}
+		} catch(ClassFormatException e) {
+			throw e;
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new ClassFormatException(ClassFormatException.ERROR_TRUNCATED_INPUT);
+		}
+	}
+
+	/**
+	 * @see IClassFileReader#getAccessFlags()
+	 */
+	public int getAccessFlags() {
+		return this.accessFlags;
+	}
+	/**
+	 * @see IClassFileReader#getAttributeCount()
+	 */
+	public int getAttributeCount() {
+		return this.attributesCount;
+	}
+
+	/**
+	 * @see IClassFileReader#getAttributes()
+	 */
+	public IClassFileAttribute[] getAttributes() {
+		return this.attributes;
+	}
+
+	/**
+	 * @see IClassFileReader#getClassIndex()
+	 */
+	public int getClassIndex() {
+		return this.classNameIndex;
+	}
+
+	/**
+	 * @see IClassFileReader#getClassName()
+	 */
+	public char[] getClassName() {
+		return this.className;
+	}
+
+	private char[] getConstantClassNameAt(byte[] classFileBytes, int[] constantPoolOffsets, int constantPoolIndex) {
+		int utf8Offset = constantPoolOffsets[u2At(classFileBytes, constantPoolOffsets[constantPoolIndex] + 1, 0)];
+		return utf8At(classFileBytes, utf8Offset + 3, 0, u2At(classFileBytes, utf8Offset + 1, 0));
+	}
+
+	/**
+	 * @see IClassFileReader#getConstantPool()
+	 */
+	public IConstantPool getConstantPool() {
+		return this.constantPool;
+	}
+	/**
+	 * @see IClassFileReader#getFieldInfos()
+	 */
+	public IFieldInfo[] getFieldInfos() {
+		return this.fields;
+	}
+
+	/**
+	 * @see IClassFileReader#getFieldsCount()
+	 */
+	public int getFieldsCount() {
+		return this.fieldsCount;
+	}
+
+	/**
+	 * @see IClassFileReader#getInnerClassesAttribute()
+	 */
+	public IInnerClassesAttribute getInnerClassesAttribute() {
+		return this.innerClassesAttribute;
+	}
+
+	/**
+	 * @see IClassFileReader#getInterfaceIndexes()
+	 */
+	public int[] getInterfaceIndexes() {
+		return this.interfaceIndexes;
+	}
+
+	/**
+	 * @see IClassFileReader#getInterfaceNames()
+	 */
+	public char[][] getInterfaceNames() {
+		return this.interfaceNames;
+	}
+
+	/**
+	 * @see IClassFileReader#getMagic()
+	 */
+	public int getMagic() {
+		return this.magicNumber;
+	}
+
+	/**
+	 * @see IClassFileReader#getMajorVersion()
+	 */
+	public int getMajorVersion() {
+		return this.majorVersion;
+	}
+
+	/**
+	 * @see IClassFileReader#getMethodInfos()
+	 */
+	public IMethodInfo[] getMethodInfos() {
+		return this.methods;
+	}
+
+	/**
+	 * @see IClassFileReader#getMethodsCount()
+	 */
+	public int getMethodsCount() {
+		return this.methodsCount;
+	}
+
+	/**
+	 * @see IClassFileReader#getMinorVersion()
+	 */
+	public int getMinorVersion() {
+		return this.minorVersion;
+	}
+
+	/**
+	 * @see IClassFileReader#getSourceFileAttribute()
+	 */
+	public ISourceAttribute getSourceFileAttribute() {
+		return this.sourceFileAttribute;
+	}
+
+	/**
+	 * @see IClassFileReader#getSuperclassIndex()
+	 */
+	public int getSuperclassIndex() {
+		return this.superclassNameIndex;
+	}
+
+	/**
+	 * @see IClassFileReader#getSuperclassName()
+	 */
+	public char[] getSuperclassName() {
+		return this.superclassName;
+	}
+	/**
+	 * @see IClassFileReader#isClass()
+	 */
+	public boolean isClass() {
+		return !isInterface();
+	}
+
+	/**
+	 * @see IClassFileReader#isInterface()
+	 */
+	public boolean isInterface() {
+		return (getAccessFlags() & IModifierConstants.ACC_INTERFACE) != 0;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java
new file mode 100644
index 0000000..1485286
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * Abstract class that defines helpers methods for decoding .class file.
+ */
+public abstract class ClassFileStruct {
+
+	protected double doubleAt(byte[] reference, int relativeOffset, int structOffset) {
+		return (Double.longBitsToDouble(i8At(reference, relativeOffset, structOffset)));
+	}
+
+	protected float floatAt(byte[] reference, int relativeOffset, int structOffset) {
+		return (Float.intBitsToFloat(i4At(reference, relativeOffset, structOffset)));
+	}
+	protected int i1At(byte[] reference, int relativeOffset, int structOffset) {
+		return reference[relativeOffset + structOffset];
+	}
+	protected int i2At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return (reference[position++] << 8) + (reference[position] & 0xFF);
+	}
+	protected int i4At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return ((reference[position++] & 0xFF) << 24)
+			+ ((reference[position++] & 0xFF) << 16)
+			+ ((reference[position++] & 0xFF) << 8)
+			+ (reference[position] & 0xFF);
+	}
+	protected long i8At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return (((long) (reference[position++] & 0xFF)) << 56)
+						+ (((long) (reference[position++] & 0xFF)) << 48)
+						+ (((long) (reference[position++] & 0xFF)) << 40)
+						+ (((long) (reference[position++] & 0xFF)) << 32)
+						+ (((long) (reference[position++] & 0xFF)) << 24)
+						+ (((long) (reference[position++] & 0xFF)) << 16)
+						+ (((long) (reference[position++] & 0xFF)) << 8)
+						+ (reference[position++] & 0xFF);
+	}
+
+	protected int u1At(byte[] reference, int relativeOffset, int structOffset) {
+		return (reference[relativeOffset + structOffset] & 0xFF);
+	}
+	protected int u2At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
+	}
+	protected long u4At(byte[] reference, int relativeOffset, int structOffset) {
+		int position = relativeOffset + structOffset;
+		return (
+			((reference[position++] & 0xFFL) << 24)
+				+ ((reference[position++] & 0xFF) << 16)
+				+ ((reference[position++] & 0xFF) << 8)
+				+ (reference[position] & 0xFF));
+	}
+	protected char[] utf8At(byte[] reference, int relativeOffset, int structOffset, int bytesAvailable) {
+		int length = bytesAvailable;
+		char outputBuf[] = new char[bytesAvailable];
+		int outputPos = 0;
+		int readOffset = structOffset + relativeOffset;
+
+		while (length != 0) {
+			int x = reference[readOffset++] & 0xFF;
+			length--;
+			if ((0x80 & x) != 0) {
+				if ((x & 0x20) != 0) {
+					length-=2;
+					x = ((x & 0xF) << 12) + ((reference[readOffset++] & 0x3F) << 6) + (reference[readOffset++] & 0x3F);
+				} else {
+					length--;
+					x = ((x & 0x1F) << 6) + (reference[readOffset++] & 0x3F);
+				}
+			}
+			outputBuf[outputPos++] = (char) x;
+		}
+
+		if (outputPos != bytesAvailable) {
+			System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
+		}
+		return outputBuf;
+	}
+
+	final boolean equals(char[] first, char[] second) {
+		if (first == second)
+			return true;
+		if (first == null || second == null)
+			return false;
+		if (first.length != second.length)
+			return false;
+
+		for (int i = first.length; --i >= 0;)
+			if (first[i] != second[i])
+				return false;
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
new file mode 100644
index 0000000..4339375
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
@@ -0,0 +1,1191 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAttributeNamesConstants;
+import org.eclipse.jdt.core.util.IBytecodeVisitor;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IExceptionTableEntry;
+import org.eclipse.jdt.core.util.ILineNumberAttribute;
+import org.eclipse.jdt.core.util.ILocalVariableAttribute;
+import org.eclipse.jdt.core.util.IOpcodeMnemonics;
+
+/**
+ * Default implementation of ICodeAttribute.
+ */
+public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute {
+	private static final IExceptionTableEntry[] NO_EXCEPTION_TABLE = new IExceptionTableEntry[0];
+	private IClassFileAttribute[] attributes;
+	private int attributesCount;
+	private byte[] bytecodes;
+	private byte[] classFileBytes;
+	private long codeLength;
+	private int codeOffset;
+	private IConstantPool constantPool;
+	private IExceptionTableEntry[] exceptionTableEntries;
+	private int exceptionTableLength;
+	private ILineNumberAttribute lineNumberAttribute;
+	private ILocalVariableAttribute localVariableAttribute;
+	private int maxLocals;
+	private int maxStack;
+
+	CodeAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.classFileBytes = classFileBytes;
+		this.constantPool = constantPool;
+		this.maxStack = u2At(classFileBytes, 6, offset);
+		this.maxLocals = u2At(classFileBytes, 8, offset);
+		this.codeLength = u4At(classFileBytes, 10, offset);
+		this.codeOffset = offset + 14;
+		int readOffset = (int) (14 + this.codeLength);
+		this.exceptionTableLength = u2At(classFileBytes, readOffset, offset);
+		readOffset += 2;
+		this.exceptionTableEntries = NO_EXCEPTION_TABLE;
+		if (this.exceptionTableLength != 0) {
+			this.exceptionTableEntries = new ExceptionTableEntry[this.exceptionTableLength];
+			for (int i = 0; i < this.exceptionTableLength; i++) {
+				this.exceptionTableEntries [i] = new ExceptionTableEntry(classFileBytes, constantPool, offset + readOffset);
+				readOffset += 8;
+			}
+		}
+		this.attributesCount = u2At(classFileBytes, readOffset, offset);
+		this.attributes = ClassFileAttribute.NO_ATTRIBUTES;
+		if (this.attributesCount != 0) {
+			this.attributes = new IClassFileAttribute[this.attributesCount];
+		}
+		int attributesIndex = 0;
+		readOffset += 2;
+		for (int i = 0; i < this.attributesCount; i++) {
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(u2At(classFileBytes, readOffset, offset));
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			char[] attributeName = constantPoolEntry.getUtf8Value();
+			if (equals(attributeName, IAttributeNamesConstants.LINE_NUMBER)) {
+				this.lineNumberAttribute = new LineNumberAttribute(classFileBytes, constantPool, offset + readOffset);
+				this.attributes[attributesIndex++] = this.lineNumberAttribute;
+			} else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE)) {
+				this.localVariableAttribute = new LocalVariableAttribute(classFileBytes, constantPool, offset + readOffset);
+				this.attributes[attributesIndex++] = this.localVariableAttribute;
+			} else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE_TYPE_TABLE)) {
+				this.attributes[attributesIndex++] = new LocalVariableTypeAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.STACK_MAP_TABLE)) {
+				this.attributes[attributesIndex++] = new StackMapTableAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.STACK_MAP)) {
+				this.attributes[attributesIndex++] = new StackMapAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else {
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			}
+			readOffset += (6 + u4At(classFileBytes, readOffset + 2, offset));
+		}
+	}
+	/**
+	 * @see ICodeAttribute#getAttributes()
+	 */
+	public IClassFileAttribute[] getAttributes() {
+		return this.attributes;
+	}
+
+	/**
+	 * @see ICodeAttribute#getAttributesCount()
+	 */
+	public int getAttributesCount() {
+		return this.attributesCount;
+	}
+
+	/**
+	 * @see ICodeAttribute#getBytecodes()
+	 */
+	public byte[] getBytecodes() {
+		if (this.bytecodes == null) {
+			System.arraycopy(this.classFileBytes, this.codeOffset, (this.bytecodes = new byte[(int) this.codeLength]), 0, (int) this.codeLength);
+		}
+		return this.bytecodes;
+	}
+
+	/**
+	 * @see ICodeAttribute#getCodeLength()
+	 */
+	public long getCodeLength() {
+		return this.codeLength;
+	}
+
+	/**
+	 * @see ICodeAttribute#getExceptionTable()
+	 */
+	public IExceptionTableEntry[] getExceptionTable() {
+		return this.exceptionTableEntries;
+	}
+
+	/**
+	 * @see ICodeAttribute#getExceptionTableLength()
+	 */
+	public int getExceptionTableLength() {
+		return this.exceptionTableLength;
+	}
+
+	/**
+	 * @see ICodeAttribute#getLineNumberAttribute()
+	 */
+	public ILineNumberAttribute getLineNumberAttribute() {
+		return this.lineNumberAttribute;
+	}
+
+	/**
+	 * @see ICodeAttribute#getLocalVariableAttribute()
+	 */
+	public ILocalVariableAttribute getLocalVariableAttribute() {
+		return this.localVariableAttribute;
+	}
+
+	/**
+	 * @see ICodeAttribute#getMaxLocals()
+	 */
+	public int getMaxLocals() {
+		return this.maxLocals;
+	}
+
+	/**
+	 * @see ICodeAttribute#getMaxStack()
+	 */
+	public int getMaxStack() {
+		return this.maxStack;
+	}
+
+	/**
+	 * @see ICodeAttribute#traverse(IBytecodeVisitor visitor)
+	 */
+	public void traverse(IBytecodeVisitor visitor) throws ClassFormatException {
+		int pc = this.codeOffset;
+		int opcode, index, _const, branchOffset;
+		IConstantPoolEntry constantPoolEntry;
+		while (true) {
+			opcode = u1At(this.classFileBytes, 0, pc);
+			switch(opcode) {
+				case IOpcodeMnemonics.NOP :
+					visitor._nop(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ACONST_NULL :
+					visitor._aconst_null(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_M1 :
+					visitor._iconst_m1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_0 :
+					visitor._iconst_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_1 :
+					visitor._iconst_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_2 :
+					visitor._iconst_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_3 :
+					visitor._iconst_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_4 :
+					visitor._iconst_4(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ICONST_5 :
+					visitor._iconst_5(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LCONST_0 :
+					visitor._lconst_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LCONST_1 :
+					visitor._lconst_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FCONST_0 :
+					visitor._fconst_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FCONST_1 :
+					visitor._fconst_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FCONST_2 :
+					visitor._fconst_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DCONST_0 :
+					visitor._dconst_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DCONST_1 :
+					visitor._dconst_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.BIPUSH :
+					visitor._bipush(pc - this.codeOffset, (byte) i1At(this.classFileBytes, 1, pc));
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.SIPUSH :
+					visitor._sipush(pc - this.codeOffset, (short) i2At(this.classFileBytes, 1, pc));
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.LDC :
+					index = u1At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Float
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Integer
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+							throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._ldc(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.LDC_W :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Float
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Integer
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+							throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._ldc_w(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.LDC2_W :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Double
+						&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Long) {
+							throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._ldc2_w(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.ILOAD :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._iload(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.LLOAD :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._lload(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.FLOAD :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._fload(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.DLOAD :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._dload(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.ALOAD :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._aload(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.ILOAD_0 :
+					visitor._iload_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ILOAD_1 :
+					visitor._iload_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ILOAD_2 :
+					visitor._iload_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ILOAD_3 :
+					visitor._iload_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LLOAD_0 :
+					visitor._lload_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LLOAD_1 :
+					visitor._lload_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LLOAD_2 :
+					visitor._lload_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LLOAD_3 :
+					visitor._lload_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FLOAD_0 :
+					visitor._fload_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FLOAD_1 :
+					visitor._fload_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FLOAD_2 :
+					visitor._fload_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FLOAD_3 :
+					visitor._fload_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DLOAD_0 :
+					visitor._dload_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DLOAD_1 :
+					visitor._dload_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DLOAD_2 :
+					visitor._dload_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DLOAD_3 :
+					visitor._dload_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ALOAD_0 :
+					visitor._aload_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ALOAD_1 :
+					visitor._aload_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ALOAD_2 :
+					visitor._aload_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ALOAD_3 :
+					visitor._aload_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IALOAD :
+					visitor._iaload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LALOAD :
+					visitor._laload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FALOAD :
+					visitor._faload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DALOAD :
+					visitor._daload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.AALOAD :
+					visitor._aaload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.BALOAD :
+					visitor._baload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.CALOAD :
+					visitor._caload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.SALOAD :
+					visitor._saload(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISTORE :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._istore(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.LSTORE :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._lstore(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.FSTORE :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._fstore(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.DSTORE :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._dstore(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.ASTORE :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._astore(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.ISTORE_0 :
+					visitor._istore_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISTORE_1 :
+					visitor._istore_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISTORE_2 :
+					visitor._istore_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISTORE_3 :
+					visitor._istore_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSTORE_0 :
+					visitor._lstore_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSTORE_1 :
+					visitor._lstore_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSTORE_2 :
+					visitor._lstore_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSTORE_3 :
+					visitor._lstore_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FSTORE_0 :
+					visitor._fstore_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FSTORE_1 :
+					visitor._fstore_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FSTORE_2 :
+					visitor._fstore_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FSTORE_3 :
+					visitor._fstore_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DSTORE_0 :
+					visitor._dstore_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DSTORE_1 :
+					visitor._dstore_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DSTORE_2 :
+					visitor._dstore_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DSTORE_3 :
+					visitor._dstore_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ASTORE_0 :
+					visitor._astore_0(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ASTORE_1 :
+					visitor._astore_1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ASTORE_2 :
+					visitor._astore_2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ASTORE_3 :
+					visitor._astore_3(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IASTORE :
+					visitor._iastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LASTORE :
+					visitor._lastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FASTORE :
+					visitor._fastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DASTORE :
+					visitor._dastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.AASTORE :
+					visitor._aastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.BASTORE :
+					visitor._bastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.CASTORE :
+					visitor._castore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.SASTORE :
+					visitor._sastore(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.POP :
+					visitor._pop(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.POP2 :
+					visitor._pop2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP :
+					visitor._dup(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP_X1 :
+					visitor._dup_x1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP_X2 :
+					visitor._dup_x2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP2 :
+					visitor._dup2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP2_X1 :
+					visitor._dup2_x1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DUP2_X2 :
+					visitor._dup2_x2(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.SWAP :
+					visitor._swap(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IADD :
+					visitor._iadd(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LADD :
+					visitor._ladd(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FADD :
+					visitor._fadd(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DADD :
+					visitor._dadd(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISUB :
+					visitor._isub(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSUB :
+					visitor._lsub(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FSUB :
+					visitor._fsub(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DSUB :
+					visitor._dsub(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IMUL :
+					visitor._imul(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LMUL :
+					visitor._lmul(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FMUL :
+					visitor._fmul(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DMUL :
+					visitor._dmul(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IDIV :
+					visitor._idiv(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LDIV :
+					visitor._ldiv(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FDIV :
+					visitor._fdiv(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DDIV :
+					visitor._ddiv(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IREM :
+					visitor._irem(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LREM :
+					visitor._lrem(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FREM :
+					visitor._frem(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DREM :
+					visitor._drem(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.INEG :
+					visitor._ineg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LNEG :
+					visitor._lneg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FNEG :
+					visitor._fneg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DNEG :
+					visitor._dneg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISHL :
+					visitor._ishl(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSHL :
+					visitor._lshl(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ISHR :
+					visitor._ishr(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LSHR :
+					visitor._lshr(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IUSHR :
+					visitor._iushr(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LUSHR :
+					visitor._lushr(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IAND :
+					visitor._iand(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LAND :
+					visitor._land(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IOR :
+					visitor._ior(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LOR :
+					visitor._lor(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IXOR :
+					visitor._ixor(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LXOR :
+					visitor._lxor(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IINC :
+					index = u1At(this.classFileBytes, 1, pc);
+					_const = i1At(this.classFileBytes, 2, pc);
+					visitor._iinc(pc - this.codeOffset, index, _const);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.I2L :
+					visitor._i2l(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.I2F :
+					visitor._i2f(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.I2D :
+					visitor._i2d(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.L2I :
+					visitor._l2i(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.L2F :
+					visitor._l2f(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.L2D :
+					visitor._l2d(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.F2I :
+					visitor._f2i(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.F2L :
+					visitor._f2l(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.F2D :
+					visitor._f2d(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.D2I :
+					visitor._d2i(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.D2L :
+					visitor._d2l(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.D2F :
+					visitor._d2f(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.I2B :
+					visitor._i2b(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.I2C :
+					visitor._i2c(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.I2S :
+					visitor._i2s(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LCMP :
+					visitor._lcmp(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FCMPL :
+					visitor._fcmpl(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FCMPG :
+					visitor._fcmpg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DCMPL :
+					visitor._dcmpl(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DCMPG :
+					visitor._dcmpg(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IFEQ :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifeq(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFNE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifne(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFLT :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._iflt(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFGE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifge(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFGT :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifgt(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFLE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifle(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPEQ :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmpeq(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPNE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmpne(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPLT :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmplt(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPGE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmpge(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPGT :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmpgt(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ICMPLE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_icmple(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ACMPEQ :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_acmpeq(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IF_ACMPNE :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._if_acmpne(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.GOTO :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._goto(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.JSR :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._jsr(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.RET :
+					index = u1At(this.classFileBytes, 1, pc);
+					visitor._ret(pc - this.codeOffset, index);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.TABLESWITCH :
+					int startpc = pc;
+					pc++;
+					while (((pc - this.codeOffset) & 0x03) != 0) { // faster than % 4
+						pc++;
+					}
+					int defaultOffset = i4At(this.classFileBytes, 0, pc);
+					pc += 4;
+					int low = i4At(this.classFileBytes, 0, pc);
+					pc += 4;
+					int high = i4At(this.classFileBytes, 0, pc);
+					pc += 4;
+					int length = high - low + 1;
+					int[] jumpOffsets = new int[length];
+					for (int i = 0; i < length; i++) {
+						jumpOffsets[i] = i4At(this.classFileBytes, 0, pc);
+						pc += 4;
+					}
+					visitor._tableswitch(startpc - this.codeOffset, defaultOffset, low, high, jumpOffsets);
+					break;
+				case IOpcodeMnemonics.LOOKUPSWITCH :
+					startpc = pc;
+					pc++;
+					while (((pc - this.codeOffset) & 0x03) != 0) {
+						pc++;
+					}
+					defaultOffset = i4At(this.classFileBytes, 0, pc);
+					pc += 4;
+					int npairs = (int) u4At(this.classFileBytes, 0, pc);
+					int[][] offset_pairs = new int[npairs][2];
+					pc += 4;
+					for (int i = 0; i < npairs; i++) {
+						offset_pairs[i][0] = i4At(this.classFileBytes, 0, pc);
+						pc += 4;
+						offset_pairs[i][1] = i4At(this.classFileBytes, 0, pc);
+						pc += 4;
+					}
+					visitor._lookupswitch(startpc - this.codeOffset, defaultOffset, npairs, offset_pairs);
+					break;
+				case IOpcodeMnemonics.IRETURN :
+					visitor._ireturn(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.LRETURN :
+					visitor._lreturn(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.FRETURN :
+					visitor._freturn(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.DRETURN :
+					visitor._dreturn(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ARETURN :
+					visitor._areturn(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.RETURN :
+					visitor._return(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.GETSTATIC :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._getstatic(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.PUTSTATIC :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._putstatic(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.GETFIELD :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._getfield(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.PUTFIELD :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._putfield(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.INVOKEVIRTUAL :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._invokevirtual(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.INVOKESPECIAL :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._invokespecial(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.INVOKESTATIC :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._invokestatic(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.INVOKEINTERFACE :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_InterfaceMethodref) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					byte count = (byte) u1At(this.classFileBytes, 3, pc);
+					int extraArgs = u1At(this.classFileBytes, 4, pc);
+					if (extraArgs != 0) {
+						throw new ClassFormatException(ClassFormatException.INVALID_ARGUMENTS_FOR_INVOKEINTERFACE);
+					}
+					visitor._invokeinterface(pc - this.codeOffset, index, count, constantPoolEntry);
+					pc += 5;
+					break;
+				case IOpcodeMnemonics.INVOKEDYNAMIC :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_InvokeDynamic) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._invokedynamic(
+							pc - this.codeOffset,
+							index,
+							constantPoolEntry);
+					pc += 5;
+					break;
+				case IOpcodeMnemonics.NEW :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._new(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.NEWARRAY :
+					int atype = u1At(this.classFileBytes, 1, pc);
+					visitor._newarray(pc - this.codeOffset, atype);
+					pc+=2;
+					break;
+				case IOpcodeMnemonics.ANEWARRAY :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._anewarray(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.ARRAYLENGTH :
+					visitor._arraylength(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.ATHROW :
+					visitor._athrow(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.CHECKCAST :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._checkcast(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.INSTANCEOF :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					visitor._instanceof(pc - this.codeOffset, index, constantPoolEntry);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.MONITORENTER :
+					visitor._monitorenter(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.MONITOREXIT :
+					visitor._monitorexit(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.WIDE :
+					opcode = u1At(this.classFileBytes, 1, pc);
+					if (opcode == IOpcodeMnemonics.IINC) {
+						index = u2At(this.classFileBytes, 2, pc);
+						_const = i2At(this.classFileBytes, 4, pc);
+						visitor._wide(pc - this.codeOffset, opcode, index, _const);
+						pc += 6;
+					} else {
+						index = u2At(this.classFileBytes, 2, pc);
+						visitor._wide(pc - this.codeOffset , opcode, index);
+						pc += 4;
+					}
+					break;
+				case IOpcodeMnemonics.MULTIANEWARRAY :
+					index = u2At(this.classFileBytes, 1, pc);
+					constantPoolEntry = this.constantPool.decodeEntry(index);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					int dimensions = u1At(this.classFileBytes, 3, pc);
+					visitor._multianewarray(pc - this.codeOffset, index, dimensions, constantPoolEntry);
+					pc+=4;
+					break;
+				case IOpcodeMnemonics.IFNULL :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifnull(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.IFNONNULL :
+					branchOffset = i2At(this.classFileBytes, 1, pc);
+					visitor._ifnonnull(pc - this.codeOffset , branchOffset);
+					pc+=3;
+					break;
+				case IOpcodeMnemonics.GOTO_W :
+					branchOffset = i4At(this.classFileBytes, 1, pc);
+					visitor._goto_w(pc - this.codeOffset, branchOffset);
+					pc+=5;
+					break;
+				case IOpcodeMnemonics.JSR_W :
+					branchOffset = i4At(this.classFileBytes, 1, pc);
+					visitor._jsr_w(pc - this.codeOffset, branchOffset);
+					pc+=5;
+					break;
+				case IOpcodeMnemonics.BREAKPOINT :
+					visitor._breakpoint(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IMPDEP1 :
+					visitor._impdep1(pc - this.codeOffset);
+					pc++;
+					break;
+				case IOpcodeMnemonics.IMPDEP2 :
+					visitor._impdep2(pc - this.codeOffset);
+					pc++;
+					break;
+				default:
+					throw new ClassFormatException(ClassFormatException.INVALID_BYTECODE);
+			}
+			if (pc >= (this.codeLength + this.codeOffset)) {
+				break;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java
new file mode 100644
index 0000000..5b119ca
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+/**
+ * Utility class to parse different code snippets
+ */
+public class CodeSnippetParsingUtil {
+
+	public RecordedParsingInformation recordedParsingInformation;
+	public boolean ignoreMethodBodies;
+	
+	public CodeSnippetParsingUtil(boolean ignoreMethodBodies) {
+		this.ignoreMethodBodies = ignoreMethodBodies;
+	}
+
+	public CodeSnippetParsingUtil() {
+		this(false);
+	}
+
+	private RecordedParsingInformation getRecordedParsingInformation(CompilationResult compilationResult, int[][] commentPositions) {
+		int problemsCount = compilationResult.problemCount;
+		CategorizedProblem[] problems = null;
+		if (problemsCount != 0) {
+			final CategorizedProblem[] compilationResultProblems = compilationResult.problems;
+			if (compilationResultProblems.length == problemsCount) {
+				problems = compilationResultProblems;
+			} else {
+				System.arraycopy(compilationResultProblems, 0, (problems = new CategorizedProblem[problemsCount]), 0, problemsCount);
+			}
+		}
+		return new RecordedParsingInformation(problems, compilationResult.getLineSeparatorPositions(), commentPositions);
+	}
+
+	public ASTNode[] parseClassBodyDeclarations(char[] source, Map settings, boolean recordParsingInformation) {
+		return parseClassBodyDeclarations(source, 0, source.length, settings, recordParsingInformation, false);
+	}
+
+	public ASTNode[] parseClassBodyDeclarations(
+			char[] source,
+			int offset,
+			int length,
+			Map settings,
+			boolean recordParsingInformation,
+			boolean enabledStatementRecovery) {
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		compilerOptions.ignoreMethodBodies = this.ignoreMethodBodies;
+		final ProblemReporter problemReporter = new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					compilerOptions,
+					new DefaultProblemFactory(Locale.getDefault()));
+
+		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
+		parser.setMethodsFullRecovery(false);
+		parser.setStatementsRecovery(enabledStatementRecovery);
+
+		ICompilationUnit sourceUnit =
+			new CompilationUnit(
+				source,
+				"", //$NON-NLS-1$
+				compilerOptions.defaultEncoding);
+
+		CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+		final CompilationUnitDeclaration compilationUnitDeclaration = new CompilationUnitDeclaration(problemReporter, compilationResult, source.length);
+		ASTNode[] result = parser.parseClassBodyDeclarations(source, offset, length, compilationUnitDeclaration);
+
+		if (recordParsingInformation) {
+			this.recordedParsingInformation = getRecordedParsingInformation(compilationResult, compilationUnitDeclaration.comments);
+		}
+		return result;
+	}
+
+	public CompilationUnitDeclaration parseCompilationUnit(char[] source, Map settings, boolean recordParsingInformation) {
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		compilerOptions.ignoreMethodBodies = this.ignoreMethodBodies;
+		CommentRecorderParser parser =
+			new CommentRecorderParser(
+				new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					compilerOptions,
+					new DefaultProblemFactory(Locale.getDefault())),
+			false);
+
+		ICompilationUnit sourceUnit =
+			new CompilationUnit(
+				source,
+				"", //$NON-NLS-1$
+				compilerOptions.defaultEncoding);
+		final CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
+
+		if (recordParsingInformation) {
+			this.recordedParsingInformation = getRecordedParsingInformation(compilationResult, compilationUnitDeclaration.comments);
+		}
+
+		if (compilationUnitDeclaration.ignoreMethodBodies) {
+			compilationUnitDeclaration.ignoreFurtherInvestigation = true;
+			// if initial diet parse did not work, no need to dig into method bodies.
+			return compilationUnitDeclaration;
+		}
+
+		//fill the methods bodies in order for the code to be generated
+		//real parse of the method....
+		parser.scanner.setSource(compilationResult);
+		org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+		if (types != null) {
+			for (int i = 0, length = types.length; i < length; i++) {
+				types[i].parseMethods(parser, compilationUnitDeclaration);
+			}
+		}
+
+		if (recordParsingInformation) {
+			this.recordedParsingInformation.updateRecordedParsingInformation(compilationResult);
+		}
+		return compilationUnitDeclaration;
+	}
+
+	public Expression parseExpression(char[] source, Map settings, boolean recordParsingInformation) {
+		return parseExpression(source, 0, source.length, settings, recordParsingInformation);
+	}
+
+	public Expression parseExpression(char[] source, int offset, int length, Map settings, boolean recordParsingInformation) {
+
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		// in this case we don't want to ignore method bodies since we are parsing only an expression
+		final ProblemReporter problemReporter = new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					compilerOptions,
+					new DefaultProblemFactory(Locale.getDefault()));
+
+		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
+
+		ICompilationUnit sourceUnit =
+			new CompilationUnit(
+				source,
+				"", //$NON-NLS-1$
+				compilerOptions.defaultEncoding);
+
+		CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration unit = new CompilationUnitDeclaration(problemReporter, compilationResult, source.length);
+		Expression result = parser.parseExpression(source, offset, length, unit, true /* record line separators */);
+
+		if (recordParsingInformation) {
+			this.recordedParsingInformation = getRecordedParsingInformation(compilationResult, unit.comments);
+		}
+		return result;
+	}
+
+	public ConstructorDeclaration parseStatements(char[] source, Map settings, boolean recordParsingInformation, boolean enabledStatementRecovery) {
+		return parseStatements(source, 0, source.length, settings, recordParsingInformation, enabledStatementRecovery);
+	}
+
+	public ConstructorDeclaration parseStatements(
+			char[] source,
+			int offset,
+			int length,
+			Map settings,
+			boolean recordParsingInformation,
+			boolean enabledStatementRecovery) {
+		if (source == null) {
+			throw new IllegalArgumentException();
+		}
+		CompilerOptions compilerOptions = new CompilerOptions(settings);
+		// in this case we don't want to ignore method bodies since we are parsing only statements
+		final ProblemReporter problemReporter = new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					compilerOptions,
+					new DefaultProblemFactory(Locale.getDefault()));
+		CommentRecorderParser parser = new CommentRecorderParser(problemReporter, false);
+		parser.setMethodsFullRecovery(false);
+		parser.setStatementsRecovery(enabledStatementRecovery);
+
+		ICompilationUnit sourceUnit =
+			new CompilationUnit(
+				source,
+				"", //$NON-NLS-1$
+				compilerOptions.defaultEncoding);
+
+		final CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+		CompilationUnitDeclaration compilationUnitDeclaration = new CompilationUnitDeclaration(problemReporter, compilationResult, length);
+
+		ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration(compilationResult);
+		constructorDeclaration.sourceEnd  = -1;
+		constructorDeclaration.declarationSourceEnd = offset + length - 1;
+		constructorDeclaration.bodyStart = offset;
+		constructorDeclaration.bodyEnd = offset + length - 1;
+
+		parser.scanner.setSource(compilationResult);
+		parser.scanner.resetTo(offset, offset + length);
+		parser.parse(constructorDeclaration, compilationUnitDeclaration, true);
+
+		if (recordParsingInformation) {
+			this.recordedParsingInformation = getRecordedParsingInformation(compilationResult, compilationUnitDeclaration.comments);
+		}
+		return constructorDeclaration;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
new file mode 100644
index 0000000..f789b58
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
@@ -0,0 +1,268 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+
+/**
+ * Internal parser used for parsing source to create DOM AST nodes.
+ *
+ * @since 3.0
+ */
+public class CommentRecorderParser extends Parser {
+
+	// support for comments
+	int[] commentStops = new int[10];
+	int[] commentStarts = new int[10];
+	int commentPtr = -1; // no comment test with commentPtr value -1
+	protected final static int CommentIncrement = 100;
+
+	/**
+	 * @param problemReporter
+	 * @param optimizeStringLiterals
+	 */
+	public CommentRecorderParser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
+		super(problemReporter, optimizeStringLiterals);
+	}
+
+	// old javadoc style check which doesn't include all leading comments into declaration
+	// for backward compatibility with 2.1 DOM
+	public void checkComment() {
+
+		// discard obsolete comments while inside methods or fields initializer (see bug 74369)
+		if (!(this.diet && this.dietInt==0) && this.scanner.commentPtr >= 0) {
+			flushCommentsDefinedPriorTo(this.endStatementPosition);
+		}
+		boolean deprecated = false;
+		boolean checkDeprecated = false;
+		int lastCommentIndex = -1;
+
+		//since jdk1.2 look only in the last java doc comment...
+		nextComment : for (lastCommentIndex = this.scanner.commentPtr; lastCommentIndex >= 0; lastCommentIndex--){
+			//look for @deprecated into the first javadoc comment preceeding the declaration
+			int commentSourceStart = this.scanner.commentStarts[lastCommentIndex];
+			// javadoc only (non javadoc comment have negative start and/or end positions.)
+			if ((commentSourceStart < 0) ||
+				(this.modifiersSourceStart != -1 && this.modifiersSourceStart < commentSourceStart) ||
+				(this.scanner.commentStops[lastCommentIndex] < 0))
+			{
+				continue nextComment;
+			}
+			checkDeprecated = true;
+			int commentSourceEnd = this.scanner.commentStops[lastCommentIndex] - 1; //stop is one over
+			// do not report problem before last parsed comment while recovering code...
+			if (this.javadocParser.shouldReportProblems) {
+				this.javadocParser.reportProblems = this.currentElement == null || commentSourceEnd > this.lastJavadocEnd;
+			} else {
+				this.javadocParser.reportProblems = false;
+			}
+			deprecated = this.javadocParser.checkDeprecation(lastCommentIndex);
+			this.javadoc = this.javadocParser.docComment;
+			if (this.currentElement == null) this.lastJavadocEnd = commentSourceEnd;
+			break nextComment;
+		}
+		if (deprecated) {
+			checkAndSetModifiers(ClassFileConstants.AccDeprecated);
+		}
+		// modify the modifier source start to point at the first comment
+		if (lastCommentIndex >= 0 && checkDeprecated) {
+			this.modifiersSourceStart = this.scanner.commentStarts[lastCommentIndex];
+			if (this.modifiersSourceStart < 0) {
+				this.modifiersSourceStart = -this.modifiersSourceStart;
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#consumeClassHeader()
+	 */
+	protected void consumeClassHeader() {
+		pushOnCommentsStack(0, this.scanner.commentPtr);
+		super.consumeClassHeader();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#consumeEmptyTypeDeclaration()
+	 */
+	protected void consumeEmptyTypeDeclaration() {
+		pushOnCommentsStack(0, this.scanner.commentPtr);
+		super.consumeEmptyTypeDeclaration();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#consumeInterfaceHeader()
+	 */
+	protected void consumeInterfaceHeader() {
+		pushOnCommentsStack(0, this.scanner.commentPtr);
+		super.consumeInterfaceHeader();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#endParse(int)
+	 */
+	protected CompilationUnitDeclaration endParse(int act) {
+		CompilationUnitDeclaration unit = super.endParse(act);
+		if (unit.comments == null) {
+			pushOnCommentsStack(0, this.scanner.commentPtr);
+			unit.comments = getCommentsPositions();
+		}
+		return unit;
+	}
+
+	/* (non-Javadoc)
+	 * Save all source comments currently stored before flushing them.
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#flushCommentsDefinedPriorTo(int)
+	 */
+	public int flushCommentsDefinedPriorTo(int position) {
+
+		int lastCommentIndex = this.scanner.commentPtr;
+		if (lastCommentIndex < 0) return position; // no comment
+
+		// compute the index of the first obsolete comment
+		int index = lastCommentIndex;
+		int validCount = 0;
+		while (index >= 0){
+			int commentEnd = this.scanner.commentStops[index];
+			if (commentEnd < 0) commentEnd = -commentEnd; // negative end position for non-javadoc comments
+			if (commentEnd <= position){
+				break;
+			}
+			index--;
+			validCount++;
+		}
+		// if the source at <position> is immediately followed by a line comment, then
+		// flush this comment and shift <position> to the comment end.
+		if (validCount > 0){
+			int immediateCommentEnd = 0;
+			while (index<lastCommentIndex && (immediateCommentEnd = -this.scanner.commentStops[index+1])  > 0){ // only tolerating non-javadoc comments (non-javadoc comment end positions are negative)
+				// is there any line break until the end of the immediate comment ? (thus only tolerating line comment)
+				immediateCommentEnd--; // comment end in one char too far
+				if (org.eclipse.jdt.internal.compiler.util.Util.getLineNumber(position, this.scanner.lineEnds, 0, this.scanner.linePtr)
+						!= org.eclipse.jdt.internal.compiler.util.Util.getLineNumber(immediateCommentEnd, this.scanner.lineEnds, 0, this.scanner.linePtr)) break;
+				position = immediateCommentEnd;
+				validCount--; // flush this comment
+				index++;
+			}
+		}
+
+		if (index < 0) return position; // no obsolete comment
+		pushOnCommentsStack(0, index); // store comment before flushing them
+
+		switch (validCount) {
+			case 0:
+				// do nothing
+				break;
+			// move valid comment infos, overriding obsolete comment infos
+			case 2:
+				this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+				this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+				this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+				this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2];
+				this.scanner.commentStops[1] = this.scanner.commentStops[index+2];
+				this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2];
+				break;
+			case 1:
+				this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+				this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+				this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+				break;
+			default:
+				System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
+				System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);
+				System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount);
+		}
+		this.scanner.commentPtr = validCount - 1;
+		return position;
+	}
+
+	/*
+	 * Build a n*2 matrix of comments positions.
+	 * For each position, 0 is for start position and 1 for end position of the comment.
+	 */
+	public int[][] getCommentsPositions() {
+		int[][] positions = new int[this.commentPtr+1][2];
+		for (int i = 0, max = this.commentPtr; i <= max; i++){
+			positions[i][0] = this.commentStarts[i];
+			positions[i][1] = this.commentStops[i];
+		}
+		return positions;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#initialize()
+	 */
+	public void initialize(boolean initializeNLS) {
+		super.initialize(initializeNLS);
+		this.commentPtr = -1;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#initialize()
+	 */
+	public void initialize() {
+		super.initialize();
+		this.commentPtr = -1;
+	}
+
+	/* (non-Javadoc)
+	 * Create and store a specific comment recorder scanner.
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#initializeScanner()
+	 */
+	public void initializeScanner() {
+		this.scanner = new Scanner(
+				false /*comment*/,
+				false /*whitespace*/,
+				this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /*nls*/,
+				this.options.sourceLevel /*sourceLevel*/,
+				this.options.taskTags/*taskTags*/,
+				this.options.taskPriorities/*taskPriorities*/,
+				this.options.isTaskCaseSensitive/*taskCaseSensitive*/);
+	}
+
+	/*
+	 * Push all stored comments in stack.
+	 */
+	private void pushOnCommentsStack(int start, int end) {
+
+		for (int i=start; i<=end; i++) {
+			// First see if comment hasn't been already stored
+			int scannerStart = this.scanner.commentStarts[i]<0 ? -this.scanner.commentStarts[i] : this.scanner.commentStarts[i];
+			int commentStart = this.commentPtr == -1 ? -1 : (this.commentStarts[this.commentPtr]<0 ? -this.commentStarts[this.commentPtr] : this.commentStarts[this.commentPtr]);
+			if (commentStart == -1 ||  scannerStart > commentStart) {
+				int stackLength = this.commentStarts.length;
+				if (++this.commentPtr >= stackLength) {
+					System.arraycopy(
+						this.commentStarts, 0,
+						this.commentStarts = new int[stackLength + CommentIncrement], 0,
+						stackLength);
+					System.arraycopy(
+						this.commentStops, 0,
+						this.commentStops = new int[stackLength + CommentIncrement], 0,
+						stackLength);
+				}
+				this.commentStarts[this.commentPtr] = this.scanner.commentStarts[i];
+				this.commentStops[this.commentPtr] = this.scanner.commentStops[i];
+			}
+		}
+	}
+	/* (non-Javadoc)
+	 * Save all source comments currently stored before flushing them.
+	 * this.scanner.commentPtr is expected *not* yet being reset before calling this method.
+	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#resetModifiers()
+	 */
+	protected void resetModifiers() {
+		pushOnCommentsStack(0, this.scanner.commentPtr);
+		super.resetModifiers();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java
new file mode 100644
index 0000000..a9c4699
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IConstantPool.
+ */
+public class ConstantPool extends ClassFileStruct implements IConstantPool {
+
+	private int constantPoolCount;
+	private int[] constantPoolOffset;
+	private byte[] classFileBytes;
+
+	ConstantPool(byte[] reference, int[] constantPoolOffset) {
+		this.constantPoolCount = constantPoolOffset.length;
+		this.constantPoolOffset = constantPoolOffset;
+		this.classFileBytes = reference;
+	}
+
+	/**
+	 * @see IConstantPool#decodeEntry(int)
+	 */
+	public IConstantPoolEntry decodeEntry(int index) {
+		ConstantPoolEntry constantPoolEntry = null;
+		int kind = getEntryKind(index);
+		switch(kind) {
+			case IConstantPoolConstant.CONSTANT_Class :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setClassInfoNameIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				constantPoolEntry.setClassInfoName(getUtf8ValueAt(constantPoolEntry.getClassInfoNameIndex()));
+				break;
+			case IConstantPoolConstant.CONSTANT_Double :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setDoubleValue(doubleAt(this.classFileBytes, 1, this.constantPoolOffset[index]));
+				break;
+			case IConstantPoolConstant.CONSTANT_Fieldref :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setClassIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				int declaringClassIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]);
+				constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex));
+				constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes,  3, this.constantPoolOffset[index]));
+				int fieldNameIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]);
+				int fieldDescriptorIndex = u2At(this.classFileBytes,  3, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]);
+				constantPoolEntry.setFieldName(getUtf8ValueAt(fieldNameIndex));
+				constantPoolEntry.setFieldDescriptor(getUtf8ValueAt(fieldDescriptorIndex));
+				break;
+			case IConstantPoolConstant.CONSTANT_Methodref :
+			case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setClassIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				declaringClassIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[constantPoolEntry.getClassIndex()]);
+				constantPoolEntry.setClassName(getUtf8ValueAt(declaringClassIndex));
+				constantPoolEntry.setNameAndTypeIndex(u2At(this.classFileBytes,  3, this.constantPoolOffset[index]));
+				int methodNameIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]);
+				int methodDescriptorIndex = u2At(this.classFileBytes,  3, this.constantPoolOffset[constantPoolEntry.getNameAndTypeIndex()]);
+				constantPoolEntry.setMethodName(getUtf8ValueAt(methodNameIndex));
+				constantPoolEntry.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex));
+				break;
+			case IConstantPoolConstant.CONSTANT_Float :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setFloatValue(floatAt(this.classFileBytes, 1, this.constantPoolOffset[index]));
+				break;
+			case IConstantPoolConstant.CONSTANT_Integer :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setIntegerValue(i4At(this.classFileBytes, 1, this.constantPoolOffset[index]));
+				break;
+			case IConstantPoolConstant.CONSTANT_Long :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setLongValue(i8At(this.classFileBytes, 1, this.constantPoolOffset[index]));
+				break;
+			case IConstantPoolConstant.CONSTANT_NameAndType :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setNameAndTypeNameIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				constantPoolEntry.setNameAndTypeDescriptorIndex(u2At(this.classFileBytes,  3, this.constantPoolOffset[index]));
+				break;
+			case IConstantPoolConstant.CONSTANT_String :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setStringIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				constantPoolEntry.setStringValue(getUtf8ValueAt(constantPoolEntry.getStringIndex()));
+				break;
+			case IConstantPoolConstant.CONSTANT_Utf8 :
+				constantPoolEntry = new ConstantPoolEntry();
+				constantPoolEntry.reset();
+				constantPoolEntry.setKind(kind);
+				constantPoolEntry.setUtf8Length(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				constantPoolEntry.setUtf8Value(getUtf8ValueAt(index));
+				break;
+			case IConstantPoolConstant.CONSTANT_MethodHandle :
+				ConstantPoolEntry2 constantPoolEntry2 = new ConstantPoolEntry2();
+				constantPoolEntry2.reset();
+				constantPoolEntry2.setKind(kind);
+				constantPoolEntry2.setReferenceKind(u1At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				constantPoolEntry2.setReferenceIndex(u2At(this.classFileBytes,  2, this.constantPoolOffset[index]));
+				constantPoolEntry = constantPoolEntry2;
+				break;
+			case IConstantPoolConstant.CONSTANT_MethodType :
+				constantPoolEntry2 = new ConstantPoolEntry2();
+				constantPoolEntry2.reset();
+				constantPoolEntry2.setKind(kind);
+				methodDescriptorIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[index]);
+				constantPoolEntry2.setDescriptorIndex(methodDescriptorIndex);
+				constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex));
+				constantPoolEntry = constantPoolEntry2;
+				break;
+			case IConstantPoolConstant.CONSTANT_InvokeDynamic :
+				constantPoolEntry2 = new ConstantPoolEntry2();
+				constantPoolEntry2.reset();
+				constantPoolEntry2.setKind(kind);
+				constantPoolEntry2.setBootstrapMethodAttributeIndex(u2At(this.classFileBytes,  1, this.constantPoolOffset[index]));
+				int nameAndTypeIndex = u2At(this.classFileBytes,  3, this.constantPoolOffset[index]);
+				constantPoolEntry2.setNameAndTypeIndex(nameAndTypeIndex);
+				methodNameIndex = u2At(this.classFileBytes,  1, this.constantPoolOffset[nameAndTypeIndex]);
+				methodDescriptorIndex = u2At(this.classFileBytes,  3, this.constantPoolOffset[nameAndTypeIndex]);
+				constantPoolEntry2.setMethodName(getUtf8ValueAt(methodNameIndex));
+				constantPoolEntry2.setMethodDescriptor(getUtf8ValueAt(methodDescriptorIndex));
+				constantPoolEntry = constantPoolEntry2;
+				break;
+		}
+		return constantPoolEntry;
+	}
+
+	/**
+	 * @see IConstantPool#getConstantPoolCount()
+	 */
+	public int getConstantPoolCount() {
+		return this.constantPoolCount;
+	}
+
+	/**
+	 * @see IConstantPool#getEntryKind(int)
+	 */
+	public int getEntryKind(int index) {
+		return u1At(this.classFileBytes, 0, this.constantPoolOffset[index]);
+	}
+
+	private char[] getUtf8ValueAt(int utf8Index) {
+		int utf8Offset = this.constantPoolOffset[utf8Index];
+		return utf8At(this.classFileBytes, 0, utf8Offset + 3, u2At(this.classFileBytes, 0, utf8Offset + 1));
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java
new file mode 100644
index 0000000..9f9cae6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java
@@ -0,0 +1,404 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+
+/**
+ * Default implementation of IConstantPoolEntry
+ *
+ * @since 2.0
+ */
+public class ConstantPoolEntry implements IConstantPoolEntry {
+
+	private int kind;
+	private int classInfoNameIndex;
+	private int classIndex;
+	private int nameAndTypeIndex;
+	private int stringIndex;
+	private char[] stringValue;
+	private int integerValue;
+	private float floatValue;
+	private double doubleValue;
+	private long longValue;
+	private int nameAndTypeDescriptorIndex;
+	private int nameAndTypeNameIndex;
+	private char[] className;
+	private char[] fieldName;
+	private char[] methodName;
+	private char[] fieldDescriptor;
+	private char[] methodDescriptor;
+	private char[] utf8Value;
+	private int utf8Length;
+	private char[] classInfoName;
+
+	public ConstantPoolEntry() {
+		this.classInfoNameIndex = -1;
+		this.classIndex = -1;
+		this.nameAndTypeIndex = -1;
+		this.stringIndex = -1;
+		this.stringValue = null;
+		this.integerValue = -1;
+		this.floatValue = -0.0f;
+		this.doubleValue = -0-0;
+		this.longValue = -1;
+		this.nameAndTypeDescriptorIndex = -1;
+		this.nameAndTypeNameIndex = -1;
+		this.className = null;
+		this.fieldName = null;
+		this.methodName = null;
+		this.fieldDescriptor = null;
+		this.methodDescriptor = null;
+		this.utf8Value = null;
+		this.utf8Length = -1;
+		this.classInfoName = null;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getKind()
+	 */
+	public int getKind() {
+		return this.kind;
+	}
+
+	/**
+	 * Sets the kind.
+	 * @param kind The kind to set
+	 */
+	public void setKind(int kind) {
+		this.kind = kind;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getClassInfoNameIndex()
+	 */
+	public int getClassInfoNameIndex() {
+		return this.classInfoNameIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getClassIndex()
+	 */
+	public int getClassIndex() {
+		return this.classIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getNameAndTypeIndex()
+	 */
+	public int getNameAndTypeIndex() {
+		return this.nameAndTypeIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getStringIndex()
+	 */
+	public int getStringIndex() {
+		return this.stringIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getStringValue()
+	 */
+	public String getStringValue() {
+		return new String(this.stringValue);
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getIntegerValue()
+	 */
+	public int getIntegerValue() {
+		return this.integerValue;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getFloatValue()
+	 */
+	public float getFloatValue() {
+		return this.floatValue;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getDoubleValue()
+	 */
+	public double getDoubleValue() {
+		return this.doubleValue;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getLongValue()
+	 */
+	public long getLongValue() {
+		return this.longValue;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getNameAndTypeInfoDescriptorIndex()
+	 */
+	public int getNameAndTypeInfoDescriptorIndex() {
+		return this.nameAndTypeDescriptorIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getNameAndTypeInfoNameIndex()
+	 */
+	public int getNameAndTypeInfoNameIndex() {
+		return this.nameAndTypeNameIndex;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getClassName()
+	 */
+	public char[] getClassName() {
+		return this.className;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getFieldName()
+	 */
+	public char[] getFieldName() {
+		return this.fieldName;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getMethodName()
+	 */
+	public char[] getMethodName() {
+		return this.methodName;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getFieldDescriptor()
+	 */
+	public char[] getFieldDescriptor() {
+		return this.fieldDescriptor;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getMethodDescriptor()
+	 */
+	public char[] getMethodDescriptor() {
+		return this.methodDescriptor;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getUtf8Value()
+	 */
+	public char[] getUtf8Value() {
+		return this.utf8Value;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getClassInfoName()
+	 */
+	public char[] getClassInfoName() {
+		return this.classInfoName;
+	}
+
+	/**
+	 * Sets the classInfoNameIndex.
+	 * @param classInfoNameIndex The classInfoNameIndex to set
+	 */
+	public void setClassInfoNameIndex(int classInfoNameIndex) {
+		this.classInfoNameIndex = classInfoNameIndex;
+	}
+
+	/**
+	 * Sets the classIndex.
+	 * @param classIndex The classIndex to set
+	 */
+	public void setClassIndex(int classIndex) {
+		this.classIndex = classIndex;
+	}
+
+	/**
+	 * Sets the nameAndTypeIndex.
+	 * @param nameAndTypeIndex The nameAndTypeIndex to set
+	 */
+	public void setNameAndTypeIndex(int nameAndTypeIndex) {
+		this.nameAndTypeIndex = nameAndTypeIndex;
+	}
+
+	/**
+	 * Sets the stringIndex.
+	 * @param stringIndex The stringIndex to set
+	 */
+	public void setStringIndex(int stringIndex) {
+		this.stringIndex = stringIndex;
+	}
+
+	/**
+	 * Sets the stringValue.
+	 * @param stringValue The stringValue to set
+	 */
+	public void setStringValue(char[] stringValue) {
+		this.stringValue = stringValue;
+	}
+
+	/**
+	 * Sets the integerValue.
+	 * @param integerValue The integerValue to set
+	 */
+	public void setIntegerValue(int integerValue) {
+		this.integerValue = integerValue;
+	}
+
+	/**
+	 * Sets the floatValue.
+	 * @param floatValue The floatValue to set
+	 */
+	public void setFloatValue(float floatValue) {
+		this.floatValue = floatValue;
+	}
+
+	/**
+	 * Sets the doubleValue.
+	 * @param doubleValue The doubleValue to set
+	 */
+	public void setDoubleValue(double doubleValue) {
+		this.doubleValue = doubleValue;
+	}
+
+	/**
+	 * Sets the longValue.
+	 * @param longValue The longValue to set
+	 */
+	public void setLongValue(long longValue) {
+		this.longValue = longValue;
+	}
+
+	/**
+	 * Gets the nameAndTypeDescriptorIndex.
+	 * @return Returns a int
+	 */
+	public int getNameAndTypeDescriptorIndex() {
+		return this.nameAndTypeDescriptorIndex;
+	}
+
+	/**
+	 * Sets the nameAndTypeDescriptorIndex.
+	 * @param nameAndTypeDescriptorIndex The nameAndTypeDescriptorIndex to set
+	 */
+	public void setNameAndTypeDescriptorIndex(int nameAndTypeDescriptorIndex) {
+		this.nameAndTypeDescriptorIndex = nameAndTypeDescriptorIndex;
+	}
+
+	/**
+	 * Gets the nameAndTypeNameIndex.
+	 * @return Returns a int
+	 */
+	public int getNameAndTypeNameIndex() {
+		return this.nameAndTypeNameIndex;
+	}
+
+	/**
+	 * Sets the nameAndTypeNameIndex.
+	 * @param nameAndTypeNameIndex The nameAndTypeNameIndex to set
+	 */
+	public void setNameAndTypeNameIndex(int nameAndTypeNameIndex) {
+		this.nameAndTypeNameIndex = nameAndTypeNameIndex;
+	}
+
+	/**
+	 * Sets the className.
+	 * @param className The className to set
+	 */
+	public void setClassName(char[] className) {
+		this.className = className;
+	}
+
+	/**
+	 * Sets the fieldName.
+	 * @param fieldName The fieldName to set
+	 */
+	public void setFieldName(char[] fieldName) {
+		this.fieldName = fieldName;
+	}
+
+	/**
+	 * Sets the methodName.
+	 * @param methodName The methodName to set
+	 */
+	public void setMethodName(char[] methodName) {
+		this.methodName = methodName;
+	}
+
+	/**
+	 * Sets the fieldDescriptor.
+	 * @param fieldDescriptor The fieldDescriptor to set
+	 */
+	public void setFieldDescriptor(char[] fieldDescriptor) {
+		this.fieldDescriptor = fieldDescriptor;
+	}
+
+	/**
+	 * Sets the methodDescriptor.
+	 *
+	 * @param methodDescriptor The methodDescriptor to set
+	 */
+	public void setMethodDescriptor(char[] methodDescriptor) {
+		this.methodDescriptor = methodDescriptor;
+	}
+
+	/**
+	 * Sets the utf8Value.
+	 * @param utf8Value The utf8Value to set
+	 */
+	public void setUtf8Value(char[] utf8Value) {
+		this.utf8Value = utf8Value;
+	}
+
+	/**
+	 * Sets the classInfoName.
+	 * @param classInfoName The classInfoName to set
+	 */
+	public void setClassInfoName(char[] classInfoName) {
+		this.classInfoName = classInfoName;
+	}
+
+	/**
+	 * @see IConstantPoolEntry#getUtf8Length()
+	 */
+	public int getUtf8Length() {
+		return this.utf8Length;
+	}
+
+	/**
+	 * Sets the utf8Length.
+	 * @param utf8Length The utf8Length to set
+	 */
+	public void setUtf8Length(int utf8Length) {
+		this.utf8Length = utf8Length;
+	}
+
+	public void reset() {
+		this.kind = 0;
+		this.classInfoNameIndex = 0;
+		this.classIndex = 0;
+		this.nameAndTypeIndex = 0;
+		this.stringIndex = 0;
+		this.stringValue = null;
+		this.integerValue = 0;
+		this.floatValue = 0.0f;
+		this.doubleValue = 0.0;
+		this.longValue = 0L;
+		this.nameAndTypeDescriptorIndex = 0;
+		this.nameAndTypeNameIndex = 0;
+		this.className = null;
+		this.fieldName = null;
+		this.methodName = null;
+		this.fieldDescriptor = null;
+		this.methodDescriptor = null;
+		this.utf8Value = null;
+		this.utf8Length = 0;
+		this.classInfoName = null;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java
new file mode 100644
index 0000000..c6c9686
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry2.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.IConstantPoolEntry2;
+
+/**
+ * Default implementation of IConstantPoolEntry
+ *
+ * @since 2.0
+ */
+public class ConstantPoolEntry2 extends ConstantPoolEntry implements IConstantPoolEntry2 {
+	
+	private int descriptorIndex;
+	private int referenceKind;
+	private int referenceIndex;
+	private int bootstrapMethodAttributeIndex;
+	
+	public int getDescriptorIndex() {
+		return this.descriptorIndex;
+	}
+
+	public int getReferenceKind() {
+		return this.referenceKind;
+	}
+
+	public int getReferenceIndex() {
+		return this.referenceIndex;
+	}
+
+	public int getBootstrapMethodAttributeIndex() {
+		return this.bootstrapMethodAttributeIndex;
+	}
+
+	public void setDescriptorIndex(int descriptorIndex) {
+		this.descriptorIndex = descriptorIndex;
+	}
+
+	public void setReferenceKind(int referenceKind) {
+		this.referenceKind = referenceKind;
+	}
+
+	public void setReferenceIndex(int referenceIndex) {
+		this.referenceIndex = referenceIndex;
+	}
+
+	public void setBootstrapMethodAttributeIndex(int bootstrapMethodAttributeIndex) {
+		this.bootstrapMethodAttributeIndex = bootstrapMethodAttributeIndex;
+	}
+	
+	public void reset() {
+		super.reset();
+		this.descriptorIndex = 0;
+		this.referenceKind = 0;
+		this.referenceIndex = 0;
+		this.bootstrapMethodAttributeIndex = 0;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java
new file mode 100644
index 0000000..d0d480f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IConstantValueAttribute;
+
+/**
+ * Default implementation of IConstantValueAttribute.
+ */
+public class ConstantValueAttribute
+	extends ClassFileAttribute
+	implements IConstantValueAttribute {
+
+	private int constantValueIndex;
+	private IConstantPoolEntry constantPoolEntry;
+
+
+	ConstantValueAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.constantValueIndex = u2At(classFileBytes, 6, offset);
+		this.constantPoolEntry = constantPool.decodeEntry(this.constantValueIndex);
+	}
+	/**
+	 * @see IConstantValueAttribute#getConstantValue()
+	 */
+	public IConstantPoolEntry getConstantValue() {
+		return this.constantPoolEntry;
+	}
+
+	/**
+	 * @see IConstantValueAttribute#getConstantValueIndex()
+	 */
+	public int getConstantValueIndex() {
+		return this.constantValueIndex;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
new file mode 100644
index 0000000..f56ce63
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.MarkerAnnotation;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.NormalAnnotation;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.internal.core.SourceRefElement;
+
+public class DOMFinder extends ASTVisitor {
+
+	public ASTNode foundNode = null;
+	public IBinding foundBinding = null;
+
+	private CompilationUnit ast;
+	private SourceRefElement element;
+	private boolean resolveBinding;
+	private int rangeStart = -1, rangeLength = 0;
+
+	public DOMFinder(CompilationUnit ast, SourceRefElement element, boolean resolveBinding) {
+		this.ast = ast;
+		this.element = element;
+		this.resolveBinding = resolveBinding;
+	}
+
+	protected boolean found(ASTNode node, ASTNode name) {
+		if (name.getStartPosition() == this.rangeStart && name.getLength() == this.rangeLength) {
+			this.foundNode = node;
+			return true;
+		}
+		return false;
+	}
+
+	public ASTNode search() throws JavaModelException {
+		ISourceRange range = null;
+		if (this.element instanceof IMember && !(this.element instanceof IInitializer))
+			range = ((IMember) this.element).getNameRange();
+		else
+			range = this.element.getSourceRange();
+		this.rangeStart = range.getOffset();
+		this.rangeLength = range.getLength();
+		this.ast.accept(this);
+		return this.foundNode;
+	}
+
+	public boolean visit(AnnotationTypeDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(AnonymousClassDeclaration node) {
+		ASTNode name;
+		ASTNode parent = node.getParent();
+		switch (parent.getNodeType()) {
+			case ASTNode.CLASS_INSTANCE_CREATION:
+				name = ((ClassInstanceCreation) parent).getType();
+				if (name.getNodeType() == ASTNode.PARAMETERIZED_TYPE) {
+					name = ((ParameterizedType) name).getType();
+				}
+				break;
+			case ASTNode.ENUM_CONSTANT_DECLARATION:
+				name = ((EnumConstantDeclaration) parent).getName();
+				break;
+			default:
+				return true;
+		}
+		if (found(node, name) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(EnumConstantDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveVariable();
+		return true;
+	}
+
+	public boolean visit(EnumDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(ImportDeclaration node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(Initializer node) {
+		// note that no binding exists for an Initializer
+		found(node, node);
+		return true;
+	}
+
+	public boolean visit(MarkerAnnotation node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveAnnotationBinding();
+		return true;
+	}
+
+	public boolean visit(MethodDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(NormalAnnotation node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveAnnotationBinding();
+		return true;
+	}
+
+	public boolean visit(PackageDeclaration node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(SingleMemberAnnotation node) {
+		if (found(node, node) && this.resolveBinding)
+			this.foundBinding = node.resolveAnnotationBinding();
+		return true;
+	}
+
+	public boolean visit(TypeDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(TypeParameter node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+
+	public boolean visit(VariableDeclarationFragment node) {
+		if (found(node, node.getName()) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
new file mode 100644
index 0000000..b5fe2ab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
@@ -0,0 +1,2576 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.core.util.IBytecodeVisitor;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IConstantPoolEntry2;
+import org.eclipse.jdt.core.util.ILocalVariableAttribute;
+import org.eclipse.jdt.core.util.ILocalVariableTableEntry;
+import org.eclipse.jdt.core.util.OpcodeStringValues;
+import org.eclipse.jdt.core.util.IOpcodeMnemonics;
+
+/**
+ * Default implementation of ByteCodeVisitor
+ */
+public class DefaultBytecodeVisitor implements IBytecodeVisitor {
+	private static final String EMPTY_CLASS_NAME = "\"\""; //$NON-NLS-1$
+	private static final String EMPTY_LOCAL_NAME = ""; //$NON-NLS-1$
+	private static final int T_BOOLEAN = 4;
+	private static final int T_CHAR = 5;
+	private static final int T_FLOAT = 6;
+	private static final int T_DOUBLE = 7;
+	private static final int T_BYTE = 8;
+	private static final int T_SHORT = 9;
+	private static final int T_INT = 10;
+	private static final int T_LONG = 11;
+
+	private StringBuffer buffer;
+	private String lineSeparator;
+	private int tabNumber;
+	private int digitNumberForPC;
+	private ILocalVariableTableEntry[] localVariableTableEntries;
+	private int localVariableAttributeLength;
+	private int mode;
+	private char[][] parameterNames;
+	private boolean isStatic;
+	private int[] argumentSizes;
+
+	public DefaultBytecodeVisitor(ICodeAttribute codeAttribute, char[][] parameterNames, char[] methodDescriptor, boolean isStatic, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		ILocalVariableAttribute localVariableAttribute = codeAttribute.getLocalVariableAttribute();
+		this.localVariableAttributeLength = localVariableAttribute == null ? 0 : localVariableAttribute.getLocalVariableTableLength();
+		if (this.localVariableAttributeLength != 0) {
+			this.localVariableTableEntries = localVariableAttribute.getLocalVariableTable();
+		} else {
+			this.localVariableTableEntries = null;
+		}
+		this.buffer = buffer;
+		this.lineSeparator = lineSeparator;
+		this.tabNumber = tabNumber + 1;
+		long codeLength = codeAttribute.getCodeLength();
+		this.digitNumberForPC = Long.toString(codeLength).length();
+		this.mode = mode;
+		this.parameterNames = parameterNames;
+		this.isStatic = isStatic;
+		// compute argument sizes
+		if (parameterNames != null) {
+			char[][] parameterTypes = Signature.getParameterTypes(methodDescriptor);
+			int length = parameterTypes.length;
+			this.argumentSizes = new int[length];
+			for (int i = 0; i < length; i++) {
+				char[] parameterType = parameterTypes[i];
+				this.argumentSizes[i] = parameterType.length == 1 && (parameterType[0] == 'D' || parameterType[0] == 'J') ? 2 : 1;
+			}
+		}
+	}
+	/**
+	 * @see IBytecodeVisitor#_aaload(int)
+	 */
+	public void _aaload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.AALOAD]);
+		writeNewLine();
+	}
+	private void dumpPcNumber(int pc) {
+		writeTabs();
+		int digitForPC = 1;
+		if (pc != 0) {
+			digitForPC = Integer.toString(pc).length();
+		}
+		for (int i = 0, max = this.digitNumberForPC - digitForPC; i < max; i++) {
+			this.buffer.append(' ');
+		}
+		this.buffer.append(pc);
+		this.buffer.append(Messages.disassembler_indentation);
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aastore(int)
+	 */
+	public void _aastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.AASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aconst_null(int)
+	 */
+	public void _aconst_null(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ACONST_NULL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_0(int)
+	 */
+	public void _aload_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load,
+			new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_0],
+				getLocalVariableName(pc, 0)
+			}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_1(int)
+	 */
+	public void _aload_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_2(int)
+	 */
+	public void _aload_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload_3(int)
+	 */
+	public void _aload_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_aload(int, int)
+	 */
+	public void _aload(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_anewarray(int, int, IConstantPoolEntry)
+	 */
+	public void _anewarray(int pc, int index, IConstantPoolEntry constantClass) {
+		dumpPcNumber(pc);
+		this.buffer
+			.append(Messages.bind(Messages.classformat_anewarray, new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ANEWARRAY],
+				Integer.toString(index),
+				returnConstantClassName(constantClass)
+			}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_areturn(int)
+	 */
+	public void _areturn(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ARETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_arraylength(int)
+	 */
+	public void _arraylength(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ARRAYLENGTH]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_0(int)
+	 */
+	public void _astore_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_1(int)
+	 */
+	public void _astore_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+	private String getLocalVariableName(int pc, int index) {
+		return getLocalVariableName(pc, index, false);
+	}
+
+	private String getLocalVariableName(int pc, int index, boolean showIndex) {
+		int nextPC = pc + 1;
+		switch(index) {
+			case 0 :
+			case 1 :
+			case 2 :
+			case 3 :
+				break;
+			default :
+				nextPC = index <= 255 ? pc + 2 : pc + 3;
+		}
+
+		for (int i = 0, max = this.localVariableAttributeLength; i < max; i++) {
+			final ILocalVariableTableEntry entry = this.localVariableTableEntries[i];
+			final int startPC = entry.getStartPC();
+			if (entry.getIndex() == index && (startPC <= nextPC) && ((startPC + entry.getLength()) > nextPC)) {
+				final StringBuffer stringBuffer = new StringBuffer();
+				if (showIndex) {
+					stringBuffer.append(' ').append(index);
+				}
+				stringBuffer.append(' ').append('[').append(entry.getName()).append(']');
+				return String.valueOf(stringBuffer);
+			}
+		}
+		if (this.parameterNames != null) {
+			if (index == 0) {
+				if (!this.isStatic) {
+					final StringBuffer stringBuffer = new StringBuffer();
+					stringBuffer.append(' ').append('[').append("this").append(']'); //$NON-NLS-1$
+					return String.valueOf(stringBuffer);
+				}
+			}
+			int indexInParameterNames = index;
+			if (index != 0) {
+				int resolvedPosition = 0;
+				if (!this.isStatic) {
+					resolvedPosition = 1;
+				}
+				int i = 0;
+				loop: for (int max = this.argumentSizes.length; i < max; i++) {
+					if (index == resolvedPosition) {
+						break loop;
+					}
+					resolvedPosition += this.argumentSizes[i];
+				}
+				indexInParameterNames = i;
+			}
+			if (indexInParameterNames < this.parameterNames.length
+					&& this.parameterNames[indexInParameterNames] != null) {
+				final StringBuffer stringBuffer = new StringBuffer();
+				if (showIndex) {
+					stringBuffer.append(' ').append(index);
+				}
+				stringBuffer.append(' ').append('[').append(this.parameterNames[indexInParameterNames]).append(']');
+				return String.valueOf(stringBuffer);
+			}
+		}
+		if (showIndex) {
+			final StringBuffer stringBuffer = new StringBuffer();
+			stringBuffer.append(' ').append(index);
+			return String.valueOf(stringBuffer);
+		}
+		return EMPTY_LOCAL_NAME;
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_2(int)
+	 */
+	public void _astore_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore_3(int)
+	 */
+	public void _astore_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_astore(int, int)
+	 */
+	public void _astore(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_athrow(int)
+	 */
+	public void _athrow(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ATHROW]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_baload(int)
+	 */
+	public void _baload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.BALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_bastore(int)
+	 */
+	public void _bastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.BASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_bipush(int, byte)
+	 */
+	public void _bipush(int pc, byte _byte) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.BIPUSH])
+			.append(Messages.disassembler_space)
+			.append(_byte);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_caload(int)
+	 */
+	public void _caload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_castore(int)
+	 */
+	public void _castore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_checkcast(int, int, IConstantPoolEntry)
+	 */
+	public void _checkcast(int pc, int index, IConstantPoolEntry constantClass) {
+		dumpPcNumber(pc);
+		this.buffer
+			.append(Messages.bind(Messages.classformat_checkcast, new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CHECKCAST],
+				Integer.toString(index),
+				returnConstantClassName(constantClass)
+			}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2f(int)
+	 */
+	public void _d2f(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.D2F]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2i(int)
+	 */
+	public void _d2i(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.D2I]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_d2l(int)
+	 */
+	public void _d2l(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.D2L]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dadd(int)
+	 */
+	public void _dadd(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DADD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_daload(int)
+	 */
+	public void _daload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dastore(int)
+	 */
+	public void _dastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dcmpg(int)
+	 */
+	public void _dcmpg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DCMPG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dcmpl(int)
+	 */
+	public void _dcmpl(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DCMPL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dconst_0(int)
+	 */
+	public void _dconst_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DCONST_0]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dconst_1(int)
+	 */
+	public void _dconst_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DCONST_1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ddiv(int)
+	 */
+	public void _ddiv(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DDIV]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_0(int)
+	 */
+	public void _dload_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load,new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_1(int)
+	 */
+	public void _dload_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_2(int)
+	 */
+	public void _dload_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload_3(int)
+	 */
+	public void _dload_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dload(int, int)
+	 */
+	public void _dload(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dmul(int)
+	 */
+	public void _dmul(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DMUL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dneg(int)
+	 */
+	public void _dneg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DNEG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_drem(int)
+	 */
+	public void _drem(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DREM]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dreturn(int)
+	 */
+	public void _dreturn(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DRETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_0(int)
+	 */
+	public void _dstore_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_1(int)
+	 */
+	public void _dstore_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_2(int)
+	 */
+	public void _dstore_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore_3(int)
+	 */
+	public void _dstore_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dstore(int,int)
+	 */
+	public void _dstore(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dsub(int)
+	 */
+	public void _dsub(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSUB]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup_x1(int)
+	 */
+	public void _dup_x1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP_X1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup_x2(int)
+	 */
+	public void _dup_x2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP_X2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup(int)
+	 */
+	public void _dup(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2_x1(int)
+	 */
+	public void _dup2_x1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP2_X1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2_x2(int)
+	 */
+	public void _dup2_x2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP2_X2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_dup2(int)
+	 */
+	public void _dup2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DUP2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2d(int)
+	 */
+	public void _f2d(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.F2D]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2i(int)
+	 */
+	public void _f2i(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.F2I]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_f2l(int)
+	 */
+	public void _f2l(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.F2L]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fadd(int)
+	 */
+	public void _fadd(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FADD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_faload(int)
+	 */
+	public void _faload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fastore(int)
+	 */
+	public void _fastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fcmpg(int)
+	 */
+	public void _fcmpg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FCMPG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fcmpl(int)
+	 */
+	public void _fcmpl(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FCMPL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_0(int)
+	 */
+	public void _fconst_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FCONST_0]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_1(int)
+	 */
+	public void _fconst_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FCONST_1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fconst_2(int)
+	 */
+	public void _fconst_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FCONST_2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fdiv(int)
+	 */
+	public void _fdiv(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FDIV]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_0(int)
+	 */
+	public void _fload_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_1(int)
+	 */
+	public void _fload_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_2(int)
+	 */
+	public void _fload_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload_3(int)
+	 */
+	public void _fload_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fload(int, int)
+	 */
+	public void _fload(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fmul(int)
+	 */
+	public void _fmul(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FMUL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fneg(int)
+	 */
+	public void _fneg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FNEG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_frem(int)
+	 */
+	public void _frem(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FREM]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_freturn(int)
+	 */
+	public void _freturn(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FRETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_0(int)
+	 */
+	public void _fstore_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store,new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_1(int)
+	 */
+	public void _fstore_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_2(int)
+	 */
+	public void _fstore_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore_3(int)
+	 */
+	public void _fstore_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fstore(int, int)
+	 */
+	public void _fstore(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_fsub(int)
+	 */
+	public void _fsub(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSUB]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_getfield(int, int, IConstantPoolEntry)
+	 */
+	public void _getfield(int pc, int index, IConstantPoolEntry constantFieldref) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_getfield, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETFIELD],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_getstatic(int, int, IConstantPoolEntry)
+	 */
+	public void _getstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_getstatic, new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETSTATIC],
+				Integer.toString(index),
+				returnDeclaringClassName(constantFieldref),
+				new String(constantFieldref.getFieldName()),
+				returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+			}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_goto_w(int, int)
+	 */
+	public void _goto_w(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GOTO_W])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_goto(int, int)
+	 */
+	public void _goto(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GOTO])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2b(int)
+	 */
+	public void _i2b(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2B]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2c(int)
+	 */
+	public void _i2c(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2C]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2d(int)
+	 */
+	public void _i2d(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2D]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2f(int)
+	 */
+	public void _i2f(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2F]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2l(int)
+	 */
+	public void _i2l(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2L]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_i2s(int)
+	 */
+	public void _i2s(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.I2S]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iadd(int)
+	 */
+	public void _iadd(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IADD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iaload(int)
+	 */
+	public void _iaload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iand(int)
+	 */
+	public void _iand(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IAND]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iastore(int)
+	 */
+	public void _iastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_acmpeq(int, int)
+	 */
+	public void _if_acmpeq(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ACMPEQ])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_acmpne(int, int)
+	 */
+	public void _if_acmpne(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ACMPNE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpeq(int, int)
+	 */
+	public void _if_icmpeq(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPEQ])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpge(int, int)
+	 */
+	public void _if_icmpge(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPGE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpgt(int, int)
+	 */
+	public void _if_icmpgt(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPGT])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmple(int, int)
+	 */
+	public void _if_icmple(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPLE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmplt(int, int)
+	 */
+	public void _if_icmplt(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPLT])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_if_icmpne(int, int)
+	 */
+	public void _if_icmpne(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPNE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_0(int)
+	 */
+	public void _iconst_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_0]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_1(int)
+	 */
+	public void _iconst_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_2(int)
+	 */
+	public void _iconst_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_3(int)
+	 */
+	public void _iconst_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_3]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_4(int)
+	 */
+	public void _iconst_4(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_4]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_5(int)
+	 */
+	public void _iconst_5(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_5]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iconst_m1(int)
+	 */
+	public void _iconst_m1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ICONST_M1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_idiv(int)
+	 */
+	public void _idiv(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IDIV]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifeq(int, int)
+	 */
+	public void _ifeq(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFEQ])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifge(int, int)
+	 */
+	public void _ifge(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFGE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifgt(int, int)
+	 */
+	public void _ifgt(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFGT])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifle(int, int)
+	 */
+	public void _ifle(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFLE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iflt(int, int)
+	 */
+	public void _iflt(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFLT])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifne(int, int)
+	 */
+	public void _ifne(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNE])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifnonnull(int, int)
+	 */
+	public void _ifnonnull(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNONNULL])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ifnull(int, int)
+	 */
+	public void _ifnull(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNULL])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iinc(int, int, int)
+	 */
+	public void _iinc(int pc, int index, int _const) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_iinc, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IINC],
+			Integer.toString(index),
+			Integer.toString(_const),
+			getLocalVariableName(pc, index, false)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_0(int)
+	 */
+	public void _iload_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_1(int)
+	 */
+	public void _iload_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_2(int)
+	 */
+	public void _iload_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload_3(int)
+	 */
+	public void _iload_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iload(int, int)
+	 */
+	public void _iload(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_imul(int)
+	 */
+	public void _imul(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IMUL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ineg(int)
+	 */
+	public void _ineg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INEG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_instanceof(int, int, IConstantPoolEntry)
+	 */
+	public void _instanceof(int pc, int index, IConstantPoolEntry constantClass) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_instanceof, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INSTANCEOF],
+			Integer.toString(index),
+			returnConstantClassName(constantClass)
+		}));
+		writeNewLine();
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)
+	 */
+	public void _invokedynamic(
+		int pc,
+		int index,
+		IConstantPoolEntry nameEntry,
+		IConstantPoolEntry descriptorEntry) {
+
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_invokedynamic, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEDYNAMIC],
+			Integer.toString(index),
+			Util.toString(
+				null,
+				nameEntry.getUtf8Value(),
+				descriptorEntry.getUtf8Value(),
+				true,
+				isCompact())
+		}));
+		writeNewLine();
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry)
+	 */
+	public void _invokedynamic(
+		int pc,
+		int index,
+		IConstantPoolEntry invokeDynamicEntry) {
+
+		dumpPcNumber(pc);
+		IConstantPoolEntry2 entry = (IConstantPoolEntry2) invokeDynamicEntry;
+		this.buffer.append(Messages.bind(Messages.classformat_invokedynamic,
+			new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEDYNAMIC],
+				Integer.toString(index),
+				Integer.toString(entry.getBootstrapMethodAttributeIndex()),
+				Util.toString(
+					null,
+					entry.getMethodName(),
+					entry.getMethodDescriptor(),
+					true,
+					isCompact())
+			}));
+		writeNewLine();
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokeinterface(int, int, byte, IConstantPoolEntry)
+	 */
+	public void _invokeinterface(
+		int pc,
+		int index,
+		byte nargs,
+		IConstantPoolEntry constantInterfaceMethodref) {
+
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_invokeinterface, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
+			Integer.toString(index),
+			Integer.toString(nargs),
+			Util.toString(
+				constantInterfaceMethodref.getClassName(),
+				constantInterfaceMethodref.getMethodName(),
+				constantInterfaceMethodref.getMethodDescriptor(),
+				true,
+				isCompact())
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_invokespecial(int, int, IConstantPoolEntry)
+	 */
+	public void _invokespecial(int pc, int index, IConstantPoolEntry constantMethodref) {
+		dumpPcNumber(pc);
+		final String signature = returnMethodSignature(constantMethodref);
+		this.buffer.append(Messages.bind(Messages.classformat_invokespecial, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
+			Integer.toString(index),
+			signature
+		}));
+		writeNewLine();
+	}
+	/**
+	 * @see IBytecodeVisitor#_invokestatic(int, int, IConstantPoolEntry)
+	 */
+	public void _invokestatic(int pc, int index, IConstantPoolEntry constantMethodref) {
+		dumpPcNumber(pc);
+		final String signature = returnMethodSignature(constantMethodref);
+		this.buffer.append(Messages.bind(Messages.classformat_invokestatic, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
+			Integer.toString(index),
+			signature
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_invokevirtual(int, int, IConstantPoolEntry)
+	 */
+	public void _invokevirtual(int pc, int index, IConstantPoolEntry constantMethodref) {
+		dumpPcNumber(pc);
+		final String signature = returnMethodSignature(constantMethodref);
+		this.buffer.append(Messages.bind(Messages.classformat_invokevirtual,new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
+			Integer.toString(index),
+			signature
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ior(int)
+	 */
+	public void _ior(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IOR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_irem(int)
+	 */
+	public void _irem(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IREM]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ireturn(int)
+	 */
+	public void _ireturn(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IRETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ishl(int)
+	 */
+	public void _ishl(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISHL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ishr(int)
+	 */
+	public void _ishr(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISHR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_0(int)
+	 */
+	public void _istore_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_1(int)
+	 */
+	public void _istore_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_2(int)
+	 */
+	public void _istore_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore_3(int)
+	 */
+	public void _istore_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_istore(int, int)
+	 */
+	public void _istore(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_isub(int)
+	 */
+	public void _isub(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISUB]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_iushr(int)
+	 */
+	public void _iushr(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IUSHR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ixor(int)
+	 */
+	public void _ixor(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IXOR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_jsr_w(int, int)
+	 */
+	public void _jsr_w(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.JSR_W])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_jsr(int, int)
+	 */
+	public void _jsr(int pc, int branchOffset) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.JSR])
+			.append(Messages.disassembler_space)
+			.append(branchOffset + pc);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2d(int)
+	 */
+	public void _l2d(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.L2D]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2f(int)
+	 */
+	public void _l2f(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.L2F]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_l2i(int)
+	 */
+	public void _l2i(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.L2I]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ladd(int)
+	 */
+	public void _ladd(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LADD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_laload(int)
+	 */
+	public void _laload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_land(int)
+	 */
+	public void _land(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LAND]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lastore(int)
+	 */
+	public void _lastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lcmp(int)
+	 */
+	public void _lcmp(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LCMP]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lconst_0(int)
+	 */
+	public void _lconst_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LCONST_0]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lconst_1(int)
+	 */
+	public void _lconst_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LCONST_1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc_w(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		dumpPcNumber(pc);
+		switch (constantPoolEntry.getKind()) {
+			case IConstantPoolConstant.CONSTANT_Float :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_float, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					Float.toString(constantPoolEntry.getFloatValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_Integer :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					Integer.toString(constantPoolEntry.getIntegerValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_String :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_string, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					Disassembler.escapeString(constantPoolEntry.getStringValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_Class :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_class, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					returnConstantClassName(constantPoolEntry)
+				}));
+		}
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		dumpPcNumber(pc);
+		switch (constantPoolEntry.getKind()) {
+			case IConstantPoolConstant.CONSTANT_Float :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_float, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					Float.toString(constantPoolEntry.getFloatValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_Integer :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					Integer.toString(constantPoolEntry.getIntegerValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_String :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_string, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					Disassembler.escapeString(constantPoolEntry.getStringValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_Class :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc_w_class, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					returnConstantClassName(constantPoolEntry)
+				}));
+		}
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldc2_w(int, int, IConstantPoolEntry)
+	 */
+	public void _ldc2_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
+		dumpPcNumber(pc);
+		switch (constantPoolEntry.getKind()) {
+			case IConstantPoolConstant.CONSTANT_Long :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc2_w_long, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
+					Integer.toString(index),
+					Long.toString(constantPoolEntry.getLongValue())
+				}));
+				break;
+			case IConstantPoolConstant.CONSTANT_Double :
+				this.buffer.append(Messages.bind(Messages.classformat_ldc2_w_double, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
+					Integer.toString(index),
+					Double.toString(constantPoolEntry.getDoubleValue())
+				}));
+		}
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ldiv(int)
+	 */
+	public void _ldiv(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDIV]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_0(int)
+	 */
+	public void _lload_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_1(int)
+	 */
+	public void _lload_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_2(int)
+	 */
+	public void _lload_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload_3(int)
+	 */
+	public void _lload_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lload(int, int)
+	 */
+	public void _lload(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_load, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lmul(int)
+	 */
+	public void _lmul(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LMUL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lneg(int)
+	 */
+	public void _lneg(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LNEG]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lookupswitch(int, int, int, int[][])
+	 */
+	public void _lookupswitch(int pc, int defaultoffset, int npairs, int[][] offset_pairs) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LOOKUPSWITCH])
+			.append(" default: ") //$NON-NLS-1$
+			.append(defaultoffset + pc);
+		writeNewLine();
+		for (int i = 0; i < npairs; i++) {
+			writeExtraTabs(3);
+			this.buffer
+				.append("case ") //$NON-NLS-1$
+				.append(offset_pairs[i][0])
+				.append(": ") //$NON-NLS-1$
+				.append(offset_pairs[i][1] + pc);
+			writeNewLine();
+		}
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lor(int)
+	 */
+	public void _lor(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LOR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lrem(int)
+	 */
+	public void _lrem(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LREM]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lreturn(int)
+	 */
+	public void _lreturn(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LRETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lshl(int)
+	 */
+	public void _lshl(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSHL]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lshr(int)
+	 */
+	public void _lshr(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSHR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_0(int)
+	 */
+	public void _lstore_0(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_0],
+			getLocalVariableName(pc, 0)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_1(int)
+	 */
+	public void _lstore_1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_1],
+			getLocalVariableName(pc, 1)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_2(int)
+	 */
+	public void _lstore_2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_2],
+			getLocalVariableName(pc, 2)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore_3(int)
+	 */
+	public void _lstore_3(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_3],
+			getLocalVariableName(pc, 3)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lstore(int, int)
+	 */
+	public void _lstore(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_store, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE],
+			getLocalVariableName(pc, index, true)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lsub(int)
+	 */
+	public void _lsub(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSUB]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lushr(int)
+	 */
+	public void _lushr(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LUSHR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_lxor(int)
+	 */
+	public void _lxor(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LXOR]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_monitorenter(int)
+	 */
+	public void _monitorenter(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MONITORENTER]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_monitorexit(int)
+	 */
+	public void _monitorexit(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MONITOREXIT]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_multianewarray(int, int, int, IConstantPoolEntry)
+	 */
+	public void _multianewarray(
+		int pc,
+		int index,
+		int dimensions,
+		IConstantPoolEntry constantClass) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_multianewarray, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MULTIANEWARRAY],
+			Integer.toString(index),
+			returnConstantClassName(constantClass)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_new(int, int, IConstantPoolEntry)
+	 */
+	public void _new(int pc, int index, IConstantPoolEntry constantClass) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_new, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEW],
+			Integer.toString(index),
+			returnConstantClassName(constantClass)
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_newarray(int, int)
+	 */
+	public void _newarray(int pc, int atype) {
+		dumpPcNumber(pc);
+		switch(atype) {
+			case T_BOOLEAN :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_boolean, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_CHAR :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_char, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_FLOAT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_float, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_DOUBLE :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_double, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_BYTE :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_byte, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_SHORT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_short, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_INT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_int, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+				break;
+			case T_LONG :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_long, new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				}));
+		}
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_nop(int)
+	 */
+	public void _nop(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NOP]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_pop(int)
+	 */
+	public void _pop(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.POP]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_pop2(int)
+	 */
+	public void _pop2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.POP2]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_putfield(int, int, IConstantPoolEntry)
+	 */
+	public void _putfield(int pc, int index, IConstantPoolEntry constantFieldref) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_putfield, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTFIELD],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_putstatic(int, int, IConstantPoolEntry)
+	 */
+	public void _putstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
+		dumpPcNumber(pc);
+		this.buffer.append(Messages.bind(Messages.classformat_putstatic, new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTSTATIC],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+		}));
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_ret(int, int)
+	 */
+	public void _ret(int pc, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.RET])
+			.append(Messages.disassembler_space)
+			.append(index);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_return(int)
+	 */
+	public void _return(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.RETURN]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_saload(int)
+	 */
+	public void _saload(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.SALOAD]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_sastore(int)
+	 */
+	public void _sastore(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.SASTORE]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_sipush(int, short)
+	 */
+	public void _sipush(int pc, short value) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.SIPUSH])
+			.append(Messages.disassembler_space)
+			.append(value);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_swap(int)
+	 */
+	public void _swap(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.SWAP]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_tableswitch(int, int, int, int, int[])
+	 */
+	public void _tableswitch(
+		int pc,
+		int defaultoffset,
+		int low,
+		int high,
+		int[] jump_offsets) {
+
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.TABLESWITCH])
+			.append(" default: ") //$NON-NLS-1$
+			.append(defaultoffset + pc);
+		writeNewLine();
+		for (int i = low; i < high + 1; i++) {
+			writeExtraTabs(3);
+			this.buffer
+				.append("case ") //$NON-NLS-1$
+				.append(i)
+				.append(": ") //$NON-NLS-1$
+				.append(jump_offsets[i - low] + pc);
+			writeNewLine();
+		}
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_wide(int, int, int)
+	 */
+	public void _wide(int pc, int iincopcode, int index, int _const) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.WIDE]);
+		writeNewLine();
+		_iinc(pc + 1, index, _const);
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_wide(int, int, int)
+	 */
+	public void _wide(int pc, int opcode, int index) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.WIDE]);
+		writeNewLine();
+		switch(opcode) {
+			case IOpcodeMnemonics.ILOAD :
+				_iload(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.FLOAD :
+				_fload(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.ALOAD :
+				_aload(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.LLOAD :
+				_lload(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.DLOAD :
+				_dload(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.ISTORE :
+				_istore(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.FSTORE :
+				_fstore(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.ASTORE :
+				_astore(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.LSTORE :
+				_lstore(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.DSTORE :
+				_dstore(pc + 1, index);
+				break;
+			case IOpcodeMnemonics.RET :
+				_ret(pc + 1, index);
+		}
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_breakpoint(int)
+	 */
+	public void _breakpoint(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.BREAKPOINT]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_impdep1(int)
+	 */
+	public void _impdep1(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IMPDEP1]);
+		writeNewLine();
+	}
+
+	/**
+	 * @see IBytecodeVisitor#_impdep2(int)
+	 */
+	public void _impdep2(int pc) {
+		dumpPcNumber(pc);
+		this.buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IMPDEP2]);
+		writeNewLine();
+	}
+
+	private boolean isCompact() {
+		return (this.mode & ClassFileBytesDisassembler.COMPACT) != 0;
+	}
+
+	private String returnConstantClassName(IConstantPoolEntry constantClass) {
+		char[] className = constantClass.getClassInfoName();
+		if (className.length == 0) {
+			return EMPTY_CLASS_NAME;
+		}
+		switch(className[0]) {
+			case '[' :
+				StringBuffer classNameBuffer = new StringBuffer();
+				Util.appendTypeSignature(className, 0, classNameBuffer, isCompact());
+				return classNameBuffer.toString();
+			default:
+				return returnClassName(className);
+		}
+	}
+	private String returnClassName(char[] classInfoName) {
+		if (classInfoName.length == 0) {
+			return EMPTY_CLASS_NAME;
+		} else if (isCompact()) {
+			int lastIndexOfSlash = CharOperation.lastIndexOf('/', classInfoName);
+			if (lastIndexOfSlash != -1) {
+				return new String(classInfoName, lastIndexOfSlash + 1, classInfoName.length - lastIndexOfSlash - 1);
+			}
+		}
+		CharOperation.replace(classInfoName, '/', '.');
+		return new String(classInfoName);
+	}
+
+	private String returnDeclaringClassName(IConstantPoolEntry constantRef) {
+		final char[] className = constantRef.getClassName();
+		return returnClassName(className);
+	}
+
+	private String returnMethodSignature(IConstantPoolEntry constantMethodref) {
+		final char[] methodDescriptor = constantMethodref.getMethodDescriptor();
+		CharOperation.replace(methodDescriptor, '$', '#');
+		final char[] signature = Util.toString(
+				constantMethodref.getClassName(),
+				constantMethodref.getMethodName(),
+				methodDescriptor,
+				true,
+				isCompact()).toCharArray();
+		CharOperation.replace(signature, '#', '$');
+		return String.valueOf(signature);
+	}
+
+	private void writeNewLine() {
+		this.buffer.append(this.lineSeparator);
+	}
+
+	private void writeTabs() {
+		for (int i = 0, max = this.tabNumber; i < max; i++) {
+			this.buffer.append(Messages.disassembler_indentation);
+		}
+	}
+
+	private void writeExtraTabs(int extraTabs) {
+		for (int i = 0, max = this.tabNumber + extraTabs; i < max; i++) {
+			this.buffer.append(Messages.disassembler_indentation);
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultStackMapFrame.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultStackMapFrame.java
new file mode 100644
index 0000000..9e67d2e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultStackMapFrame.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IStackMapFrame;
+import org.eclipse.jdt.core.util.IVerificationTypeInfo;
+
+/**
+ * Default implementation of IStackMapFrame
+ */
+public class DefaultStackMapFrame extends ClassFileStruct implements IStackMapFrame {
+	private static final IVerificationTypeInfo[] EMPTY_LOCALS_OR_STACK_ITEMS = new IVerificationTypeInfo[0];
+
+	private int readOffset;
+	private int numberOfLocals;
+	private int numberOfStackItems;
+	private IVerificationTypeInfo[] locals;
+	private IVerificationTypeInfo[] stackItems;
+	private int offsetDelta;
+
+	/**
+	 * Constructor for StackMapFrame.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public DefaultStackMapFrame(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		// FULL_FRAME
+		this.offsetDelta = u2At(classFileBytes, 0, offset);
+		int tempLocals = u2At(classFileBytes, 2, offset);
+		this.numberOfLocals = tempLocals;
+		this.readOffset = 4;
+		if (tempLocals != 0) {
+			this.locals = new IVerificationTypeInfo[tempLocals];
+			for (int i = 0; i < tempLocals; i++) {
+				VerificationInfo verificationInfo = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+				this.locals[i] = verificationInfo;
+				this.readOffset += verificationInfo.sizeInBytes();
+			}
+		} else {
+			this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+		}
+		int tempStackItems = u2At(classFileBytes, this.readOffset, offset);
+		this.readOffset += 2;
+		this.numberOfStackItems = tempStackItems;
+		if (tempStackItems != 0) {
+			this.stackItems = new IVerificationTypeInfo[tempStackItems];
+			for (int i = 0; i < tempStackItems; i++) {
+				VerificationInfo verificationInfo = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+				this.stackItems[i] = verificationInfo;
+				this.readOffset += verificationInfo.sizeInBytes();
+			}
+		} else {
+			this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+		}
+	}
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+	public int getFrameType() {
+		return 255; // full_frame
+	}
+	public IVerificationTypeInfo[] getLocals() {
+		return this.locals;
+	}
+	public int getNumberOfLocals() {
+		return this.numberOfLocals;
+	}
+	public int getNumberOfStackItems() {
+		return this.numberOfStackItems;
+	}
+	public int getOffsetDelta() {
+		return this.offsetDelta;
+	}
+	public IVerificationTypeInfo[] getStackItems() {
+		return this.stackItems;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
new file mode 100644
index 0000000..c7960b4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -0,0 +1,2558 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.*;
+import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+
+/**
+ * Disassembler of .class files. It generates an output in the Writer that looks close to
+ * the javap output.
+ */
+public class Disassembler extends ClassFileBytesDisassembler {
+
+	private static final char[] ANY_EXCEPTION = Messages.classfileformat_anyexceptionhandler.toCharArray();
+	private static final String VERSION_UNKNOWN = Messages.classfileformat_versionUnknown;
+
+	private boolean appendModifier(StringBuffer buffer, int accessFlags, int modifierConstant, String modifier, boolean firstModifier) {
+		if ((accessFlags & modifierConstant) != 0) {
+			if (!firstModifier) {
+				buffer.append(Messages.disassembler_space);
+			}
+			if (firstModifier) {
+				firstModifier = false;
+			}
+			buffer.append(modifier);
+		}
+		return firstModifier;
+	}
+
+	private void decodeModifiers(StringBuffer buffer, int accessFlags, int[] checkBits) {
+		decodeModifiers(buffer, accessFlags, false, false, checkBits);
+	}
+
+	private void decodeModifiers(StringBuffer buffer, int accessFlags, boolean printDefault, boolean asBridge, int[] checkBits) {
+		if (checkBits == null) return;
+		boolean firstModifier = true;
+		for (int i = 0, max = checkBits.length; i < max; i++) {
+			switch(checkBits[i]) {
+				case IModifierConstants.ACC_PUBLIC :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_PROTECTED :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_PRIVATE :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_ABSTRACT :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_STATIC :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_FINAL :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_SYNCHRONIZED :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_SYNCHRONIZED, "synchronized", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_NATIVE :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_NATIVE, "native", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_STRICT :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STRICT, "strictfp", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_TRANSIENT :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_TRANSIENT, "transient", firstModifier); //$NON-NLS-1$
+					break;
+				case IModifierConstants.ACC_VOLATILE :
+				// case IModifierConstants.ACC_BRIDGE :
+					if (asBridge) {
+						firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_BRIDGE, "bridge", firstModifier); //$NON-NLS-1$
+					} else {
+						firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_VOLATILE, "volatile", firstModifier); //$NON-NLS-1$
+					}
+					break;
+				case IModifierConstants.ACC_ENUM :
+					firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ENUM, "enum", firstModifier); //$NON-NLS-1$
+					break;
+			}
+		}
+		if (!firstModifier) {
+			if (!printDefault) buffer.append(Messages.disassembler_space);
+		} else if (printDefault) {
+			// no modifier: package default visibility
+			buffer.append("default"); //$NON-NLS-1$
+		}
+	}
+
+	private void decodeModifiersForField(StringBuffer buffer, int accessFlags) {
+		decodeModifiers(buffer, accessFlags, new int[] {
+				IModifierConstants.ACC_PUBLIC,
+				IModifierConstants.ACC_PROTECTED,
+				IModifierConstants.ACC_PRIVATE,
+				IModifierConstants.ACC_STATIC,
+				IModifierConstants.ACC_FINAL,
+				IModifierConstants.ACC_TRANSIENT,
+				IModifierConstants.ACC_VOLATILE,
+				IModifierConstants.ACC_ENUM
+		});
+	}
+
+	private void decodeModifiersForFieldForWorkingCopy(StringBuffer buffer, int accessFlags) {
+		decodeModifiers(buffer, accessFlags, new int[] {
+				IModifierConstants.ACC_PUBLIC,
+				IModifierConstants.ACC_PROTECTED,
+				IModifierConstants.ACC_PRIVATE,
+				IModifierConstants.ACC_STATIC,
+				IModifierConstants.ACC_FINAL,
+				IModifierConstants.ACC_TRANSIENT,
+				IModifierConstants.ACC_VOLATILE,
+		});
+	}
+
+	private final void decodeModifiersForInnerClasses(StringBuffer buffer, int accessFlags, boolean printDefault) {
+		decodeModifiers(buffer, accessFlags, printDefault, false, new int[] {
+				IModifierConstants.ACC_PUBLIC,
+				IModifierConstants.ACC_PROTECTED,
+				IModifierConstants.ACC_PRIVATE,
+				IModifierConstants.ACC_ABSTRACT,
+				IModifierConstants.ACC_STATIC,
+				IModifierConstants.ACC_FINAL,
+		});
+	}
+
+	private final void decodeModifiersForMethod(StringBuffer buffer, int accessFlags) {
+		decodeModifiers(buffer, accessFlags, false, true, new int[] {
+				IModifierConstants.ACC_PUBLIC,
+				IModifierConstants.ACC_PROTECTED,
+				IModifierConstants.ACC_PRIVATE,
+				IModifierConstants.ACC_ABSTRACT,
+				IModifierConstants.ACC_STATIC,
+				IModifierConstants.ACC_FINAL,
+				IModifierConstants.ACC_SYNCHRONIZED,
+				IModifierConstants.ACC_NATIVE,
+				IModifierConstants.ACC_STRICT,
+				IModifierConstants.ACC_BRIDGE,
+		});
+	}
+
+	private final void decodeModifiersForType(StringBuffer buffer, int accessFlags) {
+		decodeModifiers(buffer, accessFlags, new int[] {
+				IModifierConstants.ACC_PUBLIC,
+				IModifierConstants.ACC_ABSTRACT,
+				IModifierConstants.ACC_FINAL,
+		});
+	}
+	public static String escapeString(String s) {
+		return decodeStringValue(s);
+	}
+
+	static String decodeStringValue(char[] chars) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, max = chars.length; i < max; i++) {
+			char c = chars[i];
+			escapeChar(buffer, c);
+		}
+		return buffer.toString();
+	}
+
+	private static void escapeChar(StringBuffer buffer, char c) {
+		switch(c) {
+			case '\b' :
+				buffer.append("\\b"); //$NON-NLS-1$
+				break;
+			case '\t' :
+				buffer.append("\\t"); //$NON-NLS-1$
+				break;
+			case '\n' :
+				buffer.append("\\n"); //$NON-NLS-1$
+				break;
+			case '\f' :
+				buffer.append("\\f"); //$NON-NLS-1$
+				break;
+			case '\r' :
+				buffer.append("\\r"); //$NON-NLS-1$
+				break;
+			case '\0' :
+				buffer.append("\\0"); //$NON-NLS-1$
+				break;
+			case '\1' :
+				buffer.append("\\1"); //$NON-NLS-1$
+				break;
+			case '\2' :
+				buffer.append("\\2"); //$NON-NLS-1$
+				break;
+			case '\3' :
+				buffer.append("\\3"); //$NON-NLS-1$
+				break;
+			case '\4' :
+				buffer.append("\\4"); //$NON-NLS-1$
+				break;
+			case '\5' :
+				buffer.append("\\5"); //$NON-NLS-1$
+				break;
+			case '\6' :
+				buffer.append("\\6"); //$NON-NLS-1$
+				break;
+			case '\7' :
+				buffer.append("\\7"); //$NON-NLS-1$
+				break;
+			default:
+				buffer.append(c);
+		}
+	}
+
+	static String decodeStringValue(String s) {
+		return decodeStringValue(s.toCharArray());
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.util.ClassFileBytesDisassembler#disassemble(byte[], java.lang.String)
+	 */
+	public String disassemble(byte[] classFileBytes, String lineSeparator) throws ClassFormatException {
+		try {
+			return disassemble(new ClassFileReader(classFileBytes, IClassFileReader.ALL), lineSeparator, ClassFileBytesDisassembler.DEFAULT);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			throw new ClassFormatException(e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.util.ClassFileBytesDisassembler#disassemble(byte[], java.lang.String, int)
+	 */
+	public String disassemble(byte[] classFileBytes, String lineSeparator, int mode) throws ClassFormatException {
+		try {
+			return disassemble(new ClassFileReader(classFileBytes, IClassFileReader.ALL), lineSeparator, mode);
+		} catch (ArrayIndexOutOfBoundsException e) {
+			throw new ClassFormatException(e.getMessage(), e);
+		}
+	}
+
+	private void disassemble(IAnnotation annotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		final int typeIndex = annotation.getTypeIndex();
+		final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.');
+		buffer.append(
+			Messages.bind(Messages.disassembler_annotationentrystart, new String[] {
+				Integer.toString(typeIndex),
+				new String(returnClassName(Signature.toCharArray(typeName), '.', mode))
+			}));
+		final IAnnotationComponent[] components = annotation.getComponents();
+		for (int i = 0, max = components.length; i < max; i++) {
+			disassemble(components[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_annotationentryend);
+	}
+	
+	private void disassemble(IExtendedAnnotation extendedAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		final int typeIndex = extendedAnnotation.getTypeIndex();
+		final char[] typeName = CharOperation.replaceOnCopy(extendedAnnotation.getTypeName(), '/', '.');
+		buffer.append(
+			Messages.bind(Messages.disassembler_extendedannotationentrystart, new String[] {
+				Integer.toString(typeIndex),
+				new String(returnClassName(Signature.toCharArray(typeName), '.', mode))
+			}));
+		final IAnnotationComponent[] components = extendedAnnotation.getComponents();
+		for (int i = 0, max = components.length; i < max; i++) {
+			disassemble(components[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+		writeNewLine(buffer, lineSeparator, tabNumber + 2);
+		int targetType = extendedAnnotation.getTargetType();
+		buffer.append(
+				Messages.bind(Messages.disassembler_extendedannotation_targetType, new String[] {
+					Integer.toHexString(targetType),
+					getTargetType(targetType),
+				}));
+		switch(targetType) {
+			case IExtendedAnnotationConstants.METHOD_RECEIVER :
+			case IExtendedAnnotationConstants.METHOD_RETURN:
+			case IExtendedAnnotationConstants.FIELD :
+				break;
+			default:
+				writeNewLine(buffer, lineSeparator, tabNumber + 2);
+				disassembleTargetTypeContents(false, targetType, extendedAnnotation, buffer, lineSeparator, tabNumber, mode);
+		}
+		disassembleTypePathContents(targetType, extendedAnnotation, buffer, lineSeparator, tabNumber, mode);
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_extendedannotationentryend);
+	}
+
+	private void disassembleTypePathContents(int targetType, IExtendedAnnotation extendedAnnotation,StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		int[][] typepath = extendedAnnotation.getTypePath();
+		if (typepath.length != 0) {
+			writeNewLine(buffer, lineSeparator, tabNumber + 2);
+			buffer.append(
+				Messages.bind(Messages.disassembler_extendedannotation_typepath, new String[] {
+						toTypePathString(typepath),
+				}));
+		}
+	}
+	private void disassembleTargetTypeContents(boolean insideWildcard, int targetType, IExtendedAnnotation extendedAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		switch(targetType) {
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_type_parameter, new String[] {
+							Integer.toString(extendedAnnotation.getTypeParameterIndex()),
+						}));
+				break;
+			case IExtendedAnnotationConstants.CLASS_EXTENDS :
+				buffer.append(
+					Messages.bind(Messages.disassembler_extendedannotation_classextendsimplements, new String[] {
+						Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
+					}));
+				break;
+				
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_type_parameter_with_bound, new String[] {
+							Integer.toString(extendedAnnotation.getTypeParameterIndex()),
+							Integer.toString(extendedAnnotation.getTypeParameterBoundIndex()),
+						}));
+				break;				
+			case IExtendedAnnotationConstants.FIELD :
+			case IExtendedAnnotationConstants.METHOD_RETURN :
+			case IExtendedAnnotationConstants.METHOD_RECEIVER :
+				break;
+			case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_method_parameter, new String[] {
+							Integer.toString(extendedAnnotation.getParameterIndex()),
+						}));
+				break;
+			case IExtendedAnnotationConstants.THROWS :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_throws, new String[] {
+							Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
+						}));
+				break;
+
+			case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+			case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
+				buffer.append(Messages.disassembler_localvariabletargetheader);
+				writeNewLine(buffer, lineSeparator, tabNumber + 3);
+				int localVariableTableSize = extendedAnnotation.getLocalVariableRefenceInfoLength();
+				ILocalVariableReferenceInfo[] localVariableTable = extendedAnnotation.getLocalVariableTable();
+				for (int i = 0; i < localVariableTableSize; i++) {
+					if (i != 0) {
+						writeNewLine(buffer, lineSeparator, tabNumber + 3);
+					}
+					ILocalVariableReferenceInfo info = localVariableTable[i];
+					int index= info.getIndex();
+					int startPC = info.getStartPC();
+					int length  = info.getLength();
+					buffer.append(Messages.bind(Messages.classfileformat_localvariablereferenceinfoentry,
+						new String[] {
+							Integer.toString(startPC),
+							Integer.toString(startPC + length),
+							Integer.toString(index),
+						}));
+				}
+				break;
+			case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_exception_table_index, new String[] {
+							Integer.toString(extendedAnnotation.getExceptionTableIndex()),
+						}));
+				break;
+				
+			case IExtendedAnnotationConstants.INSTANCEOF :
+			case IExtendedAnnotationConstants.NEW :
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
+			case IExtendedAnnotationConstants.METHOD_REFERENCE :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
+							Integer.toString(extendedAnnotation.getOffset()),
+						}));
+				break;
+			case IExtendedAnnotationConstants.CAST :
+			case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_offset, new String[] {
+							Integer.toString(extendedAnnotation.getOffset()),
+						}));
+				writeNewLine(buffer, lineSeparator, tabNumber + 2);
+				buffer.append(
+						Messages.bind(Messages.disassembler_extendedannotation_type_argument, new String[] {
+							Integer.toString(extendedAnnotation.getAnnotationTypeIndex()),
+						}));
+				break;
+		}
+	}
+	private String getTargetType(int targetType) {
+		switch(targetType) {
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
+				return "CLASS_TYPE_PARAMETER"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
+				return "METHOD_TYPE_PARAMETER"; //$NON-NLS-1$
+
+			case IExtendedAnnotationConstants.CLASS_EXTENDS :
+				return "CLASS_EXTENDS"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
+				return "CLASS_TYPE_PARAMETER_BOUND"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+				return "METHOD_TYPE_PARAMETER_BOUND"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.FIELD :
+				return "FIELD"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_RETURN :
+				return "METHOD_RETURN"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_RECEIVER :
+				return "METHOD_RECEIVER"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
+				return "METHOD_FORMAL_PARAMETER"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.THROWS :
+				return "THROWS"; //$NON-NLS-1$
+
+			case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+				return "LOCAL_VARIABLE"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
+				return "RESOURCE_VARIABLE"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
+				return "EXCEPTION_PARAMETER"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.INSTANCEOF :
+				return "INSTANCEOF"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.NEW :
+				return "NEW"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
+				return "CONSTRUCTOR_REFERENCE"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_REFERENCE :
+				return "METHOD_REFERENCE"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.CAST :
+				return "CAST"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+				return "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+				return "METHOD_INVOCATION_TYPE_ARGUMENT"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+				return "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT"; //$NON-NLS-1$
+			case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+				return "METHOD_REFERENCE_TYPE_ARGUMENT"; //$NON-NLS-1$
+			default:
+				return "UNKNOWN"; //$NON-NLS-1$
+		}
+	}
+
+
+	private void disassemble(IAnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(
+			Messages.bind(Messages.disassembler_annotationcomponent,
+				new String[] {
+					Integer.toString(annotationComponent.getComponentNameIndex()),
+					new String(annotationComponent.getComponentName())
+				}));
+		disassemble(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1, mode);
+	}
+
+	private void disassemble(IAnnotationComponentValue annotationComponentValue, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		switch(annotationComponentValue.getTag()) {
+			case IAnnotationComponentValue.BYTE_TAG:
+			case IAnnotationComponentValue.CHAR_TAG:
+			case IAnnotationComponentValue.DOUBLE_TAG:
+			case IAnnotationComponentValue.FLOAT_TAG:
+			case IAnnotationComponentValue.INTEGER_TAG:
+			case IAnnotationComponentValue.LONG_TAG:
+			case IAnnotationComponentValue.SHORT_TAG:
+			case IAnnotationComponentValue.BOOLEAN_TAG:
+			case IAnnotationComponentValue.STRING_TAG:
+				IConstantPoolEntry constantPoolEntry = annotationComponentValue.getConstantValue();
+				String value = null;
+				switch(constantPoolEntry.getKind()) {
+					case IConstantPoolConstant.CONSTANT_Long :
+						value = constantPoolEntry.getLongValue() + "L"; //$NON-NLS-1$
+						break;
+					case IConstantPoolConstant.CONSTANT_Float :
+						value = constantPoolEntry.getFloatValue() + "f"; //$NON-NLS-1$
+						break;
+					case IConstantPoolConstant.CONSTANT_Double :
+						value = Double.toString(constantPoolEntry.getDoubleValue());
+						break;
+					case IConstantPoolConstant.CONSTANT_Integer:
+						StringBuffer temp = new StringBuffer();
+						switch(annotationComponentValue.getTag()) {
+							case IAnnotationComponentValue.CHAR_TAG :
+								temp.append('\'');
+								escapeChar(temp, (char) constantPoolEntry.getIntegerValue());
+								temp.append('\'');
+								break;
+							case IAnnotationComponentValue.BOOLEAN_TAG :
+								temp.append(constantPoolEntry.getIntegerValue() == 1 ? "true" : "false");//$NON-NLS-1$//$NON-NLS-2$
+								break;
+							case IAnnotationComponentValue.BYTE_TAG :
+								temp.append("(byte) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+								break;
+							case IAnnotationComponentValue.SHORT_TAG :
+								temp.append("(short) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+								break;
+							case IAnnotationComponentValue.INTEGER_TAG :
+								temp.append("(int) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+						}
+						value = String.valueOf(temp);
+						break;
+					case IConstantPoolConstant.CONSTANT_Utf8:
+						value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\"";//$NON-NLS-1$//$NON-NLS-2$
+				}
+				buffer.append(Messages.bind(Messages.disassembler_annotationdefaultvalue, value));
+				break;
+			case IAnnotationComponentValue.ENUM_TAG:
+				final int enumConstantTypeNameIndex = annotationComponentValue.getEnumConstantTypeNameIndex();
+				final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.');
+				final int enumConstantNameIndex = annotationComponentValue.getEnumConstantNameIndex();
+				final char[] constantName = annotationComponentValue.getEnumConstantName();
+				buffer.append(Messages.bind(Messages.disassembler_annotationenumvalue,
+					new String[] {
+						Integer.toString(enumConstantTypeNameIndex),
+						Integer.toString(enumConstantNameIndex),
+						new String(returnClassName(Signature.toCharArray(typeName), '.', mode)),
+						new String(constantName)
+					}));
+				break;
+			case IAnnotationComponentValue.CLASS_TAG:
+				final int classIndex = annotationComponentValue.getClassInfoIndex();
+				constantPoolEntry = annotationComponentValue.getClassInfo();
+				final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.');
+				buffer.append(Messages.bind(Messages.disassembler_annotationclassvalue,
+					new String[] {
+						Integer.toString(classIndex),
+						new String(returnClassName(Signature.toCharArray(className), '.', mode))
+					}));
+				break;
+			case IAnnotationComponentValue.ANNOTATION_TAG:
+				buffer.append(Messages.disassembler_annotationannotationvalue);
+				IAnnotation annotation = annotationComponentValue.getAnnotationValue();
+				disassemble(annotation, buffer, lineSeparator, tabNumber + 1, mode);
+				break;
+			case IAnnotationComponentValue.ARRAY_TAG:
+				buffer.append(Messages.disassembler_annotationarrayvaluestart);
+				final IAnnotationComponentValue[] annotationComponentValues = annotationComponentValue.getAnnotationComponentValues();
+				for (int i = 0, max = annotationComponentValues.length; i < max; i++) {
+					writeNewLine(buffer, lineSeparator, tabNumber + 1);
+					disassemble(annotationComponentValues[i], buffer, lineSeparator, tabNumber + 1, mode);
+				}
+				writeNewLine(buffer, lineSeparator, tabNumber + 1);
+				buffer.append(Messages.disassembler_annotationarrayvalueend);
+		}
+	}
+
+	private void disassemble(IAnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_annotationdefaultheader);
+		IAnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue();
+		writeNewLine(buffer, lineSeparator, tabNumber + 2);
+		disassemble(componentValue, buffer, lineSeparator, tabNumber + 1, mode);
+	}
+
+	private void disassemble(IClassFileAttribute classFileAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.bind(Messages.disassembler_genericattributeheader,
+			new String[] {
+				new String(classFileAttribute.getAttributeName()),
+				Long.toString(classFileAttribute.getAttributeLength())
+			}));
+	}
+
+	private void disassembleEnumConstructor(IClassFileReader classFileReader, char[] className, IMethodInfo methodInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		final ICodeAttribute codeAttribute = methodInfo.getCodeAttribute();
+		char[] methodDescriptor = methodInfo.getDescriptor();
+		final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
+		// disassemble compact version of annotations
+		if (runtimeInvisibleAnnotationsAttribute != null) {
+			disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			writeNewLine(buffer, lineSeparator, tabNumber);
+		}
+		if (runtimeVisibleAnnotationsAttribute != null) {
+			disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			writeNewLine(buffer, lineSeparator, tabNumber);
+		}
+		final int accessFlags = methodInfo.getAccessFlags();
+		decodeModifiersForMethod(buffer, accessFlags & IModifierConstants.ACC_PRIVATE);
+		CharOperation.replace(methodDescriptor, '/', '.');
+		final boolean isVarArgs = (accessFlags & IModifierConstants.ACC_VARARGS) != 0;
+		final char[] signature = Signature.toCharArray(methodDescriptor, returnClassName(className, '.', COMPACT), getParameterNames(methodDescriptor, codeAttribute, accessFlags) , !checkMode(mode, COMPACT), false, isVarArgs);
+		int index = CharOperation.indexOf(',', signature);
+		index = CharOperation.indexOf(',', signature, index + 1);
+		buffer.append(signature, 0, CharOperation.indexOf('(', signature) + 1);
+		buffer.append(signature, index + 2, signature.length - index - 2);
+		IExceptionAttribute exceptionAttribute = methodInfo.getExceptionAttribute();
+		if (exceptionAttribute != null) {
+			buffer.append(" throws "); //$NON-NLS-1$
+			char[][] exceptionNames = exceptionAttribute.getExceptionNames();
+			int length = exceptionNames.length;
+			for (int i = 0; i < length; i++) {
+				if (i != 0) {
+					buffer
+    					.append(Messages.disassembler_comma)
+    					.append(Messages.disassembler_space);
+				}
+				char[] exceptionName = exceptionNames[i];
+				CharOperation.replace(exceptionName, '/', '.');
+				buffer.append(returnClassName(exceptionName, '.', mode));
+			}
+		}
+		if (((accessFlags & IModifierConstants.ACC_NATIVE) == 0)
+				&& ((accessFlags & IModifierConstants.ACC_ABSTRACT) == 0)) {
+			buffer.append(" {"); //$NON-NLS-1$
+			final char[] returnType = Signature.getReturnType(methodDescriptor);
+			if (returnType.length == 1) {
+				switch(returnType[0]) {
+					case 'V' :
+						writeNewLine(buffer, lineSeparator, tabNumber);
+						break;
+					case 'I' :
+					case 'B' :
+					case 'J' :
+					case 'D' :
+					case 'F' :
+					case 'S' :
+					case 'C' :
+						writeNewLine(buffer, lineSeparator, tabNumber + 1);
+						buffer.append("return 0;"); //$NON-NLS-1$
+						writeNewLine(buffer, lineSeparator, tabNumber);
+						break;
+					default :
+						// boolean
+						writeNewLine(buffer, lineSeparator, tabNumber + 1);
+						buffer.append("return false;"); //$NON-NLS-1$
+						writeNewLine(buffer, lineSeparator, tabNumber);
+				}
+			} else {
+				// object
+				writeNewLine(buffer, lineSeparator, tabNumber + 1);
+				buffer.append("return null;"); //$NON-NLS-1$
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+			buffer.append('}');
+		} else {
+			buffer.append(';');
+		}
+	}
+
+	/**
+	 * Disassemble a method info header
+	 */
+	private void disassemble(IClassFileReader classFileReader, char[] className, IMethodInfo methodInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		final ICodeAttribute codeAttribute = methodInfo.getCodeAttribute();
+		final char[] methodDescriptor = methodInfo.getDescriptor();
+		final ISignatureAttribute signatureAttribute = (ISignatureAttribute) Util.getAttribute(methodInfo, IAttributeNamesConstants.SIGNATURE);
+		final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeVisibleTypeAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleTypeAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+		final IClassFileAttribute runtimeVisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
+		final IClassFileAttribute annotationDefaultAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.ANNOTATION_DEFAULT);
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			buffer.append(Messages.bind(Messages.classfileformat_methoddescriptor,
+				new String[] {
+					Integer.toString(methodInfo.getDescriptorIndex()),
+					new String(methodDescriptor)
+				}));
+			if (methodInfo.isDeprecated()) {
+				buffer.append(Messages.disassembler_deprecated);
+			}
+			writeNewLine(buffer, lineSeparator, tabNumber);
+			if (signatureAttribute != null) {
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+			if (codeAttribute != null) {
+				buffer.append(Messages.bind(Messages.classfileformat_stacksAndLocals,
+					new String[] {
+						Integer.toString(codeAttribute.getMaxStack()),
+						Integer.toString(codeAttribute.getMaxLocals())
+					}));
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+		}
+		if (checkMode(mode, DETAILED)) {
+			// disassemble compact version of annotations
+			if (runtimeInvisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+			if (runtimeVisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+		}
+		final int accessFlags = methodInfo.getAccessFlags();
+		decodeModifiersForMethod(buffer, accessFlags);
+		if (methodInfo.isSynthetic() && !checkMode(mode, WORKING_COPY)) {
+			buffer.append("synthetic"); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space);
+		}
+		CharOperation.replace(methodDescriptor, '/', '.');
+		final boolean isVarArgs = isVarArgs(methodInfo);
+		char[] methodHeader = null;
+		char[][] parameterNames = null;
+		if (!methodInfo.isClinit()) {
+			parameterNames = getParameterNames(methodDescriptor, codeAttribute, accessFlags);
+		}
+		if (methodInfo.isConstructor()) {
+			if (checkMode(mode, WORKING_COPY) && signatureAttribute != null) {
+				final char[] signature = signatureAttribute.getSignature();
+				CharOperation.replace(signature, '/', '.');
+				disassembleGenericSignature(mode, buffer, signature);
+				buffer.append(' ');
+				methodHeader = Signature.toCharArray(signature, returnClassName(className, '.', COMPACT), parameterNames, !checkMode(mode, COMPACT), false, isVarArgs);
+			} else {
+				methodHeader = Signature.toCharArray(methodDescriptor, returnClassName(className, '.', COMPACT), parameterNames, !checkMode(mode, COMPACT), false, isVarArgs);
+			}
+		} else if (methodInfo.isClinit()) {
+			methodHeader = Messages.bind(Messages.classfileformat_clinitname).toCharArray();
+		} else {
+			if (checkMode(mode, WORKING_COPY) && signatureAttribute != null) {
+				final char[] signature = signatureAttribute.getSignature();
+				CharOperation.replace(signature, '/', '.');
+				disassembleGenericSignature(mode, buffer, signature);
+				buffer.append(' ');
+				methodHeader = Signature.toCharArray(signature, methodInfo.getName(), parameterNames, !checkMode(mode, COMPACT), true, isVarArgs);
+			} else {
+				methodHeader = Signature.toCharArray(methodDescriptor, methodInfo.getName(), parameterNames, !checkMode(mode, COMPACT), true, isVarArgs);
+			}
+		}
+		if (checkMode(mode, DETAILED) && (runtimeInvisibleParameterAnnotationsAttribute != null || runtimeVisibleParameterAnnotationsAttribute != null)) {
+			IParameterAnnotation[] invisibleParameterAnnotations = null;
+			IParameterAnnotation[] visibleParameterAnnotations = null;
+			int length = -1;
+			if (runtimeInvisibleParameterAnnotationsAttribute != null) {
+				IRuntimeInvisibleParameterAnnotationsAttribute attribute = (IRuntimeInvisibleParameterAnnotationsAttribute) runtimeInvisibleParameterAnnotationsAttribute;
+				invisibleParameterAnnotations = attribute.getParameterAnnotations();
+				length = invisibleParameterAnnotations.length;
+				if (length > 0) {
+					int parameterNamesLength = parameterNames.length;
+					if (length < parameterNamesLength) {
+						System.arraycopy(invisibleParameterAnnotations, 0, (invisibleParameterAnnotations = new IParameterAnnotation[parameterNamesLength]), 1, length);
+						length = parameterNamesLength;
+					}
+				}
+			}
+			if (runtimeVisibleParameterAnnotationsAttribute != null) {
+				IRuntimeVisibleParameterAnnotationsAttribute attribute = (IRuntimeVisibleParameterAnnotationsAttribute) runtimeVisibleParameterAnnotationsAttribute;
+				visibleParameterAnnotations = attribute.getParameterAnnotations();
+				length = visibleParameterAnnotations.length;
+				if (length > 0) {
+					int parameterNamesLength = parameterNames.length;
+					if (length < parameterNamesLength) {
+						System.arraycopy(visibleParameterAnnotations, 0, (visibleParameterAnnotations = new IParameterAnnotation[parameterNamesLength]), 1, length);
+						length = parameterNamesLength;
+					}
+				}
+			}
+			int insertionPosition = CharOperation.indexOf('(', methodHeader) + 1;
+			int start = 0;
+			StringBuffer stringBuffer = new StringBuffer();
+			stringBuffer.append(methodHeader, 0, insertionPosition);
+			for (int i = 0; i < length; i++) {
+				if (i > 0) {
+					stringBuffer.append(' ');
+				}
+				int stringBufferSize = stringBuffer.length();
+				if (visibleParameterAnnotations != null) {
+					disassembleAsModifier(visibleParameterAnnotations, stringBuffer, i, lineSeparator, tabNumber, mode);
+				}
+				if (invisibleParameterAnnotations != null) {
+					if (stringBuffer.length() != stringBufferSize) {
+						stringBuffer.append(' ');
+						stringBufferSize = stringBuffer.length();
+					}
+					disassembleAsModifier(invisibleParameterAnnotations, stringBuffer, i, lineSeparator, tabNumber, mode);
+				}
+				if (i == 0 && stringBuffer.length() != stringBufferSize) {
+					stringBuffer.append(' ');
+				}
+				start = insertionPosition;
+				insertionPosition = CharOperation.indexOf(',', methodHeader, start + 1) + 1;
+				if (insertionPosition == 0) {
+					stringBuffer.append(methodHeader, start, methodHeader.length - start);
+				} else {
+					stringBuffer.append(methodHeader, start, insertionPosition - start);
+				}
+			}
+			buffer.append(stringBuffer);
+		} else {
+			buffer.append(methodHeader);
+		}
+		IExceptionAttribute exceptionAttribute = methodInfo.getExceptionAttribute();
+		if (exceptionAttribute != null) {
+			buffer.append(" throws "); //$NON-NLS-1$
+			char[][] exceptionNames = exceptionAttribute.getExceptionNames();
+			int length = exceptionNames.length;
+			for (int i = 0; i < length; i++) {
+				if (i != 0) {
+					buffer
+						.append(Messages.disassembler_comma)
+						.append(Messages.disassembler_space);
+				}
+				char[] exceptionName = exceptionNames[i];
+				CharOperation.replace(exceptionName, '/', '.');
+				buffer.append(returnClassName(exceptionName, '.', mode));
+			}
+		}
+		if (checkMode(mode, DETAILED)) {
+			if (annotationDefaultAttribute != null) {
+				buffer.append(" default "); //$NON-NLS-1$
+				disassembleAsModifier((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+		}
+		if (checkMode(mode, WORKING_COPY)) {
+			// put the annotation default attribute if needed
+			if (annotationDefaultAttribute != null) {
+				buffer.append(" default "); //$NON-NLS-1$
+				disassembleAsModifier((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (((accessFlags & IModifierConstants.ACC_NATIVE) == 0)
+					&& ((accessFlags & IModifierConstants.ACC_ABSTRACT) == 0)) {
+				buffer.append(" {"); //$NON-NLS-1$
+				final char[] returnType = Signature.getReturnType(methodDescriptor);
+				if (returnType.length == 1) {
+					switch(returnType[0]) {
+						case 'V' :
+							writeNewLine(buffer, lineSeparator, tabNumber);
+							break;
+						case 'I' :
+						case 'B' :
+						case 'J' :
+						case 'D' :
+						case 'F' :
+						case 'S' :
+						case 'C' :
+							writeNewLine(buffer, lineSeparator, tabNumber + 1);
+							buffer.append("return 0;"); //$NON-NLS-1$
+							writeNewLine(buffer, lineSeparator, tabNumber);
+							break;
+						default :
+							// boolean
+							writeNewLine(buffer, lineSeparator, tabNumber + 1);
+							buffer.append("return false;"); //$NON-NLS-1$
+							writeNewLine(buffer, lineSeparator, tabNumber);
+					}
+				} else {
+					// object
+					writeNewLine(buffer, lineSeparator, tabNumber + 1);
+					buffer.append("return null;"); //$NON-NLS-1$
+					writeNewLine(buffer, lineSeparator, tabNumber);
+				}
+				buffer.append('}');
+			} else {
+				buffer.append(';');
+			}
+		} else {
+			buffer.append(Messages.disassembler_endofmethodheader);
+		}
+
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			if (codeAttribute != null) {
+				disassemble(codeAttribute, parameterNames, methodDescriptor, (accessFlags & IModifierConstants.ACC_STATIC) != 0, buffer, lineSeparator, tabNumber, mode);
+			}
+		}
+		if (checkMode(mode, SYSTEM)) {
+			IClassFileAttribute[] attributes = methodInfo.getAttributes();
+			int length = attributes.length;
+			if (length != 0) {
+				for (int i = 0; i < length; i++) {
+					IClassFileAttribute attribute = attributes[i];
+					if (attribute != codeAttribute
+							&& attribute != exceptionAttribute
+							&& attribute != signatureAttribute
+							&& attribute != annotationDefaultAttribute
+							&& attribute != runtimeInvisibleAnnotationsAttribute
+							&& attribute != runtimeVisibleAnnotationsAttribute
+							&& attribute != runtimeInvisibleTypeAnnotationsAttribute
+							&& attribute != runtimeVisibleTypeAnnotationsAttribute
+							&& attribute != runtimeInvisibleParameterAnnotationsAttribute
+							&& attribute != runtimeVisibleParameterAnnotationsAttribute
+							&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED)
+							&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)) {
+						disassemble(attribute, buffer, lineSeparator, tabNumber, mode);
+						writeNewLine(buffer, lineSeparator, tabNumber);
+					}
+				}
+			}
+			if (annotationDefaultAttribute != null) {
+				disassemble((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeVisibleAnnotationsAttribute != null) {
+				disassemble((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeInvisibleAnnotationsAttribute != null) {
+				disassemble((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeVisibleParameterAnnotationsAttribute != null) {
+				disassemble((IRuntimeVisibleParameterAnnotationsAttribute) runtimeVisibleParameterAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeInvisibleParameterAnnotationsAttribute != null) {
+				disassemble((IRuntimeInvisibleParameterAnnotationsAttribute) runtimeInvisibleParameterAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeVisibleTypeAnnotationsAttribute != null) {
+				disassemble((IRuntimeVisibleTypeAnnotationsAttribute) runtimeVisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeInvisibleTypeAnnotationsAttribute != null) {
+				disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+ 			}
+		}
+	}
+
+	/**
+	 * @see #disassemble(org.eclipse.jdt.core.util.IClassFileReader, java.lang.String, int)
+	 */
+	public String disassemble(IClassFileReader classFileReader, String lineSeparator) {
+		return disassemble(classFileReader, lineSeparator, ClassFileBytesDisassembler.DEFAULT);
+	}
+
+	/**
+	 * Answers back the disassembled string of the IClassFileReader according to the
+	 * mode.
+	 * This is an output quite similar to the javap tool.
+	 *
+	 * @param classFileReader The classFileReader to be disassembled
+	 * @param lineSeparator the line separator to use.
+	 * @param mode the mode used to disassemble the IClassFileReader
+	 *
+	 * @return the disassembled string of the IClassFileReader according to the mode
+	 */
+	public String disassemble(IClassFileReader classFileReader, String lineSeparator, int mode) {
+		if (classFileReader == null) return org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING;
+		char[] className = classFileReader.getClassName();
+		if (className == null) {
+			// incomplete initialization. We cannot go further.
+			return org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING;
+		}
+		className= CharOperation.replaceOnCopy(className, '/', '.');
+		final int classNameLength = className.length;
+		final int accessFlags = classFileReader.getAccessFlags();
+		final boolean isEnum = (accessFlags & IModifierConstants.ACC_ENUM) != 0;
+	
+		StringBuffer buffer = new StringBuffer();
+		ISourceAttribute sourceAttribute = classFileReader.getSourceFileAttribute();
+		IClassFileAttribute classFileAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.SIGNATURE);
+		ISignatureAttribute signatureAttribute = (ISignatureAttribute) classFileAttribute;
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			int minorVersion = classFileReader.getMinorVersion();
+			int majorVersion = classFileReader.getMajorVersion();
+			buffer.append(Messages.disassembler_begincommentline);
+			if (sourceAttribute != null) {
+				buffer.append(Messages.disassembler_sourceattributeheader);
+				buffer.append(sourceAttribute.getSourceFileName());
+			}
+			String versionNumber = VERSION_UNKNOWN;
+			if (minorVersion == 3 && majorVersion == 45) {
+				versionNumber = JavaCore.VERSION_1_1;
+			} else if (minorVersion == 0 && majorVersion == 46) {
+				versionNumber = JavaCore.VERSION_1_2;
+			} else if (minorVersion == 0 && majorVersion == 47) {
+				versionNumber = JavaCore.VERSION_1_3;
+			} else if (minorVersion == 0 && majorVersion == 48) {
+				versionNumber = JavaCore.VERSION_1_4;
+			} else if (minorVersion == 0 && majorVersion == 49) {
+				versionNumber = JavaCore.VERSION_1_5;
+			} else if (minorVersion == 0 && majorVersion == 50) {
+				versionNumber = JavaCore.VERSION_1_6;
+			} else if (minorVersion == 0 && majorVersion == 51) {
+				versionNumber = JavaCore.VERSION_1_7;
+			} else if (minorVersion == 0 && majorVersion == 52) {
+				versionNumber = JavaCore.VERSION_1_8;
+			}
+			buffer.append(
+				Messages.bind(Messages.classfileformat_versiondetails,
+				new String[] {
+					versionNumber,
+					Integer.toString(majorVersion),
+					Integer.toString(minorVersion),
+					((accessFlags & IModifierConstants.ACC_SUPER) != 0
+							? Messages.classfileformat_superflagisset
+							: Messages.classfileformat_superflagisnotset)
+					+ (isDeprecated(classFileReader) ? ", deprecated" : org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING)//$NON-NLS-1$
+				}));
+			writeNewLine(buffer, lineSeparator, 0);
+			if (signatureAttribute != null) {
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
+				writeNewLine(buffer, lineSeparator, 0);
+			}
+		}
+		final int lastDotIndexInClassName = CharOperation.lastIndexOf('.', className);
+	
+		if (checkMode(mode, WORKING_COPY) && lastDotIndexInClassName != -1) {
+			// we print a package declaration
+			buffer.append("package ");//$NON-NLS-1$
+			buffer.append(className, 0, lastDotIndexInClassName);
+			buffer.append(';');
+			writeNewLine(buffer, lineSeparator, 0);
+		}
+	
+		IInnerClassesAttribute innerClassesAttribute = classFileReader.getInnerClassesAttribute();
+		IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
+		IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
+		IClassFileAttribute runtimeVisibleTypeAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+		IClassFileAttribute runtimeInvisibleTypeAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+
+		IClassFileAttribute bootstrapMethods = Util.getAttribute(classFileReader, IAttributeNamesConstants.BOOTSTRAP_METHODS);
+	
+		if (checkMode(mode, DETAILED)) {
+			// disassemble compact version of annotations
+			if (runtimeInvisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+				writeNewLine(buffer, lineSeparator, 0);
+			}
+			if (runtimeVisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+				writeNewLine(buffer, lineSeparator, 0);
+			}
+		}
+		boolean decoded = false;
+		if (isEnum && checkMode(mode, WORKING_COPY)) {
+			decodeModifiersForType(buffer, accessFlags & IModifierConstants.ACC_PUBLIC);
+		} else {
+			if (innerClassesAttribute != null) {
+				// search the right entry
+				IInnerClassesAttributeEntry[] entries = innerClassesAttribute.getInnerClassAttributesEntries();
+				for (int i = 0, max = entries.length; i < max ; i++) {
+					IInnerClassesAttributeEntry entry = entries[i];
+					char[] innerClassName = entry.getInnerClassName();
+					if (innerClassName != null) {
+						if (CharOperation.equals(classFileReader.getClassName(), innerClassName)) {
+							decodeModifiersForInnerClasses(buffer, entry.getAccessFlags(), false);
+							decoded = true;
+						}
+					}
+				}
+			}
+			if (!decoded) {
+				decodeModifiersForType(buffer, accessFlags);
+				if (isSynthetic(classFileReader)) {
+					buffer.append("synthetic"); //$NON-NLS-1$
+					buffer.append(Messages.disassembler_space);
+				}
+			}
+		}
+	
+		final boolean isAnnotation = (accessFlags & IModifierConstants.ACC_ANNOTATION) != 0;
+		boolean isInterface = false;
+		if (isEnum) {
+			buffer.append("enum "); //$NON-NLS-1$
+		} else if (classFileReader.isClass()) {
+			buffer.append("class "); //$NON-NLS-1$
+		} else {
+			if (isAnnotation) {
+				buffer.append("@"); //$NON-NLS-1$
+			}
+			buffer.append("interface "); //$NON-NLS-1$
+			isInterface = true;
+		}
+	
+		if (checkMode(mode, WORKING_COPY)) {
+			// we print the simple class name
+			final int start = lastDotIndexInClassName + 1;
+			buffer.append(className, start, classNameLength - start);
+			className = CharOperation.subarray(className, start, classNameLength);
+			if (signatureAttribute != null) {
+				disassembleGenericSignature(mode, buffer, signatureAttribute.getSignature());
+			}
+		} else {
+			buffer.append(className);
+		}
+	
+		char[] superclassName = classFileReader.getSuperclassName();
+		if (superclassName != null) {
+			CharOperation.replace(superclassName, '/', '.');
+			if (!isJavaLangObject(superclassName) && !isEnum) {
+				buffer.append(" extends "); //$NON-NLS-1$
+				buffer.append(returnClassName(superclassName, '.', mode));
+			}
+		}
+		if (!isAnnotation || !checkMode(mode, WORKING_COPY)) {
+			char[][] superclassInterfaces = classFileReader.getInterfaceNames();
+			int length = superclassInterfaces.length;
+			if (length != 0) {
+				if (isInterface) {
+					buffer.append(" extends "); //$NON-NLS-1$
+				} else {
+					buffer.append(" implements "); //$NON-NLS-1$
+				}
+				for (int i = 0; i < length; i++) {
+					if (i != 0) {
+						buffer
+							.append(Messages.disassembler_comma)
+							.append(Messages.disassembler_space);
+					}
+					char[] superinterface = superclassInterfaces[i];
+					CharOperation.replace(superinterface, '/', '.');
+					buffer
+						.append(returnClassName(superinterface, '.', mode));
+				}
+			}
+		}
+		buffer.append(Messages.bind(Messages.disassembler_opentypedeclaration));
+		if (checkMode(mode, SYSTEM)) {
+			disassemble(classFileReader.getConstantPool(), buffer, lineSeparator, 1);
+		}
+		disassembleTypeMembers(classFileReader, className, buffer, lineSeparator, 1, mode, isEnum);
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			IClassFileAttribute[] attributes = classFileReader.getAttributes();
+			int length = attributes.length;
+			IEnclosingMethodAttribute enclosingMethodAttribute = getEnclosingMethodAttribute(classFileReader);
+			int remainingAttributesLength = length;
+			if (innerClassesAttribute != null) {
+				remainingAttributesLength--;
+			}
+			if (enclosingMethodAttribute != null) {
+				remainingAttributesLength--;
+			}
+			if (sourceAttribute != null) {
+				remainingAttributesLength--;
+			}
+			if (signatureAttribute != null) {
+				remainingAttributesLength--;
+			}
+			if (bootstrapMethods != null) {
+				remainingAttributesLength--;
+			}
+			if (innerClassesAttribute != null
+					|| enclosingMethodAttribute != null
+					|| bootstrapMethods != null
+					|| remainingAttributesLength != 0) {
+				// this test is to ensure we don't insert more than one line separator
+				if (buffer.lastIndexOf(lineSeparator) != buffer.length() - lineSeparator.length()) {
+					writeNewLine(buffer, lineSeparator, 0);
+				}
+			}
+			if (innerClassesAttribute != null) {
+				disassemble(innerClassesAttribute, buffer, lineSeparator, 1);
+			}
+			if (enclosingMethodAttribute != null) {
+				disassemble(enclosingMethodAttribute, buffer, lineSeparator, 0);
+			}
+			if (bootstrapMethods != null) {
+				disassemble((IBootstrapMethodsAttribute) bootstrapMethods, buffer, lineSeparator, 0);
+			}
+			if (checkMode(mode, SYSTEM)) {
+				if (runtimeVisibleAnnotationsAttribute != null) {
+					disassemble((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+				}
+				if (runtimeInvisibleAnnotationsAttribute != null) {
+					disassemble((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+				}
+				if (runtimeVisibleTypeAnnotationsAttribute != null) {
+					disassemble((IRuntimeVisibleTypeAnnotationsAttribute) runtimeVisibleTypeAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+				}
+				if (runtimeInvisibleTypeAnnotationsAttribute != null) {
+					disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, 0, mode);
+	 			}
+				if (length != 0) {
+					for (int i = 0; i < length; i++) {
+						IClassFileAttribute attribute = attributes[i];
+						if (attribute != innerClassesAttribute
+								&& attribute != sourceAttribute
+								&& attribute != signatureAttribute
+								&& attribute != enclosingMethodAttribute
+								&& attribute != runtimeInvisibleAnnotationsAttribute
+								&& attribute != runtimeVisibleAnnotationsAttribute
+								&& attribute != runtimeInvisibleTypeAnnotationsAttribute
+								&& attribute != runtimeVisibleTypeAnnotationsAttribute
+								&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED)
+								&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)
+								&& attribute != bootstrapMethods) {
+							disassemble(attribute, buffer, lineSeparator, 0, mode);
+						}
+					}
+				}
+			}
+		}
+		writeNewLine(buffer, lineSeparator, 0);
+		buffer.append(Messages.disassembler_closetypedeclaration);
+		return buffer.toString();
+	}
+
+	private void disassembleGenericSignature(int mode, StringBuffer buffer, final char[] signature) {
+		CharOperation.replace(signature, '/', '.');
+		final char[][] typeParameters = Signature.getTypeParameters(signature);
+		final int typeParametersLength = typeParameters.length;
+		if (typeParametersLength != 0) {
+			buffer.append('<');
+			for (int i = 0; i < typeParametersLength; i++) {
+				if (i != 0) {
+					buffer.append(Messages.disassembler_comma);
+				}
+				// extract the name
+				buffer.append(typeParameters[i], 0, CharOperation.indexOf(':', typeParameters[i]));
+				final char[][] bounds = Signature.getTypeParameterBounds(typeParameters[i]);
+				final int boundsLength = bounds.length;
+				if (boundsLength != 0) {
+					if (boundsLength == 1) {
+						final char[] bound = bounds[0];
+						// check if this is java.lang.Object
+						if (!isJavaLangObject(Signature.toCharArray(bound))) {
+							buffer.append(" extends "); //$NON-NLS-1$
+							buffer.append(returnClassName(Signature.toCharArray(bound), '.', mode));
+						}
+					} else {
+						buffer.append(" extends "); //$NON-NLS-1$
+						for (int j= 0; j < boundsLength; j++) {
+							if (j != 0) {
+								buffer.append(" & "); //$NON-NLS-1$
+							}
+							buffer.append(returnClassName(Signature.toCharArray(bounds[j]), '.', mode));
+						}
+					}
+				}
+			}
+			buffer.append('>');
+		}
+	}
+
+	private boolean isJavaLangObject(final char[] className) {
+		return CharOperation.equals(TypeConstants.JAVA_LANG_OBJECT, CharOperation.splitOn('.', className));
+	}
+
+
+	private boolean isVarArgs(IMethodInfo methodInfo) {
+		int accessFlags = methodInfo.getAccessFlags();
+		if ((accessFlags & IModifierConstants.ACC_VARARGS) != 0) return true;
+		// check the presence of the unspecified Varargs attribute
+		return Util.getAttribute(methodInfo, AttributeNamesConstants.VarargsName) != null;
+	}
+	private void disassemble(ICodeAttribute codeAttribute, char[][] parameterNames, char[] methodDescriptor, boolean isStatic, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber - 1);
+		DefaultBytecodeVisitor visitor = new DefaultBytecodeVisitor(codeAttribute, parameterNames, methodDescriptor, isStatic, buffer, lineSeparator, tabNumber, mode);
+		try {
+			codeAttribute.traverse(visitor);
+		} catch(ClassFormatException e) {
+			dumpTab(tabNumber + 2, buffer);
+			buffer.append(Messages.classformat_classformatexception);
+			writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		}
+		final int exceptionTableLength = codeAttribute.getExceptionTableLength();
+		boolean isFirstAttribute = true;
+		if (exceptionTableLength != 0) {
+			final int tabNumberForExceptionAttribute = tabNumber + 2;
+			isFirstAttribute = false;
+			dumpTab(tabNumberForExceptionAttribute, buffer);
+			final IExceptionTableEntry[] exceptionTableEntries = codeAttribute.getExceptionTable();
+			buffer.append(Messages.disassembler_exceptiontableheader);
+			writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
+			for (int i = 0; i < exceptionTableLength; i++) {
+				if (i != 0) {
+					writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
+				}
+				IExceptionTableEntry exceptionTableEntry = exceptionTableEntries[i];
+				char[] catchType;
+				if (exceptionTableEntry.getCatchTypeIndex() != 0) {
+					catchType = exceptionTableEntry.getCatchType();
+					CharOperation.replace(catchType, '/', '.');
+					catchType = returnClassName(catchType, '.', mode);
+				} else {
+					catchType = ANY_EXCEPTION;
+				}
+				buffer.append(Messages.bind(Messages.classfileformat_exceptiontableentry,
+					new String[] {
+						Integer.toString(exceptionTableEntry.getStartPC()),
+						Integer.toString(exceptionTableEntry.getEndPC()),
+						Integer.toString(exceptionTableEntry.getHandlerPC()),
+						new String(catchType),
+					}));
+			}
+		}
+		final ILineNumberAttribute lineNumberAttribute = codeAttribute.getLineNumberAttribute();
+		final int lineAttributeLength = lineNumberAttribute == null ? 0 : lineNumberAttribute.getLineNumberTableLength();
+		if (lineAttributeLength != 0) {
+			int tabNumberForLineAttribute = tabNumber + 2;
+			if (!isFirstAttribute) {
+				writeNewLine(buffer, lineSeparator, tabNumberForLineAttribute);
+			} else {
+				dumpTab(tabNumberForLineAttribute, buffer);
+				isFirstAttribute = false;
+			}
+			buffer.append(Messages.disassembler_linenumberattributeheader);
+			writeNewLine(buffer, lineSeparator, tabNumberForLineAttribute + 1);
+			int[][] lineattributesEntries = lineNumberAttribute.getLineNumberTable();
+			for (int i = 0; i < lineAttributeLength; i++) {
+				if (i != 0) {
+					writeNewLine(buffer, lineSeparator, tabNumberForLineAttribute + 1);
+				}
+				buffer.append(Messages.bind(Messages.classfileformat_linenumbertableentry,
+					new String[] {
+						Integer.toString(lineattributesEntries[i][0]),
+						Integer.toString(lineattributesEntries[i][1])
+					}));
+			}
+		}
+		final ILocalVariableAttribute localVariableAttribute = codeAttribute.getLocalVariableAttribute();
+		final int localVariableAttributeLength = localVariableAttribute == null ? 0 : localVariableAttribute.getLocalVariableTableLength();
+		if (localVariableAttributeLength != 0) {
+			int tabNumberForLocalVariableAttribute = tabNumber + 2;
+			if (!isFirstAttribute) {
+				writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute);
+			} else {
+				isFirstAttribute = false;
+				dumpTab(tabNumberForLocalVariableAttribute, buffer);
+			}
+			buffer.append(Messages.disassembler_localvariabletableattributeheader);
+			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
+			ILocalVariableTableEntry[] localVariableTableEntries = localVariableAttribute.getLocalVariableTable();
+			for (int i = 0; i < localVariableAttributeLength; i++) {
+				if (i != 0) {
+					writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
+				}
+				ILocalVariableTableEntry localVariableTableEntry = localVariableTableEntries[i];
+				int index= localVariableTableEntry.getIndex();
+				int startPC = localVariableTableEntry.getStartPC();
+				int length  = localVariableTableEntry.getLength();
+				final char[] typeName = Signature.toCharArray(localVariableTableEntry.getDescriptor());
+				CharOperation.replace(typeName, '/', '.');
+				buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+					new String[] {
+						Integer.toString(startPC),
+						Integer.toString(startPC + length),
+						new String(localVariableTableEntry.getName()),
+						Integer.toString(index),
+						new String(returnClassName(typeName, '.', mode))
+					}));
+			}
+		}
+		final ILocalVariableTypeTableAttribute localVariableTypeAttribute= (ILocalVariableTypeTableAttribute) getAttribute(IAttributeNamesConstants.LOCAL_VARIABLE_TYPE_TABLE, codeAttribute);
+		final int localVariableTypeTableLength = localVariableTypeAttribute == null ? 0 : localVariableTypeAttribute.getLocalVariableTypeTableLength();
+		if (localVariableTypeTableLength != 0) {
+			int tabNumberForLocalVariableAttribute = tabNumber + 2;
+			if (!isFirstAttribute) {
+				writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute);
+			} else {
+				isFirstAttribute = false;
+				dumpTab(tabNumberForLocalVariableAttribute, buffer);
+			}
+			buffer.append(Messages.disassembler_localvariabletypetableattributeheader);
+			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
+			ILocalVariableTypeTableEntry[] localVariableTypeTableEntries = localVariableTypeAttribute.getLocalVariableTypeTable();
+			for (int i = 0; i < localVariableTypeTableLength; i++) {
+				if (i != 0) {
+					writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
+				}
+				ILocalVariableTypeTableEntry localVariableTypeTableEntry = localVariableTypeTableEntries[i];
+				int index= localVariableTypeTableEntry.getIndex();
+				int startPC = localVariableTypeTableEntry.getStartPC();
+				int length  = localVariableTypeTableEntry.getLength();
+				final char[] typeName = Signature.toCharArray(localVariableTypeTableEntry.getSignature());
+				CharOperation.replace(typeName, '/', '.');
+				buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+					new String[] {
+						Integer.toString(startPC),
+						Integer.toString(startPC + length),
+						new String(localVariableTypeTableEntry.getName()),
+						Integer.toString(index),
+						new String(returnClassName(typeName, '.', mode))
+					}));
+			}
+		}
+		final int length = codeAttribute.getAttributesCount();
+		if (length != 0) {
+			IClassFileAttribute[] attributes = codeAttribute.getAttributes();
+			for (int i = 0; i < length; i++) {
+				IClassFileAttribute attribute = attributes[i];
+				if (CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.STACK_MAP_TABLE)) {
+					IStackMapTableAttribute stackMapTableAttribute = (IStackMapTableAttribute) attribute;
+					if (!isFirstAttribute) {
+						writeNewLine(buffer, lineSeparator, tabNumber + 2);
+					} else {
+						isFirstAttribute = false;
+						dumpTab(tabNumber + 1, buffer);
+					}
+					int numberOfEntries = stackMapTableAttribute.getNumberOfEntries();
+					buffer.append(Messages.bind(Messages.disassembler_stackmaptableattributeheader, Integer.toString(numberOfEntries)));
+					if (numberOfEntries != 0) {
+						disassemble(stackMapTableAttribute, buffer, lineSeparator, tabNumber, mode);
+					}
+				} else if (CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.STACK_MAP)) {
+					IStackMapAttribute stackMapAttribute = (IStackMapAttribute) attribute;
+					if (!isFirstAttribute) {
+						writeNewLine(buffer, lineSeparator, tabNumber + 2);
+					} else {
+						isFirstAttribute = false;
+						dumpTab(tabNumber + 1, buffer);
+					}
+					int numberOfEntries = stackMapAttribute.getNumberOfEntries();
+					buffer.append(Messages.bind(Messages.disassembler_stackmapattributeheader, Integer.toString(numberOfEntries)));
+					if (numberOfEntries != 0) {
+						disassemble(stackMapAttribute, buffer, lineSeparator, tabNumber, mode);
+					}
+				} else if (CharOperation.equals(attribute.getAttributeName(),IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+					disassemble((IRuntimeVisibleTypeAnnotationsAttribute) attribute, buffer, lineSeparator, tabNumber, mode);
+				} else if (CharOperation.equals(attribute.getAttributeName(),IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+					disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) attribute, buffer, lineSeparator, tabNumber, mode);					
+				} else if (attribute != lineNumberAttribute
+						&& attribute != localVariableAttribute
+						&& attribute != localVariableTypeAttribute) {
+					if (!isFirstAttribute) {
+						writeNewLine(buffer, lineSeparator, tabNumber + 2);
+					} else {
+						isFirstAttribute = false;
+						dumpTab(tabNumber + 1, buffer);
+					}
+					buffer.append(Messages.bind(Messages.disassembler_genericattributeheader,
+						new String[] {
+							new String(attribute.getAttributeName()),
+							Long.toString(attribute.getAttributeLength())
+						}));
+				}
+			}
+		}
+	}
+
+	private void disassemble(IStackMapTableAttribute attribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 3);
+		int numberOfEntries = attribute.getNumberOfEntries();
+		final IStackMapFrame[] stackMapFrames = attribute.getStackMapFrame();
+		int absolutePC = -1;
+		for (int j = 0; j < numberOfEntries; j++) {
+			if (j > 0) {
+				writeNewLine(buffer, lineSeparator, tabNumber + 3);
+			}
+			final IStackMapFrame frame = stackMapFrames[j];
+			// disassemble each frame
+			int type = frame.getFrameType();
+			int offsetDelta = frame.getOffsetDelta();
+			if (absolutePC == -1) {
+				absolutePC = offsetDelta;
+			} else {
+				absolutePC += (offsetDelta + 1);
+			}
+			switch(type) {
+				case 247 : // SAME_LOCALS_1_STACK_ITEM_EXTENDED
+					buffer.append(
+						Messages.bind(
+							Messages.disassembler_frame_same_locals_1_stack_item_extended,
+							Integer.toString(absolutePC),
+							disassemble(frame.getStackItems(), mode)));
+					break;
+				case 248 :
+				case 249 :
+				case 250:
+					// CHOP
+					buffer.append(
+							Messages.bind(
+								Messages.disassembler_frame_chop,
+								Integer.toString(absolutePC),
+								Integer.toString(251 - type)));
+					break;
+				case 251 :
+					// SAME_FRAME_EXTENDED
+					buffer.append(
+							Messages.bind(
+								Messages.disassembler_frame_same_frame_extended,
+								Integer.toString(absolutePC)));
+					break;
+				case 252 :
+				case 253 :
+				case 254 :
+					// APPEND
+					buffer.append(
+							Messages.bind(
+								Messages.disassembler_frame_append,
+								Integer.toString(absolutePC),
+								disassemble(frame.getLocals(), mode)));
+					break;
+				case 255 :
+					// FULL_FRAME
+					buffer.append(
+							Messages.bind(
+								Messages.disassembler_frame_full_frame,
+								new String[] {
+									Integer.toString(absolutePC),
+									Integer.toString(frame.getNumberOfLocals()),
+									disassemble(frame.getLocals(), mode),
+									Integer.toString(frame.getNumberOfStackItems()),
+									disassemble(frame.getStackItems(), mode),
+									dumpNewLineWithTabs(lineSeparator, tabNumber + 5)
+								}));
+					break;
+				default:
+					if (type <= 63) {
+						// SAME_FRAME
+						offsetDelta = type;
+						buffer.append(
+								Messages.bind(
+									Messages.disassembler_frame_same_frame,
+									Integer.toString(absolutePC)));
+					} else if (type <= 127) {
+						// SAME_LOCALS_1_STACK_ITEM
+						offsetDelta = type - 64;
+						buffer.append(
+								Messages.bind(
+									Messages.disassembler_frame_same_locals_1_stack_item,
+									Integer.toString(absolutePC),
+									disassemble(frame.getStackItems(), mode)));
+					}
+			}
+		}
+	}
+
+	private void disassemble(IStackMapAttribute attribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 3);
+		int numberOfEntries = attribute.getNumberOfEntries();
+		final IStackMapFrame[] stackMapFrames = attribute.getStackMapFrame();
+		for (int j = 0; j < numberOfEntries; j++) {
+			if (j > 0) {
+				writeNewLine(buffer, lineSeparator, tabNumber + 3);
+			}
+			final IStackMapFrame frame = stackMapFrames[j];
+			// disassemble each frame
+			buffer.append(
+					Messages.bind(
+						Messages.disassembler_frame_full_frame,
+						new String[] {
+							Integer.toString(frame.getOffsetDelta()),
+							Integer.toString(frame.getNumberOfLocals()),
+							disassemble(frame.getLocals(), mode),
+							Integer.toString(frame.getNumberOfStackItems()),
+							disassemble(frame.getStackItems(), mode),
+							dumpNewLineWithTabs(lineSeparator, tabNumber + 5)
+						}));
+		}
+	}
+
+	private void disassemble(IConstantPool constantPool, StringBuffer buffer, String lineSeparator, int tabNumber) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		int length = constantPool.getConstantPoolCount();
+		buffer.append(Messages.disassembler_constantpoolheader);
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		for (int i = 1; i < length; i++) {
+			if (i != 1) {
+				writeNewLine(buffer, lineSeparator, tabNumber + 1);
+			}
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(i);
+			switch (constantPool.getEntryKind(i)) {
+				case IConstantPoolConstant.CONSTANT_Class :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_class,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getClassInfoNameIndex()),
+								new String(constantPoolEntry.getClassInfoName())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Double :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_double,
+							new String[] {
+								Integer.toString(i),
+								Double.toString(constantPoolEntry.getDoubleValue())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Fieldref :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_fieldref,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getClassIndex()),
+								Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+								new String(constantPoolEntry.getClassName()),
+								new String(constantPoolEntry.getFieldName()),
+								new String(constantPoolEntry.getFieldDescriptor())
+							}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Float :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_float,
+						new String[] {
+							Integer.toString(i),
+							Float.toString(constantPoolEntry.getFloatValue())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Integer :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_integer,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getIntegerValue())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
+					buffer.append(
+							Messages.bind(Messages.disassembler_constantpool_interfacemethodref,
+								new String[] {
+									Integer.toString(i),
+									Integer.toString(constantPoolEntry.getClassIndex()),
+									Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+									new String(constantPoolEntry.getClassName()),
+									new String(constantPoolEntry.getMethodName()),
+									new String(constantPoolEntry.getMethodDescriptor())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Long :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_long,
+							new String[] {
+								Integer.toString(i),
+								Long.toString(constantPoolEntry.getLongValue())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Methodref :
+					buffer.append(
+							Messages.bind(Messages.disassembler_constantpool_methodref,
+								new String[] {
+									Integer.toString(i),
+									Integer.toString(constantPoolEntry.getClassIndex()),
+									Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+									new String(constantPoolEntry.getClassName()),
+									new String(constantPoolEntry.getMethodName()),
+									new String(constantPoolEntry.getMethodDescriptor())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_NameAndType :
+					int nameIndex = constantPoolEntry.getNameAndTypeInfoNameIndex();
+					int typeIndex = constantPoolEntry.getNameAndTypeInfoDescriptorIndex();
+					IConstantPoolEntry entry = constantPool.decodeEntry(nameIndex);
+					char[] nameValue = entry.getUtf8Value();
+					entry = constantPool.decodeEntry(typeIndex);
+					char[] typeValue = entry.getUtf8Value();
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_name_and_type,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(nameIndex),
+								Integer.toString(typeIndex),
+								String.valueOf(nameValue),
+								String.valueOf(typeValue)}));
+					break;
+				case IConstantPoolConstant.CONSTANT_String :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_string,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getStringIndex()),
+								decodeStringValue(constantPoolEntry.getStringValue())}));
+					break;
+				case IConstantPoolConstant.CONSTANT_Utf8 :
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_utf8,
+							new String[] {
+								Integer.toString(i),
+								decodeStringValue(new String(constantPoolEntry.getUtf8Value()))}));
+					break;
+				case IConstantPoolConstant.CONSTANT_MethodHandle :
+					IConstantPoolEntry2 entry2 = (IConstantPoolEntry2) constantPoolEntry;
+					buffer.append(
+							Messages.bind(Messages.disassembler_constantpool_methodhandle,
+								new String[] {
+									Integer.toString(i),
+									getReferenceKind(entry2.getReferenceKind()),
+									Integer.toString(entry2.getReferenceIndex()),
+								}));
+					break;
+				case IConstantPoolConstant.CONSTANT_MethodType :
+					entry2 = (IConstantPoolEntry2) constantPoolEntry;
+					buffer.append(
+							Messages.bind(Messages.disassembler_constantpool_methodtype,
+								new String[] {
+									Integer.toString(i),
+									Integer.toString(entry2.getDescriptorIndex()),
+									String.valueOf(entry2.getMethodDescriptor()),
+								}));
+					break;
+				case IConstantPoolConstant.CONSTANT_InvokeDynamic :
+					entry2 = (IConstantPoolEntry2) constantPoolEntry;
+					buffer.append(
+						Messages.bind(Messages.disassembler_constantpool_invokedynamic,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(entry2.getBootstrapMethodAttributeIndex()),
+								Integer.toString(entry2.getNameAndTypeIndex()),
+								new String(constantPoolEntry.getMethodName()),
+								new String(constantPoolEntry.getMethodDescriptor())
+							}));
+			}
+		}
+	}
+	
+	private String getReferenceKind(int referenceKind) {
+		String message = null;
+		switch(referenceKind) {
+			case IConstantPoolConstant.METHOD_TYPE_REF_GetField :
+				message = Messages.disassembler_method_type_ref_getfield;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_GetStatic :
+				message = Messages.disassembler_method_type_ref_getstatic;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_PutField :
+				message = Messages.disassembler_method_type_ref_putfield;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_PutStatic :
+				message = Messages.disassembler_method_type_ref_putstatic;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_InvokeInterface :
+				message = Messages.disassembler_method_type_ref_invokeinterface;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_InvokeSpecial :
+				message = Messages.disassembler_method_type_ref_invokespecial;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_InvokeStatic :
+				message = Messages.disassembler_method_type_ref_invokestatic;
+				break;
+			case IConstantPoolConstant.METHOD_TYPE_REF_InvokeVirtual :
+				message = Messages.disassembler_method_type_ref_invokevirtual;
+				break;
+			default :
+				message = Messages.disassembler_method_type_ref_newinvokespecial;
+		}
+		return Messages.bind(message, new String[] { Integer.toString(referenceKind) });
+	}
+
+	private void disassemble(IEnclosingMethodAttribute enclosingMethodAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_enclosingmethodheader);
+		buffer
+			.append(Messages.disassembler_constantpoolindex)
+			.append(enclosingMethodAttribute.getEnclosingClassIndex())
+			.append(" ")//$NON-NLS-1$
+			.append(Messages.disassembler_constantpoolindex)
+			.append(enclosingMethodAttribute.getMethodNameAndTypeIndex())
+			.append(" ")//$NON-NLS-1$
+			.append(enclosingMethodAttribute.getEnclosingClass());
+		if (enclosingMethodAttribute.getMethodNameAndTypeIndex() != 0) {
+			buffer
+				.append(".")//$NON-NLS-1$
+				.append(enclosingMethodAttribute.getMethodName())
+				.append(enclosingMethodAttribute.getMethodDescriptor());
+		}
+	}
+
+	private void disassembleEnumConstants(IFieldInfo fieldInfo, StringBuffer buffer, String lineSeparator, int tabNumber, char[][] argumentTypes, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
+		// disassemble compact version of annotations
+		if (runtimeInvisibleAnnotationsAttribute != null) {
+			disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			writeNewLine(buffer, lineSeparator, tabNumber);
+		}
+		if (runtimeVisibleAnnotationsAttribute != null) {
+			disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			writeNewLine(buffer, lineSeparator, tabNumber);
+		}
+		buffer.append(new String(fieldInfo.getName()));
+		buffer.append('(');
+		final int length = argumentTypes.length;
+		if (length != 0) {
+			// insert default value for corresponding argument types
+			for (int i = 0; i < length; i++) {
+				if (i != 0) {
+					buffer.append(Messages.disassembler_comma);
+				}
+				final char[] type = argumentTypes[i];
+				switch(type.length) {
+					case 1 :
+						switch(type[0]) {
+							case 'B' :
+							case 'I' :
+							case 'J' :
+							case 'D' :
+							case 'F' :
+							case 'S' :
+								buffer.append('0');
+								break;
+							case 'Z' :
+								buffer.append("false"); //$NON-NLS-1$
+								break;
+							case 'C' :
+								buffer.append("\' \'"); //$NON-NLS-1$
+								break;
+						}
+						break;
+					default :
+						buffer.append("null"); //$NON-NLS-1$
+				}
+			}
+		}
+		buffer.append(')').append(Messages.disassembler_comma);
+	}
+
+	/**
+	 * Disassemble a field info
+	 */
+	private void disassemble(IFieldInfo fieldInfo, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		final char[] fieldDescriptor = fieldInfo.getDescriptor();
+		final ISignatureAttribute signatureAttribute = (ISignatureAttribute) Util.getAttribute(fieldInfo, IAttributeNamesConstants.SIGNATURE);
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			buffer.append(Messages.bind(Messages.classfileformat_fieldddescriptor,
+				new String[] {
+					Integer.toString(fieldInfo.getDescriptorIndex()),
+					new String(fieldDescriptor)
+				}));
+			if (fieldInfo.isDeprecated()) {
+				buffer.append(Messages.disassembler_deprecated);
+			}
+			writeNewLine(buffer, lineSeparator, tabNumber);
+			if (signatureAttribute != null) {
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+		}
+		final IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
+		final IClassFileAttribute runtimeVisibleTypeAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS);
+		final IClassFileAttribute runtimeInvisibleTypeAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS);
+		if (checkMode(mode, DETAILED)) {
+			// disassemble compact version of annotations
+			if (runtimeInvisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+			if (runtimeVisibleAnnotationsAttribute != null) {
+				disassembleAsModifier((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+		}
+		if (checkMode(mode, WORKING_COPY)) {
+			decodeModifiersForFieldForWorkingCopy(buffer, fieldInfo.getAccessFlags());
+			if (signatureAttribute != null) {
+				buffer.append(returnClassName(getSignatureForField(signatureAttribute.getSignature()), '.', mode));
+			} else {
+				buffer.append(returnClassName(getSignatureForField(fieldDescriptor), '.', mode));
+			}
+		} else {
+			decodeModifiersForField(buffer, fieldInfo.getAccessFlags());
+			if (fieldInfo.isSynthetic()) {
+				buffer.append("synthetic"); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_space);
+			}
+			buffer.append(returnClassName(getSignatureForField(fieldDescriptor), '.', mode));
+		}
+		buffer.append(' ');
+		buffer.append(new String(fieldInfo.getName()));
+		IConstantValueAttribute constantValueAttribute = fieldInfo.getConstantValueAttribute();
+		if (constantValueAttribute != null) {
+			buffer.append(Messages.disassembler_fieldhasconstant);
+			IConstantPoolEntry constantPoolEntry = constantValueAttribute.getConstantValue();
+			switch(constantPoolEntry.getKind()) {
+				case IConstantPoolConstant.CONSTANT_Long :
+					buffer.append(constantPoolEntry.getLongValue() + "L"); //$NON-NLS-1$
+					break;
+				case IConstantPoolConstant.CONSTANT_Float :
+					buffer.append(constantPoolEntry.getFloatValue() + "f"); //$NON-NLS-1$
+					break;
+				case IConstantPoolConstant.CONSTANT_Double :
+					final double doubleValue = constantPoolEntry.getDoubleValue();
+					if (checkMode(mode, ClassFileBytesDisassembler.WORKING_COPY)) {
+						if (doubleValue == Double.POSITIVE_INFINITY) {
+							buffer.append("1.0 / 0.0"); //$NON-NLS-1$
+						} else if (doubleValue == Double.NEGATIVE_INFINITY) {
+							buffer.append("-1.0 / 0.0"); //$NON-NLS-1$
+						} else {
+							buffer.append(constantPoolEntry.getDoubleValue());
+						}
+					} else {
+						buffer.append(constantPoolEntry.getDoubleValue());
+					}
+					break;
+				case IConstantPoolConstant.CONSTANT_Integer:
+					switch(fieldDescriptor[0]) {
+						case 'C' :
+							buffer.append("'" + (char) constantPoolEntry.getIntegerValue() + "'"); //$NON-NLS-1$//$NON-NLS-2$
+							break;
+						case 'Z' :
+							buffer.append(constantPoolEntry.getIntegerValue() == 1 ? "true" : "false");//$NON-NLS-1$//$NON-NLS-2$
+							break;
+						case 'B' :
+							buffer.append(constantPoolEntry.getIntegerValue());
+							break;
+						case 'S' :
+							buffer.append(constantPoolEntry.getIntegerValue());
+							break;
+						case 'I' :
+							buffer.append(constantPoolEntry.getIntegerValue());
+					}
+					break;
+				case IConstantPoolConstant.CONSTANT_String:
+					buffer.append("\"" + decodeStringValue(constantPoolEntry.getStringValue()) + "\"" );//$NON-NLS-1$//$NON-NLS-2$
+			}
+		}
+		buffer.append(Messages.disassembler_endoffieldheader);
+		if (checkMode(mode, SYSTEM)) {
+			IClassFileAttribute[] attributes = fieldInfo.getAttributes();
+			int length = attributes.length;
+			if (length != 0) {
+				for (int i = 0; i < length; i++) {
+					IClassFileAttribute attribute = attributes[i];
+					if (attribute != constantValueAttribute
+						&& attribute != signatureAttribute
+						&& attribute != runtimeInvisibleAnnotationsAttribute
+						&& attribute != runtimeVisibleAnnotationsAttribute
+						&& attribute != runtimeInvisibleTypeAnnotationsAttribute
+						&& attribute != runtimeVisibleTypeAnnotationsAttribute
+						&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.DEPRECATED)
+						&& !CharOperation.equals(attribute.getAttributeName(), IAttributeNamesConstants.SYNTHETIC)) {
+						disassemble(attribute, buffer, lineSeparator, tabNumber, mode);
+					}
+				}
+			}
+			if (runtimeVisibleAnnotationsAttribute != null) {
+				disassemble((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeInvisibleAnnotationsAttribute != null) {
+				disassemble((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeVisibleTypeAnnotationsAttribute != null) {
+				disassemble((IRuntimeVisibleTypeAnnotationsAttribute) runtimeVisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+			}
+			if (runtimeInvisibleTypeAnnotationsAttribute != null) {
+				disassemble((IRuntimeInvisibleTypeAnnotationsAttribute) runtimeInvisibleTypeAnnotationsAttribute, buffer, lineSeparator, tabNumber, mode);
+ 			}
+		}
+	}
+
+	private void disassemble(IInnerClassesAttribute innerClassesAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		buffer.append(Messages.disassembler_innerattributesheader);
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		IInnerClassesAttributeEntry[] innerClassesAttributeEntries = innerClassesAttribute.getInnerClassAttributesEntries();
+		int length = innerClassesAttributeEntries.length;
+		int innerClassNameIndex, outerClassNameIndex, innerNameIndex, accessFlags;
+		IInnerClassesAttributeEntry innerClassesAttributeEntry;
+		for (int i = 0; i < length; i++) {
+			if (i != 0) {
+				buffer.append(Messages.disassembler_comma);
+				writeNewLine(buffer, lineSeparator, tabNumber + 1);
+			}
+			innerClassesAttributeEntry = innerClassesAttributeEntries[i];
+			innerClassNameIndex = innerClassesAttributeEntry.getInnerClassNameIndex();
+			outerClassNameIndex = innerClassesAttributeEntry.getOuterClassNameIndex();
+			innerNameIndex = innerClassesAttributeEntry.getInnerNameIndex();
+			accessFlags = innerClassesAttributeEntry.getAccessFlags();
+			buffer
+				.append(Messages.disassembler_openinnerclassentry)
+				.append(Messages.disassembler_inner_class_info_name)
+				.append(Messages.disassembler_constantpoolindex)
+				.append(innerClassNameIndex);
+			if (innerClassNameIndex != 0) {
+				buffer
+					.append(Messages.disassembler_space)
+					.append(innerClassesAttributeEntry.getInnerClassName());
+			}
+			buffer
+				.append(Messages.disassembler_comma)
+				.append(Messages.disassembler_space)
+				.append(Messages.disassembler_outer_class_info_name)
+				.append(Messages.disassembler_constantpoolindex)
+				.append(outerClassNameIndex);
+			if (outerClassNameIndex != 0) {
+				buffer
+					.append(Messages.disassembler_space)
+					.append(innerClassesAttributeEntry.getOuterClassName());
+			}
+			writeNewLine(buffer, lineSeparator, tabNumber);
+			dumpTab(tabNumber, buffer);
+			buffer.append(Messages.disassembler_space);
+			buffer
+				.append(Messages.disassembler_inner_name)
+				.append(Messages.disassembler_constantpoolindex)
+				.append(innerNameIndex);
+			if (innerNameIndex != 0) {
+				buffer
+					.append(Messages.disassembler_space)
+					.append(innerClassesAttributeEntry.getInnerName());
+			}
+			buffer
+				.append(Messages.disassembler_comma)
+				.append(Messages.disassembler_space)
+				.append(Messages.disassembler_inner_accessflags)
+				.append(accessFlags)
+				.append(Messages.disassembler_space);
+			decodeModifiersForInnerClasses(buffer, accessFlags, true);
+			buffer
+				.append(Messages.disassembler_closeinnerclassentry);
+		}
+	}
+
+	private void disassemble(IBootstrapMethodsAttribute bootstrapMethodsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		buffer.append(Messages.disassembler_bootstrapmethodattributesheader);
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		IBootstrapMethodsEntry[] entries = bootstrapMethodsAttribute.getBootstrapMethods();
+		int length = entries.length;
+		for (int i = 0; i < length; i++) {
+			if (i != 0) {
+				buffer.append(Messages.disassembler_comma);
+				writeNewLine(buffer, lineSeparator, tabNumber + 1);
+			}
+			IBootstrapMethodsEntry entry = entries[i];
+			buffer.append(
+				Messages.bind(
+					Messages.disassembler_bootstrapmethodentry,
+					new String[] {
+						Integer.toString(i),
+						Integer.toString(entry.getBootstrapMethodReference()),
+						getArguments(entry.getBootstrapArguments())
+					}));
+		}
+	}
+
+	private String getArguments(int[] arguments) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append('{');
+		for (int i = 0, max = arguments.length; i < max; i++) {
+			if (i != 0) {
+				buffer.append(Messages.disassembler_comma);
+			}
+			buffer.append(
+				Messages.bind(
+					Messages.disassembler_bootstrapmethodentry_argument,
+					new String[] {
+						Integer.toString(arguments[i]),
+					}));
+		}
+		buffer.append('}');
+		return String.valueOf(buffer);
+	}
+	private void disassemble(int index, IParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		IAnnotation[] annotations = parameterAnnotation.getAnnotations();
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(
+			Messages.bind(Messages.disassembler_parameterannotationentrystart, new String[] {Integer.toString(index), Integer.toString(annotations.length)}));
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassemble(IRuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimeinvisibleannotationsattributeheader);
+		IAnnotation[] annotations = runtimeInvisibleAnnotationsAttribute.getAnnotations();
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassemble(IRuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimeinvisibleparameterannotationsattributeheader);
+		IParameterAnnotation[] parameterAnnotations = runtimeInvisibleParameterAnnotationsAttribute.getParameterAnnotations();
+		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
+			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+	
+	private void disassemble(IRuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimeinvisibletypeannotationsattributeheader);
+		IExtendedAnnotation[] extendedAnnotations = runtimeInvisibleTypeAnnotationsAttribute.getExtendedAnnotations();
+		for (int i = 0, max = extendedAnnotations.length; i < max; i++) {
+			disassemble(extendedAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+		
+	private void disassemble(IRuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimevisibleannotationsattributeheader);
+		IAnnotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassemble(IRuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimevisibleparameterannotationsattributeheader);
+		IParameterAnnotation[] parameterAnnotations = runtimeVisibleParameterAnnotationsAttribute.getParameterAnnotations();
+		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
+			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+	
+	private void disassemble(IRuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		writeNewLine(buffer, lineSeparator, tabNumber + 1);
+		buffer.append(Messages.disassembler_runtimevisibletypeannotationsattributeheader);
+		IExtendedAnnotation[] extendedAnnotations = runtimeVisibleTypeAnnotationsAttribute.getExtendedAnnotations();
+		for (int i = 0, max = extendedAnnotations.length; i < max; i++) {
+			disassemble(extendedAnnotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+ 		}
+ 	}
+
+	private String disassemble(IVerificationTypeInfo[] infos, int mode) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append('{');
+		for (int i = 0, max = infos.length; i < max; i++) {
+			if(i != 0) {
+				buffer
+						.append(Messages.disassembler_comma)
+						.append(Messages.disassembler_space);
+			}
+			switch(infos[i].getTag()) {
+				case IVerificationTypeInfo.ITEM_DOUBLE :
+					buffer.append("double"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_FLOAT :
+					buffer.append("float"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_INTEGER :
+					buffer.append("int"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_LONG :
+					buffer.append("long"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_NULL :
+					buffer.append("null"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_OBJECT :
+					char[] classTypeName = infos[i].getClassTypeName();
+					CharOperation.replace(classTypeName, '/', '.');
+					if (classTypeName.length > 0 && classTypeName[0] == '[') { // length check for resilience
+						classTypeName = Signature.toCharArray(classTypeName);
+					}
+					buffer.append(returnClassName(classTypeName, '.', mode));
+					break;
+				case IVerificationTypeInfo.ITEM_TOP :
+					buffer.append("_"); //$NON-NLS-1$
+					break;
+				case IVerificationTypeInfo.ITEM_UNINITIALIZED :
+					buffer.append("uninitialized("); //$NON-NLS-1$
+					buffer.append(infos[i].getOffset());
+					buffer.append(')');
+					break;
+				case IVerificationTypeInfo.ITEM_UNINITIALIZED_THIS :
+					buffer.append("uninitialized_this"); //$NON-NLS-1$
+			}
+		}
+		buffer.append('}');
+		return String.valueOf(buffer);
+	}
+
+	private void disassembleAsModifier(IAnnotation annotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.');
+		buffer.append('@').append(returnClassName(Signature.toCharArray(typeName), '.', mode));
+		final IAnnotationComponent[] components = annotation.getComponents();
+		final int length = components.length;
+		if (length != 0) {
+			buffer.append('(');
+			for (int i = 0; i < length; i++) {
+				if (i > 0) {
+					buffer.append(',');
+					writeNewLine(buffer, lineSeparator, tabNumber);
+				}
+				disassembleAsModifier(components[i], buffer, lineSeparator, tabNumber + 1, mode);
+			}
+			buffer.append(')');
+		}
+	}
+
+	private void disassembleAsModifier(IAnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		buffer.append(annotationComponent.getComponentName()).append('=');
+		disassembleAsModifier(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1, mode);
+	}
+
+	private void disassembleAsModifier(IAnnotationComponentValue annotationComponentValue, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		switch(annotationComponentValue.getTag()) {
+			case IAnnotationComponentValue.BYTE_TAG:
+			case IAnnotationComponentValue.CHAR_TAG:
+			case IAnnotationComponentValue.DOUBLE_TAG:
+			case IAnnotationComponentValue.FLOAT_TAG:
+			case IAnnotationComponentValue.INTEGER_TAG:
+			case IAnnotationComponentValue.LONG_TAG:
+			case IAnnotationComponentValue.SHORT_TAG:
+			case IAnnotationComponentValue.BOOLEAN_TAG:
+			case IAnnotationComponentValue.STRING_TAG:
+				IConstantPoolEntry constantPoolEntry = annotationComponentValue.getConstantValue();
+				String value = null;
+				switch(constantPoolEntry.getKind()) {
+					case IConstantPoolConstant.CONSTANT_Long :
+						value = constantPoolEntry.getLongValue() + "L"; //$NON-NLS-1$
+						break;
+					case IConstantPoolConstant.CONSTANT_Float :
+						value = constantPoolEntry.getFloatValue() + "f"; //$NON-NLS-1$
+						break;
+					case IConstantPoolConstant.CONSTANT_Double :
+						value = Double.toString(constantPoolEntry.getDoubleValue());
+						break;
+					case IConstantPoolConstant.CONSTANT_Integer:
+						StringBuffer temp = new StringBuffer();
+						switch(annotationComponentValue.getTag()) {
+							case IAnnotationComponentValue.CHAR_TAG :
+								temp.append('\'');
+								escapeChar(temp, (char) constantPoolEntry.getIntegerValue());
+								temp.append('\'');
+								break;
+							case IAnnotationComponentValue.BOOLEAN_TAG :
+								temp.append(constantPoolEntry.getIntegerValue() == 1 ? "true" : "false");//$NON-NLS-1$//$NON-NLS-2$
+								break;
+							case IAnnotationComponentValue.BYTE_TAG :
+								temp.append("(byte) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+								break;
+							case IAnnotationComponentValue.SHORT_TAG :
+								temp.append("(short) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+								break;
+							case IAnnotationComponentValue.INTEGER_TAG :
+								temp.append("(int) ").append(constantPoolEntry.getIntegerValue()); //$NON-NLS-1$
+						}
+						value = String.valueOf(temp);
+						break;
+					case IConstantPoolConstant.CONSTANT_Utf8:
+						value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\"";//$NON-NLS-1$//$NON-NLS-2$
+				}
+				buffer.append(value);
+				break;
+			case IAnnotationComponentValue.ENUM_TAG:
+				final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.');
+				final char[] constantName = annotationComponentValue.getEnumConstantName();
+				buffer.append(returnClassName(Signature.toCharArray(typeName), '.', mode)).append('.').append(constantName);
+				break;
+			case IAnnotationComponentValue.CLASS_TAG:
+				constantPoolEntry = annotationComponentValue.getClassInfo();
+				final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.');
+				buffer.append(returnClassName(Signature.toCharArray(className), '.', mode));
+				break;
+			case IAnnotationComponentValue.ANNOTATION_TAG:
+				IAnnotation annotation = annotationComponentValue.getAnnotationValue();
+				disassembleAsModifier(annotation, buffer, lineSeparator, tabNumber + 1, mode);
+				break;
+			case IAnnotationComponentValue.ARRAY_TAG:
+				final IAnnotationComponentValue[] annotationComponentValues = annotationComponentValue.getAnnotationComponentValues();
+				buffer.append('{');
+				for (int i = 0, max = annotationComponentValues.length; i < max; i++) {
+					if (i > 0) {
+						buffer.append(',');
+					}
+					disassembleAsModifier(annotationComponentValues[i], buffer, lineSeparator, tabNumber + 1, mode);
+				}
+				buffer.append('}');
+		}
+	}
+
+	private void disassembleAsModifier(IAnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		IAnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue();
+		disassembleAsModifier(componentValue, buffer, lineSeparator, tabNumber + 1, mode);
+	}
+
+	private void disassembleAsModifier(IRuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		IAnnotation[] annotations = runtimeInvisibleAnnotationsAttribute.getAnnotations();
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			disassembleAsModifier(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassembleAsModifier(IParameterAnnotation[] parameterAnnotations, StringBuffer buffer, int index, String lineSeparator, int tabNumber, int mode) {
+		if (parameterAnnotations.length > index) {
+			disassembleAsModifier(parameterAnnotations[index], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassembleAsModifier(IParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		if (parameterAnnotation == null) return;
+		IAnnotation[] annotations = parameterAnnotation.getAnnotations();
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			if (i > 0) {
+				buffer.append(' ');
+			}
+			disassembleAsModifier(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassembleAsModifier(IRuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		IAnnotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
+		for (int i = 0, max = annotations.length; i < max; i++) {
+			if (i > 0) {
+				writeNewLine(buffer, lineSeparator, tabNumber);
+			}
+			disassembleAsModifier(annotations[i], buffer, lineSeparator, tabNumber + 1, mode);
+		}
+	}
+
+	private void disassembleTypeMembers(IClassFileReader classFileReader, char[] className, StringBuffer buffer, String lineSeparator, int tabNumber, int mode, boolean isEnum) {
+		IFieldInfo[] fields = classFileReader.getFieldInfos();
+		if (isEnum && checkMode(mode, WORKING_COPY)) {
+			int index = 0;
+			final int fieldsLength = fields.length;
+			IMethodInfo[] methods = classFileReader.getMethodInfos();
+			char[][] constructorArguments = getConstructorArgumentsForEnum(methods);
+			enumConstantLoop: for (; index < fieldsLength; index++) {
+				final IFieldInfo fieldInfo = fields[index];
+				final int accessFlags = fieldInfo.getAccessFlags();
+				if ((accessFlags & IModifierConstants.ACC_ENUM) != 0) {
+					writeNewLine(buffer, lineSeparator, tabNumber);
+					disassembleEnumConstants(fields[index], buffer, lineSeparator, tabNumber, constructorArguments, mode);
+				} else {
+					break enumConstantLoop;
+				}
+			}
+			buffer.append(';');
+			boolean foundSyntheticField = false;
+			fieldLoop: for (; index < fieldsLength; index++) {
+				if (!foundSyntheticField && CharOperation.equals(TypeConstants.SYNTHETIC_ENUM_VALUES, fields[index].getName())) {
+					foundSyntheticField = true;
+					continue fieldLoop;
+				}
+				writeNewLine(buffer, lineSeparator, tabNumber);
+				disassemble(fields[index], buffer, lineSeparator, tabNumber, mode);
+			}
+			methodLoop: for (int i = 0, max = methods.length; i < max; i++) {
+				final IMethodInfo methodInfo = methods[i];
+				if (CharOperation.equals(methodInfo.getName(), TypeConstants.VALUES)) {
+					final char[] descriptor = methodInfo.getDescriptor();
+					CharOperation.replace(descriptor, '/', '.');
+					if (Signature.getParameterCount(descriptor) == 0) {
+						if (CharOperation.equals(returnClassName(Signature.getReturnType(descriptor), '.', mode),
+								CharOperation.concat(new char[] {'[', 'L'}, className, new char[] {';'}))) {
+							continue methodLoop;
+						}
+					}
+				} else if (CharOperation.equals(methodInfo.getName(), TypeConstants.VALUEOF)) {
+					final char[] descriptor = methodInfo.getDescriptor();
+					CharOperation.replace(descriptor, '/', '.');
+					final char[][] parameterTypes = Signature.getParameterTypes(descriptor);
+					if (parameterTypes.length == 1
+							&& CharOperation.equals(parameterTypes[0], "Ljava.lang.String;".toCharArray())) { //$NON-NLS-1$
+						if (CharOperation.equals(returnClassName(Signature.getReturnType(descriptor), '.', mode),
+								CharOperation.concat('L', className, ';'))) {
+							continue methodLoop;
+						}
+					}
+				} else if (methodInfo.isClinit() || methodInfo.isSynthetic()) {
+					continue methodLoop;
+				} else if (methodInfo.isConstructor()) {
+					writeNewLine(buffer, lineSeparator, tabNumber);
+					disassembleEnumConstructor(classFileReader, className, methodInfo, buffer, lineSeparator, tabNumber, mode);
+				} else {
+					writeNewLine(buffer, lineSeparator, tabNumber);
+					disassemble(classFileReader, className, methodInfo, buffer, lineSeparator, tabNumber, mode);
+				}
+			}
+		} else {
+			for (int i = 0, max = fields.length; i < max; i++) {
+				writeNewLine(buffer, lineSeparator, tabNumber);
+				disassemble(fields[i], buffer, lineSeparator, tabNumber, mode);
+			}
+			IMethodInfo[] methods = classFileReader.getMethodInfos();
+			for (int i = 0, max = methods.length; i < max; i++) {
+				writeNewLine(buffer, lineSeparator, tabNumber);
+				disassemble(classFileReader, className, methods[i], buffer, lineSeparator, tabNumber, mode);
+			}
+		}
+	}
+
+	private char[][] getConstructorArgumentsForEnum(final IMethodInfo[] methods) {
+		loop: for (int i = 0, max = methods.length; i < max; i++) {
+			IMethodInfo methodInfo = methods[i];
+			if (methodInfo.isConstructor()) {
+				char[][] parameterTypes = Signature.getParameterTypes(methodInfo.getDescriptor());
+				final int length = parameterTypes.length;
+				if (length >= 2) {
+					return CharOperation.subarray(parameterTypes, 2, length);
+				}
+			} else {
+				continue loop;
+			}
+		}
+		return null;
+	}
+
+	private final void dumpTab(int tabNumber, StringBuffer buffer) {
+		for (int i = 0; i < tabNumber; i++) {
+			buffer.append(Messages.disassembler_indentation);
+		}
+	}
+
+	private final String dumpNewLineWithTabs(String lineSeparator, int tabNumber) {
+		StringBuffer buffer = new StringBuffer();
+		writeNewLine(buffer, lineSeparator, tabNumber);
+		return String.valueOf(buffer);
+	}
+
+	/**
+	 * @see org.eclipse.jdt.core.util.ClassFileBytesDisassembler#getDescription()
+	 */
+	public String getDescription() {
+		return Messages.disassembler_description;
+	}
+
+	private IEnclosingMethodAttribute getEnclosingMethodAttribute(IClassFileReader classFileReader) {
+		IClassFileAttribute[] attributes = classFileReader.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), IAttributeNamesConstants.ENCLOSING_METHOD)) {
+				return (IEnclosingMethodAttribute) attributes[i];
+			}
+		}
+		return null;
+	}
+	private IClassFileAttribute getAttribute(final char[] attributeName, final ICodeAttribute codeAttribute) {
+		IClassFileAttribute[] attributes = codeAttribute.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), attributeName)) {
+				return attributes[i];
+			}
+		}
+		return null;
+	}
+
+	private char[][] getParameterNames(char[] methodDescriptor, ICodeAttribute codeAttribute, int accessFlags) {
+		int paramCount = Signature.getParameterCount(methodDescriptor);
+		char[][] parameterNames = new char[paramCount][];
+		// check if the code attribute has debug info for this method
+		if (codeAttribute != null) {
+			ILocalVariableAttribute localVariableAttribute = codeAttribute.getLocalVariableAttribute();
+			if (localVariableAttribute != null) {
+				ILocalVariableTableEntry[] entries = localVariableAttribute.getLocalVariableTable();
+				final int startingIndex = (accessFlags & IModifierConstants.ACC_STATIC) != 0 ? 0 : 1;
+				for (int i = 0; i < paramCount; i++) {
+					ILocalVariableTableEntry searchedEntry = getEntryFor(getLocalIndex(startingIndex, i, methodDescriptor), entries);
+					if (searchedEntry != null) {
+						parameterNames[i] = searchedEntry.getName();
+					} else {
+						parameterNames[i] = CharOperation.concat(Messages.disassembler_parametername.toCharArray(), Integer.toString(i).toCharArray());
+					}
+				}
+			} else {
+				for (int i = 0; i < paramCount; i++) {
+					parameterNames[i] = CharOperation.concat(Messages.disassembler_parametername.toCharArray(), Integer.toString(i).toCharArray());
+				}
+			}
+		} else {
+			for (int i = 0; i < paramCount; i++) {
+				parameterNames[i] = CharOperation.concat(Messages.disassembler_parametername.toCharArray(), Integer.toString(i).toCharArray());
+			}
+		}
+		return parameterNames;
+	}
+
+	private int getLocalIndex(final int startingSlot, final int index, final char[] methodDescriptor) {
+		int slot = startingSlot;
+		final char[][] types = Signature.getParameterTypes(methodDescriptor);
+		for (int i = 0; i < index; i++) {
+			final char[] type = types[i];
+			switch(type.length) {
+				case 1 :
+					switch(type[0]) {
+						case 'D' :
+						case 'J' :
+							slot += 2;
+							break;
+						default :
+							slot++;
+					}
+					break;
+				default :
+					slot++;
+			}
+		}
+		return slot;
+	}
+
+	private ILocalVariableTableEntry getEntryFor(final int index, final ILocalVariableTableEntry[] entries) {
+		for (int i = 0, max = entries.length; i < max; i++) {
+			ILocalVariableTableEntry entry = entries[i];
+			if (index == entry.getIndex()) {
+				return entry;
+			}
+		}
+		return null;
+	}
+
+	private char[] getSignatureForField(char[] fieldDescriptor) {
+		char[] newFieldDescriptor = CharOperation.replaceOnCopy(fieldDescriptor, '/', '.');
+		newFieldDescriptor = CharOperation.replaceOnCopy(newFieldDescriptor, '$', '%');
+		char[] fieldDescriptorSignature = Signature.toCharArray(newFieldDescriptor);
+		CharOperation.replace(fieldDescriptorSignature, '%', '$');
+		return fieldDescriptorSignature;
+	}
+
+	private boolean isDeprecated(IClassFileReader classFileReader) {
+		IClassFileAttribute[] attributes = classFileReader.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), IAttributeNamesConstants.DEPRECATED)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean isSynthetic(IClassFileReader classFileReader) {
+		int flags = classFileReader.getAccessFlags();
+		if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) {
+			return true;
+		}
+		IClassFileAttribute[] attributes = classFileReader.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), IAttributeNamesConstants.SYNTHETIC)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean checkMode(int mode, int flag) {
+		return (mode & flag) != 0;
+	}
+
+	private boolean isCompact(int mode) {
+		return (mode & ClassFileBytesDisassembler.COMPACT) != 0;
+	}
+
+	private char[] returnClassName(char[] classInfoName, char separator, int mode) {
+		if (classInfoName.length == 0) {
+			return CharOperation.NO_CHAR;
+		} else if (isCompact(mode)) {
+			int lastIndexOfSlash = CharOperation.lastIndexOf(separator, classInfoName);
+			if (lastIndexOfSlash != -1) {
+				return CharOperation.subarray(classInfoName, lastIndexOfSlash + 1, classInfoName.length);
+			}
+		}
+		return classInfoName;
+	}
+
+	private void writeNewLine(StringBuffer buffer, String lineSeparator, int tabNumber) {
+		buffer.append(lineSeparator);
+		dumpTab(tabNumber, buffer);
+	}
+	
+	private String toTypePathString(int[][] typepath) {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append('[');
+		for (int i = 0, max = typepath.length; i < max; i++) {
+			int[] typepathElement = typepath[i];
+			if (i > 0) {
+				buffer.append(',').append(' ');
+			}
+			switch (typepathElement[0]) {
+				case IExtendedAnnotationConstants.TYPE_PATH_DEEPER_IN_ARRAY:
+					buffer.append(Messages.disassembler_extendedannotation_typepath_array);
+					break;
+				case IExtendedAnnotationConstants.TYPE_PATH_DEEPER_IN_INNER_TYPE:
+					buffer.append(Messages.disassembler_extendedannotation_typepath_innertype);
+					break;
+				case IExtendedAnnotationConstants.TYPE_PATH_ANNOTATION_ON_WILDCARD_BOUND:
+					buffer.append(Messages.disassembler_extendedannotation_typepath_wildcard);
+					break;
+				case IExtendedAnnotationConstants.TYPE_PATH_TYPE_ARGUMENT_INDEX:
+					buffer.append(
+							Messages.bind(Messages.disassembler_extendedannotation_typepath_typeargument,
+								new String[] {
+									Integer.toString(typepathElement[1])
+								}));
+					break;
+				default:
+					throw new IllegalStateException("Unrecognized type_path_kind: "+typepathElement[0]); //$NON-NLS-1$
+			}
+		}
+		buffer.append(']');
+		return String.valueOf(buffer);	
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java
new file mode 100644
index 0000000..f3c3dbd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IEnclosingMethodAttribute;
+
+/**
+ * Default implementation of EnclosingMethodAttribute.
+ *
+ * @since 3.0
+ */
+public class EnclosingMethodAttribute extends ClassFileAttribute implements IEnclosingMethodAttribute {
+
+	private int enclosingClassIndex;
+	private char[] enclosingClassName;
+	private int methodDescriptorIndex;
+	private char[] methodDescriptor;
+	private int methodNameIndex;
+	private char[] methodName;
+	private int methodNameAndTypeIndex;
+
+	EnclosingMethodAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		int index = u2At(classFileBytes, 6, offset);
+		this.enclosingClassIndex = index;
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.enclosingClassName = constantPoolEntry.getClassInfoName();
+		this.methodNameAndTypeIndex = u2At(classFileBytes, 8, offset);
+		if (this.methodNameAndTypeIndex != 0) {
+			constantPoolEntry = constantPool.decodeEntry(this.methodNameAndTypeIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_NameAndType) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.methodDescriptorIndex = constantPoolEntry.getNameAndTypeInfoDescriptorIndex();
+			this.methodNameIndex = constantPoolEntry.getNameAndTypeInfoNameIndex();
+			constantPoolEntry = constantPool.decodeEntry(this.methodDescriptorIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.methodDescriptor = constantPoolEntry.getUtf8Value();
+			constantPoolEntry = constantPool.decodeEntry(this.methodNameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.methodName = constantPoolEntry.getUtf8Value();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getEnclosingClass()
+	 */
+	public char[] getEnclosingClass() {
+		return this.enclosingClassName;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDeclaringClassDescriptorIndex()
+	 */
+	public int getEnclosingClassIndex() {
+		return this.enclosingClassIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDescriptor()
+	 */
+	public char[] getMethodDescriptor() {
+		return this.methodDescriptor;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDescriptorIndex()
+	 */
+	public int getMethodDescriptorIndex() {
+		return this.methodDescriptorIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodName()
+	 */
+	public char[] getMethodName() {
+		return this.methodName;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodNameIndex()
+	 */
+	public int getMethodNameIndex() {
+		return this.methodNameIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodNameAndTypeIndex()
+	 */
+	public int getMethodNameAndTypeIndex() {
+		return this.methodNameAndTypeIndex;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java
new file mode 100644
index 0000000..c0ee905
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IExceptionAttribute;
+
+/**
+ * Default implementation of IExceptionAttribute.
+ */
+public class ExceptionAttribute extends ClassFileAttribute implements IExceptionAttribute {
+	private int exceptionsNumber;
+	private char[][] exceptionNames;
+	private int[] exceptionIndexes;
+
+	ExceptionAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.exceptionsNumber = u2At(classFileBytes, 6, offset);
+		int exceptionLength = this.exceptionsNumber;
+		this.exceptionNames = CharOperation.NO_CHAR_CHAR;
+		this.exceptionIndexes = org.eclipse.jdt.internal.compiler.util.Util.EMPTY_INT_ARRAY;
+		if (exceptionLength != 0) {
+			this.exceptionNames = new char[exceptionLength][];
+			this.exceptionIndexes = new int[exceptionLength];
+		}
+		int readOffset = 8;
+		IConstantPoolEntry constantPoolEntry;
+		for (int i = 0; i < exceptionLength; i++) {
+			this.exceptionIndexes[i] = u2At(classFileBytes, readOffset, offset);
+			constantPoolEntry = constantPool.decodeEntry(this.exceptionIndexes[i]);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.exceptionNames[i] = constantPoolEntry.getClassInfoName();
+			readOffset += 2;
+		}
+	}
+
+	/**
+	 * @see IExceptionAttribute#getExceptionIndexes()
+	 */
+	public int[] getExceptionIndexes() {
+		return this.exceptionIndexes;
+	}
+
+	/**
+	 * @see IExceptionAttribute#getExceptionNames()
+	 */
+	public char[][] getExceptionNames() {
+		return this.exceptionNames;
+	}
+
+	/**
+	 * @see IExceptionAttribute#getExceptionsNumber()
+	 */
+	public int getExceptionsNumber() {
+		return this.exceptionsNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java
new file mode 100644
index 0000000..0edb18b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IExceptionTableEntry;
+
+/**
+ * This class describes an entry in the exception table attribute according
+ * to the JVM specifications.
+ */
+public class ExceptionTableEntry
+	extends ClassFileStruct
+	implements IExceptionTableEntry {
+
+	private int startPC;
+	private int endPC;
+	private int handlerPC;
+	private int catchTypeIndex;
+	private char[] catchType;
+
+	ExceptionTableEntry(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		this.startPC = u2At(classFileBytes, 0, offset);
+		this.endPC = u2At(classFileBytes, 2, offset);
+		this.handlerPC = u2At(classFileBytes, 4, offset);
+		this.catchTypeIndex = u2At(classFileBytes, 6, offset);
+		if (this.catchTypeIndex != 0) {
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.catchTypeIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.catchType = constantPoolEntry.getClassInfoName();
+		}
+	}
+	/**
+	 * @see IExceptionTableEntry#getStartPC()
+	 */
+	public int getStartPC() {
+		return this.startPC;
+	}
+
+	/**
+	 * @see IExceptionTableEntry#getEndPC()
+	 */
+	public int getEndPC() {
+		return this.endPC;
+	}
+
+	/**
+	 * @see IExceptionTableEntry#getHandlerPC()
+	 */
+	public int getHandlerPC() {
+		return this.handlerPC;
+	}
+
+	/**
+	 * @see IExceptionTableEntry#getCatchTypeIndex()
+	 */
+	public int getCatchTypeIndex() {
+		return this.catchTypeIndex;
+	}
+
+	/**
+	 * @see IExceptionTableEntry#getCatchType()
+	 */
+	public char[] getCatchType() {
+		return this.catchType;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
new file mode 100644
index 0000000..902b329
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExtendedAnnotation.java
@@ -0,0 +1,296 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotationComponent;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IExtendedAnnotation;
+import org.eclipse.jdt.core.util.IExtendedAnnotationConstants;
+import org.eclipse.jdt.core.util.ILocalVariableReferenceInfo;
+
+/* http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf
+ type_annotation {
+   // New fields in JSR 308:
+   u1 target_type; // the type of the targeted program element, see Section 3.2
+   union {
+     type_parameter_target;
+     supertype_target;
+     type_parameter_bound_target;
+     empty_target;
+     method_formal_parameter_target;
+     throws_target;
+     localvar_target;
+     catch_target;
+     offset_target;
+     type_argument_target;
+     method_reference_target;
+   } target_info; // identifies the targeted program element, see Section 3.3
+   type_path target_path; // identifies targeted type in a compound type (array, generic, etc.), see Section 3.4
+   // Original fields from "annotation" structure:
+   u2 type_index;
+   u2 num_element_value_pairs;
+   {
+     u2 element_name_index;
+     element_value value;
+   } element_value_pairs[num_element_value_pairs];
+*/
+/**
+ * @since 3.9 BETA_JAVA8
+ */
+public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnnotation {
+
+	private static final IAnnotationComponent[] NO_ENTRIES = new IAnnotationComponent[0];
+	private final static int[][] NO_TYPEPATH = new int[0][0];
+
+	private int targetType;
+	private int annotationTypeIndex;
+	private int[][] typePath;
+
+	private int typeIndex;
+	private char[] typeName;
+	private int componentsNumber;
+	private IAnnotationComponent[] components;
+	private int readOffset;
+	private int offset;
+	private int typeParameterIndex;
+	private int typeParameterBoundIndex;
+	private int parameterIndex;
+	private int exceptionTableIndex;
+	private ILocalVariableReferenceInfo[] localVariableTable;
+	
+	/**
+	 * Constructor for ExtendedAnnotation, builds an annotation from the supplied bytestream.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public ExtendedAnnotation(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+
+		// Read target_type
+		int index = u1At(classFileBytes,0,offset);
+		this.targetType = index;
+		this.readOffset = 1;
+		
+		readTargetInfo(index, classFileBytes, constantPool, offset);
+
+		// Read type_path
+		index = u1At(classFileBytes, this.readOffset, offset);
+		this.readOffset++;
+		int typePathEntryCount = index;
+		if (typePathEntryCount == 0) {
+			this.typePath = NO_TYPEPATH;
+		} else {
+			this.typePath = new int[typePathEntryCount][];
+			for (int i = 0; i < typePathEntryCount; i++) {
+				int[] typePathEntry = (this.typePath[i] = new int[2]);
+				typePathEntry[0] = u1At(classFileBytes, this.readOffset++, offset);
+				typePathEntry[1] = u1At(classFileBytes, this.readOffset++, offset);
+			}
+		}
+		
+		// Read annotation
+		index = u2At(classFileBytes, this.readOffset, offset);
+		this.typeIndex = index;
+		this.readOffset+=2;
+		if (index != 0) {
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.typeName = constantPoolEntry.getUtf8Value();
+		} else {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		final int length = u2At(classFileBytes, this.readOffset, offset);
+		this.componentsNumber = length;
+		this.readOffset+=2;
+		if (length != 0) {
+			this.components = new IAnnotationComponent[length];
+			for (int i = 0; i < length; i++) {
+				AnnotationComponent component = new AnnotationComponent(classFileBytes, constantPool, offset + this.readOffset);
+				this.components[i] = component;
+				this.readOffset += component.sizeInBytes();
+			}
+		} else {
+			this.components = NO_ENTRIES;
+		}
+		if (this.annotationTypeIndex == 0xFFFF) {
+			this.annotationTypeIndex = -1;
+		}
+	}
+	
+	private void readTargetInfo(
+			int localTargetType,
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int localOffset) throws ClassFormatException {
+		switch(localTargetType) {
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
+				this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset++;
+				break;
+
+			case IExtendedAnnotationConstants.CLASS_EXTENDS :
+				this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset+=2;
+				break;
+
+			case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
+			case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
+				this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset++;
+				this.typeParameterBoundIndex = u1At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset++;
+				break;
+				
+			case IExtendedAnnotationConstants.FIELD :
+			case IExtendedAnnotationConstants.METHOD_RETURN :
+			case IExtendedAnnotationConstants.METHOD_RECEIVER :
+				// nothing to do, target_info is empty_target
+				break;
+				
+			case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
+				this.parameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset++;
+				break;
+				
+			case IExtendedAnnotationConstants.THROWS :
+				this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset+=2;
+				break;
+
+				
+			case IExtendedAnnotationConstants.LOCAL_VARIABLE :
+			case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
+				int tableLength = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset += 2;
+				this.localVariableTable = new LocalVariableReferenceInfo[tableLength];
+				for (int i = 0; i < tableLength; i++) {
+					this.localVariableTable[i] = new LocalVariableReferenceInfo(classFileBytes, constantPool, this.readOffset + localOffset);
+					this.readOffset += 6;
+				}
+				break;
+
+			case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
+				this.exceptionTableIndex = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset += 2;
+				break;
+
+			case IExtendedAnnotationConstants.NEW :
+			case IExtendedAnnotationConstants.INSTANCEOF :
+			case IExtendedAnnotationConstants.METHOD_REFERENCE :
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
+				this.offset = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset += 2;
+				break;	
+
+			case IExtendedAnnotationConstants.CAST :
+				this.offset = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset += 3; // skipping the 3rd byte which will be 0 for CAST
+				break;
+
+			case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
+			case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
+				this.offset = u2At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset += 2;
+				// read type_argument_index
+				this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
+				this.readOffset++;
+				break;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getTypeIndex()
+	 */
+	public int getTypeIndex() {
+		return this.typeIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getComponentsNumber()
+	 */
+	public int getComponentsNumber() {
+		return this.componentsNumber;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getComponents()
+	 */
+	public IAnnotationComponent[] getComponents() {
+		return this.components;
+	}
+
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IAnnotation#getTypeName()
+	 */
+	public char[] getTypeName() {
+		return this.typeName;
+	}
+
+	public int getTargetType() {
+		return this.targetType;
+	}
+	
+	public int getExceptionTableIndex() {
+		return this.exceptionTableIndex;
+	}
+
+	public int getOffset() {
+		return this.offset;
+	}
+
+	public int getLocalVariableRefenceInfoLength() {
+		return this.localVariableTable != null ? this.localVariableTable.length : 0;
+	}
+
+	public ILocalVariableReferenceInfo[] getLocalVariableTable() {
+		return this.localVariableTable;
+	}
+
+	public int getParameterIndex() {
+		return this.parameterIndex;
+	}
+
+	public int getTypeParameterIndex() {
+		return this.typeParameterIndex;
+	}
+
+	public int getTypeParameterBoundIndex() {
+		return this.typeParameterBoundIndex;
+	}
+
+	public int[][] getTypePath() {
+		return this.typePath;
+	}
+
+	public int getAnnotationTypeIndex() {
+		return this.annotationTypeIndex;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java
new file mode 100644
index 0000000..455b42e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAttributeNamesConstants;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IConstantValueAttribute;
+import org.eclipse.jdt.core.util.IFieldInfo;
+import org.eclipse.jdt.core.util.IModifierConstants;
+
+/**
+ * Default implementation of IFieldInfo.
+ */
+public class FieldInfo extends ClassFileStruct implements IFieldInfo {
+	private int accessFlags;
+	private int attributeBytes;
+	private IClassFileAttribute[] attributes;
+	private int attributesCount;
+	private IConstantValueAttribute constantValueAttribute;
+	private char[] descriptor;
+	private int descriptorIndex;
+	private boolean isDeprecated;
+	private boolean isSynthetic;
+	private char[] name;
+	private int nameIndex;
+
+	/**
+	 * @param classFileBytes byte[]
+	 * @param constantPool IConstantPool
+	 * @param offset int
+	 */
+	public FieldInfo(byte classFileBytes[], IConstantPool constantPool, int offset)
+		throws ClassFormatException {
+		final int flags = u2At(classFileBytes, 0, offset);
+		this.accessFlags = flags;
+		if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) {
+			this.isSynthetic = true;
+		}
+		this.nameIndex = u2At(classFileBytes, 2, offset);
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.name = constantPoolEntry.getUtf8Value();
+
+		this.descriptorIndex = u2At(classFileBytes, 4, offset);
+		constantPoolEntry = constantPool.decodeEntry(this.descriptorIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.descriptor = constantPoolEntry.getUtf8Value();
+
+		this.attributesCount = u2At(classFileBytes, 6, offset);
+		this.attributes = ClassFileAttribute.NO_ATTRIBUTES;
+		int readOffset = 8;
+		if (this.attributesCount != 0) {
+			this.attributes = new IClassFileAttribute[this.attributesCount];
+		}
+		int attributesIndex = 0;
+		for (int i = 0; i < this.attributesCount; i++) {
+			constantPoolEntry = constantPool.decodeEntry(u2At(classFileBytes, readOffset, offset));
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			char[] attributeName = constantPoolEntry.getUtf8Value();
+			if (equals(attributeName, IAttributeNamesConstants.DEPRECATED)) {
+				this.isDeprecated = true;
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.SYNTHETIC)) {
+				this.isSynthetic = true;
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.CONSTANT_VALUE)) {
+				this.constantValueAttribute = new ConstantValueAttribute(classFileBytes, constantPool, offset + readOffset);
+				this.attributes[attributesIndex++] = this.constantValueAttribute;
+			} else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) {
+				this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else {
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			}
+			readOffset += (6 + u4At(classFileBytes, readOffset + 2, offset));
+		}
+
+		this.attributeBytes = readOffset;
+	}
+	/**
+	 * @see IFieldInfo#getAccessFlags()
+	 */
+	public int getAccessFlags() {
+		return this.accessFlags;
+	}
+	/**
+	 * @see IFieldInfo#getAttributeCount()
+	 */
+	public int getAttributeCount() {
+		return this.attributesCount;
+	}
+
+	/**
+	 * @see IFieldInfo#getAttributes()
+	 */
+	public IClassFileAttribute[] getAttributes() {
+		return this.attributes;
+	}
+
+	/**
+	 * @see IFieldInfo#getConstantValueAttribute()
+	 */
+	public IConstantValueAttribute getConstantValueAttribute() {
+		return this.constantValueAttribute;
+	}
+
+	/**
+	 * @see IFieldInfo#getDescriptor()
+	 */
+	public char[] getDescriptor() {
+		return this.descriptor;
+	}
+
+	/**
+	 * @see IFieldInfo#getDescriptorIndex()
+	 */
+	public int getDescriptorIndex() {
+		return this.descriptorIndex;
+	}
+
+	/**
+	 * @see IFieldInfo#getName()
+	 */
+	public char[] getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see IFieldInfo#getNameIndex()
+	 */
+	public int getNameIndex() {
+		return this.nameIndex;
+	}
+	/**
+	 * @see IFieldInfo#hasConstantValueAttribute()
+	 */
+	public boolean hasConstantValueAttribute() {
+		return this.constantValueAttribute != null;
+	}
+
+	/**
+	 * @see IFieldInfo#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		return this.isDeprecated;
+	}
+
+	/**
+	 * @see IFieldInfo#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return this.isSynthetic;
+	}
+
+	int sizeInBytes() {
+		return this.attributeBytes;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
new file mode 100644
index 0000000..c77b9d0
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.search.AbstractJavaSearchScope;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Creates java element handles.
+ */
+public class HandleFactory {
+
+	/**
+	 * Cache package fragment root information to optimize speed performance.
+	 */
+	private String lastPkgFragmentRootPath;
+	private PackageFragmentRoot lastPkgFragmentRoot;
+
+	/**
+	 * Cache package handles to optimize memory.
+	 */
+	private HashtableOfArrayToObject packageHandles;
+
+	private JavaModel javaModel;
+
+	public HandleFactory() {
+		this.javaModel = JavaModelManager.getJavaModelManager().getJavaModel();
+	}
+
+
+	/**
+	 * Creates an Openable handle from the given resource path.
+	 * The resource path can be a path to a file in the workbench (e.g. /Proj/com/ibm/jdt/core/HandleFactory.java)
+	 * or a path to a file in a jar file - it then contains the path to the jar file and the path to the file in the jar
+	 * (e.g. c:/jdk1.2.2/jre/lib/rt.jar|java/lang/Object.class or /Proj/rt.jar|java/lang/Object.class)
+	 * NOTE: This assumes that the resource path is the toString() of an IPath,
+	 *       in other words, it uses the IPath.SEPARATOR for file path
+	 *            and it uses '/' for entries in a zip file.
+	 * If not null, uses the given scope as a hint for getting Java project handles.
+	 */
+	public Openable createOpenable(String resourcePath, IJavaSearchScope scope) {
+		int separatorIndex;
+		if ((separatorIndex= resourcePath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR)) > -1) {
+			// path to a class file inside a jar
+			// Optimization: cache package fragment root handle and package handles
+			int rootPathLength;
+			if (this.lastPkgFragmentRootPath == null
+					|| (rootPathLength = this.lastPkgFragmentRootPath.length()) != resourcePath.length()
+					|| !resourcePath.regionMatches(0, this.lastPkgFragmentRootPath, 0, rootPathLength)) {
+				String jarPath= resourcePath.substring(0, separatorIndex);
+				PackageFragmentRoot root= getJarPkgFragmentRoot(resourcePath, separatorIndex, jarPath, scope);
+				if (root == null)
+					return null; // match is outside classpath
+				this.lastPkgFragmentRootPath= jarPath;
+				this.lastPkgFragmentRoot= root;
+				this.packageHandles= new HashtableOfArrayToObject(5);
+			}
+			// create handle
+			String classFilePath= resourcePath.substring(separatorIndex + 1);
+			String[] simpleNames = new Path(classFilePath).segments();
+			String[] pkgName;
+			int length = simpleNames.length-1;
+			if (length > 0) {
+				pkgName = new String[length];
+				System.arraycopy(simpleNames, 0, pkgName, 0, length);
+			} else {
+				pkgName = CharOperation.NO_STRINGS;
+			}
+			IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
+			if (pkgFragment == null) {
+				pkgFragment= this.lastPkgFragmentRoot.getPackageFragment(pkgName);
+				this.packageHandles.put(pkgName, pkgFragment);
+			}
+			IClassFile classFile= pkgFragment.getClassFile(simpleNames[length]);
+			return (Openable) classFile;
+		} else {
+			// path to a file in a directory
+			// Optimization: cache package fragment root handle and package handles
+			int rootPathLength = -1;
+			if (this.lastPkgFragmentRootPath == null
+				|| !(resourcePath.startsWith(this.lastPkgFragmentRootPath)
+					&& !org.eclipse.jdt.internal.compiler.util.Util.isExcluded(resourcePath.toCharArray(), this.lastPkgFragmentRoot.fullInclusionPatternChars(), this.lastPkgFragmentRoot.fullExclusionPatternChars(), false)
+					&& (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0
+					&& resourcePath.charAt(rootPathLength) == '/')) {
+				PackageFragmentRoot root= getPkgFragmentRoot(resourcePath);
+				if (root == null)
+					return null; // match is outside classpath
+				this.lastPkgFragmentRoot = root;
+				this.lastPkgFragmentRootPath = this.lastPkgFragmentRoot.internalPath().toString();
+				this.packageHandles = new HashtableOfArrayToObject(5);
+			}
+			// create handle
+			resourcePath = resourcePath.substring(this.lastPkgFragmentRootPath.length() + 1);
+			String[] simpleNames = new Path(resourcePath).segments();
+			String[] pkgName;
+			int length = simpleNames.length-1;
+			if (length > 0) {
+				pkgName = new String[length];
+				System.arraycopy(simpleNames, 0, pkgName, 0, length);
+			} else {
+				pkgName = CharOperation.NO_STRINGS;
+			}
+			IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
+			if (pkgFragment == null) {
+				pkgFragment= this.lastPkgFragmentRoot.getPackageFragment(pkgName);
+				this.packageHandles.put(pkgName, pkgFragment);
+			}
+			String simpleName= simpleNames[length];
+			if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(simpleName)) {
+				ICompilationUnit unit= pkgFragment.getCompilationUnit(simpleName);
+				return (Openable) unit;
+			} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(simpleName)){
+				IClassFile classFile= pkgFragment.getClassFile(simpleName);
+				return (Openable) classFile;
+			}
+			return null;
+		}
+	}
+
+	/**
+	 * Returns a handle denoting the class member identified by its scope.
+	 */
+	public IJavaElement createElement(ClassScope scope, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) {
+		return createElement(scope, scope.referenceContext.sourceStart, unit, existingElements, knownScopes);
+	}
+	/**
+	 * Create handle by adding child to parent obtained by recursing into parent scopes.
+	 */
+	private IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit, HashSet existingElements, HashMap knownScopes) {
+		IJavaElement newElement = (IJavaElement)knownScopes.get(scope);
+		if (newElement != null) return newElement;
+
+		switch(scope.kind) {
+			case Scope.COMPILATION_UNIT_SCOPE :
+				newElement = unit;
+				break;
+			case Scope.CLASS_SCOPE :
+				IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+				switch (parentElement.getElementType()) {
+					case IJavaElement.COMPILATION_UNIT :
+						newElement = ((ICompilationUnit)parentElement).getType(new String(scope.enclosingSourceType().sourceName));
+						break;
+					case IJavaElement.TYPE :
+						newElement = ((IType)parentElement).getType(new String(scope.enclosingSourceType().sourceName));
+						break;
+					case IJavaElement.FIELD :
+					case IJavaElement.INITIALIZER :
+					case IJavaElement.METHOD :
+					    IMember member = (IMember)parentElement;
+					    if (member.isBinary()) {
+					        return null;
+					    } else {
+							newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1);
+							// increment occurrence count if collision is detected
+							if (newElement != null) {
+								while (!existingElements.add(newElement)) ((SourceRefElement)newElement).occurrenceCount++;
+							}
+					    }
+						break;
+				}
+				if (newElement != null) {
+					knownScopes.put(scope, newElement);
+				}
+				break;
+			case Scope.METHOD_SCOPE :
+				IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+				MethodScope methodScope = (MethodScope) scope;
+				if (methodScope.isInsideInitializer()) {
+					// inside field or initializer, must find proper one
+					TypeDeclaration type = methodScope.referenceType();
+					int occurenceCount = 1;
+					int length = type.fields == null ? 0 : type.fields.length;
+					for (int i = 0; i < length; i++) {
+						FieldDeclaration field = type.fields[i];
+						if (field.declarationSourceStart <= elementPosition && elementPosition <= field.declarationSourceEnd) {
+							switch (field.getKind()) {
+								case AbstractVariableDeclaration.FIELD :
+								case AbstractVariableDeclaration.ENUM_CONSTANT :
+									newElement = parentType.getField(new String(field.name));
+									break;
+								case AbstractVariableDeclaration.INITIALIZER :
+									newElement = parentType.getInitializer(occurenceCount);
+									break;
+							}
+							break;
+						} else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
+							occurenceCount++;
+						}
+					}
+				} else {
+					// method element
+					AbstractMethodDeclaration method = methodScope.referenceMethod();
+					newElement = parentType.getMethod(new String(method.selector), Util.typeParameterSignatures(method));
+					if (newElement != null) {
+						knownScopes.put(scope, newElement);
+					}
+				}
+				break;
+			case Scope.BLOCK_SCOPE :
+				// standard block, no element per se
+				newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+				break;
+		}
+		return newElement;
+	}
+	/**
+	 * Returns the package fragment root that corresponds to the given jar path.
+	 * See createOpenable(...) for the format of the jar path string.
+	 * If not null, uses the given scope as a hint for getting Java project handles.
+	 */
+	private PackageFragmentRoot getJarPkgFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPathString, IJavaSearchScope scope) {
+
+		IPath jarPath= new Path(jarPathString);
+
+		Object target = JavaModel.getTarget(jarPath, false);
+		if (target instanceof IFile) {
+			// internal jar: is it on the classpath of its project?
+			//  e.g. org.eclipse.swt.win32/ws/win32/swt.jar
+			//        is NOT on the classpath of org.eclipse.swt.win32
+			IFile jarFile = (IFile)target;
+			JavaProject javaProject = (JavaProject) this.javaModel.getJavaProject(jarFile);
+			try {
+				IClasspathEntry entry = javaProject.getClasspathEntryFor(jarPath);
+				if (entry != null) {
+					return (PackageFragmentRoot) javaProject.getPackageFragmentRoot(jarFile);
+				}
+			} catch (JavaModelException e) {
+				// ignore and try to find another project
+			}
+		}
+
+		// walk projects in the scope and find the first one that has the given jar path in its classpath
+		IJavaProject[] projects;
+		if (scope != null) {
+			if (scope instanceof AbstractJavaSearchScope) {
+				PackageFragmentRoot root = (PackageFragmentRoot) ((AbstractJavaSearchScope) scope).packageFragmentRoot(resourcePathString, jarSeparatorIndex, jarPathString);
+				if (root != null)
+					return root;
+			} else {
+				IPath[] enclosingProjectsAndJars = scope.enclosingProjectsAndJars();
+				int length = enclosingProjectsAndJars.length;
+				projects = new IJavaProject[length];
+				int index = 0;
+				for (int i = 0; i < length; i++) {
+					IPath path = enclosingProjectsAndJars[i];
+					if (path.segmentCount() == 1) {
+						projects[index++] = this.javaModel.getJavaProject(path.segment(0));
+					}
+				}
+				if (index < length) {
+					System.arraycopy(projects, 0, projects = new IJavaProject[index], 0, index);
+				}
+				PackageFragmentRoot root = getJarPkgFragmentRoot(jarPath, target, projects);
+				if (root != null) {
+					return root;
+				}
+			}
+		}
+
+		// not found in the scope, walk all projects
+		try {
+			projects = this.javaModel.getJavaProjects();
+		} catch (JavaModelException e) {
+			// java model is not accessible
+			return null;
+		}
+		return getJarPkgFragmentRoot(jarPath, target, projects);
+	}
+
+	private PackageFragmentRoot getJarPkgFragmentRoot(
+		IPath jarPath,
+		Object target,
+		IJavaProject[] projects) {
+		for (int i= 0, projectCount= projects.length; i < projectCount; i++) {
+			try {
+				JavaProject javaProject= (JavaProject)projects[i];
+				IClasspathEntry classpathEnty = javaProject.getClasspathEntryFor(jarPath);
+				if (classpathEnty != null) {
+					if (target instanceof IFile) {
+						// internal jar
+						return (PackageFragmentRoot) javaProject.getPackageFragmentRoot((IFile)target);
+					} else {
+						// external jar
+						return (PackageFragmentRoot) javaProject.getPackageFragmentRoot0(jarPath);
+					}
+				}
+			} catch (JavaModelException e) {
+				// JavaModelException from getResolvedClasspath - a problem occurred while accessing project: nothing we can do, ignore
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the package fragment root that contains the given resource path.
+	 */
+	private PackageFragmentRoot getPkgFragmentRoot(String pathString) {
+
+		IPath path= new Path(pathString);
+		IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
+		for (int i= 0, max= projects.length; i < max; i++) {
+			try {
+				IProject project = projects[i];
+				if (!project.isAccessible()
+					|| !project.hasNature(JavaCore.NATURE_ID)) continue;
+				IJavaProject javaProject= this.javaModel.getJavaProject(project);
+				IPackageFragmentRoot[] roots= javaProject.getPackageFragmentRoots();
+				for (int j= 0, rootCount= roots.length; j < rootCount; j++) {
+					PackageFragmentRoot root= (PackageFragmentRoot)roots[j];
+					if (root.internalPath().isPrefixOf(path) && !Util.isExcluded(path, root.fullInclusionPatternChars(), root.fullExclusionPatternChars(), false)) {
+						return root;
+					}
+				}
+			} catch (CoreException e) {
+				// CoreException from hasNature - should not happen since we check that the project is accessible
+				// JavaModelException from getPackageFragmentRoots - a problem occured while accessing project: nothing we can do, ignore
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java
new file mode 100644
index 0000000..9c24905
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfArray.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * HashSet of Object[]
+ */
+public final class HashSetOfArray implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public Object[][] set;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashSetOfArray() {
+		this(13);
+	}
+
+	public HashSetOfArray(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.set = new Object[extraRoom][];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashSetOfArray result = (HashSetOfArray) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.set.length;
+		result.set = new Object[length][];
+		System.arraycopy(this.set, 0, result.set, 0, length);
+
+		return result;
+	}
+
+	public boolean contains(Object[] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		Object[] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	private int hashCode(Object[] element) {
+		return hashCode(element, element.length);
+	}
+
+	private int hashCode(Object[] element, int length) {
+		int hash = 0;
+		for (int i = length-1; i >= 0; i--)
+			hash = Util.combineHashCodes(hash, element[i].hashCode());
+		return hash & 0x7FFFFFFF;
+	}
+
+	public Object add(Object[] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		Object[] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array))
+				return this.set[index] = array;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.set[index] = array;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return array;
+	}
+
+	public Object remove(Object[] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		Object[] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && Util.equalArraysOrNull(currentArray, array)) {
+				Object existing = this.set[index];
+				this.elementSize--;
+				this.set[index] = null;
+				rehash();
+				return existing;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+
+		HashSetOfArray newHashSet = new HashSetOfArray(this.elementSize * 2);		// double the number of expected elements
+		Object[] currentArray;
+		for (int i = this.set.length; --i >= 0;)
+			if ((currentArray = this.set[i]) != null)
+				newHashSet.add(currentArray);
+
+		this.set = newHashSet.set;
+		this.threshold = newHashSet.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		Object[] element;
+		for (int i = 0, length = this.set.length; i < length; i++)
+			if ((element = this.set[i]) != null) {
+				buffer.append('{');
+				for (int j = 0, length2 = element.length; j < length2; j++) {
+					buffer.append(element[j]);
+					if (j != length2-1)
+						buffer.append(", "); //$NON-NLS-1$
+				}
+				buffer.append("}");  //$NON-NLS-1$
+				if (i != length-1)
+					buffer.append('\n');
+			}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfCharArrayArray.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfCharArrayArray.java
new file mode 100644
index 0000000..f5e5c8b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashSetOfCharArrayArray.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * HashSet of char[][]
+ */
+public final class HashSetOfCharArrayArray implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public char[][][] set;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashSetOfCharArrayArray() {
+		this(13);
+	}
+
+	public HashSetOfCharArrayArray(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.set = new char[extraRoom][][];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashSetOfCharArrayArray result = (HashSetOfCharArrayArray) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.set.length;
+		result.set = new char[length][][];
+		System.arraycopy(this.set, 0, result.set, 0, length);
+
+		return result;
+	}
+
+	public boolean contains(char[][] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		char[][] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && CharOperation.equals(currentArray, array))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	private int hashCode(char[][] element) {
+		return hashCode(element, element.length);
+	}
+
+	private int hashCode(char[][] element, int length) {
+		int hash = 0;
+		for (int i = length-1; i >= 0; i--)
+			hash = Util.combineHashCodes(hash, CharOperation.hashCode(element[i]));
+		return hash & 0x7FFFFFFF;
+	}
+
+	public char[][] add(char[][] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		char[][] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && CharOperation.equals(currentArray, array))
+				return this.set[index] = array;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.set[index] = array;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return array;
+	}
+
+	public char[][] remove(char[][] array) {
+		int length = this.set.length;
+		int index = hashCode(array) % length;
+		int arrayLength = array.length;
+		char[][] currentArray;
+		while ((currentArray = this.set[index]) != null) {
+			if (currentArray.length == arrayLength && CharOperation.equals(currentArray, array)) {
+				char[][] existing = this.set[index];
+				this.elementSize--;
+				this.set[index] = null;
+				rehash();
+				return existing;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+		HashSetOfCharArrayArray newHashSet = new HashSetOfCharArrayArray(this.elementSize * 2);		// double the number of expected elements
+		char[][] currentArray;
+		for (int i = this.set.length; --i >= 0;)
+			if ((currentArray = this.set[i]) != null)
+				newHashSet.add(currentArray);
+
+		this.set = newHashSet.set;
+		this.threshold = newHashSet.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, length = this.set.length; i < length; i++) {
+			char[][] arrayArray = this.set[i];
+			if (arrayArray != null) {
+				buffer.append("{"); //$NON-NLS-1$
+				for (int j = 0, length2 = arrayArray.length; j < length2; j++) {
+					char[] array = arrayArray[j];
+					buffer.append('{');
+					for (int k = 0, length3 = array.length; k < length3; k++) {
+						buffer.append('\'');
+						buffer.append(array[k]);
+						buffer.append('\'');
+						if (k != length3-1)
+							buffer.append(", "); //$NON-NLS-1$
+					}
+					buffer.append('}');
+					if (j != length2-1)
+						buffer.append(", "); //$NON-NLS-1$
+				}
+				buffer.append("}");  //$NON-NLS-1$
+				if (i != length-1)
+					buffer.append('\n');
+			}
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java
new file mode 100644
index 0000000..1f822d4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * Hashtable of {Object[] --> Object }
+ */
+public final class HashtableOfArrayToObject implements Cloneable {
+
+	// to avoid using Enumerations, walk the individual tables skipping nulls
+	public Object[][] keyTable;
+	public Object[] valueTable;
+
+	public int elementSize; // number of elements in the table
+	int threshold;
+
+	public HashtableOfArrayToObject() {
+		this(13);
+	}
+
+	public HashtableOfArrayToObject(int size) {
+
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.keyTable = new Object[extraRoom][];
+		this.valueTable = new Object[extraRoom];
+	}
+
+	public Object clone() throws CloneNotSupportedException {
+		HashtableOfArrayToObject result = (HashtableOfArrayToObject) super.clone();
+		result.elementSize = this.elementSize;
+		result.threshold = this.threshold;
+
+		int length = this.keyTable.length;
+		result.keyTable = new Object[length][];
+		System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
+
+		length = this.valueTable.length;
+		result.valueTable = new Object[length];
+		System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
+		return result;
+	}
+
+	public boolean containsKey(Object[] key) {
+		int length = this.keyTable.length;
+		int index = hashCode(key) % length;
+		int keyLength = key.length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArraysOrNull(currentKey, key))
+				return true;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return false;
+	}
+
+	public Object get(Object[] key) {
+		int length = this.keyTable.length;
+		int index = hashCode(key) % length;
+		int keyLength = key.length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArraysOrNull(currentKey, key))
+				return this.valueTable[index];
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	public int getIndex(Object[] key) {
+		int length = this.keyTable.length;
+		int index = hashCode(key) % length;
+		int keyLength = key.length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArraysOrNull(currentKey, key))
+				return index;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return -1;
+	}
+	
+	public Object[] getKey(Object[] key, int keyLength) {
+		int length = this.keyTable.length;
+		int index = hashCode(key, keyLength) % length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArrays(currentKey, key, keyLength))
+				return currentKey;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private int hashCode(Object[] element) {
+		return hashCode(element, element.length);
+	}
+
+	private int hashCode(Object[] element, int length) {
+		int hash = 0;
+		for (int i = length-1; i >= 0; i--)
+			hash = Util.combineHashCodes(hash, element[i].hashCode());
+		return hash & 0x7FFFFFFF;
+	}
+
+	public Object put(Object[] key, Object value) {
+		int length = this.keyTable.length;
+		int index = hashCode(key) % length;
+		int keyLength = key.length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArraysOrNull(currentKey, key))
+				return this.valueTable[index] = value;
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		this.keyTable[index] = key;
+		this.valueTable[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		return value;
+	}
+
+	public Object removeKey(Object[] key) {
+		int length = this.keyTable.length;
+		int index = hashCode(key) % length;
+		int keyLength = key.length;
+		Object[] currentKey;
+		while ((currentKey = this.keyTable[index]) != null) {
+			if (currentKey.length == keyLength && Util.equalArraysOrNull(currentKey, key)) {
+				Object value = this.valueTable[index];
+				this.elementSize--;
+				this.keyTable[index] = null;
+				this.valueTable[index] = null;
+				rehash();
+				return value;
+			}
+			if (++index == length) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+
+		HashtableOfArrayToObject newHashtable = new HashtableOfArrayToObject(this.elementSize * 2);		// double the number of expected elements
+		Object[] currentKey;
+		for (int i = this.keyTable.length; --i >= 0;)
+			if ((currentKey = this.keyTable[i]) != null)
+				newHashtable.put(currentKey, this.valueTable[i]);
+
+		this.keyTable = newHashtable.keyTable;
+		this.valueTable = newHashtable.valueTable;
+		this.threshold = newHashtable.threshold;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		Object[] element;
+		for (int i = 0, length = this.keyTable.length; i < length; i++)
+			if ((element = this.keyTable[i]) != null) {
+				buffer.append('{');
+				for (int j = 0, length2 = element.length; j < length2; j++) {
+					buffer.append(element[j]);
+					if (j != length2-1)
+						buffer.append(", "); //$NON-NLS-1$
+				}
+				buffer.append("} -> ");  //$NON-NLS-1$
+				buffer.append(this.valueTable[i]);
+				if (i != length-1)
+					buffer.append('\n');
+			}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java
new file mode 100644
index 0000000..02ccb74
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.Enumeration;
+
+/**
+ * The <code>ICacheEnumeration</code> is used to iterate over both the keys
+ * and values in an LRUCache.  The <code>getValue()</code> method returns the
+ * value of the last key to be retrieved using <code>nextElement()</code>.
+ * The <code>nextElement()</code> method must be called before the
+ * <code>getValue()</code> method.
+ *
+ * <p>The iteration can be made efficient by making use of the fact that values in
+ * the cache (instances of <code>LRUCacheEntry</code>), know their key.  For this reason,
+ * Hashtable lookups don't have to be made at each step of the iteration.
+ *
+ * <p>Modifications to the cache must not be performed while using the
+ * enumeration.  Doing so will lead to an illegal state.
+ *
+ * @see LRUCache
+ */
+public interface ICacheEnumeration extends Enumeration {
+	/**
+	 * Returns the value of the previously accessed key in the enumeration.
+	 * Must be called after a call to nextElement().
+	 *
+	 * @return Value of current cache entry
+	 */
+	public Object getValue();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java
new file mode 100644
index 0000000..29caa9e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * Types implementing this interface can occupy a variable amount of space
+ * in an LRUCache.  Cached items that do not implement this interface are
+ * considered to occupy one unit of space.
+ *
+ * @see LRUCache
+ */
+public interface ILRUCacheable {
+	/**
+	 * Returns the space the receiver consumes in an LRU Cache.  The default space
+	 * value is 1.
+	 *
+	 * @return int Amount of cache space taken by the receiver
+	 */
+	public int getCacheFootprint();
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java
new file mode 100644
index 0000000..d0699e9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IInnerClassesAttribute;
+import org.eclipse.jdt.core.util.IInnerClassesAttributeEntry;
+
+/**
+ * Default implementation of IInnerClassesAttribute.
+ */
+public class InnerClassesAttribute extends ClassFileAttribute implements IInnerClassesAttribute {
+	private static final IInnerClassesAttributeEntry[] NO_ENTRIES = new IInnerClassesAttributeEntry[0];
+
+	private int numberOfClasses;
+	private IInnerClassesAttributeEntry[] entries;
+	/**
+	 * Constructor for InnerClassesAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public InnerClassesAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.numberOfClasses = u2At(classFileBytes, 6, offset);
+		final int length = this.numberOfClasses;
+		if (length != 0) {
+			int readOffset = 8;
+			this.entries = new IInnerClassesAttributeEntry[length];
+			for (int i = 0; i < length; i++) {
+				this.entries[i] = new InnerClassesAttributeEntry(classFileBytes, constantPool, offset + readOffset);
+				readOffset += 8;
+			}
+		} else {
+			this.entries = NO_ENTRIES;
+		}
+	}
+
+	/**
+	 * @see IInnerClassesAttribute#getInnerClassAttributesEntries()
+	 */
+	public IInnerClassesAttributeEntry[] getInnerClassAttributesEntries() {
+		return this.entries;
+	}
+
+	/**
+	 * @see IInnerClassesAttribute#getNumberOfClasses()
+	 */
+	public int getNumberOfClasses() {
+		return this.numberOfClasses;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java
new file mode 100644
index 0000000..a05753a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IInnerClassesAttributeEntry;
+
+/**
+ * Default implementation of IInnerClassesAttributeEntry
+ */
+public class InnerClassesAttributeEntry
+	extends ClassFileStruct
+	implements IInnerClassesAttributeEntry {
+
+	private int innerClassNameIndex;
+	private int outerClassNameIndex;
+	private int innerNameIndex;
+	private char[] innerClassName;
+	private char[] outerClassName;
+	private char[] innerName;
+	private int accessFlags;
+
+	public InnerClassesAttributeEntry(byte classFileBytes[], IConstantPool constantPool, int offset)
+		throws ClassFormatException {
+		this.innerClassNameIndex = u2At(classFileBytes, 0, offset);
+		this.outerClassNameIndex = u2At(classFileBytes, 2, offset);
+		this.innerNameIndex = u2At(classFileBytes, 4, offset);
+		this.accessFlags = u2At(classFileBytes, 6, offset);
+		IConstantPoolEntry constantPoolEntry;
+		if (this.innerClassNameIndex != 0) {
+			constantPoolEntry = constantPool.decodeEntry(this.innerClassNameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.innerClassName = constantPoolEntry.getClassInfoName();
+		}
+		if (this.outerClassNameIndex != 0) {
+			constantPoolEntry = constantPool.decodeEntry(this.outerClassNameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.outerClassName = constantPoolEntry.getClassInfoName();
+		}
+		if (this.innerNameIndex != 0) {
+			constantPoolEntry = constantPool.decodeEntry(this.innerNameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.innerName = constantPoolEntry.getUtf8Value();
+		}
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getAccessFlags()
+	 */
+	public int getAccessFlags() {
+		return this.accessFlags;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getInnerClassName()
+	 */
+	public char[] getInnerClassName() {
+		return this.innerClassName;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getInnerClassNameIndex()
+	 */
+	public int getInnerClassNameIndex() {
+		return this.innerClassNameIndex;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getInnerName()
+	 */
+	public char[] getInnerName() {
+		return this.innerName;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getInnerNameIndex()
+	 */
+	public int getInnerNameIndex() {
+		return this.innerNameIndex;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getOuterClassName()
+	 */
+	public char[] getOuterClassName() {
+		return this.outerClassName;
+	}
+
+	/**
+	 * @see IInnerClassesAttributeEntry#getOuterClassNameIndex()
+	 */
+	public int getOuterClassNameIndex() {
+		return this.outerClassNameIndex;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/JavaElementFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/JavaElementFinder.java
new file mode 100644
index 0000000..461f656
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/JavaElementFinder.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IOpenable;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.*;
+
+public class JavaElementFinder extends BindingKeyParser {
+
+	private JavaProject project;
+	private WorkingCopyOwner owner;
+	public IJavaElement element;
+	public JavaModelException exception;
+	private ArrayList types = new ArrayList();
+
+	public JavaElementFinder(String key, JavaProject project, WorkingCopyOwner owner) {
+		super(key);
+		this.project = project;
+		this.owner = owner;
+	}
+
+	private JavaElementFinder(BindingKeyParser parser, JavaProject project, WorkingCopyOwner owner) {
+		super(parser);
+		this.project = project;
+		this.owner = owner;
+	}
+
+	public void consumeAnnotation() {
+		if (!(this.element instanceof IAnnotatable)) return;
+		int size = this.types.size();
+		if (size == 0) return;
+		IJavaElement annotationType = ((JavaElementFinder) this.types.get(size-1)).element;
+		this.element = ((IAnnotatable) this.element).getAnnotation(annotationType.getElementName());
+	}
+
+	public void consumeField(char[] fieldName) {
+		if (!(this.element instanceof IType)) return;
+		this.element = ((IType) this.element).getField(new String(fieldName));
+	}
+
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		try {
+			this.element = this.project.findType(new String(CharOperation.replaceOnCopy(fullyQualifiedName, '/', '.')), this.owner);
+		} catch (JavaModelException e) {
+			this.exception = e;
+		}
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+		if (this.element == null) return;
+		if (this.element instanceof BinaryType) {
+			int lastSlash = CharOperation.lastIndexOf('/', uniqueKey);
+			int end = CharOperation.indexOf(';', uniqueKey, lastSlash+1);
+			char[] localName = CharOperation.subarray(uniqueKey, lastSlash+1, end);
+			IPackageFragment pkg = (IPackageFragment) this.element.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
+			this.element = pkg.getClassFile(new String(localName) + SuffixConstants.SUFFIX_STRING_class);
+		} else {
+			int firstDollar = CharOperation.indexOf('$', uniqueKey);
+			int end = CharOperation.indexOf('$', uniqueKey, firstDollar+1);
+			if (end == -1)
+				end = CharOperation.indexOf(';', uniqueKey, firstDollar+1);
+			char[] sourceStart = CharOperation.subarray(uniqueKey, firstDollar+1, end);
+			int position = Integer.parseInt(new String(sourceStart));
+			try {
+				this.element = ((ITypeRoot) this.element.getOpenable()).getElementAt(position);
+			} catch (JavaModelException e) {
+				this.exception = e;
+			}
+		}
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		if (!(this.element instanceof IType)) return;
+		this.element = ((IType) this.element).getType(new String(simpleTypeName));
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		if (!(this.element instanceof IType)) return;
+		String[] parameterTypes = Signature.getParameterTypes(new String(signature));
+		IType type = (IType) this.element;
+		IMethod method = type.getMethod(new String(selector), parameterTypes);
+		IMethod[] methods = type.findMethods(method);
+		if (methods.length > 0)
+			this.element = methods[0];
+	}
+
+	public void consumePackage(char[] pkgName) {
+		pkgName = CharOperation.replaceOnCopy(pkgName, '/', '.');
+		try {
+			this.element = this.project.findPackageFragment(new String(pkgName));
+		} catch (JavaModelException e) {
+			this.exception = e;
+		}
+	}
+
+	public void consumeParser(BindingKeyParser parser) {
+		this.types.add(parser);
+	}
+
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		if (this.element == null) return;
+		IOpenable openable = this.element.getOpenable();
+		if (!(openable instanceof ICompilationUnit)) return;
+		this.element = ((ICompilationUnit) openable).getType(new String(simpleTypeName));
+	}
+
+	public void consumeTypeVariable(char[] position, char[] typeVariableName) {
+		if (this.element == null) return;
+		switch (this.element.getElementType()) {
+		case IJavaElement.TYPE:
+			this.element = ((IType) this.element).getTypeParameter(new String(typeVariableName));
+			break;
+		case IJavaElement.METHOD:
+			this.element = ((IMethod) this.element).getTypeParameter(new String(typeVariableName));
+			break;
+		}
+	}
+
+	public BindingKeyParser newParser() {
+		return new JavaElementFinder(this, this.project, this.owner);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
new file mode 100644
index 0000000..1d755e2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+public class KeyKind extends BindingKeyParser {
+
+	public static final int F_TYPE = 0x0001;
+	public static final int F_METHOD = 0x0002;
+	public static final int F_FIELD = 0x0004;
+	public static final int F_TYPE_PARAMETER = 0x0008;
+	public static final int F_LOCAL_VAR = 0x0010;
+	public static final int F_MEMBER = 0x0020;
+	public static final int F_LOCAL = 0x0040;
+	public static final int F_PARAMETERIZED_TYPE = 0x0080;
+	public static final int F_RAW_TYPE = 0x0100;
+	public static final int F_WILDCARD_TYPE = 0x0200;
+	public static final int F_PARAMETERIZED_METHOD = 0x0400;
+	public static final int F_CAPTURE = 0x0800;
+	public static final int F_CONSTRUCTOR = 0x1000;
+
+	public int flags = 0;
+	private KeyKind innerKeyKind;
+
+	public KeyKind(BindingKeyParser parser) {
+		super(parser);
+	}
+
+	public KeyKind(String key) {
+		super(key);
+	}
+
+	public void consumeBaseType(char[] baseTypeSig) {
+		this.flags |= F_TYPE;
+	}
+
+	public void consumeCapture(int position) {
+		this.flags |= F_CAPTURE;
+	}
+
+	public void consumeField(char[] fieldName) {
+		this.flags |= F_FIELD;
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+		this.flags |= F_LOCAL;
+	}
+
+	public void consumeLocalVar(char[] varName, int occurrenceCount) {
+		this.flags |= F_LOCAL_VAR;
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.flags |= F_MEMBER;
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		this.flags |= F_METHOD;
+		if (selector.length == 0)
+			this.flags |= F_CONSTRUCTOR;
+	}
+
+	public void consumeParameterizedGenericMethod() {
+		this.flags |= F_PARAMETERIZED_METHOD;
+	}
+
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		this.flags |= isRaw ? F_RAW_TYPE : F_PARAMETERIZED_TYPE;
+	}
+
+	public void consumeParser(BindingKeyParser parser) {
+		this.innerKeyKind = (KeyKind) parser;
+	}
+
+	public void consumeRawType() {
+		this.flags |= F_RAW_TYPE;
+	}
+
+	public void consumeTopLevelType() {
+		this.flags |= F_TYPE;
+	}
+
+	public void consumeTypeParameter(char[] typeParameterName) {
+		this.flags |= F_TYPE_PARAMETER;
+	}
+
+	public void consumeTypeWithCapture() {
+		this.flags = this.innerKeyKind.flags;
+	}
+
+	public void consumeWildCard(int kind) {
+		this.flags |= F_WILDCARD_TYPE;
+	}
+
+	public BindingKeyParser newParser() {
+		return new KeyKind(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
new file mode 100644
index 0000000..613e544
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
+
+/*
+ * Converts a binding key into a signature
+ */
+public class KeyToSignature extends BindingKeyParser {
+
+	public static final int SIGNATURE = 0;
+	public static final int TYPE_ARGUMENTS = 1;
+	public static final int DECLARING_TYPE = 2;
+	public static final int THROWN_EXCEPTIONS = 3;
+
+	public StringBuffer signature = new StringBuffer();
+	private int kind;
+	private ArrayList arguments = new ArrayList();
+	private ArrayList typeArguments = new ArrayList();
+	private ArrayList typeParameters = new ArrayList();
+	private ArrayList thrownExceptions = new ArrayList();
+	private int mainTypeStart = -1;
+	private int mainTypeEnd;
+	private int typeSigStart = -1;
+
+	public KeyToSignature(BindingKeyParser parser) {
+		super(parser);
+		this.kind = ((KeyToSignature) parser).kind;
+	}
+
+	public KeyToSignature(String key, int kind) {
+		super(key);
+		this.kind = kind;
+	}
+
+	public void consumeArrayDimension(char[] brakets) {
+		this.signature.append(brakets);
+	}
+
+	public void consumeBaseType(char[] baseTypeSig) {
+		this.typeSigStart = this.signature.length();
+		this.signature.append(baseTypeSig);
+	}
+
+	public void consumeCapture(int position) {
+		this.signature.append('!');
+		this.signature.append(((KeyToSignature) this.arguments.get(0)).signature);
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+		this.signature = new StringBuffer();
+		// remove trailing semi-colon as it is added later in comsumeType()
+		uniqueKey = CharOperation.subarray(uniqueKey, 0, uniqueKey.length-1);
+		CharOperation.replace(uniqueKey, '/', '.');
+		this.signature.append(uniqueKey);
+	}
+
+	public void consumeMethod(char[] selector, char[] methodSignature) {
+		this.arguments = new ArrayList();
+		this.typeArguments = new ArrayList();
+		CharOperation.replace(methodSignature, '/', '.');
+		switch(this.kind) {
+			case SIGNATURE:
+				this.signature = new StringBuffer();
+				this.signature.append(methodSignature);
+				break;
+			case THROWN_EXCEPTIONS:
+				if (CharOperation.indexOf('^', methodSignature) > 0) {
+					char[][] types = Signature.getThrownExceptionTypes(methodSignature);
+					int length = types.length;
+					for (int i=0; i<length; i++) {
+						this.thrownExceptions.add(new String(types[i]));
+					}
+				}
+				break;
+		}
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.signature.append('$');
+		this.signature.append(simpleTypeName);
+	}
+
+	public void consumePackage(char[] pkgName) {
+		this.signature.append(pkgName);
+	}
+
+	public void consumeParameterizedGenericMethod() {
+		this.typeArguments = this.arguments;
+		int typeParametersSize = this.arguments.size();
+		if (typeParametersSize > 0) {
+			int sigLength = this.signature.length();
+			char[] methodSignature = new char[sigLength];
+			this.signature.getChars(0, sigLength, methodSignature, 0);
+			char[][] typeParameterSigs = Signature.getTypeParameters(methodSignature);
+			if (typeParameterSigs.length != typeParametersSize)
+				return;
+			this.signature = new StringBuffer();
+
+			// type parameters
+			for (int i = 0; i < typeParametersSize; i++)
+				typeParameterSigs[i] = CharOperation.concat(Signature.C_TYPE_VARIABLE,Signature.getTypeVariable(typeParameterSigs[i]), Signature.C_SEMICOLON);
+			int paramStart = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
+			char[] typeParametersString = CharOperation.subarray(methodSignature, 0, paramStart);
+			this.signature.append(typeParametersString);
+
+			// substitute parameters
+			this.signature.append(Signature.C_PARAM_START);
+			char[][] parameters = Signature.getParameterTypes(methodSignature);
+			for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++)
+				substitute(parameters[i], typeParameterSigs, typeParametersSize);
+			this.signature.append(Signature.C_PARAM_END);
+
+			// substitute return type
+			char[] returnType = Signature.getReturnType(methodSignature);
+			substitute(returnType, typeParameterSigs, typeParametersSize);
+
+			// substitute exceptions
+			char[][] exceptions = Signature.getThrownExceptionTypes(methodSignature);
+			for (int i = 0, exceptionsLength = exceptions.length; i < exceptionsLength; i++) {
+				this.signature.append(Signature.C_EXCEPTION_START);
+				substitute(exceptions[i], typeParameterSigs, typeParametersSize);
+			}
+
+		}
+	}
+
+	/*
+	 * Substitutes the type variables referenced in the given parameter (a parameterized type signature) with the corresponding
+	 * type argument.
+	 * Appends the given parameter if it is not a parameterized type signature.
+	 */
+	private void substitute(char[] parameter, char[][] typeParameterSigs, int typeParametersLength) {
+		for (int i = 0; i < typeParametersLength; i++) {
+			if (CharOperation.equals(parameter, typeParameterSigs[i])) {
+				String typeArgument = ((KeyToSignature) this.arguments.get(i)).signature.toString();
+				this.signature.append(typeArgument);
+				return;
+			}
+		}
+		int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, parameter);
+		if (genericStart > -1) {
+			this.signature.append(CharOperation.subarray(parameter, 0, genericStart));
+			char[][] parameters = Signature.getTypeArguments(parameter);
+			this.signature.append(Signature.C_GENERIC_START);
+			for (int j = 0, paramsLength = parameters.length; j < paramsLength; j++)
+				substitute(parameters[j], typeParameterSigs, typeParametersLength);
+			this.signature.append(Signature.C_GENERIC_END);
+			this.signature.append(Signature.C_SEMICOLON);
+		} else {
+			// handle array, wildcard and capture
+			int index = 0;
+			int length = parameter.length;
+			loop: while (index < length) {
+				char current = parameter[index];
+				switch (current) {
+					case Signature.C_CAPTURE:
+					case Signature.C_EXTENDS:
+					case Signature.C_SUPER:
+					case Signature.C_ARRAY:
+						this.signature.append(current);
+						index++;
+						break;
+					default:
+						break loop;
+				}
+			}
+			if (index > 0)
+				substitute(CharOperation.subarray(parameter, index, length), typeParameterSigs, typeParametersLength);
+			else
+				this.signature.append(parameter);
+		}
+	}
+
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		if (simpleTypeName != null) {
+			// member type
+			this.signature.append('.');
+			this.signature.append(simpleTypeName);
+		}
+		if (!isRaw) {
+			this.signature.append('<');
+			int length = this.arguments.size();
+			for (int i = 0; i < length; i++) {
+				this.signature.append(((KeyToSignature) this.arguments.get(i)).signature);
+			}
+			this.signature.append('>');
+			this.typeArguments = this.arguments;
+			this.arguments = new ArrayList();
+		}
+	}
+
+	public void consumeParser(BindingKeyParser parser) {
+		this.arguments.add(parser);
+	}
+
+	public void consumeField(char[] fieldName) {
+		if (this.kind == SIGNATURE) {
+			this.signature = ((KeyToSignature) this.arguments.get(0)).signature;
+		}
+	}
+
+	public void consumeException() {
+		int size = this.arguments.size();
+		if (size > 0) {
+			for (int i=0; i<size; i++) {
+				this.thrownExceptions.add(((KeyToSignature) this.arguments.get(i)).signature.toString());
+			}
+			this.arguments = new ArrayList();
+			this.typeArguments = new ArrayList();
+		}
+	}
+
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		this.typeSigStart = this.signature.length();
+		this.signature.append('L');
+		this.signature.append(CharOperation.replaceOnCopy(fullyQualifiedName, '/', '.'));
+	}
+
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		this.signature.append('~');
+		this.mainTypeStart = this.signature.lastIndexOf(".") + 1; //$NON-NLS-1$
+		if (this.mainTypeStart == 0) {
+			this.mainTypeStart = 1; // default package (1 for the 'L')
+			int i = 0;
+			// we need to preserve the array if needed
+			while (this.signature.charAt(i) == Signature.C_ARRAY) {
+				this.mainTypeStart ++;
+				i++;
+			}
+		}
+		this.mainTypeEnd = this.signature.length();
+		this.signature.append(simpleTypeName);
+	}
+
+	public void consumeType() {
+		// remove main type if needed
+		if (this.mainTypeStart != -1) {
+			this.signature.replace(this.mainTypeStart, this.mainTypeEnd, ""); //$NON-NLS-1$
+		}
+		// parameter types
+		int length = this.typeParameters.size();
+		if (length > 0) {
+			StringBuffer typeParametersSig = new StringBuffer();
+			typeParametersSig.append('<');
+			for (int i = 0; i < length; i++) {
+				char[] typeParameterSig = Signature.createTypeParameterSignature(
+						(char[]) this.typeParameters.get(i),
+						new char[][]{ ConstantPool.ObjectSignature });
+				typeParametersSig.append(typeParameterSig);
+				// TODO (jerome) add type parameter bounds in binding key
+			}
+			typeParametersSig.append('>');
+			this.signature.insert(this.typeSigStart, typeParametersSig.toString());
+			this.typeParameters = new ArrayList();
+		}
+		this.signature.append(';');
+	}
+
+	public void consumeTypeParameter(char[] typeParameterName) {
+		this.typeParameters.add(typeParameterName);
+	}
+
+	public void consumeTypeVariable(char[] position, char[] typeVariableName) {
+		this.signature = new StringBuffer();
+		this.signature.append('T');
+		this.signature.append(typeVariableName);
+		this.signature.append(';');
+	}
+
+	public void consumeTypeWithCapture() {
+		KeyToSignature keyToSignature = (KeyToSignature) this.arguments.get(0);
+		this.signature = keyToSignature.signature;
+		this.arguments = keyToSignature.arguments;
+		this.typeArguments = keyToSignature.typeArguments;
+		this.thrownExceptions = keyToSignature.thrownExceptions;
+	}
+
+	public void consumeWildCard(int wildCardKind) {
+		// don't put generic type in signature
+		this.signature = new StringBuffer();
+		switch (wildCardKind) {
+			case Wildcard.UNBOUND:
+				this.signature.append('*');
+				break;
+			case Wildcard.EXTENDS:
+				this.signature.append('+');
+				this.signature.append(((KeyToSignature) this.arguments.get(0)).signature);
+				break;
+			case Wildcard.SUPER:
+				this.signature.append('-');
+				this.signature.append(((KeyToSignature) this.arguments.get(0)).signature);
+				break;
+			default:
+				// malformed
+				return;
+		}
+	}
+
+	public String[] getThrownExceptions() {
+		int length = this.thrownExceptions.size();
+		String[] result = new String[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = (String) this.thrownExceptions.get(i);
+		}
+		return result;
+	}
+
+	public String[] getTypeArguments() {
+		int length = this.typeArguments.size();
+		String[] result = new String[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = ((KeyToSignature) this.typeArguments.get(i)).signature.toString();
+		}
+		return result;
+	}
+
+	public BindingKeyParser newParser() {
+		return new KeyToSignature(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.signature.toString();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java
new file mode 100644
index 0000000..1eaf904
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java
@@ -0,0 +1,696 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.text.NumberFormat;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * The <code>LRUCache</code> is a hashtable that stores a finite number of elements.
+ * When an attempt is made to add values to a full cache, the least recently used values
+ * in the cache are discarded to make room for the new values as necessary.
+ *
+ * <p>The data structure is based on the LRU virtual memory paging scheme.
+ *
+ * <p>Objects can take up a variable amount of cache space by implementing
+ * the <code>ILRUCacheable</code> interface.
+ *
+ * <p>This implementation is NOT thread-safe.  Synchronization wrappers would
+ * have to be added to ensure atomic insertions and deletions from the cache.
+ *
+ * @see org.eclipse.jdt.internal.core.util.ILRUCacheable
+ */
+public class LRUCache implements Cloneable {
+
+	/**
+	 * This type is used internally by the LRUCache to represent entries
+	 * stored in the cache.
+	 * It is static because it does not require a pointer to the cache
+	 * which contains it.
+	 *
+	 * @see LRUCache
+	 */
+	protected static class LRUCacheEntry {
+
+		/**
+		 * Hash table key
+		 */
+		public Object key;
+
+		/**
+		 * Hash table value (an LRUCacheEntry object)
+		 */
+		public Object value;
+
+		/**
+		 * Time value for queue sorting
+		 */
+		public int timestamp;
+
+		/**
+		 * Cache footprint of this entry
+		 */
+		public int space;
+
+		/**
+		 * Previous entry in queue
+		 */
+		public LRUCacheEntry previous;
+
+		/**
+		 * Next entry in queue
+		 */
+		public LRUCacheEntry next;
+
+		/**
+		 * Creates a new instance of the receiver with the provided values
+		 * for key, value, and space.
+		 */
+		public LRUCacheEntry (Object key, Object value, int space) {
+			this.key = key;
+			this.value = value;
+			this.space = space;
+		}
+
+		/**
+		 * Returns a String that represents the value of this object.
+		 */
+		public String toString() {
+
+			return "LRUCacheEntry [" + this.key + "-->" + this.value + "]"; //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	public class Stats {
+		private int[] counters = new int[20];
+		private long[] timestamps = new long[20];
+		private int counterIndex = -1;
+		
+		private void add(int counter) {
+			for (int i = 0; i <= this.counterIndex; i++) {
+				if (this.counters[i] == counter)
+					return;
+			}
+			int length = this.counters.length;
+			if (++this.counterIndex == length) {
+				int newLength = this.counters.length * 2;
+				System.arraycopy(this.counters, 0, this.counters = new int[newLength], 0, length);
+				System.arraycopy(this.timestamps, 0, this.timestamps = new long[newLength], 0, length);
+			}
+			this.counters[this.counterIndex] = counter;
+			this.timestamps[this.counterIndex] = System.currentTimeMillis();
+		}
+		private String getAverageAge(long totalTime, int numberOfElements, long currentTime) {
+			if (numberOfElements == 0)
+				return "N/A"; //$NON-NLS-1$
+			long time = totalTime / numberOfElements;
+			long age = currentTime - time;
+			long ageInSeconds = age/1000;
+			int seconds = 0;
+			int minutes = 0;
+			int hours = 0;
+			int days = 0;
+			if (ageInSeconds > 60) {
+				long ageInMin = ageInSeconds / 60;
+				seconds = (int) (ageInSeconds - (60 * ageInMin));
+				if (ageInMin > 60) {
+					long ageInHours = ageInMin / 60;
+					minutes = (int) (ageInMin - (60 * ageInHours));
+					if (ageInHours > 24) {
+						long ageInDays = ageInHours / 24;
+						hours = (int) (ageInHours - (24 * ageInDays));
+						days = (int) ageInDays;
+					} else {
+						hours = (int) ageInHours;
+					}
+				} else {
+					minutes = (int) ageInMin;
+				}
+			} else {
+				seconds = (int) ageInSeconds;
+			}
+			StringBuffer buffer = new StringBuffer();
+			if (days > 0) {
+				buffer.append(days);
+				buffer.append(" days "); //$NON-NLS-1$
+			}
+			if (hours > 0) {
+				buffer.append(hours);
+				buffer.append(" hours "); //$NON-NLS-1$
+			}
+			if (minutes > 0) {
+				buffer.append(minutes);
+				buffer.append(" minutes "); //$NON-NLS-1$
+			}
+			buffer.append(seconds);
+			buffer.append(" seconds"); //$NON-NLS-1$
+			return buffer.toString();
+		}
+		private long getTimestamps(int counter) {
+			for (int i = 0; i <= this.counterIndex; i++) {
+				if (this.counters[i] >= counter)
+					return this.timestamps[i];
+			}
+			return -1;
+		}
+		public synchronized String printStats() {
+			int numberOfElements = LRUCache.this.currentSpace;
+			if (numberOfElements == 0) {
+				return "No elements in cache"; //$NON-NLS-1$
+			}
+			StringBuffer buffer = new StringBuffer();
+			
+			buffer.append("Number of elements in cache: "); //$NON-NLS-1$
+			buffer.append(numberOfElements);
+			
+			final int numberOfGroups = 5;
+			int numberOfElementsPerGroup = numberOfElements / numberOfGroups;
+			buffer.append("\n("); //$NON-NLS-1$
+			buffer.append(numberOfGroups);
+			buffer.append(" groups of "); //$NON-NLS-1$
+			buffer.append(numberOfElementsPerGroup);
+			buffer.append(" elements)"); //$NON-NLS-1$
+			buffer.append("\n\nAverage age:"); //$NON-NLS-1$
+			int groupNumber = 1;
+			int elementCounter = 0;
+			LRUCacheEntry entry = LRUCache.this.entryQueueTail;
+			long currentTime = System.currentTimeMillis();
+			long accumulatedTime = 0;
+			while (entry != null) {
+				long timeStamps = getTimestamps(entry.timestamp);
+				if (timeStamps > 0) {
+					accumulatedTime += timeStamps;
+					elementCounter++;
+				}
+				if (elementCounter >= numberOfElementsPerGroup && (groupNumber < numberOfGroups)) {
+					buffer.append("\nGroup "); //$NON-NLS-1$
+					buffer.append(groupNumber);
+					if (groupNumber == 1) {
+						buffer.append(" (oldest)\t: "); //$NON-NLS-1$
+					} else {
+						buffer.append("\t\t: "); //$NON-NLS-1$
+					}
+					groupNumber++;
+					buffer.append(getAverageAge(accumulatedTime, elementCounter, currentTime));
+					elementCounter = 0;
+					accumulatedTime = 0;
+				}
+				entry = entry.previous;
+			}
+			buffer.append("\nGroup "); //$NON-NLS-1$
+			buffer.append(numberOfGroups);
+			buffer.append(" (youngest)\t: "); //$NON-NLS-1$
+			buffer.append(getAverageAge(accumulatedTime, elementCounter, currentTime));
+			
+			return buffer.toString();
+		}
+		private void removeCountersOlderThan(int counter) {
+			for (int i = 0; i <= this.counterIndex; i++) {
+				if (this.counters[i] >= counter) {
+					if (i > 0) {
+						int length = this.counterIndex-i+1;
+						System.arraycopy(this.counters, i, this.counters, 0, length);
+						System.arraycopy(this.timestamps, i, this.timestamps, 0, length);
+						this.counterIndex = length;
+					}
+					return;
+				}
+			}
+		}
+		public Object getOldestElement() {
+			return LRUCache.this.getOldestElement();
+		}
+		public long getOldestTimestamps() {
+			return getTimestamps(getOldestTimestampCounter());
+		}
+		public synchronized void snapshot() {
+			removeCountersOlderThan(getOldestTimestampCounter());
+			add(getNewestTimestampCounter());
+		}
+	}
+
+	/**
+	 * Amount of cache space used so far
+	 */
+	protected int currentSpace;
+
+	/**
+	 * Maximum space allowed in cache
+	 */
+	protected int spaceLimit;
+
+	/**
+	 * Counter for handing out sequential timestamps
+	 */
+	protected int timestampCounter;
+
+	/**
+	 * Hash table for fast random access to cache entries
+	 */
+	protected Hashtable entryTable;
+
+	/**
+	 * Start of queue (most recently used entry)
+	 */
+	protected LRUCacheEntry entryQueue;
+
+	/**
+	 * End of queue (least recently used entry)
+	 */
+	protected LRUCacheEntry entryQueueTail;
+
+	/**
+	 * Default amount of space in the cache
+	 */
+	protected static final int DEFAULT_SPACELIMIT = 100;
+	/**
+	 * Creates a new cache.  Size of cache is defined by
+	 * <code>DEFAULT_SPACELIMIT</code>.
+	 */
+	public LRUCache() {
+
+		this(DEFAULT_SPACELIMIT);
+	}
+	/**
+	 * Creates a new cache.
+	 * @param size Size of Cache
+	 */
+	public LRUCache(int size) {
+
+		this.timestampCounter = this.currentSpace = 0;
+		this.entryQueue = this.entryQueueTail = null;
+		this.entryTable = new Hashtable(size);
+		this.spaceLimit = size;
+	}
+	/**
+	 * Returns a new cache containing the same contents.
+	 *
+	 * @return New copy of object.
+	 */
+	public Object clone() {
+
+		LRUCache newCache = newInstance(this.spaceLimit);
+		LRUCacheEntry qEntry;
+
+		/* Preserve order of entries by copying from oldest to newest */
+		qEntry = this.entryQueueTail;
+		while (qEntry != null) {
+			newCache.privateAdd (qEntry.key, qEntry.value, qEntry.space);
+			qEntry = qEntry.previous;
+		}
+		return newCache;
+	}
+	public double fillingRatio() {
+		return (this.currentSpace) * 100.0 / this.spaceLimit;
+	}
+	/**
+	 * Flushes all entries from the cache.
+	 */
+	public void flush() {
+
+		this.currentSpace = 0;
+		LRUCacheEntry entry = this.entryQueueTail; // Remember last entry
+		this.entryTable = new Hashtable();  // Clear it out
+		this.entryQueue = this.entryQueueTail = null;
+		while (entry != null) {  // send deletion notifications in LRU order
+			entry = entry.previous;
+		}
+	}
+	/**
+	 * Flushes the given entry from the cache.  Does nothing if entry does not
+	 * exist in cache.
+	 *
+	 * @param key Key of object to flush
+	 */
+	public void flush (Object key) {
+
+		LRUCacheEntry entry;
+
+		entry = (LRUCacheEntry) this.entryTable.get(key);
+
+		/* If entry does not exist, return */
+		if (entry == null) return;
+
+		privateRemoveEntry (entry, false);
+	}
+	/*
+	 * Answers the existing key that is equals to the given key.
+	 * If the key is not in the cache, returns the given key
+	 */
+	public Object getKey(Object key) {
+		LRUCacheEntry entry = (LRUCacheEntry) this.entryTable.get(key);
+		if (entry == null) {
+			return key;
+		}
+		return entry.key;
+	}
+	/**
+	 * Answers the value in the cache at the given key.
+	 * If the value is not in the cache, returns null
+	 *
+	 * @param key Hash table key of object to retrieve
+	 * @return Retreived object, or null if object does not exist
+	 */
+	public Object get(Object key) {
+
+		LRUCacheEntry entry = (LRUCacheEntry) this.entryTable.get(key);
+		if (entry == null) {
+			return null;
+		}
+
+		updateTimestamp (entry);
+		return entry.value;
+	}
+	/**
+	 * Returns the amount of space that is current used in the cache.
+	 */
+	public int getCurrentSpace() {
+		return this.currentSpace;
+	}
+	/**
+	 * Returns the timestamps of the most recently used element in the cache.
+	 */
+	public int getNewestTimestampCounter() {
+		return this.entryQueue == null ? 0 : this.entryQueue.timestamp;
+	}
+	/**
+	 * Returns the timestamps of the least recently used element in the cache.
+	 */
+	public int getOldestTimestampCounter() {
+		return this.entryQueueTail == null ? 0 : this.entryQueueTail.timestamp;
+	}
+	/**
+	 * Returns the lest recently used element in the cache
+	 */
+	public Object getOldestElement() {
+		return this.entryQueueTail == null ? null : this.entryQueueTail.key;
+	}
+	
+	/**
+	 * Returns the maximum amount of space available in the cache.
+	 */
+	public int getSpaceLimit() {
+		return this.spaceLimit;
+	}
+	/**
+	 * Returns an Enumeration of the keys currently in the cache.
+	 */
+	public Enumeration keys() {
+
+		return this.entryTable.keys();
+	}
+	/**
+	 * Returns an enumeration that iterates over all the keys and values
+	 * currently in the cache.
+	 */
+	public ICacheEnumeration keysAndValues() {
+		return new ICacheEnumeration() {
+
+			Enumeration values = LRUCache.this.entryTable.elements();
+			LRUCacheEntry entry;
+
+			public boolean hasMoreElements() {
+				return this.values.hasMoreElements();
+			}
+
+			public Object nextElement() {
+				this.entry = (LRUCacheEntry) this.values.nextElement();
+				return this.entry.key;
+			}
+
+			public Object getValue() {
+				if (this.entry == null) {
+					throw new java.util.NoSuchElementException();
+				}
+				return this.entry.value;
+			}
+		};
+	}
+	/**
+	 * Ensures there is the specified amount of free space in the receiver,
+	 * by removing old entries if necessary.  Returns true if the requested space was
+	 * made available, false otherwise.
+	 *
+	 * @param space Amount of space to free up
+	 */
+	protected boolean makeSpace (int space) {
+
+		int limit;
+
+		limit = getSpaceLimit();
+
+		/* if space is already available */
+		if (this.currentSpace + space <= limit) {
+			return true;
+		}
+
+		/* if entry is too big for cache */
+		if (space > limit) {
+			return false;
+		}
+
+		/* Free up space by removing oldest entries */
+		while (this.currentSpace + space > limit && this.entryQueueTail != null) {
+			privateRemoveEntry (this.entryQueueTail, false);
+		}
+		return true;
+	}
+	/**
+	 * Returns a new LRUCache instance
+	 */
+	protected LRUCache newInstance(int size) {
+		return new LRUCache(size);
+	}
+	/**
+	 * Answers the value in the cache at the given key.
+	 * If the value is not in the cache, returns null
+	 *
+	 * This function does not modify timestamps.
+	 */
+	public Object peek(Object key) {
+
+		LRUCacheEntry entry = (LRUCacheEntry) this.entryTable.get(key);
+		if (entry == null) {
+			return null;
+		}
+		return entry.value;
+	}
+	/**
+	 * Adds an entry for the given key/value/space.
+	 */
+	protected void privateAdd (Object key, Object value, int space) {
+
+		LRUCacheEntry entry;
+
+		entry = new LRUCacheEntry(key, value, space);
+		privateAddEntry (entry, false);
+	}
+	/**
+	 * Adds the given entry from the receiver.
+	 * @param shuffle Indicates whether we are just shuffling the queue
+	 * (in which case, the entry table is not modified).
+	 */
+	protected void privateAddEntry (LRUCacheEntry entry, boolean shuffle) {
+
+		if (!shuffle) {
+			this.entryTable.put (entry.key, entry);
+			this.currentSpace += entry.space;
+		}
+
+		entry.timestamp = this.timestampCounter++;
+		entry.next = this.entryQueue;
+		entry.previous = null;
+
+		if (this.entryQueue == null) {
+			/* this is the first and last entry */
+			this.entryQueueTail = entry;
+		} else {
+			this.entryQueue.previous = entry;
+		}
+
+		this.entryQueue = entry;
+	}
+	/**
+	 * Removes the entry from the entry queue.
+	 * @param shuffle indicates whether we are just shuffling the queue
+	 * (in which case, the entry table is not modified).
+	 */
+	protected void privateRemoveEntry (LRUCacheEntry entry, boolean shuffle) {
+
+		LRUCacheEntry previous, next;
+
+		previous = entry.previous;
+		next = entry.next;
+
+		if (!shuffle) {
+			this.entryTable.remove(entry.key);
+			this.currentSpace -= entry.space;
+		}
+
+		/* if this was the first entry */
+		if (previous == null) {
+			this.entryQueue = next;
+		} else {
+			previous.next = next;
+		}
+
+		/* if this was the last entry */
+		if (next == null) {
+			this.entryQueueTail = previous;
+		} else {
+			next.previous = previous;
+		}
+	}
+	/**
+	 * Sets the value in the cache at the given key. Returns the value.
+	 *
+	 * @param key Key of object to add.
+	 * @param value Value of object to add.
+	 * @return added value.
+	 */
+	public Object put(Object key, Object value) {
+
+		int newSpace, oldSpace, newTotal;
+		LRUCacheEntry entry;
+
+		/* Check whether there's an entry in the cache */
+		newSpace = spaceFor(value);
+		entry = (LRUCacheEntry) this.entryTable.get (key);
+
+		if (entry != null) {
+
+			/**
+			 * Replace the entry in the cache if it would not overflow
+			 * the cache.  Otherwise flush the entry and re-add it so as
+			 * to keep cache within budget
+			 */
+			oldSpace = entry.space;
+			newTotal = getCurrentSpace() - oldSpace + newSpace;
+			if (newTotal <= getSpaceLimit()) {
+				updateTimestamp (entry);
+				entry.value = value;
+				entry.space = newSpace;
+				this.currentSpace = newTotal;
+				return value;
+			} else {
+				privateRemoveEntry (entry, false);
+			}
+		}
+		if (makeSpace(newSpace)) {
+			privateAdd (key, value, newSpace);
+		}
+		return value;
+	}
+	/**
+	 * Removes and returns the value in the cache for the given key.
+	 * If the key is not in the cache, returns null.
+	 *
+	 * @param key Key of object to remove from cache.
+	 * @return Value removed from cache.
+	 */
+	public Object removeKey (Object key) {
+
+		LRUCacheEntry entry = (LRUCacheEntry) this.entryTable.get(key);
+		if (entry == null) {
+			return null;
+		}
+		Object value = entry.value;
+		privateRemoveEntry (entry, false);
+		return value;
+	}
+	/**
+	 * Sets the maximum amount of space that the cache can store
+	 *
+	 * @param limit Number of units of cache space
+	 */
+	public void setSpaceLimit(int limit) {
+		if (limit < this.spaceLimit) {
+			makeSpace(this.spaceLimit - limit);
+		}
+		this.spaceLimit = limit;
+	}
+	/**
+	 * Returns the space taken by the given value.
+	 */
+	protected int spaceFor (Object value) {
+
+		if (value instanceof ILRUCacheable) {
+			return ((ILRUCacheable) value).getCacheFootprint();
+		} else {
+			return 1;
+		}
+	}
+	/**
+	 * Returns a String that represents the value of this object.  This method
+	 * is for debugging purposes only.
+	 */
+	public String toString() {
+		return
+			toStringFillingRation("LRUCache") + //$NON-NLS-1$
+			toStringContents();
+	}
+
+	/**
+	 * Returns a String that represents the contents of this object.  This method
+	 * is for debugging purposes only.
+	 */
+	protected String toStringContents() {
+		StringBuffer result = new StringBuffer();
+		int length = this.entryTable.size();
+		Object[] unsortedKeys = new Object[length];
+		String[] unsortedToStrings = new String[length];
+		Enumeration e = keys();
+		for (int i = 0; i < length; i++) {
+			Object key = e.nextElement();
+			unsortedKeys[i] = key;
+			unsortedToStrings[i] =
+				(key instanceof org.eclipse.jdt.internal.core.JavaElement) ?
+					((org.eclipse.jdt.internal.core.JavaElement)key).getElementName() :
+					key.toString();
+		}
+		ToStringSorter sorter = new ToStringSorter();
+		sorter.sort(unsortedKeys, unsortedToStrings);
+		for (int i = 0; i < length; i++) {
+			String toString = sorter.sortedStrings[i];
+			Object value = get(sorter.sortedObjects[i]);
+			result.append(toString);
+			result.append(" -> "); //$NON-NLS-1$
+			result.append(value);
+			result.append("\n"); //$NON-NLS-1$
+		}
+		return result.toString();
+	}
+
+	public String toStringFillingRation(String cacheName) {
+		StringBuffer buffer = new StringBuffer(cacheName);
+		buffer.append('[');
+		buffer.append(getSpaceLimit());
+		buffer.append("]: "); //$NON-NLS-1$
+		buffer.append(NumberFormat.getInstance().format(fillingRatio()));
+		buffer.append("% full"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+
+	/**
+	 * Updates the timestamp for the given entry, ensuring that the queue is
+	 * kept in correct order.  The entry must exist
+	 */
+	protected void updateTimestamp (LRUCacheEntry entry) {
+
+		entry.timestamp = this.timestampCounter++;
+		if (this.entryQueue != entry) {
+			privateRemoveEntry (entry, true);
+			privateAddEntry (entry, true);
+		}
+		return;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java
new file mode 100644
index 0000000..e472877
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.ILineNumberAttribute;
+
+/**
+ * Default implementation of ILineNumberAttribute.
+ */
+public class LineNumberAttribute
+	extends ClassFileAttribute
+	implements ILineNumberAttribute {
+
+	private static final int[][] NO_ENTRIES = new int[0][0];
+	private int lineNumberTableLength;
+	private int[][] lineNumberTable;
+
+	/**
+	 * Constructor for LineNumberAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LineNumberAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+
+		final int length = u2At(classFileBytes, 6, offset);
+		this.lineNumberTableLength = length;
+		if (length != 0) {
+			this.lineNumberTable = new int[length][2];
+			int readOffset = 8;
+			for (int i = 0; i < length; i++) {
+				this.lineNumberTable[i][0] = u2At(classFileBytes, readOffset, offset);
+				this.lineNumberTable[i][1] = u2At(classFileBytes, readOffset + 2, offset);
+				readOffset += 4;
+			}
+		} else {
+			this.lineNumberTable = NO_ENTRIES;
+		}
+	}
+	/**
+	 * @see ILineNumberAttribute#getLineNumberTable()
+	 */
+	public int[][] getLineNumberTable() {
+		return this.lineNumberTable;
+	}
+
+	/**
+	 * @see ILineNumberAttribute#getLineNumberTableLength()
+	 */
+	public int getLineNumberTableLength() {
+		return this.lineNumberTableLength;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java
new file mode 100644
index 0000000..d1bbdbc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.ILocalVariableAttribute;
+import org.eclipse.jdt.core.util.ILocalVariableTableEntry;
+
+/**
+ * Default implementation of ILocalVariableAttribute.
+ */
+public class LocalVariableAttribute
+	extends ClassFileAttribute
+	implements ILocalVariableAttribute {
+
+	private static final ILocalVariableTableEntry[] NO_ENTRIES = new ILocalVariableTableEntry[0];
+	private int localVariableTableLength;
+	private ILocalVariableTableEntry[] localVariableTable;
+
+	/**
+	 * Constructor for LocalVariableAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LocalVariableAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u2At(classFileBytes, 6, offset);
+		this.localVariableTableLength = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.localVariableTable = new ILocalVariableTableEntry[length];
+			for (int i = 0; i < length; i++) {
+				this.localVariableTable[i] = new LocalVariableTableEntry(classFileBytes, constantPool, offset + readOffset);
+				readOffset += 10;
+			}
+		} else {
+			this.localVariableTable = NO_ENTRIES;
+		}
+	}
+	/**
+	 * @see ILocalVariableAttribute#getLocalVariableTable()
+	 */
+	public ILocalVariableTableEntry[] getLocalVariableTable() {
+		return this.localVariableTable;
+	}
+
+	/**
+	 * @see ILocalVariableAttribute#getLocalVariableTableLength()
+	 */
+	public int getLocalVariableTableLength() {
+		return this.localVariableTableLength;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableReferenceInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableReferenceInfo.java
new file mode 100644
index 0000000..b56fcc9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableReferenceInfo.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.ILocalVariableReferenceInfo;
+
+
+public class LocalVariableReferenceInfo extends ClassFileStruct implements ILocalVariableReferenceInfo {
+
+	private int startPC;
+	private int length;
+	private int index;
+
+	/**
+	 * Constructor for LocalVariableTableEntry.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LocalVariableReferenceInfo(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		this.startPC = u2At(classFileBytes, 0, offset);
+		this.length = u2At(classFileBytes, 2, offset);
+		this.index = u2At(classFileBytes, 4, offset);
+	}
+
+	/**
+	 * @see ILocalVariableReferenceInfo#getStartPC()
+	 */
+	public int getStartPC() {
+		return this.startPC;
+	}
+
+	/**
+	 * @see ILocalVariableReferenceInfo#getLength()
+	 */
+	public int getLength() {
+		return this.length;
+	}
+
+	/**
+	 * @see ILocalVariableReferenceInfo#getIndex()
+	 */
+	public int getIndex() {
+		return this.index;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java
new file mode 100644
index 0000000..f834654
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.ILocalVariableTableEntry;
+
+/**
+ * Default implementation of ILocalVariableTableEntry
+ */
+public class LocalVariableTableEntry extends ClassFileStruct implements ILocalVariableTableEntry {
+
+	private int startPC;
+	private int length;
+	private int nameIndex;
+	private int descriptorIndex;
+	private char[] name;
+	private char[] descriptor;
+	private int index;
+
+	/**
+	 * Constructor for LocalVariableTableEntry.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LocalVariableTableEntry(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset) throws ClassFormatException {
+			this.startPC = u2At(classFileBytes, 0, offset);
+			this.length = u2At(classFileBytes, 2, offset);
+			this.nameIndex = u2At(classFileBytes, 4, offset);
+			this.descriptorIndex = u2At(classFileBytes, 6, offset);
+			this.index = u2At(classFileBytes, 8, offset);
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.name = constantPoolEntry.getUtf8Value();
+			constantPoolEntry = constantPool.decodeEntry(this.descriptorIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.descriptor = constantPoolEntry.getUtf8Value();
+		}
+
+	/**
+	 * @see ILocalVariableTableEntry#getStartPC()
+	 */
+	public int getStartPC() {
+		return this.startPC;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getLength()
+	 */
+	public int getLength() {
+		return this.length;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getNameIndex()
+	 */
+	public int getNameIndex() {
+		return this.nameIndex;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getDescriptorIndex()
+	 */
+	public int getDescriptorIndex() {
+		return this.descriptorIndex;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getIndex()
+	 */
+	public int getIndex() {
+		return this.index;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getName()
+	 */
+	public char[] getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see ILocalVariableTableEntry#getDescriptor()
+	 */
+	public char[] getDescriptor() {
+		return this.descriptor;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java
new file mode 100644
index 0000000..aa235b6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.ILocalVariableTypeTableAttribute;
+import org.eclipse.jdt.core.util.ILocalVariableTypeTableEntry;
+
+/**
+ * Default implementation of ILocalVariableTypeAttribute.
+ */
+public class LocalVariableTypeAttribute
+	extends ClassFileAttribute
+	implements ILocalVariableTypeTableAttribute {
+
+	private static final ILocalVariableTypeTableEntry[] NO_ENTRIES = new ILocalVariableTypeTableEntry[0];
+	private int localVariableTypeTableLength;
+	private ILocalVariableTypeTableEntry[] localVariableTypeTableEntries;
+
+	/**
+	 * Constructor for LocalVariableTypeAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LocalVariableTypeAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u2At(classFileBytes, 6, offset);
+		this.localVariableTypeTableLength = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.localVariableTypeTableEntries = new ILocalVariableTypeTableEntry[length];
+			for (int i = 0; i < length; i++) {
+				this.localVariableTypeTableEntries[i] = new LocalVariableTypeTableEntry(classFileBytes, constantPool, offset + readOffset);
+				readOffset += 10;
+			}
+		} else {
+			this.localVariableTypeTableEntries = NO_ENTRIES;
+		}
+	}
+	/**
+	 * @see ILocalVariableTypeTableAttribute#getLocalVariableTypeTable()
+	 */
+	public ILocalVariableTypeTableEntry[] getLocalVariableTypeTable() {
+		return this.localVariableTypeTableEntries;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableAttribute#getLocalVariableTypeTableLength()
+	 */
+	public int getLocalVariableTypeTableLength() {
+		return this.localVariableTypeTableLength;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java
new file mode 100644
index 0000000..2846efb
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.ILocalVariableTypeTableEntry;
+
+/**
+ * Default implementation of ILocalVariableTypeTableEntry
+ */
+public class LocalVariableTypeTableEntry extends ClassFileStruct implements ILocalVariableTypeTableEntry {
+
+	private int startPC;
+	private int length;
+	private int nameIndex;
+	private int signatureIndex;
+	private char[] name;
+	private char[] signature;
+	private int index;
+
+	/**
+	 * Constructor for LocalVariableTypeTableEntry.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public LocalVariableTypeTableEntry(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset) throws ClassFormatException {
+			this.startPC = u2At(classFileBytes, 0, offset);
+			this.length = u2At(classFileBytes, 2, offset);
+			this.nameIndex = u2At(classFileBytes, 4, offset);
+			this.signatureIndex = u2At(classFileBytes, 6, offset);
+			this.index = u2At(classFileBytes, 8, offset);
+			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.name = constantPoolEntry.getUtf8Value();
+			constantPoolEntry = constantPool.decodeEntry(this.signatureIndex);
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			this.signature = constantPoolEntry.getUtf8Value();
+		}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getStartPC()
+	 */
+	public int getStartPC() {
+		return this.startPC;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getLength()
+	 */
+	public int getLength() {
+		return this.length;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getNameIndex()
+	 */
+	public int getNameIndex() {
+		return this.nameIndex;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getSignatureIndex()
+	 */
+	public int getSignatureIndex() {
+		return this.signatureIndex;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getIndex()
+	 */
+	public int getIndex() {
+		return this.index;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getName()
+	 */
+	public char[] getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see ILocalVariableTypeTableEntry#getSignature()
+	 */
+	public char[] getSignature() {
+		return this.signature;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
new file mode 100644
index 0000000..86f96f2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.internal.core.JavaElement;
+
+public class MementoTokenizer {
+	public static final String COUNT = Character.toString(JavaElement.JEM_COUNT);
+	public static final String JAVAPROJECT = Character.toString(JavaElement.JEM_JAVAPROJECT);
+	public static final String PACKAGEFRAGMENTROOT = Character.toString(JavaElement.JEM_PACKAGEFRAGMENTROOT);
+	public static final String PACKAGEFRAGMENT = Character.toString(JavaElement.JEM_PACKAGEFRAGMENT);
+	public static final String FIELD = Character.toString(JavaElement.JEM_FIELD);
+	public static final String METHOD = Character.toString(JavaElement.JEM_METHOD);
+	public static final String INITIALIZER = Character.toString(JavaElement.JEM_INITIALIZER);
+	public static final String COMPILATIONUNIT = Character.toString(JavaElement.JEM_COMPILATIONUNIT);
+	public static final String CLASSFILE = Character.toString(JavaElement.JEM_CLASSFILE);
+	public static final String TYPE = Character.toString(JavaElement.JEM_TYPE);
+	public static final String PACKAGEDECLARATION = Character.toString(JavaElement.JEM_PACKAGEDECLARATION);
+	public static final String IMPORTDECLARATION = Character.toString(JavaElement.JEM_IMPORTDECLARATION);
+	public static final String LOCALVARIABLE = Character.toString(JavaElement.JEM_LOCALVARIABLE);
+	public static final String TYPE_PARAMETER = Character.toString(JavaElement.JEM_TYPE_PARAMETER);
+	public static final String ANNOTATION = Character.toString(JavaElement.JEM_ANNOTATION);
+
+	private final char[] memento;
+	private final int length;
+	private int index = 0;
+
+	public MementoTokenizer(String memento) {
+		this.memento = memento.toCharArray();
+		this.length = this.memento.length;
+	}
+
+	public boolean hasMoreTokens() {
+		return this.index < this.length;
+	}
+
+	public String nextToken() {
+		int start = this.index;
+		StringBuffer buffer = null;
+		switch (this.memento[this.index++]) {
+			case JavaElement.JEM_ESCAPE:
+				buffer = new StringBuffer();
+				buffer.append(this.memento[this.index]);
+				start = ++this.index;
+				break;
+			case JavaElement.JEM_COUNT:
+				return COUNT;
+			case JavaElement.JEM_JAVAPROJECT:
+				return JAVAPROJECT;
+			case JavaElement.JEM_PACKAGEFRAGMENTROOT:
+				return PACKAGEFRAGMENTROOT;
+			case JavaElement.JEM_PACKAGEFRAGMENT:
+				return PACKAGEFRAGMENT;
+			case JavaElement.JEM_FIELD:
+				return FIELD;
+			case JavaElement.JEM_METHOD:
+				return METHOD;
+			case JavaElement.JEM_INITIALIZER:
+				return INITIALIZER;
+			case JavaElement.JEM_COMPILATIONUNIT:
+				return COMPILATIONUNIT;
+			case JavaElement.JEM_CLASSFILE:
+				return CLASSFILE;
+			case JavaElement.JEM_TYPE:
+				return TYPE;
+			case JavaElement.JEM_PACKAGEDECLARATION:
+				return PACKAGEDECLARATION;
+			case JavaElement.JEM_IMPORTDECLARATION:
+				return IMPORTDECLARATION;
+			case JavaElement.JEM_LOCALVARIABLE:
+				return LOCALVARIABLE;
+			case JavaElement.JEM_TYPE_PARAMETER:
+				return TYPE_PARAMETER;
+			case JavaElement.JEM_ANNOTATION:
+				return ANNOTATION;
+		}
+		loop: while (this.index < this.length) {
+			switch (this.memento[this.index]) {
+				case JavaElement.JEM_ESCAPE:
+					if (buffer == null) buffer = new StringBuffer();
+					buffer.append(this.memento, start, this.index - start);
+					start = ++this.index;
+					break;
+				case JavaElement.JEM_COUNT:
+				case JavaElement.JEM_JAVAPROJECT:
+				case JavaElement.JEM_PACKAGEFRAGMENTROOT:
+				case JavaElement.JEM_PACKAGEFRAGMENT:
+				case JavaElement.JEM_FIELD:
+				case JavaElement.JEM_METHOD:
+				case JavaElement.JEM_INITIALIZER:
+				case JavaElement.JEM_COMPILATIONUNIT:
+				case JavaElement.JEM_CLASSFILE:
+				case JavaElement.JEM_TYPE:
+				case JavaElement.JEM_PACKAGEDECLARATION:
+				case JavaElement.JEM_IMPORTDECLARATION:
+				case JavaElement.JEM_LOCALVARIABLE:
+				case JavaElement.JEM_TYPE_PARAMETER:
+				case JavaElement.JEM_ANNOTATION:
+					break loop;
+			}
+			this.index++;
+		}
+		if (buffer != null) {
+			buffer.append(this.memento, start, this.index - start);
+			return buffer.toString();
+		} else {
+			return new String(this.memento, start, this.index - start);
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
new file mode 100644
index 0000000..2de3362
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -0,0 +1,447 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.text.MessageFormat;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.core.util.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String hierarchy_nullProject;
+	public static String hierarchy_nullRegion;
+	public static String hierarchy_nullFocusType;
+	public static String hierarchy_creating;
+	public static String hierarchy_creatingOnType;
+	public static String element_doesNotExist;
+	public static String element_notOnClasspath;
+	public static String element_invalidClassFileName;
+	public static String element_reconciling;
+	public static String element_attachingSource;
+	public static String element_invalidResourceForProject;
+	public static String element_nullName;
+	public static String element_nullType;
+	public static String element_illegalParent;
+	public static String javamodel_initialization;
+	public static String javamodel_initializing_delta_state;
+	public static String javamodel_building_after_upgrade;
+	public static String javamodel_configuring;
+	public static String javamodel_configuring_classpath_containers;
+	public static String javamodel_configuring_searchengine;
+	public static String javamodel_getting_build_state_number;
+	public static String javamodel_refreshing_external_jars;
+	public static String javamodel_resetting_source_attachment_properties;
+	public static String operation_needElements;
+	public static String operation_needName;
+	public static String operation_needPath;
+	public static String operation_needAbsolutePath;
+	public static String operation_needString;
+	public static String operation_notSupported;
+	public static String operation_cancelled;
+	public static String operation_nullContainer;
+	public static String operation_nullName;
+	public static String operation_copyElementProgress;
+	public static String operation_moveElementProgress;
+	public static String operation_renameElementProgress;
+	public static String operation_copyResourceProgress;
+	public static String operation_moveResourceProgress;
+	public static String operation_renameResourceProgress;
+	public static String operation_createUnitProgress;
+	public static String operation_createFieldProgress;
+	public static String operation_createImportsProgress;
+	public static String operation_createInitializerProgress;
+	public static String operation_createMethodProgress;
+	public static String operation_createPackageProgress;
+	public static String operation_createPackageFragmentProgress;
+	public static String operation_createTypeProgress;
+	public static String operation_deleteElementProgress;
+	public static String operation_deleteResourceProgress;
+	public static String operation_cannotRenameDefaultPackage;
+	public static String operation_pathOutsideProject;
+	public static String operation_sortelements;
+	public static String workingCopy_commit;
+	public static String buffer_closed;
+	public static String build_preparingBuild;
+	public static String build_readStateProgress;
+	public static String build_saveStateProgress;
+	public static String build_saveStateComplete;
+	public static String build_readingDelta;
+	public static String build_analyzingDeltas;
+	public static String build_analyzingSources;
+	public static String build_cleaningOutput;
+	public static String build_copyingResources;
+	public static String build_compiling;
+	public static String build_foundHeader;
+	public static String build_fixedHeader;
+	public static String build_oneError;
+	public static String build_oneWarning;
+	public static String build_multipleErrors;
+	public static String build_multipleWarnings;
+	public static String build_done;
+	public static String build_wrongFileFormat;
+	public static String build_cannotSaveState;
+	public static String build_cannotSaveStates;
+	public static String build_initializationError;
+	public static String build_serializationError;
+	public static String build_classFileCollision;
+	public static String build_duplicateClassFile;
+	public static String build_duplicateResource;
+	public static String build_inconsistentClassFile;
+	public static String build_inconsistentProject;
+	public static String build_incompleteClassPath;
+	public static String build_missingSourceFile;
+	public static String build_prereqProjectHasClasspathProblems;
+	public static String build_prereqProjectMustBeRebuilt;
+	public static String build_abortDueToClasspathProblems;
+	public static String status_cannot_retrieve_attached_javadoc;
+	public static String status_timeout_javadoc;
+	public static String status_cannotUseDeviceOnPath;
+	public static String status_coreException;
+	public static String status_defaultPackageReadOnly;
+	public static String status_evaluationError;
+	public static String status_JDOMError;
+	public static String status_IOException;
+	public static String status_indexOutOfBounds;
+	public static String status_invalidContents;
+	public static String status_invalidDestination;
+	public static String status_invalidName;
+	public static String status_invalidPackage;
+	public static String status_invalidPath;
+	public static String status_invalidProject;
+	public static String status_invalidResource;
+	public static String status_invalidResourceType;
+	public static String status_invalidSibling;
+	public static String status_nameCollision;
+	public static String status_noLocalContents;
+	public static String status_OK;
+	public static String status_readOnly;
+	public static String status_targetException;
+	public static String status_unknown_javadoc_format;
+	public static String status_updateConflict;
+	public static String classpath_buildPath;
+	public static String classpath_cannotNestEntryInEntry;
+	public static String classpath_cannotNestEntryInEntryNoExclusion;
+	public static String classpath_cannotNestEntryInLibrary;
+	public static String classpath_cannotNestEntryInOutput;
+	public static String classpath_cannotNestOutputInEntry;
+	public static String classpath_cannotNestOutputInOutput;
+	public static String classpath_cannotReadClasspathFile;
+	public static String classpath_cannotReferToItself;
+	public static String classpath_cannotUseDistinctSourceFolderAsOutput;
+	public static String classpath_cannotUseLibraryAsOutput;
+	public static String classpath_closedProject;
+	public static String classpath_couldNotWriteClasspathFile;
+	public static String classpath_cycle;
+	public static String classpath_duplicateEntryPath;
+	public static String classpath_illegalContainerPath;
+	public static String classpath_illegalEntryInClasspathFile;
+	public static String classpath_illegalLibraryPath;
+	public static String classpath_illegalLibraryPathInContainer;
+	public static String classpath_illegalLibraryArchive;
+	public static String classpath_archiveReadError;
+	public static String classpath_illegalExternalFolder;
+	public static String classpath_illegalExternalFolderInContainer;
+	public static String classpath_illegalProjectPath;
+	public static String classpath_illegalSourceFolderPath;
+	public static String classpath_illegalVariablePath;
+	public static String classpath_invalidClasspathInClasspathFile;
+	public static String classpath_invalidContainer;
+	public static String classpath_mustEndWithSlash;
+	public static String classpath_unboundContainerPath;
+	public static String classpath_unboundLibrary;
+	public static String classpath_userLibraryInfo;
+	public static String classpath_containerInfo;
+	public static String classpath_unboundLibraryInContainer;
+	public static String classpath_unboundProject;
+	public static String classpath_settingOutputLocationProgress;
+	public static String classpath_settingProgress;
+	public static String classpath_unboundSourceAttachment;
+	public static String classpath_unboundSourceAttachmentInContainedLibrary;
+	public static String classpath_unboundSourceFolder;
+	public static String classpath_unboundVariablePath;
+	public static String classpath_unknownKind;
+	public static String classpath_xmlFormatError;
+	public static String classpath_disabledInclusionExclusionPatterns;
+	public static String classpath_disabledMultipleOutputLocations;
+	public static String classpath_incompatibleLibraryJDKLevel;
+	public static String classpath_incompatibleLibraryJDKLevelInContainer;
+	public static String classpath_duplicateEntryExtraAttribute;
+	public static String classpath_deprecated_variable;
+	public static String file_notFound;
+	public static String file_badFormat;
+	public static String path_nullPath;
+	public static String path_mustBeAbsolute;
+	public static String cache_invalidLoadFactor;
+	public static String savedState_jobName;
+	public static String refreshing_external_folders;
+	public static String updating_external_archives_jobName;
+	public static String convention_unit_nullName;
+	public static String convention_unit_notJavaName;
+	public static String convention_classFile_nullName;
+	public static String convention_classFile_notClassFileName;
+	public static String convention_illegalIdentifier;
+	public static String convention_import_nullImport;
+	public static String convention_import_unqualifiedImport;
+	public static String convention_type_nullName;
+	public static String convention_type_nameWithBlanks;
+	public static String convention_type_dollarName;
+	public static String convention_type_lowercaseName;
+	public static String convention_type_invalidName;
+	public static String convention_package_nullName;
+	public static String convention_package_emptyName;
+	public static String convention_package_dotName;
+	public static String convention_package_nameWithBlanks;
+	public static String convention_package_consecutiveDotsName;
+	public static String convention_package_uppercaseName;
+	public static String dom_cannotDetail;
+	public static String dom_nullTypeParameter;
+	public static String dom_nullNameParameter;
+	public static String dom_nullReturnType;
+	public static String dom_nullExceptionType;
+	public static String dom_mismatchArgNamesAndTypes;
+	public static String dom_addNullChild;
+	public static String dom_addIncompatibleChild;
+	public static String dom_addChildWithParent;
+	public static String dom_unableAddChild;
+	public static String dom_addAncestorAsChild;
+	public static String dom_addNullSibling;
+	public static String dom_addSiblingBeforeRoot;
+	public static String dom_addIncompatibleSibling;
+	public static String dom_addSiblingWithParent;
+	public static String dom_addAncestorAsSibling;
+	public static String dom_addNullInterface;
+	public static String dom_nullInterfaces;
+	public static String importRewrite_processDescription;
+	public static String correction_nullRequestor;
+	public static String correction_nullUnit;
+	public static String engine_completing;
+	public static String engine_searching;
+	public static String engine_searching_indexing;
+	public static String engine_searching_matching;
+	public static String exception_wrongFormat;
+	public static String process_name;
+	public static String jobmanager_filesToIndex;
+	public static String jobmanager_indexing;
+	public static String disassembler_description;
+	public static String disassembler_opentypedeclaration;
+	public static String disassembler_closetypedeclaration;
+	public static String disassembler_parametername;
+	public static String disassembler_localvariablename;
+	public static String disassembler_endofmethodheader;
+	public static String disassembler_begincommentline;
+	public static String disassembler_fieldhasconstant;
+	public static String disassembler_endoffieldheader;
+	public static String disassembler_sourceattributeheader;
+	public static String disassembler_enclosingmethodheader;
+	public static String disassembler_exceptiontableheader;
+	public static String disassembler_linenumberattributeheader;
+	public static String disassembler_localvariabletableattributeheader;
+	public static String disassembler_localvariabletypetableattributeheader;
+	public static String disassembler_arraydimensions;
+	public static String disassembler_innerattributesheader;
+	public static String disassembler_inner_class_info_name;
+	public static String disassembler_outer_class_info_name;
+	public static String disassembler_inner_name;
+	public static String disassembler_inner_accessflags;
+	public static String disassembler_genericattributeheader;
+	public static String disassembler_signatureattributeheader;
+	public static String disassembler_bootstrapmethodattributesheader;
+	public static String disassembler_bootstrapmethodentry;
+	public static String disassembler_bootstrapmethodentry_argument;
+	public static String disassembler_indentation;
+	public static String disassembler_constantpoolindex;
+	public static String disassembler_space;
+	public static String disassembler_comma;
+	public static String disassembler_openinnerclassentry;
+	public static String disassembler_closeinnerclassentry;
+	public static String disassembler_deprecated;
+	public static String disassembler_constantpoolheader;
+	public static String disassembler_constantpool_class;
+	public static String disassembler_constantpool_double;
+	public static String disassembler_constantpool_float;
+	public static String disassembler_constantpool_integer;
+	public static String disassembler_constantpool_long;
+	public static String disassembler_constantpool_string;
+	public static String disassembler_constantpool_fieldref;
+	public static String disassembler_constantpool_interfacemethodref;
+	public static String disassembler_constantpool_methodref;
+	public static String disassembler_constantpool_name_and_type;
+	public static String disassembler_constantpool_utf8;
+	public static String disassembler_constantpool_methodhandle;
+	public static String disassembler_constantpool_methodtype;
+	public static String disassembler_constantpool_invokedynamic;
+	public static String disassembler_annotationdefaultheader;
+	public static String disassembler_annotationdefaultvalue;
+	public static String disassembler_annotationenumvalue;
+	public static String disassembler_annotationclassvalue;
+	public static String disassembler_annotationannotationvalue;
+	public static String disassembler_annotationarrayvaluestart;
+	public static String disassembler_annotationarrayvalueend;
+	public static String disassembler_annotationentrystart;
+	public static String disassembler_annotationentryend;
+	public static String disassembler_annotationcomponent;
+	// jsr308
+	public static String disassembler_extendedannotationentrystart;
+	public static String disassembler_extendedannotationentryend;
+	public static String disassembler_runtimevisibletypeannotationsattributeheader;
+	public static String disassembler_runtimeinvisibletypeannotationsattributeheader;
+	public static String disassembler_extendedannotation_classextendsimplements;
+	public static String disassembler_extendedannotation_typepath;
+	public static String disassembler_extendedannotation_method_parameter;
+	public static String disassembler_extendedannotation_offset;
+	public static String disassembler_extendedannotation_throws;
+	public static String disassembler_extendedannotation_type_argument;
+	public static String disassembler_extendedannotation_type_parameter;
+	public static String disassembler_extendedannotation_type_parameter_with_bound;
+	public static String disassembler_extendedannotation_wildcardlocationtype;
+	public static String disassembler_extendedannotation_targetType;
+	public static String disassembler_extendedannotation_wildcardlocations;
+	public static String disassembler_extendedannotation_exception_table_index;
+	public static String disassembler_extendedannotation_typepath_array;
+	public static String disassembler_extendedannotation_typepath_wildcard;
+	public static String disassembler_extendedannotation_typepath_typeargument;
+	public static String disassembler_extendedannotation_typepath_innertype;
+	public static String disassembler_localvariabletargetheader;
+
+	public static String disassembler_runtimevisibleannotationsattributeheader;
+	public static String disassembler_runtimeinvisibleannotationsattributeheader;
+	public static String disassembler_runtimevisibleparameterannotationsattributeheader;
+	public static String disassembler_runtimeinvisibleparameterannotationsattributeheader;
+	public static String disassembler_parameterannotationentrystart;
+	public static String disassembler_stackmaptableattributeheader;
+	public static String disassembler_stackmapattributeheader;
+	public static String classfileformat_versiondetails;
+	public static String classfileformat_methoddescriptor;
+	public static String classfileformat_fieldddescriptor;
+	public static String classfileformat_stacksAndLocals;
+	public static String classfileformat_superflagisnotset;
+	public static String classfileformat_superflagisset;
+	public static String classfileformat_clinitname;
+	// jsr308
+	public static String classfileformat_localvariablereferenceinfoentry;
+
+	public static String classformat_classformatexception;
+	public static String classformat_anewarray;
+	public static String classformat_checkcast;
+	public static String classformat_instanceof;
+	public static String classformat_ldc_w_class;
+	public static String classformat_ldc_w_float;
+	public static String classformat_ldc_w_integer;
+	public static String classformat_ldc_w_string;
+	public static String classformat_ldc2_w_long;
+	public static String classformat_ldc2_w_double;
+	public static String classformat_multianewarray;
+	public static String classformat_new;
+	public static String classformat_iinc;
+	public static String classformat_invokespecial;
+	public static String classformat_invokeinterface;
+	public static String classformat_invokestatic;
+	public static String classformat_invokevirtual;
+	public static String classformat_invokedynamic;
+	public static String classformat_getfield;
+	public static String classformat_getstatic;
+	public static String classformat_putstatic;
+	public static String classformat_putfield;
+	public static String classformat_newarray_boolean;
+	public static String classformat_newarray_char;
+	public static String classformat_newarray_float;
+	public static String classformat_newarray_double;
+	public static String classformat_newarray_byte;
+	public static String classformat_newarray_short;
+	public static String classformat_newarray_int;
+	public static String classformat_newarray_long;
+	public static String classformat_store;
+	public static String classformat_load;
+	public static String classfileformat_anyexceptionhandler;
+	public static String classfileformat_exceptiontableentry;
+	public static String classfileformat_linenumbertableentry;
+	public static String classfileformat_localvariabletableentry;
+	public static String classfileformat_versionUnknown;
+
+	public static String disassembler_frame_same_locals_1_stack_item_extended;
+	public static String disassembler_frame_chop;
+	public static String disassembler_frame_same_frame_extended;
+	public static String disassembler_frame_append;
+	public static String disassembler_frame_full_frame;
+	public static String disassembler_frame_same_frame;
+	public static String disassembler_frame_same_locals_1_stack_item;
+	public static String code_assist_internal_error;
+	
+	public static String disassembler_method_type_ref_getfield;
+	public static String disassembler_method_type_ref_putfield;
+	public static String disassembler_method_type_ref_getstatic;
+	public static String disassembler_method_type_ref_putstatic;
+	public static String disassembler_method_type_ref_invokestatic;
+	public static String disassembler_method_type_ref_invokevirtual;
+	public static String disassembler_method_type_ref_invokespecial;
+	public static String disassembler_method_type_ref_invokeinterface;
+	public static String disassembler_method_type_ref_newinvokespecial;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @return the manipulated String
+	 */
+	public static String bind(String message) {
+		return bind(message, null);
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param binding the object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding) {
+		return bind(message, new Object[] {binding});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param binding1 An object to be inserted into the message
+	 * @param binding2 A second object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding1, Object binding2) {
+		return bind(message, new Object[] {binding1, binding2});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 *
+	 * @param message the message to be manipulated
+	 * @param bindings An array of objects to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object[] bindings) {
+		return MessageFormat.format(message, bindings);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java
new file mode 100644
index 0000000..71bf782
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAttributeNamesConstants;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IExceptionAttribute;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.core.util.IModifierConstants;
+
+/**
+ * Default implementation of IMethodInfo.
+ */
+public class MethodInfo extends ClassFileStruct implements IMethodInfo {
+	private int accessFlags;
+	private int attributeBytes;
+	private IClassFileAttribute[] attributes;
+	private int attributesCount;
+	private ICodeAttribute codeAttribute;
+	private char[] descriptor;
+	private int descriptorIndex;
+	private IExceptionAttribute exceptionAttribute;
+	private boolean isDeprecated;
+	private boolean isSynthetic;
+	private char[] name;
+	private int nameIndex;
+
+	/**
+	 * @param classFileBytes byte[]
+	 * @param constantPool IConstantPool
+	 * @param offset int
+	 * @param decodingFlags int
+	 */
+	public MethodInfo(byte classFileBytes[], IConstantPool constantPool, int offset, int decodingFlags)
+		throws ClassFormatException {
+
+		boolean no_code_attribute = (decodingFlags & IClassFileReader.METHOD_BODIES) == 0;
+		final int flags = u2At(classFileBytes, 0, offset);
+		this.accessFlags = flags;
+		if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) {
+			this.isSynthetic = true;
+		}
+
+		this.nameIndex = u2At(classFileBytes, 2, offset);
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.name = constantPoolEntry.getUtf8Value();
+
+		this.descriptorIndex = u2At(classFileBytes, 4, offset);
+		constantPoolEntry = constantPool.decodeEntry(this.descriptorIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.descriptor = constantPoolEntry.getUtf8Value();
+
+		this.attributesCount = u2At(classFileBytes, 6, offset);
+		this.attributes = ClassFileAttribute.NO_ATTRIBUTES;
+		if (this.attributesCount != 0) {
+			if (no_code_attribute && !isAbstract() && !isNative()) {
+				if (this.attributesCount != 1) {
+					this.attributes = new IClassFileAttribute[this.attributesCount - 1];
+				}
+			} else {
+				this.attributes = new IClassFileAttribute[this.attributesCount];
+			}
+		}
+		int attributesIndex = 0;
+		int readOffset = 8;
+		for (int i = 0; i < this.attributesCount; i++) {
+			constantPoolEntry = constantPool.decodeEntry(u2At(classFileBytes, readOffset, offset));
+			if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+				throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+			}
+			char[] attributeName = constantPoolEntry.getUtf8Value();
+			if (equals(attributeName, IAttributeNamesConstants.DEPRECATED)) {
+				this.isDeprecated = true;
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.SYNTHETIC)) {
+				this.isSynthetic = true;
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.CODE)) {
+				if (!no_code_attribute) {
+					this.codeAttribute = new CodeAttribute(classFileBytes, constantPool, offset + readOffset);
+					this.attributes[attributesIndex++] = this.codeAttribute;
+				}
+			} else if (equals(attributeName, IAttributeNamesConstants.EXCEPTIONS)) {
+				this.exceptionAttribute = new ExceptionAttribute(classFileBytes, constantPool, offset + readOffset);
+				this.attributes[attributesIndex++] = this.exceptionAttribute;
+			} else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) {
+				this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleParameterAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleParameterAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.ANNOTATION_DEFAULT)) {
+				this.attributes[attributesIndex++] = new AnnotationDefaultAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeVisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS)) {
+				this.attributes[attributesIndex++] = new RuntimeInvisibleTypeAnnotationsAttribute(classFileBytes, constantPool, offset + readOffset);
+			} else {
+				this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
+			}
+			readOffset += (6 + u4At(classFileBytes, readOffset + 2, offset));
+		}
+		this.attributeBytes = readOffset;
+	}
+	/**
+	 * @see IMethodInfo#getAccessFlags()
+	 */
+	public int getAccessFlags() {
+		return this.accessFlags;
+	}
+
+	/**
+	 * @see IMethodInfo#getAttributeCount()
+	 */
+	public int getAttributeCount() {
+		return this.attributesCount;
+	}
+	/**
+	 * @see IMethodInfo#getAttributes()
+	 */
+	public IClassFileAttribute[] getAttributes() {
+		return this.attributes;
+	}
+
+	/**
+	 * @see IMethodInfo#getCodeAttribute()
+	 */
+	public ICodeAttribute getCodeAttribute() {
+		return this.codeAttribute;
+	}
+
+	/**
+	 * @see IMethodInfo#getDescriptor()
+	 */
+	public char[] getDescriptor() {
+		return this.descriptor;
+	}
+
+	/**
+	 * @see IMethodInfo#getDescriptorIndex()
+	 */
+	public int getDescriptorIndex() {
+		return this.descriptorIndex;
+	}
+
+	/**
+	 * @see IMethodInfo#getExceptionAttribute()
+	 */
+	public IExceptionAttribute getExceptionAttribute() {
+		return this.exceptionAttribute;
+	}
+
+	/**
+	 * @see IMethodInfo#getName()
+	 */
+	public char[] getName() {
+		return this.name;
+	}
+
+	/**
+	 * @see IMethodInfo#getNameIndex()
+	 */
+	public int getNameIndex() {
+		return this.nameIndex;
+	}
+
+	private boolean isAbstract() {
+		return (this.accessFlags & IModifierConstants.ACC_ABSTRACT) != 0;
+	}
+
+	/**
+	 * @see IMethodInfo#isClinit()
+	 */
+	public boolean isClinit() {
+		return this.name[0] == '<' && this.name.length == 8; // Can only match <clinit>
+	}
+
+	/**
+	 * @see IMethodInfo#isConstructor()
+	 */
+	public boolean isConstructor() {
+		return this.name[0] == '<' && this.name.length == 6; // Can only match <init>
+	}
+
+	/**
+	 * @see IMethodInfo#isDeprecated()
+	 */
+	public boolean isDeprecated() {
+		return this.isDeprecated;
+	}
+
+	private boolean isNative() {
+		return (this.accessFlags & IModifierConstants.ACC_NATIVE) != 0;
+	}
+
+	/**
+	 * @see IMethodInfo#isSynthetic()
+	 */
+	public boolean isSynthetic() {
+		return this.isSynthetic;
+	}
+
+	int sizeInBytes() {
+		return this.attributeBytes;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
new file mode 100644
index 0000000..42a24cf
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotation;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IParameterAnnotation;
+
+/**
+ * Default implementation of IParameterAnnotation
+ */
+public class ParameterAnnotation extends ClassFileStruct implements IParameterAnnotation {
+
+	private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0];
+
+	private int annotationsNumber;
+	private IAnnotation[] annotations;
+	private int readOffset;
+
+	/**
+	 * Constructor for Annotation.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public ParameterAnnotation(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+
+		final int length = u2At(classFileBytes, 0, offset);
+		this.readOffset = 2;
+		this.annotationsNumber = length;
+		if (length != 0) {
+			this.annotations = new IAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				Annotation annotation = new Annotation(classFileBytes, constantPool, offset + this.readOffset);
+				this.annotations[i] = annotation;
+				this.readOffset += annotation.sizeInBytes();
+			}
+		} else {
+			this.annotations = NO_ENTRIES;
+		}
+	}
+
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IParameterAnnotation#getAnnotations()
+	 */
+	public IAnnotation[] getAnnotations() {
+		return this.annotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IParameterAnnotation#getAnnotationsNumber()
+	 */
+	public int getAnnotationsNumber() {
+		return this.annotationsNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
new file mode 100644
index 0000000..836c55c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
@@ -0,0 +1,4148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IScanner;
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.NLSTag;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class PublicScanner implements IScanner, ITerminalSymbols {
+
+	//public int newIdentCount = 0;
+
+	/* APIs ares
+	 - getNextToken() which return the current type of the token
+	   (this value is not memorized by the scanner)
+	 - getCurrentTokenSource() which provides with the token "REAL" source
+	   (aka all unicode have been transformed into a correct char)
+	 - sourceStart gives the position into the stream
+	 - currentPosition-1 gives the sourceEnd position into the stream
+	*/
+	public long sourceLevel;
+	public long complianceLevel;
+
+	// 1.4 feature
+	public boolean useAssertAsAnIndentifier = false;
+	//flag indicating if processed source contains occurrences of keyword assert
+	public boolean containsAssertKeyword = false;
+
+	// 1.5 feature
+	public boolean useEnumAsAnIndentifier = false;
+
+	public boolean recordLineSeparator = false;
+	public char currentCharacter;
+	public int startPosition;
+	public int currentPosition;
+	public int initialPosition, eofPosition;
+	// after this position eof are generated instead of real token from the source
+
+	public boolean skipComments = false;
+	public boolean tokenizeComments = false;
+	public boolean tokenizeWhiteSpace = false;
+
+	//source should be viewed as a window (aka a part)
+	//of a entire very large stream
+	public char source[];
+
+	//unicode support
+	public char[] withoutUnicodeBuffer;
+	public int withoutUnicodePtr; //when == 0 ==> no unicode in the current token
+	public boolean unicodeAsBackSlash = false;
+
+	public boolean scanningFloatLiteral = false;
+
+	//support for /** comments
+	public final static int COMMENT_ARRAYS_SIZE = 30;
+	public int[] commentStops = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int commentPtr = -1; // no comment test with commentPtr value -1
+	protected int lastCommentLinePosition = -1;
+
+	// task tag support
+	public char[][] foundTaskTags = null;
+	public char[][] foundTaskMessages;
+	public char[][] foundTaskPriorities = null;
+	public int[][] foundTaskPositions;
+	public int foundTaskCount = 0;
+	public char[][] taskTags = null;
+	public char[][] taskPriorities = null;
+	public boolean isTaskCaseSensitive = true;
+
+	//diet parsing support - jump over some method body when requested
+	public boolean diet = false;
+
+	//support for the  poor-line-debuggers ....
+	//remember the position of the cr/lf
+	public int[] lineEnds = new int[250];
+	public int linePtr = -1;
+	public boolean wasAcr = false;
+
+	public static final String END_OF_SOURCE = "End_Of_Source"; //$NON-NLS-1$
+
+	public static final String INVALID_HEXA = "Invalid_Hexa_Literal"; //$NON-NLS-1$
+	public static final String INVALID_OCTAL = "Invalid_Octal_Literal"; //$NON-NLS-1$
+	public static final String INVALID_CHARACTER_CONSTANT = "Invalid_Character_Constant";  //$NON-NLS-1$
+	public static final String INVALID_ESCAPE = "Invalid_Escape"; //$NON-NLS-1$
+	public static final String INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
+	public static final String INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
+	public static final String INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
+	public static final String INVALID_LOW_SURROGATE = "Invalid_Low_Surrogate"; //$NON-NLS-1$
+	public static final String INVALID_HIGH_SURROGATE = "Invalid_High_Surrogate"; //$NON-NLS-1$
+
+	public static final String NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
+	public static final String UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
+	public static final String UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
+	public static final String INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
+	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$
+	private static final int[] EMPTY_LINE_ENDS = Util.EMPTY_INT_ARRAY;
+
+	public static final String INVALID_BINARY = "Invalid_Binary_Literal"; //$NON-NLS-1$
+	public static final String BINARY_LITERAL_NOT_BELOW_17 = "Binary_Literal_Not_Below_17"; //$NON-NLS-1$
+	public static final String ILLEGAL_HEXA_LITERAL = "Illegal_Hexa_Literal"; //$NON-NLS-1$
+	public static final String INVALID_UNDERSCORE = "Invalid_Underscore"; //$NON-NLS-1$
+	public static final String UNDERSCORES_IN_LITERALS_NOT_BELOW_17 = "Underscores_In_Literals_Not_Below_17"; //$NON-NLS-1$`
+
+	//----------------optimized identifier managment------------------
+	static final char[] charArray_a = new char[] {'a'},
+		charArray_b = new char[] {'b'},
+		charArray_c = new char[] {'c'},
+		charArray_d = new char[] {'d'},
+		charArray_e = new char[] {'e'},
+		charArray_f = new char[] {'f'},
+		charArray_g = new char[] {'g'},
+		charArray_h = new char[] {'h'},
+		charArray_i = new char[] {'i'},
+		charArray_j = new char[] {'j'},
+		charArray_k = new char[] {'k'},
+		charArray_l = new char[] {'l'},
+		charArray_m = new char[] {'m'},
+		charArray_n = new char[] {'n'},
+		charArray_o = new char[] {'o'},
+		charArray_p = new char[] {'p'},
+		charArray_q = new char[] {'q'},
+		charArray_r = new char[] {'r'},
+		charArray_s = new char[] {'s'},
+		charArray_t = new char[] {'t'},
+		charArray_u = new char[] {'u'},
+		charArray_v = new char[] {'v'},
+		charArray_w = new char[] {'w'},
+		charArray_x = new char[] {'x'},
+		charArray_y = new char[] {'y'},
+		charArray_z = new char[] {'z'};
+
+	static final char[] initCharArray =
+		new char[] {'\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000'};
+	static final int TableSize = 30, InternalTableSize = 6; //30*6 =210 entries
+
+	public static final int OptimizedLength = 7;
+	public /*static*/ final char[][][][] charArray_length =
+		new char[OptimizedLength][TableSize][InternalTableSize][];
+	// support for detecting non-externalized string literals
+	public static final char[] TAG_PREFIX= "//$NON-NLS-".toCharArray(); //$NON-NLS-1$
+	public static final int TAG_PREFIX_LENGTH= TAG_PREFIX.length;
+	public static final char TAG_POSTFIX= '$';
+	public static final int TAG_POSTFIX_LENGTH= 1;
+	private NLSTag[] nlsTags = null;
+	protected int nlsTagsPtr;
+	public boolean checkNonExternalizedStringLiterals;
+
+	protected int lastPosition;
+
+	// generic support
+	public boolean returnOnlyGreater = false;
+
+	/*static*/ {
+		for (int i = 0; i < 6; i++) {
+			for (int j = 0; j < TableSize; j++) {
+				for (int k = 0; k < InternalTableSize; k++) {
+					this.charArray_length[i][j][k] = initCharArray;
+				}
+			}
+		}
+	}
+	/*static*/ int newEntry2 = 0,
+		newEntry3 = 0,
+		newEntry4 = 0,
+		newEntry5 = 0,
+		newEntry6 = 0;
+	public boolean insideRecovery = false;
+
+	public static final int RoundBracket = 0;
+	public static final int SquareBracket = 1;
+	public static final int CurlyBracket = 2;
+	public static final int BracketKinds = 3;
+
+	// extended unicode support
+	public static final int LOW_SURROGATE_MIN_VALUE = 0xDC00;
+	public static final int HIGH_SURROGATE_MIN_VALUE = 0xD800;
+	public static final int HIGH_SURROGATE_MAX_VALUE = 0xDBFF;
+	public static final int LOW_SURROGATE_MAX_VALUE = 0xDFFF;
+
+public PublicScanner() {
+	this(false /*comment*/, false /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
+}
+
+public PublicScanner(
+		boolean tokenizeComments,
+		boolean tokenizeWhiteSpace,
+		boolean checkNonExternalizedStringLiterals,
+		long sourceLevel,
+		long complianceLevel,
+		char[][] taskTags,
+		char[][] taskPriorities,
+		boolean isTaskCaseSensitive) {
+
+	this.eofPosition = Integer.MAX_VALUE;
+	this.tokenizeComments = tokenizeComments;
+	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
+	this.sourceLevel = sourceLevel;
+	this.complianceLevel = complianceLevel;
+	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
+	if (taskTags != null) {
+		int taskTagsLength = taskTags.length;
+		int length = taskTagsLength;
+		if (taskPriorities != null) {
+			int taskPrioritiesLength = taskPriorities.length;
+			if (taskPrioritiesLength != taskTagsLength) {
+				if (taskPrioritiesLength > taskTagsLength) {
+					System.arraycopy(taskPriorities, 0, (taskPriorities = new char[taskTagsLength][]), 0, taskTagsLength);
+				} else {
+					System.arraycopy(taskTags, 0, (taskTags = new char[taskPrioritiesLength][]), 0, taskPrioritiesLength);
+					length = taskPrioritiesLength;
+				}
+			}
+			int[] initialIndexes = new int[length];
+			for (int i = 0; i < length; i++) {
+				initialIndexes[i] = i;
+			}
+			Util.reverseQuickSort(taskTags, 0, length - 1, initialIndexes);
+			char[][] temp = new char[length][];
+			for (int i = 0; i < length; i++) {
+				temp[i] = taskPriorities[initialIndexes[i]];
+			}
+			this.taskPriorities = temp;
+		} else {
+			Util.reverseQuickSort(taskTags, 0, length - 1);
+		}
+		this.taskTags = taskTags;
+		this.isTaskCaseSensitive = isTaskCaseSensitive;
+	}
+}
+
+public PublicScanner(
+		boolean tokenizeComments,
+		boolean tokenizeWhiteSpace,
+		boolean checkNonExternalizedStringLiterals,
+		long sourceLevel,
+		char[][] taskTags,
+		char[][] taskPriorities,
+		boolean isTaskCaseSensitive) {
+
+	this(
+		tokenizeComments,
+		tokenizeWhiteSpace,
+		checkNonExternalizedStringLiterals,
+		sourceLevel,
+		sourceLevel,
+		taskTags,
+		taskPriorities,
+		isTaskCaseSensitive);
+}
+
+public final boolean atEnd() {
+	// This code is not relevant if source is
+	// Only a part of the real stream input
+
+	return this.eofPosition <= this.currentPosition;
+}
+
+// chech presence of task: tags
+// TODO (frederic) see if we need to take unicode characters into account...
+public void checkTaskTag(int commentStart, int commentEnd) throws InvalidInputException {
+	char[] src = this.source;
+
+	// only look for newer task: tags
+	if (this.foundTaskCount > 0
+		&& this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) {
+		return;
+	}
+	int foundTaskIndex = this.foundTaskCount;
+	char previous = src[commentStart+1]; // should be '*' or '/'
+	for (
+		int i = commentStart + 2; i < commentEnd && i < this.eofPosition; i++) {
+		char[] tag = null;
+		char[] priority = null;
+		// check for tag occurrence only if not ambiguous with javadoc tag
+		if (previous != '@') {
+			nextTag : for (int itag = 0; itag < this.taskTags.length; itag++) {
+				tag = this.taskTags[itag];
+				int tagLength = tag.length;
+				if (tagLength == 0) continue nextTag;
+
+				// ensure tag is not leaded with letter if tag starts with a letter
+				if (ScannerHelper.isJavaIdentifierStart(this.complianceLevel, tag[0])) {
+					if (ScannerHelper.isJavaIdentifierPart(this.complianceLevel, previous)) {
+						continue nextTag;
+					}
+				}
+
+				for (int t = 0; t < tagLength; t++) {
+					char sc, tc;
+					int x = i+t;
+					if (x >= this.eofPosition || x >= commentEnd) continue nextTag;
+					// case sensitive check
+					if ((sc = src[i + t]) != (tc = tag[t])) {
+						// case insensitive check
+						if (this.isTaskCaseSensitive || (ScannerHelper.toLowerCase(sc) != ScannerHelper.toLowerCase(tc))) {
+							continue nextTag;
+						}
+					}
+				}
+				// ensure tag is not followed with letter if tag finishes with a letter
+				if (i+tagLength < commentEnd && ScannerHelper.isJavaIdentifierPart(this.complianceLevel, src[i+tagLength-1])) {
+					if (ScannerHelper.isJavaIdentifierPart(this.complianceLevel, src[i + tagLength]))
+						continue nextTag;
+				}
+				if (this.foundTaskTags == null) {
+					this.foundTaskTags = new char[5][];
+					this.foundTaskMessages = new char[5][];
+					this.foundTaskPriorities = new char[5][];
+					this.foundTaskPositions = new int[5][];
+				} else if (this.foundTaskCount == this.foundTaskTags.length) {
+					System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+					System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, this.foundTaskCount);
+				}
+
+				priority = this.taskPriorities != null && itag < this.taskPriorities.length
+							? this.taskPriorities[itag]
+							: null;
+
+				this.foundTaskTags[this.foundTaskCount] = tag;
+				this.foundTaskPriorities[this.foundTaskCount] = priority;
+				this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 };
+				this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR;
+				this.foundTaskCount++;
+				i += tagLength - 1; // will be incremented when looping
+				break nextTag;
+			}
+		}
+		previous = src[i];
+	}
+	boolean containsEmptyTask = false;
+	for (int i = foundTaskIndex; i < this.foundTaskCount; i++) {
+		// retrieve message start and end positions
+		int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length;
+		int max_value = i + 1 < this.foundTaskCount
+				? this.foundTaskPositions[i + 1][0] - 1
+				: commentEnd - 1;
+		// at most beginning of next task
+		if (max_value < msgStart) {
+			max_value = msgStart; // would only occur if tag is before EOF.
+		}
+		int end = -1;
+		char c;
+		for (int j = msgStart; j < max_value; j++) {
+			if ((c = src[j]) == '\n' || c == '\r') {
+				end = j - 1;
+				break;
+			}
+		}
+		if (end == -1) {
+			for (int j = max_value; j > msgStart; j--) {
+				if ((c = src[j]) == '*') {
+					end = j - 1;
+					break;
+				}
+			}
+			if (end == -1)
+				end = max_value;
+		}
+		if (msgStart == end) {
+			// if the description is empty, we might want to see if two tags are not sharing the same message
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=110797
+			containsEmptyTask = true;
+			continue;
+		}
+		// trim the message
+		// we don't trim the beginning of the message to be able to show it after the task tag
+		while (CharOperation.isWhitespace(src[end]) && msgStart <= end)
+			end--;
+		// update the end position of the task
+		this.foundTaskPositions[i][1] = end;
+		// get the message source
+		final int messageLength = end - msgStart + 1;
+		char[] message = new char[messageLength];
+		System.arraycopy(src, msgStart, message, 0, messageLength);
+		this.foundTaskMessages[i] = message;
+	}
+	if (containsEmptyTask) {
+		for (int i = foundTaskIndex, max = this.foundTaskCount; i < max; i++) {
+			if (this.foundTaskMessages[i].length == 0) {
+				loop: for (int j = i + 1; j < max; j++) {
+					if (this.foundTaskMessages[j].length != 0) {
+						this.foundTaskMessages[i] = this.foundTaskMessages[j];
+						this.foundTaskPositions[i][1] = this.foundTaskPositions[j][1];
+						break loop;
+					}
+				}
+			}
+		}
+	}
+}
+
+public char[] getCurrentIdentifierSource() {
+	//return the token REAL source (aka unicodes are precomputed)
+	if (this.withoutUnicodePtr != 0) {
+		//0 is used as a fast test flag so the real first char is in position 1
+		char[] result = new char[this.withoutUnicodePtr];
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			result,
+			0,
+			this.withoutUnicodePtr);
+		return result;
+	}
+	int length = this.currentPosition - this.startPosition;
+	if (length == this.eofPosition) return this.source;
+	switch (length) { // see OptimizedLength
+		case 1 :
+			return optimizedCurrentTokenSource1();
+		case 2 :
+			return optimizedCurrentTokenSource2();
+		case 3 :
+			return optimizedCurrentTokenSource3();
+		case 4 :
+			return optimizedCurrentTokenSource4();
+		case 5 :
+			return optimizedCurrentTokenSource5();
+		case 6 :
+			return optimizedCurrentTokenSource6();
+	}
+	char[] result = new char[length];
+	System.arraycopy(this.source, this.startPosition, result, 0, length);
+	return result;
+}
+public int getCurrentTokenEndPosition(){
+	return this.currentPosition - 1;
+}
+public char[] getCurrentTokenSource() {
+	// Return the token REAL source (aka unicodes are precomputed)
+
+	char[] result;
+	if (this.withoutUnicodePtr != 0)
+		// 0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			result = new char[this.withoutUnicodePtr],
+			0,
+			this.withoutUnicodePtr);
+	else {
+		int length;
+		System.arraycopy(
+			this.source,
+			this.startPosition,
+			result = new char[length = this.currentPosition - this.startPosition],
+			0,
+			length);
+	}
+	return result;
+}
+public final String getCurrentTokenString() {
+	// Return current token as a string
+
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		return new String(
+			this.withoutUnicodeBuffer,
+			1,
+			this.withoutUnicodePtr);
+	}
+	return new String(
+		this.source,
+		this.startPosition,
+		this.currentPosition - this.startPosition);
+}
+public char[] getCurrentTokenSourceString() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
+
+	char[] result;
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(this.withoutUnicodeBuffer, 2,
+		//2 is 1 (real start) + 1 (to jump over the ")
+		result = new char[this.withoutUnicodePtr - 2], 0, this.withoutUnicodePtr - 2);
+	else {
+		int length;
+		System.arraycopy(
+			this.source,
+			this.startPosition + 1,
+			result = new char[length = this.currentPosition - this.startPosition - 2],
+			0,
+			length);
+	}
+	return result;
+}
+public final String getCurrentStringLiteral() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
+
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		//2 is 1 (real start) + 1 (to jump over the ")
+		return new String(this.withoutUnicodeBuffer, 2, this.withoutUnicodePtr - 2);
+	else {
+		return new String(this.source, this.startPosition + 1, this.currentPosition - this.startPosition - 2);
+	}
+}
+public final char[] getRawTokenSource() {
+	int length = this.currentPosition - this.startPosition;
+	char[] tokenSource = new char[length];
+	System.arraycopy(this.source, this.startPosition, tokenSource, 0, length);
+	return tokenSource;
+}
+
+public final char[] getRawTokenSourceEnd() {
+	int length = this.eofPosition - this.currentPosition - 1;
+	char[] sourceEnd = new char[length];
+	System.arraycopy(this.source, this.currentPosition, sourceEnd, 0, length);
+	return sourceEnd;
+}
+
+public int getCurrentTokenStartPosition(){
+	return this.startPosition;
+}
+/*
+ * Search the source position corresponding to the end of a given line number
+ *
+ * Line numbers are 1-based, and relative to the scanner initialPosition.
+ * Character positions are 0-based.
+ *
+ * In case the given line number is inconsistent, answers -1.
+ */
+public final int getLineEnd(int lineNumber) {
+
+	if (this.lineEnds == null || this.linePtr == -1)
+		return -1;
+	if (lineNumber > this.lineEnds.length+1)
+		return -1;
+	if (lineNumber <= 0)
+		return -1;
+	if (lineNumber == this.lineEnds.length + 1)
+		return this.eofPosition;
+	return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
+}
+
+public final int[] getLineEnds() {
+	//return a bounded copy of this.lineEnds
+	if (this.linePtr == -1) {
+		return EMPTY_LINE_ENDS;
+	}
+	int[] copy;
+	System.arraycopy(this.lineEnds, 0, copy = new int[this.linePtr + 1], 0, this.linePtr + 1);
+	return copy;
+}
+
+/**
+ * Search the source position corresponding to the beginning of a given line number
+ *
+ * Line numbers are 1-based, and relative to the scanner initialPosition.
+ * Character positions are 0-based.
+ *
+ * e.g.	getLineStart(1) --> 0	indicates that the first line starts at character 0.
+ *
+ * In case the given line number is inconsistent, answers -1.
+ *
+ * @param lineNumber int
+ * @return int
+ */
+public final int getLineStart(int lineNumber) {
+
+	if (this.lineEnds == null || this.linePtr == -1)
+		return -1;
+	if (lineNumber > this.lineEnds.length + 1)
+		return -1;
+	if (lineNumber <= 0)
+		return -1;
+
+	if (lineNumber == 1)
+		return this.initialPosition;
+	return this.lineEnds[lineNumber-2]+1; // next line start one character behind the lineEnd of the previous line
+}
+public final int getNextChar() {
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+				getNextUnicodeChar();
+		} else {
+			this.unicodeAsBackSlash = false;
+			if (this.withoutUnicodePtr != 0) {
+			    unicodeStore();
+			}
+		}
+		return this.currentCharacter;
+	} catch (IndexOutOfBoundsException e) {
+		return -1;
+	} catch(InvalidInputException e) {
+		return -1;
+	}
+}
+public final int getNextCharWithBoundChecks() {
+	if (this.currentPosition >= this.eofPosition) {
+		return -1;
+	}
+	this.currentCharacter = this.source[this.currentPosition++];
+	if (this.currentPosition >= this.eofPosition) {
+		this.unicodeAsBackSlash = false;
+		if (this.withoutUnicodePtr != 0) {
+		    unicodeStore();
+		}
+		return this.currentCharacter;
+	}
+	if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
+		try {
+			getNextUnicodeChar();
+		} catch (InvalidInputException e) {
+			return -1;
+		}
+	} else {
+		this.unicodeAsBackSlash = false;
+		if (this.withoutUnicodePtr != 0) {
+		    unicodeStore();
+		}
+	}
+	return this.currentCharacter;
+}
+public final boolean getNextChar(char testedChar) {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is == to the testedChar
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+
+	if (this.currentPosition >= this.eofPosition) { // handle the obvious case upfront
+		this.unicodeAsBackSlash = false;
+		return false;
+	}
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (this.currentCharacter != testedChar) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} //-------------end unicode traitement--------------
+		else {
+			if (this.currentCharacter != testedChar) {
+				this.currentPosition = temp;
+				return false;
+			}
+			this.unicodeAsBackSlash = false;
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public final int getNextChar(char testedChar1, char testedChar2) {
+	//INT 0 : testChar1 \\\\///\\\\ 1 : testedChar2 \\\\///\\\\ -1 : others
+	//test can be done with (x==0) for the first and (x>0) for the second
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is == to the testedChar1/2
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return -1;
+
+	int temp = this.currentPosition;
+	try {
+		int result;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				result = -1;
+			}
+			return result;
+		} else {
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				return -1;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return result;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return -1;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return -1;
+	}
+}
+/*
+ * This method consumes digits as well as underscores if underscores are located between digits
+ * @throws InvalidInputException if underscores are not located between digits or if underscores are used in source < 1.7 
+ */
+private final void consumeDigits(int radix) throws InvalidInputException {
+	consumeDigits(radix, false);
+}
+/*
+ * This method consumes digits as well as underscores if underscores are located between digits
+ * @throws InvalidInputException if underscores are not located between digits or if underscores are used in source < 1.7 
+ */
+private final void consumeDigits(int radix, boolean expectingDigitFirst) throws InvalidInputException {
+	final int USING_UNDERSCORE = 1;
+	final int INVALID_POSITION = 2;
+	switch(consumeDigits0(radix, USING_UNDERSCORE, INVALID_POSITION, expectingDigitFirst)) {
+		case USING_UNDERSCORE :
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(UNDERSCORES_IN_LITERALS_NOT_BELOW_17);
+			}
+			break;
+		case INVALID_POSITION :
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(UNDERSCORES_IN_LITERALS_NOT_BELOW_17);
+			}
+			throw new InvalidInputException(INVALID_UNDERSCORE);
+	}
+}
+private final int consumeDigits0(int radix, int usingUnderscore, int invalidPosition, boolean expectingDigitFirst) throws InvalidInputException {
+	int kind = 0;
+	if (getNextChar('_')) {
+		if (expectingDigitFirst) {
+			return invalidPosition;
+		}
+		kind = usingUnderscore;
+		while (getNextChar('_')) {/*empty */}
+	}
+	if (getNextCharAsDigit(radix)) {
+		// continue to read digits or underscore
+		while (getNextCharAsDigit(radix)) {/*empty */}
+		int kind2 = consumeDigits0(radix, usingUnderscore, invalidPosition, false);
+		if (kind2 == 0) {
+			return kind;
+		}
+		return kind2;
+	}
+	if (kind == usingUnderscore) return invalidPosition;
+	return kind;
+}
+public final boolean getNextCharAsDigit() throws InvalidInputException {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a digit
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (!ScannerHelper.isDigit(this.currentCharacter)) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} else {
+			if (!ScannerHelper.isDigit(this.currentCharacter)) {
+				this.currentPosition = temp;
+				return false;
+			}
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public final boolean getNextCharAsDigit(int radix) {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a digit base on radix
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	if (this.currentPosition >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp = this.currentPosition;
+	try {
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
+				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
+				return false;
+			}
+			return true;
+		} else {
+			if (ScannerHelper.digit(this.currentCharacter, radix) == -1) {
+				this.currentPosition = temp;
+				return false;
+			}
+			if (this.withoutUnicodePtr != 0)
+				unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = temp;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
+	}
+}
+public boolean getNextCharAsJavaIdentifierPartWithBoundCheck() {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int pos = this.currentPosition;
+	if (pos >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp2 = this.withoutUnicodePtr;
+	try {
+		boolean unicode = false;
+		this.currentCharacter = this.source[this.currentPosition++];
+		if (this.currentPosition < this.eofPosition) {
+			if (this.currentCharacter == '\\' && this.source[this.currentPosition] == 'u') {
+				getNextUnicodeChar();
+				unicode = true;
+			}
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			// Unicode 4 detection
+			char low = (char) getNextCharWithBoundChecks();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			return true;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				return false;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+			    unicodeStore();
+			return true;
+		}
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	}
+}
+public boolean getNextCharAsJavaIdentifierPart() {
+	//BOOLEAN
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+	//Both previous lines are true if the currentCharacter is a JavaIdentifierPart
+	//On false, no side effect has occured.
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int pos;
+	if ((pos = this.currentPosition) >= this.eofPosition) // handle the obvious case upfront
+		return false;
+
+	int temp2 = this.withoutUnicodePtr;
+	try {
+		boolean unicode = false;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+			&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+			unicode = true;
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			// Unicode 4 detection
+			char low = (char) getNextChar();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(this.complianceLevel, c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
+			}
+			return true;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				return false;
+			}
+
+			if (this.withoutUnicodePtr != 0)
+			    unicodeStore();
+			return true;
+		}
+	} catch (IndexOutOfBoundsException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	}
+}
+/*
+ * External API in JavaConventions.
+ * This is used to optimize the case where the scanner is used to scan a single identifier.
+ * In this case, the AIOOBE is slower to handle than a bound check
+ */
+public int scanIdentifier() throws InvalidInputException {
+	int whiteStart = 0;
+	while (true) { //loop for jumping over comments
+		this.withoutUnicodePtr = 0;
+		//start with a new token (even comment written with unicode )
+		// ---------Consume white space and handles startPosition---------
+		whiteStart = this.currentPosition;
+		boolean isWhiteSpace, hasWhiteSpaces = false;
+		int offset;
+		int unicodePtr;
+		boolean checkIfUnicode = false;
+		do {
+			unicodePtr = this.withoutUnicodePtr;
+			offset = this.currentPosition;
+			this.startPosition = this.currentPosition;
+			if (this.currentPosition < this.eofPosition) {
+				this.currentCharacter = this.source[this.currentPosition++];
+				checkIfUnicode = this.currentPosition < this.eofPosition
+						&& this.currentCharacter == '\\'
+						&& this.source[this.currentPosition] == 'u';
+			} else if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+				// reposition scanner in case we are interested by spaces as tokens
+				this.currentPosition--;
+				this.startPosition = whiteStart;
+				return TokenNameWHITESPACE;
+			} else {
+				return TokenNameEOF;
+			}
+			if (checkIfUnicode) {
+				isWhiteSpace = jumpOverUnicodeWhiteSpace();
+				offset = this.currentPosition - offset;
+			} else {
+				offset = this.currentPosition - offset;
+				// inline version of:
+				//isWhiteSpace =
+				//	(this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
+				switch (this.currentCharacter) {
+					case 10 : /* \ u000a: LINE FEED               */
+					case 12 : /* \ u000c: FORM FEED               */
+					case 13 : /* \ u000d: CARRIAGE RETURN         */
+					case 32 : /* \ u0020: SPACE                   */
+					case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+						isWhiteSpace = true;
+						break;
+					default :
+						isWhiteSpace = false;
+				}
+			}
+			if (isWhiteSpace) {
+				hasWhiteSpaces = true;
+			}
+		} while (isWhiteSpace);
+		if (hasWhiteSpaces) {
+			if (this.tokenizeWhiteSpace) {
+				// reposition scanner in case we are interested by spaces as tokens
+				this.currentPosition-=offset;
+				this.startPosition = whiteStart;
+				if (checkIfUnicode) {
+					this.withoutUnicodePtr = unicodePtr;
+				}
+				return TokenNameWHITESPACE;
+			} else if (checkIfUnicode) {
+				this.withoutUnicodePtr = 0;
+				unicodeStore();
+			} else {
+				this.withoutUnicodePtr = 0;
+			}
+		}
+		char c = this.currentCharacter;
+		if (c < ScannerHelper.MAX_OBVIOUS) {
+			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+				return scanIdentifierOrKeywordWithBoundCheck();
+			}
+			return TokenNameERROR;
+		}
+		boolean isJavaIdStart;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			// Unicode 4 detection
+			char low = (char) getNextCharWithBoundChecks();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				throw new InvalidInputException(INVALID_LOW_SURROGATE);
+			}
+			isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+		} else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+		} else {
+			// optimized case already checked
+			isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+		}
+		if (isJavaIdStart)
+			return scanIdentifierOrKeywordWithBoundCheck();
+		return TokenNameERROR;
+	}
+}
+public int getNextToken() throws InvalidInputException {
+	this.wasAcr = false;
+	if (this.diet) {
+		jumpOverMethodBody();
+		this.diet = false;
+		return this.currentPosition > this.eofPosition ? TokenNameEOF : TokenNameRBRACE;
+	}
+	int whiteStart = 0;
+	try {
+		while (true) { //loop for jumping over comments
+			this.withoutUnicodePtr = 0;
+			//start with a new token (even comment written with unicode )
+
+			// ---------Consume white space and handles startPosition---------
+			whiteStart = this.currentPosition;
+			boolean isWhiteSpace, hasWhiteSpaces = false;
+			int offset;
+			int unicodePtr;
+			boolean checkIfUnicode = false;
+			do {
+				unicodePtr = this.withoutUnicodePtr;
+				offset = this.currentPosition;
+				this.startPosition = this.currentPosition;
+				try {
+					checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+						&& (this.source[this.currentPosition] == 'u');
+				} catch(IndexOutOfBoundsException e) {
+					if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+						// reposition scanner in case we are interested by spaces as tokens
+						this.currentPosition--;
+						this.startPosition = whiteStart;
+						return TokenNameWHITESPACE;
+					}
+					if (this.currentPosition > this.eofPosition)
+						return TokenNameEOF;
+				}
+				if (this.currentPosition > this.eofPosition) {
+					if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+						this.currentPosition--;
+						// reposition scanner in case we are interested by spaces as tokens
+						this.startPosition = whiteStart;
+						return TokenNameWHITESPACE;
+					}
+					return TokenNameEOF;
+				}
+				if (checkIfUnicode) {
+					isWhiteSpace = jumpOverUnicodeWhiteSpace();
+					offset = this.currentPosition - offset;
+				} else {
+					offset = this.currentPosition - offset;
+					if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+						if (this.recordLineSeparator) {
+							pushLineSeparator();
+						}
+					}
+					// inline version of:
+					//isWhiteSpace =
+					//	(this.currentCharacter == ' ') || ScannerHelper.isWhitespace(this.currentCharacter);
+					switch (this.currentCharacter) {
+						case 10 : /* \ u000a: LINE FEED               */
+						case 12 : /* \ u000c: FORM FEED               */
+						case 13 : /* \ u000d: CARRIAGE RETURN         */
+						case 32 : /* \ u0020: SPACE                   */
+						case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+							isWhiteSpace = true;
+							break;
+						default :
+							isWhiteSpace = false;
+					}
+				}
+				if (isWhiteSpace) {
+					hasWhiteSpaces = true;
+				}
+			} while (isWhiteSpace);
+			if (hasWhiteSpaces) {
+				if (this.tokenizeWhiteSpace) {
+					// reposition scanner in case we are interested by spaces as tokens
+					this.currentPosition-=offset;
+					this.startPosition = whiteStart;
+					if (checkIfUnicode) {
+						this.withoutUnicodePtr = unicodePtr;
+					}
+					return TokenNameWHITESPACE;
+				} else if (checkIfUnicode) {
+					this.withoutUnicodePtr = 0;
+					unicodeStore();
+				} else {
+					this.withoutUnicodePtr = 0;
+				}
+			}
+			// ---------Identify the next token-------------
+			switch (this.currentCharacter) {
+				case '@' :
+/*					if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+						return TokenNameAT;
+					} else {
+						return TokenNameERROR;
+					}*/
+					return TokenNameAT;
+				case '(' :
+					return TokenNameLPAREN;
+				case ')' :
+					return TokenNameRPAREN;
+				case '{' :
+					return TokenNameLBRACE;
+				case '}' :
+					return TokenNameRBRACE;
+				case '[' :
+					return TokenNameLBRACKET;
+				case ']' :
+					return TokenNameRBRACKET;
+				case ';' :
+					return TokenNameSEMICOLON;
+				case ',' :
+					return TokenNameCOMMA;
+				case '.' :
+					if (getNextCharAsDigit()) {
+						return scanNumber(true);
+					}
+					int temp = this.currentPosition;
+					if (getNextChar('.')) {
+						if (getNextChar('.')) {
+							return TokenNameELLIPSIS;
+						} else {
+							this.currentPosition = temp;
+							return TokenNameDOT;
+						}
+					} else {
+						this.currentPosition = temp;
+						return TokenNameDOT;
+					}
+				case '+' :
+					{
+						int test;
+						if ((test = getNextChar('+', '=')) == 0)
+							return TokenNamePLUS_PLUS;
+						if (test > 0)
+							return TokenNamePLUS_EQUAL;
+						return TokenNamePLUS;
+					}
+				case '-' :
+					{
+						int test;
+						if ((test = getNextChar('-', '=')) == 0)
+							return TokenNameMINUS_MINUS;
+						if (test > 0)
+							return TokenNameMINUS_EQUAL;
+						if (getNextChar('>'))
+							return TokenNameARROW;
+						return TokenNameMINUS;
+					}
+				case '~' :
+					return TokenNameTWIDDLE;
+				case '!' :
+					if (getNextChar('='))
+						return TokenNameNOT_EQUAL;
+					return TokenNameNOT;
+				case '*' :
+					if (getNextChar('='))
+						return TokenNameMULTIPLY_EQUAL;
+					return TokenNameMULTIPLY;
+				case '%' :
+					if (getNextChar('='))
+						return TokenNameREMAINDER_EQUAL;
+					return TokenNameREMAINDER;
+				case '<' :
+					{
+						int test;
+						if ((test = getNextChar('=', '<')) == 0)
+							return TokenNameLESS_EQUAL;
+						if (test > 0) {
+							if (getNextChar('='))
+								return TokenNameLEFT_SHIFT_EQUAL;
+							return TokenNameLEFT_SHIFT;
+						}
+						return TokenNameLESS;
+					}
+				case '>' :
+					{
+						int test;
+						if (this.returnOnlyGreater) {
+							return TokenNameGREATER;
+						}
+						if ((test = getNextChar('=', '>')) == 0)
+							return TokenNameGREATER_EQUAL;
+						if (test > 0) {
+							if ((test = getNextChar('=', '>')) == 0)
+								return TokenNameRIGHT_SHIFT_EQUAL;
+							if (test > 0) {
+								if (getNextChar('='))
+									return TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL;
+								return TokenNameUNSIGNED_RIGHT_SHIFT;
+							}
+							return TokenNameRIGHT_SHIFT;
+						}
+						return TokenNameGREATER;
+					}
+				case '=' :
+					if (getNextChar('='))
+						return TokenNameEQUAL_EQUAL;
+					return TokenNameEQUAL;
+				case '&' :
+					{
+						int test;
+						if ((test = getNextChar('&', '=')) == 0)
+							return TokenNameAND_AND;
+						if (test > 0)
+							return TokenNameAND_EQUAL;
+						return TokenNameAND;
+					}
+				case '|' :
+					{
+						int test;
+						if ((test = getNextChar('|', '=')) == 0)
+							return TokenNameOR_OR;
+						if (test > 0)
+							return TokenNameOR_EQUAL;
+						return TokenNameOR;
+					}
+				case '^' :
+					if (getNextChar('='))
+						return TokenNameXOR_EQUAL;
+					return TokenNameXOR;
+				case '?' :
+					return TokenNameQUESTION;
+				case ':' :
+					if (getNextChar(':'))
+						return TokenNameCOLON_COLON;
+					return TokenNameCOLON;
+				case '\'' :
+					{
+						int test;
+						if ((test = getNextChar('\n', '\r')) == 0) {
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (test > 0) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\'') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+					}
+					if (getNextChar('\'')) {
+						// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+						for (int lookAhead = 0; lookAhead < 3; lookAhead++) {
+							if (this.currentPosition + lookAhead == this.eofPosition)
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\n')
+								break;
+							if (this.source[this.currentPosition + lookAhead] == '\'') {
+								this.currentPosition += lookAhead + 1;
+								break;
+							}
+						}
+						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+					}
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
+						scanEscapeCharacter();
+					} else { // consume next character
+						this.unicodeAsBackSlash = false;
+						checkIfUnicode = false;
+						try {
+							checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u');
+						} catch(IndexOutOfBoundsException e) {
+							this.currentPosition--;
+							throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+						}
+						if (checkIfUnicode) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (getNextChar('\''))
+						return TokenNameCharacterLiteral;
+					// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+					for (int lookAhead = 0; lookAhead < 20; lookAhead++) {
+						if (this.currentPosition + lookAhead == this.eofPosition)
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\n')
+							break;
+						if (this.source[this.currentPosition + lookAhead] == '\'') {
+							this.currentPosition += lookAhead + 1;
+							break;
+						}
+					}
+					throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
+				case '"' :
+					try {
+						// consume next character
+						this.unicodeAsBackSlash = false;
+						boolean isUnicode = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+							isUnicode = true;
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+
+						while (this.currentCharacter != '"') {
+							if (this.currentPosition >= this.eofPosition) {
+								throw new InvalidInputException(UNTERMINATED_STRING);
+							}
+							/**** \r and \n are not valid in string literals ****/
+							if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) {
+								// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+								if (isUnicode) {
+									int start = this.currentPosition;
+									for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+										if (this.currentPosition >= this.eofPosition) {
+											this.currentPosition = start;
+											break;
+										}
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											isUnicode = true;
+											getNextUnicodeChar();
+										} else {
+											isUnicode = false;
+										}
+										if (!isUnicode && this.currentCharacter == '\n') {
+											this.currentPosition--; // set current position on new line character
+											break;
+										}
+										if (this.currentCharacter == '\"') {
+											throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+										}
+									}
+								} else {
+									this.currentPosition--; // set current position on new line character
+								}
+								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
+							}
+							if (this.currentCharacter == '\\') {
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+										this.withoutUnicodePtr--;
+									} else {
+										isUnicode = false;
+									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+								isUnicode = true;
+							} else {
+								isUnicode = false;
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+
+						}
+					} catch (IndexOutOfBoundsException e) {
+						this.currentPosition--;
+						throw new InvalidInputException(UNTERMINATED_STRING);
+					} catch (InvalidInputException e) {
+						if (e.getMessage().equals(INVALID_ESCAPE)) {
+							// relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed
+							for (int lookAhead = 0; lookAhead < 50; lookAhead++) {
+								if (this.currentPosition + lookAhead == this.eofPosition)
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\n')
+									break;
+								if (this.source[this.currentPosition + lookAhead] == '\"') {
+									this.currentPosition += lookAhead + 1;
+									break;
+								}
+							}
+
+						}
+						throw e; // rethrow
+					}
+					return TokenNameStringLiteral;
+				case '/' :
+					if (!this.skipComments) {
+						int test = getNextChar('/', '*');
+						if (test == 0) { //line comment
+							this.lastCommentLinePosition = this.currentPosition;
+							try { //get the next char
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								}
+
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								boolean isUnicode = false;
+								while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
+									if (this.currentPosition >= this.eofPosition) {
+										this.lastCommentLinePosition = this.currentPosition;
+										this.currentPosition ++;
+										// this avoids duplicating the code in the catch(IndexOutOfBoundsException e)
+										throw new IndexOutOfBoundsException();
+									}
+									this.lastCommentLinePosition = this.currentPosition;
+									//get the next char
+									isUnicode = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								/*
+								 * We need to completely consume the line break
+								 */
+								if (this.currentCharacter == '\r'
+										&& this.eofPosition > this.currentPosition) {
+									if (this.source[this.currentPosition] == '\n') {
+										this.currentPosition++;
+										this.currentCharacter = '\n';
+									} else if ((this.source[this.currentPosition] == '\\')
+										&& (this.source[this.currentPosition + 1] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									}
+								}
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.checkNonExternalizedStringLiterals &&
+											this.lastPosition < this.currentPosition) {
+										parseTags();
+									}
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.checkNonExternalizedStringLiterals &&
+										this.lastPosition < this.currentPosition) {
+									parseTags();
+								}
+								if (this.tokenizeComments) {
+									return TokenNameCOMMENT_LINE;
+								} else {
+									this.currentPosition++;
+								}
+							}
+							break;
+						}
+						if (test > 0) { //traditional and javadoc comment
+							try { //get the next char
+								boolean isJavadoc = false, star = false;
+								boolean isUnicode = false;
+								int previous;
+								// consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+
+								if (this.currentCharacter == '*') {
+									isJavadoc = true;
+									star = true;
+								}
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								isUnicode = false;
+								previous = this.currentPosition;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+									//-------------unicode traitement ------------
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++; //jump over the \\
+								}
+								// empty comment is not a javadoc /**/
+								if (this.currentCharacter == '/') {
+									isJavadoc = false;
+								}
+								//loop until end of comment */
+								int firstTag = 0;
+								while ((this.currentCharacter != '/') || (!star)) {
+									if (this.currentPosition >= this.eofPosition) {
+										throw new InvalidInputException(UNTERMINATED_COMMENT);
+									}
+									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0 && this.isFirstTag()) {
+												firstTag = previous;
+											}
+											//$FALL-THROUGH$ default case to set star to false
+										default:
+											star = false;
+									}
+									//get next char
+									previous = this.currentPosition;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+										//-------------unicode traitement ------------
+										getNextUnicodeChar();
+										isUnicode = true;
+									} else {
+										isUnicode = false;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
+								recordComment(token);
+								this.commentTagStarts[this.commentPtr] = firstTag;
+								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
+								if (this.tokenizeComments) {
+									/*
+									if (isJavadoc)
+										return TokenNameCOMMENT_JAVADOC;
+									return TokenNameCOMMENT_BLOCK;
+									*/
+									return token;
+								}
+							} catch (IndexOutOfBoundsException e) {
+								this.currentPosition--;
+								throw new InvalidInputException(UNTERMINATED_COMMENT);
+							}
+							break;
+						}
+					}
+					if (getNextChar('='))
+						return TokenNameDIVIDE_EQUAL;
+					return TokenNameDIVIDE;
+				case '\u001a' :
+					if (atEnd())
+						return TokenNameEOF;
+					//the atEnd may not be <currentPosition == source.length> if source is only some part of a real (external) stream
+					throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
+				default :
+					char c = this.currentCharacter;
+					if (c < ScannerHelper.MAX_OBVIOUS) {
+						if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+							return scanIdentifierOrKeyword();
+						} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
+								return scanNumber(false);
+						} else {
+							return TokenNameERROR;
+						}
+					}
+					boolean isJavaIdStart;
+					if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						// Unicode 4 detection
+						char low = (char) getNextChar();
+						if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+							// illegal low surrogate
+							throw new InvalidInputException(INVALID_LOW_SURROGATE);
+						}
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+					}
+					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+					} else {
+						// optimized case already checked
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+					}
+					if (isJavaIdStart)
+						return scanIdentifierOrKeyword();
+					if (ScannerHelper.isDigit(this.currentCharacter)) {
+						return scanNumber(false);
+					}
+					return TokenNameERROR;
+			}
+		}
+	} //-----------------end switch while try--------------------
+	catch (IndexOutOfBoundsException e) {
+		if (this.tokenizeWhiteSpace && (whiteStart != this.currentPosition - 1)) {
+			// reposition scanner in case we are interested by spaces as tokens
+			this.currentPosition--;
+			this.startPosition = whiteStart;
+			return TokenNameWHITESPACE;
+		}
+	}
+	return TokenNameEOF;
+}
+public void getNextUnicodeChar()
+	throws InvalidInputException {
+	//VOID
+	//handle the case of unicode.
+	//when a unicode appears then we must use a buffer that holds char internal values
+	//At the end of this method currentCharacter holds the new visited char
+	//and currentPosition points right next after it
+
+	//ALL getNextChar.... ARE OPTIMIZED COPIES
+	int c1 = 0, c2 = 0, c3 = 0, c4 = 0, unicodeSize = 6;
+	this.currentPosition++;
+	if (this.currentPosition < this.eofPosition) {
+		while (this.source[this.currentPosition] == 'u') {
+			this.currentPosition++;
+			if (this.currentPosition >= this.eofPosition) {
+				this.currentPosition--;
+				throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+			}
+			unicodeSize++;
+		}
+	} else {
+		this.currentPosition--;
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+
+	if ((this.currentPosition + 4) > this.eofPosition) {
+		this.currentPosition += (this.eofPosition - this.currentPosition);
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+	if ((c1 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c1 < 0
+    		|| (c2 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c2 < 0
+    		|| (c3 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c3 < 0
+    		|| (c4 = ScannerHelper.getHexadecimalValue(this.source[this.currentPosition++])) > 15
+    		|| c4 < 0){
+		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+	}
+	this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+	//need the unicode buffer
+	if (this.withoutUnicodePtr == 0) {
+		//buffer all the entries that have been left aside....
+		unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+	}
+	//fill the buffer with the char
+	unicodeStore();
+	this.unicodeAsBackSlash = this.currentCharacter == '\\';
+}
+public NLSTag[] getNLSTags() {
+	final int length = this.nlsTagsPtr;
+	if (length != 0) {
+		NLSTag[] result = new NLSTag[length];
+		System.arraycopy(this.nlsTags, 0, result, 0, length);
+		this.nlsTagsPtr = 0;
+		return result;
+	}
+	return null;
+}
+public char[] getSource(){
+	return this.source;
+}
+protected boolean isFirstTag() {
+	return true;
+}
+public final void jumpOverMethodBody() {
+
+	this.wasAcr = false;
+	int found = 1;
+	try {
+		while (true) { //loop for jumping over comments
+			this.withoutUnicodePtr = 0;
+			// ---------Consume white space and handles startPosition---------
+			boolean isWhiteSpace;
+			do {
+				this.startPosition = this.currentPosition;
+				if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+					&& (this.source[this.currentPosition] == 'u')) {
+					isWhiteSpace = jumpOverUnicodeWhiteSpace();
+				} else {
+					if (this.recordLineSeparator
+							&& ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
+						pushLineSeparator();
+					}
+					isWhiteSpace = CharOperation.isWhitespace(this.currentCharacter);
+				}
+			} while (isWhiteSpace);
+
+			// -------consume token until } is found---------
+			NextToken: switch (this.currentCharacter) {
+				case '{' :
+					found++;
+					break NextToken;
+				case '}' :
+					found--;
+					if (found == 0)
+						return;
+					break NextToken;
+				case '\'' :
+					{
+						boolean test;
+						test = getNextChar('\\');
+						if (test) {
+							try {
+								if (this.unicodeAsBackSlash) {
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+									} else {
+										if (this.withoutUnicodePtr != 0) {
+											unicodeStore();
+										}
+									}
+								} else {
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								scanEscapeCharacter();
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						} else {
+							try { // consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								} else {
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						}
+						getNextChar('\'');
+						break NextToken;
+					}
+				case '"' :
+					try {
+						try { // consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+									&& (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} catch (InvalidInputException ex) {
+								// ignore
+						}
+						while (this.currentCharacter != '"') {
+							if (this.currentPosition >= this.eofPosition) {
+								return;
+							}
+							if (this.currentCharacter == '\r'){
+								if (this.source[this.currentPosition] == '\n') this.currentPosition++;
+								break NextToken; // the string cannot go further that the line
+							}
+							if (this.currentCharacter == '\n'){
+								break; // the string cannot go further that the line
+							}
+							if (this.currentCharacter == '\\') {
+								try {
+									if (this.unicodeAsBackSlash) {
+										// consume next character
+										this.unicodeAsBackSlash = false;
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											getNextUnicodeChar();
+										} else {
+											if (this.withoutUnicodePtr != 0) {
+												unicodeStore();
+											}
+										}
+									} else {
+										this.currentCharacter = this.source[this.currentPosition++];
+									}
+									scanEscapeCharacter();
+								} catch (InvalidInputException ex) {
+									// ignore
+								}
+							}
+							try { // consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								} else {
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+							} catch (InvalidInputException ex) {
+								// ignore
+							}
+						}
+					} catch (IndexOutOfBoundsException e) {
+						return;
+					}
+					break NextToken;
+				case '/' :
+					{
+						int test;
+						if ((test = getNextChar('/', '*')) == 0) { //line comment
+							try {
+								this.lastCommentLinePosition = this.currentPosition;
+								//get the next char
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++;
+								} //jump over the \\
+								boolean isUnicode = false;
+								while (this.currentCharacter != '\r' && this.currentCharacter != '\n') {
+									if (this.currentPosition >= this.eofPosition) {
+										this.lastCommentLinePosition = this.currentPosition;
+										this.currentPosition ++;
+										// this avoids duplicating the code inside the catch(IndexOutOfBoundsException e) below
+										throw new IndexOutOfBoundsException();
+									}
+									this.lastCommentLinePosition = this.currentPosition;
+									//get the next char
+									isUnicode = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										isUnicode = true;
+										getNextUnicodeChar();
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								/*
+								 * We need to completely consume the line break
+								 */
+								if (this.currentCharacter == '\r'
+										&& this.eofPosition > this.currentPosition) {
+									if (this.source[this.currentPosition] == '\n') {
+										this.currentPosition++;
+										this.currentCharacter = '\n';
+									} else if ((this.source[this.currentPosition] == '\\')
+											&& (this.source[this.currentPosition + 1] == 'u')) {
+										isUnicode = true;
+										getNextUnicodeChar();
+									}
+								}
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.recordLineSeparator
+									&& ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) {
+										if (this.checkNonExternalizedStringLiterals &&
+												this.lastPosition < this.currentPosition) {
+											parseTags();
+										}
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+							} catch (IndexOutOfBoundsException e) {
+								 //an eof will then be generated
+								this.currentPosition--;
+								recordComment(TokenNameCOMMENT_LINE);
+								if (this.checkNonExternalizedStringLiterals &&
+										this.lastPosition < this.currentPosition) {
+									parseTags();
+								}
+								if (!this.tokenizeComments) {
+									this.currentPosition++;
+								}
+							}
+							break NextToken;
+						}
+						if (test > 0) { //traditional and javadoc comment
+							boolean isJavadoc = false;
+							try { //get the next char
+								boolean star = false;
+								int previous;
+								boolean isUnicode = false;
+								// consume next character
+								this.unicodeAsBackSlash = false;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+									if (this.withoutUnicodePtr != 0) {
+										unicodeStore();
+									}
+								}
+
+								if (this.currentCharacter == '*') {
+									isJavadoc = true;
+									star = true;
+								}
+								if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+									if (this.recordLineSeparator) {
+										if (isUnicode) {
+											pushUnicodeLineSeparator();
+										} else {
+											pushLineSeparator();
+										}
+									}
+								}
+								isUnicode = false;
+								previous = this.currentPosition;
+								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
+									isUnicode = true;
+								} else {
+									isUnicode = false;
+								}
+								//handle the \\u case manually into comment
+								if (this.currentCharacter == '\\') {
+									if (this.source[this.currentPosition] == '\\')
+										this.currentPosition++; //jump over the \\
+								}
+								// empty comment is not a javadoc /**/
+								if (this.currentCharacter == '/') {
+									isJavadoc = false;
+								}
+								//loop until end of comment */
+								int firstTag = 0;
+								while ((this.currentCharacter != '/') || (!star)) {
+									if (this.currentPosition >= this.eofPosition) {
+										return;
+									}
+									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
+										if (this.recordLineSeparator) {
+											if (isUnicode) {
+												pushUnicodeLineSeparator();
+											} else {
+												pushLineSeparator();
+											}
+										}
+									}
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0 && this.isFirstTag()) {
+												firstTag = previous;
+											}
+											//$FALL-THROUGH$ default case to set star to false
+										default:
+											star = false;
+									}
+									//get next char
+									previous = this.currentPosition;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
+									} else {
+										isUnicode = false;
+									}
+									//handle the \\u case manually into comment
+									if (this.currentCharacter == '\\') {
+										if (this.source[this.currentPosition] == '\\')
+											this.currentPosition++;
+									} //jump over the \\
+								}
+								recordComment(isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK);
+								this.commentTagStarts[this.commentPtr] = firstTag;
+							} catch (IndexOutOfBoundsException e) {
+								return;
+							}
+							break NextToken;
+						}
+						break NextToken;
+					}
+
+				default :
+					try {
+						char c = this.currentCharacter;
+						if (c < ScannerHelper.MAX_OBVIOUS) {
+							if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_IDENT_START) != 0) {
+								scanIdentifierOrKeyword();
+								break NextToken;
+							} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_DIGIT) != 0) {
+								scanNumber(false);
+								break NextToken;
+							} else {
+								break NextToken;
+							}
+						}
+						boolean isJavaIdStart;
+						if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							// Unicode 4 detection
+							char low = (char) getNextChar();
+							if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+								// illegal low surrogate
+								break NextToken;
+							}
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
+						} else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+							break NextToken;
+						} else {
+							// optimized case already checked
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c);
+						}
+						if (isJavaIdStart) {
+							scanIdentifierOrKeyword();
+							break NextToken;
+						}
+//						if (ScannerHelper.isDigit(this.currentCharacter)) {
+//							scanNumber(false);
+//							break NextToken;
+//						}
+					} catch (InvalidInputException ex) {
+						// ignore
+					}
+			}
+		}
+		//-----------------end switch while try--------------------
+	} catch (IndexOutOfBoundsException e) {
+		// ignore
+	} catch (InvalidInputException e) {
+		// ignore
+	}
+	return;
+}
+public final boolean jumpOverUnicodeWhiteSpace() throws InvalidInputException {
+	//BOOLEAN
+	//handle the case of unicode. Jump over the next whiteSpace
+	//making startPosition pointing on the next available char
+	//On false, the currentCharacter is filled up with a potential
+	//correct char
+
+	this.wasAcr = false;
+	getNextUnicodeChar();
+	return CharOperation.isWhitespace(this.currentCharacter);
+}
+
+final char[] optimizedCurrentTokenSource1() {
+	//return always the same char[] build only once
+
+	//optimization at no speed cost of 99.5 % of the singleCharIdentifier
+	char charOne = this.source[this.startPosition];
+	switch (charOne) {
+		case 'a' :
+			return charArray_a;
+		case 'b' :
+			return charArray_b;
+		case 'c' :
+			return charArray_c;
+		case 'd' :
+			return charArray_d;
+		case 'e' :
+			return charArray_e;
+		case 'f' :
+			return charArray_f;
+		case 'g' :
+			return charArray_g;
+		case 'h' :
+			return charArray_h;
+		case 'i' :
+			return charArray_i;
+		case 'j' :
+			return charArray_j;
+		case 'k' :
+			return charArray_k;
+		case 'l' :
+			return charArray_l;
+		case 'm' :
+			return charArray_m;
+		case 'n' :
+			return charArray_n;
+		case 'o' :
+			return charArray_o;
+		case 'p' :
+			return charArray_p;
+		case 'q' :
+			return charArray_q;
+		case 'r' :
+			return charArray_r;
+		case 's' :
+			return charArray_s;
+		case 't' :
+			return charArray_t;
+		case 'u' :
+			return charArray_u;
+		case 'v' :
+			return charArray_v;
+		case 'w' :
+			return charArray_w;
+		case 'x' :
+			return charArray_x;
+		case 'y' :
+			return charArray_y;
+		case 'z' :
+			return charArray_z;
+		default :
+			return new char[] {charOne};
+	}
+}
+final char[] optimizedCurrentTokenSource2() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0 , c1;
+	int hash = (((c0=src[start]) << 6) + (c1=src[start+1])) % TableSize;
+	char[][] table = this.charArray_length[0][hash];
+	int i = this.newEntry2;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry2;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[2], 0, 2);
+	//newIdentCount++;
+	return table[this.newEntry2 = max] = r; //(r = new char[] {c0, c1});
+}
+final char[] optimizedCurrentTokenSource3() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1=src[start+1], c2;
+	int hash = (((c0=src[start])<< 6) + (c2=src[start+2])) % TableSize;
+//	int hash = ((c0 << 12) + (c1<< 6) + c2) % TableSize;
+	char[][] table = this.charArray_length[1][hash];
+	int i = this.newEntry3;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry3;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0]) && (c1 == charArray[1]) && (c2 == charArray[2]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[3], 0, 3);
+	//newIdentCount++;
+	return table[this.newEntry3 = max] = r; //(r = new char[] {c0, c1, c2});
+}
+final char[] optimizedCurrentTokenSource4() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3];
+	int hash = (((c0=src[start]) << 6) + (c2=src[start+2])) % TableSize;
+//	int hash = (int) (((((long) c0) << 18) + (c1 << 12) + (c2 << 6) + c3) % TableSize);
+	char[][] table = this.charArray_length[2][hash];
+	int i = this.newEntry4;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry4;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[4], 0, 4);
+	//newIdentCount++;
+	return table[this.newEntry4 = max] = r; //(r = new char[] {c0, c1, c2, c3});
+}
+final char[] optimizedCurrentTokenSource5() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4;
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int) (((((long) c0) << 24) + (((long) c1) << 18) + (c2 << 12) + (c3 << 6) + c4) % TableSize);
+	char[][] table = this.charArray_length[3][hash];
+	int i = this.newEntry5;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry5;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[5], 0, 5);
+	//newIdentCount++;
+	return table[this.newEntry5 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4});
+}
+final char[] optimizedCurrentTokenSource6() {
+	//try to return the same char[] build only once
+
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4, c5 = src[start+5];
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int)(((((long) c0) << 32) + (((long) c1) << 24) + (((long) c2) << 18) + (c3 << 12) + (c4 << 6) + c5) % TableSize);
+	char[][] table = this.charArray_length[4][hash];
+	int i = this.newEntry6;
+	while (++i < InternalTableSize) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4])
+			&& (c5 == charArray[5]))
+			return charArray;
+	}
+	//---------other side---------
+	i = -1;
+	int max = this.newEntry6;
+	while (++i <= max) {
+		char[] charArray = table[i];
+		if ((c0 == charArray[0])
+			&& (c1 == charArray[1])
+			&& (c2 == charArray[2])
+			&& (c3 == charArray[3])
+			&& (c4 == charArray[4])
+			&& (c5 == charArray[5]))
+			return charArray;
+	}
+	//--------add the entry-------
+	if (++max >= InternalTableSize) max = 0;
+	char[] r;
+	System.arraycopy(src, start, r= new char[6], 0, 6);
+	//newIdentCount++;
+	return table[this.newEntry6 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4, c5});
+}
+
+private void parseTags() {
+	int position = 0;
+	final int currentStartPosition = this.startPosition;
+	final int currentLinePtr = this.linePtr;
+	if (currentLinePtr >= 0) {
+		position = this.lineEnds[currentLinePtr] + 1;
+	}
+	while (ScannerHelper.isWhitespace(this.source[position])) {
+		position++;
+	}
+	if (currentStartPosition == position) {
+		// the whole line is commented out
+		return;
+	}
+	char[] s = null;
+	int sourceEnd = this.currentPosition;
+	int sourceStart = currentStartPosition;
+	int sourceDelta = 0;
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		System.arraycopy(
+			this.withoutUnicodeBuffer,
+			1,
+			s = new char[this.withoutUnicodePtr],
+			0,
+			this.withoutUnicodePtr);
+		sourceEnd = this.withoutUnicodePtr;
+		sourceStart = 1;
+		sourceDelta = currentStartPosition;
+	} else {
+		s = this.source;
+	}
+	int pos = CharOperation.indexOf(TAG_PREFIX, s, true, sourceStart, sourceEnd);
+	if (pos != -1) {
+		if (this.nlsTags == null) {
+			this.nlsTags = new NLSTag[10];
+			this.nlsTagsPtr = 0;
+		}
+		while (pos != -1) {
+			int start = pos + TAG_PREFIX_LENGTH;
+			int end = CharOperation.indexOf(TAG_POSTFIX, s, start, sourceEnd);
+			if (end != -1) {
+				NLSTag currentTag = null;
+				final int currentLine = currentLinePtr + 1;
+				try {
+					currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, extractInt(s, start, end));
+				} catch (NumberFormatException e) {
+					currentTag = new NLSTag(pos + sourceDelta, end + sourceDelta, currentLine, -1);
+				}
+				if (this.nlsTagsPtr == this.nlsTags.length) {
+					// resize
+					System.arraycopy(this.nlsTags, 0, (this.nlsTags = new NLSTag[this.nlsTagsPtr + 10]), 0, this.nlsTagsPtr);
+				}
+				this.nlsTags[this.nlsTagsPtr++] = currentTag;
+			} else {
+				end = start;
+			}
+			pos = CharOperation.indexOf(TAG_PREFIX, s, true, end, sourceEnd);
+		}
+	}
+}
+private int extractInt(char[] array, int start, int end) {
+	int value = 0;
+	for (int i = start; i < end; i++) {
+		final char currentChar = array[i];
+		int digit = 0;
+		switch(currentChar) {
+			case '0' :
+				digit = 0;
+				break;
+			case '1' :
+				digit = 1;
+				break;
+			case '2' :
+				digit = 2;
+				break;
+			case '3' :
+				digit = 3;
+				break;
+			case '4' :
+				digit = 4;
+				break;
+			case '5' :
+				digit = 5;
+				break;
+			case '6' :
+				digit = 6;
+				break;
+			case '7' :
+				digit = 7;
+				break;
+			case '8' :
+				digit = 8;
+				break;
+			case '9' :
+				digit = 9;
+				break;
+			default :
+				throw new NumberFormatException();
+		}
+		value *= 10;
+		if (digit < 0) throw new NumberFormatException();
+		value += digit;
+	}
+	return value;
+}
+public final void pushLineSeparator() {
+	//see comment on isLineDelimiter(char) for the use of '\n' and '\r'
+	final int INCREMENT = 250;
+	//currentCharacter is at position currentPosition-1
+	// cr 000D
+	if (this.currentCharacter == '\r') {
+		int separatorPos = this.currentPosition - 1;
+		if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
+		int length = this.lineEnds.length;
+		if (++this.linePtr >=  length)
+			System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
+		this.lineEnds[this.linePtr] = separatorPos;
+		// look-ahead for merged cr+lf
+		try {
+			if (this.source[this.currentPosition] == '\n') {
+				//System.out.println("look-ahead LF-" + this.currentPosition);
+				this.lineEnds[this.linePtr] = this.currentPosition;
+				this.currentPosition++;
+				this.wasAcr = false;
+			} else {
+				this.wasAcr = true;
+			}
+		} catch(IndexOutOfBoundsException e) {
+			this.wasAcr = true;
+		}
+	} else {
+		// lf 000A
+		if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
+			if (this.wasAcr && (this.lineEnds[this.linePtr] == (this.currentPosition - 2))) {
+				//System.out.println("merge LF-" + (this.currentPosition - 1));
+				this.lineEnds[this.linePtr] = this.currentPosition - 1;
+			} else {
+				int separatorPos = this.currentPosition - 1;
+				if ((this.linePtr >= 0) && (this.lineEnds[this.linePtr] >= separatorPos)) return;
+				int length = this.lineEnds.length;
+				if (++this.linePtr >=  length)
+					System.arraycopy(this.lineEnds, 0, this.lineEnds = new int[length + INCREMENT], 0, length);
+				this.lineEnds[this.linePtr] = separatorPos;
+			}
+			this.wasAcr = false;
+		}
+	}
+}
+public final void pushUnicodeLineSeparator() {
+	// cr 000D
+	if (this.currentCharacter == '\r') {
+		if (this.source[this.currentPosition] == '\n') {
+			this.wasAcr = false;
+		} else {
+			this.wasAcr = true;
+		}
+	} else {
+		// lf 000A
+		if (this.currentCharacter == '\n') { //must merge eventual cr followed by lf
+			this.wasAcr = false;
+		}
+	}
+}
+
+public void recordComment(int token) {
+	// compute position
+	int commentStart = this.startPosition;
+	int stopPosition = this.currentPosition;
+	switch (token) {
+		case TokenNameCOMMENT_LINE:
+			// both positions are negative
+			commentStart = -this.startPosition;
+			stopPosition = -this.lastCommentLinePosition;
+			break;
+		case TokenNameCOMMENT_BLOCK:
+			// only end position is negative
+			stopPosition = -this.currentPosition;
+			break;
+	}
+
+	// a new comment is recorded
+	int length = this.commentStops.length;
+	if (++this.commentPtr >=  length) {
+		int newLength = length + COMMENT_ARRAYS_SIZE*10;
+		System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length);
+		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length);
+		System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length);
+	}
+	this.commentStops[this.commentPtr] = stopPosition;
+	this.commentStarts[this.commentPtr] = commentStart;
+}
+
+/**
+ * Reposition the scanner on some portion of the original source. The given endPosition is the last valid position.
+ * Beyond this position, the scanner will answer EOF tokens (<code>ITerminalSymbols.TokenNameEOF</code>).
+ *
+ * @param begin the given start position
+ * @param end the given end position
+ */
+public void resetTo(int begin, int end) {
+	//reset the scanner to a given position where it may rescan again
+
+	this.diet = false;
+	this.initialPosition = this.startPosition = this.currentPosition = begin;
+	if (this.source != null && this.source.length < end) {
+		this.eofPosition = this.source.length;
+	} else {
+		this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	}
+	this.commentPtr = -1; // reset comment stack
+	this.foundTaskCount = 0;
+}
+
+protected final void scanEscapeCharacter() throws InvalidInputException {
+	// the string with "\\u" is a legal string of two chars \ and u
+	//thus we use a direct access to the source (for regular cases).
+	switch (this.currentCharacter) {
+		case 'b' :
+			this.currentCharacter = '\b';
+			break;
+		case 't' :
+			this.currentCharacter = '\t';
+			break;
+		case 'n' :
+			this.currentCharacter = '\n';
+			break;
+		case 'f' :
+			this.currentCharacter = '\f';
+			break;
+		case 'r' :
+			this.currentCharacter = '\r';
+			break;
+		case '\"' :
+			this.currentCharacter = '\"';
+			break;
+		case '\'' :
+			this.currentCharacter = '\'';
+			break;
+		case '\\' :
+			this.currentCharacter = '\\';
+			break;
+		default :
+			// -----------octal escape--------------
+			// OctalDigit
+			// OctalDigit OctalDigit
+			// ZeroToThree OctalDigit OctalDigit
+
+			int number = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+			if (number >= 0 && number <= 7) {
+				boolean zeroToThreeNot = number > 3;
+				if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
+					int digit = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+					if (digit >= 0 && digit <= 7) {
+						number = (number * 8) + digit;
+						if (ScannerHelper.isDigit(this.currentCharacter = this.source[this.currentPosition++])) {
+							if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character
+								this.currentPosition--;
+							} else {
+								digit = ScannerHelper.getHexadecimalValue(this.currentCharacter);
+								if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit
+									number = (number * 8) + digit;
+								} else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character
+									this.currentPosition--;
+								}
+							}
+						} else { // has read \OctalDigit NonDigit--> ignore last character
+							this.currentPosition--;
+						}
+					} else { // has read \OctalDigit NonOctalDigit--> ignore last character
+						this.currentPosition--;
+					}
+				} else { // has read \OctalDigit --> ignore last character
+					this.currentPosition--;
+				}
+				if (number > 255)
+					throw new InvalidInputException(INVALID_ESCAPE);
+				this.currentCharacter = (char) number;
+			} else
+				throw new InvalidInputException(INVALID_ESCAPE);
+	}
+}
+public int scanIdentifierOrKeywordWithBoundCheck() {
+	//test keywords
+
+	//first dispatch on the first char.
+	//then the length. If there are several
+	//keywors with the same length AND the same first char, then do another
+	//dispatch on the second char
+	this.useAssertAsAnIndentifier = false;
+	this.useEnumAsAnIndentifier = false;
+
+	char[] src = this.source;
+	identLoop: {
+		int pos;
+		int srcLength = this.eofPosition;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < ScannerHelper.MAX_OBVIOUS) {
+				if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
+						(ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
+					if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+				} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
+						this.currentCharacter = c;
+						break identLoop;
+				} else {
+					//System.out.println("slow<=128:  "+ c);
+					while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
+					break identLoop;
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);
+				while (getNextCharAsJavaIdentifierPartWithBoundCheck()){/*empty*/}
+				break identLoop;
+			}
+		}
+	}
+
+	int index, length;
+	char[] data;
+	if (this.withoutUnicodePtr == 0) {
+		//quick test on length == 1 but not on length > 12 while most identifier
+		//have a length which is <= 12...but there are lots of identifier with
+		//only one char....
+		if ((length = this.currentPosition - this.startPosition) == 1) {
+			return TokenNameIdentifier;
+		}
+		data = this.source;
+		index = this.startPosition;
+	} else {
+		if ((length = this.withoutUnicodePtr) == 1)
+			return TokenNameIdentifier;
+		data = this.withoutUnicodeBuffer;
+		index = 1;
+	}
+
+	return internalScanIdentifierOrKeyword(index, length, data);
+}
+public int scanIdentifierOrKeyword() {
+	//test keywords
+
+	//first dispatch on the first char.
+	//then the length. If there are several
+	//keywords with the same length AND the same first char, then do another
+	//dispatch on the second char
+	this.useAssertAsAnIndentifier = false;
+	this.useEnumAsAnIndentifier = false;
+
+	char[] src = this.source;
+	identLoop: {
+		int pos;
+		int srcLength = this.eofPosition;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < ScannerHelper.MAX_OBVIOUS) {
+				if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] &
+						(ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_IDENT_PART | ScannerHelper.C_DIGIT)) != 0) {
+					if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+				} else if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & (ScannerHelper.C_SEPARATOR | ScannerHelper.C_JLS_SPACE)) != 0) {
+						this.currentCharacter = c;
+						break identLoop;
+				} else {
+					//System.out.println("slow<=128:  "+ c);
+					while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+					break identLoop;
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);
+				while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+				break identLoop;
+			}
+		}
+	}
+
+	int index, length;
+	char[] data;
+	if (this.withoutUnicodePtr == 0) {
+		//quick test on length == 1 but not on length > 12 while most identifier
+		//have a length which is <= 12...but there are lots of identifier with
+		//only one char....
+		if ((length = this.currentPosition - this.startPosition) == 1) {
+			return TokenNameIdentifier;
+		}
+		data = this.source;
+		index = this.startPosition;
+	} else {
+		if ((length = this.withoutUnicodePtr) == 1)
+			return TokenNameIdentifier;
+		data = this.withoutUnicodeBuffer;
+		index = 1;
+	}
+
+	return internalScanIdentifierOrKeyword(index, length, data);
+}
+private int internalScanIdentifierOrKeyword(int index, int length, char[] data) {
+	switch (data[index]) {
+		case 'a' :
+			switch(length) {
+				case 8: //abstract
+					if ((data[++index] == 'b')
+						&& (data[++index] == 's')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')) {
+							return TokenNameabstract;
+						} else {
+							return TokenNameIdentifier;
+						}
+				case 6: // assert
+					if ((data[++index] == 's')
+						&& (data[++index] == 's')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 't')) {
+							if (this.sourceLevel >= ClassFileConstants.JDK1_4) {
+								this.containsAssertKeyword = true;
+								return TokenNameassert;
+							} else {
+								this.useAssertAsAnIndentifier = true;
+								return TokenNameIdentifier;
+							}
+						} else {
+							return TokenNameIdentifier;
+						}
+				default:
+					return TokenNameIdentifier;
+			}
+		case 'b' : //boolean break byte
+			switch (length) {
+				case 4 :
+					if ((data[++index] == 'y') && (data[++index] == 't') && (data[++index] == 'e'))
+						return TokenNamebyte;
+					else
+						return TokenNameIdentifier;
+				case 5 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'k'))
+						return TokenNamebreak;
+					else
+						return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'n'))
+						return TokenNameboolean;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'c' : //case char catch const class continue
+			switch (length) {
+				case 4 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 's') && (data[++index] == 'e'))
+							return TokenNamecase;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'h') && (data[++index] == 'a') && (data[++index] == 'r'))
+							return TokenNamechar;
+						else
+							return TokenNameIdentifier;
+				case 5 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h'))
+							return TokenNamecatch;
+						else
+							return TokenNameIdentifier;
+					else
+						if (data[index] == 'l')
+							if ((data[++index] == 'a')
+								&& (data[++index] == 's')
+								&& (data[++index] == 's'))
+								return TokenNameclass;
+							else
+								return TokenNameIdentifier;
+						else if ((data[index] == 'o')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 's')
+							&& (data[++index] == 't'))
+							return TokenNameconst; //const is not used in java ???????
+						else
+							return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'e'))
+						return TokenNamecontinue;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'd' : //default do double
+			switch (length) {
+				case 2 :
+					if ((data[++index] == 'o'))
+						return TokenNamedo;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'b')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e'))
+						return TokenNamedouble;
+					else
+						return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'e')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'u')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 't'))
+						return TokenNamedefault;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+		case 'e' : //else extends
+			switch (length) {
+				case 4 :
+					if (data[++index] == 'l') {
+						if ((data[++index] == 's') && (data[++index] == 'e')) {
+							return TokenNameelse;
+						} else {
+							return TokenNameIdentifier;
+						}
+					} else if ((data[index] == 'n')
+							&& (data[++index] == 'u')
+							&& (data[++index] == 'm')) {
+						if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
+							return TokenNameenum;
+						} else {
+							this.useEnumAsAnIndentifier = true;
+							return TokenNameIdentifier;
+						}
+					}
+					return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'x')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'd')
+						&& (data[++index] == 's'))
+						return TokenNameextends;
+					else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'f' : //final finally float for false
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'o') && (data[++index] == 'r'))
+						return TokenNamefor;
+					else
+						return TokenNameIdentifier;
+				case 5 :
+					if (data[++index] == 'i')
+						if ((data[++index] == 'n')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'l')) {
+							return TokenNamefinal;
+						} else
+							return TokenNameIdentifier;
+					else
+						if (data[index] == 'l')
+							if ((data[++index] == 'o')
+								&& (data[++index] == 'a')
+								&& (data[++index] == 't'))
+								return TokenNamefloat;
+							else
+								return TokenNameIdentifier;
+						else
+							if ((data[index] == 'a')
+								&& (data[++index] == 'l')
+								&& (data[++index] == 's')
+								&& (data[++index] == 'e'))
+								return TokenNamefalse;
+							else
+								return TokenNameIdentifier;
+				case 7 :
+					if ((data[++index] == 'i')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'y'))
+						return TokenNamefinally;
+					else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+		case 'g' : //goto
+			if (length == 4) {
+				if ((data[++index] == 'o')
+					&& (data[++index] == 't')
+					&& (data[++index] == 'o')) {
+					return TokenNamegoto;
+				}
+			} //no goto in java are allowed, so why java removes this keyword ???
+			return TokenNameIdentifier;
+
+		case 'i' : //if implements import instanceof int interface
+			switch (length) {
+				case 2 :
+					if (data[++index] == 'f')
+						return TokenNameif;
+					else
+						return TokenNameIdentifier;
+				case 3 :
+					if ((data[++index] == 'n') && (data[++index] == 't'))
+						return TokenNameint;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'm')
+						&& (data[++index] == 'p')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 't'))
+						return TokenNameimport;
+					else
+						return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'n')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 'e'))
+						return TokenNameinterface;
+					else
+						return TokenNameIdentifier;
+				case 10 :
+					if (data[++index] == 'm')
+						if ((data[++index] == 'p')
+							&& (data[++index] == 'l')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'm')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 't')
+							&& (data[++index] == 's'))
+							return TokenNameimplements;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'n')
+							&& (data[++index] == 's')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'n')
+							&& (data[++index] == 'c')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'o')
+							&& (data[++index] == 'f'))
+							return TokenNameinstanceof;
+						else
+							return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'l' : //long
+			if (length == 4) {
+				if ((data[++index] == 'o')
+					&& (data[++index] == 'n')
+					&& (data[++index] == 'g')) {
+					return TokenNamelong;
+				}
+			}
+			return TokenNameIdentifier;
+
+		case 'n' : //native new null
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'e') && (data[++index] == 'w'))
+						return TokenNamenew;
+					else
+						return TokenNameIdentifier;
+				case 4 :
+					if ((data[++index] == 'u') && (data[++index] == 'l') && (data[++index] == 'l'))
+						return TokenNamenull;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'a')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'v')
+						&& (data[++index] == 'e')) {
+						return TokenNamenative;
+					} else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'p' : //package private protected public
+			switch (length) {
+				case 6 :
+					if ((data[++index] == 'u')
+						&& (data[++index] == 'b')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'c')) {
+						return TokenNamepublic;
+					} else
+						return TokenNameIdentifier;
+				case 7 :
+					if (data[++index] == 'a')
+						if ((data[++index] == 'c')
+							&& (data[++index] == 'k')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 'g')
+							&& (data[++index] == 'e'))
+							return TokenNamepackage;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'r')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 'v')
+							&& (data[++index] == 'a')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'e')) {
+							return TokenNameprivate;
+						} else
+							return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'd')) {
+						return TokenNameprotected;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'r' : //return
+			if (length == 6) {
+				if ((data[++index] == 'e')
+					&& (data[++index] == 't')
+					&& (data[++index] == 'u')
+					&& (data[++index] == 'r')
+					&& (data[++index] == 'n')) {
+					return TokenNamereturn;
+				}
+			}
+			return TokenNameIdentifier;
+
+		case 's' : //short static super switch synchronized strictfp
+			switch (length) {
+				case 5 :
+					if (data[++index] == 'h')
+						if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 't'))
+							return TokenNameshort;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'u')
+							&& (data[++index] == 'p')
+							&& (data[++index] == 'e')
+							&& (data[++index] == 'r'))
+							return TokenNamesuper;
+						else
+							return TokenNameIdentifier;
+
+				case 6 :
+					if (data[++index] == 't')
+						if ((data[++index] == 'a')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 'c')) {
+							return TokenNamestatic;
+						} else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'w')
+							&& (data[++index] == 'i')
+							&& (data[++index] == 't')
+							&& (data[++index] == 'c')
+							&& (data[++index] == 'h'))
+							return TokenNameswitch;
+						else
+							return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 't')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'f')
+						&& (data[++index] == 'p'))
+						return TokenNamestrictfp;
+					else
+						return TokenNameIdentifier;
+				case 12 :
+					if ((data[++index] == 'y')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'c')
+						&& (data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'z')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'd')) {
+						return TokenNamesynchronized;
+					} else
+						return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 't' : //try throw throws transient this true
+			switch (length) {
+				case 3 :
+					if ((data[++index] == 'r') && (data[++index] == 'y'))
+						return TokenNametry;
+					else
+						return TokenNameIdentifier;
+				case 4 :
+					if (data[++index] == 'h')
+						if ((data[++index] == 'i') && (data[++index] == 's'))
+							return TokenNamethis;
+						else
+							return TokenNameIdentifier;
+					else
+						if ((data[index] == 'r') && (data[++index] == 'u') && (data[++index] == 'e'))
+							return TokenNametrue;
+						else
+							return TokenNameIdentifier;
+				case 5 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'w'))
+						return TokenNamethrow;
+					else
+						return TokenNameIdentifier;
+				case 6 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'r')
+						&& (data[++index] == 'o')
+						&& (data[++index] == 'w')
+						&& (data[++index] == 's'))
+						return TokenNamethrows;
+					else
+						return TokenNameIdentifier;
+				case 9 :
+					if ((data[++index] == 'r')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 's')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'e')
+						&& (data[++index] == 'n')
+						&& (data[++index] == 't')) {
+						return TokenNametransient;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'v' : //void volatile
+			switch (length) {
+				case 4 :
+					if ((data[++index] == 'o') && (data[++index] == 'i') && (data[++index] == 'd'))
+						return TokenNamevoid;
+					else
+						return TokenNameIdentifier;
+				case 8 :
+					if ((data[++index] == 'o')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'a')
+						&& (data[++index] == 't')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e')) {
+						return TokenNamevolatile;
+					} else
+						return TokenNameIdentifier;
+
+				default :
+					return TokenNameIdentifier;
+			}
+
+		case 'w' : //while widefp
+			switch (length) {
+				case 5 :
+					if ((data[++index] == 'h')
+						&& (data[++index] == 'i')
+						&& (data[++index] == 'l')
+						&& (data[++index] == 'e'))
+						return TokenNamewhile;
+					else
+						return TokenNameIdentifier;
+					//case 6:if ( (data[++index] =='i') && (data[++index]=='d') && (data[++index]=='e') && (data[++index]=='f')&& (data[++index]=='p'))
+					//return TokenNamewidefp ;
+					//else
+					//return TokenNameIdentifier;
+				default :
+					return TokenNameIdentifier;
+			}
+
+		default :
+			return TokenNameIdentifier;
+	}
+}
+
+
+public int scanNumber(boolean dotPrefix) throws InvalidInputException {
+
+	//when entering this method the currentCharacter is the first
+	//digit of the number. It may be preceeded by a '.' when
+	//dotPrefix is true
+
+	boolean floating = dotPrefix;
+	if (!dotPrefix && (this.currentCharacter == '0')) {
+		if (getNextChar('x', 'X') >= 0) { //----------hexa-----------------
+			int start = this.currentPosition;
+			consumeDigits(16, true);
+			int end = this.currentPosition;
+			if (getNextChar('l', 'L') >= 0) {
+				if (end == start) {
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+				return TokenNameLongLiteral;
+			} else if (getNextChar('.')) {
+				// hexadecimal floating point literal
+				// read decimal part
+				boolean hasNoDigitsBeforeDot = end == start;
+				start = this.currentPosition;
+				consumeDigits(16, true);
+				end = this.currentPosition;
+				if (hasNoDigitsBeforeDot && end == start) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+
+				if (getNextChar('p', 'P') >= 0) { // consume next character
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+
+					if ((this.currentCharacter == '-')
+							|| (this.currentCharacter == '+')) { // consume next character
+						this.unicodeAsBackSlash = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (!ScannerHelper.isDigit(this.currentCharacter)) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						if (this.currentCharacter == '_') {
+							// wrongly place '_'
+							consumeDigits(10);
+							throw new InvalidInputException(INVALID_UNDERSCORE);
+						}
+						throw new InvalidInputException(INVALID_HEXA);
+					}
+					consumeDigits(10);
+					if (getNextChar('f', 'F') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						return TokenNameFloatingPointLiteral;
+					}
+					if (getNextChar('d', 'D') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						return TokenNameDoubleLiteral;
+					}
+					if (getNextChar('l', 'L') >= 0) {
+						if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+						}
+						throw new InvalidInputException(INVALID_HEXA);
+					}
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameDoubleLiteral;
+				} else {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+			} else if (getNextChar('p', 'P') >= 0) { // consume next character
+				this.unicodeAsBackSlash = false;
+				if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+						&& (this.source[this.currentPosition] == 'u')) {
+					getNextUnicodeChar();
+				} else {
+					if (this.withoutUnicodePtr != 0) {
+						unicodeStore();
+					}
+				}
+
+				if ((this.currentCharacter == '-')
+						|| (this.currentCharacter == '+')) { // consume next character
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+				}
+				if (!ScannerHelper.isDigit(this.currentCharacter)) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					if (this.currentCharacter == '_') {
+						// wrongly place '_'
+						consumeDigits(10);
+						throw new InvalidInputException(INVALID_UNDERSCORE);
+					}
+					throw new InvalidInputException(INVALID_FLOAT);
+				}
+				consumeDigits(10);
+				if (getNextChar('f', 'F') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameFloatingPointLiteral;
+				}
+				if (getNextChar('d', 'D') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					return TokenNameDoubleLiteral;
+				}
+				if (getNextChar('l', 'L') >= 0) {
+					if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+						throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+					}
+					throw new InvalidInputException(INVALID_HEXA);
+				}
+				if (this.sourceLevel < ClassFileConstants.JDK1_5) {
+					throw new InvalidInputException(ILLEGAL_HEXA_LITERAL);
+				}
+				return TokenNameDoubleLiteral;
+			} else {
+				if (end == start)
+					throw new InvalidInputException(INVALID_HEXA);
+				return TokenNameIntegerLiteral;
+			}
+		} else if (getNextChar('b', 'B') >= 0) { //----------binary-----------------
+			int start = this.currentPosition;
+			consumeDigits(2, true);
+			int end = this.currentPosition;
+			if (end == start) {
+				if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+					throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+				}
+				throw new InvalidInputException(INVALID_BINARY);
+			}
+			if (getNextChar('l', 'L') >= 0) {
+				if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+					throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+				}
+				return TokenNameLongLiteral;
+			}
+			if (this.sourceLevel < ClassFileConstants.JDK1_7) {
+				throw new InvalidInputException(BINARY_LITERAL_NOT_BELOW_17);
+			}
+			return TokenNameIntegerLiteral;
+		}
+
+		//there is no x or X nor b or B in the number
+		//potential octal
+		if (getNextCharAsDigit()) { //-------------potential octal-----------------
+			consumeDigits(10);
+
+			if (getNextChar('l', 'L') >= 0) {
+				return TokenNameLongLiteral;
+			}
+
+			if (getNextChar('f', 'F') >= 0) {
+				return TokenNameFloatingPointLiteral;
+			}
+
+			if (getNextChar('d', 'D') >= 0) {
+				return TokenNameDoubleLiteral;
+			} else { //make the distinction between octal and float ....
+				boolean isInteger = true;
+				if (getNextChar('.')) {
+					isInteger = false;
+					consumeDigits(10);
+				}
+				if (getNextChar('e', 'E') >= 0) { // consume next character
+					isInteger = false;
+					this.unicodeAsBackSlash = false;
+					if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+							&& (this.source[this.currentPosition] == 'u')) {
+						getNextUnicodeChar();
+					} else {
+						if (this.withoutUnicodePtr != 0) {
+							unicodeStore();
+						}
+					}
+
+					if ((this.currentCharacter == '-')
+							|| (this.currentCharacter == '+')) { // consume next character
+						this.unicodeAsBackSlash = false;
+						if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+								&& (this.source[this.currentPosition] == 'u')) {
+							getNextUnicodeChar();
+						} else {
+							if (this.withoutUnicodePtr != 0) {
+								unicodeStore();
+							}
+						}
+					}
+					if (!ScannerHelper.isDigit(this.currentCharacter)) {
+						if (this.currentCharacter == '_') {
+							// wrongly place '_'
+							consumeDigits(10);
+							throw new InvalidInputException(INVALID_UNDERSCORE);
+						}
+						throw new InvalidInputException(INVALID_FLOAT);
+					}
+					consumeDigits(10);
+				}
+				if (getNextChar('f', 'F') >= 0)
+					return TokenNameFloatingPointLiteral;
+				if (getNextChar('d', 'D') >= 0 || !isInteger)
+					return TokenNameDoubleLiteral;
+				return TokenNameIntegerLiteral;
+			}
+		} else {
+			/* carry on */
+		}
+	}
+
+	consumeDigits(10);
+
+	if ((!dotPrefix) && (getNextChar('l', 'L') >= 0))
+		return TokenNameLongLiteral;
+
+	if ((!dotPrefix) && (getNextChar('.'))) { //decimal part that can be empty
+		consumeDigits(10, true);
+		floating = true;
+	}
+
+	//if floating is true both exponant and suffix may be optional
+
+	if (getNextChar('e', 'E') >= 0) {
+		floating = true;
+		// consume next character
+		this.unicodeAsBackSlash = false;
+		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+				&& (this.source[this.currentPosition] == 'u')) {
+			getNextUnicodeChar();
+		} else {
+			if (this.withoutUnicodePtr != 0) {
+				unicodeStore();
+			}
+		}
+
+		if ((this.currentCharacter == '-')
+				|| (this.currentCharacter == '+')) { // consume next character
+			this.unicodeAsBackSlash = false;
+			if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
+					&& (this.source[this.currentPosition] == 'u')) {
+				getNextUnicodeChar();
+			} else {
+				if (this.withoutUnicodePtr != 0) {
+					unicodeStore();
+				}
+			}
+		}
+		if (!ScannerHelper.isDigit(this.currentCharacter)) {
+			if (this.currentCharacter == '_') {
+				// wrongly place '_'
+				consumeDigits(10);
+				throw new InvalidInputException(INVALID_UNDERSCORE);
+			}
+			throw new InvalidInputException(INVALID_FLOAT);
+		}
+		// current character is a digit so we expect no digit first (the next character could be an underscore)
+		consumeDigits(10);
+	}
+
+	if (getNextChar('d', 'D') >= 0)
+		return TokenNameDoubleLiteral;
+	if (getNextChar('f', 'F') >= 0)
+		return TokenNameFloatingPointLiteral;
+
+	//the long flag has been tested before
+
+	return floating ? TokenNameDoubleLiteral : TokenNameIntegerLiteral;
+}
+
+/**
+ * Search the line number corresponding to a specific position
+ * @param position int
+ * @return int
+ */
+public final int getLineNumber(int position) {
+	return Util.getLineNumber(position, this.lineEnds, 0, this.linePtr);
+}
+public final void setSource(char[] sourceString){
+	//the source-buffer is set to sourceString
+
+	int sourceLength;
+	if (sourceString == null) {
+		this.source = CharOperation.NO_CHAR;
+		sourceLength = 0;
+	} else {
+		this.source = sourceString;
+		sourceLength = sourceString.length;
+	}
+	this.startPosition = -1;
+	this.eofPosition = sourceLength;
+	this.initialPosition = this.currentPosition = 0;
+	this.containsAssertKeyword = false;
+	this.linePtr = -1;
+}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(char[] contents, CompilationResult compilationResult) {
+	if (contents == null) {
+		char[] cuContents = compilationResult.compilationUnit.getContents();
+		setSource(cuContents);
+	} else {
+		setSource(contents);
+	}
+	int[] lineSeparatorPositions = compilationResult.lineSeparatorPositions;
+	if (lineSeparatorPositions != null) {
+		this.lineEnds = lineSeparatorPositions;
+		this.linePtr = lineSeparatorPositions.length - 1;
+	}
+}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(CompilationResult compilationResult) {
+	setSource(null, compilationResult);
+}
+public String toString() {
+	if (this.startPosition == this.eofPosition)
+		return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
+	if (this.currentPosition > this.eofPosition)
+		return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
+	if (this.currentPosition <= 0)
+		return "NOT started!\n\n"+ new String(this.source); //$NON-NLS-1$
+
+	StringBuffer buffer = new StringBuffer();
+	if (this.startPosition < 1000) {
+		buffer.append(this.source, 0, this.startPosition);
+	} else {
+		buffer.append("<source beginning>\n...\n"); //$NON-NLS-1$
+		int line = Util.getLineNumber(this.startPosition-1000, this.lineEnds, 0, this.linePtr);
+		int lineStart = getLineStart(line);
+		buffer.append(this.source, lineStart, this.startPosition-lineStart);
+	}
+
+	buffer.append("\n===============================\nStarts here -->"); //$NON-NLS-1$
+	int middleLength = (this.currentPosition - 1) - this.startPosition + 1;
+	if (middleLength > -1) {
+		buffer.append(this.source, this.startPosition, middleLength);
+	}
+	buffer.append("<-- Ends here\n===============================\n"); //$NON-NLS-1$
+
+	buffer.append(this.source, (this.currentPosition - 1) + 1, this.eofPosition - (this.currentPosition - 1) - 1);
+
+	return buffer.toString();
+}
+public String toStringAction(int act) {
+	switch (act) {
+		case TokenNameIdentifier :
+			return "Identifier(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameabstract :
+			return "abstract"; //$NON-NLS-1$
+		case TokenNameboolean :
+			return "boolean"; //$NON-NLS-1$
+		case TokenNamebreak :
+			return "break"; //$NON-NLS-1$
+		case TokenNamebyte :
+			return "byte"; //$NON-NLS-1$
+		case TokenNamecase :
+			return "case"; //$NON-NLS-1$
+		case TokenNamecatch :
+			return "catch"; //$NON-NLS-1$
+		case TokenNamechar :
+			return "char"; //$NON-NLS-1$
+		case TokenNameclass :
+			return "class"; //$NON-NLS-1$
+		case TokenNamecontinue :
+			return "continue"; //$NON-NLS-1$
+		case TokenNamedefault :
+			return "default"; //$NON-NLS-1$
+		case TokenNamedo :
+			return "do"; //$NON-NLS-1$
+		case TokenNamedouble :
+			return "double"; //$NON-NLS-1$
+		case TokenNameelse :
+			return "else"; //$NON-NLS-1$
+		case TokenNameextends :
+			return "extends"; //$NON-NLS-1$
+		case TokenNamefalse :
+			return "false"; //$NON-NLS-1$
+		case TokenNamefinal :
+			return "final"; //$NON-NLS-1$
+		case TokenNamefinally :
+			return "finally"; //$NON-NLS-1$
+		case TokenNamefloat :
+			return "float"; //$NON-NLS-1$
+		case TokenNamefor :
+			return "for"; //$NON-NLS-1$
+		case TokenNameif :
+			return "if"; //$NON-NLS-1$
+		case TokenNameimplements :
+			return "implements"; //$NON-NLS-1$
+		case TokenNameimport :
+			return "import"; //$NON-NLS-1$
+		case TokenNameinstanceof :
+			return "instanceof"; //$NON-NLS-1$
+		case TokenNameint :
+			return "int"; //$NON-NLS-1$
+		case TokenNameinterface :
+			return "interface"; //$NON-NLS-1$
+		case TokenNamelong :
+			return "long"; //$NON-NLS-1$
+		case TokenNamenative :
+			return "native"; //$NON-NLS-1$
+		case TokenNamenew :
+			return "new"; //$NON-NLS-1$
+		case TokenNamenull :
+			return "null"; //$NON-NLS-1$
+		case TokenNamepackage :
+			return "package"; //$NON-NLS-1$
+		case TokenNameprivate :
+			return "private"; //$NON-NLS-1$
+		case TokenNameprotected :
+			return "protected"; //$NON-NLS-1$
+		case TokenNamepublic :
+			return "public"; //$NON-NLS-1$
+		case TokenNamereturn :
+			return "return"; //$NON-NLS-1$
+		case TokenNameshort :
+			return "short"; //$NON-NLS-1$
+		case TokenNamestatic :
+			return "static"; //$NON-NLS-1$
+		case TokenNamesuper :
+			return "super"; //$NON-NLS-1$
+		case TokenNameswitch :
+			return "switch"; //$NON-NLS-1$
+		case TokenNamesynchronized :
+			return "synchronized"; //$NON-NLS-1$
+		case TokenNamethis :
+			return "this"; //$NON-NLS-1$
+		case TokenNamethrow :
+			return "throw"; //$NON-NLS-1$
+		case TokenNamethrows :
+			return "throws"; //$NON-NLS-1$
+		case TokenNametransient :
+			return "transient"; //$NON-NLS-1$
+		case TokenNametrue :
+			return "true"; //$NON-NLS-1$
+		case TokenNametry :
+			return "try"; //$NON-NLS-1$
+		case TokenNamevoid :
+			return "void"; //$NON-NLS-1$
+		case TokenNamevolatile :
+			return "volatile"; //$NON-NLS-1$
+		case TokenNamewhile :
+			return "while"; //$NON-NLS-1$
+
+		case TokenNameIntegerLiteral :
+			return "Integer(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameLongLiteral :
+			return "Long(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameFloatingPointLiteral :
+			return "Float(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameDoubleLiteral :
+			return "Double(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameCharacterLiteral :
+			return "Char(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		case TokenNameStringLiteral :
+			return "String(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+
+		case TokenNamePLUS_PLUS :
+			return "++"; //$NON-NLS-1$
+		case TokenNameMINUS_MINUS :
+			return "--"; //$NON-NLS-1$
+		case TokenNameEQUAL_EQUAL :
+			return "=="; //$NON-NLS-1$
+		case TokenNameLESS_EQUAL :
+			return "<="; //$NON-NLS-1$
+		case TokenNameGREATER_EQUAL :
+			return ">="; //$NON-NLS-1$
+		case TokenNameNOT_EQUAL :
+			return "!="; //$NON-NLS-1$
+		case TokenNameLEFT_SHIFT :
+			return "<<"; //$NON-NLS-1$
+		case TokenNameRIGHT_SHIFT :
+			return ">>"; //$NON-NLS-1$
+		case TokenNameUNSIGNED_RIGHT_SHIFT :
+			return ">>>"; //$NON-NLS-1$
+		case TokenNamePLUS_EQUAL :
+			return "+="; //$NON-NLS-1$
+		case TokenNameMINUS_EQUAL :
+			return "-="; //$NON-NLS-1$
+		case TokenNameARROW :
+			return "->"; //$NON-NLS-1$
+		case TokenNameMULTIPLY_EQUAL :
+			return "*="; //$NON-NLS-1$
+		case TokenNameDIVIDE_EQUAL :
+			return "/="; //$NON-NLS-1$
+		case TokenNameAND_EQUAL :
+			return "&="; //$NON-NLS-1$
+		case TokenNameOR_EQUAL :
+			return "|="; //$NON-NLS-1$
+		case TokenNameXOR_EQUAL :
+			return "^="; //$NON-NLS-1$
+		case TokenNameREMAINDER_EQUAL :
+			return "%="; //$NON-NLS-1$
+		case TokenNameLEFT_SHIFT_EQUAL :
+			return "<<="; //$NON-NLS-1$
+		case TokenNameRIGHT_SHIFT_EQUAL :
+			return ">>="; //$NON-NLS-1$
+		case TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL :
+			return ">>>="; //$NON-NLS-1$
+		case TokenNameOR_OR :
+			return "||"; //$NON-NLS-1$
+		case TokenNameAND_AND :
+			return "&&"; //$NON-NLS-1$
+		case TokenNamePLUS :
+			return "+"; //$NON-NLS-1$
+		case TokenNameMINUS :
+			return "-"; //$NON-NLS-1$
+		case TokenNameNOT :
+			return "!"; //$NON-NLS-1$
+		case TokenNameREMAINDER :
+			return "%"; //$NON-NLS-1$
+		case TokenNameXOR :
+			return "^"; //$NON-NLS-1$
+		case TokenNameAND :
+			return "&"; //$NON-NLS-1$
+		case TokenNameMULTIPLY :
+			return "*"; //$NON-NLS-1$
+		case TokenNameOR :
+			return "|"; //$NON-NLS-1$
+		case TokenNameTWIDDLE :
+			return "~"; //$NON-NLS-1$
+		case TokenNameDIVIDE :
+			return "/"; //$NON-NLS-1$
+		case TokenNameGREATER :
+			return ">"; //$NON-NLS-1$
+		case TokenNameLESS :
+			return "<"; //$NON-NLS-1$
+		case TokenNameLPAREN :
+			return "("; //$NON-NLS-1$
+		case TokenNameRPAREN :
+			return ")"; //$NON-NLS-1$
+		case TokenNameLBRACE :
+			return "{"; //$NON-NLS-1$
+		case TokenNameRBRACE :
+			return "}"; //$NON-NLS-1$
+		case TokenNameLBRACKET :
+			return "["; //$NON-NLS-1$
+		case TokenNameRBRACKET :
+			return "]"; //$NON-NLS-1$
+		case TokenNameSEMICOLON :
+			return ";"; //$NON-NLS-1$
+		case TokenNameQUESTION :
+			return "?"; //$NON-NLS-1$
+		case TokenNameCOLON :
+			return ":"; //$NON-NLS-1$
+		case TokenNameCOLON_COLON :
+			return "::"; //$NON-NLS-1$
+		case TokenNameCOMMA :
+			return ","; //$NON-NLS-1$
+		case TokenNameDOT :
+			return "."; //$NON-NLS-1$
+		case TokenNameEQUAL :
+			return "="; //$NON-NLS-1$
+		case TokenNameEOF :
+			return "EOF"; //$NON-NLS-1$
+		case TokenNameWHITESPACE :
+			return "white_space(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+		default :
+			return "not-a-token"; //$NON-NLS-1$
+	}
+}
+public void unicodeInitializeBuffer(int length) {
+	this.withoutUnicodePtr = length;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[length+(1+10)];
+	int bLength = this.withoutUnicodeBuffer.length;
+	if (1+length >= bLength) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length + (1+10)], 0, bLength);
+	}
+	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);
+}
+public void unicodeStore() {
+	int pos = ++this.withoutUnicodePtr;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+	int length = this.withoutUnicodeBuffer.length;
+	if (pos == length) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+	}
+	this.withoutUnicodeBuffer[pos] = this.currentCharacter;
+}
+public void unicodeStore(char character) {
+	int pos = ++this.withoutUnicodePtr;
+	if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+	int length = this.withoutUnicodeBuffer.length;
+	if (pos == length) {
+		System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+	}
+	this.withoutUnicodeBuffer[pos] = character;
+}
+
+public static boolean isIdentifier(int token) {
+	return token == TerminalTokens.TokenNameIdentifier;
+}
+
+public static boolean isLiteral(int token) {
+	switch(token) {
+		case TerminalTokens.TokenNameIntegerLiteral:
+		case TerminalTokens.TokenNameLongLiteral:
+		case TerminalTokens.TokenNameFloatingPointLiteral:
+		case TerminalTokens.TokenNameDoubleLiteral:
+		case TerminalTokens.TokenNameStringLiteral:
+		case TerminalTokens.TokenNameCharacterLiteral:
+			return true;
+		default:
+			return false;
+	}
+}
+
+public static boolean isKeyword(int token) {
+	switch(token) {
+		case TerminalTokens.TokenNameabstract:
+		case TerminalTokens.TokenNameassert:
+		case TerminalTokens.TokenNamebyte:
+		case TerminalTokens.TokenNamebreak:
+		case TerminalTokens.TokenNameboolean:
+		case TerminalTokens.TokenNamecase:
+		case TerminalTokens.TokenNamechar:
+		case TerminalTokens.TokenNamecatch:
+		case TerminalTokens.TokenNameclass:
+		case TerminalTokens.TokenNamecontinue:
+		case TerminalTokens.TokenNamedo:
+		case TerminalTokens.TokenNamedouble:
+		case TerminalTokens.TokenNamedefault:
+		case TerminalTokens.TokenNameelse:
+		case TerminalTokens.TokenNameextends:
+		case TerminalTokens.TokenNamefor:
+		case TerminalTokens.TokenNamefinal:
+		case TerminalTokens.TokenNamefloat:
+		case TerminalTokens.TokenNamefalse:
+		case TerminalTokens.TokenNamefinally:
+		case TerminalTokens.TokenNameif:
+		case TerminalTokens.TokenNameint:
+		case TerminalTokens.TokenNameimport:
+		case TerminalTokens.TokenNameinterface:
+		case TerminalTokens.TokenNameimplements:
+		case TerminalTokens.TokenNameinstanceof:
+		case TerminalTokens.TokenNamelong:
+		case TerminalTokens.TokenNamenew:
+		case TerminalTokens.TokenNamenull:
+		case TerminalTokens.TokenNamenative:
+		case TerminalTokens.TokenNamepublic:
+		case TerminalTokens.TokenNamepackage:
+		case TerminalTokens.TokenNameprivate:
+		case TerminalTokens.TokenNameprotected:
+		case TerminalTokens.TokenNamereturn:
+		case TerminalTokens.TokenNameshort:
+		case TerminalTokens.TokenNamesuper:
+		case TerminalTokens.TokenNamestatic:
+		case TerminalTokens.TokenNameswitch:
+		case TerminalTokens.TokenNamestrictfp:
+		case TerminalTokens.TokenNamesynchronized:
+		case TerminalTokens.TokenNametry:
+		case TerminalTokens.TokenNamethis:
+		case TerminalTokens.TokenNametrue:
+		case TerminalTokens.TokenNamethrow:
+		case TerminalTokens.TokenNamethrows:
+		case TerminalTokens.TokenNametransient:
+		case TerminalTokens.TokenNamevoid:
+		case TerminalTokens.TokenNamevolatile:
+		case TerminalTokens.TokenNamewhile:
+			return true;
+		default:
+			return false;
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java
new file mode 100644
index 0000000..3dd9ed6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2002, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CategorizedProblem;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+
+/**
+ * Use to keep track of recorded information during the parsing like comment positions,
+ * line ends or problems.
+ */
+public class RecordedParsingInformation {
+	public CategorizedProblem[] problems;
+	public int problemsCount;
+	public int[] lineEnds;
+	public int[][] commentPositions;
+
+	public RecordedParsingInformation(CategorizedProblem[] problems, int[] lineEnds, int[][] commentPositions) {
+		this.problems = problems;
+		this.lineEnds = lineEnds;
+		this.commentPositions = commentPositions;
+		this.problemsCount = problems != null ? problems.length : 0;
+	}
+
+	void updateRecordedParsingInformation(CompilationResult compilationResult) {
+		if (compilationResult.problems != null) {
+			this.problems = compilationResult.problems;
+			this.problemsCount = this.problems.length;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java
new file mode 100644
index 0000000..e5d3c91
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * An adapter which implements the methods for handling
+ * reference information from the parser.
+ */
+public abstract class ReferenceInfoAdapter {
+/**
+ * Does nothing.
+ */
+public void acceptAnnotationTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptAnnotationTypeReference(char[] typeName, int sourcePosition) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptFieldReference(char[] fieldName, int sourcePosition) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptTypeReference(char[] typeName, int sourcePosition) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) {
+	// Does nothing
+}
+/**
+ * Does nothing.
+ */
+public void acceptUnknownReference(char[] name, int sourcePosition) {
+	// Does nothing
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ResourceCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ResourceCompilationUnit.java
new file mode 100644
index 0000000..f82a4aa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ResourceCompilationUnit.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.net.URI;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
+
+/**
+ * An ICompilationUnit that retrieves its contents using an IFile
+ */
+public class ResourceCompilationUnit extends CompilationUnit {
+
+	private IFile file;
+
+	public ResourceCompilationUnit(IFile file, URI location) {
+		super(null/*no contents*/, location == null ? file.getFullPath().toString() : location.getPath(), null/*encoding is used only when retrieving the contents*/);
+		this.file = file;
+	}
+
+	public char[] getContents() {
+		if (this.contents != null)
+			return this.contents;   // answer the cached source
+
+		// otherwise retrieve it
+		try {
+			return Util.getResourceContentsAsCharArray(this.file);
+		} catch (CoreException e) {
+			return CharOperation.NO_CHAR;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java
new file mode 100644
index 0000000..a8833bf
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotation;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeInvisibleAnnotations
+ */
+public class RuntimeInvisibleAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeInvisibleAnnotationsAttribute {
+
+	private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0];
+	private int annotationsNumber;
+	private IAnnotation[] annotations;
+
+	/**
+	 * Constructor for RuntimeInvisibleAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeInvisibleAnnotationsAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset)
+			throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u2At(classFileBytes, 6, offset);
+		this.annotationsNumber = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.annotations = new IAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset);
+				this.annotations[i] = annotation;
+				readOffset += annotation.sizeInBytes();
+			}
+		} else {
+			this.annotations = NO_ENTRIES;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotations#getAnnotations()
+	 */
+	public IAnnotation[] getAnnotations() {
+		return this.annotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotations#getAnnotationsNumber()
+	 */
+	public int getAnnotationsNumber() {
+		return this.annotationsNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java
new file mode 100644
index 0000000..e14af82
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IParameterAnnotation;
+import org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeInvisibleParameterAnnotations
+ */
+public class RuntimeInvisibleParameterAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeInvisibleParameterAnnotationsAttribute {
+
+	private static final IParameterAnnotation[] NO_ENTRIES = new IParameterAnnotation[0];
+	private IParameterAnnotation[] parameterAnnotations;
+	private int parametersNumber;
+
+	/**
+	 * Constructor for RuntimeVisibleParameterAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeInvisibleParameterAnnotationsAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u1At(classFileBytes, 6, offset);
+		this.parametersNumber = length;
+		if (length != 0) {
+			int readOffset = 7;
+			this.parameterAnnotations = new IParameterAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				ParameterAnnotation parameterAnnotation = new ParameterAnnotation(classFileBytes, constantPool, offset + readOffset);
+				this.parameterAnnotations[i] = parameterAnnotation;
+				readOffset += parameterAnnotation.sizeInBytes();
+			}
+		} else {
+			this.parameterAnnotations = NO_ENTRIES;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotations#getAnnotations()
+	 */
+	public IParameterAnnotation[] getParameterAnnotations() {
+		return this.parameterAnnotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotations#getParametersNumber()
+	 */
+	public int getParametersNumber() {
+		return this.parametersNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleTypeAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleTypeAnnotationsAttribute.java
new file mode 100644
index 0000000..cb65eab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleTypeAnnotationsAttribute.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IExtendedAnnotation;
+import org.eclipse.jdt.core.util.IRuntimeInvisibleTypeAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeInvisibleTypeAnnotations
+ */
+public class RuntimeInvisibleTypeAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeInvisibleTypeAnnotationsAttribute {
+
+	private static final IExtendedAnnotation[] NO_ENTRIES = new IExtendedAnnotation[0];
+	private int extendedAnnotationsNumber;
+	private IExtendedAnnotation[] extendedAnnotations;
+
+	/**
+	 * Constructor for RuntimeInvisibleTypeAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeInvisibleTypeAnnotationsAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset)
+			throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		// read extended annotations
+		final int length = u2At(classFileBytes, 6, offset);
+		this.extendedAnnotationsNumber = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.extendedAnnotations = new IExtendedAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				ExtendedAnnotation extendedAnnotation = new ExtendedAnnotation(classFileBytes, constantPool, offset + readOffset);
+				this.extendedAnnotations[i] = extendedAnnotation;
+				readOffset += extendedAnnotation.sizeInBytes();
+			}
+		} else {
+			this.extendedAnnotations = NO_ENTRIES;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleTypeAnnotationsAttribute.getExtendedAnnotations()
+	 */
+	public IExtendedAnnotation[] getExtendedAnnotations() {
+		return this.extendedAnnotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeInvisibleTypeAnnotationsAttribute.getExtendedAnnotationsNumber()
+	 */
+	public int getExtendedAnnotationsNumber() {
+		return this.extendedAnnotationsNumber;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java
new file mode 100644
index 0000000..4c1dd2c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IAnnotation;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IRuntimeVisibleAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeVisibleAnnotations
+ */
+public class RuntimeVisibleAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeVisibleAnnotationsAttribute {
+
+	private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0];
+	private int annotationsNumber;
+	private IAnnotation[] annotations;
+
+	/**
+	 * Constructor for RuntimeVisibleAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeVisibleAnnotationsAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u2At(classFileBytes, 6, offset);
+		this.annotationsNumber = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.annotations = new IAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset);
+				this.annotations[i] = annotation;
+				readOffset += annotation.sizeInBytes();
+			}
+		} else {
+			this.annotations = NO_ENTRIES;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleAnnotations#getAnnotations()
+	 */
+	public IAnnotation[] getAnnotations() {
+		return this.annotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleAnnotations#getAnnotationsNumber()
+	 */
+	public int getAnnotationsNumber() {
+		return this.annotationsNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java
new file mode 100644
index 0000000..00ced22
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IParameterAnnotation;
+import org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeVisibleAnnotations
+ */
+public class RuntimeVisibleParameterAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeVisibleParameterAnnotationsAttribute {
+
+	private static final IParameterAnnotation[] NO_ENTRIES = new IParameterAnnotation[0];
+	private int parametersNumber;
+	private IParameterAnnotation[] parameterAnnotations;
+
+	/**
+	 * Constructor for RuntimeVisibleParameterAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeVisibleParameterAnnotationsAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u1At(classFileBytes, 6, offset);
+		this.parametersNumber = length;
+		if (length != 0) {
+			int readOffset = 7;
+			this.parameterAnnotations = new IParameterAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				ParameterAnnotation parameterAnnotation = new ParameterAnnotation(classFileBytes, constantPool, offset + readOffset);
+				this.parameterAnnotations[i] = parameterAnnotation;
+				readOffset += parameterAnnotation.sizeInBytes();
+			}
+		} else {
+			this.parameterAnnotations = NO_ENTRIES;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotations#getAnnotations()
+	 */
+	public IParameterAnnotation[] getParameterAnnotations() {
+		return this.parameterAnnotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotations#getParametersNumber()
+	 */
+	public int getParametersNumber() {
+		return this.parametersNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleTypeAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleTypeAnnotationsAttribute.java
new file mode 100644
index 0000000..348e459
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleTypeAnnotationsAttribute.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *        Andy Clement - Contributions for
+ *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IExtendedAnnotation;
+import org.eclipse.jdt.core.util.IRuntimeVisibleTypeAnnotationsAttribute;
+
+/**
+ * Default implementation of IRuntimeVisibleTypeAnnotations
+ */
+public class RuntimeVisibleTypeAnnotationsAttribute
+	extends ClassFileAttribute
+	implements IRuntimeVisibleTypeAnnotationsAttribute {
+
+	private static final IExtendedAnnotation[] NO_ENTRIES = new IExtendedAnnotation[0];
+	private int extendedAnnotationsNumber;
+	private IExtendedAnnotation[] extendedAnnotations;
+
+	/**
+	 * Constructor for RuntimeVisibleTypeAnnotations.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public RuntimeVisibleTypeAnnotationsAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int length = u2At(classFileBytes, 6, offset);
+		this.extendedAnnotationsNumber = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.extendedAnnotations = new IExtendedAnnotation[length];
+			for (int i = 0; i < length; i++) {
+				ExtendedAnnotation extendedAnnotation = new ExtendedAnnotation(classFileBytes, constantPool, offset + readOffset);
+				this.extendedAnnotations[i] = extendedAnnotation;
+				readOffset += extendedAnnotation.sizeInBytes();
+			}
+		} else {
+			this.extendedAnnotations = NO_ENTRIES;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleTypeAnnotationsAttribute.getExtendedAnnotations()
+	 */
+	public IExtendedAnnotation[] getExtendedAnnotations() {
+		return this.extendedAnnotations;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.IRuntimeVisibleTypeAnnotationsAttribute.getExtendedAnnotationsNumber()
+	 */
+	public int getExtendedAnnotationsNumber() {
+		return this.extendedAnnotationsNumber;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java
new file mode 100644
index 0000000..0c8c311
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.ISignatureAttribute;
+
+/**
+ * @since 3.0
+ */
+public class SignatureAttribute extends ClassFileAttribute implements ISignatureAttribute {
+
+	private int signatureIndex;
+	private char[] signature;
+
+	SignatureAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		final int index = u2At(classFileBytes, 6, offset);
+		this.signatureIndex = index;
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.signature = constantPoolEntry.getUtf8Value();
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.ISignatureAttribute#getSignatureIndex()
+	 */
+	public int getSignatureIndex() {
+		return this.signatureIndex;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.util.ISignatureAttribute#getSignature()
+	 */
+	public char[] getSignature() {
+		return this.signature;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java
new file mode 100644
index 0000000..d9bb9fc
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.IDocumentPartitioningListener;
+import org.eclipse.jface.text.IPositionUpdater;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Position;
+
+/**
+ * Minimal implementation of IDocument to apply text edit onto a string.
+ */
+public class SimpleDocument implements IDocument {
+
+	private StringBuffer buffer;
+
+
+	public SimpleDocument(String source) {
+		this.buffer = new StringBuffer(source);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getChar(int)
+	 */
+	public char getChar(int offset) {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLength()
+	 */
+	public int getLength() {
+		return this.buffer.length();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#get()
+	 */
+	public String get() {
+		return this.buffer.toString();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#get(int, int)
+	 */
+	public String get(int offset, int length) {
+		return this.buffer.substring(offset, offset + length);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#set(java.lang.String)
+	 */
+	public void set(String text) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#replace(int, int, java.lang.String)
+	 */
+	public void replace(int offset, int length, String text) {
+
+		this.buffer.replace(offset, offset + length, text);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addDocumentListener(org.eclipse.jface.text.IDocumentListener)
+	 */
+	public void addDocumentListener(IDocumentListener listener) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removeDocumentListener(org.eclipse.jface.text.IDocumentListener)
+	 */
+	public void removeDocumentListener(IDocumentListener listener) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addPrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
+	 */
+	public void addPrenotifiedDocumentListener(IDocumentListener documentAdapter) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removePrenotifiedDocumentListener(org.eclipse.jface.text.IDocumentListener)
+	 */
+	public void removePrenotifiedDocumentListener(IDocumentListener documentAdapter) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addPositionCategory(java.lang.String)
+	 */
+	public void addPositionCategory(String category) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removePositionCategory(java.lang.String)
+	 */
+	public void removePositionCategory(String category) {
+			// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getPositionCategories()
+	 */
+	public String[] getPositionCategories() {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#containsPositionCategory(java.lang.String)
+	 */
+	public boolean containsPositionCategory(String category) {
+		// defining interface method
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addPosition(org.eclipse.jface.text.Position)
+	 */
+	public void addPosition(Position position) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removePosition(org.eclipse.jface.text.Position)
+	 */
+	public void removePosition(Position position) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addPosition(java.lang.String, org.eclipse.jface.text.Position)
+	 */
+	public void addPosition(String category, Position position) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removePosition(java.lang.String, org.eclipse.jface.text.Position)
+	 */
+	public void removePosition(String category, Position position) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getPositions(java.lang.String)
+	 */
+	public Position[] getPositions(String category) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#containsPosition(java.lang.String, int, int)
+	 */
+	public boolean containsPosition(String category, int offset, int length) {
+		// defining interface method
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#computeIndexInCategory(java.lang.String, int)
+	 */
+	public int computeIndexInCategory(String category, int offset) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addPositionUpdater(org.eclipse.jface.text.IPositionUpdater)
+	 */
+	public void addPositionUpdater(IPositionUpdater updater) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removePositionUpdater(org.eclipse.jface.text.IPositionUpdater)
+	 */
+	public void removePositionUpdater(IPositionUpdater updater) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#insertPositionUpdater(org.eclipse.jface.text.IPositionUpdater, int)
+	 */
+	public void insertPositionUpdater(IPositionUpdater updater, int index) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getPositionUpdaters()
+	 */
+	public IPositionUpdater[] getPositionUpdaters() {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLegalContentTypes()
+	 */
+	public String[] getLegalContentTypes() {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getContentType(int)
+	 */
+	public String getContentType(int offset) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getPartition(int)
+	 */
+	public ITypedRegion getPartition(int offset) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#computePartitioning(int, int)
+	 */
+	public ITypedRegion[] computePartitioning(int offset, int length) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#addDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
+	 */
+	public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#removeDocumentPartitioningListener(org.eclipse.jface.text.IDocumentPartitioningListener)
+	 */
+	public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#setDocumentPartitioner(org.eclipse.jface.text.IDocumentPartitioner)
+	 */
+	public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
+		// defining interface method
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getDocumentPartitioner()
+	 */
+	public IDocumentPartitioner getDocumentPartitioner() {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineLength(int)
+	 */
+	public int getLineLength(int line) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineOfOffset(int)
+	 */
+	public int getLineOfOffset(int offset) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineOffset(int)
+	 */
+	public int getLineOffset(int line) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineInformation(int)
+	 */
+	public IRegion getLineInformation(int line) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineInformationOfOffset(int)
+	 */
+	public IRegion getLineInformationOfOffset(int offset) {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getNumberOfLines()
+	 */
+	public int getNumberOfLines() {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getNumberOfLines(int, int)
+	 */
+	public int getNumberOfLines(int offset, int length) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#computeNumberOfLines(java.lang.String)
+	 */
+	public int computeNumberOfLines(String text) {
+		// defining interface method
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLegalLineDelimiters()
+	 */
+	public String[] getLegalLineDelimiters() {
+		// defining interface method
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.text.IDocument#getLineDelimiter(int)
+	 */
+	public String getLineDelimiter(int line) {
+		// defining interface method
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.jface.text.IDocument#search(int, java.lang.String, boolean, boolean, boolean)
+	 * @deprecated
+	 */
+	public int search(
+		int startOffset,
+		String findString,
+		boolean forwardSearch,
+		boolean caseSensitive,
+		boolean wholeWord) {
+		// defining interface method
+		return 0;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java
new file mode 100644
index 0000000..ff4e44b
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+public final class SimpleWordSet {
+
+// to avoid using Enumerations, walk the individual values skipping nulls
+public char[][] words;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+public SimpleWordSet(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.words = new char[extraRoom][];
+}
+
+public char[] add(char[] word) {
+	int length = this.words.length;
+	int index = CharOperation.hashCode(word) % length;
+	char[] current;
+	while ((current = this.words[index]) != null) {
+		if (CharOperation.equals(current, word)) return current;
+		if (++index == length) index = 0;
+	}
+	this.words[index] = word;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return word;
+}
+
+public boolean includes(char[] word) {
+	int length = this.words.length;
+	int index = CharOperation.hashCode(word) % length;
+	char[] current;
+	while ((current = this.words[index]) != null) {
+		if (CharOperation.equals(current, word)) return true;
+		if (++index == length) index = 0;
+	}
+	return false;
+}
+
+private void rehash() {
+	SimpleWordSet newSet = new SimpleWordSet(this.elementSize * 2); // double the number of expected elements
+	char[] current;
+	for (int i = this.words.length; --i >= 0;)
+		if ((current = this.words[i]) != null)
+			newSet.add(current);
+
+	this.words = newSet.words;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java
new file mode 100644
index 0000000..37a5727
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.ISourceAttribute;
+
+/**
+ * Default implementation of ISourceAttribute
+ */
+public class SourceFileAttribute
+	extends ClassFileAttribute
+	implements ISourceAttribute {
+
+	private int sourceFileIndex;
+	private char[] sourceFileName;
+
+	/**
+	 * Constructor for SourceFileAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public SourceFileAttribute(
+		byte[] classFileBytes,
+		IConstantPool constantPool,
+		int offset)
+		throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+		this.sourceFileIndex = u2At(classFileBytes, 6, offset);
+		IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.sourceFileIndex);
+		if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
+			throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+		}
+		this.sourceFileName = constantPoolEntry.getUtf8Value();
+	}
+	/**
+	 * @see ISourceAttribute#getSourceFileIndex()
+	 */
+	public int getSourceFileIndex() {
+		return this.sourceFileIndex;
+	}
+
+	/**
+	 * @see ISourceAttribute#getSourceFileName()
+	 */
+	public char[] getSourceFileName() {
+		return this.sourceFileName;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapAttribute.java
new file mode 100644
index 0000000..e686c7c
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapAttribute.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IStackMapFrame;
+import org.eclipse.jdt.core.util.IStackMapAttribute;
+/**
+ * Default implementation of IStackMapAttribute.
+ * @see IStackMapAttribute
+ */
+public class StackMapAttribute
+	extends ClassFileAttribute
+	implements IStackMapAttribute {
+
+	private static final IStackMapFrame[] NO_FRAMES = new IStackMapFrame[0];
+	private static final byte[] NO_ENTRIES = new byte[0];
+
+	private int numberOfEntries;
+	private IStackMapFrame[] frames;
+
+	private byte[] bytes;
+
+	/**
+	 * Constructor for LineNumberAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public StackMapAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset)
+			throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+
+		final int length = u2At(classFileBytes, 6, offset);
+		this.numberOfEntries = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.frames = new IStackMapFrame[length];
+			for (int i = 0; i < length; i++) {
+				DefaultStackMapFrame frame = new DefaultStackMapFrame(classFileBytes, constantPool, offset + readOffset);
+				this.frames[i] = frame;
+				readOffset += frame.sizeInBytes();
+			}
+		} else {
+			this.frames = NO_FRAMES;
+		}
+		final int byteLength = (int) u4At(classFileBytes, 2, offset);
+
+		if (length != 0) {
+			System.arraycopy(classFileBytes, offset + 6, this.bytes = new byte[byteLength], 0, byteLength);
+		} else {
+			this.bytes = NO_ENTRIES;
+		}
+	}
+
+	public int getNumberOfEntries() {
+		return this.numberOfEntries;
+	}
+
+	public IStackMapFrame[] getStackMapFrame() {
+		return this.frames;
+	}
+
+	/**
+	 */
+	public byte[] getBytes() {
+		return this.bytes;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapFrame.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapFrame.java
new file mode 100644
index 0000000..10dcf8e
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapFrame.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IStackMapFrame;
+import org.eclipse.jdt.core.util.IVerificationTypeInfo;
+
+/**
+ * Default implementation of IStackMapFrame
+ */
+public class StackMapFrame extends ClassFileStruct implements IStackMapFrame {
+	private static final IVerificationTypeInfo[] EMPTY_LOCALS_OR_STACK_ITEMS = new IVerificationTypeInfo[0];
+
+	private int readOffset;
+	private int frameType;
+	private int numberOfLocals;
+	private int numberOfStackItems;
+	private IVerificationTypeInfo[] locals;
+	private IVerificationTypeInfo[] stackItems;
+	private int offsetDelta;
+
+	/**
+	 * Constructor for StackMapFrame.
+	 *
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public StackMapFrame(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+
+		final int type = u1At(classFileBytes, 0, offset);
+		this.frameType = type;
+		switch(type) {
+			case 247 : // SAME_LOCALS_1_STACK_ITEM_EXTENDED
+				this.offsetDelta = u2At(classFileBytes, 1, offset);
+				this.numberOfStackItems = 1;
+				this.stackItems = new VerificationInfo[1];
+				this.readOffset = 3;
+				VerificationInfo info = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+				this.stackItems[0] = info;
+				this.readOffset += info.sizeInBytes();
+				this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.numberOfLocals = 0;
+				break;
+			case 248 :
+			case 249 :
+			case 250:
+				// CHOP
+				this.offsetDelta = u2At(classFileBytes, 1, offset);
+				this.numberOfStackItems = 0;
+				this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.readOffset = 3;
+				this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.numberOfLocals = 0;
+				break;
+			case 251 :
+				// SAME_FRAME_EXTENDED
+				this.offsetDelta = u2At(classFileBytes, 1, offset);
+				this.numberOfStackItems = 0;
+				this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.readOffset = 3;
+				this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.numberOfLocals = 0;
+				break;
+			case 252 :
+			case 253 :
+			case 254 :
+				// APPEND
+				this.offsetDelta = u2At(classFileBytes, 1, offset);
+				this.numberOfStackItems = 0;
+				this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+				this.readOffset = 3;
+				int diffLocals = type - 251;
+				this.numberOfLocals = diffLocals;
+				this.locals = new IVerificationTypeInfo[diffLocals];
+				for (int i = 0; i < diffLocals; i++) {
+					VerificationInfo verificationInfo = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+					this.locals[i] = verificationInfo;
+					this.readOffset += verificationInfo.sizeInBytes();
+				}
+				break;
+			case 255 :
+				// FULL_FRAME
+				this.offsetDelta = u2At(classFileBytes, 1, offset);
+				int tempLocals = u2At(classFileBytes, 3, offset);
+				this.numberOfLocals = tempLocals;
+				this.readOffset = 5;
+				if (tempLocals != 0) {
+					this.locals = new IVerificationTypeInfo[tempLocals];
+					for (int i = 0; i < tempLocals; i++) {
+						VerificationInfo verificationInfo = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+						this.locals[i] = verificationInfo;
+						this.readOffset += verificationInfo.sizeInBytes();
+					}
+				} else {
+					this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+				}
+				int tempStackItems = u2At(classFileBytes, this.readOffset, offset);
+				this.readOffset += 2;
+				this.numberOfStackItems = tempStackItems;
+				if (tempStackItems != 0) {
+					this.stackItems = new IVerificationTypeInfo[tempStackItems];
+					for (int i = 0; i < tempStackItems; i++) {
+						VerificationInfo verificationInfo = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+						this.stackItems[i] = verificationInfo;
+						this.readOffset += verificationInfo.sizeInBytes();
+					}
+				} else {
+					this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+				}
+				break;
+			default:
+				if (type <= 63) {
+					// SAME_FRAME
+					this.offsetDelta = type;
+					this.numberOfStackItems = 0;
+					this.stackItems = EMPTY_LOCALS_OR_STACK_ITEMS;
+					this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+					this.numberOfLocals = 0;
+					this.readOffset = 1;
+				} else if (type <= 127) {
+					// SAME_LOCALS_1_STACK_ITEM
+					this.offsetDelta = type - 64;
+					this.numberOfStackItems = 1;
+					this.stackItems = new VerificationInfo[1];
+					this.readOffset = 1;
+					info = new VerificationInfo(classFileBytes, constantPool, offset + this.readOffset);
+					this.stackItems[0] = info;
+					this.readOffset += info.sizeInBytes();
+					this.locals = EMPTY_LOCALS_OR_STACK_ITEMS;
+					this.numberOfLocals = 0;
+				}
+		}
+	}
+	int sizeInBytes() {
+		return this.readOffset;
+	}
+	public int getFrameType() {
+		return this.frameType;
+	}
+	public IVerificationTypeInfo[] getLocals() {
+		return this.locals;
+	}
+	public int getNumberOfLocals() {
+		return this.numberOfLocals;
+	}
+	public int getNumberOfStackItems() {
+		return this.numberOfStackItems;
+	}
+	public int getOffsetDelta() {
+		return this.offsetDelta;
+	}
+	public IVerificationTypeInfo[] getStackItems() {
+		return this.stackItems;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapTableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapTableAttribute.java
new file mode 100644
index 0000000..b14f422
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/StackMapTableAttribute.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IStackMapFrame;
+import org.eclipse.jdt.core.util.IStackMapTableAttribute;
+/**
+ * Default implementation of IStackMapTableAttribute.
+ * @see IStackMapTableAttribute
+ */
+public class StackMapTableAttribute
+	extends ClassFileAttribute
+	implements IStackMapTableAttribute {
+
+	private static final IStackMapFrame[] NO_FRAMES = new IStackMapFrame[0];
+	private static final byte[] NO_ENTRIES = new byte[0];
+
+	private int numberOfEntries;
+	private IStackMapFrame[] frames;
+
+	private byte[] bytes;
+
+	/**
+	 * Constructor for LineNumberAttribute.
+	 * @param classFileBytes
+	 * @param constantPool
+	 * @param offset
+	 * @throws ClassFormatException
+	 */
+	public StackMapTableAttribute(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset)
+			throws ClassFormatException {
+		super(classFileBytes, constantPool, offset);
+
+		final int length = u2At(classFileBytes, 6, offset);
+		this.numberOfEntries = length;
+		if (length != 0) {
+			int readOffset = 8;
+			this.frames = new IStackMapFrame[length];
+			for (int i = 0; i < length; i++) {
+				StackMapFrame frame = new StackMapFrame(classFileBytes, constantPool, offset + readOffset);
+				this.frames[i] = frame;
+				readOffset += frame.sizeInBytes();
+			}
+		} else {
+			this.frames = NO_FRAMES;
+		}
+		final int byteLength = (int) u4At(classFileBytes, 2, offset);
+
+		if (length != 0) {
+			System.arraycopy(classFileBytes, offset + 6, this.bytes = new byte[byteLength], 0, byteLength);
+		} else {
+			this.bytes = NO_ENTRIES;
+		}
+	}
+
+	public int getNumberOfEntries() {
+		return this.numberOfEntries;
+	}
+
+	public IStackMapFrame[] getStackMapFrame() {
+		return this.frames;
+	}
+
+	/**
+	 */
+	public byte[] getBytes() {
+		return this.bytes;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java
new file mode 100644
index 0000000..b115ce6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+/**
+ * The SortOperation takes a collection of objects and returns
+ * a sorted collection of these objects. The sorting of these
+ * objects is based on their toString(). They are sorted in
+ * alphabetical order.
+ */
+public class ToStringSorter {
+	Object[] sortedObjects;
+	String[] sortedStrings;
+/**
+ *  Returns true if stringTwo is 'greater than' stringOne
+ *  This is the 'ordering' method of the sort operation.
+ */
+public boolean compare(String stringOne, String stringTwo) {
+	return stringOne.compareTo(stringTwo) < 0;
+}
+/**
+ *  Sort the objects in sorted collection and return that collection.
+ */
+private void quickSort(int left, int right) {
+	int originalLeft = left;
+	int originalRight = right;
+	int midIndex =  left + (right - left) / 2;
+	String midToString = this.sortedStrings[midIndex];
+
+	do {
+		while (compare(this.sortedStrings[left], midToString))
+			left++;
+		while (compare(midToString, this.sortedStrings[right]))
+			right--;
+		if (left <= right) {
+			Object tmp = this.sortedObjects[left];
+			this.sortedObjects[left] = this.sortedObjects[right];
+			this.sortedObjects[right] = tmp;
+			String tmpToString = this.sortedStrings[left];
+			this.sortedStrings[left] = this.sortedStrings[right];
+			this.sortedStrings[right] = tmpToString;
+			left++;
+			right--;
+		}
+	} while (left <= right);
+
+	if (originalLeft < right)
+		quickSort(originalLeft, right);
+	if (left < originalRight)
+		quickSort(left, originalRight);
+}
+/**
+ *  Return a new sorted collection from this unsorted collection.
+ *  Sort using quick sort.
+ */
+public void sort(Object[] unSortedObjects, String[] unsortedStrings) {
+	int size = unSortedObjects.length;
+	this.sortedObjects = new Object[size];
+	this.sortedStrings = new String[size];
+
+	//copy the array so can return a new sorted collection
+	System.arraycopy(unSortedObjects, 0, this.sortedObjects, 0, size);
+	System.arraycopy(unsortedStrings, 0, this.sortedStrings, 0, size);
+	if (size > 1)
+		quickSort(0, size - 1);
+}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
new file mode 100644
index 0000000..304724f
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
@@ -0,0 +1,3315 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.QualifiedType;
+import org.eclipse.jdt.core.dom.SimpleType;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.WildcardType;
+import org.eclipse.jdt.core.util.IClassFileAttribute;
+import org.eclipse.jdt.core.util.IClassFileReader;
+import org.eclipse.jdt.core.util.ICodeAttribute;
+import org.eclipse.jdt.core.util.IFieldInfo;
+import org.eclipse.jdt.core.util.IMethodInfo;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.ClassSignature;
+import org.eclipse.jdt.internal.compiler.env.EnumConstantSignature;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IDependent;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.Annotation;
+import org.eclipse.jdt.internal.core.ClassFile;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.Member;
+import org.eclipse.jdt.internal.core.MemberValuePair;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+/**
+ * Provides convenient utility methods to other types in this package.
+ */
+public class Util {
+
+	public interface Comparable {
+		/**
+		 * Returns 0 if this and c are equal, >0 if this is greater than c,
+		 * or <0 if this is less than c.
+		 */
+		int compareTo(Comparable c);
+	}
+
+	public interface Comparer {
+		/**
+		 * Returns 0 if a and b are equal, >0 if a is greater than b,
+		 * or <0 if a is less than b.
+		 */
+		int compare(Object a, Object b);
+	}
+
+	public static interface BindingsToNodesMap {
+		public org.eclipse.jdt.internal.compiler.ast.ASTNode get(Binding binding);
+	}
+
+	private static final char ARGUMENTS_DELIMITER = '#';
+
+	private static final String EMPTY_ARGUMENT = "   "; //$NON-NLS-1$
+
+	private static char[][] JAVA_LIKE_EXTENSIONS;
+
+	private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
+	private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
+	private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
+	private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
+	private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
+	private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
+	private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
+	private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
+	private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+	private static final char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
+
+	private static final String TASK_PRIORITIES_PROBLEM = "TASK_PRIORITIES_PB"; //$NON-NLS-1$
+	private static List fgRepeatedMessages= new ArrayList(5);
+
+	private Util() {
+		// cannot be instantiated
+	}
+
+	/**
+	 * Returns a new array adding the second array at the end of first array.
+	 * It answers null if the first and second are null.
+	 * If the first array is null or if it is empty, then a new array is created with second.
+	 * If the second array is null, then the first array is returned.
+	 * <br>
+	 * <br>
+	 * For example:
+	 * <ol>
+	 * <li><pre>
+	 *    first = null
+	 *    second = "a"
+	 *    => result = {"a"}
+	 * </pre>
+	 * <li><pre>
+	 *    first = {"a"}
+	 *    second = null
+	 *    => result = {"a"}
+	 * </pre>
+	 * </li>
+	 * <li><pre>
+	 *    first = {"a"}
+	 *    second = {"b"}
+	 *    => result = {"a", "b"}
+	 * </pre>
+	 * </li>
+	 * </ol>
+	 *
+	 * @param first the first array to concatenate
+	 * @param second the array to add at the end of the first array
+	 * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
+	 */
+	public static final String[] arrayConcat(String[] first, String second) {
+		if (second == null)
+			return first;
+		if (first == null)
+			return new String[] {second};
+
+		int length = first.length;
+		if (first.length == 0) {
+			return new String[] {second};
+		}
+
+		String[] result = new String[length + 1];
+		System.arraycopy(first, 0, result, 0, length);
+		result[length] = second;
+		return result;
+	}
+
+	/**
+	 * Checks the type signature in String sig,
+	 * starting at start and ending before end (end is not included).
+	 * Returns the index of the character immediately after the signature if valid,
+	 * or -1 if not valid.
+	 */
+	private static int checkTypeSignature(String sig, int start, int end, boolean allowVoid) {
+		if (start >= end) return -1;
+		int i = start;
+		char c = sig.charAt(i++);
+		int nestingDepth = 0;
+		while (c == '[') {
+			++nestingDepth;
+			if (i >= end) return -1;
+			c = sig.charAt(i++);
+		}
+		switch (c) {
+			case 'B':
+			case 'C':
+			case 'D':
+			case 'F':
+			case 'I':
+			case 'J':
+			case 'S':
+			case 'Z':
+				break;
+			case 'V':
+				if (!allowVoid) return -1;
+				// array of void is not allowed
+				if (nestingDepth != 0) return -1;
+				break;
+			case 'L':
+				int semicolon = sig.indexOf(';', i);
+				// Must have at least one character between L and ;
+				if (semicolon <= i || semicolon >= end) return -1;
+				i = semicolon + 1;
+				break;
+			default:
+				return -1;
+		}
+		return i;
+	}
+
+	/**
+	 * Combines two hash codes to make a new one.
+	 */
+	public static int combineHashCodes(int hashCode1, int hashCode2) {
+		return hashCode1 * 17 + hashCode2;
+	}
+
+	/**
+	 * Compares two byte arrays.
+	 * Returns <0 if a byte in a is less than the corresponding byte in b, or if a is shorter, or if a is null.
+	 * Returns >0 if a byte in a is greater than the corresponding byte in b, or if a is longer, or if b is null.
+	 * Returns 0 if they are equal or both null.
+	 */
+	public static int compare(byte[] a, byte[] b) {
+		if (a == b)
+			return 0;
+		if (a == null)
+			return -1;
+		if (b == null)
+			return 1;
+		int len = Math.min(a.length, b.length);
+		for (int i = 0; i < len; ++i) {
+			int diff = a[i] - b[i];
+			if (diff != 0)
+				return diff;
+		}
+		if (a.length > len)
+			return 1;
+		if (b.length > len)
+			return -1;
+		return 0;
+	}
+	/**
+	 * Compares two strings lexicographically.
+	 * The comparison is based on the Unicode value of each character in
+	 * the strings.
+	 *
+	 * @return  the value <code>0</code> if the str1 is equal to str2;
+	 *          a value less than <code>0</code> if str1
+	 *          is lexicographically less than str2;
+	 *          and a value greater than <code>0</code> if str1 is
+	 *          lexicographically greater than str2.
+	 */
+	public static int compare(char[] str1, char[] str2) {
+		int len1= str1.length;
+		int len2= str2.length;
+		int n= Math.min(len1, len2);
+		int i= 0;
+		while (n-- != 0) {
+			char c1= str1[i];
+			char c2= str2[i++];
+			if (c1 != c2) {
+				return c1 - c2;
+			}
+		}
+		return len1 - len2;
+	}
+	/**
+	 * Concatenate a String[] compound name to a continuous char[].
+	 */
+	public static char[] concatCompoundNameToCharArray(String[] compoundName) {
+		if (compoundName == null) return null;
+		int length = compoundName.length;
+		if (length == 0) return new char[0];
+		int size = 0;
+		for (int i=0; i<length; i++) {
+			size += compoundName[i].length();
+		}
+		char[] compoundChars = new char[size+length-1];
+		int pos = 0;
+		for (int i=0; i<length; i++) {
+			String name = compoundName[i];
+			if (i > 0) compoundChars[pos++] = '.';
+			int nameLength = name.length();
+			name.getChars(0, nameLength, compoundChars, pos);
+			pos += nameLength;
+		}
+		return compoundChars;
+	}
+	public static String concatenateName(String name1, String name2, char separator) {
+		StringBuffer buf= new StringBuffer();
+		if (name1 != null && name1.length() > 0) {
+			buf.append(name1);
+		}
+		if (name2 != null && name2.length() > 0) {
+			if (buf.length() > 0) {
+				buf.append(separator);
+			}
+			buf.append(name2);
+		}
+		return buf.toString();
+	}
+	/**
+	 * Returns the concatenation of the given array parts using the given separator between each part.
+	 * <br>
+	 * <br>
+	 * For example:<br>
+	 * <ol>
+	 * <li><pre>
+	 *    array = {"a", "b"}
+	 *    separator = '.'
+	 *    => result = "a.b"
+	 * </pre>
+	 * </li>
+	 * <li><pre>
+	 *    array = {}
+	 *    separator = '.'
+	 *    => result = ""
+	 * </pre></li>
+	 * </ol>
+	 *
+	 * @param array the given array
+	 * @param separator the given separator
+	 * @return the concatenation of the given array parts using the given separator between each part
+	 */
+	public static final String concatWith(String[] array, char separator) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, length = array.length; i < length; i++) {
+			buffer.append(array[i]);
+			if (i < length - 1)
+				buffer.append(separator);
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * Returns the concatenation of the given array parts using the given separator between each
+	 * part and appending the given name at the end.
+	 * <br>
+	 * <br>
+	 * For example:<br>
+	 * <ol>
+	 * <li><pre>
+	 *    name = "c"
+	 *    array = { "a", "b" }
+	 *    separator = '.'
+	 *    => result = "a.b.c"
+	 * </pre>
+	 * </li>
+	 * <li><pre>
+	 *    name = null
+	 *    array = { "a", "b" }
+	 *    separator = '.'
+	 *    => result = "a.b"
+	 * </pre></li>
+	 * <li><pre>
+	 *    name = " c"
+	 *    array = null
+	 *    separator = '.'
+	 *    => result = "c"
+	 * </pre></li>
+	 * </ol>
+	 *
+	 * @param array the given array
+	 * @param name the given name
+	 * @param separator the given separator
+	 * @return the concatenation of the given array parts using the given separator between each
+	 * part and appending the given name at the end
+	 */
+	public static final String concatWith(
+		String[] array,
+		String name,
+		char separator) {
+
+		if (array == null || array.length == 0) return name;
+		if (name == null || name.length() == 0) return concatWith(array, separator);
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, length = array.length; i < length; i++) {
+			buffer.append(array[i]);
+			buffer.append(separator);
+		}
+		buffer.append(name);
+		return buffer.toString();
+
+	}
+	/**
+	 * Converts a type signature from the IBinaryType representation to the DC representation.
+	 */
+	public static String convertTypeSignature(char[] sig, int start, int length) {
+		return new String(sig, start, length).replace('/', '.');
+	}
+
+	/*
+	 * Returns the default java extension (".java").
+	 * To be used when the extension is not known.
+	 */
+	public static String defaultJavaExtension() {
+		return SuffixConstants.SUFFIX_STRING_java;
+	}
+
+	/**
+	 * Apply the given edit on the given string and return the updated string.
+	 * Return the given string if anything wrong happen while applying the edit.
+	 *
+	 * @param original the given string
+	 * @param edit the given edit
+	 *
+	 * @return the updated string
+	 */
+	public final static String editedString(String original, TextEdit edit) {
+		if (edit == null) {
+			return original;
+		}
+		SimpleDocument document = new SimpleDocument(original);
+		try {
+			edit.apply(document, TextEdit.NONE);
+			return document.get();
+		} catch (MalformedTreeException e) {
+			e.printStackTrace();
+		} catch (BadLocationException e) {
+			e.printStackTrace();
+		}
+		return original;
+	}
+
+	/**
+	 * Returns true iff str.toLowerCase().endsWith(end.toLowerCase())
+	 * implementation is not creating extra strings.
+	 */
+	public final static boolean endsWithIgnoreCase(String str, String end) {
+
+		int strLength = str == null ? 0 : str.length();
+		int endLength = end == null ? 0 : end.length();
+
+		// return false if the string is smaller than the end.
+		if(endLength > strLength)
+			return false;
+
+		// return false if any character of the end are
+		// not the same in lower case.
+		for(int i = 1 ; i <= endLength; i++){
+			if(ScannerHelper.toLowerCase(end.charAt(endLength - i)) != ScannerHelper.toLowerCase(str.charAt(strLength - i)))
+				return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Compares two arrays using equals() on the elements.
+	 * Neither can be null. Only the first len elements are compared.
+	 * Return false if either array is shorter than len.
+	 */
+	public static boolean equalArrays(Object[] a, Object[] b, int len) {
+		if (a == b)	return true;
+		if (a.length < len || b.length < len) return false;
+		for (int i = 0; i < len; ++i) {
+			if (a[i] == null) {
+				if (b[i] != null) return false;
+			} else {
+				if (!a[i].equals(b[i])) return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Compares two arrays using equals() on the elements.
+	 * Either or both arrays may be null.
+	 * Returns true if both are null.
+	 * Returns false if only one is null.
+	 * If both are arrays, returns true iff they have the same length and
+	 * all elements are equal.
+	 */
+	public static boolean equalArraysOrNull(int[] a, int[] b) {
+		if (a == b)
+			return true;
+		if (a == null || b == null)
+			return false;
+		int len = a.length;
+		if (len != b.length)
+			return false;
+		for (int i = 0; i < len; ++i) {
+			if (a[i] != b[i])
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Compares two arrays using equals() on the elements.
+	 * Either or both arrays may be null.
+	 * Returns true if both are null.
+	 * Returns false if only one is null.
+	 * If both are arrays, returns true iff they have the same length and
+	 * all elements compare true with equals.
+	 */
+	public static boolean equalArraysOrNull(Object[] a, Object[] b) {
+		if (a == b)	return true;
+		if (a == null || b == null) return false;
+
+		int len = a.length;
+		if (len != b.length) return false;
+		// walk array from end to beginning as this optimizes package name cases
+		// where the first part is always the same (e.g. org.eclipse.jdt)
+		for (int i = len-1; i >= 0; i--) {
+			if (a[i] == null) {
+				if (b[i] != null) return false;
+			} else {
+				if (!a[i].equals(b[i])) return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Compares two arrays using equals() on the elements.
+	 * The arrays are first sorted.
+	 * Either or both arrays may be null.
+	 * Returns true if both are null.
+	 * Returns false if only one is null.
+	 * If both are arrays, returns true iff they have the same length and
+	 * iff, after sorting both arrays, all elements compare true with equals.
+	 * The original arrays are left untouched.
+	 */
+	public static boolean equalArraysOrNullSortFirst(Comparable[] a, Comparable[] b) {
+		if (a == b)	return true;
+		if (a == null || b == null) return false;
+		int len = a.length;
+		if (len != b.length) return false;
+		if (len >= 2) {  // only need to sort if more than two items
+			a = sortCopy(a);
+			b = sortCopy(b);
+		}
+		for (int i = 0; i < len; ++i) {
+			if (!a[i].equals(b[i])) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Compares two String arrays using equals() on the elements.
+	 * The arrays are first sorted.
+	 * Either or both arrays may be null.
+	 * Returns true if both are null.
+	 * Returns false if only one is null.
+	 * If both are arrays, returns true iff they have the same length and
+	 * iff, after sorting both arrays, all elements compare true with equals.
+	 * The original arrays are left untouched.
+	 */
+	public static boolean equalArraysOrNullSortFirst(String[] a, String[] b) {
+		if (a == b)	return true;
+		if (a == null || b == null) return false;
+		int len = a.length;
+		if (len != b.length) return false;
+		if (len >= 2) {  // only need to sort if more than two items
+			a = sortCopy(a);
+			b = sortCopy(b);
+		}
+		for (int i = 0; i < len; ++i) {
+			if (!a[i].equals(b[i])) return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Compares two objects using equals().
+	 * Either or both array may be null.
+	 * Returns true if both are null.
+	 * Returns false if only one is null.
+	 * Otherwise, return the result of comparing with equals().
+	 */
+	public static boolean equalOrNull(Object a, Object b) {
+		if (a == b) {
+			return true;
+		}
+		if (a == null || b == null) {
+			return false;
+		}
+		return a.equals(b);
+	}
+
+	/*
+	 * Returns whether the given file name equals to the given string ignoring the java like extension
+	 * of the file name.
+	 * Returns false if it is not a java like file name.
+	 */
+	public static boolean equalsIgnoreJavaLikeExtension(String fileName, String string) {
+		int fileNameLength = fileName.length();
+		int stringLength = string.length();
+		if (fileNameLength < stringLength) return false;
+		for (int i = 0; i < stringLength; i ++) {
+			if (fileName.charAt(i) != string.charAt(i)) {
+				return false;
+			}
+		}
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		suffixes: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] suffix = javaLikeExtensions[i];
+			int extensionStart = stringLength+1;
+			if (extensionStart + suffix.length != fileNameLength) continue;
+			if (fileName.charAt(stringLength) != '.') continue;
+			for (int j = extensionStart; j < fileNameLength; j++) {
+				if (fileName.charAt(j) != suffix[j-extensionStart])
+					continue suffixes;
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Given a qualified name, extract the last component.
+	 * If the input is not qualified, the same string is answered.
+	 */
+	public static String extractLastName(String qualifiedName) {
+		int i = qualifiedName.lastIndexOf('.');
+		if (i == -1) return qualifiedName;
+		return qualifiedName.substring(i+1);
+	}
+
+	/**
+	 * Extracts the parameter types from a method signature.
+	 */
+	public static String[] extractParameterTypes(char[] sig) {
+		int count = getParameterCount(sig);
+		String[] result = new String[count];
+		if (count == 0)
+			return result;
+		int i = CharOperation.indexOf('(', sig) + 1;
+		count = 0;
+		int len = sig.length;
+		int start = i;
+		for (;;) {
+			if (i == len)
+				break;
+			char c = sig[i];
+			if (c == ')')
+				break;
+			if (c == '[') {
+				++i;
+			} else
+				if (c == 'L') {
+					i = CharOperation.indexOf(';', sig, i + 1) + 1;
+					Assert.isTrue(i != 0);
+					result[count++] = convertTypeSignature(sig, start, i - start);
+					start = i;
+				} else {
+					++i;
+					result[count++] = convertTypeSignature(sig, start, i - start);
+					start = i;
+				}
+		}
+		return result;
+	}
+
+	/**
+	 * Extracts the return type from a method signature.
+	 */
+	public static String extractReturnType(String sig) {
+		int i = sig.lastIndexOf(')');
+		Assert.isTrue(i != -1);
+		return sig.substring(i+1);
+	}
+	private static IFile findFirstClassFile(IFolder folder) {
+		try {
+			IResource[] members = folder.members();
+			for (int i = 0, max = members.length; i < max; i++) {
+				IResource member = members[i];
+				if (member.getType() == IResource.FOLDER) {
+					return findFirstClassFile((IFolder)member);
+				} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(member.getName())) {
+					return (IFile) member;
+				}
+			}
+		} catch (CoreException e) {
+			// ignore
+		}
+		return null;
+	}
+
+	/**
+	 * Finds the first line separator used by the given text.
+	 *
+	 * @return </code>"\n"</code> or </code>"\r"</code> or  </code>"\r\n"</code>,
+	 *			or <code>null</code> if none found
+	 */
+	public static String findLineSeparator(char[] text) {
+		// find the first line separator
+		int length = text.length;
+		if (length > 0) {
+			char nextChar = text[0];
+			for (int i = 0; i < length; i++) {
+				char currentChar = nextChar;
+				nextChar = i < length-1 ? text[i+1] : ' ';
+				switch (currentChar) {
+					case '\n': return "\n"; //$NON-NLS-1$
+					case '\r': return nextChar == '\n' ? "\r\n" : "\r"; //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		}
+		// not found
+		return null;
+	}
+
+	public static IClassFileAttribute getAttribute(IClassFileReader classFileReader, char[] attributeName) {
+		IClassFileAttribute[] attributes = classFileReader.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), attributeName)) {
+				return attributes[i];
+			}
+		}
+		return null;
+	}
+
+	public static IClassFileAttribute getAttribute(ICodeAttribute codeAttribute, char[] attributeName) {
+		IClassFileAttribute[] attributes = codeAttribute.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), attributeName)) {
+				return attributes[i];
+			}
+		}
+		return null;
+	}
+
+	public static IClassFileAttribute getAttribute(IFieldInfo fieldInfo, char[] attributeName) {
+		IClassFileAttribute[] attributes = fieldInfo.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), attributeName)) {
+				return attributes[i];
+			}
+		}
+		return null;
+	}
+
+	public static IClassFileAttribute getAttribute(IMethodInfo methodInfo, char[] attributeName) {
+		IClassFileAttribute[] attributes = methodInfo.getAttributes();
+		for (int i = 0, max = attributes.length; i < max; i++) {
+			if (CharOperation.equals(attributes[i].getAttributeName(), attributeName)) {
+				return attributes[i];
+			}
+		}
+		return null;
+	}
+
+	private static IClassFile getClassFile(char[] fileName) {
+		int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName);
+		int pkgEnd = CharOperation.lastIndexOf('/', fileName); // pkgEnd is exclusive
+		if (pkgEnd == -1)
+			pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName);
+		if (jarSeparator != -1 && pkgEnd < jarSeparator) // if in a jar and no slash, it is a default package -> pkgEnd should be equal to jarSeparator
+			pkgEnd = jarSeparator;
+		if (pkgEnd == -1)
+			return null;
+		IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator);
+		if (pkg == null) return null;
+		int start;
+		return pkg.getClassFile(new String(fileName, start = pkgEnd + 1, fileName.length - start));
+	}
+
+	private static ICompilationUnit getCompilationUnit(char[] fileName, WorkingCopyOwner workingCopyOwner) {
+		char[] slashSeparatedFileName = CharOperation.replaceOnCopy(fileName, File.separatorChar, '/');
+		int pkgEnd = CharOperation.lastIndexOf('/', slashSeparatedFileName); // pkgEnd is exclusive
+		if (pkgEnd == -1)
+			return null;
+		IPackageFragment pkg = getPackageFragment(slashSeparatedFileName, pkgEnd, -1/*no jar separator for .java files*/);
+		if (pkg == null) return null;
+		int start;
+		ICompilationUnit cu = pkg.getCompilationUnit(new String(slashSeparatedFileName, start =  pkgEnd+1, slashSeparatedFileName.length - start));
+		if (workingCopyOwner != null) {
+			ICompilationUnit workingCopy = cu.findWorkingCopy(workingCopyOwner);
+			if (workingCopy != null)
+				return workingCopy;
+		}
+		return cu;
+	}
+
+	/**
+	 * Returns the registered Java like extensions.
+	 */
+	public static char[][] getJavaLikeExtensions() {
+		if (JAVA_LIKE_EXTENSIONS == null) {
+			IContentType javaContentType = Platform.getContentTypeManager().getContentType(JavaCore.JAVA_SOURCE_CONTENT_TYPE);
+			HashSet fileExtensions = new HashSet();
+			// content types derived from java content type should be included (https://bugs.eclipse.org/bugs/show_bug.cgi?id=121715)
+			IContentType[] contentTypes = Platform.getContentTypeManager().getAllContentTypes();
+			for (int i = 0, length = contentTypes.length; i < length; i++) {
+				if (contentTypes[i].isKindOf(javaContentType)) { // note that javaContentType.isKindOf(javaContentType) == true
+					String[] fileExtension = contentTypes[i].getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+					for (int j = 0, length2 = fileExtension.length; j < length2; j++) {
+						fileExtensions.add(fileExtension[j]);
+					}
+				}
+			}
+			int length = fileExtensions.size();
+			// note that file extensions contains "java" as it is defined in JDT Core's plugin.xml
+			char[][] extensions = new char[length][];
+			extensions[0] = SuffixConstants.EXTENSION_java.toCharArray(); // ensure that "java" is first
+			int index = 1;
+			Iterator iterator = fileExtensions.iterator();
+			while (iterator.hasNext()) {
+				String fileExtension = (String) iterator.next();
+				if (SuffixConstants.EXTENSION_java.equals(fileExtension))
+					continue;
+				extensions[index++] = fileExtension.toCharArray();
+			}
+			JAVA_LIKE_EXTENSIONS = extensions;
+		}
+		return JAVA_LIKE_EXTENSIONS;
+	}
+	/**
+	 * Get the jdk level of this root.
+	 * The value can be:
+	 * <ul>
+	 * <li>major<<16 + minor : see predefined constants on ClassFileConstants </li>
+	 * <li><code>0</null> if the root is a source package fragment root or if a Java model exception occured</li>
+	 * </ul>
+	 * Returns the jdk level
+	 */
+	public static long getJdkLevel(Object targetLibrary) {
+		try {
+			ClassFileReader reader = null;
+			if (targetLibrary instanceof IFolder) {
+				IFile classFile = findFirstClassFile((IFolder) targetLibrary); // only internal classfolders are allowed
+				if (classFile != null)
+					reader = Util.newClassFileReader(classFile);
+			} else {
+				// root is a jar file or a zip file
+				ZipFile jar = null;
+				try {
+					IPath path = null;
+					if (targetLibrary instanceof IResource) {
+						path = ((IResource)targetLibrary).getFullPath();
+					} else if (targetLibrary instanceof File){
+						File f = (File) targetLibrary;
+						if (!f.isDirectory()) {
+							path = new Path(((File)targetLibrary).getPath());
+						}
+					}
+					if (path != null) {
+						jar = JavaModelManager.getJavaModelManager().getZipFile(path);
+						for (Enumeration e= jar.entries(); e.hasMoreElements();) {
+							ZipEntry member= (ZipEntry) e.nextElement();
+							String entryName= member.getName();
+							if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(entryName)) {
+								reader = ClassFileReader.read(jar, entryName);
+								break;
+							}
+						}
+					}
+				} catch (CoreException e) {
+					// ignore
+				} finally {
+					JavaModelManager.getJavaModelManager().closeZipFile(jar);
+				}
+			}
+			if (reader != null) {
+				return reader.getVersion();
+			}
+		} catch (CoreException e) {
+			// ignore
+		} catch(ClassFormatException e) {
+			// ignore
+		} catch(IOException e) {
+			// ignore
+		}
+		return 0;
+	}
+
+	/**
+	 * Returns the substring of the given file name, ending at the start of a
+	 * Java like extension. The entire file name is returned if it doesn't end
+	 * with a Java like extension.
+	 */
+	public static String getNameWithoutJavaLikeExtension(String fileName) {
+		int index = indexOfJavaLikeExtension(fileName);
+		if (index == -1)
+			return fileName;
+		return fileName.substring(0, index);
+	}
+
+	/**
+	 * Returns the line separator found in the given text.
+	 * If it is null, or not found return the line delimiter for the given project.
+	 * If the project is null, returns the line separator for the workspace.
+	 * If still null, return the system line separator.
+	 */
+	public static String getLineSeparator(String text, IJavaProject project) {
+		String lineSeparator = null;
+
+		// line delimiter in given text
+		if (text != null && text.length() != 0) {
+			lineSeparator = findLineSeparator(text.toCharArray());
+			if (lineSeparator != null)
+				return lineSeparator;
+		}
+
+		if (Platform.isRunning()) {
+			// line delimiter in project preference
+			IScopeContext[] scopeContext;
+			if (project != null) {
+				scopeContext= new IScopeContext[] { new ProjectScope(project.getProject()) };
+				lineSeparator= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
+				if (lineSeparator != null)
+					return lineSeparator;
+			}
+	
+			// line delimiter in workspace preference
+			scopeContext= new IScopeContext[] { InstanceScope.INSTANCE };
+			lineSeparator = Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
+			if (lineSeparator != null)
+				return lineSeparator;
+		}
+
+		// system line delimiter
+		return org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR;
+	}
+
+	/**
+	 * Returns the line separator used by the given buffer.
+	 * Uses the given text if none found.
+	 *
+	 * @return </code>"\n"</code> or </code>"\r"</code> or  </code>"\r\n"</code>
+	 */
+	private static String getLineSeparator(char[] text, char[] buffer) {
+		// search in this buffer's contents first
+		String lineSeparator = findLineSeparator(buffer);
+		if (lineSeparator == null) {
+			// search in the given text
+			lineSeparator = findLineSeparator(text);
+			if (lineSeparator == null) {
+				// default to system line separator
+				return getLineSeparator((String) null, (IJavaProject) null);
+			}
+		}
+		return lineSeparator;
+	}
+
+	public static IPackageFragment getPackageFragment(char[] fileName, int pkgEnd, int jarSeparator) {
+		if (jarSeparator != -1) {
+			String jarMemento = new String(fileName, 0, jarSeparator);
+			PackageFragmentRoot root = (PackageFragmentRoot) JavaCore.create(jarMemento);
+			if (pkgEnd == jarSeparator)
+				return root.getPackageFragment(CharOperation.NO_STRINGS);
+			char[] pkgName = CharOperation.subarray(fileName, jarSeparator+1, pkgEnd);
+			char[][] compoundName = CharOperation.splitOn('/', pkgName);
+			return root.getPackageFragment(CharOperation.toStrings(compoundName));
+		} else {
+			Path path = new Path(new String(fileName, 0, pkgEnd));
+			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+			IContainer folder = path.segmentCount() == 1 ? workspaceRoot.getProject(path.lastSegment()) : (IContainer) workspaceRoot.getFolder(path);
+			IJavaElement element = JavaCore.create(folder);
+			if (element == null) return null;
+			switch (element.getElementType()) {
+				case IJavaElement.PACKAGE_FRAGMENT:
+					return (IPackageFragment) element;
+				case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+					return ((PackageFragmentRoot) element).getPackageFragment(CharOperation.NO_STRINGS);
+				case IJavaElement.JAVA_PROJECT:
+					PackageFragmentRoot root = (PackageFragmentRoot) ((IJavaProject) element).getPackageFragmentRoot(folder);
+					if (root == null) return null;
+					return root.getPackageFragment(CharOperation.NO_STRINGS);
+			}
+			return null;
+		}
+	}
+
+	/**
+	 * Returns the number of parameter types in a method signature.
+	 */
+	public static int getParameterCount(char[] sig) {
+		int i = CharOperation.indexOf('(', sig) + 1;
+		Assert.isTrue(i != 0);
+		int count = 0;
+		int len = sig.length;
+		for (;;) {
+			if (i == len)
+				break;
+			char c = sig[i];
+			if (c == ')')
+				break;
+			if (c == '[') {
+				++i;
+			} else
+				if (c == 'L') {
+					++count;
+					i = CharOperation.indexOf(';', sig, i + 1) + 1;
+					Assert.isTrue(i != 0);
+				} else {
+					++count;
+					++i;
+				}
+		}
+		return count;
+	}
+
+	/**
+	 * Put all the arguments in one String.
+	 */
+	public static String getProblemArgumentsForMarker(String[] arguments){
+		StringBuffer args = new StringBuffer(10);
+
+		args.append(arguments.length);
+		args.append(':');
+
+
+		for (int j = 0; j < arguments.length; j++) {
+			if(j != 0)
+				args.append(ARGUMENTS_DELIMITER);
+
+			if(arguments[j].length() == 0) {
+				args.append(EMPTY_ARGUMENT);
+			} else {
+				encodeArgument(arguments[j], args);
+			}
+		}
+
+		return args.toString();
+	}
+
+	/**
+	 * Encode the argument by doubling the '#' if present into the argument value.
+	 * 
+	 * <p>This stores the encoded argument into the given buffer.</p>
+	 *
+	 * @param argument the given argument
+	 * @param buffer the buffer in which the encoded argument is stored
+	 */
+	private static void encodeArgument(String argument, StringBuffer buffer) {
+		for (int i = 0, max = argument.length(); i < max; i++) {
+			char charAt = argument.charAt(i);
+			switch(charAt) {
+				case ARGUMENTS_DELIMITER :
+					buffer.append(ARGUMENTS_DELIMITER).append(ARGUMENTS_DELIMITER);
+					break;
+				default:
+					buffer.append(charAt);
+			}
+		}
+	}
+
+	/**
+	 * Separate all the arguments of a String made by getProblemArgumentsForMarker
+	 */
+	public static String[] getProblemArgumentsFromMarker(String argumentsString){
+		if (argumentsString == null) {
+			return null;
+		}
+		int index = argumentsString.indexOf(':');
+		if(index == -1)
+			return null;
+
+		int length = argumentsString.length();
+		int numberOfArg = 0;
+		try{
+			numberOfArg = Integer.parseInt(argumentsString.substring(0 , index));
+		} catch (NumberFormatException e) {
+			return null;
+		}
+		argumentsString = argumentsString.substring(index + 1, length);
+
+		return decodeArgumentString(numberOfArg, argumentsString);
+	}
+
+	private static String[] decodeArgumentString(int length, String argumentsString) {
+		// decode the argumentString knowing that '#' is doubled if part of the argument value
+		if (length == 0) {
+			if (argumentsString.length() != 0) {
+				return null;
+			}
+			return CharOperation.NO_STRINGS;
+		}
+		String[] result = new String[length];
+		int count = 0;
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, max = argumentsString.length(); i < max; i++) {
+			char current = argumentsString.charAt(i);
+			switch(current) {
+				case ARGUMENTS_DELIMITER :
+					/* check the next character. If this is also ARGUMENTS_DELIMITER then only put one into the
+					 * decoded argument and proceed with the next character
+					 */
+					if ((i + 1) == max) {
+						return null;
+					}
+					char next = argumentsString.charAt(i + 1);
+					if (next == ARGUMENTS_DELIMITER) {
+						buffer.append(ARGUMENTS_DELIMITER);
+						i++; // proceed with the next character
+					} else {
+						// this means the current argument is over
+						String currentArgumentContents = String.valueOf(buffer);
+						if (EMPTY_ARGUMENT.equals(currentArgumentContents)) {
+							currentArgumentContents = org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING;
+						}
+						result[count++] = currentArgumentContents;
+						if (count > length) {
+							// too many elements - ill-formed
+							return null;
+						}
+						buffer.delete(0, buffer.length());
+					}
+					break;
+				default :
+					buffer.append(current);
+			}
+		}
+		// process last argument
+		String currentArgumentContents = String.valueOf(buffer);
+		if (EMPTY_ARGUMENT.equals(currentArgumentContents)) {
+			currentArgumentContents = org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING;
+		}
+		result[count++] = currentArgumentContents;
+		if (count > length) {
+			// too many elements - ill-formed
+			return null;
+		}
+		buffer.delete(0, buffer.length());
+		return result;
+	}
+
+	/**
+	 * Returns the given file's contents as a byte array.
+	 */
+	public static byte[] getResourceContentsAsByteArray(IFile file) throws JavaModelException {
+		InputStream stream= null;
+		try {
+			stream = file.getContents(true);
+		} catch (CoreException e) {
+			throw new JavaModelException(e);
+		}
+		try {
+			return org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsByteArray(stream, -1);
+		} catch (IOException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+		} finally {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+
+	/**
+	 * Returns the given file's contents as a character array.
+	 */
+	public static char[] getResourceContentsAsCharArray(IFile file) throws JavaModelException {
+		// Get encoding from file
+		String encoding;
+		try {
+			encoding = file.getCharset();
+		} catch(CoreException ce) {
+			// do not use any encoding
+			encoding = null;
+		}
+		return getResourceContentsAsCharArray(file, encoding);
+	}
+
+	public static char[] getResourceContentsAsCharArray(IFile file, String encoding) throws JavaModelException {
+		// Get file length
+		// workaround https://bugs.eclipse.org/bugs/show_bug.cgi?id=130736 by using java.io.File if possible
+		IPath location = file.getLocation();
+		long length;
+		if (location == null) {
+			// non local file
+			try {
+				URI locationURI = file.getLocationURI();
+				if (locationURI == null)
+					throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Messages.bind(Messages.file_notFound, file.getFullPath().toString())));
+				length = EFS.getStore(locationURI).fetchInfo().getLength();
+			} catch (CoreException e) {
+				throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST);
+			}
+		} else {
+			// local file
+			length = location.toFile().length();
+		}
+
+		// Get resource contents
+		InputStream stream= null;
+		try {
+			stream = file.getContents(true);
+		} catch (CoreException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST);
+		}
+		try {
+			return org.eclipse.jdt.internal.compiler.util.Util.getInputStreamAsCharArray(stream, (int) length, encoding);
+		} catch (IOException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+		} finally {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+
+	/*
+	 * Returns the signature of the given type.
+	 */
+	public static String getSignature(Type type) {
+		StringBuffer buffer = new StringBuffer();
+		getFullyQualifiedName(type, buffer);
+		return Signature.createTypeSignature(buffer.toString(), false/*not resolved in source*/);
+	}
+
+	/*
+	 * Returns the source attachment property for this package fragment root's path
+	 */
+	public static String getSourceAttachmentProperty(IPath path) throws JavaModelException {
+		Map rootPathToAttachments = JavaModelManager.getJavaModelManager().rootPathToAttachments;
+		String property = (String) rootPathToAttachments.get(path);
+		if (property == null) {
+			try {
+				property = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(getSourceAttachmentPropertyName(path));
+				if (property == null) {
+					rootPathToAttachments.put(path, PackageFragmentRoot.NO_SOURCE_ATTACHMENT);
+					return null;
+				}
+				rootPathToAttachments.put(path, property);
+				return property;
+			} catch (CoreException e)  {
+				throw new JavaModelException(e);
+			}
+		} else if (property.equals(PackageFragmentRoot.NO_SOURCE_ATTACHMENT)) {
+			return null;
+		} else
+			return property;
+	}
+
+	private static QualifiedName getSourceAttachmentPropertyName(IPath path) {
+		return new QualifiedName(JavaCore.PLUGIN_ID, "sourceattachment: " + path.toOSString()); //$NON-NLS-1$
+	}
+
+	public static void setSourceAttachmentProperty(IPath path, String property) {
+		if (property == null) {
+			JavaModelManager.getJavaModelManager().rootPathToAttachments.put(path, PackageFragmentRoot.NO_SOURCE_ATTACHMENT);
+		} else {
+			JavaModelManager.getJavaModelManager().rootPathToAttachments.put(path, property);
+		}
+		try {
+			ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(getSourceAttachmentPropertyName(path), property);
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/*
+	 * Returns the declaring type signature of the element represented by the given binding key.
+	 * Returns the signature of the element if it is a type.
+	 *
+	 * @return the declaring type signature
+	 */
+	public static String getDeclaringTypeSignature(String key) {
+		KeyToSignature keyToSignature = new KeyToSignature(key, KeyToSignature.DECLARING_TYPE);
+		keyToSignature.parse();
+		return keyToSignature.signature.toString();
+	}
+
+	/*
+	 * Appends to the given buffer the fully qualified name (as it appears in the source) of the given type
+	 */
+	private static void getFullyQualifiedName(Type type, StringBuffer buffer) {
+		switch (type.getNodeType()) {
+			case ASTNode.ARRAY_TYPE:
+				ArrayType arrayType = (ArrayType) type;
+				getFullyQualifiedName(arrayType.getElementType(), buffer);
+				for (int i = 0, length = arrayType.getDimensions(); i < length; i++) {
+					buffer.append('[');
+					buffer.append(']');
+				}
+				break;
+			case ASTNode.PARAMETERIZED_TYPE:
+				ParameterizedType parameterizedType = (ParameterizedType) type;
+				getFullyQualifiedName(parameterizedType.getType(), buffer);
+				buffer.append('<');
+				Iterator iterator = parameterizedType.typeArguments().iterator();
+				boolean isFirst = true;
+				while (iterator.hasNext()) {
+					if (!isFirst)
+						buffer.append(',');
+					else
+						isFirst = false;
+					Type typeArgument = (Type) iterator.next();
+					getFullyQualifiedName(typeArgument, buffer);
+				}
+				buffer.append('>');
+				break;
+			case ASTNode.PRIMITIVE_TYPE:
+				buffer.append(((PrimitiveType) type).getPrimitiveTypeCode().toString());
+				break;
+			case ASTNode.QUALIFIED_TYPE:
+				buffer.append(((QualifiedType) type).getName().getFullyQualifiedName());
+				break;
+			case ASTNode.SIMPLE_TYPE:
+				buffer.append(((SimpleType) type).getName().getFullyQualifiedName());
+				break;
+			case ASTNode.WILDCARD_TYPE:
+				buffer.append('?');
+				WildcardType wildcardType = (WildcardType) type;
+				Type bound = wildcardType.getBound();
+				if (bound == null) return;
+				if (wildcardType.isUpperBound()) {
+					buffer.append(" extends "); //$NON-NLS-1$
+				} else {
+					buffer.append(" super "); //$NON-NLS-1$
+				}
+				getFullyQualifiedName(bound, buffer);
+				break;
+		}
+	}
+
+	/**
+	 * Returns a trimmed version the simples names returned by Signature.
+	 */
+	public static String[] getTrimmedSimpleNames(String name) {
+		String[] result = Signature.getSimpleNames(name);
+		for (int i = 0, length = result.length; i < length; i++) {
+			result[i] = result[i].trim();
+		}
+		return result;
+	}
+
+	/**
+	 * Return the java element corresponding to the given compiler binding.
+	 */
+	public static JavaElement getUnresolvedJavaElement(FieldBinding binding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
+		if (binding.declaringClass == null) return null; // array length
+		JavaElement unresolvedJavaElement = getUnresolvedJavaElement(binding.declaringClass, workingCopyOwner, bindingsToNodes);
+		if (unresolvedJavaElement == null || unresolvedJavaElement.getElementType() != IJavaElement.TYPE) {
+			return null;
+		}
+		return (JavaElement) ((IType) unresolvedJavaElement).getField(String.valueOf(binding.name));
+	}
+
+	/**
+	 * Returns the IInitializer that contains the given local variable in the given type
+	 */
+	public static JavaElement getUnresolvedJavaElement(int localSourceStart, int localSourceEnd, JavaElement type) {
+		try {
+			if (!(type instanceof IType))
+				return null;
+			IInitializer[] initializers = ((IType) type).getInitializers();
+			for (int i = 0; i < initializers.length; i++) {
+				IInitializer initializer = initializers[i];
+				ISourceRange sourceRange = initializer.getSourceRange();
+				if (sourceRange != null) {
+					int initializerStart = sourceRange.getOffset();
+					int initializerEnd = initializerStart + sourceRange.getLength();
+					if (initializerStart <= localSourceStart && localSourceEnd <= initializerEnd) {
+						return (JavaElement) initializer;
+					}
+				}
+			}
+			return null;
+		} catch (JavaModelException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * Return the java element corresponding to the given compiler binding.
+	 */
+	public static JavaElement getUnresolvedJavaElement(MethodBinding methodBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
+		JavaElement unresolvedJavaElement = getUnresolvedJavaElement(methodBinding.declaringClass, workingCopyOwner, bindingsToNodes);
+		if (unresolvedJavaElement == null || unresolvedJavaElement.getElementType() != IJavaElement.TYPE) {
+			return null;
+		}
+		IType declaringType = (IType) unresolvedJavaElement;
+
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = bindingsToNodes == null ? null : bindingsToNodes.get(methodBinding);
+		if (node != null && !declaringType.isBinary()) {
+			if (node instanceof AnnotationMethodDeclaration) {
+				// node is an AnnotationMethodDeclaration
+				AnnotationMethodDeclaration typeMemberDeclaration = (AnnotationMethodDeclaration) node;
+				return (JavaElement) declaringType.getMethod(String.valueOf(typeMemberDeclaration.selector), CharOperation.NO_STRINGS); // annotation type members don't have parameters
+			} else {
+				// node is an MethodDeclaration
+				MethodDeclaration methodDeclaration = (MethodDeclaration) node;
+
+				Argument[] arguments = methodDeclaration.arguments;
+				String[] parameterSignatures;
+				if (arguments != null) {
+					parameterSignatures = new String[arguments.length];
+					for (int i = 0; i < arguments.length; i++) {
+						Argument argument = arguments[i];
+						TypeReference typeReference = argument.type;
+						int arrayDim = typeReference.dimensions();
+
+						String typeSig =
+							Signature.createTypeSignature(
+									CharOperation.concatWith(
+											typeReference.getTypeName(), '.'), false);
+						if (arrayDim > 0) {
+							typeSig = Signature.createArraySignature(typeSig, arrayDim);
+						}
+						parameterSignatures[i] = typeSig;
+
+					}
+				} else {
+					parameterSignatures = CharOperation.NO_STRINGS;
+				}
+				return (JavaElement) declaringType.getMethod(String.valueOf(methodDeclaration.selector), parameterSignatures);
+			}
+		} else {
+			// case of method not in the created AST, or a binary method
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = methodBinding.original();
+			String selector = original.isConstructor() ? declaringType.getElementName() : new String(original.selector);
+			boolean isBinary = declaringType.isBinary();
+			ReferenceBinding enclosingType = original.declaringClass.enclosingType();
+			// Static inner types' constructors don't get receivers (https://bugs.eclipse.org/bugs/show_bug.cgi?id=388137)
+			boolean isInnerBinaryTypeConstructor = isBinary && original.isConstructor() && !original.declaringClass.isStatic() && enclosingType != null;
+			TypeBinding[] parameters = original.parameters;
+			int length = parameters == null ? 0 : parameters.length;
+			int declaringIndex = isInnerBinaryTypeConstructor ? 1 : 0;
+			String[] parameterSignatures = new String[declaringIndex + length];
+			if (isInnerBinaryTypeConstructor)
+				parameterSignatures[0] = new String(enclosingType.genericTypeSignature()).replace('/', '.');
+			for (int i = 0;  i < length; i++) {
+				char[] signature = parameters[i].genericTypeSignature();
+				if (isBinary) {
+					signature = CharOperation.replaceOnCopy(signature, '/', '.');
+				} else {
+					signature = toUnresolvedTypeSignature(signature);
+				}
+				parameterSignatures[declaringIndex + i] = new String(signature);
+			}
+			IMethod result = declaringType.getMethod(selector, parameterSignatures);
+			if (isBinary)
+				return (JavaElement) result;
+			if (result.exists()) // if perfect match (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 )
+				return (JavaElement) result;
+			IMethod[] methods = null;
+			try {
+				methods = declaringType.getMethods();
+			} catch (JavaModelException e) {
+				// declaring type doesn't exist
+				return null;
+			}
+			IMethod[] candidates = Member.findMethods(result, methods);
+			if (candidates == null || candidates.length == 0)
+				return null;
+			return (JavaElement) candidates[0];
+		}
+	}
+
+	/**
+	 * Return the java element corresponding to the given compiler binding.
+	 */
+	public static JavaElement getUnresolvedJavaElement(TypeBinding typeBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
+		if (typeBinding == null)
+			return null;
+		switch (typeBinding.kind()) {
+			case Binding.ARRAY_TYPE :
+				typeBinding = ((org.eclipse.jdt.internal.compiler.lookup.ArrayBinding) typeBinding).leafComponentType();
+				return getUnresolvedJavaElement(typeBinding, workingCopyOwner, bindingsToNodes);
+			case Binding.BASE_TYPE :
+			case Binding.WILDCARD_TYPE :
+			case Binding.INTERSECTION_TYPE:
+				return null;
+			default :
+				if (typeBinding.isCapture())
+					return null;
+		}
+		ReferenceBinding referenceBinding;
+		if (typeBinding.isParameterizedType() || typeBinding.isRawType())
+			referenceBinding = (ReferenceBinding) typeBinding.erasure();
+		else
+			referenceBinding = (ReferenceBinding) typeBinding;
+		char[] fileName = referenceBinding.getFileName();
+		if (referenceBinding.isLocalType() || referenceBinding.isAnonymousType()) {
+			// local or anonymous type
+			if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(fileName)) {
+				int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName);
+				int pkgEnd = CharOperation.lastIndexOf('/', fileName); // pkgEnd is exclusive
+				if (pkgEnd == -1)
+					pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName);
+				if (jarSeparator != -1 && pkgEnd < jarSeparator) // if in a jar and no slash, it is a default package -> pkgEnd should be equal to jarSeparator
+					pkgEnd = jarSeparator;
+				if (pkgEnd == -1)
+					return null;
+				IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator);
+				char[] constantPoolName = referenceBinding.constantPoolName();
+				if (constantPoolName == null) {
+					ClassFile classFile = (ClassFile) getClassFile(fileName);
+					return classFile == null ? null : (JavaElement) classFile.getType();
+				}
+				pkgEnd = CharOperation.lastIndexOf('/', constantPoolName);
+				char[] classFileName = CharOperation.subarray(constantPoolName, pkgEnd+1, constantPoolName.length);
+				ClassFile classFile = (ClassFile) pkg.getClassFile(new String(classFileName) + SuffixConstants.SUFFIX_STRING_class);
+				return (JavaElement) classFile.getType();
+			}
+			ICompilationUnit cu = getCompilationUnit(fileName, workingCopyOwner);
+			if (cu == null) return null;
+			// must use getElementAt(...) as there is no back pointer to the defining method (scope is null after resolution has ended)
+			try {
+				int sourceStart = ((org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) referenceBinding).sourceStart;
+				return (JavaElement) cu.getElementAt(sourceStart);
+			} catch (JavaModelException e) {
+				// does not exist
+				return null;
+			}
+		} else if (referenceBinding.isTypeVariable()) {
+			// type parameter
+			final String typeVariableName = new String(referenceBinding.sourceName());
+			org.eclipse.jdt.internal.compiler.lookup.Binding declaringElement = ((org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) referenceBinding).declaringElement;
+			if (declaringElement instanceof MethodBinding) {
+				IMethod declaringMethod = (IMethod) getUnresolvedJavaElement((MethodBinding) declaringElement, workingCopyOwner, bindingsToNodes);
+				return (JavaElement) declaringMethod.getTypeParameter(typeVariableName);
+			} else {
+				IType declaringType = (IType) getUnresolvedJavaElement((TypeBinding) declaringElement, workingCopyOwner, bindingsToNodes);
+				return (JavaElement) declaringType.getTypeParameter(typeVariableName);
+			}
+		} else {
+			if (fileName == null) return null; // case of a WilCardBinding that doesn't have a corresponding Java element
+			// member or top level type
+			TypeBinding declaringTypeBinding = typeBinding.enclosingType();
+			if (declaringTypeBinding == null) {
+				// top level type
+				if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(fileName)) {
+					ClassFile classFile = (ClassFile) getClassFile(fileName);
+					if (classFile == null) return null;
+					return (JavaElement) classFile.getType();
+				}
+				ICompilationUnit cu = getCompilationUnit(fileName, workingCopyOwner);
+				if (cu == null) return null;
+				return (JavaElement) cu.getType(new String(referenceBinding.sourceName()));
+			} else {
+				// member type
+				IType declaringType = (IType) getUnresolvedJavaElement(declaringTypeBinding, workingCopyOwner, bindingsToNodes);
+				if (declaringType == null) return null;
+				return (JavaElement) declaringType.getType(new String(referenceBinding.sourceName()));
+			}
+		}
+	}
+
+	/*
+	 * Returns the index of the most specific argument paths which is strictly enclosing the path to check
+	 */
+	public static int indexOfEnclosingPath(IPath checkedPath, IPath[] paths, int pathCount) {
+
+	    int bestMatch = -1, bestLength = -1;
+		for (int i = 0; i < pathCount; i++){
+			if (paths[i].equals(checkedPath)) continue;
+			if (paths[i].isPrefixOf(checkedPath)) {
+			    int currentLength = paths[i].segmentCount();
+			    if (currentLength > bestLength) {
+			        bestLength = currentLength;
+			        bestMatch = i;
+			    }
+			}
+		}
+		return bestMatch;
+	}
+
+	/*
+	 * Returns the index of the Java like extension of the given file name
+	 * or -1 if it doesn't end with a known Java like extension.
+	 * Note this is the index of the '.' even if it is not considered part of the extension.
+	 */
+	public static int indexOfJavaLikeExtension(String fileName) {
+		int fileNameLength = fileName.length();
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		extensions: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] extension = javaLikeExtensions[i];
+			int extensionLength = extension.length;
+			int extensionStart = fileNameLength - extensionLength;
+			int dotIndex = extensionStart - 1;
+			if (dotIndex < 0) continue;
+			if (fileName.charAt(dotIndex) != '.') continue;
+			for (int j = 0; j < extensionLength; j++) {
+				if (fileName.charAt(extensionStart + j) != extension[j])
+					continue extensions;
+			}
+			return dotIndex;
+		}
+		return -1;
+	}
+
+	/*
+	 * Returns the index of the first argument paths which is equal to the path to check
+	 */
+	public static int indexOfMatchingPath(IPath checkedPath, IPath[] paths, int pathCount) {
+
+		for (int i = 0; i < pathCount; i++){
+			if (paths[i].equals(checkedPath)) return i;
+		}
+		return -1;
+	}
+
+	/*
+	 * Returns the index of the first argument paths which is strictly nested inside the path to check
+	 */
+	public static int indexOfNestedPath(IPath checkedPath, IPath[] paths, int pathCount) {
+
+		for (int i = 0; i < pathCount; i++){
+			if (checkedPath.equals(paths[i])) continue;
+			if (checkedPath.isPrefixOf(paths[i])) return i;
+		}
+		return -1;
+	}
+	/**
+	 * Returns whether the local file system supports accessing and modifying
+	 * the given attribute.
+	 */
+	protected static boolean isAttributeSupported(int attribute) {
+		return (EFS.getLocalFileSystem().attributes() & attribute) != 0;
+	}
+
+	/**
+	 * Returns whether the given resource is read-only or not.
+	 * @param resource
+	 * @return <code>true</code> if the resource is read-only, <code>false</code> if it is not or
+	 * 	if the file system does not support the read-only attribute.
+	 */
+	public static boolean isReadOnly(IResource resource) {
+		if (isReadOnlySupported()) {
+			ResourceAttributes resourceAttributes = resource.getResourceAttributes();
+			if (resourceAttributes == null) return false; // not supported on this platform for this resource
+			return resourceAttributes.isReadOnly();
+		}
+		return false;
+	}
+
+	/**
+	 * Returns whether the local file system supports accessing and modifying
+	 * the read only flag.
+	 */
+	public static boolean isReadOnlySupported() {
+		return isAttributeSupported(EFS.ATTRIBUTE_READ_ONLY);
+	}
+
+	/*
+	 * Returns whether the given java element is exluded from its root's classpath.
+	 * It doesn't check whether the root itself is on the classpath or not
+	 */
+	public static final boolean isExcluded(IJavaElement element) {
+		int elementType = element.getElementType();
+		switch (elementType) {
+			case IJavaElement.JAVA_MODEL:
+			case IJavaElement.JAVA_PROJECT:
+			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+				return false;
+
+			case IJavaElement.PACKAGE_FRAGMENT:
+				PackageFragmentRoot root = (PackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+				IResource resource = ((PackageFragment) element).resource();
+				return resource != null && isExcluded(resource, root.fullInclusionPatternChars(), root.fullExclusionPatternChars());
+
+			case IJavaElement.COMPILATION_UNIT:
+				root = (PackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+				resource = element.getResource();
+				if (resource == null)
+					return false;
+				if (isExcluded(resource, root.fullInclusionPatternChars(), root.fullExclusionPatternChars()))
+					return true;
+				return isExcluded(element.getParent());
+
+			default:
+				IJavaElement cu = element.getAncestor(IJavaElement.COMPILATION_UNIT);
+				return cu != null && isExcluded(cu);
+		}
+	}
+	/*
+	 * Returns whether the given resource path matches one of the inclusion/exclusion
+	 * patterns.
+	 * NOTE: should not be asked directly using pkg root pathes
+	 * @see IClasspathEntry#getInclusionPatterns
+	 * @see IClasspathEntry#getExclusionPatterns
+	 */
+	public final static boolean isExcluded(IPath resourcePath, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean isFolderPath) {
+		if (inclusionPatterns == null && exclusionPatterns == null) return false;
+		return org.eclipse.jdt.internal.compiler.util.Util.isExcluded(resourcePath.toString().toCharArray(), inclusionPatterns, exclusionPatterns, isFolderPath);
+	}
+
+	/*
+	 * Returns whether the given resource matches one of the exclusion patterns.
+	 * NOTE: should not be asked directly using pkg root pathes
+	 * @see IClasspathEntry#getExclusionPatterns
+	 */
+	public final static boolean isExcluded(IResource resource, char[][] inclusionPatterns, char[][] exclusionPatterns) {
+		IPath path = resource.getFullPath();
+		// ensure that folders are only excluded if all of their children are excluded
+		int resourceType = resource.getType();
+		return isExcluded(path, inclusionPatterns, exclusionPatterns, resourceType == IResource.FOLDER || resourceType == IResource.PROJECT);
+	}
+
+
+	/**
+	 * Validate the given .class file name.
+	 * A .class file name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must include the <code>".class"</code> suffix
+	 * <li> its prefix must be a valid identifier
+	 * </ul>
+	 * </p>
+	 * @param name the name of a .class file
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a .class file name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 */
+	public static boolean isValidClassFileName(String name, String sourceLevel, String complianceLevel) {
+		return JavaConventions.validateClassFileName(name, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+	}
+
+
+	/**
+	 * Validate the given compilation unit name.
+	 * A compilation unit name must obey the following rules:
+	 * <ul>
+	 * <li> it must not be null
+	 * <li> it must include the <code>".java"</code> suffix
+	 * <li> its prefix must be a valid identifier
+	 * </ul>
+	 * </p>
+	 * @param name the name of a compilation unit
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a compilation unit name, otherwise a status
+	 *		object indicating what is wrong with the name
+	 */
+	public static boolean isValidCompilationUnitName(String name, String sourceLevel, String complianceLevel) {
+		return JavaConventions.validateCompilationUnitName(name, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+	}
+
+	/**
+	 * Returns true if the given folder name is valid for a package,
+	 * false if it is not.
+	 * @param folderName the name of the folder
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 */
+	public static boolean isValidFolderNameForPackage(String folderName, String sourceLevel, String complianceLevel) {
+		return JavaConventions.validateIdentifier(folderName, sourceLevel, complianceLevel).getSeverity() != IStatus.ERROR;
+	}
+
+	/**
+	 * Returns true if the given method signature is valid,
+	 * false if it is not.
+	 */
+	public static boolean isValidMethodSignature(String sig) {
+		int len = sig.length();
+		if (len == 0) return false;
+		int i = 0;
+		char c = sig.charAt(i++);
+		if (c != '(') return false;
+		if (i >= len) return false;
+		while (sig.charAt(i) != ')') {
+			// Void is not allowed as a parameter type.
+			i = checkTypeSignature(sig, i, len, false);
+			if (i == -1) return false;
+			if (i >= len) return false;
+		}
+		++i;
+		i = checkTypeSignature(sig, i, len, true);
+		return i == len;
+	}
+
+	/**
+	 * Returns true if the given type signature is valid,
+	 * false if it is not.
+	 */
+	public static boolean isValidTypeSignature(String sig, boolean allowVoid) {
+		int len = sig.length();
+		return checkTypeSignature(sig, 0, len, allowVoid) == len;
+	}
+
+	/*
+	 * Returns the simple name of a local type from the given binary type name.
+	 * The last '$' is at lastDollar. The last character of the type name is at end-1.
+	 */
+	public static String localTypeName(String binaryTypeName, int lastDollar, int end) {
+		if (lastDollar > 0 && binaryTypeName.charAt(lastDollar-1) == '$')
+			// local name starts with a dollar sign
+			// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=103466)
+			return binaryTypeName;
+		int nameStart = lastDollar+1;
+		while (nameStart < end && Character.isDigit(binaryTypeName.charAt(nameStart)))
+			nameStart++;
+		return binaryTypeName.substring(nameStart, end);
+	}
+
+	/*
+	 * Add a log entry
+	 */
+	public static void log(Throwable e, String message) {
+		Throwable nestedException;
+		if (e instanceof JavaModelException
+				&& (nestedException = ((JavaModelException)e).getException()) != null) {
+			e = nestedException;
+		}
+		log(new Status(
+				IStatus.ERROR,
+				JavaCore.PLUGIN_ID,
+				IStatus.ERROR,
+				message,
+				e));
+	}
+
+	/**
+	 * Log a message that is potentially repeated in the same session.
+	 * The first time this method is called with a given exception, the
+	 * exception stack trace is written to the log.
+	 * <p>Only intended for use in debug statements.</p>
+	 *
+	 * @param key the given key
+	 * @param e the given exception
+	 * @throws IllegalArgumentException if the given key is null
+	 */
+	public static void logRepeatedMessage(String key, Exception e) {
+		if (key == null) {
+			throw new IllegalArgumentException("key cannot be null"); //$NON-NLS-1$
+		}
+		if (fgRepeatedMessages.contains(key)) {
+			return;
+		}
+		fgRepeatedMessages.add(key);
+		log(e);
+	}
+
+	public static void logRepeatedMessage(String key, int statusErrorID, String message) {
+		if (key == null) {
+			throw new IllegalArgumentException("key cannot be null"); //$NON-NLS-1$
+		}
+		if (fgRepeatedMessages.contains(key)) {
+			return;
+		}
+		fgRepeatedMessages.add(key);
+		log(statusErrorID, message);
+	}
+
+	/*
+	 * Add a log entry
+	 */
+	public static void log(int statusErrorID, String message) {
+		log(new Status(
+				statusErrorID,
+				JavaCore.PLUGIN_ID,
+				message));
+	}
+
+	/*
+	 * Add a log entry
+	 */
+	public static void log(IStatus status) {
+		Plugin plugin = JavaCore.getPlugin();
+		if (plugin == null) {
+			System.err.println(status.toString());
+		} else {
+			plugin.getLog().log(status);
+		}
+	}
+
+	public static void log(Throwable e) {
+		log(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Messages.code_assist_internal_error, e));
+	}
+
+	public static ClassFileReader newClassFileReader(IResource resource) throws CoreException, ClassFormatException, IOException {
+		InputStream in = null;
+		try {
+			in = ((IFile) resource).getContents(true);
+			return ClassFileReader.read(in, resource.getFullPath().toString());
+		} finally {
+			if (in != null)
+				in.close();
+		}
+	}
+
+	/**
+	 * Normalizes the cariage returns in the given text.
+	 * They are all changed  to use the given buffer's line separator.
+	 */
+	public static char[] normalizeCRs(char[] text, char[] buffer) {
+		CharArrayBuffer result = new CharArrayBuffer();
+		int lineStart = 0;
+		int length = text.length;
+		if (length == 0) return text;
+		String lineSeparator = getLineSeparator(text, buffer);
+		char nextChar = text[0];
+		for (int i = 0; i < length; i++) {
+			char currentChar = nextChar;
+			nextChar = i < length-1 ? text[i+1] : ' ';
+			switch (currentChar) {
+				case '\n':
+					int lineLength = i-lineStart;
+					char[] line = new char[lineLength];
+					System.arraycopy(text, lineStart, line, 0, lineLength);
+					result.append(line);
+					result.append(lineSeparator);
+					lineStart = i+1;
+					break;
+				case '\r':
+					lineLength = i-lineStart;
+					if (lineLength >= 0) {
+						line = new char[lineLength];
+						System.arraycopy(text, lineStart, line, 0, lineLength);
+						result.append(line);
+						result.append(lineSeparator);
+						if (nextChar == '\n') {
+							nextChar = ' ';
+							lineStart = i+2;
+						} else {
+							// when line separator are mixed in the same file
+							// \r might not be followed by a \n. If not, we should increment
+							// lineStart by one and not by two.
+							lineStart = i+1;
+						}
+					} else {
+						// when line separator are mixed in the same file
+						// we need to prevent NegativeArraySizeException
+						lineStart = i+1;
+					}
+					break;
+			}
+		}
+		char[] lastLine;
+		if (lineStart > 0) {
+			int lastLineLength = length-lineStart;
+			if (lastLineLength > 0) {
+				lastLine = new char[lastLineLength];
+				System.arraycopy(text, lineStart, lastLine, 0, lastLineLength);
+				result.append(lastLine);
+			}
+			return result.getContents();
+		}
+		return text;
+	}
+
+	/**
+	 * Normalizes the carriage returns in the given text.
+	 * They are all changed to use given buffer's line separator.
+	 */
+	public static String normalizeCRs(String text, String buffer) {
+		return new String(normalizeCRs(text.toCharArray(), buffer.toCharArray()));
+	}
+
+	/**
+	 * Converts the given relative path into a package name.
+	 * Returns null if the path is not a valid package name.
+	 * @param pkgPath the package path
+	 * @param sourceLevel the source level
+	 * @param complianceLevel the compliance level
+	 */
+	public static String packageName(IPath pkgPath, String sourceLevel, String complianceLevel) {
+		StringBuffer pkgName = new StringBuffer(IPackageFragment.DEFAULT_PACKAGE_NAME);
+		for (int j = 0, max = pkgPath.segmentCount(); j < max; j++) {
+			String segment = pkgPath.segment(j);
+			if (!isValidFolderNameForPackage(segment, sourceLevel, complianceLevel)) {
+				return null;
+			}
+			pkgName.append(segment);
+			if (j < pkgPath.segmentCount() - 1) {
+				pkgName.append("." ); //$NON-NLS-1$
+			}
+		}
+		return pkgName.toString();
+	}
+
+	/**
+	 * Returns the length of the common prefix between s1 and s2.
+	 */
+	public static int prefixLength(char[] s1, char[] s2) {
+		int len= 0;
+		int max= Math.min(s1.length, s2.length);
+		for (int i= 0; i < max && s1[i] == s2[i]; ++i)
+			++len;
+		return len;
+	}
+	/**
+	 * Returns the length of the common prefix between s1 and s2.
+	 */
+	public static int prefixLength(String s1, String s2) {
+		int len= 0;
+		int max= Math.min(s1.length(), s2.length());
+		for (int i= 0; i < max && s1.charAt(i) == s2.charAt(i); ++i)
+			++len;
+		return len;
+	}
+	private static void quickSort(char[][] list, int left, int right) {
+		int original_left= left;
+		int original_right= right;
+		char[] mid= list[left + (right - left) / 2];
+		do {
+			while (compare(list[left], mid) < 0) {
+				left++;
+			}
+			while (compare(mid, list[right]) < 0) {
+				right--;
+			}
+			if (left <= right) {
+				char[] tmp= list[left];
+				list[left]= list[right];
+				list[right]= tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			quickSort(list, original_left, right);
+		}
+		if (left < original_right) {
+			quickSort(list, left, original_right);
+		}
+	}
+
+	/**
+	 * Sort the comparable objects in the given collection.
+	 */
+	private static void quickSort(Comparable[] sortedCollection, int left, int right) {
+		int original_left = left;
+		int original_right = right;
+		Comparable mid = sortedCollection[ left + (right - left) / 2];
+		do {
+			while (sortedCollection[left].compareTo(mid) < 0) {
+				left++;
+			}
+			while (mid.compareTo(sortedCollection[right]) < 0) {
+				right--;
+			}
+			if (left <= right) {
+				Comparable tmp = sortedCollection[left];
+				sortedCollection[left] = sortedCollection[right];
+				sortedCollection[right] = tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			quickSort(sortedCollection, original_left, right);
+		}
+		if (left < original_right) {
+			quickSort(sortedCollection, left, original_right);
+		}
+	}
+	private static void quickSort(int[] list, int left, int right) {
+		int original_left= left;
+		int original_right= right;
+		int mid= list[left + (right - left) / 2];
+		do {
+			while (list[left] < mid) {
+				left++;
+			}
+			while (mid < list[right]) {
+				right--;
+			}
+			if (left <= right) {
+				int tmp= list[left];
+				list[left]= list[right];
+				list[right]= tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			quickSort(list, original_left, right);
+		}
+		if (left < original_right) {
+			quickSort(list, left, original_right);
+		}
+	}
+
+	/**
+	 * Sort the objects in the given collection using the given comparer.
+	 */
+	private static void quickSort(Object[] sortedCollection, int left, int right, Comparer comparer) {
+		int original_left = left;
+		int original_right = right;
+		Object mid = sortedCollection[ left + (right - left) / 2];
+		do {
+			while (comparer.compare(sortedCollection[left], mid) < 0) {
+				left++;
+			}
+			while (comparer.compare(mid, sortedCollection[right]) < 0) {
+				right--;
+			}
+			if (left <= right) {
+				Object tmp = sortedCollection[left];
+				sortedCollection[left] = sortedCollection[right];
+				sortedCollection[right] = tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			quickSort(sortedCollection, original_left, right, comparer);
+		}
+		if (left < original_right) {
+			quickSort(sortedCollection, left, original_right, comparer);
+		}
+	}
+
+	/**
+	 * Sort the strings in the given collection.
+	 */
+	private static void quickSort(String[] sortedCollection, int left, int right) {
+		int original_left = left;
+		int original_right = right;
+		String mid = sortedCollection[ left + (right - left) / 2];
+		do {
+			while (sortedCollection[left].compareTo(mid) < 0) {
+				left++;
+			}
+			while (mid.compareTo(sortedCollection[right]) < 0) {
+				right--;
+			}
+			if (left <= right) {
+				String tmp = sortedCollection[left];
+				sortedCollection[left] = sortedCollection[right];
+				sortedCollection[right] = tmp;
+				left++;
+				right--;
+			}
+		} while (left <= right);
+		if (original_left < right) {
+			quickSort(sortedCollection, original_left, right);
+		}
+		if (left < original_right) {
+			quickSort(sortedCollection, left, original_right);
+		}
+	}
+
+	/**
+	 * Returns the toString() of the given full path minus the first given number of segments.
+	 * The returned string is always a relative path (it has no leading slash)
+	 */
+	public static String relativePath(IPath fullPath, int skipSegmentCount) {
+		boolean hasTrailingSeparator = fullPath.hasTrailingSeparator();
+		String[] segments = fullPath.segments();
+
+		// compute length
+		int length = 0;
+		int max = segments.length;
+		if (max > skipSegmentCount) {
+			for (int i1 = skipSegmentCount; i1 < max; i1++) {
+				length += segments[i1].length();
+			}
+			//add the separator lengths
+			length += max - skipSegmentCount - 1;
+		}
+		if (hasTrailingSeparator)
+			length++;
+
+		char[] result = new char[length];
+		int offset = 0;
+		int len = segments.length - 1;
+		if (len >= skipSegmentCount) {
+			//append all but the last segment, with separators
+			for (int i = skipSegmentCount; i < len; i++) {
+				int size = segments[i].length();
+				segments[i].getChars(0, size, result, offset);
+				offset += size;
+				result[offset++] = '/';
+			}
+			//append the last segment
+			int size = segments[len].length();
+			segments[len].getChars(0, size, result, offset);
+			offset += size;
+		}
+		if (hasTrailingSeparator)
+			result[offset++] = '/';
+		return new String(result);
+	}
+
+	/*
+	 * Resets the list of Java-like extensions after a change in content-type.
+	 */
+	public static void resetJavaLikeExtensions() {
+		JAVA_LIKE_EXTENSIONS = null;
+	}
+
+	/**
+	 * Scans the given string for a type signature starting at the given index
+	 * and returns the index of the last character.
+	 * <pre>
+	 * TypeSignature:
+	 *  |  BaseTypeSignature
+	 *  |  ArrayTypeSignature
+	 *  |  ClassTypeSignature
+	 *  |  TypeVariableSignature
+	 * </pre>
+	 *
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type signature
+	 */
+	public static int scanTypeSignature(char[] string, int start) {
+		// this method is used in jdt.debug
+		return org.eclipse.jdt.internal.compiler.util.Util.scanTypeSignature(string, start);
+	}
+	/**
+	 * Return a new array which is the split of the given string using the given divider. The given end
+	 * is exclusive and the given start is inclusive.
+	 * <br>
+	 * <br>
+	 * For example:
+	 * <ol>
+	 * <li><pre>
+	 *    divider = 'b'
+	 *    string = "abbaba"
+	 *    start = 2
+	 *    end = 5
+	 *    result => { "", "a", "" }
+	 * </pre>
+	 * </li>
+	 * </ol>
+	 *
+	 * @param divider the given divider
+	 * @param string the given string
+	 * @param start the given starting index
+	 * @param end the given ending index
+	 * @return a new array which is the split of the given string using the given divider
+	 * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length
+	 */
+	public static final String[] splitOn(
+		char divider,
+		String string,
+		int start,
+		int end) {
+		int length = string == null ? 0 : string.length();
+		if (length == 0 || start > end)
+			return CharOperation.NO_STRINGS;
+
+		int wordCount = 1;
+		for (int i = start; i < end; i++)
+			if (string.charAt(i) == divider)
+				wordCount++;
+		String[] split = new String[wordCount];
+		int last = start, currentWord = 0;
+		for (int i = start; i < end; i++) {
+			if (string.charAt(i) == divider) {
+				split[currentWord++] = string.substring(last, i);
+				last = i + 1;
+			}
+		}
+		split[currentWord] = string.substring(last, end);
+		return split;
+	}
+	/**
+	 * Sets or unsets the given resource as read-only in the file system.
+	 * It's a no-op if the file system does not support the read-only attribute.
+	 *
+	 * @param resource The resource to set as read-only
+	 * @param readOnly <code>true</code> to set it to read-only,
+	 *		<code>false</code> to unset
+	 */
+	public static void setReadOnly(IResource resource, boolean readOnly) {
+		if (isReadOnlySupported()) {
+			ResourceAttributes resourceAttributes = resource.getResourceAttributes();
+			if (resourceAttributes == null) return; // not supported on this platform for this resource
+			resourceAttributes.setReadOnly(readOnly);
+			try {
+				resource.setResourceAttributes(resourceAttributes);
+			} catch (CoreException e) {
+				// ignore
+			}
+		}
+	}
+	public static void sort(char[][] list) {
+		if (list.length > 1)
+			quickSort(list, 0, list.length - 1);
+	}
+
+	/**
+	 * Sorts an array of Comparable objects in place.
+	 */
+	public static void sort(Comparable[] objects) {
+		if (objects.length > 1)
+			quickSort(objects, 0, objects.length - 1);
+	}
+	public static void sort(int[] list) {
+		if (list.length > 1)
+			quickSort(list, 0, list.length - 1);
+	}
+
+	/**
+	 * Sorts an array of objects in place.
+	 * The given comparer compares pairs of items.
+	 */
+	public static void sort(Object[] objects, Comparer comparer) {
+		if (objects.length > 1)
+			quickSort(objects, 0, objects.length - 1, comparer);
+	}
+
+	/**
+	 * Sorts an array of strings in place using quicksort.
+	 */
+	public static void sort(String[] strings) {
+		if (strings.length > 1)
+			quickSort(strings, 0, strings.length - 1);
+	}
+
+	/**
+	 * Sorts an array of Comparable objects, returning a new array
+	 * with the sorted items.  The original array is left untouched.
+	 */
+	public static Comparable[] sortCopy(Comparable[] objects) {
+		int len = objects.length;
+		Comparable[] copy = new Comparable[len];
+		System.arraycopy(objects, 0, copy, 0, len);
+		sort(copy);
+		return copy;
+	}
+
+	/**
+	 * Sorts an array of Java elements based on their toStringWithAncestors(),
+	 * returning a new array with the sorted items.
+	 * The original array is left untouched.
+	 */
+	public static IJavaElement[] sortCopy(IJavaElement[] elements) {
+		int len = elements.length;
+		IJavaElement[] copy = new IJavaElement[len];
+		System.arraycopy(elements, 0, copy, 0, len);
+		sort(copy, new Comparer() {
+			public int compare(Object a, Object b) {
+				return ((JavaElement) a).toStringWithAncestors().compareTo(((JavaElement) b).toStringWithAncestors());
+			}
+		});
+		return copy;
+	}
+
+	/**
+	 * Sorts an array of Strings, returning a new array
+	 * with the sorted items.  The original array is left untouched.
+	 */
+	public static Object[] sortCopy(Object[] objects, Comparer comparer) {
+		int len = objects.length;
+		Object[] copy = new Object[len];
+		System.arraycopy(objects, 0, copy, 0, len);
+		sort(copy, comparer);
+		return copy;
+	}
+
+	/**
+	 * Sorts an array of Strings, returning a new array
+	 * with the sorted items.  The original array is left untouched.
+	 */
+	public static String[] sortCopy(String[] objects) {
+		int len = objects.length;
+		String[] copy = new String[len];
+		System.arraycopy(objects, 0, copy, 0, len);
+		sort(copy);
+		return copy;
+	}
+
+	/*
+	 * Returns whether the given compound name starts with the given prefix.
+	 * Returns true if the n first elements of the prefix are equals and the last element of the
+	 * prefix is a prefix of the corresponding element in the compound name.
+	 */
+	public static boolean startsWithIgnoreCase(String[] compoundName, String[] prefix, boolean partialMatch) {
+		int prefixLength = prefix.length;
+		int nameLength = compoundName.length;
+		if (prefixLength > nameLength) return false;
+		for (int i = 0; i < prefixLength - 1; i++) {
+			if (!compoundName[i].equalsIgnoreCase(prefix[i]))
+				return false;
+		}
+		return (partialMatch || prefixLength == nameLength) && compoundName[prefixLength-1].toLowerCase().startsWith(prefix[prefixLength-1].toLowerCase());
+	}
+
+	/**
+	 * Converts a String[] to char[][].
+	 */
+	public static char[][] toCharArrays(String[] a) {
+		int len = a.length;
+		if (len == 0) return CharOperation.NO_CHAR_CHAR;
+		char[][] result = new char[len][];
+		for (int i = 0; i < len; ++i) {
+			result[i] = a[i].toCharArray();
+		}
+		return result;
+	}
+
+	/**
+	 * Converts a String to char[][], where segments are separate by '.'.
+	 */
+	public static char[][] toCompoundChars(String s) {
+		int len = s.length();
+		if (len == 0) {
+			return CharOperation.NO_CHAR_CHAR;
+		}
+		int segCount = 1;
+		for (int off = s.indexOf('.'); off != -1; off = s.indexOf('.', off + 1)) {
+			++segCount;
+		}
+		char[][] segs = new char[segCount][];
+		int start = 0;
+		for (int i = 0; i < segCount; ++i) {
+			int dot = s.indexOf('.', start);
+			int end = (dot == -1 ? s.length() : dot);
+			segs[i] = new char[end - start];
+			s.getChars(start, end, segs[i], 0);
+			start = end + 1;
+		}
+		return segs;
+	}
+
+	/*
+	 * Converts the given URI to a local file. Use the existing file if the uri is on the local file system.
+	 * Otherwise fetch it.
+	 * Returns null if unable to fetch it.
+	 */
+	public static File toLocalFile(URI uri, IProgressMonitor monitor) throws CoreException {
+		IFileStore fileStore = EFS.getStore(uri);
+		File localFile = fileStore.toLocalFile(EFS.NONE, monitor);
+		if (localFile ==null)
+			// non local file system
+			localFile= fileStore.toLocalFile(EFS.CACHE, monitor);
+		return localFile;
+	}
+	/**
+	 * Converts a char[][] to String, where segments are separated by '.'.
+	 */
+	public static String toString(char[][] c) {
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0, max = c.length; i < max; ++i) {
+			if (i != 0) sb.append('.');
+			sb.append(c[i]);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Converts a char[][] and a char[] to String, where segments are separated by '.'.
+	 */
+	public static String toString(char[][] c, char[] d) {
+		if (c == null) return new String(d);
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0, max = c.length; i < max; ++i) {
+			sb.append(c[i]);
+			sb.append('.');
+		}
+		sb.append(d);
+		return sb.toString();
+	}
+
+	/*
+	 * Converts a char[][] to String[].
+	 */
+	public static String[] toStrings(char[][] a) {
+		int len = a.length;
+		String[] result = new String[len];
+		for (int i = 0; i < len; ++i) {
+			result[i] = new String(a[i]);
+		}
+		return result;
+	}
+	private static char[] toUnresolvedTypeSignature(char[] signature) {
+		int length = signature.length;
+		if (length <= 1)
+			return signature;
+		StringBuffer buffer = new StringBuffer(length);
+		toUnresolvedTypeSignature(signature, 0, length, buffer);
+		int bufferLength = buffer.length();
+		char[] result = new char[bufferLength];
+		buffer.getChars(0, bufferLength, result, 0);
+		return result;
+	}
+
+	private static int toUnresolvedTypeSignature(char[] signature, int start, int length, StringBuffer buffer) {
+		if (signature[start] == Signature.C_RESOLVED)
+			buffer.append(Signature.C_UNRESOLVED);
+		else
+			buffer.append(signature[start]);
+		for (int i = start+1; i < length; i++) {
+			char c = signature[i];
+			switch (c) {
+			case '/':
+			case Signature.C_DOLLAR:
+				buffer.append(Signature.C_DOT);
+				break;
+			case Signature.C_GENERIC_START:
+				buffer.append(Signature.C_GENERIC_START);
+				i = toUnresolvedTypeSignature(signature, i+1, length, buffer);
+				break;
+			case Signature.C_GENERIC_END:
+				buffer.append(Signature.C_GENERIC_END);
+				return i;
+			default:
+				buffer.append(c);
+				break;
+			}
+		}
+		return length;
+	}
+	private static void appendArrayTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
+		int length = string.length;
+		// need a minimum 2 char
+		if (start >= length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_ARRAY) {
+			throw new IllegalArgumentException();
+		}
+
+		int index = start;
+		c = string[++index];
+		while(c == Signature.C_ARRAY) {
+			// need a minimum 2 char
+			if (index >= length - 1) {
+				throw new IllegalArgumentException();
+			}
+			c = string[++index];
+		}
+
+		appendTypeSignature(string, index, buffer, compact);
+
+		for(int i = 0, dims = index - start; i < dims; i++) {
+			buffer.append('[').append(']');
+		}
+	}
+	private static void appendClassTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
+		char c = string[start];
+		if (c != Signature.C_RESOLVED) {
+			return;
+		}
+		int p = start + 1;
+		int checkpoint = buffer.length();
+		while (true) {
+			c = string[p];
+			switch(c) {
+				case Signature.C_SEMICOLON :
+					// all done
+					return;
+				case Signature.C_DOT :
+				case '/' :
+					// erase package prefix
+					if (compact) {
+						buffer.setLength(checkpoint);
+					} else {
+						buffer.append('.');
+					}
+					break;
+				 case Signature.C_DOLLAR :
+					/**
+					 * Convert '$' in resolved type signatures into '.'.
+					 * NOTE: This assumes that the type signature is an inner type
+					 * signature. This is true in most cases, but someone can define a
+					 * non-inner type name containing a '$'.
+					 */
+					buffer.append('.');
+				 	break;
+				 default :
+					buffer.append(c);
+			}
+			p++;
+		}
+	}
+	static void appendTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
+		char c = string[start];
+		switch (c) {
+			case Signature.C_ARRAY :
+				appendArrayTypeSignature(string, start, buffer, compact);
+				break;
+			case Signature.C_RESOLVED :
+				appendClassTypeSignature(string, start, buffer, compact);
+				break;
+			case Signature.C_TYPE_VARIABLE :
+				int e = org.eclipse.jdt.internal.compiler.util.Util.scanTypeVariableSignature(string, start);
+				buffer.append(string, start + 1, e - start - 1);
+				break;
+			case Signature.C_BOOLEAN :
+				buffer.append(BOOLEAN);
+				break;
+			case Signature.C_BYTE :
+				buffer.append(BYTE);
+				break;
+			case Signature.C_CHAR :
+				buffer.append(CHAR);
+				break;
+			case Signature.C_DOUBLE :
+				buffer.append(DOUBLE);
+				break;
+			case Signature.C_FLOAT :
+				buffer.append(FLOAT);
+				break;
+			case Signature.C_INT :
+				buffer.append(INT);
+				break;
+			case Signature.C_LONG :
+				buffer.append(LONG);
+				break;
+			case Signature.C_SHORT :
+				buffer.append(SHORT);
+				break;
+			case Signature.C_VOID :
+				buffer.append(VOID);
+				break;
+		}
+	}
+	public static String toString(char[] declaringClass, char[] methodName, char[] methodSignature, boolean includeReturnType, boolean compact) {
+		final boolean isConstructor = CharOperation.equals(methodName, INIT);
+		int firstParen = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
+		if (firstParen == -1) {
+			return ""; //$NON-NLS-1$
+		}
+
+		StringBuffer buffer = new StringBuffer(methodSignature.length + 10);
+
+		// decode declaring class name
+		// it can be either an array signature or a type signature
+		if (declaringClass != null && declaringClass.length > 0) {
+			char[] declaringClassSignature = null;
+			if (declaringClass[0] == Signature.C_ARRAY) {
+				CharOperation.replace(declaringClass, '/', '.');
+				declaringClassSignature = Signature.toCharArray(declaringClass);
+			} else {
+				CharOperation.replace(declaringClass, '/', '.');
+				declaringClassSignature = declaringClass;
+			}
+			int lastIndexOfSlash = CharOperation.lastIndexOf('.', declaringClassSignature);
+			if (compact && lastIndexOfSlash != -1) {
+				buffer.append(declaringClassSignature, lastIndexOfSlash + 1, declaringClassSignature.length - lastIndexOfSlash - 1);
+			} else {
+				buffer.append(declaringClassSignature);
+			}
+			if (!isConstructor) {
+				buffer.append('.');
+			}
+		}
+
+		// selector
+		if (!isConstructor && methodName != null) {
+			buffer.append(methodName);
+		}
+
+		// parameters
+		buffer.append('(');
+		char[][] pts = Signature.getParameterTypes(methodSignature);
+		for (int i = 0, max = pts.length; i < max; i++) {
+			appendTypeSignature(pts[i], 0 , buffer, compact);
+			if (i != pts.length - 1) {
+				buffer.append(',');
+				buffer.append(' ');
+			}
+		}
+		buffer.append(')');
+
+		if (!isConstructor) {
+			buffer.append(" : "); //$NON-NLS-1$
+			// return type
+			if (includeReturnType) {
+				char[] rts = Signature.getReturnType(methodSignature);
+				appendTypeSignature(rts, 0 , buffer, compact);
+			}
+		}
+		return String.valueOf(buffer);
+	}
+	/*
+	 * Returns the unresolved type parameter signatures of the given method
+	 * e.g. {"QString;", "[int", "[[Qjava.util.Vector;"}
+	 */
+	public static String[] typeParameterSignatures(AbstractMethodDeclaration method) {
+		Argument[] args = method.arguments;
+		if (args != null) {
+			int length = args.length;
+			String[] signatures = new String[length];
+			for (int i = 0; i < args.length; i++) {
+				Argument arg = args[i];
+				signatures[i] = typeSignature(arg.type);
+			}
+			return signatures;
+		}
+		return CharOperation.NO_STRINGS;
+	}
+
+	/*
+	 * Returns the unresolved type signature of the given type reference,
+	 * e.g. "QString;", "[int", "[[Qjava.util.Vector;"
+	 */
+	public static String typeSignature(TypeReference type) {
+		String signature = null;
+		if ((type.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsUnionType) != 0) {
+			// special treatment for union type reference
+			UnionTypeReference unionTypeReference = (UnionTypeReference) type;
+			TypeReference[] typeReferences = unionTypeReference.typeReferences;
+			int length = typeReferences.length;
+			String[] typeSignatures = new String[length];
+			for(int i = 0; i < length; i++) {
+				char[][] compoundName = typeReferences[i].getParameterizedTypeName();
+				char[] typeName = CharOperation.concatWith(compoundName, '.');
+				typeSignatures[i] = Signature.createTypeSignature(typeName, false/*don't resolve*/);
+			}
+			signature = Signature.createIntersectionTypeSignature(typeSignatures);
+		} else {
+			char[][] compoundName = type.getParameterizedTypeName();
+			char[] typeName =CharOperation.concatWith(compoundName, '.');
+			signature = Signature.createTypeSignature(typeName, false/*don't resolve*/);
+		}
+		return signature;
+	}
+
+	/**
+	 * Asserts that the given method signature is valid.
+	 */
+	public static void validateMethodSignature(String sig) {
+		Assert.isTrue(isValidMethodSignature(sig));
+	}
+
+	/**
+	 * Asserts that the given type signature is valid.
+	 */
+	public static void validateTypeSignature(String sig, boolean allowVoid) {
+		Assert.isTrue(isValidTypeSignature(sig, allowVoid));
+	}
+	public static void verbose(String log) {
+		verbose(log, System.out);
+	}
+	public static synchronized void verbose(String log, PrintStream printStream) {
+		int start = 0;
+		do {
+			int end = log.indexOf('\n', start);
+			printStream.print(Thread.currentThread());
+			printStream.print(" "); //$NON-NLS-1$
+			printStream.print(log.substring(start, end == -1 ? log.length() : end+1));
+			start = end+1;
+		} while (start != 0);
+		printStream.println();
+	}
+
+	/**
+	 * Returns true if the given name ends with one of the known java like extension.
+	 * (implementation is not creating extra strings)
+	 */
+	public final static boolean isJavaLikeFileName(String name) {
+		if (name == null) return false;
+		return indexOfJavaLikeExtension(name) != -1;
+	}
+
+	/**
+	 * Returns true if the given name ends with one of the known java like extension.
+	 * (implementation is not creating extra strings)
+	 */
+	public final static boolean isJavaLikeFileName(char[] fileName) {
+		if (fileName == null) return false;
+		int fileNameLength = fileName.length;
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		extensions: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] extension = javaLikeExtensions[i];
+			int extensionLength = extension.length;
+			int extensionStart = fileNameLength - extensionLength;
+			if (extensionStart-1 < 0) continue;
+			if (fileName[extensionStart-1] != '.') continue;
+			for (int j = 0; j < extensionLength; j++) {
+				if (fileName[extensionStart + j] != extension[j])
+					continue extensions;
+			}
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Get all type arguments from an array of signatures.
+	 *
+	 * Example:
+	 * 	For following type X<Y<Z>,V<W>,U>.A<B> signatures is:
+	 * 	[
+	 * 		['L','X','<','L','Y','<','L','Z',';'>',';','L','V','<','L','W',';'>',';','L','U',';',>',';'],
+	 * 		['L','A','<','L','B',';','>',';']
+	 * 	]
+	 * 	@see #splitTypeLevelsSignature(String)
+	 * 	Then, this method returns:
+	 * 	[
+	 * 		[
+	 * 			['L','Y','<','L','Z',';'>',';'],
+	 * 			['L','V','<','L','W',';'>',';'],
+	 * 			['L','U',';']
+	 * 		],
+	 * 		[
+	 * 			['L','B',';']
+	 * 		]
+	 * 	]
+	 *
+	 * @param typeSignatures Array of signatures (one per each type levels)
+	 * @throws IllegalArgumentException If one of provided signature is malformed
+	 * @return char[][][] Array of type arguments for each signature
+	 */
+	public final static char[][][] getAllTypeArguments(char[][] typeSignatures) {
+		if (typeSignatures == null) return null;
+		int length = typeSignatures.length;
+		char[][][] typeArguments = new char[length][][];
+		for (int i=0; i<length; i++){
+			typeArguments[i] = Signature.getTypeArguments(typeSignatures[i]);
+		}
+		return typeArguments;
+	}
+	public static IAnnotation getAnnotation(JavaElement parent, IBinaryAnnotation binaryAnnotation, String memberValuePairName) {
+		char[] typeName = org.eclipse.jdt.core.Signature.toCharArray(CharOperation.replaceOnCopy(binaryAnnotation.getTypeName(), '/', '.'));
+		return new Annotation(parent, new String(typeName), memberValuePairName);
+	}
+	
+	public static Object getAnnotationMemberValue(JavaElement parent, MemberValuePair memberValuePair, Object binaryValue) {
+		if (binaryValue instanceof Constant) {
+			return getAnnotationMemberValue(memberValuePair, (Constant) binaryValue);
+		} else if (binaryValue instanceof IBinaryAnnotation) {
+			memberValuePair.valueKind = IMemberValuePair.K_ANNOTATION;
+			return getAnnotation(parent, (IBinaryAnnotation) binaryValue, memberValuePair.getMemberName());
+		} else if (binaryValue instanceof ClassSignature) {
+			memberValuePair.valueKind = IMemberValuePair.K_CLASS;
+			char[] className = Signature.toCharArray(CharOperation.replaceOnCopy(((ClassSignature) binaryValue).getTypeName(), '/', '.'));
+			return new String(className);
+		} else if (binaryValue instanceof EnumConstantSignature) {
+			memberValuePair.valueKind = IMemberValuePair.K_QUALIFIED_NAME;
+			EnumConstantSignature enumConstant = (EnumConstantSignature) binaryValue;
+			char[] enumName = Signature.toCharArray(CharOperation.replaceOnCopy(enumConstant.getTypeName(), '/', '.'));
+			char[] qualifiedName = CharOperation.concat(enumName, enumConstant.getEnumConstantName(), '.');
+			return new String(qualifiedName);
+		} else if (binaryValue instanceof Object[]) {
+			memberValuePair.valueKind = -1; // modified below by the first call to getMemberValue(...)
+			Object[] binaryValues = (Object[]) binaryValue;
+			int length = binaryValues.length;
+			Object[] values = new Object[length];
+			for (int i = 0; i < length; i++) {
+				int previousValueKind = memberValuePair.valueKind;
+				Object value = getAnnotationMemberValue(parent, memberValuePair, binaryValues[i]);
+				if (previousValueKind != -1 && memberValuePair.valueKind != previousValueKind) {
+					// values are heterogeneous, value kind is thus unknown
+					memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+				}
+				if (value instanceof Annotation) {
+					Annotation annotation = (Annotation) value;
+					for (int j = 0; j < i; j++) {
+						if (annotation.equals(values[j])) {
+							annotation.occurrenceCount++;
+						}
+					}
+				}
+				values[i] = value;
+			}
+			if (memberValuePair.valueKind == -1)
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return values;
+		} else {
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		}
+	}
+
+	/*
+	 * Creates a member value from the given constant, and sets the valueKind on the given memberValuePair
+	 */
+	public static Object getAnnotationMemberValue(MemberValuePair memberValuePair, Constant constant) {
+		if (constant == null) {
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		}
+		switch (constant.typeID()) {
+			case TypeIds.T_int :
+				memberValuePair.valueKind = IMemberValuePair.K_INT;
+				return new Integer(constant.intValue());
+			case TypeIds.T_byte :
+				memberValuePair.valueKind = IMemberValuePair.K_BYTE;
+				return new Byte(constant.byteValue());
+			case TypeIds.T_short :
+				memberValuePair.valueKind = IMemberValuePair.K_SHORT;
+				return new Short(constant.shortValue());
+			case TypeIds.T_char :
+				memberValuePair.valueKind = IMemberValuePair.K_CHAR;
+				return new Character(constant.charValue());
+			case TypeIds.T_float :
+				memberValuePair.valueKind = IMemberValuePair.K_FLOAT;
+				return new Float(constant.floatValue());
+			case TypeIds.T_double :
+				memberValuePair.valueKind = IMemberValuePair.K_DOUBLE;
+				return new Double(constant.doubleValue());
+			case TypeIds.T_boolean :
+				memberValuePair.valueKind = IMemberValuePair.K_BOOLEAN;
+				return Boolean.valueOf(constant.booleanValue());
+			case TypeIds.T_long :
+				memberValuePair.valueKind = IMemberValuePair.K_LONG;
+				return new Long(constant.longValue());
+			case TypeIds.T_JavaLangString :
+				memberValuePair.valueKind = IMemberValuePair.K_STRING;
+				return constant.stringValue();
+			default:
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+				return null;
+		}
+	}
+	
+	/*
+	 * Creates a member value from the given constant in case of negative numerals,
+	 * and sets the valueKind on the given memberValuePair
+	 */
+	public static Object getNegativeAnnotationMemberValue(MemberValuePair memberValuePair, Constant constant) {
+		if (constant == null) {
+			memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+			return null;
+		}
+		switch (constant.typeID()) {
+			case TypeIds.T_int :
+				memberValuePair.valueKind = IMemberValuePair.K_INT;
+				return new Integer(constant.intValue() * -1);
+			case TypeIds.T_float :
+				memberValuePair.valueKind = IMemberValuePair.K_FLOAT;
+				return new Float(constant.floatValue() * -1.0f);
+			case TypeIds.T_double :
+				memberValuePair.valueKind = IMemberValuePair.K_DOUBLE;
+				return new Double(constant.doubleValue() * -1.0);
+			case TypeIds.T_long :
+				memberValuePair.valueKind = IMemberValuePair.K_LONG;
+				return new Long(constant.longValue() * -1L);
+			default:
+				memberValuePair.valueKind = IMemberValuePair.K_UNKNOWN;
+				return null;
+		}
+	}
+	/**
+	 * Split signatures of all levels  from a type unique key.
+	 *
+	 * Example:
+	 * 	For following type X<Y<Z>,V<W>,U>.A<B>, unique key is:
+	 * 	"LX<LY<LZ;>;LV<LW;>;LU;>.LA<LB;>;"
+	 *
+	 * 	The return splitted signatures array is:
+	 * 	[
+	 * 		['L','X','<','L','Y','<','L','Z',';'>',';','L','V','<','L','W',';'>',';','L','U','>',';'],
+	 * 		['L','A','<','L','B',';','>',';']
+	 *
+	 * @param typeSignature ParameterizedSourceType type signature
+	 * @return char[][] Array of signatures for each level of given unique key
+	 */
+	public final static char[][] splitTypeLevelsSignature(String typeSignature) {
+		// In case of IJavaElement signature, replace '$' by '.'
+		char[] source = Signature.removeCapture(typeSignature.toCharArray());
+		CharOperation.replace(source, '$', '.');
+
+		// Init counters and arrays
+		char[][] signatures = new char[10][];
+		int signaturesCount = 0;
+//		int[] lengthes = new int [10];
+		int paramOpening = 0;
+
+		// Scan each signature character
+		for (int idx=0, ln = source.length; idx < ln; idx++) {
+			switch (source[idx]) {
+				case '>':
+					paramOpening--;
+					if (paramOpening == 0)  {
+						if (signaturesCount == signatures.length) {
+							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
+						}
+					}
+					break;
+				case '<':
+					paramOpening++;
+					break;
+				case '.':
+					if (paramOpening == 0)  {
+						if (signaturesCount == signatures.length) {
+							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
+						}
+						signatures[signaturesCount] = new char[idx+1];
+						System.arraycopy(source, 0, signatures[signaturesCount], 0, idx);
+						signatures[signaturesCount][idx] = Signature.C_SEMICOLON;
+						signaturesCount++;
+					}
+					break;
+				case '/':
+					source[idx] = '.';
+					break;
+			}
+		}
+
+		// Resize signatures array
+		char[][] typeSignatures = new char[signaturesCount+1][];
+		typeSignatures[0] = source;
+		for (int i=1, j=signaturesCount-1; i<=signaturesCount; i++, j--){
+			typeSignatures[i] = signatures[j];
+		}
+		return typeSignatures;
+	}
+
+	/*
+	 * Can throw IllegalArgumentException or ArrayIndexOutOfBoundsException
+	 */
+	public static String toAnchor(int startingIndex, char[] methodSignature, String methodName, boolean isVarArgs) {
+		try {
+			return new String(toAnchor(startingIndex, methodSignature, methodName.toCharArray(), isVarArgs));
+		} catch(IllegalArgumentException e) {
+			return null;
+		}
+	}
+	public static char[] toAnchor(int startingIndex, char[] methodSignature, char[] methodName, boolean isVargArgs) {
+		int firstParen = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
+		if (firstParen == -1) {
+			throw new IllegalArgumentException();
+		}
+
+		StringBuffer buffer = new StringBuffer(methodSignature.length + 10);
+
+		// selector
+		if (methodName != null) {
+			buffer.append(methodName);
+		}
+
+		// parameters
+		buffer.append('(');
+		char[][] pts = Signature.getParameterTypes(methodSignature);
+		for (int i = startingIndex, max = pts.length; i < max; i++) {
+			if (i == max - 1) {
+				appendTypeSignatureForAnchor(pts[i], 0 , buffer, isVargArgs);
+			} else {
+				appendTypeSignatureForAnchor(pts[i], 0 , buffer, false);
+			}
+			if (i != pts.length - 1) {
+				buffer.append(',');
+				buffer.append(' ');
+			}
+		}
+		buffer.append(')');
+		char[] result = new char[buffer.length()];
+		buffer.getChars(0, buffer.length(), result, 0);
+		return result;
+	}
+
+	private static int appendTypeSignatureForAnchor(char[] string, int start, StringBuffer buffer, boolean isVarArgs) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (isVarArgs) {
+			switch (c) {
+				case Signature.C_ARRAY :
+					return appendArrayTypeSignatureForAnchor(string, start, buffer, true);
+				case Signature.C_RESOLVED :
+				case Signature.C_TYPE_VARIABLE :
+				case Signature.C_BOOLEAN :
+				case Signature.C_BYTE :
+				case Signature.C_CHAR :
+				case Signature.C_DOUBLE :
+				case Signature.C_FLOAT :
+				case Signature.C_INT :
+				case Signature.C_LONG :
+				case Signature.C_SHORT :
+				case Signature.C_VOID :
+				case Signature.C_STAR:
+				case Signature.C_EXTENDS:
+				case Signature.C_SUPER:
+				case Signature.C_CAPTURE:
+				default:
+					throw new IllegalArgumentException(); // a var args is an array type
+			}
+		} else {
+			switch (c) {
+				case Signature.C_ARRAY :
+					return appendArrayTypeSignatureForAnchor(string, start, buffer, false);
+				case Signature.C_RESOLVED :
+					return appendClassTypeSignatureForAnchor(string, start, buffer);
+				case Signature.C_TYPE_VARIABLE :
+					int e = org.eclipse.jdt.internal.compiler.util.Util.scanTypeVariableSignature(string, start);
+					buffer.append(string, start + 1, e - start - 1);
+					return e;
+				case Signature.C_BOOLEAN :
+					buffer.append(BOOLEAN);
+					return start;
+				case Signature.C_BYTE :
+					buffer.append(BYTE);
+					return start;
+				case Signature.C_CHAR :
+					buffer.append(CHAR);
+					return start;
+				case Signature.C_DOUBLE :
+					buffer.append(DOUBLE);
+					return start;
+				case Signature.C_FLOAT :
+					buffer.append(FLOAT);
+					return start;
+				case Signature.C_INT :
+					buffer.append(INT);
+					return start;
+				case Signature.C_LONG :
+					buffer.append(LONG);
+					return start;
+				case Signature.C_SHORT :
+					buffer.append(SHORT);
+					return start;
+				case Signature.C_VOID :
+					buffer.append(VOID);
+					return start;
+				case Signature.C_CAPTURE :
+					return appendCaptureTypeSignatureForAnchor(string, start, buffer);
+				case Signature.C_STAR:
+				case Signature.C_EXTENDS:
+				case Signature.C_SUPER:
+					return appendTypeArgumentSignatureForAnchor(string, start, buffer);
+				default :
+					throw new IllegalArgumentException();
+			}
+		}
+	}
+	private static int appendTypeArgumentSignatureForAnchor(char[] string, int start, StringBuffer buffer) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch(c) {
+			case Signature.C_STAR :
+				return start;
+			case Signature.C_EXTENDS :
+				return appendTypeSignatureForAnchor(string, start + 1, buffer, false);
+			case Signature.C_SUPER :
+				return appendTypeSignatureForAnchor(string, start + 1, buffer, false);
+			default :
+				return appendTypeSignatureForAnchor(string, start, buffer, false);
+		}
+	}
+	private static int appendCaptureTypeSignatureForAnchor(char[] string, int start, StringBuffer buffer) {
+		// need a minimum 2 char
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_CAPTURE) {
+			throw new IllegalArgumentException();
+		}
+		return appendTypeArgumentSignatureForAnchor(string, start + 1, buffer);
+	}
+	private static int appendArrayTypeSignatureForAnchor(char[] string, int start, StringBuffer buffer, boolean isVarArgs) {
+		int length = string.length;
+		// need a minimum 2 char
+		if (start >= length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_ARRAY) {
+			throw new IllegalArgumentException();
+		}
+
+		int index = start;
+		c = string[++index];
+		while(c == Signature.C_ARRAY) {
+			// need a minimum 2 char
+			if (index >= length - 1) {
+				throw new IllegalArgumentException();
+			}
+			c = string[++index];
+		}
+
+		int e = appendTypeSignatureForAnchor(string, index, buffer, false);
+
+		for(int i = 1, dims = index - start; i < dims; i++) {
+			buffer.append('[').append(']');
+		}
+
+		if (isVarArgs) {
+			buffer.append('.').append('.').append('.');
+		} else {
+			buffer.append('[').append(']');
+		}
+		return e;
+	}
+	private static int appendClassTypeSignatureForAnchor(char[] string, int start, StringBuffer buffer) {
+		// need a minimum 3 chars "Lx;"
+		if (start >= string.length - 2) {
+			throw new IllegalArgumentException();
+		}
+		// must start in "L" or "Q"
+		char c = string[start];
+		if (c != Signature.C_RESOLVED && c != Signature.C_UNRESOLVED) {
+			throw new IllegalArgumentException();
+		}
+		int p = start + 1;
+		while (true) {
+			if (p >= string.length) {
+				throw new IllegalArgumentException();
+			}
+			c = string[p];
+			switch(c) {
+				case Signature.C_SEMICOLON :
+					// all done
+					return p;
+				case Signature.C_GENERIC_START :
+					int e = scanGenericEnd(string, p + 1);
+					// once we hit type arguments there are no more package prefixes
+					p = e;
+					break;
+				case Signature.C_DOT :
+					buffer.append('.');
+					break;
+				 case '/' :
+					buffer.append('/');
+					break;
+				 case Signature.C_DOLLAR :
+					// once we hit "$" there are no more package prefixes
+					/**
+					 * Convert '$' in resolved type signatures into '.'.
+					 * NOTE: This assumes that the type signature is an inner type
+					 * signature. This is true in most cases, but someone can define a
+					 * non-inner type name containing a '$'.
+					 */
+					buffer.append('.');
+				 	break;
+				 default :
+					buffer.append(c);
+			}
+			p++;
+		}
+	}
+	private static int scanGenericEnd(char[] string, int start) {
+		if (string[start] == Signature.C_GENERIC_END) {
+			return start;
+		}
+		int length = string.length;
+		int balance = 1;
+		start++;
+		while (start <= length) {
+			switch(string[start]) {
+				case Signature.C_GENERIC_END :
+					balance--;
+					if (balance == 0) {
+						return start;
+					}
+					break;
+				case Signature.C_GENERIC_START :
+					balance++;
+					break;
+			}
+			start++;
+		}
+		return start;
+	}
+
+	/*
+	 * This method adjusts the task tags and task priorities so that they have the same size
+	 */
+	public static void fixTaskTags(Map defaultOptionsMap) {
+		Object taskTagsValue = defaultOptionsMap.get(JavaCore.COMPILER_TASK_TAGS);
+		char[][] taskTags = null;
+		if (taskTagsValue instanceof String) {
+			taskTags = CharOperation.splitAndTrimOn(',', ((String) taskTagsValue).toCharArray());
+		}
+		Object taskPrioritiesValue = defaultOptionsMap.get(JavaCore.COMPILER_TASK_PRIORITIES);
+		char[][] taskPriorities = null;
+		if (taskPrioritiesValue instanceof String) {
+			taskPriorities = CharOperation.splitAndTrimOn(',', ((String) taskPrioritiesValue).toCharArray());
+		}
+		if (taskPriorities == null) {
+			if (taskTags != null) {
+				Util.logRepeatedMessage(TASK_PRIORITIES_PROBLEM, IStatus.ERROR, "Inconsistent values for taskTags (not null) and task priorities (null)"); //$NON-NLS-1$
+				defaultOptionsMap.remove(JavaCore.COMPILER_TASK_TAGS);
+			}
+			return;
+		} else if (taskTags == null) {
+			Util.logRepeatedMessage(TASK_PRIORITIES_PROBLEM, IStatus.ERROR, "Inconsistent values for taskTags (null) and task priorities (not null)"); //$NON-NLS-1$
+			defaultOptionsMap.remove(JavaCore.COMPILER_TASK_PRIORITIES);
+			return;
+		}
+		int taskTagsLength = taskTags.length;
+		int taskPrioritiesLength = taskPriorities.length;
+		if (taskTagsLength != taskPrioritiesLength) {
+			Util.logRepeatedMessage(TASK_PRIORITIES_PROBLEM, IStatus.ERROR, "Inconsistent values for taskTags and task priorities : length is different"); //$NON-NLS-1$
+			if (taskTagsLength > taskPrioritiesLength) {
+				System.arraycopy(taskTags, 0, (taskTags = new char[taskPrioritiesLength][]), 0, taskPrioritiesLength);
+				defaultOptionsMap.put(JavaCore.COMPILER_TASK_TAGS, new String(CharOperation.concatWith(taskTags,',')));
+			} else {
+				System.arraycopy(taskPriorities, 0, (taskPriorities = new char[taskTagsLength][]), 0, taskTagsLength);
+				defaultOptionsMap.put(JavaCore.COMPILER_TASK_PRIORITIES, new String(CharOperation.concatWith(taskPriorities,',')));
+			}
+		}
+	}
+	/**
+	 * Finds the IMethod element corresponding to the given selector, 
+	 * without creating a new dummy instance of a binary method. 
+	 * @param type the type in which the method is declared
+	 * @param selector the method name
+	 * @param paramTypeSignatures the type signatures of the method arguments
+	 * @param isConstructor whether we're looking for a constructor
+	 * @return an IMethod if found, otherwise null
+	 * @throws JavaModelException
+	 */
+	public static IMethod findMethod(IType type, char[] selector, String[] paramTypeSignatures, boolean isConstructor) 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
+				&& isConstructor
+				&& !Flags.isStatic(type.getFlags())) {
+			args = new String[paramTypeSignatures.length+1];
+			startingIndex = 1;
+			args[0] = Signature.createTypeSignature(enclosingType.getFullyQualifiedName(), true);
+		} else {
+			args = new String[paramTypeSignatures.length];
+		}
+		int length = args.length;
+		for(int i = startingIndex;	i< length ; i++){
+			args[i] = new String(paramTypeSignatures[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;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/VerificationInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/VerificationInfo.java
new file mode 100644
index 0000000..b276613
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/VerificationInfo.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.core.util.IConstantPool;
+import org.eclipse.jdt.core.util.IConstantPoolConstant;
+import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.IVerificationTypeInfo;
+
+public class VerificationInfo extends ClassFileStruct implements IVerificationTypeInfo {
+
+	private int tag;
+	private int offset;
+	private int constantPoolIndex;
+	private char[] classTypeName;
+	private int readOffset;
+
+	public VerificationInfo(
+			byte[] classFileBytes,
+			IConstantPool constantPool,
+			int offset) throws ClassFormatException {
+		final int t = u1At(classFileBytes, 0, offset);
+		this.tag = t;
+		this.readOffset = 1;
+		switch(t) {
+			case IVerificationTypeInfo.ITEM_OBJECT :
+				final int constantIndex = u2At(classFileBytes, 1, offset);
+				this.constantPoolIndex = constantIndex;
+				if (constantIndex != 0) {
+					IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(constantIndex);
+					if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
+						throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
+					}
+					this.classTypeName = constantPoolEntry.getClassInfoName();
+				}
+				this.readOffset += 2;
+				break;
+			case IVerificationTypeInfo.ITEM_UNINITIALIZED :
+				this.offset = u2At(classFileBytes, 1, offset);
+				this.readOffset += 2;
+		}
+	}
+
+	public int getTag() {
+		return this.tag;
+	}
+
+	public int getOffset() {
+		return this.offset;
+	}
+
+	public int getConstantPoolIndex() {
+		return this.constantPoolIndex;
+	}
+
+	public char[] getClassTypeName() {
+		return this.classTypeName;
+	}
+
+	public int sizeInBytes() {
+		return this.readOffset;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSet.java
new file mode 100644
index 0000000..7d0c885
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSet.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+/**
+ * A hashset whose values can be garbage collected.
+ */
+public class WeakHashSet {
+
+	public static class HashableWeakReference extends WeakReference {
+		public int hashCode;
+		public HashableWeakReference(Object referent, ReferenceQueue queue) {
+			super(referent, queue);
+			this.hashCode = referent.hashCode();
+		}
+		public boolean equals(Object obj) {
+			if (!(obj instanceof HashableWeakReference)) return false;
+			Object referent = get();
+			Object other = ((HashableWeakReference) obj).get();
+			if (referent == null) return other == null;
+			return referent.equals(other);
+		}
+		public int hashCode() {
+			return this.hashCode;
+		}
+		public String toString() {
+			Object referent = get();
+			if (referent == null) return "[hashCode=" + this.hashCode + "] <referent was garbage collected>"; //$NON-NLS-1$  //$NON-NLS-2$
+			return "[hashCode=" + this.hashCode + "] " + referent.toString(); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	HashableWeakReference[] values;
+	public int elementSize; // number of elements in the table
+	int threshold;
+	ReferenceQueue referenceQueue = new ReferenceQueue();
+
+	public WeakHashSet() {
+		this(5);
+	}
+
+	public WeakHashSet(int size) {
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.values = new HashableWeakReference[extraRoom];
+	}
+
+	/*
+	 * Adds the given object to this set.
+	 * If an object that is equals to the given object already exists, do nothing.
+	 * Returns the existing object or the new object if not found.
+	 */
+	public Object add(Object obj) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length,
+			index = (obj.hashCode() & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			Object referent;
+			if (obj.equals(referent = currentValue.get())) {
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		this.values[index] = new HashableWeakReference(obj, this.referenceQueue);
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+
+		return obj;
+	}
+
+	private void addValue(HashableWeakReference value) {
+		Object obj = value.get();
+		if (obj == null) return;
+		int valuesLength = this.values.length;
+		int index = (value.hashCode & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			if (obj.equals(currentValue.get())) {
+				return;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		this.values[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+	}
+
+	private void cleanupGarbageCollectedValues() {
+		HashableWeakReference toBeRemoved;
+		while ((toBeRemoved = (HashableWeakReference) this.referenceQueue.poll()) != null) {
+			int hashCode = toBeRemoved.hashCode;
+			int valuesLength = this.values.length;
+			int index = (hashCode & 0x7FFFFFFF) % valuesLength;
+			HashableWeakReference currentValue;
+			while ((currentValue = this.values[index]) != null) {
+				if (currentValue == toBeRemoved) {
+					// replace the value at index with the last value with the same hash
+					int sameHash = index;
+					int current;
+					while ((currentValue = this.values[current = (sameHash + 1) % valuesLength]) != null && currentValue.hashCode == hashCode)
+						sameHash = current;
+					this.values[index] = this.values[sameHash];
+					this.values[sameHash] = null;
+					this.elementSize--;
+					break;
+				}
+				if (++index == valuesLength) {
+					index = 0;
+				}
+			}
+		}
+	}
+
+	public boolean contains(Object obj) {
+		return get(obj) != null;
+	}
+
+	/*
+	 * Return the object that is in this set and that is equals to the given object.
+	 * Return null if not found.
+	 */
+	public Object get(Object obj) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (obj.hashCode() & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			Object referent;
+			if (obj.equals(referent = currentValue.get())) {
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+		WeakHashSet newHashSet = new WeakHashSet(this.elementSize * 2);		// double the number of expected elements
+		newHashSet.referenceQueue = this.referenceQueue;
+		HashableWeakReference currentValue;
+		for (int i = 0, length = this.values.length; i < length; i++)
+			if ((currentValue = this.values[i]) != null)
+				newHashSet.addValue(currentValue);
+
+		this.values = newHashSet.values;
+		this.threshold = newHashSet.threshold;
+		this.elementSize = newHashSet.elementSize;
+	}
+
+	/*
+	 * Removes the object that is in this set and that is equals to the given object.
+	 * Return the object that was in the set, or null if not found.
+	 */
+	public Object remove(Object obj) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (obj.hashCode() & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			Object referent;
+			if (obj.equals(referent = currentValue.get())) {
+				this.elementSize--;
+				this.values[index] = null;
+				rehash();
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer("{"); //$NON-NLS-1$
+		for (int i = 0, length = this.values.length; i < length; i++) {
+			HashableWeakReference value = this.values[i];
+			if (value != null) {
+				Object ref = value.get();
+				if (ref != null) {
+					buffer.append(ref.toString());
+					buffer.append(", "); //$NON-NLS-1$
+				}
+			}
+		}
+		buffer.append("}"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSetOfCharArray.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSetOfCharArray.java
new file mode 100644
index 0000000..6cdd530
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/WeakHashSetOfCharArray.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * A hashset of char[] whose values can be garbage collected.
+ */
+public class WeakHashSetOfCharArray {
+
+	public static class HashableWeakReference extends WeakReference {
+		public int hashCode;
+		public HashableWeakReference(char[] referent, ReferenceQueue queue) {
+			super(referent, queue);
+			this.hashCode = CharOperation.hashCode(referent);
+		}
+		public boolean equals(Object obj) {
+			if (!(obj instanceof HashableWeakReference)) return false;
+			char[] referent = (char[]) get();
+			char[] other = (char[]) ((HashableWeakReference) obj).get();
+			if (referent == null) return other == null;
+			return CharOperation.equals(referent, other);
+		}
+		public int hashCode() {
+			return this.hashCode;
+		}
+		public String toString() {
+			char[] referent = (char[]) get();
+			if (referent == null) return "[hashCode=" + this.hashCode + "] <referent was garbage collected>"; //$NON-NLS-1$  //$NON-NLS-2$
+			return "[hashCode=" + this.hashCode + "] \"" + new String(referent) + '\"'; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+	HashableWeakReference[] values;
+	public int elementSize; // number of elements in the table
+	int threshold;
+	ReferenceQueue referenceQueue = new ReferenceQueue();
+
+	public WeakHashSetOfCharArray() {
+		this(5);
+	}
+
+	public WeakHashSetOfCharArray(int size) {
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.values = new HashableWeakReference[extraRoom];
+	}
+
+	/*
+	 * Adds the given char array to this set.
+	 * If a char array that is equals to the given char array already exists, do nothing.
+	 * Returns the existing char array or the new char array if not found.
+	 */
+	public char[] add(char[] array) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length,
+			index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		this.values[index] = new HashableWeakReference(array, this.referenceQueue);
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+
+		return array;
+	}
+
+	private void addValue(HashableWeakReference value) {
+		char[] array = (char[]) value.get();
+		if (array == null) return;
+		int valuesLength = this.values.length;
+		int index = (value.hashCode & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			if (CharOperation.equals(array, (char[]) currentValue.get())) {
+				return;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		this.values[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+	}
+
+	private void cleanupGarbageCollectedValues() {
+		HashableWeakReference toBeRemoved;
+		while ((toBeRemoved = (HashableWeakReference) this.referenceQueue.poll()) != null) {
+			int hashCode = toBeRemoved.hashCode;
+			int valuesLength = this.values.length;
+			int index = (hashCode & 0x7FFFFFFF) % valuesLength;
+			HashableWeakReference currentValue;
+			while ((currentValue = this.values[index]) != null) {
+				if (currentValue == toBeRemoved) {
+					// replace the value at index with the last value with the same hash
+					int sameHash = index;
+					int current;
+					while ((currentValue = this.values[current = (sameHash + 1) % valuesLength]) != null && currentValue.hashCode == hashCode)
+						sameHash = current;
+					this.values[index] = this.values[sameHash];
+					this.values[sameHash] = null;
+					this.elementSize--;
+					break;
+				}
+				if (++index == valuesLength) {
+					index = 0;
+				}
+			}
+		}
+	}
+
+	public boolean contains(char[] array) {
+		return get(array) != null;
+	}
+
+	/*
+	 * Return the char array that is in this set and that is equals to the given char array.
+	 * Return null if not found.
+	 */
+	public char[] get(char[] array) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	private void rehash() {
+		WeakHashSetOfCharArray newHashSet = new WeakHashSetOfCharArray(this.elementSize * 2);		// double the number of expected elements
+		newHashSet.referenceQueue = this.referenceQueue;
+		HashableWeakReference currentValue;
+		for (int i = 0, length = this.values.length; i < length; i++)
+			if ((currentValue = this.values[i]) != null)
+				newHashSet.addValue(currentValue);
+
+		this.values = newHashSet.values;
+		this.threshold = newHashSet.threshold;
+		this.elementSize = newHashSet.elementSize;
+	}
+
+	/*
+	 * Removes the char array that is in this set and that is equals to the given char array.
+	 * Return the char array that was in the set, or null if not found.
+	 */
+	public char[] remove(char[] array) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				this.elementSize--;
+				this.values[index] = null;
+				rehash();
+				return referent;
+			}
+			if (++index == valuesLength) {
+				index = 0;
+			}
+		}
+		return null;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer("{"); //$NON-NLS-1$
+		for (int i = 0, length = this.values.length; i < length; i++) {
+			HashableWeakReference value = this.values[i];
+			if (value != null) {
+				char[] ref = (char[]) value.get();
+				if (ref != null) {
+					buffer.append('\"');
+					buffer.append(ref);
+					buffer.append("\", "); //$NON-NLS-1$
+				}
+			}
+		}
+		buffer.append("}"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
new file mode 100644
index 0000000..30fad38
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -0,0 +1,433 @@
+###############################################################################
+# Copyright (c) 2000, 2013 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# This is an implementation of an early-draft specification developed under the Java
+# Community Process (JCP) and is made available for testing and evaluation purposes
+# only. The code is not compatible with any specification of the JCP.
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+#        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+#                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
+###############################################################################
+
+### JavaModel messages.
+
+### hierarchy
+hierarchy_nullProject = Project argument cannot be null
+hierarchy_nullRegion = Region cannot be null
+hierarchy_nullFocusType = Type focus cannot be null
+hierarchy_creating = Creating type hierarchy...
+hierarchy_creatingOnType = Creating type hierarchy on {0}...
+
+### java element
+element_doesNotExist = {0} does not exist
+element_notOnClasspath = {0} is not on its project''s build path
+element_invalidClassFileName = {0} is not a valid class file name
+element_reconciling = Reconciling...
+element_attachingSource = Attaching source...
+element_invalidResourceForProject = Illegal argument - must be one of IProject, IFolder, or IFile
+element_nullName = Name cannot be null
+element_nullType = Type cannot be null
+element_illegalParent = Illegal parent argument
+
+### java model operations
+operation_needElements = Operation requires one or more elements
+operation_needName = Operation requires a name
+operation_needPath = Operation requires a path
+operation_needAbsolutePath = Operation requires an absolute path. Relative path specified was: ''{0}''
+operation_needString = Operation requires a String.
+operation_notSupported = Operation not supported for specified element type(s):
+operation_cancelled = Operation cancelled
+operation_nullContainer = Container cannot be null
+operation_nullName = Name cannot be null
+operation_copyElementProgress = Copying elements...
+operation_moveElementProgress = Moving elements...
+operation_renameElementProgress = Renaming elements...
+operation_copyResourceProgress = Copying resources...
+operation_moveResourceProgress = Moving resources...
+operation_renameResourceProgress = Renaming resources...
+operation_createUnitProgress = Creating a compilation unit...
+operation_createFieldProgress = Creating a field...
+operation_createImportsProgress = Creating imports...
+operation_createInitializerProgress = Creating an initializer...
+operation_createMethodProgress = Creating a method...
+operation_createPackageProgress = Creating a package declaration...
+operation_createPackageFragmentProgress = Creating package fragment(s)...
+operation_createTypeProgress = Creating a type...
+operation_deleteElementProgress = Deleting elements...
+operation_deleteResourceProgress = Deleting resources...
+operation_cannotRenameDefaultPackage = Default package cannot be renamed
+operation_pathOutsideProject = Path ''{0}'' must denote location inside project ''{1}''
+operation_sortelements = Sorting elements...
+
+### working copy
+workingCopy_commit = Committing working copy...
+
+### build status messages
+build_preparingBuild = Preparing to build {0}
+build_readStateProgress = Reading saved build state for project {0}
+build_saveStateProgress = Saving build state for project {0}
+build_saveStateComplete = Saved in {0} ms
+build_readingDelta = Reading resource change information for {0}
+build_analyzingDeltas = Analyzing deltas
+build_analyzingSources = Analyzing sources
+build_cleaningOutput = Cleaning output folder for {0}
+build_copyingResources = Copying resources to the output folder
+build_compiling = Compiling {0}
+build_foundHeader = Found
+build_fixedHeader = Fixed
+build_oneError = 1 error
+build_oneWarning = 1 warning
+build_multipleErrors = {0} errors
+build_multipleWarnings = {0} warnings
+build_done = Build done
+
+### build errors
+build_wrongFileFormat = Wrong file format
+build_cannotSaveState = Error saving last build state for project {0}
+build_cannotSaveStates = Error saving build states
+build_initializationError = Builder initialization error
+build_serializationError = Builder serialization error
+
+### build inconsistencies
+build_classFileCollision = Class file collision: {0}
+build_duplicateClassFile = The type {0} is already defined
+build_duplicateResource = The resource is a duplicate of {0} and was not copied to the output folder
+build_inconsistentClassFile = A class file was not written. The project may be inconsistent, if so try refreshing this project and building it
+build_inconsistentProject = The project was not built due to "{0}". Fix the problem, then try refreshing this project and building it since it may be inconsistent
+build_incompleteClassPath = The project was not built since its build path is incomplete. Cannot find the class file for {0}. Fix the build path then try building this project
+build_missingSourceFile = The project was not built since the source file {0} could not be read
+build_prereqProjectHasClasspathProblems = The project was not built since it depends on {0}, which has build path errors
+build_prereqProjectMustBeRebuilt = The project cannot be built until its prerequisite {0} is built. Cleaning and building all projects is recommended
+build_abortDueToClasspathProblems = The project cannot be built until build path errors are resolved
+
+### status
+status_cannotUseDeviceOnPath = Operation requires a path with no device. Path specified was: {0}
+status_coreException = Core exception
+status_defaultPackageReadOnly = Default package is read-only
+status_evaluationError = Evaluation error: {0}
+status_JDOMError = JDOM error
+status_IOException = I/O exception
+status_indexOutOfBounds = Index out of bounds
+status_invalidContents = Invalid contents specified
+status_invalidDestination = Invalid destination: ''{0}''
+status_invalidName = Invalid name specified: {0}
+status_invalidPackage = Invalid package: {0}
+status_invalidPath = Invalid path: ''{0}''
+status_invalidProject = Invalid project: {0}
+status_invalidResource = Invalid resource: {0}
+status_invalidResourceType = Invalid resource type for {0}
+status_invalidSibling = Invalid sibling: {0}
+status_nameCollision = {0} already exists in target
+status_noLocalContents = Cannot find local contents for resource: {0}
+status_OK = OK
+status_readOnly = {0} is read-only
+status_targetException = Target exception
+status_updateConflict = Update conflict
+status_cannot_retrieve_attached_javadoc = Cannot retrieve the attached javadoc for {0}{1}
+status_unknown_javadoc_format = Unknown javadoc format for {0}
+status_timeout_javadoc = Timed out while retrieving the attached javadoc for {0}{1} 
+
+### classpath
+classpath_buildPath = Build path
+classpath_cannotNestEntryInEntry = Cannot nest ''{0}'' inside ''{1}''. To enable the nesting exclude ''{2}'' from ''{1}''
+classpath_cannotNestEntryInEntryNoExclusion= Cannot nest ''{0}'' inside ''{1}''. To allow the nesting enable use of exclusion patterns in the preferences of project ''{1}'' and exclude ''{2}'' from ''{1}''
+classpath_cannotNestEntryInLibrary = Cannot nest ''{0}'' inside library ''{1}''
+classpath_cannotNestEntryInOutput = Cannot nest ''{0}'' inside output folder ''{1}''
+classpath_cannotNestOutputInEntry = Cannot nest output folder ''{0}'' inside ''{1}''
+classpath_cannotNestOutputInOutput = Cannot nest output folder ''{0}'' inside output folder ''{1}''
+classpath_cannotReadClasspathFile = Unable to read ''.classpath'' file of project ''{0}''
+classpath_cannotReferToItself = Project ''{0}'' cannot reference itself
+classpath_cannotUseDistinctSourceFolderAsOutput = Source folder ''{0}'' in project ''{2}'' cannot output to distinct source folder ''{1}''
+classpath_cannotUseLibraryAsOutput = Source folder ''{0}'' in project ''{2}'' cannot output to library ''{1}''
+classpath_closedProject = Required project ''{0}'' needs to be open
+classpath_couldNotWriteClasspathFile = Could not write ''.classpath'' file of project ''{0}'': {1}
+classpath_cycle = A cycle was detected in the build path of project ''{0}''. The cycle consists of projects '{'{1}'}'
+classpath_duplicateEntryPath = Build path contains duplicate entry: ''{0}'' for project ''{1}''
+classpath_illegalContainerPath = Illegal classpath container path: ''{0}'' in project ''{1}'', must have at least one segment (containerID+hints)
+classpath_illegalEntryInClasspathFile = Illegal entry in ''.classpath'' of project ''{0}'' file: {1}
+classpath_illegalLibraryPath = Illegal path for required library: ''{0}'' in project ''{1}''
+classpath_illegalLibraryPathInContainer = Illegal path for required library: ''{0}'' in the {1}
+classpath_illegalLibraryArchive = Illegal type of archive for required library: ''{0}'' in project ''{1}''
+classpath_archiveReadError = Archive for required library: ''{0}'' in project ''{1}'' cannot be read or is not a valid ZIP file
+classpath_illegalExternalFolder = Required library cannot denote external folder: ''{0}'' for project ''{1}''
+classpath_illegalExternalFolderInContainer = Required library cannot denote external folder: ''{0}'' in the {1}
+classpath_illegalProjectPath = Illegal path for required project: ''{0}'' in project ''{1}''
+classpath_illegalSourceFolderPath = Illegal path for required source folder: ''{0}'' in project ''{1}''
+classpath_illegalVariablePath = Illegal classpath variable path: ''{0}'' in project ''{1}'', must have at least one segment
+classpath_invalidClasspathInClasspathFile = Invalid build path in ''.classpath'' file of project ''{0}'': {1}
+classpath_invalidContainer = Invalid classpath container: ''{0}'' in project ''{1}''
+classpath_mustEndWithSlash = End exclusion filter ''{0}'' with / to fully exclude ''{1}''
+classpath_unboundContainerPath = Unbound classpath container: ''{0}'' in project ''{1}''
+classpath_unboundLibrary = Project ''{1}'' is missing required library: ''{0}''
+classpath_userLibraryInfo = user library ''{0}''
+classpath_containerInfo = container ''{0}''
+classpath_unboundLibraryInContainer = The {1} references non existing library ''{0}''
+classpath_unboundProject = Project ''{1}'' is missing required Java project: ''{0}''
+classpath_settingOutputLocationProgress = Setting output location for: ''{0}''
+classpath_settingProgress = Setting classpath for: {0}
+classpath_unboundSourceAttachment = Invalid source attachment: ''{0}'' for required library ''{1}'' in project ''{2}''
+classpath_unboundSourceAttachmentInContainedLibrary = Invalid source attachment: ''{0}'' for required library ''{1}'' in the {2}
+classpath_unboundSourceFolder = Project ''{1}'' is missing required source folder: ''{0}''
+classpath_unboundVariablePath = Unbound classpath variable: ''{0}'' in project ''{1}''
+classpath_unknownKind = Unknown kind: ''{0}''
+classpath_xmlFormatError = XML format error in ''.classpath'' file of project ''{0}'': {1}
+classpath_disabledInclusionExclusionPatterns = Inclusion or exclusion patterns are disabled in project ''{1}'', cannot selectively include or exclude from entry: ''{0}''
+classpath_disabledMultipleOutputLocations = Multiple output locations are disabled in project ''{1}'', cannot associate entry: ''{0}'' with a specific output
+classpath_incompatibleLibraryJDKLevel = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' which requires a {3} runtime
+classpath_incompatibleLibraryJDKLevelInContainer = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' (from the {3}) which requires a {4} runtime
+classpath_duplicateEntryExtraAttribute = Duplicate extra attribute: ''{0}'' in classpath entry ''{1}'' for project ''{2}''
+classpath_deprecated_variable = Classpath variable ''{0}'' in project ''{1}'' is deprecated: {2}
+
+### miscellaneous
+buffer_closed=Buffer is closed
+file_notFound = File not found: ''{0}''
+file_badFormat = Bad format
+path_nullPath = Path cannot be null
+path_mustBeAbsolute = Path must be absolute
+cache_invalidLoadFactor = Incorrect load factor
+savedState_jobName = Processing Java changes since last activation
+refreshing_external_folders = Refreshing external folders
+updating_external_archives_jobName = Refreshing external archives
+
+## java model initialization
+javamodel_initialization = Initializing Java tooling
+javamodel_initializing_delta_state= Initializing delta state
+javamodel_configuring_searchengine=Configuring search engine
+javamodel_configuring_classpath_containers=Configuring classpath containers
+javamodel_getting_build_state_number=Getting build state version number
+javamodel_configuring=Configuring {0}
+javamodel_building_after_upgrade=Triggering build after upgrade
+javamodel_refreshing_external_jars=Refreshing external archives
+javamodel_resetting_source_attachment_properties=Resetting source attachment properties
+
+### java conventions
+convention_unit_nullName = Compilation unit name must not be null
+convention_unit_notJavaName = Compilation unit name must end with .java, or one of the registered Java-like extensions
+convention_classFile_nullName = .class file name must not be null
+convention_classFile_notClassFileName = .class file name must end with .class
+convention_illegalIdentifier = ''{0}'' is not a valid Java identifier
+convention_import_nullImport = An import declaration must not be null
+convention_import_unqualifiedImport = An import declaration must not end with an unqualified *
+convention_type_nullName = A Java type name must not be null
+convention_type_nameWithBlanks = A Java type name must not start or end with a blank
+convention_type_dollarName = By convention, Java type names usually don't contain the $ character
+convention_type_lowercaseName = By convention, Java type names usually start with an uppercase letter
+convention_type_invalidName = The type name ''{0}'' is not a valid identifier
+convention_package_nullName = A package name must not be null
+convention_package_emptyName = A package name must not be empty
+convention_package_dotName = A package name cannot start or end with a dot
+convention_package_nameWithBlanks = A package name must not start or end with a blank
+convention_package_consecutiveDotsName = A package name must not contain two consecutive dots
+convention_package_uppercaseName = By convention, package names usually start with a lowercase letter
+
+### DOM
+dom_cannotDetail = Unable to generate detailed source indexes
+dom_nullTypeParameter = Cannot add parameter with null type
+dom_nullNameParameter = Cannot add parameter with null name
+dom_nullReturnType = Return type cannot be null
+dom_nullExceptionType = Cannot add null exception
+dom_mismatchArgNamesAndTypes = Types and names must have identical length
+dom_addNullChild = Attempt to add null child
+dom_addIncompatibleChild = Attempt to add child of incompatible type
+dom_addChildWithParent = Attempt to add child that is already parented
+dom_unableAddChild = Attempt to add child to node that cannot have children
+dom_addAncestorAsChild = Attempt to add ancestor as child
+dom_addNullSibling = Attempt to insert null sibling
+dom_addSiblingBeforeRoot = Attempt to insert sibling before root node
+dom_addIncompatibleSibling = Attempt to insert sibling of incompatible type
+dom_addSiblingWithParent = Attempt to insert sibling that is already parented
+dom_addAncestorAsSibling = Attempt to insert ancestor as sibling
+dom_addNullInterface = Cannot add null interface
+dom_nullInterfaces = Illegal to set super interfaces to null
+
+### import rewrite
+importRewrite_processDescription = Updating imports
+
+### correction
+correction_nullRequestor = Requestor cannot be null
+correction_nullUnit = Compilation unit cannot be null
+
+### Eclipse Java Core Search messages.
+
+engine_searching = Searching...
+engine_searching_indexing = Looking through {0} indexes...
+engine_searching_matching = Locating {0} matches...
+exception_wrongFormat = Wrong format
+process_name = Java indexing
+jobmanager_filesToIndex = {1} files to index ({0})
+jobmanager_indexing = Java indexing... 
+
+### Disassembler messages
+
+### disassembler
+disassembler_description = Default classfile disassembler
+disassembler_opentypedeclaration =\ '{'
+disassembler_closetypedeclaration = }
+disassembler_parametername = arg
+disassembler_localvariablename = local_{0}
+disassembler_endofmethodheader = ;
+disassembler_begincommentline = //\ 
+disassembler_fieldhasconstant =\ =\ 
+disassembler_endoffieldheader = ;
+disassembler_sourceattributeheader = Compiled from\ 
+disassembler_enclosingmethodheader = Enclosing Method:
+disassembler_exceptiontableheader = Exception Table:
+disassembler_linenumberattributeheader = Line numbers:
+disassembler_localvariabletableattributeheader = Local variable table:
+disassembler_localvariabletypetableattributeheader = Local variable type table:
+disassembler_arraydimensions = []
+disassembler_innerattributesheader = Inner classes:
+disassembler_inner_class_info_name = inner class info:
+disassembler_outer_class_info_name = outer class info:
+disassembler_inner_name = inner name:
+disassembler_inner_accessflags = accessflags:\ 
+disassembler_genericattributeheader = Attribute: {0} Length: {1}
+disassembler_stackmaptableattributeheader = Stack map table: number of frames {0}
+disassembler_stackmapattributeheader =  Stack map : number of frames {0}
+disassembler_signatureattributeheader = // Signature: {0}
+disassembler_bootstrapmethodattributesheader = Bootstrap methods:
+disassembler_bootstrapmethodentry = {0} : # {1} arguments: {2}
+disassembler_bootstrapmethodentry_argument = #{0}
+disassembler_indentation = \  
+disassembler_constantpoolindex =\ #
+disassembler_space = \ 
+disassembler_comma = ,
+disassembler_openinnerclassentry = [
+disassembler_closeinnerclassentry = ]
+disassembler_deprecated =\ (deprecated)
+disassembler_constantpoolheader = Constant pool:
+disassembler_constantpool_class = constant #{0} class: #{1} {2}
+disassembler_constantpool_double = constant #{0} double: {1}
+disassembler_constantpool_float = constant #{0} float: {1}
+disassembler_constantpool_integer = constant #{0} integer: {1}
+disassembler_constantpool_long = constant #{0} long: {1}
+disassembler_constantpool_string = constant #{0} string: #{1} "{2}"
+disassembler_constantpool_fieldref = constant #{0} field_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_interfacemethodref = constant #{0} interface_method_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_methodref = constant #{0} method_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_name_and_type = constant #{0} name_and_type: #{1}.#{2} {3} {4}
+disassembler_constantpool_utf8 = constant #{0} utf8: "{1}"
+disassembler_constantpool_methodhandle = constant #{0} method handle: {1} #{2} 
+disassembler_constantpool_methodtype = constant #{0} method type: #{1} {2}
+disassembler_constantpool_invokedynamic = constant #{0} invoke dynamic: #{1} #{2} {3} {4}
+disassembler_annotationdefaultheader = Annotation Default:\ 
+disassembler_annotationdefaultvalue= {0} (constant type)
+disassembler_annotationenumvalue = {2}.{3}(enum type #{0}.#{1})
+disassembler_annotationclassvalue = {1} (#{0} class type)
+disassembler_annotationannotationvalue = annotation value =
+disassembler_annotationarrayvaluestart = [
+disassembler_annotationarrayvalueend = ]
+disassembler_annotationentrystart = #{0} @{1}(
+disassembler_annotationentryend = )
+# jsr308 (next two)
+disassembler_extendedannotationentrystart=#{0} @{1}(
+disassembler_extendedannotationentryend= )
+disassembler_annotationcomponent = #{0} {1}=
+disassembler_runtimevisibleannotationsattributeheader= RuntimeVisibleAnnotations:\ 
+disassembler_runtimeinvisibleannotationsattributeheader= RuntimeInvisibleAnnotations:\ 
+# jsr308 (next two)
+disassembler_runtimevisibletypeannotationsattributeheader= RuntimeVisibleTypeAnnotations:\ 
+disassembler_runtimeinvisibletypeannotationsattributeheader= RuntimeInvisibleTypeAnnotations:\ 
+disassembler_runtimevisibleparameterannotationsattributeheader= RuntimeVisibleParameterAnnotations:\ 
+disassembler_runtimeinvisibleparameterannotationsattributeheader= RuntimeInvisibleParameterAnnotations:\ 
+disassembler_parameterannotationentrystart=Number of annotations for parameter {0}: {1}
+disassembler_frame_same_locals_1_stack_item_extended=[pc: {0}, same_locals_1_stack_item_extended, stack: {1}]
+disassembler_frame_chop=[pc: {0}, chop {1} local(s)]
+disassembler_frame_same_frame_extended=[pc: {0}, same_extended]
+disassembler_frame_append=[pc: {0}, append: {1}]
+disassembler_method_type_ref_getfield = getfield ({0})
+disassembler_method_type_ref_putfield = putfield ({0})
+disassembler_method_type_ref_getstatic = getstatic ({0})
+disassembler_method_type_ref_putstatic = putstatic ({0})
+disassembler_method_type_ref_invokestatic = invokestatic ({0})
+disassembler_method_type_ref_invokevirtual = invokevirtual ({0})
+disassembler_method_type_ref_invokeinterface = invokeinterface ({0})
+disassembler_method_type_ref_invokespecial = invokespecial ({0})
+disassembler_method_type_ref_newinvokespecial = newinvokespecial ({0})
+# {0} = offset delta
+# {1} = number of locals
+# {2} = locals
+# {3} = number of stack items
+# {4} = stack items
+# {5} = line separator + tabs
+disassembler_frame_full_frame=[pc: {0}, full, stack: {4}, locals: {2}]
+disassembler_frame_same_frame=[pc: {0}, same]
+disassembler_frame_same_locals_1_stack_item=[pc: {0}, same_locals_1_stack_item, stack: {1}]
+# jsr308
+disassembler_extendedannotation_targetType=target type = 0x{0} {1}
+disassembler_extendedannotation_classextendsimplements=type index = {0}
+disassembler_extendedannotation_typepath=location = {0}
+disassembler_extendedannotation_method_parameter=method parameter index = {0}
+disassembler_extendedannotation_offset=offset = {0}
+disassembler_extendedannotation_throws=throws index = {0}
+disassembler_extendedannotation_type_argument=type argument index = {0}
+disassembler_extendedannotation_type_parameter=type parameter index = {0}
+disassembler_extendedannotation_type_parameter_with_bound=type parameter index = {0} type parameter bound index = {1}
+disassembler_extendedannotation_wildcardlocationtype=wildcard location type = 0x{0} {1}
+disassembler_extendedannotation_wildcardlocations=wildcard locations = {0}
+disassembler_extendedannotation_exception_table_index=exception table index = {0}
+disassembler_localvariabletargetheader=local variable entries:
+disassembler_extendedannotation_typepath_array=ARRAY
+disassembler_extendedannotation_typepath_innertype=INNER_TYPE
+disassembler_extendedannotation_typepath_wildcard=WILDCARD
+disassembler_extendedannotation_typepath_typeargument=TYPE_ARGUMENT({0})
+
+### classfileformat decoding
+classfileformat_versiondetails =\ (version {0} : {1}.{2}, {3})
+classfileformat_methoddescriptor = // Method descriptor #{0} {1}
+classfileformat_fieldddescriptor = // Field descriptor #{0} {1}
+classfileformat_stacksAndLocals= // Stack: {0}, Locals: {1}
+classfileformat_superflagisnotset = no super bit
+classfileformat_superflagisset = super bit
+classfileformat_clinitname = '{'}
+classformat_classformatexception = Class Format Exception
+classfileformat_versionUnknown = unknown
+
+### string displayed for each opcode
+classformat_anewarray = {0} {2} [{1}]
+classformat_checkcast = {0} {2} [{1}]
+classformat_instanceof = {0} {2} [{1}]
+classformat_ldc_w_class = {0} <Class {2}> [{1}]
+classformat_ldc_w_float = {0} <Float {2}> [{1}]
+classformat_ldc_w_integer = {0} <Integer {2}> [{1}]
+classformat_ldc_w_string = {0} <String "{2}"> [{1}]
+classformat_ldc2_w_long = {0} <Long {2}> [{1}]
+classformat_ldc2_w_double = {0} <Double {2}> [{1}]
+classformat_multianewarray = {0} {2} [{1}]
+classformat_new = {0} {2} [{1}]
+classformat_iinc = {0} {1} {2}{3}
+classformat_invokespecial ={0} {2} [{1}]
+classformat_invokeinterface ={0} {3} [{1}] [nargs: {2}]
+classformat_invokedynamic={0} {2} {3} [{1}]
+classformat_invokestatic ={0} {2} [{1}]
+classformat_invokevirtual ={0} {2} [{1}]
+classformat_getfield ={0} {2}.{3} : {4} [{1}]
+classformat_getstatic ={0} {2}.{3} : {4} [{1}]
+classformat_putstatic ={0} {2}.{3} : {4} [{1}]
+classformat_putfield ={0} {2}.{3} : {4} [{1}]
+classformat_newarray_boolean = {0} boolean [{1}]
+classformat_newarray_char = {0} char [{1}]
+classformat_newarray_float = {0} float [{1}]
+classformat_newarray_double = {0} double [{1}]
+classformat_newarray_byte = {0} byte [{1}]
+classformat_newarray_short = {0} short [{1}]
+classformat_newarray_int = {0} int [{1}]
+classformat_newarray_long = {0} long [{1}]
+classformat_store = {0}{1}
+classformat_load = {0}{1}
+classfileformat_anyexceptionhandler=any
+classfileformat_exceptiontableentry = [pc: {0}, pc: {1}] -> {2} when : {3}
+classfileformat_linenumbertableentry = [pc: {0}, line: {1}]
+classfileformat_localvariabletableentry = [pc: {0}, pc: {1}] local: {2} index: {3} type: {4}
+# jsr 308
+classfileformat_localvariablereferenceinfoentry=[pc: {0}, pc: {1}] index: {2}
+
+### Eclipse Java Core completion messages.
+engine_completing = Computing proposals...
+code_assist_internal_error=Code assist internal error
diff --git a/org.eclipse.jdt.core/notes/API_changes.html b/org.eclipse.jdt.core/notes/API_changes.html
new file mode 100644
index 0000000..0ae31a5
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/API_changes.html
@@ -0,0 +1,565 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Breaking API changes</title>
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
+</head>
+<body text="#000000" bgcolor="#FFFFFF">
+&nbsp;
+
+<table border=0 cellspacing=5 cellpadding=2 width="100%" >
+  <tr> 
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - Breaking API changes from R2.1 to R3.0</b></font>
+	</td>
+  </tr>
+  <tr>
+	<td align="left" width="72%" class="title2">
+	  <font size="-2" color="#8080ff">java development tooling core</font>
+	</td>
+  </tr>
+	<tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td align="left" width="72%" class="title3">
+	  <font size="-1">
+	  This document lists all API changes (breaking or not) that occured between R2.1 and R3.0 and how to migrate from the R2.1 API to
+	  the R3.0 API.
+	  </font>
+	</td>
+  </tr>
+</table>
+<hr><h1>New API on <code>org.eclipse.jdt.core.dom.AST</code></h1>
+	(in progress) Last edit: 2003/07/18
+<h2>Problem description</h2>
+	Creating an DOM/AST for a compilation unit costs a lot when the user wants only a subpart
+	of the compilation unit to be populated. For example, only the statements of one method are
+	useful and there is no need to create the statements of the other methods.
+	<p>
+	See also <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40474 ">bug 40474</a>.
+	</p>
+<h2>Problem resolution</h2>
+	Two new APIs have been added on <code>org.eclipse.jdt.core.dom.AST</code>.<br>
+	<ul>
+	<li><pre><code>public static org.eclipse.jdt.core.dom.CompilationUnit parsePartialCompilationUnit(
+		org.eclipse.jdt.core.ICompilationUnit unit,
+		int position,
+		boolean resolveBindings)</code>
+		</pre>
+	</li>
+	<li><pre><code>public static org.eclipse.jdt.core.dom.CompilationUnit parsePartialCompilationUnit(
+		org.eclipse.jdt.core.ICompilationUnit unit,
+		int position,
+		boolean resolveBindings,
+		org.eclipse.jdt.core.WorkingCopyOwner owner)</code>
+		</pre>
+	</ul>
+<h2>Converting to the new API</h2>
+	None.
+
+<hr><h1>IWorkingCopy is removed</h1>
+	(in progress) Last edit: 2003/07/03
+<h2>Problem description</h2>
+	Historically, <code>IWorkingCopy</code> gathered all working copy concerns, 
+	and <code>ICompilationUnit</code> implement this interface, though only the 
+	factory method makes sense for them; thus their implementation of the working 
+	copy features do nothing relevant to clients. <code>IWorkingCopy</code> also 
+	implements the spec'ed factory method, but it doesn't work for these.
+	<p>
+	See also <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36987 ">bug 36987</a>.
+	</p>
+<h2>Problem resolution</h2>
+	Interface <code>IWorkingCopy</code> is removed and all its functionality is moved to <code>ICompilationUnit</code>.
+<h2>Converting to the new API</h2>
+	Clients using <code>IWorkingCopy</code> and <code>ICompilationUnit</code> can
+	adapt to this change by referencing <code>ICompilationUnit</code> instead of 
+	<code>IWorkingCopy</code> when a working copy is needed.
+
+<hr><h1>Working copy factory methods return ICompilationUnit</h1>
+	(in progress) Last edit: 2003/07/03
+<h2>Problem description</h2>
+	Working copies were initialy designed to be editable elements on any <code>IJavaElement</code>.
+	Pratice showed that they were used only to edit <code>ICompilationUnit</code>. This imposed 
+	downcasting to <code>IWorkingCopy</code> when using the working copy factory methods.
+<h2>Problem resolution</h2>
+	Factory methods that create <code>ICompilationUnits</code> (i.e. 
+	<code>getWorkingCopy</code>) now return an <code>ICompilationUint</code> instead of an 
+	<code>IJavaElement</code>.
+<h2>Converting to the new API</h2>
+	Clients using factory methods to create working copies can now remove the cast from 
+	<code>IJavaElement</code> to <code>IWorkingCopy</code>, <code>ICompilationUint</code>
+	being compatible with <code>IWorkingCopy</code>.
+
+<hr><h1>CharOperation.pathMatch(...) treats non absolute pattern as Ant does</h1>
+	Last edit: 2003/06/11 (-&gt;M2)
+<h2>Problem description</h2>
+	<code>CharOperation.pathMatch(...)</code> used to treat non absolute pattern <code>'foo'</code>
+	as <code>'**/foo'</code> for free. This was inconsistent with Ant patternset rules.
+<h2>Problem resolution</h2>
+	<code>CharOperation.pathMatch(...)</code> no longer treat non absolute pattern <code>'foo'</code>
+	as <code>'**/foo'</code> for free. This has no incidence on
+	source folder exclusion patterns which are implicitely concatenating exclusion patterns to source folder
+	paths when using them. Only direct clients to this <code>CharOperation</code> API will be affected.
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Change in syntax error message ID</h1>
+	Last edit: 2003/06/11 (-&gt;M2)
+<h2>Problem description</h2>
+	TODO
+<h2>Problem resolution</h2>
+	The new diagnose of syntax errors use new error messages.
+	  <p>The following messages ID are added:</p>
+		<ul>
+			<li>IProblem.ParsingErrorInsertTokenBefore</li>
+			<li>IProblem.ParsingErrorInsertTokenAfter</li>
+			<li>IProblem.ParsingErrorDeleteToken</li>
+			<li>IProblem.ParsingErrorDeleteTokens</li>
+			<li>IProblem.ParsingErrorMergeTokens</li>
+			<li>IProblem.ParsingErrorInvalidToken</li>
+			<li>IProblem.ParsingErrorMisplacedConstruct</li>
+			<li>IProblem.ParsingErrorReplaceTokens</li>
+			<li>IProblem.ParsingErrorNoSuggestionForTokens</li>
+			<li>IProblem.ParsingErrorUnexpectedEOF</li>
+			<li>IProblem.ParsingErrorInsertToComplete</li>
+			<li>IProblem.ParsingErrorInsertToCompleteScope</li>
+			<li>IProblem.ParsingErrorInsertToCompletePhrase</li>
+		</ul>
+	  <p>The following messages ID are removed:</p>
+		<ul>
+			<li>IProblem.ParsingErrorNoSuggestion</li>
+			<li>IProblem.ParsingErrorOnKeyword</li>
+			<li>IProblem.ParsingErrorOnKeywordNoSuggestion</li>
+			<li>IProblem.UnmatchedBracket</li>
+			<li>IProblem.InvalidExpressionAsStatement</li>
+		</ul>
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Force reload of .classpath file</h1>
+	Last edit: 2003/06/12 (-&gt;M2)
+<h2>Problem description</h2>
+	TODO
+<h2>Problem resolution</h2>
+	Added API <code>IJavaProject#forceClasspathReload(IProgressMonitor)</code> to force reload of <code>.classpath</code> file
+	before next automatic update occurs.
+	<pre>
+/**
+ * Force the project to reload its <code>.classpath</code> file from disk and update the classpath accordingly.
+ * Usually, a change to the <code>.classpath</code> file is automatically noticed and reconciled at the next 
+ * resource change notification event. If required to consider such a change prior to the next automatic
+ * refresh, then this functionnality should be used to trigger a refresh. In particular, if a change to the file is performed,
+ * during an operation where this change needs to be reflected before the operation ends, then an explicit refresh is
+ * necessary.
+ * 
+ * @param monitor a progress monitor for reporting operation progress
+ * @exception JavaModelException if the classpath could not be updated. Reasons
+ * include:
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
+ *  - Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
+ *  - A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
+ *  - The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+ *  - The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
+ *  - The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+ *  - The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+ * @since 3.0
+ */
+	</pre>
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Allow empty path to be equivalent to no source attachment</h1>
+	Last edit: 2003/06/13 (-&gt;M2)
+<h2>Problem description</h2>
+	<code>JavaCore.newLibraryEntry(...)</code> used to not allow an empty source attachment (
+	<code>new Path("")</code>) to be equivalent to no source attachment (i.e. <code>null</code>). 
+	This adjustment is made necessary for library entries generated from classpath variables which cannot be set to 
+	<code>null</code>. Also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38531">38531</a>.
+<h2>Problem resolution</h2>
+	<code>JavaCore.newLibraryEntry(...)</code> will now allow an empty source attachment (
+	<code>new Path("")</code>) to be equivalent to no source attachment (i.e. <code>null</code>). 
+	<pre>
+* @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
+*    or <code>null</code> if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+*   and will be automatically converted to <code>null</code>.
+	</pre>
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Close the gap between compilation units and working copies</h1>
+	Last edit: 2003/06/27 (-&gt;M2)
+<h2>Problem description</h2>
+	TODO
+	<p>See also <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36888 ">bug 36888</a>.
+	</p>
+<h2>Problem resolution</h2>
+	The following new APIs are added to <code>ICompilationUnit</code>:
+	<ul>
+	<li><pre>
+/**
+ * Changes this compilation unit handle into a working copy. A new IBuffer is
+ * created using this compilation unit handle's owner. Uses the primary owner is none was
+ * specified when this compilation unit handle was created.
+ *
+ * When switching to working copy mode, problems are reported to given 
+ * IProblemRequestor.
+ *
+ * Once in working copy mode, changes to this compilation unit or its children are done in memory.
+ * Only the new buffer is affected. Using commitWorkingCopy(boolean, IProgressMonitor)
+ * will bring the underlying resource in sync with this compilation unit.
+ *
+ * If this compilation unit was already in working copy mode, an internal counter is incremented and no
+ * other action is taken on this compilation unit. To bring this compilation unit back into the original mode 
+ * (where it reflects the underlying resource), discardWorkingCopy must be call as many 
+ * times as becomeWorkingCopy.
+ * 
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to null indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if this compilation unit could not become a working copy.
+ * @see discardWorkingCopy
+ * @since 3.0
+ */
+void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	<li><pre>
+/**
+ * Commits the contents of this working copy to its underlying resource.
+ *
+ * It is possible that the contents of the original resource have changed
+ * since this working copy was created, in which case there is an update conflict.
+ * The value of the force parameter affects the resolution of
+ * such a conflict:
+ * - true - in this case the contents of this working copy are applied to
+ * 	the underlying resource even though this working copy was created 
+ * 	before a subsequent change in the resource
+ * - false - in this case a JavaModelException is thrown
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+ * @param force a flag to handle the cases when the contents of the original resource have changed
+ * since this working copy was created
+ * @param monitor the given progress monitor
+ * @exception JavaModelException if this working copy could not commit. Reasons include:
+ * - A CoreException occurred while updating an underlying resource
+ * - This element is not a working copy (INVALID_ELEMENT_TYPES)
+ * - A update conflict (described above) (UPDATE_CONFLICT)
+ * @since 3.0
+ */
+void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	<li><pre>
+/**
+ * Changes this compilation unit in working copy mode back to its original mode.
+ *
+ * This has no effect if this compilation unit was not in working copy mode.
+ * 
+ * If becomeWorkingCopy was called several times on this
+ * compilation unit, discardWorkingCopy must be called as 
+ * many times before it switches back to the original mode.
+ * 
+ * @see becomeWorkingCopy
+ * @exception JavaModelException if this working copy could not return in its original mode.
+ * @since 3.0
+ */
+void discardWorkingCopy() throws JavaModelException;
+	</pre></li>
+	<li><pre>
+/**
+ * Returns the working copy owner of this working copy.
+ * Returns null if it is not a working copy or if it has no owner.
+ * 
+ * @return WorkingCopyOwner the owner of this working copy or null
+ * @since 3.0
+ */
+WorkingCopyOwner getOwner();
+	</pre></li>	
+	<li><pre>
+/**
+ * Returns a new working copy of this element if this element is not
+ * a working copy, or this element if this element is already a working copy.
+ * 
+ * Note: if intending to share a working copy amongst several clients, then 
+ * getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor) 
+ * should be used instead.
+ * 
+ * When the working copy instance is created, an ADDED IJavaElementDelta is 
+ * reported on this working copy.
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+* @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if the contents of this element can
+ * 	not be determined. 
+ * @return a new working copy of this element if this element is not
+ * 	a working copy, or this element if this element is already a working copy
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException;
+	</pre></li>	
+	<li><pre>
+/**
+ * Returns a shared working copy on this element using the given working copy owner to create
+ * the buffer, or this element if this element is already a working copy.
+ * This API can only answer an already existing working copy if it is based on the same
+ * original compilation unit AND was using the same working copy owner (that is, as defined by Object.equals).	 
+ * 
+ * The life time of a shared working copy is as follows:
+ * - The first call to getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
+ *   creates a new working copy for this element
+ * - Subsequent calls increment an internal counter.
+ * - A call to discardWorkingCopy() decrements the internal counter.
+ * - When this counter is 0, the working copy is discarded.
+ * 
+ * So users of this method must discard exactly once the working copy.
+ *
+ * Note that the working copy owner will be used for the life time of this working copy, that is if the 
+ * working copy is closed then reopened, this owner will be used.
+ * The buffer will be automatically initialized with the original's compilation unit content
+ * upon creation.
+ * 
+ * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+ * working copy.
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+ * @param owner the working copy owner that creates a buffer that is used to get the content 
+ *  	of the working copy
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to null indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if the contents of this element can
+ *  	not be determined. 
+ * @return a new working copy of this element using the given factory to create
+ * the buffer, or this element if this element is already a working copy
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	</ul>
+And the following abstract class replaces <code>IBufferFactory</code>:
+	<pre>
+/**
+ * The owner of an ICompilationUnit handle in working copy mode. 
+ * An owner is used to identify a working copy and to create its buffer.
+ * 
+ * @see ICompilationUnit#becomeWorkingCopy
+ * @see ICompilationUnit#discardWorkingCopy
+ * @since 3.0
+ */
+public abstract class WorkingCopyOwner {
+	/**
+	 * Creates a buffer for the given working copy.
+	 * The new buffer will be initialized with the contents of the underlying file
+	 * if and only if it was not already initialized by the compilation owner (a buffer is 
+	 * uninitialized if its content is null).
+	 * 
+	 * @param workingCopy the working copy of the buffer
+	 * @return IBuffer the created buffer for the given working copy
+	 * @see IBuffer
+	 */
+	public IBuffer createBuffer(ICompilationUnit workingCopy) {
+		...
+	}
+}
+	</pre>
+	To generalize the usage of a working copy owner (entire JavaModel is now aware of owned working copies), new
+	APIs were added. These new APIs are copies of existing APIs augmented with a <code>WorkingCopyOwner</code> 
+	parameter, that defines the working copies to consider in the operation. 
+	When specifying an owner parameter, all working copies belonging to this owner will implicitly take precedence over primary ones
+	(without requiring the owner to remember all its working copies, as in 2.1 era). Note that when no owned working copy is found, a primary
+	unit will be considered instead, and since primary units have a built-in working copy (see <code>ICompilationUnit.becomeWorkingCopy(...)</code>),
+	the primary unit may already be in working copy mode (very likely since an editor got opened on it). This means that an owner will already 
+	transparently see unsaved editor contents for all units for which it has no better working copy to contribute.
+	The following new APIs were added:
+	<ul>
+		<li><code>AST.parseCompilationUnit(char[] source, String unitName, IJavaProject project, WorkingCopyOwner owner)</code></li>
+		<li><code>AST.parseCompilationUnit(IClassFile classFile, boolean resolveBindings, WorkingCopyOwner owner)</code></li>
+		<li><code>AST.parseCompilationUnit(ICompilationUnit unit, boolean resolveBindings, WorkingCopyOwner owner)</code></li>
+		<li><code>IEvaluationContext.codeComplete(String codeSnippet, int position, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+		<li><code>IEvaluationContext.codeSelect(String codeSnippet, int offset, int length, WorkingCopyOwner owner)</code></li>
+		<li><code>IDOMCompilationUnit.getCompilationUnit(IPackageFragment parent, WorkingCopyOwner owner)</code></li>
+		<li><code>ICodeAssist.codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+		<li><code>ICodeAssist.codeSelect(int offset, int length, WorkingCopyOwner owner)</code></li>
+		<li><code>ICompilationUnit.reconcile(boolean forceProblemDetection, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IJavaProject.findElement(IPath path, WorkingCopyOwner owner)</code></li>
+		<li><code>IJavaProject.findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner)</code></li>
+		<li><code>IJavaProject.findType(String fullyQualifiedName, WorkingCopyOwner owner)</code></li>
+		<li><code>IJavaProject.newTypeHierarchy(IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IJavaProject.newTypeHierarchy(IType type, IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IPackageFragment.getCompilationUnit(String name, WorkingCopyOwner owner)</code></li>
+		<li><code>IPackageFragment.getCompilationUnits(WorkingCopyOwner owner)</code></li>
+		<li><code>IType.codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+		<li><code>IType.newSupertypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IType.newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IType.newTypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+		<li><code>IType.resolveType(String typeName, WorkingCopyOwner owner)</code></li>
+		<li><code>JavaCore.create(IFile file, WorkingCopyOwner owner)</code></li>
+		<li><code>JavaCore.create(IResource resource, WorkingCopyOwner owner)</code></li>
+		<li><code>JavaCore.create(String handleIdentifier, WorkingCopyOwner owner)</code></li>
+		<li><code>JavaCore.createCompilationUnitFrom(IFile file, WorkingCopyOwner owner)</code></li>
+		<li><code>JavaCore.getWorkingCopies(WorkingCopyOwner owner)</code></li>
+		<li><code>SearchEngine.SearchEngine(WorkingCopyOwner workingCopyOwner)</code></li>
+		<li><code>SearchEngine.createHierarchyScope(IType type, WorkingCopyOwner owner)</code></li>
+	</ul>
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>IJavaElement.getResource() returns a non null value for working copies</h1>
+	Last edit: 2003/06/18 (-&gt;M2)
+<h2>Problem description</h2>
+	<code>IJavaElement.getResource()</code> was specified to return <code>null</code> for working copies. 
+	This didn't make sense as	this is a handle-only operation and an <code>IResource</code> is also a handle. 
+<h2>Problem resolution</h2>
+	This restriction was removed and <code>IJavaElement.getResource()</code> now returns a non-<code>null</code> 
+	value for a working copy.
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Rename getOriginalElement() into getPrimaryElement()</h1>
+	Last edit: 2003/06/20 (-&gt;M2)
+<h2>Problem description</h2>
+	The 2.1 API <code>IWorkingCopy.getOriginalElement()</code> returns an <code>IJavaElement</code>. In practice 
+	the original element for a working copy is always an <code>ICompilationUnit</code> whose owner is the primary owner. 
+<h2>Problem resolution</h2>
+	<code>getPrimary()</code> was added on <code>ICompilationUnit</code> to return an <code>ICompilationUnit</code>. 
+	This new API replaces <code>getOriginalElement()</code>.
+	<pre>
+/**
+ * Returns the primary compilation unit (whose owner is the primary owner)
+ * this working copy was created from, or this compilation unit if this a primary
+ * compilation unit.
+ * Note that the returned primary compilation unit can be in working copy mode.
+ * 
+ * @return the primary compilation unit this working copy was created from,
+ * or this compilation unit if it is primary
+ * @since 3.0
+ */
+ICompilationUnit getPrimary();
+	</pre>
+	In the same manner, <code>IWorkingCopy.getOriginalElement(IJavaElement)</code> is replaced with
+	<code>IJavaElement.getPrimaryElement()</code>.
+	<pre>
+/**
+ * Returns the primary element (whose compilation unit is the primary compilation unit)
+ * this working copy element was created from, or this element if it is a descendant of a
+ * primary compilation unit or if it is not a descendant of a working copy (e.g. it is a
+ * binary member).
+ * The returned element may or may not exist.
+ * 
+ * @return the primary element this working copy element was created from, or this
+ *		element.
+ * @since 3.0
+ */
+IJavaElement getPrimaryElement();
+	</pre>
+
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>JavaCore.newLibraryEntry(...) no longer accepts a relative source attachment path</h1>
+	Last edit: 2003/06/30 (-&gt;M2)
+<h2>Problem description</h2>
+	The API <code>JavaCore.newLibraryEntry(IPath path, IPath sourceAttachmentPath, IPath sourceAttachmentRootPath, boolean isExported)</code> 
+	for creating a library classpath entry with a source attachment used to accept a relative source attachment path. It was spec'ed as such, 
+	but its implementation was too permissive.
+<h2>Problem resolution</h2>
+	From 3.0 on, an <code>IllegalArgumentException</code> will be raised if a non-relative source attachment path is provided. 
+	Note that the only exception to this rule is an empty path (answering <code>true</code> to <code>IPath.isEmpty()</code>) which is 
+	now automatically translated into <code>null</code> denoting no source attachment.
+	In 3.0, a .classpath file will compact source attachments into project relative ones (as it does with other entry pathes already). During 
+	this process, relative pathes are known to be meaning project relative (internally when reading/writing the .classpath file). Externally, 
+	only absolute pathes are allowed to avoid confusion when reading/writing the .classpath file.
+	The tolerance for empty relative pathes comes from the fact that it is possible for variable classpath entries can be resolved to library entries 
+	with no classpath. Then the variable source attachment needs to be positionned to a value meaning no source (<code>null</code>). 
+	However, assigning a classpath variable to <code>null</code> is not allowed (nullification is used to remove variables),
+	thus an empty relative source path is tolerated to work around this limitation.
+<h2>Converting to the new API</h2>
+	TODO
+
+<hr><h1>Read <code>.classpath</code> file contents even if project has not the java nature yet</h1>
+	Last edit: 2003/09/01 (-&gt;M4)
+<h2>Problem description</h2>
+In 2.0 it was allowed to access IJavaProject.getOutputLocation/getRawClasspath on a project where the JavaNature was not set yet. Since 2.1 a
+JavaModelException is thrown if that happens.
+For example, the new Java project wizard does this if a .classpath file is found at the
+location where the project will be created.
+<h2>Problem resolution</h2>
+
+	Added API <code>IJavaProject#readRawClasspath()</code> to allow user to read the raw classpath from <code>.classpath</code> disk file
+	on a java project which java nature has not been set yet.
+	<pre>
+/**
+ * Returns the raw classpath for the project as defined by its <code>.classpath</code> file from disk, or <code>null</code>
+ * if unable to read the file. 
+ * 
+ * This classpath may differ from the in-memory classpath returned by <code>getRawClasspath</code>, in case the 
+ * automatic reconciliation mechanism has not been performed yet. Usually, any change to the <code>.classpath</code> file 
+ * is automatically noticed and reconciled at the next resource change notification event. 
+ * However, if the file is modified within an operation, where this change needs to be taken into account before the 
+ * operation ends, then the classpath from disk can be read using this method, and further assigned to the project 
+ * using <code>setRawClasspath(...)</code>.
+ * 
+ * A raw classpath may contain classpath variable and/or container entries. Classpath variable entries can be resolved 
+ * individually (see <code>JavaCore#getClasspathVariable</code>), or the full classpath can be resolved at once using the 
+ * helper method <code>getResolvedClasspath</code>.
+ * TODO (jim) please reformulate to include classpath containers in resolution aspects
+ * 
+ * Note that no check is performed whether the project has the Java nature set, allowing an existing <code>.classpath</code> 
+ * file to be considered independantly (unlike <code>getRawClasspath</code> which requires the Java nature to be associated 
+ * with the project). 
+ * 
+ * @return the raw classpath from disk for the project, as a list of classpath entries
+ * @see #getRawClassPath
+ * @see IClasspathEntry
+ * @since 3.0
+ */
+	</pre>
+
+	Added API <code>IJavaProject#readOutputLocation()</code> to allow user to read the output location from <code>.classpath</code> disk file
+	on a java project which java nature has not been set yet.
+	<pre>
+/**
+ * Returns the default output location for the project as defined by its <code>.classpath</code> file from disk, or <code>null</code>
+ * if unable to read the file. 
+ * 
+ * This output location may differ from the in-memory one returned by <code>getOutputLocation</code>, in case the 
+ * automatic reconciliation mechanism has not been performed yet. Usually, any change to the <code>.classpath</code> file 
+ * is automatically noticed and reconciled at the next resource change notification event. 
+ * However, if the file is modified within an operation, where this change needs to be taken into account before the 
+ * operation ends, then the output location from disk can be read using this method, and further assigned to the project 
+ * using <code>setRawClasspath(...)</code>.
+ * 
+ * The default output location is where class files are ordinarily generated
+ * (and resource files, copied). Each source classpath entry can also
+ * specify an output location for the generated class files (and copied
+ * resource files) corresponding to compilation units under that source
+ * folder. This makes it possible to arrange generated class files for
+ * different source folders in different output folders, and not
+ * necessarily the default output folder. This means that the generated
+ * class files for the project may end up scattered across several folders,
+ * rather than all in the default output folder (which is more standard).
+ * 
+ * @return the workspace-relative absolute path of the default output folder
+ * @see #getOutputLocation
+ * @since 3.0
+ */
+	</pre>
+<h2>Converting to the new API</h2>
+	TODO
+
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html
new file mode 100644
index 0000000..621c73d
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html
@@ -0,0 +1,4372 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>JDT/Core Release Notes</title>
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
+</head>
+
+<body 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 R2.0</b></font>
+	</td>
+  </tr>
+  <tr>
+  <td align="left" width="72%" class="title1">
+      <font size="-2" color="#8080ff">Java development tools core</font></td>
+  </tr>
+	<tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td align="left" width="72%" class="title3">
+	  <font size="-1">
+	  Here are the build notes for the Eclipse JDT/Core plug-in project 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
+	  describing bug resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
+	  Most recent information is listed first.
+	  <br>
+	  This present document covers all changes up to Release 2.0, changes which occurred since then in 2.1
+	  stream are described in <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html">build notes R2.1</a>.
+	  
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build GM5 - 27th June 2002 - RELEASE 2.0 (R2_0)
+<br>Project org.eclipse.jdt.core v_264
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Changed ASCII/binary property for 'about.html' file to ASCII.</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build GM4 - 26th June 2002
+<br>Project org.eclipse.jdt.core v_263
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20553">20553</a>  
+Doc - Javadocs of 2.0 classes must specify if the class is intended to be instantiated or subclassed by client.  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20442">20442</a>  
+Doc - Javadoc missing in ICodeSnippetRequestor  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20550">20550</a> 
+Doc - fields of CorrectionEngine should not be API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20872">20872</a>  
+Doc - the javadoc is not correct for ICodeAssist#codeSelect
+<br>
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20936">20936</a>  
+nullpointer exception in org.eclipse.jdt.internal.core.builder.JavaBuilder
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020624 - 24th June 2002
+<br>Project org.eclipse.jdt.core v_262
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Updated about.html file.
+</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020621 - 21st June 2002
+<br>Project org.eclipse.jdt.core v_261
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20693">20693</a>  
+Finding references to variables does not find all occurances
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20011">20011</a>  
+Searching for Inner Classes gives bad search results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20520">20520</a>  
+Refactor - expression detection incorrect
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20643">20643</a>  
+Java Projects disappear
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020620 - 20th June 2002
+<br>Project org.eclipse.jdt.core v_260
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20532">20532</a>  
+Declaration of member binary type not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19799">19799</a>  
+More problems with importing.  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16140">16140</a>
+Non-java project gets .classpath
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20659">20659</a>  
+Compile/rebuild analysis: white space causes large rebuild
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020618 - 18th June 2002
+<br>Project org.eclipse.jdt.core v_259
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Updated about.html file with reference to CPL 1.0.
+</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020617 - 17th June 2002
+<br>Project org.eclipse.jdt.core v_258
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed deprecated 2.0 temporary API: <code>IWorkingCopy#findSharedWorkingCopy()</code> which was no longer used anyway. Proper API is taking 
+a <code>IBufferFactory</code> in argument.</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20427">20427</a>
+J9c needs internal batch compiler methods to be public
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20309">20309</a>
+cannot code resolve on binary method with member type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20158">20158</a>
+Close and reopen a project does not remove errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20325">20325</a>
+CP Variable - should not persist "initialization in progress" value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20173">20173</a>
+Open type from a jar located inside a closed project.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20135">20135</a>
+2.0 deprecated method
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20359">20359</a>
+classpath variable ECLIPSE_HOME not initialized on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20261">20261</a>
+cycle in classpath detection seems overzealous
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19826">19826</a>
+livelock during indexing?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20048">20048</a>
+Minimize recompilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20053">20053</a>
+interface with same-named method generates compile error
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020612 - 12th June 2002 - FREEZE 3
+<br>Project org.eclipse.jdt.core v_257
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19537">19537</a>
+Internal error saving file (jzentry == 0)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19917">19917</a>
+Code Assist incorrect for hidden interface fields
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19916">19916</a>
+Error accessing value from uninitialized localvariable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19566">19566</a>
+Invalid ClassCastException thrown at runtime
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3306">3306</a>
+Can't compile JDK src
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19851">19851</a>
+IllegalArgumentException in refactor-extract method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7272">7272</a>
+Open on selection not working in external JARs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14219">14219</a>
+EOF exception after building in imported plugin with extracted source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18290">18290</a>
+Incorrect errors reported during reconciling
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020611 - 11th June 2002 
+<br>Project org.eclipse.jdt.core v_256
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added protection around listener callback invocations (using <code>ISafeRunnable</code>). </li>
+<li> Removed 2 unused deprecated constants on <code>IJavaSearchConstants</code>: READ_REFERENCES and WRITE_REFERENCES.
+They were annoted with intention to discard before 2.0 since were temporarily introduced and deprecated (due to bad naming).
+<pre>
+	/** 
+	 * @deprecated - use WRITE_ACCESSES instead (will be discarded before 2.0)
+	 * @since 2.0
+	 */
+	int WRITE_REFERENCES = WRITE_ACCESSES;
+	</pre></li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19714">19714</a>
+Eclipse crashes: Drag &amp; Drop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19794">19794</a>
+Method body change may result in massive recompilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18983">18983</a>
+Replacing binary project doesn't trigger build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18953">18953</a>
+Package disapears when disconnected from CVS repopsitory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19638">19638</a>
+Open Type Hierarchy can start infinite progress monitor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19687">19687</a>
+Preferences not working with import/export
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19512">19512</a>
+ArrayIndexOutOfBound during incremental build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18922">18922</a>
+Scrapbook does not come back when errors in snippet  
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19808">19808</a>
+core ClassCastException exception in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19882">19882</a>
+maybe a cu's single type can be its proimary type too
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19586">19586</a>
+Java project removed from Projects view
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15972">15972</a>
+JAR file from classpath not indexed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18680">18680</a>
+Classpath Loop
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020606 - 6th June 2002 
+<br>Project org.eclipse.jdt.core v_255
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed deprecated API on <code>IJavaProject</code>. These were not in 1.0, and shouldn't have been
+introduced (incorrectly resurrected from 0.9).
+  <ul>
+	<li><code>IJavaProject#getClasspath(...) --&gt; IJavaProject#getRawClasspath(...) </code></li>
+	<li><code>IJavaProject#setClasspath(...) --&gt; IJavaProject#setRawClasspath(...) </code></li>
+	<li><code>IJavaProject#newProjectEntry(...) --&gt; JavaCore#newProjectEntry(...) </code></li>
+	<li><code>IJavaProject#newLibraryEntry(...) --&gt; JavaCore#newLibraryEntry(...) </code></li>
+	<li><code>IJavaProject#newSourceEntry(...) --&gt; JavaCore#newSourceEntry(...) </code></li>
+  </ul>
+</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19303">19303</a>  
+Open type does not show all type.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14109">14109</a>  
+Deadlock between ProblemTreeViewer refresh and reconciler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19254">19254</a>  
+Some local variable completion proposals are missed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19131">19131</a>  
+NPE when removing a project containing missing classfile folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19058">19058</a>  
+Closing non-java project doesn't remove root from java project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18584">18584</a>  
+New 2.0 APIs marked as deprecated should be removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18698">18698</a>  
+Seeing non-java projects in package view
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18920">18920</a>  
+NPE searching for references to a message  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18749">18749</a>
+Missing java doc for IConstantPoolEntry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18583">18583</a>  
+New constants not tagged with @since 2.0  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18708">18708</a>
+DOM AST - IllegalArgumentException organizing imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18039">18039</a>
+Opening .class file fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18621">18621</a>
+Query all types when project is closed prevents reindexing when project is open  
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19271">19271</a>    
+IOException when searching for packages  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7916">7916</a>  
+Code assist does not find class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19424">19424</a>  
+JDT processing deltas for non-java files in non-java projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18633">18633</a>  
+Build failed: Can not find the class file for org.eclipse.jdt.core.jdom.IDOMInitializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18175">18175</a>  
+Quickfix false positives for non-public classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19293">19293</a>  
+cancelling compiling does not always cancel
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18539">18539</a>  
+unable to run JDBC program, class not found
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3292">3292</a>  
+Adding new class takes very long (&gt;20s) (1GEUGFQ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3333">3333</a>  
+JavaCore does not recognize dot notation for inner classes (1GI7GZG)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18507">18507</a>
+overwritting exiting file does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18414">18414</a>
+NLS Tools: Find strings and compiler warning out of synch 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5605">5605</a>    
+NPE restarting workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3252">3252</a>    
+Code assist list could be narrower in throws completion (1GD074C)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18724">18724</a>    
+Code for the static initializer is exceeding the 65535 bytes limit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3272">3272</a>    
+CodeCompletion - should only resolve interfaces (1GE5B8X)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6259">6259</a>    
+DCR: IClasspathEntry with JavaDoc location
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10007">10007</a>    
+NPE and ClassCastException when renaming class name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3222">3222</a>    
+JM - Reminder - re-enable transient reconciling marker  (1GAJ9FQ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3267">3267</a>    
+Deadlock while refreshing form local (1GDTUSD)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5583">5583</a>    
+getNonJavaResources does not return .class files for source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16371">16371</a>    
+Java Model Exception using code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17626">17626</a>    
+Auto-format source removed newline at end of range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8863">8863</a>    
+.classpath gets overwritten if there's an XML error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3335">3335</a>    
+Java Element Deltas: Performance issues with deltas from Working Copy (1GIE36J)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3253">3253</a>    
+SEVERE: Not all external JARs show up in packages view (1GD0JZO)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=1834">1834</a>    
+Cancel build with 10000+ problems takes forever to update (1G2Q9YZ)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020601 - 1st June 2002 - FREEZE 2
+<br>Project org.eclipse.jdt.core v_254
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The resource copy exclusion filter now tolerates whitespaces inside the filter pattern, they will be trimmed
+when used. e.g. "  .*   ,  foo/ " is now accepted.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18446">18446</a>  
+JavaCore.getClasspathContainer on not yest created project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18411">18411</a>  
+External JAR refresh - caching problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18453">18453</a>  
+Deleting project doesn't remove pkg fragment root in another project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18331">18331</a>    
+Java Model not flushed when upgrading binary projects  
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020531 - 31st May 2002 
+<br>Project org.eclipse.jdt.core v_253
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Changing 2.0 API for refreshing external JARs so as to pass in a collection of *elements* to restrain the scope
+of the update (see <code>IJavaModel#refreshExternalArchives(IJavaElement[],IProgressMonitor)</code>. Elements 
+can either be package fragment roots, projects or Java model.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18418">18418</a>  
+ search: searchDeclarationsOfReferencedTypes reports import declarations  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18287">18287</a>  
+&lt;Clinit&gt; change is treated as a structural change by incremental builder
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17766">17766</a>
+Strange error when launching Eclipse from inside Eclipse 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18396">18396</a>
+ant javac target ignores source="1.4" setting inside eclipse 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14187">14187</a>  
+error rebuilding project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14607">14607</a>  
+Refactor: rename isn't updating references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16172">16172</a>  
+Namelookup slow to retrieve package fragments 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18157">18157</a>    
+Internal Error when deleting project  
+ <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18259">18259</a>  
+changing classpath causes significant recompilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10394">10394</a>  
+symbolic links upset JRE path  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9302">9302</a>
+An unexpected exception has been detected in native code outside the VM
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020530 - 30th May 2002 
+<br>Project org.eclipse.jdt.core v_252
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Compiler can now optionally report unused imports. See option named "" on <code>JavaCore#getDefaultOptions</code> comment
+<pre>
+	 * COMPILER / Reporting Unused Import
+	 *    When enabled, the compiler will issue an error or a warning for unused import 
+	 *    reference 
+	 *     - option id:		"org.eclipse.jdt.core.compiler.problem.unusedImport"
+	 *     - possible values:	{ "error", "warning", "ignore" }
+	 *     - default:		"ignore"
+</pre>
+Note that if import problems (separate settings) are disabled, unused imports will not be reported either.
+This option is also available to the batch compiler ("-warn:unusedImports"). Implementations of <code>IProblemRequestor</code>
+can identify this new problem through its ID <code>IProblem#UnusedImport</code>.
+</li>
+<li>Added API on IType so as to tell whether a type is anonymous, local or member.</li>
+<li>Changing 2.0 API for refreshing external JARs so as to pass in a collection of projects to restrain the scope
+of the update (see <code>IJavaModel#refreshExternalJARs(IJavaProject[],IProgressMonitor)</code>. </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17906">17906</a>
+Rename package fails when inner classes are imported  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18255">18255</a>
+NPE during Organize imports.... See test5 in UI tests 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18169">18169</a>
+ast: incorrect length of SingleVariableDeclaration for some array declarations 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18138">18138</a>
+Resolving failure in variable declaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18135">18135</a>
+importing plugins resulted in 9MB of errors added to log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18190">18190</a>
+add a new PackageFragmentRoot does not update the name lookup of dependent projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15441">15441</a>
+Important: Problem highlight is out of sync with compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12649">12649</a>
+Missing import after move  
+   
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18042">18042</a>
+AST: Resolving failes with semicolon while loop body 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020529 - 29th May 2002 
+<br>Project org.eclipse.jdt.core v_251
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18078">18078</a>
+memory leak - destroy a WorkingCopy remove and re-add his buffer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16187">16187</a>
+Problems occured building seleted resources. MemberTypeBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18029">18029</a>
+disassembled code viewer handles \n incorrectly 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17922">17922</a>
+ClassCastException on rename temp 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18054">18054</a>
+JDT/Core is using the platform encoding instead of the encoding set in the UI
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17923">17923</a>
+Can't find refs to binary fields  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11823">11823</a>
+npe when trying to set source to rt.jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17609">17609</a>
+deleting a resource results does not change local history
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16120">16120</a>
+SelectionParser build wrong AST for instanceof statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14468">14468</a>
+F3 doesn't work on DefaultExceptionHandler
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14373">14373</a>
+Number of spaces representing a tab is alway 4 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6169">6169</a>
+Creating the tasks view hangs the UI thread
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18070">18070</a>
+NullPointerException during build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9173">9173</a>
+Exception about missing org.eclipse.core.boot\.classpath file?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15602">15602</a>
+OutOfMemoryError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15311">15311</a>
+Importing external plug-ins from file system fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13852">13852</a>
+Cannot generate EJB inheritance deployed code without debug info
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17046">17046</a>
+Inner class reference to Outer class method not recognized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17953">17953</a>
+NullPointerException when compiling cocoon2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17930">17930</a>
+Moving secondary types is fooling the java incremental builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17873">17873</a>
+Synchronize Comparison does poor job on .classpath files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16736">16736</a>
+Comment before package statement not associated with it 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12551">12551</a>
+Search finds some but not all method refs  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17254">17254</a>
+Could not find .classpath.
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020527 - 27th May 2002 
+<br>Project org.eclipse.jdt.core v_250
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API to retrieve cached flags on type hierarchies (see <code>ITypeHierarchy#getCachedFlags(IType)</code>). Note that these
+flags can help answering both isClass/isInterface queries as well (see <code>Flags.isInterface(int)</code></li>
+<li>Added API to trigger a Java model refresh with respect to external JARs: <code>IJavaModel#refreshExternalJARs</code>.
+<pre>
+/**
+ * Triggers an update of the JavaModel with respect to the referenced external JARs.
+ * This operation will issue a JavaModel delta describing the discovered changes, in term
+ * of Java element package fragment roots added, removed or changed.
+ * 
+ * @param monitor - a progress monitor used to report progress
+ * @exception JavaModelException in one of the corresponding situation:
+ *    - an exception occurs while accessing project resources 
+ * 
+ * @see IJavaElementDelta
+ * @since 2.0
+ */
+void refreshExternalJARs(IProgressMonitor monitor) throws JavaModelException;
+</pre>
+ </li><li>Added flag for notifying a JAR content change during Java delta notification: <code>IJavaElementDelta#F_ARCHIVE_CONTENT_CHANGED</code></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17097">17097</a>
+Searching for "*" in java gives a cryptic error message dialog.  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15162">15162</a>
+Assertion failure during shutdown  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17145">17145</a>
+NPE  while compiling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17807">17807</a>
+Incremental build problems deleting secondary types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17564">17564</a>
+Register java file types with the team plugin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17422">17422</a>
+JDT Compiler Adapter and compatibility with Ant 1.5 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17101">17101</a>
+Assertion failure during shutdown  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17562">17562</a>
+Race condition on startup leads to 2 JavaModel instances
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15395">15395</a>
+AssertionFailedException when creating new Java project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17797">17797</a>
+NullPointerException while building
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17827">17827</a>
+NullPointerException at  CompilationResult.computePriority
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16761">16761</a>
+NPE when doing Project -&gt; Rebuild All
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3329">3329</a>
+Specification for IJavaElementDelta needed (1GHVW5M)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16753">16753</a>
+Exception while building
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12159">12159</a>
+Code Format is generating bogus output 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16751">16751</a>
+Renaming a class doesn't update all references  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16789">16789</a>
+Incomplete project element if .classpath file isn't readable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16279">16279</a>
+compiler creates code that causes verifier error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14113">14113</a>
+Should listen to F_SOURCEATTACHED and F_SOURCEDETACHED java deltas  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15250">15250</a>
+Need a better mapping for the method free return opcode 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16091">16091</a>
+Need way to refresh JAR files
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16354">16354</a>
+Code Assist has too many items after throws
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16863">16863</a>
+type hierarchy misses types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14892">14892</a>
+Failed package import leads to OutOfMemory errors at compile time  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17197">17197</a>
+F1 - "Add Jars" to build path locks up eclipse - win2k
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15211">15211</a>
+NPE while searching for a field  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16494">16494</a>
+newSuperTypeHierarchy on binary type returns empty hierarchy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17127">17127</a>
+IllegalArgumentException in SimpleName.setIdentifier(SimpleName.java:136) in M5 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16857">16857</a>
+Empty folder creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16209">16209</a>
+Support declared packages that are different from directory location
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6068">6068</a>
+Walkback during plugin import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12985">12985</a>
+Unexpected full build in incremental mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11022">11022</a>
+Unexpected full build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16436">16436</a>
+CoreException importing org.eclipse.ui.win32
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12520">12520</a>
+JDTCompilerAdapter does not understand -extdirs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10047">10047</a>
+JDTCompilerAdapter  ignores -nowarn and deprecation off.
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020521 - 21st May 2002 
+<br>Project org.eclipse.jdt.core v_249 - MILESTONE 6 / FREEZE 1
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>'.classpath' file is now written using platform line delimiters (used to be only using LFs). It is recommanded to convert it to 'text' format
+so as to avoid surfacing delimiter differences in between incompatible platforms. </li>
+<li>The setting allowing for filtering resource copy now also supports folder filtering. Folder names are
+recognized by their '/' suffix, e.g. "META-INF/" specifies filtering out all folder named 'META-INF' (and their contents)</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3244">3244</a>
+Classpath is not saved using UTF8 (1GCV467)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13878">13878</a>
+Request to support folders for resource copy filters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16135">16135</a>
+Unexpected errors while reconciling
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020518 - 18th May 2002 
+<br>Project org.eclipse.jdt.core v_248
+<h2>
+What's new in this drop</h2>
+<ul><li>Added <code>ToolFactory.createDefaultClassFileReader(IClassFile classfile, int decodingFlag)</code> as an helper method to
+	create a classfile reader for classfile elements.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16130">16130</a>
+build xerces/plugin.properties slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16175">16175</a>
+NPE in IndexManager#checkIndexConsistency  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15563">15563</a>
+CompletionEngine does not report type packages of local variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12374">12374</a>
+NPE in ResultCollector
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15977">15977</a>
+NPE in Code Assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14037">14037</a>
+Internal Error doing java search 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16126">16126</a>
+ArrayIndexOutOfBoundsException during compilation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16132">16132</a>
+Error on Extract Method Refactoring 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16052">16052</a>
+NPE when search reference of a constructor  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15945">15945</a>
+Creating new class causes most projects to be recompiled
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9244">9244</a>
+Search Generates OutOfMemoryError  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15423">15423</a>
+JRE_LIB source attachment via properties does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15931">15931</a>
+Proposed results to limited/invalid
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16131">16131</a>
+Java search fails to find all references to static final MB_ADDITIONS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15192">15192</a>
+PackageFragment::copy never overwrites
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020515 - 15th May 2002 
+<br>Project org.eclipse.jdt.core v_247
+<h2>
+What's new in this drop</h2>
+<ul>
+    <li> New compiler option added to control max number of problems reported on a unit. Default is 100. See <code>JavaCore#getDefaultOptions()</code>
+    <pre>
+	 * COMPILER / Maximum number of problems reported per compilation unit
+	 *    Specify the maximum number of problems reported on each compilation unit.
+	 *     - option id:			"org.eclipse.jdt.core.compiler.maxProblemPerUnit"
+	 *     - possible values:	"&lt;n&gt;" where &lt;n&gt; is zero or a positive integer (if zero then all problems are reported).
+	 *     - default:			"100"
+    </pre> </li>
+    <li>By default, the Java builder is now aborting build process on projects with classpath problems. This option can be disabled through the Java preferences:
+    Window&gt;Preferences&gt;Java&gt;Builder&gt;</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16051">16051</a>
+DOM/AST: wrong position in if statement 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15788">15788</a>
+Walkbacks at startup  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16021">16021</a>
+Infinite loop in JavaCore.isReferencedBy(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14467">14467</a>
+Outliner doesn't highlight method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16017">16017</a>
+JavaBuilder reports  build failures on dependencies onto internal JARs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15568">15568</a>
+Watchpoints, method breakpoints in interesting locations not showing in editor ruler
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16801">16801</a>
+Compiler problem when */ appears in commented String.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12955">12955</a>
+Problem with Type Dialog and HierarchyScopes - build 20020214  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16016">16016</a>
+Opening a project after starting Eclipse misses project indexes (or other internal stuff)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15190">15190</a>
+Java Build errors after save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16008">16008</a>
+Hang during shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12392">12392</a>
+Problems to add Project from repository
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15103">15103</a>
+Search results are missing qualification
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020514 - 14th May 2002 
+<br>Project org.eclipse.jdt.core v_246
+<h2>
+What's new in this drop</h2>
+<ul>
+    <li>Java compiler never record more than 100 markers for compilation problems. All APIs using IProblemRequestor still
+    	see them all. This change is intended to prevent the task list from being overhelmed with tons of secondary problems. </li>
+	<li>Added APIs that allow to create a type hierarchy with a set of working copies that take precendence
+	      over their original compilation unit:
+	      <ul>
+	      	<li><code>IType.newSuperTypeHierarchy(IWorkingCopy[], IProgressMonitor)</code></li>
+	      	<li><code>IType.newTypeHierarchy(IWorkingCopy[], IProgressMonitor)</code></li>
+	      </ul>
+	      Note that change notification and refreshing is not supported on these hierarchies.
+	</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14051">14051</a>
+The implementation for IType.resolveType(String) is not implemented as noted in the JavaDoc specs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15322">15322</a>
+need a way to create a type hierarchy that considers working copies  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15142">15142</a>
+CCE in SourceConstructorDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15349">15349</a>
+JavaModelException out of Content assist  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15677">15677</a>
+Exception calling sourceType.getFields on working copy of new class  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15657">15657</a>
+IDOMMethod.getReturnType returns null for all methods 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15804">15804</a>
+DOM/AST: wrong Length in cascading if/then/else 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15400">15400</a>
+Compiler generates way too many errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15857">15857</a>
+Deadlock in the indexer.shutdown()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15756">15756</a>
+Organizing imports doesn't pick up the right type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15430">15430</a>
+hang up eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14965">14965</a>
+Search results in .class files don't select reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15690">15690</a>
+Classpath being set in wrong notification lifecycle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15810">15810</a>
+ClasspathContainer question
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15717">15717</a>
+I cant hold JDK Compiler Compliance level setting.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15448">15448</a>
+i keep loosing preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15113">15113</a>
+extract method: assertion failure 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8137">8137</a>
+Code assist for anonymous inner type too late
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15761">15761</a>
+Log message after importing plugins fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15852">15852</a>
+need set api on IClasspathEntry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15579">15579</a>
+Incomplete Java Error Message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13756">13756</a>
+Code Completion + Type Introspection  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3198">3198</a>
+Caller of Signature.toString(String) should be aware that it won't work for '$' separated top-level types (1G4QB2S) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15332">15332</a>
+Problem with "\\" in editor/compiler 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020507 - 7th May 2002 
+<br>Project org.eclipse.jdt.core v_245
+<h2>
+What's new in this drop</h2>
+<ul>
+	<li>Added org.eclipse.jdt.core.dom.Message#Message(String, int, int). This new constructor allows to set the length field. The constructor
+	org.eclipse.jdt.core.dom.Message#Message(String, int) still exists and set the length to 0. There is no need to use the new constructor if the length
+	is never used.</li>
+	<li>Renamed org.eclipse.jdt.core.dom.Message#getSourcePosition() to org.eclipse.jdt.core.dom.Message#getStartPosition(). This
+	is more consistent with the DOM/AST API. The old method has been deprecated and will be removed in a close future.</li>
+	<li>Added org.eclipse.jdt.core.dom.Message#getLength() allowing to retrieve the length of the node on which
+	the message has been reported.</li>
+	<li> Added <code>JavaCore#getSharedWorkingCopies(IBufferFactory)</code> allowing to retrieve all registered working
+		copies for a given buffer factory. </li>
+	<li> JavaBuilder no longer build projects for which prerequisite projects aborted the build process. This considerably
+		reduces the number of secondary errors when dealing with workspace setup problems.</li>
+	<li> Added <code>IWorkingCopy#reconcile(boolean forceProblemDetection, IProgressMonitor monitor)</code> allowing to force
+		problem refresh even if working copy was already consistent.
+    <li> Added <code>IClasspathContainer</code> new kind constant <code>K_DEFAULT_SYSTEM</code> to denote system libraries implicitely contributed
+    	by a runtime. </li>
+    <li> Classpath container path can have more than 2 segments. First one is still the container ID, the remaining ones are forming the hints
+    	passed to the resolution phase (<code>ClasspathContainerInitializer</code> </li>
+    <li> Classpath containers can no longer contain variable entries </li>
+	<li>JavaCore now persists its options (<code>JavaCore#getOptions</code>) using its plugin property store. Clients no longer need to save them. </li>
+	<li>JavaCore now provides constants for all supported option IDs and values.</li>
+	<li>JavaCore option added, to allow build to abort in presence of invalid classpath. 
+	<li>Leveraged new encoding support from Platform/Core. The JavaCore option "org.eclipse.jdt.core.encoding" is now equivalent to <code>ResourcesPlugin.getEncoding()</code>.
+	<pre>
+	 * BUILDER / Abort if Invalid Classpath
+	 *    Allow to toggle the builder to abort if the classpath is invalid
+	 *     - option id:        "org.eclipse.jdt.core.builder.invalidClasspath"
+	 *     - possible values:  { "abort", "ignore" }
+	 *     - default:          "ignore"
+	</pre>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15416">15416</a>
+Classpath container - need to set value even if not referenced
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15418">15418</a>
+Classpath container - may get the init-in-progress value back
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15334">15334</a>
+ast: Message should have length 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15364">15364</a>
+search for references of DebugUIPlugin.setAttributes(...) fails  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15175">15175</a>
+Need API to retrieve all shared working copies for a buffer factory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15254">15254</a>
+JavaModelManager thinks JavaProject is closed when it is open  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3356">3356</a>
+API - should provide API for running batch compiler (1GJIWDP)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15244">15244</a>
+NPE in JDTCompilerAdapter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15289">15289</a>
+Why is an incorrect package declaration not reported during reconciling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13225">13225</a>
+quick fix: shows up only after I save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15081">15081</a>
+JavaConventions.validateClasspath allows nesting source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15044">15044</a>
+Unable to view some non-java files in external jars  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15177">15177</a>
+Classpath markers not correctly updated  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15168">15168</a>
+circular errors not reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13957">13957</a>
+LaunchingPlugin specification of resourceCopyExclusionFilter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12977">12977</a>
+Adding Java nature to a project does not bring it to like in package view  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15107">15107</a>
+Internal Error organizing imports 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15030">15030</a>
+NPE trying to open or edit source files that reference jbuilder.jar 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14838">14838</a>
+Scrapbook editor: bad handling of // comment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12543">12543</a>
+Code assist to insert method does not work when there are extra top-level statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15061">15061</a>
+IllegalArgumentException in ASTNode.setSourceRange 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15036">15036</a>
+ASTVisitor.preVisit and ASTVisitor.postVisit not called correctly 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3193">3193</a>
+JM - ISourceManipulation.delete send replace-BufferChangedEvent (1FYE8XI)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15091">15091</a>
+Too many cycle markers generated when cycle is detected  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14754">14754</a>
+CodeAssist - Duplicate method declaration proposal inside anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15051">15051</a>
+Synthetic access methods are not reported to be synthetic
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3059">3059</a>
+JRE_LIB not appended to buildPath (1GF7TAZ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15050">15050</a>
+Cleanup Javadoc @exception tags in DOM/AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14151">14151</a>
+The code formatter does not respect the "maximum line length" property when the indentation is set to tabulation. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14974">14974</a>
+Bad generated code for '+=' and '-=' operators
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15719">15719</a>
+Errors during build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15087">15087</a>
+NPE when methods from the outermost enclosing class is invoked in a anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13057">13057</a>
+NPE in JavaElementRequestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11155">11155</a>
+ArrayIndexOutOfBounds exception that caused workbench to freeze
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12921">12921</a>
+Build sometimes builds files that have not changed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14962">14962</a>
+JDT Search returning improper type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14929">14929</a>
+External Locations for Output Files
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020430 - 30th April 2002 
+<br>Project org.eclipse.jdt.core v_243
+<h2>
+What's new in this drop</h2>
+<ul>
+	<li>Priority of the background indexer has been lowered so that
+	    it doesn't interfer with other threads (e.g. when switching JRE
+	    the indexing will not start before the switch has completed)
+	</li>
+	<li>Revised Classpath Container proposal (also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.eclipse.jdt.core/notes/r2.0/classpath%20container/classpathContainer.html">notes</a>):
+	<ul>
+	<li><code>classpathContainerChanged()</code> got replaced with setter method <code>JavaCore.setClasspathContainer(IPath containerPath, IJavaProject[] affectedProjects, IClasspathContainer respectiveContainers) </code></li>
+	<li><code>ClasspathContainerResolver</code> got renamed into <code>ClasspathContainerInitializer</code></li>
+	<li> Container can no longer contain any <code>CPE_SOURCE</code> entry.
+	<li> added container interface <code> IClasspathContainer </code> in order to allow containers to be presented in a UI.
+		  <ul>
+		  <li>IClasspathEntry[] getClasspathEntries() </li>
+		  <li>String getDescription() </li>
+		  <li>int getKind() </li>
+		  <li>Path getPath() </li>
+		 </ul>
+	</ul>
+	</li>
+	<li>If the completion is inside a super type in type declaration header then the relevance grow
+		when the type have the correct nature :
+		<ul>
+			<li> After <code>extends</code> keyword of a class header the relevance grow if the type is a class.
+			</li>
+			<li> After <code>implements</code> keyword of a class header the relevance grow if the type is an interface.
+			</li>
+			<li> After <code>extends</code> keyword of an interface header the relevance grow if the type is an interface.
+			</li>
+		</ul>
+	</li>
+	<li> If the completion is inside a type in a catch or throws clause the relevance grow when the type is an exception
+		(if the name of the type contain <code>exception</code> or <code>error</code>).
+	</li>
+	<li> If the completion is inside a throw statement the relevance grow when the proposal is an exception.
+	</li>
+	<li>The background indexer now recovers from internal crash. If this happens, 
+	    a new thread is created and a consistency check is done on all indexes.
+	</li>
+	<li>An internal buffer factory is now used to create buffers when
+	    clients don't provide one.
+	</li>
+	<li>Special handling in the formatter for //$NON-NLS- comments in the source. When a line contains such comments
+	it is not formatted anymore. The user will need to manually format it. See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14387">14387</a> and
+	<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=12540">12540</a>.
+	</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14933">14933</a>
+AST: No error message generated for unreachable code 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14921">14921</a>
+No error message from inner type instantiation in static context
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13919">13919</a>
+Declaration for package not found if scope is not project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14852">14852</a>
+Organize Import: missing import 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13531">13531</a>
+Java indexing thread finds "Bonjour, le monde!" too interesting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14878">14878</a>
+static final char NegThree= (char)-3, -3 == NegThree returns true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14331">14331</a>
+ICompilationUnit.getElementAt dos not find import decl  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14038">14038</a>
+ClassCastException during JavaReconciling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14011">14011</a>
+ASTNode.checkNewChild(ASTNode, ASTNode, boolean, Class) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13577">13577</a>
+Problem highlighter is unable to import from Java3D library.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14831">14831</a>
+NPE with hierarchy search of a local variable  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14243">14243</a>
+Applet Viewer Integration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14140">14140</a>
+ClassCastException when trying to open Java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14834">14834</a>
+smalltalk-ish error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11651">11651</a>
+Auto-complete shows all Object subclasses after "throws" keyword
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=4970">4970</a>
+Automatic Code Assist needs to be smarter #6
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8651">8651</a>
+Code assist should offer exception instead of any class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14767">14767</a>
+bug in IJavaProject.findType(String, String)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14642">14642</a>
+StringIndexOutOfBoundsException when attempting to view some classes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14558">14558</a>
+Adding binary project doesn't fix classpath problems.  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14588">14588</a>
+NullPointerException in Util.equalArraysOrNull  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13492">13492</a>
+Should handle JavaModelExceptions that contains CoreException more gracefully  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12540">12540</a>
+Code formatter should leave comments at end of line 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14387">14387</a>
+Formatter isn't //$NON-NLS-1$ aware
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14313">14313</a>
+DCR: AST in methods with missing return type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14094">14094</a>
+Indexer: Deadlock on delete project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14594">14594</a>
+"Open type" doesn't find types in project with Java nature added  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14602">14602</a>
+ast: length of variable declaration fragment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14592">14592</a>
+IType#getTypes and IType#getDeclaringType are not coherent with Hastable 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13868">13868</a>
+Java Model not updated properly  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13234">13234</a>
+Can't open type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9296">9296</a>
+Hang on open type during indexing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13916">13916</a>
+api: IScanner - Scanner.linePtr
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14526">14526</a>
+NPE when resolving a SimpleName 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11529">11529</a>
+ast: missing (?) binding on simpleName in VariableDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14453">14453</a>
+Remove InfixExpression.Operator.INSTANCEOF operator 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14490">14490</a>
+Possible concurrency hole when saving index before query  
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14844">14844</a>
+NPE creating binary projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14908">14908</a>
+100% CPU utilization, hang
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14733">14733</a>
+NPE setting marker attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13743">13743</a>
+(NPE) Eclipse froze during "open type"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14074">14074</a>
+Search: Not all refs to TwoPaneElementSelector constructor found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14889">14889</a>
+bug in IJavaProject.findType(String, String)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12439">12439</a>
+auto completion doesn't consistently work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14818">14818</a>
+no message for uncaught exception in try block when return in finally
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13810">13810</a>
+ClassCastException in indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13527">13527</a>
+NPE + GP switching JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14096">14096</a>
+IWorkingCopy.findElements should not return null  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13943">13943</a>
+Eclipse crashes when doing a "rebuild all"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14440">14440</a>
+Possible bug in compiling inner classes
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020508-M5patch" - 8th May 2002 
+<br>Project org.eclipse.jdt.core v_242b
+<h2>
+What's new in this drop</h2>
+<ul>
+	<li>Java builder is logging its internal errors </li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020423 - 23rd April 2002 
+<br>Project org.eclipse.jdt.core v_242a
+<h2>
+What's new in this drop</h2>
+<ul>
+	<li>Java model API additions:
+		<ul>
+			<li><code>IJavaProject.findType(String)</code></li>
+			<li><code>IJavaProject.findType(String, String)</code></li>
+			<li><code>IMethod.isMainMethod()</code></li>
+			<li><code>IMethod.isSimilar(IMethod)</code></li>
+			<li><code>IType.getFullyQualifiedName(char)</code></li>
+			<li><code>IType.getTypeQualifiedName(char)</code></li>
+		</ul>
+	</li>
+	<li>API change: <code>IWorkingCopy.findSharedWorkingCopy()</code> is now taking an extra argument: the buffer factory it is associated with. This ensures that
+		working copies can only be reused for the same buffer factories.
+	</li>
+	<li> JavaModelOperations now guarantee the JavaModel is up to date when notifying the Java model change listeners. In particular,
+	a builder running after the Java builder will be able to query the Java model with respect to the changes introduced through Java model
+	operations (except for index queries). This was never guaranteed in 1.0, but indirectly occurred due to the fact that the previous Java
+	builder implementation did force to refresh the Java model while building. </li>
+	<li>Classpath Container Enhancement (also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.eclipse.jdt.core/notes/r2.0/classpath%20container/classpathContainer.html">notes</a>):
+	<br>Added new type of classpath entry (<code>CPE_CONTAINER</code>), (see proposal here) so as to better encapsulate client defined libraries.
+	Typically, VM installs would use classpath containers instead of classpath variables (<code>JRE_LIB</code>) so as to better describe the corresponding
+	set of libraries (including extension dirs) to be placed on the build path. 
+	<p>New APIs added to reflect this addition:
+	<ul>
+	<li><code>JavaCore.newContainerEntry(IPath containerPath)</code></li>
+	<li><code>JavaCore.newContainerEntry(IPath containerPath, boolean isExported)</code></li>
+	<li><code>JavaCore.classpathContainerChanged(IPath containerPath, IJavaElement scope) </code></li>
+	<li><code>ClasspathContainerResolver </code></li>
+	</ul>
+	</li>
+	<li>DOM/AST:<br>A new type of node has been added to handle properly the instanceof expression. So the new InstanceofExpression node 
+	replaced the usage of InfixExpression with the operator InfixExpression.Operator.INSTANCEOF. This operator has been
+	deprecated and is expected to be removed for the next integration build. See bug <A HREF="http://dev.eclipse.org/bugs/show_bug.cgi?id=14453">14453</a>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13807">13807</a>
+null binding returned for fully qualified array declaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14403">14403</a>
+ast: exception on creation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14229">14229</a>
+Failure writing to a read only .project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13905">13905</a>
+changes to read-only .classpath file are not thrown out
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6165">6165</a>
+handle read-only class path file in a graceful way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14322">14322</a>
+AST/DOM : IVariableBinding.getDeclaringClass() for 'length' field of an array return null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14343">14343</a>
+ClassFileReader.getEnclosingTypeName() should return null for anonymous types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12363">12363</a>
+Better integration of the batch compiler with ant javac task option -extdirs 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14217">14217</a>
+DOM/AST: wrong start position for expression statement 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14106">14106</a>
+Declarations in Hierarchy does not find declarations in hierarchy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13060">13060</a> 
+Type hierarchy on region populates Java Model cache for types in the region  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14117">14117</a>
+NPE importing binary projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14172">14172</a>
+Builder is setting source resources as derived!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3266">3266</a>
+Changing kind of classpath entry reports 1 delta (1GDTRTP)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13231">13231</a>
+Quick Fix: wrong proposal 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14141">14141</a>
+NullPointerException during search  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13831">13831</a>
+NPE in RegionBasedTypeHierarchy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12914">12914</a>
+Compiler cannot resolve javax.net
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13964">13964</a>
+Exception on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14198">14198</a>
+AST: CastExpression.getType().resolveBinding() is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13939">13939</a>
+DBCS: no error message to invalid character in java source 
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020418 - 18th April 2002 
+<br>Project org.eclipse.jdt.core v_241a
+<h2>
+What's new in this drop</h2>
+<ul>
+	<li>Changing the source attachement of a jar will now correctly fire source
+		attachment java deltas. The flags of these deltas are:
+		<ul>
+			<li><code>IJavaElementDelta.F_SOURCEATTACHED</code> if a source
+				has been attached to a jar and no source previously existed.
+			</li>
+			<li><code>IJavaElementDelta.F_SOURCEDETACHED</code> if a source
+				has been detached from a jar and no other source has been attached.
+			</li>
+			<li><code>IJavaElementDelta.F_SOURCEDETACHED | JavaElementDelta.F_SOURCEATTACHED</code> 
+				if an attached source has been changed.
+			</li>
+		</ul>
+	</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14023">14023</a>
+NPE in build notifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14115">14115</a>
+Changing source attachment should not fire a F_REMOVED_FROM_CLASSPATH delta  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14055">14055</a>
+NPE in JavaModelManager.getVariableAsXMLString
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14007">14007</a>
+StringLiteral.setLiteralValue does not do Unicode escaping 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14013">14013</a>
+Compiler should not consider 'this.CONST' as constant expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14008">14008</a>
+VariableBinding.getVariableId contains suspicious code 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13989">13989 </a>
+Package view doesn't refresh after JRE switching
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12588">12588</a>
+Good match marked as potential  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13143">13143</a>
+Binary constructor search does not work (ref &amp; decl)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13807">13807</a>
+null binding returned for fully qualified array declaration
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14103">14103</a>
+Too many dependents found when incrementally recompiling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=4384">4384</a>
+Setting classpath variables does two builds  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3285">3285</a>
+Why does change the source attachment trigger a build (1GEHXW3)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13906">13906</a>
+Compiler did not detect uncaught exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14019">14019</a>
+NPE with code assist working in an anonymous inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9263">9263</a>
+Code assist can't see other project's class folders  
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020416 - 16th April 2002 - MILESTONE 5
+<br>Project org.eclipse.jdt.core v_240
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Changed the package fragment caching policy so as to accomodate large workspaces. It used to be an overflowing LRU cache of size 1000
+package fragments. It now is a simple table, which is never emptied implicitly any longer. Memory overhead looks negligeable, and it allows to
+deal much better with very large workspaces. Other similar improvements were made on the same front so as to improve JRE switching with such
+workspaces.
+
+</li>
+<li> ElementChangedEvent got added notion of type (similar to IResourceChangeEvent), so as to better
+allow clients to react to JavaModel changes: 
+	<ul> 
+		<li> ElementChangedEvent.POST_CHANGE :  
+<pre>
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact 
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta</code>.
+	 *
+	 * Note: this notification occurs during the corresponding POST_CHANGE
+	 * resource change notification, and contains a full delta accounting for
+	 * any JavaModel operation  and/or resource change.
+	 *
+	 * @see IJavaElementDelta
+	 * @see IResourceChangeEvent
+	 * @see #getDelta
+	 * @since 2.0
+	 */
+	public static final int POST_CHANGE = 1;
+</pre>
+		</li>
+
+		<li> ElementChangedEvent.PRE_AUTO_BUILD 
+<pre>
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact 
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta</code>.
+	 *
+	 * Note: this notification occurs during the corresponding PRE_AUTO_BUILD
+	 * resource change notification. The delta which is notified here only contains
+	 * information relative to the previous JavaModel operations (i.e. ignores the
+	 * possible resources which have changed outside Java operations). In
+	 * particular, it is possible that the JavaModel be inconsistent with respect to
+	 * resources which got modified outside JavaModel operations (it will only be
+	 * fully consistent once the POST_CHANGE notification has occured).
+	 * 
+	 * @see IJavaElementDelta
+	 * @see IResourceChangeEvent
+	 * @see #getDelta
+	 * @since 2.0
+	 */
+	public static final int PRE_AUTO_BUILD = 2;
+</pre>
+		</li>
+
+		<li> ElementChangedEvent.RECONCILE 
+<pre>
+	/**
+	 * Event type constant (bit mask) indicating an after-the-fact 
+	 * report of creations, deletions, and modifications
+	 * to one or more Java element(s) expressed as a hierarchical
+	 * java element delta as returned by <code>getDelta</code>.
+	 *
+	 * Note: this notification occurs as a result of a working copy reconcile
+	 * operation.
+	 *
+	 * @see IJavaElementDelta
+	 * @see IResourceChangeEvent
+	 * @see #getDelta
+	 * @since 2.0
+	 */
+	public static final int POST_RECONCILE = 4;	
+</pre>
+		</li>
+	</ul>
+</li>	
+<li>	
+	Also added a corresponding API on JavaCore so as to allow registering a listener for a given type of event.
+	<pre>
+	/**
+	 * Adds the given listener for changes to Java elements.
+	 * Has no effect if an identical listener is already registered.
+	 * After completion of this method, the given listener will be registered for exactly the
+	 * the specified events.  If they were previously registered for other events, they
+	 * will be deregistered.  
+	 *
+	 * Once registered, a listener starts receiving notification of changes to
+	 * java elements in the model. The listener continues to receive 
+	 * notifications until it is replaced or removed. 
+	 * 
+	 * Listeners can listen for several types of event as defined in <code>ElementChangeEvent</code>.
+	 * Clients are free to register for any number of event types however if they register
+	 * for more than one, it is their responsibility to ensure they correctly handle the
+	 * case where the same java element change shows up in multiple notifications.  
+	 * Clients are guaranteed to receive only the events for which they are registered.
+	 *
+	 * 
+	 * @param listener the listener
+	 * @param eventMask the bit-wise OR of all event types of interest to the listener
+	 * @see IElementChangeListener
+	 * @see ElementChangeEvent
+	 * @see #removeElementChangeListener
+	 *	@since 2.0
+	 */
+	public static void addElementChangedListener(IElementChangedListener listener, int eventMask)
+	</pre>
+
+</li>	
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12353">12353</a>
+DocumentAdapter can never be closed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9628">9628</a>
+Switching JRE is slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11585">11585</a>
+Large # of projects lock essential operations in the Workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13393">13393</a>
+Extremely poor java editor performance in 2002040x
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13233">13233</a>
+IllegalArgumentException on variable declaration in evaluation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13625">13625</a>
+Remove deprecated method from AST/DOM 
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13593">13593</a>
+Code Formatter formats synchronized incorrectly. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12921">12921</a>
+Build sometimes builds files that have not changed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13522">13522</a>
+NPE on anonymous class code assist.
+
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020411 - 11th April 2002 
+<br>Project org.eclipse.jdt.core v_239
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added a first proposal for .class file reading APIs. This is still experimental and might change slightly.
+See new API in org.eclipse.jdt.core.util.
+<ul>
+<li>ByteCodeVisitorAdapter</li>
+<li>ClassFormatException</li>
+<li>DecodingFlag</li>
+<li>IAttributeNamesConstants</li>
+<li>IBytecodeVisitor</li>
+<li>IClassFileAttribute</li>
+<li>IClassFileDisassembler and ToolFactory#createDefaultClassFileDisassembler</li> 
+<li>IClassFileReader</li>
+<li>ICodeAttribute</li>
+<li>IConstantPool</li>
+<li>IConstantPoolConstant</li>
+<li>IConstantPoolEntry</li>
+<li>IConstantValueAttribute</li>
+<li>IExceptionAttribute</li>
+<li>IExceptionTableEntry</li>
+<li>IFieldInfo</li>
+<li>IInnerClassesAttribute</li>
+<li>IInnerClassesAttributeEntry</li>
+<li>ILineNumberAttribute</li>
+<li>ILocalVariableAttribute</li>
+<li>ILocalVariableTableEntry</li>
+<li>IMethodInfo</li>
+<li>IModifierConstants</li>
+<li>IOpcodeMnemonics</li>
+<li>ISourceAttribute</li>
+<li>OpcodeStringValues</li>
+</ul>
+The default implementations are in org.eclipse.jdt.internal.core.util. Any comment is welcome and related bugs 
+should be entered in JDT/Core.
+<li>Added char array based APIs on Signature. This APIs avoid creating needless Strings and
+	are thus much more performant than their String based equivalent.
+	<ul>
+		<li><code>createArraySignature(char[], int arrayCount)</code></li>
+		<li><code>createCharArrayTypeSignature(char[], boolean)</code></li>
+		<li><code>createMethodSignature(char[][], char[]) </code></li>
+		<li><code>getArrayCount(char[])</code></li>
+		<li><code>getElementType(char[])</code></li>
+		<li><code>getParameterCount(char[])</code></li>
+		<li><code>getParameterTypes(char[])</code></li>
+		<li><code>getQualifier(char[])</code></li>
+		<li><code>getReturnType(char[])</code></li>
+		<li><code>getSimpleName(char[])</code></li>
+		<li><code>getSimpleNames(char[])</code></li>
+		<li><code>toCharArray(char[], char[], char[][], boolean, boolean)</code></li>
+		<li><code>toCharArray(char[])</code></li>
+		<li><code>toQualifiedName(char[][])</code></li>
+	</ul>
+</li>
+<li>Removed temporary 2.0 API which were deprecated in previous builds:
+	<ul>
+		<li><code>IWorkingCopy#getSharedWorkingCopy(IProgressMonitor, IBufferFactory)</code>, use API with extra <code>IProblemRequestor</code></li>
+		<li><code>IWorkingCopy#getWorkingCopy(IProgressMonitor, IBufferFactory)</code>, use API with extra <code>IProblemRequestor</code></li>
+		<li><code>IWorkingCopy#reconcile(IProblemRequestor)</code>, use API with no <code>IProblemRequestor</code></li>
+	</ul>
+</li>	
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12762">12762</a>
+Performance - Signature#createTypeSignature should be implemented in term of char[]  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12688">12688</a>
+NPE with code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13408">13408</a>
+Subfolders of build folder are not marked as derived
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13355">13355</a>
+NPE during code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13391">13391</a>
+NPE doing code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13487">13487</a>
+NPE in CompletionEnige
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13395">13395</a>
+loading swt+examples with auto-build on causes deadlock (or takes a very long time)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13063">13063</a>
+NPE in extract method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13247">13247</a>
+IllegalArgumentException while creating AST 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13386">13386</a>
+'not implemented yet' surfaced on Display in debug 
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12617">12617</a>
+code assist: Proposals inside method parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12338">12338</a>
+Unnecessary recompilation when adding packages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12262">12262</a>
+Compiler Bug with import Statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7082">7082</a>
+NPE during build
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020409 - 9th April 2002 
+<br>Project org.eclipse.jdt.core v_238a
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Adding a new empty source folder no longer causes a full build. Only an incremental build is needed now.
+</li>
+<li>Java model API additions:
+	<ul>
+		<li><code>IJavaElement.getAncestor(int)</code></li>
+		<li><code>IJavaElement.getOpenable()</code></li>
+		<li><code>IJavaElement.getPath()</code></li>
+		<li><code>IJavaElement.getResource()</code></li>
+		<li><code>IJavaProject.isOnClasspath(IJavaElement)</code></li>
+		<li><code>IPackageFragmentRoot.getRawClasspathEntry()</code></li>
+		<li><code>IType.findMethods(IMethod)</code></li>
+		<li><code>IWorkingCopy.findElements(IJavaElement)</code></li>
+		<li><code>IWorkingCopy.findPrimaryType()</code></li>
+	</ul>
+</li>
+<li>ICompletionRequestor API change :
+	<ul>
+		<li> Added #beginReporting() and #endReporting() API on <code>IProblemRequestor</code>. #beginReporting is always called before restarting error detection. #endReporting is always called at the
+				end of detection.
+		</li>
+		<li> Added API for setting multiple classpath variables at once (<code>JavaCore#setClasspathVariables</code>, this allows to update
+			all affected projects exactly once, instead of iterating multiple times on each project (if it references the variable). This can improve performance
+			when setting JRE variables.
+		</li>
+		<li> Added a new parameter <code>relevance</code> to be able to sort proposal by degree of relevance.
+		<code>relevance</code> is a positive integer which are used for determine if this proposal is more relevant than another proposal.
+		This value can only be used for compare relevance. A proposal is more relevant than another if his relevance
+		value is higher.
+		<br>
+		<br><tt>ICompletionRequestor{</tt>
+		<br><tt>&nbsp;&nbsp;void acceptAnonymousType(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptClass(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptError(...);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptField(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptInterface(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptKeyword(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptLabel(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptLocalVariable(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptMethod(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptMethodDeclaration(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptModifier(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptPackage(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptType(..., <b>int relevance</b>);</tt>
+		<br><tt>&nbsp;&nbsp;void acceptVariableName(..., <b>int relevance</b>);</tt>
+		<br><tt>}</tt>
+		<br>
+		<br>
+		</li>
+		<li>
+		If the completion identifier and proposal are equal and the case match then the proposal relevance grow. Note that this isn't a 1.0 breaking API change, it
+		only affects the 2.0 new code assist API (i.e. still backward compatible with 1.0 clients) which hasn't yet reached stability, though it should be close to now.
+		</li>
+	</ul>
+</li>	
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12614">12614</a>
+Initializing JRE variables slow on plug-in activation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12986">12986</a>
+Creating a working copy does not involve the problem requestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12858">12858</a>
+Compiler Bug : Invalid Byte Code: 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11739">11739</a>
+Dead branches in package/project Hierarchy View  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12873">12873</a>
+CodeAssist : missing  proposal of method declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12007">12007</a>
+Source folder ending with .jar considered as JAR archive  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12908">12908</a>
+Build and save attempt fail with NPE and trying it many times crashs Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12246">12246</a>
+Packages view shows .class and .java files when JAR has source  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3349">3349</a>
+Need a IJavaElement.getUnderlyingResource that does not do the exists test (1GJ69GP)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12975">12975</a>
+jacks - qualified assignment to final field should be rejected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12969">12969</a>
+jacks - synchronized (void expression) should be rejected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12705">12705</a>
+Progress monitor cuts off package name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12767">12767</a>
+AST MethodBinding question
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9179">9179</a>
+DCR: Need IJavaSearchScope equals or encloses  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12444">12444</a>
+strange types names in ReorderParameters error dialog 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12781">12781</a>
+AST instanceof-InfixExpression: Cant resolve type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12778">12778</a>
+Typo in comment: InfixExpression.RIGHT_SHIFT_UNSIGNED 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12768">12768</a>
+IScanner doesn't let user state whether line separators are to be recorded
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12651">12651</a>
+NPE out of the CompletionEngine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12761">12761</a>
+Closing a top level binary type doesn't close the class files of its inner types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12760">12760</a>
+Type hierarchy missing anonymous binary type if closed  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12674">12674</a>
+Too many problems while reconciling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12373">12373</a>
+Assert$AssertionFailedException error while reconciling
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13059">13059</a>
+incorrect (?) code compiles
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12880">12880</a>
+SQLJ Support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12603">12603</a>
+Could not delete empty java file  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9600">9600</a>
+Field reference in working copy not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12995">12995</a>
+ToolFactory::createScanner - incorrect javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12933">12933</a>
+"Never used" variable warnings can't detect across scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5135">5135</a>
+Open Java editor on IResource.class do an error  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12809">12809</a>
+Unimplemented methods should not prevent class from running 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10421">10421</a>
+WSAD hang while setting buildpath  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12590">12590</a>
+Returning the type when local var is selected breaks refactoring
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12710">12710</a>
+Inconsistent behavior for the method IType.createField()
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020402 - 2nd April 2002 
+<br>Project org.eclipse.jdt.core v_237
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Improved specification of <code>IBuffer</code> by saying that:
+	<ul>
+		<li> Java model operations that manipulate an <code>IBuffer</code> (e.g. 
+			<code>IType.createMethod(...)</code>) ensures that the same line delimiter 
+			(i.e. either <code>"\n"</code> or <code>"\r"</code> or <code>"\r\n"</code>) is 
+			used accross the whole buffer. Thus these operations may change the line delimiter(s) 
+			included in the string to be append, or replaced.
+			However implementors of this interface should be aware that other clients of <code>IBuffer</code>
+			might not do such transformations beforehand.</li>
+		<li> <code>addBufferChangedListener</code> and <code>removeBufferChangedListener</code>
+			have no effect if the buffer is already closed.</li>
+		<li> Other operations that manipulate the buffer (like <code>setContent</code>
+			might throw a <code>RuntimeException</code> if called after the buffer
+			has been closed.</li>
+	</ul>
+</li>
+<li> IScanner API :
+	<ul>
+		<li> added <code>IScanner#getSource</code> so as to retrieve the scanner original source
+		<li> renamed <code>IScanner#setSourceBuffer</code> into <code>IScanner#setSource</code>
+	</ul>
+</li>	
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12454">12454</a>
+AST/DOM: IllegalArgumentException generated by bad source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12431">12431</a>
+Unclear compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12416">12416</a>
+Separate caching of project and pkg fragment root from caching of openables  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12457">12457</a>
+Need to synchronize JobManager.discardJobs(...)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12445">12445</a>
+Compiler Failure on reference to abstract interface method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12417">12417</a>
+api: IScanner, ITerminalSymbols - no way to get some tokens
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12419">12419</a>
+Weird secondary error in constructor reconciliation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12419">12419</a>
+api: IScanner - missing (?) getSourceBuffer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12380">12380</a>
+AST/DOM: resolveTypeBinding() on the second operand of a instanceof expression return null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9790">9790</a>
+Add constructors from superclass inserts in wrong place 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12387">12387</a>
+Out Of Memory error importing file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3423">3423</a>
+Need IConstants (1GKM51O)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11583">11583</a>
+Infinite loop in OverflowingLRUCache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12346">12346</a>
+Leaking closed buffers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11431">11431</a>
+Stepping from one case statement's break ends up in next case 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12326">12326</a>
+Bad line number information returned from CompilationUnit with no trailing newline
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3313">3313</a>
+Severe - Performance - Java Model redundancies (1GFKTUN)  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12470">12470</a>
+0214 - Walkback during encapsulate method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9179">9179</a>
+DCR: Need IJavaSearchScope equals or encloses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10307">10307</a>
+Code assist failed to search whole class path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7079">7079</a>
+Code formatting fails with java.lang.Error 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3255">3255</a>
+Reminder - re-enable transient marker generation during code-assist (1GDCXLB)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020426 - 26th April 2002 
+<br>Project org.eclipse.jdt.core v_236
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Reconciling with errors provide type errors in addition to syntax ones. This is still experimental,
+	and can be disabled by unchecking the editor preference for transient problems.
+</li>	
+<li>Performance improvement of index queries with the <code>WaitUntilReady</code> policy. 
+	The background indexer now takes all the CPU when another thread is waiting for it to 
+	finish indexing.
+    User will notice this improvement when doing a search or opening a type and there are 
+    still files to index.
+</li>
+<li>Scanner API
+	<ul>
+		<li>defined scanner API (see <code>org.eclipse.jdt.core.compiler.IScanner</code>). </li>
+		<li>added tool factory API (see <code>org.eclipse.jdt.core.ToolFactory#createScanner</code>), allowing to obtain
+			a scanner (implementing <code>IScanner</code> API). </li>
+	</ul>
+</li>
+<li> Code formatter API
+	<ul>
+		<li>defined code formatter API (see <code>org.eclipse.jdt.core.ICodeFormatter</code>). </li>
+		<li>added tool factory API (see <code>org.eclipse.jdt.core.ToolFactory#createCodeFormatter</code>), allowing to obtain
+			a code formatter (implementing <code>ICodeFormatter</code> API). Note that an extension point was also added
+			to allow client code to contribute a code formatter implementation. The code formatter extension point is named
+			<code>org.eclipse.jdt.core.codeFormatter</code>, also see associate comment in plugin.xml.</li>
+		<li>added tool factory API (see <code>org.eclipse.jdt.core.ToolFactory#createDefaultCodeFormatter</code>), allowing to obtain
+			a default code formatter (implementing <code>ICodeFormatter</code> API). </li>
+	</ul>
+</li>
+<li> Working Copy API : instead of passing a problem requestor (<code>org.eclipse.jdt.core.IProblemRequestor</code>) to working copy #reconcile(...)
+operation. The problem requestor is passed along at creation time. 
+	<ul>
+	<li>added IWorkingCopy.getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)</li>
+	<li>added IWorkingCopy.getSharedWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)</li>
+	</ul>
+	Previous API taking <code>IBufferFactory</code> got deprecated, they will be removed in a subsequent build.
+</li>	
+<li>Some internal classes got deprecated (as client code relies on them), since being surfaced:
+	<ul>
+		<li> <code>org.eclipse.jdt.internal.core.parser.InvalidInputException</code> <br>==&gt; <code>org.eclipse.jdt.core.compiler.InvalidInputException</code> </li>
+		<li> <code>org.eclipse.jdt.internal.core.parser.TerminalSymbols</code> <br>==&gt; <code>org.eclipse.jdt.core.compiler.ITerminalSymbols</code> </li>
+	</ul>
+	They will be removed in a subsequent build.
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3353">3353</a>
+API - Should provide api for formatting source (1GJIWCF)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3179">3179</a>
+Compiler - LF cannot run classes that miss implementations of an interface (1FNFVY8) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12199">12199</a>
+Generated classfiles should be tagged as derived resources
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11640">11640</a>
+Bug in the code formatter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10544">10544</a>
+Internal error creating long package name 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12140">12140</a>
+typo in IPackageFragmentRoot::createPackageFragment javadoc 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11422">11422</a>
+Attaching source when using variables to point to jars very unintuitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12000">12000</a>
+Main.compile does not close log file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6558">6558</a>
+Missing class path entries should be displayed as an error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3354">3354</a>
+API - should provide api for Scanning (1GJIWCT)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7496">7496</a>
+Interface shows as class under content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11475">11475</a>
+Code resolve reports types in security package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10899">10899</a>
+Can't open on selection for member type in binary class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12013">12013</a>
+JavaCore.getClasspathVariable fails on empty variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11845">11845</a>
+Internal Compiler Error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11922">11922</a>
+is this code reachable or not?
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12119">12119</a>
+Eclipse build slow on network
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7881">7881</a>
+IType.move() clobbers editing buffer of destination element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10703">10703</a>
+ast: no API to figure out the source range of 'super' keywords
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10983">10983</a>
+NullPointerException in JavaBuilder during Save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3355">3355</a>
+API - should provide API for source element parsing (1GJIWD8)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10955">10955</a>
+DCR - search: too limiting api of IJavaSearchScope  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8819">8819</a>
+Self hosting tool doesn't update search index
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11497">11497</a>
+Renaming project failed with Java Model Exception: Java Model Status [Name collision.]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12059">12059</a>
+api: JavaCore::getOptions should return Map, not Hashtable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12044">12044</a>
+Search for field reference broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11905">11905</a>
+DCR - provide scanning API
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020321 - 21st March 2002 - MILESTONE 4
+<br>Project org.eclipse.jdt.core v_235a
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12014">12014</a>
+No delta when adding package where src=bin and src!=proj  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11755">11755</a>
+resource copy filter and duplicated resource error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11640">11640</a>
+Bug in the code formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11860">11860</a>
+Cannot move a compilation unit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11627">11627</a>
+Refactoring: CCE in Pullup method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11735">11735</a>
+NPE selecting F3 in editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11854">11854</a>
+NPE on save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11805">11805</a>
+build output filter is ignored
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11568">11568</a>
+Code resolve does not work for changed constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11656">11656</a>
+Please add a ICompletionRequestorAdapter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9271">9271</a>
+NPE inspecting "null" in the expressions view 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11638">11638</a>
+ast: CompilationUnit::findDeclaringNode fails 
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11272">11272</a>
+slow context assist on method/field-rich classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11340">11340</a>
+open on selection does not work for binary types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11654">11654</a>
+NPE during build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11659">11659</a>
+ast: CompilationUnit::findDeclaringNode fails #2 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11086">11086</a>
+ClassFileCompilationUnit should implement IClassFile
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020319 - 19th March 2002
+<br>Project org.eclipse.jdt.core v_234
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> New API on IType for complete snippet in current type context. Code complete is performed against
+ source (if available) or against type structure
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <tt>void codeComplete(</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] snippet,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int insertion,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int position,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] localVariableTypeNames,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] localVariableNames,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] localVariableModifiers,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean isStatic,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ICompletionRequestor requestor) throws JavaModelException;</tt>
+<br>&nbsp;
+</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10318">10318</a>
+Feature Request: new Code Assist API required
+
+<h3>
+Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020318 - 18th March 2002
+<br>Project org.eclipse.jdt.core v_233
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added option to trace java search activity.
+    To enable it, see the following line in the org.eclipse.jdt.core/.options file:
+    <code>org.eclipse.jdt.core/debug/search=true</code>
+</li>
+<li>Added API <code>CorrectionEngine#computeCorrections(IProblem, ICompilationUnit, ICorrectionRequestor)</code>, allowing.
+to compute replacement corrections for IProblem(s) detected while reconciling.</li>
+<li>Added API <code>ISourceReference#exists()</code>, allowing.
+to check existency before invoking <code>ISourceReference</code> behavior. All implementations did already provide
+an <code>exists()</code> method since they also are implementing <code>IJavaElement</code>.</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11524">11524</a>
+api: IWorkingCopy:: getWorkingCopy() javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11511">11511</a>
+Compiler 1.4 fooled by extra interface methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11389">11389</a>
+Unused parameters not showing up as compiler warnings 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11410">11410</a>
+Exception in Java Builder when debug options turned off 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11285">11285</a>
+Potential NPE in CopyResourceElementsOperation.processPackageFragmentResource 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11440">11440</a>
+npe in rename temp 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11468">11468</a>
+NPE deleting project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11435">11435</a>
+compiler bug: overwriting implicitely abstract method in anonymous inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11250">11250</a>
+NPE in log after importing plugins  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11271">11271</a>
+Unable to delete a binary project in Java perspective  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11210">11210</a>
+ResourceDeltas are lost when merging deltas  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11371">11380</a>
+ast: missing binding for ConditionalExpression 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11371">11371</a>
+DOM/AST: node missing for super constructor call 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6243">6243</a>
+an ISourceReference API issue
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11296">11296</a>
+NPE during build
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3438">3438</a>
+OpenOnSelection - should be able to locate missing method by guessing (1GL186P)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11406">11406</a>
+ActionPerformed() method in AbstractAction not found 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3221">3221</a>
+JM - Deadlock while saving in Editor (1GAJ67W)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11201">11201</a>
+ClassCastException during build process
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020314 - 14th March 2002
+<br>Project org.eclipse.jdt.core v_232
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>IDOMFactory.createInterface()</code> and <code>IDOMFactory.createClass()</code>.
+See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10980">10980</a> for details.</li>
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11355">11355</a>
+OpenOnSelection unable to perform in single-type import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9232">9232</a>
+ICompilationUnit.delete() fails  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11176">11176</a>
+Organize imports misses org.eclipse.core.resources  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3224">3224</a>
+Tests - Re-enable reconciler tests (1GAKXZM)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10980">10980</a>
+JDT / factory for new interfaces would be nice 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10996">10996</a>
+createCompilationUnit doesn't behave as described in the documentation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11125">11125</a>
+DOM/AST: API request <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11277">11277</a>
+Difference in between outliner content and unit content
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10833">10833</a>
+Open type doesn't propose all type after a checkout  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11067">11067</a>
+Adding useful toString() method for each new DOM/AST nodes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9933">9933</a>
+Format does not handle synchronized keyword correctly 
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8675">8675</a>
+DCR - Code correction could suggest new element creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11341">11341</a>
+incorrect outline (i see only imports)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11217">11217</a>
+is double "; " on a return statement an error?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10031">10031</a>
+SEF ClassCastException 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020312 - 12th March 2002
+<br>Project org.eclipse.jdt.core v_231
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Performance improvement:
+     <ul>
+     	<li> Search doesn't populate the Java Model any longer. Thus the memory
+     	    used by a search operation can be reclaimed at the end. </li>
+     	<li> Access to zip and jar files has been improved, which should result
+     	     in better performance on a slow network. </li>
+     </ul>
+     </li>
+<li> Added flag <code>IJavaElementDelta.F_FINE_GRAINED</code> that indicates
+     that a fine-grained delta was computed for a given delta.
+     Clients can use this flag to find out if a compilation unit 
+     that have a <code>F_CONTENT</code> change should assume that there are 
+     no finer grained changes (<code>F_FINE_GRAINED</code> is set) or if 
+     finer grained changes were not considered (<code>F_FINE_GRAINED</code> 
+     is not set). 
+     </li>
+<li> Surfacing IProblem (<code>org.eclipse.jdt.core.compiler.IProblem</code>) 
+	<br>This allows some Java API to report failures in a lighter way than generating markers. Marker based API have been
+	deprecated (note that due to some deadlock in client code, some of these API did not even produce markers, e.g. reconciling). In addition to
+	surfacing problem descriptions, IProblem exposes all the IDs for the Java problem markers (attribute "id" on markers of type "org.eclipse.jdt.core.problem")</li>
+<li> Changed error reporting method for <code>ICompletionRequestor</code> to surface IProblems instead of IMarkers.</li>
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11191">11191</a>
+Strange anonymous types in outline structure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11151">11151</a>
+ast: IllegalArgumentException on AST creation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10538">10538</a>
+Possible memory leak?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10616">10616</a>
+StringIndexOutOfBoundsException opening type selection dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11152">11152</a>
+Code Select - does not work with empty selection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11129">11129</a>
+DOM/AST: Call resolveTypeBinding() on a CastExpression object throws a NullPoitnerException 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3256">3256</a>
+SearchableEnvironment - converts char[] to String, which affects performance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10984">10984</a>
+DOM/AST: CU with syntax errors 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11106">11106</a>
+DOM/AST: do statement doesn't contain trailing semicolon 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11104">11104</a>
+DOM/AST: NumberLiteral contains leading and trailing comments 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10213">10213</a>
+SearchEngine.createJavaSearchScope((IJavaElement[]) does not work for binary elements  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9240">9240</a>
+Search finds deleted classes  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11011">11011</a>
+incorrect 'variable never used' warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11025">11025</a>
+extract method: incorrectly disallowed on some boolean expressions 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10697">10697</a>
+Performance - Binary model should not cache the classfile bytes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11037">11037</a>
+DOM/AST: IllegalArgumentException when creatin AST 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10635">10635</a>
+Override methods not showing missing methods  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7930">7930</a>
+Code Assist - No completion in switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10979">10979</a>
+JDOM/add superinterface format problem 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10986">10986</a>
+DOM/AST: NPE when trying to resolve a binding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10580">10580</a>
+type hierarchy incorrect for nested types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10935">10935</a>
+DOM/AST: wrong length of variable declaration fragment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6111">6111</a>
+Missing completion 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10898">10898</a>
+DOM/AST: NullPointerException 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3261">3261</a>
+Search - Memory peak during search (1GEN17L)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6667">6667</a>
+Search: OutOfMemoryError searching wildcarded field ref  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10874">10874</a>
+DOM/AST: ClassInstanceCreation contains trailing comment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10881">10881</a>
+DOM/AST: SwitchCase.isDefault always returns false 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10865">10865</a>
+DOM/AST; AST.resolveWellKnownType("void") returns null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10861">10861</a>
+DOM/AST: TypeLiteral.resolveTypeBinding doesn't return class Class 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10819">10819</a>
+Incomplete task description after build with incomplete classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10468">10468</a>
+DOM/AST: TypeDeclaration#isLocalTypeDeclaration doesn't consider anonymous types 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10499">10499</a>
+DOM/AST: need a way to access the IMethodBinding of a ClassInstanceCreation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10496">10496</a>
+DOM/AST: need for a node that holds the body statements of a ClassInstanceCreation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10781">10781</a>
+ast: incorrect position and length for AnonymousClassDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10843">10843</a>
+DOM/AST: wrong structure for for statements 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10663">10663</a>
+ast: exception in AST converter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10759">10759</a>
+ast: incorrect length of SimpleName (subsubnode of ArrayType) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10500">10500</a>
+Shouldn't ignore inherited method with wrong argument types
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10627">10627</a>
+Rebuild Deletes non-Class Resources
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3233">3233</a>
+JM - CreateElementInCuOperation should not save working copy (1GBEKAW)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3445">3445</a>
+search: type hierarchy scope incorrect (1GLC8VS)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10954">10954</a>
+IMember::getFlags semantics on interface members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3195">3195</a>
+Unnecessary proposals in Open on selection whith syntax error (1G0EIBB)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10933">10933</a>
+DOM/AST: position of AnonymousTypeDeclaration is [-1,0] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10815">10815</a>
+Error message for "incomplete path" lacks details
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10913">10913</a>
+DOM/AST: resolveBinding() for static field access 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10698">10698</a>
+DOM/AST: exception when creating AST 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=4946">4946</a>
+Cross-project builder efficiency issues
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3213">3213</a>
+No compile error for bad interface (1G7G6M1)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10667">10667</a>
+NPE in self encapsulate field 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10389">10389</a>
+Editing non-Java files causes a recompile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10313">10313</a>
+Can not create Java project from existing source (1000+ Java files)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10794">10794</a>
+NPE from search during refactor, pull up method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10699">10699</a>
+ast: nothing in anonymous inner classes is created 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020305 - 5th March 2002
+<br>Project org.eclipse.jdt.core v_230
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added API <code>IClassFile.getWorkingCopy(IProgressMonitor, IBufferFactory)</code>
+	 for consistence with <code>IWorkingCopy</code>.
+     The returned working copy is just a wrapper on the class file's buffer.
+     Thus only the <code>getBuffer()</code> operation is valid on this working
+     copy.
+</li>
+<li> Added the notion of shared working copies. This allows clients to always
+     get the same <code>IWorkingCopy</code> instance when asking for a working copy.
+     See <code>IWorkingCopy.getSharedWorkingCopy(IProgressMonitor, IBufferFactory)</code>,
+     <code>IWorkingCopy.findSharedWorkingCopy()</code>
+     and <code>IWorkingCopy.destroy()</code> for more detail.
+</li>
+<li> Added option to trace use of shared working copies.
+    To enable it, see the following line in the org.eclipse.jdt.core/.options file:
+    <code>org.eclipse.jdt.core/debug/sharedworkingcopy=true</code>
+</li>
+<li> Added extension point to jdtcore so as to allow client plugins to register classpath variable initializers.
+  Extension point is "org.eclipse.jdt.core.classpathVariableInitializer".
+  (also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.eclipse.jdt.core/notes/r2.0/variable%20init/uninit-classpath-vars.html">design notes</a>)
+  Note that each classpath variable, if unbound, will trigger its registered initializer exactly once per session. If unsuccessful, it will stay unbound.
+
+</li>
+<li> Added option to trace classpath variable initializations.
+    To enable it, see the following line in the org.eclipse.jdt.core/.options file:
+    <code>org.eclipse.jdt.core/debug/cpvariable=true</code>
+</li>
+<li>Added option to trace access to zip and jar files from the Java model.
+    To enable it, see the following line in the org.eclipse.jdt.core/.options file:
+    <code>org.eclipse.jdt.core/debug/zipaccess=true</code>
+</li>
+<li>Resurrect some code for backport 1.0 internal functionality
+	<ul>
+	<li> org.eclipse.jdt.internal.compiler.ConfigurableOption (all the class).
+	<li> org.eclipse.jdt.internal.formatter.CodeFormatter (some methods) :
+		<ul>
+		<li> public CodeFormatter(ConfigurableOption[] settings)
+		<li> private static Map convertConfigurableOptions(ConfigurableOption[] settings)
+		<li> public static ConfigurableOption[] getDefaultOptions(Locale locale)
+		<li> public static String format(String sourceString, int initialIndentationLevel, ConfigurableOption[] options)
+		</ul>
+	<li> org.eclipse.jdt.internal.formatter.Options.properties (all the file)
+	</ul>
+</li>
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3303">3303</a>
+Many errors when adding projects from repository in a fresh install (1GF5PU7)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5285">5285</a>
+Compile errors on load when Java Perspective not open
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7085">7085</a>
+Build errors when adding the JUnit example project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10700">10700</a>
+ast: resolveBinding returns null on parameter reference 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10676">10676</a>
+StringLiteral.resolveTypeBinding() return null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10679">10679</a>
+ClassCastException when calling resolveTypeBinding() with an error 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10634">10634</a>
+Problem with compiling some java classes; class not visible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10340">10340</a>
+NPE when selecting multiple methods to "Pull up"  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10662">10662</a>
+Casting to Buffer makes it impossible for clients to implement IBuffer  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10592">10592</a> 
+ast: NPE in SingleVariableDeclaration::resolveBinding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9583">9583</a>
+DOM : Self encapsulate field: NPE 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10570">10570</a>
+ast: CatchClause has incorrect startingPoint 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10587">10587</a>
+ast: missing node for a variable binding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9588">9588</a>
+Invalid delta when replacing jar and proj=src=bin  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10495">10495</a>
+typo in ASTNode::MALFORMED javadoc 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10472">10472</a>
+CodeAssist - No completion between dot and number
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3323">3323</a>
+OpenOnSelection - no selection inside CodeFormatterPreferencePage.fTextListener initializer (1GGND3S)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10466">10466</a>
+"Cannot reference a field before it is defined" - compiler bug?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10386">10386</a>
+NPE in MatchLocator.lookupType  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10378">10378</a>
+perf problem with external JARs  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9593">9593</a>
+SelectionEngine give more results than expected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9969">9969</a>
+CodeFormatter: Bug when formatting try/catch Block 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3231">3231</a>
+1.4 - target is now 1.2 (1GHW0DF)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9998">9998</a>
+Performance - Better pruning meaningless AST nodes upon completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10240">10240</a>
+JDTCompilerAdapter doesn't understand "deprecation" from Ant 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10274">10274</a>
+DOM/AST: wrong implementation of TypeDeclaration.getFields 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10241">10241</a>
+Remaining references to com.ibm 
+<h3> 
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10753">10753</a>
+Compiler barfs on c:\ubizen with invalid unicode 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10749">10749</a>
+Bug is code formatter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10701">10701</a>
+Undefined method when compiling using JDK 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10674">10674</a>
+AST API request : method binding for ClassInstanceCreation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10583">10583</a>
+Can not save any java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10275">10275</a>
+Search: reference to class not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3437">3437</a>
+Code Assist fails when method has unknown return type (1GL12EG)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9579">9579</a>
+Search: declaration in hierarchy - wrong matches  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10460">10460</a>
+The Compiler can not resolve package level class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10244">10244</a>
+DOM/AST: MethodInvocation should have resolveBinding() method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9157">9157</a>
+My existing .class files are deleted!
+ 
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020226 - 26th February 2002
+<br>Project org.eclipse.jdt.core v_229
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Java tooling now performs normally inside method bodies whose signature could not
+be resolved.
+</li>
+<li> Specified that when an <code>IBuffer</code> is created through an 
+     <code>IBufferFactory</code>, its content is set with the original
+     element's content.
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10110">10110</a>
+Project not build since it was inconsistent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9642">9642</a>
+Search - missing inaccurate type matches  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9992">9992</a>
+Member class declaration not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10221">10221</a>
+No variable name suggestion on array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10166">10166</a>
+Interface hides Object methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7934">7934</a>
+Builder always rebuilds when workbench restarted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7456">7456</a>
+Error message with overloaded methods is confusing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10152">10152</a>
+Computing hierarchy of IResource is slow  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8809">8809</a>
+Code assist with class folders does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9763">9763</a>
+Code assist failure due to error in method signature:1GRVN5R
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9985">9985</a>
+Built in compiler will sometimes not allow Object method calls on Interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10008">10008</a>
+Internal compiler error when compiling switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9912">9912</a>
+Batch compiler doesn't put binaries in the right folder when -d is missing 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6059">6059</a>
+NPE in JavaModelStatus 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9351">9351</a>
+Copying a compilation unit onto itself destroys compilation unit 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9813">9813</a>
+VerifyError with Inner Class having private constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9492">9492</a>
+Walkback while searching  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9837">9837</a>
+Inconsistent behavior when compiling from source or using binaries for constant expressions
+
+<h3> 
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6951">6951</a>
+DCR - Builder should ignore filtered out resources
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5809">5809</a>
+Duplicate class names in separate package imports cause compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9888">9888</a>
+JAR exorter problems with META-INF in projects with no source folder  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10104">10104</a>
+Calculated serialVersionID's are incompatible with Sun's JDK
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020214 - 14th February 2002 - MILESTONE 3
+<br>Project org.eclipse.jdt.core v_228
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9479">9479</a>
+exception on package creation (discouraged name)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5999">5999</a>
+IType.resolveType returns multiple matches also the type is unambigious
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7485">7485</a>
+IType resolve fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9785">9785</a>  
+Problem in IType.resolveType()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9239">9239</a>
+search for method declaration - strange behavior  
+
+<h3> 
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5647">5647</a>
+Search results differ when using outliner context menu vs. dialog  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5239">5239</a>
+outliner gets out of synch  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5029">5029</a>
+Internal Error saving java file  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9586">9586</a>  
+Java 1.4 feature assert does not throw any exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9504">9504</a>  
+1GRU1L3:Search reference works only in outline view and not in editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9476">9476</a>  
+ArrayIndexOutOfBounds in JavaBuilder  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3262">3262</a>
+Strange output file deletion (1GDS2IX)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020212 - 12th February 200
+<br>Project org.eclipse.jdt.core v_227
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Resource copy filters : A new setting allows to specify exclusion filters for resource being copied to the output folder..
+	<ul>
+	<li>option id:			"org.eclipse.jdt.core.builder.resourceCopyExclusionFilters"
+	<li>possible values:	{ "&lt;name&gt;[,&lt;name&gt;]* } where &lt;name&gt; is a file name pattern (only * wild-cards allowed)
+	<li>default:			"" 
+	</ul>
+</li>
+<li>Encoding support : Batch compiler can be specified the source encoding format using '-encoding myEncoding' command line option.
+In case of necessity, each individual file specified on the command line can be associated with a custom encoding
+by suffixing its name with '[myEncoding]' (if applied to a folder, then all files in it will be sharing the custom
+encoding). When no encoding is specified, then the platform default is used (as before). Similarily, a JavaCore option got added to
+control the default encoding (no support yet for per file custom encoding).
+	<ul>
+	<li>option id:			"org.eclipse.jdt.core.encoding"
+	<li>possible values:	{ "" for platform default, or any of the supported encoding name }.
+	<li>default:			"" 
+	</ul>
+</li>
+<li> Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9183">9183</a> required to increment the index signature 
+version so as to trigger automatic reindexing on workspace startup (and thus add somme type references that were previously
+missing from the binary index files). Subsequent startups will not reindex any further (only if inconsistency is detected, 
+e.g. signature version is different).
+</li>
+<li> The <code>IBufferFactory</code> used when creating an <code>IWorkingCopy</code>
+(see <code>ICompilationUnit.getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory)</code>)
+is now remembered and will be reused if the working copy is closed then reopen.
+</li>
+<li>Old Java builder implementation got removed</li>
+<li>Project dependency cycle detection reenabled</li>
+<li> Open on selection no longer need a non-empty selection to perform (when empty it will use the token
+in which the selection start position is located).
+<li>Improved progress reporting while searching all types in the workspace.</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9452">9452</a>  
+IllegalArgumentException when creating an AST for TestCase.java  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7390">7390</a>
+Editing and saving read-only .java source file may cause lost of data
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7926">7926</a>
+Code Assist - No completion for class instance creation after inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7636">7636</a>
+Can't do code assist after field with local class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8369">8369</a>
+Code assist stops to work after anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9398">9398</a>
+Compiler error with double array
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9395">9395</a>
+ClassCastException during build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9185">9185</a>
+Severe shutdown performance problem  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6167">6167</a>
+Indexer not stoped on exit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7362">7362</a>
+Override Methods doesn't handle unicodes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7295">7295</a>
+Indendation in generated getters/setters of inner classes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6678">6678</a>
+Incorrect output after Add Unimplemented Method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8758">8758</a>
+null pointer exception in eclipse core while compiling Java code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6236">6236</a>
+Renamed file is not excluded from project build  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8696">8696</a>
+Code assist doesn't work in initializer of anonymous inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6064">6064</a>
+Open on selection shouldn't require selection.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9223">9223</a>
+CodeAssist failure in inner type from class file.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6847">6847</a>
+DCR - Filtering output to build directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9309">9309</a>
+DOM/AST: NPE when trying to resolve a binding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9308">9308</a>
+DOM/AST: two equal hash table accesses 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9101">9101</a>
+Parse error while typing in Java editor  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9031">9031</a>
+NPE in AbstractMethodDeclaration.compilationResult during search  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9084">9084</a>
+NPE in parser during build 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9008">9008</a>
+Code assist on method declaration gives wrong throw exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8878">8878</a>
+Code assist provides arbitrary, invalid choice after a space
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9198">9128</a>
+NegativeArraySizeException starting workbench  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9035">9035</a>
+I got an NPE 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9183">9183</a>
+BinaryIndexer doesn't index all type references 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3321">3321</a>
+Adding missing source folder doesn't remove warning (1GGCC4P)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3219">3219</a>
+JM - 'Cycle detected' should not be a marker attribute (1G8VTSA)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9169">9169</a>
+Wrong code generation for comparison of string constants 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8685">8685</a>
+Exception while deleting a method  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=4021">4021</a>
+jdt: Java elements and resources: error in source code (1GG87S9)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7878">7878</a>
+On Package creation: No warning for unconventional names  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9041">9041</a>
+search: cannot create a sub-cu scope  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9088">9088</a>
+Unreachable catch block when error in referenced class's fields 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3299">3299</a>
+Autobuild produces errors when renaming source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9009">9009</a>
+ClassCastException creating an invalid method 
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3190">3190</a>
+JM - use of "open" in java model inconsistent with core (1FW2EYQ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3268">3268</a>
+create(IProject) strange for normal projects (1GDVTER)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8527">8527</a>
+Delete inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3037">3037</a>
+Core error compiling a java class (1GEJK8Q)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9386">9386</a>
+cannot import jar files into project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7976">7976</a>
+JDT misses the new Java files created by PDE  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5713">5713</a>
+NPE when searching for references in a JAR  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9177">9177</a>
+Builder treats build errors as JavaErrors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8040">8040</a>
+java source with $ in reference won't compile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5036">5036</a>
+assertion fails on build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8498">8498</a>
+deprecated methods are not displayed in the task console  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3371">3371</a>
+Assertion failed exception during build (1GK183O)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3419">3419</a>
+asserion failed in build (1GKB9CH)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7895">7895</a>
+Wierd state: Project not built because inconsistent.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7830">7830</a>
+Deleting more than one method consecutively from the hierarchy view causes unexpected corruption of othe methods 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9190">9190</a>
+Removing a library from classpath gives not a remove delta  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9104">9104</a>
+copy package progress dialog has missing string 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5706">5706</a>  
+Cannot add two folders w/ same name but diff projects to build path of Java project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9103">9103</a>
+Search reports no references to SWT.Help  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6418">6418</a>
+Scrapbook: "Unexpected End Of File" expected  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3191">3191</a>
+JM - non-existing external jars will not come to life when created (1FWI5C4)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8980">8980</a>
+Unpredictable error catching on overridden methods with less visibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9024">9024</a>
+Do not find reference to an interface in JAR 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9040">9040</a>
+DOM/AST: why is the left hand side of an assignment an expression 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020205 - 5th February 2002
+<br>Project org.eclipse.jdt.core v_226
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> The JavaModel no longer notifies changes for generated classfiles in the output folder, these 
+were never supposed to be signaled. </li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3448">3448</a>
+No error for package and type collision in default package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9016">9016</a>
+DOM/AST: Problems with array.length access 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9014">9014</a>
+DOM/AST: NullPointerException when resolving System.err.println 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9018">9018</a>
+DOM/AST: why does the key of a variable binding include the type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5355">5355</a>
+search: NPE in searchDeclarationsOfReferencedTypes  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8928">8928</a>
+Unable to find references or declarations of methods that use static inner classes in the signature  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3291">3291</a>
+Exception adding .class file to folder in package view (1GEUF3I)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8900">8900</a>
+Search causing internal error  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8812">8812</a>
+Changing export state not propagated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8856">8856</a>
+DOM AST: positions and bindings missing on QualifiedName 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3446">3446</a>
+type hierarchy: incorrect behavior wrt working copies (1GLDHOA)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3210">3210</a>
+Search - method declarations within TypeHierarchy gives no matches (1G54BMR)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8145">8145</a>
+TypeDeclaration sourceEnd contains trailing comment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8832">8832</a>
+Sanity check error (internal error) when unused variables inside initializers  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8078">8078</a>
+Missing resource in copy CU dialog  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8764">8764</a>
+NPE while closing projects  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8359">8359</a>
+Index out of date when replacing a JAR  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8773">8773</a> 
+VerifyError : A .class file exported from VAJ does not run in JDK 1.2.2 (1GPPET0)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8697">8697</a> 
+2 compiler bugs: the operator unkown operator is undefined and defined in an inherited type and an enclosing scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8706">8706</a> 
+Compile error when compiling an anonymous class which extends java.awt.Frame
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8709">8709</a> 
+Error compiling JDK1.4 classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8340">8340</a>
+inaccurate error message when dependent project is closed  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3344">3344</a>
+JavaElementDelta reports changed class files (1GIV8IK)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8384">8384</a> 
+Unexpected compile errors when abstract method missing return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8789">8789</a> 
+Compiler incorrectly reports that abstract method has a body  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7987">7987</a>
+Field reference search should do lookup in 1.4 mode  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8863">8863</a>
+.classpath gets overwritten if there's an XML error  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7162">7162</a>
+Java Model Exceptions in log from TypeHierarchyLifeCycle  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8699">8699</a> 
+Compiler error message incomplete: Syntax error on token ''
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3324">3324</a> 
+Bad compiler error (1GHF25P) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3441">3441</a>  
+Internal error renaming a class (1GL2XCW) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7841">7841</a> 
+Overriden methods inserted past the end of source
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020129 - 29th January 2002
+<br>Project org.eclipse.jdt.core v_225
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Java compiler is JCK 1.4 compliant. When toggled in 1.4 mode (batch: -1.4 -source 1.4), the Java compiler is fully JCK 1.4 compliant 
+as of JCK 1.4 2001-10-01 update. When in 1.3 mode (default), it is JCK 1.3a compliant.
+</li>
+<li> By default, when toggled into 1.4 mode, the batch compiler will enable assertion support (e.g. -source 1.4). It can still manually
+be toggled for 1.3 source level compatibility (-source 1.3).
+</li>
+<li> Added constructor <code>SearchEngine(IWorkingCopy[])</code>
+     which takes a list of working copies that will take precedence 
+     over their original compilation units in the subsequent search 
+     operations on this search engine.
+     <br>
+     Note that this functionality is still under development and some
+     parts may not work as expected. Feedback is welcome.
+</li>
+<li> New feature to achieve problems corrections : org.eclipse.jdt.core.CorrectionEngine.
+     Correction results are answered through a requestor (org.eclipse.jdt.core.ICorrectionRequestor).
+</li>
+<li> JavaCore will no longer add indirectly prereq'ed project amongst project references.
+</li>
+<li> New JDOM AST API available (also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.eclipse.jdt.core/notes/r2.0/dom%20ast/ast.html?rev=1.1&content-type=text/html">design
+note</a>). This API has not yet reached full stability, and feedback is very welcome.
+</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8641">8641</a>
+Can't find references in hierarchy in binary projects  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8659">8659</a>  
+Unexpected changes in project references (.vcm-meta)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8358">8358</a>
+Search: doesn't find reference although there are  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6799">6799</a>
+Duplicate type collisions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8414">8414</a>
+Incorrect "unused variable" warning?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8484">8484</a>
+Internal error searching for write access to a variable  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8536">8536</a>
+Bug on "Open type hierarchy"  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8575">8575</a>
+Variable name code completion should handle arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8530">8530</a>
+Internal error using assertions (1.4 feature)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8531">8531</a>
+VerifyError in code containing assertions
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7509">7509</a>
+1GQ6DUC: WSWB:WIN2000 - Ctrl-space Code Completion does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8060">8060</a>
+Hierarchy only shows Object when opening type in binary project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3408">3408</a>
+JCK 1.4 - NAME - qualified AmbiguousName and an ExpressionName (1GK7M9B)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8584">8584</a>
+Invalid syntax error generated by compiler
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020124 - 24th January 2002 - MILESTONE 2
+<br>Project org.eclipse.jdt.core v_224
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11354">11354</a>
+Unable to edit Java code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8016">8016</a>
+getter/setter outliner reconciling broken  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8352">8352</a>
+No hierarchy when using HierachyType  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8042">8042</a>
+ClassCastException hovering in java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8216">8216</a>
+Incomplete super type hierarchy for binaries  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8125">8125</a>
+'Could not uniquely map the type name' message opening type  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7221">7221</a>
+IllegalArgumentException renaming package  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5341">5341</a>
+Error message shouldn't expose exception class  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8038">8038</a>
+Null Pointer Exception Adding Unimplemented  
+
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020123 - 23rd January 2002
+<br>Project org.eclipse.jdt.core v_223
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added workaround for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7764">7764</a>
+UI Dead Lock - IDE frozen  
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3200">3200</a>
+JavaBuilder - Build progress message could be shortened
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8087">8087</a>
+NPE when hierarchy verbose on and hierarchy on a region  
+
+<h3>
+Problem Reports Closed</h3>
+
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020122 - 22nd January 2002
+<br>Project org.eclipse.jdt.core v_222
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> The selection engine now only selects identifier between selection start and selection end.
+Previous behaviour was to select identifier between selection start and identifier end.
+(e.g. if you select <b>File</b> in <b>File</b>Input, now the selection engine select the class File and not FileInput)
+<li> Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6839">6839</a> required to increment the index signature 
+version so as to trigger automatic reindexing on workspace startup (and thus get rid of undesired anonymous type entries
+in the index files). Subsequent startups will not reindex any further (only if inconsistency is detected, e.g. signature version
+is different).
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7993">7993</a>
+NPE when creating type hierarchy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3417">3417</a> 
+JCK 1.4 - BINC - the new method is a static (respectively instance) method. (1GK7WCP)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3416">3416</a> 
+JCK 1.4 - BINC - the new method is less accessible than the old one (1GK7VXD)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3415">3415</a> 
+JCK 1.4 - BINC - the new field is a static (respectively instance) field (1GK7VSN)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3414">3414</a> 
+JCK 1.4 - BINC - the new field is less accessible than the old one (1GK7VMD)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3413">3413</a> 
+JCK 1.4 - BINC - detection of an IncompatibleClassChangeError (1GK7VCA)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3412">3412</a> 
+JCK 1.4 - BINC - Invoke overriding class methods (1GK7UGQ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3410">3410</a> 
+JCK 1.4 - BINC - Adding a String field that has the same name as a String field of a superclass (1GK7MHO)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7920">7920</a>
+JavaProject.canonicalizedPath  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7597">7597</a>
+PackageFragmentRoot which are archives loose associated resource  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7827">7827</a>
+null returned from getOriginal(IJavaElement workingCopyElement) for IMPORT_CONTAINER  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7144">7144</a>
+Hierarchy incorrect when using binary projects  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3411">3411</a>
+JCK 1.4 - BINC - Overriding instance and class methods (1GK7U6C)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3418">3418</a>
+JCK 1.4 - EXPR - a NullPointerException is raised in run time (1GK7WHA)  <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7441">7441</a>
+Open a type is extremely slow  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7616">7616</a>
+Unnecessary indexing when project is opened  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3229">3229</a>
+OpenOnSelection - strange behaviour of code resolve (1GAVL08)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6953">6953</a>
+No code assist proposals for interface constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7583">7583</a>
+DOMNode#getChild(String) needs to handle children with null names 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7584">7584</a>
+Comments on IDOMMethod#getReturnType() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3247">3247</a> 
+SelectionEngine moves selection to enclosing token (1GCSD8D)
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7956">7956</a>
+No reference found to BlockScope.analysisIndex  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3283">3283</a> 
+OpenOnSelection - Code resolve doesn't work in some situations (1GEI5QT)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5453">5453</a> 
+DCR: Code Assist for anonymous types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7617">7617</a> 
+NPE in Builder with duplicated type names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6466">6466</a> 
+Code Formatter  
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020115 - 15th January 2002
+<br>Project org.eclipse.jdt.core v_221
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> The compiler will now follow JLS 8.6 with respect to anonymous class 
+constructors (i.e. allow them to throw any exceptions).
+<li> The compiler now enforces that interface methods be compatible with Object ones.
+<li> The batch compiler will no longer create package directory structure anymore when the command line
+argument '-d' <tt>&lt;destination&gt;</tt> is omitted (compliant with standard batch compilers).
+<li> A type hierarchy that misses a super type is not rooted at Object any longer,
+     but the subtype (of the missing type) will be a root (this is the behavior of
+     VA/Java and VAME.)
+<li> Adding a type that was missing from a hierarchy will update the hierarchy correctly.
+<li> New API on ICompletionRequestor for suggest anonymous type declaration:
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <tt>void acceptAnonymousType(</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] superTypePackageName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] superTypeName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterPackageNames,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterNames,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterNames,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] completionName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int modifiers,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionStart,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionEnd);</tt>
+<br>&nbsp;
+</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7625">7625</a>
+No typehierarchy in working copy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7595">7595</a>
+New builder performs intempestive full build on method body changes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7528">7528</a>
+IlegalArgumentException in path canonicalisation  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7034">7034</a>
+code assist performance problem in scrapbook
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7119">7119</a>
+Content Assist does not complete some code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7000">7000</a>
+Switch and Try statement doesn't include trailing } 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6932">6932</a>
+Increment statement in for loop contains trailing comments 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6342">6342</a>
+Code assist on Intreface-'Constructors' incomplete
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7344">7344</a>
+Search - write acces give wrong result  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7455">7455</a>  
+Build problems when instance variable name matches constructor parameter name and assignment to this.name in try block  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6839">6839</a>
+AllTypesSearchEngine returns anonymous classes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7445">7445</a>
+char/string concat bug  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3192">3192</a>
+Invalid type hierarchy when missing type(s) in hierarchy (1GF5RN4)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3304">3304</a>
+Hierarchy not updated when changing classpath (1GF5QSW)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7422">7422</a>
+Missing project references on some imported Java projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5067">5067</a>
+CodeAssist - no variable name suggestion for base type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7363">7363</a>
+Rebuild Project action is not compiling all Java source files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7325">7325</a>
+Build collisions should be non-fatal?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7324">7324</a>
+Ambiguous multiple problem descriptions when collision of build files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3385">3385</a>
+JCK 1.4 - INTF - illegal method declaration for interface (1GK2AWS)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3318">3318</a>
+JDOM - IDomNode redefines clone() with different signature (1GFVU2V)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6101">6101</a>
+Unexpected error in inner class 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7333">7333</a>
+typo in type name: ResetSateForCodeGenerationVisitor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7354">7354</a>
+Compatibility with javac when no output directory is specified 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6473">6473</a>
+JavaConventions should use IWorkspace validate methods  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7129">7129</a>
+Problems with replacing a project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3386">3386</a>
+JCK 1.4 - EXCP - checked exception in variable initializer of anonymous class (1GK7B5L)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3367">3367</a>
+JCK 1.4 - ICLS - An instance initializer in an anonymous class may throw any exception (1GK7LYF)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7184">7184</a>
+Built in compiler does not allow anonymous class initializers to throw exceptions 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6504">6504</a>
+Type hierarchy: Subtypes in jar of another project not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3334">3334</a>
+Types hierarchy view does not show all subclasses. (1GI901Q)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6866">6866</a>  
+Code-Assist (ctrl+space) to slow with jre-src
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7071">7071</a>  
+ArrayStoreException getting hoverhelp in Java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7165">7165</a>  
+erroneous warning of unused variables  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3217">3217</a>
+JM - deleting default package (1G8417Z)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7375">7375</a>
+new classes with funny names don't appear in package view  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7302">7302</a>
+Need visibility in search results 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7305">7305</a>
+interface methods are marked abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7290">7290</a>
+Project size limitation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6232">6232</a>
+Build problems: Internal error: null when compiling JDK source code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7380">7380</a>
+Wrong scope for traverse methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7137">7137</a>
+Invalid type not flagged by compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6924">6924</a>
+ArrayIndexOutOfBoundsException when setting the build path.
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20020108 - 8th January 2002
+<br>Project org.eclipse.jdt.core v_220a
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Added new compiler option to toggle compliance level (can be either
+"1.3" or "1.4" - 1.3 being the default), and it will affect the behavior
+of the compiler with respect to JLS 8.1.5 (inherited member shadows enclosing
+one). Option is located on <tt>JavaCore#getOptions()</tt> and named <tt>"org.eclipse.jdt.core.compiler.compliance"</tt>
+Accordingly, the batch compiler accepts an extra command line argument
+"-1.3" or "-1.4" (1.3 compliance being the default).</li>
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3330">3330</a>  
+JCK 1.4 - illegal simple name imports (1GHW0G1)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7070">7070</a>
+moved classes lost!  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6785">6785</a>
+NPE in IType.resolve
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6779">6779</a>
+searchDeclarationsOfReferencedTyped - missing exception types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7035">7035</a> 
+New builder - builder does not close all JARs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7033">7033</a>
+Stale packages view after moving compilation units  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6927">6927</a>
+Static inner class won't compile (doesn't match JDK behavior)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7030">7030</a>
+IllegalArgumentException renaming project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7029">7029</a>
+Renaming a Java project doesn't refresh the packages view  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7027">7027</a>
+project gone after renaming in the navigator  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7026">7026</a>
+walkback on rename project - could not reproduce  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6889">6889</a>
+No typehierarchy for inner types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3343">3343</a>
+Missing java.lang.Object should produce a more prominent compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6948">6948</a>
+New builder - builder does not reuse opened JARs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3314">3314</a>
+Resources not appearing in Java perspective or Jar export wizard (1GFL0QT)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6890">6890</a>
+META-INF hidden  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6993">6993</a>
+JavaModel inconsistencies with units outside classpath  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3360">3360</a> 
+Code assist does not work in inner classes (1GJOVT6)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6893">6893</a> 
+LocalTypeDeclaration includes preceeding comment even if there are statements in between
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3372">3372</a> 
+Markers for build path not updated on (re-) build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5413">5413</a> 
+incorrect class source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6429">6429</a>
+declaration source start incorrect on local variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6433">6433</a>
+declaration source start incorrect on local variable #2
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3235">3235</a>
+PackageFragmentRoot existency check need to be revisited (1GCUNO7)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6865">6865</a>
+open on selection in BuildNotifier only finds contents of rt.jar  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6037">6037</a>
+JarPackageFragmentRoot.getUnderlyingResource() always returns null
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6750">6750</a>
+Batch compiler - Classpath handling is too strict  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3409">3409</a>
+JCK 1.4 - STMT - null literal in throw statement (1GK7MEQ)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4915">4915</a>
+JCK 1.4 - need a major compiler switch for 1.3 / 1.4 mode
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6678">6678</a>
+Incorrect output after Add Unimplemented Method
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3361">3361</a>
+JCK 1.4 - ICLS - field from outer class and inherited public field in nested class (1GK7LAA) 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3350">3350</a>
+JCK 1.4 - ICLS - static class from outer and class from superclass in top-level nested class (1GK7DVJ)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3351">3351</a>
+JCK 1.4 - ICLS - static class from outer and protected static class from superclass in nested class (1GK7DZV)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3352">3352</a>
+JCK 1.4 - ICLS - static class from outer and public static class from superclass in nested class (1GK7EB9) 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3362">3362</a>
+JCK 1.4 - ICLS - field from outer class and inherited field in nested class (1GK7LCX)   
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3363">3363</a>
+JCK 1.4 - ICLS - An inherited variable that shadows a name from an enclosing non-package scope (1GK7LHR)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3364">3364</a>
+JCK 1.4 - ICLS - An inherited method that shadows a name from an enclosing non-package scope (1GK7LKV)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3365">3365</a>
+JCK 1.4 - ICLS - An inherited class that shadows a name from an enclosing non-package scope (1GK7LTA)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3366">3366</a>
+JCK 1.4 - ICLS - An inherited interface that shadows a name from an enclosing non-package scope (1GK7LW2)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3375">3375</a>
+JCK 1.4 - ICLS - class from outer and protected class from superclass in top-level nested class (1GK7FLC)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3376">3376</a>
+JCK 1.4 - ICLS - class from outer and public class from superclass in top-level nested class (1GK7FOT)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3377">3377</a>
+JCK 1.4 - ICLS - class from outer and class from superclass in top-level nested class (1GK7FTA)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3378">3378</a>
+JCK 1.4 - ICLS - class from outer and protected static class from superclass in nested class (1GK7FX7)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3379">3379</a>
+JCK 1.4 - ICLS - class from outer and public static class from superclass in nested class (1GK7G2A)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3380">3380</a>
+JCK 1.4 - ICLS - class from outer and static class from superclass in nested class (1GK7G5A)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3381">3381</a>
+JCK 1.4 - ICLS - class from outer and protected class from superclass in nested class (1GK7G8E)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3382">3382</a>
+JCK 1.4 - ICLS - class from outer and public class from superclass in nested class (1GK7GC1)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3383">3383</a>
+JCK 1.4 - ICLS - class from outer and class from superclass in nested class (1GK7GQA)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3384">3384</a>
+JCK 1.4 - ICLS - static class from outer and public static class from superclass in top-level nested class. (1GK7CTV)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3387">3387</a>
+JCK 1.4 - ICLS - static field from outer class and inherited public field in top-level nested class (1GK7H0B)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3388">3388</a>
+JCK 1.4 - ICLS - static class from outer and protected static class from superclass in top-level nested class (1GK7BGP)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3389">3389</a>
+JCK 1.4 - ICLS - static class from outer and static class from superclass in top-level nested class (1GK7D2P)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3390">3390</a>
+JCK 1.4 - ICLS - static class from outer and protected class from superclass in top-level nested class (1GK7D7Q) 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3391">3391</a>
+JCK 1.4 - ICLS - static class from outer and public class from superclass in top-level nested class (1GK7DBD)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3392">3392</a>
+JCK 1.4 - ICLS - static class from outer and static class from superclass in nested class (1GK7ERE)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3393">3393</a>
+JCK 1.4 - ICLS - static class from outer and protected class from superclass in nested class (1GK7EVB)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3394">3394</a>
+JCK 1.4 - ICLS - static class from outer and public class from superclass in nested class (1GK7EZB)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3395">3395</a>
+JCK 1.4 - ICLS - static class from outer and class from superclass in nested class (1GK7F4S)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3396">3396</a>
+JCK 1.4 - ICLS - class from outer and protected static class from superclass in top-level nested class (1GK7F8L)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3397">3397</a>
+JCK 1.4 - ICLS - class from outer and public static class from superclass in top-level nested class (1GK7FCN)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3398">3398</a>
+JCK 1.4 - ICLS - class from outer and static class from superclass in top-level nested class (1GK7FHB)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3399">3399</a>
+JCK 1.4 - ICLS - static field from outer class and inherited field in top-level nested class (1GK7H2Z)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3400">3400</a>
+JCK 1.4 - ICLS - static field from outer class and inherited protected field in top-level nested class (1GK7GW6)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3401">3401</a>
+JCK 1.4 - ICLS - field from outer class and inherited field in top-level nested class (1GK7HEF)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3402">3402</a>
+JCK 1.4 - ICLS - static field from outer class and inherited protected field in nested class (1GK7HH1)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3403">3403</a>
+JCK 1.4 - ICLS - field from outer class and inherited protected field in top-level nested class (1GK7H5X)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3404">3404</a>
+JCK 1.4 - ICLS - field from outer class and inherited public field in top-level nested class (1GK7HBJ)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3405">3405</a>
+JCK 1.4 - ICLS - static field from outer class and inherited public field in nested class (1GK7HKE)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3406">3406</a>
+JCK 1.4 - ICLS - static field from outer class and inherited field in nested class (1GK7HMN)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3407">3407</a>
+JCK 1.4 - ICLS - field from outer class and inherited protected field in nested class (1GK7L79)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6061">6061</a>
+unreachable code/unused temp ? 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6443">6443</a>
+Incremental java builder doesn't handle folder create/delete nicely
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5317">5317</a>
+Reparenting class should refresh hierarchy  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6740">6740</a>
+Problems with deleting project
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6491">6491</a>
+Non-java resource folder doesn't appear under pkg fragment root  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3245">3245</a>
+sub folders with dot not visible in packages view (1GCOH17)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6806">6806</a>
+NullPointerException moving enpty cu out of default package  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=7065">7065</a>
+NPE when saving a Java source
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6956">6956</a>
+incorrect compiler error reported on extract method
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=7072">7072</a>
+Protected member in superclass not visible in subclass
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=7066">7066</a>
+Subclass can't see protected inner class of superclass  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3284">3284</a>
+Project doesn't always rebuild after changing the Java build path
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6957">6957</a>
+CCE in AnonymousLocalTypeDeclaration::traverse 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6958">6958</a>
+NPE in DeltaProcessor  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6900">6900</a>
+Rebuild project fails with error "1000 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4382">4382</a>
+NullPointerException in JavaBuilder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3199">3199</a>
+Missing classpath variables
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6848">6848</a>
+Index out of range exception with New builder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4913">4913</a>
+null argument in IncrementalImageBuilder.getBuilderType
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6760">6760</a>
+package names truncated in compilation dialog
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3295">3295</a>
+Errors from missing reference to a jar do not go away
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3450">3450</a>
+Bug in JavaSearchScope (1GLE1GC)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011218 - 18th December 2001 - MILESTONE 1
+<br>Project org.eclipse.jdt.core v_219a
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6117">6117</a>
+CodeFormatter - impossible to set indentation level and position mapping w/o deprecated methods
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6719">6719</a>
+LocalTypeDeclaration::traverse
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5432">5432</a>
+compiler syntax error is incorrect
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011211 - 11th December 2001
+<br>Project org.eclipse.jdt.core v_218
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li> Java element deltas are batched. If the java model operation modifies
+	 a resource, then the java element deltas are merged and fired during 
+	 the resource delta processing. If the java model operation doesn't 
+	 modify any resource (e.g. IWorkingCopy.reconcile()), then the java
+	 element delta is fired right away.
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3215">3215</a>
+JM - Creating a new class sends out many notifications (1GD2GT0)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6695">6695</a>
+Changing Java preference in build 20011206 throws a NullPointerException in org.eclipse.jdt.internal.core.DeltaProcessor.initializeRoots  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6761">6761</a>
+NullPointerException during replace  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3290">3290</a>
+JavaBuilder - Old class files remain after change of output location
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3188">3188</a>
+JavaBuilder - Deleting source doesn't delete binary folders (1FVPTTK)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3185">3185</a>
+JavaBuilder - Errors don't disappear
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3189">3189</a>
+JavaBuilder - Missing libraries results in insufficient dependency info
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3204">3204</a>
+ImageBuilder should show error count in the progress
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3227">3227</a>
+JCL dev - Builder did not refresh problems in exception hierarchy
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3228">3228</a>
+Discarding rt.jar from build path triggers too many recompilation
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3232">3232</a>
+Incremental builder unable to handle efficiently missing rt.jar scenario
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3234">3234</a>
+Incremental builder does not notice addition of java.lang.Object inside same project
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3241">3241</a>
+Build doesn't honor cancel
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3260">3260</a>
+NPE when doing incremental project build
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3278">3278</a>
+JavaBuilder - Problem Count rarely updated
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3287">3287</a>
+Built state does not remember old pkg fragment roots
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3301">3301</a>
+Incremental build doesn't detect disappearance of field
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3305">3305</a>
+Incremental build doesn't detect abstract method to implements
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3311">3311</a>
+performance: task list still does not scale at all
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3312">3312</a>
+Internal errors in image builder due to duplicate package fragment
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3317">3317</a>
+Fullbuild after startup
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3322">3322</a>
+NullPointerException during build in StateImpl.getSourceElementEntries
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3326">3326</a>
+Incremental build doesn't work if bin deleted
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3370">3370</a>
+Incremental compiler is compiling project when it should not
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3422">3422</a>
+NPE in Java builder during catchup
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3429">3429</a>
+Incremental compilation bug on namespace change in private local class
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3444">3444</a>
+Build problems: Marker set on Folder?
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5007">5007</a>
+Project classpath references do not follow class folders
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5109">5109</a>
+Adding project doesn't fix build errors
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5320">5320</a>
+NPE during catchup
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5641">5641</a>
+NPE on rebuild when replacing internal jar
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6538">6538</a>
+searchDeclarationsOf* incorrect 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6690">6690</a>
+CodeAssist finds types outside the classpath 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6687">6687</a>
+Wrong JavaModel refresh after drag and drop outside folder with dot in name  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6693">6693</a>
+AbstractImageBuilder.compile throws an ArrayIndexOutOfBoundsException on line 166 in build 20011206
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6670">6670</a>
+Code Assist: Cannot resolve in method body
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6674">6674</a>
+Cannot add unimplemented methods
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6629">6629</a>
+Open On Selection does not work on Linux
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5542">5542</a>
+Too many deltas are fired on each JavaModel operation  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3269">3269</a> 
+Updating the Java packages view on project creation (1GDW0U9)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3202">3202</a>
+DCR - JM - Merge Java Element Deltas with Resource Deltas (1G2B60Z)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6621">6621</a>
+NPE in Delta Processor  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3368">3368</a>
+JCK 1.4 - INTF - The field of protected interface is used in other package (1GK7M25)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6596">6596</a>
+Java compiler can generate invalid bytecode
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6586">6586</a>
+NullPointerException when resource modification done before java model is open
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6542">6542</a>
+extract method: incorrect error message  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6645">6645</a>
+Build/Rebuild does not recompile code  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6669">6669</a>
+Search doesn't find reference to a field that is only used in an initialization  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5385">5385</a>
+search: name searchDeclarationsOfSentMessages is not good  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3183">3183</a>
+JM - Builders and nested operations using Java model can get inconsistent results (1FUBV90)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3250">3250</a>
+JavaProject.retrieveResource picks first removed child delta (1GCV7PQ)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6378">6378</a>
+ClassCastException in inner class emulation  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6677">6677</a>
+\u in comment gives Invalid unicode error
+   
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011206 - 06th December 2001
+<br>Project org.eclipse.jdt.core v_217
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6564">6564</a>
+New builder - Incremental recompilation detected package problems incorrectly  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6563">6563</a>
+Package view does not refresh ok when adding both package and unit at once  
+
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3242">3242</a>
+TypeRef.getType does not work for inner types (1GCFUNT)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011204 - 4th December 2001
+<br>Project org.eclipse.jdt.core v_216c
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> New incremental builder implementation enabled by default (can reenable the 
+old implementation by changing the builder extension in the plugin.xml)
+<li> Delta processing improvement:
+	<ul>
+	<li> No longer creates unnecessary Java elements when traversing the resource delta.
+	<li> Handles changes in binary folder libraries.
+	<li> Projects that share libraries are notified individually.
+	<li> Doesn't notify empty deltas any longer.
+	</ul>
+<li> Source folder resource copying no longer perfom any copies as soon as
+one source folder coincidates with the output location.
+<li> Open on selection is more fault-tolerant: will now try to locate a
+selected method for which argument types are incorrect.
+<li> Compiler no longer rejects correct code with respect to access to protected
+members defined in enclosing types (was only accepting a subset of correct scenarii).
+</ul>
+<h3>
+Problem Reports Fixed</h3>
+
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6528">6528</a>:
+InvocationTargetException trying to search 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6494">6494</a>:
+New builder: Invalid error found (The declared package does not match the expected package) 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6461">6461</a>:
+NewBuilder - doesn't detect incorrectly located compilation units  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6456">6456</a>:
+Invalid error when compiling access to protected member inside innerclass 
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3358">3358</a>:
+Performance: indexer doing too much work? (1GJLDN7)  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5471">5471</a>: 
+CodeFormatter mapped positions broken for multi-line comments
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6431">6431</a>:
+ArrayIndexOutOfBoundsException in the SourceIndexer requestor
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6422">6422</a>:
+Resource copy should not occur as soon as one source folder overlap the
+binary output
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6416">6416</a>:
+Code resolve doesn't work on message send when parameters are not correct
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5705">5705</a>:
+Wrong positions for ClassCastLiteral
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6423">6423</a>:  
+Search - does not find declarations of method "to*String"  
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3246">3246</a>: 
+CodeCompletion - No completion on member access on anonymous class (1GD3OGA)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5454">5454</a>:
+Code Assist adds qualified code inside inner classes
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5837">5837</a>:
+ArrayIndexOutOfBoundsException in index merging
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011127 - 27th November 2001
+<br>Project org.eclipse.jdt.core v_215a
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+Better highlighting of multi-line message sending</li>
+
+<li>
+Code assist only qualifies implicit members when necessary</li>
+
+<li>
+New API for setting both classpath and output location at the same time
+(allowing to avoid classpath validation failures in case there is no way
+to change both independantly):
+
+<br><tt>IJavaProject.setRawClasspath(IClasspathEntry[] newClasspath, IPath
+newOutputLocation, IProgressMonitor monitor)</tt></li></ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6339">6339</a> Assertion
+failed in SourceType
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5618">5618</a>
+Uncaught CompletionNodeFound exception doing code assist
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6294">6294</a>
+Exception during setting the classpath
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6302">6302</a>
+AssertionFailure in open on selection
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6094">6094</a>
+Search - does not find references to JavaProject.setProject(...)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3320">3320</a>"
+Search - Match through super type not found if in different project (1GGAOFT)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6158">6158</a>"
+Search - Prefix and postfix expression not found as write reference
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4974">4974</a>:
+Set classpath / output location should be one operation
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6176">6176</a>:
+Eclipse tools index out of bounds
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6160">6160</a>:
+Index out of bounds in update references
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6151">6151</a>:
+ArrayIndexOutOfBoundsException in ObjectSet
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5943">5943</a>:
+internal error in setting buildpath (name collsion)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5471">5471</a>:
+CodeFormatter mapped positions broken for multi-line comments
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5907">5907</a>:
+Indexer errors when disk full
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5884">5884</a>:
+Code assist should only fully qualify if needed
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5514">5514</a>:
+Select a declaration does not work in unsaved working copies
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5414">5414</a>:
+ArrayIndexOutOfBoundsException in Signature
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5384">5384</a>:
+search engine: behavior different than expected
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6104">6104</a>:
+Unoptimal debugger highlight for multi-line message expression
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6210">6210</a>: Creation
+failed error when creating a source folder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3425">3425</a>:
+JavaCore.create(String handle) looses information (1GLA0QG)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6127">6127</a>:
+Reference by local class not found when searching for interface refs
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4990">4990</a>:
+Error starting Eclipse
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3471">3471</a>:
+Leading '/' in src page of Java wizard is misleading (1G842TH)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3619">3619</a>:
+inconsistent search for method declarations (1GCZZS1)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5557">5557</a>:
+Incorrect hierarchy shown (not rooted at Object)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6100">6100</a>:
+Bug in ObjectSet.Enumeration.nextElement
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011120 - 20th November 2001
+<br>Project org.eclipse.jdt.core v_213
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+CodeAssist no longer find synthetic completions.</li>
+
+<li>
+Reduced startup time of Java perspective</li>
+
+<li>
+CodeAssist option added to force full qualification of implicit field/method
+references (see JavaCore option: "org.eclipse.jdt.core.codeComplete.forceImplicitQualification").</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5982">5982</a>: content
+assist displays accessors
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5955">5955</a>:
+NPE in LookupEnvironment
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5923">5923</a>:
+Search for "length" field refs finds [].length
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5916">5916</a>:
+Search - too many matches for refs to NameLookup.findPackageFragmentRoot
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5957">5957</a>:
+Internal error in RecoveredMethod.add
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5972">5972</a>:
+Incremental builder (new) recompiling dependents of Parser for no apparent
+reason
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5940">5940</a>:
+Instance initializer in anon inner class generates errors
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5913">5913</a>:
+Performance - creating tons of classfile elements at startup
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5862">5862</a>:
+search : too many matches on search with OrPattern
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=6070">6070</a>:
+New Builder: Builder order problem
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5852">5852</a>:
+Project references not updated according to buildpath
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5471">5471</a>:
+CodeFormatter mapped positions broken for multi-line comments
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5563">5563</a>:
+Write reference on declaration not reported
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3257">3257</a>: IMethod.getParameterNames
+for ClassFiles should use names from source (1GDGN3G)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3245">3245</a>:
+sub folders with dot not visible in packages view (1GCOH17)
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011113 - 13th November 2001
+<br>Project org.eclipse.jdt.core v_211b
+<h2>
+What's new in this drop</h2>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5821">5821</a>: Refactor
+Rename renames local variable instead of member in case of name clash
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5003">5003</a>:
+Review JavaBuilder cancelation handling
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5790">5790</a>:
+IJavaProject.hasBuildState() fails with new builder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5794">5794</a>:
+Polymorphic search doesn't work in dependent projects
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5781">5781</a>:
+NPE using new image builder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5834">5834</a>:
+Incremental build recompiled unrelated project
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5215">5215</a>: search:
+missing field reference
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011112 - 12th November 2001
+<br>Project org.eclipse.jdt.core v_210_01
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+Project references are maintained by the JavaCore, in parallel with build
+path.</li>
+
+<li>
+Resurrected deprecated APIs from 0.9 which were discarded previously.</li>
+
+<li>
+ICodeCompletion reverted to 1.0 version, and got deprecated. Use ICompletionRequestor
+instead.</li>
+
+<li>
+Cross-project incremental recompilation in presence of structural changes
+in produced binaries.</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5362">5362</a>: Deeper
+than necessary JavaElementDelta when package added
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5525">5525</a>:
+ICodeCompletionRequestor isn't 1.0 compatible
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5616">5616</a>:
+NPE when compiling invalid code defining a array of strings
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5217">5217</a>:
+java search scope: missing enclosing project
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5527">5527</a>:
+Unexpected inaccurate matches for #close() declarations
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5522">5522</a>:
+Type hierarchy - missing subtypes of JavaElement
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5508">5508</a>:
+JDT cannot support periods in the folders above the package name
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5541">5541</a>:
+No refresh when adding a compilation unit inside a dot named source folder
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5532">5532</a>:
+Incremental compile missed a return type change
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5515">5515</a>:
+AbortCompilation during polymorphic search
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5275">5275</a>:
+Cross-project recompilation Defect 186249 - OTI PR# 1GLEYT1
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5267">5267</a>:
+Dependent Projects not compiled when project is saved
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5425">5425</a>:
+Exception on CodeAssist
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3194">3194</a>:
+DCR - JM - Buffer contents is duplicated (1G03HCP)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5430">5430</a>:
+Must resurrect 0.9 deprecated APIs
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4923">4923</a>:
+IJavaProject.getPackageFragmentRoots returns roots from other projects
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3308">3308</a>:
+Projects not build in correct order after load (1GF60TN)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3435">3435</a>:
+keeping the project references and required project in synch (1GL0L34)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5203">5203</a>:
+Project indexing does not restrain to source files on the classpath
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3293">3293</a>:
+search does not work in inner class (1GEUQHJ)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3249">3249</a>:
+Error message is confusing: using token instead of identifier (1GCTDYM)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5214">5214</a>:
+TVT: Apostrophe shows up multiple times in Java error messages in some
+translations (italian)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5263">5263</a>:
+TVT: Compiler error messages are hard for translators to understand
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3251">3251</a>:
+Types not included in code assist list for import (1GD06W9)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5277">5277</a>:
+Code assist on assert method do an AbortException
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5070">5070</a>:
+search: missing interface method reference
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5069">5069</a>:
+search: method reference in super missing
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5068">5068</a>:
+search: missing method reference
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5526">5526</a>: NullPointerException
+searching declarations of #close()
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5498">5498</a>:
+Java Compile - code does not compile correctly in JDT, but does with javac
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5493">5493</a>:
+Adding project references doesn't update the classpath
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5426">5426</a>:
+CodeAssist returns empty completion
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=1690">1690</a>:
+Local variables not always displayed when in scope (1GJ8PX4)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4368">4368</a>:
+Wrong match in Java Search
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3238">3238</a>:
+CodeAssist - no completion if cursor at string beginning (1GI3BYO)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3271">3271</a>:
+Unable to delete attached internal source jar (1GDX215)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3209">3209</a>:
+DCR - JM -Invalid references to IPath.getDevice() potentially breaking
+on Linux (1G4U1R7)
+<br>&nbsp;
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011025 - 25th October 2001
+<br>Project org.eclipse.jdt.core v_206
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+JavaModel is no longer performing smart classpath updates when Java package
+fragment roots are either moved or removed.</li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3568">3568</a>: no
+hoverhelp over constructor referrences (1GAJ0KP)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5218">5218</a>:
+AccSuper is not set properly
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5200">5200</a>:
+SetClasspathOperation must close root only when root is removed
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3449">3449</a>:
+CodeAssist - two type with same name must be qualified (1GLDN3Z)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4973">4973</a>:
+Rename package removes first letter of import statements
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3279">3279</a>:
+Severe - JM - Source found, even though sourcepath is false (1GELAVB)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3434">3434</a>:
+Deleting a project from the ws removes it from the buildpath! (1GKZNBS)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5021">5021</a>:
+Refactoring trashed my code
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5136">5136</a>:
+ArrayIndexOutOfBoundsException when a field declaration is an anonymous
+class
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3440">3440</a>:
+Classfile comparator should be able to ignore order (1GL2I7E)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3439">3439</a>:
+Classfile comparator should be able to ignore synthetics (1GL2I3N)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3442">3442</a>:
+NPE in SourceElementParser (1GL496I)
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3369">3369</a>: Classpath
+gets out of sync (1GJU853)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3281">3281</a>:
+change java project binary output create new package (1GEHK07)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3298">3298</a>:
+Incorrect compile error on valid case statement (1GEYWET)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3562">3562</a>:
+Outliner bug for initializers (1G93CS3)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3447">3447</a>:
+search: could automatically narrow down scope (1GLDJVN)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3288">3288</a>:
+CodeAssist - Code assist doesn't work in some methods (1GELEBH)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5073">5073</a>:
+delete does not work on default package
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3443">3443</a>:
+Unused argument/variable warnings shown twice (1GL4OW7)
+<br>&nbsp;
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011018 - 18th October 2001
+<br>Project org.eclipse.jdt.core v_205
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+CodeAssist provides variable name suggestions.
+
+<br>&nbsp;&nbsp;&nbsp; (breaking) API Changes on <tt>ICompletionRequestor</tt>
+<br>&nbsp;&nbsp;&nbsp; <b>+</b> <u>Added</u> API for suggest variable name:
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <tt>void acceptVariableName(</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] typePackageName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] typeName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] name,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] completionName,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionStart,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionEnd);</tt>
+<br>&nbsp;
+</li>
+<li>
+<p>Helper method for computing a resolved and expanded path (all exports from
+prerequisites) which was introduced in 204, got <u>removed</u>. This is
+not an API change, it never made it out officially.</p>
+
+<br>&nbsp;&nbsp; <b>-</b> <tt>IJavaProject.getExpandedClasspath(boolean)</tt>
+<p><tt>SearchEngine.createJavaSearchScope(IResource[])</tt> has been deprecated.
+Use <tt>SearchEngine.createJavaSearchScope(IJavaElement[])</tt> instead.
+The rational is that <tt>createJavaSearchScope(IResource[])</tt> was not
+well defined for projects, and it could not define a search scope for java
+elements that didn't have a corresponding resource (e.g. external jars).
+This deprecated API's behavior has also reverted to the 1.0 state for backward
+compatibility. The specification of <tt>createJavaSearchScope(IJavaElement[])</tt>
+is as follows:</p>
+<ul>
+<li>
+If an element is an <tt>IJavaProject</tt>, then the project's source folders,
+its jars (external and internal) and its references projects (with their
+source folders and jars, recursively) will be included.</li>
+
+<li>
+If an element is an <tt>IPackageFragmentRoot</tt>, then only the package
+fragments of this package fragment root will be included.</li>
+
+<li>
+If an element is an <tt>IPackageFragment</tt>, then only the compilation
+unit and class files of this package fragment will be included. Subpackages
+will NOT be included.</li>
+</ul></li>
+</ul>
+
+<h3>
+Problem Reports Fixed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=5065">5065</a>: NullPointerException
+in Code Assist
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4921">4921</a>:
+Serach does not find types in internal jar
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4917">4917</a>:
+Latest build fails updating TypeHierarchy
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3296">3296</a>:
+CodeAssist - should filter out duplicates if any (1GEWDL7)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3325">3325</a>:
+Too much codeassist match on interface (1GH0GV1)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3424">3424</a>:
+DCR: code assist support for variable name suggestions (1GKM6OQ)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3282">3282</a>:
+JCK 1.4 - DASG - assigned variable before catch block after return statement
+(1GK2AHX)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3452">3452</a>:
+NPE doing Display from Binary (1GLEG5K)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3374">3374</a>:
+SearchPatter.createPattern(...) doesn't work with unicodes (1GJYBRY)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3309">3309</a>:
+DCR - JM - could ICompilationUnit::getType throw JME? (1GF9AL9)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3310">3310</a>:
+Smoke 124: Compile errors introduced with rename refactoring (1GFBK2G)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3436">3436</a>:
+NPW in TypeHierarchy (1GL0L8D)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4919">4919</a>:
+Cannot duplicate local variable in finally block
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4943">4943</a>:
+Verification error
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=4385">4385</a>:
+QualifiedAllocationExpression.sourceEnd incorrect if type is an AnonymousLocalTypeDeclaration
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3230">3230</a>:
+Search - Too many type references for query ending with * (1GAZVGI)
+<h3>
+Problem Reports Closed</h3>
+<a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3174">3174</a>: Open-on-selection
+doesn't work on MouseAdapter (1GF69TH)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3337">3337</a>:
+Open on selection failed with double message (1GIFA80)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3207">3207</a>:
+JM - Smart save when empty CU (1G4EVHM)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=1672">1672</a>:
+Cannot evaluate classes in a sealed jar (1GHU6YK)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3220">3220</a>:
+Formatter tests refer to hardcoded path on disk (1G9R5G4)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3258">3258</a>:
+exception doing import assist (1GDIJ9D)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3240">3240</a>:
+need to find method declarations in anonymous inner types (1GCBPRI)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3254">3254</a>:
+Indexer - Should nest index source retrieval in IWorkspaceRunnable (1GD7J6F)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3225">3225</a>:
+IJavaProject.findPackageFragment strange semantic (1GAOLWQ)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3218">3218</a>:
+No interface to polymorphically acess ICompilationUnit (1G8D2ZP)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3205">3205</a>:
+Problems with IJavaModel.findPackageFragment (1G456DO)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3197">3197</a>:
+DCR - OpenOnSelection - Code resolve doesn't work on declarations (1G0UX9V)
+<br><a href="http://dev.eclipse.org/bugs/show_bug.cgi?id=3177">3177</a>:
+64kb method should be a configurable problem (1FJHGVF)
+<br>&nbsp;
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 20011011 - October 11th, 2001
+<br>Project org.eclipse.jdt.core v_204
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+Classpath entries (except for source folders) can be tagged as exported
+upon creation. When exported, an entry is contributed to dependent projects
+along with its output location.</li>
+
+<li>
+Added APIs:
+
+<br>&nbsp;&nbsp;&nbsp; Testing status of a given entry
+<br>&nbsp;&nbsp;&nbsp;&nbsp; + IClasspathEntry.isExported()</li></ul>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Creating
+entries with export flag
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
++ JavaCore.newProjectEntry(IPath, boolean)
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
++ JavaCore.newLibraryEntry(IPath, IPath, IPath, boolean)
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
++ JavaCore.newVariableEntry(IPath, boolean)
+<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Helper
+method computing a resolved and expanded path (all exports from prerequisites)
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
++ IJavaProject.getExpandedClasspath(boolean)
+<ul>
+<li>
+CodeAssist inserts qualification on field/method references in case of
+ambiguities.</li>
+
+<li>
+CodeAssist provides parameter names on method completions.
+
+<br>&nbsp;&nbsp;&nbsp; API Changes on ICompletionRequestor
+<br>&nbsp;&nbsp; + Added API for answering method declaration completions:
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void acceptMethodDeclaration(
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] declaringTypePackageName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] declaringTypeName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] selector,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterPackageNames,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterTypeNames,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterNames,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] returnTypePackageName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] returnTypeName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] completionName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int modifiers,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionStart,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionEnd);
+<br>&nbsp;&nbsp;&nbsp; + Added parameterNames to normal method results
+API:
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void acceptMethod(
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] declaringTypePackageName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] declaringTypeName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] selector,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterPackageNames,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterTypeNames,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[][] parameterNames,&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
+ADDED
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] returnTypePackageName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] returnTypeName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] completionName,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int modifiers,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionStart,
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int completionEnd);
+<br>&nbsp;
+</li>
+<li>
+CodeAssist optionally performs visibility checks (see JavaCore option:
+"org.eclipse.jdt.core.codeComplete.visibilityCheck").</li>
+
+<li>
+Search for field read and field write references. Two new constants have
+been added
+
+<br>&nbsp;&nbsp;&nbsp; on IJavaSearchConstants to be used when creating
+a field reference search pattern:
+<br>&nbsp;&nbsp;&nbsp; - READ_REFERENCES: the search results contain *only*
+read access to a field.
+<br>&nbsp;&nbsp;&nbsp; - WRITE_REFERENCES: the search results contain *only*
+write access to a field.
+<br>&nbsp;&nbsp;&nbsp; Note that if REFERENCES is used, then search results
+contain both read and write
+<br>&nbsp;&nbsp;&nbsp; accesss to a field.</li>
+<li>
+OpenOnSelection can now locate selected declarations which have a corresponding
+
+<br>&nbsp;&nbsp;&nbsp; Java element (i.e. no local declaration is found),
+and is more tolerant of
+<br>&nbsp;&nbsp;&nbsp; incorrect code.</li></ul>
+
+<h2>
+Problem Reports Fixed</h2>
+&nbsp; 3430&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; usability: parameter hints (1GKYXK5)
+<br>&nbsp; 3431&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Unreachable code in JCore
+(1GL2V6K)
+<br>&nbsp; 3175&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JCK1.3a - ICLS - Comparing
+current instance against enclosing instance inside of anonymous class.
+(1GLDSBS)
+<br>&nbsp; 1GLBOJZ:&nbsp; ITPJCORE:WIN2000 - UnaryExpression doesn't store
+expression type in bit mask
+<br>&nbsp; 1GDS7IP:&nbsp; ITPJCORE:WIN2000 - VerifyError related to a local
+index computation
+<br>&nbsp; 1GLABQ7: ITPJCORE:WIN2000 - JavaCore.create(String) throws an
+unexpected exception
+<br>&nbsp; 1GL0PGV: ITPJCORE:WINNT - Batch compiler leaving JARs open
+<br>&nbsp; 5268&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ITPJCORE:ALL - VerifyError when running app (1GL4QKI)
+<br>&nbsp; 1GLBP65: ITPJCORE:WIN2000 - search: type refs - incorrect match
+<br>&nbsp; 1GKXCOM: ITPJCORE:WIN2000 - ClassCastException during inner
+class emulation
+<br>&nbsp; 1GD07GK: ITPJUI:WIN98 - Code assist should qualify methods if
+needed.
+<br>&nbsp; 1GL1HF8: ITPJCORE:WIN2000 - Missing implementation in the compiler
+compiling invalid code
+<br>&nbsp; 1GL13OT: ITPJCORE:ALL - INameLookup should be removed
+<br>&nbsp; 1GL1I9F: ITPJCORE:WIN2000 - Wrong source mapping for binary
+methods with parameters with identical simple names
+<br>&nbsp; 1G4CIP0: ITPJUI:WIN - Source for binaries doesn't work for anonymous
+inner classes
+<br>&nbsp; 1GD79XM: ITPJCORE:WINNT - Search - search for field references
+- not all found
+<br>&nbsp; 1GLA60W: ITPJCORE:WINNT - CodeAssist - should not propose declarations
+of method already locally implemented
+<br>&nbsp; 1GLAEZB: ITPJCORE:WINNT - CodeAssist does not disambiguate method
+references
+<br>&nbsp; 1GL4F3J: ITPJCORE:WINNT - Completion on declaration should also
+provide thrown exceptions
+<br>&nbsp; 1GL11J6: ITPJCORE:WIN2000 - search: missing field references
+(nested types)
+<br>&nbsp; 1GL12XE: ITPJCORE:WIN2000 - search: missing field references
+in inner class
+<br>&nbsp; 1GL0X82: ITPJCORE:ALL - ClassCastException setting args on class
+file
+<br>&nbsp; 1GKAQJS: ITPJCORE:WIN2000 - search: incorrect results for nested
+types
+<br>&nbsp; 1GKZ8VZ: ITPJCORE:WINNT - Search - did not find references to
+member constructor
+<br>&nbsp; 1GKYS7Y: ITPJCORE:WINNT - Main not found
+<br>&nbsp; 1GELSDQ: ITPJUI:WINNT - JDOM: IType.createMethod does not insert
+nicely for inner types
+<br>&nbsp; 1GF67VL: ITPJUI:WIN98 - DCR - CodeCompletion - Code-assist for
+listener methods
+<br>&nbsp; 1GFK8YT: ITPJUI:ALL - Rename CU A.B.java to AB.java fails (NPE)
+<br>&nbsp; 1GD06J6: ITPJUI:WIN98 - Code assist should qualify fields if
+needed.
+<br>&nbsp; 1FZWGMG: ITPCOM:WIN98 - DCR - CodeAssist - code assist should
+provide method signature completions
+<br>&nbsp; 1GHVOQE: ITPJCORE:WINNT - Ambiguous completion in CodeAssist
+<br>&nbsp; 1G8DEAB: ITPJUI:WINNT - DCR: code assist super methods when
+defining method
+<br>&nbsp; 1GGNNDZ: ITPJCORE:WINNT - OpenOnSelection - non visible target
+is equivalent to no target
+<br>&nbsp; 1GE14NN: ITPJUI:WINNT - Unable to find/search for .class files
+<br>&nbsp; 1GJYFUO: ITPDUI:ALL - Evaluation hangs, evaluation thread is
+suspended
+<br>&nbsp; 1FWG453: ITPJCORE:WIN98 - OpenOnSelection - fails for default
+constructors
+<br>&nbsp; 1GDQD37: ITPJUI:WIN2000 - OpenOnSelection - Open on selection
+failure
+<br>&nbsp; 1GGZ2R7: ITPJUI:WIN2000 - Search for method refs failed
+<br>&nbsp; 1GKNXX6: ITPJCORE:WINNT - OpenOnSelection - no selection if
+targeting member type in default package
+<br>&nbsp; 1GE34EE: ITPJUI:WIN2000 - OpenOnSelection - initial selection
+wrong
+<br>&nbsp; 1GKEG73: ITPJCORE:WIN2000 - search (136): missing field declaration
+<br>&nbsp; 1GKB9YH: ITPJCORE:WIN2000 - search for field refs - incorrect
+results
+<br>&nbsp; 1GJL6EJ: ITPJCORE:WINNT - JavaConventions.validateClasspath:
+Compares against variable name
+<br>&nbsp; 1GDQEAS: ITPJUI:ALL - Indexer - delete unused indexes on Java
+core plug-in shutdown
+<br>&nbsp; 1GKM4M9: ITPJCORE:WINNT - DCR: code select should work on declarations
+<br>&nbsp; 1G2NZVT: ITPJUI:WIN2000 - DCR - OpenOnSelection - Code resolve
+doesn't work for declarations
+<h3>
+Problem Reports Closed</h3>
+&nbsp; 3223&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Search from editor's context
+menu doesn't work (1GAJCD8)
+<br>&nbsp; 3433&nbsp; search: missing field occurrecnces (1GKZ8J6)
+<br>&nbsp; 3176&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JCK1.3a - STMT - Single declaration
+in try block (1GLDSH9)
+<br>&nbsp; 1GL0MN9: ITPJCORE:WIN2000 - search: not consistent results for
+nested types
+<br>&nbsp; 1GL9UMH: ITPJCORE:WIN2000 - search: missing type occurrences
+<br>&nbsp; 1GKYXK5: ITPJUI:WIN2000 - usability: parameter hints
+<br>&nbsp; 1GEV78E: ITPJUI:WIN2000 - Code assist: private superclass methods
+show up, but others don't
+<br>&nbsp; 1GDKKTS: ITPJUI:WINNT - CodeCompletion - import assist shows
+invisible types
+<br>&nbsp; 1G7317O: ITPJCORE:WIN2000 - DCR - CodeAssist - code assist shows
+invisible members
+<br>&nbsp; 1GKK930: ITPJCORE:WINNT - No code assist for Inner type
+<br>&nbsp; 1GIIDGX: ITPJUI:WINNT - open on type: does not work on some
+types
+<br>&nbsp; 1GKOFO6: ITPJCORE:WINNT - Internal error searching for class
+references
+<br>&nbsp; 1GK96A0: ITPJCORE:WINNT - NPE during search operation
+<br>&nbsp; 1GK9B5Q: ITPJCORE:WINNT - Class reference search broken
+<br>&nbsp; 1GBOFK5: ITPJUI:ALL - "References to" on methods in jars
+<br>&nbsp; 1GKECWC: ITPJCORE:WINNT - Organize Imports fails: Typerefs not
+complete
+<br>&nbsp; 1GKCH3N: ITPJCORE:WIN2000 - search: method refs - super call
+not found
+<br>&nbsp; 1GKB475: ITPJCORE:WINNT - StringIndexOutOfBoundsException on
+searchfor methods
+<br>&nbsp; 1GJL6V0: ITPJCORE:WINNT - JavaConventions.validateClasspath:
+IStatus usage
+<br>&nbsp; 1GKM1MU: ITPJCORE:WINNT - Classpath validation: Overlapping
+accepted
+<br>&nbsp; 1GJL7RS: ITPJCORE:WINNT - JavaConventions.validateClasspath:
+nested sourcefolders
+<br>&nbsp; 1GK9NB0: ITPJCORE:WIN2000 - Another core dump - sorry
+<br>&nbsp; 1GJYG33: ITPJUI:WIN2000 - Core dump in run time workbench in
+Search
+<br>&nbsp; 1GK9S59: ITPJUI:WIN2000 - Internal error when synchronizing
+<br>&nbsp; 1GL2TZY: ITPJUI:WIN2000 - Code Completion should only show visible
+items
+<br>&nbsp; 1GKRLZ4: ITPJCORE:WIN2000 - Compiler overzealous with commas
+<br>&nbsp; 1GF98R4: ITPJUI:WINNT - JM - why is a file A.B.java seen as
+a compilation unit?
+<br>&nbsp; 1G98XR7: ITPJCORE:WIN2000 - Feature Request for JavaDoc CodeAssist
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK Build 0.202 - Spetember 27th, 2001
+<br>Project org.eclipse.jdt.core v_202
+<h2>
+What's new in this drop</h2>
+
+<ul>
+<li>
+New AST node for empty statements (org.eclipse.jdt.internal.compiler.ast.EmptyStatement)
+
+<br>&nbsp;&nbsp; i.e. 2 more APIs on the AST visitor. Note: this was not
+an official API
+</li><li>
+ISourceElementRequestor notifies enter/exit initializers instead of just
+acceptInitializer. Note: this was not an official API</li>
+
+<li>
+Search in inner-classes now works. Indexes are recomputed automatically
+on start-up.</li>
+
+<li>
+&nbsp; Removed CodeAssist option for hungry mode (org.eclipse.jdt.core.codeComplete.entireWordReplacement)
+
+<br>&nbsp;&nbsp; Client code can decide whether using inferred end position
+(hungry behavior) or original cursor location (insert behavior)
+<br>&nbsp;&nbsp; based on the keystroke (enter/insert?).</li>
+<li>
+&nbsp; org.eclipse.jdt.core.search.IJavaSearchResultCollector now clearly
+states that
+
+<br>&nbsp;&nbsp;&nbsp; the order of the search result is unspecified.</li></ul>
+
+<h2>
+Problem reports fixed</h2>
+&nbsp; 1GK2A45: ITPJCORE:WIN2000 - JCK 1.4 - possibly assigned variable
+after assignment expression when true
+<br>&nbsp; 1GK29Q8: ITPJCORE:WIN2000 - JCK 1.4 - possibly assigned value
+of a final instance variable after a constant boolean expression when false
+<br>&nbsp; 1G52F7P: ITPJCORE:WINNT - Search - finds bogus references to
+class
+<br>&nbsp; 1G4TNX1: ITPJCORE:WINNT - Search - No search anonymous results
+in inner classes
+<br>&nbsp; 1GHW0AZ: ITPJCORE:WINNT - JCK 1.4 - unreachable empty statements
+<br>&nbsp; 1GK2BLM: ITPJCORE:WIN2000 - JCK 1.4 - definitely assigned value
+after the boolean operator ? : when true
+<br>&nbsp; 1GKB28A: ITPJCORE:WIN2000 - Compiler accepts incorrect code
+<br>&nbsp; 1FL4T1Q: LFCOM:WINNT - JCK 1.4 - VerifyError due to an illegal
+jump
+<br>&nbsp; 1GK2B6D: ITPJCORE:WIN2000 - JCK 1.4 - definitely assigned value
+before the second operand of the boolean operator &amp;&amp;
+<br>&nbsp; 1GK2AOF: ITPJCORE:WIN2000 - JCK 1.4 - assigned variable before
+finally block after return statement
+<br>&nbsp; 1GK6WD3: ITPJCORE:WIN2000 - search:no fully qualified references
+are found
+<br>&nbsp; 1GK7231: ITPJCORE:WIN2000 - typos in comments
+<br>&nbsp; 1GK77HA: ITPJCORE:WINNT - Search - missing base type references
+<br>&nbsp; 1GJY2XN: ITPJUI:WIN2000 - rename type: error when with reference
+<br>&nbsp; 1GK1I2J: ITPJCORE:WIN2000 - Broken SourceEnd in ForStatement
+and WhileStatement
+<br>&nbsp; 1GK1HWY: ITPJCORE:WIN2000 - Broken sourceEnd in for Assignment
+and CompoundAssignment
+<br>&nbsp; 1GIIBC3: ITPJCORE:WINNT - search for method references - missing
+matches
+<br>&nbsp; 1GGNOTF: ITPJCORE:WINNT - Search doesn't find method referenced
+in anonymous inner class
+<br>&nbsp; 1GK1GJE: ITPJCORE:ALL - Search - StringOutBoundsException when
+searching references in JAR
+<h3>
+Problem Reports Closed</h3>
+&nbsp;1GJY3KG: ITPJUI:WIN2000 - NPE in jdt.internal.core.ClassFileInfo
+<br>&nbsp; 1GK90H4: ITPJCORE:WIN2000 - search: missing package reference
+<br>&nbsp; 1GK8TXE: ITPJCORE:WIN2000 - search: missing field reference
+<br>&nbsp; 1GK7K17: ITPJCORE:WIN2000 - search: missing type reference
+<br>&nbsp; 1GKCJIL: ITPJCORE:WIN2000 - build exception in 135
+<br>&nbsp; 1GK6WP9: ITPJCORE:WIN2000 - seach: missing type reference
+<br>&nbsp; 1GJZSBE: ITPJCORE:WINNT - ArrayIndexOutOfBoundsException during
+rebuild
+<br>&nbsp; 1GK7E6S: ITPJCORE:WIN2000 - search: StringIndexOufOfBound
+<br>&nbsp; 1GIT857: ITPJCORE:WIN2000 - Performance - Ctrl+S triggers five
+parser runs
+<br>&nbsp; 1GEHCYL: ITPUI:WINNT - Minor: Colon at wrong place in build
+dialog
+<br>&nbsp; 1FLUBRR: JRIDE:WINNT - Problems: instantiating inner classes
+<br>&nbsp; 1FLUOJI: JRIDE:WINNT - Problems: vague error message with illegal
+constructor invocation
+<br>&nbsp; 1FLZUG5: JRIDE:WINNT - Problems: invalid expression as statement
+is not reported
+<br>&nbsp; 1FLZV4M: JRIDE:WINNT - Problems: invalid hexa literal number
+not reported
+<br>&nbsp; 1FLZYES: JRIDE:WINNT - Problems: the interface cannot define
+an initializer is not reported
+<br>&nbsp; 1FQVTI1: LFCOM:WINNT - Compiler - No implicit conversion should
+not generate aconstnull
+<br>&nbsp; 1FUZYXT: ITPJCORE:WINNT - JM - Source for Binaries issue
+<br>&nbsp; 1FX0LZ0: ITPCOM:ALL - Request for comments preceeding imports
+&amp; package decls
+<br>&nbsp; 1FW8ENP: ITPJUI:WIN98 - JDOM - Deleting import statements from
+Outline obliterates intervening comments
+<br>&nbsp; 1G4PWC7: ITPJCORE:WINNT - Search - No matches with class files
+<br>&nbsp; 1G83ZKL: ITPJUI:WINNT - Compiler - unclear error message for
+a reserved word used as an identifier
+<br>&nbsp; 1GF5W1S: ITPJUI:WIN2000 - ClassCastException in LookupEnvironment
+<br>&nbsp; 1GKF01S: ITPJCORE:WINNT - Severe: internal error during search
+<br>&nbsp; 1GDVFRX: ITPJUI:WIN2000 - CodeCompletion - eats the following
+word
+<br>&nbsp; 1GF67JM: ITPJUI:WIN98 - CodeCompletion - Code-assist consumes
+next token
+<br>&nbsp; 1GCSHAC: ITPJCORE:Inconsistent codeassist behavior
+<br>&nbsp; 1GCNBTL: ITPJCORE:ALL - DCR - JM - Provide a way to read JavaCore
+default options from the plugin.xml file
+<br>&nbsp; 1GAJBOU: ITPJUI:WINNT - Code Assist shows matches after ()
+<br>&nbsp; 1FW8NV6: ITPJCORE:ALL - DCR - JM - Need API for compiler options
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Build 0.200 - September 13th, 2001
+<br>Project org.eclipse.jdt.core v_200
+<h2>
+What is new in this drop</h2>
+
+<ul>
+<li>
+JCK1.3a compliant.</li>
+
+<li>
+Added 2 new APIs on JavaConventions for classpath validation.
+
+<ul>
+<li>
+IJavaModelStatus validateClasspath(IJavaProject project, IClasspathEntry[]
+classpath, IPath outputLocation)</li>
+
+<li>
+IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry
+entry, boolean checkSourceAttachment)</li>
+</ul>
+</li>
+<li>
+Ant Eclipse compiler task added (org.eclipse.jdt.core.ant.Jdtcom)</li>
+
+<li>
+Assertions support enabled: by default the compiler is 1.3 compliant, but
+it can optionally be turned into source 1.4 mode cf. JavaCore options.</li>
+
+<li>
+More options are surfaced on JavaCore. See JavaCore.getDefaultOptions()
+for description.
+
+<ul>
+<li>
+...internal...ConfigurableOption has disappeared.</li>
+
+<li>
+Evaluation in binaries is functional</li>
+</ul>
+</li>
+<li>
+Search for references now finds results in binaries. Indexes in old workspaces
+are recomputed when restarted which may result in longer startup times.</li>
+</ul>
+
+<h2>
+Problem Reports Fixed</h2>
+1GEKKUO: ITPJCORE:ALL - JM - Util.readContentsAsBytes(InputStream) doesn't
+allow for size hint
+<br>1GBRPSJ: ITPJCORE:Options - should surface the code formatter options
+on JavaCore
+<br>1GJU3YV: ITPJCORE:ALL - ArrayIndexOutOfBoundsException in scanner
+<br>1GJL1R5: ITPJCORE:ALL - NPE in ClassFile.getSourceRange
+<br>1GH49XR: ITPJUI:WIN2000 - Organize Imports inserts bogus import
+<br>1GJU3O8: ITPJCORE:WINNT - type hierarchy: NPE
+<br>1GJIYKP: ITPJCORE:WINNT - type hierarchy - contains unrelated types
+<br>1GITFQR: IVJIDT:WIN2000 - Wrong byte code generation, Inconsistent
+stack height 1 != 0 error
+<br>1GIHUQP: ITPJCORE:WINNT - search for static field should be more accurate
+<br>1GIT66X: ITPJCORE:WINNT - ClassCastException when calling CodeAssist
+<br>1GJA0WG: ITPJCORE:WINNT - AbortCompilationUnit when doing a Search
+<br>1GH49HW: ITPJUI:WINNT - Search functionality is misleading when viewing
+source from jar
+<br>1GFXPE5: ITPJUI:ALL - Search for method references broken
+<br>1GFM3X3: ITPJUI:WINNT - Wrong code formatter default for keeping else
+on same line
+<br>1GHSM7B: ITPJUI:ALL - formatting of anonymous classes
+<br>1GGPVHN: ITPJUI:WIN2000 - Not getting hover Javadoc for ISelection
+<br>1GE2LO2: ITPJCORE:WIN2000 - SourceStart and SourceEnd of synchronized
+statement
+<br>1GIUTIZ: ITPJCORE:WIN2000 - AST: case statement doesn't cover case
+keyword
+<br>1GITCCY: ITPJCORE:WIN2000 - AST: strange LocalDeclaration.declarationSourceEnd
+<br>1GIRQFW: ITPJCORE:WIN2000 - AST: wrong source end if subnode is of
+type AnnonymousTypeDeclaration
+<br>1GIRHRP: ITPJCORE:WIN2000 - AST: wrong sourceStart and sourceEnd in
+SynchronizedStatement
+<br>1GHUAUO: ITPJCORE:ALL - Renaming an element in a working copy corrupts
+the working copy
+<br>1GHUAM1: ITPJCORE:ALL - NPE when renaming an element in a working copy
+<br>1GHDA2V: ITPJCORE:WINNT - ClassCastException when doing a search
+<br>1GFY02B: ITPJUI:ALL - Delete a method and saving introduces extra lines
+<br>1GFOFMD: ITPJUI:WIN2000 - New class should have space between package
+and class decls
+<br>1GI3R1I: ITPJCORE:WIN2000 - Compilation error evaluating super expression
+in debugger
+<br>1GII07V: ITPJCORE:WIN2000 - CompilationUnitDeclaration.traverse doesn't
+call visitor.endVisit
+<br>1GIR345: ITPJCORE:ALL - Indexer: NegativeArraySizeException
+<br>1GIRC23: ITPJCORE:ALL - CodeFormatter brace on new line problem
+<br>1GIT8SA: ITPJCORE:WIN2000 - AST: wrong sourceEnd if action is Block
+<br>1GIUQVL: ITPJCORE:WINNT - IClassPathEntry: java doc incorrect
+<br>1GIVGMH: ITPJUI:ALL - EC: Javadoc hoverhelp incorrectly uses first
+of multiple comments
+<br>1GIYKSR: ITPJCORE:WIN2000 - Ast: FieldDeclaration.traverse implemeted
+differently
+<br>1GI3ND5: ITPJCORE:WINNT - Potential optimization during IB problem
+generation
+<br>1GFBVZH: ITPUI:WIN2000 - ArrayIndexOutOfBoundsException: Java editor
+<br>1GI509E: ITPJCORE:WINNT - IJavaProject.getNonJavaResources returns
+java and class files
+<br>1GI2WAW: ITPJCORE:WINNT - Too many results for default package
+<br>1GHQZ9H: ITPJUI:ALL - Walkback doing a search
+<br>1GGYT3S: ITPJCORE:WINNT - javaconventions::validatePackageName and
+default package
+<br>1GF9856: ITPJCORE:WINNT - JM - JavaConventions::validateCompilationUnitName
+<br>1GF822P: ITPJCORE:WIN2000 - NegativeArraySizeException in Parser
+<br>1GI6T4Y: ITPJCORE:WINNT - NPE in JavaModeManager retrieving workspace
+options
+<br>1GE4ILR: ITPJCORE:ALL - Eval - Evaluation in Binary Project fails
+<br>1GI3LLC: ITPJCORE:ALL - Incorrect formatting for the new keyword
+<br>1GHU6O5: ITPJCORE:WINNT - RMIC test fail
+<br>1GHH6O7: ITPJCORE:ALL - Need to tune the exception analysis for AssertStatement
+<br>1GHUW7T: ITPJCORE:WIN2000 - Build Problem
+<br>1GI3IG9: ITPJCORE:ALL - internal compiler error involving bogus method/field
+declaration
+<br>1GHU4PK: ITPJCORE:WINNT - NoSuchMethodError when running program
+<br>1GHONAX: ITPJCORE:WIN2000 - Compiler uses different name lookup for
+refactoring
+<br>1GEJYAJ: ITPJCORE:WIN2000 - Compiler - Binding of QualifiedNameReference
+is null
+<br>1GHFHWR: ITPJCORE:ALL - Assertions: CodeAssist and Selection need to
+be updated
+<br>1GHFHXG: ITPJCORE:ALL - Assertions: Add optional warning on assert
+identifier
+<br>1GCZ9VM: ITPJCORE:WIN2000 - DCR - Compiler - Batch compiler should
+be API
+<br>1GHO6QR: ITPJCORE:WINNT - Code Assist - no method completion when return
+type is secondary one
+<br>1GH0AU7: ITPJCORE:ALL - Eval - VerifyError in scrapbook page
+<br>1GH2R62: ITPJCORE:WIN2000 - Typo in progress message
+<br>1GGYL32: ITPJCORE:ALL - Default supertypes are not visible when qualified
+<br>1GDFJK0: IVJIDT:WIN2000 - Using 'synchronized' produces invalid exception
+table values in class, causes "Illegal exception table range" exception,
+VAJ 3.5+
+<br>1GGAK6G: ITPJCORE:ALL - Incorrect javadoc comment in JavaElement
+<br>1GF9L3K: ITPDUI:ALL - Eval - Private array resolution failure
+<br>1GF8KHX: ITPJUI:ALL - Invalid project build path should be warning,
+not error
+<br>1GF7JIH: ITPJCORE:ALL - Exception when removing network drive
+<br>1GEYBL9: ITPJUI:WINNT - Adding source folders on CP is very confusing
+<br>1GEJAOT: ITPJUI:WINNT - JRE Source attachment set to path to does not
+exist
+<br>1GEHZNB: ITPJUI:WINNT - smoke 114: formatter inserts extra tab in first
+line
+<br>1GCZZT4: ITPJCORE:Fault-tolerance - missing constructor invocation
+could still answer the allocated type
+<br>1GAU96P: ITPJCORE:WINNT - DCR - JM - JavaProject should provide a class
+path validation method
+<br>1G7A1TL: ITPJCORE:WINNT - DCR - JM - Rules for classpath not specified
+<br>1FVVWZT: ITPJCORE:ALL - JM - IBinaryType should implement getSourceFileName()
+<br>&nbsp;
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html
new file mode 100644
index 0000000..cfaf7b3
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html
@@ -0,0 +1,3306 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>JDT/Core Release Notes</title>
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
+</head>
+<body 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 2.1 stream</b></font>
+	</td>
+  </tr>
+  <tr>
+	  <td align="left" width="72%" class="title2">
+	  	  <font size="-2" color="#8080ff">Java development tools core</font>
+	  </td>
+  </tr>
+	<tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  Here are the build notes for the Eclipse JDT/Core plug-in project 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
+	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
+	  This present document covers all changes since Release 2.0, changes which occurred up to Release 2.0 can be found
+	  in <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html">build notes R2.0</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 27th March 2003
+<br>Project org.eclipse.jdt.core v_311 - 2.1 RELEASE (R2_1)
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35731">35731</a>
+Unable to build problem
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35754">35754</a>
+NPE in Scope.getTypeOrPackage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35298">35298</a>
+NPE: Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31497">31497</a>
+Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35476">35476</a>
+Null pointer exception in org.eclipse.jdt.internal.compiler.lookup.Scope.getTypeOrPackage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34962">34962</a>
+NPE in Scope.getTypeOrPackage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35651">35651</a>
+"Unused private types, methods or fields" should recognize serialVersionUID.
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 26th March 2003
+<br>Project org.eclipse.jdt.core v_310
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24240">24240</a>
+DOC - JavaConventions.validateIdentifier: must NOT have the same spelling as ...
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35658">35658</a>
+Cannot resolve Inner Class reference
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 25th March 2003
+<br>Project org.eclipse.jdt.core v_309
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35654">35654</a>
+spec bug in CompilationUnitSorter.sort
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35561">35561</a>
+No source found if attached file contains 2 potential root paths
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35352">35352</a>
+NPE when attaching source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35456">35456</a>
+The Eclipse compiler generates classes that throw a VerifyError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35473">35473</a>
+NPE when exiting Eclipse
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35510">35510</a>
+Assigning code to a library that is within a jarfile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35642">35642</a>
+NPE in index manager during shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35608">35608</a>
+NPE on shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35437">35437</a>
+can't call protected methods from derived classes in other pkg
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35396">35396</a>
+Compiler error in RC2
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 20th March 2003
+<br>Project org.eclipse.jdt.core v_308 - 2.1 RELEASE CANDIDATE 3a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35306">35306</a>
+Index update request can be incorrectly handled
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 19th March 2003
+<br>Project org.eclipse.jdt.core v_307 - 2.1 RELEASE CANDIDATE 3
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34040">34040</a>
+It takes a minute to expand a project in Package explorer
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 18th March 2003
+<br>Project org.eclipse.jdt.core v_306 
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35237">35237</a>
+Ant adapter should say where to look for the .log file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35132">35132</a>
+Need to reindex jar not on classpath not detected 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35131">35131</a>
+Optimize source attachment query when no source attachment available 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35128">35128</a>
+Problems with packages named "java"
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34214">34214</a>
+createPackageDeclaration on ICompilationUnit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35098">35098</a>
+Delete compiled class files when deleting source file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35087">35087</a>
+NPE while importing plug-ins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34850">34850</a>
+Need better control over deprecation messages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34322">34322</a>
+SDK hangs while building on IBM1.3.1SR2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30418">30418</a>
+Inner classes cause compilation errors with asserts 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34789">34789</a>
+Search for references does not show subclassed methods 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33885">33885</a>
+packages with javax in their name don't import properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34992">34992</a>
+TODO as a substring in a comment generates a task 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34708">34708</a>
+unreliable full build/refresh using linked source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35093">35093</a>
+Not only changes in working copy should refresh type hierarcy. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34851">34851</a>
+Rename Class operation hangs 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 13th March 2003
+<br>Project org.eclipse.jdt.core v_305
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34845">34845</a>
+asserts do not need to be NLS'ed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34658">34658</a>
+Save All failed with unhelpful error message.
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34802">34802</a>
+instanceof produce InternalCompilerError on MacOSX with JDK1.4.1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34734">34734</a>
+internal compiler error ArrayIndexOutOfBound w/ 1.4.1 release
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34706">34706</a>
+Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34907">34907</a>
+ArrayIndexOutOfBoundsException after installing Java 1.4.1_01
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34029">34029</a>
+"False-positive" deprecated warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34813">34813</a>
+NPE from builder
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 11th March 2003
+<br>Project org.eclipse.jdt.core v_304
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927">33927</a>
+Leak in Java Editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33950">33950</a>
+Slow performance when changing code in a much referenced project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34000">34000</a>
+JDK Compliance doesn't match javac generation from an IBM or SUN JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34078">34078</a>
+Hierarchy: 27% of time spent reporting progress 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33998">33998</a>
+unexpected NullPointerException 
+   
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34566">34566</a>
+can't get assert to work with mac os x java 1.4.1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34337">34337</a>
+[RC2] Searches freezes ?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33412">33412</a>
+GB18030: Can't set JRE in a path contains GB18030 characters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34292">34292</a>
+[RC2] OutOfMemory compiling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34130">34130</a>
+Debug statements on console
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34301">34301</a>
+Java compiler doesn't dected always unreported exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32927">32927</a>
+Exception while playing with type hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34059">34059</a>
+When adding a library that is stored in a directory containing a "(" or ")" the classes are  *not* reachable for Code Assist.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33900">33900</a>
+NPE setting output directory of a source folder
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 6th March 2003
+<br>Project org.eclipse.jdt.core v_303 - 2.1 RELEASE CANDIDATE 2
+<h2>
+What's new in this drop</h2>
+<ul>
+<li><code>IJavaProject.isOnClasspath(...)</code> no longer throws any exception, but rather consistently return <code>false</code>
+in these circumstances. Indeed, it is difficult for clients to work with predicates that throw exceptions. 
+Although this change creates a source incompatibility, the change is binary compatible with 2.0 and within the original 
+spirit of the original API contract. Include in 2.1 readme.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33990">33990</a>
+.class file time-stamps out of sync with .java files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32665">32665</a>
+Closing element trace should hide children 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32634">32634</a>
+Improve readability of compiling progress message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33949">33949</a>
+DOM: assert statement has wrong length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33695">33695</a>
+project build path broken 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33475">33475</a>
+Build path seems to be lost every time Eclipse restarts 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33785">33785</a>
+Open on selection fails 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33800">33800</a>
+search: reporting too many method occurrences 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33806">33806</a>
+Code assist failure: assignment of double in for loop hides previous variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33754">33754</a>
+IJavaProject.isOnClasspath should answer false for working copies outside the classpath
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33918">33918</a>
+Libraries are not presented in the Package Explorer (I030227)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33843">33843</a>
+Compiler incorrectly generating static method calls
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33625">33625</a>
+Searching for field references with SearchEngine returns some incorrect results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31610">31610</a>
+IDE does hang-up
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 4th March 2003
+<br>Project org.eclipse.jdt.core v_302a
+<h2>
+What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33757">33757</a>
+Problem not detected when opening a working copy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33753">33753</a>
+Missing resource messages could be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33748">33748</a>
+Cannot open working copy on .java file in simple project 
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 4th March 2003
+<br>Project org.eclipse.jdt.core v_302
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Generalization of working copy deltas: the creation and destruction of any working copy (regular or shared) 
+	now fires an <code>ElementChangedEvent</code> as well indicating that the working copy has been 
+	<code>ADDED</code> or <code>REMOVED</code>. 
+	Until now, only shared working copies were providing such delta notifications.
+      <br>See: 
+      <ul>
+      <li><code>IWorkingCopy.getWorkingCopy()</code></li>
+      <li><code>IWorkingCopy.getWorkingCopy(IProgressMonitor, IBufferFactory, IProblemRequestor)</code></li>
+      <li><code>IWorkingCopy.destroy()</code></li>
+      </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31799">31799</a>
+Getting squigglies in Java files not on classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31858">31858</a>
+NPE in log 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33371">33371</a>
+Rename method dialog: Error message should quote name 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33686">33686</a>
+Missing extension point schemas
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32981">32981</a>
+Cancel Extract Interface refactoring does not cleanup working copies 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33692">33692</a>
+Cleanup in the batch compiler default options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33653">33653</a>
+Relevance - should privilege type not needing qualification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33039">33039</a>
+Quick Fix: IAE n invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32588">32588</a>
+Error saving changed source files; all files in project deleted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33560">33560</a>
+Workspace shows temporary problems also the compiler doesn't
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31765">31765</a>
+private recursive methods not marked as unused
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33231">33231</a>
+Deadlock performing CVS decoration while JRE initializers are invoked
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33571">33571</a>
+SearchEngine.searchAllTypeNames: NPE when passing null as progress monitor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33035">33035</a>
+OutOfMemoryException while searching for references 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33445">33445</a>
+CodeAssist - Relevance is not correct for local class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33462">33462</a>
+NPE during shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33424">33424</a>
+No completion available in local type constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33225">33225</a>
+Override methods... inserts methods incorrectly if class body is as {}
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33207">33207</a>
+Reject output folder that coincidate with source folder if not equal
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33621">33621</a>
+ICompilationUnit.getElementAt(int) returns strange things when parameter is in a field declaration inside anonymous and local classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33696">33696</a>
+Java source exclusion filter stopped working in RC1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32250">32250</a>
+Reporting unused private methods could be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33610">33610</a>
+Deltas sent while in operation executed with JavaCore.run
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33573">33573</a>
+NPE in IndexManager on shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33527">33527</a>
+Inexact match searching in java.math.BigDecimal 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33505">33505</a>
+Compiler fails on allowed inner class code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33461">33461</a>
+NPE upon shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33466">33466</a>
+NPE on shutdown from IndexManager
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33475">33475</a>
+Build path seems to be lost every time Eclipse restarts
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 27th February 2003
+<br>Project org.eclipse.jdt.core v_301
+<h2>
+What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33321">33321</a>
+NPE in IndexManager shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31764">31764</a>
+CompletionEngine doesn't feed errors to completion requestor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32488">32488</a>
+Request to add/remove source folder to index should not look at active job 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32392">32392</a>
+NPE in SourceMapper 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32701">32701</a>
+Disassembler doesn't show actual modifiers for member types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32919">32919</a>
+Hierarchy views progress bar is useless 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32973">32973</a>
+Codeassist relevance should privilege prefix match over need for qualification 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32629">32629</a>
+DeltaProcessor walking some binary output 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32612">32612</a>
+Saved index file names leaking names?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32376">32376</a>
+Signature.getSimpleName/Qualifier should not create an own char-array 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32628">32628</a>  
+Too much time finding out there is no source during search 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32974">32974</a>
+Invalid classpath error on ..classpath edition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32986">32986</a>
+Stack overflow, infinate recursion in compiler 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32607">32607</a>
+Removing outer folder removes nested folder's cus from index 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32937">32937</a>
+Kind not set for empty fine-grained delta 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32909">32909</a>
+compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32690">32690</a>
+Classpath error are not detected after a Check out
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32738">32738</a>
+TVT: Externalized Strings to be removed from .properties file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32957">32957</a>
+StackOverFlowError renaming class 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32323">32323</a>
+CVS information on class-Files lost during "rebuild project"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32563">32563</a>
+IAE in org.eclipse.jdt.core.Signature.toCharArray (M5) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32900">32900</a>
+Java out of memory problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25848">25848</a>
+RedHat Linux LANG=en_US.UTF-8  causes some files *NOT* to be compiled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32579">32579</a>
+abstract protected method can't be overridden
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32545">32545</a>
+Cannot override a method that's accessible in the superclass, but inaccessible in the super-superclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32179">32179</a>
+Problems searching for references to selected text
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 21st February 2003
+<br>Project org.eclipse.jdt.core v_300 - 2.1 RELEASE CANDIDATE 1
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In 1.4 compliant mode, the compiler will allow unterminated line comment (i.e. with no trailing line separator), as a consequence
+of the JLS revisal. Thus removed temporary (and unused) 2.1 API :
+<code>ToolFactory.createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean assertMode, boolean recordLineSeparator, <b>boolean strictComment</b>)</code>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32342">32342</a>
+The field type Class_A is defined in an inherited type and an enclosing scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32476">32476</a>
+Spec now allows line comment to end with EOF
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32339">32339</a>
+Cannot find declaration of SIGNATURE in Java text search
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 20th February 2003
+<br>Project org.eclipse.jdt.core v_299
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added helper method to extract problem marker arguments: <code>CorrectionEngine.getProblemArguments(IMarker problemMarker)</code>
+<li>Added 2 settings to disable classpath enhancements which could affect 2.0 clients.
+<pre>
+* JAVACORE / Enabling Usage of Classpath Exclusion Patterns
+*    When set to "disabled", no entry on a project classpath can be associated with
+*    an exclusion pattern.
+*     - option id:         "org.eclipse.jdt.core.classpath.exclusionPatterns"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "enabled"
+* 
+* JAVACORE / Enabling Usage of Classpath Multiple Output Locations
+*    When set to "disabled", no entry on a project classpath can be associated with
+*    a specific output location, preventing thus usage of multiple output locations.
+*     - option id:         "org.eclipse.jdt.core.classpath.multipleOutputLocations"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "enabled"
+</pre>
+<li>Removed temporary 2.1 API :
+    <ul>
+     <li><code>IPackageFragmentRoot.computeSourceAttachmentRootPath(IPath sourceAttachmentPath)</code>
+     </li>
+     <li><code>IJavaModelMarker.UNBOUND_CONTAINER</code>, use classpath problem marker ID instead (<code>IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND</code>).
+     </li>
+     <li><code>IJavaModelMarker.UNBOUND_VARIABLE</code>, use classpath problem marker ID instead (<code>IJavaModelStatusConstants.CP_VARIABLE_PATH_UNBOUND</code>).
+     </li>
+    </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29578">29578</a>
+Issues with migrating shared data
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32040">32040</a>
+Multiple output folders fooling Java builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32217">32217</a>
+Missing JavaCore in JDT/Core project index
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32338">32338</a>
+Auto generated comments of quickfix method generation for unnamed package class is wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32271">32271</a>
+Type Hierarchy Progress monitor improvements 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32267">32267</a>
+TypeHierarchy. Does not set progress monitor to done when cancelled 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32218">32218</a>
+Inexact matches found when should be exact 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31016">31016</a>
+builder exception found in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32225">32225</a>
+incorrect delta after deleting 2 fields 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32219">32219</a>
+JavaModel operations fail with ArrayIndexOutOfBoundsException if array empty
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32182">32182</a>
+NPE performing search 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27994">27994</a>
+Code Assist replace mode inconsistent 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041">32041</a>
+Multiple output folders fooling Java Model 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196">32196</a>
+Patch: correctly detect misisng .rsc file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32111">32111</a>
+ArrayIndexOutOfBoundsException during delete of members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32100">32100</a>
+when superpackage package empty deleting a subpackage deletes superpackage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31646">31646</a>
+No proposal using code assist in field initializer
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32227">32227</a>
+Serialization incompatibility with Sun's 1.4 compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28426">28426</a>
+Content Assist displays x(String arg0, String arg1) should be x(String str, String delim)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32164">32164</a>
+Serialization methods with private or arbitrary access modifiers should be ignored by "unused private members" compiler check.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32097">32097</a>
+Regression - attached source not found when in a subdirecory of archive
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 18th February 2003
+<br>Project org.eclipse.jdt.core v_298
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31997">31997</a>
+     requires the index format to be changed. Indexes will be automatically regenerated upon
+     subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Unused parameter diagnosis will now ignore parameters in an abstract method,
+a main method, an implementation of an abstract method or a method overriding a
+concrete one. Additional settings got added for enabling the diagnosis of the latter
+two scenarii.
+<pre>
+* COMPILER / Reporting Unused Parameter if Implementing Abstract Method
+*    When enabled, the compiler will signal unused parameters in abstract method implementations.
+*    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "disabled"
+*
+* COMPILER / Reporting Unused Parameter if Overriding Concrete Method
+*    When enabled, the compiler will signal unused parameters in methods overriding concrete ones.
+*    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedParameter".
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "disabled"
+</pre>
+</li>
+<li><b>Code completion enhancement:</b>
+   <ul>
+   <li>Relevance of a proposal is higher if the proposal is a variable name and this name contains a prefix.</li>
+   <li>Relevance of a proposal is higher if the proposal is a variable name and this name contains a suffix.</li>
+   </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32107">32107</a>
+Index signature change isn't honoured any longer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31997">31997</a>
+Refactoring d.n. work for projects with brackets in name. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31417">31417</a>
+Where has the "Root Path" field gone? [doc] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32000">32000</a>
+IJavaModel.contains() returns true for resources copied into bin folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31947">31947</a>
+NPE on shutdown in BlocksIndexInput.close()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31985">31985</a>
+NPE searching non-qualified and case insensitive type ref 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28637">28637</a>
+[Preferences] Import Preferences: Console Message: Content is not allowed in Prolog 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31748">31748</a>
+[search] search for reference is broken 2.1 M5 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31990">31990</a>
+Working copy operations should not take workspace lock 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31811">31811</a>
+VerifyError with huge switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5783">5783</a>
+Problem counts are not accumulated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31652">31652</a>
+NamingConvention.suggestXXNames: Put the most relevant first
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31628">31628</a>
+Redundant import need a warning (matching package declaration)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31867">31867</a>
+No unused import diagnosis on duplicate import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31495">31495</a>
+Should writeObject/readObject be a compiler warning?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31538">31538</a>
+serialVersionUID being flagged as an "unused" field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31757">31757</a>
+Folder with invalid pkg name should be non-Java resource 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25204">25204</a>
+Eclipse compiler option: Unused parameters (i.e. never read)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27251">27251</a>
+Compiler preferences: Unused parameters - ignore main
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31383">31383</a>
+Strange rendering of of link resources when link points to Eclipse workspace 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31756">31756</a>
+Code assist: fails inside an array which inside a function call 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31248">31248</a>
+Java Compiler progress monitor tells about probelms found
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29790">29790</a>
+OOM Exception in search cause IDE freeze
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32083">32083</a>
+overridden methods that change visibility cause compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32044">32044</a>
+Pre auto build notification fired when closing or opening a file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31903">31903</a>
+Null pointer exception loading from respository
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31968">31968</a>
+Notifier loose nested levels
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31942">31942</a>
+Bug with Selection Statement switch()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31916">31916</a>
+M5 Crashing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31923">31923</a>
+Source folder specific compiler settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31917">31917</a>
+Unused private method warning doesn't know about read/writeObject
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8452">8452</a>
+Wrong position in FieldReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12797">12797</a>
+Can't add directory pointing to class-files to project classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11023">11023</a>
+Filter code assist choices based on context
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7293">7293</a>
+Scrubbing Output Directory Can Cause Havoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6096">6096</a>
+Exception using code assist after package rename
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5043">5043</a>
+Feature Request: source folders in other projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6488">6488</a>
+Classpath Variables (allow plugins to reserve some)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31809">31809</a>
+Eclipse reports error in task view - but it's no error!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28319">28319</a>
+Unused parameter should be limited to current method/class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31243">31243</a>
+Warn of unused parameters: Should not warn when method overrides
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28139">28139</a>
+Highlight unused method parameters that are not inherited
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31380">31380</a>
+NPE setting classpath
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 13th February 2003
+<br>Project org.eclipse.jdt.core v_297
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>To help fixing bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31135 ">31135</a>,
+      added new flag <code>F_REORDER</code> on <code>IJavaElementDelta</code>. This flag is 
+      positioned if a member in a compilation unit has changed its position relatively to its siblings.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31476">31476</a>
+CU is on build path also it is located in a excluded folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31303">31303</a>
+copy of read-only package doesn't preserve read-only flag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24045">24045</a>
+Error deleting parent folder of source folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31653">31653</a>
+typos in javadoc of NamingConventions 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30623">30623</a>
+Strange java delta when creating a new class 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31446">31446</a>
+Cannot cancel 'Cleaning of output foder'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30757">30757</a>
+Out of memory exception during hierarchy scoped search 
+   
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30485">30485</a>
+ArrayOutOfBoundsException during shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30609">30609</a>
+Output folder scrubbing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31591">31591</a>
+abstract method in base class, defined in a subclass results in compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31605">31605</a>
+Single line comment on the last line of a file produces a syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31626">31626</a>
+getJavadoc() on TypeDeclaration returning incorrect comment
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 11th February 2003
+<br>Project org.eclipse.jdt.core v_296
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31377">31377</a>
+NullPointerException on binary import 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31441">31441</a>
+Match in jar missing searching for references 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31398">31398</a>
+M5 compilation problems with package abstract methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31230">31230</a>
+Code assist on variable names: uses prefix and suffix together
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31440">31440</a>
+Classpath container initializer getDescription should also take a project in argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31242">31242</a>
+exception names should use Local Var suffix/prefix, not Method Param
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31168">31168</a>
+Trying to open Java-source file with Java editor fails with I/O Exception.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31261">31261</a>
+Strange behavior when there is more errors than max errors per compilation unit
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31450">31450</a>
+Compiler bug with overriding protected abstract methods, where a parent class has package-private abstract method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31475">31475</a>
+class must implement the inherited abstract method, but cannot override it
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30720">30720</a>
+linked resources and exclusion filters: compiler markers not flushed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31467">31467</a>
+spurious "Incompatible conditional operand types" on ?: when assigning to abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30800">30800</a>
+Search - doesn't find declaration of field with unicode name 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31225">31225</a>
+Source attachment not found
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31148">31148</a>
+freezes when editing a java file and adding while(st.hasMoreTokes())
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30731">30731</a>
+Class move refactoring changes the unlinked projects in the same workplace
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 6th February 2003
+<br>Project org.eclipse.jdt.core v_295 - 2.1 MILESTONE-5 (aka 2.1 RELEASE CANDIDATE 0)
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>ClasspathContainerInitializer.getDescription(IPath containerPath)</code> so as to improve readability
+of our messages involving classpath containers (e.g. unbound container classpath problems). Default implementation answers
+the original container path.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30946">30946</a>
+Deadlock in code parser
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30999">30999</a>
+Hang/Deadlock while inserting brace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30949">30949</a>
+When compiled from eclipse, unhandled exceptions in try - finally block are not detected.
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 5th February 2003
+<br>Project org.eclipse.jdt.core v_294
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Classpath problem markers generated for unbound variable or container will have an extra attribute
+(respectively IJavaModelMarker.UNBOUND_VARIABLE or IJavaModelMarker.UNBOUND_CONTAINER) which value is
+the unbound variable or container names. This allows clients to recognize these problems, and contribute 
+suitable recovery actions for these.
+</li>
+<li> Project cycles can now be built as soon as the compiler severity for circular
+dependencies is lowered to a warning (see Preferences&gt;Java&gt;Compiler&gt;Other&gt;Circular dependencies&gt;Warning).
+</li>
+<li> Surfaced compiler options for reporting usage of char[] in String concatenations (default is still warning).
+<pre>
+* COMPILER / Reporting Usage of char[] Expressions in String Concatenations
+*    When enabled, the compiler will issue an error or a warning whenever a char[] expression
+*    is used in String concatenations (e.g. "hello" + new char[]{'w','o','r','l','d'}).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Added API <code>IJavaModel.contains()</code> to find out if an <code>IResource</code> is visible in
+     the Java model.
+</li>
+<li> 2.1 API Change in org.eclipse.jdt.core.NamingConventions: deprecated 'suggestSetterName' methods removed.
+	<ul>
+	<li><code>suggestSetterName(IJavaProject,char[],int,char[][])</code>
+	</li>
+	<li><code>suggestSetterName(IJavaProject,String,int,String[])</code>
+	</li>
+	</ul>
+</li>
+<li>Added API for sorting the members of types in a compilation.
+  <ul>
+    <li><code>org.eclipse.jdt.core.util.CompilationUnitSorter</code>
+    <pre>
+public static final String RELATIVE_ORDER = "relativeOrder";
+public static void sort(ICompilationUnit compilationUnit,
+	int[] positions,
+	Comparator comparator,
+	int options,
+	IProgressMonitor monitor) throws JavaModelException;
+    </pre>
+    </li>
+  </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30947">30947</a>
+CodeAssist - top level types are not proposed if type is qualified with package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30907">30907</a>
+Code assist doesn't work in first case statement of a switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30920">30920</a>
+Stack overflow when container resolved to null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30855">30855</a>
+Wron error message when nesting source folder in class folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30857">30857</a>
+IPackageFragmentRoot: copy removes source folders from classpath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22756">22756</a>
+Reference search does not respect package fragments scope 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30860">30860</a>
+CodeAssist - Relevance is not correct for member exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30856">30856</a>
+1.4 compliant mode should consider abstract method matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30825">30825</a>
+Missing REORDERED_IN_CLASSPATH notifications 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26909">26909</a>
+NPE opening type hierarchy for binary type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29832">29832</a>
+Bogus quickfixes after removing/adding core plugins 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30699">30699</a>
+External JAR: no refresh in JavaModel if full build occurred before 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30697">30697</a>
+Classpath marker update could trigger automatic refresh for external JARs 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30805">30805</a>
+Abstract non-visible method diagnosis fooled by intermediate declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14597">14597</a>
+rearrange source code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30417">30417</a>
+ICodeFormatter format method should specify that the positions are sorted from the lowest to the biggest
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30709">30709</a>
+Return value of IPackageFragementRoot.getElementName() has changed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30705">30705</a>
+Simple name should consider member types before toplevel types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30704">30704</a>
+01e0f should be accepted as valid floating point literal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30511">30511</a>
+IPackageFragmentRoot:move ignores FORCE flag 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30516">30516</a>
+typo in javadoc of IPackageFragmentRoot:isArchive 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30506">30506</a>
+IPackageFragmentRoot:delete does not handle external jars 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20614">20614</a>
+Failure compiling a project with cyclic dependencies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30227">30227</a>
+compilerAdapter jar should not be include in the repo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30274">30274</a>
+Need method to figure out if an IResource is visible through the Java Model 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27027">27027</a>
+ClassCastException from codeassist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30503">30503</a>
+IPackageFragmentRoot:move, copy should accept null as sibling 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30496">30496</a>
+CU/classfile name validation shouldn't scan if suffix isn't the proper one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30471">30471</a>
+AST.parseCompilationUnit(IClassFile, boolean) throws IAE even if class file has source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30487">30487</a>
+NPE during shutdown in path canonicalization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26912">26912</a>
+'null == null' fooling blank final analysis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30280">30280</a>
+NullPointerException at org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression.resolveType(QualifiedAllocationExpression.java:225)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30393">30393</a>
+Its back: Core Exception [code 380] The resource tree is locked for modifications 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5347">5347</a>
+class files not updated 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9838">9838</a>
+Wrong diagnosis compiling inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30600">30600</a>
+incorrect code assist after 'throw new'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30799">30799</a>
+Core dump with J2SDK 1.4.1_01 in java.util.zip.ZipFile.getNextEntry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30739">30739</a>
+\u4100 is rejected as an identifier character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30782">30782</a>
+Can't rename a package to the same name with different case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30522">30522</a>
+IPackageFragmentRoot: move, copy updateClasspath semantics 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30567">30567</a>
+GB18030: Class name, method name, variable name can not contain GB18030 character in some version of Eclipse for Linux.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30629">30629</a>
+search: no occurrences to type found if type in default package in nested source folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27770">27770</a>
+Rebuild all doesn't follow project dependencies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24832">24832</a>
+Recurency between projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27750">27750</a>
+[startup] starting javacore takes 13% of empty worspace startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22710">22710</a>
+simple save takes 40 seconds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30470">30470</a>
+IJavaModelStatus.getMessage not the same as getString 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30465">30465</a>
+PDE binary project import fills log with core exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28224">28224</a>
+Invalid "Unused Imports" warning when importing inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27583">27583</a>
+reconciling allocates megabytes of memory in seconds of typing
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 28th January 2003
+<br>Project org.eclipse.jdt.core v_293
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> By default, JDT/Core will consider a default task tag "TODO" (with normal priority). In the past, default was no task reported. 
+<li> Added APIs to save/restore type hierarchies. Note that the client still has to register as a <code>ITypeHierarchyChangedListener</code> once
+restoration has occurred.
+  <ul>
+     <li> <code>ITypeHierarchy.store(OutputStream, IProgressMonitor)</code> for saving a type hierarchy.
+	 </li>
+     <li> <code>IType.load(InputStream, IProgressMonitor)</code> for restoring a previously saved hierarchy.
+	 </li>
+  </ul>
+</li> 
+<li> Added APIs to manipulate package fragment roots:
+	<ul>
+	<li><code>IPackageFragmentRoot.copy(IPath, int, boolean, IClasspathEntry, IProgressMonitor)</code>
+	</li>
+	<li><code>IPackageFragmentRoot.delete(int, boolean, IProgressMonitor)</code>
+	</li>
+	<li><code>IPackageFragmentRoot.move(IPath, int, boolean, IClasspathEntry, IProgressMonitor)</code>
+	</li>
+	</ul>
+	Note that these APIs are very close to the corresponding <code>IResource</code> APIs except that
+	they filter out nested source folders, and that they update the project's classpaths if specified.
+</li>
+<li> Extended compiler optional warning for interface methods incompatible with Object
+non public methods to scenario where thrown exceptions are not compatible (problem ID:
+<code>IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod</code>).
+This problem is optional, and its severity is also controlled by the <code>JavaCore</code>
+preference <code>"org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"</code>.
+</li>
+<li> 2.1 API Change in org.eclipse.jdt.core.NamingConventions: a new boolean parameter 'isBoolean' added. The value of this parameter is <code>true</code> if the field's type is boolean.
+	<ul>
+	<li><code>suggestSetterName(IJavaProject,char[],int,char[][])</code> become <code>suggestSetterName(IJavaProject,char[],int,boolean,char[][])</code>
+	</li>
+	<li><code>suggestSetterName(IJavaProject,String,int,String[])</code> become <code>suggestSetterName(IJavaProject,String,int,boolean,String[])</code>
+	</li>
+	</ul>
+	Previous APIs got deprecated, and will be removed before 2.1.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22049">22049</a>
+Hierarchy View slow to calculate hierarchy [type hierarchy]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29411">29411</a>
+Projects rebuilt after restart of Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30282">30282</a>
+TODO task message shouldn't be multiline
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30102">30102</a>
+NamingConvention: Tests fail 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30113">30113</a>
+Wrong positions in the outliner for a field that follows an initializer 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30224">30224</a>
+No JavaElement delta when renaming non-Java project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30108">30108</a>
+not clear what 'modifiers' in NamingConventions means 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30099">30099</a>
+NamingConvention.suggestArgumentNames: No guess returned 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27291">27291</a>
+[Dialogs] Error dialog looks bad if status message is null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28666">28666</a>
+Unclear error message for invalid output folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366">29366</a>
+Search reporting invalid inaccurate match 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29864">29864</a>
+Unable to restore working set item - cannot instantiate item: org.eclipse.jdt.ui.PersistableJavaElementFactory 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28044">28044</a>
+weird errors not reported anywhere but in text and overview ruler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30013">30013</a>
+Project compiler setting workspace | project do not persist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29151">29151</a>
+NPE in Surround with try/catch block [refactoring]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29969">29969</a>
+CodeAssist: too much proposals just after 'switch'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29955">29955</a>
+Should not report incompatible throws clause for interface if Object non public ref method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29894">29894</a>
+Path matching failure (CharOperation)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29761">29761</a>
+Regular expression pattern in exclusion filter is too greedy in M4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29761">29803</a>
+Source path exclusion filter not relative source folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23134">23134</a>
+Odd behavior from code formatter
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30357">30357</a>
+Incompatibility of serialization with sun jdk
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30370">30370</a>
+Warning "import never used" in spite of use by a javadoc @link
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30209">30209</a>
+JDT compiler bytecode incompatibility with JDK bytecode  results in serialization error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27497">27497</a>
+Compile only on class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28263">28263</a>
+Better specification of source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30232">30232</a>
+NullPointerException in compilation unit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=30160">30160</a>
+CodeAssist - no completion behind jProject
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29862">29862</a>
+GB18030:Could not set a GB18030 character as workbench classpath variable.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29863">29863</a>
+GB18030: Could not create a class variable whose name contains a GB18030 character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27616">27616</a>
+[Compiler] stack overflow while editing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23299">23299</a>
+Enhance Code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29239">29239</a>  
+Refactoring throws exception if .project or .classpath read-only in 2.1 M4 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 21st January 2003
+<br>Project org.eclipse.jdt.core v_292a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29872">29872</a>
+ImportOrganizeTest failing due to file missing from index 
+      
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 21st January 2003
+<br>Project org.eclipse.jdt.core v_292
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> New compiler setting got added to control severity of incompatible interface method with Object non public method.
+This used to be reported incorrectly as an error by our compiler (e.g. <code>interface I { int clone(); }</code>), and
+is now an optional problem (default severity is WARNING). Corresponding problem ID is: <code>IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod</code>.
+<pre>
+* COMPILER / Reporting Interface Method not Compatible with non-Inherited Methods
+*    When enabled, the compiler will issue an error or a warning whenever an interface
+*    defines a method incompatible with a non-inherited Object one.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li> New compiler problems got added to report declarations of unused private members (field/method/type). A JavaCore setting
+got added to control the severity of these new problems (default severity is IGNORE). Note that currently only a valid local usage 
+is considered as a true usage (e.g. if a message send targets this method, but cannot see it, then the target method will still be 
+reported as unused). Corresponding problem IDs are: <code>IProblem.UnusedPrivateMethod</code>, <code>IProblem.UnusedPrivateField</code>, 
+<code>IProblem.UnusedPrivateType</code> and <code>IProblem.UnusedPrivateConstructor</code>.
+<pre>
+* COMPILER / Reporting Unused Private Members
+*    When enabled, the compiler will issue an error or a warning whenever a private 
+*    method or field is declared but never used within the same unit.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedPrivateMember"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li>CodeAssist now answers keyword completions. Note that there was already an API for these: <code>ICompletionRequestor#acceptKeyword(char[] keywordName, int completionStart, int completionEnd, int relevance)</code>
+which wasn't invoked until now. There is currently no way to distinguish in between a 'synchronized' keyword used as a modifier or as a statement.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26363">26363</a>
+[ast/dom] type bindings that return null for superclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22381">22381</a>
+Show unused fields and variables [refactoring] [search]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19063">19063</a>
+code assist proposals for keywords
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29771">29771</a>
+No reference found to IResource.getLocation when no case sensitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28236">28236</a>
+Search for refs to class in hierarchy matches class outside hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28951">28951</a>
+Source attachment rootpath field missing in UI 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29536">29536</a>
+Check use of IResource.getLocation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29337">29337</a>
+Poor wording in task message "This method overrides deprecated..."
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29601">29601</a>
+TypeHierarchy: Avoid to use 'isInterface' / 'isClass' 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29540">29540</a>
+Search Engine return extra results 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29524">29524</a>
+Search for declaration via patterns adds '"*" 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26260">26260</a>
+task markers: limitting the number of problems per CU limits the number of tasks/markers (in general) per CU
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29306">29306</a>
+Can't get content of CU not on classpath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3331">3331</a>
+DCR: Code Formatter should offer cast without space (1GI74GZ)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29690">29690</a>
+Locked Resource Tree (JavaModelException) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29585">29585</a>
+Core Exception as resource tree is locked initializing classpath container 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29487">29487</a>
+Internal compiler error: final field set in loop (in constructor)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29546">29546</a>
+Project rebuild cannot write over .class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29636">29636</a>
+First anonymous type should be named X$1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29638">29638</a>
+No field initializations on Object
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27413">27413</a>
+Should we reject that code?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29211">29211</a>
+Should check the visibility of the array type before accessing its length field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29213">29213</a>
+Should check the visibility of the array type before calling a method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29621">29621</a>
+Wrong Delta When Adding to Filtered Folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29637">29637</a>
+Default debug attributes don't match with javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29538">29538</a>
+External jar not indexed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28489">28489</a>
+PackageFragmentRoot.fullExclusionPatternChars() could be optimized for non-source roots 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29298">29298</a>
+Simplify AST creation for an IClassFile (minor)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29374">29374</a>
+Excluded folder on project not returned by Java Model 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27485">27485</a>
+SearchEngine returns wrong java element when searching in an archive that is included by two distinct java projects. 
+ 
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5997">5997</a>
+Code assist does not know about synchronized keyword
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3196">3196</a>
+DCR - CodeAssist - code assist doesn't assist for keywords (1G0FUQF)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23300">23300</a>
+Context sensitive Code Completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29541">29541</a>
+Scrubbing wipes out entire build directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28393">28393</a>
+Duplicate 'missing require project' marker
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25976">25976</a>
+Bug in code formatter: can't be called twice in a row...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25896">25896</a>
+weird formatting of import declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26426">26426</a>
+Add preference to sort method in the source file.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25875">25875</a>
+import splitting behavior
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23992">23992</a>
+Adding partial compilation for JAVA
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19501">19501</a>
+Found NPE in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13029">13029</a>
+"Build" sometimes builds files that have not changed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13008">13008</a>
+Move a Java file, errors remain
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11572">11572</a>
+Cannot refresh a jar file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8720">8720</a>
+include an external directory of classes in Java build path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3359">3359</a>
+Get rid of source attachment root (1GJON3Q)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28073">28073</a>
+[startup] on startup, jCore loads launching plugins which loads debug plugins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29652">29652</a>
+Can't attach source to some ZIP files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29229">29229</a>
+Internal compiler error 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28801">28801</a>
+Internal compiler error 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18239">18239</a>
+Startup takes too long with java editor open
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28819">28819</a>
+Nullpointer exception when building
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28820">28820</a>
+NullPointerException in compiler in M4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28953">28953</a>
+internal compiler error: NullPointerException in file with inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28954">28954</a>
+Internal compiler error -- assert statements in inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28980">28980</a>
+Null-pointer exception on nested class assert 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29267">29267</a>
+NullPointerExc. occured when building project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29088">29088</a>
+Internal compiler error compiling code in M4 edition of eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29031">29031</a>
+Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5520">5520</a>
+Class files which are source not shown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3531">3531</a>
+NewClass(Interface)Wizard - shows not-visible types (1G4GNH3)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23033">23033</a>
+[Tasks] Create seperate setting for stopping build on a circular dependency error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28076">28076</a>
+NPE during quick shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29144">29144</a>
+Missing code implementation in the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29527">29527</a>
+Organize imports fails on included code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29501">29501</a>
+Uninitialized variable warning does not analyze the program thoroughly enough
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29394">29394</a>
+suboptimal handling closing/opening projects in autobuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29009">29009</a>
+ClassCircularityError in RequiredPluginsInitializer
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 15th January 2003
+<br>Project org.eclipse.jdt.core v_291a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29516">29516</a>
+SearchEngine regressions in 20030114 
+      
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 14th January 2003
+<br>Project org.eclipse.jdt.core v_291
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28545">28545</a>
+JavaProject.exists() returns true if project doesn't have Java nature 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29404">29404</a>
+JavaCore.create(IProject) returns != null for non Java Projects. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28752">28752</a>
+J Search resports non-existent Java element 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22783">22783</a>
+Unexpected null in compiler error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29365">29365</a>
+Syntax error inside method body is fooling NLS string detection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29277">29277</a>
+ToolFactory.createDefaultClassFileReader: Retrieving of classfile location
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29376">29376</a>
+Remove 65k limit on static data
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29176">29176</a>  
+[DOM/AST] Statement.get/setLeadingComment should be deleted 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29274">29274</a>
+Surface non-java projects as model non-java resources 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28531">28531</a>
+Classpath Entry: Output folder can not be set to project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28824">28824</a>
+Quick Fix: Type Mismatch -&gt; Cast bug [quick fix]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28599">28599</a>
+validateClasspath rendering of paths 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29079">29079</a>
+Buildpath validation: No check that output folder is inside project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29159">29159</a>
+DeltaProcessor walks removed project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28822">28822</a>
+ClassCastException in ProblemBinding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28596">28596</a>
+Default output folder cause of validation error even if not used 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28672">28672</a>
+Batch compiler should support argument expansion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28617">28617</a>
+Qualified super reference cannot be surrounded with parentheses.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27298">27298</a>
+Must return result error could be more accurate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28869">28869</a>
+Parse error with final local vars without immediate assignment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28682">28682</a>
+org.eclipse.jdt.core.dom.ForStatement's body position is incorrect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28622">28622</a>
+Check deprecation should handle unicodes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28559">28559</a>
+@deprecated has to be at the beginning of the comment line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20844">20844</a>
+Indexing space usage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26820">26820</a>
+Out of Memory indexing new plugins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27289">27289</a>
+ClassCircularityError forces ClassNotFoundException's
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27401">27401</a>
+[startup] Review JavaCore.startup()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28557">28557</a>
+Deprecation is not checked when subclassing a deprecated member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28615">28615</a>
+Cannot optimize out -0.0 in array initializers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28750">28750</a>
+Compiler crashes with M4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27241">27241</a>
+Missing code generation for the qualifier of a static method invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3173">3173</a>
+Constant field code generation (1FEWXZW)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28583">28583</a>
+Missing one unit in package view 
+   
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3297">3297</a>
+DCR - JM - Packages view empty (1GEWRYI)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28934">28934</a>
+Using assert keyword in methods of nested classes causes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25980">25980</a>
+NullPointerException during Refactor/Move operation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29343">29343</a>
+[M4] Scribbling on missing return statement needs to go on a diet
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29197">29197</a>
+NullPointerException when compiling Class with an assert in a method of an inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29082">29082</a>
+Can't access Inner class static field through an instance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28675">28675</a>
+NPE in indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28908">28908</a>
+ClassCastException in JavaProject.computePackageFragmentRoots
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27430">27430</a>
+Java model hangs onto many ClassFile objects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29030">29030</a>
+Compiler Bug -- incorrect visibility of protected constructors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28830">28830</a>
+Flexible projects cannot share output directory
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 17th December 2002 - 2.1 MILESTONE-4
+<br>Project org.eclipse.jdt.core v_290
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new JavaCore options
+	<ul>
+	<li>CODEASSIST / Define the Prefixes for Field Name<br>
+		When the prefixes is non empty, completion for field name will begin with
+		one of the proposed prefixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.fieldPrefixes"</li>
+		<li>possible values: { "&lt;prefix&gt;[,&lt;prefix&gt;]*" } where &lt;prefix&gt; is a String without any wild-card</li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Prefixes for Static Field Name<br>
+		When the prefixes is non empty, completion for static field name will begin with
+		one of the proposed prefixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.staticFieldPrefixes"</li>
+		<li>possible values: { "&lt;prefix&gt;[,&lt;prefix&gt;]*" } where &lt;prefix&gt; is a String without any wild-card</li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Prefixes for Local Variable Name<br>
+		When the prefixes is non empty, completion for local variable name will begin with
+		one of the proposed prefixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.localPrefixes"</li>
+		<li>possible values: { "&lt;prefix&gt;[,&lt;prefix&gt;]*" } where &lt;prefix&gt; is a String without any wild-card</li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Prefixes for Argument Name<br>
+		When the prefixes is non empty, completion for argument name will begin with
+		one of the proposed prefixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.argumentPrefixes"</li>
+		<li>possible values: { "&lt;prefix&gt;[,&lt;prefix&gt;]*" } where &lt;prefix&gt; is a String without any wild-card</li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Suffixes for Field Name<br>
+		When the suffixes is non empty, completion for field name will end with
+		one of the proposed suffixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.fieldSuffixes"</li>
+		<li>possible values: { "&lt;suffix&gt;[,&lt;suffix&gt;]*" } where &lt;suffix&gt; is a String without any wild-card </li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>ODEASSIST / Define the Suffixes for Static Field Name<br>
+		When the suffixes is non empty, completion for static field name will end with
+		one of the proposed suffixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.staticFieldSuffixes"</li>
+		<li>possible values: { "&lt;suffix&gt;[,&lt;suffix&gt;]*" } where &lt;suffix&gt; is a String without any wild-card </li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Suffixes for Local Variable Name<br>
+		When the suffixes is non empty, completion for local variable name will end with
+		one of the proposed suffixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.localSuffixes"</li>
+		<li>possible values: { "&lt;suffix&gt;[,&lt;suffix&gt;]*" } where &lt;suffix&gt; is a String without any wild-card </li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	<li>CODEASSIST / Define the Suffixes for Argument Name<br>
+		When the suffixes is non empty, completion for argument name will end with
+		one of the proposed suffixes.<br>
+		<ul>
+		<li>option id: "org.eclipse.jdt.core.codeComplete.argumentSuffixes"</li>
+		<li>possible values: { "&lt;suffix&gt;[,&lt;suffix&gt;]*" } where &lt;suffix&gt; is a String without any wild-card </li>
+		<li>default: ""</li>
+	 	</ul>
+	</li>
+	</ul>
+</li>
+<li>New API class : org.eclipse.jdt.core.NamingConventions<br>
+This class provides methods for computing Java-specific names.
+<pre>
+package org.eclipse.jdt.core;
+public final class NamingConventions {
+	public static char[] removePrefixAndSuffixForArgumentName(IJavaProject javaProject, char[] argumentName) {...}
+	public static String removePrefixAndSuffixForArgumentName(IJavaProject javaProject, String argumentName) {...}
+	public static char[] removePrefixAndSuffixForFieldName(IJavaProject javaProject, char[] fieldName, int modifiers) {...}
+	public static String removePrefixAndSuffixForFieldName(IJavaProject javaProject, String fieldName, int modifiers) {...}
+	public static char[] removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, char[] localName) {...}
+	public static String removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, String localName) {...}
+	public static char[][] suggestArgumentNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {...}
+	public static String[] suggestArgumentNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {...}
+	public static char[][] suggestFieldNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, int modifiers, char[][] excludedNames) {...}
+	public static String[] suggestFieldNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, int modifiers, String[] excludedNames) {...}
+	public static char[][] suggestLocalVariableNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {...}
+	public static String[] suggestLocalVariableNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {...}
+	public static char[] suggestGetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) {...}
+	public static String suggestGetterName(IJavaProject project, String fieldName, int modifiers, boolean isBoolean, String[] excludedNames) {...}
+	public static char[] suggestSetterName(IJavaProject project, char[] fieldName, int modifiers, char[][] excludedNames) {...}
+	public static String suggestSetterName(IJavaProject project, String fieldName, int modifiers, String[] excludedNames) {...}
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28434">28434</a>
+Open Type broken when workspace has build path problems 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28326">28326</a>
+"Open Type" dialog could not open selected type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28476">28476</a>
+JRE container description wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28447">28447</a>
+Unreadable error message from build class path validation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23210">23210</a>
+Member variable name proposal
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9511">9511</a>
+Exclude files and whole packages from build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27925">27925</a>
+Openable.hasChildren is slow 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28246">28246</a>
+Class files written to custom output and default output
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27275">27275</a>
+Random craches with corupt jar in library path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28357">28357</a>
+NPE on importing plugins
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 16th December 2002
+<br>Project org.eclipse.jdt.core v_289
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28316">28316</a>
+Missing references to constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28104">28104</a>
+33 Parsers and 35 Scanners created when opening a type hiearchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28298">28298</a>
+SANITY CHECK error when compiling a specific switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28296">28296</a>
+parser gives cast expression an incorrect length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28000">28000</a>
+Too many deltas on startup, when resolving cp variables/containers
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 13th December 2002
+<br>Project org.eclipse.jdt.core v_288
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28109">28109</a>
+Excluding a source file doesn't remove its Java problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28115">28115</a>
+Ubiquitous resource in the JavaModel 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28064">28064</a>
+Stack overflow in java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28150">28150</a>  
+ClassCastException in completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22139">22139</a>
+Array initializer used inline causes syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27941">27941</a>  
+ClassCastException in CompletionParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27284">27284</a>  
+misspelled variable name proposals for array with type name ending in 'y'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27852">27852</a>  
+We should not reject a class named java if it is in the unnamed package
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28208">28208</a>
+IClasspathEntry.getExclusionPattern: String[] would be better
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28114">28114</a>
+Missing type if defined in nested source folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27371">27371</a>
+code assist / auto inserting "()" broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28087">28087</a>
+on build, findMarkers called 3 times for each project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27992">27992</a>
+Incremental compile time = complete build time
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28095">28095</a>
+JDTCompilerAdapter references old Main constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23231">23231</a>  
+[resources] Ability to hide resources from the builders
+  
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 11th December 2002
+<br>Project org.eclipse.jdt.core v_287a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28069">28069</a>
+JDTCompilerAdapter and compiler.batch.Main out of sync in I20021210 build
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 10th December 2002 
+<br>Project org.eclipse.jdt.core v_287
+<h2>
+What's new in this drop</h2>
+<ul> 
+<li>Added API <code>IJavaProject.isOnClasspath(IResource)</code> that returns whether a given resource is on the 
+     classpath of the project and whether it is excluded.
+</li>
+<li>Added mechanism to allow generic container user to request updating definitions held by
+container initializers, onto <code>org.eclipse.jdt.core.ClasspathContainerInitializer</code>:
+
+<pre>
+/**
+ * Returns <code>true</code> if this container initializer can be requested to perform updates 
+ * on its own container values. If so, then an update request will be performed using
+ * <code>ClasspathContainerInitializer#requestClasspathContainerUpdate</code>/
+ * 
+ * @param containerPath - the path of the container which requires to be updated
+ * @param project - the project for which the container is to be updated
+ * @return boolean - returns <code>true</code> if the container can be updated
+ * @since 2.1
+ */
+public boolean canUpdateClasspathContainer(IPath containerPath, IJavaProject project) {
+	// By default, classpath container initializers do not accept updating containers
+   	return false; 
+}</pre>
+<pre>
+/**
+ * Request a registered container definition to be updated according to a container suggestion. The container suggestion 
+ * only acts as a place-holder to pass along the information to update the matching container definition(s) held by the 
+ * container initializer. In particular, it is not expected to store the container suggestion as is, but rather adjust 
+ * the actual container definition based on suggested changes.
+ * 
+ * IMPORTANT: In reaction to receiving an update request, a container initializer will update the corresponding
+ * container definition (after reconciling changes) at its earliest convenience, using 
+ * <code>JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)</code>. 
+ * Until it does so, the update will not be reflected in the Java Model.
+ * 
+ * In order to anticipate whether the container initializer allows to update its containers, the predicate
+ * <code>JavaCore#canUpdateClasspathContainer</code> should be used.
+ * 
+ * @param containerPath - the path of the container which requires to be updated
+ * @param project - the project for which the container is to be updated
+ * @param containerSuggestion - a suggestion to update the corresponding container definition
+ * @throws CoreException when <code>JavaCore#setClasspathContainer</code> would throw any.
+ * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
+ * @see ClasspathContainerInitializer#canUpdateClasspathContainer(IPath, IJavaProject)
+ * @since 2.1
+ */
+public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject project, IClasspathContainer containerSuggestion) throws CoreException {
+	// By default, classpath container initializers do not accept updating containers
+}</pre>
+</li>
+<li>Added helper method to <code>org.eclipse.jdt.core.JavaCore</code> so as to retrieve a registered 
+classpath container initializer:
+<pre>/**
+ * Helper method finding the classpath container initializer registered for a given classpath container ID 
+ * or <code>null</code> if none was found while iterating over the contributions to extension point to
+ * the extension point "org.eclipse.jdt.core.classpathContainerInitializer".
+ * 
+ * A containerID is the first segment of any container path, used to identify the registered container initializer.
+ * 
+ * @return ClasspathContainerInitializer - the registered classpath container initializer or <code>null</code> if 
+ * none was found.
+ * @since 2.1
+ */
+public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID)</pre>
+</li>
+</ul> 
+ 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27890">27890</a>
+Batch compiler option -nowarn or -warn:none doesn't remove the warning for conversion from char[] to String
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27670">27670</a>
+ClasspathEntry.rootID allocates a lot of throw-away objects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27595">27595</a>
+Add isOnClasspath(IResource) as API 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27652">27652</a>
+DCR - Need a way to request container initializers to update their container definitions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27555">27555</a>
+[startup] PackageFragmentRoot - source attached too early (?) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27861">27861</a>
+VerifyError not being caught in jdt core tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27914">27914</a>
+Infinite loop setting breakpoint
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27853">27853</a>
+Incorrect invalid unicode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27840">27840</a>
+Computing non-java resources on a project should not create a NameLookup 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27690">27690</a>
+SourceElementParser doesn't parse local declarations even if it is requested
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5295">5295</a>
+Segmented view misses field comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27714">27714</a>
+JavaElement.newNotPresentException 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27735">27735</a>
+CodeAssist - No completion for type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27370">27370</a>
+code assist not working with "new .."
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27658">27658</a>
+Infinite loop when checking cycle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27683">27683</a>
+Index should be saved right after a project was indexed 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27330">27330</a>
+Signeture should reuse Scanner object 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27294">27294</a>
+Performance - getTypeSignature should not rescan element names 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26604">26604</a>
+Forward references unilaterally dissallowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27532">27532</a>
+Rebuild sometimes introduces invalid errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27597">27597</a>
+Ant adapter on a 1.4 JVM sets the target to be 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27494">27494</a>
+Source folder output folder shown in Package explorer 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27783">27783</a>
+Build output folder should not always be in the project subdirectories
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27600">27600</a>
+NPE while searching
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26602">26602</a>
+Incremental compile/build produces invalid header classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25752">25752</a>
+References list displays nulls for package name parts 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26967">26967</a>
+Upon exit always receive "JVM Terminated message"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27748">27748</a>
+JUnit import fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27660">27660</a>
+Stack overflow causes startup crash 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27236">27236</a>
+search: references to constructors - a subclass constructor reported 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27603">27603</a>
+NPE in AbstractImageBuilder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27448">27448</a>
+using SearchEngine the constructors, inner classes or packages are not found 
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 3rd December 2002 
+<br>Project org.eclipse.jdt.core v_286
+<h2>
+What's new in this drop</h2>
+<ul> 
+<li><b>Code completion enhancement:</b>
+   <ul>
+   <li>Relevance of a proposal is higher if the proposal is after an operator and the type of
+   proposal is compatible with the operator.
+   <br>In the following example <code>var1</code> is more relevant than <code>var2</code>.<pre>
+   public class X {
+      int var1;
+      Object var2;
+      void foo() {
+         int i = 1 + var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   </ul>
+</li>
+</ul> 
+ 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27487">27487</a>
+Builder doesn't handle move to nested source folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27499">27499</a>
+Bogus ClasspathVariableInitializer is found in JavaModel 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22039">22039</a>
+Provide facility to exclude files from compilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26251">26251</a>
+project compiler settings : some are not set
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25538">25538</a>
+Conflict of classfolder and outputfolder not reported 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27310">27310</a>
+CompilationUnit#lineNumber(..) doc seems flawed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27235">27235</a>  
+Bug with assignement with no effect mask
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25928">25928</a>
+Cannot nest entries in Java Build Path - Request for Feature Removal 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26806">26806</a>
+Source build path should allow subdirectories of directories already on path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27322">27322</a>
+ClassCastException during code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27247">27247</a>  
+Missing generation for the qualifier in 1.4 mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22407">22407</a>  
+Can't set Java project build output folder to different project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27250">27250</a>  
+Walkback asking for a full rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27173">27173</a>  
+API: add methodInvocation.resolveMethodBinding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24123">24123</a>
+Support for multiple output dirs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27151">27151</a>
+NPE searching in hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24308">24308</a>
+Performance - Optimization of search in hierarchy 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27204">27204</a>
+AST.lineNumber(position) is not working, if the class didn't have a new line at the end of file.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27374">27374</a>
+project specific JRE settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27295">27295</a>
+Relevance of member type in type cast should be higher 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27254">27254</a>
+Inexact matches found when search references to UnconditionalFlowContext#maxFieldCount 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26938">26938</a>
+Build Project-command removes all from build-dir
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 26th November 2002 
+<br>Project org.eclipse.jdt.core v_285
+<h2>
+What's new in this drop</h2>
+<ul> 
+<li><b>Source attachment enhancements:</b> 
+	<ul>
+	<li><b>Source folder attachment:</b> The source attachment mechanism got generalized to all binary 
+		  package fragment root. In the past, only archives did support to carry a source attachment, in the 
+		  form of a source archive. Now, both binary folder or archive can be associated with sources, which 
+		  can be either a source archive or a source folder. In particular, mixed modes are supported (binary 
+		  archive associated to source folder and reciprocally). For more details, see 
+		  <code>IPackageFragmentRoot.attachSource(IPath, IPath, IProgressMonitor)</code> and 
+		  <code>JavaCore.newLibraryEntry(...)</code>.
+	</li>
+	<li><b>Automatic root path detection:</b> If null is specified as the root path (see 
+		  <code>JavaCore.newLibraryEntry(...)</code> and <code>IPackageFragmentRoot.attachSource(...)</code>), 
+		  then the Java Model will do its best to compute this root path automatically. The underlying algorithm 
+		  finds the first .java file, parses it, and extract the package declaration to compute the root path.
+	</li>
+	<li><b>Root path detection:</b> The new API 
+		  <code>IPackageFragmentRoot.computeSourceAttachmentRootPath(IPath sourceAttachmentPath)</code> 
+		  allows to detect the root path for a given source attachment and package fragment root.
+	</li>
+	</ul>
+</li>
+<li><b>Code completion enhancement:</b>
+   <ul>
+   <li>Relevance of a proposal is lesser if the proposal is in a variable initializer and the proposal is the variable.
+   <br>In the following example <code>var2</code> is less relevant than <code>var1</code>.<pre>
+   public class X {
+      int var1;
+      int var2 = var&lt;cursor&gt;
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is lesser if the proposal is static and the qualified expression is non-static.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      static int var1;
+      int var2;
+      void foo() {
+         this.var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is higher if the completion is not qualified or is a local variable.
+   <br>In the following example the field <code>var2</code> and the parameter <code>var1</code> are more relevant
+   than field <code>var1</code>.<pre>
+   public class X {
+      int var1;
+      int var2;
+      void foo(int var1) {
+         var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is higher if the proposal is equals to the current token.
+   <br>In the following example the field <code>var</code> is more relevant than field <code>varPlus</code>.<pre>
+   public class X {
+      int var;
+      int varPlus;
+      void foo() {
+         var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   </ul>
+</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24916">24916</a>
+quick fix: does not handle additional dimentions sometimes [quick fix]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26903">26903</a>
+VerifyError when casting null to an array type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27002">27002</a>
+Scanner  allocates new ArrayList(10) everytime it's created
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26912">26912</a>
+'null == null' fooling blank final analysis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26817">26817</a>
+Class File Editor shows words translated which shouldn't be 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26452">26452</a>
+Wrong automatically generated import statements 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26881">26881</a>
+Yoyo in the debugger again
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26753">26753</a>
+Suspicious yoyo behavior when stepping through if condition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25148">25148</a>
+Can't have different case package names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26883">26883</a>
+Should report unitialized blank final field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20932">20932</a>
+Cannot add a source directory as the source of a JAR file. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8719">8719</a>
+DCR - Attac h Java Source: allow un-jarred source tree? 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6912">6912</a>
+Attach Source Requires JAR/ZIP 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26255">26255</a>
+project compiler settings : cannot go back to worspace settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26841">26841</a>
+Compiler - Does not detect non-visible member type in import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26784">26784</a>
+problem M3 sourcebuild, linux/gtk - build error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26706">26706</a>
+Cannot create project with comma characters in project path 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26195">26195</a>
+JDT compiler doesn't report recursive constructor invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26747">26747</a>
+IllegalArgumentException reading build state
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3243">3243</a>
+SourceAttachment - automatic computation of the package root does not work (1GCMTLP) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26785">26785</a>
+Unreachable empty blocks should be reported in 1.4 compliant mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26664">26664</a>
+deprecated interfaces are not allways recognized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26759">26759</a>
+Cast Compiler Error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26134">26134</a>
+JACKS - VerifyError running invalid code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26253">26253</a>
+task tags: two tags on one line creates one task for first tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26677">26677</a>
+Code Assist - expected type must be qualified.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23542">23542</a>
+CodeAssist proposal should offer non-qualified ones first
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25890">25890</a>
+code assist displays static members on non-static expressions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26025">26025</a>
+Search should not use a file based name environment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26138">26138</a>
+JACKS - The null literal should not be considered as a constant expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26585">26585</a>
+Wrong code generation in conditional expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26588">26588</a>
+Code Assist - variable must be less relevant in initialization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26142">26142</a>
+JACKS: Must reject invalid character after class definition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26141">26141</a>
+JACKS: Should report unterminated comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26129">26129</a>
+JACKS: VerifyError, because opcode jsr_w not used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25888">25888</a>
+Open on selection fails on private binary inner class contructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23126">23126</a>
+allow selecting directories when attaching source to jar's 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22145">22145</a>
+Attach source directory in addition to archive file [build path] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26459">26459</a>  
+Unused NonVoidMethodRequestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26122">26122</a>  
+JACKS: VerifyError when affecting final local in anonymous class header
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26124">26124</a>  
+JACKS - Compile error not reported when break; used in a labeled statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24934">24934</a>
+Move top level doesn't optimize the imports[refactoring] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25250">25250</a>
+Scrapbook shows wrong error message
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26580">26580</a>
+java element deltas not sent out? 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21837">21837</a>
+Eclipse hangs trying to set a breakpoint 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25406">25406</a>
+Package name change disallowed  because of case insensitivity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26885">26885</a>
+binary representation wrongly flagged as error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26526">26526</a>
+Inner class imports flagged as errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26652">26652</a>
+Encountered  "case statement must be constant" error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23076">23076</a>
+compilation does not create class files!!!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24015">24015</a>
+CVS synchronize with outgoing changes only causes Java rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25478">25478</a>
+Unresolvable import statements Problem Marker malfunctioning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26658">26658</a>
+No deprecation warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26132">26132</a>
+JACKS - Blank final instance must be assigned before the end of constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26340">26340</a>
+Using javadoc comments to generate and manage bookmarks.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=9020">9020</a>
+More intelligent code assist.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25962">25962</a>
+Output classes is scrubbed due to error in compiling a source.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26166">26166</a>
+compile single file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25684">25684</a>
+SelectionEngine to be made API?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26454">26454</a>  
+DCR: IScanner.setSourceReader
+  
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 14th November 2002 - 2.1 MILESTONE-3
+<br>Project org.eclipse.jdt.core v_284
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26259">26259</a>  
+Errors reported on save which go aways on rebuild
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 13th November 2002
+<br>Project org.eclipse.jdt.core v_283
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26128">26128</a>  
+packages don't appear in package explorer view 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26044">26044</a>
+Unexpected full builds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26098">26098</a>
+Wrong line number attribute.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24517">24517</a>
+type view does not notice when jar disappears 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26063">26063</a>  
+MacOS X: Error saving files
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 12th November 2002
+<br>Project org.eclipse.jdt.core v_282b
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In case someone deletes the .classpath and no corresponding classpath exists in memory,
+      a default .classpath is not automatically created any longer but a marker is created on the
+      project preventing this project from being built.
+      This covers the following scenarii:
+      <ul>
+      <li>Someone checks in a .project file with the Java nature but doesn't check in the .classpath file.
+            When the project is checked out, a marker is created indicating the .classpath file could not 
+            be read.</li>
+      <li>Someone shuts down the workbench, deletes the .classpath and restart the workspace.
+            When attempting to built the project,  a marker is created indicating the .classpath file could 
+            not be read and the project is not built.</li>
+       <li>The Java nature is added to a project without a .classpath file. A marker is created indicating 
+       		the .classpath file could not be read.
+      </ul>
+</li>
+<li><b>Selectivity API</b> - Source folders can be associated with filters allowing to exclude
+specified portions of the resource tree rooted at this source entry's path. Exclusion patterns 
+are expressed using the Ant file pattern syntax (i.e. **, *, ? wild-cards; where ** can stand for
+one or many folder names).
+   <ul>
+   <li>Added <code>JavaCore.newSourceEntry(IPath path, <b>IPath[] exclusionPatterns</b>)</code>
+   </li>
+   <li>Added <code>IClasspathEntry.getExclusionPatterns()</code>
+   </li>
+   </ul>
+   Full implementation will be available by 2.1 milestone-4.
+</li>
+<li><b>Multiple output folder API</b> - Source folders can be associated with a specific output
+location. The project output location is now corresponding to a default output location.
+   <ul>
+   <li>Added <code>JavaCore.newSourceEntry(IPath path, IPath[] exclusionPatterns, <b>IPath specificOutputLocation</b>)</code>
+   </li>
+   <li>Added <code>IClasspathEntry.getOutputLocation()</code>
+   </li>
+   </ul>
+   Full implementation will be available by 2.1 milestone-4.
+</li>
+<li>The Java builder now iterates over the resource tree, allowing to take advantage of forthcoming 
+workspace structure enhancements (in particular: linked folders). As a consequence, the Java builder
+will only consider the resources officially reflected in the resource tree (as opposed to existing 
+underlying files not yet reflected when the resource tree is out of sync).
+Note that the build state format has changed to reflect this evolution, as a consequence, if reusing an existing
+workspace, the first build action will have to be a rebuild-all projects, since incrementally it will
+not be able to re-read old build states associated with prerequisite projects (and an incremental build
+cannot tell the build manager a full rebuild is necessary). 
+</li>
+<li>An option allows to control whether the Java builder should clean the output folder(s). Since
+options can be specified on a per project basis, each individual project can be toggled for cleaning
+the output folder or not (default is to clean). Also, "scrubbing" output folder got renamed into 
+"cleaning" output folder. 
+<pre>
+* BUILDER / Cleaning Output Folder(s)
+*    Indicate whether the JavaBuilder is allowed to clean the output folders
+*    when performing full build operations.
+*     - option id:       "org.eclipse.jdt.core.builder.cleanOutputFolder"
+*     - possible values: { "clean", "ignore" }
+*     - default:         "clean"
+</pre>
+</li>
+<li>Integrated patch from Genady Beriozkin for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25092">25092</a>.
+The compiler will now optionally diagnose assignments having no effect (e.g. x = x).
+Added the following option to control this behavior.
+<pre>
+* COMPILER / Reporting Assignment with no effect
+*    When enabled, the compiler will issue an error or a warning whenever an assignment
+*    has no effect (e.g 'x = x').
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.noEffectAssignment"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26053">26053</a>
+builder out of order in I-20021112
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25859">25859</a>
+Error doing Java Search 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25092">25092</a>  
+Detect/Warn on possible user typos
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25894">25894</a>  
+Memory leak - Global ThisReference is leaking bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25885">25885</a>  
+Code Assist - exact expected type should be more relevant than subtype
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25184">25184</a>  
+Operations on cu outside classpath should fail 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25876">25876</a>  
+Code Assist - void method are proposed in assignment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23586">23586</a>  
+Creating a new project deletes files in the parent folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25815">25815</a>
+Code Assist does not propose member type.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25820">25820</a>
+NPE in Code Assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25811">25811</a>
+Code Assist for variable name suggestion is not perfect.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24010">24010</a>
+IType::resolveType returns null for inner types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25735">25735</a>
+Non-NLS strings are not reported properly when the ending tag is missing
+  
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22509">22509</a>  
+Unable to start some Java application
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21864">21864</a>  
+Associate package hierarchy with top-level source directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12957">12957</a>  
+Copied resources out of synch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24276">24276</a>  
+javadoc - Imports marked as unused when they are really necessary.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18320">18320</a>  
+Compiler Warning/Error/Ignore when Assigning to a Parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25994">25994</a>  
+Marker for "static method should be accessed in a static way"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25995">25995</a>  
+Marker for "static method should be accessed in a static way"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25582">25582</a>  
+Cannot specify java source path for resource !
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25665">25665</a>  
+AST adds implicit super call (PR 22306 needed on 2.0.2 stream)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25304">25304</a>  
+Code assist and parameter assistance.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24783">24783</a>  
+method parameter name code completion 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25872">25872</a>  
+Eclipse considers the Unicode char '\u000A' an invalid character constant.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25255">25255</a>  
+ICompilationUnit::getUnderlyingResource throws an exception 
+   
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 5th November 2002
+<br>Project org.eclipse.jdt.core v_281
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Code completion enhancement:
+   <ul>
+   <li>Relevance of a proposal is higher if the proposal is in a variable initializer and its type is compatible with the variable type.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      Object var1;
+      int var2;
+      void foo() {
+         int i = var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is higher if the proposal is on the right hand side of an assignment and its type is compatible with the left hand side type.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      Object var1;
+      int var2;
+      void foo() {
+         int i;
+         i = var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24626">24626</a>
+codeSelect - does not work in catch clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25688">25688</a>
+Non NLS strings improperly reported when the line separator is \r only
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25687">25687</a>
+codeSelect - fails with inner class as method parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25605">25605</a>
+[API] someJavaProject.getRequiredProjectNames(); API should specify that the array is returned in ClassPath order 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25358">25358</a>
+Creating a new Java class - Browse for parent 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25495">25495</a>
+Ant compiler adapter should treat bogus imports as errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21957">21957</a>  
+'refactor rename' allows subpackage name to start with a space 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25591">25591</a>  
+ClassCastException in CompletionEngine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25539">25539</a>  
+Unexpected inaccurate search results 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25578">25578</a>
+Abstract method declaration completion should be more relevant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25221">25221</a>
+Code assist after new keyword
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25347">25347</a>
+Deprecation-Flag in Ant doesn't work with Eclipse Compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25551">25551</a>
+Ant javac adapter always reports build successful even if there are compiler errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24939">24939</a>  
+Code Assist doesn't find protected constructor for anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3717">3717</a>  
+Smoke 114: Progress reporting when switching to different default VM (1GEHXMV) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24565">24565</a>
+CodeAssist proposing twice the same method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25520">25520</a>
+Possible problem in JavaProject#findPackageFragmentRoots(IClasspathEntry)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24518">24518</a>
+Public flag not set for interface method 
+     
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18212">18212</a>  
+Java Build Paths no updated correctly when checking out multiple projects 
+   
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 29th October 2002
+<br>Project org.eclipse.jdt.core v_280
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In 1.4 compliant mode, the compiler will report errors for unterminated line comments (i.e. not closed with a line break). For backward compatibility reason,
+the stricter check isn't performed in 1.3 compliant mode. See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23096">23096</a> for further details.
+Also note that from now on, the trailing line break is part of the line comment source range.
+</li>
+<li>The API setLeadingComment(String) on org.eclipse.jdt.core.dom.Statement class has been updated to reflect the changes made for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23096">23096</a>.
+This API strictly fits to the JLS. It doesn't use the compliance mode settings. So a line comment needs to be closed with a line break in
+order to be valid.
+See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25206">25206</a> for further details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22358">22358</a>
+[api] Would like CharOperation made API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23207">23207</a>  
+Flags.isDeprecated(IMethod.getFlags()) doesn't work 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23984">23984</a>
+validateEdit not called when changing .classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25439">25439</a>
+toString() on IBinding subclasses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25347">25347</a>
+Deprecation-Flag in Ant doesn't work with Eclipse Compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25396">25396</a>
+NPE importing external plug-ins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25433">25433</a>
+#findPackageFragmentRoots(IClasspathEntry)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25377">25377</a>
+Error location is not correct for empty array initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25174">25174</a>
+Wrong code generation of the eclipse java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25298">25298</a>
+One out of two non-externalized strings reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25188">25188</a>
+Debugger won't stop on method first statement breakpoint
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25233">25233</a>
+NPE in CompletionParser.buildMoreCompletionContext
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25206">25206</a>
+DOM/AST: Statement.setLeadingComment specification is inconsistent with the JLS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25229">25229</a>
+Compiler should not reject innerclass scenario
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25183">25183</a>
+AST: ITypeBinding of interface returns constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24833">24833</a>
+TODO: not detected if there is only a comment in .java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24744">24744</a>
+TODO: Task not found if comment after last closing brace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23096">23096</a>
+Compiler does not report end of line comment error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24559">24559</a>
+TODO: items disappear when there is a syntax error in a method body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13907">13907</a>
+Scanner does not report whitespace tokens at end of input
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25185">25185</a>
+ClassFormatError compiling a method with a compilation problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25124">25124</a>
+AST: IllegalArgumentException on creation
+  
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23208">23208</a>  
+The javadoc shown by Eclipse is different from what javadoc produces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25464">25464</a>  
+NPE during import plugins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25170">25170</a>  
+opening .java files from outside of classpath is much slower then other files 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23307">23307</a>
+Refactoring and Search are applied only on open files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20985">20985</a>
+[GM1] REGRESSION: eclipse wants to import class already imported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24906">24906</a>
+new non-nls strings not noticed on typing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25378">25378</a>
+Switching from jdk1.3.1 to jdk1.4.1 leaves me without CVS support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22304">22304</a>
+JavaModel: inner Node Constructor shows syntetic argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25373">25373</a>
+options now with 'Map'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25297">25297</a>
+AST: DCR: Allow subclasses of ASTNode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20751">20751</a>
+[F3] Discrepency between light bulbs and compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25163">25163</a>
+AST DCR: Parameter names in IMethodBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25103">25103</a>
+Formatter indentation
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 23rd October 2002
+<br>Project org.eclipse.jdt.core v_279a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25197">25197</a>  
+NPE importing external plugins  
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 22nd October 2002
+<br>Project org.eclipse.jdt.core v_279
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>By default, the compiler will produce warnings for unused imports and non-static references to static members.
+</li>
+<li>Code completion enhancement:
+   <ul>
+   <li>Relevance of a proposal is higher if the proposal is in a return statement and its type is compatible with the return type.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      Object var1;
+      int var2;
+      int foo() {
+         return var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is higher if the proposal is in a cast statement and its type is in the hierachy of the cast type.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      Object var1;
+      int var2;
+      long foo() {
+         return (int)var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   <li>Relevance of a proposal is higher if the proposal is an argument of a sent message and its type is compatible with the parameter type.
+   <br>In the following example <code>var2</code> is more relevant than <code>var1</code>.<pre>
+   public class X {
+      Object var1;
+      int var2;
+      void foo(int i) {
+         foo(var&lt;cursor&gt;
+      }
+   }</pre>
+   </li>
+   </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25040">25040</a>  
+getPackageFragmentRoots(CP entry) implementation doesn't match spec  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25041">25041</a>  
+IJavaElement#getUnderlyingResource - should fail if element doesn't exist  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24505">24505</a>  
+Refactoring an empty package makes it disappears  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24775">24775</a>  
+Wrong delta when replacing binary project with source project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25018">25018</a>
+parseCompilationUnit(..) does not report a compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24773">24773</a>
+CompilationUnit.getProblems: not all problems?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24747">24747</a>
+incorrect compile error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24974">24974</a>
+Broken link in JDT Plugin-in Developer's Guide
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24691">24691</a>  
+Missing interface makes hierarchy incomplete  
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24213">24213</a>  
+[M1] dependency checking too conservative
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24671">24671</a>  
+Attaching source to JAR triggers build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25039">25039</a>  
+Non-existing package fragment roots should not be openable  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23311">23311</a>  
+Need a way to include external JARs in the indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24956">24956</a>  
+Compiler misdiagnoses exception sequence
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24019">24019</a>  
+Jar Refresh Problem
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 15th October 2002 - 2.1 MILESTONE-2
+<br>Project org.eclipse.jdt.core v_278
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added soft dependency on plug-in "org.eclipse.team.core" to account for fileTypes contribution
+</li>
+ <li> JavaCore option added for specifying the task priorities (default is <code>""</code> meaning 
+ tasks have normal priority).
+<pre>
+ * COMPILER / Define the Automatic Task Priorities
+ *    In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
+ *    of the task markers issued by the compiler.
+ *    If the default is specified, the priority of each task marker is "NORMAL".
+ *     - option id:			"org.eclipse.jdt.core.compiler.taskPriorities"
+ *     - possible values:	{ "priority[,priority]*" } where priority is one of "HIGH", "NORMAL" or "LOW"
+ *     - default:			""
+</pre>	 
+ </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23272">23272</a>  
+Plugin dependence problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24741">24741</a>  
+Search does not find patterned type reference in binary project  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23812">23812</a>  
+Configurable (TODO) Markers priority in takslist  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22840">22840</a>  
+Refactor-&gt;Move doesn't update Local History  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24685">24685</a>  
+Inner package fragments gets deleted - model out of synch  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24498">24498</a>  
+Duplicate entries on classpath cause CP marker to no longer refresh  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24630">24630</a>
+NPE in MethodBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24622">24622</a>
+ast: problems with missing ParenthesizedExpression nodes #2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24529">24529</a>
+compiler must accept empty source files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24502">24502</a>
+AST: No binding for type accesses to a non-visible type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24511">24511</a>
+AST: Resolve on non-visible import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24501">24501</a>
+AST: No binding for fields accesses of non-visible fields
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24500">24500</a>
+AST: No binding for field instance access in constructor invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24499">24499</a>  
+AST: No binding for instance access in constructor invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17104">17104</a>  
+Compiler does not complain but "Quick Fix" ??? complains  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21893">21893</a>
+IType::isMember works the other way round
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22581">22581</a>
+Ignore unreachable code for unread variables
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21175">21175</a>  
+Incorrectly identified: Catch block is hidden by another one in the same try statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23523">23523</a>  
+Ouliner not updated after catch-up from repository  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24230">24230</a>  
+search: does not find a references to constructor in anonymous type creations nodes  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24522">24522</a>  
+New Class Dialog: No interface method stubs generated for nested class  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24567">24567</a>  
+problem with hierarchy in working copy  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21901">21901</a>
+JavaCore.setClasspathContainer is not generic enough
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24623">24623</a>
+AST: No method body when abstract modifier is existing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24558">24558</a>
+compiler error, method declaration in interface -&gt; NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24621">24621</a>
+Cannot specified JRE for each project separely ...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24600">24600</a>
+ECLIPSE_HOME not set
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14194">14194</a>
+Java source files shouldn't show errors when in src dir, but not java resource
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24514">24514</a>
+dependency analyzer is broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24400">24400</a>
+Compiler bug or java 'feature' ?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24243">24243</a>
+Heuristic to differ between internal JAR and external JAR.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23769">23769</a>
+java.lang.OutOfMemoryError
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 8th October 2002
+<br>Project org.eclipse.jdt.core v_277
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Search for constructor references now finds implicit constructor calls. Indexes in old workspaces are recomputed when restarted which may result in longer startup times. 
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24449">24449</a>
+AST: Resolve on field access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24453">24453</a>
+ast: problems with missing ParenthesizedExpression nodes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23112">23112</a>  
+search: need a way to search for references to the implicit non-arg constructor  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24440">24440</a>
+NPE when complete qualified allocation expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24406">24406</a>
+AST: Resolve on method invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24376">24376</a>  
+Attempt to change resource while tree locked during container initialization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24346">24346</a>  
+Method declaration not found in field initializer  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=13939">13939</a>
+DBCS: no error message to DBCS whitespace in java source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23829">23829</a>  
+IType::resolveType incorrectly returns null  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22541">22541</a>  
+JDT core test suites should be on dev.eclipse.org  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=2857">2857</a>  
+Renaming .java class with errors to .txt leaves errors in Task list (1GK06R3)  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24245">24245</a>  
+IJavaSearchScope.enclosingProjectsAndJars doc misleading, hard to use  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24140">24140</a>  
+Searching for references to a private field within heirarchy seems very slow  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24268">24268</a>
+DOM: NPE in NaiveASTFlattener#visit(SwitchCase node)
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23644">23644</a>  
+hierarchy: getAllSuperTypes does not include all superinterfaces?  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23593">23593</a>  
+search: strange method reference match found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8489">8489</a>
+space instead of tab
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24370">24370</a>  
+SerialUID
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24205">24205</a>  
+TypeHierarchy omits subtypes  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24375">24375</a>
+Casting of primitive final fields to its own type causes VerifyError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22548">22548</a>
+IndexOutOfBoundsException during jdt indexing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24347">24347</a>
+AST: Resolve on type name qualifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23211">23211</a>  
+Bug with search/reference !  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22894">22894</a>  
+Improperly formed ICompilationUnit?  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24324">24324</a>  
+AST: IVariableBinding.getModifiers not same as in source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23930">23930</a>
+Eclipse crash when a rebuild project !???
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21905">21905</a>
+Class file editor should indicate that .class file is missing debug attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21741">21741</a>
+Error while Build and doesn't allow to create ServerProject also
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22376">22376</a>
+Parent of JarEntryFile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24274">24274</a>
+ArrayIndexOutOfBoundsException from source mapper  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23677">23677</a>
+java.lang.OutOfMemoryError when setting class path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24233">24233</a>
+Impossible to compile projects - followinf of BUG 22509
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24233">24233</a>
+Installed JRE detection doesnt work correctly
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 1st October 2002
+<br>Project org.eclipse.jdt.core v_276
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Registered classpath variable initializers are now taking precedence on values persisted during previous session. This allows
+initializers to rebind their variables when restarting a workspace, and thus fix up their values. </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23594">23594</a>  
+code resolve: incorrectly resolving method invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21763">21763</a>  
+Problem in Java search [search]  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22846">22846</a>  
+Cannot add in a new classpath entry  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20197">20197</a>  
+Classpath Variables pref page does not refresh with latest variables [build path]  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24134">24134</a>
+JDTCompilertAdapter doesn't throw BuildException on compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24001">24001</a>
+Classpath variable/container initializer should activate 
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23656">23656</a>  
+hierarchy: type hierarchy on interfaces does not contain Object  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23890">23890</a>  
+Changing Package Declarations triggers full project rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24172">24172</a>  
+Strange behavior with wrong package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24093">24093</a>
+NPE in Java Builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22445">22445</a>
+Compiler inconsistent with javac when code returns from inside a finally {} block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24189">24189</a>
+need a way to  verify that a string can be a type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23925">23925</a>
+Class path vars missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24210">24210</a>
+NPE renaming project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24164">24164</a>
+Cannot use a specif rt.jar for a specific Java project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23989">23989</a>
+Build Path page reports cycle even if there is none
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22754">22754</a>
+JRE-Settings independent for each project
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 26th September 2002
+<br>Project org.eclipse.jdt.core v_275
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24083">24083</a>
+NPE accessing JavaProject preferences
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 24th September 2002
+<br>Project org.eclipse.jdt.core v_274
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new API findDeclaringNode(String) on CompilationUnit. This new method should be used to retrieve ASTNode
+declared in another compilation unit. See javadoc for further details or bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23734">23734</a>.
+</li>
+<li> New APIs added onto IJavaProject to enable project custom options. Project custom options are persisted into a file ".jprefs" 
+located inside the project metadata JDT/Core plugin location. Project can be specified custom options, and inherit global ones from JavaCore.
+At this point, it is unclear whether we will attempt to share these custom properties (like .classpath file).
+	<ul>
+		<li>
+<pre>
+	/**
+	 * Helper method for returning one option value only. Equivalent to <code>(String)this.getOptions(inheritJavaCoreOptions).get(optionName)</code>
+	 * Note that it may answer <code>null</code> if this option does not exist, or if there is no custom value for it.
+	 * 
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * 
+	 * @param optionName the name of an option
+	 * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+	 * @return the String value of a given option
+	 * @see JavaCore#getDefaultOptions
+	 * @since 2.1
+	 */
+	String getOption(String optionName, boolean inheritJavaCoreOptions);
+</pre>		
+		</li>
+		<li>
+<pre>
+	/**
+	 * Returns the table of the current custom options for this project. Projects remember their custom options,
+	 * i.e. only the options different from the the JavaCore global options for the workspace.
+	 * A boolean argument allows to directly merge the project options with global ones from <code>JavaCore</code>.
+	 * 
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * 
+	 * 
+	 * @param inheritJavaCoreOptions - boolean indicating whether JavaCore options should be inherited as well
+	 * @return table of current settings of all options 
+	 *   (key type: <code>String</code>; value type: <code>String</code>)
+	 * @see JavaCore#getDefaultOptions
+	 * @since 2.1
+	 */
+	Map getOptions(boolean inheritJavaCoreOptions);
+</pre>
+		</li>		
+		<li>
+<pre>
+	/**
+	 * Sets the project custom options. All and only the options explicitly included in the given table 
+	 * are remembered; all previous option settings are forgotten, including ones not explicitly
+	 * mentioned.
+	 * 
+	 * For a complete description of the configurable options, see <code>JavaCore#getDefaultOptions</code>.
+	 * 
+	 * 
+	 * @param newOptions the new options (key type: <code>String</code>; value type: <code>String</code>),
+	 *   or <code>null</code> to flush all custom options (clients will automatically get the global JavaCore options).
+	 * @see JavaCore#getDefaultOptions
+	 * @since 2.1
+	 */
+	void setOptions(Map newOptions);
+</pre>
+		</li>		
+	</ul>
+</li>
+	<li>Added <code>JavaCore.run(IWorkspaceRunnable, IProgressMonitor)</code> that allows batching
+		  of java model operations. Only one Java element changed event is reported at the end of the batch.
+		  For example the following code snippet notifies listeners twice:
+	<pre>
+	ICompilationUnit unit = ...;
+	unit.createType("class B {}", null, false, monitor);
+	unit.getType("A").createField("int i;", null, false, monitor);
+	</pre>
+		  To be notified only once, use the following:
+	<pre>
+	JavaCore.run(
+		new IWorkspaceRunnable() {
+			public void run(IProgressMonitor monitor) throws CoreException {
+				ICompilationUnit unit = ...;
+				unit.createType("class B {}", null, false, monitor);
+				unit.getType("A").createField("int i;", null, false, monitor);
+			}
+		},
+		monitor);
+	</pre>
+	</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23977">23977</a>
+.classpath corruption
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23734">23734</a>
+AST: CompilationUnit.findDeclaringNode only finds bindings from its own ast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23979">23979</a>
+Build Path page reports cycle even if there is none
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20881">20881</a>
+"organize imports" does not find an import statement "add import" does. [code manipulation]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7091">7091</a>
+turn off the debug info on a project by project basis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19663">19663</a>
+Java|Compiler|Other|Filtered resources needs to be project/team specific
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14062">14062</a>
+JDK Compliance against a project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22289">22289</a>
+To have file encoding by project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7395">7395</a>
+Set the compiler options per project instead of per workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23894">23894</a>
+Extra (TODO) Markers : There is no todo task when there is no error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23162">23162</a>
+DOM: clients should be able to control if bindings are available even if AST is modified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23901">23901</a>
+CCE in DefaultBindingResolver
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23597">23597</a>
+cannot resolve a call to a protected superclass method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23573">23573</a>
+AST: clone &amp; source locations
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22618">22618</a>
+incorrect warning about unread vars
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3239">3239</a>
+CodeFormatter: need to be able to set linedelimiter used (1GC0LFK)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22979">22979</a>
+using IScanner inside comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23550">23550</a>
+Micro-java, embedded java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23833">23833</a>  
+Java source attachment does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23402">23402</a>  
+Cancel on compile has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23635">23635</a>  
+Compilation Errors Inconsistent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21520">21520</a>  
+'Errors during build: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding' error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22148">22148</a>  
+Qlfd. vs. unqlfd. Name from IField.getTypeSignature  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21475">21475</a>
+No source for classes without debug information [general issue]
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 19th September 2002 - 2.1 MILESTONE-1
+<br>Project org.eclipse.jdt.core v_273a
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23558">23558</a>  
+Extremly slow startup  
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23788">23788</a>  
+Java compiler doesn't properly flag invalid protected access (for javac 1.4 compatibility)
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 16th September 2002
+<br>Project org.eclipse.jdt.core v_273
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The source lookup for .class files inside jar files has been improved. Before it worked only if the .class files
+had a source file attribute. This was too limiting in case of the usage of a library which has not been compiled in
+debug mode. Now in case there is no such source file attribute, an heuristic is used to create the proper entry. We
+assume that a class named A in a package p has been compiled from a class A.java in a folder p. For .class files
+that correspond to member or local classes the source mapping is using the top level class name in which the class is defined.
+The only limitiation that still exists is that it is not possible to retrieve the source for secondary types (types
+that are defined in a file which doesn't have the same name). See bug <A HREF="http://dev.eclipse.org/bugs/show_bug.cgi?id=21475">21475</a>
+for further details.</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21475">21475</a>
+Attaching Source-Code to a library which is not compiled with debug info
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23466">23466</a>
+Compiler violates JLS 8.3.2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21022">21022</a>
+warning on imports while typing and warning on unused imports is on
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329">23329</a>  
+search: incorrect range for type references in brackets  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23284">23284</a>
+AST: SingleVariableDeclaration needs extra dimensions?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23464">23464</a>
+ast: (Super)ConstructorInvocation should be wrapped in ExpressionStatement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22560">22560</a>
+"Add return type" correction could be smarter [quick fix]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23492">23492</a>
+[DOM/AST] lazy init should not count as a modification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23292">23292</a>  
+Must restart Eclipse after debug of source in .zip is updated  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22306">22306</a>
+AST: Constructor contains syntetic SuperConstructorCall
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22832">22832</a>
+select does not work when caret is at the begining of an identifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23242">23242</a>
+Bad line number info when multiple statements on same line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23362">23362</a>
+DOM: incorrect length for InfixExpression.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23357">23357</a>  
+Build not triggered on build path change
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21954">21954</a>  
+compile / debug VM mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23558">23558</a>  
+Extremly slow startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21952">21952</a>  
+Circular Dependencies Message - Error vs. Warning Message  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23375">23375</a>  
+cycle detection algorithm is O(pow(n - 1, n - 1))
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22900">22900</a>
+import of a.b.C fails if package a exists
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 10th September 2002
+<br>Project org.eclipse.jdt.core v_272
+<h2>
+What's new in this drop</h2>
+<ul>
+  <li>JavaCore option added for the error level (warning or error) of incomplete classpath or projects involved
+        in a cycle.
+        <pre>
+* JAVACORE / Reporting Incomplete Classpath
+*    An entry on the classpath doesn't exist or is not visible (e.g. a referenced project is closed).
+*     - option id:			"org.eclipse.jdt.core.incompleteClasspath"
+*     - possible values:	{ "error", "warning"}
+*     - default:			"error"
+* 
+* JAVACORE / Reporting Classpath Cycle
+*    A project is involved in a cycle.
+*     - option id:			"org.eclipse.jdt.core.circularClasspath"
+*     - possible values:	{ "error", "warning" }
+*     - default:			"error"
+        </pre>
+  </li>
+<li>New option -bootclasspath is added for the batch compiler. This option allows you to override the location of bootstrap
+class files. If omitted, the batch compiler will retrieve the libraries used by its JVM. So there is no more need to specify the
+rt.jar file using the -classpath option. The batch compiler also retrieves the contents of the property "java.class.path" if no 
+-classpath option is specified.
+</li>
+<li> Deprecation warning inside deprecated code are now ignored by default. A new JavaCore option
+allows to report them all.
+<pre>
+*	COMPILER / Reporting Deprecation Inside Deprecated Code
+*		When enabled, the compiler will signal use of deprecated API inside deprecated code.
+*     The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.deprecation".
+*     		- option id:		"org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode"
+*     		- possible values:	{ "enabled", "disabled" }
+*     		- default:			"disabled"
+</pre>
+</li>
+<li> Compiler can now optionally collect tasks from the source code. Occurrences of
+a given task tag are looked for inside any type of comments, and reported as custom task markers
+(<code>"org.eclipse.jdt.core.task"</code>).
+ <ul>
+ <li> New problem ID got created: <code>org.eclipse.jdt.core.compiler.IProblem#Task</code>. Note that
+ clients of <code>IProblemRequestor</code> will get detected tasks as warnings with this new ID, they
+ can be filtered out if needed.
+ </li>
+ <li> JavaCore option added for specifying the task tag values (default is <code>""</code> meaning no
+ task is detected).
+<pre>
+* COMPILER / Define the Automatic Task Tags
+*    When the tag is non empty, the compiler will issue a task marker whenever it encounters
+*    one of the corresponding tag inside any comment in Java source code.
+*    Generated task messages will include the tag, and range until the next line separator or comment ending, and will be trimmed.
+*     - option id:			"org.eclipse.jdt.core.taskTags"
+*     - possible values:	{ "&lt;tag&gt;[,&lt;tag&gt;]*" } where &lt;tag&gt; is a String without any wild-card 
+*     - default:			""
+</pre>	 
+ </li>
+ </ul>
+</li>
+<li> Creating a working copy on a non-existing ICompilationUnit is now allowed. 
+       Such a working copy will have its contents initialized to an empty string.
+       Commiting this working copy creates the underlying compilation unit.
+</li>
+</ul> 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23257">23257</a>
+IInitializer::getNameRange returns incorrect result
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23318">23318</a>  
+Resolution of Circular Dep. preference/error message filtering  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23113">23113</a>
+Request to enrich messages provided by AST with errors defined in IProblem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22154">22154</a>
+Proposed method for org.eclipse.jdt.core.dom.ITypeBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23181">23181</a>
+IScanner returns incorrect whitespaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23259">23259</a>
+AST: SwitchCase wrong length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23117">23117</a>
+DOM: no error message for method with wrong return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20215">20215</a>
+Batch compiler ignores the CLASSPATH env variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23054">23054</a>
+DOM - TypeDeclaration.getJavadoc() can find incorrect javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22054">22054</a>
+Can't extract local variable from super send [refactoring]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22161">22161</a>
+AST: Innerclass name: Positions wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22526">22526</a>
+Warning given when implementing deprecated methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23050">23050</a>
+DOM - IVariableBinding.getModifiers() doesn't give final modifier for local variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22939">22939</a>
+ast: incorrect range for a name in brackets
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458">22458</a>  
+Refactoring a package does not move the package's directory  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6976">6976</a>
+Auto collect tasks from code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23052">23052</a>
+DOM - CCE calling resolveBinding on an on-demand import from a type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22635">22635</a>
+recompile doesn't happen
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23118">23118</a>
+AST: BreakStatement &amp; ContinueStatement: wrong length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23048">23048</a>
+DOM - lazy initialization of empty loop bodies causes binding resolution to fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22203">22203</a>
+More dependencies increase GUI waiting time [build path]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=11529">11529</a>
+ast: missing (?) binding on simpleName in VariableDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8921">8921</a>  
+DCR - Need a way to create a working copy ignoring existing files  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22673">22673</a>  
+VerifyError in char cast of static final char referenced through instance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23075">23075</a>  
+Wrong compiling of inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23077">23077</a>  
+search: does not find type references in some imports 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22942">22942</a>  
+JavaProject.exists returns true when it should not  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22517">22517</a>  
+Cannot create type X in project Test if d:\test\X.java exists  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18684">18684</a>  
+Organize Imports doesn't work on external Jars  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22946">22946</a>  
+search: NPE  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22637">22637</a>  
+AST: Typos in Javadoc Assignment.Operator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17210">17210</a>  
+No match found when query contains '?'  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21420">21420</a>  
+Changing .classpath doesn't update JDT  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21485">21485</a>  
+NPE when doing a reference search to a package  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22428">22428</a>
+Compiler 1.4 - should report visibility issue for shadowed protected method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22418">22418</a>
+Should not complain about package for empty units
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22102">22102</a>  
+Not all implementors found for IPartListener  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20631">20631</a>  
+Declaration of local binary type not found  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20435">20435</a>  
+NPE when searching java method  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22334">22334</a>
+Compiler generates corrupt classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22361">22361</a>
+Error in javadoc for JavaCore.getResolvedClasspathEntry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21749">21749</a>
+Exported libraries and source folders
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22830">22830</a>
+Subtle visibility problem: class declaration resolved improperly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23264">23264</a>
+ast: incorrect node hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23116">23116</a>
+DCR: ModifierNode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23055">23055</a>
+DOM - SuperMethodInvocation.resolveTypeBinding() returns null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21843">21843</a>  
+Qualifier in "Type Hierarchy" View  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21158">21158</a>  
+Deadlock on startup  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22883">22883</a>  
+IJavaProject::find(String) returns null for non-primary top-level types  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22123">22123</a>  
+Inability to put a classpath var pointing to a dir inside the project which is one dir up from output dir  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12496">12496</a>  
+Creating a type hierarchy should not populate java model cache  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22453">22453</a>
+Compiler Problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22149">22149</a>
+jdk compiles but eclipse does not
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.0 Build - 1st August 2002
+<br>Project org.eclipse.jdt.core v_270
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22093">22093</a>
+VerifyError due to duplicate access method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21916">21916</a>
+VariableDeclarationExpression
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21911">21911</a>
+NPE in the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7517">7517</a>
+No control of formatting fo do {} while blocks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22078">22078</a>
+Incorrect error message
+
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 30th July 2002
+<br>Project org.eclipse.jdt.core v_269
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Add a new API getRawTokenSource() on org.eclipse.jdt.core.compiler.IScanner. It should be used if the user doesn't
+want the Unicode characters to be processed, otherwise use getCurrentTokenSource().</li>
+</ul> 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21912">21912</a>
+Compiler probleme: continue statement with label identifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21358">21358</a>
+DOM/AST: setLeadingComment and setJavadocComment doesn't support Unicode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21828">21828</a>
+Possible problem in DoStatement#accept0(...)
+  
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3458">3458</a>
+Resource folders containing source (1G4CKG9)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21627">21627</a>
+Compiled class error on iSeries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21723">21723</a>
+Getting java.lang.OutOfMemoryError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16176">16176</a>
+References to private fields could be optimized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21109">21109</a>
+Have option for compiler warning on use of static field/method through reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3357">3357</a>
+DCR - Add compiler option (1GJJQAD)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21879">21879</a>
+Search could be optimized based on visibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21868">21868</a>
+No return statement for code with infinite loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20820">20820</a>
+Squiggly line is at a bad place for missing return statement
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.0 Build - 23rd July 2002
+<br>Project org.eclipse.jdt.core v_268
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added optional compiler problem for signalling non-static invocations of static field/methods
+(see <code>JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER()</code>)
+</li>
+<li>Compilation problem descriptions are now shortened (qualified type arguments
+are dequalified in the problem message, problem arguments are left fully qualified).
+</li>
+</ul> 
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20402">20402</a>
+Error Description too long, should not list full class name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21778">21778</a>
+ClassFileReader fails on Gnome Twain class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21787">21787</a>
+Provide compiler warning of using static method via non-static style.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21768">21768</a>
+ast: incorrect length of SimpleName in MethodDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21757">21757</a>
+ast: incorrect range for Name in TypeDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21754">21754</a>
+typo in IType::getSuperInterfaceNames javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21672">21672</a>
+Wrong location for the last 'return' bytecode command
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 22nd July 2002
+<br>Project org.eclipse.jdt.core v_267
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21606">21606</a>
+ImageBuilder deletes &amp; adds rather than overwriting
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21282">21282</a>
+IType.getFullyQualifiedName() problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21182">21182</a>
+unimplemented method error after implementing in super
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21682">21682</a>
+marking a method deprecated doesn't eleminate deprecated warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21556">21556</a>
+"Missing code implementation in the compiler"
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.0 Build - 15th July 2002
+<br>Project org.eclipse.jdt.core v_266
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21580">21580</a>
+VerifyError in 1.4 compliant mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21557">21557</a>
+VM bug prevents valid Java code to be executed on VM &lt; 1.3.1
+
+<h3>Problem Reports Closed</h3>
+
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build - 12th July 2002
+<br>Project org.eclipse.jdt.core v_265
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Changed ASCII/binary property for entire project.</li>
+</ul> 
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21230">21230</a>
+Rebuilding project fails with ContextStackOverflow (CompilationResult.quickPrioritize)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21203">21203</a>
+Compile time NullPointerException in catch blocks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21447">21447</a>
+Wrong method invoked at runtime
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21482">21482</a>
+Error in generated byte code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21480">21480</a>
+Bytecode disassembler doesn't handle #invokespecial correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20725">20725</a>
+JavaBuilder.toString can throw NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20865">20865</a>
+nullPointerException being thrown by Class Type.resolveBinding()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21116">21116</a>  
+Can't compile because eclipse says that the method is not visible
+
+<h3>Problem Reports Closed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21049">21049</a>  
+Save (Build / Compile?) performance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20961">20961</a>  
+Can't get complete classpath for project.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21428">21428</a>  
+DOM/AST: AST class unnecessarily plug-in dependent?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20059">20059</a>  
+project.isOnClassPath(project) result random  
+
+<p><hr>
+For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html">build notes up to Release 2.0</a>.
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html
new file mode 100644
index 0000000..cc985a5
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html
@@ -0,0 +1,4492 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes</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.0 stream</b></font>
+    </td>
+  </tr>
+  <tr>
+    <td align="left" width="72%" class="title2">
+		<font size="-2" color="#8080ff">Java development tools core</font>
+	</td>
+  </tr>
+	<tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  Here are the build notes for the Eclipse JDT/Core plug-in project 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
+	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
+	  This present document covers all changes since Release 2.1 (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>).
+	  Older changes which occurred up to Release 2.1 can be found in 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html">build notes R2.1</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<a name="v_449"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC4 Build - 24th June 2004 - 3.0 RELEASE CANDIDATE 4
+<br>Project org.eclipse.jdt.core v_449
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_449">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fixed schema copyrights.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44068">44068</a>
+[DOC] Need more project configuration tutorials
+
+<a name="v_448"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC4 Build - 24th June 2004
+<br>Project org.eclipse.jdt.core v_448
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_448">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fixed mixed line delimiters.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_447"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC4 Build - 23rd June 2004
+<br>Project org.eclipse.jdt.core v_447
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_447">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Copyright update to 2004.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_446"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC4 Build - 22nd June 2004
+<br>Project org.eclipse.jdt.core v_446
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_446">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67769">67769</a>
+Internal StackOverflowError occurred during project build
+
+<a name="v_445"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC3 Build - 18th June 2004 - 3.0 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_445
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_445">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66898">66898</a>
+refactor-rename: encoding is not preserved
+
+<a name="v_444"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC3 Build - 18th June 2004
+<br>Project org.eclipse.jdt.core v_444
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_444">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67297">67297</a>
+Renaming included package folder throws JME 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67786">67786</a>
+OutOfMemoryError searching for reference to Object 
+
+<a name="v_443"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC3 Build - 18th June 2004
+<br>Project org.eclipse.jdt.core v_443
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_443">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67717">67717</a>
+NPE disassembling .class file
+
+<a name="v_442"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC3 Build - 17th June 2004
+<br>Project org.eclipse.jdt.core v_442
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_442">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67600">67600</a>
+String Index out of bounds when searching for all types 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67599">67599</a>
+NPE when cancelling search 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66271">66271</a>
+No need to resolve type names when selecting declaration
+
+<a name="v_441"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC3 Build - 16th June 2004
+<br>Project org.eclipse.jdt.core v_441
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_441">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67324">67324</a>
+Package Explorer doesn't update included package after moving contents of source folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41434">41434</a>
+[msic] Slow Down using classes with many methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64646">64646</a>
+[Navigator] Navigator popup causes Eclipse to hang. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65186">65186</a>
+Can't attach source from project directory [build path] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65831">65831</a>
+search for all types slow/memory intensive [search] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66675">66675</a>
+Extra period in the doc in 200406110010
+
+<a name="v_440"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC2 Build - 10th June 2004 - 3.0 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_440
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_440">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66551">66551</a>
+Error in org.eclipse.swt project on class PrinterData
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66573">66573</a>
+Shouldn't bind to local constructs
+
+<a name="v_439"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC2 Build - 10th June 2004
+<br>Project org.eclipse.jdt.core v_439
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_439">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66216">66216</a>
+Sort Members is broken.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66437">66437</a>
+Canceling search leads to broken workspace 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65266">65266</a>
+JarPackageFragmentInfo has unnecessary field 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66098">66098</a>
+MatchLocatorParser does not need advanced syntax diagnosis
+
+<a name="v_438"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC2 Build - 9th June 2004
+<br>Project org.eclipse.jdt.core v_438
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_438">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66026">66026</a>
+Large amount of garbage created by DefaultCommentMapper
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64646">64646</a>
+[Navigator] Navigator popup causes Eclipse to hang. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65288">65288</a>
+Javadoc: tag gets mangled when javadoc closing on same line without whitespace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65253">65253</a>
+[Javadoc] @@tag is wrongly parsed as @tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65180">65180</a>
+Spurious "Javadoc: xxx cannot be resolved or is not a field" error with inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65174">65174</a>
+Spurious "Javadoc: Missing reference" error
+
+<a name="v_437"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC2 Build - 8th June 2004
+<br>Project org.eclipse.jdt.core v_437
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_437">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66142">66142</a>
+SearchParticipant#scheduleDocumentIndexing() fails silently if index doesn't exist 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65795">65795</a>
+source inclusion mechanism breaks type lookups 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66099">66099</a>
+Persisted container/variable values are leaked throughout a session
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65250">65250</a>
+Problem selection does not choose first n errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65259">65259</a>
+CodeSelect should only find one match for dup methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65737">65737</a>
+Strange completion by code assist 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65871">65871</a>
+Missing SUPER_INTERFACE_TYPES_PROPERTY in EnumDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53072">53072</a>
+[DOC] Search for fully qualified constructor name reports nothing 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65116">65116</a>
+IProjectDescription.getBuildSpec copies commands 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65234">65234</a>
+Inclusion filter not working 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64657">64657</a>
+better documentation for IType#resolveType behavior 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65693">65693</a>
+Package Explorer shows .class files instead of .java 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64750">64750</a>
+NPE in Java AST Creation - editing some random file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65562">65562</a>
+Java AST creation failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65531">65531</a>
+out of the box formatter settings need to be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65677">65677</a>
+Creating hierarchy failed. See log for details. 0 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65090">65090</a>
+ASTParser with kind == K_STATEMENTS doesn't work unless source range specified
+	  	
+<a name="v_436"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC1 Build - 28th May 2004 - 3.0 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_436
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_436">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63534">63534</a>
+ConcurrentModificationException after "catching up" 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62131">62131</a>
+CodeStream should do bounds checks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64470">64470</a>
+&lt;packages prefixes=..../&gt; should be removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64299">64299</a>
+NullPointerException when OverrideIndicatorLabelDecorator is decorating
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63550">63550</a>
+NPE "Java AST Creation"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64421">64421</a>
+ArrayIndexOutOfBoundsException in PackageReferenceLocator.matchReportReference()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62453">62453</a>
+Large File: Java builder not reacting on cancel
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64377">64377</a>
+CRASH: An internal error occurred during: "Java AST creation"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64378">64378</a>
+Wording of error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64332">64332</a>
+Javadoc errors in non-API doc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64329">64329</a>
+Missing Javadoc tags declaration in API methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64170">64170</a>
+Classpath reentrance protection is not thread-safe 
+
+<a name="v_435"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC1 Build - 27th May 2004
+<br>Project org.eclipse.jdt.core v_435
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_435">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>API polish on search matches (org.eclipse.jdt.core.search.SearchMatch hierarchy):
+<ul>
+<li>added setters for all match properties (not just length &amp; offset)</li>
+<li>add insideDocComment argument to PackageReferenceMatch constructor (for 
+being consistent with other reference matches)</li>
+</ul>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62697">62697</a> for more details.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62854">62854</a>
+refactoring does not trigger reconcile 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62697">62697</a>
+Need to know if a package reference match is in Javadoc or in Code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63756">63756</a>
+multiple builds early
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63077">63077</a>
+IllegalArgumentException in Openable.codeSelect 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62861">62861</a>
+ArrayIndexOutOfBoundsException in SearchableEnvironment 
+
+
+<a name="v_434"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0RC1 Build - 26th May 2004
+<br>Project org.eclipse.jdt.core v_434
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_434">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=56870">56870</a>
+copied file not shown in package explorer / java browser [ccp] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63748">63748</a>
+Type Hierarchy: null pointer when pressing F4 on ListCellRenderer 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38839">38839</a>
+org.eclipse.jdt.internal.compiler.parser.Scanner throws thousands of Exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62869">62869</a>
+[navigation] 'Go to Next Annotation' doesn't find next error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63871">63871</a>
+Using M9, -warn: option crashes the batch compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63434">63434</a>
+NPE during checkout/build 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62737">62737</a>
+Code formatter doesn't work on some files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62639">62639</a>
+[1.5] Cheetah and extending Vector
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62769">62769</a>
+Javadoc errors in 200405180816
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62952">62952</a>
+Ant adapter behavior is a little strange
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62704">62704</a>
+Using 05180816, //toto is a task if //toto is a task tag.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51660">51660</a>
+[DOM/AST] AST.parse* should handle all legal doc tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51606">51606</a>
+Javadoc - {@inheritDoc} should be inefficient when not in first text element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62713">62713</a>
+should not be able to nest output folders [build path]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63245">63245</a>
+findPackageFragment won't return default package 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62698">62698</a>
+NPE while searching for declaration of binary package 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61017">61017</a>
+Refactoring - test case that results in uncompilable source 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63044">63044</a>
+Reference to a constructor inside a javadoc should point to a type binding and not a constructor binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62812">62812</a>
+Some malformed javadoc tags are not reported as malformed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62810">62810</a>
+Deadlock when closing editors and save 
+
+
+<a name="v_433"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 21st May 2004 - 3.0 MILESTONE-9 / 3.0 RELEASE CANDIDATE 0
+<br>Project org.eclipse.jdt.core v_433
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_433">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul><li>Put back test org.eclipse.jdt.core.tests.model.JavaElementDeltaTests.testBuildProjectUsedAsLib()
+after bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62927">62927</a> was fixed.</li>
+</ul>
+
+<a name="v_432"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 20th May 2004
+<br>Project org.eclipse.jdt.core v_432
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_432">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul><li>Excluded test org.eclipse.jdt.core.tests.model.JavaElementDeltaTests.testBuildProjectUsedAsLib()</li>
+</ul>
+
+<a name="v_431"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 20th May 2004
+<br>Project org.eclipse.jdt.core v_431
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_431">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62881">62881</a>
+JDT/Core could be contributing a content type for JAR manifests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58580">58580</a>
+VariableBinding.getVariableId() returns wrong IDs for nested types
+
+<a name="v_430"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 18th May 2004
+<br>Project org.eclipse.jdt.core v_430
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_430">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62608">62608</a>
+Include pattern ending with slash should include all subtree 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59933">59933</a>
+applying exclusion filter to opened java file makes it appear twice [build path]
+
+
+<a name="v_429"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 18th May 2004
+<br>Project org.eclipse.jdt.core v_429
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_429">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39499">39499</a>
+keyword completion does not work in anonymous inner classes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59282">59282</a>
+Unable to include an external folder with class files to project classpath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52422">52422</a>
+F3 can't find method def'n inside inner (anonymous) class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62463">62463</a>
+Wrong length for ExpressionStatement after conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61831">61831</a>
+Full build happens on every start of Eclipse 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62201">62201</a>
+NPE in MethodScope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61872">61872</a>
+library looses content when setting source attachment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54962">54962</a>
+plain reference to package not found in (@see) javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54424">54424</a>
+AST has structural problems with incomplete javadoc tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51951">51951</a>
+codeComplete finds no completion in method of local class inside static method 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50686">50686</a>
+NPE in MethodScope.createMethod 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61952">61952</a>
+Bad deprecation -- IJavaSearchConstants#CASE_SENSITIVE 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62068">62068</a>
+Index manager should use client's index location 
+
+<a name="v_428"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 13th May 2004
+<br>Project org.eclipse.jdt.core v_428
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_428">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Due to an implementation cleanup, the optional diagnosis for unnecessary empty statement or empty control-flow
+statement, will be reverted to ignore by default. If you did set it differently in the past, you will have to manually
+set it back. We now conform to the spec for this option (until JDT/UI converted, the old option ID was 
+incorrectly used: "org.eclipse.jdt.core.compiler.problem.superfluousSemicolon"):
+<pre>
+* COMPILER / Reporting Empty Statements and Unnecessary Semicolons
+*    When enabled, the compiler will issue an error or a warning if an empty statement or a
+*    unnecessary semicolon is encountered.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.emptyStatement"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>	 
+</li>
+<li>Improved error location when type indirectly referenced from required .class files.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61959">61959</a>
+dangerous practice of catching Throwable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61882">61882</a>
+Inconsistency between build errors and reconcile errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35356">35356</a>
+Convert local variable to field refactoring proposes weird name 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53555">53555</a>
+SourceType#get*QualifiedName() methods return unusable/invalid names for local types 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48752">48752</a>
+Completion: relevance could be improved for non static field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61877">61877</a>
+ClassCastException in DefaultBindingResolver
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59769">59769</a>
+Javadoc of SearchMatch#getElement(): is *enclosing* element 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58440">58440</a>
+type hierarchy incomplete when implementing fully qualified interface 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61719">61719</a>
+Incorrect fine grain delta after method copy-rename 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61075">61075</a>
+[Compiler] implementation uses numerous ArrayIndexOutOfBoundsException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19898">19898</a>
+StackOverflowError in BinaryExpression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61706">61706</a>
+Improve error message when unbound reference from binaries
+
+<a name="v_427"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 11th May 2004
+<br>Project org.eclipse.jdt.core v_427
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_427">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>A system job now reports progress when the indexer is running.</li>
+<li>The org.eclipse.jdt.core.jdom package has been deprecated. The JDOM was made obsolete by 
+      the addition in 2.0 of the more powerful, fine-grained DOM/AST API found in the 
+      org.eclipse.jdt.core.dom package.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60689">60689</a>
+AST on reconcile: AST without Javadoc comments created
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60365">60365</a>
+hierarchy view shows some interfaces as classes [type hierarchy] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53290">53290</a>
+[Javadoc] Compiler should complain when tag name is not correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53279">53279</a>
+[Javadoc] Compiler should complain when inline tag is not terminated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51600">51600</a>
+Javadoc: tags with errors are not stored in DOM AST Javadoc hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59751">59751</a>
+No Feedback/information from indexing 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42402">42402</a>
+OuterClass.this does not appear in code assist of the InnerClass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61390">61390</a>
+Indexing thread grabbing resource lock 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61408">61408</a>
+Incorrect parsing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58859">58859</a>
+[encoding] Editor does not detect BOM on .txt files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61148">61148</a>
+deprecate JDOM API 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61270">61270</a>
+Wrong delta when copying a package that overrides another package 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61181">61181</a>
+Task tag starting with double-/ (//) causes compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61040">61040</a>
+Should add protect for reentrance to #getResolvedClasspath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61214">61214</a>
+The classpath computation inside the Java builder should get rid of duplicates entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60867">60867</a>
+LocalVariableReferenceMatch should offer isReadAccess(), etc. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59638">59638</a>
+ConcurrentModificationException in JavaModelManager.saving 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61052">61052</a>
+Flatten cp container initialization 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60848">60848</a>
+[reconciling] Unclosed Comment in Java Texteditor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60822">60822</a>
+Reacting to Project &gt; Clean... 
+	  	
+<a name="v_426"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 4th May 2004
+<br>Project org.eclipse.jdt.core v_426
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_426">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new flag IJavaElementDelta.F_PRIMARY_RESOURCE that is set when the resource of a primary working copy 
+     changes (or when it is added or removed).</li>
+<li>Removed dependency on org.eclipse.runtime.compatibility.</li>
+<li>Tuned the diagnosis for unnecessary else statements to tolerate else-if constructs.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60687">60687</a>
+NPE in JavaCore.getEncoding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60581">60581</a>
+"Java AST creation" error.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48502">48502</a>
+Exception during "Java AST creation"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59750">59750</a>
+DCR: Code Assist: Hook to add getter and setters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47227">47227</a>
+Syntax error diagnosis shouldn't expose internal goal tokens
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60595">60595</a>
+AST: AST from reconcile does not have 'ORIGINAL' bit set
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59500">59500</a>
+Java Model Notification needs notification that a java class was physically saved 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60459">60459</a>
+AST: 'malformed' flag overwrites other flags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60367">60367</a>
+dynamic project references not maintained
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60257">60257</a>
+SearchPattern API: R_CASE_SENSITIVE vs. boolean isCaseSensitive 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58565">58565</a>
+code formatter doesn't format blocks with a return statement correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58724">58724</a>
+Java code formatter should add space between imports and class definition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60418">60418</a>
+remove warnings from core runtime deprecations 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57749">57749</a>
+Search in working copies doesn't find all matches 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60235">60235</a>
+WorkingCopyOwner needs clarification on
+
+
+<a name="v_425"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 28th April 2004
+<br>Project org.eclipse.jdt.core v_425
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_425">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API to register/deregister a pre-processing resource change listener:
+<pre>
+/**
+ * Adds the given listener for POST_CHANGE resource change events to the Java core. 
+ * The listener is guarantied to be notified of the POST_CHANGE resource change event before
+ * the Java core starts processing the resource change event itself.
+ * 
+ * Has no effect if an identical listener is already registered.
+ * 
+ * @param listener the listener
+ * @see #removePreResourceChangeListener(IResourceChangeListener)
+ * @since 3.0
+ */
+public static void addPreProcessingResourceChangedListener(IResourceChangeListener listener);
+	
+/**
+ * Removes the given pre-processing resource changed listener.
+ *
+ * Has no effect if an identical listener is not registered.
+ *
+ * @param listener the listener
+ * @since 3.0
+ */
+public static void removePreProcessingResourceChangedListener(IResourceChangeListener listener);
+</pre>
+</li>
+<li>When diagnostic for unnecessary semicolon is enabled, the compiler will also flag empty
+control-flow statement: e.g. if (bool);.  Note that the naming of the option is going soon
+to be revised to better reflect this evolution.
+Empty control-flow statement problem ID is: <tt>IProblem.EmptyControlFlowStatement</tt>.
+</li>
+<li>Added compiler style option to report situation where a statement is unnecessarily nested
+in else clause, e.g.: 
+<pre>
+ if (bool) 
+   return;
+ else
+   System.out.println();   // no need to be inside else
+</pre>    
+Associated problem ID is: <tt>IProblem.UnnecessaryElse</tt>.
+<pre>
+* COMPILER / Reporting Unnecessary Else
+*    When enabled, the compiler will issue an error or a warning when a statement is unnecessarily
+*    nested within an else clause (in situation where then clause is not completing normally).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unnecessaryElse"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42493">42493</a>
+Error message when evaluating: Expressionopt?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32061">32061</a>
+No code assist in instance variable inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49904">49904</a>
+[DCR] Quick Assist : unneeded else
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60081">60081</a>
+[Compiler] java.lang.VerifyError: Illegal target of jump or branch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52805">52805</a>
+[DCR] Compiler should warn when using if (test);
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58652">58652</a>
+ImageBuilderInternalException during auto build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60108">60108</a>
+SearchMatch should implement toString() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60078">60078</a>
+NPE in ASTConverter
+
+<a name="v_424"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 27th April 2004
+<br>Project org.eclipse.jdt.core v_424
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_424">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54108">54108</a>
+Weird piece of source code in SourceTypeConverter.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51500">51500</a>
+[DOM AST] Quick fix "Add unimplemented methods" fails on static variable initialized using anonymous constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59843">59843</a>
+Eclipse 3.0M8 generates ambiguous keys from ITypeBindings for nested classes with the same name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59937">59937</a>
+Should not process saved state delta during startup 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58069">58069</a>
+Compilation ERROR: Missing code implementation in the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51911">51911</a>
+@see method w/out ()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49025">49025</a>
+Util.bind(String, String[]) can be optimized a little bit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59743">59743</a>
+[Compiler] Incorrect diagnosis of ambiguous method when inheriting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57871">57871</a>
+Override Indicator: blocks editor from opening when error occurs in java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59421">59421</a>
+Bad error message from Eclipse Java Compiler when file is missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58946">58946</a>
+Standalone compiler help text is incorrect on Unix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59084">59084</a>
+[content type] ensure content types/file associations are contributed by the right plugins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59716">59716</a>
+Using 200404201300, one more blank line is inserted in front of import declarations when no package is defined
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59575">59575</a>
+invalid formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51213">51213</a>
+Unable to resolve conflict between type and package name in binaries
+
+<a name="v_423"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 22nd April 2004
+<br>Project org.eclipse.jdt.core v_423
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_423">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59363">59363</a>
+Should surface cancellation exceptions 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51075">51075</a>
+Compiler warning "is hiding a field" given for static inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38658">38658</a>
+Search for existing type fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59291">59291</a>
+Deadlock between AllTypes cache and setClasspathContainer
+
+
+<a name="v_422"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 20th April 2004
+<br>Project org.eclipse.jdt.core v_422
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_422">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API for User Library Container support in JavaCore:
+<pre>
+
+/**
+ * Name of the User Library Container id.
+ */
+public static final String USER_LIBRARY_CONTAINER_ID= "org.eclipse.jdt.USER_LIBRARY"; //$NON-NLS-1$
+
+/**
+ * Returns the names of all defined user libraries. The corresponding classpath container path
+ * is the name appended to the USER_LIBRARY_CONTAINER_ID.  
+ * @return Return an array containing the names of all known user defined.
+ */
+public static String[] getUserLibraryNames();
+</pre>
+</li>
+<li>Added API to get classpath container comparison ID in ClasspathContainerInitializer:
+<pre>
+/**
+ * Returns an object which identifies a container for comparison purpose. This allows
+ * to eliminate redundant containers when accumulating classpath entries (e.g. 
+ * runtime classpath computation). When requesting a container comparison ID, one
+ * should ensure using its corresponding container initializer. Indeed, a random container
+ * initializer cannot be held responsible for determining comparison IDs for arbitrary 
+ * containers.
+ * 
+ * @param containerPath the path of the container which is being checked
+ * @param project the project for which the container is to being checked
+ * @return returns an Object identifying the container for comparison
+ * @since 3.0
+ */
+public Object getComparisonID(IPath containerPath, IJavaProject project);
+</pre>
+By default, containers are identical if they have same container path first segment
+but this may be refined by other container initializer implementations.
+<br>
+For example, the User Library classpath container initializer added for User Library Container API
+implementation (UserLibraryClasspathContainerInitializer) refines the comparison ID to the entire container path.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52747">52747</a>
+formatter - please special case empty array init
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59000">59000</a>
+Code formatter struggles with end-of-line comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52679">52679</a>
+Code formatter formats braces in case and default statements, but no settings exist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52940">52940</a>
+Formatter: Separate control of new lines in control statements by statement type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47815">47815</a>
+Refactoring doesn't work with some project names [refactoring] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37657">37657</a>
+[plan item] Improve code formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50989">50989</a>
+Non-externalized strings wrap lines incorrectly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57689">57689</a>
+ArrayIndexOutOfBoundsException when creating a new class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55004">55004</a>
+[DCR] IVariableBinding should have a method returning the constant value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58606">58606</a>
+Inner class in child calling protected method in parent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55979">55979</a>
+There are still deprecated formatter constants without new way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57117">57117</a>
+Ant adapter preserves all deprecation when using compiler arg even if deprecation is set to off
+
+<a name="v_421"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 13th April 2004
+<br>Project org.eclipse.jdt.core v_421
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_421">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57829">57829</a>
+Should optimize assert true case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57294">57294</a>
+Ignore serialVersionUID hiding another field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41395">41395</a>
+StackOverflowError when pasting code 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57414">57414</a>
+Summary: GB18030: Can not open Java Search dialog. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57886">57886</a>
+Concurrency issue while initializing containers and variables 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57858">57858</a>
+[Compiler] Marking a field deprecated still report deprecated usage #46973
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57743">57743</a>
+[Compiler] invalid byte code produced when catching Throwable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57235">57235</a>
+DCR: AST Name.getQualifiedName()
+
+<a name="v_420"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 6th April 2004
+<br>Project org.eclipse.jdt.core v_420
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_420">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added inclusion patterns support. See <code>JavaCore.newSourceEntry(IPath,IPath[],IPath[],IPath)</code> 
+	 and <code>IClasspathEntry.getInclusionPatterns()</code> for details.</li>
+<li>Added API on WorkingCopyOwner to set the primary buffer provider (for internal use by the jdt-related plug-ins only).
+<pre>
+/**
+ * Sets the buffer provider of the primary working copy owner. Note that even if the
+ * buffer provider is a working copy owner, only its createBuffer(ICompilationUnit)
+ * method is used by the primary working copy owner. It doesn't replace the internal primary 
+ * working owner.
+ * 
+ * This method is for internal use by the jdt-related plug-ins.
+ * Clients outside of the jdt should not reference this method.
+ * 
+ * @param primaryBufferProvider the primary buffer provider
+ */
+public static void setPrimaryBufferProvider(WorkingCopyOwner primaryBufferProvider);
+</pre></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54009">54009</a>
+jardesc should be known to Team/File Content
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51867">51867</a>
+An anonymous type is missing in type hierarchy when editor is modified 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54763">54763</a>
+[Compiler] Unnecessary cast not detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52347">52347</a>
+NPE in LaunchingPlugin.shutdown 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55992">55992</a>
+AssertionFailed during preference import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29964">29964</a>
+Add inclusion filter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55088">55088</a>
+IAE when using ICU.reconcile(GET_AST_TRUE, ...) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=56462">56462</a>
+[formatter] java profile; array initializer before closing brace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=56449">56449</a>
+Need to know if a reference match is in Javadoc or in Code 
+
+<a name="v_419"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M9 Build - 30th March 2004
+<br>Project org.eclipse.jdt.core v_419
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_419">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Replaced "name" property of ParameterizedType node (DOM/AST) 
+with "type" property. The old methods and fields (added earlier in 3.0 cycle)
+are deprecated and will be removed shortly.</li>
+<li>Added typeParameters property to ClassInstanceCreation node (DOM/AST).</li>
+<li>Package org.eclipse.jdt.core.internal.dom.rewrite renamed to org.eclipse.jdt.internal.core.dom.rewrite.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=56316">56316</a>
+JavaProject exists should not populate 
+	  	
+<a name="v_418"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 25th March 2004 - 3.0 MILESTONE-8
+<br>Project org.eclipse.jdt.core v_418
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_418">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55930">55930</a>
+File encoding should be used on save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55478">55478</a>
+Unused import not reported in IDE
+	  	
+<a name="v_417"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 24th March 2004
+<br>Project org.eclipse.jdt.core v_417
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_417">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed failing tests re: encoding support.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_416"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 23rd March 2004
+<br>Project org.eclipse.jdt.core v_416
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_416">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul> 
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55504">55504</a>
+@&lt;tasktag&gt; should not be reported
+
+<a name="v_415"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 23rd March 2004
+<br>Project org.eclipse.jdt.core v_415
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_415">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul> 
+<li> Added rewriting support to DOM AST.
+There are two set of API to perform rewriting.
+<ul> 
+<li>An AST-modifying rewrite API<br>
+To use the AST-modifying rewrite the client must create an AST from an existing
+compilation unit (ASTParser#createAST(...)).
+Then the client need to start the record process of the AST changes (CompilationUnit#recordModifications())
+and modify the AST after. When modifications are done, the client can call a method to
+compute a text edit tree containing all the text changes (CompilationUnit#rewrite()).
+
+<pre>
+CompilationUnit
+	public void recordModifications()
+	public TextEdit rewrite(IDocument document, Map options) throws RewriteException
+</pre>
+</li>
+<li>A describing rewrite API<br>
+To use the describing AST rewrite, the client starts with creating an instance of NewASTRewrite. Then the client
+must not modify the AST directly but use NewASTRewrite instead. When modifications are done, the client can call
+a method to compute a text edit tree containing all the text changes (NewASTRewrite#rewrite()).
+<pre>
+NewASTRewrite
+	public final void markAsRemoved(ASTNode node, TextEditGroup editGroup)
+	public final void markAsReplaced(ASTNode node, ASTNode replacingNode, TextEditGroup editGroup)
+	public ListRewriter getListRewrite(ASTNode parent, ChildListPropertyDescriptor childProperty)
+	public TextEdit rewriteAST(IDocument document, Map options) throws RewriteException
+	...
+	
+ListRewriter
+	remove(ASTNode, TextEditGroup)
+	public void replace(ASTNode, ASTNode, TextEditGroup)
+	public void insertAfter(ASTNode, ASTNode, TextEditGroup)
+	public void insertBefore(ASTNode, ASTNode, TextEditGroup)
+	public void insertFirst(ASTNode, TextEditGroup)
+	public void insertLast(ASTNode, TextEditGroup)
+	public void insertAt(ASTNode, int, TextEditGroup)
+	...
+</pre>
+</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39068">39068</a>
+Adopt new core API for encoding on a per file basis
+
+<a name="v_414"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 22nd March 2004
+<br>Project org.eclipse.jdt.core v_414
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_414">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul> 
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46668">46668</a>
+Changes to class path containers should not change .project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55421">55421</a>
+Cannot save a .java file in a non-java project anymore 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55223">55223</a>
+Bug in comment mapper: Same comment mapped to 2 statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54044">54044</a>
+Ant log does not use system newline character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55372">55372</a>
+Should not assume that Preferences.defaultPropertyNames() returns default-default properties 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55221">55221</a>
+Bug in comment mapper: Grabs next node's Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=55102">55102</a>
+NPE when using ICU.reconcile(GET_AST_TRUE, ...) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49986">49986</a>
+setRawClasspath(...) should fire a F_CLASSPATH_CHANGED delta 
+
+<a name="v_413"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 15th March 2004
+<br>Project org.eclipse.jdt.core v_413
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_413">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul> 
+<li> Added compiler option JavaCore.COMPILER_TASK_CASE_SENSITIVE to control whether the task detection
+should be case sensitive or not. By default, it is.
+<pre>
+ * COMPILER / Determine whether task tags are case-sensitive
+ *    When enabled, task tags are considered in a case-sensitive way.
+ *     - option id:         "org.eclipse.jdt.core.compiler.taskCaseSensitive"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "enabled"
+</pre>
+</li>
+<li> Added 2 default task tags: "FIXME" and "XXX".
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54776">54776</a>
+DefaultCommentMapper: different behaviour
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54431">54431</a>
+ASTParser should honor set compiler options in all cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54043">54043</a>
+Problems with type hierarchy for binary types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53095">53095</a>
+I20040225: Won't accept breakpoint on NoClassDefFoundError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54294">54294</a>
+No default for JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48435">48435</a>
+Java Search for OR-pattern finds too much in strange project setup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40921">40921</a>
+Task tags should be case-insensitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49266">49266</a>
+FIXME task tag
+
+
+<a name="v_412"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 8th March 2004
+<br>Project org.eclipse.jdt.core v_412
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_412">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added new global JavaCore.COMPILER_DOC_COMMENT_SUPPORT option for doc comment (Javadoc) support. By default, this option is enabled for backward compatibility.
+<pre>
+ * COMPILER / Javadoc Comment Support
+ *    When this support is disabled, the compiler will ignore all javadoc problems options settings
+ *    and will not report any javadoc problem. It will also not find any reference in javadoc comment and
+ *    DOM AST Javadoc node will be only a flat text instead of having structured tag elements.
+ *     - option id:         "org.eclipse.jdt.core.compiler.doc.comment.support"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "enabled"
+</pre>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52264">52264</a>.
+</li>
+<li> Added new JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE option to allow user to inline subroutine code instead of generating JSR instructions. By default, this option is disabled.
+<pre>
+ * COMPILER / Inline JSR Bytecode Instruction
+ *    When enabled, the compiler will no longer generate JSR instructions, but rather inline corresponding
+ *    subroutine code sequences (mostly corresponding to try finally blocks). The generated code will thus
+ *    get bigger, but will load faster on virtual machines since the verification process is then much simpler. 
+ *    This mode is anticipating support for the Java Specification Request 202.
+ *     - option id:         "org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "disabled"
+ * 
+</pre>
+Corresponding command line compiler option <code>-noJSR</code> has been renamed to:
+<pre>
+    <code>-inlineJSR</code> : inline JSR bytecode
+</pre>
+which means that when specified, the compiler will no longer generate JSR bytecodes, but instead inlining the corresponding subroutine (e.g. finally block).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53757">53757</a>
+Javadoc tag @transient  ignored
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=530757">53075</a>
+https://bugs.eclipse.org/bugs/show_bug.cgi?id=53075
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53357">53357</a>
+Java AST creation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52264">52264</a>
+Need a global preference to enable Javadoc support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51529">51529</a>
+"Organize imports" is confused by references inside Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53477">53477</a>
+AnonymousClassDeclaration has wrong range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53624">53624</a>
+StackOverFlow in Code assist 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50433">50433</a>
+Rationalize signatures of AST.parse* methods 
+
+<a name="v_411"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 3rd March 2004
+<br>Project org.eclipse.jdt.core v_411
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_411">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new constant <code>IJavaElementDelta.F_CLASSPATH_CHANGED</code> that indicates that
+	  the project's raw classpath has changed.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49986">49986</a>
+setRawClasspath(...) should fire a F_CLASSPATH_CHANGED delta 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53242">53242</a>
+Consitent Out of Memory problems indexing (with multiple Java libraries)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52474">52474</a>
+UI Blocked when opening Java Perspective during CVS check out 
+
+<a name="v_410"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 2nd March 2004
+<br>Project org.eclipse.jdt.core v_410
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_410">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added following APIs to <code>org.eclipse.jdt.core.dom.CompilationUnit</code>:
+<ul>
+<li><code>getCommentList()</code>: Returns a list of the comments encountered while parsing the compilation unit.</li>
+<li><code>getExtendedStartPosition(ASTNode)</code>: Returns the extended start position of the given node.</li>
+<li><code>getExtendedLength(ASTNode)</code>: Returns the extended source length of the given node.</li>
+</ul>
+Unlike <code>ASTNode#getStartPosition()</code> and <code>ASTNode#getLength()</code>, the extended source range may include
+comments and whitespace immediately before or after the normal source range for the node.
+<br>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53445">53445</a> for more details on heuristic to find leading and trailing comments.
+</li>
+<li>Added API <code>FieldReferenceMatch.isReadAccess()</code> and <code>isWriteAccess()</code>.
+<li>Added API <code>JavaCore.run(IWorkspaceRunnable action, ISchedulingRule rule, IProgressMonitor monitor)</code> 
+	 to control the scheduling rule during a Java batch operation.
+</li>
+<li>Added API <code>SearchEngine.createJavaSearchScope(IJavaElement[], int)</code> that allows to filter the
+     classpath entries added in the scope: SOURCES, APPLICATION_LIBRARIES, SYSTEM_LIBRARIES and REQUIRED_PROJECTS.
+</li>
+<li> New command line options for batch compiler:
+  <ul>
+  <li> <code>-maxProblems &lt;n&gt;</code> :  max number of problems per compilation unit (100 by default) </li>
+  <li> <code>-noJSR</code> : do not use JSR bytecode </li>
+  </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53445">53445</a>
+[DCR] [DOM Comments] Provide extended ranges including leading/trailing comments for AST nodes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53276">53276</a>
+[DOM Comments] Wrong text element length when containing '\' character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52908">52908</a>
+[DOM Comments] Wrong text element positions when starting/ending with { or }
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48337">48337</a>
+[Search] FieldReferenceMatch should report read/write access 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52691">52691</a>
+Add batch compiler option for maxProblemsPerUnit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51045">51045</a>
+Offer to call JavaCore.run with scheduling rule 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52273">52273</a>
+Add option on predefined search scope to include/exclude system contain libraries 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49809">49809</a>
+NPE from MethodVerifier 
+
+<a name="v_409"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M8 Build - 24th February 2004
+<br>Project org.eclipse.jdt.core v_409
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_409">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new API to create a DOM AST while reconciling 
+	 <code>ICompilationUnit.reconcile(boolean, boolean, WorkingCopyOwner, IProgressMonitor)</code>.
+</li>
+<li>Removed compiler support for deprecating jsr bytecode in 1.5 compliant mode (turned off until future release).
+</li>
+<li>The constant DefaultCodeFormatterConstants.FORMATTER_PRESERVE_USER_LINEBREAKS will be removed. It has been deprecated for now and
+has no effect in the UI anymore.
+</li>
+<li>The constant DefaultCodeFormatterConstants.FORMATTER_FILLING_SPACE will be removed. It has been deprecated for now and
+has no effect in the UI anymore.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52916">52916</a>
+Strang error message when using jre1.5.0 libraries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50586">50586</a>
+[Code Formatter] trim trailing blanks/whitespace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52851">52851</a>
+Space before else should be removed in some cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52283">52283</a>
+do &lt;single-statement&gt; while(&lt;condition&gt;) is ill-formatted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52479">52479</a>
+Code Format fails on not on-demand imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52246">52246</a>
+M7 Source formatter fails silently when assert present in source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52429">52429</a>
+code formatter seems to ignore settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51623">51623</a>
+[formatter] Wrong formatting when "Preserve existing line breaks" switched on
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52305">52305</a>
+Code Formatter strips blank lines in methods and field definitions when I try to tell it not to
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52746">52746</a>
+Formatter - preserve line breaks conflicts with keep blank lines
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52804">52804</a>
+Deprecated formatter constant should indicate new way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52619">52619</a>
+NPE running Java model tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36889">36889</a>
+[DCR] Keep AST created in reconcile for active editor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52384">52384</a>
+OutOfMemoryError opening hierarchy on Object 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52355">52355</a>
+Not present exception trying to create a class in excluded package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49809">49809</a>
+NPE from MethodVerifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22104">22104</a>
+[infrastructure] NPE from IndexSummary.read(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31013">31013</a>
+ [infrastructure] npe in index crash recovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=31014">31014</a>
+[infrastructure] exception in indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51447">51447</a>
+[infrastructure] NPE running JDT Core tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52221">52221</a>
+[Compiler] should reject Local type usage when defined in other switch case block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52216">52216</a>
+[regression in M7] javadoc: @see &lt;a href&gt; shows a warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51990">51990</a>
+'parameter' vs 'argument' in compiler errors/settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52012">52012</a>
+Special 'serialPersistentFields' marked as 'never used locally'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51353">51353</a>
+The type AbstractStringBuilder is not visible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49259">49259</a>
+Task tags starting with TODO don't correctly display their priority in Tasks View
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49879">49879</a>
+java.lang.ClassCastException (SourceTypeBinding to a BinaryTypeBinding) in 30M6 within jdt.core.dom.TypeBinding.getKey(TypeBinding.java:411)
+
+<a name="v_408"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 12th February 2004 - 3.0 MILESTONE-7
+<br>Project org.eclipse.jdt.core v_408
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_408">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51603">51603</a>
+[preferences] Code formatter line wrapping preference inconsistent preview behaviour
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51476">51476</a>
+Javadoc: String or URL @see references are not stored in DOM AST Javadoc structure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51478">51478</a>
+Javadoc: @deprecated/@inheritDoc tags are not stored in DOM AST Javadoc structure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51508">51508</a>
+Javadoc: Package references DOM AST nodes binding is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51626">51626</a>
+Javadoc - DOM/AST is not correct after a @see tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51650">51650</a>
+Incorrected deprecation check
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51770">51770</a>
+Javadoc AST Node: wrong binding on qualified name part
+
+
+<a name="v_407"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 11th February 2004
+<br>Project org.eclipse.jdt.core v_407
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_407">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fixed most of the API Java doc comments. 
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51659">51659</a>
+New Code Formatter: minor problem with "White spaces/Array Initializers" option
+
+
+<a name="v_406"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 10th February 2004
+<br>Project org.eclipse.jdt.core v_406
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_406">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51035">51035</a>
+[Formatter] endline comment in case of simple if-then statement
+
+
+<a name="v_405"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 9th February 2004
+<br>Project org.eclipse.jdt.core v_405
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_405">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51363">51363</a>
+Wrong comment positions inside the Scanner.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51201">51201</a>
+Code formatter missing 'between empty brackets' option in Whitespace Array allocation configuration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50695">50695</a>
+Javadoc: package reference in @see tags is wrongly warned
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49994">49994</a>
+Strange matches with start=0, end=1 in type reference search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51300">51300</a>
+VerifyError when using a array reference assigned to null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51128">51128</a>
+[Code Formatter] Indent statements within blocks and methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51241">51241</a>
+IllegalArgumentException while creating a DOM/AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51249">51249</a>
+Performance problems in PackageFragment.getPath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50276">50276</a>
+Function call line wrapping fails on chained calls
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51190">51190</a>
+comment after else block goes to next line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51226">51226</a>
+Javadoc inside DOM AST does not support starting characters in unicode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51104">51104</a>
+Comments are not recorded when inside a method body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50858">50858</a>
+Javadoc IProblem constant not defined
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50898">50898</a>
+Javadoc AST: Missing binding for reference to non-visible type
+
+<a name="v_404"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 3rd February 2004
+<br>Project org.eclipse.jdt.core v_404
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_404">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50938">50938</a>
+Javadoc AST: Still invalid range for embedded tag
+
+<a name="v_403"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 3rd February 2004
+<br>Project org.eclipse.jdt.core v_403
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_403">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Updated porting guide to introduce search participant story (see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/porting_guide.html">porting guide</a>)</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51089">51089</a>
+Java AST creation failure 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50571">50571</a>
+search sender in hierarchy hangs 
+
+<a name="v_402"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 30th January 2004
+<br>Project org.eclipse.jdt.core v_402
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_402">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50883">50883</a>
+Javadoc AST node: Range problem with embedded tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50884">50884</a>
+Compiler crashes without a trace in the log leaving workspace in unhappy state
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50831">50831</a>
+DCR Javadoc AST: Offer well known tag names as constants 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50880">50880</a>
+JavadocAST Nodes: Wrong ranges on link
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50877">50877</a>
+Javadoc AST Nodes: Wrong ranges
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47396">47396</a>
+JAVA AST Creation failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50844">50844</a>
+AbortCompilation thrown from Name#resolveBinding() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50746">50746</a>
+Searching for variable references can cause an internal error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50838">50838</a>
+Javadoc bindings: No bindings in constructor ref parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50840">50840</a>
+Javadoc AST: wrong start position on MemberRef
+
+<a name="v_401"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 29th January 2004
+<br>Project org.eclipse.jdt.core v_401
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_401">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46126">46126</a>
+[DCR] IBinding should have a method to check @since javadoc tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50785">50785</a>
+Javadoc bindings: No bindings member refs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50784">50784</a>
+Javadoc bindings: No binding in {@link } and link disturbs other bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50781">50781</a>
+Javadoc bindings: No bindings for qualified names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50736">50736</a>
+Out of bounds exception while formatting
+
+<a name="v_400"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 28th January 2004
+<br>Project org.eclipse.jdt.core v_400
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_400">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50694">50694</a>
+Javadoc: Cannot find DOM AST bindings for types in @see tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50692">50692</a>
+Javadoc: Cannot find DOM AST bindings for inline link tags references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50719">50719</a>
+wrong formatting for java coding conventions
+
+<a name="v_399"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 27th January 2004
+<br>Project org.eclipse.jdt.core v_399
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_399">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Improve DOM/AST support for doc comments.
+<br>Following changes have been made to the DOM/AST API:
+<ul>
+<li>added Javadoc.tags() to represent structure of the doc comments</li>
+<li>deprecated Javadoc.get/setComment</li>
+<li>added 5 new node types that occur only within doc comments: TagElement, TextElement, MemberRef, MethodRef, MethodRefParameter</li>
+<li>tag elements like MemberRef, MethodRef, and Name can carry binding information (must be requested like elsewhere)</li>
+<li>added ASTVisitor(boolean) for controlling whether Javadoc.tags() are visited by default</li>
+<li>added ASTMatcher(boolean) for controlling whether Javadoc.tags() are compared vs. only Javadoc.getComment()</li>
+<li>AST.parse*(...) now returns structured doc comments (for compatibility, Javadoc.getComment() is also set as before)</li>
+</ul>
+See bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50683">50683</a>.
+</li>
+<li>
+Improve DOM/AST support for locating all comments.
+<br>Following changes have been made to the DOM/AST API:
+<ul>
+<li>added CompilationUnit.getCommentTable() to record locations of all comments found in the source</li>
+<li>added 2 new node types, LineComment and BlockComment, to represent end-of-line and traditional comments respectively</li>
+<li>these new nodes are placeholders for comments</li>
+<li>these new node types only occur in the comment table (since they can occur anywhere (lexically), there is no way to properly parent them in the regular AST nodes that reflects their position)</li>
+<li>AST.parse*(...) now returns sets the comment table on the compilation unit to include all comments (including attached and free-floating doc comments)</li>
+</ul>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50697">50697</a>.
+</li>
+<li> Added option to control whether diagnosis for unused thrown exceptions should be enabled when overriding another
+method. By default, it is disabled.
+<pre>
+* COMPILER / Reporting Unused Declared Thrown Exception in Overridind Method
+*    When disabled, the compiler will not include overriding methods in its diagnosis for unused declared
+*    thrown exceptions.
+*    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException".
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "disabled"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50644">50644</a>
+Deprecation check doesn't check that the @deprecated is at the beginning of the line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27134">27134</a>
+Add a ASTNode for non-Javadoc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50683">50683</a>
+Improve DOM/AST support for doc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50697">50697</a>
+Improve DOM/AST support for locating all comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50667">50667</a>
+Deadlock on Refactor -&gt; Extract method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47430">47430</a>
+the immutable bit is copied from the original resource to the ouput directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50601">50601</a>
+Blank lines before package declaration is one fewer than specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48292">48292</a>
+[DCR] Need AST.parsePartialClassFile(....)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50320">50320</a>
+Java model operations should use IResourceRuleFactory 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50207">50207</a>
+Compile errors fixed by 'refresh' do not reset problem list or package explorer error states 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49691">49691</a>
+JavaProject looses property listeners on preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50265">50265</a>
+Emulate old formatter with the new formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50225">50225</a>
+Calling the default formatter with an empty string returns an invalid Edit 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44876">44876</a>
+"Unnecessary declaration of thrown exception" problems
+
+
+<a name="v_398"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 20th January 2004
+<br>Project org.eclipse.jdt.core v_398
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_398">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Major renaming of constants in the code formatter. See <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49908">49908</a>.
+The old constants have been deprecated and will be removed before M7. So we encourage you to save your code formatter preferences if
+you modified the default settings. The UI will provide an automatic conversion to the new options.
+</li>
+<li>Added API for alignment options in the code formatter.  See <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49968">49968</a>.
+</li>
+<li>Changed 3.0 APIs on <code>org.eclipse.jdt.core.dom.AST</code> to take an <code>IProgressMonitor</code>. This progress monitor is checked for the cancelation of the AST creation only.
+</li>
+<li>Added API on <code>org.eclipse.jdt.core.dom.AST</code> to parse an expression or statements or class body declarations without requiring the parsing
+of the whole compilation unit. This is still subject to change before 3.0.
+<pre>
+	/**
+	 * Parses the given source between the bounds specified by the given offset (inclusive)
+	 * and the given length and creates and returns a corresponding abstract syntax tree.
+	 * 
+	 * The root node of the new AST depends on the given kind.
+	 * - <code>org.eclipse.jdt.core.dom.AST.K_CLASS_BODY_DECLARATIONS</code>: The root node is an instance of
+	 * <code>org.eclipse.jdt.core.dom.TypeDeclaration</code>. The type declaration itself doesn't contain any information.
+	 * It is simply used to return all class body declarations inside the bodyDeclaratins() collection.
+	 * - <code>org.eclipse.jdt.core.dom.AST.K_STATEMENTS</code>: The root node is an instance of
+	 * <code>org.eclipse.jdt.core.dom.Block</code>. The block itself doesn't contain any information.
+	 * It is simply used to return all the statements.
+	 * - <code>org.eclipse.jdt.core.dom.AST.K_EXPRESSION</code>: The root node is an instance of a subclass of
+	 * <code>org.eclipse.jdt.core.dom.Expression</code>.
+	 *  
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the given source (the given source itself
+	 * is not remembered with the AST). 
+	 * The source range usually begins at the first character of the first token 
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * 
+	 * This method does not compute binding information; all <code>resolveBinding</code>
+	 * methods applied to nodes of the resulting AST return <code>null</code>.
+	 * 
+	 * <code>null</code> is returned:
+	 * 1. If a syntax error is detected while parsing,
+	 * 2. If the given source doesn't correspond to the given kind.
+	 *  
+	 * @param kind the given kind to parse
+	 * @param source the string to be parsed
+	 * @param offset the given offset
+	 * @param length the given length
+	 * @param options the given options. If null, <code>JavaCore.getOptions()</code> is used.
+	 * @param monitor the progress monitor used to check if the AST creation needs to be canceled
+	 * 
+	 * @return ASTNode
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @see AST#K_CLASS_BODY_DECLARATIONS
+	 * @see AST#K_EXPRESSION
+	 * @see AST#K_STATEMENTS
+	 * @see JavaCore#getOptions()
+	 * @since 3.0
+	 */
+	public static ASTNode parse(int kind, char[] source, int offset, int length, Map options, IProgressMonitor monitor);
+</pre>
+</li>
+<li>Added API on <code>org.eclipse.jdt.core.dom.AST</code> to parse a compilation unit and specify
+the set of options to use. This is still subject to change before 3.0. The previous API was directly
+using <code>JavaCore.getOptions()</code>. This could be problematic in case you want to parse assert
+statements.
+<pre>
+	/**
+	 * Parses the given string as a Java compilation unit and creates and 
+	 * returns a corresponding abstract syntax tree.
+	 * 
+	 * The given options are used to find out the compiler options to use while parsing.
+	 * This could implies the settings for the assertion support. See the <code>JavaCore.getOptions()</code>
+	 * methods for further details.
+	 * 
+	 * 
+	 * The returned compilation unit node is the root node of a new AST.
+	 * Each node in the subtree carries source range(s) information relating back
+	 * to positions in the given source string (the given source string itself
+	 * is not remembered with the AST). 
+	 * The source range usually begins at the first character of the first token 
+	 * corresponding to the node; leading whitespace and comments are <b>not</b>
+	 * included. The source range usually extends through the last character of
+	 * the last token corresponding to the node; trailing whitespace and
+	 * comments are <b>not</b> included. There are a handful of exceptions
+	 * (including compilation units and the various body declarations); the
+	 * specification for these node type spells out the details.
+	 * Source ranges nest properly: the source range for a child is always
+	 * within the source range of its parent, and the source ranges of sibling
+	 * nodes never overlap.
+	 * If a syntax error is detected while parsing, the relevant node(s) of the
+	 * tree will be flagged as <code>MALFORMED</code>.
+	 * 
+	 * 
+	 * This method does not compute binding information; all <code>resolveBinding</code>
+	 * methods applied to nodes of the resulting AST return <code>null</code>.
+	 * 
+	 * 
+	 * @param source the string to be parsed as a Java compilation unit
+	 * @param options options to use while parsing the file. If null, <code>JavaCore.getOptions()</code> is used.
+	 * @param monitor the progress monitor used to check if the AST creation needs to be canceled
+	 * @return CompilationUnit
+	 * @see ASTNode#getFlags()
+	 * @see ASTNode#MALFORMED
+	 * @see ASTNode#getStartPosition()
+	 * @see ASTNode#getLength()
+	 * @see JavaCore#getOptions()
+	 * @since 3.0
+	 */
+	public static CompilationUnit parseCompilationUnit(char[] source, Map options, IProgressMonitor monitor);
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50258">50258</a>
+AST.parseCompilationUnit(... IWorkingCopyOwner..) should allow null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49937">49937</a>
+JavaDoc of ITypeBinding#isLocal() talks about local interfaces 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49845">49845</a>
+DCR: Allow to cancel the AST creation 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48489">48489</a>
+[DCR] AST support for a single expression (vs. CU)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49327">49327</a>
+formatter can return null TextEdit when parsing valid java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49908">49908</a>
+Renaming of DefaultCodeFormatterConstants.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49968">49968</a>
+[formatter] Alignment API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49953">49953</a>
+[Code Formatter] Cannot customize the spaces around brackets in array allocation expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=50025">50025</a>
+uppercase ZIP and JAR classpath entries ignored
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45060">45060</a>
+Missing external jar prevents build, but jar still in Java model 
+
+<a name="v_397"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M7 Build - 13th January 2004
+<br>Project org.eclipse.jdt.core v_397
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_397">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API to get the scheduling rule for a Java element:
+<pre>
+	/**
+	 * Returns the scheduling rule associated with this Java element.
+	 * This is a handle-only method.
+	 * 
+	 * @return the scheduling rule associated with this Java element
+	 * @since 3.0
+	 */
+	ISchedulingRule getSchedulingRule();
+</pre>
+</li>
+<li>Code formatter: If you did change the value of the setting controlling the insertion of a white space between empty arguments of a method declaration,
+then you have to change it again. Indeed, a spelling mistake has been fixed in the constant name. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49530">49530</a>.</li>
+<li>Inline tags are now supported in Javadoc comments:
+<ul><li>{@link} and {@linkplain} tags are now parsed using same rules as for @see tag. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48385">48385</a>.
+<br>Because references declared in these tags should be now found during search operation,  the index format had to be changed. Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).</li>
+<li>{@inheritDoc} tag is now parsed. When this tag is present in a method javadoc comment, all missing tags errors are ignored.
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45782">45782</a>.</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49843">49843</a>
+Not reporting error on constructor with no body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49491">49491</a>
+Add option to toggle warning for Javadoc multiple same name @throws tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49260">49260</a>
+Malformed Javadoc Compiler option sensitive to line breaks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45782">45782</a>
+[DCR] Compiler should take into account {@inheritDoc} tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48385">48385</a>
+[DCR] Need Javadoc warning for {@link }
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49760">49760</a>
+Splitting up FORMATTER_INSERT_SPACE_WITHIN_MESSAGE_SEND
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49763">49763</a>
+New formatter: Problem with empty statement in while
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48701">48701</a>
+NPE evaluating watch expression 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49290">49290</a>
+NullpointerException in TypeBinding.getInterfaces(). 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49660">49660</a>
+Code formatter line wrapping indentation ignores whitespace settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48293">48293</a>
+[DCR] IJavaElement should implement ISchedulingRule 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48459">48459</a>
+NPE in Type hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49653">49653</a>
+Unnecessary white space is added after last semicolon in for statement without increments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49351">49351</a>
+New code formatter: left curly brace placement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49530">49530</a>
+Spelling mistake in the FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARGUMENTS string constant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49298">49298</a>
+Code formatter does not correctly space closing bracket on method calls
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48395">48395</a>
+Hierarchy on region misses local classes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47743">47743</a>
+Open type hiearchy problems [type hierarchy] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49571">49571</a>
+White space options for method and constructor declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49577">49577</a>
+Add an option to specify the number of blank lines between two type declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49551">49551</a>
+formatter fails on empty statement between package and imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39943">39943</a>
+[navigation] outliner auto-changes selection (multi-fields) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49490">49490</a>
+New Code Formatter; Java Coding Conventions; Blank Lines; Before first declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49561">49561</a>
+Commit should only lock parent's folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47699">47699</a>
+Make org.eclipse.core.runtime.compatibility non optional 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41444">41444</a>
+[navigation] error dialog on opening class file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48350">48350</a>
+IType#resolveType(String) fails on local types 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49120">49120</a>
+search doesn't find references to anonymous inner methods 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49482">49482</a>
+New Code Formatter; if/else without curly braces; guardian clause (2)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49481">49481</a>
+New Code Formatter; if/else without curly braces; guardian clause (1)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49361">49361</a>
+FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARRAY_INITIALIZER
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49243">49243</a>
+New code formatter: missing feature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49429">49429</a>
+error during build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48404">48404</a>
+formatter: no edit returned
+
+<a name="v_396"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 18th December 2003 - 3.0 MILESTONE-6
+<br>Project org.eclipse.jdt.core v_396
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_396">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49081">49081</a>
+JDT is no more using the tab character by default for indentation 
+
+<a name="v_395"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 17th December 2003
+<br>Project org.eclipse.jdt.core v_395
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_395">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48706">48706</a>
+NPE in move refactoring 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48965">48965</a>
+Javadoc problem preference settings: Use 'include' instead of 'ignore'
+
+<a name="v_394"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 16th December 2003
+<br>Project org.eclipse.jdt.core v_394
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_394">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47209">47209</a>
+Javadoc: Type references are not found in @see tag inside a method reference
+
+<a name="v_393"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 16th December 2003
+<br>Project org.eclipse.jdt.core v_393
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_393">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48818">48818</a>
+NPE in delta processor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48711">48711</a>
+javadoc-warning if derived exception in @throws clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46040">46040</a>
+NPE in Eclipse console 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48725">48725</a>
+Cannot search for local vars in jars. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48749">48749</a>
+[Compiler] deprecation check in initializer fooled by trailing deprecated field decl
+
+
+<a name="v_392"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 15th December 2003
+<br>Project org.eclipse.jdt.core v_392
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_392">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added option to avoid reporting a warning when overriding a deprecated method. By default, such
+warnings are no longer reported.
+<pre>
+ * COMPILER / Reporting Deprecation When Overriding Deprecated Method
+ *    When enabled, the compiler will signal the declaration of a method overriding a deprecated one.
+ *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.deprecation".
+ *     - option id:        "org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "disabled"
+</pre>	 
+<li>Compiler options to signal problems with javadoc comments have been improved. User can now decide to report
+independently problems on invalid tags (syntax and references), missing tags and missing comments.
+Invalid references, missing tags or missing comments problem can be now ignored below a specific visibility level.
+Finally, user will also have the possibility to ignore missing tags and missing comments on overriding methods
+(assuming that complete Javadoc comments is done in superclass or interface declaration).
+<br>
+Here's the complete list of these options:
+<pre>
+	 * COMPILER / Reporting Invalid Javadoc Comment
+	 *    This is the generic control for the severity of Javadoc problems.
+	 *    When enabled, the compiler will issue an error or a warning for a problem in Javadoc.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadoc"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"
+	 *
+	 * COMPILER / Visibility Level For Invalid Javadoc Tags
+	 *    Set the minimum visibility level for Javadoc tag problems. Below this level problems will be ignored.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility"
+	 *     - possible values:   { "public", "protected", "default", "private" }
+	 *     - default:           "private"
+	 * 
+	 * COMPILER / Reporting Invalid Javadoc Tags
+	 *    When enabled, the compiler will signal unbound or unexpected reference tags in Javadoc.
+	 *    A 'throws' tag referencing an undeclared exception would be considered as unexpected.
+	 *    <br>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility".
+	 *    <br>
+	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.invalidJavadoc".
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadocTags"
+	 *     - possible values:   { "disabled", "enabled" }
+	 *     - default:           "enabled"
+	 * 
+	 * COMPILER / Reporting Missing Javadoc Tags
+	 *    This is the generic control for the severity of Javadoc missing tag problems.
+	 *    When enabled, the compiler will issue an error or a warning when tags are missing in Javadoc comments.
+	 *    <br>Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility".
+	 *    <br>
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocTags"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"
+	 * 
+	 * COMPILER / Visibility Level For Missing Javadoc Tags
+	 *    Set the minimum visibility level for Javadoc missing tag problems. Below this level problems will be ignored.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility"
+	 *     - possible values:   { "public", "protected", "default", "private" }
+	 *     - default:           "private"
+	 * 
+	 * COMPILER / Reporting Missing Javadoc Tags on Overriding Methods
+	 *    Specify whether the compiler will verify overriding methods in order to report Javadoc missing tag problems.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "enabled"
+	 * 
+	 * COMPILER / Reporting Missing Javadoc Comments
+	 *    This is the generic control for the severity of missing Javadoc comment problems.
+	 *    When enabled, the compiler will issue an error or a warning when Javadoc comments are missing.
+	 *    <br>Note that this diagnosis can be enabled based on the visibility of the construct associated with the expected Javadoc;
+	 *    also see the setting "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility".
+	 *    <br>
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocComments"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"
+	 * 
+	 * COMPILER / Visibility Level For Missing Javadoc Comments
+	 *    Set the minimum visibility level for missing Javadoc problems. Below this level problems will be ignored.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility"
+	 *     - possible values:   { "public", "protected", "default", "private" }
+	 *     - default:           "public"
+	 * 
+	 * COMPILER / Reporting Missing Javadoc Comments on Overriding Methods
+	 *    Specify whether the compiler will verify overriding methods in order to report missing Javadoc comment problems.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "enabled"
+	 * 
+</pre>
+Note that backward compatibility with previous options IDs: <code>"org.eclipse.jdt.core.compiler.problem.missingJavadoc"</code>
+will be supported until 3.0M7 build and removed after.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47214">47214</a>
+Cannot open declaration on a selected method of an anonymous class 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47795">47795</a>
+NPE selecting method in anonymous 2 level deep 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48335">48335</a>
+[Compiler] Need option to not report deprecation in override scenarii
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48523">48523</a>
+@throws reference incorrectly warned as not declared
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47940">47940</a>
+Unable to control level  of JavaDoc errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47319">47319</a>
+Compiler warns on missing Javadoc tags for private methods.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46976">46976</a>
+Do not warn about 'Missing Javadoc'  for overriding methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46854">46854</a>
+[DCR] Javadoc configuration setting needs more flexibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48617">48617</a>
+Error range for unresolved names in qualified references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48333">48333</a>
+[Compiler] Implicit deprecation isn't propagated to anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46084">46084</a>
+ArrayIndexOutOfBoundsException in compiler after feeding with non-real java code 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43354">43354</a>
+CodeAssist relevance should privilege package completion over type name 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48422">48422</a>
+Calling isStructureKnown() on ILocalVaraible throws JavaModelExceptions 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48261">48261</a>
+Search does not show results 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47213">47213</a>
+Inefficient recursion while initializing classpath container 
+
+<a name="v_391"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 10th December 2003
+<br>Project org.eclipse.jdt.core v_391
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_391">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>We reverted back the behavior when using the class literal. See bugs <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565">37565</a> and
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48086">48086</a>. As long as javac doesn't clarify this case, we keep
+the old behavior.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48086">48086</a>
+Compiler does not resolve references in static init blocks correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48353">48353</a>
+Indexes deleted on shutdown 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42579">42579</a>
+Eclipse allows setting a source folder's parent as output folder, which wipes out source code
+
+<a name="v_390"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 9th December 2003
+<br>Project org.eclipse.jdt.core v_390
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_390">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The classpath validation rules now allow an excluded directory to be used as an output location. 
+Remember that a source folder can be associated with exclusion rules so as to eliminate portions of the
+source tree. Nested source/library entries were already allowed given proper exclusion rules were specified,
+now we also enable nesting an output folder as well under the same restrictions.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47338">47338</a>
+CCE in CompletionParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45589">45589</a>
+Too many Util classes in JDTCore 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39539">39539</a>
+Cannot select excluded directory as output folder for class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48070">48070</a>
+[CodeAssist] ArrayIndexOutOfBoundsException in AssistParster
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48167">48167</a>
+Indentation/line wrapping problems with array initializers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32022">32022</a>
+Indirect static proposal: Wrong compiler positions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48141">48141</a>
+Formatter: Java Conventions/WS/Expressions/Operators 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45157">45157</a>
+Source Formatter: Clear all Blank lines needs to have the ability to set a number of lines to keep.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44673">44673</a>
+Formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38523">38523</a>
+so add "Insert new line after each parameter if line is too long" checkbox to Preferences &gt; Java &gt; Code Formatter &gt; New Lines
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34897">34897</a>
+Code Formatter feature request
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46937">46937</a>
+[Compiler] Marking a field deprecated still report deprecated usage
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47989">47989</a>
+Exception when searching for IPackageFragment "java.util.zip"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47997">47997</a>
+No empty line after opening brace [formatter]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48064">48064</a>
+Javadoc: NPE during build process
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44815">44815</a>
+Continuation indent for array initializer should be customizable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44813">44813</a>
+Option "Insert new line before an open brace" should work also for array initializers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43212">43212</a>
+catch variable not recognized by code-completion 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46060">46060</a>
+regression - content assist fails to present proposal 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47918">47918</a>
+New code Formatter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47968">47968</a>
+Cannot find @see references in Class javadoc comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47909">47909</a>
+Javadoc: NPE while searching a constructor references in jdt-core
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47986">47986</a>
+Formatting of 'for' initializers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47976">47976</a>
+Implementation of IField.getConstant() fails for some constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47886">47886</a>
+[Compiler] ACC_SUPER bit sets for interfaces
+
+<a name="v_389"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 2nd December 2003
+<br>Project org.eclipse.jdt.core v_389
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_389">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Spec and implementation for <code>ITypeBinding.getBinaryName()</code> was changed to be '.' separated:
+<pre>
+ /**
+ * Returns the binary name of this type binding.
+ * The binary name of a class is defined in the Java Language 
+ * Specification 2nd edition, section 13.1.
+ *
+ * Note that in some cases, the binary name may be unavailable.
+ * This may happen, for example, for a local type declared in 
+ * unreachable code.
+ *
+ * @return the binary name of this type, or null 
+ * if the binary name is unknown
+ * @since 3.0
+ */
+public String getBinaryName();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47881">47881</a>
+[Compiler] x &amp;&amp; false evaluates to "true"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47802">47802</a>
+New Code Formatter: NEXT_PER_LINE_SPLIT
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47811">47811</a>
+New Code Formatter: doesn't handle several classes per CU
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47801">47801</a>
+New Code Formatter: INSERT_SPACE_AFTER_PREFIX_OPERATOR
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47800">47800</a>
+New Code Formatter: BINARY_EXPRESSION_ALIGNMENT
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47799">47799</a>
+New Code Formatter: PUT_EMPTY_STATEMENT_ON_NEW_LINE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47776">47776</a>
+java.lang.VerifyError / Illegal target of jump or branch compiling with 3.0 M5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47341">47341</a>
+Javadoc problem for @see to protected method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47339">47339</a>
+Javadoc problem while using @see tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47132">47132</a>
+Javadoc for method in anonymous type should not be mark as missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47215">47215</a>
+Javadoc: type reference in @see tag ignore the following text
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46761">46761</a>
+Search for references: misses match in Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46675">46675</a>
+[Compiler] NullPointerException with ? operator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35220">35220</a>
+CodeAssist - method of anonymous type should not be proposed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47631">47631</a>
+PerThreadObject (JavaModelManager.deltaState) leaks Threads.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46470">46470</a>
+Wrong completion after a switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35232">35232</a>
+CodeAssist - wrong completion for static method in anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47401">47401</a>
+Wrong code assist proposals in anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47443">47443</a>
+All projects touched on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44493">44493</a>
+Improve formatting of throws clauses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44765">44765</a>
+New formatter not properly formatting long method invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44653">44653</a>
+// $NON-NLS-1$ comments not kept on same line of the string while formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46699">46699</a>
+IBinding.isSynthetic() returns false for compiler-generated constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47415">47415</a>
+[Search] package references confused with multiple fragments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38679">38679</a>
+Search for class ref shows local class containing a match on an import [search]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47049">47049</a>
+[Builder] Build output folder not getting flushed because files are not marked as derived
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46613">46613</a>
+AST nodes and string buffers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47396">47396</a>
+JAVA AST Creation failure
+
+<a name="v_388"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M6 Build - 25th November 2003
+<br>Project org.eclipse.jdt.core v_388
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_388">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47082">47082</a>
+[Compiler] Problem with final variable initialization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47180">47180</a>
+Merge different type declarations into one class
+
+
+<a name="v_387"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 21st November 2003 - 3.0 MILESTONE-5
+<br>Project org.eclipse.jdt.core v_387
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_387">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44397">44397</a>
+Search doesn't find references to local types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46571">46571</a>
+Searching for all occurrences for method declarated in local types doesn't wor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46943">46943</a>
+refactoring: encapsulate field of local type: references from enclosing type are not replaced by setter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47180">47180</a>
+NPE in Delta Processor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46788">46788</a>
+Export scripts: shouldn't use variable name version
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47160">47160</a>
+ArrayIndexOutOfBoundsException from CodeSnippetParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47177">47177</a>
+ClassCastException during hover
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47079">47079</a>
+[Builder] suspicious side-effects during incremental compile
+
+<a name="v_386"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 20th November 2003
+<br>Project org.eclipse.jdt.core v_386
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_386">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed APIs that create an <code>ICompilationUnit</code> handle given a <code>WorkingCopyOwner</code>
+	 as these can be replaced with <code>ICompilationUnit.findWorkingCopy(WorkingCopyOwner)</code>:
+	 <ul>
+	 <li><code>IPackageFragment.getCompilationUnit(String, WorkingCopyOwner)</code></li>
+	 <li><code>JavaCore.create(IFile, WorkingCopyOwner)</code></li>
+	 <li><code>JavaCore.create(IResource, WorkingCopyOwner)</code></li>
+	 <li><code>JavaCore.createCompilationUnitFrom(IFile, WorkingCopyOwner)</code></li>
+	 <li><code>IDOMCompilationUnit.getCompilationUnit(IPackageFragment, WorkingCopyOwner)</code></li>
+	 </ul>
+	 <br>
+</li>
+<li>Added API on <code>ICompilationUnit</code> to find an existing working copy given a working
+	 copy owner (it replaces <code>IWorkingCopy.findSharedWorkingCopy(IBufferFactory)</code>):
+<pre>
+/**
+ * Finds the working copy for this compilation unit, given a <code>WorkingCopyOwner</code>. 
+ * If no working copy has been created for this compilation unit associated with this
+ * working copy owner, returns <code>null</code>.
+ *
+ * Users of this method must not destroy the resulting working copy. 
+ * 
+ * @param owner the given <code>WorkingCopyOwner</code>
+ * @return the found working copy for this compilation unit, <code>null</code> if none
+ * @see WorkingCopyOwner
+ * @since 3.0
+ */
+ICompilationUnit findWorkingCopy(WorkingCopyOwner owner);
+</pre>
+</li>
+<li>Added API on <code>IClassFile</code> to create a working copy on a class file (it replaces 
+	 <code>IClassFile.getWorkingCopy(IProgressMonitor, IBufferFactory)</code>):
+<pre>
+/**
+ * Returns a working copy on the source associated with this class file using the given 
+ * owner to create the buffer, or <code>null</code> if there is no source associated
+ * with the class file.
+ * 
+ * The buffer will be automatically initialized with the source of the class file
+ * upon creation.
+ * 
+ * The only valid operations on this working copy are <code>getBuffer()</code> or <code>getPrimary()</code>.
+ *
+ * @param owner the owner that creates a buffer that is used to get the content of the working copy
+ *                 or <code>null</code> if the primary owner should be used
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ *                 or <code>null</code> if no progress should be reported 
+ * @return a  a working copy on the source associated with this class file
+ * @exception JavaModelException if the source of this class file can
+ *   not be determined. Reasons include:
+ *   - This class file does not exist (ELEMENT_DOES_NOT_EXIST)
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException;
+</pre>
+</li>
+<li>Added API on <code>ITypeBinding</code> to get the binary name of a type binding:
+<pre>
+/**
+ * Returns the binary name (as defined in the Java Language 
+ * Specification Chapter 13 Section 1) of this type binding.
+ * It is however slash ('/') separated instead of dot ('.') separated as said
+ * in the specification.
+ * Returns <code>null</code> if the type is defined in code that is unreachable.
+ *
+ * @return the binary name of this type or <code>null</code> if this type is unreachable
+ */
+String getBinaryName();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46012">46012</a>
+IllegalArgumentException in StringLiteral
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46769">46769</a>
+NPE in PatternLocator.qualifiedSourceName
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47074">47074</a>
+inability to detect invalid cast between interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46057">46057</a>
+need mechanism for retrieving the name of anonymous and local classes 
+
+<a name="v_385"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 19th November 2003
+<br>Project org.eclipse.jdt.core v_385
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_385">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46964">46964</a>
+Can not set Javadoc compiler setting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46901">46901</a>
+Strange compile error in javadoc
+
+<a name="v_384"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 19th November 2003
+<br>Project org.eclipse.jdt.core v_384
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_384">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API on <code>ICompilationUnit</code> to query whether the working copy's resource has changed 
+	 (it replaces <code>IWorkingCopy.isBasedOn(IResource)</code>):
+<pre>
+/**
+ * Returns whether the resource of this working copy has changed since the
+ * inception of this working copy.
+ * Returns <code>false</code> if this compilation unit is not in working copy mode.
+ * 
+ * @return whether the resource has changed
+ * @since 3.0
+ */
+public boolean hasResourceChanged();
+</pre>
+</li>
+<li>Added APIs on <code>IType</code> to create hierarchies using <code>ICompilationUnits</code> instead of
+     <code>IWorkingCopies</code>:
+<pre>
+/**
+ * Creates and returns a type hierarchy for this type containing
+ * this type and all of its supertypes, considering types in the given 
+ * working copies. In other words, the list of working copies will take 
+ * precedence over their original compilation units in the workspace.
+ *
+ * Note that passing an empty working copy will be as if the original compilation
+ * unit had been deleted.
+ *
+ * @param workingCopies the working copies that take precedence over their original compilation units
+ * @param monitor the given progress monitor
+ * @return a type hierarchy for this type containing this type and all of its supertypes
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @since 3.0
+ */
+ITypeHierarchy newSupertypeHierarchy(ICompilationUnit[] workingCopies, IProgressMonitor monitor) throws JavaModelException;
+
+/**
+ * Creates and returns a type hierarchy for this type containing
+ * this type, all of its supertypes, and all its subtypes in the workspace, 
+ * considering types in the given working copies. In other words, the list of working 
+ * copies that will take precedence over their original compilation units in the workspace.
+ * 
+ * Note that passing an empty working copy will be as if the original compilation
+ * unit had been deleted.
+ *
+ * @param workingCopies the working copies that take precedence over their original compilation units
+ * @param monitor the given progress monitor
+ * @return a type hierarchy for this type containing
+ * this type, all of its supertypes, and all its subtypes in the workspace
+ * @exception JavaModelException if this element does not exist or if an
+ *		exception occurs while accessing its corresponding resource.
+ * @since 3.0
+ */
+ITypeHierarchy newTypeHierarchy(ICompilationUnit[] workingCopies, IProgressMonitor monitor) throws JavaModelException;
+</pre>
+<li>Added API on <code>SearchEngine</code> to create a search engine using 
+	 <code>ICompilationUnits</code> instead of <code>IWorkingCopies</code>:
+<pre>
+/**
+ * Creates a new search engine with a list of working copies that will take precedence over 
+ * their original compilation units in the subsequent search operations.
+ *
+ * Note that passing an empty working copy will be as if the original compilation
+ * unit had been deleted.
+ *
+ * Since 3.0 the given working copies take precedence over primary working copies (if any).
+ * 
+ * @param workingCopies the working copies that take precedence over their original compilation units
+ * @since 3.0
+ */
+public SearchEngine(ICompilationUnit[] workingCopies) {...}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_383"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 18th November 2003
+<br>Project org.eclipse.jdt.core v_383
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_383">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>To avoid confusion with annotations introduced in JDK 1.5 grammar, all internal references to "annotation" (added to handle Javadoc comments) 
+got renamed into "Javadoc". As a consequence of this is that IDs for optional Javadoc problems have been updated accordingly:
+<pre>
+	 * COMPILER / Reporting Invalid Javadoc Comment
+	 *    When enabled, the compiler will issue an error or a warning when a javadoc comment is inconsistent,
+	 *    misses a tag entry or contains invalid references.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadoc"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"
+	 * COMPILER / Reporting Missing Javadoc Comment
+	 *    When enabled, the compiler will signal cases where public class, interface, method, constructor or field
+	 *    (considered as part of the API) has no javadoc comment.
+	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.invalidJavadoc".
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingJavadoc"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "disabled"
+</pre>
+Note that backward compatibility with previous options IDs: <code>"org.eclipse.jdt.core.compiler.problem.invalidAnnotation"</code> and <code>"org.eclipse.jdt.core.compiler.problem.missingAnnotation"</code>
+will be supported until 3.0M6 build and removed after.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46717">46717</a>
+The code formatter does not insert a new line before /** Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45958">45958</a>
+Compiler wrongly complains against valid @see constructor reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45112">45112</a>
+Use Javadoc instead of Annotation for comment compiler parsing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46052">46052</a>
+result of ITypeHierarchy.getAllSuperTypes() does not include Object 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46192">46192</a>
+ILocalVariable.exists() always returns false 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14103">14103</a>
+[Builder] Too many dependents found when incrementally recompiling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39601">39601</a>
+[DOM/AST] clarify documentation of source ranges
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39739">39739</a>
+[DOM/AST] VariableDeclarationStatements aren't full statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46690">46690</a>
+Code formatter always inserts space after comma in multiple locals or field declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46689">46689</a>
+Code formatter always inserts a space in front of the '-' unary operator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46686">46686</a>
+Code formatter doesn't indent properly statements following a switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46356">46356</a>
+[Builder] simple/qualified names list for indicting dependents should be hashed collections
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46612">46612</a>
+[DOM/AST] BodyDeclaration should provide a method getModifiers
+
+<a name="v_382"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 10th November 2003
+<br>Project org.eclipse.jdt.core v_382
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_382">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46276">46276</a>
+Search for package declarations incorrectly finds matches in clone project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46099">46099</a>
+Batch compiler doesn't print stats if errors and not proceeding on errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40950">40950</a>
+[infrastructure] NPE from indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46150">46150</a>
+formatter failed to format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46013">46013</a>
+IBinding.getKey() for local shouldn't return null 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46033">46033</a>
+New formatter not formatting nested constructor/methods properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=46093">46093</a>
+[Builder] Unoptimal pre-check for not writing class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45847">45847</a>
+[Builder] Reading build state is slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45982">45982</a>
+Array out of bounds error while editing Java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41611">41611</a>
+CreateCompilationUnitOperation.executeOperation() should probably force creation more agressively 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45113">45113</a>
+No hierarchy refresh when on region 
+
+
+<a name="v_381"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 4th November 2003
+<br>Project org.eclipse.jdt.core v_381
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_381">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45968">45968</a>
+[new formatter] Formatter introduces empty lines inside line comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44450">44450</a>
+Strange name range for anonymous classes. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43139">43139</a>
+Delete member in Outliner not working 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45944">45944</a>
+Stack trace attempting to find markers on a closed project 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44884">44884</a>
+Wrong list displayed while code completion 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45661">45661</a>
+Search for references of default package fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45671">45671</a>
+Need source range and getTypeSignature() for local variables 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45575">45575</a>
+Failure in nightly build of formatter tests (test325)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45783">45783</a>
+NPE in MatchLocator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22073">22073</a>
+Each "format" adds one more level of indentation.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23709">23709</a>
+for (/*comment*/; causes indentation to misbehave 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27249">27249</a>
+incorrect formatting of empty array initialization blocks 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29473">29473</a>
+wrong formatting of if...try... catch... else 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45786">45786</a>
+No selection on method declaration in field initializer 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45721">45721</a>
+Getting wrong deltas 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45674">45674</a>
+Compiler should allow compound assignment to final in unreachable code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43984">43984</a>
+NPE in background search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45707">45707</a>
+Autobuild does not kick in when using classpath containers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45655">45655</a>
+exception while editing java file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42287">42287</a>
+Should consider qualified name token positions
+
+<a name="v_380"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 28th October 2003
+<br>Project org.eclipse.jdt.core v_380
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_380">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Search is now able to find local variable references and declarations. In order to trigger such a search, the search engine must
+	be fed with an <code>ILocalVariable</code> element. Searching a local variable by its name is not supported.
+</li>
+<li>Search is now finding references in Javadoc comments. Found references are method parameters declared in <code>@param</code> tags, 
+	types of exceptions declared in <code>@throws</code>/<code>@exception</code> tags and all instance variables, methods, types or 
+	packages declared in <code>@see</code> tags.
+	<br>Note that only valid references in Javadoc comments will be reported during search. In order to ensure the integrity of your Javadoc comments,
+	you may want to enable the compiler check for Javadoc (Preferences&gt;Java&gt;Compiler&gt;Style&gt;Problem in Javadoc tags).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45641">45641</a>
+CCE when using declarations view 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45596">45596</a>
+Wrongly complains about missing parameter javadoc entry in anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45592">45592</a>
+NPE while searching a method references in jdt-core
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45520">45520</a>
+Potential NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45518">45518</a>
+Search has to find references put in javadoc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45436">45436</a>
+Javadoc warnings: wrong errors in AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45198">45198</a>
+NPE from AnnotationParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45459">45459</a>
+JDT compiler more restrictive than javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35899">35899</a>
+"hierarchy of type ... inconsistent" error message wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43967">43967</a>
+Search for references on local variable finds all occurances of variables of that type not just that variable. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37509">37509</a>
+Open Declaration opens class declaration for local variables 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45433">45433</a>
+Bug7 (and counting ;-): hundretAssignmentsToFinalVariable()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45357">45357</a>
+Compiler-Bug: "The local variable oResult may not have been initialized".txt
+
+<a name="v_379"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 21st October 2003
+<br>Project org.eclipse.jdt.core v_379
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_379">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Compiler options for controlling the severity of problems for invalid imports or unreachable code got discontinued. Indeed, allowing this kind of problems to be ignored
+or treated as a warning would violate the language spec. As a consequence, <code>JavaCore#COMPILER_PB_INVALID_IMPORT</code> and
+<code>JavaCore#COMPILER_PB_UNREACHABLE_CODE</code> got deprecated, 
+further attempts to set these preferences are now ignored and import problems or unreachable code are always reported as errors.
+<li> The warning level of the batch compiler can now be configured more easily using <code>-warn:+...</code> or <code>-warn:-...</code> command line
+argument (as opposed to only existing <code>-warn:...</code> command line argument). 
+<code>-warn:+...</code> will not override the default warning level, but simply enable
+a few more specific warnings. Similarily, <code>-warn:-...</code> will only disable specific warnings.
+<br>Note, by default the batch compiler is reporting the following warnings:
+	<ul>
+	<li>'assert' used as identifier</li>
+	<li>char[] in String concat</li>
+	<li>method with constructor name</li>
+	<li>deprecation outside deprecated code</li>
+	<li>finally block not completing normally</li>
+	<li>interface non-inherited method compatibility</li>
+	<li>hidden catch block</li>
+	<li>assignment without effect</li>
+	<li>attempt to override package-default method</li>
+	<li>unused import declaration</li>
+	<li>non-static reference to static member</li>
+	</ul>
+</li>
+<li>Code select (i.e. <code>ICodeAssit.codeSelect(...)</code>) now returns an <code>ILocalVariable</code>
+     element when a local variable or an argument is selected. 
+     <br>Note that <code>ILocalVariable</code>s are pseudo-elements:
+     they are not part of the Java model (<code>exists()</code> always returns <code>false</code>), 
+     they are not returned when asking for the children of a method, and there is no other way to create such
+     an element. One can only ask for the source range (<code>ISourceReference.getSourceRange()</code>) or
+     for the name range (<code>ILocalVariable.getNameRange()</code>) of the local variable.
+     <br>Searching a local variable is not yet implemented, but it is on the plan.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35389">35389</a>
+Compiler settings can violate JLS [build path]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44869">44869</a>
+Search: no refs found to overridden method in binary subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45110">45110</a>
+No constant for '..compiler.problem.missingAnnotation'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45100">45100</a>
+[formatter] test144 fails
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45036">45036</a>
+[formatter] New formatter fails formatting multiple field declarations using K_CLASSBODY_DECLARATION kind
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45037">45037</a>
+[formatter] New formatter doesn't insert a new line before the while in a do/while
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=45014">45014</a>
+Formatter misplaces semicolon
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44757">44757</a>
+New code formatter does not format switch statements correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44647">44647</a>
+NPE code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43754">43754</a>
+How to position this comment?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44839">44839</a>
+New formater fails with out of memory error
+
+<a name="v_378"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M5 Build - 15th October 2003
+<br>Project org.eclipse.jdt.core v_378
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_378">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Removed dependency on Xerces.
+</li>
+<li> Remove deprecated previously added API <code>IJavaProject#forceClasspathReload(IProgressMonitor)</code>
+(see comment of <a href="#v_368">v_368</a> drop below).
+</li>
+<li>Added optional compiler problem to signal problems with javadoc annotation.
+<pre>
+	 * COMPILER / Reporting Invalid Javadoc Annotation
+	 *    When enabled, the compiler will issue an error or a warning when a javadoc annotation is inconsistent,
+	 *    misses a tag entry or contains invalid references.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"
+	 * COMPILER / Reporting Missing Javadoc Annotation
+	 *    When enabled, the compiler will signal cases where public class, interface, method, constructor or field
+	 *    (considered as part of the API) has no javadoc annotation.
+	 *    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.invalidAnnotation".
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.missingAnnotation"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "disabled"
+	 * 
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44715">44715</a>
+NullPointerException compiling Java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44697">44697</a>
+Bug when i search reference of 'String' in 3.0M4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38091">38091</a>
+DCR - Generate warnings for JavaDoc missing entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44637">44637</a>
+NPE in Initializer.getPrimaryElement() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42762">42762</a>
+Compiler tests should run both in 1.3 and 1.4 mode 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44580">44580</a>
+No outline when unit name is not valid
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44651">44651</a>
+Wrong formatting of multiple local variables declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44643">44643</a>
+Remove dependancy to xerces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44662">44662</a>
+Should not validate unit/classfile handles upon creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44400">44400</a>
+Unnecessary cast not being picked up
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44143">44143</a>
+[JSR202] Remove usage of jsr bytecodes in 1.5 mode
+
+<a name="v_377"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 9th October 2003 - 3.0 MILESTONE-4
+<br>Project org.eclipse.jdt.core v_377
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_377">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44576">44576</a>
+Code formatter option "Insert a new line before an opening brace" has no effect for single else
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44570">44570</a>
+Code formatter option "Insert a new line inside an empty block" has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44503">44503</a>
+Unoptimal formatting for long constructor argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44546">44546</a>
+New formatter unable to format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44506">44506</a>
+Type hierarchy is missing anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44481">44481</a>
+"Insert new line between else and if" is not working as expected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44480">44480</a>
+Formatting the formatted string should not produce edits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44444">44444</a>
+jdt.core in trouble when project has no JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44437">44437</a>
+Typo in plugin.properties
+
+<a name="v_376"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 8th October 2003
+<br>Project org.eclipse.jdt.core v_376
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_376">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44289">44289</a>
+     requires the index format to be changed. Indexes will be automatically regenerated upon
+     subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44308">44308</a>
+NullPointerException when searching jars
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44341">44341</a>
+NPE from  delta processor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44119">44119</a>
+NPE while searching for references to Action#run() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44331">44331</a>
+Need indication that removal/add was targeted to a primary working copy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32639">32639</a>
+Missing empty fine-grain delta when reconciling 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44292">44292</a>
+IDOMType.setFlags(Flag.AccPublic) when applied to an interface having default visibility produces uncompilable code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44293">44293</a>
+DOMFactory.createInitializer() always creates a static intializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44289">44289</a>
+Search broken 
+
+<a name="v_374"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 7th October 2003
+<br>Project org.eclipse.jdt.core v_374
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_374">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The new code formatter can be activated in the ui. See the work in progress section. This first release doesn't expose
+yet all the preferences of the new code formatter. This will be done after M4. However the old formatter options should be honored by 
+the new code formatter. This is a work in progress and all problems should be reported against JDT/Core.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44242">44242</a>
+Deadlock during jdt/debug test 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44066">44066</a>
+Package Explorer doesn't show new file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44219">44219</a>
+NPE while creating TypeHierarchy for binary type "Group" 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44073">44073</a>
+Override methods action does not work for local types [code manipulation] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16231">16231</a>
+formatter creates ugly array initializer expressions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6284">6284</a>
+Java formatter enhancements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6268">6268</a>
+Code formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44036">44036</a>
+Java code formatter wraps line too much.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43651">43651</a>
+Linewrapping of throws declarations (if many)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43545">43545</a>
+Code Formatter: Don't separate long "import" clause.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43272">43272</a>
+feature request : extend the code formatter to support blanks between method / class name and bracket.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43050">43050</a>
+Formatting long arguments not very readable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40777">40777</a>
+Incorrect formatting for anonymous inner class with comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39607">39607</a>
+Incorrect formatting of anonymous inner class inside if statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39603">39603</a>
+for-Statement not correctly formatted by Codeformatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39357">39357</a>
+Better code formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38151">38151</a>
+Code formatter adds an unwanted blank line after an abstract method with a "throws" clause.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37106">37106</a>
+Code Formatter: Option to double indent wrapped lines in if statments, etc.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37057">37057</a>
+Code Formatter: Reduce number of blank lines to 1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36832">36832</a>
+wrong indent on Code Format of anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36455">36455</a>
+[Formatting] Too long lines look ugly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36108">36108</a>
+Code Formatter Clear Blank Lines Doesn't Work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35799">35799</a>
+code formatter: missing space after last array initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35433">35433</a>
+Simple Feature Request - Code Formatter Enhancement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35173">35173</a>
+Code formatter incorrectly formats this case:
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29110">29110</a>
+RFE: Disable line splitting in the code formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28098">28098</a>
+Code Formatter doesn't format JavaDoc indentation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=27196">27196</a>
+Code Formatter Won't Indent Braces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25559">25559</a>
+more code formatter options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=24200">24200</a>
+"Space inside parens &amp; brackets" option in Code Formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23144">23144</a>
+formatter issues
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22528">22528</a>
+Code formatter incorrectly indents lines
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22313">22313</a>
+Formatter doesn't like some comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21943">21943</a>
+Formatter should allow removing space after for/while/if
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20721">20721</a>
+Code formatter bug
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19999">19999</a>
+Code Formatter always clears blank lines to 1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19811">19811</a>
+Code formatter bugs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=17349">17349</a>
+Code Formatter incorrectly formats static initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=16233">16233</a>
+formatter problem with constructor, array and line-end comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=15286">15286</a>
+Code formatter: long param lists and line wrapping
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=14659">14659</a>
+Align method arguments on line break
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12456">12456</a>
+Add formatter options for controlling spaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12321">12321</a>
+Code formatter and comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=10052">10052</a>
+CodeFormatter - line splitting enhancement.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7439">7439</a>
+incorrect formatting: empty inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=7224">7224</a>
+Formatting splits package names in ugly ways
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6747">6747</a>
+Code Formatter exchange several blank lines w/ one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=5824">5824</a>
+Code Formatter needs to be more customizable to be useful
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3327">3327</a>
+Formatter - should ensure one empty line before a method declaration (1GHOJWD)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3276">3276</a>
+DCR: (LOW) Formatter option to not indent methods (1GE39ZO)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3181">3181</a>
+Does not format nicely anonymous type (1FRLTO1)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44085">44085</a>
+becomeWorkingCopy() should add the working copy in the model 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44052">44052</a>
+Deadlock on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44092">44092</a>
+Methods to generate parser files are not correct 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44084">44084</a>
+No refresh when deleting edited unit 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41643">41643</a>
+Code assist doesn't propose all valid types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44065">44065</a>
+NPE during hot code replace 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43897">43897</a>
+No completion in cast expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44061">44061</a>
+CodeAssist - no completion after class literal access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44018">44018</a>
+Change superfluous semicolon error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43872">43872</a>
+Hierarchy does not update properly when local class eliminated [type hierarchy] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43294">43294</a>
+Primary working copy: No updates when changed in working copy mode 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43907">43907</a>
+Too many warnings reported by the jdt compiler adapter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43847">43847</a>
+IPackageFragment not updated after CUs have moved 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43879">43879</a>
+working copy commit outside classpath doesn't save buffer
+
+<a name="v_373"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 30th September 2003
+<br>Project org.eclipse.jdt.core v_373
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_373">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43728">43728</a>
+Optimize CompilerOptions(Map....)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43842">43842</a>
+JDTCompilerAdapter doesn't find bootclasspath 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40782">40782</a>
+Primary working copies: unnecessary deltas on save 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43300">43300</a>
+SearchEngine(IWorkingCopy[] workingCopies) not backward compatible 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43670">43670</a>
+No classpath refresh when replacing binary project with source form
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43600">43600</a>
+NPE from JDTCompilerAdapter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43636">43636</a>
+Compiler complain that class cannot be resolved when it should be only not visible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43208">43208</a>
+ICompilation.move not supported when in workingCopyMode 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40793">40793</a>
+Primary working copies: Type search does not find type in modified CU 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43587">43587</a>
+Searching for references to default constructors reports questionable results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36143">36143</a>
+Type hierarchy doesn't include anonymous subclasses 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=8613">8613</a>
+Outline should show anonymous inner classes 
+
+
+<a name="v_372"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 24th September 2003
+<br>Project org.eclipse.jdt.core v_372
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_372">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42692">42692</a>
+JavaCC files cause VerifyError when compiled with Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43437">43437</a>
+Scanner does not like string literals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43485">43485</a>
+NPE in SearchEngine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37659">37659</a>
+[plan item] Improve shared working copies 
+
+
+<a name="v_371"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 22nd September 2003
+<br>Project org.eclipse.jdt.core v_371
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_371">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> As a consequence of migrating to background autobuild, the JavaModel will no longer broadcast deltas
+during PRE_AUTO_BUILD event notification. These were somewhat inconsistent in so far as the model wasn't
+totally up to date anyway. Now the model will only fire deltas during POST_CHANGE, or working copy reconcile
+operations.
+</li>
+<li>Part of the new support for local and anonymous types in the Java model has been released. 
+	<p>
+	This includes:
+	<ul>
+	<li>local and anonymous types are shown in the Outline view and the Package Explorer view</li>
+	<li>Java element deltas for these types are notified</li>
+	<li>handles on these types can be created (see <code>IMember.getType(String, int)</code>)</li>
+	<li><code>getChildren()</code> on a method, a field or an initializer returns the local or anonymous types defined in this element</li>
+	<li>mementos for these handles are supported</li>
+	<li>open on selection (F3) in a Java editor goes to the local type definition</li>
+	<li>type hierarchies contain anonymous and local types</li>
+	</ul>
+	<p>
+	This doesn't yet include:
+	<ul>
+	<li>search on these types</li>
+	<li>anonymous/local binary types</li>
+	</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42832">42832</a>
+Cannot get rid of this error even if the compiler settings is ignore for incompatible required binaries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41583">41583</a>
+[misc] Eclipse cannot save or compile files in non-Java project anymore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43274">43274</a>
+Type hierarchy broken 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38931">38931</a>
+Migrate delta processor to comply to new notification scheme in 3.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42281">42281</a>
+"Resource *.java does not exist"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38931">38931</a>
+org.eclipse.jdt.internal.corext.dom.NodeFinder needed in API 
+
+
+<a name="v_370"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 16th September 2003
+<br>Project org.eclipse.jdt.core v_370 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_370">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43026">43026</a>
+Running jdt/core tests on Linux is failing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43045">43045</a>
+Copy/move of package fragments with read-only subpackages fails on Linux
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43116">43116</a>
+NPE copy and pasting a method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43089">43089</a>
+Search engine doesn't report all matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43080">43080</a>
+NPE when searching in CU with incomplete method declaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42856">42856</a>
+CodeAssist - Does not work after an inner type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42839">42839</a>
+Incorrect position in org.eclipse.jdt.core.dom.ArrayType
+
+<a name="v_369"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 9th September 2003
+<br>Project org.eclipse.jdt.core v_369 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_369">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Default compiler compliance setting got raised to 1.4 level. Default source level is 1.3, and default target level is 1.2.
+To ease the 1.4 migration, the default severity for optional problem 'assert used as identifier' got raised to warning.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42760">42760</a>
+NullPointerException in JobManager when searching 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42629">42629</a>
+javac error message with missing classpath entry when claims entry dropped from path 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42614">42614</a>
+1.3 compliant mode should select default enclosing instance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42588">42588</a>
+Incorrect selection of current enclosing instance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35567">35567</a>
+Classpath validation error messages should contain project name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42443">42443</a>
+Error when inner class name has the same name than another class, but with not the same case sensitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42459">42459</a>
+DebugEvaluationTests don't run if target is 1.2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39887">39887</a>
+Resource exception while indexing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42366">42366</a>
+Classpath validation error message removed while rebuilding a project.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41680">41680</a>
+Unnecessary cast  wrongly reported
+
+<a name="v_368"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M4 Build - 1st September 2003
+<br>Project org.eclipse.jdt.core v_368 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_368">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added optional compiler problem to signal unqualified access to a non-static field. In order to improve
+code readability, qualifying field accesses is a simple way to syntactically distinguish a field access from 
+a local variable access, and thus avoid resorting to a special naming convention for fields (such as "fField").
+<pre>
+* COMPILER / Reporting Unqualified Access to Field
+*    When enabled, the compiler will issue an error or a warning when a field is access without any qualification.
+*    In order to improve code readability, it should be qualified, e.g. 'x' should rather be written 'this.x'.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li>Added optional compiler problem to signal method/constructor declared thrown checked exception which
+aren't actually raised inside the method/constructor body.
+<pre>
+* COMPILER / Reporting Unused Declared Thrown Exception
+*    When enabled, the compiler will issue an error or a warning when a method or a constructor is declaring a
+*    thrown checked exception, but never actually raises it in its body.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li>Added optional compiler problem to flag situations where a finally block does not complete normally.
+<pre>
+* COMPILER / Reporting Finally Blocks Not Completing Normally
+*    When enabled, the compiler will issue an error or a warning when a finally block does not complete normally.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Improved problem description for unreachable catch block problems. Message will now mention the exception type 
+name and better diagnose the cause of the problem. Also changed problem source range 
+to rather highlight the caught exception type instead of entire catch block. 
+<pre></pre>
+</li>
+<li>Added two new API methods <code>readRawClasspath()</code> and <code>readOutputLocation()</code> on <code>IJavaProject</code>
+interface so as to allow user to read classpath directly from disk (<code>.classpath</code> file contents). This is useful to configure
+a Java project before it is associated with the Java nature, or before the automatic classpath reconciliation mechanism has performed (within
+a resource modifying operation, and prior to the change notification). Note that these API additions are obsoleting the previously
+added API <code>IJavaProject#forceClasspathReload(IProgressMonitor)</code> (also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20931">20931</a>)
+which has thus been deprecated. Forcing the classpath reload can simply be achieved by: <code>p.setRawClasspath(p.readRawClasspath(), p.readOutputLocation(), ...)</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40383">40383</a>
+Search - should only special treat unsaved working copies 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40658">40658</a>
+IJavaProject.getOutputLocation/getRawClasspath require Java nature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42196">42196</a>
+Method popup extremely slow for JOGL code 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41534">41534</a>
+incorrect shadowing reported by rename [refactoring] 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40937">40937</a>
+ISourceReference.getSource throws ArrayIndexOutOfBoundsException 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41373">41373</a>
+SourceField.getConstant() returns null for final fields set in initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41604">41604</a>
+Possible Compiler Bug 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22976">22976</a>
+DCR - warning for unused declarations of thrown exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40736">40736</a>
+JDT compiler fails to compile legitimate Java code.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40020">40020</a>
+Exceptions in console 
+
+<a name="v_367"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M3 Build - 22nd August 2003 - 3.0 MILESTONE-3
+<br>Project org.eclipse.jdt.core v_367
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_367">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40464">40464</a>
+Index states not saved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41805">41805</a>
+ArrayIndexOutOfBoundsException while creating AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39831">39831</a>
+Search finds only "inexact" matches 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35980">35980</a>
+illegal code completion suggested (abstract methods) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40779">40779</a>
+Primary working copies: no deltas on destroy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36271">36271</a>
+CodeAssist should treat array.clone() as visible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40681">40681</a>
+no warnings for some externalized strings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40584">40584</a>
+Test suite configuration should be more flexible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41674">41674</a>
+ToolFactory.createDefaultClassFileReader does not close zipfile
+	  	
+<a name="v_366"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M3 Build - 19th August 2003
+<br>Project org.eclipse.jdt.core v_366 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_366">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In 1.4 mode, the compiler is now JCK 1.4a compliant (previously was passing JCK1.4).
+</li>
+<li>To reduce the memory consumption and improve performance, the following new APIs were added:
+<ul>
+<li>AST.parsePartialCompilationUnit(ICompilationUnit unit, int position, boolean resolveBindings)</li>
+<li>AST.parsePartialCompilationUnit(ICompilationUnit unit, int position, boolean resolveBindings, WorkingCopyOwner owner)</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41602">41602</a>
+missing @exception in javadoc of IPackageFragment.getNonJavaResources 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38635">38635</a>
+Refactor / Rename Package doesn't allow rename to same name with different case [refactoring]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40476">40476</a>
+refactor change method signature reports erroneous non-constant case statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40995">40995</a>
+NPE in ast.ExplicitConstructorCall.analyseCode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40880">40880</a>
+Wrong error range for 'indirect static access'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40174">40174</a>
+Performance issues with builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39108">39108</a>
+Numerous single type imports can slow compiler down significantly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41019">41019</a>
+org.eclipse.jdt.core.Signature cannot resolve complex type that has package name starting with letters as any primitive type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38633">38633</a>
+Search should not open requested types with match locator parser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40954">40954</a>
+ArrayIndexOutOfBoundsException during sort members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40804">40804</a>
+NPE in MethodBinding.sourceMethod()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40474">40474</a>
+DOM/AST: Add API to parse only part of a compilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40839">40839</a>
+Deprecation is reported even if there is an empty member declaration prior to the field declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40606">40606</a>
+Unable to discard empty package if containing .class files 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39174">39174</a>
+NPE in type hierarchy when opening type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40082">40082</a>
+NPE in TypeHierarchy.packageRegionContainsSamePackageFragment(TypeHierarchy.java:1314) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40090">40090</a>
+No need to close Java model on shutdown 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42589">42589</a>
+jck1.4a failures
+
+<a name="v_365a"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M3 Build - 24th July 2003
+<br>Project org.eclipse.jdt.core v_365a 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_365a">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40752">40752</a>
+internal compiler error: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40594">40594</a>
+wrong location set for org.apache.ant when building jdt component with baseLocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40715">40715</a>
+getWorkingCopy(...) should always return a new working copy for primary cus 
+
+<a name="v_365"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M3 Build - 22nd July 2003
+<br>Project org.eclipse.jdt.core v_365 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_365">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added optional diagnosis for undocumented empty blocks
+<pre>
+* COMPILER / Reporting Undocumented Empty Block
+*    When enabled, the compiler will issue an error or a warning when an empty block is detected and it is not
+*    documented with any comment.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li> Removed optional diagnosis for boolean methods throwing exception, since it proved to be useless as is.
+</li>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40116">40116</a>
+     requires the index format to be changed. Indexes will be automatically regenerated upon
+     subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40382">40382</a>
+JavaModelException#printStackTrace should be improved 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40572">40572</a>
+Unnecessary cast warning for necessary cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40322">40322</a>
+Error creating new Java projects 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40421">40421</a>
+Unnecessary cast warning...true but...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=32285">32285</a>
+DCR - extra java compiler markers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40514">40514</a>
+ArrayIndexOutOfBoundsException during detection of unnecessary casts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40442">40442</a>
+Abstract class fails to invoke interface-defined method in 1.4 compliance mode.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40116">40116</a>
+Search for references to nested class doesn't find anything 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40334">40334</a>
+Model should be more tolerant for possible compiler failures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36479">36479</a>
+Rename operation during refactoring fails 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39865">39865</a>
+Misleading error diagnosis on broken method signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=12800">12800</a>
+suboptimal error messages on mistyped 'throw/throws' keywords 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38568">38568</a>
+Search for method declarations fooled by array types 
+
+<a name="v_364b"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 18th July 2003 - 3.0 MILESTONE-2
+<br>Project org.eclipse.jdt.core v_364b 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_364b">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40495">40495</a>
+VerifyError with return statements containing a cast expression
+
+<a name="v_364a"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 17th July 2003
+<br>Project org.eclipse.jdt.core v_364a 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_364a">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40423">40423</a>
+NPE Saving a file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40288">40288</a>
+NPE while building
+
+<a name="v_364"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 16th July 2003
+<br>Project org.eclipse.jdt.core v_364 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_364">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40210">40210</a>
+ICompilationUnit#isWorkingCopy() misbehaving for discarded working copies
+
+<a name="v_363"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 15th July 2003
+<br>Project org.eclipse.jdt.core v_363 
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_363">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added flag <code>IJavaElementDelta.F_PRIMARY_WORKING_COPY</code> that signals that a compilation unit has become a
+     primary working copy, or that a primary working copy has reverted to a compilation unit (i.e. primary working copies are not notified
+     as being added/removed like other working copies, since the primary unit is only changing mode, also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40028">40028</a>).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=40028">40028</a>
+Deltas and deleted working copies 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39823">39823</a>
+AST: Would like to have binding of Serializable and Clonable
+	  	
+<a name="v_362"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 14th July 2003 
+<br>Project org.eclipse.jdt.core v_362
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_362">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added optional diagnosis for unnecessary cast or instanceof operations (matching problem IDs are
+<code>IProblem.UnnecessaryCast</code>, <code>IProblem.UnnecessaryArgumentCast</code>, <code>IProblem.UnnecessaryInstanceof</code>).
+<pre>
+* COMPILER / Reporting Unnecessary Type Check
+*    When enabled, the compiler will issue an error or a warning when a cast or an instanceof operation 
+*    is unnecessary.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>	 
+</li>
+<li> Changed Java element delta processing to be thread-safe.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39926">39926</a>
+deleting default package (not in source folder) does nothing 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39877">39877</a>
+Rebuild All generates extra "Unable to read classpath" entry. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39925">39925</a>
+Unnecessary instanceof checking leads to a NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35442">35442</a>
+flag unnecessary casts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39841">39841</a>
+Give better explanation of why abstract class can't be instantiated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39467">39467</a>
+Classes not implementing abstract methods compile without error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39763">39763</a>
+Non NLS string is reported and it should not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39779">39779</a>
+End position of IType exceeds the size of CompilationUnit 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39766">39766</a>
+compilation unit cannot be saved 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39664">39664</a>
+setSuperInterfaces(String[] interfaceNames) API of org.eclipse.jdt.core.jdom.IDOMType interface does not work for an empty array parameter as Input
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39663">39663</a>
+setSuperclass(String superclassName) API of org.eclipse.jdt.core.jdom.IDOMType interface does not work for null as Input
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39736">39736</a>
+JavaModelException on copying read-only CompilationUnits 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39009">39009</a>
+NPE in Delta processor while executing JDT/UI tests 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35739">35739</a>
+Stack dump on console 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35632">35632</a>
+NPE in DeltaProcessor 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39281">39281</a>
+Unable Refacter (renaming) an inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38450">38450</a>
+Delete: Removing default package removes source folder 
+
+<a name="v_361"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 7th July 2003 
+<br>Project org.eclipse.jdt.core v_361
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_361">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added optional compiler diagnosis for boolean method declaring thrown exceptions
+(matching problem ID is <code>IProblem.BooleanMethodThrowingException</code>)
+<pre>
+* COMPILER / Reporting Boolean Method Declaring Thrown Exceptions
+*    When enabled, the compiler will issue an error or a warning when a boolean method declaration 
+*    is specifying a clause for thrown exceptions. Some of them are predicates, and these should only 
+*    return a boolean value and not raise exceptions.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.booleanMethodThrowingException"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+<li> Added optional compiler diagnosis for indirect references to static members (matching problem IDs are:
+<code>IProblem.IndirectAccessToStaticField</code>, <code>IProblem.IndirectAccessToStaticMethod</code>, <code>IProblem.IndirectAccessToStaticType</code>).
+<pre>
+* COMPILER / Reporting Indirect Reference to a Static Member
+*    When enabled, the compiler will issue an error or a warning whenever a static field
+*    or method is accessed in an indirect way. A reference to a static member should
+*    preferably be qualified with its declaring type name.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.indirectStaticAccess"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li> Removed method <code>Parser#grammar()</code>, which was hosting the Java grammar as a massive comment. 
+From now on, the grammar is defined in its own separate file: <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/grammar/java_1_4.g"><code>java_1_4.g</code></a>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39624">39624</a>
+Should warn about predicate throwing exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39168">39168</a>
+Could remove JavaElement.fLEType field 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36989">36989</a>
+Incorrect error for "super must be first statement in constructor"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3319">3319</a>
+wrong compile-time error message (1GG1LDK)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39268">39268</a>
+Optional warning for indirect static references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39533">39533</a>
+Working copy with no corresponding file not considered by NameLookup 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39502">39502</a>
+No completion in message send
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39475">39475</a>
+Extra error diagnosis in editor from siblings
+
+<a name="v_360"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 1st July 2003 
+<br>Project org.eclipse.jdt.core v_360
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_360">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Plugin version ID got incremented to 3.0.0. 
+</li>
+<li> Removed tolerance for relative source attachments in <code>JavaCore.newLibraryEntry(...)</code>. Only
+allowing relative empty pathes so as to permit using classpath variables to denote the absence of a source attachment.
+<li>To finish closing the gap between compilation units and working copies 
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36888">bug 36888</a>), new APIs were added to generalize
+the usage of a working copy owner (entire JavaModel is now aware of owned working copies). These new APIs are copies of existing APIs augmented with
+a <code>WorkingCopyOwner</code> parameter, that defines the working copies to consider in the operation. 
+When specifying an owner parameter, all working copies belonging to this owner will implicitly take precedence over primary ones
+(without requiring the owner to remember all its working copies, as in 2.1 era). Note that when no owned working copy is found, a primary
+unit will be considered instead, and since primary units have a built-in working copy (see <code>ICompilationUnit.becomeWorkingCopy(...)</code>),
+the primary unit may already be in working copy mode (very likely since an editor got opened on it). This means that an owner will already 
+transparently see unsaved editor contents for all units for which it has no better working copy to contribute.
+The following new APIs were added:
+	<ul>
+	<li><code>AST.parseCompilationUnit(char[] source, String unitName, IJavaProject project, WorkingCopyOwner owner)</code></li>
+	<li><code>AST.parseCompilationUnit(IClassFile classFile, boolean resolveBindings, WorkingCopyOwner owner)</code></li>
+	<li><code>AST.parseCompilationUnit(ICompilationUnit unit, boolean resolveBindings, WorkingCopyOwner owner)</code></li>
+	<li><code>IEvaluationContext.codeComplete(String codeSnippet, int position, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+	<li><code>IEvaluationContext.codeSelect(String codeSnippet, int offset, int length, WorkingCopyOwner owner)</code></li>
+	<li><code>IDOMCompilationUnit.getCompilationUnit(IPackageFragment parent, WorkingCopyOwner owner)</code></li>
+	<li><code>ICodeAssist.codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+	<li><code>ICodeAssist.codeSelect(int offset, int length, WorkingCopyOwner owner)</code></li>
+	<li><code>ICompilationUnit.reconcile(boolean forceProblemDetection, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IJavaProject.findElement(IPath path, WorkingCopyOwner owner)</code></li>
+	<li><code>IJavaProject.findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner)</code></li>
+	<li><code>IJavaProject.findType(String fullyQualifiedName, WorkingCopyOwner owner)</code></li>
+	<li><code>IJavaProject.newTypeHierarchy(IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IJavaProject.newTypeHierarchy(IType type, IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IPackageFragment.getCompilationUnit(String name, WorkingCopyOwner owner)</code></li>
+	<li><code>IPackageFragment.getCompilationUnits(WorkingCopyOwner owner)</code></li>
+	<li><code>IType.codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, ICompletionRequestor requestor, WorkingCopyOwner owner)</code></li>
+	<li><code>IType.newSupertypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IType.newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IType.newTypeHierarchy(WorkingCopyOwner owner, IProgressMonitor monitor)</code></li>
+	<li><code>IType.resolveType(String typeName, WorkingCopyOwner owner)</code></li>
+	<li><code>JavaCore.create(IFile file, WorkingCopyOwner owner)</code></li>
+	<li><code>JavaCore.create(IResource resource, WorkingCopyOwner owner)</code></li>
+	<li><code>JavaCore.create(String handleIdentifier, WorkingCopyOwner owner)</code></li>
+	<li><code>JavaCore.createCompilationUnitFrom(IFile file, WorkingCopyOwner owner)</code></li>
+	<li><code>JavaCore.getWorkingCopies(WorkingCopyOwner owner)</code></li>
+	<li><code>SearchEngine.SearchEngine(WorkingCopyOwner workingCopyOwner)</code></li>
+	<li><code>SearchEngine.createHierarchyScope(IType type, WorkingCopyOwner owner)</code></li>
+	</ul>
+</li>
+<li> Added optional problem to signal superfluous semicolons (matching problem ID is <code>IProblem.SuperfluousSemicolon</code>).
+<pre>
+* COMPILER / Reporting Superfluous Semicolon
+*    When enabled, the compiler will issue an error or a warning if a superfluous semicolon is met.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.superfluousSemicolon"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=26281">26281</a>
+error hover text indicates wrong problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23166">23166</a>
+Syntax error message from Java compiler is confusing. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33213">33213</a>
+Same error reported more than once? 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36214">36214</a>
+TODOs reported twice when located at the end of the method declaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36232">36232</a>
+binding do not fully consider working copies 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36888">36888</a>
+Close the gap between original and working copies 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39311">39311</a>
+Outliner did not refresh after method rename (refactor) 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39259">39259</a>
+While statement has wrong source position
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39007">39007</a>
+Infinite loop trying to index a non-existing external jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39172">39172</a>
+Incorrect error reported if extra semi-colon exists on a return statement
+
+
+<a name="v_359"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 23rd June 2003 
+<br>Project org.eclipse.jdt.core v_359
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_359">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API on <code>ICompilationUnit</code> to get the primary compilation unit of a working copy 
+	 (it replaces <code>IWorkingCopy.getOriginalElement()</code>):
+<pre>
+/**
+ * Returns the primary compilation unit (whose owner is the primary owner)
+ * this working copy was created from, or this compilation unit if this a primary
+ * compilation unit.
+ * Note that the returned primary compilation unit can be in working copy mode.
+ * 
+ * @return the primary compilation unit this working copy was created from,
+ * or this compilation unit if it is primary
+ * @since 3.0
+ */
+ICompilationUnit getPrimary();
+</pre>
+</li>
+<li>Added API on <code>IJavaElement</code> to get the primary element of a working copy 
+	 element (it replaces <code>IWorkingCopy.getOriginalElement(IJavaElement)</code>):
+<pre>
+/**
+ * Returns the primary element (whose compilation unit is the primary compilation unit)
+ * this working copy element was created from, or this element if it is a descendant of a
+ * primary compilation unit or if it is not a descendant of a working copy (e.g. it is a
+ * binary member).
+ * The returned element may or may not exist.
+ * 
+ * @return the primary element this working copy element was created from, or this
+ * 	element.
+ * @since 3.0
+ */
+IJavaElement getPrimaryElement();
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38678">38678</a>
+workspace did not shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37006">37006</a>
+2 tasks in the tasks view instead of one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38759">38759</a>
+Task Tags: should not consider text in substrings/parts of text
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36066">36066</a>
+Outliner did not refresh after field rename 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38951">38951</a>
+NPE in editor while saving contents 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35877">35877</a>
+Stack overflow in code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35409">35409</a>
+RC2 Compiler produces bogus error messages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38838">38838</a>
+SyntaxError- unoptimal syntax error message
+
+
+<a name="v_357b"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 18th June 2003 
+<br>Project org.eclipse.jdt.core v_357b
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_357b">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Backported index manager deadlock fix on top of v_357</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38901">38901</a>
+IndexManager hangs in end-less loop
+
+
+<a name="v_358"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M2 Build - 16th June 2003 
+<br>Project org.eclipse.jdt.core v_358
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_358">cvs</a>).
+
+<p><b>NOTE:</b> This version got backed out due to severe regression
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38951">38951</a> NPE in editor while saving contents).
+Until subsequent version is made available (see above), integration builds will revert to previous version (v_357).
+
+<h2>
+What's new in this drop</h2>
+<ul>
+<li><code>JavaCore.newLibraryEntry(...)</code> will now allow an empty source attachment (<code>new Path("")</code>) to
+be equivalent to no source attachment (i.e. <code>null</code>). This adjustment is made necessary for
+library entries generated from classpath variables which cannot be set to <code>null</code>. Also see 
+bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38531">38531</a>.
+<pre>
+* @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
+*    or <code>null</code> if none. Note, since 3.0, an empty path is allowed to denote no source attachment.
+*   and will be automatically converted to <code>null</code>.
+</pre>
+</li>
+<li>Added API <code>IJavaProject#forceClasspathReload(IProgressMonitor)</code> to force reload of <code>.classpath</code> file
+before next automatic update occurs.
+<pre>
+/**
+ * Force the project to reload its <code>.classpath</code> file from disk and update the classpath accordingly.
+ * Usually, a change to the <code>.classpath</code> file is automatically noticed and reconciled at the next 
+ * resource change notification event. If required to consider such a change prior to the next automatic
+ * refresh, then this functionnality should be used to trigger a refresh. In particular, if a change to the file is performed,
+ * during an operation where this change needs to be reflected before the operation ends, then an explicit refresh is
+ * necessary.
+ * 
+ * @param monitor a progress monitor for reporting operation progress
+ * @exception JavaModelException if the classpath could not be updated. Reasons
+ * include:
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
+ *  - Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
+ *  - A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
+ *  - The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
+ *  - The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
+ *  - The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
+ *  - The classpath is being modified during resource change event notification (CORE_EXCEPTION)
+ * @since 3.0
+ */
+</pre>
+</li>
+<li>In the process of closing the gap between compilation units and working copies 
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36888 ">bug 36888 </a>), the following new APIs 
+are added to <code>ICompilationUnit</code>:
+	<ul>
+	<li><pre>
+/**
+ * Changes this compilation unit handle into a working copy. A new IBuffer is
+ * created using this compilation unit handle's owner. Uses the primary owner is none was
+ * specified when this compilation unit handle was created.
+ *
+ * When switching to working copy mode, problems are reported to given 
+ * IProblemRequestor.
+ *
+ * Once in working copy mode, changes to this compilation unit or its children are done in memory.
+ * Only the new buffer is affected. Using commitWorkingCopy(boolean, IProgressMonitor)
+ * will bring the underlying resource in sync with this compilation unit.
+ *
+ * If this compilation unit was already in working copy mode, an internal counter is incremented and no
+ * other action is taken on this compilation unit. To bring this compilation unit back into the original mode 
+ * (where it reflects the underlying resource), discardWorkingCopy must be call as many 
+ * times as becomeWorkingCopy.
+ * 
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to null indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if this compilation unit could not become a working copy.
+ * @see discardWorkingCopy
+ * @since 3.0
+ */
+void becomeWorkingCopy(IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	<li><pre>
+/**
+ * Commits the contents of this working copy to its underlying resource.
+ *
+ * It is possible that the contents of the original resource have changed
+ * since this working copy was created, in which case there is an update conflict.
+ * The value of the force parameter affects the resolution of
+ * such a conflict:
+ * - true - in this case the contents of this working copy are applied to
+ * 	the underlying resource even though this working copy was created 
+ * 	before a subsequent change in the resource
+ * - false - in this case a JavaModelException is thrown
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+ * @param force a flag to handle the cases when the contents of the original resource have changed
+ * since this working copy was created
+ * @param monitor the given progress monitor
+ * @exception JavaModelException if this working copy could not commit. Reasons include:
+ * - A CoreException occurred while updating an underlying resource
+ * - This element is not a working copy (INVALID_ELEMENT_TYPES)
+ * - A update conflict (described above) (UPDATE_CONFLICT)
+ * @since 3.0
+ */
+void commitWorkingCopy(boolean force, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	<li><pre>
+/**
+ * Changes this compilation unit in working copy mode back to its original mode.
+ *
+ * This has no effect if this compilation unit was not in working copy mode.
+ * 
+ * If becomeWorkingCopy was called several times on this
+ * compilation unit, discardWorkingCopy must be called as 
+ * many times before it switches back to the original mode.
+ * 
+ * @see becomeWorkingCopy
+ * @exception JavaModelException if this working copy could not return in its original mode.
+ * @since 3.0
+ */
+void discardWorkingCopy() throws JavaModelException;
+	</pre></li>
+	<li><pre>
+/**
+ * Returns the working copy owner of this working copy.
+ * Returns null if it is not a working copy or if it has no owner.
+ * 
+ * @return WorkingCopyOwner the owner of this working copy or null
+ * @since 3.0
+ */
+WorkingCopyOwner getOwner();
+	</pre></li>	
+	<li><pre>
+/**
+ * Returns a new working copy of this element if this element is not
+ * a working copy, or this element if this element is already a working copy.
+ * 
+ * Note: if intending to share a working copy amongst several clients, then 
+ * getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor) 
+ * should be used instead.
+ * 
+ * When the working copy instance is created, an ADDED IJavaElementDelta is 
+ * reported on this working copy.
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+* @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if the contents of this element can
+ * 	not be determined. 
+ * @return a new working copy of this element if this element is not
+ * 	a working copy, or this element if this element is already a working copy
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(IProgressMonitor monitor) throws JavaModelException;
+	</pre></li>	
+	<li><pre>
+/**
+ * Returns a shared working copy on this element using the given working copy owner to create
+ * the buffer, or this element if this element is already a working copy.
+ * This API can only answer an already existing working copy if it is based on the same
+ * original compilation unit AND was using the same working copy owner (that is, as defined by Object.equals).	 
+ * 
+ * The life time of a shared working copy is as follows:
+ * - The first call to getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)
+ *   creates a new working copy for this element
+ * - Subsequent calls increment an internal counter.
+ * - A call to discardWorkingCopy() decrements the internal counter.
+ * - When this counter is 0, the working copy is discarded.
+ * 
+ * So users of this method must discard exactly once the working copy.
+ *
+ * Note that the working copy owner will be used for the life time of this working copy, that is if the 
+ * working copy is closed then reopened, this owner will be used.
+ * The buffer will be automatically initialized with the original's compilation unit content
+ * upon creation.
+ * 
+ * When the shared working copy instance is created, an ADDED IJavaElementDelta is reported on this
+ * working copy.
+ * 
+ * Since 2.1, a working copy can be created on a not-yet existing compilation
+ * unit. In particular, such a working copy can then be committed in order to create
+ * the corresponding compilation unit.
+ * 
+ * @param owner the working copy owner that creates a buffer that is used to get the content 
+ *  	of the working copy
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * 	reconciling as they are discovered. The requestor can be set to null indicating
+ * 	that the client is not interested in problems.
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * 	or null if no progress should be reported 
+ * @exception JavaModelException if the contents of this element can
+ *  	not be determined. 
+ * @return a new working copy of this element using the given factory to create
+ * the buffer, or this element if this element is already a working copy
+ * @since 3.0
+ */
+ICompilationUnit getWorkingCopy(WorkingCopyOwner owner, IProblemRequestor problemRequestor, IProgressMonitor monitor) throws JavaModelException;	
+	</pre></li>
+	</ul>
+And the following abstract class replaces <code>IBufferFactory</code>:
+	<pre>
+/**
+ * The owner of an ICompilationUnit handle in working copy mode. 
+ * An owner is used to identify a working copy and to create its buffer.
+ * 
+ * @see ICompilationUnit#becomeWorkingCopy
+ * @see ICompilationUnit#discardWorkingCopy
+ * @since 3.0
+ */
+public abstract class WorkingCopyOwner {
+	/**
+	 * Creates a buffer for the given working copy.
+	 * The new buffer will be initialized with the contents of the underlying file
+	 * if and only if it was not already initialized by the compilation owner (a buffer is 
+	 * uninitialized if its content is null).
+	 * 
+	 * @param workingCopy the working copy of the buffer
+	 * @return IBuffer the created buffer for the given working copy
+	 * @see IBuffer
+	 */
+	public IBuffer createBuffer(ICompilationUnit workingCopy) {
+		...
+	}
+}
+	</pre>
+	The intent for the primary owner is to use a buffer factory that would be
+	provided by the org.eclipse.text infractructure. This infrastructure not being
+	ready yet, in the meantime one can change the primary owner's 
+	<code>IBufferFactory</code> using the following internal API:
+	<pre>
+org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner.PRIMARY.factory = ...;
+	</pre>
+
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38901">38901</a>
+IndexManager hangs in end-less loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38908">38908</a>
+Ant script reports that the bootclasspath cannot be infer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38531">38531</a>
+IllegalArgumentException "Source attachment path should be absolute"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38424">38424</a>
+Mistake on Web site
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38732">38732</a>
+organize imports does not work with assert in source code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38447">38447</a>
+AST: Source ranges with missing bracket
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36854">36854</a>
+NPE opening type hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33530">33530</a>
+JavaModel synchronization model should be more optimistic 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20931">20931</a>
+Need an API to reload the classpath from the file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38393">38393</a>
+bytecode generated for evaluation with parentheses is wrong
+
+<a name="v_357"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 5th June 2003 - 3.0 MILESTONE-1
+<br>Project org.eclipse.jdt.core v_357
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_357">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37274">37274</a>
+Deadlock on plugin import
+
+
+<a name="v_356"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 4th June 2003
+<br>Project org.eclipse.jdt.core v_356
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_356">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38362">38362</a>
+Inconsistent output when using comparrisson operators
+
+
+<a name="v_355"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 3rd June 2003
+<br>Project org.eclipse.jdt.core v_355
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_355">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37111">37111</a> may issue some outgoing changes
+to .classpath file since the source attachment will be shortened into a project relative path when applicable. The .classpath file
+is still backward compatible, and will continue to accept non relative source attachments as well. </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37111">37111</a>
+classpath file - java source attachment shouldn't hardcode project name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38143">38143</a>
+this = null; should raise compile time error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38124">38124</a>
+Brackets around cast accepted by Eclipse but not javac
+
+
+<a name="v_354"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 26th May 2003
+<br>Project org.eclipse.jdt.core v_354
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_354">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added <code>JavaCore</code> optional problem to detect incompatible required binaries, so as to flag situations where
+some prerequisite binaries are required a JRE level higher than the project target platform; i.e. compiling against 1.4 libraries 
+when deploying for 1.1 platform is likely unwanted.
+<pre>
+* JAVACORE / Reporting Incompatible JDK Level for Required Binaries
+*    Indicate the severity of the problem reported when a project prerequisites another project 
+*    or library with an incompatible target JDK level (e.g. project targeting 1.1 vm, but compiled against 1.4 libraries).
+*     - option id:         "org.eclipse.jdt.core.incompatibleJDKLevel"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37750">37750</a>
+incorrect handle identifier for IImportContainer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36674">36674</a>
+compiler can generate Java 1.4-only bytecode regardless of compatibility settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37962">37962</a>
+Unexpected transient problem during reconcile 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37166">37166</a>
+NPE in SearchEngine when matching type against ProblemReferenceBinding 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37438">37438</a>
+searchenging NPE in searchDeclarationsOfReferencedTypes 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37779">37779</a>
+ExceptionInInitializerError when using JDTCompilerAdapter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36307">36307</a>
+JDK1.4.2: Wrong declaring class for clone method on array class
+
+
+<a name="v_353"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 19th May 2003
+<br>Project org.eclipse.jdt.core v_353
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_353">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37621">37621</a>
+java compiler creates class with internal inconsistency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37646">37646</a>
+Help for JDTCompilerAdapter is dated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36894">36894</a>
+JobManager could wait when idle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37541">37541</a>
+Unoptimal deprecation diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37565">37565</a>
+JACKS: Class literal should not cause class initialization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37503">37503</a>
+Compiler does not take care of exclusion filter
+
+
+<a name="v_352"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 13th May 2003
+<br>Project org.eclipse.jdt.core v_352
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_352">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Lowered default severity of field/local variable hiding optional diagnosis to <code>"ignore"</code>.
+</li>
+<li>Lowered default severity of accidental boolean assignment optional diagnosis to <code>"ignore"</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37501">37501</a>
+VerifyError with assert when optimizing out unused local variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37387">37387</a>
+Compiler generates unnecessary byte codes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37381">37381</a>
+AST: Wrong source ranges on VariableDeclExpression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37200">37200</a>
+"Source-&gt;Generate Delegate Methods..." fails
+
+<a name="v_351"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 29th April 2003
+<br>Project org.eclipse.jdt.core v_351
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_351">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=37040">37040</a>
+VerifyError "Illegal target of jump or branch"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36490">36490</a>
+Java compiler misses dependency on 'static final' class variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36814">36814</a>
+NaiveASTFlattener does not serialize try-finally statements correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36772">36772</a>
+AST: CompilationUnit.findDeclaringNode: Spec/Impl not same
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36711">36711</a>
+Resource duplication message should list location of duplicate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36718">36718</a>
+Compiler should not generate references to classes not on the classpath
+
+<a name="v_350"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.0M1 Build - 22nd April 2003
+<br>Project org.eclipse.jdt.core v_350
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_350">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new compiler optional problem to signal cases where a boolean variable is assigned
+in a condition expression. It is likely an accidental situation, where a comparison was actually meant.
+<pre>
+* COMPILER / Reporting Possible Accidental Boolean Assignment
+*    When enabled, the compiler will issue an error or a warning if a boolean assignment is acting as the condition
+*    of a control statement  (where it probably was meant to be a boolean comparison).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Added new compiler settings to control the diagnosis of variable hiding other ones.
+<pre>
+* COMPILER / Reporting Local Variable Declaration Hiding another Variable
+*    When enabled, the compiler will issue an error or a warning whenever a local variable
+*    declaration is hiding some field or local variable (either locally, inherited or defined in enclosing type).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.localVariableHiding"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+*
+* COMPILER / Reporting Field Declaration Hiding another Variable
+*    When enabled, the compiler will issue an error or a warning whenever a field
+*    declaration is hiding some field or local variable (either locally, inherited or defined in enclosing type).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.fieldHiding"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+*
+* COMPILER / Reporting Special Parameter Hiding another Field
+*    When enabled, the compiler will signal cases where a constructor or setter method parameter declaration 
+*    is hiding some field (either locally, inherited or defined in enclosing type).
+*    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.localVariableHiding".
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.specialParameterHidingField"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "disabled"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36510">36510</a>
+Automatically attach source for source files located in a class folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36499">36499</a>
+exists() returns true for a source file inside a classfolder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36438">36438</a>
+null == null causes java.lang.VerifyError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35755">35755</a>
+Search in hierarchy misses dependent projects 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36465">36465</a>
+Unable to create multiple source folders when not using bin for output
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36339">36339</a>
+Try codegen issues slightly incorrect ANY exception handler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35965">35965</a>
+Source not found in source attachment 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36447">36447</a>
+Unoptimal wide conditional branch bytecode sequence
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=19286">19286</a>
+Suspicious synchronized operations 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36213">36213</a>
+ArrayIndex out of bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36244">36244</a>
+JDK1.4.2: Add -cp as a batch option 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35528">35528</a>
+When I check out a project from CVS, Updating takes a very long time
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36058">36058</a>
+Unknown NPE in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21661">21661</a>
+Compile dependency problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=28937">28937</a>
+Compiler Problem Marker: Accidental Boolean Assignment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33831">33831</a>
+ast API: add FieldAccess.resolveFieldBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35649">35649</a>
+The SourceMapper instances could share the fileNamefilter 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34896">34896</a>
+compiler setting "unused private fields"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=33751">33751</a>
+The numbering of anonymous could be optimized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35849">35849</a>
+Incremental compilation ignores linked folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35926">35926</a>
+Batch compiler compile should return false when the command line is incorrect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35421">35421</a>
+[nls] Inconsistencies between properties files and nls strings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34173">34173</a>
+Create a compiler warning when an instance variable is "re-declared" as a local variable.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=21140">21140</a>
+Warning/error on shadowing definition of data member?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35490">35490</a>
+Search doesn't work for reference of 'cursorLocation'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35338">35338</a>
+Cannot save file, "Save failed:null" error message received
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35438">35438</a>
+CastExpression resolution departs from JLS section 6.5.1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36165">36165</a>
+[DOM/AST] Incorrect grammar rule in TypeDeclaration
+
+
+<a name="v_312"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 2.1 Build (before 3.0/2.1.1 branching) - 31st March 2003
+<br>Project org.eclipse.jdt.core v_312
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_312">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=35831">35831</a>
+NPE navigating references using links
+
+<p><hr>
+For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html">build notes up to Release 2.1</a>.
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R31_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R31_buildnotes_jdt-core.html
new file mode 100644
index 0000000..c2a9d6a
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R31_buildnotes_jdt-core.html
@@ -0,0 +1,4773 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes</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.1 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  Here are the build notes for the Eclipse JDT/Core plug-in project 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
+	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>R3.1</b></a> branch. 
+	  This present document covers all changes since Release 3.0 (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>).
+	  Older changes which occurred up to Release 3.0 can be found in 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html">build notes R3.0</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<a name="v_570"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC4 - 27th June 2005 - 3.1 RELEASE (R3_1)
+<br>Project org.eclipse.jdt.core v_570
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_570">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101453">101453</a>
+java.lang.UnsupportedOperationException: Operation only supported in JLS2 AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101794">101794</a>
+[1.5][compiler] Compiling Classpath classes results in bad class file
+
+
+<a name="v_569"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC4 - 24th June 2005 - 3.1 RELEASE CANDIDATE 4
+<br>Project org.eclipse.jdt.core v_569
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_569">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101613">101613</a>
+Performance regressions in Open Type Hierarchy performance test
+	  	
+<a name="v_568"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC4 - 23rd June 2005
+<br>Project org.eclipse.jdt.core v_568
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_568">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101426">101426</a>
+[search] Search doesn't work with imported plugin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101120">101120</a>
+Cannot generate an executable of the batch compiler using gcj 3.4.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100631">100631</a>
+Internal compiler error in 3.1RC2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101230">101230</a>
+[compiler] Internal compiler error when labeled statement processing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101022">101022</a>
+[search] JUnit Test Runner on folder runs tests outside directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101019">101019</a>
+RC3: Type Hierarchy does not find implementers/extenders of inner class/interface in other project 	
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100009">100009</a>
+[assist] Content assist uses generic parameter name arg0 instead of real name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100584">100584</a>
+[1.5][dom] NPE when selecting a faulty member type following a generic type reference
+
+<a name="v_567"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC3 - 17th June 2005 - 3.1 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_567
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_567">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100519">100519</a>
+[1.5][compiler] generic parameter and qualified access seems to confuse each other
+
+
+<a name="v_566"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_566
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_566">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100421">100421</a>
+[1.5][compiler] chain of generics-extends confuse compiler
+
+
+<a name="v_565"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_565
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_565">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99654">99654</a>
+[5.0] JavaModel returns both IClassFile and ICompilationUnit for package-info.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100393">100393</a>
+Defaults for compiler errors/warnings settings
+
+<a name="v_564"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_564
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_564">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99606">bug 99606</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100302">100302</a>
+StackOverflowError during completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99606">99606</a>
+Subtype not found if parameterized on inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100293">100293</a>
+1.5 compiler - Methods using non-generic inner types of concreted generic classes generate wrong signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98322">98322</a>
+[compiler] ParameterizedTypeBinding should not have AccGenericSignature set when no type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99978">99978</a>
+MalformedTreeException on Inline Method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100128">100128</a>
+[1.5][compiler] StackOverflow compiling GNU Classpath generics branch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100142">100142</a>
+CCE when calling ITypeBinding#getJavaElement() on char[][]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100147">100147</a>
+[1.5][compiler] NPE when reporting an error on an unsafe type conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100062">100062</a>
+[formatting] Code formatter is broken on test case from bug 99999
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100162">100162</a>
+java.lang.VerifyError is produced by Eclipse Java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99428">99428</a>
+[1.5][compiler] enum classes created without final accessFlag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99999">99999</a>
+[1.5][compiler] AIOOBE with generics + nested classes + arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99686">99686</a>
+IAE in Util#scanTypeBoundSignature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100149">100149</a>
+[1.5][compiler] Raw type upper bounds should be raw types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99927">99927</a>
+NPE in ParameterizedTypeBinding.initialize
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100138">100138</a>
+[doc] Confusing documentation in Project Configuration tutorial
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99915">99915</a>
+[search] Open Type: not yet saved types not found if case-sensitve name is entered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100007">100007</a>
+[1.5][compiler] ClassCastException using array object as generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99600">99600</a>
+[search] Java model exception on "Move to new file" on inner type with inner type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99982">99982</a>
+[DOM] Wrong positions for boolean[] type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99811">99811</a>
+NPE during content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99629">99629</a>
+Error while entering expression in change variable value dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99922">99922</a>
+[1.5][compiler] NPE in compiler for Arrays.asList(3, 3.1);
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98378">98378</a>
+[search] Can't find declarations in hierarchy of interface.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97614">97614</a>
+[1.5][search] Refactoring: renaming of field of a (complex) parametrized type does not replace all occurrences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97547">97547</a>
+[search] Package search does not find references in member types import clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96950">96950</a>
+[search] Code assist proposes non accessible types into completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99510">99510</a>
+isCastCompatible seems to need capture bindings now to answer correct results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99608">99608</a>
+IMethodBinding#overrides returns false on overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99901">99901</a>
+[select]  AIOOBE when selecting package reference in import statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99282">99282</a>
+[1.5][compiler] Enum / Switch method is not initialized in a thread safe way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52921">52921</a>
+[formatting] Javadoc formatting: extra newline with [pre]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99507">99507</a>
+[javadoc] Infinit loop in DocCommentParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99397">99397</a>
+Typo in CompletionProposal#isConstructor()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99553">99553</a>
+[1.5][compiler] Parameterized class nested statically inside another parameterized type causes compile errors when used in method signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99355">99355</a>
+extract method trips up with generics and final variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99469">99469</a>
+[1.5][compiler] NPE compiling code with unknown annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99375">99375</a>
+Compiler error using Annotations
+
+<a name="v_563"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC2 - 10th June 2005 - 3.1 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_563
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_563">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99260">99260</a>
+[1.5][compiler] Bad bytecode generated with varargs + generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98331">98331</a>
+[1.5][compiler] Casting Conversion needs to check all supertypes for conflicts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99106">99106</a>
+[1.5][compiler] Ambiguous method error because methods don't override in eclipse
+
+
+<a name="v_562"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC2 - 9th June 2005
+<br>Project org.eclipse.jdt.core v_562
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_562">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97487">97487</a>
+[call hierarchy] Call Hierarchy Fails in mounted classes with attached src files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97524">97524</a>
+[prefs] Importing preferences with user library doesn't recreate jar entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99142">99142</a>
+Exception when shutting down quickly after starting
+
+<a name="v_561"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC2 - 9th June 2005
+<br>Project org.eclipse.jdt.core v_561
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_561">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The build state version number has changed. A full build of all projects in the workspace will be triggered upon
+      startup if autobuild is on, or on the next build if autobuild is off.</li>
+<li>The new list of supported warning tokens for the @SuppressWarnings annotation is:
+<ul>
+<li><b><font color="red">all</font></b> : any warning</li>
+<li><b>boxing</b> : autoboxing conversion</li>
+<li><b><font color="red">dep-ann</font></b> : missing @Deprecated annotation</li>
+<li><b><font color="red">deprecation</font></b> : deprecation outside deprecated code</li>
+<li><b>incomplete-switch</b> : incomplete enum switch (<i>enumSwitch</i>)</li>
+<li><b>hiding</b> : 
+<ol><li>field hiding another variable (<i>fieldHiding</i>)</li>
+<li>local variable hiding another variable (<i>localHiding</i>)</li>
+<li>type parameter hiding another type (<i>typeHiding</i>)</li>
+<li>hidden catch block (<i>maskedCatchBlock</i>)</li>
+</ol>
+</li>
+<li><b><font color="red">finally</font></b> : finally block not completing normally</li>
+<li><b>static-access</b> :
+<ol>
+<li>indirect reference to static member (<i>indirectStatic</i>)</li>
+<li>non-static reference to static member (<i>staticReceiver</i>)</li>
+</ol>
+</li>
+<li><b>nls</b> : string literal lacking non-nls tag //$NON-NLS-&lt;n&gt;$</li>
+<li><b><font color="red">serial</font></b> : missing serialVersionUID</li>
+<li><b>unqualified-field-access </b>: unqualified reference to field (<i>unQualifiedField</i>)</li>
+<li><b><font color="red">unchecked</font></b> : unchecked type operation</li>
+<li><b>unused</b> :
+<ol>
+<li>unread method parameter (<i>unusedArgument</i>)</li>
+<li>unread local variable (<i>unusedLocal</i>)</li>
+<li>unused private member declaration (<i>unusedPrivate</i>)</li>
+<li>unused declared thrown exception (<i>unusedThrown</i>)</li>
+</ol>
+</li>
+<li><b>synthetic-access</b> : synthetic access for innerclass (<i>syntheticAccess</i>)</li>
+</ul>
+<p>NOTE:</p><blockquote>All other warning tokens are not longer supported by @SuppressWarnings;
+considering that for some diagnosis, it is simpler to just fix the code than silence some warning.
+In <i>Italic</i> the old warning token is specified.
+<br>Warning tokens also supported by javac are in <font color="red">red</font> (also see <a href="http://www.javac.info/doc?n=JavaCompiler.WarningTokens">declared warning tokens</a>).
+</blockquote>
+</li>
+<li>CodeAssist: added a new API CompletionProposal#isConstructor() to distinguish method and constructor proposal</li>
+<li>Access rules file patterns have been changed to ignore the file extension. This allow easy switching from a source project
+     to a binary project. Thus <code>"com/test/X.java"</code> is now an invalid access rule pattern, and 
+     <code>"com/test/X"</code> is a valid access rule pattern.</li>
+<li>
+Following batch compiler options default value have been changed from "ignore" to "warning":
+<ul>
+<li>unusedLocal (unread local variable)</li>
+<li>unusedPrivate (unused private member declaration)</li>
+<li>fieldHiding (field hiding another variable)</li>
+<li>localHiding (local variable hiding another variable)</li>
+</ul>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76530">76530</a>)
+</li>
+<li>Compiler optional diagnosis for unused private members got generalized to also flag unused
+members of local types.
+</li>
+<li>Compiler no longer reports as unchecked the situation where a method of a raw type is invoked,
+and only the return type got altered by raw conversion (also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>). 
+This change is motivated to better match the language spec 3rd edition.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97087">bug 97087</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99138">99138</a>
+NPE in RawTypeBinding.computeUniqueKey(..) for raw type inside anonymous parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93975">93975</a>
+[1.5][syntax] Poor recovery when extra semicolon in annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93208">93208</a>
+[dom] CompilationUnit.rewrite throws AssertionFailedException with legal AST (bug in recoding ast modifications)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97440">97440</a>
+[1.5][compiler] StackOverflow compiling heavily generic code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99104">99104</a>
+Startup job displayed as "Initializing the Java d...ent tooling"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99084">99084</a>
+Formatter error when generic method has an argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98892">98892</a>
+[compiler] Eclipse compiler generates code that calls the finally block twice
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98969">98969</a>
+Builder didn't find state for prereq project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96586">96586</a>
+[1.5][compiler] Invalid cycle detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98954">98954</a>
+Javadoc of ITypeBinding#getErasure() is wrong for array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98504">98504</a>
+[1.5][compiler] Compiler difference between javac and jdt?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96763">96763</a>
+[1.5][search] Search for method declarations does not find overridden method with different signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96761">96761</a>
+[1.5][search] Search for declarations of generic method finds non-overriding method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98228">98228</a>
+[1.5][compiler] regression - incorrect handling of generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98720">98720</a>
+[preferences] classpath variables are not exported if the session is closed and restored
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98906">98906</a>
+No rebuild after upgrade
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98711">98711</a>
+no way to distinguish constructor from method proposals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98434">98434</a>
+A non-1.5 project with 1.5 projects in the classpath does not show methods with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98750">98750</a>
+[dom] Java DOM Parser finding syntax Problems when parsing Annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90619">90619</a>
+[1.5][compiler] Cannot implement generified interface with erased method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98500">98500</a>
+[1.5] Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98488">98488</a>
+NPE while computing a key for a paramterized type binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97087">97087</a>
+[1.5][search] Can't find reference of generic class's constructor.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93668">93668</a>
+Search indexes not rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98473">98473</a>
+AST binding: type variable reports as 'isTopLevel'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98364">98364</a>
+[1.5][compiler] Compiler allowing invalid generic interface inheritance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>
+[1.5] warn when raw iterator is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93377">93377</a>
+[1.5][compiler] Multiple auto-build failures when using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79309">79309</a>
+Nested interfaces aren't resolved correctly in import (with "Open Declaration" / F3)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96765">96765</a>
+Code completion does not work in enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98483">98483</a>
+IMethodBinding.override does not compare method names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98115">98115</a>
+Field completion failed to propose a field declared into an innerclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93789">93789</a>
+[1.5][compiler] Compiler incorrectly allows static declarations in enum constants.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98396">98396</a>
+[1.5][compiler] Casting Conversion ignores second bound of Type Variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98383">98383</a>
+[1.5][compiler] ClassCastException attempting to cast from intersection type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97322">97322</a>
+[search] Search for method references sometimes reports potential match with differing argument count
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94160">94160</a>
+[1.5][search] Generic method in superclass does not exist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91061">91061</a>
+[1.5][compiler] Static reference to outer type variable should not be allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97108">97108</a>
+[1.5][compiler] NullPointerException encountered while running Java Builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98259">98259</a>
+NPE computing ITypeBinding#getKey()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93536">93536</a>
+[1.5] Internal compiler generating error on code that javac accepts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97606">97606</a>
+[1.5][search] Raw type reference is reported as exact match for qualified names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96424">96424</a>
+[search] SearchParticipant sets containerPath to documentPath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97542">97542</a>
+ASTParser#createASTs does not correctly resolve bindings in working copies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94898">94898</a>
+[1.5] errors in ambiguous method invocation detection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94754">94754</a>
+[1.5][compiler] Ambiguous method call is not detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84035">84035</a>
+[1.5][compiler] Ambiguous method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76530">76530</a>
+[options] Warn about unused local variables and private members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98091">98091</a>
+[1.5][compiler] @SuppressWarnings("assertIdentifier") cannot be applied
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94907">94907</a>
+[assist] missing keyword completions for generic signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84001">84001</a>
+[select] Renaming of class with internal classes fails.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94641">94641</a>
+Code assist does not display parameters for constructor with type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96991">96991</a>
+[1.5][compiler] Annotation attribute should be able to reference field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96713">96713</a>
+[1.5][compiler] Inconsistency with Sun JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95684">95684</a>
+[1.5][compiler] Type handling on concrete inner class of super class is incorrect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97273">97273</a>
+Illegal argument exception in Signature#getTypeSignatureKind
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98165">98165</a>
+Wrong source range for ConditionalExpression with casted target in FieldAccess as expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96085">96085</a>
+[1.5][compiler] problems with inner classes and generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98139">98139</a>
+Java Code Formatter is severely confused by following code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98079">98079</a>
+[1.5][compiler] incorrect Bound mismatch compilation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97860">97860</a>
+[1.5][assist] All current proposals while completing after a type parameter results in a compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82560">82560</a>
+[assist] Completion fails on parameterized generic method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98086">98086</a>
+[1.5][dom] CU still have problems even with @SuppressWarnings("all")
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98037">98037</a>
+[Java Editor Templates] Templates with multiple lines are inlined when used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96258">96258</a>
+Bogus build path errors caused by multiple project import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97902">97902</a>
+NPE on Open Declaration on reference to generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80432">80432</a>
+Code Assist box exhibits strange behavior in an endless for loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96944">96944</a>
+[1.5][assist] shoud not suggest type parameters after new
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97801">97801</a>
+[1.5][codeassist] The type of the class literal must be parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85384">85384</a>
+[1.5][assist] "extends" not proposed when writing method declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97219">97219</a>
+[1.5] eclipse does not detect ambiguous method invocation errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97744">97744</a>
+[compiler][ant adapter] NPE when verbose = true and destDir not specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97480">97480</a>
+[1.5][compiler] incorrect error on some calls to raw Map.Entry.setValue
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97809">97809</a>
+Ambiguous method reference wrongly reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97814">97814</a>
+Incorrect resolved information on hover
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97841">97841</a>
+[1.5][dom] null binding for ClassInstanceCreation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90916">90916</a>
+CCE in SourceTypeConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97466">97466</a>
+NPE in SourceTypeConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97307">97307</a>
+[5.0][typing] completion for "import static" deletes all source before
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97459">97459</a>
+CCE during reconcile and AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97800">97800</a>
+[1.5][compiler] Cast type shouldn't be used in generic method argument inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95349">95349</a>
+Access rule pattern matching should ignore file extension
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97161">97161</a>
+[1.5][compiler] Internal compiler error java.lang.NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97303">97303</a>
+[1.5][compiler] Cannot convert when inferring list of inner parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97272">97272</a>
+Export preferences offers "all" button, does not export classpath variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96794">96794</a>
+Polishing disassembler output
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97275">97275</a>
+method reference should not contain type variable anymore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97187">97187</a>
+[rendering] Shows Single Char for primitve Types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96918">96918</a>
+Code Assist - suggest extends and super in the context of a wildcard type argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97190">97190</a>
+Incorrect handling of large long values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97247">97247</a>
+ArrayIndexOutOfBoundsException in ClassFile.addSyntheticSwitchTable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76155">76155</a>
+[options] Unused code warning for unused methods in anonymous inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97224">97224</a>
+[polish][compiler] Inconsistent error message for non-visible field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95481">95481</a>
+[1.5] NPE in TypeVariableBinding.checkBounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65748">65748</a>
+[type hierarchy] Hierarchy view fails to pick up class modifier change
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96633">96633</a>
+getJavaElement returns null for Object[] array binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96605">96605</a>
+JDTCompilerAdapter should allow a log without all verbose information
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96858">96858</a>
+IllegalArgumentException in Signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97164">97164</a>
+classpath variables lost when upgrading from M7 to RC1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97139">97139</a>
+eclipse 3.1RC1 compiler crash for project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96974">96974</a>
+[5.0] @SuppressWarnings({"nls"}) does not work for unexternalized strings
+
+<a name="v_560"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005 - 3.1 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_560
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_560">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96646">96646</a>
+[1.5][compiler] VerifyError - Generics and Interfaces - "Wrong return type in function"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96631">96631</a>
+NPE in Annotation on empty ArrayInitializer
+
+
+<a name="v_559"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005
+<br>Project org.eclipse.jdt.core v_559
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_559">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95638">95638</a>
+[1.5][compiler] Possibly incorrect Bounds Mismatch errors for complicated bounds
+
+
+<a name="v_558"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005
+<br>Project org.eclipse.jdt.core v_558
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_558">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The Code Assist option CODEASSIST_HIDE_RESTRICTED_REFERENCES is replaced by
+CODEASSIST_FORBIDDEN_REFERENCE_CHECK and CODEASSIST_DISCOURAGED_REFERENCE_CHECK
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94403">94403</a>).
+</li>
+<li> Code Assist suggest all member types when completion token is a single name.
+<pre>
+Y&lt;complete here&gt; // p.q.X.Y is proposed.
+</pre>
+As all member types are proposed, code assist does not propose types of the wrong kind.
+Only classes are proposed inside an extends clause, only interfaces inside an implements clause
+and only annotations in annotation reference (It was necessary before to be able to propose
+a top level type which contains these types).<br>
+Note: To re-enabled quickly the old behaviors, change the value of Completion.PROPOSE_MEMBER_TYPES.
+</li>
+<li>Added API <code>JavaCore#initializeAfterLoad(IProgressMonitor)</code> to allow
+	 a client to force the initialization of internal structures.
+</li>
+<li>Default value for <code>COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING</code> and
+	<code>COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING</code> JavaCore options have been changed from "enabled" to "disabled".<br>
+	(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96270">96270</a>).
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75816">bug 75816</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>
+Duplicate names are not allowed in classpath entry extra attributes.<br>
+Javadoc comment of each <code>JavaCore.new*Entry</code> method have been updated to clearly specify this behavior:
+<pre>
+ * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+ * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * Note that this list should not contain any duplicate name.
+</pre>
+<code>JavaConventions.validateClasspathEntry(IJavaProject,IClasspathEntry,boolean,boolean)</code> has been modified
+to verify this point. It now returns an invalid status (<code>new IJavaStatus(IJavaModelStatusConstants.NAME_COLLISION,...)</code>)
+when duplicate names are found in extra attributes.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93119">93119</a>
+code assist: proposals for wildcard types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95505">95505</a>
+Can not use code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96698">96698</a>
+org.eclipse.jdt.core.dom.VariableBinding.getUnresolvedJavaElement produce ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88364">88364</a>
+compiler options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94267">94267</a>
+[1.5][select] Selecting type parameter in binary answer match on line 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96642">96642</a>
+CCE in SourceMapper.computeAllRootPaths(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87362">87362</a>
+BindingKey#internalToSignature() should return the field's type signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94404">94404</a>
+[model] Disallow classpath attributes with same key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92398">92398</a>
+[compiler] Leverage access rule support in batch compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96588">96588</a>
+Rename Signature#removeCaptureFromMethod(...) to removeCaptureFrom(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96410">96410</a>
+Incorrect information in selection resolved key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75816">75816</a>
+[search] Call Hierarchy does not find calls to the constructor of java.util.HashMap.Entry [call hierarchy]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95167">95167</a>
+[content assist] Spurious "Access restriction" error during code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95580">95580</a>
+CreateField on IType doesn't work if the type is an enum type that has enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95963">95963</a>
+(3.1M7) Compiler error when parameterizing with missing inner type.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96134">96134</a>
+Internal error for odd (probably illegal) class declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96464">96464</a>
+[assist] JavaCorePreferenceInitializer does not initialized CODEASSIST_DISCOURAGED_REFERENCE_CHECK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96414">96414</a>
+Javadoc of ASTParser#setCompilerOptions(..): mention that setProject(..) resets options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95933">95933</a>
+Refining a generic method causes AbstractMethodError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94897">94897</a>
+[1.5] Compiler does not reject class with two erasure-equivalent methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96213">96213</a>
+Eclipse 3.1M7 - Field completion stack overflow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96401">96401</a>
+jdt.core tests pass, but fill the .log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96439">96439</a>
+Hierarchy not refreshed if adding a dependent project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82852">82852</a>
+"Searching for errors in &lt;project&gt;" running unit tests from package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95154">95154</a>
+Missing package.html files for API packages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96387">96387</a>
+Schemas for extension points are inaccurate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93249">93249</a>
+Code assist doesn't propose full method stub
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94878">94878</a>
+Configuration details is large, containing many prefs for PDE and JDT classpath containers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96270">96270</a>
+[javadoc] Missing Javadoc comment: 'check overriding..' should be 'off' by default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96300">96300</a>
+Use the line separator platform preference for new files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94303">94303</a>
+import static adds annoying semicolon
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83716">83716</a>
+[search] refs to 2-arg constructor on Action found unexpected matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96071">96071</a>
+Javadoc for IJavaProject.findType(String ) is not consistant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94903">94903</a>
+Error setting method breakpoint in 1.5 project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88395">88395</a>
+[1.5][compiler] Binary compat problem with enum/switch codegen
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95727">95727</a>
+ITypeBinding#getJavaElement() returns a ResolvedSourceField for an anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95909">95909</a>
+Error with static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95794">95794</a>
+[1.5][search] Search for all occurrences does not find references in static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95911">95911</a>
+[5.0][dom] Wrong node range for variable declaration fragment containing anonymous class declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93941">93941</a>
+Classpath initialization on shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93731">93731</a>
+JDT core job still running after shutdown.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89849">89849</a>
+[1.5][assist] Completion in switch proposes already written enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91670">91670</a>
+package-info.java is not being correctly compiled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93880">93880</a>
+[1.5][javadoc] Source range of PackageDeclaration does not include Javadoc child
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93254">93254</a>
+[assist] ClassCastException when complete annotation type ref
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95760">95760</a>
+[1.5][search] MatchLocator does not compile against 5.0 JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93668">93668</a>
+Search indexes not rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95748">95748</a>
+SourceMapper should not write timing info to stdout
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92555">92555</a>
+Code assist in Annotations suggests non-annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92733">92733</a>
+[assist] Classes suggested in implements clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94965">94965</a>
+[assist] code assist should suggest inner types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92937">92937</a>
+Need API: JavaCore#initializeAfterLoad()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90215">90215</a>
+[1.5] Enums implementing generic interfaces can compile incorrectly.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95244">95244</a>
+performance optimization in SourceMapper.computeAllRootPaths
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91615">91615</a>
+Wrong class opened by debugger/"Open Type"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39856">39856</a>
+External jar's timestamps should be persisted accross sessions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89632">89632</a>
+Exception when trying to evaluate in Snippet Editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95538">95538</a>
+Operation not supported in JLS2 AST from resolving MethodBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95521">95521</a>
+[1.5][javadoc] validation with @see tag not working for generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95286">95286</a>
+[1.5][javadoc] package-info.java incorrectly flags "Missing comment for public declaration"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95388">95388</a>
+[code manipulation] NPE sorting members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94150">94150</a>
+[1.5][javadoc][enum] javadoc is always null for EnumConstantDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94653">94653</a>
+[1.5][select] Selection on invalid raw member type should still surface raw type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94092">94092</a>
+ASTParser#createASTs(..) restores wrong bindings from capture keys
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88719">88719</a>
+UserLibrary.serialize /createFromString need support for access restriction / attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89937">89937</a>
+[1.5][compiler] Annotation attribute should not be able to reference field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93891">93891</a>
+Restricted UIPlugin is in my code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93905">93905</a>
+Batch compiler - add a timestamp to log files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95262">95262</a>
+ASTParser fails with K_CLASS_BODY_DECLARATIONS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95211">95211</a>
+[api] stale J2SE5 comment in IDOMImport
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95431">95431</a>
+Code formatter fails to format this code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95394">95394</a>
+Problem resolving types for Assignment ("+=") on 3.1M7
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83034">83034</a>
+[1.5][compiler] method on A&lt;D,?&gt; not applicable for argument &lt;?&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87550">87550</a>
+[1.5] [compiler] The method in the type is not applicable for the arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95021">95021</a>
+[1.5][compiler] incorrectly inferred method type parameters bug in 3.1M6?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91588">91588</a>
+Delete CVS project and then add as source project leads to duplicate Open Type entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73969">73969</a>
+Full build on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80118">80118</a>
+[search] OutOfMemoryError while searching for Test class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87749">87749</a>
+different IMethodBindings of generic method have equal getKey()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94398">94398</a>
+Error attempting to find References
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93408">93408</a>
+ITypeBinding#isEqualTo(..) does not resolve type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94389">94389</a>
+[search] InvocationTargetException on Rename
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79990">79990</a>
+[1.5][search] Search for method declaration doesn't find method with instantiated type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95066">95066</a>
+[1.5][compiler] Wrong Cast Allowed
+
+
+<a name="v_557"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 12th May 2005 - 3.1 MILESTONE 7 / 3.1 RELEASE CANDIDATE 0
+<br>Project org.eclipse.jdt.core v_557
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_557">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94308">94308</a>
+[1.5][compiler] @SuppressWarnings("deprecation") does not suppress warnings from javadoc
+
+
+<a name="v_556"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 12th May 2005
+<br>Project org.eclipse.jdt.core v_556
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_556">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Enabled by default the optional compiler diagnosis to signal unhandled warning tokens in <code>@SuppressWarnings</code> annotations.
+Note that this warning can itself be turned off using @SuppressWarnings("warningToken").
+<pre>
+* COMPILER / Reporting Unhandled Warning Token for @SuppressWarnings
+*    When enabled, the compiler will issue an error or a warning when encountering a token
+*    it cannot handle inside a @SuppressWarnings annotation.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94718">bug 94718</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94928">94928</a>
+[1.5][compiler] NPE in ParameterizedGenericMethodBinding generated by making method generic
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93727">93727</a>
+Code Formatter fails with Method Parameter Annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93075">93075</a>
+Invalid source ranges for nested ParameterizedTypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92360">92360</a>
+type binding with isWildcardType() == true should not have isClass() == true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94168">94168</a>
+Java annotation is missing in EnumConstantDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94867">94867</a>
+[1.5][compiler] Annotation method should tolerate empty array default value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94747">94747</a>
+[1.5][compiler] Error message is not optimal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94718">94718</a>
+[1.5][search][annot] Find references in workspace breaks on an annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94644">94644</a>
+[1.5][compiler] Non-static member type of raw type should be raw
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94206">94206</a>
+CCE in BindingKeyResolver when restoring array type of method type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94260">94260</a>
+[Preferences] preference option missing in Compiler Settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94262">94262</a>
+[1.5] non static class must not be visible through static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93904">93904</a>
+Batch compiler -log option broken for some values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87627">87627</a>
+[1.5][search] references to type variable yield non-existent elements in search view
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93588">93588</a>
+[compiler] java.lang.VerifyError: Looks similar to 60040 but is happening on current release
+
+
+<a name="v_555"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 9th May 2005
+<br>Project org.eclipse.jdt.core v_555
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_555">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Code Assist provide the enclosing type reference when cursor is inside a type argument
+and the completion token is empty (in the same way as method calls).
+<pre>
+p.q.X&lt;&lt;complete here&gt;&gt; // p.q.X&lt;T,U&gt; is proposed.
+p.q.X&lt;Object, &lt;complete here&gt;&gt; //p.q.X&lt;T,U&gt; is proposed
+</pre>
+</li>
+<li> Code Assist provide the enclosing annotation reference when completion is inside an annotation argument
+and the completion token is empty (in the same way as method calls).
+<pre>
+@Annot(&lt;complete here&gt;) // p.Annot is proposed.
+@Annot(foo1=0, &lt;complete here&gt;) // p.Annot is proposed.
+</pre>
+</li>
+<li> In 5.0 compliant mode, changed local inner type naming convention to reflect JLS 13.1 (3rd edition).
+As a consequence, instead of generating a file named <code>X$1$A.class</code>, it will simply be <code>X$1A.class"</code>.
+</li>
+<li> Added optional compiler diagnosis to signal unhandled warning tokens in <code>@SuppressWarnings</code> annotations.
+Note that this warning can itself be turned off using @SuppressWarnings("warningToken").
+<pre>
+* COMPILER / Reporting Unhandled Warning Token for @SuppressWarnings
+*    When enabled, the compiler will issue an error or a warning when encountering a token
+*    it cannot handle inside a @SuppressWarnings annotation.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li> Added compiler option to control whether @SuppressWarning annotations are active or not.
+By disabling them, one can quickly revive all hidden warnings.
+<pre>
+* COMPILER / Determine whether @SuppressWarnings is effective
+*    When enabled, the @SuppressWarnings annotation can be used to suppress some compiler warnings. 
+*    When disabled, all @SupressWarnings annotations are ignored; i.e., warnings are reported.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.suppressWarnings"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "enabled"
+</pre>
+</li>
+<li> Added API on <code>CorrectionEngine</code> for computing the warning token corresponding to an optional warning ID.
+<pre>
+/**
+ * Returns a token which can be used to suppress a given warning using 
+ * <code>@SuppressWarnings</code> annotation, for a given problem ID 
+ * ({@link IProblem }). If a particular problem is not suppressable, 
+ * <code>null</code> will be returned. 
+ * 
+ * Note: <code>@SuppressWarnings</code> can only suppress warnings, 
+ * which means that if some problems got promoted to ERROR using custom compiler 
+ * settings ({@link IJavaProject#setOption(String, String)}), the 
+ * <code>@SuppressWarnings</code> annotation will be ineffective.
+ * 
+ * Note: <code>@SuppressWarnings</code> can be argumented with 
+ * <code>"all"</code> so as to suppress all possible warnings at once.
+ * 
+ * Note: The tokens returned are not necessarily standardized across Java 
+ * compilers. If you were to use one of these tokens in an @SuppressWarnings 
+ * annotation in the Java source code, the effects (if any) may vary from 
+ * compiler to compiler.
+ * 
+ * @param problemID
+ *         the ID of a given warning to suppress
+ * @return a String which can be used in <code>@SuppressWarnings</code> annotation, 
+ * or <code>null</code> if unable to suppress this warning.
+ * @since 3.1
+ */
+public static String getWarningToken(int problemID)
+</pre>
+</li>
+<li>More warning tokens are now recognized by <code>@SuppressWarnings</code>, see list below. Note that
+these are subject to changing in the near future.
+  <ul>
+     <li>all : any warning</li>
+     <li>boxing : autoboxing conversion</li>
+     <li>charConcat : char[] in String concat</li>
+     <li>conditionAssign : possible accidental boolean assignment</li>
+     <li>constructorName : method with constructor name</li>
+     <li>dep-ann : missing @Deprecated annotation</li>
+     <li>deprecation : deprecation outside deprecated code</li>
+     <li>emptyBlock : undocumented empty block</li>
+     <li>enumSwitch : incomplete enum switch</li>
+     <li>fieldHiding : field hiding another variable</li>
+     <li>finalBound : type parameter with final bound</li>
+     <li>finally : finally block not completing normally</li>
+     <li>indirectStatic : indirect reference to static member</li>
+     <li>intfAnnotation : annotation type used as super interface</li>
+     <li>intfNonInherited : interface non-inherited method compatibility</li>
+     <li>javadoc : invalid javadoc</li>
+     <li>localHiding : local variable hiding another variable</li>
+     <li>maskedCatchBlock : hidden catch block</li>
+     <li>nls : string literal lacking non-nls tag //$NON-NLS-&lt;n&gt;$</li>
+     <li>noEffectAssign : assignment without effect</li>
+     <li>over-ann : missing @Override annotation</li>
+     <li>pkgDefaultMethod : attempt to override package-default method</li>
+     <li>semicolon : unnecessary semicolon, empty statement</li>
+     <li>serial : missing serialVersionUID</li>
+     <li>unqualifiedField : unqualified reference to field</li>
+     <li>unchecked : unchecked type operation</li>
+     <li>unusedArgument : unread method parameter</li>
+     <li>unusedImport : unused import declaration</li>
+     <li>unusedLocal : unread local variable</li>
+     <li>unusedPrivate : unused private member declaration</li>
+     <li>unusedThrown : unused declared thrown exception</li>
+     <li>unnecessaryElse : unnecessary else clause</li>
+     <li>uselessTypeCheck : unnecessary cast/instanceof operation</li>
+     <li>specialParamHiding : constructor or setter parameter hiding another field</li>
+     <li>staticReceiver : non-static reference to static member</li>
+     <li>syntheticAccess : synthetic access for innerclass</li>
+     <li>typeHiding : type parameter hiding another type</li>
+     <li>varargsCast : varargs argument need explicit cast</li>
+     <li>warningToken : unhandled warning token</li>
+  </ul>
+</li>
+<li>
+SearchMatch now has a implicit field which shows whether the associated element is implicit or not
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94062">94062</a>).<br>
+Added new API methods to access this field:
+<ul>
+<li><code>SearchMatch#isImplicit()</code><br></li>
+<li><code>SearchMatch#setImplicit(boolean)</code></li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94053">94053</a>
+[javadoc] Unknown references are not warned for string or href in @see/@link tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94111">94111</a>
+[assist] provide parameter hints for template instantiations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94062">94062</a>
+[1.5][search][annot] search for annotation elements incorrect match range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93392">93392</a>
+[1.5][search] Reference to implicit annotation element "value" has wrong offset
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84968">84968</a>
+[1.5][generics] Exception type handling broken in latest milestone
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75885">75885</a>
+[1.5][compiler] Naming convention for local innerclasses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89426">89426</a>
+provide Java class file content type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93826">93826</a>
+ArrayIndexOutOfBoundsException when opening type hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83739">83739</a>
+[1.5] support @SuppressWarnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89850">89850</a>
+Duplicate strings of VM path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83750">83750</a>
+[perf] Excessive File.isFile calls for clients of JavaModel.getTarget(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92210">92210</a>
+[search] Search for method declaration in working set (source folder) searches in whole project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93913">93913</a>
+wrong resolved type caused by a static import
+
+
+<a name="v_554"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 6th May 2005
+<br>Project org.eclipse.jdt.core v_554
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_554">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Code Assist doesn't propose anymore type completion when completion token is empty.<br>
+Note: the code to propose completion when token is empty is not removed.
+Change the value of Completion.NO_TYPE_COMPLETION_ON_EMPTY_TOKEN to re-enabled this behavior.
+</li>
+<li>@SuppressWarnings is now supported. Recognized warning names are: <code>"all"</code>, <code>"deprecation"</code>,
+<code>"serial"</code>, <code>"unchecked"</code>, <code>"finally"</code>.
+</li>
+<li>Changed Code Assist options.<br>
+    CODEASSIST_FORBIDDEN_REFERENCE_CHECK and CODEASSIST_DISCOURAGED_REFERENCE_CHECK are replaced by CODEASSIST_HIDE_RESTRICTED_REFERENCES.<br>
+    <pre>
+/*
+ *  CODEASSIST / Hide Proposals for Restricted Completions
+ *    When value is "never", never hide proposals for restricted completions.
+ *    When value is "error", hide proposals for restricted completions if insertion of these completions would create a compile error.
+ *    When value is "warning", hide proposals for restricted completions if insertion of these completions would create a compile error or warning.
+ *    To configure the severity of restrictions, "org.eclipse.jdt.core.compiler.problem.forbiddenReference"
+ *    option must be used for forbidden reference and "org.eclipse.jdt.core.compiler.problem.discouragedReference"
+ *    option must be used for discouraged reference.
+ *     - option id:         "org.eclipse.jdt.core.codeComplete.restrictionsCheck"
+ *     - possible values:   { "never", "error", "warning" }
+ *     - default:           "error"
+ */
+ public static final String CODEASSIST_HIDE_RESTRICTED_REFERENCES;
+    </pre></li>
+<li>Removed 3.1 APIs <code>BindingKey#getDeclaringTypeSignature()</code> and
+    <code>BindingKey#toSignature()</code> as they were found error prone. See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93105">bug 93105</a>
+    for details.</li>
+<li>Added support for 'capture' inside Code Assist. Delaring type of a completion proposal is captured for qualified completion.</li>
+<li>Added APIs to replace a range of moved nodes (<code>ListRewrite#createMoveTarget(first, last, replacingNode, editGroup)</code>). 
+    See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91938">bug 91938</a> for details.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93854">93854</a>
+IAE in Util.scanTypeSignature when scanning a signature retrieved from a binding key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93662">93662</a>
+Singature#getTypeParameters returns strange signature string
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93113">93113</a>
+Opening the Type Hierarchy of Object uses 400M of heap
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92071">92071</a>
+Duplicate entry on classpath with -promiscuous mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93486">93486</a>
+[compiler] Wrong compile errors reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93487">93487</a>
+IType#findMethods fails on vararg methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90186">90186</a>
+resolved key of methods should contain parametrized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88082">88082</a>
+ASTParser#createASTs(..) does not use the given progress monitor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90612">90612</a>
+Forbidden types must not be available in Code Assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93105">93105</a>
+Remove unnecessary APIs on BindingKey
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93396">93396</a>
+[1.5] problem with recovery and enum constant body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92899">92899</a>
+Empty extra attributes list should not appear in .classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93275">93275</a>
+Need ITypeBinding#getDeclaringClass() for capture types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93298">93298</a>
+[1.5][compiler] nested statics and templates compilation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92477">92477</a>
+[1.5][compiler] Internal compiler error: NullPointerException in ReferenceBinding.findSuperTypeErasingTo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83083">83083</a>
+[1.5][compiler] NPE while checking bounds of type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93204">93204</a>
+[1.5][compiler] EnumSet.of within generic class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90775">90775</a>
+[1.5][compiler] Missing unchecked warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88202">88202</a>
+Javadoc: clarify ITypeBinding#getTypeBounds()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93093">93093</a>
+[1.5][dom] Capture binding "? extends Number[]" has bound Object instead of Number[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93102">93102</a>
+[1.5] Cannot restore capture binding from binding key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93082">93082</a>
+[1.5][compiler] Eclipse accepts assignment between captures with array-type bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91467">91467</a>
+[1.5][compiler] Eclipse asks for and then complains about unnecessary cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92982">92982</a>
+[1.5][compiler] Bounds and erasure of capture and type variable bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84690">84690</a>
+[assist] CompletionProposal.getDeclarationSignature returns null for array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92821">92821</a>
+[javadoc] Organize Imports - M6 - incorrectly retains import when only referered to in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91542">91542</a>
+[1.5][search] JavaModelException on ResolvedSourceMethod during refactoring
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92981">92981</a>
+Content Assist overrides wrong method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91619">91619</a>
+Extraneous exported package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92872">92872</a>
+[api] API constants renamed in IProblem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92888">92888</a>
+ITypeBinding#isEqualTo(..) is wrong for capture bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84224">84224</a>
+Need advice for finding duplicate Types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92944">92944</a>
+[1.5][search] SearchEngine#searchAllTypeNames doesn't honor enum or annotation element kind
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91078">91078</a>
+[search] Java search for package reference wrongly identifies inner class as package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92005">92005</a>
+AIOBE during content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67139">67139</a>
+[classpath] n^2 classpath computations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80063">80063</a>
+code assist allows overriding super class' private method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82208">82208</a>
+[search] BasicSearchEngine#searchAllTypeNames doc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3336">3336</a>
+SearchEngine doesn't support CLASS and INTERFACE (1GIEPRK)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90160">90160</a>
+[search] SearchEngine.createJavaSearchScope swallows problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88174">88174</a>
+[1.5][search][enum] method declarations not found in anonymous enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91938">91938</a>
+[ast rewrite] new API: move range of nodes and replace
+
+<a name="v_553"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 26th April 2005
+<br>Project org.eclipse.jdt.core v_553
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_553">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed the need to load <code>java.lang.RuntimeException</code> and <code>java.lang.Error</code> eagerly
+during compilation when assessing unchecked exception diagnosis. This allows Java class library developpers to be 
+more minimalistic.
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83230">bug 83230</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added support for Javadoc in package-info.java. Compiler now verifies package comment tags
+syntax and references for this compilation unit. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83804">83804</a> for 
+further details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91761">91761</a>
+[1.5][compiler] Return statements ignored in anonymous inner classes used as enum constant constructor parameters.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84049">84049</a>
+[javadoc][dom] Extended ranges wrong for method name without return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82673">82673</a>
+[search] Refactor-&gt;Rename on local class also renames references to different local classes with same name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81062">81062</a>
+[builder] Build is aborted even when no errors are occuring (incomplete build path == warning)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83012">83012</a>
+[1.5][search][annot] Search for annotations misses references in default and values constructs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92588">92588</a>
+Full build in reaction to beginRule failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92451">92451</a>
+code assist failure: new+cast+arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92373">92373</a>
+[1.5] Can't distinguish capture ITypeBindings by #getKey() or #isEqualTo()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92370">92370</a>
+[1.5] IAE in Signature.getParameterCount(..) for method proposal on capture type receiver
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92361">92361</a>
+[1.5] NPE in ITypeBinding#getJavaElement() for capture binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92315">92315</a>
+[search] NPE in MethodLocator.matchReportReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86380">86380</a>
+[1.5][search][annot] Add support to find references inside annotations on a package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83804">83804</a>
+[1.5][javadoc] Missing Javadoc node for package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83501">83501</a>
+IBinding#getJavaElement needs better specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83230">83230</a>
+[1.5][search][annot] search for annotation elements does not seem to be implemented yet
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89624">89624</a>
+Open on selection proposes twice the same entry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92237">92237</a>
+IType resolved key: key.toSignature has wrong format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91804">91804</a>
+JavaProject.isOnClasspath(IJavaElement) should avoid resolving classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92059">92059</a>
+IVariableBinding#getJavaElement() thows NPE for array's 'length' field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84551">84551</a>
+[1.5][compiler] compiler must not allow implicit static reference to outer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89440">89440</a>
+[1.5][problems] Reference to member of parameterized type incorrectly marked as error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84973">84973</a>
+[1.5] parameterized inner type is illegal without parameterized  outer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90484">90484</a>
+[1.5][compiler] Missing override annotation conflicts with Javac error checking
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81831">81831</a>
+[1.5][compiler] JDT compiler tries to infer the wildcard type "too early" in case of recursive generic type-bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89274">89274</a>
+[1.5][compiler] Enums in hierarchies with generics produces unnecessary warnings and errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90137">90137</a>
+[1.5][compiler] Collections.sort (List&lt;Comparable&gt;) compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90879">90879</a>
+[1.5][compiler] Cannot sort a raw Comparable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85281">85281</a>
+[1.5][compiler]  A&lt;++Element&gt; should not be assignable a  A&lt;+Element&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91091">91091</a>
+[quick assist] Cannot rename type name in file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90881">90881</a>
+[1.5][compiler] NPE in builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84496">84496</a>
+[1.5][compiler] Capture Conversion not correctly implemented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92086">92086</a>
+[index] ClassCastException in DiskIndex.mergeCategory()
+
+<a name="v_552"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 20th April 2005
+<br>Project org.eclipse.jdt.core v_552
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_552">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91772">91772</a>
+Exported plugin dependencies are missing from the classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88769">88769</a>
+IMethodBinding#getJavaElement() drops extra array dimensions and varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88892">88892</a>
+[1.5] IMethodBinding#getJavaElement() returns nonexistent IMethods (wrong parameter types)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91445">91445</a>
+IMethodBinding.getJavaElement() returns an "unopen" IMethod
+	  	
+<a name="v_551"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 19th April 2005
+<br>Project org.eclipse.jdt.core v_551
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_551">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added performance instrumentation to track performance problem (use PerformanceStats from Core).<br>
+To enabled this Jdtcore instrumentation, you must add some new entries inside .options.
+<ul>
+<li><code>org.eclipse.jdt.core/perf/completion=300</code>: add an entry to performance.log if CompletionEngine.complete() take more than 300ms</li>
+<li><code>org.eclipse.jdt.core/perf/selection=300</code> add an entry to performance.log if SelectionEngine.select() take more than 300ms</li>
+<li><code>org.eclipse.jdt.core/perf/javadeltalistener=500</code> add an entry to performance.log if the call to the listener take more than 500ms</li>
+<li><code>org.eclipse.jdt.core/perf/variableinitializer=5000</code> add an entry to performance.log if the initialization take more than 5000ms</li>
+<li><code>org.eclipse.jdt.core/perf/containerinitializer=5000</code> add an entry to performance.log if the initialization take more than 5000ms</li>
+<li><code>org.eclipse.jdt.core/perf/reconcile=1000</code> add an entry to performance.log if ComplationUnit.reconcile() take more than 1000ms</li>
+</ul>
+Current default thresholds are not accurate and must be adjusted.
+</li>
+<li>Added support for completion inside single member annotation and annotation attribute value.
+<pre>
+@MyAnnotation(&lt;complete here&gt;
+@MyAnnotation(foo=&lt;complete here&gt;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91861">91861</a>
+Deadlock on startup while computing namelookup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89411">89411</a>
+ICompilationUnit#becomeWorkingCopy takes 18% of startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91716">91716</a>
+[prefs] Too many calls to EclipsePreference#get while scanning full workspace units
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90615">90615</a>
+Proposal for boolean
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84877">84877</a>
+Performance on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91497">91497</a>
+[prefs] JavaCore should not give access to default preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90414">90414</a>
+[content assist] Content Assist fails when escape sequence present
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91438">91438</a>
+Need definitive set of jdt-core tests checked into cvs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91498">91498</a>
+Reconcile still sees old access rules
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91221">91221</a>
+Code assist stopped working
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91371">91371</a>
+[assist] Stack Overflow - Field completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91098">91098</a>
+The Mark Occurrences feature does not mark all occurrences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79288">79288</a>
+Code assist offers types which are out of scope ==&gt; compile errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88298">88298</a>
+[1.5][assist] no completion inside SingleMemberAnnotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91238">91238</a>
+Malfunction of Format function
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91160">91160</a>
+SourceField.getConstant() incorrect for char constants
+
+<a name="v_550"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 12th April 2005
+<br>Project org.eclipse.jdt.core v_550
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_550">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90431">bug 90431</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89096">89096</a>
+Convert to new platform NLS support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90302">90302</a>
+[javadoc] {@inheritedDoc} should be inactive for non-overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90779">90779</a>
+[search] Constructor Declaration search with ignoring declaring and return type also ignores type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90915">90915</a>
+[1.5][search] NPE in PatternLocator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90266">90266</a>
+[select] Code select returns null when there's a string including a slash on same line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90605">90605</a>
+Severity is not severe enough
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89470">89470</a>
+Generic Method override compatibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90446">90446</a>
+Update CreateTypeMemberOperation for changes in Indents 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90431">90431</a>
+Improve path lookup in scopes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90423">90423</a>
+[1.5][compiler] Generic method overloading. Javac allows but eclipse doesn't
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90213">90213</a>
+[Formatter] Redundant space in multidimensional array literals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88263">88263</a>
+[1.5][compiler] Autobox and extends
+
+
+<a name="v_549"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M7 - 5th April 2005
+<br>Project org.eclipse.jdt.core v_549
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_549">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89815">89815</a>
+Types not found using Open Type and search for declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77809">77809</a>
+[format] Line wrapping for enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49896">49896</a>
+Formatters should have option to use tabs only for leading indents.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89777">89777</a>
+Improve doc formatting for IMethodBinding.getMethodDeclaration()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90111">90111</a>
+[1.5][compiler] Compiler warning "tagged with @Override" not correct with static methods
+
+<a name="v_548"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 1st April 2005
+<br>Project org.eclipse.jdt.core v_548 - 3.1 MILESTONE 6
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_548">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+New Code Formatter built-in profile has been added: "Eclipse [built-in]".<br>
+This new profile is based on "Java Conventions" but uses tab character (instead of space) and set tab size to 4 (instead of 8).<br>
+JavaCore was using these values by default but they were wrongly showed as "Java Conventions" in Code Formatter
+preference page. This problem is now fixed (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89739">89739</a>).<br>
+Code formatter behavior is still fully compatible with previous milestones for users who have not modified Code Formatter
+options in their workspace. However, users who have explicitely modified them and have troubles with use of tab character,
+should open Code Formatter preference page and either select this new "Eclipse" profile or verify state of "Use of tab character"
+check-box.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89982">89982</a>
+[1.5][compiler] Internal failure during missing enum  case diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89848">89848</a>
+[search] does not find method references in anonymous class of imported jarred plugin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89778">89778</a>
+NPE in bindThrownExceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89710">89710</a>
+[compiler] local variable range is wrong.
+
+
+<a name="v_547"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 31st March 2005
+<br>Project org.eclipse.jdt.core v_547
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_547">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89739">89739</a>
+[prefs] Default for formatter should be Tab characters, not spaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89448">89448</a>
+Java Generics code throws a java.lang.NoClassDefFoundError
+
+
+<a name="v_546"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 31st March 2005
+<br>Project org.eclipse.jdt.core v_546
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_546">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In order to fix bugs <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=49896">49896</a> and <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=77809">77809</a>, we added the following
+two APIs:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS</code></li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89477">89477</a>
+[1.5][select] ArrayStoreException in SelectionEngine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73658">73658</a>
+[1.5] Not all new 1.5 formatter options seem to work
+
+<a name="v_545"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 29th March 2005
+<br>Project org.eclipse.jdt.core v_545
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_545">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81497">81497</a>
+[format] Wrong feeding after array-initialization
+
+<a name="v_544"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 29th March 2005
+<br>Project org.eclipse.jdt.core v_544
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_544">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In order to fix <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73104">73104</a>, we have added the following new API:
+<ul><li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INDENTATION_SIZE</code></li>
+<li>Added new API <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#MIXED</code>. This new constant is used for the option:
+<code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR</code>.</li>
+</ul>
+</li>
+<li>Added new API on <code>org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringMethod()</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86580">86580</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89312">89312</a>
+API: BindingKey should probably be final
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89318">89318</a>
+[formatter] Option FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89302">89302</a>
+[formatter] Insert space after comma in enum constants has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73104">73104</a>
+[format] indentation amount tied to tab size
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84872">84872</a>
+Improve string sharing in JavaModelCache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68148">68148</a>
+[model] Leaking persisted containers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89110">89110</a>
+Redundant information in SourceTypeElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89092">89092</a>
+Redundant information in ImportDeclarationElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89090">89090</a>
+Redundant information in SourceFieldElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89014">89014</a>
+IMethodBinding#isEqualTo(..) returns true for methods in different anonymous classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86580">86580</a>
+API on ITypeBinding for asking about the declaring node of type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88575">88575</a>
+[1.5] treatment of Object.getClass() not API compliant
+
+<a name="v_543"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 24th March 2005
+<br>Project org.eclipse.jdt.core v_543
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_543">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new kinds for the code formatter:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_SINGLE_LINE_COMMENT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_MULTI_LINE_COMMENT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_JAVA_DOC</code></li>
+</ul>
+</li>
+<li>Added new options to format comments:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_CLEAR_BLANK_LINES</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_HEADER</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_HTML</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_SOURCE</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INDENT_ROOT_TAGS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_LINE_LENGTH</code></li>
+</ul>
+</li>
+<li>Added constant for the javadoc location attribute name: <code>IClasspathAttribute#JAVADOC_LOCATION_ATTRIBUTE_NAME</code>.</li>
+<li>Added API to create an array type binding key from a type key and array dimension: <code>BindingKey#createArrayTypeBindingKey(String typeKey, int arrayDimension)</code></li>
+<li>Added API to create a binding key from a type name: <code>BindingKey#createTypeBindingKey(String typeName)</code>.</li>
+<li>Added API to create a parameterized or raw type binding key from a generic type binding key and argument type binding keys:
+    <code>BindingKey#createParameterizedTypeBindingKey(String genericTypeKey, String[] argumentTypeKeys)</code>.</li>
+<li>Added API to create a type variable binding key from a type variable name and a declaring key: <code>createTypeVariableBindingKey(String typeVariableName, String declaringKey)</code></li>
+<li>Added API to create a wildcard binding key from a type key and wildcard kind: <code>BindingKey#createWildcardTypeBindingKey(String typeKey, char kind)</code></li>
+<li>Added API to query whether a field is an enum constant: <code>IField#isEnumConstant()</code></li>
+<li>Added API to code assist for access rule management.
+<ul>
+<li>Added JavaCore#CODEASSIST_FORBIDDEN_REFERENCE_CHECK and JavaCore#CODEASSIST_DISCOURAGED_REFERENCE_CHECK options</li>
+<li>Removed JavaCore#CODEASSIST_RESTRICTIONS_CHECK (Replaced by CODEASSIST_FORBIDDEN_REFERENCE)</li>
+<li>Added CompletionProposal#getAccessibility()</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89088">89088</a>
+[performance] Scanner is sending 2 messages per identifier character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83502">83502</a>
+Need API to create binding keys.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88845">88845</a>
+NPE in codeComplete for supertype that extends invisible type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70827">70827</a>
+[Search] wrong reference match to private method of supertype
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88300">88300</a>
+[search] Reference search result is changed by placement of private method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87173">87173</a>
+Surface compiler information about boxing/unboxing in the DOM AST (implicit conversion)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88841">88841</a>
+IAE while opening ASTView
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88548">88548</a>
+Need to get constant value on expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88921">88921</a>
+[Formatter] Adopt comment formatter from JDT/UI inside JDT/Core API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88849">88849</a>
+Infinite loop in scanner when using eof=Integer.MAX_VALUE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88859">88859</a>
+Constant for the name of the Javadoc attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71460">71460</a>
+[model] Non *.java file association with Java contents.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88756">88756</a>
+[codeassist] Code assist propose anonymous enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76863">76863</a>
+[1.5][model] IField should offer a method isEnumConstant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88757">88757</a>
+[API] SwitchStatement.statements() returns list of SwitchGroups
+
+<a name="v_542"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 22nd March 2005
+<br>Project org.eclipse.jdt.core v_542
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_542">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The internal build state format has changed and a full build is expected when restarting an existing workspace with this version of JDT Core.</li>
+<li>Added the following APIs to control access rules severity:
+     <ul>
+     <li><code>org.eclipse.jdt.core.IAccessRule</code>
+           <ul>
+           <li><code>int K_ACCESSIBLE;</code></li>
+           <li><code>int K_NON_ACCESSIBLE;</code></li>
+           <li><code>int K_DISCOURAGED;</code></li>
+           <li><code>IPath getPattern();</code></li>
+           <li><code>int getKind();</code></li>
+           </ul>
+      </li>
+      <li><code>org.eclipse.jdt.core.JavaCore</code>
+           <ul>
+           <li><code>String COMPILER_PB_DISCOURAGED_REFERENCE;</code></li>
+           <li><code>IAccessRule newAccessRule(IPath pattern, int kind);</code></li>
+           <li><code>IClasspathEntry newContainerEntry(
+							IPath containerPath, 
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newLibraryEntry(
+							IPath path,
+							IPath sourceAttachmentPath,
+							IPath sourceAttachmentRootPath,
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newProjectEntry(
+							IPath path, 
+							IAccessRule[] accessRules, 
+							boolean combineAccessRules,
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newVariableEntry(
+							IPath variablePath,
+							IPath variableSourceAttachmentPath,
+							IPath variableSourceAttachmentRootPath,
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           </ul>
+      </li>
+      <li><code>org.eclipse.jdt.core.IClasspathEntry</code>
+            <ul>
+           <li><code>boolean combineAccessRules();</code>
+           <li><code>IAccessRule[] getAccessRules();</code>
+           </ul>
+      </li>
+      </ul>
+</li>
+<li>Code select now works into Javadoc comment wherever a reference can be specified
+(i.e. @see, @link, @linkplain, @throws, @exception, @param or @value tags)<br>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54968">54968</a>).<br>
+For example, hit F3 with cursor located in <code>MyClass</code>, in following Javadoc comment:
+<pre>
+/**
+ * @see MyClass This is my class
+ */
+</pre>
+will open editor on MyClass.java file.
+</li>
+<li>New CodeSelect feature: Code select return an element if the selection is an enum constant inside a switch label.
+<pre>
+Colors c;
+swith(c) {
+  case BLUE:
+  case RED; // select RED
+}
+</pre>
+</li>
+<li>Added new kind of type signature: <code>Signature#WILDCARD_TYPE_SIGNATURE</code>.<br>
+<code>Signature#getTypeSignatureKind(char[])</code> and <code>Signature#getTypeSignatureKind(String)</code>
+now return <code>Signature#WILDCARD_TYPE_SIGNATURE</code> if the signature is a wildcard : * or +Ljava.lang.Object; or -Ljava.lang.Object;
+</li>
+<li>Added new completion API to describe context in which the completion occurs.<br>
+Currently only the expected types of the potential completion proposals are proposed.
+<pre>
+ X x = zzz&lt;complete here&gt;
+</pre>
+In this example the expected type is <code>X</code>. It is not mandatory to a proposal
+to respect this expectation and it is possible that there is no completion proposal.
+<pre>
+public class CompletionContext  {
+  public char[][] getExpectedTypesSignatures() {...}
+  public char[][] getExpectedTypesKeys() {...}
+}
+</pre>
+Client must override <code>CompletionRequestor#acceptContext(..)</code> to know the context.
+This method call ocurs after the call to <code>beginReporting()</code> and before the call to any
+<code>accept(CompletionProposal)</code> method.
+<pre>
+public class CompletionRequestor {
+  ...
+  public void acceptContext(CompletionContext context) {..}
+  ...   
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87644">87644</a>
+Control access rules severity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88625">88625</a>
+[1.5][compiler] Invalid Enum comparing (Build id: I20050219-1500)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87998">87998</a>
+[1.5][compiler] Enum constants generate warnings about synthetic constructor access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88562">88562</a>
+Internal compiler error when compiling GNU Classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88295">88295</a>
+[1.5][assist] too many completion on enum case label
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88446">88446</a>
+[1.5] annotations declared inside generic classes are not visible at runtime
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54968">54968</a>
+[javadoc][select] ICodeAssist#codeSelect doesn't work for member references in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85379">85379</a>
+[1.5][select][enum] Code resolve on enum in switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88429">88429</a>
+Redundant information in SourceMethodElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88428">88428</a>
+Class file reader's method info still hold on byte array
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88223">88223</a>
+[1.5][compiler] Local enums are not reported as error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88224">88224</a>
+[1.5][DOM] ASTRewriteAnalyzer blows up with local enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86971">86971</a>
+[1.5][codeselect] F3 should perform if selecting '@Deprecated'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85713">85713</a>
+Signature.getTypeSignatureKind does not like wildcard types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87762">87762</a>
+[model] suspicious huge amount of IPackageFragmentRoot[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88252">88252</a>
+Deleting a MemberValuePair with a NormalAnnotation child does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87818">87818</a>
+[compiler] local enums are illegal, but does this need to be a syntax error?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>
+[dom] deprecate JLS2 once JLS3 is fully supported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81797">81797</a>
+NPE in SortElementBuilder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80036">80036</a>
+EmptyStackException in CompilationUnitSorter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88187">88187</a>
+Unexpected deprecation warnings during full build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88094">88094</a>
+[1.5] compiler accepts two methods with same erasure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86970">86970</a>
+[codeassist] Add an API on completion proposal API to surface the expected type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88124">88124</a>
+More deprecated warnings than expected
+
+
+
+<a name="v_541"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 15th March 2005
+<br>Project org.eclipse.jdt.core v_541
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_541">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+
+<li>Compiler now recognizes <code>@Deprecated</code> annotations, and treats them equivalent
+to doc comment <code>/** @deprecated */</code>.
+</li>
+<li>Added optional compiler diagnosis to flag deprecated constructs missing a proper
+<code>@Deprecated</code> annotation (to encourage using annotations instead of doc comment tag).
+Corresponding problem IDs are: <code>IProblem.FieldMissingDeprecatedAnnotation</code>,
+<code>IProblem.MethodMissingDeprecatedAnnotation</code>,
+<code>IProblem.TypeMissingDeprecatedAnnotation</code>.
+<pre>
+* COMPILER / Reporting Missing @Deprecated Annotation
+*    When enabled, the compiler will issue an error or a warning whenever encountering a declaration
+*    carrying a @deprecated doc tag but has no corresponding @Deprecated annotation.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"     
+</pre>
+</li>
+<li>JLS2 API have been deprecated (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>).</li>
+<li>Allowed javadoc reference to varargs methods (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87845">87845</a>).<br>
+The 1.5 spec for the Javadoc tool does not mention the possibility
+of a variable arity indicator in method references. However, the 1.5
+Javadoc tool itself does indeed support it. Since it makes sense to have
+a way to explicitly refer to variable arity methods, it seems more likely
+that the Javadoc spec is wrong in this case.<br>
+Following API methods were added to <code>MethodRefParameter</code>:
+<pre>
+/**
+ * The "varargs" structural property of this node type (added in JLS3 API).
+ * @since 3.1
+ */
+public static final SimplePropertyDescriptor VARARGS_PROPERTY;
+/**
+ * Returns whether this method reference parameter is for
+ * the last parameter of a variable arity method (added in JLS3 API).
+ * 
+ * Note that the binding for the type <code>Foo</code>in the vararg method
+ * reference <code>#fun(Foo...)</code> is always for the type as 
+ * written; i.e., the type binding for <code>Foo</code>. However, if you
+ * navigate from the MethodRef to its method binding to the
+ * type binding for its last parameter, the type binding for the vararg
+ * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+ * the way vararg methods get compiled.
+ * 
+ * 
+ * @return <code>true</code> if this is a variable arity parameter,
+ *    and <code>false</code> otherwise
+ * @exception UnsupportedOperationException if this operation is used in
+ * a JLS2 AST
+ * @since 3.1
+ */ 
+public boolean isVarargs();
+/**
+ * Sets whether this method reference parameter is for the last parameter of
+ * a variable arity method (added in JLS3 API).
+ * 
+ * @param variableArity <code>true</code> if this is a variable arity
+ *    parameter, and <code>false</code> otherwise
+ * @since 3.1
+ */ 
+public void setVarargs(boolean variableArity);
+</pre>
+</li>
+<li>Added new flags on nature of match to specify that declaring or return type should be ignored during the search
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80264">80264</a>).<br>
+These flags are defined on <code>IJavaSearchConstants</code> interface:
+<pre>
+/**
+ * Ignore declaring type while searching result.
+ * Can be used in conjunction with any of the nature of match.
+ * @since 3.1
+ */
+int IGNORE_DECLARING_TYPE = 0x10;
+/**
+ * Ignore return type while searching result.
+ * Can be used in conjunction with any of the nature of match.
+ * Note that:
+ * 	- for fields search, pattern will ignore field type
+ * 	- this flag will have no effect for types search
+ * @since 3.1
+ */
+int IGNORE_RETURN_TYPE = 0x20;
+</pre>
+Note that these flags are active only for search of declarations (i.e. <code>IJavaSearchConstants.DECLARATIONS</code> and <code>IJavaSearchConstants.ALL_OCCURRENCES</code>)
+and while searching for IJavaElement (see doc of <code>SearchPattern.createPattern(IJavaElement, int)</code> API method).
+</li>
+<li>Improved API for type name requestor. Abstract class <code>TypeNameRequestor</code> replaces interface <code>ITypeNameRequestor</code> which is deprecated.<br>
+There's now only a single method for type name requestor while accepting a type:
+<pre>
+/**
+ * Accepts a top-level or a member type.
+ *
+ * The default implementation of this method does nothing.
+ * Subclasses should override.
+ *
+ * @param modifiers the modifier flags of the type. Note that for source type,
+ *	these flags may slightly differ from thoses get after resolution.
+ *	For example an interface defined by <code>interface A {}</code>, although obviously public,
+ *	will be returned false by <code>Flags.isPublic(modifiers)</code> due to the fact
+ *	that its declaration does not explicitely define <code>public</code> flag.
+ *	@see org.eclipse.jdt.core.Flags
+ * @param packageName the dot-separated name of the package of the type
+ * @param simpleTypeName the simple name of the type
+ * @param enclosingTypeNames if the type is a member type, 
+ *	the simple names of the enclosing types from the outer-most to the
+ *	direct parent of the type (for example, if the class is x.y.A$B$C then
+ *	the enclosing types are [A, B]. This is an empty array if the type
+ *	is a top-level type.
+ * @param path the full path to the resource containing the type. If the resource is a .class file
+ *	or a .java file, this is the full path in the workspace to this resource. If the
+ *	resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+ *	by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>: 
+ *	the first path is the full OS path to the archive (if it is an external archive), 
+ *	or the workspace relative <code>IPath</code> to the archive (if it is an internal archive), 
+ *	the second path is the path to the resource inside the archive.
+ */
+public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path)
+</pre>
+Clients can now distinguish Annotation, Enum, Interface and Class using <code>Flags</code> API methods on <code>modifiers</code> parameter.
+</li>
+<li>Added support for package-info.java. This allows to define annotations on the package declaration. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86167">86167</a> for 
+further details.</li>
+<li>Added API <code>JavaCore#newProjectEntry(IPath, IPath[], IPath[], boolean, IClasspathAttribute[], boolean)</code>
+      that take a 'combineAccessRestrictions' flag to control whether access restrictions of exported libraries of the project
+      should be combined with the access restrictions of this project entry.
+</li>
+<li>Added API method <code>AST#newName(String qualifiedName)</code> for creating 
+<code>SimpleName</code> or <code>QualifiedName</code>
+nodes depending on the form of the given name string.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83643">83643</a>
+[1.5] @Deprecated members not 'slashed'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86291">86291</a>
+[1.5][compiler] Annotation attribute see members of the annotated type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>
+[dom] deprecate JLS2 once JLS3 is fully supported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77349">77349</a>
+[compiler] ClassFormatError when accessing clone() or finalize() methods from an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87956">87956</a>
+compiling error on jdk1.5 collection generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87900">87900</a>
+Error 'Requesting Java AST from selection': Bug in the Java AST parser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87754">87754</a>
+[1.5][javadoc][dom] Type of ArrayType component type inside MethodRef has no binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87845">87845</a>
+[1.5][dom][javadoc] allow javadoc references to vararg methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87778">87778</a>
+[search] doesn't find all declarations of method with covariant return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80264">80264</a>
+[search] Search for method declarations in workspace, disregarding declaring type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85924">85924</a>
+[1.5][compiler[ code generation error in M5 w/regard to generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87849">87849</a>
+[AST] SimpleName.setIdentifier() not detecting bogus identifiers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86779">86779</a>
+AST#resolveWellKnownType(..) should support primitive type wrappers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85900">85900</a>
+[1.5] [compiler] internal compiler reports name clash
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87777">87777</a>
+Bindings.isEqualTo returns false for equal bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86902">86902</a>
+[1.5][compiler] Raw field access is not flagged as unsafe type operation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81498">81498</a>
+[search] ITypeNameRequestor should support enums and annotations as well
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87490">87490</a>
+Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85491">85491</a>
+[1.5] Compiler rejects autoboxing-calls to overloaded varargs methods as ambiguous
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87613">87613</a>
+Access restrictions should only apply to project's own package fragment roots
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86167">86167</a>
+[1.5] Add support for package-info.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87350">87350</a>
+IllegalArgumentException when converting AST with invalid enum body declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85262">85262</a>
+[1.5] Bound mismatch: type R is not a valid substitute for the bounded parameter...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87498">87498</a>
+StackOverflowError when marking occurrences of Comparable in Collections.min(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87481">87481</a>
+[1.5] type reference in CastExpression is generic type instead of parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87463">87463</a>
+The built-in Eclipse compiler behaves differently than IBM or Sun JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85226">85226</a>
+[1.5] EnumConstantDeclaration should declare resolveConstructorBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36938">36938</a>
+[plan item][1.5] Add early support for J2SE 1.5 features
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87404">87404</a>
+[javadoc] Unexpected not defined warning on constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85811">85811</a>
+BindingKey.toSignature should return method signature for methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87411">87411</a>
+[dom] API: ast.newName(String qualifiedName)
+	  	
+<a name="v_540"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 8th March 2005
+<br>Project org.eclipse.jdt.core v_540
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_540">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83693">83693</a>
+[search][javadoc] References to methods/constructors: range does not include parameter lists
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87273">87273</a>
+[1.5][compiler] Code with generics compiles, but throws a NoSuchMethodError when executed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87050">87050</a>
+ASTParser#createASTs(..) cannot resolve method type parameter binding from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83002">83002</a>
+[1.5] Compiler generates incorrect signature for throws clause.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87318">87318</a>
+[1.5][compiler] Array.asList(int[]) should be accepted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87171">87171</a>
+Find declaring node doesn't work for methods/fields using type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86908">86908</a>
+Code formatter fails to format when this code is present
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86967">86967</a>
+[1.5][dom] NPE in BindingKeyResolver for multi-level parameterized type binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86898">86898</a>
+[1.5][compiler] compiler should flag unchecked cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87267">87267</a>
+[1.5][compiler] cast from Integer[] to int[] should fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82830">82830</a>
+AST: String concatenation represented as single node
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83393">83393</a>
+[1.5][javadoc] reference to vararg method also considers non-array type as correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83285">83285</a>
+[javadoc] Javadoc reference to constructor of secondary type has no binding / not found by search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87042">87042</a>
+Passing null as first vararg makes parameter null (3.1M4)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86906">86906</a>
+[1.5][dom] SourceType#createField fails for enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86878">86878</a>
+Parameterized varargs causes Java formatter to fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80221">80221</a>
+[dom][javadoc] No Javadoc comment node when return type missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86901">86901</a>
+[1.5][search] Static import method references not found in unused import
+
+<a name="v_539"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 1st March 2005
+<br>Project org.eclipse.jdt.core v_539
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_539">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83319">bug 83319</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added optional compiler diagnosis to flag incomplete enum switch statements.
+Corresponding problem ID is: <code>IProblem.MissingEnumConstantCase</code>
+<pre>
+* COMPILER / Reporting Incomplete Enum Switch
+*    When enabled, the compiler will issue an error or a warning whenever an enum constant has
+*    no corresponding case label in an enum switch statement
+*    type has no case label matching an enum constant.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li>Added API <code>org.eclipse.jdt.core.dom.CompilationUnit#getJavaElement()</code> to retrieve the compilation unit
+     or class file the compilation unit node was created from.
+</li>
+<li>Added API <code>IMethodBinding#isSubsignature(IMethodBinding)</code> to find out if a method's signature 
+     is a subsignature of another method.
+</li>
+<li>Added optional compiler diagnosis to flag method overriding a superclass method, but missing 
+proper <code>@Override</code> annotation.
+Corresponding problem ID is: <code>IProblem.MissingOverrideAnnotation</code>
+
+<pre>
+* COMPILER / Reporting Missing @Override Annotation
+*    When enabled, the compiler will issue an error or a warning whenever encountering a method
+*    declaration which overrides a superclass method but has no @Override annotation.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"                               
+</pre>
+</li>
+<li>New CodeAssist feature: Enum constant are proposed inside switch label if the expression is an enum.
+<pre>
+Colors c;
+swith(c) {
+  case BLUE:
+  case RED&lt;complete here&gt;
+}
+</pre>
+</li>
+<li>New CodeAssist feature: Annotation's attribute name are proposed.
+<pre>
+@Annot(attr&lt;complete here&gt;=value)
+</pre>
+To propose this new completion kind a new API has been added: CompletionProposal.ANNOTATION_ATTRIBUTE_REF.<br>
+<pre>
+/**
+ * Completion is a reference to annotation's attribute.
+ * This kind of completion might occur in a context like
+ * &lt;code&gt;"@Annot(attr^=value)"&lt;/code&gt; and complete it to
+ * &lt;code&gt;"@Annot(attribute^=value)"&lt;/code&gt;.
+ * &lt;p&gt;
+ * The following additional context information is available
+ * for this kind of completion proposal at little extra cost:
+ * &lt;ul&gt;
+ * &lt;li&gt;{@link #getDeclarationSignature()} -
+ * the type signature of the annotation that declares the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getFlags()} -
+ * the modifiers flags of the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getName()} -
+ * the simple name of the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getSignature()} -
+ * the type signature of the attribute's type (as opposed to the
+ * signature of the type in which the referenced attribute
+ * is declared)
+ * &lt;/li&gt;
+ * &lt;/ul&gt;
+ * &lt;/p&gt;
+ * 
+ * @see #getKind()
+ */
+ public static final int ANNOTATION_ATTRIBUTE_REF = 13;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83319">83319</a>
+[1.5][search] Search does not find references to statically imported methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86838">86838</a>
+[1.5] [compiler] Eclipse compiles parameterized code that javac says is "is not within its bound"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84121">84121</a>
+[1.5][search][varargs] reference to type reported as inaccurate in vararg
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83388">83388</a>
+[search] SearchRequestor reports 'null' as match
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86775">86775</a>
+[1.5][compiler] Infer Generic Types Arguments throws NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86596">86596</a>
+[search] Search for type finds segments in import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79378">79378</a>
+[search] IOOBE when inlining a method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68825">68825</a>
+[compiler][1.5] detect not-exhaustive enum switches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81377">81377</a>
+[1.5][search] Semantics of search for methods with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84944">84944</a>
+[1.5][builder] Parameterized return type is sometimes not visible.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83770">83770</a>
+[1.5] ITypeBinding getQualifiedName doesn't cover the case of parameterized member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84140">84140</a>
+The type binding of a vararg should be an array not a simple type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83100">83100</a>
+[5.0] need IVariableBinding.isGeneric/Parametrized, getGeneric..
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86663">86663</a>
+[DOM] AbortCompilation should not abort the creation of the tree
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86463">86463</a>
+[1.5][compiler] Compiler-Bug using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86611">86611</a>
+[1.4] 1.5 power double causes compiler internal failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86531">86531</a>
+Javadoc: class AST has several parameterless methods claiming to throw IllegalArgumentException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86217">86217</a>
+NPE resolving bounds of Type Variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84554">84554</a>
+[1.5] code assist in enum switch statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75702">75702</a>
+[dom] Need a way to get back from an AST to the originating ICompilationUnit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86410">86410</a>
+formatting generics type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86487">86487</a>
+[1.5] infinite loop in enhanced for statement when the current element is optimized out
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73676">73676</a>
+[dom] Need API on bindings for overriding and assignment rules
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72258">72258</a>
+[model] Should be able to dynamicaly set the size of Java model cache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84562">84562</a>
+[DCR][1.5][options] Optional warning/error to avoid accidental overrides with JDK 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85538">85538</a>
+[1.5] compiler does not reject cyclic annotation element types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86141">86141</a>
+[recovery] ClassCastException with annotation of parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86179">86179</a>
+[1.5] Type parameters lost with nested inheritance and generics
+
+<a name="v_538"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M6 - 22nd February 2005
+<br>Project org.eclipse.jdt.core v_538
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_538">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Inclusion/exclusion filters used as import restrictions have been renamed into 'accessible files' and 'non accessible files' patterns.
+     The following APIs have been added on <code>IClasspathEntry</code>: <code>getAccessibleFiles()</code> and <code>getNonAccessibleFiles()</code>.
+     These are valid only for library, project, container and variable entries. <code>getInclusionPatterns()</code> and <code>getExclusionPatterns()</code> 
+     temporary return the accessible files and non accessible files patterns for these entries.
+</li>
+<li>Added ability to associate classpath attributes to a classpath entry (see <code>IClasspathAttribute</code>). A classpath attribute
+     is created using <code>JavaCore#newClasspathAttribute(String, String)</code>. Then one can associate this attribute with 
+     a classpath entry using one of:
+     <ul>
+     <li><code>JavaCore#newContainerEntry(IPath containerPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newLibraryEntry(IPath path, IPath sourceAttachmentPath, IPath sourceAttachmentRootPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newProjectEntry(IPath path, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation, IClasspathAttribute[] extraAttributes)</code></li>
+     <li><code>JavaCore#newVariableEntry(IPath variablePath, IPath variableSourceAttachmentPath, IPath variableSourceAttachmentRootPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     </ul>
+</li>
+<li>Added optional compiler diagnosis when a type parameter declaration is hiding another type.
+Corresponding problem ID is: <code>IProblem.TypeParameterHidingType</code>
+<pre>
+* COMPILER / Reporting Type Parameter Declaration Hiding another Type
+*    When enabled, the compiler will issue an error or a warning whenever a type parameter
+*    declaration is hiding some type.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.typeParameterHiding"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>The predicates <code>isInterface()</code> on Java element and DOM AST are now answering <code>true</code>
+for annotation types. Indeed, annotation types are allowed to be implemented just like regular interfaces.
+</li>
+<li>Added optional compiler diagnosis signalling usage of an annotation type as a super interface.
+Corresponding problem ID is: <code>IProblem.AnnotationTypeUsedAsSuperInterface</code>
+<pre>
+* COMPILER / Reporting Use of Annotation Type as Super Interface
+*    When enabled, the compiler will issue an error or a warning whenever an annotation type is used
+*    as a super-interface. Though legal, this is discouraged.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72704">72704</a>
+[compiler][1.5] unexpected IBindings and class files with conflicting method argument types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85397">85397</a>
+[1.5][enum] erroneous strictfp keyword on enum type produces error on constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83321">83321</a>
+[1.5][assist][enum] no override completion proposals in type when followed by a package visible enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85402">85402</a>
+[1.5][assist] NPE while trying to complete on empty annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85290">85290</a>
+[1.5] Code assist for annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85810">85810</a>
+[1.5][search] Missed type parameter reference in implements clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85421">85421</a>
+[1.5][search] NPE while searching type parameter reference in workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85432">85432</a>
+Make jdtcore.jar an executable jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85933">85933</a>
+Type parameters in anonymous type is missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82429">82429</a>
+[1.5] Need emulation of Unicode 4 using 1.4 libraries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85062">85062</a>
+[compiler] Implicit static method invocation should target the receiver type not the declaring class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84355">84355</a>
+[1.5] Generics bounds overzealous when converting to Object
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85477">85477</a>
+[1.5] certain unchecked conversion not reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85303">85303</a>
+[1.5] wrong declaring class for invokevirtual call
+
+
+<a name="v_537"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 15th February 2005 - 3.1 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_537
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_537">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85203">85203</a>
+VerifyError running o.e.pdu.ui from workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85160">85160</a>
+[compiler] java.lang.Object.finalize() method cannot be invoked on an array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85157">85157</a>
+[compiler] Integer[] is not compatible with String[] in conditional expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85215">85215</a>
+[DOM][1.5] Annotation type getModifiers() always returns 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85115">85115</a>
+[1.5] AST annotation.isTopLevel() doesn't work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84724">84724</a>
+[5.0][search] fails to find call sites for varargs constructors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85125">85125</a>
+When bracket is placed after MethodDeclarator, build fails.
+
+<a name="v_536"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 14th February 2005
+<br>Project org.eclipse.jdt.core v_536
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_536">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78906">78906</a>
+[1.5][compiler] this$0 is not allowed as a field in a member class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79396">79396</a>
+[compiler] Static receiver for a static method invocation should be generated to cover side-effects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84801">84801</a>
+Bad code generated for Java 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83902">83902</a>
+[1.5] AbstractMethodError when using covariant returns
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83901">83901</a>
+[1.5] AbstractMethodError: Compiler fails to catch missing methods of implemented interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82461">82461</a>
+[5.0] Unconventional formatting of annotations in ASTRewrite
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81244">81244</a>
+error range for generic vararg argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84743">84743</a>
+[1.5][compiler] Cast between two interfaces doesn't need to check compatibility of method return types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84869">84869</a>
+Missing constant for "org.eclipse.jdt.core.compiler.problem.autoboxing"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84770">84770</a>
+Formatter fails in specific case (.class in code)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84778">84778</a>
+NaiveASTFlattener should add spaces around extendedOperands in InfixExpression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84791">84791</a>
+[1.5][compiler] eclipse doesn't allow types to be derived from annotation types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83600">83600</a>
+[code assist] METHOD_REF proposals have non-standard signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80630">80630</a>
+[1.5] Conditional expression unboxing  should handle this case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84717">84717</a>
+Typo in javadoc of Signature.C_GENERIC_END
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84528">84528</a>
+Not visiting line comments in compilation unit?
+	  	
+<a name="v_535"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 8th February 2005
+<br>Project org.eclipse.jdt.core v_535
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_535">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Tuned generic method type argument inference (JLS 15.12.2.7&amp;8).
+</li>
+<li> Optional diagnosis for assignment with no effect now also detects: "var = var++;" scenario.
+<li>Added APIs <code>IType#getKey()</code>, <code>IField#getKey()</code>, <code>IMethod#getKey()</code>
+    that return a binding key for these Java elements.
+</li>
+<li>Added APIs <code>IType#isResolved()</code>, <code>IField#isResolved()</code>, 
+    <code>IMethod#isResolved()</code> that return whether these Java elements are resolved elements
+    and thus whether their key (see above) contains resolved information.
+</li>
+<li>Added API class <code>org.eclipse.jdt.core.BindingKey</code> to decode a binding key
+    obtained from <code>IBinding#getKey()</code> or one of the <code>getKey()</code> methods above.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84717">84717</a>
+Typo in javadoc of Signature.C_GENERIC_START
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84669">84669</a>
+[5.0] VerifyError: Expecting to find object/array on stack
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84593">84593</a>
+[1.5][compiler] NPE during problem detection with raw reference to parameterized inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84558">84558</a>
+Strange error message when using keywords "const" and "goto" as variable names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83648">83648</a>
+[1.5] Enum constructor cannot be public or protected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83379">83379</a>
+[1.5] compiler does not warn when overriding methods with parameters as array and vararg
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84345">84345</a>
+[1.5][compiler] Widening reference is possible when boxing in a cast expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83615">83615</a>
+[1.5][compiler] lenient subclass checking with interdependent type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84480">84480</a>
+Warning for "no effect assignment" j = j++
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83500">83500</a>
+Can't restore a secondary top level from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84416">84416</a>
+Stepping into message send without receiver should highlight message before sending message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76773">76773</a>
+Stepping through conditional looks like it evaluates both halves
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84504">84504</a>
+[Format] Extra empty line before class in default package when imports are specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83383">83383</a>
+IllegalArgumentException in Signature.getParameterCount
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83218">83218</a>
+[1.5] Covariant return type &amp; generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83499">83499</a>
+NPE when restoring ITypeBinding from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83611">83611</a>
+compiler reports error but there is no error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84055">84055</a>
+[1.5] Unnecessary cast  wrongly reported with boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83965">83965</a>
+[1.5][compiler] Widening conversion is possible when unboxing in a cast expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81544">81544</a>
+[dom] java.util.List&lt;URL&gt; sometimes has a binding, sometimes not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82647">82647</a>
+[compiler][1.5] Erroneous error with autoboxing and conditional operand
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79696">79696</a>
+[dom] Wrong type binding in qualified name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84215">84215</a>
+ArrayIndexOutOfBoundsException, internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84181">84181</a>
+[1.5] ITypeBinding.isFromSource incorrect on raw bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83376">83376</a>
+[1.5] compiler should error on ambiguous method invocation due to duplicate static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78934">78934</a>
+[1.5][dom] ParameterizedType for nested generic types has missing bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83162">83162</a>
+Eclipse reports no name clash with equivalent bridge methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81332">81332</a>
+[1.5][compiler] Is this a name clash?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80626">80626</a>
+[1.5] enum types cannot define a compareTo(Object o) method
+
+
+<a name="v_534"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 1st February 2005
+<br>Project org.eclipse.jdt.core v_534
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_534">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Add CompletionProposal#getDeclaringKey() and CompletionProposal#getKey() API
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84064">84064</a>
+AST: Wrong source ranges for superconstructorinv with type args
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83939">83939</a>
+[1.5][compiler] null is allowed as a legal element value in annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83817">83817</a>
+IBinding#isEqualTo(..) returns true for methods of different parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82349">82349</a>
+[compiler][1.5] Problems deriving from generic class that uses inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83904">83904</a>
+[compiler][1.5] Y&lt;T&gt; should be uniquely defined in the same signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83646">83646</a>
+NPE renaming package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83398">83398</a>
+[compiler][1.5] compiler allows adding Object to List<? super Number>
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83219">83219</a>
+NPE in ProblemReporter with duplicate abstract enum methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83860">83860</a>
+[1.5] java.lang.VerifyError with Enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83847">83847</a>
+[compiler][1.5] can create annonymous class of an enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83236">83236</a>
+ClassCastException using code assist in a javadoc comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83822">83822</a>
+Classes at root of project not found in Open Type dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83593">83593</a>
+Rename of enum type does not update constructor / throws ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83225">83225</a>
+[1.5] incorrect(?) compiler errors with type inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83127">83127</a>
+[1.5][javadoc][dom] Wrong / strange bindings for references in javadoc to methods with type variables as parameter types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80257">80257</a>
+[1.5][javadoc][dom] Type references in javadocs should have generic binding, not raw
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83713">83713</a>
+[search] IAE while searching reference to parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83684">83684</a>
+[formatting] Formatting codes like A extends B.C&lt;Object&gt; has no effect.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83599">83599</a>
+CU dirty after move refactoring
+
+
+<a name="v_533"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 25th January 2005
+<br>Project org.eclipse.jdt.core v_533
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_533">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Search engine is now able to find references and declarations to ITypeParameter.<br>
+To perform this kind of search, clients need to create a pattern using <code>SearchPattern.createPattern(IJavaElement,int,int)</code>
+providing searched ITypeParameter for IJavaElement parameter.
+</li>
+<li><code>TypeParameter#resolveBinding()</code> now returns an <code>ITypeBinding</code> instead of
+     an <code>IBinding</code></li>
+<li>Java model operations have been ported off the deprecated JDOM. They now use AST rewrite. This enables
+     these operations on local and anonymous types, enumerations and annotation types.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83489">83489</a>
+[select] Code select returns IType instead of ITypeParameter on method parameters types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83536">83536</a>
+"Incompatible argument to function" at vararg function
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83300">83300</a>
+[1.5] ClassCastException in #getJavaElement() on binding of annotation element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81190">81190</a>
+[1.5][search] no search for type parameters - SearchPattern is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82671">82671</a>
+[compiler][1.5]Protected field not visible to subclass in different package when having a class parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83210">83210</a>
+Unidentical ITypeBindings for same type from same AST from reconcile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80800">80800</a>
+getErasure() of ITypeBinding and IMethodBinding don't match the JLS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83304">83304</a>
+[1.5][search] Erasure match doesn't work for binary parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83078">83078</a>
+Auto formating multiple classes has errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25800">25800</a>
+Class file editor uses non-standard modifier order
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82859">82859</a>
+[1.5] void.class is incompatible with Void.TYPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83297">83297</a>
+[1.5] Annotation bindings don't provide their declared elements/methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43483">43483</a>
+[model] Can not add method to local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77894">77894</a>
+[model] Remove dependency to old JDOM in JavaModel implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83161">83161</a>
+Can't access public field from private subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78151">78151</a>
+'Insert single proposals automatically' should not insert without prefix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83096">83096</a>
+[1.5][compiler] NPE for class with duplicate type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82547">82547</a>
+[1.5][compiler] NullPointerException compiling invalid source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83098">83098</a>
+IBinding#isEqualTo(..) does not compare occurrence count of local variables
+
+
+<a name="v_532"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 18th January 2005
+<br>Project org.eclipse.jdt.core v_532
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_532">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Support for generic methods/constructors search has been added to SearchEngine (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75642">75642</a>).<br>
+User can now search for declaration and/or references to generic methods/constructors or parameterized methods/constructors (like <code>public &lt;U&gt; void foo(U u){}</code> or <code>&lt;String&gt;foo("")</code> for example).
+This search can be done either selecting a JavaElement or using Java Search dialog.
+</li>
+<li>Added new API <code>JavaConventions#validateTypeVariableName(String)</code>.</li>
+<li>Added new API <code>JavaCore#newTypeHierarchy(IRegion,WorkingCopyOwner,IProgressMonitor)</code> that creates a hierarchy
+     independently of a project.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83032">83032</a>
+VerifyError for anonymous declaration using variable arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75642">75642</a>
+[1.5][search] Methods and constructor search does not work with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83013">83013</a>
+[5.0] TypeDeclaration after AnnotationTypeDeclaration has wrong source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82985">82985</a>
+Static imports can't resolve bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83011">83011</a>
+[5.0] TypeName of an Annotation has no binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79144">79144</a>
+[1.5][compiler] generic type checking not performed for method return array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82844">82844</a>
+[1.5] Array type as type variable bound gives internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81590">81590</a>
+[1.5][compiler] Iteration over nested arrays is broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82439">82439</a>
+[compiler] [1.5] internal compiler reports type mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80945">80945</a>
+[1.5] Code assist does not offer static fields and methods from static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82590">82590</a>
+[compiler] [1.5]  internal compiler reports method not implemented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81721">81721</a>
+[compiler][1.5] Correct use of generic interfaces give compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82754">82754</a>
+[1.5] too many methods allowed by static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80745">80745</a>
+[1.5][compiler] Two interfaces with methods with compatible return types are compatible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80736">80736</a>
+[1.5] Compiler doesn't check that bounds have methods with same return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73535">73535</a>
+[1.5][model] Method to validate type parameter names missing in JavaConventions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82740">82740</a>
+[assist] NPE inside CompletionEngine with 1.5 code if compliance source level is 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80098">80098</a>
+newTypeHierarchy(IRegion,...) should not be constrained to an IJavaProject
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82510">82510</a>
+[compiler] Util.bind(...) methods should use MessageFormat
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81706">81706</a>
+[1.5] Static import of static method produces compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82670">82670</a>
+[5.0] wrong source range for VariableDeclarationFragment with ArrayCreation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80743">80743</a>
+[compiler] Interface cannot define a method from Object with a different return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82616">82616</a>
+CharacterLiteral.charValue fails for '\000'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77283">77283</a>
+Incremental and full builds produce different problem markers for same duplicate type error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74394">74394</a>
+[compiler] Provide XML output option for Eclipse compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81719">81719</a>
+[compiler][1.5] Correct use of generic abstract classes give compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81945">81945</a>
+[compiler] Enum and Duplicate case error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82542">82542</a>
+Internal error during AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82558">82558</a>
+[select] Text selection fail on constructor when parameters are parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78232">78232</a>
+[1.5][generics]Erroneous warning implementing generic method from interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82504">82504</a>
+[compiler][1.5] ClassCastException when parsing a CastExpression between an array type and a type variable
+
+
+<a name="v_531"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 11th January 2005
+<br>Project org.eclipse.jdt.core v_531
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_531">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>ASTParser#createBindings(IJavaElement[],IProgressMonitor)</code> to create the DOM bindings for the given 
+     Java elements.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82004">bug 82004</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Merged problem <code>IProblem.UnnecessaryArgumentCast</code> with <code>IProblem.UnnecessaryCast</code> since it provided little additional value,
+and was rather perceived as confusing. From now on, only <code>IProblem.UnnecessaryCast</code> is reported.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82514">82514</a>
+[1.5][javadoc] Problem with generics in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82382">82382</a>
+IMethodBinding#getJavaElement() for method m(T t) in parameterized type Gen&lt;T&gt; is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81923">81923</a>
+In certain cases generics seens to be applied before autoboxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82250">82250</a>
+[5.0] don't allow duplicate interface bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82432">82432</a>
+[1.5] VerifyError with Autoboxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82187">82187</a>
+[compiler] [1.5] internal compiler reports bound mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82159">82159</a>
+[compiler][1.5] Eclipse vs. javac: Differences when creating generic inner types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81535">81535</a>
+[compiler] compliance 1.5 should work with source 1.4 on 1.5 libraries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82137">82137</a>
+[select] Code resolve doesn't work on static imports [5.0]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82102">82102</a>
+Should not compile related methods with different signatures but same erasures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76761">76761</a>
+[model] ImportContainer.hasChildren() should not return true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79334">79334</a>
+[classpath] Build path info not updated properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82217">82217</a>
+[compiler][5.0] switch on enum allows non enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73081">73081</a>
+Inconsistant type cast warning.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81856">81856</a>
+quote problems in property files (JDT)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68823">68823</a>
+[dom] Ctrl+C command fails when "assert" is enabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81824">81824</a>
+A generic interface is allowed to be implemented more than once - contrary to Java language specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81571">81571</a>
+Autoboxing ambiguousy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81568">81568</a>
+[1.5][compiler] Covariant return types fails when an interface extends another interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82216">82216</a>
+IVariableBinding: Need to know if it is enum constant or normal var
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78520">78520</a>
+[model] IType#getSuperInterfaceTypeSignatures() doesn't include type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82253">82253</a>
+[5.0] Signature#getSimpleName(String) inserts superfluous whitespace characters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78698">78698</a>
+[format] Space before ? should default to false
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81063">81063</a>
+[model] Clarify the problem requestor paramter in becomeWorkingCopy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82004">82004</a>
+[model][5.0] 3.1M4 type hierarchy for generic interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82141">82141</a>
+AST: Missing Bindings on annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82140">82140</a>
+AST: Annotation node not in AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82136">82136</a>
+Interface with own Annotations not accessible when used as a library
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81727">81727</a>
+[1.5] Redundant warning of parameterized return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81762">81762</a>
+[model] AIOOB in breakpoints view
+
+<a name="v_530"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M5 - 4th January 2005
+<br>Project org.eclipse.jdt.core v_530
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_530">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Added optional compiler diagnosis reporting when boxing/unboxing conversion is performed. Corresponding problem IDs are:
+<code>IProblem.BoxingConversion</code> and <code>IProblem.UnboxingConversion</code>.
+<pre>
+* COMPILER / Reporting Boxing/Unboxing Conversion
+*    When enabled, the compiler will issue an error or a warning whenever a boxing or an unboxing
+*    conversion is performed.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.autoboxing"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>	 
+<li> Renamed unsafe type operation optional problem into unchecked type operation, to better match notion of
+"unchecked" warning from JLS 3rd edition.
+<pre>
+* COMPILER / Reporting Unchecked Type Operation
+*    When enabled, the compiler will issue an error or a warning whenever an operation involves generic types, and potentially
+*    invalidates type safety since involving raw types (e.g. invoking #foo(X&lt;String&gt;) with arguments  (X)).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81556">81556</a>
+[search] correct results are missing in java search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81825">81825</a>
+[1.5][compiler] Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71195">71195</a>
+[model] NullPointerException @ org.eclipse.jdt.internal.core.Buffer.removeBufferChangedListener
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79883">79883</a>
+[prefs] -pluginCustomization doesn't pick up compiler preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81718">81718</a>
+[1.5] "Static import never used" warning disappears when variable of same name is declared
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81971">81971</a>
+[1.5][compiler] compiler allows use of void type as method arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82053">82053</a>
+generic semantics have some problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82088">82088</a>
+[search][javadoc] Method parameter types references not found in @see/@link tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79766">79766</a>
+[model] NPE in CancelableNameEnvironment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81417">81417</a>
+[dom] getJavaElement() throws a NPE for WildcardBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81724">81724</a>
+[1.5] NullPointerException in FieldBinding.canBeSeenBy when using static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80223">80223</a>
+[search] Declaration search doesn't consider visibility to determine overriding methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81084">81084</a>
+[1.5][search]Rename field fails on field based on parameterized type with member type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80890">80890</a>
+[search] Strange search engine behaviour
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81376">81376</a>
+[search] Clarify effects of R_ERASURE_MATCH for searches other than TYPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81618">81618</a>
+[1.5][compiler] unsafe type operation warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78122">78122</a>
+[compiler] Detect and visually indicate auto-boxing in Jdk1.5 code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78592">78592</a>
+[1.5][compiler] missing unchecked cast warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78591">78591</a>
+[1.5][compiler] missing unchecked cast warning
+
+
+<a name="v_529"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 16th December 2004 - 3.1 MILESTONE 4
+<br>Project org.eclipse.jdt.core v_529
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_529">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81258">81258</a>
+IMethodBinding#getJavaElement() is null with inferred method parameterization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80765">80765</a>
+[1.5][generics] Invalid class files generated, compiler strange behaviour 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81317">81317</a>
+ClasspathTests.java and GenericTypeTest.java could not be read (illegal characters)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81262">81262</a>
+[Java 5] Verification error when creating anonymous enum subtypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80964">80964</a>
+[1.5] Annotations with RetentionPolicy.RUNTIME are lost after a rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80028">80028</a>
+Ambiguous method error where javac succeeds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80739">80739</a>
+[1.5] Two methods ends up with the same signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81134">81134</a>
+[dom] [5.0] NPE when creating AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81023">81023</a>
+[1.5] Wrong position for class instance creation with type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81141">81141</a>
+CCE in ProblemBinding when using annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80544">80544</a>
+[1.5][annot]error on @Override of abstract methods
+
+
+<a name="v_528"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 14th December 2004
+<br>Project org.eclipse.jdt.core v_528
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_528">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80957">80957</a>
+NPE using code assist for unresolved type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80960">80960</a>
+[dom] NPE in ASTConverter#convert(...)
+
+<a name="v_527"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 14th December 2004
+<br>Project org.eclipse.jdt.core v_527
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_527">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80918">80918</a>
+[1.5][search] ClassCastException when searching for references to binary type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80914">80914</a>
+[1.5][search] SearchPattern R_EQUIVALENT_MATCH matchRule does not work properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80910">80910</a>
+[javadoc] Invalid missing reference warning on @see or @link tags
+
+<a name="v_526"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 13th December 2004
+<br>Project org.eclipse.jdt.core v_526
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_526">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Initial support for search on annotations has been implemented. Declarations or references to annotation types are now found by search engine.<br>
+However, it is not currently able to find annotation member (fields or methods). This should be done for next milestone.
+</li>
+<li>
+SearchPattern now accept two new flags for match rule: R_ERASURE_MATCH and R_EQUIVALENT_MATCH (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79790">79790</a>).<br>
+<pre>
+	/**
+	 * Match rule: The search pattern matches search results as raw types or parameterized types with same erasure.
+	 * Example:
+	 *	- pattern: List&lt;Exception&gt;
+	 *	- match: List&lt;Object&gt;
+	 * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_ERASURE_MATCH}
+	 * This rule is not activated by default, so raw types or parameterized types with same erasure will not be found
+	 * for pattern List&lt;String&gt;,
+	 * Note that with this pattern, the match selection will be only on the erasure even for parameterized types.
+	 * @since 3.1
+	 */
+	public static final int R_ERASURE_MATCH = 16;
+	/**
+	 * Match rule: The search pattern matches search results as raw types or parameterized types with equivalent type parameters.
+	 * Example:
+	 *	- pattern: List&lt;Exception&gt;
+	 *	- match:
+	 * 		+ List&lt;? extends Throwable&gt;
+	 * 		+ List&lt;? super RuntimeException&gt;
+	 * 		+ List&lt;?&gt;
+	 * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_EQUIVALENT_MATCH}
+	 * This rule is not activated by default, so raw types or equivalent parameterized types will not be found
+	 * for pattern List&lt;String&gt;,
+	 * This mode is overridden by {@link  #R_ERASURE_MATCH} as erasure matches obviously include equivalent ones.
+	 * That means that pattern with rule set to {@link #R_EQUIVALENT_MATCH} | {@link  #R_ERASURE_MATCH}
+	 * will return same results than rule only set with {@link  #R_ERASURE_MATCH}.
+	 * @since 3.1
+	 */
+	public static final int R_EQUIVALENT_MATCH = 32;
+</pre>
+Added new API method to make this flag settable even while creating pattern using a IJavaElement:
+<ul>
+<li><code>SearchPattern#createPattern(IJavaElement element, int limitTo, int matchRule)</code></li>
+</ul>
+</li>
+<li>
+SearchMatch now has a rule field which shows the rule used while reporting the match (initial implementation for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79866">79866</a>).<br>
+Added new API methods to access this field:
+<ul>
+<li><code>SearchMatch#getRule()</code><br></li>
+<li><code>SearchMatch#setRule(int)</code></li>
+</ul>
+</li>
+<li>Added API IType#getFullyQualifiedParameterizedName() that shows the type parameter/arguments if the type is generic/parameterized.</li>
+<li>Added support in Java model for annotation types and annotations.</li>
+<li>Support for indexing annotation types required the index version to be incremented. 
+      Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).</li>
+<li>Added compiler support for autoboxing </li>
+<li>Code Assist now works for annotations. When performing a completion inside an annotation name,
+ proposals are possibles types and annotations types are more relevant than other types</li>
+<li>Code Select now works for annotations and annotation methods in correct code.</li>
+<li>Recovery now works for annotation type declaration and annotation method declaration</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80338">80338</a>
+getReturnType() throws a NullArgumentException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80788">80788</a>
+Interface and annotation member types are implicitiely static
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80780">80780</a>
+IncompatibleClassChangeError for Annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80714">80714</a>
+Strange syntax diagnosis with incorrect annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80699">80699</a>
+Code Select does not work for annotations inside class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79790">79790</a>
+[1.5][search] Need to distinguish between raw and restricted search in the case of instantiated types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80672">80672</a>
+[1.5] Annotation change does not trigger recompilation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80466">80466</a>
+ITypeBinding#getJavaElement() is null for declaration of java.util.List&lt;E&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80083">80083</a>
+VerifyError on String-Operator += when using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77430">77430</a>
+[1.5] case statements with enum values not correctly supported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80597">80597</a>
+[compiler] NPE while reporting array empty dimensions problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80126">80126</a>
+[assist] CompletionRequestor.setIgnored should allow POTENTIAL_METHOD_DECLARATION
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80602">80602</a>
+Javadoc of ASTNode#getStartPosition() contains dangling reference to ASTParser 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80455">80455</a>
+[5.0] ITypeBinding.canAssign not aware of type boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80579">80579</a>
+NPE is ITypeBinding.isCastCompatible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80328">80328</a>
+[annotation] annotation problem type should implements java,lang.annotation.Annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79953">79953</a>
+AST Creation Error while editing Java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78849">78849</a>
+[1.5][compiler] Java 1.5 Boxing and Character?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79641">79641</a>
+boolean autoboxing does not work with Object varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80384">80384</a>
+Cannot decode package signature from CompletionProposal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79254">79254</a>
+autoboxing does not work in combination with downcasting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80045">80045</a>
+NPE in MethodBinding.signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80378">80378</a>
+Javadoc of CompletionProposal#getFlags() needs polish
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80208">80208</a>
+[1.5][compiler] NPE trying to resolve single static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79803">79803</a>
+[1.5][search] Search for references to type A reports match for type variable A
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79860">79860</a>
+[1.5][search] Search doesn't find type reference in type parameter bound
+
+<a name="v_525"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 7th December 2004
+<br>Project org.eclipse.jdt.core v_525
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_525">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Compiler now checks annotation location according to @Target meta-annotation</li>
+<li> Compiler now checks method overriding according to @Override annotation</li>
+<!--
+<li> Added compiler support to flag inconsistent null checks (using interprocedural flow analysis)
+<pre>
+* COMPILER / Reporting Inconsistent null Checks
+*    When enabled, the compiler will issue an error or a warning whenever assumption were made on a variable
+*    with respect to holding null/non-null values, but the assumption is not followed in a consistent manner.
+*    Situations include:
+*         - if variable was assumed to be null and further used to access field or methods
+*         - if variable was assumed to be null or non-null and further tested for null cases.
+*         
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.inconsistentNullCheck"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+-->
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79891">79891</a>
+[GENERICS] Array of Inner Class creation works on eclipse, but fails to compile with sun jdk
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79809">79809</a>
+[1.5][dom][javadoc] Need better support for type parameter Javadoc tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79904">79904</a>
+[1.5][dom][javadoc] TagElement range not complete for type parameter tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80144">80144</a>
+[1.5] Mutually-recursive type bounds interfere with inheritance of generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76751">76751</a>
+[1.5][annot] Can't use annotation classes as argument to generic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80014">80014</a>
+@Retention(RetentionPolicy.RUNTIME) is ignored for annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80114">80114</a>
+[1.5][Regression] Annotation type cannot have constructors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80021">80021</a>
+[1.5] CCE in VariableBinding.getJavaElement()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80041">80041</a>
+IVariableBinding#isEqualTo(..) doesn't tell parameters from different methods apart
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77463">77463</a>
+[1.5][annot] Wrong error marker text for type annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79967">79967</a>
+NPE in WildcardBinding.signature with Mark Occurrences in Collections.class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79974">79974</a>
+[1.5] Wrong javadoc for TypeDeclarationStatement 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79795">79795</a>
+Code formatter doesn't handle enums well.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79673">79673</a>
+[1.5] Wrong method binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79797">79797</a>
+[1.5] Inconsistent classfile - moving code around
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79847">79847</a>
+[1.5][annot] Array type cannot have two or more dimensions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79844">79844</a>
+[1.5][annot] when int value can be contained in a short, the cast is not required
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79848">79848</a>
+[1.5][annot] Array of java.lang.Class is a legal value for the type of an annotation type member declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79779">79779</a>
+Code Formatter fails with static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79668">79668</a>
+[1.5][annot] implicit wrapping in array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78915">78915</a>
+[1.5][compiler] enum cannot be explicitly abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78916">78916</a>
+[1.5][compiler] abstract methods in an enum declaration must be implemented for each constant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79690">79690</a>
+Find declaring node doesn't work for type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79775">79775</a>
+[dom]ClassCastException inside ASTConverter when opening a java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79752">79752</a>
+Need access to type binding of anonymous enumerations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79772">79772</a>
+Internal compiler error with I20041123/24/30
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79136">79136</a>
+API clarification for *Binding#getErasure(): why not a "general back-link"?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76318">76318</a>
+[tests] Cannot run ASTModelBridgeTests if workspace path segment count is 1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78914">78914</a>
+[1.5][compiler] super() cannot be called in the constructor of an enum declaration
+
+<a name="v_524"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 30th November 2004
+<br>Project org.eclipse.jdt.core v_524
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_524">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Support for generic types search has been added to SearchEngine (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75641">75641</a>).<br>
+User can now search for declaration and/or references to generic types or parameterized types (like <code>public class List&lt;T&gt; {}</code> or <code>List&lt;String&gt;</code> for example).
+This search can of course be done either selecting a JavaElement (see following point) or using Java Search dialog.
+</li>
+<li>Support for generic types and generic methods selection has been added inside CodeSelect.
+When the result is a parameterized type reference, the returned JavaElement is a 
+<code>ParameterizedSourceType</code> or <code>ParameterizedBinaryType</code>.
+When the result is a parameterized method invocation, the returned JavaElement is a 
+<code>ParameterizedSourceMethod</code> or <code>ParameterizedBinaryMethod</code>.
+When the result is a field access to a generic type's field, the returned JavaElement is a 
+<code>ParameterizedSourceField</code> or <code>ParameterizedBinaryField</code>.
+</li>
+<li>The internal Java model cache now adapts to the number of elements in the workspace. For example if a project
+      has 1000 package fragment roots, the space limit of the cache of roots will increase to 1000. This size is reset to
+      its default when the project is closed.
+</li>
+<li>Added the following compatibility rules APIs:
+     <ul>
+     <li><code>ITypeBinding#isAssignmentCompatible(ITypeBinding)</code></li>
+     <li><code>ITypeBinding#isCastCompatible(ITypeBinding)</code></li>
+     <li><code>ITypeBinding#isSubTypeCompatible(ITypeBinding)</code></li>
+     <li><code>IMethodBinding#overrides(IMethodBinding)</code></li>
+     </ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79349">79349</a>
+[1.5] Annotation with default value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79756">79756</a>
+Erroneous compile error "The local variable may not have been initialized"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79635">79635</a>
+NPE when asking an IMethodBinding whether it overrides itself
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79667">79667</a>
+[1.5][annot] value in member pair value must be a constant expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79666">79666</a>
+[1.5][annot] Default value of annotation type member declaration must be assignment compatible with return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79663">79663</a>
+[1.5][annot] Modifiers for field declaration must be public  in an annotation type declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79665">79665</a>
+[1.5][annot] Field declarations inside annotation type declaration must be constant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79512">79512</a>
+[1.5] Extract Method must not generate return type with type variable [refactoring][1.5]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79609">79609</a>
+ITypeBinding#isEqualTo(..) thinks independent method type parameters are equal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79610">79610</a>
+IVariableBinding#getJavaElement() returns null for local variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75641">75641</a>
+[1.5][search] Types search does not work with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79612">79612</a>
+ClassCastException on referenceTypeBinding.isEqualTo(primitiveTypeBinding)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79545">79545</a>
+Eclipse vs Sun JDK: different class files from the same source code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78293">78293</a>
+[1.5][compiler] Should flag implementing twice generic interface with different arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79544">79544</a>
+ITypeBinding#isEqualTo(..) does not compare type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79570">79570</a>
+[1.5][DOM] v4 type binding should not be parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78087">78087</a>
+[dom] TypeBinding#getJavaElement() throws IllegalArgumentException for parameterized or raw reference to binary type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78183">78183</a>
+TypeBinding#getQualifiedName() does not honor Javadocs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79109">79109</a>
+[1.5][DOM] AnnotationTypeMemberDeclaration.resolveBinding() might return a IMethodBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79395">79395</a>
+IllegalArgumentException in CompilationUnitResolver.parse (line 323)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77283">77283</a>
+Incremental and full builds produce different problem markers for same duplicate type error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79263">79263</a>
+ClassCastException in SourceElementParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79460">79460</a>
+IMethodBinding of non-generic method says isRawMethod()==true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79390">79390</a>
+[1.5][compiler] ClassCastException creating a generic local class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77806">77806</a>
+[1.5][dom] SimpleType AST node of List in List&lt;String&gt; has no type binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79362">79362</a>
+IllegalArgumentException during "Java AST creation"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75785">75785</a>
+Missing binding on non-visible type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79163">79163</a>
+[compiler] Dependency on indirectly referenced types not correctly computed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77272">77272</a>
+[builder] Delta compilation fails to notice errors when removing an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79271">79271</a>
+ITypeBinding#isEqualTo(..) returns true when comparing ArrayList&lt;Integer&gt; to its erasure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77388">77388</a>
+[compiler] Reference to constructor includes space after closing parenthesis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78931">78931</a>
+[select] cannot select qualified type name without the qualified package name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79267">79267</a>
+[search] Refactoring of static generic member fails partially
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72258">72258</a>
+[model] Should be able to dynamicaly set the size of Java model cache
+
+<a name="v_523"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 23rd November 2004
+<br>Project org.eclipse.jdt.core v_523
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_523">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Compiler is now able to parse 1.5 syntax in Javadoc comments (see bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70891">70891</a>
+and <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70892">70892</a>).<br>
+Note: these changes only apply to <a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javadoc.html#@param">@param</a> and
+<a href="http://download.oracle.com/javase/6/docs/technotes/tools/windows/javadoc.html#@value">{@value}</a> tags.
+</li>
+<li>Batch AST creation API was finalized. See <code>ASTParser#createASTs(ICompilationUnit[],String[],ASTRequestor,IProgressMonitor)</code>
+     and <code>ASTRequestor</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79110">79110</a>
+[1.5] Missing attribute for local and anonymous classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78057">78057</a>
+[dom] Can IBinding#getKey() return null?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78757">78757</a>
+MethodBinding.getJavaElement() returns null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78930">78930</a>
+ITypeBinding#getJavaElement() throws NPE for type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73675">73675</a>
+[dom] Need AST creation pipeline
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73971">73971</a>
+[1.5] Ambiguous method error with overloaded parameterized methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78581">78581</a>
+[search] NPE while searching
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79108">79108</a>
+[1.5][DOM] enumConstantDeclaration.resolveBinding() always returns null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77645">77645</a>
+[1.5][dom] navigate from local var binding to declaring method binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79098">79098</a>
+[dom] [1.5] EnhancedForStatement#resolveBinding() is superfluous
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77562">77562</a>
+[1.5] overriding methods with more specific generic return types causes compile errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79091">79091</a>
+[compiler] Should report invalid type only on the name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77093">77093</a>
+[search] No references found to method with member type argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77184">77184</a>
+[1.5][select] Code select does not select enum declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78801">78801</a>
+[assist] NPE attempting to code assist for parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78128">78128</a>
+Error deleting project with jar file referenced by other project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78275">78275</a>
+[recovery] NPE in GoToNextPreviousMemberAction with syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70891">70891</a>
+[1.5][javadoc] Compiler should accept new 1.5 syntax for @param
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78858">78858</a>
+[1.5] Internal compiler error: java.lang.NullPointerException at ParameterizedTypeBinding.getMethods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78905">78905</a>
+[1.5][compiler] Wrong hex decimal floating point literal is not rejected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77630">77630</a>
+[compiler] no error when importing package inside static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78075">78075</a>
+normal and static import of the same class doesn't work correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78056">78056</a>
+[1.5] static import of a static member of a non static member type must be allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77955">77955</a>
+[1.5] member classes of super class are not allowed inside static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78082">78082</a>
+[1.5][search] FieldReferenceMatch in static import should not include qualifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78714">78714</a>
+"Convert local to field" should know about prefixes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75814">75814</a>
+Inconsistent results when adding a breakpoint to class file with src attached
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78190">78190</a>
+[dom] Add ast creation performance tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78189">78189</a>
+[model] Add hierarchy performance tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78188">78188</a>
+[search] Add search performance test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78740">78740</a>
+IDOMType.getFlags() fails to represent interface flags correctly.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78735">78735</a>
+IBinding#isEqualTo(..) fails with a field that hides another
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78232">78232</a>
+[1.5][generics]Erroneous warning implementing generic method from interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78140">78140</a>
+[1.5][compiler] Unchecked conversion warning when overriding a generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77861">77861</a>
+[1.5] Illegal class file generated with duplicate methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77785">77785</a>
+[1.5][compiler] Generics: missing name clash error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77496">77496</a>
+[1.5] compiler doesn't detect illegal method overriding due to non-matching return type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74936">74936</a>
+[1.5] Compiler does not warn for missing implementation of Map.putAll abstract method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74594">74594</a>
+[1.5] ClassFormat error when running this example
+
+
+<a name="v_522"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 16th November 2004
+<br>Project org.eclipse.jdt.core v_522
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_522">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In 1.5 compliant mode, T[].clone() invocations are considered to be of type T[], as opposed to Object
+previously. </li>
+
+<li>New ComletionProposal kind <code>METHOD_NAME_REFERENCE</code>.
+This completion is a reference to a method name.
+<br>This kind of completion might occur in a context like
+<code>"import java.lang.Math.co^"</code> and complete it to
+<code>"import java.lang.Math.cos;"</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77808">77808</a>
+[1.5][dom] type bindings for raw List and List&lt;E&gt; have same key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78704">78704</a>
+[1.5][compiler]Internal compiler error in org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78663">78663</a>
+[1.5][compiler] Generics, assign error with equal types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78649">78649</a>
+[1.5] ITypeBinding.isUpperBound wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77398">77398</a>
+[1.5] Organize imports does not honor enum types [code manipulation]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78464">78464</a>
+[1.5][compiler] bad args_size attribute value for Enum constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78104">78104</a>
+[1.5][compiler] java.lang.Object.clone() implicitely needs an implicit cast to receiver type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78321">78321</a>
+Problem with Enum.values in static initializer.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78310">78310</a>
+[dom] [1.5] improve tests for IBindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78015">78015</a>
+[1.5][compiler] AbstractMethodError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78266">78266</a>
+[dom] [1.5] API of ITypeBinding: no isGenericType() query
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64310">64310</a>
+[1.5][model] Signature implementation does not fully support generic parameterized type names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77968">77968</a>
+[compiler] ArrayIndexOutOfBoundsException from parser when using Java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77573">77573</a>
+[1.5][assist] Code assist does not propose static fields
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78008">78008</a>
+[1.5][compiler] java.lang.VerifyError on shortcut if-else
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78018">78018</a>
+[1.5][javadoc] Missing Javadoc comments Problem for enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73784">73784</a>
+[search] java search internal error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77644">77644</a>
+[dom] AST node extended positions may be wrong while moving
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78160">78160</a>
+Invalid classfile for problem type
+
+<a name="v_521"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M4 - 9th November 2004
+<br>Project org.eclipse.jdt.core v_521
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_521">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li><code>ICompletionRequestor</code> was deprecated. Use <code>CompletionRequestor</code> instead.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77359">77359</a>
+[1.5][dom] Pull up of type declaration facilities
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76132">76132</a>
+[1.5][wildcards] Bound mismatch incorrectly diagnosed with type variable quantification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78139">78139</a>
+[1.5][compiler] spurious type mismatch problems with generics.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77602">77602</a>
+[javadoc] "Only consider members as visible as" is does not work for syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77510">77510</a>
+[javadoc] compiler wrongly report deprecation when option "process javadoc comments" is not set
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78027">78027</a>
+[1.5] Generics, bound mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78089">78089</a>
+[1.5] [compiler] Annotations are not accepted inside interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74119">74119</a>
+[1.5] Unexpected compile error with bound types with Eclipse 3.1M1.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78049">78049</a>
+[1.5][compiler] Missed error for generic array creation.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73970">73970</a>
+[1.5][dom] overloaded parameterized methods have same method binding key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77422">77422</a>
+[1.5][compiler] ArrayIndexOutOfBoundsException with vararg constructor of generic superclass
+
+<a name="v_520"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 4th November 2004 - 3.1 MILESTONE 3
+<br>Project org.eclipse.jdt.core v_520
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_520">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77244">77244</a>
+[1.5][enum] final enum class crashes the compiler
+
+<a name="v_519"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 4th November 2004
+<br>Project org.eclipse.jdt.core v_519
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_519">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76780">76780</a>
+[model] return type not recognized correctly on some generic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77772">77772</a>
+[1.5] some enums failing to parse; internal error dialog pops up while typin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77538">77538</a>
+[dom] AST rewrite fails to generate the modified code
+
+
+<a name="v_518"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 2nd November 2004
+<br>Project org.eclipse.jdt.core v_518
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_518">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API that allows to batch the creation of DOM ASTs: <code>ASTParser#createASTs(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor)</code>.
+      Note this API is still under development and subject to change without notice.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70056">70056</a>
+[1.5] Please support varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77327">77327</a>
+[1.5] Contravariance of generic Type raises Error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71612">71612</a>
+[1.5] ClassFormatError when running simple example
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76434">76434</a>
+[1.5]  Generics, assign error despite equal types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76720">76720</a>
+[1.5] Implementing generic bounded subinterface causes Bound mismatch error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76219">76219</a>
+[1.5][wildcards] Not-necessarily-unbounded wildcards in method formal parameter types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76601">76601</a>
+[1.5] parameterized types: eclipse incorrectly reports errors
+
+<a name="v_517"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 2nd November 2004
+<br>Project org.eclipse.jdt.core v_517
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_517">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Search engine is now able to find declarations and references to varargs methods. This required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Default severity for access restriction violations got raised to "warning".
+<pre>
+* COMPILER / Reporting Forbidden Reference to Type with Restricted Access
+*    When enabled, the compiler will issue an error or a warning when referring to a type with restricted access, as defined according
+*    to the access restriction specifications.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.forbiddenReference"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77273">77273</a>
+[model] ArrayIndexOutOfBoundsException when creating type hierarchy with duplicate types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76359">76359</a>
+[1.5] Unsafe operation not reported while using member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77235">77235</a>
+ArrayIndexOutOfBounds in Parser in reconciler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68710">68710</a>
+Open Declaration opens wrong target
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77249">77249</a>
+Annotation on class cancels "public" modifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77212">77212</a>
+[1.5][enum] declared enum type .valueOf(String) throws ArrayIndexOutOfBoundsException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75400">75400</a>
+[1.5] Wrong type mismatch error reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75156">75156</a>
+[1.5] wrong diagnosis for method override
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70695">70695</a>
+[1.5] warning for easily detectible incorrect bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72643">72643</a>
+[1.5] parser doesn't recognize when generic methods aren't used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77051">77051</a>
+[1.5] Type mismatch involving super
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77175">77175</a>
+[1.5] DefaultBindingResolver#resolveType(EnumDeclaration) always returns null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75328">75328</a>
+[1.5][wildcards] Bound Mismatch for ? type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72886">72886</a>
+[search] references to endVisit(MethodInvocation) reports refs to endVisit(SuperMethodInvocation)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75329">75329</a>
+[classpath] Restrict visibility of Java Project content
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74285">74285</a>
+Code assist doesn't  suggest parameter names for methods of generic types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74588">74588</a>
+[1.5] missing enclosing instance is wrongly reported when accessing an enclosing instance variable.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76313">76313</a>
+[1.5] Error while using parametrized static factory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77151">77151</a>
+[1.5] Enum constant cannot be qualified when used as a case label
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77118">77118</a>
+[1.5] Covariance: cannot override method returning Object with method returning an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77052">77052</a>
+[1.5] Type mismatch on embedded type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76620">76620</a>
+Selection bug (Open Declaration)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76874">76874</a>
+[1.5] Out of memory reconciling some invalid enum source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76682">76682</a>
+Certain code prevents saving and copy operations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74669">74669</a>
+[1.5] NullPointerException during save and compile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74032">74032</a>
+[1.5] Generics: bad method referenced when a type variable extends two types
+
+<a name="v_516"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 26th October 2004
+<br>Project org.eclipse.jdt.core v_516
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_516">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Support for search on enum has been implemented. Declarations or references to enum type, fields, constructors and methods are correctly found by search engine.
+</li>
+<li>Support to compute type hierarchies on enum required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added support inside CompletionEngine to not propose completion when an access restriction is violated.
+Currently access restrictions are applied only to top level types.
+</li>
+<li>Added code assist option to not propose completion when an access restriction is violated.
+<pre>
+	 * CODEASSIST / Activate Access Restrictions Sensitive Completion
+	 *    When active, completion doesn't show that is access restricted.
+	 *     - option id:         "org.eclipse.jdt.core.codeComplete.restrictionsCheck"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "disabled"
+</pre>
+</li>
+<li>Added first-cut of enumeration support into compiler. Requires some more work to properly
+diagnose error situations, and be leveraged in various JDT/Core functionalities.
+</li>
+<li>Improved problem descriptions to show ellipsis in varargs method signatures
+</li>
+<li>Added <code>org.eclipse.jdt.core.util.ClassFileBytesDisassembler#SYSTEM</code> field to support an extra-detailed output from the
+disassembler. It can show constant pool contents.
+</li>
+<li>In order to fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76440">76440</a>, two APIs on <code>org.eclipse.jdt.core.Signature</code> have been added to handle var args in the signature decoding.
+<ul>
+<li><code>Signature#toCharArray(char[],char[],char[][],boolean,boolean,boolean)</code>
+</li>
+<li><code>Signature#toString(String,String,String[],boolean,boolean,boolean)</code>
+</li>
+</ul>
+</li>
+<li>Added compiler option to diagnose need for cast of varargs argument. Matching problem IDs are 
+<code>IProblem.MethodVarargsArgumentNeedCast</code> &amp; <code>IProblem.ConstructorVarargsArgumentNeedCast</code>
+<pre>
+* COMPILER / Reporting Varargs Argument Needing a Cast in Method/Constructor Invocation
+*    When enabled, the compiler will issue an error or a warning whenever a varargs arguments should be cast
+*    when passed to a method/constructor invocation. (e.g. Class.getMethod(String name, Class ... args )  
+*    invoked with arguments ("foo", null)).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74851">74851</a>
+[1.5] enum errors in 3.1M1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75134">75134</a>
+[1.5] Type mismatch error generated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76880">76880</a>
+Unable to resolve enum type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76766">76766</a>
+[1.5] Option to format empty enum declaration or empty enum constant body has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76642">76642</a>
+Inner Enum Declarations not formatted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76093">76093</a>
+Varargs support should define a subtype of ArrayTypeReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76472">76472</a>
+Duplicate entries in the constant pool for some methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76440">76440</a>
+[1.5] Disassembler doesn't render 1.5 constructs correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76524">76524</a>
+need a isVarargs() method on IMethodBinding
+	 
+<a name="v_515"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 19th October 2004
+<br>Project org.eclipse.jdt.core v_515
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_515">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Code assist use static imports to propose completions.
+</li>
+<li>2 new Javadoc compiler options have been added (see bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53977">53977</a>
+and <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75701">75701</a>).<br>
+While reporting problems on invalid Javadoc tags, user can now decide not to report deprecation and/or visibility warnings on references used in @see, @link or @values tags.
+<br>
+Here's the description of these new options:
+<pre>
+	 * COMPILER / Reporting Invalid Javadoc Tags with Deprecated References
+	 *    Specify whether the compiler will report deprecated references used in Javadoc tags.
+	 *    Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility".
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "enabled"
+	 * 
+	 * COMPILER / Reporting Invalid Javadoc Tags with Not Visible References
+	 *    Specify whether the compiler will report non-visible references used in Javadoc tags.
+	 *    Note that this diagnosis can be enabled based on the visibility of the construct associated with the Javadoc;
+	 *    also see the setting "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility".
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "enabled"
+	 * 
+</pre>
+</li>
+<li>Changed build state format to record access restrictions. As a consequence, a full rebuild will be
+required when reusing existing workspaces.
+</li>
+<li>Added tracing (org.eclipse.jdt.core/debug/resolution) to show the number of packages, roots and working copies used during name resolution.</li>
+<li>New API <code>org.eclipse.jdt.core.dom.EnumDeclaration#enumConstants()</code>. The enum constants are now in a separate list
+from the body declarations. The  <code>org.eclipse.jdt.core.dom.EnumDeclaration#getEnumConstants()</code> method has been deprecated and
+will be removed after M3. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76190">76190</a> for further details.
+</li>
+<li>New requestor API <code>CompletionRequestor</code> is implemented inside code assist engine.
+</li>
+<li>Added missing API to <code>IType</code> for new completion requestor support:
+<ul>
+  <li><code>IType#codeComplete(char[],int,int,char[][],char[][],int[],boolean,CompletionRequestor,WorkingCopyOwner)</code></li>
+  <li><code>IType#codeComplete(char[],int,int,char[][],char[][],int[],boolean,CompletionRequestor)</code></li>
+</ul>
+</li>
+<li>Added missing API to <code>IEvaluationContext</code> for new completion requestor support:
+<ul>
+  <li><code>IEvaluationContext#codeComplete(String,int,CompletionRequestor, WorkingCopyOwner)</code></li>
+  <li><code>IEvaluationContext#codeComplete(String,int,CompletionRequestor)</code></li>
+</ul>
+</li>
+<li>Added new API inside <code>Signature</code> to extract package name part or type name part of a type signature:
+<ul>
+  <li><code>Signature#getSignatureQualifier(char[])</code></li>
+  <li><code>Signature#getSignatureQualifier(String)</code></li>
+  <li><code>Signature#getSignatureSimpleName(char[])</code></li>
+  <li><code>Signature#getSignatureSimpleName(String)</code></li>
+</ul>
+</li>
+<li>Added support in Java model for varargs methods:
+     <ul>
+     <li><code>Flags.isVarargs(method.getFlags())</code> now returns whether the method is a varargs method.</li>
+     <li>Operations that resolve (like reconcile, search, etc.) now convert varargs source methods into varargs MethodDeclarations.</li>
+     </ul>
+</li>
+<li> Introduced access restrictions so as to better enforce API contracts across components.
+<p>
+<i>Problem:</i> Libraries are usually packaged to contain both API for compile-time and implementation for runtime;
+and thus expose a superset of the API contract to client programs, allowing them to make forbidden
+assumptions on internals (a typical restriction for Eclipse developpers is to not use internal classes 
+from prerequisite plug-ins). 
+One solution for solving this issue is to separate the API from its implementation into 2 distinct libraries 
+(compile-time/runtime) and then use the classpath rules to only include the API portion on the classpath
+for compiling. However, this usually proves to be unrealistic, since the API is often mixed with some implementation
+aspects (not officially part of the API) which are carrying references to its internals 
+(supertype hierarchy, field or method signatures). When it happens, then the compiler needs the implementation
+also to be on the classpath in order to resolve all signatures appropriately; which goes back to the original
+problem of exposing too much to unaware clients.
+<p>
+Instead, we allowed classpath rules to be associated with some import restrictions so as to select portions 
+of prerequisite projects or libraries which are legal to use inside this project. 
+Access restrictions are expressed as inclusion/exclusion rules on classpath entries (using Ant fileset notation
+for discriminating on package and/or file names, e.g. <code>excluding='**/internal/'</code> would exclude 
+all types defined any <code>internal</code> package),
+and can be associated to project, library, classpath variable or classpath container classpath entries. 
+Note that restrictions are automatically combined along a classpath chain. For instance, if a classpath container entry is
+associated with some restrictions, then when resolved to a set of entries, these will automatically inherit the
+container restrictions (and could still provide further custom restrictions on a per entry basis).
+<p>
+When a forbidden reference to a restricted type is detected, the compiler will issue a problem which severity
+can be controlled by JavaCore preference "org.eclipse.jdt.core.compiler.problem.forbiddenReference". 
+Corresponding problem marker ID is <code>IProblem.ForbiddenReference</code>.
+<pre>
+* COMPILER / Reporting Forbidden Reference to Type with Restricted Access
+*    When enabled, the compiler will issue an error or a warning when referring to a type with restricted access, as defined according
+*    to the access restriction specifications.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.forbiddenReference"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+
+<p>
+In order to challenge this new functionality before leveraged in UI or PDE, Eclipse developpers need to perform
+the following two actions:
+<ol>
+<li> edit some .classpath file to exclude all types located in "**/internal/" packages from prerequisites;
+i.e. replace line
+<pre>
+	&lt;classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/&gt;
+</pre>
+with
+<pre>
+	&lt;classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins" excluding="**/internal/"/&gt;
+</pre>
+</li>
+<li> enable compiler warning for forbidden references, i.e. add the following line to the workspace 
+default preferences located in: <code>&lt;workspace&gt;\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.core.prefs</code>
+<pre>
+	org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+</pre>
+Note: alternatively, it could be specified on a per project basis, by adding line to <code>&lt;project&gt;/.settings/org.eclipse.jdt.core.prefs</code>.
+</li>
+</ol>
+</li>
+<li>Static imports are now supported:
+<pre>
+<b><font color="#0000ff">import static</font></b> <i><font color="#A0A0A0">type</font></i>.*;
+<b><font color="#0000ff">import static</font></b> <i><font color="#A0A0A0">type</font></i>.<i><font color="#A0A0A0">identifier</font></i>;
+</pre>
+Java Search is also able to find referenced type, field and/or member in static imports but required the index version to be incremented.<br>
+Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76324">76324</a>
+[Javadoc] Wrongly reports invalid link format in @see and @link
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74369">74369</a>
+[Javadoc] incorrect javadoc in local class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75701">75701</a>
+[Javadoc] References in Javadoc to deprecated members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53977">53977</a>
+[DCR] [Javadoc] Add a Javadoc option not to report errors on non-visible references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76360">76360</a>
+[1.5] NPE when using static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76174">76174</a>
+[1.5] missing error when using static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76159">76159</a>
+Missing type in hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76328">76328</a>
+Using latest, NPE in codeassist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66296">66296</a>
+Slow closing editor after startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76277">76277</a>
+IllegalArgumentException: Invalid string literal : &gt;("i" + "ib2")&lt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76190">76190</a>
+DCR AST: EnumDeclaration: Separate field and body statement lists
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76244">76244</a>
+[1.5] No error on invalid static import declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76181">76181</a>
+Formatter fails on EnumDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74776">74776</a>
+[Search] Wrong search results for almost identical method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29865">29865</a>
+Source visibility in project dependency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76181">76181</a>
+Formatter fails on EnumDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76100">76100</a>
+AST: Javadoc node not available on AnnotationTypeDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76103">76103</a>
+[1.5] Inner AnnotationTypeDeclaration not parsed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76027">76027</a>
+Optimization of code assist in debugger
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75090">75090</a>
+source positions calculated wrongly
+
+
+<a name="v_514"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 12th October 2004
+<br>Project org.eclipse.jdt.core v_514
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_514">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Type search works with generic (only for string pattern, see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75641#c4">75641</a>).<br>
+For example, user can enter <i><code>List&lt;String&gt;</code></i> in Java Search text and search for type references.<br>
+Match(es) will be found if this parameterized type is used in the search scope.<br>
+Note that some API changes still need to be done to make generic type search work while selecting a parameterized type from Java editor.
+</li>
+<li>Field search works with generic (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73277">73277</a>).<br>
+For example, user can search for references to a field declared as <pre>List&lt;String&gt; ls;</pre>
+Match(es) will be found if this field is used in the search scope.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75649">75649</a>
+[1.5] completion inside a wildcard does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52379">52379</a>
+JavaElement.getElementInfo no longer works
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74753">74753</a>
+[1.5] codeassist failing on type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73277">73277</a>
+[1.5][Search] Fields search does not work with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73671">73671</a>
+[1.5] Signature.getTypeArguments should also tolerate normal types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73078">73078</a>
+ISourceManipulation.delete() tries to run in WorkspaceRoot scheduling rule
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75561">75561</a>
+Rename package results in I/O exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75644">75644</a>
+Array index out of bounds doing code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74286">74286</a>
+IllegalArgumentException during codeselect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75720">75720</a>
+[1.5] Formatter cannot format code that contains varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75112">75112</a>
+[Search] Cannot find reference to a member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75632">75632</a>
+Infinite loop in DefaultCommentMapper#storeLeadingComments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75658">75658</a>
+[1.5] SourceElementParser do not compute correctly bounds of type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75488">75488</a>
+Incorrect code formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70602">70602</a>
+Why is equals(..) method of IBindings not implemented?
+
+<a name="v_513"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 5th October 2004
+<br>Project org.eclipse.jdt.core v_513
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_513">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The batch compiler now support 5 as a valid version number for -target and -source options.
+5 is equivalent to 1.5.</li>
+<li>Added support for static imports. Can now import all static members of a type, such as <code>java.lang.Math</code>.</li>
+<li>Added new API <code>IBinding#getJavaElement()</code> to get the Java element corresponding to a 
+     <code>org.eclipse.jdt.core.dom.IBinding</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75466">75466</a>
+[1.5] IAE in JavaElement.exists() for Collection&lt;E&gt;#containsAll(Collection&lt;?&gt;)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75455">75455</a>
+[1.5] IAE on Content Assist for variable of type List&lt;? extends Number&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75489">75489</a>
+Batch compiler should support -target 5 or -source 5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73963">73963</a>
+[1.5] Wrong errors in widening reference conversion to parameterized class type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75221">75221</a>
+Failure in test for build I200409281200 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74126">74126</a>
+Compiler should support new hexadecimal floating-point literals
+
+<a name="v_512"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M3 - 28th September 2004
+<br>Project org.eclipse.jdt.core v_512
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_512">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74761">74761</a>
+[1.5] Invalid compiler binding for qualified raw type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68927">68927</a>
+'non-static access to static member' problem not reported for super field access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74938">74938</a>
+Syntax error for annotation in 1.4 has unknown source range
+
+<a name="v_511"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 24th September 2004 - 3.1 MILESTONE 2
+<br>Project org.eclipse.jdt.core v_511
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_511">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74934">74934</a>
+ArrayIndexOutOfBoundsException with float literal
+
+<a name="v_510"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 23rd September 2004
+<br>Project org.eclipse.jdt.core v_510
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_510">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Support for hexadecimal floating-point literals has been added. This is available in 1.5 mode only.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72583">72583</a>
+[1.5] NPE in Scope.minimalErasedCandidate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74096">74096</a>
+[1.5] visibility check ignores type bounds?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74592">74592</a>
+[1.5] Invalid cycle diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74420">74420</a>
+[1.5] Unexpected "Illegal forward reference to type parameter T"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74519">74519</a>
+Can declare @interface in 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74544">74544</a>
+[1.5] Invalid compiler binding for parameterized qualified type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74514">74514</a>
+NPE in AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74014">74014</a>
+prefix path for source attachements - automatic detection does not seem to work 
+
+<a name="v_509"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 21st September 2004
+<br>Project org.eclipse.jdt.core v_509
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_509">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74355">74355</a>
+-source 1.4 and -1.5 leads to an error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74320">74320</a>
+[1.5] Unused private member diagnosis fooled by generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74289">74289</a>
+AIOOB Exception in WeakHashSet.cleanupGarbageCollectedValues 
+
+
+<a name="v_508"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 20th September 2004
+<br>Project org.eclipse.jdt.core v_508
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_508">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73740">73740</a>
+Diagnosis for serialization should not render j2me development impossible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74244">74244</a>
+[1.5] boolean.class == Boolean.TYPE should be true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73995">73995</a>
+[Javadoc] Wrong warning for missing return type description for @return {@inheritDoc}
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72644">72644</a>
+[1.5] Problems with generic maps
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73356">73356</a>
+Index not updated after adding a source folder 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73961">73961</a>
+IPackageBinding#getName() should return "" for default package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73933">73933</a>
+Clarifications of the DOM/AST API for VariableDeclarationExpression and VariableDeclarationStatement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73891">73891</a>
+Should not use String#intern() 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73837">73837</a>
+Java 1.5 generics problem (Eclipse 3.1M1)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73336">73336</a>
+[1.5][search] Search Engine does not find type references of actual generic type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73762">73762</a>
+Line ends not reset when setting a different source 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73884">73884</a>
+[1.5] Unexpected error for class implementing generic interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73896">73896</a>
+StackOverflowError resolving bindings of java.util.Collections
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73678">73678</a>
+[1.5] NPE when saving an editor which contains genric type
+
+<a name="v_507"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 14th September 2004
+<br>Project org.eclipse.jdt.core v_507
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_507">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72683">72683</a>
+Slow code assist in Display view 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73696">73696</a>
+searching only works for IJavaSearchConstants.TYPE, but not CLASS or INTERFACE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73479">73479</a>
+[Javadoc] Improve error message for invalid link in @see tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73551">73551</a>
+[Search] NPE while searching package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73112">73112</a>
+[Search] SearchEngine doesn't find all fields multiple field declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71267">71267</a>
+[Search][Javadoc] SearchMatch in class javadoc reported with element of type IImportDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73348">73348</a>
+[Javadoc] Missing description for return tag is not always warned
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73573">73573</a>
+[1.5] - CodeAssist - ArrayIndexOutOfBoundsException with genric type completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67976">67976</a>
+Exceptions in log when Opening type while checking out 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72684">72684</a>
+MemberElementInfo#name should be removed 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73530">73530</a>
+[1.5] VerifyError using generics and direct array access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73286">73286</a>
+NPE on save
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73497 ">73497</a>
+Problem methods don't point to the right position in source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73561">73561</a>
+AST: Enum constant source range too small
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71279">71279</a>
+[Search] NPE in TypeReferenceLocator when moving CU with unresolved type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67981">67981</a>
+Add Java Exception Breakpoint is broken 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72859">72859</a>
+NPE in ASTConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72214">72214</a>
+[Prefs] IllegalStateException when importing preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62472">62472</a>
+[1.5] Suspicious syntax errors for missing semicolon
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72889">72889</a>
+same key different types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68555">68555</a>
+SearchEngine errors when package and class named the same
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72891">72891</a>
+missing type parameters for IMethodBindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72882">72882</a>
+ITypeBinding.getQualifiedName for type variables wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73371">73371</a>
+[1.5] Code formatter doesn't seem to accept enum declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73048">73048</a>
+Stackoverflow on AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69002">69002</a>
+CompilationUnit#destroy contains e.printStackTrace 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70787">70787</a>
+Compilation warning for IndexManager 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73245">73245</a>
+Error source range of 'class cannot be superinterface'
+
+<a name="v_506"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 7th September 2004
+<br>Project org.eclipse.jdt.core v_506
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_506">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li><code>ITypeParameter</code>s are no longer children of their <code>IType</code> or <code>IMethod</code>.
+     To get the type parameters of a type or a method use <code>IType/IMethod#getTypeParameters()</code>.</li>
+<li>The temporary field <code>TypeParameter#ENABLED</code> has been removed.</li>
+<li>Code select (<code>ICodeAssist#codeSelect()</code>) return a <code>ITypeParameter</code> when a type
+    parameter is selected.</li>
+<li>Added optional compiler diagnosis for usage of 'enum' as an identifier.
+Corresponding problem ID is IProblem.UseEnumAsAnIdentifier.
+</li>
+<li>
+<pre>
+* COMPILER / Reporting Usage of 'enum' Identifier
+*    When enabled, the compiler will issue an error or a warning whenever 'enum' is 
+*    used as an identifier (reserved keyword in 1.5)
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.enumIdentifier"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66533">66533</a>
+[1.5] add a warning for 'enum' used as identifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70892">70892</a>
+[1.5][Javadoc] Compiler should parse reference for inline tag @value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73255">73255</a>
+[1.5][reconciling] ClassCastException in SourceTypeElementInfo#getTypeParameterBounds 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72946">72946</a>
+Refactoring context menu does not show inline action on local variables [refactoring] [inline temp]
+
+<a name="v_505"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 31st August 2004
+<br>Project org.eclipse.jdt.core v_505
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_505">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added empty "performance" target to test.xml files.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72772">72772</a>
+[1.5][Search Engine] ClassCastException: org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding
+
+<a name="v_504"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 31st August 2004
+<br>Project org.eclipse.jdt.core v_504
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_504">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new Java element <code>ITypeParameter</code> that represents a formal type parameter in a generic type or method.
+     Note types and methods should have type parameters as children, but this is currently disabled as JDT UI doesn't support
+     this kind of element yet.
+     To enable set <code>org.eclipse.jdt.internal.core.TypeParameter#ENABLED</code> to <code>true</code>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72942">72942</a>
+[1.5] 'AT' is visible inside syntax error messages 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68343">68343</a>
+IDOMType.setSuperInterfaces() with empty array has no impact on Interfaces 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72083">72083</a>
+[1.5] NPE while compiling FindBugs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71080">71080</a>
+[1.5] Type parameter bound &lt;E extends Enum&lt;E&gt;&gt; should be allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62070">62070</a>
+Should revisit reference recording
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36397">36397</a>
+Compiling source which indirectly references unavailable classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62822">62822</a>
+[1.5] Bound mismatch: The type X is not a valid substitute for the bounded parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72094">72094</a>
+NPE inside qualified type reference resolution
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72468">72468</a>
+"hierarchy of ... type is inconsistent" error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59082">59082</a>
+[1.5] Should not offer argument completion for non generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72501">72501</a>
+[1.5] CodeAssist - ArrayIndexOutOfBoundsException with ParameterizedQualifiedTypeReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72640">72640</a>
+Codestream target level is initialized with source level
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72560">72560</a>
+[1.5] VerifyError in nested generics loop
+
+<a name="v_503"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M2 - 24th August 2004
+<br>Project org.eclipse.jdt.core v_503
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_503">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>All resource change listeners/builder now react to new encoding change notification.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70193">70193</a>
+DBCS - The GB18030 character cannot be correctly generated into ".classpath" file when new a source folder named with GB18030 character. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70997">70997</a>
+Debugger doesn't stop in finally block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=47074">47074</a>
+inability to detect invalid cast between interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71910">71910</a>
+Weird exception handlers ranges with any exception handlers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72352">72352</a>
+"No completion available" after cast to "String[]"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71702">71702</a>
+code completion doesn't work anymore after Array cast. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68847">68847</a>
+[1.5] DCR Signature: API to separate raw type and type parameters 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72348">72348</a>
+[1.5][Type Hierarchy] Super type hierarchy of class extending generic type is empty 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72105">72105</a>
+[1.5] NPE in SelectionEngine.selectFrom 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72230">72230</a>
+[1.5][Type Signature] IAE in createCharArrayTypeSignature 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68506">68506</a>
+Java code formatter strips newline, leaving final line unterminated!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59052">59052</a>
+[1.5][reconciling] DOM conversion incomplete for generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72248">72248</a>
+[1.5] StackOverflowError caused by methods type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72233">72233</a>
+IAE creating AST for java.lang.SuppressWarnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57585">57585</a>
+memory optimization in JavaModelCache 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72238">72238</a>
+[1.5] CodeAssist - Wrong completion inside parameterized type 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68585">68585</a>
+index is out of date after encoding change 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68594">68594</a>
+[1.5] NPE after code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70995">70995</a>
+[1.5] Add 1.5 constructs in the code formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68842">68842</a>
+[1.5] AST: parameter type binding: getKey seems wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71852">71852</a>
+ClassCastException in HandleFactory.createElement(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69066">69066</a>
+[1.5] getTypeArguments incorrect (?) when type argument is a type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68838">68838</a>
+[1.5] AST: Missing bindings in type parameters
+	  	
+<a name="v_502"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M1 - 10th August 2004 - 3.1 MILESTONE 1
+<br>Project org.eclipse.jdt.core v_502
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_502">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66908">66908</a>
+Code assist javadoc confused by duplicate java.lang.String
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66570">66570</a>
+Code assist fails due to capitalization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71705">71705</a>
+[1.5] CodeAssist failure with simple test case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69598">69598</a>
+[1.5] Auto Completion not available in new for-loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71672">71672</a>
+[1.5] MethodInvocation has no type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67790">67790</a>
+[1.5] AST: ConstructorInvocation type arguments not in source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70292">70292</a>
+[1.5] enum makes Copy, Cut commands fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71241">71241</a>
+[1.5] different methods with same erasure should not override
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69901">69901</a>
+[1.5] Interface / Generic: unchecked conversion should throw a warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71467">71467</a>
+JavaConventions.ValidatePackageName() does not return ERROR
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71113">71113</a>
+[1.5] improve DOM/AST specs for bindings for JLS3 constructs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71079">71079</a>
+[1.5] ClassCastException resolving Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70969">70969</a>
+[1.5] compile error with conditional operator and wildcards
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70611">70611</a>
+[1.5] Specific generic class declaration breaks save and load
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69931">69931</a>
+JDTCompilerAdapter prevents use of Cheetah
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71007">71007</a>
+[1.5] Qualified name not supported as member value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70984">70984</a>
+[1.5] Invalid syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70986">70986</a>
+[Prefs] Old Java project prefs are not all stored while migrating to new API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70975">70975</a>
+[1.5] Type mismatch when compiling against binary generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70656">70656</a>
+[1.5] StackOverflow when resolving Enum&lt;FormattedFloatingDecimal$Form&gt; 
+
+
+<a name="v_501"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M1 - 27th July 2004 - Codename "Cheetah"
+<br>Project org.eclipse.jdt.core v_501
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_501">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Plugin version ID got incremented to 3.1.0. </li>
+<li>Added support for method return type covariance</li>
+<li>Added optional compiler diagnosis for serializabe classes missing a declaration of serialVersionUID field.
+Corresponding problem ID is IProblem.MissingSerialVersion.
+</li>
+<pre>
+* COMPILER / Reporting Missing Declaration of serialVersionUID Field on Serializable Class
+*    When enabled, the compiler will issue an error or a warning whenever a serializable class is missing a local declaration 
+*    of a serialVersionUID field. This field must be declared as static final and be of type long.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.missingSerialVersion"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+<li>Added <code>isConstructor()</code> and <code>isSynthetic()</code> getters to MethodReferenceMatch.
+<br>
+When a search requestor (<code>SearchRequestor</code>) accepts this kind of match,
+it can now distinguish between method and constructor reference matches. It can also know
+if a constructor reference match is a default constructor or use an implicit super call.
+<br>
+Note that synthetic method reference match is not supported yet.
+</li>
+<li>Once 1.5 source compliance is enabled, the typecheck rules for conditional operator (a ? b : c) 
+allows scenario where 'b' and 'c' have a common supertype (i.e. it is no longer required for
+one to be assignable to the other as in the past). This is required by JLS 3rd edition.
+</li>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69028">69028</a>
+     requires the index version to be incremented. Indexes will be automatically regenerated upon
+     subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>The spec for MethodDeclaration.typeParameters was changed to remove the
+clause that said that type parameters were not meaningful for
+constructors. According to the latest JLS3, both constructors and methods
+are allowed to have type parameters.
+(bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70665">70665</a>).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48336">48336</a>
+[Search] Participants should surface in search progress
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70598">70598</a>
+[Encoding] ArrayIndexOutOfBoundsException while testing BOM on *.txt files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70767">70767</a>
+[1.5] NPE compiling code with explicit constructor invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70717">70717</a>
+Batch compiler should report compilation errors to console
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70665">70665</a>
+[DOM/AST] missing type parameters for constructor declaration in JLS3
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70618">70618</a>
+[1.5] Variable T should be allowed as argument of supertype
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70616">70616</a>
+[1.5] Unable to bind type variable in binary from Enum&lt;E&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70609">70609</a>
+[1.5] NPE compiling Container
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70606">70606</a>
+[1.5] ClassCastException compiling DefaultTreeCellEditor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69351">69351</a>
+[1.5] Error should be issued if generic type is extending Throwable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62822">62822</a>
+[1.5] Bound mismatch: The type X is not a valid substitute for the bounded parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69626">69626</a>
+[1.5] The return type is incompatible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=41018">41018</a>
+Method reference with member type parameter(s) not found
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70053">70053</a>
+[1.5] VerifyError - incompatible argument to function
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69942">69942</a>
+compiler warning for serializable classes that do not explicitly declare serialVersionUID
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70398">70398</a>
+Java AST creation error due to NullPointerException in IF statement test block.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43587">43587</a>
+Searching for references to default constructors reports questionable results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70243">70243</a>
+[1.5] no warning for unsafe cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69799">69799</a>
+[1.5] NPE when saving File with forEach loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69320">69320</a>
+[1.5] generic parameter type compiles by eclipse, not by javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69800">69800</a>
+[1.5] eclipse fails to report incompatible types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70295">70295</a>
+[1.5] method(Class&lt;?>) is not applicable for Class&lt;? extends Object&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70247">70247</a>
+[1.5] NPE in TypeVariableBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68726">68726</a>
+[Javadoc] Target attribute in @see link triggers warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68993">68993</a>
+IllegalArgumentException when opening project preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69806">69806</a>
+formatter doesn't handle strictfp correctly.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69776">69776</a>
+[1.5] VerifyError: Incompatible object argument for function call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69713">69713</a>
+[1.5] Cannot save java document, throws nullpointer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69542">69542</a>
+[1.5] ByteCode differs from javac ByteCode in behaviour
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69554">69554</a>
+Eclipse Java compiler is not completely compliant to Javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69658">69658</a>
+typo in javadoc of ClassInstanceCreation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69308">69308</a>
+All ASTNodes that deal with modifiers should offer a method setModifiers(List modifiers)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69302">69302</a>
+[Javadoc] Invalid reference warning inconsistent with javadoc tool
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69275">69275</a>
+[Javadoc] Invalid warning on @see link
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69272">69272</a>
+[Javadoc] Invalid malformed reference (missing separator)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68087">68087</a>
+[Javadoc] '-' character should be accepted in tag names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68025">68025</a>
+Javadoc processing does not detect some wrong links
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68017">68017</a>
+Javadoc processing does not detect missing argument to @return
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69573">69573</a>
+[1.5] Missing Message for Compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69028">69028</a>
+Anonymous type in argument of super() is not in type hierarchy 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69375">69375</a>
+[1.5] wildcards: no error for incorrect assignment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68698">68698</a>
+Bug in inner class emulation:compiler doesn't reject illegal code.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69359">69359</a>
+[1.5] Trouble with "unnecassary cast" warnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69271">69271</a>
+decimal integer literals should not consist of FULL WIDTH Unicode digits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69349">69349</a>
+[DOM/AST] Wrong end position for method declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69152">69152</a>
+[NPE] An internal error occurred during: "Override indicator installation job". 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68010">68010</a>
+[1.5] Return type of bridge method is not correct inside outliner 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69170">69170</a>
+[1.5] no error for new T[0]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69353">69353</a>
+[1.5] Should reject usage of type parameter in catch block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69288">69288</a>
+[1.5] Unsafe type operations should be reported against individual expressions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64305">64305</a>
+[1.5] Bad "return type is incompatible" error for array values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69251">69251</a>
+[1.5] can't instantiate bounded wildcard
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69141">69141</a>
+[1.5] Wildcards with lower bound do not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69276">69276</a>
+[1.5] NPE in ReturnStatement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64154">64154</a>
+[1.5] incorrect 'constructor not visible'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65943">65943</a>
+Closing/opening a project doesn't have the correct delta 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68998">68998</a>
+[1.5] NPE in java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68146">68146</a>
+Search should not populate Java model cache 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67789">67789</a>
+Java element delta from refresh contains excluded package 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68845">68845</a>
+[1.5] AST: AbstractTypeDeclaration should have resolveBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66512">66512</a>
+Invalid classpath entry not rejected 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67643">67643</a>
+[1.5] Incompatible conditional operand types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68981">68981</a>
+[1.5] NPE in code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68891">68891</a>
+[1.5] TypeVariableBinding does not know his declaring type or method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68862">68862</a>
+[1.5] ClassCastException when moving a a java file 
+
+<a name="v_500"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse SDK 3.1M1 - 29th June 2004 - Codename "Cheetah"
+<br>Project org.eclipse.jdt.core v_500 (Cheetah06)
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_500">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>From target 1.5 on, the JSR bytecode instruction is no longer generated. As a consequence, the 
+    corresponding compiler option status will be ignored as soon as -target 1.5 is specified.
+</li>
+<li>Batch compiler defaults to 1.5 source and target, when toggled in 1.5 compliant mode ("-1.5").
+</li>
+<li>Added support for generics to JavaModel, thus enabling editor problem reconciling, outliner, type hierarchies. </li>
+<li>Improved codeassist and codeselect handling of generics </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68837">68837</a>
+[1.5] AST: Missing source range in parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68133">68133</a>
+[1.5] VerifyError: Code segment has wrong length in class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68863">68863</a>
+Missing entry in local variable attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68440">68440</a>
+[1.5] VerifyError with new for loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64159">64159</a>
+[1.5] call to addAll(Collection&lt;? extends T&gt;) incorrectly dissalowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68602">68602</a>
+[1.5] AST converter fails on local types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66424">66424</a>
+[1.5] Collections in new style for loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64417">64417</a>
+[1.5] NPE in SourceTypeBinding.resolveTypesFor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68730">68730</a>
+[1.5] No completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65953">65953</a>
+[1.5] Internal Compiler Error: ArrayIndexOutOfBoundsException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58470">58470</a>
+[1.5] Source mapper fooled by generics 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64336">64336</a>
+[1.5] Signature does allow to create parameterized type signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68557">68557</a>
+[1.5] ArrayIndexOutOfBoundsException in SourceTypeConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68006">68006</a>
+[1.5] Invalid modifier after parse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65503">65503</a>
+[1.5] "new" for-loop inside "old" for-loop gives error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65870">65870</a>
+[1.5] AST creation fails when created with comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64301">64301</a>
+[1.5] Cast required where no cast should be required
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63556">63556</a>
+[1.5] Error when creating generic classes specializing distant generic parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63590">63590</a>
+[1.5] Cheetah allows generic throws clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63555">63555</a>
+[1.5] Cannot put generic type fields inside static inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58722">58722</a>
+[1.5] cannot extend interfaces
+
+
+<a name="v_429_Cheetah05"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Eclipse SDK 3.1M1 - 15th May 2004
+<br>Project org.eclipse.jdt.core v_429_Cheetah05
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_429_Cheetah05">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Cast/instanceof operations are now fully supported, along with extra diagnosis for unsafe type operations.
+</li>
+<li>
+Explicit parameterizations of message sends and constructor calls are also supported.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62416">62416</a>
+[1.5] An error has occurred when creating this (Java) editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=62292">62292</a>
+[1.5] Missing receiver in parameterized message send
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61507">61507</a>
+[1.5] NPE in computeCompatibleMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60681">60681</a>
+[1.5] Return type not strict enough
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60563">60563</a>
+[1.5] VerifyError when using generics and arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59258">59258</a>
+Possibility to share compiler preferences for a shared project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=60556">60556</a>
+[1.5] Collections.unmodifiableList(List&lt;A&gt;)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58978">58978</a>
+[1.5] Generic method needs better error reporting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59983">59983</a>
+[1.5] Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58903">58903</a>
+[1.5] Implementing inherited generic methods
+
+
+<a name="v_422_Cheetah04"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Eclipse SDK 3.1M1 - 23th April 2004
+<br>Project org.eclipse.jdt.core v_422_Cheetah04
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_422_Cheetah04">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Wildcard type compatibilities got reworked quite significantly. In
+particular, it now diagnoses
+usage of methods which parameters are of wildcard type (see 59641).
+</li>
+<li>
+Covariance is still not supported, but the Cheetah can now issue synthetic
+bridge methods for allowing overriding to parameterized methods.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59723">59723</a>
+[1.5] Compiler rejects usage of ArrayList.toArray(char[][])
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59628">59628</a>
+[1.5] Erroneous diagnosis for missing abstract method implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59641">59641</a>
+[1.5] Compiler should refuse usage of wildcard argument values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=59147">59147</a>
+[1.5] Compiler rejects correct code with wildcards and raw types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58979">58979</a>
+[1.5] NullPointerException in compiler
+
+
+<a name="v_421_Cheetah03"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Eclipse SDK 3.1M1 - 16th April 2004
+<br>Project org.eclipse.jdt.core v_421_Cheetah03
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_421_Cheetah03">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+The Cheetah is now able to digest generic methods and perform type inference.
+It also recognizes the Object.getClass() method and perform adequate
+substitutions (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57784">57784</a>).
+</li>
+<li>
+Generic types completion is available and type parameters are proposed
+as possible completions.
+Currently type parameter proposals are given by
+ICompletionRequestor#acceptClass().
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58715">58715</a>
+[1.5] The return type is incompatible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58631">58631</a>
+[1.5] Cycle in hierarchy no longer detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58666">58666</a>
+[1.5] Object.getClass() need to be treated special ?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57784">57784</a>
+[1.5] Errors using Arrays.asList(T [])
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=58461">58461</a>
+[1.5] java.lang.VerifyError from enhanced for loop
+
+
+<a name="v_421_Cheetah02"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Eclipse SDK 3.1M1 - 13th April 2004
+<br>Project org.eclipse.jdt.core v_421_Cheetah02
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_421_Cheetah02">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Properly decode signatures of parameterized member types which are flourishing in 1.5 class libs,
+ and were reported as bogus inconsistencies with Cheetah01.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53036">53036</a>
+Incorrect highlighting for type problem in qualified type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57716">57716</a>
+[1.5] NPE compiling SelectionParser in source 1.5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57397">57397</a>
+[1.5] Unable to save unit
+
+<a name="v_420_Cheetah01"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java development tools core</h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Eclipse SDK 3.1M1 - 4th April 2004
+<br>Project org.eclipse.jdt.core v_420_Cheetah01
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_420_Cheetah01">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> JDK 1.5 support.
+<li> JavaCore 1.5 specific options. Either augmented to consider 1.5 or added.
+<pre>
+* COMPILER / Setting Compliance Level
+*    Select the compliance level for the compiler. In "1.3" mode, source and target settings
+*    should not go beyond "1.3" level.
+*     - option id:         "org.eclipse.jdt.core.compiler.compliance"
+*     - possible values:   { "1.3", "1.4", "1.5" }
+*     - default:           "1.4"
+* 
+* COMPILER / Setting Source Compatibility Mode
+*    Specify whether which source level compatibility is used. From 1.4 on, 'assert' is a keyword
+*    reserved for assertion support. Also note, than when toggling to 1.4 mode, the target VM
+*   level should be set to "1.4" and the compliance mode should be "1.4".
+*   Source level 1.5 is necessary to enable generics, autoboxing, covariance, annotations, enumerations
+*   enhanced for loop, static imports and varargs. Once toggled, the target VM level should be set to "1.5"
+*   and the compliance mode should be "1.5".
+*     - option id:         "org.eclipse.jdt.core.compiler.source"
+*     - possible values:   { "1.3", "1.4", "1.5" }
+*     - default:           "1.3"
+* 
+* COMPILER / Defining Target Java Platform
+*    For binary compatibility reason, .class files can be tagged to with certain VM versions and later.
+*    Note that "1.4" target require to toggle compliance mode to "1.4" too. Similarily, "1.5" target require
+*    to toggle compliance mode to "1.5".
+*     - option id:         "org.eclipse.jdt.core.compiler.codegen.targetPlatform"
+*     - possible values:   { "1.1", "1.2", "1.3", "1.4", "1.5" }
+*     - default:           "1.2"
+* 
+* COMPILER / Reporting Unsafe Type Operation
+*    When enabled, the compiler will issue an error or a warning whenever an operation involves generic types, and potentially
+*    invalidates type safety since involving raw types (e.g. invoking #foo(X&lt;String&gt;) with arguments  (X)).
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+*
+* COMPILER / Reporting final Bound for Type Parameter
+*    When enabled, the compiler will issue an error or a warning whenever a generic type parameter is associated with a 
+*    bound corresponding to a final type; since final types cannot be further extended, the parameter is pretty useless.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.finalParameterBound"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=56731">56731</a>
+[1.5] NPE inside ClassFileStruct when compiling with jre 1.5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=51262">51262</a>
+[1.5] Handling of additional bounds in type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52673">52673</a>
+[1.5] ArrayStoreException in 1.5 parser
+
+
+<p><hr>
+For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html">build notes up to Release 3.0</a>.
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R32_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R32_buildnotes_jdt-core.html
new file mode 100644
index 0000000..37787aa
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R32_buildnotes_jdt-core.html
@@ -0,0 +1,3369 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes 3.2</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.2 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
+	  For more information on 3.2 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.2/index.php#release-plan">JDT/Core release plan</a>, 
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.2/index.php#milestone-plan">milestone plan</a>, 
+	  the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_2.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.0 (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>).
+	  Older changes which occurred up to Release 3.0 can be found in 
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html">build notes R2.1</a>.
+	  -->
+	  This present document covers all changes since Release 3.1 (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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches: 
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>, 
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+<a name="v_671"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2 - 6th June 2006 - 3.2 RELEASE (R3_2)
+<br>Project org.eclipse.jdt.core v_671
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_671">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=145248">145248</a>
+MD5 checksums missing for JDT Core Batch Compiler JARs
+
+<a name="v_670"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC7 - 2nd June 2006 - 3.2 RELEASE CANDIDATE 7
+<br>Project org.eclipse.jdt.core v_670
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_670">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=140879">140879</a>
+Spontaneous error &quot;java.util.Set cannot be resolved...&quot;
+
+<a name="v_669"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC7 - 2nd June 2006
+<br>Project org.eclipse.jdt.core v_669
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_669">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=144504">144504</a>
+JDT Core model JUnit tests fail when ordering of methods reversed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143718">143718</a>
+[1.6][compiler] ClassFormatError : wrong stack map frame is used
+
+<a name="v_668"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC6 - 26th May 2006 - 3.2 RELEASE CANDIDATE 6
+<br>Project org.eclipse.jdt.core v_668
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_668">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=142793">142793</a>
+NPE in core.dom.ASTConverter.createFakeEmptyStatement results in java.lang.OutOfMemory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142653">142653</a>
+[1.5][compiler] JDT Internal Compiler Error: NullPointerException in MethodVerifier.computeInheritedMethods(), Eclipe 3.2RC4
+
+<a name="v_667"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC5 - 19th May 2006 - 3.2 RELEASE CANDIDATE 5
+<br>Project org.eclipse.jdt.core v_667
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_667">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=142087">142087</a>
+[1.5][compiler] NPE in computeCompatibleMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141800">141800</a>
+[1.5][compiler] Necessary cast is marked as "unnecessary" for cast check in 3.2RC4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141949">141949</a>
+Missing usage restrictions specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142001">142001</a>
+[batch][options] Typo in help message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141797">141797</a>
+Spelling mistakes in JDT error messages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141704">141704</a>
+[1.5][compiler] Eclipse 3.2RC4 Doesn't recognize implemented method by abstract class
+
+<a name="v_666"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC4 - 11th May 2006 - 3.2 RELEASE CANDIDATE 4
+<br>Project org.eclipse.jdt.core v_666
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_666">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=139931">139931</a>
+[1.5][compiler] Unnecessary cast warning and varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140569">140569</a>
+[1.5][compiler] Ambiguous conversion from generic to parameterized/raw type confuses Eclipse's way of resolving unresolved binary references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141155">141155</a>
+[1.5][compiler] Enum valueOf(String) method should not be final
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127766">127766</a>
+[1.5][compiler] inconsistent treatment of explicit subclasses of Enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140750">140750</a>
+java.lang.IllegalStateException: zip file closed on typing while &quot;Computing additional info&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140318">140318</a>
+AST: Invalid annotation binding for incomplete code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140873">140873</a>
+No version range specified when requiring bundles
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140643">140643</a>
+[compiler] $foo() not found in anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140301">140301</a>
+API documentation of CharOperation.camelCaseMatch/4 is wrong or misleading
+
+<a name="v_665"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC3 - 5th May 2006 - 3.2 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_665
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_665">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Reverting change for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140262">140262</a>.
+     Note that ver665 is no longer used and has been removed from CVS.</li>
+</ul>
+
+<a name="v_664"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC3 - 4th May 2006
+<br>Project org.eclipse.jdt.core v_664
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_664">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=140168">140168</a>
+Ambiguous Failure in Connection with Varargs
+
+<a name="v_663"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC3 - 4th May 2006
+<br>Project org.eclipse.jdt.core v_663
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_663">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=138577">138577</a>
+Package content disapear in package explorer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139937">139937</a>
+CompletionContext not automatically accepted when using IEvaluationContext
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139689">139689</a>
+NPE in packages explorer
+
+<a name="v_662"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC3 - 2nd May 2006 
+<br>Project org.eclipse.jdt.core v_662
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_662">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=139099">139099</a>
+[compiler] Ambiguous method regression error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139137">139137</a>
+Increment build failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139160">139160</a>
+IMethod#getParameterNames() should not throw JME if javadoc not parseable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139279">139279</a>
+Fup of bug 134110, got CCE changing an external jar contents and refreshing the project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138999">138999</a>
+Regression: Fix for 128258 introduces regression in JavaProject.exists()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139569">139569</a>
+Batch compiler should check if java home is null when trying to set the extDirs and endorsed dirs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139525">139525</a>
+[1.5][compiler] Valid generics involved assignment is flagged as an error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106631">106631</a>
+Access rule has no effect
+
+
+<a name="v_661"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC2 - 28th April 2006 - 3.2 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_661
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_661">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Released an improvement for performance tests</li>
+</ul>
+
+<a name="v_660"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC2 - 27th April 2006
+<br>Project org.eclipse.jdt.core v_660
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_660">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=95839">95839</a>
+[ast rewrite] problems with single line comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138672">138672</a>
+Bad code completion formatting for Collections.synchronizedMap
+
+
+<br><a name="v_659"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC2 - 27th April 2006
+<br>Project org.eclipse.jdt.core v_659
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_659">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=129814">129814</a>
+NPE due to CompilationUnit.getContents() returning null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138684">138684</a>
+Javadoc of ASTRewrite.getExtendedSourceRangeComputer() refers to inexistent class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135323">135323</a>
+[compiler] Anonymous inner class scope error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138435">138435</a>
+[search] Stack trace while searching
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138167">138167</a>
+Java Model Exception when proposal window opened
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136095">136095</a>
+Type Hierarchy incomplete with illegally parameterized superinterfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138507">138507</a>
+exception in .class file editor for classes imported via plug-in import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138432">138432</a>
+Spec of ICodeAssist#codeSelect() doesn't describe the behavior of empty selection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127570">127570</a>
+[compiler][null] lazy initialization coding pattern within loops
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136508">136508</a>
+Inner Classes in Interfaces No Longer Compiles
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97085">97085</a>
+(3.1M7) Static import code assist shouldn't propose &lt;package&gt;.*;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137984">137984</a>
+[search] Field references not found when type is a qualified member type [regression]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136580">136580</a>
+[ast rewrite] Comma is missing between update expressions in the ForStatement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137649">137649</a>
+grammar problem in progress message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133737">133737</a>
+[1.5][compiler] Eclipse compiler compiles program but javac does not (1 of 2)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129388">129388</a>
+[1.5][compiler] Non-public Junit Assert.format accessible to test cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137634">137634</a>
+CompilationParticipant not correctly recording new dependencies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135729">135729</a>
+Cant resolve class A, if class A was enhanced in a post compilation step
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90438">90438</a>
+[compiler][1.5] Two problems: Automatically generated method has wrong generic type; Compilation error with JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95829">95829</a>
+[assist] toArray proposed twice
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137918">137918</a>
+[1.5][compiler] instanceof accepts primitive type as left-hand-side
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137623">137623</a>
+Exception calculating java content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137744">137744</a>
+[compiler] java.lang.ClassFormatError: test/B (Repetitive method name/signature)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80904">80904</a>
+Quick Fix &quot;Assign parameter to new field&quot; doesn't appear with commented type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83685">83685</a>
+[assist] Content assist fails when there's a dot ('.') after type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137203">137203</a>
+[1.5][compiler] enclosing parameterized types seem to confuse eclipse's build process
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137619">137619</a>
+Compiler doesn't log exceptions when a runtime exception occurs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112030">112030</a>
+ContentAssist fails with IllegalArgumentException on primitive array class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137456">137456</a>
+NPE when trying to view a class file with attached source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133491">133491</a>
+Missing code assist in annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137298">137298</a>
+[compiler] Local variables not reported as not been initialized when more than 64 locals are defined
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136972">136972</a>
+[reconciler] Error in static init blok with inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137053">137053</a>
+Better error reporting when the output directory is a file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126419">126419</a>
+ecj should include value of &quot;java.endorsed.dirs&quot; system property in its bootclasspath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137087">137087</a>
+Open Type - missing matches when using mixed case pattern
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135997">135997</a>
+[AST] invalid source range with recovered node
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136678">136678</a>
+missing @param in internal API (Compiler new constructors, options parameter) + spelling mistake
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136946">136946</a>
+[1.5][compiler] internal compiler error -- ArrayOutOfBoundException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136886">136886</a>
+Open declaration gives NPE in Scope.minimalErasedCandidates
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133071">133071</a>
+Cycles are wrongly detected.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136543">136543</a>
+[1.5][compiler] Eclipse gives a "name clash" error while javac accepts the code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134110">134110</a>
+[regression] Does not pick-up interface changes from classes in the build path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104293">104293</a>
+[1.5][DOM] Extract local doesn't replace all occurences of expression.
+
+<a name="v_658"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC1 - 13th April 2006 - 3.2 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_658
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_658">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fixed failing test on Linux and MacOS</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_657"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC1 - 12th April 2006
+<br>Project org.eclipse.jdt.core v_657
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_657">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=99729">99729</a>
+[ast rewrite] first annotation not on new line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136313">136313</a>
+Open Type is case-sensitive
+
+<a name="v_656"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC1 - 12th April 2006
+<br>Project org.eclipse.jdt.core v_656
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_656">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+CamelCase patterns now accept lowercases (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130390">130390</a>).<br>
+For example, <code>NuPoEx</code> type string pattern will match <code>NullPointerException</code> type but will not match <code>NoPermissionException</code>.<br>
+This allow user to reduce matches list on small or common patterns.<br>
+</li>
+<li>
+Search Engine now returns subclasses as exact matches while searching for implementors of a class
+(see bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124645">124645</a> and
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122442">122442</a>).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81949">81949</a>
+[1.5][compiler] Cycle detected / type hierarchy error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106450">106450</a>
+[1.5][assist] Code assist doesn't propose methods when hinting generic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124645">124645</a>
+[search] for implementors does not find subclasses of binary classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133848">133848</a>
+-sourcepath should also be supported for jars and zip files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136231">136231</a>
+encoding of CharOperation.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=136016">136016</a>
+[refactoring] CCE during Use Supertype refactoring
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135296">135296</a>
+opening a special java file results in an &quot;out of memory&quot; message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135838">135838</a>
+[search] Improve search progress monitor label
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108180">108180</a>
+[compiler] Sanity check error with try/finally block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130390">130390</a>
+CamelCase algorithm cleanup and improvement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133351">133351</a>
+[compiler] No effect assignment diagnosis range isn't correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121734">121734</a>
+Cycle in class hierarchy causes infinite loop in Decoration Calculation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115918">115918</a>
+[1.5][compiler] Internal compiler error : NPE in Scope.minimalErasedCandidates
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129330">129330</a>
+strange statement recovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135602">135602</a>
+[compiler] Codegen bug for continue statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86293">86293</a>
+[search] Search for method declaration with pattern "run()" reports match in binary field instead of anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135292">135292</a>
+[compiler] NPE in ProblemReporter.invalidField plus .log swamping
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135217">135217</a>
+Compiler class constructor change in 3.2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135083">135083</a>
+RangeUtil#isInInterval(...) takes significant amount of time while editing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134976">134976</a>
+[completion] relevance of some types aren't correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125823">125823</a>
+Buildpath marker not of marker type 'buildpath_problem'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89686">89686</a>
+[1.5][search][enum] Reference to constructors does not include parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109691">109691</a>
+Importing preferences does not update classpath variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128562">128562</a>
+Javadoc of ITypeBinding#isAssignmentCompatible() is unclear
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132191">132191</a>
+IMethodBinding.overrides(IMethodBinding) returns true even if the given argument is private.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135110">135110</a>
+Duplicate Assert class in org.eclipse.core.internal.expressions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133562">133562</a>
+Extract to local variable generates variable called 'enum'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108087">108087</a>
+Java conventions default formatter settings confused
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110811">110811</a>
+[1.5] Raw type binding for reference to non-generic type
+
+<a name="v_655a"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC1 - 5th April 2006
+<br>Project org.eclipse.jdt.core v_655a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_655a">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=131707">131707</a>
+Cannot add classpath variables when starting with -pluginCustomization option
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134839">134839</a>
+[compiler] Incorrect compile errors reported in 1.3 compliance level
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128423">128423</a>
+[1.5][compiler] ClassCastException on illegal code fragment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107901">107901</a>
+Clarify Javadoc for ASTParser#setUnitName
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132841">132841</a>
+[1.5][compiler] Incorrectly compared method parameters when member types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132831">132831</a>
+[1.5][compiler] Compiler generate brige when not needed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119844">119844</a>
+javadoc extraction: type comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131519">131519</a>
+JDK with attached source unnavigable.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92357">92357</a>
+ITypeHierarchy#getType() should return an unresolved handle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97494">97494</a>
+[1.5][compiler] Inappropriate error level and message for generic type mismatch
+
+<a name="v_654"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2RC1 - 4th April 2006
+<br>Project org.eclipse.jdt.core v_654
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_654">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=134172">134172</a>
+Crap Perfomance opening Java file with lots of imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134255">134255</a>
+Unoptimal JavaElementInfo construction
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134645">134645</a>
+[1.5][compiler] Java Compiler throws internal exception..
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134118">134118</a>
+[1.5][compiler] 'ambiguous' error on legal static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96648">96648</a>
+Batch compiler - error messages for duplicate output, bootclasspath, sourcepath and extdirs entries could be more explicit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86813">86813</a>
+[compiler] step into switch statement locate wrong line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83318">83318</a>
+[1.5] 'Open declaration' fails for type variables in class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134345">134345</a>
+Problems from CompilationParticipants do not get cleaned up unless there are Java errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133918">133918</a>
+[1.5][compiler] Duplicate return; in CastExpression line 258
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89347">89347</a>
+[compiler] public constructor of protected inner class invisible in subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134064">134064</a>
+[1.5][compiler] Duplicate error messages when an annotation value expects a boolean but gets an array
+
+<a name="v_653"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 30th March 2006 - 3.2 MILESTONE 6
+<br>Project org.eclipse.jdt.core v_653
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_653">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=134064">134064</a>
+recreateModifiedClassFileInOutputFolder only works in default package
+
+<a name="v_652"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 29th March 2006
+<br>Project org.eclipse.jdt.core v_652
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_652">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=133738">133738</a>
+[compiler] Eclipse compiler compiles program but javac does not (2 of 2)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133748">133748</a>
+Javac task includes all files from the extDirs list
+
+<a name="v_651"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 29th March 2006
+<br>Project org.eclipse.jdt.core v_651
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_651">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new option to JavaCore
+<pre>
+* BUILDER / Recreate Modified class files in Output Folder
+*    Indicate whether the JavaBuilder should check for any changes to .class files
+*    in the output folders while performing incremental build operations. If changes
+*    are detected to managed .class files, then a full build is performed, otherwise
+*    the changes are left as is. Tools further altering generated .class files, like optimizers,
+*    should ensure this option remains set in its default state of ignore.
+*     - option id:         "org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder"
+*     - possible values:   { "enabled", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131935">131935</a>
+[1.5][compiler] Illegal generic conversion allowed.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129082">129082</a>
+[regression] Refresh-&gt;Run action deletes all files in 'bin' directory and recompiles all classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132613">132613</a>
+NPE in java builder when trying to retrieve a file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106090">106090</a>
+[generics] Method invocation resolution depends on declaration order
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133440">133440</a>
+[1.5][compiler] JDT allows annotation to have a null default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130982">130982</a>
+META-INF directories shown as empty META-INF.* packages in J2EE Navigator
+
+<a name="v_650"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 27th March 2006
+<br>Project org.eclipse.jdt.core v_650
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_650">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Types, fields and methods annotated with the @Deprecated annotation are now rendered as deprecated in the Outline view.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133292">133292</a>
+[compiler] Compiler accepts spurious semicolon in array initialiser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89807">89807</a>
+Outliner should recognize @Deprecated annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123476">123476</a>
+[compiler] misleading error message (root cause not reported)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133334">133334</a>
+Indexing project 3 times during import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132494">132494</a>
+JavaModelException opening up class file in non java project
+
+
+<a name="v_649"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 26th March 2006
+<br>Project org.eclipse.jdt.core v_649
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_649">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=130359">130359</a>
+[compiler][null] wrong warning in try/catch with RuntimeException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128962">128962</a>
+[compiler][null] incorrect analysis within try finally with a constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132974">132974</a>
+[compiler] missing error on uninitialized final local
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120892">120892</a>
+[assist] inconsistent completions for constructors an methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129371">129371</a>
+[compiler][null] False positives from null reference analyzer with break
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132651">132651</a>
+Javadoc of CompletionContext#getTokenEnd() and CompletionProposal#getCompletionLocation are not correct.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94925">94925</a>
+[search] Bad performance on showing package selection dialog when creating new import group
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131720">131720</a>
+[compiler] optimization: the distribution of the number of elements into CharArrayCache instances suggest that smaller instances should be optimized/removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131921">131921</a>
+NPE caugth in DefaultBindingResolver.resolveName(Name)
+
+<a name="v_648"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 22nd March 2006
+<br>Project org.eclipse.jdt.core v_648
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_648">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=132813">132813</a>
+[compiler] NPE in Javadoc.resolve(Javadoc.java:196) + log swamped
+<a name="v_647"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 21st March 2006
+<br>Project org.eclipse.jdt.core v_647
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_647">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=123943">123943</a>
+[1.5][compiler] Invalid ambiguous method error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129056">129056</a>
+compiler fails to detect ambiguous method when autoboxing and implementing an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132575">132575</a>
+Incorrect classpath are not reported inside the log xml
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128276">128276</a>
+Breakpoint Propertie Error.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129991">129991</a>
+[refactoring] Rename sourcefolder fails with JME
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131459">131459</a>
+Java model returns stale resolved source type for binary type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131937">131937</a>
+JDT core adding problem markers to non-java projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132120">132120</a>
+[compiler][null] NPE batch compiling JDT/Core from HEAD
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132072">132072</a>
+[compiler][null] AIOOBE in null check compiling com.sun.org.apache.xalan.internal.res.XSLTErrorResources 
+from JDK 1.5 source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131681">131681</a>
+NullPointerException during javaCompletionProposalComputer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128547">128547</a>
+[compiler] null reference analysis: false positive in try/finally
+
+<a name="v_646"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 14th March 2006
+<br>Project org.eclipse.jdt.core v_646
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_646">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The ASTParser can now be used without initializing JDT/Core. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87852">87852</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87852">87852</a>
+ASTParser fails when called from another program
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99114">99114</a>
+[search] OOM Exception in Java search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121569">121569</a>
+[Import/Export] Importing projects in workspace, the default build order is alphabetical instead of by dependency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=131373">131373</a>
+Verbose mode of the ant adapter should be a real verbose mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122650">122650</a>
+ASTParser.createBindings(IJavaElement[]) returns wrong element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130140">130140</a>
+ASTParser should specify failure for IClassFile without source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130317">130317</a>
+ASTParser with IClassFile as source creates type bindings that are not isEqualTo(..) binary bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130683">130683</a>
+NPE in DeltaProcessingState.addElementChangedListener()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130980">130980</a>
+[compiler] When the contents of the unit cannot be retrieved, the compiler should report an error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130330">130330</a>
+bogus null check in BindingComparator#isEqual(MethodBinding, MethodBinding, HashSet)
+
+<a name="v_645"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 7th March 2006
+<br>Project org.eclipse.jdt.core v_645
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_645">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Compilation participant reporting problems using <code>BuildContext#recordNewProblems(...)</code> now need to declare the problems
+     marker type as being managed for this problems to be persisted as markers by the Java builder. Declaring a managed marker type is
+     done using the 'managedMarker' sequence in the 'compilationParticipant' extension point.</li>
+<li>Compiler now supports <code>@SuppressWarnings("cast")</code> for silencing unnecessary cast diagnostics.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130543">130543</a>
+[1.5][compiler] Error creating array of generics of inner class.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130528">130528</a>
+NPE in FieldBinding.getAnnotations(..) for length field of array
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130516">130516</a>
+[1.5][compiler] Add support for "cast" warning token
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105801">105801</a>
+[1.5][compiler] Too many warnings for non-matching types of arguments of varargs call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128418">128418</a>
+[1.5][compiler] eclipse doesn't emit unchecked warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129957">129957</a>
+Binary class file editor shows &quot;implements&quot; instead of &quot;extends&quot; for an interface's super-interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104536">104536</a>
+[compiler] Ant adapter doesn't use the right source and target values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130117">130117</a>
+[compiler] Wrong error generated "The method Inner in type Inner can only set one of public / protected / private"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129190">129190</a>
+[1.5][compiler] Contrary behaviour to Sun's compiler concerning typed classes, non-static inner classes and inheritence
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129909">129909</a>
+Recovered AST - VariableDeclaratorId isn't recovered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130017">130017</a>
+[1.5][compiler] @Override cannot be used for static methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100919">100919</a>
+Closing or deleting projects leads to Java model error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129624">129624</a>
+AccessRuleSet#messageTemplates takes a lot of memory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117758">117758</a>
+[compiler] private dropped from inner class constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128219">128219</a>
+Builder participants should create their own marker types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61189">61189</a>
+Error messages with "AssignmentOperator ArrayInitializer" could be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128063">128063</a>
+[1.5][compiler] Compiler reports errors against compilabale code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116072">116072</a>
+cached classpath containers not removed when project deleted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119238">119238</a>
+[1.5][compiler] Unchecked generic type operation warning if access to static field of parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122775">122775</a>
+[1.5][compiler] StackOverflow in compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114140">114140</a>
+assertion failed when opening a class file not not the classpath
+
+<a name="v_644"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 28th February 2006
+<br>Project org.eclipse.jdt.core v_644
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_644">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>For 1.5 targets (or when toggling preference for Inlining Finally Blocks), the compiler is inlining finally blocks
+at every exit point inside a try statement. With fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128705">128705</a>,
+the inlining got smarter, and identical exit point are now sharing the same inlined finally block (to be truly identical,
+exit points must denote the same break/continue label, or be return from void method, or return the same constant or null value.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127628">bug 127628</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128814">128814</a>
+[prefs] NPEs in log during tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127628">127628</a>
+[index] CodeAssist doesn't filter deprecated types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128848">128848</a>
+closing bracket added into comment upon format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128258">128258</a>
+Project name of java elements from external file is _E_X_T_E_R_N_A_L_P_R_O_J_E_C_T_
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127241">127241</a>
+SIOOBE in StubUtility.hasConstantName during quick fix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127395">127395</a>
+AST: SimpleName must not be empty
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128014">128014</a>
+[compiler][null] invalid analysis when redundant check is done
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129555">129555</a>
+[dom] The length of a recovered fake SimpleName should be 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129241">129241</a>
+[Javadoc] deprecation warning wrongly reported when ignoring Malformed Javadoc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128877">128877</a>
+[search] reports inexistent IMethod for binary constructor of inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127919">127919</a>
+[compiler][null] non String objects references involved into string concatenation should not raise null ref. warnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113371">113371</a>
+Performance: discardWorkingPerCopyInfo emptys Cache before building Delta
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128705">128705</a>
+[Compiler][1.5] Jsr inlining limitation in the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129305">129305</a>
+[compiler] Could optimize "return null" in presence of subroutine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129306">129306</a>
+[compiler] inlineJSR may cause entering twice finally block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129096">129096</a>
+Wrong positions for array of parameterized type as a parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128961">128961</a>
+AST: errors with parentheses expressions in for-init initialisers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128960">128960</a>
+AST: errors with parameter array and full qualified types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129361">129361</a>
+Uninitialized fields in jdt/core code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102160">102160</a>
+[compiler][1.5] Only first error is reported on circularity references between annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127275">127275</a>
+[compiler] Generalize ProblemReporter#localSourceEnd
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128840">128840</a>
+[compiler] Wrong warning for unnecessary semicolon as else statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129316">129316</a>
+[compiler] Incremental compile confuses unsound type hierarchy and deprecation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125956">125956</a>
+[1.5][compiler] Failed to compile Jaxb 2.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129142">129142</a>
+VariableDeclarator isn't recovered by statments recovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128594">128594</a>
+Javadoc problems with category CAT_INTERNAL
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128169">128169</a>
+[codeassist] Type parameter name of method declaration proposal must not create conflit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128823">128823</a>
+ArrayIndexOutOfBoundsException in log
+
+
+
+<a name="v_643"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M6 - 21st February 2006
+<br>Project org.eclipse.jdt.core v_643
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_643">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In problem view, all optional errors treated as fatal are now grouped into the "Fatal errors" category.
+Note that there is an option to control whether optional errors are intended to be fatal or not, by default
+they are considered fatal (see <code>Preferences&gt;Java&gt;Compiler&gt;Building&gt;Treat configurable errors like fatal errors...</code></li>
+<li>Build states for very large projects should now save in a fraction of the time.</li>
+<li>Diagnosis for assignment with no effect can now recognize following patterns:
+  <ul>
+  <li><code>int i = i = 0;</code></li>
+  <li><code>i = i = 0;</code></li>
+  <li><code>i = ++i;</code></li>
+  </ul></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106446">106446</a>
+[compiler] "Cannot be resolved to a type" errors for some default top-level class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128045">128045</a>
+[assist] Autocomplete on variable names fails if name starts with a part of an existing prefix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100369">100369</a>
+[compiler] No effect assignment diagnosis could be made smarter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127323">127323</a>
+context assist exception when trying to autocomplete inside a malformed enum switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127244">127244</a>
+[compiler] Null reference analysis doesn't understand assertions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128560">128560</a>
+[compiler] Java 1.4 compiler (UI?) incorrectly reports incompatible return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128077">128077</a>
+AST - instanceof - getLength returns wrong length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127996">127996</a>
+Performance: long time spent in State.write(..) looping over ArrayList&lt;char[][]&gt;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128389">128389</a>
+[compiler][1.5] generic inner type cannot extend Throwable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127583">127583</a>
+[1.5][compiler] Call to constructor with mismatched type parameter and arguement not detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128217">128217</a>
+Grouping all fatal problems together
+
+
+<a name="v_642"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 16th February 2006 - 3.2 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_642
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_642">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>CategorizedProblem#getExtraMarkerAttributeNames()</code> and <code>getExtraMarkerAttributeValues()</code> to allow to 
+	specify extra attributes in problem markers.</li>
+<li>Added 'managedMarker' sequence on 'compilationParticipant' extension point to declare marker types that are persisted by the Java builder.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+
+<a name="v_641"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 15th February 2006
+<br>Project org.eclipse.jdt.core v_641
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_641">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128033">bug 128033</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128033">128033</a>
+[1.5][search] Not all references are found in standard annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128008">128008</a>
+type parameter with final bound is categorized as non-optional
+
+
+<a name="v_640"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 15th February 2006
+<br>Project org.eclipse.jdt.core v_640
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_640">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The Java model now better accommodates very big JAR files (i.e. containing lots of packages). Before 3.2 M5, such JAR files would 
+cause the Java model cache to overflow frequently, which induced poor performance, since the same JAR file kept being read over 
+and over again. A workaround was to start Eclipse with more memory to enjoy good performance again (as the cache size is a function 
+of the memory size).
+<p>JAR files are now read more selectively, and thus interesting portions remain in the cache longer without consuming lots of memory.
+User editing experience is thus significantly improved on large workspaces containing big JARs. 
+As a consequence, our experiments show that the memory requirement for developing Eclipse in Eclipse can be lowered 
+to 128MB only (i.e. passing -Xmx128m to the VM) as opposed to 256MB as currently specified in the eclipse.ini file. 
+</li>
+<li>Removed <code> IMethodBinding#isOverriding()</code> API introduced during 3.2 in DOM AST, as it doesn't meet
+client expectation, who isn't even using it (also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90660">90660</a>).
+<li>
+Added optional compiler diagnosis for signaling fall-through switch cases.
+<pre>
+* COMPILER / Reporting Switch Fall-Through Case
+*    When enabled, the compiler will issue an error or a warning if a case may be
+*    entered by falling through previous case. Empty cases are allowed.         *     
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.fallthroughCase"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+Fall-through warnings can be silenced using <code>@SuppressWarnings("fallthrough")</code>.<br>
+Also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67836">67836</a> for details.
+</li></ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67836">67836</a>
+[compiler] warning on fall through
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127393">127393</a>
+uncategorized problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127213">127213</a>
+Flags class missing methods
+
+<a name="v_639"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 13th February 2006
+<br>Project org.eclipse.jdt.core v_639
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_639">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Code Assist can filter deprecated types and members.<br>
+When filtering is enabled all deprecated types and members aren't proposed unless
+they are in the same compilation unit as the completion location.<br>
+Added new options to control this new behavior.
+<pre>
+ *  CODEASSIST / Activate Deprecation Sensitive Completion
+ *    When active, completion doesn't show deprecated members and types.
+ *     - option id:         "org.eclipse.jdt.core.codeComplete.deprecationCheck"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "disable"
+ * 
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126564">126564</a>
+[1.5][compiler]Inconsistent error reporting between static import and direct field access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127239">127239</a>
+BuildContext needs to be spec'ed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127296">127296</a>
+[codeasist]Add the ability to hide deprecated methods from Code Assist
+
+<a name="v_638"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 13th February 2006
+<br>Project org.eclipse.jdt.core v_638
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_638">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added optional null reference analysis for local variables. It can be activated using the following
+	preference:
+	<code>Window&gt;Preferences&gt;Java&gt;Compiler&gt;Errors/Warnings&gt;Potential programming problems&gt;Null reference</code>.
+	Also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110030">110030</a> for details.
+	<br>Note that the analysis is fairly conservative, aligned on definite assignment rules.  It is intentionally not complaining on all
+	possible cases, but only considering these for which a suspicion gets introduced (e.g. if later on a null check is performed).
+	The analysis could be further improved by introducing annotations (@CanBeNull, @CannotBeNull) but these would need to
+	get standardized first. 
+	<br>	Null reference warnings can be silenced using <code>@SuppressWarnings("null")</code>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126803">126803</a>
+Compile error in LocationElementTokenizer.java in source build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127255">127255</a>
+[compiler] Compiler incorrectly reports &quot;variable may not have been initialized&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125731">125731</a>
+[api] Separate category id for 'type restriction' problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116647">116647</a>
+[compiler] Incorrect warning about unnecessary cast
+
+
+<a name="v_637"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 10th February 2006
+<br>Project org.eclipse.jdt.core v_637
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_637">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added constants in the code formatter.<br>
+<code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INDENT_BODY_DECLARATIONS_COMPARE_TO_ANNOTATION_DECLARATION_HEADER</code>
+<code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION</code>
+<br>See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126625">126625</a> for details.</li>
+<li>Code Assist: Improve variable name completion<br>
+Variable name completion try to keep typed characters even if they don't match to a part of the type name.<br>
+e.g: Element rootE| is completed to Element rootElement.
+</li>
+<li>Added API <code>org.eclipse.jdt.core.CorrectionEngine#getAllWarningTokens()</code> to 
+    get all the valid warning tokens, which can be used into <code>@SuppressWarnings</code>
+    annotations. See bug 
+    <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126326">126326</a> for details.</li>
+<li>Changed the way to flag DOM AST nodes as RECOVERED.<br>
+Now only nodes which really contains added/removed/replaced tokens are flagged. A parent of these kind of node isn't flagged.
+Sometimes our heuristic can't recognize the really recovered node, so in this case all potentially recovered nodes are flagged.</li>
+<li>Fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119203">119203</a>
+has been removed due to bad side effects (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127048">127048</a>)</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127048">127048</a>
+[search] References to Java element 'CorrectionEngine' not found
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98684">98684</a>
+[search] Code assist shown inner types of unreleated project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127078">127078</a>
+[compiler] inappropriate error location for QualifiedNameReferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127181">127181</a>
+New API elements missing @since
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127144">127144</a>
+beginTask/done not called on progress monitor to ASTParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123470">123470</a>
+AST: new type IResolvedAnnotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108539">108539</a>
+Error popup at breakpoint in tomcat project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99006">99006</a>
+Incorrect warning when a non-varargs method overrides a varargs method.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120563">120563</a>
+Javadoc has many references to .java where all java source files are meant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=42253">42253</a>
+[plan][dom/ast] Make AST more robust against syntax errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125006">125006</a>
+ClassFile wastes memory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126156">126156</a>
+IBinding#getJavaElement() should spec 'null' for anonymous constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126326">126326</a>
+[api] all supported SuppressWarning tokens
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121652">121652</a>
+100% CPU usage when changing application focus or saving
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120838">120838</a>
+typos in spec of ICodeAssist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126227">126227</a>
+default constructor not resolving for method-level classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124525">124525</a>
+[assist] Smarter Autocompletion for variable names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126625">126625</a>
+Added missing options for formatting annotation types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126673">126673</a>
+NPE in Buffer.addBufferChangedListener
+
+<a name="v_636"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 7th February 2006
+<br>Project org.eclipse.jdt.core v_636
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_636">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API to ASTRewrite to get actual value of a property as managed by the rewriter. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96663">96663</a> for details.</li>
+<li>Added an application to format code in a headless environment. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75333">75333</a> for details.</li>
+<li>Java projects can now depend on other Java projects that have replaced the default builder with their own builder, such as an Ant builder.
+We will now trust that the Ant build was successful and propagate any changes to the affected class files.
+<br>Note: When projects are associated with the Java builder, it is able to track structural changes to classfiles (signatures etc...) and only recompile
+dependents of structurally changed classfiles. In the absence of a Java builder on a prereq project, all modified classfiles will be considered as
+(potentially) structurally changed; and thus recompilation will be less optimal.</li>
+<li>Access restriction warnings (discouraged &amp; non-accessible) can now be silenced using <code>@SuppressWarnings("restriction")</code>.
+     Note: if certain restrictions are configured as errors, the annotation has no effect. </li>
+<li>Added API <code>org.eclipse.jdt.core.formatter.CodeFormatter#createIndentationString(int)</code> to return the indentation string corresponding to the given indentation level.<br>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111446">111446</a> for details.</li>
+<li>Added new class <code>org.eclipse.jdt.core.formatter.IndentManipulation</code> to deal with indentations.<br>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111446">111446</a> for details.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124469">bug 124469</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99497">99497</a>
+In some cases Java project refresh should kick clean build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126598">126598</a>
+[DOM][AST] String[] s =  {&quot;&quot;,,,} leads to wrong positions after conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126347">126347</a>
+AIOOBE in CompilerUnitScope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126148">126148</a>
+IAE when typing String[] s =  {"",,,};
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126330">126330</a>
+Type reference not found in jar file if sources was not already opened
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126321">126321</a>
+[options] Add constant in JavaCore for nullReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126160">126160</a>
+method from outer scope not resolved with erroneous arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97693">97693</a>
+[1.5][compiler] Unchecked generic cast gives false compiler error.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125965">125965</a>
+[prefs] &quot;Export/Import preferences&quot; should let user to choose wich preference to export/import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124469">124469</a>
+[1.5][search] does not find references to enum type in binary annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75333">75333</a>
+[format] standalone code reformatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122987">122987</a>
+[1.5][compiler] Boxing conversion should be performed in conditional expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125807">125807</a>
+NPE in ResolvedMemberValuePair#init()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79359">79359</a>
+Project cannot depend on a project built by ant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126091">126091</a>
+[1.5][compiler] Java compiler generates extra field for enums with abstract methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126191">126191</a>
+Code formatter doesn't format properly empty enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126177">126177</a>
+[1.5][compiler] Visibility issue with intersection type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126180">126180</a>
+[1.5][compiler] NPE reporting invalid enclosing type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114456">114456</a>
+@SuppressWarnings for access restriction
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126087">126087</a>
+[1.5][compiler] Java compiler generates incorrect byte code for empty enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124611">124611</a>
+IAE in Signature.createCharArrayTypeSignature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90660">90660</a>
+[plan] Consider surfacing override information available in compiler AST in DOM AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111446">111446</a>
+API to work with tabWidth/indentWidth and indents
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=126015">126015</a>
+reconcile does not provide AST if there's no problem requestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125903">125903</a>
+[javadoc] Treat whitespace in javadoc tags as invalid tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125301">125301</a>
+Handling of classes with $ in class name.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125961">125961</a>
+Add &quot;emacs style&quot; output to batch compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125953">125953</a>
+UnconditionalFlowInfo.java has non-UTF-8 character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124853">124853</a>
+[compiler] Compiler generates wrong code (try-catch-finally)
+
+
+<a name="v_635"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 31st January 2006
+<br>Project org.eclipse.jdt.core v_635
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_635">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>org.eclipse.jdt.core.dom.IVariableBinding#isParameter()</code> in order to fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106545">106545</a>.</li>
+<li>Added API <code>BindingKey#toSignature()</code> to transform a binding key into a resolved signature.</li>
+<li>Added marker attribute "categoryId" onto Java problem markers.
+<li>Added API <code>WorkingCopyOwner#newWorkingCopy(String,IClasspathEntry[],IProblemRequestor,IProgressMonitor)</code>
+     for editing compilation units outside the workspace.</li>
+<li>The temporary option JavaCore.COMPILER_STATEMENTS_RECOVERY is removed</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119452">119452</a>
+CategorizedProblem's category should be available from markers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125676">125676</a>
+@category should not read beyond end of line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125360">125360</a>
+IJavaProject#setOption() doesn't work if same option as default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106545">106545</a>
+API: IVariableBinding.isMethodParameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125641">125641</a>
+Problems enabling AST with recovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125675">125675</a>
+@category not reflected in outliner in live fashion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125570">125570</a>
+[1.5][compiler] Named inner inner classes have illegal names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124943">124943</a>
+[1.4][compiler] 1.4 Compiler Compliance not working for compareTo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124810">124810</a>
+Strange field binding has inconsistent hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125291">125291</a>
+Enable conditional loading of APT
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125178">125178</a>
+[search] AIOOBE in PatternLocator when searching for dependency extent from manifest
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124388">124388</a>
+[DOM AST] Method defaults not resolved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125270">125270</a>
+ASTParser fails to parse text to ArrayInitializer expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100869">100869</a>
+[1.5][compiler] The eclipse compiler thinks my method is ambiguous but javac does not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65637">65637</a>
+[model] Excluded package still in Java model
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125217">125217</a>
+Two failures in the BatchCompilerTests on MacOS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124290">124290</a>
+AbstractImageBuilder writeClassFileBytes creates resources before calling setDerived
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124145">124145</a>
+Questions on IAccessRule.ignoreIfBetter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125047">125047</a>
+IMethodBinding#getJavaElement() should spec 'null' for default constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120079">120079</a>
+[api] need solution for BindingKey#internalToSignature()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125036">125036</a>
+ResolvedMemberValuePair#buildDOMValue(..) uses &quot;new Boolean(..)&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121715">121715</a>
+Util#getJavaLikeExtensions doesn't consider Java-like content types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125067">125067</a>
+Should not resolved binary fields/methods when computing hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61013">61013</a>
+[plan][model] Minimal support for editing units outside workspace
+
+<a name="v_634"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 24th January 2006
+<br>Project org.eclipse.jdt.core v_634
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_634">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added EFS support for zip and jar files. JDT/Core now fully supports EFS.</li>
+<li>Added support for optional classpath entries. When optional, a missing entry is not complained
+     against, and simply ignored.
+     In order to be optional, an entry must carry an <code>IClasspathAttribute#OPTIONAL</code> 
+     extra attribute. The possible values for this attribute are <code>"true"</code> or <code>"false"</code>. 
+	 When not present, <code>"false"</code> is assumed. If the value of this attribute is <code>"true"</code>, 
+	 the classpath entry is optional. </li>
+<li>Added support for statement recovery in Parser<br>
+	 Currently this new behavior is incomplete (mapping non-terminals -&gt; terminals) and disabled. The option JavaCore.COMPILER_STATEMENTS_RECOVERY must be set to ENABLED to use it (It's a temporary option).</li>
+<li>Added API for DOM ASTNode flag: <code>ASTNode.RECOVERED</code><br>
+	 It is a flag constant indicating that this node or a part of this node is recovered
+	 from source that contains a syntax error detected in the vicinity.</li>
+<li>Added API: <code>ASTParser#setStatementsRecovery(boolean enabled)</code><br>
+	 This method allow to enable statements recovery for ASTParser.
+	 Statements recovery is disabled by default.</li>
+<li>Added API: <code>ICompilationUnit#reconcile(int astLevel, boolean forceProblemDetection, boolean enableStatementsRecovery, WorkingCopyOwner owner, IProgressMonitor monitor)</code><br>
+	 This method allow to enable statements recovery for reconcile operation.</li>
+<li>Added two warning tokens to the batch compiler options: <code>discouraged</code> and 
+    <code>forbidden</code>, so as to suppress warnings about access rules restrictions.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110030">110030</a>
+[compiler] Provide support for null reference analysis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99620">99620</a>
+[compiler] The batch compiler should not print to the console when taking another output stream in input
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124212">124212</a>
+Eclipse compiler produces incomplete debug info for variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124533">124533</a>
+[batch] Ability to turn off discouraged references warnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124471">124471</a>
+ResolvedAnnotations are not completely resolved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124346">124346</a>
+[1.5][compiler] Unexpected deprecation warning when @deprecated tag and @Deprecated annotation are mixed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123522">123522</a>
+@SuppressWarnings("unused") does not suppress "unused import" warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122442">122442</a>
+[search] API inconsistency with IJavaSearchConstants.IMPLEMENTORS and SearchPattern
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123437">123437</a>
+Support EFS for zip/jar files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124296">124296</a>
+Recovered ast nodes don't nest properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124101">124101</a>
+[compiler] NPE when resolving array initializer in fault tolerant mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95056">95056</a>
+[1.5][compiler] @Deprecated not recognized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123514">123514</a>
+[1.5] [assist]ArrayStoreException in content assist for malformed field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122615">122615</a>
+validate classpath propose to exlude a source folder even though exlusion patterns are disabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124117">124117</a>
+Optional classpath entry
+
+<a name="v_633"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 17th January 2006
+<br>Project org.eclipse.jdt.core v_633
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_633">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>IAccessRule#IGNORE_IF_BETTER</code> that indicates that the rule should be ignored if a better rule is found.
+     E.g. if a rule <code>K_NON_ACCESSIBLE | IGNORE_IF_BETTER</code> matches type p.X and a rule <code>K_DISCOURAGED</code> 
+     that also matches p.X is found after the first one, then p.X will be reported as discouraged.</li>
+<li>Added the support to compute the stack map frames (requires a 6.0 VM to run). See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109980">109980</a> for details.
+<br>This is still experimental.</li>
+<li>Added API for the configuration of the Import Rewrite: <code>ImportRewrite#setImportOrder()</code>, <code>ImportRewrite#setOnDemandImportThreshold()</code> and
+<code>ImportRewrite#setStaticOnDemandImportThreshold()</code>. For compatibility reasons the actual configuration option values stay in
+JDT.UI</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98127">98127</a>
+Access restrictions started showing up after switching to bundle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122316">122316</a>
+Problems using new Compilation Participant extension point
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123893">123893</a>
+CCE in ResolvedAnnotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124003">124003</a>
+JavaCore should spec 1.6 compliance/source compatibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87718">87718</a>
+Listener on build process on a per file basis.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122881">122881</a>
+[1.5][compiler] Multiple interface inheritance is incompatible with Sun compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109980">109980</a>
+[plan] Add support for StackMapTable attribute as per jsr-202
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122995">122995</a>
+[1.5][compiler] Access rules don't apply to generic types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123721">123721</a>
+two types of 'remove' for TODO task tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123396">123396</a>
+Regression: NameLookup creation longs around 1mn on project with heavy hiearchy (200 src folders * 200 packages)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103615">103615</a>
+[organize import] Organize imports should have separate "limit" for static import *-ing
+
+<a name="v_632"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M5 - 10th January 2006
+<br>Project org.eclipse.jdt.core v_632
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_632">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added Import Rewrite as API (<code>org.eclipse.jdt.core.dom.ImportRewrite</code>). The import rewriter is used to add new imports according
+to a user specified import order. See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=73054">73054</a> for details.</li>
+<li>Added new APIs for checking modifiers (<code>org.eclipse.jdt.core.dom.Modifier#isPublic(), org.eclipse.jdt.core.dom.Modifier#isStatic(), ...</code>). See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=122460">122460</a> for details.</li>
+<li>Added new API <code>org.eclipse.jdt.core.IJavaElement#String getAttachedJavadoc(IProgressMonitor monitor)</code>. See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=122506">122506</a> for details.
+The former API <code>org.eclipse.jdt.core.IJavaElement#String getAttachedJavadoc(IProgressMonitor monitor, String defaultEncoding)</code> has been deprecated.</li>
+<li>Added new API <code>org.eclipse.jdt.core.dom.ITypeBinding#getComponentType()</code> in order to retrieve the binding 
+corresponding to the component type of the array binding. See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=120264">120264</a> for details.
+This API is still subject to change before 3.2 release.
+</li>
+<li>
+Added optional compiler diagnosis for signaling method parameter assignments.
+<pre>
+* COMPILER / Reporting Parameter Assignment
+*    When enabled, the compiler will issue an error or a warning if a parameter is
+*    assigned to.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.parameterAssignment"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123096">123096</a>
+[javadoc][assist] @linkplain no longer proposed when 1.4 compliance is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123078">123078</a>
+[1.5][compiler] Problem inferring from #getClass() invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103839">103839</a>
+Format of variablesAndContainers.dat doesn't scale well
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121026">121026</a>
+[javadoc][assist] @link method proposal has superfluous space
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120130">120130</a>
+IField.getConstant() fails for a certain constant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122755">122755</a>
+Exceptions thrown if you type a period immediately after final slash of Javadoc inside a method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117282">117282</a>
+Package declaration inserted on wrong CU while copying class if names collide and editor opened
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118507">118507</a>
+Autobuild churn during classpath init
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119249">119249</a>
+codeResolve, search, etc. don't work on constructor of binary inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118823">118823</a>
+[model] Secondary types cache not reset while removing _all_ secondary types from CU
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122763">122763</a>
+[builder] OutOfMemoryError while cleaning org.eclipse.jdt.core project - this fix triggers a
+full rebuild of the workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119161">119161</a>
+classes in &quot;deep&quot; packages not fully recognized when using tight inclusion filters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108830">108830</a>
+[compiler] Improve switch fault-tolerance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122610">122610</a>
+[1.5][compiler] Qualified this has generic type binding instead of parameterized one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121076">121076</a>
+Wrong field gets renamed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73054">73054</a>
+[import rewrite] Make Import Rewriter API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122618">122618</a>
+[assist][javadoc] Javadoc code assist should support @category tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122616">122616</a>
+[javadoc] IMember.getCategories() only returns first category
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53773">53773</a>
+[compiler] Warning on assignments to parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122460">122460</a>
+Why is checking a modifier so code intensive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120816">120816</a>
+[search] NullPointerException at ...jdt.internal.compiler.lookup.SourceTypeBinding.getMethods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76266">76266</a>
+[compiler] Access restriction should also apply to inherited members - this fix triggers a
+full rebuild of the workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122506">122506</a>
+[hovering] javadoc hover shows a broken string from DBCS javadoc html files.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116833">116833</a>
+IMethodBinding#isEqualTo(..) returns true for methods in anonymous classes with error in parent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120264">120264</a>
+[api] have array binding X[][][], want X[][] and X[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116615">116615</a>
+Use a publicID in the DOCTYPE of the compilation XML log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120263">120263</a>
+[compiler] missing binding on array initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120410">120410</a>
+Wasted space on problems due to large underlying char[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120875">120875</a>
+Javadoc extraction might includes optional annotation type member information for an annotation type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121187">121187</a>
+Javadoc contains undefined HTML entity &amp;ast;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119175">119175</a>
+[compiler] Wrong pc in the line number table attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118897">118897</a>
+ASTParser resolves bindings without request
+
+
+<a name="v_631"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 14th December 2005 - 3.2 MILESTONE 4
+<br>Project org.eclipse.jdt.core v_631
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_631">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=120902">120902</a>
+Member.getJavadocRange() causes AIOOBE
+
+
+<a name="v_630"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 14th December 2005
+<br>Project org.eclipse.jdt.core v_630
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_630">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=120847">120847</a>
+[javadoc] AIOOBE while getting attached javadoc in Javadoc view
+
+<a name="v_629"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 13th December 2005
+<br>Project org.eclipse.jdt.core v_629
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_629">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The constant <code>JavaCore.CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC</code> has been deprecated and it will be removed
+after M4. Use <code>JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC</code> instead.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120640">120640</a>
+[javadoc] Open External Javadoc fails for nested binary types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120597">120597</a>
+JME extracting Javadoc for public fields from 1.5 doc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120637">120637</a>
+javadoc extraction: includes field title for Java 5 classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120559">120559</a>
+Getting Javadoc from attached Javadoc gives JavaModelException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120545">120545</a>
+Misleading constant: CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120522">120522</a>
+[assist] No proposal in @Target annotation attributes
+
+<a name="v_628"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 12th December 2005
+<br>Project org.eclipse.jdt.core v_628
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_628">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=120350">120350</a>
+[model] Secondary type not found by code resolve
+
+<a name="v_627"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 9th December 2005
+<br>Project org.eclipse.jdt.core v_627
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_627">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Change the default value of JavaCore#CODEASSIST_CAMEL_CASE_MATCH to "enabled" as
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114098">bug 114098</a> is fixed.</li>
+<li>Added support for EFS on non zip file. Support for zip and jar files is blocked by 
+     <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=119244">bug 119244</a></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120092">120092</a>
+[search] Java like extensions functionality causes performance issue for search engine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117740">117740</a>
+Parameter names completion should be done asynchronoulsy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110422">110422</a>
+[search] BasicSearchEngine doesn't find all type declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110291">110291</a>
+[search] BasicSearchEngine return constructor declarations that doesn't exist in source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83064">83064</a>
+[plan][1.5] Unidentical bindings for declaration of and reference to Class.MethodArray
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119545">119545</a>
+[search] Binary java method model elements returned by SearchEngine have unresolved parameter types
+
+<a name="v_626"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 6th December 2005
+<br>Project org.eclipse.jdt.core v_626
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_626">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=119430">119430</a>
+Potential performance problem in getViolatedRestriction()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113944">113944</a>
+[plan] Support for refactoring of JAR files
+
+<a name="v_625"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 6th December 2005
+<br>Project org.eclipse.jdt.core v_625
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_625">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API methods on IJavaProject to find secondary types while searching for type
+on a project (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118789">118789</a>):
+<pre>
+	/**
+	 * Same functionality as {@link #findType(String)} but also look for secondary
+	 * types if given name does not match a compilation unit name.
+	 * 
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath 
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, WorkingCopyOwner)}
+	 * but also look for secondary types if given name does not match
+	 * a compilation unit name.
+	 * 
+	 * @param fullyQualifiedName the given fully qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath 
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String fullyQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, String)} but also look for
+	 * secondary types if given name does not match a compilation unit name.
+	 * 
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath 
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String packageName, String typeQualifiedName, IProgressMonitor progressMonitor) throws JavaModelException;
+	/**
+	 * Same functionality as {@link #findType(String, String, WorkingCopyOwner)}
+	 * but also look for secondary types if given name does not match a compilation unit name.
+	 * 
+	 * @param packageName the given package name
+	 * @param typeQualifiedName the given type qualified name
+	 * @param owner the owner of the returned type's compilation unit
+	 * @param progressMonitor the progress monitor to report progress to,
+	 * 	or <code>null</code> if no progress monitor is provided
+	 * @exception JavaModelException if this project does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @return the first type found following this project's classpath 
+	 * with the given fully qualified name or <code>null</code> if none is found
+	 * @see IType#getFullyQualifiedName(char)
+	 * @since 3.2
+	 */
+	IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner, IProgressMonitor progressMonitor) throws JavaModelException;
+</pre>
+Note that previously existing find type API methods:
+<ul>
+<li><code>IJavaproject#findType(String)</code></li>
+<li><code>IJavaproject#findType(String, WorkingCopyOwner)</code></li>
+<li><code>IJavaproject#findType(String, String)</code></li>
+<li><code>IJavaproject#findType(String, String, WorkingCopyOwner)</code></li>
+</ul>
+will <b>not</b> find secondary types (same behavior than for 3.1 version).<br>
+This means that fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36032">36032</a>
+was slightly modified as it introduced an non-deterministic behavior of these API methods
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118789">118789</a> for the whole story...).
+</li>
+<li>Added API <code>SearchParticipant#removeIndex(IPath)</code> to remove both index file
+    from a given location and its corresponding Index in IndexManager cache.
+</li>
+<li>Added API <code>IJavaProject#setRawClasspath(IClasspathEntry[], IPath, boolean, IProgressMonitor)</code>
+     to change the output location as well as the classpath without touching resources.</li>
+<li>Added constant constant JavaCore#JAVA_SOURCE_CONTENT_TYPE to retrieve the Java source content type from 
+     the content type manager (see org.eclipse.core.runtime.content.IContentTypeManager#getContentType(String))</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119108">119108</a>
+Access Rules and Path separators
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110593">110593</a>
+[1.5][compiler] NPE in ProblemReporter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115693">115693</a>
+[1.5][compiler] Unnecessary double checkcast instruction emmited
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118789">118789</a>
+IJavaProject#findType(String) returns null for secondary type quickly after creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118876">118876</a>
+[dom] TypeDeclaration nodes aren't flagged as MALFORMED
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105592">105592</a>
+Enum switch statement compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118888">118888</a>
+Need an entry point to create a org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader using a stream
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118092">118092</a>
+Eclipse hangs on code assist when writing ?&lt;c
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116650">116650</a>
+[search] SearchParticipant has no way to remove specific index file from IndexManager cache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118798">118798</a>
+Unexpected JME on IMethod.getParameterNames
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114571">114571</a>
+concurrent access to HashMap
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71460">71460</a>
+[model] Non *.java file association with Java contents.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118397">118397</a>
+[javadoc][assist] No completion available while completing inside a qualified reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118393">118393</a>
+ICompilationUnit.findPrimaryType: Should use JavaCore.removeJavaLikeExtension
+
+<a name="v_624"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 29th November 2005
+<br>Project org.eclipse.jdt.core v_624
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_624">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>IJavaProject#setRawClasspath(IClasspathEntry[], boolean, IProgressMonitor)</code> 
+     to set the classpath without touching the .classpath file.</li>
+<li>Added API <code>org.eclipse.jdt.core.compiler.CharOperation#equals(char[], char[], int, int, boolean)</code>.</li>
+<li>Added API <code>org.eclipse.jdt.core.compiler.CharOperation#replace(char[], char[], char, int, int)</code>.</li>
+<li>Plugin version now respects new versionning requirements. See <a href="http://eclipse.org/equinox/documents/plugin-versioning.html">plugin versioning</a> and bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99393">99393</a>.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36032">bug 36032</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added API <code>IMember#getOccurrenceCount()</code> to return the relative position of the member in the source.</li>
+<li>Added API <code>WorkingCopyOwner#newWorkingCopy(String,IProgressMonitor)</code> to create a new working copy 
+     without an underlying resource.</li>
+<li>Added API on TypeReferenceMatch to report local element and other elements while
+searching for type references (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110336">110336</a>):
+<pre>
+	/**
+	 * Returns the local element of this search match.
+	 * This may be a local variable which declaring type is the referenced one
+	 * or a type parameter which extends it.
+	 * 
+	 * @return the element of the search match, or <code>null</code> if none or there's
+	 * 	no more specific local element than the element itself ({@link SearchMatch#getElement()}).
+	 */
+	public final IJavaElement getLocalElement()
+	/**
+	 * Returns other enclosing elements of this search match.
+	 *
+	 * If {@link #getLocalElement()} is not <code>null</code>, these may be other
+	 * local elements such as additional local variables of a multiple local
+	 * variables declaration. Otherwise, these may be other elements such as
+	 * additional fields of a multiple fields declaration.
+	 * 
+	 * @return the other elements of the search match, or <code>null</code> if none
+	 */
+	public final IJavaElement[] getOtherElements()
+	/**
+	 * Sets the local element of this search match.
+	 * 
+	 * @param localElement A more specific local element that corresponds to the match,
+	 * 	or <code>null</code> if none
+	 */
+	public final void setLocalElement(IJavaElement localElement)
+	/**
+	 * Sets the other elements of this search match.
+	 * 
+	 * @param otherElements the other elements of the match,
+	 * 	or <code>null</code> if none
+	 */
+	public final void setOtherElements(IJavaElement[] otherElements)
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118246">118246</a>
+Definition of getJavaLikeExtensions() leads to programming errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118311">118311</a>
+type \@ in javadoc comment and code assist == hang
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117020">117020</a>
+[search] Search for '*' does not report empty packages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111416">111416</a>
+[search] wrong potential matches on a static method open
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118214">118214</a>
+[completion] "has inconsistent hierarchy" field should not be proposed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118105">118105</a>
+[javadoc][assist] Hang with 100% CPU during code assist on comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=118064">118064</a>
+Access rules are not flushed between classpaths in batch mode.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117451">117451</a>
+[compiler] Codegen could better optimize field access when value not required
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117120">117120</a>
+[compiler] VerifyError: Expecting to find integer on stack
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36032">36032</a>
+[plan] JavaProject.findType() fails to find second type in source file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117183">117183</a>
+[javadoc][assist] No completion in text when cursor location is followed by a '.'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116573">116573</a>
+wrong guess of binding with overloaded methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117861">117861</a>
+[1.5][compiler] invalid handling of static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110336">110336</a>
+[plan][search] Should optionaly return the local variable for type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117890">117890</a>
+JavaElement.getURLContents(...) leaves file open
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117589">117589</a>
+Completion dialog shows html file name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115040">115040</a>
+Provide API for getting occurrence count from initializers and types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117121">117121</a>
+Can't create class called A$B in eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116858">116858</a>
+java code formatter problem with switch statements and comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117495">117495</a>
+Compiler: ternary ops return wrong type when condition is boolean literal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61013">61013</a>
+[plan][model] Minimal support for editing units outside workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117487">117487</a>
+Classpaths in the build scripts need to be updated
+
+<a name="v_623"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 22nd November 2005
+<br>Project org.eclipse.jdt.core v_623
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_623">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li><code>JavaCore#initializeAfterLoad(IProgressMonitor)</code> used to schedule a job to do its work. 
+      It now does it in the same thread. Note this is not an API change as the spec allows both scenarii.
+</li>
+<li> DOM type bindings for generics got adjusted. There were situations where a reference to a generic type from within itself would expose the declared 
+generic type binding, instead of a parameterized type binding (using its own type parameters as type arguments). This is now corrected, clients should 
+ensure they did not rely on the previous inconsistency (note: no change was required from direct JDT dependents).
+</li>
+<li>Added APIs <code>JavaCore#getJavaLikeExtensions(), isJavaLikeFileName(String), and removeJavaLikeExtension(String)</code>
+     to get the available Java-like extensions (from the Java source content-type), checking if a file is a Java-like file, and removing
+     the Java-like extension from a file name.
+</li>
+<li>Added new API for org.eclipse.jdt.core.dom.CompilationUnit:
+<pre>
+	/**
+	 * Returns the column number corresponding to the given source character
+	 * position in the original source string. Column number are zero-based. 
+	 * Return <code>-1</code> if it is beyond the valid range or <code>-2</code>
+	 * if the column number information is unknown.
+	 * 
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 0-based column number, or <code>-1</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or <code>-2</code> if column number information is unknown for this
+	 *    compilation unit
+	 * @see ASTParser
+	 * @since 3.2
+	 */
+	public int getColumnNumber(final int position)
+	/**
+	 * Given a line number and column number, returns the corresponding 
+	 * position in the original source string.
+	 * Returns -2 if no line number information is available for this
+	 * compilation unit. 
+	 * Returns the total size of the source string if <code>line</code>
+	 * is greater than the actual number lines in the unit.
+	 * Returns -1 if <code>column</code> is less than 0,  
+	 * or the position of the last character of the line if <code>column</code>
+	 * is beyond the legal range, or the given line number is less than one. 
+	 * 
+	 * @param line the one-based line number
+	 * @param column the zero-based column number
+	 * @return the 0-based character position in the source string; 
+	 * <code>-2</code> if line/column number information is not known 
+	 * for this compilation unit or <code>-1</code> the inputs are not valid
+	 * @since 3.2
+	 */
+	 public int getPosition(int line, int column)
+	/**
+	 * Returns the line number corresponding to the given source character
+	 * position in the original source string. The initial line of the 
+	 * compilation unit is numbered 1, and each line extends through the
+	 * last character of the end-of-line delimiter. The very last line extends
+	 * through the end of the source string and has no line delimiter.
+	 * For example, the source string <code>class A\n{\n}</code> has 3 lines
+	 * corresponding to inclusive character ranges [0,7], [8,9], and [10,10].
+	 * Returns -1 for a character position that does not correspond to any
+	 * source line, or -2 if no line number information is available for this
+	 * compilation unit.
+	 * 
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 1-based line number, or <code>-1</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or <code>-2</code> if line number information is not known for this
+	 *    compilation unit
+	 * @see ASTParser
+	 * @since 3.2
+	 */
+	public int getLineNumber(int position) 	
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117382">117382</a>
+synthetic class$N fields generated unnecessarily
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115658">115658</a>
+ReconcileContext/CompilationParticipant clarifications
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=61946">61946</a>
+AST: NPE in IVariableBinding.getConstantValue
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116472">116472</a>
+Ambigous API definition on CompilationUnit.getPosition()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117032">117032</a>
+AST line numbers: Problems with single line source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116745">116745</a>
+[compiler] VerifyError: Incompatible type for getting or setting field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98154">98154</a>
+Code assist from Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116464">116464</a>
+[javadoc] Unicode tag name are not correctly parsed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114941">114941</a>
+Remove init job
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114935">114935</a>
+ASTParser.createASTs parses more CUs then required
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116311">116311</a>
+[search] NPE searching for reference to our Assert class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115067">115067</a>
+Util#getJavaLikeExtensions should become API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80472">80472</a>
+Binding of parameterized return type List&lt;E&gt; subList(...) should not be generic binding
+
+
+<a name="v_622"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 16th November 2005
+<br>Project org.eclipse.jdt.core v_622
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_622">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>IMethod#getRawParameterNames()</code> that returns the invented names arg0...argn for a binary method.</li>
+<li>Added API <code>IOpenable#findRecommendedLineSeparator()</code> that finds the line separator for the given Java element.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116419">116419</a>
+code assist regression: POTENTIAL_METHOD_DECLARATION not offered anymore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84750">84750</a>
+[perf] BinaryMethod.getParameterNames does not follow IMethod API contract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110650">110650</a>
+Need API for determining Java line delimiter
+
+<a name="v_621"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 15th November 2005
+<br>Project org.eclipse.jdt.core v_621
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_621">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Due to bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110964">110964</a> fix,
+some javadoc compiler options default value have been changed.
+<pre>
+JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS:
+	- old default value = "enabled"
+	- new default value = "disabled"
+JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS__DEPRECATED_REF
+	- old default value = "enabled"
+	- new default value = "disabled"
+JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS__NOT_VISIBLE_REF
+	- old default value = "enabled"
+	- new default value = "disabled"
+JavaCore.COMPILER_PB_INVALID_JAVADOC_TAGS_VISIBILITY
+	- old default value = "private"
+	- new default value = "public"
+JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_VISIBILITY
+	- old default value = "private"
+	- new default value = "public"
+</pre>
+</li>
+<li>Added new API for org.eclipse.jdt.core.dom.CompilationUnit:
+<pre>
+	/**
+	 * Return the index in the whole comments list {@link #getCommentList() }
+	 * of the first leading comments associated with the given node. 
+	 * 
+	 * @param node the node
+	 * @return 0-based index of first leading comment or -1 if node has
+	 *	no associated comment before its start position.
+	 * @since 3.2
+	 */
+	public int firstLeadingCommentIndex(ASTNode node)
+	/**
+	 * Return the index in the whole comments list {@link #getCommentList() }
+	 * of the last trailing comments associated with the given node. 
+	 * 
+	 * @param node the node
+	 * @return 0-based index of last trailing comment or -1 if node has
+	 * 	no associated comment after its end position.
+	 * @since 3.2
+	 */
+	public int lastTrailingCommentIndex(ASTNode node)
+	/**
+	 * Returns the column number corresponding to the given source character
+	 * position in the original source string. Column number are zero-based. 
+	 * Return zero if it is beyond the valid range.
+	 * 
+	 * @param position a 0-based character position, possibly
+	 *   negative or out of range
+	 * @return the 0-based coloumn number, or <code>0</code> if the character
+	 *    position does not correspond to a source line in the original
+	 *    source file or if column number information is not known for this
+	 *    compilation unit
+	 * @see ASTParser
+	 * @since 3.2
+	 */
+	public int columnNumber(final int position)
+	/**
+	 * Given a line number and column number, returns the corresponding 
+	 * position in the original source string.
+	 * Returns 0 if no line number information is available for this
+	 * compilation unit or the requested line number is less than one. 
+	 * Returns the total size of the source string if <code>line</code>
+	 * is greater than the actual number lines in the unit.
+	 * Returns 0 if <code>column</code> is less than 0,  
+	 * or the position of the last character of the line if <code>column</code>
+	 * is beyond the legal range. 
+	 * 
+	 * @param line the one-based line number
+	 * @param column the zero-based column number
+	 * @return the 0-based character position in the source string; 
+	 * returns <code>0</code> if line/column number information is not known 
+	 * for this compilation unit or the inputs are not valid
+	 * @since 3.2
+	 */
+	 public int getPosition(int line, int column)
+</pre>
+</li>
+<li>A tool to automate the update of the build notes is available on this update-site:<br>
+http://www.eclipse.org/jdt/core/tools/jdtcoretools/update-site/<br>
+<p>This is matching the format of the JDT/Core buildnotes. But the code can be easily customized for a different format.</p>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115662">115662</a>
+[javadoc][assist] link completion in types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106140">106140</a>
+[compiler] Eclipse3.1.0: unrecognized class invisibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113108">113108</a>
+[API][comments] CompilationUnit.getNodeComments(ASTNode)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110964">110964</a>
+[javadoc] Change compiler default options to have minimum javadoc warnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116028">116028</a>
+annotations only applied to first field in a declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112843">112843</a>
+Cut blocked by background build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116028">116028</a>
+annotations only applied to first field in a declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110797">110797</a>
+In case of multiple task tags on a single line, the tasks view does not show the complete line for each tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110173">110173</a>
+[plan] API to extract the Javadoc as HTML from attached HTML
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110188">110188</a>
+[plan][assist] Provide hook for completing inside string literal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107105">107105</a>
+[1.5][compiler] method override check does not detect differences in additional type bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115408">115408</a>
+[compiler] ArrayIndexOutOfBoundsException in CodeStream.java
+	  	
+<a name="v_620"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M4 - 8th November 2005
+<br>Project org.eclipse.jdt.core v_620
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_620">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added support for participating in reconcile (see <code>compilationParticipant</code> extension point as well as 
+     <code>CompilationParticipant</code> and <code>ReconcileContext</code> classes.)
+     Note that this support is still work in progress and it is subject to change.
+     Ability to participate in building will be added later.
+</li>
+<li>Code Assist: added support for completing on label in break/continue statement.
+</li>
+<li>Added new CompletionContext API (first part of fix for bug
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110181">110181</a>) :
+<pre>
+/**
+ * Returns the completed token.
+ * This token is either the identifier or Java language keyword
+ * or the string literal under, immediately preceding, 
+ * the original request offset. If the original request offset
+ * is not within or immediately after an identifier or keyword or
+ * a string literal then the returned value is &lt;code&gt;null&lt;/code&gt;.
+ * 
+ * @return completed token or &lt;code&gt;null&lt;/code&gt;
+ * @since 3.2
+ */
+public char[] getToken()
+
+/**
+ * Returns the kind of completion token being proposed.
+ * 
+ * The set of different kinds of completion token is
+ * expected to change over time. It is strongly recommended
+ * that clients do not assume that the kind is one of the
+ * ones they know about, and code defensively for the
+ * possibility of unexpected future growth.
+ * 
+ * @return the kind; one of the kind constants declared on
+ * this class whose name starts with &lt;code&gt;TOKEN_KIND&lt;/code&gt;,
+ * or possibly a kind unknown to the caller
+ * @since 3.2
+ */
+public int getTokenKind()
+
+/**
+ * Returns the character index of the start of the
+ * subrange in the source file buffer containing the
+ * relevant token being completed. This
+ * token is either the identifier or Java language keyword
+ * under, or immediately preceding, the original request 
+ * offset. If the original request offset is not within
+ * or immediately after an identifier or keyword, then the
+ * position returned is original request offset and the
+ * token range is empty.
+ * 
+ * @return character index of token start position (inclusive)
+ * @since 3.2
+ */
+public int getTokenStart()
+
+/**
+ * Returns the character index of the end (exclusive) of the subrange
+ * in the source file buffer containing the
+ * relevant token. When there is no relevant token, the
+ * range is empty
+ * (&lt;code&gt;getTokenEnd() == getTokenStart()&lt;/code&gt;).
+ * 
+ * @return character index of token end position (exclusive)
+ * @since 3.2
+ */
+public int getTokenEnd()
+
+/**
+ * Returns the offset position in the source file buffer
+ * after which code assist is requested.
+ * 
+ * @return offset position in the source file buffer
+ * @since 3.2
+ */
+public int getOffset()
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115363">115363</a>
+java.lang.VerifyError in org.eclipse.ui.workbench from HEAD, using N20051107
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22072">22072</a>
+Code completion on continue label: broken.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113950">113950</a>
+[1.5][compiler] Problems implementing inherited generic abstract methods and type erasure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115181">115181</a>
+[1.5][compiler] Wrongly flagged "Usage of a raw type"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113945">113945</a>
+No codeassist in anonymous class in generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114086">114086</a>
+Refactor-&gt;Rename of instance variables fails with "-1" when Code Style-&gt;Fields prefix list has dangling ","
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114341">114341</a>
+[javadoc][assist] range of the qualified type completion in javadoc text isn't correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114338">114338</a>
+[javadoc] Reconciler reports wrong javadoc warning (missing return type)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102286">102286</a>
+Error when trying F4-Type Hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114909">114909</a>
+AST: String concatenation represented as single node
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114539">114539</a>
+[search] Internal error when refactoring code with errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114855">114855</a>
+[compiler] OutOfMemoryError compiling deeply nested try-catch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114087">114087</a>
+[1.5][compiler] Eclipse compiles code that cannot be compiled with JDK!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114304">114304</a>
+[1.5][compiler] Return type not compatible with generic subinterface.
+
+
+<a name="v_619"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 31st October 2005 - 3.2 MILESTONE 3
+<br>Project org.eclipse.jdt.core v_619
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_619">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Three new API methods have been added on SearchPattern (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113549">113549</a>):
+<pre>
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or false otherwise. 
+ * CamelCase matching does NOT accept explicit wild-cards '*' and '?' and is inherently case sensitive.
+ *
+ * CamelCase denotes the convention of writing compound names without spaces, and capitalizing every term.
+ * This function recognizes both upper and lower CamelCase, depending whether the leading character is capitalized
+ * or not. The leading part of an upper CamelCase pattern is assumed to contain a sequence of capitals which are appearing
+ * in the matching name; e.g. 'NPE' will match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper CamelCase convention, whereas method or field
+ * names follow the lower CamelCase convention.
+ *
+ * The pattern may contain trailing lowercase characters, which will be match in a case sensitive way. These characters must
+ * appear in sequence in the name, after the last matching capital of the pattern. For instance, 'NPExcep' will match
+ * 'NullPointerException', but not 'NullPointerExCEPTION'.
+ * 
+ * For example:
+ *  - pattern = "NPE"
+ *    name = NullPointerException
+ *    result =&gt; true
+ *  - pattern = "npe"
+ *    name = NullPointerException
+ *    result =&gt; false
+ *
+ * @see CharOperation#camelCaseMatch(char[], char[])
+ * 	Implementation has been entirely copied from this method except for array lengthes
+ * 	which were obviously replaced with calls to {@link String#length()}.
+ * 
+ * @param pattern the given pattern
+ * @param name the given name
+ * @return true if the pattern matches the given name, false otherwise
+ */
+public static final boolean camelCaseMatch(String pattern, String name)
+
+/**
+ * Answers true if a sub-pattern matches the subpart of the given name using CamelCase rules, or false otherwise.  
+ * CamelCase matching does NOT accept explicit wild-cards '*' and '?' and is inherently case sensitive. 
+ * Can match only subset of name/pattern, considering end positions as non-inclusive.
+ * The subpattern is defined by the patternStart and patternEnd positions.
+ *
+ * CamelCase denotes the convention of writing compound names without spaces, and capitalizing every term.
+ * This function recognizes both upper and lower CamelCase, depending whether the leading character is capitalized
+ * or not. The leading part of an upper CamelCase pattern is assumed to contain a sequence of capitals which are appearing
+ * in the matching name; e.g. 'NPE' will match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper CamelCase convention, whereas method or field
+ * names follow the lower CamelCase convention.
+ *
+ * The pattern may contain trailing lowercase characters, which will be match in a case sensitive way. These characters must
+ * appear in sequence in the name, after the last matching capital of the pattern. For instance, 'NPExcep' will match
+ * 'NullPointerException', but not 'NullPointerExCEPTION'.
+ * 
+ * For example:
+ *	- pattern = "NPE"
+ *    patternStart = 1
+ *    patternEnd = 3
+ *    name = NullPointerException
+ *    nameStart = 0
+ *    nameEnd = 20
+ *    result =&gt; true
+ *  - pattern = "npe"
+ *    patternStart = 1
+ *    patternEnd = 3
+ *    name = NullPointerException
+ *    nameStart = 0
+ *    nameEnd = 20
+ *    result =&gt; false
+ *
+ * @see CharOperation#camelCaseMatch(char[], int, int, char[], int, int)
+ * 	Implementation has been entirely copied from this method except for array lengthes
+ * 	which were obviously replaced with calls to {@link String#length()} and
+ * 	for array direct access which were replaced with calls to {@link String#charAt(int)}.
+ * 
+ * @param pattern the given pattern
+ * @param patternStart the given pattern start
+ * @param patternEnd the given pattern end
+ * @param name the given name
+ * @param nameStart the given name start
+ * @param nameEnd the given name end
+ * @return true if a sub-pattern matches the subpart of the given name, false otherwise
+ */
+public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd)
+
+/**
+ * Validate compatibility between given string pattern and match rule.
+ *
+ * Optimized (i.e. returned match rule is modified) combinations are:
+ *  - {@link #R_PATTERN_MATCH} without any '*' or '?' in string pattern:
+ * 		pattern match bit is unset,
+ * 	- {@link #R_PATTERN_MATCH} and {@link #R_PREFIX_MATCH}  bits simultaneously set:
+ * 		prefix match bit is unset,
+ * 	- {@link #R_PATTERN_MATCH} and {@link #R_CAMELCASE_MATCH}  bits simultaneously set:
+ * 		camel case match bit is unset,
+ * 	- {@link #R_CAMELCASE_MATCH} with invalid combination of uppercase and lowercase characters:
+ * 		camel case match bit is unset and replaced with prefix match pattern,
+ * 	- {@link #R_CAMELCASE_MATCH} combined with {@link #R_PREFIX_MATCH} and {@link #R_CASE_SENSITIVE}
+ * 		bits is reduced to only {@link #R_CAMELCASE_MATCH} as Camel Case search is already prefix and case sensitive.
+ *
+ * Rejected (i.e. returned match rule -1) combinations are:
+ * 	- {@link #R_REGEXP_MATCH} with any other match mode bit set.
+ *
+ * @param stringPattern The string pattern
+ * @param matchRule The match rule
+ * @return Optimized valid match rule or -1 if an incompatibility was detected.
+ */
+public static int validateMatchRule(String stringPattern, int matchRule) {
+</pre>
+</li>
+<li>Added Camel Case support in completion.
+When you perform code complete, the proposals list contains proposals whose name match with the camel case pattern.
+<br>
+e.g. a possible proposal for TT| is ToTo.
+</li>
+<li>Added option to control Camel Case completion.
+<pre>
+/**
+ * CODEASSIST / Activate Camel Case Sensitive Completion
+ *    When active, completion show proposals whose name match to the CamelCase pattern.
+ *     - option id:         "org.eclipse.jdt.core.codeComplete.camelCaseMatch"
+ *     - possible values:   { "enabled", "disabled" }
+ *     - default:           "disabled"
+ */
+JavaCore#CODEASSIST_CAMEL_CASE_MATCH
+</pre>
+Currently this option is disabled by default. The default value of this option will be set to enabled when JDT/Text will be able to manage this kind of proposal
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114098">bug 114098</a>)
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114091">114091</a>
+[assist][javadoc] eternal loop 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114077">114077</a>
+No NLS Warning if unnecessary nls tag before declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83206">83206</a>
+ICodeAssist#codeSelect(..) on implicit methods should not return a java element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102572">102572</a>
+[plan] Add CamelHumps completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113649">113649</a>
+[javadoc][assist] CompletionOnJavadocTag token is not correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113765">113765</a>
+[1.5] Insufficient recovery in generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113671">113671</a>
+[search] AIOOBE in SearchEngine#searchAllTypeNames
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113549">113549</a>
+Need camel case matching routines for Strings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113722">113722</a>
+Sort members is confused with syntax errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113273">113273</a>
+[1.5][compiler] Compiler confused by multiply bounded type parameter
+
+
+<a name="v_618"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 25th October 2005
+<br>Project org.eclipse.jdt.core v_618
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_618">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Completion engine now supports completion inside Javadoc. User can complete after any word
+in Javadoc and get most appropriate proposal depending on area of completion.<br>
+Here is a breaf summary of code assist functionality in javadoc:
+<ul>
+<li>Completion of javadoc tag now only gives valid proposals.<br>
+Some examples:
+<ul>
+<li>complete <code>@pa|</code> will give <code>@param</code> proposal only in javadoc of method or generic type declarations,</li>
+<li>complete <code>{@co|</code> will give <code>{@code }</code> proposal only if your compiler compliance has been set to 1.5 or over,</li>
+<li>etc.</li>
+</ul>
+</li>
+<li>Completion in "formal reference" of <code>@see</code>, <code>@throws</code>, <code>@exception</code>, <code>{@link}</code>,
+<code>{@linplain}</code> or <code>{@value}</code> tags will behave like completion in java code. Type qualification for
+types will be inserted depending on "Add import instead of qualified name" Code Assist preferences.
+</li>
+<li>Completion is now available in text area of javadoc comment.<br>
+Some examples:
+<ul>
+<li>complete at caret in following code:
+<pre>
+/**
+ * This is an example of completion inside text area: S|
+ */
+public class Sample {}
+</pre>
+will propose both <code>String</code> and <code>Sample</code>, but also <code>{@link String }</code> and
+<code>{@link Sample }</code>.
+Currently each proposal is available either as java code type name or direclty inserted as a {@link} tag.
+This part is still under work and final behavior should depend on a new JDT/UI preferences...<br>
+<br>
+</li>
+<li>complete at caret in following code:
+<pre>
+/**
+ * This is an example of completion inside text area: #m|
+ */
+public class Sample {
+  void method() {}
+}
+</pre>
+will propose <code>{@link #method() }</code>.
+</li>
+</ul>
+</li>
+</ul>
+<br>
+New API methods have also been added to <code>CompletionContext</code>:
+<pre>
+/**
+ * Tell user whether completion takes place in a javadoc comment or not.
+ * 
+ * @return boolean true if completion takes place in a javadoc comment, false otherwise.
+ * @since 3.2
+ */
+public boolean isInJavadoc() {...}
+/**
+ * Tell user whether completion takes place in text area of a javadoc comment or not.
+ * 
+ * @return boolean true if completion takes place in a text area of a javadoc comment, false otherwise.
+ * @since 3.2
+ */
+public boolean isInJavadocText() {...}
+/**
+ * Tell user whether completion takes place in a formal reference of a javadoc tag or not.
+ * Tags with formal reference are:
+ * 	- @see
+ * 	- @throws
+ * 	- @exception
+ * 	- {@link Object}
+ * 	- {@linkplain Object}
+ * 	- {@value} when compiler compliance is set at leats to 1.5
+ * 
+ * @return boolean true if completion takes place in formal reference of a javadoc tag, false otherwise.
+ * @since 3.2
+ */
+public boolean isInJavadocFormalReference() {...}
+</pre>
+</li>
+<li>Added API <code>org.eclipse.jdt.core.IMember#ISourceRange getJavadocRange() throws JavaModelException</code>. This API can be used
+to retrieve the source range of a javadoc comment attached to the corresponding member.
+</li>
+<li>Added compiler option so as to specify whether optional errors should be fatal or not. By default, an optional error is 
+treated as fatal as a normal language error (as defined by the language spec book), when disabling this option, clients will
+be able to treat optional errors as severe warnings only, which will be rendered as errors, but no longer prevent from running
+the code. There is some work planned on UI side so as to better distinguish amongst mandatory vs. optional errors.
+<pre>
+* COMPILER / Treating Optional Error as Fatal
+*    When enabled, optional errors (i.e. optional problems which severity is set to "error") will be treated as standard
+*    compiler errors, yielding problem methods/types preventing from running offending code until the issue got resolved.
+*    When disabled, optional errors are only considered as warnings, still carrying an error indication to make them more
+*    severe. Note that by default, errors are fatal, whether they are optional or not.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.fatalOptionalError"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "enabled"
+</pre>	 
+</li>
+<li>Added <code>IJavaElementDelta#F_CATEGORIES</code>. This flag is set when one or more categories of an element 
+     are added/changed/removed.</li>
+<li>
+Java search engine is now able to perform search using Camel Case pattern while using new match rule flag
+defined on <code>SearchPattern</code> (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110060">110060</a>):
+<pre>
+/**
+ * Match rule: The search pattern contains a Camel Case expression.
+ * For example, <code>NPE</code> type string pattern will match
+ * <code>NullPointerException</code> type.
+ * @see CharOperation#camelCaseMatch(char[], char[]) for a detailed explanation
+ * of Camel Case matching.
+ *
+ * Can be combined to {@link #R_PREFIX_MATCH} match rule. For example,
+ * when prefix match rule is combined with Camel Case match rule,
+ * <code>"nPE"</code> pattern will match <code>nPException</code>.
+ *
+ * Match rule {@link #R_PATTERN_MATCH} may also be combined but both rules
+ * will not be used simultaneously as they are mutually exclusive.
+ * Used match rule depends on whether string pattern contains specific pattern 
+ * characters (e.g. '*' or '?') or not. If it does, then only Pattern match rule
+ * will be used, otherwise only Camel Case match will be used.
+ * For example, with <code>"NPE"</code> string pattern, search will only use
+ * Camel Case match rule, but with <code>N*P*E*</code> string pattern, it will 
+ * use only Pattern match rule.
+ * 
+ * @since 3.2
+ */
+public static final int R_CAMELCASE_MATCH = 0x0080;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113506">113506</a>
+[javadoc][assist] No tag proposals when there is a prefix on a line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113376">113376</a>
+[javadoc][assist] wrong overwrite range on completion followed by a tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113374">113374</a>
+[javadoc][assist] do not propose anything if the prefix is preceded by a special character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106466">106466</a>
+[1.5][compiler] Type parameter followed by other types in bound - rejected by javac, accepted by Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110172">110172</a>
+[plan] API to extract the Javadoc on org.eclipse.jdt.core.IMember
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87868">87868</a>
+[1.5][javadoc][assist] Dodgy completion in javadoc comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86112">86112</a>
+[javadoc][assist] Wrong reference to binary static initializer in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67732">67732</a>
+[javadoc][assist] Content assist doesn't work in Javadoc "line breaks"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=22043">22043</a>
+[javadoc][assist] Code Completion in Javadoc @see/@link doesn't work on partially entered argument types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107282">107282</a>
+[plan][compiler] Non mandatory JLS errors should not end up in problem methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52840">52840</a>
+Howto generate the parser: LPG 2.30 is which version of JikesPG?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113051">113051</a>
+No classpath marker produced when cycle through PDE container
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=113110">113110</a>
+TestFailures in DebugSuite
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112109">112109</a>
+Compilation problem: Eclipse does not recognise parametrized notify-method in generic context
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100970">100970</a>
+[1.5][compiler] Interface methods may conflict with Object methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112418">112418</a>
+PDE generate build file and ant task eclipse.buildScript ignore javaSource and javaTarget
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112973">112973</a>
+NLS tags like //$NON-NLS-?$ don't have the right range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110060">110060</a>
+[plan][search] Add support for Camel Case search pattern
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100182">100182</a>
+[1.5][compiler] unecessary cast in case of boxing
+
+
+<a name="v_617"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 18th October 2005
+<br>Project org.eclipse.jdt.core v_617
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_617">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In 5.0 compliant mode, the classfile name for an anonymous class is now correctly referring to its 
+innermost enclosing type name, e.g. "X$1$1" for an anonymous nested inside another anonymous; where 
+it was "X$2" before 5.0.</li>
+<li>Added compiler diagnosis to signal unused label (from labeled statement). Note that a label is considered to be
+used if explicitly referenced only.
+<pre>
+* COMPILER / Reporting Unreferenced Label
+*    When enabled, the compiler will issue an error or a warning when encountering a labeled statement which label
+*    is never explicitly referenced. A label is considered to be referenced if its name explicitly appears behind a break
+*    or continue statement; for instance the following label would be considered unreferenced;   LABEL: { break; }
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedLabel"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Added API <code>org.eclipse.jdt.core.ToolFactory#createDefaultClassFileReader(java.io.InputStream,int)</code>
+     that allows to the creation of an org.eclipse.jdt.core.util.IClassFileReader object using an input stream.
+</li>
+<li>Added API <code>JavaCore#addPreProcessingResourceChangedListener(IResourceChangeListener,int)</code>
+     that allows to register an <code>IResourceChangedListener</code> for a given event type that runs
+     before JDT Core.</li>
+<li>Added APIs to get the values of the @category tag in the Javadoc of a type, field or method: 
+     <code>IMember#getCategories()</code> and to get the children of a type for a given category
+     <code>IType#getChildrenForCategory(String)</code>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112137">112137</a>
+ConcurrentModificationException when CTRL+LeftClick on constructor call in Java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85298">85298</a>
+[1.5][enum] IType of anonymous enum declaration says isLocal() == false
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108856">108856</a>
+[1.5][compiler] Inner inner classes have illegal names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112231">112231</a>
+[1.5][compiler] enum declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112381">112381</a>
+Javadoc of IMethodBinding#overrides(IMethodBinding) refers to wrong JLS2 section
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105756">105756</a>
+[1.5][model] Incorrect warning on using raw types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112609">112609</a>
+StackOverflow when initializing Java Core
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112666">112666</a>
+[1.5][compiler] Compiler rejects valid assignment to complex capture
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=63840">63840</a>
+warning on unused labels
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112617">112617</a>
+[API] Add ToolFactory.createDefaultClassFileReader(InputStream,int)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112518">112518</a>
+[performance] NLS detection should be faster
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107814">107814</a>
+@SuppressWarnings("unused") requires additional //$NON-NLS-1$
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110613">110613</a>
+[1.5][compiler] Should not report warnings for nls string inside annotation declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112500">112500</a>
+[1.5][compiler] bug between inference and wilcard
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111350">111350</a>
+[1.5][compiler] method override and generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108782">108782</a>
+[1.5][compiler] inconsistent @Override error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108780">108780</a>
+[1.5][compiler] Subsignature checking does not respect erasure conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105808">105808</a>
+[1.5][dom] MethodBinding#overrides(..) should not consider return types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=23669">23669</a>
+[plan][DCR][Javadoc] Add support for @cat / @category organization of class members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112268">112268</a>
+[1.5][compiler] Type mismatch introduced in 3.1.1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112346">112346</a>
+[1.5][javadoc] Unexpected "Invalid reference" on javadoc field reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112190">112190</a>
+batch compiler option "-warn:+allUnchecked" does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112223">112223</a>
+Scanner#getNextToken() behavior doesn't seems consistent if there is an unicode inside a string.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107045">107045</a>
+[1.5][compiler] Compiler misses name clash with bounded class type parameter
+
+
+<a name="v_616"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 11th October 2005
+<br>Project org.eclipse.jdt.core v_616
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_616">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added CharOperation API to perform CamelCase matching. This new matching mode will be leveraged into
+codeassist and search.
+<pre>
+* Answers true if the pattern matches the given name using CamelCase rules, or false otherwise. 
+* char[] CamelCase matching does NOT accept explicit wild-cards '*' and '?'. 
+*
+* CamelCase denotes the convention of writing compound names without spaces, and capitalizing every term.
+* This function recognizes both upper and lower CamelCase, depending whether the leading character is capitalized
+* or not. The leading part of an upper CamelCase pattern is assumed to contain a sequence of capitals which are appearing
+* in the matching name; e.g. 'NPE' will match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+* uses a lowercase first character. In Java, type names follow the upper CamelCase convention, whereas method or field
+* names follow the lower CamelCase convention.
+*
+* The pattern may contain trailing lowercase characters, which will be match in a case sensitive way. These characters must
+* appear in sequence in the name, after the last matching capital of the pattern. For instance, 'NPExcep' will match
+* 'NullPointerException', but not 'NullPointerExCEPTION'.
+public static final boolean camelCaseMatch(char[] pattern, char[] name)
+public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd)
+</pre>
+</li>
+<li>Tuned new compiler diagnosis for raw type references. This problem can now be enabled independantly from 
+unchecked type operations, and carries its own severity settings. Removed "Type safety:" prefix from problem description
+as it is not truly fragilizing type integrity. This warning can still be silenced by <code>@SuppressWarnings("unchecked")</code>
+<pre>
+* COMPILER / Reporting Raw Type Reference
+*    When enabled, the compiler will issue an error or a warning when detecting references to raw types. Raw types are 
+*    discouraged, and are intended to help interfacing with legacy code. In the future, the language specification may 
+*    reject raw references to generic types.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.rawTypeReference"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre></li>
+<li>Added API <code>CategorizedProblem</code> to extend <code>IProblem</code> definitions with notion of
+problem category and marker type. This will enable other pluggable tool to participate in various compilation stages
+and report domain specific problems through the existing API (<code>IProblem</code> based). It is recommended that
+clients do not directly implement <code>IProblem</code> but instead do extend the abstract class <code>CategorizedProblem</code>.
+<pre>
+/**
+ * Returns an integer identifying the category of this problem. Categories, like problem IDs are
+ * defined in the context of some marker type. Custom implementations of <code>CategorizedProblem</code>
+ * may choose arbitrary values for problem/category IDs, as long as they are associated with a different
+ * marker type.
+ * @return id - an integer identifying the category of this problem
+ */
+public abstract int getCategoryID();
+</pre><pre>	
+/**
+ * Returns the marker type associated to this problem, if it was persisted into a marker by the JavaBuilder
+ * Standard Java problems are associated to marker type "org.eclipse.jdt.core.problem"), standard tasks 
+ * are associated to marker type "org.eclipse.jdt.core.task".
+ * @return the type of the marker which would be associated to the problem
+ * @see org.eclipse.jdt.core.IJavaModelMarker#JAVA_MODEL_PROBLEM_MARKER
+ * @see org.eclipse.jdt.core.IJavaModelMarker#TASK_MARKER
+ */
+public abstract String getMarkerType(); 
+</pre></li>
+<li>Added API <code>IJavaElementDelta#F_AST_AFFECTED</code> and <code>IJavaElementDelta#getCompilationUnitAST()</code>.
+     The Java element delta's flag is set to <code>F_AST_AFFECTED</code> when a reconcile operation affects the AST
+     created in the last reconcile operation. In this case the AST should be re-acquired using <code>getCompilationUnitAST()</code>.
+</li>
+<li>Added API to encode and decode a classpath entry (<code>IJavaProject#encodeClasspathEntry(IClasspathEntry)
+     and decodeClasspathEntry(String)</code>.
+<li>Added API <code>IClassFile#becomeWorkingCopy(...)</code> that returns an <code>ICompilationUnit</code>
+     in working copy mode on the given class file. See its Javadoc for more details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111898">111898</a>
+[compiler] Wrong code generation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111822">111822</a>
+DOMParser.createASTs() NPE at FieldReference.getConstantFor(FieldReference.java:408)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109118">109118</a>
+[1.5][compiler] Unhandled Exception Compiler error involving generics in java 1.5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111812">111812</a>
+[compiler] should improve error highlighting for static initializer errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111208">111208</a>
+[1.5][compiler] Compiler gets confused by multiple generic-extends'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111618">111618</a>
+[1.5][dom] Foreach statement shows extraneous semi column into debug variables view
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111703">111703</a>
+Static initialization block in anonymous inner class causes compiler to fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110168">110168</a>
+[plan] Broadcast AST when reconciling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111767">111767</a>
+Disassembler doesn't produce an output that can be compiled for annotation types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111299">111299</a>
+JavaModelCache may overflow the memory.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110596">110596</a>
+[assist] don't rank java.lang types lower if a simple name duplicate exists
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110171">110171</a>
+[plan] API to encode/decode a classpath entry into XML form
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111511">111511</a>
+Comments in compiler @arguments file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111420">111420</a>
+Disassembler doesn't generate type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111396">111396</a>
+TypeHierarchy doesn't notify listeners on addition of fully qualified subtypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110160">110160</a>
+[plan] Working copy for class file
+
+<a name="v_615"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 4th October 2005
+<br>Project org.eclipse.jdt.core v_615
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_615">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Compiler diagnosis for unnecessary cast is now able to recognize situations like:
+  <ul>
+  <li> <code>List l = (ArrayList) someList; </code></li>
+  <li> <code>List foo(List someList) { return (ArrayList) someList;} </code></li>
+  </ul></li>
+  <li>Compliance settings can now refer to "1.6" (aka "6.0") in addition to 1.3, 1.4 and 1.5. When classfile target is toggled to "1.6"
+  the major/minor version will be adjusted accordingly. Some 1.6 specific attributes (e.g. StackMapTable) are not produced yet.
+  </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111222">111222</a>
+[compiler] add new constants to support JDK 6.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111219">111219</a>
+Disassembler generates syntactically incorrect code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111014">111014</a>
+Internal Compiler Error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106010">106010</a>
+[1.5][compiler] Wrong warning message issued in generic nesting type casting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110813">110813</a>
+[search] ImportMatchLocatorParser should be implemented in its own CU
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70228">70228</a>
+new compiler warning for stuff like Object o = (Integer)(new Object())
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110576">110576</a>
+[encoding] Rename CU looses encoding for file which charset is determined by contents
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110304">110304</a>
+Formatter has no options for 'return'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110251">110251</a>
+Inaccurate problem description on bad nested class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110657">110657</a>
+[DOM] wrong position for single variable declaration inside enhanced for statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110987">110987</a>
+[compiler] the operator is not used to InstanceOfExpression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108731">108731</a>
+improved error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110433">110433</a>
+JavaModelManager#getElementsOutOfSynchWithBuffers() should use a HashSet
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110434">110434</a>
+Move WeakHashSet to model
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110439">110439</a>
+HashableWeakReference should be static
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110449">110449</a>
+Remove field IndexBasedHierarchyBuilder#handleToWorkingCopy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110789">110789</a>
+ProjectCache.pathToResolvedEntries should be rootToResolvedEntries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69471">69471</a>
+[DOM/AST] Improve guessing of method binding for overloaded methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110773">110773</a>
+ITypeBinding#isEqualTo(..) is wrong when comparing NodeList&lt;String&gt;.Cursor to its type declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109963">109963</a>
+[dom] Two VariableDeclarationStatements in switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109940">109940</a>
+[dom] IllegalArgumentException is thrown in CharacterLiteral.charValue()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110270">110270</a>
+Failure in model test 20050921-1200
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110082">110082</a>
+[compiler] Increase compiler performance for "Remove superfluous NLS strings" warnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110849">110849</a>
+[compiler] Batch compiler doesn't use the user.dir if no classpath is specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110738">110738</a>
+[1.5][compiler] Internal compiler error while processing Currency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110826">110826</a>
+[compiler] Batch compiler doesn't work when set on the bootclasspath
+
+<a name="v_614"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M3 - 27th September 2005
+<br>Project org.eclipse.jdt.core v_614
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_614">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+Added optional compiler diagnosis for signaling usage of raw types. A raw type is a reference to some
+generic type without any type argument (e.g. "List" in place of "List&lt;Element&gt;").
+<pre>
+* COMPILER / Reporting Raw Type Reference
+*    When enabled, the compiler will signal references to raw types. Raw types are discouraged, and are intended to help interfacing
+*    with legacy code. In the future, the language specification may reject raw references to generic types.
+*    The severity of the problem is controlled with option "org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation".
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.rawTypeReference"
+*     - possible values:   { "enabled", "disabled" }
+*     - default:           "disabled"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107004">107004</a>
+NPE in TypeBinding.getKey()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108740">108740</a>
+[1.5][compiler] Type hierarchy with generics fails with NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101456">101456</a>
+Proposals and Open Declaration fail with NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110570">110570</a>
+[1.5][compiler] error in type deduction
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110563">110563</a>
+[1.5][compiler] Internal compiler error for varags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89529">89529</a>
+[1.5][compiler] improve warnings for raw types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110182">110182</a>
+[compiler] Eclipse does not recompile rt.jar properly 
+
+
+<a name="v_613"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 21st September 2005 - 3.2 MILESTONE 2
+<br>Project org.eclipse.jdt.core v_613
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_613">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=109055">109055</a>
+Error starting JDT Core due to IAE: Path for project must have only one segment.
+	  	
+<a name="v_612"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 19th September 2005
+<br>Project org.eclipse.jdt.core v_612
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_612">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=108203">108203</a>
+[1.5][compiler] cannot compile internal class implementing interface with parameterized method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107681">107681</a>
+[1.5][compiler] invalid ambiguous invocation diagnostic
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107098">107098</a>
+[1.5][compiler] method override check fails with instantiated type parameter in bound
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103849">103849</a>
+[jdk][compiler] Incorrect ambiguity error for generic types + inheritance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102631">102631</a>
+[1.5][compiler] false java error for ambiguous methods
+
+<a name="v_611"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 16th September 2005
+<br>Project org.eclipse.jdt.core v_611
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_611">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=109646">109646</a>
+[DOM] Parsing using K_STATEMENTS doesn't return the right tree for multiple local declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109535">109535</a>
+[DOM] Wrong infix expression when '-' is used within string literals
+
+<a name="v_610"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 13th September 2005
+<br>Project org.eclipse.jdt.core v_610
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_610">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=109333">109333</a>
+[DOM/AST] OR_OR and AND_AND expression are not converted to an infix expression using extended operands
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109340">109340</a>
+[Formatter] Wrong positionning of empty statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108622">108622</a>
+[javadoc][dom] ASTNode not including javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52283">52283</a>
+do &lt;single-statement&gt; while(&lt;condition&gt;) is ill-formatted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101080">101080</a>
+NPE during computePriority for problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108783">108783</a>
+[1.5][compiler] Runnable masks Iterable interface in bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107110">107110</a>
+IMethodBinding.isSubsignature not yet correctly implemented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101380">101380</a>
+[1.5][compiler] Problem when implementing generic interface with method that has enum parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108820">108820</a>
+Index based type hierarchy should not consider interfaces in index when focus is a class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99734">99734</a>
+[select] CodeSelect fails when selecting an anonymous class of Object
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108615">108615</a>
+Unable to inherit abstract methods from jarred interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108263">108263</a>
+[1.5][compiler] Constants initilialization doesn't work inside Annotation
+
+
+<a name="v_609"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 6th September 2005
+<br>Project org.eclipse.jdt.core v_609
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_609">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The size limit of the internal Java model cache is now function of the max heap size (-Xmx VM argument) given to the Java Virtual Machine.
+      Thus users who give more memory to the VM because they have big .jar files on their classpath will see an increase in performance.
+</li>
+<li>Reading the .classpath file is now forward compatible with upcoming versions. If a .classpath file contains unknown elements and attributes,
+     these are left untouched and are persisted.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104695">104695</a>
+[1.5][compiler] Compiler allows instanceof with non-reifiable array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101425">101425</a>
+Classpath persistence should be resilient with unknown attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108372">108372</a>
+[1.5][compiler] Inner class of enclosing raw type don't works
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106202">106202</a>
+JavaModelCache should have configurable LRU cache limits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107756">107756</a>
+[1.5][compiler] Invalid diagnostic invoking method through raw interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100636">100636</a>
+[model] Can't find overriden methods of protected nonstatic inner class.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100606">100606</a>
+NPE during reconcile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101228">101228</a>
+JME on code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103466">103466</a>
+Stack Overflow: Requesting Java AST from selection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87193">87193</a>
+CodeFormatter Indent on column wrapping
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99645">99645</a>
+[select] CodeSelect doesn't work for type parameter declaration of a local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71766">71766</a>
+[format] Formatter fails to wrap lines for assignment statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102284">102284</a>
+[5.0 ] CCE in ParameterizedTypeBinding [code assist]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83206">83206</a>
+ICodeAssist#codeSelect(..) on implicit methods should not return a java element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72402">72402</a>
+[format] align method arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103706">103706</a>
+[formatter] indent empty lines
+
+<a name="v_608"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 30th August 2005
+<br>Project org.eclipse.jdt.core v_608
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_608">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=83005">83005</a>
+[1.5][assist] Content Assist in annotation offers to override methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105581">105581</a>
+Creating a Java project from existing source fails because of "Unhandled event loop exception": ArrayIndexOutOfBoundsException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104486">104486</a>
+newNotPresentException when reconciling CU in a non-java project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104879">104879</a>
+BindingKey#internalToSignature() returns invalid signature for local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106725">106725</a>
+[content assist] wrong method created when overriding static method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107330">107330</a>
+ASTParser#createASTs(..) returns invalid binding for key of local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107580">107580</a>
+Putting a period after an enum element with a constructor causes a crash
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107735">107735</a>
+StringIndexOutOfBoundsException in Util.getNameWithoutJavaLikeExtension()
+	  	
+<a name="v_607"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 23rd August 2005
+<br>Project org.eclipse.jdt.core v_607
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_607">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=107535">107535</a>
+batch compiler should put is own version in the compiler log file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107079">107079</a>
+[1.5][compiler] mis-compiled Wildcard capture leads to a ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107249">107249</a>
+NullPointerException at BinaryIndexer.indexDocument()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104202">104202</a>
+Better locations for assignement errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102422">102422</a>
+Exception referencing class in large jar files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100549">100549</a>
+Strange binding keys from AST on class file of nested type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101777">101777</a>
+[search] selecting class with a main type ignores the default package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107124">107124</a>
+NullPointerException at ClassFileStruct.u2At
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106581">106581</a>
+[javadoc] null type binding for parameter in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106936">106936</a>
+[1.5][compiler] Unoptimal lub computation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106865">106865</a>
+[1.5][compiler] capture conversion doesn't handle array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105284">105284</a>
+[1.5][compiler] Autoboxing: Type mismatch
+
+
+<a name="v_606"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M2 - 16th August 2005
+<br>Project org.eclipse.jdt.core v_606
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_606">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48976">48976</a> is now enabled again. A tool can be installed from <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/tools/jdtcoretools/update-site">update site</a>
+to easily remove unnecessary nls tags. Copy the link as a new update site under Eclipse. The tool requires a build &gt; 20050812.
+<ul>
+<li>nls tags are ignored in isolated line comments like:<br>
+<pre>
+<code>		...
+		// System.out.println(""); //$NON-NLS-1$
+		...</code>
+</pre>
+</li>
+<li>Other nls comments are reported as unnecessary if they don't match a corresponding string literal</li>
+<li>The tool removes the unnecessary nls tags even if the line comment is used for another comment:
+<pre>
+<code>String s = "Hello, World"; //$NON-NLS-1$ This won't be removed //$NON-NLS-2$ at all</code>
+</pre>
+becomes:
+<pre>
+<code>String s = "Hello, World"; //$NON-NLS-1$ This won't be removed  at all</code>
+</pre>
+
+</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106964">106964</a>
+[1.5][search] AIOBE in MethodLocator.matchOverriddenMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99903">99903</a>
+[1.5][search] range wrong for package-info
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99662">99662</a>
+[1.5] JavaModel returns inexistent IType for package-info ICompilationUnits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106875">106875</a>
+[compiler] Unnecessary nls tags detection fails on duplicate tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105284">105284</a>
+[1.5][compiler] Autoboxing: Type mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106834">106834</a>
+IMethodBinding#isEqualTo(..) wrong with overloaded parameterized methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48976">48976</a>
+Remove superfluous $NON-NLS comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105816">105816</a>
+Extraneous NLS tag incorrectly found in comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106106">106106</a>
+[1.5][compiler] Compiler error with Arrays.asList in Java 5 mode?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106403">106403</a>
+PublicScanner returns EOF late
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105531">105531</a>
+[1.5][compiler] ecj from CVS generates spurious incomprehensible error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106514">106514</a>
+[1.5][compiler] Improve diagnostic on bound mismatch for GenericTypeTests.test790
+
+
+<a name="v_605"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 10th August 2005 - 3.2 MILESTONE 1 
+<br>Project org.eclipse.jdt.core v_605
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_605">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=106656">106656</a>
+[compiler] Batch compiler exits with error code -1 when only warnings are found
+
+
+<a name="v_604"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 9th August 2005
+<br>Project org.eclipse.jdt.core v_604
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_604">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=106297">106297</a>
+[1.5][compiler] new A&lt;X&gt;().new B(){}
+
+
+<a name="v_603"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 8th August 2005
+<br>Project org.eclipse.jdt.core v_603
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_603">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=100041">100041</a>
+[javadoc][dom] Wrong positions when javadoc comment inside method declaration
+
+
+<a name="v_602"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 2nd August 2005
+<br>Project org.eclipse.jdt.core v_602
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_602">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The compiler won't report anymore unnecessary non nls tags (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48976">48976</a> for details).<br>
+This will be reverted after 3.2M1 build.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105635">105635</a>
+incorrect parsing of field declarations with generic types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100772">100772</a>
+[1.5][search] Search for declarations in hierarchy reports too many matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100695">100695</a>
+[1.5][search] Renaming a field of generic array type has no effect
+
+<a name="v_601"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 2nd August 2005
+<br>Project org.eclipse.jdt.core v_601
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_601">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The Java conventions built-in code formatter profile has been updated to reflect the tab size at 8.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104765">104765</a>
+Tab width error in Java Conventions [built-in]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105192">105192</a>
+NaiveASTFlattener incorrectly renders a for statement with multiple initializers or multiple updaters
+
+<a name="v_600"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.2M1 - 26th July 2005
+<br>Project org.eclipse.jdt.core v_600
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_600">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=105430">105430</a>
+ecj chokes when classpath has leading separator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104738">104738</a>
+[1.5][compiler] Enclosing method attribute is generated for member type of a local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104704">104704</a>
+[compiler] caching in the constant pool could be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104664">104664</a>
+[compiler] repeat mode is broken in the batch compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99423">99423</a>
+[1.5] [javadoc] inconsistent getStartPosition()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104649">104649</a>
+[1.5][compiler] method type variable: inference broken for null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104877">104877</a>
+[1.5] TypeDeclarationStatement should use DECLARATION_PROPERTY in JLS3 API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104780">104780</a>
+TVT 3.1: TCT 386 - wrong description for option FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104655">104655</a>
+[1.5] inconsistent compiler behavior in generic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104551">104551</a>
+[1.5][compiler] Method override checks fail with raw subtype and type variable as type bound
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104492">104492</a>
+[AST]java.lang.ClassCastException: org.eclipse.jdt.core.dom.PrimitiveType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103485">103485</a>
+[1.5][compiler] compiler: wrongfully accepted method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104245">104245</a>
+AST.newCompilationUnit javadoc error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103994">103994</a>
+[1.5][compiler] Internal compiler error while overriding bootstrap class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103528">103528</a>
+[1.5][compiler] compiler allows invalid assignment with method type parameter and nested wildcards
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104082">104082</a>
+[1.5][compiler] 1.5 source code gets internal eclipse null pointer error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104167">104167</a>
+[1.5][compiler] incorrect 'unread field' diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103320">103320</a>
+Method-local subtype with instance initializer break JDOM
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103636">103636</a>
+JDT compiler produces invalid XML
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103227">103227</a>
+[1.5][compiler] VerifyError in case of a parametrized anonymous class inside a static inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103148">103148</a>
+[1.5][assist] Code completion breaks if using static method generics ( Class.&lt;T&gt;staticMethod(params) )
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103472">103472</a>
+[1.5][compiler] Should detect incompatible super interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91426">91426</a>
+[Markers] Java task tags in Task View don't have configured priority
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103023">103023</a>
+[1.5][compiler] StackOverflow inferring type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102778">102778</a>
+Scrapbook page doesn't work with enhanced for statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101283">101283</a>
+[1.5][javadoc] Javadoc validation raises missing implementation in compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100868">100868</a>
+Code assist does not recommend methods in anonymous enum subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101456">101456</a>
+Proposals and Open Declaration fail with NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101387">101387</a>
+[1.5][compiler] Incorrect Cycle detected in type hierarchy error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97326">97326</a>
+[dom] ITypeBinding#isFromSource() is always false for type variables, wildcards, and capture types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100153">100153</a>
+[1.5][compiler] Bound check failure on recursive formal bound
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100808">100808</a>
+[assist] Wrong replace range for package proposals if there is no line termination
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98532">98532</a>
+[1.5][compiler] Spurious 'type parameter T is hiding the type T' warning for static nested classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100797">100797</a>
+editor general failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100043">100043</a>
+[1.5][compiler] false compiler error on ?: ternary operator with boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102181">102181</a>
+[1.5][compiler] Generic varargs are built with incorrect array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102305">102305</a>
+Error in JDT Core during reconcile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102213">102213</a>
+[1.5][compiler] enum constants cannot be referenced inside enum constants initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101955">101955</a>
+NullPointerException after invoking extract method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97220">97220</a>
+Should not issue nls warning for annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101885">101885</a>
+[mode] sort operation doesn't set the RELATIVE_ORDER for enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101247">101247</a>
+[formatter] Fails to format some labelled statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101713">101713</a>
+[1.5][compiler] Access to static fields within enum constructors inconsistent with javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101779">101779</a>
+[1.5][compiler] VerifyError using -- operator on unboxed generic Integer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101208">101208</a>
+[compiler] instanceof check cannot be unnecessary on null values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100619">100619</a>
+[1.5][compiler] Incorrect duplicate bound diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94759">94759</a>
+[1.5][compiler] @Override doesn't report an error inside interface when specified for clone() method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98538">98538</a>
+[1.5][compiler] Inference broken for subtypes of subtypes of F-bounded types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102650">102650</a>
+[ast rewrite] Removing all TYPE_PARAMETERS_PROPERTY values in a derived type gives incompilable code
+
+
+<p><hr>
+For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R31_buildnotes_jdt-core.html">build notes up to Release 3.1</a>.
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/notes/R33_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R33_buildnotes_jdt-core.html
new file mode 100644
index 0000000..6ca636e
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R33_buildnotes_jdt-core.html
@@ -0,0 +1,3221 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes 3.3</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.3 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch.
+	  For more information on 3.3 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.3/index.php#release-plan">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.3/index.php#milestone-plan">milestone plan</a>,
+	  the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_2.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.0 (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>).
+	  Older changes which occurred up to Release 3.0 can be found in
+	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html">build notes R2.1</a>.
+	  -->
+	  This present document covers all changes since Release 3.2 (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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+<a name="v_771"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3 - June 21, 2007 - 3.3 RELEASE
+<br>Project org.eclipse.jdt.core v_771
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_771">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=193570">193570</a>
+add eclipse.inf to top level directory of jdt.core
+
+<a name="v_770"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC4 - June 5, 2007 - 3.3 RELEASE CANDIDATE 4
+<br>Project org.eclipse.jdt.core v_770
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_770">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=190748">190748</a>
+[1.5][compiler] AbstractMethodError on derived implementation of derived Interface declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=189933">189933</a>
+[compiler][1.5] extraneous ambiguous constructor error on generics
+
+<a name="v_769"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC4 - June 4, 2007
+<br>Project org.eclipse.jdt.core v_769
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_769">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=190493">190493</a>
+[1.6][compiler] Compiling for 1.6 should not require compiler to run on 1.6 itself
+
+
+<a name="v_768"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC3 - May 30, 2007 - 3.3 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_768
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_768">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=189547">189547</a>
+Possible resource leak in org.eclipse.jdt.internal.compiler.parser.Parser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=189852">189852</a>
+[perfs] Too many JDT/Core performance tests in fingerprints
+
+<a name="v_767"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC3 - May 29, 2007
+<br>Project org.eclipse.jdt.core v_767
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_767">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=189456">189456</a>
+Formatter is slow on  big files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188105">188105</a>
+org.eclipse.jdt.apt.pluggable.core imported as source does not compile
+
+<a name="v_766"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC2 - May 25, 2007 - 3.3 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_766
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_766">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The new API <code>ToolFactory#createCodeFormatter(Map options, int mode)</code> allows to specify whether the code
+      formatter is going to format new code or existing code.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188960">188960</a>
+[1.5][compiler]Do not detect duplicate constructors in a ParameterizedType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185928">185928</a>
+New Formatter Option &quot;Never indent comments on first column&quot; breaks formatting of auto generated bodies
+
+<a name="v_765"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC2 - May 24, 2007
+<br>Project org.eclipse.jdt.core v_765
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_765">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=172820">172820</a>
+Hard-coded class libraries names in org/eclipse/jdt/core/tests/util/Util.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188741">188741</a>
+[1.5][compiler] Incorrect ambiguous method error with inherited raw type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188247">188247</a>
+[content assist] Code Completion for static importing fields not working
+
+
+<a name="v_764"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC2 - May 23, 2007
+<br>Project org.eclipse.jdt.core v_764
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_764">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=188648">188648</a>
+ECJ compiler fails to find boot classes on Harmony
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188656">188656</a>
+[perfs] 2% regression on some Batch Compiler tests since v_756
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188136">188136</a>
+[javadoc][assist] Errors in org.eclipse.jdt.ui.JavaTypeCompletionProposalComputer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188127">188127</a>
+[test] Some tests fail on Harmony
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162054">162054</a>
+[build] Got a failure on MultiProjectTests.testCycle5 on my speedy test box...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188103">188103</a>
+[1.5][compiler] Inappropriate usage of HashSet
+
+<a name="v_763"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 16, 2007 - 3.3 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_763
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_763">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=187329">187329</a>
+compilation error constants created with static methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=187223">187223</a>
+CompletionTestsRequestor2.getReversedResults has incorrect comparator
+
+<a name="v_762"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 16, 2007
+<br>Project org.eclipse.jdt.core v_762
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_762">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=133141">133141</a>
+Must JavaCore.create(IFile) always do full checks?
+
+<a name="v_761"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 15, 2007
+<br>Project org.eclipse.jdt.core v_761
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_761">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=183338">183338</a>
+[perfs] Too many JDT/Core performance tests are yellow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186833">186833</a>
+[1.5][compiler] Should detect member supertype cycle when resolved thru static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186382">186382</a>
+[1.5][compiler] Ambiguous method call error reported on a demonstrably unambiguous call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186749">186749</a>
+CCE in Scope.findMemberType
+
+<a name="v_760"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 15, 2007
+<br>Project org.eclipse.jdt.core v_760
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_760">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=177922">177922</a>
+FlexibleProjectContainer refresh logic sporadically leaves project with &quot;missing library&quot; error on rename/delete
+
+<a name="v_759"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 14, 2007
+<br>Project org.eclipse.jdt.core v_759
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_759">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=185576">185576</a>
+[javadoc][assist] Type parameters should not be proposed while completing in @link or @see reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143026">143026</a>
+[ast rewrite] Clean up parantheses are not recognizing comment //
+
+<a name="v_758"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 11, 2007
+<br>Project org.eclipse.jdt.core v_758
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_758">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=168208">168208</a>
+Renaming classes from lowercase to uppercase results in an error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186181">186181</a>
+1.5 compiler does not understand class files built by -target jsr14
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186415">186415</a>
+[search] Search for package declarations should not return duplicate elements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185129">185129</a>
+NPE in LocalVariableBinding.computeUniqueKey
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185119">185119</a>
+[search] TypeNameMatch must specify that it could not be overridden by clients
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=184546">184546</a>
+[compiler][null] Spurious redundant null check warning in finally when the class has a static field
+
+<a name="v_757"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 10, 2007
+<br>Project org.eclipse.jdt.core v_757
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_757">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=185306">185306</a>
+Help with fields and methods on binary super types with unresolved references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185950">185950</a>
+[performance] opening class file without source attachement is too slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186189">186189</a>
+NPE trying to open the following class using the ASTView
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173944">173944</a>
+cannot cancel build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185182">185182</a>
+Fup of 126712, the two regressions tests in RuntimeTests should be rewritten
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185733">185733</a>
+Refreshing external jar doesn't update problem marker
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143025">143025</a>
+[build path] Derived attribute on default output folder of Java project doesn't work
+
+<a name="v_756"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3RC1 - May 7, 2007
+<br>Project org.eclipse.jdt.core v_756
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_756">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=185787">185787</a>
+[1.5][compiler] Missing unnecessary cast diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154693">154693</a>
+project clean &amp; build sometimes copies subversion .svn folders to bin tree
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84886">84886</a>
+[compiler] compiled code wrong with ambiguous inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185768">185768</a>
+[1.6][compiler] Enabling apt by default in batch mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185567">185567</a>
+[compiler] dead bytecodes are generated inside optimized boolean condition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162965">162965</a>
+[compiler] dead bytecodes are generated inside conditional expressions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185310">185310</a>
+Removing internal jar referenced from another project doesn't update Package Explorer
+
+<a name="v_755"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - May 2, 2007 - 3.3 MILESTONE 7
+<br>Project org.eclipse.jdt.core v_755
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_755">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=156731">156731</a>
+[compiler] Improve compiler fault-tolerance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=184957">184957</a>
+[1.5][compiler] Compiler crash
+
+<a name="v_754"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 30, 2007
+<br>Project org.eclipse.jdt.core v_754
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_754">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=184293">184293</a>
+Unnecessary inherited method errors reported against subtypes
+
+<a name="v_753"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 28, 2007
+<br>Project org.eclipse.jdt.core v_753
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_753">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=165783">165783</a>
+[ast rewrite] Import declaration static property can not be set correctly
+
+<a name="v_752"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 27, 2007
+<br>Project org.eclipse.jdt.core v_752
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_752">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=175409">175409</a>
+method reference contains generic method binding
+
+<a name="v_751"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 26, 2007
+<br>Project org.eclipse.jdt.core v_751
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_751">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=180713">180713</a>
+Anonymous type rendered as number in hover
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182154">182154</a>
+Java search gives no results on workspace with multiple projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144776">144776</a>
+JavaProject.resetCaches() needs to reset dependent projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179011">179011</a>
+IType#getMethod(..) should not throw AFE when name contains dot
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162104">162104</a>
+NPE in PackageExplorerContentProvider.getPackageFragmentRoots()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158985">158985</a>
+Code completion engine hints annotations on wrong places
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183833">183833</a>
+NPE in latest build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183413">183413</a>
+PDE can't find the source for plug-ins in the target
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=184102">184102</a>
+[1.6][compiler] Inconsistent stackmap frame generated for static initializer of enums containing overridden methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146556">146556</a>
+Should refactor boolean fields into bits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49314">49314</a>
+comments formatted even if &quot;Enable comment formatting&quot; is disabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=20793">20793</a>
+[formatter] The code formatter indent left aligned comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180905">180905</a>
+Tweaks to recovered bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183216">183216</a>
+[1.5][compiler] Cannot refer to a generic member type using a non static subclass of the enclosing type
+
+<a name="v_750"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 24, 2007
+<br>Project org.eclipse.jdt.core v_750
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_750">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=182930">182930</a>
+JavaModelCache's size  grows when displaying type hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183062">183062</a>
+[search] OutOfMemoryError during rename refactoring
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79068">79068</a>
+[formatter] Need option to control line wrapping before/after operators
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180789">180789</a>
+[1.5][compiler] invalid incompatible return type error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183538">183538</a>
+Not getting @Inherited annotation on annotation types from binary
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183468">183468</a>
+NPE trying to call isDefault() on the MemberValuePairBinding corresponding to array=1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183395">183395</a>
+Fup of bug 144858, internal error is thrown for wrong exception type in catch clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181349">181349</a>
+ArrayIndexOutOfBoundsException while editing Java code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182485">182485</a>
+Missing translation files in JDT plug-ins
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161175">161175</a>
+JarPackageFragmentRoot slow to initialize
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182204">182204</a>
+Deleting a JRE referenced by container does not result in unbound container problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162370">162370</a>
+MethodVerifier#areReturnTypesEqual is a misnomer
+
+<a name="v_749"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 17, 2007
+<br>Project org.eclipse.jdt.core v_749
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_749">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=118217">118217</a>
+Compiler error/warning option 'Parameter is never read' produces a lot of false-positives
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181393">181393</a>
+DefaultASTVisitor doesn't override all methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145329">145329</a>
+[scaling] Unable to locate source in monster workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177174">177174</a>
+[assist] Wrong names are proposed as unresolved local variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181727">181727</a>
+[perfs] JDT/Core performances tests last too long on slowest releng test boxes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180109">180109</a>
+[compiler] JDT Throws ClassCastException on incremental build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177819">177819</a>
+Jar files added to a plugin are ignored
+
+<a name="v_748"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 10, 2007
+<br>Project org.eclipse.jdt.core v_748
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_748">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=181269">181269</a>
+Deleting secondary type is not detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179684">179684</a>
+&quot;Reconcile editor change&quot; perf test is getting slower
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180683">180683</a>
+codeSelect does not work in unicode names like \u0042
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181270">181270</a>
+[1.5][compiler] Class literal of array of type parameter should be rejected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178551">178551</a>
+[index] Deadlock when doing Type Hierarchy while updating a large workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180524">180524</a>
+NPE in ITypeBinding#createArrayType(..) on anonymous type
+
+<a name="v_747"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - April 3, 2007
+<br>Project org.eclipse.jdt.core v_747
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_747">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=178213">178213</a>
+Compilation Unit not shown in Package Explorer after a rename
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180471">180471</a>
+[compiler] Unoptimal code generation for for-loops when no continuation point
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176320">176320</a>
+Non linear progress in open type dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176472">176472</a>
+[compiler][null] extraneous error in case of a labeled while(true) statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166963">166963</a>
+[compiler] resolve binding for local variable in ConstructorInvocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179630">179630</a>
+Compiler parsing tests fail with IBM J2SE 1.4.2, 5.0, and 6.0 (early access)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=151787">151787</a>
+[compiler] compiler allows assignment to final field in constructor other than through 'this'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178499">178499</a>
+[perfs] JDT/Core model performances tests must be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180169">180169</a>
+Add protection against missbehaving container (returning null entries)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180046">180046</a>
+patch to antadapter eclipse.inf
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166449">166449</a>
+Don't abort build when CompilationParticipants fix classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179529">179529</a>
+Stop Eclipse takes a lot of time in case of big workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179000">179000</a>
+[code assist] run() should not be a valid proposal inside the scrapbook page
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169728">169728</a>
+[1.5][compiler] WildcardBinding.boundCheck coding error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179056">179056</a>
+[compiler] Compiler gives misleading Range for invisible field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179699">179699</a>
+type.newTypeHierarchy doesn't cancel
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179672">179672</a>
+[assist] Only one assertion method should be called by completion parser test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174445">174445</a>
+[1.5][compiler] missing unchecked conversion warning upon parametrized method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179258">179258</a>
+simple reconcile starts problem finder - main thread waiting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179477">179477</a>
+[compiler] problem in first element of array initializer suppresses further problems
+
+<a name="v_746"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M7 - March 27, 2007
+<br>Project org.eclipse.jdt.core v_746
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_746">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=179199">179199</a>
+[search] Open type throws NPE during Items filtering
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178895">178895</a>
+[compiler][null] A for-each loop changes its value on each iterator but the null pointer analysis is not taking that into consideration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177863">177863</a>
+[compiler][null] Spurious null pointer warning in finally block (involving def. unknown)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179065">179065</a>
+[DOM] Test coverage for IMemberValuePairBinding methods must be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=179042">179042</a>
+[DOM] Implementation of IBinding.getModifiers() should return Modifier.NONE when no modifiers are available
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178861">178861</a>
+Executing run() in a scrapbook page leads to a NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178039">178039</a>
+Separate advanced verbose for container and variable initialization from regular verbose
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178847">178847</a>
+[search] Potential matches found when searching references to IJavaElement#getResource()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174920">174920</a>
+[model] closing a single project causes all variables and containers to be saved
+
+<a name="v_745"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 21, 2007 - 3.3 MILESTONE 6
+<br>Project org.eclipse.jdt.core v_745
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_745">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li><code>org.eclipse.jdt.core.JavaCore#setCompilanceOptions(String, Map)</code> has been renamed to <code>org.eclipse.jdt.core.JavaCore.setComplianceOptions(String, Map)</code>.</li>
+<li><code>org.eclipse.jdt.core.dom.RecoveredTypeBinding</code>, <code>org.eclipse.jdt.core.dom.RecoveredVariableBinding</code> are not part of the API. They have been
+changed to package default visibility.</li>
+<li><code>org.eclipse.jdt.core.search.MethodReferenceMatch#isPolymorphic()</code> has been removed.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178616">178616</a>
+[API] Fix typo for JavaCore#setComplianceOptions(String, Map)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178607">178607</a>
+[API][dom] RecoveredTypeBinding and RecoveredVariableBinding should not be public
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178594">178594</a>
+[search] Deprecated MethodReferenceMatch.isPolymorphic() should be removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176118">176118</a>
+Missing library classes kill Intellisense without Error
+
+<a name="v_744"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 20, 2007
+<br>Project org.eclipse.jdt.core v_744
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_744">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>This drop only fixes tests failures reported in I20070319-1800.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_743"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 19, 2007
+<br>Project org.eclipse.jdt.core v_743
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_743">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New constant API have been added in <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants</code> in order to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=20793">20793</a>.
+The implementation will be provided after 3.3M6.<br>
+<pre>
+	/**
+	 * FORMATTER / Option to indent block comments that start on the first column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.formatter.never_indent_block_comments_on_first_column"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_NEVER_INDENT_BLOCK_COMMENTS_ON_FIRST_COLUMN = JavaCore.PLUGIN_ID + ".formatter.never_indent_block_comments_on_first_column"; //$NON-NLS-1$	
+	/**
+	 * FORMATTER / Option to indent line comments that start on the first column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.formatter.never_indent_line_comments_on_first_column"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN = JavaCore.PLUGIN_ID + ".formatter.never_indent_line_comments_on_first_column"; //$NON-NLS-1$	
+</pre>
+</li>
+<li>New constant API have been added in <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants</code> in order to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=79068">79068</a>.
+The implementation will be provided after 3.3M6.<br>
+<pre>
+	/**
+	 * FORMATTER / Option to wrap before the binary operator
+	 *     - option id:         "org.eclipse.jdt.core.formatter.wrap_before_binary_operator"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * This option is used only if the option {@link #FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION} is set.
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.3
+	 */
+	public static final String FORMATTER_WRAP_BEFORE_BINARY_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.wrap_before_binary_operator"; //$NON-NLS-1$
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154984">154984</a>
+Jars in library not recognized sometimes.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102473">102473</a>
+code assist: parameter names not harvested from debug info in class files
+
+<a name="v_742"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 18, 2007
+<br>Project org.eclipse.jdt.core v_742
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_742">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>As some clients need to know if some classpath container children attributes are supported or
+can be modifiable, the following API methods have been added in <code>org.eclipse.jdt.core.ClasspathContainerInitializer</code> class:
+<ul>
+<li><code>#getAccessRulesStatus(IPath, IJavaProject)</code></li>
+<li><code>#getAttributeStatus(IPath, IJavaProject, String)</code></li>
+<li><code>#getSourceAttachmentStatus(IPath, IJavaProject)</code></li>
+</ul>
+For each of these methods, the returned status can have one of the following severities:
+<ul>
+<li><code>IStatus#OK</code>: means that the attribute is supported <strong>and</strong> is modifiable</li>
+<li><code>IStatus#ERROR</code>: means that either the attribute is not supported or is not modifiable.<br>
+	In this case, the <code>IStatus#getCode()</code> will have respectively the <code>#ATTRIBUTE_NOT_SUPPORTED</code> value
+	or the <code>#ATTRIBUTE_READ_ONLY</code> value.</li>
+</ul>
+Note that if the subclass does not override this method, then the default behavior is
+to return <code>IStatus#OK</code> if and only if the classpath container can
+be updated (see <code>#canUpdateClasspathContainer(IPath, IJavaProject)</code>).
+</li>
+<li>API addition to fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130001">130001</a>. It is being able for a user
+to query what options were enabled when the DOM/AST tree has been created. The following API methods have been added:
+<ul>
+<li><code>org.eclipse.jdt.core.dom.AST#hasResolvedBindings()</code></li>
+<li><code>org.eclipse.jdt.core.dom.AST#hasStatementsRecovery()</code></li>
+<li><code>org.eclipse.jdt.core.dom.AST#hasBindingsRecovery()</code></li>
+</ul>
+</li>
+<li>API addition to fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149567">149567</a>. It is about
+the incomplete binding handling. The following API methods or fields have been added:
+<ul>
+<li><code>org.eclipse.jdt.core.dom.ASTParser#setBindingsRecovery(boolean)</code></li>
+<li><code>org.eclipse.jdt.core.dom.IBinding#isRecovered()</code></li>
+<li><code>org.eclipse.jdt.core.ICompilationUnit#reconcile(int, int, WorkingCopyOwner, IProgressMonitor)</code></li>
+<li><code>org.eclipse.jdt.core.ICompilationUnit#FORCE_PROBLEM_DETECTION</code></li>
+<li><code>org.eclipse.jdt.core.ICompilationUnit#ENABLE_STATEMENTS_RECOVERY</code></li>
+<li><code>org.eclipse.jdt.core.ICompilationUnit#ENABLE_BINDINGS_RECOVERY</code></li>
+</ul>
+</li>
+<li>The working copy owner (<code>WorkingCopyOwner</code>) now specifies the problem requestor
+(<code>IProblemrequestor</code>) used to report problems on working copies it owns 
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175243">175243</a>).<br>
+To implement this new responsibility, a new API method has been added on <code>WorkingCopyOwner</code> class:
+<pre>
+/**
+ * Returns the problem requestor used by a working copy of this working copy owner.
+ *
+ * By default, no problem requestor is configured. Clients can override this 
+ * method to provide a requestor.
+ * 
+ * @param workingCopy The problem requestor used for the given working copy.
+ * If <code>null</code>, then return the problem requestor used for all working 
+ * copies of the working copy owner.
+ * @return the problem requestor to be used by working copies of this working 
+ * copy owner or <code>null</code> if no problem requestor is configured.
+ * 
+ * @since 3.3
+ */
+public IProblemRequestor getProblemRequestor(ICompilationUnit workingCopy) {
+	return null;
+}
+</pre>
+As a consequence of this addition, <code>IProblemRequestor</code> parameter
+of <code>*WorkingCopy</code> methods becomes unnecessary and corresponding
+methods have been deprecated:
+<ol>
+<li><code>ICompilationUnit#becomeWorkingCopy(IProblemRequestor, IProgressMonitor)</code></li>
+<li><code>ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProblemRequestor, IProgressMonitor)</code></li>
+<li><code>IClassFile#becomeWorkingCopy(IProblemRequestor, WorkingCopyOwner, IProgressMonitor)</code></li>
+<li><code>WorkingCopyOwner#newWorkingCopy(String, IClasspathEntry[], IProblemRequestor, IProgressMonitor)</code></li>
+</ol>
+And are obviously replaced by following methods:
+<ol>
+<li><code>ICompilationUnit#becomeWorkingCopy(IProgressMonitor)</code></li>
+<li><code>ICompilationUnit#getWorkingCopy(WorkingCopyOwner, IProgressMonitor)</code></li>
+<li><code>IClassFile#becomeWorkingCopy(WorkingCopyOwner, IProgressMonitor)</code></li>
+<li><code>WorkingCopyOwner#newWorkingCopy(String, IClasspathEntry[], IProgressMonitor)</code></li>
+</ol>
+</li>
+<li>Added API org.eclipse.jdt.core.JavaCore#getGeneratedResources(IRegion, boolean) to be able to get the generated resources for all
+elements of a IRegion. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6584">6584</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177623">177623</a>
+[1.6][compiler] Stackmap frames generation should be protected against invalid code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177621">177621</a>
+XML log might be corrupted if an exception occurs while extracting problem context
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176725">176725</a>
+[recovery] member value array initializer aren;t correctly recovered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168077">168077</a>
+[classpath] Let classpath containers define what is configurable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177478">177478</a>
+[formatter] Indent new lines option adds extra empty lines
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130001">130001</a>
+[api][AST] org.eclipse.jdt.core.dom.AST: should have API hasResolvedBindings, hasStatementRecovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149567">149567</a>
+AST DCR: Allow incomplete variable bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177009">177009</a>
+[javadoc] Missing Javadoc tag not reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177319">177319</a>
+Annotation Processing (APT) affects eclipse speed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177194">177194</a>
+[1.5][compiler] preserveAllLocals option has undesirable side-effect when invoking generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177372">177372</a>
+[1.5][compiler] Missing unboxing conversion when no value required from message send
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176825">176825</a>
+FullSourceWorkspaceCompletionTests doesn't run correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177386">177386</a>
+Wording in Javadoc of TypeNameMatch and -Requestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177115">177115</a>
+NullPointerException in BindingKeyResolver.consumeTypeVariable(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175243">175243</a>
+[model] Let working copy owner control the problem requestor used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163733">163733</a>
+IncrementalImageBuilder.deleteGeneratedFiles() is broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=177079">177079</a>
+Add jdt.apt.pluggable.core as x-friend to jdt.core
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6584">6584</a>
+Need a way to get class files for a java file (or CU)
+
+<a name="v_741"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 13, 2007
+<br>Project org.eclipse.jdt.core v_741
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_741">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The non-Java resources in jar files returned by <code>IPackageFragmentRoot#getNonJavaResources()</code> and
+      <code>IPackageFragment#getNonJavaResources()</code> are now of type <code>IJarEntryResource</code> (a subinterface
+      of <code>IStorage</code>). This interface allows to navigate the tree of non-Java resources using the
+      <code>getChildren()</code> and <code>getParent()</code> methods.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176269">176269</a>
+[index] NullPointerException filtering for exception breakpoint
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176027">176027</a>
+[javadoc] {@link} to member type handled incorrectly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153044">153044</a>
+JarEntryFile does not return fully qualified path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170595">170595</a>
+[batch][compiler] BatchCompilerTest#test024 is no more significant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176971">176971</a>
+[assist] types are computed if TYPE_REF are filterred and JAVADOC_TYPE_REF aren't filtered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175987">175987</a>
+[1.5][compiler] Missing error when implementing a method with a mix of parameterized and raw generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148944">148944</a>
+need to render resource folders in JARs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176190">176190</a>
+[assist] Inferred variable names are not good when the declared type is a base type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176057">176057</a>
+IAE in ASTConverter for invalid source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174436">174436</a>
+API request: MethodInvocation/SuperMethodInvocation#isResolvedTypeInferredFromExpectedType()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176364">176364</a>
+[assist] missing return and continue proposals within switch statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161704">161704</a>
+[model] Improve progress for Java initialization task job
+
+<a name="v_740"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - March 6, 2007
+<br>Project org.eclipse.jdt.core v_740
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_740">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Refined the problem IDs and messages associated to null-related issues
+    detection, for which typical examples would now be:
+    <ul>
+      <li><code>NullLocalVariableReference</code> - Null pointer access: The variable o can only be null at this location</li>
+      <li><code>PotentialNullLocalVariableReference</code> - Potential null pointer access: The variable o may be null at this location</li>
+      <li><code>RedundantNullCheckOnNullLocalVariable</code> - Redundant null check: The variable o can only be null at this location</li>
+      <li><code>NullLocalVariableComparisonYieldsFalse</code> - Null comparison always yields false: The variable x can only be null at this location</li>
+      <li><code>RedundantLocalVariableNullAssignment</code> - Redundant assignment: The variable x can only be null at this location</li>
+      <li><code>NullLocalVariableInstanceofYieldsFalse</code> - instanceof always yields false: The variable o can only be null at this location</li>
+      <li><code>RedundantNullCheckOnNonNullLocalVariable</code> - Redundant null check: The variable o2 cannot be null at this location</li>
+      <li><code>NonNullLocalVariableComparisonYieldsFalse</code> - Null comparison always yields false: The variable i cannot be null at this location</li>
+    </ul>
+    Note that problem IDs <code>LocalVariableCannotBeNull</code>,
+    <code>LocalVariableCanOnlyBeNull</code>, and
+    <code>LocalVariableMayBeNull</code> have been deprecated.<br>
+    See bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175570">175570</a>
+    and <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175571">175571</a>
+    for details.
+</li>
+<li>The API method <code>IClassFile#getType()</code> does not longer throw <code>JavaModelException</code>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154667">154667</a>).</li>
+<li>Code Assist: unresolved simple names are proposed when completing a simple name reference<br>
+<pre>
+package test;
+public class E1 {
+        void m() {
+                variable = 10;
+                System.out.println(v); // do completion after 'v'
+        }
+}
+</pre>
+When <i>v</i> is completed, <i>variable</i> is proposed as a possible local variable which are not yet declared.<br>
+Unresolved simple names are searched before and after the completion location.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174588">174588</a>
+[compiler] Code in abstract class calls wrong overloaded method. Correct method is defined in the implemented interface.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176321">176321</a>
+Test failures in MethodParameterGuessingCompletionTest
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176361">176361</a>
+[search] TypeNameMatchRequestorWrapper creates invalid handle for member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176358">176358</a>
+[search] Failure in JavaSearchBugsTest while running random tests order
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147461">147461</a>
+[compiler][batch][options] tighten the use of : and ; within access restriction specifications
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162865">162865</a>
+Content assist for undeclared locals when using local
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154667">154667</a>
+IClassFile#getType() should not throw JavaModelException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175571">175571</a>
+[compiler][null] Better compiler message for 'Redundant null check'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175570">175570</a>
+[compiler][null] Improve compiler message for 'Null reference'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175849">175849</a>
+Project is touched on restart
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175832">175832</a>
+[recovery] $missing$ should not be shown inside a message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175834">175834</a>
+[assist] already defined name is proposed as variable name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175531">175531</a>
+Livelock in OverflowingLRUCache.privateRemoveEntry
+
+<a name="v_739"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - 27th February 2007
+<br>Project org.eclipse.jdt.core v_739
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_739">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Refined the options that control null-related issues detection. The existing
+<code>nullReference</code> option has been repurposed and split into three
+options:
+<pre>
+COMPILER / Reporting Null Dereference
+   When enabled, the compiler will issue an error or a warning whenever a
+   variable that is statically known to hold a null value is used to
+   access a field or method.
+    - option id:         "org.eclipse.jdt.core.compiler.problem.nullReference"
+    - possible values:   { "error", "warning", "ignore" }
+    - default:           "ignore"
+COMPILER / Reporting Potential Null Dereference
+   When enabled, the compiler will issue an error or a warning whenever a
+   variable that has formerly been tested against null but is not (no more)
+   statically known to hold a non-null value is used to access a field or
+   method.
+    - option id:         "org.eclipse.jdt.core.compiler.problem.potentialNullReference"
+    - possible values:   { "error", "warning", "ignore" }
+    - default:           "ignore"
+COMPILER / Reporting Redundant Null Check
+   When enabled, the compiler will issue an error or a warning whenever a
+   variable that is statically known to hold a null or a non-null value
+   is tested against null.
+    - option id:         "org.eclipse.jdt.core.compiler.problem.redundantNullCheck"
+    - possible values:   { "error", "warning", "ignore" }
+    - default:           "ignore"
+</pre>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170704">170704</a>
+for details.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170704">170704</a>
+[compiler][null][enh] separate "null dereference" and "null reference" compiler options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172666">172666</a>
+Importing pde.ui and dependencies as binary gives compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174971">174971</a>
+[index] Many exceptions from background indexer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172913">172913</a>
+[compiler][1.5] an extra checkcast bytecode instruction generated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174879">174879</a>
+[1.5][compiler] Optimisation for empty if blocks results in not evaluating the test expression
+
+<a name="v_738"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - 21st February 2007
+<br>Project org.eclipse.jdt.core v_738
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_738">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=171802">171802</a>
+[javadoc][select] F3 does not work on method which have deprecated type as argument
+
+<a name="v_737"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - 20th February 2007
+<br>Project org.eclipse.jdt.core v_737
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_737">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>API added on <code>org.eclipse.jdt.core.IClassFile</code>:
+<pre>
+/**
+ * Returns the bytes contained in this class file.
+ *
+ * @return the bytes contained in this class file
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @since 3.3
+ */
+byte[] getBytes() throws JavaModelException;
+</pre>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150244">150244</a> for details.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171653">171653</a>
+[index] Java Tooling initialization performance issue after startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174348">174348</a>
+[classpath] Classpath validation messages are non-standard
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172345">172345</a>
+[model][delta] path error markers are not regenerated on project rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97199">97199</a>
+[formatting] Code formatting activation in comments (using &lt;PRE&gt;) is case sensitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150244">150244</a>
+[API] Add getBytes() on IClassFile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174434">174434</a>
+[1.5][compiler] Parameterized constructor leads to Internal Errror
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152850">152850</a>
+[formatter] Formatter marks unchanged file dirty
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104371">104371</a>
+[JDOM] JDOM should not crash on 1.5 code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168910">168910</a>
+Should default compliance be 6.0 in JSR199 batch compilation?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167317">167317</a>
+ecjsrc.zip should contain a build system
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173992">173992</a>
+Duplicate local variable  for exception in different catch blocks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174298">174298</a>
+Wrong NAME_PROPERTY child type for AnnotationTypeDeclaration and EnumDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174002">174002</a>
+[assist] Exceptions which are already covered by the another exception are proposed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174001">174001</a>
+[assist] Unexpected types are proposed inside catch block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149154">149154</a>
+BinaryMethod#getParameterNames() should not try to extract from attached javadoc for synthetics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=174131">174131</a>
+[assist] Result of test CompletionTests#testCompletionInsideExtends10 is wrong
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=34373">34373</a>
+Class file view doesn't show actual modifiers for member types
+
+<a name="v_736"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M6 - 13th February 2007
+<br>Project org.eclipse.jdt.core v_736
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_736">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=158039">158039</a>
+[ast rewrite] ArrayIndexOutOfBoundsException when rewriting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173907">173907</a>
+[code assist] severe NPE on exception completions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173800">173800</a>
+[compiler] suboptimal line number attributes for cascading field accesses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173849">173849</a>
+ITypeBinding#getJavaElement() fails for array of inner type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173853">173853</a>
+[recovery] Recovery add an unnecessary default contructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173013">173013</a>
+[assist] NPE while completing in catch formal parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142234">142234</a>
+problem range includes parenthesis for warning on expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=107001">107001</a>
+ITypeBinding#getBinaryName() returns java.lang.Object for type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156307">156307</a>
+JavaElement.getURLContents() hack breaks &quot;Open External Javadoc&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111529">111529</a>
+npe trying to get ITypeBinding for parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144742">144742</a>
+Setting the bootclasspath for some VMs fails the evaluation tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172743">172743</a>
+[jsr269] APT needs to convert IFile into internal ICompilationUnit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138897">138897</a>
+Error ranges for unreachable code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172848">172848</a>
+[formatter] code formatter produces syntax error (unary operator+ followed by prefix increment operator++)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173376">173376</a>
+[jsr269] Multiple annotations on class, only first is resolved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173416">173416</a>
+[compiler][batch][options] ecj doesn't support classpath entry starting with [
+
+<a name="v_735"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 8th February 2007 - 3.3 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_735
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_735">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=172633">172633</a>
+NPEs while starting my workspace
+
+<a name="v_734"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 3rd February 2007
+<br>Project org.eclipse.jdt.core v_734
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_734">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New extension point has been added to register an annotation processor manager inside the Java Builder.
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172369">172369</a> for details.</li>
+<li>In order to fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49412">49412</a>, the following constants have been deprecated:
+<ul>
+<li>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES</li>
+<li>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT</li>
+</ul>
+They have been replaced by these constants respectively:
+<ul>
+<li>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT<br>
+org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT</li>
+<li>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT<br>
+org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT<br>
+org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172648">172648</a>
+[model] Some inconsistencies while adding listeners to DeltaProcessingState
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49412">49412</a>
+[formatting] Offer comment formatting options per comment type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161996">161996</a>
+[compiler][batch][options] ecj can't cope with [] brackets in classpath names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172444">172444</a>
+build workspace operation launched after each startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172028">172028</a>
+[clean up] Sort members clean up leaks working copies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172369">172369</a>
+Adding an extension point to register an annotation processor inside the java builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172189">172189</a>
+[1.5][compiler] NPE in CompilationUnitProblemFinder.process with explicit wildcard invocation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172207">172207</a>
+[model] Marker for deprecated classpath variable should always have WARNING severity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=172328">172328</a>
+Javadoc for SearchEngine.searchAllTypeNames(..) has wrong @param ordering
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171684">171684</a>
+Replace references to IMarker.GENERATED_BY with IMarker.SOURCE_ID
+
+<a name="v_733"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 30th January 2007
+<br>Project org.eclipse.jdt.core v_733
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_733">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added in <code>org.eclipse.jdt.core.compiler.CharOperation</code>:<br>
+<pre>
+/**
+ * Compares the two char arrays lexicographically.
+ *
+ * Returns a negative integer if array1 lexicographically precedes the array2,
+ * a positive integer if this array1 lexicographically follows the array2, or
+ * zero if both arrays are equal.
+ *
+ * @param array1 the first array
+ * @param array2 the second array
+ * @return the returned value of the comparison between array1 and array2
+ * @throws NullPointerException if one of the arrays is null
+ * @since 3.3
+ */
+public static final int compareTo(char[] array1, char[] array2)
+</pre>
+</li>
+<li>New API added in <code>org.eclipse.jdt.core.util.CompilationUnitSorter</code>:<br>
+<pre>	/**
+	 * Reorders the declarations in the given compilation unit according to the
+	 * specified comparator. The caller is responsible for arranging in advance
+	 * that the given compilation unit is a working copy, and for applying the
+	 * returned TextEdit afterwards.
+	 *
+	 * <b>Note:</b> Reordering the members within a type declaration might be
+	 * more than a cosmetic change and could have potentially serious
+	 * repercussions. Firstly, the order in which the fields of a type are
+	 * initialized is significant in the Java language; reordering fields and
+	 * initializers may result in compilation errors or change the execution
+	 * behavior of the code. Secondly, reordering a class's members may affect
+	 * how its instances are serialized. This operation should therefore be used
+	 * with caution and due concern for potential negative side effects.
+	 *
+	 *
+	 * The <code>compare</code> method of the given comparator is passed pairs
+	 * of body declarations (subclasses of <code>BodyDeclaration</code>)
+	 * representing body declarations at the same level. The nodes are from an
+	 * AST of the specified level ({@link org.eclipse.jdt.core.dom.ASTParser#newParser(int)}.
+	 * Clients will generally use AST.JLS3 since that will cover all
+	 * constructs found in Java 1.0, 1.1, 1.2, 1.3, 1.4, and 1.5 source code.
+	 * The comparator is called on body declarations of nested classes,
+	 * including anonymous and local classes, but always at the same level.
+	 * Clients need to provide a comparator implementation (there is no standard
+	 * comparator). The <code>RELATIVE_ORDER</code> property attached to these
+	 * AST nodes affords the comparator a way to preserve the original relative
+	 * order.
+	 *
+	 *
+	 * The body declarations passed as parameters to the comparator always carry
+	 * at least the following minimal signature information:
+	 *
+	 *
+	 * <code>TypeDeclaration</code>
+	 * <code>modifiers, isInterface, name, superclass,
+	 *        superInterfaces, typeParameters
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>FieldDeclaration</code>
+	 * <code>modifiers, type, fragments
+	 *        (VariableDeclarationFragments
+	 *        with name only)
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>MethodDeclaration</code>
+	 * <code>modifiers, isConstructor, returnType, name,
+	 *        typeParameters, parameters
+	 *        (SingleVariableDeclarations with name, type, and modifiers only),
+	 *        thrownExceptions
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>Initializer</code>
+	 * <code>modifiers
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>AnnotationTypeDeclaration</code>
+	 * <code>modifiers, name
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>AnnotationTypeMemberDeclaration</code>
+	 * <code>modifiers, name, type, default
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>EnumDeclaration</code>
+	 * <code>modifiers, name, superInterfaces
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * <code>EnumConstantDeclaration</code>
+	 * <code>modifiers, name, arguments
+	 *        RELATIVE_ORDER property</code>
+	 *
+	 * Clients should not rely on the AST nodes being properly parented
+	 * or on having source range information. (Future releases may provide
+	 * options for requesting additional information like source positions, full
+	 * ASTs, non-recursive sorting, etc.)
+	 *
+	 * @param unit
+	 *            the CompilationUnit to sort
+	 * @param comparator
+	 *            the comparator capable of ordering
+	 *            <code>BodyDeclaration</code>s; this comparator is passed
+	 *            AST nodes from an AST of the specified AST level
+	 * @param options
+	 *            bitwise-or of option flags; <code>0</code> for default
+	 *            behavior (reserved for future growth)
+	 * @param group
+	 *            the text edit group to use when generating text edits, or <code>null</code>
+	 * @param monitor
+	 *            the progress monitor to notify, or <code>null</code> if none
+	 * @return a TextEdit describing the required edits to do the sort, or <code>null</code>
+	 *            if sorting is not required
+	 * @exception JavaModelException
+	 *                if the compilation unit could not be sorted. Reasons
+	 *                include:
+	 *                - The given compilation unit does not exist
+	 *                (ELEMENT_DOES_NOT_EXIST)
+	 *                - The given compilation unit is not a working copy
+	 *                (INVALID_ELEMENT_TYPES)
+	 *                - A <code>CoreException</code> occurred while
+	 *                accessing the underlying resource
+	 *                - The given compilation unit doesn't come from an ICompilationUnit and this ICompilationUnit is
+	 *                not a working copy (NO_ELEMENTS_TO_PROCESS)
+	 * @exception IllegalArgumentException
+	 *                if the given compilation unit is null or if the given
+	 *                comparator is null, or if <code>options</code> is not one
+	 *                of the supported levels.
+	 * @see org.eclipse.jdt.core.dom.BodyDeclaration
+	 * @see #RELATIVE_ORDER
+	 * @since 3.3
+	 */
+	 public static TextEdit sort(CompilationUnit unit,
+			Comparator comparator,
+			int options,
+			TextEditGroup group,
+			IProgressMonitor monitor) throws JavaModelException;</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166354">166354</a>
+[1.5][compiler] extraneous error caused by a non visible method of an inherited
+class taking precedence over a visible method of an enclosing class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167190">167190</a>
+[search] TypeNameMatchRequestorWrapper causing ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141830">141830</a>
+[1.3][compiler] Severe runtime errors with anonymous classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171634">171634</a>
+[formatter] doesn't add line feed at end of file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171472">171472</a>
+[1.6][compiler] Illegal stack map frames
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163590">163590</a>
+[1.5][compiler] Incompatible type bounds message points to the generic type instead of its type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171771">171771</a>
+[assist] JAVADOC_TYPE_REF aren't correctly filtered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171184">171184</a>
+[compiler] Java compiler does not generate InnerClass attribute as per JVMS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=173279">173279</a>
+[indexing] Category table is not cached for rt.jar since 1.5 version
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138309">138309</a>
+[index] Optimize index files path storage in DiskIndex and IndexManager
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166570">166570</a>
+[assist] Proposal computer from the 'org.eclipse.mylar.java' plug-in did not complete normally
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162073">162073</a>
+[compiler] extraneous interface compatibility error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171066">171066</a>
+Provide TextEdit when sorting compilation unit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170318">170318</a>
+[1.5][compiler] improve message on nameclash when overriding method with "wildcard" parameter
+
+<a name="v_732"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 23rd January 2007
+<br>Project org.eclipse.jdt.core v_732
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_732">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Code Assist: Exception thrown in a try block are more relevant if the completion occurs in a catch clause.
+Already caught exceptions are filtered.
+<pre>
+public class X {
+  void foo() throws XAException, XBException {}
+  void bar() {
+    try {
+    	foo();
+    } catch(XAException e) {
+    } catch(X| //do ctrl + space at |
+  }
+</pre>
+In this example XBException will more relevant than XCException and XAException won't be proposed.
+</li>
+<li>Classpath variable may now be flagged as deprecated or read-only (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138599">138599</a>
+and bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156226">156226</a>).<br>
+Two new attributes have been added on <code>ClasspathVariableInitializer</code> schema:
+<pre>
+   &lt;element name="classpathVariableInitializer"&gt;
+      &lt;complexType&gt;
+         ...
+         &lt;attribute name="deprecated" type="string"&gt;
+            &lt;annotation&gt;
+               &lt;documentation&gt;
+                  String explaining the reason why the associated variable is deprecated
+               &lt;/documentation&gt;
+               &lt;appInfo&gt;
+                  &lt;meta.attribute translatable="true"/&gt;
+               &lt;/appInfo&gt;
+            &lt;/annotation&gt;
+         &lt;/attribute&gt;
+         &lt;attribute name="readOnly" type="boolean"&gt;
+            &lt;annotation&gt;
+               &lt;documentation&gt;
+                  Indicates that the associated variable cannot be modified
+               &lt;/documentation&gt;
+            &lt;/annotation&gt;
+         &lt;/attribute&gt;
+      &lt;/complexType&gt;
+   &lt;/element&gt;
+</pre>
+When deprecated attribute is set on ClasspathVariableInitializer extension point, classpath entry validation
+returns a warning status if no other error was previously detected.
+<br>
+For example, following <code> classpathVariableInitializer</code> extension point set
+the <code>TEST</code> classpath variable as deprecated and read-only:
+<pre>
+   &lt;extension
+         point="org.eclipse.jdt.core.classpathVariableInitializer"&gt;
+      &lt;classpathVariableInitializer
+            class="org.eclipse.jdt.tests.model.TestInitializer"
+            deprecated="The reason why this variable is deprecated"
+            readOnly="true"
+            variable="TEST"&gt;
+      &lt;/classpathVariableInitializer&gt;
+   &lt;/extension&gt;
+</pre>
+Calling <code>JavaConventions.validateClasspathEntry(IJavaProject, IClasspathEntry, boolean)</code>
+method on this variable entry will return a <code>IStatus.WARNING</code> status with following message:
+.
+<br>
+Classpath variable deprecation message and read-only information are accessible using two new added
+<code>JavaCore</code> API methods:
+<pre>
+/**
+ * Returns deprecation message of a given classpath variable.
+ *
+ * @param variableName
+ * @return A string if the classpath variable is deprecated, <code>null</code> otherwise.
+ * @since 3.3
+ */
+public static String getClasspathVariableDeprecationMessage(String variableName)
+
+/**
+ * Returns whether a given classpath variable is read-only or not.
+ *
+ * @param variableName
+ * @return <code>true</code> if the classpath variable is read-only,
+ * 	<code>false</code> otherwise.
+ * @since 3.3
+ */
+public static boolean isClasspathVariableReadOnly(String variableName)
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169017">169017</a>
+[1.6][compiler] VerifyError: Inconsistent stackmap frames
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156226">156226</a>
+[model][classpath] Allow classpath variable to be marked as non modifiable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138599">138599</a>
+[model][classpath] Need a way to mark a classpath variable as deprecated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157584">157584</a>
+[content assist] There is no content assist for catching exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171016">171016</a>
+[javadoc][assist] No completion for tag when uppercase is used
+
+
+<a name="v_731"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 16th January 2007
+<br>Project org.eclipse.jdt.core v_731
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_731">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The compiler can now detect unused local types (as opposed to only private types up until now). </li>
+<li>The compiler is now better able to detect unused private constructors, it now tolerates more than the
+private constructor with no parameter as the known pattern for blocking instantiation. Basically, unless a
+non private constructor is defined as well, it will ignore unused private constructors from now on (also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163443">163443</a>).</li>
+<li>Code Assist can propose import statements:
+<pre>
+public class CompletionProposal {
+	...
+	/**
+	 * Completion is an import of reference to a static field.
+	 * &lt;p&gt;
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * &lt;ul&gt;
+	 * &lt;li&gt;{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the field that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getFlags()} -
+	 * the modifiers flags (including ACC_ENUM) of the field that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getName()} -
+	 * the simple name of the field that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getSignature()} -
+	 * the type signature of the field's type (as opposed to the
+	 * signature of the type in which the referenced field
+	 * is declared)
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int FIELD_IMPORT;
+
+	/**
+	 * Completion is an import of reference to a static method.
+	 * &lt;p&gt;
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * &lt;ul&gt;
+	 * &lt;li&gt;{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the method that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getFlags()} -
+	 * the modifiers flags of the method that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getName()} -
+	 * the simple name of the method that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getSignature()} -
+	 * the method signature of the method that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int METHOD_IMPORT;
+
+	/**
+	 * Completion is an import of reference to a type.
+	 * Only reference to reference types are allowed.
+	 * &lt;p&gt;
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * &lt;ul&gt;
+	 * &lt;li&gt;{@link #getDeclarationSignature()} -
+	 * the dot-based package name of the package that contains
+	 * the type that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getSignature()} -
+	 * the type signature of the type that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getFlags()} -
+	 * the modifiers flags (including Flags.AccInterface, AccEnum,
+	 * and AccAnnotation) of the type that is imported
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getAdditionalFlags()} -
+	 * the completion flags (including ComletionFlags.StaticImport)
+	 * of the proposed import
+	 * &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 *
+	 * @see #getKind()
+	 *
+	 * @since 3.3
+	 */
+	public static final int TYPE_IMPORT;
+	...
+}
+</pre></li>
+<li>Code Assist propose completions computed from a list a favorite references.
+<pre>
+public class CompletionRequestor {
+	...
+	/**
+	 * Returns the favorite references which are used to compute some completion proposals.
+	 * &lt;p&gt;
+	 * A favorite reference is a qualified reference as it can be seen in an import statement.&lt;br&gt;
+	 * e.g. &lt;code&gt;{"java.util.Arrays"}&lt;/code&gt;&lt;br&gt;
+	 * It can be an on demand reference.&lt;br&gt;
+	 * e.g. &lt;code&gt;{"java.util.Arrays.*"}&lt;/code&gt;
+	 * It can be a reference to a static method or field (as in a static import)&lt;br&gt;
+	 * e.g. &lt;code&gt;{"java.util.Arrays.equals"}&lt;/code&gt;
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * Currently only on demand type references (&lt;code&gt;"java.util.Arrays.*"&lt;/code&gt;),
+	 * references to a static method or a static field are used to compute completion proposals.
+	 * Other kind of reference could be used in the future.
+	 * &lt;/p&gt;
+	 * @return favorite imports
+	 *
+	 * @since 3.3
+	 */
+	public String[] getFavoriteReferences() {...}
+
+	/**
+	 * Set the favorite references which will be used to compute some completion proposals.
+	 * A favorite reference is a qualified reference as it can be seen in an import statement.&lt;br&gt;
+	 *
+	 * @param favoriteImports
+	 *
+	 * @see #getFavoriteReferences()
+	 *
+	 * @since 3.3
+	 */
+	public void setFavoriteReferences(String[] favoriteImports) {...}
+	...
+}
+</pre>
+With the following example if the favorite reference is <b>"java.util.Arrays.*"</b> then a proposal
+will be the method <b>"sort()"</b> with a required proposal of a static import <b>"import static java.util.Arrays.sort;"</b>.
+If the completion level is lesser than 1.5 the proposal will be <b>"Arrays.sort()"</b> with a required proposal of an import
+<b>"import java.util.Arrays;"</b>.
+<p>
+The option <code>JavaCore.CODEASSIST_SUGGEST_STATIC_IMPORTS</code> can be disabled to avoid to propose static import
+even if compliance is 1.5 or greater.
+</p>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168331">168331</a>
+[1.5][compiler] AbstractMethodError on interface method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170181">170181</a>
+[compiler] Could diagnose unused local types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144044">144044</a>
+[search] NPE when trying to find references to field variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152123">152123</a>
+[1.5][assist] Code assist for references that require static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170247">170247</a>
+[model] Document reasons to use or not use CompilationParticipant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140340">140340</a>
+[5.0][templates] foreach template does not work when an Iterable over a static inner class exists
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163443">163443</a>
+[clean up] private constructor with parameter flagged as unnecessary
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152961">152961</a>
+[compiler] Private inner interface is "never used locally"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157035">157035</a>
+&quot;Open Type Hierarchy&quot; fails if subtype is anonymous or local class and location for this subtype contains &quot;.class&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167488">167488</a>
+[compiler] Fup of bug 165291, the two warnings (assignment has no effect) should not be reported
+
+
+<a name="v_730"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 9th January 2007
+<br>Project org.eclipse.jdt.core v_730
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_730">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The grammar file java_1_5.g is renamed java.g.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162478">162478</a>
+NPE in MethodBinding#signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169744">169744</a>
+[AST] character position range wrong for super method call with type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162991">162991</a>
+[1.5][compiler] Name clash reported for (correct) eclipse-generated code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157336">157336</a>
+build output contains unnecessary empty directories
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157019">157019</a>
+[build] incremental build involving a resource filter fails to produce expected subdirectory of the output folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99738">99738</a>
+[formatting] each format shifts code inside &lt;pre&gt; one space to the right
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169596">169596</a>
+anewarray not propertly supported in 1.6
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169545">169545</a>
+java_1_4.g should be removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168665">168665</a>
+[1.6][compiler] AIOOBE during stack map frame generation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160550">160550</a>
+Infinite build when projects have cycle and build path errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114349">114349</a>
+[compiler] Problems building cyclical projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161541">161541</a>
+[compiler][1.5] eclipse fails to compile when two methods are joined to one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166977">166977</a>
+[vista] Unexpected errors while running JDT/Core tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168671">168671</a>
+[model] Model tests should not run read-only tests when file system does not support it
+
+<a name="v_729"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 19th December 2006
+<br>Project org.eclipse.jdt.core v_729
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_729">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=168610">168610</a>
+Chkpii error in build I20061218-0800
+
+<a name="v_728"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M5 - 19th December 2006
+<br>Project org.eclipse.jdt.core v_728
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_728">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=167743">167743</a>
+[search] Open Type Dialog cannot find types from projects migrated from 3.2.1 workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168088">168088</a>
+SourceTypeConverter NPE in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160773">160773</a>
+[jsr269] Need interfaces between jdt compiler and jsr269 impl
+
+
+<a name="v_727"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 9th December 2006 - 3.3 MILESTONE 4
+<br>Project org.eclipse.jdt.core v_727
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_727">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+  <li>IMarker-s generated by JDT and compiler participants may now have their
+      IMarker#GENERATED_BY attribute set according to the following rules:
+      <ul>
+        <li>IMarker-s generated by JDT get JavaBuilder#GENERATED_BY, currently
+            valued to JDT, as their GENERATED_BY attribute; <em>that value is
+            non API and may change in future releases</em>;</li>
+        <li>IMarker-s originating from compiler participants' categorized
+            problems which do not have the IMarker#GENERATED_BY extra attribute
+            set do not have their GENERATED_BY attribute set;</li>
+        <li>IMarker-s originating from compiler participants' categorized
+            problems which have the IMarker#GENERATED_BY set to a given value
+            get their GENERATED_BY attribute set to the said value.</li>
+      </ul>
+      See also bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158611">158611</a>.
+  </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167217">167217</a>
+[1.5][compiler] ClassCastException during annotation code generation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165900">165900</a>
+[select] Incoherent behavior when there is ambiguous methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166570">166570</a>
+[assist] Proposal computer from the 'org.eclipse.mylar.java' plug-in did not complete normally
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158611">158611</a>
+Set 'generatedBy' attribute of IMarker anywhere markers are generated in JDT/Core code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166348">166348</a>
+[search] Stack trace console resolves wrong source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164792">164792</a>
+CodeAssist should treat #clone() special in 1.5 mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154111">154111</a>
+Compiler API (JSR 199)
+
+<a name="v_726"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 5th December 2006
+<br>Project org.eclipse.jdt.core v_726
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_726">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=166641">166641</a>
+[compiler] uninitialized variable not reported in if (false) block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140191">140191</a>
+NPE in ClassFileReader.getSourceName logs full CU source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166436">166436</a>
+[javadoc] Potentially wrong javadoc warning for unexpected duplicate tag @value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166365">166365</a>
+[javadoc] severity level of malformed javadoc comments did not work properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=166077">166077</a>
+[compiler] extraneous tests in Scope#findExactMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165976">165976</a>
+ECJ Ant adapter doesn't allow setting empty bootclasspath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142205">142205</a>
+[batch][options] -deprecation option is not on by default, whereas the help message says so
+
+<a name="v_725"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 28th November 2006
+<br>Project org.eclipse.jdt.core v_725
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_725">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added <code>org.eclipse.jdt.core.JavaCore#VERSION_1_7</code>. It can be used to set the compliance, the source or the
+target platform values. This has no impact right now beside setting the major version inside .class file to
+<code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants#MAJOR_VERSION_1_7</code>.</li>
+<li>Added new API <code>org.eclipse.jdt.core.JavaCore#setComplianceOptions(String, Map)</code> to set the compiler's
+options relative to a given compiler's compliance.</li>
+<li>Tuned compiler semantics for unchecked cast detection. As a consequence, more warnings should be issued
+(also see bugs <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106451">106451</a> and
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165143">165143</a>). </li>
+<li>Raw type warnings are now also diagnosed for cast types. </li>
+<li>Improved compiler diagnosis for type hiding to now report: member type hiding type parameters,
+nested types hiding other accessible types in scope (direct enclosing are already reported as errors). </li>
+<li>Compiler is now more resilient with duplicate local type declarations; thus allowing further
+operation to still be carried out accurately (codeselect, completion, search, DOM AST ops)
+(cf. bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165662">165662</a>).</li>
+<li>New Java Model element interface has been added as common supertype for <code>ICompilationUnit</code> and <code>IClassFile</code>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125504">125504</a>).
+<pre>
+/**
+ * Represents an entire Java type root (either an <code>ICompilationUnit</code>
+ * or an <code>IClassFile</code>).
+ *
+ * This interface is not intended to be implemented by clients.
+ *
+ * @see ICompilationUnit
+ * @see IClassFile
+ * @since 3.3
+ */
+public interface ITypeRoot extends IJavaElement, IParent, IOpenable, ISourceReference, ICodeAssist {
+...
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165917">165917</a>
+Error range for IProblem.IncompatibleReturnType should be predictable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165620">165620</a>
+Regression in 3.3M3 with generics - ambiguous method.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163370">163370</a>
+[1.5][compiler] Incorrect ambiguous method error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165794">165794</a>
+[javadoc] Should not report ambiguous on method with parameterized types as parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165701">165701</a>
+[model] NPE while computing method unique key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142219">142219</a>
+[batch][options] inconsistent help message: -X&lt;option&gt; vs -Xemacs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160520">160520</a>
+[compiler] Should better locate overriding return type conflict onto return type reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125504">125504</a>
+[API] common supertype for ICompilationUnit and IClassFile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165525">165525</a>
+[comments] ASTParser excludes trailing line comments from extended range of fields in enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165654">165654</a>
+[ast rewrite] add final to parameter does not work with annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161980">161980</a>
+Make some member class static
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161975">161975</a>
+Should factorized all empty strings constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163680">163680</a>
+[1.5] [compiler] JDT Internal Exception under import circularity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165645">165645</a>
+[1.5][compiler] Member type should take precedence over enclosing type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165662">165662</a>
+[compiler] Be more resilient with duplicate local types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161617">161617</a>
+[ast rewrite] replacing InstanceofExpression.LEFT_OPERAND_PROPERTY should ensure whitespace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165291">165291</a>
+[1.5] Missing diagnosis for illegal forward field ref in generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165453">165453</a>
+[1.5][compiler] Improve unchecked cast message in compiler's warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165145">165145</a>
+[1.5][compiler] Missing raw type warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106451">106451</a>
+[1.5][compiler] Error and unchecked warnings missing for cast to parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165143">165143</a>
+[1.5][compiler] Missing unchecked cast warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165346">165346</a>
+[compiler][null] org.eclipse.jdt.internal.compiler.ast.OperatorExpression.nullStatus(FlowInfo) too conservative
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149118">149118</a>
+[batch] shorten the error message in case a .java directory is used as a parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156339">156339</a>
+Abort compilation surfaces through the UI
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164657">164657</a>
+[compiler] Wrong line is showed during debug
+
+<a name="v_724"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 21st November 2006
+<br>Project org.eclipse.jdt.core v_724
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_724">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BLANK_LINES_BETWEEN_IMPORT_GROUPS</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164946">165210</a> for details.</li>
+<li>Added <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_SPACE_BEFORE_PARENTHESIZED_EXPRESSION_IN_THROW</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164946">164946</a> for details.</li>
+<li>javadoc checker now correctly allow usage of {@value} tags only on field declaration when source level is less than 1.5
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153399">153399</a>).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164707">164707</a>
+ArrayIndexOutOfBoundsException in JavaModelManager if source level == 6.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165210">165210</a>
+Fup of bug 74997, add new formatter option for number of blank lines between import groups
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165069">165069</a>
+[1.5][compiler] incorrect field hiding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165081">165081</a>
+[1.5][compiler] Fup of bug 165069, unused imports are not reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154993">154993</a>
+org.eclipse.jdt.ui.JavaNoTypeCompletionProposalComputer throws a runtime exception when using content assist on 'this.' in annontations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139621">139621</a>
+[javadoc][assist] No Javadoc completions if there's no member below
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164946">164946</a>
+Spaces in control statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163807">163807</a>
+JDT fails to compile legal Java source files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153399">153399</a>
+[javadoc] JDT Core should warn if the @value tag is not used correctly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84049">84049</a>
+[javadoc][dom] Extended ranges wrong for method name without return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164791">164791</a>
+[search] Type reference reports anonymous type in invalid class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164450">164450</a>
+[comments] DefaultCommentMapper should release scanner after use
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163984">163984</a>
+[search] no results from SearchEngine.searchAllTypeNames with types in scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74997">74997</a>
+import rewrite: no empty line between groups
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164311">164311</a>
+Code completion unavailable for static methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156352">156352</a>
+NPE when accessing annotations from ITypeBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99928">99928</a>
+ContentAssist should propose methods of intersection types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157570">157570</a>
+Bug in ASTParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164656">164656</a>
+IScanner.setSource should spec that 'null' is allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160637">160637</a>
+getKey(...) for BinaryMethod returns a key with '.' in the return type instead of '/'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=110771">110771</a>
+align all ICompilationUnit#getContents implementations on a 'never null' behavior
+
+<a name="v_723"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 14th November 2006
+<br>Project org.eclipse.jdt.core v_723
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_723">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>javadoc checker did incorrectly allow compatible matches for method references; where only exact matches are mandated
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163659">163659</a>).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=140980">140980</a>
+[recovery] ClassCastException from JDT compiler
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=162918">162918</a>
+[compiler] Illegal usage of a local inside a switch statement is not rejected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164121">164121</a>
+[search] Misses declarations of method parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164081">164081</a>
+XML log could contain package information
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160301">160301</a>
+[search] too many matches found for method references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163659">163659</a>
+[javadoc] Compiler should warn when method parameters are not identical
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164092">164092</a>
+[model] Possible NullPointerException in org.eclipse.jdt.internal.core.Buffer.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164091">164091</a>
+[model] Possible NullPointerException in JavaProjectElementInfo.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159939">159939</a>
+[1.5][compiler] Eclipse allows List&lt;void[]&gt;, javac doesn't
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162621">162621</a>
+[model][delta] Validation errors do not clear after replacing jar file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163782">163782</a>
+Possible resource leaks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162026">162026</a>
+[1.5][compiler] Erroneous Report of an Ambiguous Method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163600">163600</a>
+[compiler] Internal references to static inner classes fail in presence of assert keyword
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149004">149004</a>
+static fields from package classes wrong quick-fix'ed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101476">101476</a>
+&quot;Serializable class without serialVersionUID&quot; setting and writeReplace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163647">163647</a>
+[model] Thrown exceptions are not found in method binding key which have a capture as declaring class
+
+<a name="v_722"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M4 - 7th November 2006
+<br>Project org.eclipse.jdt.core v_722
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_722">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li><code>JavaConventions</code> can now validate names using specific source and compliance levels. New <code>validate*Name</code> API methods
+with the source and the compliance level as given parameters have been added to this class. Clients should now use these new methods instead
+of deprecated ones which only verify names using the 1.3 default level.
+</li>
+<li>Added new API method on <code>org.eclipse.jdt.core.BindingKey</code> class to get the exceptions thrown by a method
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155003">155003</a>):
+<pre>
+	/**
+	 * Returns the thrown exception signatures of the element represented by this binding key.
+	 * If this binding key does not  represent a method or does not throw any exception,
+	 * returns an empty array.
+	 *
+	 * @return the thrown exceptions signatures
+	 * @since 3.3
+	 */
+	public String[] getThrownExceptions()
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162903">162903</a>
+SuppressWarnings and NON-NLS'd strings as errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161400">161400</a>
+Scanning of identifiers should be optimized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163349">163349</a>
+[assist] code assist doesn't correctly use scanner eofPosition
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162968">162968</a>
+Content Assist for undeclared local variable should prioritize unbound names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163549">163549</a>
+Exclude JDT ant tasks from signing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163072">163072</a>
+[search] method reference reports wrong potential matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155003">155003</a>
+[model] Missing exception types / wrong signature?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161621">161621</a>
+enum is a Keyword for Java5 and cannot be used as a Enum name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162743">162743</a>
+Duplicate variable declaration code assist proposals
+
+<a name="v_721"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 30th October 2006 - 3.3 MILESTONE 3
+<br>Project org.eclipse.jdt.core v_721
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_721">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Removed fix for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141289">141289</a></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_720"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 30th October 2006
+<br>Project org.eclipse.jdt.core v_720
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_720">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=148041">148041</a>
+[compiler][1.5] should issue unchecked warning on cast to Set&lt;X&gt; of Iterator#next () returning X
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159631">159631</a>
+[dom] NPE while trying to cleanup specific pair of file
+
+<a name="v_719"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 29th October 2006
+<br>Project org.eclipse.jdt.core v_719
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_719">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=161846">161846</a>
+Expanding a java project with invalid classpath container entries in Project Explorer causes CPU to stay at 100%
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159738">159738</a>
+[1.5][compiler] Missing class casts in generated byte code for generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162296">162296</a>
+[compiler] Anonymous and local classes are tagged as final and/or private in the inner class infos
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162390">162390</a>
+JavaCodeFormatter Annotation Bug
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162400">162400</a>
+[1.5][compiler] Return type inference does not perform well in array initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159893">159893</a>
+[compiler] Compilation Error with nested classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=162056">162056</a>
+[recovery] Confusing errors in editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154811">154811</a>
+[compiler] Internal compiler error while parsing/formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160823">160823</a>
+[formatter] Java Conventions [built-in] inserts blank line between field declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161412">161412</a>
+org.eclipse.jdt.internal.core.NamedMember#getFullyQualifiedParameterizedName probably boggus
+
+<a name="v_718"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 24th October 2006
+<br>Project org.eclipse.jdt.core v_718
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_718">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New compiler warning to detect overriding of a method without a super invocation has been added.
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156736">156736</a> for further details.</li>
+<li>Code Assist propose unresolved names as possible local variable name<br>
+<pre>
+int f&lt;code assist&gt;
+System.out.print(foo);
+</pre>
+In this example foo is proposed as a possible completion.
+</li>
+<li>The compiler now tolerates that methods implementing a method declared
+    in an implemented interface or an extended abstract class bear an @Override
+    annotation (1.6 mode only - see also bug
+    <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141931">141931</a>).</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161967">161967</a>
+Map.keySet() can be replaced with Map.entrySet() when value is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161214">161214</a>
+[compiler] Fup on bug 159709: improve deprecation marks propagation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161581">161581</a>
+Adding a missing folder doesn't remove classpath marker
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157996">157996</a>
+[compiler] ProblemReferenceBinding missing a closestMatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160337">160337</a>
+Empty block not detected inside anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161555">161555</a>
+org.eclipse.jdt.core.tests.model.ReconcilerTests#testDeleteTwoMethods is failing on IBM 1.5 VM
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161557">161557</a>
+[assist] JavaTypeCompletionProposalComputer throws a runtime exception when using content assist on generics type argument with instance member arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150228">150228</a>
+Code assist for unresolved local variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161204">161204</a>
+code assist with unresolved types does not work when using 5.0 rt.jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161554">161554</a>
+org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest#test1050 fails on IBM JDK 1.5 VM
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141931">141931</a>
+[1.5][compiler] @Override: upcoming changes of the reference implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161476">161476</a>
+org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest.test024 passes unexpectedly with IBM Java2 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161459">161459</a>
+9 tests in org.eclipse.jdt.core.tests.compiler.regression fail on IBM Java2 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156736">156736</a>
+[compiler] Add compiler option to warn overriding methods that do not call super
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159711">159711</a>
+[1.5][compiler] wrongly reports ambiguous method error
+
+<a name="v_717"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 17th October 2006
+<br>Project org.eclipse.jdt.core v_717
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_717">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li><code>TypeNameMatch</code> API has been polished while implementing new <code>searchAllTypeNames(char[][] char[][],...)</code>
+API method (see next point).<br>
+This class has been abstracted and clients now need to use added <code>SearchEngine</code> following method
+to create an instance of it:
+<pre>
+/**
+ * Create a type name match on a given type with specific modifiers.
+ *
+ * @param type The java model handle of the type
+ * @param modifiers Modifiers of the type
+ * @return A non-null match on the given type.
+ */
+public static TypeNameMatch createTypeNameMatch(IType type, int modifiers)
+</pre>
+Early performance tests using added <code>searchAllTypeNames</code> method with <code>TypeNameMatchRequestor</code>
+requestor (i.e. a la Open Type dialog) show interesting memory footprint reduction (around 30%). More precise measures of this
+performance improvement will be done later...
+</li>
+<li>Added new <code>SearchEngine</code> API method for search all type names with multiple qualifications and type names
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160324">160324</a>).<br>
+Only requestor differs from already existing corresponding <code>searchAllTypeNames</code> method:
+<pre>
+/**
+ * Searches for all top-level types and member types in the given scope matching any of the given qualifications
+ * and type names in a case sensitive way.
+ *
+ * Provided {@link TypeNameMatchRequestor} requestor will collect {@link TypeNameMatch}
+ * matches found during the search.
+...
+ * @param nameMatchRequestor the {@link TypeNameMatchRequestor requestor} that collects
+ * 				{@link TypeNameMatch matches} of the search.
+...
+ * @since 3.3
+ */
+public void searchAllTypeNames(
+	final char[][] qualifications,
+	final char[][] typeNames,
+	IJavaSearchScope scope,
+	final TypeNameMatchRequestor nameMatchRequestor,
+	int waitingPolicy,
+	IProgressMonitor progressMonitor)  throws JavaModelException
+</pre>
+Similarily to previous added <code>searchAllTypeNames</code> new API method, clients have to provide
+a new requestor: <code>TypeNameMatchRequestor</code> in order to get matches collected during the search.<br>
+</li>
+<li>Code Assist can return completion proprosals that required some other completion proposals:<br>
+To apply a completion proposal the required completion proposals must be applied otherwise the resulting code won't be correct.<br>
+To manage completion proposalswith required proposals the following API have been added:
+<pre>
+public class CompletionProposal {
+
+	...
+
+	/**
+	 * Returns the required completion proposals.
+	 * The proposal can be apply only if these required completion proposals are also applied.
+	 * If the required proposal aren't applied the completion could create complations problems.
+	 *
+	 * &lt;p&gt;
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * &lt;ul&gt;
+	 * 	&lt;li&gt;&lt;code&gt;FIELD_REF&lt;/code&gt; - The allowed required proposals for this kind are:
+	 *   &lt;ul&gt;
+	 *    &lt;li&gt;&lt;code&gt;TYPE_REF&lt;/code&gt;&lt;/li&gt;
+	 *   &lt;/ul&gt;
+	 * &lt;/li&gt;
+	 * 	&lt;li&gt;&lt;code&gt;METHOD_REF&lt;/code&gt; - The allowed required proposals for this kind are:
+	 *   &lt;ul&gt;
+	 *    &lt;li&gt;&lt;code&gt;TYPE_REF&lt;/code&gt;&lt;/li&gt;
+	 *   &lt;/ul&gt;
+	 *  &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * Other kinds of required proposals will be returned in the future, therefore clients of this
+	 * API must allow with {@link CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)}
+	 * only kinds which are in this list to avoid unexpected results in the future.
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * A required completion proposal cannot have required completion proposals.
+	 * &lt;/p&gt;
+	 *
+	 * @return the required completion proposals, or &lt;code&gt;null&lt;/code&gt; if none.
+	 *
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int,boolean)
+	 *
+	 * @since 3.3
+	 */
+	public CompletionProposal[] getRequiredProposals() {...}
+
+	...
+
+}
+</pre>
+<pre>
+public class CompletionRequestor {
+
+	...
+
+	/**
+	 * Returns whether a proposal of a given kind with a required proposal
+	 * of the given kind is allowed.
+	 *
+	 * @param proposalKind one of the kind constants declared
+	 * @param requiredProposalKind)one of the kind constants declared
+	 * on &lt;code&gt;CompletionProposal&lt;/code&gt;
+	 * @return &lt;code&gt;true&lt;/code&gt; if a proposal of a given kind with a required proposal
+	 * of the given kind is allowed by this requestor, and &lt;code&gt;false&lt;/code&gt;
+	 * if it isn't of interest.
+	 * &lt;p&gt;
+	 * By default, all kinds of required proposals aren't allowed.
+	 * &lt;/p&gt;
+	 * @see #setAllowsRequiredProposals(int, int, boolean)
+	 * @see CompletionProposal#getKind()
+	 * @see CompletionProposal#getRequiredProposals()
+	 *
+	 * @since 3.3
+	 */
+	public boolean isAllowingRequiredProposals(int proposalKind, int requiredProposalKind) {...}
+
+	/**
+	 * Sets whether a proposal of a given kind with a required proposal
+	 * of the given kind is allowed.
+	 *
+	 * Currenlty only a subset of kinds support required proposals. To see what combinations
+	 * are supported you must look at {@link CompletionProposal#getRequiredProposals()}
+	 * documentation.
+	 *
+	 * @param proposalKind one of the kind constants declared
+	 * @param requiredProposalKind)one of the kind constants declared
+	 * on &lt;code&gt;CompletionProposal&lt;/code&gt;
+	 * @param allow &lt;code&gt;true&lt;/code&gt; if a proposal of a given kind with a required proposal
+	 * of the given kind is allowed by this requestor, and &lt;code&gt;false&lt;/code&gt;
+	 * if it isn't of interest
+	 * @see #isAllowingRequiredProposals(int, int)
+	 * @see CompletionProposal#getKind()
+	 * @see CompletionProposal#getRequiredProposals()
+	 *
+	 * @since 3.3
+	 */
+	public void setAllowsRequiredProposals(int proposalKind, int requiredProposalKind)boolean allow) {...}
+
+	...
+
+}
+</pre>
+</li>
+<li>Code Assist propose completion even if the type of a variable or the return type of the method is missing.<br>
+e.g.
+<pre>
+package p;
+public class X {
+  void foo() {
+    Vector v = null;
+    v.addEl| // complete at | location
+  }
+}
+</pre>
+A completion proposal with required proposals will be returned. The main proposal will be the method <code>addElement()</code>
+at <code>addEl</code> location with a required proposal of the type <code>java.util.Vector</code> at
+<code>Vector</code> location.
+The same kind of completion can be computed with the following examples.
+<pre>
+package p;
+public class X {
+  Vector v = null;
+  void foo() {
+    v.addEl| // complete at | location
+  }
+}
+</pre>
+<pre>
+package p;
+public class X {
+  Vector bar() {return null;}
+  void foo() {
+    bar().addEl| // complete at | location
+  }
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161190">161190</a>
+[search] All type search doesn't find all types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=151756">151756</a>
+[compiler] unverifiable bytecode created with cvs head compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161028">161028</a>
+[search] NPE on organize imports in TypeNameMatch.equals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160854">160854</a>
+[search] No type is found using seachAllTypeNames(char[][],char[][],...) methods when no type names is specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80339">80339</a>
+Wrong error message "; expected" when writing an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159709">159709</a>
+[compiler] missing warnings for deprecated member types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157170">157170</a>
+[AST visitor] Unvisited elements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159973">159973</a>
+[1.5] [compiler] VerifyError due to compiler generating incorrect synthetic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160655">160655</a>
+[assist] Bug with code assist and generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44984">44984</a>
+[typing] Automatically optimize class imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160494">160494</a>
+[search] searchAllTypeNames(char[][], char[][],...) fails to find types in default package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160328">160328</a>
+[search] Remove constructor TypeNameMatch(IType)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160327">160327</a>
+[search] Add specification for TypeNameMatch.getType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160324">160324</a>
+[search] SearchEngine.searchAllTypeNames(char[][], char[][], TypeNameMatchRequestor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160323">160323</a>
+[search] TypeNameMatch: support hashCode/equals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160352">160352</a>
+COMPACT mode doesn't work for exception table in the disassembler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90600">90600</a>
+[model] CreateElementInCUOperation.apply: should use project options for rewriter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160352">160352</a>
+COMPACT mode doesn't work for exception table in the disassembler
+
+<a name="v_716"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 10th October 2006
+<br>Project org.eclipse.jdt.core v_716
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_716">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Raw type reference are now reported by default. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159456">159456</a>.</li>
+<li>API of <code>TypeNameMatch</code> has been changed to improve memory consumption performance.
+It now creates IType handle while accepting the type information from indexes and stores their modifiers
+to avoid java element opening while getting this piece of information.<br>
+Note that there's no Java Model initialization nor populating while creating handles...<br>
+Note also that previously added API method on IJavaProject has been removed:
+<pre>
+IType findType(String packageName,
+	String typeQualifiedName,
+	IPackageFragmentRoot root,
+	ICompilationUnit[] units,
+	IProgressMonitor progressMonitor) throws JavaModelException;
+</pre>
+</li>
+<li>While fixing bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157814">157814</a>, new <code>MethodReferenceMatch.isPolymorphic()</code> API method has been renamed to:
+<pre>
+/**
+ * Returns whether the reference is on a message sent from a type
+ * which is a super type of the searched method declaring type.
+ * If <code>true</code>, the method called at run-time may or may not be
+ * the search target, depending on the run-time type of the receiver object.
+ *
+ * @return <code>true</code> if the reference is on a message sent from
+ * a super-type of the search method declaring class, <code>false </code> otherwise
+ */
+public boolean isSuperInvocation()
+</pre>
+</li>
+<li>Added new API <code>ClasspathContainerInitializer#getFailureContainer(...)</code> that returns the classpath container that
+     should be used if a container initializer fails to initialize a container.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95008">95008</a>
+[assist] Missing completion for field initialization in boolean case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160015">160015</a>
+[1.5][javadoc] Missing warning on autoboxing compatible methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160132">160132</a>
+[1.5][compiler] Compiler fails with indirect reference error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160005">160005</a>
+Add protection about misbehaving container initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86482">86482</a>
+ISourceRange implementation does not implements value equals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157814">157814</a>
+[search] polymorphic matches in supertype hierarchy should be marked as potential
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148380">148380</a>
+[search] get IType from TypeNameRequestor result
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160025">160025</a>
+CharOperation fails with AIOOBE when replaced array contains the same chars
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159641">159641</a>
+patch to refactor Main and add new &quot;GCCMain&quot; driver
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=134848">134848</a>
+[compiler][null] false positive after nested loop with break to explicit label
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159654">159654</a>
+[compiler] unverifiable bytecode created by current cvs head compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158518">158518</a>
+Remove dependency of GenericTypeTest#test370 on SUN internal APIs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159607">159607</a>
+[1.5][compiler] M2: Unnecessary cast is necessary
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158267">158267</a>
+Brace positions line after annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158258">158258</a>
+Double check sorting algorithms
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159456">159456</a>
+[1.5][compiler] Enable compiler warning for raw type reference by default
+
+<a name="v_715"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 3rd October 2006
+<br>Project org.eclipse.jdt.core v_715
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_715">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new <code>SearchEngine</code> API method for search all type names (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148380">148380</a>).<br>
+Only requestor differs from already existing <code>searchAllTypeNames</code> method:
+<pre>
+/**
+ * Searches for all top-level types and member types in the given scope.
+ * The search can be selecting specific types (given a package name using specific match mode
+ * and/or a type name using another specific match mode).
+ *
+ * Provided {@link TypeNameMatchRequestor} requestor will collect {@link TypeNameMatch}
+ * matches found during the search.
+...
+ * @param nameMatchRequestor the {@link TypeNameMatchRequestor requestor} that collects
+ * 				{@link TypeNameMatch matches} of the search.
+...
+ * @since 3.3
+ */
+public void searchAllTypeNames(
+	final char[] packageName,
+	final int packageMatchRule,
+	final char[] typeName,
+	final int typeMatchRule,
+	int searchFor,
+	IJavaSearchScope scope,
+	final TypeNameMatchRequestor nameMatchRequestor,
+	int waitingPolicy,
+	IProgressMonitor progressMonitor)  throws JavaModelException
+</pre>
+Clients have to provide a new requestor: <code>TypeNameMatchRequestor</code> in order to
+get matches collected during the search.<br>
+Note that this match (<code>TypeNameMatch</code>) can resolve type and then provide corresponding java model <code>IType</code>:
+<pre>
+/**
+ * Returns the java model type corresponding to fully qualified type name
+ * (based on package, enclosing types and simple name).
+ *
+ * @return the java model type
+ * @throws JavaModelException happens when type stored information are not valid
+ */
+public IType resolvedType() throws JavaModelException
+</pre>
+</li>
+<li>
+Deprecated existing <code>SearchEngine</code> API helper method:
+<pre>
+	public void searchAllTypeNames(
+		final char[] packageExactName,
+		final char[] typeName,
+		final int matchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final TypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException
+</pre>
+This should avoid to have too many similar <code>searchAllTypeNames</code> available methods...
+</li>
+<li>
+Added new <code>JavaCore</code> API method to create a java element from an <code>IFile</code>
+using a specific project:
+<pre>
+/**
+ * Returns the Java element corresponding to the given file, its project being the given
+ * project.
+ * Returns <code>null</code> if unable to associate the given file
+ * with a Java element.
+ *
+ * The file must be one of:
+ *  . a file with one of the {@link JavaCore#getJavaLikeExtensions()
+ *      Java-like extensions} - the element returned is the corresponding <code>ICompilationUnit</code>
+ *  . a <code>.class</code> file - the element returned is the corresponding <code>IClassFile</code>
+ *  . a <code>.jar</code> file - the element returned is the corresponding <code>IPackageFragmentRoot</code>
+ *
+ * Creating a Java element has the side effect of creating and opening all of the
+ * element's parents if they are not yet open.
+ *
+ * @param file the given file
+ * @return the Java element corresponding to the given file, or
+ * <code>null</code> if unable to associate the given file
+ * with a Java element
+ * @since 3.3
+ */
+public static IJavaElement create(IFile file, IJavaProject project)
+</pre>
+Existing API method <code>JavaCore.create(IFile)</code> assumed that project to use was the file one
+but it was not always the case, especially for class files belonging to an external class folder...<br>
+Note that no other methods was added for <code>IResource</code> and <code>IFolder</code> as default project was
+always well computed for this kind of resources.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158506">158506</a>
+[search] SearchEngine.searchAllTypeNames should spec that null is valid for package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159325">159325</a>
+Any idea why ClasspathEntry checks for string object reference instead of equals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155824">155824</a>
+[javadoc] Content assist  doesn't suggest Varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150289">150289</a>
+[hierarchy] NPE in hierarchy builder when region is empty
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159250">159250</a>
+[1.5][compiler] Should better locate raw type usage for array qualified type references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159245">159245</a>
+[1.5][compiler] Missing raw type usage warning for array type ref
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159243">159243</a>
+[compiler] Should better locate deprecation issue for qualified type ref
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158951">158951</a>
+[model] IWorkingCopy should not be referenced in any javadoc comment of JavaModel methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153133">153133</a>
+[model] toggle breakpoint in constructor creates a class load breakpoint
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159021">159021</a>
+[compiler] Unused locals initialisation is optimized out when it is a single name reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158548">158548</a>
+[1.5][compiler] Compiler should be more resilient with unresolved parameterized type references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154995">154995</a>
+[compiler][null] false positive in embedded while/while/break code
+
+<a name="v_714"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M3 - 26th September 2006
+<br>Project org.eclipse.jdt.core v_714
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_714">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=147667">147667</a>
+[1.5][compiler] Illegal compile error: "the method XXX is ambiguous for the type YYY"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158000">158000</a>
+[compiler][null] Second diagnostic absorbed within finally blocks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150082">150082</a>
+[compiler][null] Null reference warning ignores try blocks
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149665">149665</a>
+[compiler][null] Unexpected variable might be null warning in finally block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147118">147118</a>
+[compiler][null] Incorrect null analysis involving do_while loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142303">142303</a>
+Right-click, "Open Declaration" fails under 3.2RC4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141518">141518</a>
+IEvaluationContext.newVariable is not considered when doing codecomplete.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143001">143001</a>
+Statement recovery doesn't recover broken try statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123225">123225</a>
+Code assist suggests overridden method
+
+<a name="v_713"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M2 - 15th September 2006 - 3.3 MILESTONE 2
+<br>Project org.eclipse.jdt.core v_713
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_713">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added <code>isPolymorphic()</code> getter to <code>MethodReferenceMatch</code> (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73401">bug 73401</a>
+and <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156491">bug 156491</a>).
+<br>
+When a search requestor (<code>SearchRequestor</code>) accepts this kind of match,
+it knows if a method reference match is a polymorphic method (i.e. implemented in a super or sub type) or not.
+<p>
+For example, in example below:</p>
+<pre>
+class A { public void foo() {} }
+class B extends A {}
+class C extends B { public void foo() {} }
+class D extends C {}
+public class X {
+	void foo() {
+		new B().foo();
+		new C().foo();
+		new D().foo();
+	}
+}
+</pre>
+<p>
+Searching for all references to <code>C.foo()</code> method get 3 matches
+(instance of <code>MethodReferenceMatch</code>). Two of them, <code>new B().foo()</code> and
+<code>new D().foo()</code> are flagged as polymorphic due to the fact that these are methods
+respectively of a superclass and of a subclass...
+</p>
+<p>
+Search view has been modified to filter this kind of matches when user wants to focus only
+on exact references of the searched method.</p>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157389">157389</a>
+[1.4][compiler] assertionStatus is not set properly for nested types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157333">157333</a>
+calling delete on enum constant deletes entire Enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157403">157403</a>
+NPE when trying to get the ast for a class with boggus annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156491">156491</a>
+[search] Reference search unusable in some situations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73401">73401</a>
+[search] Unable to search just for references to overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157247">157247</a>
+[1.6] [compiler] VerifyError with StackMap frames when no local variable attributes are generated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157086">157086</a>
+should adopt ICU Collator and use new APIs on StructuredViewer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149751">149751</a>
+Enum-valued annotation element handles non-enum constant badly
+
+<a name="v_712"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M2 - 12th September 2006
+<br>Project org.eclipse.jdt.core v_712
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_712">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Code Assist: Annotation types are proposed even there is no prefix.
+<pre>
+   public @interface MyAnnot {
+      int foo();
+   }
+   @|
+   public class AClass {}
+</pre>
+'MyAnnot' is proposed if you do code assist at '|' location.
+</li>
+<li>
+Added new flag on nature of searched element to specify both interfaces and annotations (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156177">bug 156177</a>).
+This flag is defined on IJavaSearchConstants interface:
+<pre>
+	/**
+	 * The searched element is an interface or annotation type.
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.3
+	 */
+	int INTERFACE_AND_ANNOTATION= 11;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148859">148859</a>
+[model][delta] Package Explorer only shows default package after import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156591">156591</a>
+[1.5][compiler] constant-specific methods in enum cannot be abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156540">156540</a>
+[1.5][compiler] Compiler produces invalid bytecode for certain enum declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156177">156177</a>
+[search] interfaces and annotations could be found with only one requets of searchAllTypeName
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156340">156340</a>
+[search] searchAllTypeNames return nothing for empty prefix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=151189">151189</a>
+[search] Declaration search does not find all matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153874">153874</a>
+[1.5][compiler] Compiler fails to consider bridge method with -source 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129983">129983</a>
+[1.5][assist] Need partial word for annotation autocompletion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156194">156194</a>
+[codeassist] PROPOSE_MEMBER_TYPES can be removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155115">155115</a>
+UnresolvedReferenceBindings surfacing through DOM AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153128">153128</a>
+[compiler] Duplicate methods generated (from invalid source, but still :-)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156119">156119</a>
+No warning for unnecessary semicolon in interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155255">155255</a>
+[1.5][compiler] ternary conditional operator returns wrong type
+
+
+<a name="v_711"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M2 - 5th September 2006
+<br>Project org.eclipse.jdt.core v_711
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_711">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added to the batch compiler the ability to redefine the destination path
+    on a source folder basis. Directories cited as sources, directly or as
+    arguments to the <code>-classpath</code> and other classpath related
+    options, can bear a <code>[-d dir]</code> specification that directs the
+    generated class files to <code>dir</code> for source files fetched from the
+    said directories.
+    For example, given the source files <code>src/X.java</code> and
+    <code>Y.java</code>, X depending from Y, the command <code>ecj src[-d bin1]
+    -d bin2</code> will produce the files <code>bin1/X.class</code> and
+    <code>bin2/Y.class</code>, while the command <code>ecj src[-d bin] -d
+    none</code> will only produce the file <code>bin/X.class</code>.
+</li>
+<li>Code Assist: Annotation arguments names are proposed even there is no prefix.
+<pre>
+   public @interface MyAnnot {
+      int foo();
+   }
+   @MyAnnot(|
+   public class AClass {}
+</pre>
+'foo' is proposed if you do code assist at '|' location.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148521">148521</a>
+[5.0][content assist] Content assist show all members of a full annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156108">156108</a>
+[1.5][compiler] Autoboxing doesnt workt in switch-statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140123">140123</a>
+Missing callback in CodeSnippetToCuMapper#getCompletionRequestor()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153130">153130</a>
+[assist] IOB during content assist in scrapbook
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154170">154170</a>
+Printing warnings breaks in-editor quick fixes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146554">146554</a>
+[batch][compiler][options] Allow the batch compiler to output compiled files
+into multiple output folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155887">155887</a>
+Breakpoint in 'finally' not hit - test suite failing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155795">155795</a>
+Patch to fix jface.text.Assert deprecation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154880">154880</a>
+DeltaProcessor does not set project references if first build is a project build
+
+<a name="v_710"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M2 - 29th August 2006
+<br>Project org.eclipse.jdt.core v_710
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_710">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=155423">155423</a>
+[compiler] Unoptimal code generation when an initializer contains a statement that returns
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=151153">151153</a>
+[1.6][compiler] Invalid Stackmap attribute generated for ternary operator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145397">145397</a>
+[1.6][compiler] Invalid StackMap attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148224">148224</a>
+AST API request: have binding for int, need int[], int[][] ....
+
+<a name="v_709"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M2 - 15th August 2006
+<br>Project org.eclipse.jdt.core v_709
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_709">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=151756">151756</a>
+[compiler] unverifiable bytecode created with cvs head compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153303">153303</a>
+IBinding.getAnnotations() returns array with null element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148661">148661</a>
+[formatter] leverage CombinedBinaryExpression in BinaryExpressionFragmentBuilder#visit(BinaryExpression, BlockScope)
+
+<a name="v_708"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 6th August 2006 - 3.3 MILESTONE 1
+<br>Project org.eclipse.jdt.core v_708
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_708">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95152">bug 95152</a> required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95152">95152</a>
+[search] F3 can't find synthetic constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152725">152725</a>
+[1.6][formatter] Code formatter does not format 1.5 code when source level is 1.6
+
+<a name="v_707"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 3rd August 2006
+<br>Project org.eclipse.jdt.core v_707
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_707">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+SearchPattern API method <code>createPattern(IJavaElement, int, int)</code> behavior has been modified for generic searches.<br>
+It now returns erasure matches instead of exact ones  (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124489">124489</a> for detailed discussion on this topic).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116459">116459</a>
+[1.5][search] Generic type reference should return exact match on parameterized type with its own variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124489">124489</a>
+[1.5][search] &quot;Find unused dependencies&quot; misses references to generic types
+
+<a name="v_706"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 1st August 2006
+<br>Project org.eclipse.jdt.core v_706
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_706">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=133024">133024</a>
+[ast rewrite] ASTRewrite does not honor forced line splits
+
+<a name="v_705"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 25th July 2006
+<br>Project org.eclipse.jdt.core v_705
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_705">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=151118">151118</a>
+verifier errors occur when running osgi tests
+
+<a name="v_704"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 18th July 2006
+<br>Project org.eclipse.jdt.core v_704
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_704">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Wildcard captures are now indicating some ID to better address ambiguities in error messages
+<br>e.g. now telling: <code>capture#2-of ? extends Number</code> is not compatible with <code>capture#1-of ? extends Number</code>
+<br>as opposed to: <code>capture-of ? extends Number</code> is not compatible with <code>capture-of ? extends Number</code>
+(also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149573">149573</a>).</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129317">129317</a>
+Outline view inconsistent with code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102875">102875</a>
+code assist should propose types even if there's no initial character(s)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129584">129584</a>
+Java model gives different results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150758">150758</a>
+[1.5][compiler] NullPointerException in internal compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150074">150074</a>
+[compiler] init part of for each loop with empty body is not executed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149028">149028</a>
+Limiting number of characters to read with the file size is invalid.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149893">149893</a>
+[1.5] Compilation error: The method is ambiguous for the type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149376">149376</a>
+Internal compiler error on "import static"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149573">149573</a>
+[1.5][compiler] Improve readable name of wildcard captures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128073">128073</a>
+Content Assist should give static fields and methods declared in target type higher relevance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149043">149043</a>
+Unresolvable classpath container leads to lots of scheduled jobs
+
+<a name="v_703"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 4th July 2006
+<br>Project org.eclipse.jdt.core v_703
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_703">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=149013">149013</a>
+[javadoc] In latest 3.3 build, there is a javadoc error in org.eclipse.core.resources
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119857">119857</a>
+[javadoc] Some inner class references should be flagged as unresolved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103304">103304</a>
+[Javadoc] Wrong reference proposal for inner classes.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148797">148797</a>
+Syntax error in java class results in AST=null-error on "organize imports"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148742">148742</a>
+[5.0][content assist] Annotation content assist not working in all cases for parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117302">117302</a>
+Clean build of large project gives unresolved type errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147875">147875</a>
+[1.5][compiler] NPE when initializing annotations of a binary field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146012">146012</a>
+No F_CONTENT flag on delta when reverting to old annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148970">148970</a>
+Exceptions opening external Java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148949">148949</a>
+JarEntryFile now returning 'null'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120865">120865</a>
+ICompilationUnit.findPrimaryType(..) should not throw internal AFE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148370">148370</a>
+[formatter] new Class&lt;?&gt;[] {} kills formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148010">148010</a>
+Code select doesn't find binary parameterized method
+
+<a name="v_702"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 27th June 2006
+<br>Project org.eclipse.jdt.core v_702
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_702">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Add new Search API method to support patterns for package/enclosing type name while searching all types names
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92264">92264</a>).<br>
+<pre>
+/**
+ * Searches for all top-level types and member types in the given scope.
+ * The search can be selecting specific types (given a package name using specific match mode
+ * and/or a type name using another specific match mode).
+ *
+ * @param packageName the full name of the package of the searched types, or a prefix for this
+ *                    package, or a wild-carded string for this package.
+ * @param typeName the dot-separated qualified name of the searched type (the qualification include
+ *                 the enclosing types if the searched type is a member type), or a prefix
+ *                 for this type, or a wild-carded string for this type.
+ * @param packageMatchRule one of
+ *        . {@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
+ *            of the searched types.
+ *        . {@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
+ *            of the searched types.
+ *        . {@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.
+ *        . {@link SearchPattern#R_CAMELCASE_MATCH} if type name are camel case of the names of the searched types.
+ *    combined with {@link SearchPattern#R_CASE_SENSITIVE},
+ *       e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+ *       or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+ * @param typeMatchRule one of
+ *        . {@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
+ *            of the searched types.
+ *        . {@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
+ *            of the searched types.
+ *        . {@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.
+ *        . {@link SearchPattern#R_CAMELCASE_MATCH} if type name are camel case of the names of the searched types.
+ *     combined with {@link SearchPattern#R_CASE_SENSITIVE},
+ *       e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+ *       or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+ * @param searchFor determines the nature of the searched elements
+ *     . {@link IJavaSearchConstants#CLASS}: only look for classes
+ *     . {@link IJavaSearchConstants#INTERFACE}: only look for interfaces
+ *     . {@link IJavaSearchConstants#ENUM}: only look for enumeration
+ *     . {@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type
+ *     . {@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations
+ *     . {@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces
+ *     . {@link IJavaSearchConstants#TYPE}: look for all types (i.e. classes, interfaces, enum and annotation types)
+ * @param scope the scope to search in
+ * @param nameRequestor the requestor that collects the results of the search
+ * @param waitingPolicy one of
+ *        . {@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately
+ *        . {@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+ *            underlying indexer has not finished indexing the workspace
+ *        . {@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+ *            underlying indexer to finish indexing the workspace
+ * @param progressMonitor the progress monitor to report progress to, or null if no progress
+ *                        monitor is provided
+ * @exception JavaModelException if the search failed. Reasons include:
+ *        . the classpath is incorrectly set
+ * @since 3.3
+ */
+public void searchAllTypeNames(
+	final char[] packageName,
+	final int packageMatchRule,
+	final char[] typeName,
+	final int typeMatchRule,
+	int searchFor,
+	IJavaSearchScope scope,
+	final TypeNameRequestor nameRequestor,
+	int waitingPolicy,
+	IProgressMonitor progressMonitor)  throws JavaModelException
+</pre>
+Note that already existing <code>searchAllTypeNames(char [], char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)</code> API method documentation has been updated to reflected the fact
+that package name is an exact name and does not accept wildcards.
+</li>
+<li>Incremented plug-in version ID to &quot;3.3.0&quot; due to newly added API method (see details above).</li>
+<li>Huge String concatenations - thousands of terms and beyond - are now
+    handled smoothly by the compiler even when they are not solely comprised of
+    literals and other constants (cf. bug
+    <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102728">102728</a>).
+    </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148278">148278</a>
+Default-package classes missing in Package Explorer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148352">148352</a>
+NLS warning shows up on incomplete code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102728">102728</a>
+[compiler] Reduce the stack depth demands of extended string concatenation ASTs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142530">142530</a>
+[hierarchical packages] '.' in folder names confuses package explorer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148523">148523</a>
+[batch] Batch compiler output contains extra linebreak before line position
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147485">147485</a>
+Anonymous type missing from java model
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111086">111086</a>
+[1.5][compiler] Compiler accepts call to parameterized method with invalid arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148215">148215</a>
+[search] Exception while searching for declarations of referenced types in binary java elements packaged in a jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146331">146331</a>
+Java Editor won't save file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145367">145367</a>
+Failing to open a binary member leaves cache inconsistent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96237">96237</a>
+[javadoc] Inner types must be qualified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92264">92264</a>
+[search] all types names should support patterns for package/enclosing type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102720">102720</a>
+org.eclipse.jdt.core.Signature spec incomplete
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148015">148015</a>
+NPE in log from ClasspathChange
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143212">143212</a>
+IAE in log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145544">145544</a>
+Comment indentation wrong when using sun conventions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146214">146214</a>
+Refactor XmlWritter and Main.Logger
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147877">147877</a>
+source end of array access isn't correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145007">145007</a>
+[1.5][javadoc] Generics + Inner Class -&gt; Javadoc &quot;missing @throws&quot; warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147690">147690</a>
+[1.5][compiler] Incompatible serialversionuid when using covariant in Java 1.5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147747">147747</a>
+max stack for clinit of enum overestimated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142059">142059</a>
+[efs] renaming package fails to update references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143013">143013</a>
+SWTException: Failed to execute runnable (...AbortCompilation)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147024">147024</a>
+[compiler] Compiler bug when accessing static final attribute in a non-static way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143684">143684</a>
+Creating of static imports is unavailable..
+
+<a name="v_701"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 20th June 2006
+<br>Project org.eclipse.jdt.core v_701
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_701">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120667">bug 120667</a> required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147736">147736</a>
+ClassCastException in TypeHierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91709">91709</a>
+[1.5][model] Quick Fix Error but no Problem Reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147381">147381</a>
+[1.5][compiler] Generics discrepancy between Eclipse compiler and Sun compiler.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139555">139555</a>
+[hierarchy] Opening a class from Type hierarchy will give the wrong one if source and compiled are in defined in project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144573">144573</a>
+compilationParticipant extension point schema incomplete
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145835">145835</a>
+getJavaClassLibs needs to account for IBM J2SE 1.5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145333">145333</a>
+[hierarchy] Resolving too much
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122444">122444</a>
+[hierarchy] Type hierarchy of inner member type misses anonymous subtypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114894">114894</a>
+[compiler] Compiler generate dead bytecode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=147096">147096</a>
+ecj.jar manifest should not use x-friends, but use x-internal=true instead
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146015">146015</a>
+Some JDT/Core tests results are still VM dependent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120667">120667</a>
+[hierarchy] Type hierarchy for enum type does not include anonymous subtypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146324">146324</a>
+Batch builds produce "The type X is already defined" errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146615">146615</a>
+[hierarchy] TypeHierarchyTests is tests order dependent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142207">142207</a>
+[batch][options] Source/target level names 5 and 5.0 missing from batch
+compiler help message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76734">76734</a>
+[classpath] Attemp to lock workspace during container initialization
+
+<a name="v_700"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.3M1 - 13th June 2006
+<br>Project org.eclipse.jdt.core v_700
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_700">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Progressive help message for the batch compiler.<br>
+	The new <tt>-help:warn</tt> option displays details about the various
+    parameters applicable to the <tt>-warn</tt> option; these details are no
+    more part of the general help message, which is thus more compact
+    (cf. bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144248">144248</a>).
+    </li>
+<li>Compiler is now better resilient to duplicate local variables, thus allowing further
+operation to still be carried out accurately (codeselect, completion, search, DOM AST ops)
+(cf. bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144858">144858</a>).</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146215">146215</a>
+JDT Core tests should not be dependent on HashMap implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144858">144858</a>
+[compiler] Should be more resilient with duplicate locals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145746">145746</a>
+[1.5][compiler] Enum synthetic methods should be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145732">145732</a>
+[1.5][compiler] Inconsistent behavior in ECJ code for enum types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145516">145516</a>
+Bad performance when compiling a java file with non java content
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142897">142897</a>
+[1.5][compiler] Compiler cannot resolve type of inner class of a bounded generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144976">144976</a>
+[hierarchy] NPE in ReferenceBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=145500">145500</a>
+[hierarchy] Superclass could be more resilient
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144866">144866</a>
+[assist][javadoc] Wrong completion inside @value tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144414">144414</a>
+JDT Compiler fails while standard javac compiler can proceed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142772">142772</a>
+[1.5][compiler] Compilation succeeds with static imports that fail with javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=143259">143259</a>
+[1.5][compiler] NullPointerException in ReferenceBinding.binarySearch , Eclipse 3.2RC4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144426">144426</a>
+[compiler] Compiler incorrectly reports "assignment to variable has no effect" when it is a duplicate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=144248">144248</a>
+[batch] Progressive help text
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141512">141512</a>
+[batch] re-format the help message so as to fit into 80 columns
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141522">141522</a>
+[compiler][batch] ClassFile#buildAllDirectoriesInto should protect itself
+against concurrent directory creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141330">141330</a>
+[1.5][compiler] Suspicious error message for type mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141252">141252</a>
+[1.6]][compiler] ClassFormatError: Illegal class name "" in class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141810">141810</a>
+[1.5][compiler] Enum switch tables incorrectly generated by the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141327">141327</a>
+StackFrame and VerificationTypeInfo must call super.clone() in their clone() method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140476">140476</a>
+JDOM: IDOMType.setSuperInterfaces(new String [0]) fails to remove existing implements clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132430">132430</a>
+[1.5][javadoc] Unwanted missing tag warning for overridden method with parameter containing type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130752">130752</a>
+[comments] first BlockComment parsed as LineComment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=140156">140156</a>
+[1.5][search] Invalid method handle with parameterized parameters when no source is attached
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=123679">123679</a>
+[search] missing icon or bad hit in search results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=141550">141550</a>
+Enable now passing tests
+
+<hr>
+<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R32_buildnotes_jdt-core.html">build notes up to Release 3.2</a>.</p>
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/notes/R34_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R34_buildnotes_jdt-core.html
new file mode 100644
index 0000000..a61c044
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R34_buildnotes_jdt-core.html
@@ -0,0 +1,3511 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes 3.4</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.4 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch.
+	  For more information on 3.4 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.4/index.php#release-plan">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.4/index.php#milestone-plan">milestone plan</a>,
+	  the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_4.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.3 (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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_3_maintenance">R3.3.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<a name="v_874"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4.0 - June 13, 2008 - 3.4.0
+<br>Project org.eclipse.jdt.core v_874
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_874">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=236599">236599</a>
+Fix wording of JDT
+
+<a name="v_873"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4.0 - June 9, 2008
+<br>Project org.eclipse.jdt.core v_873
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_873">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=236252">236252</a>
+Batch compiler's help should not have 'release candidate-4' in the version name
+
+<a name="v_872"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC4 - June 3, 2008 - 3.4 RELEASE CANDIDATE 4
+<br>Project org.eclipse.jdt.core v_872
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_872">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=234718">234718</a>
+JarPackageFragmentRoot.computeChildren(..) is slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=234848">234848</a>
+Need to trace classpath container initialization failures
+
+<a name="v_871"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC3 - May 29, 2008 - 3.4 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_871
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_871">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=234307">234307</a>
+Java Model Exception from org.eclipse.jdt.internal.core.Buffer.save(Buffer.javga:361)
+
+<a name="v_870"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC3 - May 29, 2008
+<br>Project org.eclipse.jdt.core v_870
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_870">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=234336">234336</a>
+[formatter] JavaDocTestCase.testMultiLineCommentIndent* tests fail in I20080527-2000 build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233800">233800</a>
+[1.5][compiler] Internal compiler NPE on checkUnsafeCast
+
+<a name="v_869"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC3 - May 27, 2008
+<br>Project org.eclipse.jdt.core v_869
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_869">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=234120">234120</a>
+PublicScanner not in sync with internal Scanner
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233625">233625</a>
+Content Assist outof memory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232768">232768</a>
+[formatter] does not format block and single line comment if too much selected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233887">233887</a>
+[javadoc][1.5] Build of Eclipse project stop by NullPointerException and will not continue on Eclipse version later than 3.4M7
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232814">232814</a>
+[compiler] Testcase with &quot;value1 - (-value2)&quot; not working when value2 is final
+
+<a name="v_868"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC2 - May 22, 2008 - 3.4 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_868
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_868">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=230944">230944</a>
+[formatter] Formatter does not respect /*-
+
+<a name="v_867"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC2 - May 22, 2008
+<br>Project org.eclipse.jdt.core v_867
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_867">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=232788">232788</a>
+[formatter] Formatter misaligns stars when formatting block comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233228">233228</a>
+[formatter] line comments which contains \\u are not correctly formatted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233224">233224</a>
+[formatter] Xdoclet tags looses @ on format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232466">232466</a>
+[formatter] References of inlined tags are still split in certain circumstances
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228648">228648</a>
+AST: no binding for Javadoc reference to inner class
+
+<a name="v_866"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC2 - May 20, 2008
+<br>Project org.eclipse.jdt.core v_866
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_866">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=232803">232803</a>
+Reconcile doesn't find methods with a $ in parameter types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232488">232488</a>
+[formatter] Code formatter scrambles JavaDoc of Generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=225737">225737</a>
+[compiler][1.5] Generics - JDT cannot compile hudson-core when javac can
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231861">231861</a>
+[1.5][compiler] Generics: problem with partial generics
+
+
+<a name="v_865"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 15, 2008- 3.4 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_865
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_865">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=232285">232285</a>
+[formatter] New comment formatter wrongly formats javadoc header/footer with several contiguous stars
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229480">229480</a>
+[builder] compiler exception causes NPE in AbstractImageBuilder.acceptResult()
+
+<a name="v_864"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 14, 2008
+<br>Project org.eclipse.jdt.core v_864
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_864">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=232037">232037</a>
+CompilationUnit#equals(Object) throws NPE if owner is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227185">227185</a>
+[1.5][compiler] Compiler error using generics with static class
+ 
+
+<a name="v_863"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 13, 2008
+<br>Project org.eclipse.jdt.core v_863
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_863">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=231297">231297</a>
+[formatter] New JavaDoc formatter wrongly split inline tags before reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231263">231263</a>
+[formatter] New JavaDoc formatter wrongly indent tags description
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229682">229682</a>
+[formatter] New comment put text over the max line length in some cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231293">231293</a>
+New errors about indirectly referenced classes from required .class files in 20080508-200
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231622">231622</a>
+Some classes from Missing classes from Cntrl-Shift-T
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231747">231747</a>
+[assist] UnsupportedOperationException even when the context is extended
+
+<a name="v_862"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 12, 2008
+<br>Project org.eclipse.jdt.core v_862
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_862">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=231579">231579</a>
+Converting compiler.tool to API tools support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231367">231367</a>
+org.eclipse.jdt.compiler.tool is not singleton
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230026">230026</a>
+[1.5][compiler] CCE during static import resolution with parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230885">230885</a>
+[content assist] NPE at ParameterGuesser.createVariable()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163200">163200</a>
+Moving code with compile errors outside of a source folder preserve compile errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229951">229951</a>
+StackOverflowError during JavaSearchScope.add for large workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230864">230864</a>
+[assist] Code assist do not work in parameterized method with 'this' as receive
+
+<a name="v_861"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 8, 2008
+<br>Project org.eclipse.jdt.core v_861
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_861">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=230127">230127</a>
+[clean up] NPE in Organize Imports save action
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231053">231053</a>
+[formatter] Comment formatter fails to format long strings in @see references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231060">231060</a>
+[formatter] '*' are not preserved in Javadoc comments when located at the beginning of the line
+
+<a name="v_860"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 7, 2008
+<br>Project org.eclipse.jdt.core v_860
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_860">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=222284">222284</a>
+[search] ZipException while searching if linked jar doesn't exist any longer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191322">191322</a>
+[javadoc] @see or @link reference to method without signature fails to resolve to base class method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194743">194743</a>
+Constructor tooltip does not show constructor javadoc without source attachment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228464">228464</a>
+Annotation.getMemberValuePairs() empty for single attribute with empty value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229128">229128</a>
+[search] Search finding matches in working copies that are not part of scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230391">230391</a>
+[organize imports] unmatched packages group is always first
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229927">229927</a>
+No code assist in array initializer
+
+<a name="v_859"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4RC1 - May 5, 2008
+<br>Project org.eclipse.jdt.core v_859
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_859">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=230364">230364</a>
+[formatter] Test failure in CleanUpStressTest after changes to comment formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214558">214558</a>
+[1.5][compiler] javac reports ambiguous method ref that Eclipse does not identify
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228291">228291</a>
+[1.5][compiler] Incorrect unsafe warning for casting complex but static types.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230070">230070</a>
+[1.5][compiler] Internal compiler error: NullPointerException at org.eclipse.jdt.internal.compiler.ast.CastExpression.checkUnsafeCast()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230230">230230</a>
+[formatter] New comment formatter does not handle properly all scanner exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230184">230184</a>
+[formatter] New comment formatter split comment line between contiguous tokens
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229954">229954</a>
+[formatter] New comment formatter fails to format correctly when invalid throws reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229932">229932</a>
+[formatter] New comment formatter wrongly formats @param tags with wrong syntax
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229683">229683</a>
+[formatter] New comment formatter takes 2 passes to format when tags are inside text
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229968">229968</a>
+Perf regression while computing type hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229636">229636</a>
+JavaModelException should stay instanciatable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228109">228109</a>
+[1.5][compiler] Enum static field initializer in enum constructor failed to give compilation error
+
+<a name="v_858"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 30, 2008 - 3.4 MILESTONE 7
+<br>Project org.eclipse.jdt.core v_858
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_858">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=228651">228651</a>
+[dom] NPE in MemberValuePairBinding.isDefault()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229569">229569</a>
+[formatter] New comments formatter does not indent lines inside immutable tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229526">229526</a>
+Conversion to Api tools adds a new internal method inside an API class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229595">229595</a>
+OptionTests.testBug68993() failing due to wrong assumption
+
+<a name="v_857"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 29, 2008
+<br>Project org.eclipse.jdt.core v_857
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_857">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=229373">229373</a>
+[formatter] New comment formatter gets lost when encountering invalid closing tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229304">229304</a>
+cannot 'Open Type' a binary type that is present in an external folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229326">229326</a>
+[formatter] New comment formatter takes 2 passes to format some block comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227730">227730</a>
+[Javadoc] Missing description should not be warned for {@inheritDoc}
+
+<a name="v_856"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 28, 2008
+<br>Project org.eclipse.jdt.core v_856
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_856">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=229108">229108</a>
+[formatter] New comment formatter adds unnecessary spaces before and after &lt;code&gt; tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229107">229107</a>
+[formatter] New comment formatter fails to format correctly when &lt;table ...&gt; tags is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229103">229103</a>
+[formatter] New comment formatter split inlined tags incorrectly
+
+<a name="v_855"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 27, 2008
+<br>Project org.eclipse.jdt.core v_855
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_855">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=227043">227043</a>
+[formatter] CodeFormatter does not format line and block comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228528">228528</a>
+NPE when interrupting the build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228639">228639</a>
+Source attachment root detection doesn't work if source folder contains META-INF
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79798">79798</a>
+[compiler] Wrong compiler error when interface overrides two methods with same signature but different exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227546">227546</a>
+[assist] No method declaration completion in enum constant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158526">158526</a>
+[search] NPE in JavaSearchScope.addEnclosingProjectOrJar(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182738">182738</a>
+[search] Avoid keeping list of roots in JavaWorkspaceScope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228193">228193</a>
+[formatter] Javadoc comments are still formatted using JavaDocRegion!
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227822">227822</a>
+[select] ClassCastException thrown if unable to resolve core Java types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227855">227855</a>
+incorrect compilation errors related to annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208010">208010</a>
+[compiler] Compiler reports unneccessary warning for static members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222735">222735</a>
+DOM AST: hide recovered bindings unless 'recovered bindings' is enabled
+
+<a name="v_854"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 22, 2008
+<br>Project org.eclipse.jdt.core v_854
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_854">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>ZIP archives that have an extension other than <code>.zip</code> and <code>.jar</code> can now be put on the classpath as well.
+      See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182360">bug 182360</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209643">209643</a>
+keyword completion proposals for @interface and enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227531">227531</a>
+add one exception logging in ASTParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227941">227941</a>
+org.eclipse.jdt.internal.compiler.batch.Main writes bad characters to an xml log file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227930">227930</a>
+[compiler] NPE during exception reporting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227502">227502</a>
+[1.5][compiler] Bad error message for abstract enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227761">227761</a>
+NPE from CompletionContext.getVisibleElements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227813">227813</a>
+root detection in in external linked source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209149">209149</a>
+[1.7][compiler] 1.7 compliance allows type params to be declared in any order
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182360">182360</a>
+Only Jar and Zip files allowed for java.io.File in ClasspathContainers using
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222326">222326</a>
+[1.5][compiler] NullPointerException during: "Compute launch button tooltip"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161030">161030</a>
+add code assist for enum values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207631">207631</a>
+[Content Assist] Autocompletion fails after use of binary right-shift operators
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226918">226918</a>
+[jsr199] the standard java file manager returned by the Eclipse compiler does not accept non-modifiable iterators as remaining arg to JavaFileManager#handleOption
+
+<a name="v_853"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 15, 2008
+<br>Project org.eclipse.jdt.core v_853
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_853">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The Java compiler now uses multiple CPUs when running in batch mode. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142126">142126</a>.</li>
+<li>In order to avoid breaking existing clients while fixing bug 
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102780">102780</a>, 
+the new formatter behavior (i.e. format comments while formatting the whole
+compilation unit) will be activated only if a specific flag was set.
+<p>
+This flag is defined in CodeFormatter and named <code>'F_INCLUDE_COMMENTS'</code>.
+Clients will have to combine it with existing CodeFormatter.K_COMPILATION_UNIT
+or CodeFormatter.UNKNOWN kinds to see the fix for this bug activated...
+</p>
+Here's its complete new API changes done on
+<code>org.eclipse.jdt.core.formatter.CodeFormatter</code>:
+<pre>
+/**
+ * Flag used to include the comments during the formatting of the code
+ * snippet.
+ *
+ * This flag can only be combined with following kinds:
+ *      . {@link #K_COMPILATION_UNIT}
+ *      . {@link #K_UNKNOWN}
+ *
+ * Note also that it has an effect only when the option
+ * {@link DefaultCodeFormatterConstants
+ *  #FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT}
+ * is set to {@link DefaultCodeFormatterConstants#TRUE} while calling
+ * {@link #format(int, String, int, int, int, String)} or
+ * {@link #format(int, String, IRegion[], int, String)} methods
+ *
+ * For example, with the Eclipse default formatter options, the formatting of
+ * the following code snippet using {@link #K_COMPILATION_UNIT}:
+ *
+ * public class X {
+ * /**
+ *  * This is just a simple example to show that comments will be formatted while processing a compilation unit only if the constant flag <code>F_INCLUDE_COMMENT</code> flag is set.
+ *  * @param str The input string */
+ *  void foo(String str){}}
+ *
+ * will produce the following output:
+ *
+ * public class X {
+ *      /**
+ *       * This is just a simple example to show that comments will be formatted while processing a compilation unit only if the constant flag <code>F_INCLUDE_COMMENT</code> flag is set.
+ *       * 
+ *       * @param str The input string
+ *       */
+ *      void foo(String str){
+ *      }
+ *  }
+ *
+ * Adding this flavor to the kind given while formatting the same source
+ * (e.g. {@link #K_COMPILATION_UNIT} | {@link #F_INCLUDE_COMMENTS})
+ * will produce the following output instead:
+ *
+ * public class X {
+ *      /**
+ *       * This is just a simple example to show that comments will be formatted
+ *       * while processing a compilation unit only if the constant flag
+ *       * <code>F_INCLUDE_COMMENT</code> flag is set.
+ *       * 
+ *       * @param str
+ *       *                 The input string
+ *       */
+ *      void foo(String str){
+ *      }
+ *  }
+ *
+ * <i><u>Note</u>: Although we're convinced that the formatter should
+ * always include the comments while processing a
+ * {@link #K_COMPILATION_UNIT kind of compilation unit}, we
+ * have decided to add a specific flag to fix this formatter incorrect behavior.
+ * This will prevent all existing clients using the {@link #K_COMPILATION_UNIT}
+ * kind to be broken while formatting.</i>
+ *
+ * @since 3.4
+ */
+public static final int F_INCLUDE_COMMENTS = 0x1000;
+</pre>
+Note that CodeFormatter.UNKNOWN and CodeFormatter.K_COMPILATION_UNIT
+specification will be updated to include this new possible combination:
+<pre>
+/**
+ * Unknown kind
+ * 
+ * Note that since 3.4, the {@link #F_INCLUDE_COMMENTS} flag can be added
+ * to this constant in order to get the comments formatted if a
+ * compilation unit is processed.
+ */
+public static final int K_UNKNOWN = 0x00;
+
+/**
+ * Kind used to format a compilation unit
+ *
+ * Note that using this constant, the javadoc comments are only indented while
+ * processing the compilation unit.
+ *
+ * <b>Since 3.4</b>, if the corresponding comment option is set to
+ * <code>true</code> then it is also possible to format the comments on the fly
+ * by adding the {@link #F_INCLUDE_COMMENTS} flag to this kind of format.
+ */
+public static final int K_COMPILATION_UNIT = 0x08;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142126">142126</a>
+utilizing multiple CPUs for Java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102780">102780</a>
+[formatter] CodeFormatter does not format Javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219855">219855</a>
+[1.5][compiler] StackOverflowError during: "Requesting Java AST from selection"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223986">223986</a>
+Invalid incompatible return type error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226890">226890</a>
+[jsr199] enable CompilerToolTests#testCompilerOneClassWithEclipseCompiler4 on Linux
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226673">226673</a>
+CompletionContext.getVisibleElements(..) doesn't find assignable fields
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178982">178982</a>
+[assist] Bad static import relevance in content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=225563">225563</a>
+Class with compile errors results in invalid class file format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226313">226313</a>
+Anonymous enum type has wrong name and source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223685">223685</a>
+[clean-up] Necessary cast removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82712">82712</a>
+[1.5] Code assist does not show method parameters from static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226134">226134</a>
+CCE in SourceMethod.getDefaultValue() for constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97310">97310</a>
+code assist for type variable bounds: should not suggest classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=224402">224402</a>
+[compiler] CCE in compiler: MissingTypeBinding cannot be cast to ProblemReferenceBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96604">96604</a>
+[1.5][codeassist] missing proposals for wildcard capture
+
+<a name="v_852"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 8, 2008
+<br>Project org.eclipse.jdt.core v_852
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_852">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=215331">215331</a>
+[assist] Inconsistent completions for member types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221904">221904</a>
+Java Model Exception while trying to open *.class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223488">223488</a>
+'package-info.java' does not exist in PackageBinding.getAnnotations()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193045">193045</a>
+[1.5][assist] Code completion fails in inner class w/ foreach loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223899">223899</a>
+Base type var should not be proposed before Object var in == case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=225577">225577</a>
+[compiler] Default abstract methods should be tagged as synthetic
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=133005">133005</a>
+BinaryTypeConverter cannot convert generic type reference.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=224351">224351</a>
+Regression in performance test FullSourceWorkspaceModelTests#testFindType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215975">215975</a>
+new field declaration CompletionProposal cuts changes initial prefix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217078">217078</a>
+[compiler] compiler.regression.RuntimeTests#test0001_memory_exhaustion failing when using IBM JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219099">219099</a>
+Content assist does not not offer multiple choices for ambiguous static imports
+
+<a name="v_851"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M7 - April 1, 2008
+<br>Project org.eclipse.jdt.core v_851
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_851">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=224715">224715</a>
+Missing abstract problem methods should be tagged as synthetic methods
+
+<a name="v_850"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 28, 2008 - 3.4 MILESTONE 6
+<br>Project org.eclipse.jdt.core v_850
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_850">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=224458">224458</a>
+[search] NPE trying to search for a field declaration
+
+<a name="v_849"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 27, 2008
+<br>Project org.eclipse.jdt.core v_849
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_849">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=223878">223878</a>
+[content assist] Illegal argument exception from content assist
+
+<a name="v_848"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 26, 2008
+<br>Project org.eclipse.jdt.core v_848
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_848">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=222534">222534</a>
+[compiler] wrong field hides field warning for private fields
+
+<a name="v_847"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 25, 2008
+<br>Project org.eclipse.jdt.core v_847
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_847">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li><code>JavaCore.COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_ALL_TAGS</code> introduced in 3.4M3 has been renamed to 
+     <code>COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION_ALL_STANDARD_TAGS</code>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223838">223838</a>
+[dom] AnnotationBinding.isRecovered() always return false
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221267">221267</a>
+[1.5][compiler] missing annotation bindings on interface method parameter
+
+<a name="v_846"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 23, 2008
+<br>Project org.eclipse.jdt.core v_846
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_846">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The batch compiler now uses the <code>Class-Path</code> clause of jar files 
+    manifests to complete the classpath. For jar files that are specified on a
+    <code>-classpath</code> option, the compiler follows <code>Class-Path</code>
+    clauses recursively and appends each referenced jar file to the end of the 
+    classpath, provided it is not on the classpath yet. See bug
+    <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97332">97332</a> for
+    further details.</li>
+<li>Added APIs to call the batch compiler from a stand-alone application:
+	 <code>BatchCompiler#compiler(String, PrintWriter, PrintWriter, CompilationProgress)</code> and
+	 <code>BatchCompiler#compiler(String[], PrintWriter, PrintWriter, CompilationProgress)</code>.
+	 See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217233">217233</a> for more details.</li>
+<li>All search reference matches may now have a local element. Clients can access
+this local element using the <code>getLocalElement()</code> method on the new
+<code>ReferenceMatch</code> API class:<pre>
+
+/**
+ * An abstract Java search match that represents a reference.
+ *
+ * This class is not intended to be subclassed by clients.
+ *
+ * @since 3.4
+ */
+public abstract class ReferenceMatch extends SearchMatch {
+...
+/**
+ * Returns the local element of this search match, or <code>null</code> if none.
+ * A local element is the inner most element that contains the reference and that is not
+ * reachable by navigating from the root of the {@link IJavaModel} using 
+ * {@link IParent#getChildren()}.
+ *
+ * Known element types for local elements are {@link IJavaElement#ANNOTATION}, 
+ * {@link IJavaElement#LOCAL_VARIABLE} and {@link IJavaElement#TYPE_PARAMETER}.
+ * However clients should not assume that this set of element types is closed as
+ * other types of elements may be returned in the future, e.g. if new types
+ * of elements are added in the Java model. Clients can only assume that the
+ * {@link IJavaElement#getParent() parent} chain of this local element eventually leads 
+ * to the element from {@link #getElement()}.
+ *
+ * The local element being an {@link IAnnotation} is the most usal case. For example,
+ *
+ *    . searching for the references to the method <code>Annot.clazz()</code> in
+ * 
+ *             public class Test {
+ *                 void method() {
+ *                     @Annot(clazz=Test.class) int x;
+ *                 }
+ *             }
+ * 
+ *      will return one {@link MethodReferenceMatch} match whose local element
+ *      is the {@link IAnnotation} '<code>Annot</code>'.
+ *
+ *    . searching for the references to the type <code>Deprecated</code> in
+ * 
+ *             public class Test {
+ *                @Deprecated void method() {}
+ *             }
+ * 
+ *      will return one {@link TypeReferenceMatch} match whose local element
+ *      is the {@link IAnnotation} '<code>Deprecated</code>'.
+ *
+ *    . searching for the references to the field <code>CONST</code> in
+ * 
+ *              @Num(number= Num.CONST)
+ *              @interface Num {
+ *                  public static final int CONST= 42;
+ *                  int number();
+ *              }
+ * 
+ *      will return one {@link FieldReferenceMatch} match whose local element
+ *      is the {@link IAnnotation} '<code>Num</code>'.
+ *
+ * A local element may also be a {@link ILocalVariable} whose type is the referenced type. For example,
+ *
+ *    . searching for the references to the type <code>Test</code> in
+ * 
+ *         public class Test {
+ *             void foo() {
+ *                Test local;
+ *             }
+ *         }
+ * 
+ *      will return one {@link TypeReferenceMatch} match whose local element
+ *      is the {@link ILocalVariable} '<code>local</code>'.
+ *
+ * Or a local element may be an {@link ITypeParameter} that extends the referenced type. For example,
+ *
+ *    . searching for the references to the type <code>Test</code> in 
+ * 
+ *         public class X&lt;T extends Test&gt; {
+ *         }
+ * 
+ *      will return one {@link TypeReferenceMatch} match whose local element
+ *      is the {@link ITypeParameter} '<code>T</code>'.
+ * 
+ * @return the local element of this search match, or <code>null</code> if none.
+ * 
+ * @since 3.4
+ */
+public IJavaElement getLocalElement() {
+	return null;
+}
+</pre>
+See <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209996">bug 209996</a>
+for more details.
+</li>
+
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209996">209996</a>
+[search] Add a way to access the most local enclosing annotation for reference search matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222902">222902</a>
+[Javadoc] Missing description should not be warned in some cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217233">217233</a>
+[compiler] Add compiler API to call the batch compiler from a stand-alone application
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223495">223495</a>
+[assist] Member types of missing parametrized types are not proposed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223479">223479</a>
+[assist] Member types of missing types are not proposed in class body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223253">223253</a>
+NPE in TypeBinding.getName
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=223360">223360</a>
+[search] Huge error message if OOME while building workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222213">222213</a>
+Java model not updated after quick fix 'Add unimplemented methods'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97332">97332</a>
+[compiler] Add support for classpath specified in manifest file inside a jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218824">218824</a>
+[DOM/AST] incorrect code leads to IllegalArgumentException during AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183211">183211</a>
+[1.5][compiler] single static import for a field is ambiguous
+
+<a name="v_845"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 18, 2008
+<br>Project org.eclipse.jdt.core v_845
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_845">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new API <code>org.eclipse.jdt.core.JavaCore#getOptionForConfigurableSeverity(int)</code>
+    to link back problem IDs to options that configure problems:<br>
+<pre>
+	/**
+	 * Returns the option that can be used to configure the severity of the 
+	 * compiler problem identified by problemID if any, null otherwise. Non-null 
+	 * return values are taken from the constants defined by this class whose 
+	 * names start with COMPILER_PB and for which the possible values of the 
+	 * option are defined by { "error", "warning", "ignore" }. A null return 
+	 * value means that the provided problem ID is unknown or that it matches 
+	 * a problem whose severity cannot be configured.
+	 * @param problemID one of the problem IDs defined by {@link IProblem}
+	 * @return the option that can be used to configure the severity of the 
+	 *         compiler problem identified by problemID if any, null otherwise
+	 * @since 3.4
+	 */
+	public static String getOptionForConfigurableSeverity(int problemID) {...}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222399">222399</a>
+Regression in several Model performance tests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221680">221680</a>
+Classpath gets reset randomly in headless mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222458">222458</a>
+IType#getFullyQualifiedParameterizedName() is underspecified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221723">221723</a>
+Override method fails with and error saying &quot;1&quot; due to a java.lang.ArrayIndexOutOfBoundsException:
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218603">218603</a>
+[api] provide a mapping from problem id to preference key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219625">219625</a>
+[1.5][compiler] Generics related AbstractMethodError that is not given by Sun Java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216930">216930</a>
+[1.5][compiler] Wrong compiler error when using static method with same signature as non static one but with variable arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222457">222457</a>
+Javadoc fixes for IType#get*QualifiedName()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222080">222080</a>
+[assist] Wrong proposals order when completing on an item of an array
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222182">222182</a>
+[formatter] AIOOB in Util.getLineNumber(Util.java:438)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=156168">156168</a>
+[model] type separator is ignored in BinaryType.getFullyQualifiedName(enclosingTypeSeparator)
+
+<a name="v_844"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 11, 2008
+<br>Project org.eclipse.jdt.core v_844
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_844">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>CodeAssist: Added new API to give more information about completion context:<br>
+<ul>
+<li>CompletionContext#getEnclosingElement() - This method returns the innermost enclosing Java element which contains the completion location.
+<pre>
+public class X {
+	void foo() {
+		zzz| // ctrl+space at | location
+	}
+}
+</pre>
+<code>getEnclosingElement()</code> returns the IMethod named foo.
+</li>
+<li>CompletionContext#getVisibleElements(String) - This method returns the elements visible from the completion location.
+<pre>
+public class X {
+	p.Y f1;
+	p.Z f2;
+	void foo() {
+		p.Y l1;
+		p.Z l2;
+		zzz| // ctrl+space at | location
+	}
+}
+</pre>
+<code>getVisibleElements("Lp/Z;")</code> returns the IField named f2 and the ILocalVariable name l2.
+</li>
+</ul>
+
+<pre>
+public class CompletionRequestor {
+	...
+	
+	/**
+	 * Returns whether this requestor requires an extended context.
+	 * 
+	 * By default this method return <code>false</code>.
+	 * 
+	 * @return <code>true</code> if this requestor requires an extended context.
+	 * 
+	 * @see CompletionContext#isExtended()
+	 * 
+	 * @since 3.4
+	 */
+	public boolean isExtendedContextRequired() {...}
+	
+	/**
+	 * Sets whether this requestor requires an extended context.
+	 * 
+	 * @param require <code>true</code> if this requestor requires an extended context.
+	 * 
+	 * @see CompletionContext#isExtended()
+	 * 
+	 * @since 3.4
+	 */
+	public void setRequireExtendedContext(boolean require) {...}
+	
+	...
+}
+ </pre>
+ <pre>
+public class CompletionContext {
+	...
+	
+	/**
+	 * Returns whether this completion context is an extended context.
+	 * Some methods of this context can be used only if this context is an extended context but an extended context consumes more memory.
+	 * 
+	 * @return <code>true</code> if this completion context is an extended context.
+	 * 
+	 * @since 3.4
+	 */
+	public boolean isExtended() {...}
+	
+	/**
+	 * Returns the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 * The returned Java element and all Java elements in the same compilation unit which can be navigated to from the returned Java element are special Java elements:
+	 *
+	 * - they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation
+	 * - they are not updated if the buffer changes.
+	 * - they do not contain local types which are not visible from the completion location.
+	 * - they do not give information about categories. {@link IMember#getCategories()} will return an empty array
+	 * 
+	 * Reasons for returning <code>null</code> include:
+	 * 
+	 * - the compilation unit no longer exists
+	 * - the completion occurred in a binary type. However this restriction might be relaxed in the future.
+	 * 
+	 * @return the innermost enclosing Java element which contains the completion location or <code>null</code> if this element cannot be computed.
+	 * 
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 * 
+	 * @since 3.4
+	 */
+	public IJavaElement getEnclosingElement() {...}
+	
+	/**
+	 * Return the elements which are visible from the completion location and which can be assigned to the given type.
+	 * An element is assignable if its type can be assigned to a variable
+	 * of the given type, as specified in section 5.2 of <em>The Java Language
+	 * Specification, Third Edition</em> (JLS3).
+	 * A visible element is either:
+	 *
+	 * - a {@link ILocalVariable} - the element type is {@link ILocalVariable#getTypeSignature()}
+	 * - a {@link IField} - the element type is {@link IField#getTypeSignature()}
+	 * - a {@link IMethod} - the element type is {@link IMethod#getReturnType()}
+	 * 
+	 * Returned elements defined in the completed compilation unit are special Java elements:
+	 * 
+	 * - they are based on the current content of the compilation unit's buffer, they are not the result of a reconcile operation
+	 * - they are not updated if the buffer changes.
+	 * - they do not contain local types which are not visible from the completion location.
+	 * - they do not give information about categories. {@link IMember#getCategories()} will return an empty array
+	 * 
+	 * Note the array can be empty if:
+	 *
+	 * - the compilation unit no longer exists
+	 * - the completion occurred in a binary type. However this restriction might be relaxed in the future.
+	 * 
+	 * @param typeSignature elements which can be assigned to this type are returned.
+	 * 		If <code>null</code> there is no constraint on the type of the returned elements.
+	 * 
+	 * @return elements which are visible from the completion location and which can be assigned to the given type.
+	 * 
+	 * @exception UnsupportedOperationException if the context is not an extended context
+	 * 
+	 * @see #isExtended()
+	 * 
+	 * @since 3.4
+	 */
+	public IJavaElement[] getVisibleElements(String typeSignature) {...}
+	
+	...
+}
+ </pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221266">221266</a>
+Bad syntax error report on string literals containing escapes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202470">202470</a>
+[assist] provide all elements that are visible
+
+<a name="v_843"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 5, 2008
+<br>Project org.eclipse.jdt.core v_843
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_843">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new compiler option to control whether Exception and Throwable are
+    considered or not while reporting unused declared thrown exceptions.
+<pre>
+ * Compiler option ID: Reporting Unused Declared Thrown Exception Exempts Exception And Throwable.
+ *    When enabled, the compiler will issue an error or a warning when a 
+ *    method or a constructor is declaring a checked exception else than
+ *    java.lang.Throwable or java.lang.Exception as thrown,
+ *    but its body actually raises neither that exception, nor any other 
+ *    exception extending it. When disabled, the compiler will issue an 
+ *    error or a warning when a method or a constructor is declaring a 
+ *    checked exception (including java.lang.Throwable and 
+ *    java.lang.Exception) as thrown, but its body actually raises 
+ *    neither that exception, nor any other exception extending it. 
+ *    The severity of the unused declared thrown exception problem is 
+ *    controlled with option COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION.
+ *    This diagnostic is further tuned by options
+ *    COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE
+ *    and COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_WHEN_OVERRIDING.
+ *
+ *    Option id: "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable"
+ *    Possible values: { "enabled", "disabled" }
+ *    Default: "enabled"
+ </pre>
+(note that the specification for unusedDeclaredThrownException has been
+amended accordingly, and that another option that had been added in 3.4M5 but
+never surfaced in the IDE has been withdrawn; see 
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=219461">bug 219461</a>
+for details)
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221215">221215</a>
+[assist] NPE in problem reporter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219461">219461</a>
+[compiler][options] Limit warning for unecessary unchecked exceptions to Throwable and Exception
+
+<a name="v_842"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - March 4, 2008
+<br>Project org.eclipse.jdt.core v_842
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_842">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added one new <code>IJavaSearchConstants</code> fine grained search API
+constant to reduce the search to type references used in the <code>instanceof</code>
+pattern (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221130">bug 221130</a>):
+<pre>
+/**
+ * Return only type references used as an instance of.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int INSTANCEOF_TYPE_REFERENCE = 0x100000;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221110">221110</a>
+[search] NPE at org.eclipse.jdt.internal.compiler.util.SimpleLookupTable.removeKey
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=221130">221130</a>
+[search] No fine-grain search for instanceof criteria
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220565">220565</a>
+adapt to new API ICompilationUnit.applyEdits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219937">219937</a>
+Javadoc content assist does not propose method inherited from interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167262">167262</a>
+[1.5][compiler] @Override specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220967">220967</a>
+[compiler] Extra secondary error in presence of missing type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220811">220811</a>
+NPE trying to update classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215841">215841</a>
+[search] Opening Type Hierarchy extremely slow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220542">220542</a>
+Trailing separator in classpath entry lost
+
+<a name="v_841"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - February 27, 2008
+<br>Project org.eclipse.jdt.core v_841
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_841">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API added on ICompilationUnit to apply text edits to its buffer. 
+<pre>
+public interface ICompilationUnit {
+	...
+	
+   /**
+    * Applies a text edit to the compilation unit's buffer. 
+    * 
+    * @param edit the edit to apply
+    * @param monitor the progress monitor to use or <code>null</code> if
+    *                no progress should be reported
+    * @return the undo edit 
+    * @throws JavaModelException if this edit can not be applied to the
+    *                            compilation unit's buffer. Reasons include:
+    * This compilation unit does not exist
+    * ({@link IJavaModelStatusConstants#ELEMENT_DOES_NOT_EXIST}).
+    * The provided edit can not be applied as there is a problem with the
+    * text edit locations ({@link IJavaModelStatusConstants#BAD_TEXT_EDIT_LOCATION}).
+    * 
+    * @since 3.4
+    */
+    public UndoEdit applyTextEdit(TextEdit edit, IProgressMonitor monitor) throws JavaModelException;
+    ...
+}
+</pre>
+Implementors of IBuffer can now additionally implement <code>IBuffer.ITextEditCapability</code>
+and provide the implementation for <code>applyTextEdit</code>. Calls to <code>ICompilationUnit.applyTextEdit</code>
+will then be forwarded to this API.
+</li>
+<li>Compiler is now also able to recover missing parameterized types (e.g. <code>Zork&lt;String&gt;</code>).</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196200">196200</a>
+[jsr269] Need annotation bindings even when code contains errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220361">220361</a>
+[1.5][compiler] Compiler incorrectly rejects static raw member type as parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220111">220111</a>
+[1.5][compiler] Type mismatch errors on identical types; code compiles with javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=117694">117694</a>
+[api] Applying edits to a ICompilationUnit.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220453">220453</a>
+Addition of externalFoldersManager inside the java model manager breaks retrieval of JavaCore.getOptions() with no headless eclipse
+
+	
+
+
+<a name="v_840"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - February 26, 2008
+<br>Project org.eclipse.jdt.core v_840
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_840">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>External library folders are now supported. One can use the existing API <code>JavaCore#newLibraryEntry(...)</code> with 
+     a file system path to an external library folder to add this folder on the build path. Note that one can also use an external source folder
+     as a source attachment using the same API.</li>
+<li>Code Assist: Added API to give information about the completed token location.<br>
+Clients can call <code>CompletionContext#getTokenLocation()</code> to know if the completed token is at the start of the member
+or at the start of a statement. In the future this API could be improved and more locations could be recognized.
+<pre>
+public class CompletionContext {
+	...
+	
+	/**
+	 * The completed token is the first token of a member declaration.
+	 * e.g.
+	 *
+	 * public class X {
+	 *   Foo| // completion occurs at |
+	 * }
+	 * 
+	 * @see #getTokenLocation()
+	 * 
+	 * @since 3.4
+	 */
+	public static final int TL_MEMBER_START = 1;
+	
+	/**
+	 * The completed token is the first token of a statement.
+	 * e.g.
+	 *
+	 * public class X {
+	 *   public void bar() {
+	 *     Foo| // completion occurs at |
+	 *   }
+	 * }
+	 * 
+	 * @see #getTokenLocation()
+	 * 
+	 * @since 3.4
+	 */
+	public static final int TL_STATEMENT_START = 2;
+	
+	/**
+	 * Returns the location of completion token being proposed.
+	 * The returned location is a bit mask which can contain some values
+	 * of the constants declared on this class whose name starts with <code>TL</code>,
+	 * or possibly values unknown to the caller.
+	 * 
+	 * The set of different location values is expected to change over time.
+	 * It is strongly recommended that clients do <b>not</b> assume that
+	 * the location contains only known value, and code defensively for 
+	 * the possibility of unexpected future growth.
+	 * 
+	 * @return the location
+	 * 
+	 * @since 3.4
+	 */
+	public int getTokenLocation() {...}
+	
+	...
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218397">218397</a>
+[search] Can't find references of generic local class.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220171">220171</a>
+[assist] No suggesting 'hasGenericError' variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182537">182537</a>
+Enhance classpath container to support external class folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202467">202467</a>
+[assist] provide info what is completed
+
+<a name="v_839"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - February 22, 2008
+<br>Project org.eclipse.jdt.core v_839
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_839">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The compiler is now better resilient to missing types referenced from sources. This will improve secondary errors, 
+and all JDT stack manipulating DOM AST and bindings. Annotation processors are also now able to see such missing types
+(also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196200">196200</a>). Note that with current support, 
+parameterized types are not fully recovered.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_838"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - February 19, 2008
+<br>Project org.eclipse.jdt.core v_838
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_838">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=217995">217995</a>
+Documentation for JavaCore#COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION [...] fails to make crystal-clear the cases of Exception and Throwable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217910">217910</a>
+Parameter annotations should be displayed in front of each parameter in disassembled code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=219064">219064</a>
+Javadoc of AST#newTypeDeclaration() refers to inexistent setEnumeration(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212096">212096</a>
+LocalVariable.hashCode throws NPE when this.parent is null
+
+<a name="v_837"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M6 - February 12, 2008
+<br>Project org.eclipse.jdt.core v_837
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_837">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=217907">217907</a>
+Compact mode in the disassembler should also work for annotation values
+
+<a name="v_836"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - February 5, 2008 - 3.4 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_836
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_836">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=212100">212100</a>
+[dom] Can't create binding to inner class
+
+<a name="v_835"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - February 3, 2008
+<br>Project org.eclipse.jdt.core v_835
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_835">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Code formatter: 3 new options were added to better handle the addition of new lines after annotations.
+<pre>
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER
+ * FORMATTER / Option to insert a new line after an annotation on a member (package, class, method, field declaration)
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member"
+ *     - possible values:   { INSERT, DO_NOT_INSERT }
+ *     - default:           INSERT
+ * 
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER
+ * FORMATTER / Option to insert a new line after an annotation on a parameter
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
+ *     - possible values:   { INSERT, DO_NOT_INSERT }
+ *     - default:           DO_NOT_INSERT
+ *
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE
+ * FORMATTER / Option to insert a new line after an annotation on a local variable
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
+ *     - 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=122247">bug 122247</a><br>
+Also note that previously available code formatter constant FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION has been deprecated.<br>
+All new options must be enabled to activate old strategy.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210425">210425</a>
+[1.5][compiler] @SuppressWarnings(&quot;unchecked&quot;)  not considered necessary for unconstrained generic parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217059">217059</a>
+Regression in Model performance test testProjectFindUnknownType()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212912">212912</a>
+Javadoc bugs in IMemberValuePair
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122247">122247</a>
+[formatter] add support to handle parameter annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216686">216686</a>
+[1.5][compiler] Failures of inference and overload resolution
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216897">216897</a>
+[compiler][options] Compile error when disabling 'Ignore Unchecked Exception'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216683">216683</a>
+[1.5][compiler] Confusion when homnymous types in local and enclosing scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202490">202490</a>
+Javadoc of JavaCore options hard to use
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216291">216291</a>
+[1.5][compiler] Compiler messages should use &quot;1.5&quot; instead of &quot;5.0&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216875">216875</a>
+[search] Field- and LocalVariableReferenceMatch confuse read/write for field access on LHS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216895">216895</a>
+NPE found in .log while running ClasspathTests
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216817">216817</a>
+JavaCore.getEncoding() fails when there is no workspace.
+
+<a name="v_834"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - January 29, 2008
+<br>Project org.eclipse.jdt.core v_834
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_834">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=216692">216692</a>
+[1.5][compiler] Protected type not visible in subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216565">216565</a>
+[1.5][compiler] Cannot convert T to T
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216747">216747</a>
+Should use AVOID_NATURE_CONFIG when updating project references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208260">208260</a>
+[search] Document the pattern syntax for SearchPattern#createPattern(String, ..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=130778">130778</a>
+Invalid annotation elements cause no annotation to be in the AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210524">210524</a>
+[batch][compiler][options] -warn:allDeprecation -warn:-deprecation does not behave as documented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216100">216100</a>
+[1.5][compiler] Brigdes are not correcly generated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213249">213249</a>
+Regression in TypeHierarchy when a super-class can't be resolved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215681">215681</a>
+Type Hierarchy crashes in some cases of user input
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215333">215333</a>
+[batch][compiler][options] the documentation for specialParamHiding needs improvement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100278">100278</a>
+[compiler] Add compiler warning for explicitly declared runtime exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191090">191090</a>
+[compiler] Preserve annotations for the problem methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215843">215843</a>
+[1.5][compiler] Compiler error with generic covariant
+
+<a name="v_833"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - January 22, 2008
+<br>Project org.eclipse.jdt.core v_833
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_833">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=215976">215976</a>
+PublicScanner doesn't contain all the fix of Scanner
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215759">215759</a>
+DOM AST regression tests should be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=215858">215858</a>
+[AST/DOM] CCE when using ASTParser.setFocalPosition(int) with the position of a field declaration name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127739">127739</a>
+IAE in Signature.getReturnType while hovering a method of type having $ in its name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210746">210746</a>
+Class folder in build path does not refresh properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138882">138882</a>
+Should surface failure to get CU's contents
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214972">214972</a>
+[1.5][compiler] Wrong Signature for methods inside InnerTypes with generics .
+
+<a name="v_832"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - January 15, 2008
+<br>Project org.eclipse.jdt.core v_832
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_832">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=215019">215019</a>
+[search] JavaSearchBugsTests.testBug181488a is randomly failing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213703">213703</a>
+[search] Indexing job progress should be more detailed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186540">186540</a>
+[search] engine should allocate progress monitor ticks for reporting package declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214731">214731</a>
+[batch][compiler] ClasspathJar#getPath does not honor its contract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211588">211588</a>
+[batch][compiler][options] undue interactions between enableJavadoc, javadoc and allJavadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213427">213427</a>
+EFS throws NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181981">181981</a>
+[model] Linked Source Folders with Parallel package structure do not work with occurrences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213692">213692</a>
+[compiler] Wrong unnecessary NON-NLS diagnostic after syntax recovery
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214450">214450</a>
+annotation is broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=176831">176831</a>
+[search] No search results due to malformed search scope
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214647">214647</a>
+[dom] NPE in MethodBinding.getParameterAnnotations(..)
+
+
+<a name="v_831"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - January 8, 2008
+<br>Project org.eclipse.jdt.core v_831
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_831">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=209936">209936</a>
+[javadoc] Missing code implementation in the compiler on inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210681">210681</a>
+Code assist fails to propose inner type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211881">211881</a>
+[assist] Code assist fails inside an if statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212153">212153</a>
+stack overflow when press ctrl+space
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210518">210518</a>
+[batch][compiler][options] -warn:unused wrongly behaves as -warn:+unused
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214002">214002</a>
+[dom] NPE in MethodBinding.getParameterAnnotations()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153765">153765</a>
+[search] Reference to package is not found in qualified annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213284">213284</a>
+[formatter] NPE on formatting region
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213283">213283</a>
+[formatter] AIOOBE when formatting region
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213570">213570</a>
+IncrementalTests#testRenameMainType() fails with IBM JRE 6.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=213509">213509</a>
+[dom] IMethodBinding.getParameterAnnotations returns annotations for wrong parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204749">204749</a>
+[1.5][javadoc] NPE in JavadocQualifiedTypeReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212834">212834</a>
+[dom] IMethodBinding.getParameterAnnotations does not return annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211718">211718</a>
+[1.5][compiler] compiler error with nested enum in class using generics
+
+<a name="v_830"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M5 - December 18, 2007
+<br>Project org.eclipse.jdt.core v_830
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_830">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=212857">212857</a>
+[dom] AST has wrong source range after parameter with array-valued annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212224">212224</a>
+Unresolvable type causes ArrayOutOfBoundsException in IType.resolveType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=212769">212769</a>
+SetClasspathOperation no longer adds project for refresh
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=164862">164862</a>
+[ast rewrite] ListRewrite.remove(...) does not remove inserted nodes
+
+<a name="v_829"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - December 12, 2007 - 3.4 MILESTONE 4
+<br>Project org.eclipse.jdt.core v_829
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_829">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=212599">212599</a>
+[search] fine grained search must not report matches in Javadoc
+
+<a name="v_828"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - December 8, 2007
+<br>Project org.eclipse.jdt.core v_828
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_828">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=209993">209993</a>
+[1.5][search] Generic search does not work properly while using BindingKey
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211781">211781</a>
+[search] clarify 'ALLOCATION_EXPRESSION_TYPE_REFERENCE'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211779">211779</a>
+[search] better name for SUPERTYPE_TYPE_REFERENCE?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211872">211872</a>
+[search] References to annotations not found in class file without source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210094">210094</a>
+Creating type hierarchy does not report progress
+
+<a name="v_827"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - December 4, 2007
+<br>Project org.eclipse.jdt.core v_827
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_827">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added <code>IJavaSearchConstants</code> API constants for fine grained search
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155013">bug 155013</a>).<br>
+These constants are additional flags which should be set on <code>limitTo</code>
+parameter while calling <code>SearchPattern.createPattern(...)</code> methods.<br>
+They can be combined to get results of multiple fine grain search in one single query.
+<p>
+Here is the exhaustive list of these fine grain search flags:<pre>
+
+/**
+ * Return only type references used as the type of a field declaration.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int FIELD_DECLARATION_TYPE_REFERENCE = 0x40;
+
+/**
+ * Return only type references used as the type of a local variable declaration.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE = 0x80;
+
+/**
+ * Return only type references used as the type of a method parameter
+ * declaration.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int PARAMETER_DECLARATION_TYPE_REFERENCE = 0x100;
+
+/**
+ * Return only type references used as a super type or as a super interface.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int SUPERTYPE_TYPE_REFERENCE = 0x200;
+
+/**
+ * Return only type references used in a throws clause.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int THROWS_CLAUSE_TYPE_REFERENCE = 0x400;
+
+/**
+ * Return only type references used in a cast expression.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int CAST_TYPE_REFERENCE = 0x800;
+
+/**
+ * Return only type references used in a catch header.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int CATCH_TYPE_REFERENCE = 0x1000;
+
+/**
+ * Return only type references used in class instance creation.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * Example:
+ * 	public class Test {
+ * 		Test() {}
+ * 		static Test bar()  {
+ * 			return new <i>Test</i>();
+ * 		}
+ * 	}
+ *
+ * Searching references to the type <code>Test</code> using this flag in the
+ * above snippet will match only the reference in italic.
+ * 
+ * Note that array creations are not returned when using this flag.
+ * 
+ * @since 3.4
+ * @category limitTo
+ */
+int CLASS_INSTANCE_CREATION_TYPE_REFERENCE = 0x2000;
+
+/**
+ * Return only type references used as a method return type.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int RETURN_TYPE_REFERENCE = 0x4000;
+
+/**
+ * Return only type references used in an import declaration.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int IMPORT_DECLARATION_TYPE_REFERENCE = 0x8000;
+
+/**
+ * Return only type references used as an annotation.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int ANNOTATION_TYPE_REFERENCE = 0x10000;
+
+/**
+ * Return only type references used as a type argument in a parameterized
+ * type or a parameterized method.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int TYPE_ARGUMENT_TYPE_REFERENCE = 0x20000;
+
+/**
+ * Return only type references used as a type variable bound.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int TYPE_VARIABLE_BOUND_TYPE_REFERENCE = 0x40000;
+
+/**
+ * Return only type references used as a wildcard bound.
+ *
+ * When this flag is set, only {@link TypeReferenceMatch} matches will be
+ * returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int WILDCARD_BOUND_TYPE_REFERENCE = 0x80000;
+
+/**
+ * Return only super field accesses or super method invocations (e.g. using the
+ * <code>super</code> qualifier).
+ *
+ * When this flag is set, the kind of returned matches will depend on the
+ * specified nature of the searched element:
+ * 	. for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+ * 		matches will be returned,
+ * 	. for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+ * 		matches will be returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int SUPER_REFERENCE = 0x1000000;
+
+/**
+ * Return only qualified field accesses or qualified method invocations.
+ *
+ * When this flag is set, the kind of returned matches will depend on the
+ * specified nature of the searched element:
+ * 	. for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+ * 		matches will be returned,
+ * 	. for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+ * 		matches will be returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int QUALIFIED_REFERENCE = 0x2000000;
+
+/**
+ * Return only primary field accesses or primary method invocations (e.g. using
+ * the <code>this</code> qualifier).
+ *
+ * When this flag is set, the kind of returned matches will depend on the
+ * specified nature of the searched element:
+ * 	. for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+ * 		matches will be returned,
+ * 	. for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+ * 		matches will be returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int THIS_REFERENCE = 0x4000000;
+
+/**
+ * Return only field accesses or method invocations without any qualification.
+ *
+ * When this flag is set, the kind of returned matches will depend on the
+ * specified nature of the searched element:
+ * 	. for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+ * 		matches will be returned,
+ * 	. for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+ * 		matches will be returned.
+ *
+ * @since 3.4
+ * @category limitTo
+ */
+int IMPLICIT_THIS_REFERENCE = 0x8000000;
+</pre>
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209642">bug 209642</a> required the index version to be incremented. 
+    Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress 
+    dialogs).
+</li>
+<li>Search Engine is now able to find references to annotations inside class files which do not have any attached sources.
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211366">bug 211366</a> for more details).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211857">211857</a>
+[search] Standard annotations references not found on binary fields and methods when no source is attached
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211366">211366</a>
+[search] does not return references to types in binary classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211762">211762</a>
+ConcurrentModificationException initializing Java Tools
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210498">210498</a>
+Extra type in hierarchy when focusing on local class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211609">211609</a>
+[compiler][1.5] Unable to resolve annotations defined with a Class attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209936">209936</a>
+[javadoc] Missing code implementation in the compiler on inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206597">206597</a>
+IType#resolveType(String) is not implemented for binary types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207775">207775</a>
+incomplete source range for anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211290">211290</a>
+Wrong delta renaming .classpath file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207890">207890</a>
+Checking out JFace and then SWT leads to a strange state
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209642">209642</a>
+[index] Improve search for annotation references by using a specific category
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=155013">155013</a>
+[search] [DCR] More finegrained options for Java search
+
+<a name="v_826"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - November 27, 2007
+<br>Project org.eclipse.jdt.core v_826
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_826">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Tuned the compiler diagnosis for unused <code>@SuppressWarnings</code> to only complain if the relevant warnings were effectively
+enabled when compiling. So if you turn off certain warnings, then the compiler is not going to suggest getting rid of existing <code>@SuppressWarnings</code>
+in your code, until you will have enabled these back, and the compiler will have proved that there is no occurrence of them.
+</li>
+<li>Added API <code>IMethod#getDefaultValue()</code> to retrieve the default value of an annotation method.</li>
+<li>Added API <code>IMemberValuePair#K_SIMPLE_NAME</code> to indicate that the value kind of the value is a simple name reference.</li>
+<li>Added API <code>IJavaProject#findElement(String, WorkingCopyOwner)</code> to retrieve a <code>IJavaElement</code> from a binding key.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192670">192670</a>
+[api] need api to get from binding key to a IJavaElement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210567">210567</a>
+[1.5][search] Parameterized type reference not found when used in type parameter bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210922">210922</a>
+ArrayStoreException when formatting set of regions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210353">210353</a>
+Improve documentation for overridingPackageDefaultMethod option in JavaCore#getDefaultOptions' javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208541">208541</a>
+[formatter] Formatter does not format whole region/selection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210638">210638</a>
+[Debug] Can't restore Breakpoints view : concurrent access/hashmap
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210691">210691</a>
+[search] Type references position invalid in import references when using &quot;*&quot; pattern
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210689">210689</a>
+[search] Type references are not found in import declarations when JUnit tests only use working copies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210565">210565</a>
+Null value is obtained from IMemberValuePair, when type is Enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209958">209958</a>
+Support getting default value from IMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210310">210310</a>
+IJavaElementDelta contains wrong data after APT processor is enabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210213">210213</a>
+[1.5][compiler] Unused SuppressWarnings shouldn't complain if warnings are not even enabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210070">210070</a>
+Type hierarchy unpredictable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210404">210404</a>
+Method parameters are not recovered when followed by an annotation with a syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210422">210422</a>
+[compiler] Need to have local bindings created in error cases
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=210273">210273</a>
+Content Assist cannot cope with explicit parameter types
+
+<a name="v_825"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - November 20, 2007
+<br>Project org.eclipse.jdt.core v_825
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_825">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=209623">209623</a>
+NullPointerexception on List.toArray + F3
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209823">209823</a>
+IAnnotation#getSourceRange() and #getNameRange() throw JME on annotation of ILocalVariable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209961">209961</a>
+[compiler][apt] NPE in apt processing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209475">209475</a>
+BindingKey.isRawType() doesn't return the right result
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209222">209222</a>
+Stack overflow in TypeHierarchyPerfTest
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209661">209661</a>
+ILocalVariable for method parameter misses annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209655">209655</a>
+[jsr199] export package should specify x-internal:=true
+
+<a name="v_824"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - November 13, 2007
+<br>Project org.eclipse.jdt.core v_824
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_824">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new compiler option to find redundant superinterfaces.
+<pre>
+* COMPILER / Reporting Redundant Superinterface
+*    When enabled, the compiler will issue an error or a warning if a type
+*    explicitly implements an interface that is already implemented by any 
+*    of its supertypes.
+*     - option id: "org.eclipse.jdt.core.compiler.problem.redundantSuperinterface"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77918">bug 77918</a>)
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200951">200951</a>
+[ast rewrite] removing parentheses yields syntax error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209319">209319</a>
+[ast rewrite] @SuppressWarning is inserting an extra line break
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208383">208383</a>
+IProblem.UnusedWarningToken has wrong category
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209153">209153</a>
+[1.5][compiler] VerifyError due to generic cast to a non visible type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209150">209150</a>
+[dom] Recovered type binding for &quot;java.lang.Object&quot; information are not complete
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186410">186410</a>
+[dom] StackOverflowError due to endless superclass bindings hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77918">77918</a>
+[compiler] Unnecessary implementation of interface in class declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208995">208995</a>
+Static method hides method from instance when using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209054">209054</a>
+[search] for references to method finds wrong interface call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208234">208234</a>
+Specify that CodeFormatter is not intended to be subclassed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138018">138018</a>
+When passed unsupported javac -warn warning options, fail gracefully &amp; ignore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206423">206423</a>
+Optimization opportunity in DefaultProblemFactory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208960">208960</a>
+Internal Compiler Error on valid code with particular combination of org.eclipse.jdt.core.compiler.codegen.targetPlatform and o.e.j.c.c.source
+
+<a name="v_823"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M4 - November 6, 2007
+<br>Project org.eclipse.jdt.core v_823
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_823">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=208807">208807</a>
+JavaCore.getDefaultOptions() throws an exception when there is no workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178596">178596</a>
+[search] Search for method references does not find references to interface method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207754">207754</a>
+[AST][DOM] source range of ParenthesizedExpression does not include the parenthesis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=187430">187430</a>
+Unresolved types surfacing through DOM AST for annotation default values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207929">207929</a>
+No import added to declaring class if static member is 'class'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207572">207572</a>
+[select] codeselect not available if unterminated string literal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111093">111093</a>
+More problems with IMethodBinding#isSubsignature(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206017">206017</a>
+[compiler] Type mistmatch on field declaration should be reported against initialization expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208263">208263</a>
+[ast rewrite] performance problems with lots of changes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207758">207758</a>
+[1.5][compiler] Unused SupressWarnings detection should consider more error situations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207573">207573</a>
+[1.5][compiler] Internal compiler error: ClassCastException / ArrayBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208030">208030</a>
+[1.7][compiler] Missing unused type argument warning for constructor invocations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=208386">208386</a>
+Annotation Javadoc glitches
+
+<a name="v_822"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 31, 2007 - 3.4 MILESTONE 3
+<br>Project org.eclipse.jdt.core v_822
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_822">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added API <code>CodeFormatter#format(int, String, IRegion[], int, String)</code> to allow the formatting of a set of
+	 <code>org.eclipse.jface.text.IRegion</code>s.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203304">203304</a>
+Allow to format set of regions
+
+<a name="v_821"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 27, 2007
+<br>Project org.eclipse.jdt.core v_821
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_821">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new compiler optional warning for diagnosing unnecessary @SuppressWarnings annotation. This is mostly helpful
+to get rid of <code>@SupressWarnings(...)</code> annotations which were necessary a while ago, but are no longer useful.
+Note that <code>@SuppressWarnings("all")</code> is still silencing the warning for unnecessary <code>@SuppressWarnings</code>,
+as it is the master switch to silence ALL warnings.
+Also added option: <code>JavaCore.COMPILER_PB_UNUSED_WARNING_TOKEN</code> and problem ID
+<code>IProblem.UnusedWarningToken</code>.
+<pre>
+* COMPILER / Reporting Unnecessary @SuppressWarnings
+*    When enabled, the compiler will issue an error or a warning when encountering @SuppressWarnings annotation 
+*    for which no corresponding warning got detected in the code. This diagnostic is provided to help developers to get
+*    rid of transient @SuppressWarnings no longer needed. Note that <code>@SuppressWarnings("all")</code> is still 
+*    silencing the warning for unnecessary <code>@SuppressWarnings</code>, as it is the master switch to silence ALL warnings.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedWarningToken"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127533">bug 127533</a>)
+</li>
+<li>Added the following APIs to support annotation in the Java model (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79112">bug 79112</a>
+     for more details):
+     <ul>
+     <li><pre>
+public interface IAnnotation extends IJavaElement, ISourceReference {
+	String getElementName();
+	IMemberValuePair[] getMemberValuePairs() throws JavaModelException;
+	ISourceRange getNameRange() throws JavaModelException;
+	int getOccurrenceCount();
+}    </pre></li>
+     <li><pre>
+public interface IMemberValuePair {
+	int K_INT = 1;
+	int K_BYTE = 2;
+	int K_SHORT = 3;
+	int K_CHAR = 4;
+	int K_FLOAT = 5;
+	int K_DOUBLE = 6;
+	int K_LONG = 7;
+	int K_BOOLEAN = 8;
+	int K_STRING = 9;
+	int K_ANNOTATION = 10;
+	int K_CLASS = 11;
+	int K_QUALIFIED_NAME = 12;
+	int K_UNKNOWN = 13;
+	String getMemberName();
+	Object getValue();
+	int getValueKind();
+}    </pre></li>
+     <li><pre>
+public interface IAnnotatable {
+	IAnnotation getAnnotation(String name);
+	IAnnotation[] getAnnotations() throws JavaModelException;
+}    </pre><code>IField</code>, <code>IMethod</code>, <code>IType</code>, <code>IPackageDeclaration</code>, and <code>ILocalVariable</code>
+     now implement this interface.</li>
+     <li><pre>
+public interface IJavaElement extends IAdaptable {
+	...
+	int ANNOTATION = 16;
+	...
+}    </pre></li>
+     <li><pre>
+public interface IJavaElementDelta {
+	...
+	public int F_ANNOTATIONS = 0x400000;
+	public IJavaElementDelta[] getAnnotationDeltas();	
+	...
+}    </pre></li>
+     </ul>
+</li>
+<li>Code Assist: Added API <code>CompletionRequestor#CompletionRequestor(boolean ignoreAll)</code> to be able to ignore all completion kinds by default instead of propose all completion kinds by default.
+</li>
+<li>Code Assist: Improved code assist inside an <code>if</code> statement with an <code>instanceof</code> expression as condition.<br>
+When a member access is completed in this case then the members of the <code>instanceof</code> type are proposed and the receiver is casted to this type.
+<pre>
+Object x = ... ;
+if (x instanceof IType) {
+   x.get|code assist
+</pre>
+The method <code>IType#getFullyQualifiedName()</code> will be proposed and the receiver will be casted to <code>IType</code>.
+The completion string will be '((IType)x).getFullyQualifiedName()'.<br>
+<br>
+These proposals will be proposed with the new proposal kinds <code>CompletionProposal#METHOD_REF_WITH_CASTED_RECEIVER</code> and
+<code>CompletionProposal#FIELD_REF_WITH_CASTED_RECEIVER</code>.<br>
+These new proposals require new API on CompletionProposal to be usable by client.
+<pre>
+public class CompletionProposal {
+   ...
+
+   /**
+    * Completion is a reference to a method with a casted receiver.
+    * This kind of completion might occur in a context like
+    * &lt;code&gt;"receiver.fo^();"&lt;/code&gt; and complete it to
+    * &lt;code&gt;""((X)receiver).foo();"&lt;/code&gt;.
+    * &lt;p&gt;
+    * The following additional context information is available
+    * for this kind of completion proposal at little extra cost:
+    * &lt;ul&gt;
+    * &lt;li&gt;{@link #getDeclarationSignature()} -
+    * the type signature of the type that declares the method that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getFlags()} -
+    * the modifiers flags of the method that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getName()} -
+    * the simple name of the method that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getReceiverSignature()} -
+    * the type signature of the receiver type. It's the type of the cast expression.
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getSignature()} -
+    * the method signature of the method that is referenced
+    * &lt;/li&gt;
+    * &lt;/ul&gt;
+    * &lt;/p&gt;
+    * 
+    * @see #getKind()
+    * 
+    * @since 3.4
+    */
+    public static final int METHOD_REF_WITH_CASTED_RECEIVER;
+
+   /**
+    * Completion is a reference to a field with a casted receiver.
+    * This kind of completion might occur in a context like
+    * &lt;code&gt;"recevier.ref^ = 0;"&lt;/code&gt; and complete it to
+    * &lt;code&gt;"((X)receiver).refcount = 0;"&lt;/code&gt;.
+    * &lt;p&gt;
+    * The following additional context information is available
+    * for this kind of completion proposal at little extra cost:
+    * &lt;ul&gt;
+    * &lt;li&gt;{@link #getDeclarationSignature()} -
+    * the type signature of the type that declares the field that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getFlags()} -
+    * the modifiers flags (including ACC_ENUM) of the field that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getName()} -
+    * the simple name of the field that is referenced
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getReceiverSignature()} -
+    * the type signature of the receiver type. It's the type of the cast expression.
+    * &lt;/li&gt;
+    * &lt;li&gt;{@link #getSignature()} -
+    * the type signature of the field's type (as opposed to the
+    * signature of the type in which the referenced field
+    * is declared)
+    * &lt;/li&gt;
+    * 
+    * &lt;/ul&gt;
+    * &lt;/p&gt;
+    * 
+    * @see #getKind()
+    * 
+    * @since 3.4
+    */
+   public static final int FIELD_REF_WITH_CASTED_RECEIVER;
+
+   /**
+    * Returns the type signature or package name of the relevant
+    * receiver in the context, or &lt;code&gt;null&lt;/code&gt; if none.
+    * &lt;p&gt;
+    * This field is available for the following kinds of
+    * completion proposals:
+    * &lt;ul&gt;
+    *  &lt;li&gt;&lt;code&gt;FIELD_REF_WITH_CASTED_RECEIVER&lt;/code&gt; - type signature
+    * of the type that cast the receiver of the field that is referenced&lt;/li&gt;
+    *  &lt;li&gt;&lt;code&gt;METHOD_REF_WITH_CASTED_RECEIVER&lt;/code&gt; - type signature
+    * of the type that cast the receiver of the method that is referenced&lt;/li&gt;
+    * &lt;/ul&gt;
+    * For kinds of completion proposals, this method returns
+    * &lt;code&gt;null&lt;/code&gt;. Clients must not modify the array
+    * returned.
+    * &lt;/p&gt;
+    * 
+    * @return a type signature or a package name (depending
+    * on the kind of completion), or &lt;code&gt;null&lt;/code&gt; if none
+    * @see Signature
+    * 
+    * @since 3.4
+    */
+   public char[] getReceiverSignature() {}
+
+   /**
+    * Returns the character index of the start of the
+    * subrange in the source file buffer containing the
+    * relevant receiver of the member being completed. This
+    * receiver is an expression.
+    * 
+    * &lt;p&gt;
+    * This field is available for the following kinds of
+    * completion proposals:
+    * &lt;ul&gt;
+    *  &lt;li&gt;&lt;code&gt;FIELD_REF_WITH_CASTED_RECEIVER&lt;/code&gt;&lt;/li&gt;
+    *  &lt;li&gt;&lt;code&gt;METHOD_REF_WITH_CASTED_RECEIVER&lt;/code&gt;&lt;/li&gt;
+    * &lt;/ul&gt;
+    * For kinds of completion proposals, this method returns &lt;code&gt;0&lt;/code&gt;.
+    * &lt;/p&gt;
+    * 
+    * @return character index of receiver start position (inclusive)
+    * 
+    * @since 3.4
+    */
+   public int getReceiverStart() {}
+
+   /**
+    * Returns the character index of the end (exclusive) of the subrange
+    * in the source file buffer containing the
+    * relevant receiver of the member being completed.
+    * 
+    * * &lt;p&gt;
+    * This field is available for the following kinds of
+    * completion proposals:
+    * &lt;ul&gt;
+    *  &lt;li&gt;&lt;code&gt;FIELD_REF_WITH_CASTED_RECEIVER&lt;/code&gt;&lt;/li&gt;
+    *  &lt;li&gt;&lt;code&gt;METHOD_REF_WITH_CASTED_RECEIVER&lt;/code&gt;&lt;/li&gt;
+    * &lt;/ul&gt;
+    * For kinds of completion proposals, this method returns &lt;code&gt;0&lt;/code&gt;.
+    * &lt;/p&gt;
+    * 
+    * @return character index of receiver end position (exclusive)
+    * 
+    * @since 3.4
+    */
+   public int getReceiverEnd() {}
+
+   ...
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=127533">127533</a>
+[1.5][compiler] warning on unused @SuppressWarnings annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207445">207445</a>
+IMemberValuePair with heterogenous array values should be of kind K_UNKNOWN
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207257">207257</a>
+[search] SearchEngine returns incorrectly typed SearchMatch when searching for local variable declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207441">207441</a>
+Wrong delta for files created in folders that are on a java project as classes folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207465">207465</a>
+[assist] CompletionRequestor javadoc doesn't specify if 'isIgnored' has an effect on required proposals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193210">193210</a>
+[1.5][compiler] Internal compiler error java.lang.NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193909">193909</a>
+improve content assist after 'instanceof'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207299">207299</a>
+[1.5][compiler] StackOverflow when eliminating type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207418">207418</a>
+Need API on CompletionRequestor to ignore all proposals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79112">79112</a>
+[1.5] [model] accessing annotation on Java elements
+
+<a name="v_820"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 23, 2007
+<br>Project org.eclipse.jdt.core v_820
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_820">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new compiler participant API to notify participants when a project's build is finished
+(see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=180107">bug 180107</a>):
+<pre>
+/**
+ * Notifies this participant that a build has finished for the project.
+ * This will be sent, even if buildStarting() was not sent when no source files needed to be compiled
+ * or the build failed.
+ * Only sent to participants interested in the project.
+ * @param project the project about to build
+ * @since 3.4
+  */
+public void buildFinished(IJavaProject project)
+</pre>
+</li>
+<li>The 'Null pointer access' potential programming problem is now reported as a 
+    warning by default, whereas it was previously ignored. See details in bug
+    <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192875">192875</a>.
+</li> 
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157541">157541</a>
+[organize imports] organize imports does not work in package-info.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200724">200724</a>
+[compiler] Assignment with no effect undetected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192875">192875</a>
+[compiler][options][null] Set &quot;Null pointer access&quot; to warning by default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=180107">180107</a>
+[PERF] need CompilationParticipant.buildComplete() API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=205860">205860</a>
+ASTParser.createBindings() returns [null]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206027">206027</a>
+JavaCore#initializeAfterLoad - Util.setSourceAttachmentProperty performance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206522">206522</a>
+Chkpii error in N20071016-0010
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206483">206483</a>
+[compiler][1.7] 1.7 VMs cannot read .class files generated with target 1.7
+
+<a name="v_819"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 16, 2007
+<br>Project org.eclipse.jdt.core v_819
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_819">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new compiler optional warning for diagnosing generic invocations of non-generic methods. Basically, from Java7 compliance on, a non-generic method
+may be invoked with explicit type arguments syntax, which though unused are to be silently ignored. With this warning, the compiler will still flag such situations.
+The warning is on by default, and is suppressable with <code>@SuppressWarnings("unused")</code>.
+Also added option: <code>JavaCore.COMPILER_PB_UNUSED_TYPE_ARGUMENTS_FOR_METHOD_INVOCATION</code> and problem ID
+<code>IProblem.UnusedTypeArgumentsForMethodInvocation</code>.
+<pre>
+* COMPILER / Reporting Presence of Type Arguments for a Non-Generic Method Invocation
+*    When enabled, the compiler will issue an error or a warning whenever type arguments are encountered for a
+*    non-generic method invocation. Note that prior to compliance level is "1.7", this situation would automatically result
+*    in an error. From Java7 on, unused type arguments are being tolerated, and optionally warned against.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.unusedTypeArgumentsForMethodInvocation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122885">bug 122885</a> required the build state format to change. 
+    As a consequence, a full rebuild is expected when reusing existing workspaces.
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168230">168230</a>
+[1.5][compiler] Non-generic methods can be called with type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206336">206336</a>
+[assist] CompletionProposal#getTokenStart() return always 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=122885">122885</a>
+[builder] Project build states should not store the access restrictions templates
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=205235">205235</a>
+[1.5][compiler] Eclipse syntax highlighting flag correct syntax as a hierarchy cycle
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200026">200026</a>
+[1.5][compiler] compiler message on incomplete enum declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200016">200016</a>
+[1.5][compiler] better error message when enum constants must implement methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=121024">121024</a>
+[1.5][compiler] Call of parametrized method reported ambiguous by eclipse not by javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206021">206021</a>
+Improve progress reporting in &quot;Initializing Java Tooling&quot; job
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204845">204845</a>
+BatchCompilerTest tests fail when the runtime JRE points to a path containing white spaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195823">195823</a>
+ClassFormatException during class file indexing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120088">120088</a>
+[1.5][compiler] Incomparable types - object.getClass() == Some.class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148046">148046</a>
+[compiler][1.5] should raise an incompatible types error when a given type variable cannot fulfill its bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=158870">158870</a>
+[1.5][compiler] javac inconvertible types on cast allowed by Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89940">89940</a>
+[1.5][compiler] wrong cast allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90437">90437</a>
+[1.5][compiler] Casting with Erasure generates warning in Eclipse but ERROR with JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=165352">165352</a>
+[1.5][compiler] Cast should be rejected
+
+
+<a name="v_818"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 9, 2007
+<br>Project org.eclipse.jdt.core v_818
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_818">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=205847">205847</a>
+[compiler] Compiler referencing Java model code
+
+<a name="v_817"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 8, 2007
+<br>Project org.eclipse.jdt.core v_817
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_817">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added API <code>SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH</code>.<br>
+This constant tells Search Engine to report matches which have <b>exactly</b>
+the same count of parts (i.e. uppercase characters) than the Camel Case pattern 
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201426">bug 201426</a>):
+<pre>
+/**
+ * Match rule: The search pattern contains a Camel Case expression with
+ * a strict expected number of parts.
+ *
+ * Examples:
+ * 	. 'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 	  but not 'HashMapEntry'
+ * 	. 'HMap' type string pattern will still match previous 'HashMap' and
+ * 	  'HtmlMapper' types, but not 'HighMagnitude'
+ *
+ * This rule is not intended to be combined with any other match rule. In case
+ * of other match rule flags are combined with this one, then match rule validation
+ * will return a modified rule in order to perform a better appropriate search request
+ * (see {@link #validateMatchRule(String, int)} for more details).
+ *
+ * @see CharOperation#camelCaseMatch(char[], char[], boolean) for a detailed
+ * explanation of Camel Case matching.
+ *
+ * @since 3.4
+ */
+public static final int R_CAMELCASE_SAME_PART_COUNT_MATCH = 0x0100;
+</pre>
+Note that this constant replace previous one <code>R_CAMEL_CASE_MATCH</code>
+added while fixing <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124624">bug 124624</a>.<br>
+Also note that <code>R_CAMELCASE_MATCH</code> is no longer deprecated as, finally,
+Camel Case match rule flags are not supposed to be combined with other ones (e.g.
+<code>R_PREFIX_MATCH</code> or <code>R_PATTERN_MATCH</code>).
+</li>
+<li>Existing API method <code>SearchPattern#validateMatchRule(String, int)</code>
+has been modified to include the new <code>#R_CAMELCASE_SAME_PART_COUNT_MATCH</code> constant:
+<pre>
+/**
+ * Validate compatibility between given string pattern and match rule.
+ *
+ * In certain circumstances described in the table below, the returned match rule is
+ * modified in order to provide a more efficient search pattern:
+ * 	1.	when the {@link #R_REGEXP_MATCH} flag is set, then <b>the pattern is
+ * 		rejected</b> as this kind of match is not supported yet and <code>-1</code>
+ * 		s returned).
+ * 	2.	when the string pattern has <u>no</u> pattern characters (e.g. '*' or '?')
+ * 		and the pattern match flag is set (i.e. the match rule has the {@link #R_PATTERN_MATCH}
+ * 		flag), then <b>the pattern match flag is reset</b>.
+ * 		Reversely, when the string pattern has pattern characters and the pattern
+ * 		match flag is <u>not</u> set, then <b>the pattern match flag is set</b>.
+ * 	3.	when the {@link #R_PATTERN_MATCH} flag is set then, <b>other
+ * 		{@link #R_PREFIX_MATCH}, {@link #R_CAMELCASE_MATCH} or
+ * 		{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH} flags are reset</b>
+ * 		if they are tentatively combined.
+ * 	4.	when the {@link #R_CAMELCASE_MATCH} flag is set, then <b>other 
+ * 		{@link #R_PREFIX_MATCH} or {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}
+ * 		flags are reset</b> if they are tentatively combined.
+ * 		Reversely, if the string pattern cannot be a camel case pattern (i.e. contains
+ * 		invalid Java identifier characters or does not have at least two uppercase
+ * 		characters - one for method camel case patterns), then <b>the CamelCase
+ * 		match flag is replaced with a prefix match flag</b>.
+ * 	5.	when the {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH} flag is set,
+ * 		then <b>({@link #R_PREFIX_MATCH} flag is reset</b> if it's tentatively
+ * 		combined.
+ * 		Reversely, if the string pattern cannot be a camel case pattern (i.e. contains
+ * 		invalid Java identifier characters or does not have at least two uppercase
+ * 		characters - one for method camel case patterns), then <b>the CamelCase
+ * 		part count match flag is reset</b>.
+ * <i>Note: the rules are validated in the documented order. For example, it means
+ * 	that as soon as the string pattern contains one pattern character, the pattern
+ * 	match flag will be set and all other match flags reset: validation of rule 2)
+ * 	followed by rule 3)...</i>
+ *
+ * @param stringPattern The string pattern
+ * @param matchRule The match rule
+ * @return Optimized valid match rule or -1 if an incompatibility was detected.
+ * @since 3.2
+ */
+public static int validateMatchRule(String stringPattern, int matchRule) {
+...
+}
+</pre>
+</li>
+<li><code>CharOperation</code> and <code>SearchPattern</code> Camel Case API methods
+added while fixing <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124624">bug 124624</a>)
+have been modified to clarify the behavior of the additional boolean parameter.<br>
+This parameter now indicates whether the pattern and the name should have the same
+count of parts (i.e. uppercase characters) or not:
+<pre>
+/**
+ *...
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ *...
+ * . pattern = "HM".toCharArray()
+ * name = "HashMapEntry".toCharArray()
+ * result =&gt; (samePartCount == false)
+ *...
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.
+ * 	&nbsp;&nbsp;For example:
+ * 		. 'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'
+ * 		. 'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, char[] name, boolean samePartCount) {
+...
+}
+
+/**
+ *...
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ *...
+ * . pattern = "HM".toCharArray()
+ * patternStart = 0
+ * patternEnd = 2
+ * name = "HashMapEntry".toCharArray()
+ * nameStart = 0
+ * nameEnd = 12
+ * result =&gt; (samePartCount == false)
+ *...
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.
+ * 	&nbsp;&nbsp;For example:
+ * 		. 'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'
+ * 		. 'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd, boolean prefixMatch) {
+...
+}
+</pre>
+Note that similar modifications have been done on <code>SearchPattern</code>
+corresponding methods:
+<pre>
+public static final boolean camelCaseMatch(String pattern, String name, boolean samePartCount) {
+...
+}
+public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd, boolean samePartCount) {
+...
+}
+</pre>
+</li>
+<li>Modified API <code>CompletionProposal#getRequiredProposals()</code>.<br>
+<code>TYPE_REF</code> proposals can now have a TYPE_REF proposal as required proposal 
+</li>
+<li>CodeAssist: Member types and static members are proposed when the receiver is a not yet imported type.
+<pre>
+package p;
+public class X {
+   public static void bar() {}
+}
+
+package q;
+public class Y {
+   public void foo() {
+      X.bar
+   }
+}
+</pre>
+When the completion occurs after <i>X.bar</i> the method <code>X#bar()</code> is proposed with a required proposal to complete the not yet imported type.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=44627">44627</a>
+[assist] improve content assist for static members when import missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=125518">125518</a>
+[javadoc] Embedding html in a link placed in a @see JavaDoc tag causes a warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86769">86769</a>
+[javadoc] Warn/Error for 'Missing javadoc comments' doesn't recognize private inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=168849">168849</a>
+[javadoc] Javadoc warning on @see reference in class level docs.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190970">190970</a>
+[javadoc] &quot;field never read locally&quot; analysis should not consider javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195374">195374</a>
+[javadoc] Missing Javadoc warning for required qualification for inner types at 1.4 level
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192449">192449</a>
+[javadoc][assist] SelectionJavadocParser should not report problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73352">73352</a>
+[Javadoc] Missing description should be warned for all tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191931">191931</a>
+BatchImageBuilder sometimes marks resources as derived before deleting them
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201426">201426</a>
+[search] New SearchPattern constant R_CAMEL_CASE_MATCH name may be misleading for users
+
+<a name="v_816"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - October 2, 2007
+<br>Project org.eclipse.jdt.core v_816
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_816">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added API <code>IJavaElementDelta#F_RESOLVED_CLASSPATH_CHANGED</code>. This flag is set when the resolved classpath of a Java project changes.
+     This is independent from <code>IJavaElementDelta#F_CLASSPATH_CHANGED</code> which indicates that the raw classpath has changed.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204624">204624</a>
+[1.5][compiler] No error on abstract method implementation with missing parameter generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204339">204339</a>
+[compiler] Invalid length for missing package declaration in empty package-info.java file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203587">203587</a>
+Improve messages consistency in case of generic methods having same erasure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204662">204662</a>
+org.eclipse.jdt.internal.compiler.parser.Parser.endParse throws NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203662">203662</a>
+Perf: Unnecessary compilation when package added to second source root
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204805">204805</a>
+ICompilationUnit.commitWorkingCopy doesn't send typeHierarchyChanged
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204652">204652</a>
+&quot;Open Type&quot;: ClassCastException in conjunction with a class folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204534">204534</a>
+[1.5][compiler] Annoying consequence of method verification problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204417">204417</a>
+NullPointerException in SelectionOnQualifiedAllocationExpression.resolveType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204536">204536</a>
+[1.5][compiler] Type variables insufficiently connected in presence of errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154071">154071</a>
+No notification of change if a project is added or removed from a container
+
+<a name="v_815"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M3 - September 25, 2007
+<br>Project org.eclipse.jdt.core v_815
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_815">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=199668">199668</a>
+IAE in ASTNode.setSourceRange while editing a class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204283">204283</a>
+[compiler] synthetic field for class literal access should not be created for int.class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190094">190094</a>
+Java Outline Causes Eclipse Lock-up.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203609">203609</a>
+[1.6][compiler] AccSynthetic should be set for package-info type if target &gt;= 1.6
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203579">203579</a>
+[dom] Length of VariableDeclarationFragment is not the same inside a 'for' initialisation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204040">204040</a>
+Class literal code generation must be improved for cldc target
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=204108">204108</a>
+unused import in jdt.internal.compiler.lookup.TypeBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169049">169049</a>
+[1.5][compiler] Bogus bound mismatch errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203905">203905</a>
+[1.5][compiler] shows wrong error with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203721">203721</a>
+[compiler] &quot;Parameter is never read&quot; not reported if unnecessary declared checked exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200158">200158</a>
+[compiler] inconsistent handling of unreachable code
+
+<a name="v_814"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - September 19, 2007 - 3.4 MILESTONE 2
+<br>Project org.eclipse.jdt.core v_814
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_814">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=204002">204002</a>
+AIOB when enabling CLDC 1.1
+
+<a name="v_813"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - September 17, 2007
+<br>Project org.eclipse.jdt.core v_813
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_813">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The <code>SearchPattern#R_CAMELCASE_MATCH</code> constant is no longer deprecated and<br>
+the new constant <code>SearchPattern#R_CAMEL_CASE_MATCH</code> <b>will surely be renamed in next milestone</b>.<br>
+(see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201426">bug 201426</a> to follow-up
+work in progress in this area...)
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203577">203577</a>
+ClassFormatException viewing annotation with empty target annotation
+
+<a name="v_812"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - September 15, 2007
+<br>Project org.eclipse.jdt.core v_812
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_812">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new API <code>org.eclipse.jdt.core.JavaCore#VERSION_CLDC_1_1</code> in order to support the cldc1.1 target inside the IDE.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120223">120223</a>
+[compiler] Support for "-target cldc1.1"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203241">203241</a>
+[compiler] Missing warning when a serializable class without serialVersionUID is also abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203454">203454</a>
+NPE in compiler when processing annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203342">203342</a>
+AST of a NumberLiteral has wrong source code range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203089">203089</a>
+getDefaultOptions misses option
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159214">159214</a>
+[1.5] [compiler] Eclipse compiler wildcard bug
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202404">202404</a>
+[1.5][compiler] Incorrect handling of type variable bounds issued by capture conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203318">203318</a>
+[1.5][compiler] Improper capture of wildcard with lesser bound than parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202936">202936</a>
+[compiler] Compiler error for Java switch expression provides inaccurate list of allowed data types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203061">203061</a>
+[compiler] Uninitialized member variables used in nonstatic initializers of peer members don't trigger compilation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203058">203058</a>
+Building workspace hangs in endless loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202830">202830</a>
+[compiler][1.5] eclipse fails to compile subclass when superclass has two generic methods of the same name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203020">203020</a>
+formatter may change code semantics on unary operators
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201182">201182</a>
+[compiler][null] Null pointer access compiler warning fails when &quot;throw null&quot;
+
+
+<a name="v_811"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - September 11, 2007
+<br>Project org.eclipse.jdt.core v_811
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_811">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added an option that allows @throws javadoc entries to defuse the unused
+    declared thrown exception check. 
+<pre>
+COMPILER / Consider Reference in Doc Comment for Unused Declared Thrown Exception Check
+   When enabled, the compiler will consider doc comment references to exceptions 
+   (i.e. @throws clauses) for the unused declared thrown exception check. Thus, 
+   documented exceptions will be considered as mandated as per doc contract.
+   The severity of the unused declared thrown exception problem is controlled 
+   with option "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException".
+   Note: this option has no effect until the doc comment support is enabled 
+   according to the option "org.eclipse.jdt.core.compiler.doc.comment.support".
+    - option id:         "org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocReference"
+    - possible values:   { "enabled", "disabled" }
+    - default:           "enabled"
+</pre>
+See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73244">73244</a>
+for details.
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73244">73244</a>
+[options] Improve &quot;Unnecessary declaration of thrown checked exceptions&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89301">89301</a>
+Any user operation that would trigger an autobuild should cancel a running autobuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=184298">184298</a>
+[compiler][null] Spurious &quot;Variable can only be null&quot; warning in case of an infinite loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201929">201929</a>
+Member of local type should not have a fully qualified name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=202134">202134</a>
+[1.6][compiler] org.eclipse.jdt.tests.compiler.regression.ConformTest#test003 never ends in .16 mode
+
+
+<a name="v_810"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - September 4, 2007
+<br>Project org.eclipse.jdt.core v_810
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_810">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=202076">202076</a>
+NPE in DeltaProcessor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=182359">182359</a>
+[compiler] optimize line number generation using the new getLineNumber method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185350">185350</a>
+[1.6][compiler] Code generation seems to be much slower than in 1.5 mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196253">196253</a>
+[1.5][compiler] Failure to compile generics with wildcard and inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=189158">189158</a>
+[1.5][compiler] Malformed generic signature for nested classes (. vs $)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201062">201062</a>
+Missing library in project classpath even library exists
+
+<a name="v_809"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - August 28, 2007
+<br>Project org.eclipse.jdt.core v_809
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_809">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Prefix matching can be disabled while using Camel Case API methods. (see 
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124624">bug 124624</a>).<br>
+Following API methods have been added on <code>org.eclipse.jdt.core.compiler.CharOperation</code>:
+<pre>
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or
+ * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
+ * '*' and '?' and is inherently case sensitive.
+ *
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ *
+ * The pattern may contain lowercase characters, which will be match in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ *
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ *
+ * CamelCase may or may not match prefixes depending on the given parameter.
+ * When the prefix match parameter is <code>true</code>, the given pattern can
+ * match only a prefix of the given name. For instance, 'HM' , 'HaMa' and  'HMap'
+ * patterns will all match 'HashMap', 'HatMapper' <b>and</b> 'HashMapEntry'.
+ * Reversely, if the prefix match parameter is <code>false</code>, then pattern
+ * and name must have <b>exactly</b> the same number of parts, and their last
+ * parts must be identical if they contain lowercase characters.
+ * For instance, 'HMap' and 'HaMap' patterns will match 'HashMap' but neither
+ * 'HashMapEntry' nor 'HatMapper'. Note that when the last part does not contain
+ * lowercase characters, then the name may end with lowercase characters.
+ * So, 'HM' pattern will match both 'HashMap' <b>and</b> 'HatMapper' but will not
+ * match 'HashMapEntry'.
+ *
+ * Examples:
+ *  1.	pattern = { 'N', 'P', 'E' }
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	result =&gt; true
+ *  2.	pattern = { 'N', 'P', 'E' }
+ *  	name = { 'N', 'o', 'P', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	result =&gt; true
+ *  3.	pattern = { 'N', 'u', 'P', 'o', 'E', 'x' }
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	result =&gt; true
+ *  4.	pattern = { 'N', 'u', 'P', 'o', 'E', 'x' }
+ *  	name = { 'N', 'o', 'P', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	result =&gt; false
+ *  5.	pattern = { 'n', p', 'e' }
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	result =&gt; false
+ *  6.	pattern = { 'I', 'P', 'L', '3' }
+ *  	name = { 'I', 'P', 'e', 'r', 's', 'p', 'e', 'c', 't', 'i', 'v', 'e', 'L', 'i', 's', 't', 'e', 'n', 'e', 'r', '3' }
+ *  	result =&gt; true
+ *  7.	pattern = { 'H', M' }
+ *  	name = { 'H', 'a', 's', 'h', 'M', 'a', 'p', 'E', 'n', 't', 'r', 'y' }
+ *  	result =&gt; (prefixMatch == true)
+ *  8.	pattern = { 'H', M', 'a', 'p' }
+ *  	name = { 'H', 'a', 't', 'M', 'a', 'p', 'p', 'e', 'r' }
+ *  	result =&gt; (prefixMatch == true)
+ * 
+ * @param pattern the given pattern
+ * @param name the given name
+ * @param prefixMatch flag telling whether the pattern can match name prefix or not.
+ * 		. For example, when it's <code>true</code>:
+ * 			- 'HM' type string pattern will match  'HashMap' and 'HtmlMapper' types,
+ * 			  but not 'HashMapEntry'
+ * 			- 'HMap' type string pattern will match  'HashMap' type but not 'HtmlMapper'.
+ * 		. and, when it's <code>false</code>:
+ * 			- 'HM' type string pattern will match both   'HashMap' and 'HtmlMapper'
+ * 			  and 'HashMapEntry'
+ * 			- 'HMap' type string pattern will match both 'HashMap' and 'HtmlMapper'
+ * 			  types.
+ *
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, char[] name, boolean prefixMatch) {
+...
+}
+
+/**
+ * Answers true if a sub-pattern matches the sub-part of the given name using 
+ * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
+ * accept explicit wild-cards '*' and '?' and is inherently case sensitive. 
+ * Can match only subset of name/pattern, considering end positions as
+ * non-inclusive. The sub-pattern is defined by the patternStart and patternEnd
+ * positions.
+ *
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain
+ * a sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ *
+ * The pattern may contain lowercase characters, which will be match in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ *
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ *
+ * CamelCase may or may not match prefixes depending on the given parameter.
+ * When the prefix match parameter is <code>true</code>, the given pattern can
+ * match only a prefix of the given name. For instance, 'HM' , 'HaMa' and  'HMap'
+ * patterns will all match 'HashMap', 'HatMapper' <b>and</b> 'HashMapEntry'.
+ * Reversely, if the prefix match parameter is <code>false</code>, then pattern
+ * and name must have <b>exactly</b> the same number of parts, and their last
+ * parts must be identical if they contain lowercase characters.
+ * For instance, 'HMap' and 'HaMap' patterns will match 'HashMap' but neither
+ * 'HashMapEntry' nor 'HatMapper'. Note that when the last part does not contain
+ * lowercase characters, then the name may end with lowercase characters.
+ * So, 'HM' pattern will match both 'HashMap' <b>and</b> 'HatMapper' but will not
+ * match 'HashMapEntry'.
+ *
+ * Examples:
+ *  1.	pattern = { 'N', 'P', 'E' }
+ *  	patternStart = 0
+ *  	patternEnd = 3
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	nameStart = 0
+ *  	nameEnd = 20
+ *  	result =&gt; true
+ *  2.	pattern = { 'N', 'P', 'E' }
+ *  	patternStart = 0
+ *  	patternEnd = 3
+ *  	name = { 'N', 'o', 'P', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	nameStart = 0
+ *  	nameEnd = 21
+ *  	result =&gt; true
+ *  3.	pattern = { 'N', 'u', 'P', 'o', 'E', 'x' }
+ *  	patternStart = 0
+ *  	patternEnd = 6
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	nameStart = 0
+ *  	nameEnd = 20
+ *  	result =&gt; true
+ *  4.	pattern = { 'N', 'u', 'P', 'o', 'E', 'x' }
+ *  	patternStart = 0
+ *  	patternEnd = 6
+ *  	name = { 'N', 'o', 'P', 'e', 'r', 'm', 'i', 's', 's', 'i', 'o', 'n', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	nameStart = 0
+ *  	nameEnd = 21
+ *  	result =&gt; false
+ *  5.	pattern = { 'n', p', 'e' }
+ *  	patternStart = 0
+ *  	patternEnd = 3
+ *  	name = { 'N', 'u','l', 'l', 'P', 'o', 'i', 'n', 't', 'e', 'r', 'E', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n' }
+ *  	nameStart = 20
+ *  	nameEnd = 9
+ *  	result =&gt; false
+ *  6.	pattern = { 'I', 'P', 'L', '3' }
+ *  	patternStart = 0
+ *  	patternEnd = 4
+ *  	name = { 'I', 'P', 'e', 'r', 's', 'p', 'e', 'c', 't', 'i', 'v', 'e', 'L', 'i', 's', 't', 'e', 'n', 'e', 'r', '3' }
+ *  	nameStart = 0
+ *  	nameEnd = 21
+ *  	result =&gt; true
+ *  7.	pattern = { 'H', M' }
+ *  	patternStart = 0
+ *  	patternEnd = 2
+ *  	name = { 'H', 'a', 's', 'h', 'M', 'a', 'p', 'E', 'n', 't', 'r', 'y' }
+ *  	nameStart = 0
+ *  	nameEnd = 12
+ *  	result =&gt; (prefixMatch == true)
+ *  8.	pattern = { 'H', M', 'a', 'p' }
+ *  	patternStart = 0
+ *  	patternEnd = 4
+ *  	name = { 'H', 'a', 't', 'M', 'a', 'p', 'p', 'e', 'r' }
+ *  	nameStart = 0
+ *  	nameEnd = 9
+ *  	result =&gt; (prefixMatch == true)
+ * 
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @param prefixMatch flag telling whether the pattern can match name prefix or not.
+ * 		. For example, when it's <code>true</code>:
+ * 			- 'HM' type string pattern will match  'HashMap' and 'HtmlMapper' types,
+ * 			  but not 'HashMapEntry'
+ * 			- 'HMap' type string pattern will match  'HashMap' type but not 'HtmlMapper'.
+ * 		. and, when it's <code>false</code>:
+ * 			- 'HM' type string pattern will match both   'HashMap' and 'HtmlMapper'
+ * 			  and 'HashMapEntry'
+ * 			- 'HMap' type string pattern will match both 'HashMap' and 'HtmlMapper'
+ * 			  types.
+ *
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd, boolean prefixMatch) {
+...
+}
+</pre>
+Note that same methods have been added on <code>SearchPattern</code> but with
+<code>String</code> parameters instead of <code>char[]</code> ones (javadoc comments
+are identical):
+<pre>
+public static final boolean camelCaseMatch(String pattern, String name, boolean prefixMatch) {
+...
+}
+public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd, boolean prefixMatch) {
+...
+}
+</pre>
+Note also that methods <code>camelCaseMatch(String, int, int, String, int, int)</code>
+of <code>CharOperation</code> and <code>SearchPattern</code> classes have been
+deprecated to avoid too many 'camelCaseMatch*' methods on these classes.
+</li>
+<li>Search Engine has been modified to better handle additional <code>SearchPattern</code>
+constants while using Camel Case one (see <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200400">bug 200400</a>).<br>
+Existing <code>SearchPattern#R_CAMELCASE_MATCH</code> constant has been deprecated and<br>
+is <b>now replaced by <code>SearchPattern#R_CAMEL_CASE_MATCH</code></b>:<pre>
+	/**
+	 * Match rule: The search pattern contains a Camel Case expression with
+	 * a strict number of parts and preventing automatic prefix matching for the last
+	 * part (if it consists of multiple letters).
+	 * 
+	 * Examples:
+	 * 	. 'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+	 * 		but not 'HashMapEntry'
+	 * 	. 'HMap' type string pattern will match 'HashMap' type but not 'HtmlMapper'.
+	 *
+	 * This Camel Case match rule does not allow prefix match but accept insensitive
+	 * case. For instance, 'HashMap' or 'HASHMAP' patterns using this Camel Case
+	 * rule will match both 'HashMap' but not 'HashMapEntry'.
+	 *
+	 * This rule still can be combined to prefix match to accept prefix matches
+	 * ('HashMap' pattern matching 'HashMapEntry' name). It can also be combined
+	 * to case sensitive match to reject case insensitive matches ('HAMA' pattern
+	 * will not match 'HashMap' name).
+	 *
+	 * If {@link #R_PATTERN_MATCH} rule is also combined, then the real used
+	 * match rule will depend on whether string pattern contains specific pattern
+	 * characters (e.g. '*' or '?') or not. If it does, then only Pattern match rule will
+	 * be used, otherwise only Camel Case match will be used.
+	 * For example, with 'NPE' string pattern, search will only use
+	 * Camel Case match rule, but with 'N*P*E*' string pattern, it will 
+	 * use only Pattern match rule.
+	 *
+	 * @see CharOperation#camelCaseMatch(char[], char[], boolean) for a detailed
+	 * explanation of Camel Case matching.
+	 *
+	 * @since 3.4
+	 */
+	public static final int R_CAMEL_CASE_MATCH = 0x0100;
+</pre>
+This change was necessary has the obsolete <code>R_CAMELCASE_MATCH</code> could
+not support correctly additional constants as <code>R_PREFIX_MATCH</code> or 
+<code>R_CASE_SENSITIVE</code>.<br>
+However, this deprecated constant is still accepted for backward compatibility
+but user is advised to replace it with <code>R_CAMEL_CASE_MATCH | R_PREFIX_MATCH</code>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201066">201066</a>
+[prefs] Preferences listeners are not removed while shutting down JavaModelManager
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152841">152841</a>
+[model] IJavaProject.findType(name, monitor) doesn't find secondary type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=108456">108456</a>
+IPackageFragmentRoot#getPackageFragment() should not accept invalid package names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201104">201104</a>
+JavaElement of a recovered type binding should not return a compilation unit with no parent
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190622">190622</a>
+type binding marked as recovered but all is compiling
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201064">201064</a>
+[search] SearchEngine.searchAllTypeNames(..) does not find CamelCase match
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183117">183117</a>
+User Library Lost
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200400">200400</a>
+[search] Camel Case match prefix insensitive although spec says prefix sensitive
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=124624">124624</a>
+[search] Camelcase matching routines should support end character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191739">191739</a>
+"Duplicate nested type" bogus error on static class of abstract class or interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200931">200931</a>
+GENERATED_BY references still exist in some javadoc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200547">200547</a>
+[1.5][compiler] Invalid ambiguous error when calling an overriden generic method with MULTIPLE bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198120">198120</a>
+[1.5][compiler] Cannot directly invoke the abstract method huch(I1) for the type I1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196254">196254</a>
+Overrides wrong for wildcard parameterized methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193265">193265</a>
+[1.5][compiler] Incorrect ambiguous method error involving abstract classes and enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198253">198253</a>
+unversioned downloads of ecj.jar and ecjsrc.zip
+
+
+<a name="v_808"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - August 21, 2007
+<br>Project org.eclipse.jdt.core v_808
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_808">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186781">bug 186781</a> required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>API method <code>JavaProject.setOption(String, String)</code> behavior has been slightly changed consequent upon following bugs fixing:
+<ul>
+<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152562">bug 152562</a>: 
+<code>null</code> is now accepted for the option value and remove the corresponding preference from the project,</li>
+<li><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152578">bug 152578</a>: 
+the preference is not removed from project when the value is equals to the workspace preference value.</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=183923">183923</a>
+[prefs] NPE in JavaProject#setOptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152578">152578</a>
+[prefs] IJavaProject.setOption(Object,Object) wrongly removes key when value is equals to JavaCore one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=152562">152562</a>
+[prefs] IJavaProject.setOption(..., null) does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200449">200449</a>
+[model] Classpath variable deprecation message is not flushed from cache when variable is removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186113">186113</a>
+[model] classpath variable deprecation messages not initialized when called
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=109695">109695</a>
+[search] Numbers should be treated as upper-case letters in CamelCase matching
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186781">186781</a>
+StackOverflowError while computing launch button tooltip
+
+<a name="v_807"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - August 15, 2007
+<br>Project org.eclipse.jdt.core v_807
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_807">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200064">bug 200064</a> required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=200064">200064</a>
+[search] ResourceException while searching for method reference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198051">198051</a>
+[1.5][compiler] Improper Polymorphic Exception Handling 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194399">194399</a>
+IJavaProject.findType(String, String, WorkingCopyOwner) doesn't return the same element with different VMs.
+
+<a name="v_806"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M2 - August 14, 2007
+<br>Project org.eclipse.jdt.core v_806
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_806">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138184">bug 138184</a> required the index version to be incremented.
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169970">169970</a>
+[model] code assist favorites must honour build path of project in context
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135493">135493</a>
+[search] Clarify TypeNameRequestor#acceptType(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=138184">138184</a>
+[search] Type Dialog (Could not uniquely map the name to a type)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=199004">199004</a>
+[search] Java Search in 'JRE libraries' finds matches in Application Libraries
+
+<a name="v_805"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - August 2, 2007 - 3.4 MILESTONE 1
+<br>Project org.eclipse.jdt.core v_805
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_805">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=198483">198483</a>
+BuilderTests: need expectingUniqueCompiledClasses method
+
+<a name="v_804"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - August 1, 2007
+<br>Project org.eclipse.jdt.core v_804
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_804">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>All tests projects and org.eclipse.jdt.compiler.tool project's versions have been incremented.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198362">198362</a>
+Formatter stops working when source code contains following line
+
+<a name="v_803"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - July 30, 2007
+<br>Project org.eclipse.jdt.core v_803
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_803">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=109636">109636</a>
+Comment formatter doesn't support &quot;&amp;#42;/&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=197169">197169</a>
+Formatter expands &amp;#64; in annotation in javadoc, creating invalid tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198153">198153</a>
+[formatter] adds extra space before expanded numerical entity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=197400">197400</a>
+NPE for completion engine in class static block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53727">53727</a>
+[Tasks]  longest tags should match
+
+<a name="v_802"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - July 23, 2007
+<br>Project org.eclipse.jdt.core v_802
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_802">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=166093">166093</a>
+[search] NPE searching for references to private static method in class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196514">196514</a>
+Bunch of exception during code typing in JDT editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186333">186333</a>
+[search] Should better locate fields and methods matches on binary super types with unresolved references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=167357">167357</a>
+non-empty init block in local member type has no children
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186114">186114</a>
+IMethodBinding.overrides(..) should consider static
+
+<a name="v_801"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - July 17, 2007
+<br>Project org.eclipse.jdt.core v_801
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_801">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Incremented JDT/Core plug-in id to "3.4.0" as fix for 186822 adds new constants in <code>org.eclipse.jdt.core.compiler.IProblem</code>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196339">196339</a>
+[search] SearchEngine not returning correct result
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196354">196354</a>
+ClassCastException in package binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196249">196249</a>
+problem in parsing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195802">195802</a>
+Name clash compile error generated if superclass is abstract
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195468">195468</a>
+[1.5][compiler] Eclipse compiler differs from javac with generics (name clash)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=196653">196653</a>
+[compiler] More resilience with unbound caught exceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192387">192387</a>
+Wrong warning location for a non static reference to an enum value.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195228">195228</a>
+[search] Invalid path in open type dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186822">186822</a>
+[1.5][compiler] Add more resilience on annotation and enum type declaration with type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97998">97998</a>
+[builder] improve the error handling in case the build encounters a locked file within the the output folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=188876">188876</a>
+[assist] Proposals inside an import statement shouldn't be fully qualified
+
+<a name="v_800"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.4M1 - July 9, 2007
+<br>Project org.eclipse.jdt.core v_800
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_800">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Incremented JDT/Core plug-in id to "3.3.100". Will go to "3.4.0" as soon as an API/feature gets added.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190960">190960</a>
+[batch][compiler] help message for annotations processing should be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103654">103654</a>
+BindingKey.getTypeArguments bug with qualified types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191125">191125</a>
+[1.5] [assist] NPE in CompletionEngine.proposeType()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195489">195489</a>
+[search] Javadoc reference not found while using SearchEngine.searchDeclarationsOfReferencedTypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195317">195317</a>
+[compiler] java.lang.ClassFormatError: Invalid pc in LineNumberTable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195509">195509</a>
+Need to improve classpath resolution for Apache Harmony in org/eclipse/jdt/core/tests/util/Util.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195526">195526</a>
+org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest.test0744 depends on non-specified package-private class HashMap.Entry implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191082">191082</a>
+AnnotationMirror.getPosition() returns wrong value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=189799">189799</a>
+[jsr269] Make getDocComment() behave more like javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192774">192774</a>
+Annotation AST nodes should have unique IAnnotationBindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171703">171703</a>
+Eclipse cannot find source for *.class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=193979">193979</a>
+AST parser generates wrong AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95288">95288</a>
+[model] CreatePackageFragmentOperation runs with wrong ISchedulingRule
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142044">142044</a>
+[search] &quot;And&quot; Pattern fails with NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=111882">111882</a>
+[assist] Invalid relevance while completing in case of a switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195263">195263</a>
+Update exportplugins.xml to 3.3.100 and 3.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=181488">181488</a>
+[index] Lots of unbuffered sequential reads in DiskIndex
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=18311">18311</a>
+api: ISourceReference::getSource can return undocumented result
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=129560">129560</a>
+[spec] Questionable javadoc for IJavaElement#isStructureKnown()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=178226">178226</a>
+Clarify spec for IJarEntryResource
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=163229">163229</a>
+[model] IAccessRule does not say it cannot be implemented by clients
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149590">149590</a>
+[model] bindings for duplicate local variables share same key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=195091">195091</a>
+Index is rebuilt on each startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170889">170889</a>
+[5.0][content assist] strange label for 'class' proposal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190965">190965</a>
+[compiler] useless assignment to local variable parameters in Scope line 431
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=153125">153125</a>
+[getter setter] Getters/setters for variables starting with non-Latin letter are generated incorrectly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186760">186760</a>
+Two cases of switch in DeltaProcessor#fire could be merged
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170954">170954</a>
+void should not be proposed inside method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120766">120766</a>
+problems when using classes of the same name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=137452">137452</a>
+Autocomplete adds &quot;Void&quot; instead of doing nothing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194420">194420</a>
+Misleading error message when build fails due to out of sync workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132139">132139</a>
+[assist] Duplicate names while completing in local variable declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99631">99631</a>
+[assist][5.0] Unnecessary proposals on annotation completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=171037">171037</a>
+[codeassist] if 1.4 or higher code assist after 'import' should not suggest types from default package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=139446">139446</a>
+[build path] bug in the Edit Library dialog box, when changing the default JRE, and switching from alternate JRE to workspace default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192497">192497</a>
+Cannot always find method definition, depending on cursor position
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=151967">151967</a>
+[1.5][assist] Code completion with enumerations implementing an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=150632">150632</a>
+[assist] Content Assist and Parameter Hints sometimes don't work for constructor call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194435">194435</a>
+JDT Core manifest contains invalid prereqed version
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185318">185318</a>
+[assist] No proposals when completing inside a method import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102031">102031</a>
+Content assist proposes same type twice after &quot;call(new |&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=157069">157069</a>
+[assist] Content Assist introduces compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=119434">119434</a>
+[code select] Code select returns doubled java element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194034">194034</a>
+[1.5][Compiler] Inconsistency with javac: subclass does not properly inherit generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185037">185037</a>
+Optimization opportunity in MethodVerifier
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191928">191928</a>
+Use Util.log instead of printStackTrace at AbstractImageBuilder#612
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=194185">194185</a>
+[search] for package declarations finds also subpackages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=191908">191908</a>
+[1.5][compiler] Missing strike through for deprecated declaration fragment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=192285">192285</a>
+[formatter] Java source formatter not working if class has annotation on single line multiple fields declaration.
+
+<hr>
+<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R33_buildnotes_jdt-core.html">build notes up to Release 3.3</a>.</p>
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/notes/R35_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R35_buildnotes_jdt-core.html
new file mode 100644
index 0000000..009720c
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R35_buildnotes_jdt-core.html
@@ -0,0 +1,2266 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>JDT/Core Release Notes 3.5</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.5 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch.
+	  For more information on 3.5 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.5/index.php#release-plan">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.5/index.php#milestone-plan">milestone plan</a>,
+	  the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_5.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.4 (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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_4_maintenance">R3.4.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_3_maintenance">R3.3.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+<a name="v_963"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC3 - May 27, 2009 - 3.5 RC3
+<br>Project org.eclipse.jdt.core v_963
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_963">cvs</a>).
+<h2>What's new in this drop</h2>
+Reverting change for bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236818">236818</a>.
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_962"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC3 - May 26, 2009
+<br>Project org.eclipse.jdt.core v_962
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_962">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=234194">234194</a>
+Run copyright tool
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=277669">277669</a>
+IBinding.getJavaElement() returns 'null' where it should not
+
+<a name="v_961"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC2 - May 21, 2009 - 3.5 RC2
+<br>Project org.eclipse.jdt.core v_961
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_961">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=277372">277372</a>
+[1.5][compiler] Signature attribute should not be generated with target jsr14
+
+<a name="v_960"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC2 - May 20, 2009
+<br>Project org.eclipse.jdt.core v_960
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_960">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=273991">273991</a>
+[assist] Wrong relevance for some proposals which are not compatible with the expected type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=276890">276890</a>
+[content assist] proposes nothing for generic type with non-trivial constructor
+
+<a name="v_959"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC1 - May 14, 2009 - 3.5 RC1
+<br>Project org.eclipse.jdt.core v_959
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_959">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=275471">275471</a>
+Eclipse Compiler needs a compile dependency to a plug-in, but javac does not need that dependency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170197">170197</a>
+[model] JavaCore.newLibraryEntry(.., IClasspathAttribute[], ..) should check for null
+
+<a name="v_958"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC1 - May 12, 2009
+<br>Project org.eclipse.jdt.core v_958
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_958">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=275381">275381</a>
+[1.5][compiler] Missing innerClass attribute for inner types used as type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255752">255752</a>
+[javadoc][assist] Inappropriate completion proposals for javadoc at compilation unit level
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=275467">275467</a>
+Batch compiler writes log using default encoding instead of UTF-8
+
+<a name="v_957"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC1 - May 7, 2009
+<br>Project org.eclipse.jdt.core v_957
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_957">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=273157">273157</a>
+[performance] ManifestAnalyzer is causing a 2x performance drop in the updating of classpath of JavaProjects in comparison with 3.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=268879">268879</a>
+External folders project not cleaned up
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=275215">275215</a>
+org.eclipse.jdt.internal.core.util.KeyToSignature#consumeType() uses a method not available in J2SE-1.4 EE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=275244">275244</a>
+org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ZipEntry, ZipFile) should use BufferedInputStream
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=132679">132679</a>
+[assist] Completion fails within non-static anonymous inner class
+
+<a name="v_956"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5RC1 - May 6, 2009
+<br>Project org.eclipse.jdt.core v_956
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_956">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=274114">274114</a>
+org.eclipse.jdt.internal.compiler.tool.Options must be updated with latest compiler options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=185422">185422</a>
+[1.5][compiler] Incorrectly allows generic use of private inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=274917">274917</a>
+Incorrect &quot;empty block&quot; warning underlining on annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=274557">274557</a>
+CompletionContext problem with annotation value element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=274332">274332</a>
+jdt.core.model tests take 2 hours to finish on the mac
+
+<a name="v_955"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 29, 2009 - 3.5 MILESTONE 7
+<br>Project org.eclipse.jdt.core v_955
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_955">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=274397">274397</a>
+tag projects changed since I20090421-0930 build
+
+<a name="v_954"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 28, 2009
+<br>Project org.eclipse.jdt.core v_954
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_954">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=269934">269934</a>
+[apt] APT-generated classes that contain annotations causes NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=259950">259950</a>
+Update copyright for 2009
+
+<a name="v_953"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 27, 2009
+<br>Project org.eclipse.jdt.core v_953
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_953">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=272204">272204</a>
+null should never be part of a type hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260031">260031</a>
+Wrong type for class constants in stackmap frames
+ 
+<a name="v_952"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 27, 2009
+<br>Project org.eclipse.jdt.core v_952
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_952">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=273862">273862</a>
+[1.7][compiler] Return type should be used to decide method duplicates
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84720">84720</a>
+[1.5][assist] proposal ranking by return value should consider auto(un)boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=272711">272711</a>
+Exceptions in ASTRewrite
+
+<a name="v_951"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 24, 2009
+<br>Project org.eclipse.jdt.core v_951
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_951">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=273308">273308</a>
+[perfs] Save very slow because DeltaProcessor#resourceChanged(..) resolves classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154823">154823</a>
+[getter setter] Getters Setters generation doesn't follow naming convention
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263786">263786</a>
+NamingConventions#suggestVariableNames(..) should not modify all caps parts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263769">263769</a>
+Javadoc glitches in JavaCore#setComplianceOptions(String, Map)
+
+<a name="v_950"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 21, 2009
+<br>Project org.eclipse.jdt.core v_950
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_950">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=266771">266771</a>
+NameLookup.findPackageFragment returns very incorrect package fragments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=271102">271102</a>
+Java model corrupt after switching target platform
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270784">270784</a>
+[perfs] Big regression on FullSourceWorkspaceModelTests#testCloseProjects() test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=272450">272450</a>
+DBCS3.5: Classpath resolution fails to honor the 'Class-Path' header of JAR manifest file in DBCS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=272706">272706</a>
+[Model] Generics lost on IField when coming from .class files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246832">246832</a>
+[1.5][assist] Camel case completion not working with statically imported methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=267833">267833</a>
+[javadoc] Custom tags should not be allowed for inline tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=271680">271680</a>
+[compiler] Stack overflow pasting in Java editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251827">251827</a>
+[search] Search for type reference with wildcards finds references in package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=271284">271284</a>
+[search] AIOOBE in StringOperation.getCamelCaseMatchingRegions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=272148">272148</a>
+[assist] Constructors with an array as parameter type are not proposed
+
+<a name="v_949"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 14, 2009
+<br>Project org.eclipse.jdt.core v_949
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_949">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=271561">271561</a>
+JavaModelException when accessing an array of nested annotations
+
+<a name="v_948"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - April 7, 2009
+<br>Project org.eclipse.jdt.core v_948
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_948">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=271303">271303</a>
+[1.5][compiler] Override and package visibility issue
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270367">270367</a>
+[DOM] NullPointerException in ParenthesizedExpression.resolveTypeBinding()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=253008">253008</a>
+[assist] Boolean expressions should be proposed with higher relevence in if(), while() etc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270983">270983</a>
+[formatter] Enum with field declarations but no constants confuses formatter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=159851">159851</a>
+[1.5] [compiler] Eclipse compiler fails to report type parameter bounds errors when generic instance is a type argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270446">270446</a>
+&quot;Compute launch button tooltip&quot; error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270148">270148</a>
+ASTParser cannot parse K_CLASS_BODY_DECLARATIONS with syntax errors
+
+<a name="v_947"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - March 31, 2009
+<br>Project org.eclipse.jdt.core v_947
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_947">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=270409">270409</a>
+[perfs] No JDT/Core tests results in last baseline run
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=267670">267670</a>
+Private enum constant incorrectly marked as never read locally
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269493">269493</a>
+[assist] Keywords are not proposed in a for statement without block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270194">270194</a>
+[1.5][compiler] Java error in 3.5M6 that was not present in 3.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270257">270257</a>
+[perfs] Small regression on 'JDT/Core plugin initialization' test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=270113">270113</a>
+[code assist] Missing ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION proposal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269985">269985</a>
+Full Build triggered when using class folder on classpath and custom builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207935">207935</a>
+[1.5][compiler] inconsistency with javac 1.5&amp;1.6 involving parameterized invocation of non-generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269964">269964</a>
+[perfs] Regression on 'Search all type names' test
+
+<a name="v_946"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - March 24, 2009
+<br>Project org.eclipse.jdt.core v_946
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_946">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=247037">247037</a>
+[javadoc] compiler should issue warning for {@inheritDoc} at illegal location
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244406">244406</a>
+[buildpath] Internal jars refered with OS path are shown as non-Java resources
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269476">269476</a>
+testInitJDTPlugin() seems to leak several DeltaProcessor and JavaModelManager
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=269336">269336</a>
+[prefs] JavaProject preferences listeners are not removed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=203060">203060</a>
+[codeassist] assert keyword should not be proposed when compliance level is set to 1.3
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251539">251539</a>
+[1.6][compiler] java.lang.IllegalArgumentException: info cannot be null (StackMapFrame.java)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=268837">268837</a>
+[1.6][compiler] Incorrectly report ambiguity of methods with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265104">265104</a>
+Reconciler cannot handle annotation with reference to missing type
+
+<a name="v_945"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M7 - March 17, 2009
+<br>Project org.eclipse.jdt.core v_945
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_945">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=267789">267789</a>
+eclipse-Automated-Tests-3.4.zip produces compile errors (build path?) with IBM JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=268802">268802</a>
+Useless call to getSource() in SourceTypeConverter
+
+<a name="v_944"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - March 10, 2009 - 3.5 MILESTONE 6
+<br>Project org.eclipse.jdt.core v_944
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_944">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=267941">267941</a>
+[perfs] Possible regression on 'Code assist in expression' test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=267773">267773</a>
+[open type] Use of ? results in error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=267658">267658</a>
+[formatter] Javadoc comments may be still formatted as block comments
+
+<a name="v_943"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - March 9, 2009
+<br>Project org.eclipse.jdt.core v_943
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_943">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=124646">124646</a>
+Connecting type parameter fails for local types
+
+<a name="v_942"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - March 7, 2009
+<br>Project org.eclipse.jdt.core v_942
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_942">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added the following APIs to allow clients to provide the source of a compilation unit or a package that is neither on the 
+       classpath nor in a working copy.
+       <ul>
+       <li><code>org.eclipse.jdt.core.WorkingCopyOwner.findSource(String, String)</code></li>
+       <li><code>org.eclipse.jdt.core.WorkingCopyOwner.isPackage(String[])</code></li>
+       </ul>
+       See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257528">bug 257528</a> for details.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=267088">267088</a>
+[1.5][compiler] Misleading error message in case of inherited methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260840">260840</a>
+NamingConventions creates wrong plural for name ending in &lt;vowel&gt;y
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243406">243406</a>
+[code assist] Content assist gives &quot;assertion failed&quot; for import Foo|.Bar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237241">237241</a>
+Content assist does not scale with javadoc on type with many members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265962">265962</a>
+[compiler] Internal compiler error on while with return clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236520">236520</a>
+[search] AIOOBE in PatternLocator.updateMatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265103">265103</a>
+Manifest Class-Path is not read correctly with ECJ
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99399">99399</a>
+[1.5][assist] Code assist propose final classes in methods type parameter extends clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257528">257528</a>
+An API to incrementaly generate compilation units for binding resolution environment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=266582">266582</a>
+[1.5][compiler] AbortCompilation while decoding the type variable of an anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=266837">266837</a>
+[model] SourceField.getConstant does not supply a value if type is fully qualified
+
+<a name="v_941"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - March 3, 2009
+<br>Project org.eclipse.jdt.core v_941
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_941">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=252442">252442</a>
+[Search] NPE after move followed by undo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=261722">261722</a>
+[search] NPE after removing a project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=266421">266421</a>
+[1.5][compiler] code compiles correctly in 3.4.1 but gives compilation errors in 3.5M5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260011">260011</a>
+[formatter] Formatting of html in javadoc comments doesn't work with style attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217108">217108</a>
+[formatter] deletes blank lines between comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198963">198963</a>
+[formatter] 3.3 Code Formatter repeatedly indents block comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265571">265571</a>
+Abstract method that is not directly used is flagged as unused
+
+<a name="v_940"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - February 24, 2009
+<br>Project org.eclipse.jdt.core v_940
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_940">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Fixed odd API in <code>ReferenceMatch</code><br>
+(see more details in bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248878">248878</a>).
+</li>
+</ul>
+
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265820">265820</a>
+Unused methods inside org.eclipse.jdt.internal.core.dom.rewrite.ImportRewriteAnalyzer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233356">233356</a>
+[search] NPE in org.eclipse.jdt.internal.compiler.util.SimpleLookupTable.get()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265630">265630</a>
+[search][perfs] Regression in testSearchPackageDeclarationsWorkspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248878">248878</a>
+[search] Odd API in ReferenceMatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=206930">206930</a>
+[1.5][compiler] Mismatch between javac and Eclipse compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265142">265142</a>
+Compiler fails to warn on unused constructors of private classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264950">264950</a>
+[scanner] IScanner does not return whitespace token
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264843">264843</a>
+[1.5][compiler] Eclipse compiler fails to reject invalid code with primitives autoboxed to generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=265065">265065</a>
+[search] java.lang.ClassCastException while running &quot;Refactor...Extract Class&quot;
+
+<a name="v_939"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - February 17, 2009
+<br>Project org.eclipse.jdt.core v_939
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_939">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API method on <code>SearchPattern</code> to provide matching
+regions between a pattern and a name when they are compared using a given match rule<br>
+(see more details in bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218605">218605</a>).
+<pre>
+/**
+ * Answers all the regions in a given name matching a given pattern using
+ * a specified match rule.
+ * 
+ * Each of these regions is made of its starting index and its length in the given
+ * name. They are all concatenated in a single array of <code>int</code>
+ * which therefore always has an even length.
+ * 
+ * All returned regions are disjointed from each other. That means that the end
+ * of a region is always different than the start of the following one.
+ * For example, if two regions are returned:
+ * <code>{ start1, length1, start2, length2 }</code>
+ * then <code>start1+length1</code> will always be smaller than
+ * <code>start2</code>.
+ * 
+ * The possible comparison rules between the name and the pattern are:
+ *     . {@link #R_EXACT_MATCH exact matching}
+ *     . {@link #R_PREFIX_MATCH prefix matching}
+ *     . {@link #R_PATTERN_MATCH pattern matching}
+ *     . {@link #R_CAMELCASE_MATCH camel case matching}
+ *     . {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH camel case matching with same parts count}
+ *
+ * Each of these rules may be combined with the
+ * {@link #R_CASE_SENSITIVE case sensitive flag} if the match comparison
+ * should respect the case.
+ *
+ * Examples:
+ *    .   pattern = "NPE"
+ *        name = NullPointerException / NoPermissionException
+ *        matchRule = {@link #R_CAMELCASE_MATCH}
+ *        result:  { 0, 1, 4, 1, 11, 1 } / { 0, 1, 2, 1, 12, 1 } 
+ *     .  pattern = "NuPoEx"
+ *        name = NullPointerException
+ *        matchRule = {@link #R_CAMELCASE_MATCH}
+ *        result:  { 0, 2, 4, 2, 11, 2 }
+ *     .  pattern = "IPL3"
+ *        name = "IPerspectiveListener3"
+ *        matchRule = {@link #R_CAMELCASE_MATCH}
+ *        result:  { 0, 2, 12, 1, 20, 1 }
+ *     .  pattern = "HashME"
+ *        name = "HashMapEntry"
+ *        matchRule = {@link #R_CAMELCASE_MATCH}
+ *        result:  { 0, 5, 7, 1 }
+ *     .  pattern = "N???Po*Ex?eption"
+ *        name = NullPointerException
+ *        matchRule = {@link #R_PATTERN_MATCH} | {@link #R_CASE_SENSITIVE}
+ *        result:  { 0, 1, 4, 2, 11, 2, 14, 6 }
+ *     .  pattern = "Ha*M*ent*"
+ *        name = "HashMapEntry"
+ *        matchRule = {@link #R_PATTERN_MATCH}
+ *        result:  { 0, 2, 4, 1, 7, 3 }
+ * 
+ * @see #camelCaseMatch(String, String, boolean) for more details on the
+ * 	camel case behavior
+ * @see CharOperation#match(char[], char[], boolean) for more details on the
+ * 	pattern match behavior
+ *
+ * @param pattern the given pattern. If <code>null</code>,
+ *     then an empty region (<code>new int[0]</code>) will be returned
+ *     showing that the name matches the pattern but no common
+ *     character has been found.
+ * @param name the given name
+ * @param matchRule the rule to apply for the comparison.
+ *     The following values are accepted:
+ *         . {@link #R_EXACT_MATCH}
+ *         . {@link #R_PREFIX_MATCH}
+ *         . {@link #R_PATTERN_MATCH}
+ *         . {@link #R_CAMELCASE_MATCH}
+ *         . {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}
+ * 
+ *     Each of these valid values may be also combined with
+ *     the {@link #R_CASE_SENSITIVE} flag.
+ * 
+ *     Some examples:
+ *         . {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}:
+ *           if an exact case sensitive match is expected,
+ *         . {@link #R_PREFIX_MATCH}:
+ *           if a case insensitive prefix match is expected,
+ *         . {@link #R_CAMELCASE_MATCH}:
+ *           if a case insensitive camel case match is expected,
+ *         . {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}
+ *            | {@link #R_CASE_SENSITIVE}:
+ *           if a case sensitive camel case with same parts count match
+ *           is expected,
+ *         . etc.
+ * 
+ * @return an array of <code>int</code> having two slots per returned
+ *     regions (the first one is the region starting index and the second one
+ *     is the region length or <code>null</code> if the given name does not
+ *     match the given pattern).
+ *
+ *     The returned regions may be empty (<code>new int[0]</code>) if the
+ *     pattern is <code>null</code> (whatever the match rule is). The returned
+ *     regions will also be empty if the pattern is only made of <code>'?'</code>
+ *     and/or <code>'*'</code> character(s) (e.g. <code>'*'</code>,
+ *     <code>'?*'</code>, <code>'???'</code>, etc.) when using a pattern
+ *     match rule.
+ * 
+ * @since 3.5
+ */
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264991">264991</a>
+Wrong 'unused' problem reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237742">237742</a>
+[javadoc] Javadoc tag name validation is incorrect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264843">264843</a>
+[1.5][compiler] Eclipse compiler fails to reject invalid code with primitives autoboxed to generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264881">264881</a>
+[1.5][compiler]Incorrect unchecked conversion warnings for return types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=201912">201912</a>
+[compiler] Unused public members of private classes not flagged
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264817">264817</a>
+[search] &lt;char&gt; + * returns 'null' from SearchPattern.getMatchingRegions(String, String, int)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264816">264816</a>
+[search] AIOOBE in StringOperation.getPatternMatchingRegions(..) with pattern &quot;?*&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250454">250454</a>
+[search] Cannot find method references between projects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218605">218605</a>
+[search] SearchPattern: provide way to get the matching regions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263558">263558</a>
+Can't compile package-info.java from FindBugs with 3.5 Eclipse
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=264443">264443</a>
+[parser] ASTParser.createASTs and IVariableBinding
+
+<a name="v_938"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - February 10, 2009
+<br>Project org.eclipse.jdt.core v_938
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_938">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=261594">261594</a>
+Adjust code to new PRE_REFRESH semantics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263877">263877</a>
+[1.5][compiler] forward reference error flagged within enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263633">263633</a>
+[1.5][compiler] Invalid type mismatch for after generic method inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262932">262932</a>
+[assist] Constructor completion makes array allocation difficult
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263653">263653</a>
+patch for jdt.core.model.tests to accommodate icu 4.0.1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246627">246627</a>
+[ast rewrite] Wrong indentation for statement inserted before SwitchCase
+
+<a name="v_937"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M6 - February 3, 2009
+<br>Project org.eclipse.jdt.core v_937
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_937">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=202393">202393</a>
+[compiler] Incomplete code coverage or useless statement within ThrowStatement#resolve
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=263215">263215</a>
+[1.5][compiler]  I20090129-1200 generates suddenly an generics compile error that 3.5M4  didnt do
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=261510">261510</a>
+[compiler] Deadlock in static initializer of JDT classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262517">262517</a>
+[ast rewrite] Whitespace settings in formatter ignored when adding annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260848">260848</a>
+[perfs] Regression on JDT/Core plugin initialization performance test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257716">257716</a>
+[compiler] Erroneous blank field may not have been initialized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262408">262408</a>
+remove deprecated NamingConventions.VK_CONSTANT_FIELD
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262717">262717</a>
+Wrong line numbers in classfile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262568">262568</a>
+improve Javadoc for ICompilationUnit.applyTextEdit(TextEdit, IProgressMonitor)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262389">262389</a>
+Internal code must not use ICompilationUnit.applyTextEdit
+
+<a name="v_936"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - January 27, 2009 - 3.5 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_936
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_936">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=262304">262304</a>
+[1.5][compiler] Enum constant in annotation value: javac vs Eclipse differ
+
+<a name="v_935"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - January 25, 2009
+<br>Project org.eclipse.jdt.core v_935
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_935">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added APIs to take into account the generic type and the rank of a wildcard type binding:
+       <code>ITypeBinding#getGenericTypeOfWildcardType()</code>, <code>ITypeBinding#getRank()</code>, and
+       <code>BindingKey#createWildcardTypeBindingKey(String genericTypeKey, char boundKind, String boundTypeKey, int rank)</code>.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262208">262208</a>
+[1.5][compiler]Incorrect @Override and name clash errors 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262209">262209</a>
+[1.5][compiler]Incorrect ambiguous method calls 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=234609">234609</a>
+[dom] BindingKey#toSignature() fails with key from createWilcardTypeBindingKey(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=261973">261973</a>
+[assist] Constructor completion should be improved (bug 6930)
+
+<a name="v_934"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - January 20, 2009
+<br>Project org.eclipse.jdt.core v_934
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_934">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new API to propose constructor completion<br>
+When "new ArrayLis" is completed now constructors are proposed instead of type references.
+This new completion kind is <code>CONSTRUCTOR_INVOCATION</code> and this proposal has always a 
+<code>TYPE_REF</code> required proposal to describe the type of the constructor.
+The <code>CONSTRUCTOR_INVOCATION</code> has "()" as completion string and <code>TYPE_REF</code> has
+"java.util.ArrayList" as completion string.<br>
+There is also a similar new API to complete anonymous type constructor: <code>ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION</code><br>
+
+
+<pre>
+
+	/**
+	 * Completion is a reference to a constructor.
+	 * This kind of completion might occur in a context like
+	 * &lt;code&gt;"new Lis"&lt;/code&gt; and complete it to
+	 * &lt;code&gt;"new List();"&lt;/code&gt; if List is a class that is not abstract.
+	 * &lt;p&gt;
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * &lt;ul&gt;
+	 * &lt;li&gt;{@link #getDeclarationSignature()} -
+	 * the type signature of the type that declares the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getFlags()} -
+	 * the modifiers flags of the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getName()} -
+	 * the simple name of the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getSignature()} -
+	 * the method signature of the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor}
+	 * (e.g. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)}).&lt;br&gt;
+	 * This kind of proposal is always is only proposals with a {@link #TYPE_REF} required proposal, so this kind of required proposal must be allowed:
+	 * &lt;code&gt;requestor.setAllowsRequiredProposals(CONSTRUCTOR_INVOCATION, TYPE_REF, true)&lt;/code&gt;.
+	 * &lt;/p&gt;
+	 *
+	 * @see #getKind()
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int CONSTRUCTOR_INVOCATION = 26;
+	
+	/**
+	 * Completion is a reference of a constructor of an anonymous class.
+	 * This kind of completion might occur in a context like
+	 * &lt;code&gt;"new Lis^;"&lt;/code&gt; and complete it to
+	 * &lt;code&gt;"new List() {}"&lt;/code&gt; if List is an interface or abstract class.
+	 * &lt;p&gt;
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * &lt;ul&gt;
+	 * &lt;li&gt;{@link #getDeclarationSignature()} -
+	 * the type signature of the type being implemented or subclassed
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getDeclarationKey()} -
+	 * the type unique key of the type being implemented or subclassed
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getSignature()} -
+	 * the method signature of the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getKey()} -
+	 * the method unique key of the constructor that is referenced
+	 * if the declaring type is not an interface
+	 * &lt;/li&gt;
+	 * &lt;li&gt;{@link #getFlags()} -
+	 * the modifiers flags of the constructor that is referenced
+	 * &lt;/li&gt;
+	 * &lt;/ul&gt;
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * This kind of proposal could require a long computation, so they are computed only if completion operation is called with a {@link IProgressMonitor}
+	 * (e.g. {@link ICodeAssist#codeComplete(int, CompletionRequestor, IProgressMonitor)})&lt;br&gt;
+	 * This kind of proposal is always is only proposals with a {@link #TYPE_REF} required proposal, so this kind of required proposal must be allowed:
+	 * &lt;code&gt;requestor.setAllowsRequiredProposals(CONSTRUCTOR_INVOCATION, TYPE_REF, true)&lt;/code&gt;.
+	 * &lt;/p&gt;
+	 *
+	 * @see #getKind()
+	 * @see CompletionRequestor#setAllowsRequiredProposals(int, int, boolean)
+	 * 
+	 * @since 3.5
+	 */
+	public static final int ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION = 27;
+</pre>
+These new proposals can require a long computation so they are proposed only if code assist was called with a progress monitor.
+To avoid that the code assist operation takes too much time a <code>IProgressMonitor</code> which automatically cancel the code
+assist operation when a specified amount of time is reached could be used.
+
+<pre>
+new IProgressMonitor() {
+    private final static int TIMEOUT = 500; //ms
+    private long endTime;
+    public void beginTask(String name, int totalWork) {
+        fEndTime= System.currentTimeMillis() + TIMEOUT;
+    }
+    public boolean isCanceled() {
+        return endTime &lt;= System.currentTimeMillis();
+    }
+    ...
+ };
+</pre>
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6930">bug 6930</a> required the index version to be incremented. 
+    Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress 
+    dialogs) and the size of the new indexes will be bigger.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260717">260717</a>
+[assist] Constructors should be proposed even when the declaring type is not imported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=6930">6930</a>
+[assist] Constructor completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=220311">220311</a>
+[1.5][compiler] package-info.java does not recognise duplicate annotations as a problem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=259685">259685</a>
+Bogus build error &quot;Cannot nest&quot; xyz &quot;inside library&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260798">260798</a>
+[formatter] Strange behavior of never join lines
+
+<a name="v_933"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - January 13, 2009
+<br>Project org.eclipse.jdt.core v_933
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_933">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Improved generic method inference to better match JLS 15.12.2.6. The compiler now infers better in presence of unchecked conversion in argument types (raw types). </li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=214948">214948</a>
+Incorrect deprecation warning on annotation instances
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260276">260276</a>
+[formatter] Inconsistent formatting of one-line block comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239607">239607</a>
+[formatter] Incorrect removal of asterisk (*) within a block comment when formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=254998">254998</a>
+[formatter] wrong type comment format during code generation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=258798">258798</a>
+[1.5][compiler] Return type should be erased after unchecked conversion during inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=258906">258906</a>
+[jsr269] Package annotations not visible to Java 6 APT processors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=259633">259633</a>
+[1.5][compiler] Bound of type parameter of class in method not checked
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=149768">149768</a>
+Annotations should be a compilation dependency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=260257">260257</a>
+Reduce space taken by SourceRefElementInfos
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=259607">259607</a>
+Deadlock opening launch configuration dialog
+
+<a name="v_932"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - January 6, 2009
+<br>Project org.eclipse.jdt.core v_932
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_932">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=258145">258145</a>
+Fup of bug 252555, JME is thrown when package-info.java exists twice in the same project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=259129">259129</a>
+[compiler] Fup of bug 258950, wrong line number attribute for cascading method invocations
+
+<a name="v_931"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M5 - December 16, 2008
+<br>Project org.eclipse.jdt.core v_931
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_931">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=171136">171136</a>
+[buildpath] Illegal type of archive for required library is an incorrect message.
+
+<a name="v_930"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - December 10, 2008 - 3.5 MILESTONE 4
+<br>Project org.eclipse.jdt.core v_930
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_930">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=255008">255008</a>
+[compiler] Assert statement discrepancy with javac caused by an uninitialized variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=258039">258039</a>
+[1.5][compiler] Misleading error message for &quot;instanceof List&lt;Object&gt;&quot;
+
+<a name="v_929"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - December 8, 2008
+<br>Project org.eclipse.jdt.core v_929
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_929">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added property to adjust the size of the openable cache: "org.eclipse.jdt.core.javamodelcache.ratio". For example, starting Eclipse as follows will increase the
+     size of the openable cache by 50%: 
+     <pre>eclipse.exe -vmArgs -Dorg.eclipse.jdt.core.javamodelcache.ratio=1.5</pre>
+</li>
+<li>
+As users may want to have different behavior in comments, the new formatter
+preference to preserve line breaks is now controlled by two different options:
+<ul>
+<li>for the already wrapped code lines:<br>
+<code>DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES</code>
+<pre>
+/**
+ * FORMATTER / Option to specify whether the formatter can join wrapped lines or not
+ * 
+ * 		For example, the wrapped lines of method foo return statement in following test case:
+ * 			class X {
+ * 			String foo() {
+ * 			return "select x "
+ * 			       + "from y "
+ * 			       + "where z=a";
+ * 			}
+ * 			}
+ *
+ * 		will be preserved by the formatter when the new preference is used
+ * 		even if the maximum line width would give it enough space to join the lines.
+ * 		Hence produces the following output:
+ * 			class X {
+ * 			    String foo() {
+ * 			        return "select x "
+ * 			                + "from y "
+ * 			                + "where z=a";
+ * 			    }
+ * 			}
+ *
+ *     - option id:         "org.eclipse.jdt.core.formatter.join_wrapped_lines"
+ *     - possible values:   { TRUE, FALSE }
+ *     - default:           TRUE
+ * 
+ * @since 3.5
+ */
+</pre>
+</li>
+<li>for the lines in comments:<br>
+<code>DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS</code>
+<pre>
+/**
+ * FORMATTER / Option to specify whether the formatter can join text lines in comments or not
+ * 
+ * 		For example, the following comment:
+ * 			/**
+ * 			 * The foo method.
+ * 			 * foo is a substitute for bar.
+ * 			 */
+ * 			public class X {
+ * 			}
+ * 
+ * 		will be unchanged by the formatter when this new preference is used,
+ * 		even if the maximum line width would give it enough space to join the lines.
+ *
+ *     - option id:         "org.eclipse.jdt.core.formatter.join_lines_in_comments"
+ *     - possible values:   { TRUE, FALSE }
+ *     - default:           TRUE
+ *
+ * @since 3.5
+ */
+</pre>
+</li>
+</ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257907">257907</a>
+[Formatter] FORMATTER_PRESERVE_EXISTING_LINE_BREAKS needs clarification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257906">257906</a>
+[Formatter] should have separate 'preserve existing line breaks' for code and comment formatting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232816">232816</a>
+[buildpath] Misleading problem text for missing jar in user library
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257849">257849</a>
+[1.5][compiler] Internal compiler error using generics w/ abstract classes &amp; interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257869">257869</a>
+Adjust Java model cache size using a property
+
+<a name="v_928"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - December 7, 2008
+<br>Project org.eclipse.jdt.core v_928
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_928">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+Added a new formatter preference to preserve existing breaks in already wrapped and comments lines.<br>
+<p>
+For example, the wrapped lines of method foo return statement in following test case:
+</p>
+<pre>
+class X {
+String foo() {
+return "select x "
+       + "from y "
+       + "where z=a";
+}
+}
+</pre>
+will be preserved by the formatter when the new preference is used, hence produces
+now the following output:
+<pre>
+class X {
+    String foo() {
+        return "select x "
+                + "from y "
+                + "where z=a";
+    }
+}
+</pre>
+Similarly, following comment:
+<pre>
+/**
+ * The foo method.
+ * foo is a substitute for bar.
+ */
+public class X {
+}
+</pre>
+is now unchanged by the formatter when this new preference is used...<br>
+<p>
+This diagnosis is controlled by the option:<br>
+<code>DefaultCodeFormatterConstants.FORMATTER_PRESERVE_EXISTING_LINE_BREAKS</code>:</p>
+<pre>
+/**
+ * FORMATTER / Option to specify whether the formatter should preserve existing line breaks or not
+ *     - option id:         "org.eclipse.jdt.core.formatter.preserve_existing_line_breaks"
+ *     - possible values:   { TRUE, FALSE }
+ *     - default:           FALSE
+ * @since 3.5
+ */
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257434">257434</a>
+[1.5][compiler] Should detect type mismatch after capture
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257384">257384</a>
+AIOOBE during problem reporting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239130">239130</a>
+[formatter] Comment formatter does not keep blank lines after @see references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198074">198074</a>
+[formatter] the code formatter doesn't respect my new lines
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256799">256799</a>
+[formatter] Formatter wrongly adds space to //$FALL-THROUGH$ is
+
+<a name="v_927"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - December 2, 2008
+<br>Project org.eclipse.jdt.core v_927
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_927">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+Improved dead code detection by having it (optionally) tolerate trivial IF statement,
+such as <code>if (DEBUG) ...</code>. This extra option is defined by
+<code>JavaCore.COMPILER_PB_DEAD_CODE_IN_TRIVIAL_IF_STATEMENT</code>.
+<pre>
+* Compiler option ID: Reporting Dead Code Inside Trivial If Statement.
+* When enabled, the compiler will signal presence of dead code inside trivial IF statement, e.g. if (DEBUG)...
+* The severity of the problem is controlled with option {@link #COMPILER_PB_DEAD_CODE}.
+* 
+* Option id:"org.eclipse.jdt.core.compiler.problem.deadCodeInTrivialIfStatement"
+* Possible values:{ "enabled", "disabled" }
+* Default:"warning"
+</pre>
+</li>
+<li>Dead code detection warning also got enabled by default.
+<pre>
+* Compiler option ID: Reporting Dead Code.
+* When enabled, the compiler will issue an error or a warning if some non fatal dead code is detected. For instance, if (false) foo();
+* is not reported as truly unreachable code by the Java Language Specification. If this diagnostic is enabled, then the invocation of foo() is
+* going to be signaled as being dead code.
+* Option id:"org.eclipse.jdt.core.compiler.problem.deadCode"
+* Possible values:{ "error", "warning", "ignore" }
+* Default:"warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256329">256329</a>
+Impossible NPE in JavaModelManager.getOptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256882">256882</a>
+[compiler] Enable DeadCode detection by default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255970">255970</a>
+test tear down failed causing cascade of failures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207093">207093</a>
+Perf: adding a new top-level package is slow if many source files exist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=252948">252948</a>
+Unncessary compilation when adding packages with an existing path segment at the beginning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256735">256735</a>
+Marker property value is too long for internal compiler error (java.lang.StackOverflowError)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227986">227986</a>
+Avoid duplicated strings in Java model
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256463">256463</a>
+[compiler] Support common debug pattern in unreachable code detection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256679">256679</a>
+[perfs] SearchAllTypeNames performance tests are slower on eplnx2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=228845">228845</a>
+[hierarchy] Type hierarchy should include subtypes in primary working copies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=252571">252571</a>
+[buildpath] External folder appears empty after workspace move
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=256404">256404</a>
+Wrong handle identifier for external library folder
+
+<a name="v_926"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - November 25, 2008
+<br>Project org.eclipse.jdt.core v_926
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_926">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+Added a new compiler warning to signal presence of dead code,  e.g. <code>if (false) deadCode(); </code>.
+This diagnosis is controlled by option: 
+<code>JavaCore.COMPILER_PB_DEAD_CODE</code> and produces a problem marker which ID is <code>IProblem.DeadCode</code> problem ID.
+<pre>
+* Compiler option ID: Reporting Dead Code.
+* When enabled, the compiler will issue an error or a warning if some non fatal dead code is detected. For instance, if (false) foo();
+* is not reported as truly unreachable code by the Java Language Specification. If this diagnostic is enabled, then the invocation of foo() is
+* going to be signaled as being dead code.
+* Option id:"org.eclipse.jdt.core.compiler.problem.deadCode"
+* Possible values:{ "error", "warning", "ignore" }
+* Default:"ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251504">251504</a>
+[index] Wrong indexes may be used while performing a search request
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48399">48399</a>
+[compiler] Enhance unreachable code detection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=254825">254825</a>
+[javadoc] compile error when referencing outer param from inner class javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=252555">252555</a>
+[javadoc] NPE on duplicate package-info
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251690">251690</a>
+[compiler] NPE if type collides with a package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249134">249134</a>
+[compiler] error message (implement abstract method) not as intended
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154162">154162</a>
+[1.5][compiler] Uninformative error message for qualified enum constants in switch statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255974">255974</a>
+Abusive usage of InvalidInputException in the compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251693">251693</a>
+NamingConventions.suggestXXXNames should call suggestVariableNames()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255345">255345</a>
+Problems in new NamingConventions APIs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255452">255452</a>
+[1.5][compiler] Eclipse allows forward reference in enum constructor
+
+<a name="v_925"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - November 18, 2008
+<br>Project org.eclipse.jdt.core v_925
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_925">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=255501">255501</a>
+EncodingTests failing when run by itself
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=255035">255035</a>
+[compiler] Internal compile error gets reported (NPE)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250297">250297</a>
+[compiler] NPE in org.eclipse.jdt.internal.compiler.problem.ProblemReporter.missingTypeInMethod(ProblemReporter.java:4925)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232558">232558</a>
+[compiler] += is not allowed between Object and String
+
+<a name="v_924"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - November 10, 2008
+<br>Project org.eclipse.jdt.core v_924
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_924">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=252868">252868</a>
+[batch][compiler] ConcurrentModificationException in org.eclipse.jdt.internal.compiler.batch.ClasspathJar.fetchLinkedJars
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236242">236242</a>
+[compiler][1.7] compiler difference to javac 7 involving parameterized uses of raw methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211256">211256</a>
+[ast rewrite] whitespace missing between return and expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=253891">253891</a>
+Incorrect tag closure in JavaModel javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=252120">252120</a>
+[1.5][compiler] raw type diagnostic not coherent with javac one
+
+<a name="v_923"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M4 - November 4, 2008
+<br>Project org.eclipse.jdt.core v_923
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_923">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=250211">250211</a>
+[search] Organize Imports Hangs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241821">241821</a>
+[compiler] Multiple interfaces and incompatible return types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251279">251279</a>
+[1.5][compiler] Covariant generics interfaces causes compile error
+
+<a name="v_922"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 29, 2008 - 3.5 MILESTONE 3
+<br>Project org.eclipse.jdt.core v_922
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_922">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=252481">252481</a>
+[code assist] NPE in findAllTypes
+
+<a name="v_921"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 28, 2008
+<br>Project org.eclipse.jdt.core v_921
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_921">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=252264">252264</a>
+Invalid classpath header messages should be logged in verbose mode only
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=252392">252392</a>
+Missing jars referenced in the Class-Path: clause of a MANIFEST.MF file should not be reported as errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247845">247845</a>
+[misc] Errors in log from fetching Javadoc when working disconnected
+
+<a name="v_920"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 25, 2008
+<br>Project org.eclipse.jdt.core v_920
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_920">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>NamingConventions has now a more flexible API to suggest variable name: <code>NamingConventions.suggestVariableNames()</code>.<br>
+The same method can be used to suggest local, instance field, static field and constant field name.
+This method use a new specific heuristic to generate constant name with upper case and underscore (e.g. <code>CONSTANT_FIELD_NAME</code>).
+<pre>
+public static String[] suggestVariableNames(
+			int variableKind,
+			int baseNameKind,
+			String baseName,
+			IJavaProject javaProject,
+			int dim,
+			String[] excluded,
+			boolean evaluateDefault)
+</pre>
+</li>
+<li>NamingConventions has now an API to compute the name used to generate a variable name: <code>NamingConventions.getBaseName()</code>.<br>
+<pre>
+public static String getBaseName(
+			int variableKind,
+			String variableName,
+			IJavaProject javaProject)
+</pre>
+</li>
+<li>New options are added to specify the prefixes and suffixes of a constant field: <code>JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES</code> and <code>JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES</code>.
+</li></ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250975">250975</a>
+[1.5][compiler] Stack overflow on static import.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249785">249785</a>
+[javadoc][assist] Javadoc content assist after &quot;@see #&quot; does not work with deprecated member before
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249692">249692</a>
+The ImportRewriteAnalyzer does not honor a formatter setting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251814">251814</a>
+[1.5][compiler] Dup Enum#valueOf(...) should keep the synthetic one
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248309">248309</a>
+[model] IAnnotatable#getAnnotations() does not work for standard annotations on binary members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251518">251518</a>
+Tons of invalid API tooling errors when checking out jdt.core
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251356">251356</a>
+Fix for bug 146768 breaks JDT Refactoring and its test
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249027">249027</a>
+NPE in Engine if type collides with a package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85946">85946</a>
+NamingConventions.suggestFieldNames(..) does not consider 'final' modifier for constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38111">38111</a>
+[DCR] Make NamingConventions more flexible
+
+<a name="v_919"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 21, 2008
+<br>Project org.eclipse.jdt.core v_919
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_919">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>The compiler is now better resilient with duplicate field/method definitions and will avoid secondary errors 
+detected when subsenquently using the offending field/method.
+</li></ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251523">251523</a>
+[1.5][compiler] Should still flag Enum#valueOf override
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246276">246276</a>
+NPE during code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249844">249844</a>
+IBinding#getJavaElement() always returns null for IAnnotationBindings declared in annotation or enum types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=146768">146768</a>
+[compiler] Should be more resilient with duplicate fields/methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251091">251091</a>
+Covariant return types not honored for combined extension and implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=251079">251079</a>
+Got error dialog after switching default JRE
+
+<a name="v_918"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 16, 2008
+<br>Project org.eclipse.jdt.core v_918
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_918">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New API for the ASTVisitor class: <code>org.eclipse.jdt.core.dom.ASTVisitor.preVisit2(ASTNode)</code>.<br>
+New API type: <code>org.eclipse.jdt.core.dom.NodeFinder</code>.<br>
+All details are available in bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53024">53024</a>.<br>
+These new APIs are still under discussion and are released for JDT/UI adoption.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250946">250946</a>
+Bogus jar file is added to the project build path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250022">250022</a>
+Java Model Exception: Java Model Status when getting code assist in debug detail formatter dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53024">53024</a>
+[DOM] Move NodeFinder to a non-internal package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250753">250753</a>
+[formatter] Insert space between empty braces in array initializers ignored without &quot;Keep empty array initializer on one line&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248319">248319</a>
+[compiler][1.5] Valid Java source produces class file that doesn't verify (VerifyError, javac compiles correctly)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249567">249567</a>
+Incorrect behavior of Util.getUnresolvedJavaElement(...) method
+
+<a name="v_917"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 14, 2008
+<br>Project org.eclipse.jdt.core v_917
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_917">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Duplicate classpath entries are no longer reported if they are duplicate because of the classpath resolution
+      (e.g. if two classpath containers add the same entry to the resolved classpath).
+       Duplicate classpath entries at the raw classpath level are still reported.
+       See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175226">bug 175226</a> for details.
+</li>
+<li>
+Added a new compiler warning to report a missing hashCode() method when overriding the equals() method from Object. 
+This diagnosis is controlled by option: 
+<code>JavaCore.COMPILER_PB_MISSING_HASHCODE_METHOD</code> and produces a problem marker which ID is
+<code>IProblem.MissingHashCodeMethod</code> problem ID.
+<pre>
+  Compiler option ID: Reporting Missing HashCode Method.
+  When enabled, the compiler will issue an error or a warning if a type
+  overrides Object.equals(Object) but does not override hashCode().
+  Option id: "org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod"
+  Possible values: { "error", "warning", "ignore" }
+  Default: "ignore"
+</pre>
+</li>
+<li>The "Class-Path:" clause of a jar manifest is now honored in the Java model. Jars referenced by "Class-Path:" are now automatically
+      added to the build path. See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198572">bug 198572</a> for details.</li>
+<li>Code Select search types outside the current project scope if no types are found in this scope</li>
+<li>Code Assist operation can be called with a progress monitor:
+<pre>
+public interface ICodeAssist {
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The &lt;code&gt;offset&lt;/code&gt;
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An &lt;code&gt;offset&lt;/code&gt; of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * &lt;p&gt;
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * &lt;/p&gt;
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:&lt;ul&gt;
+	 *  &lt;li&gt;This Java element does not exist (ELEMENT_DOES_NOT_EXIST)&lt;/li&gt;
+	 *  &lt;li&gt; The position specified is &lt; -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * &lt;/ul&gt;
+	 *
+	 * @exception IllegalArgumentException if &lt;code&gt;requestor&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;
+	 * @since 3.0
+	 * @deprecated Use {@link #codeComplete(int, CompletionRequestor, WorkingCopyOwner)} instead.
+	 */
+	void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner)
+		throws JavaModelException;
+
+	/**
+	 * Performs code completion at the given offset position in this compilation unit,
+	 * reporting results to the given completion requestor. The &lt;code&gt;offset&lt;/code&gt;
+	 * is the 0-based index of the character, after which code assist is desired.
+	 * An &lt;code&gt;offset&lt;/code&gt; of -1 indicates to code assist at the beginning of this
+	 * compilation unit.
+	 * &lt;p&gt;
+	 *
+	 * @param offset the given offset position
+	 * @param requestor the given completion requestor
+	 * @exception JavaModelException if code assist could not be performed. Reasons include:&lt;ul&gt;
+	 *  &lt;li&gt;This Java element does not exist (ELEMENT_DOES_NOT_EXIST)&lt;/li&gt;
+	 *  &lt;li&gt; The position specified is &lt; -1 or is greater than this compilation unit's
+	 *      source length (INDEX_OUT_OF_BOUNDS)
+	 * &lt;/ul&gt;
+	 *
+	 * @exception IllegalArgumentException if &lt;code&gt;requestor&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;
+	 * @since 3.0
+ 	 */
+	void codeComplete(int offset, CompletionRequestor requestor)
+		throws JavaModelException;
+}
+
+public interface IType {
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 *
+	 * If the type can access to his source code and the insertion position is valid,
+	 * then completion is performed against source. Otherwise the completion is performed
+	 * against type structure and given locals variables.
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position within snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.5
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Do code completion inside a code snippet in the context of the current type.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * &lt;p&gt;
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * &lt;/p&gt;&lt;p&gt;
+	 * If the type can access to his source code and the insertion position is valid,
+	 * then completion is performed against source. Otherwise the completion is performed
+	 * against type structure and given locals variables.
+	 * &lt;/p&gt;
+	 *
+	 * @param snippet the code snippet
+	 * @param insertion the position with in source where the snippet
+	 * is inserted. This position must not be in comments.
+	 * A possible value is -1, if the position is not known.
+	 * @param position the position with in snippet where the user
+	 * is performing code assist.
+	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
+	 * type names of local variables visible at the current scope
+	 * @param localVariableNames an array (possibly empty) of local variable names
+	 * that are visible at the current scope
+	 * @param localVariableModifiers an array (possible empty) of modifiers for
+	 * local variables
+	 * @param isStatic whether the current scope is in a static context
+	 * @param requestor the completion requestor
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if this element does not exist or if an
+	 *		exception occurs while accessing its corresponding resource.
+	 * @since 3.5
+	 */
+	void codeComplete(
+		char[] snippet,
+		int insertion,
+		int position,
+		char[][] localVariableTypeNames,
+		char[][] localVariableNames,
+		int[] localVariableModifiers,
+		boolean isStatic,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+}
+
+public interface IEvaluationContext {
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * &lt;p&gt;
+	 * Note that code completion does not involve evaluation.
+	 * &lt;p&gt;
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  &lt;ul&gt;
+	 *	  &lt;li&gt;The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)&lt;/li&gt;
+	 *  &lt;/ul&gt;
+	 * @since 3.5
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+
+	/**
+	 * Performs a code completion at the given position in the given code snippet,
+	 * reporting results to the given completion requestor.
+	 * It considers types in the working copies with the given owner first. In other words,
+	 * the owner's working copies will take precedence over their original compilation units
+	 * in the workspace.
+	 * &lt;p&gt;
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * &lt;/p&gt;
+	 * &lt;p&gt;
+	 * Note that code completion does not involve evaluation.
+	 * &lt;p&gt;
+	 *
+	 * @param codeSnippet the code snippet to complete in
+	 * @param position the character position in the code snippet to complete at,
+	 *   or -1 indicating the beginning of the snippet
+	 * @param requestor the code completion requestor capable of accepting all
+	 *    possible types of completions
+	 * @param owner the owner of working copies that take precedence over their original compilation units
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if code completion could not be performed. Reasons include:
+	 *  &lt;ul&gt;
+	 *	  &lt;li&gt;The position specified is less than -1 or is greater than the snippet's
+	 *	    length (INDEX_OUT_OF_BOUNDS)&lt;/li&gt;
+	 *  &lt;/ul&gt;
+	 * @since 3.5
+	 */
+	public void codeComplete(
+		String codeSnippet,
+		int position,
+		CompletionRequestor requestor,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor)
+		throws JavaModelException;
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250685">250685</a>
+[assist] Code assist can bot be canceled when search indexes are not ready
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250083">250083</a>
+[model] Search indexes are not correctly updated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=175226">175226</a>
+[buildpath] Build path contains duplicate entry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=38751">38751</a>
+Optionally show compiler warning when equals() is overriden but hashCode() is not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249930">249930</a>
+Deadlock with JavaModelManager$PerProjectInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=250398">250398</a>
+[assist] Faults in javadoc of IType#codeComplete
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247941">247941</a>
+[assist] Add progress monitor to code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243820">243820</a>
+[1.5][compiler] Method has same erasure as an interface method but is not considered to implement it
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232880">232880</a>
+[select] Navigate to classes in workspace even if not on classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=198572">198572</a>
+eclipse does not respect class-path manifest of external jars
+
+<a name="v_916"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - October 7, 2008
+<br>Project org.eclipse.jdt.core v_916
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_916">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+The new compiler warning (added during 3.5M1) to signal absence of <code>synchronized</code> modifier 
+when overriding a synchronized method got disabled by default.
+<pre>
+  Compiler option ID: Reporting Missing Synchronized Modifier On Inherited Method.
+  When enabled, the compiler will issue an error or a warning if a method
+  overrides a synchronized method without having a synchronized modifier.
+  Option id: "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"
+  Possible values: { "error", "warning", "ignore" }
+  Default: "ignore"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249140">249140</a>
+[1.5][compiler] asymmetric errors with covariant inherited methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244762">244762</a>
+[1.5][compiler] Internal compiler error java.lang.NullPointerException after importing file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227527">227527</a>
+[1.5][compiler] Useless error message for local enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=227530">227530</a>
+[1.5][compiler] Incomplete error message for annotation inside a member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247981">247981</a>
+save on a single file (any type - java source, text file  
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249584">249584</a>
+CompilerParticipant constants should be marked as such
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=161977">161977</a>
+[compiler] Identical branches in org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding#syntheticMethods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249535">249535</a>
+[compiler] Consider disabling the syncOverride warning/error by default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247666">247666</a>
+[1.5][compiler] AIOOBE inside missing type reporting
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249321">249321</a>
+IPackagerFragmentRoot#getRawClasspathEntry() returns resolved &quot;..&quot; path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=249107">249107</a>
+[compiler] IllegalAccessError in presence of synthetic field access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247953">247953</a>
+[1.5][compiler] IllegalAccessError: tried to access class p.IA from class X
+
+<a name="v_915"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - September 30, 2008
+<br>Project org.eclipse.jdt.core v_915
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_915">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added support for ".." in classpath for library, variable and container entries.
+		See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57732">bug 57732</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248680">248680</a>
+Error when create a new element (class, interface,...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=57732">57732</a>
+[buildpath] relative build classpath leading outside of eclipse workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247612">247612</a>
+[compiler] Compiler could avoid allocating field bindings for receiver type change
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247757">247757</a>
+[model] Move a class to root package, lose block comment at the top
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241400">241400</a>
+[LinkedResources] Random errors when changing project settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248313">248313</a>
+[DOM] Javadoc bug in StringLiteral#setLiteralValue(String)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248308">248308</a>
+Typo in Javadoc of IBinding#getAnnotations()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=248243">248243</a>
+Add apt.pluggable.core as x-friend for jdt.core
+
+<a name="v_914"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M3 - September 23, 2008
+<br>Project org.eclipse.jdt.core v_914
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_914">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=247835">247835</a>
+SearchPattern extends non-API type InternalSearchPattern
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245858">245858</a>
+CompletionProposal extends non-API type InternalCompletionProposal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247688">247688</a>
+SearchDocument extends non-API type InternalSearchDocument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245860">245860</a>
+BuildContext extends non-API type CompilationParticipantResult
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247292">247292</a>
+[compiler] Compiler should avoid allocating method bindings for receiver type change
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245835">245835</a>
+CompletionContext extends non-API type InternalCompletionContext
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247618">247618</a>
+*ReferenceMatch extends non-API type InternalReferenceMatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247307">247307</a>
+[1.5][compiler] Array clone return type should be governed by source level instead of compliance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=128563">128563</a>
+[compiler] Inner class compiles but IllegalAccessError if splitted with two output folders
+
+<a name="v_913"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - September 13, 2008 - 3.5 MILESTONE 2
+<br>Project org.eclipse.jdt.core v_913
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_913">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=246955">246955</a>
+Add API compatibility filter for ITypeRoot
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=211054">211054</a>
+[javadoc] @see package reference should raise a warning except for the package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243692">243692</a>
+[buildpath] Cannot set Attached Source from Class File Editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207765">207765</a>
+[javadoc] Javadoc warning on @see reference could be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=247118">247118</a>
+Endless loop in Signature.encodeQualifiedName
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244164">244164</a>
+[1.5][compiler] Missing implementation error when referencing a generic field with error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233187">233187</a>
+[javadoc] partially qualified inner types  should be warned
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=170637">170637</a>
+[javadoc] incorrect warning about missing parameter javadoc when using many links
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=142990">142990</a>
+[model] Rename operation should not use workspace root rule
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246712">246712</a>
+[javadoc] Unexpected warning about missing parameter doc in case of @inheritDoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246682">246682</a>
+Inconsistent parser/scanner encoding for commentStart position
+
+<a name="v_912"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - September 9, 2008
+<br>Project org.eclipse.jdt.core v_912
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_912">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Introduced a marker comment (<code>$FALL-THROUGH$</code>) for silencing compiler diagnosis for switch case 
+falling through next case. This allows to document intended fall through situations in the code.
+Note: The marker comment can also be a block comment, i.e. <code>/* $FALL-THROUGH$ */</code>.
+<br>e.g. 
+<pre>
+    switch(val) {
+        case 0 :
+            doit(0);
+            // $FALL-THROUGH$ - also fall into next case
+       case 1:
+            doit(1);
+            break;
+    }
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245257">245257</a>
+[compiler] Allow to suppress fall-through warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240034">240034</a>
+[buildpath] Eclipse ignores .classpath file if it is encoded in UTF8 with BOM
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245963">245963</a>
+deprecate unused JavaCore.COMPILER_PB_BOOLEAN_METHOD_THROWING_EXCEPTION
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237772">237772</a>
+[implementation] Deadlock in JDT causing UI freeze
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114116">114116</a>
+[assist] name suggestion for collections
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=246066">246066</a>
+[batch] Redundant superinterface warning cannot be activated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245973">245973</a>
+[compiler] Problem irritant cannot exceed 64bit limit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244849">244849</a>
+[implementation] Memory leak in DeltaProcessingState#externalTimeStamps ?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=207657">207657</a>
+[search] Exception when refactoring member type to top-level.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243023">243023</a>
+[content assist] RuntimeException thrown by JavaTypeCompletionProposalComputer
+
+<a name="v_911"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - September 2, 2008
+<br>Project org.eclipse.jdt.core v_911
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_911">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>
+Added a new compiler warning to signal absence of <code>synchronized</code> modifier when overriding a synchronized method. 
+This diagnosis is controlled by option: 
+<code>JavaCore.COMPILER_PB_MISSING_SYNCHRONIZED_ON_INHERITED_METHOD</code> and produces a problem marker which ID is
+<code>IProblem.MissingSynchronizedModifierInInheritedMethod</code> problem ID;
+it may be suppressed using <code>@SuppressWarnings("super")</code>.
+<pre>
+  Compiler option ID: Reporting Missing Synchronized Modifier On Inherited Method.
+  When enabled, the compiler will issue an error or a warning if a method
+  overrides a synchronized method without having a synchronized modifier.
+  Option id: "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"
+  Possible values: { "error", "warning", "ignore" }
+  Default: "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222900">222900</a>
+[Javadoc] Missing description is warned if valid description is on a new line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=186858">186858</a>
+Intermittent failure of org.eclipse.jdt.core.tests.model.ExclusionPatternsTests#testCreateExcludedPackage2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237453">237453</a>
+[formatter] Save actions fails to remove excess new lines when set to &quot;format edited lines&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245830">245830</a>
+ClasspathEntry illegally instantiates AssertionFailedException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=242029">242029</a>
+Multiple source attachment paths don't work when source attachment path points to a folder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=234583">234583</a>
+[formatter] Code formatter should adapt edits instead of regions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245576">245576</a>
+No error message for updating read-only .classpath file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245563">245563</a>
+npe in reconciler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245518">245518</a>
+ICompilationUnit.createType failing with unexpected exception
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245435">245435</a>
+[1.5][compiler] &quot;Value for annotation attribute must be a constant expression&quot; error on valid constant expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=245348">245348</a>
+[DOM] Annotations are recognized by ASTParser even in COMPILER_SOURCE is set &lt; 1.5
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241751">241751</a>
+Using a ClasspathContainerInitializer requires the use of workspace lock
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=242448">242448</a>
+[1.5][compiler] Sun's javac compiles the following but jdt does not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239066">239066</a>
+[compiler] Overriding a Synchronized Method with a Non-synchronized Method
+
+<a name="v_910"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - August 26, 2008
+<br>Project org.eclipse.jdt.core v_910
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_910">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=239096">239096</a>
+Implementation oddness in TypeHierarchy#getAllSuper*(IType)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=244549">244549</a>
+JavaCore.create(String handleIdentifier) fails for local variable with parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241687">241687</a>
+[formatter] problem formatting block comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240686">240686</a>
+[formatter] Formatter do unexpected things
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=242933">242933</a>
+[1.5] NullPointerException for @Range(min=1, max=9999999999999999)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241345">241345</a>
+[formatter] Didn't Format HTML tags is unavailable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=242646">242646</a>
+deadlock on org.eclipse.jdt.internal.core.ExternalFoldersManager
+
+<a name="v_909"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - August 19, 2008
+<br>Project org.eclipse.jdt.core v_909
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_909">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=244477">244477</a>
+[formatter] Formatter fails on special Java array construct
+
+<a name="v_908"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M2 - August 11, 2008
+<br>Project org.eclipse.jdt.core v_908
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_908">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=239833">239833</a>
+[compiler] Odd compiler error message "Illegal modifier for the method ..."
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243715">243715</a>
+[DOM] Parser.createASTs() throws exception on 'illogical' JavaDoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=243653">243653</a>
+ASTRewrite is incorrectly documented
+
+<a name="v_907"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - August 6, 2008 - 3.5 MILESTONE 1
+<br>Project org.eclipse.jdt.core v_907
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_907">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=242961">242961</a> [DOM] ITypeBinding.getDeclaredFields returns empty results if any field has undefined type
+
+<a name="v_906"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 31, 2008
+<br>Project org.eclipse.jdt.core v_906
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_906">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=242292">242292</a>
+call to createAST(..) throws IllegalStateException when parser source is not char[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=218500">218500</a>
+[dom] bug in ITypeBinding.getQualifiedName for member of local type
+
+<a name="v_905"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 28, 2008
+<br>Project org.eclipse.jdt.core v_905
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_905">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=236096">236096</a>
+Incorrectly allow raw return type in overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238014">238014</a>
+[1.5][compiler] Missing "name clash" error?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238817">238817</a>
+[1.5][compiler] Unexpected nameclash reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237418">237418</a>
+deadlock between auto-build/refresh right after startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=241841">241841</a>
+[compiler] Compilation error 'incompatible types' should use full qualified class names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239439">239439</a>
+[1.5][compiler] Behavior change for binding for parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106821">106821</a>
+[assist] Code assist: Deprecated elements not marked
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209639">209639</a>
+codeSelect does not resolve correct key for implicit method type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239117">239117</a>
+AST overlapping source ranges in recovered AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=230830">230830</a>
+[select] Search doesn't find annotated local variable declaration with error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=229092">229092</a>
+[batch compiler] error reporting is non-deterministic
+
+<a name="v_904"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 21, 2008
+<br>Project org.eclipse.jdt.core v_904
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_904">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=169682">169682</a>
+In class that compiles and runs when ctrl+space is pressed I get &quot;No completions available&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240815">240815</a>
+[DOM] CCE in AST#resolveWellKnownType(..)  for java.lang.Boolean without rt.jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235727">235727</a>
+misspelling in syntax error message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236193">236193</a>
+DiagnoseParser has unreachable code
+
+<a name="v_903"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 15, 2008
+<br>Project org.eclipse.jdt.core v_903
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_903">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=237469">237469</a>
+[assist] AbortCompilation in log during normal editing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240214">240214</a>
+[compiler] final bit should be cleared from class file access flag for anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240349">240349</a>
+Improve disassembler output
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=240206">240206</a>
+ITypeRoot should have @noimplement tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237937">237937</a>
+[javadoc] Wrong &quot;Javadoc: Malformed link reference&quot; if href label contains //
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237931">237931</a>
+[1.6][compiler] wrong signature of String[][] in class file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101610">101610</a>
+Code assist not offered without transitive dependency
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239229">239229</a>
+[compiler] Regression bug against Eclipse 3.3: cannot resolve correct import
+
+<a name="v_902"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 8, 2008
+<br>Project org.eclipse.jdt.core v_902
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_902">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=236336">236336</a>
+[1.6][compiler] Stack map generation error with 10,000-line method in Java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239941">239941</a>
+[formatter] Unclosed html tags make the formatter to produce incorrect outputs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239719">239719</a>
+[formatter] Code formatter destroys pre formatted javadoc comments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238923">238923</a>
+[1.6][compiler] Internal compiler error caused by a for loop in an initializer block
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239758">239758</a>
+[1.5][compiler] Generic interface inheritance and overriding error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239305">239305</a>
+[compiler] VerifyError caused by casting long to long to int
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=239198">239198</a>
+[compiler] NegativeArraySizeException thrown for triple quotes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238920">238920</a>
+[formatter] Code Formatter removes javadoc status if @category present
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238853">238853</a>
+[formatter] Code Formatter does not properly format valid xhtml (&lt;br /&gt; &amp; &lt;p /&gt;) in javadoc.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=160217">160217</a>
+[ast rewrite] ASTRewrite#getListRewrite does not fullfill spec
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232565">232565</a>
+[1.5][compiler] wrong autoboxing code generation leads to VerifyError at runtime
+
+<a name="v_901"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - July 1, 2008
+<br>Project org.eclipse.jdt.core v_901
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_901">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=232478">232478</a>
+[buildpath] Classpath failed to bind to installed JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238210">238210</a>
+[formatter] CodeFormatter wraps line comments without whitespaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238484">238484</a>
+[1.5][compiler] Eclipse generates bad code (major regression)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235370">235370</a>
+Add performance test for bug 234718
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=135906">135906</a>
+CompilationUnitStructureRequestor.resolveDuplicates has bad performance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=169678">169678</a>
+[hierarchy] Type Hierarchy on static nested class includes unrelated types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95480">95480</a>
+[model] Missing INVALID_SIBLING exception when creating a type in an enum type that contains constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235369">235369</a>
+DeltaProcessor.resetProjectCaches() should clear the list of projects to reset
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=190840">190840</a>
+SourceMapper#computeAllRootPaths(IType) factorisation suggestion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=148664">148664</a>
+[spec] IJavaModel#getJavaProject(String) throws IAE for invalid name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=231130">231130</a>
+[spec] IClassFile.getPath() not specified for external class folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=209425">209425</a>
+[spec] Ambiguous JavaDoc in ASTParser#setUnitName regarding source folders
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235272">235272</a>
+javadoc of JavaCore#COMPILER_PB_MISSING_JAVADOC_TAG_DESCRIPTION needs improvement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235778">235778</a>
+Potential race condition computing resolved classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=154865">154865</a>
+[hierarchy] Focus on Package only shows classes with missing superclasses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236445">236445</a>
+NPE in content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237123">237123</a>
+[search] And/OrPatterns miss to override one overload
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=226357">226357</a>
+[dom] NPE in MethodBinding.getParameterAnnotations() if some, but not all parameters are annotated
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=120082">120082</a>
+Signature is missing capture
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235882">235882</a>
+[compiler] constructor-scoped inner classes unable to recognize final member variable initialization
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=238090">238090</a>
+[formatter] New lines wrongly added while formatting too long @see references
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237942">237942</a>
+[formatter] String references are put on next line when over the max line length
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233259">233259</a>
+[formatter] html tag should not be split by formatter
+
+
+<a name="v_900"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.5M1 - June 24, 2008
+<br>Project org.eclipse.jdt.core v_900
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_900">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Incremented JDT/Core plug-in id to "3.5.0", since added new API/feature.
+</li>
+<li>Added a new compiler warning to detect comparisons between identical expressions. This diagnosis is controlled by option: 
+<code>JavaCore.COMPILER_PB_COMPARING_IDENTICAL</code> and produces a problem marker which ID is
+<code>IProblem.ComparingIdentical</code> problem ID.
+<pre>
+Compiler option ID: Reporting Comparison of Identical Expressions.
+When enabled, the compiler will issue an error or a warning if a comparison
+is involving identical operands (e.g <code>'x == x'</code>).
+  - Option id:"org.eclipse.jdt.core.compiler.problem.comparingIdentical"
+  - Possible values: { "error", "warning", "ignore" }
+  - Default: "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=234172">234172</a>
+[1.5][select] no hover in qualified name with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=233568">233568</a>
+Type in Server Runtime is not resolved in editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=217287">217287</a>
+[dom]IVariableBinding#getJavaElement() return null for variable inside an initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235921">235921</a>
+[1.5][compiler] Incorrect generic signature attribute created for inner anonymous type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=234619">234619</a>
+[1.5][compiler] Object#getClass() has wrong expression type binding with JRE from 1.6
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=115814">115814</a>
+[compiler] warning on comparing same to same
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=235004">235004</a>
+[compiler] Misleading compiler warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=232944">232944</a>
+IMember#getJavadocRange() should end with &quot;*/&quot;
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=222665">222665</a>
+Error opening workbench
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=216772">216772</a>
+IJavaModel#refreshExternalArchives fails to refresh ExternalJavaProject jar cache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=205917">205917</a>
+JavaCore#create(String, WorkingCopyOwner) should deal with null owner
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=237051">237051</a>
+[formatter] Formatter insert blank lines after javadoc if javadoc contains Commons Attributes @@ annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=236230">236230</a>
+[formatter] SIOOBE while formatting a compilation unit.
+
+
+<hr>
+<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R34_buildnotes_jdt-core.html">build notes up to Release 3.4</a>.</p>
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/notes/R36_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R36_buildnotes_jdt-core.html
new file mode 100644
index 0000000..bfa4eff
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R36_buildnotes_jdt-core.html
@@ -0,0 +1,2283 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<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>
+   <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>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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>,
+	  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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_5_maintenance">R3.5.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_4_maintenance">R3.4.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_3_maintenance">R3.3.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+<a name="v_A58"></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>).
+<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 name="v_A57"></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>).
+<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>
+<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>
+
+<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
+
+<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>
+
+<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";
+</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>
+<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);	
+</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 name="v_A36"></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>).
+<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>
+<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"
+ *     - 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. 
+ *
+ * 
+ * @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.
+ *
+ * Option id:"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"
+ * Possible values:{ "error", "warning", "ignore" }
+ * Default:"ignore"
+ *
+ * @since 3.6
+ * @category CompilerOptionID
+ */
+public static final String COMPILER_PB_UNUSED_OBJECT_ALLOCATION = PLUGIN_ID + ".compiler.problem.unusedObjectAllocation";
+</pre>
+</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:
+<pre>
+/**
+ * Returns the reconcile flag of this context. This flag is a bitwise value of the constant defined
+ * in ICompilationUnit.
+ *
+ * @return the reconcile flag of this context
+ * @since 3.6
+ *
+ * @see ICompilationUnit#ENABLE_BINDINGS_RECOVERY
+ * @see ICompilationUnit#ENABLE_STATEMENTS_RECOVERY
+ * @see ICompilationUnit#IGNORE_METHOD_BODIES
+ */
+public int getReconcileFlags();
+</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 name="v_A29a"></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>).
+<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 name="v_A28"></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>).
+<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 name="v_A27"></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>).
+<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 name="v_A26"></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>).
+<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 name="v_A25"></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>).
+<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>:
+<pre>
+/**
+ * Returns the accessibility of the type name match
+ *
+ * @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
+ */
+public abstract int getAccessibility();
+</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:
+<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;
+
+</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 name="v_A23"></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>).
+<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 name="v_A22"></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>).
+<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 name="v_A21"></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>).
+<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 name="v_A20"></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>).
+<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 name="v_A19"></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>).
+<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 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>
+<br>
+  <p>
+    <a href="http://validator.w3.org/check?uri=referer"><img
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/notes/R37_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R37_buildnotes_jdt-core.html
new file mode 100644
index 0000000..9ee657a
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/R37_buildnotes_jdt-core.html
@@ -0,0 +1,1771 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <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.7 stream</b></font>
+    </td>
+  </tr>
+  <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
+  <tr>
+  	<td class="title3">
+	  <font size="-1">
+	  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.7 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.7/plan.php">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.7/plan.php#current-milestone">milestone plan</a>,
+	  the overall <a href="http://www.eclipse.org/projects/project-plan.php?planurl=http://www.eclipse.org/eclipse/development/plans/eclipse_project_plan_3_7.xml">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.6 (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>).
+	  <br>Maintenance of previous releases of JDT/Core is performed in parallel branches:
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_6_maintenance">R3.6.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_5_maintenance">R3.5.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_4_maintenance">R3.4.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_3_maintenance">R3.3.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_2_maintenance">R3.2.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_1_maintenance">R3.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R3_0_maintenance">R3.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_1_maintenance">R2.1.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=R2_0_1">R2.0.x</a>,
+		  <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=ECLIPSE_1_0">R1.0.x</a>.
+	  </font>
+	</td>
+  </tr>
+</table>
+
+<a name="v_B61"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - June 7, 2011
+<br>Project org.eclipse.jdt.core v_B61
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B61">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Update batch compiler version to refer to 3.7.0 and not 3.7.0 RC2</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_B60"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC2 - May 19, 2011
+<br>Project org.eclipse.jdt.core v_B60
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B60">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346002">346002</a>
+Import of User Library with invalid path hoses User Library Dialog -- can not fix
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340181">340181</a>
+Formatter from the command line breaks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346029">346029</a>
+[1.7][compiler] Eclipse compiles code rejected by JDK7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345628">345628</a>
+[1.7] Rename disjunctive type to union type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345559">345559</a>
+[1.7][compiler] Type inference for generic allocation can be avoided for invalid constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342819">342819</a>
+Code rejected by javac with name clash error compiles under eclipse.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334306">334306</a>
+[1.7][compiler] name clash reported in javac 1.7 and not in javac 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345579">345579</a>
+[1.7][compiler] Weird error message in rethrow site
+
+<a name="v_B59"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 12, 2011 - 3.7.0 RC1
+<br>Project org.eclipse.jdt.core v_B59
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B59">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=345569">345569</a>
+FUP of bug 345334: CodeSnippetTest has lot of failures
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345522">345522</a>
+[1.7][compiler] Compilers fails to compute precisely rethrown types
+
+<a name="v_B58"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 11, 2011
+<br>Project org.eclipse.jdt.core v_B58
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B58">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=345334">345334</a>
+CodeSnippet's run method is missing @Override annotation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344824">344824</a>
+[1.7][compiler] Incorrect error range for unreachable catch block error in multi-catch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340486">340486</a>
+[1.7][compiler] Missing error in multi catch scenario
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359">345359</a>
+[1.7][compiler] AIOOB on diamond construct with argument error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345239">345239</a>
+[1.7][compiler] Compiler should issue better diagnostics for use of &lt;&gt; with anonymous classes
+
+<a name="v_B57"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 10, 2011
+<br>Project org.eclipse.jdt.core v_B57
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B57">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=336451">336451</a>
+&quot;Content Assist&quot; does not complete normally on certain types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324987">324987</a>
+[formatter] API compatibility problem with Annotation Newline options
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344655">344655</a>
+[1.7][compiler] Prohibit use of &lt;&gt; with explicit type arguments to generic constructor
+
+<a name="v_B56"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 6, 2011
+<br>Project org.eclipse.jdt.core v_B56
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B56">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Reverting fix for bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336648">336648</a></li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328575">328575</a>
+Inheritance of annotation fails with generic classes
+
+<a name="v_B55"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 5, 2011
+<br>Project org.eclipse.jdt.core v_B55
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B55">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=90486">90486</a>
+Give more info when a dependency cycle is detected
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343865">343865</a>
+[assist] CompletionContext token start and end incorrectly returning 0
+
+<a name="v_B54"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7RC1 - May 4, 2011
+<br>Project org.eclipse.jdt.core v_B54
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B54">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=264301">264301</a>
+AssertionFailedException resolving JavaProject classpath
+
+<a name="v_B53"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 27, 2011 - 3.7.0 M7
+<br>Project org.eclipse.jdt.core v_B53
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B53">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Reverting fix for bug 292087: anonymous class in array member initializer confuses content assist</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_B52"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 27, 2011
+<br>Project org.eclipse.jdt.core v_B52
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B52">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Update copyrights</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785">343785</a>
+[1.7] Incorrect line numbers in stack trace with try with resources
+
+<a name="v_B51"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 25, 2011
+<br>Project org.eclipse.jdt.core v_B51
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B51">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=339226">339226</a>
+Document assumptions about DefaultBindingResolver.newAstToOldAst
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343713">343713</a>
+[compiler] bogus line number in constructor of inner class in 1.5 compliance
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343687">343687</a>
+[1.7] IAE in NumberLiteral#setToken(String) for binary tokens and tokens with underscore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339478">339478</a>
+[1.7][compiler] support for diamond case
+
+<a name="v_B50"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 21, 2011
+<br>Project org.eclipse.jdt.core v_B50
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B50">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=343607">343607</a>
+[APT] Improve output for javax.annotation.processing.Messager problems
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476">343476</a>
+[1.7][assist] propose String variables and fields inside catch expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087">292087</a>
+anonymous class in array member initializer confuses content assist
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343475">343475</a>
+[1.7] Compiler warning for invalid type inside switch needs to be improved
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342">343342</a>
+[assist] Non constant variables, strings and methods are proposed inside case statements
+
+<a name="v_B49"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 21, 2011
+<br>Project org.eclipse.jdt.core v_B49
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B49">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=328281">328281</a>
+visibility leaks not detected when analyzing unused field in private class
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335986">335986</a>
+No expected event fired when removing a JAR file from a classpath container
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342671">342671</a>
+ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+
+<a name="v_B48"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 19, 2011
+<br>Project org.eclipse.jdt.core v_B48
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B48">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=337415">337415</a>
+External folders project is not created
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342455">342455</a>
+AST swallows stars ('*') at end of {@code} and {@literal} Javadoc fragments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342757">342757</a>
+ArrayIndexOutOfBoundsException in MethodInfoWithParameterAnnotations.getParameterAnnotations when generating method info for an inner class constructor with annotated parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340691">340691</a>
+Syntax error leads to ClassCastException in ASTConverter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342671">342671</a>
+ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
+
+<a name="v_B47"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 13, 2011
+<br>Project org.eclipse.jdt.core v_B47
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B47">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342300">342300</a>
+[null]Spurious &quot;null pointer access&quot; warning on unboxing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342416">342416</a>
+[1.7] Signature#createIntersectionTypeSignature(..) should take array of signatures
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340059">340059</a>
+[1.7] IAE when dealing with Signature of disjunctive type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341759">341759</a>
+NPE in ITypeBinding#getName() for intersection type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341499">341499</a>
+[compiler][null] allocate extra bits in all methods of UnconditionalFlowInfo
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342054">342054</a>
+ILocalVariable#isParameter() returns true for exception of catch clause
+
+<a name="v_B46"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 6, 2011
+<br>Project org.eclipse.jdt.core v_B46
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B46">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341475">341475</a>
+Eclipse doesn't show a &quot;never read locally&quot; warning if a private field serialVersionUID exists but the class does not implement Serializable
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334493">334493</a>
+[1.7][compiler] Difference in behavior with Javac7
+
+<a name="v_B45"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - April 6, 2011
+<br>Project org.eclipse.jdt.core v_B45
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B45">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338789">338789</a>
+[1.7][assist] No proposal inside a multi catch statement after '|'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341333">341333</a>
+[1.7][compiler] DisjunctiveTypeReference#resolveType(..) does not set the value for DisjunctiveTypeReference$resolvedType
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340634">340634</a>
+[1.7][compiler][multicatch] Compiler accepts type variables as catch parameter type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=200827">200827</a>
+[spec] IElementChangedListener should mention where to register
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340626">340626</a>
+[1.7][compiler] Inconsistent source pinpointing in multi-catch blocks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340513">340513</a>
+[1.7][compiler] Unicode 6.0 characters work at compiler compliance level 1.5 and 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340445">340445</a>
+[1.7] ASTRewriteAnalyzer and ASTRewriteFlattener need updates
+
+<a name="v_B44"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - March 22, 2011
+<br>Project org.eclipse.jdt.core v_B44
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B44">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=339447">339447</a>
+synchronized access modifier retained on clone() bridge
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340372">340372</a>
+[1.7] NaiveASTFlattener needs to support the new AST nodes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340365">340365</a>
+[1.7] Problems in new APIs (TryStatementWithResources, DisjunctiveType)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340375">340375</a>
+[1.7] Merge TryStatementWithResources into TryStatement
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339891">339891</a>
+NPE when searching for method (with '*' wildcard character)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340022">340022</a>
+[1.7][compiler] Support for precise rethrow
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340029">340029</a>
+[1.5][compiler] Enum constructor that throws Exception reports a confusing error message
+
+<a name="v_B43"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M7 - March 15, 2011
+<br>Project org.eclipse.jdt.core v_B43
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B43">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=339337">339337</a>
+isLocal() in IType returns true for anonymous types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339837">339837</a>
+[1.7][compiler] Multicatch syntax not rejected at 1.6-
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962">337962</a>
+COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS misses reference to field from supertype
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338011">338011</a>
+COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS wrongly suppresses constructor parameter type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337751">337751</a>
+COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS misses references in conditional expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339870">339870</a>
+[1.7] Bad list of subclasses in Statement AST node
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339913">339913</a>
+[compiler] Misleading error message for annotations inside a method body
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339864">339864</a>
+[1.7] Add recovery in ASTConverter for all new constructs in JLS3 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402">338402</a>
+[1.7][compiler][enh] Open issues in try with resources implementation
+
+<a name="v_B42"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 9, 2011 - 3.7.0 M6
+<br>Project org.eclipse.jdt.core v_B42
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B42">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=339250">339250</a>
+[null] Incorrect redundant null check warning on a String
+
+<a name="v_B41"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 8, 2011
+<br>Project org.eclipse.jdt.core v_B41
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B41">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=339139">339139</a>
+[compiler] HEAD contents of org.eclipse.wst.jsdt.core doesn't compile anymore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338649">338649</a>
+[perfs] Regression on FullSourceWorkspaceModelTests#testInitJDTPlugin
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339128">339128</a>
+[Doc] Sort statements and expressions inside DOM documentation for both abstract classes org.eclipse.jdt.core.dom.Expressionn and org.eclipse.jdt.core.dom.Statement
+
+<a name="v_B40"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 6, 2011
+<br>Project org.eclipse.jdt.core v_B40
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B40">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=326950">326950</a>
+[compiler][null]Do not optimize code generation based on static analysis (dead code)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324178">324178</a>
+[null] ConditionalExpression.nullStatus(..) doesn't take into account the analysis of condition itself
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338006">338006</a>
+IJavaProject#getPackageFragmentRoots() should return roots in order
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338234">338234</a>
+[compiler] Missing warning for uninitialized variable in dead code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336428">336428</a>
+[compiler][null] bogus warning &quot;redundant null check&quot; in condition of do {} while() loop
+
+<a name="v_B39"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 1, 2011
+<br>Project org.eclipse.jdt.core v_B39
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B39">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added new constant on org.eclipse.jdt.core.IJavaProject to provide the value of the classpath file path. See details in bug
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241598">241598</a>.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338118">338118</a>
+[compiler] CastExpression type should be changed to be a type reference and not an expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=171019">171019</a>
+[javadoc][select] F3 on {@inheritDoc} tag should navigate to target javadoc
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=222188">222188</a>
+[javadoc] Incorrect usage of inner type not reported
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338303">338303</a>
+[compiler][null] Warning about Redundant assignment conflicts with definite assignment analysis
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337868">337868</a>
+[compiler][model] incomplete support for package-info.java when using SearchableEnvironment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337964">337964</a>
+[DOM] code that would definitely cause NPE if executed
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241598">241598</a>
+[API] Constant needed for .classpath
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795">337795</a>
+[1.7][compiler] Missing unchecked warning at varargs method/ctor declaration site
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337802">337802</a>
+[1.7][compiler] Usage of 0x0ffffffff is being reported as out of range.
+
+<a name="v_B38"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - February 22, 2011
+<br>Project org.eclipse.jdt.core v_B38
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B38">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API to ease the retrieval of method parameter's annotations (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783">334783</a> for details):
+<pre>
+/**
+ * Returns the parameters of this method.
+ * An empty array is returned, if the method has no parameters.
+ * For binary types, associated source is used to retrieve the name range,
+ * source range and the flags.
+ * These local variables can be used to retrieve the parameter annotations.
+ * 
+ * @return the parameters of this method
+ * @throws JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @since 3.7
+ */
+ILocalVariable[] getParameters() throws JavaModelException;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799">337799</a>
+[1.7][compiler][varargs] Eclipse fails to report error on incorrect SafeVarargs usage
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337738">337738</a>
+[1.7][content assist]Test CompletionParserTest#testEA_1 fails
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783">334783</a>
+[API] Add new API to ease the retrieval of the parameter annotations for an IMethod
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336046">336046</a>
+Source attachment not recovered when importing Projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336782">336782</a>
+[1.7][recovery]Extra error tokens with invalid unary operator
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313870">313870</a>
+Wrong warnings on Java.Compiler.Errors/Warnings &quot;Redundant null check&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337275">337275</a>
+Incorrect/outdated javadoc for org.eclipse.jdt.core.dom.Expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337093">337093</a>
+[compiler][generics] Javac-warning on vararg missing in Eclipse
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336934">336934</a>
+[compiler] NPE in Scope.getTypeOrPackage
+
+<a name="v_B37"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - February 15, 2011
+<br>Project org.eclipse.jdt.core v_B37
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B37">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Adding a new token "javadoc" for @suppressWarnings to remove all warnings related to javadoc.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335751">335751</a>
+[1.7][compiler] Cycle inheritance in type arguments is not detected
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335309">335309</a>
+[formatter] FUP of bug 332843: add regression test
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334622">334622</a>
+Eclipse compiler allows access to private fields for typed variables
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737">274737</a>
+Relative Classpath entries should not be resolved relative to the workspace
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=179566">179566</a>
+[compiler] Support of @SuppressWarnings for JavaDoc Warnings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336821">336821</a>
+Javadoc reference to constructor does not work without parameter list
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331138">331138</a>
+ASTRewrite#replace(..) does not consider the TargetSourceRangeComputer
+
+<a name="v_B36"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - February 11, 2011
+<br>Project org.eclipse.jdt.core v_B36
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B36">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>All JDT/Core projects (tests included) have been set to force strict compatibility between the JRE used for the project
+and the BREE defined for the project.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336544">336544</a>
+[regression][compiler] Source flagged as dead code incorrectly.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=189459">189459</a>
+[1.6][compiler] Doc comment support should not be systematically activated while processing annotations
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332838">332838</a>
+Bogus potential null pointer access warning (regression; works with 3.6)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334377">334377</a>
+[1.5][compiler] Invalid 'type mismatch' error in conditional expression (if-else construct behaves correct)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336322">336322</a>
+[1.7][search]CCE while searching for a type reference in multiple catch parameters
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335780">335780</a>
+Compiler says a method can be potentially static but this method contains 'this'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310747">310747</a>
+[content assist] Irrelevant proposals while completing inside array initializer.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335845">335845</a>
+[compiler] compiler wrongly suggests to add a static qualifier to a method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335602">335602</a>
+[search] Java indexing thread can index data outside of workspace
+
+<a name="v_B35"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - January 25, 2011 - 3.7.0 M5
+<br>Project org.eclipse.jdt.core v_B35
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B35">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=324189">324189</a>
+ [search] Method declaration search returns false results (suffix match on type name)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=327143">327143</a>
+IndexManager should not accept new jobs if the processing thread is null
+
+<a name="v_B34"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - January 24, 2011
+<br>Project org.eclipse.jdt.core v_B34
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B34">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New code formatter option to preserve existing white space between code and line comments.
+<br>See details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282988">282988</a>:
+<pre>
+	/**
+	 * FORMATTER / Option to control whether the white space between code and line comments should be preserved or replaced with a single space
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 *
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.7
+	 */
+	public final static String FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT = "org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments";
+</pre>
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335093">335093</a>
+[compiler][null] minimal hook for future null annotation support
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334119">334119</a>
+AIOOBE in BindingKeyParser.parseInnerType (was: Copy Qualified Name throws ArrayIndexOutOfBoundsException)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282988">282988</a>
+[formatter] Option to align single-line comments in a column
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334652">334652</a>
+Javadoc content not found for non-static inner class constructors
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=136091">136091</a>
+Cannot access Javadoc location over http
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333089">333089</a>
+[compiler][null]AIOOBE while assigning variable a potentially null value in try/finally
+
+<a name="v_B33"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - January 18, 2011
+<br>Project org.eclipse.jdt.core v_B33
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B33">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=325418">325418</a>
+[search] Search for method declarations returns spurious potential matches for anonymous classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332744">332744</a>
+Generated model code doesn't compile with J2SE-1.4 execution environment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334315">334315</a>
+[compiler] Problem types with missing superclass or superinterfaces should use Object for missing types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333956">333956</a>
+CompilerOptions#warningOptionNames(): OPTION_ReportRawTypeReference missing
+
+<a name="v_B32"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - January 11, 2011
+<br>Project org.eclipse.jdt.core v_B32
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B32">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=327654">327654</a>
+FUP of bug 317264: Refactoring is not possible if the commons-lang.jar is in the path
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333710">333710</a>
+[DOM] wrong JavaElement for recovered ITypeBinding
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333669">333669</a>
+[DOM] Incorrect signature for type arguments in test case from bug 333360
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333360">333360</a>
+[DOM] eclipse fails to create array binding in this situation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332423">332423</a>
+[1.5][compiler] ClassCastException when compiling against scala-libary.jar
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332268">332268</a>
+[assist] Allow proposals for static fields in initializers of fields being declared textually in advance
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331334">331334</a>
+[1.5][compiler] &quot;The code for the static initializer is exceeding the 65535 bytes limit&quot; in enum
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=333487">333487</a>
+[formatter] Incorrectly ordered method arguments in Scribe
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332843">332843</a>
+[formatter] format save action fails with SIOOBE
+
+<a name="v_B31"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - January 4, 2011
+<br>Project org.eclipse.jdt.core v_B31
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B31">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=317039">317039</a>
+[formatter] Code Formatter fails on inner class source indentation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330313">330313</a>
+[formatter] 'Never join already wrapped lines' formatter option does correctly indent
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329227">329227</a>
+Usage of broken quicksort algorithm in jdt.internal.compiler.util.Util
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332359">332359</a>
+org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding should return number of fields directly
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332818">332818</a>
+[formatter] Java formatter, Blank Lines tab, only 1st line indented when multiple lines is set
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332877">332877</a>
+[formatter] line comment wrongly put on a new line
+
+<a name="v_B30"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - December 21, 2010
+<br>Project org.eclipse.jdt.core v_B30
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B30">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_MISSING_STATIC_ON_METHOD added to raise warning or error for a method
+    which qualifies to be declared as <code>static</code>, but not been declared as one.(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322581">318682</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting a method that qualifies as static, but not declared static.
+	 * When enabled, the compiler will issue an error or a warning if a method has
+	 * not been declared as <code>static</code>, even though it qualifies as one.
+	 * 
+	 * Option id:<code>"org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic"</code>
+	 * Possible values:<code>{ "error", "warning", "ignore" }</code>
+	 * Default:<code>"ignore"</code>
+	 * 
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBeStatic";
+	</pre>
+</li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD added to raise warning or error for a method
+    which may qualify to be declared as <code>static</code> when another method doesn't override it,
+    but not been declared as one.(see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322581">318682</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting a method that may qualify as static, but not declared static.
+	 * When enabled, the compiler will issue an error or a warning if a method has
+	 * not been declared as <code>static</code>, even though it may qualify as one,
+	 * when another method doesn't override it.
+	 * 
+	 * Option id:<code>"org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic"</code>
+	 * Possible values:<code>{ "error", "warning", "ignore" }</code>
+	 * Default:<code>"ignore"</code>
+	 * 
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_POTENTIALLY_MISSING_STATIC_ON_METHOD = PLUGIN_ID + ".compiler.problem.reportMethodCanBePotentiallyStatic";
+</pre>
+</li>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS added to give the user control over whether forced and unavoidable generic type problems should be reported by the compiler or not (see details in <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817">bug 322817</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting of Unavoidable Generic Type Problems.
+	 * When enabled, the compiler will issue an error or warning even when it detects a generic type problem
+	 * that could not have been avoided by the programmer. As an example, a type may be forced to use raw types
+	 * in its method signatures and return types because the methods it overrides from a super type are declared to
+	 * use raw types in the first place.
+	 *
+	 * Option id:<code>"org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems"</code>
+	 * Possible values:<code>{ "enabled", "disabled" }</code>
+	 * Default:<code>"enabled"</code>
+	 *
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS = PLUGIN_ID + ".compiler.problem.unavoidableGenericTypeProblems";
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=327471">327471</a>
+java.io.EOFException at java.io.DataInputStream.readInt(Unknown Source)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332619">332619</a>
+Small error in IType#codeComplete Javadoc example
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318682">318682</a>
+Enhancement request: Warning if no fields are used and the method is still not static
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322817">322817</a>
+Compiler option to ignore unavoidable type safety problems due to raw APIs
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332451">332451</a>
+Javadoc cleanup in SearchEngine#createJavaSearchScope(IJavaElement[], int)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=332637">332637</a>
+Dead Code detection removing code that isn't dead
+
+<a name="v_B29"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M5 - December 14, 2010
+<br>Project org.eclipse.jdt.core v_B29
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B29">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=331736">331736</a>
+[dom] tests should check for malformed nodes - may catch a parser bug
+
+<a name="v_B28"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - December 6, 2010 - 3.7.0 M4
+<br>Project org.eclipse.jdt.core v_B28
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B28">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=331872">331872</a>
+[compiler] NPE in Scope.createArrayType when attempting qualified access from type parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331770">331770</a>
+org.eclipse.jdt.core.tests.model.JavaSearchBugsTests.testBug323514a() is failing in  N20101202-2000
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331632">331632</a>
+FUP of 323514: Add performance tracking test for scenario
+
+<a name="v_B27"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - December 4, 2010 - 3.7.0 M4
+<br>Project org.eclipse.jdt.core v_B27
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B27">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=324367">324367</a>
+IJavaProject.findPackageFragmentRoots(IClasspathEntry cpe) returns empty list
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=327899">327899</a>
+include the Ant compiler adapter in ecj JAR
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446">331446</a>
+[1.4/1.5] Unexpected ambiguous error for 1.4 project
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323514">323514</a>
+[indexing] The Java Indexer is taking longer to run in eclipse 3.6 when opening projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671">329671</a>
+Regression: arg0,1,2... parameter names are cached
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305172">305172</a>
+[common navigator] Project Explorer not fully updating with jar classpath container changes.
+
+<a name="v_B26"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - November 30, 2010
+<br>Project org.eclipse.jdt.core v_B26
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B26">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=331271">331271</a>
+[assist] Reconsider assumption to filter not yet declared fields from being proposed
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329663">329663</a>
+[type hierarchy] Interfaces duplicated in type hierarchy on two packages from multiple projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328362">328362</a>
+[formatter] Format regions does not format as expected
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=331120">331120</a>
+Improvements to Signature API
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=299384">299384</a>
+codeSelect does not find declaration of constructor with generic parameter type when referenced from 1.4 code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329822">329822</a>
+[1.7][compiler] Stackoverflow  error if compiled in 1.7 compliance mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330869">330869</a>
+Bogus error reported for Incompatible operand types Class&lt;capture#2-of ? extends T&gt; and Class&lt;Bug.Bar&gt;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330845">330845</a>
+[Model] Possible bug in Member class
+
+<a name="v_B25"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - November 23, 2010
+<br>Project org.eclipse.jdt.core v_B25
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B25">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li> Added a new API in org.eclipse.jdt.core.compiler.CharOperation to find if a given character array starts with a given prefix, at the given index. (see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329288">329288</a>):
+<pre>
+    /**
+     * Answers true if the given name, starting from the given index, starts with the given prefix,
+     * false otherwise. isCaseSensitive is used to find out whether or not the comparison should be
+     * case sensitive.
+     * 
+     * 
+     * For example:
+     * 
+     * 1.   prefix = { 'a' , 'B' }
+     *      name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
+     *      startIndex = 2
+     *      isCaseSensitive = false
+     *      result => true
+     *
+     * 2.   prefix = { 'a' , 'B' }
+     *      name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
+     *      startIndex = 2
+     *      isCaseSensitive = true
+     *      result => false
+     * 
+     *
+     * @param prefix the given prefix
+     * @param name the given name
+     * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
+     * @param startIndex index from which the prefix should be searched in the name
+     * @return true if the given name starts with the given prefix, false otherwise
+     * @throws NullPointerException if the given name is null or if the given prefix is null
+     * @since 3.7
+     */
+     public static final boolean prefixEquals(char[] prefix,	char[] name, boolean isCaseSensitive, int startIndex)
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325481">325481</a>
+[assist] fields declared after a particular field are proposed in its initialization
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329727">329727</a>
+Invalid check in the isConstructor() method of the IMethod implementation.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329288">329288</a>
+Fetching parameter names literally hangs on a class with a lot of methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330435">330435</a>
+[1.4][1.5][compiler] Wrong handling of parameterized methods in 1.4 mode with generified JDK
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330445">330445</a>
+[1.4][1.5][compiler] Properties doesn't match Map&lt;String, String&gt; in 1.4 compliance mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330347">330347</a>
+[1.4][1.5][compiler] The performance test FullSourceWorkspaceBuildTests#testFullBuildDefault() fails
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329156">329156</a>
+[compiler][APT] Source generated in last round not compiled
+
+<a name="v_B24"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - November 16, 2010
+<br>Project org.eclipse.jdt.core v_B24
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B24">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=329998">329998</a>
+[content assist] override method proposal in anonymous class inserts bad stub
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=330081">330081</a>
+[compiler] ArrayIndexOutOfBoundsException when Switched from C/C++ Perspective to Java Perspective
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328519">328519</a>
+[compiler] local variable cannot be optimized out despite warning &quot;not used&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329709">329709</a>
+[formatter] Formatter fails to format enum with extra semicolon and body
+
+<a name="v_B23"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M4 - November 9, 2010
+<br>Project org.eclipse.jdt.core v_B23
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B23">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=329593">329593</a>
+[1.4/1.5] [compiler] incorrect error about incompatible operand
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588">329588</a>
+[1.4/1.5][compiler] Class cast issue with java.lang.Class and the 1.4/1.5 mixed mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329584">329584</a>
+[1.4/1.5][compiler] Compiler is confused about name clashes in 1.4 project
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328674">328674</a>
+[assist] local being declared proposed inside its initialization
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=329344">329344</a>
+[compiler] Batch compiler should not removed some duplicated entries on the classpath
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565">186565</a>
+[1.5][compiler] 1.4/1.5 .class file interaction
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328689">328689</a>
+[1.4][compiler] &quot;Incompatible conditional operand types Class and Class&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328775">328775</a>
+[compiler] Compiler fails to warn about invalid cast when using J2SE 1.4 compiler settings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827">328827</a>
+Compiler fails to recognize a Map when using J2SE 1.4 compiler settings
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850">324850</a>
+Compile error claims method is missing but is inherited
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328969">328969</a>
+[DOM] NPE retrieving a java element for an annotation binding
+
+<a name="v_B22"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 28, 2010 - 3.7.0 M3
+<br>Project org.eclipse.jdt.core v_B22
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B22">cvs</a>).
+<h2>What's new in this drop</h2>
+This build input simply reverts the change made for bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850">324850</a>.
+
+<h3>Problem Reports Fixed</h3>
+
+<a name="v_B21"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 27, 2010
+<br>Project org.eclipse.jdt.core v_B21
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B21">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=328786">328786</a>
+[search] NPE in field match locator
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328744">328744</a>
+Removed warnings related to fix for 185682
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=229042">229042</a>
+[buildpath] could create build path error in case of invalid external JAR format
+
+<a name="v_B20"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 25, 2010
+<br>Project org.eclipse.jdt.core v_B20
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B20">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282152">282152</a>
+[1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328240">328240</a>
+org.eclipse.text.edits.MalformedTreeException: Overlapping text edits
+
+<a name="v_B19"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 24, 2010
+<br>Project org.eclipse.jdt.core v_B19
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B19">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=185682">185682</a>
+Increment/decrement operators mark local variables as read
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328400">328400</a>
+TextEdit computed incorrectly for inserting annotation before package declaration
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511">303511</a>
+Allow to specify encoding for source attachments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=326354">326354</a>
+[3.6][compiler][regression] Compiler in 3.6 and 3.6.1 generates bad code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328361">328361</a>
+[1.4][compiler] variable initialized within an assert expression are no longer reported as potential non initialized
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328247">328247</a>
+Disassemble fails to disassemble synthetic constructor with varargs arguments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328115">328115</a>
+[DOM] All ASTNode APIs should specify types of property descriptors
+
+<a name="v_B18"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 19, 2010
+<br>Project org.eclipse.jdt.core v_B18
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B18">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=327429">327429</a>
+Use Charset.name() instead of Charset.toString() to get the encoding
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=327817">327817</a>
+ecjsrc.zip should be ecjsrc.jar
+
+<a name="v_B17"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 12, 2010
+<br>Project org.eclipse.jdt.core v_B17
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B17">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS added to enable or disable the missing Javadoc tag warning or error for a method
+    paramater without a corresponding <code>@param</code> tag. (see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322581">322581</a>):
+<pre>
+    /**
+     * Compiler option ID: Reporting Missing Javadoc Tags for Method Type Parameters.
+     * Specify whether a missing <code>@param</code> for a type parameter in a method declaration should be reported.
+     * When enabled, the compiler will issue a missing Javadoc tag error or warning for a type parameter without a 
+     * corresponding <code>@param</code> tag.
+     *	
+     * This option only has an effect if the compiler compliance is 1.5 or greater.
+     * 
+     * Option id:<code>"org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters"</code>
+     * Possible values:<code>{ "enabled", "disabled" }</code>
+     * Default:<code>"disabled"</code>
+     * 
+     * @since 3.7
+     * @category CompilerOptionID
+     */
+     public static final String COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS = PLUGIN_ID + ".compiler.problem.missingJavadocTagsMethodTypeParameters";
+</pre>
+</li>
+<li>Added new API on org.eclipse.jdt.core.dom.rewrite.ASTRewrite to store properties (See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325131">325131</a>).
+<pre>
+	/**
+	 * Returns the value of the named property of this rewrite, or null if none.
+	 *
+	 * @param propertyName the property name
+	 * @return the property value, or <code>null</code> if none
+	 * @see #setProperty(String,Object)
+	 * @throws IllegalArgumentException if the given property name is null
+	 * @since 3.7
+	 */
+	public final Object getProperty(String propertyName);
+</pre>
+<pre>
+	/**
+	 * Sets the named property of this rewrite to the given value,
+	 * or to null to clear it.
+	 * 
+	 * Clients should employ property names that are sufficiently unique
+	 * to avoid inadvertent conflicts with other clients that might also be
+	 * setting properties on the same rewrite.
+	 * 
+	 * 
+	 * Note that modifying a property is not considered a modification to the
+	 * AST itself. This is to allow clients to decorate existing rewrites with
+	 * their own properties without jeopardizing certain things (like the
+	 * validity of bindings), which rely on the underlying tree remaining static.
+	 * 
+	 *
+	 * @param propertyName the property name
+	 * @param data the new property value, or null if none
+	 * @see #getProperty(String)
+	 * @throws IllegalArgumentException if the given property name is null
+	 * @since 3.7
+	 */
+	public final void setProperty(String propertyName, Object data);
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324367">324367</a>
+IJavaProject.findPackageFragmentRoots(IClasspathEntry cpe) returns empty list
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311022">311022</a>
+NPE in InternalExtendedCompletionContext.getVisibleElement
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325131">325131</a>
+ASTRewrite should offer get/setProperty() like ASTNode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322789">322789</a>
+package-info.java Won't Build On First Compile Pass
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322581">322581</a>
+[5.0] Add Javadoc compiler option to (not) report missing tags for method type parameters
+
+<a name="v_B16"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - October 5, 2010 - 3.7.0 M3
+<br>Project org.eclipse.jdt.core v_B16
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B16">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS added to give the user flexibility to see null related warning arising because of assert statements (see details in <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342">bug 325342</a>):
+<pre>
+    /**
+     * Compiler option ID: Raise null related errors or warnings arising because of assert statements.
+     * When enabled, the compiler will flag all null related errors or warnings that have been enabled by the user,
+     * irrespective of whether a variable occurred in an assert statement.
+     * When disabled, the compiler will not flag null related errors or warnings on variables that got marked as maybe or definitely
+     * <code>null</code> in an assert statement upstream.
+     *
+     * Option id:<code>"org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts"</code>
+     * Possible values:<code>{ "enabled", "disabled" }</code>
+     * Default:<code>"disabled"</code>
+     *
+     * @since 3.7
+     * @category CompilerOptionID
+     */
+     public static final String COMPILER_PB_INCLUDE_ASSERTS_IN_NULL_ANALYSIS = PLUGIN_ID + ".compiler.problem.includeNullInfoFromAsserts";
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323012">323012</a>
+[jsr14][compiler] Class literal value is not cached when target is jsr14
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342">325342</a>
+Add new option for null analysis based on assert result.
+
+<a name="v_B15"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - September 28, 2010
+<br>Project org.eclipse.jdt.core v_B15
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B15">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=312603">312603</a>
+[content assist] field being declared is proposed as a method argument inside initialization
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342">325342</a>
+Add new option for null analysis based on assert result.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325481">325481</a>
+[assist] fields declared after a particular field are proposed in its initialization
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633">325633</a>
+1.4 project confused when referencing a return type of generic array from 1.5 project
+
+<a name="v_B14a"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M3 - September 21, 2010
+<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=325567">325567</a>
+A blocking &quot;java.lang.IllegalArgumentException: info cannot be null&quot; exception
+
+<a name="v_B13a"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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>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>
+    /**
+     * 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();
+
+    /**
+     * 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();
+
+    /**
+     * 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();
+
+    /**
+     * 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>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>
+    /**
+     * 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=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_B10"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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>Code formatter: 4 new options were added to better handle the addition of
+new lines after annotations.
+<pre>
+ * 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:           INSERT
+ * 
+ * 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
+ *
+ * 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
+ *
+ * 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>
+<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 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.
+ *
+ * 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).
+ *
+ * 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
+ */
+ISourceRange getNameRange() throws JavaModelException;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<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_B09"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B08"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B07"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B06"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B05"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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>
+New API added to be able to retrieve the name range for <code>org.eclipse.jdt.core.IImportDeclaration</code>:
+<pre>
+/**
+ * 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.
+ * 
+ *
+ * @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
+ */
+ISourceRange getNameRange() throws JavaModelException;
+</pre>
+</li>
+<li>
+New API added to be able to retrieve the name range for <code>org.eclipse.jdt.core.IPackageDeclaration</code>:
+<pre>
+/**
+ * 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=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_B04"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B03"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B02"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B01"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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=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_B00"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+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="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
+
+
+<hr>
+<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
+        src="http://www.w3.org/Icons/valid-html401"
+        alt="Valid HTML 4.01 Transitional" height="31" width="88"></a>
+  </p>
+</body>
+</html>
+
diff --git a/org.eclipse.jdt.core/notes/porting_guide.html b/org.eclipse.jdt.core/notes/porting_guide.html
new file mode 100644
index 0000000..1121f75
--- /dev/null
+++ b/org.eclipse.jdt.core/notes/porting_guide.html
@@ -0,0 +1,349 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>JDT Core Porting Guide</title>
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">	 
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
+</head>
+
+<body>
+
+<h1>JDT Core 3.0 Porting Guide</h1>
+<p>Last modified January 30, 2004</p> 
+<p>These entries for the porting guide cover Debug-related items.</p>
+<h2>Required changes for 3.0</h2>
+<p>None.</p>
+<h2>Recommended changes for 3.0</h2>
+<p><b class="title1">
+[JDT only] Improved support for working copies (package org.eclipse.jdt.core)
+</b></p>
+<p>The Java model working copy facility has been reworked in 3.0 to provide
+greatly increased functionality. Prior to 3.0, the Java model allowed creation
+of individual working copies of compilation units. Changes could be made to the
+working copy and later committed. There was support for limited analysis of a
+working copy in the context of the rest of the Java model. However, there was no
+way these these analyses could ever take into account more than one of the
+working copies at a time.</p>
+<p>The changes in 3.0 make it possible to create and manage sets of working
+copies of compilation units, and to perform analyses in the presence of all
+working copies in a set. For example, it is now possible for a client like JDT
+refactoring to create working copies for one or more compilation units that it
+is considering modifying and then to resolve type references between the working
+copies. Formerly this was only possible after the changes to the compilation
+unit working copies had been committed.</p>
+<p>The Java model API changes in 2 ways to add this improved support:</p>
+<p>(1) The functionality formerly found on IWorkingCopy and inherited by
+ICompilationUnit has been consolidated into ICompilationUnit. The IWorkingCopy
+interface was only used in this one place, and was gratuitously more general
+that in needed to be. This change simplifies the API. IWorkingCopy has been
+deprecated. Other places in the API where IWorkingCopy is used as a parameter or
+result type have been deprecated as well; the replacement API methods mention
+ICompilationUnit instead of IWorkingCopy.</p>
+<p>(2) The interface IBufferFactory has been replaced by WorkingCopyOwner. The
+improved support for working copies requires that there be an object to own the
+working copies. Although IBufferFactory is in the right place, the name does not
+adequately convey how the new working copy mechanism works. WorkingCopyOwner is
+much more suggestive. In addition, WorkingCopyOwner is declared as an abstract
+class, rather than as an interface, to allow the notion of working copy owner to
+evolve in the future. The one method on IBufferFactory moves to WorkingCopyOwner
+unaffected. WorkingCopyOwner does not implement IBufferFactory to make it clear
+that IBufferFactory is a thing of the past. IBufferFactory has been deprecated.
+Other places in the API where IBufferFactory&nbsp; appears as a parameter or
+result type have been deprecated as well; the replacement API methods mention
+WorkingCopyOwner instead of IBufferFactory.</p>
+<p>These changes do not break binary compatibility.</p>
+<p>When migrating, all references to the type IWorkingCopy should instead
+reference ICompilationUnit. The sole implementation of IWorkingCopy implements
+ICompilationUnit as well, meaning objects of type IWorkingCopy can be safely
+cast to ICompilationUnit.</p>
+<p>A class that implements IBufferFactory will need to replaced by a subclass of
+WorkingCopyOwner. Although WorkingCopyOwner does not implement IBufferFactory
+itself, it would be possible to declare the subclass of WorkingCopyOwner that
+implements IBufferFactory thereby creating a bridge between old and new (IBufferFactory
+declares createBuffer(IOpenable) whereas WorkingCopyOwner declares
+createBuffer(ICompilationUnit); ICompilationUnit extends IOpenable).</p>
+<p>Because the changes involving IWorkingCopy and IBufferFactory are interwined,
+we recommend dealing with both at the same time. The detail</p>
+<ul>
+  <li>IWorkingCopy (package org.eclipse.jdt.core)
+    <ul>
+      <li>public void commit(boolean, IProgressMonitor) has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public void commitWorkingCopy(boolean, IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>Replace wc.commit(b,monitor) with ((ICompilationUnit)
+            wc).commitWorkingCopy(b,monitor)</li>
+        </ul>
+      </li>
+      <li>public void destroy() has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public void discardWorkingCopy(boolean, IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>Replace wc.destroy() with ((ICompilationUnit)
+            wc).discardWorkingCopy()</li>
+        </ul>
+      </li>
+      <li>public IJavaElement findSharedWorkingCopy(IBufferFactory) has been
+        deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public ICompilationUnit findWorkingCopy(WorkingCopyOwner)</li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>public IJavaElement getOriginal(IJavaElement) has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on IJavaElement:
+            <ul>
+              <li>public IJavaElement getPrimaryElement()</li>
+            </ul>
+          </li>
+        </ul>
+        <ul>
+          <li>Replace wc.getOriginal(elt) with elt.getPrimaryElement()</li>
+          <li>Note: Unlike IWorkingCopy.getOriginal,
+            IJavaElement.getPrimaryElement does not return <code>null</code> if
+            the receiver is not a working copy.</li>
+        </ul>
+      </li>
+      <li>public IJavaElement getOriginalElement() has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public ICompilationUnit getPrimary()</li>
+            </ul>
+          </li>
+          <li>Replace wc.getOriginalElement() with ((ICompilationUnit)
+            wc).getPrimary()</li>
+          <li>Note: Unlike IWorkingCopy.getOriginalElement,
+            IWorkingCopy.getPrimary does not return <code>null</code> if the
+            receiver is not a working copy.</li>
+        </ul>
+      </li>
+      <li>public IJavaElement[] findElements(IJavaElement) has been deprecated.
+        <ul>
+          <li>The method is now declared on ICompilationUnit directly.</li>
+          <li>Replace wc.findElements(elts) with ((ICompilationUnit)
+            wc).findElements(elts)</li>
+        </ul>
+      </li>
+      <li>public IType findPrimaryType() has been deprecated.
+        <ul>
+          <li>The method is now declared on ICompilationUnit directly.</li>
+          <li>Replace wc.findPrimaryType() with ((ICompilationUnit)
+            wc).findPrimaryType()</li>
+        </ul>
+      </li>
+      <li>public IJavaElement getSharedWorkingCopy(IProgressMonitor,
+        IBufferFactory, IProblemRequestor) has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
+                IProblemRequestor, IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>[parameter order scrambling]</li>
+        </ul>
+      </li>
+      <li>public IJavaElement getWorkingCopy() has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public ICompilationUnit getWorkingCopy(IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>Replace wc.getWorkingCopy() with ((ICompilationUnit)
+            wc).getWorkingCopy(null)</li>
+        </ul>
+      </li>
+      <li>public IJavaElement getWorkingCopy(IProgressMonitor, IBufferFactory,
+        IProblemRequestor) has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
+                IProblemRequestor, IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>[parameter order scrambling]</li>
+        </ul>
+      </li>
+      <li>public boolean isBasedOn(IResource) has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public boolean hasResourceChanged()</li>
+            </ul>
+          </li>
+          <li>Replace wc.isBasesOn(res) with ((ICompilationUnit)
+            wc).hasResourceChanged()</li>
+        </ul>
+      </li>
+      <li>public boolean isWorkingCopy() has been deprecated.
+        <ul>
+          <li>The method is now declared on ICompilationUnit directly.</li>
+          <li>Replace wc.isWorkingCopy() with ((ICompilationUnit)
+            wc).isWorkingCopy()</li>
+        </ul>
+      </li>
+      <li>public IMarker[]&nbsp; reconcile() has been deprecated.
+        <ul>
+          <li>The equivalent functionality is now provided on ICompilationUnit
+            directly:
+            <ul>
+              <li>public void reconcile(boolean,boolean,WorkingCopyOwner,IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>Replace wc.reconcile() with ((ICompilationUnit)
+            wc).reconcile(false,false,null,null)</li>
+          <li>Note: The former method always returned null; the replacement
+            method does not return a result.</li>
+        </ul>
+      </li>
+      <li>public void reconcile(boolean, IProgressMonitor) has been deprecated.
+        <ul>
+          <li>The method is now declared on ICompilationUnit directly.</li>
+          <li>Replace wc.reconcile(b,monitor) with ((ICompilationUnit)
+            wc).reconcile(false,b,null,monitor)</li>
+        </ul>
+      </li>
+      <li>public void restore() has been deprecated.
+        <ul>
+          <li>The method is now declared on ICompilationUnit directly.</li>
+          <li>Replace wc.restore() with ((ICompilationUnit) wc).restore()</li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li>IType (package org.eclipse.jdt.core)
+    <ul>
+      <li>public ITypeHierarchy newSupertypeHierarchy(IWorkingCopy[],
+        IProgressMonitor) has been deprecated.
+        <ul>
+          <li>The replacement method is provided on the same class:
+            <ul>
+              <li>public ITypeHierarchy newSupertypeHierarchy(ICompilationUnit[],
+                IProgressMonitor)</li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+      <li>public ITypeHierarchy newTypeHierarchy(IWorkingCopy[],
+        IProgressMonitor) has been deprecated.
+        <ul>
+          <li>The replacement method is provided on the same class:
+            <ul>
+              <li>public ITypeHierarchy newTypeHierarchy(ICompilationUnit[],
+                IProgressMonitor)</li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li>IClassFile (package org.eclipse.jdt.core)
+    <ul>
+      <li>public IJavaElement getWorkingCopy(IProgressMonitor, IBufferFactory)
+        has been deprecated.
+        <ul>
+          <li>The replacement method is provided on the same class:
+            <ul>
+              <li>public ICompilationUnit getWorkingCopy(WorkingCopyOwner,
+                IProgressMonitor)</li>
+            </ul>
+          </li>
+          <li>[parameter order scrambling]</li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li>JavaCore (package org.eclipse.jdt.core)
+    <ul>
+      <li>public IWorkingCopy[] getSharedWorkingCopies(IBufferFactory) has been
+        deprecated.
+        <ul>
+          <li>The replacement method is provided on the same class:
+            <ul>
+              <li>public ICompilationUnit[] getWorkingCopies(WorkingCopyOwner)</li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+  <li>SearchEngine (package org.eclipse.jdt.core.search)
+    <ul>
+      <li>public SearchEngine(IWorkingCopy[]) has been deprecated.
+        <ul>
+          <li>The replacement constructor is provided on the same class:
+            <ul>
+              <li>public SearchEngine(ICompilationUnit[])</li>
+            </ul>
+          </li>
+        </ul>
+      </li>
+    </ul>
+  </li>
+</ul>
+
+<p><b class="title1">
+[JDT only] Java search participants (package org.eclipse.jdt.core.search)
+</b></p>
+<p>Languages close to Java (such as JSP, SQLJ, JWS, etc.) should be able to participate in Java searching. 
+In particular implementors of such languages should be able to:</p>
+<ul>
+<li>index their source by converting it into Java equivalent, and feeding it to the Java indexer</li>
+<li>index their source by parsing it themselves, but record Java index entries</li>
+<li>locate matches in their source by converting it into Java equivalent, and feeding it to the Java match locator</li>
+<li>locate matches in their source by matching themselves, and return Java matches</li>
+</ul>
+<p>Such an implementor is called a search participant. It extends the SearchParticipant 
+class. Search participants are passed to search queries 
+(see SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor).</p>
+<p>For either indexing or locating matches, a search participant needs to define a subclass of 
+SearchDocument that can retrieve the contents of a document by overriding either 
+getByteContents() or getCharContents(). An instance of such class is
+returned in SearchParticipant.getDocument(IFile) or getDocument(String).</p>
+<p>A search participant whishing to index some document will use 
+SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) to schedule the indexing
+of the given document in the given index. Once the document is ready to be indexed, the underlying framework
+calls SearchParticipant.indexDocument(SearchDocument, IPath). The search participant is then
+supposed to get the document's content, parse it and add index entries using 
+SearchParticipant.addIndexEntry(char[], char[], SearchDocument).</p>
+<p>Once indexing is done, one can then query the indexes and locate matches using 
+SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor).
+This first asks each search participant for the indexes needed by this query using 
+SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope). For each index entry that matches
+the given pattern, a search document is created by asking the search participant (see getDocument(String)).
+All these documents are passed to the search participant so that it can locate matches using 
+locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor).
+The search participant notifies the SearchRequestor of search matches using acceptSearchMatch(SearchMatch)
+and passing an instance of a subclass of SearchMatch.</p>
+<p>A search participant can delegate part of its work to the default Java search participant. An instance of
+this default participant is obtained using SearchEngine.getDefaultSearchParticipant(). For example when asked to
+locate matches, an SQLJ participant can create documents .java documents from its .sqlj documents and
+delegate the work to the default participant passing it the .java documents.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jdt.core/plugin.jars b/org.eclipse.jdt.core/plugin.jars
new file mode 100644
index 0000000..b47c1c8
--- /dev/null
+++ b/org.eclipse.jdt.core/plugin.jars
@@ -0,0 +1,9 @@
+jdtcore.jar=\
+	batch,\
+	codeassist,\
+	compiler,\
+	eval,\
+	formatter,\
+	dom,\
+	model, \
+	search
diff --git a/org.eclipse.jdt.core/plugin.properties b/org.eclipse.jdt.core/plugin.properties
new file mode 100644
index 0000000..b6b29a2
--- /dev/null
+++ b/org.eclipse.jdt.core/plugin.properties
@@ -0,0 +1,28 @@
+###############################################################################
+# Copyright (c) 2000, 2009 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+providerName=Eclipse.org
+pluginName=Java Development Tools Core
+javaNatureName=Java
+javaBuilderName=Java Builder
+javaProblemName=Java Problem
+buildPathProblemName=Build Path Problem
+transientJavaProblemName=Transient Java Problem
+classpathVariableInitializersName=Classpath Variable Initializers
+classpathContainerInitializersName=Classpath Container Initializers
+codeFormattersName=Source Code Formatters
+compilationParticipantsName=Compilation Participants
+annotationProcessorManagerName=Java 6 Annotation Processor Manager
+javaTaskName=Java Task
+javaPropertiesName=Java Properties File
+javaSourceName=Java Source File
+javaClassName=Java Class File
+jarManifestName=JAR Manifest File
+
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
new file mode 100644
index 0000000..5d69788
--- /dev/null
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<!--
+    Copyright (c) 2004, 2011 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<!-- =================================================================================== -->
+<!-- JDT/CORE Plug-in Manifest                                                           -->
+<!-- =================================================================================== -->
+<plugin>
+
+<!-- =================================================================================== -->
+<!-- Prerequisite Plug-ins                                                               -->
+<!-- =================================================================================== -->
+
+
+<!-- =================================================================================== -->
+<!-- Runtime Libraries                                                                   -->
+<!-- =================================================================================== -->
+
+
+<!-- =================================================================================== -->
+<!-- Extension Point: Initializers of Classpath Variables                                -->
+<!-- =================================================================================== -->
+
+<extension-point name="%classpathVariableInitializersName" 
+	id="classpathVariableInitializer"
+	schema="schema/classpathVariableInitializer.exsd"/>
+  
+<!-- =================================================================================== -->
+<!-- Extension Point: Initializers of Classpath Containers                               -->
+<!-- =================================================================================== -->
+
+<extension-point name="%classpathContainerInitializersName" 
+	id="classpathContainerInitializer" 
+	schema="schema/classpathContainerInitializer.exsd"/>
+
+<!-- =================================================================================== -->
+<!-- Extension Point: Formatter of Source Code                                           -->
+<!-- =================================================================================== -->
+
+<extension-point name="%codeFormattersName" 
+	id="codeFormatter"
+	schema="schema/codeFormatter.exsd"/>
+
+<!-- =================================================================================== -->
+<!-- Extension Point: Compilation Participant                                            -->
+<!-- =================================================================================== -->
+
+<extension-point name="%compilationParticipantsName" 
+	id="compilationParticipant"
+	schema="schema/compilationParticipant.exsd"/>
+
+<!-- =================================================================================== -->
+<!-- Extension Point: Java 6 Annotation Processor Manager                                -->
+<!-- =================================================================================== -->
+
+<extension-point name="%annotationProcessorManagerName" 
+	id="annotationProcessorManager"
+	schema="schema/annotationProcessorManager.exsd"/>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Nature                                                              -->
+<!-- =================================================================================== -->
+
+<extension 
+	point="org.eclipse.core.resources.natures" 
+	id="javanature"
+	name="%javaNatureName">
+	<runtime>
+		<run class="org.eclipse.jdt.internal.core.JavaProject">
+		</run>
+	</runtime>
+</extension>
+
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Builder                                                             -->
+<!-- =================================================================================== -->
+
+<extension 
+	point="org.eclipse.core.resources.builders" 
+	id="javabuilder"
+	name="%javaBuilderName">
+	<builder>
+		<run class="org.eclipse.jdt.internal.core.builder.JavaBuilder">
+		</run>
+	</builder>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Problem                                                             -->
+<!-- =================================================================================== -->
+<extension id="problem" point="org.eclipse.core.resources.markers" name="%javaProblemName">
+	<super type="org.eclipse.core.resources.problemmarker"/>
+	<super type="org.eclipse.core.resources.textmarker"/>
+	<persistent value="true"/>
+	<attribute name="id"/>
+	<attribute name="flags"/>
+	<attribute name="arguments"/>
+	<attribute name="categoryId"/>
+</extension>   
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Buildpath Problem                                                   -->
+<!-- =================================================================================== -->
+<extension id="buildpath_problem" point="org.eclipse.core.resources.markers" name="%buildPathProblemName">
+	<super type="org.eclipse.core.resources.problemmarker"/>
+	<super type="org.eclipse.core.resources.textmarker"/>
+	<persistent value="true"/>
+	<attribute name ="cycleDetected"/>
+	<attribute name="id"/>
+	<attribute name="arguments"/>
+</extension>   
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Transient Problem                                                   -->
+<!-- =================================================================================== -->
+<extension id="transient_problem" point="org.eclipse.core.resources.markers" name="%transientJavaProblemName">
+	<super type="org.eclipse.core.resources.textmarker"/>
+	<persistent value="false"/>
+	<attribute name="id"/>
+	<attribute name="flags"/>
+	<attribute name="arguments"/>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Task                                                                -->
+<!-- =================================================================================== -->
+<extension id="task" name="%javaTaskName" point="org.eclipse.core.resources.markers">
+    <super type="org.eclipse.core.resources.taskmarker"/> 
+    <persistent value="true"/>
+</extension>
+    
+<!-- =================================================================================== -->
+<!-- Extension: Javac Ant Adapter                                                        -->
+<!-- =================================================================================== -->
+<extension 
+	point="org.eclipse.ant.core.extraClasspathEntries">
+	<extraClasspathEntry
+		library="jdtCompilerAdapter.jar">
+	</extraClasspathEntry>
+</extension> 
+
+<!-- =================================================================================== -->
+<!-- Extension: Javac Ant Task                                                           -->
+<!-- =================================================================================== -->
+<extension point="org.eclipse.ant.core.antTasks">
+	<antTask
+		name="eclipse.checkDebugAttributes"
+		class="org.eclipse.jdt.core.CheckDebugAttributes"
+		library="jdtCompilerAdapter.jar">
+	</antTask>
+	<antTask
+		name="eclipse.buildJarIndex"
+		class="org.eclipse.jdt.core.BuildJarIndex"
+		library="jdtCompilerAdapter.jar">
+	</antTask>
+</extension>
+      
+<!-- =================================================================================== -->
+<!-- Extension: User Library Container                                                   -->
+<!-- =================================================================================== -->
+<extension
+      point="org.eclipse.jdt.core.classpathContainerInitializer">
+      <classpathContainerInitializer
+            class="org.eclipse.jdt.internal.core.UserLibraryClasspathContainerInitializer"
+            id="org.eclipse.jdt.USER_LIBRARY">
+      </classpathContainerInitializer>
+   </extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java File Types                                                          -->
+<!-- =================================================================================== -->
+<extension point="org.eclipse.team.core.fileTypes">
+	<fileTypes extension="java" type="text"/>
+	<fileTypes extension="classpath" type="text"/>
+	<fileTypes extension="properties" type="text"/>
+	<fileTypes extension="class" type="binary"/>
+	<fileTypes extension="jar" type="binary"/>
+	<fileTypes extension="jardesc" type="text"/>
+	<fileTypes extension="zip" type="binary"/>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Code Formatter                                                      -->
+<!-- =================================================================================== -->
+<extension
+      id="JavaCodeFormatter"
+      point="org.eclipse.core.runtime.applications">
+      	<application>
+      		<run class="org.eclipse.jdt.core.formatter.CodeFormatterApplication" />
+		</application>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Generate Indexer                                                    -->
+<!-- =================================================================================== -->
+<extension
+      id="JavaIndexer"
+      point="org.eclipse.core.runtime.applications">
+   		<application>
+      		<run class="org.eclipse.jdt.core.index.JavaIndexerApplication" />
+   		</application>
+</extension>
+
+<!-- =================================================================================== -->
+<!-- Extension: Java Content Types                                                       -->
+<!-- =================================================================================== -->
+<extension point="org.eclipse.core.contenttype.contentTypes">
+	<!-- declares a content type for Java Properties files -->
+	<content-type id="javaProperties" name="%javaPropertiesName" 
+		base-type="org.eclipse.core.runtime.text"
+		priority="high"				
+		file-extensions="properties"
+		default-charset="ISO-8859-1"/>
+	<!-- Associates .classpath to the XML content type -->
+	<file-association 
+		content-type="org.eclipse.core.runtime.xml" 
+		file-names=".classpath"/>  
+	<!-- declares a content type for Java Source files -->
+	<content-type id="javaSource" name="%javaSourceName" 
+		base-type="org.eclipse.core.runtime.text"
+		priority="high"				
+		file-extensions="java"/>
+	<!-- declares a content type for Java class files -->
+    <content-type id="javaClass" name="%javaClassName" 
+        priority="high"				
+        file-extensions="class">        
+        <describer
+            class="org.eclipse.core.runtime.content.BinarySignatureDescriber">
+            <parameter name="signature" value="CA, FE, BA, BE"/>
+        </describer>
+    </content-type>        
+	<!-- declares a content type for JAR manifest files -->
+    <content-type id="JARManifest" name="%jarManifestName" 
+        base-type="org.eclipse.core.runtime.text"
+        priority="high"				
+        file-names="MANIFEST.MF"
+        default-charset="UTF-8"/>
+</extension>
+      
+<!-- =================================================================================== -->
+<!-- Extension: Eclipse preferences initializer                                          -->
+<!-- =================================================================================== -->
+<extension
+      point="org.eclipse.core.runtime.preferences">
+   <initializer class="org.eclipse.jdt.internal.core.JavaCorePreferenceInitializer"/>
+</extension>
+<extension
+      point="org.eclipse.core.runtime.preferences">
+   <modifier class="org.eclipse.jdt.internal.core.JavaCorePreferenceModifyListener"/>
+</extension>
+
+</plugin>
diff --git a/org.eclipse.jdt.core/pom.xml b/org.eclipse.jdt.core/pom.xml
new file mode 100644
index 0000000..5b035b5
--- /dev/null
+++ b/org.eclipse.jdt.core/pom.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2012, 2013 Eclipse Foundation and others.
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Distribution License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/org/documents/edl-v10.php
+ 
+  Contributors:
+     Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>eclipse.jdt.core</artifactId>
+    <groupId>eclipse.jdt.core</groupId>
+    <version>4.3.0-SNAPSHOT</version>
+  </parent>
+  <groupId>org.eclipse.jdt</groupId>
+  <artifactId>org.eclipse.jdt.core</artifactId>
+  <version>3.9.0-SNAPSHOT</version>
+  <packaging>eclipse-plugin</packaging>
+
+  <build>
+    <plugins>
+    <plugin>
+		<artifactId>maven-antrun-plugin</artifactId>
+		<executions>
+			<execution>
+				<phase>prepare-package</phase>
+				<configuration>
+					<tasks>
+						<replace token="bundle_qualifier," value="${buildQualifier}," dir="${project.build.directory}/classes">
+							<include name="org/eclipse/jdt/internal/compiler/batch/messages.properties" />
+						</replace>
+					</tasks>
+				</configuration>
+				<goals>
+					<goal>run</goal>
+				</goals>
+			</execution>
+		</executions>
+	  </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho.extras</groupId>
+        <artifactId>tycho-custom-bundle-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>antadapter</id>
+            <phase>package</phase>
+            <goals>
+              <goal>custom-bundle</goal>
+            </goals>
+			<configuration>
+				<archive>
+					<addMavenDescriptor>false</addMavenDescriptor>
+				</archive>
+              <bundleLocation>${project.basedir}/scripts/antadapter</bundleLocation>
+              <classifier>antadapter</classifier>
+              <fileSets>
+                <fileSet>
+                  <directory>${project.build.directory}/jdtCompilerAdapter.jar-classes</directory>
+                  <excludes>
+                    <exclude>org/eclipse/jdt/core/CheckDebugAttributes*.*</exclude>
+                    <exclude>org/eclipse/jdt/core/BuildJarIndex*.*</exclude>
+                  </excludes>
+                </fileSet>
+              </fileSets>
+            </configuration>
+          </execution>
+          <execution>
+            <id>batch-compiler-src</id>
+            <phase>package</phase>
+            <goals>
+              <goal>custom-bundle</goal>
+            </goals>
+            <configuration>
+				<archive>
+					<addMavenDescriptor>false</addMavenDescriptor>
+				</archive>
+              <bundleLocation>${project.basedir}/scripts/source</bundleLocation>
+              <classifier>batch-compiler-src</classifier>
+              <fileSets>
+                <fileSet>
+                  <directory>${project.basedir}/batch</directory>
+                </fileSet>
+                <fileSet>
+                  <directory>${project.basedir}/compiler</directory>
+                </fileSet>
+                <fileSet>
+                  <directory>${project.basedir}/antadapter</directory>
+                  <excludes>
+				    <exclude>org/eclipse/jdt/core/CheckDebugAttributes.java</exclude>
+					<exclude>org/eclipse/jdt/core/BuildJarIndex.java</exclude>
+                  </excludes>
+                </fileSet>
+				<fileSet>
+                  <directory>${project.basedir}/../org.eclipse.jdt.compiler.tool/src</directory>
+                </fileSet>
+				<fileSet>
+                  <directory>${project.basedir}/../org.eclipse.jdt.compiler.apt/src</directory>
+                </fileSet>
+				<fileSet>
+                  <directory>${project.basedir}/scripts</directory>
+                  <includes>
+				    <include>about.html</include>
+					<include>build.xml</include>
+                  </includes>
+                </fileSet>
+              </fileSets>
+            </configuration>
+          </execution>
+          <execution>
+            <id>batch-compiler</id>
+            <phase>package</phase>
+            <goals>
+              <goal>custom-bundle</goal>
+            </goals>
+            <configuration>
+				<archive>
+					<addMavenDescriptor>false</addMavenDescriptor>
+				</archive>
+              <bundleLocation>${project.basedir}/scripts/binary</bundleLocation>
+              <classifier>batch-compiler</classifier>
+              <fileSets>
+                <fileSet>
+                  <directory>${project.build.directory}/jdtCompilerAdapter.jar-classes</directory>
+                  <includes>
+				    <include>META-INF/eclipse.inf</include>
+                  </includes>
+                </fileSet>
+				<fileSet>
+                  <directory>${project.basedir}/scripts</directory>
+                  <includes>
+				    <include>about.html</include>
+                  </includes>
+                </fileSet>
+                <fileSet>
+                  <directory>${project.build.directory}/classes</directory>
+                  <includes>
+                    <include>org/eclipse/jdt/internal/compiler/**</include>
+                    <include>org/eclipse/jdt/core/compiler/**</include>
+                  </includes>
+                  <excludes>
+                    <exclude>**/package.htm*</exclude>
+                    <exclude>org/eclipse/jdt/core/compiler/CompilationParticipant*.class</exclude>
+                    <exclude>org/eclipse/jdt/core/compiler/BuildContext.class</exclude>
+                    <exclude>org/eclipse/jdt/core/compiler/IScanner.class</exclude>
+                    <exclude>org/eclipse/jdt/core/compiler/ITerminalSymbols*.class</exclude>
+                    <exclude>org/eclipse/jdt/core/compiler/ReconcileContext*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/DocumentElementParser*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/ISourceElementRequestor*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/SourceElementParser*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/SourceJavadocParser*.class</exclude>
+                    <exclude>org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter*.class</exclude>
+                  </excludes>
+                </fileSet>
+              </fileSets>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-p2-plugin</artifactId>
+        <version>${tycho.version}</version>
+        <executions>
+          <execution>
+            <id>attached-p2-metadata</id>
+            <phase>package</phase>
+            <goals>
+              <goal>p2-metadata</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd b/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd
new file mode 100644
index 0000000..11d9c55
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd
@@ -0,0 +1,123 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="annotationProcessorManager" name="Java 6 Annotation Processor Manager"/>
+      </appInfo>
+      <documentation>
+         This extension point gives the JDT access to a Java 6 annotation processor manager on platforms where that is available. At most one Java 6 annotation processor manager extension can be registered.  Java 5 annotation processors are handled separately, using the org.eclipse.jdt.core.compilationParticipants extension point.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="annotationProcessorManager"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="annotationProcessorManager">
+      <annotation>
+         <documentation>
+            The Java 6 annotation processor is responsible for dispatching Java 6 annotation processors in the context of IDE builds and reconciles.  There is at most one Java 6 annotation processor manager system-wide.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+         </sequence>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that implements the Java 6 annotation processor manager. This class must implement a public subclass of &lt;code&gt;org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager&lt;/code&gt; with a public 0-argument constructor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a unique identifier for this participant
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         3.3
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         org.eclipse.jdt.compiler.apt
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2007 BEA Systems, Inc and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at 
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
new file mode 100644
index 0000000..5d282b5
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
@@ -0,0 +1,124 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="classpathContainerInitializer" name="Classpath Container Initializers"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to contribute custom classpath container initializers, 
+      which are used to lazily bind classpath containers to instances of org.eclipse.jdt.core.IClasspathContainer.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="classpathContainerInitializer" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="classpathContainerInitializer">
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a unique name identifying all containers for which this initializer will be activated.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that implements this container initializer.
+         This class must implement a public subclass of &lt;code&gt;org.eclipse.jdt.core.ClasspathContainerInitializer&lt;/code&gt; with a public 0-argument constructor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.ClasspathContainerInitializer"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         2.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of a declaration of a &lt;code&gt;ClasspathContainerInitializer&lt;/code&gt; for a classpath container named &quot;JDK&quot;:  &lt;pre&gt;                                                                       
+&lt;extension point=&quot;org.eclipse.jdt.core.classpathContainerInitializer&quot;&gt;            
+   &lt;classpathContainerInitializer                                          
+      id=&quot;JDK&quot;                                                        
+      class=&quot;com.example.MyInitializer&quot;/&gt;                           
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2000, 2004 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made 
+available under the terms of the Eclipse Public License v1.0 which accompanies 
+this distribution, and is available at &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
new file mode 100644
index 0000000..eb0b558
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
@@ -0,0 +1,141 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="classpathVariableInitializer" name="Classpath Variable Initializers"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to contribute custom classpath variable initializers, 
+      which are used to lazily bind classpath variables.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="classpathVariableInitializer" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="classpathVariableInitializer">
+      <complexType>
+         <attribute name="variable" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a unique name identifying the variable for which this initializer will be activated.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that implements this variable initializer.
+         This class must implement a public subclass of &lt;code&gt;org.eclipse.jdt.core.ClasspathVariableInitializer&lt;/code&gt; with a public 0-argument constructor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.ClasspathVariableInitializer"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="deprecated" type="string">
+            <annotation>
+               <documentation>
+                  String explaining the reason why the associated variable is deprecated
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="readOnly" type="boolean">
+            <annotation>
+               <documentation>
+                  Indicates that the associated variable cannot be modified
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         2.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of a declaration of a &lt;code&gt;ClasspathVariableInitializer&lt;/code&gt; for a classpath variable named &quot;FOO&quot;:  &lt;pre&gt;                                                                       
+&lt;extension point=&quot;org.eclipse.jdt.core.classpathVariableInitializer&quot;&gt;            
+   &lt;classpathVariableInitializer                                          
+      variable=&quot;FOO&quot;                                                        
+      class=&quot;com.example.CPVInitializer&quot;/&gt;                           
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2000, 2004 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made 
+available under the terms of the Eclipse Public License v1.0 which accompanies 
+this distribution, and is available at &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.jdt.core/schema/codeFormatter.exsd b/org.eclipse.jdt.core/schema/codeFormatter.exsd
new file mode 100644
index 0000000..61c1911
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/codeFormatter.exsd
@@ -0,0 +1,100 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="codeFormatter" name="Code Formatters"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to contribute new source code formatter implementations.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appInfo>
+            <meta.element deprecated="true" />
+         </appInfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="codeFormatter" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a fully qualified identifier of the target extension point
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  an optional identifier of the extension instance
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  an optional name of the extension instance
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="codeFormatter">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that defines the code formatter implementation. This class must be a public implementation of &lt;code&gt;org.eclipse.jdt.core.ICodeFormatter&lt;/code&gt; with a public 0-argument constructor.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         2.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of an implementation of &lt;code&gt;ICodeFormatter&lt;/code&gt;:  &lt;pre&gt;                                                                       
+&lt;extension point=&quot;org.eclipse.jdt.core.codeFormatter&quot;&gt;            
+   &lt;codeFormatter                                                                                              
+      class=&quot;com.example.MyCodeFormatter&quot;/&gt;                           
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2000, 2010 IBM Corporation and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials are made 
+available under the terms of the Eclipse Public License v1.0 which accompanies 
+this distribution, and is available at &lt;a
+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.jdt.core/schema/compilationParticipant.exsd b/org.eclipse.jdt.core/schema/compilationParticipant.exsd
new file mode 100644
index 0000000..b786852
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/compilationParticipant.exsd
@@ -0,0 +1,192 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jdt.core">
+<annotation>
+      <appInfo>
+         <meta.schema plugin="org.eclipse.jdt.core" id="compilationParticipant" name="Compilation Participants"/>
+      </appInfo>
+      <documentation>
+         This extension point allows clients to participate in the compilation process by receiving notifications at various stages of build and reconcile, via a org.eclipse.jdt.core.compiler.CompilationParticipant.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <complexType>
+         <sequence>
+            <element ref="compilationParticipant" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appInfo>
+                  <meta.attribute translatable="true"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="compilationParticipant">
+      <annotation>
+         <documentation>
+            definition of a compilation participant. This definition allows to order participants. Participants are run by group. The group of participants that modify the environment is run first, then the group of participants that create problems is run, finally the group of other participants is run. Inside each group, participants are ordered using their &apos;requires&apos; attributes. If a &apos;requires&apos; attribute point to a participant that doesn&apos;t belong to the group, it is ignored.
+         </documentation>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="requires" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="managedMarker" minOccurs="0" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the class that implements this compilation participant. This class must implement a public subclass of &lt;code&gt;org.eclipse.jdt.core.compiler.CompilationParticipant&lt;/code&gt; with a public 0-argument constructor.
+               </documentation>
+               <appInfo>
+                  <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.compiler.CompilationParticipant"/>
+               </appInfo>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  a unique identifier for this participant
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="modifiesEnvironment" type="boolean">
+            <annotation>
+               <documentation>
+                  optionally specify whether this compilation participant modifies the environment, thus affecting binding resolution. If not specified, false is assumed.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="createsProblems" type="boolean">
+            <annotation>
+               <documentation>
+                  optionally specifies whether this compilation participant creates problems. If not specified, false is assumed.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="requiredSourceLevel" type="string">
+            <annotation>
+               <documentation>
+                  the required source level this participant needs (one of the JavaCore.VERSION* constants). If a project&apos;s source level is below this required source level, the participant will not be invoked. If this attribute is not specified, the participant will be invoked for any source level.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="requires">
+      <annotation>
+         <documentation>
+            a participant that is required to run this compilation participant
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="id" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the unique identifier of the participant that is required
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="managedMarker">
+      <annotation>
+         <documentation>
+            a managed marker is created from the recorded problems (see BuildContext#recordNewProblems(CategorizedProblem[])) and is removed when the corresponding source file is re-built or when the project is cleaned
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="markerType" type="string" use="required">
+            <annotation>
+               <documentation>
+                  the type of the managed marker
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="since"/>
+      </appInfo>
+      <documentation>
+         3.2
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="examples"/>
+      </appInfo>
+      <documentation>
+         Example of a declaration of a &lt;code&gt;compilationParticipant&lt;/code&gt;:  &lt;pre&gt;                                                                       
+&lt;extension
+      id=&quot;apt&quot;
+      name=&quot;%annotationProcessingName&quot;
+      point=&quot;org.eclipse.jdt.core.compilationParticipant&quot;&gt;
+   &lt;compilationParticipant
+         class=&quot;org.eclipse.jdt.apt.core.internal.AptCompilationParticipant&quot;
+         id=&quot;APT&quot;
+         requiredSourceLevel=&quot;1.5&quot;&gt;
+      &lt;managedMarker markerType=&quot;org.eclipse.jdt.apt.core.compile.problem&quot;/&gt;
+   &lt;/compilationParticipant&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="apiInfo"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="implementation"/>
+      </appInfo>
+      <documentation>
+         
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appInfo>
+         <meta.section type="copyright"/>
+      </appInfo>
+      <documentation>
+         Copyright (c) 2006 BEA Systems, Inc and others.&lt;br&gt;
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v1.0
+which accompanies this distribution, and is available at 
+&lt;a href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;
+      </documentation>
+   </annotation>
+
+</schema>
diff --git a/org.eclipse.jdt.core/schema/compiler.dtd b/org.eclipse.jdt.core/schema/compiler.dtd
new file mode 100644
index 0000000..7d989a3
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/compiler.dtd
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!ELEMENT compiler (error*,command_line?,options?,classpaths?,error*,warning*,sources*,extra_problems?,stats?,exception*)>
+<!ELEMENT command_line (argument*)>
+<!ELEMENT options (option*)>
+<!ELEMENT classpaths (classpath+)>
+<!ELEMENT error (#PCDATA)>
+<!ELEMENT warning (#PCDATA)>
+<!ELEMENT sources (source+)>
+<!ELEMENT source (problems*,tasks*,(classfile | error)*)>
+<!ELEMENT problems (problem+)>
+<!ELEMENT problem (message,source_context,arguments?)>
+<!ELEMENT arguments (argument+)>
+<!ELEMENT tasks (task+)>
+<!ELEMENT task (message, source_context)>
+<!ELEMENT stats (time?,number_of_lines?,problem_summary?,number_of_classfiles?)>
+<!ELEMENT argument (#PCDATA)>
+<!ELEMENT option (#PCDATA)>
+<!ELEMENT classpath (#PCDATA)>
+<!ELEMENT message (#PCDATA)>
+<!ELEMENT number_of_lines (#PCDATA)>
+<!ELEMENT time (#PCDATA)>
+<!ELEMENT number_of_classfiles (#PCDATA)>
+<!ELEMENT classfile (#PCDATA)>
+<!ELEMENT source_context (#PCDATA)>
+<!ELEMENT problem_summary (#PCDATA)>
+<!ELEMENT exception (#PCDATA)>
+<!ELEMENT extra_problems (extra_problem+)>
+<!ELEMENT extra_problem (message,source_context)>
+<!ATTLIST argument value CDATA #REQUIRED>
+<!ATTLIST option key   CDATA #REQUIRED
+				 value CDATA #REQUIRED
+>
+<!ATTLIST classpath path CDATA #REQUIRED
+                    id   CDATA #REQUIRED
+>
+<!ATTLIST source path    CDATA #REQUIRED
+                 output  CDATA #IMPLIED
+                 package CDATA #IMPLIED>
+<!ATTLIST problems problems CDATA #REQUIRED
+				   errors   CDATA #REQUIRED
+				   warnings CDATA #REQUIRED
+>
+<!ATTLIST tasks tasks CDATA #REQUIRED>
+<!ATTLIST problem charEnd    CDATA #REQUIRED
+				  charStart  CDATA #REQUIRED
+				  severity   CDATA #REQUIRED
+				  line       CDATA #REQUIRED
+				  id         CDATA #REQUIRED
+				  problemID  CDATA #IMPLIED
+				  optionKey  CDATA #IMPLIED
+				  categoryID CDATA #IMPLIED
+>
+<!ATTLIST extra_problem charEnd   CDATA #REQUIRED
+				        charStart CDATA #REQUIRED
+				        severity  CDATA #REQUIRED
+				        line      CDATA #REQUIRED
+>
+<!ATTLIST extra_problems problems CDATA #REQUIRED
+>
+<!ATTLIST message value CDATA #REQUIRED>
+<!ATTLIST source_context value       CDATA #REQUIRED
+                         sourceStart CDATA #REQUIRED
+                         sourceEnd   CDATA #REQUIRED
+>
+<!ATTLIST task charEnd    CDATA #REQUIRED
+			   charStart  CDATA #REQUIRED
+			   line       CDATA #REQUIRED
+			   optionKey  CDATA #IMPLIED
+>
+<!ATTLIST classfile path CDATA #REQUIRED>
+<!ATTLIST error message CDATA #REQUIRED>
+<!ATTLIST warning message CDATA #REQUIRED>
+<!ATTLIST problem_summary problems CDATA #REQUIRED
+                          errors   CDATA #REQUIRED
+                          warnings CDATA #REQUIRED
+                          tasks    CDATA #REQUIRED
+>
+<!ATTLIST number_of_classfiles value CDATA #REQUIRED>
+<!ATTLIST time value CDATA #REQUIRED>
+<!ATTLIST number_of_lines value CDATA #REQUIRED>
+<!ATTLIST compiler name      CDATA #REQUIRED
+                  copyright CDATA #REQUIRED
+                  version   CDATA #REQUIRED
+>
+<!ATTLIST exception class CDATA #REQUIRED
+			        message CDATA #REQUIRED
+>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/GenerateBuildScript$1.class b/org.eclipse.jdt.core/scripts/GenerateBuildScript$1.class
new file mode 100644
index 0000000..2104d6d
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/GenerateBuildScript$1.class
Binary files differ
diff --git a/org.eclipse.jdt.core/scripts/GenerateBuildScript$2.class b/org.eclipse.jdt.core/scripts/GenerateBuildScript$2.class
new file mode 100644
index 0000000..e52da5e
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/GenerateBuildScript$2.class
Binary files differ
diff --git a/org.eclipse.jdt.core/scripts/GenerateBuildScript.class b/org.eclipse.jdt.core/scripts/GenerateBuildScript.class
new file mode 100644
index 0000000..d355baf
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/GenerateBuildScript.class
Binary files differ
diff --git a/org.eclipse.jdt.core/scripts/GenerateBuildScript.java b/org.eclipse.jdt.core/scripts/GenerateBuildScript.java
new file mode 100644
index 0000000..d0bb011
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/GenerateBuildScript.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+
+public class GenerateBuildScript {
+
+	private static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+	private static final String HEADER=
+		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"<project name=\"export-executable\" default=\"build_executable\">" +LINE_SEPARATOR + //$NON-NLS-1$
+		"    <target name=\"build_executable\">" + LINE_SEPARATOR; //$NON-NLS-1$
+
+	private static final String SOURCE_FILES =
+		"	    <echo message=\"compiling sources      -> .o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"        <apply failonerror=\"true\" executable=\"$'{'gcc-path'}'/bin/{0}\" dest=\"{1}\" parallel=\"false\">" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"--verbose\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"--classpath={1}\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-O2\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-c\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-fassume-compiled\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-march=pentium4\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-mfpmath=sse\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <srcfile/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <targetfile/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <fileset dir=\"{1}\" includes=\"**/*.java\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <mapper type=\"glob\" from=\"*.java\" to=\"*.o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"        </apply>" + LINE_SEPARATOR + LINE_SEPARATOR; //$NON-NLS-1$
+	private static final String FOOTER =
+		"        <echo message=\"linking .o -> $'{'binaryname'}'\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"        <apply failonerror=\"true\" executable=\"$'{'gcc-path'}'/bin/{0}\" parallel=\"true\">" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"--verbose\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg line =\"-o $'{'dest'}'/$'{'binaryname'}'\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-fassume-compiled\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-march=pentium4\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-mfpmath=sse\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg line=\"--main=org.eclipse.jdt.internal.compiler.batch.Main\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <fileset dir=\"{1}\" includes=\"**/*.o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"       </apply>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"    </target>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"</project>" + LINE_SEPARATOR; //$NON-NLS-1$
+
+	private static void collectAllFiles(File root, ArrayList collector, FileFilter fileFilter) {
+		File[] files = root.listFiles(fileFilter);
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isDirectory()) {
+				collectAllFiles(files[i], collector, fileFilter);
+			} else {
+				String newElement = files[i].getAbsolutePath();
+				newElement = newElement.replace('\\', '/');
+				collector.add(newElement);
+			}
+		}
+	}
+
+	private static void dumpAllProperties(Writer writer, File sourceDir, ArrayList collector, String gcj_exe, String dest_dir) throws IOException {
+		writer.write("        <echo message=\"compiling resources   -> .o\"/>" + LINE_SEPARATOR); //$NON-NLS-1$
+		for (int i = 0, max = collector.size(); i < max; i++) {
+			String absolutePath = (String) collector.get(i);
+			String fileName = absolutePath.substring(sourceDir.getAbsolutePath().length() + 1); 
+			writer.write(MessageFormat.format("  		<exec dir=\"{1}\" executable=\"$'{'gcc-path'}'/bin/{0}\">" + LINE_SEPARATOR, new Object[] { gcj_exe, dest_dir})); //$NON-NLS-1$
+			writer.write("  		<arg line=\"--resource "); //$NON-NLS-1$
+			writer.write(fileName + " " + fileName + " -c -o " + getObjectName(fileName) + "\"/>" + LINE_SEPARATOR); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+			writer.write("  		</exec>" + LINE_SEPARATOR); //$NON-NLS-1$
+		}
+	}
+
+	private static void dumpAllClassFiles(Writer writer, File sourceDir, ArrayList collector, String gcj_exe, String dest_dir) throws IOException {
+		writer.write("        <echo message=\"compiling class files   -> .o\"/>" + LINE_SEPARATOR); //$NON-NLS-1$
+		writer.write(
+				MessageFormat.format(
+		"        <apply failonerror=\"true\" executable=\"$'{'gcc-path'}'/bin/{0}\" dest=\"{1}\" parallel=\"false\">" + LINE_SEPARATOR + //$NON-NLS-1$
+		"  			 <arg value=\"--verbose\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"--classpath={1}\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-O2\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-c\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-fassume-compiled\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-march=pentium4\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-mfpmath=sse\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <srcfile/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <arg value=\"-o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <targetfile/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <fileset dir=\"{1}\" includes=\"**/*.class\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"            <mapper type=\"glob\" from=\"*.class\" to=\"*.o\"/>" + LINE_SEPARATOR + //$NON-NLS-1$
+		"        </apply>" + LINE_SEPARATOR + LINE_SEPARATOR,//$NON-NLS-1$
+		new Object[] {
+				gcj_exe,
+				dest_dir
+		}));
+	}
+
+	private static String getObjectName(String fileName) {
+		return fileName.substring(0, fileName.lastIndexOf('.')) + ".o"; //$NON-NLS-1$
+	}
+			
+	public static void main(String[] args) {
+		if (args.length != 5) {
+			System.out.println("Usage: script_name directory gcj_exe_name dest_dir source/bin"); //$NON-NLS-1$
+			return;
+		}
+		try {
+			BufferedWriter writer = new BufferedWriter(new FileWriter(new File(args[0])));
+			writer.write(HEADER);
+			File sourceDir = new File(args[1]);
+			if (sourceDir.exists()) { 
+				ArrayList collector = new ArrayList();
+				collectAllFiles(sourceDir, collector, new FileFilter() {
+					public boolean accept(File pathname) {
+						String fileName = pathname.getAbsolutePath();
+						return pathname.isDirectory() || fileName.endsWith(".rsc") || fileName.endsWith(".properties"); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+				});
+				dumpAllProperties(writer, sourceDir, collector, args[2], args[3]);
+				if ("source".equals(args[4])) { //$NON-NLS-1$
+					writer.write(MessageFormat.format(SOURCE_FILES, new Object[] {args[2], args[3]}));
+				} else {
+					collector = new ArrayList();
+					collectAllFiles(sourceDir, collector, new FileFilter() {
+						public boolean accept(File pathname) {
+							String fileName = pathname.getAbsolutePath();
+							return pathname.isDirectory() || fileName.endsWith(".class"); //$NON-NLS-1$
+						}
+					});
+					dumpAllClassFiles(writer, sourceDir, collector, args[2], args[3]);				
+				}
+			}
+			writer.write(MessageFormat.format(FOOTER, new Object[] {args[2], args[3]}));
+			writer.flush();
+			writer.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/scripts/about.html b/org.eclipse.jdt.core/scripts/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 2, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/antadapter/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/antadapter/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9c26db8
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/antadapter/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jdt.core.ant.compiler.adapter;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-ClassPath: bogus
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Import-Package: org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.internal.antadapter,
+ org.eclipse.jdt.internal.compiler.batch,
+ org.eclipse.jdt.internal.compiler.impl,
+ org.eclipse.jdt.internal.compiler.util
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.core/scripts/antadapter/plugin.properties b/org.eclipse.jdt.core/scripts/antadapter/plugin.properties
new file mode 100644
index 0000000..c474505
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/antadapter/plugin.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2010 EclipseSource Inc. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     EclipseSource Inc. - initial API and implementation
+###############################################################################
+
+providerName=Eclipse.org
+pluginName=JDT ECJ Ant Compiler Adapter
diff --git a/org.eclipse.jdt.core/scripts/antadapter/plugin.xml b/org.eclipse.jdt.core/scripts/antadapter/plugin.xml
new file mode 100644
index 0000000..acbb711
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/antadapter/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<!--
+    Copyright (c) 2010 EclipseSource Inc. and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+    Contributors:
+      EclipseSource Inc. - initial API and implementation
+ -->
+<plugin>
+<extension 
+	point="org.eclipse.ant.core.extraClasspathEntries">
+	<extraClasspathEntry
+		library="/">
+	</extraClasspathEntry>
+</extension> 
+</plugin>
diff --git a/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..aa7b923
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/binary/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-ManifestVersion: 2
+Bundle-Name: Eclipse Compiler for Java(TM)
+Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch
+Bundle-Version: 3.9.0.qualifier
+Bundle-ClassPath: .
+Bundle-Vendor: Eclipse.org
+Export-Package: org.eclipse.jdt.core,
+ org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.internal.antadapter;x-internal:=true,
+ org.eclipse.jdt.internal.compiler;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.apt.dispatch;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.apt.model;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.apt.util;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.ast;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.batch;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.classfmt;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.codegen;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.env;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.flow;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.impl;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.lookup;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.parser;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.parser.diagnose;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.problem;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.util;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.tool;x-internal:=true
diff --git a/org.eclipse.jdt.core/scripts/build.xml b/org.eclipse.jdt.core/scripts/build.xml
new file mode 100644
index 0000000..e772a07
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/build.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2012 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir=".">
+
+	<property name="output" value="bin" />
+	<property name="jar_file" value="ecj.jar" />
+
+	<target name="build">
+		<delete file="${basedir}/${jar_file}" failonerror="no" />
+		<delete dir="${output}" failonerror="no" />
+		<mkdir dir="${output}" />
+
+		<javac srcdir="${basedir}" destdir="${output}"
+				debuglevel="lines,source"
+				source="1.3"
+				target="1.2"
+			excludes="org/eclipse/jdt/internal/compiler/tool/*,**/apt/**">
+			<compilerarg line="-Xlint:none"/>
+		</javac>
+
+		<javac destdir="${output}"
+				debuglevel="lines,source"
+				source="1.6"
+				target="1.6"
+				includes="org/eclipse/jdt/internal/compiler/tool/*">
+			<src path="${basedir}"/>
+			<include name="org/eclipse/jdt/internal/compiler/tool/*"/>
+			<include name="**/apt/**"/>
+			<compilerarg line="-Xlint:none"/>
+		</javac>
+
+		<delete file="${basedir}/META-INF/MANIFEST.MF" failonerror="false"/>
+		<copy tofile="${basedir}/META-INF/MANIFEST.MF" file="${basedir}/scripts/binary/META-INF/MANIFEST.MF"/>
+		<zip destfile="${basedir}/${jar_file}">
+			<fileset dir="${output}" />
+			<fileset dir="${basedir}">
+				<include name="about.html"/>
+				<include name="**/*.rsc"/>
+				<include name="**/readableNames.props"/>
+				<include name="META-INF/**"/>
+				<include name="**/*.properties"/>
+				<exclude name="META-INF/eclipse.inf"/>
+			</fileset>
+		</zip>
+		<delete dir="${output}" />
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/build_ecj.xml b/org.eclipse.jdt.core/scripts/build_ecj.xml
new file mode 100644
index 0000000..20807dc
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/build_ecj.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2011 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir=".">
+
+	<property name="version" value="3.1.0" />
+	<property name="gcc-path" value="C:/java_tools/thisiscool-gcc/gcc-4.0" />
+	<property name="binaryname" value="ejavac${version}" />
+	<property name="dest" value="c:/temp/bingcj" />
+	<property name="extract_folder" value="${dest}/src/" />
+	<property name="work" value="${dest}/tmp/" />
+	<property name="source" value="C:/eclipse/I1111/eclipse/plugins/org.eclipse.jdt.source_3.1.0/src/org.eclipse.jdt.core_3.1.0/jdtcoresrc.zip" />
+	<property name="binaries" value="C:/eclipse/I1111/eclipse/plugins/org.eclipse.jdt.core_3.1.0/jdtcore.jar" />
+	<property name="gcj_script_name" value="export-executable.xml" />
+
+	<target name="build">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no" />
+		<mkdir dir="${dest}" />
+
+		<unzip overwrite="yes" dest="${work}" src="${source}">
+			<patternset>
+				<include name="**/compiler/**" />
+				<exclude name="**/compiler/**/*.html" />
+				<exclude name="**/IScanner.java" />
+				<exclude name="**/ITerminalSymbols.java" />
+				<exclude name="**/DocumentElementParser.java" />
+				<exclude name="**/IDocumentElementRequestor.java" />
+				<exclude name="**/ISourceElementRequestor.java" />
+				<exclude name="**/SourceElementParser.java" />
+				<exclude name="**/SourceElementRequestorAdapter.java" />
+				<exclude name="**/SourceConstructorDeclaration.java" />
+				<exclude name="**/SourceFieldDeclaration.java" />
+				<exclude name="**/SourceMethodDeclaration.java" />
+				<exclude name="**/SourceTypeConverter.java" />
+			</patternset>
+		</unzip>
+
+		<unzip overwrite="yes" dest="${work}" src="${binaries}">
+			<patternset>
+				<include name="**/compiler/**/*.properties" />
+				<include name="**/*.rsc" />
+				<exclude name="**/*.class" />
+				<exclude name="**/*.mf" />
+			</patternset>
+		</unzip>
+
+		<!-- echo message="generate build script" />
+		<java classname="GenerateBuildScript">
+			<sysproperty key="user.dir" value="${basedir}/scripts"/>
+			<arg value="${gcj_script_name}"/>
+			<arg value="${basedir}/${work}"/>
+			<classpath>
+				<pathelement path="${basedir}/scripts"/>
+			</classpath>
+		</java>
+		
+		<echo message="run the new build script" />
+		<ant antfile="${basedir}/scripts/export-executable.xml"/>
+		<delete file="${basedir}/scripts/export-executable.xml"/ -->
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/export-ecj.xml b/org.eclipse.jdt.core/scripts/export-ecj.xml
new file mode 100644
index 0000000..75ae978
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/export-ecj.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2007, 2012 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<!-- build script to create a batch compiler from org.eclipse.jdt.core -->
+<project name="Eclipse Batch Compiler" default="export-all" basedir="..">
+	<target name="init">
+		<tstamp/>
+		<property name="bundleVersion" value="3.9.0.qualifier"/>
+		<fail unless="bundleVersion" message="Property 'bundleVersion' must be provided by caller"/>
+		<condition property="bundleVersionOK">
+			<matches pattern="\d\.\d\.\d.*" string="${bundleVersion}"/>
+		</condition>
+		<fail message="bundleVersion variable had unexpected format. Should be digit.digit.digit,ANY but was ${bundleVersion}" unless="bundleVersionOK"/>
+		<script language="javascript">
+			var bundleVersion = project.getProperty("bundleVersion");
+			var pattern = new RegExp(/^(\d+)\.(\d+)\.(\d+)\.(.*)$/);
+			var sArray = pattern.exec(bundleVersion); // sArray 0 is "whole match"
+			project.setProperty("bundleVersionMajor", sArray[1]);
+			project.setProperty("bundleVersionMinor", sArray[2]);
+			project.setProperty("bundleVersionService", sArray[3]);
+			project.setProperty("bundleVersionQualifer", sArray[4])
+		</script>
+		<property name="ecj-temp-folder" value="${basedir}/ecj-temp-folder" />
+		<property name="ecj-temp-src-folder" value="${basedir}/ecj-temp-src-folder" />
+		<mkdir dir="${ecj-temp-src-folder}" />
+		<mkdir dir="${ecj-temp-folder}"/>
+	</target>
+	
+	<target name="extract-batch-compiler" depends="init">
+		<property name="target.folder" value="${basedir}/bin"/>
+		<replace file="${target.folder}/org/eclipse/jdt/internal/compiler/batch/messages.properties" token="bundle_qualifier" value="${bundleVersionQualifer}"/>
+		<echo message="Extract .class file and properties for the batch compiler" />
+		<copy todir="${ecj-temp-folder}">
+			<fileset dir="${target.folder}">
+				<include name="org/eclipse/jdt/internal/compiler/**"/>
+				<include name="org/eclipse/jdt/core/compiler/**"/>
+				<exclude name="**/package.htm*"/>
+				<exclude name="org/eclipse/jdt/core/compiler/CompilationParticipant*.class"/>
+				<exclude name="org/eclipse/jdt/core/compiler/BuildContext.class"/>
+				<exclude name="org/eclipse/jdt/core/compiler/IScanner.class"/>
+				<exclude name="org/eclipse/jdt/core/compiler/ITerminalSymbols*.class"/>
+				<exclude name="org/eclipse/jdt/core/compiler/ReconcileContext*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/DocumentElementParser*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/ISourceElementRequestor*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/SourceElementParser*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/SourceJavadocParser*.class"/>
+				<exclude name="org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter*.class"/>
+			</fileset>
+		</copy>
+	</target>
+
+	<target name="extract-_jsr199" depends="init">
+		<property name="target.folder" value="${basedir}/../org.eclipse.jdt.compiler.tool/bin"/>
+		<echo message="Extract .class file and properties for the jsr199" />
+		<copy todir="${ecj-temp-folder}" failonerror="false">
+			<fileset dir="${target.folder}"/>
+		</copy>
+	</target>
+	
+	<target name="extract-_jsr269" depends="init">
+		<property name="jsr_project" value="org.eclipse.jdt.compiler.apt"/>
+		<property name="target.folder" value="${basedir}/../org.eclipse.jdt.compiler.apt/bin"/>
+		<echo message="Extract .class file and properties for the jsr269" />
+		<copy todir="${ecj-temp-folder}" failonerror="false">
+			<fileset dir="${target.folder}"/>
+		</copy>
+	</target>
+
+	<target name="extract-ant-adapter-compiler" depends="init">
+		<property name="target.folder" value="${basedir}/antbin"/>
+		<echo message="Extract .class file and properties for the ant adapter" />
+		<mkdir dir="${ecj-temp-folder}"/>
+		<copy todir="${ecj-temp-folder}">
+			<fileset dir="${target.folder}">
+				<exclude name="org/eclipse/jdt/core/CheckDebugAttributes*.*"/>
+				<exclude name="org/eclipse/jdt/core/BuildJarIndex*.*"/>
+			</fileset>
+		</copy>
+	</target>
+
+	<target name="export" depends="init">
+		<property name="buildLabel" value="head" />
+		<property name="dest" value="../../ecj-export" />
+		<mkdir dir="${dest}" />
+		<echo message="UPDATE ecj-${buildLabel}.jar" />
+		<delete file="${dest}/ecj-${buildLabel}.jar" failonerror="false"/>
+		<copy todir="${ecj-temp-folder}">
+			<fileset dir="scripts/binary" />
+		</copy>
+		<replace file="${ecj-temp-folder}/META-INF/MANIFEST.MF" token="qualifier" value="${bundleVersionQualifer}"/>
+		<zip zipfile="${dest}/ecj-${buildLabel}.jar">
+			<fileset dir="${ecj-temp-folder}">
+				<include name="**/*"/>
+			</fileset>
+			<fileset dir="scripts">
+				<include name="about.html" />
+			</fileset>
+		</zip>
+
+		<echo message="UPDATE ecjsrc-${buildLabel}.jar" />
+		<delete file="${dest}/ecjsrc-${buildLabel}.jar" failonerror="false"/>
+		<copy todir="${ecj-temp-src-folder}">
+			<fileset dir="scripts/source" />
+		</copy>
+		<copy todir="${ecj-temp-src-folder}/scripts/binary">
+			<fileset dir="scripts/binary" />
+		</copy>
+		<replace file="${ecj-temp-src-folder}/META-INF/MANIFEST.MF" token="qualifier" value="${bundleVersionQualifer}"/>
+		<replace file="${ecj-temp-src-folder}/scripts/binary/META-INF/MANIFEST.MF" token="qualifier" value="${bundleVersionQualifer}"/>
+		<zip zipfile="${dest}/ecjsrc-${buildLabel}.jar">
+			<zipfileset dir="ecj-temp-src-folder" />
+			<zipfileset dir="batch">
+				<exclude name="org/eclipse/jdt/internal/compiler/batch/messages.properties"/>
+			</zipfileset>
+			<fileset dir="${ecj-temp-folder}">
+				<include name="**/messages.properties"/>
+			</fileset>
+			<zipfileset dir="compiler" />
+			<zipfileset dir="antadapter">
+				<exclude name="org/eclipse/jdt/core/CheckDebugAttributes.java"/>
+				<exclude name="org/eclipse/jdt/core/BuildJarIndex.java"/>
+			</zipfileset>
+			<zipfileset dir="scripts">
+				<include name="about.html" />
+				<include name="build.xml" />
+			</zipfileset>
+		</zip>
+		<antcall target="cleanup"/>
+	</target>
+
+	<target name="export_src_bin">
+		<property name="dest" value="../../ecj-export" />
+		<mkdir dir="${dest}" />
+		<echo message="UPDATE ecj_all.jar" />
+		<delete file="${dest}/ecj_all.jar" failonerror="false"/>
+		<mkdir dir="${ecj-temp-src-folder}/src" />
+		<copy todir="${ecj-temp-folder}">
+			<fileset dir="scripts/binary" />
+		</copy>
+		<replace file="${ecj-temp-folder}/META-INF/MANIFEST.MF" token="qualifier" value="${bundleVersionQualifer}"/>
+
+		<copy todir="${ecj-temp-src-folder}/src">
+			<fileset dir="batch" />
+			<fileset dir="compiler" />
+			<fileset dir="antadapter">
+				<exclude name="org/eclipse/jdt/core/CheckDebugAttributes.java"/>
+				<exclude name="org/eclipse/jdt/core/BuildJarIndex.java"/>
+			</fileset>
+		</copy>
+
+		<zip zipfile="${dest}/ecj_all.jar">
+			<fileset dir="${ecj-temp-folder}">
+				<include name="**/*"/>
+				<include name="about.html"/>
+			</fileset>
+			<fileset dir="${ecj-temp-src-folder}">
+				<exclude name="META-INF/**"/>
+			</fileset>
+			<fileset dir="scripts">
+				<include name="about.html" />
+			</fileset>
+		</zip>
+
+		<delete dir="${ecj-temp-src-folder}" failonerror="false"/>
+	</target>
+
+	<target name="cleanup">
+		<delete dir="${ecj-temp-folder}" failonerror="false"/>
+		<delete dir="${ecj-temp-src-folder}" failonerror="false"/>
+	</target>
+
+	<target name="export-all" depends="init">
+		<antcall target="extract-batch-compiler"/>
+		<antcall target="extract-ant-adapter-compiler"/>
+		<antcall target="extract-_jsr199"/>
+		<antcall target="extract-_jsr269"/>
+		<antcall target="export_src_bin"/>
+		<antcall target="export"/>
+		<antcall target="cleanup"/>
+	</target>
+</project>
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac.xml b/org.eclipse.jdt.core/scripts/export-ejavac.xml
new file mode 100644
index 0000000..22e0ccc
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/export-ejavac.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir="..">
+
+	<property name="version" value="32M4SM" />
+	<property name="gcc-path" value="/oliviert/gcj4.0.3/xgcc" />
+	<property name="binaryname" value="ejavac${version}.exe" />
+	<property name="dest" value="../../bingcj" />
+	<property name="work" value="${dest}/tmp/" />
+	<property name="source" value="/oliviert/workspaces/head/org.eclipse.jdt.core" />
+	<property name="gcj_script_name" value="export-executable.xml"/>
+
+    <target name="build">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no"/>
+		<mkdir dir="${dest}" />
+	
+		<copy todir="${work}">
+		    <fileset dir="${source}/batch/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${work}">
+		    <fileset dir="${source}/compiler/" excludes='**/*.html' />
+		</copy>
+	
+		<echo message="generate build script" />
+		<java classname="GenerateBuildScript">
+			<arg value="${basedir}/scripts/${gcj_script_name}"/>
+			<arg value="${basedir}/${work}"/>
+			<arg value="i686-pc-mingw32-gcj"/>
+			<arg value="${basedir}/${work}"/>
+			<arg value="source"/>			
+			<classpath>
+				<pathelement path="${basedir}/scripts"/>
+			</classpath>
+		</java>
+		
+		<echo message="run the new build script" />
+		<ant antfile="${basedir}/scripts/export-executable.xml"/>
+		<delete file="${basedir}/scripts/export-executable.xml"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac2.xml b/org.eclipse.jdt.core/scripts/export-ejavac2.xml
new file mode 100644
index 0000000..52ce9d8
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/export-ejavac2.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir="..">
+
+	<property name="version" value="32M4" />
+	<property name="gcc-path" value="/oliviert/gcj4.0.3/xgcc" />
+	<property name="binaryname" value="ejc${version}.exe" />
+	<property name="dest" value="../../bingcj" />
+	<property name="work" value="${dest}/tmp/" />
+	<property name="bin" value="${dest}/bin/" />
+	<property name="source" value="/oliviert/workspaces/head/org.eclipse.jdt.core" />
+	<property name="gcj_script_name" value="export-executable.xml"/>
+
+    <target name="build">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no"/>
+		<mkdir dir="${dest}" />
+		<delete dir="${bin}" failonerror="no"/>
+		<mkdir dir="${bin}" />
+	
+		<copy todir="${work}">
+		    <fileset dir="${source}/batch/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${work}">
+		    <fileset dir="${source}/compiler/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/batch/" includes='**/*.properties' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/compiler/" includes='**/*.properties' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/compiler/" includes='**/*.rsc' />
+		</copy>
+   
+		<javac srcdir="${work}"
+			destdir="${bin}"
+			nowarn="on"
+			deprecation="off"
+			source="1.3"
+			debug="on"
+			verbose="off"
+			target="1.2">
+		    <compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="-1.4 -inlineJSR"/>
+		</javac>
+	
+		<echo message="generate build script" />
+		<java classname="GenerateBuildScript">
+			<arg value="${basedir}/scripts/${gcj_script_name}"/>
+			<arg value="${basedir}/${bin}"/>
+			<arg value="i686-pc-mingw32-gcj"/>
+			<arg value="${basedir}/${bin}"/>
+			<arg value="bin"/>
+			<classpath>
+				<pathelement path="${basedir}/scripts"/>
+			</classpath>
+		</java>
+		
+		<echo message="run the new build script" />
+		<ant antfile="${basedir}/scripts/export-executable.xml"/>
+		<delete file="${basedir}/scripts/export-executable.xml"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac2_linux.xml b/org.eclipse.jdt.core/scripts/export-ejavac2_linux.xml
new file mode 100644
index 0000000..91f931d
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/export-ejavac2_linux.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir="..">
+
+	<property name="version" value="32M4" />
+	<property name="gcc-path" value="/oliviert/gcj4.1_linux/gcc" />
+	<property name="binaryname" value="ejc${version}" />
+	<property name="dest" value="../../bingcj" />
+	<property name="work" value="${dest}/tmp/" />
+	<property name="bin" value="${dest}/bin/" />
+	<property name="source" value="/oliviert/workspaces/head/org.eclipse.jdt.core" />
+	<property name="gcj_script_name" value="export-executable.xml"/>
+
+    <target name="build">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no"/>
+		<mkdir dir="${dest}" />
+		<delete dir="${bin}" failonerror="no"/>
+		<mkdir dir="${bin}" />
+	
+		<copy todir="${work}">
+		    <fileset dir="${source}/batch/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${work}">
+		    <fileset dir="${source}/compiler/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/batch/" includes='**/*.properties' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/compiler/" includes='**/*.properties' />
+		</copy>
+		<copy todir="${bin}">
+		    <fileset dir="${source}/compiler/" includes='**/*.rsc' />
+		</copy>
+   
+		<javac srcdir="${work}"
+			destdir="${bin}"
+			nowarn="on"
+			deprecation="off"
+			source="1.3"
+			debug="on"
+			verbose="off"
+			target="1.2">
+		    <compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="-1.4 -inlineJSR"/>
+		</javac>
+	
+		<echo message="generate build script" />
+		<java classname="GenerateBuildScript">
+			<arg value="${basedir}/scripts/${gcj_script_name}"/>
+			<arg value="${basedir}/${bin}"/>
+			<arg value="i686-pc-linux-gnu-gcj"/>
+			<arg value="${basedir}/${bin}"/>
+			<arg value="bin"/>
+			<classpath>
+				<pathelement path="${basedir}/scripts"/>
+			</classpath>
+		</java>
+		
+		<echo message="run the new build script" />
+		<ant antfile="${basedir}/scripts/export-executable.xml"/>
+		<delete file="${basedir}/scripts/export-executable.xml"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac_linux.xml b/org.eclipse.jdt.core/scripts/export-ejavac_linux.xml
new file mode 100755
index 0000000..3e2cbbc
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/export-ejavac_linux.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="export-executable" default="build" basedir="..">
+
+	<property name="version" value="v632linux" />
+	<property name="gcc-path" value="/oliviert/gcj4.1_linux/gcc" />
+	<property name="binaryname" value="ejc${version}" />
+	<property name="dest" value="../../bingcj" />
+	<property name="work" value="${dest}/tmp/" />
+	<property name="source" value="/oliviert/workspaces/head/org.eclipse.jdt.core" />
+	<property name="gcj_script_name" value="export-executable.xml"/>
+
+    <target name="build">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no"/>
+		<mkdir dir="${dest}" />
+	
+		<copy todir="${work}">
+		    <fileset dir="${source}/batch/" excludes='**/*.html' />
+		</copy>
+		<copy todir="${work}">
+		    <fileset dir="${source}/compiler/" excludes='**/*.html' />
+		</copy>
+	
+		<echo message="generate build script" />
+		<java classname="GenerateBuildScript">
+			<arg value="${basedir}/scripts/${gcj_script_name}"/>
+			<arg value="${basedir}/${work}"/>
+			<arg value="i686-pc-linux-gnu-gcj"/>
+			<arg value="${basedir}/${work}"/>
+			<arg value="source"/>			
+			<classpath>
+				<pathelement path="${basedir}/scripts"/>
+			</classpath>
+		</java>
+		
+		<echo message="run the new build script" />
+		<ant antfile="${basedir}/scripts/export-executable.xml"/>
+		<delete file="${basedir}/scripts/export-executable.xml"/>
+	</target>
+</project>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/exportplugin.xml b/org.eclipse.jdt.core/scripts/exportplugin.xml
new file mode 100644
index 0000000..0caf4af
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/exportplugin.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2007, 2012 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<!-- build script to create a plugin from ${plugin} -->
+<project name="${plugin}" default="export plug-in [_3.8.1]" basedir="..">
+<target name="export plug-in [_3.8.1]">
+    <tstamp/>
+	<property name="qualifier" value="z${DSTAMP}-${TSTAMP}" />
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.8.1"/>
+	</antcall>
+</target>
+<target name="export plug-in [_3.8.1.qualifier] (binary only)">
+    <tstamp/>
+	<property name="qualifier" value="z${DSTAMP}-${TSTAMP}" />
+	<antcall target="zz_internal_export_binary_only">
+		<param name="jdt_core_version" value="3.8.1.${qualifier}"/>
+	</antcall>
+</target>
+<target name="export plug-in [_3.8.1.qualifier] (with sources)">
+    <tstamp/>
+	<property name="qualifier" value="z${DSTAMP}-${TSTAMP}" />
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.8.1.${qualifier}"/>
+	</antcall>
+</target>
+
+<target name="zz_internal_export">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="plugin-dir" value="${export-dir}/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${plugin-dir}" />
+	<mkdir dir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+  	<jar 
+		jarfile="${plugin-dir}/jdtCompilerAdapter.jar"
+		basedir="antbin"/>
+
+	<echo message="UPDATE ${plugin}_${jdt_core_version}.jar" />
+	<copy todir="${plugin-dir}/META-INF">
+		<fileset dir="META-INF" />
+	</copy>  
+	<replaceregexp file="${plugin-dir}/META-INF/MANIFEST.MF" match="Bundle-Version: ((\d)+\.(\d)+\.(\d)+\.)qualifier" replace="Bundle-Version: \1${qualifier}" byline="true" />
+	<zip zipfile="${plugin-dir}/${plugin}_${jdt_core_version}.jar">
+		<fileset dir=".">
+		  <include name="plugin.xml" />
+		  <include name="plugin.properties" />
+	      <include name=".options"/>
+          <include name="about.html"/>
+        </fileset>
+		<fileset dir="${plugin-dir}">
+			<include name="META-INF/**" />
+		</fileset>
+        <fileset dir="bin" />
+        <fileset file="${plugin-dir}/jdtCompilerAdapter.jar"/>
+        <zipfileset dir="batch" prefix="src"/>
+	    <zipfileset dir="codeassist" prefix="src"/>
+	    <zipfileset dir="compiler" prefix="src"/>
+	    <zipfileset dir="dom" prefix="src"/>
+	    <zipfileset dir="eval" prefix="src"/>
+	    <zipfileset dir="formatter" prefix="src"/>
+	    <zipfileset dir="model" prefix="src"/>
+	    <zipfileset dir="search" prefix="src"/>
+	</zip>
+	<delete dir="${plugin-dir}/META-INF" />
+
+	<delete file="${plugin-dir}/jdtCompilerAdapter.jar"/>
+
+	<echo message="UPDATE ${export-dir}/../${plugin}_${jdt_core_version}.zip" />
+	<zip zipfile="${export-dir}/../${plugin}_${jdt_core_version}.zip"
+	    basedir="${export-dir}" 
+	    includes="${plugin}_${jdt_core_version}/**"	/>		
+	<!--
+		<delete dir="${plugin-dir}" />
+	-->
+</target>
+
+<target name="zz_internal_export_binary_only">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="plugin-dir" value="${export-dir}/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${plugin-dir}" />
+	<mkdir dir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+  	<jar 
+		jarfile="${plugin-dir}/jdtCompilerAdapter.jar"
+		basedir="antbin"/>
+
+	<echo message="UPDATE ${plugin}_${jdt_core_version}.jar" />
+	<copy todir="${plugin-dir}/META-INF">
+		<fileset dir="META-INF" />
+	</copy>  
+	<replaceregexp file="${plugin-dir}/META-INF/MANIFEST.MF" match="Bundle-Version: ((\d)+\.(\d)+\.(\d)+\.)qualifier" replace="Bundle-Version: \1${qualifier}" byline="true" />
+	<zip zipfile="${plugin-dir}/${plugin}_${jdt_core_version}.jar">
+		<fileset dir=".">
+		  <include name="plugin.xml" />
+		  <include name="plugin.properties" />
+	      <include name=".options"/>
+          <include name="about.html"/>
+        </fileset>
+		<fileset dir="${plugin-dir}">
+			<include name="META-INF/**" />
+		</fileset>
+        <fileset dir="bin" />
+        <fileset file="${plugin-dir}/jdtCompilerAdapter.jar"/>
+	</zip>
+	<delete dir="${plugin-dir}/META-INF" />
+
+	<delete file="${plugin-dir}/jdtCompilerAdapter.jar"/>
+
+	<echo message="UPDATE ${export-dir}/../${plugin}_${jdt_core_version}.zip" />
+	<zip zipfile="${export-dir}/../${plugin}_${jdt_core_version}.zip"
+	    basedir="${export-dir}" 
+	    includes="${plugin}_${jdt_core_version}/**"	/>
+	<!--
+		<delete dir="${plugin-dir}" />
+	-->
+</target>
+
+</project>
diff --git a/org.eclipse.jdt.core/scripts/ikvm_script.xml b/org.eclipse.jdt.core/scripts/ikvm_script.xml
new file mode 100644
index 0000000..922bb32
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/ikvm_script.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<project name="ecj" default="all" basedir="..">
+	<!-- target name="checkout">
+     <exec program="cvs" commandline="-z3 -d:pserver:anonymous@dev.eclipse.org:/home/eclipse co org.eclipse.jdt.core" />
+   </target>
+   <target name="allsources">
+     <exec program="cmd" commandline="/c dir /s/b org.eclipse.jdt.core\batch\*.java > allsources.lst" />
+     <exec program="cmd" commandline="/c dir /s/b org.eclipse.jdt.core\compiler\*.java >> allsources.lst" />
+   </target>
+   <target name="classes">
+     <exec program="../bin/ikvmstub.exe" commandline="IKVM.GNU.Classpath" useruntimeengine="true" />
+     <exec program="jikes" commandline="-nowarn -classpath IKVM.GNU.Classpath.jar;org.eclipse.jdt.core/compiler;org.eclipse.jdt.core/batch @allsources.lst" />
+     <delete file="IKVM.GNU.Classpath.jar" />
+   </target -->
+	<property name="ikvm_home" value="D:\java_tools\ikvm" />
+	<property name="dest" value="../../bingcj" />
+	<property name="work" value="${dest}/tmp" />
+	<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	<property name="source" value="D:/eclipse/workspaces/head/org.eclipse.jdt.core" />
+
+    <target name="clean">
+		<echo message="target: ${dest}" />
+		<delete dir="${dest}" failonerror="no"/>
+		<mkdir dir="${dest}" />
+	</target>	
+
+	<target name="retrieve_class_files">
+		<copy todir="${work}">
+		    <fileset dir="${source}/batch/" includes='**/*.java' />
+		</copy>
+		<copy todir="${work}">
+		    <fileset dir="${source}/compiler/" includes='**/*.java' />
+		</copy>
+
+		<echo message="copy resource files"/>
+		<copy todir="${dest}">
+		    <fileset dir="${source}/compiler/" includes='**/*.rsc' />
+		</copy>
+
+		<echo message="copy properties files from compiler"/>
+		<copy todir="${dest}">
+		    <fileset dir="${source}/compiler/" includes='**/*.properties' />
+		    <fileset dir="${source}/batch/" includes='**/*.properties' />
+		</copy>
+
+		<javac srcdir="${work}" destdir="${dest}" nowarn="off" deprecation="off" source="1.4" debug="off" verbose="on">
+			<classpath>
+				<path location="${work}"/>
+			</classpath>
+		</javac>
+
+		<delete dir="${work}" failonerror="no"/>
+	</target>
+
+	<target name="ecj">
+		<exec dir="${dest}" executable="${ikvm_home}/bin/ikvmc.exe" output="${dest}/log.txt">
+			<arg line="-out:ecj.exe -main:org.eclipse.jdt.internal.compiler.batch.Main -recurse:./*.class -recurse:./*.properties -recurse:./*.rsc"/>
+		</exec>
+		<copy file="${ikvm_home}/bin/IKVM.Runtime.dll" todir="${dest}" />
+		<copy file="${ikvm_home}/bin/IKVM.GNU.Classpath.dll" todir="${dest}" />
+	</target>
+
+	<target name="all" depends="clean, retrieve_class_files, ecj">
+	</target>
+</project>
diff --git a/org.eclipse.jdt.core/scripts/oldexportplugin.xml b/org.eclipse.jdt.core/scripts/oldexportplugin.xml
new file mode 100644
index 0000000..79fe67d
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/oldexportplugin.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+    Copyright (c) 2007, 2009 IBM Corporation and others.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+    
+    Contributors:
+        IBM Corporation - initial API and implementation
+ -->
+
+<!-- build script to create a plugin from ${plugin} -->
+<project name="${plugin}" default="export plug-in [_3.1.0]" basedir="..">
+
+<target name="export plug-in [_3.1.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_3.0.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.0.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.1]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.1.1"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.0] (directory structure)">
+	<antcall target="zz_internal_export_structure">
+		<param name="jdt_core_version" value="2.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.0.1]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.0.1"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.0.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.0.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_1.9.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="1.9.0"/>
+	</antcall>
+</target>
+
+<target name="zz_internal_export">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="plugin-dir" value="${export-dir}/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${plugin-dir}" />
+	<mkdir dir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtcore.jar" />
+	<jar 
+		jarfile="${plugin-dir}/jdtcore.jar"
+		basedir="bin"
+		manifest="META-INF/MANIFEST.MF"/>
+		
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+	<jar 
+		jarfile="${plugin-dir}/jdtCompilerAdapter.jar"
+		basedir="antbin"/>
+
+	<echo message="UPDATE plugin.xml" />
+	<copy file="plugin.xml" todir="${plugin-dir}" />
+	<echo message="UPDATE plugin.properties" />
+	<copy file="plugin.properties" todir="${plugin-dir}" />
+
+	<echo message="UPDATE .options" />
+	<copy file=".options" todir="${plugin-dir}" />
+
+	<echo message="UPDATE about.html" />
+	<copy file="about.html" todir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtcoresrc.zip" />
+	<zip zipfile="${plugin-dir}/jdtcoresrc.zip">
+	    <fileset dir="batch" />
+	    <fileset dir="codeassist" />
+	    <fileset dir="compiler" />
+	    <fileset dir="dom" />
+	    <fileset dir="eval" />
+	    <fileset dir="formatter" />
+	    <fileset dir="model" />
+	    <fileset dir="search" />
+	</zip>		
+
+	<echo message="UPDATE jdtCompilerAdaptersrc.zip" />
+	<zip zipfile="${plugin-dir}/jdtCompilerAdaptersrc.zip">
+		<fileset dir="antadapter" />
+	</zip>	    
+
+	<echo message="UPDATE ${export-dir}/../${plugin}_${jdt_core_version}.zip" />
+	<zip zipfile="${export-dir}/../${plugin}_${jdt_core_version}.zip"
+	    basedir="${export-dir}" 
+	    includes="${plugin}_${jdt_core_version}/**"	/>		
+</target>
+
+<target name="zz_internal_export_structure">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="bin_dest" value="${export-dir}/eclipse/plugins/${plugin}_${jdt_core_version}"/>
+	<property name="src_dest" value="${export-dir}/eclipse/plugins/org.eclipse.jdt.source_${jdt_core_version}/src/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${bin_dest}" />
+	<delete dir="${src_dest}" />
+	<mkdir dir="${bin_dest}" />
+	<mkdir dir="${src_dest}" />
+
+	<echo message="UPDATE jdtcore.jar" />
+	<jar 
+		jarfile="${bin_dest}/jdtcore.jar"
+		basedir="bin" 
+		excludes="**/JDTCompilerAdapter.class,**/antadapter/*"/>
+		
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+	<jar 
+		jarfile="${bin_dest}/jdtCompilerAdapter.jar"
+		basedir="bin" 
+		includes="**/JDTCompilerAdapter.class,**/antadapter/*"/>
+
+	<echo message="UPDATE plugin.xml" />
+	<copy file="plugin.xml" todir="${bin_dest}" />
+	<echo message="UPDATE plugin.properties" />
+	<copy file="plugin.properties" todir="${bin_dest}" />
+
+	<echo message="UPDATE .options" />
+	<copy file=".options" todir="${bin_dest}" />
+
+	<echo message="UPDATE about.html" />
+	<copy file="about.html" todir="${bin_dest}" />
+
+	<echo message="UPDATE jdtcoresrc.zip" />
+	<zip zipfile="${src_dest}/jdtcoresrc.zip">
+	    <fileset dir="batch" />
+	    <fileset dir="codeassist" />
+	    <fileset dir="compiler" />
+	    <fileset dir="dom" />
+	    <fileset dir="eval" />
+	    <fileset dir="formatter" />
+	    <fileset dir="model" />
+	    <fileset dir="search" />
+	</zip>		
+</target>
+
+</project>
diff --git a/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..b8a4601
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/source/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Source of Eclipse Compiler for Java(TM)
+Bundle-SymbolicName: org.eclipse.jdt.core.compiler.batch.source
+Bundle-Version: 3.9.0.qualifier
+Bundle-Vendor: Eclipse.org
+Eclipse-SourceBundle: org.eclipse.jdt.core.compiler.batch;version="3.9.0.qualifier";roots:="."
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java
new file mode 100644
index 0000000..4fa991a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexer.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.index;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.internal.core.search.indexing.DefaultJavaIndexer;
+
+/**
+ * {@link JavaIndexer} provides functionality to generate index files which can be used by the JDT {@link SearchEngine}.
+ * The generated index files can be used as a classpath attribute for the particular classpath entry.
+ * 
+ * <p> The search engine indexes all the elements referred in the classpath entries of the project into
+ * index files. These index files are used to search the elements faster. Indexing for bigger jars could
+ * take some time. To avoid this time, one can generate the index file and specify it when the jar is added
+ * to the classpath of the project. </p>
+ *
+ * @since 3.8
+ */
+public final class JavaIndexer {
+
+	/**
+	 * Generates the index file for the specified jar.
+	 * @param pathToJar The full path to the jar that needs to be indexed
+	 * @param pathToIndexFile The full path to the index file that needs to be generated
+	 * @throws IOException if the jar is not found or could not write into the index file
+	 * @since 3.8
+	 */
+	public static void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException {
+		new DefaultJavaIndexer().generateIndexForJar(pathToJar, pathToIndexFile);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java
new file mode 100644
index 0000000..7aae18a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/JavaIndexerApplication.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ *  Copyright (c) 2011 IBM Corporation and others.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ * 
+ *  Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Implements an Eclipse Application for {@link org.eclipse.jdt.core.index.JavaIndexer}.
+ * 
+ * <p>
+ * On MacOS, when invoked using the Eclipse executable, the "user.dir" property is set to the folder in which the
+ * eclipse.ini file is located. This makes it harder to use relative paths to point to the files to be jar'd or to
+ * the index file that is generated.
+ * </p>
+ * 
+ * 
+ * @since 3.8
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class JavaIndexerApplication implements IApplication {
+
+	private final static class Messages extends NLS {
+		private static final String MESSAGES_NAME = "org.eclipse.jdt.core.index.messages";//$NON-NLS-1$
+
+		public static String CommandLineProcessing;
+		public static String CommandLineUsage;
+		public static String CommandLineOnlyOneOutputError;
+		public static String CommandLineOutputTakesArgs;
+		public static String CommandLineOnlyOneJarError;
+		public static String CommandLineJarNotSpecified;
+		public static String CommandLineIndexFileNotSpecified;
+		public static String CaughtException;
+		public static String CommandLineJarFileNotExist;
+
+		static {
+			NLS.initializeMessages(MESSAGES_NAME, Messages.class);
+		}
+
+		public static String bind(String message) {
+			return bind(message, null);
+		}
+
+		public static String bind(String message, Object binding) {
+			return bind(message, new Object[] { binding });
+		}
+
+		public static String bind(String message, Object binding1, Object binding2) {
+			return bind(message, new Object[] { binding1, binding2 });
+		}
+
+		public static String bind(String message, Object[] bindings) {
+			return MessageFormat.format(message, bindings);
+		}
+	}
+
+	private String jarToIndex;
+	private String indexFile;
+	private boolean verbose = false;
+	private static final String PDE_LAUNCH = "-pdelaunch"; //$NON-NLS-1$
+	private static final String ARG_HELP = "-help"; //$NON-NLS-1$
+	private static final String ARG_VERBOSE = "-verbose"; //$NON-NLS-1$
+	private static final String ARG_OUTPUT = "-output"; //$NON-NLS-1$
+
+	private void displayHelp() {
+		System.out.println(Messages.bind(Messages.CommandLineUsage));
+	}
+
+	private void displayError(String message) {
+		System.out.println(message);
+		System.out.println();
+		displayHelp();
+	}
+
+	private boolean processCommandLine(String[] argsArray) {
+		ArrayList args = new ArrayList();
+		for (int i = 0, max = argsArray.length; i < max; i++) {
+			args.add(argsArray[i]);
+		}
+		int index = 0;
+		final int argCount = argsArray.length;
+
+		loop: while (index < argCount) {
+			String currentArg = argsArray[index++];
+			if (PDE_LAUNCH.equals(currentArg)) {
+				continue loop;
+			} else if (ARG_HELP.equals(currentArg)) {
+				displayHelp();
+				return false;
+			} else if (ARG_VERBOSE.equals(currentArg)) {
+				this.verbose = true;
+				continue loop;
+			} else if (ARG_OUTPUT.equals(currentArg)) {
+				if (this.indexFile != null) {
+					displayError(Messages.bind(Messages.CommandLineOnlyOneOutputError));
+					return false;
+				} else if (index == argCount) {
+					displayError(Messages.bind(Messages.CommandLineOutputTakesArgs));
+					return false;
+				}
+				this.indexFile = argsArray[index++];
+			} else {
+				if (this.jarToIndex != null) {
+					displayError(Messages.bind(Messages.CommandLineOnlyOneJarError));
+					return false;
+				}
+				this.jarToIndex = currentArg;
+			}
+		}
+		return true;
+	}
+
+	public Object start(IApplicationContext context) throws Exception {
+		boolean execute = processCommandLine((String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS));
+		if (execute) {
+			if (this.jarToIndex != null && this.indexFile != null) {
+				File f = new File(this.jarToIndex);
+				if (f.exists()) {
+					if (this.verbose) {
+						System.out.println(Messages.bind(Messages.CommandLineProcessing, this.indexFile, this.jarToIndex));
+					}
+					try {
+						JavaIndexer.generateIndexForJar(this.jarToIndex, this.indexFile);
+					} catch (IOException e) {
+						System.out.println(Messages.bind(Messages.CaughtException, "IOException", e.getLocalizedMessage())); //$NON-NLS-1$
+					}
+				} else {
+						System.out.println(Messages.bind(Messages.CommandLineJarFileNotExist, this.jarToIndex));
+				}
+			} else if (this.jarToIndex == null) {
+				System.out.println(Messages.bind(Messages.CommandLineJarNotSpecified));
+			} else if (this.indexFile == null) {
+				System.out.println(Messages.bind(Messages.CommandLineIndexFileNotSpecified));
+			}
+		}
+		return IApplication.EXIT_OK;
+	}
+
+	public void stop() {
+		// do nothing
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties
new file mode 100644
index 0000000..13ef933
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/messages.properties
@@ -0,0 +1,29 @@
+###############################################################################
+# Copyright (c) 2000, 2011 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+CommandLineUsage=Usage: eclipse -application org.eclipse.jdt.core.JavaIndexer [ OPTIONS ] -output <indexFile> <jarfile>\n\
+\n\
+\   -output <indexFile> Path to the index file to be generated.\n\
+\
+\   <jarfile>   Path to the jar for which index needs to be generated.\n\
+\
+\n\
+\ OPTIONS:\n\
+\n\
+\   -help                Display this message.\n\
+\   -verbose             Be verbose about the job.
+CommandLineProcessing=Generating index {0} for the jar {1}.
+CommandLineOnlyOneOutputError=Only one output needs to be specified.
+CommandLineOutputTakesArgs=-output should be followed by the path to the index file.
+CommandLineOnlyOneJarError=Only one jar file needs to be specified.
+CommandLineJarNotSpecified=No jar file is specified.
+CommandLineIndexFileNotSpecified=No index file is specified.
+CaughtException=Exception {0} - {1}.
+CommandLineJarFileNotExist={0} does not exist.
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html
new file mode 100644
index 0000000..ea16568
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/index/package.html
@@ -0,0 +1,19 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for generating indexes that can be used by the JDT search engine.
+<h2>
+Package Specification</h2>
+This package provides support for generating indexes that can be used by the search engine. The search engine 
+indexes all the elements referred in the classpath entries of the project into
+index files. These index files are used to search the elements faster. Indexing for bigger jars could
+take some time. To avoid this time, one can generate the index file and specify it when the jar is added
+to the classpath of the project.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java
new file mode 100644
index 0000000..7c0af9b
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a field declaration.
+ * The element is an <code>IField</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class FieldDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new field declaration match.
+	 *
+	 * @param element the field declaration
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public FieldDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java
new file mode 100644
index 0000000..68692ba
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a field reference.
+ * The element is the inner-most enclosing member that references this field.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class FieldReferenceMatch extends ReferenceMatch {
+
+private boolean isReadAccess;
+private boolean isWriteAccess;
+
+/**
+ * Creates a new field reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references
+ * 		this field
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param isReadAccess whether the match represents a read access
+ * @param isWriteAccess whether the match represents a write access
+ * @param insideDocComment <code>true</code> if this search match is inside a
+ *            doc comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ */
+public FieldReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+	this.isReadAccess = isReadAccess;
+	this.isWriteAccess = isWriteAccess;
+}
+
+/**
+ * Returns whether the field reference is a read access to the field.
+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+ *
+ * @return whether the field reference is a read access to the field.
+ */
+public final boolean isReadAccess() {
+	return this.isReadAccess;
+}
+
+/**
+ * Returns whether the field reference is a write access to the field.
+ * Note that a field reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+ *
+ * @return whether the field reference is a write access to the field.
+ */
+public final boolean isWriteAccess() {
+	return this.isWriteAccess;
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java
new file mode 100644
index 0000000..2a731fb
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java
@@ -0,0 +1,537 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.jdt.internal.core.search.processing.*;
+
+/**
+ * <p>
+ * This interface defines the constants used by the search engine.
+ * </p>
+ * <p>
+ * This interface declares constants only.
+ * </p>
+ * @see org.eclipse.jdt.core.search.SearchEngine
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IJavaSearchConstants {
+
+	/**
+	 * The nature of searched element or the nature
+	 * of match in unknown.
+	 */
+	int UNKNOWN = -1;
+
+	/* Nature of searched element */
+
+	/**
+	 * The searched element is a type, which may include classes, interfaces,
+	 * enums, and annotation types.
+	 *
+	 * @category searchFor
+	 */
+	int TYPE= 0;
+
+	/**
+	 * The searched element is a method.
+	 *
+	 * @category searchFor
+	 */
+	int METHOD= 1;
+
+	/**
+	 * The searched element is a package.
+	 *
+	 * @category searchFor
+	 */
+	int PACKAGE= 2;
+
+	/**
+	 * The searched element is a constructor.
+	 *
+	 * @category searchFor
+	 */
+	int CONSTRUCTOR= 3;
+
+	/**
+	 * The searched element is a field.
+	 *
+	 * @category searchFor
+	 */
+	int FIELD= 4;
+
+	/**
+	 * The searched element is a class.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @category searchFor
+	 */
+	int CLASS= 5;
+
+	/**
+	 * The searched element is an interface.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @category searchFor
+	 */
+	int INTERFACE= 6;
+
+	/**
+	 * The searched element is an enum.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @since 3.1
+	 * @category searchFor
+	 */
+	int ENUM= 7;
+
+	/**
+	 * The searched element is an annotation type.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @since 3.1
+	 * @category searchFor
+	 */
+	int ANNOTATION_TYPE= 8;
+
+	/**
+	 * The searched element is a class or enum type.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @since 3.1
+	 * @category searchFor
+	 */
+	int CLASS_AND_ENUM= 9;
+
+	/**
+	 * The searched element is a class or interface type.
+	 * More selective than using {@link #TYPE}.
+	 *
+	 * @since 3.1
+	 * @category searchFor
+	 */
+	int CLASS_AND_INTERFACE= 10;
+
+	/**
+	 * The searched element is an interface or annotation type.
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.3
+	 * @category searchFor
+	 */
+	int INTERFACE_AND_ANNOTATION= 11;
+
+	/* Nature of match */
+
+	/**
+	 * The search result is a declaration.
+	 * Can be used in conjunction with any of the nature of searched elements
+	 * so as to better narrow down the search.
+	 *
+	 * @category limitTo
+	 */
+	int DECLARATIONS= 0;
+
+	/**
+	 * The search result is a type that implements an interface or extends a class.
+	 * Used in conjunction with either TYPE or CLASS or INTERFACE, it will
+	 * respectively search for any type implementing/extending a type,
+	 * or rather exclusively search for classes implementing/extending the type, or
+	 * interfaces extending the type.
+	 *
+	 * @category limitTo
+	 */
+	int IMPLEMENTORS= 1;
+
+	/**
+	 * The search result is a reference.
+	 * Can be used in conjunction with any of the nature of searched elements
+	 * so as to better narrow down the search.
+	 * References can contain implementers since they are more generic kind
+	 * of matches.
+	 *
+	 * @category limitTo
+	 */
+	int REFERENCES= 2;
+
+	/**
+	 * The search result is a declaration, a reference, or an implementer
+	 * of an interface.
+	 * Can be used in conjunction with any of the nature of searched elements
+	 * so as to better narrow down the search.
+	 *
+	 * @category limitTo
+	 */
+	int ALL_OCCURRENCES= 3;
+
+	/**
+	 * When searching for field matches, it will exclusively find read accesses, as
+	 * opposed to write accesses. Note that some expressions are considered both
+	 * as field read/write accesses: for example, x++; x+= 1;
+	 *
+	 * @since 2.0
+	 * @category limitTo
+	 */
+	int READ_ACCESSES = 4;
+
+	/**
+	 * When searching for field matches, it will exclusively find write accesses, as
+	 * opposed to read accesses. Note that some expressions are considered both
+	 * as field read/write accesses: for example,  x++; x+= 1;
+	 *
+	 * @since 2.0
+	 * @category limitTo
+	 */
+	int WRITE_ACCESSES = 5;
+
+	/**
+	 * Ignore declaring type while searching result.
+	 * Can be used in conjunction with any of the nature of match.
+	 *
+	 * @since 3.1
+	 * @category limitTo
+	 */
+	int IGNORE_DECLARING_TYPE = 0x10;
+
+	/**
+	 * Ignore return type while searching result.
+	 * Can be used in conjunction with any other nature of match.
+	 * Note that:
+	 * <ul>
+	 * 	<li>for fields search, pattern will ignore field type</li>
+	 * 	<li>this flag will have no effect for types search</li>
+	 *	</ul>
+	 *
+	 * @since 3.1
+	 * @category limitTo
+	 */
+	int IGNORE_RETURN_TYPE = 0x20;
+
+	/**
+	 * Return only type references used as the type of a field declaration.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int FIELD_DECLARATION_TYPE_REFERENCE = 0x40;
+
+	/**
+	 * Return only type references used as the type of a local variable declaration.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE = 0x80;
+
+	/**
+	 * Return only type references used as the type of a method parameter
+	 * declaration.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int PARAMETER_DECLARATION_TYPE_REFERENCE = 0x100;
+
+	/**
+	 * Return only type references used as a super type or as a super interface.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int SUPERTYPE_TYPE_REFERENCE = 0x200;
+
+	/**
+	 * Return only type references used in a throws clause.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int THROWS_CLAUSE_TYPE_REFERENCE = 0x400;
+
+	/**
+	 * Return only type references used in a cast expression.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int CAST_TYPE_REFERENCE = 0x800;
+
+	/**
+	 * Return only type references used in a catch header.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int CATCH_TYPE_REFERENCE = 0x1000;
+
+	/**
+	 * Return only type references used in class instance creation.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p><p>
+	 *	Example:
+	 *<pre>
+	 * public class Test {
+	 * 	Test() {}
+	 * 	static Test bar()  {
+	 * 		return new <i>Test</i>();
+	 * 	}
+	 * }
+	 *</pre>
+	 * Searching references to the type <code>Test</code> using this flag in the
+	 * above snippet will match only the reference in italic.
+	 * </p><p>
+	 * Note that array creations are not returned when using this flag.
+	 * </p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int CLASS_INSTANCE_CREATION_TYPE_REFERENCE = 0x2000;
+
+	/**
+	 * Return only type references used as a method return type.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int RETURN_TYPE_REFERENCE = 0x4000;
+
+	/**
+	 * Return only type references used in an import declaration.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int IMPORT_DECLARATION_TYPE_REFERENCE = 0x8000;
+
+	/**
+	 * Return only type references used as an annotation.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int ANNOTATION_TYPE_REFERENCE = 0x10000;
+
+	/**
+	 * Return only type references used as a type argument in a parameterized
+	 * type or a parameterized method.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int TYPE_ARGUMENT_TYPE_REFERENCE = 0x20000;
+
+	/**
+	 * Return only type references used as a type variable bound.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int TYPE_VARIABLE_BOUND_TYPE_REFERENCE = 0x40000;
+
+	/**
+	 * Return only type references used as a wildcard bound.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int WILDCARD_BOUND_TYPE_REFERENCE = 0x80000;
+
+	/**
+	 * Return only type references used as a type of an <code>instanceof</code>
+	 * expression.
+	 * <p>
+	 * When this flag is set, only {@link TypeReferenceMatch} matches will be
+	 * returned.
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int INSTANCEOF_TYPE_REFERENCE = 0x100000;
+
+	/**
+	 * Return only super field accesses or super method invocations (e.g. using the
+	 * <code>super</code> qualifier).
+	 * <p>
+	 * When this flag is set, the kind of returned matches will depend on the
+	 * specified nature of the searched element:
+	 * <ul>
+	 * 	<li>for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+	 * 		matches will be returned,</li>
+	 * 	<li>for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+	 * 		matches will be returned.</li>
+	 * </ul>
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int SUPER_REFERENCE = 0x1000000;
+
+	/**
+	 * Return only qualified field accesses or qualified method invocations.
+	 * <p>
+	 * When this flag is set, the kind of returned matches will depend on the
+	 * specified nature of the searched element:
+	 * <ul>
+	 * 	<li>for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+	 * 		matches will be returned,</li>
+	 * 	<li>for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+	 * 		matches will be returned.</li>
+	 * </ul>
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int QUALIFIED_REFERENCE = 0x2000000;
+
+	/**
+	 * Return only primary field accesses or primary method invocations (e.g. using
+	 * the <code>this</code> qualifier).
+	 * <p>
+	 * When this flag is set, the kind of returned matches will depend on the
+	 * specified nature of the searched element:
+	 * <ul>
+	 * 	<li>for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+	 * 		matches will be returned,</li>
+	 * 	<li>for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+	 * 		matches will be returned.</li>
+	 * </ul>
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int THIS_REFERENCE = 0x4000000;
+
+	/**
+	 * Return only field accesses or method invocations without any qualification.
+	 * <p>
+	 * When this flag is set, the kind of returned matches will depend on the
+	 * specified nature of the searched element:
+	 * <ul>
+	 * 	<li>for the {@link #FIELD} nature, only {@link FieldReferenceMatch}
+	 * 		matches will be returned,</li>
+	 * 	<li>for the {@link #METHOD} nature, only {@link MethodReferenceMatch}
+	 * 		matches will be returned.</li>
+	 * </ul>
+	 *</p>
+	 * @since 3.4
+	 * @category limitTo
+	 */
+	int IMPLICIT_THIS_REFERENCE = 0x8000000;
+
+	/* Syntactic match modes */
+
+	/**
+	 * The search pattern matches exactly the search result,
+	 * that is, the source of the search result equals the search pattern.
+	 *
+	 * @deprecated Use {@link SearchPattern#R_EXACT_MATCH} instead.
+	 * @category matchRule
+	 */
+	int EXACT_MATCH = 0;
+	/**
+	 * The search pattern is a prefix of the search result.
+	 *
+	 * @deprecated Use {@link SearchPattern#R_PREFIX_MATCH} instead.
+	 * @category matchRule
+	 */
+	int PREFIX_MATCH = 1;
+	/**
+	 * The search pattern contains one or more wild cards ('*') where a
+	 * wild-card can replace 0 or more characters in the search result.
+	 *
+	 * @deprecated Use {@link SearchPattern#R_PATTERN_MATCH} instead.
+	 * @category matchRule
+	 */
+	int PATTERN_MATCH = 2;
+
+
+	/* Case sensitivity */
+
+	/**
+	 * The search pattern matches the search result only
+	 * if cases are the same.
+	 *
+	 * @deprecated Use the methods that take the matchMode
+	 *   with {@link SearchPattern#R_CASE_SENSITIVE} as a matchRule instead.
+	 * @category matchRule
+	 */
+	boolean CASE_SENSITIVE = true;
+	/**
+	 * The search pattern ignores cases in the search result.
+	 *
+	 * @deprecated Use the methods that take the matchMode
+	 *   without {@link SearchPattern#R_CASE_SENSITIVE} as a matchRule instead.
+	 * @category matchRule
+	 */
+	boolean CASE_INSENSITIVE = false;
+
+
+	/* Waiting policies */
+
+	/**
+	 * The search operation starts immediately, even if the underlying indexer
+	 * has not finished indexing the workspace. Results will more likely
+	 * not contain all the matches.
+	 */
+	int FORCE_IMMEDIATE_SEARCH = IJob.ForceImmediate;
+	/**
+	 * The search operation throws an <code>org.eclipse.core.runtime.OperationCanceledException</code>
+	 * if the underlying indexer has not finished indexing the workspace.
+	 */
+	int CANCEL_IF_NOT_READY_TO_SEARCH = IJob.CancelIfNotReady;
+	/**
+	 * The search operation waits for the underlying indexer to finish indexing
+	 * the workspace before starting the search.
+	 */
+	int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady;
+
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java
new file mode 100644
index 0000000..e038ec4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A <code>IJavaSearchResultCollector</code> collects search results from a <code>search</code>
+ * query to a <code>SearchEngine</code>. Clients must implement this interface and pass
+ * an instance to the <code>search(...)</code> methods. When a search starts, the <code>aboutToStart()</code>
+ * method is called, then 0 or more call to <code>accept(...)</code> are done, finally the
+ * <code>done()</code> method is called.
+ * <p>
+ * Results provided to this collector may be accurate - in this case they have an <code>EXACT_MATCH</code> accuracy -
+ * or they might be potential matches only - they have a <code>POTENTIAL_MATCH</code> accuracy. This last
+ * case can occur when a problem prevented the <code>SearchEngine</code> from resolving the match.
+ * </p>
+ * <p>
+ * The order of the results is unspecified. Clients must not rely on this order to display results,
+ * but they should sort these results (for example, in syntactical order).
+ * <p>
+ * The <code>IJavaSearchResultCollector</code> is also used to provide a progress monitor to the
+ * <code>SearchEngine</code>.
+ * </p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see SearchEngine
+ * @deprecated Since 3.0, the class
+ * {@link org.eclipse.jdt.core.search.SearchRequestor} replaces this interface.
+ */
+public interface IJavaSearchResultCollector {
+	/**
+	 * The search result corresponds exactly to the search pattern.
+	 *
+     * @deprecated Use {@link SearchMatch#A_ACCURATE} instead.
+	 */
+	int EXACT_MATCH = 0;
+
+	/**
+	 * The search result is potentially a match for the search pattern,
+	 * but a problem prevented the search engine from being more accurate
+	 * (typically because of the classpath was not correctly set).
+	 *
+     * @deprecated Use {@link SearchMatch#A_INACCURATE} instead.
+	 */
+	 int POTENTIAL_MATCH = 1;
+
+/**
+ * Called before the actual search starts.
+ *
+ * @deprecated Replaced by {@link SearchRequestor#beginReporting()}.
+ */
+public void aboutToStart();
+/**
+ * Accepts the given search result.
+ *
+ * @param resource the resource in which the match has been found
+ * @param start the start position of the match, -1 if it is unknown
+ * @param end the end position of the match, -1 if it is unknown;
+ *  the ending offset is exclusive, meaning that the actual range of characters
+ *  covered is <code>[start, end]</code>
+ * @param enclosingElement the Java element that contains the character range
+ *	<code>[start, end]</code>; the value can be <code>null</code> indicating that
+ *	no enclosing Java element has been found
+ * @param accuracy the level of accuracy the search result has; either
+ *  <code>EXACT_MATCH</code> or <code>POTENTIAL_MATCH</code>
+ * @exception CoreException if this collector had a problem accepting the search result
+ * @deprecated Replaced by {@link SearchRequestor#acceptSearchMatch(SearchMatch)}.
+ */
+public void accept(
+	IResource resource,
+	int start,
+	int end,
+	IJavaElement enclosingElement,
+	int accuracy)
+	throws CoreException;
+/**
+ * Called when the search has ended.
+ *
+ * @deprecated Replaced by {@link SearchRequestor#endReporting()}.
+ */
+public void done();
+/**
+ * Returns the progress monitor used to report progress.
+ *
+ * @return a progress monitor or null if no progress monitor is provided
+ */
+public IProgressMonitor getProgressMonitor();
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java
new file mode 100644
index 0000000..64776ec
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IType;
+
+/**
+ * An <code>IJavaSearchScope</code> defines where search result should be found by a
+ * <code>SearchEngine</code>. Clients must pass an instance of this interface
+ * to the <code>search(...)</code> methods. Such an instance can be created
+ * using the following factory methods: {@link SearchEngine#createHierarchyScope(IType)},
+ * {@link SearchEngine#createJavaSearchScope(IJavaElement[])}, {@link SearchEngine#createWorkspaceScope()} or clients
+ * may choose to implement this interface.
+ */
+public interface IJavaSearchScope {
+/**
+ * This constant defines the separator of the resourcePath string of the <code>encloses(String)</code>
+ * method. If present in the string, it separates the path to the jar file from the path
+ * to the .class file in the jar.
+ */
+String JAR_FILE_ENTRY_SEPARATOR = "|"; //$NON-NLS-1$
+/**
+ * Include type constant (bit mask) indicating that source folders should be considered in the search scope.
+ * @since 3.0
+ */
+int SOURCES = 1;
+/**
+ * Include type constant (bit mask) indicating that application libraries should be considered in the search scope.
+ * @since 3.0
+ */
+int APPLICATION_LIBRARIES = 2;
+/**
+ * Include type constant (bit mask) indicating that system libraries should be considered in the search scope.
+ * @since 3.0
+ */
+int SYSTEM_LIBRARIES = 4;
+/**
+ * Include type constant (bit mask) indicating that referenced projects should be considered in the search scope.
+ * @since 3.0
+ */
+int REFERENCED_PROJECTS = 8;
+/**
+ * Checks whether the resource at the given path is enclosed by this scope.
+ *
+ * @param resourcePath if the resource is contained in
+ * a JAR file, the path is composed of 2 paths separated
+ * by <code>JAR_FILE_ENTRY_SEPARATOR</code>: the first path is the full OS path
+ * to the JAR (if it is an external JAR), or the workspace relative <code>IPath</code>
+ * to the JAR (if it is an internal JAR),
+ * the second path is the path to the resource inside the JAR.
+ * @return whether the resource is enclosed by this scope
+ */
+public boolean encloses(String resourcePath);
+/**
+ * Checks whether this scope encloses the given element.
+ *
+ * @param element the given element
+ * @return <code>true</code> if the element is in this scope
+ */
+public boolean encloses(IJavaElement element);
+/**
+ * Returns the paths to the enclosing projects and JARs for this search scope.
+ * <ul>
+ * <li> If the path is a project path, this is the full path of the project
+ *       (see <code>IResource.getFullPath()</code>).
+ *        For example, /MyProject
+ * </li>
+ * <li> If the path is a JAR path and this JAR is internal to the workspace,
+ *        this is the full path of the JAR file (see <code>IResource.getFullPath()</code>).
+ *        For example, /MyProject/mylib.jar
+ * </li>
+ * <li> If the path is a JAR path and this JAR is external to the workspace,
+ *        this is the full OS path to the JAR file on the file system.
+ *        For example, d:\libs\mylib.jar
+ * </li>
+ * </ul>
+ *
+ * @return an array of paths to the enclosing projects and JARS.
+ */
+IPath[] enclosingProjectsAndJars();
+/**
+ * Returns whether this scope contains any <code>.class</code> files (either
+ * in folders or within JARs).
+ *
+ * @return whether this scope contains any <code>.class</code> files
+ * @deprecated Use
+ * {@link org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[])}
+ * with the package fragment roots that correspond to the binaries instead.
+ */
+boolean includesBinaries();
+/**
+ * Returns whether this scope includes classpaths defined by
+ * the projects of the resources of this search scope.
+ *
+ * @return whether this scope includes classpaths
+ * @deprecated Use
+ * {@link org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[])}
+ * with a Java project instead.
+ */
+boolean includesClasspaths();
+/**
+ * Sets whether this scope contains any <code>.class</code> files (either
+ * in folders or within JARs).
+ *
+ * @param includesBinaries whether this scope contains any <code>.class</code> files
+ * @deprecated Use
+ * {@link org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[])}
+ * with the package fragment roots that correspond to the binaries instead.
+ */
+public void setIncludesBinaries(boolean includesBinaries);
+/**
+ * Sets whether this scope includes the classpaths defined by
+ * the projects of the resources of this search scope.
+ *
+ * @param includesClasspaths whether this scope includes classpaths
+ * @deprecated Use
+ * {@link org.eclipse.jdt.core.search.SearchEngine#createJavaSearchScope(IJavaElement[])}
+ * with a Java project instead.
+ */
+public void setIncludesClasspaths(boolean includesClasspaths);
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java
new file mode 100644
index 0000000..855d622
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+/**
+ * A search pattern defines how search results are found. Use <code>SearchEngine.createSearchPattern</code>
+ * to create a search pattern.
+ *
+ * @see SearchEngine#createSearchPattern(org.eclipse.jdt.core.IJavaElement, int)
+ * @see SearchEngine#createSearchPattern(String, int, int, boolean)
+ * @deprecated Since 3.0, the class
+ * {@link org.eclipse.jdt.core.search.SearchPattern} replaces this interface.
+ */
+public interface ISearchPattern {
+	// used as a marker interface: contains no methods
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java
new file mode 100644
index 0000000..56d5a65
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+/**
+ * A <code>ITypeNameRequestor</code> collects search results from a <code>searchAllTypeNames</code>
+ * query to a <code>SearchEngine</code>. Clients must implement this interface and pass
+ * an instance to the <code>searchAllTypeNames(...)</code> method. Only top-level and
+ * member types are reported. Local types are not reported.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * @deprecated Use abstract class {@link TypeNameRequestor} instead.
+ */
+public interface ITypeNameRequestor {
+/**
+ * Accepts a top-level or a member class.
+ *
+ * @param packageName the dot-separated name of the package of the class
+ * @param simpleTypeName the simple name of the class
+ * @param enclosingTypeNames if the class is a member type,
+ *          the simple names of the enclosing types from the outer-most to the
+ *          direct parent of the class (for example, if the class is x.y.A$B$C then
+ *          the enclosing types are [A, B]. This is an empty array if the class
+ *          is a top-level type.
+ * @param path the full path to the resource containing the class. If the resource is a .class file
+ *          or a source file, this is the full path in the workspace to this resource. If the
+ *          resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+ *		 	 by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>:
+ *			 the first path is the full OS path to the archive (if it is an external archive),
+ *			 or the workspace relative <code>IPath</code> to the archive (if it is an internal archive),
+ * 		 the second path is the path to the resource inside the archive.
+ */
+void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path);
+/**
+ * Accepts a top-level or a member interface.
+ *
+ * @param packageName the dot-separated name of the package of the interface
+ * @param simpleTypeName the simple name of the interface
+ * @param enclosingTypeNames if the interface is a member type,
+ *          the simple names of the enclosing types from the outer-most to the
+ *          direct parent of the interface (for example, if the interface is x.y.A$B$I then
+ *          the enclosing types are [A, B]. This is an empty array if the interface
+ *          is a top-level type.
+ * @param path the full path to the resource containing the interface. If the resource is a .class file
+ *          or a source file, this is the full path in the workspace to this resource. If the
+ *          resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+ *		 	 by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>:
+ *			 the first path is the full OS path to the archive (if it is an external archive),
+ *			 or the workspace relative <code>IPath</code> to the archive (if it is an internal archive),
+ * 		 the second path is the path to the resource inside the archive.
+ * */
+void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path);
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java
new file mode 100644
index 0000000..1315cf8
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a local variable declaration.
+ * The element is an <code>ILocalVariable</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class LocalVariableDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new local variable declaration match.
+	 *
+	 * @param element the local variable declaration
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public LocalVariableDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java
new file mode 100644
index 0000000..1f1cc70
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a local variable reference.
+ * The element is the inner-most enclosing member that references this local variable.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class LocalVariableReferenceMatch extends SearchMatch {
+
+	private boolean isReadAccess;
+	private boolean isWriteAccess;
+
+	/**
+	 * Creates a new local variable reference match.
+	 *
+	 * @param enclosingElement the inner-most enclosing member that references this local variable
+	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param isReadAccess whether the match represents a read access
+	 * @param isWriteAccess whethre the match represents a write access
+	 * @param insideDocComment <code>true</code> if this search match is inside a doc
+	 * comment, and <code>false</code> otherwise
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public LocalVariableReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean isReadAccess, boolean isWriteAccess, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+		super(enclosingElement, accuracy, offset, length, participant, resource);
+		this.isReadAccess = isReadAccess;
+		this.isWriteAccess = isWriteAccess;
+		setInsideDocComment(insideDocComment);
+	}
+
+	/**
+	 * Returns whether the local variable reference is a read access to the variable.
+	 * Note that a local variable reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+	 *
+	 * @return whether the local variable reference is a read access to the variable.
+	 */
+	public final boolean isReadAccess() {
+		return this.isReadAccess;
+	}
+
+	/**
+	 * Returns whether the local variable reference is a write access to the variable.
+	 * Note that a local variable reference can be read and written at once in case of compound assignments (e.g. i += 0;)
+	 *
+	 * @return whether the local variable reference is a write access to the variable.
+	 */
+	public final boolean isWriteAccess() {
+		return this.isWriteAccess;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java
new file mode 100644
index 0000000..c61f83c
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a method declaration.
+ * The element is an <code>IMethod</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class MethodDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new method declaration match.
+	 *
+	 * @param element the method declaration
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public MethodDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java
new file mode 100644
index 0000000..06a5571
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a method reference.
+ * The element is the inner-most enclosing member that references this method.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class MethodReferenceMatch extends ReferenceMatch {
+	private boolean constructor;
+	private boolean synthetic;
+	private boolean superInvocation;
+
+/**
+ * Creates a new method reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this method
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * 		comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ */
+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
+/**
+ * Creates a new method reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this method
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param constructor <code>true</code> if this search match a constructor
+ * 		<code>false</code> otherwise
+ * @param synthetic <code>true</code> if this search match a synthetic element
+ * 		<code>false</code> otherwise
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ * @since 3.1
+ */
+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	this(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+	this.constructor = constructor;
+	this.synthetic = synthetic;
+}
+
+/**
+ * Creates a new method reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this method
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param constructor <code>true</code> if this search matches a constructor
+ * 		<code>false</code> otherwise
+ * @param synthetic <code>true</code> if this search matches a synthetic element
+ * 		<code>false</code> otherwise
+ * @param superInvocation <code>true</code> if this search matches a super-type invocation
+ * 		element <code>false</code> otherwise
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * 		comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ * @since 3.3
+ */
+public MethodReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean constructor, boolean synthetic, boolean superInvocation, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	this(enclosingElement, accuracy, offset, length, constructor, synthetic, insideDocComment, participant, resource);
+	this.superInvocation = superInvocation;
+}
+
+/**
+ * Returns whether the reference is on a constructor.
+ *
+ * @return Returns whether the reference is on a constructor or not.
+ * @since 3.1
+ */
+public final boolean isConstructor() {
+	return this.constructor;
+}
+
+/**
+ * Returns whether the reference is on a synthetic element.
+ * Note that this field is only used for constructor reference. This happens when default constructor
+ * declaration is used or implicit super constructor is called.
+ *
+ * @return whether the reference is synthetic or not.
+ * @since 3.1
+ */
+public final boolean isSynthetic() {
+	return this.synthetic;
+}
+
+/**
+ * Returns whether the reference is on a message sent from a type
+ * which is a super type of the searched method declaring type.
+ * If <code>true</code>, the method called at run-time may or may not be
+ * the search target, depending on the run-time type of the receiver object.
+ *
+ * @return <code>true</code> if the reference is on a message sent from
+ * a super-type of the searched method declaring class, <code>false</code> otherwise
+ * @since 3.3
+ */
+public boolean isSuperInvocation() {
+	return this.superInvocation;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java
new file mode 100644
index 0000000..5afbc1a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a package declaration.
+ * The element is an <code>IPackageFragment</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class PackageDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new package declaration match.
+	 *
+	 * @param element the package declaration
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public PackageDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java
new file mode 100644
index 0000000..f768aa4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a package reference.
+ * The element is the inner-most enclosing member that references this package.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class PackageReferenceMatch extends ReferenceMatch {
+
+/**
+ * Creates a new package reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this package
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * 		comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ */
+public PackageReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ReferenceMatch.java
new file mode 100644
index 0000000..6a85254
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ReferenceMatch.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.*;
+
+/**
+ * An abstract Java search match that represents a reference.
+ * 
+ * @since 3.4
+ */
+public abstract class ReferenceMatch extends SearchMatch {
+
+	IJavaElement localElement;
+
+/**
+ * Creates a new reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this java element
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * 		comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ */
+public ReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	super(enclosingElement, accuracy, offset, length, participant, resource);
+	setInsideDocComment(insideDocComment);
+}
+
+/**
+ * Returns the local element of this search match, or <code>null</code> if none.
+ * A local element is the inner-most element that contains the reference and that is
+ * not reachable by navigating from the root of the {@link IJavaModel} using
+ * {@link IParent#getChildren()}.
+ * <p>
+ * Known element types for local elements are {@link IJavaElement#ANNOTATION},
+ * {@link IJavaElement#LOCAL_VARIABLE} and {@link IJavaElement#TYPE_PARAMETER}.<br>
+ * However clients should not assume that this set of element types is closed as
+ * other types of elements may be returned in the future, e.g. if new types
+ * of elements are added in the Java model. Clients can only assume that the
+ * {@link IJavaElement#getParent() parent} chain of this local element eventually
+ * leads to the element from {@link #getElement()}.
+ * </p><p>
+ * The local element being an {@link IAnnotation} is the most usual case. For example,
+ * <ul>
+ * 	<li>searching for the references to the method <code>Annot.clazz()</code> in
+ * 			<pre>
+ *             public class Test {
+ *                 void method() {
+ *                     &#0064;Annot(clazz=Test.class) int x;
+ *                 }
+ *             }</pre>
+ * 			will return one {@link MethodReferenceMatch} match whose local element
+ * 			is the {@link IAnnotation} '<code>Annot</code>'.<br><br>
+ * 	</li>
+ *		<li>searching for the references to the type <code>Deprecated</code> in
+ *				<pre>
+ *             public class Test {
+ *                &#0064;Deprecated void method() {}
+ *             }</pre>
+ * 			will return one {@link TypeReferenceMatch} match whose local element
+ * 			is the {@link IAnnotation} '<code>Deprecated</code>'.<br><br>
+ * 	</li>
+ * 	<li>searching for the references to the field <code>CONST</code> in
+ * 			<pre>
+ *              &#0064;Num(number= Num.CONST)
+ *              &#0064;interface Num {
+ *                  public static final int CONST= 42;
+ *                  int number();
+ *              }</pre>
+ * 			will return one {@link FieldReferenceMatch} match whose local element
+ * 			is the {@link IAnnotation} '<code>Num</code>'.<br><br>
+ * 	</li>
+ * </ul>
+ * </p><p>
+ * A local element may also be a {@link ILocalVariable} whose type is the referenced
+ * type. For example,
+ * <ul>
+ * 	<li>searching for the references to the type <code>Test</code> in
+ * 		<pre>
+ *         public class Test {
+ *             void foo() {
+ *                Test local;
+ *             }
+ *         }</pre>
+ * 		will return one {@link TypeReferenceMatch} match whose local element
+ * 		is the {@link ILocalVariable} '<code>local</code>'.<br><br>
+ * 	</li>
+ * </ul>
+ * Or a local element may be an {@link ITypeParameter} that extends the referenced
+ * type. For example,
+ * <ul>
+ * 	<li>searching for the references to the type <code>Test</code> in
+ * 		<pre>
+ *         public class X&lt; T extends Test&gt; {
+ *         }</pre>
+ * 		will return one {@link TypeReferenceMatch} match whose local element
+ * 		is the {@link ITypeParameter} '<code>T</code>'.<br><br>
+ * </ul>
+ * </p>
+ *
+ * @return the local element of this search match, or <code>null</code> if none.
+ *
+ * @since 3.4
+ */
+final public IJavaElement getLocalElement() {
+	return this.localElement;
+}
+
+/**
+ * Store the local element in the match.
+ *
+ * @param element The local element to be stored
+ * 
+ * @since 3.5
+ */
+final public void setLocalElement(IJavaElement element) {
+	this.localElement = element;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java
new file mode 100644
index 0000000..0c16fe6
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.core.index.Index;
+
+/**
+ * A search document encapsulates a content to be either indexed or searched in.
+ * A search participant creates a search document.
+ * <p>
+ * This class is intended to be subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public abstract class SearchDocument {
+	private Index index;
+	private String containerRelativePath;
+	private SourceElementParser parser;
+	private String documentPath;
+	private SearchParticipant participant;
+
+	/**
+	 * Creates a new search document. The given document path is a string that uniquely identifies the document.
+	 * Most of the time it is a workspace-relative path, but it can also be a file system path, or a path inside a zip file.
+	 *
+	 * @param documentPath the path to the document,
+	 * or <code>null</code> if none
+	 * @param participant the participant that creates the search document
+	 */
+	protected SearchDocument(String documentPath, SearchParticipant participant) {
+		this.documentPath = documentPath;
+		this.participant = participant;
+	}
+
+	/**
+	 * Adds the given index entry (category and key) coming from this
+	 * document to the index. This method must be called from
+	 * {@link SearchParticipant#indexDocument(SearchDocument document, org.eclipse.core.runtime.IPath indexPath)}.
+	 *
+	 * @param category the category of the index entry
+	 * @param key the key of the index entry
+	 */
+	public void addIndexEntry(char[] category, char[] key) {
+		if (this.index != null)
+			this.index.addIndexEntry(category, key, getContainerRelativePath());
+	}
+
+	/**
+	 * Returns the contents of this document.
+	 * Contents may be different from actual resource at corresponding document path,
+	 * in case of preprocessing.
+	 * <p>
+	 * This method must be implemented in subclasses.
+	 * </p><p>
+	 * Note: some implementation may choose to cache the contents directly on the
+	 * document for performance reason. However, this could induce scalability issues due
+	 * to the fact that collections of documents are manipulated throughout the search
+	 * operation, and cached contents would then consume lots of memory until they are
+	 * all released at once in the end.
+	 * </p>
+	 *
+	 * @return the contents of this document,
+	 * or <code>null</code> if none
+	 */
+	public abstract byte[] getByteContents();
+
+	/**
+	 * Returns the contents of this document.
+	 * Contents may be different from actual resource at corresponding document
+	 * path due to preprocessing.
+	 * <p>
+	 * This method must be implemented in subclasses.
+	 * </p><p>
+	 * Note: some implementation may choose to cache the contents directly on the
+	 * document for performance reason. However, this could induce scalability issues due
+	 * to the fact that collections of documents are manipulated throughout the search
+	 * operation, and cached contents would then consume lots of memory until they are
+	 * all released at once in the end.
+	 * </p>
+	 *
+	 * @return the contents of this document,
+	 * or <code>null</code> if none
+	 */
+	public abstract char[] getCharContents();
+
+	private String getContainerRelativePath() {
+		if (this.containerRelativePath == null)
+			this.containerRelativePath = this.index.containerRelativePath(getPath());
+		return this.containerRelativePath;
+	}
+
+	/**
+	 * Returns the encoding for this document.
+	 * <p>
+	 * This method must be implemented in subclasses.
+	 * </p>
+	 *
+	 * @return the encoding for this document,
+	 * or <code>null</code> if none
+	 */
+	public abstract String getEncoding();
+
+	/**
+	 * @nooverride This method is not intended to be re-implemented or extended by clients.
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public SourceElementParser getParser() {
+		return this.parser;
+	}
+	
+	/**
+	 * Returns the participant that created this document.
+	 *
+	 * @return the participant that created this document
+	 */
+	public final SearchParticipant getParticipant() {
+		return this.participant;
+	}
+
+	/**
+	 * Returns the path to the original document to publicly mention in index
+	 * or search results. This path is a string that uniquely identifies the document.
+	 * Most of the time it is a workspace-relative path, but it can also be a file system path,
+	 * or a path inside a zip file.
+	 *
+	 * @return the path to the document
+	 */
+	public final String getPath() {
+		return this.documentPath;
+	}
+	/**
+	 * Removes all index entries from the index for the given document.
+	 * This method must be called from
+	 * {@link SearchParticipant#indexDocument(SearchDocument document, org.eclipse.core.runtime.IPath indexPath)}.
+	 */
+	public void removeAllIndexEntries() {
+		if (this.index != null)
+			this.index.remove(getContainerRelativePath());
+	}
+	
+	/**
+	 * @nooverride This method is not intended to be re-implemented or extended by clients.
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public void setIndex(Index indexToSet) {
+		this.index = indexToSet;
+	}
+	
+	/**
+	 * @nooverride This method is not intended to be re-implemented or extended by clients.
+	 * @noreference This method is not intended to be referenced by clients.
+	 */
+	public void setParser(SourceElementParser sourceElementParser) {
+		this.parser = sourceElementParser;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
new file mode 100644
index 0000000..586cd89
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
@@ -0,0 +1,1340 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for bug 215139 and bug 295894
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.core.search.*;
+import org.eclipse.jdt.internal.core.search.matching.*;
+
+/**
+ * A {@link SearchEngine} searches for Java elements following a search pattern.
+ * The search can be limited to a search scope.
+ * <p>
+ * Various search patterns can be created using the factory methods
+ * {@link SearchPattern#createPattern(String, int, int, int)}, {@link SearchPattern#createPattern(IJavaElement, int)},
+ * {@link SearchPattern#createOrPattern(SearchPattern, SearchPattern)}.
+ * </p>
+ * <p>For example, one can search for references to a method in the hierarchy of a type,
+ * or one can search for the declarations of types starting with "Abstract" in a project.
+ * </p>
+ * <p>
+ * This class may be instantiated.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class SearchEngine {
+
+	/**
+	 * Internal adapter class.
+	 * @deprecated marking deprecated as it uses deprecated ISearchPattern
+	 */
+	static class SearchPatternAdapter implements ISearchPattern {
+		SearchPattern pattern;
+		SearchPatternAdapter(SearchPattern pattern) {
+			this.pattern = pattern;
+		}
+	}
+
+	/**
+	 * Internal adapter class.
+	 * @deprecated marking deprecated as it uses deprecated IJavaSearchResultCollector
+	 */
+	static class ResultCollectorAdapter extends SearchRequestor {
+		IJavaSearchResultCollector resultCollector;
+		ResultCollectorAdapter(IJavaSearchResultCollector resultCollector) {
+			this.resultCollector = resultCollector;
+		}
+		/**
+		 * @see org.eclipse.jdt.core.search.SearchRequestor#acceptSearchMatch(org.eclipse.jdt.core.search.SearchMatch)
+		 */
+		public void acceptSearchMatch(SearchMatch match) throws CoreException {
+			this.resultCollector.accept(
+				match.getResource(),
+				match.getOffset(),
+				match.getOffset() + match.getLength(),
+				(IJavaElement) match.getElement(),
+				match.getAccuracy()
+			);
+		}
+		/**
+		 * @see org.eclipse.jdt.core.search.SearchRequestor#beginReporting()
+		 */
+		public void beginReporting() {
+			this.resultCollector.aboutToStart();
+		}
+		/**
+		 * @see org.eclipse.jdt.core.search.SearchRequestor#endReporting()
+		 */
+		public void endReporting() {
+			this.resultCollector.done();
+		}
+	}
+
+	/**
+	 * Internal adapter class.
+	 * @deprecated marking deprecated as it uses deprecated ITypeNameRequestor
+	 */
+	static class TypeNameRequestorAdapter implements IRestrictedAccessTypeRequestor {
+		ITypeNameRequestor nameRequestor;
+		TypeNameRequestorAdapter(ITypeNameRequestor requestor) {
+			this.nameRequestor = requestor;
+		}
+		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+			if (Flags.isInterface(modifiers)) {
+				this.nameRequestor.acceptInterface(packageName, simpleTypeName, enclosingTypeNames, path);
+			} else {
+				this.nameRequestor.acceptClass(packageName, simpleTypeName, enclosingTypeNames, path);
+			}
+		}
+	}
+
+	// Search engine now uses basic engine functionalities
+	private BasicSearchEngine basicEngine;
+
+	/**
+	 * Creates a new search engine.
+	 */
+	public SearchEngine() {
+		this.basicEngine = new BasicSearchEngine();
+	}
+
+	/**
+	 * Creates a new search engine with a list of working copies that will take precedence over
+	 * their original compilation units in the subsequent search operations.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.</p>
+	 * <p>
+	 * Since 3.0 the given working copies take precedence over primary working copies (if any).
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @since 3.0
+	 */
+	public SearchEngine(ICompilationUnit[] workingCopies) {
+		this.basicEngine = new BasicSearchEngine(workingCopies);
+	}
+	/**
+	 * Creates a new search engine with a list of working copies that will take precedence over
+	 * their original compilation units in the subsequent search operations.
+	 * <p>
+	 * Note that passing an empty working copy will be as if the original compilation
+	 * unit had been deleted.</p>
+	 * <p>
+	 * Since 3.0 the given working copies take precedence over primary working copies (if any).
+	 *
+	 * @param workingCopies the working copies that take precedence over their original compilation units
+	 * @since 2.0
+	 * @deprecated Use {@link #SearchEngine(ICompilationUnit[])} instead.
+	 */
+	public SearchEngine(IWorkingCopy[] workingCopies) {
+		int length = workingCopies.length;
+		ICompilationUnit[] units = new ICompilationUnit[length];
+		System.arraycopy(workingCopies, 0, units, 0, length);
+		this.basicEngine = new BasicSearchEngine(units);
+	}
+
+	/**
+	 * Creates a new search engine with the given working copy owner.
+	 * The working copies owned by this owner will take precedence over
+	 * the primary compilation units in the subsequent search operations.
+	 *
+	 * @param workingCopyOwner the owner of the working copies that take precedence over their original compilation units
+	 * @since 3.0
+	 */
+	public SearchEngine(WorkingCopyOwner workingCopyOwner) {
+		this.basicEngine = new BasicSearchEngine(workingCopyOwner);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the hierarchy of the given type.
+	 * The Java elements resulting from a search with this scope will
+	 * be types in this hierarchy, or members of the types in this hierarchy.
+	 *
+	 * @param type the focus of the hierarchy scope
+	 * @return a new hierarchy scope
+	 * @exception JavaModelException if the hierarchy could not be computed on the given type
+	 */
+	public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException {
+		return BasicSearchEngine.createHierarchyScope(type);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the hierarchy of the given type.
+	 * When the hierarchy is computed, the types defined in the working copies owned
+	 * by the given owner take precedence over the original compilation units.
+	 * The Java elements resulting from a search with this scope will
+	 * be types in this hierarchy, or members of the types in this hierarchy.
+	 *
+	 * @param type the focus of the hierarchy scope
+	 * @param owner the owner of working copies that take precedence over original compilation units
+	 * @return a new hierarchy scope
+	 * @exception JavaModelException if the hierarchy could not be computed on the given type
+	 * @since 3.0
+	 */
+	public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException {
+		return BasicSearchEngine.createHierarchyScope(type, owner);
+	}
+
+	/**
+	 * 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.
+	 * <p>
+	 * Unlike the <code>createHierarchyScope</code> methods, this method creates <em>strict</em>
+	 * scopes that only contain types that actually span the hierarchy of the focus
+	 * type, but do not include additional enclosing or member types.
+	 * </p>
+	 * <p>
+	 * 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,
+	 * and exclude supertypes. Also, inclusion of the focus type itself is controlled by a parameter. 
+	 * </p>
+	 * 
+	 * @param project the project to which to constrain the search, or <code>null</code> if
+	 *        search should consider all types in the workspace 
+	 * @param type the focus of the hierarchy scope
+	 * @param onlySubtypes if <code>true</code> only subtypes of <code>type</code> are considered
+	 * @param includeFocusType if true the focus type <code>type</code> 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 <code>null</code> 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 {
+		return BasicSearchEngine.createStrictHierarchyScope(project, type, onlySubtypes, includeFocusType, owner);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the given resources.
+	 * The Java elements resulting from a search with this scope will
+	 * have their underlying resource included in or equals to one of the given
+	 * resources.
+	 * <p>
+	 * Resources must not overlap, for example, one cannot include a folder and its children.
+	 * </p>
+	 *
+	 * @param resources the resources the scope is limited to
+	 * @return a new Java search scope
+	 * @deprecated Use {@link #createJavaSearchScope(IJavaElement[])} instead.
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IResource[] resources) {
+		int length = resources.length;
+		IJavaElement[] elements = new IJavaElement[length];
+		for (int i = 0; i < length; i++) {
+			elements[i] = JavaCore.create(resources[i]);
+		}
+		return createJavaSearchScope(elements);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the given Java elements.
+	 * The Java elements resulting from a search with this scope will
+	 * be children of the given elements.
+	 * <p>
+	 * If an element is an {@link IJavaProject}, then the project's source folders,
+	 * its jars (external and internal) and its referenced projects (with their source
+	 * folders and jars, recursively) will be included.</p>
+	 * <p>If an element is an {@link IPackageFragmentRoot}, then only the package fragments of
+	 * this package fragment root will be included.</p>
+	 * <p>If an element is an {@link IPackageFragment}, then only the compilation unit and class
+	 * files of this package fragment will be included. Subpackages will NOT be
+	 * included.</p>
+	 *
+	 * <p>In other words, this is equivalent to using SearchEngine.createJavaSearchScope(elements, true).</p>
+	 *
+	 * @param elements the Java elements the scope is limited to
+	 * @return a new Java search scope
+	 * @since 2.0
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) {
+		return BasicSearchEngine.createJavaSearchScope(elements);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the given Java elements.
+	 * The Java elements resulting from a search with this scope will
+	 * be children of the given elements.
+	 *
+	 * <p>If an element is an {@link IJavaProject}, then the project's source folders,
+	 * its jars (external and internal) and - if specified - its referenced projects
+	 * (with their source folders and jars, recursively) will be included.</p>
+	 * <p>If an element is an {@link IPackageFragmentRoot}, then only the package fragments of
+	 * this package fragment root will be included.</p>
+	 * <p>If an element is an {@link IPackageFragment}, then only the compilation unit and class
+	 * files of this package fragment will be included. Subpackages will NOT be
+	 * included.</p>
+	 *
+	 * @param elements the Java elements the scope is limited to
+	 * @param includeReferencedProjects a flag indicating if referenced projects must be
+	 * 									 recursively included
+	 * @return a new Java search scope
+	 * @since 2.0
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) {
+		return BasicSearchEngine.createJavaSearchScope(elements, includeReferencedProjects);
+	}
+
+	/**
+	 * Returns a Java search scope limited to the given Java elements.
+	 * The Java elements resulting from a search with this scope will
+	 * be children of the given elements.
+	 *
+	 * <p>If an element is an IJavaProject, then it includes:</p>
+	 * <ul>
+	 * <li>its source folders if {@link IJavaSearchScope#SOURCES} is specified,</li>
+	 * <li>its application libraries (internal and external jars, class folders that are on the raw classpath,
+	 *   or the ones that are coming from a classpath path variable,
+	 *   or the ones that are coming from a classpath container with the K_APPLICATION kind)
+	 *   if {@link IJavaSearchScope#APPLICATION_LIBRARIES} is specified</li>
+	 * <li>its system libraries (internal and external jars, class folders that are coming from an
+	 *   IClasspathContainer with the K_SYSTEM kind)
+	 *   if {@link IJavaSearchScope#SYSTEM_LIBRARIES} is specified</li>
+	 * <li>its referenced projects (with their source folders and jars, recursively)
+	 *   if {@link IJavaSearchScope#REFERENCED_PROJECTS} is specified.</li>
+	 * </ul>
+	 * <p>If an element is an {@link IPackageFragmentRoot}, then only the package fragments of
+	 * this package fragment root will be included.</p>
+	 * <p>If an element is an {@link IPackageFragment}, then only the compilation unit and class
+	 * files of this package fragment will be included. Subpackages will NOT be
+	 * included.</p>
+	 *
+	 * @param elements the Java elements the scope is limited to
+	 * @param includeMask the bit-wise OR of all include types of interest
+	 * @return a new Java search scope
+	 * @see IJavaSearchScope#SOURCES
+	 * @see IJavaSearchScope#APPLICATION_LIBRARIES
+	 * @see IJavaSearchScope#SYSTEM_LIBRARIES
+	 * @see IJavaSearchScope#REFERENCED_PROJECTS
+	 * @since 3.0
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) {
+		return BasicSearchEngine.createJavaSearchScope(elements, includeMask);
+	}
+
+	/**
+	 * Returns a search pattern that combines the given two patterns into a "or" pattern.
+	 * The search result will match either the left pattern or the right pattern.
+	 *
+	 * @param leftPattern the left pattern
+	 * @param rightPattern the right pattern
+	 * @return a "or" pattern
+	 * @deprecated Use {@link SearchPattern#createOrPattern(SearchPattern, SearchPattern)} instead.
+	 */
+	public static ISearchPattern createOrSearchPattern(ISearchPattern leftPattern, ISearchPattern rightPattern) {
+		SearchPattern left = ((SearchPatternAdapter) leftPattern).pattern;
+		SearchPattern right = ((SearchPatternAdapter) rightPattern).pattern;
+		SearchPattern pattern = SearchPattern.createOrPattern(left, right);
+		return new SearchPatternAdapter(pattern);
+	}
+
+	/**
+	 * Returns a search pattern based on a given string pattern. The string patterns support '*' wild-cards.
+	 * The remaining parameters are used to narrow down the type of expected results.
+	 *
+	 * <br>
+	 *	Examples:
+	 *	<ul>
+	 * 		<li>search for case insensitive references to <code>Object</code>:
+	 *			<code>createSearchPattern("Object", TYPE, REFERENCES, false);</code></li>
+	 *  	<li>search for case sensitive references to exact <code>Object()</code> constructor:
+	 *			<code>createSearchPattern("java.lang.Object()", CONSTRUCTOR, REFERENCES, true);</code></li>
+	 *  	<li>search for implementers of <code>java.lang.Runnable</code>:
+	 *			<code>createSearchPattern("java.lang.Runnable", TYPE, IMPLEMENTORS, true);</code></li>
+	 *  </ul>
+	 * @param stringPattern the given pattern
+	 * @param searchFor determines the nature of the searched elements
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for both classes and interfaces</li>
+	 *		<li>{@link IJavaSearchConstants#FIELD}: look for fields</li>
+	 *		<li>{@link IJavaSearchConstants#METHOD}: look for methods</li>
+	 *		<li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li>
+	 *		<li>{@link IJavaSearchConstants#PACKAGE}: look for packages</li>
+	 *	</ul>
+	 * @param limitTo determines the nature of the expected matches
+	 *	<ul>
+	 * 		<li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching with the corresponding
+	 * 			element. In case the element is a method, declarations of matching methods in subtypes will also
+	 *  		be found, allowing to find declarations of abstract methods, etc.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or references as specified
+	 *  		above.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for types, will find all types
+	 *				which directly implement/extend a given interface.
+	 *				Note that types may be only classes or only interfaces if {@link IJavaSearchConstants#CLASS } or
+	 *				{@link IJavaSearchConstants#INTERFACE} is respectively used instead of {@link IJavaSearchConstants#TYPE}.
+	 *		</li>
+	 *	</ul>
+	 *
+	 * @param isCaseSensitive indicates whether the search is case sensitive or not.
+	 * @return a search pattern on the given string pattern, or <code>null</code> if the string pattern is ill-formed.
+	 * @deprecated Use {@link SearchPattern#createPattern(String, int, int, int)} instead.
+	 */
+	public static ISearchPattern createSearchPattern(String stringPattern, int searchFor, int limitTo, boolean isCaseSensitive) {
+		int matchMode = stringPattern.indexOf('*') != -1 || stringPattern.indexOf('?') != -1
+			? SearchPattern.R_PATTERN_MATCH
+			: SearchPattern.R_EXACT_MATCH;
+		int matchRule = isCaseSensitive ? matchMode | SearchPattern.R_CASE_SENSITIVE : matchMode;
+		return  new SearchPatternAdapter(SearchPattern.createPattern(stringPattern, searchFor, limitTo, matchRule));
+	}
+
+	/**
+	 * Returns a search pattern based on a given Java element.
+	 * The pattern is used to trigger the appropriate search, and can be parameterized as follows:
+	 *
+	 * @param element the Java element the search pattern is based on
+	 * @param limitTo determines the nature of the expected matches
+	 * 	<ul>
+	 * 		<li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching with the corresponding
+	 * 			element. In case the element is a method, declarations of matching methods in subtypes will also
+	 *  		be found, allowing to find declarations of abstract methods, etc.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or references as specified
+	 *  		above.</li>
+	 *
+	 *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for types, will find all types
+	 *				which directly implement/extend a given interface.</li>
+	 *	</ul>
+	 * @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
+	 * @deprecated Use {@link SearchPattern#createPattern(IJavaElement, int)} instead.
+	 */
+	public static ISearchPattern createSearchPattern(IJavaElement element, int limitTo) {
+		return new SearchPatternAdapter(SearchPattern.createPattern(element, limitTo));
+	}
+
+	/**
+	 * Create a type name match on a given type with specific modifiers.
+	 *
+	 * @param type The java model handle of the type
+	 * @param modifiers Modifiers of the type
+	 * @return A non-null match on the given type.
+	 * @since 3.3
+	 */
+	public static TypeNameMatch createTypeNameMatch(IType type, int modifiers) {
+		return BasicSearchEngine.createTypeNameMatch(type, modifiers);
+	}
+
+	/**
+	 * Returns a Java search scope with the workspace as the only limit.
+	 *
+	 * @return a new workspace scope
+	 */
+	public static IJavaSearchScope createWorkspaceScope() {
+		return BasicSearchEngine.createWorkspaceScope();
+	}
+	/**
+	 * Returns a new default Java search participant.
+	 *
+	 * @return a new default Java search participant
+	 * @since 3.0
+	 */
+	public static SearchParticipant getDefaultSearchParticipant() {
+		return BasicSearchEngine.getDefaultSearchParticipant();
+	}
+
+	/**
+	 * Searches for the Java element determined by the given signature. The signature
+	 * can be incomplete. For example, a call like
+	 * <code>search(ws, "run()", METHOD,REFERENCES, col)</code>
+	 * searches for all references to the method <code>run</code>.
+	 *
+	 * Note that by default the pattern will be case insensitive. For specifying case s
+	 * sensitive search, use <code>search(workspace, createSearchPattern(patternString, searchFor, limitTo, true), scope, resultCollector);</code>
+	 *
+	 * @param workspace the workspace
+	 * @param patternString the pattern to be searched for
+	 * @param searchFor a hint what kind of Java element the string pattern represents.
+	 *  Look into {@link IJavaSearchConstants} for valid values
+	 * @param limitTo one of the following values:
+	 *	<ul>
+	 *	  <li>{@link IJavaSearchConstants#DECLARATIONS}: search
+	 *		  for declarations only </li>
+	 *	  <li>{@link IJavaSearchConstants#REFERENCES}: search
+	 *		  for all references </li>
+	 *	  <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: search
+	 *		  for both declarations and all references </li>
+	 *	  <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for types, will find all types
+	 *			which directly implement/extend a given interface.<br>
+	 *			Note that types may be only classes or only interfaces if respectively {@link IJavaSearchConstants#CLASS} or
+	 *			{@link IJavaSearchConstants#INTERFACE} is used for searchFor parameter instead of {@link IJavaSearchConstants#TYPE}.
+	 *	  </li>
+	 * </ul>
+	 * @param scope the search result has to be limited to the given scope
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link  #search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void search(IWorkspace workspace, String patternString, int searchFor, int limitTo, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		try {
+			int matchMode = patternString.indexOf('*') != -1 || patternString.indexOf('?') != -1
+				? SearchPattern.R_PATTERN_MATCH
+				: SearchPattern.R_EXACT_MATCH;
+			search(
+				SearchPattern.createPattern(patternString, searchFor, limitTo, matchMode | SearchPattern.R_CASE_SENSITIVE),
+				new SearchParticipant[] {getDefaultSearchParticipant()},
+				scope,
+				new ResultCollectorAdapter(resultCollector),
+				resultCollector.getProgressMonitor());
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException)
+				throw (JavaModelException) e;
+			throw new JavaModelException(e);
+		}
+	}
+
+	/**
+	 * Searches for the given Java element.
+	 *
+	 * @param workspace the workspace
+	 * @param element the Java element to be searched for
+	 * @param limitTo one of the following values:
+	 *	<ul>
+	 *	  <li>{@link IJavaSearchConstants#DECLARATIONS}: search
+	 *		  for declarations only </li>
+	 *	  <li>{@link IJavaSearchConstants#REFERENCES}: search
+	 *		  for all references </li>
+	 *	  <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: search
+	 *		  for both declarations and all references </li>
+	 *	  <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for types, will find all types
+	 *				which directly implement/extend a given interface.</li>
+	 * 	</ul>
+	 * @param scope the search result has to be limited to the given scope
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link #search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void search(IWorkspace workspace, IJavaElement element, int limitTo, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		search(workspace, createSearchPattern(element, limitTo), scope, resultCollector);
+	}
+
+	/**
+	 * Searches for matches of a given search pattern. Search patterns can be created using helper
+	 * methods (from a String pattern or a Java element) and encapsulate the description of what is
+	 * being searched (for example, search method declarations in a case sensitive way).
+	 *
+	 * @param workspace the workspace
+	 * @param searchPattern the pattern to be searched for
+	 * @param scope the search result has to be limited to the given scope
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link  #search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void search(IWorkspace workspace, ISearchPattern searchPattern, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		try {
+			search(
+				((SearchPatternAdapter)searchPattern).pattern,
+				new SearchParticipant[] {getDefaultSearchParticipant()},
+				scope,
+				new ResultCollectorAdapter(resultCollector),
+				resultCollector.getProgressMonitor());
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException)
+				throw (JavaModelException) e;
+			throw new JavaModelException(e);
+		}
+	}
+
+	/**
+	 * Searches for matches of a given search pattern. Search patterns can be created using helper
+	 * methods (from a String pattern or a Java element) and encapsulate the description of what is
+	 * being searched (for example, search method declarations in a case sensitive way).
+	 *
+	 * @param pattern the pattern to search
+	 * @param participants the participants in the search
+	 * @param scope the search scope
+	 * @param requestor the requestor to report the matches to
+	 * @param monitor the progress monitor used to report progress
+	 * @exception CoreException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 *@since 3.0
+	 */
+	public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+		this.basicEngine.search(pattern, participants, scope, requestor, monitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package exact full name or
+	 * a type name with specific match mode).
+	 *
+	 * @param packageExactName the exact package full name of the searched types.<br>
+	 * 					If you want to use a prefix or a wild-carded string for package, you need to use
+	 * 					{@link #searchAllTypeNames(char[], int, char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)}
+	 * 					method  instead. May be <code>null</code>, then any package name is accepted.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 *					May be <code>null</code>, then any type name is accepted.
+	 * @param matchRule type name match rule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type
+	 *			name are the full names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type
+	 *			name are prefixes of the names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and
+	 *			type name contain wild-cards.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if the type name is a
+	 *			camel case of the searched types name.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH}
+	 *			if the type name is a camel case with same part count of the searched
+	 *			types name.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param searchFor determines the nature of the searched elements
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+	 *		<li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+	 * 	<li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+	 *		<li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for all types (i.e. classes, interfaces, enum and annotation types)</li>
+	 *	</ul>
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.1
+	 * @deprecated Use {@link #searchAllTypeNames(char[], int, char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)}
+	 * 	instead
+	 */
+	public void searchAllTypeNames(
+		final char[] packageExactName,
+		final char[] typeName,
+		final int matchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final TypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		searchAllTypeNames(packageExactName, SearchPattern.R_EXACT_MATCH, typeName, matchRule, searchFor, scope, nameRequestor, waitingPolicy, progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package name using specific match mode
+	 * and/or a type name using another specific match mode).
+	 *
+	 * @param packageName the full name of the package of the searched types, or a prefix for this
+	 *						package, or a wild-carded string for this package.
+	 *						May be <code>null</code>, then any package name is accepted.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 *					May be <code>null</code>, then any type name is accepted.
+	 * @param packageMatchRule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type
+	 *			name are the full names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type
+	 *			name are prefixes of the names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and
+	 *			type name contain wild-cards.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if the package name is a
+	 *			camel case of the searched types package name.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH}
+	 *			if the package name is a camel case with same part count of the searched
+	 *			types package name.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param typeMatchRule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type
+	 *			name are the full names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type
+	 *			name are prefixes of the names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and
+	 *			type name contain wild-cards.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if the type name is a
+	 *			camel case of the searched types name.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH}
+	 *			if the type name is a camel case with same part count of the searched
+	 *			types name.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param searchFor determines the nature of the searched elements
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+	 *		<li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+	 * 	<li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+	 *		<li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for all types (i.e. classes, interfaces, enum and annotation types)</li>
+	 *	</ul>
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.3
+	 */
+	public void searchAllTypeNames(
+		final char[] packageName,
+		final int packageMatchRule,
+		final char[] typeName,
+		final int typeMatchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final TypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
+		this.basicEngine.searchAllTypeNames(packageName,
+			packageMatchRule,
+			typeName,
+			typeMatchRule,
+			searchFor,
+			scope,
+			requestorWrapper,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package name using specific match mode
+	 * and/or a type name using another specific match mode).
+	 * <p>
+	 * Provided {@link TypeNameMatchRequestor} requestor will collect {@link TypeNameMatch}
+	 * matches found during the search.
+	 * </p>
+	 *
+	 * @param packageName the full name of the package of the searched types, or a prefix for this
+	 *						package, or a wild-carded string for this package.
+	 *						May be <code>null</code>, then any package name is accepted.
+	 * @param packageMatchRule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type
+	 *			name are the full names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type
+	 *			name are prefixes of the names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and
+	 *			type name contain wild-cards.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if the package name is a
+	 *			camel case of the searched types package name.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH}
+	 *			if the package name is a camel case with same part count of the searched
+	 *			types package name.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 *					May be <code>null</code>, then any type name is accepted.
+	 * @param typeMatchRule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type
+	 *			name are the full names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type
+	 *			name are prefixes of the names of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and
+	 *			type name contain wild-cards.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_MATCH} if the type name is a
+	 *			camel case of the searched types name.</li>
+	 *		<li>{@link SearchPattern#R_CAMELCASE_SAME_PART_COUNT_MATCH}
+	 *			if the type name is a camel case with same part count of the searched
+	 *			types name.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param searchFor determines the nature of the searched elements
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+	 *		<li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+	 * 	<li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+	 *		<li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for all types (i.e. classes, interfaces, enum and annotation types)</li>
+	 *	</ul>
+	 * @param scope the scope to search in
+	 * @param nameMatchRequestor the {@link TypeNameMatchRequestor requestor} that collects
+	 * 				{@link TypeNameMatch matches} of the search.
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.3
+	 */
+	public void searchAllTypeNames(
+		final char[] packageName,
+		final int packageMatchRule,
+		final char[] typeName,
+		final int typeMatchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final TypeNameMatchRequestor nameMatchRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameMatchRequestorWrapper requestorWrapper = new TypeNameMatchRequestorWrapper(nameMatchRequestor, scope);
+		this.basicEngine.searchAllTypeNames(packageName,
+			packageMatchRule,
+			typeName,
+			typeMatchRule,
+			searchFor,
+			scope,
+			requestorWrapper,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope matching any of the given qualifications
+	 * and type names in a case sensitive way.
+	 *
+	 * @param qualifications the qualified name of the package/enclosing type of the searched types.
+	 *					May be <code>null</code>, then any package name is accepted.
+	 * @param typeNames the simple names of the searched types.
+	 *					If this parameter is <code>null</code>, then no type will be found.
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.1
+	 */
+	public void searchAllTypeNames(
+		final char[][] qualifications,
+		final char[][] typeNames,
+		IJavaSearchScope scope,
+		final TypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
+		this.basicEngine.searchAllTypeNames(
+			qualifications,
+			typeNames,
+			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
+			IJavaSearchConstants.TYPE,
+			scope,
+			requestorWrapper,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope matching any of the given qualifications
+	 * and type names in a case sensitive way.
+	 * <p>
+	 * Provided {@link TypeNameMatchRequestor} requestor will collect {@link TypeNameMatch}
+	 * matches found during the search.
+	 * </p>
+	 *
+	 * @param qualifications the qualified name of the package/enclosing type of the searched types.
+	 *					May be <code>null</code>, then any package name is accepted.
+	 * @param typeNames the simple names of the searched types.
+	 *					If this parameter is <code>null</code>, then no type will be found.
+	 * @param scope the scope to search in
+	 * @param nameMatchRequestor the {@link TypeNameMatchRequestor requestor} that collects
+	 * 				{@link TypeNameMatch matches} of the search.
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.3
+	 */
+	public void searchAllTypeNames(
+		final char[][] qualifications,
+		final char[][] typeNames,
+		IJavaSearchScope scope,
+		final TypeNameMatchRequestor nameMatchRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameMatchRequestorWrapper requestorWrapper = new TypeNameMatchRequestorWrapper(nameMatchRequestor, scope);
+		this.basicEngine.searchAllTypeNames(
+			qualifications,
+			typeNames,
+			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
+			IJavaSearchConstants.TYPE,
+			scope,
+			requestorWrapper,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package or a type name
+	 * prefix and match modes).
+	 *
+	 * @param packageName the full name of the package of the searched types, or a prefix for this
+	 *						package, or a wild-carded string for this package.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 * @param matchRule one of
+	 * <ul>
+	 *		<li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
+	 *			of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
+	 *			of the searched types.</li>
+	 *		<li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
+	 * </ul>
+	 * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+	 *   e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+	 *   or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+	 * @param searchFor one of
+	 * <ul>
+	 * 		<li>{@link IJavaSearchConstants#CLASS} if searching for classes only</li>
+	 * 		<li>{@link IJavaSearchConstants#INTERFACE} if searching for interfaces only</li>
+	 * 		<li>{@link IJavaSearchConstants#TYPE} if searching for both classes and interfaces</li>
+	 * </ul>
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.0
+	 *@deprecated Use {@link #searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)} instead
+	 */
+	public void searchAllTypeNames(
+		final char[] packageName,
+		final char[] typeName,
+		final int matchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final ITypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameRequestorAdapter requestorAdapter = new TypeNameRequestorAdapter(nameRequestor);
+		this.basicEngine.searchAllTypeNames(packageName, SearchPattern.R_EXACT_MATCH, typeName, matchRule, searchFor, scope, requestorAdapter, waitingPolicy, progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package or a type name
+	 * prefix and match modes).
+	 *
+	 * @param workspace the workspace to search in
+	 * @param packageName the full name of the package of the searched types, or a prefix for this
+	 *						package, or a wild-carded string for this package.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 * @param matchMode one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#EXACT_MATCH} if the package name and type name are the full names
+	 *			of the searched types.</li>
+	 *		<li>{@link IJavaSearchConstants#PREFIX_MATCH} if the package name and type name are prefixes of the names
+	 *			of the searched types.</li>
+	 *		<li>{@link IJavaSearchConstants#PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
+	 * </ul>
+	 * @param isCaseSensitive whether the search should be case sensitive
+	 * @param searchFor one of
+	 * <ul>
+	 * 		<li>{@link IJavaSearchConstants#CLASS} if searching for classes only</li>
+	 * 		<li>{@link IJavaSearchConstants#INTERFACE} if searching for interfaces only</li>
+	 * 		<li>{@link IJavaSearchConstants#TYPE} if searching for both classes and interfaces</li>
+	 * </ul>
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+	 *		<li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 *@deprecated Use {@link #searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, ITypeNameRequestor, int, IProgressMonitor)} instead
+	 */
+	public void searchAllTypeNames(
+		IWorkspace workspace,
+		final char[] packageName,
+		final char[] typeName,
+		final int matchMode,
+		final boolean isCaseSensitive,
+		int searchFor,
+		IJavaSearchScope scope,
+		final ITypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		searchAllTypeNames(
+			packageName,
+			typeName,
+			isCaseSensitive ? matchMode | SearchPattern.R_CASE_SENSITIVE : matchMode,
+			searchFor,
+			scope,
+			nameRequestor,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all declarations of the fields accessed in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the field declarations using the given requestor.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *			int field1;
+	 *		}
+	 *		class B extends A {
+	 *			String value;
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				B b = new B();
+	 *				System.out.println(b.value + b.field1);
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of accessed fields in method
+	 * <code>X.test()</code> would collect the fields
+	 * <code>B.value</code> and <code>A.field1</code>.
+	 * </p>
+	 *
+	 * @param enclosingElement the field, method, type, or compilation unit to be searched in
+	 * @param requestor a callback object to which each match is reported
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 *@exception IllegalArgumentException if the given java element has not the right type
+	 * @since 3.0
+	 */
+	public void searchDeclarationsOfAccessedFields(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		this.basicEngine.searchDeclarationsOfAccessedFields(enclosingElement, requestor, monitor);
+	}
+
+	/**
+	 * Searches for all declarations of the fields accessed in the given element.
+	 * The element can be a compilation unit, a source type, or a source method.
+	 * Reports the field declarations using the given collector.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *			int field1;
+	 *		}
+	 *		class B extends A {
+	 *			String value;
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				B b = new B();
+	 *				System.out.println(b.value + b.field1);
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of accessed fields in method
+	 * <code>X.test()</code> would collect the fields
+	 * <code>B.value</code> and <code>A.field1</code>.
+	 * </p>
+	 *
+	 * @param workspace the workspace
+	 * @param enclosingElement the method, type, or compilation unit to be searched in
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link  #searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void searchDeclarationsOfAccessedFields(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement);
+		this.basicEngine.searchDeclarations(enclosingElement, new ResultCollectorAdapter(resultCollector), pattern, resultCollector.getProgressMonitor());
+	}
+
+	/**
+	 * Searches for all declarations of the types referenced in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the type declarations using the given requestor.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *		}
+	 *		class B extends A {
+	 *		}
+	 *		interface I {
+	 *		  int VALUE = 0;
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				B b = new B();
+	 *				this.foo(b, I.VALUE);
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of referenced types in method <code>X.test()</code>
+	 * would collect the class <code>B</code> and the interface <code>I</code>.
+	 * </p>
+	 *
+	 * @param enclosingElement the field, method, type, or compilation unit to be searched in
+	 * @param requestor a callback object to which each match is reported
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 *@exception IllegalArgumentException if the given java element has not the right type
+	 * @since 3.0
+	 */
+	public void searchDeclarationsOfReferencedTypes(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		this.basicEngine.searchDeclarationsOfReferencedTypes(enclosingElement, requestor, monitor);
+	}
+
+	/**
+	 * Searches for all declarations of the types referenced in the given element.
+	 * The element can be a compilation unit, a source type, or a source method.
+	 * Reports the type declarations using the given collector.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *		}
+	 *		class B extends A {
+	 *		}
+	 *		interface I {
+	 *		  int VALUE = 0;
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				B b = new B();
+	 *				this.foo(b, I.VALUE);
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of referenced types in method <code>X.test()</code>
+	 * would collect the class <code>B</code> and the interface <code>I</code>.
+	 * </p>
+	 *
+	 * @param workspace the workspace
+	 * @param enclosingElement the method, type, or compilation unit to be searched in
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link #searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void searchDeclarationsOfReferencedTypes(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement);
+		this.basicEngine.searchDeclarations(enclosingElement, new ResultCollectorAdapter(resultCollector), pattern, resultCollector.getProgressMonitor());
+	}
+
+	/**
+	 * Searches for all declarations of the methods invoked in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the method declarations using the given requestor.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *			void foo() {};
+	 *			void bar() {};
+	 *		}
+	 *		class B extends A {
+	 *			void foo() {};
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				A a = new B();
+	 *				a.foo();
+	 *				B b = (B)a;
+	 *				b.bar();
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of sent messages in method
+	 * <code>X.test()</code> would collect the methods
+	 * <code>A.foo()</code>, <code>B.foo()</code>, and <code>A.bar()</code>.
+	 * </p>
+	 *
+	 * @param enclosingElement the field, method, type or compilation unit to be searched in
+	 * @param requestor a callback object to which each match is reported
+	 * @param monitor the progress monitor used to report progress
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 *@exception IllegalArgumentException if the given java element has not the right type
+	 * @since 3.0
+	 */
+	public void searchDeclarationsOfSentMessages(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		this.basicEngine.searchDeclarationsOfSentMessages(enclosingElement, requestor, monitor);
+	}
+
+	/**
+	 * Searches for all declarations of the methods invoked in the given element.
+	 * The element can be a compilation unit, a source type, or a source method.
+	 * Reports the method declarations using the given collector.
+	 * <p>
+	 * Consider the following code:
+	 * <code>
+	 * <pre>
+	 *		class A {
+	 *			void foo() {};
+	 *			void bar() {};
+	 *		}
+	 *		class B extends A {
+	 *			void foo() {};
+	 *		}
+	 *		class X {
+	 *			void test() {
+	 *				A a = new B();
+	 *				a.foo();
+	 *				B b = (B)a;
+	 *				b.bar();
+	 *			};
+	 *		}
+	 * </pre>
+	 * </code>
+	 * then searching for declarations of sent messages in method
+	 * <code>X.test()</code> would collect the methods
+	 * <code>A.foo()</code>, <code>B.foo()</code>, and <code>A.bar()</code>.
+	 * </p>
+	 *
+	 * @param workspace the workspace
+	 * @param enclosingElement the method, type, or compilation unit to be searched in
+	 * @param resultCollector a callback object to which each match is reported
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the element doesn't exist</li>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @deprecated Use {@link #searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, IProgressMonitor)} instead.
+	 */
+	public void searchDeclarationsOfSentMessages(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException {
+		SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement);
+		this.basicEngine.searchDeclarations(enclosingElement, new ResultCollectorAdapter(resultCollector), pattern, resultCollector.getProgressMonitor());
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
new file mode 100644
index 0000000..ccaa772
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.core.JavaElement;
+
+/**
+ * A search match represents the result of a search query.
+ *
+ * Search matches may be accurate (<code>A_ACCURATE</code>) or they might be
+ * merely potential matches (<code>A_INACCURATE</code>). The latter occurs when
+ * a compile-time problem prevents the search engine from completely resolving
+ * the match.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @see SearchEngine#search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, org.eclipse.core.runtime.IProgressMonitor)
+ * @since 3.0
+ */
+public class SearchMatch {
+
+	/**
+	 * The search result corresponds an exact match of the search pattern.
+	 *
+	 * @see #getAccuracy()
+	 */
+	public static final int A_ACCURATE = 0;
+
+	/**
+	 * The search result is potentially a match for the search pattern,
+	 * but the search engine is unable to fully check it (for example, because
+	 * there are errors in the code or the classpath are not correctly set).
+	 *
+	 * @see #getAccuracy()
+	 */
+	public static final int A_INACCURATE = 1;
+
+	private Object element;
+	private int length;
+	private int offset;
+
+	private int accuracy;
+	private SearchParticipant participant;
+	private IResource resource;
+
+	private boolean insideDocComment = false;
+
+	// store the rule used while reporting the match
+	private final static int ALL_GENERIC_FLAVORS = SearchPattern.R_FULL_MATCH |
+								SearchPattern.R_EQUIVALENT_MATCH |
+								SearchPattern.R_ERASURE_MATCH;
+	private int rule = ALL_GENERIC_FLAVORS;
+
+	// store other necessary information
+	private boolean raw = false;
+	private boolean implicit = false;
+
+	/**
+	 * Creates a new search match.
+	 * <p>
+	 * Note that <code>isInsideDocComment()</code> defaults to false.
+	 * </p>
+	 *
+	 * @param element the element that encloses or corresponds to the match,
+	 * or <code>null</code> if none
+	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element, or <code>null</code> if none
+	 */
+	public SearchMatch(
+			IJavaElement element,
+			int accuracy,
+			int offset,
+			int length,
+			SearchParticipant participant,
+			IResource resource) {
+		this.element = element;
+		this.offset = offset;
+		this.length = length;
+		this.accuracy = accuracy & A_INACCURATE;
+		if (accuracy > A_INACCURATE) {
+			int genericFlavors = accuracy & ALL_GENERIC_FLAVORS;
+			if (genericFlavors > 0) {
+				this.rule &= ~ALL_GENERIC_FLAVORS; // reset generic flavors
+			}
+			this.rule |= accuracy & ~A_INACCURATE; // accuracy may have also some rule information
+		}
+		this.participant = participant;
+		this.resource = resource;
+	}
+
+	/**
+	 * Returns the accuracy of this search match.
+	 *
+	 * @return one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 */
+	public final int getAccuracy() {
+		return this.accuracy;
+	}
+
+	/**
+	 * Returns the element of this search match.
+	 * In case of a reference match, this is the inner-most enclosing element of the reference.
+	 * In case of a declaration match, this is the declaration.
+	 *
+	 * @return the element of the search match, or <code>null</code> if none
+	 */
+	public final Object getElement() {
+		return this.element;
+	}
+
+	/**
+	 * Returns the length of this search match.
+	 *
+	 * @return the length of this search match, or -1 if unknown
+	 */
+	public final int getLength() {
+		return this.length;
+	}
+
+	/**
+	 * Returns the offset of this search match.
+	 *
+	 * @return the offset of this search match, or -1 if unknown
+	 */
+	public final int getOffset() {
+		return this.offset;
+	}
+
+	/**
+	 * Returns the search participant which issued this search match.
+	 *
+	 * @return the participant which issued this search match
+	 */
+	public final SearchParticipant getParticipant() {
+		return this.participant;
+	}
+
+	/**
+	 * Returns the resource containing this search match.
+	 *
+	 * @return the resource of the match, or <code>null</code> if none
+	 */
+	public final IResource getResource() {
+		return this.resource;
+	}
+
+	/**
+	 * Returns the rule used while creating the match.
+	 *
+	 * @return one of {@link SearchPattern#R_FULL_MATCH}, {@link SearchPattern#R_EQUIVALENT_MATCH}
+	 * 	or {@link SearchPattern#R_ERASURE_MATCH}
+	 * @since 3.1
+	 */
+	public final int getRule() {
+		return this.rule;
+	}
+
+	/**
+	 * Returns whether match element is compatible with searched pattern or not.
+	 * Note that equivalent matches are also erasure ones.
+	 *
+	 * @return <code>true</code> if match element is compatible
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isEquivalent() {
+		return isErasure() && (this.rule & SearchPattern.R_EQUIVALENT_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether match element only has same erasure than searched pattern or not.
+	 * Note that this is always true for both generic and non-generic element as soon
+	 * as the accuracy is accurate.
+	 *
+	 * @return <code>true</code> if match element has same erasure
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isErasure() {
+		return (this.rule & SearchPattern.R_ERASURE_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether element matches exactly searched pattern or not.
+	 * Note that exact matches are also erasure and equivalent ones.
+	 *
+	 * @return <code>true</code> if match is exact
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isExact() {
+		return isEquivalent() && (this.rule & SearchPattern.R_FULL_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether the associated element is implicit or not.
+	 *
+	 * Note that this piece of information is currently only implemented
+	 * for implicit member pair value in annotation.
+	 *
+	 * @return <code>true</code> if this match is associated to an implicit
+	 * element and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isImplicit() {
+		return this.implicit;
+	}
+
+	/**
+	 * Returns whether the associated element is a raw type/method or not.
+	 *
+	 * @return <code>true</code> if this match is associated to a raw
+	 * type or method and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isRaw() {
+		return this.raw;
+	}
+
+	/**
+	 * Returns whether this search match is inside a doc comment of a Java
+	 * source file.
+	 *
+	 * @return <code>true</code> if this search match is inside a doc
+	 * comment, and <code>false</code> otherwise
+	 */
+	public final boolean isInsideDocComment() {
+		// default is outside a doc comment
+		return this.insideDocComment;
+	}
+
+	/**
+	 * Sets the accuracy of this match.
+	 *
+	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 */
+	public final void setAccuracy (int accuracy) {
+		this.accuracy = accuracy;
+	}
+
+	/**
+	 * Sets the element of this search match.
+	 *
+	 * @param element the element that encloses or corresponds to the match,
+	 * or <code>null</code> if none
+	 */
+	public final void setElement (Object element) {
+		this.element = element;
+	}
+
+	/**
+	 * Sets whether this search match is inside a doc comment of a Java
+	 * source file.
+	 *
+	 * @param insideDoc <code>true</code> if this search match is inside a doc
+	 * comment, and <code>false</code> otherwise
+	 */
+	public final void setInsideDocComment (boolean insideDoc) {
+		this.insideDocComment = insideDoc;
+	}
+
+	/**
+	 * Sets whether the associated element is implicit or not.
+	 * Typically, this is the case when match is on an implicit constructor
+	 * or an implicit member pair value in annotation.
+	 *
+	 * @param implicit <code>true</code> if this match is associated to an implicit
+	 * element and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final void setImplicit(boolean implicit) {
+		this.implicit = implicit;
+	}
+
+	/**
+	 * Sets the length of this search match.
+	 *
+	 * @param length the length of the match, or -1 if unknown
+	 */
+	public final void setLength(int length) {
+		this.length = length;
+	}
+
+	/**
+	 * Sets the offset of this search match.
+	 *
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 */
+	public final void setOffset(int offset) {
+		this.offset = offset;
+	}
+
+	/**
+	 * Sets the participant of this match.
+	 *
+	 * @param participant the search participant that created this match
+	 */
+	public final void setParticipant (SearchParticipant participant) {
+		this.participant = participant;
+	}
+
+	/**
+	 * Sets the resource of this match.
+	 *
+	 * @param resource the resource of the match, or <code>null</code> if none
+	 */
+	public final void setResource (IResource resource) {
+		this.resource = resource;
+	}
+
+	/**
+	 * Set the rule used while reporting the match.
+	 *
+	 * @param rule one of {@link SearchPattern#R_FULL_MATCH}, {@link SearchPattern#R_EQUIVALENT_MATCH}
+	 * 	or {@link SearchPattern#R_ERASURE_MATCH}
+	 * @since 3.1
+	 */
+	public final void setRule(int rule) {
+		this.rule = rule;
+	}
+
+	/**
+	 * Set whether the associated element is a raw type/method or not.
+	 *
+	 * @param raw <code>true</code> if this search match is associated to a raw
+	 * type or method and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final void setRaw(boolean raw) {
+		this.raw = raw;
+	}
+
+	/* (non-javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("Search match"); //$NON-NLS-1$
+		buffer.append("\n  accuracy="); //$NON-NLS-1$
+		buffer.append(this.accuracy == A_ACCURATE ? "ACCURATE" : "INACCURATE"); //$NON-NLS-1$ //$NON-NLS-2$
+		buffer.append("\n  rule="); //$NON-NLS-1$
+		if ((this.rule & SearchPattern.R_FULL_MATCH) != 0) {
+			buffer.append("EXACT"); //$NON-NLS-1$
+		} else if ((this.rule & SearchPattern.R_EQUIVALENT_MATCH) != 0) {
+			buffer.append("EQUIVALENT"); //$NON-NLS-1$
+		} else if ((this.rule & SearchPattern.R_ERASURE_MATCH) != 0) {
+			buffer.append("ERASURE"); //$NON-NLS-1$
+		}
+		buffer.append("\n  raw="); //$NON-NLS-1$
+		buffer.append(this.raw);
+		buffer.append("\n  offset="); //$NON-NLS-1$
+		buffer.append(this.offset);
+		buffer.append("\n  length="); //$NON-NLS-1$
+		buffer.append(this.length);
+		if (this.element != null) {
+			buffer.append("\n  element="); //$NON-NLS-1$
+			buffer.append(((JavaElement)getElement()).toStringWithAncestors());
+		}
+		buffer.append("\n"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
new file mode 100644
index 0000000..15155e4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.index.FileIndexLocation;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+
+/**
+ * A search participant describes a particular extension to a generic search
+ * mechanism, permitting combined search actions which will involve all required
+ * participants.
+ * <p>
+ * A search participant is involved in the indexing phase and in the search phase.
+ * The indexing phase consists in taking one or more search documents, parse them, and
+ * add index entries in an index chosen by the participant. An index is identified by a
+ * path on disk.
+ * The search phase consists in selecting the indexes corresponding to a search pattern
+ * and a search scope, from these indexes the search infrastructure extracts the document paths
+ * that match the search pattern asking the search participant for the corresponding document,
+ * finally the search participant is asked to locate the matches precisely in these search documents.
+ * </p>
+ * <p>
+ * This class is intended to be subclassed by clients. During the indexing phase,
+ * a subclass will be called with the following requests in order:
+ * <ul>
+ * <li>{@link #scheduleDocumentIndexing(SearchDocument, IPath)}</li>
+ * <li>{@link #indexDocument(SearchDocument, IPath)}</li>
+ * </ul>
+ * During the search phase, a subclass will be called with the following requests in order:
+ * <ul>
+ * <li>{@link #selectIndexes(SearchPattern, IJavaSearchScope)}</li>
+ * <li>one or more {@link #getDocument(String)}</li>
+ * <li>{@link #locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor)}</li>
+ * </ul>
+ * </p>
+ *
+ * @since 3.0
+ */
+public abstract class SearchParticipant {
+
+	private IPath lastIndexLocation;
+
+	/**
+	 * Creates a new search participant.
+	 */
+	protected SearchParticipant() {
+		// do nothing
+	}
+
+	/**
+	 * Notification that this participant's help is needed in a search.
+	 * <p>
+	 * This method should be re-implemented in subclasses that need to do something
+	 * when the participant is needed in a search.
+	 * </p>
+	 */
+	public void beginSearching() {
+		// do nothing
+	}
+
+	/**
+	 * Notification that this participant's help is no longer needed.
+	 * <p>
+	 * This method should be re-implemented in subclasses that need to do something
+	 * when the participant is no longer needed in a search.
+	 * </p>
+	 */
+	public void doneSearching() {
+		// do nothing
+	}
+
+	/**
+	 * Returns a displayable name of this search participant.
+	 * <p>
+	 * This method should be re-implemented in subclasses that need to
+	 * display a meaningful name.
+	 * </p>
+	 *
+	 * @return the displayable name of this search participant
+	 */
+	public String getDescription() {
+		return "Search participant"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns a search document for the given path.
+	 * The given document path is a string that uniquely identifies the document.
+	 * Most of the time it is a workspace-relative path, but it can also be a file system path, or a path inside a zip file.
+	 * <p>
+	 * Implementors of this method can either create an instance of their own subclass of
+	 * {@link SearchDocument} or return an existing instance of such a subclass.
+	 * </p>
+	 *
+	 * @param documentPath the path of the document.
+	 * @return a search document
+	 */
+	public abstract SearchDocument getDocument(String documentPath);
+
+	/**
+	 * Indexes the given document in the given index. A search participant
+	 * asked to index a document should parse it and call
+	 * {@link SearchDocument#addIndexEntry(char[], char[])} as many times as
+	 * needed to add index entries to the index. If delegating to another
+	 * participant, it should use the original index location (and not the
+	 * delegatee's one). In the particular case of delegating to the default
+	 * search participant (see {@link SearchEngine#getDefaultSearchParticipant()}),
+	 * the provided document's path must be a path ending with one of the
+	 * {@link org.eclipse.jdt.core.JavaCore#getJavaLikeExtensions() Java-like extensions}
+	 * or with '.class'.
+	 * <p>
+	 * The given index location must represent a path in the file system to a file that
+	 * either already exists or is going to be created. If it exists, it must be an index file,
+	 * otherwise its data might be overwritten.
+	 * </p><p>
+	 * Clients are not expected to call this method.
+	 * </p>
+	 *
+	 * @param document the document to index
+	 * @param indexLocation the location in the file system to the index
+	 */
+	public abstract void indexDocument(SearchDocument document, IPath indexLocation);
+
+	/**
+	 * Locates the matches in the given documents using the given search pattern
+	 * and search scope, and reports them to the given search requestor. This
+	 * method is called by the search engine once it has search documents
+	 * matching the given pattern in the given search scope.
+	 * <p>
+	 * Note that a participant (e.g. a JSP participant) can pre-process the contents of the given documents,
+	 * create its own documents whose contents are Java compilation units and delegate the match location
+	 * to the default participant (see {@link SearchEngine#getDefaultSearchParticipant()}). Passing its own
+	 * {@link SearchRequestor} this participant can then map the match positions back to the original
+	 * contents, create its own matches and report them to the original requestor.
+	 * </p><p>
+	 * Implementors of this method should check the progress monitor
+	 * for cancelation when it is safe and appropriate to do so.  The cancelation
+	 * request should be propagated to the caller by throwing
+	 * <code>OperationCanceledException</code>.
+	 * </p>
+	 *
+	 * @param documents the documents to locate matches in
+	 * @param pattern the search pattern to use when locating matches
+	 * @param scope the scope to limit the search to
+	 * @param requestor the requestor to report matches to
+	 * @param monitor the progress monitor to report progress to,
+	 * or <code>null</code> if no progress should be reported
+	 * @throws CoreException if the requestor had problem accepting one of the matches
+	 */
+	public abstract void locateMatches(SearchDocument[] documents, SearchPattern pattern, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException;
+
+	/**
+	 * Removes the index for a given path.
+	 * <p>
+	 * The given index location must represent a path in the file system to a file that
+	 * already exists and must be an index file, otherwise nothing will be done.
+	 * </p><p>
+	 * It is strongly recommended to use this method instead of deleting file directly
+	 * otherwise cached index will not be removed.
+	 * </p>
+	 *
+	 * @param indexLocation the location in the file system to the index
+	 * @since 3.2
+	 */
+	public void removeIndex(IPath indexLocation){
+		IndexManager manager = JavaModelManager.getIndexManager();
+		manager.removeIndexPath(indexLocation);
+	}
+
+	/**
+	 * Schedules the indexing of the given document.
+	 * Once the document is ready to be indexed,
+	 * {@link #indexDocument(SearchDocument, IPath) indexDocument(document, indexPath)}
+	 * will be called in a different thread than the caller's thread.
+	 * <p>
+	 * The given index location must represent a path in the file system to a file that
+	 * either already exists or is going to be created. If it exists, it must be an index file,
+	 * otherwise its data might be overwritten.
+	 * </p><p>
+	 * When the index is no longer needed, clients should use {@link #removeIndex(IPath) }
+	 * to discard it.
+	 * </p>
+	 *
+	 * @param document the document to index
+	 * @param indexPath the location on the file system of the index
+	 */
+	public final void scheduleDocumentIndexing(SearchDocument document, IPath indexPath) {
+		IPath documentPath = new Path(document.getPath());
+		Object file = JavaModel.getTarget(documentPath, true);
+		IPath containerPath = documentPath;
+		if (file instanceof IResource) {
+			containerPath = ((IResource)file).getProject().getFullPath();
+		} else if (file == null) {
+			containerPath = documentPath.removeLastSegments(1);
+		}
+		IndexManager manager = JavaModelManager.getIndexManager();
+		// TODO (frederic) should not have to create index manually, should expose API that recreates index instead
+		IndexLocation indexLocation;
+		indexLocation = new FileIndexLocation(indexPath.toFile(), true);
+		manager.ensureIndexExists(indexLocation, containerPath);
+		manager.scheduleDocumentIndexing(document, containerPath, indexLocation, this);
+		if (!indexPath.equals(this.lastIndexLocation)) {
+			manager.updateParticipant(indexPath, containerPath);
+			this.lastIndexLocation = indexPath;
+		}
+	}
+
+	/**
+	 * Returns the collection of index locations to consider when performing the
+	 * given search query in the given scope. The search engine calls this
+	 * method before locating matches.
+	 * <p>
+	 * An index location represents a path in the file system to a file that holds index information.
+	 * </p><p>
+	 * Clients are not expected to call this method.
+	 * </p>
+	 *
+	 * @param query the search pattern to consider
+	 * @param scope the given search scope
+	 * @return the collection of index paths to consider
+	 */
+	public abstract IPath[] selectIndexes(SearchPattern query, IJavaSearchScope scope);
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
new file mode 100644
index 0000000..bd1f4a7
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
@@ -0,0 +1,2598 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.core.LocalVariable;
+import org.eclipse.jdt.internal.core.index.EntryResult;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.HierarchyScope;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.JavaSearchScope;
+import org.eclipse.jdt.internal.core.search.StringOperation;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.search.matching.*;
+
+
+/**
+ * A search pattern defines how search results are found. Use <code>SearchPattern.createPattern</code>
+ * to create a search pattern.
+ * <p>
+ * Search patterns are used during the search phase to decode index entries that were added during the indexing phase
+ * (see {@link SearchDocument#addIndexEntry(char[], char[])}). When an index is queried, the
+ * index categories and keys to consider are retrieved from the search pattern using {@link #getIndexCategories()} and
+ * {@link #getIndexKey()}, as well as the match rule (see {@link #getMatchRule()}). A blank pattern is
+ * then created (see {@link #getBlankPattern()}). This blank pattern is used as a record as follows.
+ * For each index entry in the given index categories and that starts with the given key, the blank pattern is fed using
+ * {@link #decodeIndexKey(char[])}. The original pattern is then asked if it matches the decoded key using
+ * {@link #matchesDecodedKey(SearchPattern)}. If it matches, a search document is created for this index entry
+ * using {@link SearchParticipant#getDocument(String)}.
+ *
+ * </p><p>
+ * This class is intended to be sub-classed by clients. A default behavior is provided for each of the methods above, that
+ * clients can override if they wish.
+ * </p>
+ * @see #createPattern(org.eclipse.jdt.core.IJavaElement, int)
+ * @see #createPattern(String, int, int, int)
+ * @since 3.0
+ */
+public abstract class SearchPattern {
+
+	// Rules for pattern matching: (exact, prefix, pattern) [ | case sensitive]
+	/**
+	 * Match rule: The search pattern matches exactly the search result,
+	 * that is, the source of the search result equals the search pattern.
+	 */
+	public static final int R_EXACT_MATCH = 0;
+
+	/**
+	 * Match rule: The search pattern is a prefix of the search result.
+	 */
+	public static final int R_PREFIX_MATCH = 0x0001;
+
+	/**
+	 * Match rule: The search pattern contains one or more wild cards ('*' or '?').
+	 * A '*' wild-card can replace 0 or more characters in the search result.
+	 * A '?' wild-card replaces exactly 1 character in the search result.
+	 */
+	public static final int R_PATTERN_MATCH = 0x0002;
+
+	/**
+	 * Match rule: The search pattern contains a regular expression.
+	 * <p><b>Warning:</b> The support for this rule is <b>not yet implemented</b></p>
+	 */
+	public static final int R_REGEXP_MATCH = 0x0004;
+
+	/**
+	 * Match rule: The search pattern matches the search result only if cases are the same.
+	 * Can be combined to previous rules, e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}
+	 */
+	public static final int R_CASE_SENSITIVE = 0x0008;
+
+	/**
+	 * Match rule: The search pattern matches search results as raw/parameterized types/methods with same erasure.
+	 * This mode has no effect on other java elements search.<br>
+	 * Type search example:
+	 * 	<ul>
+	 * 	<li>pattern: <code>List&lt;Exception&gt;</code></li>
+	 * 	<li>match: <code>List&lt;Object&gt;</code></li>
+	 * 	</ul>
+	 * Method search example:
+	 * 	<ul>
+	 * 	<li>declaration: <code>&lt;T&gt;foo(T t)</code></li>
+	 * 	<li>pattern: <code>&lt;Exception&gt;foo(new Exception())</code></li>
+	 * 	<li>match: <code>&lt;Object&gt;foo(new Object())</code></li>
+	 * 	</ul>
+	 * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_ERASURE_MATCH}
+	 * This rule is not activated by default, so raw types or parameterized types with same erasure will not be found
+	 * for pattern List&lt;String&gt;,
+	 * Note that with this pattern, the match selection will be only on the erasure even for parameterized types.
+	 * @since 3.1
+	 */
+	public static final int R_ERASURE_MATCH = 0x0010;
+
+	/**
+	 * Match rule: The search pattern matches search results as raw/parameterized types/methods with equivalent type parameters.
+	 * This mode has no effect on other java elements search.<br>
+	 * Type search example:
+	 * <ul>
+	 * 	<li>pattern: <code>List&lt;Exception&gt;</code></li>
+	 * 	<li>match:
+	 * 		<ul>
+	 * 		<li><code>List&lt;? extends Throwable&gt;</code></li>
+	 * 		<li><code>List&lt;? super RuntimeException&gt;</code></li>
+	 * 		<li><code>List&lt;?&gt;</code></li>
+	 *			</ul>
+	 * 	</li>
+	 * 	</ul>
+	 * Method search example:
+	 * 	<ul>
+	 * 	<li>declaration: <code>&lt;T&gt;foo(T t)</code></li>
+	 * 	<li>pattern: <code>&lt;Exception&gt;foo(new Exception())</code></li>
+	 * 	<li>match:
+	 * 		<ul>
+	 * 		<li><code>&lt;? extends Throwable&gt;foo(new Exception())</code></li>
+	 * 		<li><code>&lt;? super RuntimeException&gt;foo(new Exception())</code></li>
+	 * 		<li><code>foo(new Exception())</code></li>
+	 *			</ul>
+	 * 	</ul>
+	 * Can be combined to all other match rules, e.g. {@link #R_CASE_SENSITIVE} | {@link #R_EQUIVALENT_MATCH}
+	 * This rule is not activated by default, so raw types or equivalent parameterized types will not be found
+	 * for pattern List&lt;String&gt;,
+	 * This mode is overridden by {@link  #R_ERASURE_MATCH} as erasure matches obviously include equivalent ones.
+	 * That means that pattern with rule set to {@link #R_EQUIVALENT_MATCH} | {@link  #R_ERASURE_MATCH}
+	 * will return same results than rule only set with {@link  #R_ERASURE_MATCH}.
+	 * @since 3.1
+	 */
+	public static final int R_EQUIVALENT_MATCH = 0x0020;
+
+	/**
+	 * Match rule: The search pattern matches exactly the search result,
+	 * that is, the source of the search result equals the search pattern.
+	 * @since 3.1
+	 */
+	public static final int R_FULL_MATCH = 0x0040;
+
+	/**
+	 * Match rule: The search pattern contains a Camel Case expression.
+	 * <p>
+	 * Examples:
+	 * <ul>
+	 * 	<li>'NPE' type string pattern will match
+	 * 		'NullPointerException' and 'NoPermissionException' types,</li>
+	 * 	<li>'NuPoEx' type string pattern will only match
+	 * 		'NullPointerException' type.</li>
+	 * </ul>
+	 *
+	 * This rule is not intended to be combined with any other match rule. In case
+	 * of other match rule flags are combined with this one, then match rule validation
+	 * will return a modified rule in order to perform a better appropriate search request
+	 * (see {@link #validateMatchRule(String, int)} for more details).
+	 * <p>
+	 * @see #camelCaseMatch(String, String) for a detailed explanation of Camel
+	 * 	Case matching.
+	 *
+	 * @since 3.2
+	 */
+	public static final int R_CAMELCASE_MATCH = 0x0080;
+
+	/**
+	 * Match rule: The search pattern contains a Camel Case expression with
+	 * a strict expected number of parts.
+	 * <br>
+	 * Examples:
+	 * <ul>
+	 * 	<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+	 * 		but not 'HashMapEntry'
+	 * 	</li>
+	 * 	<li>'HMap' type string pattern will still match previous 'HashMap' and
+	 * 		'HtmlMapper' types, but not 'HighMagnitude'
+	 * 	</li>
+	 * </ul>
+	 *
+	 * This rule is not intended to be combined with any other match rule. In case
+	 * of other match rule flags are combined with this one, then match rule validation
+	 * will return a modified rule in order to perform a better appropriate search request
+	 * (see {@link #validateMatchRule(String, int)} for more details).
+	 * <p>
+	 * @see CharOperation#camelCaseMatch(char[], char[], boolean) for a detailed
+	 * explanation of Camel Case matching.
+	 *<p>
+	 * @since 3.4
+	 */
+	public static final int R_CAMELCASE_SAME_PART_COUNT_MATCH = 0x0100;
+
+	private static final int MODE_MASK = R_EXACT_MATCH
+		| R_PREFIX_MATCH
+		| R_PATTERN_MATCH
+		| R_REGEXP_MATCH
+		| R_CAMELCASE_MATCH
+		| R_CAMELCASE_SAME_PART_COUNT_MATCH;
+
+	private int matchRule;
+
+	/**
+	 * The focus element (used for reference patterns)
+	 * @noreference This field is not intended to be referenced by clients. 
+	 */
+	public IJavaElement focus;
+
+	/**
+	 * @noreference This field is not intended to be referenced by clients.
+	 */
+	public int kind;
+	
+	/**
+	 * @noreference This field is not intended to be referenced by clients.
+	 */
+	public boolean mustResolve = true;
+	
+/**
+ * Creates a search pattern with the rule to apply for matching index keys.
+ * It can be exact match, prefix match, pattern match or regexp match.
+ * Rule can also be combined with a case sensitivity flag.
+ *
+ * @param matchRule one of following match rule
+ * 	<ul>
+ * 		<li>{@link #R_EXACT_MATCH}</li>
+ * 		<li>{@link #R_PREFIX_MATCH}</li>
+ * 		<li>{@link #R_PATTERN_MATCH}</li>
+ * 		<li>{@link #R_REGEXP_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
+ * 	</ul>
+ * 	which may be also combined with one of following flag:
+ * 	<ul>
+ * 		<li>{@link #R_CASE_SENSITIVE}</li>
+ * 		<li>{@link #R_ERASURE_MATCH}</li>
+ * 		<li>{@link #R_EQUIVALENT_MATCH}</li>
+ * 	</ul>
+ *		For example,
+ *		<ul>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}: if an exact
+ *				and case sensitive match is requested,</li>
+ *			<li>{@link #R_PREFIX_MATCH} if a case insensitive prefix match is requested</li>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}: if a case
+ *				insensitive and erasure match is requested.</li>
+ *		</ul>
+ * 	Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} has no effect
+ * 	on non-generic types/methods search.
+ * 	<p>
+ * 	Note also that default behavior for generic types/methods search is to find exact matches.
+ */
+public SearchPattern(int matchRule) {
+	this.matchRule = matchRule;
+	// Set full match implicit mode
+	if ((matchRule & (R_EQUIVALENT_MATCH | R_ERASURE_MATCH )) == 0) {
+		this.matchRule |= R_FULL_MATCH;
+	}
+	// reset other incompatible flags
+	if ((matchRule & R_CAMELCASE_MATCH) != 0) {
+		this.matchRule &= ~R_CAMELCASE_SAME_PART_COUNT_MATCH;
+		this.matchRule &= ~R_PREFIX_MATCH;
+	} else if ((matchRule & R_CAMELCASE_SAME_PART_COUNT_MATCH) != 0) {
+		this.matchRule &= ~R_PREFIX_MATCH;
+	}
+}
+/**
+ * @noreference This method is not intended to be referenced by clients.
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public void acceptMatch(String relativePath, String containerPath, char separator, SearchPattern pattern, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope) {
+	acceptMatch(relativePath, containerPath, separator, pattern, requestor, participant, scope, null);
+}
+/**
+ * @noreference This method is not intended to be referenced by clients.
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public void acceptMatch(String relativePath, String containerPath, char separator, SearchPattern pattern, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor monitor) {
+
+	if (scope instanceof JavaSearchScope) {
+		JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
+		// Get document path access restriction from java search scope
+		// Note that requestor has to verify if needed whether the document violates the access restriction or not
+		AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, containerPath);
+		if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the document path
+			StringBuffer documentPath = new StringBuffer(containerPath.length() + 1 + relativePath.length());
+			documentPath.append(containerPath);
+			documentPath.append(separator);
+			documentPath.append(relativePath);
+			if (!requestor.acceptIndexMatch(documentPath.toString(), pattern, participant, access))
+				throw new OperationCanceledException();
+		}
+	} else {
+		StringBuffer buffer = new StringBuffer(containerPath.length() + 1 + relativePath.length());
+		buffer.append(containerPath);
+		buffer.append(separator);
+		buffer.append(relativePath);
+		String documentPath = buffer.toString();
+		boolean encloses = (scope instanceof HierarchyScope) ? ((HierarchyScope)scope).encloses(documentPath, monitor)
+							: scope.encloses(documentPath);
+		if (encloses) 
+			if (!requestor.acceptIndexMatch(documentPath, pattern, participant, null))
+				throw new OperationCanceledException();
+
+	}
+}
+/**
+ * @noreference This method is not intended to be referenced by clients. 
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public SearchPattern currentPattern() {
+	return this;
+}
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or
+ * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
+ * '*' and '?' and is inherently case sensitive.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Using this method allows matching names to have more parts than the specified
+ * pattern (see {@link #camelCaseMatch(String, String, boolean)}).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
+ * 'HatMapper' <b>and also</b> 'HashMapEntry'.
+ * <p>
+ * <pre>
+ * Examples:
+ * <ol><li>  pattern = "NPE"
+ *  name = NullPointerException / NoPermissionException
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  name = NullPointerException
+ *  result => true</li>
+ * <li>  pattern = "npe"
+ *  name = NullPointerException
+ *  result => false</li>
+ * <li>  pattern = "IPL3"
+ *  name = "IPerspectiveListener3"
+ *  result => true</li>
+ * <li>  pattern = "HM"
+ *  name = "HashMapEntry"
+ *  result => true</li>
+ * <li>  pattern = "HMap"
+ *  name = "HatMapper"
+ *  result => true</li>
+ * </ol></pre>
+ *
+ * @see #camelCaseMatch(String, int, int, String, int, int, boolean) for algorithm
+ * implementation
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.2
+ */
+public static final boolean camelCaseMatch(String pattern, String name) {
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	if (name == null)
+		return false; // null name cannot match
+
+	return camelCaseMatch(pattern, 0, pattern.length(), name, 0, name.length(), false/*not the same count of parts*/);
+}
+
+/**
+ * Answers true if the pattern matches the given name using CamelCase rules, or
+ * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
+ * '*' and '?' and is inherently case sensitive.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ * <p>
+ * <pre>
+ * Examples:
+ * <ol><li>  pattern = "NPE"
+ *  name = NullPointerException / NoPermissionException
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  name = NullPointerException
+ *  result => true</li>
+ * <li>  pattern = "npe"
+ *  name = NullPointerException
+ *  result => false</li>
+ * <li>  pattern = "IPL3"
+ *  name = "IPerspectiveListener3"
+ *  result => true</li>
+ * <li>  pattern = "HM"
+ *  name = "HashMapEntry"
+ *  result => (samePartCount == false)</li>
+ * </ol></pre>
+ *
+ * @see #camelCaseMatch(String, int, int, String, int, int, boolean) for algorithm
+ * 	implementation
+ *
+ * @param pattern the given pattern
+ * @param name the given name
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.<br>
+ * 	&nbsp;&nbsp;For example:
+ * 	<ul>
+ * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'</li>
+ * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
+ * 	</ul>
+ * @return true if the pattern matches the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(String pattern, String name, boolean samePartCount) {
+	if (pattern == null)
+		return true; // null pattern is equivalent to '*'
+	if (name == null)
+		return false; // null name cannot match
+
+	return camelCaseMatch(pattern, 0, pattern.length(), name, 0, name.length(), samePartCount);
+}
+
+/**
+ * Answers true if a sub-pattern matches the sub-part of the given name using
+ * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
+ * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
+ * Can match only subset of name/pattern, considering end positions as non-inclusive.
+ * The sub-pattern is defined by the patternStart and patternEnd positions.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain a
+ * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * Using this method allows matching names to have more parts than the specified
+ * pattern (see {@link #camelCaseMatch(String, int, int, String, int, int, boolean)}).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
+ * 'HatMapper' <b>and also</b> 'HashMapEntry'.
+ * <p>
+ * <pre>Examples:<ol>
+ * <li>  pattern = "NPE"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => true</li>
+ * <li>  pattern = "NPE"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NoPermissionException
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  patternStart = 0
+ *  patternEnd = 6
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  patternStart = 0
+ *  patternEnd = 6
+ *  name = NoPermissionException
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => false</li>
+ * <li>  pattern = "npe"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => false</li>
+ * <li>  pattern = "IPL3"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = "IPerspectiveListener3"
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => true</li>
+ * <li>  pattern = "HM"
+ *  patternStart = 0
+ *  patternEnd = 2
+ *  name = "HashMapEntry"
+ *  nameStart = 0
+ *  nameEnd = 12
+ *  result => true</li>
+ * <li>  pattern = "HMap"
+ *  patternStart = 0
+ *  patternEnd = 4
+ *  name = "HatMapper"
+ *  nameStart = 0
+ *  nameEnd = 9
+ *  result => true</li>
+ * </ol></pre>
+ *
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.2
+ */
+public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd) {
+	return camelCaseMatch(pattern, patternStart, patternEnd, name, nameStart, nameEnd, false/*not the same count of parts*/);
+}
+
+/**
+ * Answers true if a sub-pattern matches the sub-part of the given name using
+ * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
+ * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
+ * Can match only subset of name/pattern, considering end positions as
+ * non-inclusive. The sub-pattern is defined by the patternStart and patternEnd
+ * positions.
+ * <p>
+ * CamelCase denotes the convention of writing compound names without spaces,
+ * and capitalizing every term. This function recognizes both upper and lower
+ * CamelCase, depending whether the leading character is capitalized or not.
+ * The leading part of an upper CamelCase pattern is assumed to contain
+ * a sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
+ * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
+ * uses a lowercase first character. In Java, type names follow the upper
+ * CamelCase convention, whereas method or field names follow the lower
+ * CamelCase convention.
+ * <p>
+ * The pattern may contain lowercase characters, which will be matched in a case
+ * sensitive way. These characters must appear in sequence in the name.
+ * For instance, 'NPExcep' will match 'NullPointerException', but not
+ * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
+ * 'NoPointerException'.
+ * <p>
+ * Digit characters are treated in a special way. They can be used in the pattern
+ * but are not always considered as leading character. For instance, both
+ * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
+ * <p>
+ * CamelCase can be restricted to match only the same count of parts. When this
+ * restriction is specified the given pattern and the given name must have <b>exactly</b>
+ * the same number of parts (i.e. the same number of uppercase characters).<br>
+ * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
+ * 'HatMapper' <b>but not</b> 'HashMapEntry'.
+ * <p>
+ * <pre>Examples:<ol>
+ * <li>  pattern = "NPE"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => true</li>
+ * <li>  pattern = "NPE"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NoPermissionException
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  patternStart = 0
+ *  patternEnd = 6
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => true</li>
+ * <li>  pattern = "NuPoEx"
+ *  patternStart = 0
+ *  patternEnd = 6
+ *  name = NoPermissionException
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => false</li>
+ * <li>  pattern = "npe"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = NullPointerException
+ *  nameStart = 0
+ *  nameEnd = 20
+ *  result => false</li>
+ * <li>  pattern = "IPL3"
+ *  patternStart = 0
+ *  patternEnd = 3
+ *  name = "IPerspectiveListener3"
+ *  nameStart = 0
+ *  nameEnd = 21
+ *  result => true</li>
+ * <li>  pattern = "HM"
+ *  patternStart = 0
+ *  patternEnd = 2
+ *  name = "HashMapEntry"
+ *  nameStart = 0
+ *  nameEnd = 12
+ *  result => (samePartCount == false)</li>
+ * </ol></pre>
+ *
+ * @see CharOperation#camelCaseMatch(char[], int, int, char[], int, int, boolean)
+ * 	from which algorithm implementation has been entirely copied.
+ *
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.<br>
+ * 	&nbsp;&nbsp;For example:
+ * 	<ul>
+ * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'</li>
+ * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
+ * 	</ul>
+ * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
+ * @since 3.4
+ */
+public static final boolean camelCaseMatch(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd, boolean samePartCount) {
+	return StringOperation.getCamelCaseMatchingRegions(pattern, patternStart, patternEnd, name, nameStart, nameEnd, samePartCount) != null;
+}
+
+/**
+ * Answers all the regions in a given name matching a given pattern using
+ * a specified match rule.
+ * </p><p>
+ * Each of these regions is made of its starting index and its length in the given
+ * name. They are all concatenated in a single array of <code>int</code>
+ * which therefore always has an even length.
+ * </p><p>
+ * All returned regions are disjointed from each other. That means that the end
+ * of a region is always different than the start of the following one.<br>
+ * For example, if two regions are returned:<br>
+ * <code>{ start1, length1, start2, length2 }</code><br>
+ * then <code>start1+length1</code> will always be smaller than
+ * <code>start2</code>.
+ * </p><p>
+ * The possible comparison rules between the name and the pattern are:
+ * <ul>
+ * <li>{@link #R_EXACT_MATCH exact matching}</li>
+ * <li>{@link #R_PREFIX_MATCH prefix matching}</li>
+ * <li>{@link #R_PATTERN_MATCH pattern matching}</li>
+ * <li>{@link #R_CAMELCASE_MATCH camel case matching}</li>
+ * <li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH camel case matching with same parts count}</li>
+ * </ul>
+ * Each of these rules may be combined with the
+ * {@link #R_CASE_SENSITIVE case sensitive flag} if the match comparison
+ * should respect the case.
+ * <pre>
+ * Examples:
+ * <ol><li>  pattern = "NPE"
+ *  name = NullPointerException / NoPermissionException
+ *  matchRule = {@link #R_CAMELCASE_MATCH}
+ *  result:  { 0, 1, 4, 1, 11, 1 } / { 0, 1, 2, 1, 12, 1 } </li>
+ * <li>  pattern = "NuPoEx"
+ *  name = NullPointerException
+ *  matchRule = {@link #R_CAMELCASE_MATCH}
+ *  result:  { 0, 2, 4, 2, 11, 2 }</li>
+ * <li>  pattern = "IPL3"
+ *  name = "IPerspectiveListener3"
+ *  matchRule = {@link #R_CAMELCASE_MATCH}
+ *  result:  { 0, 2, 12, 1, 20, 1 }</li>
+ * <li>  pattern = "HashME"
+ *  name = "HashMapEntry"
+ *  matchRule = {@link #R_CAMELCASE_MATCH}
+ *  result:  { 0, 5, 7, 1 }</li>
+ * <li>  pattern = "N???Po*Ex?eption"
+ *  name = NullPointerException
+ *  matchRule = {@link #R_PATTERN_MATCH} | {@link #R_CASE_SENSITIVE}
+ *  result:  { 0, 1, 4, 2, 11, 2, 14, 6 }</li>
+ * <li>  pattern = "Ha*M*ent*"
+ *  name = "HashMapEntry"
+ *  matchRule = {@link #R_PATTERN_MATCH}
+ *  result:  { 0, 2, 4, 1, 7, 3 }</li>
+ * </ol></pre>
+ *
+ * @see #camelCaseMatch(String, String, boolean) for more details on the
+ * 	camel case behavior
+ * @see CharOperation#match(char[], char[], boolean) for more details on the
+ * 	pattern match behavior
+ *
+ * @param pattern the given pattern. If <code>null</code>,
+ *     then an empty region (<code>new int[0]</code>) will be returned
+ *     showing that the name matches the pattern but no common
+ *     character has been found.
+ * @param name the given name
+ * @param matchRule the rule to apply for the comparison.<br>
+ *     The following values are accepted:
+ *     <ul>
+ *         <li>{@link #R_EXACT_MATCH}</li>
+ *         <li>{@link #R_PREFIX_MATCH}</li>
+ *         <li>{@link #R_PATTERN_MATCH}</li>
+ *         <li>{@link #R_CAMELCASE_MATCH}</li>
+ *         <li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
+ *     </ul>
+ *     <p>
+ *     Each of these valid values may be also combined with
+ *     the {@link #R_CASE_SENSITIVE} flag.
+ *     </p>
+ *     Some examples:
+ *     <ul>
+ *         <li>{@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}:
+ *                 if an exact case sensitive match is expected,</li>
+ *         <li>{@link #R_PREFIX_MATCH}:
+ *                 if a case insensitive prefix match is expected,</li>
+ *         <li>{@link #R_CAMELCASE_MATCH}:
+ *                 if a case insensitive camel case match is expected,</li>
+ *         <li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}
+ *                 | {@link #R_CASE_SENSITIVE}:
+ *                 if a case sensitive camel case with same parts count match
+ *                 is expected,</li>
+ *         <li>etc.</li>
+ *     </ul>
+ * @return an array of <code>int</code> having two slots per returned
+ *     regions (the first one is the region starting index and the second one
+ *     is the region length or <code>null</code> if the given name does not
+ *     match the given pattern).
+ *     <p>
+ *     The returned regions may be empty (<code>new int[0]</code>) if the
+ *     pattern is <code>null</code> (whatever the match rule is). The returned
+ *     regions will also be empty if the pattern is only made of <code>'?'</code>
+ *     and/or <code>'*'</code> character(s) (e.g. <code>'*'</code>,
+ *     <code>'?*'</code>, <code>'???'</code>, etc.) when using a pattern
+ *     match rule.
+ *     </p>
+ * 
+ * @since 3.5
+ */
+public static final int[] getMatchingRegions(String pattern, String name, int matchRule) {
+	if (name == null) return null;
+	final int nameLength = name.length();
+	if (pattern == null) {
+		return new int[] { 0, nameLength };
+	}
+	final int patternLength = pattern.length();
+	boolean countMatch = false;
+	switch (matchRule) {
+		case SearchPattern.R_EXACT_MATCH:
+			if (patternLength == nameLength && pattern.equalsIgnoreCase(name)) {
+				return new int[] { 0, patternLength };
+			}
+			break;
+		case SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE:
+			if (patternLength == nameLength && pattern.equals(name)) {
+				return new int[] { 0, patternLength };
+			}
+			break;
+		case SearchPattern.R_PREFIX_MATCH:
+			if (patternLength <= nameLength && name.substring(0, patternLength).equalsIgnoreCase(pattern)) {
+				return new int[] { 0, patternLength };
+			}
+			break;
+		case SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE:
+			if (name.startsWith(pattern)) {
+				return new int[] { 0, patternLength };
+			}
+			break;
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			countMatch = true;
+			//$FALL-THROUGH$
+		case SearchPattern.R_CAMELCASE_MATCH:
+			if (patternLength <= nameLength) {
+				int[] regions = StringOperation.getCamelCaseMatchingRegions(pattern, 0, patternLength, name, 0, nameLength, countMatch);
+				if (regions != null) return regions;
+				if (name.substring(0, patternLength).equalsIgnoreCase(pattern)) {
+					return new int[] { 0, patternLength };
+				}
+			}
+			break;
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_CASE_SENSITIVE:
+			countMatch = true;
+			//$FALL-THROUGH$
+		case SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CASE_SENSITIVE:
+			if (patternLength <= nameLength) {
+				return StringOperation.getCamelCaseMatchingRegions(pattern, 0, patternLength, name, 0, nameLength, countMatch);
+			}
+			break;
+		case SearchPattern.R_PATTERN_MATCH:
+			return StringOperation.getPatternMatchingRegions(pattern, 0, patternLength, name, 0, nameLength, false);
+		case SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE:
+			return StringOperation.getPatternMatchingRegions(pattern, 0, patternLength, name, 0, nameLength, true);
+	}
+	return null;
+}
+
+/**
+ * Returns a search pattern that combines the given two patterns into an
+ * "and" pattern. The search result will match both the left pattern and
+ * the right pattern.
+ *
+ * @param leftPattern the left pattern
+ * @param rightPattern the right pattern
+ * @return an "and" pattern
+ * @deprecated Unfortunately, this functionality is not fully supported yet
+ * 	(see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=142044" for more details).
+ * 	This might be done in a further version...
+ */
+public static SearchPattern createAndPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
+	return new AndPattern(leftPattern, rightPattern);
+}
+
+private static SearchPattern createFieldPattern(String patternString, int limitTo, int matchRule) {
+	// use 1.7 as the source level as there are more valid tokens in 1.7 mode
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=376673
+	Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_7/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+	scanner.setSource(patternString.toCharArray());
+	final int InsideDeclaringPart = 1;
+	final int InsideType = 2;
+	int lastToken = -1;
+
+	String declaringType = null, fieldName = null;
+	String type = null;
+	int mode = InsideDeclaringPart;
+	int token;
+	try {
+		token = scanner.getNextToken();
+	} catch (InvalidInputException e) {
+		return null;
+	}
+	while (token != TerminalTokens.TokenNameEOF) {
+		switch(mode) {
+			// read declaring type and fieldName
+			case InsideDeclaringPart :
+				switch (token) {
+					case TerminalTokens.TokenNameDOT:
+						if (declaringType == null) {
+							if (fieldName == null) return null;
+							declaringType = fieldName;
+						} else {
+							String tokenSource = scanner.getCurrentTokenString();
+							declaringType += tokenSource + fieldName;
+						}
+						fieldName = null;
+						break;
+					case TerminalTokens.TokenNameWHITESPACE:
+						if (!(TerminalTokens.TokenNameWHITESPACE == lastToken || TerminalTokens.TokenNameDOT == lastToken))
+							mode = InsideType;
+						break;
+					default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+						if (fieldName == null)
+							fieldName = scanner.getCurrentTokenString();
+						else
+							fieldName += scanner.getCurrentTokenString();
+				}
+				break;
+			// read type
+			case InsideType:
+				switch (token) {
+					case TerminalTokens.TokenNameWHITESPACE:
+						break;
+					default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+						if (type == null)
+							type = scanner.getCurrentTokenString();
+						else
+							type += scanner.getCurrentTokenString();
+				}
+				break;
+		}
+		lastToken = token;
+		try {
+			token = scanner.getNextToken();
+		} catch (InvalidInputException e) {
+			return null;
+		}
+	}
+	if (fieldName == null) return null;
+
+	char[] fieldNameChars = fieldName.toCharArray();
+	if (fieldNameChars.length == 1 && fieldNameChars[0] == '*') fieldNameChars = null;
+
+	char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
+	char[] typeQualification = null, typeSimpleName = null;
+
+	// extract declaring type infos
+	if (declaringType != null) {
+		char[] declaringTypePart = declaringType.toCharArray();
+		int lastDotPosition = CharOperation.lastIndexOf('.', declaringTypePart);
+		if (lastDotPosition >= 0) {
+			declaringTypeQualification = CharOperation.subarray(declaringTypePart, 0, lastDotPosition);
+			if (declaringTypeQualification.length == 1 && declaringTypeQualification[0] == '*')
+				declaringTypeQualification = null;
+			declaringTypeSimpleName = CharOperation.subarray(declaringTypePart, lastDotPosition+1, declaringTypePart.length);
+		} else {
+			declaringTypeSimpleName = declaringTypePart;
+		}
+		if (declaringTypeSimpleName.length == 1 && declaringTypeSimpleName[0] == '*')
+			declaringTypeSimpleName = null;
+	}
+	// extract type infos
+	if (type != null) {
+		char[] typePart = type.toCharArray();
+		int lastDotPosition = CharOperation.lastIndexOf('.', typePart);
+		if (lastDotPosition >= 0) {
+			typeQualification = CharOperation.subarray(typePart, 0, lastDotPosition);
+			if (typeQualification.length == 1 && typeQualification[0] == '*') {
+				typeQualification = null;
+			} else {
+				// prefix with a '*' as the full qualification could be bigger (because of an import)
+				typeQualification = CharOperation.concat(IIndexConstants.ONE_STAR, typeQualification);
+			}
+			typeSimpleName = CharOperation.subarray(typePart, lastDotPosition+1, typePart.length);
+		} else {
+			typeSimpleName = typePart;
+		}
+		if (typeSimpleName.length == 1 && typeSimpleName[0] == '*')
+			typeSimpleName = null;
+	}
+	// Create field pattern
+	return new FieldPattern(
+			fieldNameChars,
+			declaringTypeQualification,
+			declaringTypeSimpleName,
+			typeQualification,
+			typeSimpleName,
+			limitTo,
+			matchRule);
+}
+
+private static SearchPattern createMethodOrConstructorPattern(String patternString, int limitTo, int matchRule, boolean isConstructor) {
+	// use 1.7 as the source level as there are more valid tokens in 1.7 mode
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=376673
+	Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_7/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+	scanner.setSource(patternString.toCharArray());
+	final int InsideSelector = 1;
+	final int InsideTypeArguments = 2;
+	final int InsideParameter = 3;
+	final int InsideReturnType = 4;
+	int lastToken = -1;
+
+	String declaringType = null, selector = null, parameterType = null;
+	String[] parameterTypes = null;
+	char[][] typeArguments = null;
+	String typeArgumentsString = null;
+	int parameterCount = -1;
+	String returnType = null;
+	boolean foundClosingParenthesis = false;
+	int mode = InsideSelector;
+	int token, argCount = 0;
+	try {
+		token = scanner.getNextToken();
+	} catch (InvalidInputException e) {
+		return null;
+	}
+	while (token != TerminalTokens.TokenNameEOF) {
+		switch(mode) {
+			// read declaring type and selector
+			case InsideSelector :
+				if (argCount == 0) {
+					switch (token) {
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							if (selector == null || lastToken == TerminalTokens.TokenNameDOT) {
+								typeArgumentsString = scanner.getCurrentTokenString();
+								mode = InsideTypeArguments;
+								break;
+							}
+							if (declaringType == null) {
+								declaringType = selector;
+							} else {
+								declaringType += '.' + selector;
+							}
+							declaringType += scanner.getCurrentTokenString();
+							selector = null;
+							break;
+						case TerminalTokens.TokenNameDOT:
+							if (!isConstructor && typeArgumentsString != null) return null; // invalid syntax
+							if (declaringType == null) {
+								if (selector == null) return null; // invalid syntax
+								declaringType = selector;
+							} else if (selector != null) {
+								declaringType += scanner.getCurrentTokenString() + selector;
+							}
+							selector = null;
+							break;
+						case TerminalTokens.TokenNameLPAREN:
+							parameterTypes = new String[5];
+							parameterCount = 0;
+							mode = InsideParameter;
+							break;
+						case TerminalTokens.TokenNameWHITESPACE:
+							switch (lastToken) {
+								case TerminalTokens.TokenNameWHITESPACE:
+								case TerminalTokens.TokenNameDOT:
+								case TerminalTokens.TokenNameGREATER:
+								case TerminalTokens.TokenNameRIGHT_SHIFT:
+								case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+									break;
+								default:
+									mode = InsideReturnType;
+									break;
+							}
+							break;
+						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+							if (selector == null)
+								selector = scanner.getCurrentTokenString();
+							else
+								selector += scanner.getCurrentTokenString();
+							break;
+					}
+				} else {
+					if (declaringType == null) return null; // invalid syntax
+					switch (token) {
+						case TerminalTokens.TokenNameGREATER:
+						case TerminalTokens.TokenNameRIGHT_SHIFT:
+						case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+							argCount--;
+							break;
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							break;
+					}
+					declaringType += scanner.getCurrentTokenString();
+				}
+				break;
+			// read type arguments
+			case InsideTypeArguments:
+				if (typeArgumentsString == null) return null; // invalid syntax
+				typeArgumentsString += scanner.getCurrentTokenString();
+				switch (token) {
+					case TerminalTokens.TokenNameGREATER:
+					case TerminalTokens.TokenNameRIGHT_SHIFT:
+					case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+						argCount--;
+						if (argCount == 0) {
+							String pseudoType = "Type"+typeArgumentsString; //$NON-NLS-1$
+							typeArguments = Signature.getTypeArguments(Signature.createTypeSignature(pseudoType, false).toCharArray());
+							mode = InsideSelector;
+						}
+						break;
+					case TerminalTokens.TokenNameLESS:
+						argCount++;
+						break;
+				}
+				break;
+			// read parameter types
+			case InsideParameter :
+				if (argCount == 0) {
+					switch (token) {
+						case TerminalTokens.TokenNameWHITESPACE:
+							break;
+						case TerminalTokens.TokenNameCOMMA:
+							if (parameterType == null) return null;
+							if (parameterTypes != null) {
+								if (parameterTypes.length == parameterCount)
+									System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
+								parameterTypes[parameterCount++] = parameterType;
+							}
+							parameterType = null;
+							break;
+						case TerminalTokens.TokenNameRPAREN:
+							foundClosingParenthesis = true;
+							if (parameterType != null && parameterTypes != null) {
+								if (parameterTypes.length == parameterCount)
+									System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
+								parameterTypes[parameterCount++] = parameterType;
+							}
+							mode = isConstructor ? InsideTypeArguments : InsideReturnType;
+							break;
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							if (parameterType == null) return null; // invalid syntax
+							// $FALL-THROUGH$ - fall through next case to add token
+						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+							if (parameterType == null)
+								parameterType = scanner.getCurrentTokenString();
+							else
+								parameterType += scanner.getCurrentTokenString();
+					}
+				} else {
+					if (parameterType == null) return null; // invalid syntax
+					switch (token) {
+						case TerminalTokens.TokenNameGREATER:
+						case TerminalTokens.TokenNameRIGHT_SHIFT:
+						case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+							argCount--;
+							break;
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							break;
+					}
+					parameterType += scanner.getCurrentTokenString();
+				}
+				break;
+			// read return type
+			case InsideReturnType:
+				if (argCount == 0) {
+					switch (token) {
+						case TerminalTokens.TokenNameWHITESPACE:
+							break;
+						case TerminalTokens.TokenNameLPAREN:
+							parameterTypes = new String[5];
+							parameterCount = 0;
+							mode = InsideParameter;
+							break;
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							if (returnType == null) return null; // invalid syntax
+							// $FALL-THROUGH$ - fall through next case to add token
+						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+							if (returnType == null)
+								returnType = scanner.getCurrentTokenString();
+							else
+								returnType += scanner.getCurrentTokenString();
+					}
+				} else {
+					if (returnType == null) return null; // invalid syntax
+					switch (token) {
+						case TerminalTokens.TokenNameGREATER:
+						case TerminalTokens.TokenNameRIGHT_SHIFT:
+						case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+							argCount--;
+							break;
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
+							break;
+					}
+					returnType += scanner.getCurrentTokenString();
+				}
+				break;
+		}
+		lastToken = token;
+		try {
+			token = scanner.getNextToken();
+		} catch (InvalidInputException e) {
+			return null;
+		}
+	}
+	// parenthesis mismatch
+	if (parameterCount>0 && !foundClosingParenthesis) return null;
+	// type arguments mismatch
+	if (argCount > 0) return null;
+
+	char[] selectorChars = null;
+	if (isConstructor) {
+		// retrieve type for constructor patterns
+		if (declaringType == null)
+			declaringType = selector;
+		else if (selector != null)
+			declaringType += '.' + selector;
+	} else {
+		// get selector chars
+		if (selector == null) return null;
+		selectorChars = selector.toCharArray();
+		if (selectorChars.length == 1 && selectorChars[0] == '*')
+			selectorChars = null;
+	}
+
+	char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
+	char[] returnTypeQualification = null, returnTypeSimpleName = null;
+	char[][] parameterTypeQualifications = null, parameterTypeSimpleNames = null;
+	// Signatures
+	String declaringTypeSignature = null;
+	String returnTypeSignature = null;
+	String[] parameterTypeSignatures = null;
+
+	// extract declaring type infos
+	if (declaringType != null) {
+		// get declaring type part and signature
+		char[] declaringTypePart = null;
+		try {
+			declaringTypeSignature = Signature.createTypeSignature(declaringType, false);
+			if (declaringTypeSignature.indexOf(Signature.C_GENERIC_START) < 0) {
+				declaringTypePart = declaringType.toCharArray();
+			} else {
+				declaringTypePart = Signature.toCharArray(Signature.getTypeErasure(declaringTypeSignature.toCharArray()));
+			}
+		}
+		catch (IllegalArgumentException iae) {
+			// declaring type is invalid
+			return null;
+		}
+		int lastDotPosition = CharOperation.lastIndexOf('.', declaringTypePart);
+		if (lastDotPosition >= 0) {
+			declaringTypeQualification = CharOperation.subarray(declaringTypePart, 0, lastDotPosition);
+			if (declaringTypeQualification.length == 1 && declaringTypeQualification[0] == '*')
+				declaringTypeQualification = null;
+			declaringTypeSimpleName = CharOperation.subarray(declaringTypePart, lastDotPosition+1, declaringTypePart.length);
+		} else {
+			declaringTypeSimpleName = declaringTypePart;
+		}
+		if (declaringTypeSimpleName.length == 1 && declaringTypeSimpleName[0] == '*')
+			declaringTypeSimpleName = null;
+	}
+	// extract parameter types infos
+	if (parameterCount >= 0) {
+		parameterTypeQualifications = new char[parameterCount][];
+		parameterTypeSimpleNames = new char[parameterCount][];
+		parameterTypeSignatures = new String[parameterCount];
+		for (int i = 0; i < parameterCount; i++) {
+			// get parameter type part and signature
+			char[] parameterTypePart = null;
+			try {
+				if (parameterTypes != null) {
+					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypes[i], false);
+					if (parameterTypeSignatures[i].indexOf(Signature.C_GENERIC_START) < 0) {
+						parameterTypePart = parameterTypes[i].toCharArray();
+					} else {
+						parameterTypePart = Signature.toCharArray(Signature.getTypeErasure(parameterTypeSignatures[i].toCharArray()));
+					}
+				}
+			}
+			catch (IllegalArgumentException iae) {
+				// string is not a valid type syntax
+				return null;
+			}
+			int lastDotPosition = parameterTypePart==null ? -1 : CharOperation.lastIndexOf('.', parameterTypePart);
+			if (parameterTypePart != null && lastDotPosition >= 0) {
+				parameterTypeQualifications[i] = CharOperation.subarray(parameterTypePart, 0, lastDotPosition);
+				if (parameterTypeQualifications[i].length == 1 && parameterTypeQualifications[i][0] == '*') {
+					parameterTypeQualifications[i] = null;
+				} else {
+					// prefix with a '*' as the full qualification could be bigger (because of an import)
+					parameterTypeQualifications[i] = CharOperation.concat(IIndexConstants.ONE_STAR, parameterTypeQualifications[i]);
+				}
+				parameterTypeSimpleNames[i] = CharOperation.subarray(parameterTypePart, lastDotPosition+1, parameterTypePart.length);
+			} else {
+				parameterTypeQualifications[i] = null;
+				parameterTypeSimpleNames[i] = parameterTypePart;
+			}
+			if (parameterTypeSimpleNames[i].length == 1 && parameterTypeSimpleNames[i][0] == '*')
+				parameterTypeSimpleNames[i] = null;
+		}
+	}
+	// extract return type infos
+	if (returnType != null) {
+		// get return type part and signature
+		char[] returnTypePart = null;
+		try {
+			returnTypeSignature = Signature.createTypeSignature(returnType, false);
+			if (returnTypeSignature.indexOf(Signature.C_GENERIC_START) < 0) {
+				returnTypePart = returnType.toCharArray();
+			} else {
+				returnTypePart = Signature.toCharArray(Signature.getTypeErasure(returnTypeSignature.toCharArray()));
+			}
+		}
+		catch (IllegalArgumentException iae) {
+			// declaring type is invalid
+			return null;
+		}
+		int lastDotPosition = CharOperation.lastIndexOf('.', returnTypePart);
+		if (lastDotPosition >= 0) {
+			returnTypeQualification = CharOperation.subarray(returnTypePart, 0, lastDotPosition);
+			if (returnTypeQualification.length == 1 && returnTypeQualification[0] == '*') {
+				returnTypeQualification = null;
+			} else {
+				// because of an import
+				returnTypeQualification = CharOperation.concat(IIndexConstants.ONE_STAR, returnTypeQualification);
+			}
+			returnTypeSimpleName = CharOperation.subarray(returnTypePart, lastDotPosition+1, returnTypePart.length);
+		} else {
+			returnTypeSimpleName = returnTypePart;
+		}
+		if (returnTypeSimpleName.length == 1 && returnTypeSimpleName[0] == '*')
+			returnTypeSimpleName = null;
+	}
+	// Create method/constructor pattern
+	if (isConstructor) {
+		return new ConstructorPattern(
+				declaringTypeSimpleName,
+				declaringTypeQualification,
+				declaringTypeSignature,
+				parameterTypeQualifications,
+				parameterTypeSimpleNames,
+				parameterTypeSignatures,
+				typeArguments,
+				limitTo,
+				matchRule);
+	} else {
+		return new MethodPattern(
+				selectorChars,
+				declaringTypeQualification,
+				declaringTypeSimpleName,
+				declaringTypeSignature,
+				returnTypeQualification,
+				returnTypeSimpleName,
+				returnTypeSignature,
+				parameterTypeQualifications,
+				parameterTypeSimpleNames,
+				parameterTypeSignatures,
+				typeArguments,
+				limitTo,
+				matchRule);
+	}
+}
+
+/**
+ * Returns a search pattern that combines the given two patterns into an
+ * "or" pattern. The search result will match either the left pattern or the
+ * right pattern.
+ *
+ * @param leftPattern the left pattern
+ * @param rightPattern the right pattern
+ * @return an "or" pattern
+ */
+public static SearchPattern createOrPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
+	return new OrPattern(leftPattern, rightPattern);
+}
+
+private static SearchPattern createPackagePattern(String patternString, int limitTo, int matchRule) {
+	switch (limitTo) {
+		case IJavaSearchConstants.DECLARATIONS :
+			return new PackageDeclarationPattern(patternString.toCharArray(), matchRule);
+		case IJavaSearchConstants.REFERENCES :
+			return new PackageReferencePattern(patternString.toCharArray(), matchRule);
+		case IJavaSearchConstants.ALL_OCCURRENCES :
+			return new OrPattern(
+				new PackageDeclarationPattern(patternString.toCharArray(), matchRule),
+				new PackageReferencePattern(patternString.toCharArray(), matchRule)
+			);
+	}
+	return null;
+}
+
+/**
+ * Returns a search pattern based on a given string pattern. The string patterns support '*' wild-cards.
+ * The remaining parameters are used to narrow down the type of expected results.
+ *
+ * <br>
+ *	Examples:
+ *	<ul>
+ * 		<li>search for case insensitive references to <code>Object</code>:
+ *			<code>createSearchPattern("Object", IJavaSearchConstants.TYPE, IJavaSearchConstants.REFERENCES, false);</code></li>
+ *  	<li>search for case sensitive references to exact <code>Object()</code> constructor:
+ *			<code>createSearchPattern("java.lang.Object()", IJavaSearchConstants.CONSTRUCTOR, IJavaSearchConstants.REFERENCES, true);</code></li>
+ *  	<li>search for implementers of <code>java.lang.Runnable</code>:
+ *			<code>createSearchPattern("java.lang.Runnable", IJavaSearchConstants.TYPE, IJavaSearchConstants.IMPLEMENTORS, true);</code></li>
+ *  </ul>
+ * @param stringPattern the given pattern
+ * <ul>
+ * 	<li>Type patterns have the following syntax:
+ * 		<p><b><code>[qualification '.']typeName ['&lt;' typeArguments '&gt;']</code></b></p>
+ *			<p>Examples:</p>
+ *			<ul>
+ * 			<li><code>java.lang.Object</code></li>
+ *				<li><code>Runnable</code></li>
+ *				<li><code>List&lt;String&gt;</code></li>
+ *			</ul>
+ *			<p>
+ *			Type arguments can be specified to search for references to parameterized types
+ * 		using following syntax:</p><p>
+ * 		<b><code>'&lt;' { [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* | '?' } '&gt;'</code></b>
+ * 		</p><div style="font-style:italic;">
+ * 		Note that:
+ * 		<ul>
+ * 			<li>'*' is not valid inside type arguments definition &lt;&gt;</li>
+ * 			<li>'?' is treated as a wildcard when it is inside &lt;&gt; (i.e. it must be put on first position of the type argument)</li>
+ * 		</ul>
+ * 		</div>
+ * 	</li>
+ * 	<li>Method patterns have the following syntax:
+ * 		<p><b><code>[declaringType '.'] ['&lt;' typeArguments '&gt;'] methodName ['(' parameterTypes ')'] [returnType]</code></b></p>
+ *			<p>Type arguments have the same syntax as explained in the type patterns section.</p>
+ *			<p>Examples:</p>
+ *			<ul>
+ *				<li><code>java.lang.Runnable.run() void</code></li>
+ *				<li><code>main(*)</code></li>
+ *				<li><code>&lt;String&gt;toArray(String[])</code></li>
+ *			</ul>
+ *	</li>
+ * 	<li>Constructor patterns have the following syntax:
+ *			<p><b><code>['&lt;' typeArguments '&gt;'] [declaringQualification '.'] typeName ['(' parameterTypes ')']</code></b></p>
+ *			<p>Type arguments have the same syntax as explained in the type patterns section.</p>
+ *			<p><i>Note that the constructor name should not be entered as it is always the same as the type name.</i></p>
+ *			<p>Examples:</p>
+ *			<ul>
+ *				<li><code>java.lang.Object()</code></li>
+ *				<li><code>Test(*)</code></li>
+ *				<li><code>&lt;Exception&gt;Sample(Exception)</code></li>
+ *			</ul>
+ * 		<br>
+ * 	</li>
+ * 	<li>Field patterns have the following syntax:
+ *			<p><b><code>[declaringType '.'] fieldName [fieldType]</code></b></p>
+ *			<p>Examples:</p>
+ *			<ul>
+ *				<li><code>java.lang.String.serialVersionUID long</code></li>
+ *				<li><code>field*</code></li>
+ *			</ul>
+ * 	</li>
+ * 	<li>Package patterns have the following syntax:
+ *			<p><b><code>packageNameSegment {'.' packageNameSegment}</code></b></p>
+ *			<p>Examples:</p>
+ *			<ul>
+ *				<li><code>java.lang</code></li>
+ *				<li><code>org.e*.jdt.c*e</code></li>
+ *			</ul>
+ * 	</li>
+ * </ul>
+ * @param searchFor determines the nature of the searched elements
+ *	<ul>
+ * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+ *	<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+ * 	<li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+ *	<li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+ * 	<li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+ *	<li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+ * 	<li>{@link IJavaSearchConstants#TYPE}: look for all types (i.e. classes, interfaces, enum and annotation types)</li>
+ *	<li>{@link IJavaSearchConstants#FIELD}: look for fields</li>
+ *	<li>{@link IJavaSearchConstants#METHOD}: look for methods</li>
+ *	<li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li>
+ *	<li>{@link IJavaSearchConstants#PACKAGE}: look for packages</li>
+ *	</ul>
+ * @param limitTo determines the nature of the expected matches
+ *	<ul>
+ * 	<li>{@link IJavaSearchConstants#DECLARATIONS DECLARATIONS}: will search declarations matching
+ * 			with the corresponding element. In case the element is a method, declarations of matching
+ * 			methods in sub-types will also be found, allowing to find declarations of abstract methods, etc.<br>
+ * 			Note that additional flags {@link IJavaSearchConstants#IGNORE_DECLARING_TYPE IGNORE_DECLARING_TYPE} and
+ * 			{@link IJavaSearchConstants#IGNORE_RETURN_TYPE IGNORE_RETURN_TYPE} are ignored for string patterns.
+ * 			This is due to the fact that client may omit to define them in string pattern to have same behavior.
+ * 	</li>
+ *		 <li>{@link IJavaSearchConstants#REFERENCES REFERENCES}: will search references to the given element.</li>
+ *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES ALL_OCCURRENCES}: will search for either declarations or
+ *				references as specified above.
+ *		</li>
+ *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS IMPLEMENTORS}: for types, will find all types
+ *				which directly implement/extend a given interface.
+ *				Note that types may be only classes or only interfaces if {@link IJavaSearchConstants#CLASS CLASS} or
+ *				{@link IJavaSearchConstants#INTERFACE INTERFACE} is respectively used instead of {@link IJavaSearchConstants#TYPE TYPE}.
+ *		</li>
+ *		 <li>All other fine grain constants defined in the <b>limitTo</b> category
+ *				of the {@link IJavaSearchConstants} are also accepted nature: 
+ * 			<table border=0>
+ *     			<tr>
+ *         		<th align=left>Fine grain constant
+ *         		<th align=left>Meaning
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#FIELD_DECLARATION_TYPE_REFERENCE FIELD_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a field declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a local variable declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#PARAMETER_DECLARATION_TYPE_REFERENCE PARAMETER_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a method parameter declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPERTYPE_TYPE_REFERENCE SUPERTYPE_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a super type or as a super interface.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THROWS_CLAUSE_TYPE_REFERENCE THROWS_CLAUSE_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a throws clause.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CAST_TYPE_REFERENCE CAST_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a cast expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CATCH_TYPE_REFERENCE CATCH_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a catch header.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CLASS_INSTANCE_CREATION_TYPE_REFERENCE CLASS_INSTANCE_CREATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in class instance creation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#RETURN_TYPE_REFERENCE RETURN_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a method return type.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPORT_DECLARATION_TYPE_REFERENCE IMPORT_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in an import declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#ANNOTATION_TYPE_REFERENCE ANNOTATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as an annotation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_ARGUMENT_TYPE_REFERENCE TYPE_ARGUMENT_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type argument in a parameterized type or a parameterized method.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_VARIABLE_BOUND_TYPE_REFERENCE TYPE_VARIABLE_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type variable bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#WILDCARD_BOUND_TYPE_REFERENCE WILDCARD_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a wildcard bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#INSTANCEOF_TYPE_REFERENCE INSTANCEOF_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type of an <code>instanceof</code> expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPER_REFERENCE SUPER_REFERENCE}
+ *         		<td>Return only super field accesses or super method invocations (e.g. using the <code>super</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#QUALIFIED_REFERENCE QUALIFIED_REFERENCE}
+ *         		<td>Return only qualified field accesses or qualified method invocations.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THIS_REFERENCE THIS_REFERENCE}
+ *         		<td>Return only primary field accesses or primary method invocations (e.g. using the <code>this</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPLICIT_THIS_REFERENCE IMPLICIT_THIS_REFERENCE}
+ *         		<td>Return only field accesses or method invocations without any qualification.
+ * 			</table>
+ *		</li>
+ *	</ul>
+ * @param matchRule one of the following match rules
+ * 	<ul>
+ * 		<li>{@link #R_EXACT_MATCH}</li>
+ * 		<li>{@link #R_PREFIX_MATCH}</li>
+ * 		<li>{@link #R_PATTERN_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
+ * 	</ul>
+ * 	, which may be also combined with one of the following flags:
+ * 	<ul>
+ * 		<li>{@link #R_CASE_SENSITIVE}</li>
+ * 		<li>{@link #R_ERASURE_MATCH}</li>
+ * 		<li>{@link #R_EQUIVALENT_MATCH}</li>
+ * 	</ul>
+ *		For example,
+ *		<ul>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}: if an exact
+ *				and case sensitive match is requested,</li>
+ *			<li>{@link #R_PREFIX_MATCH} if a case insensitive prefix match is requested</li>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}: if a case
+ *				insensitive and erasure match is requested.</li>
+ *		</ul>
+ * 	<p>Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} has no effect
+ * 	on non-generic types/methods search.</p>
+ * 	<p>
+ * 	Note also that the default behavior for generic types/methods search is to find exact matches.</p>
+ * @return a search pattern on the given string pattern, or <code>null</code> if the string pattern is ill-formed
+ */
+public static SearchPattern createPattern(String stringPattern, int searchFor, int limitTo, int matchRule) {
+	if (stringPattern == null || stringPattern.length() == 0) return null;
+
+	if ((matchRule = validateMatchRule(stringPattern, matchRule)) == -1) {
+		return null;
+	}
+
+	// Ignore additional nature flags
+	limitTo &= ~(IJavaSearchConstants.IGNORE_DECLARING_TYPE+IJavaSearchConstants.IGNORE_RETURN_TYPE);
+
+	switch (searchFor) {
+		case IJavaSearchConstants.CLASS:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_SUFFIX);
+		case IJavaSearchConstants.CLASS_AND_INTERFACE:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_AND_INTERFACE_SUFFIX);
+		case IJavaSearchConstants.CLASS_AND_ENUM:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_AND_ENUM_SUFFIX);
+		case IJavaSearchConstants.INTERFACE:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.INTERFACE_SUFFIX);
+		case IJavaSearchConstants.INTERFACE_AND_ANNOTATION:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX);
+		case IJavaSearchConstants.ENUM:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.ENUM_SUFFIX);
+		case IJavaSearchConstants.ANNOTATION_TYPE:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.ANNOTATION_TYPE_SUFFIX);
+		case IJavaSearchConstants.TYPE:
+			return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.TYPE_SUFFIX);
+		case IJavaSearchConstants.METHOD:
+			return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, false/*not a constructor*/);
+		case IJavaSearchConstants.CONSTRUCTOR:
+			return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, true/*constructor*/);
+		case IJavaSearchConstants.FIELD:
+			return createFieldPattern(stringPattern, limitTo, matchRule);
+		case IJavaSearchConstants.PACKAGE:
+			return createPackagePattern(stringPattern, limitTo, matchRule);
+	}
+	return null;
+}
+
+/**
+ * Returns a search pattern based on a given Java element.
+ * The pattern is used to trigger the appropriate search.
+ * <br>
+ * Note that for generic searches, the returned pattern consider {@link #R_ERASURE_MATCH} matches.
+ * If other kind of generic matches (i.e. {@link #R_EXACT_MATCH} or {@link #R_EQUIVALENT_MATCH})
+ * are expected, {@link #createPattern(IJavaElement, int, int)} method need to be used instead with
+ * the explicit match rule specified.
+ * <br>
+ * The pattern can be parameterized as follows:
+ *
+ * @param element the Java element the search pattern is based on
+ * @param limitTo determines the nature of the expected matches
+ *	<ul>
+ * 	<li>{@link IJavaSearchConstants#DECLARATIONS DECLARATIONS}: will search declarations matching
+ * 			with the corresponding element. In case the element is a method, declarations of matching
+ * 			methods in sub-types will also be found, allowing to find declarations of abstract methods, etc.
+ *				Some additional flags may be specified while searching declaration:
+ *				<ul>
+ *					<li>{@link IJavaSearchConstants#IGNORE_DECLARING_TYPE IGNORE_DECLARING_TYPE}: declaring type will be ignored
+ *							during the search.<br>
+ *							For example using following test case:
+ *					<pre>
+ *                  class A { A method() { return null; } }
+ *                  class B extends A { B method() { return null; } }
+ *                  class C { A method() { return null; } }
+ *					</pre>
+ *							search for <code>method</code> declaration with this flag
+ *							will return 2 matches: in A and in C
+ *					</li>
+ *					<li>{@link IJavaSearchConstants#IGNORE_RETURN_TYPE IGNORE_RETURN_TYPE}: return type will be ignored
+ *							during the search.<br>
+ *							Using same example, search for <code>method</code> declaration with this flag
+ *							will return 2 matches: in A and in B.
+ *					</li>
+ *				</ul>
+ *				Note that these two flags may be combined and both declaring and return types can be ignored
+ *				during the search. Then, using same example, search for <code>method</code> declaration
+ *				with these 2 flags will return 3 matches: in A, in B  and in C
+ * 	</li>
+ *		 <li>{@link IJavaSearchConstants#REFERENCES REFERENCES}: will search references to the given element.</li>
+ *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES ALL_OCCURRENCES}: will search for either declarations or
+ *				references as specified above.
+ *		</li>
+ *		 <li>All other fine grain constants defined in the <b>limitTo</b> category
+ *				of the {@link IJavaSearchConstants} are also accepted nature: 
+ * 			<table border=0>
+ *     			<tr>
+ *         		<th align=left>Fine grain constant
+ *         		<th align=left>Meaning
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#FIELD_DECLARATION_TYPE_REFERENCE FIELD_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a field declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a local variable declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#PARAMETER_DECLARATION_TYPE_REFERENCE PARAMETER_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a method parameter declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPERTYPE_TYPE_REFERENCE SUPERTYPE_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a super type or as a super interface.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THROWS_CLAUSE_TYPE_REFERENCE THROWS_CLAUSE_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a throws clause.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CAST_TYPE_REFERENCE CAST_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a cast expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CATCH_TYPE_REFERENCE CATCH_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a catch header.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CLASS_INSTANCE_CREATION_TYPE_REFERENCE CLASS_INSTANCE_CREATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in class instance creation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#RETURN_TYPE_REFERENCE RETURN_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a method return type.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPORT_DECLARATION_TYPE_REFERENCE IMPORT_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in an import declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#ANNOTATION_TYPE_REFERENCE ANNOTATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as an annotation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_ARGUMENT_TYPE_REFERENCE TYPE_ARGUMENT_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type argument in a parameterized type or a parameterized method.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_VARIABLE_BOUND_TYPE_REFERENCE TYPE_VARIABLE_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type variable bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#WILDCARD_BOUND_TYPE_REFERENCE WILDCARD_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a wildcard bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#INSTANCEOF_TYPE_REFERENCE INSTANCEOF_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type of an <code>instanceof</code> expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPER_REFERENCE SUPER_REFERENCE}
+ *         		<td>Return only super field accesses or super method invocations (e.g. using the <code>super</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#QUALIFIED_REFERENCE QUALIFIED_REFERENCE}
+ *         		<td>Return only qualified field accesses or qualified method invocations.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THIS_REFERENCE THIS_REFERENCE}
+ *         		<td>Return only primary field accesses or primary method invocations (e.g. using the <code>this</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPLICIT_THIS_REFERENCE IMPLICIT_THIS_REFERENCE}
+ *         		<td>Return only field accesses or method invocations without any qualification.
+ * 			</table>
+ *		</li>
+ *	</ul>
+ * @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
+ */
+public static SearchPattern createPattern(IJavaElement element, int limitTo) {
+	return createPattern(element, limitTo, R_EXACT_MATCH | R_CASE_SENSITIVE | R_ERASURE_MATCH);
+}
+
+/**
+ * Returns a search pattern based on a given Java element.
+ * The pattern is used to trigger the appropriate search, and can be parameterized as follows:
+ *
+ * @param element the Java element the search pattern is based on
+ * @param limitTo determines the nature of the expected matches
+ *	<ul>
+ * 	<li>{@link IJavaSearchConstants#DECLARATIONS DECLARATIONS}: will search declarations matching
+ * 			with the corresponding element. In case the element is a method, declarations of matching
+ * 			methods in sub-types will also be found, allowing to find declarations of abstract methods, etc.
+ *				Some additional flags may be specified while searching declaration:
+ *				<ul>
+ *					<li>{@link IJavaSearchConstants#IGNORE_DECLARING_TYPE IGNORE_DECLARING_TYPE}: declaring type will be ignored
+ *							during the search.<br>
+ *							For example using following test case:
+ *					<pre>
+ *                  class A { A method() { return null; } }
+ *                  class B extends A { B method() { return null; } }
+ *                  class C { A method() { return null; } }
+ *					</pre>
+ *							search for <code>method</code> declaration with this flag
+ *							will return 2 matches: in A and in C
+ *					</li>
+ *					<li>{@link IJavaSearchConstants#IGNORE_RETURN_TYPE IGNORE_RETURN_TYPE}: return type will be ignored
+ *							during the search.<br>
+ *							Using same example, search for <code>method</code> declaration with this flag
+ *							will return 2 matches: in A and in B.
+ *					</li>
+ *				</ul>
+ *				Note that these two flags may be combined and both declaring and return types can be ignored
+ *				during the search. Then, using same example, search for <code>method</code> declaration
+ *				with these 2 flags will return 3 matches: in A, in B  and in C
+ * 	</li>
+ *		 <li>{@link IJavaSearchConstants#REFERENCES REFERENCES}: will search references to the given element.</li>
+ *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES ALL_OCCURRENCES}: will search for either declarations or
+ *				references as specified above.
+ *		</li>
+ *		 <li>All other fine grain constants defined in the <b>limitTo</b> category
+ *				of the {@link IJavaSearchConstants} are also accepted nature: 
+ * 			<table border=0>
+ *     			<tr>
+ *         		<th align=left>Fine grain constant
+ *         		<th align=left>Meaning
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#FIELD_DECLARATION_TYPE_REFERENCE FIELD_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a field declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a local variable declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#PARAMETER_DECLARATION_TYPE_REFERENCE PARAMETER_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as the type of a method parameter declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPERTYPE_TYPE_REFERENCE SUPERTYPE_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a super type or as a super interface.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THROWS_CLAUSE_TYPE_REFERENCE THROWS_CLAUSE_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a throws clause.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CAST_TYPE_REFERENCE CAST_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a cast expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CATCH_TYPE_REFERENCE CATCH_TYPE_REFERENCE}
+ *         		<td>Return only type references used in a catch header.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#CLASS_INSTANCE_CREATION_TYPE_REFERENCE CLASS_INSTANCE_CREATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in class instance creation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#RETURN_TYPE_REFERENCE RETURN_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a method return type.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPORT_DECLARATION_TYPE_REFERENCE IMPORT_DECLARATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used in an import declaration.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#ANNOTATION_TYPE_REFERENCE ANNOTATION_TYPE_REFERENCE}
+ *         		<td>Return only type references used as an annotation.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_ARGUMENT_TYPE_REFERENCE TYPE_ARGUMENT_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type argument in a parameterized type or a parameterized method.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#TYPE_VARIABLE_BOUND_TYPE_REFERENCE TYPE_VARIABLE_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type variable bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#WILDCARD_BOUND_TYPE_REFERENCE WILDCARD_BOUND_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a wildcard bound.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#INSTANCEOF_TYPE_REFERENCE INSTANCEOF_TYPE_REFERENCE}
+ *         		<td>Return only type references used as a type of an <code>instanceof</code> expression.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#SUPER_REFERENCE SUPER_REFERENCE}
+ *         		<td>Return only super field accesses or super method invocations (e.g. using the <code>super</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#QUALIFIED_REFERENCE QUALIFIED_REFERENCE}
+ *         		<td>Return only qualified field accesses or qualified method invocations.
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#THIS_REFERENCE THIS_REFERENCE}
+ *         		<td>Return only primary field accesses or primary method invocations (e.g. using the <code>this</code> qualifier).
+ *     			<tr>
+ *         		<td>{@link IJavaSearchConstants#IMPLICIT_THIS_REFERENCE IMPLICIT_THIS_REFERENCE}
+ *         		<td>Return only field accesses or method invocations without any qualification.
+ * 			</table>
+ * 	</li>
+ *	</ul>
+ * @param matchRule one of the following match rules:
+ * 	<ul>
+ * 		<li>{@link #R_EXACT_MATCH}</li>
+ * 		<li>{@link #R_PREFIX_MATCH}</li>
+ * 		<li>{@link #R_PATTERN_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_MATCH}</li>
+ * 		<li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
+ * 	</ul>
+ * 	, which may be also combined with one of the following flags:
+ * 	<ul>
+ * 		<li>{@link #R_CASE_SENSITIVE}</li>
+ * 		<li>{@link #R_ERASURE_MATCH}</li>
+ * 		<li>{@link #R_EQUIVALENT_MATCH}</li>
+ * 	</ul>
+ *		For example,
+ *		<ul>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}: if an exact
+ *				and case sensitive match is requested,</li>
+ *			<li>{@link #R_PREFIX_MATCH} if a case insensitive prefix match is requested</li>
+ *			<li>{@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}: if a case
+ *				insensitive and erasure match is requested.</li>
+ *		</ul>
+ * 	Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} has no effect
+ * 	on non-generic types/methods search.
+ * 	<p>
+ * 	Note also that default behavior for generic types/methods search is to find exact matches.
+ * @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
+ * @since 3.1
+ */
+public static SearchPattern createPattern(IJavaElement element, int limitTo, int matchRule) {
+	SearchPattern searchPattern = null;
+	int lastDot;
+	boolean ignoreDeclaringType = false;
+	boolean ignoreReturnType = false;
+	int maskedLimitTo = limitTo & ~(IJavaSearchConstants.IGNORE_DECLARING_TYPE+IJavaSearchConstants.IGNORE_RETURN_TYPE);
+	if (maskedLimitTo == IJavaSearchConstants.DECLARATIONS || maskedLimitTo == IJavaSearchConstants.ALL_OCCURRENCES) {
+		ignoreDeclaringType = (limitTo & IJavaSearchConstants.IGNORE_DECLARING_TYPE) != 0;
+		ignoreReturnType = (limitTo & IJavaSearchConstants.IGNORE_RETURN_TYPE) != 0;
+	}
+	if ((matchRule = validateMatchRule(null, matchRule)) == -1) {
+		return null;
+	}
+	char[] declaringSimpleName = null;
+	char[] declaringQualification = null;
+	switch (element.getElementType()) {
+		case IJavaElement.FIELD :
+			IField field = (IField) element;
+			if (!ignoreDeclaringType) {
+				IType declaringClass = field.getDeclaringType();
+				declaringSimpleName = declaringClass.getElementName().toCharArray();
+				declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
+				char[][] enclosingNames = enclosingTypeNames(declaringClass);
+				if (enclosingNames.length > 0) {
+					declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
+				}
+			}
+			char[] name = field.getElementName().toCharArray();
+			char[] typeSimpleName = null;
+			char[] typeQualification = null;
+			String typeSignature = null;
+			if (!ignoreReturnType) {
+				try {
+					typeSignature = field.getTypeSignature();
+					char[] signature = typeSignature.toCharArray();
+					char[] typeErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+					CharOperation.replace(typeErasure, '$', '.');
+					if ((lastDot = CharOperation.lastIndexOf('.', typeErasure)) == -1) {
+						typeSimpleName = typeErasure;
+					} else {
+						typeSimpleName = CharOperation.subarray(typeErasure, lastDot + 1, typeErasure.length);
+						typeQualification = CharOperation.subarray(typeErasure, 0, lastDot);
+						if (!field.isBinary()) {
+							// prefix with a '*' as the full qualification could be bigger (because of an import)
+							typeQualification = CharOperation.concat(IIndexConstants.ONE_STAR, typeQualification);
+						}
+					}
+				} catch (JavaModelException e) {
+					return null;
+				}
+			}
+			// Create field pattern
+			searchPattern =
+				new FieldPattern(
+					name,
+					declaringQualification,
+					declaringSimpleName,
+					typeQualification,
+					typeSimpleName,
+					typeSignature,
+					limitTo,
+					matchRule);
+			break;
+		case IJavaElement.IMPORT_DECLARATION :
+			String elementName = element.getElementName();
+			lastDot = elementName.lastIndexOf('.');
+			if (lastDot == -1) return null; // invalid import declaration
+			IImportDeclaration importDecl = (IImportDeclaration)element;
+			if (importDecl.isOnDemand()) {
+				searchPattern = createPackagePattern(elementName.substring(0, lastDot), maskedLimitTo, matchRule);
+			} else {
+				searchPattern =
+					createTypePattern(
+						elementName.substring(lastDot+1).toCharArray(),
+						elementName.substring(0, lastDot).toCharArray(),
+						null,
+						null,
+						null,
+						maskedLimitTo,
+						matchRule);
+			}
+			break;
+		case IJavaElement.LOCAL_VARIABLE :
+			LocalVariable localVar = (LocalVariable) element;
+			searchPattern = new LocalVariablePattern(localVar, limitTo, matchRule);
+			break;
+		case IJavaElement.TYPE_PARAMETER:
+			ITypeParameter typeParam = (ITypeParameter) element;
+			boolean findParamDeclarations = true;
+			boolean findParamReferences = true;
+			switch (maskedLimitTo) {
+				case IJavaSearchConstants.DECLARATIONS :
+					findParamReferences = false;
+					break;
+				case IJavaSearchConstants.REFERENCES :
+					findParamDeclarations = false;
+					break;
+			}
+			searchPattern =
+				new TypeParameterPattern(
+					findParamDeclarations,
+					findParamReferences,
+					typeParam,
+					matchRule);
+			break;
+		case IJavaElement.METHOD :
+			IMethod method = (IMethod) element;
+			boolean isConstructor;
+			try {
+				isConstructor = method.isConstructor();
+			} catch (JavaModelException e) {
+				return null;
+			}
+			IType declaringClass = method.getDeclaringType();
+			if (ignoreDeclaringType) {
+				if (isConstructor) declaringSimpleName = declaringClass.getElementName().toCharArray();
+			} else {
+				declaringSimpleName = declaringClass.getElementName().toCharArray();
+				declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
+				char[][] enclosingNames = enclosingTypeNames(declaringClass);
+				if (enclosingNames.length > 0) {
+					declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
+				}
+			}
+			char[] selector = method.getElementName().toCharArray();
+			char[] returnSimpleName = null;
+			char[] returnQualification = null;
+			String returnSignature = null;
+			if (!ignoreReturnType) {
+				try {
+					returnSignature = method.getReturnType();
+					char[] signature = returnSignature.toCharArray();
+					char[] returnErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+					CharOperation.replace(returnErasure, '$', '.');
+					if ((lastDot = CharOperation.lastIndexOf('.', returnErasure)) == -1) {
+						returnSimpleName = returnErasure;
+					} else {
+						returnSimpleName = CharOperation.subarray(returnErasure, lastDot + 1, returnErasure.length);
+						returnQualification = CharOperation.subarray(returnErasure, 0, lastDot);
+						if (!method.isBinary()) {
+							// prefix with a '*' as the full qualification could be bigger (because of an import)
+							CharOperation.concat(IIndexConstants.ONE_STAR, returnQualification);
+						}
+					}
+				} catch (JavaModelException e) {
+					return null;
+				}
+			}
+			String[] parameterTypes = method.getParameterTypes();
+			int paramCount = parameterTypes.length;
+			char[][] parameterSimpleNames = new char[paramCount][];
+			char[][] parameterQualifications = new char[paramCount][];
+			String[] parameterSignatures = new String[paramCount];
+			for (int i = 0; i < paramCount; i++) {
+				parameterSignatures[i] = parameterTypes[i];
+				char[] signature = parameterSignatures[i].toCharArray();
+				char[] paramErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+				CharOperation.replace(paramErasure, '$', '.');
+				if ((lastDot = CharOperation.lastIndexOf('.', paramErasure)) == -1) {
+					parameterSimpleNames[i] = paramErasure;
+					parameterQualifications[i] = null;
+				} else {
+					parameterSimpleNames[i] = CharOperation.subarray(paramErasure, lastDot + 1, paramErasure.length);
+					parameterQualifications[i] = CharOperation.subarray(paramErasure, 0, lastDot);
+					if (!method.isBinary()) {
+						// prefix with a '*' as the full qualification could be bigger (because of an import)
+						CharOperation.concat(IIndexConstants.ONE_STAR, parameterQualifications[i]);
+					}
+				}
+			}
+
+			// Create method/constructor pattern
+			if (isConstructor) {
+				searchPattern =
+					new ConstructorPattern(
+						declaringSimpleName,
+						declaringQualification,
+						parameterQualifications,
+						parameterSimpleNames,
+						parameterSignatures,
+						method,
+						limitTo,
+						matchRule);
+			} else {
+				searchPattern =
+					new MethodPattern(
+						selector,
+						declaringQualification,
+						declaringSimpleName,
+						returnQualification,
+						returnSimpleName,
+						returnSignature,
+						parameterQualifications,
+						parameterSimpleNames,
+						parameterSignatures,
+						method,
+						limitTo,
+						matchRule);
+			}
+			break;
+		case IJavaElement.TYPE :
+			IType type = (IType)element;
+			searchPattern = 	createTypePattern(
+						type.getElementName().toCharArray(),
+						type.getPackageFragment().getElementName().toCharArray(),
+						ignoreDeclaringType ? null : enclosingTypeNames(type),
+						null,
+						type,
+						maskedLimitTo,
+						matchRule);
+			break;
+		case IJavaElement.PACKAGE_DECLARATION :
+		case IJavaElement.PACKAGE_FRAGMENT :
+			searchPattern = createPackagePattern(element.getElementName(), maskedLimitTo, matchRule);
+			break;
+	}
+	if (searchPattern != null)
+		MatchLocator.setFocus(searchPattern, element);
+	return searchPattern;
+}
+
+private static SearchPattern createTypePattern(char[] simpleName, char[] packageName, char[][] enclosingTypeNames, String typeSignature, IType type, int limitTo, int matchRule) {
+	switch (limitTo) {
+		case IJavaSearchConstants.DECLARATIONS :
+			return new TypeDeclarationPattern(
+				packageName,
+				enclosingTypeNames,
+				simpleName,
+				IIndexConstants.TYPE_SUFFIX,
+				matchRule);
+		case IJavaSearchConstants.REFERENCES :
+			if (type != null) {
+				return new TypeReferencePattern(
+					CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+					simpleName,
+					type,
+					matchRule);
+			}
+			return new TypeReferencePattern(
+				CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+				simpleName,
+				typeSignature,
+				matchRule);
+		case IJavaSearchConstants.IMPLEMENTORS :
+			return new SuperTypeReferencePattern(
+				CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+				simpleName,
+				SuperTypeReferencePattern.ONLY_SUPER_INTERFACES,
+				matchRule);
+		case IJavaSearchConstants.ALL_OCCURRENCES :
+			return new OrPattern(
+				new TypeDeclarationPattern(
+					packageName,
+					enclosingTypeNames,
+					simpleName,
+					IIndexConstants.TYPE_SUFFIX,
+					matchRule),
+				(type != null)
+					? new TypeReferencePattern(
+						CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+						simpleName,
+						type,
+						matchRule)
+					: new TypeReferencePattern(
+						CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+						simpleName,
+						typeSignature,
+						matchRule)
+			);
+		default:
+			if (type != null) {
+				return new TypeReferencePattern(
+					CharOperation.concatWith(packageName, enclosingTypeNames, '.'),
+					simpleName,
+					type,
+					limitTo,
+					matchRule);
+			}
+	}
+	return null;
+}
+
+private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule, char indexSuffix) {
+	// use 1.7 as the source level as there are more valid tokens in 1.7 mode
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=376673
+	Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_7/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+	scanner.setSource(patternString.toCharArray());
+	String type = null;
+	int token;
+	try {
+		token = scanner.getNextToken();
+	} catch (InvalidInputException e) {
+		return null;
+	}
+	int argCount = 0;
+	while (token != TerminalTokens.TokenNameEOF) {
+		if (argCount == 0) {
+			switch (token) {
+				case TerminalTokens.TokenNameWHITESPACE:
+					break;
+				case TerminalTokens.TokenNameLESS:
+					argCount++;
+					// $FALL-THROUGH$ - fall through default case to add token to type
+				default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+					if (type == null)
+						type = scanner.getCurrentTokenString();
+					else
+						type += scanner.getCurrentTokenString();
+			}
+		} else {
+			switch (token) {
+				case TerminalTokens.TokenNameGREATER:
+				case TerminalTokens.TokenNameRIGHT_SHIFT:
+				case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+					argCount--;
+					break;
+				case TerminalTokens.TokenNameLESS:
+					argCount++;
+					break;
+			}
+			if (type == null) return null; // invalid syntax
+			type += scanner.getCurrentTokenString();
+		}
+		try {
+			token = scanner.getNextToken();
+		} catch (InvalidInputException e) {
+			return null;
+		}
+	}
+	if (type == null) return null;
+	String typeSignature = null;
+	char[] qualificationChars = null, typeChars = null;
+
+	// get type part and signature
+	char[] typePart = null;
+	try {
+		typeSignature = Signature.createTypeSignature(type, false);
+		if (typeSignature.indexOf(Signature.C_GENERIC_START) < 0) {
+			typePart = type.toCharArray();
+		} else {
+			typePart = Signature.toCharArray(Signature.getTypeErasure(typeSignature.toCharArray()));
+		}
+	}
+	catch (IllegalArgumentException iae) {
+		// string is not a valid type syntax
+		return null;
+	}
+
+	// get qualification name
+	int lastDotPosition = CharOperation.lastIndexOf('.', typePart);
+	if (lastDotPosition >= 0) {
+		qualificationChars = CharOperation.subarray(typePart, 0, lastDotPosition);
+		if (qualificationChars.length == 1 && qualificationChars[0] == '*')
+			qualificationChars = null;
+		typeChars = CharOperation.subarray(typePart, lastDotPosition+1, typePart.length);
+	} else {
+		typeChars = typePart;
+	}
+	if (typeChars.length == 1 && typeChars[0] == '*') {
+		typeChars = null;
+	}
+	switch (limitTo) {
+		case IJavaSearchConstants.DECLARATIONS : // cannot search for explicit member types
+			return new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule);
+		case IJavaSearchConstants.REFERENCES :
+			return new TypeReferencePattern(qualificationChars, typeChars, typeSignature, indexSuffix, matchRule);
+		case IJavaSearchConstants.IMPLEMENTORS :
+			return new SuperTypeReferencePattern(qualificationChars, typeChars, SuperTypeReferencePattern.ONLY_SUPER_INTERFACES, indexSuffix, matchRule);
+		case IJavaSearchConstants.ALL_OCCURRENCES :
+			return new OrPattern(
+				new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule),// cannot search for explicit member types
+				new TypeReferencePattern(qualificationChars, typeChars, typeSignature, indexSuffix, matchRule));
+		default:
+			return new TypeReferencePattern(qualificationChars, typeChars, typeSignature, limitTo, indexSuffix, matchRule);
+	}
+}
+/**
+ * Returns the enclosing type names of the given type.
+ */
+private static char[][] enclosingTypeNames(IType type) {
+	IJavaElement parent = type.getParent();
+	switch (parent.getElementType()) {
+		case IJavaElement.CLASS_FILE:
+			// For a binary type, the parent is not the enclosing type, but the declaring type is.
+			// (see bug 20532  Declaration of member binary type not found)
+			IType declaringType = type.getDeclaringType();
+			if (declaringType == null) return CharOperation.NO_CHAR_CHAR;
+			return CharOperation.arrayConcat(
+				enclosingTypeNames(declaringType),
+				declaringType.getElementName().toCharArray());
+		case IJavaElement.COMPILATION_UNIT:
+			return CharOperation.NO_CHAR_CHAR;
+		case IJavaElement.FIELD:
+		case IJavaElement.INITIALIZER:
+		case IJavaElement.METHOD:
+			IType declaringClass = ((IMember) parent).getDeclaringType();
+			return CharOperation.arrayConcat(
+				enclosingTypeNames(declaringClass),
+				new char[][] {declaringClass.getElementName().toCharArray(), IIndexConstants.ONE_STAR});
+		case IJavaElement.TYPE:
+			return CharOperation.arrayConcat(
+				enclosingTypeNames((IType)parent),
+				parent.getElementName().toCharArray());
+		default:
+			return null;
+	}
+}
+
+/**
+ * Decode the given index key in this pattern. The decoded index key is used by
+ * {@link #matchesDecodedKey(SearchPattern)} to find out if the corresponding index entry
+ * should be considered.
+ * <p>
+ * This method should be re-implemented in subclasses that need to decode an index key.
+ * </p>
+ *
+ * @param key the given index key
+ */
+public void decodeIndexKey(char[] key) {
+	// called from findIndexMatches(), override as necessary
+}
+/**
+ * Query a given index for matching entries. Assumes the sender has opened the index and will close when finished.
+ * 
+ * @noreference This method is not intended to be referenced by clients. 
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor monitor) throws IOException {
+	if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+	try {
+		index.startQuery();
+		SearchPattern pattern = currentPattern();
+		EntryResult[] entries = pattern.queryIn(index);
+		if (entries == null) return;
+
+		SearchPattern decodedResult = pattern.getBlankPattern();
+		String containerPath = index.containerPath;
+		char separator = index.separator;
+		for (int i = 0, l = entries.length; i < l; i++) {
+			if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+
+			EntryResult entry = entries[i];
+			decodedResult.decodeIndexKey(entry.getWord());
+			if (pattern.matchesDecodedKey(decodedResult)) {
+				// TODO (kent) some clients may not need the document names
+				String[] names = entry.getDocumentNames(index);
+				for (int j = 0, n = names.length; j < n; j++)
+					acceptMatch(names[j], containerPath, separator, decodedResult, requestor, participant, scope, monitor);
+			}
+		}
+	} finally {
+		index.stopQuery();
+	}
+}
+/**
+ * Returns a blank pattern that can be used as a record to decode an index key.
+ * <p>
+ * Implementors of this method should return a new search pattern that is going to be used
+ * to decode index keys.
+ * </p>
+ *
+ * @return a new blank pattern
+ * @see #decodeIndexKey(char[])
+ */
+public abstract SearchPattern getBlankPattern();
+/**
+ * Returns a key to find in relevant index categories, if null then all index entries are matched.
+ * The key will be matched according to some match rule. These potential matches
+ * will be further narrowed by the match locator, but precise match locating can be expensive,
+ * and index query should be as accurate as possible so as to eliminate obvious false hits.
+ * <p>
+ * This method should be re-implemented in subclasses that need to narrow down the
+ * index query.
+ * </p>
+ *
+ * @return an index key from this pattern, or <code>null</code> if all index entries are matched.
+ */
+public char[] getIndexKey() {
+	return null; // called from queryIn(), override as necessary
+}
+/**
+ * Returns an array of index categories to consider for this index query.
+ * These potential matches will be further narrowed by the match locator, but precise
+ * match locating can be expensive, and index query should be as accurate as possible
+ * so as to eliminate obvious false hits.
+ * <p>
+ * This method should be re-implemented in subclasses that need to narrow down the
+ * index query.
+ * </p>
+ *
+ * @return an array of index categories
+ */
+public char[][] getIndexCategories() {
+	return CharOperation.NO_CHAR_CHAR; // called from queryIn(), override as necessary
+}
+/**
+ * Returns the rule to apply for matching index keys. Can be exact match, prefix match, pattern match or regexp match.
+ * Rule can also be combined with a case sensitivity flag.
+ *
+ * @return one of R_EXACT_MATCH, R_PREFIX_MATCH, R_PATTERN_MATCH, R_REGEXP_MATCH combined with R_CASE_SENSITIVE,
+ *   e.g. R_EXACT_MATCH | R_CASE_SENSITIVE if an exact and case sensitive match is requested,
+ *   or R_PREFIX_MATCH if a prefix non case sensitive match is requested.
+ */
+public final int getMatchRule() {
+	return this.matchRule;
+}
+/**
+ * @noreference This method is not intended to be referenced by clients. 
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public boolean isPolymorphicSearch() {
+	return false;
+}
+/**
+ * Returns whether this pattern matches the given pattern (representing a decoded index key).
+ * <p>
+ * This method should be re-implemented in subclasses that need to narrow down the
+ * index query.
+ * </p>
+ *
+ * @param decodedPattern a pattern representing a decoded index key
+ * @return whether this pattern matches the given pattern
+ */
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	return true; // called from findIndexMatches(), override as necessary if index key is encoded
+}
+
+/**
+ * Returns whether the given name matches the given pattern.
+ * <p>
+ * This method should be re-implemented in subclasses that need to define how
+ * a name matches a pattern.
+ * </p>
+ *
+ * @param pattern the given pattern, or <code>null</code> to represent "*"
+ * @param name the given name
+ * @return whether the given name matches the given pattern
+ */
+public boolean matchesName(char[] pattern, char[] name) {
+	if (pattern == null) return true; // null is as if it was "*"
+	if (name != null) {
+		boolean isCaseSensitive = (this.matchRule & R_CASE_SENSITIVE) != 0;
+		int matchMode = this.matchRule & MODE_MASK;
+		boolean emptyPattern = pattern.length == 0;
+		if (emptyPattern && (this.matchRule & R_PREFIX_MATCH) != 0) return true;
+		boolean sameLength = pattern.length == name.length;
+		boolean canBePrefix = name.length >= pattern.length;
+		boolean matchFirstChar = !isCaseSensitive || emptyPattern || (name.length > 0 &&  pattern[0] == name[0]);
+		switch (matchMode) {
+			case R_EXACT_MATCH :
+				if (sameLength && matchFirstChar) {
+					return CharOperation.equals(pattern, name, isCaseSensitive);
+				}
+				break;
+
+			case R_PREFIX_MATCH :
+				if (canBePrefix && matchFirstChar) {
+					return CharOperation.prefixEquals(pattern, name, isCaseSensitive);
+				}
+				break;
+
+			case R_PATTERN_MATCH :
+				if (!isCaseSensitive)
+					pattern = CharOperation.toLowerCase(pattern);
+				return CharOperation.match(pattern, name, isCaseSensitive);
+
+			case SearchPattern.R_CAMELCASE_MATCH:
+				if (matchFirstChar && CharOperation.camelCaseMatch(pattern, name, false)) {
+					return true;
+				}
+				// only test case insensitive as CamelCase already verified prefix case sensitive
+				if (!isCaseSensitive && matchFirstChar && CharOperation.prefixEquals(pattern, name, false)) {
+					return true;
+				}
+				break;
+
+			case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+				return matchFirstChar && CharOperation.camelCaseMatch(pattern, name, true);
+
+			case R_REGEXP_MATCH :
+				// TODO implement regular expression match
+				return true;
+		}
+	}
+	return false;
+}
+
+/**
+ * Validate compatibility between given string pattern and match rule.
+ *<br>
+ * In certain circumstances described in the table below, the returned match rule is
+ * modified in order to provide a more efficient search pattern:
+ * <ol>
+ * 	<li>when the {@link #R_REGEXP_MATCH} flag is set, then <b>the pattern is
+ * 		rejected</b> as this kind of match is not supported yet and <code>-1</code>
+ * 		is returned).
+ * 	</li>
+ * 	<li>when the string pattern has <u>no</u> pattern characters (e.g. '*' or '?')
+ * 		and the pattern match flag is set (i.e. the match rule has the {@link #R_PATTERN_MATCH}
+ * 		flag), then <b>the pattern match flag is reset</b>.<br>
+ * 		Reversely, when the string pattern has pattern characters and the pattern
+ * 		match flag is <u>not</u> set, then <b>the pattern match flag is set</b>.
+ * 	</li>
+ * 	<li>when the {@link #R_PATTERN_MATCH} flag is set then, <b>other
+ * 		{@link #R_PREFIX_MATCH}, {@link #R_CAMELCASE_MATCH} or
+ * 		{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH} flags are reset</b>
+ * 		if they are tentatively combined.
+ * 	</li>
+ * 	<li>when the {@link #R_CAMELCASE_MATCH} flag is set, then <b>other
+ * 		{@link #R_PREFIX_MATCH} or {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}
+ * 		flags are reset</b> if they are tentatively combined.<br>
+ * 		Reversely, if the string pattern cannot be a camel case pattern (i.e. contains
+ * 		invalid Java identifier characters or does not have at least two uppercase
+ * 		characters - one for method camel case patterns), then <b>the CamelCase
+ * 		match flag is replaced with a prefix match flag</b>.
+ * 	</li>
+ * 	<li>when the {@link #R_CAMELCASE_SAME_PART_COUNT_MATCH} flag is set,
+ * 		then <b>({@link #R_PREFIX_MATCH} flag is reset</b> if it's tentatively
+ * 		combined.<br>
+ * 		Reversely, if the string pattern cannot be a camel case pattern (i.e. contains
+ * 		invalid Java identifier characters or does not have at least two uppercase
+ * 		characters - one for method camel case patterns), then <b>the CamelCase
+ * 		part count match flag is reset</b>.
+ * 	</li>
+ * </ol>
+ * <i>Note: the rules are validated in the documented order. For example, it means
+ * 	that as soon as the string pattern contains one pattern character, the pattern
+ * 	match flag will be set and all other match flags reset: validation of rule 2)
+ * 	followed by rule 3)...</i>
+ *<p>
+ *
+ * @param stringPattern The string pattern
+ * @param matchRule The match rule
+ * @return Optimized valid match rule or -1 if an incompatibility was detected.
+ * @since 3.2
+ */
+public static int validateMatchRule(String stringPattern, int matchRule) {
+
+	// Verify Regexp match rule
+	if ((matchRule & R_REGEXP_MATCH) != 0) {
+		// regexp is not supported yet
+		return -1;
+	}
+
+	// Verify Pattern match rule
+	if (stringPattern != null) {
+		int starIndex = stringPattern.indexOf('*');
+		int questionIndex = stringPattern.indexOf('?');
+		if (starIndex < 0 && questionIndex < 0) {
+			// reset pattern match flag if any
+			matchRule &= ~R_PATTERN_MATCH;
+		} else {
+			// force Pattern rule
+			matchRule |= R_PATTERN_MATCH;
+		}
+	}
+	if ((matchRule & R_PATTERN_MATCH) != 0) {
+		// reset other incompatible flags
+		matchRule &= ~R_CAMELCASE_MATCH;
+		matchRule &= ~R_CAMELCASE_SAME_PART_COUNT_MATCH;
+		matchRule &= ~R_PREFIX_MATCH;
+		return matchRule;
+	}
+
+	// Verify Camel Case
+	if ((matchRule & R_CAMELCASE_MATCH) != 0) {
+		// reset other incompatible flags
+		matchRule &= ~R_CAMELCASE_SAME_PART_COUNT_MATCH;
+		matchRule &= ~R_PREFIX_MATCH;
+		// validate camel case rule and modify it if not valid
+		boolean validCamelCase = validateCamelCasePattern(stringPattern);
+		if (!validCamelCase) {
+			matchRule &= ~R_CAMELCASE_MATCH;
+			matchRule |= R_PREFIX_MATCH;
+		}
+		return matchRule;
+	}
+
+	// Verify Camel Case with same count of parts
+	if ((matchRule & R_CAMELCASE_SAME_PART_COUNT_MATCH) != 0) {
+		// reset other incompatible flags
+		matchRule &= ~R_PREFIX_MATCH;
+		// validate camel case rule and modify it if not valid
+		boolean validCamelCase = validateCamelCasePattern(stringPattern);
+		if (!validCamelCase) {
+			matchRule &= ~R_CAMELCASE_SAME_PART_COUNT_MATCH;
+		}
+		return matchRule;
+	}
+
+	// Return the validated match rule (modified if necessary)
+	return matchRule;
+}
+
+/*
+ * Validate pattern for a camel case match rule
+ * @return
+ */
+private static boolean validateCamelCasePattern(String stringPattern) {
+	if (stringPattern == null) return true;
+	// verify sting pattern validity
+	int length = stringPattern.length();
+	boolean validCamelCase = true;
+	boolean lowerCamelCase = false;
+	int uppercase = 0;
+	for (int i=0; i<length && validCamelCase; i++) {
+		char ch = stringPattern.charAt(i);
+		validCamelCase = i==0 ? ScannerHelper.isJavaIdentifierStart(ch) : ScannerHelper.isJavaIdentifierPart(ch);
+		// at least one uppercase character is need in CamelCase pattern
+		// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=136313)
+		if (ScannerHelper.isUpperCase(ch)) uppercase++;
+		if (i==0) lowerCamelCase = uppercase == 0;
+	}
+	if (validCamelCase) {
+		validCamelCase = lowerCamelCase ? uppercase > 0 : uppercase > 1 ;
+	}
+	return validCamelCase;
+}
+
+/**
+ * @noreference This method is not intended to be referenced by clients. 
+ * @nooverride This method is not intended to be re-implemented or extended by clients.
+ */
+public EntryResult[] queryIn(Index index) throws IOException {
+	return index.query(getIndexCategories(), getIndexKey(), getMatchRule());
+}
+
+/**
+ * @see java.lang.Object#toString()
+ */
+public String toString() {
+	return "SearchPattern"; //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java
new file mode 100644
index 0000000..72841e6
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Collects the results from a search engine query.
+ * Clients implement a subclass to pass to <code>SearchEngine.search</code>
+ * and implement the {@link #acceptSearchMatch(SearchMatch)} method, and
+ * possibly override other life cycle methods.
+ * <p>
+ * The search engine calls <code>beginReporting()</code> when a search starts,
+ * then calls <code>acceptSearchMatch(...)</code> for each search result, and
+ * finally calls <code>endReporting()</code>. The order of the search results
+ * is unspecified and may vary from request to request; when displaying results,
+ * clients should not rely on the order but should instead arrange the results
+ * in an order that would be more meaningful to the user.
+ * </p>
+ *
+ * @see SearchEngine
+ * @since 3.0
+ */
+public abstract class SearchRequestor {
+
+	/**
+	 * Accepts the given search match.
+	 *
+	 * @param match the found match
+	 * @throws CoreException
+	 */
+	public abstract void acceptSearchMatch(SearchMatch match) throws CoreException;
+
+	/**
+	 * Notification sent before starting the search action.
+	 * Typically, this would tell a search requestor to clear previously
+	 * recorded search results.
+	 * <p>
+	 * The default implementation of this method does nothing. Subclasses
+	 * may override.
+	 * </p>
+	 */
+	public void beginReporting() {
+		// do nothing
+	}
+
+	/**
+	 * Notification sent after having completed the search action.
+	 * Typically, this would tell a search requestor collector that no more
+	 * results will be forthcoming in this search.
+	 * <p>
+	 * The default implementation of this method does nothing. Subclasses
+	 * may override.
+	 * </p>
+	 */
+	public void endReporting() {
+		// do nothing
+	}
+
+	/**
+	 * Intermediate notification sent when the given participant starts to
+	 * contribute.
+	 * <p>
+	 * The default implementation of this method does nothing. Subclasses
+	 * may override.
+	 * </p>
+	 *
+	 * @param participant the participant that is starting to contribute
+	 */
+	public void enterParticipant(SearchParticipant participant) {
+		// do nothing
+	}
+
+	/**
+	 * Intermediate notification sent when the given participant is finished
+	 * contributing.
+	 * <p>
+	 * The default implementation of this method does nothing. Subclasses
+	 * may override.
+	 * </p>
+	 *
+	 * @param participant the participant that finished contributing
+	 */
+	public void exitParticipant(SearchParticipant participant) {
+		// do nothing
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java
new file mode 100644
index 0000000..93ab008
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a type declaration.
+ * The element is an <code>IType</code>.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TypeDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new type declaration match.
+	 *
+	 * @param element the type declaration
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public TypeDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatch.java
new file mode 100644
index 0000000..9ca3a3a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatch.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.jdt.core.*;
+
+/**
+ * A match collected while {@link SearchEngine searching} for
+ * all type names methods using a {@link TypeNameRequestor requestor}.
+ * <p>
+ * The type of this match is available from {@link #getType()}.
+ * </p>
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ *
+ * @see TypeNameMatchRequestor
+ * @see SearchEngine#searchAllTypeNames(char[], int, char[], int, int, IJavaSearchScope, TypeNameMatchRequestor, int, org.eclipse.core.runtime.IProgressMonitor)
+ * @see SearchEngine#searchAllTypeNames(char[][], char[][], IJavaSearchScope, TypeNameMatchRequestor, int, org.eclipse.core.runtime.IProgressMonitor)
+ * @since 3.3
+ */
+public abstract class TypeNameMatch {
+
+/**
+ * Returns the accessibility of the type name match
+ *
+ * @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
+ */
+public abstract int getAccessibility();
+
+/**
+ * Returns the matched type's fully qualified name using '.' character
+ * as separator (e.g. package name + '.' enclosing type names + '.' simple name).
+ *
+ * @see #getType()
+ * @see IType#getFullyQualifiedName(char)
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return Fully qualified type name of the type
+ */
+public String getFullyQualifiedName() {
+	return getType().getFullyQualifiedName('.');
+}
+
+/**
+ * Returns the modifiers of the matched type.
+ * <p>
+ * This is a handle-only method as neither Java Model nor classpath
+ * initialization is done while calling this method.
+ *
+ * @return the type modifiers
+ */
+public abstract int getModifiers();
+
+/**
+ * Returns the package fragment root of the stored type.
+ * Package fragment root cannot be null and <strong>does</strong> exist.
+ *
+ * @see #getType()
+ * @see IJavaElement#getAncestor(int)
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return the existing java model package fragment root (i.e. cannot be <code>null</code>
+ * 	and will return <code>true</code> to <code>exists()</code> message).
+ */
+public IPackageFragmentRoot getPackageFragmentRoot() {
+	return (IPackageFragmentRoot) getType().getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+}
+
+/**
+ * Returns the package name of the stored type.
+ *
+ * @see #getType()
+ * @see IType#getPackageFragment()
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return the package name
+ */
+public String getPackageName() {
+	return getType().getPackageFragment().getElementName();
+}
+
+/**
+ * Returns the name of the stored type.
+ *
+ * @see #getType()
+ * @see IJavaElement#getElementName()
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return the type name
+ */
+public String getSimpleTypeName() {
+	return getType().getElementName();
+}
+
+/**
+ * Returns a java model type handle.
+ * This handle may exist or not, but is not supposed to be <code>null</code>.
+ * <p>
+ * This is a handle-only method as neither Java Model nor classpath
+ * initializations are done while calling this method.
+ *
+ * @see IType
+ * @return the non-null handle on matched java model type.
+ */
+public abstract IType getType();
+
+/**
+ * Name of the type container using '.' character
+ * as separator (e.g. package name + '.' + enclosing type names).
+ *
+ * @see #getType()
+ * @see IMember#getDeclaringType()
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return name of the type container
+ */
+public String getTypeContainerName() {
+	IType outerType = getType().getDeclaringType();
+	if (outerType != null) {
+		return outerType.getFullyQualifiedName('.');
+	} else {
+		return getType().getPackageFragment().getElementName();
+	}
+}
+
+/**
+ * Returns the matched type's type qualified name using '.' character
+ * as separator (e.g. enclosing type names + '.' + simple name).
+ *
+ * @see #getType()
+ * @see IType#getTypeQualifiedName(char)
+ *
+ * @throws NullPointerException if matched type is <code> null</code>
+ * @return fully qualified type name of the type
+ */
+public String getTypeQualifiedName() {
+	return getType().getTypeQualifiedName('.');
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatchRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatchRequestor.java
new file mode 100644
index 0000000..390593e
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameMatchRequestor.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+/**
+ * A <code>TypeNameMatchRequestor</code> collects matches from a <code>searchAllTypeNames</code>
+ * query to a <code>SearchEngine</code>. Clients must subclass this abstract class and pass an instance to the
+ * {@link SearchEngine#searchAllTypeNames(
+ *		char[] packageName,
+ *		int packageMatchRule,
+ *		char[] typeName,
+ *		int typeMatchRule,
+ *		int searchFor,
+ *		IJavaSearchScope scope,
+ *		TypeNameMatchRequestor nameMatchRequestor,
+ *		int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor)} method.
+ * Only top-level and member types are reported. Local types are not reported.
+ * <p>
+ * While {@link TypeNameRequestor} only reports type names information (e.g. package, enclosing types, simple name, modifiers, etc.),
+ * this class reports {@link TypeNameMatch} objects instead, which store this information and can return
+ * an {@link org.eclipse.jdt.core.IType} handle.
+ * </p>
+ * <p>
+ * This class may be subclassed by clients.
+ * </p>
+ * @see TypeNameMatch
+ * @see TypeNameRequestor
+ *
+ * @since 3.3
+ */
+public abstract class TypeNameMatchRequestor {
+	/**
+	 * Accepts a type name match ({@link TypeNameMatch}) which contains top-level or a member type
+	 * information as package name, enclosing types names, simple type name, modifiers, etc.
+	 *
+	 * @param match the match which contains all type information
+	 */
+	public abstract void acceptTypeNameMatch(TypeNameMatch match);
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java
new file mode 100644
index 0000000..159d81e
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+/**
+ * A <code>TypeNameRequestor</code> collects search results from a <code>searchAllTypeNames</code>
+ * query to a <code>SearchEngine</code>. Clients must subclass this abstract class and pass
+ * an instance to the <code>SearchEngine.searchAllTypeNames(...)</code> method. Only top-level and
+ * member types are reported. Local types are not reported.
+ * <p>
+ * This class may be subclassed by clients.
+ * </p>
+ * @since 3.1
+ */
+public abstract class TypeNameRequestor {
+	/**
+	 * Accepts a top-level or a member type.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses should override.
+	 * </p>
+	 *
+	 * @param modifiers the modifier flags of the type. Note that for source type,
+	 *		these flags may slightly differ from those get after resolution.
+	 *		For example an interface defined by <code>interface A {}</code>,
+	 *		although obviously public, will be returned false by <code>Flags.isPublic(modifiers)</code>
+	 *		due to the fact that its declaration does not explicitly define public flag.
+	 *		@see org.eclipse.jdt.core.Flags
+	 * @param packageName the package name as specified in the package declaration (i.e. a dot-separated name)
+	 * @param simpleTypeName the simple name of the type
+	 * @param enclosingTypeNames if the type is a member type,
+	 *          the simple names of the enclosing types from the outer-most to the
+	 *          direct parent of the type (for example, if the class is x.y.A$B$C then
+	 *          the enclosing types are [A, B]. This is an empty array if the type
+	 *          is a top-level type.
+	 * @param path the full path to the resource containing the type. If the resource is a .class file
+	 *          or a source file, this is the full path in the workspace to this resource. If the
+	 *          resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+	 *		 	 by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>:
+	 *			 the first path is the full OS path to the archive (if it is an external archive),
+	 *			 or the workspace relative <code>IPath</code> to the archive (if it is an internal archive),
+	 * 		 the second path is the path to the resource inside the archive.
+	 */
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
+		// do nothing
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java
new file mode 100644
index 0000000..b6745cc
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a type parameter declaration or reference.
+ * The element is an {@link org.eclipse.jdt.core.ITypeParameter}.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class TypeParameterDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new type parameter match.
+	 *
+	 * @param element the type parameter
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public TypeParameterDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java
new file mode 100644
index 0000000..5e74210
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a type parameter declaration or reference.
+ * The element is the inner-most enclosing member that references this type parameter.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class TypeParameterReferenceMatch extends SearchMatch {
+
+	/**
+	 * Creates a new field reference match.
+	 *
+	 * @param enclosingElement the inner-most enclosing member that references this field
+	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param insideDocComment <code>true</code> if this search match is inside a doc
+	 * comment, and <code>false</code> otherwise
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public TypeParameterReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+		super(enclosingElement, accuracy, offset, length, participant, resource);
+		setInsideDocComment(insideDocComment);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java
new file mode 100644
index 0000000..e84e8eb
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.*;
+
+/**
+ * A Java search match that represents a type reference.
+ * The element is the inner-most enclosing member that references this type.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TypeReferenceMatch extends ReferenceMatch {
+
+	private IJavaElement[] otherElements;
+
+/**
+ * Creates a new type reference match.
+ *
+ * @param enclosingElement the inner-most enclosing member that references this type
+ * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+ * @param offset the offset the match starts at, or -1 if unknown
+ * @param length the length of the match, or -1 if unknown
+ * @param insideDocComment <code>true</code> if this search match is inside a doc
+ * 				comment, and <code>false</code> otherwise
+ * @param participant the search participant that created the match
+ * @param resource the resource of the element
+ */
+public TypeReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+	super(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
+/**
+ * Returns other elements also enclosing the type reference. This typically can
+ * happen for multiple fields or local variable declarations.
+ *<p>
+ * For example,
+ * <ul>
+ * 	<li>searching for the references to the type <code>Test</code> in
+ *         <pre>
+ *         public class Test {
+ *             Test test1, test2, test3;
+ *             void method() {}
+ *         }
+ *         </pre>
+ * 		will return one match whose other elements is an array of two fields:
+ * 		{@link IField test2} and {@link IField test3}.
+ * 		<br><br>
+ * 	</li>
+ * 	<li>searching for the references to the type <code>Test</code> in
+ * 		<pre>
+ *         public class Test {
+ *             String str;
+ *             void method() {
+ *                 Test local1, local2, local3;
+ *             }
+ *         }
+ *         </pre>
+ * 		will return one match whose other elements is an array of two local
+ * 		variables: {@link ILocalVariable local2} and {@link ILocalVariable local3}.
+ * 		<br><br>
+ * 	</li>
+ * 	<li>since 3.6, searching for the references to the type
+ * 		<code>Test</code> in
+ * 		<pre>
+ *         public class Test {
+ *                 void testB(int testKind) {
+ *                         &#064;Annot int test1, test2;
+ *                 }
+ *         }
+ *         &#064;interface Annot {}
+ *         </pre>
+ * 		will return one match whose other elements is an array of one annotation:
+ * 		{@link IAnnotation Annot} which parent is the local variable
+ * 		{@link ILocalVariable test2}.
+ * 	</li>
+ * </ul>
+ *
+ * @return the other elements of the search match, or <code>null</code> if none
+ * @since 3.2
+ */
+public final IJavaElement[] getOtherElements() {
+	return this.otherElements;
+}
+
+/**
+ * Sets the other elements of this search match.
+ *
+ * @see #getOtherElements()
+ *
+ * @param otherElements the other elements of the match,
+ * 	or <code>null</code> if none
+ * @since 3.2
+ */
+public final void setOtherElements(IJavaElement[] otherElements) {
+	this.otherElements = otherElements;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/package.html b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/package.html
new file mode 100644
index 0000000..1d7beb0
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/package.html
@@ -0,0 +1,18 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides support for searching the workspace Java
+elements that match a particular description.
+<h2>
+Package Specification</h2>
+This package provides support for searching the workspace Java elements
+that match a particular description. In particular, it provides a search
+engine with a set of search patterns and search result requestors.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
new file mode 100644
index 0000000..e29b5a7
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -0,0 +1,1305 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import java.io.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.util.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
+
+public class DiskIndex {
+
+IndexLocation indexLocation;
+
+private int headerInfoOffset;
+private int numberOfChunks;
+private int sizeOfLastChunk;
+private int[] chunkOffsets;
+private int documentReferenceSize; // 1, 2 or more bytes... depends on # of document names
+private int startOfCategoryTables;
+private HashtableOfIntValues categoryOffsets, categoryEnds;
+
+private int cacheUserCount;
+private String[][] cachedChunks; // decompressed chunks of document names
+private HashtableOfObject categoryTables; // category name -> HashtableOfObject(words -> int[] of document #'s) or offset if not read yet
+private char[] cachedCategoryName;
+
+private static final int DEFAULT_BUFFER_SIZE = 2048;
+private static int BUFFER_READ_SIZE = DEFAULT_BUFFER_SIZE;
+private static final int BUFFER_WRITE_SIZE = DEFAULT_BUFFER_SIZE;
+private byte[] streamBuffer;
+private int bufferIndex, bufferEnd; // used when reading from the file into the streamBuffer
+private int streamEnd; // used when writing data from the streamBuffer to the file
+char separator = Index.DEFAULT_SEPARATOR;
+
+public static final String SIGNATURE= "INDEX VERSION 1.126"; //$NON-NLS-1$
+private static final char[] SIGNATURE_CHARS = SIGNATURE.toCharArray();
+public static boolean DEBUG = false;
+
+private static final int RE_INDEXED = -1;
+private static final int DELETED = -2;
+
+private static final int CHUNK_SIZE = 100;
+
+private static final SimpleSetOfCharArray INTERNED_CATEGORY_NAMES = new SimpleSetOfCharArray(20);
+
+static class IntList {
+
+int size;
+int[] elements;
+
+IntList(int[] elements) {
+	this.elements = elements;
+	this.size = elements.length;
+}
+void add(int newElement) {
+	if (this.size == this.elements.length) {
+		int newSize = this.size * 3;
+		if (newSize < 7) newSize = 7;
+		System.arraycopy(this.elements, 0, this.elements = new int[newSize], 0, this.size);
+	}
+	this.elements[this.size++] = newElement;
+}
+int[] asArray() {
+	int[] result = new int[this.size];
+	System.arraycopy(this.elements, 0, result, 0, this.size);
+	return result;
+}
+}
+
+
+DiskIndex() {
+	this.headerInfoOffset = -1;
+	this.numberOfChunks = -1;
+	this.sizeOfLastChunk = -1;
+	this.chunkOffsets = null;
+	this.documentReferenceSize = -1;
+	this.cacheUserCount = -1;
+	this.cachedChunks = null;
+	this.categoryTables = null;
+	this.cachedCategoryName = null;
+	this.categoryOffsets = null;
+	this.categoryEnds = null;
+}
+DiskIndex(IndexLocation location) throws IOException {
+	this();
+	if (location == null) {
+		throw new IllegalArgumentException();
+	}
+	this.indexLocation = location;
+}
+SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException {
+	// must skip over documents which have been added/changed/deleted in the memory index
+	String[] docNames = readAllDocumentNames();
+	SimpleSet results = new SimpleSet(docNames.length);
+	if (substring == null) {
+		if (memoryIndex == null) {
+			for (int i = 0, l = docNames.length; i < l; i++)
+				results.add(docNames[i]);
+		} else {
+			SimpleLookupTable docsToRefs = memoryIndex.docsToReferences;
+			for (int i = 0, l = docNames.length; i < l; i++) {
+				String docName = docNames[i];
+				if (!docsToRefs.containsKey(docName))
+					results.add(docName);
+			}
+		}
+	} else {
+		if (memoryIndex == null) {
+			for (int i = 0, l = docNames.length; i < l; i++)
+				if (docNames[i].startsWith(substring, 0))
+					results.add(docNames[i]);
+		} else {
+			SimpleLookupTable docsToRefs = memoryIndex.docsToReferences;
+			for (int i = 0, l = docNames.length; i < l; i++) {
+				String docName = docNames[i];
+				if (docName.startsWith(substring, 0) && !docsToRefs.containsKey(docName))
+					results.add(docName);
+			}
+		}
+	}
+	return results;
+}
+private HashtableOfObject addQueryResult(HashtableOfObject results, char[] word, Object docs, MemoryIndex memoryIndex, boolean prevResults) throws IOException {
+	// must skip over documents which have been added/changed/deleted in the memory index
+	if (results == null)
+		results = new HashtableOfObject(13);
+	EntryResult result = prevResults ? (EntryResult) results.get(word) : null;
+	if (memoryIndex == null) {
+		if (result == null)
+			results.putUnsafely(word, new EntryResult(word, docs));
+		else
+			result.addDocumentTable(docs);
+	} else {
+		SimpleLookupTable docsToRefs = memoryIndex.docsToReferences;
+		if (result == null) result = new EntryResult(word, null);
+		int[] docNumbers = readDocumentNumbers(docs);
+		for (int i = 0, l = docNumbers.length; i < l; i++) {
+			String docName = readDocumentName(docNumbers[i]);
+			if (!docsToRefs.containsKey(docName))
+				result.addDocumentName(docName);
+		}
+		if (!result.isEmpty())
+			results.put(word, result);
+	}
+	return results;
+}
+HashtableOfObject addQueryResults(char[][] categories, char[] key, int matchRule, MemoryIndex memoryIndex) throws IOException {
+	// assumes sender has called startQuery() & will call stopQuery() when finished
+	if (this.categoryOffsets == null) return null; // file is empty
+
+	HashtableOfObject results = null; // initialized if needed
+	
+	// No need to check the results table for duplicates while processing the
+	// first category table or if the first category tables doesn't have any results.
+	boolean prevResults = false;
+	if (key == null) {
+		for (int i = 0, l = categories.length; i < l; i++) {
+			HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], true); // cache if key is null since its a definite match
+			if (wordsToDocNumbers != null) {
+				char[][] words = wordsToDocNumbers.keyTable;
+				Object[] values = wordsToDocNumbers.valueTable;
+				if (results == null)
+					results = new HashtableOfObject(wordsToDocNumbers.elementSize);
+				for (int j = 0, m = words.length; j < m; j++)
+					if (words[j] != null)
+						results = addQueryResult(results, words[j], values[j], memoryIndex, prevResults);
+			}
+			prevResults = results != null;
+		}
+		if (results != null && this.cachedChunks == null)
+			cacheDocumentNames();
+	} else {
+		switch (matchRule) {
+			case SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE:
+				for (int i = 0, l = categories.length; i < l; i++) {
+					HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], false);
+					Object value;
+					if (wordsToDocNumbers != null && (value = wordsToDocNumbers.get(key)) != null)
+						results = addQueryResult(results, key, value, memoryIndex, prevResults);
+					prevResults = results != null;
+				}
+				break;
+			case SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE:
+				for (int i = 0, l = categories.length; i < l; i++) {
+					HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], false);
+					if (wordsToDocNumbers != null) {
+						char[][] words = wordsToDocNumbers.keyTable;
+						Object[] values = wordsToDocNumbers.valueTable;
+						for (int j = 0, m = words.length; j < m; j++) {
+							char[] word = words[j];
+							if (word != null && key[0] == word[0] && CharOperation.prefixEquals(key, word))
+								results = addQueryResult(results, word, values[j], memoryIndex, prevResults);
+						}
+					}
+					prevResults = results != null;
+				}
+				break;
+			default:
+				for (int i = 0, l = categories.length; i < l; i++) {
+					HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], false);
+					if (wordsToDocNumbers != null) {
+						char[][] words = wordsToDocNumbers.keyTable;
+						Object[] values = wordsToDocNumbers.valueTable;
+						for (int j = 0, m = words.length; j < m; j++) {
+							char[] word = words[j];
+							if (word != null && Index.isMatch(key, word, matchRule))
+								results = addQueryResult(results, word, values[j], memoryIndex, prevResults);
+						}
+					}
+					prevResults = results != null;
+				}
+		}
+	}
+
+	return results;
+}
+private void cacheDocumentNames() throws IOException {
+	// will need all document names so get them now
+	this.cachedChunks = new String[this.numberOfChunks][];
+	InputStream stream = this.indexLocation.getInputStream();
+	try {
+		if (this.numberOfChunks > 5) BUFFER_READ_SIZE <<= 1;
+		int offset = this.chunkOffsets[0];
+		stream.skip(offset);
+		this.streamBuffer = new byte[BUFFER_READ_SIZE];
+		this.bufferIndex = 0;
+		this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+		for (int i = 0; i < this.numberOfChunks; i++) {
+			int size = i == this.numberOfChunks - 1 ? this.sizeOfLastChunk : CHUNK_SIZE;
+			readChunk(this.cachedChunks[i] = new String[size], stream, 0, size);
+		}
+	} catch (IOException e) {
+		this.cachedChunks = null;
+		throw e;
+	} finally {
+		stream.close();
+		this.streamBuffer = null;
+		BUFFER_READ_SIZE = DEFAULT_BUFFER_SIZE;
+	}
+}
+private String[] computeDocumentNames(String[] onDiskNames, int[] positions, SimpleLookupTable indexedDocuments, MemoryIndex memoryIndex) {
+	int onDiskLength = onDiskNames.length;
+	Object[] docNames = memoryIndex.docsToReferences.keyTable;
+	Object[] referenceTables = memoryIndex.docsToReferences.valueTable;
+	if (onDiskLength == 0) {
+		// disk index was empty, so add every indexed document
+		for (int i = 0, l = referenceTables.length; i < l; i++)
+			if (referenceTables[i] != null)
+				indexedDocuments.put(docNames[i], null); // remember each new document
+
+		String[] newDocNames = new String[indexedDocuments.elementSize];
+		int count = 0;
+		Object[] added = indexedDocuments.keyTable;
+		for (int i = 0, l = added.length; i < l; i++)
+			if (added[i] != null)
+				newDocNames[count++] = (String) added[i];
+		Util.sort(newDocNames);
+		for (int i = 0, l = newDocNames.length; i < l; i++)
+			indexedDocuments.put(newDocNames[i], new Integer(i));
+		return newDocNames;
+	}
+
+	// initialize positions as if each document will remain in the same position
+	for (int i = 0; i < onDiskLength; i++)
+		positions[i] = i;
+
+	// find out if the memory index has any new or deleted documents, if not then the names & positions are the same
+	int numDeletedDocNames = 0;
+	nextPath : for (int i = 0, l = docNames.length; i < l; i++) {
+		String docName = (String) docNames[i];
+		if (docName != null) {
+			for (int j = 0; j < onDiskLength; j++) {
+				if (docName.equals(onDiskNames[j])) {
+					if (referenceTables[i] == null) {
+						positions[j] = DELETED;
+						numDeletedDocNames++;
+					} else {
+						positions[j] = RE_INDEXED;
+					}
+					continue nextPath;
+				}
+			}
+			if (referenceTables[i] != null)
+				indexedDocuments.put(docName, null); // remember each new document, skip deleted documents which were never saved
+		}
+	}
+
+	String[] newDocNames = onDiskNames;
+	if (numDeletedDocNames > 0 || indexedDocuments.elementSize > 0) {
+		// some new documents have been added or some old ones deleted
+		newDocNames = new String[onDiskLength + indexedDocuments.elementSize - numDeletedDocNames];
+		int count = 0;
+		for (int i = 0; i < onDiskLength; i++)
+			if (positions[i] >= RE_INDEXED)
+				newDocNames[count++] = onDiskNames[i]; // keep each unchanged document
+		Object[] added = indexedDocuments.keyTable;
+		for (int i = 0, l = added.length; i < l; i++)
+			if (added[i] != null)
+				newDocNames[count++] = (String) added[i]; // add each new document
+		Util.sort(newDocNames);
+		for (int i = 0, l = newDocNames.length; i < l; i++)
+			if (indexedDocuments.containsKey(newDocNames[i]))
+				indexedDocuments.put(newDocNames[i], new Integer(i)); // remember the position for each new document
+	}
+
+	// need to be able to look up an old position (ref# from a ref[]) and map it to its new position
+	// if its old position == DELETED then its forgotton
+	// if its old position == ReINDEXED then its also forgotten but its new position is needed to map references
+	int count = -1;
+	for (int i = 0; i < onDiskLength;) {
+		switch(positions[i]) {
+			case DELETED :
+				i++; // skip over deleted... references are forgotten
+				break;
+			case RE_INDEXED :
+				String newName = newDocNames[++count];
+				if (newName.equals(onDiskNames[i])) {
+					indexedDocuments.put(newName, new Integer(count)); // the reindexed docName that was at position i is now at position count
+					i++;
+				}
+				break;
+			default :
+				if (newDocNames[++count].equals(onDiskNames[i]))
+					positions[i++] = count; // the unchanged docName that was at position i is now at position count
+		}
+	}
+	return newDocNames;
+}
+private void copyQueryResults(HashtableOfObject categoryToWords, int newPosition) {
+	char[][] categoryNames = categoryToWords.keyTable;
+	Object[] wordSets = categoryToWords.valueTable;
+	for (int i = 0, l = categoryNames.length; i < l; i++) {
+		char[] categoryName = categoryNames[i];
+		if (categoryName != null) {
+			SimpleWordSet wordSet = (SimpleWordSet) wordSets[i];
+			HashtableOfObject wordsToDocs = (HashtableOfObject) this.categoryTables.get(categoryName);
+			if (wordsToDocs == null)
+				this.categoryTables.put(categoryName, wordsToDocs = new HashtableOfObject(wordSet.elementSize));
+
+			char[][] words = wordSet.words;
+			for (int j = 0, m = words.length; j < m; j++) {
+				char[] word = words[j];
+				if (word != null) {
+					Object o = wordsToDocs.get(word);
+					if (o == null) {
+						wordsToDocs.putUnsafely(word, new int[] {newPosition});
+					} else if (o instanceof IntList) {
+						((IntList) o).add(newPosition);
+					} else {
+						IntList list = new IntList((int[]) o);
+						list.add(newPosition);
+						wordsToDocs.put(word, list);
+					}
+				}
+			}
+		}
+	}
+}
+void initialize(boolean reuseExistingFile) throws IOException {
+	if (this.indexLocation.exists()) {
+		if (reuseExistingFile) {
+			InputStream stream = this.indexLocation.getInputStream();
+			if (stream == null) {
+				throw new IOException("Failed to use the index file"); //$NON-NLS-1$
+			}
+			this.streamBuffer = new byte[BUFFER_READ_SIZE];
+			this.bufferIndex = 0;
+			this.bufferEnd = stream.read(this.streamBuffer, 0, 128);
+			try {
+				char[] signature = readStreamChars(stream);
+				if (!CharOperation.equals(signature, SIGNATURE_CHARS)) {
+					throw new IOException(Messages.exception_wrongFormat);
+				}
+				this.headerInfoOffset = readStreamInt(stream);
+				if (this.headerInfoOffset > 0) { // file is empty if its not set
+					stream.skip(this.headerInfoOffset - this.bufferEnd); // assume that the header info offset is over current buffer end
+					this.bufferIndex = 0;
+					this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+					readHeaderInfo(stream);
+				}
+			} finally {
+				stream.close();
+			}
+			return;
+		}
+		if (!this.indexLocation.delete()) {
+			if (DEBUG)
+				System.out.println("initialize - Failed to delete index " + this.indexLocation); //$NON-NLS-1$
+			throw new IOException("Failed to delete index " + this.indexLocation); //$NON-NLS-1$
+		}
+	}
+	if (this.indexLocation.createNewFile()) {
+		FileOutputStream stream = new FileOutputStream(this.indexLocation.getIndexFile(), false);
+		try {
+			this.streamBuffer = new byte[BUFFER_READ_SIZE];
+			this.bufferIndex = 0;
+			writeStreamChars(stream, SIGNATURE_CHARS);
+			writeStreamInt(stream, -1); // file is empty
+			// write the buffer to the stream
+			if (this.bufferIndex > 0) {
+				stream.write(this.streamBuffer, 0, this.bufferIndex);
+				this.bufferIndex = 0;
+			}
+		} finally {
+			stream.close();
+		}
+	} else {
+		if (DEBUG)
+			System.out.println("initialize - Failed to create new index " + this.indexLocation); //$NON-NLS-1$
+		throw new IOException("Failed to create new index " + this.indexLocation); //$NON-NLS-1$
+	}
+}
+private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException {
+	if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file
+		if (DEBUG)
+			System.out.println("initializeFrom - Failed to delete temp index " + this.indexLocation); //$NON-NLS-1$
+	} else if (!newIndexFile.createNewFile()) {
+		if (DEBUG)
+			System.out.println("initializeFrom - Failed to create temp index " + this.indexLocation); //$NON-NLS-1$
+		throw new IOException("Failed to create temp index " + this.indexLocation); //$NON-NLS-1$
+	}
+
+	int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize;
+	this.categoryOffsets = new HashtableOfIntValues(size);
+	this.categoryEnds = new HashtableOfIntValues(size);
+	this.categoryTables = new HashtableOfObject(size);
+	this.separator = diskIndex.separator;
+}
+private void mergeCategories(DiskIndex onDisk, int[] positions, FileOutputStream stream) throws IOException {
+	// at this point, this.categoryTables contains the names -> wordsToDocs added in copyQueryResults()
+	char[][] oldNames = onDisk.categoryOffsets.keyTable;
+	for (int i = 0, l = oldNames.length; i < l; i++) {
+		char[] oldName = oldNames[i];
+		if (oldName != null && !this.categoryTables.containsKey(oldName))
+			this.categoryTables.put(oldName, null);
+	}
+
+	char[][] categoryNames = this.categoryTables.keyTable;
+	for (int i = 0, l = categoryNames.length; i < l; i++)
+		if (categoryNames[i] != null)
+			mergeCategory(categoryNames[i], onDisk, positions, stream);
+	this.categoryTables = null;
+}
+private void mergeCategory(char[] categoryName, DiskIndex onDisk, int[] positions, FileOutputStream stream) throws IOException {
+	HashtableOfObject wordsToDocs = (HashtableOfObject) this.categoryTables.get(categoryName);
+	if (wordsToDocs == null)
+		wordsToDocs = new HashtableOfObject(3);
+
+	HashtableOfObject oldWordsToDocs = onDisk.readCategoryTable(categoryName, true);
+	if (oldWordsToDocs != null) {
+		char[][] oldWords = oldWordsToDocs.keyTable;
+		Object[] oldArrayOffsets = oldWordsToDocs.valueTable;
+		nextWord: for (int i = 0, l = oldWords.length; i < l; i++) {
+			char[] oldWord = oldWords[i];
+			if (oldWord != null) {
+				int[] oldDocNumbers = (int[]) oldArrayOffsets[i];
+				int length = oldDocNumbers.length;
+				int[] mappedNumbers = new int[length];
+				int count = 0;
+				for (int j = 0; j < length; j++) {
+					int pos = positions[oldDocNumbers[j]];
+					if (pos > RE_INDEXED) // forget any reference to a document which was deleted or re_indexed
+						mappedNumbers[count++] = pos;
+				}
+				if (count < length) {
+					if (count == 0) continue nextWord; // skip words which no longer have any references
+					System.arraycopy(mappedNumbers, 0, mappedNumbers = new int[count], 0, count);
+				}
+
+				Object o = wordsToDocs.get(oldWord);
+				if (o == null) {
+					wordsToDocs.putUnsafely(oldWord, mappedNumbers);
+				} else {
+					IntList list = null;
+					if (o instanceof IntList) {
+						list = (IntList) o;
+					} else {
+						list = new IntList((int[]) o);
+						wordsToDocs.put(oldWord, list);
+					}
+					for (int j = 0; j < count; j++)
+						list.add(mappedNumbers[j]);
+				}
+			}
+		}
+		onDisk.categoryTables.put(categoryName, null); // flush cached table
+	}
+	writeCategoryTable(categoryName, wordsToDocs, stream);
+}
+DiskIndex mergeWith(MemoryIndex memoryIndex) throws IOException {
+ 	// assume write lock is held
+	// compute & write out new docNames
+	if (this.indexLocation == null) {
+		throw new IOException("Pre-built index file not writeable");  //$NON-NLS-1$
+	}
+	String[] docNames = readAllDocumentNames();
+	int previousLength = docNames.length;
+	int[] positions = new int[previousLength]; // keeps track of the position of each document in the new sorted docNames
+	SimpleLookupTable indexedDocuments = new SimpleLookupTable(3); // for each new/changed document in the memoryIndex
+	docNames = computeDocumentNames(docNames, positions, indexedDocuments, memoryIndex);
+	if (docNames.length == 0) {
+		if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved
+
+		// index is now empty since all the saved documents were removed
+		DiskIndex newDiskIndex = new DiskIndex(this.indexLocation);
+		newDiskIndex.initialize(false);
+		return newDiskIndex;
+	}
+	File oldIndexFile = this.indexLocation.getIndexFile();
+	DiskIndex newDiskIndex = new DiskIndex(new FileIndexLocation(new File(oldIndexFile.getPath() + ".tmp"))); //$NON-NLS-1$
+	File newIndexFile = newDiskIndex.indexLocation.getIndexFile();
+	try {
+		newDiskIndex.initializeFrom(this, newIndexFile);
+		FileOutputStream stream = new FileOutputStream(newIndexFile, false);
+		int offsetToHeader = -1;
+		try {
+			newDiskIndex.writeAllDocumentNames(docNames, stream);
+			docNames = null; // free up the space
+
+			// add each new/changed doc to empty category tables using its new position #
+			if (indexedDocuments.elementSize > 0) {
+				Object[] names = indexedDocuments.keyTable;
+				Object[] integerPositions = indexedDocuments.valueTable;
+				for (int i = 0, l = names.length; i < l; i++)
+					if (names[i] != null)
+						newDiskIndex.copyQueryResults(
+							(HashtableOfObject) memoryIndex.docsToReferences.get(names[i]), ((Integer) integerPositions[i]).intValue());
+			}
+			indexedDocuments = null; // free up the space
+
+			// merge each category table with the new ones & write them out
+			if (previousLength == 0)
+				newDiskIndex.writeCategories(stream);
+			else
+				newDiskIndex.mergeCategories(this, positions, stream);
+			offsetToHeader = newDiskIndex.streamEnd;
+			newDiskIndex.writeHeaderInfo(stream);
+			positions = null; // free up the space
+		} finally {
+			stream.close();
+			this.streamBuffer = null;
+		}
+		newDiskIndex.writeOffsetToHeader(offsetToHeader);
+
+		// rename file by deleting previous index file & renaming temp one
+		if (oldIndexFile.exists() && !oldIndexFile.delete()) {
+			if (DEBUG)
+				System.out.println("mergeWith - Failed to delete " + this.indexLocation); //$NON-NLS-1$
+			throw new IOException("Failed to delete index file " + this.indexLocation); //$NON-NLS-1$
+		}
+		if (!newIndexFile.renameTo(oldIndexFile)) {
+			if (DEBUG)
+				System.out.println("mergeWith - Failed to rename " + this.indexLocation); //$NON-NLS-1$
+			throw new IOException("Failed to rename index file " + this.indexLocation); //$NON-NLS-1$
+		}
+	} catch (IOException e) {
+		if (newIndexFile.exists() && !newIndexFile.delete())
+			if (DEBUG)
+				System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexLocation); //$NON-NLS-1$
+		throw e;
+	}
+
+	newDiskIndex.indexLocation = this.indexLocation;
+	return newDiskIndex;
+}
+private synchronized String[] readAllDocumentNames() throws IOException {
+	if (this.numberOfChunks <= 0)
+		return CharOperation.NO_STRINGS;
+
+	InputStream stream = this.indexLocation.getInputStream();
+	try {
+		int offset = this.chunkOffsets[0];
+		stream.skip(offset);
+		this.streamBuffer = new byte[BUFFER_READ_SIZE];
+		this.bufferIndex = 0;
+		this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+		int lastIndex = this.numberOfChunks - 1;
+		String[] docNames = new String[lastIndex * CHUNK_SIZE + this.sizeOfLastChunk];
+		for (int i = 0; i < this.numberOfChunks; i++)
+			readChunk(docNames, stream, i * CHUNK_SIZE, i < lastIndex ? CHUNK_SIZE : this.sizeOfLastChunk);
+		return docNames;
+	} finally {
+		stream.close();
+		this.streamBuffer = null;
+	}
+}
+private synchronized HashtableOfObject readCategoryTable(char[] categoryName, boolean readDocNumbers) throws IOException {
+	// result will be null if categoryName is unknown
+	int offset = this.categoryOffsets.get(categoryName);
+	if (offset == HashtableOfIntValues.NO_VALUE) {
+		return null;
+	}
+
+	if (this.categoryTables == null) {
+		this.categoryTables = new HashtableOfObject(3);
+	} else {
+		HashtableOfObject cachedTable = (HashtableOfObject) this.categoryTables.get(categoryName);
+		if (cachedTable != null) {
+			if (readDocNumbers) { // must cache remaining document number arrays
+				Object[] arrayOffsets = cachedTable.valueTable;
+				for (int i = 0, l = arrayOffsets.length; i < l; i++)
+					if (arrayOffsets[i] instanceof Integer)
+						arrayOffsets[i] = readDocumentNumbers(arrayOffsets[i]);
+			}
+			return cachedTable;
+		}
+	}
+
+	InputStream stream = this.indexLocation.getInputStream();
+	HashtableOfObject categoryTable = null;
+	char[][] matchingWords = null;
+	int count = 0;
+	int firstOffset = -1;
+	this.streamBuffer = new byte[BUFFER_READ_SIZE];
+	try {
+		stream.skip(offset);
+		this.bufferIndex = 0;
+		this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+		int size = readStreamInt(stream);
+		try {
+			if (size < 0) { // DEBUG
+				System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
+				System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
+				System.err.println("offset = "+offset); //$NON-NLS-1$
+				System.err.println("size = "+size); //$NON-NLS-1$
+				System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
+			}
+			categoryTable = new HashtableOfObject(size);
+		} catch (OutOfMemoryError oom) {
+			// DEBUG
+			oom.printStackTrace();
+			System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
+			System.err.println("file = "+this.indexLocation); //$NON-NLS-1$
+			System.err.println("offset = "+offset); //$NON-NLS-1$
+			System.err.println("size = "+size); //$NON-NLS-1$
+			System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
+			throw oom;
+		}
+		int largeArraySize = 256;
+		for (int i = 0; i < size; i++) {
+			char[] word = readStreamChars(stream);
+			int arrayOffset = readStreamInt(stream);
+			// if arrayOffset is:
+			//		<= 0 then the array size == 1 with the value -> -arrayOffset
+			//		> 1 & < 256 then the size of the array is > 1 & < 256, the document array follows immediately
+			//		256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table)
+			if (arrayOffset <= 0) {
+				categoryTable.putUnsafely(word, new int[] {-arrayOffset}); // store 1 element array by negating documentNumber
+			} else if (arrayOffset < largeArraySize) {
+				categoryTable.putUnsafely(word, readStreamDocumentArray(stream, arrayOffset)); // read in-lined array providing size
+			} else {
+				arrayOffset = readStreamInt(stream); // read actual offset
+				if (readDocNumbers) {
+					if (matchingWords == null)
+						matchingWords = new char[size][];
+					if (count == 0)
+						firstOffset = arrayOffset;
+					matchingWords[count++] = word;
+				}
+				categoryTable.putUnsafely(word, new Integer(arrayOffset)); // offset to array in the file
+			}
+		}
+		this.categoryTables.put(INTERNED_CATEGORY_NAMES.get(categoryName), categoryTable);
+		// cache the table as long as its not too big
+		// in practice, some tables can be greater than 500K when they contain more than 10K elements
+		this.cachedCategoryName = categoryTable.elementSize < 20000 ? categoryName : null;
+	} catch (IOException ioe) {
+		this.streamBuffer = null;
+		throw ioe;
+	} finally {
+		stream.close();
+	}
+
+	if (matchingWords != null && count > 0) {
+		stream = this.indexLocation.getInputStream();
+		try {
+			stream.skip(firstOffset);
+			this.bufferIndex = 0;
+			this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+			for (int i = 0; i < count; i++) { // each array follows the previous one
+				categoryTable.put(matchingWords[i], readStreamDocumentArray(stream, readStreamInt(stream)));
+			}
+		} catch (IOException ioe) {
+			this.streamBuffer = null;
+			throw ioe;
+		} finally {
+			stream.close();
+		}
+	}
+	this.streamBuffer = null;
+	return categoryTable;
+}
+private void readChunk(String[] docNames, InputStream stream, int index, int size) throws IOException {
+	String current = new String(readStreamChars(stream));
+	docNames[index++] = current;
+	for (int i = 1; i < size; i++) {
+		if (stream != null && this.bufferIndex + 2 >= this.bufferEnd)
+			readStreamBuffer(stream);
+		int start = this.streamBuffer[this.bufferIndex++] & 0xFF;
+		int end = this.streamBuffer[this.bufferIndex++] & 0xFF;
+		String next  = new String(readStreamChars(stream));
+		if (start > 0) {
+			if (end > 0) {
+				int length = current.length();
+				next = current.substring(0, start) + next + current.substring(length - end, length);
+			} else {
+				next = current.substring(0, start) + next;
+			}
+		} else if (end > 0) {
+			int length = current.length();
+			next = next + current.substring(length - end, length);
+		}
+		docNames[index++] = next;
+		current = next;
+	}
+}
+synchronized String readDocumentName(int docNumber) throws IOException {
+	if (this.cachedChunks == null)
+		this.cachedChunks = new String[this.numberOfChunks][];
+
+	int chunkNumber = docNumber / CHUNK_SIZE;
+	String[] chunk = this.cachedChunks[chunkNumber];
+	if (chunk == null) {
+		boolean isLastChunk = chunkNumber == this.numberOfChunks - 1;
+		int start = this.chunkOffsets[chunkNumber];
+		int numberOfBytes = (isLastChunk ? this.startOfCategoryTables : this.chunkOffsets[chunkNumber + 1]) - start;
+		if (numberOfBytes < 0)
+			throw new IllegalArgumentException();
+		this.streamBuffer = new byte[numberOfBytes];
+		this.bufferIndex = 0;
+		InputStream file = this.indexLocation.getInputStream();
+		try {
+			file.skip(start);
+			if (file.read(this.streamBuffer, 0, numberOfBytes) != numberOfBytes)
+				throw new IOException();
+		} catch (IOException ioe) {
+			this.streamBuffer = null;
+			throw ioe;
+		} finally {
+			file.close();
+		}
+		int numberOfNames = isLastChunk ? this.sizeOfLastChunk : CHUNK_SIZE;
+		chunk = new String[numberOfNames];
+		try {
+			readChunk(chunk, null, 0, numberOfNames);
+		} catch (IOException ioe) {
+			this.streamBuffer = null;
+			throw ioe;
+		}
+		this.cachedChunks[chunkNumber] = chunk;
+	}
+	this.streamBuffer = null;
+	return chunk[docNumber - (chunkNumber * CHUNK_SIZE)];
+}
+synchronized int[] readDocumentNumbers(Object arrayOffset) throws IOException {
+	// arrayOffset is either a cached array of docNumbers or an Integer offset in the file
+	if (arrayOffset instanceof int[])
+		return (int[]) arrayOffset;
+
+	InputStream stream = this.indexLocation.getInputStream();
+	try {
+		int offset = ((Integer) arrayOffset).intValue();
+		stream.skip(offset);
+		this.streamBuffer = new byte[BUFFER_READ_SIZE];
+		this.bufferIndex = 0;
+		this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length);
+		return readStreamDocumentArray(stream, readStreamInt(stream));
+	} finally {
+		stream.close();
+		this.streamBuffer = null;
+	}
+}
+private void readHeaderInfo(InputStream stream) throws IOException {
+
+	// must be same order as writeHeaderInfo()
+	this.numberOfChunks = readStreamInt(stream);
+	this.sizeOfLastChunk = this.streamBuffer[this.bufferIndex++] & 0xFF;
+	this.documentReferenceSize = this.streamBuffer[this.bufferIndex++] & 0xFF;
+	this.separator = (char) (this.streamBuffer[this.bufferIndex++] & 0xFF);
+	long length = this.indexLocation.length();
+	if (length != -1 && this.numberOfChunks > length) {
+		// not an accurate check, but good enough https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
+		if (DEBUG)
+			System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
+		throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
+	}
+	this.chunkOffsets = new int[this.numberOfChunks];
+	for (int i = 0; i < this.numberOfChunks; i++)
+		this.chunkOffsets[i] = readStreamInt(stream);
+
+	this.startOfCategoryTables = readStreamInt(stream);
+
+	int size = readStreamInt(stream);
+	this.categoryOffsets = new HashtableOfIntValues(size);
+	this.categoryEnds = new HashtableOfIntValues(size);
+	if (length != -1 && size > length) {
+		//  not an accurate check, but good enough  https://bugs.eclipse.org/bugs/show_bug.cgi?id=350612
+		if (DEBUG)
+			System.out.println("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
+		throw new IOException("Index file is corrupted " + this.indexLocation); //$NON-NLS-1$
+	}
+	char[] previousCategory = null;
+	int offset = -1;
+	for (int i = 0; i < size; i++) {
+		char[] categoryName = INTERNED_CATEGORY_NAMES.get(readStreamChars(stream));
+		offset = readStreamInt(stream);
+		this.categoryOffsets.put(categoryName, offset); // cache offset to category table
+		if (previousCategory != null) {
+			this.categoryEnds.put(previousCategory, offset); // cache end of the category table
+		}
+		previousCategory = categoryName;
+	}
+	if (previousCategory != null) {
+		this.categoryEnds.put(previousCategory, this.headerInfoOffset); // cache end of the category table
+	}
+	this.categoryTables = new HashtableOfObject(3);
+}
+synchronized void startQuery() {
+	this.cacheUserCount++;
+}
+synchronized void stopQuery() {
+	if (--this.cacheUserCount < 0) {
+		// clear cached items
+		this.cacheUserCount = -1;
+		this.cachedChunks = null;
+		if (this.categoryTables != null) {
+			if (this.cachedCategoryName == null) {
+				this.categoryTables = null;
+			} else if (this.categoryTables.elementSize > 1) {
+				HashtableOfObject newTables = new HashtableOfObject(3);
+				newTables.put(this.cachedCategoryName, this.categoryTables.get(this.cachedCategoryName));
+				this.categoryTables = newTables;
+			}
+		}
+	}
+}
+private void readStreamBuffer(InputStream stream) throws IOException {
+	// if we're about to read a known amount at the end of the existing buffer, but it does not completely fit
+	// so we need to shift the remaining bytes to be read, and fill the buffer from the stream
+	if (this.bufferEnd < this.streamBuffer.length) {
+		if (stream.available() == 0)
+			return; // we're at the end of the stream - nothing left to read
+	}
+
+	int bytesInBuffer = this.bufferEnd - this.bufferIndex;
+	if (bytesInBuffer > 0)
+		System.arraycopy(this.streamBuffer, this.bufferIndex, this.streamBuffer, 0, bytesInBuffer);
+	this.bufferEnd = bytesInBuffer + stream.read(this.streamBuffer, bytesInBuffer, this.bufferIndex);
+	this.bufferIndex = 0;
+}
+/**
+ * Reads in a string from the specified data input stream. The
+ * string has been encoded using a modified UTF-8 format.
+ * <p>
+ * The first two bytes are read as an unsigned short.
+ * This value gives the number of following bytes that are in the encoded string,
+ * not the length of the resulting string. The following bytes are then
+ * interpreted as bytes encoding characters in the UTF-8 format
+ * and are converted into characters.
+ * <p>
+ * This method blocks until all the bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @param      stream   a data input stream.
+ * @return     UTF decoded string as a char array
+ * @exception  EOFException if this end of data input is reached while reading it.
+ * @exception  IOException if an I/O error occurs while reading data input.
+ * @exception  UTFDataFormatException  if the bytes do not represent a
+ *               valid UTF-8 encoding of a Unicode string.
+ */
+private char[] readStreamChars(InputStream stream) throws IOException {
+	// read chars array length
+	if (stream != null && this.bufferIndex + 2 >= this.bufferEnd)
+		readStreamBuffer(stream);
+	int length = (this.streamBuffer[this.bufferIndex++] & 0xFF) << 8;
+	length += this.streamBuffer[this.bufferIndex++] & 0xFF;
+
+	// fill the chars from bytes buffer
+	char[] word = new char[length];
+	int i = 0;
+	while (i < length) {
+		// how many characters can be decoded without refilling the buffer?
+		int charsInBuffer = i + ((this.bufferEnd - this.bufferIndex) / 3);
+		// all the characters must already be in the buffer if we're at the end of the stream
+		if (charsInBuffer > length || stream == null  || (this.bufferEnd != this.streamBuffer.length && stream.available() == 0))
+			charsInBuffer = length;
+		while (i < charsInBuffer) {
+			byte b = this.streamBuffer[this.bufferIndex++];
+			switch (b & 0xF0) {
+				case 0x00 :
+				case 0x10 :
+				case 0x20 :
+				case 0x30 :
+				case 0x40 :
+				case 0x50 :
+				case 0x60 :
+				case 0x70 :
+					word[i++]= (char) b;
+					break;
+				case 0xC0 :
+				case 0xD0 :
+					char next = (char) this.streamBuffer[this.bufferIndex++];
+					if ((next & 0xC0) != 0x80) {
+						throw new UTFDataFormatException();
+					}
+					char ch = (char) ((b & 0x1F) << 6);
+					ch |= next & 0x3F;
+					word[i++] = ch;
+					break;
+				case 0xE0 :
+					char first = (char) this.streamBuffer[this.bufferIndex++];
+					char second = (char) this.streamBuffer[this.bufferIndex++];
+					if ((first & second & 0xC0) != 0x80) {
+						throw new UTFDataFormatException();
+					}
+					ch = (char) ((b & 0x0F) << 12);
+					ch |= ((first& 0x3F) << 6);
+					ch |= second & 0x3F;
+					word[i++] = ch;
+					break;
+				default:
+					throw new UTFDataFormatException();
+			}
+		}
+		if (i < length && stream != null)
+			readStreamBuffer(stream);
+	}
+	return word;
+}
+private int[] readStreamDocumentArray(InputStream stream, int arraySize) throws IOException {
+	int[] indexes = new int[arraySize];
+	if (arraySize == 0) return indexes;
+
+	int i = 0;
+	switch (this.documentReferenceSize) {
+		case 1 :
+			while (i < arraySize) {
+				// how many bytes without refilling the buffer?
+				int bytesInBuffer = i + this.bufferEnd - this.bufferIndex;
+				if (bytesInBuffer > arraySize)
+					bytesInBuffer = arraySize;
+				while (i < bytesInBuffer) {
+					indexes[i++] = this.streamBuffer[this.bufferIndex++] & 0xFF;
+				}
+				if (i < arraySize && stream != null)
+					readStreamBuffer(stream);
+			}
+			break;
+		case 2 :
+			while (i < arraySize) {
+				// how many shorts without refilling the buffer?
+				int shortsInBuffer = i + ((this.bufferEnd - this.bufferIndex) / 2);
+				if (shortsInBuffer > arraySize)
+					shortsInBuffer = arraySize;
+				while (i < shortsInBuffer) {
+					int val = (this.streamBuffer[this.bufferIndex++] & 0xFF) << 8;
+					indexes[i++] = val + (this.streamBuffer[this.bufferIndex++] & 0xFF);
+				}
+				if (i < arraySize && stream != null)
+					readStreamBuffer(stream);
+			}
+			break;
+		default :
+			while (i < arraySize) {
+				indexes[i++] = readStreamInt(stream);
+			}
+			break;
+	}
+	return indexes;
+}
+private int readStreamInt(InputStream stream) throws IOException {
+	if (this.bufferIndex + 4 >= this.bufferEnd) {
+		readStreamBuffer(stream);
+	}
+	int val = (this.streamBuffer[this.bufferIndex++] & 0xFF) << 24;
+	val += (this.streamBuffer[this.bufferIndex++] & 0xFF) << 16;
+	val += (this.streamBuffer[this.bufferIndex++] & 0xFF) << 8;
+	return val + (this.streamBuffer[this.bufferIndex++] & 0xFF);
+}
+private void writeAllDocumentNames(String[] sortedDocNames, FileOutputStream stream) throws IOException {
+	if (sortedDocNames.length == 0)
+		throw new IllegalArgumentException();
+
+	// assume the file was just created by initializeFrom()
+	this.streamBuffer = new byte[BUFFER_WRITE_SIZE];
+	this.bufferIndex = 0;
+	this.streamEnd = 0;
+
+	// in order, write: SIGNATURE & headerInfoOffset place holder, then each compressed chunk of document names
+	writeStreamChars(stream, SIGNATURE_CHARS);
+	this.headerInfoOffset = this.streamEnd;
+	writeStreamInt(stream, -1); // will overwrite with correct value later
+
+	int size = sortedDocNames.length;
+	this.numberOfChunks = (size / CHUNK_SIZE) + 1;
+	this.sizeOfLastChunk = size % CHUNK_SIZE;
+	if (this.sizeOfLastChunk == 0) {
+		this.numberOfChunks--;
+		this.sizeOfLastChunk = CHUNK_SIZE;
+	}
+	this.documentReferenceSize = size <= 0x7F ? 1 : (size <= 0x7FFF ? 2 : 4); // number of bytes used to encode a reference
+
+	this.chunkOffsets = new int[this.numberOfChunks];
+	int lastIndex = this.numberOfChunks - 1;
+	for (int i = 0; i < this.numberOfChunks; i++) {
+		this.chunkOffsets[i] = this.streamEnd;
+
+		int chunkSize = i == lastIndex ? this.sizeOfLastChunk : CHUNK_SIZE;
+		int chunkIndex = i * CHUNK_SIZE;
+		String current = sortedDocNames[chunkIndex];
+		writeStreamChars(stream, current.toCharArray());
+		for (int j = 1; j < chunkSize; j++) {
+			String next = sortedDocNames[chunkIndex + j];
+			int len1 = current.length();
+			int len2 = next.length();
+			int max = len1 < len2 ? len1 : len2;
+			int start = 0; // number of identical characters at the beginning (also the index of first character that is different)
+			while (current.charAt(start) == next.charAt(start)) {
+				start++;
+				if (max == start) break; // current is 'abba', next is 'abbab'
+			}
+			if (start > 255) start = 255;
+
+			int end = 0; // number of identical characters at the end
+			while (current.charAt(--len1) == next.charAt(--len2)) {
+				end++;
+				if (len2 == start) break; // current is 'abbba', next is 'abba'
+				if (len1 == 0) break; // current is 'xabc', next is 'xyabc'
+			}
+			if (end > 255) end = 255;
+			if ((this.bufferIndex + 2) >= BUFFER_WRITE_SIZE)  {
+				stream.write(this.streamBuffer, 0, this.bufferIndex);
+				this.bufferIndex = 0;
+			}
+			this.streamBuffer[this.bufferIndex++] = (byte) start;
+			this.streamBuffer[this.bufferIndex++] = (byte) end;
+			this.streamEnd += 2;
+
+			int last = next.length() - end;
+			writeStreamChars(stream, (start < last ? CharOperation.subarray(next.toCharArray(), start, last) : CharOperation.NO_CHAR));
+			current = next;
+		}
+	}
+	this.startOfCategoryTables = this.streamEnd + 1;
+}
+private void writeCategories(FileOutputStream stream) throws IOException {
+	char[][] categoryNames = this.categoryTables.keyTable;
+	Object[] tables = this.categoryTables.valueTable;
+	for (int i = 0, l = categoryNames.length; i < l; i++)
+		if (categoryNames[i] != null)
+			writeCategoryTable(categoryNames[i], (HashtableOfObject) tables[i], stream);
+	this.categoryTables = null;
+}
+private void writeCategoryTable(char[] categoryName, HashtableOfObject wordsToDocs, FileOutputStream stream) throws IOException {
+	// the format of a category table is as follows:
+	// any document number arrays with >= 256 elements are written before the table (the offset to each array is remembered)
+	// then the number of word->int[] pairs in the table is written
+	// for each word -> int[] pair, the word is written followed by:
+	//		an int <= 0 if the array size == 1
+	//		an int > 1 & < 256 for the size of the array if its > 1 & < 256, the document array follows immediately
+	//		256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table)
+
+	int largeArraySize = 256;
+	Object[] values = wordsToDocs.valueTable;
+	for (int i = 0, l = values.length; i < l; i++) {
+		Object o = values[i];
+		if (o != null) {
+			if (o instanceof IntList)
+				o = values[i] = ((IntList) values[i]).asArray();
+			int[] documentNumbers = (int[]) o;
+			if (documentNumbers.length >= largeArraySize) {
+				values[i] = new Integer(this.streamEnd);
+				writeDocumentNumbers(documentNumbers, stream);
+			}
+		}
+	}
+
+	this.categoryOffsets.put(categoryName, this.streamEnd); // remember the offset to the start of the table
+	this.categoryTables.put(categoryName, null); // flush cached table
+	writeStreamInt(stream, wordsToDocs.elementSize);
+	char[][] words = wordsToDocs.keyTable;
+	for (int i = 0, l = words.length; i < l; i++) {
+		Object o = values[i];
+		if (o != null) {
+			writeStreamChars(stream, words[i]);
+			if (o instanceof int[]) {
+				int[] documentNumbers = (int[]) o;
+				if (documentNumbers.length == 1)
+					writeStreamInt(stream, -documentNumbers[0]); // store an array of 1 element by negating the documentNumber (can be zero)
+				else
+					writeDocumentNumbers(documentNumbers, stream);
+			} else {
+				writeStreamInt(stream, largeArraySize); // mark to identify that an offset follows
+				writeStreamInt(stream, ((Integer) o).intValue()); // offset in the file of the array of document numbers
+			}
+		}
+	}
+}
+private void writeDocumentNumbers(int[] documentNumbers, FileOutputStream stream) throws IOException {
+	// must store length as a positive int to detect in-lined array of 1 element
+	int length = documentNumbers.length;
+	writeStreamInt(stream, length);
+	Util.sort(documentNumbers);
+	int start = 0;
+	switch (this.documentReferenceSize) {
+		case 1 :
+			while ((this.bufferIndex + length - start) >= BUFFER_WRITE_SIZE) {
+				// when documentNumbers is large, write BUFFER_WRITE_SIZE parts & fall thru to write the last part
+				int bytesLeft = BUFFER_WRITE_SIZE - this.bufferIndex;
+				for (int i=0; i < bytesLeft; i++) {
+					this.streamBuffer[this.bufferIndex++] = (byte) documentNumbers[start++];
+				}
+				stream.write(this.streamBuffer, 0, this.bufferIndex);
+				this.bufferIndex = 0;
+			}
+			while (start < length) {
+				this.streamBuffer[this.bufferIndex++] = (byte) documentNumbers[start++];
+			}
+			this.streamEnd += length;
+			break;
+		case 2 :
+			while ((this.bufferIndex + ((length - start) * 2)) >= BUFFER_WRITE_SIZE) {
+				// when documentNumbers is large, write BUFFER_WRITE_SIZE parts & fall thru to write the last part
+				int shortsLeft = (BUFFER_WRITE_SIZE - this.bufferIndex) / 2;
+				for (int i=0; i < shortsLeft; i++) {
+					this.streamBuffer[this.bufferIndex++] = (byte) (documentNumbers[start] >> 8);
+					this.streamBuffer[this.bufferIndex++] = (byte) documentNumbers[start++];
+				}
+				stream.write(this.streamBuffer, 0, this.bufferIndex);
+				this.bufferIndex = 0;
+			}
+			while (start < length) {
+				this.streamBuffer[this.bufferIndex++] = (byte) (documentNumbers[start] >> 8);
+				this.streamBuffer[this.bufferIndex++] = (byte) documentNumbers[start++];
+			}
+			this.streamEnd += length * 2;
+			break;
+		default :
+			while (start < length) {
+				writeStreamInt(stream, documentNumbers[start++]);
+			}
+			break;
+	}
+}
+private void writeHeaderInfo(FileOutputStream stream) throws IOException {
+	writeStreamInt(stream, this.numberOfChunks);
+	if ((this.bufferIndex + 3) >= BUFFER_WRITE_SIZE)  {
+		stream.write(this.streamBuffer, 0, this.bufferIndex);
+		this.bufferIndex = 0;
+	}
+	this.streamBuffer[this.bufferIndex++] = (byte) this.sizeOfLastChunk;
+	this.streamBuffer[this.bufferIndex++] = (byte) this.documentReferenceSize;
+	this.streamBuffer[this.bufferIndex++] = (byte) this.separator;
+	this.streamEnd += 3;
+
+	// apend the file with chunk offsets
+	for (int i = 0; i < this.numberOfChunks; i++) {
+		writeStreamInt(stream, this.chunkOffsets[i]);
+	}
+
+	writeStreamInt(stream, this.startOfCategoryTables);
+
+	// append the file with the category offsets... # of name -> offset pairs, followed by each name & an offset to its word->doc# table
+	writeStreamInt(stream, this.categoryOffsets.elementSize);
+	char[][] categoryNames = this.categoryOffsets.keyTable;
+	int[] offsets = this.categoryOffsets.valueTable;
+	for (int i = 0, l = categoryNames.length; i < l; i++) {
+		if (categoryNames[i] != null) {
+			writeStreamChars(stream, categoryNames[i]);
+			writeStreamInt(stream, offsets[i]);
+		}
+	}
+	// ensure buffer is written to the stream
+	if (this.bufferIndex > 0) {
+		stream.write(this.streamBuffer, 0, this.bufferIndex);
+		this.bufferIndex = 0;
+	}
+}
+private void writeOffsetToHeader(int offsetToHeader) throws IOException {
+	if (offsetToHeader > 0) {
+		RandomAccessFile file = new RandomAccessFile(this.indexLocation.getIndexFile(), "rw"); //$NON-NLS-1$
+		try {
+			file.seek(this.headerInfoOffset); // offset to position in header
+			file.writeInt(offsetToHeader);
+			this.headerInfoOffset = offsetToHeader; // update to reflect the correct offset
+		} finally {
+			file.close();
+		}
+	}
+}
+/**
+ * Writes a string to the given output stream using UTF-8
+ * encoding in a machine-independent manner.
+ * <p>
+ * First, two bytes of the array are giving the number of bytes to
+ * follow. This value is the number of bytes actually written out,
+ * not the length of the string. Following the length, each character
+ * of the string is put in the bytes array, in sequence, using the UTF-8
+ * encoding for the character.
+ * </p>
+ * <p>
+ * Then the entire byte array is written to the output stream
+ * using {@link OutputStream#write(byte[], int, int)} method.
+ * </p>
+ *
+ * @param array char array to be written.
+ * @exception  IOException  if an I/O error occurs while writting
+ * 	the bytes array to the stream.
+ */
+private void writeStreamChars(FileOutputStream stream, char[] array) throws IOException {
+	if ((this.bufferIndex + 2) >= BUFFER_WRITE_SIZE)  {
+		stream.write(this.streamBuffer, 0, this.bufferIndex);
+		this.bufferIndex = 0;
+	}
+	int length = array.length;
+	this.streamBuffer[this.bufferIndex++] = (byte) ((length >>> 8) & 0xFF); // store chars array length instead of bytes
+	this.streamBuffer[this.bufferIndex++] = (byte) (length & 0xFF); // this will allow to read it faster
+	this.streamEnd += 2;
+
+	// we're assuming that very few char[] are so large that we need to flush the buffer more than once, if at all
+	int totalBytesNeeded = length * 3;
+	if (totalBytesNeeded <= BUFFER_WRITE_SIZE) {
+		if (this.bufferIndex + totalBytesNeeded > BUFFER_WRITE_SIZE) {
+			// flush the buffer now to make sure there is room for the array
+			stream.write(this.streamBuffer, 0, this.bufferIndex);
+			this.bufferIndex = 0;
+		}
+		writeStreamChars(stream, array, 0, length);
+	} else {
+		int charsPerWrite = BUFFER_WRITE_SIZE / 3;
+		int start = 0;
+		while (start < length) {
+			stream.write(this.streamBuffer, 0, this.bufferIndex);
+			this.bufferIndex = 0;
+			int charsLeftToWrite = length - start;
+			int end = start + (charsPerWrite < charsLeftToWrite ? charsPerWrite : charsLeftToWrite);
+			writeStreamChars(stream, array, start, end);
+			start = end;
+		}
+	}
+}
+private void writeStreamChars(FileOutputStream stream, char[] array, int start, int end) throws IOException {
+	// start can NOT be == end
+	// must have checked that there is enough room for end - start * 3 bytes in the buffer
+
+	int oldIndex = this.bufferIndex;
+	while (start < end) {
+		int ch = array[start++];
+		if ((ch & 0x007F) == ch) {
+			this.streamBuffer[this.bufferIndex++] = (byte) ch;
+		} else if ((ch & 0x07FF) == ch) {
+			// first two bits are stored in first byte
+			byte b = (byte) (ch >> 6);
+			b &= 0x1F;
+			b |= 0xC0;
+			this.streamBuffer[this.bufferIndex++] = b;
+			// last six bits are stored in second byte
+			b = (byte) (ch & 0x3F);
+			b |= 0x80;
+			this.streamBuffer[this.bufferIndex++] = b;
+		} else {
+			// first four bits are stored in first byte
+			byte b = (byte) (ch >> 12);
+			b &= 0x0F;
+			b |= 0xE0;
+			this.streamBuffer[this.bufferIndex++] = b;
+			// six following bits are stored in second byte
+			b = (byte) (ch >> 6);
+			b &= 0x3F;
+			b |= 0x80;
+			this.streamBuffer[this.bufferIndex++] = b;
+			// last six bits are stored in third byte
+			b = (byte) (ch & 0x3F);
+			b |= 0x80;
+			this.streamBuffer[this.bufferIndex++] = b;
+		}
+	}
+	this.streamEnd += this.bufferIndex - oldIndex;
+}
+private void writeStreamInt(FileOutputStream stream, int val) throws IOException {
+	if ((this.bufferIndex + 4) >= BUFFER_WRITE_SIZE)  {
+		stream.write(this.streamBuffer, 0, this.bufferIndex);
+		this.bufferIndex = 0;
+	}
+	this.streamBuffer[this.bufferIndex++] = (byte) (val >> 24);
+	this.streamBuffer[this.bufferIndex++] = (byte) (val >> 16);
+	this.streamBuffer[this.bufferIndex++] = (byte) (val >> 8);
+	this.streamBuffer[this.bufferIndex++] = (byte) val;
+	this.streamEnd += 4;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java
new file mode 100644
index 0000000..ad65513
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class EntryResult {
+
+private char[] word;
+private Object[] documentTables;
+private SimpleSet documentNames;
+
+public EntryResult(char[] word, Object table) {
+	this.word = word;
+	if (table != null)
+		this.documentTables = new Object[] {table};
+}
+public void addDocumentName(String documentName) {
+	if (this.documentNames == null)
+		this.documentNames = new SimpleSet(3);
+	this.documentNames.add(documentName);
+}
+public void addDocumentTable(Object table) {
+	if (this.documentTables != null) {
+		int length = this.documentTables.length;
+		System.arraycopy(this.documentTables, 0, this.documentTables = new Object[length + 1], 0, length);
+		this.documentTables[length] = table;
+	} else {
+		this.documentTables = new Object[] {table};
+	}
+}
+public char[] getWord() {
+	return this.word;
+}
+public String[] getDocumentNames(Index index) throws java.io.IOException {
+	if (this.documentTables != null) {
+		int length = this.documentTables.length;
+		if (length == 1 && this.documentNames == null) { // have a single table
+			Object offset = this.documentTables[0];
+			int[] numbers = index.diskIndex.readDocumentNumbers(offset);
+			String[] names = new String[numbers.length];
+			for (int i = 0, l = numbers.length; i < l; i++)
+				names[i] = index.diskIndex.readDocumentName(numbers[i]);
+			return names;
+		}
+
+		for (int i = 0; i < length; i++) {
+			Object offset = this.documentTables[i];
+			int[] numbers = index.diskIndex.readDocumentNumbers(offset);
+			for (int j = 0, k = numbers.length; j < k; j++)
+				addDocumentName(index.diskIndex.readDocumentName(numbers[j]));
+		}
+	}
+
+	if (this.documentNames == null)
+		return CharOperation.NO_STRINGS;
+
+	String[] names = new String[this.documentNames.elementSize];
+	int count = 0;
+	Object[] values = this.documentNames.values;
+	for (int i = 0, l = values.length; i < l; i++)
+		if (values[i] != null)
+			names[count++] = (String) values[i];
+	return names;
+}
+public boolean isEmpty() {
+	return this.documentTables == null && this.documentNames == null;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java
new file mode 100644
index 0000000..f0648dd
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/FileIndexLocation.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class FileIndexLocation extends IndexLocation {
+	File indexFile;
+
+	public FileIndexLocation(File file) {
+		super(file);
+		this.indexFile = file;
+	}
+
+	public FileIndexLocation(URL url, File file) {
+		super(url);
+		this.indexFile = file;
+	}
+
+	public FileIndexLocation(File file, boolean participantIndex) {
+		this(file);
+		this.participantIndex = true;
+	}
+
+	public boolean createNewFile() throws IOException {
+		File directory = this.indexFile.getParentFile();
+		if (directory != null && !directory.exists()) {
+			directory.mkdirs();
+		}
+		// always call File#createNewFile() so that the IOException is thrown if there is a failure
+		return this.indexFile.createNewFile();
+	}
+
+	public boolean delete() {
+		return this.indexFile.delete();
+	}
+
+	public boolean equals(Object other) {
+		if (!(other instanceof FileIndexLocation)) return false;
+		return this.indexFile.equals(((FileIndexLocation) other).indexFile);
+	}
+
+	public boolean exists() {
+		return this.indexFile.exists();
+	}
+
+	public String fileName() {
+		return this.indexFile.getName();
+	}
+	
+	public File getIndexFile() {
+		return this.indexFile;
+	}
+
+	InputStream getInputStream() throws IOException {
+		return new FileInputStream(this.indexFile);
+	}
+
+	public String getCanonicalFilePath() {
+		try {
+			return this.indexFile.getCanonicalPath();
+		} catch (IOException e) {
+			// ignore
+		}
+		return null;
+	}
+
+	public int hashCode() {
+		return this.indexFile.hashCode();
+	}
+
+	public long lastModified() {
+		return this.indexFile.lastModified();
+	}
+
+	public long length() {
+		return this.indexFile.length();
+	}
+
+	public boolean startsWith(IPath path) {
+		try {
+			return path.isPrefixOf(new Path(this.indexFile.getCanonicalPath()));
+		} catch (IOException e) {
+			return false;
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
new file mode 100644
index 0000000..cac1956
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import java.io.*;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
+
+/**
+ * An <code>Index</code> maps document names to their referenced words in various categories.
+ * <p>
+ * Queries can search a single category or several at the same time.
+ * </p>
+ * Indexes are not synchronized structures and should only be queried/updated one at a time.
+ */
+public class Index {
+
+public String containerPath;
+public ReadWriteMonitor monitor;
+
+// Separator to use after the container path
+static final char DEFAULT_SEPARATOR = '/';
+public char separator = DEFAULT_SEPARATOR;
+static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0);
+
+protected DiskIndex diskIndex;
+protected MemoryIndex memoryIndex;
+
+/**
+ * Mask used on match rule for indexing.
+ */
+static final int MATCH_RULE_INDEX_MASK =
+	SearchPattern.R_EXACT_MATCH |
+	SearchPattern.R_PREFIX_MATCH |
+	SearchPattern.R_PATTERN_MATCH |
+	SearchPattern.R_REGEXP_MATCH |
+	SearchPattern.R_CASE_SENSITIVE |
+	SearchPattern.R_CAMELCASE_MATCH |
+	SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH;
+
+public static boolean isMatch(char[] pattern, char[] word, int matchRule) {
+	if (pattern == null) return true;
+	int patternLength = pattern.length;
+	int wordLength = word.length;
+	if (patternLength == 0) return matchRule != SearchPattern.R_EXACT_MATCH;
+	if (wordLength == 0) return (matchRule & SearchPattern.R_PATTERN_MATCH) != 0 && patternLength == 1 && pattern[0] == '*';
+
+	// need to mask some bits of pattern rule (bug 79790)
+	switch(matchRule & MATCH_RULE_INDEX_MASK) {
+		case SearchPattern.R_EXACT_MATCH :
+			return patternLength == wordLength && CharOperation.equals(pattern, word, false);
+		case SearchPattern.R_PREFIX_MATCH :
+			return patternLength <= wordLength && CharOperation.prefixEquals(pattern, word, false);
+		case SearchPattern.R_PATTERN_MATCH :
+			return CharOperation.match(pattern, word, false);
+		case SearchPattern.R_CAMELCASE_MATCH:
+		// same part count is not activated because index key may have uppercase letters after the type name
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			if (CharOperation.camelCaseMatch(pattern, word, false)) {
+				return true;
+			}
+			return patternLength <= wordLength && CharOperation.prefixEquals(pattern, word, false);
+		case SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE :
+			return pattern[0] == word[0] && patternLength == wordLength && CharOperation.equals(pattern, word);
+		case SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE :
+			return pattern[0] == word[0] && patternLength <= wordLength && CharOperation.prefixEquals(pattern, word);
+		case SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE :
+			return CharOperation.match(pattern, word, true);
+		case SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CASE_SENSITIVE :
+		// same part count is not activated because index key may have uppercase letters after the type name
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_CASE_SENSITIVE :
+			return (pattern[0] == word[0] && CharOperation.camelCaseMatch(pattern, word, false));
+	}
+	return false;
+}
+
+
+public Index(IndexLocation location, String containerPath, boolean reuseExistingFile) throws IOException {
+	this.containerPath = containerPath;
+	this.monitor = new ReadWriteMonitor();
+
+	this.memoryIndex = new MemoryIndex();
+	this.diskIndex = new DiskIndex(location);
+	this.diskIndex.initialize(reuseExistingFile);
+	if (reuseExistingFile) this.separator = this.diskIndex.separator;
+}
+public void addIndexEntry(char[] category, char[] key, String containerRelativePath) {
+	this.memoryIndex.addIndexEntry(category, key, containerRelativePath);
+}
+public String containerRelativePath(String documentPath) {
+	int index = documentPath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
+	if (index == -1) {
+		index = this.containerPath.length();
+		if (documentPath.length() <= index)
+			throw new IllegalArgumentException("Document path " + documentPath + " must be relative to " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+	return documentPath.substring(index + 1);
+}
+public File getIndexFile() {
+	return this.diskIndex == null ? null : this.diskIndex.indexLocation.getIndexFile();
+}
+public IndexLocation getIndexLocation() {
+	return this.diskIndex == null ? null : this.diskIndex.indexLocation;
+}
+public long getIndexLastModified() {
+	return this.diskIndex == null? -1 : this.diskIndex.indexLocation.lastModified();
+}
+public boolean hasChanged() {
+	return this.memoryIndex.hasChanged();
+}
+/**
+ * Returns the entries containing the given key in a group of categories, or null if no matches are found.
+ * The matchRule dictates whether its an exact, prefix or pattern match, as well as case sensitive or insensitive.
+ * If the key is null then all entries in specified categories are returned.
+ */
+public EntryResult[] query(char[][] categories, char[] key, int matchRule) throws IOException {
+	if (this.memoryIndex.shouldMerge() && this.monitor.exitReadEnterWrite()) {
+		try {
+			save();
+		} finally {
+			this.monitor.exitWriteEnterRead();
+		}
+	}
+
+	HashtableOfObject results;
+	int rule = matchRule & MATCH_RULE_INDEX_MASK;
+	if (this.memoryIndex.hasChanged()) {
+		results = this.diskIndex.addQueryResults(categories, key, rule, this.memoryIndex);
+		results = this.memoryIndex.addQueryResults(categories, key, rule, results);
+	} else {
+		results = this.diskIndex.addQueryResults(categories, key, rule, null);
+	}
+	if (results == null) return null;
+
+	EntryResult[] entryResults = new EntryResult[results.elementSize];
+	int count = 0;
+	Object[] values = results.valueTable;
+	for (int i = 0, l = values.length; i < l; i++) {
+		EntryResult result = (EntryResult) values[i];
+		if (result != null)
+			entryResults[count++] = result;
+	}
+	return entryResults;
+}
+/**
+ * Returns the document names that contain the given substring, if null then returns all of them.
+ */
+public String[] queryDocumentNames(String substring) throws IOException {
+	SimpleSet results;
+	if (this.memoryIndex.hasChanged()) {
+		results = this.diskIndex.addDocumentNames(substring, this.memoryIndex);
+		this.memoryIndex.addDocumentNames(substring, results);
+	} else {
+		results = this.diskIndex.addDocumentNames(substring, null);
+	}
+	if (results.elementSize == 0) return null;
+
+	String[] documentNames = new String[results.elementSize];
+	int count = 0;
+	Object[] paths = results.values;
+	for (int i = 0, l = paths.length; i < l; i++)
+		if (paths[i] != null)
+			documentNames[count++] = (String) paths[i];
+	return documentNames;
+}
+public void remove(String containerRelativePath) {
+	this.memoryIndex.remove(containerRelativePath);
+}
+/**
+ * Reset memory and disk indexes.
+ * 
+ * @throws IOException
+ */
+public void reset() throws IOException {
+	this.memoryIndex = new MemoryIndex();
+	this.diskIndex = new DiskIndex(this.diskIndex.indexLocation);
+	this.diskIndex.initialize(false/*do not reuse the index file*/);
+}
+public void save() throws IOException {
+	// must own the write lock of the monitor
+	if (!hasChanged()) return;
+
+	int numberOfChanges = this.memoryIndex.docsToReferences.elementSize;
+	this.diskIndex.separator = this.separator;
+	this.diskIndex = this.diskIndex.mergeWith(this.memoryIndex);
+	this.memoryIndex = new MemoryIndex();
+	if (numberOfChanges > 1000)
+		System.gc(); // reclaim space if the MemoryIndex was very BIG
+}
+public void startQuery() {
+	if (this.diskIndex != null)
+		this.diskIndex.startQuery();
+}
+public void stopQuery() {
+	if (this.diskIndex != null)
+		this.diskIndex.stopQuery();
+}
+public String toString() {
+	return "Index for " + this.containerPath; //$NON-NLS-1$
+}
+public boolean isIndexForJar()
+{
+	return this.separator == JAR_SEPARATOR;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java
new file mode 100644
index 0000000..f5103b0
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/IndexLocation.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * The location of the index files are represented as {@link IndexLocation}
+ * 
+ * This is an abstract class to allow different implementation for a jar entry and a file
+ * on the disk. Some of these functions could mean different for a jar entry or a file
+ * 
+ */
+public abstract class IndexLocation {
+	
+	public static IndexLocation createIndexLocation(URL url) {
+		URL localUrl;
+		try {
+			localUrl = FileLocator.resolve(url);
+		} catch (IOException e) {
+			return null;
+		}
+		if (localUrl.getProtocol().equals("file")) { //$NON-NLS-1$
+			File localFile = null;
+			try {
+				URI localFileURI = new URI(localUrl.toExternalForm());
+				localFile = new File(localFileURI);
+			}
+			catch(Exception ex) {
+				localFile = new File(localUrl.getPath());
+			}
+			return new FileIndexLocation(url, localFile);
+		}
+		return new JarIndexLocation(url, localUrl);
+	}
+	
+	private final URL url; // url of the given index location
+
+	/**
+	 * Set to true if this index location is of an index file specified
+	 * by a participant through 
+	 * {@link org.eclipse.jdt.core.search.SearchParticipant#scheduleDocumentIndexing}
+	 */
+	protected boolean participantIndex;
+	
+	protected IndexLocation(File file) {
+		URL tempUrl = null;
+		try {
+			tempUrl = file.toURI().toURL();
+		} catch (MalformedURLException e) {
+			// should not happen
+		}
+		this.url = tempUrl;
+	}
+	
+	public IndexLocation(URL url) {
+		this.url = url;
+	}
+
+	/**
+	 * Closes any open streams.
+	 */
+	public void close() {
+		// default nothing to do
+	}
+
+	/**
+	 * Creates a new file for the given index location
+	 * @return true if the file is created
+	 * @throws IOException
+	 */
+	public abstract boolean createNewFile() throws IOException;
+
+	public abstract boolean delete();
+
+	public abstract boolean exists();
+	
+	public abstract String fileName();
+
+	/**
+	 * @return the canonical file path if the location is a file or null otherwise
+	 */
+	public abstract String getCanonicalFilePath();
+
+	public abstract File getIndexFile();
+
+	abstract InputStream getInputStream() throws IOException;
+
+	public URL getUrl() {
+		return this.url;
+	}
+
+	public int hashCode() {
+		return this.url.hashCode();
+	}
+
+	public boolean isParticipantIndex() {
+		return this.participantIndex;
+	}
+
+	/**
+	 * @return the last modified time if the location is a file or -1 otherwise
+	 */
+	public abstract long lastModified();
+
+	/**
+	 * @return the length of the file if the location is a file or -1 otherwise
+	 */
+	public abstract long length();
+
+	public abstract boolean startsWith(IPath path);
+
+	public String toString() {
+		return this.url.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java
new file mode 100644
index 0000000..a93a264
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/JarIndexLocation.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class JarIndexLocation extends IndexLocation {
+	private JarFile jarFile = null;
+	private JarEntry jarEntry = null;
+	private URL localUrl;
+
+	public JarIndexLocation(URL url, URL localUrl2) {
+		super(url);
+		this.localUrl = localUrl2;
+	}
+
+	public boolean createNewFile() throws IOException {
+		return false;
+	}
+
+	public void close() {
+		if (this.jarFile != null) {
+			try {
+				this.jarFile.close();
+			} catch (IOException e) {
+				// ignore
+			}
+			this.jarFile = null;
+		}
+	}
+
+	public boolean delete() {
+		return false;
+	}
+
+	public boolean equals(Object other) {
+		if (!(other instanceof JarIndexLocation)) return false;
+		return this.localUrl.equals(((JarIndexLocation) other).localUrl);
+	}
+
+	public boolean exists() {
+		try {
+			if (this.jarFile == null) {
+				JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
+				JarFile file = connection.getJarFile();
+				if (file == null)
+					return false;
+				file.close();
+			}
+		} catch (IOException e) {
+			return false;
+		}
+		return true;
+	}
+
+	public String fileName() {
+		return null;
+	}
+
+	public File getIndexFile() {
+		return null;
+	}
+
+	InputStream getInputStream() throws IOException {
+		if (this.jarFile == null) {
+			JarURLConnection connection = (JarURLConnection) this.localUrl.openConnection();
+			this.jarFile = connection.getJarFile();
+			this.jarEntry = connection.getJarEntry();
+		}
+		if (this.jarFile == null || this.jarEntry == null)
+			return null;
+		return this.jarFile.getInputStream(this.jarEntry);
+	}
+
+	public String getCanonicalFilePath() {
+		return null;
+	}
+
+	public long lastModified() {
+		return -1;
+	}
+
+	public long length() {
+		return -1;
+	}
+
+	public boolean startsWith(IPath path) {
+		return (path.isPrefixOf(new Path(this.localUrl.getPath())));
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java
new file mode 100644
index 0000000..1f8d84f
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.index;
+
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.util.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class MemoryIndex {
+
+public int NUM_CHANGES = 100; // number of separate document changes... used to decide when to merge
+
+SimpleLookupTable docsToReferences; // document paths -> HashtableOfObject(category names -> set of words)
+SimpleWordSet allWords; // save space by locally interning the referenced words, since an indexer can generate numerous duplicates
+String lastDocumentName;
+HashtableOfObject lastReferenceTable;
+
+MemoryIndex() {
+	this.docsToReferences = new SimpleLookupTable(7);
+	this.allWords = new SimpleWordSet(7);
+}
+void addDocumentNames(String substring, SimpleSet results) {
+	// assumed the disk index already skipped over documents which have been added/changed/deleted
+	Object[] paths = this.docsToReferences.keyTable;
+	Object[] referenceTables = this.docsToReferences.valueTable;
+	if (substring == null) { // add all new/changed documents
+		for (int i = 0, l = referenceTables.length; i < l; i++)
+			if (referenceTables[i] != null)
+				results.add(paths[i]);
+	} else {
+		for (int i = 0, l = referenceTables.length; i < l; i++)
+			if (referenceTables[i] != null && ((String) paths[i]).startsWith(substring, 0))
+				results.add(paths[i]);
+	}
+}
+void addIndexEntry(char[] category, char[] key, String documentName) {
+	HashtableOfObject referenceTable;
+	if (documentName.equals(this.lastDocumentName))
+		referenceTable = this.lastReferenceTable;
+	else {
+		// assumed a document was removed before its reindexed
+		referenceTable = (HashtableOfObject) this.docsToReferences.get(documentName);
+		if (referenceTable == null)
+			this.docsToReferences.put(documentName, referenceTable = new HashtableOfObject(3));
+		this.lastDocumentName = documentName;
+		this.lastReferenceTable = referenceTable;
+	}
+
+	SimpleWordSet existingWords = (SimpleWordSet) referenceTable.get(category);
+	if (existingWords == null)
+		referenceTable.put(category, existingWords = new SimpleWordSet(1));
+
+	existingWords.add(this.allWords.add(key));
+}
+HashtableOfObject addQueryResults(char[][] categories, char[] key, int matchRule, HashtableOfObject results) {
+	// assumed the disk index already skipped over documents which have been added/changed/deleted
+	// results maps a word -> EntryResult
+	Object[] paths = this.docsToReferences.keyTable;
+	Object[] referenceTables = this.docsToReferences.valueTable;
+	if (matchRule == (SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE) && key != null) {
+		nextPath : for (int i = 0, l = referenceTables.length; i < l; i++) {
+			HashtableOfObject categoryToWords = (HashtableOfObject) referenceTables[i];
+			if (categoryToWords != null) {
+				for (int j = 0, m = categories.length; j < m; j++) {
+					SimpleWordSet wordSet = (SimpleWordSet) categoryToWords.get(categories[j]);
+					if (wordSet != null && wordSet.includes(key)) {
+						if (results == null)
+							results = new HashtableOfObject(13);
+						EntryResult result = (EntryResult) results.get(key);
+						if (result == null)
+							results.put(key, result = new EntryResult(key, null));
+						result.addDocumentName((String) paths[i]);
+						continue nextPath;
+					}
+				}
+			}
+		}
+	} else {
+		for (int i = 0, l = referenceTables.length; i < l; i++) {
+			HashtableOfObject categoryToWords = (HashtableOfObject) referenceTables[i];
+			if (categoryToWords != null) {
+				for (int j = 0, m = categories.length; j < m; j++) {
+					SimpleWordSet wordSet = (SimpleWordSet) categoryToWords.get(categories[j]);
+					if (wordSet != null) {
+						char[][] words = wordSet.words;
+						for (int k = 0, n = words.length; k < n; k++) {
+							char[] word = words[k];
+							if (word != null && Index.isMatch(key, word, matchRule)) {
+								if (results == null)
+									results = new HashtableOfObject(13);
+								EntryResult result = (EntryResult) results.get(word);
+								if (result == null)
+									results.put(word, result = new EntryResult(word, null));
+								result.addDocumentName((String) paths[i]);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return results;
+}
+boolean hasChanged() {
+	return this.docsToReferences.elementSize > 0;
+}
+void remove(String documentName) {
+	if (documentName.equals(this.lastDocumentName)) {
+		this.lastDocumentName = null;
+		this.lastReferenceTable = null;
+	}
+	this.docsToReferences.put(documentName, null);
+}
+boolean shouldMerge() {
+	return this.docsToReferences.elementSize >= this.NUM_CHANGES;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractJavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractJavaSearchScope.java
new file mode 100644
index 0000000..d401b35
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractJavaSearchScope.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+
+
+public abstract class AbstractJavaSearchScope extends AbstractSearchScope {
+
+/**
+ * Get access rule set corresponding to a given path.
+ * @param relativePath The path user want to have restriction access
+ * @return The access rule set for given path or null if none is set for it.
+ * 	Returns specific unit access rule set when scope does not enclose the given path.
+ */
+abstract public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath);
+
+/**
+ * Returns the package fragment root corresponding to a given resource path.
+ *
+ * @param resourcePathString path of expected package fragment root.
+ * @param jarSeparatorIndex the index of the jar separator in the resource path, or -1 if none
+ * @param jarPath the already extracted jar path, or null if none
+ * @return the {@link IPackageFragmentRoot package fragment root} which path
+ * 	match the given one or <code>null</code> if none was found.
+ */
+abstract public IPackageFragmentRoot packageFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPath);
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java
new file mode 100644
index 0000000..afa05dc
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+
+public abstract class AbstractSearchScope implements IJavaSearchScope {
+
+/**
+ * @see IJavaSearchScope#includesBinaries()
+ * @deprecated
+ */
+public boolean includesBinaries() {
+	return true;
+}
+
+/**
+ * @see IJavaSearchScope#includesClasspaths()
+ * @deprecated
+ */
+public boolean includesClasspaths() {
+	return true;
+}
+
+/* (non-Javadoc)
+ * Process the given delta and refresh its internal state if needed.
+ * Returns whether the internal state was refreshed.
+ */
+public abstract void processDelta(IJavaElementDelta delta, int eventType);
+
+/**
+ * @see IJavaSearchScope#setIncludesBinaries(boolean)
+ * @deprecated
+ */
+public void setIncludesBinaries(boolean includesBinaries) {
+	// implements interface method
+}
+
+/**
+ * @see IJavaSearchScope#setIncludesClasspaths(boolean)
+ * @deprecated
+ */
+public void setIncludesClasspaths(boolean includesClasspaths) {
+	// implements interface method
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
new file mode 100644
index 0000000..ba5c38b
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
@@ -0,0 +1,1617 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for bug 215139 and bug 295894
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.search.indexing.*;
+import org.eclipse.jdt.internal.core.search.matching.*;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Search basic engine. Public search engine (see {@link org.eclipse.jdt.core.search.SearchEngine}
+ * for detailed comment), now uses basic engine functionalities.
+ * Note that search basic engine does not implement deprecated functionalities...
+ */
+public class BasicSearchEngine {
+
+	/*
+	 * A default parser to parse non-reconciled working copies
+	 */
+	private Parser parser;
+	private CompilerOptions compilerOptions;
+
+	/*
+	 * A list of working copies that take precedence over their original
+	 * compilation units.
+	 */
+	private ICompilationUnit[] workingCopies;
+
+	/*
+	 * A working copy owner whose working copies will take precedent over
+	 * their original compilation units.
+	 */
+	private WorkingCopyOwner workingCopyOwner;
+
+	/**
+	 * For tracing purpose.
+	 */
+	public static boolean VERBOSE = false;
+
+	/*
+	 * Creates a new search basic engine.
+	 */
+	public BasicSearchEngine() {
+		// will use working copies of PRIMARY owner
+	}
+
+	/**
+	 * @see SearchEngine#SearchEngine(ICompilationUnit[]) for detailed comment.
+	 */
+	public BasicSearchEngine(ICompilationUnit[] workingCopies) {
+		this.workingCopies = workingCopies;
+	}
+
+	char convertTypeKind(int typeDeclarationKind) {
+		switch(typeDeclarationKind) {
+			case TypeDeclaration.CLASS_DECL : return IIndexConstants.CLASS_SUFFIX;
+			case TypeDeclaration.INTERFACE_DECL : return IIndexConstants.INTERFACE_SUFFIX;
+			case TypeDeclaration.ENUM_DECL : return IIndexConstants.ENUM_SUFFIX;
+			case TypeDeclaration.ANNOTATION_TYPE_DECL : return IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+			default : return IIndexConstants.TYPE_SUFFIX;
+		}
+	}
+	/**
+	 * @see SearchEngine#SearchEngine(WorkingCopyOwner) for detailed comment.
+	 */
+	public BasicSearchEngine(WorkingCopyOwner workingCopyOwner) {
+		this.workingCopyOwner = workingCopyOwner;
+	}
+
+	/**
+	 * @see SearchEngine#createHierarchyScope(IType) for detailed comment.
+	 */
+	public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException {
+		return createHierarchyScope(type, DefaultWorkingCopyOwner.PRIMARY);
+	}
+
+	/**
+	 * @see SearchEngine#createHierarchyScope(IType,WorkingCopyOwner) for detailed comment.
+	 */
+	public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException {
+		return new HierarchyScope(type, owner);
+	}
+
+	/**
+	 * @see SearchEngine#createStrictHierarchyScope(IJavaProject,IType,boolean,boolean,WorkingCopyOwner) for detailed comment.
+	 */
+	public static IJavaSearchScope createStrictHierarchyScope(IJavaProject project, IType type, boolean onlySubtypes, boolean includeFocusType, WorkingCopyOwner owner) throws JavaModelException {
+		return new HierarchyScope(project, type, owner, onlySubtypes, true, includeFocusType);
+	}
+
+	/**
+	 * @see SearchEngine#createJavaSearchScope(IJavaElement[]) for detailed comment.
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) {
+		return createJavaSearchScope(elements, true);
+	}
+
+	/**
+	 * @see SearchEngine#createJavaSearchScope(IJavaElement[], boolean) for detailed comment.
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) {
+		int includeMask = IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES;
+		if (includeReferencedProjects) {
+			includeMask |= IJavaSearchScope.REFERENCED_PROJECTS;
+		}
+		return createJavaSearchScope(elements, includeMask);
+	}
+
+	/**
+	 * @see SearchEngine#createJavaSearchScope(IJavaElement[], int) for detailed comment.
+	 */
+	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) {
+		HashSet projectsToBeAdded = new HashSet(2);
+		for (int i = 0, length = elements.length; i < length; i++) {
+			IJavaElement element = elements[i];
+			if (element instanceof JavaProject) {
+				projectsToBeAdded.add(element);
+			}
+		}
+		JavaSearchScope scope = new JavaSearchScope();
+		for (int i = 0, length = elements.length; i < length; i++) {
+			IJavaElement element = elements[i];
+			if (element != null) {
+				try {
+					if (projectsToBeAdded.contains(element)) {
+						scope.add((JavaProject)element, includeMask, projectsToBeAdded);
+					} else {
+						scope.add(element);
+					}
+				} catch (JavaModelException e) {
+					// ignore
+				}
+			}
+		}
+		return scope;
+	}
+
+	/**
+	 * @see SearchEngine#createTypeNameMatch(IType, int) for detailed comment.
+	 */
+	public static TypeNameMatch createTypeNameMatch(IType type, int modifiers) {
+		return new JavaSearchTypeNameMatch(type, modifiers);
+	}
+
+	/**
+	 * @see SearchEngine#createWorkspaceScope() for detailed comment.
+	 */
+	public static IJavaSearchScope createWorkspaceScope() {
+		return JavaModelManager.getJavaModelManager().getWorkspaceScope();
+	}
+
+	/**
+	 * Searches for matches to a given query. Search queries can be created using helper
+	 * methods (from a String pattern or a Java element) and encapsulate the description of what is
+	 * being searched (for example, search method declarations in a case sensitive way).
+	 *
+	 * @param scope the search result has to be limited to the given scope
+	 * @param requestor a callback object to which each match is reported
+	 */
+	void findMatches(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+		if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+		try {
+			if (VERBOSE) {
+				Util.verbose("Searching for pattern: " + pattern.toString()); //$NON-NLS-1$
+				Util.verbose(scope.toString());
+			}
+			if (participants == null) {
+				if (VERBOSE) Util.verbose("No participants => do nothing!"); //$NON-NLS-1$
+				return;
+			}
+
+			/* initialize progress monitor */
+			int length = participants.length;
+			if (monitor != null)
+				monitor.beginTask(Messages.engine_searching, 100 * length);
+			IndexManager indexManager = JavaModelManager.getIndexManager();
+			requestor.beginReporting();
+			for (int i = 0; i < length; i++) {
+				if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+
+				SearchParticipant participant = participants[i];
+				try {
+					if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_indexing, new String[] {participant.getDescription()}));
+					participant.beginSearching();
+					requestor.enterParticipant(participant);
+					PathCollector pathCollector = new PathCollector();
+					indexManager.performConcurrentJob(
+						new PatternSearchJob(pattern, participant, scope, pathCollector),
+						IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+						monitor==null ? null : new SubProgressMonitor(monitor, 50));
+					if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+
+					// locate index matches if any (note that all search matches could have been issued during index querying)
+					if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_matching, new String[] {participant.getDescription()}));
+					String[] indexMatchPaths = pathCollector.getPaths();
+					if (indexMatchPaths != null) {
+						pathCollector = null; // release
+						int indexMatchLength = indexMatchPaths.length;
+						SearchDocument[] indexMatches = new SearchDocument[indexMatchLength];
+						for (int j = 0; j < indexMatchLength; j++) {
+							indexMatches[j] = participant.getDocument(indexMatchPaths[j]);
+						}
+						SearchDocument[] matches = MatchLocator.addWorkingCopies(pattern, indexMatches, getWorkingCopies(), participant);
+						participant.locateMatches(matches, pattern, scope, requestor, monitor==null ? null : new SubProgressMonitor(monitor, 50));
+					}
+				} finally {
+					requestor.exitParticipant(participant);
+					participant.doneSearching();
+				}
+			}
+		} finally {
+			requestor.endReporting();
+			if (monitor != null)
+				monitor.done();
+		}
+	}
+	/**
+	 * Returns a new default Java search participant.
+	 *
+	 * @return a new default Java search participant
+	 * @since 3.0
+	 */
+	public static SearchParticipant getDefaultSearchParticipant() {
+		return new JavaSearchParticipant();
+	}
+
+	/**
+	 * @param matchRule
+	 */
+	public static String getMatchRuleString(final int matchRule) {
+		if (matchRule == 0) {
+			return "R_EXACT_MATCH"; //$NON-NLS-1$
+		}
+		StringBuffer buffer = new StringBuffer();
+		for (int i=1; i<=16; i++) {
+			int bit = matchRule & (1<<(i-1));
+			if (bit != 0 && buffer.length()>0) buffer.append(" | "); //$NON-NLS-1$
+			switch (bit) {
+				case SearchPattern.R_PREFIX_MATCH:
+					buffer.append("R_PREFIX_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_CASE_SENSITIVE:
+					buffer.append("R_CASE_SENSITIVE"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_EQUIVALENT_MATCH:
+					buffer.append("R_EQUIVALENT_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_ERASURE_MATCH:
+					buffer.append("R_ERASURE_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_FULL_MATCH:
+					buffer.append("R_FULL_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_PATTERN_MATCH:
+					buffer.append("R_PATTERN_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_REGEXP_MATCH:
+					buffer.append("R_REGEXP_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_CAMELCASE_MATCH:
+					buffer.append("R_CAMELCASE_MATCH"); //$NON-NLS-1$
+					break;
+				case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+					buffer.append("R_CAMELCASE_SAME_PART_COUNT_MATCH"); //$NON-NLS-1$
+					break;
+			}
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * Return kind of search corresponding to given value.
+	 *
+	 * @param searchFor
+	 */
+	public static String getSearchForString(final int searchFor) {
+		switch (searchFor) {
+			case IJavaSearchConstants.TYPE:
+				return ("TYPE"); //$NON-NLS-1$
+			case IJavaSearchConstants.METHOD:
+				return ("METHOD"); //$NON-NLS-1$
+			case IJavaSearchConstants.PACKAGE:
+				return ("PACKAGE"); //$NON-NLS-1$
+			case IJavaSearchConstants.CONSTRUCTOR:
+				return ("CONSTRUCTOR"); //$NON-NLS-1$
+			case IJavaSearchConstants.FIELD:
+				return ("FIELD"); //$NON-NLS-1$
+			case IJavaSearchConstants.CLASS:
+				return ("CLASS"); //$NON-NLS-1$
+			case IJavaSearchConstants.INTERFACE:
+				return ("INTERFACE"); //$NON-NLS-1$
+			case IJavaSearchConstants.ENUM:
+				return ("ENUM"); //$NON-NLS-1$
+			case IJavaSearchConstants.ANNOTATION_TYPE:
+				return ("ANNOTATION_TYPE"); //$NON-NLS-1$
+			case IJavaSearchConstants.CLASS_AND_ENUM:
+				return ("CLASS_AND_ENUM"); //$NON-NLS-1$
+			case IJavaSearchConstants.CLASS_AND_INTERFACE:
+				return ("CLASS_AND_INTERFACE"); //$NON-NLS-1$
+			case IJavaSearchConstants.INTERFACE_AND_ANNOTATION:
+				return ("INTERFACE_AND_ANNOTATION"); //$NON-NLS-1$
+		}
+		return "UNKNOWN"; //$NON-NLS-1$
+	}
+
+	private Parser getParser() {
+		if (this.parser == null) {
+			this.compilerOptions = new CompilerOptions(JavaCore.getOptions());
+			ProblemReporter problemReporter =
+				new ProblemReporter(
+					DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+					this.compilerOptions,
+					new DefaultProblemFactory());
+			this.parser = new Parser(problemReporter, true);
+		}
+		return this.parser;
+	}
+
+	/*
+	 * Returns the list of working copies used by this search engine.
+	 * Returns null if none.
+	 */
+	private ICompilationUnit[] getWorkingCopies() {
+		ICompilationUnit[] copies;
+		if (this.workingCopies != null) {
+			if (this.workingCopyOwner == null) {
+				copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/);
+				if (copies == null) {
+					copies = this.workingCopies;
+				} else {
+					HashMap pathToCUs = new HashMap();
+					for (int i = 0, length = copies.length; i < length; i++) {
+						ICompilationUnit unit = copies[i];
+						pathToCUs.put(unit.getPath(), unit);
+					}
+					for (int i = 0, length = this.workingCopies.length; i < length; i++) {
+						ICompilationUnit unit = this.workingCopies[i];
+						pathToCUs.put(unit.getPath(), unit);
+					}
+					int length = pathToCUs.size();
+					copies = new ICompilationUnit[length];
+					pathToCUs.values().toArray(copies);
+				}
+			} else {
+				copies = this.workingCopies;
+			}
+		} else if (this.workingCopyOwner != null) {
+			copies = JavaModelManager.getJavaModelManager().getWorkingCopies(this.workingCopyOwner, true/*add primary WCs*/);
+		} else {
+			copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/);
+		}
+		if (copies == null) return null;
+
+		// filter out primary working copies that are saved
+		ICompilationUnit[] result = null;
+		int length = copies.length;
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			CompilationUnit copy = (CompilationUnit)copies[i];
+			try {
+				if (!copy.isPrimary()
+						|| copy.hasUnsavedChanges()
+						|| copy.hasResourceChanged()) {
+					if (result == null) {
+						result = new ICompilationUnit[length];
+					}
+					result[index++] = copy;
+				}
+			}  catch (JavaModelException e) {
+				// copy doesn't exist: ignore
+			}
+		}
+		if (index != length && result != null) {
+			System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index);
+		}
+		return result;
+	}
+
+	/*
+	 * Returns the working copy to use to do the search on the given Java element.
+	 */
+	private ICompilationUnit[] getWorkingCopies(IJavaElement element) {
+		if (element instanceof IMember) {
+			ICompilationUnit cu = ((IMember)element).getCompilationUnit();
+			if (cu != null && cu.isWorkingCopy()) {
+				return new ICompilationUnit[] { cu };
+			}
+		} else if (element instanceof ICompilationUnit) {
+			return new ICompilationUnit[] { (ICompilationUnit) element };
+		}
+
+		return null;
+	}
+
+	boolean match(char patternTypeSuffix, int modifiers) {
+		switch(patternTypeSuffix) {
+			case IIndexConstants.CLASS_SUFFIX :
+				return (modifiers & (Flags.AccAnnotation | Flags.AccInterface | Flags.AccEnum)) == 0;
+			case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX:
+				return (modifiers & (Flags.AccAnnotation | Flags.AccEnum)) == 0;
+			case IIndexConstants.CLASS_AND_ENUM_SUFFIX:
+				return (modifiers & (Flags.AccAnnotation | Flags.AccInterface)) == 0;
+			case IIndexConstants.INTERFACE_SUFFIX :
+				return (modifiers & Flags.AccInterface) != 0;
+			case IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX:
+				return (modifiers & (Flags.AccInterface | Flags.AccAnnotation)) != 0;
+			case IIndexConstants.ENUM_SUFFIX :
+				return (modifiers & Flags.AccEnum) != 0;
+			case IIndexConstants.ANNOTATION_TYPE_SUFFIX :
+				return (modifiers & Flags.AccAnnotation) != 0;
+		}
+		return true;
+	}
+
+	boolean match(char patternTypeSuffix, char[] patternPkg, int matchRulePkg, char[] patternTypeName, int matchRuleType, int typeKind, char[] pkg, char[] typeName) {
+		switch(patternTypeSuffix) {
+			case IIndexConstants.CLASS_SUFFIX :
+				if (typeKind != TypeDeclaration.CLASS_DECL) return false;
+				break;
+			case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX:
+				if (typeKind != TypeDeclaration.CLASS_DECL && typeKind != TypeDeclaration.INTERFACE_DECL) return false;
+				break;
+			case IIndexConstants.CLASS_AND_ENUM_SUFFIX:
+				if (typeKind != TypeDeclaration.CLASS_DECL && typeKind != TypeDeclaration.ENUM_DECL) return false;
+				break;
+			case IIndexConstants.INTERFACE_SUFFIX :
+				if (typeKind != TypeDeclaration.INTERFACE_DECL) return false;
+				break;
+			case IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX:
+				if (typeKind != TypeDeclaration.INTERFACE_DECL && typeKind != TypeDeclaration.ANNOTATION_TYPE_DECL) return false;
+				break;
+			case IIndexConstants.ENUM_SUFFIX :
+				if (typeKind != TypeDeclaration.ENUM_DECL) return false;
+				break;
+			case IIndexConstants.ANNOTATION_TYPE_SUFFIX :
+				if (typeKind != TypeDeclaration.ANNOTATION_TYPE_DECL) return false;
+				break;
+			case IIndexConstants.TYPE_SUFFIX : // nothing
+		}
+
+		boolean isPkgCaseSensitive = (matchRulePkg & SearchPattern.R_CASE_SENSITIVE) != 0;
+		if (patternPkg != null && !CharOperation.equals(patternPkg, pkg, isPkgCaseSensitive))
+			return false;
+		
+		boolean isCaseSensitive = (matchRuleType & SearchPattern.R_CASE_SENSITIVE) != 0;
+		if (patternTypeName != null) {
+			boolean isCamelCase = (matchRuleType & (SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
+			int matchMode = matchRuleType & JavaSearchPattern.MATCH_MODE_MASK;
+			if (!isCaseSensitive && !isCamelCase) {
+				patternTypeName = CharOperation.toLowerCase(patternTypeName);
+			}
+			boolean matchFirstChar = !isCaseSensitive || patternTypeName[0] == typeName[0];
+			switch(matchMode) {
+				case SearchPattern.R_EXACT_MATCH :
+					return matchFirstChar && CharOperation.equals(patternTypeName, typeName, isCaseSensitive);
+				case SearchPattern.R_PREFIX_MATCH :
+					return matchFirstChar && CharOperation.prefixEquals(patternTypeName, typeName, isCaseSensitive);
+				case SearchPattern.R_PATTERN_MATCH :
+					return CharOperation.match(patternTypeName, typeName, isCaseSensitive);
+				case SearchPattern.R_REGEXP_MATCH :
+					// TODO (frederic) implement regular expression match
+					break;
+				case SearchPattern.R_CAMELCASE_MATCH:
+					if (matchFirstChar && CharOperation.camelCaseMatch(patternTypeName, typeName, false)) {
+						return true;
+					}
+					return !isCaseSensitive && matchFirstChar && CharOperation.prefixEquals(patternTypeName, typeName, false);
+				case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+					return matchFirstChar && CharOperation.camelCaseMatch(patternTypeName, typeName, true);
+			}
+		}
+		return true;
+
+	}
+
+	/**
+	 * Searches for matches of a given search pattern. Search patterns can be created using helper
+	 * methods (from a String pattern or a Java element) and encapsulate the description of what is
+	 * being searched (for example, search method declarations in a case sensitive way).
+	 *
+	 * @see SearchEngine#search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); //$NON-NLS-1$
+		}
+		findMatches(pattern, participants, scope, requestor, monitor);
+	}
+	
+	public void searchAllConstructorDeclarations(
+		final char[] packageName,
+		final char[] typeName,
+		final int typeMatchRule,
+		IJavaSearchScope scope,
+		final IRestrictedAccessConstructorRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		// Validate match rule first
+		final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
+		
+		final int pkgMatchRule = SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE;
+		final char NoSuffix = IIndexConstants.TYPE_SUFFIX; // Used as TYPE_SUFFIX has no effect in method #match(char, char[] , int, char[], int , int, char[], char[])
+
+		// Debug
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchAllConstructorDeclarations(char[], char[], int, IJavaSearchScope, IRestrictedAccessConstructorRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
+			if (validatedTypeMatchRule != typeMatchRule) {
+				Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+			}
+			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
+		}
+		if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
+
+		// Create pattern
+		IndexManager indexManager = JavaModelManager.getIndexManager();
+		final ConstructorDeclarationPattern pattern = new ConstructorDeclarationPattern(
+				packageName,
+				typeName,
+				validatedTypeMatchRule);
+
+		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+		final HashSet workingCopyPaths = new HashSet();
+		String workingCopyPath = null;
+		ICompilationUnit[] copies = getWorkingCopies();
+		final int copiesLength = copies == null ? 0 : copies.length;
+		if (copies != null) {
+			if (copiesLength == 1) {
+				workingCopyPath = copies[0].getPath().toString();
+			} else {
+				for (int i = 0; i < copiesLength; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					workingCopyPaths.add(workingCopy.getPath().toString());
+				}
+			}
+		}
+		final String singleWkcpPath = workingCopyPath;
+
+		// Index requestor
+		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+				// Filter unexpected types
+				ConstructorDeclarationPattern record = (ConstructorDeclarationPattern)indexRecord;
+				
+				if ((record.extraFlags & ExtraFlags.IsMemberType) != 0) {
+					return true; // filter out member classes
+				}
+				if ((record.extraFlags & ExtraFlags.IsLocalType) != 0) {
+					return true; // filter out local and anonymous classes
+				}
+				switch (copiesLength) {
+					case 0:
+						break;
+					case 1:
+						if (singleWkcpPath.equals(documentPath)) {
+							return true; // filter out *the* working copy
+						}
+						break;
+					default:
+						if (workingCopyPaths.contains(documentPath)) {
+							return true; // filter out working copies
+						}
+						break;
+				}
+
+				// Accept document path
+				AccessRestriction accessRestriction = null;
+				if (access != null) {
+					// Compute document relative path
+					int pkgLength = (record.declaringPackageName==null || record.declaringPackageName.length==0) ? 0 : record.declaringPackageName.length+1;
+					int nameLength = record.declaringSimpleName==null ? 0 : record.declaringSimpleName.length;
+					char[] path = new char[pkgLength+nameLength];
+					int pos = 0;
+					if (pkgLength > 0) {
+						System.arraycopy(record.declaringPackageName, 0, path, pos, pkgLength-1);
+						CharOperation.replace(path, '.', '/');
+						path[pkgLength-1] = '/';
+						pos += pkgLength;
+					}
+					if (nameLength > 0) {
+						System.arraycopy(record.declaringSimpleName, 0, path, pos, nameLength);
+						pos += nameLength;
+					}
+					// Update access restriction if path is not empty
+					if (pos > 0) {
+						accessRestriction = access.getViolatedRestriction(path);
+					}
+				}
+				nameRequestor.acceptConstructor(
+						record.modifiers,
+						record.declaringSimpleName,
+						record.parameterCount,
+						record.signature,
+						record.parameterTypes,
+						record.parameterNames,
+						record.declaringTypeModifiers,
+						record.declaringPackageName,
+						record.extraFlags,
+						documentPath,
+						accessRestriction);
+				return true;
+			}
+		};
+
+		try {
+			if (progressMonitor != null) {
+				progressMonitor.beginTask(Messages.engine_searching, 1000);
+			}
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 1000-copiesLength));
+
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0; i < copiesLength; i++) {
+					final ICompilationUnit workingCopy = copies[i];
+					if (scope instanceof HierarchyScope) {
+						if (!((HierarchyScope)scope).encloses(workingCopy, progressMonitor)) continue;
+					} else {
+						if (!scope.encloses(workingCopy)) continue;
+					}
+					
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							char[] simpleName = type.getElementName().toCharArray();
+							if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, simpleName) && !type.isMember()) {
+								
+								int extraFlags = ExtraFlags.getExtraFlags(type);
+								
+								boolean hasConstructor = false;
+								
+								IMethod[] methods = type.getMethods();
+								for (int k = 0; k < methods.length; k++) {
+									IMethod method = methods[k];
+									if (method.isConstructor()) {
+										hasConstructor = true;
+										
+										String[] stringParameterNames = method.getParameterNames();
+										String[] stringParameterTypes = method.getParameterTypes();
+										int length = stringParameterNames.length;
+										char[][] parameterNames = new char[length][];
+										char[][] parameterTypes = new char[length][];
+										for (int l = 0; l < length; l++) {
+											parameterNames[l] = stringParameterNames[l].toCharArray();
+											parameterTypes[l] = Signature.toCharArray(Signature.getTypeErasure(stringParameterTypes[l]).toCharArray());
+										}
+										
+										nameRequestor.acceptConstructor(
+												method.getFlags(),
+												simpleName,
+												parameterNames.length,
+												null,// signature is not used for source type
+												parameterTypes, 
+												parameterNames,
+												type.getFlags(),
+												packageDeclaration,
+												extraFlags,
+												path,
+												null);
+									}
+								}
+								
+								if (!hasConstructor) {
+									nameRequestor.acceptConstructor(
+											Flags.AccPublic,
+											simpleName,
+											-1,
+											null, // signature is not used for source type
+											CharOperation.NO_CHAR_CHAR,
+											CharOperation.NO_CHAR_CHAR,
+											type.getFlags(),
+											packageDeclaration,
+											extraFlags,
+											path,
+											null);
+								}
+							}
+						}
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllConstructorDeclarationsVisitor extends ASTVisitor {
+								private TypeDeclaration[] declaringTypes = new TypeDeclaration[0];
+								private int declaringTypesPtr = -1;
+								
+								private void endVisit(TypeDeclaration typeDeclaration) {
+									if (!hasConstructor(typeDeclaration) && typeDeclaration.enclosingType == null) {
+									
+										if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, typeDeclaration.name)) {
+											nameRequestor.acceptConstructor(
+													Flags.AccPublic,
+													typeName,
+													-1,
+													null, // signature is not used for source type
+													CharOperation.NO_CHAR_CHAR,
+													CharOperation.NO_CHAR_CHAR,
+													typeDeclaration.modifiers,
+													packageDeclaration,
+													ExtraFlags.getExtraFlags(typeDeclaration),
+													path,
+													null);
+										}
+									}
+									
+									this.declaringTypes[this.declaringTypesPtr] = null;
+									this.declaringTypesPtr--;
+								}
+								
+								public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+									endVisit(typeDeclaration);
+								}
+								
+								public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+									endVisit(memberTypeDeclaration);
+								}
+								
+								private boolean hasConstructor(TypeDeclaration typeDeclaration) {
+									AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+									int length = methods == null ? 0 : methods.length;
+									for (int j = 0; j < length; j++) {
+										if (methods[j].isConstructor()) {
+											return true;
+										}
+									}
+									
+									return false;
+								}
+								public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope classScope) {
+									TypeDeclaration typeDeclaration = this.declaringTypes[this.declaringTypesPtr];
+									if (match(NoSuffix, packageName, pkgMatchRule, typeName, validatedTypeMatchRule, 0/*no kind*/, packageDeclaration, typeDeclaration.name)) {
+										Argument[] arguments = constructorDeclaration.arguments;
+										int length = arguments == null ? 0 : arguments.length;
+										char[][] parameterNames = new char[length][];
+										char[][] parameterTypes = new char[length][];
+										for (int l = 0; l < length; l++) {
+											Argument argument = arguments[l];
+											parameterNames[l] = argument.name;
+											if (argument.type instanceof SingleTypeReference) {
+												parameterTypes[l] = ((SingleTypeReference)argument.type).token;
+											} else {
+												parameterTypes[l] = CharOperation.concatWith(((QualifiedTypeReference)argument.type).tokens, '.');
+											}
+										}
+										
+										TypeDeclaration enclosing = typeDeclaration.enclosingType;
+										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+										while (enclosing != null) {
+											enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+											if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+												enclosing = enclosing.enclosingType;
+											} else {
+												enclosing = null;
+											}
+										}
+										
+										nameRequestor.acceptConstructor(
+												constructorDeclaration.modifiers,
+												typeName,
+												parameterNames.length,
+												null, // signature is not used for source type
+												parameterTypes,
+												parameterNames,
+												typeDeclaration.modifiers,
+												packageDeclaration,
+												ExtraFlags.getExtraFlags(typeDeclaration),
+												path,
+												null);
+									}
+									return false; // no need to find constructors from local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; 
+								}
+								
+								private boolean visit(TypeDeclaration typeDeclaration) {
+									if(this.declaringTypes.length <= ++this.declaringTypesPtr) {
+										int length = this.declaringTypesPtr;
+										System.arraycopy(this.declaringTypes, 0, this.declaringTypes = new TypeDeclaration[length * 2 + 1], 0, length);
+									}
+									this.declaringTypes[this.declaringTypesPtr] = typeDeclaration;
+									return true;
+								}
+								
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope s) {
+									return visit(typeDeclaration);
+								}
+								
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope s) {
+									return visit(memberTypeDeclaration);
+								}
+							}
+							parsedUnit.traverse(new AllConstructorDeclarationsVisitor(), parsedUnit.scope);
+						}
+					}
+					if (progressMonitor != null) {
+						if (progressMonitor.isCanceled()) throw new OperationCanceledException();
+						progressMonitor.worked(1);
+					}
+				}
+			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
+		}
+	}
+
+	/**
+	 * Searches for all secondary types in the given scope.
+	 * The search can be selecting specific types (given a package or a type name
+	 * prefix and match modes).
+	 */
+	public void searchAllSecondaryTypeNames(
+			IPackageFragmentRoot[] sourceFolders,
+			final IRestrictedAccessTypeRequestor nameRequestor,
+			boolean waitForIndexes,
+			IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); //$NON-NLS-1$
+			StringBuffer buffer = new StringBuffer("	- source folders: "); //$NON-NLS-1$
+			int length = sourceFolders.length;
+			for (int i=0; i<length; i++) {
+				if (i==0) {
+					buffer.append('[');
+				} else {
+					buffer.append(',');
+				}
+				buffer.append(sourceFolders[i].getElementName());
+			}
+			buffer.append("]\n	- waitForIndexes: "); //$NON-NLS-1$
+			buffer.append(waitForIndexes);
+			Util.verbose(buffer.toString());
+		}
+
+		IndexManager indexManager = JavaModelManager.getIndexManager();
+		final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern();
+
+		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+		final HashSet workingCopyPaths = new HashSet();
+		String workingCopyPath = null;
+		ICompilationUnit[] copies = getWorkingCopies();
+		final int copiesLength = copies == null ? 0 : copies.length;
+		if (copies != null) {
+			if (copiesLength == 1) {
+				workingCopyPath = copies[0].getPath().toString();
+			} else {
+				for (int i = 0; i < copiesLength; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					workingCopyPaths.add(workingCopy.getPath().toString());
+				}
+			}
+		}
+		final String singleWkcpPath = workingCopyPath;
+
+		// Index requestor
+		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+				// Filter unexpected types
+				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+				if (!record.secondary) {
+					return true; // filter maint types
+				}
+				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+					return true; // filter out local and anonymous classes
+				}
+				switch (copiesLength) {
+					case 0:
+						break;
+					case 1:
+						if (singleWkcpPath.equals(documentPath)) {
+							return true; // fliter out *the* working copy
+						}
+						break;
+					default:
+						if (workingCopyPaths.contains(documentPath)) {
+							return true; // filter out working copies
+						}
+						break;
+				}
+
+				// Accept document path
+				AccessRestriction accessRestriction = null;
+				if (access != null) {
+					// Compute document relative path
+					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
+					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
+					char[] path = new char[pkgLength+nameLength];
+					int pos = 0;
+					if (pkgLength > 0) {
+						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
+						CharOperation.replace(path, '.', '/');
+						path[pkgLength-1] = '/';
+						pos += pkgLength;
+					}
+					if (nameLength > 0) {
+						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+						pos += nameLength;
+					}
+					// Update access restriction if path is not empty
+					if (pos > 0) {
+						accessRestriction = access.getViolatedRestriction(path);
+					}
+				}
+				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+				return true;
+			}
+		};
+
+		// add type names from indexes
+		try {
+			if (progressMonitor != null) {
+				progressMonitor.beginTask(Messages.engine_searching, 100);
+			}
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					createJavaSearchScope(sourceFolders),
+					searchRequestor),
+				waitForIndexes
+					? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
+					: IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH,
+				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
+		} catch (OperationCanceledException oce) {
+			// do nothing
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
+		}
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package or a type name
+	 * prefix and match modes).
+	 *
+	 * @see SearchEngine#searchAllTypeNames(char[], int, char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void searchAllTypeNames(
+		final char[] packageName,
+		final int packageMatchRule,
+		final char[] typeName,
+		final int typeMatchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final IRestrictedAccessTypeRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		// Validate match rule first
+		final int validatedTypeMatchRule = SearchPattern.validateMatchRule(typeName == null ? null : new String (typeName), typeMatchRule);
+
+		// Debug
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+			Util.verbose("	- package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- package match rule: "+getMatchRuleString(packageMatchRule)); //$NON-NLS-1$
+			Util.verbose("	- type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- type match rule: "+getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
+			if (validatedTypeMatchRule != typeMatchRule) {
+				Util.verbose("	- validated type match rule: "+getMatchRuleString(validatedTypeMatchRule)); //$NON-NLS-1$
+			}
+			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
+			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
+		}
+		if (validatedTypeMatchRule == -1) return; // invalid match rule => return no results
+
+		// Create pattern
+		IndexManager indexManager = JavaModelManager.getIndexManager();
+		final char typeSuffix;
+		switch(searchFor){
+			case IJavaSearchConstants.CLASS :
+				typeSuffix = IIndexConstants.CLASS_SUFFIX;
+				break;
+			case IJavaSearchConstants.CLASS_AND_INTERFACE :
+				typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+				break;
+			case IJavaSearchConstants.CLASS_AND_ENUM :
+				typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+				break;
+			case IJavaSearchConstants.INTERFACE :
+				typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
+				break;
+			case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
+				typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
+				break;
+			case IJavaSearchConstants.ENUM :
+				typeSuffix = IIndexConstants.ENUM_SUFFIX;
+				break;
+			case IJavaSearchConstants.ANNOTATION_TYPE :
+				typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+				break;
+			default :
+				typeSuffix = IIndexConstants.TYPE_SUFFIX;
+				break;
+		}
+		final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH
+			? new TypeDeclarationPattern(
+				packageName,
+				null,
+				typeName,
+				typeSuffix,
+				validatedTypeMatchRule)
+			: new QualifiedTypeDeclarationPattern(
+				packageName,
+				packageMatchRule,
+				typeName,
+				typeSuffix,
+				validatedTypeMatchRule);
+
+		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+		final HashSet workingCopyPaths = new HashSet();
+		String workingCopyPath = null;
+		ICompilationUnit[] copies = getWorkingCopies();
+		final int copiesLength = copies == null ? 0 : copies.length;
+		if (copies != null) {
+			if (copiesLength == 1) {
+				workingCopyPath = copies[0].getPath().toString();
+			} else {
+				for (int i = 0; i < copiesLength; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					workingCopyPaths.add(workingCopy.getPath().toString());
+				}
+			}
+		}
+		final String singleWkcpPath = workingCopyPath;
+
+		// Index requestor
+		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+				// Filter unexpected types
+				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+					return true; // filter out local and anonymous classes
+				}
+				switch (copiesLength) {
+					case 0:
+						break;
+					case 1:
+						if (singleWkcpPath.equals(documentPath)) {
+							return true; // filter out *the* working copy
+						}
+						break;
+					default:
+						if (workingCopyPaths.contains(documentPath)) {
+							return true; // filter out working copies
+						}
+						break;
+				}
+
+				// Accept document path
+				AccessRestriction accessRestriction = null;
+				if (access != null) {
+					// Compute document relative path
+					int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
+					int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
+					char[] path = new char[pkgLength+nameLength];
+					int pos = 0;
+					if (pkgLength > 0) {
+						System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
+						CharOperation.replace(path, '.', '/');
+						path[pkgLength-1] = '/';
+						pos += pkgLength;
+					}
+					if (nameLength > 0) {
+						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+						pos += nameLength;
+					}
+					// Update access restriction if path is not empty
+					if (pos > 0) {
+						accessRestriction = access.getViolatedRestriction(path);
+					}
+				}
+				if (match(record.typeSuffix, record.modifiers)) {
+					nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+				}
+				return true;
+			}
+		};
+
+		try {
+			if (progressMonitor != null) {
+				progressMonitor.beginTask(Messages.engine_searching, 1000);
+			}
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 1000-copiesLength));
+
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0; i < copiesLength; i++) {
+					final ICompilationUnit workingCopy = copies[i];
+					if (scope instanceof HierarchyScope) {
+						if (!((HierarchyScope)scope).encloses(workingCopy, progressMonitor)) continue;
+					} else {
+						if (!scope.encloses(workingCopy)) continue;
+					}
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							IJavaElement parent = type.getParent();
+							char[][] enclosingTypeNames;
+							if (parent instanceof IType) {
+								char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
+								enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
+							} else {
+								enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+							}
+							char[] simpleName = type.getElementName().toCharArray();
+							int kind;
+							if (type.isEnum()) {
+								kind = TypeDeclaration.ENUM_DECL;
+							} else if (type.isAnnotation()) {
+								kind = TypeDeclaration.ANNOTATION_TYPE_DECL;
+							}	else if (type.isClass()) {
+								kind = TypeDeclaration.CLASS_DECL;
+							} else /*if (type.isInterface())*/ {
+								kind = TypeDeclaration.INTERFACE_DECL;
+							}
+							if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, kind, packageDeclaration, simpleName)) {
+								if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+									((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, type.getFlags()));
+								} else {
+									nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+								}
+							}
+						}
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllTypeDeclarationsVisitor extends ASTVisitor {
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; // no local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
+									if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) {
+										if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+											IType type = workingCopy.getType(new String(typeName));
+											((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, typeDeclaration.modifiers));
+										} else {
+											nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
+										}
+									}
+									return true;
+								}
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+									if (match(typeSuffix, packageName, packageMatchRule, typeName, validatedTypeMatchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) {
+										// compute enclosing type names
+										TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
+										char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+										while (enclosing != null) {
+											enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+											if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+												enclosing = enclosing.enclosingType;
+											} else {
+												enclosing = null;
+											}
+										}
+										// report
+										if (nameRequestor instanceof TypeNameMatchRequestorWrapper) {
+											IType type = workingCopy.getType(new String(enclosingTypeNames[0]));
+											for (int j=1, l=enclosingTypeNames.length; j<l; j++) {
+												type = type.getType(new String(enclosingTypeNames[j]));
+											}
+											((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, 0));
+										} else {
+											nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+										}
+									}
+									return true;
+								}
+							}
+							parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
+						}
+					}
+					if (progressMonitor != null) {
+						if (progressMonitor.isCanceled()) throw new OperationCanceledException();
+						progressMonitor.worked(1);
+					}
+				}
+			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
+		}
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope using  a case sensitive exact match
+	 * with the given qualified names and type names.
+	 *
+	 * @see SearchEngine#searchAllTypeNames(char[][], char[][], IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void searchAllTypeNames(
+		final char[][] qualifications,
+		final char[][] typeNames,
+		final int matchRule,
+		int searchFor,
+		IJavaSearchScope scope,
+		final IRestrictedAccessTypeRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		// Debug
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+			Util.verbose("	- package name: "+(qualifications==null?"null":new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- type name: "+(typeNames==null?"null":new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+			Util.verbose("	- match rule: "+getMatchRuleString(matchRule)); //$NON-NLS-1$
+			Util.verbose("	- search for: "+searchFor); //$NON-NLS-1$
+			Util.verbose("	- scope: "+scope); //$NON-NLS-1$
+		}
+		IndexManager indexManager = JavaModelManager.getIndexManager();
+
+		// Create pattern
+		final char typeSuffix;
+		switch(searchFor){
+			case IJavaSearchConstants.CLASS :
+				typeSuffix = IIndexConstants.CLASS_SUFFIX;
+				break;
+			case IJavaSearchConstants.CLASS_AND_INTERFACE :
+				typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+				break;
+			case IJavaSearchConstants.CLASS_AND_ENUM :
+				typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+				break;
+			case IJavaSearchConstants.INTERFACE :
+				typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
+				break;
+			case IJavaSearchConstants.INTERFACE_AND_ANNOTATION :
+				typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX;
+				break;
+			case IJavaSearchConstants.ENUM :
+				typeSuffix = IIndexConstants.ENUM_SUFFIX;
+				break;
+			case IJavaSearchConstants.ANNOTATION_TYPE :
+				typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+				break;
+			default :
+				typeSuffix = IIndexConstants.TYPE_SUFFIX;
+				break;
+		}
+		final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule);
+
+		// Get working copy path(s). Store in a single string in case of only one to optimize comparison in requestor
+		final HashSet workingCopyPaths = new HashSet();
+		String workingCopyPath = null;
+		ICompilationUnit[] copies = getWorkingCopies();
+		final int copiesLength = copies == null ? 0 : copies.length;
+		if (copies != null) {
+			if (copiesLength == 1) {
+				workingCopyPath = copies[0].getPath().toString();
+			} else {
+				for (int i = 0; i < copiesLength; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					workingCopyPaths.add(workingCopy.getPath().toString());
+				}
+			}
+		}
+		final String singleWkcpPath = workingCopyPath;
+
+		// Index requestor
+		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+				// Filter unexpected types
+				QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord;
+				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
+					return true; // filter out local and anonymous classes
+				}
+				switch (copiesLength) {
+					case 0:
+						break;
+					case 1:
+						if (singleWkcpPath.equals(documentPath)) {
+							return true; // filter out *the* working copy
+						}
+						break;
+					default:
+						if (workingCopyPaths.contains(documentPath)) {
+							return true; // filter out working copies
+						}
+						break;
+				}
+
+				// Accept document path
+				AccessRestriction accessRestriction = null;
+				if (access != null) {
+					// Compute document relative path
+					int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1;
+					int nameLength = record.simpleName == null ? 0 : record.simpleName.length;
+					char[] path = new char[qualificationLength + nameLength];
+					int pos = 0;
+					if (qualificationLength > 0) {
+						System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
+						CharOperation.replace(path, '.', '/');
+						path[qualificationLength-1] = '/';
+						pos += qualificationLength;
+					}
+					if (nameLength > 0) {
+						System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+						pos += nameLength;
+					}
+					// Update access restriction if path is not empty
+					if (pos > 0) {
+						accessRestriction = access.getViolatedRestriction(path);
+					}
+				}
+				nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+				return true;
+			}
+		};
+
+		try {
+			if (progressMonitor != null) {
+				progressMonitor.beginTask(Messages.engine_searching, 100);
+			}
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern,
+					getDefaultSearchParticipant(), // Java search only
+					scope,
+					searchRequestor),
+				waitingPolicy,
+				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
+
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0, length = copies.length; i < length; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							IJavaElement parent = type.getParent();
+							char[][] enclosingTypeNames;
+							char[] qualification = packageDeclaration;
+							if (parent instanceof IType) {
+								char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
+								enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
+								qualification = CharOperation.concat(qualification, parentQualifiedName);
+							} else {
+								enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+							}
+							char[] simpleName = type.getElementName().toCharArray();
+							char suffix = IIndexConstants.TYPE_SUFFIX;
+							if (type.isClass()) {
+								suffix = IIndexConstants.CLASS_SUFFIX;
+							} else if (type.isInterface()) {
+								suffix = IIndexConstants.INTERFACE_SUFFIX;
+							} else if (type.isEnum()) {
+								suffix = IIndexConstants.ENUM_SUFFIX;
+							} else if (type.isAnnotation()) {
+								suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+							}
+							if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) {
+								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+							}
+						}
+					} else {
+						Parser basicParser = getParser();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy;
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null
+								? CharOperation.NO_CHAR
+								: CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllTypeDeclarationsVisitor extends ASTVisitor {
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; // no local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
+									}
+									return true;
+								}
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+									// compute enclosing type names
+									char[] qualification = packageDeclaration;
+									TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
+									char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+									while (enclosing != null) {
+										qualification = CharOperation.concat(qualification, enclosing.name, '.');
+										enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+										if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
+											enclosing = enclosing.enclosingType;
+										} else {
+											enclosing = null;
+										}
+									}
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+									}
+									return true;
+								}
+							}
+							parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
+						}
+					}
+				}
+			}
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
+		}
+	}
+
+	public void searchDeclarations(IJavaElement enclosingElement, SearchRequestor requestor, SearchPattern pattern, IProgressMonitor monitor) throws JavaModelException {
+		if (VERBOSE) {
+			Util.verbose("	- java element: "+enclosingElement); //$NON-NLS-1$
+		}
+		IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement});
+		IResource resource = ((JavaElement) enclosingElement).resource();
+		if (enclosingElement instanceof IMember) {
+			IMember member = (IMember) enclosingElement;
+			ICompilationUnit cu = member.getCompilationUnit();
+			if (cu != null) {
+				resource = cu.getResource();
+			} else if (member.isBinary()) {
+				// binary member resource cannot be used as this
+				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=148215
+				resource = null;
+			}
+		}
+		try {
+			if (resource instanceof IFile) {
+				try {
+					requestor.beginReporting();
+					if (VERBOSE) {
+						Util.verbose("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
+					}
+					SearchParticipant participant = getDefaultSearchParticipant();
+					SearchDocument[] documents = MatchLocator.addWorkingCopies(
+						pattern,
+						new SearchDocument[] {new JavaSearchDocument(enclosingElement.getPath().toString(), participant)},
+						getWorkingCopies(enclosingElement),
+						participant);
+					participant.locateMatches(
+						documents,
+						pattern,
+						scope,
+						requestor,
+						monitor);
+				} finally {
+					requestor.endReporting();
+				}
+			} else {
+				search(
+					pattern,
+					new SearchParticipant[] {getDefaultSearchParticipant()},
+					scope,
+					requestor,
+					monitor);
+			}
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException)
+				throw (JavaModelException) e;
+			throw new JavaModelException(e);
+		}
+	}
+
+	/**
+	 * Searches for all declarations of the fields accessed in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the field declarations using the given requestor.
+	 *
+	 * @see SearchEngine#searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void searchDeclarationsOfAccessedFields(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+		}
+		// Do not accept other kind of element type than those specified in the spec
+		switch (enclosingElement.getElementType()) {
+			case IJavaElement.FIELD:
+			case IJavaElement.METHOD:
+			case IJavaElement.TYPE:
+			case IJavaElement.COMPILATION_UNIT:
+				// valid element type
+				break;
+			default:
+				throw new IllegalArgumentException();
+		}
+		SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement);
+		searchDeclarations(enclosingElement, requestor, pattern, monitor);
+	}
+
+	/**
+	 * Searches for all declarations of the types referenced in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the type declarations using the given requestor.
+	 *
+	 * @see SearchEngine#searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void searchDeclarationsOfReferencedTypes(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+		}
+		// Do not accept other kind of element type than those specified in the spec
+		switch (enclosingElement.getElementType()) {
+			case IJavaElement.FIELD:
+			case IJavaElement.METHOD:
+			case IJavaElement.TYPE:
+			case IJavaElement.COMPILATION_UNIT:
+				// valid element type
+				break;
+			default:
+				throw new IllegalArgumentException();
+		}
+		SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement);
+		searchDeclarations(enclosingElement, requestor, pattern, monitor);
+	}
+
+	/**
+	 * Searches for all declarations of the methods invoked in the given element.
+	 * The element can be a compilation unit or a source type/method/field.
+	 * Reports the method declarations using the given requestor.
+	 *
+	 * @see SearchEngine#searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, IProgressMonitor)
+	 * 	for detailed comment
+	 */
+	public void searchDeclarationsOfSentMessages(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+		if (VERBOSE) {
+			Util.verbose("BasicSearchEngine.searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+		}
+		// Do not accept other kind of element type than those specified in the spec
+		switch (enclosingElement.getElementType()) {
+			case IJavaElement.FIELD:
+			case IJavaElement.METHOD:
+			case IJavaElement.TYPE:
+			case IJavaElement.COMPILATION_UNIT:
+				// valid element type
+				break;
+			default:
+				throw new IllegalArgumentException();
+		}
+		SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement);
+		searchDeclarations(enclosingElement, requestor, pattern, monitor);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java
new file mode 100644
index 0000000..6224c5b
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contributions for bug 215139 and bug 295894
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
+
+/**
+ * Scope limited to the subtype and supertype hierarchy of a given type.
+ */
+public class HierarchyScope extends AbstractSearchScope implements SuffixConstants {
+
+	public IType focusType;
+	private String focusPath;
+	private WorkingCopyOwner owner;
+
+	private ITypeHierarchy hierarchy;
+	private HashSet resourcePaths;
+	private IPath[] enclosingProjectsAndJars;
+
+	protected IResource[] elements;
+	protected int elementCount;
+
+	public boolean needsRefresh;
+
+	private HashSet subTypes = null; // null means: don't filter for subTypes
+	private IJavaProject javaProject = null; // null means: don't constrain the search to a project
+	private boolean allowMemberAndEnclosingTypes = true;
+	private boolean includeFocusType = true;
+
+	/* (non-Javadoc)
+	 * Adds the given resource to this search scope.
+	 */
+	public void add(IResource element) {
+		if (this.elementCount == this.elements.length) {
+			System.arraycopy(
+				this.elements,
+				0,
+				this.elements = new IResource[this.elementCount * 2],
+				0,
+				this.elementCount);
+		}
+		this.elements[this.elementCount++] = element;
+	}
+
+	/**
+	 * Creates a new hierarchy scope for the given type with the given configuration options.
+	 * @param project      constrain the search result to this project, 
+	 *                     or <code>null</code> if search should consider all types in the workspace 
+	 * @param type         the focus type of the hierarchy
+	 * @param owner 	   the owner of working copies that take precedence over original compilation units, 
+	 *                     or <code>null</code> if the primary working copy owner should be used
+	 * @param onlySubtypes if true search only subtypes of 'type'
+	 * @param noMembersOrEnclosingTypes if true the hierarchy is strict, 
+	 * 					   i.e., no additional member types or enclosing types of types spanning the hierarchy are included,
+	 * 					   otherwise all member and enclosing types of types in the hierarchy are included.
+	 * @param includeFocusType if true the focus type <code>type</code> is included in the resulting scope, otherwise it is excluded
+	 */
+	public HierarchyScope(IJavaProject project, IType type, WorkingCopyOwner owner, boolean onlySubtypes, boolean noMembersOrEnclosingTypes, boolean includeFocusType) throws JavaModelException {
+		this(type, owner);
+		this.javaProject = project;
+		if (onlySubtypes) {
+			this.subTypes = new HashSet();
+		}
+		this.includeFocusType = includeFocusType;
+		this.allowMemberAndEnclosingTypes = !noMembersOrEnclosingTypes;
+	}
+
+	/* (non-Javadoc)
+	 * Creates a new hiearchy scope for the given type.
+	 */
+	public HierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException {
+		this.focusType = type;
+		this.owner = owner;
+
+		this.enclosingProjectsAndJars = computeProjectsAndJars(type);
+
+		// resource path
+		IPackageFragmentRoot root = (IPackageFragmentRoot)type.getPackageFragment().getParent();
+		if (root.isArchive()) {
+			IPath jarPath = root.getPath();
+			Object target = JavaModel.getTarget(jarPath, true);
+			String zipFileName;
+			if (target instanceof IFile) {
+				// internal jar
+				zipFileName = jarPath.toString();
+			} else if (target instanceof File) {
+				// external jar
+				zipFileName = ((File)target).getPath();
+			} else {
+				return; // unknown target
+			}
+			this.focusPath =
+				zipFileName
+					+ JAR_FILE_ENTRY_SEPARATOR
+					+ type.getFullyQualifiedName().replace('.', '/')
+					+ SUFFIX_STRING_class;
+		} else {
+			this.focusPath = type.getPath().toString();
+		}
+
+		this.needsRefresh = true;
+
+		//disabled for now as this could be expensive
+		//JavaModelManager.getJavaModelManager().rememberScope(this);
+	}
+	private void buildResourceVector() {
+		HashMap resources = new HashMap();
+		HashMap paths = new HashMap();
+		IType[] types = null;
+		if (this.subTypes != null) {
+			types = this.hierarchy.getAllSubtypes(this.focusType);
+			if (this.includeFocusType) {
+				int len = types.length;
+				System.arraycopy(types, 0, types=new IType[len+1], 0, len);
+				types[len] = this.focusType;
+			}
+		} else {
+			types = this.hierarchy.getAllTypes();
+		}
+		for (int i = 0; i < types.length; i++) {
+			IType type = types[i];
+			if (this.subTypes != null) {
+				// remember subtypes for later use in encloses()
+				this.subTypes.add(type);
+			}
+			IResource resource = ((JavaElement)type).resource();
+			if (resource != null && resources.get(resource) == null) {
+				resources.put(resource, resource);
+				add(resource);
+			}
+			IPackageFragmentRoot root =
+				(IPackageFragmentRoot) type.getPackageFragment().getParent();
+			if (root instanceof JarPackageFragmentRoot) {
+				// type in a jar
+				JarPackageFragmentRoot jar = (JarPackageFragmentRoot) root;
+				IPath jarPath = jar.getPath();
+				Object target = JavaModel.getTarget(jarPath, true);
+				String zipFileName;
+				if (target instanceof IFile) {
+					// internal jar
+					zipFileName = jarPath.toString();
+				} else if (target instanceof File) {
+					// external jar
+					zipFileName = ((File)target).getPath();
+				} else {
+					continue; // unknown target
+				}
+				String resourcePath =
+					zipFileName
+						+ JAR_FILE_ENTRY_SEPARATOR
+						+ type.getFullyQualifiedName().replace('.', '/')
+						+ SUFFIX_STRING_class;
+
+				this.resourcePaths.add(resourcePath);
+				paths.put(jarPath, type);
+			} else {
+				// type is a project
+				paths.put(type.getJavaProject().getProject().getFullPath(), type);
+			}
+		}
+		this.enclosingProjectsAndJars = new IPath[paths.size()];
+		int i = 0;
+		for (Iterator iter = paths.keySet().iterator(); iter.hasNext();) {
+			this.enclosingProjectsAndJars[i++] = (IPath) iter.next();
+		}
+	}
+	/*
+	 * Computes the paths of projects and jars that the hierarchy on the given type could contain.
+	 * This is a super set of the project and jar paths once the hierarchy is computed.
+	 */
+	private IPath[] computeProjectsAndJars(IType type) throws JavaModelException {
+		HashSet set = new HashSet();
+		IPackageFragmentRoot root = (IPackageFragmentRoot)type.getPackageFragment().getParent();
+		if (root.isArchive()) {
+			// add the root
+			set.add(root.getPath());
+			// add all projects that reference this archive and their dependents
+			IPath rootPath = root.getPath();
+			IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+			IJavaProject[] projects = model.getJavaProjects();
+			HashSet visited = new HashSet();
+			for (int i = 0; i < projects.length; i++) {
+				JavaProject project = (JavaProject) projects[i];
+				IClasspathEntry entry = project.getClasspathEntryFor(rootPath);
+				if (entry != null) {
+					// add the project and its binary pkg fragment roots
+					IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
+					set.add(project.getPath());
+					for (int k = 0; k < roots.length; k++) {
+						IPackageFragmentRoot pkgFragmentRoot = roots[k];
+						if (pkgFragmentRoot.getKind() == IPackageFragmentRoot.K_BINARY) {
+							set.add(pkgFragmentRoot.getPath());
+						}
+					}
+					// add the dependent projects
+					computeDependents(project, set, visited);
+				}
+			}
+		} else {
+			// add all the project's pkg fragment roots
+			IJavaProject project = (IJavaProject)root.getParent();
+			IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
+			for (int i = 0; i < roots.length; i++) {
+				IPackageFragmentRoot pkgFragmentRoot = roots[i];
+				if (pkgFragmentRoot.getKind() == IPackageFragmentRoot.K_BINARY) {
+					set.add(pkgFragmentRoot.getPath());
+				} else {
+					set.add(pkgFragmentRoot.getParent().getPath());
+				}
+			}
+			// add the dependent projects
+			computeDependents(project, set, new HashSet());
+		}
+		IPath[] result = new IPath[set.size()];
+		set.toArray(result);
+		return result;
+	}
+	private void computeDependents(IJavaProject project, HashSet set, HashSet visited) {
+		if (visited.contains(project)) return;
+		visited.add(project);
+		IProject[] dependents = project.getProject().getReferencingProjects();
+		for (int i = 0; i < dependents.length; i++) {
+			try {
+				IJavaProject dependent = JavaCore.create(dependents[i]);
+				IPackageFragmentRoot[] roots = dependent.getPackageFragmentRoots();
+				set.add(dependent.getPath());
+				for (int j = 0; j < roots.length; j++) {
+					IPackageFragmentRoot pkgFragmentRoot = roots[j];
+					if (pkgFragmentRoot.isArchive()) {
+						set.add(pkgFragmentRoot.getPath());
+					}
+				}
+				computeDependents(dependent, set, visited);
+			} catch (JavaModelException e) {
+				// project is not a java project
+			}
+		}
+	}
+	/* (non-Javadoc)
+	 * @see IJavaSearchScope#encloses(String)
+	 */
+	public boolean encloses(String resourcePath) {
+		return encloses(resourcePath, null);
+	}
+	public boolean encloses(String resourcePath, IProgressMonitor progressMonitor) {
+		if (this.hierarchy == null) {
+			if (resourcePath.equals(this.focusPath)) {
+				return true;
+			} else {
+				if (this.needsRefresh) {
+					try {
+						initialize(progressMonitor);
+					} catch (JavaModelException e) {
+						return false;
+					}
+				} else {
+					// the scope is used only to find enclosing projects and jars
+					// clients is responsible for filtering out elements not in the hierarchy (see SearchEngine)
+					return true;
+				}
+			}
+		}
+		if (this.needsRefresh) {
+			try {
+				refresh(progressMonitor);
+			} catch(JavaModelException e) {
+				return false;
+			}
+		}
+		int separatorIndex = resourcePath.indexOf(JAR_FILE_ENTRY_SEPARATOR);
+		if (separatorIndex != -1) {
+			return this.resourcePaths.contains(resourcePath);
+		} else {
+			for (int i = 0; i < this.elementCount; i++) {
+				if (resourcePath.startsWith(this.elements[i].getFullPath().toString())) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+	/** 
+	 * Optionally perform additional checks after element has already passed matching based on index/documents.
+	 * 
+	 * @param element the given element
+	 * @return <code>true</code> if the element is enclosed or if no fine grained checking 
+	 *         (regarding subtypes and members) is requested
+	 */
+	public boolean enclosesFineGrained(IJavaElement element) {
+		if ((this.subTypes == null) && this.allowMemberAndEnclosingTypes) 
+			return true; // no fine grained checking requested
+		return encloses(element, null);
+	}
+	/* (non-Javadoc)
+	 * @see IJavaSearchScope#encloses(IJavaElement)
+	 */
+	public boolean encloses(IJavaElement element) {
+		return encloses(element, null);
+	}
+	public boolean encloses(IJavaElement element, IProgressMonitor progressMonitor) {
+		if (this.hierarchy == null) {
+			if (this.includeFocusType && this.focusType.equals(element.getAncestor(IJavaElement.TYPE))) {
+				return true;
+			} else {
+				if (this.needsRefresh) {
+					try {
+						initialize(progressMonitor);
+					} catch (JavaModelException e) {
+						return false;
+					}
+				} else {
+					// the scope is used only to find enclosing projects and jars
+					// clients is responsible for filtering out elements not in the hierarchy (see SearchEngine)
+					return true;
+				}
+			}
+		}
+		if (this.needsRefresh) {
+			try {
+				refresh(progressMonitor);
+			} catch(JavaModelException e) {
+				return false;
+			}
+		}
+		IType type = null;
+		if (element instanceof IType) {
+			type = (IType) element;
+		} else if (element instanceof IMember) {
+			type = ((IMember) element).getDeclaringType();
+		}
+		if (type != null) {
+			if (this.focusType.equals(type))
+				return this.includeFocusType;
+			// potentially allow travelling in:
+			if (enclosesType(type, this.allowMemberAndEnclosingTypes)) {
+				return true;
+			}
+			if (this.allowMemberAndEnclosingTypes) {
+				// travel out: queried type is enclosed in this scope if its (indirect) declaring type is:
+				IType enclosing = type.getDeclaringType();
+				while (enclosing != null) {
+					// don't allow travelling in again:
+					if (enclosesType(enclosing, false)) {
+						return true;
+					}
+					enclosing = enclosing.getDeclaringType();
+				}
+			}
+		}
+		return false;
+	}
+	private boolean enclosesType(IType type, boolean recurse) {
+		if (this.subTypes != null) {
+			// searching subtypes
+			if (this.subTypes.contains(type)) {
+				return true;
+			}
+			// be flexible: look at original element (see bug 14106 and below)
+			IType original = type.isBinary() ? null : (IType)type.getPrimaryElement();
+			if (original != type && this.subTypes.contains(original)) {
+				return true;
+			}
+		} else {
+			if (this.hierarchy.contains(type)) {
+				return true;
+			} else {
+				// be flexible: look at original element (see bug 14106 Declarations in Hierarchy does not find declarations in hierarchy)
+				IType original;
+				if (!type.isBinary()
+						&& (original = (IType)type.getPrimaryElement()) != null) {
+					if (this.hierarchy.contains(original)) {
+						return true;
+					}
+				}
+			}
+		}
+		if (recurse) {
+			// queried type is enclosed in this scope if one of its members is:
+			try {
+				IType[] memberTypes = type.getTypes();
+				for (int i = 0; i < memberTypes.length; i++) {
+					if (enclosesType(memberTypes[i], recurse)) {
+						return true;
+					}
+				}
+			} catch (JavaModelException e) {
+				return false;
+			}
+		}
+		return false;
+	}
+	/* (non-Javadoc)
+	 * @see IJavaSearchScope#enclosingProjectsAndJars()
+	 * @deprecated
+	 */
+	public IPath[] enclosingProjectsAndJars() {
+		if (this.needsRefresh) {
+			try {
+				refresh(null);
+			} catch(JavaModelException e) {
+				return new IPath[0];
+			}
+		}
+		return this.enclosingProjectsAndJars;
+	}
+	protected void initialize() throws JavaModelException {
+		initialize(null);
+	}
+	protected void initialize(IProgressMonitor progressMonitor) throws JavaModelException {
+		this.resourcePaths = new HashSet();
+		this.elements = new IResource[5];
+		this.elementCount = 0;
+		this.needsRefresh = false;
+		if (this.hierarchy == null) {
+			if (this.javaProject != null) {
+				this.hierarchy = this.focusType.newTypeHierarchy(this.javaProject, this.owner, progressMonitor);
+			} else {
+				this.hierarchy = this.focusType.newTypeHierarchy(this.owner, progressMonitor);
+			}
+		} else {
+			this.hierarchy.refresh(progressMonitor);
+		}
+		buildResourceVector();
+	}
+	/*
+	 * @see AbstractSearchScope#processDelta(IJavaElementDelta)
+	 */
+	public void processDelta(IJavaElementDelta delta, int eventType) {
+		if (this.needsRefresh) return;
+		this.needsRefresh = this.hierarchy == null ? false : ((TypeHierarchy)this.hierarchy).isAffected(delta, eventType);
+	}
+	protected void refresh() throws JavaModelException {
+		refresh(null);
+	}
+	protected void refresh(IProgressMonitor progressMonitor) throws JavaModelException {
+		if (this.hierarchy != null) {
+			initialize(progressMonitor);
+		}
+	}
+	public String toString() {
+		return "HierarchyScope on " + ((JavaElement)this.focusType).toStringWithAncestors(); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java
new file mode 100644
index 0000000..15d2011
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessConstructorRequestor.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * A <code>IRestrictedAccessConstructorRequestor</code> collects search results from a <code>searchAllConstructorDeclarations</code>
+ * query to a <code>SearchBasicEngine</code> providing restricted access information of declaring type when a constructor is accepted.
+ */
+public interface IRestrictedAccessConstructorRequestor {
+
+	public void acceptConstructor(
+			int modifiers,
+			char[] simpleTypeName,
+			int parameterCount,
+			char[] signature,
+			char[][] parameterTypes,
+			char[][] parameterNames,
+			int typeModifiers,
+			char[] packageName,
+			int extraFlags,
+			String path,
+			AccessRestriction access);
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java
new file mode 100644
index 0000000..aa1041c
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * A <code>IRestrictedAccessTypeRequestor</code> collects search results from a <code>searchAllTypeNames</code>
+ * query to a <code>SearchBasicEngine</code> providing restricted access information when a type is accepted.
+ * @see org.eclipse.jdt.core.search.TypeNameRequestor
+ */
+public interface IRestrictedAccessTypeRequestor {
+
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java
new file mode 100644
index 0000000..5e71480
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+
+/**
+ * TODO add spec
+ */
+public abstract class IndexQueryRequestor {
+
+	// answer false if requesting cancel
+	public abstract boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access);
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
new file mode 100644
index 0000000..20990c9
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
@@ -0,0 +1,316 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nikolay Botev - Bug 348507
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.util.LinkedHashSet;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.builder.ReferenceCollection;
+import org.eclipse.jdt.internal.core.builder.State;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+import org.eclipse.jdt.internal.core.search.matching.MethodPattern;
+
+/**
+ * Selects the indexes that correspond to projects in a given search scope
+ * and that are dependent on a given focus element.
+ */
+public class IndexSelector {
+	IJavaSearchScope searchScope;
+	SearchPattern pattern;
+	IndexLocation[] indexLocations; // cache of the keys for looking index up
+
+public IndexSelector(
+		IJavaSearchScope searchScope,
+		SearchPattern pattern) {
+
+	this.searchScope = searchScope;
+	this.pattern = pattern;
+}
+/**
+ * Returns whether elements of the given project or jar can see the given focus (an IJavaProject or
+ * a JarPackageFragmentRot) either because the focus is part of the project or the jar, or because it is
+ * accessible throught the project's classpath
+ */
+public static boolean canSeeFocus(SearchPattern pattern, IPath projectOrJarPath) {
+	try {
+		IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+		IJavaProject project = getJavaProject(projectOrJarPath, model);
+		IJavaElement[] focuses = getFocusedElementsAndTypes(pattern, project, null);
+		if (focuses.length == 0) return false;
+		if (project != null) {
+			return canSeeFocus(focuses, (JavaProject) project, null);
+		}
+
+		// projectOrJarPath is a jar
+		// it can see the focus only if it is on the classpath of a project that can see the focus
+		IJavaProject[] allProjects = model.getJavaProjects();
+		for (int i = 0, length = allProjects.length; i < length; i++) {
+			JavaProject otherProject = (JavaProject) allProjects[i];
+			IClasspathEntry entry = otherProject.getClasspathEntryFor(projectOrJarPath);
+			if (entry != null && entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+				if (canSeeFocus(focuses, otherProject, null)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	} catch (JavaModelException e) {
+		return false;
+	}
+}
+private static boolean canSeeFocus(IJavaElement[] focuses, JavaProject javaProject, char[][][] focusQualifiedNames) {
+	int length = focuses.length;
+	for (int i=0; i<length; i++) {
+		if (canSeeFocus(focuses[i], javaProject, focusQualifiedNames)) return true;
+	}
+	return false;
+}
+private static boolean canSeeFocus(IJavaElement focus, JavaProject javaProject, char[][][] focusQualifiedNames) {
+	try {
+		if (focus == null) return false;
+		if (focus.equals(javaProject)) return true;
+
+		if (focus instanceof JarPackageFragmentRoot) {
+			// focus is part of a jar
+			IPath focusPath = focus.getPath();
+			IClasspathEntry[] entries = javaProject.getExpandedClasspath();
+			for (int i = 0, length = entries.length; i < length; i++) {
+				IClasspathEntry entry = entries[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(focusPath))
+					return true;
+			}
+			return false;
+		}
+		// look for dependent projects
+		IPath focusPath = ((JavaProject) focus).getProject().getFullPath();
+		IClasspathEntry[] entries = javaProject.getExpandedClasspath();
+		for (int i = 0, length = entries.length; i < length; i++) {
+			IClasspathEntry entry = entries[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(focusPath)) {
+				if (focusQualifiedNames != null) { // builder state is usable, hence use it to try to reduce project which can see the focus...
+					State projectState = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(javaProject.getProject(), null);
+					if (projectState != null) {
+						Object[] values = projectState.getReferences().valueTable;
+						int vLength = values.length;
+						for (int j=0; j<vLength; j++)  {
+							if (values[j] == null) continue;
+							ReferenceCollection references = (ReferenceCollection) values[j];
+							if (references.includes(focusQualifiedNames, null, null)) {
+								return true;
+							}
+						}
+						return false;
+					}
+				}
+				return true;
+			}
+		}
+		return false;
+	} catch (JavaModelException e) {
+		return false;
+	}
+}
+
+/*
+ * Create the list of focused jars or projects.
+ */
+private static IJavaElement[] getFocusedElementsAndTypes(SearchPattern pattern, IJavaElement focusElement, ObjectVector superTypes) throws JavaModelException {
+	if (pattern instanceof MethodPattern) {
+		// For method pattern, it needs to walk along the focus type super hierarchy
+		// and add jars/projects of all the encountered types.
+		IType type = (IType) pattern.focus.getAncestor(IJavaElement.TYPE);
+		MethodPattern methodPattern = (MethodPattern) pattern;
+		String selector = new String(methodPattern.selector);
+		int parameterCount = methodPattern.parameterCount;
+		ITypeHierarchy superHierarchy = type.newSupertypeHierarchy(null);
+		IType[] allTypes = superHierarchy.getAllSupertypes(type);
+		int length = allTypes.length;
+		SimpleSet focusSet = new SimpleSet(length+1);
+		if (focusElement != null) focusSet.add(focusElement);
+		for (int i=0; i<length; i++) {
+			IMethod[] methods = allTypes[i].getMethods();
+			int mLength = methods.length;
+			for (int m=0; m<mLength; m++) {
+				if (parameterCount == methods[m].getNumberOfParameters() && methods[m].getElementName().equals(selector)) {
+					IPackageFragmentRoot root = (IPackageFragmentRoot) allTypes[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+					IJavaElement element = root.isArchive() ? root : root.getParent();
+					focusSet.add(element);
+					if (superTypes != null) superTypes.add(allTypes[i]);
+					break;
+				}
+			}
+		}
+		// Rebuilt a contiguous array
+		IJavaElement[] focuses = new IJavaElement[focusSet.elementSize];
+		Object[] values = focusSet.values;
+		int count = 0;
+		for (int i = values.length; --i >= 0;) {
+			if (values[i] != null) {
+				focuses[count++] = (IJavaElement) values[i];
+			}
+		}
+		return focuses;
+	}
+	if (focusElement == null) return new IJavaElement[0];
+	return new IJavaElement[] { focusElement };
+}
+
+/*
+ *  Compute the list of paths which are keying index files.
+ */
+private void initializeIndexLocations() {
+	IPath[] projectsAndJars = this.searchScope.enclosingProjectsAndJars();
+	IndexManager manager = JavaModelManager.getIndexManager();
+	// use a linked set to preserve the order during search: see bug 348507
+	LinkedHashSet locations = new LinkedHashSet();
+	IJavaElement focus = MatchLocator.projectOrJarFocus(this.pattern);
+	if (focus == null) {
+		for (int i = 0; i < projectsAndJars.length; i++) {
+			IPath path = projectsAndJars[i];
+			Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+			if (target instanceof IFolder) // case of an external folder
+				path = ((IFolder) target).getFullPath();
+			locations.add(manager.computeIndexLocation(path));
+		}
+	} else {
+		try {
+			// See whether the state builder might be used to reduce the number of index locations
+		
+			// find the projects from projectsAndJars that see the focus then walk those projects looking for the jars from projectsAndJars
+			int length = projectsAndJars.length;
+			JavaProject[] projectsCanSeeFocus = new JavaProject[length];
+			SimpleSet visitedProjects = new SimpleSet(length);
+			int projectIndex = 0;
+			SimpleSet externalLibsToCheck = new SimpleSet(length);
+			ObjectVector superTypes = new ObjectVector();
+			IJavaElement[] focuses = getFocusedElementsAndTypes(this.pattern, focus, superTypes);
+			char[][][] focusQualifiedNames = null;
+			boolean isAutoBuilding = ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding();
+			if (isAutoBuilding && focus instanceof IJavaProject) {
+				focusQualifiedNames = getQualifiedNames(superTypes);
+			}
+			IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+			for (int i = 0; i < length; i++) {
+				IPath path = projectsAndJars[i];
+				JavaProject project = (JavaProject) getJavaProject(path, model);
+				if (project != null) {
+					visitedProjects.add(project);
+					if (canSeeFocus(focuses, project, focusQualifiedNames)) {
+						locations.add(manager.computeIndexLocation(path));
+						projectsCanSeeFocus[projectIndex++] = project;
+					}
+				} else {
+					externalLibsToCheck.add(path);
+				}
+			}
+			for (int i = 0; i < projectIndex && externalLibsToCheck.elementSize > 0; i++) {
+				IClasspathEntry[] entries = projectsCanSeeFocus[i].getResolvedClasspath();
+				for (int j = entries.length; --j >= 0;) {
+					IClasspathEntry entry = entries[j];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+						IPath path = entry.getPath();
+						if (externalLibsToCheck.remove(path) != null) {
+							Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+							if (target instanceof IFolder) // case of an external folder
+								path = ((IFolder) target).getFullPath();
+							locations.add(manager.computeIndexLocation(path));
+						}
+					}
+				}
+			}
+			// jar files can be included in the search scope without including one of the projects that references them, so scan all projects that have not been visited
+			if (externalLibsToCheck.elementSize > 0) {
+				IJavaProject[] allProjects = model.getJavaProjects();
+				for (int i = 0, l = allProjects.length; i < l && externalLibsToCheck.elementSize > 0; i++) {
+					JavaProject project = (JavaProject) allProjects[i];
+					if (!visitedProjects.includes(project)) {
+						IClasspathEntry[] entries = project.getResolvedClasspath();
+						for (int j = entries.length; --j >= 0;) {
+							IClasspathEntry entry = entries[j];
+							if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+								IPath path = entry.getPath();
+								if (externalLibsToCheck.remove(path) != null) {
+									Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+									if (target instanceof IFolder) // case of an external folder
+										path = ((IFolder) target).getFullPath();
+									locations.add(manager.computeIndexLocation(path));
+								}
+							}
+						}
+					}
+				}
+			}
+		} catch (JavaModelException e) {
+			// ignored
+		}
+	}
+
+	locations.remove(null); // Ensure no nulls
+	this.indexLocations = (IndexLocation[]) locations.toArray(new IndexLocation[locations.size()]);
+}
+
+public IndexLocation[] getIndexLocations() {
+	if (this.indexLocations == null) {
+		initializeIndexLocations();
+	}
+	return this.indexLocations;
+}
+
+/**
+ * Returns the java project that corresponds to the given path.
+ * Returns null if the path doesn't correspond to a project.
+ */
+private static IJavaProject getJavaProject(IPath path, IJavaModel model) {
+	IJavaProject project = model.getJavaProject(path.lastSegment());
+	if (project.exists()) {
+		return project;
+	}
+	return null;
+}
+
+private char[][][] getQualifiedNames(ObjectVector types) {
+	final int size = types.size;
+	char[][][] focusQualifiedNames = null;
+	IJavaElement javaElement = this.pattern.focus;
+	int index = 0;
+	while (javaElement != null && !(javaElement instanceof ITypeRoot)) {
+		javaElement = javaElement.getParent();
+	}
+	if (javaElement != null) {
+		IType primaryType = ((ITypeRoot) javaElement).findPrimaryType();
+		if (primaryType != null) {
+			focusQualifiedNames = new char[size+1][][];
+			focusQualifiedNames[index++] = CharOperation.splitOn('.', primaryType.getFullyQualifiedName().toCharArray());
+		} 
+	}
+	if (focusQualifiedNames == null) {
+		focusQualifiedNames = new char[size][][];
+	}
+	for (int i = 0; i < size; i++) {
+		focusQualifiedNames[index++] = CharOperation.splitOn('.', ((IType)(types.elementAt(i))).getFullyQualifiedName().toCharArray());
+	}
+	return focusQualifiedNames.length == 0 ? null : ReferenceCollection.internQualifiedNames(focusQualifiedNames, true);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java
new file mode 100644
index 0000000..f5f3311
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class JavaSearchDocument extends SearchDocument {
+
+	private IFile file;
+	protected byte[] byteContents;
+	protected char[] charContents;
+
+	public JavaSearchDocument(String documentPath, SearchParticipant participant) {
+		super(documentPath, participant);
+	}
+	public JavaSearchDocument(java.util.zip.ZipEntry zipEntry, IPath zipFilePath, byte[] contents, SearchParticipant participant) {
+		super(zipFilePath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + zipEntry.getName(), participant);
+		this.byteContents = contents;
+	}
+
+	public byte[] getByteContents() {
+		if (this.byteContents != null) return this.byteContents;
+		try {
+			return Util.getResourceContentsAsByteArray(getFile());
+		} catch (JavaModelException e) {
+			if (BasicSearchEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
+				e.printStackTrace();
+			}
+			return null;
+		}
+	}
+	public char[] getCharContents() {
+		if (this.charContents != null) return this.charContents;
+		try {
+			return Util.getResourceContentsAsCharArray(getFile());
+		} catch (JavaModelException e) {
+			if (BasicSearchEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
+				e.printStackTrace();
+			}
+			return null;
+		}
+	}
+	public String getEncoding() {
+		// Return the encoding of the associated file
+		IFile resource = getFile();
+		if (resource != null) {
+			try {
+				return resource.getCharset();
+			}
+			catch(CoreException ce) {
+				try {
+					return ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
+				} catch (CoreException e) {
+					// use no encoding
+				}
+			}
+		}
+		return null;
+	}
+	private IFile getFile() {
+		if (this.file == null)
+			this.file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(getPath()));
+		return this.file;
+	}
+	public String toString() {
+		return "SearchDocument for " + getPath(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java
new file mode 100644
index 0000000..cf970b3
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.indexing.BinaryIndexer;
+import org.eclipse.jdt.internal.core.search.indexing.SourceIndexer;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+
+/**
+ * A search participant describes a particular extension to a generic search mechanism, allowing thus to
+ * perform combined search actions which will involve all required participants
+ *
+ * A search scope defines which participants are involved.
+ *
+ * A search participant is responsible for holding index files, and selecting the appropriate ones to feed to
+ * index queries. It also can map a document path to an actual document (note that documents could live outside
+ * the workspace or no exist yet, and thus aren't just resources).
+ */
+public class JavaSearchParticipant extends SearchParticipant {
+
+	private ThreadLocal indexSelector = new ThreadLocal();
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#beginSearching()
+	 */
+	public void beginSearching() {
+		super.beginSearching();
+		this.indexSelector.set(null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#doneSearching()
+	 */
+	public void doneSearching() {
+		this.indexSelector.set(null);
+		super.doneSearching();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#getName()
+	 */
+	public String getDescription() {
+		return "Java"; //$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#getDocument(String)
+	 */
+	public SearchDocument getDocument(String documentPath) {
+		return new JavaSearchDocument(documentPath, this);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#indexDocument(SearchDocument)
+	 */
+	public void indexDocument(SearchDocument document, IPath indexPath) {
+		// TODO must verify that the document + indexPath match, when this is not called from scheduleDocumentIndexing
+		document.removeAllIndexEntries(); // in case the document was already indexed
+
+		String documentPath = document.getPath();
+		if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(documentPath)) {
+			new SourceIndexer(document).indexDocument();
+		} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(documentPath)) {
+			new BinaryIndexer(document).indexDocument();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see SearchParticipant#locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor)
+	 */
+	public void locateMatches(SearchDocument[] indexMatches, SearchPattern pattern,
+			IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+
+		MatchLocator matchLocator =
+			new MatchLocator(
+				pattern,
+				requestor,
+				scope,
+				monitor
+		);
+
+		/* eliminating false matches and locating them */
+		if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
+		matchLocator.locateMatches(indexMatches);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.search.SearchParticipant#selectIndexes(org.eclipse.jdt.core.search.SearchQuery, org.eclipse.jdt.core.search.SearchContext)
+	 */
+	public IPath[] selectIndexes(SearchPattern pattern, IJavaSearchScope scope) {
+		IndexSelector selector = (IndexSelector) this.indexSelector.get();
+		if (selector == null) {
+			selector = new IndexSelector(scope, pattern);
+			this.indexSelector.set(selector);
+		}
+		IndexLocation[] urls = selector.getIndexLocations();
+		IPath[] paths = new IPath[urls.length];
+		for (int i = 0; i < urls.length; i++) {
+			paths[i] = new Path(urls[i].getIndexFile().getPath());
+		}
+		return paths;
+	}
+
+	public IndexLocation[] selectIndexURLs(SearchPattern pattern, IJavaSearchScope scope) {
+		IndexSelector selector = (IndexSelector) this.indexSelector.get();
+		if (selector == null) {
+			selector = new IndexSelector(scope, pattern);
+			this.indexSelector.set(selector);
+		}
+		return selector.getIndexLocations();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
new file mode 100644
index 0000000..617d8c4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathContainer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
+import org.eclipse.jdt.internal.core.ExternalFoldersManager;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A Java-specific scope for searching relative to one or more java elements.
+ */
+public class JavaSearchScope extends AbstractJavaSearchScope {
+
+	private ArrayList elements;
+
+	/* The paths of the resources in this search scope
+	    (or the classpath entries' paths if the resources are projects)
+	*/
+	private ArrayList projectPaths = new ArrayList(); // container paths projects
+	private int[] projectIndexes; // Indexes of projects in list
+	private String[] containerPaths; // path to the container (e.g. /P/src, /P/lib.jar, c:\temp\mylib.jar)
+	private String[] relativePaths; // path relative to the container (e.g. x/y/Z.class, x/y, (empty))
+	private boolean[] isPkgPath; // in the case of packages, matches must be direct children of the folder
+	protected AccessRuleSet[] pathRestrictions;
+	private int pathsCount;
+	private int threshold;
+
+	private IPath[] enclosingProjectsAndJars;
+	public final static AccessRuleSet NOT_ENCLOSED = new AccessRuleSet(null, (byte) 0, null);
+
+public JavaSearchScope() {
+	this(5);
+}
+
+private JavaSearchScope(int size) {
+	initialize(size);
+
+	//disabled for now as this could be expensive
+	//JavaModelManager.getJavaModelManager().rememberScope(this);
+}
+
+private void addEnclosingProjectOrJar(IPath path) {
+	int length = this.enclosingProjectsAndJars.length;
+	for (int i = 0; i < length; i++) {
+		if (this.enclosingProjectsAndJars[i].equals(path)) return;
+	}
+	System.arraycopy(
+		this.enclosingProjectsAndJars,
+		0,
+		this.enclosingProjectsAndJars = new IPath[length+1],
+		0,
+		length);
+	this.enclosingProjectsAndJars[length] = path;
+}
+
+/**
+ * Add java project all fragment roots to current java search scope.
+ * @see #add(JavaProject, IPath, int, HashSet, HashSet, IClasspathEntry)
+ */
+public void add(JavaProject project, int includeMask, HashSet projectsToBeAdded) throws JavaModelException {
+	add(project, null, includeMask, projectsToBeAdded, new HashSet(2), null);
+}
+/**
+ * Add a path to current java search scope or all project fragment roots if null.
+ * Use project resolved classpath to retrieve and store access restriction on each classpath entry.
+ * Recurse if dependent projects are found.
+ * @param javaProject Project used to get resolved classpath entries
+ * @param pathToAdd Path to add in case of single element or null if user want to add all project package fragment roots
+ * @param includeMask Mask to apply on classpath entries
+ * @param projectsToBeAdded Set to avoid infinite recursion
+ * @param visitedProjects Set to avoid adding twice the same project
+ * @param referringEntry Project raw entry in referring project classpath
+ * @throws JavaModelException May happen while getting java model info
+ */
+void add(JavaProject javaProject, IPath pathToAdd, int includeMask, HashSet projectsToBeAdded, HashSet visitedProjects, IClasspathEntry referringEntry) throws JavaModelException {
+	IProject project = javaProject.getProject();
+	if (!project.isAccessible() || !visitedProjects.add(project)) return;
+
+	IPath projectPath = project.getFullPath();
+	String projectPathString = projectPath.toString();
+	addEnclosingProjectOrJar(projectPath);
+
+	IClasspathEntry[] entries = javaProject.getResolvedClasspath();
+	IJavaModel model = javaProject.getJavaModel();
+	JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
+	for (int i = 0, length = entries.length; i < length; i++) {
+		IClasspathEntry entry = entries[i];
+		AccessRuleSet access = null;
+		ClasspathEntry cpEntry = (ClasspathEntry) entry;
+		if (referringEntry != null) {
+			// Add only exported entries.
+			// Source folder are implicitly exported.
+			if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) {
+				continue;
+			}
+			cpEntry = cpEntry.combineWith((ClasspathEntry)referringEntry);
+//				cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry);
+		}
+		access = cpEntry.getAccessRuleSet();
+		switch (entry.getEntryKind()) {
+			case IClasspathEntry.CPE_LIBRARY:
+				IClasspathEntry rawEntry = null;
+				Map rootPathToRawEntries = perProjectInfo.rootPathToRawEntries;
+				if (rootPathToRawEntries != null) {
+					rawEntry = (IClasspathEntry) rootPathToRawEntries.get(entry.getPath());
+				}
+				if (rawEntry == null) break;
+				rawKind: switch (rawEntry.getEntryKind()) {
+					case IClasspathEntry.CPE_LIBRARY:
+					case IClasspathEntry.CPE_VARIABLE:
+						if ((includeMask & APPLICATION_LIBRARIES) != 0) {
+							IPath path = entry.getPath();
+							if (pathToAdd == null || pathToAdd.equals(path)) {
+								Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+								if (target instanceof IFolder) // case of an external folder
+									path = ((IFolder) target).getFullPath();
+								String pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
+								add(projectPath.toString(), "", pathToString, false/*not a package*/, access); //$NON-NLS-1$
+								addEnclosingProjectOrJar(entry.getPath());
+							}
+						}
+						break;
+					case IClasspathEntry.CPE_CONTAINER:
+						IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), javaProject);
+						if (container == null) break;
+						switch (container.getKind()) {
+							case IClasspathContainer.K_APPLICATION:
+								if ((includeMask & APPLICATION_LIBRARIES) == 0) break rawKind;
+								break;
+							case IClasspathContainer.K_SYSTEM:
+							case IClasspathContainer.K_DEFAULT_SYSTEM:
+								if ((includeMask & SYSTEM_LIBRARIES) == 0) break rawKind;
+								break;
+							default:
+								break rawKind;
+						}
+						IPath path = entry.getPath();
+						if (pathToAdd == null || pathToAdd.equals(path)) {
+							Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+							if (target instanceof IFolder) // case of an external folder
+								path = ((IFolder) target).getFullPath();
+							String pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
+							add(projectPath.toString(), "", pathToString, false/*not a package*/, access); //$NON-NLS-1$
+							addEnclosingProjectOrJar(entry.getPath());
+						}
+						break;
+				}
+				break;
+			case IClasspathEntry.CPE_PROJECT:
+				if ((includeMask & REFERENCED_PROJECTS) != 0) {
+					IPath path = entry.getPath();
+					if (pathToAdd == null || pathToAdd.equals(path)) {
+						JavaProject referencedProject = (JavaProject) model.getJavaProject(path.lastSegment());
+						if (!projectsToBeAdded.contains(referencedProject)) { // do not recurse if depending project was used to create the scope
+							add(referencedProject, null, includeMask, projectsToBeAdded, visitedProjects, cpEntry);
+						}
+					}
+				}
+				break;
+			case IClasspathEntry.CPE_SOURCE:
+				if ((includeMask & SOURCES) != 0) {
+					IPath path = entry.getPath();
+					if (pathToAdd == null || pathToAdd.equals(path)) {
+						add(projectPath.toString(), Util.relativePath(path,1/*remove project segment*/), projectPathString, false/*not a package*/, access);
+					}
+				}
+				break;
+		}
+	}
+}
+/**
+ * Add an element to the java search scope.
+ * @param element The element we want to add to current java search scope
+ * @throws JavaModelException May happen if some Java Model info are not available
+ */
+public void add(IJavaElement element) throws JavaModelException {
+	IPath containerPath = null;
+	String containerPathToString = null;
+	PackageFragmentRoot root = null;
+	int includeMask = SOURCES | APPLICATION_LIBRARIES | SYSTEM_LIBRARIES;
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			// a workspace sope should be used
+			break;
+		case IJavaElement.JAVA_PROJECT:
+			add((JavaProject)element, null, includeMask, new HashSet(2), new HashSet(2), null);
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			root = (PackageFragmentRoot)element;
+			IPath rootPath = root.internalPath();
+			containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : rootPath;
+			containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+			IResource rootResource = root.resource();
+			String projectPath = root.getJavaProject().getPath().toString();
+			if (rootResource != null && rootResource.isAccessible()) {
+				String relativePath = Util.relativePath(rootResource.getFullPath(), containerPath.segmentCount());
+				add(projectPath, relativePath, containerPathToString, false/*not a package*/, null);
+			} else {
+				add(projectPath, "", containerPathToString, false/*not a package*/, null); //$NON-NLS-1$
+			}
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT:
+			root = (PackageFragmentRoot)element.getParent();
+			projectPath = root.getJavaProject().getPath().toString();
+			if (root.isArchive()) {
+				String relativePath = Util.concatWith(((PackageFragment) element).names, '/');
+				containerPath = root.getPath();
+				containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+				add(projectPath, relativePath, containerPathToString, true/*package*/, null);
+			} else {
+				IResource resource = ((JavaElement) element).resource();
+				if (resource != null) {
+					if (resource.isAccessible()) {
+						containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.internalPath();
+					} else {
+						// for working copies, get resource container full path
+						containerPath = resource.getParent().getFullPath();
+					}
+					containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+					String relativePath = Util.relativePath(resource.getFullPath(), containerPath.segmentCount());
+					add(projectPath, relativePath, containerPathToString, true/*package*/, null);
+				}
+			}
+			break;
+		default:
+			// remember sub-cu (or sub-class file) java elements
+			if (element instanceof IMember) {
+				if (this.elements == null) {
+					this.elements = new ArrayList();
+				}
+				this.elements.add(element);
+			}
+			root = (PackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			projectPath = root.getJavaProject().getPath().toString();
+			String relativePath;
+			if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
+				containerPath = root.getParent().getPath();
+				relativePath = Util.relativePath(getPath(element, false/*full path*/), 1/*remove project segment*/);
+			} else {
+				containerPath = root.internalPath();
+				relativePath = getPath(element, true/*relative path*/).toString();
+			}
+			containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+			add(projectPath, relativePath, containerPathToString, false/*not a package*/, null);
+	}
+
+	if (root != null)
+		addEnclosingProjectOrJar(root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.getPath());
+}
+
+/**
+ * Adds the given path to this search scope. Remember if subfolders need to be included
+ * and associated access restriction as well.
+ */
+private void add(String projectPath, String relativePath, String containerPath, boolean isPackage, AccessRuleSet access) {
+	// normalize containerPath and relativePath
+	containerPath = normalize(containerPath);
+	relativePath = normalize(relativePath);
+	int length = this.containerPaths.length,
+		index = (containerPath.hashCode()& 0x7FFFFFFF) % length;
+	String currentRelativePath, currentContainerPath;
+	while ((currentRelativePath = this.relativePaths[index]) != null && (currentContainerPath = this.containerPaths[index]) != null) {
+		if (currentRelativePath.equals(relativePath) && currentContainerPath.equals(containerPath))
+			return;
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	int idx = this.projectPaths.indexOf(projectPath);
+	if (idx == -1) {
+		// store project in separated list to minimize memory footprint
+		this.projectPaths.add(projectPath);
+		idx = this.projectPaths.indexOf(projectPath);
+	}
+	this.projectIndexes[index] = idx;
+	this.relativePaths[index] = relativePath;
+	this.containerPaths[index] = containerPath;
+	this.isPkgPath[index] = isPackage;
+	if (this.pathRestrictions != null)
+		this.pathRestrictions[index] = access;
+	else if (access != null) {
+		this.pathRestrictions = new AccessRuleSet[this.relativePaths.length];
+		this.pathRestrictions[index] = access;
+	}
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.pathsCount > this.threshold)
+		rehash();
+}
+
+/*
+ * E.g.
+ *
+ * 1. /P/src/pkg/X.java
+ * 2. /P/src/pkg
+ * 3. /P/lib.jar|org/eclipse/jdt/core/IJavaElement.class
+ * 4. /home/mylib.jar|x/y/z/X.class
+ * 5. c:\temp\mylib.jar|x/y/Y.class
+ *
+ * @see IJavaSearchScope#encloses(String)
+ */
+public boolean encloses(String resourcePathString) {
+	int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR);
+	if (separatorIndex != -1) {
+		// internal or external jar (case 3, 4, or 5)
+		String jarPath = resourcePathString.substring(0, separatorIndex);
+		String relativePath = resourcePathString.substring(separatorIndex+1);
+		return indexOf(jarPath, relativePath) >= 0;
+	}
+	// resource in workspace (case 1 or 2)
+	return indexOf(resourcePathString) >= 0;
+}
+
+/**
+ * Returns paths list index of given path or -1 if not found.
+ * NOTE: Use indexOf(String, String) for path inside jars
+ *
+ * @param fullPath the full path of the resource, e.g.
+ *   1. /P/src/pkg/X.java
+ *   2. /P/src/pkg
+ */
+private int indexOf(String fullPath) {
+	// cannot guess the index of the container path
+	// fallback to sequentially looking at all known paths
+	for (int i = 0, length = this.relativePaths.length; i < length; i++) {
+		String currentRelativePath = this.relativePaths[i];
+		if (currentRelativePath == null) continue;
+		String currentContainerPath = this.containerPaths[i];
+		String currentFullPath = currentRelativePath.length() == 0 ? currentContainerPath : (currentContainerPath + '/' + currentRelativePath);
+		if (encloses(currentFullPath, fullPath, i))
+			return i;
+	}
+	return -1;
+}
+
+/**
+ * Returns paths list index of given path or -1 if not found.
+ * @param containerPath the path of the container, e.g.
+ *   1. /P/src
+ *   2. /P
+ *   3. /P/lib.jar
+ *   4. /home/mylib.jar
+ *   5. c:\temp\mylib.jar
+ * @param relativePath the forward slash path relatively to the container, e.g.
+ *   1. x/y/Z.class
+ *   2. x/y
+ *   3. X.java
+ *   4. (empty)
+ */
+private int indexOf(String containerPath, String relativePath) {
+	// use the hash to get faster comparison
+	int length = this.containerPaths.length,
+		index = (containerPath.hashCode()& 0x7FFFFFFF) % length;
+	String currentContainerPath;
+	while ((currentContainerPath = this.containerPaths[index]) != null) {
+		if (currentContainerPath.equals(containerPath)) {
+			String currentRelativePath = this.relativePaths[index];
+			if (encloses(currentRelativePath, relativePath, index))
+				return index;
+		}
+		if (++index == length) {
+			index = 0;
+		}
+	}
+	return -1;
+}
+
+/*
+ * Returns whether the enclosing path encloses the given path (or is equal to it)
+ */
+private boolean encloses(String enclosingPath, String path, int index) {
+	// normalize given path as it can come from outside
+	path = normalize(path);
+
+	int pathLength = path.length();
+	int enclosingLength = enclosingPath.length();
+	if (pathLength < enclosingLength) {
+		return false;
+	}
+	if (enclosingLength == 0) {
+		return true;
+	}
+	if (pathLength == enclosingLength) {
+		return path.equals(enclosingPath);
+	}
+	if (!this.isPkgPath[index]) {
+		return path.startsWith(enclosingPath)
+			&& path.charAt(enclosingLength) == '/';
+	} else {
+		// if looking at a package, this scope encloses the given path
+		// if the given path is a direct child of the folder
+		// or if the given path path is the folder path (see bug 13919 Declaration for package not found if scope is not project)
+		if (path.startsWith(enclosingPath)
+			&& ((enclosingPath.length() == path.lastIndexOf('/'))
+				|| (enclosingPath.length() == path.length()))) {
+			return true;
+		}
+	}
+	return false;
+}
+
+/* (non-Javadoc)
+ * @see IJavaSearchScope#encloses(IJavaElement)
+ */
+public boolean encloses(IJavaElement element) {
+	if (this.elements != null) {
+		for (int i = 0, length = this.elements.size(); i < length; i++) {
+			IJavaElement scopeElement = (IJavaElement)this.elements.get(i);
+			IJavaElement searchedElement = element;
+			while (searchedElement != null) {
+				if (searchedElement.equals(scopeElement))
+					return true;
+				searchedElement = searchedElement.getParent();
+			}
+		}
+		return false;
+	}
+	IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+	if (root != null && root.isArchive()) {
+		// external or internal jar
+		IPath rootPath = root.getPath();
+		String rootPathToString = rootPath.getDevice() == null ? rootPath.toString() : rootPath.toOSString();
+		IPath relativePath = getPath(element, true/*relative path*/);
+		return indexOf(rootPathToString, relativePath.toString()) >= 0;
+	}
+	// resource in workspace
+	String fullResourcePathString = getPath(element, false/*full path*/).toString();
+	return indexOf(fullResourcePathString) >= 0;
+}
+
+/* (non-Javadoc)
+ * @see IJavaSearchScope#enclosingProjectsAndJars()
+ */
+public IPath[] enclosingProjectsAndJars() {
+	return this.enclosingProjectsAndJars;
+}
+private IPath getPath(IJavaElement element, boolean relativeToRoot) {
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			return Path.EMPTY;
+		case IJavaElement.JAVA_PROJECT:
+			return element.getPath();
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			if (relativeToRoot)
+				return Path.EMPTY;
+			return element.getPath();
+		case IJavaElement.PACKAGE_FRAGMENT:
+			String relativePath = Util.concatWith(((PackageFragment) element).names, '/');
+			return getPath(element.getParent(), relativeToRoot).append(new Path(relativePath));
+		case IJavaElement.COMPILATION_UNIT:
+		case IJavaElement.CLASS_FILE:
+			return getPath(element.getParent(), relativeToRoot).append(new Path(element.getElementName()));
+		default:
+			return getPath(element.getParent(), relativeToRoot);
+	}
+}
+
+/**
+ * Get access rule set corresponding to a given path.
+ * @param relativePath The path user want to have restriction access
+ * @return The access rule set for given path or null if none is set for it.
+ * 	Returns specific uninit access rule set when scope does not enclose the given path.
+ */
+public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) {
+	int index = indexOf(containerPath, relativePath);
+	if (index == -1) {
+		// this search scope does not enclose given path
+		return NOT_ENCLOSED;
+	}
+	if (this.pathRestrictions == null)
+		return null;
+	return this.pathRestrictions[index];
+}
+
+protected void initialize(int size) {
+	this.pathsCount = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.relativePaths = new String[extraRoom];
+	this.containerPaths = new String[extraRoom];
+	this.projectPaths = new ArrayList();
+	this.projectIndexes = new int[extraRoom];
+	this.isPkgPath = new boolean[extraRoom];
+	this.pathRestrictions = null; // null to optimize case where no access rules are used
+
+	this.enclosingProjectsAndJars = new IPath[0];
+}
+
+/*
+ * Removes trailing slashes from the given path
+ */
+private String normalize(String path) {
+	int pathLength = path.length();
+	int index = pathLength-1;
+	while (index >= 0 && path.charAt(index) == '/')
+		index--;
+	if (index != pathLength-1)
+		return path.substring(0, index + 1);
+	return path;
+}
+
+/*
+ * @see AbstractSearchScope#processDelta(IJavaElementDelta)
+ */
+public void processDelta(IJavaElementDelta delta, int eventType) {
+	switch (delta.getKind()) {
+		case IJavaElementDelta.CHANGED:
+			IJavaElementDelta[] children = delta.getAffectedChildren();
+			for (int i = 0, length = children.length; i < length; i++) {
+				IJavaElementDelta child = children[i];
+				processDelta(child, eventType);
+			}
+			break;
+		case IJavaElementDelta.REMOVED:
+			IJavaElement element = delta.getElement();
+			if (this.encloses(element)) {
+				if (this.elements != null) {
+					this.elements.remove(element);
+				}
+				String path = null;
+				switch (element.getElementType()) {
+					case IJavaElement.JAVA_PROJECT:
+						path = ((IJavaProject)element).getProject().getFullPath().toString();
+						break;
+					case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+						path = ((IPackageFragmentRoot)element).getPath().toString();
+						break;
+					default:
+						return;
+				}
+				for (int i = 0; i < this.pathsCount; i++) {
+					if (this.relativePaths[i].equals(path)) {
+						this.relativePaths[i] = null;
+						rehash();
+						break;
+					}
+				}
+			}
+			break;
+	}
+}
+
+/**
+ * @see AbstractJavaSearchScope#packageFragmentRoot(String, int, String)
+ */
+public IPackageFragmentRoot packageFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPath) {
+	int index = -1;
+	boolean isJarFile = jarSeparatorIndex != -1;
+	if (isJarFile) {
+		// internal or external jar (case 3, 4, or 5)
+		String relativePath = resourcePathString.substring(jarSeparatorIndex+1);
+		index = indexOf(jarPath, relativePath);
+	} else {
+		// resource in workspace (case 1 or 2)
+		index = indexOf(resourcePathString);
+	}
+	if (index >= 0) {
+		int idx = this.projectIndexes[index];
+		String projectPath = idx == -1 ? null : (String) this.projectPaths.get(idx);
+		if (projectPath != null) {
+			IJavaProject project =JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(projectPath));
+			if (isJarFile) {
+				IResource resource = JavaModel.getWorkspaceTarget(new Path(jarPath));
+				if (resource != null)
+					return project.getPackageFragmentRoot(resource);
+				return project.getPackageFragmentRoot(jarPath);
+			}
+			Object target = JavaModel.getWorkspaceTarget(new Path(this.containerPaths[index]+'/'+this.relativePaths[index]));
+			if (target != null) {
+				if (target instanceof IProject) {
+					return project.getPackageFragmentRoot((IProject) target);
+				}
+				IJavaElement element = JavaModelManager.create((IResource) target, project);
+				return (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			}
+		}
+	}
+	return null;
+}
+
+private void rehash() {
+	JavaSearchScope newScope = new JavaSearchScope(this.pathsCount * 2);		// double the number of expected elements
+	newScope.projectPaths.ensureCapacity(this.projectPaths.size());
+	String currentPath;
+	for (int i=0, length=this.relativePaths.length; i<length; i++)
+		if ((currentPath = this.relativePaths[i]) != null) {
+			int idx = this.projectIndexes[i];
+			String projectPath = idx == -1 ? null : (String)this.projectPaths.get(idx);
+			newScope.add(projectPath, currentPath, this.containerPaths[i], this.isPkgPath[i], this.pathRestrictions == null ? null : this.pathRestrictions[i]);
+		}
+
+	this.relativePaths = newScope.relativePaths;
+	this.containerPaths = newScope.containerPaths;
+	this.projectPaths = newScope.projectPaths;
+	this.projectIndexes = newScope.projectIndexes;
+	this.isPkgPath = newScope.isPkgPath;
+	this.pathRestrictions = newScope.pathRestrictions;
+	this.threshold = newScope.threshold;
+}
+
+public String toString() {
+	StringBuffer result = new StringBuffer("JavaSearchScope on "); //$NON-NLS-1$
+	if (this.elements != null) {
+		result.append("["); //$NON-NLS-1$
+		for (int i = 0, length = this.elements.size(); i < length; i++) {
+			JavaElement element = (JavaElement)this.elements.get(i);
+			result.append("\n\t"); //$NON-NLS-1$
+			result.append(element.toStringWithAncestors());
+		}
+		result.append("\n]"); //$NON-NLS-1$
+	} else {
+		if (this.pathsCount == 0) {
+			result.append("[empty scope]"); //$NON-NLS-1$
+		} else {
+			result.append("["); //$NON-NLS-1$
+			String[] paths = new String[this.relativePaths.length];
+			int index = 0;
+			for (int i = 0; i < this.relativePaths.length; i++) {
+				String path = this.relativePaths[i];
+				if (path == null) continue;
+				String containerPath;
+				if (ExternalFoldersManager.isInternalPathForExternalFolder(new Path(this.containerPaths[i]))) {
+					Object target = JavaModel.getWorkspaceTarget(new Path(this.containerPaths[i]));
+					containerPath = ((IFolder) target).getLocation().toOSString();
+				} else {
+					containerPath = this.containerPaths[i];
+				}
+				if (path.length() > 0) {
+					paths[index++] = containerPath + '/' + path;
+				} else {
+					paths[index++] = containerPath;
+				}
+			}
+			System.arraycopy(paths, 0, paths = new String[index], 0, index);
+			Util.sort(paths);
+			for (int i = 0; i < index; i++) {
+				result.append("\n\t"); //$NON-NLS-1$
+				result.append(paths[i]);
+			}
+			result.append("\n]"); //$NON-NLS-1$
+		}
+	}
+	return result.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchTypeNameMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchTypeNameMatch.java
new file mode 100644
index 0000000..110e0e1
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchTypeNameMatch.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.search.*;
+
+/**
+ * Java Search concrete class for a type name match.
+ *
+ * @since 3.3
+ */
+public class JavaSearchTypeNameMatch extends TypeNameMatch {
+
+	private IType type;
+	private int modifiers = -1; // store modifiers to avoid java model population
+
+	private int accessibility = IAccessRule.K_ACCESSIBLE;
+
+/**
+ * Creates a new Java Search type name match.
+ */
+public JavaSearchTypeNameMatch(IType type, int modifiers) {
+	this.type = type;
+	this.modifiers = modifiers;
+}
+
+/* (non-Javadoc)
+ * Returns whether the matched type is equals to the given object or not.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+public boolean equals(Object obj) {
+	if (obj == this) return true; // avoid unnecessary calls for identical objects
+	if (obj instanceof TypeNameMatch) {
+		TypeNameMatch match = (TypeNameMatch) obj;
+		if (this.type == null) {
+			return match.getType() == null && match.getModifiers() == this.modifiers;
+		}
+		return this.type.equals(match.getType()) && match.getModifiers() == this.modifiers;
+	}
+	return false;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.search.TypeNameMatch#getAccessibility()
+ */
+public int getAccessibility() {
+	return this.accessibility;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.search.TypeNameMatch#getModifiers()
+ */
+public int getModifiers() {
+	return this.modifiers;
+}
+
+/* (non-Javadoc)
+ * Note that returned handle exists as it matches a type accepted
+ * from up-to-date index file.
+ * @see org.eclipse.jdt.core.search.TypeNameMatch#getType()
+ */
+public IType getType() {
+	return this.type;
+}
+
+/* (non-Javadoc)
+ * Returns the hash code of the matched type.
+ * @see java.lang.Object#hashCode()
+ */
+public int hashCode() {
+	if (this.type == null) return this.modifiers;
+	return this.type.hashCode();
+}
+
+/**
+ * Sets the accessibility of the accepted match.
+ * 
+ * @param accessibility the accessibility of the current match
+ */
+public void setAccessibility(int accessibility) {
+	this.accessibility = accessibility;
+}
+
+/**
+ * Set modifiers of the matched type.
+ *
+ * @param modifiers the modifiers of the matched type.
+ */
+public void setModifiers(int modifiers) {
+	this.modifiers = modifiers;
+}
+
+/**
+ * Set matched type.
+ *
+ * @param type the matched type.
+ */
+public void setType(IType type) {
+	this.type = type;
+}
+
+/* (non-Javadoc)
+ * Returns the string of the matched type.
+ * @see java.lang.Object#toString()
+ */
+public String toString() {
+	if (this.type == null) return super.toString();
+	return this.type.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
new file mode 100644
index 0000000..6049d1d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nikolay Botev - Bug 348507
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaElementDelta;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.core.DeltaProcessor;
+import org.eclipse.jdt.internal.core.ExternalFoldersManager;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A Java-specific scope for searching the entire workspace.
+ * The scope can be configured to not search binaries. By default, binaries
+ * are included.
+ */
+public class JavaWorkspaceScope extends AbstractJavaSearchScope {
+
+	private IPath[] enclosingPaths = null;
+
+public JavaWorkspaceScope() {
+	// As nothing is stored in the JavaWorkspaceScope now, no initialization is longer needed
+}
+
+public boolean encloses(IJavaElement element) {
+	/*A workspace scope encloses all java elements (this assumes that the index selector
+	 * and thus enclosingProjectAndJars() returns indexes on the classpath only and that these
+	 * indexes are consistent.)
+	 * NOTE: Returning true gains 20% of a hierarchy build on Object
+	 */
+	return true;
+}
+public boolean encloses(String resourcePathString) {
+	/*A workspace scope encloses all resources (this assumes that the index selector
+	 * and thus enclosingProjectAndJars() returns indexes on the classpath only and that these
+	 * indexes are consistent.)
+	 * NOTE: Returning true gains 20% of a hierarchy build on Object
+	 */
+	return true;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.search.IJavaSearchScope#enclosingProjectsAndJars()
+ */
+public IPath[] enclosingProjectsAndJars() {
+	IPath[] result = this.enclosingPaths;
+	if (result != null) {
+		return result;
+	}
+	long start = BasicSearchEngine.VERBOSE ? System.currentTimeMillis() : -1;
+	try {
+		IJavaProject[] projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+		// use a linked set to preserve the order during search: see bug 348507
+		Set paths = new LinkedHashSet(projects.length * 2);
+		for (int i = 0, length = projects.length; i < length; i++) {
+			JavaProject javaProject = (JavaProject) projects[i];
+
+			// Add project full path
+			IPath projectPath = javaProject.getProject().getFullPath();
+			paths.add(projectPath);
+		}
+
+		// add the project source paths first in a separate loop above
+		// to ensure source files always get higher precedence during search.
+		// see bug 348507
+
+		for (int i = 0, length = projects.length; i < length; i++) {
+			JavaProject javaProject = (JavaProject) projects[i];
+
+			// Add project libraries paths
+			IClasspathEntry[] entries = javaProject.getResolvedClasspath();
+			for (int j = 0, eLength = entries.length; j < eLength; j++) {
+				IClasspathEntry entry = entries[j];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+					IPath path = entry.getPath();
+					Object target = JavaModel.getTarget(path, false/*don't check existence*/);
+					if (target instanceof IFolder) // case of an external folder
+						path = ((IFolder) target).getFullPath();
+					paths.add(entry.getPath());
+				}
+			}
+		}
+		result = new IPath[paths.size()];
+		paths.toArray(result);
+		return this.enclosingPaths = result;
+	} catch (JavaModelException e) {
+		Util.log(e, "Exception while computing workspace scope's enclosing projects and jars"); //$NON-NLS-1$
+		return new IPath[0];
+	} finally {
+		if (BasicSearchEngine.VERBOSE) {
+			long time = System.currentTimeMillis() - start;
+			int length = result == null ? 0 : result.length;
+			Util.verbose("JavaWorkspaceScope.enclosingProjectsAndJars: "+length+" paths computed in "+time+"ms."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		}
+	}
+}
+
+public boolean equals(Object o) {
+  return o == this; // use the singleton pattern
+}
+
+public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) {
+	// Do not consider access rules on workspace scope
+	return null;
+}
+
+public int hashCode() {
+	return JavaWorkspaceScope.class.hashCode();
+}
+
+/**
+ * @see AbstractJavaSearchScope#packageFragmentRoot(String, int, String)
+ */
+public IPackageFragmentRoot packageFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPath) {
+	HashMap rootInfos = JavaModelManager.getDeltaState().roots;
+	DeltaProcessor.RootInfo rootInfo = null;
+	if (jarPath != null) {
+		IPath path = new Path(jarPath);
+		rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(path);
+	} else {
+		IPath path = new Path(resourcePathString);
+		if (ExternalFoldersManager.isInternalPathForExternalFolder(path)) {
+			IResource resource = JavaModel.getWorkspaceTarget(path.uptoSegment(2/*linked folders for external folders are always of size 2*/));
+			if (resource != null)
+				rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(resource.getLocation());
+		} else {
+			rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(path);
+			while (rootInfo == null && path.segmentCount() > 0) {
+				path = path.removeLastSegments(1);
+				rootInfo = (DeltaProcessor.RootInfo) rootInfos.get(path);
+			}
+		}
+	}
+	if (rootInfo == null)
+		return null;
+	return rootInfo.getPackageFragmentRoot(null/*no resource hint*/);
+}
+
+public void processDelta(IJavaElementDelta delta, int eventType) {
+	if (this.enclosingPaths == null) return;
+	IJavaElement element = delta.getElement();
+	switch (element.getElementType()) {
+		case IJavaElement.JAVA_MODEL:
+			IJavaElementDelta[] children = delta.getAffectedChildren();
+			for (int i = 0, length = children.length; i < length; i++) {
+				IJavaElementDelta child = children[i];
+				processDelta(child, eventType);
+			}
+			break;
+		case IJavaElement.JAVA_PROJECT:
+			int kind = delta.getKind();
+			switch (kind) {
+				case IJavaElementDelta.ADDED:
+				case IJavaElementDelta.REMOVED:
+					this.enclosingPaths = null;
+					break;
+				case IJavaElementDelta.CHANGED:
+					int flags = delta.getFlags();
+					if ((flags & IJavaElementDelta.F_CLOSED) != 0
+							|| (flags & IJavaElementDelta.F_OPENED) != 0) {
+						this.enclosingPaths = null;
+					} else {
+						children = delta.getAffectedChildren();
+						for (int i = 0, length = children.length; i < length; i++) {
+							IJavaElementDelta child = children[i];
+							processDelta(child, eventType);
+						}
+					}
+					break;
+			}
+			break;
+		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+			kind = delta.getKind();
+			switch (kind) {
+				case IJavaElementDelta.ADDED:
+				case IJavaElementDelta.REMOVED:
+					this.enclosingPaths = null;
+					break;
+				case IJavaElementDelta.CHANGED:
+					int flags = delta.getFlags();
+					if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) > 0
+						|| (flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) > 0) {
+						this.enclosingPaths = null;
+					}
+					break;
+			}
+			break;
+	}
+}
+
+
+public String toString() {
+	StringBuffer result = new StringBuffer("JavaWorkspaceScope on "); //$NON-NLS-1$
+	IPath[] paths = enclosingProjectsAndJars();
+	int length = paths == null ? 0 : paths.length;
+	if (length == 0) {
+		result.append("[empty scope]"); //$NON-NLS-1$
+	} else {
+		result.append("["); //$NON-NLS-1$
+		for (int i = 0; i < length; i++) {
+			result.append("\n\t"); //$NON-NLS-1$
+			result.append(paths[i]);
+		}
+		result.append("\n]"); //$NON-NLS-1$
+	}
+	return result.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java
new file mode 100644
index 0000000..fb16879
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.util.HashSet;
+
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+
+/**
+ * Collects the resource paths reported by a client to this search requestor.
+ */
+public class PathCollector extends IndexQueryRequestor {
+
+	/* a set of resource paths */
+	public HashSet paths = new HashSet(5);
+
+	/* (non-Javadoc)
+	 * @see IndexQueryRequestor#acceptIndexMatch(String, SearchPattern, SearchParticipant, AccessRuleSet)
+	 */
+	public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+		this.paths.add(documentPath);
+		return true;
+	}
+
+	/**
+	 * Returns the paths that have been collected.
+	 */
+	public String[] getPaths() {
+		return (String[]) this.paths.toArray(new String[this.paths.size()]);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java
new file mode 100644
index 0000000..c83c2f1
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.index.FileIndexLocation;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+import org.eclipse.jdt.internal.core.search.processing.IJob;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class PatternSearchJob implements IJob {
+
+protected SearchPattern pattern;
+protected IJavaSearchScope scope;
+protected SearchParticipant participant;
+protected IndexQueryRequestor requestor;
+protected boolean areIndexesReady;
+protected long executionTime = 0;
+
+public PatternSearchJob(SearchPattern pattern, SearchParticipant participant, IJavaSearchScope scope, IndexQueryRequestor requestor) {
+	this.pattern = pattern;
+	this.participant = participant;
+	this.scope = scope;
+	this.requestor = requestor;
+}
+public boolean belongsTo(String jobFamily) {
+	return true;
+}
+public void cancel() {
+	// search job is cancelled through progress
+}
+public void ensureReadyToRun() {
+	if (!this.areIndexesReady)
+		getIndexes(null/*progress*/); // may trigger some index recreation
+}
+public boolean execute(IProgressMonitor progressMonitor) {
+	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
+
+	boolean isComplete = COMPLETE;
+	this.executionTime = 0;
+	Index[] indexes = getIndexes(progressMonitor);
+	try {
+		int max = indexes.length;
+		if (progressMonitor != null)
+			progressMonitor.beginTask("", max); //$NON-NLS-1$
+		for (int i = 0; i < max; i++) {
+			isComplete &= search(indexes[i], progressMonitor);
+			if (progressMonitor != null) {
+				if (progressMonitor.isCanceled()) throw new OperationCanceledException();
+				progressMonitor.worked(1);
+			}
+		}
+		if (JobManager.VERBOSE)
+			Util.verbose("-> execution time: " + this.executionTime + "ms - " + this);//$NON-NLS-1$//$NON-NLS-2$
+		return isComplete;
+	} finally {
+		if (progressMonitor != null)
+			progressMonitor.done();
+	}
+}
+public Index[] getIndexes(IProgressMonitor progressMonitor) {
+	// acquire the in-memory indexes on the fly
+	IndexLocation[] indexLocations;
+	int length;
+	if (this.participant instanceof JavaSearchParticipant) {
+		indexLocations = ((JavaSearchParticipant)this.participant).selectIndexURLs(this.pattern, this.scope);
+		length = indexLocations.length;
+	} else {
+		IPath[] paths = this.participant.selectIndexes(this.pattern, this.scope);
+		length = paths.length;
+		indexLocations = new IndexLocation[paths.length];
+		for (int i = 0, len = paths.length; i < len; i++) {
+			indexLocations[i] = new FileIndexLocation(paths[i].toFile(), true);
+		}
+	}
+	Index[] indexes = JavaModelManager.getIndexManager().getIndexes(indexLocations, progressMonitor);
+	this.areIndexesReady = indexes.length == length;
+	return indexes;
+}
+public String getJobFamily() {
+	return ""; //$NON-NLS-1$
+}
+public boolean search(Index index, IProgressMonitor progressMonitor) {
+	if (index == null) return COMPLETE;
+	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
+	ReadWriteMonitor monitor = index.monitor;
+	if (monitor == null) return COMPLETE; // index got deleted since acquired
+	try {
+		monitor.enterRead(); // ask permission to read
+		long start = System.currentTimeMillis();
+		MatchLocator.findIndexMatches(this.pattern, index, this.requestor, this.participant, this.scope, progressMonitor);
+		this.executionTime += System.currentTimeMillis() - start;
+		return COMPLETE;
+	} catch (IOException e) {
+		if (e instanceof java.io.EOFException)
+			e.printStackTrace();
+		return FAILED;
+	} finally {
+		monitor.exitRead(); // finished reading
+	}
+}
+public String toString() {
+	return "searching " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/StringOperation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/StringOperation.java
new file mode 100644
index 0000000..6c654ab
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/StringOperation.java
@@ -0,0 +1,494 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * This class is a collection of helper methods to manipulate strings during search.
+ */
+public final class StringOperation {
+
+	private final static int[] EMPTY_REGIONS = new int[0];
+
+/**
+ * Answers all the regions in a given name matching a given camel case pattern.
+ * </p><p>
+ * Each of these regions is made of its starting index and its length in the given
+ * name. They are all concatenated in a single array of <code>int</code>
+ * which therefore always has an even length.
+ * </p><p>
+ * Note that each region is disjointed from the following one.<br>
+ * E.g. if the regions are <code>{ start1, length1, start2, length2 }</code>,
+ * then <code>start1+length1</code> will always be smaller than
+ * <code>start2</code>.
+ * </p><p>
+ * <pre>
+ * Examples:
+ * <ol><li>  pattern = "NPE"
+ *  name = NullPointerException / NoPermissionException
+ *  result:  { 0, 1, 4, 1, 11, 1 } / { 0, 1, 2, 1, 12, 1 } </li>
+ * <li>  pattern = "NuPoEx"
+ *  name = NullPointerException
+ *  result:  { 0, 2, 4, 2, 11, 2 }</li>
+ * <li>  pattern = "IPL3"
+ *  name = "IPerspectiveListener3"
+ *  result:  { 0, 2, 12, 1, 20, 1 }</li>
+ * <li>  pattern = "HashME"
+ *  name = "HashMapEntry"
+ *  result:  { 0, 5, 7, 1 }</li>
+ * </ol></pre>
+ *</p>
+ * @see CharOperation#camelCaseMatch(char[], int, int, char[], int, int, boolean)
+ * 	for more details on the camel case behavior
+ * @see CharOperation#match(char[], char[], boolean) for more details on the
+ * 	pattern match behavior
+ *
+ * @param pattern the given pattern
+ * @param patternStart the start index of the pattern, inclusive
+ * @param patternEnd the end index of the pattern, exclusive
+ * @param name the given name
+ * @param nameStart the start index of the name, inclusive
+ * @param nameEnd the end index of the name, exclusive
+ * @param samePartCount flag telling whether the pattern and the name should
+ * 	have the same count of parts or not.<br>
+ * 	&nbsp;&nbsp;For example:
+ * 	<ul>
+ * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
+ * 				but not 'HashMapEntry'</li>
+ * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
+ * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
+ * 	</ul>
+ * @return an array of <code>int</code> having two slots per returned
+ * 	regions (first one is the starting index of the region and the second
+ * 	one the length of the region).<br>
+ * 	Note that it may be <code>null</code> if the given name does not match
+ * 	the pattern
+ * @since 3.5
+ */
+public static final int[] getCamelCaseMatchingRegions(String pattern, int patternStart, int patternEnd, String name, int nameStart, int nameEnd, boolean samePartCount) {
+
+	/* !!!!!!!!!! WARNING !!!!!!!!!!
+	 * The algorithm used in this method has been fully inspired from
+	 * CharOperation#camelCaseMatch(char[], int, int, char[], int, int, boolean).
+	 *
+	 * So, if any change needs to be applied in the algorithm, do NOT forget
+	 * to backport it in the CharOperation method!
+	 */
+
+	if (name == null)
+		return null; // null name cannot match
+	if (pattern == null) {
+		// null pattern cannot match any region
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=264816
+		return EMPTY_REGIONS;
+	}
+	if (patternEnd < 0) 	patternEnd = pattern.length();
+	if (nameEnd < 0) nameEnd = name.length();
+
+	if (patternEnd <= patternStart) {
+		return nameEnd <= nameStart
+			? new int[] { patternStart, patternEnd-patternStart }
+			: null;
+	}
+	if (nameEnd <= nameStart) return null;
+	// check first pattern char
+	if (name.charAt(nameStart) != pattern.charAt(patternStart)) {
+		// first char must strictly match (upper/lower)
+		return null;
+	}
+
+	char patternChar, nameChar;
+	int iPattern = patternStart;
+	int iName = nameStart;
+
+	// init segments
+	int parts = 1;
+	for (int i=patternStart+1; i<patternEnd; i++) {
+		final char ch = pattern.charAt(i);
+		if (ch < ScannerHelper.MAX_OBVIOUS) {
+			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[ch] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) != 0) {
+				parts++;
+			}
+		} else if (Character.isJavaIdentifierPart(ch) && (Character.isUpperCase(ch) || Character.isDigit(ch))) {
+			parts++;
+		}
+	}
+	int[] segments = null;
+	int count = 0; // count
+
+	// Main loop is on pattern characters
+	int segmentStart = iName;
+	while (true) {
+		iPattern++;
+		iName++;
+
+		if (iPattern == patternEnd) { // we have exhausted pattern...
+			// it's a match if the name can have additional parts (i.e. uppercase characters) or is also exhausted
+			if (!samePartCount || iName == nameEnd) {
+				if (segments == null) {
+					segments = new int[2];
+				}
+				segments[count++] = segmentStart;
+				segments[count++] = iName - segmentStart;
+				if (count < segments.length) {
+					System.arraycopy(segments, 0, segments = new int[count], 0, count);
+				}
+				return segments;
+			}
+
+			// otherwise it's a match only if the name has no more uppercase characters
+			int segmentEnd = iName;
+			while (true) {
+				if (iName == nameEnd) {
+					// we have exhausted the name, so it's a match
+					if (segments == null) {
+						segments = new int[2];
+					}
+					segments[count++] = segmentStart;
+					segments[count++] = segmentEnd - segmentStart;
+					if (count < segments.length) {
+						System.arraycopy(segments, 0, segments = new int[count], 0, count);
+					}
+					return segments;
+				}
+				nameChar = name.charAt(iName);
+				// test if the name character is uppercase
+				if (nameChar < ScannerHelper.MAX_OBVIOUS) {
+					if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] & ScannerHelper.C_UPPER_LETTER) != 0) {
+						return null;
+					}
+				}
+				else if (!Character.isJavaIdentifierPart(nameChar) || Character.isUpperCase(nameChar)) {
+					return null;
+				}
+				iName++;
+			}
+		}
+
+		if (iName == nameEnd){
+			// We have exhausted the name (and not the pattern), so it's not a match
+			return null;
+		}
+
+		// For as long as we're exactly matching, bring it on (even if it's a lower case character)
+		if ((patternChar = pattern.charAt(iPattern)) == name.charAt(iName)) {
+			continue;
+		}
+		int segmentEnd = iName;
+
+		// If characters are not equals, then it's not a match if patternChar is lowercase
+		if (patternChar < ScannerHelper.MAX_OBVIOUS) {
+			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) == 0) {
+				return null;
+			}
+		} else if (Character.isJavaIdentifierPart(patternChar) && !Character.isUpperCase(patternChar) && !Character.isDigit(patternChar)) {
+			return null;
+		}
+
+		// patternChar is uppercase, so let's find the next uppercase in name
+		while (true) {
+			if (iName == nameEnd){
+	            //	We have exhausted name (and not pattern), so it's not a match
+				return null;
+			}
+
+			nameChar = name.charAt(iName);
+			if (nameChar < ScannerHelper.MAX_OBVIOUS) {
+				int charNature = ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar];
+				if ((charNature & (ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_SPECIAL)) != 0) {
+					// nameChar is lowercase
+					iName++;
+				} else if ((charNature & ScannerHelper.C_DIGIT) != 0) {
+					// nameChar is digit => break if the digit is current pattern character otherwise consume it
+					if (patternChar == nameChar) break;
+					iName++;
+				// nameChar is uppercase...
+				} else  if (patternChar != nameChar) {
+					//.. and it does not match patternChar, so it's not a match
+					return null;
+				} else {
+					//.. and it matched patternChar. Back to the big loop
+					break;
+				}
+			}
+			// Same tests for non-obvious characters
+			else if (Character.isJavaIdentifierPart(nameChar) && !Character.isUpperCase(nameChar)) {
+				iName++;
+			} else if (Character.isDigit(nameChar)) {
+				if (patternChar == nameChar) break;
+				iName++;
+			} else  if (patternChar != nameChar) {
+				return null;
+			} else {
+				break;
+			}
+		}
+		// At this point, either name has been exhausted, or it is at an uppercase letter.
+		// Since pattern is also at an uppercase letter
+		if (segments == null) {
+			segments = new int[parts*2];
+		}
+		segments[count++] = segmentStart;
+		segments[count++] = segmentEnd - segmentStart;
+		segmentStart = iName;
+	}
+}
+
+/**
+ * Answers all the regions in a given name matching a given <i>pattern</i>
+ * pattern (e.g. "H*M??").
+ * </p><p>
+ * Each of these regions is made of its starting index and its length in the given
+ * name. They are all concatenated in a single array of <code>int</code>
+ * which therefore always has an even length.
+ * </p><p>
+ * Note that each region is disjointed from the following one.<br>
+ * E.g. if the regions are <code>{ start1, length1, start2, length2 }</code>,
+ * then <code>start1+length1</code> will always be smaller than
+ * <code>start2</code>.
+ * </p><p>
+ * <pre>
+ * Examples:
+ * <ol>
+ * <li>  pattern = "N???Po*Ex?eption"
+ *  name = NullPointerException
+ *  result:  { 0, 1, 4, 2, 11, 2, 14, 6 }</li>
+ * <li>  pattern = "Ha*M*ent*"
+ *  name = "HashMapEntry"
+ *  result:  { 0, 2, 4, 1, 7, 3 }</li>
+ * </ol></pre>
+ *</p>
+ * @see CharOperation#match(char[], char[], boolean) for more details on the
+ * 	pattern match behavior
+ *
+ * @param pattern the given pattern
+ * @param patternStart the given pattern start
+ * @param patternEnd the given pattern end
+ * @param name the given name
+ * @param nameStart the given name start
+ * @param nameEnd the given name end
+ * @param isCaseSensitive flag to know if the matching should be case sensitive
+ * @return an array of <code>int</code> having two slots per returned
+ * 	regions (first one is the starting index of the region and the second
+ * 	one the length of the region).<br>
+ * 	Note that it may be <code>null</code> if the given name does not match
+ * 	the pattern
+ * @since 3.5
+ */
+public static final int[] getPatternMatchingRegions(
+	String pattern,
+	int patternStart,
+	int patternEnd,
+	String name,
+	int nameStart,
+	int nameEnd,
+	boolean isCaseSensitive) {
+
+	/* !!!!!!!!!! WARNING !!!!!!!!!!
+	 * The algorithm used in this method has been fully inspired from
+	 * CharOperation#match(char[], int, int, char[], int, int, boolean).
+	 *
+	 * So, if any change needs to be applied in the algorithm, do NOT forget
+	 * to backport it in the CharOperation method!
+	 */
+
+	if (name == null) return null; // null name cannot match
+	if (pattern == null) {
+		// null pattern cannot match any region
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=264816
+		return EMPTY_REGIONS;
+	}
+	int iPattern = patternStart;
+	int iName = nameStart;
+
+	// init segments parts
+	if (patternEnd < 0)
+		patternEnd = pattern.length();
+	if (nameEnd < 0)
+		nameEnd = name.length();
+	int questions = 0;
+	int parts = 0;
+	char previous = 0;
+	for (int i=patternStart; i<patternEnd; i++) {
+		char ch = pattern.charAt(i);
+		switch (ch) {
+			case '?':
+				questions++;
+				break;
+			case '*':
+				break;
+			default:
+				switch (previous) {
+					case 0 :
+					case '?':
+					case '*':
+						parts++;
+						break;
+				}
+		}
+		previous = ch;
+	}
+	if (parts == 0) {
+		if (questions <= (nameEnd - nameStart)) return EMPTY_REGIONS;
+		return null;
+	}
+	int[] segments = new int[parts*2];
+
+	/* check first segment */
+	int count = 0;
+	int start = iName;
+	char patternChar = 0;
+	previous = 0;
+	while ((iPattern < patternEnd)
+		&& (patternChar = pattern.charAt(iPattern)) != '*') {
+		if (iName == nameEnd)
+			return null;
+		if (patternChar == '?') {
+			switch (previous) {
+				case 0:
+				case '?':
+					break;
+				default:
+					segments[count++] = start;
+					segments[count++] = iPattern-start;
+					break;
+			}
+		} else {
+			if (isCaseSensitive) {
+				if (patternChar != name.charAt(iName)) {
+					return null;
+				}
+			} else if (ScannerHelper.toLowerCase(patternChar) != ScannerHelper.toLowerCase(name.charAt(iName))) {
+				return null;
+			}
+			switch (previous) {
+				case 0:
+				case '?':
+					start = iPattern;
+					break;
+			}
+		}
+		iName++;
+		iPattern++;
+		previous = patternChar;
+	}
+	/* check sequence of star+segment */
+	int segmentStart;
+	if (patternChar == '*') {
+		if (iPattern > 0 && previous != '?') {
+			segments[count++] = start;
+			segments[count++] = iName-start;
+			start = iName;
+		}
+		segmentStart = ++iPattern; // skip star
+	} else {
+		if (iName == nameEnd) {
+			if (count == (parts*2)) return segments;
+			int end = patternEnd;
+			if (previous == '?') { // last char was a '?' => purge all trailing '?'
+				while (pattern.charAt(--end-1) == '?') {
+					if (end == start) {
+						return new int[] { patternStart, patternEnd-patternStart };
+					}
+				}
+			}
+			return new int[] { start, end-start };
+		}
+		return null;
+	}
+	int prefixStart = iName;
+	int previousCount = count;
+	previous = patternChar;
+	char previousSegment = patternChar;
+	checkSegment : while (iName < nameEnd) {
+		if (iPattern == patternEnd) {
+			iPattern = segmentStart; // mismatch - restart current segment
+			iName = ++prefixStart;
+			previous = previousSegment;
+			continue checkSegment;
+		}
+		/* segment is ending */
+		if ((patternChar = pattern.charAt(iPattern)) == '*') {
+			segmentStart = ++iPattern; // skip star
+			if (segmentStart == patternEnd) {
+				if (count < (parts*2)) {
+					segments[count++] = start;
+					segments[count++] = iName-start;
+				}
+				return segments;
+			}
+			switch (previous) {
+				case '*':
+				case '?':
+					break;
+				default:
+					segments[count++] = start;
+					segments[count++] = iName-start;
+					break;
+			}
+			prefixStart = iName;
+			start = prefixStart;
+			previous = patternChar;
+			previousSegment = patternChar;
+			continue checkSegment;
+		}
+		/* check current name character */
+		previousCount = count;
+		if (patternChar == '?') {
+			switch (previous) {
+				case '*':
+				case '?':
+					break;
+				default:
+					segments[count++] = start;
+					segments[count++] = iName-start;
+					break;
+			}
+		} else {
+			boolean mismatch;
+			if (isCaseSensitive) {
+				mismatch = name.charAt(iName) != patternChar;
+			} else {
+				mismatch = ScannerHelper.toLowerCase(name.charAt(iName)) != ScannerHelper.toLowerCase(patternChar);
+			}
+			if (mismatch) {
+				iPattern = segmentStart; // mismatch - restart current segment
+				iName = ++prefixStart;
+				start = prefixStart;
+				count = previousCount;
+				previous = previousSegment;
+				continue checkSegment;
+			}
+			switch (previous) {
+				case '?':
+					start = iName;
+					break;
+			}
+		}
+		iName++;
+		iPattern++;
+		previous = patternChar;
+	}
+
+	if ((segmentStart == patternEnd)
+		|| (iName == nameEnd && iPattern == patternEnd)
+		|| (iPattern == patternEnd - 1 && pattern.charAt(iPattern) == '*')) {
+		if (count < (parts*2)) {
+			segments[count++] = start;
+			segments[count++] = iName-start;
+		}
+		return segments;
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java
new file mode 100644
index 0000000..8b8c0e7
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.index.Index;
+
+public class SubTypeSearchJob extends PatternSearchJob {
+
+SimpleSet indexes = new SimpleSet(5);
+
+public SubTypeSearchJob(SearchPattern pattern, SearchParticipant participant, IJavaSearchScope scope, IndexQueryRequestor requestor) {
+	super(pattern, participant, scope, requestor);
+}
+public void finished() {
+	Object[] values = this.indexes.values;
+	for (int i = 0, l = values.length; i < l; i++)
+		if (values[i] != null)
+			((Index) values[i]).stopQuery();
+}
+public Index[] getIndexes(IProgressMonitor progressMonitor) {
+	if (this.indexes.elementSize == 0) {
+		return super.getIndexes(progressMonitor);
+	}
+	this.areIndexesReady = true; // use stored indexes until the job's end
+	Index[] values = new Index[this.indexes.elementSize];
+	this.indexes.asArray(values);
+	return values;
+}
+public boolean search(Index index, IProgressMonitor progressMonitor) {
+	if (index == null) return COMPLETE;
+	if (this.indexes.addIfNotIncluded(index) == index)
+		index.startQuery();
+	return super.search(index, progressMonitor);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameMatchRequestorWrapper.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameMatchRequestorWrapper.java
new file mode 100644
index 0000000..81a74da
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameMatchRequestorWrapper.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 215139
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
+import org.eclipse.jdt.core.search.TypeNameRequestor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.core.Openable;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jdt.internal.core.util.HandleFactory;
+import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+
+/**
+ * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
+ * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
+ * 	char[] packageName,
+ * 	int packageMatchRule,
+ * 	char[] typeName,
+ * 	int typeMatchRule,
+ * 	int searchFor,
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope,
+ * 	IRestrictedAccessTypeRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
+ * from  API method {@link org.eclipse.jdt.core.search.SearchEngine#searchAllTypeNames(
+ * 	char[] packageName,
+ * 	int packageMatchRule,
+ * 	char[] typeName,
+ * 	int matchRule,
+ * 	int searchFor,
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope,
+ * 	TypeNameRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
+ */
+public class TypeNameMatchRequestorWrapper implements IRestrictedAccessTypeRequestor {
+	TypeNameMatchRequestor requestor;
+	private IJavaSearchScope scope; // scope is needed to retrieve project path for external resource
+	private HandleFactory handleFactory; // in case of IJavaSearchScope defined by clients, use an HandleFactory instead
+
+	/**
+	 * Cache package fragment root information to optimize speed performance.
+	 */
+	private String lastPkgFragmentRootPath;
+	private IPackageFragmentRoot lastPkgFragmentRoot;
+
+	/**
+	 * Cache package handles to optimize memory.
+	 */
+	private HashtableOfArrayToObject packageHandles;
+	private Object lastProject;
+	private long complianceValue;
+
+public TypeNameMatchRequestorWrapper(TypeNameMatchRequestor requestor, IJavaSearchScope scope) {
+	this.requestor = requestor;
+	this.scope = scope;
+	if (!(scope instanceof AbstractJavaSearchScope)) {
+		this.handleFactory = new HandleFactory();
+	}
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor#acceptType(int, char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
+ */
+public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+
+	// Get type
+	try {
+		IType type = null;
+		if (this.handleFactory != null) {
+			Openable openable = this.handleFactory.createOpenable(path, this.scope);
+			if (openable == null) return;
+			switch (openable.getElementType()) {
+				case IJavaElement.COMPILATION_UNIT:
+					ICompilationUnit cu = (ICompilationUnit) openable;
+					if (enclosingTypeNames != null && enclosingTypeNames.length > 0) {
+						type = cu.getType(new String(enclosingTypeNames[0]));
+						for (int j=1, l=enclosingTypeNames.length; j<l; j++) {
+							type = type.getType(new String(enclosingTypeNames[j]));
+						}
+						type = type.getType(new String(simpleTypeName));
+					} else {
+						type = cu.getType(new String(simpleTypeName));
+					}
+					break;
+				case IJavaElement.CLASS_FILE:
+					type = ((IClassFile)openable).getType();
+					break;
+			}
+		} else {
+			int separatorIndex= path.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
+			type = separatorIndex == -1
+				? createTypeFromPath(path, new String(simpleTypeName), enclosingTypeNames)
+				: createTypeFromJar(path, separatorIndex);
+		}
+
+		// Accept match if the type has been found
+		if (type != null) {
+			// hierarchy scopes require one more check:
+			if (!(this.scope instanceof HierarchyScope) || ((HierarchyScope)this.scope).enclosesFineGrained(type)) {
+
+				// Create the match
+				final JavaSearchTypeNameMatch match = new JavaSearchTypeNameMatch(type, modifiers);
+
+				// Update match accessibility
+				if(access != null) {
+					switch (access.getProblemId()) {
+						case IProblem.ForbiddenReference:
+							match.setAccessibility(IAccessRule.K_NON_ACCESSIBLE);
+							break;
+						case IProblem.DiscouragedReference:
+							match.setAccessibility(IAccessRule.K_DISCOURAGED);
+							break;
+					}
+				}
+
+				// Accept match
+				this.requestor.acceptTypeNameMatch(match);
+			}
+		}
+	} catch (JavaModelException e) {
+		// skip
+	}
+}
+private IType createTypeFromJar(String resourcePath, int separatorIndex) throws JavaModelException {
+	// path to a class file inside a jar
+	// Optimization: cache package fragment root handle and package handles
+	if (this.lastPkgFragmentRootPath == null
+			|| this.lastPkgFragmentRootPath.length() > resourcePath.length()
+			|| !resourcePath.startsWith(this.lastPkgFragmentRootPath)) {
+		String jarPath= resourcePath.substring(0, separatorIndex);
+		IPackageFragmentRoot root= ((AbstractJavaSearchScope)this.scope).packageFragmentRoot(resourcePath, separatorIndex, jarPath);
+		if (root == null) return null;
+		this.lastPkgFragmentRootPath= jarPath;
+		this.lastPkgFragmentRoot= root;
+		this.packageHandles= new HashtableOfArrayToObject(5);
+	}
+	// create handle
+	String classFilePath= resourcePath.substring(separatorIndex + 1);
+	String[] simpleNames = new Path(classFilePath).segments();
+	String[] pkgName;
+	int length = simpleNames.length-1;
+	if (length > 0) {
+		pkgName = new String[length];
+		System.arraycopy(simpleNames, 0, pkgName, 0, length);
+	} else {
+		pkgName = CharOperation.NO_STRINGS;
+	}
+	IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
+	if (pkgFragment == null) {
+		pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName);
+		// filter org.apache.commons.lang.enum package for projects above 1.5 
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264
+		if (length == 5 && pkgName[4].equals("enum")) { //$NON-NLS-1$
+			IJavaProject proj = (IJavaProject)pkgFragment.getAncestor(IJavaElement.JAVA_PROJECT);
+			if (!proj.equals(this.lastProject)) {
+				String complianceStr = proj.getOption(CompilerOptions.OPTION_Source, true);
+				this.complianceValue = CompilerOptions.versionToJdkLevel(complianceStr);
+				this.lastProject = proj;
+			}
+			if (this.complianceValue >= ClassFileConstants.JDK1_5)
+				return null;
+		} 
+		this.packageHandles.put(pkgName, pkgFragment);
+	}
+	return pkgFragment.getClassFile(simpleNames[length]).getType();
+}
+private IType createTypeFromPath(String resourcePath, String simpleTypeName, char[][] enclosingTypeNames) throws JavaModelException {
+	// path to a file in a directory
+	// Optimization: cache package fragment root handle and package handles
+	int rootPathLength = -1;
+	if (this.lastPkgFragmentRootPath == null
+		|| !(resourcePath.startsWith(this.lastPkgFragmentRootPath)
+			&& (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0
+			&& resourcePath.charAt(rootPathLength) == '/')) {
+		PackageFragmentRoot root = (PackageFragmentRoot) ((AbstractJavaSearchScope)this.scope).packageFragmentRoot(resourcePath, -1/*not a jar*/, null/*no jar path*/);
+		if (root == null) return null;
+		this.lastPkgFragmentRoot = root;
+		this.lastPkgFragmentRootPath = root.internalPath().toString();
+		this.packageHandles = new HashtableOfArrayToObject(5);
+	}
+	// create handle
+	resourcePath = resourcePath.substring(this.lastPkgFragmentRootPath.length() + 1);
+	String[] simpleNames = new Path(resourcePath).segments();
+	String[] pkgName;
+	int length = simpleNames.length-1;
+	if (length > 0) {
+		pkgName = new String[length];
+		System.arraycopy(simpleNames, 0, pkgName, 0, length);
+	} else {
+		pkgName = CharOperation.NO_STRINGS;
+	}
+	IPackageFragment pkgFragment= (IPackageFragment) this.packageHandles.get(pkgName);
+	if (pkgFragment == null) {
+		pkgFragment= ((PackageFragmentRoot) this.lastPkgFragmentRoot).getPackageFragment(pkgName);
+		this.packageHandles.put(pkgName, pkgFragment);
+	}
+	String simpleName= simpleNames[length];
+	if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(simpleName)) {
+		ICompilationUnit unit= pkgFragment.getCompilationUnit(simpleName);
+		int etnLength = enclosingTypeNames == null ? 0 : enclosingTypeNames.length;
+		IType type = (etnLength == 0) ? unit.getType(simpleTypeName) : unit.getType(new String(enclosingTypeNames[0]));
+		if (etnLength > 0) {
+			for (int i=1; i<etnLength; i++) {
+				type = type.getType(new String(enclosingTypeNames[i]));
+			}
+			type = type.getType(simpleTypeName);
+		}
+		return type;
+	} else if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(simpleName)){
+		IClassFile classFile= pkgFragment.getClassFile(simpleName);
+		return classFile.getType();
+	}
+	return null;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java
new file mode 100644
index 0000000..31a4527
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search;
+
+import org.eclipse.jdt.core.search.TypeNameRequestor;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+
+/**
+ * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
+ * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
+ * 	char[] packageName,
+ * 	int packageMatchRule,
+ * 	char[] typeName,
+ * 	int typeMatchRule,
+ * 	int searchFor,
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope,
+ * 	IRestrictedAccessTypeRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
+ * from  API method {@link org.eclipse.jdt.core.search.SearchEngine#searchAllTypeNames(
+ * 	char[] packageName,
+ * 	int packageMatchRule,
+ * 	char[] typeName,
+ * 	int matchRule,
+ * 	int searchFor,
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope,
+ * 	TypeNameRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
+ */
+public class TypeNameRequestorWrapper implements IRestrictedAccessTypeRequestor {
+	TypeNameRequestor requestor;
+	public TypeNameRequestorWrapper(TypeNameRequestor requestor) {
+		this.requestor = requestor;
+	}
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+		this.requestor.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
new file mode 100644
index 0000000..242a331
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.search.matching.*;
+
+public abstract class AbstractIndexer implements IIndexConstants {
+
+	SearchDocument document;
+
+	public AbstractIndexer(SearchDocument document) {
+		this.document = document;
+	}
+	public void addAnnotationTypeDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, boolean secondary) {
+		addTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, secondary);
+
+		addIndexEntry(
+			SUPER_REF,
+			SuperTypeReferencePattern.createIndexKey(
+				modifiers, packageName, name, enclosingTypeNames, null, ANNOTATION_TYPE_SUFFIX, CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_ANNOTATION, '.'), ANNOTATION_TYPE_SUFFIX));
+	}
+	public void addAnnotationTypeReference(char[] typeName) {
+		addIndexEntry(ANNOTATION_REF, CharOperation.lastSegment(typeName, '.'));
+	}
+	public void addClassDeclaration(
+			int modifiers,
+			char[] packageName,
+			char[] name,
+			char[][] enclosingTypeNames,
+			char[] superclass,
+			char[][] superinterfaces,
+			char[][] typeParameterSignatures,
+			boolean secondary) {
+		addTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, secondary);
+
+		if (superclass != null) {
+			superclass = erasure(superclass);
+			addTypeReference(superclass);
+		}
+		addIndexEntry(
+			SUPER_REF,
+			SuperTypeReferencePattern.createIndexKey(
+				modifiers, packageName, name, enclosingTypeNames, typeParameterSignatures, CLASS_SUFFIX, superclass, CLASS_SUFFIX));
+		if (superinterfaces != null) {
+			for (int i = 0, max = superinterfaces.length; i < max; i++) {
+				char[] superinterface = erasure(superinterfaces[i]);
+				addTypeReference(superinterface);
+				addIndexEntry(
+					SUPER_REF,
+					SuperTypeReferencePattern.createIndexKey(
+						modifiers, packageName, name, enclosingTypeNames, typeParameterSignatures, CLASS_SUFFIX, superinterface, INTERFACE_SUFFIX));
+			}
+		}
+	}
+	private char[] erasure(char[] typeName) {
+		int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, typeName);
+		if (genericStart > -1)
+			typeName = CharOperation.subarray(typeName, 0, genericStart);
+		return typeName;
+	}
+	public void addConstructorDeclaration(
+			char[] typeName,
+			int argCount,
+			char[] signature,
+			char[][] parameterTypes,
+			char[][] parameterNames,
+			int modifiers,
+			char[] packageName,
+			int typeModifiers,
+			char[][] exceptionTypes,
+			int extraFlags) {
+		addIndexEntry(
+				CONSTRUCTOR_DECL,
+				ConstructorPattern.createDeclarationIndexKey(
+						typeName,
+						argCount,
+						signature,
+						parameterTypes,
+						parameterNames,
+						modifiers,
+						packageName,
+						typeModifiers,
+						extraFlags));
+		
+		if (parameterTypes != null) {
+			for (int i = 0; i < argCount; i++)
+				addTypeReference(parameterTypes[i]);
+		}
+		if (exceptionTypes != null)
+			for (int i = 0, max = exceptionTypes.length; i < max; i++)
+				addTypeReference(exceptionTypes[i]);
+	}
+	public void addConstructorReference(char[] typeName, int argCount) {
+		char[] simpleTypeName = CharOperation.lastSegment(typeName,'.');
+		addTypeReference(simpleTypeName);
+		addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(simpleTypeName, argCount));
+		char[] innermostTypeName = CharOperation.lastSegment(simpleTypeName,'$');
+		if (innermostTypeName != simpleTypeName)
+			addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(innermostTypeName, argCount));
+	}
+	public void addDefaultConstructorDeclaration(
+			char[] typeName,
+			char[] packageName,
+			int typeModifiers,
+			int extraFlags) {
+		addIndexEntry(CONSTRUCTOR_DECL, ConstructorPattern.createDefaultDeclarationIndexKey(CharOperation.lastSegment(typeName,'.'), packageName, typeModifiers, extraFlags));
+	}
+	public void addEnumDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[] superclass, char[][] superinterfaces, boolean secondary) {
+		addTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, secondary);
+
+		addIndexEntry(
+			SUPER_REF,
+			SuperTypeReferencePattern.createIndexKey(
+				modifiers, packageName, name, enclosingTypeNames, null, ENUM_SUFFIX, superclass, CLASS_SUFFIX));
+		if (superinterfaces != null) {
+			for (int i = 0, max = superinterfaces.length; i < max; i++) {
+				char[] superinterface = erasure(superinterfaces[i]);
+				addTypeReference(superinterface);
+				addIndexEntry(
+					SUPER_REF,
+					SuperTypeReferencePattern.createIndexKey(
+						modifiers, packageName, name, enclosingTypeNames, null, ENUM_SUFFIX, superinterface, INTERFACE_SUFFIX));
+			}
+		}
+	}
+	public void addFieldDeclaration(char[] typeName, char[] fieldName) {
+		addIndexEntry(FIELD_DECL, FieldPattern.createIndexKey(fieldName));
+		addTypeReference(typeName);
+	}
+	public void addFieldReference(char[] fieldName) {
+		addNameReference(fieldName);
+	}
+	protected void addIndexEntry(char[] category, char[] key) {
+		this.document.addIndexEntry(category, key);
+	}
+	public void addInterfaceDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[][] superinterfaces, char[][] typeParameterSignatures, boolean secondary) {
+		addTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, secondary);
+
+		if (superinterfaces != null) {
+			for (int i = 0, max = superinterfaces.length; i < max; i++) {
+				char[] superinterface = erasure(superinterfaces[i]);
+				addTypeReference(superinterface);
+				addIndexEntry(
+					SUPER_REF,
+					SuperTypeReferencePattern.createIndexKey(
+						modifiers, packageName, name, enclosingTypeNames, typeParameterSignatures, INTERFACE_SUFFIX, superinterface, INTERFACE_SUFFIX));
+			}
+		}
+	}
+	public void addMethodDeclaration(char[] methodName, char[][] parameterTypes, char[] returnType, char[][] exceptionTypes) {
+		int argCount = parameterTypes == null ? 0 : parameterTypes.length;
+		addIndexEntry(METHOD_DECL, MethodPattern.createIndexKey(methodName, argCount));
+
+		if (parameterTypes != null) {
+			for (int i = 0; i < argCount; i++)
+				addTypeReference(parameterTypes[i]);
+		}
+		if (exceptionTypes != null)
+			for (int i = 0, max = exceptionTypes.length; i < max; i++)
+				addTypeReference(exceptionTypes[i]);
+		if (returnType != null)
+			addTypeReference(returnType);
+	}
+	public void addMethodReference(char[] methodName, int argCount) {
+		addIndexEntry(METHOD_REF, MethodPattern.createIndexKey(methodName, argCount));
+	}
+	public void addNameReference(char[] name) {
+		addIndexEntry(REF, name);
+	}
+	protected void addTypeDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, boolean secondary) {
+		char[] indexKey = TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames, secondary);
+		if (secondary)
+			JavaModelManager.getJavaModelManager().secondaryTypeAdding(
+				this.document.getPath(),
+				name == null ? CharOperation.NO_CHAR : name,
+				packageName == null ? CharOperation.NO_CHAR : packageName);
+
+		addIndexEntry(TYPE_DECL, indexKey);
+	}
+	public void addTypeReference(char[] typeName) {
+		addNameReference(CharOperation.lastSegment(typeName, '.'));
+	}
+	public abstract void indexDocument();
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
new file mode 100644
index 0000000..a250f0b
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+class AddFolderToIndex extends IndexRequest {
+	IPath folderPath;
+	IProject project;
+	char[][] inclusionPatterns;
+	char[][] exclusionPatterns;
+
+	public AddFolderToIndex(IPath folderPath, IProject project, char[][] inclusionPatterns, char[][] exclusionPatterns, IndexManager manager) {
+		super(project.getFullPath(), manager);
+		this.folderPath = folderPath;
+		this.project = project;
+		this.inclusionPatterns = inclusionPatterns;
+		this.exclusionPatterns = exclusionPatterns;
+	}
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+		if (!this.project.isAccessible()) return true; // nothing to do
+		IResource folder = this.project.getParent().findMember(this.folderPath);
+		if (folder == null || folder.getType() == IResource.FILE) return true; // nothing to do, source folder was removed
+
+		/* ensure no concurrent write access to index */
+		Index index = this.manager.getIndex(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+		if (index == null) return true;
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) return true; // index got deleted since acquired
+
+		try {
+			monitor.enterRead(); // ask permission to read
+
+			final IPath container = this.containerPath;
+			final IndexManager indexManager = this.manager;
+			final SourceElementParser parser = indexManager.getSourceElementParser(JavaCore.create(this.project), null/*requestor will be set by indexer*/);
+			if (this.exclusionPatterns == null && this.inclusionPatterns == null) {
+				folder.accept(
+					new IResourceProxyVisitor() {
+						public boolean visit(IResourceProxy proxy) /* throws CoreException */{
+							if (proxy.getType() == IResource.FILE) {
+								if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName()))
+									indexManager.addSource((IFile) proxy.requestResource(), container, parser);
+								return false;
+							}
+							return true;
+						}
+					},
+					IResource.NONE
+				);
+			} else {
+				folder.accept(
+					new IResourceProxyVisitor() {
+						public boolean visit(IResourceProxy proxy) /* throws CoreException */{
+							switch(proxy.getType()) {
+								case IResource.FILE :
+									if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+										IResource resource = proxy.requestResource();
+										if (!Util.isExcluded(resource, AddFolderToIndex.this.inclusionPatterns, AddFolderToIndex.this.exclusionPatterns))
+											indexManager.addSource((IFile)resource, container, parser);
+									}
+									return false;
+								case IResource.FOLDER :
+									if (AddFolderToIndex.this.exclusionPatterns != null && AddFolderToIndex.this.inclusionPatterns == null) {
+										// if there are inclusion patterns then we must walk the children
+										if (Util.isExcluded(proxy.requestFullPath(), AddFolderToIndex.this.inclusionPatterns, AddFolderToIndex.this.exclusionPatterns, true))
+										    return false;
+									}
+							}
+							return true;
+						}
+					},
+					IResource.NONE
+				);
+			}
+		} catch (CoreException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to add " + this.folderPath + " to index because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			return false;
+		} finally {
+			monitor.exitRead(); // free read lock
+		}
+		return true;
+	}
+	public String toString() {
+		return "adding " + this.folderPath + " to index " + this.containerPath; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
new file mode 100644
index 0000000..42f0bb4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+
+class AddJarFileToIndex extends IndexRequest {
+
+	private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0);
+	IFile resource;
+	Scanner scanner;
+	private IndexLocation indexFileURL;
+	private final boolean forceIndexUpdate;
+
+	public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) {
+		this(resource, indexFile, manager, false);
+	}
+	public AddJarFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
+		super(resource.getFullPath(), manager);
+		this.resource = resource;
+		this.indexFileURL = indexFile;
+		this.forceIndexUpdate = updateIndex;
+	}
+	public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager) {
+		this(jarPath, indexFile, manager, false);
+	}
+	public AddJarFileToIndex(IPath jarPath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
+		// external JAR scenario - no resource
+		super(jarPath, manager);
+		this.indexFileURL = indexFile;
+		this.forceIndexUpdate = updateIndex;
+	}
+	public boolean equals(Object o) {
+		if (o instanceof AddJarFileToIndex) {
+			if (this.resource != null)
+				return this.resource.equals(((AddJarFileToIndex) o).resource);
+			if (this.containerPath != null)
+				return this.containerPath.equals(((AddJarFileToIndex) o).containerPath);
+		}
+		return false;
+	}
+	public int hashCode() {
+		if (this.resource != null)
+			return this.resource.hashCode();
+		if (this.containerPath != null)
+			return this.containerPath.hashCode();
+		return -1;
+	}
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+		if (hasPreBuiltIndex()) {
+			boolean added = this.manager.addIndex(this.containerPath, this.indexFileURL);
+			if (added) return true;	
+			this.indexFileURL = null;
+		}
+
+		try {
+			// if index is already cached, then do not perform any check
+			// MUST reset the IndexManager if a jar file is changed
+			Index index = this.manager.getIndexForUpdate(this.containerPath, false, /*do not reuse index file*/ false /*do not create if none*/);
+			if (index != null) {
+				if (JobManager.VERBOSE)
+					org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index already exists) for " + this.containerPath); //$NON-NLS-1$
+				return true;
+			}
+
+			index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+			if (index == null) {
+				if (JobManager.VERBOSE)
+					org.eclipse.jdt.internal.core.util.Util.verbose("-> index could not be created for " + this.containerPath); //$NON-NLS-1$
+				return true;
+			}
+			ReadWriteMonitor monitor = index.monitor;
+			if (monitor == null) {
+				if (JobManager.VERBOSE)
+					org.eclipse.jdt.internal.core.util.Util.verbose("-> index for " + this.containerPath + " just got deleted"); //$NON-NLS-1$//$NON-NLS-2$
+				return true; // index got deleted since acquired
+			}
+			index.separator = JAR_SEPARATOR;
+			ZipFile zip = null;
+			try {
+				// this path will be a relative path to the workspace in case the zipfile in the workspace otherwise it will be a path in the
+				// local file system
+				Path zipFilePath = null;
+
+				monitor.enterWrite(); // ask permission to write
+				if (this.resource != null) {
+					URI location = this.resource.getLocationURI();
+					if (location == null) return false;
+					if (JavaModelManager.ZIP_ACCESS_VERBOSE)
+						System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$	//$NON-NLS-2$
+					File file = null;
+					try {
+						file = org.eclipse.jdt.internal.core.util.Util.toLocalFile(location, progressMonitor);
+					} catch (CoreException e) {
+						if (JobManager.VERBOSE) {
+							org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+							e.printStackTrace();
+						}
+					}
+					if (file == null) {
+						if (JobManager.VERBOSE)
+							org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + location.getPath() + " because the file could not be fetched"); //$NON-NLS-1$ //$NON-NLS-2$
+						return false;
+					}
+					zip = new ZipFile(file);
+					zipFilePath = (Path) this.resource.getFullPath().makeRelative();
+					// absolute path relative to the workspace
+				} else {
+					if (JavaModelManager.ZIP_ACCESS_VERBOSE)
+						System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Creating ZipFile on " + this.containerPath); //$NON-NLS-1$	//$NON-NLS-2$
+					// external file -> it is ok to use toFile()
+					zip = new ZipFile(this.containerPath.toFile());
+					zipFilePath = (Path) this.containerPath;
+					// path is already canonical since coming from a library classpath entry
+				}
+
+				if (this.isCancelled) {
+					if (JobManager.VERBOSE)
+						org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$
+					return false;
+				}
+
+				if (JobManager.VERBOSE)
+					org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing " + zip.getName()); //$NON-NLS-1$
+				long initialTime = System.currentTimeMillis();
+
+				String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$
+				if (paths != null) {
+					int max = paths.length;
+					/* check integrity of the existing index file
+					 * if the length is equal to 0, we want to index the whole jar again
+					 * If not, then we want to check that there is no missing entry, if
+					 * one entry is missing then we recreate the index
+					 */
+					String EXISTS = "OK"; //$NON-NLS-1$
+					String DELETED = "DELETED"; //$NON-NLS-1$
+					SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11);
+					for (int i = 0; i < max; i++)
+						indexedFileNames.put(paths[i], DELETED);
+					for (Enumeration e = zip.entries(); e.hasMoreElements();) {
+						// iterate each entry to index it
+						ZipEntry ze = (ZipEntry) e.nextElement();
+						String zipEntryName = ze.getName();
+						if (Util.isClassFileName(zipEntryName) && isValidPackageNameForClass(zipEntryName))
+								// the class file may not be there if the package name is not valid
+							indexedFileNames.put(zipEntryName, EXISTS);
+					}
+					boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added
+					if (!needToReindex) {
+						Object[] valueTable = indexedFileNames.valueTable;
+						for (int i = 0, l = valueTable.length; i < l; i++) {
+							if (valueTable[i] == DELETED) {
+								needToReindex = true; // a file was deleted so re-index
+								break;
+							}
+						}
+						if (!needToReindex) {
+							if (JobManager.VERBOSE)
+								org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$
+								+ zip.getName() + " (" //$NON-NLS-1$
+								+ (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$
+							this.manager.saveIndex(index); // to ensure its placed into the saved state
+							return true;
+						}
+					}
+				}
+
+				// Index the jar for the first time or reindex the jar in case the previous index file has been corrupted
+				// index already existed: recreate it so that we forget about previous entries
+				SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
+				if (!this.manager.resetIndex(this.containerPath)) {
+					// failed to recreate index, see 73330
+					this.manager.removeIndex(this.containerPath);
+					return false;
+				}
+				index.separator = JAR_SEPARATOR;
+				IPath indexPath = null;
+				IndexLocation indexLocation;
+				if ((indexLocation = index.getIndexLocation()) != null) {
+					indexPath = new Path(indexLocation.getCanonicalFilePath());
+				}
+				for (Enumeration e = zip.entries(); e.hasMoreElements();) {
+					if (this.isCancelled) {
+						if (JobManager.VERBOSE)
+							org.eclipse.jdt.internal.core.util.Util.verbose("-> indexing of " + zip.getName() + " has been cancelled"); //$NON-NLS-1$ //$NON-NLS-2$
+						return false;
+					}
+
+					// iterate each entry to index it
+					ZipEntry ze = (ZipEntry) e.nextElement();
+					String zipEntryName = ze.getName();
+					if (Util.isClassFileName(zipEntryName) && 
+							isValidPackageNameForClass(zipEntryName)) {
+						// index only classes coming from valid packages - https://bugs.eclipse.org/bugs/show_bug.cgi?id=293861
+						final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
+						JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, classFileBytes, participant);
+						this.manager.indexDocument(entryDocument, participant, index, indexPath);
+					}
+				}
+				this.manager.saveIndex(index);
+				if (JobManager.VERBOSE)
+					org.eclipse.jdt.internal.core.util.Util.verbose("-> done indexing of " //$NON-NLS-1$
+						+ zip.getName() + " (" //$NON-NLS-1$
+						+ (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$
+			} finally {
+				if (zip != null) {
+					if (JavaModelManager.ZIP_ACCESS_VERBOSE)
+						System.out.println("(" + Thread.currentThread() + ") [AddJarFileToIndex.execute()] Closing ZipFile " + zip); //$NON-NLS-1$	//$NON-NLS-2$
+					zip.close();
+				}
+				monitor.exitWrite(); // free write lock
+			}
+		} catch (IOException e) {
+			if (JobManager.VERBOSE) {
+				org.eclipse.jdt.internal.core.util.Util.verbose("-> failed to index " + this.containerPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			this.manager.removeIndex(this.containerPath);
+			return false;
+		}
+		return true;
+	}
+	public String getJobFamily() {
+		if (this.resource != null)
+			return super.getJobFamily();
+		return this.containerPath.toOSString(); // external jar
+	}	
+	private boolean isIdentifier() throws InvalidInputException {
+		switch(this.scanner.scanIdentifier()) {
+			// assert and enum will not be recognized as java identifiers 
+			// in 1.7 mode, which are in 1.3.
+			case TerminalTokens.TokenNameIdentifier:
+			case TerminalTokens.TokenNameassert:
+			case TerminalTokens.TokenNameenum:
+				return true;
+			default:
+				return false;
+		}
+	}
+	private  boolean isValidPackageNameForClass(String className) {
+		char[] classNameArray = className.toCharArray();
+		// use 1.7 as the source level as there are more valid identifiers in 1.7 mode
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=376673
+		if (this.scanner == null)
+			this.scanner = new Scanner(false /* comment */, true /* whitespace */, false /* nls */,
+					ClassFileConstants.JDK1_7/* sourceLevel */, null/* taskTag */, null/* taskPriorities */, true /* taskCaseSensitive */);
+		
+		this.scanner.setSource(classNameArray); 
+		this.scanner.eofPosition = classNameArray.length - SuffixConstants.SUFFIX_CLASS.length;
+		try {
+			if (isIdentifier()) {
+				while (this.scanner.eofPosition > this.scanner.currentPosition) {
+					if (this.scanner.getNextChar() != '/' || this.scanner.eofPosition <= this.scanner.currentPosition) {
+						return false;
+					}
+					if (!isIdentifier()) return false;
+				}
+				return true;
+			}
+		} catch (InvalidInputException e) {
+			// invalid class name
+		}
+		return false;
+	}
+	protected Integer updatedIndexState() {
+
+		Integer updateState = null;
+		if(hasPreBuiltIndex()) {
+			updateState = IndexManager.REUSE_STATE;
+		}
+		else {
+			updateState = IndexManager.REBUILDING_STATE;
+		}
+		return updateState;
+	}
+	public String toString() {
+		return "indexing " + this.containerPath.toString(); //$NON-NLS-1$
+	}
+
+	protected boolean hasPreBuiltIndex() {
+		return !this.forceIndexUpdate && (this.indexFileURL != null && this.indexFileURL.exists());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
new file mode 100644
index 0000000..f752c34
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
@@ -0,0 +1,845 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
+import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
+import org.eclipse.jdt.internal.compiler.env.ClassSignature;
+import org.eclipse.jdt.internal.compiler.env.EnumConstantSignature;
+import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class BinaryIndexer extends AbstractIndexer implements SuffixConstants {
+	private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
+	private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
+	private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
+	private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
+	private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
+	private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
+	private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
+	private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
+	private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+	private static final char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
+
+	public BinaryIndexer(SearchDocument document) {
+		super(document);
+	}
+	private void addBinaryStandardAnnotations(long annotationTagBits) {
+		if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) {
+			return;
+		}
+		if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+			addBinaryTargetAnnotation(annotationTagBits);
+		}
+		if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+			addBinaryRetentionAnnotation(annotationTagBits);
+		}
+		if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationInherited) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationOverride) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) {
+			char[][] compoundName = TypeConstants.JAVA_LANG_SAFEVARARGS;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+		if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+			char[][] compoundName =
+					TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE;
+			addAnnotationTypeReference(compoundName[compoundName.length-1]);
+		}
+	}
+	private void addBinaryTargetAnnotation(long bits) {
+		char[][] compoundName = null;
+		if ((bits & TagBits.AnnotationForAnnotationType) != 0) {
+			compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+			addTypeReference(compoundName[compoundName.length-1]);
+			addFieldReference(TypeConstants.UPPER_ANNOTATION_TYPE);
+		}
+		if ((bits & TagBits.AnnotationForConstructor) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_CONSTRUCTOR);
+		}
+		if ((bits & TagBits.AnnotationForField) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_FIELD);
+		}
+		if ((bits & TagBits.AnnotationForLocalVariable) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_LOCAL_VARIABLE);
+		}
+		if ((bits & TagBits.AnnotationForMethod) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_METHOD);
+		}
+		if ((bits & TagBits.AnnotationForPackage) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_PACKAGE);
+		}
+		if ((bits & TagBits.AnnotationForParameter) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.UPPER_PARAMETER);
+		}
+		if ((bits & TagBits.AnnotationForType) != 0) {
+			if (compoundName == null) {
+				compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
+				addTypeReference(compoundName[compoundName.length-1]);
+			}
+			addFieldReference(TypeConstants.TYPE);
+		}
+	}
+	private void addBinaryRetentionAnnotation(long bits) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY;
+		addTypeReference(compoundName[compoundName.length-1]);
+		if ((bits & TagBits.AnnotationRuntimeRetention) == TagBits.AnnotationRuntimeRetention) {
+			addFieldReference(TypeConstants.UPPER_RUNTIME);
+		} else if ((bits & TagBits.AnnotationClassRetention) != 0) {
+			addFieldReference(TypeConstants.UPPER_CLASS);
+		} else if ((bits & TagBits.AnnotationSourceRetention) != 0) {
+			addFieldReference(TypeConstants.UPPER_SOURCE);
+		}
+	}
+	private void addBinaryAnnotation(IBinaryAnnotation annotation) {
+		addAnnotationTypeReference(replace('/', '.', Signature.toCharArray(annotation.getTypeName())));
+		IBinaryElementValuePair[] valuePairs = annotation.getElementValuePairs();
+		if (valuePairs != null) {
+			for (int j=0, vpLength=valuePairs.length; j<vpLength; j++) {
+				IBinaryElementValuePair valuePair = valuePairs[j];
+				addMethodReference(valuePair.getName(), 0);
+				Object pairValue = valuePair.getValue();
+				addPairValue(pairValue);
+			}
+		}
+	}
+	private void addPairValue(Object pairValue) {
+		if (pairValue instanceof EnumConstantSignature) {
+			EnumConstantSignature enumConstant = (EnumConstantSignature) pairValue;
+			addTypeReference(replace('/', '.', Signature.toCharArray(enumConstant.getTypeName())));
+			addNameReference(enumConstant.getEnumConstantName());
+		} else if (pairValue instanceof ClassSignature) {
+			ClassSignature classConstant = (ClassSignature) pairValue;
+			addTypeReference(replace('/', '.', Signature.toCharArray(classConstant.getTypeName())));
+		} else if (pairValue instanceof IBinaryAnnotation) {
+			addBinaryAnnotation((IBinaryAnnotation) pairValue);
+		} else if (pairValue instanceof Object[]) {
+			Object[] objects = (Object[]) pairValue;
+			for (int i=0,l=objects.length; i<l; i++) {
+				addPairValue(objects[i]);
+			}
+		}
+	}
+	public void addTypeReference(char[] typeName) {
+		int length = typeName.length;
+		if (length > 2 && typeName[length - 2] == '$') {
+			switch (typeName[length - 1]) {
+				case '0' :
+				case '1' :
+				case '2' :
+				case '3' :
+				case '4' :
+				case '5' :
+				case '6' :
+				case '7' :
+				case '8' :
+				case '9' :
+					return; // skip local type names
+			}
+		}
+
+	 	// consider that A$B is a member type: so replace '$' with '.'
+	 	// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40116)
+		typeName = CharOperation.replaceOnCopy(typeName, '$', '.'); // copy it so the original is not modified
+
+		super.addTypeReference(typeName);
+	}
+	/**
+	 * For example:
+	 *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
+	 *   - void foo(int) is (I)V ==> int
+	 */
+	private void convertToArrayType(char[][] parameterTypes, int counter, int arrayDim) {
+		int length = parameterTypes[counter].length;
+		char[] arrayType = new char[length + arrayDim*2];
+		System.arraycopy(parameterTypes[counter], 0, arrayType, 0, length);
+		for (int i = 0; i < arrayDim; i++) {
+			arrayType[length + (i * 2)] = '[';
+			arrayType[length + (i * 2) + 1] = ']';
+		}
+		parameterTypes[counter] = arrayType;
+	}
+	/**
+	 * For example:
+	 *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
+	 *   - void foo(int) is (I)V ==> int
+	 */
+	private char[] convertToArrayType(char[] typeName, int arrayDim) {
+		int length = typeName.length;
+		char[] arrayType = new char[length + arrayDim*2];
+		System.arraycopy(typeName, 0, arrayType, 0, length);
+		for (int i = 0; i < arrayDim; i++) {
+			arrayType[length + (i * 2)] = '[';
+			arrayType[length + (i * 2) + 1] = ']';
+		}
+		return arrayType;
+	}
+	private char[] decodeFieldType(char[] signature) throws ClassFormatException {
+		if (signature == null) return null;
+		int arrayDim = 0;
+		for (int i = 0, max = signature.length; i < max; i++) {
+			switch(signature[i]) {
+				case 'B':
+					if (arrayDim > 0)
+						return convertToArrayType(BYTE, arrayDim);
+					return BYTE;
+
+				case 'C':
+					if (arrayDim > 0)
+						return convertToArrayType(CHAR, arrayDim);
+					return CHAR;
+
+				case 'D':
+					if (arrayDim > 0)
+						return convertToArrayType(DOUBLE, arrayDim);
+					return DOUBLE;
+
+				case 'F':
+					if (arrayDim > 0)
+						return convertToArrayType(FLOAT, arrayDim);
+					return FLOAT;
+
+				case 'I':
+					if (arrayDim > 0)
+					return convertToArrayType(INT, arrayDim);
+					return INT;
+
+				case 'J':
+					if (arrayDim > 0)
+						return convertToArrayType(LONG, arrayDim);
+					return LONG;
+
+				case 'L':
+					int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
+					if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+					if (arrayDim > 0) {
+						return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim);
+					}
+					return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
+
+				case 'S':
+					if (arrayDim > 0)
+						return convertToArrayType(SHORT, arrayDim);
+					return SHORT;
+
+				case 'Z':
+					if (arrayDim > 0)
+						return convertToArrayType(BOOLEAN, arrayDim);
+					return BOOLEAN;
+
+				case 'V':
+					return VOID;
+
+				case '[':
+					arrayDim++;
+					break;
+
+				default:
+					throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+			}
+		}
+		return null;
+	}
+	/**
+	 * For example:
+	 *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
+	 *   - void foo(int) is (I)V ==> int
+	 */
+	private char[][] decodeParameterTypes(char[] signature, boolean firstIsSynthetic) throws ClassFormatException {
+		if (signature == null) return null;
+		int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
+		if (indexOfClosingParen == 1) {
+			// there is no parameter
+			return null;
+		}
+		if (indexOfClosingParen == -1) {
+			throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+		}
+		char[][] parameterTypes = new char[3][];
+		int parameterTypesCounter = 0;
+		int arrayDim = 0;
+		for (int i = 1; i < indexOfClosingParen; i++) {
+			if (parameterTypesCounter == parameterTypes.length) {
+				// resize
+				System.arraycopy(parameterTypes, 0, (parameterTypes = new char[parameterTypesCounter * 2][]), 0, parameterTypesCounter);
+			}
+			switch(signature[i]) {
+				case 'B':
+					parameterTypes[parameterTypesCounter++] = BYTE;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'C':
+					parameterTypes[parameterTypesCounter++] = CHAR;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'D':
+					parameterTypes[parameterTypesCounter++] = DOUBLE;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'F':
+					parameterTypes[parameterTypesCounter++] = FLOAT;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'I':
+					parameterTypes[parameterTypesCounter++] = INT;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'J':
+					parameterTypes[parameterTypesCounter++] = LONG;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'L':
+					int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
+					if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+					if (firstIsSynthetic && parameterTypesCounter == 0) {
+						// skip first synthetic parameter
+						firstIsSynthetic = false;
+					} else {
+						parameterTypes[parameterTypesCounter++] = replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
+						if (arrayDim > 0)
+							convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					}
+					i = indexOfSemiColon;
+					arrayDim = 0;
+					break;
+
+				case 'S':
+					parameterTypes[parameterTypesCounter++] = SHORT;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case 'Z':
+					parameterTypes[parameterTypesCounter++] = BOOLEAN;
+					if (arrayDim > 0)
+						convertToArrayType(parameterTypes, parameterTypesCounter-1, arrayDim);
+					arrayDim = 0;
+					break;
+
+				case '[':
+					arrayDim++;
+					break;
+
+				default:
+					throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+			}
+		}
+		if (parameterTypes.length != parameterTypesCounter) {
+			System.arraycopy(parameterTypes, 0, parameterTypes = new char[parameterTypesCounter][], 0, parameterTypesCounter);
+		}
+		return parameterTypes;
+	}
+	private char[] decodeReturnType(char[] signature) throws ClassFormatException {
+		if (signature == null) return null;
+		int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
+		if (indexOfClosingParen == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+		int arrayDim = 0;
+		for (int i = indexOfClosingParen + 1, max = signature.length; i < max; i++) {
+			switch(signature[i]) {
+				case 'B':
+					if (arrayDim > 0)
+						return convertToArrayType(BYTE, arrayDim);
+					return BYTE;
+
+				case 'C':
+					if (arrayDim > 0)
+						return convertToArrayType(CHAR, arrayDim);
+					return CHAR;
+
+				case 'D':
+					if (arrayDim > 0)
+						return convertToArrayType(DOUBLE, arrayDim);
+					return DOUBLE;
+
+				case 'F':
+					if (arrayDim > 0)
+						return convertToArrayType(FLOAT, arrayDim);
+					return FLOAT;
+
+				case 'I':
+					if (arrayDim > 0)
+						return convertToArrayType(INT, arrayDim);
+					return INT;
+
+				case 'J':
+					if (arrayDim > 0)
+						return convertToArrayType(LONG, arrayDim);
+					return LONG;
+
+				case 'L':
+					int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
+					if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+					if (arrayDim > 0) {
+						return convertToArrayType(replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon)), arrayDim);
+					}
+					return replace('/','.',CharOperation.subarray(signature, i + 1, indexOfSemiColon));
+
+				case 'S':
+					if (arrayDim > 0)
+						return convertToArrayType(SHORT, arrayDim);
+					return SHORT;
+
+				case 'Z':
+					if (arrayDim > 0)
+						return convertToArrayType(BOOLEAN, arrayDim);
+					return BOOLEAN;
+
+				case 'V':
+					return VOID;
+
+				case '[':
+					arrayDim++;
+					break;
+
+				default:
+					throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+			}
+		}
+		return null;
+	}
+	private int extractArgCount(char[] signature, char[] className) throws ClassFormatException {
+		int indexOfClosingParen = CharOperation.lastIndexOf(')', signature);
+		if (indexOfClosingParen == 1) {
+			// there is no parameter
+			return 0;
+		}
+		if (indexOfClosingParen == -1) {
+			throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+		}
+		int parameterTypesCounter = 0;
+		for (int i = 1; i < indexOfClosingParen; i++) {
+			switch(signature[i]) {
+				case 'B':
+				case 'C':
+				case 'D':
+				case 'F':
+				case 'I':
+				case 'J':
+				case 'S':
+				case 'Z':
+					parameterTypesCounter++;
+					break;
+				case 'L':
+					int indexOfSemiColon = CharOperation.indexOf(';', signature, i+1);
+					if (indexOfSemiColon == -1) throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+					// verify if first parameter is synthetic
+					if (className != null && parameterTypesCounter == 0) {
+						char[] classSignature = Signature.createCharArrayTypeSignature(className, true);
+						int length = indexOfSemiColon-i+1;
+						if (classSignature.length > (length+1)) {
+							// synthetic means that parameter type has same signature than given class
+							for (int j=i, k=0; j<indexOfSemiColon; j++, k++) {
+								if (!(signature[j] == classSignature[k] || (signature[j] == '/' && classSignature[k] == '.' ))) {
+									parameterTypesCounter++;
+									break;
+								}
+							}
+						} else {
+							parameterTypesCounter++;
+						}
+						className = null; // do not verify following parameters
+					} else {
+						parameterTypesCounter++;
+					}
+					i = indexOfSemiColon;
+					break;
+				case '[':
+					break;
+				default:
+					throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
+			}
+		}
+		return parameterTypesCounter;
+	}
+	private char[] extractClassName(int[] constantPoolOffsets, ClassFileReader reader, int index) {
+		// the entry at i has to be a field ref or a method/interface method ref.
+		int class_index = reader.u2At(constantPoolOffsets[index] + 1);
+		int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[class_index] + 1)];
+		return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+	}
+	private char[] extractName(int[] constantPoolOffsets, ClassFileReader reader, int index) {
+		int nameAndTypeIndex = reader.u2At(constantPoolOffsets[index] + 3);
+		int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[nameAndTypeIndex] + 1)];
+		return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+	}
+	private char[] extractClassReference(int[] constantPoolOffsets, ClassFileReader reader, int index) {
+		// the entry at i has to be a class ref.
+		int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[index] + 1)];
+		return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+	}
+	/**
+	 * Extract all type, method, field and interface method references from the constant pool
+	 */
+	private void extractReferenceFromConstantPool(byte[] contents, ClassFileReader reader) throws ClassFormatException {
+		int[] constantPoolOffsets = reader.getConstantPoolOffsets();
+		int constantPoolCount = constantPoolOffsets.length;
+		for (int i = 1; i < constantPoolCount; i++) {
+			int tag = reader.u1At(constantPoolOffsets[i]);
+			/**
+			 * u1 tag
+			 * u2 class_index
+			 * u2 name_and_type_index
+			 */
+			char[] name = null;
+			char[] type = null;
+			switch (tag) {
+				case ClassFileConstants.FieldRefTag :
+					// add reference to the class/interface and field name and type
+					name = extractName(constantPoolOffsets, reader, i);
+					addFieldReference(name);
+					break;
+				case ClassFileConstants.MethodRefTag :
+					// add reference to the class and method name and type
+				case ClassFileConstants.InterfaceMethodRefTag :
+					// add reference to the interface and method name and type
+					name = extractName(constantPoolOffsets, reader, i);
+					type = extractType(constantPoolOffsets, reader, i);
+					if (CharOperation.equals(INIT, name)) {
+						// get class name and see if it's a local type or not
+						char[] className = extractClassName(constantPoolOffsets, reader, i);
+						boolean localType = false;
+						if (className !=  null) {
+							for (int c = 0, max = className.length; c < max; c++) {
+								switch (className[c]) {
+									case '/':
+										className[c] = '.';
+										break;
+									case '$':
+										localType = true;
+										break;
+								}
+							}
+						}
+						// add a constructor reference, use class name to extract arg count if it's a local type to remove synthetic parameter
+						addConstructorReference(className, extractArgCount(type, localType?className:null));
+					} else {
+						// add a method reference
+						addMethodReference(name, extractArgCount(type, null));
+					}
+					break;
+				case ClassFileConstants.ClassTag :
+					// add a type reference
+					name = extractClassReference(constantPoolOffsets, reader, i);
+					if (name.length > 0 && name[0] == '[')
+						break; // skip over array references
+					name = replace('/', '.', name); // so that it looks like java.lang.String
+					addTypeReference(name);
+
+					// also add a simple reference on each segment of the qualification (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=24741)
+					char[][] qualification = CharOperation.splitOn('.', name);
+					for (int j = 0, length = qualification.length; j < length; j++) {
+						addNameReference(qualification[j]);
+					}
+					break;
+			}
+		}
+	}
+	private char[] extractType(int[] constantPoolOffsets, ClassFileReader reader, int index) {
+		int constantPoolIndex = reader.u2At(constantPoolOffsets[index] + 3);
+		int utf8Offset = constantPoolOffsets[reader.u2At(constantPoolOffsets[constantPoolIndex] + 3)];
+		return reader.utf8At(utf8Offset + 3, reader.u2At(utf8Offset + 1));
+	}
+	public void indexDocument() {
+		try {
+			final byte[] contents = this.document.getByteContents();
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=107124
+			// contents can potentially be null if a IOException occurs while retrieving the contents
+			if (contents == null) return;
+			final String path = this.document.getPath();
+			ClassFileReader reader = new ClassFileReader(contents, path == null ? null : path.toCharArray());
+
+			// first add type references
+			char[] className = replace('/', '.', reader.getName()); // looks like java/lang/String
+			// need to extract the package name and the simple name
+			int packageNameIndex = CharOperation.lastIndexOf('.', className);
+			char[] packageName = null;
+			char[] name = null;
+			if (packageNameIndex >= 0) {
+				packageName = CharOperation.subarray(className, 0, packageNameIndex);
+				name = CharOperation.subarray(className, packageNameIndex + 1, className.length);
+			} else {
+				packageName = CharOperation.NO_CHAR;
+				name = className;
+			}
+			char[] enclosingTypeName = null;
+			boolean isNestedType = reader.isNestedType();
+			if (isNestedType) {
+				if (reader.isAnonymous()) {
+					name = CharOperation.NO_CHAR;
+				} else {
+					name = reader.getInnerSourceName();
+				}
+				if (reader.isLocal() || reader.isAnonymous()) {
+					// set specific ['0'] value for local and anonymous to be able to filter them
+					enclosingTypeName = ONE_ZERO;
+				} else {
+					char[] fullEnclosingName = reader.getEnclosingTypeName();
+					int nameLength = fullEnclosingName.length - packageNameIndex - 1;
+					if (nameLength <= 0) {
+						// See PR 1GIR345: ITPJCORE:ALL - Indexer: NegativeArraySizeException
+						return;
+					}
+					enclosingTypeName = new char[nameLength];
+					System.arraycopy(fullEnclosingName, packageNameIndex + 1, enclosingTypeName, 0, nameLength);
+				}
+			}
+			// type parameters
+			char[][] typeParameterSignatures = null;
+			char[] genericSignature = reader.getGenericSignature();
+			if (genericSignature != null) {
+				CharOperation.replace(genericSignature, '/', '.');
+				typeParameterSignatures = Signature.getTypeParameters(genericSignature);
+			}
+
+			// eliminate invalid innerclasses (1G4KCF7)
+			if (name == null) return;
+
+			char[][] superinterfaces = replace('/', '.', reader.getInterfaceNames());
+			char[][] enclosingTypeNames = enclosingTypeName == null ? null : new char[][] {enclosingTypeName};
+			int modifiers = reader.getModifiers();
+			switch (TypeDeclaration.kind(modifiers)) {
+				case TypeDeclaration.CLASS_DECL :
+					char[] superclass = replace('/', '.', reader.getSuperclassName());
+					addClassDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, typeParameterSignatures, false);
+					break;
+				case TypeDeclaration.INTERFACE_DECL :
+					addInterfaceDeclaration(modifiers, packageName, name, enclosingTypeNames, superinterfaces, typeParameterSignatures, false);
+					break;
+				case TypeDeclaration.ENUM_DECL :
+					superclass = replace('/', '.', reader.getSuperclassName());
+					addEnumDeclaration(modifiers, packageName, name, enclosingTypeNames, superclass, superinterfaces, false);
+					break;
+				case TypeDeclaration.ANNOTATION_TYPE_DECL :
+					addAnnotationTypeDeclaration(modifiers, packageName, name, enclosingTypeNames, false);
+					break;
+			}
+
+			// Look for references in class annotations
+			IBinaryAnnotation[] annotations = reader.getAnnotations();
+			if (annotations != null) {
+				for (int a=0, length=annotations.length; a<length; a++) {
+					IBinaryAnnotation annotation = annotations[a];
+					addBinaryAnnotation(annotation);
+				}
+			}
+			long tagBits = reader.getTagBits() & TagBits.AllStandardAnnotationsMask;
+			if (tagBits != 0) {
+				addBinaryStandardAnnotations(tagBits);
+			}
+			
+			int extraFlags = ExtraFlags.getExtraFlags(reader);
+
+			// first reference all methods declarations and field declarations
+			MethodInfo[] methods = (MethodInfo[]) reader.getMethods();
+			boolean noConstructor = true;
+			if (methods != null) {
+				for (int i = 0, max = methods.length; i < max; i++) {
+					MethodInfo method = methods[i];
+					boolean isConstructor = method.isConstructor();
+					char[] descriptor = method.getMethodDescriptor();
+					char[][] parameterTypes = decodeParameterTypes(descriptor, isConstructor && isNestedType);
+					char[] returnType = decodeReturnType(descriptor);
+					char[][] exceptionTypes = replace('/', '.', method.getExceptionTypeNames());
+					if (isConstructor) {
+						noConstructor = false;
+						char[] signature = method.getGenericSignature();
+						if (signature == null) {
+							if (reader.isNestedType() && ((modifiers & ClassFileConstants.AccStatic) == 0)) {
+								signature = removeFirstSyntheticParameter(descriptor);
+							} else {
+								signature = descriptor;
+							}
+						}
+						addConstructorDeclaration(
+								name,
+								parameterTypes == null ? 0 : parameterTypes.length,
+								signature,	
+								parameterTypes,
+								method.getArgumentNames(),
+								method.getModifiers(),
+								packageName,
+								modifiers,
+								exceptionTypes,
+								extraFlags);
+					} else {
+						if (!method.isClinit()) {
+							addMethodDeclaration(method.getSelector(), parameterTypes, returnType, exceptionTypes);
+						}
+					}
+					// look for references in method annotations
+					annotations = method.getAnnotations();
+					if (annotations != null) {
+						for (int a=0, length=annotations.length; a<length; a++) {
+							IBinaryAnnotation annotation = annotations[a];
+							addBinaryAnnotation(annotation);
+						}
+					}
+					tagBits = method.getTagBits() & TagBits.AllStandardAnnotationsMask;
+					if (tagBits != 0) {
+						addBinaryStandardAnnotations(tagBits);
+					}
+				}
+			}
+			if (noConstructor) {
+				addDefaultConstructorDeclaration(className, packageName, modifiers, extraFlags);
+			}
+			FieldInfo[] fields = (FieldInfo[]) reader.getFields();
+			if (fields != null) {
+				for (int i = 0, max = fields.length; i < max; i++) {
+					FieldInfo field = fields[i];
+					char[] fieldName = field.getName();
+					char[] fieldType = decodeFieldType(replace('/', '.', field.getTypeName()));
+					addFieldDeclaration(fieldType, fieldName);
+					// look for references in field annotations
+					annotations = field.getAnnotations();
+					if (annotations != null) {
+						for (int a=0, length=annotations.length; a<length; a++) {
+							IBinaryAnnotation annotation = annotations[a];
+							addBinaryAnnotation(annotation);
+						}
+					}
+					tagBits = field.getTagBits() & TagBits.AllStandardAnnotationsMask;
+					if (tagBits != 0) {
+						addBinaryStandardAnnotations(tagBits);
+					}
+				}
+			}
+			// record all references found inside the .class file
+			extractReferenceFromConstantPool(contents, reader);
+		} catch (ClassFormatException e) {
+			// ignore
+			this.document.removeAllIndexEntries();
+			Util.log(IStatus.WARNING, "The Java indexing could not index " + this.document.getPath() + ". This .class file doesn't follow the class file format specification. Please report this issue against the .class file vendor"); //$NON-NLS-1$ //$NON-NLS-2$
+		} catch (RuntimeException e) {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=182154
+			// logging the entry that could not be indexed and continue with the next one
+			// we remove all entries relative to the boggus document
+			this.document.removeAllIndexEntries();
+			Util.log(IStatus.WARNING, "The Java indexing could not index " + this.document.getPath() + ". This .class file doesn't follow the class file format specification. Please report this issue against the .class file vendor"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	private char[] removeFirstSyntheticParameter(char[] descriptor) {
+		if (descriptor == null) return null;
+		if (descriptor.length < 3) return descriptor;
+		if (descriptor[0] != '(') return descriptor;
+		if (descriptor[1] != ')') {
+			// remove the first synthetic parameter
+			int start = org.eclipse.jdt.internal.compiler.util.Util.scanTypeSignature(descriptor, 1) + 1;
+			int length = descriptor.length - start;
+			char[] signature = new char[length + 1];
+			signature[0] = descriptor[0];
+			System.arraycopy(descriptor, start, signature, 1, length);
+			return signature;
+		} else {
+			return descriptor;
+		}
+	}
+	/*
+	 * Modify the array by replacing all occurences of toBeReplaced with newChar
+	 */
+	private char[][] replace(char toBeReplaced, char newChar, char[][] array) {
+		if (array == null) return null;
+		for (int i = 0, max = array.length; i < max; i++) {
+			replace(toBeReplaced, newChar, array[i]);
+		}
+		return array;
+	}
+	/*
+	 * Modify the array by replacing all occurences of toBeReplaced with newChar
+	 */
+	private char[] replace(char toBeReplaced, char newChar, char[] array) {
+		if (array == null) return null;
+		for (int i = 0, max = array.length; i < max; i++) {
+			if (array[i] == toBeReplaced) {
+				array[i] = newChar;
+			}
+		}
+		return array;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java
new file mode 100644
index 0000000..a548c45
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/DefaultJavaIndexer.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.index.FileIndexLocation;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
+import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
+
+public class DefaultJavaIndexer {
+	private static final char JAR_SEPARATOR = IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR.charAt(0);
+	
+	public void generateIndexForJar(String pathToJar, String pathToIndexFile) throws IOException {
+		File f = new File(pathToJar);
+		if (!f.exists()) {
+			throw new FileNotFoundException(pathToJar + " not found"); //$NON-NLS-1$
+		}
+		IndexLocation indexLocation = new FileIndexLocation(new File(pathToIndexFile));
+		Index index = new Index(indexLocation, pathToJar, false /*reuse index file*/);
+		SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
+		index.separator = JAR_SEPARATOR;
+		ZipFile zip = new ZipFile(pathToJar);
+		try {
+			for (Enumeration e = zip.entries(); e.hasMoreElements();) {
+				// iterate each entry to index it
+				ZipEntry ze = (ZipEntry) e.nextElement();
+				String zipEntryName = ze.getName();
+				if (Util.isClassFileName(zipEntryName)) {
+					final byte[] classFileBytes = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
+					JavaSearchDocument entryDocument = new JavaSearchDocument(ze, new Path(pathToJar), classFileBytes, participant);
+					entryDocument.setIndex(index);
+					new BinaryIndexer(entryDocument).indexDocument();
+				}
+			}
+			index.save();
+		} finally {
+			zip.close();
+		}
+		return;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
new file mode 100644
index 0000000..0ae4567
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+
+public interface IIndexConstants {
+
+	/* index encoding */
+	char[] REF= "ref".toCharArray(); //$NON-NLS-1$
+	char[] ANNOTATION_REF= "annotationRef".toCharArray(); //$NON-NLS-1$
+	char[] METHOD_REF= "methodRef".toCharArray(); //$NON-NLS-1$
+	char[] CONSTRUCTOR_REF= "constructorRef".toCharArray(); //$NON-NLS-1$
+	char[] SUPER_REF = "superRef".toCharArray(); //$NON-NLS-1$
+	char[] TYPE_DECL = "typeDecl".toCharArray(); //$NON-NLS-1$
+	char[] METHOD_DECL= "methodDecl".toCharArray(); //$NON-NLS-1$
+	char[] CONSTRUCTOR_DECL= "constructorDecl".toCharArray(); //$NON-NLS-1$
+	char[] FIELD_DECL= "fieldDecl".toCharArray(); //$NON-NLS-1$
+	char[] OBJECT = "Object".toCharArray(); //$NON-NLS-1$
+	char[][] COUNTS=
+		new char[][] { new char[] {'/', '0'}, new char[] {'/', '1'}, new char[] {'/', '2'}, new char[] {'/', '3'}, new char[] {'/', '4'},
+			new char[] {'/', '5'}, new char[] {'/', '6'}, new char[] {'/', '7'}, new char[] {'/', '8'}, new char[] {'/', '9'}
+	};
+	char[] DEFAULT_CONSTRUCTOR = new char[]{'/', '#'};
+	char CLASS_SUFFIX = 'C';
+	char INTERFACE_SUFFIX = 'I';
+	char ENUM_SUFFIX = 'E';
+	char ANNOTATION_TYPE_SUFFIX = 'A';
+	char TYPE_SUFFIX = 0;
+	char CLASS_AND_ENUM_SUFFIX = IJavaSearchConstants.CLASS_AND_ENUM;
+	char CLASS_AND_INTERFACE_SUFFIX = IJavaSearchConstants.CLASS_AND_INTERFACE;
+	char INTERFACE_AND_ANNOTATION_SUFFIX = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
+	char SEPARATOR= '/';
+	char PARAMETER_SEPARATOR= ',';
+	char SECONDARY_SUFFIX = 'S';
+
+	char[] ONE_STAR = new char[] {'*'};
+	char[][] ONE_STAR_CHAR = new char[][] {ONE_STAR};
+
+	// used as special marker for enclosing type name of local and anonymous classes
+	char ZERO_CHAR = '0';
+	char[] ONE_ZERO = new char[] { ZERO_CHAR };
+	char[][] ONE_ZERO_CHAR = new char[][] {ONE_ZERO};
+
+	int PKG_REF_PATTERN = 0x0001;
+	int PKG_DECL_PATTERN = 0x0002;
+	int TYPE_REF_PATTERN = 0x0004;
+	int TYPE_DECL_PATTERN = 0x0008;
+	int SUPER_REF_PATTERN = 0x0010;
+	int CONSTRUCTOR_PATTERN = 0x0020;
+	int FIELD_PATTERN = 0x0040;
+	int METHOD_PATTERN = 0x0080;
+	int OR_PATTERN = 0x0100;
+	int LOCAL_VAR_PATTERN = 0x0200;
+	int TYPE_PARAM_PATTERN = 0x0400;
+	int AND_PATTERN = 0x0800;
+	int ANNOT_REF_PATTERN = 0x1000;
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
new file mode 100644
index 0000000..96aa904
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashSet;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class IndexAllProject extends IndexRequest {
+	IProject project;
+
+	public IndexAllProject(IProject project, IndexManager manager) {
+		super(project.getFullPath(), manager);
+		this.project = project;
+	}
+	public boolean equals(Object o) {
+		if (o instanceof IndexAllProject)
+			return this.project.equals(((IndexAllProject) o).project);
+		return false;
+	}
+	/**
+	 * Ensure consistency of a project index. Need to walk all nested resources,
+	 * and discover resources which have either been changed, added or deleted
+	 * since the index was produced.
+	 */
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+		if (!this.project.isAccessible()) return true; // nothing to do
+
+		ReadWriteMonitor monitor = null;
+		try {
+			// Get source folder entries. Libraries are done as a separate job
+			JavaProject javaProject = (JavaProject)JavaCore.create(this.project);
+			// Do not create marker while getting raw classpath (see bug 41859)
+			IClasspathEntry[] entries = javaProject.getRawClasspath();
+			int length = entries.length;
+			IClasspathEntry[] sourceEntries = new IClasspathEntry[length];
+			int sourceEntriesNumber = 0;
+			for (int i = 0; i < length; i++) {
+				IClasspathEntry entry = entries[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE)
+					sourceEntries[sourceEntriesNumber++] = entry;
+			}
+			if (sourceEntriesNumber == 0) {
+				IPath projectPath = javaProject.getPath();
+				for (int i = 0; i < length; i++) {
+					IClasspathEntry entry = entries[i];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectPath)) {
+						// the project is also a library folder (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89815)
+						// ensure a job exists to index it as a binary folder
+						this.manager.indexLibrary(projectPath, this.project, ((ClasspathEntry)entry).getLibraryIndexLocation());
+						return true;
+					}
+				}
+
+				// nothing to index but want to save an empty index file so its not 'rebuilt' when part of a search request
+				Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+				if (index != null)
+					this.manager.saveIndex(index);
+				return true;
+			}
+			if (sourceEntriesNumber != length)
+				System.arraycopy(sourceEntries, 0, sourceEntries = new IClasspathEntry[sourceEntriesNumber], 0, sourceEntriesNumber);
+
+			Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+			if (index == null) return true;
+			monitor = index.monitor;
+			if (monitor == null) return true; // index got deleted since acquired
+
+			monitor.enterRead(); // ask permission to read
+
+			String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$
+			int max = paths == null ? 0 : paths.length;
+			final SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11);
+			final String OK = "OK"; //$NON-NLS-1$
+			final String DELETED = "DELETED"; //$NON-NLS-1$
+			if (paths != null) {
+				for (int i = 0; i < max; i++)
+					indexedFileNames.put(paths[i], DELETED);
+			}
+			final long indexLastModified = max == 0 ? 0L : index.getIndexLastModified();
+
+			IWorkspaceRoot root = this.project.getWorkspace().getRoot();
+			for (int i = 0; i < sourceEntriesNumber; i++) {
+				if (this.isCancelled) return false;
+
+				IClasspathEntry entry = sourceEntries[i];
+				IResource sourceFolder = root.findMember(entry.getPath());
+				if (sourceFolder != null) {
+
+					// collect output locations if source is project (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041)
+					final HashSet outputs = new HashSet();
+					if (sourceFolder.getType() == IResource.PROJECT) {
+						// Do not create marker while getting output location (see bug 41859)
+						outputs.add(javaProject.getOutputLocation());
+						for (int j = 0; j < sourceEntriesNumber; j++) {
+							IPath output = sourceEntries[j].getOutputLocation();
+							if (output != null) {
+								outputs.add(output);
+							}
+						}
+					}
+					final boolean hasOutputs = !outputs.isEmpty();
+
+					final char[][] inclusionPatterns = ((ClasspathEntry) entry).fullInclusionPatternChars();
+					final char[][] exclusionPatterns = ((ClasspathEntry) entry).fullExclusionPatternChars();
+					if (max == 0) {
+						sourceFolder.accept(
+							new IResourceProxyVisitor() {
+								public boolean visit(IResourceProxy proxy) {
+									if (IndexAllProject.this.isCancelled) return false;
+									switch(proxy.getType()) {
+										case IResource.FILE :
+											if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+												IFile file = (IFile) proxy.requestResource();
+												if (exclusionPatterns != null || inclusionPatterns != null)
+													if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
+														return false;
+												indexedFileNames.put(Util.relativePath(file.getFullPath(), 1/*remove project segment*/), file);
+											}
+											return false;
+										case IResource.FOLDER :
+											if (exclusionPatterns != null && inclusionPatterns == null) {
+												// if there are inclusion patterns then we must walk the children
+												if (Util.isExcluded(proxy.requestFullPath(), inclusionPatterns, exclusionPatterns, true))
+												    return false;
+											}
+											if (hasOutputs && outputs.contains(proxy.requestFullPath()))
+												return false;
+									}
+									return true;
+								}
+							},
+							IResource.NONE
+						);
+					} else {
+						sourceFolder.accept(
+							new IResourceProxyVisitor() {
+								public boolean visit(IResourceProxy proxy) throws CoreException {
+									if (IndexAllProject.this.isCancelled) return false;
+									switch(proxy.getType()) {
+										case IResource.FILE :
+											if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+												IFile file = (IFile) proxy.requestResource();
+												URI location = file.getLocationURI();
+												if (location == null) return false;
+												if (exclusionPatterns != null || inclusionPatterns != null)
+													if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
+														return false;
+												String relativePathString = Util.relativePath(file.getFullPath(), 1/*remove project segment*/);
+												indexedFileNames.put(relativePathString,
+													indexedFileNames.get(relativePathString) == null
+															|| indexLastModified < EFS.getStore(location).fetchInfo().getLastModified()
+														? (Object) file
+														: (Object) OK);
+											}
+											return false;
+										case IResource.FOLDER :
+											if (exclusionPatterns != null || inclusionPatterns != null)
+												if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns))
+													return false;
+											if (hasOutputs && outputs.contains(proxy.requestFullPath()))
+												return false;
+									}
+									return true;
+								}
+							},
+							IResource.NONE
+						);
+					}
+				}
+			}
+
+			SourceElementParser parser = this.manager.getSourceElementParser(javaProject, null/*requestor will be set by indexer*/);
+			Object[] names = indexedFileNames.keyTable;
+			Object[] values = indexedFileNames.valueTable;
+			for (int i = 0, namesLength = names.length; i < namesLength; i++) {
+				String name = (String) names[i];
+				if (name != null) {
+					if (this.isCancelled) return false;
+
+					Object value = values[i];
+					if (value != OK) {
+						if (value == DELETED)
+							this.manager.remove(name, this.containerPath);
+						else
+							this.manager.addSource((IFile) value, this.containerPath, parser);
+					}
+				}
+			}
+
+			// request to save index when all cus have been indexed... also sets state to SAVED_STATE
+			this.manager.request(new SaveIndex(this.containerPath, this.manager));
+		} catch (CoreException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to index " + this.project + " because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			this.manager.removeIndex(this.containerPath);
+			return false;
+		} catch (IOException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to index " + this.project + " because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			this.manager.removeIndex(this.containerPath);
+			return false;
+		} finally {
+			if (monitor != null)
+				monitor.exitRead(); // free read lock
+		}
+		return true;
+	}
+	public int hashCode() {
+		return this.project.hashCode();
+	}
+	protected Integer updatedIndexState() {
+		return IndexManager.REBUILDING_STATE;
+	}
+	public String toString() {
+		return "indexing project " + this.project.getFullPath(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java
new file mode 100644
index 0000000..3b19020
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class IndexBinaryFolder extends IndexRequest {
+	IContainer folder;
+
+	public IndexBinaryFolder(IContainer folder, IndexManager manager) {
+		super(folder.getFullPath(), manager);
+		this.folder = folder;
+	}
+	public boolean equals(Object o) {
+		if (o instanceof IndexBinaryFolder)
+			return this.folder.equals(((IndexBinaryFolder) o).folder);
+		return false;
+	}
+	/**
+	 * Ensure consistency of a folder index. Need to walk all nested resources,
+	 * and discover resources which have either been changed, added or deleted
+	 * since the index was produced.
+	 */
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+		if (!this.folder.isAccessible()) return true; // nothing to do
+
+		Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+		if (index == null) return true;
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) return true; // index got deleted since acquired
+
+		try {
+			monitor.enterRead(); // ask permission to read
+
+			String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$
+			int max = paths == null ? 0 : paths.length;
+			final SimpleLookupTable indexedFileNames = new SimpleLookupTable(max==0 ? 33 : max+11);
+			final String OK = "OK"; //$NON-NLS-1$
+			final String DELETED = "DELETED"; //$NON-NLS-1$
+			if (paths == null) {
+				this.folder.accept(new IResourceProxyVisitor() {
+					public boolean visit(IResourceProxy proxy) {
+						if (IndexBinaryFolder.this.isCancelled) return false;
+						if (proxy.getType() == IResource.FILE) {
+							if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
+								IFile file = (IFile) proxy.requestResource();
+								String containerRelativePath = Util.relativePath(file.getFullPath(), IndexBinaryFolder.this.containerPath.segmentCount());
+								indexedFileNames.put(containerRelativePath, file);
+							}
+							return false;
+						}
+						return true;
+					}
+				}, IResource.NONE);
+			} else {
+				for (int i = 0; i < max; i++) {
+					indexedFileNames.put(paths[i], DELETED);
+				}
+				final long indexLastModified = index.getIndexLastModified();
+				this.folder.accept(
+					new IResourceProxyVisitor() {
+						public boolean visit(IResourceProxy proxy) throws CoreException {
+							if (IndexBinaryFolder.this.isCancelled) return false;
+							if (proxy.getType() == IResource.FILE) {
+								if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
+									IFile file = (IFile) proxy.requestResource();
+									URI location = file.getLocationURI();
+									if (location != null) {
+										String containerRelativePath = Util.relativePath(file.getFullPath(), IndexBinaryFolder.this.containerPath.segmentCount());
+										indexedFileNames.put(containerRelativePath,
+											indexedFileNames.get(containerRelativePath) == null
+													|| indexLastModified <
+													EFS.getStore(location).fetchInfo().getLastModified()
+												? (Object) file
+												: (Object) OK);
+									}
+								}
+								return false;
+							}
+							return true;
+						}
+					},
+					IResource.NONE
+				);
+			}
+
+			Object[] names = indexedFileNames.keyTable;
+			Object[] values = indexedFileNames.valueTable;
+			for (int i = 0, length = names.length; i < length; i++) {
+				String name = (String) names[i];
+				if (name != null) {
+					if (this.isCancelled) return false;
+
+					Object value = values[i];
+					if (value != OK) {
+						if (value == DELETED)
+							this.manager.remove(name, this.containerPath);
+						else {
+							this.manager.addBinary((IFile) value, this.containerPath);
+						}
+					}
+				}
+			}
+
+			// request to save index when all class files have been indexed... also sets state to SAVED_STATE
+			this.manager.request(new SaveIndex(this.containerPath, this.manager));
+		} catch (CoreException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to index " + this.folder + " because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			this.manager.removeIndex(this.containerPath);
+			return false;
+		} catch (IOException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to index " + this.folder + " because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			this.manager.removeIndex(this.containerPath);
+			return false;
+		} finally {
+			monitor.exitRead(); // free read lock
+		}
+		return true;
+	}
+	public int hashCode() {
+		return this.folder.hashCode();
+	}
+	protected Integer updatedIndexState() {
+		return IndexManager.REBUILDING_STATE;
+	}
+	public String toString() {
+		return "indexing binary folder " + this.folder.getFullPath(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
new file mode 100644
index 0000000..4834c32
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -0,0 +1,1211 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import java.util.zip.CRC32;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.index.*;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.PatternSearchJob;
+import org.eclipse.jdt.internal.core.search.processing.IJob;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class IndexManager extends JobManager implements IIndexConstants {
+
+	// key = containerPath, value = indexLocation path
+	// indexLocation path is created by appending an index file name to the getJavaPluginWorkingLocation() path
+	public SimpleLookupTable indexLocations = new SimpleLookupTable();
+	// key = indexLocation path, value = an index
+	private SimpleLookupTable indexes = new SimpleLookupTable();
+
+	/* need to save ? */
+	private boolean needToSave = false;
+	private IPath javaPluginLocation = null;
+
+	/* can only replace a current state if its less than the new one */
+	// key = indexLocation path, value = index state integer
+	private SimpleLookupTable indexStates = null;
+	private File indexNamesMapFile = new File(getSavedIndexesDirectory(), "indexNamesMap.txt"); //$NON-NLS-1$
+	private File savedIndexNamesFile = new File(getSavedIndexesDirectory(), "savedIndexNames.txt"); //$NON-NLS-1$
+	private File participantIndexNamesFile = new File(getSavedIndexesDirectory(), "participantsIndexNames.txt"); //$NON-NLS-1$
+	private boolean javaLikeNamesChanged = true;
+	public static final Integer SAVED_STATE = new Integer(0);
+	public static final Integer UPDATING_STATE = new Integer(1);
+	public static final Integer UNKNOWN_STATE = new Integer(2);
+	public static final Integer REBUILDING_STATE = new Integer(3);
+	public static final Integer REUSE_STATE = new Integer(4);
+	
+	// search participants who register indexes with the index manager
+	private SimpleLookupTable participantsContainers = null;
+	private boolean participantUpdated = false;
+
+	// should JDT manage (update, delete as needed) pre-built indexes?
+	public static final String MANAGE_PRODUCT_INDEXES_PROPERTY = "jdt.core.manageProductIndexes"; //$NON-NLS-1$
+	private static final boolean IS_MANAGING_PRODUCT_INDEXES_PROPERTY = Boolean.getBoolean(MANAGE_PRODUCT_INDEXES_PROPERTY);
+
+	// Debug
+	public static boolean DEBUG = false;
+
+
+public synchronized void aboutToUpdateIndex(IPath containerPath, Integer newIndexState) {
+	// newIndexState is either UPDATING_STATE or REBUILDING_STATE
+	// must tag the index as inconsistent, in case we exit before the update job is started
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	Object state = getIndexStates().get(indexLocation);
+	Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
+	if (currentIndexState.compareTo(REBUILDING_STATE) >= 0) return; // already rebuilding the index
+
+	int compare = newIndexState.compareTo(currentIndexState);
+	if (compare > 0) {
+		// so UPDATING_STATE replaces SAVED_STATE and REBUILDING_STATE replaces everything
+		updateIndexState(indexLocation, newIndexState);
+	} else if (compare < 0 && this.indexes.get(indexLocation) == null) {
+		// if already cached index then there is nothing more to do
+		rebuildIndex(indexLocation, containerPath);
+	}
+}
+/**
+ * Trigger addition of a resource to an index
+ * Note: the actual operation is performed in background
+ */
+public void addBinary(IFile resource, IPath containerPath) {
+	if (JavaCore.getPlugin() == null) return;
+	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
+	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
+}
+/**
+ * Trigger addition of a resource to an index
+ * Note: the actual operation is performed in background
+ */
+public void addSource(IFile resource, IPath containerPath, SourceElementParser parser) {
+	if (JavaCore.getPlugin() == null) return;
+	SearchParticipant participant = SearchEngine.getDefaultSearchParticipant();
+	SearchDocument document = participant.getDocument(resource.getFullPath().toString());
+	document.setParser(parser);
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	scheduleDocumentIndexing(document, containerPath, indexLocation, participant);
+}
+/*
+ * Removes unused indexes from disk.
+ */
+public void cleanUpIndexes() {
+	SimpleSet knownPaths = new SimpleSet();
+	IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope();
+	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
+	Index[] selectedIndexes = job.getIndexes(null);
+	for (int i = 0, l = selectedIndexes.length; i < l; i++) {
+		IndexLocation IndexLocation = selectedIndexes[i].getIndexLocation();
+		knownPaths.add(IndexLocation);
+	}
+
+	if (this.indexStates != null) {
+		Object[] keys = this.indexStates.keyTable;
+		IndexLocation[] locations = new IndexLocation[this.indexStates.elementSize];
+		int count = 0;
+		for (int i = 0, l = keys.length; i < l; i++) {
+			IndexLocation key = (IndexLocation) keys[i];
+			if (key != null && !knownPaths.includes(key))
+				locations[count++] = key;
+		}
+		if (count > 0)
+			removeIndexesState(locations);
+	}
+	deleteIndexFiles(knownPaths);
+}
+/**
+ * Compute the pre-built index location for a specified URL
+ */
+public synchronized IndexLocation computeIndexLocation(IPath containerPath, final URL newIndexURL) {
+	IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath);
+	if (indexLocation == null) {
+		if(newIndexURL != null) {
+			indexLocation = IndexLocation.createIndexLocation(newIndexURL);
+			// update caches
+			indexLocation = (IndexLocation) getIndexStates().getKey(indexLocation);
+			this.indexLocations.put(containerPath, indexLocation);
+		}
+	}
+	else {
+		// an existing index location exists - make sure it has not changed (i.e. the URL has not changed)
+		URL existingURL = indexLocation.getUrl();
+		if (newIndexURL != null) {
+			// if either URL is different then the index location has been updated so rebuild.
+			if(!newIndexURL.equals(existingURL)) {
+				// URL has changed so remove the old index and create a new one
+				this.removeIndex(containerPath);
+				// create a new one
+				indexLocation = IndexLocation.createIndexLocation(newIndexURL);
+				// update caches
+				indexLocation = (IndexLocation) getIndexStates().getKey(indexLocation);
+				this.indexLocations.put(containerPath, indexLocation);
+			}
+		}
+	}
+	return indexLocation;
+}
+public synchronized IndexLocation computeIndexLocation(IPath containerPath) {
+	IndexLocation indexLocation = (IndexLocation) this.indexLocations.get(containerPath);
+	if (indexLocation == null) {
+		String pathString = containerPath.toOSString();
+		CRC32 checksumCalculator = new CRC32();
+		checksumCalculator.update(pathString.getBytes());
+		String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
+		if (VERBOSE)
+			Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
+		// to share the indexLocation between the indexLocations and indexStates tables, get the key from the indexStates table
+		indexLocation = (IndexLocation) getIndexStates().getKey(new FileIndexLocation(new File(getSavedIndexesDirectory(), fileName)));
+		this.indexLocations.put(containerPath, indexLocation);
+	}
+	return indexLocation;
+}
+public void deleteIndexFiles() {
+	if (DEBUG)
+		Util.verbose("Deleting index files"); //$NON-NLS-1$
+	this.savedIndexNamesFile.delete(); // forget saved indexes & delete each index file
+	deleteIndexFiles(null);
+}
+private void deleteIndexFiles(SimpleSet pathsToKeep) {
+	File[] indexesFiles = getSavedIndexesDirectory().listFiles();
+	if (indexesFiles == null) return;
+
+	for (int i = 0, l = indexesFiles.length; i < l; i++) {
+		String fileName = indexesFiles[i].getAbsolutePath();
+		if (pathsToKeep != null && pathsToKeep.includes(new FileIndexLocation(indexesFiles[i]))) continue;
+		String suffix = ".index"; //$NON-NLS-1$
+		if (fileName.regionMatches(true, fileName.length() - suffix.length(), suffix, 0, suffix.length())) {
+			if (VERBOSE || DEBUG)
+				Util.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$
+			indexesFiles[i].delete();
+		}
+	}
+}
+/*
+ * Creates an empty index at the given location, for the given container path, if none exist.
+ */
+public synchronized void ensureIndexExists(IndexLocation indexLocation, IPath containerPath) {
+	SimpleLookupTable states = getIndexStates();
+	Object state = states.get(indexLocation);
+	if (state == null) {
+		updateIndexState(indexLocation, REBUILDING_STATE);
+		getIndex(containerPath, indexLocation, true, true);
+	}
+}
+public SourceElementParser getSourceElementParser(IJavaProject project, ISourceElementRequestor requestor) {
+	// disable task tags to speed up parsing
+	Map options = project.getOptions(true);
+	options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+
+	SourceElementParser parser = new IndexingParser(
+		requestor,
+		new DefaultProblemFactory(Locale.getDefault()),
+		new CompilerOptions(options),
+		true, // index local declarations
+		true, // optimize string literals
+		false); // do not use source javadoc parser to speed up parsing
+	parser.reportOnlyOneSyntaxError = true;
+
+	// Always check javadoc while indexing
+	parser.javadocParser.checkDocComment = true;
+	parser.javadocParser.reportProblems = false;
+
+	return parser;
+}
+/**
+ * Returns the index for a given index location
+ *
+ * @param indexLocation The path of the index file
+ * @return The corresponding index or <code>null</code> if not found
+ */
+public synchronized Index getIndex(IndexLocation indexLocation) {
+	return (Index) this.indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
+}
+/**
+ * Returns the index for a given project, according to the following algorithm:
+ * - if index is already in memory: answers this one back
+ * - if (reuseExistingFile) then read it and return this index and record it in memory
+ * - if (createIfMissing) then create a new empty index and record it in memory
+ *
+ * Warning: Does not check whether index is consistent (not being used)
+ */
+public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
+}
+/**
+ * Returns the index for a given project, according to the following algorithm:
+ * - if index is already in memory: answers this one back
+ * - if (reuseExistingFile) then read it and return this index and record it in memory
+ * - if (createIfMissing) then create a new empty index and record it in memory
+ *
+ * Warning: Does not check whether index is consistent (not being used)
+ */
+public synchronized Index getIndex(IPath containerPath, IndexLocation indexLocation, boolean reuseExistingFile, boolean createIfMissing) {
+	// Path is already canonical per construction
+	Index index = getIndex(indexLocation);
+	if (index == null) {
+		Object state = getIndexStates().get(indexLocation);
+		Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
+		if (currentIndexState == UNKNOWN_STATE) {
+			// should only be reachable for query jobs
+			// IF you put an index in the cache, then AddJarFileToIndex fails because it thinks there is nothing to do
+			rebuildIndex(indexLocation, containerPath);
+			return null;
+		}
+
+		// index isn't cached, consider reusing an existing index file
+		String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+		if (reuseExistingFile) {
+			if (indexLocation.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
+				try {
+					index = new Index(indexLocation, containerPathString, true /*reuse index file*/);
+					this.indexes.put(indexLocation, index);
+					return index;
+				} catch (IOException e) {
+					// failed to read the existing file or its no longer compatible
+					if (currentIndexState != REBUILDING_STATE && currentIndexState != REUSE_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt
+						if (VERBOSE)
+							Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+						rebuildIndex(indexLocation, containerPath);
+						return null;
+					}
+					/*index = null;*/ // will fall thru to createIfMissing & create a empty index for the rebuild all job to populate
+				}
+			}
+			if (currentIndexState == SAVED_STATE) { // rebuild index if existing file is missing
+				rebuildIndex(indexLocation, containerPath);
+				return null;
+			}
+			if (currentIndexState == REUSE_STATE) {
+				// supposed to be in reuse state but error in the index file, so reindex.
+				if (VERBOSE)
+					Util.verbose("-> cannot reuse given index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+				this.indexLocations.put(containerPath, null);
+				indexLocation = computeIndexLocation(containerPath);
+				rebuildIndex(indexLocation, containerPath);
+				return null;
+			}
+		}
+		// index wasn't found on disk, consider creating an empty new one
+		if (createIfMissing) {
+			try {
+				if (VERBOSE)
+					Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+				index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/);
+				this.indexes.put(indexLocation, index);
+				return index;
+			} catch (IOException e) {
+				if (VERBOSE)
+					Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+				// The file could not be created. Possible reason: the project has been deleted.
+				return null;
+			}
+		}
+	}
+	//System.out.println(" index name: " + path.toOSString() + " <----> " + index.getIndexFile().getName());
+	return index;
+}
+/**
+ * Returns all the existing indexes for a list of index locations.
+ * Note that this may trigger some indexes recreation work
+ *
+ * @param locations The list of of the index files path
+ * @return The corresponding indexes list.
+ */
+public Index[] getIndexes(IndexLocation[] locations, IProgressMonitor progressMonitor) {
+	// acquire the in-memory indexes on the fly
+	int length = locations.length;
+	Index[] locatedIndexes = new Index[length];
+	int count = 0;
+	if (this.javaLikeNamesChanged) {
+		this.javaLikeNamesChanged = hasJavaLikeNamesChanged();
+	}
+	for (int i = 0; i < length; i++) {
+		if (progressMonitor != null && progressMonitor.isCanceled()) {
+			throw new OperationCanceledException();
+		}
+		// may trigger some index recreation work
+		IndexLocation indexLocation = locations[i];
+		Index index = getIndex(indexLocation);
+		if (index == null) {
+			// only need containerPath if the index must be built
+			IPath containerPath = (IPath) this.indexLocations.keyForValue(indexLocation);
+			if (containerPath != null) {// sanity check
+				index = getIndex(containerPath, indexLocation, true /*reuse index file*/, false /*do not create if none*/);
+				if (index != null && this.javaLikeNamesChanged && !index.isIndexForJar()) {
+					// When a change in java like names extension has been detected, all
+					// non jar files indexes (i.e. containing sources) need to be rebuilt.
+					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=286379
+					File indexFile = index.getIndexFile();
+					if (indexFile.exists()) {
+						if (DEBUG)
+							Util.verbose("Change in javaLikeNames - removing index file for " + containerPath ); //$NON-NLS-1$
+						indexFile.delete();
+					}
+					this.indexes.put(indexLocation, null);
+					rebuildIndex(indexLocation, containerPath);
+					index = null;
+				}
+			} else {
+				if (indexLocation.isParticipantIndex() && indexLocation.exists()) { // the index belongs to non-jdt search participant
+					try {
+						IPath container = getParticipantsContainer(indexLocation);
+						if (container != null) {
+							index = new Index(indexLocation, container.toOSString(), true /*reuse index file*/);
+							this.indexes.put(indexLocation, index);
+						}
+					} catch (IOException e) {
+						// ignore
+					}
+				}
+			}
+		}
+		if (index != null)
+			locatedIndexes[count++] = index; // only consider indexes which are ready
+	}
+	if (this.javaLikeNamesChanged) {
+		writeJavaLikeNamesFile();
+		this.javaLikeNamesChanged = false;
+	}
+	if (count < length) {
+		System.arraycopy(locatedIndexes, 0, locatedIndexes=new Index[count], 0, count);
+	}
+	return locatedIndexes;
+}
+public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	if (getIndexStates().get(indexLocation) == REBUILDING_STATE)
+		return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
+
+	return null; // abort the job since the index has been removed from the REBUILDING_STATE
+}
+private SimpleLookupTable getIndexStates() {
+	if (this.indexStates != null) return this.indexStates;
+
+	this.indexStates = new SimpleLookupTable();
+	File indexesDirectoryPath = getSavedIndexesDirectory();
+	char[][] savedNames = readIndexState(getJavaPluginWorkingLocation().toOSString());
+	if (savedNames != null) {
+		for (int i = 1, l = savedNames.length; i < l; i++) { // first name is saved signature, see readIndexState()
+			char[] savedName = savedNames[i];
+			if (savedName.length > 0) {
+				IndexLocation indexLocation = new FileIndexLocation(new File(indexesDirectoryPath, String.valueOf(savedName))); // shares indexesDirectoryPath's segments
+				if (VERBOSE)
+					Util.verbose("Reading saved index file " + indexLocation); //$NON-NLS-1$
+				this.indexStates.put(indexLocation, SAVED_STATE);
+			}
+		}
+	} else {
+		// All the index files are getting deleted and hence there is no need to 
+		// further check for change in javaLikeNames. 
+		writeJavaLikeNamesFile();
+		this.javaLikeNamesChanged = false;
+		deleteIndexFiles();
+	}
+	readIndexMap();
+	return this.indexStates;
+}
+private IPath getParticipantsContainer(IndexLocation indexLocation) {
+	if (this.participantsContainers == null) {
+		readParticipantsIndexNamesFile();
+	}
+	return (IPath)this.participantsContainers.get(indexLocation);
+}
+private IPath getJavaPluginWorkingLocation() {
+	if (this.javaPluginLocation != null) return this.javaPluginLocation;
+
+	IPath stateLocation = JavaCore.getPlugin().getStateLocation();
+	return this.javaPluginLocation = stateLocation;
+}
+private File getSavedIndexesDirectory() {
+	return new File(getJavaPluginWorkingLocation().toOSString());
+}
+/*
+ * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=286379
+ * Returns true if there is a change in javaLikeNames since it
+ * has been last stored. 
+ * The javaLikeNames stored in the file javaLikeNames.txt 
+ * is compared with the current javaLikeNames and if there is a change, this 
+ * function returns true. If the file javaLikeNames.txt doesn't exist and there 
+ * is only one javaLikeName (.java), then this returns false so that no-reindexing 
+ * happens. 
+ */
+private boolean hasJavaLikeNamesChanged() {
+	char[][] currentNames = Util.getJavaLikeExtensions();
+	int current = currentNames.length;
+	char[][] prevNames = readJavaLikeNamesFile();
+	if (prevNames == null) {
+		if (VERBOSE && current != 1)
+			Util.verbose("No Java like names found and there is atleast one non-default javaLikeName", System.err); //$NON-NLS-1$
+		return (current != 1); //Ignore if only java
+	}
+	int prev = prevNames.length;
+	if (current != prev) {
+		if (VERBOSE)
+			Util.verbose("Java like names have changed", System.err); //$NON-NLS-1$
+		return true;
+	}
+	if (current > 1) {
+		// Sort the current java like names. 
+		// Copy the array to avoid modifying the Util static variable
+		System.arraycopy(currentNames, 0, currentNames = new char[current][], 0, current);
+		Util.sort(currentNames);
+	}
+	
+	// The JavaLikeNames would have been sorted before getting stored in the file,
+	// hence just do a direct compare.
+	for (int i = 0; i < current; i++) {
+		if (!CharOperation.equals(currentNames[i],prevNames[i])) {
+			if (VERBOSE)
+				Util.verbose("Java like names have changed", System.err); //$NON-NLS-1$
+			return true;
+		}
+	}
+	return false;
+}
+public void indexDocument(SearchDocument searchDocument, SearchParticipant searchParticipant, Index index, IPath indexLocation) {
+	try {
+		searchDocument.setIndex(index);
+		searchParticipant.indexDocument(searchDocument, indexLocation);
+	} finally {
+		searchDocument.setIndex(null);
+	}
+}
+/**
+ * Trigger addition of the entire content of a project
+ * Note: the actual operation is performed in background
+ */
+public void indexAll(IProject project) {
+	if (JavaCore.getPlugin() == null) return;
+
+	// Also request indexing of binaries on the classpath
+	// determine the new children
+	try {
+		JavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+		JavaProject javaProject = (JavaProject) model.getJavaProject(project);
+		// only consider immediate libraries - each project will do the same
+		// NOTE: force to resolve CP variables before calling indexer - 19303, so that initializers
+		// will be run in the current thread.
+		IClasspathEntry[] entries = javaProject.getResolvedClasspath();
+		for (int i = 0; i < entries.length; i++) {
+			IClasspathEntry entry= entries[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY)
+				indexLibrary(entry.getPath(), project, ((ClasspathEntry)entry).getLibraryIndexLocation());
+		}
+	} catch(JavaModelException e){ // cannot retrieve classpath info
+	}
+
+	// check if the same request is not already in the queue
+	IndexRequest request = new IndexAllProject(project, this);
+	if (!isJobWaiting(request))
+		request(request);
+}
+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) {
+	this.indexLibrary(path, requestingProject, indexURL, false);
+}
+
+/**
+ * Trigger addition of a library to an index
+ * Note: the actual operation is performed in background
+ */
+public void indexLibrary(IPath path, IProject requestingProject, URL indexURL, final boolean updateIndex) {
+	// requestingProject is no longer used to cancel jobs but leave it here just in case
+	IndexLocation indexFile = null;
+	if(indexURL != null) {
+		if(IS_MANAGING_PRODUCT_INDEXES_PROPERTY) {
+			indexFile = computeIndexLocation(path, indexURL);
+		}
+		else {
+			indexFile = IndexLocation.createIndexLocation(indexURL);
+		}
+	}
+	if (JavaCore.getPlugin() == null) return;
+	IndexRequest request = null;
+	boolean forceIndexUpdate = IS_MANAGING_PRODUCT_INDEXES_PROPERTY && updateIndex;
+	Object target = JavaModel.getTarget(path, true);
+	if (target instanceof IFile) {
+		request = new AddJarFileToIndex((IFile) target, indexFile, this, forceIndexUpdate);
+	} else if (target instanceof File) {
+		request = new AddJarFileToIndex(path, indexFile, this, forceIndexUpdate);
+	} else if (target instanceof IContainer) {
+		request = new IndexBinaryFolder((IContainer) target, this);
+	} else {
+		return;
+	}
+
+	// check if the same request is not already in the queue
+	if (!isJobWaiting(request))
+		request(request);
+}
+
+synchronized boolean addIndex(IPath containerPath, IndexLocation indexFile) {
+	getIndexStates().put(indexFile, REUSE_STATE);
+	this.indexLocations.put(containerPath, indexFile);
+	Index index = getIndex(containerPath, indexFile, true, false);
+	if (index == null) {
+		indexFile.close();
+		this.indexLocations.put(containerPath, null);
+		return false;
+	}
+	writeIndexMapFile();
+	return true;
+}
+
+/**
+ * Index the content of the given source folder.
+ */
+public void indexSourceFolder(JavaProject javaProject, IPath sourceFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) {
+	IProject project = javaProject.getProject();
+	if (this.jobEnd > this.jobStart) {
+		// skip it if a job to index the project is already in the queue
+		IndexRequest request = new IndexAllProject(project, this);
+		if (isJobWaiting(request)) return;
+	}
+
+	request(new AddFolderToIndex(sourceFolder, project, inclusionPatterns, exclusionPatterns, this));
+}
+public synchronized void jobWasCancelled(IPath containerPath) {
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	Index index = getIndex(indexLocation);
+	if (index != null) {
+		index.monitor = null;
+		this.indexes.removeKey(indexLocation);
+	}
+	updateIndexState(indexLocation, UNKNOWN_STATE);
+}
+/**
+ * Advance to the next available job, once the current one has been completed.
+ * Note: clients awaiting until the job count is zero are still waiting at this point.
+ */
+protected synchronized void moveToNextJob() {
+	// remember that one job was executed, and we will need to save indexes at some point
+	this.needToSave = true;
+	super.moveToNextJob();
+}
+/**
+ * No more job awaiting.
+ */
+protected void notifyIdle(long idlingTime){
+	if (idlingTime > 1000 && this.needToSave) saveIndexes();
+}
+/**
+ * Name of the background process
+ */
+public String processName(){
+	return Messages.process_name;
+}
+private char[][] readJavaLikeNamesFile() {
+	try {
+		String pathName = getJavaPluginWorkingLocation().toOSString();	
+		File javaLikeNamesFile = new File(pathName, "javaLikeNames.txt"); //$NON-NLS-1$
+		if (!javaLikeNamesFile.exists())
+			return null;
+		char[] javaLikeNames = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(javaLikeNamesFile, null);
+		if (javaLikeNames.length > 0) {
+			char[][] names = CharOperation.splitOn('\n', javaLikeNames);
+			return names;
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to read javaLikeNames file"); //$NON-NLS-1$
+	}
+	return null;
+}
+private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) {
+	Object target = JavaModel.getTarget(containerPath, true);
+	if (target == null) return;
+
+	if (VERBOSE)
+		Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath); //$NON-NLS-1$ //$NON-NLS-2$
+
+	updateIndexState(indexLocation, REBUILDING_STATE);
+	IndexRequest request = null;
+	if (target instanceof IProject) {
+		IProject p = (IProject) target;
+		if (JavaProject.hasJavaNature(p))
+			request = new IndexAllProject(p, this);
+	} else if (target instanceof IFolder) {
+		request = new IndexBinaryFolder((IFolder) target, this);
+	} else if (target instanceof IFile) {
+		request = new AddJarFileToIndex((IFile) target, null, this);
+	} else if (target instanceof File) {
+		request = new AddJarFileToIndex(containerPath, null, this);
+	}
+	if (request != null)
+		request(request);
+}
+/**
+ * Recreates the index for a given path, keeping the same read-write monitor.
+ * Returns the new empty index or null if it didn't exist before.
+ * Warning: Does not check whether index is consistent (not being used)
+ */
+public synchronized Index recreateIndex(IPath containerPath) {
+	// only called to over write an existing cached index...
+	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+	try {
+		// Path is already canonical
+		IndexLocation indexLocation = computeIndexLocation(containerPath);
+		Index index = getIndex(indexLocation);
+		ReadWriteMonitor monitor = index == null ? null : index.monitor;
+
+		if (VERBOSE)
+			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+		index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/);
+		this.indexes.put(indexLocation, index);
+		index.monitor = monitor;
+		return index;
+	} catch (IOException e) {
+		// The file could not be created. Possible reason: the project has been deleted.
+		if (VERBOSE) {
+			Util.verbose("-> failed to recreate index for path: "+containerPathString); //$NON-NLS-1$
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
+/**
+ * Trigger removal of a resource to an index
+ * Note: the actual operation is performed in background
+ */
+public void remove(String containerRelativePath, IPath indexedContainer){
+	request(new RemoveFromIndex(containerRelativePath, indexedContainer, this));
+}
+/**
+ * Removes the index for a given path.
+ * This is a no-op if the index did not exist.
+ */
+public synchronized void removeIndex(IPath containerPath) {
+	if (VERBOSE || DEBUG)
+		Util.verbose("removing index " + containerPath); //$NON-NLS-1$
+	IndexLocation indexLocation = computeIndexLocation(containerPath);
+	Index index = getIndex(indexLocation);
+	File indexFile = null;
+	if (index != null) {
+		index.monitor = null;
+		indexFile = index.getIndexFile();
+	}
+	if (indexFile == null)
+		indexFile = indexLocation.getIndexFile(); // index is not cached yet, but still want to delete the file
+	if (this.indexStates.get(indexLocation) == REUSE_STATE) {
+		indexLocation.close();
+		this.indexLocations.put(containerPath, null);
+	} else if (indexFile != null && indexFile.exists()) {
+		if (DEBUG)
+			Util.verbose("removing index file " + indexFile); //$NON-NLS-1$
+		indexFile.delete();
+	}
+	this.indexes.removeKey(indexLocation);
+	if (IS_MANAGING_PRODUCT_INDEXES_PROPERTY) {
+		this.indexLocations.removeKey(containerPath);
+	}
+	updateIndexState(indexLocation, null);
+}
+/**
+ * Removes all indexes whose paths start with (or are equal to) the given path.
+ */
+public synchronized void removeIndexPath(IPath path) {
+	if (VERBOSE || DEBUG)
+		Util.verbose("removing index path " + path); //$NON-NLS-1$
+	Object[] keyTable = this.indexes.keyTable;
+	Object[] valueTable = this.indexes.valueTable;
+	IndexLocation[] locations = null;
+	int max = this.indexes.elementSize;
+	int count = 0;
+	for (int i = 0, l = keyTable.length; i < l; i++) {
+		IndexLocation indexLocation = (IndexLocation) keyTable[i];
+		if (indexLocation == null)
+			continue;
+		if (indexLocation.startsWith(path)) {
+			Index index = (Index) valueTable[i];
+			index.monitor = null;
+			if (locations == null)
+				locations = new IndexLocation[max];
+			locations[count++] = indexLocation;
+			if (this.indexStates.get(indexLocation) == REUSE_STATE) {
+				indexLocation.close();
+			} else {
+				if (DEBUG)
+					Util.verbose("removing index file " + indexLocation); //$NON-NLS-1$
+				indexLocation.delete();
+			}
+		} else {
+			max--;
+		}
+	}
+	if (locations != null) {
+		for (int i = 0; i < count; i++)
+			this.indexes.removeKey(locations[i]);
+		removeIndexesState(locations);
+		if (this.participantsContainers != null) {
+			boolean update = false;
+			for (int i = 0; i < count; i++) {
+				if (this.participantsContainers.get(locations[i]) != null) {
+					update = true;
+					this.participantsContainers.removeKey(locations[i]);
+				}
+			}
+			if (update) writeParticipantsIndexNamesFile();
+		}
+	}
+}
+/**
+ * Removes all indexes whose paths start with (or are equal to) the given path.
+ */
+public synchronized void removeIndexFamily(IPath path) {
+	// only finds cached index files... shutdown removes all non-cached index files
+	ArrayList toRemove = null;
+	Object[] containerPaths = this.indexLocations.keyTable;
+	for (int i = 0, length = containerPaths.length; i < length; i++) {
+		IPath containerPath = (IPath) containerPaths[i];
+		if (containerPath == null) continue;
+		if (path.isPrefixOf(containerPath)) {
+			if (toRemove == null)
+				toRemove = new ArrayList();
+			toRemove.add(containerPath);
+		}
+	}
+	if (toRemove != null)
+		for (int i = 0, length = toRemove.size(); i < length; i++)
+			removeIndex((IPath) toRemove.get(i));
+}
+/**
+ * Remove the content of the given source folder from the index.
+ */
+public void removeSourceFolderFromIndex(JavaProject javaProject, IPath sourceFolder, char[][] inclusionPatterns, char[][] exclusionPatterns) {
+	IProject project = javaProject.getProject();
+	if (this.jobEnd > this.jobStart) {
+		// skip it if a job to index the project is already in the queue
+		IndexRequest request = new IndexAllProject(project, this);
+		if (isJobWaiting(request)) return;
+	}
+
+	request(new RemoveFolderFromIndex(sourceFolder, inclusionPatterns, exclusionPatterns, project, this));
+}
+/**
+ * Flush current state
+ */
+public synchronized void reset() {
+	super.reset();
+	if (this.indexes != null) {
+		this.indexes = new SimpleLookupTable();
+		this.indexStates = null;
+	}
+	this.indexLocations = new SimpleLookupTable();
+	this.javaPluginLocation = null;
+}
+/**
+ * Resets the index for a given path.
+ * Returns true if the index was reset, false otherwise.
+ */
+public synchronized boolean resetIndex(IPath containerPath) {
+	// only called to over write an existing cached index...
+	String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+	try {
+		// Path is already canonical
+		IndexLocation indexLocation = computeIndexLocation(containerPath);
+		Index index = getIndex(indexLocation);
+		if (VERBOSE) {
+			Util.verbose("-> reseting index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		if (index == null) {
+			// the index does not exist, try to recreate it
+			return recreateIndex(containerPath) != null;
+		}
+		index.reset();
+		return true;
+	} catch (IOException e) {
+		// The file could not be created. Possible reason: the project has been deleted.
+		if (VERBOSE) {
+			Util.verbose("-> failed to reset index for path: "+containerPathString); //$NON-NLS-1$
+			e.printStackTrace();
+		}
+		return false;
+	}
+}
+public void saveIndex(Index index) throws IOException {
+	// must have permission to write from the write monitor
+	if (index.hasChanged()) {
+		if (VERBOSE)
+			Util.verbose("-> saving index " + index.getIndexLocation()); //$NON-NLS-1$
+		index.save();
+	}
+	synchronized (this) {
+		IPath containerPath = new Path(index.containerPath);
+		if (this.jobEnd > this.jobStart) {
+			for (int i = this.jobEnd; i > this.jobStart; i--) { // skip the current job
+				IJob job = this.awaitingJobs[i];
+				if (job instanceof IndexRequest)
+					if (((IndexRequest) job).containerPath.equals(containerPath)) return;
+			}
+		}
+		IndexLocation indexLocation = computeIndexLocation(containerPath);
+		updateIndexState(indexLocation, SAVED_STATE);
+	}
+}
+/**
+ * Commit all index memory changes to disk
+ */
+public void saveIndexes() {
+	// only save cached indexes... the rest were not modified
+	ArrayList toSave = new ArrayList();
+	synchronized(this) {
+		Object[] valueTable = this.indexes.valueTable;
+		for (int i = 0, l = valueTable.length; i < l; i++) {
+			Index index = (Index) valueTable[i];
+			if (index != null)
+				toSave.add(index);
+		}
+	}
+
+	boolean allSaved = true;
+	for (int i = 0, length = toSave.size(); i < length; i++) {
+		Index index = (Index) toSave.get(i);
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) continue; // index got deleted since acquired
+		try {
+			// take read lock before checking if index has changed
+			// don't take write lock yet since it can cause a deadlock (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50571)
+			monitor.enterRead();
+			if (index.hasChanged()) {
+				if (monitor.exitReadEnterWrite()) {
+					try {
+						saveIndex(index);
+					} catch(IOException e) {
+						if (VERBOSE) {
+							Util.verbose("-> got the following exception while saving:", System.err); //$NON-NLS-1$
+							e.printStackTrace();
+						}
+						allSaved = false;
+					} finally {
+						monitor.exitWriteEnterRead();
+					}
+				} else {
+					allSaved = false;
+				}
+			}
+		} finally {
+			monitor.exitRead();
+		}
+	}
+	if (this.participantsContainers != null && this.participantUpdated) {
+		writeParticipantsIndexNamesFile();
+		this.participantUpdated = false;
+	}
+	this.needToSave = !allSaved;
+}
+public void scheduleDocumentIndexing(final SearchDocument searchDocument, IPath container, final IndexLocation indexLocation, final SearchParticipant searchParticipant) {
+	request(new IndexRequest(container, this) {
+		public boolean execute(IProgressMonitor progressMonitor) {
+			if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+			/* ensure no concurrent write access to index */
+			Index index = getIndex(this.containerPath, indexLocation, true, /*reuse index file*/ true /*create if none*/);
+			if (index == null) return true;
+			ReadWriteMonitor monitor = index.monitor;
+			if (monitor == null) return true; // index got deleted since acquired
+
+			try {
+				monitor.enterWrite(); // ask permission to write
+				indexDocument(searchDocument, searchParticipant, index, new Path(indexLocation.getCanonicalFilePath()));
+			} finally {
+				monitor.exitWrite(); // free write lock
+			}
+			return true;
+		}
+		public String toString() {
+			return "indexing " + searchDocument.getPath(); //$NON-NLS-1$
+		}
+	});
+}
+
+public String toString() {
+	StringBuffer buffer = new StringBuffer(10);
+	buffer.append(super.toString());
+	buffer.append("In-memory indexes:\n"); //$NON-NLS-1$
+	int count = 0;
+	Object[] valueTable = this.indexes.valueTable;
+	for (int i = 0, l = valueTable.length; i < l; i++) {
+		Index index = (Index) valueTable[i];
+		if (index != null)
+			buffer.append(++count).append(" - ").append(index.toString()).append('\n'); //$NON-NLS-1$
+	}
+	return buffer.toString();
+}
+
+private void readIndexMap() {
+	try {
+		char[] indexMaps = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.indexNamesMapFile, null);
+		char[][] names = CharOperation.splitOn('\n', indexMaps);
+		if (names.length >= 3) {
+			// First line is DiskIndex signature (see writeIndexMapFile())
+			String savedSignature = DiskIndex.SIGNATURE;
+			if (savedSignature.equals(new String(names[0]))) {
+				for (int i = 1, l = names.length-1 ; i < l ; i+=2) {
+					IndexLocation indexPath = IndexLocation.createIndexLocation(new URL(new String(names[i])));
+					this.indexLocations.put(new Path(new String(names[i+1])), indexPath );
+					this.indexStates.put(indexPath, REUSE_STATE);
+				}
+			}		
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to read saved index file names"); //$NON-NLS-1$
+	}
+	return;
+}
+private char[][] readIndexState(String dirOSString) {
+	try {
+		char[] savedIndexNames = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.savedIndexNamesFile, null);
+		if (savedIndexNames.length > 0) {
+			char[][] names = CharOperation.splitOn('\n', savedIndexNames);
+			if (names.length > 1) {
+				// First line is DiskIndex signature + saved plugin working location (see writeSavedIndexNamesFile())
+				String savedSignature = DiskIndex.SIGNATURE + "+" + dirOSString; //$NON-NLS-1$
+				if (savedSignature.equals(new String(names[0])))
+					return names;
+			}
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to read saved index file names"); //$NON-NLS-1$
+	}
+	return null;
+}
+private void readParticipantsIndexNamesFile() {
+	SimpleLookupTable containers = new SimpleLookupTable(3);
+	try {
+		char[] participantIndexNames = org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.participantIndexNamesFile, null);
+		if (participantIndexNames.length > 0) {
+			char[][] names = CharOperation.splitOn('\n', participantIndexNames);
+			if (names.length >= 3) {
+				// First line is DiskIndex signature  (see writeParticipantsIndexNamesFile())
+				if (DiskIndex.SIGNATURE.equals(new String(names[0]))) {					
+					for (int i = 1, l = names.length-1 ; i < l ; i+=2) {
+						IndexLocation indexLocation = new FileIndexLocation(new File(new String(names[i])), true);
+						containers.put(indexLocation, new Path(new String(names[i+1])));
+					}
+				}				
+			}
+		}	
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to read participant index file names"); //$NON-NLS-1$
+	}
+	this.participantsContainers = containers;
+	return;
+}
+private synchronized void removeIndexesState(IndexLocation[] locations) {
+	getIndexStates(); // ensure the states are initialized
+	int length = locations.length;
+	boolean changed = false;
+	for (int i=0; i<length; i++) {
+		if (locations[i] == null) continue;
+		if ((this.indexStates.removeKey(locations[i]) != null)) {
+			changed = true;
+			if (VERBOSE) {
+				Util.verbose("-> index state updated to: ? for: "+locations[i]); //$NON-NLS-1$
+			}
+		}
+	}
+	if (!changed) return;
+
+	writeSavedIndexNamesFile();
+	writeIndexMapFile();
+}
+private synchronized void updateIndexState(IndexLocation indexLocation, Integer indexState) {
+	if (indexLocation == null)
+		throw new IllegalArgumentException();
+
+	getIndexStates(); // ensure the states are initialized
+	if (indexState != null) {
+		if (indexState.equals(this.indexStates.get(indexLocation))) return; // not changed
+		this.indexStates.put(indexLocation, indexState);
+	} else {
+		if (!this.indexStates.containsKey(indexLocation)) return; // did not exist anyway
+		this.indexStates.removeKey(indexLocation);
+	}
+
+	writeSavedIndexNamesFile();
+
+	if (VERBOSE) {
+		if (indexState == null) {
+			Util.verbose("-> index state removed for: "+indexLocation); //$NON-NLS-1$
+		} else {
+			String state = "?"; //$NON-NLS-1$
+			if (indexState == SAVED_STATE) state = "SAVED"; //$NON-NLS-1$
+			else if (indexState == UPDATING_STATE) state = "UPDATING"; //$NON-NLS-1$
+			else if (indexState == UNKNOWN_STATE) state = "UNKNOWN"; //$NON-NLS-1$
+			else if (indexState == REBUILDING_STATE) state = "REBUILDING"; //$NON-NLS-1$
+			else if (indexState == REUSE_STATE) state = "REUSE"; //$NON-NLS-1$
+			Util.verbose("-> index state updated to: " + state + " for: "+indexLocation); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+
+}
+public void updateParticipant(IPath indexPath, IPath containerPath) {
+	if (this.participantsContainers == null) {
+		readParticipantsIndexNamesFile();
+	}
+	IndexLocation indexLocation = new FileIndexLocation(indexPath.toFile(), true);
+	if (this.participantsContainers.get(indexLocation) == null) {
+		this.participantsContainers.put(indexLocation, containerPath);
+		this.participantUpdated  = true;
+	}
+}
+private void writeJavaLikeNamesFile() {
+	BufferedWriter writer = null;
+	String pathName = getJavaPluginWorkingLocation().toOSString();
+	try {		
+		char[][] currentNames = Util.getJavaLikeExtensions();
+		int length = currentNames.length;
+		if (length > 1) {
+			// Sort the current java like names. 
+			// Copy the array to avoid modifying the Util static variable
+			System.arraycopy(currentNames, 0, currentNames=new char[length][], 0, length);
+			Util.sort(currentNames);
+		}
+		File javaLikeNamesFile = new File(pathName, "javaLikeNames.txt"); //$NON-NLS-1$
+		writer = new BufferedWriter(new FileWriter(javaLikeNamesFile));
+		for (int i = 0; i < length-1; i++) {
+			writer.write(currentNames[i]);
+			writer.write('\n');
+		}
+		if (length > 0) 
+			writer.write(currentNames[length-1]);
+		
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to write javaLikeNames file", System.err); //$NON-NLS-1$
+	} finally {
+		if (writer != null) {
+			try {
+				writer.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+}
+private void writeIndexMapFile() {
+	BufferedWriter writer = null;
+	try {
+		writer = new BufferedWriter(new FileWriter(this.indexNamesMapFile));
+		writer.write(DiskIndex.SIGNATURE);
+		writer.write('\n');
+		Object[] keys = this.indexStates.keyTable;
+		Object[] states = this.indexStates.valueTable;
+		for (int i = 0, l = states.length; i < l; i++) {
+			IndexLocation location = (IndexLocation)keys[i];
+			if (location != null && states[i] == REUSE_STATE) {
+				IPath container = (IPath)this.indexLocations.keyForValue(location);
+				if (container != null) {
+					writer.write(location.toString());
+					writer.write('\n');
+					writer.write(container.toOSString());
+					writer.write('\n');
+				}
+			}
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to write saved index file names", System.err); //$NON-NLS-1$
+	} finally {
+		if (writer != null) {
+			try {
+				writer.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+}
+private void writeParticipantsIndexNamesFile() {
+	BufferedWriter writer = null;
+	try {
+		writer = new BufferedWriter(new FileWriter(this.participantIndexNamesFile));
+		writer.write(DiskIndex.SIGNATURE);
+		writer.write('\n');
+		Object[] indexFiles = this.participantsContainers.keyTable;
+		Object[] containers = this.participantsContainers.valueTable;
+		for (int i = 0, l = indexFiles.length; i < l; i++) {
+			IndexLocation indexFile = (IndexLocation)indexFiles[i];
+			if (indexFile != null) {
+				writer.write(indexFile.getIndexFile().getPath());
+				writer.write('\n');
+				writer.write(((IPath)containers[i]).toOSString());
+				writer.write('\n');
+			}
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to write participant index file names", System.err); //$NON-NLS-1$
+	} finally {
+		if (writer != null) {
+			try {
+				writer.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+}
+private void writeSavedIndexNamesFile() {
+	BufferedWriter writer = null;
+	try {
+		writer = new BufferedWriter(new FileWriter(this.savedIndexNamesFile));
+		writer.write(DiskIndex.SIGNATURE);
+		writer.write('+');
+		writer.write(getJavaPluginWorkingLocation().toOSString());
+		writer.write('\n');
+		Object[] keys = this.indexStates.keyTable;
+		Object[] states = this.indexStates.valueTable;
+		for (int i = 0, l = states.length; i < l; i++) {
+			IndexLocation key = (IndexLocation) keys[i];
+			if (key != null && states[i] == SAVED_STATE) {
+				writer.write(key.fileName());
+				writer.write('\n');
+			}
+		}
+	} catch (IOException ignored) {
+		if (VERBOSE)
+			Util.verbose("Failed to write saved index file names", System.err); //$NON-NLS-1$
+	} finally {
+		if (writer != null) {
+			try {
+				writer.close();
+			} catch (IOException e) {
+				// ignore
+			}
+		}
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
new file mode 100644
index 0000000..d919fe5
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.internal.core.search.processing.IJob;
+
+public abstract class IndexRequest implements IJob {
+	protected boolean isCancelled = false;
+	protected IPath containerPath;
+	protected IndexManager manager;
+
+	public IndexRequest(IPath containerPath, IndexManager manager) {
+		this.containerPath = containerPath;
+		this.manager = manager;
+	}
+	public boolean belongsTo(String projectNameOrJarPath) {
+		// used to remove pending jobs because the project was deleted... not to delete index files
+		// can be found either by project name or JAR path name
+		return projectNameOrJarPath.equals(this.containerPath.segment(0))
+			|| projectNameOrJarPath.equals(this.containerPath.toString());
+	}
+	public void cancel() {
+		this.manager.jobWasCancelled(this.containerPath);
+		this.isCancelled = true;
+	}
+	public void ensureReadyToRun() {
+		// tag the index as inconsistent
+		this.manager.aboutToUpdateIndex(this.containerPath, updatedIndexState());
+	}
+	public String getJobFamily() {
+		return this.containerPath.toString();
+	}
+	protected Integer updatedIndexState() {
+		return IndexManager.UPDATING_STATE;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexingParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexingParser.java
new file mode 100644
index 0000000..253ff1a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexingParser.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/*
+ * A source element parser that avoids creating unnecessary nodes.
+ */
+public class IndexingParser extends SourceElementParser {
+	SingleNameReference singleNameReference = new SingleNameReference(CharOperation.NO_CHAR, 0);
+	QualifiedNameReference qualifiedNameReference = new QualifiedNameReference(CharOperation.NO_CHAR_CHAR, new long[0], 0, 0);
+	ImportReference importReference = new ImportReference(CharOperation.NO_CHAR_CHAR, new long[1], false, 0);
+
+	public IndexingParser(ISourceElementRequestor requestor, IProblemFactory problemFactory, CompilerOptions options, boolean reportLocalDeclarations, boolean optimizeStringLiterals, boolean useSourceJavadocParser) {
+		super(requestor, problemFactory, options, reportLocalDeclarations,
+				optimizeStringLiterals, useSourceJavadocParser);
+	}
+
+	protected ImportReference newImportReference(char[][] tokens, long[] sourcePositions, boolean onDemand, int mod) {
+		ImportReference ref = this.importReference;
+		ref.tokens = tokens;
+		ref.sourcePositions = sourcePositions;
+		if (onDemand) {
+			ref.bits |= ASTNode.OnDemand;
+		}
+		ref.sourceEnd = (int) (sourcePositions[sourcePositions.length-1] & 0x00000000FFFFFFFF);
+		ref.sourceStart = (int) (sourcePositions[0] >>> 32);
+		ref.modifiers = this.modifiers;
+		return ref;
+	}
+
+	protected SingleNameReference newSingleNameReference(char[] source, long positions) {
+		SingleNameReference ref = this.singleNameReference;
+		ref.token = source;
+		ref.sourceStart = (int) (positions >>> 32);
+		ref.sourceEnd = (int) positions;
+		return ref;
+	}
+
+	protected QualifiedNameReference newQualifiedNameReference(char[][] tokens, long[] positions, int sourceStart, int sourceEnd) {
+		QualifiedNameReference ref = this.qualifiedNameReference;
+		ref.tokens = tokens;
+		ref.sourcePositions = positions;
+		ref.sourceStart = sourceStart;
+		ref.sourceEnd = sourceEnd;
+		return ref;
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java
new file mode 100644
index 0000000..2824aea
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+/**
+ * Monitor ensuring no more than one writer working concurrently.
+ * Multiple readers are allowed to perform simultaneously.
+ */
+public class ReadWriteMonitor {
+
+/**
+ * <0 : writing (cannot go beyond -1, i.e one concurrent writer)
+ * =0 : idle
+ * >0 : reading (number of concurrent readers)
+ */
+private int status = 0;
+/**
+ * Concurrent reading is allowed
+ * Blocking only when already writing.
+ */
+public synchronized void enterRead() {
+	while (this.status < 0) {
+		try {
+			wait();
+		} catch(InterruptedException e) {
+			// ignore
+		}
+	}
+	this.status++;
+}
+/**
+ * Only one writer at a time is allowed to perform
+ * Blocking only when already writing or reading.
+ */
+public synchronized void enterWrite() {
+	while (this.status != 0) {
+		try {
+			wait();
+		} catch(InterruptedException e) {
+			// ignore
+		}
+	}
+	this.status--;
+}
+/**
+ * Only notify waiting writer(s) if last reader
+ */
+public synchronized void exitRead() {
+
+	if (--this.status == 0) notifyAll();
+}
+/**
+ * When writing is over, all readers and possible
+ * writers are granted permission to restart concurrently
+ */
+public synchronized void exitWrite() {
+
+	if (++this.status == 0) notifyAll();
+}
+/**
+ * Atomic exitRead/enterWrite: Allows to keep monitor in between
+ * exit read and next enter write.
+ * Use when writing changes is optional, otherwise call the individual methods.
+ * Returns false if multiple readers are accessing the index.
+ */
+public synchronized boolean exitReadEnterWrite() {
+	if (this.status != 1) return false; // only continue if this is the only reader
+
+	this.status = -1;
+	return true;
+}
+/**
+ * Atomic exitWrite/enterRead: Allows to keep monitor in between
+ * exit write and next enter read.
+ * When writing is over, all readers are granted permissing to restart
+ * concurrently.
+ * This is the same as:
+ * <pre>
+ * synchronized(monitor) {
+ *   monitor.exitWrite();
+ *   monitor.enterRead();
+ * }
+ * </pre>
+ */
+public synchronized void exitWriteEnterRead() {
+	exitWrite();
+	enterRead();
+}
+public String toString() {
+	StringBuffer buffer = new StringBuffer();
+	if (this.status == 0) {
+		buffer.append("Monitor idle "); //$NON-NLS-1$
+	} else if (this.status < 0) {
+		buffer.append("Monitor writing "); //$NON-NLS-1$
+	} else if (this.status > 0) {
+		buffer.append("Monitor reading "); //$NON-NLS-1$
+	}
+	buffer.append("(status = "); //$NON-NLS-1$
+	buffer.append(this.status);
+	buffer.append(")"); //$NON-NLS-1$
+	return buffer.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java
new file mode 100644
index 0000000..7043f69
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+class RemoveFolderFromIndex extends IndexRequest {
+	IPath folderPath;
+	char[][] inclusionPatterns;
+	char[][] exclusionPatterns;
+
+	public RemoveFolderFromIndex(IPath folderPath, char[][] inclusionPatterns, char[][] exclusionPatterns, IProject project, IndexManager manager) {
+		super(project.getFullPath(), manager);
+		this.folderPath = folderPath;
+		this.inclusionPatterns = inclusionPatterns;
+		this.exclusionPatterns = exclusionPatterns;
+	}
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+		/* ensure no concurrent write access to index */
+		Index index = this.manager.getIndex(this.containerPath, true, /*reuse index file*/ false /*create if none*/);
+		if (index == null) return true;
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) return true; // index got deleted since acquired
+
+		try {
+			monitor.enterRead(); // ask permission to read
+			String containerRelativePath = Util.relativePath(this.folderPath, this.containerPath.segmentCount());
+			String[] paths = index.queryDocumentNames(containerRelativePath);
+			// all file names belonging to the folder or its subfolders and that are not excluded (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32607)
+			if (paths != null) {
+				if (this.exclusionPatterns == null && this.inclusionPatterns == null) {
+					for (int i = 0, max = paths.length; i < max; i++) {
+						this.manager.remove(paths[i], this.containerPath); // write lock will be acquired by the remove operation
+					}
+				} else {
+					for (int i = 0, max = paths.length; i < max; i++) {
+						String documentPath =  this.containerPath.toString() + '/' + paths[i];
+						if (!Util.isExcluded(new Path(documentPath), this.inclusionPatterns, this.exclusionPatterns, false))
+							this.manager.remove(paths[i], this.containerPath); // write lock will be acquired by the remove operation
+					}
+				}
+			}
+		} catch (IOException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to remove " + this.folderPath + " from index because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			return false;
+		} finally {
+			monitor.exitRead(); // free read lock
+		}
+		return true;
+	}
+	public String toString() {
+		return "removing " + this.folderPath + " from index " + this.containerPath; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java
new file mode 100644
index 0000000..123f970
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.core.index.Index;
+
+class RemoveFromIndex extends IndexRequest {
+	String resourceName;
+
+	public RemoveFromIndex(String resourceName, IPath containerPath, IndexManager manager) {
+		super(containerPath, manager);
+		this.resourceName = resourceName;
+	}
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+		/* ensure no concurrent write access to index */
+		Index index = this.manager.getIndex(this.containerPath, true, /*reuse index file*/ false /*create if none*/);
+		if (index == null) return true;
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) return true; // index got deleted since acquired
+
+		try {
+			monitor.enterWrite(); // ask permission to write
+			index.remove(this.resourceName);
+		} finally {
+			monitor.exitWrite(); // free write lock
+		}
+		return true;
+	}
+	public String toString() {
+		return "removing " + this.resourceName + " from index " + this.containerPath; //$NON-NLS-1$ //$NON-NLS-2$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java
new file mode 100644
index 0000000..0b2ca36
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/*
+ * Save the index of a project.
+ */
+public class SaveIndex extends IndexRequest {
+	public SaveIndex(IPath containerPath, IndexManager manager) {
+		super(containerPath, manager);
+	}
+	public boolean execute(IProgressMonitor progressMonitor) {
+
+		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
+
+		/* ensure no concurrent write access to index */
+		Index index = this.manager.getIndex(this.containerPath, true /*reuse index file*/, false /*don't create if none*/);
+		if (index == null) return true;
+		ReadWriteMonitor monitor = index.monitor;
+		if (monitor == null) return true; // index got deleted since acquired
+
+		try {
+			monitor.enterWrite(); // ask permission to write
+			this.manager.saveIndex(index);
+		} catch (IOException e) {
+			if (JobManager.VERBOSE) {
+				Util.verbose("-> failed to save index " + this.containerPath + " because of the following exception:", System.err); //$NON-NLS-1$ //$NON-NLS-2$
+				e.printStackTrace();
+			}
+			return false;
+		} finally {
+			monitor.exitWrite(); // free write lock
+		}
+		return true;
+	}
+	public String toString() {
+		return "saving index for " + this.containerPath; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
new file mode 100644
index 0000000..3fdf60c
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.jdom.CompilationUnit;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+
+/**
+ * A SourceIndexer indexes java files using a java parser. The following items are indexed:
+ * Declarations of:<br>
+ * - Classes<br>
+ * - Interfaces;<br>
+ * - Methods;<br>
+ * - Fields;<br>
+ * References to:<br>
+ * - Methods (with number of arguments); <br>
+ * - Fields;<br>
+ * - Types;<br>
+ * - Constructors.
+ */
+public class SourceIndexer extends AbstractIndexer implements SuffixConstants {
+
+	public SourceIndexer(SearchDocument document) {
+		super(document);
+	}
+	public void indexDocument() {
+		// Create a new Parser
+		SourceIndexerRequestor requestor = new SourceIndexerRequestor(this);
+		String documentPath = this.document.getPath();
+		SourceElementParser parser = this.document.getParser();
+		if (parser == null) {
+			IPath path = new Path(documentPath);
+			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
+			parser = JavaModelManager.getJavaModelManager().indexManager.getSourceElementParser(JavaCore.create(project), requestor);
+		} else {
+			parser.setRequestor(requestor);
+		}
+
+		// Launch the parser
+		char[] source = null;
+		char[] name = null;
+		try {
+			source = this.document.getCharContents();
+			name = documentPath.toCharArray();
+		} catch(Exception e){
+			// ignore
+		}
+		if (source == null || name == null) return; // could not retrieve document info (e.g. resource was discarded)
+		CompilationUnit compilationUnit = new CompilationUnit(source, name);
+		try {
+			parser.parseCompilationUnit(compilationUnit, true/*full parse*/, null/*no progress*/);
+		} catch (Exception e) {
+			if (JobManager.VERBOSE) {
+				e.printStackTrace();
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
new file mode 100644
index 0000000..4ada576
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.indexing;
+
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.core.search.processing.JobManager;
+
+/**
+ * This class is used by the JavaParserIndexer. When parsing the java file, the requestor
+ * recognizes the java elements (methods, fields, ...) and add them to an index.
+ */
+public class SourceIndexerRequestor implements ISourceElementRequestor, IIndexConstants {
+	SourceIndexer indexer;
+
+	char[] packageName = CharOperation.NO_CHAR;
+	char[][] enclosingTypeNames = new char[5][];
+	int depth = 0;
+	int methodDepth = 0;
+
+public SourceIndexerRequestor(SourceIndexer indexer) {
+	this.indexer = indexer;
+}
+/**
+ * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[][], int, int)
+ */
+public void acceptAnnotationTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
+	int length = typeName.length;
+	for (int i = 0; i < length - 1; i++)
+		acceptUnknownReference(typeName[i], 0);
+	acceptAnnotationTypeReference(typeName[length - 1], 0);
+}
+/**
+ * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[], int)
+ */
+public void acceptAnnotationTypeReference(char[] simpleTypeName, int sourcePosition) {
+	this.indexer.addAnnotationTypeReference(simpleTypeName);
+}
+/**
+ * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
+ */
+public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {
+	if (CharOperation.indexOf(Signature.C_GENERIC_START, typeName) > 0) {
+		typeName = Signature.toCharArray(Signature.getTypeErasure(Signature.createTypeSignature(typeName, false)).toCharArray());
+	}
+	this.indexer.addConstructorReference(typeName, argCount);
+	int lastDot = CharOperation.lastIndexOf('.', typeName);
+	if (lastDot != -1) {
+		char[][] qualification = CharOperation.splitOn('.', CharOperation.subarray(typeName, 0, lastDot));
+		for (int i = 0, length = qualification.length; i < length; i++) {
+			this.indexer.addNameReference(qualification[i]);
+		}
+	}
+}
+/**
+ * @see ISourceElementRequestor#acceptFieldReference(char[], int)
+ */
+public void acceptFieldReference(char[] fieldName, int sourcePosition) {
+	this.indexer.addFieldReference(fieldName);
+}
+/**
+ * @see ISourceElementRequestor#acceptImport(int, int, int, int, char[][], boolean, int)
+ */
+public void acceptImport(int declarationStart, int declarationEnd, int nameStart, int nameEnd, char[][] tokens, boolean onDemand, int modifiers) {
+	// imports have already been reported while creating the ImportRef node (see SourceElementParser#comsume*ImportDeclarationName() methods)
+}
+/**
+ * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
+ */
+public void acceptLineSeparatorPositions(int[] positions) {
+	// implements interface method
+}
+/**
+ * @see ISourceElementRequestor#acceptMethodReference(char[], int, int)
+ */
+public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) {
+	this.indexer.addMethodReference(methodName, argCount);
+}
+/**
+ * @see ISourceElementRequestor#acceptPackage(ImportReference)
+ */
+public void acceptPackage(ImportReference importReference) {
+	this.packageName = CharOperation.concatWith(importReference.getImportName(), '.');
+}
+/**
+ * @see ISourceElementRequestor#acceptProblem(CategorizedProblem)
+ */
+public void acceptProblem(CategorizedProblem problem) {
+	// implements interface method
+}
+/**
+ * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int)
+ */
+public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
+	int length = typeName.length;
+	for (int i = 0; i < length - 1; i++)
+		acceptUnknownReference(typeName[i], 0); // ?
+	acceptTypeReference(typeName[length - 1], 0);
+}
+/**
+ * @see ISourceElementRequestor#acceptTypeReference(char[], int)
+ */
+public void acceptTypeReference(char[] simpleTypeName, int sourcePosition) {
+	this.indexer.addTypeReference(simpleTypeName);
+}
+/**
+ * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int)
+ */
+public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) {
+	for (int i = 0; i < name.length; i++) {
+		acceptUnknownReference(name[i], 0);
+	}
+}
+/**
+ * @see ISourceElementRequestor#acceptUnknownReference(char[], int)
+ */
+public void acceptUnknownReference(char[] name, int sourcePosition) {
+	this.indexer.addNameReference(name);
+}
+
+private void addDefaultConstructorIfNecessary(TypeInfo typeInfo) {
+	boolean hasConstructor = false;
+	
+	TypeDeclaration typeDeclaration = typeInfo.node;
+	AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+	int methodCounter = methods == null ? 0 : methods.length;
+	done : for (int i = 0; i < methodCounter; i++) {
+		AbstractMethodDeclaration method = methods[i];
+		if (method.isConstructor() && !method.isDefaultConstructor()) {
+			hasConstructor = true;
+			break done;
+		}
+	}
+	
+	if (!hasConstructor) {
+		this.indexer.addDefaultConstructorDeclaration(
+				typeInfo.name,
+				this.packageName == null ? CharOperation.NO_CHAR : this.packageName,
+				typeInfo.modifiers,
+				getMoreExtraFlags(typeInfo.extraFlags));
+	}
+}
+/*
+ * Rebuild the proper qualification for the current source type:
+ *
+ * java.lang.Object ---> null
+ * java.util.Hashtable$Entry --> [Hashtable]
+ * x.y.A$B$C --> [A, B]
+ */
+public char[][] enclosingTypeNames(){
+
+	if (this.depth == 0) return null;
+
+	char[][] qualification = new char[this.depth][];
+	System.arraycopy(this.enclosingTypeNames, 0, qualification, 0, this.depth);
+	return qualification;
+}
+private void enterAnnotationType(TypeInfo typeInfo) {
+	char[][] typeNames;
+	if (this.methodDepth > 0) {
+		typeNames = ONE_ZERO_CHAR;
+	} else {
+		typeNames = enclosingTypeNames();
+	}
+	this.indexer.addAnnotationTypeDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.secondary);
+	addDefaultConstructorIfNecessary(typeInfo);
+	pushTypeName(typeInfo.name);
+}
+
+private void enterClass(TypeInfo typeInfo) {
+
+	// eliminate possible qualifications, given they need to be fully resolved again
+	if (typeInfo.superclass != null) {
+		typeInfo.superclass = getSimpleName(typeInfo.superclass);
+
+		// add implicit constructor reference to default constructor
+		this.indexer.addConstructorReference(typeInfo.superclass, 0);
+	}
+	if (typeInfo.superinterfaces != null){
+		for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++) {
+			typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
+		}
+	}
+	char[][] typeNames;
+	if (this.methodDepth > 0) {
+		// set specific ['0'] value for local and anonymous to be able to filter them
+		typeNames = ONE_ZERO_CHAR;
+	} else {
+		typeNames = enclosingTypeNames();
+	}
+	char[][] typeParameterSignatures = null;
+	if (typeInfo.typeParameters != null) {
+		int typeParametersLength = typeInfo.typeParameters.length;
+		typeParameterSignatures = new char[typeParametersLength][];
+		for (int i = 0; i < typeParametersLength; i++) {
+			ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
+			typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds == null ? CharOperation.NO_CHAR_CHAR : typeParameterInfo.bounds);
+		}
+	}
+	this.indexer.addClassDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superclass, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
+	addDefaultConstructorIfNecessary(typeInfo);
+	pushTypeName(typeInfo.name);
+}
+/**
+ * @see ISourceElementRequestor#enterCompilationUnit()
+ */
+public void enterCompilationUnit() {
+	// implements interface method
+}
+/**
+ * @see ISourceElementRequestor#enterConstructor(ISourceElementRequestor.MethodInfo)
+ */
+public void enterConstructor(MethodInfo methodInfo) {
+	int argCount = methodInfo.parameterTypes == null ? 0 : methodInfo.parameterTypes.length;
+	this.indexer.addConstructorDeclaration(
+			methodInfo.name,
+			argCount,
+			null,
+			methodInfo.parameterTypes,
+			methodInfo.parameterNames,
+			methodInfo.modifiers,
+			methodInfo.declaringPackageName,
+			methodInfo.declaringTypeModifiers,
+			methodInfo.exceptionTypes,
+			getMoreExtraFlags(methodInfo.extraFlags));
+	this.methodDepth++;
+}
+private void enterEnum(TypeInfo typeInfo) {
+	// eliminate possible qualifications, given they need to be fully resolved again
+	if (typeInfo.superinterfaces != null){
+		for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
+			typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
+		}
+	}
+	char[][] typeNames;
+	if (this.methodDepth > 0) {
+		typeNames = ONE_ZERO_CHAR;
+	} else {
+		typeNames = enclosingTypeNames();
+	}
+	char[] superclass = typeInfo.superclass == null ? CharOperation.concatWith(TypeConstants.JAVA_LANG_ENUM, '.'): typeInfo.superclass;
+	this.indexer.addEnumDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, superclass, typeInfo.superinterfaces, typeInfo.secondary);
+	addDefaultConstructorIfNecessary(typeInfo);
+	pushTypeName(typeInfo.name);
+}
+/**
+ * @see ISourceElementRequestor#enterField(ISourceElementRequestor.FieldInfo)
+ */
+public void enterField(FieldInfo fieldInfo) {
+	this.indexer.addFieldDeclaration(fieldInfo.type, fieldInfo.name);
+	this.methodDepth++;
+}
+/**
+ * @see ISourceElementRequestor#enterInitializer(int, int)
+ */
+public void enterInitializer(int declarationSourceStart, int modifiers) {
+	this.methodDepth++;
+}
+private void enterInterface(TypeInfo typeInfo) {
+	// eliminate possible qualifications, given they need to be fully resolved again
+	if (typeInfo.superinterfaces != null){
+		for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
+			typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
+		}
+	}
+	char[][] typeNames;
+	if (this.methodDepth > 0) {
+		typeNames = ONE_ZERO_CHAR;
+	} else {
+		typeNames = enclosingTypeNames();
+	}
+	char[][] typeParameterSignatures = null;
+	if (typeInfo.typeParameters != null) {
+		int typeParametersLength = typeInfo.typeParameters.length;
+		typeParameterSignatures = new char[typeParametersLength][];
+		for (int i = 0; i < typeParametersLength; i++) {
+			ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
+			typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds);
+		}
+	}
+	this.indexer.addInterfaceDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
+	addDefaultConstructorIfNecessary(typeInfo);
+	pushTypeName(typeInfo.name);
+}
+/**
+ * @see ISourceElementRequestor#enterMethod(ISourceElementRequestor.MethodInfo)
+ */
+public void enterMethod(MethodInfo methodInfo) {
+	this.indexer.addMethodDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.returnType, methodInfo.exceptionTypes);
+	this.methodDepth++;
+}
+/**
+ * @see ISourceElementRequestor#enterType(ISourceElementRequestor.TypeInfo)
+ */
+public void enterType(TypeInfo typeInfo) {
+	// TODO (jerome) might want to merge the 4 methods
+	switch (TypeDeclaration.kind(typeInfo.modifiers)) {
+		case TypeDeclaration.CLASS_DECL:
+			enterClass(typeInfo);
+			break;
+		case TypeDeclaration.ANNOTATION_TYPE_DECL:
+			enterAnnotationType(typeInfo);
+			break;
+		case TypeDeclaration.INTERFACE_DECL:
+			enterInterface(typeInfo);
+			break;
+		case TypeDeclaration.ENUM_DECL:
+			enterEnum(typeInfo);
+			break;
+	}
+}
+
+/**
+ * @see ISourceElementRequestor#exitCompilationUnit(int)
+ */
+public void exitCompilationUnit(int declarationEnd) {
+	// implements interface method
+}
+/**
+ * @see ISourceElementRequestor#exitConstructor(int)
+ */
+public void exitConstructor(int declarationEnd) {
+	this.methodDepth--;
+}
+/**
+ * @see ISourceElementRequestor#exitField(int, int, int)
+ */
+public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
+	this.methodDepth--;
+}
+/**
+ * @see ISourceElementRequestor#exitInitializer(int)
+ */
+public void exitInitializer(int declarationEnd) {
+	this.methodDepth--;
+}
+/**
+ * @see ISourceElementRequestor#exitMethod(int, Expression)
+ */
+public void exitMethod(int declarationEnd, Expression defaultValue) {
+	this.methodDepth--;
+}
+/**
+ * @see ISourceElementRequestor#exitType(int)
+ */
+public void exitType(int declarationEnd) {
+	popTypeName();
+}
+/*
+ * Returns the unqualified name without parameters from the given type name.
+ */
+private char[] getSimpleName(char[] typeName) {
+	int lastDot = -1, lastGenericStart = -1;
+	int depthCount = 0;
+	int length = typeName.length;
+	lastDotLookup: for (int i = length -1; i >= 0; i--) {
+		switch (typeName[i]) {
+			case '.':
+				if (depthCount == 0) {
+					lastDot = i;
+					break lastDotLookup;
+				}
+				break;
+			case '<':
+				depthCount--;
+				if (depthCount == 0) lastGenericStart = i;
+				break;
+			case '>':
+				depthCount++;
+				break;
+		}
+	}
+	if (lastGenericStart < 0) {
+		if (lastDot < 0) {
+			return typeName;
+		}
+		return  CharOperation.subarray(typeName, lastDot + 1, length);
+	}
+	return  CharOperation.subarray(typeName, lastDot + 1, lastGenericStart);
+}
+private int getMoreExtraFlags(int extraFlags) {
+	if (this.methodDepth > 0) {
+		extraFlags |= ExtraFlags.IsLocalType;
+	}
+	return extraFlags;
+}
+public void popTypeName() {
+	if (this.depth > 0) {
+		this.enclosingTypeNames[--this.depth] = null;
+	} else if (JobManager.VERBOSE) {
+		// dump a trace so it can be tracked down
+		try {
+			this.enclosingTypeNames[-1] = null;
+		} catch (ArrayIndexOutOfBoundsException e) {
+			e.printStackTrace();
+		}
+	}
+}
+public void pushTypeName(char[] typeName) {
+	if (this.depth == this.enclosingTypeNames.length)
+		System.arraycopy(this.enclosingTypeNames, 0, this.enclosingTypeNames = new char[this.depth*2][], 0, this.depth);
+	this.enclosingTypeNames[this.depth++] = typeName;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java
new file mode 100644
index 0000000..9e9b2aa
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndLocator.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class AndLocator extends PatternLocator {
+
+final PatternLocator[] patternLocators;
+final int[] levels;
+
+public AndLocator(AndPattern pattern) {
+	super(pattern);
+
+	SearchPattern[] patterns = pattern.patterns;
+	PatternLocator[] locators = new PatternLocator[patterns.length];
+	this.levels = new int[patterns.length];
+	for (int i=0, l=patterns.length; i<l; i++) {
+		locators[i] = PatternLocator.patternLocator(patterns[i]);
+		this.levels[i] = IMPOSSIBLE_MATCH;
+	}
+	this.patternLocators = locators;
+}
+public void initializePolymorphicSearch(MatchLocator locator) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		this.patternLocators[i].initializePolymorphicSearch(locator);
+	}
+}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(Expression node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MessageSend node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(Reference node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeReference node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+protected int matchContainer() {
+	int result = ALL_CONTAINER;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		result &= this.patternLocators[i].matchContainer();
+	}
+	return result;
+}
+protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+	PatternLocator weakestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].matchLevel(importRef);
+		if (newLevel == IMPOSSIBLE_MATCH) return;
+		if (weakestPattern == null || newLevel < level) {
+			weakestPattern = this.patternLocators[i];
+			level = newLevel;
+		}
+	}
+	weakestPattern.matchReportImportRef(importRef, binding, element, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	PatternLocator weakestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		if (this.patternLocators[i].referenceType() == 0) return; // impossible match
+		int newLevel = this.patternLocators[i].resolveLevel(reference);
+		if (newLevel == IMPOSSIBLE_MATCH) return;
+		if (weakestPattern == null || newLevel < level) {
+			weakestPattern = this.patternLocators[i];
+			level = newLevel;
+		}
+	}
+	weakestPattern.matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+public int resolveLevel(ASTNode node) {
+	int level = ACCURATE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].resolveLevel(node);
+		if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+		this.levels[i] = newLevel;
+		if (newLevel < level) {
+			level = newLevel; // want to answer the weaker match
+		}
+	}
+	return level;
+}
+public int resolveLevel(Binding binding) {
+	int level = ACCURATE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].resolveLevel(binding);
+		if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+		this.levels[i] = newLevel;
+		if (newLevel < level) {
+			level = newLevel; // want to answer the weaker match
+		}
+	}
+	return level;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#setFlavors(int)
+ */
+void setFlavors(int flavors) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		this.patternLocators[i].setFlavors(flavors);
+	}
+}
+public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		this.patternLocators[i].recordResolution(typeReference, resolution);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java
new file mode 100644
index 0000000..35d0146
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.search.SearchPattern;
+
+public class AndPattern extends IntersectingPattern {
+protected SearchPattern[] patterns;
+int current;
+
+private static int combinedMatchRule(int matchRule, int matchRule2) {
+	int combined = matchRule & matchRule2;
+	int compatibility = combined & MATCH_COMPATIBILITY_MASK;
+	if (compatibility == 0) {
+		if ((matchRule & MATCH_COMPATIBILITY_MASK) == R_FULL_MATCH) {
+			compatibility = matchRule2;
+		} else if ((matchRule2 & MATCH_COMPATIBILITY_MASK) == R_FULL_MATCH) {
+			compatibility = matchRule;
+		} else {
+			compatibility = Math.min(matchRule & MATCH_COMPATIBILITY_MASK, matchRule2 & MATCH_COMPATIBILITY_MASK);
+		}
+	}
+	return (combined & (R_EXACT_MATCH | R_PREFIX_MATCH | R_PATTERN_MATCH | R_REGEXP_MATCH))
+		| (combined & R_CASE_SENSITIVE)
+		| compatibility
+		| (combined & (R_CAMELCASE_MATCH | R_CAMELCASE_SAME_PART_COUNT_MATCH));
+}
+
+public AndPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
+	super(AND_PATTERN, combinedMatchRule(leftPattern.getMatchRule(), rightPattern.getMatchRule()));
+	this.mustResolve = leftPattern.mustResolve || rightPattern.mustResolve;
+
+	SearchPattern[] leftPatterns = leftPattern instanceof AndPattern ? ((AndPattern) leftPattern).patterns : null;
+	SearchPattern[] rightPatterns = rightPattern instanceof AndPattern ? ((AndPattern) rightPattern).patterns : null;
+	int leftSize = leftPatterns == null ? 1 : leftPatterns.length;
+	int rightSize = rightPatterns == null ? 1 : rightPatterns.length;
+	this.patterns = new SearchPattern[leftSize + rightSize];
+
+	if (leftPatterns == null)
+		this.patterns[0] = leftPattern;
+	else
+		System.arraycopy(leftPatterns, 0, this.patterns, 0, leftSize);
+	if (rightPatterns == null)
+		this.patterns[leftSize] = rightPattern;
+	else
+		System.arraycopy(rightPatterns, 0, this.patterns, leftSize, rightSize);
+
+	// Store erasure match
+	this.matchCompatibility = getMatchRule() & MATCH_COMPATIBILITY_MASK;
+
+	this.current = 0;
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.InternalSearchPattern#currentPattern()
+ */
+public SearchPattern currentPattern() {
+	return this.patterns[this.current++];
+}
+
+protected boolean hasNextQuery() {
+	return this.current < (this.patterns.length-1);
+}
+
+protected void resetQuery() {
+	this.current = 0;
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
new file mode 100644
index 0000000..1c86721
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
@@ -0,0 +1,523 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
+import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class ClassFileMatchLocator implements IIndexConstants {
+
+private static final long TARGET_ANNOTATION_BITS =
+	TagBits.AnnotationForType |
+	TagBits.AnnotationForParameter |
+	TagBits.AnnotationForPackage |
+	TagBits.AnnotationForMethod |
+	TagBits.AnnotationForLocalVariable |
+	TagBits.AnnotationForField |
+	TagBits.AnnotationForConstructor |
+	TagBits.AnnotationForAnnotationType;
+private static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, '.');
+public static char[] convertClassFileFormat(char[] name) {
+	return CharOperation.replaceOnCopy(name, '/', '.');
+}
+
+private  boolean checkAnnotation(IBinaryAnnotation annotation, TypeReferencePattern pattern) {
+	if (checkTypeName(pattern.simpleName, pattern.qualification, convertClassFileFormat(Signature.toCharArray(annotation.getTypeName())), pattern.isCaseSensitive, pattern.isCamelCase)) {
+		return true;
+	}
+	IBinaryElementValuePair[] valuePairs = annotation.getElementValuePairs();
+	if (valuePairs != null) {
+		for (int j=0, vpLength=valuePairs.length; j<vpLength; j++) {
+			IBinaryElementValuePair valuePair = valuePairs[j];
+			Object pairValue = valuePair.getValue();
+			if (pairValue instanceof IBinaryAnnotation) {
+				if (checkAnnotation((IBinaryAnnotation) pairValue, pattern)) {
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+private boolean checkAnnotations(TypeReferencePattern pattern, IBinaryAnnotation[] annotations, long tagBits) {
+	if (annotations != null) {
+		for (int a=0, length=annotations.length; a<length; a++) {
+			IBinaryAnnotation annotation = annotations[a];
+			if (checkAnnotation(annotation, pattern)) {
+				return true;
+			}
+		}
+	}
+	if ((tagBits & TagBits.AllStandardAnnotationsMask) != 0 && checkStandardAnnotations(tagBits, pattern)) {
+		return true;
+	}
+	return false;
+}
+private boolean checkAnnotationTypeReference(char[] fullyQualifiedName, TypeReferencePattern pattern) {
+	return checkTypeName(pattern.simpleName, pattern.qualification, fullyQualifiedName, pattern.isCaseSensitive, pattern.isCamelCase);
+}
+private boolean checkDeclaringType(IBinaryType enclosingBinaryType, char[] simpleName, char[] qualification, boolean isCaseSensitive, boolean isCamelCase) {
+	if (simpleName == null && qualification == null) return true;
+	if (enclosingBinaryType == null) return true;
+
+	char[] declaringTypeName = convertClassFileFormat(enclosingBinaryType.getName());
+	return checkTypeName(simpleName, qualification, declaringTypeName, isCaseSensitive, isCamelCase);
+}
+private boolean checkParameters(char[] methodDescriptor, char[][] parameterSimpleNames, char[][] parameterQualifications, boolean isCaseSensitive, boolean isCamelCase) {
+	char[][] arguments = Signature.getParameterTypes(methodDescriptor);
+	int parameterCount = parameterSimpleNames.length;
+	if (parameterCount != arguments.length) return false;
+	for (int i = 0; i < parameterCount; i++)
+		if (!checkTypeName(parameterSimpleNames[i], parameterQualifications[i], Signature.toCharArray(arguments[i]), isCaseSensitive, isCamelCase))
+			return false;
+	return true;
+}
+private boolean checkStandardAnnotations(long annotationTagBits, TypeReferencePattern pattern) {
+	if ((annotationTagBits & TagBits.AllStandardAnnotationsMask) == 0) {
+		return false;
+	}
+	if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) ||
+			((annotationTagBits & TARGET_ANNOTATION_BITS) != 0 && checkAnnotationTypeReference(JAVA_LANG_ANNOTATION_ELEMENTTYPE, pattern))) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern) ||
+			checkAnnotationTypeReference(CharOperation.concatWith(TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationInherited) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationOverride) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_SAFEVARARGS;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+		char[][] compoundName = TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE;
+		if (checkAnnotationTypeReference(CharOperation.concatWith(compoundName, '.'), pattern)) {
+			return true;
+		}
+	}
+	return false;
+}
+private boolean checkTypeName(char[] simpleName, char[] qualification, char[] fullyQualifiedTypeName, boolean isCaseSensitive, boolean isCamelCase) {
+	// NOTE: if case insensitive then simpleName & qualification are assumed to be lowercase
+	char[] wildcardPattern = PatternLocator.qualifiedPattern(simpleName, qualification);
+	if (wildcardPattern == null) return true;
+	return CharOperation.match(wildcardPattern, fullyQualifiedTypeName, isCaseSensitive);
+}
+/**
+ * Locate declaration in the current class file. This class file is always in a jar.
+ */
+public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info) throws CoreException {
+	SearchPattern pattern = locator.pattern;
+
+	// check annotations references
+	matchAnnotations(pattern, locator, classFile, info);
+
+	// check class definition
+	BinaryType binaryType = (BinaryType) classFile.getType();
+	if (matchBinary(pattern, info, null)) {
+		binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey());
+		locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
+		return;
+	}
+
+	// Define arrays to store methods/fields from binary type if necessary
+	IBinaryMethod[] binaryMethods = info.getMethods();
+	int bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
+	IBinaryMethod[] unresolvedMethods = null;
+	char[][] binaryMethodSignatures = null;
+	boolean hasUnresolvedMethods = false;
+
+	// Get fields from binary type info
+	IBinaryField[] binaryFields = info.getFields();
+	int bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
+	IBinaryField[] unresolvedFields = null;
+	boolean hasUnresolvedFields = false;
+
+	// Report as many accurate matches as possible
+	int accuracy = SearchMatch.A_ACCURATE;
+	boolean mustResolve = pattern.mustResolve;
+	if (mustResolve) {
+		BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info);
+		if (binding != null) {
+			// filter out element not in hierarchy scope
+			if (!locator.typeInHierarchy(binding)) return;
+
+			// Search matches on resolved methods
+			MethodBinding[] availableMethods = binding.availableMethods();
+			int aMethodsLength = availableMethods == null ? 0 : availableMethods.length;
+			hasUnresolvedMethods = bMethodsLength != aMethodsLength;
+			for (int i = 0; i < aMethodsLength; i++) {
+				MethodBinding method = availableMethods[i];
+				char[] methodSignature = method.genericSignature();
+				if (methodSignature == null) methodSignature = method.signature();
+
+				// Report the match if possible
+				int level = locator.patternLocator.resolveLevel(method);
+				if (level != PatternLocator.IMPOSSIBLE_MATCH) {
+					IMethod methodHandle = binaryType.getMethod(
+						new String(method.isConstructor() ? binding.compoundName[binding.compoundName.length-1] : method.selector),
+						CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature))));
+					accuracy = level == PatternLocator.ACCURATE_MATCH ? SearchMatch.A_ACCURATE : SearchMatch.A_INACCURATE;
+					locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, accuracy);
+				}
+
+				// Remove method from unresolved list
+				if (hasUnresolvedMethods) {
+					if (binaryMethodSignatures == null) { // Store binary method signatures to avoid multiple computation
+						binaryMethodSignatures = new char[bMethodsLength][];
+						for (int j=0; j<bMethodsLength; j++) {
+							IBinaryMethod binaryMethod = binaryMethods[j];
+							char[] signature = binaryMethod.getGenericSignature();
+							if (signature == null) signature = binaryMethod.getMethodDescriptor();
+							binaryMethodSignatures[j] = signature;
+						}
+					}
+					for (int j=0; j<bMethodsLength; j++) {
+						if (CharOperation.equals(binaryMethods[j].getSelector(), method.selector) && CharOperation.equals(binaryMethodSignatures[j], methodSignature)) {
+							if (unresolvedMethods == null) {
+								System.arraycopy(binaryMethods, 0, unresolvedMethods = new IBinaryMethod[bMethodsLength], 0, bMethodsLength);
+							}
+							unresolvedMethods[j] = null;
+							break;
+						}
+					}
+				}
+			}
+
+			// Search matches on resolved fields
+			FieldBinding[] availableFields = binding.availableFields();
+			int aFieldsLength = availableFields == null ? 0 : availableFields.length;
+			hasUnresolvedFields = bFieldsLength != aFieldsLength;
+			for (int i = 0; i < aFieldsLength; i++) {
+				FieldBinding field = availableFields[i];
+
+				// Report the match if possible
+				int level = locator.patternLocator.resolveLevel(field);
+				if (level != PatternLocator.IMPOSSIBLE_MATCH) {
+					IField fieldHandle = binaryType.getField(new String(field.name));
+					accuracy = level == PatternLocator.ACCURATE_MATCH ? SearchMatch.A_ACCURATE : SearchMatch.A_INACCURATE;
+					locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, accuracy);
+				}
+
+				// Remove the field from unresolved list
+				if (hasUnresolvedFields) {
+					for (int j=0; j<bFieldsLength; j++) {
+						if ( CharOperation.equals(binaryFields[j].getName(), field.name)) {
+							if (unresolvedFields == null) {
+								System.arraycopy(binaryFields, 0, unresolvedFields = new IBinaryField[bFieldsLength], 0, bFieldsLength);
+							}
+							unresolvedFields[j] = null;
+							break;
+						}
+					}
+				}
+			}
+
+			// If all methods/fields were accurate then returns now
+			if (!hasUnresolvedMethods && !hasUnresolvedFields) {
+				return;
+			}
+		}
+		accuracy = SearchMatch.A_INACCURATE;
+	}
+
+	// Report inaccurate methods
+	if (mustResolve) binaryMethods = unresolvedMethods;
+	bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
+	for (int i=0; i < bMethodsLength; i++) {
+		IBinaryMethod method = binaryMethods[i];
+		if (method == null) continue; // impossible match or already reported as accurate
+		if (matchBinary(pattern, method, info)) {
+			char[] name;
+			if (method.isConstructor()) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=329727
+				// We don't need the enclosing type name for the constructor name
+				name = info.getSourceName();
+			} else {
+				name = method.getSelector();
+			}
+			String selector = new String(name);
+			char[] methodSignature = binaryMethodSignatures == null ? null : binaryMethodSignatures[i];
+			if (methodSignature == null) {
+				methodSignature = method.getGenericSignature();
+				if (methodSignature == null) methodSignature = method.getMethodDescriptor();
+			}
+			String[] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(methodSignature)));
+			IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
+			methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey());
+			locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
+		}
+	}
+
+	// Report inaccurate fields
+	if (mustResolve) binaryFields =  unresolvedFields;
+	bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
+	for (int i=0; i<bFieldsLength; i++) {
+		IBinaryField field = binaryFields[i];
+		if (field == null) continue; // impossible match or already reported as accurate
+		if (matchBinary(pattern, field, info)) {
+			String fieldName = new String(field.getName());
+			IField fieldHandle = binaryType.getField(fieldName);
+			fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
+			locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
+		}
+	}
+}
+/*
+ * Look for annotations references
+ */
+private void matchAnnotations(SearchPattern pattern, MatchLocator locator, ClassFile classFile, IBinaryType binaryType) throws CoreException {
+	// Only process TypeReference patterns
+	switch (pattern.kind) {
+		case TYPE_REF_PATTERN:
+			break;
+		case OR_PATTERN:
+			SearchPattern[] patterns = ((OrPattern) pattern).patterns;
+			for (int i = 0, length = patterns.length; i < length; i++) {
+				matchAnnotations(patterns[i], locator, classFile, binaryType);
+			}
+			// $FALL-THROUGH$ - fall through default to return
+		default:
+			return;
+	}
+	TypeReferencePattern typeReferencePattern  = (TypeReferencePattern) pattern;
+
+	// Look for references in class annotations
+	IBinaryAnnotation[] annotations = binaryType.getAnnotations();
+	BinaryType classFileBinaryType = (BinaryType) classFile.getType();
+	BinaryTypeBinding binaryTypeBinding = null;
+	if (checkAnnotations(typeReferencePattern, annotations, binaryType.getTagBits())) {
+		classFileBinaryType = new ResolvedBinaryType((JavaElement) classFileBinaryType.getParent(), classFileBinaryType.getElementName(), classFileBinaryType.getKey());
+		TypeReferenceMatch match = new TypeReferenceMatch(classFileBinaryType, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
+		// TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
+		match.setLocalElement(null);
+		locator.report(match);
+	}
+
+	// Look for references in methods annotations
+	MethodInfo[] methods = (MethodInfo[]) binaryType.getMethods();
+	if (methods != null) {
+		for (int i = 0, max = methods.length; i < max; i++) {
+			MethodInfo method = methods[i];
+			if (checkAnnotations(typeReferencePattern, method.getAnnotations(), method.getTagBits())) {
+					binaryTypeBinding = locator.cacheBinaryType(classFileBinaryType, binaryType);
+					IMethod methodHandle = classFileBinaryType.getMethod(
+						new String(method.isConstructor() ? binaryTypeBinding.compoundName[binaryTypeBinding.compoundName.length-1] : method.getSelector()),
+						CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor()))));
+					TypeReferenceMatch match = new TypeReferenceMatch(methodHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
+					// TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
+					match.setLocalElement(null);
+					locator.report(match);
+			}
+		}
+	}
+
+	// Look for references in fields annotations
+	FieldInfo[] fields = (FieldInfo[]) binaryType.getFields();
+	if (fields != null) {
+		for (int i = 0, max = fields.length; i < max; i++) {
+			FieldInfo field = fields[i];
+			if (checkAnnotations(typeReferencePattern, field.getAnnotations(), field.getTagBits())) {
+					IField fieldHandle = classFileBinaryType.getField(new String(field.getName()));
+					TypeReferenceMatch match = new TypeReferenceMatch(fieldHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource);
+					// TODO 3.4 M7 (frederic) - bug 209996: see how create the annotation handle from the binary and put it in the local element
+					match.setLocalElement(null);
+					locator.report(match);
+			}
+		}
+	}
+}
+/**
+ * Finds out whether the given binary info matches the search pattern.
+ * Default is to return false.
+ */
+boolean matchBinary(SearchPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	switch (pattern.kind) {
+		case CONSTRUCTOR_PATTERN :
+			return matchConstructor((ConstructorPattern) pattern, binaryInfo, enclosingBinaryType);
+		case FIELD_PATTERN :
+			return matchField((FieldPattern) pattern, binaryInfo, enclosingBinaryType);
+		case METHOD_PATTERN :
+			return matchMethod((MethodPattern) pattern, binaryInfo, enclosingBinaryType);
+		case SUPER_REF_PATTERN :
+			return matchSuperTypeReference((SuperTypeReferencePattern) pattern, binaryInfo, enclosingBinaryType);
+		case TYPE_DECL_PATTERN :
+			return matchTypeDeclaration((TypeDeclarationPattern) pattern, binaryInfo, enclosingBinaryType);
+		case OR_PATTERN :
+			SearchPattern[] patterns = ((OrPattern) pattern).patterns;
+			for (int i = 0, length = patterns.length; i < length; i++)
+				if (matchBinary(patterns[i], binaryInfo, enclosingBinaryType)) return true;
+	}
+	return false;
+}
+boolean matchConstructor(ConstructorPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	if (!pattern.findDeclarations) return false; // only relevant when finding declarations
+	if (!(binaryInfo instanceof IBinaryMethod)) return false;
+
+	IBinaryMethod method = (IBinaryMethod) binaryInfo;
+	if (!method.isConstructor()) return false;
+	if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
+		return false;
+	if (pattern.parameterSimpleNames != null) {
+		char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
+		if (!checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
+			return false;
+	}
+	return true;
+}
+boolean matchField(FieldPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	if (!pattern.findDeclarations) return false; // only relevant when finding declarations
+	if (!(binaryInfo instanceof IBinaryField)) return false;
+
+	IBinaryField field = (IBinaryField) binaryInfo;
+	if (!pattern.matchesName(pattern.name, field.getName())) return false;
+	if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
+		return false;
+
+	char[] fieldTypeSignature = Signature.toCharArray(convertClassFileFormat(field.getTypeName()));
+	return checkTypeName(pattern.typeSimpleName, pattern.typeQualification, fieldTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase());
+}
+boolean matchMethod(MethodPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	if (!pattern.findDeclarations) return false; // only relevant when finding declarations
+	if (!(binaryInfo instanceof IBinaryMethod)) return false;
+
+	IBinaryMethod method = (IBinaryMethod) binaryInfo;
+	if (!pattern.matchesName(pattern.selector, method.getSelector())) return false;
+	if (!checkDeclaringType(enclosingBinaryType, pattern.declaringSimpleName, pattern.declaringQualification, pattern.isCaseSensitive(), pattern.isCamelCase()))
+		return false;
+
+	// look at return type only if declaring type is not specified
+	boolean checkReturnType = pattern.declaringSimpleName == null && (pattern.returnSimpleName != null || pattern.returnQualification != null);
+	boolean checkParameters = pattern.parameterSimpleNames != null;
+	if (checkReturnType || checkParameters) {
+		char[] methodDescriptor = convertClassFileFormat(method.getMethodDescriptor());
+		if (checkReturnType) {
+			char[] returnTypeSignature = Signature.toCharArray(Signature.getReturnType(methodDescriptor));
+			if (!checkTypeName(pattern.returnSimpleName, pattern.returnQualification, returnTypeSignature, pattern.isCaseSensitive(), pattern.isCamelCase()))
+				return false;
+		}
+		if (checkParameters &&  !checkParameters(methodDescriptor, pattern.parameterSimpleNames, pattern.parameterQualifications, pattern.isCaseSensitive(), pattern.isCamelCase()))
+			return false;
+	}
+	return true;
+}
+boolean matchSuperTypeReference(SuperTypeReferencePattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	if (!(binaryInfo instanceof IBinaryType)) return false;
+
+	IBinaryType type = (IBinaryType) binaryInfo;
+	if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) {
+		char[] vmName = type.getSuperclassName();
+		if (vmName != null) {
+			char[] superclassName = convertClassFileFormat(vmName);
+			if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superclassName, pattern.isCaseSensitive(), pattern.isCamelCase()))
+				return true;
+		}
+	}
+
+	if (pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) {
+		char[][] superInterfaces = type.getInterfaceNames();
+		if (superInterfaces != null) {
+			for (int i = 0, max = superInterfaces.length; i < max; i++) {
+				char[] superInterfaceName = convertClassFileFormat(superInterfaces[i]);
+				if (checkTypeName(pattern.superSimpleName, pattern.superQualification, superInterfaceName, pattern.isCaseSensitive(), pattern.isCamelCase()))
+					return true;
+			}
+		}
+	}
+	return false;
+}
+boolean matchTypeDeclaration(TypeDeclarationPattern pattern, Object binaryInfo, IBinaryType enclosingBinaryType) {
+	if (!(binaryInfo instanceof IBinaryType)) return false;
+
+	IBinaryType type = (IBinaryType) binaryInfo;
+	char[] fullyQualifiedTypeName = convertClassFileFormat(type.getName());
+	boolean qualifiedPattern = pattern instanceof QualifiedTypeDeclarationPattern;
+	if (pattern.enclosingTypeNames == null || qualifiedPattern) {
+		char[] simpleName = (pattern.getMatchMode() == SearchPattern.R_PREFIX_MATCH)
+			? CharOperation.concat(pattern.simpleName, IIndexConstants.ONE_STAR)
+			: pattern.simpleName;
+		char[] pkg = qualifiedPattern ? ((QualifiedTypeDeclarationPattern)pattern).qualification : pattern.pkg;
+		if (!checkTypeName(simpleName, pkg, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
+	} else {
+		char[] enclosingTypeName = CharOperation.concatWith(pattern.enclosingTypeNames, '.');
+		char[] patternString = pattern.pkg == null
+			? enclosingTypeName
+			: CharOperation.concat(pattern.pkg, enclosingTypeName, '.');
+		if (!checkTypeName(pattern.simpleName, patternString, fullyQualifiedTypeName, pattern.isCaseSensitive(), pattern.isCamelCase())) return false;
+	}
+
+	int kind  = TypeDeclaration.kind(type.getModifiers());
+	switch (pattern.typeSuffix) {
+		case CLASS_SUFFIX:
+			return kind == TypeDeclaration.CLASS_DECL;
+		case INTERFACE_SUFFIX:
+			return kind == TypeDeclaration.INTERFACE_DECL;
+		case ENUM_SUFFIX:
+			return kind == TypeDeclaration.ENUM_DECL;
+		case ANNOTATION_TYPE_SUFFIX:
+			return kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
+		case CLASS_AND_INTERFACE_SUFFIX:
+			return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.INTERFACE_DECL;
+		case CLASS_AND_ENUM_SUFFIX:
+			return kind == TypeDeclaration.CLASS_DECL || kind == TypeDeclaration.ENUM_DECL;
+		case INTERFACE_AND_ANNOTATION_SUFFIX:
+			return kind == TypeDeclaration.INTERFACE_DECL || kind == TypeDeclaration.ANNOTATION_TYPE_DECL;
+		case TYPE_SUFFIX: // nothing
+	}
+	return true;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
new file mode 100644
index 0000000..e60c625
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
+import org.eclipse.jdt.internal.core.util.ResourceCompilationUnit;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathSourceDirectory extends ClasspathLocation {
+
+	IContainer sourceFolder;
+	SimpleLookupTable directoryCache;
+	SimpleLookupTable missingPackageHolder = new SimpleLookupTable();
+	char[][] fullExclusionPatternChars;
+	char[][] fulInclusionPatternChars;
+
+ClasspathSourceDirectory(IContainer sourceFolder, char[][] fullExclusionPatternChars, char[][] fulInclusionPatternChars) {
+	this.sourceFolder = sourceFolder;
+	this.directoryCache = new SimpleLookupTable(5);
+	this.fullExclusionPatternChars = fullExclusionPatternChars;
+	this.fulInclusionPatternChars = fulInclusionPatternChars;
+}
+
+public void cleanup() {
+	this.directoryCache = null;
+}
+
+SimpleLookupTable directoryTable(String qualifiedPackageName) {
+	SimpleLookupTable dirTable = (SimpleLookupTable) this.directoryCache.get(qualifiedPackageName);
+	if (dirTable == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
+	if (dirTable != null) return dirTable;
+
+	try {
+		IResource container = this.sourceFolder.findMember(qualifiedPackageName); // this is a case-sensitive check
+		if (container instanceof IContainer) {
+			IResource[] members = ((IContainer) container).members();
+			dirTable = new SimpleLookupTable();
+			for (int i = 0, l = members.length; i < l; i++) {
+				IResource m = members[i];
+				String name;
+				if (m.getType() == IResource.FILE) {
+					int index = Util.indexOfJavaLikeExtension(name = m.getName());
+					if (index >= 0) {
+						String fullPath = m.getFullPath().toString();
+						if (!org.eclipse.jdt.internal.compiler.util.Util.isExcluded(fullPath.toCharArray(), this.fulInclusionPatternChars, this.fullExclusionPatternChars, false/*not a folder path*/)) {
+							dirTable.put(name.substring(0, index), m);
+						}
+					}
+				}
+			}
+			// look for secondary types, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=382778
+			IJavaProject project = JavaCore.create(container.getProject());
+			Map secondaryTypePaths = JavaModelManager.getJavaModelManager().secondaryTypes(project, false, null);
+			if (secondaryTypePaths.size() > 0) {
+				Map typesInPackage = (Map) secondaryTypePaths.get(qualifiedPackageName);
+				if (typesInPackage != null && typesInPackage.size() > 0) {
+					for (Iterator j = typesInPackage.keySet().iterator(); j.hasNext();) {
+						String secondaryTypeName = (String) j.next();
+						IType secondaryType = (IType) typesInPackage.get(secondaryTypeName);
+						IJavaElement parent = secondaryType.getParent();
+						String fullPath = parent.getResource().getFullPath().toString();
+						if (!org.eclipse.jdt.internal.compiler.util.Util.isExcluded(fullPath.toCharArray(), this.fulInclusionPatternChars, this.fullExclusionPatternChars, false/*not a folder path*/)) {
+							dirTable.put(secondaryTypeName, parent.getResource());
+						}
+					}
+				}
+			}
+			this.directoryCache.put(qualifiedPackageName, dirTable);
+			return dirTable;
+		}
+	} catch(CoreException ignored) {
+		// treat as if missing
+	}
+	this.directoryCache.put(qualifiedPackageName, this.missingPackageHolder);
+	return null;
+}
+
+public boolean equals(Object o) {
+	if (this == o) return true;
+	if (!(o instanceof ClasspathSourceDirectory)) return false;
+
+	return this.sourceFolder.equals(((ClasspathSourceDirectory) o).sourceFolder);
+}
+
+public NameEnvironmentAnswer findClass(String sourceFileWithoutExtension, String qualifiedPackageName, String qualifiedSourceFileWithoutExtension) {
+	SimpleLookupTable dirTable = directoryTable(qualifiedPackageName);
+	if (dirTable != null && dirTable.elementSize > 0) {
+		IFile file = (IFile) dirTable.get(sourceFileWithoutExtension);
+		if (file != null) {
+			return new NameEnvironmentAnswer(new ResourceCompilationUnit(file, file.getLocationURI()), null /* no access restriction */);
+		}
+	}
+	return null;
+}
+
+public IPath getProjectRelativePath() {
+	return this.sourceFolder.getProjectRelativePath();
+}
+
+public int hashCode() {
+	return this.sourceFolder == null ? super.hashCode() : this.sourceFolder.hashCode();
+}
+
+public boolean isPackage(String qualifiedPackageName) {
+	return directoryTable(qualifiedPackageName) != null;
+}
+
+public void reset() {
+	this.directoryCache = new SimpleLookupTable(5);
+}
+
+public String toString() {
+	return "Source classpath directory " + this.sourceFolder.getFullPath().toString(); //$NON-NLS-1$
+}
+
+public String debugPathString() {
+	return this.sourceFolder.getFullPath().toString();
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java
new file mode 100644
index 0000000..ef15815
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorDeclarationPattern.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+public class ConstructorDeclarationPattern extends ConstructorPattern {
+	public int extraFlags;
+	
+	public int declaringTypeModifiers;
+	public char[] declaringPackageName;
+	
+	public int modifiers;
+	public char[] signature;
+	public char[][] parameterTypes;
+	public char[][] parameterNames;
+
+public ConstructorDeclarationPattern(char[] declaringPackageName, char[] declaringSimpleName, int matchRule) {
+	this(matchRule);
+	this.declaringSimpleName = (this.isCaseSensitive || this.isCamelCase) ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
+	this.declaringPackageName = declaringPackageName;
+	this.findDeclarations = true;
+	this.findReferences = false;
+	this.parameterCount = -1;
+	this.mustResolve = false;
+}
+
+ConstructorDeclarationPattern(int matchRule) {
+	super(matchRule);
+}
+public void decodeIndexKey(char[] key) {
+	int last = key.length - 1;
+	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+	this.declaringSimpleName = CharOperation.subarray(key, 0, slash);
+	
+	int start = slash + 1;
+	slash = CharOperation.indexOf(SEPARATOR, key, start);
+	last = slash - 1;
+	
+	boolean isDefaultConstructor = key[last] == '#';
+	if (isDefaultConstructor) {
+		this.parameterCount = -1;
+	} else {
+		this.parameterCount = 0;
+		int power = 1;
+		for (int i = last; i >= start; i--) {
+			if (i == last) {
+				this.parameterCount = key[i] - '0';
+			} else {
+				power *= 10;
+				this.parameterCount += power * (key[i] - '0');
+			}
+		}
+	}
+	
+	slash = slash + 3;
+	last = slash - 1;
+	
+	int typeModifiersWithExtraFlags = key[last-1] + (key[last]<<16);
+	this.declaringTypeModifiers = decodeModifers(typeModifiersWithExtraFlags);
+	this.extraFlags = decodeExtraFlags(typeModifiersWithExtraFlags);
+	
+	// initialize optional fields
+	this.declaringPackageName = null;
+	this.modifiers = 0;
+	this.signature = null;
+	this.parameterTypes = null;
+	this.parameterNames = null;
+	
+	boolean isMemberType = (this.extraFlags & ExtraFlags.IsMemberType) != 0;
+	
+	if (!isMemberType) {
+		start = slash + 1;
+		if (this.parameterCount == -1) {
+			slash = key.length;
+			last = slash - 1;
+		} else {
+			slash = CharOperation.indexOf(SEPARATOR, key, start);
+		}
+		last = slash - 1;
+		
+		this.declaringPackageName = CharOperation.subarray(key, start, slash);
+		
+		start = slash + 1;
+		if (this.parameterCount == 0) {
+			slash = slash + 3;
+			last = slash - 1;
+			
+			this.modifiers = key[last-1] + (key[last]<<16);
+		} else if (this.parameterCount > 0){
+			slash = CharOperation.indexOf(SEPARATOR, key, start);
+			last = slash - 1;
+			
+			boolean hasParameterStoredAsSignature = (this.extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0;
+			if (hasParameterStoredAsSignature) {
+				this.signature  = CharOperation.subarray(key, start, slash);
+				CharOperation.replace(this.signature , '\\', SEPARATOR);
+			} else {
+				this.parameterTypes = CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
+			}
+			start = slash + 1;
+			slash = CharOperation.indexOf(SEPARATOR, key, start);
+			last = slash - 1;
+			
+			if (slash != start) {
+				this.parameterNames = CharOperation.splitOn(PARAMETER_SEPARATOR, key, start, slash);
+			}
+			
+			slash = slash + 3;
+			last = slash - 1;
+			
+			this.modifiers = key[last-1] + (key[last]<<16);
+		} else {
+			this.modifiers = ClassFileConstants.AccPublic;
+		}
+	}
+	
+	removeInternalFlags(); // remove internal flags
+}
+
+public SearchPattern getBlankPattern() {
+	return new ConstructorDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	return DECL_CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	ConstructorDeclarationPattern pattern = (ConstructorDeclarationPattern) decodedPattern;
+	
+	// only top level types
+	if ((pattern.extraFlags & ExtraFlags.IsMemberType) != 0) return false;
+	
+	// check package - exact match only
+	if (this.declaringPackageName != null && !CharOperation.equals(this.declaringPackageName, pattern.declaringPackageName, true))
+		return false;
+
+	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+		&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
+}
+private void removeInternalFlags() {
+	this.extraFlags = this.extraFlags & ~ExtraFlags.ParameterTypesStoredAsSignature; // ParameterTypesStoredAsSignature is an internal flags only used to decode key
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
new file mode 100644
index 0000000..8342e17
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
@@ -0,0 +1,380 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class ConstructorLocator extends PatternLocator {
+
+protected ConstructorPattern pattern;
+
+public ConstructorLocator(ConstructorPattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ExplicitConstructorCall
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+	if (!(node instanceof ExplicitConstructorCall)) return IMPOSSIBLE_MATCH;
+
+	if (!matchParametersCount(node, ((ExplicitConstructorCall) node).arguments)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) {
+	int referencesLevel = this.pattern.findReferences ? matchLevelForReferences(node) : IMPOSSIBLE_MATCH;
+	int declarationsLevel = this.pattern.findDeclarations ? matchLevelForDeclarations(node) : IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel); // use the stronger match
+}
+public int match(Expression node, MatchingNodeSet nodeSet) { // interested in AllocationExpression
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+	if (!(node instanceof AllocationExpression)) return IMPOSSIBLE_MATCH;
+
+	// constructor name is simple type name
+	AllocationExpression allocation = (AllocationExpression) node;
+	char[][] typeName = allocation.type.getTypeName();
+	if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, typeName[typeName.length-1]))
+		return IMPOSSIBLE_MATCH;
+
+	if (!matchParametersCount(node, allocation.arguments)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+public int match(FieldDeclaration field, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+	// look only for enum constant
+	if (field.type != null || !(field.initialization instanceof AllocationExpression)) return IMPOSSIBLE_MATCH;
+
+	AllocationExpression allocation = (AllocationExpression) field.initialization;
+	if (field.binding != null && field.binding.declaringClass != null) {
+		if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, field.binding.declaringClass.sourceName()))
+			return IMPOSSIBLE_MATCH;
+	}
+
+	if (!matchParametersCount(field, allocation.arguments)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(field, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+/**
+ * Special case for message send in javadoc comment. They can be in fact bound to a constructor.
+ * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=83285"
+ */
+public int match(MessageSend msgSend, MatchingNodeSet nodeSet)  {
+	if ((msgSend.bits & ASTNode.InsideJavadoc) == 0) return IMPOSSIBLE_MATCH;
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+	if (this.pattern.declaringSimpleName == null || CharOperation.equals(msgSend.selector, this.pattern.declaringSimpleName)) {
+		return nodeSet.addMatch(msgSend, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+	}
+	return IMPOSSIBLE_MATCH;
+}
+//public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+
+	// need to look for a generated default constructor
+	return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+//public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
+
+protected int matchConstructor(MethodBinding constructor) {
+	if (!constructor.isConstructor()) return IMPOSSIBLE_MATCH;
+
+	// declaring type, simple name has already been matched by matchIndexEntry()
+	int level = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, constructor.declaringClass);
+	if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+
+	// parameter types
+	int parameterCount = this.pattern.parameterCount;
+	if (parameterCount > -1) {
+		if (constructor.parameters == null) return INACCURATE_MATCH;
+		if (parameterCount != constructor.parameters.length) return IMPOSSIBLE_MATCH;
+		for (int i = 0; i < parameterCount; i++) {
+			// TODO (frederic) use this call to refine accuracy on parameter types
+//			int newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, constructor.parameters[i]);
+			int newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], constructor.parameters[i]);
+			if (level > newLevel) {
+				if (newLevel == IMPOSSIBLE_MATCH) {
+//					if (isErasureMatch) {
+//						return ERASURE_MATCH;
+//					}
+					return IMPOSSIBLE_MATCH;
+				}
+				level = newLevel; // can only be downgraded
+			}
+		}
+	}
+	return level;
+}
+protected int matchContainer() {
+	if (this.pattern.findReferences) return ALL_CONTAINER; // handles both declarations + references & just references
+	// COMPILATION_UNIT_CONTAINER - implicit constructor call: case of Y extends X and Y doesn't define any constructor
+	// CLASS_CONTAINER - implicit constructor call: case of constructor declaration with no explicit super call
+	// METHOD_CONTAINER - reference in another constructor
+	// FIELD_CONTAINER - anonymous in a field initializer
+
+	// declarations are only found in Class
+	return CLASS_CONTAINER;
+}
+protected int matchLevelForReferences(ConstructorDeclaration constructor) {
+	ExplicitConstructorCall constructorCall = constructor.constructorCall;
+	if (constructorCall == null || constructorCall.accessMode != ExplicitConstructorCall.ImplicitSuper)
+		return IMPOSSIBLE_MATCH;
+
+	if (this.pattern.parameterSimpleNames != null) {
+		int length = this.pattern.parameterSimpleNames.length;
+		Expression[] args = constructorCall.arguments;
+		int argsLength = args == null ? 0 : args.length;
+		if (length != argsLength) return IMPOSSIBLE_MATCH;
+	}
+	return this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+}
+protected int matchLevelForDeclarations(ConstructorDeclaration constructor) {
+	// constructor name is stored in selector field
+	if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, constructor.selector))
+		return IMPOSSIBLE_MATCH;
+
+	if (this.pattern.parameterSimpleNames != null) {
+		int length = this.pattern.parameterSimpleNames.length;
+		Argument[] args = constructor.arguments;
+		int argsLength = args == null ? 0 : args.length;
+		if (length != argsLength) return IMPOSSIBLE_MATCH;
+	}
+
+	// Verify type arguments (do not reject if pattern has no argument as it can be an erasure match)
+	if (this.pattern.hasConstructorArguments()) {
+		if (constructor.typeParameters == null || constructor.typeParameters.length != this.pattern.constructorArguments.length) return IMPOSSIBLE_MATCH;
+	}
+
+	return this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+}
+boolean matchParametersCount(ASTNode node, Expression[] args) {
+	if (this.pattern.parameterSimpleNames != null && (!this.pattern.varargs || ((node.bits & ASTNode.InsideJavadoc) != 0))) {
+		int length = this.pattern.parameterCount;
+		if (length < 0) length = this.pattern.parameterSimpleNames.length;
+		int argsLength = args == null ? 0 : args.length;
+		if (length != argsLength) {
+			return false;
+		}
+	}
+	return true;
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+
+	MethodBinding constructorBinding = null;
+	boolean isSynthetic = false;
+	if (reference instanceof ExplicitConstructorCall) {
+		ExplicitConstructorCall call = (ExplicitConstructorCall) reference;
+		isSynthetic = call.isImplicitSuper();
+		constructorBinding = call.binding;
+	} else if (reference instanceof AllocationExpression) {
+		AllocationExpression alloc = (AllocationExpression) reference;
+		constructorBinding = alloc.binding;
+	} else if (reference instanceof TypeDeclaration || reference instanceof FieldDeclaration) {
+		super.matchReportReference(reference, element, elementBinding, accuracy, locator);
+		if (this.match != null) return;
+	}
+
+	// Create search match
+	this.match = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, true, isSynthetic, reference);
+
+	// Look to refine accuracy
+	if (constructorBinding instanceof ParameterizedGenericMethodBinding) { // parameterized generic method
+		// Update match regarding constructor type arguments
+		ParameterizedGenericMethodBinding parameterizedMethodBinding = (ParameterizedGenericMethodBinding) constructorBinding;
+		this.match.setRaw(parameterizedMethodBinding.isRaw);
+		TypeBinding[] typeBindings = parameterizedMethodBinding.isRaw ? null : parameterizedMethodBinding.typeArguments;
+		updateMatch(typeBindings, locator, this.pattern.constructorArguments, this.pattern.hasConstructorParameters());
+
+		// Update match regarding declaring class type arguments
+		if (constructorBinding.declaringClass.isParameterizedType() || constructorBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)constructorBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasConstructorArguments() || parameterizedBinding.isParameterizedWithOwnVariables()) {
+				// special case for constructor pattern which defines arguments but no type
+				// in this case, we only use refined accuracy for constructor
+			} else if (this.pattern.hasTypeArguments() && !this.pattern.hasConstructorArguments()) {
+				// special case for constructor pattern which defines no constructor arguments but has type ones
+				// in this case, we do not use refined accuracy
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			} else {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding constructor parameters
+		// TODO ? (frederic)
+	} else if (constructorBinding instanceof ParameterizedMethodBinding) {
+		// Update match regarding declaring class type arguments
+		if (constructorBinding.declaringClass.isParameterizedType() || constructorBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)constructorBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasConstructorArguments()) {
+				// special case for constructor pattern which defines arguments but no type
+				updateMatch(parameterizedBinding, new char[][][] {this.pattern.constructorArguments}, this.pattern.hasTypeParameters(), 0, locator);
+			} else if (!parameterizedBinding.isParameterizedWithOwnVariables()) {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding constructor parameters
+		// TODO ? (frederic)
+	} else if (this.pattern.hasConstructorArguments()) { // binding has no type params, compatible erasure if pattern does
+		this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+	}
+
+	// See whether it is necessary to report or not
+	if (this.match.getRule() == 0) return; // impossible match
+	boolean report = (this.isErasureMatch && this.match.isErasure()) || (this.isEquivalentMatch && this.match.isEquivalent()) || this.match.isExact();
+	if (!report) return;
+
+	// Report match
+	int offset = reference.sourceStart;
+	this.match.setOffset(offset);
+	this.match.setLength(reference.sourceEnd - offset + 1);
+	if (reference instanceof FieldDeclaration) { // enum declaration
+		FieldDeclaration enumConstant  = (FieldDeclaration) reference;
+		if (enumConstant.initialization instanceof QualifiedAllocationExpression) {
+			locator.reportAccurateEnumConstructorReference(this.match, enumConstant, (QualifiedAllocationExpression) enumConstant.initialization);
+			return;
+		}
+	}
+	locator.report(this.match);
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding binding, int accuracy, int length, MatchLocator locator) {
+	this.match = null;
+	int offset = reference.sourceStart;
+	if (this.pattern.findReferences) {
+		if (reference instanceof TypeDeclaration) {
+			TypeDeclaration type = (TypeDeclaration) reference;
+			AbstractMethodDeclaration[] methods = type.methods;
+			if (methods != null) {
+				for (int i = 0, max = methods.length; i < max; i++) {
+					AbstractMethodDeclaration method = methods[i];
+					boolean synthetic = method.isDefaultConstructor() && method.sourceStart < type.bodyStart;
+					this.match = locator.newMethodReferenceMatch(element, binding, accuracy, offset, length, method.isConstructor(), synthetic, method);
+				}
+			}
+		} else if (reference instanceof ConstructorDeclaration) {
+			ConstructorDeclaration constructor = (ConstructorDeclaration) reference;
+			ExplicitConstructorCall call = constructor.constructorCall;
+			boolean synthetic = call != null && call.isImplicitSuper();
+			this.match = locator.newMethodReferenceMatch(element, binding, accuracy, offset, length, constructor.isConstructor(), synthetic, constructor);
+		}
+	}
+	if (this.match != null) {
+		return this.match;
+	}
+	// super implementation...
+    return locator.newDeclarationMatch(element, binding, accuracy, reference.sourceStart, length);
+}
+public int resolveLevel(ASTNode node) {
+	if (this.pattern.findReferences) {
+		if (node instanceof AllocationExpression)
+			return resolveLevel((AllocationExpression) node);
+		if (node instanceof ExplicitConstructorCall)
+			return resolveLevel(((ExplicitConstructorCall) node).binding);
+		if (node instanceof TypeDeclaration)
+			return resolveLevel((TypeDeclaration) node);
+		if (node instanceof FieldDeclaration)
+			return resolveLevel((FieldDeclaration) node);
+		if (node instanceof JavadocMessageSend) {
+			return resolveLevel(((JavadocMessageSend)node).binding);
+		}
+	}
+	if (node instanceof ConstructorDeclaration)
+		return resolveLevel((ConstructorDeclaration) node, true);
+	return IMPOSSIBLE_MATCH;
+}
+protected int referenceType() {
+	return IJavaElement.METHOD;
+}
+protected int resolveLevel(AllocationExpression allocation) {
+	// constructor name is simple type name
+	char[][] typeName = allocation.type.getTypeName();
+	if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, typeName[typeName.length-1]))
+		return IMPOSSIBLE_MATCH;
+
+	return resolveLevel(allocation.binding);
+}
+protected int resolveLevel(FieldDeclaration field) {
+	// only accept enum constants
+	if (field.type != null || field.binding == null) return IMPOSSIBLE_MATCH;
+	if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, field.binding.type.sourceName()))
+		return IMPOSSIBLE_MATCH;
+	if (!(field.initialization instanceof AllocationExpression) || field.initialization.resolvedType.isLocalType()) return IMPOSSIBLE_MATCH;
+
+	return resolveLevel(((AllocationExpression)field.initialization).binding);
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof MethodBinding)) return IMPOSSIBLE_MATCH;
+
+	MethodBinding constructor = (MethodBinding) binding;
+	int level= matchConstructor(constructor);
+	if (level== IMPOSSIBLE_MATCH) {
+		if (constructor != constructor.original()) {
+			level= matchConstructor(constructor.original());
+		}
+	}
+	return level;
+}
+protected int resolveLevel(ConstructorDeclaration constructor, boolean checkDeclarations) {
+	int referencesLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences) {
+		ExplicitConstructorCall constructorCall = constructor.constructorCall;
+		if (constructorCall != null && constructorCall.accessMode == ExplicitConstructorCall.ImplicitSuper) {
+			// eliminate explicit super call as it will be treated with matchLevel(ExplicitConstructorCall, boolean)
+			int callCount = (constructorCall.arguments == null) ? 0 : constructorCall.arguments.length;
+			int patternCount = (this.pattern.parameterSimpleNames == null) ? 0 : this.pattern.parameterSimpleNames.length;
+			if (patternCount != callCount) {
+				referencesLevel = IMPOSSIBLE_MATCH;
+			} else {
+				referencesLevel = resolveLevel(constructorCall.binding);
+				if (referencesLevel == ACCURATE_MATCH) return ACCURATE_MATCH; // cannot get better
+			}
+		}
+	}
+	if (!checkDeclarations) return referencesLevel;
+
+	int declarationsLevel = this.pattern.findDeclarations ? resolveLevel(constructor.binding) : IMPOSSIBLE_MATCH;
+	return referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel; // answer the stronger match
+}
+protected int resolveLevel(TypeDeclaration type) {
+	// find default constructor
+	AbstractMethodDeclaration[] methods = type.methods;
+	if (methods != null) {
+		for (int i = 0, length = methods.length; i < length; i++) {
+			AbstractMethodDeclaration method = methods[i];
+			if (method.isDefaultConstructor() && method.sourceStart < type.bodyStart) // if synthetic
+				return resolveLevel((ConstructorDeclaration) method, false);
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
new file mode 100644
index 0000000..2cdb4a3
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
@@ -0,0 +1,579 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ExtraFlags;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.core.index.EntryResult;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ConstructorPattern extends JavaSearchPattern {
+
+protected boolean findDeclarations = true;
+protected boolean findReferences = true;
+
+public char[] declaringQualification;
+public char[] declaringSimpleName;
+
+public char[][] parameterQualifications;
+public char[][] parameterSimpleNames;
+public int parameterCount;
+public boolean varargs = false;
+
+// Signatures and arguments for generic search
+char[][][] parametersTypeSignatures;
+char[][][][] parametersTypeArguments;
+boolean constructorParameters = false;
+char[][] constructorArguments;
+
+protected static char[][] REF_CATEGORIES = { CONSTRUCTOR_REF };
+protected static char[][] REF_AND_DECL_CATEGORIES = { CONSTRUCTOR_REF, CONSTRUCTOR_DECL };
+protected static char[][] DECL_CATEGORIES = { CONSTRUCTOR_DECL };
+
+public final static int FINE_GRAIN_MASK =
+	IJavaSearchConstants.SUPER_REFERENCE |
+	IJavaSearchConstants.QUALIFIED_REFERENCE |
+	IJavaSearchConstants.THIS_REFERENCE |
+	IJavaSearchConstants.IMPLICIT_THIS_REFERENCE;
+
+
+/**
+ * Constructor entries are encoded as described
+ * 
+ * Binary constructor for class
+ * TypeName '/' Arity '/' TypeModifers '/' PackageName '/' Signature '/' ParameterNamesopt '/' Modifiers
+ * Source constructor for class
+ * TypeName '/' Arity '/' TypeModifers '/' PackageName '/' ParameterTypes '/' ParameterNamesopt '/' Modifiers
+ * Constructor with 0 arity for class
+ * TypeName '/' 0 '/' TypeModifers '/' PackageName '/' Modifiers
+ * Constructor for enum, interface (annotation) and class with default constructor
+ * TypeName '/' # '/' TypeModifers '/' PackageName
+ * Constructor for member type
+ * TypeName '/' Arity '/' TypeModifers
+ * 
+ * TypeModifiers contains some encoded extra information
+ * 		{@link ExtraFlags#IsMemberType}
+ * 		{@link ExtraFlags#HasNonPrivateStaticMemberTypes}
+ * 		{@link ExtraFlags#ParameterTypesStoredAsSignature}
+ */
+public static char[] createDeclarationIndexKey(
+		char[] typeName,
+		int argCount,
+		char[] signature,
+		char[][] parameterTypes,
+		char[][] parameterNames,
+		int modifiers,
+		char[] packageName,
+		int typeModifiers,
+		int extraFlags) {
+	
+	char[] countChars;
+	char[] parameterTypesChars = null;
+	char[] parameterNamesChars = null;
+	
+	if (argCount < 0) {
+		countChars = DEFAULT_CONSTRUCTOR;
+	} else {
+		countChars = argCount < 10
+		? COUNTS[argCount]
+		: ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
+		
+		if (argCount > 0) {
+			if (signature == null) {
+				if (parameterTypes != null && parameterTypes.length == argCount) {
+					char[][] parameterTypeErasures = new char[argCount][];
+					for (int i = 0; i < parameterTypes.length; i++) {
+						parameterTypeErasures[i] = getTypeErasure(parameterTypes[i]);
+					}
+					parameterTypesChars = CharOperation.concatWith(parameterTypeErasures, PARAMETER_SEPARATOR);
+				}
+			} else {
+				extraFlags |= ExtraFlags.ParameterTypesStoredAsSignature;
+			}
+			
+			if (parameterNames != null && parameterNames.length == argCount) {
+				parameterNamesChars = CharOperation.concatWith(parameterNames, PARAMETER_SEPARATOR);
+			}
+		}
+	}
+	
+	boolean isMemberType = (extraFlags & ExtraFlags.IsMemberType) != 0;
+	
+	int typeNameLength = typeName == null ? 0 : typeName.length;
+	int packageNameLength = packageName == null ? 0 : packageName.length;
+	int countCharsLength = countChars.length;
+	int parameterTypesLength = signature == null ? (parameterTypesChars == null ? 0 : parameterTypesChars.length): signature.length;
+	int parameterNamesLength = parameterNamesChars == null ? 0 : parameterNamesChars.length;
+	
+	int resultLength = typeNameLength + countCharsLength + 3; // SEPARATOR=1 + TypeModifers=2
+	if (!isMemberType) {
+		resultLength += packageNameLength + 1; // SEPARATOR=1
+		if (argCount >= 0) {
+			resultLength += 3; // SEPARATOR=1 + Modifiers=2
+		}
+		
+		if (argCount > 0) {
+			resultLength += parameterTypesLength + parameterNamesLength + 2; //SEPARATOR=1 + SEPARATOR=1
+		}
+	}
+	
+	char[] result = new char[resultLength];
+	
+	int pos = 0;
+	if (typeNameLength > 0) {
+		System.arraycopy(typeName, 0, result, pos, typeNameLength);
+		pos += typeNameLength;
+	}
+	
+	if (countCharsLength > 0) {
+		System.arraycopy(countChars, 0, result, pos, countCharsLength);
+		pos += countCharsLength;
+	}
+	
+	int typeModifiersWithExtraFlags = typeModifiers | encodeExtraFlags(extraFlags);
+	result[pos++] = SEPARATOR;
+	result[pos++] = (char) typeModifiersWithExtraFlags;
+	result[pos++] = (char) (typeModifiersWithExtraFlags>>16);
+	
+	if (!isMemberType) {
+		result[pos++] = SEPARATOR;
+		if (packageNameLength > 0) {
+			System.arraycopy(packageName, 0, result, pos, packageNameLength);
+			pos += packageNameLength;
+		}
+		
+		if (argCount == 0) {
+			result[pos++] = SEPARATOR;
+			result[pos++] = (char) modifiers;
+			result[pos++] = (char) (modifiers>>16);
+		} else if (argCount > 0) {
+			result[pos++] = SEPARATOR;
+			if (parameterTypesLength > 0) {
+				if (signature == null) {
+					System.arraycopy(parameterTypesChars, 0, result, pos, parameterTypesLength);
+				} else {
+					System.arraycopy(CharOperation.replaceOnCopy(signature, SEPARATOR, '\\'), 0, result, pos, parameterTypesLength);
+				}
+				pos += parameterTypesLength;
+			}
+			
+			result[pos++] = SEPARATOR;
+			if (parameterNamesLength > 0) {
+				System.arraycopy(parameterNamesChars, 0, result, pos, parameterNamesLength);
+				pos += parameterNamesLength;
+			}
+			
+			result[pos++] = SEPARATOR;
+			result[pos++] = (char) modifiers;
+			result[pos++] = (char) (modifiers>>16);
+		}
+		
+	}
+	
+	return result;
+}
+public static char[] createDefaultDeclarationIndexKey(
+		char[] typeName,
+		char[] packageName,
+		int typeModifiers,
+		int extraFlags) {
+	return createDeclarationIndexKey(
+			typeName,
+			-1, // used to identify default constructor
+			null,
+			null,
+			null,
+			0, //
+			packageName,
+			typeModifiers,
+			extraFlags);
+}
+
+/**
+ * Constructor entries are encoded as TypeName '/' Arity:
+ * e.g. 'X/0'
+ */
+public static char[] createIndexKey(char[] typeName, int argCount) {
+	char[] countChars = argCount < 10
+		? COUNTS[argCount]
+		: ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
+	return CharOperation.concat(typeName, countChars);
+}
+static int decodeExtraFlags(int modifiersWithExtraFlags) {
+	int extraFlags = 0;
+	
+	if ((modifiersWithExtraFlags & ASTNode.Bit28) != 0) {
+		extraFlags |= ExtraFlags.ParameterTypesStoredAsSignature;
+	}
+	
+	if ((modifiersWithExtraFlags & ASTNode.Bit29) != 0) {
+		extraFlags |= ExtraFlags.IsLocalType;
+	}
+	
+	if ((modifiersWithExtraFlags & ASTNode.Bit30) != 0) {
+		extraFlags |= ExtraFlags.IsMemberType;
+	}
+	
+	if ((modifiersWithExtraFlags & ASTNode.Bit31) != 0) {
+		extraFlags |= ExtraFlags.HasNonPrivateStaticMemberTypes;
+	}
+	
+	return extraFlags;
+}
+static int decodeModifers(int modifiersWithExtraFlags) {
+	return modifiersWithExtraFlags & ~(ASTNode.Bit31 | ASTNode.Bit30 | ASTNode.Bit29 | ASTNode.Bit28);
+}
+private static int encodeExtraFlags(int extraFlags) {
+	int encodedExtraFlags = 0;
+	
+	if ((extraFlags & ExtraFlags.ParameterTypesStoredAsSignature) != 0) {
+		encodedExtraFlags |= ASTNode.Bit28;
+	}
+	
+	if ((extraFlags & ExtraFlags.IsLocalType) != 0) {
+		encodedExtraFlags |= ASTNode.Bit29;
+	}
+	
+	if ((extraFlags & ExtraFlags.IsMemberType) != 0) {
+		encodedExtraFlags |= ASTNode.Bit30;
+	}
+	if ((extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0) {
+		encodedExtraFlags |= ASTNode.Bit31;
+	}
+	
+	return encodedExtraFlags;
+}
+private static char[] getTypeErasure(char[] typeName) {
+	int index;
+	if ((index = CharOperation.indexOf('<', typeName)) == -1) return typeName;
+	
+	int length = typeName.length;
+	char[] typeErasurename = new char[length - 2];
+	
+	System.arraycopy(typeName, 0, typeErasurename, 0, index);
+	
+	int depth = 1;
+	for (int i = index + 1; i < length; i++) {
+		switch (typeName[i]) {
+			case '<':
+				depth++;
+				break;
+			case '>':
+				depth--;
+				break;
+			default:
+				if (depth == 0) {
+					typeErasurename[index++] = typeName[i];
+				}
+				break;
+		}
+	}
+	
+	System.arraycopy(typeErasurename, 0, typeErasurename = new char[index], 0, index);
+	return typeErasurename;
+}
+ConstructorPattern(int matchRule) {
+	super(CONSTRUCTOR_PATTERN, matchRule);
+}
+public ConstructorPattern(
+	char[] declaringSimpleName,
+	char[] declaringQualification,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	int limitTo,
+	int matchRule) {
+
+	this(matchRule);
+
+	this.fineGrain = limitTo & FINE_GRAIN_MASK;
+    if (this.fineGrain == 0) {
+		switch (limitTo) {
+			case IJavaSearchConstants.DECLARATIONS :
+				this.findReferences = false;
+				break;
+			case IJavaSearchConstants.REFERENCES :
+				this.findDeclarations = false;
+				break;
+			case IJavaSearchConstants.ALL_OCCURRENCES :
+				break;
+		}
+    } else {
+		this.findDeclarations = false;
+    }
+
+	this.declaringQualification = this.isCaseSensitive ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
+	this.declaringSimpleName = (this.isCaseSensitive || this.isCamelCase) ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
+	if (parameterSimpleNames != null) {
+		this.parameterCount = parameterSimpleNames.length;
+		boolean synthetic = this.parameterCount>0 && declaringQualification != null && CharOperation.equals(CharOperation.concat(parameterQualifications[0], parameterSimpleNames[0], '.'), declaringQualification);
+		int offset = 0;
+		if (synthetic) {
+			// skip first synthetic parameter
+			this.parameterCount--;
+			offset++;
+		}
+		this.parameterQualifications = new char[this.parameterCount][];
+		this.parameterSimpleNames = new char[this.parameterCount][];
+		for (int i = 0; i < this.parameterCount; i++) {
+			this.parameterQualifications[i] = this.isCaseSensitive ? parameterQualifications[i+offset] : CharOperation.toLowerCase(parameterQualifications[i+offset]);
+			this.parameterSimpleNames[i] = this.isCaseSensitive ? parameterSimpleNames[i+offset] : CharOperation.toLowerCase(parameterSimpleNames[i+offset]);
+		}
+	} else {
+		this.parameterCount = -1;
+	}
+	this.mustResolve = mustResolve();
+}
+/*
+ * Instantiate a method pattern with signatures for generics search
+ */
+public ConstructorPattern(
+	char[] declaringSimpleName,
+	char[] declaringQualification,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	IMethod method,
+	int limitTo,
+	int matchRule) {
+
+	this(declaringSimpleName,
+		declaringQualification,
+		parameterQualifications,
+		parameterSimpleNames,
+		limitTo,
+		matchRule);
+
+	// Set flags
+	try {
+		this.varargs = (method.getFlags() & Flags.AccVarargs) != 0;
+	} catch (JavaModelException e) {
+		// do nothing
+	}
+
+	// Get unique key for parameterized constructors
+	String genericDeclaringTypeSignature = null;
+	if (method.isResolved()) {
+		String key = method.getKey();
+		BindingKey bindingKey = new BindingKey(key);
+		if (bindingKey.isParameterizedType()) {
+			genericDeclaringTypeSignature = Util.getDeclaringTypeSignature(key);
+			// Store type signature and arguments for declaring type
+			if (genericDeclaringTypeSignature != null) {
+					this.typeSignatures = Util.splitTypeLevelsSignature(genericDeclaringTypeSignature);
+					setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+			}
+		}
+	} else {
+		this.constructorParameters = true;
+		storeTypeSignaturesAndArguments(method.getDeclaringType());
+	}
+
+	// store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			this.parametersTypeSignatures = new char[length][][];
+			this.parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				this.parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				this.parametersTypeArguments[i] = Util.getAllTypeArguments(this.parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	this.constructorArguments = extractMethodArguments(method);
+	if (hasConstructorArguments())  this.mustResolve = true;
+}
+/*
+ * Instantiate a method pattern with signatures for generics search
+ */
+public ConstructorPattern(
+	char[] declaringSimpleName,
+	char[] declaringQualification,
+	String declaringSignature,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	char[][] arguments,
+	int limitTo,
+	int matchRule) {
+
+	this(declaringSimpleName,
+		declaringQualification,
+		parameterQualifications,
+		parameterSimpleNames,
+		limitTo,
+		matchRule);
+
+	// Store type signature and arguments for declaring type
+	if (declaringSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(declaringSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			this.parametersTypeSignatures = new char[length][][];
+			this.parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				this.parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				this.parametersTypeArguments[i] = Util.getAllTypeArguments(this.parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	this.constructorArguments = arguments;
+	if (arguments  == null || arguments.length == 0) {
+		if (getTypeArguments() != null && getTypeArguments().length > 0) {
+			this.constructorArguments = getTypeArguments()[0];
+		}
+	}
+	if (hasConstructorArguments())  this.mustResolve = true;
+}
+
+public void decodeIndexKey(char[] key) {
+	int last = key.length - 1;
+	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+	this.declaringSimpleName = CharOperation.subarray(key, 0, slash);
+	
+	int start = slash + 1;
+	slash = CharOperation.indexOf(SEPARATOR, key, start);
+	if (slash != -1) {
+		last = slash - 1;
+	}
+	
+	boolean isDefaultConstructor = key[last] == '#';
+	if (isDefaultConstructor) {
+		this.parameterCount = -1;
+	} else {
+		this.parameterCount = 0;
+		int power = 1;
+		for (int i = last; i >= start; i--) {
+			if (i == last) {
+				this.parameterCount = key[i] - '0';
+			} else {
+				power *= 10;
+				this.parameterCount += power * (key[i] - '0');
+			}
+		}
+	}
+}
+public SearchPattern getBlankPattern() {
+	return new ConstructorPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	if (this.findReferences)
+		return this.findDeclarations ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES;
+	if (this.findDeclarations)
+		return DECL_CATEGORIES;
+	return CharOperation.NO_CHAR_CHAR;
+}
+boolean hasConstructorArguments() {
+	return this.constructorArguments != null && this.constructorArguments.length > 0;
+}
+boolean hasConstructorParameters() {
+	return this.constructorParameters;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	ConstructorPattern pattern = (ConstructorPattern) decodedPattern;
+
+	return pattern.parameterCount != -1
+		&& (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+		&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
+}
+protected boolean mustResolve() {
+	if (this.declaringQualification != null) return true;
+
+	// parameter types
+	if (this.parameterSimpleNames != null)
+		for (int i = 0, max = this.parameterSimpleNames.length; i < max; i++)
+			if (this.parameterQualifications[i] != null) return true;
+	return this.findReferences; // need to check resolved default constructors and explicit constructor calls
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+	char[] key = this.declaringSimpleName; // can be null
+	int matchRule = getMatchRule();
+
+	switch(getMatchMode()) {
+		case R_EXACT_MATCH :
+			if (this.declaringSimpleName != null && this.parameterCount >= 0 && !this.varargs) {
+				key = createIndexKey(this.declaringSimpleName, this.parameterCount);
+			}
+			matchRule &= ~R_EXACT_MATCH;
+			matchRule |= R_PREFIX_MATCH;
+			break;
+		case R_PREFIX_MATCH :
+			// do a prefix query with the declaringSimpleName
+			break;
+		case R_PATTERN_MATCH :
+			if (this.parameterCount >= 0 && !this.varargs) {
+				key = CharOperation.concat(createIndexKey(this.declaringSimpleName == null ? ONE_STAR : this.declaringSimpleName, this.parameterCount), ONE_STAR);
+			} else if (this.declaringSimpleName != null && this.declaringSimpleName[this.declaringSimpleName.length - 1] != '*') {
+				key = CharOperation.concat(this.declaringSimpleName, ONE_STAR, SEPARATOR);
+			} else if (key != null){
+				key = CharOperation.concat(key, ONE_STAR);
+			}
+			// else do a pattern query with just the declaringSimpleName
+			break;
+		case R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+		case R_CAMELCASE_MATCH:
+		case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			// do a prefix query with the declaringSimpleName
+			break;
+	}
+
+	return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+}
+protected StringBuffer print(StringBuffer output) {
+	if (this.findDeclarations) {
+		output.append(this.findReferences
+			? "ConstructorCombinedPattern: " //$NON-NLS-1$
+			: "ConstructorDeclarationPattern: "); //$NON-NLS-1$
+	} else {
+		output.append("ConstructorReferencePattern: "); //$NON-NLS-1$
+	}
+	if (this.declaringQualification != null)
+		output.append(this.declaringQualification).append('.');
+	if (this.declaringSimpleName != null)
+		output.append(this.declaringSimpleName);
+	else if (this.declaringQualification != null)
+		output.append("*"); //$NON-NLS-1$
+
+	output.append('(');
+	if (this.parameterSimpleNames == null) {
+		output.append("..."); //$NON-NLS-1$
+	} else {
+		for (int i = 0, max = this.parameterSimpleNames.length; i < max; i++) {
+			if (i > 0) output.append(", "); //$NON-NLS-1$
+			if (this.parameterQualifications[i] != null) output.append(this.parameterQualifications[i]).append('.');
+			if (this.parameterSimpleNames[i] == null) output.append('*'); else output.append(this.parameterSimpleNames[i]);
+		}
+	}
+	output.append(')');
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java
new file mode 100644
index 0000000..ecb528d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class DeclarationOfAccessedFieldsPattern extends FieldPattern {
+
+protected IJavaElement enclosingElement;
+protected SimpleSet knownFields;
+
+public DeclarationOfAccessedFieldsPattern(IJavaElement enclosingElement) {
+	super(null, null, null, null, null, IJavaSearchConstants.REFERENCES, R_PATTERN_MATCH);
+
+	this.enclosingElement = enclosingElement;
+	this.knownFields = new SimpleSet();
+	this.mustResolve = true;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java
new file mode 100644
index 0000000..e07a4e0
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+//import java.util.HashSet;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class DeclarationOfReferencedMethodsPattern extends MethodPattern {
+
+protected IJavaElement enclosingElement;
+protected SimpleSet knownMethods;
+
+public DeclarationOfReferencedMethodsPattern(IJavaElement enclosingElement) {
+	super(null, null, null, null, null, null, null, null, IJavaSearchConstants.REFERENCES, R_PATTERN_MATCH);
+
+	this.enclosingElement = enclosingElement;
+	this.knownMethods = new SimpleSet();
+	this.mustResolve = true;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java
new file mode 100644
index 0000000..15de8fe
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+
+public class DeclarationOfReferencedTypesPattern extends TypeReferencePattern {
+
+protected SimpleSet knownTypes;
+protected IJavaElement enclosingElement;
+
+public DeclarationOfReferencedTypesPattern(IJavaElement enclosingElement) {
+	super(null, null, R_PATTERN_MATCH);
+
+	this.enclosingElement = enclosingElement;
+	this.knownTypes = new SimpleSet();
+	this.mustResolve = true;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
new file mode 100644
index 0000000..278f087
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.JavaElement;
+
+public class FieldLocator extends VariableLocator {
+
+protected boolean isDeclarationOfAccessedFieldsPattern;
+
+public FieldLocator(FieldPattern pattern) {
+	super(pattern);
+
+	this.isDeclarationOfAccessedFieldsPattern = this.pattern instanceof DeclarationOfAccessedFieldsPattern;
+}
+protected int fineGrain() {
+	return this.pattern.fineGrain;
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) {
+	int declarationsLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences) {
+		if (node instanceof ImportReference) {
+			// With static import, we can have static field reference in import reference
+			ImportReference importRef = (ImportReference) node;
+			int length = importRef.tokens.length-1;
+			if (importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0) && matchesName(this.pattern.name, importRef.tokens[length])) {
+				char[][] compoundName = new char[length][];
+				System.arraycopy(importRef.tokens, 0, compoundName, 0, length);
+				FieldPattern fieldPattern = (FieldPattern) this.pattern;
+				char[] declaringType = CharOperation.concat(fieldPattern.declaringQualification, fieldPattern.declaringSimpleName, '.');
+				if (matchesName(declaringType, CharOperation.concatWith(compoundName, '.'))) {
+					declarationsLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				}
+			}
+		}
+	}
+	return nodeSet.addMatch(node, declarationsLevel);
+}
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
+	int referencesLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences)
+		// must be a write only access with an initializer
+		if (this.pattern.writeAccess && !this.pattern.readAccess && node.initialization != null)
+			if (matchesName(this.pattern.name, node.name))
+				referencesLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+
+	int declarationsLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findDeclarations) {
+		switch (node.getKind()) {
+			case AbstractVariableDeclaration.FIELD :
+			case AbstractVariableDeclaration.ENUM_CONSTANT :
+				if (matchesName(this.pattern.name, node.name))
+					if (matchesTypeReference(((FieldPattern)this.pattern).typeSimpleName, node.type))
+						declarationsLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				break;
+		}
+	}
+	return nodeSet.addMatch(node, referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel); // use the stronger match
+}
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
+
+protected int matchContainer() {
+	if (this.pattern.findReferences || this.pattern.fineGrain != 0) {
+		// need to look everywhere to find in javadocs and static import
+		return ALL_CONTAINER;
+	}
+	return CLASS_CONTAINER;
+}
+protected int matchField(FieldBinding field, boolean matchName) {
+	if (field == null) return INACCURATE_MATCH;
+
+	if (matchName && !matchesName(this.pattern.name, field.readableName())) return IMPOSSIBLE_MATCH;
+
+	FieldPattern fieldPattern = (FieldPattern)this.pattern;
+	ReferenceBinding receiverBinding = field.declaringClass;
+	if (receiverBinding == null) {
+		if (field == ArrayBinding.ArrayLength)
+			// optimized case for length field of an array
+			return fieldPattern.declaringQualification == null && fieldPattern.declaringSimpleName == null
+				? ACCURATE_MATCH
+				: IMPOSSIBLE_MATCH;
+		return INACCURATE_MATCH;
+	}
+
+	// Note there is no dynamic lookup for field access
+	int declaringLevel = resolveLevelForType(fieldPattern.declaringSimpleName, fieldPattern.declaringQualification, receiverBinding);
+	if (declaringLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+
+	// look at field type only if declaring type is not specified
+	if (fieldPattern.declaringSimpleName == null) return declaringLevel;
+
+	// get real field binding
+	FieldBinding fieldBinding = field;
+	if (field instanceof ParameterizedFieldBinding) {
+		fieldBinding = ((ParameterizedFieldBinding) field).originalField;
+	}
+
+	int typeLevel = resolveLevelForType(fieldBinding.type);
+	return declaringLevel > typeLevel ? typeLevel : declaringLevel; // return the weaker match
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ * Accept to report match of static field on static import
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	if (importRef.isStatic() && binding instanceof FieldBinding) {
+		super.matchLevelAndReportImportRef(importRef, binding, locator);
+	}
+}
+protected int matchReference(Reference node, MatchingNodeSet nodeSet, boolean writeOnlyAccess) {
+	if (node instanceof FieldReference) {
+		if (matchesName(this.pattern.name, ((FieldReference) node).token))
+			return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+		return IMPOSSIBLE_MATCH;
+	}
+	return super.matchReference(node, nodeSet, writeOnlyAccess);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements,Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	if (this.isDeclarationOfAccessedFieldsPattern) {
+		// need exact match to be able to open on type ref
+		if (accuracy != SearchMatch.A_ACCURATE) return;
+
+		// element that references the field must be included in the enclosing element
+		DeclarationOfAccessedFieldsPattern declPattern = (DeclarationOfAccessedFieldsPattern) this.pattern;
+		while (element != null && !declPattern.enclosingElement.equals(element))
+			element = element.getParent();
+		if (element != null) {
+			if (reference instanceof FieldReference) {
+				reportDeclaration(((FieldReference) reference).binding, locator, declPattern.knownFields);
+			} else if (reference instanceof QualifiedNameReference) {
+				QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
+				Binding nameBinding = qNameRef.binding;
+				if (nameBinding instanceof FieldBinding)
+					reportDeclaration((FieldBinding)nameBinding, locator, declPattern.knownFields);
+				int otherMax = qNameRef.otherBindings == null ? 0 : qNameRef.otherBindings.length;
+				for (int i = 0; i < otherMax; i++)
+					reportDeclaration(qNameRef.otherBindings[i], locator, declPattern.knownFields);
+			} else if (reference instanceof SingleNameReference) {
+				reportDeclaration((FieldBinding)((SingleNameReference) reference).binding, locator, declPattern.knownFields);
+			}
+		}
+	} else if (reference instanceof ImportReference) {
+		ImportReference importRef = (ImportReference) reference;
+		long[] positions = importRef.sourcePositions;
+		int lastIndex = importRef.tokens.length - 1;
+		int start = (int) ((positions[lastIndex]) >>> 32);
+		int end = (int) positions[lastIndex];
+		this.match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, start, end-start+1, importRef);
+		locator.report(this.match);
+	} else if (reference instanceof FieldReference) {
+		FieldReference fieldReference = (FieldReference) reference;
+		long position = fieldReference.nameSourcePosition;
+		int start = (int) (position >>> 32);
+		int end = (int) position;
+		this.match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, start, end-start+1, fieldReference);
+		locator.report(this.match);
+	} else if (reference instanceof SingleNameReference) {
+		int offset = reference.sourceStart;
+		this.match = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
+		locator.report(this.match);
+	} else if (reference instanceof QualifiedNameReference) {
+		QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
+		int length = qNameRef.tokens.length;
+		SearchMatch[] matches = new SearchMatch[length];
+		Binding nameBinding = qNameRef.binding;
+		int indexOfFirstFieldBinding = qNameRef.indexOfFirstFieldBinding > 0 ? qNameRef.indexOfFirstFieldBinding-1 : 0;
+
+		// first token
+		if (matchesName(this.pattern.name, qNameRef.tokens[indexOfFirstFieldBinding]) && !(nameBinding instanceof LocalVariableBinding)) {
+			FieldBinding fieldBinding = nameBinding instanceof FieldBinding ? (FieldBinding) nameBinding : null;
+			if (fieldBinding == null) {
+				matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, -1, -1, reference);
+			} else {
+				switch (matchField(fieldBinding, false)) {
+					case ACCURATE_MATCH:
+						matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference);
+						break;
+					case INACCURATE_MATCH:
+						this.match = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference);
+						if (fieldBinding.type != null && fieldBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) {
+							updateMatch((ParameterizedTypeBinding) fieldBinding.type, this.pattern.getTypeArguments(), locator);
+						}
+						matches[indexOfFirstFieldBinding] = this.match;
+						break;
+				}
+			}
+		}
+
+		// other tokens
+		for (int i = indexOfFirstFieldBinding+1; i < length; i++) {
+			char[] token = qNameRef.tokens[i];
+			if (matchesName(this.pattern.name, token)) {
+				FieldBinding otherBinding = qNameRef.otherBindings == null ? null : qNameRef.otherBindings[i-(indexOfFirstFieldBinding+1)];
+				if (otherBinding == null) {
+					matches[i] = locator.newFieldReferenceMatch(element, localElement, elementBinding, accuracy, -1, -1, reference);
+				} else {
+					switch (matchField(otherBinding, false)) {
+						case ACCURATE_MATCH:
+							matches[i] = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference);
+							break;
+						case INACCURATE_MATCH:
+							this.match = locator.newFieldReferenceMatch(element, localElement, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference);
+							if (otherBinding.type != null && otherBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) {
+								updateMatch((ParameterizedTypeBinding) otherBinding.type, this.pattern.getTypeArguments(), locator);
+							}
+							matches[i] = this.match;
+							break;
+					}
+				}
+			}
+		}
+		locator.reportAccurateFieldReference(matches, qNameRef);
+	}
+}
+/* (non-Javadoc)
+ * Overridden to reject unexact matches.
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#updateMatch(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding, char[][][], org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ *
+ */
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
+	// We can only refine if locator has an unit scope.
+	if (locator.unitScope == null) return;
+	updateMatch(parameterizedBinding, patternTypeArguments, false, 0, locator);
+	if (!this.match.isExact()) {
+		// cannot accept neither erasure nor compatible match
+		this.match.setRule(0);
+	}
+}
+protected void reportDeclaration(FieldBinding fieldBinding, MatchLocator locator, SimpleSet knownFields) throws CoreException {
+	// ignore length field
+	if (fieldBinding == ArrayBinding.ArrayLength) return;
+
+	ReferenceBinding declaringClass = fieldBinding.declaringClass;
+	IType type = locator.lookupType(declaringClass);
+	if (type == null) return; // case of a secondary type
+
+	char[] bindingName = fieldBinding.name;
+	IField field = type.getField(new String(bindingName));
+	if (knownFields.addIfNotIncluded(field) == null) return;
+
+	IResource resource = type.getResource();
+	boolean isBinary = type.isBinary();
+	IBinaryType info = null;
+	if (isBinary) {
+		if (resource == null)
+			resource = type.getJavaProject().getProject();
+		info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile) type.getClassFile(), resource);
+		locator.reportBinaryMemberDeclaration(resource, field, fieldBinding, info, SearchMatch.A_ACCURATE);
+	} else {
+		if (declaringClass instanceof ParameterizedTypeBinding)
+			declaringClass = ((ParameterizedTypeBinding) declaringClass).genericType();
+		ClassScope scope = ((SourceTypeBinding) declaringClass).scope;
+		if (scope != null) {
+			TypeDeclaration typeDecl = scope.referenceContext;
+			FieldDeclaration fieldDecl = null;
+			FieldDeclaration[] fieldDecls = typeDecl.fields;
+			int length = fieldDecls == null ? 0 : fieldDecls.length;
+			for (int i = 0; i < length; i++) {
+				if (CharOperation.equals(bindingName, fieldDecls[i].name)) {
+					fieldDecl = fieldDecls[i];
+					break;
+				}
+			}
+			if (fieldDecl != null) {
+				int offset = fieldDecl.sourceStart;
+				this.match = new FieldDeclarationMatch(((JavaElement) field).resolved(fieldBinding), SearchMatch.A_ACCURATE, offset, fieldDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+				locator.report(this.match);
+			}
+		}
+	}
+}
+protected int referenceType() {
+	return IJavaElement.FIELD;
+}
+public int resolveLevel(ASTNode possiblelMatchingNode) {
+	if (this.pattern.findReferences || this.pattern.fineGrain != 0) {
+		if (possiblelMatchingNode instanceof FieldReference)
+			return matchField(((FieldReference) possiblelMatchingNode).binding, true);
+		else if (possiblelMatchingNode instanceof NameReference)
+			return resolveLevel((NameReference) possiblelMatchingNode);
+	}
+	if (possiblelMatchingNode instanceof FieldDeclaration)
+		return matchField(((FieldDeclaration) possiblelMatchingNode).binding, true);
+	return IMPOSSIBLE_MATCH;
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof FieldBinding)) return IMPOSSIBLE_MATCH;
+
+	return matchField((FieldBinding) binding, true);
+}
+protected int resolveLevel(NameReference nameRef) {
+	if (nameRef instanceof SingleNameReference)
+		return resolveLevel(nameRef.binding);
+
+	Binding binding = nameRef.binding;
+	QualifiedNameReference qNameRef = (QualifiedNameReference) nameRef;
+	FieldBinding fieldBinding = null;
+	if (binding instanceof FieldBinding) {
+		fieldBinding = (FieldBinding) binding;
+		char[] bindingName = fieldBinding.name;
+		int lastDot = CharOperation.lastIndexOf('.', bindingName);
+		if (lastDot > -1)
+			bindingName = CharOperation.subarray(bindingName, lastDot+1, bindingName.length);
+		if (matchesName(this.pattern.name, bindingName)) {
+			int level = matchField(fieldBinding, false);
+			if (level != IMPOSSIBLE_MATCH) return level;
+		}
+	}
+	int otherMax = qNameRef.otherBindings == null ? 0 : qNameRef.otherBindings.length;
+	for (int i = 0; i < otherMax; i++) {
+		char[] token = qNameRef.tokens[i + qNameRef.indexOfFirstFieldBinding];
+		if (matchesName(this.pattern.name, token)) {
+			FieldBinding otherBinding = qNameRef.otherBindings[i];
+			int level = matchField(otherBinding, false);
+			if (level != IMPOSSIBLE_MATCH) return level;
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+/* (non-Javadoc)
+ * Resolve level for type with a given binding.
+ */
+protected int resolveLevelForType(TypeBinding typeBinding) {
+	FieldPattern fieldPattern = (FieldPattern) this.pattern;
+	TypeBinding fieldTypeBinding = typeBinding;
+	if (fieldTypeBinding != null && fieldTypeBinding.isParameterizedType()) {
+		fieldTypeBinding = typeBinding.erasure();
+	}
+	return resolveLevelForType(
+			fieldPattern.typeSimpleName,
+			fieldPattern.typeQualification,
+			fieldPattern.getTypeArguments(),
+			0,
+			fieldTypeBinding);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java
new file mode 100644
index 0000000..f720f37
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class FieldPattern extends VariablePattern {
+
+// declaring type
+protected char[] declaringQualification;
+protected char[] declaringSimpleName;
+
+// type
+protected char[] typeQualification;
+protected char[] typeSimpleName;
+
+protected static char[][] REF_CATEGORIES = { REF };
+protected static char[][] REF_AND_DECL_CATEGORIES = { REF, FIELD_DECL };
+protected static char[][] DECL_CATEGORIES = { FIELD_DECL };
+
+public static char[] createIndexKey(char[] fieldName) {
+	return fieldName;
+}
+
+public FieldPattern(
+	char[] name,
+	char[] declaringQualification,
+	char[] declaringSimpleName,
+	char[] typeQualification,
+	char[] typeSimpleName,
+	int limitTo,
+	int matchRule) {
+
+	super(FIELD_PATTERN, name, limitTo, matchRule);
+
+	this.declaringQualification = this.isCaseSensitive ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
+	this.declaringSimpleName = this.isCaseSensitive ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
+	this.typeQualification = this.isCaseSensitive ? typeQualification : CharOperation.toLowerCase(typeQualification);
+	this.typeSimpleName = (this.isCaseSensitive || this.isCamelCase) ? typeSimpleName : CharOperation.toLowerCase(typeSimpleName);
+
+	this.mustResolve = mustResolve();
+}
+/*
+ * Instantiate a field pattern with additional information for generic search
+ */
+public FieldPattern(
+	char[] name,
+	char[] declaringQualification,
+	char[] declaringSimpleName,
+	char[] typeQualification,
+	char[] typeSimpleName,
+	String typeSignature,
+	int limitTo,
+	int matchRule) {
+
+	this(name, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName, limitTo, matchRule);
+
+	// store type signatures and arguments
+	if (typeSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(typeSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	}
+}
+public void decodeIndexKey(char[] key) {
+	this.name = key;
+}
+public SearchPattern getBlankPattern() {
+	return new FieldPattern(null, null, null, null, null, 0, R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[] getIndexKey() {
+	return this.name;
+}
+public char[][] getIndexCategories() {
+	if (this.findReferences || this.fineGrain != 0)
+		return this.findDeclarations || this.writeAccess ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES;
+	if (this.findDeclarations)
+		return DECL_CATEGORIES;
+	return CharOperation.NO_CHAR_CHAR;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	return true; // index key is not encoded so query results all match
+}
+protected boolean mustResolve() {
+	if (this.declaringSimpleName != null || this.declaringQualification != null) return true;
+	if (this.typeSimpleName != null || this.typeQualification != null) return true;
+
+	return super.mustResolve();
+}
+protected StringBuffer print(StringBuffer output) {
+	if (this.findDeclarations) {
+		output.append(this.findReferences
+			? "FieldCombinedPattern: " //$NON-NLS-1$
+			: "FieldDeclarationPattern: "); //$NON-NLS-1$
+	} else {
+		output.append("FieldReferencePattern: "); //$NON-NLS-1$
+	}
+	if (this.declaringQualification != null) output.append(this.declaringQualification).append('.');
+	if (this.declaringSimpleName != null)
+		output.append(this.declaringSimpleName).append('.');
+	else if (this.declaringQualification != null) output.append("*."); //$NON-NLS-1$
+	if (this.name == null) {
+		output.append("*"); //$NON-NLS-1$
+	} else {
+		output.append(this.name);
+	}
+	if (this.typeQualification != null)
+		output.append(" --> ").append(this.typeQualification).append('.'); //$NON-NLS-1$
+	else if (this.typeSimpleName != null) output.append(" --> "); //$NON-NLS-1$
+	if (this.typeSimpleName != null)
+		output.append(this.typeSimpleName);
+	else if (this.typeQualification != null) output.append("*"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ImportMatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ImportMatchLocatorParser.java
new file mode 100644
index 0000000..1779c25
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ImportMatchLocatorParser.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+class ImportMatchLocatorParser extends MatchLocatorParser {
+
+	boolean reportImportMatch;
+
+protected ImportMatchLocatorParser(ProblemReporter problemReporter, MatchLocator locator) {
+	super(problemReporter, locator);
+	this.reportImportMatch = this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.IMPORT_DECLARATION_TYPE_REFERENCE) != 0;
+}
+protected void consumeStaticImportOnDemandDeclarationName() {
+	super.consumeStaticImportOnDemandDeclarationName();
+	if (this.reportImportMatch) {
+		this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+	}
+}
+protected void consumeSingleStaticImportDeclarationName() {
+	super.consumeSingleStaticImportDeclarationName();
+	if (this.reportImportMatch) {
+		this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+	}
+}
+protected void consumeSingleTypeImportDeclarationName() {
+	super.consumeSingleTypeImportDeclarationName();
+	if (this.reportImportMatch) {
+		this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+	}
+}
+protected void consumeTypeImportOnDemandDeclarationName() {
+	super.consumeTypeImportOnDemandDeclarationName();
+	if (this.reportImportMatch) {
+		this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+	}
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IntersectingPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IntersectingPattern.java
new file mode 100644
index 0000000..87bd73f
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IntersectingPattern.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.index.*;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+
+/**
+ * Query the index multiple times and do an 'and' on the results.
+ */
+public abstract class IntersectingPattern extends JavaSearchPattern {
+
+public IntersectingPattern(int patternKind, int matchRule) {
+	super(patternKind, matchRule);
+}
+public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) throws IOException {
+	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
+
+	resetQuery();
+	SimpleSet intersectedNames = null;
+	try {
+		index.startQuery();
+		do {
+			SearchPattern pattern = currentPattern();
+			EntryResult[] entries = pattern.queryIn(index);
+			if (entries == null) return;
+
+			SearchPattern decodedResult = pattern.getBlankPattern();
+			SimpleSet newIntersectedNames = new SimpleSet(3);
+			for (int i = 0, l = entries.length; i < l; i++) {
+				if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
+
+				EntryResult entry = entries[i];
+				decodedResult.decodeIndexKey(entry.getWord());
+				if (pattern.matchesDecodedKey(decodedResult)) {
+					String[] names = entry.getDocumentNames(index);
+					if (intersectedNames != null) {
+						for (int j = 0, n = names.length; j < n; j++)
+							if (intersectedNames.includes(names[j]))
+								newIntersectedNames.add(names[j]);
+					} else {
+						for (int j = 0, n = names.length; j < n; j++)
+							newIntersectedNames.add(names[j]);
+					}
+				}
+			}
+
+			if (newIntersectedNames.elementSize == 0) return;
+			intersectedNames = newIntersectedNames;
+		} while (hasNextQuery());
+	} finally {
+		index.stopQuery();
+	}
+
+	String containerPath = index.containerPath;
+	char separator = index.separator;
+	Object[] names = intersectedNames.values;
+	for (int i = 0, l = names.length; i < l; i++)
+		if (names[i] != null)
+			acceptMatch((String) names[i], containerPath, separator, null/*no pattern*/, requestor, participant, scope, progressMonitor); // AndPatterns cannot provide the decoded result
+}
+/**
+ * Returns whether another query must be done.
+ */
+protected abstract boolean hasNextQuery();
+/**
+ * Resets the query and prepares this pattern to be queried.
+ */
+protected abstract void resetQuery();
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
new file mode 100644
index 0000000..685ad02
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.util.HashMap;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+//import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+//import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.ClasspathEntry;
+import org.eclipse.jdt.internal.core.JavaModel;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jdt.internal.core.builder.ClasspathJar;
+import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/*
+ * A name environment based on the classpath of a Java project.
+ */
+public class JavaSearchNameEnvironment implements INameEnvironment, SuffixConstants {
+
+	ClasspathLocation[] locations;
+
+	/*
+	 * A map from the fully qualified slash-separated name of the main type (String) to the working copy
+	 */
+	HashMap workingCopies;
+
+public JavaSearchNameEnvironment(IJavaProject javaProject, org.eclipse.jdt.core.ICompilationUnit[] copies) {
+	computeClasspathLocations(javaProject.getProject().getWorkspace().getRoot(), (JavaProject) javaProject);
+	try {
+		int length = copies == null ? 0 : copies.length;
+		this.workingCopies = new HashMap(length);
+		if (copies != null) {
+			for (int i = 0; i < length; i++) {
+				org.eclipse.jdt.core.ICompilationUnit workingCopy = copies[i];
+				IPackageDeclaration[] pkgs = workingCopy.getPackageDeclarations();
+				String pkg = pkgs.length > 0 ? pkgs[0].getElementName() : ""; //$NON-NLS-1$
+				String cuName = workingCopy.getElementName();
+				String mainTypeName = Util.getNameWithoutJavaLikeExtension(cuName);
+				String qualifiedMainTypeName = pkg.length() == 0 ? mainTypeName : pkg.replace('.', '/') + '/' + mainTypeName;
+				this.workingCopies.put(qualifiedMainTypeName, workingCopy);
+			}
+		}
+	} catch (JavaModelException e) {
+		// working copy doesn't exist: cannot happen
+	}
+}
+
+public void cleanup() {
+	for (int i = 0, length = this.locations.length; i < length; i++) {
+		this.locations[i].cleanup();
+	}
+}
+
+private void computeClasspathLocations(IWorkspaceRoot workspaceRoot, JavaProject javaProject) {
+
+	IPackageFragmentRoot[] roots = null;
+	try {
+		roots = javaProject.getAllPackageFragmentRoots();
+	} catch (JavaModelException e) {
+		// project doesn't exist
+		this.locations = new ClasspathLocation[0];
+		return;
+	}
+	int length = roots.length;
+	ClasspathLocation[] cpLocations = new ClasspathLocation[length];
+	int index = 0;
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	for (int i = 0; i < length; i++) {
+		PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
+		IPath path = root.getPath();
+		try {
+			if (root.isArchive()) {
+				ZipFile zipFile = manager.getZipFile(path);
+				cpLocations[index++] = new ClasspathJar(zipFile, ((ClasspathEntry) root.getRawClasspathEntry()).getAccessRuleSet());
+			} else {
+				Object target = JavaModel.getTarget(path, true);
+				if (target == null) {
+					// target doesn't exist any longer
+					// just resize cpLocations
+					System.arraycopy(cpLocations, 0, cpLocations = new ClasspathLocation[cpLocations.length-1], 0, index);
+				} else if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
+					cpLocations[index++] = new ClasspathSourceDirectory((IContainer)target, root.fullExclusionPatternChars(), root.fullInclusionPatternChars());
+				} else {
+					cpLocations[index++] = ClasspathLocation.forBinaryFolder((IContainer) target, false, ((ClasspathEntry) root.getRawClasspathEntry()).getAccessRuleSet());
+				}
+			}
+		} catch (CoreException e1) {
+			// problem opening zip file or getting root kind
+			// consider root corrupt and ignore
+			// just resize cpLocations
+			System.arraycopy(cpLocations, 0, cpLocations = new ClasspathLocation[cpLocations.length-1], 0, index);
+		}
+	}
+	this.locations = cpLocations;
+}
+
+private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName) {
+	String
+		binaryFileName = null, qBinaryFileName = null,
+		sourceFileName = null, qSourceFileName = null,
+		qPackageName = null;
+	NameEnvironmentAnswer suggestedAnswer = null;
+	for (int i = 0, length = this.locations.length; i < length; i++) {
+		ClasspathLocation location = this.locations[i];
+		NameEnvironmentAnswer answer;
+		if (location instanceof ClasspathSourceDirectory) {
+			if (sourceFileName == null) {
+				qSourceFileName = qualifiedTypeName; // doesn't include the file extension
+				sourceFileName = qSourceFileName;
+				qPackageName =  ""; //$NON-NLS-1$
+				if (qualifiedTypeName.length() > typeName.length) {
+					int typeNameStart = qSourceFileName.length() - typeName.length;
+					qPackageName =  qSourceFileName.substring(0, typeNameStart - 1);
+					sourceFileName = qSourceFileName.substring(typeNameStart);
+				}
+			}
+			ICompilationUnit workingCopy = (ICompilationUnit) this.workingCopies.get(qualifiedTypeName);
+			if (workingCopy != null) {
+				answer = new NameEnvironmentAnswer(workingCopy, null /*no access restriction*/);
+			} else {
+				answer = location.findClass(
+					sourceFileName, // doesn't include the file extension
+					qPackageName,
+					qSourceFileName);  // doesn't include the file extension
+			}
+		} else {
+			if (binaryFileName == null) {
+				qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class;
+				binaryFileName = qBinaryFileName;
+				qPackageName =  ""; //$NON-NLS-1$
+				if (qualifiedTypeName.length() > typeName.length) {
+					int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
+					qPackageName =  qBinaryFileName.substring(0, typeNameStart - 1);
+					binaryFileName = qBinaryFileName.substring(typeNameStart);
+				}
+			}
+			answer =
+				location.findClass(
+					binaryFileName,
+					qPackageName,
+					qBinaryFileName);
+		}
+		if (answer != null) {
+			if (!answer.ignoreIfBetter()) {
+				if (answer.isBetter(suggestedAnswer))
+					return answer;
+			} else if (answer.isBetter(suggestedAnswer))
+				// remember suggestion and keep looking
+				suggestedAnswer = answer;
+		}
+	}
+	if (suggestedAnswer != null)
+		// no better answer was found
+		return suggestedAnswer;
+	return null;
+}
+
+public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
+	if (typeName != null)
+		return findClass(
+			new String(CharOperation.concatWith(packageName, typeName, '/')),
+			typeName);
+	return null;
+}
+
+public NameEnvironmentAnswer findType(char[][] compoundName) {
+	if (compoundName != null)
+		return findClass(
+			new String(CharOperation.concatWith(compoundName, '/')),
+			compoundName[compoundName.length - 1]);
+	return null;
+}
+
+public boolean isPackage(char[][] compoundName, char[] packageName) {
+	return isPackage(new String(CharOperation.concatWith(compoundName, packageName, '/')));
+}
+
+public boolean isPackage(String qualifiedPackageName) {
+	for (int i = 0, length = this.locations.length; i < length; i++)
+		if (this.locations[i].isPackage(qualifiedPackageName))
+			return true;
+	return false;
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
new file mode 100644
index 0000000..f53e2e2
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
@@ -0,0 +1,446 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+
+public class JavaSearchPattern extends SearchPattern implements IIndexConstants {
+
+	/*
+	 * Whether this pattern is case sensitive.
+	 */
+	boolean isCaseSensitive;
+	/*
+	 * Whether this pattern is camel case.
+	 */
+	boolean isCamelCase;
+
+	/**
+	 * One of following pattern value:
+	 * <ul>
+	 * 	<li>{@link #R_EXACT_MATCH}</li>
+	 *		<li>{@link #R_PREFIX_MATCH}</li>
+	 *		<li>{@link #R_PATTERN_MATCH}</li>
+	 *		<li>{@link #R_REGEXP_MATCH}</li>
+	 *		<li>{@link #R_CAMELCASE_MATCH}</li>
+	 *		<li>{@link #R_CAMELCASE_SAME_PART_COUNT_MATCH}</li>
+	 * </ul>
+	 */
+	int matchMode;
+
+	/**
+	 * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
+	 */
+	int matchCompatibility;
+
+	/**
+	 * Fine grain limitation
+	 */
+	public int fineGrain = 0;
+
+	/**
+	 * Mask used on match rule for match mode.
+	 */
+	public static final int MATCH_MODE_MASK = R_EXACT_MATCH
+		| R_PREFIX_MATCH
+		| R_PATTERN_MATCH
+		| R_REGEXP_MATCH
+		| R_CAMELCASE_MATCH
+		| R_CAMELCASE_SAME_PART_COUNT_MATCH;
+
+	/**
+	 * Mask used on match rule for generic relevance.
+	 */
+	public static final int MATCH_COMPATIBILITY_MASK = R_ERASURE_MATCH | R_EQUIVALENT_MATCH | R_FULL_MATCH;
+
+	// Signatures and arguments for parameterized types search
+	char[][] typeSignatures;
+	private char[][][] typeArguments;
+	private int flags = 0;
+	static final int HAS_TYPE_ARGUMENTS = 1;
+
+	protected JavaSearchPattern(int patternKind, int matchRule) {
+		super(matchRule);
+		this.kind = patternKind;
+		// Use getMatchRule() instead of matchRule as super constructor may modify its value
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=81377
+		int rule = getMatchRule();
+		this.isCaseSensitive = (rule & R_CASE_SENSITIVE) != 0;
+		this.isCamelCase = (rule & (R_CAMELCASE_MATCH | R_CAMELCASE_SAME_PART_COUNT_MATCH)) != 0;
+		this.matchCompatibility = rule & MATCH_COMPATIBILITY_MASK;
+		this.matchMode = rule & MATCH_MODE_MASK;
+	}
+
+	/**
+	 * @param fineGrain
+	 */
+	public static String getFineGrainFlagString(final int fineGrain) {
+		if (fineGrain == 0) {
+			return "none"; //$NON-NLS-1$
+		}
+		StringBuffer buffer = new StringBuffer();
+		for (int i=1; i<=32; i++) {
+			int bit = fineGrain & (1<<(i-1));
+			if (bit != 0 && buffer.length()>0) buffer.append(" | "); //$NON-NLS-1$
+			switch (bit) {
+				case IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE:
+					buffer.append("FIELD_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE:
+					buffer.append("LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.PARAMETER_DECLARATION_TYPE_REFERENCE:
+					buffer.append("PARAMETER_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE:
+					buffer.append("SUPERTYPE_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.THROWS_CLAUSE_TYPE_REFERENCE:
+					buffer.append("THROWS_CLAUSE_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.CAST_TYPE_REFERENCE:
+					buffer.append("CAST_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.CATCH_TYPE_REFERENCE:
+					buffer.append("CATCH_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE:
+					buffer.append("CLASS_INSTANCE_CREATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.RETURN_TYPE_REFERENCE:
+					buffer.append("RETURN_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.IMPORT_DECLARATION_TYPE_REFERENCE:
+					buffer.append("IMPORT_DECLARATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE:
+					buffer.append("ANNOTATION_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE:
+					buffer.append("TYPE_ARGUMENT_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE:
+					buffer.append("TYPE_VARIABLE_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE:
+					buffer.append("WILDCARD_BOUND_TYPE_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.SUPER_REFERENCE:
+					buffer.append("SUPER_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.QUALIFIED_REFERENCE:
+					buffer.append("QUALIFIED_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.THIS_REFERENCE:
+					buffer.append("THIS_REFERENCE"); //$NON-NLS-1$
+					break;
+				case IJavaSearchConstants.IMPLICIT_THIS_REFERENCE:
+					buffer.append("IMPLICIT_THIS_REFERENCE"); //$NON-NLS-1$
+					break;
+			}
+		}
+		return buffer.toString();
+	}
+
+	public SearchPattern getBlankPattern() {
+		return null;
+	}
+
+	final int getMatchMode() {
+		return this.matchMode;
+	}
+
+	final boolean isCamelCase() {
+		return this.isCamelCase;
+	}
+
+	final boolean isCaseSensitive () {
+		return this.isCaseSensitive;
+	}
+
+	final boolean isErasureMatch() {
+		return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
+	}
+
+	final boolean isEquivalentMatch() {
+		return (this.matchCompatibility & R_EQUIVALENT_MATCH) != 0;
+	}
+
+	/*
+	 * Extract method arguments using unique key for parameterized methods
+	 * and type parameters for non-generic ones.
+	 */
+	char[][] extractMethodArguments(IMethod method) {
+
+		// Use bind key if the element is resolved
+		if (method.isResolved()) {
+			BindingKey bindingKey = new BindingKey(method.getKey());
+			if (bindingKey.isParameterizedMethod()) {
+				String[] argumentsSignatures = bindingKey.getTypeArguments();
+				int length = argumentsSignatures.length;
+				if (length > 0) {
+					char[][] methodArguments = new char[length][];
+					for (int i=0; i<length; i++) {
+						methodArguments[i] = argumentsSignatures[i].toCharArray();
+						CharOperation.replace(methodArguments[i], new char[] { '$', '/' }, '.');
+					}
+					return methodArguments;
+				}
+			}
+			return null;
+		}
+
+		// Try to get the argument using the JavaModel info
+		try {
+			ITypeParameter[] parameters = method.getTypeParameters();
+			if (parameters != null) {
+				int length = parameters.length;
+				if (length > 0) {
+					char[][] arguments = new char[length][];
+					for (int i=0; i<length; i++) {
+						arguments[i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
+					}
+					return arguments;
+				}
+			}
+		}
+		catch (JavaModelException jme) {
+			// do nothing
+		}
+		return null;
+	}
+
+	/**
+	 * @return Returns the typeArguments.
+	 */
+	final char[][][] getTypeArguments() {
+		return this.typeArguments;
+	}
+
+	/**
+	 * Returns whether the pattern has signatures or not.
+	 * If pattern {@link #typeArguments} field, this field shows that it was built
+	 * on a generic source type.
+	 * @return true if {@link #typeSignatures} field is not null and has a length greater than 0.
+	 */
+	public final boolean hasSignatures() {
+		return this.typeSignatures != null && this.typeSignatures.length > 0;
+	}
+
+	/**
+	 * Returns whether the pattern includes type arguments information or not.
+	 * @return default is false
+	 */
+	public final boolean hasTypeArguments() {
+		return (this.flags & HAS_TYPE_ARGUMENTS) != 0;
+	}
+
+	/**
+	 * Returns whether the pattern includes type parameters information or not.
+	 * @return true if {@link #typeArguments} contains type parameters instead
+	 * 	type arguments signatures.
+	 */
+	public final boolean hasTypeParameters() {
+		return !hasSignatures() && hasTypeArguments();
+	}
+
+	/**
+	 * Return whether two suffixes are compatible.
+	 *
+	 * Note that obvious compatibility values as equals and {@link IIndexConstants#TYPE_SUFFIX}
+	 * has to be tested by caller to avoid unnecessary method call...
+	 *
+	 * @param typeSuffix
+	 * @param patternSuffix
+	 * @return true if suffixes are compatible, false otherwise
+	 */
+	boolean matchDifferentTypeSuffixes(int typeSuffix, int patternSuffix) {
+		switch(typeSuffix) {
+			case CLASS_SUFFIX :
+				switch (patternSuffix) {
+					case CLASS_AND_INTERFACE_SUFFIX :
+					case CLASS_AND_ENUM_SUFFIX :
+						return true;
+				}
+				return false;
+
+			case INTERFACE_SUFFIX :
+				switch (patternSuffix) {
+					case CLASS_AND_INTERFACE_SUFFIX :
+					case INTERFACE_AND_ANNOTATION_SUFFIX:
+						return true;
+				}
+				return false;
+
+			case ENUM_SUFFIX :
+				return patternSuffix == CLASS_AND_ENUM_SUFFIX;
+
+			case ANNOTATION_TYPE_SUFFIX :
+				return patternSuffix == INTERFACE_AND_ANNOTATION_SUFFIX;
+
+			case CLASS_AND_INTERFACE_SUFFIX :
+				switch (patternSuffix) {
+					case CLASS_SUFFIX :
+					case INTERFACE_SUFFIX :
+						return true;
+				}
+				return false;
+
+			case CLASS_AND_ENUM_SUFFIX :
+				switch (patternSuffix) {
+					case CLASS_SUFFIX :
+					case ENUM_SUFFIX :
+						return true;
+				}
+				return false;
+
+			case INTERFACE_AND_ANNOTATION_SUFFIX :
+				switch (patternSuffix) {
+					case INTERFACE_SUFFIX :
+					case ANNOTATION_TYPE_SUFFIX :
+						return true;
+				}
+				return false;
+		}
+
+		// Default behavior is to match suffixes
+		return true;
+	}
+
+	protected StringBuffer print(StringBuffer output) {
+		output.append(", "); //$NON-NLS-1$
+		if (hasTypeArguments() && hasSignatures()) {
+			output.append("signature:\""); //$NON-NLS-1$
+			output.append(this.typeSignatures[0]);
+			output.append("\", "); //$NON-NLS-1$
+		}
+		switch(getMatchMode()) {
+			case R_EXACT_MATCH :
+				output.append("exact match, "); //$NON-NLS-1$
+				break;
+			case R_PREFIX_MATCH :
+				output.append("prefix match, "); //$NON-NLS-1$
+				break;
+			case R_PATTERN_MATCH :
+				output.append("pattern match, "); //$NON-NLS-1$
+				break;
+			case R_REGEXP_MATCH :
+				output.append("regexp match, "); //$NON-NLS-1$
+				break;
+			case R_CAMELCASE_MATCH :
+				output.append("camel case match, "); //$NON-NLS-1$
+				break;
+			case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+				output.append("camel case same part count match, "); //$NON-NLS-1$
+				break;
+		}
+		if (isCaseSensitive())
+			output.append("case sensitive, "); //$NON-NLS-1$
+		else
+			output.append("case insensitive, "); //$NON-NLS-1$
+		if ((this.matchCompatibility & R_FULL_MATCH) != 0) {
+			output.append("generic full match, "); //$NON-NLS-1$
+		}
+		if ((this.matchCompatibility & R_ERASURE_MATCH) != 0) {
+			output.append("generic erasure match, "); //$NON-NLS-1$
+		}
+		if ((this.matchCompatibility & R_EQUIVALENT_MATCH) != 0) {
+			output.append("generic equivalent match, "); //$NON-NLS-1$
+		}
+		output.append("fine grain: "); //$NON-NLS-1$
+		output.append(getFineGrainFlagString(this.fineGrain));
+		return output;
+	}
+
+	/**
+	 * @param typeArguments The typeArguments to set.
+	 */
+	final void setTypeArguments(char[][][] typeArguments) {
+		this.typeArguments = typeArguments;
+		// update flags
+		if (this.typeArguments != null) {
+			int length = this.typeArguments.length;
+			for (int i=0; i<length; i++) {
+				if (this.typeArguments[i] != null && this.typeArguments[i].length > 0) {
+					this.flags |= HAS_TYPE_ARGUMENTS;
+					break;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Extract and store type signatures and arguments using unique key for parameterized types
+	 * and type parameters for non-generic ones
+	 */
+	void storeTypeSignaturesAndArguments(IType type) {
+		if (type.isResolved()) {
+			BindingKey bindingKey = new BindingKey(type.getKey());
+			if (bindingKey.isParameterizedType() || bindingKey.isRawType()) {
+				String signature = bindingKey.toSignature();
+				this.typeSignatures = Util.splitTypeLevelsSignature(signature);
+				setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+			}
+			return;
+		}
+
+		// Scan hierarchy to store type arguments at each level
+		char[][][] typeParameters = new char[10][][];
+		int ptr = -1;
+		boolean hasParameters = false;
+		try {
+			IJavaElement parent = type;
+			ITypeParameter[] parameters = null;
+			while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
+				if (++ptr > typeParameters.length) {
+					System.arraycopy(typeParameters, 0, typeParameters = new char[typeParameters.length+10][][], 0, ptr);
+				}
+				IType parentType = (IType) parent;
+				parameters = parentType.getTypeParameters();
+				if (parameters !=null) {
+					int length = parameters.length;
+					if (length > 0) {
+						hasParameters = true;
+						typeParameters[ptr] = new char[length][];
+						for (int i=0; i<length; i++)
+							typeParameters[ptr][i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
+					}
+				}
+				parent = parent.getParent();
+			}
+		}
+		catch (JavaModelException jme) {
+			return;
+		}
+
+		// Store type arguments if any
+		if (hasParameters) {
+			if (++ptr < typeParameters.length)
+				System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
+			setTypeArguments(typeParameters);
+		}
+	}
+	public final String toString() {
+		return print(new StringBuffer(30)).toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java
new file mode 100644
index 0000000..a90c88d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.core.LocalVariable;
+
+public class LocalVariableLocator extends VariableLocator {
+
+public LocalVariableLocator(LocalVariablePattern pattern) {
+	super(pattern);
+}
+public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
+	int referencesLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences)
+		// must be a write only access with an initializer
+		if (this.pattern.writeAccess && !this.pattern.readAccess && node.initialization != null)
+			if (matchesName(this.pattern.name, node.name))
+				referencesLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+
+	int declarationsLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findDeclarations)
+		if (matchesName(this.pattern.name, node.name))
+			if (node.declarationSourceStart == getLocalVariable().declarationSourceStart)
+				declarationsLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+
+	return nodeSet.addMatch(node, referencesLevel >= declarationsLevel ? referencesLevel : declarationsLevel); // use the stronger match
+}
+private LocalVariable getLocalVariable() {
+	return ((LocalVariablePattern) this.pattern).localVariable;
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	int offset = -1;
+	int length = -1;
+	if (reference instanceof SingleNameReference) {
+		offset = reference.sourceStart;
+		length = reference.sourceEnd-offset+1;
+	} else if (reference instanceof QualifiedNameReference) {
+		QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
+		long sourcePosition = qNameRef.sourcePositions[0];
+		offset = (int) (sourcePosition >>> 32);
+		length = ((int) sourcePosition) - offset +1;
+	} else if (reference instanceof LocalDeclaration) {
+		LocalVariable localVariable = getLocalVariable();
+		offset = localVariable.nameStart;
+		length = localVariable.nameEnd-offset+1;
+		element = localVariable;
+		this.match = locator.newDeclarationMatch(element, null, accuracy, offset, length);
+		locator.report(this.match);
+		return;
+	}
+	if (offset >= 0) {
+		this.match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, length, reference);
+		locator.report(this.match);
+	}
+}
+protected int matchContainer() {
+	return METHOD_CONTAINER;
+}
+protected int matchLocalVariable(LocalVariableBinding variable, boolean matchName) {
+	if (variable == null) return INACCURATE_MATCH;
+
+	if (matchName && !matchesName(this.pattern.name, variable.readableName())) return IMPOSSIBLE_MATCH;
+
+	return variable.declaration.declarationSourceStart == getLocalVariable().declarationSourceStart
+		? ACCURATE_MATCH
+		: IMPOSSIBLE_MATCH;
+}
+protected int referenceType() {
+	return IJavaElement.LOCAL_VARIABLE;
+}
+public int resolveLevel(ASTNode possiblelMatchingNode) {
+	if (this.pattern.findReferences || this.pattern.fineGrain != 0)
+		if (possiblelMatchingNode instanceof NameReference)
+			return resolveLevel((NameReference) possiblelMatchingNode);
+	if (possiblelMatchingNode instanceof LocalDeclaration)
+		return matchLocalVariable(((LocalDeclaration) possiblelMatchingNode).binding, true);
+	return IMPOSSIBLE_MATCH;
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof LocalVariableBinding)) return IMPOSSIBLE_MATCH;
+
+	return matchLocalVariable((LocalVariableBinding) binding, true);
+}
+protected int resolveLevel(NameReference nameRef) {
+	return resolveLevel(nameRef.binding);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java
new file mode 100644
index 0000000..3b2b061
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.LocalVariable;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.JavaSearchScope;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class LocalVariablePattern extends VariablePattern {
+
+LocalVariable localVariable;
+
+public LocalVariablePattern(LocalVariable localVariable, int limitTo, int matchRule) {
+	super(LOCAL_VAR_PATTERN, localVariable.getElementName().toCharArray(), limitTo, matchRule);
+	this.localVariable = localVariable;
+}
+public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) {
+    IPackageFragmentRoot root = (IPackageFragmentRoot)this.localVariable.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+	String documentPath;
+	String relativePath;
+    if (root.isArchive()) {
+        IType type = (IType)this.localVariable.getAncestor(IJavaElement.TYPE);
+        relativePath = (type.getFullyQualifiedName('$')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
+        documentPath = root.getPath() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + relativePath;
+    } else {
+		IPath path = this.localVariable.getPath();
+        documentPath = path.toString();
+		relativePath = Util.relativePath(path, 1/*remove project segment*/);
+    }
+
+	if (scope instanceof JavaSearchScope) {
+		JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
+		// Get document path access restriction from java search scope
+		// Note that requestor has to verify if needed whether the document violates the access restriction or not
+		AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, index.containerPath);
+		if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the path
+			if (!requestor.acceptIndexMatch(documentPath, this, participant, access))
+				throw new OperationCanceledException();
+		}
+	} else if (scope.encloses(documentPath)) {
+		if (!requestor.acceptIndexMatch(documentPath, this, participant, null))
+			throw new OperationCanceledException();
+	}
+}
+protected StringBuffer print(StringBuffer output) {
+	if (this.findDeclarations) {
+		output.append(this.findReferences
+			? "LocalVarCombinedPattern: " //$NON-NLS-1$
+			: "LocalVarDeclarationPattern: "); //$NON-NLS-1$
+	} else {
+		output.append("LocalVarReferencePattern: "); //$NON-NLS-1$
+	}
+	output.append(this.localVariable.toStringWithAncestors());
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
new file mode 100644
index 0000000..90d2fb7
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -0,0 +1,2929 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.zip.ZipFile;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.*;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver;
+import org.eclipse.jdt.internal.core.BinaryMember;
+import org.eclipse.jdt.internal.core.BinaryType;
+import org.eclipse.jdt.internal.core.ClassFile;
+import org.eclipse.jdt.internal.core.CompilationUnit;
+import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
+import org.eclipse.jdt.internal.core.JavaElement;
+import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.JavaProject;
+import org.eclipse.jdt.internal.core.LocalVariable;
+import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.Openable;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.SourceMapper;
+import org.eclipse.jdt.internal.core.SourceMethod;
+import org.eclipse.jdt.internal.core.SourceType;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
+import org.eclipse.jdt.internal.core.util.HandleFactory;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class MatchLocator implements ITypeRequestor {
+
+public static final int MAX_AT_ONCE;
+static {
+	long maxMemory = Runtime.getRuntime().maxMemory();
+	int ratio = (int) Math.round(((double) maxMemory) / (64 * 0x100000));
+	switch (ratio) {
+		case 0:
+		case 1:
+			MAX_AT_ONCE = 100;
+			break;
+		case 2:
+			MAX_AT_ONCE = 200;
+			break;
+		case 3:
+			MAX_AT_ONCE = 300;
+			break;
+		default:
+			MAX_AT_ONCE = 400;
+			break;
+	}
+}
+
+// permanent state
+public SearchPattern pattern;
+public PatternLocator patternLocator;
+public int matchContainer;
+public SearchRequestor requestor;
+public IJavaSearchScope scope;
+public IProgressMonitor progressMonitor;
+
+public org.eclipse.jdt.core.ICompilationUnit[] workingCopies;
+public HandleFactory handleFactory;
+
+// cache of all super type names if scope is hierarchy scope
+public char[][][] allSuperTypeNames;
+
+// the following is valid for the current project
+public MatchLocatorParser parser;
+private Parser basicParser;
+public INameEnvironment nameEnvironment;
+public NameLookup nameLookup;
+public LookupEnvironment lookupEnvironment;
+public HierarchyResolver hierarchyResolver;
+
+public CompilerOptions options;
+
+// management of PossibleMatch to be processed
+public int numberOfMatches; // (numberOfMatches - 1) is the last unit in matchesToProcess
+public PossibleMatch[] matchesToProcess;
+public PossibleMatch currentPossibleMatch;
+
+/*
+ * Time spent in the IJavaSearchResultCollector
+ */
+public long resultCollectorTime = 0;
+
+// Progress information
+int progressStep;
+int progressWorked;
+
+// Binding resolution and cache
+CompilationUnitScope unitScope;
+SimpleLookupTable bindings;
+
+// Cache for method handles
+HashSet methodHandles;
+
+private final boolean searchPackageDeclaration;
+private int sourceStartOfMethodToRetain;
+private int sourceEndOfMethodToRetain;
+
+public static class WorkingCopyDocument extends JavaSearchDocument {
+	public org.eclipse.jdt.core.ICompilationUnit workingCopy;
+	WorkingCopyDocument(org.eclipse.jdt.core.ICompilationUnit workingCopy, SearchParticipant participant) {
+		super(workingCopy.getPath().toString(), participant);
+		this.charContents = ((CompilationUnit)workingCopy).getContents();
+		this.workingCopy = workingCopy;
+	}
+	public String toString() {
+		return "WorkingCopyDocument for " + getPath(); //$NON-NLS-1$
+	}
+}
+
+public static class WrappedCoreException extends RuntimeException {
+	private static final long serialVersionUID = 8354329870126121212L; // backward compatible
+	public CoreException coreException;
+	public WrappedCoreException(CoreException coreException) {
+		this.coreException = coreException;
+	}
+}
+
+public static SearchDocument[] addWorkingCopies(SearchPattern pattern, SearchDocument[] indexMatches, org.eclipse.jdt.core.ICompilationUnit[] copies, SearchParticipant participant) {
+	if (copies == null) return indexMatches;
+	// working copies take precedence over corresponding compilation units
+	HashMap workingCopyDocuments = workingCopiesThatCanSeeFocus(copies, pattern, participant);
+	if (workingCopyDocuments.size() == 0) return indexMatches;
+	SearchDocument[] matches = null;
+	int length = indexMatches.length;
+	for (int i = 0; i < length; i++) {
+		SearchDocument searchDocument = indexMatches[i];
+		if (searchDocument.getParticipant() == participant) {
+			SearchDocument workingCopyDocument = (SearchDocument) workingCopyDocuments.remove(searchDocument.getPath());
+			if (workingCopyDocument != null) {
+				if (matches == null) {
+					System.arraycopy(indexMatches, 0, matches = new SearchDocument[length], 0, length);
+				}
+				matches[i] = workingCopyDocument;
+			}
+		}
+	}
+	if (matches == null) { // no working copy
+		matches = indexMatches;
+	}
+	int remainingWorkingCopiesSize = workingCopyDocuments.size();
+	if (remainingWorkingCopiesSize != 0) {
+		System.arraycopy(matches, 0, matches = new SearchDocument[length+remainingWorkingCopiesSize], 0, length);
+		Iterator iterator = workingCopyDocuments.values().iterator();
+		int index = length;
+		while (iterator.hasNext()) {
+			matches[index++] = (SearchDocument) iterator.next();
+		}
+	}
+	return matches;
+}
+
+public static void setFocus(SearchPattern pattern, IJavaElement focus) {
+	pattern.focus = focus;
+}
+
+/*
+ * Returns the working copies that can see the given focus.
+ */
+private static HashMap workingCopiesThatCanSeeFocus(org.eclipse.jdt.core.ICompilationUnit[] copies, SearchPattern pattern, SearchParticipant participant) {
+	if (copies == null) return new HashMap();
+	HashMap result = new HashMap();
+	for (int i=0, length = copies.length; i<length; i++) {
+		org.eclipse.jdt.core.ICompilationUnit workingCopy = copies[i];
+		IPath projectOrJar = MatchLocator.getProjectOrJar(workingCopy).getPath();
+		if (pattern.focus == null || IndexSelector.canSeeFocus(pattern, projectOrJar)) {
+			result.put(
+				workingCopy.getPath().toString(),
+				new WorkingCopyDocument(workingCopy, participant)
+			);
+		}
+	}
+	return result;
+}
+
+public static ClassFileReader classFileReader(IType type) {
+	IClassFile classFile = type.getClassFile();
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	if (classFile.isOpen())
+		return (ClassFileReader) manager.getInfo(type);
+
+	PackageFragment pkg = (PackageFragment) type.getPackageFragment();
+	IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
+	try {
+		if (!root.isArchive())
+			return Util.newClassFileReader(((JavaElement) type).resource());
+
+		ZipFile zipFile = null;
+		try {
+			IPath zipPath = root.getPath();
+			if (JavaModelManager.ZIP_ACCESS_VERBOSE)
+				System.out.println("(" + Thread.currentThread() + ") [MatchLocator.classFileReader()] Creating ZipFile on " + zipPath); //$NON-NLS-1$	//$NON-NLS-2$
+			zipFile = manager.getZipFile(zipPath);
+			String classFileName = classFile.getElementName();
+			String path = Util.concatWith(pkg.names, classFileName, '/');
+			return ClassFileReader.read(zipFile, path);
+		} finally {
+			manager.closeZipFile(zipFile);
+		}
+	} catch (ClassFormatException e) {
+		// invalid class file: return null
+	} catch (CoreException e) {
+		// cannot read class file: return null
+	} catch (IOException e) {
+		// cannot read class file: return null
+	}
+	return null;
+}
+
+/**
+ * Query a given index for matching entries. Assumes the sender has opened the index and will close when finished.
+ */
+public static void findIndexMatches(SearchPattern pattern, Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor monitor) throws IOException {
+	pattern.findIndexMatches(index, requestor, participant, scope, monitor);
+}
+
+public static IJavaElement getProjectOrJar(IJavaElement element) {
+	while (!(element instanceof IJavaProject) && !(element instanceof JarPackageFragmentRoot)) {
+		element = element.getParent();
+	}
+	return element;
+}
+
+public static IJavaElement projectOrJarFocus(SearchPattern pattern) {
+	return pattern == null || pattern.focus == null ? null : getProjectOrJar(pattern.focus);
+}
+
+public MatchLocator(
+	SearchPattern pattern,
+	SearchRequestor requestor,
+	IJavaSearchScope scope,
+	IProgressMonitor progressMonitor) {
+
+	this.pattern = pattern;
+	this.patternLocator = PatternLocator.patternLocator(this.pattern);
+	this.matchContainer = this.patternLocator == null ? 0 : this.patternLocator.matchContainer();
+	this.requestor = requestor;
+	this.scope = scope;
+	this.progressMonitor = progressMonitor;
+	if (pattern instanceof PackageDeclarationPattern) {
+		this.searchPackageDeclaration = true;
+	} else if (pattern instanceof OrPattern) {
+		this.searchPackageDeclaration = ((OrPattern)pattern).hasPackageDeclaration();
+	} else {
+		this.searchPackageDeclaration = false;
+	}
+	if (pattern instanceof MethodPattern) {
+	    IType type = ((MethodPattern) pattern).declaringType;
+	    if (type != null && !type.isBinary()) {
+	    	SourceType sourceType = (SourceType) type;
+	    	IMember local = sourceType.getOuterMostLocalContext();
+	    	if (local instanceof IMethod) { // remember this method's range so we don't purge its statements.
+	    		try {
+	    			ISourceRange range = local.getSourceRange();
+	    			this.sourceStartOfMethodToRetain  = range.getOffset();
+	    			this.sourceEndOfMethodToRetain = this.sourceStartOfMethodToRetain + range.getLength() - 1; // offset is 0 based.
+	    		} catch (JavaModelException e) {
+	    			// drop silently. 
+	    		}
+	    	}
+	    }
+	}
+}
+/**
+ * Add an additional binary type
+ */
+public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+	this.lookupEnvironment.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
+}
+/**
+ * Add an additional compilation unit into the loop
+ *  ->  build compilation unit declarations, their bindings and record their results.
+ */
+public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
+	// Switch the current policy and compilation result for this unit to the requested one.
+	CompilationResult unitResult = new CompilationResult(sourceUnit, 1, 1, this.options.maxProblemsPerUnit);
+	try {
+		CompilationUnitDeclaration parsedUnit = basicParser().dietParse(sourceUnit, unitResult);
+		this.lookupEnvironment.buildTypeBindings(parsedUnit, accessRestriction);
+		this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+	} catch (AbortCompilationUnit e) {
+		// at this point, currentCompilationUnitResult may not be sourceUnit, but some other
+		// one requested further along to resolve sourceUnit.
+		if (unitResult.compilationUnit == sourceUnit) { // only report once
+			//requestor.acceptResult(unitResult.tagAsAccepted());
+		} else {
+			throw e; // want to abort enclosing request to compile
+		}
+	}
+	// Display unit error in debug mode
+	if (BasicSearchEngine.VERBOSE) {
+		if (unitResult.problemCount > 0) {
+			System.out.println(unitResult);
+		}
+	}
+}
+/**
+ * Add additional source types
+ */
+public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
+	// case of SearchableEnvironment of an IJavaProject is used
+	ISourceType sourceType = sourceTypes[0];
+	while (sourceType.getEnclosingType() != null)
+		sourceType = sourceType.getEnclosingType();
+	if (sourceType instanceof SourceTypeElementInfo) {
+		// get source
+		SourceTypeElementInfo elementInfo = (SourceTypeElementInfo) sourceType;
+		IType type = elementInfo.getHandle();
+		ICompilationUnit sourceUnit = (ICompilationUnit) type.getCompilationUnit();
+		accept(sourceUnit, accessRestriction);
+	} else {
+		CompilationResult result = new CompilationResult(sourceType.getFileName(), 1, 1, 0);
+		CompilationUnitDeclaration unit =
+			SourceTypeConverter.buildCompilationUnit(
+				sourceTypes,
+				SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+				| SourceTypeConverter.MEMBER_TYPE, // need member types
+				// no need for field initialization
+				this.lookupEnvironment.problemReporter,
+				result);
+		this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
+		this.lookupEnvironment.completeTypeBindings(unit, true);
+	}
+}
+protected Parser basicParser() {
+	if (this.basicParser == null) {
+		ProblemReporter problemReporter =
+			new ProblemReporter(
+				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+				this.options,
+				new DefaultProblemFactory());
+		this.basicParser = new Parser(problemReporter, false);
+		this.basicParser.reportOnlyOneSyntaxError = true;
+	}
+	return this.basicParser;
+}
+/*
+ * Caches the given binary type in the lookup environment and returns it.
+ * Returns the existing one if already cached.
+ * Returns null if source type binding was cached.
+ */
+protected BinaryTypeBinding cacheBinaryType(IType type, IBinaryType binaryType) throws JavaModelException {
+	IType enclosingType = type.getDeclaringType();
+	if (enclosingType != null)
+		cacheBinaryType(enclosingType, null); // cache enclosing types first, so that binary type can be found in lookup enviroment
+	if (binaryType == null) {
+		ClassFile classFile = (ClassFile) type.getClassFile();
+		try {
+			binaryType = getBinaryInfo(classFile, classFile.resource());
+		} catch (CoreException e) {
+			if (e instanceof JavaModelException) {
+				throw (JavaModelException) e;
+			} else {
+				throw new JavaModelException(e);
+			}
+		}
+	}
+	BinaryTypeBinding binding = this.lookupEnvironment.cacheBinaryType(binaryType, null /*no access restriction*/);
+	if (binding == null) { // it was already cached as a result of a previous query
+		char[][] compoundName = CharOperation.splitOn('.', type.getFullyQualifiedName().toCharArray());
+		ReferenceBinding referenceBinding = this.lookupEnvironment.getCachedType(compoundName);
+		if (referenceBinding != null && (referenceBinding instanceof BinaryTypeBinding))
+			binding = (BinaryTypeBinding) referenceBinding; // if the binding could be found and if it comes from a binary type
+	}
+	return binding;
+}
+/*
+ * Computes the super type names of the focus type if any.
+ */
+protected char[][][] computeSuperTypeNames(IType focusType) {
+	String fullyQualifiedName = focusType.getFullyQualifiedName();
+	int lastDot = fullyQualifiedName.lastIndexOf('.');
+	char[] qualification = lastDot == -1 ? CharOperation.NO_CHAR : fullyQualifiedName.substring(0, lastDot).toCharArray();
+	char[] simpleName = focusType.getElementName().toCharArray();
+
+	SuperTypeNamesCollector superTypeNamesCollector =
+		new SuperTypeNamesCollector(
+			this.pattern,
+			simpleName,
+			qualification,
+			new MatchLocator(this.pattern, this.requestor, this.scope, this.progressMonitor), // clone MatchLocator so that it has no side effect
+			focusType,
+			this.progressMonitor);
+	try {
+		this.allSuperTypeNames = superTypeNamesCollector.collect();
+	} catch (JavaModelException e) {
+		// problem collecting super type names: leave it null
+	}
+	return this.allSuperTypeNames;
+}
+/**
+ * Creates an IMethod from the given method declaration and type.
+ */
+protected IJavaElement createHandle(AbstractMethodDeclaration method, IJavaElement parent) {
+	if (!(parent instanceof IType)) return parent;
+
+	IType type = (IType) parent;
+	Argument[] arguments = method.arguments;
+	int argCount = arguments == null ? 0 : arguments.length;
+	if (type.isBinary()) {
+		// don't cache the methods of the binary type
+		// fall thru if its a constructor with a synthetic argument... find it the slower way
+		ClassFileReader reader = classFileReader(type);
+		if (reader != null) {
+			// build arguments names
+			boolean firstIsSynthetic = false;
+			if (reader.isMember() && method.isConstructor() && !Flags.isStatic(reader.getModifiers())) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=48261
+				firstIsSynthetic = true;
+				argCount++;
+			}
+			char[][] argumentTypeNames = new char[argCount][];
+			for (int i = 0; i < argCount; i++) {
+				char[] typeName = null;
+				if (i == 0 && firstIsSynthetic) {
+					typeName = type.getDeclaringType().getFullyQualifiedName().toCharArray();
+				} else if (arguments != null) {
+					TypeReference typeRef = arguments[firstIsSynthetic ? i - 1 : i].type;
+					typeName = CharOperation.concatWith(typeRef.getTypeName(), '.');
+					for (int k = 0, dim = typeRef.dimensions(); k < dim; k++)
+						typeName = CharOperation.concat(typeName, new char[] {'[', ']'});
+				}
+				if (typeName == null) {
+					// invalid type name
+					return null;
+				}
+				argumentTypeNames[i] = typeName;
+			}
+			// return binary method
+			IMethod binaryMethod = createBinaryMethodHandle(type, method.selector, argumentTypeNames);
+			if (binaryMethod == null) {
+				// when first attempt fails, try with similar matches if any...
+				PossibleMatch similarMatch = this.currentPossibleMatch.getSimilarMatch();
+				while (similarMatch != null) {
+					type = ((ClassFile)similarMatch.openable).getType();
+					binaryMethod = createBinaryMethodHandle(type, method.selector, argumentTypeNames);
+					if (binaryMethod != null) {
+						return binaryMethod;
+					}
+					similarMatch = similarMatch.getSimilarMatch();
+				}
+			}
+			return binaryMethod;
+		}
+		if (BasicSearchEngine.VERBOSE) {
+			System.out.println("Not able to createHandle for the method " + //$NON-NLS-1$
+					CharOperation.charToString(method.selector) + " May miss some results");  //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	String[] parameterTypeSignatures = new String[argCount];
+	if (arguments != null) {
+		for (int i = 0; i < argCount; i++) {
+			TypeReference typeRef = arguments[i].type;
+			char[] typeName = CharOperation.concatWith(typeRef.getParameterizedTypeName(), '.');
+			parameterTypeSignatures[i] = Signature.createTypeSignature(typeName, false);
+		}
+	}
+
+	return createMethodHandle(type, new String(method.selector), parameterTypeSignatures);
+}
+/*
+ * Create binary method handle
+ */
+IMethod createBinaryMethodHandle(IType type, char[] methodSelector, char[][] argumentTypeNames) {
+	ClassFileReader reader = MatchLocator.classFileReader(type);
+	if (reader != null) {
+		IBinaryMethod[] methods = reader.getMethods();
+		if (methods != null) {
+			int argCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
+			nextMethod : for (int i = 0, methodsLength = methods.length; i < methodsLength; i++) {
+				IBinaryMethod binaryMethod = methods[i];
+				char[] selector = binaryMethod.isConstructor() ? type.getElementName().toCharArray() : binaryMethod.getSelector();
+				if (CharOperation.equals(selector, methodSelector)) {
+					char[] signature = binaryMethod.getGenericSignature();
+					if (signature == null) signature = binaryMethod.getMethodDescriptor();
+					char[][] parameterTypes = Signature.getParameterTypes(signature);
+					if (argCount != parameterTypes.length) continue nextMethod;
+					if (argumentTypeNames != null) {
+						for (int j = 0; j < argCount; j++) {
+							char[] parameterTypeName = ClassFileMatchLocator.convertClassFileFormat(parameterTypes[j]);
+							if (!CharOperation.endsWith(Signature.toCharArray(Signature.getTypeErasure(parameterTypeName)), CharOperation.replaceOnCopy(argumentTypeNames[j], '$', '.')))
+								continue nextMethod;
+							parameterTypes[j] = parameterTypeName;
+						}
+					}
+					return (IMethod) createMethodHandle(type, new String(selector), CharOperation.toStrings(parameterTypes));
+				}
+			}
+		}
+	}
+	return null;
+}
+/*
+ * Create method handle.
+ * Store occurrences for create handle to retrieve possible duplicate ones.
+ */
+private IJavaElement createMethodHandle(IType type, String methodName, String[] parameterTypeSignatures) {
+	IMethod methodHandle = type.getMethod(methodName, parameterTypeSignatures);
+	if (methodHandle instanceof SourceMethod) {
+		while (this.methodHandles.contains(methodHandle)) {
+			((SourceMethod) methodHandle).occurrenceCount++;
+		}
+	}
+	this.methodHandles.add(methodHandle);
+	return methodHandle;
+}
+/**
+ * Creates an IField from the given field declaration and type.
+ */
+protected IJavaElement createHandle(FieldDeclaration fieldDeclaration, TypeDeclaration typeDeclaration, IJavaElement parent) {
+	if (!(parent instanceof IType)) return parent;
+	IType type = (IType) parent;
+
+	switch (fieldDeclaration.getKind()) {
+		case AbstractVariableDeclaration.FIELD :
+		case AbstractVariableDeclaration.ENUM_CONSTANT :
+			return ((IType) parent).getField(new String(fieldDeclaration.name));
+	}
+	if (type.isBinary()) {
+		// do not return initializer for binary types
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=98378
+		return type;
+	}
+	// find occurrence count of the given initializer in its type declaration
+	int occurrenceCount = 0;
+	FieldDeclaration[] fields = typeDeclaration.fields;
+	int length = fields == null ? 0 : fields.length;
+	for (int i = 0; i < length; i++) {
+		if (fields[i].getKind() == AbstractVariableDeclaration.INITIALIZER) {
+			occurrenceCount++;
+			if (fields[i].equals(fieldDeclaration)) break;
+		}
+	}
+	return ((IType) parent).getInitializer(occurrenceCount);
+}
+/**
+ * Create an handle for a local variable declaration (may be a local variable or type parameter).
+ */
+protected IJavaElement createHandle(AbstractVariableDeclaration variableDeclaration, IJavaElement parent) {
+	switch (variableDeclaration.getKind()) {
+		case AbstractVariableDeclaration.LOCAL_VARIABLE:
+			if (variableDeclaration.type.resolvedType != null) {
+				return new LocalVariable((JavaElement)parent,
+					new String(variableDeclaration.name),
+					variableDeclaration.declarationSourceStart,
+					variableDeclaration.declarationSourceEnd,
+					variableDeclaration.sourceStart,
+					variableDeclaration.sourceEnd,
+					new String(variableDeclaration.type.resolvedType.signature()),
+					variableDeclaration.annotations,
+					variableDeclaration.modifiers,
+					false
+				);
+			}
+			break;
+		case AbstractVariableDeclaration.PARAMETER:
+			if (variableDeclaration.type.resolvedType != null) {
+				return new LocalVariable((JavaElement)parent,
+					new String(variableDeclaration.name),
+					variableDeclaration.declarationSourceStart,
+					variableDeclaration.declarationSourceEnd,
+					variableDeclaration.sourceStart,
+					variableDeclaration.sourceEnd,
+					new String(variableDeclaration.type.resolvedType.signature()),
+					variableDeclaration.annotations,
+					variableDeclaration.modifiers,
+					true
+				);
+			}
+			break;
+		case AbstractVariableDeclaration.TYPE_PARAMETER:
+			return new org.eclipse.jdt.internal.core.TypeParameter((JavaElement)parent, new String(variableDeclaration.name));
+	}
+	return null;
+}
+/**
+ * Create an handle for a local variable declaration (may be a local variable or type parameter).
+ */
+protected IJavaElement createHandle(Annotation annotation, IAnnotatable parent) {
+	if (parent == null) return null;
+	TypeReference typeRef = annotation.type;
+	char[][] typeName = typeRef.getTypeName();
+	String name = new String(typeName[typeName.length-1]);
+	try {
+		IAnnotation[] annotations = parent.getAnnotations();
+		int length = annotations == null ? 0 : annotations.length;
+		for (int i=0; i<length; i++) {
+			if (annotations[i].getElementName().equals(name)) {
+				return annotations[i];
+			}
+		}
+	}
+	catch (JavaModelException jme) {
+		// skip
+	}
+	return null;
+}
+/*
+ * Create handles for a list of fields
+ */
+private IJavaElement[] createHandles(FieldDeclaration[] fields, TypeDeclaration type, IJavaElement parent) {
+	IJavaElement[] otherElements = null;
+	if (fields != null) {
+		int length = fields.length;
+		int size = 0;
+		while (size<length && fields[size] != null) {
+			size++;
+		}
+		otherElements = new IJavaElement[size];
+		for (int j=0; j<size; j++) {
+			otherElements[j] = createHandle(fields[j], type, parent);
+		}
+	}
+	return otherElements;
+}
+/*
+ * Creates hierarchy resolver if needed.
+ * Returns whether focus is visible.
+ */
+protected boolean createHierarchyResolver(IType focusType, PossibleMatch[] possibleMatches) {
+	// cache focus type if not a possible match
+	char[][] compoundName = CharOperation.splitOn('.', focusType.getFullyQualifiedName().toCharArray());
+	boolean isPossibleMatch = false;
+	for (int i = 0, length = possibleMatches.length; i < length; i++) {
+		if (CharOperation.equals(possibleMatches[i].compoundName, compoundName)) {
+			isPossibleMatch = true;
+			break;
+		}
+	}
+	if (!isPossibleMatch) {
+		if (focusType.isBinary()) {
+			try {
+				cacheBinaryType(focusType, null);
+			} catch (JavaModelException e) {
+				return false;
+			}
+		} else {
+			// cache all types in the focus' compilation unit (even secondary types)
+			accept((ICompilationUnit) focusType.getCompilationUnit(), null /*TODO no access restriction*/);
+		}
+	}
+
+	// resolve focus type
+	this.hierarchyResolver = new HierarchyResolver(this.lookupEnvironment, null/*hierarchy is not going to be computed*/);
+	ReferenceBinding binding = this.hierarchyResolver.setFocusType(compoundName);
+	return binding != null && binding.isValidBinding() && (binding.tagBits & TagBits.HierarchyHasProblems) == 0;
+}
+/**
+ * Creates an IImportDeclaration from the given import statement
+ */
+protected IJavaElement createImportHandle(ImportReference importRef) {
+	char[] importName = CharOperation.concatWith(importRef.getImportName(), '.');
+	if ((importRef.bits & ASTNode.OnDemand) != 0)
+		importName = CharOperation.concat(importName, ".*" .toCharArray()); //$NON-NLS-1$
+	Openable openable = this.currentPossibleMatch.openable;
+	if (openable instanceof CompilationUnit)
+		return ((CompilationUnit) openable).getImport(new String(importName));
+
+	// binary types do not contain import statements so just answer the top-level type as the element
+	IType binaryType = ((ClassFile) openable).getType();
+	String typeName = binaryType.getElementName();
+	int lastDollar = typeName.lastIndexOf('$');
+	if (lastDollar == -1) return binaryType;
+	return createTypeHandle(typeName.substring(0, lastDollar));
+}
+/**
+ * Creates an IImportDeclaration from the given import statement
+ */
+protected IJavaElement createPackageDeclarationHandle(CompilationUnitDeclaration unit) {
+	if (unit.isPackageInfo()) {
+		char[] packName = CharOperation.concatWith(unit.currentPackage.getImportName(), '.');
+		Openable openable = this.currentPossibleMatch.openable;
+		if (openable instanceof CompilationUnit) {
+			return ((CompilationUnit) openable).getPackageDeclaration(new String(packName));
+		}
+	}
+	return createTypeHandle(new String(unit.getMainTypeName()));
+}
+/**
+ * Creates an IType from the given simple top level type name.
+ */
+protected IType createTypeHandle(String simpleTypeName) {
+	Openable openable = this.currentPossibleMatch.openable;
+	if (openable instanceof CompilationUnit)
+		return ((CompilationUnit) openable).getType(simpleTypeName);
+
+	IType binaryType = ((ClassFile) openable).getType();
+	String binaryTypeQualifiedName = binaryType.getTypeQualifiedName();
+	if (simpleTypeName.equals(binaryTypeQualifiedName))
+		return binaryType; // answer only top-level types, sometimes the classFile is for a member/local type
+
+	// type name may be null for anonymous (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=164791)
+	String classFileName = simpleTypeName.length() == 0 ? binaryTypeQualifiedName : simpleTypeName;
+	IClassFile classFile = binaryType.getPackageFragment().getClassFile(classFileName + SuffixConstants.SUFFIX_STRING_class);
+	return classFile.getType();
+}
+protected boolean encloses(IJavaElement element) {
+	if (element != null) {
+		if (this.scope instanceof HierarchyScope)
+			return ((HierarchyScope)this.scope).encloses(element, this.progressMonitor);
+		else 
+			return this.scope.encloses(element);
+	}
+	return false;
+}
+private boolean filterEnum(SearchMatch match) {
+	
+	// filter org.apache.commons.lang.enum package for projects above 1.5 
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264	
+	IJavaElement element = (IJavaElement)match.getElement();
+	PackageFragment pkg = (PackageFragment)element.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
+	if (pkg != null) {
+		// enum was found in org.apache.commons.lang.enum at index 5
+		if (pkg.names.length == 5 && pkg.names[4].equals("enum")) {  //$NON-NLS-1$
+			if (this.options == null) {
+				IJavaProject proj = (IJavaProject)pkg.getAncestor(IJavaElement.JAVA_PROJECT);
+				String complianceStr = proj.getOption(CompilerOptions.OPTION_Source, true);
+				if (CompilerOptions.versionToJdkLevel(complianceStr) >= ClassFileConstants.JDK1_5)
+					return true;
+			} else if (this.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+/* (non-Javadoc)
+ * Return info about last type argument of a parameterized type reference.
+ * These info are made of concatenation of 2 int values which are respectively
+ *  depth and end position of the last type argument.
+ * For example, this method will return 0x300000020 for type ref List<List<List<String>>>
+ * if end position of type reference "String" equals 32.
+ */
+private long findLastTypeArgumentInfo(TypeReference typeRef) {
+	// Get last list of type arguments for parameterized qualified type reference
+	TypeReference lastTypeArgument = typeRef;
+	int depth = 0;
+	while (true) {
+		TypeReference[] lastTypeArguments = null;
+		if (lastTypeArgument instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference pqtRef = (ParameterizedQualifiedTypeReference) lastTypeArgument;
+			for (int i=pqtRef.typeArguments.length-1; i>=0 && lastTypeArguments==null; i--) {
+				lastTypeArguments = pqtRef.typeArguments[i];
+			}
+		}
+		// Get last type argument for single type reference of last list of argument of parameterized qualified type reference
+		TypeReference last = null;
+		if (lastTypeArgument instanceof ParameterizedSingleTypeReference || lastTypeArguments != null) {
+			if (lastTypeArguments == null) {
+				lastTypeArguments = ((ParameterizedSingleTypeReference)lastTypeArgument).typeArguments;
+			}
+			if (lastTypeArguments != null) {
+				for (int i=lastTypeArguments.length-1; i>=0 && last==null; i++) {
+					last = lastTypeArguments[i];
+				}
+			}
+		}
+		if (last == null) break;
+		depth++;
+		lastTypeArgument = last;
+	}
+	// Current type reference is not parameterized. So, it is the last type argument
+	return (((long) depth) << 32) + lastTypeArgument.sourceEnd;
+}
+protected IBinaryType getBinaryInfo(ClassFile classFile, IResource resource) throws CoreException {
+	BinaryType binaryType = (BinaryType) classFile.getType();
+	if (classFile.isOpen())
+		return (IBinaryType) binaryType.getElementInfo(); // reuse the info from the java model cache
+
+	// create a temporary info
+	IBinaryType info;
+	try {
+		PackageFragment pkg = (PackageFragment) classFile.getParent();
+		PackageFragmentRoot root = (PackageFragmentRoot) pkg.getParent();
+		if (root.isArchive()) {
+			// class file in a jar
+			String classFileName = classFile.getElementName();
+			String classFilePath = Util.concatWith(pkg.names, classFileName, '/');
+			ZipFile zipFile = null;
+			try {
+				zipFile = ((JarPackageFragmentRoot) root).getJar();
+				info = ClassFileReader.read(zipFile, classFilePath);
+			} finally {
+				JavaModelManager.getJavaModelManager().closeZipFile(zipFile);
+			}
+		} else {
+			// class file in a directory
+			info = Util.newClassFileReader(resource);
+		}
+		if (info == null) throw binaryType.newNotPresentException();
+		return info;
+	} catch (ClassFormatException e) {
+		//e.printStackTrace();
+		return null;
+	} catch (java.io.IOException e) {
+		throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+	}
+}
+protected IType getFocusType() {
+	return this.scope instanceof HierarchyScope ? ((HierarchyScope) this.scope).focusType : null;
+}
+protected void getMethodBodies(CompilationUnitDeclaration unit, MatchingNodeSet nodeSet) {
+	if (unit.ignoreMethodBodies) {
+		unit.ignoreFurtherInvestigation = true;
+		return; // if initial diet parse did not work, no need to dig into method bodies.
+	}
+
+	// save existing values to restore them at the end of the parsing process
+	// see bug 47079 for more details
+	int[] oldLineEnds = this.parser.scanner.lineEnds;
+	int oldLinePtr = this.parser.scanner.linePtr;
+
+	try {
+		CompilationResult compilationResult = unit.compilationResult;
+		this.parser.scanner.setSource(compilationResult);
+
+		if (this.parser.javadocParser.checkDocComment) {
+			char[] contents = compilationResult.compilationUnit.getContents();
+			this.parser.javadocParser.scanner.setSource(contents);
+		}
+		this.parser.nodeSet = nodeSet;
+		this.parser.parseBodies(unit);
+	} finally {
+		this.parser.nodeSet = null;
+		// this is done to prevent any side effects on the compilation unit result
+		// line separator positions array.
+		this.parser.scanner.lineEnds = oldLineEnds;
+		this.parser.scanner.linePtr = oldLinePtr;
+	}
+}
+protected TypeBinding getType(Object typeKey, char[] typeName) {
+	if (this.unitScope == null || typeName == null || typeName.length == 0) return null;
+	// Try to get binding from cache
+	Binding binding = (Binding) this.bindings.get(typeKey);
+	if (binding != null) {
+		if (binding instanceof TypeBinding && binding.isValidBinding())
+			return (TypeBinding) binding;
+		return null;
+	}
+	// Get binding from unit scope
+	char[][] compoundName = CharOperation.splitOn('.', typeName);
+	TypeBinding typeBinding = this.unitScope.getType(compoundName, compoundName.length);
+	if (typeBinding == null || !typeBinding.isValidBinding()) {
+		typeBinding = this.lookupEnvironment.getType(compoundName);
+	}
+	this.bindings.put(typeKey, typeBinding);
+	return typeBinding != null && typeBinding.isValidBinding() ? typeBinding : null;
+}
+public MethodBinding getMethodBinding(MethodPattern methodPattern) {
+    MethodBinding methodBinding = getMethodBinding0(methodPattern);
+    if (methodBinding != null)
+    	return methodBinding; // known to be valid.
+    // special handling for methods of anonymous/local types. Since these cannot be looked up in the environment the usual way ...
+    if (methodPattern.focus instanceof SourceMethod) {
+    	char[] typeName = PatternLocator.qualifiedPattern(methodPattern.declaringSimpleName, methodPattern.declaringQualification);
+    	if (CharOperation.indexOf(IIndexConstants.ONE_STAR, typeName, true) >= 0) { // See org.eclipse.jdt.core.search.SearchPattern.enclosingTypeNames(IType)
+    		IType type = methodPattern.declaringType;
+    		IType enclosingType = type.getDeclaringType();
+    		while (enclosingType != null) {
+    			type = enclosingType;
+    			enclosingType = type.getDeclaringType();
+    		}
+    		typeName = type.getFullyQualifiedName().toCharArray();
+    		TypeBinding declaringTypeBinding = getType(typeName, typeName);
+    		if (declaringTypeBinding instanceof SourceTypeBinding) {
+    			SourceTypeBinding sourceTypeBinding = ((SourceTypeBinding) declaringTypeBinding);
+    			ClassScope skope = sourceTypeBinding.scope;
+    			if (skope != null) {
+    				CompilationUnitDeclaration unit = skope.referenceCompilationUnit();
+    				if (unit != null) {
+    					AbstractMethodDeclaration amd = new ASTNodeFinder(unit).findMethod((IMethod) methodPattern.focus);
+    					if (amd != null && amd.binding != null && amd.binding.isValidBinding()) {
+    						this.bindings.put(methodPattern, amd.binding);
+    						return amd.binding;
+    					}
+    				}
+    			}
+    		}
+    	}
+    }
+	return null;
+}
+private MethodBinding getMethodBinding0(MethodPattern methodPattern) {
+	if (this.unitScope == null) return null;
+	// Try to get binding from cache
+	Binding binding = (Binding) this.bindings.get(methodPattern);
+	if (binding != null) {
+		if (binding instanceof MethodBinding && binding.isValidBinding())
+			return (MethodBinding) binding;
+		return null;
+	}
+	//	Get binding from unit scope
+	char[] typeName = PatternLocator.qualifiedPattern(methodPattern.declaringSimpleName, methodPattern.declaringQualification);
+	if (typeName == null) {
+		if (methodPattern.declaringType == null) return null;
+		typeName = methodPattern.declaringType.getFullyQualifiedName().toCharArray();
+	}
+	TypeBinding declaringTypeBinding = getType(typeName, typeName);
+	if (declaringTypeBinding != null) {
+		if (declaringTypeBinding.isArrayType()) {
+			declaringTypeBinding = declaringTypeBinding.leafComponentType();
+		}
+		if (!declaringTypeBinding.isBaseType()) {
+			char[][] parameterTypes = methodPattern.parameterSimpleNames;
+			if (parameterTypes == null) return null;
+			int paramTypeslength = parameterTypes.length;
+			ReferenceBinding referenceBinding = (ReferenceBinding) declaringTypeBinding;
+			MethodBinding[] methods = referenceBinding.getMethods(methodPattern.selector);
+			int methodsLength = methods.length;
+			TypeVariableBinding[] refTypeVariables = referenceBinding.typeVariables();
+			int typeVarLength = refTypeVariables==null ? 0 : refTypeVariables.length;
+			for (int i=0; i<methodsLength; i++) {
+				TypeBinding[] methodParameters = methods[i].parameters;
+				int paramLength = methodParameters==null ? 0 : methodParameters.length;
+				TypeVariableBinding[] methodTypeVariables = methods[i].typeVariables;
+				int methTypeVarLength = methodTypeVariables==null ? 0 : methodTypeVariables.length;
+				boolean found = false;
+				if (methodParameters != null && paramLength == paramTypeslength) {
+					for (int p=0; p<paramLength; p++) {
+						if (CharOperation.equals(methodParameters[p].sourceName(), parameterTypes[p])) {
+							// param erasure match
+							found = true;
+						} else {
+							// type variable
+							found = false;
+							if (refTypeVariables != null) {
+								for (int v=0; v<typeVarLength; v++) {
+									if (!CharOperation.equals(refTypeVariables[v].sourceName, parameterTypes[p])) {
+										found = false;
+										break;
+									}
+									found = true;
+								}
+							}
+							if (!found && methodTypeVariables != null) {
+								for (int v=0; v<methTypeVarLength; v++) {
+									if (!CharOperation.equals(methodTypeVariables[v].sourceName, parameterTypes[p])) {
+										found = false;
+										break;
+									}
+									found = true;
+								}
+							}
+							if (!found) break;
+						}
+					}
+				}
+				if (found) {
+					this.bindings.put(methodPattern, methods[i]);
+					return methods[i];
+				}
+			}
+		}
+	}
+	this.bindings.put(methodPattern, new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));
+	return null;
+}
+protected boolean hasAlreadyDefinedType(CompilationUnitDeclaration parsedUnit) {
+	CompilationResult result = parsedUnit.compilationResult;
+	if (result == null) return false;
+	for (int i = 0; i < result.problemCount; i++)
+		if (result.problems[i].getID() == IProblem.DuplicateTypes)
+			return true;
+	return false;
+}
+/**
+ * Create a new parser for the given project, as well as a lookup environment.
+ */
+public void initialize(JavaProject project, int possibleMatchSize) throws JavaModelException {
+	// clean up name environment only if there are several possible match as it is reused
+	// when only one possible match (bug 58581)
+	if (this.nameEnvironment != null && possibleMatchSize != 1)
+		this.nameEnvironment.cleanup();
+
+	SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.workingCopies);
+
+	// if only one possible match, a file name environment costs too much,
+	// so use the existing searchable  environment which will populate the java model
+	// only for this possible match and its required types.
+	this.nameEnvironment = possibleMatchSize == 1
+		? (INameEnvironment) searchableEnvironment
+		: (INameEnvironment) new JavaSearchNameEnvironment(project, this.workingCopies);
+
+	// create lookup environment
+	Map map = project.getOptions(true);
+	map.put(CompilerOptions.OPTION_TaskTags, org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING);
+	this.options = new CompilerOptions(map);
+	ProblemReporter problemReporter =
+		new ProblemReporter(
+			DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+			this.options,
+			new DefaultProblemFactory());
+	this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, this.nameEnvironment);
+	this.lookupEnvironment.mayTolerateMissingType = true;
+	this.parser = MatchLocatorParser.createParser(problemReporter, this);
+
+	// basic parser needs also to be reset as project options may have changed
+	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=163072
+	this.basicParser = null;
+
+	// remember project's name lookup
+	this.nameLookup = searchableEnvironment.nameLookup;
+
+	// initialize queue of units
+	this.numberOfMatches = 0;
+	this.matchesToProcess = new PossibleMatch[possibleMatchSize];
+
+	this.lookupEnvironment.addResolutionListener(this.patternLocator);
+}
+protected void locateMatches(JavaProject javaProject, PossibleMatch[] possibleMatches, int start, int length) throws CoreException {
+	initialize(javaProject, length);
+
+	// create and resolve binding (equivalent to beginCompilation() in Compiler)
+	boolean mustResolvePattern = this.pattern.mustResolve;
+	boolean mustResolve = mustResolvePattern;
+	this.patternLocator.mayBeGeneric = this.options.sourceLevel >= ClassFileConstants.JDK1_5;
+	boolean bindingsWereCreated = mustResolve;
+	try {
+		for (int i = start, maxUnits = start + length; i < maxUnits; i++) {
+			PossibleMatch possibleMatch = possibleMatches[i];
+			try {
+				if (!parseAndBuildBindings(possibleMatch, mustResolvePattern)) continue;
+				// Currently we only need to resolve over pattern flag if there's potential parameterized types
+				if (this.patternLocator.mayBeGeneric) {
+					// If pattern does not resolve then rely on possible match node set resolution
+					// which may have been modified while locator was adding possible matches to it
+					if (!mustResolvePattern && !mustResolve) {
+						mustResolve = possibleMatch.nodeSet.mustResolve;
+						bindingsWereCreated = mustResolve;
+					}
+				} else {
+					// Reset matching node resolution with pattern one if there's no potential parameterized type
+					// to minimize side effect on previous search behavior
+					possibleMatch.nodeSet.mustResolve = mustResolvePattern;
+				}
+				// possible match node resolution has been merged with pattern one, so rely on it to know
+				// whether we need to process compilation unit now or later
+				if (!possibleMatch.nodeSet.mustResolve) {
+					if (this.progressMonitor != null) {
+						this.progressWorked++;
+						if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+					}
+					process(possibleMatch, bindingsWereCreated);
+					if (this.numberOfMatches>0 && this.matchesToProcess[this.numberOfMatches-1] == possibleMatch) {
+						// forget last possible match as it was processed
+						this.numberOfMatches--;
+					}
+				}
+			} finally {
+				if (possibleMatch.hasSimilarMatch()) {
+					// If there is similar match, then also process it
+					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=211872
+					possibleMatches[i] = possibleMatch.getSimilarMatch();
+					i--;
+				}
+				if (!possibleMatch.nodeSet.mustResolve)
+					possibleMatch.cleanUp();
+			}
+		}
+		if (mustResolve)
+			this.lookupEnvironment.completeTypeBindings();
+
+		// create hierarchy resolver if needed
+		IType focusType = getFocusType();
+		if (focusType == null) {
+			this.hierarchyResolver = null;
+		} else if (!createHierarchyResolver(focusType, possibleMatches)) {
+			// focus type is not visible, use the super type names instead of the bindings
+			if (computeSuperTypeNames(focusType) == null) return;
+		}
+	} catch (AbortCompilation e) {
+		bindingsWereCreated = false;
+	}
+
+	if (!mustResolve) {
+		return;
+	}
+
+	// possible match resolution
+	for (int i = 0; i < this.numberOfMatches; i++) {
+		if (this.progressMonitor != null && this.progressMonitor.isCanceled())
+			throw new OperationCanceledException();
+		PossibleMatch possibleMatch = this.matchesToProcess[i];
+		this.matchesToProcess[i] = null; // release reference to processed possible match
+		try {
+			process(possibleMatch, bindingsWereCreated);
+		} catch (AbortCompilation e) {
+			// problem with class path: it could not find base classes
+			// continue and try next matching openable reporting inaccurate matches (since bindings will be null)
+			bindingsWereCreated = false;
+		} catch (JavaModelException e) {
+			// problem with class path: it could not find base classes
+			// continue and try next matching openable reporting inaccurate matches (since bindings will be null)
+			bindingsWereCreated = false;
+		} finally {
+			if (this.progressMonitor != null) {
+				this.progressWorked++;
+				if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+			}
+			if (this.options.verbose)
+				System.out.println(
+					Messages.bind(Messages.compilation_done,
+						new String[] {
+							String.valueOf(i + 1),
+							String.valueOf(this.numberOfMatches),
+							new String(possibleMatch.parsedUnit.getFileName())
+						}));
+			// cleanup compilation unit result
+			possibleMatch.cleanUp();
+		}
+	}
+}
+/**
+ * Locate the matches amongst the possible matches.
+ */
+protected void locateMatches(JavaProject javaProject, PossibleMatchSet matchSet, int expected) throws CoreException {
+	PossibleMatch[] possibleMatches = matchSet.getPossibleMatches(javaProject.getPackageFragmentRoots());
+	int length = possibleMatches.length;
+	// increase progress from duplicate matches not stored in matchSet while adding...
+	if (this.progressMonitor != null && expected>length) {
+		this.progressWorked += expected-length;
+		this.progressMonitor.worked( expected-length);
+	}
+	// locate matches (processed matches are limited to avoid problem while using VM default memory heap size)
+	for (int index = 0; index < length;) {
+		int max = Math.min(MAX_AT_ONCE, length - index);
+		locateMatches(javaProject, possibleMatches, index, max);
+		index += max;
+	}
+	this.patternLocator.clear();
+}
+/**
+ * Locate the matches in the given files and report them using the search requestor.
+ */
+public void locateMatches(SearchDocument[] searchDocuments) throws CoreException {
+	if (this.patternLocator == null) return;
+	int docsLength = searchDocuments.length;
+	int progressLength = docsLength;
+	if (BasicSearchEngine.VERBOSE) {
+		System.out.println("Locating matches in documents ["); //$NON-NLS-1$
+		for (int i = 0; i < docsLength; i++)
+			System.out.println("\t" + searchDocuments[i]); //$NON-NLS-1$
+		System.out.println("]"); //$NON-NLS-1$
+	}
+	IJavaProject[] javaModelProjects = null;
+	if (this.searchPackageDeclaration) {
+		javaModelProjects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+		progressLength += javaModelProjects.length;
+	}
+
+	// init infos for progress increasing
+	int n = progressLength<1000 ? Math.min(Math.max(progressLength/200+1, 2),4) : 5 *(progressLength/1000);
+	this.progressStep = progressLength < n ? 1 : progressLength / n; // step should not be 0
+	this.progressWorked = 0;
+
+	// extract working copies
+	ArrayList copies = new ArrayList();
+	for (int i = 0; i < docsLength; i++) {
+		SearchDocument document = searchDocuments[i];
+		if (document instanceof WorkingCopyDocument) {
+			copies.add(((WorkingCopyDocument)document).workingCopy);
+		}
+	}
+	int copiesLength = copies.size();
+	this.workingCopies = new org.eclipse.jdt.core.ICompilationUnit[copiesLength];
+	copies.toArray(this.workingCopies);
+
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	this.bindings = new SimpleLookupTable();
+	try {
+		// optimize access to zip files during search operation
+		manager.cacheZipFiles(this);
+
+		// initialize handle factory (used as a cache of handles so as to optimize space)
+		if (this.handleFactory == null)
+			this.handleFactory = new HandleFactory();
+
+		if (this.progressMonitor != null) {
+			this.progressMonitor.beginTask("", searchDocuments.length); //$NON-NLS-1$
+		}
+
+		// initialize pattern for polymorphic search (i.e. method reference pattern)
+		this.patternLocator.initializePolymorphicSearch(this);
+
+		JavaProject previousJavaProject = null;
+		PossibleMatchSet matchSet = new PossibleMatchSet();
+		Util.sort(searchDocuments, new Util.Comparer() {
+			public int compare(Object a, Object b) {
+				return ((SearchDocument)a).getPath().compareTo(((SearchDocument)b).getPath());
+			}
+		});
+		int displayed = 0; // progress worked displayed
+		String previousPath = null;
+		SearchParticipant searchParticipant = null;
+		for (int i = 0; i < docsLength; i++) {
+			if (this.progressMonitor != null && this.progressMonitor.isCanceled()) {
+				throw new OperationCanceledException();
+			}
+
+			// skip duplicate paths
+			SearchDocument searchDocument = searchDocuments[i];
+			if (searchParticipant == null) {
+				searchParticipant = searchDocument.getParticipant();
+			}
+			searchDocuments[i] = null; // free current document
+			String pathString = searchDocument.getPath();
+			if (i > 0 && pathString.equals(previousPath)) {
+				if (this.progressMonitor != null) {
+					this.progressWorked++;
+					if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+				}
+				displayed++;
+				continue;
+			}
+			previousPath = pathString;
+
+			Openable openable;
+			org.eclipse.jdt.core.ICompilationUnit workingCopy = null;
+			if (searchDocument instanceof WorkingCopyDocument) {
+				workingCopy = ((WorkingCopyDocument)searchDocument).workingCopy;
+				openable = (Openable) workingCopy;
+			} else {
+				openable = this.handleFactory.createOpenable(pathString, this.scope);
+			}
+			if (openable == null) {
+				if (this.progressMonitor != null) {
+					this.progressWorked++;
+					if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+				}
+				displayed++;
+				continue; // match is outside classpath
+			}
+
+			// create new parser and lookup environment if this is a new project
+			IResource resource = null;
+			JavaProject javaProject = (JavaProject) openable.getJavaProject();
+			resource = workingCopy != null ? workingCopy.getResource() : openable.getResource();
+			if (resource == null)
+				resource = javaProject.getProject(); // case of a file in an external jar or external folder
+			if (!javaProject.equals(previousJavaProject)) {
+				// locate matches in previous project
+				if (previousJavaProject != null) {
+					try {
+						locateMatches(previousJavaProject, matchSet, i-displayed);
+						displayed = i;
+					} catch (JavaModelException e) {
+						// problem with classpath in this project -> skip it
+					}
+					matchSet.reset();
+				}
+				previousJavaProject = javaProject;
+			}
+			matchSet.add(new PossibleMatch(this, resource, openable, searchDocument,this.pattern.mustResolve));
+		}
+
+		// last project
+		if (previousJavaProject != null) {
+			try {
+				locateMatches(previousJavaProject, matchSet, docsLength-displayed);
+			} catch (JavaModelException e) {
+				// problem with classpath in last project -> ignore
+			}
+		}
+
+		if (this.searchPackageDeclaration) {
+			locatePackageDeclarations(searchParticipant, javaModelProjects);
+		}
+
+	} finally {
+		if (this.progressMonitor != null)
+			this.progressMonitor.done();
+		if (this.nameEnvironment != null)
+			this.nameEnvironment.cleanup();
+		manager.flushZipFiles(this);
+		this.bindings = null;
+	}
+}
+/**
+ * Locates the package declarations corresponding to this locator's pattern.
+ */
+protected void locatePackageDeclarations(SearchParticipant participant, IJavaProject[] projects) throws CoreException {
+	locatePackageDeclarations(this.pattern, participant, projects);
+}
+/**
+ * Locates the package declarations corresponding to the search pattern.
+ */
+protected void locatePackageDeclarations(SearchPattern searchPattern, SearchParticipant participant, IJavaProject[] projects) throws CoreException {
+	if (this.progressMonitor != null && this.progressMonitor.isCanceled()) {
+		throw new OperationCanceledException();
+	}
+	if (searchPattern instanceof OrPattern) {
+		SearchPattern[] patterns = ((OrPattern) searchPattern).patterns;
+		for (int i = 0, length = patterns.length; i < length; i++) {
+			locatePackageDeclarations(patterns[i], participant, projects);
+		}
+	} else if (searchPattern instanceof PackageDeclarationPattern) {
+		IJavaElement focus = searchPattern.focus;
+		if (focus != null) {
+			if (encloses(focus)) {
+				SearchMatch match = new PackageDeclarationMatch(focus.getAncestor(IJavaElement.PACKAGE_FRAGMENT), SearchMatch.A_ACCURATE, -1, -1, participant, focus.getResource());
+				report(match);
+			}
+			return;
+		}
+		PackageDeclarationPattern pkgPattern = (PackageDeclarationPattern) searchPattern;
+		boolean isWorkspaceScope = this.scope == JavaModelManager.getJavaModelManager().getWorkspaceScope();
+		IPath[] scopeProjectsAndJars =  isWorkspaceScope ? null : this.scope.enclosingProjectsAndJars();
+		int scopeLength = isWorkspaceScope ? 0 : scopeProjectsAndJars.length;
+		SimpleSet packages = new SimpleSet();
+		for (int i = 0, length = projects.length; i < length; i++) {
+			IJavaProject javaProject = projects[i];
+			if (this.progressMonitor != null) {
+				if (this.progressMonitor.isCanceled()) throw new OperationCanceledException();
+				this.progressWorked++;
+				if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+			}
+			// Verify that project belongs to the scope
+			if (!isWorkspaceScope) {
+				boolean found = false;
+				for (int j=0; j<scopeLength; j++) {
+					if (javaProject.getPath().equals(scopeProjectsAndJars[j])) {
+						found = true;
+						break;
+					}
+				}
+				if (!found) continue;
+			}
+			// Get all project package fragment names
+			this.nameLookup = ((JavaProject) projects[i]).newNameLookup(this.workingCopies);
+			IPackageFragment[] packageFragments = this.nameLookup.findPackageFragments(new String(pkgPattern.pkgName), false, true);
+			int pLength = packageFragments == null ? 0 : packageFragments.length;
+			// Report matches avoiding duplicate names
+			for (int p=0; p<pLength; p++) {
+				IPackageFragment fragment = packageFragments[p];
+				if (packages.addIfNotIncluded(fragment) == null) continue;
+				if (encloses(fragment)) {
+					IResource resource = fragment.getResource();
+					if (resource == null) // case of a file in an external jar
+						resource = javaProject.getProject();
+					try {
+						if (encloses(fragment)) {
+							SearchMatch match = new PackageDeclarationMatch(fragment, SearchMatch.A_ACCURATE, -1, -1, participant, resource);
+							report(match);
+						}
+					} catch (JavaModelException e) {
+						throw e;
+					} catch (CoreException e) {
+						throw new JavaModelException(e);
+					}
+				}
+			}
+		}
+	}
+}
+//*/
+protected IType lookupType(ReferenceBinding typeBinding) {
+	if (typeBinding == null || !typeBinding.isValidBinding()) return null;
+
+	char[] packageName = typeBinding.qualifiedPackageName();
+	IPackageFragment[] pkgs = this.nameLookup.findPackageFragments(
+		(packageName == null || packageName.length == 0)
+			? IPackageFragment.DEFAULT_PACKAGE_NAME
+			: new String(packageName),
+		false);
+
+	// iterate type lookup in each package fragment
+	char[] sourceName = typeBinding.qualifiedSourceName();
+	String typeName = new String(sourceName);
+	int acceptFlag = 0;
+	if (typeBinding.isAnnotationType()) {
+		acceptFlag = NameLookup.ACCEPT_ANNOTATIONS;
+	} else if (typeBinding.isEnum()) {
+		acceptFlag = NameLookup.ACCEPT_ENUMS;
+	} else if (typeBinding.isInterface()) {
+		acceptFlag = NameLookup.ACCEPT_INTERFACES;
+	} else if (typeBinding.isClass()) {
+		acceptFlag = NameLookup.ACCEPT_CLASSES;
+	}
+	if (pkgs != null) {
+		for (int i = 0, length = pkgs.length; i < length; i++) {
+			IType type = this.nameLookup.findType(typeName, pkgs[i],  false,  acceptFlag, true/*consider secondary types*/);
+			if (type != null) return type;
+		}
+	}
+
+	// search inside enclosing element
+	char[][] qualifiedName = CharOperation.splitOn('.', sourceName);
+	int length = qualifiedName.length;
+	if (length == 0) return null;
+
+	IType type = createTypeHandle(new String(qualifiedName[0])); // find the top-level type
+	if (type == null) return null;
+
+	for (int i = 1; i < length; i++) {
+		type = type.getType(new String(qualifiedName[i]));
+		if (type == null) return null;
+	}
+	if (type.exists()) return type;
+	return null;
+}
+public SearchMatch newDeclarationMatch(
+		IJavaElement element,
+		Binding binding,
+		int accuracy,
+		int offset,
+		int length) {
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	return newDeclarationMatch(element, binding, accuracy, offset, length, participant, resource);
+}
+
+public SearchMatch newDeclarationMatch(
+		IJavaElement element,
+		Binding binding,
+		int accuracy,
+		int offset,
+		int length,
+		SearchParticipant participant,
+		IResource resource) {
+	switch (element.getElementType()) {
+		case IJavaElement.PACKAGE_FRAGMENT:
+			return new PackageDeclarationMatch(element, accuracy, offset, length, participant, resource);
+		case IJavaElement.TYPE:
+			return new TypeDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
+		case IJavaElement.FIELD:
+			return new FieldDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
+		case IJavaElement.METHOD:
+			return new MethodDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
+		case IJavaElement.LOCAL_VARIABLE:
+			return new LocalVariableDeclarationMatch(element, accuracy, offset, length, participant, resource);
+		case IJavaElement.PACKAGE_DECLARATION:
+			return new PackageDeclarationMatch(element, accuracy, offset, length, participant, resource);
+		case IJavaElement.TYPE_PARAMETER:
+			return new TypeParameterDeclarationMatch(element, accuracy, offset, length, participant, resource);
+		default:
+			return null;
+	}
+}
+
+public FieldReferenceMatch newFieldReferenceMatch(
+		IJavaElement enclosingElement,
+		IJavaElement localElement,
+		Binding enclosingBinding,
+		int accuracy,
+		int offset,
+		int length, ASTNode reference) {
+	int bits = reference.bits;
+	boolean isCompoundAssigned = (bits & ASTNode.IsCompoundAssigned) != 0;
+	boolean isReadAccess = isCompoundAssigned || (bits & ASTNode.IsStrictlyAssigned) == 0;
+	boolean isWriteAccess = isCompoundAssigned || (bits & ASTNode.IsStrictlyAssigned) != 0;
+	if (isWriteAccess) {
+		if (reference instanceof QualifiedNameReference) {
+			char[][] tokens = ((QualifiedNameReference)reference).tokens;
+			char[] lastToken = tokens[tokens.length-1];
+			if (this.pattern instanceof OrPattern) {
+				SearchPattern[] patterns = ((OrPattern) this.pattern).patterns;
+				for (int i = 0, pLength = patterns.length; i < pLength; i++) {
+					if (!this.patternLocator.matchesName(((VariablePattern)patterns[i]).name, lastToken)) {
+			        	isWriteAccess = false;
+			        	isReadAccess = true;
+					}
+				}
+			} else if (!this.patternLocator.matchesName(((VariablePattern)this.pattern).name, lastToken)) {
+	        	isWriteAccess = false;
+	        	isReadAccess = true;
+			}
+        }
+	}
+	boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0;
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	if (enclosingBinding != null) {
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
+	}
+	FieldReferenceMatch match = new FieldReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource);
+	match.setLocalElement(localElement);
+	return match;
+}
+
+public SearchMatch newLocalVariableReferenceMatch(
+		IJavaElement enclosingElement,
+		int accuracy,
+		int offset,
+		int length,
+		ASTNode reference) {
+	int bits = reference.bits;
+	boolean isCompoundAssigned = (bits & ASTNode.IsCompoundAssigned) != 0;
+	boolean isReadAccess = isCompoundAssigned || (bits & ASTNode.IsStrictlyAssigned) == 0;
+	boolean isWriteAccess = isCompoundAssigned || (bits & ASTNode.IsStrictlyAssigned) != 0;
+	if (isWriteAccess) {
+		if (reference instanceof QualifiedNameReference) {
+			char[][] tokens = ((QualifiedNameReference)reference).tokens;
+			char[] lastToken = tokens[tokens.length-1];
+			if (this.pattern instanceof OrPattern) {
+				SearchPattern[] patterns = ((OrPattern) this.pattern).patterns;
+				for (int i = 0, pLength = patterns.length; i < pLength; i++) {
+					if (!this.patternLocator.matchesName(((VariablePattern)patterns[i]).name, lastToken)) {
+			        	isWriteAccess = false;
+			        	isReadAccess = true;
+					}
+				}
+			} else if (!this.patternLocator.matchesName(((VariablePattern)this.pattern).name, lastToken)) {
+	        	isWriteAccess = false;
+	        	isReadAccess = true;
+			}
+        }
+	}
+	boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0;
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	return new LocalVariableReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource);
+}
+
+public MethodReferenceMatch newMethodReferenceMatch(
+		IJavaElement enclosingElement,
+		Binding enclosingBinding,
+		int accuracy,
+		int offset,
+		int length,
+		boolean isConstructor,
+		boolean isSynthetic,
+		ASTNode reference) {
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
+	if (enclosingBinding != null)
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
+	boolean isOverridden = (accuracy & PatternLocator.SUPER_INVOCATION_FLAVOR) != 0;
+	return new MethodReferenceMatch(enclosingElement, accuracy, offset, length, isConstructor, isSynthetic, isOverridden, insideDocComment, participant, resource);
+}
+
+public PackageReferenceMatch newPackageReferenceMatch(
+		IJavaElement enclosingElement,
+		int accuracy,
+		int offset,
+		int length,
+		ASTNode reference) {
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
+	return new PackageReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
+public SearchMatch newTypeParameterReferenceMatch(
+		IJavaElement enclosingElement,
+		int accuracy,
+		int offset,
+		int length,
+		ASTNode reference) {
+	int bits = reference.bits;
+	boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0;
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	return new TypeParameterReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
+public TypeReferenceMatch newTypeReferenceMatch(
+		IJavaElement enclosingElement,
+		Binding enclosingBinding,
+		int accuracy,
+		int offset,
+		int length,
+		ASTNode reference) {
+	SearchParticipant participant = getParticipant();
+	IResource resource = this.currentPossibleMatch.resource;
+	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
+	if (enclosingBinding != null)
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
+	return new TypeReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
+public TypeReferenceMatch newTypeReferenceMatch(
+		IJavaElement enclosingElement,
+		Binding enclosingBinding,
+		int accuracy,
+		ASTNode reference) {
+	return newTypeReferenceMatch(enclosingElement, enclosingBinding, accuracy, reference.sourceStart, reference.sourceEnd-reference.sourceStart+1, reference);
+}
+
+/**
+ * Add the possibleMatch to the loop
+ *  ->  build compilation unit declarations, their bindings and record their results.
+ */
+protected boolean parseAndBuildBindings(PossibleMatch possibleMatch, boolean mustResolve) throws CoreException {
+	if (this.progressMonitor != null && this.progressMonitor.isCanceled())
+		throw new OperationCanceledException();
+
+	try {
+		if (BasicSearchEngine.VERBOSE)
+			System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+
+		this.parser.nodeSet = possibleMatch.nodeSet;
+		CompilationResult unitResult = new CompilationResult(possibleMatch, 1, 1, this.options.maxProblemsPerUnit);
+		CompilationUnitDeclaration parsedUnit = this.parser.dietParse(possibleMatch, unitResult);
+		if (parsedUnit != null) {
+			if (!parsedUnit.isEmpty()) {
+				if (mustResolve) {
+					this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+				}
+				if (hasAlreadyDefinedType(parsedUnit)) return false; // skip type has it is hidden so not visible
+				getMethodBodies(parsedUnit, possibleMatch.nodeSet);
+				if (this.patternLocator.mayBeGeneric && !mustResolve && possibleMatch.nodeSet.mustResolve) {
+					// special case: possible match node set force resolution although pattern does not
+					// => we need to build types for this compilation unit
+					this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+				}
+			}
+
+			// add the possibleMatch with its parsedUnit to matchesToProcess
+			possibleMatch.parsedUnit = parsedUnit;
+			int size = this.matchesToProcess.length;
+			if (this.numberOfMatches == size)
+				System.arraycopy(this.matchesToProcess, 0, this.matchesToProcess = new PossibleMatch[size == 0 ? 1 : size * 2], 0, this.numberOfMatches);
+			this.matchesToProcess[this.numberOfMatches++] = possibleMatch;
+		}
+	} finally {
+		this.parser.nodeSet = null;
+	}
+	return true;
+}
+/*
+ * Process a compilation unit already parsed and build.
+ */
+protected void process(PossibleMatch possibleMatch, boolean bindingsWereCreated) throws CoreException {
+	this.currentPossibleMatch = possibleMatch;
+	CompilationUnitDeclaration unit = possibleMatch.parsedUnit;
+	try {
+		if (unit.isEmpty()) {
+			if (this.currentPossibleMatch.openable instanceof ClassFile) {
+				ClassFile classFile = (ClassFile) this.currentPossibleMatch.openable;
+				IBinaryType info = null;
+				try {
+					info = getBinaryInfo(classFile, classFile.resource());
+				}
+				catch (CoreException ce) {
+					// Do nothing
+				}
+				if (info != null) {
+					boolean mayBeGeneric = this.patternLocator.mayBeGeneric;
+					this.patternLocator.mayBeGeneric = false; // there's no longer generic in class files
+					try {
+						new ClassFileMatchLocator().locateMatches(this, classFile, info);
+					}
+					finally {
+						this.patternLocator.mayBeGeneric = mayBeGeneric;
+					}
+				}
+			}
+			return;
+		}
+		if (hasAlreadyDefinedType(unit)) return; // skip type has it is hidden so not visible
+
+		// Move getMethodBodies to #parseAndBuildings(...) method to allow possible match resolution management
+		//getMethodBodies(unit);
+
+		boolean mustResolve = (this.pattern.mustResolve || possibleMatch.nodeSet.mustResolve);
+		if (bindingsWereCreated && mustResolve) {
+			if (unit.types != null) {
+				if (BasicSearchEngine.VERBOSE)
+					System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+
+				this.lookupEnvironment.unitBeingCompleted = unit;
+				reduceParseTree(unit);
+
+				if (unit.scope != null) {
+					// fault in fields & methods
+					unit.scope.faultInTypes();
+				}
+				unit.resolve();
+			} else if (unit.isPackageInfo()) {
+				if (BasicSearchEngine.VERBOSE)
+					System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+				unit.resolve();
+			}
+		}
+		reportMatching(unit, mustResolve);
+	} catch (AbortCompilation e) {
+		if (BasicSearchEngine.VERBOSE) {
+			System.out.println("AbortCompilation while resolving unit " + String.valueOf(unit.getFileName())); //$NON-NLS-1$
+			e.printStackTrace();
+		}
+		// could not resolve: report inaccurate matches
+		reportMatching(unit, false); // do not resolve when cu has errors
+		if (!(e instanceof AbortCompilationUnit)) {
+			// problem with class path
+			throw e;
+		}
+	} finally {
+		this.lookupEnvironment.unitBeingCompleted = null;
+		this.currentPossibleMatch = null;
+	}
+}
+protected void purgeMethodStatements(TypeDeclaration type, boolean checkEachMethod) {
+	checkEachMethod = checkEachMethod
+		&& this.currentPossibleMatch.nodeSet.hasPossibleNodes(type.declarationSourceStart, type.declarationSourceEnd);
+	AbstractMethodDeclaration[] methods = type.methods;
+	if (methods != null) {
+		if (checkEachMethod) {
+			for (int j = 0, length = methods.length; j < length; j++) {
+				AbstractMethodDeclaration method = methods[j];
+				if (!this.currentPossibleMatch.nodeSet.hasPossibleNodes(method.declarationSourceStart, method.declarationSourceEnd)) {
+					if (this.sourceStartOfMethodToRetain != method.declarationSourceStart || this.sourceEndOfMethodToRetain != method.declarationSourceEnd) { // approximate, but no big deal
+						method.statements = null;
+						method.javadoc = null;
+					}
+				}
+			}
+		} else {
+			for (int j = 0, length = methods.length; j < length; j++) {
+				AbstractMethodDeclaration method = methods[j];
+				if (this.sourceStartOfMethodToRetain != method.declarationSourceStart || this.sourceEndOfMethodToRetain != method.declarationSourceEnd) { // approximate, but no big deal
+					method.statements = null;
+					method.javadoc = null;
+				}
+			}
+		}
+	}
+
+	TypeDeclaration[] memberTypes = type.memberTypes;
+	if (memberTypes != null)
+		for (int i = 0, l = memberTypes.length; i < l; i++)
+			purgeMethodStatements(memberTypes[i], checkEachMethod);
+}
+/**
+ * Called prior to the unit being resolved. Reduce the parse tree where possible.
+ */
+protected void reduceParseTree(CompilationUnitDeclaration unit) {
+	// remove statements from methods that have no possible matching nodes
+	TypeDeclaration[] types = unit.types;
+	for (int i = 0, l = types.length; i < l; i++)
+		purgeMethodStatements(types[i], true);
+}
+public SearchParticipant getParticipant() {
+	return this.currentPossibleMatch.document.getParticipant();
+}
+
+protected void report(SearchMatch match) throws CoreException {
+	if (match == null) {
+		if (BasicSearchEngine.VERBOSE) {
+			System.out.println("Cannot report a null match!!!"); //$NON-NLS-1$
+		}
+		return;
+	}
+	if (filterEnum(match)){
+		if (BasicSearchEngine.VERBOSE) {
+			System.out.println("Filtered package with name enum"); //$NON-NLS-1$
+		}
+		return;
+	}
+	long start = -1;
+	if (BasicSearchEngine.VERBOSE) {
+		start = System.currentTimeMillis();
+		System.out.println("Reporting match"); //$NON-NLS-1$
+		System.out.println("\tResource: " + match.getResource());//$NON-NLS-1$
+		System.out.println("\tPositions: [offset=" + match.getOffset() + ", length=" + match.getLength() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		try {
+			if (this.parser != null && match.getOffset() > 0 && match.getLength() > 0 && !(match.getElement() instanceof BinaryMember)) {
+				String selection = new String(this.parser.scanner.source, match.getOffset(), match.getLength());
+				System.out.println("\tSelection: -->" + selection + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		} catch (Exception e) {
+			// it's just for debug purposes... ignore all exceptions in this area
+		}
+		try {
+			JavaElement javaElement = (JavaElement)match.getElement();
+			System.out.println("\tJava element: "+ javaElement.toStringWithAncestors()); //$NON-NLS-1$
+			if (!javaElement.exists()) {
+				System.out.println("\t\tWARNING: this element does NOT exist!"); //$NON-NLS-1$
+			}
+		} catch (Exception e) {
+			// it's just for debug purposes... ignore all exceptions in this area
+		}
+		if (match instanceof ReferenceMatch) {
+			try {
+				ReferenceMatch refMatch = (ReferenceMatch) match;
+				JavaElement local = (JavaElement) refMatch.getLocalElement();
+				if (local != null) {
+					System.out.println("\tLocal element: "+ local.toStringWithAncestors()); //$NON-NLS-1$
+				}
+				if (match instanceof TypeReferenceMatch) {
+					IJavaElement[] others = ((TypeReferenceMatch) refMatch).getOtherElements();
+					if (others != null) {
+						int length = others.length;
+						if (length > 0) {
+							System.out.println("\tOther elements:"); //$NON-NLS-1$
+							for (int i=0; i<length; i++) {
+								JavaElement other = (JavaElement) others[i];
+								System.out.println("\t\t- "+ other.toStringWithAncestors()); //$NON-NLS-1$
+							}
+						}
+					}
+				}
+			} catch (Exception e) {
+				// it's just for debug purposes... ignore all exceptions in this area
+			}
+		}
+		System.out.println(match.getAccuracy() == SearchMatch.A_ACCURATE
+			? "\tAccuracy: EXACT_MATCH" //$NON-NLS-1$
+			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
+		System.out.print("\tRule: "); //$NON-NLS-1$
+		if (match.isExact()) {
+			System.out.print("EXACT"); //$NON-NLS-1$
+		} else if (match.isEquivalent()) {
+			System.out.print("EQUIVALENT"); //$NON-NLS-1$
+		} else if (match.isErasure()) {
+			System.out.print("ERASURE"); //$NON-NLS-1$
+		} else {
+			System.out.print("INVALID RULE"); //$NON-NLS-1$
+		}
+		if (match instanceof MethodReferenceMatch) {
+			MethodReferenceMatch methodReferenceMatch = (MethodReferenceMatch) match;
+			if (methodReferenceMatch.isSuperInvocation()) {
+				System.out.print("+SUPER INVOCATION"); //$NON-NLS-1$
+			}
+			if (methodReferenceMatch.isImplicit()) {
+				System.out.print("+IMPLICIT"); //$NON-NLS-1$
+			}
+			if (methodReferenceMatch.isSynthetic()) {
+				System.out.print("+SYNTHETIC"); //$NON-NLS-1$
+			}
+		}
+		System.out.println("\n\tRaw: "+match.isRaw()); //$NON-NLS-1$
+	}
+	this.requestor.acceptSearchMatch(match);
+	if (BasicSearchEngine.VERBOSE)
+		this.resultCollectorTime += System.currentTimeMillis()-start;
+}
+/**
+ * Finds the accurate positions of the sequence of tokens given by qualifiedName
+ * in the source and reports a reference to this this qualified name
+ * to the search requestor.
+ */
+protected void reportAccurateTypeReference(SearchMatch match, ASTNode typeRef, char[] name) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
+
+	int sourceStart = typeRef.sourceStart;
+	int sourceEnd = typeRef.sourceEnd;
+
+	// Compute source positions of the qualified reference
+	if (name != null) {
+		Scanner scanner = this.parser.scanner;
+		scanner.setSource(this.currentPossibleMatch.getContents());
+		scanner.resetTo(sourceStart, sourceEnd);
+
+		int token = -1;
+		int currentPosition;
+		do {
+			currentPosition = scanner.currentPosition;
+			try {
+				token = scanner.getNextToken();
+			} catch (InvalidInputException e) {
+				// ignore
+			}
+			if (token == TerminalTokens.TokenNameIdentifier && this.pattern.matchesName(name, scanner.getCurrentTokenSource())) {
+				int length = scanner.currentPosition-currentPosition;
+				match.setOffset(currentPosition);
+				match.setLength(length);
+				report(match);
+				return;
+			}
+		} while (token != TerminalTokens.TokenNameEOF);
+	}
+
+	//	Report match
+	match.setOffset(sourceStart);
+	match.setLength(sourceEnd-sourceStart+1);
+	report(match);
+}
+
+/**
+ * Finds the accurate positions of the sequence of tokens given by qualifiedName
+ * in the source and reports a reference to this parameterized type name
+ * to the search requestor.
+ * @since 3.1
+ */
+protected void reportAccurateParameterizedMethodReference(SearchMatch match, ASTNode statement, TypeReference[] typeArguments) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
+
+	// If there's type arguments, look for end (i.e. char '>') of last one.
+	int start = match.getOffset();
+	if (typeArguments != null && typeArguments.length > 0) {
+		boolean isErasureMatch= (this.pattern instanceof OrPattern) ? ((OrPattern)this.pattern).isErasureMatch() : ((JavaSearchPattern)this.pattern).isErasureMatch();
+		if (!isErasureMatch) {
+
+			// Initialize scanner
+			Scanner scanner = this.parser.scanner;
+			char[] source = this.currentPossibleMatch.getContents();
+			scanner.setSource(source);
+
+			// Search previous opening '<'
+			start = typeArguments[0].sourceStart;
+			int end = statement.sourceEnd;
+			scanner.resetTo(start, end);
+			int lineStart = start;
+			try {
+				linesUp: while (true) {
+					while (scanner.source[scanner.currentPosition] != '\n') {
+						scanner.currentPosition--;
+						if (scanner.currentPosition == 0) break linesUp;
+					}
+					lineStart = scanner.currentPosition+1;
+					scanner.resetTo(lineStart, end);
+					while (!scanner.atEnd()) {
+						if (scanner.getNextToken() == TerminalTokens.TokenNameLESS) {
+							start = scanner.getCurrentTokenStartPosition();
+							break linesUp;
+						}
+					}
+					end = lineStart - 2;
+					scanner.currentPosition = end;
+				}
+			}
+			catch (InvalidInputException ex) {
+				// give up
+			}
+	 	}
+	}
+
+	// Report match
+	match.setOffset(start);
+	match.setLength(statement.sourceEnd-start+1);
+	report(match);
+}
+
+/**
+ * Finds the accurate positions of the sequence of tokens given by qualifiedName
+ * in the source and reports a reference to this parameterized type name
+ * to the search requestor.
+ * @since 3.1
+ */
+protected void reportAccurateParameterizedTypeReference(SearchMatch match, TypeReference typeRef, int index, TypeReference[] typeArguments) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
+
+	// If there's type arguments, look for end (i.e. char '>') of last one.
+	int end = typeRef.sourceEnd;
+	if (typeArguments != null) {
+
+		boolean shouldMatchErasure= (this.pattern instanceof OrPattern) ? ((OrPattern)this.pattern).isErasureMatch() : ((JavaSearchPattern)this.pattern).isErasureMatch();
+		boolean hasSignatures = (this.pattern instanceof OrPattern) ? ((OrPattern)this.pattern).hasSignatures() : ((JavaSearchPattern)this.pattern).hasSignatures();
+		if (shouldMatchErasure || !hasSignatures) {
+			// if pattern is erasure only, then select the end of the reference
+			if (typeRef instanceof QualifiedTypeReference && index >= 0) {
+				long[] positions = ((QualifiedTypeReference) typeRef).sourcePositions;
+				end = (int) positions[index];
+			} else if (typeRef instanceof ArrayTypeReference) {
+				end = ((ArrayTypeReference) typeRef).originalSourceEnd;
+			}
+		}  else {
+			// Initialize scanner
+			Scanner scanner = this.parser.scanner;
+			char[] source = this.currentPossibleMatch.getContents();
+			scanner.setSource(source);
+
+			// Set scanner position at end of last type argument
+			scanner.resetTo(end, source.length-1);
+			int depth = 0;
+			for (int i=typeArguments.length-1; i>=0; i--) {
+				if (typeArguments[i] != null) {
+					long lastTypeArgInfo = findLastTypeArgumentInfo(typeArguments[i]);
+					depth = (int) (lastTypeArgInfo >>> 32)+1;
+					scanner.resetTo(((int)lastTypeArgInfo)+1, scanner.eofPosition-1);
+					break;
+				}
+			}
+
+			// Now, scan to search next closing '>'
+			while (depth-- > 0) {
+				while (!scanner.atEnd()) {
+					if (scanner.getNextChar() == '>') {
+						end = scanner.currentPosition - 1;
+						break;
+					}
+				}
+			}
+	 	}
+	}
+
+	// Report match
+	match.setLength(end-match.getOffset()+1);
+	report(match);
+}
+/**
+ * Finds the accurate positions of each valid token in the source and
+ * reports a reference to this token to the search requestor.
+ * A token is valid if it has an accuracy which is not -1.
+ */
+protected void reportAccurateEnumConstructorReference(SearchMatch match, FieldDeclaration field, AllocationExpression allocation) throws CoreException {
+	// Verify that field declaration is really an enum constant
+	if (allocation == null || allocation.enumConstant == null) {
+		report(match);
+		return;
+	}
+
+	// Get scan area
+	int sourceStart = match.getOffset()+match.getLength();
+	if (allocation.arguments != null && allocation.arguments.length > 0) {
+		sourceStart = allocation.arguments[allocation.arguments.length-1].sourceEnd+1;
+	}
+	int sourceEnd = field.declarationSourceEnd;
+	if (allocation instanceof QualifiedAllocationExpression) {
+		QualifiedAllocationExpression qualifiedAllocation = (QualifiedAllocationExpression) allocation;
+		if (qualifiedAllocation.anonymousType != null) {
+			sourceEnd = qualifiedAllocation.anonymousType.sourceStart - 1;
+		}
+	}
+
+	// Scan to find last closing parenthesis
+	Scanner scanner = this.parser.scanner;
+	scanner.setSource(this.currentPossibleMatch.getContents());
+	scanner.resetTo(sourceStart, sourceEnd);
+	try {
+		int token = scanner.getNextToken();
+		while (token != TerminalTokens.TokenNameEOF) {
+			if (token == TerminalTokens.TokenNameRPAREN) {
+				sourceEnd = scanner.getCurrentTokenEndPosition();
+			}
+			token = scanner.getNextToken();
+		}
+	}
+	catch (InvalidInputException iie) {
+		// give up
+	}
+
+	// Report match
+	match.setLength(sourceEnd-match.getOffset()+1);
+	report(match);
+}
+/**
+ * Finds the accurate positions of each valid token in the source and
+ * reports a reference to this token to the search requestor.
+ * A token is valid if it has an accuracy which is not -1.
+ */
+protected void reportAccurateFieldReference(SearchMatch[] matches, QualifiedNameReference qNameRef) throws CoreException {
+	if (matches == null) return; // there's nothing to accurate in this case
+	int matchesLength = matches.length;
+
+	int sourceStart = qNameRef.sourceStart;
+	int sourceEnd = qNameRef.sourceEnd;
+	char[][] tokens = qNameRef.tokens;
+
+	// compute source positions of the qualified reference
+	Scanner scanner = this.parser.scanner;
+	scanner.setSource(this.currentPossibleMatch.getContents());
+	scanner.resetTo(sourceStart, sourceEnd);
+	int sourceLength = sourceEnd-sourceStart+1;
+
+	int refSourceStart = -1, refSourceEnd = -1;
+	int length = tokens.length;
+	int token = -1;
+	int previousValid = -1;
+	int i = 0;
+	int index = 0;
+	do {
+		int currentPosition = scanner.currentPosition;
+		// read token
+		try {
+			token = scanner.getNextToken();
+		} catch (InvalidInputException e) {
+			//ignore
+		}
+		if (token != TerminalTokens.TokenNameEOF) {
+			char[] currentTokenSource = scanner.getCurrentTokenSource();
+			boolean equals = false;
+			while (i < length && !(equals = this.pattern.matchesName(tokens[i++], currentTokenSource))){/*empty*/}
+			if (equals && (previousValid == -1 || previousValid == i - 2)) {
+				previousValid = i - 1;
+				if (refSourceStart == -1)
+					refSourceStart = currentPosition;
+				refSourceEnd = scanner.currentPosition - 1;
+			} else {
+				i = 0;
+				refSourceStart = -1;
+				previousValid = -1;
+			}
+			// read '.'
+			try {
+				token = scanner.getNextToken();
+			} catch (InvalidInputException e) {
+				// ignore
+			}
+		}
+		SearchMatch match = matches[index];
+		if (match != null && match.getRule() != 0) {
+			if (!encloses((IJavaElement)match.getElement())) return;
+			// accept reference
+			if (refSourceStart != -1) {
+				match.setOffset(refSourceStart);
+				match.setLength(refSourceEnd-refSourceStart+1);
+				report(match);
+			} else {
+				match.setOffset(sourceStart);
+				match.setLength(sourceLength);
+				report(match);
+			}
+			i = 0;
+		}
+		refSourceStart = -1;
+		previousValid = -1;
+		if (index < matchesLength - 1) {
+			index++;
+		}
+	} while (token != TerminalTokens.TokenNameEOF);
+
+}
+protected void reportBinaryMemberDeclaration(IResource resource, IMember binaryMember, Binding binaryMemberBinding, IBinaryType info, int accuracy) throws CoreException {
+	ClassFile classFile = (ClassFile) binaryMember.getClassFile();
+	ISourceRange range = classFile.isOpen() ? binaryMember.getNameRange() : SourceMapper.UNKNOWN_RANGE;
+	if (range.getOffset() == -1) {
+		BinaryType type = (BinaryType) classFile.getType();
+		String sourceFileName = type.sourceFileName(info);
+		if (sourceFileName != null) {
+			SourceMapper mapper = classFile.getSourceMapper();
+			if (mapper != null) {
+				char[] contents = mapper.findSource(type, sourceFileName);
+				if (contents != null)
+					range = mapper.mapSource(type, contents, info, binaryMember);
+			}
+		}
+	}
+	if (resource == null) resource =  this.currentPossibleMatch.resource;
+	SearchMatch match = newDeclarationMatch(binaryMember, binaryMemberBinding, accuracy, range.getOffset(), range.getLength(), getParticipant(), resource);
+	report(match);
+}
+/**
+ * Visit the given method declaration and report the nodes that match exactly the
+ * search pattern (i.e. the ones in the matching nodes set)
+ * Note that the method declaration has already been checked.
+ */
+protected void reportMatching(AbstractMethodDeclaration method, TypeDeclaration type, IJavaElement parent, int accuracy, boolean typeInHierarchy, MatchingNodeSet nodeSet) throws CoreException {
+	IJavaElement enclosingElement = null;
+
+	// report method declaration itself
+	if (accuracy > -1) {
+		enclosingElement = createHandle(method, parent);
+		if (enclosingElement != null) { // skip if unable to find method
+			// compute source positions of the selector
+			Scanner scanner = this.parser.scanner;
+			int nameSourceStart = method.sourceStart;
+			scanner.setSource(this.currentPossibleMatch.getContents());
+			scanner.resetTo(nameSourceStart, method.sourceEnd);
+			try {
+				scanner.getNextToken();
+			} catch (InvalidInputException e) {
+				// ignore
+			}
+			if (encloses(enclosingElement)) {
+				SearchMatch match = null;
+				if (method.isDefaultConstructor()) {
+					// Use type for match associated element as default constructor does not exist in source
+					int offset = type.sourceStart;
+					match = this.patternLocator.newDeclarationMatch(type, parent, type.binding, accuracy, type.sourceEnd-offset+1, this);
+				} else {
+					int length = scanner.currentPosition - nameSourceStart;
+					match = this.patternLocator.newDeclarationMatch(method, enclosingElement, method.binding, accuracy, length, this);
+				}
+				if (match != null) {
+					report(match);
+				}
+			}
+		}
+	}
+
+	// handle nodes for the local type first
+	if ((method.bits & ASTNode.HasLocalType) != 0) {
+		if (enclosingElement == null) {
+			enclosingElement = createHandle(method, parent);
+		}
+		// Traverse method declaration to report matches both in local types declaration
+		// and in local variables declaration
+		ASTNode[] nodes = typeInHierarchy ? nodeSet.matchingNodes(method.declarationSourceStart, method.declarationSourceEnd) : null;
+		boolean report = (this.matchContainer & PatternLocator.METHOD_CONTAINER) != 0 && encloses(enclosingElement);
+		MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, report ? nodes : null, nodeSet, this);
+		try {
+			method.traverse(declarationVisitor, (ClassScope) null);
+		} catch (WrappedCoreException e) {
+			throw e.coreException;
+		}
+		// Report all nodes and remove them
+		if (nodes != null) {
+			int length = nodes.length;
+			for (int i = 0; i < length; i++) {
+				Integer level = (Integer) nodeSet.matchingNodes.removeKey(nodes[i]);
+				if (report && level != null) {
+	    	        this.patternLocator.matchReportReference(nodes[i], enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), method.binding, level.intValue(), this);
+				}
+			}
+		}
+	}
+
+	// report the type parameters
+	TypeParameter[] typeParameters = method.typeParameters();
+	if (typeParameters != null) {
+		if (enclosingElement == null) {
+			enclosingElement = createHandle(method, parent);
+		}
+		if (enclosingElement != null) {
+			reportMatching(typeParameters, enclosingElement, parent, method.binding, nodeSet);
+		}
+	}
+
+	// report annotations
+	if (method.annotations != null) {
+		if (enclosingElement == null) {
+			enclosingElement = createHandle(method, parent);
+		}
+		if (enclosingElement != null) {
+			reportMatching(method.annotations, enclosingElement, null, method.binding, nodeSet, true, true);
+		}
+	}
+
+	// references in this method
+	if (typeInHierarchy) {
+		ASTNode[] nodes = nodeSet.matchingNodes(method.declarationSourceStart, method.declarationSourceEnd);
+		if (nodes != null) {
+			if ((this.matchContainer & PatternLocator.METHOD_CONTAINER) != 0) {
+				if (enclosingElement == null) {
+					enclosingElement = createHandle(method, parent);
+				}
+				if (encloses(enclosingElement)) {
+					if (this.pattern.mustResolve) {
+						// Visit only if the pattern must resolve
+						MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, nodes, nodeSet, this);
+						method.traverse(declarationVisitor, (ClassScope) null);
+						int length = nodes.length;
+						for (int i = 0; i < length; i++) {
+							Integer level = (Integer) nodeSet.matchingNodes.removeKey(nodes[i]);
+							if (level != null) { // ensure that the reference has not been already reported while visiting
+				    	        this.patternLocator.matchReportReference(nodes[i], enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), method.binding, level.intValue(), this);
+							}
+						}
+					} else {
+						for (int i = 0, l = nodes.length; i < l; i++) {
+							ASTNode node = nodes[i];
+							Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+							if (level != null) { // ensure that the reference has not been already reported while visiting
+								this.patternLocator.matchReportReference(node, enclosingElement, null, null, method.binding, level.intValue(), this);
+							}
+						}
+					}
+					return;
+				}
+			}
+			// Remove all remaining nodes
+			for (int i = 0, l = nodes.length; i < l; i++) {
+				nodeSet.matchingNodes.removeKey(nodes[i]);
+			}
+		}
+	}
+}
+/**
+ * Report matching in annotations.
+ * @param otherElements TODO
+ */
+protected void reportMatching(Annotation[] annotations, IJavaElement enclosingElement, IJavaElement[] otherElements, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedContainer, boolean enclosesElement) throws CoreException {
+	for (int i=0, al=annotations.length; i<al; i++) {
+		Annotation annotationType = annotations[i];
+		IJavaElement localAnnotation = null;
+		IJavaElement[] otherAnnotations = null;
+		int length = otherElements == null ? 0 : otherElements.length;
+		boolean handlesCreated = false;
+
+		// Look for annotation type ref
+		TypeReference typeRef = annotationType.type;
+		Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
+		if (level != null && enclosesElement && matchedContainer) {
+			localAnnotation = createHandle(annotationType, (IAnnotatable) enclosingElement);
+			if (length > 0) {
+				otherAnnotations = new IJavaElement[length];
+				for (int o=0; o<length; o++) {
+					otherAnnotations[o] = createHandle(annotationType, (IAnnotatable) otherElements[o]);
+				}
+			}
+			handlesCreated = true;
+			this.patternLocator.matchReportReference(typeRef, enclosingElement, localAnnotation, otherAnnotations, elementBinding, level.intValue(), this);
+		}
+
+		// Look for attribute ref
+		MemberValuePair[] pairs = annotationType.memberValuePairs();
+		for (int j = 0, pl = pairs.length; j < pl; j++) {
+			MemberValuePair pair = pairs[j];
+			level = (Integer) nodeSet.matchingNodes.removeKey(pair);
+			if (level != null && enclosesElement) {
+				ASTNode reference = (annotationType instanceof SingleMemberAnnotation) ? (ASTNode) annotationType: pair;
+				if (!handlesCreated) {
+					localAnnotation = createHandle(annotationType, (IAnnotatable) enclosingElement);
+					if (length > 0) {
+						otherAnnotations = new IJavaElement[length];
+						for (int o=0; o<length; o++) {
+							otherAnnotations[o] = createHandle(annotationType, (IAnnotatable) otherElements[o]);
+						}
+					}
+					handlesCreated = true;
+				}
+				this.patternLocator.matchReportReference(reference, enclosingElement, localAnnotation, otherAnnotations, pair.binding, level.intValue(), this);
+			}
+		}
+
+		// Look for reference inside annotation
+		ASTNode[] nodes = nodeSet.matchingNodes(annotationType.sourceStart, annotationType.declarationSourceEnd);
+		if (nodes != null) {
+			if (!matchedContainer) {
+				for (int j = 0, nl = nodes.length; j < nl; j++) {
+					nodeSet.matchingNodes.removeKey(nodes[j]);
+				}
+			} else {
+				for (int j = 0, nl = nodes.length; j < nl; j++) {
+					ASTNode node = nodes[j];
+					level = (Integer) nodeSet.matchingNodes.removeKey(node);
+					if (enclosesElement) {
+						if (!handlesCreated) {
+							localAnnotation = createHandle(annotationType, (IAnnotatable) enclosingElement);
+							if (length > 0) {
+								otherAnnotations = new IJavaElement[length];
+								for (int o=0; o<length; o++) {
+									otherAnnotations[o] = createHandle(annotationType, (IAnnotatable) otherElements[o]);
+								}
+							}
+							handlesCreated = true;
+						}
+						this.patternLocator.matchReportReference(node, enclosingElement, localAnnotation, otherAnnotations, elementBinding, level.intValue(), this);
+					}
+				}
+			}
+		}
+	}
+}
+private void reportMatching(Annotation[][] annotationsList, IJavaElement enclosingElement, Binding binding,
+		MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
+	if (annotationsList != null) {
+		for (int i = 0, length = annotationsList.length; i < length; ++i) {
+			Annotation[] annotations = annotationsList[i];
+			if (annotations != null) 
+				reportMatching(annotations, enclosingElement, null, binding, nodeSet, matchedClassContainer, encloses(enclosingElement));	
+		}
+	}
+}
+/**
+ * Visit the given resolved parse tree and report the nodes that match the search pattern.
+ */
+protected void reportMatching(CompilationUnitDeclaration unit, boolean mustResolve) throws CoreException {
+	MatchingNodeSet nodeSet = this.currentPossibleMatch.nodeSet;
+	boolean locatorMustResolve = this.patternLocator.mustResolve;
+	if (nodeSet.mustResolve) this.patternLocator.mustResolve = true;
+	if (BasicSearchEngine.VERBOSE) {
+		System.out.println("Report matching: "); //$NON-NLS-1$
+		int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
+		System.out.print("	- node set: accurate="+ size); //$NON-NLS-1$
+		size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
+		System.out.println(", possible="+size); //$NON-NLS-1$
+		System.out.print("	- must resolve: "+mustResolve); //$NON-NLS-1$
+		System.out.print(" (locator: "+this.patternLocator.mustResolve); //$NON-NLS-1$
+		System.out.println(", nodeSet: "+nodeSet.mustResolve+')'); //$NON-NLS-1$
+		System.out.println("	- fine grain flags="+ JavaSearchPattern.getFineGrainFlagString(this.patternLocator.fineGrain())); //$NON-NLS-1$
+	}
+	if (mustResolve) {
+		this.unitScope= unit.scope.compilationUnitScope();
+		// move the possible matching nodes that exactly match the search pattern to the matching nodes set
+		Object[] nodes = nodeSet.possibleMatchingNodesSet.values;
+		for (int i = 0, l = nodes.length; i < l; i++) {
+			ASTNode node = (ASTNode) nodes[i];
+			if (node == null) continue;
+			if (node instanceof ImportReference) {
+				// special case for import refs: they don't know their binding
+				// import ref cannot be in the hierarchy of a type
+				if (this.hierarchyResolver != null) continue;
+
+				ImportReference importRef = (ImportReference) node;
+				Binding binding = (importRef.bits & ASTNode.OnDemand) != 0
+					? this.unitScope.getImport(CharOperation.subarray(importRef.tokens, 0, importRef.tokens.length), true, importRef.isStatic())
+					: this.unitScope.getImport(importRef.tokens, false, importRef.isStatic());
+				this.patternLocator.matchLevelAndReportImportRef(importRef, binding, this);
+			} else {
+				nodeSet.addMatch(node, this.patternLocator.resolveLevel(node));
+			}
+		}
+		nodeSet.possibleMatchingNodesSet = new SimpleSet(3);
+		if (BasicSearchEngine.VERBOSE) {
+			int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
+			System.out.print("	- node set: accurate="+size); //$NON-NLS-1$
+			size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
+			System.out.println(", possible="+size); //$NON-NLS-1$
+		}
+	} else {
+		this.unitScope = null;
+	}
+
+	if (nodeSet.matchingNodes.elementSize == 0) return; // no matching nodes were found
+	this.methodHandles = new HashSet();
+
+	boolean matchedUnitContainer = (this.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0;
+
+	// report references in javadoc
+	if (unit.javadoc != null) {
+		ASTNode[] nodes = nodeSet.matchingNodes(unit.javadoc.sourceStart, unit.javadoc.sourceEnd);
+		if (nodes != null) {
+			if (!matchedUnitContainer) {
+				for (int i = 0, l = nodes.length; i < l; i++)
+					nodeSet.matchingNodes.removeKey(nodes[i]);
+			} else {
+				IJavaElement element = createPackageDeclarationHandle(unit);
+				for (int i = 0, l = nodes.length; i < l; i++) {
+					ASTNode node = nodes[i];
+					Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+					if (encloses(element)) {
+						this.patternLocator.matchReportReference(node, element, null, null, null/*no binding*/, level.intValue(), this);
+					}
+				}
+			}
+		}
+	}
+
+	if (matchedUnitContainer) {
+		ImportReference pkg = unit.currentPackage;
+		if (pkg != null && pkg.annotations != null) {
+			IJavaElement element = createPackageDeclarationHandle(unit);
+			if (element != null) {
+				reportMatching(pkg.annotations, element, null, null, nodeSet, true, encloses(element));
+			}
+		}
+
+		ImportReference[] imports = unit.imports;
+		if (imports != null) {
+			for (int i = 0, l = imports.length; i < l; i++) {
+				ImportReference importRef = imports[i];
+				Integer level = (Integer) nodeSet.matchingNodes.removeKey(importRef);
+				if (level != null) {
+					this.patternLocator.matchReportImportRef(importRef, null /*no binding*/, createImportHandle(importRef), level.intValue(), this);
+				}
+			}
+		}
+	}
+
+	TypeDeclaration[] types = unit.types;
+	if (types != null) {
+		for (int i = 0, l = types.length; i < l; i++) {
+			if (nodeSet.matchingNodes.elementSize == 0) return; // reported all the matching nodes
+			TypeDeclaration type = types[i];
+			Integer level = (Integer) nodeSet.matchingNodes.removeKey(type);
+			int accuracy = (level != null && matchedUnitContainer) ? level.intValue() : -1;
+			reportMatching(type, null, accuracy, nodeSet, 1);
+		}
+	}
+
+	// Clear handle cache
+	this.methodHandles = null;
+	this.bindings.removeKey(this.pattern);
+	this.patternLocator.mustResolve = locatorMustResolve;
+}
+/**
+ * Visit the given field declaration and report the nodes that match exactly the
+ * search pattern (i.e. the ones in the matching nodes set)
+ */
+protected void reportMatching(FieldDeclaration field, FieldDeclaration[] otherFields, TypeDeclaration type, IJavaElement parent, int accuracy, boolean typeInHierarchy, MatchingNodeSet nodeSet) throws CoreException {
+	IJavaElement enclosingElement = null;
+	if (accuracy > -1) {
+		enclosingElement = createHandle(field, type, parent);
+		if (encloses(enclosingElement)) {
+			int offset = field.sourceStart;
+			SearchMatch match = newDeclarationMatch(enclosingElement, field.binding, accuracy, offset, field.sourceEnd-offset+1);
+			if (field.initialization instanceof AllocationExpression) {
+				reportAccurateEnumConstructorReference(match, field, (AllocationExpression) field.initialization);
+			} else {
+				report(match);
+			}
+		}
+	}
+
+	// handle the nodes for the local type first
+	if ((field.bits & ASTNode.HasLocalType) != 0) {
+		if (enclosingElement == null) {
+			enclosingElement = createHandle(field, type, parent);
+		}
+		// Traverse field declaration(s) to report matches both in local types declaration
+		// and in local variables declaration
+		int fieldEnd = field.endPart2Position == 0 ? field.declarationSourceEnd : field.endPart2Position;
+		ASTNode[] nodes = typeInHierarchy ? nodeSet.matchingNodes(field.sourceStart, fieldEnd) : null;
+		boolean report = (this.matchContainer & PatternLocator.FIELD_CONTAINER) != 0 && encloses(enclosingElement);
+		MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, report ? nodes : null, nodeSet, this);
+		try {
+			field.traverse(declarationVisitor, (MethodScope) null);
+		} catch (WrappedCoreException e) {
+			throw e.coreException;
+		}
+		// Report all nodes and remove them
+		if (nodes != null) {
+			int length = nodes.length;
+			for (int i = 0; i < length; i++) {
+				ASTNode node = nodes[i];
+				Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+				if (report && level != null) {
+					if (node instanceof TypeDeclaration) {
+						// use field declaration to report match (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=88174)
+						AllocationExpression allocation = ((TypeDeclaration)node).allocation;
+						if (allocation != null && allocation.enumConstant != null) {
+							node = field;
+						}
+					}
+	    	        this.patternLocator.matchReportReference(node, enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), field.binding, level.intValue(), this);
+				}
+			}
+		}
+	}
+
+	// report annotations
+	IJavaElement[] otherElements = null;
+	if (field.annotations != null) {
+		if (enclosingElement == null) {
+			enclosingElement = createHandle(field, type, parent);
+		}
+		if (otherFields != null) {
+			otherElements = createHandles(otherFields, type, parent);
+		}
+		reportMatching(field.annotations, enclosingElement, otherElements, field.binding, nodeSet, true, true);
+	}
+
+	if (typeInHierarchy) {
+		// Look at field declaration
+		if (field.endPart1Position != 0) { // not necessary if field is an initializer
+			ASTNode[] nodes = nodeSet.matchingNodes(field.declarationSourceStart, field.endPart1Position);
+			if (nodes != null) {
+				if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) {
+					for (int i = 0, l = nodes.length; i < l; i++)
+						nodeSet.matchingNodes.removeKey(nodes[i]);
+				} else {
+					if (enclosingElement == null)
+						enclosingElement = createHandle(field, type, parent);
+					if (encloses(enclosingElement)) {
+						for (int i = 0, l = nodes.length; i < l; i++) {
+							ASTNode node = nodes[i];
+							Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+							if (otherFields != null && otherElements == null) {
+								otherElements = createHandles(otherFields, type, parent);
+							}
+							this.patternLocator.matchReportReference(node, enclosingElement, null, otherElements, field.binding, level.intValue(), this);
+						}
+					}
+				}
+			}
+		}
+
+		// Look in initializer
+		int fieldEnd = field.endPart2Position == 0 ? field.declarationSourceEnd : field.endPart2Position;
+		ASTNode[] nodes = nodeSet.matchingNodes(field.sourceStart, fieldEnd);
+		if (nodes != null) {
+			if ((this.matchContainer & PatternLocator.FIELD_CONTAINER) == 0) {
+				for (int i = 0, l = nodes.length; i < l; i++) {
+					nodeSet.matchingNodes.removeKey(nodes[i]);
+				}
+			} else {
+				if (enclosingElement == null) {
+					enclosingElement = createHandle(field, type, parent);
+				}
+				if (encloses(enclosingElement)) {
+					MemberDeclarationVisitor declarationVisitor = new MemberDeclarationVisitor(enclosingElement, nodes, nodeSet, this);
+					field.traverse(declarationVisitor, (MethodScope) null);
+					int length = nodes.length;
+					for (int i = 0; i < length; i++) {
+						ASTNode node = nodes[i];
+						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+						if (level != null) { // ensure that the reference has not been already reported while visiting
+							if (node instanceof TypeDeclaration) {
+								// use field declaration to report match (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=88174)
+								AllocationExpression allocation = ((TypeDeclaration)node).allocation;
+								if (allocation != null && allocation.enumConstant != null) {
+									node = field;
+								}
+							}
+			    	        this.patternLocator.matchReportReference(node, enclosingElement, declarationVisitor.getLocalElement(i), declarationVisitor.getOtherElements(i), field.binding, level.intValue(), this);
+						}
+					}
+					return;
+				}
+			}
+		}
+	}
+}
+/**
+ * Visit the given type declaration and report the nodes that match exactly the
+ * search pattern (i.e. the ones in the matching nodes set)
+ */
+protected void reportMatching(TypeDeclaration type, IJavaElement parent, int accuracy, MatchingNodeSet nodeSet, int occurrenceCount) throws CoreException {
+	// create type handle
+	IJavaElement enclosingElement = parent;
+	if (enclosingElement == null) {
+		enclosingElement = createTypeHandle(new String(type.name));
+	} else if (enclosingElement instanceof IType) {
+		enclosingElement = ((IType) parent).getType(new String(type.name));
+	} else if (enclosingElement instanceof IMember) {
+	    IMember member = (IMember) parent;
+		if (member.isBinary())  {
+			enclosingElement = ((IClassFile)this.currentPossibleMatch.openable).getType();
+		} else {
+			enclosingElement = member.getType(new String(type.name), occurrenceCount);
+		}
+	}
+	if (enclosingElement == null) return;
+	boolean enclosesElement = encloses(enclosingElement);
+
+	// report the type declaration
+	if (accuracy > -1 && enclosesElement) {
+		int offset = type.sourceStart;
+		SearchMatch match = this.patternLocator.newDeclarationMatch(type, enclosingElement, type.binding, accuracy, type.sourceEnd-offset+1, this);
+		report(match);
+	}
+
+	boolean matchedClassContainer = (this.matchContainer & PatternLocator.CLASS_CONTAINER) != 0;
+
+	// report the type parameters
+	if (type.typeParameters != null) {
+		reportMatching(type.typeParameters, enclosingElement, parent, type.binding, nodeSet);
+	}
+
+	// report annotations
+	if (type.annotations != null) {
+		reportMatching(type.annotations, enclosingElement, null, type.binding, nodeSet, matchedClassContainer, enclosesElement);
+	}
+
+	// report references in javadoc
+	if (type.javadoc != null) {
+		ASTNode[] nodes = nodeSet.matchingNodes(type.declarationSourceStart, type.sourceStart);
+		if (nodes != null) {
+			if (!matchedClassContainer) {
+				for (int i = 0, l = nodes.length; i < l; i++)
+					nodeSet.matchingNodes.removeKey(nodes[i]);
+			} else {
+				for (int i = 0, l = nodes.length; i < l; i++) {
+					ASTNode node = nodes[i];
+					Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+					if (enclosesElement) {
+						this.patternLocator.matchReportReference(node, enclosingElement, null, null, type.binding, level.intValue(), this);
+					}
+				}
+			}
+		}
+	}
+
+	// super types
+	if ((type.bits & ASTNode.IsAnonymousType) != 0) {
+		TypeReference superType = type.allocation.type;
+		if (superType != null) {
+			Integer level = (Integer) nodeSet.matchingNodes.removeKey(superType);
+			if (level != null && matchedClassContainer)
+				this.patternLocator.matchReportReference(superType, enclosingElement, null, null, type.binding, level.intValue(), this);
+		}
+	} else {
+		TypeReference superClass = type.superclass;
+		if (superClass != null) {
+			reportMatchingSuper(superClass, enclosingElement, type.binding, nodeSet, matchedClassContainer);
+			for (int i = 0, length = superClass.annotations == null ? 0 : superClass.annotations.length; i < length; i++) {
+				reportMatching(superClass.annotations[i], enclosingElement, null, type.binding, nodeSet, matchedClassContainer, enclosesElement);	
+			}
+		}
+		TypeReference[] superInterfaces = type.superInterfaces;
+		if (superInterfaces != null) {
+			for (int i = 0, l = superInterfaces.length; i < l; i++) {
+				reportMatchingSuper(superInterfaces[i], enclosingElement, type.binding, nodeSet, matchedClassContainer);
+				TypeReference typeReference  = type.superInterfaces[i];
+				if (typeReference != null &&  typeReference.annotations != null) {
+					for (int j = 0, length = typeReference.annotations.length; j < length; j++) {
+						reportMatching(typeReference.annotations[j], enclosingElement, null, type.binding, nodeSet, matchedClassContainer, enclosesElement);	
+					}
+				}			
+			}
+		}
+	}
+
+	// filter out element not in hierarchy scope
+	boolean typeInHierarchy = type.binding == null || typeInHierarchy(type.binding);
+	matchedClassContainer = matchedClassContainer && typeInHierarchy;
+
+	// Visit fields
+	FieldDeclaration[] fields = type.fields;
+	if (fields != null) {
+		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
+		FieldDeclaration[] otherFields = null;
+		int first = -1;
+		int length = fields.length;
+		for (int i = 0; i < length; i++) {
+			FieldDeclaration field = fields[i];
+			boolean last = field.endPart2Position == 0 || field.declarationEnd == field.endPart2Position;
+			// Store first index of multiple field declaration
+			if (!last) {
+				if (first == -1) {
+					first = i;
+				}
+			}
+			if (first >= 0) {
+				// Store all multiple fields but first one for other elements
+				if (i > first) {
+					if (otherFields == null) {
+						otherFields = new FieldDeclaration[length-i];
+					}
+					otherFields[i-1-first] = field;
+				}
+				// On last field, report match with all other elements
+				if (last) {
+					for (int j=first; j<=i; j++) {
+						Integer level = (Integer) nodeSet.matchingNodes.removeKey(fields[j]);
+						int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
+						reportMatching(fields[j], otherFields, type, enclosingElement, value, typeInHierarchy, nodeSet);
+					}
+					first = -1;
+					otherFields = null;
+				}
+			} else {
+				// Single field, report normally
+				Integer level = (Integer) nodeSet.matchingNodes.removeKey(field);
+				int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
+				reportMatching(field, null, type, enclosingElement, value, typeInHierarchy, nodeSet);
+			}
+		}
+	}
+
+	// Visit methods
+	AbstractMethodDeclaration[] methods = type.methods;
+	if (methods != null) {
+		if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
+		for (int i = 0, l = methods.length; i < l; i++) {
+			AbstractMethodDeclaration method = methods[i];
+			Integer level = (Integer) nodeSet.matchingNodes.removeKey(method);
+			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
+			reportMatching(method, type, enclosingElement, value, typeInHierarchy, nodeSet);
+		}
+	}
+
+	// Visit types
+	TypeDeclaration[] memberTypes = type.memberTypes;
+	if (memberTypes != null) {
+		for (int i = 0, l = memberTypes.length; i < l; i++) {
+			if (nodeSet.matchingNodes.elementSize == 0) return;	// end as all matching nodes were reported
+			TypeDeclaration memberType = memberTypes[i];
+			Integer level = (Integer) nodeSet.matchingNodes.removeKey(memberType);
+			int value = (level != null && matchedClassContainer) ? level.intValue() : -1;
+			reportMatching(memberType, enclosingElement, value, nodeSet, 1);
+		}
+	}
+}
+/**
+ * Report matches in type parameters.
+ */
+protected void reportMatching(TypeParameter[] typeParameters, IJavaElement enclosingElement, IJavaElement parent, Binding binding, MatchingNodeSet nodeSet) throws CoreException {
+	if (typeParameters == null) return;
+	for (int i=0, l=typeParameters.length; i<l; i++) {
+		TypeParameter typeParameter = typeParameters[i];
+		if (typeParameter != null) {
+			Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
+			if (level != null) {
+				if (level.intValue() > -1 && encloses(enclosingElement)) {
+					int offset = typeParameter.sourceStart;
+					SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
+					report(match);
+				}
+			}
+			boolean matchedClassContainer = (this.matchContainer & PatternLocator.ALL_CONTAINER) != 0;
+			if (typeParameter.annotations != null) {
+				reportMatching(typeParameter.annotations, enclosingElement, null, typeParameter.binding, nodeSet, matchedClassContainer, encloses(enclosingElement));	
+			}
+			if (typeParameter.type != null) {
+				reportMatching(typeParameter.type.annotations, enclosingElement, typeParameter.binding, nodeSet, matchedClassContainer);
+				level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
+				if (level != null) {
+					IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+					this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, localElement, null, binding, level.intValue(), this);
+				}
+				if (typeParameter.type instanceof ParameterizedSingleTypeReference) {
+                    ParameterizedSingleTypeReference paramSTR = (ParameterizedSingleTypeReference) typeParameter.type;
+                    if (paramSTR.typeArguments != null) {
+                    	int length = paramSTR.typeArguments.length;
+                    	for (int k=0; k<length; k++) {
+							TypeReference typeArgument = paramSTR.typeArguments[k];
+							reportMatching(typeArgument.annotations, enclosingElement, typeArgument.resolvedType, nodeSet, matchedClassContainer);
+							level = (Integer) nodeSet.matchingNodes.removeKey(typeArgument);
+							if (level != null) {
+								IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+								this.patternLocator.matchReportReference(typeArgument, enclosingElement, localElement, null, binding, level.intValue(), this);
+							}
+							if (typeArgument instanceof Wildcard) {
+	                            TypeReference wildcardBound = ((Wildcard) typeArgument).bound;
+	                            if (wildcardBound != null) {
+		            				reportMatching(wildcardBound.annotations, enclosingElement, wildcardBound.resolvedType, nodeSet, matchedClassContainer);
+									level = (Integer) nodeSet.matchingNodes.removeKey(wildcardBound);
+									if (level != null) {
+										IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+										this.patternLocator.matchReportReference(wildcardBound, enclosingElement, localElement, null, binding, level.intValue(), this);
+									}
+	                            }
+                            }
+                    	}
+                    }
+				}
+			}
+			if (typeParameter.bounds != null) {
+				for (int j=0, b=typeParameter.bounds.length; j<b; j++) {
+					TypeReference typeParameterBound = typeParameter.bounds[j];
+					level = (Integer) nodeSet.matchingNodes.removeKey(typeParameterBound);
+					if (level != null) {
+						IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+						this.patternLocator.matchReportReference(typeParameterBound, enclosingElement, localElement, null, binding, level.intValue(), this);
+					}
+					if (typeParameterBound instanceof ParameterizedSingleTypeReference) {
+	                    ParameterizedSingleTypeReference paramSTR = (ParameterizedSingleTypeReference) typeParameterBound;
+	                    if (paramSTR.typeArguments != null) {
+	                    	int length = paramSTR.typeArguments.length;
+	                    	for (int k=0; k<length; k++) {
+								TypeReference typeArgument = paramSTR.typeArguments[k];
+								level = (Integer) nodeSet.matchingNodes.removeKey(typeArgument);
+								if (level != null) {
+									IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+									this.patternLocator.matchReportReference(typeArgument, enclosingElement, localElement, null, binding, level.intValue(), this);
+								}
+								if (typeArgument instanceof Wildcard) {
+		                            TypeReference wildcardBound = ((Wildcard) typeArgument).bound;
+		                            if (wildcardBound != null) {
+										level = (Integer) nodeSet.matchingNodes.removeKey(wildcardBound);
+										if (level != null) {
+											IJavaElement localElement = createHandle(typeParameter, enclosingElement);
+											this.patternLocator.matchReportReference(wildcardBound, enclosingElement, localElement, null, binding, level.intValue(), this);
+										}
+		                            }
+	                            }
+	                    	}
+	                    }
+                    }
+				}
+			}
+		}
+	}
+}
+protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
+	ASTNode[] nodes = null;
+	if (superReference instanceof ParameterizedSingleTypeReference || superReference instanceof ParameterizedQualifiedTypeReference) {
+		long lastTypeArgumentInfo = findLastTypeArgumentInfo(superReference);
+		nodes = nodeSet.matchingNodes(superReference.sourceStart, (int)lastTypeArgumentInfo);
+	}
+	if (nodes != null) {
+		if ((this.matchContainer & PatternLocator.CLASS_CONTAINER) == 0) {
+			for (int i = 0, l = nodes.length; i < l; i++)
+				nodeSet.matchingNodes.removeKey(nodes[i]);
+		} else {
+			if (encloses(enclosingElement))
+				for (int i = 0, l = nodes.length; i < l; i++) {
+					ASTNode node = nodes[i];
+					Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+					this.patternLocator.matchReportReference(node, enclosingElement, null, null, elementBinding, level.intValue(), this);
+				}
+		}
+	} else if (encloses(enclosingElement)) {
+		Integer level = (Integer) nodeSet.matchingNodes.removeKey(superReference);
+		if (level != null && matchedClassContainer)
+			this.patternLocator.matchReportReference(superReference, enclosingElement, null, null, elementBinding, level.intValue(), this);
+	}
+}
+protected boolean typeInHierarchy(ReferenceBinding binding) {
+	if (this.hierarchyResolver == null) return true; // not a hierarchy scope
+	if (this.hierarchyResolver.subOrSuperOfFocus(binding)) return true;
+
+	if (this.allSuperTypeNames != null) {
+		char[][] compoundName = binding.compoundName;
+		for (int i = 0, length = this.allSuperTypeNames.length; i < length; i++)
+			if (CharOperation.equals(compoundName, this.allSuperTypeNames[i]))
+				return true;
+	}
+	return false;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
new file mode 100644
index 0000000..151300d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -0,0 +1,866 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+
+/**
+ * A parser that locates ast nodes that match a given search pattern.
+ */
+public class MatchLocatorParser extends Parser {
+
+	MatchingNodeSet nodeSet;
+	PatternLocator patternLocator;
+	private ASTVisitor localDeclarationVisitor;
+	final int patternFineGrain;
+
+public static MatchLocatorParser createParser(ProblemReporter problemReporter, MatchLocator locator) {
+	if ((locator.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0) {
+		return new ImportMatchLocatorParser(problemReporter, locator);
+	}
+	return new MatchLocatorParser(problemReporter, locator);
+}
+
+/**
+ * An ast visitor that visits local type declarations.
+ */
+public class NoClassNoMethodDeclarationVisitor extends ASTVisitor {
+	public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+		return (constructorDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+	public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+		return (fieldDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type;
+	}
+	public boolean visit(Initializer initializer, MethodScope scope) {
+		return (initializer.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+	public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+		return (methodDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+}
+public class MethodButNoClassDeclarationVisitor extends NoClassNoMethodDeclarationVisitor {
+	public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+		MatchLocatorParser.this.patternLocator.match(localTypeDeclaration, MatchLocatorParser.this.nodeSet);
+		return true;
+	}
+}
+public class ClassButNoMethodDeclarationVisitor extends ASTVisitor {
+	public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+		MatchLocatorParser.this.patternLocator.match(constructorDeclaration, MatchLocatorParser.this.nodeSet);
+		return (constructorDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+	public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+		MatchLocatorParser.this.patternLocator.match(fieldDeclaration, MatchLocatorParser.this.nodeSet);
+		return (fieldDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type;
+	}
+	public boolean visit(Initializer initializer, MethodScope scope) {
+		MatchLocatorParser.this.patternLocator.match(initializer, MatchLocatorParser.this.nodeSet);
+		return (initializer.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+	public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+		MatchLocatorParser.this.patternLocator.match(memberTypeDeclaration, MatchLocatorParser.this.nodeSet);
+		return true;
+	}
+	public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+		MatchLocatorParser.this.patternLocator.match(methodDeclaration, MatchLocatorParser.this.nodeSet);
+		return (methodDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
+	}
+	public boolean visit(AnnotationMethodDeclaration methodDeclaration, ClassScope scope) {
+		MatchLocatorParser.this.patternLocator.match(methodDeclaration, MatchLocatorParser.this.nodeSet);
+		return false; // no local type for annotation type members
+	}
+}
+public class ClassAndMethodDeclarationVisitor extends ClassButNoMethodDeclarationVisitor {
+	public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
+		MatchLocatorParser.this.patternLocator.match(localTypeDeclaration, MatchLocatorParser.this.nodeSet);
+		return true;
+	}
+}
+
+protected MatchLocatorParser(ProblemReporter problemReporter, MatchLocator locator) {
+	super(problemReporter, true);
+	this.reportOnlyOneSyntaxError = true;
+	this.patternLocator = locator.patternLocator;
+	if ((locator.matchContainer & PatternLocator.CLASS_CONTAINER) != 0) {
+		this.localDeclarationVisitor = (locator.matchContainer & PatternLocator.METHOD_CONTAINER) != 0
+			? new ClassAndMethodDeclarationVisitor()
+			: new ClassButNoMethodDeclarationVisitor();
+	} else {
+		this.localDeclarationVisitor = (locator.matchContainer & PatternLocator.METHOD_CONTAINER) != 0
+			? new MethodButNoClassDeclarationVisitor()
+			: new NoClassNoMethodDeclarationVisitor();
+	}
+	this.patternFineGrain = this.patternLocator.fineGrain();
+}
+public void checkComment() {
+	super.checkComment();
+	if (this.javadocParser.checkDocComment && this.javadoc != null && this.patternFineGrain == 0 /* there's no fine grain concerning Javadoc*/) {
+
+		// Search for pattern locator matches in javadoc comment parameters @param tags
+		JavadocSingleNameReference[] paramReferences = this.javadoc.paramReferences;
+		if (paramReferences != null) {
+			for (int i=0, length=paramReferences.length; i < length; i++) {
+				this.patternLocator.match(paramReferences[i], this.nodeSet);
+			}
+		}
+
+		// Search for pattern locator matches in javadoc comment type parameters @param tags
+		JavadocSingleTypeReference[] paramTypeParameters = this.javadoc.paramTypeParameters;
+		if (paramTypeParameters != null) {
+			for (int i=0, length=paramTypeParameters.length; i < length; i++) {
+				this.patternLocator.match(paramTypeParameters[i], this.nodeSet);
+			}
+		}
+
+		// Search for pattern locator matches in javadoc comment @throws/@exception tags
+		TypeReference[] thrownExceptions = this.javadoc.exceptionReferences;
+		if (thrownExceptions != null) {
+			for (int i=0, length=thrownExceptions.length; i < length; i++) {
+				this.patternLocator.match(thrownExceptions[i], this.nodeSet);
+			}
+		}
+
+		// Search for pattern locator matches in javadoc comment @see tags
+		Expression[] references = this.javadoc.seeReferences;
+		if (references != null) {
+			for (int i=0, length=references.length; i < length; i++) {
+				Expression reference = references[i];
+				if (reference instanceof TypeReference) {
+					TypeReference typeRef = (TypeReference) reference;
+					this.patternLocator.match(typeRef, this.nodeSet);
+				} else if (reference instanceof JavadocFieldReference) {
+					JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
+					this.patternLocator.match(fieldRef, this.nodeSet);
+					if (fieldRef.receiver instanceof TypeReference && !fieldRef.receiver.isThis()) {
+						TypeReference typeRef = (TypeReference) fieldRef.receiver;
+						this.patternLocator.match(typeRef, this.nodeSet);
+					}
+				} else if (reference instanceof JavadocMessageSend) {
+					JavadocMessageSend messageSend = (JavadocMessageSend) reference;
+					this.patternLocator.match(messageSend, this.nodeSet);
+					if (messageSend.receiver instanceof TypeReference && !messageSend.receiver.isThis()) {
+						TypeReference typeRef = (TypeReference) messageSend.receiver;
+						this.patternLocator.match(typeRef, this.nodeSet);
+					}
+					if (messageSend.arguments != null) {
+						for (int a=0,al=messageSend.arguments.length; a<al; a++) {
+							JavadocArgumentExpression argument = (JavadocArgumentExpression) messageSend.arguments[a];
+							if (argument.argument != null && argument.argument.type != null) {
+								this.patternLocator.match(argument.argument.type, this.nodeSet);
+							}
+						}
+					}
+				} else if (reference instanceof JavadocAllocationExpression) {
+					JavadocAllocationExpression constructor = (JavadocAllocationExpression) reference;
+					this.patternLocator.match(constructor, this.nodeSet);
+					if (constructor.type != null && !constructor.type.isThis()) {
+						this.patternLocator.match(constructor.type, this.nodeSet);
+					}
+					if (constructor.arguments != null) {
+						for (int a=0,al=constructor.arguments.length; a<al; a++) {
+							this.patternLocator.match(constructor.arguments[a], this.nodeSet);
+							JavadocArgumentExpression argument = (JavadocArgumentExpression) constructor.arguments[a];
+							if (argument.argument != null && argument.argument.type != null) {
+								this.patternLocator.match(argument.argument.type, this.nodeSet);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+protected void classInstanceCreation(boolean alwaysQualified) {
+	super.classInstanceCreation(alwaysQualified);
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+	} else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
+		AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(allocation.type, this.nodeSet);
+	}
+}
+
+protected void consumeAdditionalBound() {
+	super.consumeAdditionalBound();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
+		TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(typeReference, this.nodeSet);
+	}
+}
+
+protected void consumeAssignment() {
+	super.consumeAssignment();
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeCastExpressionLL1() {
+	super.consumeCastExpressionLL1();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCastExpressionLL1WithBounds() {
+	super.consumeCastExpressionLL1WithBounds();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCastExpressionWithGenericsArray() {
+	super.consumeCastExpressionWithGenericsArray();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCastExpressionWithNameArray() {
+	super.consumeCastExpressionWithNameArray();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCastExpressionWithPrimitiveType() {
+	super.consumeCastExpressionWithPrimitiveType();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCastExpressionWithQualifiedGenericsArray() {
+	super.consumeCastExpressionWithQualifiedGenericsArray();
+	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
+		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(castExpression.type, this.nodeSet);
+	}
+}
+protected void consumeCatchFormalParameter() {
+	super.consumeCatchFormalParameter();
+	this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
+}
+
+protected void consumeClassHeaderExtends() {
+	this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
+	super.consumeClassHeaderExtends();
+	if ((this.patternFineGrain & IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE) != 0) {
+		TypeDeclaration typeDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
+		this.patternLocator.match(typeDeclaration.superclass, this.nodeSet);
+	}
+	this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
+}
+
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+	} else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
+		AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(allocation.type, this.nodeSet);
+	}
+}
+
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+	} else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
+		AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(allocation.type, this.nodeSet);
+	}
+}
+
+protected void consumeEnterAnonymousClassBody(boolean qualified) {
+	this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
+	super.consumeEnterAnonymousClassBody(qualified);
+	this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
+}
+
+protected void consumeEnterVariable() {
+	boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
+	super.consumeEnterVariable();
+	if (isLocalDeclaration) {
+		if ((this.patternFineGrain & IJavaSearchConstants.LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE) != 0) {
+			LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
+			this.patternLocator.match(localDeclaration.type, this.nodeSet);
+		}
+	} else {
+		if ((this.patternFineGrain & IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE) != 0) {
+			FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
+			this.patternLocator.match(fieldDeclaration.type, this.nodeSet);
+		}
+	}
+}
+
+protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
+	super.consumeExplicitConstructorInvocation(flag, recFlag);
+	this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+}
+protected void consumeExplicitConstructorInvocationWithTypeArguments(int flag, int recFlag) {
+	super.consumeExplicitConstructorInvocationWithTypeArguments(flag, recFlag);
+	this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
+}
+protected void consumeFieldAccess(boolean isSuperAccess) {
+	super.consumeFieldAccess(isSuperAccess);
+
+	int fineGrain = isSuperAccess ? IJavaSearchConstants.SUPER_REFERENCE : IJavaSearchConstants.THIS_REFERENCE;
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & fineGrain) != 0) {
+		// this is always a Reference
+		this.patternLocator.match((Reference) this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeFormalParameter(boolean isVarArgs) {
+	super.consumeFormalParameter(isVarArgs);
+	this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
+}
+
+protected void consumeInstanceOfExpression() {
+	super.consumeInstanceOfExpression();
+	if ((this.patternFineGrain & IJavaSearchConstants.INSTANCEOF_TYPE_REFERENCE) != 0) {
+		InstanceOfExpression expression = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(expression.type, this.nodeSet);
+	}
+}
+protected void consumeInstanceOfExpressionWithName() {
+	super.consumeInstanceOfExpressionWithName();
+	if ((this.patternFineGrain & IJavaSearchConstants.INSTANCEOF_TYPE_REFERENCE) != 0) {
+		InstanceOfExpression expression = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
+		this.patternLocator.match(expression.type, this.nodeSet);
+	}
+}
+protected void consumeInterfaceType() {
+	this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
+	super.consumeInterfaceType();
+	if ((this.patternFineGrain & IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE) != 0) {
+		TypeReference typeReference = (TypeReference) this.astStack[this.astPtr];
+		this.patternLocator.match(typeReference, this.nodeSet);
+	}
+	this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
+}
+
+protected void consumeLocalVariableDeclaration() {
+	super.consumeLocalVariableDeclaration();
+	this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
+}
+
+protected void consumeMarkerAnnotation(boolean isTypeAnnotation) {
+	super.consumeMarkerAnnotation(isTypeAnnotation);
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
+		Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+		this.patternLocator.match(annotation, this.nodeSet);
+	}
+}
+protected void consumeMemberValuePair() {
+	super.consumeMemberValuePair();
+	this.patternLocator.match((MemberValuePair) this.astStack[this.astPtr], this.nodeSet);
+}
+
+protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
+	super.consumeMethodHeaderName(isAnnotationMethod);
+	if ((this.patternFineGrain & IJavaSearchConstants.RETURN_TYPE_REFERENCE) != 0) {
+		// when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
+		MethodDeclaration methodDeclaration = (MethodDeclaration) this.astStack[this.astPtr];
+		this.patternLocator.match(methodDeclaration.returnType, this.nodeSet);
+	}
+}
+protected void consumeMethodHeaderRightParen() {
+	super.consumeMethodHeaderRightParen();
+	if ((this.patternFineGrain & IJavaSearchConstants.PARAMETER_DECLARATION_TYPE_REFERENCE) != 0) {
+		// when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
+		AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) this.astStack[this.astPtr];
+		Argument[] arguments = methodDeclaration.arguments;
+		if (arguments != null) {
+			int argLength = arguments.length;
+			for (int i=0; i<argLength; i++) {
+				this.patternLocator.match(arguments[i].type, this.nodeSet);
+			}
+		}
+	}
+}
+protected void consumeMethodHeaderThrowsClause() {
+	super.consumeMethodHeaderThrowsClause();
+	if ((this.patternFineGrain & IJavaSearchConstants.THROWS_CLAUSE_TYPE_REFERENCE) != 0) {
+		// when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
+		AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) this.astStack[this.astPtr];
+		TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
+		if (thrownExceptions != null) {
+			int thrownLength = thrownExceptions.length;
+			for (int i=0; i<thrownLength; i++) {
+				this.patternLocator.match(thrownExceptions[i], this.nodeSet);
+			}
+		}
+	}
+}
+
+protected void consumeMethodInvocationName() {
+	super.consumeMethodInvocationName();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(messageSend, this.nodeSet);
+	} else {
+		if (messageSend.receiver.isThis()) {
+			if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
+				this.patternLocator.match(messageSend, this.nodeSet);
+			}
+		} else {
+			if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
+				this.patternLocator.match(messageSend, this.nodeSet);
+			}
+		}
+	}
+}
+
+protected void consumeMethodInvocationNameWithTypeArguments() {
+	super.consumeMethodInvocationNameWithTypeArguments();
+	MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(messageSend, this.nodeSet);
+	} else {
+		if (messageSend.receiver.isThis()) {
+			if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
+				this.patternLocator.match(messageSend, this.nodeSet);
+			}
+		} else {
+			if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
+				this.patternLocator.match(messageSend, this.nodeSet);
+			}
+		}
+	}
+}
+
+protected void consumeMethodInvocationPrimary() {
+	super.consumeMethodInvocationPrimary();
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.THIS_REFERENCE) != 0) {
+		this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+	super.consumeMethodInvocationPrimaryWithTypeArguments();
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.THIS_REFERENCE) != 0) {
+		this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeMethodInvocationSuper() {
+	super.consumeMethodInvocationSuper();
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.SUPER_REFERENCE) != 0) {
+		this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+	super.consumeMethodInvocationSuperWithTypeArguments();
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.SUPER_REFERENCE) != 0) {
+		this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
+	}
+}
+
+protected void consumeNormalAnnotation(boolean isTypeAnnotation) {
+	super.consumeNormalAnnotation(isTypeAnnotation);
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
+		// this is always an Annotation
+		Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+		this.patternLocator.match(annotation, this.nodeSet);
+	}
+}
+
+protected void consumeOnlyTypeArguments() {
+	super.consumeOnlyTypeArguments();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		if (length == 1) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[this.genericsPtr];
+			if (!(typeReference instanceof Wildcard)) {
+				this.patternLocator.match(typeReference, this.nodeSet);
+            }
+		}
+	}
+}
+
+protected void consumePrimaryNoNewArray() {
+	// pop parenthesis positions (and don't update expression positions
+	// (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329)
+	this.intPtr--;
+	this.intPtr--;
+}
+
+protected void consumePrimaryNoNewArrayWithName() {
+	// PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN
+	pushOnExpressionStack(getUnspecifiedReferenceOptimized());
+	// pop parenthesis positions (and don't update expression positions
+	// (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329)
+	this.intPtr--;
+	this.intPtr--;
+}
+
+protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) {
+	super.consumeSingleMemberAnnotation(isTypeAnnotation);
+	if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
+		// this is always an Annotation
+		Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : this.expressionStack[this.expressionPtr]);
+		this.patternLocator.match(annotation, this.nodeSet);
+	}
+}
+
+protected void consumeStatementCatch() {
+	super.consumeStatementCatch();
+	if ((this.patternFineGrain & IJavaSearchConstants.CATCH_TYPE_REFERENCE) != 0) {
+		// when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
+		LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr-1];
+		if (localDeclaration.type instanceof UnionTypeReference) {
+			TypeReference[] refs = ((UnionTypeReference)localDeclaration.type).typeReferences;
+			for (int i = 0, len  = refs.length; i < len; i++) {
+				this.patternLocator.match(refs[i], this.nodeSet);
+			}
+		} else {
+			this.patternLocator.match(localDeclaration.type, this.nodeSet);
+		}
+	}
+}
+
+protected void consumeTypeArgumentList1() {
+	super.consumeTypeArgumentList1();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		for (int i=this.genericsPtr-this.genericsLengthStack[this.genericsLengthPtr]+1; i<=this.genericsPtr; i++) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[i];
+			if (!(typeReference instanceof Wildcard)) {
+				this.patternLocator.match(typeReference, this.nodeSet);
+            }
+		}
+	}
+}
+
+protected void consumeTypeArgumentList2() {
+	super.consumeTypeArgumentList2();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		for (int i=this.genericsPtr-this.genericsLengthStack[this.genericsLengthPtr]+1; i<=this.genericsPtr; i++) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[i];
+			if (!(typeReference instanceof Wildcard)) {
+				this.patternLocator.match(typeReference, this.nodeSet);
+            }
+		}
+	}
+}
+
+protected void consumeTypeArgumentList3() {
+	super.consumeTypeArgumentList3();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		for (int i=this.genericsPtr-this.genericsLengthStack[this.genericsLengthPtr]+1; i<=this.genericsPtr; i++) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[i];
+			if (!(typeReference instanceof Wildcard)) {
+				this.patternLocator.match(typeReference, this.nodeSet);
+            }
+		}
+	}
+}
+
+protected void consumeTypeArgumentReferenceType1() {
+	super.consumeTypeArgumentReferenceType1();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		if (length == 1) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[this.genericsPtr];
+			TypeReference[] typeArguments = null;
+			if (typeReference instanceof ParameterizedSingleTypeReference) {
+	            typeArguments = ((ParameterizedSingleTypeReference) typeReference).typeArguments;
+            } else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
+	            TypeReference[][] allTypeArguments = ((ParameterizedQualifiedTypeReference) typeReference).typeArguments;
+	            typeArguments = allTypeArguments[allTypeArguments.length-1];
+            }
+			if (typeArguments != null) {
+	            for (int i=0, ln=typeArguments.length; i<ln; i++) {
+	            	if (!(typeArguments[i] instanceof Wildcard)) {
+						this.patternLocator.match(typeArguments[i], this.nodeSet);
+	            	}
+	            }
+			}
+		}
+	}
+}
+
+protected void consumeTypeArgumentReferenceType2() {
+	super.consumeTypeArgumentReferenceType2();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		if (length == 1) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[this.genericsPtr];
+			TypeReference[] typeArguments = null;
+			if (typeReference instanceof ParameterizedSingleTypeReference) {
+	            typeArguments = ((ParameterizedSingleTypeReference) typeReference).typeArguments;
+            } else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
+	            TypeReference[][] allTypeArguments = ((ParameterizedQualifiedTypeReference) typeReference).typeArguments;
+	            typeArguments = allTypeArguments[allTypeArguments.length-1];
+            }
+			if (typeArguments != null) {
+	            for (int i=0, ln=typeArguments.length; i<ln; i++) {
+	            	if (!(typeArguments[i] instanceof Wildcard)) {
+						this.patternLocator.match(typeArguments[i], this.nodeSet);
+	            	}
+	            }
+			}
+		}
+	}
+}
+
+protected void consumeTypeArguments() {
+	super.consumeTypeArguments();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
+		int length = this.genericsLengthStack[this.genericsLengthPtr];
+		if (length == 1) {
+			TypeReference typeReference = (TypeReference)this.genericsStack[this.genericsPtr];
+			if (!(typeReference instanceof Wildcard)) {
+				this.patternLocator.match(typeReference, this.nodeSet);
+            }
+		}
+	}
+}
+
+protected void consumeTypeParameter1WithExtends() {
+	super.consumeTypeParameter1WithExtends();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(typeParameter.type, this.nodeSet);
+	}
+}
+
+protected void consumeTypeParameter1WithExtendsAndBounds() {
+	super.consumeTypeParameter1WithExtendsAndBounds();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(typeParameter.type, this.nodeSet);
+	}
+}
+
+protected void consumeTypeParameterHeader() {
+	super.consumeTypeParameterHeader();
+	this.patternLocator.match((TypeParameter)this.genericsStack[this.genericsPtr], this.nodeSet);
+}
+
+protected void consumeTypeParameterWithExtends() {
+	super.consumeTypeParameterWithExtends();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(typeParameter.type, this.nodeSet);
+	}
+}
+
+protected void consumeTypeParameterWithExtendsAndBounds() {
+	super.consumeTypeParameterWithExtendsAndBounds();
+	if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
+		TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(typeParameter.type, this.nodeSet);
+	}
+}
+
+protected void consumeUnaryExpression(int op, boolean post) {
+	super.consumeUnaryExpression(op, post);
+	this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+}
+
+protected void consumeWildcardBounds1Extends() {
+	super.consumeWildcardBounds1Extends();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBounds1Super() {
+	super.consumeWildcardBounds1Super();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBounds2Extends() {
+	super.consumeWildcardBounds2Extends();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBounds2Super() {
+	super.consumeWildcardBounds2Super();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBounds3Extends() {
+	super.consumeWildcardBounds3Extends();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBounds3Super() {
+	super.consumeWildcardBounds3Super();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBoundsExtends() {
+	super.consumeWildcardBoundsExtends();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected void consumeWildcardBoundsSuper() {
+	super.consumeWildcardBoundsSuper();
+	if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
+		Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+		this.patternLocator.match(wildcard.bound, this.nodeSet);
+	}
+}
+
+protected TypeReference copyDims(TypeReference typeRef, int dim) {
+	TypeReference result = super.copyDims(typeRef, dim);
+	 if (this.nodeSet.removePossibleMatch(typeRef) != null)
+		this.nodeSet.addPossibleMatch(result);
+	 else if (this.nodeSet.removeTrustedMatch(typeRef) != null)
+		this.nodeSet.addTrustedMatch(result, true);
+	return result;
+}
+protected TypeReference copyDims(TypeReference typeRef, int dim, Annotation [][] annotationsOnDimensions) {
+	TypeReference result = super.copyDims(typeRef, dim, annotationsOnDimensions);
+	 if (this.nodeSet.removePossibleMatch(typeRef) != null)
+		this.nodeSet.addPossibleMatch(result);
+	 else if (this.nodeSet.removeTrustedMatch(typeRef) != null)
+		this.nodeSet.addTrustedMatch(result, true);
+	return result;
+}
+protected TypeReference getTypeReference(int dim) {
+	TypeReference typeRef = super.getTypeReference(dim);
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(typeRef, this.nodeSet); // NB: Don't check container since type reference can happen anywhere
+	}
+	return typeRef;
+}
+protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
+	NameReference nameRef = super.getUnspecifiedReference(rejectTypeAnnotations);
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(nameRef, this.nodeSet); // NB: Don't check container since unspecified reference can happen anywhere
+	} else if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
+		if (nameRef instanceof QualifiedNameReference) {
+			this.patternLocator.match(nameRef, this.nodeSet);
+		}
+	} else if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
+		if (nameRef instanceof SingleNameReference) {
+			this.patternLocator.match(nameRef, this.nodeSet);
+		}
+	}
+	return nameRef;
+}
+protected NameReference getUnspecifiedReferenceOptimized() {
+	NameReference nameRef = super.getUnspecifiedReferenceOptimized();
+	if (this.patternFineGrain == 0) {
+		this.patternLocator.match(nameRef, this.nodeSet); // NB: Don't check container since unspecified reference can happen anywhere
+	} else {
+		boolean flagQualifiedRef = (this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0;
+		boolean flagImplicitThis = (this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0;
+		if (flagQualifiedRef && flagImplicitThis) {
+			this.patternLocator.match(nameRef, this.nodeSet);
+		} else if (flagQualifiedRef) {
+			if (nameRef instanceof QualifiedNameReference) {
+				this.patternLocator.match(nameRef, this.nodeSet);
+			}
+		} else if (flagImplicitThis) {
+			if (nameRef instanceof SingleNameReference) {
+				this.patternLocator.match(nameRef, this.nodeSet);
+			}
+		}
+	}
+	return nameRef;
+}
+/**
+ * Parses the method bodies in the given compilation unit
+ * @param unit CompilationUnitDeclaration
+ */
+public void parseBodies(CompilationUnitDeclaration unit) {
+	TypeDeclaration[] types = unit.types;
+	if (types == null) return;
+
+	for (int i = 0; i < types.length; i++) {
+		TypeDeclaration type = types[i];
+		this.patternLocator.match(type, this.nodeSet);
+		this.parseBodies(type, unit);
+	}
+}
+/**
+ * Parses the member bodies in the given type.
+ * @param type TypeDeclaration
+ * @param unit CompilationUnitDeclaration
+ */
+protected void parseBodies(TypeDeclaration type, CompilationUnitDeclaration unit) {
+	FieldDeclaration[] fields = type.fields;
+	if (fields != null) {
+		for (int i = 0; i < fields.length; i++) {
+			FieldDeclaration field = fields[i];
+			if (field instanceof Initializer)
+				this.parse((Initializer) field, type, unit);
+			field.traverse(this.localDeclarationVisitor, null);
+		}
+	}
+
+	AbstractMethodDeclaration[] methods = type.methods;
+	if (methods != null) {
+		for (int i = 0; i < methods.length; i++) {
+			AbstractMethodDeclaration method = methods[i];
+			if (method.sourceStart >= type.bodyStart) { // if not synthetic
+				if (method instanceof MethodDeclaration) {
+					MethodDeclaration methodDeclaration = (MethodDeclaration) method;
+					this.parse(methodDeclaration, unit);
+					methodDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null);
+				} else if (method instanceof ConstructorDeclaration) {
+					ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method;
+					this.parse(constructorDeclaration, unit, false);
+					constructorDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null);
+				}
+			} else if (method.isDefaultConstructor()) {
+				method.parseStatements(this, unit);
+			}
+		}
+	}
+
+	TypeDeclaration[] memberTypes = type.memberTypes;
+	if (memberTypes != null) {
+		for (int i = 0; i < memberTypes.length; i++) {
+			TypeDeclaration memberType = memberTypes[i];
+			this.parseBodies(memberType, unit);
+			memberType.traverse(this.localDeclarationVisitor, (ClassScope) null);
+		}
+	}
+}
+
+}
+
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
new file mode 100644
index 0000000..0ce2634
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfLong;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * A set of matches and possible matches, which need to be resolved.
+ */
+public class MatchingNodeSet {
+
+/**
+ * Map of matching ast nodes that don't need to be resolved to their accuracy level.
+ * Each node is removed as it is reported.
+ */
+SimpleLookupTable matchingNodes = new SimpleLookupTable(3); // node -> accuracy
+private HashtableOfLong matchingNodesKeys = new HashtableOfLong(3); // sourceRange -> node
+static Integer EXACT_MATCH = new Integer(SearchMatch.A_ACCURATE);
+static Integer POTENTIAL_MATCH = new Integer(SearchMatch.A_INACCURATE);
+static Integer ERASURE_MATCH = new Integer(SearchPattern.R_ERASURE_MATCH);
+
+/**
+ * Tell whether locators need to resolve or not for current matching node set.
+ */
+public boolean mustResolve;
+
+/**
+ * Set of possible matching ast nodes. They need to be resolved
+ * to determine if they really match the search pattern.
+ */
+SimpleSet possibleMatchingNodesSet = new SimpleSet(7);
+private HashtableOfLong possibleMatchingNodesKeys = new HashtableOfLong(7);
+
+
+public MatchingNodeSet(boolean mustResolvePattern) {
+	super();
+	this.mustResolve = mustResolvePattern;
+}
+
+public int addMatch(ASTNode node, int matchLevel) {
+	int maskedLevel = matchLevel & PatternLocator.MATCH_LEVEL_MASK;
+	switch (maskedLevel) {
+		case PatternLocator.INACCURATE_MATCH:
+			if (matchLevel != maskedLevel) {
+				addTrustedMatch(node, new Integer(SearchMatch.A_INACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
+			} else {
+				addTrustedMatch(node, POTENTIAL_MATCH);
+			}
+			break;
+		case PatternLocator.POSSIBLE_MATCH:
+			addPossibleMatch(node);
+			break;
+		case PatternLocator.ERASURE_MATCH:
+			if (matchLevel != maskedLevel) {
+				addTrustedMatch(node, new Integer(SearchPattern.R_ERASURE_MATCH+(matchLevel & PatternLocator.FLAVORS_MASK)));
+			} else {
+				addTrustedMatch(node, ERASURE_MATCH);
+			}
+			break;
+		case PatternLocator.ACCURATE_MATCH:
+			if (matchLevel != maskedLevel) {
+				addTrustedMatch(node, new Integer(SearchMatch.A_ACCURATE+(matchLevel & PatternLocator.FLAVORS_MASK)));
+			} else {
+				addTrustedMatch(node, EXACT_MATCH);
+			}
+			break;
+	}
+	return matchLevel;
+}
+public void addPossibleMatch(ASTNode node) {
+	// remove existing node at same position from set
+	// (case of recovery that created the same node several time
+	// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
+	long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
+	ASTNode existing = (ASTNode) this.possibleMatchingNodesKeys.get(key);
+	if (existing != null && existing.getClass().equals(node.getClass()))
+		this.possibleMatchingNodesSet.remove(existing);
+
+	// add node to set
+	this.possibleMatchingNodesSet.add(node);
+	this.possibleMatchingNodesKeys.put(key, node);
+}
+public void addTrustedMatch(ASTNode node, boolean isExact) {
+	addTrustedMatch(node, isExact ? EXACT_MATCH : POTENTIAL_MATCH);
+
+}
+void addTrustedMatch(ASTNode node, Integer level) {
+	// remove existing node at same position from set
+	// (case of recovery that created the same node several time
+	// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
+	long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
+	ASTNode existing = (ASTNode) this.matchingNodesKeys.get(key);
+	if (existing != null && existing.getClass().equals(node.getClass()))
+		this.matchingNodes.removeKey(existing);
+
+	// map node to its accuracy level
+	this.matchingNodes.put(node, level);
+	this.matchingNodesKeys.put(key, node);
+}
+protected boolean hasPossibleNodes(int start, int end) {
+	Object[] nodes = this.possibleMatchingNodesSet.values;
+	for (int i = 0, l = nodes.length; i < l; i++) {
+		ASTNode node = (ASTNode) nodes[i];
+		if (node != null && start <= node.sourceStart && node.sourceEnd <= end)
+			return true;
+	}
+	nodes = this.matchingNodes.keyTable;
+	for (int i = 0, l = nodes.length; i < l; i++) {
+		ASTNode node = (ASTNode) nodes[i];
+		if (node != null && start <= node.sourceStart && node.sourceEnd <= end)
+			return true;
+	}
+	return false;
+}
+/**
+ * Returns the matching nodes that are in the given range in the source order.
+ */
+protected ASTNode[] matchingNodes(int start, int end) {
+	ArrayList nodes = null;
+	Object[] keyTable = this.matchingNodes.keyTable;
+	for (int i = 0, l = keyTable.length; i < l; i++) {
+		ASTNode node = (ASTNode) keyTable[i];
+		if (node != null && start <= node.sourceStart && node.sourceEnd <= end) {
+			if (nodes == null) nodes = new ArrayList();
+			nodes.add(node);
+		}
+	}
+	if (nodes == null) return null;
+
+	ASTNode[] result = new ASTNode[nodes.size()];
+	nodes.toArray(result);
+
+	// sort nodes by source starts
+	Util.Comparer comparer = new Util.Comparer() {
+		public int compare(Object o1, Object o2) {
+			return ((ASTNode) o1).sourceStart - ((ASTNode) o2).sourceStart;
+		}
+	};
+	Util.sort(result, comparer);
+	return result;
+}
+public Object removePossibleMatch(ASTNode node) {
+	long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
+	ASTNode existing = (ASTNode) this.possibleMatchingNodesKeys.get(key);
+	if (existing == null) return null;
+
+	this.possibleMatchingNodesKeys.put(key, null);
+	return this.possibleMatchingNodesSet.remove(node);
+}
+public Object removeTrustedMatch(ASTNode node) {
+	long key = (((long) node.sourceStart) << 32) + node.sourceEnd;
+	ASTNode existing = (ASTNode) this.matchingNodesKeys.get(key);
+	if (existing == null) return null;
+
+	this.matchingNodesKeys.put(key, null);
+	return this.matchingNodes.removeKey(node);
+}
+public String toString() {
+	// TODO (jerome) should show both tables
+	StringBuffer result = new StringBuffer();
+	result.append("Exact matches:"); //$NON-NLS-1$
+	Object[] keyTable = this.matchingNodes.keyTable;
+	Object[] valueTable = this.matchingNodes.valueTable;
+	for (int i = 0, l = keyTable.length; i < l; i++) {
+		ASTNode node = (ASTNode) keyTable[i];
+		if (node == null) continue;
+		result.append("\n\t"); //$NON-NLS-1$
+		switch (((Integer)valueTable[i]).intValue()) {
+			case SearchMatch.A_ACCURATE:
+				result.append("ACCURATE_MATCH: "); //$NON-NLS-1$
+				break;
+			case SearchMatch.A_INACCURATE:
+				result.append("INACCURATE_MATCH: "); //$NON-NLS-1$
+				break;
+			case SearchPattern.R_ERASURE_MATCH:
+				result.append("ERASURE_MATCH: "); //$NON-NLS-1$
+				break;
+		}
+		node.print(0, result);
+	}
+
+	result.append("\nPossible matches:"); //$NON-NLS-1$
+	Object[] nodes = this.possibleMatchingNodesSet.values;
+	for (int i = 0, l = nodes.length; i < l; i++) {
+		ASTNode node = (ASTNode) nodes[i];
+		if (node == null) continue;
+		result.append("\nPOSSIBLE_MATCH: "); //$NON-NLS-1$
+		node.print(0, result);
+	}
+	return result.toString();
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java
new file mode 100644
index 0000000..ca95c05
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MemberDeclarationVisitor.java
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IAnnotatable;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator.WrappedCoreException;
+
+/**
+ * Specific visitor of field or method declaration which can identify and store
+ * the local and  other elements of one or several matching nodes.
+ * <p>
+ * This visitor can also peek up local or anonymous type declaration and restart
+ * a new {@link MatchLocator} traverse on this type.
+ * </p>
+ */
+class MemberDeclarationVisitor extends ASTVisitor {
+	// Matches information
+	private final MatchLocator locator;
+	private final IJavaElement enclosingElement;
+	private final MatchingNodeSet nodeSet;
+	private final ASTNode[] matchingNodes;
+	private final ASTNode matchingNode;
+
+	// Local type storage
+	HashtableOfIntValues occurrencesCounts = new HashtableOfIntValues(); // key = class name (char[]), value = occurrenceCount (int)
+	int nodesCount = 0;
+
+	// Local and other elements storage
+	private Annotation annotation;
+	private LocalDeclaration localDeclaration;
+	IJavaElement localElement;
+	IJavaElement[] localElements, otherElements;
+	IJavaElement[][] allOtherElements;
+	int ptr = -1;
+	int[] ptrs;
+
+public MemberDeclarationVisitor(IJavaElement element, ASTNode[] nodes, MatchingNodeSet set, MatchLocator locator) {
+	this.enclosingElement = element;
+	this.nodeSet = set;
+	this.locator = locator;
+	if (nodes == null) {
+		this.matchingNode = null;
+		this.matchingNodes = null;
+	} else {
+		this.nodesCount = nodes.length;
+		if (nodes.length == 1) {
+			this.matchingNode = nodes[0];
+			this.matchingNodes = null;
+		} else {
+			this.matchingNode = null;
+			this.matchingNodes = nodes;
+			this.localElements = new IJavaElement[this.nodesCount];
+			this.ptrs = new int[this.nodesCount];
+			this.allOtherElements = new IJavaElement[this.nodesCount][];
+		}
+	}
+}
+public void endVisit(Argument argument, BlockScope scope) {
+    this.localDeclaration = null;
+}
+public void endVisit(LocalDeclaration declaration, BlockScope scope) {
+    this.localDeclaration = null;
+}
+public void endVisit(MarkerAnnotation markerAnnotation, BlockScope unused) {
+	this.annotation = null;
+}
+public void endVisit(NormalAnnotation normalAnnotation, BlockScope unused) {
+	this.annotation = null;
+}
+public void endVisit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) {
+	this.annotation = null;
+}
+IJavaElement getLocalElement(int idx) {
+	if (this.nodesCount == 1) {
+		return this.localElement;
+	}
+	if (this.localElements != null) {
+		return this.localElements[idx];
+	}
+	return null;
+}
+IJavaElement[] getOtherElements(int idx) {
+	if (this.nodesCount == 1) {
+		if (this.otherElements != null) {
+			int length = this.otherElements.length;
+			if (this.ptr < (length-1)) {
+				System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[this.ptr+1], 0, this.ptr+1);
+			}
+		}
+		return this.otherElements;
+	}
+	IJavaElement[] elements = this.allOtherElements == null ? null : this.allOtherElements[idx];
+	if (elements != null) {
+		int length = elements.length;
+		if (this.ptrs[idx] < (length-1)) {
+			System.arraycopy(elements, 0, elements = this.allOtherElements[idx] = new IJavaElement[this.ptrs[idx]+1], 0, this.ptrs[idx]+1);
+		}
+	}
+	return elements;
+}
+private int matchNode(ASTNode reference) {
+	if (this.matchingNode != null) {
+		if (this.matchingNode == reference) return 0;
+	} else {
+	    int length = this.matchingNodes.length;
+		for (int i=0; i<length; i++) {
+			if (this.matchingNodes[i] == reference)  { // == is intentional
+				return i;
+			}
+		}
+	}
+	return -1;
+}
+/*
+ * Store the handle for the reference of the given index (e.g. peek in #matchingNodes
+ * or #matchingNode).
+ * Note that for performance reason, matching node and associated handles are
+ * not stored in array when there's only one reference to identify.
+ */
+private void storeHandle(int idx) {
+	if (this.localDeclaration == null) return;
+	IJavaElement handle = this.locator.createHandle(this.localDeclaration, this.enclosingElement);
+    if (this.nodesCount == 1) {
+    	if (this.localElement == null) {
+    		if (this.annotation == null) {
+		    	this.localElement =  handle;
+    		} else {
+		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
+		    	if (annotHandle == null) {
+			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
+		    	}
+		    	this.localElement = annotHandle == null ? handle : annotHandle;
+    		}
+    	} else {
+	    	if (++this.ptr == 0) {
+	    		this.otherElements = new IJavaElement[10];
+	    	} else {
+	            int length = this.otherElements.length;
+	            if (this.ptr == length) {
+	            	System.arraycopy(this.otherElements, 0, this.otherElements = new IJavaElement[length+10], 0, length);
+	            }
+            }
+    		if (this.annotation == null) {
+		    	this.otherElements[this.ptr] = handle;
+    		} else {
+		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
+		    	if (annotHandle == null) {
+			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
+		    	}
+		    	this.otherElements[this.ptr] = annotHandle == null ? handle : annotHandle;
+    		}
+    	}
+    } else {
+    	if (this.localElements[idx] == null) {
+	    	if (this.annotation == null) {
+		    	this.localElements[idx] =  handle;
+    		} else {
+		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
+		    	if (annotHandle == null) {
+			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
+		    	}
+		    	this.localElements[idx] = annotHandle == null ? handle : annotHandle;
+    		}
+			this.ptrs[idx] = -1;
+	    } else {
+	        int oPtr = ++this.ptrs[idx];
+	    	if (oPtr== 0) {
+    			this.allOtherElements[idx] = new IJavaElement[10];
+    		} else {
+            	int length = this.allOtherElements[idx].length;
+	            if (oPtr == length) {
+	            	System.arraycopy(this.allOtherElements[idx], 0, this.allOtherElements[idx] = new IJavaElement[length+10], 0, length);
+        	    }
+	        }
+	    	if (this.annotation == null) {
+	 		   	this.allOtherElements[idx][oPtr] = handle;
+    		} else {
+		    	IJavaElement annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) handle);
+		    	if (annotHandle == null) {
+			    	annotHandle = this.locator.createHandle(this.annotation, (IAnnotatable) this.enclosingElement);
+		    	}
+	 		   	this.allOtherElements[idx][oPtr] = annotHandle == null ? handle : annotHandle;
+    		}
+    	}
+    }
+}
+public boolean visit(Argument argument, BlockScope scope) {
+    this.localDeclaration = argument;
+    return true;
+}
+public boolean visit(LocalDeclaration declaration, BlockScope scope) {
+    this.localDeclaration = declaration;
+    return true;
+}
+public boolean visit(MarkerAnnotation markerAnnotation, BlockScope unused) {
+	this.annotation = markerAnnotation;
+	return true;
+}
+public boolean visit(NormalAnnotation normalAnnotation, BlockScope unused) {
+	this.annotation = normalAnnotation;
+	return true;
+}
+public boolean visit(QualifiedNameReference nameReference, BlockScope unused) {
+	if (this.nodesCount > 0){
+		int idx = matchNode(nameReference);
+		if (idx >= 0) {
+			storeHandle(idx);
+		}
+	}
+	return false;
+}
+public boolean visit(QualifiedTypeReference typeReference, BlockScope unused) {
+	if (this.nodesCount > 0){
+		int idx = matchNode(typeReference);
+		if (idx >= 0) {
+			storeHandle(idx);
+		}
+	}
+	return false;
+}
+public boolean visit(SingleMemberAnnotation singleMemberAnnotation, BlockScope unused) {
+	this.annotation = singleMemberAnnotation;
+	return true;
+}
+public boolean visit(SingleNameReference nameReference, BlockScope unused) {
+	if (this.nodesCount > 0){
+		int idx = matchNode(nameReference);
+		if (idx >= 0) {
+			storeHandle(idx);
+		}
+	}
+	return false;
+}
+public boolean visit(SingleTypeReference typeReference, BlockScope unused) {
+	if (this.nodesCount > 0){
+		int idx = matchNode(typeReference);
+		if (idx >= 0) {
+			storeHandle(idx);
+		}
+	}
+	return false;
+}
+public boolean visit(TypeDeclaration typeDeclaration, BlockScope unused) {
+	try {
+		char[] simpleName;
+		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+			simpleName = CharOperation.NO_CHAR;
+		} else {
+			simpleName = typeDeclaration.name;
+		}
+		int occurrenceCount = this.occurrencesCounts.get(simpleName);
+		if (occurrenceCount == HashtableOfIntValues.NO_VALUE) {
+			occurrenceCount = 1;
+		} else {
+			occurrenceCount = occurrenceCount + 1;
+		}
+		this.occurrencesCounts.put(simpleName, occurrenceCount);
+		if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
+			this.locator.reportMatching(typeDeclaration, this.enclosingElement, -1, this.nodeSet, occurrenceCount);
+		} else {
+			Integer level = (Integer) this.nodeSet.matchingNodes.removeKey(typeDeclaration);
+			this.locator.reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, this.nodeSet, occurrenceCount);
+		}
+		return false; // don't visit members as this was done during reportMatching(...)
+	} catch (CoreException e) {
+		throw new WrappedCoreException(e);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
new file mode 100644
index 0000000..cd7cfda
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
@@ -0,0 +1,845 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Samrat Dhillon samrat.dhillon@gmail.com - Search for method references is
+ *               returning methods as overriden even if the superclass's method is 
+ *               only package-visible - https://bugs.eclipse.org/357547
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+
+public class MethodLocator extends PatternLocator {
+
+protected MethodPattern pattern;
+protected boolean isDeclarationOfReferencedMethodsPattern;
+
+//extra reference info
+public char[][][] allSuperDeclaringTypeNames;
+
+// This is set only if focus is null. In these cases
+// it will be hard to determine if the super class is of the same package
+// at a latter point. Hence, this array is created with all the super class 
+// names of the same package name as of the matching class name.
+// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=357547
+private char[][][] samePkgSuperDeclaringTypeNames;
+
+private MatchLocator matchLocator;
+//method declarations which parameters verification fail
+private HashMap methodDeclarationsWithInvalidParam = new HashMap();
+
+
+public MethodLocator(MethodPattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+	this.isDeclarationOfReferencedMethodsPattern = this.pattern instanceof DeclarationOfReferencedMethodsPattern;
+}
+/*
+ * Clear caches
+ */
+protected void clear() {
+	this.methodDeclarationsWithInvalidParam = new HashMap();
+}
+protected int fineGrain() {
+	return this.pattern.fineGrain;
+}
+
+private ReferenceBinding getMatchingSuper(ReferenceBinding binding) {
+	if (binding == null) return null;
+	ReferenceBinding superBinding = binding.superclass();
+	int level = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, superBinding);
+	if (level != IMPOSSIBLE_MATCH) return superBinding;
+	// matches superclass
+	if (!binding.isInterface() && !CharOperation.equals(binding.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
+		superBinding = getMatchingSuper(superBinding);
+		if (superBinding != null) return superBinding;
+	}
+	// matches interfaces
+	ReferenceBinding[] interfaces = binding.superInterfaces();
+	if (interfaces == null) return null;
+	for (int i = 0; i < interfaces.length; i++) {
+		level = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, interfaces[i]);
+		if (level != IMPOSSIBLE_MATCH) return interfaces[i];
+		superBinding = getMatchingSuper(interfaces[i]);
+		if (superBinding != null) return superBinding;
+	}
+	return null;
+}
+
+private MethodBinding getMethodBinding(ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes) {
+	MethodBinding[] methods = type.getMethods(methodName);
+	MethodBinding method = null;
+	methodsLoop: for (int i=0, length=methods.length; i<length; i++) {
+		method = methods[i];
+		TypeBinding[] parameters = method.parameters;
+		if (argumentTypes.length == parameters.length) {
+			for (int j=0,l=parameters.length; j<l; j++) {
+				if (parameters[j].erasure() != argumentTypes[j].erasure()) {
+					continue methodsLoop;
+				}
+			}
+			return method;
+		}
+	}
+	return null;
+}
+
+public void initializePolymorphicSearch(MatchLocator locator) {
+	long start = 0;
+	if (BasicSearchEngine.VERBOSE) {
+		start = System.currentTimeMillis();
+	}
+	try {
+		SuperTypeNamesCollector namesCollector = 
+			new SuperTypeNamesCollector(
+				this.pattern,
+				this.pattern.declaringSimpleName,
+				this.pattern.declaringQualification,
+				locator,
+				this.pattern.declaringType,
+				locator.progressMonitor);
+		this.allSuperDeclaringTypeNames = namesCollector.collect();
+		this.samePkgSuperDeclaringTypeNames = namesCollector.getSamePackageSuperTypeNames();
+		this.matchLocator = locator;	
+	} catch (JavaModelException e) {
+		// inaccurate matches will be found
+	}
+	if (BasicSearchEngine.VERBOSE) {
+		System.out.println("Time to initialize polymorphic search: "+(System.currentTimeMillis()-start)); //$NON-NLS-1$
+	}
+}
+/*
+ * Return whether a type name is in pattern all super declaring types names.
+ */
+private boolean isTypeInSuperDeclaringTypeNames(char[][] typeName) {
+	if (this.allSuperDeclaringTypeNames == null) return false;
+	int length = this.allSuperDeclaringTypeNames.length;
+	for (int i= 0; i<length; i++) {
+		if (CharOperation.equals(this.allSuperDeclaringTypeNames[i], typeName)) {
+			return true;
+		}
+	}
+	return false;
+}
+/**
+ * Returns whether the code gen will use an invoke virtual for
+ * this message send or not.
+ */
+protected boolean isVirtualInvoke(MethodBinding method, MessageSend messageSend) {
+		return !method.isStatic() && !method.isPrivate() && !messageSend.isSuperAccess()
+			&& !(method.isDefault() && this.pattern.focus != null 
+			&& !CharOperation.equals(this.pattern.declaringPackageName, method.declaringClass.qualifiedPackageName()));
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) {
+	int declarationsLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences) {
+		if (node instanceof ImportReference) {
+			// With static import, we can have static method reference in import reference
+			ImportReference importRef = (ImportReference) node;
+			int length = importRef.tokens.length-1;
+			if (importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0) && matchesName(this.pattern.selector, importRef.tokens[length])) {
+				char[][] compoundName = new char[length][];
+				System.arraycopy(importRef.tokens, 0, compoundName, 0, length);
+				char[] declaringType = CharOperation.concat(this.pattern.declaringQualification, this.pattern.declaringSimpleName, '.');
+				if (matchesName(declaringType, CharOperation.concatWith(compoundName, '.'))) {
+					declarationsLevel = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				}
+			}
+		}
+	}
+	return nodeSet.addMatch(node, declarationsLevel);
+}
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findDeclarations) return IMPOSSIBLE_MATCH;
+
+	// Verify method name
+	if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH;
+
+	// Verify parameters types
+	boolean resolve = this.pattern.mustResolve;
+	if (this.pattern.parameterSimpleNames != null) {
+		int length = this.pattern.parameterSimpleNames.length;
+		ASTNode[] args = node.arguments;
+		int argsLength = args == null ? 0 : args.length;
+		if (length != argsLength) return IMPOSSIBLE_MATCH;
+		for (int i = 0; i < argsLength; i++) {
+			if (args != null && !matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) {
+				// Do not return as impossible when source level is at least 1.5
+				if (this.mayBeGeneric) {
+					if (!this.pattern.mustResolve) {
+						// Set resolution flag on node set in case of types was inferred in parameterized types from generic ones...
+					 	// (see  bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
+						nodeSet.mustResolve = true;
+						resolve = true;
+					}
+					this.methodDeclarationsWithInvalidParam.put(node, null);
+				} else {
+					return IMPOSSIBLE_MATCH;
+				}
+			}
+		}
+	}
+
+	// Verify type arguments (do not reject if pattern has no argument as it can be an erasure match)
+	if (this.pattern.hasMethodArguments()) {
+		if (node.typeParameters == null || node.typeParameters.length != this.pattern.methodArguments.length) return IMPOSSIBLE_MATCH;
+	}
+
+	// Method declaration may match pattern
+	return nodeSet.addMatch(node, resolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+
+	if (!matchesName(this.pattern.selector, node.name)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+public int match(MessageSend node, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+
+	if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH;
+	if (this.pattern.parameterSimpleNames != null && (!this.pattern.varargs || ((node.bits & ASTNode.InsideJavadoc) != 0))) {
+		int length = this.pattern.parameterSimpleNames.length;
+		ASTNode[] args = node.arguments;
+		int argsLength = args == null ? 0 : args.length;
+		if (length != argsLength) return IMPOSSIBLE_MATCH;
+	}
+
+	return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+//public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+	MemberValuePair[] pairs = node.memberValuePairs();
+	if (pairs == null || pairs.length == 0) return IMPOSSIBLE_MATCH;
+
+	int length = pairs.length;
+	MemberValuePair pair = null;
+	for (int i=0; i<length; i++) {
+		pair = node.memberValuePairs()[i];
+		if (matchesName(this.pattern.selector, pair.name)) {
+			ASTNode possibleNode = (node instanceof SingleMemberAnnotation) ? (ASTNode) node : pair;
+			return nodeSet.addMatch(possibleNode, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
+
+protected int matchContainer() {
+	if (this.pattern.findReferences) {
+		// need to look almost everywhere to find in javadocs and static import
+		return ALL_CONTAINER;
+	}
+	return CLASS_CONTAINER;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ * Accept to report match of static field on static import
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	if (importRef.isStatic() && binding instanceof MethodBinding) {
+		super.matchLevelAndReportImportRef(importRef, binding, locator);
+	}
+}
+protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
+	if (!matchesName(this.pattern.selector, method.selector)) return IMPOSSIBLE_MATCH;
+
+	int level = ACCURATE_MATCH;
+	// look at return type only if declaring type is not specified
+	if (this.pattern.declaringSimpleName == null) {
+		// TODO (frederic) use this call to refine accuracy on return type
+		// int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, this.pattern.returnTypeArguments, 0, method.returnType);
+		int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, method.returnType);
+		if (level > newLevel) {
+			if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+			level = newLevel; // can only be downgraded
+		}
+	}
+
+	// parameter types
+	int parameterCount = this.pattern.parameterSimpleNames == null ? -1 : this.pattern.parameterSimpleNames.length;
+	if (parameterCount > -1) {
+		// global verification
+		if (method.parameters == null) return INACCURATE_MATCH;
+		if (parameterCount != method.parameters.length) return IMPOSSIBLE_MATCH;
+		if (!method.isValidBinding() && ((ProblemMethodBinding)method).problemId() == ProblemReasons.Ambiguous) {
+			// return inaccurate match for ambiguous call (bug 80890)
+			return INACCURATE_MATCH;
+		}
+		boolean foundTypeVariable = false;
+		// verify each parameter
+		for (int i = 0; i < parameterCount; i++) {
+			TypeBinding argType = method.parameters[i];
+			int newLevel = IMPOSSIBLE_MATCH;
+			if (argType.isMemberType()) {
+				// only compare source name for member type (bug 41018)
+				newLevel = CharOperation.match(this.pattern.parameterSimpleNames[i], argType.sourceName(), this.isCaseSensitive)
+					? ACCURATE_MATCH
+					: IMPOSSIBLE_MATCH;
+			} else {
+				// TODO (frederic) use this call to refine accuracy on parameter types
+//				 newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
+				newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], argType);
+			}
+			if (level > newLevel) {
+				if (newLevel == IMPOSSIBLE_MATCH) {
+					if (skipImpossibleArg) {
+						// Do not consider match as impossible while finding declarations and source level >= 1.5
+					 	// (see  bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
+						newLevel = level;
+					} else if (argType.isTypeVariable()) {
+						newLevel = level;
+						foundTypeVariable = true;
+					} else {
+						return IMPOSSIBLE_MATCH;
+					}
+				}
+				level = newLevel; // can only be downgraded
+			}
+		}
+		if (foundTypeVariable) {
+			if (!method.isStatic() && !method.isPrivate()) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=123836, No point in textually comparing type variables, captures etc with concrete types. 
+				MethodBinding focusMethodBinding = this.matchLocator.getMethodBinding(this.pattern);
+				if (focusMethodBinding != null) {
+					if (matchOverriddenMethod(focusMethodBinding.declaringClass, focusMethodBinding, method)) {
+						return ACCURATE_MATCH;
+					}
+				}
+			} 
+			return IMPOSSIBLE_MATCH;
+		}
+	}
+
+	return level;
+}
+// This works for only methods of parameterized types.
+private boolean matchOverriddenMethod(ReferenceBinding type, MethodBinding method, MethodBinding matchMethod) {
+	if (type == null || this.pattern.selector == null) return false;
+
+	// matches superclass
+	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
+		ReferenceBinding superClass = type.superclass();
+		if (superClass.isParameterizedType()) {
+			MethodBinding[] methods = superClass.getMethods(this.pattern.selector);
+			int length = methods.length;
+			for (int i = 0; i<length; i++) {
+				if (methods[i].areParametersEqual(method)) {
+					if (matchMethod == null) {
+						if (methodParametersEqualsPattern(methods[i].original())) return true;
+					} else {
+						if (methods[i].original().areParametersEqual(matchMethod)) return true;
+					}
+				}
+			}
+		}
+		if (matchOverriddenMethod(superClass, method, matchMethod)) {
+			return true;
+		}
+	}
+
+	// matches interfaces
+	ReferenceBinding[] interfaces = type.superInterfaces();
+	if (interfaces == null) return false;
+	int iLength = interfaces.length;
+	for (int i = 0; i<iLength; i++) {
+		if (interfaces[i].isParameterizedType()) {
+			MethodBinding[] methods = interfaces[i].getMethods(this.pattern.selector);
+			int length = methods.length;
+			for (int j = 0; j<length; j++) {
+				if (methods[j].areParametersEqual(method)) {
+					if (matchMethod == null) {
+						if (methodParametersEqualsPattern(methods[j].original())) return true;
+					} else {
+						if (methods[j].original().areParametersEqual(matchMethod)) return true;
+					}
+				}
+			}
+		}
+		if (matchOverriddenMethod(interfaces[i], method, matchMethod)) {
+			return true;
+		}
+	}
+	return false;
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+/**
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	MethodBinding methodBinding = (reference instanceof MessageSend) ? ((MessageSend)reference).binding: ((elementBinding instanceof MethodBinding) ? (MethodBinding) elementBinding : null);
+	if (this.isDeclarationOfReferencedMethodsPattern) {
+		if (methodBinding == null) return;
+		// need exact match to be able to open on type ref
+		if (accuracy != SearchMatch.A_ACCURATE) return;
+
+		// element that references the method must be included in the enclosing element
+		DeclarationOfReferencedMethodsPattern declPattern = (DeclarationOfReferencedMethodsPattern) this.pattern;
+		while (element != null && !declPattern.enclosingElement.equals(element))
+			element = element.getParent();
+		if (element != null) {
+			reportDeclaration(methodBinding, locator, declPattern.knownMethods);
+		}
+	} else {
+		MethodReferenceMatch methodReferenceMatch = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, false /*not constructor*/, false/*not synthetic*/, reference);
+		methodReferenceMatch.setLocalElement(localElement);
+		this.match = methodReferenceMatch;
+		if (this.pattern.findReferences && reference instanceof MessageSend) {
+			IJavaElement focus = this.pattern.focus;
+			// verify closest match if pattern was bound
+			// (see bug 70827)
+			if (focus != null && focus.getElementType() == IJavaElement.METHOD) {
+				if (methodBinding != null && methodBinding.declaringClass != null) {
+					boolean isPrivate = Flags.isPrivate(((IMethod) focus).getFlags());
+					if (isPrivate && !CharOperation.equals(methodBinding.declaringClass.sourceName, focus.getParent().getElementName().toCharArray())) {
+						return; // finally the match was not possible
+					}
+				}
+			}
+			matchReportReference((MessageSend)reference, locator, accuracy, ((MessageSend)reference).binding);
+		} else {
+			if (reference instanceof SingleMemberAnnotation) {
+				reference = ((SingleMemberAnnotation)reference).memberValuePairs()[0];
+				this.match.setImplicit(true);
+			}
+			int offset = reference.sourceStart;
+			int length =  reference.sourceEnd - offset + 1;
+			this.match.setOffset(offset);
+			this.match.setLength(length);
+			locator.report(this.match);
+		}
+	}
+}
+void matchReportReference(MessageSend messageSend, MatchLocator locator, int accuracy, MethodBinding methodBinding) throws CoreException {
+
+	// Look if there's a need to special report for parameterized type
+	boolean isParameterized = false;
+	if (methodBinding instanceof ParameterizedGenericMethodBinding) { // parameterized generic method
+		isParameterized = true;
+
+		// Update match regarding method type arguments
+		ParameterizedGenericMethodBinding parameterizedMethodBinding = (ParameterizedGenericMethodBinding) methodBinding;
+		this.match.setRaw(parameterizedMethodBinding.isRaw);
+		TypeBinding[] typeArguments = /*parameterizedMethodBinding.isRaw ? null :*/ parameterizedMethodBinding.typeArguments;
+		updateMatch(typeArguments, locator, this.pattern.methodArguments, this.pattern.hasMethodParameters());
+
+		// Update match regarding declaring class type arguments
+		if (methodBinding.declaringClass.isParameterizedType() || methodBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)methodBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasMethodArguments() || parameterizedBinding.isParameterizedWithOwnVariables()) {
+				// special case for pattern which defines method arguments but not its declaring type
+				// in this case, we do not refine accuracy using declaring type arguments...!
+			} else {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding method parameters
+		// TODO ? (frederic)
+
+		// Update match regarding method return type
+		// TODO ? (frederic)
+
+		// Special case for errors
+		if (this.match.getRule() != 0 && messageSend.resolvedType == null) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+	} else if (methodBinding instanceof ParameterizedMethodBinding) {
+		isParameterized = true;
+		if (methodBinding.declaringClass.isParameterizedType() || methodBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)methodBinding.declaringClass;
+			if (!parameterizedBinding.isParameterizedWithOwnVariables()) {
+				if ((accuracy & (SUB_INVOCATION_FLAVOR | OVERRIDDEN_METHOD_FLAVOR)) != 0) {
+					// type parameters need to be compared with the class that is really being searched
+					// https://bugs.eclipse.org/375971
+					ReferenceBinding refBinding = getMatchingSuper(((ReferenceBinding)messageSend.actualReceiverType));
+					if (refBinding instanceof ParameterizedTypeBinding) {
+						parameterizedBinding = ((ParameterizedTypeBinding)refBinding);
+					}
+				}
+				if ((accuracy & SUPER_INVOCATION_FLAVOR) == 0) {
+					// not able to get the type parameters if the match is super
+					updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+				}
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding method parameters
+		// TODO ? (frederic)
+
+		// Update match regarding method return type
+		// TODO ? (frederic)
+
+		// Special case for errors
+		if (this.match.getRule() != 0 && messageSend.resolvedType == null) {
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+	} else if (this.pattern.hasMethodArguments()) { // binding has no type params, compatible erasure if pattern does
+		this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+	}
+
+	// See whether it is necessary to report or not
+	if (this.match.getRule() == 0) return; // impossible match
+	boolean report = (this.isErasureMatch && this.match.isErasure()) || (this.isEquivalentMatch && this.match.isEquivalent()) || this.match.isExact();
+	if (!report) return;
+
+	// Report match
+	int offset = (int) (messageSend.nameSourcePosition >>> 32);
+	this.match.setOffset(offset);
+	this.match.setLength(messageSend.sourceEnd - offset + 1);
+	 if (isParameterized && this.pattern.hasMethodArguments())  {
+		locator.reportAccurateParameterizedMethodReference(this.match, messageSend, messageSend.typeArguments);
+	} else {
+		locator.report(this.match);
+	}
+}
+/*
+ * Return whether method parameters are equals to pattern ones.
+ */
+private boolean methodParametersEqualsPattern(MethodBinding method) {
+	TypeBinding[] methodParameters = method.parameters;
+
+	int length = methodParameters.length;
+	if (length != this.pattern.parameterSimpleNames.length) return false;
+
+	for (int i = 0; i < length; i++) {
+		char[] paramQualifiedName = qualifiedPattern(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i]);
+		if (!CharOperation.match(paramQualifiedName, methodParameters[i].readableName(), this.isCaseSensitive)) {
+			return false;
+		}
+	}
+	return true;
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
+	if (elementBinding != null) {
+		MethodBinding methodBinding = (MethodBinding) elementBinding;
+		// If method parameters verification was not valid, then try to see if method arguments can match a method in hierarchy
+		if (this.methodDeclarationsWithInvalidParam.containsKey(reference)) {
+			// First see if this reference has already been resolved => report match if validated
+			Boolean report = (Boolean) this.methodDeclarationsWithInvalidParam.get(reference);
+			if (report != null) {
+				if (report.booleanValue()) {
+					return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+				}
+				return null;
+			}
+			if (matchOverriddenMethod(methodBinding.declaringClass, methodBinding, null)) {
+				this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
+				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+			}
+			if (isTypeInSuperDeclaringTypeNames(methodBinding.declaringClass.compoundName)) {
+				MethodBinding patternBinding = locator.getMethodBinding(this.pattern);
+				if (patternBinding != null) {
+					if (!matchOverriddenMethod(patternBinding.declaringClass, patternBinding, methodBinding)) {
+						this.methodDeclarationsWithInvalidParam.put(reference, Boolean.FALSE);
+						return null;
+					}
+				}
+				this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
+				return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+			}
+			this.methodDeclarationsWithInvalidParam.put(reference, Boolean.FALSE);
+			return null;
+		}
+	}
+	return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+}
+protected int referenceType() {
+	return IJavaElement.METHOD;
+}
+protected void reportDeclaration(MethodBinding methodBinding, MatchLocator locator, SimpleSet knownMethods) throws CoreException {
+	ReferenceBinding declaringClass = methodBinding.declaringClass;
+	IType type = locator.lookupType(declaringClass);
+	if (type == null) return; // case of a secondary type
+
+	// Report match for binary
+	if (type.isBinary()) {
+		IMethod method = null;
+		TypeBinding[] parameters = methodBinding.original().parameters;
+		int parameterLength = parameters.length;
+		char[][] parameterTypes = new char[parameterLength][];
+		for (int i = 0; i<parameterLength; i++) {
+			char[] typeName = parameters[i].qualifiedSourceName();
+			for (int j=0, dim=parameters[i].dimensions(); j<dim; j++) {
+				typeName = CharOperation.concat(typeName, new char[] {'[', ']'});
+			}
+			parameterTypes[i] = typeName;
+		}
+		method = locator.createBinaryMethodHandle(type, methodBinding.selector, parameterTypes);
+		if (method == null || knownMethods.addIfNotIncluded(method) == null) return;
+	
+		IResource resource = type.getResource();
+		if (resource == null)
+			resource = type.getJavaProject().getProject();
+		IBinaryType info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile)type.getClassFile(), resource);
+		locator.reportBinaryMemberDeclaration(resource, method, methodBinding, info, SearchMatch.A_ACCURATE);
+		return;
+	}
+
+	// When source is available, report match if method is found in the declaring type
+	IResource resource = type.getResource();
+	if (declaringClass instanceof ParameterizedTypeBinding)
+		declaringClass = ((ParameterizedTypeBinding) declaringClass).genericType();
+	ClassScope scope = ((SourceTypeBinding) declaringClass).scope;
+	if (scope != null) {
+		TypeDeclaration typeDecl = scope.referenceContext;
+		AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(methodBinding.original());
+		if (methodDecl != null) {
+			// Create method handle from method declaration
+			String methodName = new String(methodBinding.selector);
+			Argument[] arguments = methodDecl.arguments;
+			int length = arguments == null ? 0 : arguments.length;
+			String[] parameterTypes = new String[length];
+			for (int i = 0; i  < length; i++) {
+				char[][] typeName = arguments[i].type.getParameterizedTypeName();
+				parameterTypes[i] = Signature.createTypeSignature(CharOperation.concatWith(typeName, '.'), false);
+			}
+			IMethod method = type.getMethod(methodName, parameterTypes);
+			if (method == null || knownMethods.addIfNotIncluded(method) == null) return;
+
+			// Create and report corresponding match
+			int offset = methodDecl.sourceStart;
+			this.match = new MethodDeclarationMatch(method, SearchMatch.A_ACCURATE, offset, methodDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+			locator.report(this.match);
+		}
+	}
+}
+public int resolveLevel(ASTNode possibleMatchingNode) {
+	if (this.pattern.findReferences) {
+		if (possibleMatchingNode instanceof MessageSend) {
+			return resolveLevel((MessageSend) possibleMatchingNode);
+		}
+		if (possibleMatchingNode instanceof SingleMemberAnnotation) {
+			SingleMemberAnnotation annotation = (SingleMemberAnnotation) possibleMatchingNode;
+			return resolveLevel(annotation.memberValuePairs()[0].binding);
+		}
+		if (possibleMatchingNode instanceof MemberValuePair) {
+			MemberValuePair memberValuePair = (MemberValuePair) possibleMatchingNode;
+			return resolveLevel(memberValuePair.binding);
+		}
+	}
+	if (this.pattern.findDeclarations) {
+		if (possibleMatchingNode instanceof MethodDeclaration) {
+			return resolveLevel(((MethodDeclaration) possibleMatchingNode).binding);
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof MethodBinding)) return IMPOSSIBLE_MATCH;
+
+	MethodBinding method = (MethodBinding) binding;
+	boolean skipVerif = this.pattern.findDeclarations && this.mayBeGeneric;
+	int methodLevel = matchMethod(method, skipVerif);
+	if (methodLevel == IMPOSSIBLE_MATCH) {
+		if (method != method.original()) methodLevel = matchMethod(method.original(), skipVerif);
+		if (methodLevel == IMPOSSIBLE_MATCH) {
+			return IMPOSSIBLE_MATCH;
+		} else {
+			method = method.original();
+		}
+	}
+
+	// declaring type
+	if (this.pattern.declaringSimpleName == null && this.pattern.declaringQualification == null) return methodLevel; // since any declaring class will do
+
+	boolean subType = !method.isStatic() && !method.isPrivate();
+	if (subType && this.pattern.declaringQualification != null && method.declaringClass != null && method.declaringClass.fPackage != null) {
+		subType = CharOperation.compareWith(this.pattern.declaringQualification, method.declaringClass.fPackage.shortReadableName()) == 0;
+	}
+	int declaringLevel = subType
+		? resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass, method.selector, null, method.declaringClass.qualifiedPackageName(), method.isDefault())
+		: resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass);
+	return (methodLevel & MATCH_LEVEL_MASK) > (declaringLevel & MATCH_LEVEL_MASK) ? declaringLevel : methodLevel; // return the weaker match
+}
+protected int resolveLevel(MessageSend messageSend) {
+	MethodBinding method = messageSend.binding;
+	if (method == null) {
+		return INACCURATE_MATCH;
+	}
+	if (messageSend.resolvedType == null) {
+		// Closest match may have different argument numbers when ProblemReason is NotFound
+		// see MessageSend#resolveType(BlockScope)
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=97322
+		int argLength = messageSend.arguments == null ? 0 : messageSend.arguments.length;
+		if (this.pattern.parameterSimpleNames == null || argLength == this.pattern.parameterSimpleNames.length) {
+			return INACCURATE_MATCH;
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	int methodLevel = matchMethod(method, false);
+	if (methodLevel == IMPOSSIBLE_MATCH) {
+		if (method != method.original()) methodLevel = matchMethod(method.original(), false);
+		if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+		method = method.original();
+	}
+
+	// receiver type
+	if (this.pattern.declaringSimpleName == null && this.pattern.declaringQualification == null) return methodLevel; // since any declaring class will do
+
+	int declaringLevel;
+	if (isVirtualInvoke(method, messageSend) && (messageSend.actualReceiverType instanceof ReferenceBinding)) {
+		ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType;
+		declaringLevel = resolveLevelAsSubtype(this.pattern.declaringSimpleName, this.pattern.declaringQualification, methodReceiverType, method.selector, method.parameters, methodReceiverType.qualifiedPackageName(), method.isDefault());
+		if (declaringLevel == IMPOSSIBLE_MATCH) {
+			if (method.declaringClass == null || this.allSuperDeclaringTypeNames == null) {
+				declaringLevel = INACCURATE_MATCH;
+			} else {
+				char[][][] superTypeNames = (method.isDefault() && this.pattern.focus == null) ? this.samePkgSuperDeclaringTypeNames: this.allSuperDeclaringTypeNames;
+				if (superTypeNames != null && resolveLevelAsSuperInvocation(methodReceiverType, method.parameters, superTypeNames, true)) {
+						declaringLevel = methodLevel // since this is an ACCURATE_MATCH so return the possibly weaker match
+							| SUPER_INVOCATION_FLAVOR; // this is an overridden method => add flavor to returned level
+				}
+			}
+		}
+		if ((declaringLevel & FLAVORS_MASK) != 0) {
+			// level got some flavors => return it
+			return declaringLevel;
+		}
+	} else {
+		declaringLevel = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass);
+	}
+	return (methodLevel & MATCH_LEVEL_MASK) > (declaringLevel & MATCH_LEVEL_MASK) ? declaringLevel : methodLevel; // return the weaker match
+}
+
+/**
+ * Returns whether the given reference type binding matches or is a subtype of a type
+ * that matches the given qualified pattern.
+ * Returns ACCURATE_MATCH if it does.
+ * Returns INACCURATE_MATCH if resolve fails
+ * Returns IMPOSSIBLE_MATCH if it doesn't.
+ */
+protected int resolveLevelAsSubtype(char[] simplePattern, char[] qualifiedPattern, ReferenceBinding type, char[] methodName, TypeBinding[] argumentTypes, char[] packageName, boolean isDefault) {
+	if (type == null) return INACCURATE_MATCH;
+
+	int level = resolveLevelForType(simplePattern, qualifiedPattern, type);
+	if (level != IMPOSSIBLE_MATCH) {
+		if (isDefault && !CharOperation.equals(packageName, type.qualifiedPackageName())) {
+			return IMPOSSIBLE_MATCH;
+		}
+		MethodBinding method = argumentTypes == null ? null : getMethodBinding(type, methodName, argumentTypes);
+		if (((method != null && !method.isAbstract()) || !type.isAbstract()) && !type.isInterface()) { // if concrete, then method is overridden
+			level |= OVERRIDDEN_METHOD_FLAVOR;
+		}
+		return level;
+	}
+
+	// matches superclass
+	if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
+		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, type.superclass(), methodName, argumentTypes, packageName, isDefault);
+		if (level != IMPOSSIBLE_MATCH) {
+			if (argumentTypes != null) {
+				// need to verify if method may be overridden
+				MethodBinding method = getMethodBinding(type, methodName, argumentTypes);
+				if (method != null) { // one method match in hierarchy
+					if ((level & OVERRIDDEN_METHOD_FLAVOR) != 0) {
+						// this method is already overridden on a super class, current match is impossible
+						return IMPOSSIBLE_MATCH;
+					}
+					if (!method.isAbstract() && !type.isInterface()) {
+						// store the fact that the method is overridden
+						level |= OVERRIDDEN_METHOD_FLAVOR;
+					}
+				}
+			}
+			return level | SUB_INVOCATION_FLAVOR; // add flavor to returned level
+		}
+	}
+
+	// matches interfaces
+	ReferenceBinding[] interfaces = type.superInterfaces();
+	if (interfaces == null) return INACCURATE_MATCH;
+	for (int i = 0; i < interfaces.length; i++) {
+		level = resolveLevelAsSubtype(simplePattern, qualifiedPattern, interfaces[i], methodName, null, packageName, isDefault);
+		if (level != IMPOSSIBLE_MATCH) {
+			if (!type.isAbstract() && !type.isInterface()) { // if concrete class, then method is overridden
+				level |= OVERRIDDEN_METHOD_FLAVOR;
+			}
+			return level | SUB_INVOCATION_FLAVOR; // add flavor to returned level
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+
+/*
+ * Return whether the given type binding or one of its possible super interfaces
+ * matches a type in the declaring type names hierarchy.
+ */
+private boolean resolveLevelAsSuperInvocation(ReferenceBinding type, TypeBinding[] argumentTypes, char[][][] superTypeNames, boolean methodAlreadyVerified) {
+	char[][] compoundName = type.compoundName;
+	for (int i = 0, max = superTypeNames.length; i < max; i++) {
+		if (CharOperation.equals(superTypeNames[i], compoundName)) {
+			// need to verify if the type implements the pattern method
+			if (methodAlreadyVerified) return true; // already verified before enter into this method (see resolveLevel(MessageSend))
+			MethodBinding[] methods = type.getMethods(this.pattern.selector);
+			for (int j=0, length=methods.length; j<length; j++) {
+				MethodBinding method = methods[j];
+				TypeBinding[] parameters = method.parameters;
+				if (argumentTypes.length == parameters.length) {
+					boolean found = true;
+					for (int k=0,l=parameters.length; k<l; k++) {
+						if (parameters[k].erasure() != argumentTypes[k].erasure()) {
+							found = false;
+							break;
+						}
+					}
+					if (found) {
+						return true;
+					}
+				}
+			}
+			break;
+		}
+	}
+
+	// If the given type is an interface then a common super interface may be found
+	// in a parallel branch of the super hierarchy, so we need to verify all super interfaces.
+	// If it's a class then there's only one possible branch for the hierarchy and
+	// this branch has been already verified by the test above
+	if (type.isInterface()) {
+		ReferenceBinding[] interfaces = type.superInterfaces();
+		if (interfaces == null) return false;
+		for (int i = 0; i < interfaces.length; i++) {
+			if (resolveLevelAsSuperInvocation(interfaces[i], argumentTypes, superTypeNames, false)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
new file mode 100644
index 0000000..e746a32
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.index.*;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class MethodPattern extends JavaSearchPattern {
+
+protected boolean findDeclarations = true;
+protected boolean findReferences = true;
+
+public char[] selector;
+
+public char[] declaringQualification;
+public char[] declaringSimpleName;
+public char[] declaringPackageName; //set only when focus is not null
+
+public char[] returnQualification;
+public char[] returnSimpleName;
+
+public char[][] parameterQualifications;
+public char[][] parameterSimpleNames;
+public int parameterCount;
+public boolean varargs = false;
+
+// extra reference info
+protected IType declaringType;
+
+// Signatures and arguments for generic search
+char[][] returnTypeSignatures;
+char[][][] parametersTypeSignatures;
+char[][][][] parametersTypeArguments;
+boolean methodParameters = false;
+char[][] methodArguments;
+
+protected static char[][] REF_CATEGORIES = { METHOD_REF };
+protected static char[][] REF_AND_DECL_CATEGORIES = { METHOD_REF, METHOD_DECL };
+protected static char[][] DECL_CATEGORIES = { METHOD_DECL };
+
+public final static int FINE_GRAIN_MASK =
+	IJavaSearchConstants.SUPER_REFERENCE |
+	IJavaSearchConstants.QUALIFIED_REFERENCE |
+	IJavaSearchConstants.THIS_REFERENCE |
+	IJavaSearchConstants.IMPLICIT_THIS_REFERENCE;
+
+/**
+ * Method entries are encoded as selector '/' Arity:
+ * e.g. 'foo/0'
+ */
+public static char[] createIndexKey(char[] selector, int argCount) {
+	char[] countChars = argCount < 10
+		? COUNTS[argCount]
+		: ("/" + String.valueOf(argCount)).toCharArray(); //$NON-NLS-1$
+	return CharOperation.concat(selector, countChars);
+}
+
+MethodPattern(int matchRule) {
+	super(METHOD_PATTERN, matchRule);
+}
+public MethodPattern(
+	char[] selector,
+	char[] declaringQualification,
+	char[] declaringSimpleName,
+	char[] returnQualification,
+	char[] returnSimpleName,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	IType declaringType,
+	int limitTo,
+	int matchRule) {
+
+	this(matchRule);
+
+	this.fineGrain = limitTo & FINE_GRAIN_MASK;
+    if (this.fineGrain == 0) {
+		switch (limitTo & 0xF) {
+			case IJavaSearchConstants.DECLARATIONS :
+				this.findReferences = false;
+				break;
+			case IJavaSearchConstants.REFERENCES :
+				this.findDeclarations = false;
+				break;
+			case IJavaSearchConstants.ALL_OCCURRENCES :
+				break;
+		}
+    } else {
+		this.findDeclarations = false;
+    }
+
+	this.selector = (this.isCaseSensitive || this.isCamelCase) ? selector : CharOperation.toLowerCase(selector);
+	this.declaringQualification = this.isCaseSensitive ? declaringQualification : CharOperation.toLowerCase(declaringQualification);
+	this.declaringSimpleName = this.isCaseSensitive ? declaringSimpleName : CharOperation.toLowerCase(declaringSimpleName);
+	this.returnQualification = this.isCaseSensitive ? returnQualification : CharOperation.toLowerCase(returnQualification);
+	this.returnSimpleName = this.isCaseSensitive ? returnSimpleName : CharOperation.toLowerCase(returnSimpleName);
+	if (parameterSimpleNames != null) {
+		this.parameterCount = parameterSimpleNames.length;
+		this.parameterQualifications = new char[this.parameterCount][];
+		this.parameterSimpleNames = new char[this.parameterCount][];
+		for (int i = 0; i < this.parameterCount; i++) {
+			this.parameterQualifications[i] = this.isCaseSensitive ? parameterQualifications[i] : CharOperation.toLowerCase(parameterQualifications[i]);
+			this.parameterSimpleNames[i] = this.isCaseSensitive ? parameterSimpleNames[i] : CharOperation.toLowerCase(parameterSimpleNames[i]);
+		}
+	} else {
+		this.parameterCount = -1;
+	}
+	this.declaringType = declaringType;
+	if (this.declaringType !=  null) {
+		this.declaringPackageName = this.declaringType.getPackageFragment().getElementName().toCharArray();
+	}
+	this.mustResolve = mustResolve();
+}
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public MethodPattern(
+	char[] selector,
+	char[] declaringQualification,
+	char[] declaringSimpleName,
+	char[] returnQualification,
+	char[] returnSimpleName,
+	String returnSignature,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	IMethod method,
+	int limitTo,
+	int matchRule) {
+
+	this(selector,
+		declaringQualification,
+		declaringSimpleName,
+		returnQualification,
+		returnSimpleName,
+		parameterQualifications,
+		parameterSimpleNames,
+		method.getDeclaringType(),
+		limitTo,
+		matchRule);
+
+	// Set flags
+	try {
+		this.varargs = (method.getFlags() & Flags.AccVarargs) != 0;
+	} catch (JavaModelException e) {
+		// do nothing
+	}
+
+	// Get unique key for parameterized constructors
+	String genericDeclaringTypeSignature = null;
+	if (method.isResolved()) {
+		String key = method.getKey();
+		BindingKey bindingKey = new BindingKey(key);
+		if (bindingKey.isParameterizedType()) {
+			genericDeclaringTypeSignature = Util.getDeclaringTypeSignature(key);
+			// Store type signature and arguments for declaring type
+			if (genericDeclaringTypeSignature != null) {
+					this.typeSignatures = Util.splitTypeLevelsSignature(genericDeclaringTypeSignature);
+					setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+			}
+		}
+	} else {
+		this.methodParameters = true;
+		storeTypeSignaturesAndArguments(this.declaringType);
+	}
+
+	// Store type signatures and arguments for return type
+	if (returnSignature != null) {
+		this.returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			this.parametersTypeSignatures = new char[length][][];
+			this.parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				this.parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				this.parametersTypeArguments[i] = Util.getAllTypeArguments(this.parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	this.methodArguments = extractMethodArguments(method);
+	if (hasMethodArguments())  this.mustResolve = true;
+}
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public MethodPattern(
+	char[] selector,
+	char[] declaringQualification,
+	char[] declaringSimpleName,
+	String declaringSignature,
+	char[] returnQualification,
+	char[] returnSimpleName,
+	String returnSignature,
+	char[][] parameterQualifications,
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	char[][] arguments,
+	int limitTo,
+	int matchRule) {
+
+	this(selector,
+		declaringQualification,
+		declaringSimpleName,
+		returnQualification,
+		returnSimpleName,
+		parameterQualifications,
+		parameterSimpleNames,
+		null,
+		limitTo,
+		matchRule);
+
+	// Store type signature and arguments for declaring type
+	if (declaringSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(declaringSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	}
+
+	// Store type signatures and arguments for return type
+	if (returnSignature != null) {
+		this.returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			this.parametersTypeSignatures = new char[length][][];
+			this.parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				this.parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				this.parametersTypeArguments[i] = Util.getAllTypeArguments(this.parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	this.methodArguments = arguments;
+	if (hasMethodArguments())  this.mustResolve = true;
+}
+public void decodeIndexKey(char[] key) {
+	int last = key.length - 1;
+	this.parameterCount = 0;
+	this.selector = null;
+	int power = 1;
+	for (int i=last; i>=0; i--) {
+		if (key[i] == SEPARATOR) {
+			System.arraycopy(key, 0, this.selector = new char[i], 0, i);
+			break;
+		}
+		if (i == last) {
+			this.parameterCount = key[i] - '0';
+		} else {
+			power *= 10;
+			this.parameterCount += power * (key[i] - '0');
+		}
+	}
+}
+public SearchPattern getBlankPattern() {
+	return new MethodPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	if (this.findReferences)
+		return this.findDeclarations ? REF_AND_DECL_CATEGORIES : REF_CATEGORIES;
+	if (this.findDeclarations)
+		return DECL_CATEGORIES;
+	return CharOperation.NO_CHAR_CHAR;
+}
+boolean hasMethodArguments() {
+	return this.methodArguments != null && this.methodArguments.length > 0;
+}
+boolean hasMethodParameters() {
+	return this.methodParameters;
+}
+public boolean isPolymorphicSearch() {
+	return this.findReferences;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	MethodPattern pattern = (MethodPattern) decodedPattern;
+
+	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+		&& matchesName(this.selector, pattern.selector);
+}
+/**
+ * Returns whether a method declaration or message send must be resolved to
+ * find out if this method pattern matches it.
+ */
+protected boolean mustResolve() {
+	// declaring type
+	// If declaring type is specified - even with simple name - always resolves
+	if (this.declaringSimpleName != null || this.declaringQualification != null) return true;
+
+	// return type
+	// If return type is specified - even with simple name - always resolves
+	if (this.returnSimpleName != null || this.returnQualification != null) return true;
+
+	// parameter types
+	if (this.parameterSimpleNames != null)
+		for (int i = 0, max = this.parameterSimpleNames.length; i < max; i++)
+			if (this.parameterQualifications[i] != null) return true;
+	return false;
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+	char[] key = this.selector; // can be null
+	int matchRule = getMatchRule();
+
+	switch(getMatchMode()) {
+		case R_EXACT_MATCH :
+			if (this.selector != null && this.parameterCount >= 0 && !this.varargs)
+				key = createIndexKey(this.selector, this.parameterCount);
+			else { // do a prefix query with the selector
+				matchRule &= ~R_EXACT_MATCH;
+				matchRule |= R_PREFIX_MATCH;
+			}
+			break;
+		case R_PREFIX_MATCH :
+			// do a prefix query with the selector
+			break;
+		case R_PATTERN_MATCH :
+			if (this.parameterCount >= 0 && !this.varargs)
+				key = createIndexKey(this.selector == null ? ONE_STAR : this.selector, this.parameterCount);
+			else if (this.selector != null && this.selector[this.selector.length - 1] != '*')
+				key = CharOperation.concat(this.selector, ONE_STAR, SEPARATOR);
+			// else do a pattern query with just the selector
+			break;
+		case R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+		case R_CAMELCASE_MATCH:
+		case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			// do a prefix query with the selector
+			break;
+	}
+
+	return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+}
+protected StringBuffer print(StringBuffer output) {
+	if (this.findDeclarations) {
+		output.append(this.findReferences
+			? "MethodCombinedPattern: " //$NON-NLS-1$
+			: "MethodDeclarationPattern: "); //$NON-NLS-1$
+	} else {
+		output.append("MethodReferencePattern: "); //$NON-NLS-1$
+	}
+	if (this.declaringQualification != null)
+		output.append(this.declaringQualification).append('.');
+	if (this.declaringSimpleName != null)
+		output.append(this.declaringSimpleName).append('.');
+	else if (this.declaringQualification != null)
+		output.append("*."); //$NON-NLS-1$
+
+	if (this.selector != null)
+		output.append(this.selector);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append('(');
+	if (this.parameterSimpleNames == null) {
+		output.append("..."); //$NON-NLS-1$
+	} else {
+		for (int i = 0, max = this.parameterSimpleNames.length; i < max; i++) {
+			if (i > 0) output.append(", "); //$NON-NLS-1$
+			if (this.parameterQualifications[i] != null) output.append(this.parameterQualifications[i]).append('.');
+			if (this.parameterSimpleNames[i] == null) output.append('*'); else output.append(this.parameterSimpleNames[i]);
+		}
+	}
+	output.append(')');
+	if (this.returnQualification != null)
+		output.append(" --> ").append(this.returnQualification).append('.'); //$NON-NLS-1$
+	else if (this.returnSimpleName != null)
+		output.append(" --> "); //$NON-NLS-1$
+	if (this.returnSimpleName != null)
+		output.append(this.returnSimpleName);
+	else if (this.returnQualification != null)
+		output.append("*"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
new file mode 100644
index 0000000..93c3c8a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.index.*;
+
+public class MultiTypeDeclarationPattern extends JavaSearchPattern {
+
+public char[][] simpleNames;
+public char[][] qualifications;
+
+// set to CLASS_SUFFIX for only matching classes
+// set to INTERFACE_SUFFIX for only matching interfaces
+// set to ENUM_SUFFIX for only matching enums
+// set to ANNOTATION_TYPE_SUFFIX for only matching annotation types
+// set to TYPE_SUFFIX for matching both classes and interfaces
+public char typeSuffix;
+
+protected static char[][] CATEGORIES = { TYPE_DECL };
+
+public MultiTypeDeclarationPattern(
+	char[][] qualifications,
+	char[][] simpleNames,
+	char typeSuffix,
+	int matchRule) {
+
+	this(matchRule);
+
+	if (this.isCaseSensitive || qualifications == null) {
+		this.qualifications = qualifications;
+	} else {
+		int length = qualifications.length;
+		this.qualifications = new char[length][];
+		for (int i = 0; i < length; i++)
+			this.qualifications[i] = CharOperation.toLowerCase(qualifications[i]);
+	}
+	// null simple names are allowed (should return all names)
+	if (simpleNames != null) {
+		if (this.isCaseSensitive || this.isCamelCase) {
+			this.simpleNames = simpleNames;
+		} else {
+			int length = simpleNames.length;
+			this.simpleNames = new char[length][];
+			for (int i = 0; i < length; i++)
+				this.simpleNames[i] = CharOperation.toLowerCase(simpleNames[i]);
+		}
+	}
+	this.typeSuffix = typeSuffix;
+
+	this.mustResolve = typeSuffix != TYPE_SUFFIX; // only used to report type declarations, not their positions
+}
+MultiTypeDeclarationPattern(int matchRule) {
+	super(TYPE_DECL_PATTERN, matchRule);
+}
+public SearchPattern getBlankPattern() {
+	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	return CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
+
+	// check type suffix
+	if (this.typeSuffix != pattern.typeSuffix && this.typeSuffix != TYPE_SUFFIX) {
+		if (!matchDifferentTypeSuffixes(this.typeSuffix, pattern.typeSuffix)) {
+			return false;
+		}
+	}
+
+	// check qualified name
+	if (this.qualifications != null) {
+		int count = 0;
+		int max = this.qualifications.length;
+		if (max == 0 && pattern.qualification.length > 0) {
+			return false;
+		}
+		if (max > 0) {
+			for (; count < max; count++)
+				if (matchesName(this.qualifications[count], pattern.qualification))
+					break;
+			if (count == max) return false;
+		}
+	}
+
+	// check simple name (null are allowed)
+	if (this.simpleNames == null) return true;
+	int count = 0;
+	int max = this.simpleNames.length;
+	for (; count < max; count++)
+		if (matchesName(this.simpleNames[count], pattern.simpleName))
+			break;
+	return count < max;
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+	if (this.simpleNames == null) {
+		// if no simple names then return all possible ones from index
+		return index.query(getIndexCategories(), null, -1); // match rule is irrelevant when the key is null
+	}
+
+	int count = -1;
+	int numOfNames = this.simpleNames.length;
+	EntryResult[][] allResults = numOfNames > 1 ? new EntryResult[numOfNames][] : null;
+	for (int i = 0; i < numOfNames; i++) {
+		char[] key = this.simpleNames[i];
+		int matchRule = getMatchRule();
+
+		switch(getMatchMode()) {
+			case R_PREFIX_MATCH :
+				// do a prefix query with the simpleName
+				break;
+			case R_EXACT_MATCH :
+				// do a prefix query with the simpleName
+				matchRule &= ~R_EXACT_MATCH;
+				matchRule |= R_PREFIX_MATCH;
+				key = CharOperation.append(key, SEPARATOR);
+				break;
+			case R_PATTERN_MATCH :
+				if (key[key.length - 1] != '*')
+					key = CharOperation.concat(key, ONE_STAR, SEPARATOR);
+				break;
+			case R_REGEXP_MATCH :
+				// TODO (frederic) implement regular expression match
+				break;
+			case R_CAMELCASE_MATCH:
+			case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+				// do a prefix query with the simpleName
+				break;
+		}
+
+		EntryResult[] entries = index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+		if (entries != null) {
+			if (allResults == null) return entries;
+			allResults[++count] = entries;
+		}
+	}
+
+	if (count == -1) return null;
+	int total = 0;
+	for (int i = 0; i <= count; i++)
+		total += allResults[i].length;
+	EntryResult[] allEntries = new EntryResult[total];
+	int next = 0;
+	for (int i = 0; i <= count; i++) {
+		EntryResult[] entries = allResults[i];
+		System.arraycopy(entries, 0, allEntries, next, entries.length);
+		next += entries.length;
+	}
+	return allEntries;
+}
+protected StringBuffer print(StringBuffer output) {
+	switch (this.typeSuffix){
+		case CLASS_SUFFIX :
+			output.append("MultiClassDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case CLASS_AND_INTERFACE_SUFFIX :
+			output.append("MultiClassAndInterfaceDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case CLASS_AND_ENUM_SUFFIX :
+			output.append("MultiClassAndEnumDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case INTERFACE_SUFFIX :
+			output.append("MultiInterfaceDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case INTERFACE_AND_ANNOTATION_SUFFIX :
+			output.append("MultiInterfaceAndAnnotationDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case ENUM_SUFFIX :
+			output.append("MultiEnumDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case ANNOTATION_TYPE_SUFFIX :
+			output.append("MultiAnnotationTypeDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		default :
+			output.append("MultiTypeDeclarationPattern: "); //$NON-NLS-1$
+			break;
+	}
+	if (this.qualifications != null) {
+		output.append("qualifications: <"); //$NON-NLS-1$
+		for (int i = 0; i < this.qualifications.length; i++){
+			output.append(this.qualifications[i]);
+			if (i < this.qualifications.length - 1)
+				output.append(", "); //$NON-NLS-1$
+		}
+		output.append("> "); //$NON-NLS-1$
+	}
+	if (this.simpleNames != null) {
+		output.append("simpleNames: <"); //$NON-NLS-1$
+		for (int i = 0; i < this.simpleNames.length; i++){
+			output.append(this.simpleNames[i]);
+			if (i < this.simpleNames.length - 1)
+				output.append(", "); //$NON-NLS-1$
+		}
+		output.append(">"); //$NON-NLS-1$
+	}
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
new file mode 100644
index 0000000..f435ac7
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class OrLocator extends PatternLocator {
+
+protected PatternLocator[] patternLocators;
+
+public OrLocator(OrPattern pattern) {
+	super(pattern);
+
+	SearchPattern[] patterns = pattern.patterns;
+	int length = patterns.length;
+	this.patternLocators = new PatternLocator[length];
+	for (int i = 0; i < length; i++)
+		this.patternLocators[i] = PatternLocator.patternLocator(patterns[i]);
+}
+public void initializePolymorphicSearch(MatchLocator locator) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++)
+		this.patternLocators[i].initializePolymorphicSearch(locator);
+}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(Expression node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(MessageSend node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(Reference node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+public int match(TypeReference node, MatchingNodeSet nodeSet) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].match(node, nodeSet);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel;
+		}
+	}
+	return level;
+}
+protected int matchContainer() {
+	int result = 0;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++)
+		result |= this.patternLocators[i].matchContainer();
+	return result;
+}
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+
+	// for static import, binding can be a field binding or a member type binding
+	// verify that in this case binding is static and use declaring class for fields
+	Binding refBinding = binding;
+	if (importRef.isStatic()) {
+		if (binding instanceof FieldBinding) {
+			FieldBinding fieldBinding = (FieldBinding) binding;
+			if (!fieldBinding.isStatic()) return;
+			refBinding = fieldBinding.declaringClass;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = (MethodBinding) binding;
+			if (!methodBinding.isStatic()) return;
+			refBinding = methodBinding.declaringClass;
+		} else if (binding instanceof MemberTypeBinding) {
+			MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
+			if (!memberBinding.isStatic()) return;
+		}
+	}
+
+	// Look for closest pattern
+	PatternLocator closestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		PatternLocator patternLocator = this.patternLocators[i];
+		int newLevel = patternLocator.referenceType() == 0 ? IMPOSSIBLE_MATCH : patternLocator.resolveLevel(refBinding);
+		if (newLevel > level) {
+			closestPattern = patternLocator;
+			if (newLevel == ACCURATE_MATCH) break;
+			level = newLevel;
+		}
+	}
+	if (closestPattern != null) {
+		closestPattern.matchLevelAndReportImportRef(importRef, binding, locator);
+	}
+}
+protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+	PatternLocator closestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].matchLevel(importRef);
+		if (newLevel > level) {
+			closestPattern = this.patternLocators[i];
+			if (newLevel == ACCURATE_MATCH) break;
+			level = newLevel;
+		}
+	}
+	if (closestPattern != null)
+		closestPattern.matchReportImportRef(importRef, binding, element, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	PatternLocator closestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		PatternLocator patternLocator = this.patternLocators[i];
+		int newLevel = patternLocator.referenceType() == 0 ? IMPOSSIBLE_MATCH : patternLocator.resolveLevel(reference);
+		if (newLevel > level) {
+			closestPattern = patternLocator;
+			if (newLevel == ACCURATE_MATCH) break;
+			level = newLevel;
+		}
+	}
+	if (closestPattern != null)
+		closestPattern.matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
+	PatternLocator closestPattern = null;
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, pl = this.patternLocators.length; i < pl; i++) {
+		PatternLocator patternLocator = this.patternLocators[i];
+		int newLevel = patternLocator.referenceType() == 0 ? IMPOSSIBLE_MATCH : patternLocator.resolveLevel(reference);
+		if (newLevel > level) {
+			closestPattern = patternLocator;
+			if (newLevel == ACCURATE_MATCH) break;
+			level = newLevel;
+		}
+	}
+	if (closestPattern != null) {
+	    return closestPattern.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+	}
+	// super implementation...
+    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
+}
+public int resolveLevel(ASTNode node) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].resolveLevel(node);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel; // want to answer the stronger match
+		}
+	}
+	return level;
+}
+public int resolveLevel(Binding binding) {
+	int level = IMPOSSIBLE_MATCH;
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		int newLevel = this.patternLocators[i].resolveLevel(binding);
+		if (newLevel > level) {
+			if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+			level = newLevel; // want to answer the stronger match
+		}
+	}
+	return level;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#setFlavors(int)
+ */
+void setFlavors(int flavors) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		this.patternLocators[i].setFlavors(flavors);
+	}
+}
+public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) {
+	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
+		this.patternLocators[i].recordResolution(typeReference, resolution);
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java
new file mode 100644
index 0000000..0287850
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class OrPattern extends SearchPattern implements IIndexConstants {
+
+	protected SearchPattern[] patterns;
+
+	/**
+	 * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
+	 */
+	int matchCompatibility;
+
+	public OrPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
+		super(Math.max(leftPattern.getMatchRule(), rightPattern.getMatchRule()));
+		this.kind = OR_PATTERN;
+		this.mustResolve = leftPattern.mustResolve || rightPattern.mustResolve;
+
+		SearchPattern[] leftPatterns = leftPattern instanceof OrPattern ? ((OrPattern) leftPattern).patterns : null;
+		SearchPattern[] rightPatterns = rightPattern instanceof OrPattern ? ((OrPattern) rightPattern).patterns : null;
+		int leftSize = leftPatterns == null ? 1 : leftPatterns.length;
+		int rightSize = rightPatterns == null ? 1 : rightPatterns.length;
+		this.patterns = new SearchPattern[leftSize + rightSize];
+
+		if (leftPatterns == null)
+			this.patterns[0] = leftPattern;
+		else
+			System.arraycopy(leftPatterns, 0, this.patterns, 0, leftSize);
+		if (rightPatterns == null)
+			this.patterns[leftSize] = rightPattern;
+		else
+			System.arraycopy(rightPatterns, 0, this.patterns, leftSize, rightSize);
+
+		// Store erasure match
+		this.matchCompatibility = 0;
+		for (int i = 0, length = this.patterns.length; i < length; i++) {
+			this.matchCompatibility |= ((JavaSearchPattern) this.patterns[i]).matchCompatibility;
+		}
+	}
+	public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) throws IOException {
+		// per construction, OR pattern can only be used with a PathCollector (which already gather results using a set)
+		try {
+			index.startQuery();
+			for (int i = 0, length = this.patterns.length; i < length; i++)
+				this.patterns[i].findIndexMatches(index, requestor, participant, scope, progressMonitor);
+		} finally {
+			index.stopQuery();
+		}
+	}
+
+	public SearchPattern getBlankPattern() {
+		return null;
+	}
+
+	boolean isErasureMatch() {
+		return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
+	}
+
+	public boolean isPolymorphicSearch() {
+		for (int i = 0, length = this.patterns.length; i < length; i++)
+			if (this.patterns[i].isPolymorphicSearch()) return true;
+		return false;
+	}
+
+	/**
+	 * Returns whether the pattern has one or several package declaration or not.
+	 *
+	 * @return <code>true</code> if one at least of the stored pattern is a package declaration
+	 * 	pattern ({@link PackageDeclarationPattern}), <code>false</code> otherwise.
+	 */
+	public final boolean hasPackageDeclaration() {
+		for (int i = 0, length = this.patterns.length; i < length; i++) {
+			if (this.patterns[i] instanceof PackageDeclarationPattern) return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Returns whether the pattern has signatures or not.
+	 * @return true if one at least of the stored pattern has signatures.
+	 */
+	public final boolean hasSignatures() {
+		boolean isErasureMatch = isErasureMatch();
+		for (int i = 0, length = this.patterns.length; i < length && !isErasureMatch; i++) {
+			if (((JavaSearchPattern) this.patterns[i]).hasSignatures()) return true;
+		}
+		return false;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(this.patterns[0].toString());
+		for (int i = 1, length = this.patterns.length; i < length; i++) {
+			buffer.append("\n| "); //$NON-NLS-1$
+			buffer.append(this.patterns[i].toString());
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java
new file mode 100644
index 0000000..051ddae
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+public class PackageDeclarationLocator extends PatternLocator {
+
+protected PackageDeclarationPattern pattern;
+
+public PackageDeclarationLocator(PackageDeclarationPattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+protected int matchContainer() {
+	return 0;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java
new file mode 100644
index 0000000..12c5108
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.internal.core.index.*;
+
+public class PackageDeclarationPattern extends JavaSearchPattern {
+
+protected char[] pkgName;
+
+public PackageDeclarationPattern(char[] pkgName, int matchRule) {
+	super(PKG_DECL_PATTERN, matchRule);
+	this.pkgName = pkgName;
+}
+public EntryResult[] queryIn(Index index) {
+	// package declarations are not indexed
+	return null;
+}
+protected StringBuffer print(StringBuffer output) {
+	output.append("PackageDeclarationPattern: <"); //$NON-NLS-1$
+	if (this.pkgName != null)
+		output.append(this.pkgName);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
new file mode 100644
index 0000000..ff8549d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.PackageReferenceMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class PackageReferenceLocator extends PatternLocator {
+
+protected PackageReferencePattern pattern;
+
+// check that referenced type is actually defined in this package fragment
+public static boolean isDeclaringPackageFragment(IPackageFragment packageFragment, ReferenceBinding typeBinding) {
+	char[] fileName = typeBinding.getFileName();
+	if (fileName != null) {
+		// retrieve the actual file name from the full path (sources are generally only containing it already)
+		fileName = CharOperation.replaceOnCopy(fileName, '/', '\\'); // ensure to not do any side effect on file name (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=136016)
+		fileName = CharOperation.lastSegment(fileName, '\\');
+
+		try {
+			switch (packageFragment.getKind()) {
+				case IPackageFragmentRoot.K_SOURCE :
+					if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(fileName) || !packageFragment.getCompilationUnit(new String(fileName)).exists()) {
+						return false; // unit doesn't live in selected package
+					}
+					break;
+				case IPackageFragmentRoot.K_BINARY :
+//					if (Util.isJavaFileName(fileName)) { // binary with attached source
+//						int length = fileName.length;
+//						System.arraycopy(fileName, 0, fileName = new char[length], 0, length - 4); // copy all but extension
+//						System.arraycopy(SuffixConstants.SUFFIX_class, 0, fileName, length - 4, 4);
+//					}
+					if (!Util.isClassFileName(fileName) || !packageFragment.getClassFile(new String(fileName)).exists()) {
+						return false; // classfile doesn't live in selected package
+					}
+					break;
+			}
+		} catch(JavaModelException e) {
+			// unable to determine kind; tolerate this match
+		}
+	}
+	return true; // by default, do not eliminate
+}
+
+public PackageReferenceLocator(PackageReferencePattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	return match(node.type, nodeSet);
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ImportReference
+	if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, matchLevel((ImportReference) node));
+}
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(Reference node, MatchingNodeSet nodeSet) { // interested in QualifiedNameReference
+	if (!(node instanceof QualifiedNameReference)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedNameReference) node).tokens));
+}
+//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(TypeReference node, MatchingNodeSet nodeSet) { // interested in QualifiedTypeReference only
+	if (node instanceof JavadocSingleTypeReference) {
+		char[][] tokens = new char[][] { ((JavadocSingleTypeReference) node).token };
+		return nodeSet.addMatch(node, matchLevelForTokens(tokens));
+	}
+	if (!(node instanceof QualifiedTypeReference)) return IMPOSSIBLE_MATCH;
+	return nodeSet.addMatch(node, matchLevelForTokens(((QualifiedTypeReference) node).tokens));
+}
+
+protected int matchLevel(ImportReference importRef) {
+	return matchLevelForTokens(importRef.tokens);
+}
+protected int matchLevelForTokens(char[][] tokens) {
+	if (this.pattern.pkgName == null) return ACCURATE_MATCH;
+
+	switch (this.matchMode) {
+		case SearchPattern.R_EXACT_MATCH:
+		case SearchPattern.R_PREFIX_MATCH:
+			if (CharOperation.prefixEquals(this.pattern.pkgName, CharOperation.concatWith(tokens, '.'), this.isCaseSensitive)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_PATTERN_MATCH:
+			char[] patternName = this.pattern.pkgName[this.pattern.pkgName.length - 1] == '*'
+				? this.pattern.pkgName
+				: CharOperation.concat(this.pattern.pkgName, ".*".toCharArray()); //$NON-NLS-1$
+			if (CharOperation.match(patternName, CharOperation.concatWith(tokens, '.'), this.isCaseSensitive)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+
+		case SearchPattern.R_CAMELCASE_MATCH:
+			char[] packageName = CharOperation.concatWith(tokens, '.');
+			if (CharOperation.camelCaseMatch(this.pattern.pkgName, packageName, false)) {
+				return POSSIBLE_MATCH;
+			}
+			// only test case insensitive as CamelCase already verified prefix case sensitive
+			if (!this.isCaseSensitive && CharOperation.prefixEquals(this.pattern.pkgName, packageName, false)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			if (CharOperation.camelCaseMatch(this.pattern.pkgName, CharOperation.concatWith(tokens, '.'), true)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+	}
+	return IMPOSSIBLE_MATCH;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	Binding refBinding = binding;
+	if (importRef.isStatic()) {
+		// for static import, binding can be a field binding or a member type binding
+		// verify that in this case binding is static and use declaring class for fields
+		if (binding instanceof FieldBinding) {
+			FieldBinding fieldBinding = (FieldBinding) binding;
+			if (!fieldBinding.isStatic()) return;
+			refBinding = fieldBinding.declaringClass;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = (MethodBinding) binding;
+			if (!methodBinding.isStatic()) return;
+			refBinding = methodBinding.declaringClass;
+		} else if (binding instanceof MemberTypeBinding) {
+			MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
+			if (!memberBinding.isStatic()) return;
+		}
+	}
+	super.matchLevelAndReportImportRef(importRef, refBinding, locator);
+}
+protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+	if (binding == null) {
+		this.matchReportReference(importRef, element, null/*no binding*/, accuracy, locator);
+	} else {
+		if (locator.encloses(element)) {
+			long[] positions = importRef.sourcePositions;
+			int last = positions.length - 1;
+			if (binding instanceof ProblemReferenceBinding)
+				binding = ((ProblemReferenceBinding) binding).closestMatch();
+			if (binding instanceof ReferenceBinding) {
+				PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage;
+				if (pkgBinding != null)
+					last = pkgBinding.compoundName.length;
+			}
+			if (binding instanceof PackageBinding)
+				last = ((PackageBinding) binding).compoundName.length;
+			int start = (int) (positions[0] >>> 32);
+			int end = (int) positions[last - 1];
+			this.match = locator.newPackageReferenceMatch(element, accuracy, start, end-start+1, importRef);
+			locator.report(this.match);
+		}
+	}
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	long[] positions = null;
+	int last = -1;
+	if (reference instanceof ImportReference) {
+		ImportReference importRef = (ImportReference) reference;
+		positions = importRef.sourcePositions;
+		last = (importRef.bits & ASTNode.OnDemand) != 0 ? positions.length : positions.length - 1;
+	} else {
+		TypeBinding typeBinding = null;
+		if (reference instanceof QualifiedNameReference) {
+			QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
+			positions = qNameRef.sourcePositions;
+			switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
+				case Binding.FIELD : // reading a field
+					typeBinding = qNameRef.actualReceiverType;
+					break;
+				case Binding.TYPE : //=============only type ==============
+					if (qNameRef.binding instanceof TypeBinding)
+						typeBinding = (TypeBinding) qNameRef.binding;
+					break;
+				case Binding.VARIABLE : //============unbound cases===========
+				case Binding.TYPE | Binding.VARIABLE :
+					Binding binding = qNameRef.binding;
+					if (binding instanceof TypeBinding) {
+						typeBinding = (TypeBinding) binding;
+					} else if (binding instanceof ProblemFieldBinding) {
+						typeBinding = qNameRef.actualReceiverType;
+						last = qNameRef.tokens.length - (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2);
+					} else if (binding instanceof ProblemBinding) {
+						ProblemBinding pbBinding = (ProblemBinding) binding;
+						typeBinding = pbBinding.searchType;
+						last = CharOperation.occurencesOf('.', pbBinding.name);
+					}
+					break;
+			}
+		} else if (reference instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qTypeRef = (QualifiedTypeReference) reference;
+			positions = qTypeRef.sourcePositions;
+			typeBinding = qTypeRef.resolvedType;
+		} else if (reference instanceof JavadocSingleTypeReference) {
+			JavadocSingleTypeReference jsTypeRef = (JavadocSingleTypeReference) reference;
+			positions = new long[1];
+			positions[0] = (((long)jsTypeRef.sourceStart) << 32) + jsTypeRef.sourceEnd;
+			typeBinding = jsTypeRef.resolvedType;
+		}
+		if (positions == null) return;
+		if (typeBinding instanceof ArrayBinding)
+			typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+		if (typeBinding instanceof ProblemReferenceBinding)
+			typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch();
+		if (typeBinding instanceof ReferenceBinding) {
+			PackageBinding pkgBinding = ((ReferenceBinding) typeBinding).fPackage;
+			if (pkgBinding != null)
+				last = pkgBinding.compoundName.length;
+		}
+		// Do not report qualified references which are only enclosing type
+		// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=91078)
+		ReferenceBinding enclosingType = typeBinding == null ? null: typeBinding.enclosingType();
+		if (enclosingType != null) {
+			int length = positions.length;
+			while (enclosingType != null && length > 0) {
+				length--;
+				enclosingType = enclosingType.enclosingType();
+			}
+			if (length <= 1) return;
+		}
+	}
+	if (last == -1) {
+		last = this.pattern.segments.length;
+	}
+	if (last == 0) return;
+	if (last > positions.length) last = positions.length;
+	int sourceStart = (int) (positions[0] >>> 32);
+	int sourceEnd = ((int) positions[last - 1]);
+	PackageReferenceMatch packageReferenceMatch = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference);
+	packageReferenceMatch.setLocalElement(localElement);
+	this.match = packageReferenceMatch;
+	locator.report(this.match);
+}
+protected int referenceType() {
+	return IJavaElement.PACKAGE_FRAGMENT;
+}
+public int resolveLevel(ASTNode node) {
+	if (node instanceof JavadocQualifiedTypeReference) {
+		JavadocQualifiedTypeReference qualifRef = (JavadocQualifiedTypeReference) node;
+		if (qualifRef.packageBinding != null)
+			return resolveLevel(qualifRef.packageBinding);
+		return resolveLevel(qualifRef.resolvedType);
+	}
+	if (node instanceof JavadocSingleTypeReference) {
+		JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) node;
+		if (singleRef.packageBinding != null)
+			return resolveLevel(singleRef.packageBinding);
+		return IMPOSSIBLE_MATCH;
+	}
+	if (node instanceof QualifiedTypeReference)
+		return resolveLevel(((QualifiedTypeReference) node).resolvedType);
+	if (node instanceof QualifiedNameReference)
+		return this.resolveLevel((QualifiedNameReference) node);
+//	if (node instanceof ImportReference) - Not called when resolve is true, see MatchingNodeSet.reportMatching(unit)
+	return IMPOSSIBLE_MATCH;
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+
+	char[][] compoundName = null;
+	if (binding instanceof ImportBinding) {
+		compoundName = ((ImportBinding) binding).compoundName;
+	} else if (binding instanceof PackageBinding) {
+		compoundName = ((PackageBinding) binding).compoundName;
+	} else {
+		if (binding instanceof ArrayBinding)
+			binding = ((ArrayBinding) binding).leafComponentType;
+		if (binding instanceof ProblemReferenceBinding)
+			binding = ((ProblemReferenceBinding) binding).closestMatch();
+		if (binding == null) return INACCURATE_MATCH;
+
+		if (binding instanceof ReferenceBinding) {
+			PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage;
+			if (pkgBinding == null) return INACCURATE_MATCH;
+			compoundName = pkgBinding.compoundName;
+		}
+	}
+	if (compoundName != null && matchesName(this.pattern.pkgName, CharOperation.concatWith(compoundName, '.'))) {
+		if (this.pattern.focus instanceof IPackageFragment && binding instanceof ReferenceBinding) {
+			// check that type is located inside this instance of a package fragment
+			if (!isDeclaringPackageFragment((IPackageFragment) this.pattern.focus, (ReferenceBinding)binding))
+				return IMPOSSIBLE_MATCH;
+		}
+		return ACCURATE_MATCH;
+	}
+	return IMPOSSIBLE_MATCH;
+}
+protected int resolveLevel(QualifiedNameReference qNameRef) {
+	TypeBinding typeBinding = null;
+	switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3))
+				return IMPOSSIBLE_MATCH; // must be at least p1.A.x
+			typeBinding = qNameRef.actualReceiverType;
+			break;
+		case Binding.LOCAL : // reading a local variable
+			return IMPOSSIBLE_MATCH; // no package match in it
+		case Binding.TYPE : //=============only type ==============
+			if (qNameRef.binding instanceof TypeBinding)
+				typeBinding = (TypeBinding) qNameRef.binding;
+			break;
+		/*
+		 * Handling of unbound qualified name references. The match may reside in the resolved fragment,
+		 * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
+		 */
+		case Binding.VARIABLE : //============unbound cases===========
+		case Binding.TYPE | Binding.VARIABLE :
+			Binding binding = qNameRef.binding;
+			if (binding instanceof ProblemReferenceBinding) {
+				typeBinding = (TypeBinding) binding;
+			} else if (binding instanceof ProblemFieldBinding) {
+				if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 3 : qNameRef.otherBindings.length + 3))
+					return IMPOSSIBLE_MATCH; // must be at least p1.A.x
+				typeBinding = qNameRef.actualReceiverType;
+			} else if (binding instanceof ProblemBinding) {
+				ProblemBinding pbBinding = (ProblemBinding) binding;
+				if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
+					return INACCURATE_MATCH;
+				typeBinding = pbBinding.searchType;
+			}
+			break;
+	}
+	return resolveLevel(typeBinding);
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java
new file mode 100644
index 0000000..3ecfc39
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+
+public class PackageReferencePattern extends IntersectingPattern {
+
+protected char[] pkgName;
+
+protected char[][] segments;
+protected int currentSegment;
+
+protected static char[][] CATEGORIES = { REF };
+
+public PackageReferencePattern(char[] pkgName, int matchRule) {
+	this(matchRule);
+
+	if (pkgName == null || pkgName.length == 0) {
+		this.pkgName = null;
+		this.segments = new char[][] {CharOperation.NO_CHAR};
+		this.mustResolve = false;
+	} else {
+		this.pkgName = (this.isCaseSensitive || this.isCamelCase) ? pkgName : CharOperation.toLowerCase(pkgName);
+		this.segments = CharOperation.splitOn('.', this.pkgName);
+		this.mustResolve = true;
+	}
+}
+PackageReferencePattern(int matchRule) {
+	super(PKG_REF_PATTERN, matchRule);
+}
+public void decodeIndexKey(char[] key) {
+	// Package reference keys are encoded as 'name' (where 'name' is the last segment of the package name)
+	this.pkgName = key;
+}
+public SearchPattern getBlankPattern() {
+	return new PackageReferencePattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[] getIndexKey() {
+	// Package reference keys are encoded as 'name' (where 'name' is the last segment of the package name)
+	if (this.currentSegment >= 0)
+		return this.segments[this.currentSegment];
+	return null;
+}
+public char[][] getIndexCategories() {
+	return CATEGORIES;
+}
+protected boolean hasNextQuery() {
+	// if package has at least 4 segments, don't look at the first 2 since they are mostly
+	// redundant (e.g. in 'org.eclipse.jdt.core.*' 'org.eclipse' is used all the time)
+	return --this.currentSegment >= (this.segments.length >= 4 ? 2 : 0);
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	return true; // index key is not encoded so query results all match
+}
+protected void resetQuery() {
+	/* walk the segments from end to start as it will find less potential references using 'lang' than 'java' */
+	this.currentSegment = this.segments.length - 1;
+}
+protected StringBuffer print(StringBuffer output) {
+	output.append("PackageReferencePattern: <"); //$NON-NLS-1$
+	if (this.pkgName != null)
+		output.append(this.pkgName);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
new file mode 100644
index 0000000..7992580
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
@@ -0,0 +1,976 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public abstract class PatternLocator implements IIndexConstants, IQualifiedTypeResolutionListener {
+
+// store pattern info
+protected int matchMode;
+protected boolean isCaseSensitive;
+protected boolean isEquivalentMatch;
+protected boolean isErasureMatch;
+protected boolean mustResolve;
+protected boolean mayBeGeneric;
+
+// match to report
+SearchMatch match = null;
+
+/* match levels */
+public static final int IMPOSSIBLE_MATCH = 0;
+public static final int INACCURATE_MATCH = 1;
+public static final int POSSIBLE_MATCH = 2;
+public static final int ACCURATE_MATCH = 3;
+public static final int ERASURE_MATCH = 4;
+
+// Possible rule match flavors
+int flavors = 0;
+// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866
+public static final int NO_FLAVOR = 0x0000;
+public static final int EXACT_FLAVOR = 0x0010;
+public static final int PREFIX_FLAVOR = 0x0020;
+public static final int PATTERN_FLAVOR = 0x0040;
+public static final int REGEXP_FLAVOR = 0x0080;
+public static final int CAMELCASE_FLAVOR = 0x0100;
+public static final int SUPER_INVOCATION_FLAVOR = 0x0200;
+public static final int SUB_INVOCATION_FLAVOR = 0x0400;
+public static final int OVERRIDDEN_METHOD_FLAVOR = 0x0800;
+public static final int SUPERTYPE_REF_FLAVOR = 0x1000;
+public static final int MATCH_LEVEL_MASK = 0x0F;
+public static final int FLAVORS_MASK = ~MATCH_LEVEL_MASK;
+
+/* match container */
+public static final int COMPILATION_UNIT_CONTAINER = 1;
+public static final int CLASS_CONTAINER = 2;
+public static final int METHOD_CONTAINER = 4;
+public static final int FIELD_CONTAINER = 8;
+public static final int ALL_CONTAINER =
+	COMPILATION_UNIT_CONTAINER | CLASS_CONTAINER | METHOD_CONTAINER | FIELD_CONTAINER;
+
+/* match rule */
+public static final int RAW_MASK = SearchPattern.R_EQUIVALENT_MATCH | SearchPattern.R_ERASURE_MATCH;
+public static final int RULE_MASK = RAW_MASK; // no other values for the while...
+
+public static PatternLocator patternLocator(SearchPattern pattern) {
+	switch (pattern.kind) {
+		case IIndexConstants.PKG_REF_PATTERN :
+			return new PackageReferenceLocator((PackageReferencePattern) pattern);
+		case IIndexConstants.PKG_DECL_PATTERN :
+			return new PackageDeclarationLocator((PackageDeclarationPattern) pattern);
+		case IIndexConstants.TYPE_REF_PATTERN :
+			return new TypeReferenceLocator((TypeReferencePattern) pattern);
+		case IIndexConstants.TYPE_DECL_PATTERN :
+			return new TypeDeclarationLocator((TypeDeclarationPattern) pattern);
+		case IIndexConstants.SUPER_REF_PATTERN :
+			return new SuperTypeReferenceLocator((SuperTypeReferencePattern) pattern);
+		case IIndexConstants.CONSTRUCTOR_PATTERN :
+			return new ConstructorLocator((ConstructorPattern) pattern);
+		case IIndexConstants.FIELD_PATTERN :
+			return new FieldLocator((FieldPattern) pattern);
+		case IIndexConstants.METHOD_PATTERN :
+			return new MethodLocator((MethodPattern) pattern);
+		case IIndexConstants.OR_PATTERN :
+			return new OrLocator((OrPattern) pattern);
+		case IIndexConstants.AND_PATTERN :
+			return new AndLocator((AndPattern) pattern);
+		case IIndexConstants.LOCAL_VAR_PATTERN :
+			return new LocalVariableLocator((LocalVariablePattern) pattern);
+		case IIndexConstants.TYPE_PARAM_PATTERN:
+			return new TypeParameterLocator((TypeParameterPattern) pattern);
+	}
+	return null;
+}
+public static char[] qualifiedPattern(char[] simpleNamePattern, char[] qualificationPattern) {
+	// NOTE: if case insensitive search then simpleNamePattern & qualificationPattern are assumed to be lowercase
+	if (simpleNamePattern == null) {
+		if (qualificationPattern == null) return null;
+		return CharOperation.concat(qualificationPattern, ONE_STAR, '.');
+	} else {
+		return qualificationPattern == null
+			? CharOperation.concat(ONE_STAR, simpleNamePattern)
+			: CharOperation.concat(qualificationPattern, simpleNamePattern, '.');
+	}
+}
+public static char[] qualifiedSourceName(TypeBinding binding) {
+	if (binding instanceof ReferenceBinding) {
+		ReferenceBinding type = (ReferenceBinding) binding;
+		if (type.isLocalType())
+			return type.isMemberType()
+				? CharOperation.concat(qualifiedSourceName(type.enclosingType()), type.sourceName(), '.')
+				: CharOperation.concat(qualifiedSourceName(type.enclosingType()), new char[] {'.', '1', '.'}, type.sourceName());
+	}
+	return binding != null ? binding.qualifiedSourceName() : null;
+}
+
+public PatternLocator(SearchPattern pattern) {
+	int matchRule = pattern.getMatchRule();
+	this.isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
+	this.isErasureMatch = (matchRule & SearchPattern.R_ERASURE_MATCH) != 0;
+	this.isEquivalentMatch = (matchRule & SearchPattern.R_EQUIVALENT_MATCH) != 0;
+	this.matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
+	this.mustResolve = pattern.mustResolve;
+}
+/*
+ * Clear caches
+ */
+protected void clear() {
+	// nothing to clear by default
+}
+/* (non-Javadoc)
+ * Modify PatternLocator.qualifiedPattern behavior:
+ * do not add star before simple name pattern when qualification pattern is null.
+ * This avoid to match p.X when pattern is only X...
+ */
+protected char[] getQualifiedPattern(char[] simpleNamePattern, char[] qualificationPattern) {
+	// NOTE: if case insensitive search then simpleNamePattern & qualificationPattern are assumed to be lowercase
+	if (simpleNamePattern == null) {
+		if (qualificationPattern == null) return null;
+		return CharOperation.concat(qualificationPattern, ONE_STAR, '.');
+	} else if (qualificationPattern == null) {
+		return simpleNamePattern;
+	} else {
+		return CharOperation.concat(qualificationPattern, simpleNamePattern, '.');
+	}
+}
+/* (non-Javadoc)
+ * Modify PatternLocator.qualifiedSourceName behavior:
+ * also concatenate enclosing type name when type is a only a member type.
+ */
+protected char[] getQualifiedSourceName(TypeBinding binding) {
+	TypeBinding type = binding instanceof ArrayBinding ? ((ArrayBinding)binding).leafComponentType : binding;
+	if (type instanceof ReferenceBinding) {
+		if (type.isLocalType()) {
+			return CharOperation.concat(qualifiedSourceName(type.enclosingType()), new char[] {'.', '1', '.'}, binding.sourceName());
+		} else if (type.isMemberType()) {
+			return CharOperation.concat(qualifiedSourceName(type.enclosingType()), binding.sourceName(), '.');
+		}
+	}
+	return binding != null ? binding.qualifiedSourceName() : null;
+}
+/*
+ * Get binding of type argument from a class unit scope and its index position.
+ * Cache is lazy initialized and if no binding is found, then store a problem binding
+ * to avoid making research twice...
+ */
+protected TypeBinding getTypeNameBinding(int index) {
+	return null;
+}
+/**
+ * Initializes this search pattern so that polymorphic search can be performed.
+ */
+public void initializePolymorphicSearch(MatchLocator locator) {
+	// default is to do nothing
+}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+/**
+ * Check if the given ast node syntactically matches this pattern.
+ * If it does, add it to the match set.
+ * Returns the match level.
+ */
+public int match(ASTNode node, MatchingNodeSet nodeSet) { // needed for some generic nodes
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(Expression node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(FieldDeclaration node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(LocalDeclaration node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(MessageSend node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(Reference node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+public int match(TypeReference node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
+/**
+ * Returns the type(s) of container for this pattern.
+ * It is a bit combination of types, denoting compilation unit, class declarations, field declarations or method declarations.
+ */
+protected int matchContainer() {
+	// override if the pattern can be more specific
+	return ALL_CONTAINER;
+}
+protected int fineGrain() {
+	return 0;
+}
+/**
+ * Returns whether the given name matches the given pattern.
+ */
+protected boolean matchesName(char[] pattern, char[] name) {
+	if (pattern == null) return true; // null is as if it was "*"
+	if (name == null) return false; // cannot match null name
+	return matchNameValue(pattern, name) != IMPOSSIBLE_MATCH;
+}
+/**
+ * Return how the given name matches the given pattern.
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=79866"
+ *
+ * @param pattern
+ * @param name
+ * @return Possible values are:
+ * <ul>
+ * 	<li> {@link #ACCURATE_MATCH}</li>
+ * 	<li> {@link #IMPOSSIBLE_MATCH}</li>
+ * 	<li> {@link #POSSIBLE_MATCH} which may be flavored with following values:
+ * 		<ul>
+ * 		<li>{@link #EXACT_FLAVOR}: Given name is equals to pattern</li>
+ * 		<li>{@link #PREFIX_FLAVOR}: Given name prefix equals to pattern</li>
+ * 		<li>{@link #CAMELCASE_FLAVOR}: Given name matches pattern as Camel Case</li>
+ * 		<li>{@link #PATTERN_FLAVOR}: Given name matches pattern as Pattern (i.e. using '*' and '?' characters)</li>
+ * 		</ul>
+ * 	</li>
+ * </ul>
+ */
+protected int matchNameValue(char[] pattern, char[] name) {
+	if (pattern == null) return ACCURATE_MATCH; // null is as if it was "*"
+	if (name == null) return IMPOSSIBLE_MATCH; // cannot match null name
+	if (name.length == 0) { // empty name
+		if (pattern.length == 0) { // can only matches empty pattern
+			return ACCURATE_MATCH;
+		}
+		return IMPOSSIBLE_MATCH;
+	} else if (pattern.length == 0) {
+		return IMPOSSIBLE_MATCH; // need to have both name and pattern length==0 to be accurate
+	}
+	boolean matchFirstChar = !this.isCaseSensitive || pattern[0] == name[0];
+	boolean sameLength = pattern.length == name.length;
+	boolean canBePrefix = name.length >= pattern.length;
+	switch (this.matchMode) {
+		case SearchPattern.R_EXACT_MATCH:
+			if (sameLength && matchFirstChar && CharOperation.equals(pattern, name, this.isCaseSensitive)) {
+				return POSSIBLE_MATCH | EXACT_FLAVOR;
+			}
+			break;
+
+		case SearchPattern.R_PREFIX_MATCH:
+			if (canBePrefix && matchFirstChar && CharOperation.prefixEquals(pattern, name, this.isCaseSensitive)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_PATTERN_MATCH:
+			// TODO_PERFS (frederic) Not sure this lowercase is necessary
+			if (!this.isCaseSensitive) {
+				pattern = CharOperation.toLowerCase(pattern);
+			}
+			if (CharOperation.match(pattern, name, this.isCaseSensitive)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+
+		case SearchPattern.R_CAMELCASE_MATCH:
+			if (CharOperation.camelCaseMatch(pattern, name, false)) {
+				return POSSIBLE_MATCH;
+			}
+			// only test case insensitive as CamelCase same part count already verified prefix case sensitive
+			if (!this.isCaseSensitive && CharOperation.prefixEquals(pattern, name, false)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			if (CharOperation.camelCaseMatch(pattern, name, true)) {
+				return POSSIBLE_MATCH;
+			}
+			break;
+	}
+	return IMPOSSIBLE_MATCH;
+}
+/**
+ * Returns whether the given type reference matches the given pattern.
+ */
+protected boolean matchesTypeReference(char[] pattern, TypeReference type) {
+	if (pattern == null) return true; // null is as if it was "*"
+	if (type == null) return true; // treat as an inexact match
+
+	char[][] compoundName = type.getTypeName();
+	char[] simpleName = compoundName[compoundName.length - 1];
+	int dimensions = type.dimensions() * 2;
+	if (dimensions > 0) {
+		int length = simpleName.length;
+		char[] result = new char[length + dimensions];
+		System.arraycopy(simpleName, 0, result, 0, length);
+		for (int i = length, l = result.length; i < l;) {
+			result[i++] = '[';
+			result[i++] = ']';
+		}
+		simpleName = result;
+	}
+
+	return matchesName(pattern, simpleName);
+}
+/**
+ * Returns the match level for the given importRef.
+ */
+protected int matchLevel(ImportReference importRef) {
+	// override if interested in import references which are caught by the generic version of match(ASTNode, MatchingNodeSet)
+	return IMPOSSIBLE_MATCH;
+}
+/**
+ * Reports the match of the given import reference if the resolveLevel is high enough.
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	int level = resolveLevel(binding);
+	if (level >= INACCURATE_MATCH) {
+		matchReportImportRef(
+			importRef,
+			binding,
+			locator.createImportHandle(importRef),
+			level == ACCURATE_MATCH
+				? SearchMatch.A_ACCURATE
+				: SearchMatch.A_INACCURATE,
+			locator);
+	}
+}
+/**
+ * Reports the match of the given import reference.
+ */
+protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+	if (locator.encloses(element)) {
+		// default is to report a match as a regular ref.
+		this.matchReportReference(importRef, element, null/*no binding*/, accuracy, locator);
+	}
+}
+/**
+ * Reports the match of the given reference.
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	this.match = null;
+	int referenceType = referenceType();
+	int offset = reference.sourceStart;
+	switch (referenceType) {
+		case IJavaElement.PACKAGE_FRAGMENT:
+			this.match = locator.newPackageReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
+		case IJavaElement.TYPE:
+			this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
+		case IJavaElement.FIELD:
+			this.match = locator.newFieldReferenceMatch(element, null, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
+		case IJavaElement.LOCAL_VARIABLE:
+			this.match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
+		case IJavaElement.TYPE_PARAMETER:
+			this.match = locator.newTypeParameterReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
+	}
+	if (this.match != null) {
+		locator.report(this.match);
+	}
+}
+/**
+ * Reports the match of the given reference. Also provide a local element to eventually report in match.
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, elementBinding, accuracy, locator);
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
+    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
+}
+protected int referenceType() {
+	return 0; // defaults to unknown (a generic JavaSearchMatch will be created)
+}
+/**
+ * Finds out whether the given ast node matches this search pattern.
+ * Returns IMPOSSIBLE_MATCH if it doesn't.
+ * Returns INACCURATE_MATCH if it potentially matches this search pattern (i.e.
+ * it has already been resolved but resolving failed.)
+ * Returns ACCURATE_MATCH if it matches exactly this search pattern (i.e.
+ * it doesn't need to be resolved or it has already been resolved.)
+ */
+public int resolveLevel(ASTNode possibleMatchingNode) {
+	// only called with nodes which were possible matches to the call to matchLevel
+	// need to do instance of checks to find out exact type of ASTNode
+	return IMPOSSIBLE_MATCH;
+}
+/**
+ * Set the flavors for which the locator has to be focused on.
+ * If not set, the locator will accept all matches with or without flavors.
+ * When set, the locator will only accept match having the corresponding flavors.
+ * 
+ * @param flavors Bits mask specifying the flavors to be accepted or
+ * 	<code>0</code> to ignore the flavors while accepting matches.
+ */
+void setFlavors(int flavors) {
+	this.flavors = flavors;
+}
+/*
+ * Update pattern locator match for parameterized top level types.
+ * Set match raw flag and recurse to enclosing types if any...
+ */
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope != null) {
+		updateMatch(parameterizedBinding, patternTypeArguments, false, 0, locator);
+	}
+}
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, boolean patternHasTypeParameters, int depth, MatchLocator locator) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope == null) return;
+
+	// Set match raw flag
+	boolean endPattern = patternTypeArguments==null  ? true  : depth>=patternTypeArguments.length;
+	TypeBinding[] argumentsBindings = parameterizedBinding.arguments;
+	boolean isRaw = parameterizedBinding.isRawType()|| (argumentsBindings==null && parameterizedBinding.genericType().isGenericType());
+	if (isRaw && !this.match.isRaw()) {
+		this.match.setRaw(isRaw);
+	}
+
+	// Update match
+	if (!endPattern && patternTypeArguments != null) {
+		// verify if this is a reference to the generic type itself
+		if (!isRaw && patternHasTypeParameters && argumentsBindings != null) {
+			boolean needUpdate = false;
+			TypeVariableBinding[] typeVariables = parameterizedBinding.genericType().typeVariables();
+			int length = argumentsBindings.length;
+			if (length == typeVariables.length) {
+				for (int i=0; i<length; i++) {
+					if (argumentsBindings[i] != typeVariables[i]) {
+						needUpdate = true;
+						break;
+					}
+				}
+			}
+			if (needUpdate) {
+				char[][] patternArguments =  patternTypeArguments[depth];
+				updateMatch(argumentsBindings, locator, patternArguments, patternHasTypeParameters);
+			}
+		} else {
+			char[][] patternArguments =  patternTypeArguments[depth];
+			updateMatch(argumentsBindings, locator, patternArguments, patternHasTypeParameters);
+		}
+	}
+
+	// Recurse
+	TypeBinding enclosingType = parameterizedBinding.enclosingType();
+	if (enclosingType != null && (enclosingType.isParameterizedType() || enclosingType.isRawType())) {
+		updateMatch((ParameterizedTypeBinding)enclosingType, patternTypeArguments, patternHasTypeParameters, depth+1, locator);
+	}
+}
+/*
+ * Update pattern locator match comparing type arguments with pattern ones.
+ * Try to resolve pattern and look for compatibility with type arguments
+ * to set match rule.
+ */
+protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments, boolean hasTypeParameters) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope == null) return;
+
+	// First compare lengthes
+	int patternTypeArgsLength = patternArguments==null ? 0 : patternArguments.length;
+	int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length;
+
+	// Initialize match rule
+	int matchRule = this.match.getRule();
+	if (this.match.isRaw()) {
+		if (patternTypeArgsLength != 0) {
+			matchRule &= ~SearchPattern.R_FULL_MATCH;
+		}
+	}
+	if (hasTypeParameters) {
+		matchRule = SearchPattern.R_ERASURE_MATCH;
+	}
+
+	// Compare arguments lengthes
+	if (patternTypeArgsLength == typeArgumentsLength) {
+		if (!this.match.isRaw() && hasTypeParameters) {
+			// generic patterns are always not compatible match
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+			return;
+		}
+	} else {
+		if (patternTypeArgsLength==0) {
+			if (!this.match.isRaw() || hasTypeParameters) {
+				this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
+			}
+		} else  if (typeArgumentsLength==0) {
+			// raw binding is always compatible
+			this.match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
+		} else {
+			this.match.setRule(0); // impossible match
+		}
+		return;
+	}
+	if (argumentsBinding == null || patternArguments == null) {
+		this.match.setRule(matchRule);
+		return;
+	}
+
+	// Compare binding for each type argument only if pattern is not erasure only and at first level
+	if (!hasTypeParameters && !this.match.isRaw() && (this.match.isEquivalent() || this.match.isExact())) {
+		for (int i=0; i<typeArgumentsLength; i++) {
+			// Get parameterized type argument binding
+			TypeBinding argumentBinding = argumentsBinding[i];
+			if (argumentBinding instanceof CaptureBinding) {
+				WildcardBinding capturedWildcard = ((CaptureBinding)argumentBinding).wildcard;
+				if (capturedWildcard != null) argumentBinding = capturedWildcard;
+			}
+			// Get binding for pattern argument
+			char[] patternTypeArgument = patternArguments[i];
+			char patternWildcard = patternTypeArgument[0];
+			char[] patternTypeName = patternTypeArgument;
+			int patternWildcardKind = -1;
+			switch (patternWildcard) {
+				case Signature.C_STAR:
+					if (argumentBinding.isWildcard()) {
+						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
+						if (wildcardBinding.boundKind == Wildcard.UNBOUND) continue;
+					}
+					matchRule &= ~SearchPattern.R_FULL_MATCH;
+					continue; // unbound parameter always match
+				case Signature.C_EXTENDS :
+					patternWildcardKind = Wildcard.EXTENDS;
+					patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
+					break;
+				case Signature.C_SUPER :
+					patternWildcardKind = Wildcard.SUPER;
+					patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
+					break;
+				default :
+					break;
+			}
+			patternTypeName = Signature.toCharArray(patternTypeName);
+			TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName);
+
+			// If have no binding for pattern arg, then we won't be able to refine accuracy
+			if (patternBinding == null) {
+				if (argumentBinding.isWildcard()) {
+					WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
+					if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
+					} else {
+						this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+						return;
+					}
+				}
+				continue;
+			}
+
+			// Verify the pattern binding is compatible with match type argument binding
+			switch (patternWildcard) {
+				case Signature.C_STAR : // UNBOUND pattern
+					// unbound always match => skip to next argument
+					matchRule &= ~SearchPattern.R_FULL_MATCH;
+					continue;
+				case Signature.C_EXTENDS : // EXTENDS pattern
+					if (argumentBinding.isWildcard()) { // argument is a wildcard
+						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
+						// It's ok if wildcards are identical
+						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+							continue;
+						}
+						// Look for wildcard compatibility
+						switch (wildcardBinding.boundKind) {
+							case Wildcard.EXTENDS:
+								if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
+									// valid when arg extends a subclass of pattern
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
+									continue;
+								}
+								break;
+							case Wildcard.SUPER:
+								break;
+							case Wildcard.UNBOUND:
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
+								continue;
+						}
+					} else if (argumentBinding.isCompatibleWith(patternBinding)) {
+						// valid when arg is a subclass of pattern
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
+						continue;
+					}
+					break;
+				case Signature.C_SUPER : // SUPER pattern
+					if (argumentBinding.isWildcard()) { // argument is a wildcard
+						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
+						// It's ok if wildcards are identical
+						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+							continue;
+						}
+						// Look for wildcard compatibility
+						switch (wildcardBinding.boundKind) {
+							case Wildcard.EXTENDS:
+								break;
+							case Wildcard.SUPER:
+								if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
+									// valid only when arg super a superclass of pattern
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
+									continue;
+								}
+								break;
+							case Wildcard.UNBOUND:
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
+								continue;
+						}
+					} else if (patternBinding.isCompatibleWith(argumentBinding)) {
+						// valid only when arg is a superclass of pattern
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
+						continue;
+					}
+					break;
+				default:
+					if (argumentBinding.isWildcard()) {
+						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
+						switch (wildcardBinding.boundKind) {
+							case Wildcard.EXTENDS:
+								if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
+									// valid only when arg extends a superclass of pattern
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
+									continue;
+								}
+								break;
+							case Wildcard.SUPER:
+								if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
+									// valid only when arg super a subclass of pattern
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
+									continue;
+								}
+								break;
+							case Wildcard.UNBOUND:
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
+								continue;
+						}
+					} else if (argumentBinding == patternBinding)
+						// valid only when arg is equals to pattern
+						continue;
+					break;
+			}
+
+			// Argument does not match => erasure match will be the only possible one
+			this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+			return;
+		}
+	}
+
+	// Set match rule
+	this.match.setRule(matchRule);
+}
+/**
+ * Finds out whether the given binding matches this search pattern.
+ * Returns ACCURATE_MATCH if it does.
+ * Returns INACCURATE_MATCH if resolve failed but match is still possible.
+ * Returns IMPOSSIBLE_MATCH otherwise.
+ * Default is to return INACCURATE_MATCH.
+ */
+public int resolveLevel(Binding binding) {
+	// override if the pattern can match the binding
+	return INACCURATE_MATCH;
+}
+/**
+ * Returns whether the given type binding matches the given simple name pattern
+ * and qualification pattern.
+ * Note that from since 3.1, this method resolve to accurate member or local types
+ * even if they are not fully qualified (i.e. X.Member instead of p.X.Member).
+ * Returns ACCURATE_MATCH if it does.
+ * Returns INACCURATE_MATCH if resolve failed.
+ * Returns IMPOSSIBLE_MATCH if it doesn't.
+ */
+protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern, TypeBinding binding) {
+//	return resolveLevelForType(qualifiedPattern(simpleNamePattern, qualificationPattern), type);
+	char[] qualifiedPattern = getQualifiedPattern(simpleNamePattern, qualificationPattern);
+	int level = resolveLevelForType(qualifiedPattern, binding);
+	if (level == ACCURATE_MATCH || binding == null  || !binding.isValidBinding()) return level;
+	TypeBinding type = binding instanceof ArrayBinding ? ((ArrayBinding)binding).leafComponentType : binding;
+	char[] sourceName = null;
+	if (type.isMemberType() || type.isLocalType()) {
+		if (qualificationPattern != null) {
+			sourceName =  getQualifiedSourceName(binding);
+		} else {
+			sourceName =  binding.sourceName();
+		}
+	} else if (qualificationPattern == null) {
+		sourceName =  getQualifiedSourceName(binding);
+	}
+	if (sourceName == null) return IMPOSSIBLE_MATCH;
+	switch (this.matchMode) {
+		case SearchPattern.R_PREFIX_MATCH:
+			if (CharOperation.prefixEquals(qualifiedPattern, sourceName, this.isCaseSensitive)) {
+				return ACCURATE_MATCH;
+			}
+			break;
+		case SearchPattern.R_CAMELCASE_MATCH:
+			if ((qualifiedPattern.length>0 && sourceName.length>0 && qualifiedPattern[0] == sourceName[0])) {
+				if (CharOperation.camelCaseMatch(qualifiedPattern, sourceName, false)) {
+					return ACCURATE_MATCH;
+				}
+				if (!this.isCaseSensitive && CharOperation.prefixEquals(qualifiedPattern, sourceName, false)) {
+					return ACCURATE_MATCH;
+				}
+			}
+			break;
+		case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			if ((qualifiedPattern.length>0 && sourceName.length>0 && qualifiedPattern[0] == sourceName[0])) {
+				if (CharOperation.camelCaseMatch(qualifiedPattern, sourceName, true)) {
+					return ACCURATE_MATCH;
+				}
+			}
+			break;
+		default:
+			if (CharOperation.match(qualifiedPattern, sourceName, this.isCaseSensitive)) {
+				return ACCURATE_MATCH;
+			}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+
+/**
+ * Returns whether the given type binding matches the given qualified pattern.
+ * Returns ACCURATE_MATCH if it does.
+ * Returns INACCURATE_MATCH if resolve failed.
+ * Returns IMPOSSIBLE_MATCH if it doesn't.
+ */
+protected int resolveLevelForType(char[] qualifiedPattern, TypeBinding type) {
+	if (qualifiedPattern == null) return ACCURATE_MATCH;
+	if (type == null || !type.isValidBinding()) return INACCURATE_MATCH;
+
+	// Type variable cannot be specified through pattern => this kind of binding cannot match it (see bug 79803)
+	if (type.isTypeVariable()) return IMPOSSIBLE_MATCH;
+
+	// NOTE: if case insensitive search then qualifiedPattern is assumed to be lowercase
+
+	char[] qualifiedPackageName = type.qualifiedPackageName();
+	char[] qualifiedSourceName = qualifiedSourceName(type);
+	char[] fullyQualifiedTypeName = qualifiedPackageName.length == 0
+		? qualifiedSourceName
+		: CharOperation.concat(qualifiedPackageName, qualifiedSourceName, '.');
+	return CharOperation.match(qualifiedPattern, fullyQualifiedTypeName, this.isCaseSensitive)
+		? ACCURATE_MATCH
+		: IMPOSSIBLE_MATCH;
+}
+/* (non-Javadoc)
+ * Resolve level for type with a given binding with all pattern information.
+ */
+protected int resolveLevelForType (char[] simpleNamePattern,
+									char[] qualificationPattern,
+									char[][][] patternTypeArguments,
+									int depth,
+									TypeBinding type) {
+	// standard search with no generic additional information must succeed
+	int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type);
+	if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+	if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0 || depth >= patternTypeArguments.length) {
+		return level;
+	}
+
+	// if pattern is erasure match (see bug 79790), commute impossible to erasure
+	int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;
+
+	// pattern has type parameter(s) or type argument(s)
+	if (type.isGenericType()) {
+		// Binding is generic, get its type variable(s)
+		TypeVariableBinding[] typeVariables = null;
+		if (type instanceof SourceTypeBinding) {
+			SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type;
+			typeVariables = sourceTypeBinding.typeVariables;
+		} else if (type instanceof BinaryTypeBinding) {
+			BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type;
+			if (this.mustResolve)
+				typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance
+		}
+		if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
+			typeVariables != null && typeVariables.length > 0) {
+			if (typeVariables.length != patternTypeArguments[depth].length) return IMPOSSIBLE_MATCH;
+		}
+		// TODO (frederic) do we need to verify each parameter?
+		return level; // we can't do better
+	}
+
+	// raw type always match
+	if (type.isRawType()) {
+		return level;
+	}
+
+	// Standard types (i.e. neither generic nor parameterized nor raw types)
+	// cannot match pattern with type parameters or arguments
+	TypeBinding leafType = type.leafComponentType();
+	if (!leafType.isParameterizedType()) {
+		return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
+	}
+
+	// Parameterized type
+	ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType;
+
+	// Compare arguments only if there ones on both sides
+	if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
+		paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) {
+
+		// type parameters length must match at least specified type names length
+		int length = patternTypeArguments[depth].length;
+		if (paramTypeBinding.arguments.length != length) return IMPOSSIBLE_MATCH;
+
+		// verify each pattern type parameter
+		nextTypeArgument: for (int i= 0; i<length; i++) {
+			char[] patternTypeArgument = patternTypeArguments[depth][i];
+			TypeBinding argTypeBinding = paramTypeBinding.arguments[i];
+			// get corresponding pattern wildcard
+			switch (patternTypeArgument[0]) {
+				case Signature.C_STAR : // unbound parameter always match
+				case Signature.C_SUPER : // needs pattern type parameter binding
+					// skip to next type argument as it will be resolved later
+					continue nextTypeArgument;
+				case Signature.C_EXTENDS :
+					// remove wildcard from patter type argument
+					patternTypeArgument = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length);
+					break;
+				default :
+					// no wildcard
+					break;
+			}
+			// get pattern type argument from its signature
+			patternTypeArgument = Signature.toCharArray(patternTypeArgument);
+			if (!this.isCaseSensitive) patternTypeArgument = CharOperation.toLowerCase(patternTypeArgument);
+			boolean patternTypeArgHasAnyChars = CharOperation.contains(new char[] {'*', '?'}, patternTypeArgument);
+
+			// Verify that names match...
+			// ...special case for wildcard
+			if (argTypeBinding instanceof CaptureBinding) {
+				WildcardBinding capturedWildcard = ((CaptureBinding)argTypeBinding).wildcard;
+				if (capturedWildcard != null) argTypeBinding = capturedWildcard;
+			}
+			if (argTypeBinding.isWildcard()) {
+				WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding;
+				switch (wildcardBinding.boundKind) {
+					case Wildcard.EXTENDS:
+						// Invalid if type argument is not exact
+						if (patternTypeArgHasAnyChars) return impossible;
+						continue nextTypeArgument;
+					case Wildcard.UNBOUND:
+						// there's no bound name to match => valid
+						continue nextTypeArgument;
+				}
+				// Look if bound name match pattern type argument
+				ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound;
+				if (CharOperation.match(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) ||
+					CharOperation.match(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) {
+					// found name in hierarchy => match
+					continue nextTypeArgument;
+				}
+
+				// If pattern is not exact then match fails
+				if (patternTypeArgHasAnyChars) return impossible;
+
+				// Look for bound name in type argument superclasses
+				boundBinding = boundBinding.superclass();
+				while (boundBinding != null) {
+					if (CharOperation.equals(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) ||
+						CharOperation.equals(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) {
+						// found name in hierarchy => match
+						continue nextTypeArgument;
+					} else if (boundBinding.isLocalType() || boundBinding.isMemberType()) {
+						// for local or member type, verify also source name (bug 81084)
+						if (CharOperation.match(patternTypeArgument, boundBinding.sourceName(), this.isCaseSensitive))
+							continue nextTypeArgument;
+					}
+					boundBinding = boundBinding.superclass();
+				}
+				return impossible;
+			}
+
+			// See if names match
+			if (CharOperation.match(patternTypeArgument, argTypeBinding.shortReadableName(), this.isCaseSensitive) ||
+				CharOperation.match(patternTypeArgument, argTypeBinding.readableName(), this.isCaseSensitive)) {
+				continue nextTypeArgument;
+			} else if (argTypeBinding.isLocalType() || argTypeBinding.isMemberType()) {
+				// for local or member type, verify also source name (bug 81084)
+				if (CharOperation.match(patternTypeArgument, argTypeBinding.sourceName(), this.isCaseSensitive))
+					continue nextTypeArgument;
+			}
+
+			// If pattern is not exact then match fails
+			if (patternTypeArgHasAnyChars) return impossible;
+
+			// Scan hierarchy
+			TypeBinding leafTypeBinding = argTypeBinding.leafComponentType();
+			if (leafTypeBinding.isBaseType()) return impossible;
+			ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass();
+			while (refBinding != null) {
+				if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) ||
+					CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) {
+					// found name in hierarchy => match
+					continue nextTypeArgument;
+				} else if (refBinding.isLocalType() || refBinding.isMemberType()) {
+					// for local or member type, verify also source name (bug 81084)
+					if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
+						continue nextTypeArgument;
+				}
+				refBinding = refBinding.superclass();
+			}
+			return impossible;
+		}
+	}
+
+	// Recurse on enclosing type
+	TypeBinding enclosingType = paramTypeBinding.enclosingType();
+	if (enclosingType != null && enclosingType.isParameterizedType() && depth < patternTypeArguments.length && qualificationPattern != null) {
+		int lastDot = CharOperation.lastIndexOf('.', qualificationPattern);
+		char[] enclosingQualificationPattern = lastDot==-1 ? null : CharOperation.subarray(qualificationPattern, 0, lastDot);
+		char[] enclosingSimpleNamePattern = lastDot==-1 ? qualificationPattern : CharOperation.subarray(qualificationPattern, lastDot+1, qualificationPattern.length);
+		int enclosingLevel = resolveLevelForType(enclosingSimpleNamePattern, enclosingQualificationPattern, patternTypeArguments, depth+1, enclosingType);
+		if (enclosingLevel == impossible) return impossible;
+		if (enclosingLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+	}
+	return level;
+}
+public String toString(){
+	return "SearchPattern"; //$NON-NLS-1$
+}
+public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) {
+	// noop by default
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
new file mode 100644
index 0000000..2a967c4
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchDocument;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class PossibleMatch implements ICompilationUnit {
+
+public static final String NO_SOURCE_FILE_NAME = "NO SOURCE FILE NAME"; //$NON-NLS-1$
+public static final char[] NO_SOURCE_FILE = new char[0];
+
+public IResource resource;
+public Openable openable;
+public MatchingNodeSet nodeSet;
+public char[][] compoundName;
+CompilationUnitDeclaration parsedUnit;
+public SearchDocument document;
+private String sourceFileName;
+private char[] source;
+private PossibleMatch similarMatch;
+
+public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document, boolean mustResolve) {
+	this.resource = resource;
+	this.openable = openable;
+	this.document = document;
+	this.nodeSet = new MatchingNodeSet(mustResolve);
+	char[] qualifiedName = getQualifiedName();
+	if (qualifiedName != null)
+		this.compoundName = CharOperation.splitOn('.', qualifiedName);
+}
+public void cleanUp() {
+	this.source = null;
+	if (this.parsedUnit != null) {
+		this.parsedUnit.cleanUp();
+		this.parsedUnit = null;
+	}
+	this.nodeSet = null;
+}
+public boolean equals(Object obj) {
+	if (this.compoundName == null) return super.equals(obj);
+	if (!(obj instanceof PossibleMatch)) return false;
+
+	// By using the compoundName of the source file, multiple .class files (A, A$M...) are considered equal
+	// Even .class files for secondary types and their nested types
+	return CharOperation.equals(this.compoundName, ((PossibleMatch) obj).compoundName);
+}
+public char[] getContents() {
+	char[] contents = (this.source == NO_SOURCE_FILE) ? null : this.source;
+	if (this.source == null) {
+		if (this.openable instanceof ClassFile) {
+			String fileName = getSourceFileName();
+			if (fileName == NO_SOURCE_FILE_NAME) return CharOperation.NO_CHAR;
+
+			SourceMapper sourceMapper = this.openable.getSourceMapper();
+			if (sourceMapper != null) {
+				IType type = ((ClassFile) this.openable).getType();
+				contents = sourceMapper.findSource(type, fileName);
+			}
+		} else {
+			contents = this.document.getCharContents();
+		}
+		this.source = (contents == null) ? NO_SOURCE_FILE : contents;
+	}
+	return contents;
+}
+/**
+ * The exact openable file name. In particular, will be the originating .class file for binary openable with attached
+ * source.
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ * @see PackageReferenceLocator#isDeclaringPackageFragment(IPackageFragment, org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
+ */
+public char[] getFileName() {
+	return this.openable.getElementName().toCharArray();
+}
+public char[] getMainTypeName() {
+	// The file is no longer opened to get its name => remove fix for bug 32182
+	return this.compoundName[this.compoundName.length-1];
+}
+public char[][] getPackageName() {
+	int length = this.compoundName.length;
+	if (length <= 1) return CharOperation.NO_CHAR_CHAR;
+	return CharOperation.subarray(this.compoundName, 0, length - 1);
+}
+/*
+ * Returns the fully qualified name of the main type of the compilation unit
+ * or the main type of the .java file that defined the class file.
+ */
+private char[] getQualifiedName() {
+	if (this.openable instanceof CompilationUnit) {
+		// get file name
+		String fileName = this.openable.getElementName(); // working copy on a .class file may not have a resource, so use the element name
+		// get main type name
+		char[] mainTypeName = Util.getNameWithoutJavaLikeExtension(fileName).toCharArray();
+		CompilationUnit cu = (CompilationUnit) this.openable;
+		return cu.getType(new String(mainTypeName)).getFullyQualifiedName().toCharArray();
+	} else if (this.openable instanceof ClassFile) {
+		String fileName = getSourceFileName();
+		if (fileName == NO_SOURCE_FILE_NAME)
+			return ((ClassFile) this.openable).getType().getFullyQualifiedName('.').toCharArray();
+
+		// Class file may have a source file name with ".java" extension (see bug 73784)
+		int index = Util.indexOfJavaLikeExtension(fileName);
+		String simpleName = index==-1 ? fileName : fileName.substring(0, index);
+		PackageFragment pkg = (PackageFragment) this.openable.getParent();
+		return Util.concatWith(pkg.names, simpleName, '.').toCharArray();
+	}
+	return null;
+}
+PossibleMatch getSimilarMatch() {
+	return this.similarMatch;
+}
+/*
+ * Returns the source file name of the class file.
+ * Returns NO_SOURCE_FILE_NAME if not found.
+ */
+private String getSourceFileName() {
+	if (this.sourceFileName != null) return this.sourceFileName;
+
+	this.sourceFileName = NO_SOURCE_FILE_NAME;
+	if (this.openable.getSourceMapper() != null) {
+		BinaryType type = (BinaryType) ((ClassFile) this.openable).getType();
+		ClassFileReader reader = MatchLocator.classFileReader(type);
+		if (reader != null) {
+			String fileName = type.sourceFileName(reader);
+			this.sourceFileName = fileName == null ? NO_SOURCE_FILE_NAME : fileName;
+		}
+	}
+	return this.sourceFileName;
+}
+boolean hasSimilarMatch() {
+	return this.similarMatch != null && this.source == NO_SOURCE_FILE;
+}
+public int hashCode() {
+	if (this.compoundName == null) return super.hashCode();
+
+	int hashCode = 0;
+	for (int i = 0, length = this.compoundName.length; i < length; i++)
+		hashCode += CharOperation.hashCode(this.compoundName[i]);
+	return hashCode;
+}
+public boolean ignoreOptionalProblems() {
+	return false;
+}
+void setSimilarMatch(PossibleMatch possibleMatch) {
+	// source does not matter on similar match as it is read on
+	// the first stored possible match
+	possibleMatch.source = NO_SOURCE_FILE;
+	this.similarMatch = possibleMatch;
+}
+public String toString() {
+	return this.openable == null ? "Fake PossibleMatch" : this.openable.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java
new file mode 100644
index 0000000..df8ef79
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
+/**
+ * A set of PossibleMatches that is sorted by package fragment roots.
+ */
+public class PossibleMatchSet {
+
+private SimpleLookupTable rootsToPossibleMatches = new SimpleLookupTable(5);
+private int elementCount = 0;
+
+public void add(PossibleMatch possibleMatch) {
+	IPath path = possibleMatch.openable.getPackageFragmentRoot().getPath();
+	ObjectVector possibleMatches = (ObjectVector) this.rootsToPossibleMatches.get(path);
+	if (possibleMatches != null) {
+		PossibleMatch storedMatch = (PossibleMatch) possibleMatches.find(possibleMatch);
+		if (storedMatch != null) {
+			while (storedMatch.getSimilarMatch() != null) {
+				storedMatch = storedMatch.getSimilarMatch();
+			}
+			storedMatch.setSimilarMatch(possibleMatch);
+			return;
+		}
+	} else{
+		this.rootsToPossibleMatches.put(path, possibleMatches = new ObjectVector());
+	}
+
+	possibleMatches.add(possibleMatch);
+	this.elementCount++;
+}
+public PossibleMatch[] getPossibleMatches(IPackageFragmentRoot[] roots) {
+	PossibleMatch[] result = new PossibleMatch[this.elementCount];
+	int index = 0;
+	for (int i = 0, length = roots.length; i < length; i++) {
+		ObjectVector possibleMatches = (ObjectVector) this.rootsToPossibleMatches.get(roots[i].getPath());
+		if (possibleMatches != null) {
+			possibleMatches.copyInto(result, index);
+			index += possibleMatches.size();
+		}
+	}
+	if (index < this.elementCount)
+		System.arraycopy(result, 0, result = new PossibleMatch[index], 0, index);
+	return result;
+}
+public void reset() {
+	this.rootsToPossibleMatches = new SimpleLookupTable(5);
+	this.elementCount = 0;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
new file mode 100644
index 0000000..42f0e7d
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+
+public class QualifiedTypeDeclarationPattern extends TypeDeclarationPattern {
+
+public char[] qualification;
+PackageDeclarationPattern packagePattern;
+public int packageIndex = -1;
+
+public QualifiedTypeDeclarationPattern(char[] qualification, char[] simpleName, char typeSuffix, int matchRule) {
+	this(matchRule);
+
+	this.qualification = this.isCaseSensitive ? qualification : CharOperation.toLowerCase(qualification);
+	this.simpleName = (this.isCaseSensitive || this.isCamelCase) ? simpleName : CharOperation.toLowerCase(simpleName);
+	this.typeSuffix = typeSuffix;
+
+	this.mustResolve = this.qualification != null || typeSuffix != TYPE_SUFFIX;
+}
+public QualifiedTypeDeclarationPattern(char[] qualification, int qualificationMatchRule, char[] simpleName, char typeSuffix, int matchRule) {
+	this(qualification, simpleName, typeSuffix, matchRule);
+	this.packagePattern = new PackageDeclarationPattern(qualification, qualificationMatchRule);
+}
+QualifiedTypeDeclarationPattern(int matchRule) {
+	super(matchRule);
+}
+public void decodeIndexKey(char[] key) {
+	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+	this.simpleName = CharOperation.subarray(key, 0, slash);
+
+	int start = ++slash;
+	if (key[start] == SEPARATOR) {
+		this.pkg = CharOperation.NO_CHAR;
+	} else {
+		slash = CharOperation.indexOf(SEPARATOR, key, start);
+		this.pkg = internedPackageNames.add(CharOperation.subarray(key, start, slash));
+	}
+	this.qualification = this.pkg;
+
+	// Continue key read by the end to decode modifiers
+	int last = key.length-1;
+	this.secondary = key[last] == 'S';
+	if (this.secondary) {
+		last -= 2;
+	}
+	this.modifiers = key[last-1] + (key[last]<<16);
+	decodeModifiers();
+
+	// Retrieve enclosing type names
+	start = slash + 1;
+	last -= 2; // position of ending slash
+	if (start == last) {
+		this.enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+	} else {
+		int length = this.qualification.length;
+		int size = last - start;
+		System.arraycopy(this.qualification, 0, this.qualification = new char[length+1+size], 0, length);
+		this.qualification[length] = '.';
+		if (last == (start+1) && key[start] == ZERO_CHAR) {
+			this.enclosingTypeNames = ONE_ZERO_CHAR;
+			this.qualification[length+1] = ZERO_CHAR;
+		} else {
+			this.enclosingTypeNames = CharOperation.splitOn('.', key, start, last);
+			System.arraycopy(key, start, this.qualification, length+1, size);
+		}
+	}
+}
+public SearchPattern getBlankPattern() {
+	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
+
+	// check type suffix
+	if (this.typeSuffix != pattern.typeSuffix && this.typeSuffix != TYPE_SUFFIX) {
+		if (!matchDifferentTypeSuffixes(this.typeSuffix, pattern.typeSuffix)) {
+			return false;
+		}
+	}
+
+	// check name
+	return matchesName(this.simpleName, pattern.simpleName) &&
+		(this.qualification == null || this.packagePattern == null || this.packagePattern.matchesName(this.qualification, pattern.qualification));
+}
+protected StringBuffer print(StringBuffer output) {
+	switch (this.typeSuffix){
+		case CLASS_SUFFIX :
+			output.append("ClassDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case CLASS_AND_INTERFACE_SUFFIX:
+			output.append("ClassAndInterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case CLASS_AND_ENUM_SUFFIX :
+			output.append("ClassAndEnumDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case INTERFACE_SUFFIX :
+			output.append("InterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case INTERFACE_AND_ANNOTATION_SUFFIX:
+			output.append("InterfaceAndAnnotationDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case ENUM_SUFFIX :
+			output.append("EnumDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		case ANNOTATION_TYPE_SUFFIX :
+			output.append("AnnotationTypeDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+		default :
+			output.append("TypeDeclarationPattern: qualification<"); //$NON-NLS-1$
+			break;
+	}
+	if (this.qualification != null)
+		output.append(this.qualification);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">, type<"); //$NON-NLS-1$
+	if (this.simpleName != null)
+		output.append(this.simpleName);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append("> "); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SecondaryTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SecondaryTypeDeclarationPattern.java
new file mode 100644
index 0000000..f6714a8
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SecondaryTypeDeclarationPattern.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.index.EntryResult;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class SecondaryTypeDeclarationPattern extends TypeDeclarationPattern {
+
+	private final static char[] SECONDARY_PATTERN_KEY = "*/S".toCharArray(); //$NON-NLS-1$
+
+public SecondaryTypeDeclarationPattern() {
+	super(null, null, null, IIndexConstants.SECONDARY_SUFFIX, R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+
+public SecondaryTypeDeclarationPattern(int matchRule) {
+	super(matchRule);
+}
+
+public SearchPattern getBlankPattern() {
+	return new SecondaryTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+protected StringBuffer print(StringBuffer output) {
+	output.append("Secondary"); //$NON-NLS-1$
+	return super.print(output);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.TypeDeclarationPattern#queryIn(org.eclipse.jdt.internal.core.index.Index)
+ */
+public EntryResult[] queryIn(Index index) throws IOException {
+	return index.query(CATEGORIES, SECONDARY_PATTERN_KEY, R_PATTERN_MATCH | R_CASE_SENSITIVE);
+}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java
new file mode 100644
index 0000000..3b45099
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.ast.Initializer;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
+import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.search.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Collects the super type names of a given declaring type.
+ * Returns NOT_FOUND_DECLARING_TYPE if the declaring type was not found.
+ * Returns null if the declaring type pattern doesn't require an exact match.
+ */
+public class SuperTypeNamesCollector {
+
+	/**
+	 * An ast visitor that visits type declarations and member type declarations
+	 * collecting their super type names.
+	 */
+	public class TypeDeclarationVisitor extends ASTVisitor {
+		public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+			ReferenceBinding binding = typeDeclaration.binding;
+			if (SuperTypeNamesCollector.this.matches(binding))
+				collectSuperTypeNames(binding, binding.compoundName);
+			return true;
+		}
+		public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
+			ReferenceBinding binding = typeDeclaration.binding;
+			if (SuperTypeNamesCollector.this.matches(binding))
+				collectSuperTypeNames(binding, binding.compoundName);
+			return true;
+		}
+		public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
+			ReferenceBinding binding = memberTypeDeclaration.binding;
+			if (SuperTypeNamesCollector.this.matches(binding))
+				collectSuperTypeNames(binding, binding.compoundName);
+			return true;
+		}
+		public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
+			return false; // don't visit field declarations
+		}
+		public boolean visit(Initializer initializer, MethodScope scope) {
+			return false; // don't visit initializers
+		}
+		public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
+			return false; // don't visit constructor declarations
+		}
+		public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
+			return false; // don't visit method declarations
+		}
+	}
+SearchPattern pattern;
+char[] typeSimpleName;
+char[] typeQualification;
+MatchLocator locator;
+IType type;
+IProgressMonitor progressMonitor;
+char[][][] result;
+int resultIndex;
+
+char[][][] samePackageSuperTypeName; // set only if focus is null
+int samePackageIndex;
+
+public SuperTypeNamesCollector(
+	SearchPattern pattern,
+	char[] typeSimpleName,
+	char[] typeQualification,
+	MatchLocator locator,
+	IType type,
+	IProgressMonitor progressMonitor) {
+
+	this.pattern = pattern;
+	this.typeSimpleName = typeSimpleName;
+	this.typeQualification = typeQualification;
+	this.locator = locator;
+	this.type = type;
+	this.progressMonitor = progressMonitor;
+}
+
+private boolean addIfSamePackage(char[][] compoundName, char[][] path) {
+	if (compoundName.length != path.length) return false;
+	int resultLength = this.samePackageSuperTypeName.length;
+	for (int i = 0; i < resultLength; i++)
+		if (CharOperation.equals(this.samePackageSuperTypeName[i], compoundName)) return false; // already known
+	
+	for (int i = 0, length = compoundName.length - 1; i < length; i ++) {
+		if (!CharOperation.equals(compoundName[i], path[i])) return false;
+	}
+	if (resultLength == this.samePackageIndex)
+		System.arraycopy(this.samePackageSuperTypeName, 0, this.samePackageSuperTypeName = new char[resultLength*2][][], 0, resultLength);
+	this.samePackageSuperTypeName[this.samePackageIndex++] = compoundName;
+	return true;
+}
+
+protected void addToResult(char[][] compoundName) {
+	int resultLength = this.result.length;
+	for (int i = 0; i < resultLength; i++)
+		if (CharOperation.equals(this.result[i], compoundName)) return; // already known
+
+	if (resultLength == this.resultIndex)
+		System.arraycopy(this.result, 0, this.result = new char[resultLength*2][][], 0, resultLength);
+	this.result[this.resultIndex++] = compoundName;
+}
+
+/*
+ * Parse the given compilation unit and build its type bindings.
+ */
+protected CompilationUnitDeclaration buildBindings(ICompilationUnit compilationUnit, boolean isTopLevelOrMember) throws JavaModelException {
+	// source unit
+	org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnit;
+
+	CompilationResult compilationResult = new CompilationResult(sourceUnit, 1, 1, 0);
+	CompilationUnitDeclaration unit =
+		isTopLevelOrMember ?
+			this.locator.basicParser().dietParse(sourceUnit, compilationResult) :
+			this.locator.basicParser().parse(sourceUnit, compilationResult);
+	if (unit != null) {
+		this.locator.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);
+		this.locator.lookupEnvironment.completeTypeBindings(unit, !isTopLevelOrMember);
+		if (!isTopLevelOrMember) {
+			if (unit.scope != null)
+				unit.scope.faultInTypes(); // fault in fields & methods
+			unit.resolve();
+		}
+	}
+	return unit;
+}
+public char[][][] collect() throws JavaModelException {
+	if (this.type != null) {
+		// Collect the paths of the cus that are in the hierarchy of the given type
+		this.result = new char[1][][];
+		this.resultIndex = 0;
+		JavaProject javaProject = (JavaProject) this.type.getJavaProject();
+		this.locator.initialize(javaProject, 0);
+		try {
+			if (this.type.isBinary()) {
+				BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null);
+				if (binding != null)
+					collectSuperTypeNames(binding, null);
+			} else {
+				ICompilationUnit unit = this.type.getCompilationUnit();
+				SourceType sourceType = (SourceType) this.type;
+				boolean isTopLevelOrMember = sourceType.getOuterMostLocalContext() == null;
+				CompilationUnitDeclaration parsedUnit = buildBindings(unit, isTopLevelOrMember);
+				if (parsedUnit != null) {
+					TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type);
+					if (typeDecl != null && typeDecl.binding != null)
+						collectSuperTypeNames(typeDecl.binding, null);
+				}
+			}
+		} catch (AbortCompilation e) {
+			// problem with classpath: report inaccurate matches
+			return null;
+		}
+		if (this.result.length > this.resultIndex)
+			System.arraycopy(this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
+		return this.result;
+	}
+
+	// Collect the paths of the cus that declare a type which matches declaringQualification + declaringSimpleName
+	String[] paths = getPathsOfDeclaringType();
+	if (paths == null) return null;
+
+	// Create bindings from source types and binary types and collect super type names of the type declaration
+	// that match the given declaring type
+	Util.sort(paths); // sort by projects
+	JavaProject previousProject = null;
+	this.result = new char[1][][];
+	this.samePackageSuperTypeName = new char[1][][];
+	this.resultIndex = 0;
+	for (int i = 0, length = paths.length; i < length; i++) {
+		try {
+			Openable openable = this.locator.handleFactory.createOpenable(paths[i], this.locator.scope);
+			if (openable == null) continue; // outside classpath
+
+			IJavaProject project = openable.getJavaProject();
+			if (!project.equals(previousProject)) {
+				previousProject = (JavaProject) project;
+				this.locator.initialize(previousProject, 0);
+			}
+			if (openable instanceof ICompilationUnit) {
+				ICompilationUnit unit = (ICompilationUnit) openable;
+				CompilationUnitDeclaration parsedUnit = buildBindings(unit, true /*only top level and member types are visible to the focus type*/);
+				if (parsedUnit != null)
+					parsedUnit.traverse(new TypeDeclarationVisitor(), parsedUnit.scope);
+			} else if (openable instanceof IClassFile) {
+				IClassFile classFile = (IClassFile) openable;
+				BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null);
+				if (matches(binding))
+					collectSuperTypeNames(binding, binding.compoundName);
+			}
+		} catch (AbortCompilation e) {
+			// ignore: continue with next element
+		} catch (JavaModelException e) {
+			// ignore: continue with next element
+		}
+	}
+	if (this.result.length > this.resultIndex)
+		System.arraycopy(this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
+	return this.result;
+}
+/**
+ * Collects the names of all the supertypes of the given type.
+ */
+protected void collectSuperTypeNames(ReferenceBinding binding, char[][] path) {
+	ReferenceBinding superclass = binding.superclass();
+	if (path != null && superclass != null) {
+		boolean samePackage = addIfSamePackage(superclass.compoundName, path);
+		if (!samePackage) path = null;
+	}
+	if (superclass != null) {
+		addToResult(superclass.compoundName);
+		collectSuperTypeNames(superclass, path);
+	}
+
+	ReferenceBinding[] interfaces = binding.superInterfaces();
+	if (interfaces != null) {
+		for (int i = 0; i < interfaces.length; i++) {
+			ReferenceBinding interfaceBinding = interfaces[i];
+			addToResult(interfaceBinding.compoundName);
+			collectSuperTypeNames(interfaceBinding, path);
+		}
+	}
+}
+protected String[] getPathsOfDeclaringType() {
+	if (this.typeQualification == null && this.typeSimpleName == null) return null;
+
+	final PathCollector pathCollector = new PathCollector();
+	IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
+	IndexManager indexManager = JavaModelManager.getIndexManager();
+	SearchPattern searchPattern = new TypeDeclarationPattern(
+		this.typeSimpleName != null ? null : this.typeQualification, // use the qualification only if no simple name
+		null, // do find member types
+		this.typeSimpleName,
+		IIndexConstants.TYPE_SUFFIX,
+		this.pattern.getMatchRule());
+	IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+			TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+			if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR) {  // filter out local and anonymous classes
+				pathCollector.acceptIndexMatch(documentPath, indexRecord, participant, access);
+			}
+			return true;
+		}
+	};
+
+	indexManager.performConcurrentJob(
+		new PatternSearchJob(
+			searchPattern,
+			new JavaSearchParticipant(),
+			scope,
+			searchRequestor),
+		IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+		this.progressMonitor == null ? null : new SubProgressMonitor(this.progressMonitor, 100));
+	return pathCollector.getPaths();
+}
+public char[][][] getSamePackageSuperTypeNames() {
+	return this.samePackageSuperTypeName;
+}
+protected boolean matches(char[][] compoundName) {
+	int length = compoundName.length;
+	if (length == 0) return false;
+	char[] simpleName = compoundName[length-1];
+	int last = length - 1;
+	if (this.typeSimpleName == null || this.pattern.matchesName(simpleName, this.typeSimpleName)) {
+		// most frequent case: simple name equals last segment of compoundName
+		char[][] qualification = new char[last][];
+		System.arraycopy(compoundName, 0, qualification, 0, last);
+		return this.pattern.matchesName(this.typeQualification, CharOperation.concatWith(qualification, '.'));
+	}
+
+	if (!CharOperation.endsWith(simpleName, this.typeSimpleName)) return false;
+
+	// member type -> transform A.B.C$D into A.B.C.D
+	System.arraycopy(compoundName, 0, compoundName = new char[length+1][], 0, last);
+	int dollar = CharOperation.indexOf('$', simpleName);
+	if (dollar == -1) return false;
+	compoundName[last] = CharOperation.subarray(simpleName, 0, dollar);
+	compoundName[length] = CharOperation.subarray(simpleName, dollar+1, simpleName.length);
+	return this.matches(compoundName);
+}
+protected boolean matches(ReferenceBinding binding) {
+	return binding != null && binding.compoundName != null && this.matches(binding.compoundName);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java
new file mode 100644
index 0000000..1143687
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class SuperTypeReferenceLocator extends PatternLocator {
+
+protected SuperTypeReferencePattern pattern;
+
+public SuperTypeReferenceLocator(SuperTypeReferencePattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+//public int match(ASTNode node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(TypeReference node, MatchingNodeSet nodeSet) {
+	if (this.flavors != SUPERTYPE_REF_FLAVOR) return IMPOSSIBLE_MATCH;
+	if (this.pattern.superSimpleName == null)
+		return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+
+	char[] typeRefSimpleName = null;
+	if (node instanceof SingleTypeReference) {
+		typeRefSimpleName = ((SingleTypeReference) node).token;
+	} else { // QualifiedTypeReference
+		char[][] tokens = ((QualifiedTypeReference) node).tokens;
+		typeRefSimpleName = tokens[tokens.length-1];
+	}
+	if (matchesName(this.pattern.superSimpleName, typeRefSimpleName))
+		return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+
+	return IMPOSSIBLE_MATCH;
+}
+
+protected int matchContainer() {
+	return CLASS_CONTAINER;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, org.eclipse.jdt.internal.compiler.lookup.Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	if (elementBinding instanceof ReferenceBinding) {
+		ReferenceBinding referenceBinding = (ReferenceBinding) elementBinding;
+		if (referenceBinding.isClass() && this.pattern.typeSuffix == IIndexConstants.INTERFACE_SUFFIX) {
+			// do not report class if expected types are only interfaces
+			return;
+		}
+		if (referenceBinding.isInterface() && this.pattern.typeSuffix == IIndexConstants.CLASS_SUFFIX) {
+			// do not report interface if expected types are only classes
+			return;
+		}
+	}
+	super.matchReportReference(reference, element, elementBinding, accuracy, locator);
+}
+protected int referenceType() {
+	return IJavaElement.TYPE;
+}
+public int resolveLevel(ASTNode node) {
+	if (!(node instanceof TypeReference)) return IMPOSSIBLE_MATCH;
+
+	TypeReference typeRef = (TypeReference) node;
+	TypeBinding typeBinding = typeRef.resolvedType;
+	if (typeBinding instanceof ArrayBinding)
+		typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+	if (typeBinding instanceof ProblemReferenceBinding)
+		typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch();
+
+	if (typeBinding == null || !typeBinding.isValidBinding()) return INACCURATE_MATCH;
+	return resolveLevelForType(this.pattern.superSimpleName, this.pattern.superQualification, typeBinding);
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof ReferenceBinding)) return IMPOSSIBLE_MATCH;
+
+	ReferenceBinding type = (ReferenceBinding) binding;
+	int level = IMPOSSIBLE_MATCH;
+	if (this.pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_INTERFACES) {
+		level = resolveLevelForType(this.pattern.superSimpleName, this.pattern.superQualification, type.superclass());
+		if (level == ACCURATE_MATCH) return ACCURATE_MATCH;
+	}
+
+	if (this.pattern.superRefKind != SuperTypeReferencePattern.ONLY_SUPER_CLASSES) {
+		ReferenceBinding[] superInterfaces = type.superInterfaces();
+		for (int i = 0, max = superInterfaces.length; i < max; i++) {
+			int newLevel = resolveLevelForType(this.pattern.superSimpleName, this.pattern.superQualification, superInterfaces[i]);
+			if (newLevel > level) {
+				if (newLevel == ACCURATE_MATCH) return ACCURATE_MATCH;
+				level = newLevel;
+			}
+		}
+	}
+	return level;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java
new file mode 100644
index 0000000..687eccf
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.core.index.*;
+
+public class SuperTypeReferencePattern extends JavaSearchPattern {
+
+public char[] superQualification;
+public char[] superSimpleName;
+public char superClassOrInterface;
+
+// set to CLASS_SUFFIX for only matching classes
+// set to INTERFACE_SUFFIX for only matching interfaces
+// set to TYPE_SUFFIX for matching both classes and interfaces
+public char typeSuffix;
+public char[] pkgName;
+public char[] simpleName;
+public char[] enclosingTypeName;
+public char classOrInterface;
+public int modifiers;
+public char[][] typeParameterSignatures;
+
+protected int superRefKind;
+public static final int ALL_SUPER_TYPES = 0;
+public static final int ONLY_SUPER_INTERFACES = 1; // used for IMPLEMENTORS
+public static final int ONLY_SUPER_CLASSES = 2; // used for hierarchy with a class focus
+
+protected static char[][] CATEGORIES = { SUPER_REF };
+
+public static char[] createIndexKey(
+	int modifiers,
+	char[] packageName,
+	char[] typeName,
+	char[][] enclosingTypeNames,
+	char[][] typeParameterSignatures,
+	char classOrInterface,
+	char[] superTypeName,
+	char superClassOrInterface) {
+
+	if (superTypeName == null)
+		superTypeName = OBJECT;
+	char[] superSimpleName = CharOperation.lastSegment(superTypeName, '.');
+	char[] superQualification = null;
+	if (superSimpleName != superTypeName) {
+		int length = superTypeName.length - superSimpleName.length - 1;
+		superQualification = new char[length];
+		System.arraycopy(superTypeName, 0, superQualification, 0, length);
+	}
+
+	// if the supertype name contains a $, then split it into: source name and append the $ prefix to the qualification
+	//	e.g. p.A$B ---> p.A$ + B
+	char[] superTypeSourceName = CharOperation.lastSegment(superSimpleName, '$');
+	if (superTypeSourceName != superSimpleName) {
+		int start = superQualification == null ? 0 : superQualification.length + 1;
+		int prefixLength = superSimpleName.length - superTypeSourceName.length;
+		char[] mangledQualification = new char[start + prefixLength];
+		if (superQualification != null) {
+			System.arraycopy(superQualification, 0, mangledQualification, 0, start-1);
+			mangledQualification[start-1] = '.';
+		}
+		System.arraycopy(superSimpleName, 0, mangledQualification, start, prefixLength);
+		superQualification = mangledQualification;
+		superSimpleName = superTypeSourceName;
+	}
+
+	char[] simpleName = CharOperation.lastSegment(typeName, '.');
+	char[] enclosingTypeName = CharOperation.concatWith(enclosingTypeNames, '$');
+	if (superQualification != null && CharOperation.equals(superQualification, packageName))
+		packageName = ONE_ZERO; // save some space
+
+	char[] typeParameters = CharOperation.NO_CHAR;
+	int typeParametersLength = 0;
+	if (typeParameterSignatures != null) {
+		StringBuffer buffer = new StringBuffer();
+		for (int i = 0, length = typeParameterSignatures.length; i < length; i++) {
+			char[] typeParameter = typeParameterSignatures[i];
+			buffer.append(typeParameter);
+			typeParametersLength += typeParameter.length;
+			if (i != length-1) {
+				buffer.append(',');
+				typeParametersLength++;
+			}
+		}
+		typeParameters = new char[typeParametersLength];
+		buffer.getChars(0, typeParametersLength, typeParameters, 0);
+	}
+
+	// superSimpleName / superQualification / simpleName / enclosingTypeName / typeParameters / packageName / superClassOrInterface classOrInterface modifiers
+	int superLength = superSimpleName == null ? 0 : superSimpleName.length;
+	int superQLength = superQualification == null ? 0 : superQualification.length;
+	int simpleLength = simpleName == null ? 0 : simpleName.length;
+	int enclosingLength = enclosingTypeName == null ? 0 : enclosingTypeName.length;
+	int packageLength = packageName == null ? 0 : packageName.length;
+	char[] result = new char[superLength + superQLength + simpleLength + enclosingLength + typeParametersLength + packageLength + 9];
+	int pos = 0;
+	if (superLength > 0) {
+		System.arraycopy(superSimpleName, 0, result, pos, superLength);
+		pos += superLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (superQLength > 0) {
+		System.arraycopy(superQualification, 0, result, pos, superQLength);
+		pos += superQLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (simpleLength > 0) {
+		System.arraycopy(simpleName, 0, result, pos, simpleLength);
+		pos += simpleLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (enclosingLength > 0) {
+		System.arraycopy(enclosingTypeName, 0, result, pos, enclosingLength);
+		pos += enclosingLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (typeParametersLength > 0) {
+		System.arraycopy(typeParameters, 0, result, pos, typeParametersLength);
+		pos += typeParametersLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (packageLength > 0) {
+		System.arraycopy(packageName, 0, result, pos, packageLength);
+		pos += packageLength;
+	}
+	result[pos++] = SEPARATOR;
+	result[pos++] = superClassOrInterface;
+	result[pos++] = classOrInterface;
+	result[pos] = (char) modifiers;
+	return result;
+}
+
+public SuperTypeReferencePattern(
+	char[] superQualification,
+	char[] superSimpleName,
+	int superRefKind,
+	int matchRule) {
+
+	this(matchRule);
+
+	this.superQualification = this.isCaseSensitive ? superQualification : CharOperation.toLowerCase(superQualification);
+	this.superSimpleName = (this.isCaseSensitive || this.isCamelCase) ? superSimpleName : CharOperation.toLowerCase(superSimpleName);
+	this.mustResolve = superQualification != null;
+	this.superRefKind = superRefKind;
+}
+public SuperTypeReferencePattern(
+	char[] superQualification,
+	char[] superSimpleName,
+	int superRefKind,
+	char typeSuffix,
+	int matchRule) {
+
+	this(superQualification, superSimpleName, superRefKind, matchRule);
+	this.typeSuffix = typeSuffix;
+	this.mustResolve = superQualification != null || typeSuffix != TYPE_SUFFIX;
+}
+SuperTypeReferencePattern(int matchRule) {
+	super(SUPER_REF_PATTERN, matchRule);
+}
+/*
+ * superSimpleName / superQualification / simpleName / enclosingTypeName / typeParameters / pkgName / superClassOrInterface classOrInterface modifiers
+ */
+public void decodeIndexKey(char[] key) {
+	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+	this.superSimpleName = CharOperation.subarray(key, 0, slash);
+
+	// some values may not have been know when indexed so decode as null
+	int start = slash + 1;
+	slash = CharOperation.indexOf(SEPARATOR, key, start);
+	this.superQualification = slash == start ? null : CharOperation.subarray(key, start, slash);
+
+	slash = CharOperation.indexOf(SEPARATOR, key, start = slash + 1);
+	this.simpleName = CharOperation.subarray(key, start, slash);
+
+	start = ++slash;
+	if (key[start] == SEPARATOR) {
+		this.enclosingTypeName = null;
+	} else {
+		slash = CharOperation.indexOf(SEPARATOR, key, start);
+		if (slash == (start+1) && key[start] == ZERO_CHAR) {
+			this.enclosingTypeName = ONE_ZERO;
+		} else {
+			char[] names = CharOperation.subarray(key, start, slash);
+			this.enclosingTypeName = names;
+		}
+	}
+
+	start = ++slash;
+	if (key[start] == SEPARATOR) {
+		this.typeParameterSignatures = null;
+	} else {
+		slash = CharOperation.indexOf(SEPARATOR, key, start);
+		this.typeParameterSignatures = CharOperation.splitOn(',', key, start, slash);
+	}
+
+	start = ++slash;
+	if (key[start] == SEPARATOR) {
+		this.pkgName = null;
+	} else {
+		slash = CharOperation.indexOf(SEPARATOR, key, start);
+		if (slash == (start+1) && key[start] == ZERO_CHAR) {
+			this.pkgName = this.superQualification;
+		} else {
+			char[] names = CharOperation.subarray(key, start, slash);
+			this.pkgName = names;
+		}
+	}
+
+	this.superClassOrInterface = key[slash + 1];
+	this.classOrInterface = key[slash + 2];
+	this.modifiers = key[slash + 3]; // implicit cast to int type
+}
+public SearchPattern getBlankPattern() {
+	return new SuperTypeReferencePattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	return CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	SuperTypeReferencePattern pattern = (SuperTypeReferencePattern) decodedPattern;
+	if (this.superRefKind == ONLY_SUPER_CLASSES && pattern.enclosingTypeName != ONE_ZERO/*not an anonymous*/)
+		// consider enumerations as classes, reject interfaces and annotations
+		if (pattern.superClassOrInterface == INTERFACE_SUFFIX
+			|| pattern.superClassOrInterface == ANNOTATION_TYPE_SUFFIX)
+			return false;
+
+	if (pattern.superQualification != null)
+		if (!matchesName(this.superQualification, pattern.superQualification)) return false;
+
+	return matchesName(this.superSimpleName, pattern.superSimpleName);
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+	char[] key = this.superSimpleName; // can be null
+	int matchRule = getMatchRule();
+
+	// cannot include the superQualification since it may not exist in the index
+	switch(getMatchMode()) {
+		case R_EXACT_MATCH :
+			// do a prefix query with the superSimpleName
+			matchRule &= ~R_EXACT_MATCH;
+			matchRule |= R_PREFIX_MATCH;
+			if (this.superSimpleName != null)
+				key = CharOperation.append(this.superSimpleName, SEPARATOR);
+			break;
+		case R_PREFIX_MATCH :
+			// do a prefix query with the superSimpleName
+			break;
+		case R_PATTERN_MATCH :
+			// do a pattern query with the superSimpleName
+			break;
+		case R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+		case R_CAMELCASE_MATCH:
+		case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			// do a prefix query with the superSimpleName
+			break;
+	}
+
+	return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+}
+protected StringBuffer print(StringBuffer output) {
+	switch (this.superRefKind) {
+		case ALL_SUPER_TYPES:
+			output.append("SuperTypeReferencePattern: <"); //$NON-NLS-1$
+			break;
+		case ONLY_SUPER_INTERFACES:
+			output.append("SuperInterfaceReferencePattern: <"); //$NON-NLS-1$
+			break;
+		case ONLY_SUPER_CLASSES:
+			output.append("SuperClassReferencePattern: <"); //$NON-NLS-1$
+			break;
+	}
+	if (this.superSimpleName != null)
+		output.append(this.superSimpleName);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
new file mode 100644
index 0000000..bdbd12a
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+public class TypeDeclarationLocator extends PatternLocator {
+
+protected TypeDeclarationPattern pattern; // can be a QualifiedTypeDeclarationPattern
+
+public TypeDeclarationLocator(TypeDeclarationPattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+//public int match(ASTNode node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
+	if (this.pattern.simpleName == null || matchesName(this.pattern.simpleName, node.name))
+		return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+
+	return IMPOSSIBLE_MATCH;
+}
+//public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
+
+public int resolveLevel(ASTNode node) {
+	if (!(node instanceof TypeDeclaration)) return IMPOSSIBLE_MATCH;
+
+	return resolveLevel(((TypeDeclaration) node).binding);
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof TypeBinding)) return IMPOSSIBLE_MATCH;
+
+	TypeBinding type = (TypeBinding) binding;
+
+	switch (this.pattern.typeSuffix) {
+		case CLASS_SUFFIX:
+			if (!type.isClass()) return IMPOSSIBLE_MATCH;
+			break;
+		case CLASS_AND_INTERFACE_SUFFIX:
+			if (!(type.isClass() || (type.isInterface() && !type.isAnnotationType()))) return IMPOSSIBLE_MATCH;
+			break;
+		case CLASS_AND_ENUM_SUFFIX:
+			if (!(type.isClass() || type.isEnum())) return IMPOSSIBLE_MATCH;
+			break;
+		case INTERFACE_SUFFIX:
+			if (!type.isInterface() || type.isAnnotationType()) return IMPOSSIBLE_MATCH;
+			break;
+		case INTERFACE_AND_ANNOTATION_SUFFIX:
+			if (!(type.isInterface() || type.isAnnotationType())) return IMPOSSIBLE_MATCH;
+			break;
+		case ENUM_SUFFIX:
+			if (!type.isEnum()) return IMPOSSIBLE_MATCH;
+			break;
+		case ANNOTATION_TYPE_SUFFIX:
+			if (!type.isAnnotationType()) return IMPOSSIBLE_MATCH;
+			break;
+		case TYPE_SUFFIX : // nothing
+	}
+
+	// fully qualified name
+	if (this.pattern instanceof QualifiedTypeDeclarationPattern) {
+		QualifiedTypeDeclarationPattern qualifiedPattern = (QualifiedTypeDeclarationPattern) this.pattern;
+		return resolveLevelForType(qualifiedPattern.simpleName, qualifiedPattern.qualification, type);
+	} else {
+		char[] enclosingTypeName = this.pattern.enclosingTypeNames == null ? null : CharOperation.concatWith(this.pattern.enclosingTypeNames, '.');
+		return resolveLevelForType(this.pattern.simpleName, this.pattern.pkg, enclosingTypeName, type);
+	}
+}
+/**
+ * Returns whether the given type binding matches the given simple name pattern
+ * qualification pattern and enclosing type name pattern.
+ */
+protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern, char[] enclosingNamePattern, TypeBinding type) {
+	if (enclosingNamePattern == null)
+		return resolveLevelForType(simpleNamePattern, qualificationPattern, type);
+	if (qualificationPattern == null)
+		return resolveLevelForType(simpleNamePattern, enclosingNamePattern, type);
+
+	// case of an import reference while searching for ALL_OCCURENCES of a type (see bug 37166)
+	if (type instanceof ProblemReferenceBinding) return IMPOSSIBLE_MATCH;
+
+	// pattern was created from a Java element: qualification is the package name.
+	char[] fullQualificationPattern = CharOperation.concat(qualificationPattern, enclosingNamePattern, '.');
+	if (CharOperation.equals(this.pattern.pkg, CharOperation.concatWith(type.getPackage().compoundName, '.')))
+		return resolveLevelForType(simpleNamePattern, fullQualificationPattern, type);
+	return IMPOSSIBLE_MATCH;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
new file mode 100644
index 0000000..ea813ef
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.core.index.*;
+
+public class TypeDeclarationPattern extends JavaSearchPattern {
+
+public char[] simpleName;
+public char[] pkg;
+public char[][] enclosingTypeNames;
+
+// set to CLASS_SUFFIX for only matching classes
+// set to INTERFACE_SUFFIX for only matching interfaces
+// set to ENUM_SUFFIX for only matching enums
+// set to ANNOTATION_TYPE_SUFFIX for only matching annotation types
+// set to TYPE_SUFFIX for matching both classes and interfaces
+public char typeSuffix;
+public int modifiers;
+public boolean secondary = false;
+
+protected static char[][] CATEGORIES = { TYPE_DECL };
+
+// want to save space by interning the package names for each match
+static PackageNameSet internedPackageNames = new PackageNameSet(1001);
+static class PackageNameSet {
+
+public char[][] names;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+PackageNameSet(int size) {
+	this.elementSize = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.5f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.names = new char[extraRoom][];
+}
+
+char[] add(char[] name) {
+	int length = this.names.length;
+	int index = CharOperation.hashCode(name) % length;
+	char[] current;
+	while ((current = this.names[index]) != null) {
+		if (CharOperation.equals(current, name)) return current;
+		if (++index == length) index = 0;
+	}
+	this.names[index] = name;
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.elementSize > this.threshold) rehash();
+	return name;
+}
+
+void rehash() {
+	PackageNameSet newSet = new PackageNameSet(this.elementSize * 2); // double the number of expected elements
+	char[] current;
+	for (int i = this.names.length; --i >= 0;)
+		if ((current = this.names[i]) != null)
+			newSet.add(current);
+
+	this.names = newSet.names;
+	this.elementSize = newSet.elementSize;
+	this.threshold = newSet.threshold;
+}
+}
+
+/*
+ * Create index key for type declaration pattern:
+ *		key = typeName / packageName / enclosingTypeName / modifiers
+ * or for secondary types
+ *		key = typeName / packageName / enclosingTypeName / modifiers / 'S'
+ */
+public static char[] createIndexKey(int modifiers, char[] typeName, char[] packageName, char[][] enclosingTypeNames, boolean secondary) { //, char typeSuffix) {
+	int typeNameLength = typeName == null ? 0 : typeName.length;
+	int packageLength = packageName == null ? 0 : packageName.length;
+	int enclosingNamesLength = 0;
+	if (enclosingTypeNames != null) {
+		for (int i = 0, length = enclosingTypeNames.length; i < length;) {
+			enclosingNamesLength += enclosingTypeNames[i].length;
+			if (++i < length)
+				enclosingNamesLength++; // for the '.' separator
+		}
+	}
+
+	int resultLength = typeNameLength + packageLength + enclosingNamesLength + 5;
+	if (secondary) resultLength += 2;
+	char[] result = new char[resultLength];
+	int pos = 0;
+	if (typeNameLength > 0) {
+		System.arraycopy(typeName, 0, result, pos, typeNameLength);
+		pos += typeNameLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (packageLength > 0) {
+		System.arraycopy(packageName, 0, result, pos, packageLength);
+		pos += packageLength;
+	}
+	result[pos++] = SEPARATOR;
+	if (enclosingTypeNames != null && enclosingNamesLength > 0) {
+		for (int i = 0, length = enclosingTypeNames.length; i < length;) {
+			char[] enclosingName = enclosingTypeNames[i];
+			int itsLength = enclosingName.length;
+			System.arraycopy(enclosingName, 0, result, pos, itsLength);
+			pos += itsLength;
+			if (++i < length)
+				result[pos++] = '.';
+		}
+	}
+	result[pos++] = SEPARATOR;
+	result[pos++] = (char) modifiers;
+	result[pos] = (char) (modifiers>>16);
+	if (secondary) {
+		result[++pos] = SEPARATOR;
+		result[++pos] = 'S';
+	}
+	return result;
+}
+
+public TypeDeclarationPattern(
+	char[] pkg,
+	char[][] enclosingTypeNames,
+	char[] simpleName,
+	char typeSuffix,
+	int matchRule) {
+
+	this(matchRule);
+
+	this.pkg = this.isCaseSensitive ? pkg : CharOperation.toLowerCase(pkg);
+	if (this.isCaseSensitive || enclosingTypeNames == null) {
+		this.enclosingTypeNames = enclosingTypeNames;
+	} else {
+		int length = enclosingTypeNames.length;
+		this.enclosingTypeNames = new char[length][];
+		for (int i = 0; i < length; i++)
+			this.enclosingTypeNames[i] = CharOperation.toLowerCase(enclosingTypeNames[i]);
+	}
+	this.simpleName = (this.isCaseSensitive || this.isCamelCase) ? simpleName : CharOperation.toLowerCase(simpleName);
+	this.typeSuffix = typeSuffix;
+
+	this.mustResolve = (this.pkg != null && this.enclosingTypeNames != null) || typeSuffix != TYPE_SUFFIX;
+}
+TypeDeclarationPattern(int matchRule) {
+	super(TYPE_DECL_PATTERN, matchRule);
+}
+/*
+ * Type entries are encoded as:
+ * 	simpleTypeName / packageName / enclosingTypeName / modifiers
+ *			e.g. Object/java.lang//0
+ * 		e.g. Cloneable/java.lang//512
+ * 		e.g. LazyValue/javax.swing/UIDefaults/0
+ * or for secondary types as:
+ * 	simpleTypeName / packageName / enclosingTypeName / modifiers / S
+ */
+public void decodeIndexKey(char[] key) {
+	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
+	this.simpleName = CharOperation.subarray(key, 0, slash);
+
+	int start = ++slash;
+	if (key[start] == SEPARATOR) {
+		this.pkg = CharOperation.NO_CHAR;
+	} else {
+		slash = CharOperation.indexOf(SEPARATOR, key, start);
+		this.pkg = internedPackageNames.add(CharOperation.subarray(key, start, slash));
+	}
+
+	// Continue key read by the end to decode modifiers
+	int last = key.length-1;
+	this.secondary = key[last] == 'S';
+	if (this.secondary) {
+		last -= 2;
+	}
+	this.modifiers = key[last-1] + (key[last]<<16);
+	decodeModifiers();
+
+	// Retrieve enclosing type names
+	start = slash + 1;
+	last -= 2; // position of ending slash
+	if (start == last) {
+		this.enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+	} else {
+		if (last == (start+1) && key[start] == ZERO_CHAR) {
+			this.enclosingTypeNames = ONE_ZERO_CHAR;
+		} else {
+			this.enclosingTypeNames = CharOperation.splitOn('.', key, start, last);
+		}
+	}
+}
+protected void decodeModifiers() {
+
+	// Extract suffix from modifiers instead of index key
+	switch (this.modifiers & (ClassFileConstants.AccInterface|ClassFileConstants.AccEnum|ClassFileConstants.AccAnnotation)) {
+		case ClassFileConstants.AccAnnotation:
+		case ClassFileConstants.AccAnnotation+ClassFileConstants.AccInterface:
+			this.typeSuffix = ANNOTATION_TYPE_SUFFIX;
+			break;
+		case ClassFileConstants.AccEnum:
+			this.typeSuffix = ENUM_SUFFIX;
+			break;
+		case ClassFileConstants.AccInterface:
+			this.typeSuffix = INTERFACE_SUFFIX;
+			break;
+		default:
+			this.typeSuffix = CLASS_SUFFIX;
+			break;
+	}
+}
+public SearchPattern getBlankPattern() {
+	return new TypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	return CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	TypeDeclarationPattern pattern = (TypeDeclarationPattern) decodedPattern;
+
+	// check type suffix
+	if (this.typeSuffix != pattern.typeSuffix && this.typeSuffix != TYPE_SUFFIX) {
+		if (!matchDifferentTypeSuffixes(this.typeSuffix, pattern.typeSuffix)) {
+			return false;
+		}
+	}
+
+	// check name
+	if (!matchesName(this.simpleName, pattern.simpleName))
+		return false;
+
+	// check package - exact match only
+	if (this.pkg != null && !CharOperation.equals(this.pkg, pattern.pkg, isCaseSensitive()))
+		return false;
+
+	// check enclosingTypeNames - exact match only
+	if (this.enclosingTypeNames != null) {
+		if (this.enclosingTypeNames.length == 0)
+			return pattern.enclosingTypeNames.length == 0;
+		if (this.enclosingTypeNames.length == 1 && pattern.enclosingTypeNames.length == 1)
+			return CharOperation.equals(this.enclosingTypeNames[0], pattern.enclosingTypeNames[0], isCaseSensitive());
+		if (pattern.enclosingTypeNames == ONE_ZERO_CHAR)
+			return true; // is a local or anonymous type
+		return CharOperation.equals(this.enclosingTypeNames, pattern.enclosingTypeNames, isCaseSensitive());
+	}
+	return true;
+}
+public EntryResult[] queryIn(Index index) throws IOException {
+	char[] key = this.simpleName; // can be null
+	int matchRule = getMatchRule();
+
+	switch(getMatchMode()) {
+		case R_PREFIX_MATCH :
+			// do a prefix query with the simpleName
+			break;
+		case R_EXACT_MATCH :
+			matchRule &= ~R_EXACT_MATCH;
+			if (this.simpleName != null) {
+				matchRule |= R_PREFIX_MATCH;
+				key = this.pkg == null
+					? CharOperation.append(this.simpleName, SEPARATOR)
+					: CharOperation.concat(this.simpleName, SEPARATOR, this.pkg, SEPARATOR, CharOperation.NO_CHAR);
+				break; // do a prefix query with the simpleName and possibly the pkg
+			}
+			matchRule |= R_PATTERN_MATCH;
+			// $FALL-THROUGH$ - fall thru to encode the key and do a pattern query
+		case R_PATTERN_MATCH :
+			if (this.pkg == null) {
+				if (this.simpleName == null) {
+					switch(this.typeSuffix) {
+						case CLASS_SUFFIX :
+						case INTERFACE_SUFFIX :
+						case ENUM_SUFFIX :
+						case ANNOTATION_TYPE_SUFFIX :
+						case CLASS_AND_INTERFACE_SUFFIX :
+						case CLASS_AND_ENUM_SUFFIX :
+						case INTERFACE_AND_ANNOTATION_SUFFIX :
+							// null key already returns all types
+							// key = new char[] {ONE_STAR[0],  SEPARATOR, ONE_STAR[0]};
+							break;
+					}
+				} else if (this.simpleName[this.simpleName.length - 1] != '*') {
+					key = CharOperation.concat(this.simpleName, ONE_STAR, SEPARATOR);
+				}
+				break; // do a pattern query with the current encoded key
+			}
+			// must decode to check enclosingTypeNames due to the encoding of local types
+			key = CharOperation.concat(
+				this.simpleName == null ? ONE_STAR : this.simpleName, SEPARATOR, this.pkg, SEPARATOR, ONE_STAR);
+			break;
+		case R_REGEXP_MATCH :
+			// TODO (frederic) implement regular expression match
+			break;
+		case R_CAMELCASE_MATCH:
+		case R_CAMELCASE_SAME_PART_COUNT_MATCH:
+			// do a prefix query with the simpleName
+			break;
+	}
+
+	return index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+}
+protected StringBuffer print(StringBuffer output) {
+	switch (this.typeSuffix){
+		case CLASS_SUFFIX :
+			output.append("ClassDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case CLASS_AND_INTERFACE_SUFFIX:
+			output.append("ClassAndInterfaceDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case CLASS_AND_ENUM_SUFFIX :
+			output.append("ClassAndEnumDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case INTERFACE_SUFFIX :
+			output.append("InterfaceDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case INTERFACE_AND_ANNOTATION_SUFFIX:
+			output.append("InterfaceAndAnnotationDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case ENUM_SUFFIX :
+			output.append("EnumDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		case ANNOTATION_TYPE_SUFFIX :
+			output.append("AnnotationTypeDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+		default :
+			output.append("TypeDeclarationPattern: pkg<"); //$NON-NLS-1$
+			break;
+	}
+	if (this.pkg != null)
+		output.append(this.pkg);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">, enclosing<"); //$NON-NLS-1$
+	if (this.enclosingTypeNames != null) {
+		for (int i = 0; i < this.enclosingTypeNames.length; i++){
+			output.append(this.enclosingTypeNames[i]);
+			if (i < this.enclosingTypeNames.length - 1)
+				output.append('.');
+		}
+	} else {
+		output.append("*"); //$NON-NLS-1$
+	}
+	output.append(">, type<"); //$NON-NLS-1$
+	if (this.simpleName != null)
+		output.append(this.simpleName);
+	else
+		output.append("*"); //$NON-NLS-1$
+	output.append(">"); //$NON-NLS-1$
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java
new file mode 100644
index 0000000..00b206f
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+
+/**
+ * Search engine locator for type parameters matches.
+ */
+public class TypeParameterLocator extends PatternLocator {
+
+	protected TypeParameterPattern pattern;
+
+	public TypeParameterLocator(TypeParameterPattern pattern) {
+		super(pattern);
+		this.pattern = pattern;
+	}
+
+	/*
+	 * Verify whether a type reference matches name pattern.
+	 * Type parameter references (i.e. type arguments) are compiler type reference nodes
+	 */
+	public int match(TypeReference node, MatchingNodeSet nodeSet) {
+		if (this.pattern.findReferences) {
+			if (node instanceof SingleTypeReference) { // Type parameter cannot be qualified
+				if (matchesName(this.pattern.name, ((SingleTypeReference) node).token)) {
+					int level = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+					return nodeSet.addMatch(node, level);
+				}
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+
+	/*
+	 * Verify whether a type parameter matches name pattern.
+	 */
+	public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+		if (this.pattern.findDeclarations) {
+			if (matchesName(this.pattern.name, node.name)) {
+				int level = this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				return nodeSet.addMatch(node, level);
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	/*
+	 * While searching for references, need to match all containers as we can have references in javadoc comments.
+	 * Otherwise, only class or method container can declare type parameters.
+	 */
+	protected int matchContainer() {
+		if (this.pattern.findReferences) {
+			return ALL_CONTAINER;
+		}
+		return CLASS_CONTAINER | METHOD_CONTAINER;
+	}
+
+	/*
+	 * Verify that a type variable binding match pattern infos.
+	 * For types, only look at declaring member name.
+	 * For methods, also look at declaring class and parameters type names
+	 */
+	protected int matchTypeParameter(TypeVariableBinding variable, boolean matchName) {
+		if (variable == null || variable.declaringElement == null) return INACCURATE_MATCH;
+		if (variable.declaringElement instanceof ReferenceBinding) {
+			ReferenceBinding refBinding  = (ReferenceBinding) variable.declaringElement;
+			if (matchesName(refBinding.sourceName, this.pattern.declaringMemberName)) {
+				return ACCURATE_MATCH;
+			}
+		} else if (variable.declaringElement instanceof MethodBinding) {
+			MethodBinding methBinding  = (MethodBinding) variable.declaringElement;
+			if (matchesName(methBinding.declaringClass.sourceName, this.pattern.methodDeclaringClassName) &&
+				(methBinding.isConstructor() || matchesName(methBinding.selector, this.pattern.declaringMemberName))) {
+				int length = this.pattern.methodArgumentTypes==null ? 0 : this.pattern.methodArgumentTypes.length;
+				if (methBinding.parameters == null) {
+					if (length == 0) return ACCURATE_MATCH;
+				} else if (methBinding.parameters.length == length){
+					for (int i=0; i<length; i++) {
+						if (!matchesName(methBinding.parameters[i].shortReadableName(), this.pattern.methodArgumentTypes[i])) {
+							return IMPOSSIBLE_MATCH;
+						}
+					}
+					return ACCURATE_MATCH;
+				}
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	protected int referenceType() {
+		return IJavaElement.TYPE_PARAMETER;
+	}
+
+	/*
+	 * Resolve level for a possible matching node.
+	 * Only type references while searching references and type parameters
+	 * while searching declarations are valid.
+	 */
+	public int resolveLevel(ASTNode possibleMatchingNode) {
+		if (this.pattern.findReferences) {
+			if (possibleMatchingNode instanceof SingleTypeReference) {
+				return resolveLevel(((SingleTypeReference) possibleMatchingNode).resolvedType);
+			}
+		}
+		if (this.pattern.findDeclarations) {
+			if (possibleMatchingNode instanceof TypeParameter) {
+				return matchTypeParameter(((TypeParameter) possibleMatchingNode).binding, true);
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	/*
+	 * Resolve level for a binding.
+	 * Only type variable bindings are valid.
+	 */
+	public int resolveLevel(Binding binding) {
+		if (binding == null) return INACCURATE_MATCH;
+		if (!(binding instanceof TypeVariableBinding)) return IMPOSSIBLE_MATCH;
+
+		return matchTypeParameter((TypeVariableBinding) binding, true);
+	}
+
+	public String toString() {
+		return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java
new file mode 100644
index 0000000..05749aa
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.JavaSearchScope;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Pattern to search type parameters.
+ *
+ * @since 3.1
+ */
+public class TypeParameterPattern extends JavaSearchPattern {
+
+	protected boolean findDeclarations;
+	protected boolean findReferences;
+	protected char[] name;
+	protected ITypeParameter typeParameter;
+	protected char[] declaringMemberName;
+	protected char[] methodDeclaringClassName;
+	protected char[][] methodArgumentTypes;
+
+	/**
+	 * @param findDeclarations
+	 * @param findReferences
+	 * @param typeParameter
+	 * @param matchRule
+	 */
+	public TypeParameterPattern(boolean findDeclarations, boolean findReferences, ITypeParameter typeParameter, int matchRule) {
+		super(TYPE_PARAM_PATTERN, matchRule);
+
+		this.findDeclarations = findDeclarations; // set to find declarations & all occurences
+		this.findReferences = findReferences; // set to find references & all occurences
+		this.typeParameter = typeParameter;
+		this.name = typeParameter.getElementName().toCharArray(); // store type parameter name
+		IMember member = typeParameter.getDeclaringMember();
+		this.declaringMemberName = member.getElementName().toCharArray(); // store type parameter declaring member name
+
+		// For method type parameter, store also declaring class name and parameters type names
+		if (member instanceof IMethod) {
+			IMethod method = (IMethod) member;
+			this.methodDeclaringClassName = method.getParent().getElementName().toCharArray();
+			String[] parameters = method.getParameterTypes();
+			int length = parameters.length;
+			this.methodArgumentTypes = new char[length][];
+			for (int i=0; i<length; i++) {
+				this.methodArgumentTypes[i] = Signature.toCharArray(parameters[i].toCharArray());
+			}
+		}
+	}
+
+	/*
+	 * Same than LocalVariablePattern.
+	 */
+	public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) {
+	    IPackageFragmentRoot root = (IPackageFragmentRoot) this.typeParameter.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		String documentPath;
+		String relativePath;
+	    if (root.isArchive()) {
+ 	    	IType type = (IType) this.typeParameter.getAncestor(IJavaElement.TYPE);
+    	    relativePath = (type.getFullyQualifiedName('$')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
+	        documentPath = root.getPath() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + relativePath;
+	    } else {
+			IPath path = this.typeParameter.getPath();
+	        documentPath = path.toString();
+			relativePath = Util.relativePath(path, 1/*remove project segment*/);
+	    }
+
+		if (scope instanceof JavaSearchScope) {
+			JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
+			// Get document path access restriction from java search scope
+			// Note that requestor has to verify if needed whether the document violates the access restriction or not
+			AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, index.containerPath);
+			if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the path
+				if (!requestor.acceptIndexMatch(documentPath, this, participant, access))
+					throw new OperationCanceledException();
+			}
+		} else if (scope.encloses(documentPath)) {
+			if (!requestor.acceptIndexMatch(documentPath, this, participant, null))
+				throw new OperationCanceledException();
+		}
+	}
+
+	protected StringBuffer print(StringBuffer output) {
+		if (this.findDeclarations) {
+			output.append(this.findReferences
+				? "TypeParamCombinedPattern: " //$NON-NLS-1$
+				: "TypeParamDeclarationPattern: "); //$NON-NLS-1$
+		} else {
+			output.append("TypeParamReferencePattern: "); //$NON-NLS-1$
+		}
+		output.append(this.typeParameter.toString());
+		return super.print(output);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
new file mode 100644
index 0000000..ddea928
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
@@ -0,0 +1,775 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.*;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.core.JavaElement;
+
+public class TypeReferenceLocator extends PatternLocator {
+
+protected TypeReferencePattern pattern;
+protected boolean isDeclarationOfReferencedTypesPattern;
+
+private final int fineGrain;
+
+public TypeReferenceLocator(TypeReferencePattern pattern) {
+
+	super(pattern);
+
+	this.pattern = pattern;
+	this.fineGrain = pattern == null ? 0 : pattern.fineGrain;
+	this.isDeclarationOfReferencedTypesPattern = this.pattern instanceof DeclarationOfReferencedTypesPattern;
+}
+protected IJavaElement findElement(IJavaElement element, int accuracy) {
+	// need exact match to be able to open on type ref
+	if (accuracy != SearchMatch.A_ACCURATE) return null;
+
+	// element that references the type must be included in the enclosing element
+	DeclarationOfReferencedTypesPattern declPattern = (DeclarationOfReferencedTypesPattern) this.pattern;
+	while (element != null && !declPattern.enclosingElement.equals(element))
+		element = element.getParent();
+	return element;
+}
+protected int fineGrain() {
+	return this.fineGrain;
+}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+	return match(node.type, nodeSet);
+}
+public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ImportReference
+	if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH;
+
+	return nodeSet.addMatch(node, matchLevel((ImportReference) node));
+}
+//public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(Reference node, MatchingNodeSet nodeSet) { // interested in NameReference & its subtypes
+	if (!(node instanceof NameReference)) return IMPOSSIBLE_MATCH;
+
+	if (this.pattern.simpleName == null)
+		return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+
+	if (node instanceof SingleNameReference) {
+		if (matchesName(this.pattern.simpleName, ((SingleNameReference) node).token))
+			return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref
+	} else {
+		char[][] tokens = ((QualifiedNameReference) node).tokens;
+		for (int i = 0, max = tokens.length; i < max; i++)
+			if (matchesName(this.pattern.simpleName, tokens[i]))
+				return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref
+	}
+
+	return IMPOSSIBLE_MATCH;
+}
+//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(TypeReference node, MatchingNodeSet nodeSet) {
+	if (this.pattern.simpleName == null)
+		return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+
+	if (node instanceof SingleTypeReference) {
+		if (matchesName(this.pattern.simpleName, ((SingleTypeReference) node).token))
+			return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+	} else {
+		char[][] tokens = ((QualifiedTypeReference) node).tokens;
+		for (int i = 0, max = tokens.length; i < max; i++)
+			if (matchesName(this.pattern.simpleName, tokens[i]))
+				return nodeSet.addMatch(node, POSSIBLE_MATCH); // resolution is needed to find out if it is a type ref
+	}
+
+	return IMPOSSIBLE_MATCH;
+}
+
+protected int matchLevel(ImportReference importRef) {
+	if (this.pattern.qualification == null) {
+		if (this.pattern.simpleName == null) return ACCURATE_MATCH;
+		char[][] tokens = importRef.tokens;
+		boolean onDemand = (importRef.bits & ASTNode.OnDemand) != 0;
+		final boolean isStatic = importRef.isStatic();
+		if (!isStatic && onDemand) {
+			return IMPOSSIBLE_MATCH;
+		}
+		int length = tokens.length;
+		if (matchesName(this.pattern.simpleName, tokens[length-1])) {
+			return ACCURATE_MATCH;
+		}
+		if (isStatic && !onDemand && length > 1) {
+			if (matchesName(this.pattern.simpleName, tokens[length-2])) {
+				return ACCURATE_MATCH;
+			}
+		}
+	} else {
+		char[][] tokens = importRef.tokens;
+		char[] qualifiedPattern = this.pattern.simpleName == null
+			? this.pattern.qualification
+			: CharOperation.concat(this.pattern.qualification, this.pattern.simpleName, '.');
+		char[] qualifiedTypeName = CharOperation.concatWith(tokens, '.');
+		if (qualifiedPattern == null) return ACCURATE_MATCH; // null is as if it was "*"
+		if (qualifiedTypeName == null) return IMPOSSIBLE_MATCH; // cannot match null name
+		if (qualifiedTypeName.length == 0) { // empty name
+			if (qualifiedPattern.length == 0) { // can only matches empty pattern
+				return ACCURATE_MATCH;
+			}
+			return IMPOSSIBLE_MATCH;
+		}
+		boolean matchFirstChar = !this.isCaseSensitive || (qualifiedPattern[0] == qualifiedTypeName[0]);
+		switch (this.matchMode) {
+			case SearchPattern.R_EXACT_MATCH:
+			case SearchPattern.R_PREFIX_MATCH:
+				if (CharOperation.prefixEquals(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) {
+					return POSSIBLE_MATCH;
+				}
+				break;
+
+			case SearchPattern.R_PATTERN_MATCH:
+				if (CharOperation.match(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) {
+					return POSSIBLE_MATCH;
+				}
+				break;
+
+			case SearchPattern.R_REGEXP_MATCH :
+				// TODO (frederic) implement regular expression match
+				break;
+			case SearchPattern.R_CAMELCASE_MATCH:
+				if (matchFirstChar && CharOperation.camelCaseMatch(qualifiedPattern, qualifiedTypeName, false)) {
+					return POSSIBLE_MATCH;
+				}
+				// only test case insensitive as CamelCase already verified prefix case sensitive
+				if (!this.isCaseSensitive && CharOperation.prefixEquals(qualifiedPattern, qualifiedTypeName, false)) {
+					return POSSIBLE_MATCH;
+				}
+				break;
+			case SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH:
+				if (matchFirstChar && CharOperation.camelCaseMatch(qualifiedPattern, qualifiedTypeName, true)) {
+					return POSSIBLE_MATCH;
+				}
+				break;
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	Binding refBinding = binding;
+	if (importRef.isStatic()) {
+		// for static import, binding can be a field binding or a member type binding
+		// verify that in this case binding is static and use declaring class for fields
+		if (binding instanceof FieldBinding) {
+			FieldBinding fieldBinding = (FieldBinding) binding;
+			if (!fieldBinding.isStatic()) return;
+			refBinding = fieldBinding.declaringClass;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = (MethodBinding) binding;
+			if (!methodBinding.isStatic()) return;
+			refBinding = methodBinding.declaringClass;
+		} else if (binding instanceof MemberTypeBinding) {
+			MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
+			if (!memberBinding.isStatic()) return;
+		}
+		// resolve and report
+		int level = resolveLevel(refBinding);
+		if (level >= INACCURATE_MATCH) {
+			matchReportImportRef(
+				importRef,
+				binding,
+				locator.createImportHandle(importRef),
+				level == ACCURATE_MATCH
+					? SearchMatch.A_ACCURATE
+					: SearchMatch.A_INACCURATE,
+				locator);
+		}
+		return;
+	}
+	super.matchLevelAndReportImportRef(importRef, refBinding, locator);
+}
+protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+	if (this.isDeclarationOfReferencedTypesPattern) {
+		if ((element = findElement(element, accuracy)) != null) {
+			SimpleSet knownTypes = ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes;
+			while (binding instanceof ReferenceBinding) {
+				ReferenceBinding typeBinding = (ReferenceBinding) binding;
+				reportDeclaration(typeBinding, 1, locator, knownTypes);
+				binding = typeBinding.enclosingType();
+			}
+		}
+		return;
+	}
+
+	// return if this is not necessary to report
+	if (this.pattern.hasTypeArguments() && !this.isEquivalentMatch &&!this.isErasureMatch) {
+		return;
+	}
+
+	// Return if fine grain is on and does not concern import reference
+	if ((this.pattern.fineGrain != 0 && (this.pattern.fineGrain & IJavaSearchConstants.IMPORT_DECLARATION_TYPE_REFERENCE) == 0)) {
+		return;
+	}
+
+	// Create search match
+	this.match = locator.newTypeReferenceMatch(element, binding, accuracy, importRef);
+
+	// set match raw flag and rule
+	this.match.setRaw(true);
+	if (this.pattern.hasTypeArguments()) {
+		// binding is raw => only compatible erasure if pattern has type arguments
+		this.match.setRule(this.match.getRule() & (~SearchPattern.R_FULL_MATCH));
+	}
+
+	// Try to find best selection for match
+	TypeBinding typeBinding = null;
+	boolean lastButOne = false;
+	if (binding instanceof ReferenceBinding) {
+		typeBinding = (ReferenceBinding) binding;
+	} else if (binding instanceof FieldBinding) { // may happen for static import
+		typeBinding = ((FieldBinding)binding).declaringClass;
+		lastButOne = importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0);
+	} else if (binding instanceof MethodBinding) { // may happen for static import
+		typeBinding = ((MethodBinding)binding).declaringClass;
+		lastButOne = importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0);
+	}
+	if (typeBinding != null) {
+		int lastIndex = importRef.tokens.length - 1;
+		if (lastButOne) {
+			// for field or method static import, use last but one token
+			lastIndex--;
+		}
+		if (typeBinding instanceof ProblemReferenceBinding) {
+			ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
+			typeBinding = pbBinding.closestMatch();
+			lastIndex = pbBinding.compoundName.length - 1;
+		}
+		// try to match all enclosing types for which the token matches as well.
+		while (typeBinding != null && lastIndex >= 0) {
+			if (resolveLevelForType(typeBinding) != IMPOSSIBLE_MATCH) {
+				if (locator.encloses(element)) {
+					long[] positions = importRef.sourcePositions;
+					// index now depends on pattern type signature
+					int index = lastIndex;
+					if (this.pattern.qualification != null) {
+						index = lastIndex - this.pattern.segmentsSize;
+					}
+					if (index < 0) index = 0;
+					int start = (int) ((positions[index]) >>> 32);
+					int end = (int) positions[lastIndex];
+					// report match
+					this.match.setOffset(start);
+					this.match.setLength(end-start+1);
+					locator.report(this.match);
+				}
+				return;
+			}
+			lastIndex--;
+			typeBinding = typeBinding.enclosingType();
+		}
+	}
+	locator.reportAccurateTypeReference(this.match, importRef, this.pattern.simpleName);
+}
+protected void matchReportReference(ArrayTypeReference arrayRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	if (this.pattern.simpleName == null) {
+		// TODO (frederic) need to add a test for this case while searching generic types...
+		if (locator.encloses(element)) {
+			int offset = arrayRef.sourceStart;
+			int length = arrayRef.sourceEnd-offset+1;
+			if (this.match == null) {
+				this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, length, arrayRef);
+			} else {
+				this.match.setOffset(offset);
+				this.match.setLength(length);
+			}
+			locator.report(this.match);
+			return;
+		}
+	}
+	this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, arrayRef);
+	if (arrayRef.resolvedType != null) {
+		matchReportReference(arrayRef, -1, arrayRef.resolvedType.leafComponentType(), locator);
+		return;
+	}
+	locator.reportAccurateTypeReference(this.match, arrayRef, this.pattern.simpleName);
+}
+/**
+ * Reports the match of the given reference.
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	matchReportReference(reference, element, null, null, elementBinding, accuracy, locator);
+}
+/**
+ * Reports the match of the given reference. Also provide a local and other elements to eventually report in match.
+ */
+protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	if (this.isDeclarationOfReferencedTypesPattern) {
+		if ((element = findElement(element, accuracy)) != null)
+			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
+		return;
+	}
+
+	// Create search match
+	TypeReferenceMatch refMatch = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
+	refMatch.setLocalElement(localElement);
+	refMatch.setOtherElements(otherElements);
+	this.match = refMatch;
+
+	// Report match depending on reference type
+	if (reference instanceof QualifiedNameReference)
+		matchReportReference((QualifiedNameReference) reference, element, elementBinding, accuracy, locator);
+	else if (reference instanceof QualifiedTypeReference)
+		matchReportReference((QualifiedTypeReference) reference, element, elementBinding, accuracy, locator);
+	else if (reference instanceof ArrayTypeReference)
+		matchReportReference((ArrayTypeReference) reference, element, elementBinding, accuracy, locator);
+	else {
+		TypeBinding typeBinding = reference instanceof Expression ? ((Expression)reference).resolvedType : null;
+		if (typeBinding != null) {
+			matchReportReference((Expression)reference, -1, typeBinding, locator);
+			return;
+		}
+		locator.report(this.match);
+	}
+}
+protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	Binding binding = qNameRef.binding;
+	TypeBinding typeBinding = null;
+	int lastIndex = qNameRef.tokens.length - 1;
+	switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			typeBinding = qNameRef.actualReceiverType;
+			lastIndex -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1;
+			break;
+		case Binding.TYPE : //=============only type ==============
+			if (binding instanceof TypeBinding)
+				typeBinding = (TypeBinding) binding;
+			break;
+		case Binding.VARIABLE : //============unbound cases===========
+		case Binding.TYPE | Binding.VARIABLE :
+			if (binding instanceof ProblemReferenceBinding) {
+				typeBinding = (TypeBinding) binding;
+			} else if (binding instanceof ProblemFieldBinding) {
+				typeBinding = qNameRef.actualReceiverType;
+				lastIndex -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1;
+			} else if (binding instanceof ProblemBinding) {
+				typeBinding = ((ProblemBinding) binding).searchType;
+			}
+			break;
+	}
+	if (typeBinding instanceof ProblemReferenceBinding) {
+		ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
+		typeBinding = pbBinding.closestMatch();
+		lastIndex = pbBinding.compoundName.length - 1;
+	}
+
+	// Create search match to report
+	if (this.match == null) {
+		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
+	}
+
+	// try to match all enclosing types for which the token matches as well.
+	if (typeBinding instanceof ReferenceBinding) {
+		ReferenceBinding refBinding = (ReferenceBinding) typeBinding;
+		while (refBinding != null && lastIndex >= 0) {
+			if (resolveLevelForType(refBinding) == ACCURATE_MATCH) {
+				if (locator.encloses(element)) {
+					long[] positions = qNameRef.sourcePositions;
+					// index now depends on pattern type signature
+					int index = lastIndex;
+					if (this.pattern.qualification != null) {
+						index = lastIndex - this.pattern.segmentsSize;
+					}
+					if (index < 0) index = 0;
+					int start = (int) ((positions[index]) >>> 32);
+					int end = (int) positions[lastIndex];
+					this.match.setOffset(start);
+					this.match.setLength(end-start+1);
+
+					//  Look if there's a need to special report for parameterized type
+					matchReportReference(qNameRef, lastIndex, refBinding, locator);
+				}
+				return;
+			}
+			lastIndex--;
+			refBinding = refBinding.enclosingType();
+		}
+	}
+	locator.reportAccurateTypeReference(this.match, qNameRef, this.pattern.simpleName);
+}
+protected void matchReportReference(QualifiedTypeReference qTypeRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	TypeBinding typeBinding = qTypeRef.resolvedType;
+	int lastIndex = qTypeRef.tokens.length - 1;
+	if (typeBinding instanceof ArrayBinding)
+		typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+	if (typeBinding instanceof ProblemReferenceBinding) {
+		ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
+		typeBinding = pbBinding.closestMatch();
+		lastIndex = pbBinding.compoundName.length - 1;
+	}
+
+	// Create search match to report
+	if (this.match == null) {
+		this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
+	}
+
+	// try to match all enclosing types for which the token matches as well
+	if (typeBinding instanceof ReferenceBinding) {
+		ReferenceBinding refBinding = (ReferenceBinding) typeBinding;
+		while (refBinding != null && lastIndex >= 0) {
+			if (resolveLevelForType(refBinding) != IMPOSSIBLE_MATCH) {
+				if (locator.encloses(element)) {
+					long[] positions = qTypeRef.sourcePositions;
+					// index now depends on pattern type signature
+					int index = lastIndex;
+					if (this.pattern.qualification != null) {
+						index = lastIndex - this.pattern.segmentsSize;
+					}
+					if (index < 0) index = 0;
+					int start = (int) ((positions[index]) >>> 32);
+					int end = (int) positions[lastIndex];
+					this.match.setOffset(start);
+					this.match.setLength(end-start+1);
+
+					//  Look if there's a need to special report for parameterized type
+					matchReportReference(qTypeRef, lastIndex, refBinding, locator);
+				}
+				return;
+			}
+			lastIndex--;
+			refBinding = refBinding.enclosingType();
+		}
+	}
+	locator.reportAccurateTypeReference(this.match, qTypeRef, this.pattern.simpleName);
+}
+void matchReportReference(Expression expr, int lastIndex, TypeBinding refBinding, MatchLocator locator) throws CoreException {
+
+	// Look if there's a need to special report for parameterized type
+	if (refBinding.isParameterizedType() || refBinding.isRawType()) {
+
+		// Try to refine accuracy
+		ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)refBinding;
+		updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+
+		// See whether it is necessary to report or not
+		if (this.match.getRule() == 0) return; // impossible match
+		boolean report = (this.isErasureMatch && this.match.isErasure()) || (this.isEquivalentMatch && this.match.isEquivalent()) || this.match.isExact();
+		if (!report) return;
+
+		// Make a special report for parameterized types if necessary
+		 if (refBinding.isParameterizedType() && this.pattern.hasTypeArguments())  {
+			TypeReference typeRef = null;
+			TypeReference[] typeArguments = null;
+			if (expr instanceof ParameterizedQualifiedTypeReference) {
+				typeRef = (ParameterizedQualifiedTypeReference) expr;
+				typeArguments = ((ParameterizedQualifiedTypeReference) expr).typeArguments[lastIndex];
+			}
+			else if (expr instanceof ParameterizedSingleTypeReference) {
+				typeRef = (ParameterizedSingleTypeReference) expr;
+				typeArguments = ((ParameterizedSingleTypeReference) expr).typeArguments;
+			}
+			if (typeRef != null) {
+				locator.reportAccurateParameterizedTypeReference(this.match, typeRef, lastIndex, typeArguments);
+				return;
+			}
+		}
+	} else if (this.pattern.hasTypeArguments()) { // binding has no type params, compatible erasure if pattern does
+		this.match.setRule(SearchPattern.R_ERASURE_MATCH);
+	}
+
+	// Report match
+	if (expr instanceof ArrayTypeReference) {
+		locator.reportAccurateTypeReference(this.match, expr, this.pattern.simpleName);
+		return;
+	}
+	if (refBinding.isLocalType()) {
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=82673
+		LocalTypeBinding local = (LocalTypeBinding) refBinding.erasure();
+		IJavaElement focus = this.pattern.focus;
+		if (focus != null && local.enclosingMethod != null && focus.getParent().getElementType() == IJavaElement.METHOD) {
+			IMethod method = (IMethod) focus.getParent();
+			if (!CharOperation.equals(local.enclosingMethod.selector, method.getElementName().toCharArray())) {
+				return;
+			}
+		}
+	}
+	if (this.pattern.simpleName == null) {
+		this.match.setOffset(expr.sourceStart);
+		this.match.setLength(expr.sourceEnd-expr.sourceStart+1);
+	}
+	locator.report(this.match);
+}
+protected int referenceType() {
+	return IJavaElement.TYPE;
+}
+protected void reportDeclaration(ASTNode reference, IJavaElement element, MatchLocator locator, SimpleSet knownTypes) throws CoreException {
+	int maxType = -1;
+	TypeBinding typeBinding = null;
+	if (reference instanceof TypeReference) {
+		typeBinding = ((TypeReference) reference).resolvedType;
+		maxType = Integer.MAX_VALUE;
+	} else if (reference instanceof QualifiedNameReference) {
+		QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
+		Binding binding = qNameRef.binding;
+		maxType = qNameRef.tokens.length - 1;
+		switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
+			case Binding.FIELD : // reading a field
+				typeBinding = qNameRef.actualReceiverType;
+				maxType -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1;
+				break;
+			case Binding.TYPE : //=============only type ==============
+				if (binding instanceof TypeBinding)
+					typeBinding = (TypeBinding) binding;
+				break;
+			case Binding.VARIABLE : //============unbound cases===========
+			case Binding.TYPE | Binding.VARIABLE :
+				if (binding instanceof ProblemFieldBinding) {
+					typeBinding = qNameRef.actualReceiverType;
+					maxType -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1;
+				} else if (binding instanceof ProblemBinding) {
+					ProblemBinding pbBinding = (ProblemBinding) binding;
+					typeBinding = pbBinding.searchType; // second chance with recorded type so far
+					char[] partialQualifiedName = pbBinding.name;
+					maxType = CharOperation.occurencesOf('.', partialQualifiedName) - 1; // index of last bound token is one before the pb token
+					if (typeBinding == null || maxType < 0) return;
+				}
+				break;
+		}
+	} else if (reference instanceof SingleNameReference) {
+		typeBinding = (TypeBinding) ((SingleNameReference) reference).binding;
+		maxType = 1;
+	}
+
+	if (typeBinding instanceof ArrayBinding)
+		typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+	if (typeBinding == null || typeBinding instanceof BaseTypeBinding) return;
+	if (typeBinding instanceof ProblemReferenceBinding) {
+		TypeBinding original = typeBinding.closestMatch();
+		if (original == null) return; // original may not be set (bug 71279)
+		typeBinding = original;
+	}
+	typeBinding = typeBinding.erasure();
+	reportDeclaration((ReferenceBinding) typeBinding, maxType, locator, knownTypes);
+}
+protected void reportDeclaration(ReferenceBinding typeBinding, int maxType, MatchLocator locator, SimpleSet knownTypes) throws CoreException {
+	IType type = locator.lookupType(typeBinding);
+	if (type == null) return; // case of a secondary type
+
+	IResource resource = type.getResource();
+	boolean isBinary = type.isBinary();
+	IBinaryType info = null;
+	if (isBinary) {
+		if (resource == null)
+			resource = type.getJavaProject().getProject();
+		info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile) type.getClassFile(), resource);
+	}
+	while (maxType >= 0 && type != null) {
+		if (!knownTypes.includes(type)) {
+			if (isBinary) {
+				locator.reportBinaryMemberDeclaration(resource, type, typeBinding, info, SearchMatch.A_ACCURATE);
+			} else {
+				if (typeBinding instanceof ParameterizedTypeBinding)
+					typeBinding = ((ParameterizedTypeBinding) typeBinding).genericType();
+				ClassScope scope = ((SourceTypeBinding) typeBinding).scope;
+				if (scope != null) {
+					TypeDeclaration typeDecl = scope.referenceContext;
+					int offset = typeDecl.sourceStart;
+					this.match = new TypeDeclarationMatch(((JavaElement) type).resolved(typeBinding), SearchMatch.A_ACCURATE, offset, typeDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+					locator.report(this.match);
+				}
+			}
+			knownTypes.add(type);
+		}
+		typeBinding = typeBinding.enclosingType();
+		IJavaElement parent = type.getParent();
+		if (parent instanceof IType) {
+			type = (IType)parent;
+		} else {
+			type = null;
+		}
+		maxType--;
+	}
+}
+public int resolveLevel(ASTNode node) {
+	if (node instanceof TypeReference)
+		return resolveLevel((TypeReference) node);
+	if (node instanceof NameReference)
+		return resolveLevel((NameReference) node);
+//	if (node instanceof ImportReference) - Not called when resolve is true, see MatchingNodeSet.reportMatching(unit)
+	return IMPOSSIBLE_MATCH;
+}
+public int resolveLevel(Binding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+	if (!(binding instanceof TypeBinding)) return IMPOSSIBLE_MATCH;
+
+	TypeBinding typeBinding = (TypeBinding) binding;
+	if (typeBinding instanceof ArrayBinding)
+		typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+	if (typeBinding instanceof ProblemReferenceBinding)
+		typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch();
+
+	return resolveLevelForTypeOrEnclosingTypes(this.pattern.simpleName, this.pattern.qualification, typeBinding);
+}
+protected int resolveLevel(NameReference nameRef) {
+	Binding binding = nameRef.binding;
+
+	if (nameRef instanceof SingleNameReference) {
+		if (binding instanceof ProblemReferenceBinding)
+			binding = ((ProblemReferenceBinding) binding).closestMatch();
+		if (binding instanceof ReferenceBinding)
+			return resolveLevelForType((ReferenceBinding) binding);
+		return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH;
+	}
+
+	TypeBinding typeBinding = null;
+	QualifiedNameReference qNameRef = (QualifiedNameReference) nameRef;
+	switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) {
+		case Binding.FIELD : // reading a field
+			if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2))
+				return IMPOSSIBLE_MATCH; // must be at least A.x
+			typeBinding = nameRef.actualReceiverType;
+			break;
+		case Binding.LOCAL : // reading a local variable
+			return IMPOSSIBLE_MATCH; // no type match in it
+		case Binding.TYPE : //=============only type ==============
+			if (binding instanceof TypeBinding)
+				typeBinding = (TypeBinding) binding;
+			break;
+		/*
+		 * Handling of unbound qualified name references. The match may reside in the resolved fragment,
+		 * which is recorded inside the problem binding, along with the portion of the name until it became a problem.
+		 */
+		case Binding.VARIABLE : //============unbound cases===========
+		case Binding.TYPE | Binding.VARIABLE :
+			if (binding instanceof ProblemReferenceBinding) {
+				typeBinding = (TypeBinding) binding;
+			} else if (binding instanceof ProblemFieldBinding) {
+				if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2))
+					return IMPOSSIBLE_MATCH; // must be at least A.x
+				typeBinding = nameRef.actualReceiverType;
+			} else if (binding instanceof ProblemBinding) {
+				ProblemBinding pbBinding = (ProblemBinding) binding;
+				if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) // index of last bound token is one before the pb token
+					return INACCURATE_MATCH;
+				typeBinding = pbBinding.searchType;
+			}
+			break;
+	}
+	return resolveLevel(typeBinding);
+}
+protected int resolveLevel(TypeReference typeRef) {
+	TypeBinding typeBinding = typeRef.resolvedType;
+	if (typeBinding instanceof ArrayBinding)
+		typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
+	if (typeBinding instanceof ProblemReferenceBinding)
+		typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch();
+
+	if (typeRef instanceof SingleTypeReference) {
+		return resolveLevelForType(typeBinding);
+	} else
+		return resolveLevelForTypeOrQualifyingTypes(typeRef, typeBinding);
+}
+/* (non-Javadoc)
+ * Resolve level for type with a given binding.
+ * This is just an helper to avoid call of method with all parameters...
+ */
+protected int resolveLevelForType(TypeBinding typeBinding) {
+	if (typeBinding == null || !typeBinding.isValidBinding()) {
+		if (this.pattern.typeSuffix != TYPE_SUFFIX) return INACCURATE_MATCH;
+	} else {
+		switch (this.pattern.typeSuffix) {
+			case CLASS_SUFFIX:
+				if (!typeBinding.isClass()) return IMPOSSIBLE_MATCH;
+				break;
+			case CLASS_AND_INTERFACE_SUFFIX:
+				if (!(typeBinding.isClass() || (typeBinding.isInterface() && !typeBinding.isAnnotationType()))) return IMPOSSIBLE_MATCH;
+				break;
+			case CLASS_AND_ENUM_SUFFIX:
+				if (!(typeBinding.isClass() || typeBinding.isEnum())) return IMPOSSIBLE_MATCH;
+				break;
+			case INTERFACE_SUFFIX:
+				if (!typeBinding.isInterface() || typeBinding.isAnnotationType()) return IMPOSSIBLE_MATCH;
+				break;
+			case INTERFACE_AND_ANNOTATION_SUFFIX:
+				if (!(typeBinding.isInterface() || typeBinding.isAnnotationType())) return IMPOSSIBLE_MATCH;
+				break;
+			case ENUM_SUFFIX:
+				if (!typeBinding.isEnum()) return IMPOSSIBLE_MATCH;
+				break;
+			case ANNOTATION_TYPE_SUFFIX:
+				if (!typeBinding.isAnnotationType()) return IMPOSSIBLE_MATCH;
+				break;
+			case TYPE_SUFFIX : // nothing
+		}
+	}
+	return resolveLevelForType( this.pattern.simpleName,
+						this.pattern.qualification,
+						this.pattern.getTypeArguments(),
+						0,
+						typeBinding);
+}
+/**
+ * Returns whether the given type binding or one of its enclosing types
+ * matches the given simple name pattern and qualification pattern.
+ * Returns ACCURATE_MATCH if it does.
+ * Returns INACCURATE_MATCH if resolve failed.
+ * Returns IMPOSSIBLE_MATCH if it doesn't.
+ */
+protected int resolveLevelForTypeOrEnclosingTypes(char[] simpleNamePattern, char[] qualificationPattern, TypeBinding binding) {
+	if (binding == null) return INACCURATE_MATCH;
+
+	if (binding instanceof ReferenceBinding) {
+		ReferenceBinding type = (ReferenceBinding) binding;
+		while (type != null) {
+			int level = resolveLevelForType(type);
+			if (level != IMPOSSIBLE_MATCH) return level;
+
+			type = type.enclosingType();
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+private Map/*<QualifiedTypeReference, List<TypeBinding>>*/ recordedResolutions = new HashMap();
+int resolveLevelForTypeOrQualifyingTypes(TypeReference typeRef, TypeBinding typeBinding) {
+	if (typeBinding == null || !typeBinding.isValidBinding()) return INACCURATE_MATCH;
+	List resolutionsList = (List) this.recordedResolutions.get(typeRef);
+	if (resolutionsList != null) {
+		for (Iterator i = resolutionsList.iterator(); i.hasNext();) {
+			TypeBinding resolution = (TypeBinding) i.next();
+			int level = resolveLevelForType(resolution);
+			if (level != IMPOSSIBLE_MATCH) return level;
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+public void recordResolution(QualifiedTypeReference typeReference, TypeBinding resolution) {
+	List/*<TypeBinding>*/ resolutionsForTypeReference = (List) this.recordedResolutions.get(typeReference);
+	if (resolutionsForTypeReference == null) {
+		resolutionsForTypeReference = new ArrayList();
+	}
+	resolutionsForTypeReference.add(resolution);
+	this.recordedResolutions.put(typeReference, resolutionsForTypeReference);
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java
new file mode 100644
index 0000000..e87aa65
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class TypeReferencePattern extends IntersectingPattern {
+
+	protected char[] qualification;
+	protected char[] simpleName;
+
+	protected char[] currentCategory;
+
+	/* Optimization: case where simpleName == null */
+	public int segmentsSize;
+	protected char[][] segments;
+	protected int currentSegment;
+
+	private final static char[][]
+		CATEGORIES = { REF, ANNOTATION_REF },
+		CATEGORIES_ANNOT_REF = { ANNOTATION_REF };
+	private char[][] categories;
+	char typeSuffix = TYPE_SUFFIX;
+
+	public TypeReferencePattern(char[] qualification, char[] simpleName, int matchRule) {
+		this(matchRule);
+
+		this.qualification = this.isCaseSensitive ? qualification : CharOperation.toLowerCase(qualification);
+		this.simpleName = (this.isCaseSensitive || this.isCamelCase) ? simpleName : CharOperation.toLowerCase(simpleName);
+
+		if (simpleName == null)
+			this.segments = this.qualification == null ? ONE_STAR_CHAR : CharOperation.splitOn('.', this.qualification);
+		else
+			this.segments = null;
+
+		if (this.segments == null)
+			if (this.qualification == null)
+				this.segmentsSize =  0;
+			else
+				this.segmentsSize =  CharOperation.occurencesOf('.', this.qualification) + 1;
+		else
+			this.segmentsSize = this.segments.length;
+
+		this.mustResolve = true; // always resolve (in case of a simple name reference being a potential match)
+	}
+	/*
+	 * Instantiate a type reference pattern with additional information for generics search
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, String typeSignature, int matchRule) {
+		this(qualification, simpleName, typeSignature, 0, TYPE_SUFFIX, matchRule);
+	}
+	/*
+	 * Instantiate a type reference pattern with additional information for generics search and search elements nature
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, String typeSignature, char typeSuffix, int matchRule) {
+		this(qualification, simpleName, typeSignature, 0, typeSuffix, matchRule);
+	}
+
+	/*
+	 * Instanciate a type reference pattern with additional information for generics search, search elements nature and fine grain information
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, String typeSignature, int limitTo, char typeSuffix, int matchRule) {
+		this(qualification, simpleName,matchRule);
+		this.typeSuffix = typeSuffix;
+		if (typeSignature != null) {
+			// store type signatures and arguments
+			this.typeSignatures = Util.splitTypeLevelsSignature(typeSignature);
+			setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+			if (hasTypeArguments()) {
+				this.segmentsSize = getTypeArguments().length + CharOperation.occurencesOf('/', this.typeSignatures[0]) - 1;
+			}
+		}
+	    this.fineGrain = limitTo & 0xFFFFFFF0;
+	    if (this.fineGrain == IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) {
+	    	this.categories = CATEGORIES_ANNOT_REF;
+	    }
+	}
+
+	/*
+	 * Instantiate a type reference pattern with additional information for generics search
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, IType type, int matchRule) {
+		this(qualification, simpleName, type, 0, matchRule);
+	}
+
+	/*
+	 * Instanciate a type reference pattern with additional information for generics search
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, IType type, int limitTo, int matchRule) {
+		this(qualification, simpleName,matchRule);
+		storeTypeSignaturesAndArguments(type);
+	    this.fineGrain = limitTo & 0xFFFFFFF0;
+	}
+
+	TypeReferencePattern(int matchRule) {
+		super(TYPE_REF_PATTERN, matchRule);
+		this.categories = CATEGORIES;
+	}
+	public void decodeIndexKey(char[] key) {
+		this.simpleName = key;
+	}
+	public SearchPattern getBlankPattern() {
+		return new TypeReferencePattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+	}
+	public char[] getIndexKey() {
+		if (this.simpleName != null)
+			return this.simpleName;
+
+		// Optimization, e.g. type reference is 'org.eclipse.jdt.core.*'
+		if (this.currentSegment >= 0)
+			return this.segments[this.currentSegment];
+		return null;
+	}
+	public char[][] getIndexCategories() {
+		return this.categories;
+	}
+	protected boolean hasNextQuery() {
+		if (this.segments == null) return false;
+
+		// Optimization, e.g. type reference is 'org.eclipse.jdt.core.*'
+		// if package has at least 4 segments, don't look at the first 2 since they are mostly
+		// redundant (e.g. in 'org.eclipse.jdt.core.*' 'org.eclipse' is used all the time)
+		return --this.currentSegment >= (this.segments.length >= 4 ? 2 : 0);
+	}
+
+	public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+		return true; // index key is not encoded so query results all match
+	}
+
+	protected void resetQuery() {
+		/* walk the segments from end to start as it will find less potential references using 'lang' than 'java' */
+		if (this.segments != null)
+			this.currentSegment = this.segments.length - 1;
+	}
+	protected StringBuffer print(StringBuffer output) {
+		String patternClassName = getClass().getName();
+		output.append(patternClassName.substring(patternClassName.lastIndexOf('.')+1));
+		output.append(": qualification<"); //$NON-NLS-1$
+		if (this.qualification != null)
+			output.append(this.qualification);
+		else
+			output.append("*"); //$NON-NLS-1$
+		output.append(">, type<"); //$NON-NLS-1$
+		if (this.simpleName != null)
+			output.append(this.simpleName);
+		else
+			output.append("*"); //$NON-NLS-1$
+		output.append(">"); //$NON-NLS-1$
+		return super.print(output);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java
new file mode 100644
index 0000000..ba2d782
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+
+public class VariableLocator extends PatternLocator {
+
+protected VariablePattern pattern;
+
+public VariableLocator(VariablePattern pattern) {
+	super(pattern);
+
+	this.pattern = pattern;
+}
+public int match(Expression node, MatchingNodeSet nodeSet) { // interested in Assignment
+	if (this.pattern.writeAccess) {
+		if (this.pattern.readAccess) return IMPOSSIBLE_MATCH; // already checked the lhs in match(Reference...) before we reached here
+
+		if (node instanceof Assignment) {
+			Expression lhs = ((Assignment) node).lhs;
+			if (lhs instanceof Reference)
+				return matchReference((Reference) lhs, nodeSet, true);
+		}
+	} else if (this.pattern.readAccess || this.pattern.fineGrain != 0) {
+		if (node instanceof Assignment && !(node instanceof CompoundAssignment)) {
+			// the lhs of a simple assignment may be added in match(Reference...) before we reach here
+			// for example, the fieldRef to 'this.x' in the statement this.x = x; is not considered a readAccess
+			char[] lastToken = null;
+			Expression lhs = ((Assignment) node).lhs;
+			if (lhs instanceof QualifiedNameReference) {
+				char[][] tokens = ((QualifiedNameReference)lhs).tokens;
+				lastToken = tokens[tokens.length-1];
+			}
+			if (lastToken == null || matchesName(this.pattern.name, lastToken)) {
+				nodeSet.removePossibleMatch(lhs);
+				nodeSet.removeTrustedMatch(lhs);
+			}
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+public int match(Reference node, MatchingNodeSet nodeSet) { // interested in NameReference & its subtypes
+	return (this.pattern.readAccess || this.pattern.fineGrain != 0)
+		? matchReference(node, nodeSet, false)
+		: IMPOSSIBLE_MATCH;
+}
+protected int matchReference(Reference node, MatchingNodeSet nodeSet, boolean writeOnlyAccess) {
+	if (node instanceof NameReference) {
+		if (this.pattern.name == null) {
+			return nodeSet.addMatch(node, this.pattern.mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+		} else if (node instanceof SingleNameReference) {
+			if (matchesName(this.pattern.name, ((SingleNameReference) node).token))
+				return nodeSet.addMatch(node, POSSIBLE_MATCH);
+		} else {
+			QualifiedNameReference qNameRef = (QualifiedNameReference) node;
+			char[][] tokens = qNameRef.tokens;
+			if (writeOnlyAccess) {
+				// in the case of the assigment of a qualified name reference, the match must be on the last token
+				if (matchesName(this.pattern.name, tokens[tokens.length-1]))
+					return nodeSet.addMatch(node, POSSIBLE_MATCH);
+			} else {
+				for (int i = 0, max = tokens.length; i < max; i++)
+					if (matchesName(this.pattern.name, tokens[i]))
+						return nodeSet.addMatch(node, POSSIBLE_MATCH);
+			}
+		}
+	}
+	return IMPOSSIBLE_MATCH;
+}
+public String toString() {
+	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java
new file mode 100644
index 0000000..9756dc1
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+
+public abstract class VariablePattern extends JavaSearchPattern {
+
+protected boolean findDeclarations = false;
+protected boolean findReferences = false;
+protected boolean readAccess = false;
+protected boolean writeAccess = false;
+
+protected char[] name;
+
+public final static int FINE_GRAIN_MASK =
+	IJavaSearchConstants.SUPER_REFERENCE |
+	IJavaSearchConstants.QUALIFIED_REFERENCE |
+	IJavaSearchConstants.THIS_REFERENCE |
+	IJavaSearchConstants.IMPLICIT_THIS_REFERENCE;
+
+public VariablePattern(int patternKind, char[] name, int limitTo, int matchRule) {
+	super(patternKind, matchRule);
+
+    this.fineGrain = limitTo & FINE_GRAIN_MASK;
+    if (this.fineGrain == 0) {
+		switch (limitTo & 0xF) {
+			case IJavaSearchConstants.DECLARATIONS :
+				this.findDeclarations = true;
+				break;
+			case IJavaSearchConstants.REFERENCES :
+				this.readAccess = true;
+				this.writeAccess = true;
+				break;
+			case IJavaSearchConstants.READ_ACCESSES :
+				this.readAccess = true;
+				break;
+			case IJavaSearchConstants.WRITE_ACCESSES :
+				this.writeAccess = true;
+				break;
+			case IJavaSearchConstants.ALL_OCCURRENCES :
+				this.findDeclarations = true;
+				this.readAccess = true;
+				this.writeAccess = true;
+				break;
+		}
+		this.findReferences = this.readAccess || this.writeAccess;
+    }
+
+	this.name = (this.isCaseSensitive || this.isCamelCase) ? name : CharOperation.toLowerCase(name);
+}
+/*
+ * Returns whether a method declaration or message send will need to be resolved to
+ * find out if this method pattern matches it.
+ */
+protected boolean mustResolve() {
+	// would like to change this so that we only do it if generic references are found
+	return this.findReferences || this.fineGrain != 0; // always resolve (in case of a simple name reference being a potential match)
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java
new file mode 100644
index 0000000..db444bf
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.processing;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public interface IJob {
+
+	/* Waiting policies */
+	int ForceImmediate = 1;
+	int CancelIfNotReady = 2;
+	int WaitUntilReady = 3;
+
+	/* Job's result */
+	boolean FAILED = false;
+	boolean COMPLETE = true;
+
+	/**
+	 * Answer true if the job belongs to a given family (tag)
+	 */
+	public boolean belongsTo(String jobFamily);
+	/**
+	 * Asks this job to cancel its execution. The cancellation
+	 * can take an undertermined amount of time.
+	 */
+	public void cancel();
+	/**
+	 * Ensures that this job is ready to run.
+	 */
+	public void ensureReadyToRun();
+	/**
+	 * Execute the current job, answer whether it was successful.
+	 */
+	public boolean execute(IProgressMonitor progress);
+
+	/**
+	 * Returns this job's family
+	 */
+	public String getJobFamily();
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
new file mode 100644
index 0000000..e1774d9
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.processing;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public abstract class JobManager implements Runnable {
+
+	/* queue of jobs to execute */
+	protected IJob[] awaitingJobs = new IJob[10];
+	protected int jobStart = 0;
+	protected int jobEnd = -1;
+	protected boolean executing = false;
+
+	/* background processing */
+	protected Thread processingThread;
+	protected Job progressJob;
+
+	/* counter indicating whether job execution is enabled or not, disabled if <= 0
+	    it cannot go beyond 1 */
+	private int enableCount = 1;
+
+	public static boolean VERBOSE = false;
+	/* flag indicating that the activation has completed */
+	public boolean activated = false;
+
+	private int awaitingClients = 0;
+
+	/**
+	 * Invoked exactly once, in background, before starting processing any job
+	 */
+	public void activateProcessing() {
+		this.activated = true;
+	}
+	/**
+	 * Answer the amount of awaiting jobs.
+	 */
+	public synchronized int awaitingJobsCount() {
+		// pretend busy in case concurrent job attempts performing before activated
+		return this.activated ? this.jobEnd - this.jobStart + 1 : 1;
+	}
+	/**
+	 * Answers the first job in the queue, or null if there is no job available
+	 * Until the job has completed, the job manager will keep answering the same job.
+	 */
+	public synchronized IJob currentJob() {
+		if (this.enableCount > 0 && this.jobStart <= this.jobEnd)
+			return this.awaitingJobs[this.jobStart];
+		return null;
+	}
+	public synchronized void disable() {
+		this.enableCount--;
+		if (VERBOSE)
+			Util.verbose("DISABLING background indexing"); //$NON-NLS-1$
+	}
+	/**
+	 * Remove the index from cache for a given project.
+	 * Passing null as a job family discards them all.
+	 */
+	public void discardJobs(String jobFamily) {
+
+		if (VERBOSE)
+			Util.verbose("DISCARD   background job family - " + jobFamily); //$NON-NLS-1$
+
+		try {
+			IJob currentJob;
+			// cancel current job if it belongs to the given family
+			synchronized(this){
+				currentJob = currentJob();
+				disable();
+			}
+			if (currentJob != null && (jobFamily == null || currentJob.belongsTo(jobFamily))) {
+				currentJob.cancel();
+
+				// wait until current active job has finished
+				while (this.processingThread != null && this.executing){
+					try {
+						if (VERBOSE)
+							Util.verbose("-> waiting end of current background job - " + currentJob); //$NON-NLS-1$
+						Thread.sleep(50);
+					} catch(InterruptedException e){
+						// ignore
+					}
+				}
+			}
+
+			// flush and compact awaiting jobs
+			int loc = -1;
+			synchronized(this) {
+				for (int i = this.jobStart; i <= this.jobEnd; i++) {
+					currentJob = this.awaitingJobs[i];
+					if (currentJob != null) { // sanity check
+						this.awaitingJobs[i] = null;
+						if (!(jobFamily == null || currentJob.belongsTo(jobFamily))) { // copy down, compacting
+							this.awaitingJobs[++loc] = currentJob;
+						} else {
+							if (VERBOSE)
+								Util.verbose("-> discarding background job  - " + currentJob); //$NON-NLS-1$
+							currentJob.cancel();
+						}
+					}
+				}
+				this.jobStart = 0;
+				this.jobEnd = loc;
+			}
+		} finally {
+			enable();
+		}
+		if (VERBOSE)
+			Util.verbose("DISCARD   DONE with background job family - " + jobFamily); //$NON-NLS-1$
+	}
+	public synchronized void enable() {
+		this.enableCount++;
+		if (VERBOSE)
+			Util.verbose("ENABLING  background indexing"); //$NON-NLS-1$
+		notifyAll(); // wake up the background thread if it is waiting (context must be synchronized)
+	}
+	protected synchronized boolean isJobWaiting(IJob request) {
+		for (int i = this.jobEnd; i > this.jobStart; i--) // don't check job at jobStart, as it may have already started
+			if (request.equals(this.awaitingJobs[i])) return true;
+		return false;
+	}
+	/**
+	 * Advance to the next available job, once the current one has been completed.
+	 * Note: clients awaiting until the job count is zero are still waiting at this point.
+	 */
+	protected synchronized void moveToNextJob() {
+		//if (!enabled) return;
+
+		if (this.jobStart <= this.jobEnd) {
+			this.awaitingJobs[this.jobStart++] = null;
+			if (this.jobStart > this.jobEnd) {
+				this.jobStart = 0;
+				this.jobEnd = -1;
+			}
+		}
+	}
+	/**
+	 * When idle, give chance to do something
+	 */
+	protected void notifyIdle(long idlingTime) {
+		// do nothing
+	}
+	/**
+	 * This API is allowing to run one job in concurrence with background processing.
+	 * Indeed since other jobs are performed in background, resource sharing might be
+	 * an issue.Therefore, this functionality allows a given job to be run without
+	 * colliding with background ones.
+	 * Note: multiple thread might attempt to perform concurrent jobs at the same time,
+	 *            and should synchronize (it is deliberately left to clients to decide whether
+	 *            concurrent jobs might interfere or not. In general, multiple read jobs are ok).
+	 *
+	 * Waiting policy can be:
+	 * 		IJobConstants.ForceImmediateSearch
+	 * 		IJobConstants.CancelIfNotReadyToSearch
+	 * 		IJobConstants.WaitUntilReadyToSearch
+	 *
+	 */
+	public boolean performConcurrentJob(IJob searchJob, int waitingPolicy, IProgressMonitor progress) {
+		if (VERBOSE)
+			Util.verbose("STARTING  concurrent job - " + searchJob); //$NON-NLS-1$
+
+		searchJob.ensureReadyToRun();
+
+		boolean status = IJob.FAILED;
+		try {
+			int concurrentJobWork = 100;
+			if (progress != null)
+				progress.beginTask("", concurrentJobWork); //$NON-NLS-1$
+			if (awaitingJobsCount() > 0) {
+				switch (waitingPolicy) {
+
+					case IJob.ForceImmediate :
+						if (VERBOSE)
+							Util.verbose("-> NOT READY - forcing immediate - " + searchJob);//$NON-NLS-1$
+						try {
+							disable(); // pause indexing
+							status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+						} finally {
+							enable();
+						}
+						if (VERBOSE)
+							Util.verbose("FINISHED  concurrent job - " + searchJob); //$NON-NLS-1$
+						return status;
+
+					case IJob.CancelIfNotReady :
+						if (VERBOSE)
+							Util.verbose("-> NOT READY - cancelling - " + searchJob); //$NON-NLS-1$
+						if (VERBOSE)
+							Util.verbose("CANCELED concurrent job - " + searchJob); //$NON-NLS-1$
+						throw new OperationCanceledException();
+
+					case IJob.WaitUntilReady :
+						IProgressMonitor subProgress = null;
+						try {
+							int totalWork = 1000;
+							if (progress != null) {
+								subProgress = new SubProgressMonitor(progress, concurrentJobWork * 8 / 10);
+								subProgress.beginTask("", totalWork); //$NON-NLS-1$
+								concurrentJobWork = concurrentJobWork * 2 / 10;
+							}
+							// use local variable to avoid potential NPE (see bug 20435 NPE when searching java method
+							// and bug 42760 NullPointerException in JobManager when searching)
+							Thread t = this.processingThread;
+							int originalPriority = t == null ? -1 : t.getPriority();
+							try {
+								if (t != null)
+									t.setPriority(Thread.currentThread().getPriority());
+								synchronized(this) {
+									this.awaitingClients++;
+								}
+								IJob previousJob = null;
+								int awaitingJobsCount;
+								int lastJobsCount = totalWork;
+								float lastWorked = 0;
+								float totalWorked = 0;
+								while ((awaitingJobsCount = awaitingJobsCount()) > 0) {
+									if ((subProgress != null && subProgress.isCanceled())
+											|| this.processingThread == null)
+										throw new OperationCanceledException();
+									IJob currentJob = currentJob();
+									// currentJob can be null when jobs have been added to the queue but job manager is not enabled
+									if (currentJob != null && currentJob != previousJob) {
+										if (VERBOSE)
+											Util.verbose("-> NOT READY - waiting until ready - " + searchJob);//$NON-NLS-1$
+										if (subProgress != null) {
+											String indexing = Messages.bind(Messages.jobmanager_filesToIndex, currentJob.getJobFamily(), Integer.toString(awaitingJobsCount));
+											subProgress.subTask(indexing);
+											// ratio of the amount of work relative to the total work
+											float ratio = awaitingJobsCount < totalWork ? 1 : ((float) totalWork) / awaitingJobsCount;
+											if (lastJobsCount > awaitingJobsCount) {
+												totalWorked += (lastJobsCount - awaitingJobsCount) * ratio;
+											} else {
+												// more jobs were added, just increment by the ratio
+												totalWorked += ratio;
+											}
+											if (totalWorked - lastWorked >= 1) {
+												subProgress.worked((int) (totalWorked - lastWorked));
+												lastWorked = totalWorked;
+											}
+											lastJobsCount = awaitingJobsCount;
+										}
+										previousJob = currentJob;
+									}
+									try {
+										if (VERBOSE)
+											Util.verbose("-> GOING TO SLEEP - " + searchJob);//$NON-NLS-1$
+										Thread.sleep(50);
+									} catch (InterruptedException e) {
+										// ignore
+									}
+								}
+							} finally {
+								synchronized(this) {
+									this.awaitingClients--;
+								}
+								if (t != null && originalPriority > -1 && t.isAlive())
+									t.setPriority(originalPriority);
+							}
+						} finally {
+							if (subProgress != null)
+								subProgress.done();
+						}
+				}
+			}
+			status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+		} finally {
+			if (progress != null)
+				progress.done();
+			if (VERBOSE)
+				Util.verbose("FINISHED  concurrent job - " + searchJob); //$NON-NLS-1$
+		}
+		return status;
+	}
+	public abstract String processName();
+
+	public synchronized void request(IJob job) {
+
+		job.ensureReadyToRun();
+
+		// append the job to the list of ones to process later on
+		int size = this.awaitingJobs.length;
+		if (++this.jobEnd == size) { // when growing, relocate jobs starting at position 0
+			this.jobEnd -= this.jobStart; // jobEnd now equals the number of jobs
+			if (this.jobEnd < 50 && this.jobEnd < this.jobStart) {
+				// plenty of free space in the queue so shift the remaining jobs to the beginning instead of growing it
+				System.arraycopy(this.awaitingJobs, this.jobStart, this.awaitingJobs, 0, this.jobEnd);
+				for (int i = this.jobStart; i < size; i++)
+					this.awaitingJobs[i] = null;
+			} else {
+				System.arraycopy(this.awaitingJobs, this.jobStart, this.awaitingJobs = new IJob[size * 2], 0, this.jobEnd);
+			}
+			this.jobStart = 0;
+		}
+		this.awaitingJobs[this.jobEnd] = job;
+		if (VERBOSE) {
+			Util.verbose("REQUEST   background job - " + job); //$NON-NLS-1$
+			Util.verbose("AWAITING JOBS count: " + awaitingJobsCount()); //$NON-NLS-1$
+		}
+		notifyAll(); // wake up the background thread if it is waiting
+	}
+	/**
+	 * Flush current state
+	 */
+	public synchronized void reset() {
+		if (VERBOSE)
+			Util.verbose("Reset"); //$NON-NLS-1$
+
+		if (this.processingThread != null) {
+			discardJobs(null); // discard all jobs
+		} else {
+			/* initiate background processing */
+			this.processingThread = new Thread(this, processName());
+			this.processingThread.setDaemon(true);
+			// less prioritary by default, priority is raised if clients are actively waiting on it
+			this.processingThread.setPriority(Thread.NORM_PRIORITY-1);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=296343
+			// set the context loader to avoid leaking the current context loader
+			this.processingThread.setContextClassLoader(this.getClass().getClassLoader());
+			this.processingThread.start();
+		}
+	}
+	/**
+	 * Infinite loop performing resource indexing
+	 */
+	public void run() {
+
+		long idlingStart = -1;
+		activateProcessing();
+		try {
+			class ProgressJob extends Job {
+				ProgressJob(String name) {
+					super(name);
+				}
+				protected IStatus run(IProgressMonitor monitor) {
+					IJob job = currentJob();
+					while (!monitor.isCanceled() && job != null) {
+						 String taskName = new StringBuffer(Messages.jobmanager_indexing)
+							.append(Messages.bind(Messages.jobmanager_filesToIndex, job.getJobFamily(), Integer.toString(awaitingJobsCount())))
+							.toString();
+						monitor.subTask(taskName);
+						setName(taskName);
+						try {
+							Thread.sleep(500);
+						} catch (InterruptedException e) {
+							// ignore
+						}
+						job = currentJob();
+					}
+					return Status.OK_STATUS;
+				}
+			}
+			this.progressJob = null;
+			while (this.processingThread != null) {
+				try {
+					IJob job;
+					synchronized (this) {
+						// handle shutdown case when notifyAll came before the wait but after the while loop was entered
+						if (this.processingThread == null) continue;
+
+						// must check for new job inside this sync block to avoid timing hole
+						if ((job = currentJob()) == null) {
+							if (this.progressJob != null) {
+								this.progressJob.cancel();
+								this.progressJob = null;
+							}
+							if (idlingStart < 0)
+								idlingStart = System.currentTimeMillis();
+							else
+								notifyIdle(System.currentTimeMillis() - idlingStart);
+							this.wait(); // wait until a new job is posted (or reenabled:38901)
+						} else {
+							idlingStart = -1;
+						}
+					}
+					if (job == null) {
+						notifyIdle(System.currentTimeMillis() - idlingStart);
+						// just woke up, delay before processing any new jobs, allow some time for the active thread to finish
+						Thread.sleep(500);
+						continue;
+					}
+					if (VERBOSE) {
+						Util.verbose(awaitingJobsCount() + " awaiting jobs"); //$NON-NLS-1$
+						Util.verbose("STARTING background job - " + job); //$NON-NLS-1$
+					}
+					try {
+						this.executing = true;
+						if (this.progressJob == null) {
+							this.progressJob = new ProgressJob(Messages.bind(Messages.jobmanager_indexing, "", "")); //$NON-NLS-1$ //$NON-NLS-2$
+							this.progressJob.setPriority(Job.LONG);
+							this.progressJob.setSystem(true);
+							this.progressJob.schedule();
+						}
+						/*boolean status = */job.execute(null);
+						//if (status == FAILED) request(job);
+					} finally {
+						this.executing = false;
+						if (VERBOSE)
+							Util.verbose("FINISHED background job - " + job); //$NON-NLS-1$
+						moveToNextJob();
+						if (this.awaitingClients == 0)
+							Thread.sleep(50);
+					}
+				} catch (InterruptedException e) { // background indexing was interrupted
+				}
+			}
+		} catch (RuntimeException e) {
+			if (this.processingThread != null) { // if not shutting down
+				// log exception
+				Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+				// keep job manager alive
+				discardJobs(null);
+				this.processingThread = null;
+				reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+			}
+			throw e;
+		} catch (Error e) {
+			if (this.processingThread != null && !(e instanceof ThreadDeath)) {
+				// log exception
+				Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+				// keep job manager alive
+				discardJobs(null);
+				this.processingThread = null;
+				reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+			}
+			throw e;
+		}
+	}
+	/**
+	 * Stop background processing, and wait until the current job is completed before returning
+	 */
+	public void shutdown() {
+
+		if (VERBOSE)
+			Util.verbose("Shutdown"); //$NON-NLS-1$
+
+		disable();
+		discardJobs(null); // will wait until current executing job has completed
+		Thread thread = this.processingThread;
+		try {
+			if (thread != null) { // see http://bugs.eclipse.org/bugs/show_bug.cgi?id=31858
+				synchronized (this) {
+					this.processingThread = null; // mark the job manager as shutting down so that the thread will stop by itself
+					notifyAll(); // ensure its awake so it can be shutdown
+				}
+				// in case processing thread is handling a job
+				thread.join();
+			}
+			Job job = this.progressJob;
+			if (job != null) {
+				job.cancel();
+				job.join();
+			}
+		} catch (InterruptedException e) {
+			// ignore
+		}
+	}
+	public String toString() {
+		StringBuffer buffer = new StringBuffer(10);
+		buffer.append("Enable count:").append(this.enableCount).append('\n'); //$NON-NLS-1$
+		int numJobs = this.jobEnd - this.jobStart + 1;
+		buffer.append("Jobs in queue:").append(numJobs).append('\n'); //$NON-NLS-1$
+		for (int i = 0; i < numJobs && i < 15; i++) {
+			buffer.append(i).append(" - job["+i+"]: ").append(this.awaitingJobs[this.jobStart+i]).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		return buffer.toString();
+	}
+}
